+++ /dev/null
-SubDir TOP src ;
-
-SubInclude TOP src squirrel ;
-SubInclude TOP src scripting ;
-
-sources =
- [ Wildcard *.cpp *.hpp ]
- [ Wildcard audio : *.cpp *.hpp ]
- [ Wildcard audio/newapi : *.cpp *.hpp ]
- [ Wildcard badguy : *.cpp *.hpp ]
- [ Wildcard binreloc : *.c *.h ]
- [ Wildcard control : *.cpp *.hpp ]
- [ Wildcard gui : *.cpp *.hpp ]
- [ Wildcard lisp : *.cpp *.hpp ]
- [ Wildcard math : *.cpp *.hpp ]
- [ Wildcard object : *.cpp *.hpp ]
- [ Wildcard physfs : *.cpp *.hpp ]
- [ Wildcard sprite : *.cpp *.hpp ]
- [ Wildcard tinygettext : *.cpp *.hpp ]
- [ Wildcard trigger : *.cpp *.hpp ]
- [ Wildcard video : *.cpp *.hpp ]
- [ Wildcard worldmap : *.cpp *.hpp ]
- [ Wildcard obstack : *.c *.h *.hpp ]
-;
-TRANSLATABLE_SOURCES += [ SearchSource $(sources) ] ;
-
-#Application supertux : $(sources) $(wrapper_objects) ;
-Application supertux2 : $(sources) $(wrapper_objects) : linkerfile ;
-C++Flags supertux2 : -DAPPDATADIR=\'\"$(appdatadir)\"\' ;
-LinkWith supertux2 : squirrel ;
-ExternalLibs supertux2 : SDL SDLIMAGE GL OPENAL VORBIS VORBISFILE OGG ICONV PHYSFS BINRELOC LIBCURL ;
-Help supertux2 : "Build the supertux2 executable" ;
-IncludeDir supertux2 : squirrel/include squirrel ;
-Package [ Wildcard scripting : *.cpp *.hpp ] ;
-
+++ /dev/null
-// $Id$
-//
-// SuperTux - Add-on
-// Copyright (C) 2007 Christoph Sommer <christoph.sommer@2007.expires.deltadevelopment.de>
-//
-// 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.
-//
-
-#include <sstream>
-#include <stdexcept>
-#include "addon.hpp"
-#include "addon_manager.hpp"
-
-void
-Addon::install()
-{
- AddonManager& adm = AddonManager::get_instance();
- adm.install(*this);
-}
-
-void
-Addon::remove()
-{
- AddonManager& adm = AddonManager::get_instance();
- adm.remove(*this);
-}
-
-void
-Addon::parse(const lisp::Lisp& lisp)
-{
- try {
- lisp.get("kind", kind);
- lisp.get("title", title);
- lisp.get("author", author);
- lisp.get("license", license);
- lisp.get("http-url", http_url);
- lisp.get("file", file);
- lisp.get("md5", md5);
- } catch(std::exception& e) {
- std::stringstream msg;
- msg << "Problem when parsing addoninfo: " << e.what();
- throw std::runtime_error(msg.str());
- }
-}
-
-void
-Addon::parse(std::string fname)
-{
- try {
- lisp::Parser parser;
- const lisp::Lisp* root = parser.parse(fname);
- const lisp::Lisp* addon = root->get_lisp("supertux-addoninfo");
- if(!addon) throw std::runtime_error("file is not a supertux-addoninfo file.");
- parse(*addon);
- } catch(std::exception& e) {
- std::stringstream msg;
- msg << "Problem when reading addoninfo '" << fname << "': " << e.what();
- throw std::runtime_error(msg.str());
- }
-}
-
-void
-Addon::write(lisp::Writer& writer) const
-{
- writer.start_list("supertux-addoninfo");
- if (kind != "") writer.write_string("kind", kind);
- if (title != "") writer.write_string("title", title);
- if (author != "") writer.write_string("author", author);
- if (license != "") writer.write_string("license", license);
- if (http_url != "") writer.write_string("http-url", http_url);
- if (file != "") writer.write_string("file", file);
- if (md5 != "") writer.write_string("md5", md5);
- writer.end_list("supertux-addoninfo");
-}
-
-void
-Addon::write(std::string fname) const
-{
- lisp::Writer writer(fname);
- write(writer);
-}
-
-bool
-Addon::equals(const Addon& addon2) const
-{
- if ((this->md5 == "") || (addon2.md5 == "")) return (this->title == addon2.title);
- return (this->md5 == addon2.md5);
-}
-
+++ /dev/null
-// $Id$
-//
-// SuperTux - Add-on
-// Copyright (C) 2007 Christoph Sommer <christoph.sommer@2007.expires.deltadevelopment.de>
-//
-// 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.
-//
-#ifndef ADDON_H
-#define ADDON_H
-
-#include <string>
-#include <vector>
-#include "lisp/parser.hpp"
-#include "lisp/lisp.hpp"
-#include "lisp/writer.hpp"
-
-/**
- * Represents an (available or installed) Add-on, e.g. a level set
- */
-class Addon
-{
-public:
- std::string kind;
- std::string title;
- std::string author;
- std::string license;
- std::string http_url;
- std::string file;
- std::string md5;
-
- bool isInstalled;
-
- /**
- * Download and install Add-on
- */
- void install();
-
- /**
- * Physically delete Add-on
- */
- void remove();
-
- /**
- * Read additional information from given contents of a (supertux-addoninfo ...) block
- */
- void parse(const lisp::Lisp& lisp);
-
- /**
- * Read additional information from given file
- */
- void parse(std::string fname);
-
- /**
- * Writes out Add-on metainformation to a Lisp Writer
- */
- void write(lisp::Writer& writer) const;
-
- /**
- * Writes out Add-on metainformation to a file
- */
- void write(std::string fname) const;
-
- /**
- * Checks if Add-on is the same as given one.
- * If available, checks MD5 sum, else relies on title alone.
- */
- bool equals(const Addon& addon2) const;
-
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux - Add-on Manager
-// Copyright (C) 2007 Christoph Sommer <christoph.sommer@2007.expires.deltadevelopment.de>
-//
-// 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.
-//
-
-#include <sstream>
-#include <stdexcept>
-#include <list>
-//#include <physfs.h>
-#include <unison/vfs/FileSystem.hpp>
-#include <unison/vfs/sdl/Utils.hpp>
-#include <sys/stat.h>
-#include <stdio.h>
-#include "SDL.h"
-#include "addon_manager.hpp"
-#include "config.h"
-#include "log.hpp"
-#include "lisp/parser.hpp"
-#include "lisp/lisp.hpp"
-#include "lisp/list_iterator.hpp"
-
-#ifdef HAVE_LIBCURL
-#include <curl/curl.h>
-#include <curl/types.h>
-#include <curl/easy.h>
-#endif
-
-#ifdef HAVE_LIBCURL
-namespace {
-
- size_t my_curl_string_append(void *ptr, size_t size, size_t nmemb, void *string_ptr)
- {
- std::string& s = *static_cast<std::string*>(string_ptr);
- std::string buf(static_cast<char*>(ptr), size * nmemb);
- s += buf;
- log_debug << "read " << size * nmemb << " bytes of data..." << std::endl;
- return size * nmemb;
- }
-
- /*size_t my_curl_physfs_write(void *ptr, size_t size, size_t nmemb, void *f_p)
- {
- PHYSFS_file* f = static_cast<PHYSFS_file*>(f_p);
- PHYSFS_sint64 written = PHYSFS_write(f, ptr, size, nmemb);
- log_debug << "read " << size * nmemb << " bytes of data..." << std::endl;
- return size * written;
- }*/
-
- size_t my_curl_sdl_write(void *ptr, size_t size, size_t nmemb, void *f_p)
- {
- SDL_RWops* f = static_cast<SDL_RWops*>(f_p);
- int written = SDL_RWwrite(f, ptr, size, nmemb);
- log_debug << "wrote " << size * nmemb << " bytes of data..." << std::endl;
- return size * written;
- }
-
-}
-#endif
-
-AddonManager&
-AddonManager::get_instance()
-{
- static AddonManager instance;
- return instance;
-}
-
-AddonManager::AddonManager()
-{
-#ifdef HAVE_LIBCURL
- curl_global_init(CURL_GLOBAL_ALL);
-#endif
-}
-
-AddonManager::~AddonManager()
-{
-#ifdef HAVE_LIBCURL
- curl_global_cleanup();
-#endif
-}
-
-std::vector<Addon>
-AddonManager::get_installed_addons() const
-{
- std::vector<Addon> addons;
-
- Unison::VFS::FileSystem &fs = Unison::VFS::FileSystem::get();
- std::vector<std::string> search_path = fs.get_search_path();
- for(std::vector<std::string>::iterator iter = search_path.begin();iter != search_path.end();++iter)
- {
- // get filename of potential archive
- std::string fileName = *iter;
-
- // make sure it's in the writeDir
- static const std::string writeDir = fs.get_write_dir();
- if (fileName.compare(0, writeDir.length(), writeDir) != 0) continue;
-
- // make sure it looks like an archive
- static const std::string archiveExt = ".zip";
- if (fileName.compare(fileName.length()-archiveExt.length(), archiveExt.length(), archiveExt) != 0) continue;
-
- // make sure it exists
- struct stat stats;
- if (stat(fileName.c_str(), &stats) != 0) continue;
-
- // make sure it's an actual file
- if (!S_ISREG(stats.st_mode)) continue;
-
- Addon addon;
-
- // extract nice title as fallback for when the Add-on has no addoninfo file
- static std::string dirSep = fs.get_dir_sep();
- std::string::size_type n = fileName.rfind(dirSep) + 1;
- if (n == std::string::npos) n = 0;
- addon.title = fileName.substr(n, fileName.length() - n - archiveExt.length());
- std::string shortFileName = fileName.substr(n, fileName.length() - n);
- addon.file = shortFileName;
-
- // read an accompaining .nfo file, if it exists
- static const std::string infoExt = ".nfo";
- std::string infoFileName = fileName.substr(n, fileName.length() - n - archiveExt.length()) + infoExt;
- if (fs.exists(infoFileName)) {
- addon.parse(infoFileName);
- if (addon.file != shortFileName) {
- log_warning << "Add-on \"" << addon.title << "\", contained in file \"" << shortFileName << "\" is accompained by an addoninfo file that specifies \"" << addon.file << "\" as the Add-on's file name. Skipping." << std::endl;
- }
- }
-
- // make sure the Add-on's file name does not contain weird characters
- if (addon.file.find_first_not_of("match.quiz-proxy_gwenblvdjfks0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ") != std::string::npos) {
- log_warning << "Add-on \"" << addon.title << "\" contains unsafe file name. Skipping." << std::endl;
- continue;
- }
-
- addon.isInstalled = true;
- addons.push_back(addon);
- }
-
- return addons;
-}
-
-std::vector<Addon>
-AddonManager::get_available_addons() const
-{
- std::vector<Addon> addons;
-
-#ifdef HAVE_LIBCURL
-
- char error_buffer[CURL_ERROR_SIZE+1];
-
- const char* baseUrl = "http://supertux.lethargik.org/addons/index.nfo";
- std::string addoninfos = "";
-
- CURL *curl_handle;
- curl_handle = curl_easy_init();
- curl_easy_setopt(curl_handle, CURLOPT_URL, baseUrl);
- curl_easy_setopt(curl_handle, CURLOPT_USERAGENT, "SuperTux/" PACKAGE_VERSION " libcURL");
- curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, my_curl_string_append);
- curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, &addoninfos);
- curl_easy_setopt(curl_handle, CURLOPT_ERRORBUFFER, error_buffer);
- curl_easy_setopt(curl_handle, CURLOPT_NOPROGRESS, 1);
- curl_easy_setopt(curl_handle, CURLOPT_NOSIGNAL, 1);
- curl_easy_setopt(curl_handle, CURLOPT_FAILONERROR, 1);
- CURLcode result = curl_easy_perform(curl_handle);
- curl_easy_cleanup(curl_handle);
-
- if (result != CURLE_OK) {
- std::string why = error_buffer[0] ? error_buffer : "unhandled error";
- throw std::runtime_error("Downloading Add-on list failed: " + why);
- }
-
- try {
- lisp::Parser parser;
- std::stringstream addoninfos_stream(addoninfos);
- const lisp::Lisp* root = parser.parse(addoninfos_stream, "supertux-addons");
-
- const lisp::Lisp* addons_lisp = root->get_lisp("supertux-addons");
- if(!addons_lisp) throw std::runtime_error("Downloaded file is not an Add-on list");
-
- lisp::ListIterator iter(addons_lisp);
- while(iter.next()) {
- const std::string& token = iter.item();
- if(token == "supertux-addoninfo") {
- Addon addon;
- addon.parse(*(iter.lisp()));
-
- // make sure the Add-on's file name does not contain weird characters
- if (addon.file.find_first_not_of("match.quiz-proxy_gwenblvdjfks0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ") != std::string::npos) {
- log_warning << "Add-on \"" << addon.title << "\" contains unsafe file name. Skipping." << std::endl;
- continue;
- }
-
- addon.isInstalled = false;
- addons.push_back(addon);
- } else {
- log_warning << "Unknown token '" << token << "' in Add-on list" << std::endl;
- }
- }
- } catch(std::exception& e) {
- std::stringstream msg;
- msg << "Problem when reading Add-on list: " << e.what();
- throw std::runtime_error(msg.str());
- }
-
-#endif
-
- return addons;
-}
-
-
-void
-AddonManager::install(const Addon& addon)
-{
- // make sure the Add-on's file name does not contain weird characters
- if (addon.file.find_first_not_of("match.quiz-proxy_gwenblvdjfks0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ") != std::string::npos) {
- throw std::runtime_error("Add-on has unsafe file name (\""+addon.file+"\")");
- }
-
- Unison::VFS::FileSystem &fs = Unison::VFS::FileSystem::get();
-
-#ifdef HAVE_LIBCURL
-
- char error_buffer[CURL_ERROR_SIZE+1];
-
- char* url = (char*)malloc(addon.http_url.length() + 1);
- strncpy(url, addon.http_url.c_str(), addon.http_url.length() + 1);
-
- //PHYSFS_file* f = PHYSFS_openWrite(addon.file.c_str());
- SDL_RWops *f = Unison::VFS::SDL::Utils::open_physfs_in(addon.file);
-
- log_debug << "Downloading \"" << url << "\"" << std::endl;
-
- CURL *curl_handle;
- curl_handle = curl_easy_init();
- curl_easy_setopt(curl_handle, CURLOPT_URL, url);
- curl_easy_setopt(curl_handle, CURLOPT_USERAGENT, "SuperTux/" PACKAGE_VERSION " libcURL");
- curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, my_curl_sdl_write);
- curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, f);
- curl_easy_setopt(curl_handle, CURLOPT_ERRORBUFFER, error_buffer);
- curl_easy_setopt(curl_handle, CURLOPT_NOPROGRESS, 1);
- curl_easy_setopt(curl_handle, CURLOPT_NOSIGNAL, 1);
- curl_easy_setopt(curl_handle, CURLOPT_FAILONERROR, 1);
- CURLcode result = curl_easy_perform(curl_handle);
- curl_easy_cleanup(curl_handle);
-
- //PHYSFS_close(f);
- SDL_RWclose(f);
-
- free(url);
-
- if (result != CURLE_OK) {
- //PHYSFS_delete(addon.file.c_str());
- fs.rm(addon.file);
- std::string why = error_buffer[0] ? error_buffer : "unhandled error";
- throw std::runtime_error("Downloading Add-on failed: " + why);
- }
-
- // write an accompaining .nfo file
- static const std::string archiveExt = ".zip";
- static const std::string infoExt = ".nfo";
- std::string infoFileName = addon.file.substr(0, addon.file.length()-archiveExt.length()) + infoExt;
- addon.write(infoFileName);
-
- //static const std::string writeDir = PHYSFS_getWriteDir();
- //static const std::string dirSep = PHYSFS_getDirSeparator();
- static const std::string writeDir = fs.get_write_dir();
- static const std::string dirSep = fs.get_dir_sep();
- std::string fullFilename = writeDir + dirSep + addon.file;
- log_debug << "Finished downloading \"" << fullFilename << "\"" << std::endl;
- fs.mount(fullFilename, "/", true);
- //PHYSFS_addToSearchPath(fullFilename.c_str(), 1);
-#else
- (void) addon;
-#endif
-
-}
-
-void
-AddonManager::remove(const Addon& addon)
-{
- // make sure the Add-on's file name does not contain weird characters
- if (addon.file.find_first_not_of("match.quiz-proxy_gwenblvdjfks0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ") != std::string::npos) {
- throw std::runtime_error("Add-on has unsafe file name (\""+addon.file+"\")");
- }
-
- log_debug << "deleting file \"" << addon.file << "\"" << std::endl;
-
- Unison::VFS::FileSystem &fs = Unison::VFS::FileSystem::get();
- fs.umount(addon.file);
- fs.rm(addon.file);
-
- // remove an accompaining .nfo file
- static const std::string archiveExt = ".zip";
- static const std::string infoExt = ".nfo";
- std::string infoFileName = addon.file.substr(0, addon.file.length()-archiveExt.length()) + infoExt;
- if (fs.exists(infoFileName)) {
- log_debug << "deleting file \"" << infoFileName << "\"" << std::endl;
- fs.rm(infoFileName);
- }
-}
-
+++ /dev/null
-// $Id$
-//
-// SuperTux - Add-on Manager
-// Copyright (C) 2007 Christoph Sommer <christoph.sommer@2007.expires.deltadevelopment.de>
-//
-// 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.
-//
-#ifndef ADDON_MANAGER_H
-#define ADDON_MANAGER_H
-
-#include <string>
-#include <vector>
-#include "addon.hpp"
-
-/**
- * Checks for, installs and removes Add-ons
- */
-class AddonManager
-{
-public:
- /**
- * returns a list of installed Add-ons
- */
- std::vector<Addon> get_installed_addons() const;
-
- /**
- * returns a list of available Add-ons
- */
- std::vector<Addon> get_available_addons() const;
-
- /**
- * Download and install Add-on
- */
- void install(const Addon& addon);
-
- /**
- * Physically delete Add-on
- */
- void remove(const Addon& addon);
-
- static AddonManager& get_instance();
-
-protected:
- AddonManager();
- ~AddonManager();
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#include <config.h>
-
-#include "dummy_sound_source.hpp"
-
-class DummySoundSource : public SoundSource
-{
-public:
- DummySoundSource()
- {}
- virtual ~DummySoundSource()
- {}
-
- virtual void play()
- {
- is_playing = true;
- }
-
- virtual void stop()
- {
- is_playing = false;
- }
-
- virtual bool playing()
- {
- return is_playing;
- }
-
- virtual void set_looping(bool )
- {
- }
-
- virtual void set_gain(float )
- {
- }
-
- virtual void set_pitch(float )
- {
- }
-
- virtual void set_position(const Vector& )
- {
- }
-
- virtual void set_velocity(const Vector& )
- {
- }
-
- virtual void set_reference_distance(float )
- {
- }
-
- virtual void set_rollof_factor(float )
- {
- }
-
-private:
- bool is_playing;
-};
-
-SoundSource* create_dummy_sound_source()
-{
- return new DummySoundSource();
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#ifndef __DUMMY_SOUND_SOURCE_HPP__
-#define __DUMMY_SOUND_SOURCE_HPP__
-
-#include "sound_source.hpp"
-
-SoundSource* create_dummy_sound_source();
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#include <config.h>
-
-#include "openal_sound_source.hpp"
-#include "sound_manager.hpp"
-
-OpenALSoundSource::OpenALSoundSource()
-{
- alGenSources(1, &source);
- SoundManager::check_al_error("Couldn't create audio source: ");
- set_reference_distance(128);
-}
-
-OpenALSoundSource::~OpenALSoundSource()
-{
- stop();
- alDeleteSources(1, &source);
-}
-
-void
-OpenALSoundSource::stop()
-{
- alSourceStop(source);
- alSourcei(source, AL_BUFFER, AL_NONE);
- SoundManager::check_al_error("Problem stopping audio source: ");
-}
-
-void
-OpenALSoundSource::play()
-{
- alSourcePlay(source);
- SoundManager::check_al_error("Couldn't start audio source: ");
-}
-
-bool
-OpenALSoundSource::playing()
-{
- ALint state = AL_PLAYING;
- alGetSourcei(source, AL_SOURCE_STATE, &state);
- return state != AL_STOPPED;
-}
-
-void
-OpenALSoundSource::update()
-{
-}
-
-void
-OpenALSoundSource::set_looping(bool looping)
-{
- alSourcei(source, AL_LOOPING, looping ? AL_TRUE : AL_FALSE);
-}
-
-void
-OpenALSoundSource::set_position(const Vector& position)
-{
- alSource3f(source, AL_POSITION, position.x, position.y, 0);
-}
-
-void
-OpenALSoundSource::set_velocity(const Vector& velocity)
-{
- alSource3f(source, AL_VELOCITY, velocity.x, velocity.y, 0);
-}
-
-void
-OpenALSoundSource::set_gain(float gain)
-{
- alSourcef(source, AL_GAIN, gain);
-}
-
-void
-OpenALSoundSource::set_pitch(float pitch)
-{
- alSourcef(source, AL_PITCH, pitch);
-}
-
-void
-OpenALSoundSource::set_reference_distance(float distance)
-{
- alSourcef(source, AL_REFERENCE_DISTANCE, distance);
-}
-
-void
-OpenALSoundSource::set_rollof_factor(float factor)
-{
- alSourcef(source, AL_ROLLOFF_FACTOR, factor);
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#ifndef __OPENAL_SOUND_SOURCE_H__
-#define __OPENAL_SOUND_SOURCE_H__
-
-#ifndef MACOSX
-#include <AL/al.h>
-#else
-#include <OpenAL/al.h>
-#endif
-
-#include "math/vector.hpp"
-#include "sound_source.hpp"
-
-class OpenALSoundSource : public SoundSource
-{
-public:
- OpenALSoundSource();
- virtual ~OpenALSoundSource();
-
- virtual void play();
- virtual void stop();
- virtual bool playing();
-
- virtual void update();
-
- virtual void set_looping(bool looping);
- virtual void set_gain(float gain);
- virtual void set_pitch(float pitch);
- virtual void set_position(const Vector& position);
- virtual void set_velocity(const Vector& position);
- virtual void set_reference_distance(float distance);
- virtual void set_rollof_factor(float factor);
-
-protected:
- friend class SoundManager;
-
- ALuint source;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-/** Used SDL_mixer and glest source as reference */
-#include <config.h>
-
-#include "sound_file.hpp"
-
-#include <stdio.h>
-#include <stdint.h>
-#include <algorithm>
-#include <stdexcept>
-#include <sstream>
-#include <assert.h>
-#include <physfs.h>
-#include <vorbis/codec.h>
-#include <vorbis/vorbisfile.h>
-#include "log.hpp"
-#include "lisp/parser.hpp"
-#include "lisp/lisp.hpp"
-#include "file_system.hpp"
-
-class WavSoundFile : public SoundFile
-{
-public:
- WavSoundFile(PHYSFS_file* file);
- ~WavSoundFile();
-
- size_t read(void* buffer, size_t buffer_size);
- void reset();
-
-private:
- PHYSFS_file* file;
-
- PHYSFS_sint64 datastart;
-};
-
-static inline uint32_t read32LE(PHYSFS_file* file)
-{
- uint32_t result;
- if(PHYSFS_readULE32(file, &result) == 0)
- throw std::runtime_error("file too short");
-
- return result;
-}
-
-static inline uint16_t read16LE(PHYSFS_file* file)
-{
- uint16_t result;
- if(PHYSFS_readULE16(file, &result) == 0)
- throw std::runtime_error("file too short");
-
- return result;
-}
-
-WavSoundFile::WavSoundFile(PHYSFS_file* file)
-{
- this->file = file;
-
- char magic[4];
- if(PHYSFS_read(file, magic, sizeof(magic), 1) != 1)
- throw std::runtime_error("Couldn't read file magic (not a wave file)");
- if(strncmp(magic, "RIFF", 4) != 0) {
- log_debug << "MAGIC: " << magic << std::endl;
- throw std::runtime_error("file is not a RIFF wav file");
- }
-
- uint32_t wavelen = read32LE(file);
- (void) wavelen;
-
- if(PHYSFS_read(file, magic, sizeof(magic), 1) != 1)
- throw std::runtime_error("Couldn't read chunk header (not a wav file?)");
- if(strncmp(magic, "WAVE", 4) != 0)
- throw std::runtime_error("file is not a valid RIFF/WAVE file");
-
- char chunkmagic[4];
- uint32_t chunklen;
-
- // search audio data format chunk
- do {
- if(PHYSFS_read(file, chunkmagic, sizeof(chunkmagic), 1) != 1)
- throw std::runtime_error("EOF while searching format chunk");
- chunklen = read32LE(file);
-
- if(strncmp(chunkmagic, "fmt ", 4) == 0)
- break;
-
- if(strncmp(chunkmagic, "fact", 4) == 0
- || strncmp(chunkmagic, "LIST", 4) == 0) {
- // skip chunk
- if(PHYSFS_seek(file, PHYSFS_tell(file) + chunklen) == 0)
- throw std::runtime_error("EOF while searching fmt chunk");
- } else {
- throw std::runtime_error("complex WAVE files not supported");
- }
- } while(true);
-
- if(chunklen < 16)
- throw std::runtime_error("Format chunk too short");
-
- // parse format
- uint16_t encoding = read16LE(file);
- if(encoding != 1)
- throw std::runtime_error("only PCM encoding supported");
- channels = read16LE(file);
- rate = read32LE(file);
- uint32_t byterate = read32LE(file);
- (void) byterate;
- uint16_t blockalign = read16LE(file);
- (void) blockalign;
- bits_per_sample = read16LE(file);
-
- if(chunklen > 16) {
- if(PHYSFS_seek(file, PHYSFS_tell(file) + (chunklen-16)) == 0)
- throw std::runtime_error("EOF while reading reast of format chunk");
- }
-
- // set file offset to DATA chunk data
- do {
- if(PHYSFS_read(file, chunkmagic, sizeof(chunkmagic), 1) != 1)
- throw std::runtime_error("EOF while searching data chunk");
- chunklen = read32LE(file);
-
- if(strncmp(chunkmagic, "data", 4) == 0)
- break;
-
- // skip chunk
- if(PHYSFS_seek(file, PHYSFS_tell(file) + chunklen) == 0)
- throw std::runtime_error("EOF while searching fmt chunk");
- } while(true);
-
- datastart = PHYSFS_tell(file);
- size = static_cast<size_t> (chunklen);
-}
-
-WavSoundFile::~WavSoundFile()
-{
- PHYSFS_close(file);
-}
-
-void
-WavSoundFile::reset()
-{
- if(PHYSFS_seek(file, datastart) == 0)
- throw std::runtime_error("Couldn't seek to data start");
-}
-
-size_t
-WavSoundFile::read(void* buffer, size_t buffer_size)
-{
- PHYSFS_sint64 end = datastart + size;
- PHYSFS_sint64 cur = PHYSFS_tell(file);
- if(cur >= end)
- return 0;
-
- size_t readsize = std::min(static_cast<size_t> (end - cur), buffer_size);
- if(PHYSFS_read(file, buffer, readsize, 1) != 1)
- throw std::runtime_error("read error while reading samples");
-
-#ifdef WORDS_BIGENDIAN
- if (bits_per_sample != 16)
- return readsize;
- char *tmp = (char*)buffer;
-
- size_t i;
- char c;
- for (i = 0; i < readsize / 2; i++)
- {
- c = tmp[2*i];
- tmp[2*i] = tmp[2*i+1];
- tmp[2*i+1] = c;
- }
-
- buffer = tmp;
-#endif
-
- return readsize;
-}
-
-//---------------------------------------------------------------------------
-
-class OggSoundFile : public SoundFile
-{
-public:
- OggSoundFile(PHYSFS_file* file, double loop_begin, double loop_at);
- ~OggSoundFile();
-
- size_t read(void* buffer, size_t buffer_size);
- void reset();
-
-private:
- static size_t cb_read(void* ptr, size_t size, size_t nmemb, void* source);
- static int cb_seek(void* source, ogg_int64_t offset, int whence);
- static int cb_close(void* source);
- static long cb_tell(void* source);
-
- PHYSFS_file* file;
- OggVorbis_File vorbis_file;
- ogg_int64_t loop_begin;
- ogg_int64_t loop_at;
- size_t normal_buffer_loop;
-};
-
-OggSoundFile::OggSoundFile(PHYSFS_file* file, double loop_begin, double loop_at)
-{
- this->file = file;
-
- ov_callbacks callbacks = { cb_read, cb_seek, cb_close, cb_tell };
- ov_open_callbacks(file, &vorbis_file, 0, 0, callbacks);
-
- vorbis_info* vi = ov_info(&vorbis_file, -1);
-
- channels = vi->channels;
- rate = vi->rate;
- bits_per_sample = 16;
- size = static_cast<size_t> (ov_pcm_total(&vorbis_file, -1) * 2);
-
- double sample_len = 1.0f / rate;
- double samples_begin = loop_begin / sample_len;
- double sample_loop = loop_at / sample_len;
-
- this->loop_begin = (ogg_int64_t) samples_begin;
- if(loop_begin < 0) {
- this->loop_at = (ogg_int64_t) -1;
- } else {
- this->loop_at = (ogg_int64_t) sample_loop;
- }
-}
-
-OggSoundFile::~OggSoundFile()
-{
- ov_clear(&vorbis_file);
-}
-
-size_t
-OggSoundFile::read(void* _buffer, size_t buffer_size)
-{
- char* buffer = reinterpret_cast<char*> (_buffer);
- int section = 0;
- size_t totalBytesRead = 0;
-
- while(buffer_size>0) {
-#ifdef WORDS_BIGENDIAN
- int bigendian = 1;
-#else
- int bigendian = 0;
-#endif
-
- size_t bytes_to_read = buffer_size;
- if(loop_at > 0) {
- size_t bytes_per_sample = 2;
- ogg_int64_t time = ov_pcm_tell(&vorbis_file);
- ogg_int64_t samples_left_till_loop = loop_at - time;
- ogg_int64_t bytes_left_till_loop
- = samples_left_till_loop * bytes_per_sample;
- if(bytes_left_till_loop <= 4)
- break;
-
- if(bytes_left_till_loop < (ogg_int64_t) bytes_to_read) {
- bytes_to_read = (size_t) bytes_left_till_loop;
- }
- }
-
- long bytesRead
- = ov_read(&vorbis_file, buffer, bytes_to_read, bigendian,
- 2, 1, §ion);
- if(bytesRead == 0) {
- break;
- }
- buffer_size -= bytesRead;
- buffer += bytesRead;
- totalBytesRead += bytesRead;
- }
-
- return totalBytesRead;
-}
-
-void
-OggSoundFile::reset()
-{
- ov_pcm_seek(&vorbis_file, loop_begin);
-}
-
-size_t
-OggSoundFile::cb_read(void* ptr, size_t size, size_t nmemb, void* source)
-{
- PHYSFS_file* file = reinterpret_cast<PHYSFS_file*> (source);
-
- PHYSFS_sint64 res
- = PHYSFS_read(file, ptr, static_cast<PHYSFS_uint32> (size),
- static_cast<PHYSFS_uint32> (nmemb));
- if(res <= 0)
- return 0;
-
- return static_cast<size_t> (res);
-}
-
-int
-OggSoundFile::cb_seek(void* source, ogg_int64_t offset, int whence)
-{
- PHYSFS_file* file = reinterpret_cast<PHYSFS_file*> (source);
-
- switch(whence) {
- case SEEK_SET:
- if(PHYSFS_seek(file, static_cast<PHYSFS_uint64> (offset)) == 0)
- return -1;
- break;
- case SEEK_CUR:
- if(PHYSFS_seek(file, PHYSFS_tell(file) + offset) == 0)
- return -1;
- break;
- case SEEK_END:
- if(PHYSFS_seek(file, PHYSFS_fileLength(file) + offset) == 0)
- return -1;
- break;
- default:
-#ifdef DEBUG
- assert(false);
-#else
- return -1;
-#endif
- }
- return 0;
-}
-
-int
-OggSoundFile::cb_close(void* source)
-{
- PHYSFS_file* file = reinterpret_cast<PHYSFS_file*> (source);
- PHYSFS_close(file);
- return 0;
-}
-
-long
-OggSoundFile::cb_tell(void* source)
-{
- PHYSFS_file* file = reinterpret_cast<PHYSFS_file*> (source);
- return static_cast<long> (PHYSFS_tell(file));
-}
-
-//---------------------------------------------------------------------------
-
-SoundFile* load_music_file(const std::string& filename)
-{
- lisp::Parser parser(false);
- const lisp::Lisp* root = parser.parse(filename);
- const lisp::Lisp* music = root->get_lisp("supertux-music");
- if(music == NULL)
- throw std::runtime_error("file is not a supertux-music file.");
-
- std::string raw_music_file;
- float loop_begin = 0;
- float loop_at = -1;
-
- music->get("file", raw_music_file);
- music->get("loop-begin", loop_begin);
- music->get("loop-at", loop_at);
-
- if(loop_begin < 0) {
- throw std::runtime_error("can't loop from negative value");
- }
-
- std::string basedir = FileSystem::dirname(filename);
- raw_music_file = FileSystem::normalize(basedir + raw_music_file);
-
- PHYSFS_file* file = PHYSFS_openRead(raw_music_file.c_str());
- if(!file) {
- std::stringstream msg;
- msg << "Couldn't open '" << raw_music_file << "': " << PHYSFS_getLastError();
- throw std::runtime_error(msg.str());
- }
-
- return new OggSoundFile(file, loop_begin, loop_at);
-}
-
-SoundFile* load_sound_file(const std::string& filename)
-{
- if(filename.length() > 6
- && filename.compare(filename.length()-6, 6, ".music") == 0) {
- return load_music_file(filename);
- }
-
- PHYSFS_file* file = PHYSFS_openRead(filename.c_str());
- if(!file) {
- std::stringstream msg;
- msg << "Couldn't open '" << filename << "': " << PHYSFS_getLastError();
- throw std::runtime_error(msg.str());
- }
-
- try {
- char magic[4];
- if(PHYSFS_read(file, magic, sizeof(magic), 1) != 1)
- throw std::runtime_error("Couldn't read magic, file too short");
- PHYSFS_seek(file, 0);
- if(strncmp(magic, "RIFF", 4) == 0)
- return new WavSoundFile(file);
- else if(strncmp(magic, "OggS", 4) == 0)
- return new OggSoundFile(file, 0, -1);
- else
- throw std::runtime_error("Unknown file format");
- } catch(std::exception& e) {
- std::stringstream msg;
- msg << "Couldn't read '" << filename << "': " << e.what();
- throw std::runtime_error(msg.str());
- }
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __SOUND_FILE_H__
-#define __SOUND_FILE_H__
-
-#include <stdio.h>
-#include <iostream>
-
-class SoundFile
-{
-public:
- virtual ~SoundFile()
- { }
-
- virtual size_t read(void* buffer, size_t buffer_size) = 0;
- virtual void reset() = 0;
-
- int channels;
- int rate;
- int bits_per_sample;
- /// size in bytes
- size_t size;
-};
-
-SoundFile* load_sound_file(const std::string& filename);
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#include <config.h>
-
-#include "sound_manager.hpp"
-
-#include <stdexcept>
-#include <iostream>
-#include <sstream>
-#include <memory>
-#include <assert.h>
-#include <SDL.h>
-
-#include "sound_file.hpp"
-#include "sound_source.hpp"
-#include "openal_sound_source.hpp"
-#include "stream_sound_source.hpp"
-#include "dummy_sound_source.hpp"
-#include "log.hpp"
-#include "timer.hpp"
-
-#ifndef DEBUG
- /** Older openal versions often miss this function and it isn't that vital for
- * supertux...
- */
-#ifdef alcGetString
-#undef alcGetString
-#endif
-#define alcGetString(x,y) ""
-#endif
-
-SoundManager* sound_manager = 0;
-
-SoundManager::SoundManager()
- : device(0), context(0), sound_enabled(false), music_source(0),
- music_enabled(false)
-{
- try {
- device = alcOpenDevice(0);
- if (device == NULL) {
- throw std::runtime_error("Couldn't open audio device.");
- }
-
- int attributes[] = { 0 };
- context = alcCreateContext(device, attributes);
- check_alc_error("Couldn't create audio context: ");
- alcMakeContextCurrent(context);
- check_alc_error("Couldn't select audio context: ");
-
- check_al_error("Audio error after init: ");
- sound_enabled = true;
- music_enabled = true;
- } catch(std::exception& e) {
- if(context != NULL)
- alcDestroyContext(context);
- context = NULL;
- if(device != NULL)
- alcCloseDevice(device);
- device = NULL;
- log_warning << "Couldn't initialize audio device: " << e.what() << std::endl;
- print_openal_version();
- }
-}
-
-SoundManager::~SoundManager()
-{
- delete music_source;
-
- for(SoundSources::iterator i = sources.begin(); i != sources.end(); ++i) {
- delete *i;
- }
-
- for(SoundBuffers::iterator i = buffers.begin(); i != buffers.end(); ++i) {
- ALuint buffer = i->second;
- alDeleteBuffers(1, &buffer);
- }
-
- if(context != NULL) {
- alcDestroyContext(context);
- }
- if(device != NULL) {
- alcCloseDevice(device);
- }
-}
-
-ALuint
-SoundManager::load_file_into_buffer(SoundFile* file)
-{
- ALenum format = get_sample_format(file);
- ALuint buffer;
- alGenBuffers(1, &buffer);
- check_al_error("Couldn't create audio buffer: ");
- char* samples = new char[file->size];
- try {
- file->read(samples, file->size);
- alBufferData(buffer, format, samples,
- static_cast<ALsizei> (file->size),
- static_cast<ALsizei> (file->rate));
- check_al_error("Couldn't fill audio buffer: ");
- } catch(...) {
- delete[] samples;
- throw;
- }
- delete[] samples;
-
- return buffer;
-}
-
-OpenALSoundSource*
-SoundManager::intern_create_sound_source(const std::string& filename)
-{
- if(!sound_enabled)
- throw std::runtime_error("sound disabled");
-
- std::auto_ptr<OpenALSoundSource> source (new OpenALSoundSource());
-
- ALuint buffer;
-
- // reuse an existing static sound buffer
- SoundBuffers::iterator i = buffers.find(filename);
- if(i != buffers.end()) {
- buffer = i->second;
- } else {
- // Load sound file
- std::auto_ptr<SoundFile> file (load_sound_file(filename));
-
- if(file->size < 100000) {
- buffer = load_file_into_buffer(file.get());
- buffers.insert(std::make_pair(filename, buffer));
- } else {
- StreamSoundSource* source = new StreamSoundSource();
- source->set_sound_file(file.release());
- return source;
- }
- }
-
- alSourcei(source->source, AL_BUFFER, buffer);
- return source.release();
-}
-
-SoundSource*
-SoundManager::create_sound_source(const std::string& filename)
-{
- if(!sound_enabled)
- return create_dummy_sound_source();
-
- try {
- return intern_create_sound_source(filename);
- } catch(std::exception &e) {
- log_warning << "Couldn't create audio source: " << e.what() << std::endl;
- return create_dummy_sound_source();
- }
-}
-
-void
-SoundManager::preload(const std::string& filename)
-{
- if(!sound_enabled)
- return;
-
- SoundBuffers::iterator i = buffers.find(filename);
- // already loaded?
- if(i != buffers.end())
- return;
-
- std::auto_ptr<SoundFile> file (load_sound_file(filename));
- // only keep small files
- if(file->size >= 100000)
- return;
-
- ALuint buffer = load_file_into_buffer(file.get());
- buffers.insert(std::make_pair(filename, buffer));
-}
-
-void
-SoundManager::play(const std::string& filename, const Vector& pos)
-{
- if(!sound_enabled)
- return;
-
- try {
- std::auto_ptr<OpenALSoundSource> source
- (intern_create_sound_source(filename));
-
- if(pos == Vector(-1, -1)) {
- source->set_rollof_factor(0);
- } else {
- source->set_position(pos);
- }
- source->play();
- sources.push_back(source.release());
- } catch(std::exception& e) {
- log_warning << "Couldn't play sound " << filename << ": " << e.what() << std::endl;
- }
-}
-
-void
-SoundManager::manage_source(SoundSource* source)
-{
- assert(source != NULL);
-
- OpenALSoundSource* openal_source = dynamic_cast<OpenALSoundSource*> (source);
- if(openal_source != NULL) {
- sources.push_back(openal_source);
- }
-}
-
-void
-SoundManager::register_for_update( StreamSoundSource* sss ){
- if( sss != NULL ){
- update_list.push_back( sss );
- }
-}
-
-void
-SoundManager::remove_from_update( StreamSoundSource* sss ){
- if( sss != NULL ){
- StreamSoundSources::iterator i = update_list.begin();
- while( i != update_list.end() ){
- if( *i == sss ){
- i = update_list.erase(i);
- } else {
- i++;
- }
- }
- }
-}
-
-void
-SoundManager::enable_sound(bool enable)
-{
- if(device == NULL)
- return;
-
- sound_enabled = enable;
-}
-
-void
-SoundManager::enable_music(bool enable)
-{
- if(device == NULL)
- return;
-
- music_enabled = enable;
- if(music_enabled) {
- play_music(current_music);
- } else {
- if(music_source) {
- delete music_source;
- music_source = 0;
- }
- }
-}
-
-void
-SoundManager::stop_music(float fadetime)
-{
- if(fadetime > 0) {
- if(music_source
- && music_source->get_fade_state() != StreamSoundSource::FadingOff)
- music_source->set_fading(StreamSoundSource::FadingOff, fadetime);
- } else {
- delete music_source;
- music_source = NULL;
- }
- current_music = "";
-}
-
-void
-SoundManager::play_music(const std::string& filename, bool fade)
-{
- if(filename == current_music && music_source != NULL)
- return;
- current_music = filename;
- if(!music_enabled)
- return;
-
- if(filename == "") {
- delete music_source;
- music_source = NULL;
- return;
- }
-
- try {
- std::auto_ptr<StreamSoundSource> newmusic (new StreamSoundSource());
- alSourcef(newmusic->source, AL_ROLLOFF_FACTOR, 0);
- newmusic->set_sound_file(load_sound_file(filename));
- newmusic->set_looping(true);
- if(fade)
- newmusic->set_fading(StreamSoundSource::FadingOn, .5f);
- newmusic->play();
-
- delete music_source;
- music_source = newmusic.release();
- } catch(std::exception& e) {
- log_warning << "Couldn't play music file '" << filename << "': " << e.what() << std::endl;
- }
-}
-
-void
-SoundManager::set_listener_position(const Vector& pos)
-{
- static Uint32 lastticks = SDL_GetTicks();
-
- Uint32 current_ticks = SDL_GetTicks();
- if(current_ticks - lastticks < 300)
- return;
- lastticks = current_ticks;
-
- alListener3f(AL_POSITION, pos.x, pos.y, 0);
-}
-
-void
-SoundManager::set_listener_velocity(const Vector& vel)
-{
- alListener3f(AL_VELOCITY, vel.x, vel.y, 0);
-}
-
-void
-SoundManager::update()
-{
- static Uint32 lasttime = SDL_GetTicks();
- Uint32 now = SDL_GetTicks();
-
- if(now - lasttime < 300)
- return;
- lasttime = now;
-
- // update and check for finished sound sources
- for(SoundSources::iterator i = sources.begin(); i != sources.end(); ) {
- OpenALSoundSource* source = *i;
-
- source->update();
-
- if(!source->playing()) {
- delete source;
- i = sources.erase(i);
- } else {
- ++i;
- }
- }
- // check streaming sounds
- if(music_source) {
- music_source->update();
- }
-
- if (context)
- {
- alcProcessContext(context);
- check_alc_error("Error while processing audio context: ");
- }
-
- //run update() for stream_sound_source
- StreamSoundSources::iterator s = update_list.begin();
- while( s != update_list.end() ){
- (*s)->update();
- s++;
- }
-}
-
-ALenum
-SoundManager::get_sample_format(SoundFile* file)
-{
- if(file->channels == 2) {
- if(file->bits_per_sample == 16) {
- return AL_FORMAT_STEREO16;
- } else if(file->bits_per_sample == 8) {
- return AL_FORMAT_STEREO8;
- } else {
- throw std::runtime_error("Only 16 and 8 bit samples supported");
- }
- } else if(file->channels == 1) {
- if(file->bits_per_sample == 16) {
- return AL_FORMAT_MONO16;
- } else if(file->bits_per_sample == 8) {
- return AL_FORMAT_MONO8;
- } else {
- throw std::runtime_error("Only 16 and 8 bit samples supported");
- }
- }
-
- throw std::runtime_error("Only 1 and 2 channel samples supported");
-}
-
-void
-SoundManager::print_openal_version()
-{
- log_info << "OpenAL Vendor: " << alGetString(AL_VENDOR) << std::endl;
- log_info << "OpenAL Version: " << alGetString(AL_VERSION) << std::endl;
- log_info << "OpenAL Renderer: " << alGetString(AL_RENDERER) << std::endl;
- log_info << "OpenAl Extensions: " << alGetString(AL_EXTENSIONS) << std::endl;
-}
-
-void
-SoundManager::check_alc_error(const char* message)
-{
- int err = alcGetError(device);
- if(err != ALC_NO_ERROR) {
- std::stringstream msg;
- msg << message << alcGetString(device, err);
- throw std::runtime_error(msg.str());
- }
-}
-
-void
-SoundManager::check_al_error(const char* message)
-{
- int err = alGetError();
- if(err != AL_NO_ERROR) {
- std::stringstream msg;
- msg << message << alGetString(err);
- throw std::runtime_error(msg.str());
- }
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#ifndef __SOUND_MANAGER_H__
-#define __SOUND_MANAGER_H__
-
-#include <string>
-#include <vector>
-#include <map>
-
-#ifndef MACOSX
-#include <AL/alc.h>
-#include <AL/al.h>
-#else
-#include <OpenAL/alc.h>
-#include <OpenAL/al.h>
-#endif
-
-#include "math/vector.hpp"
-
-class SoundFile;
-class SoundSource;
-class StreamSoundSource;
-class OpenALSoundSource;
-
-class SoundManager
-{
-public:
- SoundManager();
- virtual ~SoundManager();
-
- void enable_sound(bool sound_enabled);
- /**
- * Creates a new sound source object which plays the specified soundfile.
- * You are responsible for deleting the sound source later (this will stop the
- * sound).
- * This function never throws exceptions, but might return a DummySoundSource
- */
- SoundSource* create_sound_source(const std::string& filename);
- /**
- * Convenience function to simply play a sound at a given position.
- */
- void play(const std::string& name, const Vector& pos = Vector(-1, -1));
- /**
- * Adds the source to the list of managed sources (= the source gets deleted
- * when it finished playing)
- */
- void manage_source(SoundSource* source);
- /// preloads a sound, so that you don't get a lag later when playing it
- void preload(const std::string& name);
-
- void set_listener_position(const Vector& position);
- void set_listener_velocity(const Vector& velocity);
-
- void enable_music(bool music_enabled);
- void play_music(const std::string& filename, bool fade = false);
- void stop_music(float fadetime = 0);
-
- bool is_music_enabled() { return music_enabled; }
- bool is_sound_enabled() { return sound_enabled; }
-
- bool is_audio_enabled() {
- return device != 0 && context != 0;
- }
-
- void update();
-
- /*
- * Tell soundmanager to call update() for stream_sound_source.
- */
- void register_for_update( StreamSoundSource* sss );
- /*
- * Unsubscribe from updates for stream_sound_source.
- */
- void remove_from_update( StreamSoundSource* sss );
-
-private:
- friend class OpenALSoundSource;
- friend class StreamSoundSource;
-
- /** creates a new sound source, might throw exceptions, never returns NULL */
- OpenALSoundSource* intern_create_sound_source(const std::string& filename);
- static ALuint load_file_into_buffer(SoundFile* file);
- static ALenum get_sample_format(SoundFile* file);
-
- void print_openal_version();
- void check_alc_error(const char* message);
- static void check_al_error(const char* message);
-
- ALCdevice* device;
- ALCcontext* context;
- bool sound_enabled;
-
- typedef std::map<std::string, ALuint> SoundBuffers;
- SoundBuffers buffers;
- typedef std::vector<OpenALSoundSource*> SoundSources;
- SoundSources sources;
-
- typedef std::vector<StreamSoundSource*> StreamSoundSources;
- StreamSoundSources update_list;
-
- StreamSoundSource* music_source;
-
- bool music_enabled;
- std::string current_music;
-};
-
-extern SoundManager* sound_manager;
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#ifndef __SOUND_SOURCE_H__
-#define __SOUND_SOURCE_H__
-
-#include "math/vector.hpp"
-
-/**
- * A sound source represents the source of audio output. You can place
- * sources at certain points in your world or set their velocity to produce
- * doppler effects
- */
-class SoundSource
-{
-public:
- virtual ~SoundSource()
- { }
-
- virtual void play() = 0;
- virtual void stop() = 0;
- virtual bool playing() = 0;
-
- virtual void set_looping(bool looping) = 0;
- /// Set volume (0.0 is silent, 1.0 is normal)
- virtual void set_gain(float gain) = 0;
- virtual void set_pitch(float pitch) = 0;
- virtual void set_position(const Vector& position) = 0;
- virtual void set_velocity(const Vector& position) = 0;
- virtual void set_reference_distance(float distance) = 0;
- virtual void set_rollof_factor(float factor) = 0;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-#include <assert.h>
-
-#include <SDL.h>
-
-#include "stream_sound_source.hpp"
-#include "sound_manager.hpp"
-#include "sound_file.hpp"
-#include "timer.hpp"
-#include "log.hpp"
-
-StreamSoundSource::StreamSoundSource()
- : file(0), fade_state(NoFading), looping(false)
-{
- alGenBuffers(STREAMFRAGMENTS, buffers);
- SoundManager::check_al_error("Couldn't allocate audio buffers: ");
- //add me to update list
- sound_manager->register_for_update( this );
-}
-
-StreamSoundSource::~StreamSoundSource()
-{
- //don't update me any longer
- sound_manager->remove_from_update( this );
- delete file;
- stop();
- alDeleteBuffers(STREAMFRAGMENTS, buffers);
- SoundManager::check_al_error("Couldn't delete audio buffers: ");
-}
-
-void
-StreamSoundSource::set_sound_file(SoundFile* newfile)
-{
- delete file;
- file = newfile;
-
- ALint queued;
- alGetSourcei(source, AL_BUFFERS_QUEUED, &queued);
- for(size_t i = 0; i < STREAMFRAGMENTS - queued; ++i) {
- if(fillBufferAndQueue(buffers[i]) == false)
- break;
- }
-}
-
-void
-StreamSoundSource::update()
-{
- ALint processed = 0;
- alGetSourcei(source, AL_BUFFERS_PROCESSED, &processed);
- for(ALint i = 0; i < processed; ++i) {
- ALuint buffer;
- alSourceUnqueueBuffers(source, 1, &buffer);
- SoundManager::check_al_error("Couldn't unqueu audio buffer: ");
-
- if(fillBufferAndQueue(buffer) == false)
- break;
- }
-
- if(!playing()) {
- if(processed == 0 || !looping)
- return;
-
- // we might have to restart the source if we had a buffer underrun
- log_info << "Restarting audio source because of buffer underrun" << std::endl;
- play();
- }
-
- if(fade_state == FadingOn) {
- float time = real_time - fade_start_time;
- if(time >= fade_time) {
- set_gain(1.0);
- fade_state = NoFading;
- } else {
- set_gain(time / fade_time);
- }
- } else if(fade_state == FadingOff) {
- float time = real_time - fade_start_time;
- if(time >= fade_time) {
- stop();
- fade_state = NoFading;
- } else {
- set_gain( (fade_time-time) / fade_time);
- }
- }
-}
-
-void
-StreamSoundSource::set_fading(FadeState state, float fade_time)
-{
- this->fade_state = state;
- this->fade_time = fade_time;
- this->fade_start_time = real_time;
-}
-
-bool
-StreamSoundSource::fillBufferAndQueue(ALuint buffer)
-{
- // fill buffer
- char* bufferdata = new char[STREAMFRAGMENTSIZE];
- size_t bytesread = 0;
- do {
- bytesread += file->read(bufferdata + bytesread,
- STREAMFRAGMENTSIZE - bytesread);
- // end of sound file
- if(bytesread < STREAMFRAGMENTSIZE) {
- if(looping)
- file->reset();
- else
- break;
- }
- } while(bytesread < STREAMFRAGMENTSIZE);
-
- if(bytesread > 0) {
- ALenum format = SoundManager::get_sample_format(file);
- alBufferData(buffer, format, bufferdata, bytesread, file->rate);
- SoundManager::check_al_error("Couldn't refill audio buffer: ");
-
- alSourceQueueBuffers(source, 1, &buffer);
- SoundManager::check_al_error("Couldn't queue audio buffer: ");
- }
- delete[] bufferdata;
-
- // return false if there aren't more buffers to fill
- return bytesread >= STREAMFRAGMENTSIZE;
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __STREAM_SOUND_SOURCE_H__
-#define __STREAM_SOUND_SOURCE_H__
-
-#include <stdio.h>
-#include <SDL.h>
-#include "openal_sound_source.hpp"
-
-class SoundFile;
-
-class StreamSoundSource : public OpenALSoundSource
-{
-public:
- StreamSoundSource();
- virtual ~StreamSoundSource();
-
- void set_sound_file(SoundFile* file);
-
- enum FadeState { NoFading, FadingOn, FadingOff };
-
- void set_fading(FadeState state, float fadetime);
- FadeState get_fade_state() const
- {
- return fade_state;
- }
- void update();
-
- void set_looping(bool looping)
- {
- this->looping = looping;
- }
- bool get_looping() const
- {
- return looping;
- }
-
-private:
- static const size_t STREAMBUFFERSIZE = 1024 * 500;
- static const size_t STREAMFRAGMENTS = 5;
- static const size_t STREAMFRAGMENTSIZE
- = STREAMBUFFERSIZE / STREAMFRAGMENTS;
-
- bool fillBufferAndQueue(ALuint buffer);
- SoundFile* file;
- ALuint buffers[STREAMFRAGMENTS];
-
- FadeState fade_state;
- float fade_start_time;
- float fade_time;
- bool looping;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// AngryStone - A spiked block that charges towards the player
-// Copyright (C) 2006 Christoph Sommer <supertux@2006.expires.deltadevelopment.de>
-//
-// 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.
-
-#include <config.h>
-
-#include "angrystone.hpp"
-
-static const float SPEED = 240;
-
-static const float CHARGE_TIME = .5;
-static const float ATTACK_TIME = 1;
-static const float RECOVER_TIME = .5;
-
-AngryStone::AngryStone(const lisp::Lisp& reader)
- : BadGuy(reader, "images/creatures/angrystone/angrystone.sprite"), state(IDLE)
-{
-}
-
-void
-AngryStone::write(lisp::Writer& writer)
-{
- writer.start_list("angrystone");
-
- writer.write_float("x", start_position.x);
- writer.write_float("y", start_position.y);
-
- writer.end_list("angrystone");
-}
-
-void
-AngryStone::activate()
-{
- physic.set_velocity_x(0);
- physic.set_velocity_y(0);
- physic.enable_gravity(true);
- sprite->set_action("idle");
-}
-
-void
-AngryStone::collision_solid(const CollisionHit& hit)
-{
- // TODO
- (void) hit;
-#if 0
- if ((state == ATTACKING) &&
- (hit.normal.x == -attackDirection.x) && (hit.normal.y == attackDirection.y)) {
- state = IDLE;
- sprite->set_action("idle");
- physic.set_velocity_x(0);
- physic.set_velocity_y(0);
- physic.enable_gravity(true);
- oldWallDirection.x = attackDirection.x;
- oldWallDirection.y = attackDirection.y;
- }
-#endif
-}
-
-void
-AngryStone::kill_fall()
-{
- //prevents AngryStone from getting killed by other enemies or the player
-}
-
-HitResponse
-AngryStone::collision_badguy(BadGuy& badguy, const CollisionHit& )
-{
- if (state == ATTACKING) {
- badguy.kill_fall();
- return FORCE_MOVE;
- }
-
- return FORCE_MOVE;
-}
-
-void
-AngryStone::active_update(float elapsed_time) {
- BadGuy::active_update(elapsed_time);
-
- if (state == IDLE) {
- MovingObject* player = this->get_nearest_player();
- MovingObject* badguy = this;
- const Vector playerPos = player->get_pos();
- const Vector badguyPos = badguy->get_pos();
- float dx = (playerPos.x - badguyPos.x);
- float dy = (playerPos.y - badguyPos.y);
-
- float playerHeight = player->get_bbox().p2.y - player->get_bbox().p1.y;
- float badguyHeight = badguy->get_bbox().p2.y - badguy->get_bbox().p1.y;
-
- float playerWidth = player->get_bbox().p2.x - player->get_bbox().p1.x;
- float badguyWidth = badguy->get_bbox().p2.x - badguy->get_bbox().p1.x;
-
- if ((dx > -playerWidth) && (dx < badguyWidth)) {
- if (dy > 0) {
- attackDirection.x = 0;
- attackDirection.y = 1;
- } else {
- attackDirection.x = 0;
- attackDirection.y = -1;
- }
- if ((attackDirection.x != oldWallDirection.x) || (attackDirection.y != oldWallDirection.y)) {
- sprite->set_action("charging");
- timer.start(CHARGE_TIME);
- state = CHARGING;
- }
- } else
- if ((dy > -playerHeight) && (dy < badguyHeight)) {
- if (dx > 0) {
- attackDirection.x = 1;
- attackDirection.y = 0;
- } else {
- attackDirection.x = -1;
- attackDirection.y = 0;
- }
- if ((attackDirection.x != oldWallDirection.x) || (attackDirection.y != oldWallDirection.y)) {
- sprite->set_action("charging");
- timer.start(CHARGE_TIME);
- state = CHARGING;
- }
- }
-
- }
-
- if (state == CHARGING) {
- if (timer.check()) {
- sprite->set_action("attacking");
- timer.start(ATTACK_TIME);
- state = ATTACKING;
- physic.enable_gravity(false);
- physic.set_velocity_x(SPEED * attackDirection.x);
- physic.set_velocity_y(SPEED * attackDirection.y);
- oldWallDirection.x = 0;
- oldWallDirection.y = 0;
- }
- }
-
- if (state == ATTACKING) {
- if (timer.check()) {
- timer.start(RECOVER_TIME);
- state = RECOVERING;
- sprite->set_action("idle");
- physic.enable_gravity(true);
- physic.set_velocity_x(0);
- physic.set_velocity_y(0);
- }
- }
-
- if (state == RECOVERING) {
- if (timer.check()) {
- state = IDLE;
- sprite->set_action("idle");
- physic.enable_gravity(true);
- physic.set_velocity_x(0);
- physic.set_velocity_y(0);
- }
- }
-
-}
-
-IMPLEMENT_FACTORY(AngryStone, "angrystone")
+++ /dev/null
-// $Id$
-//
-// AngryStone - A spiked block that charges towards the player
-// Copyright (C) 2006 Christoph Sommer <supertux@2006.expires.deltadevelopment.de>
-//
-// 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.
-
-#ifndef __ANGRYSTONE_H__
-#define __ANGRYSTONE_H__
-
-#include "badguy.hpp"
-
-class AngryStone : public BadGuy
-{
-public:
- AngryStone(const lisp::Lisp& reader);
-
- void activate();
- void write(lisp::Writer& writer);
- void collision_solid(const CollisionHit& hit);
- HitResponse collision_badguy(BadGuy& badguy, const CollisionHit& hit);
- void active_update(float elapsed_time);
- void kill_fall();
-
- virtual AngryStone* clone() const { return new AngryStone(*this); }
-
-protected:
- Vector attackDirection; /**< 1-normalized vector of current attack direction */
- Vector oldWallDirection; /**< if wall was hit during last attack: 1-normalized vector of last attack direction, (0,0) otherwise */
-
- Timer timer;
-
- enum AngryStoneState {
- IDLE,
- CHARGING,
- ATTACKING,
- RECOVERING
- };
- AngryStoneState state;
-
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#include <config.h>
-
-#include "badguy.hpp"
-#include "object/camera.hpp"
-#include "object/tilemap.hpp"
-#include "tile.hpp"
-#include "statistics.hpp"
-#include "game_session.hpp"
-#include "log.hpp"
-#include "level.hpp"
-#include "object/bullet.hpp"
-#include "main.hpp"
-#include "object/particles.hpp"
-#include "random_generator.hpp"
-
-static const float SQUISH_TIME = 2;
-static const float X_OFFSCREEN_DISTANCE = 1600;
-static const float Y_OFFSCREEN_DISTANCE = 1200;
-
-BadGuy::BadGuy(const Vector& pos, const std::string& sprite_name, int layer)
- : MovingSprite(pos, sprite_name, layer, COLGROUP_DISABLED), countMe(true),
- dir(LEFT), start_dir(AUTO), frozen(false), ignited(false),
- state(STATE_INIT), on_ground_flag(false)
-{
- start_position = bbox.p1;
-
- sound_manager->preload("sounds/squish.wav");
- sound_manager->preload("sounds/fall.wav");
-}
-
-BadGuy::BadGuy(const Vector& pos, Direction direction, const std::string& sprite_name, int layer)
- : MovingSprite(pos, sprite_name, layer, COLGROUP_DISABLED), countMe(true),
- dir(direction), start_dir(direction), frozen(false), ignited(false),
- state(STATE_INIT), on_ground_flag(false)
-{
- start_position = bbox.p1;
-
- sound_manager->preload("sounds/squish.wav");
- sound_manager->preload("sounds/fall.wav");
-}
-
-BadGuy::BadGuy(const lisp::Lisp& reader, const std::string& sprite_name, int layer)
- : MovingSprite(reader, sprite_name, layer, COLGROUP_DISABLED), countMe(true), dir(LEFT), start_dir(AUTO), frozen(false), ignited(false), state(STATE_INIT), on_ground_flag(false)
-{
- start_position = bbox.p1;
-
- std::string dir_str = "auto";
- reader.get("direction", dir_str);
- start_dir = str2dir( dir_str );
- dir = start_dir;
-
- reader.get("dead-script", dead_script);
-
- sound_manager->preload("sounds/squish.wav");
- sound_manager->preload("sounds/fall.wav");
-}
-
-void
-BadGuy::draw(DrawingContext& context)
-{
- if(!sprite)
- return;
- if(state == STATE_INIT || state == STATE_INACTIVE)
- return;
- if(state == STATE_FALLING) {
- DrawingEffect old_effect = context.get_drawing_effect();
- context.set_drawing_effect((DrawingEffect) (old_effect | VERTICAL_FLIP));
- sprite->draw(context, get_pos(), layer);
- context.set_drawing_effect(old_effect);
- } else {
- sprite->draw(context, get_pos(), layer);
- }
-}
-
-void
-BadGuy::update(float elapsed_time)
-{
- if(!Sector::current()->inside(bbox)) {
- remove_me();
- return;
- }
- if(is_offscreen()) {
- if (state == STATE_ACTIVE) deactivate();
- set_state(STATE_INACTIVE);
- }
-
- switch(state) {
- case STATE_ACTIVE:
- active_update(elapsed_time);
- break;
- case STATE_INIT:
- case STATE_INACTIVE:
- inactive_update(elapsed_time);
- try_activate();
- break;
- case STATE_SQUISHED:
- if(state_timer.check()) {
- remove_me();
- break;
- }
- movement = physic.get_movement(elapsed_time);
- break;
- case STATE_FALLING:
- movement = physic.get_movement(elapsed_time);
- break;
- }
-
- on_ground_flag = false;
-}
-
-Direction
-BadGuy::str2dir( std::string dir_str )
-{
- if( dir_str == "auto" )
- return AUTO;
- if( dir_str == "left" )
- return LEFT;
- if( dir_str == "right" )
- return RIGHT;
-
- //default to "auto"
- log_warning << "Badguy::str2dir: unknown direction \"" << dir_str << "\"" << std::endl;;
- return AUTO;
-}
-
-void
-BadGuy::activate()
-{
-}
-
-void
-BadGuy::deactivate()
-{
-}
-
-void
-BadGuy::write(lisp::Writer& )
-{
- log_warning << "tried to write out a generic badguy" << std::endl;
-}
-
-void
-BadGuy::active_update(float elapsed_time)
-{
- movement = physic.get_movement(elapsed_time);
-}
-
-void
-BadGuy::inactive_update(float )
-{
-}
-
-void
-BadGuy::collision_tile(uint32_t tile_attributes)
-{
- if(tile_attributes & Tile::HURTS) {
- if (tile_attributes & Tile::FIRE) {
- if (is_flammable()) ignite();
- }
- else if (tile_attributes & Tile::ICE) {
- if (is_freezable()) freeze();
- }
- else {
- kill_fall();
- }
- }
-}
-
-HitResponse
-BadGuy::collision(GameObject& other, const CollisionHit& hit)
-{
- switch(state) {
- case STATE_INIT:
- case STATE_INACTIVE:
- return ABORT_MOVE;
- case STATE_ACTIVE: {
- BadGuy* badguy = dynamic_cast<BadGuy*> (&other);
- if(badguy && badguy->state == STATE_ACTIVE && badguy->get_group() == COLGROUP_MOVING) {
-
- // hit from above?
- if (badguy->get_bbox().p2.y < (bbox.p1.y + 16)) {
- if(collision_squished(*badguy)) {
- return ABORT_MOVE;
- }
- }
-
- return collision_badguy(*badguy, hit);
- }
-
- Player* player = dynamic_cast<Player*> (&other);
- if(player) {
-
- // hit from above?
- if (player->get_bbox().p2.y < (bbox.p1.y + 16)) {
- if(collision_squished(*player)) {
- return ABORT_MOVE;
- }
- }
-
- return collision_player(*player, hit);
- }
-
- Bullet* bullet = dynamic_cast<Bullet*> (&other);
- if(bullet)
- return collision_bullet(*bullet, hit);
-
- return FORCE_MOVE;
- }
- case STATE_SQUISHED:
- return FORCE_MOVE;
- case STATE_FALLING:
- return FORCE_MOVE;
- }
-
- return ABORT_MOVE;
-}
-
-void
-BadGuy::collision_solid(const CollisionHit& hit)
-{
- physic.set_velocity_x(0);
- physic.set_velocity_y(0);
- update_on_ground_flag(hit);
-}
-
-HitResponse
-BadGuy::collision_player(Player& player, const CollisionHit& )
-{
- if(player.is_invincible()) {
- kill_fall();
- return ABORT_MOVE;
- }
-
- if(frozen)
- unfreeze();
- player.kill(false);
- return FORCE_MOVE;
-}
-
-HitResponse
-BadGuy::collision_badguy(BadGuy& , const CollisionHit& )
-{
- return FORCE_MOVE;
-}
-
-bool
-BadGuy::collision_squished(GameObject& )
-{
- return false;
-}
-
-HitResponse
-BadGuy::collision_bullet(Bullet& bullet, const CollisionHit& hit)
-{
- if (is_frozen()) {
- if(bullet.get_type() == FIRE_BONUS) {
- // fire bullet thaws frozen badguys
- unfreeze();
- bullet.remove_me();
- return ABORT_MOVE;
- } else {
- // other bullets ricochet
- bullet.ricochet(*this, hit);
- return FORCE_MOVE;
- }
- }
- else if (is_ignited()) {
- if(bullet.get_type() == ICE_BONUS) {
- // ice bullets extinguish ignited badguys
- extinguish();
- bullet.remove_me();
- return ABORT_MOVE;
- } else {
- // other bullets are absorbed by ignited badguys
- bullet.remove_me();
- return FORCE_MOVE;
- }
- }
- else if(bullet.get_type() == FIRE_BONUS && is_flammable()) {
- // fire bullets ignite flammable badguys
- ignite();
- bullet.remove_me();
- return ABORT_MOVE;
- }
- else if(bullet.get_type() == ICE_BONUS && is_freezable()) {
- // ice bullets freeze freezable badguys
- freeze();
- bullet.remove_me();
- return ABORT_MOVE;
- }
- else {
- // in all other cases, bullets ricochet
- bullet.ricochet(*this, hit);
- return FORCE_MOVE;
- }
-}
-
-void
-BadGuy::kill_squished(GameObject& object)
-{
- sound_manager->play("sounds/squish.wav", get_pos());
- physic.enable_gravity(true);
- physic.set_velocity_x(0);
- physic.set_velocity_y(0);
- set_state(STATE_SQUISHED);
- set_group(COLGROUP_MOVING_ONLY_STATIC);
- Player* player = dynamic_cast<Player*>(&object);
- if (player) {
- if (countMe) Sector::current()->get_level()->stats.badguys++;
- player->bounce(*this);
- }
-
- // start dead-script
- if(dead_script != "") {
- std::istringstream stream(dead_script);
- Sector::current()->run_script(stream, "dead-script");
- }
-}
-
-void
-BadGuy::kill_fall()
-{
- sound_manager->play("sounds/fall.wav", get_pos());
- if (countMe) Sector::current()->get_level()->stats.badguys++;
- physic.set_velocity_y(0);
- physic.enable_gravity(true);
- set_state(STATE_FALLING);
-
- // start dead-script
- if(dead_script != "") {
- std::istringstream stream(dead_script);
- Sector::current()->run_script(stream, "dead-script");
- }
-}
-
-void
-BadGuy::run_dead_script()
-{
- if (countMe)
- Sector::current()->get_level()->stats.badguys++;
-
- // start dead-script
- if(dead_script != "") {
- std::istringstream stream(dead_script);
- Sector::current()->run_script(stream, "dead-script");
- }
-}
-
-void
-BadGuy::set_state(State state)
-{
- if(this->state == state)
- return;
-
- State laststate = this->state;
- this->state = state;
- switch(state) {
- case STATE_SQUISHED:
- state_timer.start(SQUISH_TIME);
- break;
- case STATE_ACTIVE:
- set_group(COLGROUP_MOVING);
- bbox.set_pos(start_position);
- break;
- case STATE_INACTIVE:
- // was the badguy dead anyway?
- if(laststate == STATE_SQUISHED || laststate == STATE_FALLING) {
- remove_me();
- }
- set_group(COLGROUP_DISABLED);
- break;
- case STATE_FALLING:
- set_group(COLGROUP_DISABLED);
- break;
- default:
- break;
- }
-}
-
-bool
-BadGuy::is_offscreen()
-{
- float scroll_x = Sector::current()->camera->get_translation().x;
- float scroll_y = Sector::current()->camera->get_translation().y;
-
- if(bbox.p2.x < scroll_x - X_OFFSCREEN_DISTANCE
- || bbox.p1.x > scroll_x + X_OFFSCREEN_DISTANCE + SCREEN_WIDTH
- || bbox.p2.y < scroll_y - Y_OFFSCREEN_DISTANCE
- || bbox.p1.y > scroll_y + Y_OFFSCREEN_DISTANCE + SCREEN_HEIGHT)
- return true;
-
- return false;
-}
-
-void
-BadGuy::try_activate()
-{
- float scroll_x = Sector::current()->camera->get_translation().x;
- float scroll_y = Sector::current()->camera->get_translation().y;
-
- /* Activate badguys if they're just around the screen to avoid
- * the effect of having badguys suddenly popping up from nowhere.
- */
- //Badguy left of screen
- if (start_position.x > scroll_x - X_OFFSCREEN_DISTANCE &&
- start_position.x < scroll_x - bbox.get_width() &&
- start_position.y > scroll_y - Y_OFFSCREEN_DISTANCE &&
- start_position.y < scroll_y + SCREEN_HEIGHT + Y_OFFSCREEN_DISTANCE) {
- if (start_dir != AUTO) dir = start_dir; else dir = RIGHT;
- set_state(STATE_ACTIVE);
- activate();
- //Badguy right of screen
- } else if (start_position.x > scroll_x + SCREEN_WIDTH &&
- start_position.x < scroll_x + SCREEN_WIDTH + X_OFFSCREEN_DISTANCE &&
- start_position.y > scroll_y - Y_OFFSCREEN_DISTANCE &&
- start_position.y < scroll_y + SCREEN_HEIGHT + Y_OFFSCREEN_DISTANCE) {
- if (start_dir != AUTO) dir = start_dir; else dir = LEFT;
- set_state(STATE_ACTIVE);
- activate();
- //Badguy over or under screen
- } else if (start_position.x > scroll_x - X_OFFSCREEN_DISTANCE &&
- start_position.x < scroll_x + SCREEN_WIDTH + X_OFFSCREEN_DISTANCE &&
- ((start_position.y > scroll_y + SCREEN_HEIGHT &&
- start_position.y < scroll_y + SCREEN_HEIGHT + Y_OFFSCREEN_DISTANCE) ||
- (start_position.y > scroll_y - Y_OFFSCREEN_DISTANCE &&
- start_position.y < scroll_y - bbox.get_height() ))) {
- if (start_dir != AUTO) dir = start_dir;
- else{
- // if nearest player is to our right, start facing right
- Player* player = get_nearest_player();
- if (player && (player->get_bbox().p1.x > get_bbox().p2.x)) {
- dir = RIGHT;
- } else {
- dir = LEFT;
- }
- }
- set_state(STATE_ACTIVE);
- activate();
- } else if(state == STATE_INIT
- && start_position.x > scroll_x - X_OFFSCREEN_DISTANCE
- && start_position.x < scroll_x + X_OFFSCREEN_DISTANCE + SCREEN_WIDTH
- && start_position.y > scroll_y - Y_OFFSCREEN_DISTANCE
- && start_position.y < scroll_y + Y_OFFSCREEN_DISTANCE + SCREEN_HEIGHT ) {
- if (start_dir != AUTO) {
- dir = start_dir;
- } else {
- // if nearest player is to our right, start facing right
- Player* player = get_nearest_player();
- if (player && (player->get_bbox().p1.x > get_bbox().p2.x)) {
- dir = RIGHT;
- } else {
- dir = LEFT;
- }
- }
- set_state(STATE_ACTIVE);
- activate();
- }
-}
-
-bool
-BadGuy::might_fall(int height)
-{
- // make sure we check for at least a 1-pixel fall
- assert(height > 0);
-
- float x1;
- float x2;
- float y1 = bbox.p2.y + 1;
- float y2 = bbox.p2.y + 1 + height;
- if (dir == LEFT) {
- x1 = bbox.p1.x - 1;
- x2 = bbox.p1.x - 1;
- } else {
- x1 = bbox.p2.x + 1;
- x2 = bbox.p2.x + 1;
- }
- return Sector::current()->is_free_of_statics(Rect(x1, y1, x2, y2));
-}
-
-Player*
-BadGuy::get_nearest_player()
-{
- // FIXME: does not really return nearest player
-
- std::vector<Player*> players = Sector::current()->get_players();
- for (std::vector<Player*>::iterator playerIter = players.begin(); playerIter != players.end(); ++playerIter) {
- Player* player = *playerIter;
- return player;
- }
-
- return 0;
-}
-
-void
-BadGuy::update_on_ground_flag(const CollisionHit& hit)
-{
- if (hit.bottom) {
- on_ground_flag = true;
- floor_normal = hit.slope_normal;
- }
-}
-
-bool
-BadGuy::on_ground()
-{
- return on_ground_flag;
-}
-
-Vector
-BadGuy::get_floor_normal()
-{
- return floor_normal;
-}
-
-void
-BadGuy::freeze()
-{
- set_group(COLGROUP_MOVING_STATIC);
- frozen = true;
-}
-
-void
-BadGuy::unfreeze()
-{
- set_group(COLGROUP_MOVING);
- frozen = false;
-}
-
-bool
-BadGuy::is_freezable() const
-{
- return false;
-}
-
-bool
-BadGuy::is_frozen() const
-{
- return frozen;
-}
-
-void
-BadGuy::ignite()
-{
- kill_fall();
-}
-
-void
-BadGuy::extinguish()
-{
-}
-
-bool
-BadGuy::is_flammable() const
-{
- return true;
-}
-
-bool
-BadGuy::is_ignited() const
-{
- return ignited;
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __BADGUY_H__
-#define __BADGUY_H__
-
-// moved them here to make it less typing when implementing new badguys
-#include <math.h>
-#include "timer.hpp"
-#include "object/moving_sprite.hpp"
-#include "physic.hpp"
-#include "object/player.hpp"
-#include "serializable.hpp"
-#include "resources.hpp"
-#include "sector.hpp"
-#include "direction.hpp"
-#include "object_factory.hpp"
-#include "lisp/parser.hpp"
-#include "lisp/lisp.hpp"
-#include "lisp/writer.hpp"
-#include "video/drawing_context.hpp"
-#include "audio/sound_manager.hpp"
-#include "audio/sound_source.hpp"
-
-class BadGuy : public MovingSprite, protected UsesPhysic, public Serializable
-{
-public:
- BadGuy(const Vector& pos, const std::string& sprite_name, int layer = LAYER_OBJECTS);
- BadGuy(const Vector& pos, Direction direction, const std::string& sprite_name, int layer = LAYER_OBJECTS);
- BadGuy(const lisp::Lisp& reader, const std::string& sprite_name, int layer = LAYER_OBJECTS);
-
- /** Called when the badguy is drawn. The default implementation simply draws
- * the badguy sprite on screen
- */
- virtual void draw(DrawingContext& context);
- /** Called each frame. The default implementation checks badguy state and
- * calls active_update and inactive_update
- */
- virtual void update(float elapsed_time);
- /** Called when a collision with another object occured. The default
- * implemetnation calls collision_player, collision_solid, collision_badguy
- * and collision_squished
- */
- virtual HitResponse collision(GameObject& other, const CollisionHit& hit);
-
- /** Called when a collision with tile with special attributes occured */
- virtual void collision_tile(uint32_t tile_attributes);
-
- /** Set the badguy to kill/falling state, which makes him falling of the
- * screen (his sprite is turned upside-down)
- */
- virtual void kill_fall();
-
- /** Call this, if you use custom kill_fall() or kill_squashed(GameObject& object) */
- virtual void run_dead_script();
-
- /** Writes out the badguy into the included lisp::Writer. Useful e.g. when
- * converting an old-format level to the new format.
- */
- virtual void write(lisp::Writer& writer);
-
- /**
- * True if this badguy can break bricks or open bonusblocks in his current form.
- */
- virtual bool can_break()
- {
- return false;
- }
-
- Vector get_start_position() const
- {
- return start_position;
- }
- void set_start_position(const Vector& vec)
- {
- start_position = vec;
- }
-
- /** Count this badguy to the statistics? This value should not be changed
- * during runtime. */
- bool countMe;
-
- /**
- * Called when hit by a fire bullet, and is_flammable() returns true
- */
- virtual void ignite();
-
- /**
- * Called to revert a badguy when is_ignited() returns true
- */
- virtual void extinguish();
-
- /**
- * Returns whether to call ignite() when a badguy gets hit by a fire bullet
- */
- virtual bool is_flammable() const;
-
- /**
- * Returns whether this badguys is currently on fire
- */
- bool is_ignited() const;
-
- /**
- * Called when hit by an ice bullet, and is_freezable() returns true.
- */
- virtual void freeze();
-
- /**
- * Called to unfreeze the badguy.
- */
- virtual void unfreeze();
-
- virtual bool is_freezable() const;
-
- bool is_frozen() const;
-
-protected:
- enum State {
- STATE_INIT,
- STATE_INACTIVE,
- STATE_ACTIVE,
- STATE_SQUISHED,
- STATE_FALLING
- };
-
- /** Called when the badguy collided with a player */
- virtual HitResponse collision_player(Player& player, const CollisionHit& hit);
- /** Called when the badguy collided with solid ground */
- virtual void collision_solid(const CollisionHit& hit);
- /** Called when the badguy collided with another badguy */
- virtual HitResponse collision_badguy(BadGuy& other, const CollisionHit& hit);
-
- /** Called when the player hit the badguy from above. You should return true
- * if the badguy was squished, false if squishing wasn't possible
- */
- virtual bool collision_squished(GameObject& object);
-
- /** Called when the badguy collided with a bullet */
- virtual HitResponse collision_bullet(Bullet& bullet, const CollisionHit& hit);
-
- /** called each frame when the badguy is activated. */
- virtual void active_update(float elapsed_time);
- /** called each frame when the badguy is not activated. */
- virtual void inactive_update(float elapsed_time);
-
- /**
- * called when the badguy has been activated. (As a side effect the dir
- * variable might have been changed so that it faces towards the player.
- */
- virtual void activate();
- /** called when the badguy has been deactivated */
- virtual void deactivate();
-
- void kill_squished(GameObject& object);
-
- void set_state(State state);
- State get_state() const
- { return state; }
-
- /**
- * returns a pointer to the nearest player or 0 if no player is available
- */
- Player* get_nearest_player();
-
- /// is the enemy activated
- bool activated;
- /**
- * initial position of the enemy. Also the position where enemy respawns when
- * after being deactivated.
- */
- bool is_offscreen();
- /**
- * Returns true if we might soon fall at least @c height pixels. Minimum
- * value for height is 1 pixel
- */
- bool might_fall(int height = 1);
-
- Vector start_position;
-
- /**
- * The direction we currently face in
- */
- Direction dir;
-
- /**
- * The direction we initially faced in
- */
- Direction start_dir;
-
- /**
- * Get Direction from String.
- */
- Direction str2dir( std::string dir_str );
-
- /**
- * Update on_ground_flag judging by solid collision @c hit.
- * This gets called from the base implementation of collision_solid, so call this when overriding collision_solid's default behaviour.
- */
- void update_on_ground_flag(const CollisionHit& hit);
-
- /**
- * Returns true if we touched ground in the past frame
- * This only works if update_on_ground_flag() gets called in collision_solid.
- */
- bool on_ground();
-
- /**
- * Returns floor normal stored the last time when update_on_ground_flag was called and we touched something solid from above.
- */
- Vector get_floor_normal();
-
- bool frozen;
- bool ignited; /**< true if this badguy is currently on fire */
-
- std::string dead_script; /**< script to execute when badguy is killed */
-
-private:
- void try_activate();
-
- State state;
- Timer state_timer;
- bool on_ground_flag; /**< true if we touched something solid from above and update_on_ground_flag was called last frame */
- Vector floor_normal; /**< floor normal stored the last time when update_on_ground_flag was called and we touched something solid from above */
-
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include "bomb.hpp"
-#include "random_generator.hpp"
-#include "object/explosion.hpp"
-
-Bomb::Bomb(const Vector& pos, Direction dir, std::string custom_sprite /*= "images/creatures/mr_bomb/mr_bomb.sprite"*/ )
- : BadGuy( pos, dir, custom_sprite )
-{
- state = STATE_TICKING;
- set_action(dir == LEFT ? "ticking-left" : "ticking-right", 1);
- countMe = false;
-
- ticking.reset(sound_manager->create_sound_source("sounds/fizz.wav"));
- ticking->set_position(get_pos());
- ticking->set_looping(true);
- ticking->set_gain(2.0);
- ticking->set_reference_distance(32);
- ticking->play();
-}
-
-Bomb::Bomb(const Bomb& other)
- : BadGuy(other), state(other.state)
-{
- if (state == STATE_TICKING) {
- ticking.reset(sound_manager->create_sound_source("sounds/fizz.wav"));
- ticking->set_position(get_pos());
- ticking->set_looping(true);
- ticking->set_gain(2.0);
- ticking->set_reference_distance(32);
- ticking->play();
- }
-}
-
-void
-Bomb::write(lisp::Writer& )
-{
- // bombs are only temporarily so don't write them out...
-}
-
-void
-Bomb::collision_solid(const CollisionHit& hit)
-{
- if(hit.bottom)
- physic.set_velocity_y(0);
-}
-
-HitResponse
-Bomb::collision_player(Player& , const CollisionHit& )
-{
- return ABORT_MOVE;
-}
-
-HitResponse
-Bomb::collision_badguy(BadGuy& , const CollisionHit& )
-{
- return ABORT_MOVE;
-}
-
-void
-Bomb::active_update(float )
-{
- ticking->set_position(get_pos());
- if(sprite->animation_done()) {
- explode();
- }
-}
-
-void
-Bomb::explode()
-{
- ticking->stop();
-
- remove_me();
- Explosion* explosion = new Explosion(get_bbox().get_middle());
- Sector::current()->add_object(explosion);
-
- run_dead_script();
-}
-
-void
-Bomb::kill_fall()
-{
- explode();
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __BOMB_H__
-#define __BOMB_H__
-
-#include "badguy.hpp"
-
-class Bomb : public BadGuy
-{
-public:
- Bomb(const Vector& pos, Direction dir, std::string custom_sprite = "images/creatures/mr_bomb/bomb.sprite" );
- Bomb(const Bomb& bomb);
-
- void write(lisp::Writer& writer);
- void collision_solid(const CollisionHit& hit);
- HitResponse collision_player(Player& player, const CollisionHit& hit);
- HitResponse collision_badguy(BadGuy& badguy, const CollisionHit& hit);
- void active_update(float elapsed_time);
- void kill_fall();
- void explode();
-
-private:
- enum State {
- STATE_TICKING
- };
-
- State state;
-
- std::auto_ptr<SoundSource> ticking;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include "bouncing_snowball.hpp"
-
-static const float JUMPSPEED = -450;
-static const float WALKSPEED = 80;
-
-BouncingSnowball::BouncingSnowball(const lisp::Lisp& reader)
- : BadGuy(reader, "images/creatures/bouncing_snowball/bouncing_snowball.sprite")
-{
-}
-
-BouncingSnowball::BouncingSnowball(const Vector& pos, Direction d)
- : BadGuy(pos, d, "images/creatures/bouncing_snowball/bouncing_snowball.sprite")
-{
-}
-
-void
-BouncingSnowball::write(lisp::Writer& writer)
-{
- writer.start_list("bouncingsnowball");
-
- writer.write_float("x", start_position.x);
- writer.write_float("y", start_position.y);
-
- writer.end_list("bouncingsnowball");
-}
-
-void
-BouncingSnowball::activate()
-{
- physic.set_velocity_x(dir == LEFT ? -WALKSPEED : WALKSPEED);
- sprite->set_action(dir == LEFT ? "left" : "right");
-}
-
-bool
-BouncingSnowball::collision_squished(GameObject& object)
-{
- sprite->set_action("squished");
- kill_squished(object);
- return true;
-}
-
-void
-BouncingSnowball::collision_solid(const CollisionHit& hit)
-{
- if(hit.bottom) {
- if(get_state() == STATE_ACTIVE) {
- physic.set_velocity_y(JUMPSPEED);
- } else {
- physic.set_velocity_y(0);
- }
- } else if(hit.top) {
- physic.set_velocity_y(0);
- }
-
- if(hit.left || hit.right) { // left or right collision
- dir = dir == LEFT ? RIGHT : LEFT;
- sprite->set_action(dir == LEFT ? "left" : "right");
- physic.set_velocity_x(-physic.get_velocity_x());
- }
-}
-
-HitResponse
-BouncingSnowball::collision_badguy(BadGuy& , const CollisionHit& hit)
-{
- collision_solid(hit);
- return CONTINUE;
-}
-
-IMPLEMENT_FACTORY(BouncingSnowball, "bouncingsnowball")
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __BOUNCING_SNOWBALL_H__
-#define __BOUNCING_SNOWBALL_H__
-
-#include "badguy.hpp"
-
-class BouncingSnowball : public BadGuy
-{
-public:
- BouncingSnowball(const lisp::Lisp& reader);
- BouncingSnowball(const Vector& pos, Direction d);
-
- void activate();
- void write(lisp::Writer& writer);
- void collision_solid(const CollisionHit& hit);
- HitResponse collision_badguy(BadGuy& badguy, const CollisionHit& hit);
-
- virtual BouncingSnowball* clone() const { return new BouncingSnowball(*this); }
-
-protected:
- bool collision_squished(GameObject& object);
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// Dart - Your average poison dart
-// Copyright (C) 2006 Christoph Sommer <supertux@2006.expires.deltadevelopment.de>
-//
-// 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.
-
-#include <config.h>
-
-#include "dart.hpp"
-
-namespace {
- const float SPEED = 200;
-}
-
-static const std::string SOUNDFILE = "sounds/flame.wav";
-
-Dart::Dart(const lisp::Lisp& reader)
- : BadGuy(reader, "images/creatures/dart/dart.sprite"), parent(0)
-{
- physic.enable_gravity(false);
- countMe = false;
- sound_manager->preload("sounds/darthit.wav");
- sound_manager->preload("sounds/stomp.wav");
-}
-
-Dart::Dart(const Vector& pos, Direction d, const BadGuy* parent = 0)
- : BadGuy(pos, d, "images/creatures/dart/dart.sprite"), parent(parent)
-{
- physic.enable_gravity(false);
- countMe = false;
- sound_manager->preload("sounds/darthit.wav");
- sound_manager->preload("sounds/stomp.wav");
-}
-
-Dart::Dart(const Dart& other)
- : BadGuy(other), parent(other.parent)
-{
- sound_source.reset(sound_manager->create_sound_source(SOUNDFILE));
- sound_manager->preload("sounds/darthit.wav");
- sound_manager->preload("sounds/stomp.wav");
-}
-
-Dart::~Dart()
-{
-}
-
-bool
-Dart::updatePointers(const GameObject* from_object, GameObject* to_object)
-{
- if (from_object == parent) {
- parent = dynamic_cast<Dart*>(to_object);
- return true;
- }
- return false;
-}
-
-void
-Dart::write(lisp::Writer& writer)
-{
- writer.start_list("dart");
- writer.write_float("x", start_position.x);
- writer.write_float("y", start_position.y);
- writer.end_list("dart");
-}
-
-void
-Dart::activate()
-{
- physic.set_velocity_x(dir == LEFT ? -::SPEED : ::SPEED);
- sprite->set_action(dir == LEFT ? "flying-left" : "flying-right");
-
- sound_source.reset(sound_manager->create_sound_source(SOUNDFILE));
- sound_source->set_position(get_pos());
- sound_source->set_looping(true);
- sound_source->set_gain(1.0);
- sound_source->set_reference_distance(32);
- sound_source->play();
-}
-
-void
-Dart::deactivate()
-{
- sound_source.reset();
- remove_me();
-}
-
-void
-Dart::active_update(float elapsed_time)
-{
- BadGuy::active_update(elapsed_time);
- sound_source->set_position(get_pos());
-}
-
-void
-Dart::collision_solid(const CollisionHit& )
-{
- sound_manager->play("sounds/darthit.wav", get_pos());
- remove_me();
-}
-
-HitResponse
-Dart::collision_badguy(BadGuy& badguy, const CollisionHit& )
-{
- // ignore collisions with parent
- if (&badguy == parent) {
- return FORCE_MOVE;
- }
- sound_manager->play("sounds/stomp.wav", get_pos());
- remove_me();
- badguy.kill_fall();
- return ABORT_MOVE;
-}
-
-HitResponse
-Dart::collision_player(Player& player, const CollisionHit& hit)
-{
- sound_manager->play("sounds/stomp.wav", get_pos());
- remove_me();
- return BadGuy::collision_player(player, hit);
-}
-
-IMPLEMENT_FACTORY(Dart, "dart")
+++ /dev/null
-// $Id$
-//
-// Dart - Your average poison dart
-// Copyright (C) 2006 Christoph Sommer <supertux@2006.expires.deltadevelopment.de>
-//
-// 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.
-
-#ifndef __DART_H__
-#define __DART_H__
-
-#include "badguy.hpp"
-
-/**
- * Badguy "Dart" - Your average poison dart
- */
-class Dart : public BadGuy
-{
-public:
- Dart(const lisp::Lisp& reader);
- Dart(const Vector& pos, Direction d, const BadGuy* parent);
- Dart(const Dart& dart);
- ~Dart();
-
- void activate();
- void deactivate();
- void write(lisp::Writer& writer);
-
- void active_update(float elapsed_time);
-
- void collision_solid(const CollisionHit& hit);
- HitResponse collision_badguy(BadGuy& badguy, const CollisionHit& hit);
- HitResponse collision_player(Player& player, const CollisionHit& hit);
-
- virtual Dart* clone() const { return new Dart(*this); }
-
- virtual bool updatePointers(const GameObject* from_object, GameObject* to_object);
-
-protected:
- const BadGuy* parent; /**< collisions with this BadGuy will be ignored */
- std::auto_ptr<SoundSource> sound_source; /**< SoundSource for ambient sound */
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// DartTrap - Shoots a Dart at regular intervals
-// Copyright (C) 2006 Christoph Sommer <supertux@2006.expires.deltadevelopment.de>
-//
-// 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.
-
-#include <config.h>
-
-#include "darttrap.hpp"
-#include "dart.hpp"
-
-namespace {
- const float MUZZLE_Y = 25; /**< [px] muzzle y-offset from top */
-}
-
-DartTrap::DartTrap(const lisp::Lisp& reader)
- : BadGuy(reader, "images/creatures/darttrap/darttrap.sprite", LAYER_TILES-1), initial_delay(0), fire_delay(2), ammo(-1), state(IDLE)
-{
- reader.get("initial-delay", initial_delay);
- reader.get("fire-delay", fire_delay);
- reader.get("ammo", ammo);
- countMe = false;
- sound_manager->preload("sounds/dartfire.wav");
- if (start_dir == AUTO) log_warning << "Setting a DartTrap's direction to AUTO is no good idea" << std::endl;
-}
-
-void
-DartTrap::write(lisp::Writer& writer)
-{
- writer.start_list("darttrap");
- writer.write_float("x", start_position.x);
- writer.write_float("y", start_position.y);
- writer.write_float("initial-delay", initial_delay);
- writer.write_float("fire-delay", fire_delay);
- writer.write_int("ammo", ammo);
- writer.end_list("darttrap");
-}
-
-void
-DartTrap::activate()
-{
- state = IDLE;
- sprite->set_action(dir == LEFT ? "idle-left" : "idle-right");
- set_group(COLGROUP_DISABLED);
-
- if (initial_delay == 0) initial_delay = 0.1f;
- fire_timer.start(initial_delay);
-}
-
-HitResponse
-DartTrap::collision_player(Player& , const CollisionHit& )
-{
- return ABORT_MOVE;
-}
-
-void
-DartTrap::active_update(float )
-{
- if (state == IDLE) {
- if ((ammo != 0) && (fire_timer.check())) {
- if (ammo > 0) ammo--;
- load();
- fire_timer.start(fire_delay);
- }
- }
- if (state == LOADING) {
- if (sprite->animation_done()) {
- fire();
- }
- }
-}
-
-void
-DartTrap::load()
-{
- state = LOADING;
- sprite->set_action(dir == LEFT ? "loading-left" : "loading-right", 1);
-}
-
-void
-DartTrap::fire()
-{
- float px = get_pos().x;
- if (dir == RIGHT) px += 5;
- float py = get_pos().y;
- py += MUZZLE_Y;
-
- sound_manager->play("sounds/dartfire.wav", get_pos());
- Sector::current()->add_object(new Dart(Vector(px, py), dir, this));
- state = IDLE;
- sprite->set_action(dir == LEFT ? "idle-left" : "idle-right");
-}
-
-IMPLEMENT_FACTORY(DartTrap, "darttrap")
+++ /dev/null
-// $Id$
-//
-// DartTrap - Shoots a Dart at regular intervals
-// Copyright (C) 2006 Christoph Sommer <supertux@2006.expires.deltadevelopment.de>
-//
-// 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.
-
-#ifndef __DARTTRAP_H__
-#define __DARTTRAP_H__
-
-#include "badguy.hpp"
-#include "timer.hpp"
-
-/**
- * Badguy "DartTrap" - Shoots a Dart at regular intervals
- */
-class DartTrap : public BadGuy
-{
-public:
- DartTrap(const lisp::Lisp& reader);
-
- void activate();
- void write(lisp::Writer& writer);
- void active_update(float elapsed_time);
- HitResponse collision_player(Player& player, const CollisionHit& hit);
-
- virtual DartTrap* clone() const { return new DartTrap(*this); }
-
-protected:
- enum State {
- IDLE, LOADING
- };
-
- void load(); /**< load a shot */
- void fire(); /**< fire a shot */
-
- float initial_delay; /**< time to wait before firing first shot */
- float fire_delay; /**< reload time */
- int ammo; /**< ammo left (-1 means unlimited) */
-
- State state; /**< current state */
- Timer fire_timer; /**< time until new shot is fired */
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include "dispenser.hpp"
-#include "badguy/bouncing_snowball.hpp"
-#include "badguy/snowball.hpp"
-#include "badguy/mrbomb.hpp"
-#include "badguy/mriceblock.hpp"
-#include "badguy/mrrocket.hpp"
-#include "badguy/poisonivy.hpp"
-#include "badguy/snail.hpp"
-#include "badguy/skullyhop.hpp"
-#include "random_generator.hpp"
-
-Dispenser::Dispenser(const lisp::Lisp& reader)
- : BadGuy(reader, "images/creatures/dispenser/dispenser.sprite")
-{
- reader.get("cycle", cycle);
- reader.get("badguy", badguy);
- if (badguy == "mrrocket") {
- if (start_dir == AUTO) log_warning << "Setting a Dispenser's direction to AUTO is no good idea" << std::endl;
- sprite->set_action(dir == LEFT ? "working-left" : "working-right");
- }
- else {sprite->set_action("dropper");}
- bbox.set_size(sprite->get_current_hitbox_width(), sprite->get_current_hitbox_height());
- countMe = false;
-}
-
-void
-Dispenser::write(lisp::Writer& writer)
-{
- writer.start_list("dispenser");
-
- writer.write_float("x", start_position.x);
- writer.write_float("y", start_position.y);
- writer.write_float("cycle", cycle);
- writer.write_string("badguy", badguy);
-
- writer.end_list("dispenser");
-}
-
-void
-Dispenser::activate()
-{
- if(frozen)
- return;
- dispense_timer.start(cycle, true);
- launch_badguy();
-}
-
-void
-Dispenser::deactivate()
-{
- dispense_timer.stop();
-}
-
-//TODO: Add launching velocity to certain badguys
-bool
-Dispenser::collision_squished(GameObject& object)
-{
- //TODO: Should it act like a normal tile when killed?
- sprite->set_action(dir == LEFT ? "broken-left" : "broken-right");
- dispense_timer.start(0);
- Player* player = dynamic_cast<Player*>(&object);
- if (player) player->bounce(*this);
- kill_squished(object);
- return true;
-}
-
-void
-Dispenser::active_update(float )
-{
- if (dispense_timer.check()) {
- launch_badguy();
- }
-}
-
-// Add themed randomizer
-void
-Dispenser::launch_badguy()
-{
- //FIXME: Does is_offscreen() work right here?
- if (!is_offscreen()) {
- if (badguy == "snowball")
- Sector::current()->add_object(new SnowBall(Vector(get_pos().x, get_pos().y+32), dir));
- else if (badguy == "bouncingsnowball")
- Sector::current()->add_object(new BouncingSnowball(Vector(get_pos().x, get_pos().y+32), dir));
- else if (badguy == "mrbomb")
- Sector::current()->add_object(new MrBomb(Vector(get_pos().x, get_pos().y+32), dir));
- else if (badguy == "mriceblock")
- Sector::current()->add_object(new MrIceBlock(Vector(get_pos().x, get_pos().y+32), dir));
- else if (badguy == "snail")
- Sector::current()->add_object(new Snail(Vector(get_pos().x, get_pos().y+32), dir));
- else if (badguy == "mrrocket") {
- Sector::current()->add_object(new MrRocket(Vector(get_pos().x+(dir == LEFT ? -32 : 32), get_pos().y), dir));}
- else if (badguy == "poisonivy")
- Sector::current()->add_object(new PoisonIvy(Vector(get_pos().x, get_pos().y+32), dir));
- else if (badguy == "skullyhop")
- Sector::current()->add_object(new SkullyHop(Vector(get_pos().x, get_pos().y+44), dir));
- else if (badguy == "random")
- {
- switch (systemRandom.rand(7))
- {
- case 0: Sector::current()->add_object(new SnowBall(Vector(get_pos().x, get_pos().y+32), dir)); break;
- case 1: Sector::current()->add_object(new BouncingSnowball(Vector(get_pos().x, get_pos().y+32), dir)); break;
- case 2: Sector::current()->add_object(new MrBomb(Vector(get_pos().x, get_pos().y+32), dir)); break;
- case 3: Sector::current()->add_object(new MrIceBlock(Vector(get_pos().x, get_pos().y+32), dir)); break;
- case 4: Sector::current()->add_object(new PoisonIvy(Vector(get_pos().x, get_pos().y+32), dir)); break;
- case 5: Sector::current()->add_object(new Snail(Vector(get_pos().x, get_pos().y+32), dir)); break;
- case 6: Sector::current()->add_object(new SkullyHop(Vector(get_pos().x, get_pos().y+44), dir)); break;
- }
- }
- }
-}
-
-void
-Dispenser::freeze()
-{
- BadGuy::freeze();
- dispense_timer.stop();
-}
-
-void
-Dispenser::unfreeze()
-{
- BadGuy::unfreeze();
- activate();
-}
-
-bool
-Dispenser::is_freezable() const
-{
- return true;
-}
-IMPLEMENT_FACTORY(Dispenser, "dispenser")
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __DISPENSER_H__
-#define __DISPENSER_H__
-
-#include "badguy.hpp"
-#include "timer.hpp"
-
-class Dispenser : public BadGuy
-{
-public:
- Dispenser(const lisp::Lisp& reader);
-
- void activate();
- void deactivate();
- void write(lisp::Writer& writer);
- void active_update(float elapsed_time);
-
- void freeze();
- void unfreeze();
- bool is_freezable() const;
-
- virtual Dispenser* clone() const { return new Dispenser(*this); }
-
-protected:
- bool collision_squished(GameObject& object);
- void launch_badguy();
- float cycle;
- std::string badguy;
- Timer dispense_timer;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include "fish.hpp"
-#include "tile.hpp"
-#include "object/tilemap.hpp"
-#include "log.hpp"
-
-static const float FISH_JUMP_POWER = -600;
-static const float FISH_WAIT_TIME = 1;
-
-Fish::Fish(const lisp::Lisp& reader)
- : BadGuy(reader, "images/creatures/fish/fish.sprite", LAYER_TILES-1), stop_y(0)
-{
- physic.enable_gravity(true);
-}
-
-Fish::Fish(const Vector& pos)
- : BadGuy(pos, "images/creatures/fish/fish.sprite", LAYER_TILES-1), stop_y(0)
-{
- physic.enable_gravity(true);
-}
-
-void
-Fish::write(lisp::Writer& writer)
-{
- writer.start_list("fish");
-
- writer.write_float("x", start_position.x);
- writer.write_float("y", start_position.y);
-
- writer.end_list("fish");
-}
-
-void
-Fish::collision_solid(const CollisionHit& chit)
-{
- hit(chit);
-}
-
-HitResponse
-Fish::collision_badguy(BadGuy& , const CollisionHit& chit)
-{
- return hit(chit);
-}
-
-void
-Fish::draw(DrawingContext& context)
-{
- if(waiting.started())
- return;
-
- BadGuy::draw(context);
-}
-
-HitResponse
-Fish::hit(const CollisionHit& hit)
-{
- if(hit.top) {
- physic.set_velocity_y(0);
- }
-
- return CONTINUE;
-}
-
-void
-Fish::collision_tile(uint32_t tile_attributes)
-{
- if ((tile_attributes & Tile::WATER) && (physic.get_velocity_y() >= 0)) {
-
- // initialize stop position if uninitialized
- if (stop_y == 0) stop_y = get_pos().y + get_bbox().get_height();
-
- // stop when we have reached the stop position
- if (get_pos().y >= stop_y) {
- if(!frozen)
- start_waiting();
- movement = Vector(0, 0);
- }
-
- }
-}
-
-void
-Fish::active_update(float elapsed_time)
-{
- BadGuy::active_update(elapsed_time);
-
- // waited long enough?
- if(waiting.check()) {
- jump();
- }
-
- // set sprite
- if(!frozen)
- sprite->set_action(physic.get_velocity_y() < 0 ? "normal" : "down");
-
- // we can't afford flying out of the tilemap, 'cause the engine would remove us.
- if ((get_pos().y - 31.8) < 0) // too high, let us fall
- {
- physic.set_velocity_y(0);
- physic.enable_gravity(true);
- }
-}
-
-void
-Fish::start_waiting()
-{
- waiting.start(FISH_WAIT_TIME);
- set_group(COLGROUP_DISABLED);
- physic.enable_gravity(false);
- physic.set_velocity_y(0);
-}
-
-void
-Fish::jump()
-{
- physic.set_velocity_y(FISH_JUMP_POWER);
- physic.enable_gravity(true);
- set_group(COLGROUP_MOVING);
-}
-
-void
-Fish::freeze()
-{
- BadGuy::freeze();
- sprite->set_action(physic.get_velocity_y() < 0 ? "iced" : "iced-down");
- waiting.stop();
-}
-
-void
-Fish::unfreeze()
-{ // does this happen at all? (or do fishes die when they fall frozen?)
- BadGuy::unfreeze();
- start_waiting();
-}
-
-bool
-Fish::is_freezable() const
-{
- return true;
-}
-
-IMPLEMENT_FACTORY(Fish, "fish")
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __FISH_H__
-#define __FISH_H__
-
-#include "badguy.hpp"
-
-class Fish : public BadGuy
-{
-public:
- Fish(const lisp::Lisp& );
- Fish(const Vector& pos);
-
- void draw(DrawingContext& context);
-
- void collision_solid(const CollisionHit& hit);
- HitResponse collision_badguy(BadGuy& , const CollisionHit& );
- void collision_tile(uint32_t tile_attributes);
-
- void write(lisp::Writer& );
- void active_update(float);
-
- void freeze();
- void unfreeze();
- bool is_freezable() const;
-
- virtual Fish* clone() const { return new Fish(*this); }
-
-private:
- HitResponse hit(const CollisionHit& );
- void start_waiting();
- void jump();
-
- Timer waiting;
- float stop_y; /**< y-coordinate to stop at */
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include "flame.hpp"
-#include "log.hpp"
-
-static const std::string SOUNDFILE = "sounds/flame.wav";
-
-Flame::Flame(const lisp::Lisp& reader)
- : BadGuy(reader, "images/creatures/flame/flame.sprite", LAYER_FLOATINGOBJECTS), angle(0), radius(100), speed(2)
-{
- reader.get("radius", radius);
- reader.get("speed", speed);
- bbox.set_pos(Vector(start_position.x + cos(angle) * radius,
- start_position.y + sin(angle) * radius));
- countMe = false;
- sound_manager->preload(SOUNDFILE);
-}
-
-void
-Flame::write(lisp::Writer& writer)
-{
- writer.start_list("flame");
-
- writer.write_float("x", start_position.x);
- writer.write_float("y", start_position.y);
- writer.write_float("radius", radius);
- writer.write_float("speed", speed);
-
- writer.end_list("flame");
-}
-
-void
-Flame::active_update(float elapsed_time)
-{
- angle = fmodf(angle + elapsed_time * speed, (float) (2*M_PI));
- Vector newpos(start_position.x + cos(angle) * radius,
- start_position.y + sin(angle) * radius);
- movement = newpos - get_pos();
-
- sound_source->set_position(get_pos());
-}
-
-void
-Flame::activate()
-{
- set_group(COLGROUP_TOUCHABLE);
-
- sound_source.reset(sound_manager->create_sound_source(SOUNDFILE));
- sound_source->set_position(get_pos());
- sound_source->set_looping(true);
- sound_source->set_gain(2.0);
- sound_source->set_reference_distance(32);
- sound_source->play();
-}
-
-void
-Flame::deactivate()
-{
- sound_source.reset();
-}
-
-void
-Flame::kill_fall()
-{
-}
-
-IMPLEMENT_FACTORY(Flame, "flame")
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#ifndef __FLAME_H__
-#define __FLAME_H__
-
-#include "badguy.hpp"
-
-class Flame : public BadGuy
-{
-public:
- Flame(const lisp::Lisp& reader);
- Flame(const Flame& flame);
-
- void activate();
- void deactivate();
-
- void write(lisp::Writer& write);
- void active_update(float elapsed_time);
- void kill_fall();
-
-private:
- float angle;
- float radius;
- float speed;
-
- std::auto_ptr<SoundSource> sound_source;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include <stdio.h>
-
-#include "flyingsnowball.hpp"
-#include "random_generator.hpp"
-#include "object/sprite_particle.hpp"
-
-static const float FLYTIME = 1.0f;
-static const float FLYSPEED = -100.0f;
-
-namespace {
- const float PUFF_PROBABILITY = 0.1f; /**< chanche of puffs being spawned in the current cycle */
- const float PUFF_INTERVAL_MIN = 0.1f; /**< spawn new puff of smoke at most that often */
- const float PUFF_INTERVAL_MAX = 1.1f; /**< spawn new puff of smoke at least that often */
-}
-
-FlyingSnowBall::FlyingSnowBall(const lisp::Lisp& reader)
- : BadGuy(reader, "images/creatures/flying_snowball/flying_snowball.sprite")
-{
- physic.enable_gravity(false);
-}
-
-FlyingSnowBall::FlyingSnowBall(const Vector& pos)
- : BadGuy(pos, "images/creatures/flying_snowball/flying_snowball.sprite")
-{
- physic.enable_gravity(false);
-}
-
-void
-FlyingSnowBall::write(lisp::Writer& writer)
-{
- writer.start_list("flyingsnowball");
-
- writer.write_float("x", start_position.x);
- writer.write_float("y", start_position.y);
-
- writer.end_list("flyingsnowball");
-}
-
-void
-FlyingSnowBall::activate()
-{
- sprite->set_action(dir == LEFT ? "left" : "right");
- mode = FLY_UP;
- physic.set_velocity_y(FLYSPEED);
- timer.start(FLYTIME/2);
- puff_timer.start(systemRandom.randf(PUFF_INTERVAL_MIN, PUFF_INTERVAL_MAX));
-}
-
-bool
-FlyingSnowBall::collision_squished(GameObject& object)
-{
- sprite->set_action(dir == LEFT ? "squished-left" : "squished-right");
- kill_squished(object);
- return true;
-}
-
-void
-FlyingSnowBall::collision_solid(const CollisionHit& hit)
-{
- if(hit.top || hit.bottom) {
- physic.set_velocity_y(0);
- }
-}
-
-void
-FlyingSnowBall::active_update(float elapsed_time)
-{
- if(timer.check()) {
- if(mode == FLY_UP) {
- mode = FLY_DOWN;
- physic.set_velocity_y(-FLYSPEED);
-
- // stop puffing
- puff_timer.stop();
-
- } else if(mode == FLY_DOWN) {
- mode = FLY_UP;
- physic.set_velocity_y(FLYSPEED);
-
- // roll a dice whether to start puffing
- if (systemRandom.randf(0, 1) < PUFF_PROBABILITY) {
- puff_timer.start(systemRandom.randf(PUFF_INTERVAL_MIN, PUFF_INTERVAL_MAX));
- }
-
- }
- timer.start(FLYTIME);
- }
- movement=physic.get_movement(elapsed_time);
-
- Player* player = this->get_nearest_player();
- if (player) {
- dir = (player->get_pos().x > get_pos().x) ? RIGHT : LEFT;
- sprite->set_action(dir == LEFT ? "left" : "right");
- }
-
- // spawn smoke puffs
- if (puff_timer.check()) {
- Vector ppos = bbox.get_middle();
- Vector pspeed = Vector(systemRandom.randf(-10, 10), 150);
- Vector paccel = Vector(0,0);
- Sector::current()->add_object(new SpriteParticle("images/objects/particles/smoke.sprite", "default", ppos, ANCHOR_MIDDLE, pspeed, paccel, LAYER_OBJECTS-1));
- puff_timer.start(systemRandom.randf(PUFF_INTERVAL_MIN, PUFF_INTERVAL_MAX));
- }
-}
-
-IMPLEMENT_FACTORY(FlyingSnowBall, "flyingsnowball")
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __FLYINGSNOWBALL_H__
-#define __FLYINGSNOWBALL_H__
-
-#include "badguy.hpp"
-
-class FlyingSnowBall : public BadGuy
-{
-public:
- FlyingSnowBall(const lisp::Lisp& reader);
- FlyingSnowBall(const Vector& pos);
-
- void activate();
- void write(lisp::Writer& writer);
- void active_update(float elapsed_time);
- void collision_solid(const CollisionHit& hit);
-
- virtual FlyingSnowBall* clone() const { return new FlyingSnowBall(*this); }
-
-protected:
- enum FlyingSnowballMode {
- FLY_UP,
- FLY_DOWN
- };
- FlyingSnowballMode mode;
- bool collision_squished(GameObject& object);
-private:
- Timer timer;
- Timer puff_timer; /**< time until the next smoke puff is spawned */
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux - Boss "GhostTree"
-// Copyright (C) 2007 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#include <config.h>
-
-#include "ghosttree.hpp"
-#include "treewillowisp.hpp"
-#include "sprite/sprite_manager.hpp"
-#include "root.hpp"
-#include "random_generator.hpp"
-#include "object/lantern.hpp"
-
-static const size_t WILLOWISP_COUNT = 10;
-static const float ROOT_TOP_OFFSET = 64;
-static const float WILLOWISP_TOP_OFFSET = -64;
-static const Vector SUCK_TARGET_OFFSET = Vector(-16,-16);
-static const float SUCK_TARGET_SPREAD = 8;
-
-GhostTree::GhostTree(const lisp::Lisp& lisp)
- : BadGuy(lisp, "images/creatures/ghosttree/ghosttree.sprite",
- LAYER_OBJECTS - 10), mystate(STATE_IDLE),
- willo_spawn_y(0), willo_radius(200), willo_speed(1.8f), willo_color(0),
- treecolor(0), suck_lantern(0)
-{
- glow_sprite.reset(sprite_manager->create("images/creatures/ghosttree/ghosttree-glow.sprite"));
-}
-
-GhostTree::~GhostTree()
-{
-}
-
-void
-GhostTree::die()
-{
- mystate = STATE_DYING;
- sprite->set_action("dying", 1);
- glow_sprite->set_action("dying", 1);
-
- std::vector<TreeWillOWisp*>::iterator iter;
- for(iter = willowisps.begin(); iter != willowisps.end(); ++iter) {
- TreeWillOWisp *willo = *iter;
- willo->vanish();
- }
-}
-
-void
-GhostTree::activate()
-{
- willowisp_timer.start(1.0f, true);
- colorchange_timer.start(13, true);
- root_timer.start(5, true);
- set_group(COLGROUP_TOUCHABLE);
-}
-
-void
-GhostTree::active_update(float elapsed_time)
-{
- (void) elapsed_time;
-
- if (mystate == STATE_IDLE) {
- if(colorchange_timer.check()) {
- sound_manager->play("sounds/tree_howling.ogg", get_pos());
- suck_timer.start(3);
- treecolor = (treecolor + 1) % 3;
-
- Color col;
- switch(treecolor) {
- case 0: col = Color(1, 0, 0); break;
- case 1: col = Color(0, 1, 0); break;
- case 2: col = Color(0, 0, 1); break;
- case 3: col = Color(1, 1, 0); break;
- case 4: col = Color(1, 0, 1); break;
- case 5: col = Color(0, 1, 1); break;
- default: assert(false);
- }
- glow_sprite->set_color(col);
- }
-
- if(suck_timer.check()) {
- Color col = glow_sprite->get_color();
- sound_manager->play("sounds/tree_suck.ogg", get_pos());
- std::vector<TreeWillOWisp*>::iterator iter;
- for(iter = willowisps.begin(); iter != willowisps.end(); ++iter) {
- TreeWillOWisp *willo = *iter;
- if(willo->get_color() == col) {
- willo->start_sucking(get_bbox().get_middle() + SUCK_TARGET_OFFSET + Vector(systemRandom.randf(-SUCK_TARGET_SPREAD, SUCK_TARGET_SPREAD), systemRandom.randf(-SUCK_TARGET_SPREAD, SUCK_TARGET_SPREAD)));
- }
- }
- mystate = STATE_SUCKING;
- }
-
- if(willowisp_timer.check()) {
- if(willowisps.size() < WILLOWISP_COUNT) {
- Vector pos = Vector(bbox.get_width() / 2, bbox.get_height() / 2 + willo_spawn_y + WILLOWISP_TOP_OFFSET);
- TreeWillOWisp *willowisp
- = new TreeWillOWisp(this, pos, 200 + willo_radius, willo_speed);
-
- Sector::current()->add_object(willowisp);
- willowisps.push_back(willowisp);
-
- willo_spawn_y -= 40;
- if(willo_spawn_y < -160)
- willo_spawn_y = 0;
-
- willo_radius += 20;
- if(willo_radius > 120)
- willo_radius = 0;
-
- if(willo_speed == 1.8f) {
- willo_speed = 1.5f;
- } else {
- willo_speed = 1.8f;
- }
-
- do {
- willo_color = (willo_color + 1) % 3;
- } while(willo_color == treecolor);
-
- switch(willo_color) {
- case 0: willowisp->set_color(Color(1, 0, 0)); break;
- case 1: willowisp->set_color(Color(0, 1, 0)); break;
- case 2: willowisp->set_color(Color(0, 0, 1)); break;
- case 3: willowisp->set_color(Color(1, 1, 0)); break;
- case 4: willowisp->set_color(Color(1, 0, 1)); break;
- case 5: willowisp->set_color(Color(0, 1, 1)); break;
- default: assert(false);
- }
- }
- }
-
- if(root_timer.check()) {
- /* TODO indicate root with an animation */
- Player* player = get_nearest_player();
- Root* root = new Root(Vector(player->get_bbox().get_left(), get_bbox().get_bottom()+ROOT_TOP_OFFSET));
- Sector::current()->add_object(root);
- }
- } else if (mystate == STATE_SWALLOWING) {
- if (suck_lantern) {
- // suck in lantern
- assert (suck_lantern);
- Vector pos = suck_lantern->get_pos();
- Vector delta = get_bbox().get_middle() + SUCK_TARGET_OFFSET - pos;
- Vector dir = delta.unit();
- if (delta.norm() < 1) {
- dir = delta;
- suck_lantern->ungrab(*this, RIGHT);
- suck_lantern->remove_me();
- suck_lantern = 0;
- sprite->set_action("swallow", 1);
- } else {
- pos += dir;
- suck_lantern->grab(*this, pos, RIGHT);
- }
- } else {
- // wait until lantern is swallowed
- if (sprite->animation_done()) {
- if (is_color_deadly(suck_lantern_color)) {
- die();
- } else {
- sprite->set_action("default");
- mystate = STATE_IDLE;
- spawn_lantern();
- }
- }
- }
- }
-}
-
-bool
-GhostTree::is_color_deadly(Color color) const {
- if (color == Color(0,0,0)) return false;
- Color my_color = glow_sprite->get_color();
- return ((my_color.red != color.red) || (my_color.green != color.green) || (my_color.blue != color.blue));
-}
-
-void
-GhostTree::willowisp_died(TreeWillOWisp *willowisp)
-{
- if ((mystate == STATE_SUCKING) && (willowisp->was_sucked)) {
- mystate = STATE_IDLE;
- }
- willowisps.erase(std::find(willowisps.begin(), willowisps.end(), willowisp));
-}
-
-void
-GhostTree::draw(DrawingContext& context)
-{
- BadGuy::draw(context);
-
- context.push_target();
- context.push_transform();
- context.set_target(DrawingContext::LIGHTMAP);
- if (mystate == STATE_SUCKING) {
- context.set_alpha(0.5 + fmodf(game_time, 0.5));
- } else {
- context.set_alpha(0.5);
- }
- glow_sprite->draw(context, get_pos(), layer);
- context.pop_transform();
- context.pop_target();
-}
-
-bool
-GhostTree::collides(GameObject& other, const CollisionHit& ) {
- if (mystate != STATE_SUCKING) return false;
- if (dynamic_cast<Lantern*>(&other)) return true;
- if (dynamic_cast<Player*>(&other)) return true;
- return false;
-}
-
-HitResponse
-GhostTree::collision(GameObject& other, const CollisionHit& ) {
- if(mystate != STATE_SUCKING) return ABORT_MOVE;
-
- Player* player = dynamic_cast<Player*>(&other);
- if (player) {
- player->kill(false);
- }
-
- Lantern* lantern = dynamic_cast<Lantern*>(&other);
- if (lantern) {
- suck_lantern = lantern;
- suck_lantern->grab(*this, suck_lantern->get_pos(), RIGHT);
- suck_lantern_color = lantern->get_color();
- mystate = STATE_SWALLOWING;
- }
-
- return ABORT_MOVE;
-}
-
-void
-GhostTree::spawn_lantern() {
- Lantern* lantern = new Lantern(get_bbox().get_middle() + SUCK_TARGET_OFFSET);
- Sector::current()->add_object(lantern);
-}
-
-IMPLEMENT_FACTORY(GhostTree, "ghosttree");
-
+++ /dev/null
-// $Id$
-//
-// SuperTux - Boss "GhostTree"
-// Copyright (C) 2007 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#ifndef __GHOSTTREE_H__
-#define __GHOSTTREE_H__
-
-#include <vector>
-#include "badguy.hpp"
-
-class TreeWillOWisp;
-class Lantern;
-
-class GhostTree : public BadGuy
-{
-public:
- GhostTree(const lisp::Lisp& lisp);
- ~GhostTree();
-
- virtual bool is_flammable() const { return false; }
- virtual bool is_freezable() const { return false; }
- virtual void kill_fall() { }
-
- void activate();
- void active_update(float elapsed_time);
- void willowisp_died(TreeWillOWisp* willowisp);
- virtual void draw(DrawingContext& context);
-
- virtual bool collides(GameObject& other, const CollisionHit& hit);
- virtual HitResponse collision(GameObject& other, const CollisionHit& hit);
-
- void die();
-
-private:
- enum MyState {
- STATE_IDLE, STATE_SUCKING, STATE_SWALLOWING, STATE_DYING
- };
- MyState mystate;
- Timer willowisp_timer;
- float willo_spawn_y;
- float willo_radius;
- float willo_speed;
- int willo_color;
-
- std::auto_ptr<Sprite> glow_sprite;
- Timer colorchange_timer;
- Timer suck_timer;
- Timer root_timer;
- int treecolor;
- Color suck_lantern_color;
-
- Lantern* suck_lantern; /**< Lantern that is currently being sucked in */
-
- std::vector<TreeWillOWisp*> willowisps;
-
- bool is_color_deadly(Color color) const;
- void spawn_lantern();
-};
-
-#endif
-
+++ /dev/null
-// $Id$
-//
-// SuperTux - Badguy "Igel"
-// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
-//
-// 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.
-
-#include <config.h>
-
-#include "igel.hpp"
-#include "object/block.hpp"
-#include "sector.hpp"
-#include "object/bullet.hpp"
-
-namespace {
- const float WALKSPEED = 80; /**< speed at which we walk around */
- const float TURN_RECOVER_TIME = 0.5; /**< seconds before we will again turn around when shot at */
- const float RANGE_OF_VISION = 256; /**< range in px at which we can see bullets */
-}
-
-Igel::Igel(const lisp::Lisp& reader)
- : WalkingBadguy(reader, "images/creatures/igel/igel.sprite", "walking-left", "walking-right")
-{
- walk_speed = WALKSPEED;
- max_drop_height = 16;
-}
-
-Igel::Igel(const Vector& pos, Direction d)
- : WalkingBadguy(pos, d, "images/creatures/igel/igel.sprite", "walking-left", "walking-right")
-{
- walk_speed = WALKSPEED;
- max_drop_height = 16;
-}
-
-void
-Igel::write(lisp::Writer& writer)
-{
- writer.start_list("igel");
- WalkingBadguy::write(writer);
- writer.end_list("igel");
-}
-
-void
-Igel::be_normal()
-{
- activate();
-}
-
-void
-Igel::turn_around()
-{
- WalkingBadguy::turn_around();
- turn_recover_timer.start(TURN_RECOVER_TIME);
-}
-
-bool
-Igel::can_see(const MovingObject& o)
-{
- Rect mb = get_bbox();
- Rect ob = o.get_bbox();
-
- bool inReach_left = ((ob.p2.x < mb.p1.x) && (ob.p2.x >= mb.p1.x-((dir == LEFT) ? RANGE_OF_VISION : 0)));
- bool inReach_right = ((ob.p1.x > mb.p2.x) && (ob.p1.x <= mb.p2.x+((dir == RIGHT) ? RANGE_OF_VISION : 0)));
- bool inReach_top = (ob.p2.y >= mb.p1.y);
- bool inReach_bottom = (ob.p1.y <= mb.p2.y);
-
- return ((inReach_left || inReach_right) && inReach_top && inReach_bottom);
-}
-
-void
-Igel::active_update(float elapsed_time)
-{
- bool wants_to_flee = false;
-
- // check if we see a fire bullet
- Sector* sector = Sector::current();
- for (Sector::GameObjects::iterator i = sector->gameobjects.begin(); i != sector->gameobjects.end(); ++i) {
- Bullet* bullet = dynamic_cast<Bullet*>(*i);
- if (!bullet) continue;
- if (bullet->get_type() != FIRE_BONUS) continue;
- if (can_see(*bullet)) wants_to_flee = true;
- }
-
- // if we flee, handle this ourselves
- if (wants_to_flee && (!turn_recover_timer.started())) {
- turn_around();
- BadGuy::active_update(elapsed_time);
- return;
- }
-
- // else adhere to default behaviour
- WalkingBadguy::active_update(elapsed_time);
-}
-
-HitResponse
-Igel::collision_bullet(Bullet& bullet, const CollisionHit& hit)
-{
- // default reaction if hit on front side
- if (((dir == LEFT) && hit.left) || ((dir == RIGHT) && hit.right)) {
- return BadGuy::collision_bullet(bullet, hit);
- }
-
- // else make bullet ricochet and ignore the hit
- bullet.ricochet(*this, hit);
- return FORCE_MOVE;
-}
-
-bool
-Igel::collision_squished(GameObject& )
-{
- // this will hurt
- return false;
-}
-
-IMPLEMENT_FACTORY(Igel, "igel")
+++ /dev/null
-// $Id$
-//
-// SuperTux - Badguy "Igel"
-// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
-//
-// 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.
-
-#ifndef __IGEL_H__
-#define __IGEL_H__
-
-#include "walking_badguy.hpp"
-#include "moving_object.hpp"
-
-/**
- * Badguy "Igel" - a hedgehog that can absorb bullets
- */
-class Igel : public WalkingBadguy
-{
-public:
- Igel(const lisp::Lisp& reader);
- Igel(const Vector& pos, Direction d);
-
- void write(lisp::Writer& writer);
- HitResponse collision_bullet(Bullet& bullet, const CollisionHit& hit);
-
- void active_update(float elapsed_time);
-
- virtual Igel* clone() const { return new Igel(*this); }
-
-protected:
- bool collision_squished(GameObject& object);
- void be_normal(); /**< switch to state STATE_NORMAL */
- void turn_around(); /**< reverse direction, assumes we are in STATE_NORMAL */
- bool can_see(const MovingObject& o); /**< check if we can see o */
-
-private:
- Timer turn_recover_timer; /**< wait time until we will turn around again when shot at */
-
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include "jumpy.hpp"
-
-static const float JUMPSPEED=-600;
-static const float JUMPY_MID_TOLERANCE=4;
-static const float JUMPY_LOW_TOLERANCE=2;
-
-Jumpy::Jumpy(const lisp::Lisp& reader)
- : BadGuy(reader, "images/creatures/jumpy/jumpy.sprite"), groundhit_pos_set(false)
-{
-}
-
-void
-Jumpy::write(lisp::Writer& writer)
-{
- writer.start_list("jumpy");
-
- writer.write_float("x", start_position.x);
- writer.write_float("y", start_position.y);
-
- writer.end_list("jumpy");
-}
-
-void
-Jumpy::collision_solid(const CollisionHit& chit)
-{
- hit(chit);
-}
-
-HitResponse
-Jumpy::collision_badguy(BadGuy& , const CollisionHit& chit)
-{
- return hit(chit);
-}
-
-HitResponse
-Jumpy::hit(const CollisionHit& chit)
-{
- if(chit.bottom) {
- if (!groundhit_pos_set)
- {
- pos_groundhit = get_pos();
- groundhit_pos_set = true;
- }
-
- physic.set_velocity_y(frozen ? 0 : JUMPSPEED);
- // TODO create a nice sound for this...
- //sound_manager->play("sounds/skid.wav");
- } else if(chit.top) {
- physic.set_velocity_y(0);
- }
-
- return CONTINUE;
-}
-
-void
-Jumpy::active_update(float elapsed_time)
-{
- BadGuy::active_update(elapsed_time);
-
- if(frozen)
- return;
-
- Player* player = this->get_nearest_player();
- if (player)
- {
- dir = (player->get_pos().x > get_pos().x) ? RIGHT : LEFT;
- }
-
- if (!groundhit_pos_set)
- {
- sprite->set_action(dir == LEFT ? "left-middle" : "right-middle");
- return;
- }
-
- if ( get_pos().y < (pos_groundhit.y - JUMPY_MID_TOLERANCE ) )
- sprite->set_action(dir == LEFT ? "left-up" : "right-up");
- else if ( get_pos().y >= (pos_groundhit.y - JUMPY_MID_TOLERANCE) &&
- get_pos().y < (pos_groundhit.y - JUMPY_LOW_TOLERANCE) )
- sprite->set_action(dir == LEFT ? "left-middle" : "right-middle");
- else
- sprite->set_action(dir == LEFT ? "left-down" : "right-down");
-}
-
-void
-Jumpy::freeze()
-{
- BadGuy::freeze();
- physic.set_velocity_y(std::max(0.0f, physic.get_velocity_y()));
- sprite->set_action(dir == LEFT ? "left-iced" : "right-iced");
-}
-
-bool
-Jumpy::is_freezable() const
-{
- return true;
-}
-
-IMPLEMENT_FACTORY(Jumpy, "jumpy")
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __JUMPY_H__
-#define __JUMPY_H__
-
-#include "badguy.hpp"
-
-class Jumpy : public BadGuy
-{
-public:
- Jumpy(const lisp::Lisp& reader);
-
- void collision_solid(const CollisionHit& hit);
- HitResponse collision_badguy(BadGuy& other, const CollisionHit& hit);
-
- void write(lisp::Writer& writer);
- void active_update(float);
-
- void freeze();
- bool is_freezable() const;
-
- virtual Jumpy* clone() const { return new Jumpy(*this); }
-
-private:
- HitResponse hit(const CollisionHit& hit);
- Vector pos_groundhit;
- bool groundhit_pos_set;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include "kugelblitz.hpp"
-#include "object/tilemap.hpp"
-#include "object/camera.hpp"
-#include "tile.hpp"
-#include "random_generator.hpp"
-
-#define LIFETIME 5
-#define MOVETIME 0.75
-#define BASE_SPEED 200
-#define RAND_SPEED 150
-
-static const float X_OFFSCREEN_DISTANCE = 1600;
-static const float Y_OFFSCREEN_DISTANCE = 1200;
-
-Kugelblitz::Kugelblitz(const lisp::Lisp& reader)
- : BadGuy(Vector(0,0), "images/creatures/kugelblitz/kugelblitz.sprite"), groundhit_pos_set(false)
-{
- reader.get("x", start_position.x);
- sprite->set_action("falling");
- physic.enable_gravity(false);
-}
-
-void
-Kugelblitz::write(lisp::Writer& writer)
-{
- writer.start_list("kugelblitz");
-
- writer.write_float("x", start_position.x);
-
- writer.end_list("kugelblitz");
-}
-
-void
-Kugelblitz::activate()
-{
- physic.set_velocity_y(300);
- physic.set_velocity_x(-20); //fall a little to the left
- direction = 1;
- dying = false;
-}
-
-void
-Kugelblitz::collision_solid(const CollisionHit& chit)
-{
- hit(chit);
-}
-
-HitResponse
-Kugelblitz::collision_player(Player& player, const CollisionHit& )
-{
- if(player.is_invincible()) {
- explode();
- return ABORT_MOVE;
- }
- // hit from above?
- if(player.get_movement().y - get_movement().y > 0 && player.get_bbox().p2.y <
- (get_bbox().p1.y + get_bbox().p2.y) / 2) {
- // if it's not is it possible to squish us, then this will hurt
- if(!collision_squished(player))
- player.kill(false);
- explode();
- return FORCE_MOVE;
- }
- player.kill(false);
- explode();
- return FORCE_MOVE;
-}
-
-HitResponse
-Kugelblitz::collision_badguy(BadGuy& other , const CollisionHit& chit)
-{
- //Let the Kugelblitz explode, too? The problem with that is that
- //two Kugelblitzes would cancel each other out on contact...
- other.kill_fall();
- return hit(chit);
-}
-
-HitResponse
-Kugelblitz::hit(const CollisionHit& hit)
-{
- // hit floor?
- if(hit.bottom) {
- if (!groundhit_pos_set)
- {
- pos_groundhit = get_pos();
- groundhit_pos_set = true;
- }
- sprite->set_action("flying");
- physic.set_velocity_y(0);
- //Set random initial speed and direction
- direction = systemRandom.rand(2)? 1: -1;
- int speed = (BASE_SPEED + (systemRandom.rand(RAND_SPEED))) * direction;
- physic.set_velocity_x(speed);
- movement_timer.start(MOVETIME);
- lifetime.start(LIFETIME);
-
- } else if(hit.top) { // bumped on roof
- physic.set_velocity_y(0);
- }
-
- return CONTINUE;
-}
-
-void
-Kugelblitz::active_update(float elapsed_time)
-{
- if (lifetime.check()) {
- explode();
- }
- else {
- if (groundhit_pos_set) {
- if (movement_timer.check()) {
- if (direction == 1) direction = -1; else direction = 1;
- int speed = (BASE_SPEED + (systemRandom.rand(RAND_SPEED))) * direction;
- physic.set_velocity_x(speed);
- movement_timer.start(MOVETIME);
- }
- }
- /*
- if (Sector::current()->solids->get_tile_at(get_pos())->getAttributes() == 16) {
- //HIT WATER
- Sector::current()->add_object(new Electrifier(75,1421,1.5));
- Sector::current()->add_object(new Electrifier(76,1422,1.5));
- explode();
- }
- if (Sector::current()->solids->get_tile_at(get_pos())->getAttributes() == 48) {
- //HIT ELECTRIFIED WATER
- explode();
- }
- */
- }
- BadGuy::active_update(elapsed_time);
-}
-
-void
-Kugelblitz::kill_fall()
-{
-}
-
-void
-Kugelblitz::explode()
-{
- if (!dying) {
- sprite->set_action("pop");
- lifetime.start(0.2f);
- dying = true;
- }
- else remove_me();
-}
-
-void
-Kugelblitz::try_activate()
-{
- //FIXME: Don't activate Kugelblitz before it's on-screen
- float scroll_x = Sector::current()->camera->get_translation().x;
- float scroll_y = Sector::current()->camera->get_translation().y;
-
- /* Activate badguys if they're just around the screen to avoid
- * the effect of having badguys suddenly popping up from nowhere.
- */
- if (start_position.x > scroll_x - X_OFFSCREEN_DISTANCE &&
- start_position.x < scroll_x - bbox.get_width() &&
- start_position.y > scroll_y - Y_OFFSCREEN_DISTANCE &&
- start_position.y < scroll_y + Y_OFFSCREEN_DISTANCE) {
- dir = RIGHT;
- set_state(STATE_ACTIVE);
- activate();
- } else if (start_position.x > scroll_x &&
- start_position.x < scroll_x + X_OFFSCREEN_DISTANCE &&
- start_position.y > scroll_y - Y_OFFSCREEN_DISTANCE &&
- start_position.y < scroll_y + Y_OFFSCREEN_DISTANCE) {
- dir = LEFT;
- set_state(STATE_ACTIVE);
- activate();
- } else if (start_position.x > scroll_x - X_OFFSCREEN_DISTANCE &&
- start_position.x < scroll_x + X_OFFSCREEN_DISTANCE &&
- ((start_position.y > scroll_y &&
- start_position.y < scroll_y + Y_OFFSCREEN_DISTANCE) ||
- (start_position.y > scroll_y - Y_OFFSCREEN_DISTANCE &&
- start_position.y < scroll_y))) {
- dir = start_position.x < scroll_x ? RIGHT : LEFT;
- set_state(STATE_ACTIVE);
- activate();
- } else if(state == STATE_INIT
- && start_position.x > scroll_x - X_OFFSCREEN_DISTANCE
- && start_position.x < scroll_x + X_OFFSCREEN_DISTANCE
- && start_position.y > scroll_y - Y_OFFSCREEN_DISTANCE
- && start_position.y < scroll_y + Y_OFFSCREEN_DISTANCE) {
- dir = LEFT;
- set_state(STATE_ACTIVE);
- activate();
- }
-}
-
-IMPLEMENT_FACTORY(Kugelblitz, "kugelblitz")
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __KUGELBLITZ_H__
-#define __KUGELBLITZ_H__
-
-#include "badguy.hpp"
-#include "timer.hpp"
-#include "object/electrifier.hpp"
-
-class Kugelblitz : public BadGuy
-{
-public:
- Kugelblitz(const lisp::Lisp& reader);
-
- void activate();
- HitResponse collision_badguy(BadGuy& other, const CollisionHit& hit);
- void collision_solid(const CollisionHit& hit);
- HitResponse collision_player(Player& player, const CollisionHit& hit);
-
- void write(lisp::Writer& writer);
- void active_update(float);
- void kill_fall();
- void explode();
-
- virtual Kugelblitz* clone() const { return new Kugelblitz(*this); }
-
-private:
- void try_activate();
- HitResponse hit(const CollisionHit& hit);
- Vector pos_groundhit;
- bool groundhit_pos_set;
- bool dying;
- Timer movement_timer;
- Timer lifetime;
- int direction;
- State state;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux - Mole Badguy
-// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
-//
-// 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.
-
-#include <config.h>
-
-#include "mole.hpp"
-#include "mole_rock.hpp"
-#include "tile.hpp"
-#include "object/tilemap.hpp"
-#include "random_generator.hpp"
-#include "log.hpp"
-#include "level.hpp"
-
-static const float IDLE_TIME = 0.2f; /**< time to wait before and after throwing */
-static const float THROW_TIME = 4.6f; /**< time to spend throwing */
-static const float THROW_INTERVAL = 1; /**< time between two thrown rocks */
-static const float THROW_VELOCITY = 400; /**< initial velocity of thrown rocks */
-
-Mole::Mole(const lisp::Lisp& reader)
- : BadGuy(reader, "images/creatures/mole/mole.sprite", LAYER_TILES-1), state(PRE_THROWING)
-{
- physic.enable_gravity(false);
-}
-
-Mole::Mole(const Vector& pos)
- : BadGuy(pos, "images/creatures/mole/mole.sprite", LAYER_TILES-1), state(PRE_THROWING)
-{
- physic.enable_gravity(false);
-}
-
-void
-Mole::write(lisp::Writer& writer)
-{
- writer.start_list("mole");
- writer.write_float("x", start_position.x);
- writer.write_float("y", start_position.y);
- writer.end_list("mole");
-}
-
-void
-Mole::activate()
-{
- if (state != DEAD) set_state(PRE_THROWING);
-}
-
-void
-Mole::kill_fall()
-{
- set_state(DEAD);
- sound_manager->play("sounds/fall.wav", get_pos());
- if (countMe) Sector::current()->get_level()->stats.badguys++;
-}
-
-HitResponse
-Mole::collision_badguy(BadGuy& , const CollisionHit& )
-{
- return FORCE_MOVE;
-}
-
-bool
-Mole::collision_squished(GameObject& )
-{
- set_state(DEAD);
- sound_manager->play("sounds/squish.wav", get_pos());
- if (countMe) Sector::current()->get_level()->stats.badguys++;
- return true;
-}
-
-void
-Mole::throw_rock()
-{
- float px = get_bbox().get_middle().x;
- float py = get_bbox().get_middle().y;
-
- float angle = systemRandom.rand(90 - 15, 90 + 15) * (M_PI / 180);
- float vx = cos(angle) * THROW_VELOCITY;
- float vy = -sin(angle) * THROW_VELOCITY;
-
- sound_manager->play("sounds/dartfire.wav", get_pos());
- Sector::current()->add_object(new MoleRock(Vector(px, py), Vector(vx, vy), this));
-}
-
-void
-Mole::active_update(float elapsed_time)
-{
- BadGuy::active_update(elapsed_time);
-
- switch (state) {
- case PRE_THROWING:
- if (timer.check()) {
- set_state(THROWING);
- }
- break;
- case THROWING:
- if (throw_timer.check()) {
- throw_rock();
- throw_timer.start(THROW_INTERVAL);
- }
- if (timer.check()) {
- set_state(POST_THROWING);
- }
- break;
- case POST_THROWING:
- if (timer.check()) {
- set_state(PEEKING);
- }
- break;
- case PEEKING:
- if (sprite->animation_done()) {
- set_state(PRE_THROWING);
- }
- break;
- case DEAD:
- break;
- }
-
-}
-
-void
-Mole::set_state(MoleState new_state)
-{
- switch (new_state) {
- case PRE_THROWING:
- sprite->set_action("idle");
- set_group(COLGROUP_DISABLED);
- timer.start(IDLE_TIME);
- break;
- case THROWING:
- sprite->set_action("idle");
- set_group(COLGROUP_DISABLED);
- timer.start(THROW_TIME);
- throw_timer.start(THROW_INTERVAL);
- break;
- case POST_THROWING:
- sprite->set_action("idle");
- set_group(COLGROUP_DISABLED);
- timer.start(IDLE_TIME);
- break;
- case PEEKING:
- sprite->set_action("peeking", 1);
- set_group(COLGROUP_STATIC);
- break;
- case DEAD:
- sprite->set_action("idle");
- set_group(COLGROUP_DISABLED);
- break;
- }
-
- state = new_state;
-}
-
-IMPLEMENT_FACTORY(Mole, "mole")
+++ /dev/null
-// $Id$
-//
-// SuperTux - Mole Badguy
-// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
-//
-// 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.
-
-#ifndef __MOLE_H__
-#define __MOLE_H__
-
-#include "badguy.hpp"
-
-class Mole : public BadGuy
-{
-public:
- Mole(const lisp::Lisp& );
- Mole(const Vector& pos);
-
- void kill_fall();
- HitResponse collision_badguy(BadGuy& , const CollisionHit& );
- bool collision_squished(GameObject& object);
-
- void activate();
- void write(lisp::Writer& );
- void active_update(float);
-
- virtual Mole* clone() const { return new Mole(*this); }
-
-private:
- enum MoleState {
- PRE_THROWING,
- THROWING,
- POST_THROWING,
- PEEKING,
- DEAD
- };
-
- MoleState state;
- Timer timer;
- Timer throw_timer;
-
- void set_state(MoleState new_state);
- void throw_rock();
-
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// MoleRock - Rock thrown by "Mole" Badguy
-// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
-//
-// 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.
-
-#include <config.h>
-
-#include "mole_rock.hpp"
-
-MoleRock::MoleRock(const lisp::Lisp& reader)
- : BadGuy(reader, "images/creatures/mole/mole_rock.sprite", LAYER_TILES - 2), parent(0), initial_velocity(Vector(0, -400))
-{
- physic.enable_gravity(true);
- countMe = false;
-}
-
-MoleRock::MoleRock(const Vector& pos, const Vector& velocity, const BadGuy* parent = 0)
- : BadGuy(pos, LEFT, "images/creatures/mole/mole_rock.sprite", LAYER_TILES - 2), parent(parent), initial_velocity(velocity)
-{
- physic.enable_gravity(true);
- countMe = false;
-}
-
-MoleRock::MoleRock(const MoleRock& other)
- : BadGuy(other), parent(other.parent), initial_velocity(Vector(0, -400))
-{
-}
-
-MoleRock::~MoleRock()
-{
-}
-
-bool
-MoleRock::updatePointers(const GameObject* from_object, GameObject* to_object)
-{
- if (from_object == parent) {
- parent = dynamic_cast<MoleRock*>(to_object);
- return true;
- }
- return false;
-}
-
-void
-MoleRock::write(lisp::Writer& writer)
-{
- writer.start_list("mole_rock");
- writer.write_float("x", start_position.x);
- writer.write_float("y", start_position.y);
- writer.end_list("mole_rock");
-}
-
-void
-MoleRock::activate()
-{
- physic.set_velocity(initial_velocity);
- sprite->set_action("default");
-}
-
-void
-MoleRock::deactivate()
-{
- remove_me();
-}
-
-void
-MoleRock::active_update(float elapsed_time)
-{
- BadGuy::active_update(elapsed_time);
-}
-
-void
-MoleRock::collision_solid(const CollisionHit& )
-{
- sound_manager->play("sounds/darthit.wav", get_pos());
- remove_me();
-}
-
-HitResponse
-MoleRock::collision_badguy(BadGuy& badguy, const CollisionHit& )
-{
- // ignore collisions with parent
- if (&badguy == parent) {
- return FORCE_MOVE;
- }
- sound_manager->play("sounds/stomp.wav", get_pos());
- remove_me();
- badguy.kill_fall();
- return ABORT_MOVE;
-}
-
-HitResponse
-MoleRock::collision_player(Player& player, const CollisionHit& hit)
-{
- sound_manager->play("sounds/stomp.wav", get_pos());
- remove_me();
- return BadGuy::collision_player(player, hit);
-}
-
-IMPLEMENT_FACTORY(MoleRock, "mole_rock")
+++ /dev/null
-// $Id$
-//
-// MoleRock - Rock thrown by "Mole" Badguy
-// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
-//
-// 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.
-
-#ifndef __MOLE_ROCK_H__
-#define __MOLE_ROCK_H__
-
-#include "badguy.hpp"
-
-/**
- * Badguy "MoleRock" - Rock thrown by "Mole" Badguy
- */
-class MoleRock : public BadGuy
-{
-public:
- MoleRock(const lisp::Lisp& reader);
- MoleRock(const Vector& pos, const Vector& velocity, const BadGuy* parent);
- MoleRock(const MoleRock& mole_rock);
- ~MoleRock();
-
- void activate();
- void deactivate();
- void write(lisp::Writer& writer);
-
- void active_update(float elapsed_time);
-
- void collision_solid(const CollisionHit& hit);
- HitResponse collision_badguy(BadGuy& badguy, const CollisionHit& hit);
- HitResponse collision_player(Player& player, const CollisionHit& hit);
-
- virtual MoleRock* clone() const { return new MoleRock(*this); }
-
- virtual bool updatePointers(const GameObject* from_object, GameObject* to_object);
-
-protected:
- const BadGuy* parent; /**< collisions with this BadGuy will be ignored */
- const Vector initial_velocity; /**< velocity at time of creation */
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include "mrbomb.hpp"
-#include "bomb.hpp"
-#include "object/explosion.hpp"
-#include "sprite/sprite_manager.hpp"
-#include "audio/sound_manager.hpp"
-
-MrBomb::MrBomb(const lisp::Lisp& reader)
- : WalkingBadguy(reader, "images/creatures/mr_bomb/mr_bomb.sprite", "left", "right")
-{
- walk_speed = 80;
- max_drop_height = 16;
- grabbed = false;
-
- //Prevent stutter when Tux jumps on Mr Bomb
- sound_manager->preload("sounds/explosion.wav");
-
- //Check if we need another sprite
- if( !reader.get( "sprite", sprite_name ) ){
- return;
- }
- if( sprite_name == "" ){
- sprite_name = "images/creatures/mr_bomb/mr_bomb.sprite";
- return;
- }
- //Replace sprite
- sprite = sprite_manager->create( sprite_name );
-}
-
-/* MrBomb created by a despencer always gets default sprite atm.*/
-MrBomb::MrBomb(const Vector& pos, Direction d)
- : WalkingBadguy(pos, d, "images/creatures/mr_bomb/mr_bomb.sprite", "left", "right")
-{
- walk_speed = 80;
- max_drop_height = 16;
- grabbed = false;
- sound_manager->preload("sounds/explosion.wav");
-}
-
-void
-MrBomb::write(lisp::Writer& writer)
-{
- writer.start_list("mrbomb");
- WalkingBadguy::write(writer);
- writer.end_list("mrbomb");
-}
-
-HitResponse
-MrBomb::collision(GameObject& object, const CollisionHit& hit)
-{
- if(grabbed)
- return FORCE_MOVE;
- return WalkingBadguy::collision(object, hit);
-}
-
-HitResponse
-MrBomb::collision_player(Player& player, const CollisionHit& hit)
-{
- if(grabbed)
- return FORCE_MOVE;
- return WalkingBadguy::collision_player(player, hit);
-}
-
-bool
-MrBomb::collision_squished(GameObject& object)
-{
- remove_me();
- Sector::current()->add_object(new Bomb(get_pos(), dir, sprite_name ));
- kill_squished(object);
- return true;
-}
-
-void
-MrBomb::active_update(float elapsed_time)
-{
- if(grabbed)
- return;
- WalkingBadguy::active_update(elapsed_time);
-}
-
-void
-MrBomb::kill_fall()
-{
- remove_me();
- Explosion* explosion = new Explosion(get_bbox().get_middle());
- Sector::current()->add_object(explosion);
-
- run_dead_script();
-}
-
-void
-MrBomb::grab(MovingObject&, const Vector& pos, Direction dir)
-{
- assert(frozen);
- movement = pos - get_pos();
- this->dir = dir;
- sprite->set_action(dir == LEFT ? "iced-left" : "iced-right");
- set_group(COLGROUP_DISABLED);
- grabbed = true;
-}
-
-void
-MrBomb::ungrab(MovingObject& , Direction dir)
-{
- this->dir = dir;
- set_group(COLGROUP_MOVING);
- grabbed = false;
-}
-
-void
-MrBomb::freeze()
-{
- WalkingBadguy::freeze();
- sprite->set_action(dir == LEFT ? "iced-left" : "iced-right");
-}
-
-bool
-MrBomb::is_freezable() const
-{
- return true;
-}
-
-bool
-MrBomb::is_portable() const
-{
- return frozen;
-}
-
-IMPLEMENT_FACTORY(MrBomb, "mrbomb")
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __MRBOMB_H__
-#define __MRBOMB_H__
-
-#include "walking_badguy.hpp"
-#include "object/portable.hpp"
-
-class MrBomb : public WalkingBadguy, public Portable
-{
-public:
- MrBomb(const lisp::Lisp& reader);
- MrBomb(const Vector& pos, Direction d);
-
- void write(lisp::Writer& writer);
- void kill_fall();
- HitResponse collision(GameObject& object, const CollisionHit& hit);
- HitResponse collision_player(Player& player, const CollisionHit& hit);
-
- void active_update(float elapsed_time);
-
- void grab(MovingObject& object, const Vector& pos, Direction dir);
- void ungrab(MovingObject& object, Direction dir);
- bool is_portable() const;
-
- void freeze();
- bool is_freezable() const;
-
- virtual MrBomb* clone() const { return new MrBomb(*this); }
-
-protected:
- bool collision_squished(GameObject& object);
-
-private:
- bool grabbed;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include "mriceblock.hpp"
-#include "object/block.hpp"
-
-namespace {
- const float KICKSPEED = 500;
- const int MAXSQUISHES = 10;
-}
-
-MrIceBlock::MrIceBlock(const lisp::Lisp& reader)
- : WalkingBadguy(reader, "images/creatures/mr_iceblock/mr_iceblock.sprite", "left", "right"), ice_state(ICESTATE_NORMAL), squishcount(0)
-{
- walk_speed = 80;
- max_drop_height = 600;
- sound_manager->preload("sounds/iceblock_bump.wav");
- sound_manager->preload("sounds/stomp.wav");
- sound_manager->preload("sounds/kick.wav");
-}
-
-MrIceBlock::MrIceBlock(const Vector& pos, Direction d)
- : WalkingBadguy(pos, d, "images/creatures/mr_iceblock/mr_iceblock.sprite", "left", "right"), ice_state(ICESTATE_NORMAL), squishcount(0)
-{
- walk_speed = 80;
- max_drop_height = 600;
- sound_manager->preload("sounds/iceblock_bump.wav");
- sound_manager->preload("sounds/stomp.wav");
- sound_manager->preload("sounds/kick.wav");
-}
-
-void
-MrIceBlock::write(lisp::Writer& writer)
-{
- writer.start_list("mriceblock");
- WalkingBadguy::write(writer);
- writer.end_list("mriceblock");
-}
-
-void
-MrIceBlock::activate()
-{
- WalkingBadguy::activate();
- set_state(ICESTATE_NORMAL);
-}
-
-void
-MrIceBlock::active_update(float elapsed_time)
-{
- if(ice_state == ICESTATE_GRABBED)
- return;
-
- if(ice_state == ICESTATE_FLAT && flat_timer.check()) {
- set_state(ICESTATE_NORMAL);
- }
-
- if (ice_state == ICESTATE_NORMAL)
- {
- WalkingBadguy::active_update(elapsed_time);
- return;
- }
-
- BadGuy::active_update(elapsed_time);
-}
-
-bool
-MrIceBlock::can_break(){
- return ice_state == ICESTATE_KICKED;
-}
-
-void
-MrIceBlock::collision_solid(const CollisionHit& hit)
-{
- update_on_ground_flag(hit);
-
- if(hit.top || hit.bottom) { // floor or roof
- physic.set_velocity_y(0);
- return;
- }
-
- // hit left or right
- switch(ice_state) {
- case ICESTATE_NORMAL:
- WalkingBadguy::collision_solid(hit);
- break;
- case ICESTATE_KICKED: {
- if(hit.right && dir == RIGHT) {
- dir = LEFT;
- sound_manager->play("sounds/iceblock_bump.wav", get_pos());
- physic.set_velocity_x(-KICKSPEED);
- } else if(hit.left && dir == LEFT) {
- dir = RIGHT;
- sound_manager->play("sounds/iceblock_bump.wav", get_pos());
- physic.set_velocity_x(KICKSPEED);
- }
- sprite->set_action(dir == LEFT ? "flat-left" : "flat-right");
- break;
- }
- case ICESTATE_FLAT:
- physic.set_velocity_x(0);
- break;
- case ICESTATE_GRABBED:
- break;
- }
-}
-
-HitResponse
-MrIceBlock::collision(GameObject& object, const CollisionHit& hit)
-{
- if(ice_state == ICESTATE_GRABBED)
- return FORCE_MOVE;
-
- return BadGuy::collision(object, hit);
-}
-
-HitResponse
-MrIceBlock::collision_player(Player& player, const CollisionHit& hit)
-{
- if(ice_state == ICESTATE_GRABBED)
- return FORCE_MOVE;
-
- if(dir == UP) {
- return FORCE_MOVE;
- }
-
- // handle kicks from left or right side
- if(ice_state == ICESTATE_FLAT && get_state() == STATE_ACTIVE) {
- if(hit.left) {
- dir = RIGHT;
- player.kick();
- set_state(ICESTATE_KICKED);
- return FORCE_MOVE;
- } else if(hit.right) {
- dir = LEFT;
- player.kick();
- set_state(ICESTATE_KICKED);
- return FORCE_MOVE;
- }
- }
-
- return BadGuy::collision_player(player, hit);
-}
-
-HitResponse
-MrIceBlock::collision_badguy(BadGuy& badguy, const CollisionHit& hit)
-{
- switch(ice_state) {
- case ICESTATE_NORMAL:
- return WalkingBadguy::collision_badguy(badguy, hit);
- case ICESTATE_FLAT:
- return FORCE_MOVE;
- case ICESTATE_KICKED:
- badguy.kill_fall();
- return FORCE_MOVE;
- default:
- assert(false);
- }
-
- return ABORT_MOVE;
-}
-
-bool
-MrIceBlock::collision_squished(GameObject& object)
-{
- switch(ice_state) {
- case ICESTATE_KICKED:
- case ICESTATE_NORMAL:
- squishcount++;
- if(squishcount >= MAXSQUISHES) {
- kill_fall();
- return true;
- }
-
- set_state(ICESTATE_FLAT);
- break;
- case ICESTATE_FLAT:
- {
- MovingObject* movingobject = dynamic_cast<MovingObject*>(&object);
- if (movingobject && (movingobject->get_pos().x < get_pos().x)) {
- dir = RIGHT;
- } else {
- dir = LEFT;
- }
- }
- set_state(ICESTATE_KICKED);
- break;
- case ICESTATE_GRABBED:
- assert(false);
- break;
- }
-
- Player* player = dynamic_cast<Player*>(&object);
- if (player) player->bounce(*this);
- return true;
-}
-
-void
-MrIceBlock::set_state(IceState state)
-{
- if(ice_state == state)
- return;
-
- switch(state) {
- case ICESTATE_NORMAL:
- WalkingBadguy::activate();
- break;
- case ICESTATE_FLAT:
- if(dir == UP) {
- physic.set_velocity_y(-KICKSPEED);
- bbox.set_size(34, 31.8f);
- } else {
- sound_manager->play("sounds/stomp.wav", get_pos());
- physic.set_velocity_x(0);
- physic.set_velocity_y(0);
-
- sprite->set_action(dir == LEFT ? "flat-left" : "flat-right");
- }
- flat_timer.start(4);
- break;
- case ICESTATE_KICKED:
- sound_manager->play("sounds/kick.wav", get_pos());
-
- physic.set_velocity_x(dir == LEFT ? -KICKSPEED : KICKSPEED);
- sprite->set_action(dir == LEFT ? "flat-left" : "flat-right");
- // we should slide above 1 block holes now...
- bbox.set_size(34, 31.8f);
- break;
- case ICESTATE_GRABBED:
- flat_timer.stop();
- break;
- default:
- assert(false);
- }
- ice_state = state;
-}
-
-void
-MrIceBlock::grab(MovingObject&, const Vector& pos, Direction dir)
-{
- movement = pos - get_pos();
- this->dir = dir;
- sprite->set_action(dir == LEFT ? "flat-left" : "flat-right");
- set_state(ICESTATE_GRABBED);
- set_group(COLGROUP_DISABLED);
-}
-
-void
-MrIceBlock::ungrab(MovingObject& , Direction dir)
-{
- this->dir = dir;
- set_state(dir == UP ? ICESTATE_FLAT : ICESTATE_KICKED);
- set_group(COLGROUP_MOVING);
-}
-
-bool
-MrIceBlock::is_portable() const
-{
- return ice_state == ICESTATE_FLAT;
-}
-
-IMPLEMENT_FACTORY(MrIceBlock, "mriceblock")
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __MRICEBLOCK_H__
-#define __MRICEBLOCK_H__
-
-#include "walking_badguy.hpp"
-#include "object/portable.hpp"
-
-class MrIceBlock : public WalkingBadguy, public Portable
-{
-public:
- MrIceBlock(const lisp::Lisp& reader);
- MrIceBlock(const Vector& pos, Direction d);
-
- void activate();
- void write(lisp::Writer& writer);
- HitResponse collision(GameObject& object, const CollisionHit& hit);
- void collision_solid(const CollisionHit& hit);
- HitResponse collision_badguy(BadGuy& badguy, const CollisionHit& hit);
- HitResponse collision_player(Player& player, const CollisionHit& hit);
-
- void active_update(float elapsed_time);
-
- void grab(MovingObject& object, const Vector& pos, Direction dir);
- void ungrab(MovingObject& object, Direction dir);
- bool is_portable() const;
-
- bool can_break();
-
- virtual MrIceBlock* clone() const { return new MrIceBlock(*this); }
-
-protected:
- bool collision_squished(GameObject& object);
-
-private:
- enum IceState {
- ICESTATE_NORMAL,
- ICESTATE_FLAT,
- ICESTATE_GRABBED,
- ICESTATE_KICKED
- };
-
- void set_state(IceState state);
-
- IceState ice_state;
- Timer flat_timer;
- int squishcount;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include "mrrocket.hpp"
-#include "object/explosion.hpp"
-
-static const float SPEED = 200;
-
-MrRocket::MrRocket(const lisp::Lisp& reader)
- : BadGuy(reader, "images/creatures/mr_rocket/mr_rocket.sprite")
-{
-}
-
-MrRocket::MrRocket(const Vector& pos, Direction d)
- : BadGuy(pos, d, "images/creatures/mr_rocket/mr_rocket.sprite")
-{
-}
-
-void
-MrRocket::write(lisp::Writer& writer)
-{
- writer.start_list("mrrocket");
-
- writer.write_float("x", start_position.x);
- writer.write_float("y", start_position.y);
-
- writer.end_list("mrrocket");
-}
-
-void
-MrRocket::activate()
-{
- physic.set_velocity_x(dir == LEFT ? -SPEED : SPEED);
- physic.enable_gravity(false);
- sprite->set_action(dir == LEFT ? "left" : "right");
-}
-
-void
-MrRocket::active_update(float elapsed_time)
-{
- if (collision_timer.check()) {
- Sector::current()->add_object(new Explosion(get_bbox().get_middle()));
- remove_me();
- }
- else if (!collision_timer.started()) {
- movement=physic.get_movement(elapsed_time);
- sprite->set_action(dir == LEFT ? "left" : "right");
- }
-}
-
-bool
-MrRocket::collision_squished(GameObject& object)
-{
- sprite->set_action(dir == LEFT ? "squished-left" : "squished-right");
- kill_squished(object);
- kill_fall();
- return true;
-}
-
-void
-MrRocket::collision_solid(const CollisionHit& hit)
-{
- if(hit.top || hit.bottom) {
- physic.set_velocity_y(0);
- } else if(hit.left || hit.right) {
- sprite->set_action(dir == LEFT ? "collision-left" : "collision-right");
- physic.set_velocity_x(0);
- collision_timer.start(0.2f, true);
- }
-}
-
-IMPLEMENT_FACTORY(MrRocket, "mrrocket")
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __MRROCKET_H__
-#define __MRROCKET_H__
-
-#include "badguy.hpp"
-#include "timer.hpp"
-
-class MrRocket : public BadGuy
-{
-public:
- MrRocket(const lisp::Lisp& reader);
- MrRocket(const Vector& pos, Direction d);
-
- void activate();
- void active_update(float elapsed_time);
- void write(lisp::Writer& writer);
- void collision_solid(const CollisionHit& hit);
-
- virtual MrRocket* clone() const { return new MrRocket(*this); }
-
-protected:
- bool collision_squished(GameObject& object);
- Timer collision_timer;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include "mrtree.hpp"
-#include "stumpy.hpp"
-#include "poisonivy.hpp"
-#include "random_generator.hpp"
-#include "object/sprite_particle.hpp"
-#include "sector.hpp"
-
-static const float WALKSPEED = 100;
-
-static const float POISONIVY_WIDTH = 32;
-static const float POISONIVY_HEIGHT = 32;
-static const float POISONIVY_Y_OFFSET = 24;
-
-
-MrTree::MrTree(const lisp::Lisp& reader)
- : WalkingBadguy(reader, "images/creatures/mr_tree/mr_tree.sprite","left","right")
-{
- walk_speed = WALKSPEED;
- max_drop_height = 16;
- sound_manager->preload("sounds/mr_tree.ogg");
-}
-
-void
-MrTree::write(lisp::Writer& writer)
-{
- writer.start_list("mrtree");
- WalkingBadguy::write(writer);
- writer.end_list("mrtree");
-}
-
-bool
-MrTree::collision_squished(GameObject& object)
-{
- // replace with Stumpy
- Vector stumpy_pos = get_pos();
- stumpy_pos.x += 20;
- stumpy_pos.y += 25;
- Stumpy* stumpy = new Stumpy(stumpy_pos, dir);
- remove_me();
- Sector::current()->add_object(stumpy);
-
- // give Feedback
- sound_manager->play("sounds/mr_tree.ogg", get_pos());
- Player* player = dynamic_cast<Player*>(&object);
- if (player) player->bounce(*this);
-
- // spawn some particles
- // TODO: provide convenience function in MovingSprite or MovingObject?
- for (int px = (int)stumpy->get_bbox().p1.x; px < (int)stumpy->get_bbox().p2.x; px+=10) {
- Vector ppos = Vector(px, stumpy->get_bbox().p1.y-5);
- float angle = systemRandom.randf(-M_PI_2, M_PI_2);
- float velocity = systemRandom.randf(45, 90);
- float vx = sin(angle)*velocity;
- float vy = -cos(angle)*velocity;
- Vector pspeed = Vector(vx, vy);
- Vector paccel = Vector(0, 100);
- Sector::current()->add_object(new SpriteParticle("images/objects/particles/leaf.sprite", "default", ppos, ANCHOR_MIDDLE, pspeed, paccel, LAYER_OBJECTS-1));
- }
-
- // spawn PoisonIvy
- Vector leaf1_pos = Vector(stumpy_pos.x - POISONIVY_WIDTH - 1, stumpy_pos.y - POISONIVY_Y_OFFSET);
- Rect leaf1_bbox = Rect(leaf1_pos.x, leaf1_pos.y, leaf1_pos.x + POISONIVY_WIDTH, leaf1_pos.y + POISONIVY_HEIGHT);
- if (Sector::current()->is_free_of_movingstatics(leaf1_bbox, this)) {
- PoisonIvy* leaf1 = new PoisonIvy(leaf1_bbox.p1, LEFT);
- leaf1 = leaf1;
- Sector::current()->add_object(leaf1);
- }
-
- // spawn PoisonIvy
- Vector leaf2_pos = Vector(stumpy_pos.x + sprite->get_current_hitbox_width() + 1, stumpy_pos.y - POISONIVY_Y_OFFSET);
- Rect leaf2_bbox = Rect(leaf2_pos.x, leaf2_pos.y, leaf2_pos.x + POISONIVY_WIDTH, leaf2_pos.y + POISONIVY_HEIGHT);
- if (Sector::current()->is_free_of_movingstatics(leaf2_bbox, this)) {
- PoisonIvy* leaf2 = new PoisonIvy(leaf2_bbox.p1, RIGHT);
- leaf2 = leaf2;
- Sector::current()->add_object(leaf2);
- }
-
- return true;
-}
-
-IMPLEMENT_FACTORY(MrTree, "mrtree")
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __MRTREE_H__
-#define __MRTREE_H__
-
-#include "walking_badguy.hpp"
-
-class MrTree : public WalkingBadguy
-{
-public:
- MrTree(const lisp::Lisp& reader);
- void write(lisp::Writer& writer);
- virtual MrTree* clone() const { return new MrTree(*this); }
-
-protected:
- bool collision_squished(GameObject& object);
-
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include "plant.hpp"
-
-static const float WALKSPEED = 80;
-static const float WAKE_TIME = .5;
-
-Plant::Plant(const lisp::Lisp& reader)
- : BadGuy(reader, "images/creatures/plant/plant.sprite")
-{
- state = PLANT_SLEEPING;
-}
-
-void
-Plant::write(lisp::Writer& writer)
-{
- writer.start_list("plant");
-
- writer.write_float("x", start_position.x);
- writer.write_float("y", start_position.y);
-
- writer.end_list("plant");
-}
-
-void
-Plant::activate()
-{
- //FIXME: turns sspiky around for debugging
- dir = dir == LEFT ? RIGHT : LEFT;
-
- state = PLANT_SLEEPING;
- physic.set_velocity_x(0);
- sprite->set_action(dir == LEFT ? "sleeping-left" : "sleeping-right");
-}
-
-void
-Plant::collision_solid(const CollisionHit& hit)
-{
- if(hit.top || hit.bottom) {
- physic.set_velocity_y(0);
- } else if(hit.left || hit.right) {
- dir = dir == LEFT ? RIGHT : LEFT;
- sprite->set_action(dir == LEFT ? "left" : "right");
- physic.set_velocity_x(-physic.get_velocity_x());
- }
-}
-
-HitResponse
-Plant::collision_badguy(BadGuy& , const CollisionHit& hit)
-{
- if(state != PLANT_WALKING) return CONTINUE;
-
- if(hit.left || hit.right) {
- dir = dir == LEFT ? RIGHT : LEFT;
- sprite->set_action(dir == LEFT ? "left" : "right");
- physic.set_velocity_x(-physic.get_velocity_x());
- }
-
- return CONTINUE;
-}
-
-void
-Plant::active_update(float elapsed_time) {
- BadGuy::active_update(elapsed_time);
-
- if(state == PLANT_SLEEPING) {
-
- Player* player = this->get_nearest_player();
- if (player) {
- Rect mb = this->get_bbox();
- Rect pb = player->get_bbox();
-
- bool inReach_left = (pb.p2.x >= mb.p2.x-((dir == LEFT) ? 256 : 0));
- bool inReach_right = (pb.p1.x <= mb.p1.x+((dir == RIGHT) ? 256 : 0));
- bool inReach_top = (pb.p2.y >= mb.p2.y);
- bool inReach_bottom = (pb.p1.y <= mb.p1.y);
-
- if (inReach_left && inReach_right && inReach_top && inReach_bottom) {
- // wake up
- sprite->set_action(dir == LEFT ? "waking-left" : "waking-right");
- if(!timer.started()) timer.start(WAKE_TIME);
- state = PLANT_WAKING;
- }
- }
- }
-
- if(state == PLANT_WAKING) {
- if(timer.check()) {
- // start walking
- sprite->set_action(dir == LEFT ? "left" : "right");
- physic.set_velocity_x(dir == LEFT ? -WALKSPEED : WALKSPEED);
- state = PLANT_WALKING;
- }
- }
-
-}
-
-IMPLEMENT_FACTORY(Plant, "plant")
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __PLANT_H__
-#define __PLANT_H__
-
-#include "badguy.hpp"
-
-class Plant : public BadGuy
-{
-public:
- Plant(const lisp::Lisp& reader);
-
- void activate();
- void write(lisp::Writer& writer);
- void collision_solid(const CollisionHit& hit);
- HitResponse collision_badguy(BadGuy& badguy, const CollisionHit& hit);
- void active_update(float elapsed_time);
-
- virtual Plant* clone() const { return new Plant(*this); }
-
-protected:
- Timer timer;
-
- enum PlantState {
- PLANT_SLEEPING,
- PLANT_WAKING,
- PLANT_WALKING
- };
- PlantState state;
-
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include "poisonivy.hpp"
-#include "random_generator.hpp"
-#include "object/sprite_particle.hpp"
-
-PoisonIvy::PoisonIvy(const lisp::Lisp& reader)
- : WalkingBadguy(reader, "images/creatures/poison_ivy/poison_ivy.sprite", "left", "right")
-{
- walk_speed = 80;
-}
-
-PoisonIvy::PoisonIvy(const Vector& pos, Direction d)
- : WalkingBadguy(pos, d, "images/creatures/poison_ivy/poison_ivy.sprite", "left", "right")
-{
- walk_speed = 80;
-}
-
-void
-PoisonIvy::write(lisp::Writer& writer)
-{
- writer.start_list("poisonivy");
- WalkingBadguy::write(writer);
- writer.end_list("poisonivy");
-}
-
-bool
-PoisonIvy::collision_squished(GameObject& object)
-{
- sprite->set_action(dir == LEFT ? "squished-left" : "squished-right");
- // spawn some particles
- // TODO: provide convenience function in MovingSprite or MovingObject?
- for (int i = 0; i < 3; i++) {
- Vector ppos = bbox.get_middle();
- float angle = systemRandom.randf(-M_PI_2, M_PI_2);
- float velocity = systemRandom.randf(350, 400);
- float vx = sin(angle)*velocity;
- float vy = -cos(angle)*velocity;
- Vector pspeed = Vector(vx, vy);
- Vector paccel = Vector(0, 100);
- Sector::current()->add_object(new SpriteParticle("images/objects/particles/poisonivy.sprite", "default", ppos, ANCHOR_MIDDLE, pspeed, paccel, LAYER_OBJECTS-1));
- }
- kill_squished(object);
- return true;
-}
-
-IMPLEMENT_FACTORY(PoisonIvy, "poisonivy")
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __POISONIVY_H__
-#define __POISONIVY_H__
-
-#include "walking_badguy.hpp"
-
-class PoisonIvy : public WalkingBadguy
-{
-public:
- PoisonIvy(const lisp::Lisp& reader);
- PoisonIvy(const Vector& pos, Direction d);
-
- void write(lisp::Writer& writer);
- virtual PoisonIvy* clone() const { return new PoisonIvy(*this); }
-
-protected:
- bool collision_squished(GameObject& object);
-
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux - "Will-O-Wisp" Badguy
-// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
-//
-// 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.
-#include <config.h>
-
-#include "root.hpp"
-#include "sprite/sprite_manager.hpp"
-#include "timer.hpp"
-
-static const float SPEED_GROW = 256;
-static const float SPEED_SHRINK = 128;
-static const float HATCH_TIME = 0.75;
-
-Root::Root(const Vector& pos)
- : BadGuy(pos, "images/creatures/ghosttree/root.sprite", LAYER_TILES-1),
- mystate(STATE_APPEARING), offset_y(0)
-{
- base_sprite.reset(sprite_manager->create("images/creatures/ghosttree/root-base.sprite"));
- base_sprite->set_action("appearing", 1);
- base_sprite->set_animation_loops(1); // TODO: necessary because set_action ignores loops for default action
- physic.enable_gravity(false);
-}
-
-Root::~Root()
-{
-}
-
-void
-Root::activate()
-{
- set_group(COLGROUP_TOUCHABLE);
-}
-
-void
-Root::deactivate()
-{
- remove_me();
-}
-
-void
-Root::active_update(float elapsed_time)
-{
- if (mystate == STATE_APPEARING) {
- if (base_sprite->animation_done()) {
- hatch_timer.start(HATCH_TIME);
- mystate = STATE_HATCHING;
- }
- }
- if (mystate == STATE_HATCHING) {
- if (!hatch_timer.started()) mystate = STATE_GROWING;
- }
- else if (mystate == STATE_GROWING) {
- offset_y -= elapsed_time * SPEED_GROW;
- if (offset_y < -sprite->get_height()) {
- offset_y = -sprite->get_height();
- mystate = STATE_SHRINKING;
- }
- set_pos(start_position + Vector(0, offset_y));
- }
- else if (mystate == STATE_SHRINKING) {
- offset_y += elapsed_time * SPEED_SHRINK;
- if (offset_y > 0) {
- offset_y = 0;
- mystate = STATE_VANISHING;
- base_sprite->set_action("vanishing", 2);
- base_sprite->set_animation_loops(2); // TODO: doesn't seem to work for loops=1
- }
- set_pos(start_position + Vector(0, offset_y));
- }
- else if (mystate == STATE_VANISHING) {
- if (base_sprite->animation_done()) remove_me();
- }
- BadGuy::active_update(elapsed_time);
-}
-
-void
-Root::draw(DrawingContext& context)
-{
- base_sprite->draw(context, start_position, LAYER_TILES+1);
- if ((mystate != STATE_APPEARING) && (mystate != STATE_VANISHING)) BadGuy::draw(context);
-}
-
+++ /dev/null
-// $Id$
-//
-// SuperTux - Boss "GhostTree"
-// Copyright (C) 2007 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#ifndef __ROOT_H__
-#define __ROOT_H__
-
-#include <memory>
-#include "badguy.hpp"
-
-class Timer;
-
-class Root : public BadGuy
-{
-public:
- Root(const Vector& pos);
- ~Root();
-
- void activate();
- void deactivate();
- void active_update(float elapsed_time);
- virtual void draw(DrawingContext& context);
- virtual bool is_flammable() const { return false; }
- virtual bool is_freezable() const { return false; }
- virtual void kill_fall() { }
-
-protected:
- enum MyState {
- STATE_APPEARING, STATE_HATCHING, STATE_GROWING, STATE_SHRINKING, STATE_VANISHING
- };
- MyState mystate;
- std::auto_ptr<Sprite> base_sprite;
- float offset_y;
- Timer hatch_timer;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SkullyHop - A Hopping Skull
-// Copyright (C) 2006 Christoph Sommer <supertux@2006.expires.deltadevelopment.de>
-//
-// 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.
-#include <config.h>
-
-#include "skullyhop.hpp"
-#include "random_generator.hpp"
-
-namespace {
- const float VERTICAL_SPEED = -450; /**< y-speed when jumping */
- const float HORIZONTAL_SPEED = 220; /**< x-speed when jumping */
- const float MIN_RECOVER_TIME = 0.1f; /**< minimum time to stand still before starting a (new) jump */
- const float MAX_RECOVER_TIME = 1.0f; /**< maximum time to stand still before starting a (new) jump */
- static const std::string HOP_SOUND = "sounds/hop.ogg";
-}
-
-SkullyHop::SkullyHop(const lisp::Lisp& reader)
- : BadGuy(reader, "images/creatures/skullyhop/skullyhop.sprite")
-{
- sound_manager->preload( HOP_SOUND );
-}
-
-SkullyHop::SkullyHop(const Vector& pos, Direction d)
- : BadGuy(pos, d, "images/creatures/skullyhop/skullyhop.sprite")
-{
- sound_manager->preload( HOP_SOUND );
-}
-
-void
-SkullyHop::write(lisp::Writer& writer)
-{
- writer.start_list("skullyhop");
- writer.write_float("x", start_position.x);
- writer.write_float("y", start_position.y);
- writer.end_list("skullyhop");
-}
-
-void
-SkullyHop::activate()
-{
- // initial state is JUMPING, because we might start airborne
- state = JUMPING;
- sprite->set_action(dir == LEFT ? "jumping-left" : "jumping-right");
-}
-
-void
-SkullyHop::set_state(SkullyHopState newState)
-{
- if (newState == STANDING) {
- physic.set_velocity_x(0);
- physic.set_velocity_y(0);
- sprite->set_action(dir == LEFT ? "standing-left" : "standing-right");
-
- float recover_time = systemRandom.randf(MIN_RECOVER_TIME,MAX_RECOVER_TIME);
- recover_timer.start(recover_time);
- } else
- if (newState == CHARGING) {
- sprite->set_action(dir == LEFT ? "charging-left" : "charging-right", 1);
- } else
- if (newState == JUMPING) {
- sprite->set_action(dir == LEFT ? "jumping-left" : "jumping-right");
- physic.set_velocity_x(dir == LEFT ? -HORIZONTAL_SPEED : HORIZONTAL_SPEED);
- physic.set_velocity_y(VERTICAL_SPEED);
- sound_manager->play( HOP_SOUND, get_pos());
- }
-
- state = newState;
-}
-
-bool
-SkullyHop::collision_squished(GameObject& object)
-{
- sprite->set_action(dir == LEFT ? "squished-left" : "squished-right");
- kill_squished(object);
- return true;
-}
-
-void
-SkullyHop::collision_solid(const CollisionHit& hit)
-{
- // just default behaviour (i.e. stop at floor/walls) when squished
- if (BadGuy::get_state() == STATE_SQUISHED) {
- BadGuy::collision_solid(hit);
- }
-
- // ignore collisions while standing still
- if(state != JUMPING)
- return;
-
- // check if we hit the floor while falling
- if(hit.bottom && physic.get_velocity_y() > 0 ) {
- set_state(STANDING);
- }
- // check if we hit the roof while climbing
- if(hit.top) {
- physic.set_velocity_y(0);
- }
-
- // check if we hit left or right while moving in either direction
- if(hit.left || hit.right) {
- dir = dir == LEFT ? RIGHT : LEFT;
- sprite->set_action(dir == LEFT ? "jumping-left" : "jumping-right");
- physic.set_velocity_x(-0.25*physic.get_velocity_x());
- }
-}
-
-HitResponse
-SkullyHop::collision_badguy(BadGuy& , const CollisionHit& hit)
-{
- // behaviour for badguy collisions is the same as for collisions with solids
- collision_solid(hit);
-
- return CONTINUE;
-}
-
-void
-SkullyHop::active_update(float elapsed_time)
-{
- BadGuy::active_update(elapsed_time);
-
- // charge when fully recovered
- if ((state == STANDING) && (recover_timer.check())) {
- set_state(CHARGING);
- return;
- }
-
- // jump as soon as charging animation completed
- if ((state == CHARGING) && (sprite->animation_done())) {
- set_state(JUMPING);
- return;
- }
-}
-
-IMPLEMENT_FACTORY(SkullyHop, "skullyhop")
+++ /dev/null
-// $Id$
-//
-// SkullyHop - A Hopping Skull
-// Copyright (C) 2006 Christoph Sommer <supertux@2006.expires.deltadevelopment.de>
-//
-// 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.
-
-#ifndef __SKULLYHOP_H__
-#define __SKULLYHOP_H__
-
-#include "badguy.hpp"
-
-/**
- * Badguy "SkullyHop" - A Hopping Skull
- */
-class SkullyHop : public BadGuy
-{
-public:
- SkullyHop(const lisp::Lisp& reader);
- SkullyHop(const Vector& pos, Direction d);
-
- void activate();
- void write(lisp::Writer& writer);
- void collision_solid(const CollisionHit& hit);
- HitResponse collision_badguy(BadGuy& badguy, const CollisionHit& hit);
- bool collision_squished(GameObject& object);
- void active_update(float elapsed_time);
-
- virtual SkullyHop* clone() const { return new SkullyHop(*this); }
-
-protected:
- enum SkullyHopState {
- STANDING,
- CHARGING,
- JUMPING
- };
-
- Timer recover_timer;
- SkullyHopState state;
-
- void set_state(SkullyHopState newState);
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux - Badguy "Snail"
-// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
-//
-// 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.
-
-#include <config.h>
-
-#include "snail.hpp"
-#include "object/block.hpp"
-
-namespace {
- const float KICKSPEED = 500;
- const int MAXSQUISHES = 10;
- const float KICKSPEED_Y = -500; /**< y-velocity gained when kicked */
-}
-
-Snail::Snail(const lisp::Lisp& reader)
- : WalkingBadguy(reader, "images/creatures/snail/snail.sprite", "left", "right"), state(STATE_NORMAL), squishcount(0)
-{
- walk_speed = 80;
- max_drop_height = 600;
- sound_manager->preload("sounds/iceblock_bump.wav");
- sound_manager->preload("sounds/stomp.wav");
- sound_manager->preload("sounds/kick.wav");
-}
-
-Snail::Snail(const Vector& pos, Direction d)
- : WalkingBadguy(pos, d, "images/creatures/snail/snail.sprite", "left", "right"), state(STATE_NORMAL), squishcount(0)
-{
- walk_speed = 80;
- max_drop_height = 600;
- sound_manager->preload("sounds/iceblock_bump.wav");
- sound_manager->preload("sounds/stomp.wav");
- sound_manager->preload("sounds/kick.wav");
-}
-
-void
-Snail::write(lisp::Writer& writer)
-{
- writer.start_list("snail");
- WalkingBadguy::write(writer);
- writer.end_list("snail");
-}
-
-void
-Snail::activate()
-{
- WalkingBadguy::activate();
- be_normal();
-}
-
-void
-Snail::be_normal()
-{
- if (state == STATE_NORMAL) return;
-
- state = STATE_NORMAL;
- WalkingBadguy::activate();
-}
-
-void
-Snail::be_flat()
-{
- state = STATE_FLAT;
- sprite->set_action(dir == LEFT ? "flat-left" : "flat-right");
- sprite->set_fps(64);
-
- physic.set_velocity_x(0);
- physic.set_velocity_y(0);
-
- flat_timer.start(4);
-}
-
-void
-Snail::be_kicked()
-{
- state = STATE_KICKED_DELAY;
- sprite->set_action(dir == LEFT ? "flat-left" : "flat-right");
- sprite->set_fps(64);
-
- physic.set_velocity_x(0);
- physic.set_velocity_y(0);
-
- // start a timer to delay addition of upward movement until we are (hopefully) out from under the player
- kicked_delay_timer.start(0.05f);
-}
-
-bool
-Snail::can_break(){
- return state == STATE_KICKED;
-}
-
-void
-Snail::active_update(float elapsed_time)
-{
- switch (state) {
-
- case STATE_NORMAL:
- WalkingBadguy::active_update(elapsed_time);
- break;
-
- case STATE_FLAT:
- if (flat_timer.started()) {
- sprite->set_fps(64 - 15 * flat_timer.get_timegone());
- }
- if (flat_timer.check()) {
- be_normal();
- }
- BadGuy::active_update(elapsed_time);
- break;
-
- case STATE_KICKED_DELAY:
- if (kicked_delay_timer.check()) {
- physic.set_velocity_x(dir == LEFT ? -KICKSPEED : KICKSPEED);
- physic.set_velocity_y(KICKSPEED_Y);
- state = STATE_KICKED;
- }
- BadGuy::active_update(elapsed_time);
- break;
-
- case STATE_KICKED:
- physic.set_velocity_x(physic.get_velocity_x() * pow(0.99, elapsed_time/0.02));
- if (fabsf(physic.get_velocity_x()) < walk_speed) be_normal();
- BadGuy::active_update(elapsed_time);
- break;
-
- }
-}
-
-void
-Snail::collision_solid(const CollisionHit& hit)
-{
- update_on_ground_flag(hit);
-
- switch (state) {
- case STATE_NORMAL:
- WalkingBadguy::collision_solid(hit);
- break;
- case STATE_FLAT:
- if(hit.top || hit.bottom) {
- physic.set_velocity_y(0);
- }
- if(hit.left || hit.right) {
- }
- break;
- case STATE_KICKED_DELAY:
- if(hit.top || hit.bottom) {
- physic.set_velocity_y(0);
- }
- if(hit.left || hit.right) {
- physic.set_velocity_x(0);
- }
- break;
- case STATE_KICKED:
- if(hit.top || hit.bottom) {
- physic.set_velocity_y(0);
- }
- if(hit.left || hit.right) {
- sound_manager->play("sounds/iceblock_bump.wav", get_pos());
-
- if( ( dir == LEFT && hit.left ) || ( dir == RIGHT && hit.right) ){
- dir = (dir == LEFT) ? RIGHT : LEFT;
- sprite->set_action(dir == LEFT ? "flat-left" : "flat-right");
-
- physic.set_velocity_x(-physic.get_velocity_x()*0.75);
- if (fabsf(physic.get_velocity_x()) < walk_speed) be_normal();
- }
-
- }
- break;
- }
-
-}
-
-HitResponse
-Snail::collision_badguy(BadGuy& badguy, const CollisionHit& hit)
-{
- switch(state) {
- case STATE_NORMAL:
- return WalkingBadguy::collision_badguy(badguy, hit);
- case STATE_FLAT:
- case STATE_KICKED_DELAY:
- return FORCE_MOVE;
- case STATE_KICKED:
- badguy.kill_fall();
- return FORCE_MOVE;
- default:
- assert(false);
- }
-
- return ABORT_MOVE;
-}
-
-bool
-Snail::collision_squished(GameObject& object)
-{
- switch(state) {
-
- case STATE_KICKED:
- case STATE_NORMAL:
- squishcount++;
- if(squishcount >= MAXSQUISHES) {
- kill_fall();
- return true;
- }
-
- sound_manager->play("sounds/stomp.wav", get_pos());
- be_flat();
- break;
-
- case STATE_FLAT:
- sound_manager->play("sounds/kick.wav", get_pos());
- {
- MovingObject* movingobject = dynamic_cast<MovingObject*>(&object);
- if (movingobject && (movingobject->get_pos().x < get_pos().x)) {
- dir = RIGHT;
- } else {
- dir = LEFT;
- }
- }
- be_kicked();
- break;
-
- case STATE_KICKED_DELAY:
- break;
-
- }
-
- Player* player = dynamic_cast<Player*>(&object);
- if (player) player->bounce(*this);
- return true;
-}
-
-IMPLEMENT_FACTORY(Snail, "snail")
+++ /dev/null
-// $Id$
-//
-// SuperTux - Badguy "Snail"
-// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
-//
-// 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.
-
-#ifndef __SNAIL_H__
-#define __SNAIL_H__
-
-#include "walking_badguy.hpp"
-
-/**
- * Badguy "Snail" - a snail-like creature that can be flipped and tossed around at an angle
- */
-class Snail : public WalkingBadguy
-{
-public:
- Snail(const lisp::Lisp& reader);
- Snail(const Vector& pos, Direction d);
-
- void activate();
- void write(lisp::Writer& writer);
- void collision_solid(const CollisionHit& hit);
- HitResponse collision_badguy(BadGuy& badguy, const CollisionHit& hit);
- bool can_break();
-
- void active_update(float elapsed_time);
-
- virtual Snail* clone() const { return new Snail(*this); }
-
-protected:
- bool collision_squished(GameObject& object);
- void be_normal(); /**< switch to state STATE_NORMAL */
- void be_flat(); /**< switch to state STATE_FLAT */
- void be_kicked(); /**< switch to state STATE_KICKED_DELAY */
-
-private:
- enum State {
- STATE_NORMAL, /**< walking around */
- STATE_FLAT, /**< flipped upside-down */
- STATE_KICKED_DELAY, /**< short delay before being launched */
- STATE_KICKED /**< launched */
- };
- State state;
- Timer flat_timer; /**< wait time until flipping right-side-up again */
- Timer kicked_delay_timer; /**< wait time until switching from STATE_KICKED_DELAY to STATE_KICKED */
- int squishcount;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include "snowball.hpp"
-
-SnowBall::SnowBall(const lisp::Lisp& reader)
- : WalkingBadguy(reader, "images/creatures/snowball/snowball.sprite", "left", "right")
-{
- walk_speed = 80;
-}
-
-SnowBall::SnowBall(const Vector& pos, Direction d)
- : WalkingBadguy(pos, d, "images/creatures/snowball/snowball.sprite", "left", "right")
-{
- walk_speed = 80;
-}
-
-void
-SnowBall::write(lisp::Writer& writer)
-{
- writer.start_list("snowball");
- WalkingBadguy::write(writer);
- writer.end_list("snowball");
-}
-
-bool
-SnowBall::collision_squished(GameObject& object)
-{
- sprite->set_action(dir == LEFT ? "squished-left" : "squished-right");
- kill_squished(object);
- return true;
-}
-
-IMPLEMENT_FACTORY(SnowBall, "snowball")
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __SNOWBALL_H__
-#define __SNOWBALL_H__
-
-#include "walking_badguy.hpp"
-
-class SnowBall : public WalkingBadguy
-{
-public:
- SnowBall(const lisp::Lisp& reader);
- SnowBall(const Vector& pos, Direction d);
-
- void write(lisp::Writer& writer);
- virtual SnowBall* clone() const { return new SnowBall(*this); }
-
-protected:
- bool collision_squished(GameObject& object);
-
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-#include <stdio.h>
-
-#include "spidermite.hpp"
-
-static const float FLYTIME = 1.2f;
-static const float FLYSPEED = -100.0f;
-
-SpiderMite::SpiderMite(const lisp::Lisp& reader)
- : BadGuy(reader, "images/creatures/spidermite/spidermite.sprite")
-{
- physic.enable_gravity(false);
-}
-
-SpiderMite::SpiderMite(const Vector& pos)
- : BadGuy(pos, "images/creatures/spidermite/spidermite.sprite")
-{
- physic.enable_gravity(false);
-}
-
-void
-SpiderMite::write(lisp::Writer& writer)
-{
- writer.start_list("spidermite");
-
- writer.write_float("x", start_position.x);
- writer.write_float("y", start_position.y);
-
- writer.end_list("spidermite");
-}
-
-void
-SpiderMite::activate()
-{
- sprite->set_action(dir == LEFT ? "left" : "right");
- mode = FLY_UP;
- physic.set_velocity_y(FLYSPEED);
- timer.start(FLYTIME/2);
-}
-
-bool
-SpiderMite::collision_squished(GameObject& object)
-{
- sprite->set_action(dir == LEFT ? "squished-left" : "squished-right");
- kill_squished(object);
- return true;
-}
-
-void
-SpiderMite::collision_solid(const CollisionHit& hit)
-{
- if(hit.top || hit.bottom) { // hit floor or roof?
- physic.set_velocity_y(0);
- }
-}
-
-void
-SpiderMite::active_update(float elapsed_time)
-{
- if(timer.check()) {
- if(mode == FLY_UP) {
- mode = FLY_DOWN;
- physic.set_velocity_y(-FLYSPEED);
- } else if(mode == FLY_DOWN) {
- mode = FLY_UP;
- physic.set_velocity_y(FLYSPEED);
- }
- timer.start(FLYTIME);
- }
- movement=physic.get_movement(elapsed_time);
-
- Player* player = this->get_nearest_player();
- if (player) {
- dir = (player->get_pos().x > get_pos().x) ? RIGHT : LEFT;
- sprite->set_action(dir == LEFT ? "left" : "right");
- }
-}
-
-IMPLEMENT_FACTORY(SpiderMite, "spidermite")
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __SPIDERMITE_H__
-#define __SPIDERMITE_H__
-
-#include "badguy.hpp"
-
-class SpiderMite : public BadGuy
-{
-public:
- SpiderMite(const lisp::Lisp& reader);
- SpiderMite(const Vector& pos);
-
- void activate();
- void write(lisp::Writer& writer);
- void active_update(float elapsed_time);
- void collision_solid(const CollisionHit& hit);
-
- virtual SpiderMite* clone() const { return new SpiderMite(*this); }
-
-protected:
- enum SpiderMiteMode {
- FLY_UP,
- FLY_DOWN
- };
- SpiderMiteMode mode;
- bool collision_squished(GameObject& object);
-private:
- Timer timer;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include "spiky.hpp"
-
-Spiky::Spiky(const lisp::Lisp& reader)
- : WalkingBadguy(reader, "images/creatures/spiky/spiky.sprite", "left", "right")
-{
- walk_speed = 80;
- max_drop_height = 600;
-}
-
-void
-Spiky::write(lisp::Writer& writer)
-{
- writer.start_list("spiky");
- WalkingBadguy::write(writer);
- writer.end_list("spiky");
-}
-
-void
-Spiky::freeze()
-{
- WalkingBadguy::freeze();
- sprite->set_action(dir == LEFT ? "iced-left" : "iced-right");
-}
-
-bool
-Spiky::is_freezable() const
-{
- return true;
-}
-
-IMPLEMENT_FACTORY(Spiky, "spiky")
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __SPIKY_H__
-#define __SPIKY_H__
-
-#include "walking_badguy.hpp"
-
-class Spiky : public WalkingBadguy
-{
-public:
- Spiky(const lisp::Lisp& reader);
-
- void write(lisp::Writer& writer);
- virtual Spiky* clone() const { return new Spiky(*this); }
-
- void freeze();
- bool is_freezable() const;
-
-private:
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include "sspiky.hpp"
-
-static const float WALKSPEED = 80;
-
-SSpiky::SSpiky(const lisp::Lisp& reader)
- : WalkingBadguy(reader, "images/creatures/spiky/sleepingspiky.sprite", "left", "right"), state(SSPIKY_SLEEPING)
-{
- walk_speed = WALKSPEED;
- max_drop_height = -1;
-}
-
-void
-SSpiky::write(lisp::Writer& writer)
-{
- writer.start_list("sspiky");
- WalkingBadguy::write(writer);
- writer.end_list("sspiky");
-}
-
-void
-SSpiky::activate()
-{
- state = SSPIKY_SLEEPING;
- physic.set_velocity_x(0);
- sprite->set_action(dir == LEFT ? "sleeping-left" : "sleeping-right");
-}
-
-void
-SSpiky::collision_solid(const CollisionHit& hit)
-{
- if(state != SSPIKY_WALKING) {
- BadGuy::collision_solid(hit);
- return;
- }
- WalkingBadguy::collision_solid(hit);
-}
-
-HitResponse
-SSpiky::collision_badguy(BadGuy& badguy, const CollisionHit& hit)
-{
- if(state != SSPIKY_WALKING) {
- return BadGuy::collision_badguy(badguy, hit);
- }
- return WalkingBadguy::collision_badguy(badguy, hit);
-}
-
-void
-SSpiky::active_update(float elapsed_time) {
-
- if(state == SSPIKY_WALKING) {
- WalkingBadguy::active_update(elapsed_time);
- return;
- }
-
- if(state == SSPIKY_SLEEPING) {
-
- Player* player = this->get_nearest_player();
- if (player) {
- Rect mb = this->get_bbox();
- Rect pb = player->get_bbox();
-
- bool inReach_left = (pb.p2.x >= mb.p2.x-((dir == LEFT) ? 256 : 0));
- bool inReach_right = (pb.p1.x <= mb.p1.x+((dir == RIGHT) ? 256 : 0));
- bool inReach_top = (pb.p2.y >= mb.p1.y);
- bool inReach_bottom = (pb.p1.y <= mb.p2.y);
-
- if (inReach_left && inReach_right && inReach_top && inReach_bottom) {
- // wake up
- sprite->set_action(dir == LEFT ? "waking-left" : "waking-right", 1);
- state = SSPIKY_WAKING;
- }
- }
-
- BadGuy::active_update(elapsed_time);
- }
-
- if(state == SSPIKY_WAKING) {
- if(sprite->animation_done()) {
- // start walking
- state = SSPIKY_WALKING;
- WalkingBadguy::activate();
- }
-
- BadGuy::active_update(elapsed_time);
- }
-}
-
-void
-SSpiky::freeze()
-{
- WalkingBadguy::freeze();
- sprite->set_action(dir == LEFT ? "iced-left" : "iced-right");
- state = SSPIKY_WALKING; // if we get hit while sleeping, wake up :)
-}
-
-bool
-SSpiky::is_freezable() const
-{
- return true;
-}
-
-IMPLEMENT_FACTORY(SSpiky, "sspiky")
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __SSPIKY_H__
-#define __SSPIKY_H__
-
-#include "walking_badguy.hpp"
-
-class SSpiky : public WalkingBadguy
-{
-public:
- SSpiky(const lisp::Lisp& reader);
-
- void activate();
- void write(lisp::Writer& writer);
- void collision_solid(const CollisionHit& hit);
- HitResponse collision_badguy(BadGuy& badguy, const CollisionHit& hit);
- void active_update(float elapsed_time);
-
- void freeze();
- bool is_freezable() const;
-
- virtual SSpiky* clone() const { return new SSpiky(*this); }
-
-protected:
- enum SSpikyState {
- SSPIKY_SLEEPING,
- SSPIKY_WAKING,
- SSPIKY_WALKING
- };
- SSpikyState state;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include "stalactite.hpp"
-#include "random_generator.hpp"
-
-static const int SHAKE_RANGE_X = 40;
-static const float SHAKE_TIME = .8f;
-static const float SQUISH_TIME = 2;
-static const float SHAKE_RANGE_Y = 400;
-
-Stalactite::Stalactite(const lisp::Lisp& lisp)
- : BadGuy(lisp, "images/creatures/stalactite/stalactite.sprite", LAYER_TILES - 1), state(STALACTITE_HANGING)
-{
- countMe = false;
-}
-
-void
-Stalactite::write(lisp::Writer& writer)
-{
- writer.start_list("stalactite");
- writer.write_float("x", start_position.x);
- writer.write_float("y", start_position.y);
- writer.end_list("stalactite");
-}
-
-void
-Stalactite::active_update(float elapsed_time)
-{
- if(state == STALACTITE_HANGING) {
- Player* player = this->get_nearest_player();
- if (player) {
- if(player->get_bbox().p2.x > bbox.p1.x - SHAKE_RANGE_X
- && player->get_bbox().p1.x < bbox.p2.x + SHAKE_RANGE_X
- && player->get_bbox().p2.y > bbox.p1.y
- && player->get_bbox().p1.y < bbox.p2.y + SHAKE_RANGE_Y) {
- timer.start(SHAKE_TIME);
- state = STALACTITE_SHAKING;
- }
- }
- } else if(state == STALACTITE_SHAKING) {
- if(timer.check()) {
- state = STALACTITE_FALLING;
- physic.enable_gravity(true);
- }
- } else if(state == STALACTITE_FALLING || state == STALACTITE_SQUISHED) {
- movement = physic.get_movement(elapsed_time);
- if(state == STALACTITE_SQUISHED && timer.check())
- remove_me();
- }
-}
-
-void
-Stalactite::squish()
-{
- state = STALACTITE_SQUISHED;
- set_group(COLGROUP_MOVING_ONLY_STATIC);
- sprite->set_action("squished");
- if(!timer.started())
- timer.start(SQUISH_TIME);
-}
-
-void
-Stalactite::collision_solid(const CollisionHit& hit)
-{
- if(state == STALACTITE_FALLING) {
- if (hit.bottom) squish();
- }
- if(state == STALACTITE_SQUISHED) {
- physic.set_velocity_y(0);
- }
-}
-
-HitResponse
-Stalactite::collision_player(Player& player)
-{
- if(state != STALACTITE_SQUISHED) {
- player.kill(false);
- }
-
- return FORCE_MOVE;
-}
-
-HitResponse
-Stalactite::collision_badguy(BadGuy& other, const CollisionHit& hit)
-{
- if (state == STALACTITE_SQUISHED) return FORCE_MOVE;
- if (state != STALACTITE_FALLING) return BadGuy::collision_badguy(other, hit);
-
- // ignore other Stalactites
- if (dynamic_cast<Stalactite*>(&other)) return FORCE_MOVE;
-
- if (other.is_freezable()) {
- other.freeze();
- } else {
- other.kill_fall();
- }
-
- remove_me();
-
- return FORCE_MOVE;
-}
-
-void
-Stalactite::kill_fall()
-{
-}
-
-void
-Stalactite::draw(DrawingContext& context)
-{
- if(get_state() != STATE_ACTIVE)
- return;
-
-
- if(state == STALACTITE_SQUISHED) {
- sprite->draw(context, get_pos(), LAYER_OBJECTS);
- return;
- }
-
- if(state == STALACTITE_SHAKING) {
- sprite->draw(context, get_pos() + Vector(systemRandom.rand(-3,3), 0), layer);
- } else {
- sprite->draw(context, get_pos(), layer);
- }
-}
-
-void
-Stalactite::deactivate()
-{
- if(state != STALACTITE_HANGING)
- remove_me();
-}
-
-IMPLEMENT_FACTORY(Stalactite, "stalactite")
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __STALACTITE_H__
-#define __STALACTITE_H__
-
-#include "badguy.hpp"
-
-class Stalactite : public BadGuy
-{
-public:
- Stalactite(const lisp::Lisp& reader);
-
- void active_update(float elapsed_time);
- void write(lisp::Writer& writer);
- void collision_solid(const CollisionHit& hit);
- HitResponse collision_player(Player& player);
- HitResponse collision_badguy(BadGuy& other, const CollisionHit& hit);
-
- void kill_fall();
- void draw(DrawingContext& context);
- void deactivate();
-
- virtual Stalactite* clone() const { return new Stalactite(*this); }
-
- void squish();
-
-protected:
- Timer timer;
-
- enum StalactiteState {
- STALACTITE_HANGING,
- STALACTITE_SHAKING,
- STALACTITE_FALLING,
- STALACTITE_SQUISHED
- };
- StalactiteState state;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include "stumpy.hpp"
-#include "poisonivy.hpp"
-#include "random_generator.hpp"
-#include "object/sprite_particle.hpp"
-
-static const float WALKSPEED = 120;
-static const float INVINCIBLE_TIME = 1;
-
-Stumpy::Stumpy(const lisp::Lisp& reader)
- : WalkingBadguy(reader, "images/creatures/mr_tree/stumpy.sprite","left","right"), mystate(STATE_NORMAL)
-{
- walk_speed = WALKSPEED;
- max_drop_height = 16;
- sound_manager->preload("sounds/mr_tree.ogg");
- sound_manager->preload("sounds/mr_treehit.ogg");
-}
-
-Stumpy::Stumpy(const Vector& pos, Direction d)
- : WalkingBadguy(pos, d, "images/creatures/mr_tree/stumpy.sprite","left","right"), mystate(STATE_INVINCIBLE)
-{
- walk_speed = WALKSPEED;
- max_drop_height = 16;
- sound_manager->preload("sounds/mr_treehit.ogg");
- invincible_timer.start(INVINCIBLE_TIME);
-}
-
-
-void
-Stumpy::write(lisp::Writer& writer)
-{
- writer.start_list("stumpy");
- WalkingBadguy::write(writer);
- writer.end_list("stumpy");
-}
-
-void
-Stumpy::activate()
-{
- switch (mystate) {
- case STATE_INVINCIBLE:
- sprite->set_action(dir == LEFT ? "dizzy-left" : "dizzy-right");
- bbox.set_size(sprite->get_current_hitbox_width(), sprite->get_current_hitbox_height());
- physic.set_velocity_x(0);
- break;
- case STATE_NORMAL:
- WalkingBadguy::activate();
- break;
- }
-}
-
-void
-Stumpy::active_update(float elapsed_time)
-{
- switch (mystate) {
- case STATE_INVINCIBLE:
- if (invincible_timer.check()) {
- mystate = STATE_NORMAL;
- WalkingBadguy::activate();
- }
- BadGuy::active_update(elapsed_time);
- break;
- case STATE_NORMAL:
- WalkingBadguy::active_update(elapsed_time);
- break;
- }
-}
-
-bool
-Stumpy::collision_squished(GameObject& object)
-{
-
- // if we're still invincible, we ignore the hit
- if (mystate == STATE_INVINCIBLE) {
- sound_manager->play("sounds/mr_treehit.ogg", get_pos());
- Player* player = dynamic_cast<Player*>(&object);
- if (player) player->bounce(*this);
- return true;
- }
-
- // if we can die, we do
- if (mystate == STATE_NORMAL) {
- sprite->set_action(dir == LEFT ? "squished-left" : "squished-right");
- set_size(sprite->get_current_hitbox_width(), sprite->get_current_hitbox_height());
- kill_squished(object);
- // spawn some particles
- // TODO: provide convenience function in MovingSprite or MovingObject?
- for (int i = 0; i < 25; i++) {
- Vector ppos = bbox.get_middle();
- float angle = systemRandom.randf(-M_PI_2, M_PI_2);
- float velocity = systemRandom.randf(45, 90);
- float vx = sin(angle)*velocity;
- float vy = -cos(angle)*velocity;
- Vector pspeed = Vector(vx, vy);
- Vector paccel = Vector(0, 100);
- Sector::current()->add_object(new SpriteParticle("images/objects/particles/bark.sprite", "default", ppos, ANCHOR_MIDDLE, pspeed, paccel, LAYER_OBJECTS-1));
- }
-
- return true;
-
- }
-
- //TODO: exception?
- return true;
-}
-
-void
-Stumpy::collision_solid(const CollisionHit& hit)
-{
- update_on_ground_flag(hit);
-
- switch (mystate) {
- case STATE_INVINCIBLE:
- if(hit.top || hit.bottom) {
- physic.set_velocity_y(0);
- }
- if(hit.left || hit.right) {
- physic.set_velocity_x(0);
- }
- break;
- case STATE_NORMAL:
- WalkingBadguy::collision_solid(hit);
- break;
- }
-}
-
-HitResponse
-Stumpy::collision_badguy(BadGuy& badguy, const CollisionHit& hit)
-{
- switch (mystate) {
- case STATE_INVINCIBLE:
- if(hit.top || hit.bottom) {
- physic.set_velocity_y(0);
- }
- if(hit.left || hit.right) {
- physic.set_velocity_x(0);
- }
- return CONTINUE;
- break;
- case STATE_NORMAL:
- return WalkingBadguy::collision_badguy(badguy, hit);
- break;
- }
- return CONTINUE;
-}
-
-IMPLEMENT_FACTORY(Stumpy, "stumpy")
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __STUMPY_H__
-#define __STUMPY_H__
-
-#include "walking_badguy.hpp"
-
-class Stumpy : public WalkingBadguy
-{
-public:
- Stumpy(const lisp::Lisp& reader);
- Stumpy(const Vector& pos, Direction d);
-
- void activate();
- void active_update(float elapsed_time);
- void write(lisp::Writer& writer);
- void collision_solid(const CollisionHit& hit);
- HitResponse collision_badguy(BadGuy& badguy, const CollisionHit& hit);
-
- virtual Stumpy* clone() const { return new Stumpy(*this); }
-
-protected:
- enum MyState {
- STATE_INVINCIBLE, STATE_NORMAL
- };
- MyState mystate;
-
- Timer invincible_timer;
-
- bool collision_squished(GameObject& object);
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// Toad - A jumping toad
-// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
-//
-// 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.
-#include <config.h>
-
-#include "toad.hpp"
-#include "random_generator.hpp"
-
-namespace {
- const float VERTICAL_SPEED = -450; /**< y-speed when jumping */
- const float HORIZONTAL_SPEED = 320; /**< x-speed when jumping */
- const float RECOVER_TIME = 0.5; /**< time to stand still before starting a (new) jump */
- static const std::string HOP_SOUND = "sounds/hop.ogg";
-}
-
-Toad::Toad(const lisp::Lisp& reader)
- : BadGuy(reader, "images/creatures/toad/toad.sprite")
-{
- sound_manager->preload(HOP_SOUND);
-}
-
-Toad::Toad(const Vector& pos, Direction d)
- : BadGuy(pos, d, "images/creatures/toad/toad.sprite")
-{
- sound_manager->preload(HOP_SOUND);
-}
-
-void
-Toad::write(lisp::Writer& writer)
-{
- writer.start_list("toad");
- writer.write_float("x", start_position.x);
- writer.write_float("y", start_position.y);
- writer.end_list("toad");
-}
-
-void
-Toad::activate()
-{
- // initial state is JUMPING, because we might start airborne
- state = JUMPING;
- sprite->set_action(dir == LEFT ? "jumping-left" : "jumping-right");
-}
-
-void
-Toad::set_state(ToadState newState)
-{
- if (newState == IDLE) {
- physic.set_velocity_x(0);
- physic.set_velocity_y(0);
- sprite->set_action(dir == LEFT ? "idle-left" : "idle-right");
-
- recover_timer.start(RECOVER_TIME);
- } else
- if (newState == JUMPING) {
- sprite->set_action(dir == LEFT ? "jumping-left" : "jumping-right");
- physic.set_velocity_x(dir == LEFT ? -HORIZONTAL_SPEED : HORIZONTAL_SPEED);
- physic.set_velocity_y(VERTICAL_SPEED);
- sound_manager->play( HOP_SOUND, get_pos());
- } else
- if (newState == FALLING) {
- Player* player = get_nearest_player();
- // face player
- if (player && (player->get_bbox().p2.x < get_bbox().p1.x) && (dir == RIGHT)) dir = LEFT;
- if (player && (player->get_bbox().p1.x > get_bbox().p2.x) && (dir == LEFT)) dir = RIGHT;
- sprite->set_action(dir == LEFT ? "idle-left" : "idle-right");
- }
-
- state = newState;
-}
-
-bool
-Toad::collision_squished(GameObject& object)
-{
- sprite->set_action(dir == LEFT ? "squished-left" : "squished-right");
- kill_squished(object);
- return true;
-}
-
-void
-Toad::collision_solid(const CollisionHit& hit)
-{
- // just default behaviour (i.e. stop at floor/walls) when squished
- if (BadGuy::get_state() == STATE_SQUISHED) {
- BadGuy::collision_solid(hit);
- return;
- }
-
- // ignore collisions while standing still
- if(state == IDLE) {
- return;
- }
-
- // check if we hit left or right while moving in either direction
- if(((physic.get_velocity_x() < 0) && hit.left) || ((physic.get_velocity_x() > 0) && hit.right)) {
- /*
- dir = dir == LEFT ? RIGHT : LEFT;
- if (state == JUMPING) {
- sprite->set_action(dir == LEFT ? "jumping-left" : "jumping-right");
- } else {
- sprite->set_action(dir == LEFT ? "idle-left" : "idle-right");
- }
- */
- physic.set_velocity_x(-0.25*physic.get_velocity_x());
- }
-
- // check if we hit the floor while falling
- if ((state == FALLING) && hit.bottom) {
- set_state(IDLE);
- return;
- }
-
- // check if we hit the roof while climbing
- if ((state == JUMPING) && hit.top) {
- physic.set_velocity_y(0);
- }
-
-}
-
-HitResponse
-Toad::collision_badguy(BadGuy& , const CollisionHit& hit)
-{
- // behaviour for badguy collisions is the same as for collisions with solids
- collision_solid(hit);
-
- return CONTINUE;
-}
-
-void
-Toad::active_update(float elapsed_time)
-{
- BadGuy::active_update(elapsed_time);
-
- // change sprite when we are falling
- if ((state == JUMPING) && (physic.get_velocity_y() > 0)) {
- set_state(FALLING);
- return;
- }
-
- // jump when fully recovered
- if ((state == IDLE) && (recover_timer.check())) {
- set_state(JUMPING);
- return;
- }
-
-}
-
-IMPLEMENT_FACTORY(Toad, "toad")
+++ /dev/null
-// $Id$
-//
-// Toad - A jumping toad
-// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
-//
-// 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.
-
-#ifndef __TOAD_H__
-#define __TOAD_H__
-
-#include "badguy.hpp"
-
-/**
- * Badguy "Toad" - A jumping toad
- */
-class Toad : public BadGuy
-{
-public:
- Toad(const lisp::Lisp& reader);
- Toad(const Vector& pos, Direction d);
-
- void activate();
- void write(lisp::Writer& writer);
- void collision_solid(const CollisionHit& hit);
- HitResponse collision_badguy(BadGuy& badguy, const CollisionHit& hit);
- bool collision_squished(GameObject& object);
- void active_update(float elapsed_time);
-
- virtual Toad* clone() const { return new Toad(*this); }
-
-protected:
- enum ToadState {
- IDLE,
- JUMPING,
- FALLING
- };
-
- Timer recover_timer;
- ToadState state;
-
- void set_state(ToadState newState);
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux - "Totem" Badguy
-// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
-//
-// 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.
-
-#include <config.h>
-
-#include "totem.hpp"
-#include "log.hpp"
-
-static const float WALKSPEED = 100;
-static const float JUMP_ON_SPEED_Y = -400;
-static const float JUMP_OFF_SPEED_Y = -500;
-static const std::string LAND_ON_TOTEM_SOUND = "sounds/totem.ogg";
-
-Totem::Totem(const lisp::Lisp& reader)
- : BadGuy(reader, "images/creatures/totem/totem.sprite")
-{
- carrying = 0;
- carried_by = 0;
- sound_manager->preload( LAND_ON_TOTEM_SOUND );
-}
-
-Totem::Totem(const Totem& other)
- : BadGuy(other), carrying(other.carrying), carried_by(other.carried_by)
-{
- sound_manager->preload( LAND_ON_TOTEM_SOUND );
-}
-
-Totem::~Totem()
-{
- if (carrying) carrying->jump_off();
- if (carried_by) jump_off();
-}
-
-bool
-Totem::updatePointers(const GameObject* from_object, GameObject* to_object)
-{
- if (from_object == carrying) {
- carrying = dynamic_cast<Totem*>(to_object);
- return true;
- }
- if (from_object == carried_by) {
- carried_by = dynamic_cast<Totem*>(to_object);
- return true;
- }
- return false;
-}
-
-void
-Totem::write(lisp::Writer& writer)
-{
- writer.start_list("totem");
-
- writer.write_float("x", start_position.x);
- writer.write_float("y", start_position.y);
-
- writer.end_list("totem");
-}
-
-void
-Totem::activate()
-{
- if (!carried_by) {
- physic.set_velocity_x(dir == LEFT ? -WALKSPEED : WALKSPEED);
- sprite->set_action(dir == LEFT ? "walking-left" : "walking-right");
- return;
- } else {
- synchronize_with(carried_by);
- sprite->set_action(dir == LEFT ? "stacked-left" : "stacked-right");
- return;
- }
-}
-
-void
-Totem::active_update(float elapsed_time)
-{
- BadGuy::active_update(elapsed_time);
-
- if (!carried_by) {
- if (on_ground() && might_fall())
- {
- dir = (dir == LEFT ? RIGHT : LEFT);
- activate();
- }
-
- Sector* s = Sector::current();
- if (s) {
- // jump a bit if we find a suitable totem
- for (std::vector<MovingObject*>::iterator i = s->moving_objects.begin(); i != s->moving_objects.end(); i++) {
- Totem* t = dynamic_cast<Totem*>(*i);
- if (!t) continue;
-
- // skip if we are not approaching each other
- if (!((this->dir == LEFT) && (t->dir == RIGHT))) continue;
-
- Vector p1 = this->get_pos();
- Vector p2 = t->get_pos();
-
- // skip if not on same height
- float dy = (p1.y - p2.y);
- if (fabsf(dy - 0) > 2) continue;
-
- // skip if too far away
- float dx = (p1.x - p2.x);
- if (fabsf(dx - 128) > 2) continue;
-
- physic.set_velocity_y(JUMP_ON_SPEED_Y);
- p1.y -= 1;
- this->set_pos(p1);
- break;
- }
- }
- }
-
- if (carried_by) {
- this->synchronize_with(carried_by);
- }
-
- if (carrying) {
- carrying->synchronize_with(this);
- }
-
-}
-
-bool
-Totem::collision_squished(GameObject& object)
-{
- if (carrying) carrying->jump_off();
- if (carried_by) {
- Player* player = dynamic_cast<Player*>(&object);
- if (player) player->bounce(*this);
- jump_off();
- }
-
- sprite->set_action(dir == LEFT ? "squished-left" : "squished-right");
- bbox.set_size(sprite->get_current_hitbox_width(), sprite->get_current_hitbox_height());
-
- kill_squished(object);
- return true;
-}
-
-void
-Totem::collision_solid(const CollisionHit& hit)
-{
- update_on_ground_flag(hit);
-
- // if we are being carried around, pass event to bottom of stack and ignore it
- if (carried_by) {
- carried_by->collision_solid(hit);
- return;
- }
-
- // If we hit something from above or below: stop moving in this direction
- if (hit.top || hit.bottom) {
- physic.set_velocity_y(0);
- }
-
- // If we are hit from the direction we are facing: turn around
- if (hit.left && (dir == LEFT)) {
- dir = RIGHT;
- activate();
- }
- if (hit.right && (dir == RIGHT)) {
- dir = LEFT;
- activate();
- }
-}
-
-HitResponse
-Totem::collision_badguy(BadGuy& badguy, const CollisionHit& hit)
-{
- // if we are being carried around, pass event to bottom of stack and ignore it
- if (carried_by) {
- carried_by->collision_badguy(badguy, hit);
- return CONTINUE;
- }
-
- // if we hit a Totem that is not from our stack: have our base jump on its top
- Totem* totem = dynamic_cast<Totem*>(&badguy);
- if (totem) {
- Totem* thisBase = this; while (thisBase->carried_by) thisBase=thisBase->carried_by;
- Totem* srcBase = totem; while (srcBase->carried_by) srcBase=srcBase->carried_by;
- Totem* thisTop = this; while (thisTop->carrying) thisTop=thisTop->carrying;
- if (srcBase != thisBase) {
- srcBase->jump_on(thisTop);
- }
- }
-
- // If we are hit from the direction we are facing: turn around
- if(hit.left && (dir == LEFT)) {
- dir = RIGHT;
- activate();
- }
- if(hit.right && (dir == RIGHT)) {
- dir = LEFT;
- activate();
- }
-
- return CONTINUE;
-}
-
-void
-Totem::kill_fall()
-{
- if (carrying) carrying->jump_off();
- if (carried_by) jump_off();
-
- BadGuy::kill_fall();
-}
-
-void
-Totem::jump_on(Totem* target)
-{
- if (target->carrying) {
- log_warning << "target is already carrying someone" << std::endl;
- return;
- }
-
- target->carrying = this;
-
- this->carried_by = target;
- this->activate();
- bbox.set_size(sprite->get_current_hitbox_width(), sprite->get_current_hitbox_height());
-
- sound_manager->play( LAND_ON_TOTEM_SOUND , get_pos());
-
-
- this->synchronize_with(target);
-}
-
-void
-Totem::jump_off() {
- if (!carried_by) {
- log_warning << "not carried by anyone" << std::endl;
- return;
- }
-
- carried_by->carrying = 0;
-
- this->carried_by = 0;
-
- this->activate();
- bbox.set_size(sprite->get_current_hitbox_width(), sprite->get_current_hitbox_height());
-
-
- physic.set_velocity_y(JUMP_OFF_SPEED_Y);
-}
-
-void
-Totem::synchronize_with(Totem* base)
-{
-
- if (dir != base->dir) {
- dir = base->dir;
- sprite->set_action(dir == LEFT ? "stacked-left" : "stacked-right");
- }
-
- Vector pos = base->get_pos();
- pos.y -= sprite->get_current_hitbox_height();
- set_pos(pos);
-
- physic.set_velocity_x(base->physic.get_velocity_x());
- physic.set_velocity_y(base->physic.get_velocity_y());
-}
-
-
-IMPLEMENT_FACTORY(Totem, "totem")
+++ /dev/null
-// $Id$
-//
-// SuperTux - "Totem" Badguy
-// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
-//
-// 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.
-
-#ifndef __TOTEM_H__
-#define __TOTEM_H__
-
-#include "badguy.hpp"
-
-/**
- * "Totem" Badguy - A variable-height stack of wooden blocks
- */
-class Totem : public BadGuy
-{
-public:
- Totem(const lisp::Lisp& reader);
- Totem(const Totem& totem);
- ~Totem();
-
- void activate();
- void active_update(float elapsed_time);
- void write(lisp::Writer& writer);
- void collision_solid(const CollisionHit& hit);
- HitResponse collision_badguy(BadGuy& badguy, const CollisionHit& hit);
-
- virtual Totem* clone() const { return new Totem(*this); }
- virtual bool updatePointers(const GameObject* from_object, GameObject* to_object);
-
-protected:
- Totem* carrying; /**< Totem we are currently carrying (or 0) */
- Totem* carried_by; /**< Totem by which we are currently carried (or 0) */
-
- bool collision_squished(GameObject& object);
- void kill_fall();
-
- void jump_on(Totem* target); /**< jump on target */
- void jump_off(); /**< jump off current base */
-
- void synchronize_with(Totem* baseTotem); /**< synchronize position and movement with baseTotem */
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux - "Will-O-Wisp" Badguy
-// Copyright (C) 2007 Matthias Braun
-//
-// 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.
-#include <config.h>
-
-#include "treewillowisp.hpp"
-#include "ghosttree.hpp"
-#include "object/lantern.hpp"
-
-static const std::string SOUNDFILE = "sounds/willowisp.wav";
-static const float SUCKSPEED = 25;
-
-TreeWillOWisp::TreeWillOWisp(GhostTree* tree, const Vector& pos,
- float radius, float speed)
- : BadGuy(Vector(0, 0), "images/creatures/willowisp/willowisp.sprite",
- LAYER_OBJECTS - 20), was_sucked(false), mystate(STATE_DEFAULT), tree(tree)
-{
- treepos_delta = pos;
- sound_manager->preload(SOUNDFILE);
-
- this->radius = radius;
- this->angle = 0;
- this->speed = speed;
- start_position = tree->get_pos() + treepos_delta;
-}
-
-TreeWillOWisp::~TreeWillOWisp()
-{
-}
-
-void
-TreeWillOWisp::activate()
-{
- sound_source.reset(sound_manager->create_sound_source(SOUNDFILE));
- sound_source->set_position(get_pos());
- sound_source->set_looping(true);
- sound_source->set_gain(2.0);
- sound_source->set_reference_distance(32);
- sound_source->play();
-
- set_group(COLGROUP_MOVING);
-}
-
-void
-TreeWillOWisp::vanish()
-{
- mystate = STATE_VANISHING;
- sprite->set_action("vanishing", 1);
- set_group(COLGROUP_DISABLED);
-}
-
-void
-TreeWillOWisp::start_sucking(Vector suck_target)
-{
- mystate = STATE_SUCKED;
- this->suck_target = suck_target;
- was_sucked = true;
-}
-
-HitResponse
-TreeWillOWisp::collision_player(Player& player, const CollisionHit& hit)
-{
- //TODO: basically a no-op. Remove if this doesn't change.
- return BadGuy::collision_player(player, hit);
-}
-
-bool
-TreeWillOWisp::collides(GameObject& other, const CollisionHit& ) {
- Lantern* lantern = dynamic_cast<Lantern*>(&other);
- if (lantern && lantern->is_open())
- return true;
- if (dynamic_cast<Player*>(&other))
- return true;
-
- return false;
-}
-
-void
-TreeWillOWisp::draw(DrawingContext& context)
-{
- sprite->draw(context, get_pos(), layer);
-
- context.push_target();
- context.set_target(DrawingContext::LIGHTMAP);
-
- sprite->draw(context, get_pos(), layer);
-
- context.pop_target();
-}
-
-void
-TreeWillOWisp::active_update(float elapsed_time)
-{
- // remove TreeWillOWisp if it has completely vanished
- if (mystate == STATE_VANISHING) {
- if(sprite->animation_done()) {
- remove_me();
- tree->willowisp_died(this);
- }
- return;
- }
-
- if (mystate == STATE_SUCKED) {
- Vector dir = suck_target - get_pos();
- if(dir.norm() < 5) {
- vanish();
- return;
- }
- Vector newpos = get_pos() + dir * elapsed_time;
- movement = newpos - get_pos();
- return;
- }
-
- angle = fmodf(angle + elapsed_time * speed, (float) (2*M_PI));
- Vector newpos(tree->get_pos() + treepos_delta + Vector(sin(angle) * radius, 0));
- movement = newpos - get_pos();
- float sizemod = cos(angle) * 0.8f;
- /* TODO: modify sprite size */
-
- sound_source->set_position(get_pos());
-
- if(sizemod < 0) {
- layer = LAYER_OBJECTS + 5;
- } else {
- layer = LAYER_OBJECTS - 20;
- }
-}
-
-void
-TreeWillOWisp::set_color(const Color& color)
-{
- this->color = color;
- sprite->set_color(color);
-}
-
-Color
-TreeWillOWisp::get_color() const
-{
- return color;
-}
-
+++ /dev/null
-// $Id$
-//
-// SuperTux - "Will-O-Wisp" Badguy
-// Copyright (C) 2007 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __TREEWILLOWISP_H__
-#define __TREEWILLOWISP_H__
-
-#include "badguy.hpp"
-
-class GhostTree;
-
-class TreeWillOWisp : public BadGuy
-{
-public:
- TreeWillOWisp(GhostTree* tree, const Vector& pos, float radius, float speed);
- virtual ~TreeWillOWisp();
-
- void activate();
-
- /**
- * make TreeWillOWisp vanish
- */
- void vanish();
- void start_sucking(Vector suck_target);
- bool was_sucked;
-
- void active_update(float elapsed_time);
- void set_color(const Color& color);
- Color get_color() const;
-
- virtual bool is_flammable() const { return false; }
- virtual bool is_freezable() const { return false; }
- virtual void kill_fall() { vanish(); }
-
- virtual void draw(DrawingContext& context);
-
-protected:
- virtual bool collides(GameObject& other, const CollisionHit& hit);
- HitResponse collision_player(Player& player, const CollisionHit& hit);
-
-private:
- enum MyState {
- STATE_DEFAULT, STATE_VANISHING, STATE_SUCKED
- };
- MyState mystate;
-
- Color color;
- float angle;
- float radius;
- float speed;
-
- std::auto_ptr<SoundSource> sound_source;
- Vector treepos_delta;
- GhostTree* tree;
-
- Vector suck_target;
-};
-
-#endif
-
+++ /dev/null
-// $Id$
-//
-// SuperTux - WalkingBadguy
-// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
-//
-// 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.
-
-#include <config.h>
-
-#include "walking_badguy.hpp"
-#include "log.hpp"
-#include "timer.hpp"
-
-WalkingBadguy::WalkingBadguy(const Vector& pos, const std::string& sprite_name, const std::string& walk_left_action, const std::string& walk_right_action, int layer)
- : BadGuy(pos, sprite_name, layer), walk_left_action(walk_left_action), walk_right_action(walk_right_action), walk_speed(80), max_drop_height(-1)
-{
-}
-
-WalkingBadguy::WalkingBadguy(const Vector& pos, Direction direction, const std::string& sprite_name, const std::string& walk_left_action, const std::string& walk_right_action, int layer)
- : BadGuy(pos, direction, sprite_name, layer), walk_left_action(walk_left_action), walk_right_action(walk_right_action), walk_speed(80), max_drop_height(-1)
-{
-}
-
-WalkingBadguy::WalkingBadguy(const lisp::Lisp& reader, const std::string& sprite_name, const std::string& walk_left_action, const std::string& walk_right_action, int layer)
- : BadGuy(reader, sprite_name, layer), walk_left_action(walk_left_action), walk_right_action(walk_right_action), walk_speed(80), max_drop_height(-1)
-{
-}
-
-void
-WalkingBadguy::write(lisp::Writer& writer)
-{
- writer.write_float("x", start_position.x);
- writer.write_float("y", start_position.y);
-}
-
-void
-WalkingBadguy::activate()
-{
- if(frozen)
- return;
- sprite->set_action(dir == LEFT ? walk_left_action : walk_right_action);
- bbox.set_size(sprite->get_current_hitbox_width(), sprite->get_current_hitbox_height());
- physic.set_velocity_x(dir == LEFT ? -walk_speed : walk_speed);
-}
-
-void
-WalkingBadguy::active_update(float elapsed_time)
-{
- BadGuy::active_update(elapsed_time);
-
- if (max_drop_height > -1) {
- if (on_ground() && might_fall(max_drop_height+1))
- {
- turn_around();
- }
- }
-
-}
-
-void
-WalkingBadguy::collision_solid(const CollisionHit& hit)
-{
-
- update_on_ground_flag(hit);
-
- if (hit.top) {
- if (physic.get_velocity_y() < 0) physic.set_velocity_y(0);
- }
- if (hit.bottom) {
- if (physic.get_velocity_y() > 0) physic.set_velocity_y(0);
- }
-
- if ((hit.left && (hit.slope_normal.y == 0) && (dir == LEFT)) || (hit.right && (hit.slope_normal.y == 0) && (dir == RIGHT))) {
- turn_around();
- }
-
-}
-
-HitResponse
-WalkingBadguy::collision_badguy(BadGuy& , const CollisionHit& hit)
-{
-
- if ((hit.left && (dir == LEFT)) || (hit.right && (dir == RIGHT))) {
- turn_around();
- }
-
- return CONTINUE;
-}
-
-void
-WalkingBadguy::turn_around()
-{
- if(frozen)
- return;
- dir = dir == LEFT ? RIGHT : LEFT;
- sprite->set_action(dir == LEFT ? walk_left_action : walk_right_action);
- physic.set_velocity_x(-physic.get_velocity_x());
-
- // if we get dizzy, we fall off the screen
- if (turn_around_timer.started()) {
- if (turn_around_counter++ > 10) kill_fall();
- } else {
- turn_around_timer.start(1);
- turn_around_counter = 0;
- }
-
-}
-
-void
-WalkingBadguy::freeze()
-{
- BadGuy::freeze();
- physic.set_velocity_x(0);
-}
-
-void
-WalkingBadguy::unfreeze()
-{
- BadGuy::unfreeze();
- WalkingBadguy::activate();
-}
-
-
-float
-WalkingBadguy::get_velocity_y() const
-{
- return physic.get_velocity_y();
-}
-
-void
-WalkingBadguy::set_velocity_y(float vy)
-{
- physic.set_velocity_y(vy);
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux - WalkingBadguy
-// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
-//
-// 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.
-
-#ifndef __WALKING_BADGUY_H__
-#define __WALKING_BADGUY_H__
-
-#include "badguy.hpp"
-
-class Timer;
-
-/**
- * Baseclass for a Badguy that just walks around.
- */
-class WalkingBadguy : public BadGuy
-{
-public:
- WalkingBadguy(const Vector& pos, const std::string& sprite_name, const std::string& walk_left_action, const std::string& walk_right_action, int layer = LAYER_OBJECTS);
- WalkingBadguy(const Vector& pos, Direction direction, const std::string& sprite_name, const std::string& walk_left_action, const std::string& walk_right_action, int layer = LAYER_OBJECTS);
- WalkingBadguy(const lisp::Lisp& reader, const std::string& sprite_name, const std::string& walk_left_action, const std::string& walk_right_action, int layer = LAYER_OBJECTS);
-
- void activate();
- void write(lisp::Writer& writer);
- void active_update(float elapsed_time);
- void collision_solid(const CollisionHit& hit);
- HitResponse collision_badguy(BadGuy& badguy, const CollisionHit& hit);
- void freeze();
- void unfreeze();
-
- float get_velocity_y() const;
- void set_velocity_y(float vy);
-
-protected:
- void turn_around();
-
- std::string walk_left_action;
- std::string walk_right_action;
- float walk_speed;
- int max_drop_height; /**< Maximum height of drop before we will turn around, or -1 to just drop from any ledge */
- Timer turn_around_timer;
- int turn_around_counter; /**< counts number of turns since turn_around_timer was started */
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux - Walking Leaf
-// Copyright (C) 2006 Wolfgang Becker <uafr@gmx.de>
-//
-// 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.
-
-#include <config.h>
-
-#include "walkingleaf.hpp"
-#include "random_generator.hpp"
-#include "object/sprite_particle.hpp"
-
-WalkingLeaf::WalkingLeaf(const lisp::Lisp& reader)
- : WalkingBadguy(reader, "images/creatures/walkingleaf/walkingleaf.sprite", "left", "right")
-{
- walk_speed = 60;
- max_drop_height = 16;
-}
-
-WalkingLeaf::WalkingLeaf(const Vector& pos, Direction d)
- : WalkingBadguy(pos, d, "images/creatures/walkingleaf/walkingleaf.sprite", "left", "right")
-{
- walk_speed = 60;
- max_drop_height = 16;
-}
-
-bool
-WalkingLeaf::collision_squished(GameObject& object)
-{
- sprite->set_action(dir == LEFT ? "squished-left" : "squished-right");
- kill_squished(object);
- return true;
-}
-
-IMPLEMENT_FACTORY(WalkingLeaf, "walkingleaf")
+++ /dev/null
-// $Id$
-//
-// SuperTux - Walking Leaf
-// Copyright (C) 2006 Wolfgang Becker <uafr@gmx.de>
-//
-// 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.
-
-#ifndef __WALKINGLEAF_H__
-#define __WALKINGLEAF_H__
-
-#include "walking_badguy.hpp"
-
-/*
- * Easy to kill badguy that does not jump down from it's ledge.
- */
-class WalkingLeaf : public WalkingBadguy
-{
-public:
- WalkingLeaf(const lisp::Lisp& reader);
- WalkingLeaf(const Vector& pos, Direction d);
-
- virtual WalkingLeaf* clone() const { return new WalkingLeaf(*this); }
-
-protected:
- bool collision_squished(GameObject& object);
-
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux - "Will-O-Wisp" Badguy
-// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
-//
-// 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.
-#include <config.h>
-
-#include "willowisp.hpp"
-#include "log.hpp"
-#include "game_session.hpp"
-#include "object/lantern.hpp"
-#include "object/player.hpp"
-#include "scripting/squirrel_util.hpp"
-
-static const float FLYSPEED = 64; /**< speed in px per second */
-static const float TRACK_RANGE = 384; /**< at what distance to start tracking the player */
-static const float VANISH_RANGE = 512; /**< at what distance to stop tracking and vanish */
-static const std::string SOUNDFILE = "sounds/willowisp.wav";
-
-WillOWisp::WillOWisp(const lisp::Lisp& reader)
- : BadGuy(reader, "images/creatures/willowisp/willowisp.sprite", LAYER_FLOATINGOBJECTS), mystate(STATE_IDLE), target_sector("main"), target_spawnpoint("main")
-{
- bool running = false;
- flyspeed = FLYSPEED;
- track_range = TRACK_RANGE;
- vanish_range = VANISH_RANGE;
-
- reader.get("sector", target_sector);
- reader.get("spawnpoint", target_spawnpoint);
- reader.get("name", name);
- reader.get("flyspeed", flyspeed);
- reader.get("track-range", track_range);
- reader.get("vanish-range", vanish_range);
- reader.get("hit-script", hit_script);
- reader.get("running", running);
-
- const lisp::Lisp* pathLisp = reader.get_lisp("path");
- if(pathLisp != NULL) {
- path.reset(new Path());
- path->read(*pathLisp);
- walker.reset(new PathWalker(path.get(), running));
- if(running)
- mystate = STATE_PATHMOVING_TRACK;
- }
-
- countMe = false;
- sound_manager->preload(SOUNDFILE);
-}
-
-void
-WillOWisp::draw(DrawingContext& context)
-{
- sprite->draw(context, get_pos(), layer);
-
- context.push_target();
- context.set_target(DrawingContext::LIGHTMAP);
-
- sprite->draw(context, get_pos(), layer);
-
- context.pop_target();
-}
-
-void
-WillOWisp::active_update(float elapsed_time)
-{
- Player* player = get_nearest_player();
- if (!player) return;
- Vector p1 = this->get_pos() + (this->get_bbox().p2 - this->get_bbox().p1) / 2;
- Vector p2 = player->get_pos() + (player->get_bbox().p2 - player->get_bbox().p1) / 2;
- Vector dist = (p2 - p1);
-
- switch(mystate) {
- case STATE_STOPPED:
- break;
-
- case STATE_IDLE:
- if (dist.norm() <= track_range) {
- mystate = STATE_TRACKING;
- }
- break;
-
- case STATE_TRACKING:
- if (dist.norm() <= vanish_range) {
- Vector dir = dist.unit();
- movement = dir * elapsed_time * flyspeed;
- } else {
- vanish();
- }
- sound_source->set_position(get_pos());
- break;
-
- case STATE_WARPING:
- if(sprite->animation_done()) {
- remove_me();
- }
-
- case STATE_VANISHING: {
- Vector dir = dist.unit();
- movement = dir * elapsed_time * flyspeed;
- if(sprite->animation_done()) {
- remove_me();
- }
- break;
- }
-
- case STATE_PATHMOVING:
- case STATE_PATHMOVING_TRACK:
- if(walker.get() == NULL)
- return;
- movement = walker->advance(elapsed_time) - get_pos();
- if(mystate == STATE_PATHMOVING_TRACK && dist.norm() <= track_range) {
- mystate = STATE_TRACKING;
- }
- break;
-
- default:
- assert(false);
- }
-}
-
-void
-WillOWisp::activate()
-{
- sprite->set_action("idle");
-
- sound_source.reset(sound_manager->create_sound_source(SOUNDFILE));
- sound_source->set_position(get_pos());
- sound_source->set_looping(true);
- sound_source->set_gain(2.0);
- sound_source->set_reference_distance(32);
- sound_source->play();
-}
-
-void
-WillOWisp::deactivate()
-{
- sound_source.reset(NULL);
-
- switch (mystate) {
- case STATE_STOPPED:
- case STATE_IDLE:
- case STATE_PATHMOVING:
- case STATE_PATHMOVING_TRACK:
- break;
- case STATE_TRACKING:
- mystate = STATE_IDLE;
- break;
- case STATE_WARPING:
- case STATE_VANISHING:
- remove_me();
- break;
- }
-}
-
-void
-WillOWisp::vanish()
-{
- mystate = STATE_VANISHING;
- sprite->set_action("vanishing", 1);
- set_group(COLGROUP_DISABLED);
-}
-
-bool
-WillOWisp::collides(GameObject& other, const CollisionHit& ) {
- Lantern* lantern = dynamic_cast<Lantern*>(&other);
-
- if (lantern && lantern->is_open())
- return true;
-
- if (dynamic_cast<Player*>(&other))
- return true;
-
- return false;
-}
-
-HitResponse
-WillOWisp::collision_player(Player& player, const CollisionHit& ) {
- if(player.is_invincible())
- return ABORT_MOVE;
-
- if (mystate != STATE_TRACKING)
- return ABORT_MOVE;
-
- mystate = STATE_WARPING;
- sprite->set_action("warping", 1);
-
- if(hit_script != "") {
- std::istringstream stream(hit_script);
- Sector::current()->run_script(stream, "hit-script");
- } else {
- GameSession::current()->respawn(target_sector, target_spawnpoint);
- }
- sound_manager->play("sounds/warp.wav");
-
- return CONTINUE;
-}
-
-void
-WillOWisp::goto_node(int node_no)
-{
- walker->goto_node(node_no);
- if(mystate != STATE_PATHMOVING && mystate != STATE_PATHMOVING_TRACK) {
- mystate = STATE_PATHMOVING;
- }
-}
-
-void
-WillOWisp::start_moving()
-{
- walker->start_moving();
-}
-
-void
-WillOWisp::stop_moving()
-{
- walker->stop_moving();
-}
-
-void
-WillOWisp::set_state(const std::string& new_state)
-{
- if(new_state == "stopped") {
- mystate = STATE_STOPPED;
- } else if(new_state == "idle") {
- mystate = STATE_IDLE;
- } else if(new_state == "move_path") {
- mystate = STATE_PATHMOVING;
- walker->start_moving();
- } else if(new_state == "move_path_track") {
- mystate = STATE_PATHMOVING_TRACK;
- walker->start_moving();
- } else if(new_state == "normal") {
- mystate = STATE_IDLE;
- } else if(new_state == "vanish") {
- vanish();
- } else {
- std::ostringstream msg;
- msg << "Can't set unknown willowisp state '" << new_state << "', should "
- "be stopped, move_path, move_path_track or normal";
- throw new std::runtime_error(msg.str());
- }
-}
-
-void
-WillOWisp::expose(HSQUIRRELVM vm, SQInteger table_idx)
-{
- if (name.empty())
- return;
-
- std::cout << "Expose me '" << name << "'\n";
- Scripting::WillOWisp* interface = static_cast<Scripting::WillOWisp*> (this);
- expose_object(vm, table_idx, interface, name);
-}
-
-void
-WillOWisp::unexpose(HSQUIRRELVM vm, SQInteger table_idx)
-{
- if (name.empty())
- return;
-
- std::cout << "UnExpose me '" << name << "'\n";
- Scripting::unexpose_object(vm, table_idx, name);
-}
-
-IMPLEMENT_FACTORY(WillOWisp, "willowisp")
+++ /dev/null
-// $Id$
-//
-// SuperTux - "Will-O-Wisp" Badguy
-// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
-//
-// 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.
-
-#ifndef __WILLOWISP_H__
-#define __WILLOWISP_H__
-
-#include "badguy.hpp"
-#include "object/path.hpp"
-#include "object/path_walker.hpp"
-#include "script_interface.hpp"
-#include "scripting/willowisp.hpp"
-
-class WillOWisp : public BadGuy, public Scripting::WillOWisp,
- public ScriptInterface
-{
-public:
- WillOWisp(const lisp::Lisp& reader);
-
- void activate();
- void deactivate();
-
- void active_update(float elapsed_time);
- virtual bool is_flammable() const { return false; }
- virtual bool is_freezable() const { return false; }
- virtual void kill_fall() { vanish(); }
-
- /**
- * make WillOWisp vanish
- */
- void vanish();
-
- virtual void draw(DrawingContext& context);
-
- virtual void goto_node(int node_no);
- virtual void set_state(const std::string& state);
- virtual void start_moving();
- virtual void stop_moving();
-
- virtual void expose(HSQUIRRELVM vm, SQInteger table_idx);
- virtual void unexpose(HSQUIRRELVM vm, SQInteger table_idx);
-
-protected:
- virtual bool collides(GameObject& other, const CollisionHit& hit);
- HitResponse collision_player(Player& player, const CollisionHit& hit);
-
-private:
- enum MyState {
- STATE_STOPPED, STATE_IDLE, STATE_TRACKING, STATE_VANISHING, STATE_WARPING,
- STATE_PATHMOVING, STATE_PATHMOVING_TRACK
- };
- MyState mystate;
-
- std::string target_sector;
- std::string target_spawnpoint;
- std::string hit_script;
-
- std::auto_ptr<SoundSource> sound_source;
-
- std::auto_ptr<Path> path;
- std::auto_ptr<PathWalker> walker;
-
- float flyspeed;
- float track_range;
- float vanish_range;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux - Boss "Yeti"
-// Copyright (C) 2005 Matthias Braun <matze@braunis.de>
-// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
-//
-// 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.
-#include <config.h>
-
-#include <float.h>
-#include <sstream>
-#include <memory>
-#include "yeti.hpp"
-#include "object/camera.hpp"
-#include "yeti_stalactite.hpp"
-#include "bouncing_snowball.hpp"
-#include "game_session.hpp"
-#include "level.hpp"
-
-namespace {
- const float JUMP_DOWN_VX = 250; /**< horizontal speed while jumping off the dais */
- const float JUMP_DOWN_VY = -250; /**< vertical speed while jumping off the dais */
-
- const float RUN_VX = 350; /**< horizontal speed while running */
-
- const float JUMP_UP_VX = 350; /**< horizontal speed while jumping on the dais */
- const float JUMP_UP_VY = -800; /**< vertical speed while jumping on the dais */
-
- const float STOMP_VY = -250; /** vertical speed while stomping on the dais */
-
- const float LEFT_STAND_X = 16; /**< x-coordinate of left dais' end position */
- const float RIGHT_STAND_X = 800-60-16; /**< x-coordinate of right dais' end position */
- const float LEFT_JUMP_X = LEFT_STAND_X+224; /**< x-coordinate of from where to jump on the left dais */
- const float RIGHT_JUMP_X = RIGHT_STAND_X-224; /**< x-coordinate of from where to jump on the right dais */
- const float STOMP_WAIT = .5; /**< time we stay on the dais before jumping again */
- const float SAFE_TIME = .5; /**< the time we are safe when tux just hit us */
- const int INITIAL_HITPOINTS = 3; /**< number of hits we can take */
-
- const float SQUISH_TIME = 5;
-}
-
-Yeti::Yeti(const lisp::Lisp& reader)
- : BadGuy(reader, "images/creatures/yeti/yeti.sprite")
-{
- hit_points = INITIAL_HITPOINTS;
- countMe = false;
- sound_manager->preload("sounds/yeti_gna.wav");
- sound_manager->preload("sounds/yeti_roar.wav");
- hud_head.reset(new Surface("images/creatures/yeti/hudlife.png"));
-}
-
-Yeti::~Yeti()
-{
-}
-
-void
-Yeti::activate()
-{
- dir = RIGHT;
- jump_down();
-}
-
-void
-Yeti::draw(DrawingContext& context)
-{
- // we blink when we are safe
- if(safe_timer.started() && size_t(game_time*40)%2)
- return;
-
- draw_hit_points(context);
-
- BadGuy::draw(context);
-}
-
-void
-Yeti::draw_hit_points(DrawingContext& context)
-{
- int i;
-
- Surface *hh = hud_head.get();
- if (!hh)
- return;
-
- context.push_transform();
- context.set_translation(Vector(0, 0));
-
- for (i = 0; i < hit_points; ++i)
- {
- context.draw_surface(hh, Vector(BORDER_X + (i * hh->get_width()), BORDER_Y + 1), LAYER_FOREGROUND1);
- }
-
- context.pop_transform();
-}
-
-void
-Yeti::active_update(float elapsed_time)
-{
- switch(state) {
- case JUMP_DOWN:
- physic.set_velocity_x((dir==RIGHT)?+JUMP_DOWN_VX:-JUMP_DOWN_VX);
- break;
- case RUN:
- physic.set_velocity_x((dir==RIGHT)?+RUN_VX:-RUN_VX);
- if (((dir == RIGHT) && (get_pos().x >= RIGHT_JUMP_X)) || ((dir == LEFT) && (get_pos().x <= LEFT_JUMP_X))) jump_up();
- break;
- case JUMP_UP:
- physic.set_velocity_x((dir==RIGHT)?+JUMP_UP_VX:-JUMP_UP_VX);
- if (((dir == RIGHT) && (get_pos().x >= RIGHT_STAND_X)) || ((dir == LEFT) && (get_pos().x <= LEFT_STAND_X))) be_angry();
- break;
- case BE_ANGRY:
- if(state_timer.check()) {
- sound_manager->play("sounds/yeti_gna.wav");
- physic.set_velocity_y(STOMP_VY);
- sprite->set_action((dir==RIGHT)?"stomp-right":"stomp-left");
- }
- break;
- case SQUISHED:
- if (state_timer.check()) {
- remove_me();
- }
- break;
- }
-
- movement = physic.get_movement(elapsed_time);
-}
-
-void
-Yeti::jump_down()
-{
- sprite->set_action((dir==RIGHT)?"jump-right":"jump-left");
- physic.set_velocity_x((dir==RIGHT)?(+JUMP_DOWN_VX):(-JUMP_DOWN_VX));
- physic.set_velocity_y(JUMP_DOWN_VY);
- state = JUMP_DOWN;
-}
-
-void
-Yeti::run()
-{
- sprite->set_action((dir==RIGHT)?"run-right":"run-left");
- physic.set_velocity_x((dir==RIGHT)?(+RUN_VX):(-RUN_VX));
- physic.set_velocity_y(0);
- state = RUN;
-}
-
-void
-Yeti::jump_up()
-{
- sprite->set_action((dir==RIGHT)?"jump-right":"jump-left");
- physic.set_velocity_x((dir==RIGHT)?(+JUMP_UP_VX):(-JUMP_UP_VX));
- physic.set_velocity_y(JUMP_UP_VY);
- state = JUMP_UP;
-}
-
-void
-Yeti::be_angry()
-{
- //turn around
- dir = (dir==RIGHT)?LEFT:RIGHT;
-
- sprite->set_action((dir==RIGHT)?"stand-right":"stand-left");
- physic.set_velocity_x(0);
- physic.set_velocity_y(0);
- if (hit_points < INITIAL_HITPOINTS) summon_snowball();
- stomp_count = 0;
- state = BE_ANGRY;
- state_timer.start(STOMP_WAIT);
-}
-
-void
-Yeti::summon_snowball()
-{
- Sector::current()->add_object(new BouncingSnowball(Vector(get_pos().x+(dir == RIGHT ? 64 : -64), get_pos().y), dir));
-}
-
-bool
-Yeti::collision_squished(GameObject& object)
-{
- kill_squished(object);
-
- return true;
-}
-
-void
-Yeti::kill_squished(GameObject& object)
-{
- Player* player = dynamic_cast<Player*>(&object);
- if (player) {
- player->bounce(*this);
- take_hit(*player);
- }
-}
-
-void Yeti::take_hit(Player& )
-{
- if(safe_timer.started())
- return;
-
- sound_manager->play("sounds/yeti_roar.wav");
- hit_points--;
-
- if(hit_points <= 0) {
- // We're dead
- physic.enable_gravity(true);
- physic.set_velocity_x(0);
- physic.set_velocity_y(0);
-
- state = SQUISHED;
- state_timer.start(SQUISH_TIME);
- set_group(COLGROUP_MOVING_ONLY_STATIC);
- sprite->set_action("dead");
-
- if (countMe) Sector::current()->get_level()->stats.badguys++;
-
- if(dead_script != "") {
- std::istringstream stream(dead_script);
- Sector::current()->run_script(stream, "Yeti - dead-script");
- }
- }
- else {
- safe_timer.start(SAFE_TIME);
- }
-}
-
-void
-Yeti::kill_fall()
-{
- // shooting bullets or being invincible won't work :)
- take_hit(*get_nearest_player()); // FIXME: debug only(?)
-}
-
-void
-Yeti::write(lisp::Writer& writer)
-{
- writer.start_list("yeti");
-
- writer.write_float("x", start_position.x);
- writer.write_float("y", start_position.y);
-
- writer.end_list("yeti");
-}
-
-void
-Yeti::drop_stalactite()
-{
- // make a stalactite falling down and shake camera a bit
- Sector::current()->camera->shake(.1f, 0, 10);
-
- YetiStalactite* nearest = 0;
- float dist = FLT_MAX;
-
- Player* player = this->get_nearest_player();
- if (!player) return;
-
- Sector* sector = Sector::current();
- for(Sector::GameObjects::iterator i = sector->gameobjects.begin();
- i != sector->gameobjects.end(); ++i) {
- YetiStalactite* stalactite = dynamic_cast<YetiStalactite*> (*i);
- if(stalactite && stalactite->is_hanging()) {
- float sdist
- = fabsf(stalactite->get_pos().x - player->get_pos().x);
- if(sdist < dist) {
- nearest = stalactite;
- dist = sdist;
- }
- }
- }
-
- if(nearest)
- nearest->start_shaking();
-}
-
-void
-Yeti::collision_solid(const CollisionHit& hit)
-{
- if(hit.top || hit.bottom) {
- // hit floor or roof
- physic.set_velocity_y(0);
- switch (state) {
- case JUMP_DOWN:
- run();
- break;
- case RUN:
- break;
- case JUMP_UP:
- break;
- case BE_ANGRY:
- // we just landed
- if(!state_timer.started()) {
- sprite->set_action((dir==RIGHT)?"stand-right":"stand-left");
- stomp_count++;
- drop_stalactite();
-
- // go to other side after 3 jumps
- if(stomp_count == 3) {
- jump_down();
- } else {
- // jump again
- state_timer.start(STOMP_WAIT);
- }
- }
- break;
- case SQUISHED:
- break;
- }
- } else if(hit.left || hit.right) {
- // hit wall
- jump_up();
- }
-}
-
-IMPLEMENT_FACTORY(Yeti, "yeti")
+++ /dev/null
-// $Id$
-//
-// SuperTux - Boss "Yeti"
-// Copyright (C) 2005 Matthias Braun <matze@braunis.de>
-// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
-//
-// 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.
-
-#ifndef __YETI_H__
-#define __YETI_H__
-
-#include <memory>
-
-#include "badguy.hpp"
-
-class Yeti : public BadGuy
-{
-public:
- Yeti(const lisp::Lisp& lisp);
- ~Yeti();
-
- void draw(DrawingContext& context);
- void write(lisp::Writer& writer);
- void activate();
- void active_update(float elapsed_time);
- void collision_solid(const CollisionHit& hit);
- bool collision_squished(GameObject& object);
- void kill_squished(GameObject& object);
- void kill_fall();
-
- virtual Yeti* clone() const { return new Yeti((Yeti&)*this); }
-
-private:
- void run();
- void jump_up();
- void be_angry();
- void drop_stalactite();
- void summon_snowball();
- void jump_down();
-
- void draw_hit_points(DrawingContext& context);
-
- void take_hit(Player& player);
-
- enum YetiState {
- JUMP_DOWN,
- RUN,
- JUMP_UP,
- BE_ANGRY,
- SQUISHED
- };
- YetiState state;
- Timer state_timer;
- Timer safe_timer;
- int stomp_count;
- int hit_points;
- std::auto_ptr<Surface> hud_head;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include "yeti_stalactite.hpp"
-
-static const float SHAKE_TIME = .8f;
-
-YetiStalactite::YetiStalactite(const lisp::Lisp& lisp)
- : Stalactite(lisp)
-{
-}
-
-YetiStalactite::~YetiStalactite()
-{
-}
-
-void
-YetiStalactite::write(lisp::Writer& writer)
-{
- writer.start_list("yeti_stalactite");
- writer.write_float("x", start_position.x);
- writer.write_float("y", start_position.y);
- writer.end_list("yeti_stalactite");
-}
-
-void
-YetiStalactite::start_shaking()
-{
- timer.start(SHAKE_TIME);
- state = STALACTITE_SHAKING;
-}
-
-bool
-YetiStalactite::is_hanging()
-{
- return state == STALACTITE_HANGING;
-}
-
-void
-YetiStalactite::active_update(float elapsed_time)
-{
- if(state == STALACTITE_HANGING)
- return;
-
- Stalactite::active_update(elapsed_time);
-}
-
-IMPLEMENT_FACTORY(YetiStalactite, "yeti_stalactite")
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-
-#ifndef __YETI_STALACTITE_H__
-#define __YETI_STALACTITE_H__
-
-#include "stalactite.hpp"
-
-class YetiStalactite : public Stalactite
-{
-public:
- YetiStalactite(const lisp::Lisp& lisp);
- virtual ~YetiStalactite();
-
- void write(lisp::Writer& );
- void active_update(float elapsed_time);
- void start_shaking();
- bool is_hanging();
-
- virtual YetiStalactite* clone() const { return new YetiStalactite(*this); }
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// Zeekling - flyer that swoops down when she spots the player
-// Copyright (C) 2005 Matthias Braun <matze@braunis.de>
-// Copyright (C) 2006 Christoph Sommer <supertux@2006.expires.deltadevelopment.de>
-//
-// 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.
-
-#include <config.h>
-#include <math.h>
-
-#include "zeekling.hpp"
-#include "random_generator.hpp"
-
-Zeekling::Zeekling(const lisp::Lisp& reader)
- : BadGuy(reader, "images/creatures/zeekling/zeekling.sprite"), last_player(0)
-{
- state = FLYING;
-}
-
-Zeekling::Zeekling(const Vector& pos, Direction d)
- : BadGuy(pos, d, "images/creatures/zeekling/zeekling.sprite"), last_player(0)
-{
- state = FLYING;
-}
-
-void
-Zeekling::write(lisp::Writer& writer)
-{
- writer.start_list("zeekling");
-
- writer.write_float("x", start_position.x);
- writer.write_float("y", start_position.y);
-
- writer.end_list("zeekling");
-}
-
-void
-Zeekling::activate()
-{
- speed = systemRandom.rand(130, 171);
- physic.set_velocity_x(dir == LEFT ? -speed : speed);
- physic.enable_gravity(false);
- sprite->set_action(dir == LEFT ? "left" : "right");
-}
-
-bool
-Zeekling::collision_squished(GameObject& object)
-{
- sprite->set_action(dir == LEFT ? "squished-left" : "squished-right");
- kill_squished(object);
- kill_fall();
- return true;
-}
-
-void
-Zeekling::onBumpHorizontal() {
- if (state == FLYING) {
- dir = (dir == LEFT ? RIGHT : LEFT);
- sprite->set_action(dir == LEFT ? "left" : "right");
- physic.set_velocity_x(dir == LEFT ? -speed : speed);
- } else
- if (state == DIVING) {
- dir = (dir == LEFT ? RIGHT : LEFT);
- state = FLYING;
- sprite->set_action(dir == LEFT ? "left" : "right");
- physic.set_velocity_x(dir == LEFT ? -speed : speed);
- physic.set_velocity_y(0);
- } else
- if (state == CLIMBING) {
- dir = (dir == LEFT ? RIGHT : LEFT);
- sprite->set_action(dir == LEFT ? "left" : "right");
- physic.set_velocity_x(dir == LEFT ? -speed : speed);
- } else {
- assert(false);
- }
-}
-
-void
-Zeekling::onBumpVertical() {
- if (state == FLYING) {
- physic.set_velocity_y(0);
- } else
- if (state == DIVING) {
- state = CLIMBING;
- physic.set_velocity_y(-speed);
- sprite->set_action(dir == LEFT ? "left" : "right");
- } else
- if (state == CLIMBING) {
- state = FLYING;
- physic.set_velocity_y(0);
- }
-}
-
-void
-Zeekling::collision_solid(const CollisionHit& hit)
-{
- if(hit.top || hit.bottom) {
- onBumpVertical();
- } else if(hit.left || hit.right) {
- onBumpHorizontal();
- }
-}
-
-/**
- * linear prediction of player and badguy positions to decide if we should enter the DIVING state
- */
-bool
-Zeekling::should_we_dive() {
-
- const MovingObject* player = this->get_nearest_player();
- if (player && last_player && (player == last_player)) {
-
- // get positions, calculate movement
- const Vector player_pos = player->get_pos();
- const Vector player_mov = (player_pos - last_player_pos);
- const Vector self_pos = this->get_pos();
- const Vector self_mov = (self_pos - last_self_pos);
-
- // new vertical speed to test with
- float vy = 2*fabsf(self_mov.x);
-
- // do not dive if we are not above the player
- float height = player_pos.y - self_pos.y;
- if (height <= 0) return false;
-
- // do not dive if we are too far above the player
- if (height > 512) return false;
-
- // do not dive if we would not descend faster than the player
- float relSpeed = vy - player_mov.y;
- if (relSpeed <= 0) return false;
-
- // guess number of frames to descend to same height as player
- float estFrames = height / relSpeed;
-
- // guess where the player would be at this time
- float estPx = (player_pos.x + (estFrames * player_mov.x));
-
- // guess where we would be at this time
- float estBx = (self_pos.x + (estFrames * self_mov.x));
-
- // near misses are OK, too
- if (fabsf(estPx - estBx) < 8) return true;
- }
-
- // update last player tracked, as well as our positions
- last_player = player;
- if (player) {
- last_player_pos = player->get_pos();
- last_self_pos = this->get_pos();
- }
-
- return false;
-}
-
-void
-Zeekling::active_update(float elapsed_time) {
- if (state == FLYING) {
- if (should_we_dive()) {
- state = DIVING;
- physic.set_velocity_y(2*fabsf(physic.get_velocity_x()));
- sprite->set_action(dir == LEFT ? "diving-left" : "diving-right");
- }
- BadGuy::active_update(elapsed_time);
- return;
- } else if (state == DIVING) {
- BadGuy::active_update(elapsed_time);
- return;
- } else if (state == CLIMBING) {
- // stop climbing when we're back at initial height
- if (get_pos().y <= start_position.y) {
- state = FLYING;
- physic.set_velocity_y(0);
- }
- BadGuy::active_update(elapsed_time);
- return;
- } else {
- assert(false);
- }
-}
-
-IMPLEMENT_FACTORY(Zeekling, "zeekling")
+++ /dev/null
-// $Id$
-//
-// Zeekling - flyer that swoops down when she spots the player
-// Copyright (C) 2005 Matthias Braun <matze@braunis.de>
-// Copyright (C) 2006 Christoph Sommer <supertux@2006.expires.deltadevelopment.de>
-//
-// 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.
-
-#ifndef __ZEEKLING_H__
-#define __ZEEKLING_H__
-
-#include "badguy.hpp"
-
-class Zeekling : public BadGuy
-{
-public:
- Zeekling(const lisp::Lisp& reader);
- Zeekling(const Vector& pos, Direction d);
-
- void activate();
- void write(lisp::Writer& writer);
- void collision_solid(const CollisionHit& hit);
- void active_update(float elapsed_time);
-
- virtual Zeekling* clone() const { return new Zeekling(*this); }
-
-protected:
- bool collision_squished(GameObject& object);
- float speed;
-
- Timer diveRecoverTimer;
-
- enum ZeeklingState {
- FLYING,
- DIVING,
- CLIMBING
- };
- ZeeklingState state;
-
-private:
- const MovingObject* last_player; /**< last player we tracked */
- Vector last_player_pos; /**< position we last spotted the player at */
- Vector last_self_pos; /**< position we last were at */
-
- bool should_we_dive();
- void onBumpHorizontal();
- void onBumpVertical();
-};
-
-#endif
+++ /dev/null
-/*
- * BinReloc - a library for creating relocatable executables
- * Written by: Hongli Lai <h.lai@chello.nl>
- * http://autopackage.org/
- *
- * This source code is public domain. You can relicense this code
- * under whatever license you want.
- *
- * See http://autopackage.org/docs/binreloc/ for
- * more information and how to use this.
- */
-
-#ifndef __BINRELOC_C__
-#define __BINRELOC_C__
-
-// [Christoph] use config.h, which defines ENABLE_BINRELOC
-#include <config.h>
-
-#ifdef ENABLE_BINRELOC
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <unistd.h>
-#endif /* ENABLE_BINRELOC */
-#include <stdio.h>
-#include <stdlib.h>
-#include <limits.h>
-#include <string.h>
-#include "binreloc.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif /* __cplusplus */
-
-
-
-/** @internal
- * Find the canonical filename of the executable. Returns the filename
- * (which must be freed) or NULL on error. If the parameter 'error' is
- * not NULL, the error code will be stored there, if an error occured.
- */
-static char *
-_br_find_exe (BrInitError *error)
-{
-#ifndef ENABLE_BINRELOC
- if (error)
- *error = BR_INIT_ERROR_DISABLED;
- return NULL;
-#else
- char *path, *path2, *line, *result;
- size_t buf_size;
- ssize_t size;
- struct stat stat_buf;
- FILE *f;
-
- /* Read from /proc/self/exe (symlink) */
- if (sizeof (path) > SSIZE_MAX)
- buf_size = SSIZE_MAX - 1;
- else
- buf_size = PATH_MAX - 1;
- path = (char *) malloc (buf_size);
- if (path == NULL) {
- /* Cannot allocate memory. */
- if (error)
- *error = BR_INIT_ERROR_NOMEM;
- return NULL;
- }
- path2 = (char *) malloc (buf_size);
- if (path2 == NULL) {
- /* Cannot allocate memory. */
- if (error)
- *error = BR_INIT_ERROR_NOMEM;
- free (path);
- return NULL;
- }
-
- strncpy (path2, "/proc/self/exe", buf_size - 1);
-
- while (1) {
- int i;
-
- size = readlink (path2, path, buf_size - 1);
- if (size == -1) {
- /* Error. */
- free (path2);
- break;
- }
-
- /* readlink() success. */
- path[size] = '\0';
-
- /* Check whether the symlink's target is also a symlink.
- * We want to get the final target. */
- i = stat (path, &stat_buf);
- if (i == -1) {
- /* Error. */
- free (path2);
- break;
- }
-
- /* stat() success. */
- if (!S_ISLNK (stat_buf.st_mode)) {
- /* path is not a symlink. Done. */
- free (path2);
- return path;
- }
-
- /* path is a symlink. Continue loop and resolve this. */
- strncpy (path, path2, buf_size - 1);
- }
-
-
- /* readlink() or stat() failed; this can happen when the program is
- * running in Valgrind 2.2. Read from /proc/self/maps as fallback. */
-
- buf_size = PATH_MAX + 128;
- line = (char *) realloc (path, buf_size);
- if (line == NULL) {
- /* Cannot allocate memory. */
- free (path);
- if (error)
- *error = BR_INIT_ERROR_NOMEM;
- return NULL;
- }
-
- f = fopen ("/proc/self/maps", "r");
- if (f == NULL) {
- free (line);
- if (error)
- *error = BR_INIT_ERROR_OPEN_MAPS;
- return NULL;
- }
-
- /* The first entry should be the executable name. */
- result = fgets (line, (int) buf_size, f);
- if (result == NULL) {
- fclose (f);
- free (line);
- if (error)
- *error = BR_INIT_ERROR_READ_MAPS;
- return NULL;
- }
-
- /* Get rid of newline character. */
- buf_size = strlen (line);
- if (buf_size <= 0) {
- /* Huh? An empty string? */
- fclose (f);
- free (line);
- if (error)
- *error = BR_INIT_ERROR_INVALID_MAPS;
- return NULL;
- }
- if (line[buf_size - 1] == 10)
- line[buf_size - 1] = 0;
-
- /* Extract the filename; it is always an absolute path. */
- path = strchr (line, '/');
-
- /* Sanity check. */
- if (strstr (line, " r-xp ") == NULL || path == NULL) {
- fclose (f);
- free (line);
- if (error)
- *error = BR_INIT_ERROR_INVALID_MAPS;
- return NULL;
- }
-
- path = strdup (path);
- free (line);
- fclose (f);
- return path;
-#endif /* ENABLE_BINRELOC */
-}
-
-
-/** @internal
- * Find the canonical filename of the executable which owns symbol.
- * Returns a filename which must be freed, or NULL on error.
- */
-static char *
-_br_find_exe_for_symbol (const void *symbol, BrInitError *error)
-{
- symbol = symbol; // [Christoph] mark it as used
-#ifndef ENABLE_BINRELOC
- if (error)
- *error = BR_INIT_ERROR_DISABLED;
- return (char *) NULL;
-#else
- #define SIZE PATH_MAX + 100
- FILE *f;
- size_t address_string_len;
- char *address_string, line[SIZE], *found;
-
- if (symbol == NULL)
- return (char *) NULL;
-
- f = fopen ("/proc/self/maps", "r");
- if (f == NULL)
- return (char *) NULL;
-
- address_string_len = 4;
- address_string = (char *) malloc (address_string_len);
- found = (char *) NULL;
-
- while (!feof (f)) {
- char *start_addr, *end_addr, *end_addr_end, *file;
- void *start_addr_p, *end_addr_p;
- size_t len;
-
- if (fgets (line, SIZE, f) == NULL)
- break;
-
- /* Sanity check. */
- if (strstr (line, " r-xp ") == NULL || strchr (line, '/') == NULL)
- continue;
-
- /* Parse line. */
- start_addr = line;
- end_addr = strchr (line, '-');
- file = strchr (line, '/');
-
- /* More sanity check. */
- if (!(file > end_addr && end_addr != NULL && end_addr[0] == '-'))
- continue;
-
- end_addr[0] = '\0';
- end_addr++;
- end_addr_end = strchr (end_addr, ' ');
- if (end_addr_end == NULL)
- continue;
-
- end_addr_end[0] = '\0';
- len = strlen (file);
- if (len == 0)
- continue;
- if (file[len - 1] == '\n')
- file[len - 1] = '\0';
-
- /* Get rid of "(deleted)" from the filename. */
- len = strlen (file);
- if (len > 10 && strcmp (file + len - 10, " (deleted)") == 0)
- file[len - 10] = '\0';
-
- /* I don't know whether this can happen but better safe than sorry. */
- len = strlen (start_addr);
- if (len != strlen (end_addr))
- continue;
-
-
- /* Transform the addresses into a string in the form of 0xdeadbeef,
- * then transform that into a pointer. */
- if (address_string_len < len + 3) {
- address_string_len = len + 3;
- address_string = (char *) realloc (address_string, address_string_len);
- }
-
- memcpy (address_string, "0x", 2);
- memcpy (address_string + 2, start_addr, len);
- address_string[2 + len] = '\0';
- sscanf (address_string, "%p", &start_addr_p);
-
- memcpy (address_string, "0x", 2);
- memcpy (address_string + 2, end_addr, len);
- address_string[2 + len] = '\0';
- sscanf (address_string, "%p", &end_addr_p);
-
-
- if (symbol >= start_addr_p && symbol < end_addr_p) {
- found = file;
- break;
- }
- }
-
- free (address_string);
- fclose (f);
-
- if (found == NULL)
- return (char *) NULL;
- else
- return strdup (found);
-#endif /* ENABLE_BINRELOC */
-}
-
-
-#ifndef BINRELOC_RUNNING_DOXYGEN
- #undef NULL
- #define NULL ((void *) 0) /* typecasted as char* for C++ type safeness */
-#endif
-
-static char *exe = (char *) NULL;
-
-
-/** Initialize the BinReloc library (for applications).
- *
- * This function must be called before using any other BinReloc functions.
- * It attempts to locate the application's canonical filename.
- *
- * @note If you want to use BinReloc for a library, then you should call
- * br_init_lib() instead.
- *
- * @param error If BinReloc failed to initialize, then the error code will
- * be stored in this variable. Set to NULL if you want to
- * ignore this. See #BrInitError for a list of error codes.
- *
- * @returns 1 on success, 0 if BinReloc failed to initialize.
- */
-int
-br_init (BrInitError *error)
-{
- exe = _br_find_exe (error);
- return exe != NULL;
-}
-
-
-/** Initialize the BinReloc library (for libraries).
- *
- * This function must be called before using any other BinReloc functions.
- * It attempts to locate the calling library's canonical filename.
- *
- * @note The BinReloc source code MUST be included in your library, or this
- * function won't work correctly.
- *
- * @param error If BinReloc failed to initialize, then the error code will
- * be stored in this variable. Set to NULL if you want to
- * ignore this. See #BrInitError for a list of error codes.
- *
- * @returns 1 on success, 0 if a filename cannot be found.
- */
-int
-br_init_lib (BrInitError *error)
-{
- exe = _br_find_exe_for_symbol ((const void *) "", error);
- return exe != NULL;
-}
-
-
-/** Find the canonical filename of the current application.
- *
- * @param default_exe A default filename which will be used as fallback.
- * @returns A string containing the application's canonical filename,
- * which must be freed when no longer necessary. If BinReloc is
- * not initialized, or if br_init() failed, then a copy of
- * default_exe will be returned. If default_exe is NULL, then
- * NULL will be returned.
- */
-char *
-br_find_exe (const char *default_exe)
-{
- if (exe == (char *) NULL) {
- /* BinReloc is not initialized. */
- if (default_exe != (const char *) NULL)
- return strdup (default_exe);
- else
- return (char *) NULL;
- }
- return strdup (exe);
-}
-
-
-/** Locate the directory in which the current application is installed.
- *
- * The prefix is generated by the following pseudo-code evaluation:
- * \code
- * dirname(exename)
- * \endcode
- *
- * @param default_dir A default directory which will used as fallback.
- * @return A string containing the directory, which must be freed when no
- * longer necessary. If BinReloc is not initialized, or if the
- * initialization function failed, then a copy of default_dir
- * will be returned. If default_dir is NULL, then NULL will be
- * returned.
- */
-char *
-br_find_exe_dir (const char *default_dir)
-{
- if (exe == NULL) {
- /* BinReloc not initialized. */
- if (default_dir != NULL)
- return strdup (default_dir);
- else
- return NULL;
- }
-
- return br_dirname (exe);
-}
-
-
-/** Locate the prefix in which the current application is installed.
- *
- * The prefix is generated by the following pseudo-code evaluation:
- * \code
- * dirname(dirname(exename))
- * \endcode
- *
- * @param default_prefix A default prefix which will used as fallback.
- * @return A string containing the prefix, which must be freed when no
- * longer necessary. If BinReloc is not initialized, or if
- * the initialization function failed, then a copy of default_prefix
- * will be returned. If default_prefix is NULL, then NULL will be returned.
- */
-char *
-br_find_prefix (const char *default_prefix)
-{
- char *dir1, *dir2;
-
- if (exe == (char *) NULL) {
- /* BinReloc not initialized. */
- if (default_prefix != (const char *) NULL)
- return strdup (default_prefix);
- else
- return (char *) NULL;
- }
-
- dir1 = br_dirname (exe);
- dir2 = br_dirname (dir1);
- free (dir1);
- return dir2;
-}
-
-
-/** Locate the application's binary folder.
- *
- * The path is generated by the following pseudo-code evaluation:
- * \code
- * prefix + "/bin"
- * \endcode
- *
- * @param default_bin_dir A default path which will used as fallback.
- * @return A string containing the bin folder's path, which must be freed when
- * no longer necessary. If BinReloc is not initialized, or if
- * the initialization function failed, then a copy of default_bin_dir will
- * be returned. If default_bin_dir is NULL, then NULL will be returned.
- */
-char *
-br_find_bin_dir (const char *default_bin_dir)
-{
- char *prefix, *dir;
-
- prefix = br_find_prefix ((const char *) NULL);
- if (prefix == (char *) NULL) {
- /* BinReloc not initialized. */
- if (default_bin_dir != (const char *) NULL)
- return strdup (default_bin_dir);
- else
- return (char *) NULL;
- }
-
- dir = br_build_path (prefix, "bin");
- free (prefix);
- return dir;
-}
-
-
-/** Locate the application's superuser binary folder.
- *
- * The path is generated by the following pseudo-code evaluation:
- * \code
- * prefix + "/sbin"
- * \endcode
- *
- * @param default_sbin_dir A default path which will used as fallback.
- * @return A string containing the sbin folder's path, which must be freed when
- * no longer necessary. If BinReloc is not initialized, or if the
- * initialization function failed, then a copy of default_sbin_dir will
- * be returned. If default_bin_dir is NULL, then NULL will be returned.
- */
-char *
-br_find_sbin_dir (const char *default_sbin_dir)
-{
- char *prefix, *dir;
-
- prefix = br_find_prefix ((const char *) NULL);
- if (prefix == (char *) NULL) {
- /* BinReloc not initialized. */
- if (default_sbin_dir != (const char *) NULL)
- return strdup (default_sbin_dir);
- else
- return (char *) NULL;
- }
-
- dir = br_build_path (prefix, "sbin");
- free (prefix);
- return dir;
-}
-
-
-/** Locate the application's data folder.
- *
- * The path is generated by the following pseudo-code evaluation:
- * \code
- * prefix + "/share"
- * \endcode
- *
- * @param default_data_dir A default path which will used as fallback.
- * @return A string containing the data folder's path, which must be freed when
- * no longer necessary. If BinReloc is not initialized, or if the
- * initialization function failed, then a copy of default_data_dir
- * will be returned. If default_data_dir is NULL, then NULL will be
- * returned.
- */
-char *
-br_find_data_dir (const char *default_data_dir)
-{
- char *prefix, *dir;
-
- prefix = br_find_prefix ((const char *) NULL);
- if (prefix == (char *) NULL) {
- /* BinReloc not initialized. */
- if (default_data_dir != (const char *) NULL)
- return strdup (default_data_dir);
- else
- return (char *) NULL;
- }
-
- dir = br_build_path (prefix, "share");
- free (prefix);
- return dir;
-}
-
-
-/** Locate the application's localization folder.
- *
- * The path is generated by the following pseudo-code evaluation:
- * \code
- * prefix + "/share/locale"
- * \endcode
- *
- * @param default_locale_dir A default path which will used as fallback.
- * @return A string containing the localization folder's path, which must be freed when
- * no longer necessary. If BinReloc is not initialized, or if the
- * initialization function failed, then a copy of default_locale_dir will be returned.
- * If default_locale_dir is NULL, then NULL will be returned.
- */
-char *
-br_find_locale_dir (const char *default_locale_dir)
-{
- char *data_dir, *dir;
-
- data_dir = br_find_data_dir ((const char *) NULL);
- if (data_dir == (char *) NULL) {
- /* BinReloc not initialized. */
- if (default_locale_dir != (const char *) NULL)
- return strdup (default_locale_dir);
- else
- return (char *) NULL;
- }
-
- dir = br_build_path (data_dir, "locale");
- free (data_dir);
- return dir;
-}
-
-
-/** Locate the application's library folder.
- *
- * The path is generated by the following pseudo-code evaluation:
- * \code
- * prefix + "/lib"
- * \endcode
- *
- * @param default_lib_dir A default path which will used as fallback.
- * @return A string containing the library folder's path, which must be freed when
- * no longer necessary. If BinReloc is not initialized, or if the initialization
- * function failed, then a copy of default_lib_dir will be returned.
- * If default_lib_dir is NULL, then NULL will be returned.
- */
-char *
-br_find_lib_dir (const char *default_lib_dir)
-{
- char *prefix, *dir;
-
- prefix = br_find_prefix ((const char *) NULL);
- if (prefix == (char *) NULL) {
- /* BinReloc not initialized. */
- if (default_lib_dir != (const char *) NULL)
- return strdup (default_lib_dir);
- else
- return (char *) NULL;
- }
-
- dir = br_build_path (prefix, "lib");
- free (prefix);
- return dir;
-}
-
-
-/** Locate the application's libexec folder.
- *
- * The path is generated by the following pseudo-code evaluation:
- * \code
- * prefix + "/libexec"
- * \endcode
- *
- * @param default_libexec_dir A default path which will used as fallback.
- * @return A string containing the libexec folder's path, which must be freed when
- * no longer necessary. If BinReloc is not initialized, or if the initialization
- * function failed, then a copy of default_libexec_dir will be returned.
- * If default_libexec_dir is NULL, then NULL will be returned.
- */
-char *
-br_find_libexec_dir (const char *default_libexec_dir)
-{
- char *prefix, *dir;
-
- prefix = br_find_prefix ((const char *) NULL);
- if (prefix == (char *) NULL) {
- /* BinReloc not initialized. */
- if (default_libexec_dir != (const char *) NULL)
- return strdup (default_libexec_dir);
- else
- return (char *) NULL;
- }
-
- dir = br_build_path (prefix, "libexec");
- free (prefix);
- return dir;
-}
-
-
-/** Locate the application's configuration files folder.
- *
- * The path is generated by the following pseudo-code evaluation:
- * \code
- * prefix + "/etc"
- * \endcode
- *
- * @param default_etc_dir A default path which will used as fallback.
- * @return A string containing the etc folder's path, which must be freed when
- * no longer necessary. If BinReloc is not initialized, or if the initialization
- * function failed, then a copy of default_etc_dir will be returned.
- * If default_etc_dir is NULL, then NULL will be returned.
- */
-char *
-br_find_etc_dir (const char *default_etc_dir)
-{
- char *prefix, *dir;
-
- prefix = br_find_prefix ((const char *) NULL);
- if (prefix == (char *) NULL) {
- /* BinReloc not initialized. */
- if (default_etc_dir != (const char *) NULL)
- return strdup (default_etc_dir);
- else
- return (char *) NULL;
- }
-
- dir = br_build_path (prefix, "etc");
- free (prefix);
- return dir;
-}
-
-
-/***********************
- * Utility functions
- ***********************/
-
-/** Concatenate str1 and str2 to a newly allocated string.
- *
- * @param str1 A string.
- * @param str2 Another string.
- * @returns A newly-allocated string. This string should be freed when no longer needed.
- */
-char *
-br_strcat (const char *str1, const char *str2)
-{
- char *result;
- size_t len1, len2;
-
- if (str1 == NULL)
- str1 = "";
- if (str2 == NULL)
- str2 = "";
-
- len1 = strlen (str1);
- len2 = strlen (str2);
-
- result = (char *) malloc (len1 + len2 + 1);
- memcpy (result, str1, len1);
- memcpy (result + len1, str2, len2);
- result[len1 + len2] = '\0';
-
- return result;
-}
-
-
-char *
-br_build_path (const char *dir, const char *file)
-{
- char *dir2, *result;
- size_t len;
- int must_free = 0;
-
- len = strlen (dir);
- if (len > 0 && dir[len - 1] != '/') {
- dir2 = br_strcat (dir, "/");
- must_free = 1;
- } else
- dir2 = (char *) dir;
-
- result = br_strcat (dir2, file);
- if (must_free)
- free (dir2);
- return result;
-}
-
-
-/* Emulates glibc's strndup() */
-static char *
-br_strndup (const char *str, size_t size)
-{
- char *result = (char *) NULL;
- size_t len;
-
- if (str == (const char *) NULL)
- return (char *) NULL;
-
- len = strlen (str);
- if (len == 0)
- return strdup ("");
- if (size > len)
- size = len;
-
- result = (char *) malloc (len + 1);
- memcpy (result, str, size);
- result[size] = '\0';
- return result;
-}
-
-
-/** Extracts the directory component of a path.
- *
- * Similar to g_dirname() or the dirname commandline application.
- *
- * Example:
- * \code
- * br_dirname ("/usr/local/foobar"); --> Returns: "/usr/local"
- * \endcode
- *
- * @param path A path.
- * @returns A directory name. This string should be freed when no longer needed.
- */
-char *
-br_dirname (const char *path)
-{
- char *end, *result;
-
- if (path == (const char *) NULL)
- return (char *) NULL;
-
- end = strrchr (path, '/');
- if (end == (const char *) NULL)
- return strdup (".");
-
- while (end > path && *end == '/')
- end--;
- result = br_strndup (path, end - path + 1);
- if (result[0] == 0) {
- free (result);
- return strdup ("/");
- } else
- return result;
-}
-
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-#endif /* __BINRELOC_C__ */
+++ /dev/null
-/*
- * BinReloc - a library for creating relocatable executables
- * Written by: Hongli Lai <h.lai@chello.nl>
- * http://autopackage.org/
- *
- * This source code is public domain. You can relicense this code
- * under whatever license you want.
- *
- * See http://autopackage.org/docs/binreloc/ for
- * more information and how to use this.
- */
-
-#ifndef __BINRELOC_H__
-#define __BINRELOC_H__
-
-#ifdef __cplusplus
-extern "C" {
-#endif /* __cplusplus */
-
-
-/** These error codes can be returned by br_init(), br_init_lib(), gbr_init() or gbr_init_lib(). */
-typedef enum {
- /** Cannot allocate memory. */
- BR_INIT_ERROR_NOMEM,
- /** Unable to open /proc/self/maps; see errno for details. */
- BR_INIT_ERROR_OPEN_MAPS,
- /** Unable to read from /proc/self/maps; see errno for details. */
- BR_INIT_ERROR_READ_MAPS,
- /** The file format of /proc/self/maps is invalid; kernel bug? */
- BR_INIT_ERROR_INVALID_MAPS,
- /** BinReloc is disabled (the ENABLE_BINRELOC macro is not defined). */
- BR_INIT_ERROR_DISABLED
-} BrInitError;
-
-
-#ifndef BINRELOC_RUNNING_DOXYGEN
-/* Mangle symbol names to avoid symbol collisions with other ELF objects. */
- #define br_init PTeH3518859728963_br_init
- #define br_init_lib PTeH3518859728963_br_init_lib
- #define br_find_exe PTeH3518859728963_br_find_exe
- #define br_find_exe_dir PTeH3518859728963_br_find_exe_dir
- #define br_find_prefix PTeH3518859728963_br_find_prefix
- #define br_find_bin_dir PTeH3518859728963_br_find_bin_dir
- #define br_find_sbin_dir PTeH3518859728963_br_find_sbin_dir
- #define br_find_data_dir PTeH3518859728963_br_find_data_dir
- #define br_find_locale_dir PTeH3518859728963_br_find_locale_dir
- #define br_find_lib_dir PTeH3518859728963_br_find_lib_dir
- #define br_find_libexec_dir PTeH3518859728963_br_find_libexec_dir
- #define br_find_etc_dir PTeH3518859728963_br_find_etc_dir
- #define br_strcat PTeH3518859728963_br_strcat
- #define br_build_path PTeH3518859728963_br_build_path
- #define br_dirname PTeH3518859728963_br_dirname
-
-
-#endif
-int br_init (BrInitError *error);
-int br_init_lib (BrInitError *error);
-
-char *br_find_exe (const char *default_exe);
-char *br_find_exe_dir (const char *default_dir);
-char *br_find_prefix (const char *default_prefix);
-char *br_find_bin_dir (const char *default_bin_dir);
-char *br_find_sbin_dir (const char *default_sbin_dir);
-char *br_find_data_dir (const char *default_data_dir);
-char *br_find_locale_dir (const char *default_locale_dir);
-char *br_find_lib_dir (const char *default_lib_dir);
-char *br_find_libexec_dir (const char *default_libexec_dir);
-char *br_find_etc_dir (const char *default_etc_dir);
-
-/* Utility functions */
-char *br_strcat (const char *str1, const char *str2);
-char *br_build_path (const char *dir, const char *file);
-char *br_dirname (const char *path);
-
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-#endif /* __BINRELOC_H__ */
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#include <config.h>
-
-#include "collision.hpp"
-
-#include <algorithm>
-#include <iostream>
-#include <stdio.h>
-#include <float.h>
-#include <math.h>
-#include "math/vector.hpp"
-#include "math/aatriangle.hpp"
-#include "math/rect.hpp"
-#include "collision_hit.hpp"
-#include "log.hpp"
-
-namespace collision
-{
-
-bool intersects(const Rect& r1, const Rect& r2)
-{
- if(r1.p2.x < r2.p1.x || r1.p1.x > r2.p2.x)
- return false;
- if(r1.p2.y < r2.p1.y || r1.p1.y > r2.p2.y)
- return false;
-
- return true;
-}
-
-//---------------------------------------------------------------------------
-
-namespace {
- inline void makePlane(const Vector& p1, const Vector& p2, Vector& n, float& c)
- {
- n = Vector(p2.y-p1.y, p1.x-p2.x);
- c = -(p2 * n);
- float nval = n.norm();
- n /= nval;
- c /= nval;
- }
-
- static const float DELTA = .0001f;
-}
-
-bool rectangle_aatriangle(Constraints* constraints, const Rect& rect,
- const AATriangle& triangle)
-{
- if(!intersects(rect, (const Rect&) triangle))
- return false;
-
- Vector normal;
- float c;
- Vector p1;
- Rect area;
- switch(triangle.dir & AATriangle::DEFORM_MASK) {
- case 0:
- area.p1 = triangle.p1;
- area.p2 = triangle.p2;
- break;
- case AATriangle::DEFORM1:
- area.p1 = Vector(triangle.p1.x, triangle.p1.y + triangle.get_height()/2);
- area.p2 = triangle.p2;
- break;
- case AATriangle::DEFORM2:
- area.p1 = triangle.p1;
- area.p2 = Vector(triangle.p2.x, triangle.p1.y + triangle.get_height()/2);
- break;
- case AATriangle::DEFORM3:
- area.p1 = triangle.p1;
- area.p2 = Vector(triangle.p1.x + triangle.get_width()/2, triangle.p2.y);
- break;
- case AATriangle::DEFORM4:
- area.p1 = Vector(triangle.p1.x + triangle.get_width()/2, triangle.p1.y);
- area.p2 = triangle.p2;
- break;
- default:
- assert(false);
- }
-
- switch(triangle.dir & AATriangle::DIRECTION_MASK) {
- case AATriangle::SOUTHWEST:
- p1 = Vector(rect.p1.x, rect.p2.y);
- makePlane(area.p1, area.p2, normal, c);
- break;
- case AATriangle::NORTHEAST:
- p1 = Vector(rect.p2.x, rect.p1.y);
- makePlane(area.p2, area.p1, normal, c);
- break;
- case AATriangle::SOUTHEAST:
- p1 = rect.p2;
- makePlane(Vector(area.p1.x, area.p2.y),
- Vector(area.p2.x, area.p1.y), normal, c);
- break;
- case AATriangle::NORTHWEST:
- p1 = rect.p1;
- makePlane(Vector(area.p2.x, area.p1.y),
- Vector(area.p1.x, area.p2.y), normal, c);
- break;
- default:
- assert(false);
- }
-
- float n_p1 = -(normal * p1);
- float depth = n_p1 - c;
- if(depth < 0)
- return false;
-
-#if 0
- std::cout << "R: " << rect << " Tri: " << triangle << "\n";
- std::cout << "Norm: " << normal << " Depth: " << depth << "\n";
-#endif
-
- Vector outvec = normal * (depth + 0.2f);
-
- const float RDELTA = 3;
- if(p1.x < area.p1.x - RDELTA || p1.x > area.p2.x + RDELTA
- || p1.y < area.p1.y - RDELTA || p1.y > area.p2.y + RDELTA) {
- set_rectangle_rectangle_constraints(constraints, rect, area);
- constraints->hit.left = false;
- constraints->hit.right = false;
- } else {
- if(outvec.x < 0) {
- constraints->right = rect.get_right() + outvec.x;
- } else {
- constraints->left = rect.get_left() + outvec.x;
- }
-
- if(outvec.y < 0) {
- constraints->bottom = rect.get_bottom() + outvec.y;
- constraints->hit.bottom = true;
- } else {
- constraints->top = rect.get_top() + outvec.y;
- constraints->hit.top = true;
- }
- constraints->hit.slope_normal = normal;
- }
-
- return true;
-}
-
-void set_rectangle_rectangle_constraints(Constraints* constraints,
- const Rect& r1, const Rect& r2)
-{
- float itop = r1.get_bottom() - r2.get_top();
- float ibottom = r2.get_bottom() - r1.get_top();
- float ileft = r1.get_right() - r2.get_left();
- float iright = r2.get_right() - r1.get_left();
-
- float vert_penetration = std::min(itop, ibottom);
- float horiz_penetration = std::min(ileft, iright);
- if(vert_penetration < horiz_penetration) {
- if(itop < ibottom) {
- constraints->bottom = std::min(constraints->bottom, r2.get_top());
- constraints->hit.bottom = true;
- } else {
- constraints->top = std::max(constraints->top, r2.get_bottom());
- constraints->hit.top = true;
- }
- } else {
- if(ileft < iright) {
- constraints->right = std::min(constraints->right, r2.get_left());
- constraints->hit.right = true;
- } else {
- constraints->left = std::max(constraints->left, r2.get_right());
- constraints->hit.left = true;
- }
- }
-}
-
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#ifndef __COLLISION_H__
-#define __COLLISION_H__
-
-#include <float.h>
-#include "collision_hit.hpp"
-#include <limits>
-
-class Vector;
-class Rect;
-class AATriangle;
-
-namespace collision
-{
-
-class Constraints
-{
-public:
- Constraints() {
- float infinity = (std::numeric_limits<float>::has_infinity ? std::numeric_limits<float>::infinity() : std::numeric_limits<float>::max());
- left = -infinity;
- right = infinity;
- top = -infinity;
- bottom = infinity;
- }
-
- bool has_constraints() const {
- float infinity = (std::numeric_limits<float>::has_infinity ? std::numeric_limits<float>::infinity() : std::numeric_limits<float>::max());
- return left > -infinity || right < infinity
- || top > -infinity || bottom < infinity;
- }
-
- float left;
- float right;
- float top;
- float bottom;
- Vector ground_movement;
- CollisionHit hit;
-};
-
-/** checks if 2 rectangle intersect each other */
-bool intersects(const Rect& r1, const Rect& r2);
-
-/** does collision detection between a rectangle and an axis aligned triangle
- * Returns true in case of a collision and fills in the hit structure then.
- */
-bool rectangle_aatriangle(Constraints* constraints, const Rect& rect,
- const AATriangle& triangle);
-
-void set_rectangle_rectangle_constraints(Constraints* constraints,
- const Rect& r1, const Rect& r2);
-
-}
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#ifndef SUPERTUX_COLLISION_HIT_H
-#define SUPERTUX_COLLISION_HIT_H
-
-#include <float.h>
-#include <math.h>
-#include "math/vector.hpp"
-
-/**
- * Used as return value for the collision functions, to indicate how the
- * collision should be handled
- */
-enum HitResponse
-{
- /// don't move the object
- ABORT_MOVE = 0,
- /// move object out of collision and check for collisions again
- /// if this happens to often then the move will just be aborted
- CONTINUE,
- /// do the move ignoring the collision
- FORCE_MOVE,
- /// passes movement to collided object
- PASS_MOVEMENT,
-
- /// the object should not appear solid
- PASSTHROUGH,
- /// the object should appear solid
- SOLID,
-};
-
-/**
- * This class collects data about a collision
- */
-class CollisionHit
-{
-public:
- CollisionHit() {
- left = false;
- right = false;
- top = false;
- bottom = false;
- crush = false;
- }
-
- bool left, right;
- bool top, bottom;
- bool crush;
-
- Vector slope_normal;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux - Console
-// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
-//
-// 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.
-#include <config.h>
-
-#include <iostream>
-#include <math.h>
-#include <SDL_timer.h>
-#include <SDL_keyboard.h>
-#include "console.hpp"
-#include "video/drawing_context.hpp"
-#include "video/surface.hpp"
-#include "scripting/squirrel_error.hpp"
-#include "scripting/squirrel_util.hpp"
-#include "physfs/physfs_stream.hpp"
-#include "player_status.hpp"
-#include "main.hpp"
-#include "log.hpp"
-#include "resources.hpp"
-#include "gameconfig.hpp"
-
-/// speed (pixels/s) the console closes
-static const float FADE_SPEED = 1;
-
-Console::Console()
- : history_position(history.end()), vm(NULL), backgroundOffset(0),
- height(0), alpha(1.0), offset(0), focused(false), stayOpen(0) {
- fontheight = 8;
-}
-
-Console::~Console()
-{
- if(vm != NULL) {
- sq_release(Scripting::global_vm, &vm_object);
- }
-}
-
-void
-Console::init_graphics()
-{
- font.reset(new Font(Font::FIXED,
- "images/engine/fonts/andale12.png",
- "images/engine/fonts/andale12-shadow.png", 7, 14, 1));
- fontheight = font->get_height();
- background.reset(new Surface("images/engine/console.png"));
- background2.reset(new Surface("images/engine/console2.png"));
-}
-
-void
-Console::flush(ConsoleStreamBuffer* buffer)
-{
- if (buffer == &outputBuffer) {
- std::string s = outputBuffer.str();
- if ((s.length() > 0) && ((s[s.length()-1] == '\n') || (s[s.length()-1] == '\r'))) {
- while ((s[s.length()-1] == '\n') || (s[s.length()-1] == '\r')) s.erase(s.length()-1);
- addLines(s);
- outputBuffer.str(std::string());
- }
- }
-}
-
-void
-Console::ready_vm()
-{
- if(vm == NULL) {
- vm = Scripting::global_vm;
- HSQUIRRELVM new_vm = sq_newthread(vm, 16);
- if(new_vm == NULL)
- throw Scripting::SquirrelError(vm, "Couldn't create new VM thread for console");
-
- // store reference to thread
- sq_resetobject(&vm_object);
- if(SQ_FAILED(sq_getstackobj(vm, -1, &vm_object)))
- throw Scripting::SquirrelError(vm, "Couldn't get vm object for console");
- sq_addref(vm, &vm_object);
- sq_pop(vm, 1);
-
- // create new roottable for thread
- sq_newtable(new_vm);
- sq_pushroottable(new_vm);
- if(SQ_FAILED(sq_setdelegate(new_vm, -2)))
- throw Scripting::SquirrelError(new_vm, "Couldn't set console_table delegate");
-
- sq_setroottable(new_vm);
-
- vm = new_vm;
-
- try {
- std::string filename = "scripts/console.nut";
- IFileStream stream(filename);
- Scripting::compile_and_run(vm, stream, filename);
- } catch(std::exception& e) {
- log_warning << "Couldn't load console.nut: " << e.what() << std::endl;
- }
- }
-}
-
-void
-Console::execute_script(const std::string& command)
-{
- using namespace Scripting;
-
- ready_vm();
-
- SQInteger oldtop = sq_gettop(vm);
- try {
- if(SQ_FAILED(sq_compilebuffer(vm, command.c_str(), command.length(),
- "", SQTrue)))
- throw SquirrelError(vm, "Couldn't compile command");
-
- sq_pushroottable(vm);
- if(SQ_FAILED(sq_call(vm, 1, SQTrue, SQTrue)))
- throw SquirrelError(vm, "Problem while executing command");
-
- if(sq_gettype(vm, -1) != OT_NULL)
- addLines(squirrel2string(vm, -1));
- } catch(std::exception& e) {
- addLines(e.what());
- }
- SQInteger newtop = sq_gettop(vm);
- if(newtop < oldtop) {
- log_fatal << "Script destroyed squirrel stack..." << std::endl;
- } else {
- sq_settop(vm, oldtop);
- }
-}
-
-void
-Console::input(char c)
-{
- inputBuffer.insert(inputBufferPosition, 1, c);
- inputBufferPosition++;
-}
-
-void
-Console::backspace()
-{
- if ((inputBufferPosition > 0) && (inputBuffer.length() > 0)) {
- inputBuffer.erase(inputBufferPosition-1, 1);
- inputBufferPosition--;
- }
-}
-
-void
-Console::eraseChar()
-{
- if (inputBufferPosition < (int)inputBuffer.length()) {
- inputBuffer.erase(inputBufferPosition, 1);
- }
-}
-
-void
-Console::enter()
-{
- addLines("> "+inputBuffer);
- parse(inputBuffer);
- inputBuffer = "";
- inputBufferPosition = 0;
-}
-
-void
-Console::scroll(int numLines)
-{
- offset += numLines;
- if (offset > 0) offset = 0;
-}
-
-void
-Console::show_history(int offset)
-{
- while ((offset > 0) && (history_position != history.end())) {
- history_position++;
- offset--;
- }
- while ((offset < 0) && (history_position != history.begin())) {
- history_position--;
- offset++;
- }
- if (history_position == history.end()) {
- inputBuffer = "";
- inputBufferPosition = 0;
- } else {
- inputBuffer = *history_position;
- inputBufferPosition = inputBuffer.length();
- }
-}
-
-void
-Console::move_cursor(int offset)
-{
- if (offset == -65535) inputBufferPosition = 0;
- if (offset == +65535) inputBufferPosition = inputBuffer.length();
- inputBufferPosition+=offset;
- if (inputBufferPosition < 0) inputBufferPosition = 0;
- if (inputBufferPosition > (int)inputBuffer.length()) inputBufferPosition = inputBuffer.length();
-}
-
-// Helper functions for Console::autocomplete
-// TODO: Fix rough documentation
-namespace {
-
-void sq_insert_commands(std::list<std::string>& cmds, HSQUIRRELVM vm, std::string table_prefix, std::string search_prefix);
-
-/**
- * Acts upon key,value on top of stack:
- * Appends key (plus type-dependent suffix) to cmds if table_prefix+key starts with search_prefix;
- * Calls sq_insert_commands if search_prefix starts with table_prefix+key (and value is a table/class/instance);
- */
-void
-sq_insert_command(std::list<std::string>& cmds, HSQUIRRELVM vm, std::string table_prefix, std::string search_prefix)
-{
- const SQChar* key_chars;
- if (SQ_FAILED(sq_getstring(vm, -2, &key_chars))) return;
- std::string key_string = table_prefix + key_chars;
-
- switch (sq_gettype(vm, -1)) {
- case OT_INSTANCE:
- key_string+=".";
- if (search_prefix.substr(0, key_string.length()) == key_string) {
- sq_getclass(vm, -1);
- sq_insert_commands(cmds, vm, key_string, search_prefix);
- sq_pop(vm, 1);
- }
- break;
- case OT_TABLE:
- case OT_CLASS:
- key_string+=".";
- if (search_prefix.substr(0, key_string.length()) == key_string) {
- sq_insert_commands(cmds, vm, key_string, search_prefix);
- }
- break;
- case OT_CLOSURE:
- case OT_NATIVECLOSURE:
- key_string+="()";
- break;
- default:
- break;
- }
-
- if (key_string.substr(0, search_prefix.length()) == search_prefix) {
- cmds.push_back(key_string);
- }
-
-}
-
-/**
- * calls sq_insert_command for all entries of table/class on top of stack
- */
-void
-sq_insert_commands(std::list<std::string>& cmds, HSQUIRRELVM vm, std::string table_prefix, std::string search_prefix)
-{
- sq_pushnull(vm); // push iterator
- while (SQ_SUCCEEDED(sq_next(vm,-2))) {
- sq_insert_command(cmds, vm, table_prefix, search_prefix);
- sq_pop(vm, 2); // pop key, val
- }
- sq_pop(vm, 1); // pop iterator
-}
-
-
-}
-// End of Console::autocomplete helper functions
-
-void
-Console::autocomplete()
-{
- //int autocompleteFrom = inputBuffer.find_last_of(" ();+", inputBufferPosition);
- int autocompleteFrom = inputBuffer.find_last_not_of("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_->.", inputBufferPosition);
- if (autocompleteFrom != (int)std::string::npos) {
- autocompleteFrom += 1;
- } else {
- autocompleteFrom = 0;
- }
- std::string prefix = inputBuffer.substr(autocompleteFrom, inputBufferPosition - autocompleteFrom);
- addLines("> "+prefix);
-
- std::list<std::string> cmds;
-
- ready_vm();
-
- // append all keys of the current root table to list
- sq_pushroottable(vm); // push root table
- while(true) {
- // check all keys (and their children) for matches
- sq_insert_commands(cmds, vm, "", prefix);
-
- // cycle through parent(delegate) table
- SQInteger oldtop = sq_gettop(vm);
- if(SQ_FAILED(sq_getdelegate(vm, -1)) || oldtop == sq_gettop(vm)) {
- break;
- }
- sq_remove(vm, -2); // remove old table
- }
- sq_pop(vm, 1); // remove table
-
- // depending on number of hits, show matches or autocomplete
- if (cmds.size() == 0) addLines("No known command starts with \""+prefix+"\"");
- if (cmds.size() == 1) {
- // one match: just replace input buffer with full command
- std::string replaceWith = cmds.front();
- inputBuffer.replace(autocompleteFrom, prefix.length(), replaceWith);
- inputBufferPosition += (replaceWith.length() - prefix.length());
- }
- if (cmds.size() > 1) {
- // multiple matches: show all matches and set input buffer to longest common prefix
- std::string commonPrefix = cmds.front();
- while (cmds.begin() != cmds.end()) {
- std::string cmd = cmds.front();
- cmds.pop_front();
- addLines(cmd);
- for (int n = commonPrefix.length(); n >= 1; n--) {
- if (cmd.compare(0, n, commonPrefix) != 0) commonPrefix.resize(n-1); else break;
- }
- }
- std::string replaceWith = commonPrefix;
- inputBuffer.replace(autocompleteFrom, prefix.length(), replaceWith);
- inputBufferPosition += (replaceWith.length() - prefix.length());
- }
-}
-
-void
-Console::addLines(std::string s)
-{
- std::istringstream iss(s);
- std::string line;
- while (std::getline(iss, line, '\n')) addLine(line);
-}
-
-void
-Console::addLine(std::string s)
-{
- // output line to stderr
- std::cerr << s << std::endl;
-
- // wrap long lines
- std::string overflow;
- unsigned int line_count = 0;
- do {
- lines.push_front(Font::wrap_to_chars(s, 99, &overflow));
- line_count++;
- s = overflow;
- } while (s.length() > 0);
-
- // trim scrollback buffer
- while (lines.size() >= 1000)
- lines.pop_back();
-
- // increase console height if necessary
- if (height < 64) {
- if(height < 4)
- height = 4;
- height += fontheight * line_count;
- }
-
- // reset console to full opacity
- alpha = 1.0;
-
- // increase time that console stays open
- if(stayOpen < 6)
- stayOpen += 1.5;
-}
-
-void
-Console::parse(std::string s)
-{
- // make sure we actually have something to parse
- if (s.length() == 0) return;
-
- // add line to history
- history.push_back(s);
- history_position = history.end();
-
- // split line into list of args
- std::vector<std::string> args;
- size_t start = 0;
- size_t end = 0;
- while (1) {
- start = s.find_first_not_of(" ,", end);
- end = s.find_first_of(" ,", start);
- if (start == s.npos) break;
- args.push_back(s.substr(start, end-start));
- }
-
- // command is args[0]
- if (args.size() == 0) return;
- std::string command = args.front();
- args.erase(args.begin());
-
- // ignore if it's an internal command
- if (consoleCommand(command,args)) return;
-
- try {
- execute_script(s);
- } catch(std::exception& e) {
- addLines(e.what());
- }
-
-}
-
-bool
-Console::consoleCommand(std::string /*command*/, std::vector<std::string> /*arguments*/)
-{
- return false;
-}
-
-bool
-Console::hasFocus()
-{
- return focused;
-}
-
-void
-Console::show()
-{
- if(!config->console_enabled)
- return;
-
- focused = true;
- height = 256;
- alpha = 1.0;
- SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);
-}
-
-void
-Console::hide()
-{
- focused = false;
- height = 0;
- stayOpen = 0;
-
- // clear input buffer
- inputBuffer = "";
- inputBufferPosition = 0;
- SDL_EnableKeyRepeat(0, SDL_DEFAULT_REPEAT_INTERVAL);
-}
-
-void
-Console::toggle()
-{
- if (Console::hasFocus()) {
- Console::hide();
- }
- else {
- Console::show();
- }
-}
-
-void
-Console::update(float elapsed_time)
-{
- if(stayOpen > 0) {
- stayOpen -= elapsed_time;
- if(stayOpen < 0)
- stayOpen = 0;
- } else if(!focused && height > 0) {
- alpha -= elapsed_time * FADE_SPEED;
- if(alpha < 0) {
- alpha = 0;
- height = 0;
- }
- }
-}
-
-void
-Console::draw(DrawingContext& context)
-{
- if (height == 0)
- return;
-
- int layer = LAYER_GUI + 1;
-
- context.push_transform();
- context.set_alpha(alpha);
- context.draw_surface(background2.get(), Vector(SCREEN_WIDTH/2 - background->get_width()/2 - background->get_width() + backgroundOffset, height - background->get_height()), layer);
- context.draw_surface(background2.get(), Vector(SCREEN_WIDTH/2 - background->get_width()/2 + backgroundOffset, height - background->get_height()), layer);
- for (int x = (SCREEN_WIDTH/2 - background->get_width()/2 - (static_cast<int>(ceilf((float)SCREEN_WIDTH / (float)background->get_width()) - 1) * background->get_width())); x < SCREEN_WIDTH; x+=background->get_width()) {
- context.draw_surface(background.get(), Vector(x, height - background->get_height()), layer);
- }
- backgroundOffset+=10;
- if (backgroundOffset > (int)background->get_width()) backgroundOffset -= (int)background->get_width();
-
- int lineNo = 0;
-
- if (focused) {
- lineNo++;
- float py = height-4-1 * font->get_height();
- context.draw_text(font.get(), "> "+inputBuffer, Vector(4, py), ALIGN_LEFT, layer);
- if (SDL_GetTicks() % 1000 < 750) {
- int cursor_px = 2 + inputBufferPosition;
- context.draw_text(font.get(), "_", Vector(4 + (cursor_px * font->get_text_width("X")), py), ALIGN_LEFT, layer);
- }
- }
-
- int skipLines = -offset;
- for (std::list<std::string>::iterator i = lines.begin(); i != lines.end(); i++) {
- if (skipLines-- > 0) continue;
- lineNo++;
- float py = height - 4 - lineNo*font->get_height();
- if (py < -font->get_height()) break;
- context.draw_text(font.get(), *i, Vector(4, py), ALIGN_LEFT, layer);
- }
- context.pop_transform();
-}
-
-Console* Console::instance = NULL;
-int Console::inputBufferPosition = 0;
-std::string Console::inputBuffer;
-ConsoleStreamBuffer Console::outputBuffer;
-std::ostream Console::output(&Console::outputBuffer);
-
+++ /dev/null
-// $Id$
-//
-// SuperTux - Console
-// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
-//
-// 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.
-
-#ifndef SUPERTUX_CONSOLE_H
-#define SUPERTUX_CONSOLE_H
-
-#include <list>
-#include <map>
-#include <vector>
-#include <string>
-#include <sstream>
-#include <iostream>
-#include <squirrel.h>
-
-class Console;
-class ConsoleStreamBuffer;
-class ConsoleCommandReceiver;
-class DrawingContext;
-class Surface;
-class Font;
-
-class Console
-{
-public:
- Console();
- ~Console();
-
- static Console* instance;
-
- static std::ostream output; /**< stream of characters to output to the console. Do not forget to send std::endl or to flush the stream. */
-
- void init_graphics();
-
- void input(char c); /**< add character to inputBuffer */
- void backspace(); /**< delete character left of inputBufferPosition */
- void eraseChar(); /**< delete character at inputBufferPosition */
- void enter(); /**< process and clear input stream */
- void scroll(int offset); /**< scroll console text up or down by @c offset lines */
- void autocomplete(); /**< autocomplete current command */
- void show_history(int offset); /**< move @c offset lines forward through history; Negative offset moves backward */
- void move_cursor(int offset); /**< move the cursor @c offset chars to the right; Negative offset moves backward; 0xFFFF moves to the end */
-
- void draw(DrawingContext& context); /**< draw the console in a DrawingContext */
- void update(float elapsed_time);
-
- void show(); /**< display the console */
- void hide(); /**< hide the console */
- void toggle(); /**< display the console if hidden, hide otherwise */
-
- bool hasFocus(); /**< true if characters should be sent to the console instead of their normal target */
-
- template<typename T> static bool string_is(std::string s) {
- std::istringstream iss(s);
- T i;
- if ((iss >> i) && iss.eof()) {
- return true;
- } else {
- return false;
- }
- }
-
- template<typename T> static T string_to(std::string s) {
- std::istringstream iss(s);
- T i;
- if ((iss >> i) && iss.eof()) {
- return i;
- } else {
- return T();
- }
- }
-
-private:
- std::list<std::string> history; /**< command history. New lines get added to back. */
- std::list<std::string>::iterator history_position; /**< item of command history that is currently displayed */
- std::list<std::string> lines; /**< backbuffer of lines sent to the console. New lines get added to front. */
-
- std::auto_ptr<Surface> background; /**< console background image */
- std::auto_ptr<Surface> background2; /**< second, moving console background image */
-
- HSQUIRRELVM vm; /**< squirrel thread for the console (with custom roottable) */
- HSQOBJECT vm_object;
-
- int backgroundOffset; /**< current offset of scrolling background image */
- float height; /**< height of the console in px */
- float alpha;
- int offset; /**< decrease to scroll text up */
- bool focused; /**< true if console has input focus */
- std::auto_ptr<Font> font;
- float fontheight; /**< height of the font (this is a separate var, because the font could not be initialized yet but is needed in the addLine message */
-
- float stayOpen;
-
- static int inputBufferPosition; /**< position in inputBuffer before which to append new characters */
- static std::string inputBuffer; /**< string used for keyboard input */
- static ConsoleStreamBuffer outputBuffer; /**< stream buffer used by output stream */
-
- void addLines(std::string s); /**< display a string of (potentially) multiple lines in the console */
- void addLine(std::string s); /**< display a line in the console */
- void parse(std::string s); /**< react to a given command */
-
- /** ready a virtual machine instance, creating a new thread and loading default .nut files if needed */
- void ready_vm();
-
- /** execute squirrel script and output result */
- void execute_script(const std::string& s);
-
- bool consoleCommand(std::string command, std::vector<std::string> arguments); /**< process internal command; return false if command was unknown, true otherwise */
-
- friend class ConsoleStreamBuffer;
- void flush(ConsoleStreamBuffer* buffer); /**< act upon changes in a ConsoleStreamBuffer */
-};
-
-class ConsoleStreamBuffer : public std::stringbuf
-{
- public:
- int sync()
- {
- int result = std::stringbuf::sync();
- if(Console::instance != NULL)
- Console::instance->flush(this);
- return result;
- }
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include "codecontroller.hpp"
-
-CodeController::CodeController()
-{}
-
-CodeController::~CodeController()
-{}
-
-void
-CodeController::press(Control c, bool pressed)
-{
- controls[c] = pressed;
-}
-
-void
-CodeController::update()
-{
- Controller::update();
-
- for(int i = 0; i < CONTROLCOUNT; ++i)
- controls[i] = false;
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __CODECONTROLLER_H__
-#define __CODECONTROLLER_H__
-
-#include "controller.hpp"
-
-/**
- * This is a dummy controler that doesn't react to any user input but should
- * be controlled by code
- */
-class CodeController : public Controller
-{
-public:
- CodeController();
- virtual ~CodeController();
-
- void press(Control c, bool pressed = true);
- void update();
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include "controller.hpp"
-
-const char* Controller::controlNames[] = {
- "left",
- "right",
- "up",
- "down",
- "jump",
- "action",
- "pause-menu",
- "menu-select",
- "console",
- "peek-left",
- "peek-right",
- 0
-};
-
-Controller::Controller()
-{
- reset();
-}
-
-Controller::~Controller()
-{}
-
-void
-Controller::reset()
-{
- for(int i = 0; i < CONTROLCOUNT; ++i) {
- controls[i] = false;
- oldControls[i] = false;
- }
-}
-
-bool
-Controller::hold(Control control)
-{
- return controls[control];
-}
-
-bool
-Controller::pressed(Control control)
-{
- return !oldControls[control] && controls[control];
-}
-
-bool
-Controller::released(Control control)
-{
- return oldControls[control] && !controls[control];
-}
-
-void
-Controller::update()
-{
- for(int i = 0; i < CONTROLCOUNT; ++i)
- oldControls[i] = controls[i];
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __CONTROLLER_H__
-#define __CONTROLLER_H__
-
-class Controller
-{
-public:
- static const char* controlNames[];
-
- enum Control {
- LEFT = 0,
- RIGHT,
- UP,
- DOWN,
-
- JUMP,
- ACTION,
-
- PAUSE_MENU,
- MENU_SELECT,
-
- CONSOLE,
-
- PEEK_LEFT,
- PEEK_RIGHT,
-
- CONTROLCOUNT
- };
-
- Controller();
- virtual ~Controller();
-
- /** returns true if the control is pressed down */
- bool hold(Control control);
- /** returns true if the control has just been pressed down this frame */
- bool pressed(Control control);
- /** returns true if the control has just been released this frame */
- bool released(Control control);
-
- virtual void reset();
- virtual void update();
-
-protected:
- /** current control status */
- bool controls[CONTROLCOUNT];
- /** control status at last frame */
- bool oldControls[CONTROLCOUNT];
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>,
-// 2007 Ingo Ruhnke <grumbel@gmx.de>
-//
-// 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.
-
-#include <config.h>
-
-#include <sstream>
-#include "joystickkeyboardcontroller.hpp"
-#include "log.hpp"
-#include "gui/menu.hpp"
-#include "gettext.hpp"
-#include "lisp/lisp.hpp"
-#include "lisp/list_iterator.hpp"
-#include "game_session.hpp"
-#include "console.hpp"
-#include "gameconfig.hpp"
-
-class JoystickKeyboardController::JoystickMenu : public Menu
-{
-public:
- JoystickMenu(JoystickKeyboardController* controller);
- virtual ~JoystickMenu();
-
- void update();
- std::string get_button_name(int button);
- void update_menu_item(Control id);
- virtual void menu_action(MenuItem* item);
- JoystickKeyboardController* controller;
-};
-
-class JoystickKeyboardController::KeyboardMenu : public Menu
-{
-public:
- KeyboardMenu(JoystickKeyboardController* controller);
- ~KeyboardMenu();
-
- void update();
- std::string get_key_name(SDLKey key);
- virtual void menu_action(MenuItem* item);
- JoystickKeyboardController* controller;
-};
-
-JoystickKeyboardController::JoystickKeyboardController()
- : hat_state(0),
- wait_for_key(-1), wait_for_joystick(-1),
- key_options_menu(0), joystick_options_menu(0)
-{
- // initialize default keyboard map
- keymap[SDLK_LEFT] = LEFT;
- keymap[SDLK_RIGHT] = RIGHT;
- keymap[SDLK_UP] = UP;
- keymap[SDLK_DOWN] = DOWN;
- keymap[SDLK_SPACE] = JUMP;
- keymap[SDLK_LCTRL] = ACTION;
- keymap[SDLK_LALT] = ACTION;
- keymap[SDLK_ESCAPE] = PAUSE_MENU;
- keymap[SDLK_p] = PAUSE_MENU;
- keymap[SDLK_PAUSE] = PAUSE_MENU;
- keymap[SDLK_RETURN] = MENU_SELECT;
- keymap[SDLK_KP_ENTER] = MENU_SELECT;
- keymap[SDLK_CARET] = CONSOLE;
- keymap[SDLK_DELETE] = PEEK_LEFT;
- keymap[SDLK_END] = PEEK_RIGHT;
-
- jump_with_up = false;
-
- int joystick_count = SDL_NumJoysticks();
- min_joybuttons = -1;
- max_joybuttons = -1;
- max_joyaxis = -1;
- max_joyhats = -1;
-
- for(int i = 0; i < joystick_count; ++i) {
- SDL_Joystick* joystick = SDL_JoystickOpen(i);
- bool good = true;
- if(SDL_JoystickNumButtons(joystick) < 2) {
- log_info << "Joystick " << i << " has less than 2 buttons" << std::endl;
- good = false;
- }
- if(SDL_JoystickNumAxes(joystick) < 2
- && SDL_JoystickNumHats(joystick) == 0) {
- log_info << "Joystick " << i << " has less than 2 axes and no hat" << std::endl;
- good = false;
- }
- if(!good) {
- SDL_JoystickClose(joystick);
- continue;
- }
-
- if(min_joybuttons < 0 || SDL_JoystickNumButtons(joystick) < min_joybuttons)
- min_joybuttons = SDL_JoystickNumButtons(joystick);
-
- if(SDL_JoystickNumButtons(joystick) > max_joybuttons)
- max_joybuttons = SDL_JoystickNumButtons(joystick);
-
- if(SDL_JoystickNumAxes(joystick) > max_joyaxis)
- max_joyaxis = SDL_JoystickNumAxes(joystick);
-
- if(SDL_JoystickNumHats(joystick) > max_joyhats)
- max_joyhats = SDL_JoystickNumHats(joystick);
-
- joysticks.push_back(joystick);
- }
-
- dead_zone = 1000;
-
- // Default joystick button configuration
- joy_button_map[0] = JUMP;
- joy_button_map[1] = ACTION;
- // 6 or more Buttons
- if( min_joybuttons > 5 ){
- joy_button_map[4] = PEEK_LEFT;
- joy_button_map[5] = PEEK_RIGHT;
- // 8 or more
- if(min_joybuttons > 7)
- joy_button_map[min_joybuttons-1] = PAUSE_MENU;
- } else {
- // map the last 2 buttons to menu and pause
- if(min_joybuttons > 2)
- joy_button_map[min_joybuttons-1] = PAUSE_MENU;
- // map all remaining joystick buttons to MENU_SELECT
- for(int i = 2; i < max_joybuttons; ++i) {
- if(i != min_joybuttons-1)
- joy_button_map[i] = MENU_SELECT;
- }
- }
-
- // Default joystick axis configuration
- joy_axis_map[-1] = LEFT;
- joy_axis_map[ 1] = RIGHT;
- joy_axis_map[-2] = UP;
- joy_axis_map[ 2] = DOWN;
-
- // some joysticks or SDL seem to produce some bogus events after being opened
- Uint32 ticks = SDL_GetTicks();
- while(SDL_GetTicks() - ticks < 200) {
- SDL_Event event;
- SDL_PollEvent(&event);
- }
-}
-
-JoystickKeyboardController::~JoystickKeyboardController()
-{
- for(std::vector<SDL_Joystick*>::iterator i = joysticks.begin();
- i != joysticks.end(); ++i) {
- if(*i != 0)
- SDL_JoystickClose(*i);
- }
-
- delete key_options_menu;
- delete joystick_options_menu;
-}
-
-void
-JoystickKeyboardController::read(const lisp::Lisp& lisp)
-{
- const lisp::Lisp* keymap_lisp = lisp.get_lisp("keymap");
- if(keymap_lisp) {
- keymap.clear();
- lisp::ListIterator iter(keymap_lisp);
- while(iter.next()) {
- if(iter.item() == "map") {
- int key = -1;
- std::string control;
- const lisp::Lisp* map = iter.lisp();
- map->get("key", key);
- map->get("control", control);
- if(key < SDLK_FIRST || key >= SDLK_LAST) {
- log_info << "Invalid key '" << key << "' in keymap" << std::endl;
- continue;
- }
-
- int i = 0;
- for(i = 0; controlNames[i] != 0; ++i) {
- if(control == controlNames[i])
- break;
- }
- if(controlNames[i] == 0) {
- log_info << "Invalid control '" << control << "' in keymap" << std::endl;
- continue;
- }
- keymap[(SDLKey) key] = (Control)i;
- } else {
- log_info << "Invalid lisp element '" << iter.item() << "' in keymap" << std::endl;
- }
- }
- }
-
- const lisp::Lisp* joystick_lisp = lisp.get_lisp("joystick");
- if(joystick_lisp) {
- joystick_lisp->get("dead-zone", dead_zone);
- joystick_lisp->get("jump-with-up", jump_with_up);
- lisp::ListIterator iter(joystick_lisp);
- while(iter.next()) {
- if(iter.item() == "map") {
- int button = -1;
- int axis = 0;
- int hat = -1;
- std::string control;
- const lisp::Lisp* map = iter.lisp();
-
- map->get("control", control);
- int i = 0;
- for(i = 0; controlNames[i] != 0; ++i) {
- if(control == controlNames[i])
- break;
- }
- if(controlNames[i] == 0) {
- log_info << "Invalid control '" << control << "' in buttonmap" << std::endl;
- continue;
- }
-
- if (map->get("button", button)) {
- if(button < 0 || button >= max_joybuttons) {
- log_info << "Invalid button '" << button << "' in buttonmap" << std::endl;
- continue;
- }
- bind_joybutton(button, (Control) i);
- }
-
- if (map->get("axis", axis)) {
- if (axis == 0 || abs(axis) > max_joyaxis) {
- log_info << "Invalid axis '" << axis << "' in axismap" << std::endl;
- continue;
- }
- bind_joyaxis(axis, (Control) i);
- }
-
- if (map->get("hat", hat)) {
- if (hat != SDL_HAT_UP &&
- hat != SDL_HAT_DOWN &&
- hat != SDL_HAT_LEFT &&
- hat != SDL_HAT_RIGHT) {
- log_info << "Invalid axis '" << axis << "' in axismap" << std::endl;
- continue;
- } else {
- bind_joyhat(hat, (Control) i);
- }
- }
- }
- }
- }
-}
-
-void
-JoystickKeyboardController::write(lisp::Writer& writer)
-{
- writer.start_list("keymap");
- for(KeyMap::iterator i = keymap.begin(); i != keymap.end(); ++i) {
- writer.start_list("map");
- writer.write_int("key", (int) i->first);
- writer.write_string("control", controlNames[i->second]);
- writer.end_list("map");
- }
- writer.end_list("keymap");
-
- writer.start_list("joystick");
- writer.write_int("dead-zone", dead_zone);
- writer.write_bool("jump-with-up", jump_with_up);
-
- for(ButtonMap::iterator i = joy_button_map.begin(); i != joy_button_map.end();
- ++i) {
- writer.start_list("map");
- writer.write_int("button", i->first);
- writer.write_string("control", controlNames[i->second]);
- writer.end_list("map");
- }
-
- for(HatMap::iterator i = joy_hat_map.begin(); i != joy_hat_map.end(); ++i) {
- writer.start_list("map");
- writer.write_int("hat", i->first);
- writer.write_string("control", controlNames[i->second]);
- writer.end_list("map");
- }
-
- for(AxisMap::iterator i = joy_axis_map.begin(); i != joy_axis_map.end(); ++i) {
- writer.start_list("map");
- writer.write_int("axis", i->first);
- writer.write_string("control", controlNames[i->second]);
- writer.end_list("map");
- }
-
- writer.end_list("joystick");
-}
-
-void
-JoystickKeyboardController::reset()
-{
- Controller::reset();
-}
-
-void
-JoystickKeyboardController::set_joy_controls(Control id, bool value)
-{
- if (jump_with_up && id == Controller::UP)
- controls[Controller::JUMP] = value;
-
- controls[(Control)id] = value;
-}
-
-void
-JoystickKeyboardController::process_event(const SDL_Event& event)
-{
- switch(event.type) {
- case SDL_KEYUP:
- case SDL_KEYDOWN:
- process_key_event(event);
- break;
-
- case SDL_JOYAXISMOTION:
- process_axis_event(event.jaxis);
- break;
-
- case SDL_JOYHATMOTION:
- process_hat_event(event.jhat);
- break;
-
- case SDL_JOYBUTTONDOWN:
- case SDL_JOYBUTTONUP:
- process_button_event(event.jbutton);
- break;
-
- default:
- break;
- }
-}
-
-void
-JoystickKeyboardController::process_button_event(const SDL_JoyButtonEvent& jbutton)
-{
- if(wait_for_joystick >= 0)
- {
- if(jbutton.state == SDL_PRESSED)
- {
- bind_joybutton(jbutton.button, (Control)wait_for_joystick);
- joystick_options_menu->update();
- reset();
- wait_for_joystick = -1;
- }
- }
- else
- {
- ButtonMap::iterator i = joy_button_map.find(jbutton.button);
- if(i == joy_button_map.end()) {
- log_debug << "Unmapped joybutton " << (int)jbutton.button << " pressed" << std::endl;
- } else {
- set_joy_controls(i->second, (jbutton.state == SDL_PRESSED));
- }
- }
-}
-
-void
-JoystickKeyboardController::process_axis_event(const SDL_JoyAxisEvent& jaxis)
-{
- if (wait_for_joystick >= 0)
- {
- if (abs(jaxis.value) > dead_zone) {
- if (jaxis.value < 0)
- bind_joyaxis(-(jaxis.axis + 1), Control(wait_for_joystick));
- else
- bind_joyaxis(jaxis.axis + 1, Control(wait_for_joystick));
-
- joystick_options_menu->update();
- wait_for_joystick = -1;
- }
- }
- else
- {
- // Split the axis into left and right, so that both can be
- // mapped seperatly (needed for jump/down vs up/down)
- int axis = jaxis.axis + 1;
-
- AxisMap::iterator left = joy_axis_map.find(-axis);
- AxisMap::iterator right = joy_axis_map.find(axis);
-
- if(left == joy_axis_map.end()) {
- std::cout << "Unmapped joyaxis " << (int)jaxis.axis << " moved" << std::endl;
- } else {
- if (jaxis.value < -dead_zone)
- set_joy_controls(left->second, true);
- else if (jaxis.value > dead_zone)
- set_joy_controls(left->second, false);
- else
- set_joy_controls(left->second, false);
- }
-
- if(right == joy_axis_map.end()) {
- std::cout << "Unmapped joyaxis " << (int)jaxis.axis << " moved" << std::endl;
- } else {
- if (jaxis.value < -dead_zone)
- set_joy_controls(right->second, false);
- else if (jaxis.value > dead_zone)
- set_joy_controls(right->second, true);
- else
- set_joy_controls(right->second, false);
- }
- }
-}
-
-void
-JoystickKeyboardController::process_hat_event(const SDL_JoyHatEvent& jhat)
-{
- Uint8 changed = hat_state ^ jhat.value;
-
- if (wait_for_joystick >= 0)
- {
- if (changed & SDL_HAT_UP && jhat.value & SDL_HAT_UP)
- bind_joyhat(SDL_HAT_UP, (Control)wait_for_joystick);
-
- if (changed & SDL_HAT_DOWN && jhat.value & SDL_HAT_DOWN)
- bind_joyhat(SDL_HAT_DOWN, (Control)wait_for_joystick);
-
- if (changed & SDL_HAT_LEFT && jhat.value & SDL_HAT_LEFT)
- bind_joyhat(SDL_HAT_LEFT, (Control)wait_for_joystick);
-
- if (changed & SDL_HAT_RIGHT && jhat.value & SDL_HAT_RIGHT)
- bind_joyhat(SDL_HAT_RIGHT, (Control)wait_for_joystick);
-
- joystick_options_menu->update();
- wait_for_joystick = -1;
- }
- else
- {
- if (changed & SDL_HAT_UP)
- {
- HatMap::iterator it = joy_hat_map.find(SDL_HAT_UP);
- if (it != joy_hat_map.end())
- set_joy_controls(it->second, jhat.value & SDL_HAT_UP);
- }
-
- if (changed & SDL_HAT_DOWN)
- {
- HatMap::iterator it = joy_hat_map.find(SDL_HAT_DOWN);
- if (it != joy_hat_map.end())
- set_joy_controls(it->second, jhat.value & SDL_HAT_DOWN);
- }
-
- if (changed & SDL_HAT_LEFT)
- {
- HatMap::iterator it = joy_hat_map.find(SDL_HAT_LEFT);
- if (it != joy_hat_map.end())
- set_joy_controls(it->second, jhat.value & SDL_HAT_LEFT);
- }
-
- if (changed & SDL_HAT_RIGHT)
- {
- HatMap::iterator it = joy_hat_map.find(SDL_HAT_RIGHT);
- if (it != joy_hat_map.end())
- set_joy_controls(it->second, jhat.value & SDL_HAT_RIGHT);
- }
- }
-
- hat_state = jhat.value;
-}
-
-void
-JoystickKeyboardController::process_key_event(const SDL_Event& event)
-{
- KeyMap::iterator key_mapping = keymap.find(event.key.keysym.sym);
-
- // if console key was pressed: toggle console
- if ((key_mapping != keymap.end()) && (key_mapping->second == CONSOLE)) {
- if (event.type == SDL_KEYDOWN)
- Console::instance->toggle();
- } else {
- if (Console::instance->hasFocus()) {
- // if console is open: send key there
- process_console_key_event(event);
- } else if (Menu::current()) {
- // if menu mode: send key there
- process_menu_key_event(event);
- } else if(key_mapping == keymap.end()) {
- // default action: update controls
- log_debug << "Key " << event.key.keysym.sym << " is unbound" << std::endl;
- } else {
- Control control = key_mapping->second;
- controls[control] = (event.type == SDL_KEYDOWN);
- }
- }
-}
-
-void
-JoystickKeyboardController::process_console_key_event(const SDL_Event& event)
-{
- if (event.type != SDL_KEYDOWN) return;
-
- switch (event.key.keysym.sym) {
- case SDLK_RETURN:
- Console::instance->enter();
- break;
- case SDLK_BACKSPACE:
- Console::instance->backspace();
- break;
- case SDLK_TAB:
- Console::instance->autocomplete();
- break;
- case SDLK_PAGEUP:
- Console::instance->scroll(-1);
- break;
- case SDLK_PAGEDOWN:
- Console::instance->scroll(+1);
- break;
- case SDLK_HOME:
- Console::instance->move_cursor(-65535);
- break;
- case SDLK_END:
- Console::instance->move_cursor(+65535);
- break;
- case SDLK_UP:
- Console::instance->show_history(-1);
- break;
- case SDLK_DOWN:
- Console::instance->show_history(+1);
- break;
- case SDLK_LEFT:
- Console::instance->move_cursor(-1);
- break;
- case SDLK_RIGHT:
- Console::instance->move_cursor(+1);
- break;
- default:
- int c = event.key.keysym.unicode;
- if ((c >= 32) && (c <= 126)) {
- Console::instance->input((char)c);
- }
- break;
- }
-}
-
-void
-JoystickKeyboardController::process_menu_key_event(const SDL_Event& event)
-{
- // wait for key mode?
- if(wait_for_key >= 0) {
- if(event.type == SDL_KEYUP)
- return;
-
- if(event.key.keysym.sym != SDLK_ESCAPE
- && event.key.keysym.sym != SDLK_PAUSE) {
- bind_key(event.key.keysym.sym, (Control) wait_for_key);
- }
- reset();
- key_options_menu->update();
- wait_for_key = -1;
- return;
- }
- if(wait_for_joystick >= 0) {
- if(event.key.keysym.sym == SDLK_ESCAPE) {
- reset();
- joystick_options_menu->update();
- wait_for_joystick = -1;
- }
- return;
- }
-
- Control control;
- /* we use default keys when the menu is open (to avoid problems when
- * redefining keys to invalid settings
- */
- switch(event.key.keysym.sym) {
- case SDLK_UP:
- control = UP;
- break;
- case SDLK_DOWN:
- control = DOWN;
- break;
- case SDLK_LEFT:
- control = LEFT;
- break;
- case SDLK_RIGHT:
- control = RIGHT;
- break;
- case SDLK_SPACE:
- case SDLK_RETURN:
- case SDLK_KP_ENTER:
- control = MENU_SELECT;
- break;
- case SDLK_ESCAPE:
- case SDLK_PAUSE:
- control = PAUSE_MENU;
- break;
- default:
- return;
- break;
- }
-
- controls[control] = (event.type == SDL_KEYDOWN);
-}
-
-void
-JoystickKeyboardController::unbind_joystick_control(Control control)
-{
- // remove all previous mappings for that control
- for(AxisMap::iterator i = joy_axis_map.begin(); i != joy_axis_map.end(); /* no ++i */) {
- if(i->second == control)
- joy_axis_map.erase(i++);
- else
- ++i;
- }
-
- for(ButtonMap::iterator i = joy_button_map.begin(); i != joy_button_map.end(); /* no ++i */) {
- if(i->second == control)
- joy_button_map.erase(i++);
- else
- ++i;
- }
-
- for(HatMap::iterator i = joy_hat_map.begin(); i != joy_hat_map.end(); /* no ++i */) {
- if(i->second == control)
- joy_hat_map.erase(i++);
- else
- ++i;
- }
-}
-
-void
-JoystickKeyboardController::bind_joyaxis(int axis, Control control)
-{
- // axis isn't the SDL axis number, but axisnumber + 1 with sign
- // changed depending on if the positive or negative end is to be
- // used (negative axis 0 becomes -1, positive axis 2 becomes +3,
- // etc.)
-
- unbind_joystick_control(control);
-
- // add new mapping
- joy_axis_map[axis] = control;
-}
-
-void
-JoystickKeyboardController::bind_joyhat(int dir, Control c)
-{
- unbind_joystick_control(c);
-
- // add new mapping
- joy_hat_map[dir] = c;
-}
-
-void
-JoystickKeyboardController::bind_joybutton(int button, Control control)
-{
- unbind_joystick_control(control);
-
- // add new mapping
- joy_button_map[button] = control;
-}
-
-void
-JoystickKeyboardController::bind_key(SDLKey key, Control control)
-{
- // remove all previous mappings for that control and for that key
- for(KeyMap::iterator i = keymap.begin();
- i != keymap.end(); /* no ++i */) {
- if(i->second == control) {
- KeyMap::iterator e = i;
- ++i;
- keymap.erase(e);
- } else {
- ++i;
- }
- }
-
- KeyMap::iterator i = keymap.find(key);
- if(i != keymap.end())
- keymap.erase(i);
-
- // add new mapping
- keymap[key]= control;
-}
-
-void
-JoystickKeyboardController::print_joystick_mappings()
-{
- std::cout << "Joystick Mappings" << std::endl;
- std::cout << "-----------------" << std::endl;
- for(AxisMap::iterator i = joy_axis_map.begin(); i != joy_axis_map.end(); ++i) {
- std::cout << "Axis: " << i->first << " -> " << i->second << std::endl;
- }
-
- for(ButtonMap::iterator i = joy_button_map.begin(); i != joy_button_map.end(); ++i) {
- std::cout << "Button: " << i->first << " -> " << i->second << std::endl;
- }
-
- for(HatMap::iterator i = joy_hat_map.begin(); i != joy_hat_map.end(); ++i) {
- std::cout << "Hat: " << i->first << " -> " << i->second << std::endl;
- }
- std::cout << std::endl;
-}
-
-SDLKey
-JoystickKeyboardController::reversemap_key(Control c)
-{
- for(KeyMap::iterator i = keymap.begin(); i != keymap.end(); ++i) {
- if(i->second == c)
- return i->first;
- }
-
- return SDLK_UNKNOWN;
-}
-
-int
-JoystickKeyboardController::reversemap_joyaxis(Control c)
-{
- for(AxisMap::iterator i = joy_axis_map.begin(); i != joy_axis_map.end(); ++i) {
- if(i->second == c)
- return i->first;
- }
-
- return 0;
-}
-
-int
-JoystickKeyboardController::reversemap_joybutton(Control c)
-{
- for(ButtonMap::iterator i = joy_button_map.begin(); i != joy_button_map.end(); ++i) {
- if(i->second == c)
- return i->first;
- }
-
- return -1;
-}
-
-int
-JoystickKeyboardController::reversemap_joyhat(Control c)
-{
- for(HatMap::iterator i = joy_hat_map.begin(); i != joy_hat_map.end(); ++i) {
- if(i->second == c)
- return i->first;
- }
-
- return -1;
-}
-
-Menu*
-JoystickKeyboardController::get_key_options_menu()
-{
- if(key_options_menu == 0) {
- key_options_menu = new KeyboardMenu(this);
- }
-
- return key_options_menu;
-}
-
-Menu*
-JoystickKeyboardController::get_joystick_options_menu()
-{
- if(joystick_options_menu == 0) {
- joystick_options_menu = new JoystickMenu(this);
- }
-
- return joystick_options_menu;
-}
-
-//----------------------------------------------------------------------------
-
-JoystickKeyboardController::KeyboardMenu::KeyboardMenu(
- JoystickKeyboardController* _controller)
- : controller(_controller)
-{
- add_label(_("Setup Keyboard"));
- add_hl();
- add_controlfield(Controller::UP, _("Up"));
- add_controlfield(Controller::DOWN, _("Down"));
- add_controlfield(Controller::LEFT, _("Left"));
- add_controlfield(Controller::RIGHT, _("Right"));
- add_controlfield(Controller::JUMP, _("Jump"));
- add_controlfield(Controller::ACTION, _("Action"));
- add_controlfield(Controller::PEEK_LEFT, _("Peek Left"));
- add_controlfield(Controller::PEEK_RIGHT, _("Peek Right"));
- if (config->console_enabled) {
- add_controlfield(Controller::CONSOLE, _("Console"));
- }
- add_hl();
- add_back(_("Back"));
- update();
-}
-
-JoystickKeyboardController::KeyboardMenu::~KeyboardMenu()
-{}
-
-std::string
-JoystickKeyboardController::KeyboardMenu::get_key_name(SDLKey key)
-{
- switch(key) {
- case SDLK_UNKNOWN:
- return _("None");
- case SDLK_UP:
- return _("Up cursor");
- case SDLK_DOWN:
- return _("Down cursor");
- case SDLK_LEFT:
- return _("Left cursor");
- case SDLK_RIGHT:
- return _("Right cursor");
- case SDLK_RETURN:
- return _("Return");
- case SDLK_SPACE:
- return _("Space");
- case SDLK_RSHIFT:
- return _("Right Shift");
- case SDLK_LSHIFT:
- return _("Left Shift");
- case SDLK_RCTRL:
- return _("Right Control");
- case SDLK_LCTRL:
- return _("Left Control");
- case SDLK_RALT:
- return _("Right Alt");
- case SDLK_LALT:
- return _("Left Alt");
- default:
- return SDL_GetKeyName((SDLKey) key);
- }
-}
-
-void
-JoystickKeyboardController::KeyboardMenu::menu_action(MenuItem* item)
-{
- assert(item->id >= 0 && item->id < Controller::CONTROLCOUNT);
- item->change_input(_("Press Key"));
- controller->wait_for_key = item->id;
-}
-
-void
-JoystickKeyboardController::KeyboardMenu::update()
-{
- // update menu
- get_item_by_id((int) Controller::UP).change_input(get_key_name(
- controller->reversemap_key(Controller::UP)));
- get_item_by_id((int) Controller::DOWN).change_input(get_key_name(
- controller->reversemap_key(Controller::DOWN)));
- get_item_by_id((int) Controller::LEFT).change_input(get_key_name(
- controller->reversemap_key(Controller::LEFT)));
- get_item_by_id((int) Controller::RIGHT).change_input(get_key_name(
- controller->reversemap_key(Controller::RIGHT)));
- get_item_by_id((int) Controller::JUMP).change_input(get_key_name(
- controller->reversemap_key(Controller::JUMP)));
- get_item_by_id((int) Controller::ACTION).change_input(get_key_name(
- controller->reversemap_key(Controller::ACTION)));
- get_item_by_id((int) Controller::PEEK_LEFT).change_input(get_key_name(
- controller->reversemap_key(Controller::PEEK_LEFT)));
- get_item_by_id((int) Controller::PEEK_RIGHT).change_input(get_key_name(
- controller->reversemap_key(Controller::PEEK_RIGHT)));
- if (config->console_enabled) {
- get_item_by_id((int) Controller::CONSOLE).change_input(get_key_name(
- controller->reversemap_key(Controller::CONSOLE)));
- }
-}
-
-//---------------------------------------------------------------------------
-
-JoystickKeyboardController::JoystickMenu::JoystickMenu(
- JoystickKeyboardController* _controller)
- : controller(_controller)
-{
- add_label(_("Setup Joystick"));
- add_hl();
- if(controller->joysticks.size() > 0) {
- add_controlfield(Controller::UP, _("Up"));
- add_controlfield(Controller::DOWN, _("Down"));
- add_controlfield(Controller::LEFT, _("Left"));
- add_controlfield(Controller::RIGHT, _("Right"));
- add_controlfield(Controller::JUMP, _("Jump"));
- add_controlfield(Controller::ACTION, _("Action"));
- add_controlfield(Controller::PAUSE_MENU, _("Pause/Menu"));
- add_controlfield(Controller::PEEK_LEFT, _("Peek Left"));
- add_controlfield(Controller::PEEK_RIGHT, _("Peek Right"));
-
- add_toggle(Controller::CONTROLCOUNT, _("Jump with Up"), controller->jump_with_up);
- } else {
- add_deactive(-1, _("No Joysticks found"));
- }
- add_hl();
- add_back(_("Back"));
- update();
-}
-
-JoystickKeyboardController::JoystickMenu::~JoystickMenu()
-{}
-
-std::string
-JoystickKeyboardController::JoystickMenu::get_button_name(int button)
-{
- if(button < 0)
- return _("None");
-
- std::ostringstream name;
- name << "Button " << button;
- return name.str();
-}
-
-void
-JoystickKeyboardController::JoystickMenu::menu_action(MenuItem* item)
-{
- if (item->id >= 0 && item->id < Controller::CONTROLCOUNT) {
- item->change_input(_("Press Button"));
- controller->wait_for_joystick = item->id;
- } else if (item->id == Controller::CONTROLCOUNT) {
- controller->jump_with_up = item->toggled;
- }
-}
-
-void
-JoystickKeyboardController::JoystickMenu::update_menu_item(Control id)
-{
- int button = controller->reversemap_joybutton(id);
- int axis = controller->reversemap_joyaxis(id);
- int hat_dir = controller->reversemap_joyhat(id);
-
- if (button != -1) {
- get_item_by_id((int)id).change_input(get_button_name(button));
- } else if (axis != 0) {
- std::ostringstream name;
-
- name << "Axis ";
-
- if (axis < 0)
- name << "-";
- else
- name << "+";
-
- if (abs(axis) == 1)
- name << "X";
- else if (abs(axis) == 2)
- name << "Y";
- else if (abs(axis) == 2)
- name << "X2";
- else if (abs(axis) == 3)
- name << "Y2";
- else
- name << abs(axis);
-
- get_item_by_id((int)id).change_input(name.str());
- } else if (hat_dir != -1) {
- std::string name;
-
- switch (hat_dir)
- {
- case SDL_HAT_UP:
- name = "Hat Up";
- break;
-
- case SDL_HAT_DOWN:
- name = "Hat Down";
- break;
-
- case SDL_HAT_LEFT:
- name = "Hat Left";
- break;
-
- case SDL_HAT_RIGHT:
- name = "Hat Right";
- break;
-
- default:
- name = "Unknown hat_dir";
- break;
- }
-
- get_item_by_id((int)id).change_input(name);
- } else {
- get_item_by_id((int)id).change_input("None");
- }
-}
-
-void
-JoystickKeyboardController::JoystickMenu::update()
-{
- if(controller->joysticks.size() == 0)
- return;
-
- update_menu_item(Controller::UP);
- update_menu_item(Controller::DOWN);
- update_menu_item(Controller::LEFT);
- update_menu_item(Controller::RIGHT);
-
- update_menu_item(Controller::JUMP);
- update_menu_item(Controller::ACTION);
- update_menu_item(Controller::PAUSE_MENU);
- update_menu_item(Controller::PEEK_LEFT);
- update_menu_item(Controller::PEEK_RIGHT);
-
- get_item_by_id(Controller::CONTROLCOUNT).toggled = controller->jump_with_up;
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __JOYSTICKKEYBOARDCONTROLLER_H__
-#define __JOYSTICKKEYBOARDCONTROLLER_H__
-
-#include "controller.hpp"
-#include "lisp/lisp.hpp"
-#include "lisp/writer.hpp"
-#include <SDL.h>
-#include <string>
-#include <map>
-
-class Menu;
-
-class JoystickKeyboardController : public Controller
-{
-public:
- JoystickKeyboardController();
- virtual ~JoystickKeyboardController();
-
- /** Process an SDL Event and return true if the event has been used
- */
- void process_event(const SDL_Event& event);
-
- void write(lisp::Writer& writer);
- void read(const lisp::Lisp& lisp);
- void reset();
-
- Menu* get_key_options_menu();
- Menu* get_joystick_options_menu();
-
-private:
- void process_key_event(const SDL_Event& event);
- void process_hat_event(const SDL_JoyHatEvent& jhat);
- void process_axis_event(const SDL_JoyAxisEvent& jaxis);
- void process_button_event(const SDL_JoyButtonEvent& jbutton);
- void process_console_key_event(const SDL_Event& event);
- void process_menu_key_event(const SDL_Event& event);
-
- void print_joystick_mappings();
-
- typedef std::map<SDLKey, Control> KeyMap;
- KeyMap keymap;
-
- typedef std::map<int, Control> ButtonMap;
- ButtonMap joy_button_map;
-
- typedef std::map<int, Control> AxisMap;
- AxisMap joy_axis_map;
-
- typedef std::map<int, Control> HatMap;
- HatMap joy_hat_map;
-
- std::vector<SDL_Joystick*> joysticks;
-
- std::string name;
-
- int dead_zone;
- /// the number of buttons all joysticks have
- int min_joybuttons;
- /// the max number of buttons a joystick has
- int max_joybuttons;
-
- int max_joyaxis;
-
- int max_joyhats;
-
- Uint8 hat_state;
-
- bool jump_with_up;
-
- SDLKey reversemap_key(Control c);
- int reversemap_joybutton(Control c);
- int reversemap_joyaxis(Control c);
- int reversemap_joyhat(Control c);
-
- void unbind_joystick_control(Control c);
-
- void bind_joybutton(int button, Control c);
- void bind_joyaxis(int axis, Control c);
- void bind_joyhat(int dir, Control c);
- void bind_key(SDLKey key, Control c);
-
- void set_joy_controls(Control id, bool value);
-
- int wait_for_key;
- int wait_for_joystick;
-
- class KeyboardMenu;
- class JoystickMenu;
-
- KeyboardMenu* key_options_menu;
- JoystickMenu* joystick_options_menu;
- friend class KeyboardMenu;
- friend class JoystickMenu;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#ifndef SUPERTUX_DIRECTION_H
-#define SUPERTUX_DIRECTION_H
-
-enum Direction { AUTO, LEFT, RIGHT, UP, DOWN };
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#include <config.h>
-
-#include "fadeout.hpp"
-#include "main.hpp"
-#include "video/drawing_context.hpp"
-
-FadeOut::FadeOut(float fade_time, Color color)
- : color(color), fade_time(fade_time), accum_time(0)
-{
-}
-
-FadeOut::~FadeOut()
-{
-}
-
-void
-FadeOut::update(float elapsed_time)
-{
- accum_time += elapsed_time;
- if(accum_time > fade_time)
- accum_time = fade_time;
-}
-
-void
-FadeOut::draw(DrawingContext& context)
-{
- Color col = color;
- col.alpha = accum_time / fade_time;
- context.draw_filled_rect(Vector(0, 0),
- Vector(SCREEN_WIDTH, SCREEN_HEIGHT),
- col, LAYER_GUI+1);
-}
-
-bool
-FadeOut::done()
-{
- return accum_time >= fade_time;
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#ifndef __FADEOUT_HPP__
-#define __FADEOUT_HPP__
-
-#include "video/color.hpp"
-#include "screen_fade.hpp"
-
-/**
- * Fades a screen towards a specific color
- */
-class FadeOut : public ScreenFade
-{
-public:
- FadeOut(float fade_time, Color dest_color = Color(0, 0, 0));
- virtual ~FadeOut();
-
- virtual void update(float elapsed_time);
- virtual void draw(DrawingContext& context);
-
- /// returns true if the effect is completed
- virtual bool done();
-
-private:
- Color color;
- float fade_time;
- float accum_time;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include "log.hpp"
-#include "file_system.hpp"
-
-#include <string>
-#include <vector>
-#include <sstream>
-
-namespace FileSystem
-{
-
-std::string dirname(const std::string& filename)
-{
- std::string::size_type p = filename.find_last_of('/');
- if(p == std::string::npos)
- return "";
-
- return filename.substr(0, p+1);
-}
-
-std::string basename(const std::string& filename)
-{
- std::string::size_type p = filename.find_last_of('/');
- if(p == std::string::npos)
- return filename;
-
- return filename.substr(p+1, filename.size()-p-1);
-}
-
-std::string strip_extension(const std::string& filename)
-{
- std::string::size_type p = filename.find_last_of('.');
- if(p == std::string::npos)
- return filename;
-
- return filename.substr(0, p);
-}
-
-std::string normalize(const std::string& filename)
-{
- std::vector<std::string> path_stack;
-
- const char* p = filename.c_str();
-
- while(true) {
- while(*p == '/') {
- p++;
- continue;
- }
-
- const char* pstart = p;
- while(*p != '/' && *p != 0) {
- ++p;
- }
-
- size_t len = p - pstart;
- if(len == 0)
- break;
-
- std::string pathelem(pstart, p-pstart);
- if(pathelem == ".")
- continue;
-
- if(pathelem == "..") {
- if(path_stack.empty()) {
-
- log_warning << "Invalid '..' in path '" << filename << "'" << std::endl;
- // push it into the result path so that the users sees his error...
- path_stack.push_back(pathelem);
- } else {
- path_stack.pop_back();
- }
- } else {
- path_stack.push_back(pathelem);
- }
- }
-
- // construct path
- std::ostringstream result;
- for(std::vector<std::string>::iterator i = path_stack.begin();
- i != path_stack.end(); ++i) {
- result << '/' << *i;
- }
- if(path_stack.empty())
- result << '/';
-
- return result.str();
-}
-
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __FILESYSTEM_H__
-#define __FILESYSTEM_H__
-
-#include <set>
-#include <string>
-
-namespace FileSystem
-{
- std::string dirname(const std::string& filename);
- std::string basename(const std::string& filename);
-
- /**
- * remove everything starting from and including the last dot
- */
- std::string strip_extension(const std::string& filename);
-
- /**
- * normalize filename so that "blup/bla/blo/../../bar" will become
- * "blup/bar"
- */
- std::string normalize(const std::string& filename);
-}
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#include <config.h>
-
-#include "flip_level_transformer.hpp"
-#include "object/tilemap.hpp"
-#include "object/camera.hpp"
-#include "badguy/badguy.hpp"
-#include "sector.hpp"
-#include "tile_manager.hpp"
-#include "spawn_point.hpp"
-#include "object/platform.hpp"
-#include "object/block.hpp"
-
-void
-FlipLevelTransformer::transform_sector(Sector* sector)
-{
- float height = sector->get_height();
-
- for(Sector::GameObjects::iterator i = sector->gameobjects.begin();
- i != sector->gameobjects.end(); ++i) {
- GameObject* object = *i;
-
- TileMap* tilemap = dynamic_cast<TileMap*> (object);
- if(tilemap) {
- transform_tilemap(tilemap);
- }
- Player* player = dynamic_cast<Player*> (object);
- if(player) {
- Vector pos = player->get_pos();
- pos.y = height - pos.y - player->get_bbox().get_height();
- player->move(pos);
- continue;
- }
- BadGuy* badguy = dynamic_cast<BadGuy*> (object);
- if(badguy) {
- transform_badguy(height, badguy);
- }
- Platform* platform = dynamic_cast<Platform*> (object);
- if(platform) {
- transform_platform(height, *platform);
- }
- Block* block = dynamic_cast<Block*> (object);
- if(block) {
- transform_block(height, *block);
- }
- MovingObject* mobject = dynamic_cast<MovingObject*> (object);
- if(mobject) {
- transform_moving_object(height, mobject);
- }
- }
- for(Sector::SpawnPoints::iterator i = sector->spawnpoints.begin();
- i != sector->spawnpoints.end(); ++i) {
- transform_spawnpoint(height, *i);
- }
-
- if(sector->camera != 0 && sector->player != 0)
- sector->camera->reset(sector->player->get_pos());
-}
-
-void
-FlipLevelTransformer::transform_tilemap(TileMap* tilemap)
-{
- for(size_t x = 0; x < tilemap->get_width(); ++x) {
- for(size_t y = 0; y < tilemap->get_height()/2; ++y) {
- // swap tiles
- int y2 = tilemap->get_height()-1-y;
- const Tile* t1 = tilemap->get_tile(x, y);
- const Tile* t2 = tilemap->get_tile(x, y2);
- tilemap->change(x, y, t2->getID());
- tilemap->change(x, y2, t1->getID());
- }
- }
- if(tilemap->get_drawing_effect() != 0) {
- tilemap->set_drawing_effect(NO_EFFECT);
- } else {
- tilemap->set_drawing_effect(VERTICAL_FLIP);
- }
-}
-
-void
-FlipLevelTransformer::transform_badguy(float height, BadGuy* badguy)
-{
- Vector pos = badguy->get_start_position();
- pos.y = height - pos.y;
- badguy->set_start_position(pos);
-}
-
-void
-FlipLevelTransformer::transform_spawnpoint(float height, SpawnPoint* spawn)
-{
- Vector pos = spawn->pos;
- pos.y = height - pos.y;
- spawn->pos = pos;
-}
-
-void
-FlipLevelTransformer::transform_moving_object(float height, MovingObject*object)
-{
- Vector pos = object->get_pos();
- pos.y = height - pos.y - object->get_bbox().get_height();
- object->set_pos(pos);
-}
-
-void
-FlipLevelTransformer::transform_platform(float height, Platform& platform)
-{
- Path& path = platform.get_path();
- for (std::vector<Path::Node>::iterator i = path.nodes.begin(); i != path.nodes.end(); i++) {
- Vector& pos = i->position;
- pos.y = height - pos.y - platform.get_bbox().get_height();
- }
-}
-
-void
-FlipLevelTransformer::transform_block(float height, Block& block)
-{
- block.original_y = height - block.original_y - block.get_bbox().get_height();
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#ifndef __FLIP_LEVEL_TRANSFORMER_H__
-#define __FLIP_LEVEL_TRANSFORMER_H__
-
-#include "level_transformer.hpp"
-
-class TileMap;
-class BadGuy;
-class SpawnPoint;
-class MovingObject;
-class Platform;
-class Block;
-
-/** Vertically or horizontally flip a level */
-class FlipLevelTransformer : public LevelTransformer
-{
-public:
- virtual void transform_sector(Sector* sector);
-
-private:
- void transform_tilemap(TileMap* tilemap);
- void transform_moving_object(float height, MovingObject* object);
- void transform_badguy(float height, BadGuy* badguy);
- void transform_spawnpoint(float height, SpawnPoint* spawnpoint);
- void transform_platform(float height, Platform& platform);
- void transform_block(float height, Block& block);
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-#include "log.hpp"
-#include "game_object.hpp"
-#include "object_remove_listener.hpp"
-
-GameObject::GameObject()
- : wants_to_die(false), remove_listeners(NULL)
-{
-}
-
-GameObject::~GameObject()
-{
- // call remove listeners (and remove them from the list)
- RemoveListenerListEntry* entry = remove_listeners;
- while(entry != NULL) {
- RemoveListenerListEntry* next = entry->next;
- entry->listener->object_removed(this);
- delete entry;
- entry = next;
- }
-}
-
-
-void
-GameObject::add_remove_listener(ObjectRemoveListener* listener)
-{
- RemoveListenerListEntry* entry = new RemoveListenerListEntry();
- entry->next = remove_listeners;
- entry->listener = listener;
- remove_listeners = entry;
-}
-
-void
-GameObject::del_remove_listener(ObjectRemoveListener* listener)
-{
- RemoveListenerListEntry* entry = remove_listeners;
- if (entry->listener == listener) {
- remove_listeners = entry->next;
- delete entry;
- return;
- }
- RemoveListenerListEntry* next = entry->next;
- while(next != NULL) {
- if (next->listener == listener) {
- entry->next = next->next;
- delete next;
- break;
- }
- entry = next;
- next = next->next;
- }
-}
-
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#ifndef SUPERTUX_GAMEOBJECT_H
-#define SUPERTUX_GAMEOBJECT_H
-
-#include <string>
-#include "refcounter.hpp"
-
-class DrawingContext;
-class ObjectRemoveListener;
-
-/**
- * This is a base class for all game objects. Each sector of a level will hold a
- * list of active GameObject while the game is played.
- *
- * This class is responsible for:
- * - Updating and Drawing the object. This should happen in the update() and
- * draw() functions. Both are called once per frame.
- * - Providing a safe way to remove the object by calling the remove_me
- * functions.
- */
-class GameObject : public RefCounter
-{
-public:
- GameObject();
- virtual ~GameObject();
-
- /** This function is called once per frame and allows the object to update
- * it's state. The elapsed_time is the time since the last frame in
- * seconds and should be the base for all timed calculations (don't use
- * SDL_GetTicks directly as this will fail in pause mode)
- */
- virtual void update(float elapsed_time) = 0;
-
- /** The GameObject should draw itself onto the provided DrawingContext if this
- * function is called.
- */
- virtual void draw(DrawingContext& context) = 0;
-
- /** returns true if the object is not scheduled to be removed yet */
- bool is_valid() const
- {
- return !wants_to_die;
- }
-
- /** schedules this object to be removed at the end of the frame */
- void remove_me()
- {
- wants_to_die = true;
- }
-
- /** registers a remove listener which will be called if the object
- * gets removed/destroyed
- */
- void add_remove_listener(ObjectRemoveListener* listener);
-
- /**
- * unregisters a remove listener, so it will no longer be called if the object
- * gets removed/destroyed
- */
- void del_remove_listener(ObjectRemoveListener* listener);
-
- const std::string& get_name() const
- {
- return name;
- }
-
-private:
- /** this flag indicates if the object should be removed at the end of the
- * frame
- */
- bool wants_to_die;
-
- struct RemoveListenerListEntry
- {
- RemoveListenerListEntry* next;
- ObjectRemoveListener* listener;
- };
- RemoveListenerListEntry* remove_listeners;
-
-protected:
- /**
- * a name for the gameobject, this is mostly a hint for scripts and for
- * debugging, don't rely on names being set or being unique
- */
- std::string name;
-};
-
-#endif /*SUPERTUX_GAMEOBJECT_H*/
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#include <config.h>
-
-#include <fstream>
-#include <sstream>
-#include <assert.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <math.h>
-#include <string.h>
-#include <errno.h>
-#include <unistd.h>
-#include <time.h>
-#include <stdexcept>
-
-#include <SDL.h>
-
-#include "game_session.hpp"
-#include "log.hpp"
-#include "console.hpp"
-#include "worldmap/worldmap.hpp"
-#include "mainloop.hpp"
-#include "audio/sound_manager.hpp"
-#include "gui/menu.hpp"
-#include "sector.hpp"
-#include "level.hpp"
-#include "tile.hpp"
-#include "player_status.hpp"
-#include "object/particlesystem.hpp"
-#include "object/background.hpp"
-#include "object/gradient.hpp"
-#include "object/tilemap.hpp"
-#include "object/camera.hpp"
-#include "object/player.hpp"
-#include "object/level_time.hpp"
-#include "lisp/lisp.hpp"
-#include "lisp/parser.hpp"
-#include "resources.hpp"
-#include "statistics.hpp"
-#include "timer.hpp"
-#include "options_menu.hpp"
-#include "textscroller.hpp"
-#include "control/codecontroller.hpp"
-#include "control/joystickkeyboardcontroller.hpp"
-#include "main.hpp"
-#include "file_system.hpp"
-#include "gameconfig.hpp"
-#include "gettext.hpp"
-#include "console.hpp"
-#include "flip_level_transformer.hpp"
-#include "trigger/secretarea_trigger.hpp"
-#include "trigger/sequence_trigger.hpp"
-#include "random_generator.hpp"
-#include "scripting/squirrel_util.hpp"
-#include "object/endsequence_walkright.hpp"
-#include "object/endsequence_walkleft.hpp"
-#include "object/endsequence_fireworks.hpp"
-#include "direction.hpp"
-#include "scripting/time_scheduler.hpp"
-
-// the engine will be run with a logical framerate of 64fps.
-// We chose 64fps here because it is a power of 2, so 1/64 gives an "even"
-// binary fraction...
-static const float LOGICAL_FPS = 64.0;
-
-enum GameMenuIDs {
- MNID_CONTINUE,
- MNID_ABORTLEVEL
-};
-
-GameSession* GameSession::current_ = NULL;
-
-GameSession::GameSession(const std::string& levelfile_, Statistics* statistics)
- : level(0), currentsector(0),
- end_sequence(0),
- levelfile(levelfile_), best_level_statistics(statistics),
- capture_demo_stream(0), playback_demo_stream(0), demo_controller(0),
- play_time(0)
-{
- current_ = this;
- currentsector = NULL;
-
- game_pause = false;
- speed_before_pause = main_loop->get_speed();
-
- statistics_backdrop.reset(new Surface("images/engine/menu/score-backdrop.png"));
-
- restart_level();
-
- game_menu.reset(new Menu());
- game_menu->add_label(_("Pause"));
- game_menu->add_hl();
- game_menu->add_entry(MNID_CONTINUE, _("Continue"));
- game_menu->add_submenu(_("Options"), get_options_menu());
- game_menu->add_hl();
- game_menu->add_entry(MNID_ABORTLEVEL, _("Abort Level"));
-}
-
-void
-GameSession::restart_level()
-{
- game_pause = false;
- end_sequence = 0;
-
- main_controller->reset();
-
- currentsector = 0;
-
- level.reset(new Level);
- level->load(levelfile);
- level->stats.total_coins = level->get_total_coins();
- level->stats.total_badguys = level->get_total_badguys();
- level->stats.total_secrets = level->get_total_count<SecretAreaTrigger>();
- level->stats.reset();
- if(reset_sector != "")level->stats.declare_invalid();
-
- if(reset_sector != "") {
- currentsector = level->get_sector(reset_sector);
- if(!currentsector) {
- std::stringstream msg;
- msg << "Couldn't find sector '" << reset_sector << "' for resetting tux.";
- throw std::runtime_error(msg.str());
- }
- currentsector->activate(reset_pos);
- } else {
- currentsector = level->get_sector("main");
- if(!currentsector)
- throw std::runtime_error("Couldn't find main sector");
- currentsector->activate("main");
- }
-
- //levelintro();
-
- sound_manager->stop_music();
- currentsector->play_music(LEVEL_MUSIC);
-
- if(capture_file != "") {
- int newSeed=0; // next run uses a new seed
- while (newSeed == 0) // which is the next non-zero random num.
- newSeed = systemRandom.rand();
- config->random_seed = systemRandom.srand(newSeed);
- log_info << "Next run uses random seed " <<config->random_seed <<std::endl;
- record_demo(capture_file);
- }
-}
-
-GameSession::~GameSession()
-{
- delete capture_demo_stream;
- delete playback_demo_stream;
- delete demo_controller;
- free_options_menu();
-
- current_ = NULL;
-}
-
-void
-GameSession::record_demo(const std::string& filename)
-{
- delete capture_demo_stream;
-
- capture_demo_stream = new std::ofstream(filename.c_str());
- if(!capture_demo_stream->good()) {
- std::stringstream msg;
- msg << "Couldn't open demo file '" << filename << "' for writing.";
- throw std::runtime_error(msg.str());
- }
- capture_file = filename;
-
- char buf[30]; // save the seed in the demo file
- snprintf(buf, sizeof(buf), "random_seed=%10d", config->random_seed);
- for (int i=0; i==0 || buf[i-1]; i++)
- capture_demo_stream->put(buf[i]);
-}
-
-int
-GameSession::get_demo_random_seed(const std::string& filename)
-{
- std::istream* test_stream = new std::ifstream(filename.c_str());
- if(test_stream->good()) {
- char buf[30]; // recall the seed from the demo file
- int seed;
- for (int i=0; i<30 && (i==0 || buf[i-1]); i++)
- test_stream->get(buf[i]);
- if (sscanf(buf, "random_seed=%10d", &seed) == 1) {
- log_info << "Random seed " << seed << " from demo file" << std::endl;
- return seed;
- }
- else
- log_info << "Demo file contains no random number" << std::endl;
- }
- return 0;
-}
-
-void
-GameSession::play_demo(const std::string& filename)
-{
- delete playback_demo_stream;
- delete demo_controller;
-
- playback_demo_stream = new std::ifstream(filename.c_str());
- if(!playback_demo_stream->good()) {
- std::stringstream msg;
- msg << "Couldn't open demo file '" << filename << "' for reading.";
- throw std::runtime_error(msg.str());
- }
-
- Player& tux = *currentsector->player;
- demo_controller = new CodeController();
- tux.set_controller(demo_controller);
-
- // skip over random seed, if it exists in the file
- char buf[30]; // ascii decimal seed
- int seed;
- for (int i=0; i<30 && (i==0 || buf[i-1]); i++)
- playback_demo_stream->get(buf[i]);
- if (sscanf(buf, "random_seed=%010d", &seed) != 1)
- playback_demo_stream->seekg(0); // old style w/o seed, restart at beg
-}
-
-void
-GameSession::levelintro()
-{
- sound_manager->stop_music();
-
- DrawingContext context;
- for(Sector::GameObjects::iterator i = currentsector->gameobjects.begin();
- i != currentsector->gameobjects.end(); ++i) {
- Background* background = dynamic_cast<Background*> (*i);
- if(background) {
- background->draw(context);
- }
- Gradient* gradient = dynamic_cast<Gradient*> (*i);
- if(gradient) {
- gradient->draw(context);
- }
- }
-
-// context.draw_text(gold_text, level->get_name(), Vector(SCREEN_WIDTH/2, 160),
-// ALIGN_CENTER, LAYER_FOREGROUND1);
- context.draw_center_text(gold_text, level->get_name(), Vector(0, 160),
- LAYER_FOREGROUND1);
-
- std::stringstream ss_coins;
- ss_coins << _("Coins") << ": " << player_status->coins;
- context.draw_text(white_text, ss_coins.str(), Vector(SCREEN_WIDTH/2, 210),
- ALIGN_CENTER, LAYER_FOREGROUND1);
-
- if((level->get_author().size()) && (level->get_author() != "SuperTux Team"))
- context.draw_text(white_small_text,
- std::string(_("contributed by ")) + level->get_author(),
- Vector(SCREEN_WIDTH/2, 350), ALIGN_CENTER, LAYER_FOREGROUND1);
-
- if(best_level_statistics != NULL)
- best_level_statistics->draw_message_info(context, _("Best Level Statistics"));
-
- wait_for_event(1.0, 3.0);
-}
-
-void
-GameSession::on_escape_press()
-{
- if(currentsector->player->is_dying() || end_sequence)
- {
- // Let the timers run out, we fast-forward them to force past a sequence
- if (end_sequence)
- end_sequence->stop();
-
- currentsector->player->dying_timer.start(FLT_EPSILON);
- return; // don't let the player open the menu, when he is dying
- }
-
- if(level->on_menukey_script != "") {
- std::istringstream in(level->on_menukey_script);
- run_script(in, "OnMenuKeyScript");
- } else {
- toggle_pause();
- }
-}
-
-void
-GameSession::toggle_pause()
-{
- if(!game_pause) {
- speed_before_pause = main_loop->get_speed();
- main_loop->set_speed(0);
- Menu::set_current(game_menu.get());
- game_menu->set_active_item(MNID_CONTINUE);
- game_pause = true;
- } else {
- main_loop->set_speed(speed_before_pause);
- Menu::set_current(NULL);
- game_pause = false;
- }
-}
-
-HSQUIRRELVM
-GameSession::run_script(std::istream& in, const std::string& sourcename)
-{
- using namespace Scripting;
-
- // garbage collect thread list
- for(ScriptList::iterator i = scripts.begin();
- i != scripts.end(); ) {
- HSQOBJECT& object = *i;
- HSQUIRRELVM vm = object_to_vm(object);
-
- if(sq_getvmstate(vm) != SQ_VMSTATE_SUSPENDED) {
- sq_release(global_vm, &object);
- i = scripts.erase(i);
- continue;
- }
-
- ++i;
- }
-
- HSQOBJECT object = create_thread(global_vm);
- scripts.push_back(object);
-
- HSQUIRRELVM vm = object_to_vm(object);
-
- compile_and_run(vm, in, sourcename);
-
- return vm;
-}
-
-void
-GameSession::process_events()
-{
- // end of pause mode?
- if(!Menu::current() && game_pause) {
- game_pause = false;
- }
-
- // playback a demo?
- if(playback_demo_stream != 0) {
- demo_controller->update();
- char left = false;
- char right = false;
- char up = false;
- char down = false;
- char jump = false;
- char action = false;
- playback_demo_stream->get(left);
- playback_demo_stream->get(right);
- playback_demo_stream->get(up);
- playback_demo_stream->get(down);
- playback_demo_stream->get(jump);
- playback_demo_stream->get(action);
- demo_controller->press(Controller::LEFT, left);
- demo_controller->press(Controller::RIGHT, right);
- demo_controller->press(Controller::UP, up);
- demo_controller->press(Controller::DOWN, down);
- demo_controller->press(Controller::JUMP, jump);
- demo_controller->press(Controller::ACTION, action);
- }
-
- // save input for demo?
- if(capture_demo_stream != 0) {
- capture_demo_stream ->put(main_controller->hold(Controller::LEFT));
- capture_demo_stream ->put(main_controller->hold(Controller::RIGHT));
- capture_demo_stream ->put(main_controller->hold(Controller::UP));
- capture_demo_stream ->put(main_controller->hold(Controller::DOWN));
- capture_demo_stream ->put(main_controller->hold(Controller::JUMP));
- capture_demo_stream ->put(main_controller->hold(Controller::ACTION));
- }
-}
-
-void
-GameSession::check_end_conditions()
-{
- Player* tux = currentsector->player;
-
- /* End of level? */
- if(end_sequence && end_sequence->is_done()) {
- finish(true);
- } else if (!end_sequence && tux->is_dead()) {
- restart_level();
- }
-}
-
-void
-GameSession::draw(DrawingContext& context)
-{
- currentsector->draw(context);
- drawstatus(context);
-
- if(game_pause)
- draw_pause(context);
-}
-
-void
-GameSession::draw_pause(DrawingContext& context)
-{
- context.draw_filled_rect(
- Vector(0,0), Vector(SCREEN_WIDTH, SCREEN_HEIGHT),
- Color(.2f, .2f, .2f, .5f), LAYER_FOREGROUND1);
-}
-
-void
-GameSession::process_menu()
-{
- Menu* menu = Menu::current();
- if(menu) {
- menu->update();
-
- if(menu == game_menu.get()) {
- switch (game_menu->check()) {
- case MNID_CONTINUE:
- Menu::set_current(0);
- toggle_pause();
- break;
- case MNID_ABORTLEVEL:
- Menu::set_current(0);
- main_loop->exit_screen();
- break;
- }
- }
- }
-}
-
-void
-GameSession::setup()
-{
- Menu::set_current(NULL);
- current_ = this;
-
- if(currentsector != Sector::current()) {
- currentsector->activate(currentsector->player->get_pos());
- }
- currentsector->play_music(LEVEL_MUSIC);
-
- // Eat unneeded events
- SDL_Event event;
- while(SDL_PollEvent(&event))
- {}
-}
-
-void
-GameSession::update(float elapsed_time)
-{
- // handle controller
- if(main_controller->pressed(Controller::PAUSE_MENU))
- on_escape_press();
-
- process_events();
- process_menu();
-
- check_end_conditions();
-
- // respawning in new sector?
- if(newsector != "" && newspawnpoint != "") {
- Sector* sector = level->get_sector(newsector);
- if(sector == 0) {
- log_warning << "Sector '" << newsector << "' not found" << std::endl;
- }
- sector->activate(newspawnpoint);
- sector->play_music(LEVEL_MUSIC);
- currentsector = sector;
- newsector = "";
- newspawnpoint = "";
- }
-
- // Update the world state and all objects in the world
- if(!game_pause) {
- // Update the world
- if (!end_sequence) {
- play_time += elapsed_time; //TODO: make sure we don't count cutscene time
- level->stats.time = play_time;
- currentsector->update(elapsed_time);
- } else {
- if (!end_sequence->is_tux_stopped()) {
- currentsector->update(elapsed_time);
- } else {
- end_sequence->update(elapsed_time);
- }
- }
- }
-
- // update sounds
- sound_manager->set_listener_position(currentsector->player->get_pos());
-
- /* Handle music: */
- if (end_sequence)
- return;
-
- if(currentsector->player->invincible_timer.started()) {
- if(currentsector->player->invincible_timer.get_timeleft() <=
- TUX_INVINCIBLE_TIME_WARNING) {
- currentsector->play_music(HERRING_WARNING_MUSIC);
- } else {
- currentsector->play_music(HERRING_MUSIC);
- }
- } else if(currentsector->get_music_type() != LEVEL_MUSIC) {
- currentsector->play_music(LEVEL_MUSIC);
- }
-}
-
-void
-GameSession::finish(bool win)
-{
- using namespace WorldMapNS;
-
- if(win) {
- if(WorldMap::current())
- WorldMap::current()->finished_level(level.get());
- }
-
- main_loop->exit_screen();
-}
-
-void
-GameSession::respawn(const std::string& sector, const std::string& spawnpoint)
-{
- newsector = sector;
- newspawnpoint = spawnpoint;
-}
-
-void
-GameSession::set_reset_point(const std::string& sector, const Vector& pos)
-{
- reset_sector = sector;
- reset_pos = pos;
-}
-
-std::string
-GameSession::get_working_directory()
-{
- return FileSystem::dirname(levelfile);
-}
-
-void
-GameSession::display_info_box(const std::string& text)
-{
- InfoBox* box = new InfoBox(text);
-
- bool running = true;
- DrawingContext context;
-
- while(running) {
-
- // TODO make a screen out of this, another mainloop is ugly
- main_controller->update();
- SDL_Event event;
- while (SDL_PollEvent(&event)) {
- main_controller->process_event(event);
- if(event.type == SDL_QUIT)
- main_loop->quit();
- }
-
- if(main_controller->pressed(Controller::JUMP)
- || main_controller->pressed(Controller::ACTION)
- || main_controller->pressed(Controller::PAUSE_MENU)
- || main_controller->pressed(Controller::MENU_SELECT))
- running = false;
- else if(main_controller->pressed(Controller::DOWN))
- box->scrolldown();
- else if(main_controller->pressed(Controller::UP))
- box->scrollup();
- box->draw(context);
- draw(context);
- context.do_drawing();
- sound_manager->update();
- }
-
- delete box;
-}
-
-void
-GameSession::start_sequence(const std::string& sequencename)
-{
- // handle special "stoptux" sequence
- if (sequencename == "stoptux") {
- if (!end_sequence) {
- log_warning << "Final target reached without an active end sequence" << std::endl;
- this->start_sequence("endsequence");
- }
- if (end_sequence) end_sequence->stop_tux();
- return;
- }
-
- // abort if a sequence is already playing
- if (end_sequence)
- return;
-
- if (sequencename == "endsequence") {
- if (currentsector->get_players()[0]->physic.get_velocity_x() < 0) {
- end_sequence = new EndSequenceWalkLeft();
- } else {
- end_sequence = new EndSequenceWalkRight();
- }
- } else if (sequencename == "fireworks") {
- end_sequence = new EndSequenceFireworks();
- } else {
- log_warning << "Unknown sequence '" << sequencename << "'. Ignoring." << std::endl;
- return;
- }
-
- /* slow down the game for end-sequence */
- main_loop->set_speed(0.5f);
-
- currentsector->add_object(end_sequence);
- end_sequence->start();
-
- sound_manager->play_music("music/leveldone.ogg", false);
- currentsector->player->invincible_timer.start(10000.0f);
-
- // Stop all clocks.
- for(std::vector<GameObject*>::iterator i = currentsector->gameobjects.begin();
- i != currentsector->gameobjects.end(); ++i)
- {
- GameObject* obj = *i;
-
- LevelTime* lt = dynamic_cast<LevelTime*> (obj);
- if(lt)
- lt->stop();
- }
-}
-
-/* (Status): */
-void
-GameSession::drawstatus(DrawingContext& context)
-{
- player_status->draw(context);
-
- // draw level stats while end_sequence is running
- if (end_sequence) {
- level->stats.draw_endseq_panel(context, best_level_statistics, statistics_backdrop.get());
- }
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#ifndef SUPERTUX_GAMELOOP_H
-#define SUPERTUX_GAMELOOP_H
-
-#include <string>
-#include <SDL.h>
-#include <squirrel.h>
-#include "screen.hpp"
-#include "math/vector.hpp"
-#include "video/surface.hpp"
-#include "object/endsequence.hpp"
-
-class Level;
-class Sector;
-class Statistics;
-class DrawingContext;
-class CodeController;
-class Menu;
-
-/**
- * The GameSession class controlls the controll flow of the Game (the part
- * where you actually play a level)
- */
-class GameSession : public Screen
-{
-public:
- GameSession(const std::string& levelfile, Statistics* statistics = NULL);
- ~GameSession();
-
- void record_demo(const std::string& filename);
- int get_demo_random_seed(const std::string& filename);
- void play_demo(const std::string& filename);
-
- void draw(DrawingContext& context);
- void update(float frame_ratio);
- void setup();
-
- void set_current()
- { current_ = this; }
- static GameSession* current()
- { return current_; }
-
- /// ends the current level
- void finish(bool win = true);
- void respawn(const std::string& sectorname, const std::string& spawnpointname);
- void set_reset_point(const std::string& sectorname, const Vector& pos);
- std::string get_reset_point_sectorname()
- { return reset_sector; }
-
- Vector get_reset_point_pos()
- { return reset_pos; }
-
- void display_info_box(const std::string& text);
-
- Sector* get_current_sector()
- { return currentsector; }
-
- Level* get_current_level()
- { return level.get(); }
-
- void start_sequence(const std::string& sequencename);
-
- /**
- * returns the "working directory" usually this is the directory where the
- * currently played level resides. This is used when locating additional
- * resources for the current level/world
- */
- std::string get_working_directory();
- void restart_level();
-
- void toggle_pause();
-
-private:
- void check_end_conditions();
- void process_events();
- void capture_demo_step();
-
- void levelintro();
- void drawstatus(DrawingContext& context);
- void draw_pause(DrawingContext& context);
-
- HSQUIRRELVM run_script(std::istream& in, const std::string& sourcename);
- void on_escape_press();
- void process_menu();
-
- std::auto_ptr<Level> level;
- std::auto_ptr<Surface> statistics_backdrop;
-
- // scripts
- typedef std::vector<HSQOBJECT> ScriptList;
- ScriptList scripts;
-
- Sector* currentsector;
-
- int levelnb;
- int pause_menu_frame;
-
- EndSequence* end_sequence;
-
- bool game_pause;
- float speed_before_pause;
-
- std::string levelfile;
-
- // reset point (the point where tux respawns if he dies)
- std::string reset_sector;
- Vector reset_pos;
-
- // the sector and spawnpoint we should spawn after this frame
- std::string newsector;
- std::string newspawnpoint;
-
- static GameSession* current_;
-
- Statistics* best_level_statistics;
-
- std::ostream* capture_demo_stream;
- std::string capture_file;
- std::istream* playback_demo_stream;
- CodeController* demo_controller;
-
- std::auto_ptr<Menu> game_menu;
-
- float play_time; /**< total time in seconds that this session ran interactively */
-};
-
-#endif /*SUPERTUX_GAMELOOP_H*/
+++ /dev/null
-// $Id$
-//
-// SuperTux - A Jump'n Run
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#include <config.h>
-
-#include "gameconfig.hpp"
-
-#include <stdlib.h>
-#include <string>
-#include <stdexcept>
-
-#include "lisp/parser.hpp"
-#include "lisp/lisp.hpp"
-#include "lisp/writer.hpp"
-#include "control/joystickkeyboardcontroller.hpp"
-#include "resources.hpp"
-#include "main.hpp"
-
-Config* config = 0;
-
-Config::Config()
-{
- use_fullscreen = true;
- //video = AUTO_VIDEO;
- video = "auto";
- try_vsync = true;
- show_fps = false;
- sound_enabled = true;
- music_enabled = true;
- console_enabled = false;
- random_seed = 0; // set by time(), by default (unless in config)
-
- screenwidth = 800;
- screenheight = 600;
- aspect_ratio = -1; // autodetect
-
- enable_script_debugger = false;
-
- locale = ""; // autodetect
-}
-
-Config::~Config()
-{}
-
-void
-Config::load()
-{
- lisp::Parser parser;
- const lisp::Lisp* root = parser.parse("config");
-
- const lisp::Lisp* config_lisp = root->get_lisp("supertux-config");
- if(!config_lisp)
- throw std::runtime_error("File is not a supertux-config file");
-
- config_lisp->get("show_fps", show_fps);
- config_lisp->get("console", console_enabled);
- config_lisp->get("locale", locale);
- config_lisp->get("random_seed", random_seed);
-
- const lisp::Lisp* config_video_lisp = config_lisp->get_lisp("video");
- if(config_video_lisp) {
- config_video_lisp->get("fullscreen", use_fullscreen);
- //std::string video_string;
- //config_video_lisp->get("video", video_string);
- //video = get_video_system(video_string);
- config_video_lisp->get("video", video);
- config_video_lisp->get("vsync", try_vsync);
- config_video_lisp->get("width", screenwidth);
- config_video_lisp->get("height", screenheight);
- config_video_lisp->get("aspect_ratio", aspect_ratio);
- }
-
- const lisp::Lisp* config_audio_lisp = config_lisp->get_lisp("audio");
- if(config_audio_lisp) {
- config_audio_lisp->get("sound_enabled", sound_enabled);
- config_audio_lisp->get("music_enabled", music_enabled);
- }
-
- const lisp::Lisp* config_control_lisp = config_lisp->get_lisp("control");
- if(config_control_lisp && main_controller) {
- main_controller->read(*config_control_lisp);
- }
-}
-
-void
-Config::save()
-{
- lisp::Writer writer("config");
-
- writer.start_list("supertux-config");
-
- writer.write_bool("show_fps", show_fps);
- writer.write_bool("console", console_enabled);
- writer.write_string("locale", locale);
-
- writer.start_list("video");
- writer.write_bool("fullscreen", use_fullscreen);
- //writer.write_string("video", get_video_string(video));
- writer.write_string("video", video);
- writer.write_bool("vsync", try_vsync);
- writer.write_int("width", screenwidth);
- writer.write_int("height", screenheight);
- writer.write_float("aspect_ratio", aspect_ratio);
- writer.end_list("video");
-
- writer.start_list("audio");
- writer.write_bool("sound_enabled", sound_enabled);
- writer.write_bool("music_enabled", music_enabled);
- writer.end_list("audio");
-
- if(main_controller) {
- writer.start_list("control");
- main_controller->write(writer);
- writer.end_list("control");
- }
-
- writer.end_list("supertux-config");
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux=
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#ifndef SUPERTUX_CONFIG_H
-#define SUPERTUX_CONFIG_H
-
-#include <config.h>
-
-#include <string>
-
-//#include "video/video_systems.hpp"
-
-class Config
-{
-public:
- Config();
- ~Config();
-
- void load();
- void save();
-
- /** screen width in pixel (warning: this is the real screen width+height,
- * you should use the logical SCREEN_WIDTH and SCREEN_HEIGHT for your
- * rendering code.)
- */
- int screenwidth;
- int screenheight;
- float aspect_ratio;
-
- bool use_fullscreen;
- std::string video;
- bool try_vsync;
- bool show_fps;
- bool sound_enabled;
- bool music_enabled;
- bool console_enabled;
-
- int random_seed; // initial random seed. 0 ==> set from time()
-
- /** this variable is set if supertux should start in a specific level */
- std::string start_level;
- bool enable_script_debugger;
- std::string start_demo;
- std::string record_demo;
-
- std::string locale; /**< force SuperTux language to this locale, e.g. "de". A file "data/locale/xx.po" must exist for this to work. An empty string means autodetect. */
-};
-
-extern Config* config;
-
-#endif
+++ /dev/null
-/*
- This program is free software; you can redistribute it and/or modify it
- under the terms of the GNU Library General Public License as published
- by the Free Software Foundation; either version 2, 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
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library 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. */
-#ifndef _LIBGETTEXT_H
-#define _LIBGETTEXT_H
-
-#include "tinygettext/tinygettext.hpp"
-
-extern TinyGetText::DictionaryManager dictionary_manager;
-
-static inline const char* _(const char* message)
-{
- return dictionary_manager.get_dictionary().translate(message);
-}
-
-static inline std::string _(const std::string& message)
-{
- return dictionary_manager.get_dictionary().translate(message);
-}
-
-static inline const char* N_(const char* id, const char* id2, int num)
-{
- return dictionary_manager.get_dictionary().translate(id, id2, num).c_str();
-}
-
-#endif /* _LIBGETTEXT_H */
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include <SDL.h>
-#include <iostream>
-
-#include "main.hpp"
-#include "button.hpp"
-#include "mousecursor.hpp"
-#include "video/font.hpp"
-#include "video/surface.hpp"
-
-Font* Button::info_font = 0;
-extern SDL_Surface* screen;
-
-/* Buttons */
-
-Button::Button(Surface* image_, std::string info_, SDLKey binding_)
- : binding(binding_)
-{
- image = image_;
- size = Vector(image->get_width(), image->get_height());
- id = 0;
- info = info_;
-}
-
-Button::~Button()
-{
-}
-
-void Button::draw(DrawingContext &context, bool selected)
-{
-if(selected)
- context.draw_filled_rect(pos, size, Color (200,240,220), LAYER_GUI);
-else
- context.draw_filled_rect(pos, size, Color (200,200,220), LAYER_GUI);
-
-Vector tanslation = -context.get_translation();
-if(state == BT_SHOW_INFO)
- {
- Vector offset;
- if(pos.x + tanslation.x < 100 && pos.y + tanslation.y > SCREEN_HEIGHT - 20)
- offset = Vector(size.x, - 10);
- else if(pos.x + tanslation.x < 100)
- offset = Vector(size.x, 0);
- else
- offset = Vector(-30, -size.y/2);
- context.draw_text(info_font, info, pos + offset, ALIGN_LEFT, LAYER_GUI+2);
- if(binding != 0)
- context.draw_text(info_font, "(" + std::string(SDL_GetKeyName(binding)) +
- ")", pos + offset + Vector(0,12),
- ALIGN_LEFT, LAYER_GUI+2);
- }
-
-context.draw_surface_part(image, Vector(0,0), size, pos, LAYER_GUI+1);
-}
-
-int Button::event(SDL_Event &event, int x_offset, int y_offset)
-{
-state = BT_NONE;
-switch(event.type)
- {
- case SDL_MOUSEBUTTONDOWN:
- if(event.button.x > pos.x + x_offset && event.button.x < pos.x + x_offset + size.x &&
- event.button.y > pos.y + y_offset && event.button.y < pos.y + y_offset + size.y)
- {
- if(event.button.button == SDL_BUTTON_RIGHT)
- state = BT_SHOW_INFO;
- }
- break;
- case SDL_MOUSEBUTTONUP:
- if(event.button.x > pos.x + x_offset && event.button.x < pos.x + x_offset + size.x &&
- event.button.y > pos.y + y_offset && event.button.y < pos.y + y_offset + size.y)
- {
- if(event.button.button == SDL_BUTTON_LEFT)
- state = BT_SELECTED;
- }
- break;
- case SDL_KEYDOWN: // key pressed
- if(event.key.keysym.sym == binding)
- state = BT_SELECTED;
- break;
- default:
- break;
- }
-return state;
-}
-
-/* Group of buttons */
-
-ButtonGroup::ButtonGroup(Vector pos_, Vector buttons_size_, Vector buttons_box_)
- : pos(pos_), buttons_size(buttons_size_), buttons_box(buttons_box_)
-{
-buttons.clear();
-row = 0;
-button_selected = -1;
-mouse_hover = false;
-mouse_left_button = false;
-buttons_pair_nb = 0;
-}
-
-ButtonGroup::~ButtonGroup()
-{
-}
-
-void ButtonGroup::add_button(Button button, int id, bool select)
-{
-button.pos.x = ((buttons.size()-buttons_pair_nb) % (int)buttons_box.x) * buttons_size.x;
-button.pos.y = ((int)((buttons.size()-buttons_pair_nb) / buttons_box.x)) * buttons_size.y;
-button.size = buttons_size;
-button.id = id;
-if(select)
- button_selected = id;
-
-buttons.push_back(button);
-}
-
-void ButtonGroup::add_pair_of_buttons(Button button1, int id1, Button button2, int id2)
-{
-button1.pos.x = button2.pos.x = ((buttons.size()-buttons_pair_nb) % (int)buttons_box.x) * buttons_size.x;
-button1.pos.y = button2.pos.y = ((int)((buttons.size()-buttons_pair_nb) / buttons_box.x)) * buttons_size.y;
-button1.size.x = button2.size.x = buttons_size.x;
-button1.size.y = button2.size.y = buttons_size.y / 2;
-button2.pos.y += buttons_size.y / 2;
-button1.id = id1;
-button2.id = id2;
-
-buttons_pair_nb++;
-buttons.push_back(button1);
-buttons.push_back(button2);
-}
-
-void ButtonGroup::draw(DrawingContext &context)
-{
-context.draw_filled_rect(pos - Vector(12,4),
- Vector(buttons_size.x*buttons_box.x + 16, buttons_size.y*buttons_box.y + 8),
- Color (0,0,0, 128), LAYER_GUI-1);
-
-context.push_transform();
-context.set_translation(Vector(-pos.x, -pos.y + buttons_size.y*row));
-for(Buttons::iterator i = buttons.begin(); i != buttons.end(); ++i)
- {
- if(i->pos.y < row*buttons_size.y ||
- i->pos.y + i->size.y > (row + buttons_box.y) * buttons_size.y)
- continue;
-
- i->draw(context, i->id == button_selected);
- }
-context.pop_transform();
-}
-
-bool ButtonGroup::event(SDL_Event &event)
-{
-bool caught_event = false;
-
-switch(event.type)
- {
- case SDL_MOUSEMOTION:
- mouse_hover = false;
-
- if(mouse_left_button)
- {
- pos.x += int(event.motion.xrel * float(SCREEN_WIDTH)/screen->w);
- pos.y += int(event.motion.yrel * float(SCREEN_HEIGHT)/screen->h);
- caught_event = true;
- }
- if(event.button.x > pos.x-12 && event.button.x < pos.x+16 + buttons_box.x*buttons_size.x &&
- event.button.y > pos.y-4 && event.button.y < pos.y+8 + buttons_box.y*buttons_size.y)
- mouse_hover = true;
- break;
- case SDL_MOUSEBUTTONDOWN:
- if(event.button.x < pos.x-12 || event.button.x > pos.x+16 +
- buttons_box.x*buttons_size.x || event.button.y < pos.y-4 ||
- event.button.y > pos.y+8 + buttons_box.y*buttons_size.y)
- break;
-
- caught_event = true;
-
- if(event.button.button == SDL_BUTTON_WHEELUP)
- {
- row--;
- if(row < 0)
- row = 0;
- }
- else if(event.button.button == SDL_BUTTON_WHEELDOWN)
- {
- row++;
- if(row > (int)((buttons.size()-buttons_pair_nb)/buttons_box.x) - (int)buttons_box.y +
- ((int)(buttons.size()-buttons_pair_nb)%(int)buttons_box.x != 0 ? 1 : 0))
- row = (int)((buttons.size()-buttons_pair_nb)/buttons_box.x) - (int)buttons_box.y +
- ((int)(buttons.size()-buttons_pair_nb)%(int)buttons_box.x != 0 ? 1 : 0);
- }
- else if(event.button.button == SDL_BUTTON_LEFT)
- mouse_left_button = true;
- else
- caught_event = false;
- break;
- case SDL_MOUSEBUTTONUP:
- mouse_left_button = false;
- break;
- default:
- break;
- }
-
-if(caught_event)
- return true;
-
-for(Buttons::iterator i = buttons.begin(); i != buttons.end(); ++i)
- {
- if(i->pos.y < row*buttons_size.y ||
- i->pos.y + i->size.y > (row + buttons_box.y) * buttons_size.y)
- continue;
-
- if(i->event(event, (int)pos.x,
- (int)pos.y - row*(int)buttons_size.y) == BT_SELECTED)
- {
- button_selected = i->id;
- caught_event = true;
- break;
- }
- }
-
-return caught_event;
-}
-
-int ButtonGroup::selected_id()
-{
-return button_selected;
-}
-
-void ButtonGroup::set_unselected()
-{
-button_selected = -1;
-}
-
-bool ButtonGroup::is_hover()
-{
-return mouse_hover;
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef SUPERTUX_BUTTON_H
-#define SUPERTUX_BUTTON_H
-
-#include <vector>
-#include <string>
-
-#include "math/vector.hpp"
-#include "video/drawing_context.hpp"
-
-class Surface;
-
-class ButtonGroup;
-
-enum {
- BT_NONE,
- BT_HOVER,
- BT_SELECTED,
- BT_SHOW_INFO
- };
-
-class Button
-{
-public:
- Button(Surface* image_, std::string info_, SDLKey binding_);
- ~Button();
-
- void draw(DrawingContext& context, bool selected);
- int event(SDL_Event& event, int x_offset = 0, int y_offset = 0);
-
- static Font* info_font;
-
-private:
- friend class ButtonGroup;
-
- Vector pos, size;
-
- Surface* image;
- SDLKey binding;
-
- int id;
- int state;
- std::string info;
-};
-
-class ButtonGroup
-{
-public:
- ButtonGroup(Vector pos_, Vector size_, Vector button_box_);
- ~ButtonGroup();
-
- void draw(DrawingContext& context);
- bool event(SDL_Event& event);
-
- void add_button(Button button, int id, bool select = false);
- void add_pair_of_buttons(Button button1, int id1, Button button2, int id2);
-
- int selected_id();
- void set_unselected();
- bool is_hover();
-
-private:
- Vector pos, buttons_size, buttons_box;
- typedef std::vector <Button> Buttons;
- Buttons buttons;
-
- int button_selected, row;
- bool mouse_hover, mouse_left_button;
-
- int buttons_pair_nb;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include <sys/types.h>
-#include <ctype.h>
-
-#include <iostream>
-#include <sstream>
-#include <cstdlib>
-#include <cstdio>
-#include <string>
-#include <cassert>
-#include <stdexcept>
-
-#include "menu.hpp"
-#include "mainloop.hpp"
-#include "video/drawing_context.hpp"
-#include "gettext.hpp"
-#include "math/vector.hpp"
-#include "main.hpp"
-#include "resources.hpp"
-#include "timer.hpp"
-#include "control/joystickkeyboardcontroller.hpp"
-
-static const float MENU_REPEAT_INITIAL = 0.4f;
-static const float MENU_REPEAT_RATE = 0.2f;
-static const float FLICK_CURSOR_TIME = 0.5f;
-
-extern SDL_Surface* screen;
-
-std::vector<Menu*> Menu::last_menus;
-Menu* Menu::current_ = 0;
-Font* Menu::default_font;
-Font* Menu::active_font;
-Font* Menu::deactive_font;
-Font* Menu::label_font;
-Font* Menu::field_font;
-
-/* just displays a Yes/No text that can be used to confirm stuff */
-bool confirm_dialog(Surface *background, std::string text)
-{
- //Surface* cap_screen = Surface::CaptureScreen();
- Menu* dialog = new Menu;
- dialog->add_deactive(-1, text);
- dialog->add_hl();
- dialog->add_entry(true, _("Yes"));
- dialog->add_entry(false, _("No"));
- dialog->add_hl();
-
- Menu::set_current(dialog);
-
- DrawingContext context;
-
- // TODO make this a screen and not another mainloop...
- while(true)
- {
- SDL_Event event;
- while (SDL_PollEvent(&event)) {
- if(event.type == SDL_QUIT)
- main_loop->quit();
- main_controller->process_event(event);
- dialog->event(event);
- }
-
- if(background == NULL)
- context.draw_gradient(Color(0.8f, 0.95f, 0.85f), Color(0.8f, 0.8f, 0.8f),
- LAYER_BACKGROUND0);
- else
- context.draw_surface(background, Vector(0,0), LAYER_BACKGROUND0);
-
- dialog->draw(context);
- dialog->update();
-
- switch (dialog->check())
- {
- case true:
- //delete cap_screen;
- Menu::set_current(0);
- delete dialog;
- return true;
- break;
- case false:
- //delete cap_screen;
- Menu::set_current(0);
- delete dialog;
- return false;
- break;
- default:
- break;
- }
-
- mouse_cursor->draw(context);
- context.do_drawing();
- SDL_Delay(25);
- }
-
- return false;
-}
-
-void
-Menu::push_current(Menu* pmenu)
-{
- if (current_)
- last_menus.push_back(current_);
-
- current_ = pmenu;
- current_->effect_time = real_time;
-}
-
-void
-Menu::pop_current()
-{
- if (last_menus.size() >= 1) {
- current_ = last_menus.back();
- current_->effect_time = real_time;
- last_menus.pop_back();
- } else {
- current_ = 0;
- }
-}
-
-void
-Menu::set_current(Menu* menu)
-{
- last_menus.clear();
-
- if (menu)
- menu->effect_time = real_time;
-
- current_ = menu;
- // just to be sure...
- main_controller->reset();
-}
-
-MenuItem::MenuItem(MenuItemKind _kind, int _id)
- : kind(_kind) , id(_id)
-{
- toggled = false;
- selected = false;
- target_menu = 0;
-}
-
-void
-MenuItem::change_text(const std::string& text_)
-{
- text = text_;
-}
-
-void
-MenuItem::change_input(const std::string& text_)
-{
- input = text_;
-}
-
-std::string MenuItem::get_input_with_symbol(bool active_item)
-{
- if(!active_item) {
- input_flickering = true;
- } else {
- input_flickering = ((int) (real_time / FLICK_CURSOR_TIME)) % 2;
- }
-
- char str[1024];
- if(input_flickering)
- snprintf(str, sizeof(str), "%s ",input.c_str());
- else
- snprintf(str, sizeof(str), "%s_",input.c_str());
-
- std::string string = str;
-
- return string;
-}
-
-Menu::~Menu()
-{
- for(std::vector<MenuItem*>::iterator i = items.begin();
- i != items.end(); ++i)
- delete *i;
- if(current_ == this)
- current_ = NULL;
-}
-
-Menu::Menu()
-{
- hit_item = -1;
- menuaction = MENU_ACTION_NONE;
- delete_character = 0;
- mn_input_char = '\0';
-
- pos_x = SCREEN_WIDTH/2;
- pos_y = SCREEN_HEIGHT/2;
- arrange_left = 0;
- active_item = -1;
-
- checkbox.reset(new Surface("images/engine/menu/checkbox-unchecked.png"));
- checkbox_checked.reset(new Surface("images/engine/menu/checkbox-checked.png"));
- back.reset(new Surface("images/engine/menu/arrow-back.png"));
- arrow_left.reset(new Surface("images/engine/menu/arrow-left.png"));
- arrow_right.reset(new Surface("images/engine/menu/arrow-right.png"));
-}
-
-void Menu::set_pos(float x, float y, float rw, float rh)
-{
- pos_x = x + get_width() * rw;
- pos_y = y + get_height() * rh;
-}
-
-/* Add an item to a menu */
-void
-Menu::additem(MenuItem* item)
-{
- items.push_back(item);
-
- /* If a new menu is being built, the active item shouldn't be set to
- * something that isnt selectable. Set the active_item to the first
- * selectable item added
- */
- if (active_item == -1
- && item->kind != MN_HL
- && item->kind != MN_LABEL
- && item->kind != MN_DEACTIVE) {
- active_item = items.size() - 1;
- }
-}
-
-void
-Menu::add_hl()
-{
- additem(new MenuItem(MN_HL));
-}
-
-void
-Menu::add_label(const std::string& text)
-{
- MenuItem* item = new MenuItem(MN_LABEL);
- item->text = text;
- additem(item);
-}
-
-void
-Menu::add_controlfield(int id, const std::string& text,
- const std::string& mapping)
-{
- MenuItem* item = new MenuItem(MN_CONTROLFIELD, id);
- item->change_text(text);
- item->change_input(mapping);
- additem(item);
-}
-
-void
-Menu::add_entry(int id, const std::string& text)
-{
- MenuItem* item = new MenuItem(MN_ACTION, id);
- item->text = text;
- additem(item);
-}
-
-void
-Menu::add_deactive(int id, const std::string& text)
-{
- MenuItem* item = new MenuItem(MN_DEACTIVE, id);
- item->text = text;
- additem(item);
-}
-
-void
-Menu::add_toggle(int id, const std::string& text, bool toogled)
-{
- MenuItem* item = new MenuItem(MN_TOGGLE, id);
- item->text = text;
- item->toggled = toogled;
- additem(item);
-}
-
-void
-Menu::add_back(const std::string& text)
-{
- MenuItem* item = new MenuItem(MN_BACK);
- item->text = text;
- additem(item);
-}
-
-void
-Menu::add_submenu(const std::string& text, Menu* submenu, int id)
-{
- MenuItem* item = new MenuItem(MN_GOTO, id);
- item->text = text;
- item->target_menu = submenu;
- additem(item);
-}
-
-void
-Menu::clear()
-{
- for(std::vector<MenuItem*>::iterator i = items.begin();
- i != items.end(); ++i) {
- delete *i;
- }
- items.clear();
- active_item = -1;
-}
-
-/* Process actions done on the menu */
-void
-Menu::update()
-{
- /** check main input controller... */
- if(main_controller->pressed(Controller::UP)) {
- menuaction = MENU_ACTION_UP;
- menu_repeat_time = real_time + MENU_REPEAT_INITIAL;
- }
- if(main_controller->hold(Controller::UP) &&
- menu_repeat_time != 0 && real_time > menu_repeat_time) {
- menuaction = MENU_ACTION_UP;
- menu_repeat_time = real_time + MENU_REPEAT_RATE;
- }
- if(main_controller->pressed(Controller::DOWN)) {
- menuaction = MENU_ACTION_DOWN;
- menu_repeat_time = real_time + MENU_REPEAT_INITIAL;
- }
- if(main_controller->hold(Controller::DOWN) &&
- menu_repeat_time != 0 && real_time > menu_repeat_time) {
- menuaction = MENU_ACTION_DOWN;
- menu_repeat_time = real_time + MENU_REPEAT_RATE;
- }
- if(main_controller->pressed(Controller::ACTION)
- || main_controller->pressed(Controller::MENU_SELECT)) {
- menuaction = MENU_ACTION_HIT;
- }
- if(main_controller->pressed(Controller::PAUSE_MENU)) {
- menuaction = MENU_ACTION_BACK;
- }
-
- hit_item = -1;
- if(items.size() == 0)
- return;
-
- int last_active_item = active_item;
- switch(menuaction) {
- case MENU_ACTION_UP:
- do {
- if (active_item > 0)
- --active_item;
- else
- active_item = int(items.size())-1;
- } while ((items[active_item]->kind == MN_HL
- || items[active_item]->kind == MN_LABEL
- || items[active_item]->kind == MN_DEACTIVE)
- && (active_item != last_active_item));
-
- break;
-
- case MENU_ACTION_DOWN:
- do {
- if(active_item < int(items.size())-1 )
- ++active_item;
- else
- active_item = 0;
- } while ((items[active_item]->kind == MN_HL
- || items[active_item]->kind == MN_LABEL
- || items[active_item]->kind == MN_DEACTIVE)
- && (active_item != last_active_item));
-
- break;
-
- case MENU_ACTION_LEFT:
- if(items[active_item]->kind == MN_STRINGSELECT) {
- if(items[active_item]->selected > 0)
- items[active_item]->selected--;
- else
- items[active_item]->selected = items[active_item]->list.size()-1;
- }
- break;
-
- case MENU_ACTION_RIGHT:
- if(items[active_item]->kind == MN_STRINGSELECT) {
- if(items[active_item]->selected+1 < items[active_item]->list.size())
- items[active_item]->selected++;
- else
- items[active_item]->selected = 0;
- }
- break;
-
- case MENU_ACTION_HIT: {
- hit_item = active_item;
- switch (items[active_item]->kind) {
- case MN_GOTO:
- assert(items[active_item]->target_menu != 0);
- Menu::push_current(items[active_item]->target_menu);
- break;
-
- case MN_TOGGLE:
- items[active_item]->toggled = !items[active_item]->toggled;
- menu_action(items[active_item]);
- break;
-
- case MN_CONTROLFIELD:
- menu_action(items[active_item]);
- break;
-
- case MN_ACTION:
- menu_action(items[active_item]);
- break;
-
- case MN_TEXTFIELD:
- case MN_NUMFIELD:
- menuaction = MENU_ACTION_DOWN;
- update();
- break;
-
- case MN_BACK:
- Menu::pop_current();
- break;
- default:
- break;
- }
- break;
- }
-
- case MENU_ACTION_REMOVE:
- if(items[active_item]->kind == MN_TEXTFIELD
- || items[active_item]->kind == MN_NUMFIELD)
- {
- if(!items[active_item]->input.empty())
- {
- int i = items[active_item]->input.size();
-
- while(delete_character > 0) /* remove charactes */
- {
- items[active_item]->input.resize(i-1);
- delete_character--;
- }
- }
- }
- break;
-
- case MENU_ACTION_INPUT:
- if(items[active_item]->kind == MN_TEXTFIELD
- || (items[active_item]->kind == MN_NUMFIELD
- && mn_input_char >= '0' && mn_input_char <= '9'))
- {
- items[active_item]->input.push_back(mn_input_char);
- }
- break;
-
- case MENU_ACTION_BACK:
- Menu::pop_current();
- break;
-
- case MENU_ACTION_NONE:
- break;
- }
- menuaction = MENU_ACTION_NONE;
-
- assert(active_item < int(items.size()));
-}
-
-int
-Menu::check()
-{
- if (hit_item != -1)
- return items[hit_item]->id;
- else
- return -1;
-}
-
-void
-Menu::menu_action(MenuItem* )
-{}
-
-void
-Menu::draw_item(DrawingContext& context, int index)
-{
- float menu_height = get_height();
- float menu_width = get_width();
-
- MenuItem& pitem = *(items[index]);
-
- int effect_offset = 0;
- if(effect_time != 0) {
- if(real_time - effect_time > 0.5) {
- effect_time = 0;
- } else {
- float effect_delta = (0.5 - (real_time - effect_time)) * 250;
- effect_offset = (int) ((index % 2) ? effect_delta : -effect_delta);
- }
- }
-
- Font* text_font = default_font;
- float x_pos = pos_x;
- float y_pos = pos_y + 24*index - menu_height/2 + 12 + effect_offset;
- int shadow_size = 2;
- int text_width = int(text_font->get_text_width(pitem.text));
- int input_width = int(text_font->get_text_width(pitem.input) + 10);
- int list_width = 0;
- if(pitem.list.size() > 0) {
- list_width = (int) text_font->get_text_width(pitem.list[pitem.selected]);
- }
-
- if (arrange_left)
- x_pos += 24 - menu_width/2 + (text_width + input_width + list_width)/2;
-
- if(index == active_item)
- {
- shadow_size = 3;
- text_font = active_font;
- }
-
- switch (pitem.kind)
- {
- case MN_DEACTIVE:
- {
- context.draw_text(deactive_font, pitem.text,
- Vector(SCREEN_WIDTH/2, y_pos - int(deactive_font->get_height()/2)),
- ALIGN_CENTER, LAYER_GUI);
- break;
- }
-
- case MN_HL:
- {
- // TODO
- float x = pos_x - menu_width/2;
- float y = y_pos - 12 - effect_offset;
- /* Draw a horizontal line with a little 3d effect */
- context.draw_filled_rect(Vector(x, y + 6),
- Vector(menu_width, 4),
- Color(0.6f, 0.7f, 1.0f, 1.0f), LAYER_GUI);
- context.draw_filled_rect(Vector(x, y + 6),
- Vector(menu_width, 2),
- Color(1.0f, 1.0f, 1.0f, 1.0f), LAYER_GUI);
- break;
- }
- case MN_LABEL:
- {
- context.draw_text(label_font, pitem.text,
- Vector(SCREEN_WIDTH/2, y_pos - int(label_font->get_height()/2)),
- ALIGN_CENTER, LAYER_GUI);
- break;
- }
- case MN_TEXTFIELD:
- case MN_NUMFIELD:
- case MN_CONTROLFIELD:
- {
- float width = text_width + input_width + 5;
- float text_pos = SCREEN_WIDTH/2 - width/2;
- float input_pos = text_pos + text_width + 10;
-
- context.draw_filled_rect(
- Vector(input_pos - 5, y_pos - 10),
- Vector(input_width + 10, 20),
- Color(1.0f, 1.0f, 1.0f, 1.0f), LAYER_GUI-5);
- context.draw_filled_rect(
- Vector(input_pos - 4, y_pos - 9),
- Vector(input_width + 8, 18),
- Color(0, 0, 0, 0.5f), LAYER_GUI-4);
-
- if(pitem.kind == MN_TEXTFIELD || pitem.kind == MN_NUMFIELD)
- {
- if(active_item == index)
- context.draw_text(field_font,
- pitem.get_input_with_symbol(true),
- Vector(input_pos, y_pos - int(field_font->get_height()/2)),
- ALIGN_LEFT, LAYER_GUI);
- else
- context.draw_text(field_font,
- pitem.get_input_with_symbol(false),
- Vector(input_pos, y_pos - int(field_font->get_height()/2)),
- ALIGN_LEFT, LAYER_GUI);
- }
- else
- context.draw_text(field_font, pitem.input,
- Vector(input_pos, y_pos - int(field_font->get_height()/2)),
- ALIGN_LEFT, LAYER_GUI);
-
- context.draw_text(text_font, pitem.text,
- Vector(text_pos, y_pos - int(text_font->get_height()/2)),
- ALIGN_LEFT, LAYER_GUI);
- break;
- }
- case MN_STRINGSELECT:
- {
- int list_pos_2 = list_width + 16;
- int list_pos = list_width/2;
- int text_pos = (text_width + 16)/2;
-
- /* Draw arrows */
- context.draw_surface(arrow_left.get(),
- Vector(x_pos - list_pos + text_pos - 17, y_pos - 8),
- LAYER_GUI);
- context.draw_surface(arrow_right.get(),
- Vector(x_pos - list_pos + text_pos - 1 + list_pos_2, y_pos - 8),
- LAYER_GUI);
-
- /* Draw input background */
- context.draw_filled_rect(
- Vector(x_pos - list_pos + text_pos - 1, y_pos - 10),
- Vector(list_pos_2 + 2, 20),
- Color(1.0f, 1.0f, 1.0f, 1.0f), LAYER_GUI - 4);
- context.draw_filled_rect(
- Vector(x_pos - list_pos + text_pos, y_pos - 9),
- Vector(list_pos_2, 18),
- Color(0, 0, 0, 0.5f), LAYER_GUI - 5);
-
- context.draw_text(text_font, pitem.list[pitem.selected],
- Vector(SCREEN_WIDTH/2 + text_pos, y_pos - int(text_font->get_height()/2)),
- ALIGN_CENTER, LAYER_GUI);
- context.draw_text(text_font, pitem.text,
- Vector(SCREEN_WIDTH/2 + list_pos_2/2, y_pos - int(text_font->get_height()/2)),
- ALIGN_CENTER, LAYER_GUI);
- break;
- }
- case MN_BACK:
- {
- context.draw_text(text_font, pitem.text,
- Vector(SCREEN_WIDTH/2, y_pos - int(text_font->get_height()/2)),
- ALIGN_CENTER, LAYER_GUI);
- context.draw_surface(back.get(),
- Vector(x_pos + text_width/2 + 16, y_pos - 8),
- LAYER_GUI);
- break;
- }
-
- case MN_TOGGLE:
- {
- context.draw_text(text_font, pitem.text,
- Vector(SCREEN_WIDTH/2, y_pos - (text_font->get_height()/2)),
- ALIGN_CENTER, LAYER_GUI);
-
- if(pitem.toggled)
- context.draw_surface(checkbox_checked.get(),
- Vector(x_pos + (text_width+16)/2, y_pos - 8),
- LAYER_GUI + 1);
- else
- context.draw_surface(checkbox.get(),
- Vector(x_pos + (text_width+16)/2, y_pos - 8),
- LAYER_GUI + 1);
- break;
- }
- case MN_ACTION:
- context.draw_text(text_font, pitem.text,
- Vector(SCREEN_WIDTH/2, y_pos - int(text_font->get_height()/2)),
- ALIGN_CENTER, LAYER_GUI);
- break;
-
- case MN_GOTO:
- context.draw_text(text_font, pitem.text,
- Vector(SCREEN_WIDTH/2, y_pos - int(text_font->get_height()/2)),
- ALIGN_CENTER, LAYER_GUI);
- break;
- }
-}
-
-float Menu::get_width() const
-{
- /* The width of the menu has to be more than the width of the text
- with the most characters */
- float menu_width = 0;
- for(unsigned int i = 0; i < items.size(); ++i)
- {
- Font* font = default_font;
- if(items[i]->kind == MN_LABEL)
- font = label_font;
-
- float w = font->get_text_width(items[i]->text) +
- label_font->get_text_width(items[i]->input) + 16;
- if(items[i]->kind == MN_TOGGLE)
- w += 32;
-
- if(w > menu_width)
- menu_width = w;
- }
-
- return menu_width + 24;
-}
-
-float Menu::get_height() const
-{
- return items.size() * 24;
-}
-
-/* Draw the current menu. */
-void
-Menu::draw(DrawingContext& context)
-{
- if(MouseCursor::current()) {
- MouseCursor::current()->draw(context);
- }
-
- float menu_height = get_height();
- float menu_width = get_width();
-
- /* Draw a transparent background */
- context.draw_filled_rect(
- Vector(pos_x - menu_width/2, pos_y - 24*items.size()/2 - 10),
- Vector(menu_width,menu_height + 20),
- Color(0.6f, 0.7f, 0.8f, 0.5f), LAYER_GUI-10);
-
- for(unsigned int i = 0; i < items.size(); ++i)
- {
- draw_item(context, i);
- }
-}
-
-MenuItem&
-Menu::get_item_by_id(int id)
-{
- for(std::vector<MenuItem*>::iterator i = items.begin();
- i != items.end(); ++i) {
- MenuItem& item = **i;
-
- if(item.id == id)
- return item;
- }
-
- throw std::runtime_error("MenuItem not found");
-}
-
-const MenuItem&
-Menu::get_item_by_id(int id) const
-{
- for(std::vector<MenuItem*>::const_iterator i = items.begin();
- i != items.end(); ++i) {
- const MenuItem& item = **i;
-
- if(item.id == id)
- return item;
- }
-
- throw std::runtime_error("MenuItem not found");
-}
-
-int Menu::get_active_item_id()
-{
- return items[active_item]->id;
-}
-
-bool
-Menu::is_toggled(int id) const
-{
- return get_item_by_id(id).toggled;
-}
-
-/* Check for menu event */
-void
-Menu::event(const SDL_Event& event)
-{
- if(effect_time != 0)
- return;
-
- switch(event.type) {
- case SDL_MOUSEBUTTONDOWN:
- {
- int x = int(event.motion.x * float(SCREEN_WIDTH)/screen->w);
- int y = int(event.motion.y * float(SCREEN_HEIGHT)/screen->h);
-
- if(x > pos_x - get_width()/2 &&
- x < pos_x + get_width()/2 &&
- y > pos_y - get_height()/2 &&
- y < pos_y + get_height()/2)
- {
- menuaction = MENU_ACTION_HIT;
- }
- }
- break;
-
- case SDL_MOUSEMOTION:
- {
- float x = event.motion.x * SCREEN_WIDTH/screen->w;
- float y = event.motion.y * SCREEN_HEIGHT/screen->h;
-
- if(x > pos_x - get_width()/2 &&
- x < pos_x + get_width()/2 &&
- y > pos_y - get_height()/2 &&
- y < pos_y + get_height()/2)
- {
- int new_active_item
- = static_cast<int> ((y - (pos_y - get_height()/2)) / 24);
-
- /* only change the mouse focus to a selectable item */
- if ((items[new_active_item]->kind != MN_HL)
- && (items[new_active_item]->kind != MN_LABEL)
- && (items[new_active_item]->kind != MN_DEACTIVE))
- active_item = new_active_item;
-
- if(MouseCursor::current())
- MouseCursor::current()->set_state(MC_LINK);
- }
- else
- {
- if(MouseCursor::current())
- MouseCursor::current()->set_state(MC_NORMAL);
- }
- }
- break;
-
- default:
- break;
- }
-}
-
-void
-Menu::set_active_item(int id)
-{
- for(size_t i = 0; i < items.size(); ++i) {
- MenuItem* item = items[i];
- if(item->id == id) {
- active_item = i;
- break;
- }
- }
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef SUPERTUX_MENU_H
-#define SUPERTUX_MENU_H
-
-#include <vector>
-#include <memory>
-#include <set>
-#include <string>
-#include <utility>
-#include <assert.h>
-
-#include <SDL.h>
-
-#include "video/surface.hpp"
-#include "video/font.hpp"
-#include "mousecursor.hpp"
-
-bool confirm_dialog(Surface* background, std::string text);
-
-/* Kinds of menu items */
-enum MenuItemKind {
- MN_ACTION,
- MN_GOTO,
- MN_TOGGLE,
- MN_BACK,
- MN_DEACTIVE,
- MN_TEXTFIELD,
- MN_NUMFIELD,
- MN_CONTROLFIELD,
- MN_STRINGSELECT,
- MN_LABEL,
- MN_HL, /* horizontal line */
-};
-
-class Menu;
-
-class MenuItem
-{
-public:
- MenuItem(MenuItemKind kind, int id = -1);
- MenuItemKind kind;
- int id; // item id
- bool toggled;
- std::string text;
- std::string input;
-
- std::vector<std::string> list; // list of values for a STRINGSELECT item
- size_t selected; // currently selected item
-
- Menu* target_menu;
-
- void change_text (const std::string& text);
- void change_input(const std::string& text);
-
- static MenuItem* create(MenuItemKind kind, const std::string& text,
- int init_toggle, Menu* target_menu, int id, int key);
-
- std::string get_input_with_symbol(bool active_item); // returns the text with an input symbol
-
-private:
- /// copy-construction not allowed
- MenuItem(const MenuItem& ) { assert(false); }
- /// assignment not allowed
- void operator= (const MenuItem& ) { assert(false); }
-
- /// keyboard key or joystick button
- bool input_flickering;
-};
-
-class Menu
-{
-private:
- static std::vector<Menu*> last_menus;
- static Menu* current_;
-
- static void pop_current();
-
-public:
- /** Set the current menu, if pmenu is NULL, hide the current menu */
- static void set_current(Menu* pmenu);
-
- static void push_current(Menu* pmenu);
-
- /** Return the current active menu or NULL if none is active */
- static Menu* current()
- {
- return current_;
- }
-
-private:
- /* Action done on the menu */
- enum MenuAction {
- MENU_ACTION_NONE = -1,
- MENU_ACTION_UP,
- MENU_ACTION_DOWN,
- MENU_ACTION_LEFT,
- MENU_ACTION_RIGHT,
- MENU_ACTION_HIT,
- MENU_ACTION_INPUT,
- MENU_ACTION_REMOVE,
- MENU_ACTION_BACK
- };
-
- /** Number of the item that got 'hit' (ie. pressed) in the last
- event()/update() call, -1 if none */
- int hit_item;
-
- // position of the menu (ie. center of the menu, not top/left)
- float pos_x;
- float pos_y;
-
- /** input event for the menu (up, down, left, right, etc.) */
- MenuAction menuaction;
-
- /* input implementation variables */
- int delete_character;
- char mn_input_char;
- float menu_repeat_time;
-
-public:
- static Font* default_font;
- static Font* active_font;
- static Font* deactive_font;
- static Font* label_font;
- static Font* field_font;
-
- std::vector<MenuItem*> items;
-
- Menu();
- virtual ~Menu();
-
- void add_hl();
- void add_label(const std::string& text);
- void add_entry(int id, const std::string& text);
- void add_toggle(int id, const std::string& text, bool toggled = false);
- void add_deactive(int id, const std::string& text);
- void add_back(const std::string& text);
- void add_submenu(const std::string& text, Menu* submenu, int id = -1);
- void add_controlfield(int id, const std::string& text,
- const std::string& mapping = "");
-
- virtual void menu_action(MenuItem* item);
-
- void update();
-
- /** Remove all entries from the menu */
- void clear();
-
- /** Return the index of the menu item that was 'hit' (ie. the user
- clicked on it) in the last event() call */
- int check ();
-
- MenuItem& get_item(int index)
- {
- return *(items[index]);
- }
- MenuItem& get_item_by_id(int id);
- const MenuItem& get_item_by_id(int id) const;
-
- int get_active_item_id();
- void set_active_item(int id);
-
- void draw(DrawingContext& context);
- void set_pos(float x, float y, float rw = 0, float rh = 0);
-
- void event(const SDL_Event& event);
-
- bool is_toggled(int id) const;
-
-protected:
- void additem(MenuItem* pmenu_item);
- float get_width() const;
- float get_height() const;
-
-private:
- void check_controlfield_change_event(const SDL_Event& event);
- void draw_item(DrawingContext& context, int index);
- float effect_time;
- int arrange_left;
- int active_item;
-
- std::auto_ptr<Surface> checkbox;
- std::auto_ptr<Surface> checkbox_checked;
- std::auto_ptr<Surface> back;
- std::auto_ptr<Surface> arrow_left;
- std::auto_ptr<Surface> arrow_right;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include <SDL_events.h>
-#include <SDL_mouse.h>
-
-#include "video/drawing_context.hpp"
-#include "gui/mousecursor.hpp"
-#include "main.hpp"
-
-MouseCursor* MouseCursor::current_ = 0;
-extern SDL_Surface* screen;
-
-MouseCursor::MouseCursor(std::string cursor_file) : mid_x(0), mid_y(0)
-{
- cursor = new Surface(cursor_file);
-
- cur_state = MC_NORMAL;
-}
-
-MouseCursor::~MouseCursor()
-{
- delete cursor;
-}
-
-int MouseCursor::state()
-{
- return cur_state;
-}
-
-void MouseCursor::set_state(int nstate)
-{
- cur_state = nstate;
-}
-
-void MouseCursor::set_mid(int x, int y)
-{
- mid_x = x;
- mid_y = y;
-}
-
-void MouseCursor::draw(DrawingContext& context)
-{
- if(cur_state == MC_HIDE)
- return;
-
- int x,y,w,h;
- Uint8 ispressed = SDL_GetMouseState(&x,&y);
-
- x = int(x * float(SCREEN_WIDTH)/screen->w);
- y = int(y * float(SCREEN_HEIGHT)/screen->h);
-
- w = (int) cursor->get_width();
- h = (int) (cursor->get_height() / MC_STATES_NB);
- if(ispressed &SDL_BUTTON(1) || ispressed &SDL_BUTTON(2)) {
- if(cur_state != MC_CLICK) {
- state_before_click = cur_state;
- cur_state = MC_CLICK;
- }
- } else {
- if(cur_state == MC_CLICK)
- cur_state = state_before_click;
- }
-
- context.draw_surface_part(cursor, Vector(0, h*cur_state),
- Vector(w, h), Vector(x-mid_x, y-mid_y), LAYER_GUI+100);
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef SUPERTUX_MOUSECURSOR_H
-#define SUPERTUX_MOUSECURSOR_H
-
-#include <string>
-
-#include "video/surface.hpp"
-
-#define MC_STATES_NB 3
-
-enum {
- MC_NORMAL = 0,
- MC_CLICK,
- MC_LINK,
- MC_HIDE
-};
-
-class DrawingContext;
-
-/// Mouse cursor.
-/** Used to create mouse cursors.
- The mouse cursors can be animated
- and can be used in four different states.
- (MC_NORMAL, MC_CLICK, MC_LINK or MC_HIDE) */
-class MouseCursor
-{
-public:
- /// Constructor of MouseCursor.
- /** Expects an imagefile for the cursor and the number of animation frames it contains. */
- MouseCursor(std::string cursor_file);
- ~MouseCursor();
- /// Get MouseCursor state.
- /** (MC_NORMAL, MC_CLICK, MC_LINK or MC_HIDE) */
- int state();
- /// Set MouseCursor state.
- /** (MC_NORMAL, MC_CLICK, MC_LINK or MC_HIDE) */
- void set_state(int nstate);
- /// Define the middle of a MouseCursor.
- /** Useful for cross mouse cursor images in example. */
- void set_mid(int x, int y);
-
- /// Draw MouseCursor on screen.
- void draw(DrawingContext& context);
-
- /// Return the current cursor.
- static MouseCursor* current()
- { return current_; };
- /// Set current cursor.
- static void set_current(MouseCursor* pcursor)
- { current_ = pcursor; };
-
-private:
- int mid_x, mid_y;
- static MouseCursor* current_;
- int state_before_click;
- int cur_state;
- Surface* cursor;
-};
-
-#endif /*SUPERTUX_MOUSECURSOR_H*/
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#include <config.h>
-
-#include <map>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <iostream>
-#include <fstream>
-#include <sstream>
-#include <memory>
-#include <stdexcept>
-
-#include "log.hpp"
-#include "lisp/parser.hpp"
-#include "lisp/lisp.hpp"
-#include "lisp/list_iterator.hpp"
-#include "lisp/writer.hpp"
-#include "level.hpp"
-#include "physic.hpp"
-#include "sector.hpp"
-#include "tile.hpp"
-#include "resources.hpp"
-#include "file_system.hpp"
-#include "object/gameobjs.hpp"
-#include "object/camera.hpp"
-#include "object/tilemap.hpp"
-#include "object/coin.hpp"
-#include "object/block.hpp"
-
-using namespace std;
-
-Level::Level()
- : name("noname"), author("Mr. X")
-{
-}
-
-void
-Level::load(const std::string& filepath)
-{
- try {
- lisp::Parser parser;
- const lisp::Lisp* root = parser.parse(filepath);
-
- const lisp::Lisp* level = root->get_lisp("supertux-level");
- if(!level)
- throw std::runtime_error("file is not a supertux-level file.");
-
- int version = 1;
- level->get("version", version);
- if(version == 1) {
- load_old_format(*level);
- return;
- }
-
- contact = "";
- license = "";
-
- lisp::ListIterator iter(level);
- while(iter.next()) {
- const std::string& token = iter.item();
- if(token == "version") {
- iter.value()->get(version);
- if(version > 2) {
- log_warning << "level format newer than application" << std::endl;
- }
- } else if(token == "name") {
- iter.value()->get(name);
- } else if(token == "author") {
- iter.value()->get(author);
- } else if(token == "contact") {
- iter.value()->get(contact);
- } else if(token == "license") {
- iter.value()->get(license);
- } else if(token == "on-menukey-script") {
- iter.value()->get(on_menukey_script);
- } else if(token == "sector") {
- Sector* sector = new Sector(this);
- sector->parse(*(iter.lisp()));
- add_sector(sector);
- } else {
- log_warning << "Unknown token '" << token << "' in level file" << std::endl;
- }
- }
-
- if (license == "") log_warning << "The level author did not specify a license for this level. You might not be allowed to share it." << std::endl;
-
- } catch(std::exception& e) {
- std::stringstream msg;
- msg << "Problem when reading level '" << filepath << "': " << e.what();
- throw std::runtime_error(msg.str());
- }
-}
-
-void
-Level::load_old_format(const lisp::Lisp& reader)
-{
- reader.get("name", name);
- reader.get("author", author);
-
- Sector* sector = new Sector(this);
- sector->parse_old_format(reader);
- add_sector(sector);
-}
-
-void
-Level::save(const std::string& filename)
-{
- lisp::Writer* writer = new lisp::Writer(filename);
-
- writer->write_comment("Level made using SuperTux's built-in Level Editor");
-
- writer->start_list("supertux-level");
-
- int version = 2;
- writer->write_int("version", version);
-
- writer->write_string("name", name, true);
- writer->write_string("author", author);
- if(on_menukey_script != "")
- writer->write_string("on-menukey-script", on_menukey_script);
-
- for(Sectors::iterator i = sectors.begin(); i != sectors.end(); ++i) {
- Sector* sector = *i;
- writer->start_list("sector");
- sector->write(*writer);
- writer->end_list("sector");
- }
-
- writer->end_list("supertux-level");
-
- delete writer;
-}
-
-Level::~Level()
-{
- for(Sectors::iterator i = sectors.begin(); i != sectors.end(); ++i)
- delete *i;
-}
-
-void
-Level::add_sector(Sector* sector)
-{
- Sector* test = get_sector(sector->get_name());
- if(test != 0) {
- throw std::runtime_error("Trying to add 2 sectors with same name");
- }
- sectors.push_back(sector);
-}
-
-Sector*
-Level::get_sector(const std::string& name)
-{
- for(Sectors::iterator i = sectors.begin(); i != sectors.end(); ++i) {
- Sector* sector = *i;
- if(sector->get_name() == name)
- return sector;
- }
-
- return 0;
-}
-
-size_t
-Level::get_sector_count()
-{
- return sectors.size();
-}
-
-Sector*
-Level::get_sector(size_t num)
-{
- return sectors.at(num);
-}
-
-int
-Level::get_total_coins()
-{
- int total_coins = 0;
- for(Sectors::iterator i = sectors.begin(); i != sectors.end(); ++i) {
- Sector* sector = *i;
- for(Sector::GameObjects::iterator o = sector->gameobjects.begin();
- o != sector->gameobjects.end(); ++o) {
- Coin* coin = dynamic_cast<Coin*> (*o);
- if(coin)
- {
- total_coins++;
- continue;
- }
- BonusBlock *block = dynamic_cast<BonusBlock*> (*o);
- if(block)
- {
- if (block->contents == BonusBlock::CONTENT_COIN)
- {
- total_coins++;
- continue;
- }
-#if 0
- // FIXME: do we want this? q.v. src/object/oneup.cpp
- else if (block->contents == BonusBlock::CONTENT_1UP)
- {
- total_coins += 100;
- continue;
- }
-#endif
- }
- }
- }
- return total_coins;
-}
-
-int
-Level::get_total_badguys()
-{
- int total_badguys = 0;
- for(Sectors::iterator i = sectors.begin(); i != sectors.end(); ++i)
- total_badguys += (*i)->get_total_badguys();
- return total_badguys;
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef SUPERTUX_LEVEL_H
-#define SUPERTUX_LEVEL_H
-
-#include <vector>
-#include <string>
-#include "statistics.hpp"
-#include "sector.hpp"
-
-namespace lisp {
-class Lisp;
-}
-
-class Level
-{
-public:
- std::string name;
- std::string author;
- std::string contact;
- std::string license;
- std::string on_menukey_script;
- typedef std::vector<Sector*> Sectors;
- Sectors sectors;
- Statistics stats;
-
-public:
- Level();
- ~Level();
-
- // loads a levelfile
- void load(const std::string& filename);
- void save(const std::string& filename);
-
- const std::string& get_name() const
- { return name; }
-
- const std::string& get_author() const
- { return author; }
-
- void add_sector(Sector* sector);
-
- Sector* get_sector(const std::string& name);
-
- size_t get_sector_count();
- Sector* get_sector(size_t num);
-
- int get_total_coins();
- int get_total_badguys();
-
- /** Get total number of GameObjects of given type */
- template<class T> int get_total_count()
- {
- int total = 0;
- for(Sectors::iterator i = sectors.begin(); i != sectors.end(); ++i) {
- total += (*i)->get_total_count<T>();
- }
- return total;
- }
-
-private:
- void load_old_format(const lisp::Lisp& reader);
-};
-
-#endif /*SUPERTUX_LEVEL_H*/
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include "level_transformer.hpp"
-#include "level.hpp"
-
-LevelTransformer::~LevelTransformer()
-{
-}
-
-void
-LevelTransformer::transform(Level* level)
-{
- for(size_t i = 0; i < level->get_sector_count(); ++i) {
- transform_sector(level->get_sector(i));
- }
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __LEVEL_TRANSFORMER_H__
-#define __LEVEL_TRANSFORMER_H__
-
-class Level;
-class Sector;
-
-/**
- * This class is an abstract interface for algorithms that transform levels in
- * some way before they are played.
- */
-class LevelTransformer
-{
-public:
- virtual ~LevelTransformer();
-
- /** transform a complete Level, the standard implementation just calls
- * transformSector on each sector in the level.
- */
- virtual void transform(Level* level);
-
- virtual void transform_sector(Sector* sector) = 0;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#include <config.h>
-
-#include <sstream>
-#include <stdexcept>
-#include <iostream>
-
-#include "lexer.hpp"
-
-namespace lisp
-{
-
-class EOFException
-{
-};
-
-Lexer::Lexer(std::istream& newstream)
- : stream(newstream), eof(false), linenumber(0)
-{
- try {
- // trigger a refill of the buffer
- c = 0;
- bufend = 0;
- nextChar();
- } catch(EOFException& ) {
- }
-}
-
-Lexer::~Lexer()
-{
-}
-
-void
-Lexer::nextChar()
-{
- ++c;
- if(c >= bufend) {
- if(eof)
- throw EOFException();
- stream.read(buffer, BUFFER_SIZE);
- size_t bytes_read = stream.gcount();
-
- c = buffer;
- bufend = buffer + bytes_read;
-
- // the following is a hack that appends an additional ' ' at the end of
- // the file to avoid problems when parsing symbols/elements and a sudden
- // EOF. This is faster than relying on unget and IMO also nicer.
- if(bytes_read == 0 || stream.eof()) {
- eof = true;
- *bufend = ' ';
- ++bufend;
- }
- }
-}
-
-Lexer::TokenType
-Lexer::getNextToken()
-{
- static const char* delims = "\"();";
-
- try {
- while(isspace(*c)) {
- if(*c == '\n')
- ++linenumber;
- nextChar();
- };
-
- token_length = 0;
-
- switch(*c) {
- case ';': // comment
- while(true) {
- nextChar();
- if(*c == '\n') {
- ++linenumber;
- break;
- }
- }
- return getNextToken(); // and again
- case '(':
- nextChar();
- return TOKEN_OPEN_PAREN;
- case ')':
- nextChar();
- return TOKEN_CLOSE_PAREN;
- case '"': { // string
- int startline = linenumber;
- try {
- while(1) {
- nextChar();
- if(*c == '"')
- break;
- else if (*c == '\r') // XXX this breaks with pure \r EOL
- continue;
- else if(*c == '\n')
- linenumber++;
- else if(*c == '\\') {
- nextChar();
- switch(*c) {
- case 'n':
- *c = '\n';
- break;
- case 't':
- *c = '\t';
- break;
- }
- }
- if(token_length < MAX_TOKEN_LENGTH)
- token_string[token_length++] = *c;
- }
- token_string[token_length] = 0;
- } catch(EOFException& ) {
- std::stringstream msg;
- msg << "Parse error in line " << startline << ": "
- << "EOF while parsing string.";
- throw std::runtime_error(msg.str());
- }
- nextChar();
- return TOKEN_STRING;
- }
- case '#': // constant
- try {
- nextChar();
-
- while(isalnum(*c) || *c == '_') {
- if(token_length < MAX_TOKEN_LENGTH)
- token_string[token_length++] = *c;
- nextChar();
- }
- token_string[token_length] = 0;
- } catch(EOFException& ) {
- std::stringstream msg;
- msg << "Parse Error in line " << linenumber << ": "
- << "EOF while parsing constant.";
- throw std::runtime_error(msg.str());
- }
-
- if(strcmp(token_string, "t") == 0)
- return TOKEN_TRUE;
- if(strcmp(token_string, "f") == 0)
- return TOKEN_FALSE;
-
- // we only handle #t and #f constants at the moment...
-
- {
- std::stringstream msg;
- msg << "Parse Error in line " << linenumber << ": "
- << "Unknown constant '" << token_string << "'.";
- throw std::runtime_error(msg.str());
- }
-
- default:
- if(isdigit(*c) || *c == '-') {
- bool have_nondigits = false;
- bool have_digits = false;
- int have_floating_point = 0;
-
- do {
- if(isdigit(*c))
- have_digits = true;
- else if(*c == '.')
- ++have_floating_point;
- else if(isalnum(*c) || *c == '_')
- have_nondigits = true;
-
- if(token_length < MAX_TOKEN_LENGTH)
- token_string[token_length++] = *c;
-
- nextChar();
- } while(!isspace(*c) && !strchr(delims, *c));
-
- token_string[token_length] = 0;
-
- // no nextChar
-
- if(have_nondigits || !have_digits || have_floating_point > 1)
- return TOKEN_SYMBOL;
- else if(have_floating_point == 1)
- return TOKEN_REAL;
- else
- return TOKEN_INTEGER;
- } else {
- do {
- if(token_length < MAX_TOKEN_LENGTH)
- token_string[token_length++] = *c;
- nextChar();
- } while(!isspace(*c) && !strchr(delims, *c));
- token_string[token_length] = 0;
-
- // no nextChar
-
- return TOKEN_SYMBOL;
- }
- }
- } catch(EOFException& ) {
- return TOKEN_EOF;
- }
-}
-
-} // end of namespace lisp
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#ifndef __LISPLEXER_H__
-#define __LISPLEXER_H__
-
-namespace lisp
-{
-
-class Lexer
-{
-public:
- enum TokenType {
- TOKEN_EOF,
- TOKEN_OPEN_PAREN,
- TOKEN_CLOSE_PAREN,
- TOKEN_SYMBOL,
- TOKEN_STRING,
- TOKEN_INTEGER,
- TOKEN_REAL,
- TOKEN_TRUE,
- TOKEN_FALSE
- };
-
- Lexer(std::istream& stream);
- ~Lexer();
-
- TokenType getNextToken();
- const char* getString() const
- { return token_string; }
- int getLineNumber() const
- { return linenumber; }
-
-private:
- enum {
- MAX_TOKEN_LENGTH = 16384,
- BUFFER_SIZE = 1024
- };
-
- inline void nextChar();
-
- std::istream& stream;
- bool eof;
- int linenumber;
- char buffer[BUFFER_SIZE+1];
- char* bufend;
- char* c;
- char token_string[MAX_TOKEN_LENGTH + 1];
- int token_length;
-};
-
-} // end of namespace lisp
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include "lisp.hpp"
-
-namespace lisp
-{
-
-Lisp::Lisp(LispType newtype)
- : type(newtype)
-{
-}
-
-Lisp::~Lisp()
-{
- // resources should be on parser obstack, so no need to delete anything
-}
-
-const Lisp*
-Lisp::get_lisp(const char* name) const
-{
- for(const Lisp* p = this; p != 0; p = p->get_cdr()) {
- const Lisp* child = p->get_car();
- if(!child || child->get_type() != TYPE_CONS)
- continue;
- const Lisp* childname = child->get_car();
- if(!childname)
- continue;
- std::string childName;
- if(!childname->get(childName))
- continue;
- if(childName == name) {
- return child->get_cdr();
- }
- }
-
- return 0;
-}
-
-void
-Lisp::print(int indent) const
-{
- for(int i = 0; i < indent; ++i)
- printf(" ");
-
- if(type == TYPE_CONS) {
- printf("(\n");
- const Lisp* lisp = this;
- while(lisp) {
- if(lisp->v.cons.car)
- lisp->v.cons.car->print(indent + 1);
- lisp = lisp->v.cons.cdr;
- }
- for(int i = 0; i < indent; ++i)
- printf(" ");
- printf(")");
- }
- if(type == TYPE_STRING) {
- printf("'%s' ", v.string);
- }
- if(type == TYPE_INTEGER) {
- printf("%d", v.integer);
- }
- if(type == TYPE_REAL) {
- printf("%f", v.real);
- }
- if(type == TYPE_SYMBOL) {
- printf("%s ", v.string);
- }
- if(type == TYPE_BOOLEAN) {
- printf("%s ", v.boolean ? "true" : "false");
- }
- printf("\n");
-}
-
-} // end of namespace lisp
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __LISPREADER_H__
-#define __LISPREADER_H__
-
-#include <string>
-#include <vector>
-#include <assert.h>
-
-namespace lisp
-{
-
-class Lisp
-{
-public:
- ~Lisp();
-
- enum LispType {
- TYPE_CONS,
- TYPE_SYMBOL,
- TYPE_INTEGER,
- TYPE_STRING,
- TYPE_REAL,
- TYPE_BOOLEAN
- };
-
- LispType get_type() const
- { return type; }
-
- const Lisp* get_car() const
- { return v.cons.car; }
- const Lisp* get_cdr() const
- { return v.cons.cdr; }
-
- bool get(std::string& val) const
- {
- if(type != TYPE_STRING && type != TYPE_SYMBOL)
- return false;
- val = v.string;
- return true;
- }
-
- std::string get_symbol() const
- {
- assert(type == TYPE_SYMBOL);
- return v.string;
- }
-
- std::string get_string() const
- {
- assert(type == TYPE_STRING);
- return v.string;
- }
-
- bool get(unsigned int& val) const
- {
- if(type != TYPE_INTEGER)
- return false;
- val = v.integer;
- return true;
- }
-
- bool get(int& val) const
- {
- if(type != TYPE_INTEGER)
- return false;
- val = v.integer;
- return true;
- }
-
- int get_int() const
- {
- assert(type == TYPE_INTEGER);
- return v.integer;
- }
-
- bool get(float& val) const
- {
- if(type != TYPE_REAL) {
- if(type == TYPE_INTEGER) {
- val = (float) v.integer;
- return true;
- }
- return false;
- }
- val = v.real;
- return true;
- }
-
- float get_float() const
- {
- assert(type == TYPE_REAL);
- return v.real;
- }
-
- bool get(bool& val) const
- {
- if(type != TYPE_BOOLEAN)
- return false;
- val = v.boolean;
- return true;
- }
-
- bool get_bool() const
- {
- assert(type == TYPE_BOOLEAN);
- return v.boolean;
- }
-
- /** conveniance functions which traverse the list until a child with a
- * specified name is found. The value part is then interpreted in a specific
- * way. The functions return true, if a child was found and could be
- * interpreted correctly, otherwise false is returned and the variable value
- * is not changed.
- * (Please note that searching the lisp structure is O(n) so these functions
- * are no good idea for performance critical areas)
- */
- template<class T>
- bool get(const char* name, T& val) const
- {
- const Lisp* lisp = get_lisp(name);
- if(!lisp)
- return false;
-
- if(lisp->get_type() != TYPE_CONS)
- return false;
- lisp = lisp->get_car();
- if(!lisp)
- return false;
- return lisp->get(val);
- }
-
- template<class T>
- bool get_vector(const char* name, std::vector<T>& vec) const
- {
- vec.clear();
-
- const Lisp* child = get_lisp(name);
- if(!child)
- return false;
-
- for( ; child != 0; child = child->get_cdr()) {
- T val;
- if(!child->get_car())
- continue;
- if(child->get_car()->get(val)) {
- vec.push_back(val);
- }
- }
-
- return true;
- }
-
- const Lisp* get_lisp(const char* name) const;
- const Lisp* get_lisp(const std::string& name) const
- { return get_lisp(name.c_str()); }
-
- // for debugging
- void print(int indent = 0) const;
-
-private:
- friend class Parser;
- Lisp(LispType newtype);
-
- LispType type;
- union
- {
- struct
- {
- const Lisp* car;
- const Lisp* cdr;
- } cons;
-
- char* string;
- int integer;
- bool boolean;
- float real;
- } v;
-};
-
-} // end of namespace lisp
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include "list_iterator.hpp"
-#include <stdexcept>
-
-namespace lisp
-{
-
-ListIterator::ListIterator(const lisp::Lisp* newlisp)
- : current_lisp(0), cur(newlisp)
-{
-}
-
-bool
-ListIterator::next()
-{
- if(cur == 0)
- return false;
-
- const lisp::Lisp* child = cur->get_car();
- if(!child)
- throw std::runtime_error("child is 0 in list entry");
- if(child->get_type() != lisp::Lisp::TYPE_CONS)
- throw std::runtime_error("Expected CONS");
- const lisp::Lisp* name = child->get_car();
- if(!name || (
- name->get_type() != lisp::Lisp::TYPE_SYMBOL
- && name->get_type() != lisp::Lisp::TYPE_STRING))
- throw std::runtime_error("Expected symbol");
- name->get(current_item);
- current_lisp = child->get_cdr();
-
- cur = cur->get_cdr();
- return true;
-}
-
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __LISP_ITERATOR_H__
-#define __LISP_ITERATOR_H__
-
-#include "lisp/lisp.hpp"
-
-namespace lisp
-{
-
-/**
- * Small and a bit hacky helper class that helps parsing lisp lists where all
- * entries are lists again themselves
- */
-class ListIterator
-{
-public:
- ListIterator(const lisp::Lisp* cur);
-
- const std::string& item() const
- { return current_item; }
- const lisp::Lisp* lisp() const
- { return current_lisp; }
- const lisp::Lisp* value() const
- { return current_lisp->get_car(); }
- bool next();
-
-private:
- std::string current_item;
- const lisp::Lisp* current_lisp;
- const lisp::Lisp* cur;
-};
-
-}
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#include <config.h>
-
-#include <sstream>
-#include <stdexcept>
-#include <fstream>
-#include <cassert>
-#include <iostream>
-
-#include "tinygettext/tinygettext.hpp"
-#include "physfs/physfs_stream.hpp"
-#include "parser.hpp"
-#include "lisp.hpp"
-#include "obstack/obstackpp.hpp"
-
-#include "gameconfig.hpp"
-
-namespace lisp
-{
-
-Parser::Parser(bool translate)
- : lexer(0), dictionary_manager(0), dictionary(0)
-{
- if(translate) {
- dictionary_manager = new TinyGetText::DictionaryManager();
- dictionary_manager->set_charset("UTF-8");
- if (config && (config->locale != "")) dictionary_manager->set_language(config->locale);
- }
-
- obstack_init(&obst);
-}
-
-Parser::~Parser()
-{
- obstack_free(&obst, NULL);
- delete lexer;
- delete dictionary_manager;
-}
-
-static std::string dirname(const std::string& filename)
-{
- std::string::size_type p = filename.find_last_of('/');
- if(p == std::string::npos)
- return "";
-
- return filename.substr(0, p+1);
-}
-
-const Lisp*
-Parser::parse(const std::string& filename)
-{
- Unison::VFS::istream in(filename);
- //IFileStreambuf ins(filename);
- //std::istream in(&ins);
-
- if(!in.good()) {
- std::stringstream msg;
- msg << "Parser problem: Couldn't open file '" << filename << "'.";
- throw std::runtime_error(msg.str());
- }
-
- if(dictionary_manager) {
- dictionary_manager->add_directory(dirname(filename));
- dictionary = & (dictionary_manager->get_dictionary());
- }
-
- return parse(in, filename);
-}
-
-const Lisp*
-Parser::parse(std::istream& stream, const std::string& sourcename)
-{
- delete lexer;
- lexer = new Lexer(stream);
-
- this->filename = sourcename;
- token = lexer->getNextToken();
-
- Lisp* result = new(obst) Lisp(Lisp::TYPE_CONS);
- result->v.cons.car = read();
- result->v.cons.cdr = 0;
-
- delete lexer;
- lexer = 0;
-
- return result;
-}
-
-void
-Parser::parse_error(const char* msg) const
-{
- std::stringstream emsg;
- emsg << "Parse Error at '" << filename << "' line " << lexer->getLineNumber()
- << ": " << msg;
- throw std::runtime_error(emsg.str());
-}
-
-const Lisp*
-Parser::read()
-{
- Lisp* result;
- switch(token) {
- case Lexer::TOKEN_EOF: {
- parse_error("Unexpected EOF.");
- }
- case Lexer::TOKEN_CLOSE_PAREN: {
- parse_error("Unexpected ')'.");
- }
- case Lexer::TOKEN_OPEN_PAREN: {
- result = new(obst) Lisp(Lisp::TYPE_CONS);
-
- token = lexer->getNextToken();
- if(token == Lexer::TOKEN_CLOSE_PAREN) {
- result->v.cons.car = 0;
- result->v.cons.cdr = 0;
- break;
- }
-
- if(token == Lexer::TOKEN_SYMBOL &&
- strcmp(lexer->getString(), "_") == 0) {
- // evaluate translation function (_ str) in place here
- token = lexer->getNextToken();
- if(token != Lexer::TOKEN_STRING)
- parse_error("Expected string after '(_'");
-
- result = new(obst) Lisp(Lisp::TYPE_STRING);
- if(dictionary) {
- std::string translation = dictionary->translate(lexer->getString());
- result->v.string = new(obst) char[translation.size()+1];
- memcpy(result->v.string, translation.c_str(), translation.size()+1);
- } else {
- size_t len = strlen(lexer->getString()) + 1;
- result->v.string = new(obst) char[len];
- memcpy(result->v.string, lexer->getString(), len);
- }
- token = lexer->getNextToken();
- if(token != Lexer::TOKEN_CLOSE_PAREN)
- parse_error("Expected ')' after '(_ string'");
- break;
- }
-
- Lisp* cur = result;
- do {
- cur->v.cons.car = read();
- if(token == Lexer::TOKEN_CLOSE_PAREN) {
- cur->v.cons.cdr = 0;
- break;
- }
- Lisp *newcur = new(obst) Lisp(Lisp::TYPE_CONS);
- cur->v.cons.cdr = newcur;
- cur = newcur;
- } while(1);
-
- break;
- }
- case Lexer::TOKEN_SYMBOL: {
- result = new(obst) Lisp(Lisp::TYPE_SYMBOL);
- size_t len = strlen(lexer->getString()) + 1;
- result->v.string = new(obst) char[len];
- memcpy(result->v.string, lexer->getString(), len);
- break;
- }
- case Lexer::TOKEN_STRING: {
- result = new(obst) Lisp(Lisp::TYPE_STRING);
- size_t len = strlen(lexer->getString()) + 1;
- result->v.string = new(obst) char[len];
- memcpy(result->v.string, lexer->getString(), len);
- break;
- }
- case Lexer::TOKEN_INTEGER:
- result = new(obst) Lisp(Lisp::TYPE_INTEGER);
- sscanf(lexer->getString(), "%d", &result->v.integer);
- break;
- case Lexer::TOKEN_REAL:
- result = new(obst) Lisp(Lisp::TYPE_REAL);
- sscanf(lexer->getString(), "%f", &result->v.real);
- break;
- case Lexer::TOKEN_TRUE:
- result = new(obst) Lisp(Lisp::TYPE_BOOLEAN);
- result->v.boolean = true;
- break;
- case Lexer::TOKEN_FALSE:
- result = new(obst) Lisp(Lisp::TYPE_BOOLEAN);
- result->v.boolean = false;
- break;
-
- default:
- // this should never happen
- assert(false);
- }
-
- token = lexer->getNextToken();
- return result;
-}
-
-} // end of namespace lisp
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __LISPPARSER_H__
-#define __LISPPARSER_H__
-
-#include <string>
-#include "lexer.hpp"
-#include "obstack/obstack.h"
-
-namespace TinyGetText {
-class Dictionary;
-class DictionaryManager;
-}
-
-namespace lisp
-{
-
-class Lisp;
-class LispFile;
-
-class Parser
-{
-public:
- Parser(bool translate = true);
- ~Parser();
-
- /**
- * Parses a lispfile and returns the s-expression structure.
- * Note that all memory is held by the parser so don't destroy the parser
- * before you are finished with the lisp tree
- */
- const Lisp* parse(const std::string& filename);
- /**
- * Same as parse but reads from a generic std::istream. The sourcename is
- * used for errormessages to indicate the source of the data.
- */
- const Lisp* parse(std::istream& stream, const std::string& sourcename);
-
-private:
- void parse_error(const char* msg) const;
- const Lisp* read();
-
- Lexer* lexer;
- std::string filename;
- TinyGetText::DictionaryManager* dictionary_manager;
- TinyGetText::Dictionary* dictionary;
- Lexer::TokenType token;
-
- struct obstack obst;
-};
-
-} // end of namespace lisp
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include <iostream>
-
-#include "writer.hpp"
-#include "physfs/physfs_stream.hpp"
-#include "log.hpp"
-
-namespace lisp
-{
-
-Writer::Writer(const std::string& filename)
-{
- out = new OFileStream(filename);
- out_owned = true;
- indent_depth = 0;
- out->precision(10);
-}
-
-Writer::Writer(std::ostream* newout)
-{
- out = newout;
- out_owned = false;
- indent_depth = 0;
- out->precision(10);
-}
-
-Writer::~Writer()
-{
- if(lists.size() > 0) {
- log_warning << "Not all sections closed in lispwriter" << std::endl;
- }
- if(out_owned)
- delete out;
-}
-
-void
-Writer::write_comment(const std::string& comment)
-{
- *out << "; " << comment << "\n";
-}
-
-void
-Writer::start_list(const std::string& listname, bool string)
-{
- indent();
- *out << '(';
- if(string)
- write_escaped_string(listname);
- else
- *out << listname;
- *out << '\n';
- indent_depth += 2;
-
- lists.push_back(listname);
-}
-
-void
-Writer::end_list(const std::string& listname)
-{
- if(lists.size() == 0) {
- log_warning << "Trying to close list '" << listname << "', which is not open" << std::endl;
- return;
- }
- if(lists.back() != listname) {
- log_warning << "trying to close list '" << listname << "' while list '" << lists.back() << "' is open" << std::endl;
- return;
- }
- lists.pop_back();
-
- indent_depth -= 2;
- indent();
- *out << ")\n";
-}
-
-void
-Writer::write_int(const std::string& name, int value)
-{
- indent();
- *out << '(' << name << ' ' << value << ")\n";
-}
-
-void
-Writer::write_float(const std::string& name, float value)
-{
- indent();
- *out << '(' << name << ' ' << value << ")\n";
-}
-
-void
-Writer::write_string(const std::string& name, const std::string& value,
- bool translatable)
-{
- indent();
- *out << '(' << name;
- if(translatable) {
- *out << " (_ ";
- write_escaped_string(value);
- *out << "))\n";
- } else {
- *out << " ";
- write_escaped_string(value);
- *out << ")\n";
- }
-}
-
-void
-Writer::write_bool(const std::string& name, bool value)
-{
- indent();
- *out << '(' << name << ' ' << (value ? "#t" : "#f") << ")\n";
-}
-
-void
-Writer::write_int_vector(const std::string& name,
- const std::vector<int>& value)
-{
- indent();
- *out << '(' << name;
- for(std::vector<int>::const_iterator i = value.begin(); i != value.end(); ++i)
- *out << " " << *i;
- *out << ")\n";
-}
-
-void
-Writer::write_int_vector(const std::string& name,
- const std::vector<unsigned int>& value)
-{
- indent();
- *out << '(' << name;
- for(std::vector<unsigned int>::const_iterator i = value.begin(); i != value.end(); ++i)
- *out << " " << *i;
- *out << ")\n";
-}
-
-void
-Writer::write_float_vector(const std::string& name,
- const std::vector<float>& value)
-{
- indent();
- *out << '(' << name;
- for(std::vector<float>::const_iterator i = value.begin(); i != value.end(); ++i)
- *out << " " << *i;
- *out << ")\n";
-}
-
-void
-Writer::write_escaped_string(const std::string& str)
-{
- *out << '"';
- for(const char* c = str.c_str(); *c != 0; ++c) {
- if(*c == '\"')
- *out << "\\\"";
- else if(*c == '\\')
- *out << "\\\\";
- else
- *out << *c;
- }
- *out << '"';
-}
-
-void
-Writer::indent()
-{
- for(int i = 0; i<indent_depth; ++i)
- *out << ' ';
-}
-
-} // end of namespace lisp
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef SUPERTUX_LISPWRITER_H
-#define SUPERTUX_LISPWRITER_H
-
-#include <iostream>
-#include <string>
-#include <vector>
-
-namespace lisp
-{
-
- class Writer
- {
- public:
- Writer(const std::string& filename);
- Writer(std::ostream* out);
- ~Writer();
-
- void write_comment(const std::string& comment);
-
- void start_list(const std::string& listname, bool string = false);
-
- void write_int(const std::string& name, int value);
- void write_float(const std::string& name, float value);
- void write_string(const std::string& name, const std::string& value,
- bool translatable = false);
- void write_bool(const std::string& name, bool value);
- void write_int_vector(const std::string& name, const std::vector<int>& value);
- void write_int_vector(const std::string& name, const std::vector<unsigned int>& value);
- void write_float_vector(const std::string& name, const std::vector<float>& value);
- // add more write-functions when needed...
-
- void end_list(const std::string& listname);
-
- private:
- void write_escaped_string(const std::string& str);
- void indent();
-
- std::ostream* out;
- bool out_owned;
- int indent_depth;
- std::vector<std::string> lists;
- };
-
-} //namespace lisp
-
-#endif //SUPERTUX_LISPWRITER_H
+++ /dev/null
-// $Id$
-//
-// SuperTux Debug Helper Functions
-// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
-//
-// 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.
-#include <config.h>
-
-#include "log.hpp"
-#include "math/vector.hpp"
-#include "math/rect.hpp"
-
-std::ostream& operator<<(std::ostream& out, const Vector& vector)
-{
- out << '[' << vector.x << ',' << vector.y << ']';
- return out;
-}
-
-std::ostream& operator<<(std::ostream& out, const Rect& rect)
-{
- out << "[" << rect.get_left() << "," << rect.get_top() << " "
- << rect.get_right() << "," << rect.get_bottom() << "]";
- return out;
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux Debug Helper Functions
-// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
-//
-// 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.
-#ifndef __SUPERTUX_MSG_H__
-#define __SUPERTUX_MSG_H__
-
-#include <iostream>
-#include <stdio.h>
-
-#include "console.hpp"
-
-#ifdef DEBUG
-
-namespace {
-
-inline std::ostream& log_debug_f(const char* file, int line) {
- Console::output << "[DEBUG] " << file << ":" << line << " ";
- return Console::output;
-}
-
-inline std::ostream& log_info_f(const char* file, int line) {
- Console::output << "[INFO] " << file << ":" << line << " ";
- return Console::output;
-}
-
-inline std::ostream& log_warning_f(const char* file, int line) {
- Console::output << "[WARNING] " << file << ":" << line << " ";
- return Console::output;
-}
-
-inline std::ostream& log_fatal_f(const char* file, int line) {
- Console::output << "[FATAL] " << file << ":" << line << " ";
- return Console::output;
-}
-
-}
-
-#define log_debug log_debug_f(__FILE__, __LINE__)
-#define log_info log_info_f(__FILE__, __LINE__)
-#define log_warning log_warning_f(__FILE__, __LINE__)
-#define log_fatal log_fatal_f(__FILE__, __LINE__)
-
-#else
-
-namespace {
-
-inline std::ostream& log_warning_f() {
- Console::output << "Warning: ";
- return Console::output;
-}
-
-inline std::ostream& log_fatal_f() {
- Console::output << "Fatal: ";
- return Console::output;
-}
-
-}
-
-#define log_debug if (0) std::cerr
-#define log_info std::cout
-#define log_warning log_warning_f()
-#define log_fatal log_fatal_f()
-
-#endif
-
-class Vector;
-std::ostream& operator<< (std::ostream& str, const Vector& vector);
-class Rect;
-std::ostream& operator<< (std::ostream& str, const Rect& rect);
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#include <config.h>
-#include <assert.h>
-
-#include "log.hpp"
-#include "main.hpp"
-
-#include <stdexcept>
-#include <sstream>
-#include <ctime>
-#include <cstdlib>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <unistd.h>
-//#include <physfs.h>
-#include <SDL.h>
-//#include <SDL_image.h>
-
-#ifdef MACOSX
-namespace supertux_apple {
-#include <CoreFoundation/CoreFoundation.h>
-}
-#endif
-
-#include <unison/video/Window.hpp>
-#include <unison/vfs/FileSystem.hpp>
-
-#include "gameconfig.hpp"
-#include "resources.hpp"
-#include "gettext.hpp"
-#include "audio/sound_manager.hpp"
-#include "video/surface.hpp"
-//#include "video/texture_manager.hpp"
-#include "video/drawing_context.hpp"
-#include "video/glutil.hpp"
-#include "control/joystickkeyboardcontroller.hpp"
-#include "options_menu.hpp"
-#include "mainloop.hpp"
-#include "title.hpp"
-#include "game_session.hpp"
-#include "scripting/level.hpp"
-#include "scripting/squirrel_util.hpp"
-#include "file_system.hpp"
-#include "physfs/physfs_sdl.hpp"
-#include "random_generator.hpp"
-#include "worldmap/worldmap.hpp"
-#include "binreloc/binreloc.h"
-
-namespace { DrawingContext *context_pointer; }
-SDL_Surface *screen;
-JoystickKeyboardController* main_controller = 0;
-TinyGetText::DictionaryManager dictionary_manager;
-
-int SCREEN_WIDTH;
-int SCREEN_HEIGHT;
-
-static void init_config()
-{
- config = new Config();
- try {
- config->load();
- } catch(std::exception& e) {
- log_info << "Couldn't load config file: " << e.what() << ", using default settings" << std::endl;
- }
-}
-
-static void init_tinygettext()
-{
- dictionary_manager.add_directory("locale");
- dictionary_manager.set_charset("UTF-8");
-
- // Config setting "locale" overrides language detection
- if (config->locale != "") {
- dictionary_manager.set_language( config->locale );
- }
-}
-
-static void init_physfs(const char* argv0)
-{
- Unison::VFS::FileSystem &fs = Unison::VFS::FileSystem::get();
- std::string application = "supertux2";
- std::string userdir = fs.get_user_dir();
- std::string dirsep = fs.get_dir_sep();
- std::string writedir = userdir + "." + application;
- fs.set_write_dir(writedir);
- fs.mount(writedir, "/", true);
-
- // Search for archives and add them to the search path
- const char* archiveExt = ".zip";
- std::vector<std::string> rc = fs.ls("/");
- for(std::vector<std::string>::iterator iter = rc.begin(); iter != rc.end(); ++iter)
- {
- std::string ext = iter->substr(iter->length() - 4);
- if(strcasecmp(ext.c_str(), archiveExt) == 0)
- {
- std::string dir = fs.get_real_dir(*iter);
- fs.mount(dir + fs.get_dir_sep() + *iter, "/", true);
- }
- }
-
- // when started from source dir...
- std::string dir = fs.get_base_dir();
- dir += "/data";
- std::string testfname = dir;
- testfname += "/credits.txt";
- bool sourcedir = false;
- FILE* f = fopen(testfname.c_str(), "r");
- if(f) {
- fclose(f);
- fs.mount(dir, "/", true);
- sourcedir = true;
- /*if(!PHYSFS_addToSearchPath(dir.c_str(), 1)) {
- log_warning << "Couldn't add '" << dir << "' to physfs searchpath: " << PHYSFS_getLastError() << std::endl;
- } else {
- sourcedir = true;
- }*/
- }
-
-#ifdef MACOSX
- // when started from Application file on Mac OS X...
- char path[PATH_MAX];
- CFBundleRef mainBundle = CFBundleGetMainBundle();
- assert(mainBundle != 0);
- CFURLRef mainBundleURL = CFBundleCopyBundleURL(mainBundle);
- assert(mainBundleURL != 0);
- CFStringRef pathStr = CFUrlCopyFileSystemPath(mainBundleURL, kCFURLPOSIXPathStyle);
- assert(pathStr != 0);
- CFStringGetCString(pathStr, path, PATH_MAX, kCFStringEncodingUTF8);
- CFRelease(mainBundleURL);
- CFRelease(pathStr);
-
- dir = std::string(path) + "/Contents/Resources/data";
- testfname = dir + "/credits.txt";
- sourcedir = false;
- f = fopen(testfname.c_str(), "r");
- if(f) {
- fclose(f);
- fs.mount(dir, "/", true);
- sourcedir = true;
- /*if(!PHYSFS_addToSearchPath(dir.c_str(), 1)) {
- log_warning << "Couldn't add '" << dir << "' to physfs searchpath: " << PHYSFS_getLastError() << std::endl;
- } else {
- sourcedir = true;
- }*/
- }
-#endif
-
-#ifdef _WIN32
- fs.mount(".\\data", "/", true);
- //PHYSFS_addToSearchPath(".\\data", 1);
-#endif
-
- if(!sourcedir) {
-#if defined(APPDATADIR) || defined(ENABLE_BINRELOC)
- std::string datadir;
-#ifdef ENABLE_BINRELOC
-
- char* dir;
- br_init (NULL);
- dir = br_find_data_dir(APPDATADIR);
- datadir = dir;
- free(dir);
-
-#else
- datadir = APPDATADIR;
-#endif
- datadir += "/";
- datadir += application;
- fs.mount(datadir, "/", true);
- /*if(!PHYSFS_addToSearchPath(datadir.c_str(), 1)) {
- log_warning << "Couldn't add '" << datadir << "' to physfs searchpath: " << PHYSFS_getLastError() << std::endl;
- }*/
-#endif
- }
-
- // allow symbolic links
- //PHYSFS_permitSymbolicLinks(1);
- //fs.follow_sym_links(true);
-
- //show search Path
- std::vector<std::string> searchpath = fs.get_search_path();
- for(std::vector<std::string>::iterator iter = searchpath.begin(); iter != searchpath.end(); ++iter)
- log_info << "[" << *iter << "] is in the search path" << std::endl;
- /*
- char** searchpath = PHYSFS_getSearchPath();
- for(char** i = searchpath; *i != NULL; i++)
- log_info << "[" << *i << "] is in the search path" << std::endl;
- PHYSFS_freeList(searchpath);
- */
-
-#if 0
- if(!PHYSFS_init(argv0)) {
- std::stringstream msg;
- msg << "Couldn't initialize physfs: " << PHYSFS_getLastError();
- throw std::runtime_error(msg.str());
- }
-
- // Initialize physfs (this is a slightly modified version of
- // PHYSFS_setSaneConfig
- const char* application = "supertux2"; //instead of PACKAGE_NAME so we can coexist with MS1
- const char* userdir = PHYSFS_getUserDir();
- const char* dirsep = PHYSFS_getDirSeparator();
- char* writedir = new char[strlen(userdir) + strlen(application) + 2];
-
- // Set configuration directory
- sprintf(writedir, "%s.%s", userdir, application);
- if(!PHYSFS_setWriteDir(writedir)) {
- // try to create the directory
- char* mkdir = new char[strlen(application) + 2];
- sprintf(mkdir, ".%s", application);
- if(!PHYSFS_setWriteDir(userdir) || !PHYSFS_mkdir(mkdir)) {
- std::ostringstream msg;
- msg << "Failed creating configuration directory '"
- << writedir << "': " << PHYSFS_getLastError();
- delete[] writedir;
- delete[] mkdir;
- throw std::runtime_error(msg.str());
- }
- delete[] mkdir;
-
- if(!PHYSFS_setWriteDir(writedir)) {
- std::ostringstream msg;
- msg << "Failed to use configuration directory '"
- << writedir << "': " << PHYSFS_getLastError();
- delete[] writedir;
- throw std::runtime_error(msg.str());
- }
- }
- PHYSFS_addToSearchPath(writedir, 0);
- delete[] writedir;
-
- // Search for archives and add them to the search path
- const char* archiveExt = "zip";
- char** rc = PHYSFS_enumerateFiles("/");
- size_t extlen = strlen(archiveExt);
-
- for(char** i = rc; *i != 0; ++i) {
- size_t l = strlen(*i);
- if((l > extlen) && ((*i)[l - extlen - 1] == '.')) {
- const char* ext = (*i) + (l - extlen);
- if(strcasecmp(ext, archiveExt) == 0) {
- const char* d = PHYSFS_getRealDir(*i);
- char* str = new char[strlen(d) + strlen(dirsep) + l + 1];
- sprintf(str, "%s%s%s", d, dirsep, *i);
- PHYSFS_addToSearchPath(str, 1);
- delete[] str;
- }
- }
- }
-
- PHYSFS_freeList(rc);
-
- // when started from source dir...
- std::string dir = PHYSFS_getBaseDir();
- dir += "/data";
- std::string testfname = dir;
- testfname += "/credits.txt";
- bool sourcedir = false;
- FILE* f = fopen(testfname.c_str(), "r");
- if(f) {
- fclose(f);
- if(!PHYSFS_addToSearchPath(dir.c_str(), 1)) {
- log_warning << "Couldn't add '" << dir << "' to physfs searchpath: " << PHYSFS_getLastError() << std::endl;
- } else {
- sourcedir = true;
- }
- }
-
-#ifdef MACOSX
-{
- using namespace supertux_apple;
-
- // when started from Application file on Mac OS X...
- char path[PATH_MAX];
- CFBundleRef mainBundle = CFBundleGetMainBundle();
- assert(mainBundle != 0);
- CFURLRef mainBundleURL = CFBundleCopyBundleURL(mainBundle);
- assert(mainBundleURL != 0);
- CFStringRef pathStr = CFURLCopyFileSystemPath(mainBundleURL, kCFURLPOSIXPathStyle);
- assert(pathStr != 0);
- CFStringGetCString(pathStr, path, PATH_MAX, kCFStringEncodingUTF8);
- CFRelease(mainBundleURL);
- CFRelease(pathStr);
-
- dir = std::string(path) + "/Contents/Resources/data";
- testfname = dir + "/credits.txt";
- sourcedir = false;
- f = fopen(testfname.c_str(), "r");
- if(f) {
- fclose(f);
- if(!PHYSFS_addToSearchPath(dir.c_str(), 1)) {
- log_warning << "Couldn't add '" << dir << "' to physfs searchpath: " << PHYSFS_getLastError() << std::endl;
- } else {
- sourcedir = true;
- }
- }
-}
-#endif
-
-#ifdef _WIN32
- PHYSFS_addToSearchPath(".\\data", 1);
-#endif
-
- if(!sourcedir) {
-#if defined(APPDATADIR) || defined(ENABLE_BINRELOC)
- std::string datadir;
-#ifdef ENABLE_BINRELOC
-
- char* dir;
- br_init (NULL);
- dir = br_find_data_dir(APPDATADIR);
- datadir = dir;
- free(dir);
-
-#else
- datadir = APPDATADIR;
-#endif
- datadir += "/";
- datadir += application;
- if(!PHYSFS_addToSearchPath(datadir.c_str(), 1)) {
- log_warning << "Couldn't add '" << datadir << "' to physfs searchpath: " << PHYSFS_getLastError() << std::endl;
- }
-#endif
- }
-
- // allow symbolic links
- PHYSFS_permitSymbolicLinks(1);
-
- //show search Path
- char** searchpath = PHYSFS_getSearchPath();
- for(char** i = searchpath; *i != NULL; i++)
- log_info << "[" << *i << "] is in the search path" << std::endl;
- PHYSFS_freeList(searchpath);
-#endif
-}
-
-static void print_usage(const char* argv0)
-{
- fprintf(stderr, _("Usage: %s [OPTIONS] [LEVELFILE]\n\n"), argv0);
- fprintf(stderr,
- _("Options:\n"
- " -f, --fullscreen Run in fullscreen mode\n"
- " -w, --window Run in window mode\n"
- " -g, --geometry WIDTHxHEIGHT Run SuperTux in given resolution\n"
- " -a, --aspect WIDTH:HEIGHT Run SuperTux with given aspect ratio\n"
- " --disable-sfx Disable sound effects\n"
- " --disable-music Disable music\n"
- " --help Show this help message\n"
- " --version Display SuperTux version and quit\n"
- " --console Enable ingame scripting console\n"
- " --noconsole Disable ingame scripting console\n"
- " --show-fps Display framerate in levels\n"
- " --no-show-fps Do not display framerate in levels\n"
- " --record-demo FILE LEVEL Record a demo to FILE\n"
- " --play-demo FILE LEVEL Play a recorded demo\n"
- "\n"));
-}
-
-/**
- * Options that should be evaluated prior to any initializations at all go here
- */
-static bool pre_parse_commandline(int argc, char** argv)
-{
- for(int i = 1; i < argc; ++i) {
- std::string arg = argv[i];
-
- if(arg == "--version") {
- std::cout << PACKAGE_NAME << " " << PACKAGE_VERSION << std::endl;
- return true;
- }
- }
-
- return false;
-}
-
-/**
- * Options that should be evaluated after config is read go here
- */
-static bool parse_commandline(int argc, char** argv)
-{
- for(int i = 1; i < argc; ++i) {
- std::string arg = argv[i];
-
- if(arg == "--help") {
- print_usage(argv[0]);
- return true;
- } else if(arg == "--fullscreen" || arg == "-f") {
- config->use_fullscreen = true;
- } else if(arg == "--window" || arg == "-w") {
- config->use_fullscreen = false;
- } else if(arg == "--geometry" || arg == "-g") {
- if(i+1 >= argc) {
- print_usage(argv[0]);
- throw std::runtime_error("Need to specify a parameter for geometry switch");
- }
- if(sscanf(argv[++i], "%dx%d", &config->screenwidth, &config->screenheight)
- != 2) {
- print_usage(argv[0]);
- throw std::runtime_error("Invalid geometry spec, should be WIDTHxHEIGHT");
- }
- } else if(arg == "--aspect" || arg == "-a") {
- if(i+1 >= argc) {
- print_usage(argv[0]);
- throw std::runtime_error("Need to specify a parameter for aspect switch");
- }
- if(strcasecmp(argv[i+1], "auto") == 0) {
- i++;
- config->aspect_ratio = -1;
- } else {
- int aspect_width, aspect_height;
- if(sscanf(argv[++i], "%d:%d", &aspect_width, &aspect_height) != 2) {
- print_usage(argv[0]);
- throw std::runtime_error("Invalid aspect spec, should be WIDTH:HEIGHT");
- }
- config->aspect_ratio = static_cast<double>(aspect_width) /
- static_cast<double>(aspect_height);
- }
- } else if(arg == "--show-fps") {
- config->show_fps = true;
- } else if(arg == "--no-show-fps") {
- config->show_fps = false;
- } else if(arg == "--console") {
- config->console_enabled = true;
- } else if(arg == "--noconsole") {
- config->console_enabled = false;
- } else if(arg == "--disable-sfx") {
- config->sound_enabled = false;
- } else if(arg == "--disable-music") {
- config->music_enabled = false;
- } else if(arg == "--play-demo") {
- if(i+1 >= argc) {
- print_usage(argv[0]);
- throw std::runtime_error("Need to specify a demo filename");
- }
- config->start_demo = argv[++i];
- } else if(arg == "--record-demo") {
- if(i+1 >= argc) {
- print_usage(argv[0]);
- throw std::runtime_error("Need to specify a demo filename");
- }
- config->record_demo = argv[++i];
- } else if(arg == "-d") {
- config->enable_script_debugger = true;
- } else if(arg[0] != '-') {
- config->start_level = arg;
- } else {
- log_warning << "Unknown option '" << arg << "'. Use --help to see a list of options" << std::endl;
- return true;
- }
- }
-
- return false;
-}
-
-static void init_sdl()
-{
- if(SDL_Init(SDL_INIT_TIMER | SDL_INIT_VIDEO | SDL_INIT_JOYSTICK) < 0) {
- std::stringstream msg;
- msg << "Couldn't initialize SDL: " << SDL_GetError();
- throw std::runtime_error(msg.str());
- }
- // just to be sure
- atexit(SDL_Quit);
-
- SDL_EnableUNICODE(1);
-
- // wait 100ms and clear SDL event queue because sometimes we have random
- // joystick events in the queue on startup...
- SDL_Delay(100);
- SDL_Event dummy;
- while(SDL_PollEvent(&dummy))
- ;
-}
-
-static void init_rand()
-{
- config->random_seed = systemRandom.srand(config->random_seed);
-
- //const char *how = config->random_seed? ", user fixed.": ", from time().";
- //log_info << "Using random seed " << config->random_seed << how << std::endl;
-}
-
-void init_video()
-{
- static int desktop_width = 0;
- static int desktop_height = 0;
-
-/* unfortunately only newer SDLs have these infos */
-#if SDL_MAJOR_VERSION > 1 || SDL_MINOR_VERSION > 2 || (SDL_MINOR_VERSION == 2 && SDL_PATCHLEVEL >= 10)
- /* find which resolution the user normally uses */
- if(desktop_width == 0) {
- const SDL_VideoInfo *info = SDL_GetVideoInfo();
- desktop_width = info->current_w;
- desktop_height = info->current_h;
- }
-#endif
-
- double aspect_ratio = config->aspect_ratio;
-
- // try to guess aspect ratio of monitor if needed
- if (aspect_ratio <= 0) {
-// TODO: commented out because
-// 1) it tends to guess wrong if widescreen-monitors don't stretch 800x600 to fit, but just display black borders
-// 2) aspect ratios other than 4:3 are largely untested
-/*
- if(config->use_fullscreen && desktop_width > 0) {
- aspect_ratio = static_cast<double>(desktop_width) / static_cast<double>(desktop_height);
- } else {
-*/
- aspect_ratio = 4.0 / 3.0;
-/*
- }
-*/
- }
-
- // use aspect ratio to calculate logical resolution
- if (aspect_ratio > 1) {
- SCREEN_WIDTH = static_cast<int> (600 * aspect_ratio + 0.5);
- SCREEN_HEIGHT = 600;
- } else {
- SCREEN_WIDTH = 600;
- SCREEN_HEIGHT = static_cast<int> (600 * 1/aspect_ratio + 0.5);
- }
-
- context_pointer->init_renderer();
- screen = SDL_GetVideoSurface();
-
- Unison::Video::Window::get().set_title(PACKAGE_NAME " " PACKAGE_VERSION);
- Unison::Video::Window::get().set_icon(Unison::Video::Surface("images/engine/icons/supertux.xpm"));
- //SDL_WM_SetCaption(PACKAGE_NAME " " PACKAGE_VERSION, 0);
-
- // set icon
- /*
- SDL_Surface* icon = IMG_Load_RW(
- get_physfs_SDLRWops("images/engine/icons/supertux.xpm"), true);
- if(icon != 0) {
- SDL_WM_SetIcon(icon, 0);
- SDL_FreeSurface(icon);
- }
-#ifdef DEBUG
- else {
- log_warning << "Couldn't find icon 'images/engine/icons/supertux.xpm'" << std::endl;
- }
-#endif
- */
-
- SDL_ShowCursor(0);
-
- log_info << (config->use_fullscreen?"fullscreen ":"window ") << SCREEN_WIDTH << "x" << SCREEN_HEIGHT << " Ratio: " << aspect_ratio << "\n";
-}
-
-static void init_audio()
-{
- sound_manager = new SoundManager();
-
- sound_manager->enable_sound(config->sound_enabled);
- sound_manager->enable_music(config->music_enabled);
-}
-
-static void quit_audio()
-{
- if(sound_manager != NULL) {
- delete sound_manager;
- sound_manager = NULL;
- }
-}
-
-void wait_for_event(float min_delay, float max_delay)
-{
- assert(min_delay <= max_delay);
-
- Uint32 min = (Uint32) (min_delay * 1000);
- Uint32 max = (Uint32) (max_delay * 1000);
-
- Uint32 ticks = SDL_GetTicks();
- while(SDL_GetTicks() - ticks < min) {
- SDL_Delay(10);
- sound_manager->update();
- }
-
- // clear event queue
- SDL_Event event;
- while (SDL_PollEvent(&event))
- {}
-
- /* Handle events: */
- bool running = false;
- ticks = SDL_GetTicks();
- while(running) {
- while(SDL_PollEvent(&event)) {
- switch(event.type) {
- case SDL_QUIT:
- main_loop->quit();
- break;
- case SDL_KEYDOWN:
- case SDL_JOYBUTTONDOWN:
- case SDL_MOUSEBUTTONDOWN:
- running = false;
- }
- }
- if(SDL_GetTicks() - ticks >= (max - min))
- running = false;
- sound_manager->update();
- SDL_Delay(10);
- }
-}
-
-#ifdef DEBUG
-static Uint32 last_timelog_ticks = 0;
-static const char* last_timelog_component = 0;
-
-static inline void timelog(const char* component)
-{
- Uint32 current_ticks = SDL_GetTicks();
-
- if(last_timelog_component != 0) {
- log_info << "Component '" << last_timelog_component << "' finished after " << (current_ticks - last_timelog_ticks) / 1000.0 << " seconds" << std::endl;
- }
-
- last_timelog_ticks = current_ticks;
- last_timelog_component = component;
-}
-#else
-static inline void timelog(const char* )
-{
-}
-#endif
-
-int main(int argc, char** argv)
-{
- int result = 0;
-
-#ifndef NO_CATCH
- try {
-#endif
-
- if(pre_parse_commandline(argc, argv))
- return 0;
-
- Console::instance = new Console();
- init_physfs(argv[0]);
- init_sdl();
-
- timelog("controller");
- main_controller = new JoystickKeyboardController();
- timelog("config");
- init_config();
- timelog("tinygettext");
- init_tinygettext();
- timelog("commandline");
- if(parse_commandline(argc, argv))
- return 0;
- timelog("audio");
- init_audio();
- timelog("video");
- DrawingContext context;
- context_pointer = &context;
- init_video();
- Console::instance->init_graphics();
- timelog("scripting");
- Scripting::init_squirrel(config->enable_script_debugger);
- timelog("resources");
- load_shared();
- timelog(0);
-
- main_loop = new MainLoop();
- if(config->start_level != "") {
- // we have a normal path specified at commandline not physfs paths.
- // So we simply mount that path here...
- std::string dir = FileSystem::dirname(config->start_level);
- Unison::VFS::FileSystem::get().mount(dir, "/", true);
- //PHYSFS_addToSearchPath(dir.c_str(), true);
-
- if(config->start_level.size() > 4 &&
- config->start_level.compare(config->start_level.size() - 5, 5, ".stwm") == 0) {
- init_rand();
- main_loop->push_screen(new WorldMapNS::WorldMap(
- FileSystem::basename(config->start_level)));
- } else {
- init_rand();//If level uses random eg. for
- // rain particles before we do this:
- std::auto_ptr<GameSession> session (
- new GameSession(FileSystem::basename(config->start_level)));
-
- config->random_seed =session->get_demo_random_seed(config->start_demo);
- init_rand();//initialise generator with seed from session
-
- if(config->start_demo != "")
- session->play_demo(config->start_demo);
-
- if(config->record_demo != "")
- session->record_demo(config->record_demo);
- main_loop->push_screen(session.release());
- }
- } else {
- init_rand();
- main_loop->push_screen(new TitleScreen());
- }
-
- //init_rand(); PAK: this call might subsume the above 3, but I'm chicken!
- main_loop->run(context);
-#ifndef NO_CATCH
- } catch(std::exception& e) {
- log_fatal << "Unexpected exception: " << e.what() << std::endl;
- result = 1;
- } catch(...) {
- log_fatal << "Unexpected exception" << std::endl;
- result = 1;
- }
-#endif
-
- delete main_loop;
- main_loop = NULL;
-
- unload_shared();
- quit_audio();
-
- if(config)
- config->save();
- delete config;
- config = NULL;
- delete main_controller;
- main_controller = NULL;
- delete Console::instance;
- Console::instance = NULL;
- Scripting::exit_squirrel();
- //delete texture_manager;
- //texture_manager = NULL;
- SDL_Quit();
- //PHYSFS_deinit();
-
- return result;
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#ifndef __MAIN_H__
-#define __MAIN_H__
-
-void init_video();
-void wait_for_event(float min_delay, float max_delay);
-
-/// The width of the display (this is a logical value, not the physical value)
-extern int SCREEN_WIDTH;
-/// The height of the display (this is a logical value, not the physical value)
-extern int SCREEN_HEIGHT;
-
-// global variables
-class JoystickKeyboardController;
-extern JoystickKeyboardController* main_controller;
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#include <config.h>
-
-#include "mainloop.hpp"
-
-#include <stdlib.h>
-#include <SDL.h>
-#include "video/drawing_context.hpp"
-#include "control/joystickkeyboardcontroller.hpp"
-#include "gui/menu.hpp"
-#include "audio/sound_manager.hpp"
-#include "scripting/time_scheduler.hpp"
-#include "scripting/squirrel_util.hpp"
-#include "gameconfig.hpp"
-#include "main.hpp"
-#include "resources.hpp"
-#include "screen.hpp"
-#include "screen_fade.hpp"
-#include "timer.hpp"
-#include "player_status.hpp"
-#include "random_generator.hpp"
-
-// the engine will be run with a logical framerate of 64fps.
-// We chose 64fps here because it is a power of 2, so 1/64 gives an "even"
-// binary fraction...
-static const float LOGICAL_FPS = 64.0;
-/** ticks (as returned from SDL_GetTicks) per frame */
-static const Uint32 TICKS_PER_FRAME = (Uint32) (1000.0 / LOGICAL_FPS);
-/** don't skip more than every 2nd frame */
-static const int MAX_FRAME_SKIP = 2;
-
-MainLoop* main_loop = NULL;
-
-MainLoop::MainLoop()
- : speed(1.0), nextpop(false), nextpush(false), fps(0), screenshot_requested(false)
-{
- using namespace Scripting;
- TimeScheduler::instance = new TimeScheduler();
-}
-
-MainLoop::~MainLoop()
-{
- using namespace Scripting;
- delete TimeScheduler::instance;
- TimeScheduler::instance = NULL;
-
- for(std::vector<Screen*>::iterator i = screen_stack.begin();
- i != screen_stack.end(); ++i) {
- delete *i;
- }
-}
-
-void
-MainLoop::push_screen(Screen* screen, ScreenFade* screen_fade)
-{
- this->next_screen.reset(screen);
- this->screen_fade.reset(screen_fade);
- nextpush = !nextpop;
- nextpop = false;
- speed = 1.0;
-}
-
-void
-MainLoop::exit_screen(ScreenFade* screen_fade)
-{
- next_screen.reset(NULL);
- this->screen_fade.reset(screen_fade);
- nextpop = true;
- nextpush = false;
-}
-
-void
-MainLoop::set_screen_fade(ScreenFade* screen_fade)
-{
- this->screen_fade.reset(screen_fade);
-}
-
-void
-MainLoop::quit(ScreenFade* screen_fade)
-{
- for(std::vector<Screen*>::iterator i = screen_stack.begin();
- i != screen_stack.end(); ++i)
- delete *i;
- screen_stack.clear();
-
- exit_screen(screen_fade);
-}
-
-void
-MainLoop::set_speed(float speed)
-{
- this->speed = speed;
-}
-
-float
-MainLoop::get_speed() const
-{
- return speed;
-}
-
-void
-MainLoop::draw_fps(DrawingContext& context, float fps_fps)
-{
- char str[60];
- snprintf(str, sizeof(str), "%3.1f", fps_fps);
- const char* fpstext = "FPS";
- context.draw_text(white_text, fpstext, Vector(SCREEN_WIDTH - white_text->get_text_width(fpstext) - gold_text->get_text_width(" 99999") - BORDER_X, BORDER_Y + 20), ALIGN_LEFT, LAYER_HUD);
- context.draw_text(gold_text, str, Vector(SCREEN_WIDTH - BORDER_X, BORDER_Y + 20), ALIGN_RIGHT, LAYER_HUD);
-}
-
-void
-MainLoop::draw(DrawingContext& context)
-{
- static Uint32 fps_ticks = SDL_GetTicks();
- static int frame_count = 0;
-
- current_screen->draw(context);
- if(Menu::current() != NULL)
- Menu::current()->draw(context);
- if(screen_fade.get() != NULL)
- screen_fade->draw(context);
- Console::instance->draw(context);
-
- if(config->show_fps)
- draw_fps(context, fps);
-
- // if a screenshot was requested, pass request on to drawing_context
- if (screenshot_requested) {
- context.take_screenshot();
- screenshot_requested = false;
- }
- context.do_drawing();
-
- /* Calculate frames per second */
- if(config->show_fps)
- {
- ++frame_count;
-
- if(SDL_GetTicks() - fps_ticks >= 500)
- {
- fps = (float) frame_count / .5;
- frame_count = 0;
- fps_ticks = SDL_GetTicks();
- }
- }
-}
-
-void
-MainLoop::update_gamelogic(float elapsed_time)
-{
- Scripting::update_debugger();
- Scripting::TimeScheduler::instance->update(game_time);
- current_screen->update(elapsed_time);
- if(screen_fade.get() != NULL)
- screen_fade->update(elapsed_time);
- Console::instance->update(elapsed_time);
-}
-
-void
-MainLoop::process_events()
-{
- main_controller->update();
- SDL_Event event;
- while(SDL_PollEvent(&event)) {
- main_controller->process_event(event);
- if(Menu::current() != NULL)
- Menu::current()->event(event);
- if(event.type == SDL_QUIT)
- quit();
- else if (event.type == SDL_KEYDOWN && event.key.keysym.sym == SDLK_F11) {
- config->use_fullscreen = !config->use_fullscreen;
- init_video();
- }
- else if (event.type == SDL_KEYDOWN && event.key.keysym.sym == SDLK_PRINT) {
- take_screenshot();
- }
- }
-}
-
-void
-MainLoop::handle_screen_switch()
-{
- while( (next_screen.get() != NULL || nextpop) &&
- (screen_fade.get() == NULL || screen_fade->done())) {
- if(current_screen.get() != NULL) {
- current_screen->leave();
- }
-
- if(nextpop) {
- if(screen_stack.empty()) {
- running = false;
- break;
- }
- next_screen.reset(screen_stack.back());
- screen_stack.pop_back();
- }
- if(nextpush && current_screen.get() != NULL) {
- screen_stack.push_back(current_screen.release());
- }
-
- nextpush = false;
- nextpop = false;
- speed = 1.0;
- if(next_screen.get() != NULL)
- next_screen->setup();
- current_screen.reset(next_screen.release());
- screen_fade.reset(NULL);
-
- waiting_threads.wakeup();
- }
-}
-
-void
-MainLoop::run(DrawingContext &context)
-{
- Uint32 last_ticks = 0;
- Uint32 elapsed_ticks = 0;
-
- running = true;
- while(running) {
-
- handle_screen_switch();
- if(!running || current_screen.get() == NULL)
- break;
-
- Uint32 ticks = SDL_GetTicks();
- elapsed_ticks += ticks - last_ticks;
- last_ticks = ticks;
-
- if (elapsed_ticks > TICKS_PER_FRAME*4) {
- // when the game loads up or levels are switched the
- // elapsed_ticks grows extremly large, so we just ignore those
- // large time jumps
- elapsed_ticks = 0;
- }
-
- int frames = 0;
-
- if (elapsed_ticks > TICKS_PER_FRAME) {
- while(elapsed_ticks > TICKS_PER_FRAME && frames < MAX_FRAME_SKIP) {
- elapsed_ticks -= TICKS_PER_FRAME;
- float timestep = 1.0 / LOGICAL_FPS;
- real_time += timestep;
- timestep *= speed;
- game_time += timestep;
-
- process_events();
- update_gamelogic(timestep);
- frames += 1;
- }
-
- draw(context);
- }
-
- sound_manager->update();
-
- SDL_Delay(0);
- }
-}
-
-void
-MainLoop::take_screenshot()
-{
- screenshot_requested = true;
-}
-
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#ifndef __MAINLOOP_HPP__
-#define __MAINLOOP_HPP__
-
-#include <memory>
-#include <vector>
-#include "scripting/thread_queue.hpp"
-
-class Screen;
-class Console;
-class ScreenFade;
-class DrawingContext;
-
-class MainLoop
-{
-public:
- MainLoop();
- ~MainLoop();
-
- void run(DrawingContext &context);
- void exit_screen(ScreenFade* fade = NULL);
- void quit(ScreenFade* fade = NULL);
- void set_speed(float speed);
- float get_speed() const;
-
- /**
- * requests that a screenshot be taken after the next frame has been rendered
- */
- void take_screenshot();
-
- // push new screen on screen_stack
- void push_screen(Screen* screen, ScreenFade* fade = NULL);
- void set_screen_fade(ScreenFade* fade);
-
- /// threads that wait for a screenswitch
- Scripting::ThreadQueue waiting_threads;
-
-private:
- void draw_fps(DrawingContext& context, float fps);
- void draw(DrawingContext& context);
- void update_gamelogic(float elapsed_time);
- void process_events();
- void handle_screen_switch();
-
- bool running;
- float speed;
- bool nextpop;
- bool nextpush;
- /// measured fps
- float fps;
- std::auto_ptr<Screen> next_screen;
- std::auto_ptr<Screen> current_screen;
- std::auto_ptr<Console> console;
- std::auto_ptr<ScreenFade> screen_fade;
- std::vector<Screen*> screen_stack;
- bool screenshot_requested; /**< true if a screenshot should be taken after the next frame has been rendered */
-};
-
-extern MainLoop* main_loop;
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __AATRIANGLE_H__
-#define __AATRIANGLE_H__
-
-#include "rect.hpp"
-
-/**
- * An axis aligned triangle (ie. a triangle where 2 sides are parallel to the x-
- * and y-axis.
- */
-class AATriangle : public Rect
-{
-public:
- /** Directions:
- *
- * SOUTHEWEST NORTHEAST SOUTHEAST NORTHWEST
- * * or *---* or * or *---*
- * | \ \ | / | | /
- * | \ \ | / | | /
- * *---* * *---* *
- *
- * Deform flags: (see docs/aatriangletypes.png for details)
- */
- enum Direction {
- SOUTHWEST = 0,
- NORTHEAST,
- SOUTHEAST,
- NORTHWEST,
- DIRECTION_MASK = 0x0003,
- DEFORM1 = 0x0010,
- DEFORM2 = 0x0020,
- DEFORM3 = 0x0030,
- DEFORM4 = 0x0040,
- DEFORM_MASK = 0x0070
- };
-
- AATriangle()
- : dir(SOUTHWEST)
- {
- }
- AATriangle(const Vector& v1, const Vector& v2, int newdir)
- : Rect(v1, v2), dir(newdir)
- {
- }
-
- int dir;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __RECT_H__
-#define __RECT_H__
-
-#include <assert.h>
-#include "vector.hpp"
-
-/** This class represents a rectangle.
- * (Implementation Note) We're using upper left and lower right point instead of
- * upper left and width/height here, because that makes the collision dectection
- * a little bit efficienter.
- */
-class Rect
-{
-public:
- Rect()
- { }
-
- Rect(const Vector& np1, const Vector& np2)
- : p1(np1), p2(np2)
- {
- }
-
- Rect(float x1, float y1, float x2, float y2)
- : p1(x1, y1), p2(x2, y2)
- {
- assert(p1.x <= p2.x && p1.y <= p2.y);
- }
-
- float get_left() const
- { return p1.x; }
-
- float get_right() const
- { return p2.x; }
-
- float get_top() const
- { return p1.y; }
-
- float get_bottom() const
- { return p2.y; }
-
- float get_width() const
- { return p2.x - p1.x; }
-
- float get_height() const
- { return p2.y - p1.y; }
-
- Vector get_middle() const
- { return Vector((p1.x+p2.x)/2, (p1.y+p2.y)/2); }
-
- void set_pos(const Vector& v)
- {
- move(v-p1);
- }
-
- void set_height(float height)
- {
- p2.y = p1.y + height;
- }
- void set_width(float width)
- {
- p2.x = p1.x + width;
- }
- void set_size(float width, float height)
- {
- set_width(width);
- set_height(height);
- }
- Vector get_size()
- {
- return Vector(get_width(), get_height());
- }
-
- void move(const Vector& v)
- {
- p1 += v;
- p2 += v;
- }
-
- bool contains(const Vector& v) const
- {
- return v.x >= p1.x && v.y >= p1.y && v.x < p2.x && v.y < p2.y;
- }
- bool contains(const Rect& other) const
- {
- if(p1.x >= other.p2.x || other.p1.x >= p2.x)
- return false;
- if(p1.y >= other.p2.y || other.p1.y >= p2.y)
- return false;
-
- return true;
- }
-
- // leave these 2 public to safe the headaches of set/get functions for such
- // simple things :)
-
- /// upper left edge
- Vector p1;
- /// lower right edge
- Vector p2;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include <cmath>
-
-#include "math/vector.hpp"
-
-Vector Vector::unit() const
-{
- return *this / norm();
-}
-
-float Vector::norm() const
-{
- return sqrt(x*x + y*y);
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef SUPERTUX_VECTOR_H
-#define SUPERTUX_VECTOR_H
-
-/** Simple two dimensional vector. */
-class Vector
-{
-public:
- Vector(float nx, float ny)
- : x(nx), y(ny)
- { }
- Vector(const Vector& other)
- : x(other.x), y(other.y)
- { }
- Vector()
- : x(0), y(0)
- { }
-
- bool operator ==(const Vector& other) const
- {
- return x == other.x && y == other.y;
- }
-
- bool operator !=(const Vector& other) const
- {
- return !(x == other.x && y == other.y);
- }
-
- const Vector& operator=(const Vector& other)
- {
- x = other.x;
- y = other.y;
- return *this;
- }
-
- Vector operator+(const Vector& other) const
- {
- return Vector(x + other.x, y + other.y);
- }
-
- Vector operator-(const Vector& other) const
- {
- return Vector(x - other.x, y - other.y);
- }
-
- Vector operator*(float s) const
- {
- return Vector(x * s, y * s);
- }
-
- Vector operator/(float s) const
- {
- return Vector(x / s, y / s);
- }
-
- Vector operator-() const
- {
- return Vector(-x, -y);
- }
-
- const Vector& operator +=(const Vector& other)
- {
- x += other.x;
- y += other.y;
- return *this;
- }
-
- const Vector& operator -=(const Vector& other)
- {
- x -= other.x;
- y -= other.y;
- return *this;
- }
-
- const Vector& operator *=(float val)
- {
- x *= val;
- y *= val;
- return *this;
- }
-
- const Vector& operator /=(float val)
- {
- x /= val;
- y /= val;
- return *this;
- }
-
- /// Scalar product of 2 vectors
- float operator*(const Vector& other) const
- {
- return x*other.x + y*other.y;
- }
-
- float norm() const;
- Vector unit() const;
-
- // ... add the other operators as needed, I'm too lazy now ...
-
- float x, y; // leave this public, get/set methods just give me headaches
- // for such simple stuff :)
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#include <config.h>
-
-#include "moving_object.hpp"
-
-MovingObject::MovingObject()
-{
- group = COLGROUP_MOVING;
-}
-
-MovingObject::~MovingObject()
-{
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#ifndef SUPERTUX_MOVING_OBJECT_H
-#define SUPERTUX_MOVING_OBJECT_H
-
-#include <stdint.h>
-
-#include "game_object.hpp"
-#include "collision_hit.hpp"
-#include "math/vector.hpp"
-#include "math/rect.hpp"
-
-class Sector;
-class CollisionGrid;
-
-enum CollisionGroup {
- /** Objects in DISABLED group are not tested for collisions */
- COLGROUP_DISABLED = 0,
- /**
- * "default" is moving object. MovingObjects get tested against all other
- * objects and against other movingobjects
- */
- COLGROUP_MOVING,
- /**
- * a Moving object, that is not tested against other MovingObjects (or other
- * MovingOnlyStatic objects), but is tested against all other objects.
- */
- COLGROUP_MOVING_ONLY_STATIC,
- /** TODO write docu :-/ */
- COLGROUP_MOVING_STATIC,
- /**
- * Doesn't move and isn't explicitely checked for collisions with other
- * objects (but other objects might check with this)
- * The difference to COLGROUP_TOUCHABLE is that we can do multiple
- * collision response tests in a row which is needed for static object
- * that tux walks on. The results for collisions with STATIC objects
- * are also sorted by time (so that the first hit gets handled first).
- *
- * Use this for static obstacles
- */
- COLGROUP_STATIC,
- /**
- * Isn't explicitely checked for collisions with other objects. But other
- * objects might check with this object.
- * Difference to COLGROUP_STATIC is that collisions with this object are
- * only tested once and collision response is typically not handled
- *
- * Use this for touchable things like spikes/areas or collectibles like
- * coins
- */
- COLGROUP_TOUCHABLE,
-
- /**
- * Should be used for tilemaps
- */
- COLGROUP_TILEMAP
-};
-
-/**
- * Base class for all dynamic/moving game objects. This class contains things
- * for handling the bounding boxes and collision feedback.
- */
-class MovingObject : public GameObject
-{
-public:
- MovingObject();
- virtual ~MovingObject();
-
- /** this function is called when the object collided with something solid */
- virtual void collision_solid(const CollisionHit& hit)
- {
- (void) hit;
- }
- /**
- * when 2 objects collided, we will first call the pre_collision_check
- * functions of both objects that can decide on how to react to the collision.
- */
- virtual bool collides(GameObject& other, const CollisionHit& hit)
- {
- (void) other;
- (void) hit;
- return true;
- }
- /** this function is called when the object collided with any other object */
- virtual HitResponse collision(GameObject& other, const CollisionHit& hit) = 0;
- /** called when tiles with special attributes have been touched */
- virtual void collision_tile(uint32_t tile_attributes)
- {
- (void) tile_attributes;
- }
-
- const Vector& get_pos() const
- {
- return bbox.p1;
- }
-
- /** returns the bounding box of the Object */
- const Rect& get_bbox() const
- {
- return bbox;
- }
-
- const Vector& get_movement() const
- {
- return movement;
- }
-
- /** places the moving object at a specific position. Be carefull when
- * using this function. There are no collision detection checks performed
- * here so bad things could happen.
- */
- virtual void set_pos(const Vector& pos)
- {
- dest.move(pos-get_pos());
- bbox.set_pos(pos);
- }
-
- /**
- * sets the moving object's bbox to a specific width. Be careful when
- * using this function. There are no collision detection checks performed
- * here so bad things could happen.
- */
- virtual void set_width(float w)
- {
- dest.set_width(w);
- bbox.set_width(w);
- }
-
- /**
- * sets the moving object's bbox to a specific size. Be careful when
- * using this function. There are no collision detection checks performed
- * here so bad things could happen.
- */
- virtual void set_size(float w, float h)
- {
- dest.set_size(w, h);
- bbox.set_size(w, h);
- }
-
- CollisionGroup get_group() const
- {
- return group;
- }
-
-protected:
- friend class Sector;
- friend class CollisionGrid;
- friend class Platform;
-
- void set_group(CollisionGroup group)
- {
- this->group = group;
- }
-
- /** The bounding box of the object (as used for collision detection, this
- * isn't necessarily the bounding box for graphics)
- */
- Rect bbox;
- /** The movement that will happen till next frame
- */
- Vector movement;
- /** The collision group */
- CollisionGroup group;
-
-private:
- /**
- * this is only here for internal collision detection use (don't touch this
- * from outside collision detection code)
- *
- * This field holds the currently anticipated destination of the object
- * during collision detection
- */
- Rect dest;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include <math.h>
-#include <stdexcept>
-#include <iostream>
-#include <limits>
-
-#include "ambient_sound.hpp"
-#include "object_factory.hpp"
-#include "lisp/lisp.hpp"
-#include "sector.hpp"
-#include "audio/sound_manager.hpp"
-#include "audio/sound_source.hpp"
-#include "log.hpp"
-#include "scripting/squirrel_util.hpp"
-
-AmbientSound::AmbientSound(const lisp::Lisp& lisp)
-{
- name="";
- position.x = 0;
- position.y = 0;
-
- dimension.x = 0;
- dimension.y = 0;
-
- distance_factor = 0;
- distance_bias = 0;
- maximumvolume = 1;
- sample = "";
- currentvolume = 0;
-
- if (!(lisp.get("x", position.x)&&lisp.get("y", position.y))) {
- log_warning << "No Position in ambient_sound" << std::endl;
- }
-
- lisp.get("name" , name);
- lisp.get("width" , dimension.x);
- lisp.get("height", dimension.y);
-
- lisp.get("distance_factor",distance_factor);
- lisp.get("distance_bias" ,distance_bias );
- lisp.get("sample" ,sample );
- lisp.get("volume" ,maximumvolume );
-
- // set dimension to zero if smaller than 64, which is default size in flexlay
-
- if ((dimension.x <= 64) || (dimension.y <= 64)) {
- dimension.x = 0;
- dimension.y = 0;
- }
-
- // square all distances (saves us a sqrt later)
-
- distance_bias*=distance_bias;
- distance_factor*=distance_factor;
-
- // set default silence_distance
-
- if (distance_factor == 0)
- silence_distance = std::numeric_limits<float>::max();
- else
- silence_distance = 1/distance_factor;
-
- lisp.get("silence_distance",silence_distance);
-
- sound_source = 0; // not playing at the beginning
- latency=0;
-}
-
-AmbientSound::AmbientSound(Vector pos, float factor, float bias, float vol, std::string file)
-{
- position.x=pos.x;
- position.y=pos.y;
-
- dimension.x=0;
- dimension.y=0;
-
- distance_factor=factor*factor;
- distance_bias=bias*bias;
- maximumvolume=vol;
- sample=file;
-
- // set default silence_distance
-
- if (distance_factor == 0)
- silence_distance = std::numeric_limits<float>::max();
- else
- silence_distance = 1/distance_factor;
-
- sound_source = 0; // not playing at the beginning
- latency=0;
-}
-
-AmbientSound::~AmbientSound() {
- stop_playing();
-}
-
-void
-AmbientSound::hit(Player& )
-{
-}
-
-void
-AmbientSound::stop_playing() {
- delete sound_source;
- sound_source = 0;
-}
-
-void
-AmbientSound::start_playing()
-{
- try {
- sound_source = sound_manager->create_sound_source(sample);
- if(!sound_source)
- throw std::runtime_error("file not found");
-
- sound_source->set_gain(0);
- sound_source->set_looping(true);
- currentvolume=targetvolume=1e-20f;
- sound_source->play();
- } catch(std::exception& e) {
- log_warning << "Couldn't play '" << sample << "': " << e.what() << "" << std::endl;
- delete sound_source;
- sound_source = 0;
- remove_me();
- }
-}
-
-void
-AmbientSound::update(float deltat)
-{
- if (latency-- <= 0) {
- float px,py;
- float rx,ry;
-
- // Player position
- px=Sector::current()->player->get_pos().x;
- py=Sector::current()->player->get_pos().y;
-
- // Relate to which point in the area
- rx=px<position.x?position.x:
- (px<position.x+dimension.x?px:position.x+dimension.x);
- ry=py<position.y?position.y:
- (py<position.y+dimension.y?py:position.y+dimension.y);
-
- // calculate square of distance
- float sqrdistance=(px-rx)*(px-rx)+(py-ry)*(py-ry);
- sqrdistance-=distance_bias;
-
- // inside the bias: full volume (distance 0)
- if (sqrdistance<0)
- sqrdistance=0;
-
- // calculate target volume - will never become 0
- targetvolume=1/(1+sqrdistance*distance_factor);
- float rise=targetvolume/currentvolume;
-
- // rise/fall half life?
- currentvolume*=pow(rise,deltat*10);
- currentvolume += 1e-6f; // volume is at least 1e-6 (0 would never rise)
-
- if (sound_source != 0) {
-
- // set the volume
- sound_source->set_gain(currentvolume*maximumvolume);
-
- if (sqrdistance>=silence_distance && currentvolume<1e-3)
- stop_playing();
- latency=0;
- } else {
- if (sqrdistance<silence_distance) {
- start_playing();
- latency=0;
- }
- else // set a reasonable latency
- latency=(int)(0.001/distance_factor);
- //(int)(10*((sqrdistance-silence_distance)/silence_distance));
- }
- }
-
- // heuristically measured "good" latency maximum
-
- // if (latency>0.001/distance_factor)
- // latency=
-}
-
-void
-AmbientSound::draw(DrawingContext &)
-{
-}
-
-void
-AmbientSound::expose(HSQUIRRELVM vm, SQInteger table_idx)
-{
- Scripting::AmbientSound* interface = static_cast<Scripting::AmbientSound*> (this);
- expose_object(vm, table_idx, interface, name, false);
-}
-
-void
-AmbientSound::unexpose(HSQUIRRELVM vm, SQInteger table_idx)
-{
- Scripting::unexpose_object(vm, table_idx, name);
-}
-
-void
-AmbientSound::set_pos(float x, float y)
-{
- position.x = x;
- position.y = y;
-}
-
-float
-AmbientSound::get_pos_x() const
-{
- return position.x;
-}
-
-float
-AmbientSound::get_pos_y() const
-{
- return position.y;
-}
-
-IMPLEMENT_FACTORY(AmbientSound, "ambient_sound");
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-
-/**
- * Ambient Sound Source, gamma version. Features:
- *
- * - "rounded rectancle" geometry with position, dimension and
- * "rounding radius" (extending in all directions) of a 100%
- * volume area, adjustable maximum volume, inverse square
- * falloff outside area.
- *
- * - degenerates gracefully to a disc for dimension=0
- *
- * - parameters:
- *
- * x, y position
- * width, height dimension
- * distance_factor high = steep fallofff
- * distance_bias high = big "100% disc"
- * silence_distance defaults reasonably.
- * sample sample to be played back in loop mode
- *
- * basti_
- */
-
-#ifndef __AMBIENT_SOUND_H__
-#define __AMBIENT_SOUND_H__
-
-#include "game_object.hpp"
-#include "resources.hpp"
-#include "player.hpp"
-#include "script_interface.hpp"
-#include "scripting/ambient_sound.hpp"
-
-class SoundSource;
-
-class AmbientSound : public GameObject, public ScriptInterface, public Scripting::AmbientSound
-{
-public:
- AmbientSound(const lisp::Lisp& lisp);
- AmbientSound(Vector pos, float factor, float bias, float vol, std::string file);
- ~AmbientSound();
-
- void set_pos(Vector newpos)
- {
- position=newpos;
- }
- const Vector get_pos() const
- {
- return position;
- }
-
- /**
- * @name Scriptable Methods
- * @{
- */
- void set_pos(float x, float y);
- float get_pos_x() const;
- float get_pos_y() const;
- /**
- * @}
- */
-
-protected:
- virtual void hit(Player& player);
- virtual void update(float time);
- virtual void draw(DrawingContext&);
- virtual void start_playing();
- virtual void stop_playing();
- virtual void expose(HSQUIRRELVM vm, SQInteger table_idx);
- virtual void unexpose(HSQUIRRELVM vm, SQInteger table_idx);
-private:
- std::string name; /**< user-defined name for use in scripts or empty string if not scriptable */
- Vector position;
- Vector dimension;
-
- std::string sample;
- SoundSource* sound_source;
- int latency;
-
- float distance_factor; /// distance scaling
- float distance_bias; /// 100% volume disc radius
- float silence_distance; /// not implemented yet
-
- float maximumvolume; /// maximum volume
- float targetvolume; /// how loud we want to be
- float currentvolume; /// how loud we are
-
- float * volume_ptr; /// this will be used by the volume adjustment effect.
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include <stdexcept>
-#include <sstream>
-#include "anchor_point.hpp"
-#include "math/rect.hpp"
-#include "log.hpp"
-
-std::string anchor_point_to_string(AnchorPoint point)
-{
- switch(point) {
- case ANCHOR_TOP_LEFT:
- return "topleft";
- case ANCHOR_TOP:
- return "top";
- case ANCHOR_TOP_RIGHT:
- return "topright";
- case ANCHOR_LEFT:
- return "left";
- case ANCHOR_MIDDLE:
- return "middle";
- case ANCHOR_RIGHT:
- return "right";
- case ANCHOR_BOTTOM_LEFT:
- return "bottomleft";
- case ANCHOR_BOTTOM:
- return "bottom";
- case ANCHOR_BOTTOM_RIGHT:
- return "bottomright";
- default:
- throw std::runtime_error("Invalid anchor point");
- }
-}
-
-AnchorPoint string_to_anchor_point(const std::string& str)
-{
- if(str == "topleft")
- return ANCHOR_TOP_LEFT;
- else if(str == "top")
- return ANCHOR_TOP;
- else if(str == "topright")
- return ANCHOR_TOP_RIGHT;
- else if(str == "left")
- return ANCHOR_LEFT;
- else if(str == "middle")
- return ANCHOR_MIDDLE;
- else if(str == "right")
- return ANCHOR_RIGHT;
- else if(str == "bottomleft")
- return ANCHOR_BOTTOM_LEFT;
- else if(str == "bottom")
- return ANCHOR_BOTTOM;
- else if(str == "bottomright")
- return ANCHOR_BOTTOM_RIGHT;
-
- std::ostringstream msg;
- msg << "Unknown anchor '" << str << "'";
- throw std::runtime_error(msg.str());
-}
-
-Vector get_anchor_pos(const Rect& rect, AnchorPoint point)
-{
- Vector result;
-
- switch(point & ANCHOR_V_MASK) {
- case ANCHOR_LEFT:
- result.x = rect.get_left();
- break;
- case ANCHOR_MIDDLE:
- result.x = rect.get_left() + (rect.get_right() - rect.get_left()) / 2.0;
- break;
- case ANCHOR_RIGHT:
- result.x = rect.get_right();
- break;
- default:
-#ifdef DEBUG
- throw std::runtime_error("Invalid anchor point found");
-#endif
- log_warning << "Invalid anchor point found" << std::endl;
- result.x = rect.get_left();
- break;
- }
-
- switch(point & ANCHOR_H_MASK) {
- case ANCHOR_TOP:
- result.y = rect.get_top();
- break;
- case ANCHOR_MIDDLE:
- result.y = rect.get_top() + (rect.get_bottom() - rect.get_top()) / 2.0;
- break;
- case ANCHOR_BOTTOM:
- result.y = rect.get_bottom();
- break;
- default:
-#ifdef DEBUG
- throw std::runtime_error("Invalid anchor point found");
-#endif
- log_warning << "Invalid anchor point found" << std::endl;
- result.y = rect.get_top();
- break;
- }
-
- return result;
-}
-
-Vector get_anchor_pos(const Rect& destrect, float width, float height,
- AnchorPoint point)
-{
- Vector result;
-
- switch(point & ANCHOR_V_MASK) {
- case ANCHOR_LEFT:
- result.x = destrect.get_left();
- break;
- case ANCHOR_MIDDLE:
- result.x = destrect.get_middle().x - width/2.0;
- break;
- case ANCHOR_RIGHT:
- result.x = destrect.get_right() - width;
- break;
- default:
-#ifdef DEBUG
- throw std::runtime_error("Invalid anchor point found");
-#endif
- log_warning << "Invalid anchor point found" << std::endl;
- result.x = destrect.get_left();
- break;
- }
-
- switch(point & ANCHOR_H_MASK) {
- case ANCHOR_TOP:
- result.y = destrect.get_top();
- break;
- case ANCHOR_MIDDLE:
- result.y = destrect.get_middle().y - height/2.0;
- break;
- case ANCHOR_BOTTOM:
- result.y = destrect.get_bottom() - height;
- break;
- default:
-#ifdef DEBUG
- throw std::runtime_error("Invalid anchor point found");
-#endif
- log_warning << "Invalid anchor point found" << std::endl;
- result.y = destrect.get_top();
- break;
- }
-
- return result;
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __ANCHOR_POINT_HPP__
-#define __ANCHOR_POINT_HPP__
-
-#include <string>
-#include "math/vector.hpp"
-
-class Rect;
-
-enum AnchorPoint {
- ANCHOR_H_MASK = 0x00f0,
- ANCHOR_TOP = 0x0010,
- ANCHOR_BOTTOM = 0x0020,
- ANCHOR_V_MASK = 0x000f,
- ANCHOR_LEFT = 0x0001,
- ANCHOR_RIGHT = 0x0002,
- ANCHOR_MIDDLE = 0x0000,
-
- ANCHOR_TOP_LEFT = ANCHOR_TOP | ANCHOR_LEFT,
- ANCHOR_TOP_RIGHT = ANCHOR_TOP | ANCHOR_RIGHT,
- ANCHOR_BOTTOM_LEFT = ANCHOR_BOTTOM | ANCHOR_LEFT,
- ANCHOR_BOTTOM_RIGHT = ANCHOR_BOTTOM | ANCHOR_RIGHT,
-};
-
-std::string anchor_point_to_string(AnchorPoint point);
-AnchorPoint string_to_anchor_point(const std::string& str);
-Vector get_anchor_pos(const Rect& rect, AnchorPoint point);
-Vector get_anchor_pos(const Rect& destrect, float width, float height,
- AnchorPoint point);
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include <stdexcept>
-#include "background.hpp"
-#include "camera.hpp"
-#include "video/drawing_context.hpp"
-#include "lisp/lisp.hpp"
-#include "lisp/writer.hpp"
-#include "object_factory.hpp"
-#include "resources.hpp"
-#include "main.hpp"
-#include "log.hpp"
-
-Background::Background()
- : layer(LAYER_BACKGROUND0)
-{
-}
-
-Background::Background(const lisp::Lisp& reader)
- : layer(LAYER_BACKGROUND0)
-{
- // read position, defaults to (0,0)
- float px = 0;
- float py = 0;
- reader.get("x", px);
- reader.get("y", py);
- this->pos = Vector(px,py);
-
- speed = 1.0;
- speed_y = 1.0;
-
- reader.get("layer", layer);
- if(!reader.get("image", imagefile) || !reader.get("speed", speed))
- throw std::runtime_error("Must specify image and speed for background");
-
- set_image(imagefile, speed);
- reader.get("speed-y", speed_y);
- if (reader.get("image-top", imagefile_top)) {
- image_top.reset(new Surface(imagefile_top));
- }
- if (reader.get("image-bottom", imagefile_bottom)) {
- image_bottom.reset(new Surface(imagefile_bottom));
- }
-}
-
-Background::~Background()
-{
-}
-
-void
-Background::write(lisp::Writer& writer)
-{
- writer.start_list("background");
-
- if (image_top.get() != NULL)
- writer.write_string("image-top", imagefile_top);
-
- writer.write_string("image", imagefile);
- if (image_bottom.get() != NULL)
- writer.write_string("image-bottom", imagefile_bottom);
-
- writer.write_float("speed", speed);
- writer.write_float("speed-y", speed_y);
- writer.write_int("layer", layer);
-
- writer.end_list("background");
-}
-
-void
-Background::update(float)
-{
-}
-
-void
-Background::set_image(const std::string& name, float speed)
-{
- this->imagefile = name;
- this->speed = speed;
-
- image.reset(new Surface(name));
-}
-
-void
-Background::draw(DrawingContext& context)
-{
- if(image.get() == NULL)
- return;
-
- int w = (int) image->get_width();
- int h = (int) image->get_height();
- int sx = int(pos.x-context.get_translation().x * speed) % w - w;
- int sy = int(pos.y-context.get_translation().y * speed_y) % h - h;
- int center_image_py = int(pos.y-context.get_translation().y * speed_y);
- int bottom_image_py = int(pos.y-context.get_translation().y * speed_y) + h;
- context.push_transform();
- context.set_translation(Vector(0, 0));
- for(int x = sx; x < SCREEN_WIDTH; x += w) {
- for(int y = sy; y < SCREEN_HEIGHT; y += h) {
- if (image_top.get() != NULL && (y < center_image_py)) {
- context.draw_surface(image_top.get(), Vector(x, y), layer);
- continue;
- }
- if (image_bottom.get() != NULL && (y >= bottom_image_py)) {
- context.draw_surface(image_bottom.get(), Vector(x, y), layer);
- continue;
- }
- context.draw_surface(image.get(), Vector(x, y), layer);
- }
- }
- context.pop_transform();
-}
-
-IMPLEMENT_FACTORY(Background, "background");
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef SUPERTUX_BACKGROUND_H
-#define SUPERTUX_BACKGROUND_H
-
-#include <memory>
-#include "video/surface.hpp"
-#include "video/drawing_context.hpp"
-#include "game_object.hpp"
-#include "serializable.hpp"
-
-class DisplayManager;
-
-namespace lisp {
-class Lisp;
-}
-
-class Background : public GameObject, public Serializable
-{
-public:
- Background();
- Background(const lisp::Lisp& reader);
- virtual ~Background();
-
- virtual void write(lisp::Writer& writer);
-
- void set_image(const std::string& name, float bkgd_speed);
-
- std::string get_image() const
- { return imagefile; }
- float get_speed() const
- { return speed; }
-
- virtual void update(float elapsed_time);
-
- virtual void draw(DrawingContext& context);
-
-private:
- int layer;
- std::string imagefile_top;
- std::string imagefile;
- std::string imagefile_bottom;
- Vector pos; /**< coordinates of upper-left corner of image */
- float speed; /**< scroll-speed in horizontal direction */
- float speed_y; /**< scroll-speed in vertical direction */
- std::auto_ptr<Surface> image_top; /**< image to draw above pos */
- std::auto_ptr<Surface> image; /**< image to draw, anchored at pos */
- std::auto_ptr<Surface> image_bottom; /**< image to draw below pos+screenheight */
-};
-
-#endif /*SUPERTUX_BACKGROUND_H*/
+++ /dev/null
-// $Id$
-//
-// SuperTux - BicyclePlatform
-// Copyright (C) 2007 Christoph Sommer <christoph.sommer@2007.expires.deltadevelopment.de>
-//
-// 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.
-
-#include <config.h>
-
-#include "bicycle_platform.hpp"
-
-#include <math.h>
-#include <stdexcept>
-#include "log.hpp"
-#include "video/drawing_context.hpp"
-#include "resources.hpp"
-#include "player.hpp"
-#include "path.hpp"
-#include "path_walker.hpp"
-#include "sprite/sprite.hpp"
-#include "lisp/lisp.hpp"
-#include "object_factory.hpp"
-#include "sector.hpp"
-#include "object/portable.hpp"
-
-BicyclePlatform::BicyclePlatform(const lisp::Lisp& reader)
- : MovingSprite(reader, LAYER_OBJECTS, COLGROUP_STATIC),
- master(0), slave(0), radius(128), angle(0), angular_speed(0), momentum(0)
-{
- center = get_pos();
-}
-
-BicyclePlatform::BicyclePlatform(BicyclePlatform* master)
- : MovingSprite(*master),
- master(master), slave(this), center(master->center), radius(master->radius), angle(master->angle + M_PI), angular_speed(0), momentum(0)
-{
- set_pos(get_pos() + Vector(master->get_bbox().get_width(), 0));
- master->master = master;
- master->slave = this;
-}
-
-BicyclePlatform::~BicyclePlatform() {
- if ((this == master) && (master)) {
- slave->master = 0;
- slave->slave = 0;
- }
- if ((master) && (this == slave)) {
- master->master = 0;
- master->slave = 0;
- }
- master = 0;
- slave = 0;
-}
-
-HitResponse
-BicyclePlatform::collision(GameObject& other, const CollisionHit& )
-{
-
- // somehow the hit parameter does not get filled in, so to determine (hit.top == true) we do this:
- MovingObject* mo = dynamic_cast<MovingObject*>(&other);
- if (!mo) return FORCE_MOVE;
- if ((mo->get_bbox().p2.y) > (get_bbox().p1.y + 2)) return FORCE_MOVE;
-
- Player* pl = dynamic_cast<Player*>(mo);
- if (pl) {
- if (pl->is_big()) momentum += 1;
- Portable* po = pl->get_grabbed_object();
- MovingObject* pomo = dynamic_cast<MovingObject*>(po);
- if (contacts.insert(pomo).second) momentum += 1;
- }
-
- if (contacts.insert(&other).second) momentum += 1;
- return FORCE_MOVE;
-}
-
-void
-BicyclePlatform::update(float elapsed_time)
-{
- if (!slave) {
- Sector::current()->add_object(new BicyclePlatform(this));
- return;
- }
- if (!master) {
- return;
- }
- if (this == slave) {
- angle = master->angle + M_PI;
- while (angle < 0) { angle += 2*M_PI; }
- while (angle > 2*M_PI) { angle -= 2*M_PI; }
- Vector dest = center + Vector(cosf(angle), sinf(angle)) * radius - (bbox.get_size() * 0.5);
- movement = dest - get_pos();
- }
- if (this == master) {
- float momentum_diff = momentum - slave->momentum;
- contacts.clear(); momentum = 0;
- slave->contacts.clear(); slave->momentum = 0;
-
- float angular_momentum = cosf(angle) * momentum_diff;
-
- angular_speed += (angular_momentum * elapsed_time) * M_PI;
- angular_speed *= 1 - elapsed_time * 0.2;
- angle += angular_speed * elapsed_time;
- while (angle < 0) { angle += 2*M_PI; }
- while (angle > 2*M_PI) { angle -= 2*M_PI; }
- angular_speed = std::min(std::max(angular_speed, static_cast<float>(-128*M_PI*elapsed_time)), static_cast<float>(128*M_PI*elapsed_time));
- Vector dest = center + Vector(cosf(angle), sinf(angle)) * radius - (bbox.get_size() * 0.5);
- movement = dest - get_pos();
-
- center += Vector(angular_speed, 0) * elapsed_time * 32;
- slave->center += Vector(angular_speed, 0) * elapsed_time * 32;
-
- }
-}
-
-IMPLEMENT_FACTORY(BicyclePlatform, "bicycle-platform");
-
+++ /dev/null
-// $Id$
-//
-// SuperTux - BicyclePlatform
-// Copyright (C) 2007 Christoph Sommer <christoph.sommer@2007.expires.deltadevelopment.de>
-//
-// 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.
-
-#ifndef __BICYCLE_PLATFORM_H__
-#define __BICYCLE_PLATFORM_H__
-
-#include <memory>
-#include <string>
-#include <set>
-#include "object/moving_sprite.hpp"
-#include "object/path.hpp"
-#include "object/path_walker.hpp"
-
-/**
- * Used to construct a pair of bicycle platforms: If one is pushed down, the other one rises
- */
-class BicyclePlatform : public MovingSprite
-{
-public:
- BicyclePlatform(const lisp::Lisp& reader);
- BicyclePlatform(BicyclePlatform* master);
- virtual ~BicyclePlatform();
-
- virtual HitResponse collision(GameObject& other, const CollisionHit& hit);
- virtual void update(float elapsed_time);
-
-protected:
- BicyclePlatform* master; /**< pointer to BicyclePlatform that does movement calculation */
- BicyclePlatform* slave; /**< pointer to BicyclePlatform that reacts to master platform's movement calculation */
- Vector center; /**< pivot point */
- float radius; /**< radius of circle */
- float angle; /**< current angle */
- float angular_speed; /**< angular speed in rad per second */
- std::set<GameObject*> contacts; /**< objects that are currently pushing on the platform */
- float momentum; /** angular momentum in rad per second per second*/
-
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include "block.hpp"
-#include "log.hpp"
-
-#include <stdexcept>
-
-#include "resources.hpp"
-#include "player.hpp"
-#include "sector.hpp"
-#include "sprite/sprite.hpp"
-#include "sprite/sprite_manager.hpp"
-#include "video/drawing_context.hpp"
-#include "lisp/lisp.hpp"
-#include "gameobjs.hpp"
-#include "portable.hpp"
-#include "specialriser.hpp"
-#include "growup.hpp"
-#include "flower.hpp"
-#include "oneup.hpp"
-#include "star.hpp"
-#include "player_status.hpp"
-#include "badguy/badguy.hpp"
-#include "coin.hpp"
-#include "object_factory.hpp"
-#include "lisp/list_iterator.hpp"
-#include "object_factory.hpp"
-#include "level.hpp"
-
-static const float BOUNCY_BRICK_MAX_OFFSET = 8;
-static const float BOUNCY_BRICK_SPEED = 90;
-static const float EPSILON = .0001f;
-
-Block::Block(Sprite* newsprite)
- : sprite(newsprite), bouncing(false), breaking(false), bounce_dir(0), bounce_offset(0)
-{
- bbox.set_size(32, 32.1f);
- set_group(COLGROUP_STATIC);
- sound_manager->preload("sounds/upgrade.wav");
- sound_manager->preload("sounds/brick.wav");
-}
-
-Block::~Block()
-{
- delete sprite;
-}
-
-HitResponse
-Block::collision(GameObject& other, const CollisionHit& )
-{
- Player* player = dynamic_cast<Player*> (&other);
- if(player) {
- if(player->get_bbox().get_top() > get_bbox().get_bottom() - 7.0) {
- hit(*player);
- }
- }
-
- // only interact with other objects if...
- // 1) we are bouncing
- // and
- // 2) the object is not portable (either never or not currently)
- Portable* portable = dynamic_cast<Portable*> (&other);
- if(bouncing && (portable == 0 || (!portable->is_portable()))) {
-
- // Badguys get killed
- BadGuy* badguy = dynamic_cast<BadGuy*> (&other);
- if(badguy) {
- badguy->kill_fall();
- }
-
- // Coins get collected
- Coin* coin = dynamic_cast<Coin*> (&other);
- if(coin) {
- coin->collect();
- }
-
- }
-
- return SOLID;
-}
-
-void
-Block::update(float elapsed_time)
-{
- if(!bouncing)
- return;
-
- float offset = original_y - get_pos().y;
- if(offset > BOUNCY_BRICK_MAX_OFFSET) {
- bounce_dir = BOUNCY_BRICK_SPEED;
- movement = Vector(0, bounce_dir * elapsed_time);
- if(breaking){
- break_me();
- }
- } else if(offset < BOUNCY_BRICK_SPEED * elapsed_time && bounce_dir > 0) {
- movement = Vector(0, offset);
- bounce_dir = 0;
- bouncing = false;
- } else {
- movement = Vector(0, bounce_dir * elapsed_time);
- }
-}
-
-void
-Block::draw(DrawingContext& context)
-{
- sprite->draw(context, get_pos(), LAYER_OBJECTS+1);
-}
-
-void
-Block::start_bounce()
-{
- original_y = bbox.p1.y;
- bouncing = true;
- bounce_dir = -BOUNCY_BRICK_SPEED;
- bounce_offset = 0;
-}
-
-void
-Block::start_break()
-{
- start_bounce();
- breaking = true;
-}
-
-//---------------------------------------------------------------------------
-
-BonusBlock::BonusBlock(const Vector& pos, int data)
- : Block(sprite_manager->create("images/objects/bonus_block/bonusblock.sprite")), object(0)
-{
- bbox.set_pos(pos);
- sprite->set_action("normal");
- switch(data) {
- case 1: contents = CONTENT_COIN; break;
- case 2: contents = CONTENT_FIREGROW; break;
- case 3: contents = CONTENT_STAR; break;
- case 4: contents = CONTENT_1UP; break;
- case 5: contents = CONTENT_ICEGROW; break;
- default:
- log_warning << "Invalid box contents" << std::endl;
- contents = CONTENT_COIN;
- break;
- }
-}
-
-BonusBlock::BonusBlock(const lisp::Lisp& lisp)
- : Block(sprite_manager->create("images/objects/bonus_block/bonusblock.sprite"))
-{
- Vector pos;
-
- contents = CONTENT_COIN;
- lisp::ListIterator iter(&lisp);
- while(iter.next()) {
- const std::string& token = iter.item();
- if(token == "x") {
- iter.value()->get(pos.x);
- } else if(token == "y") {
- iter.value()->get(pos.y);
- } else if(token == "contents") {
- std::string contentstring;
- iter.value()->get(contentstring);
- if(contentstring == "coin") {
- contents = CONTENT_COIN;
- } else if(contentstring == "firegrow") {
- contents = CONTENT_FIREGROW;
- } else if(contentstring == "icegrow") {
- contents = CONTENT_ICEGROW;
- } else if(contentstring == "star") {
- contents = CONTENT_STAR;
- } else if(contentstring == "1up") {
- contents = CONTENT_1UP;
- } else if(contentstring == "custom") {
- contents = CONTENT_CUSTOM;
- } else {
- log_warning << "Invalid box contents '" << contentstring << "'" << std::endl;
- }
- } else {
- if(contents == CONTENT_CUSTOM) {
- GameObject* game_object = create_object(token, *(iter.lisp()));
- object = dynamic_cast<MovingObject*> (game_object);
- if(object == 0)
- throw std::runtime_error(
- "Only MovingObjects are allowed inside BonusBlocks");
- } else {
- log_warning << "Invalid element '" << token << "' in bonusblock" << std::endl;
- }
- }
- }
-
- if(contents == CONTENT_CUSTOM && object == 0)
- throw std::runtime_error("Need to specify content object for custom block");
-
- bbox.set_pos(pos);
-}
-
-BonusBlock::~BonusBlock()
-{
- delete object;
-}
-
-void
-BonusBlock::hit(Player& )
-{
- try_open();
-}
-
-HitResponse
-BonusBlock::collision(GameObject& other, const CollisionHit& hit){
- BadGuy* badguy = dynamic_cast<BadGuy*> (&other);
- if(badguy) {
- // hit contains no information for collisions with blocks.
- // Badguy's bottom has to be below the top of the bonusblock
- // +7 is required to slide over one tile gaps.
- if( badguy->can_break() && ( badguy->get_bbox().get_bottom() > get_bbox().get_top() + 7.0) ){
- try_open();
- }
- }
- Portable* portable = dynamic_cast<Portable*> (&other);
- if(portable) {
- MovingObject* moving = dynamic_cast<MovingObject*> (&other);
- if(moving->get_bbox().get_top() > get_bbox().get_bottom() - 7.0) {
- try_open();
- }
- }
- return Block::collision(other, hit);
-}
-
-void
-BonusBlock::try_open()
-{
- if(sprite->get_action() == "empty") {
- sound_manager->play("sounds/brick.wav");
- return;
- }
-
- Sector* sector = Sector::current();
- assert(sector);
- assert(sector->player);
- Player& player = *(sector->player);
- Direction direction = (player.get_bbox().get_middle().x > get_bbox().get_middle().x) ? LEFT : RIGHT;
-
- switch(contents) {
- case CONTENT_COIN:
- Sector::current()->add_object(new BouncyCoin(get_pos()));
- player.get_status()->add_coins(1);
- Sector::current()->get_level()->stats.coins++;
- break;
-
- case CONTENT_FIREGROW:
- if(player.get_status()->bonus == NO_BONUS) {
- SpecialRiser* riser = new SpecialRiser(get_pos(), new GrowUp(direction));
- sector->add_object(riser);
- } else {
- SpecialRiser* riser = new SpecialRiser(
- get_pos(), new Flower(FIRE_BONUS));
- sector->add_object(riser);
- }
- sound_manager->play("sounds/upgrade.wav");
- break;
-
- case CONTENT_ICEGROW:
- if(player.get_status()->bonus == NO_BONUS) {
- SpecialRiser* riser = new SpecialRiser(get_pos(), new GrowUp(direction));
- sector->add_object(riser);
- } else {
- SpecialRiser* riser = new SpecialRiser(
- get_pos(), new Flower(ICE_BONUS));
- sector->add_object(riser);
- }
- sound_manager->play("sounds/upgrade.wav");
- break;
-
- case CONTENT_STAR:
- sector->add_object(new Star(get_pos() + Vector(0, -32), direction));
- break;
-
- case CONTENT_1UP:
- sector->add_object(new OneUp(get_pos(), direction));
- break;
-
- case CONTENT_CUSTOM:
- SpecialRiser* riser = new SpecialRiser(get_pos(), object);
- object = 0;
- sector->add_object(riser);
- sound_manager->play("sounds/upgrade.wav");
- break;
- }
-
- start_bounce();
- sprite->set_action("empty");
-}
-
-void
-Block::break_me()
-{
- Sector* sector = Sector::current();
- sector->add_object(
- new BrokenBrick(new Sprite(*sprite), get_pos(), Vector(-100, -400)));
- sector->add_object(
- new BrokenBrick(new Sprite(*sprite), get_pos() + Vector(0, 16),
- Vector(-150, -300)));
- sector->add_object(
- new BrokenBrick(new Sprite(*sprite), get_pos() + Vector(16, 0),
- Vector(100, -400)));
- sector->add_object(
- new BrokenBrick(new Sprite(*sprite), get_pos() + Vector(16, 16),
- Vector(150, -300)));
- remove_me();
-}
-
-IMPLEMENT_FACTORY(BonusBlock, "bonusblock");
-
-//---------------------------------------------------------------------------
-
-Brick::Brick(const Vector& pos, int data)
- : Block(sprite_manager->create("images/objects/bonus_block/brick.sprite")), breakable(false),
- coin_counter(0)
-{
- bbox.set_pos(pos);
- if(data == 1)
- coin_counter = 5;
- else
- breakable = true;
-}
-
-void
-Brick::hit(Player& )
-{
- if(sprite->get_action() == "empty")
- return;
-
- try_break(true);
-}
-
-HitResponse
-Brick::collision(GameObject& other, const CollisionHit& hit){
- BadGuy* badguy = dynamic_cast<BadGuy*> (&other);
- if(badguy) {
- // hit contains no information for collisions with blocks.
- // Badguy's bottom has to be below the top of the brick
- // +7 is required to slide over one tile gaps.
- if( badguy->can_break() && ( badguy->get_bbox().get_bottom() > get_bbox().get_top() + 7.0 ) ){
- try_break(false);
- }
- }
- Portable* portable = dynamic_cast<Portable*> (&other);
- if(portable) {
- MovingObject* moving = dynamic_cast<MovingObject*> (&other);
- if(moving->get_bbox().get_top() > get_bbox().get_bottom() - 7.0) {
- try_break();
- }
- }
- return Block::collision(other, hit);
-}
-
-void
-Brick::try_break(bool playerhit)
-{
- if(sprite->get_action() == "empty")
- return;
-
- sound_manager->play("sounds/brick.wav");
- Sector* sector = Sector::current();
- Player& player = *(sector->player);
- if(coin_counter > 0) {
- sector->add_object(new BouncyCoin(get_pos()));
- coin_counter--;
- player.get_status()->add_coins(1);
- if(coin_counter == 0)
- sprite->set_action("empty");
- start_bounce();
- } else if(breakable) {
- if(playerhit){
- if(player.is_big()){
- start_break();
- return;
- } else {
- start_bounce();
- return;
- }
- }
- break_me();
- }
-}
-
-//IMPLEMENT_FACTORY(Brick, "brick");
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __BLOCK_H__
-#define __BLOCK_H__
-
-#include "moving_object.hpp"
-#include "lisp/lisp.hpp"
-
-class Sprite;
-class Player;
-
-class Block : public MovingObject
-{
-public:
- Block(Sprite* sprite = 0);
- ~Block();
-
- virtual HitResponse collision(GameObject& other, const CollisionHit& hit);
- virtual void update(float elapsed_time);
- virtual void draw(DrawingContext& context);
-
-protected:
- friend class FlipLevelTransformer;
-
- virtual void hit(Player& player) = 0;
- void start_bounce();
- void start_break();
- void break_me();
-
- Sprite* sprite;
- bool bouncing;
- bool breaking;
- float bounce_dir;
- float bounce_offset;
- float original_y;
-
-};
-
-class BonusBlock : public Block
-{
-public:
- BonusBlock(const Vector& pos, int data);
- BonusBlock(const lisp::Lisp& lisp);
- virtual ~BonusBlock();
- HitResponse collision(GameObject& other, const CollisionHit& hit);
-
- void try_open();
-
- enum Contents {
- CONTENT_COIN,
- CONTENT_FIREGROW,
- CONTENT_ICEGROW,
- CONTENT_STAR,
- CONTENT_1UP,
- CONTENT_CUSTOM
- };
-
- Contents contents;
-protected:
- virtual void hit(Player& player);
-
-private:
- MovingObject* object;
-};
-
-class Brick : public Block
-{
-public:
- Brick(const Vector& pos, int data);
-
- void try_break(bool playerhit = false);
- HitResponse collision(GameObject& other, const CollisionHit& hit);
-
-protected:
- virtual void hit(Player& player);
-
-private:
- bool breakable;
- int coin_counter;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include <math.h>
-#include "bullet.hpp"
-#include "resources.hpp"
-#include "camera.hpp"
-#include "sector.hpp"
-#include "sprite/sprite_manager.hpp"
-#include "badguy/badguy.hpp"
-#include "main.hpp"
-
-namespace {
- const float BULLET_XM = 600;
- const float BULLET_STARTING_YM = 0;
-}
-
-Bullet::Bullet(const Vector& pos, float xm, int dir, BonusType type)
- : life_count(3), type(type)
-{
- float speed = dir == RIGHT ? BULLET_XM : -BULLET_XM;
- physic.set_velocity_x(speed + xm);
-
- if(type == FIRE_BONUS) {
- sprite.reset(sprite_manager->create("images/objects/bullets/firebullet.sprite"));
- } else if(type == ICE_BONUS) {
- life_count = 10;
- sprite.reset(sprite_manager->create("images/objects/bullets/icebullet.sprite"));
- }
-
- bbox.set_pos(pos);
- bbox.set_size(sprite->get_current_hitbox_width(), sprite->get_current_hitbox_height());
-}
-
-Bullet::~Bullet()
-{
-}
-
-void
-Bullet::update(float elapsed_time)
-{
- // remove bullet when it's offscreen
- float scroll_x =
- Sector::current()->camera->get_translation().x;
- float scroll_y =
- Sector::current()->camera->get_translation().y;
- if (get_pos().x < scroll_x ||
- get_pos().x > scroll_x + SCREEN_WIDTH ||
-// get_pos().y < scroll_y ||
- get_pos().y > scroll_y + SCREEN_HEIGHT ||
- life_count <= 0) {
- remove_me();
- return;
- }
-
- movement = physic.get_movement(elapsed_time);
-}
-
-void
-Bullet::draw(DrawingContext& context)
-{
- sprite->draw(context, get_pos(), LAYER_OBJECTS);
-}
-
-void
-Bullet::collision_solid(const CollisionHit& hit)
-{
- if(hit.top || hit.bottom) {
- physic.set_velocity_y(-physic.get_velocity_y());
- life_count--;
- } else if(hit.left || hit.right) {
- if(type == ICE_BONUS) {
- physic.set_velocity_x(-physic.get_velocity_x());
- life_count--;
- } else
- remove_me();
- }
-}
-
-void
-Bullet::ricochet(GameObject& , const CollisionHit& hit)
-{
- collision_solid(hit);
-}
-
-HitResponse
-Bullet::collision(GameObject& , const CollisionHit& )
-{
- return FORCE_MOVE;
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __BULLET_H__
-#define __BULLET_H__
-
-#include "moving_object.hpp"
-#include "physic.hpp"
-#include "sprite/sprite.hpp"
-#include "player_status.hpp"
-
-class Bullet : public MovingObject, private UsesPhysic
-{
-public:
- Bullet(const Vector& pos, float xm, int dir, BonusType type);
- ~Bullet();
-
- void update(float elapsed_time);
- void draw(DrawingContext& context);
- void collision_solid(const CollisionHit& hit);
- HitResponse collision(GameObject& other, const CollisionHit& hit);
-
- /**
- * Makes bullet bounce off an object (that got hit).
- * To be called by the collision handler of that object.
- * Note that the @c hit parameter is filled in as perceived by the object, not by the bullet.
- */
- void ricochet(GameObject& other, const CollisionHit& hit);
-
- BonusType get_type()
- {
- return type;
- }
-
-private:
- int life_count;
- std::auto_ptr<Sprite> sprite;
- BonusType type;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#include <config.h>
-
-#include <stdexcept>
-#include <sstream>
-#include <cmath>
-
-#include "lisp/lisp.hpp"
-#include "lisp/writer.hpp"
-#include "lisp/list_iterator.hpp"
-#include "lisp/parser.hpp"
-#include "scripting/camera.hpp"
-#include "scripting/squirrel_util.hpp"
-#include "camera.hpp"
-#include "player.hpp"
-#include "tilemap.hpp"
-#include "game_session.hpp"
-#include "sector.hpp"
-#include "main.hpp"
-#include "object_factory.hpp"
-#include "log.hpp"
-#include "path.hpp"
-#include "path_walker.hpp"
-
-class CameraConfig
-{
-public:
- // 0 = No, 1 = Fix, 2 = Mario/Yoshi, 3 = Kirby
- int ymode;
- // as above, 4 = super metroid like
- int xmode;
- float kirby_rectsize_x;
- float kirby_rectsize_y;
- // where to fix the player (used for Yoshi and Fix camera)
- float target_y;
- float target_x;
- // maximum scrolling speed in Y direction
- float max_speed_y;
- float max_speed_x;
- // factor to dynamically increase max_speed_x based on player speed
- float dynamic_max_speed_x;
-
- // time the player has to face into the other direction before we assume a
- // changed direction
- float dirchange_time;
- // edge_x
- float edge_x;
- // when too change from noscroll mode back to lookahead left/right mode
- // set to <= 0 to disable noscroll mode
- float sensitive_x;
-
- float clamp_y;
- float clamp_x;
-
- float dynamic_speed_sm;
-
- CameraConfig() {
- xmode = 1;
- ymode = 1;
- target_x = .5f;
- target_y = 2.f/3.f;
- max_speed_y = 140;
- max_speed_x = 130;
- clamp_x = 1.f/6.f;
- clamp_y = 1.f/6.f;
- kirby_rectsize_x = 0.2f;
- kirby_rectsize_y = 0.34f;
- edge_x = 1.f/3.f;
- sensitive_x = 1.f/4.f;
- dynamic_max_speed_x = 1.0;
- dirchange_time = 0.2f;
- dynamic_speed_sm = 1.0f;
- }
-
- void load(const std::string& filename)
- {
- lisp::Parser parser;
- const lisp::Lisp* root = parser.parse(filename);
- const lisp::Lisp* camconfig = root->get_lisp("camera-config");
- if(camconfig == NULL)
- throw std::runtime_error("file is not a camera config file.");
-
- camconfig->get("xmode", xmode);
- camconfig->get("ymode", ymode);
- camconfig->get("target-x", target_x);
- camconfig->get("target-y", target_y);
- camconfig->get("max-speed-x", max_speed_x);
- camconfig->get("max-speed-y", max_speed_y);
- camconfig->get("dynamic-max-speed-x", dynamic_max_speed_x);
- camconfig->get("dirchange-time", dirchange_time);
- camconfig->get("clamp-x", clamp_x);
- camconfig->get("clamp-y", clamp_y);
- camconfig->get("kirby-rectsize-x", kirby_rectsize_x);
- camconfig->get("kirby-rectsize-y", kirby_rectsize_y);
- camconfig->get("edge-x", edge_x);
- camconfig->get("sensitive-x", sensitive_x);
- camconfig->get("dynamic-speed-sm", dynamic_speed_sm);
- }
-};
-
-Camera::Camera(Sector* newsector, std::string name)
- : mode(NORMAL), sector(newsector), lookahead_mode(LOOKAHEAD_NONE),
- lookahead_pos(0)
-{
- this->name = name;
- config = new CameraConfig();
- reload_config();
-}
-
-Camera::~Camera()
-{
- delete config;
-}
-
-void
-Camera::expose(HSQUIRRELVM vm, SQInteger table_idx)
-{
- if(name.empty()) return;
- Scripting::Camera* interface = new Scripting::Camera(this);
- expose_object(vm, table_idx, interface, name, true);
-}
-
-void
-Camera::unexpose(HSQUIRRELVM vm, SQInteger table_idx)
-{
- if(name.empty()) return;
- Scripting::unexpose_object(vm, table_idx, name);
-}
-
-void
-Camera::draw(DrawingContext& )
-{
-}
-
-const Vector&
-Camera::get_translation() const
-{
- return translation;
-}
-
-void
-Camera::parse(const lisp::Lisp& reader)
-{
- std::string modename;
-
- reader.get("mode", modename);
- if(modename == "normal") {
- mode = NORMAL;
- } else if(modename == "autoscroll") {
- mode = AUTOSCROLL;
-
- const lisp::Lisp* pathLisp = reader.get_lisp("path");
- if(pathLisp == NULL)
- throw std::runtime_error("No path specified in autoscroll camera.");
-
- autoscroll_path.reset(new Path());
- autoscroll_path->read(*pathLisp);
- autoscroll_walker.reset(new PathWalker(autoscroll_path.get()));
- } else if(modename == "manual") {
- mode = MANUAL;
- } else {
- std::stringstream str;
- str << "invalid camera mode '" << modename << "'found in worldfile.";
- throw std::runtime_error(str.str());
- }
-}
-
-void
-Camera::write(lisp::Writer& writer)
-{
- writer.start_list("camera");
-
- if(mode == NORMAL) {
- writer.write_string("mode", "normal");
- } else if(mode == AUTOSCROLL) {
- writer.write_string("mode", "autoscroll");
- autoscroll_path->write(writer);
- } else if(mode == MANUAL) {
- writer.write_string("mode", "manual");
- }
-
- writer.end_list("camera");
-}
-
-void
-Camera::reset(const Vector& tuxpos)
-{
- translation.x = tuxpos.x - SCREEN_WIDTH/3 * 2;
- translation.y = tuxpos.y - SCREEN_HEIGHT/2;
- shakespeed = 0;
- shaketimer.stop();
- keep_in_bounds(translation);
-}
-
-void
-Camera::shake(float time, float x, float y)
-{
- shaketimer.start(time);
- shakedepth_x = x;
- shakedepth_y = y;
- shakespeed = M_PI/2 / time;
-}
-
-void
-Camera::scroll_to(const Vector& goal, float scrolltime)
-{
- scroll_from = translation;
- scroll_goal = goal;
- keep_in_bounds(scroll_goal);
-
- scroll_to_pos = 0;
- scrollspeed = 1.0 / scrolltime;
- mode = SCROLLTO;
-}
-
-static const float EPSILON = .00001f;
-static const float MAX_SPEED_Y = 140;
-
-void
-Camera::update(float elapsed_time)
-{
- switch(mode) {
- case NORMAL:
- update_scroll_normal(elapsed_time);
- break;
- case AUTOSCROLL:
- update_scroll_autoscroll(elapsed_time);
- break;
- case SCROLLTO:
- update_scroll_to(elapsed_time);
- break;
- default:
- break;
- }
- shake();
-}
-
-void
-Camera::reload_config()
-{
- config->load("camera.cfg");
-}
-
-float clamp(float val, float min, float max)
-{
- if(val < min)
- return min;
- if(val > max)
- return max;
-
- return val;
-}
-
-void
-Camera::keep_in_bounds(Vector& translation)
-{
- float width = sector->get_width();
- float height = sector->get_height();
-
- // don't scroll before the start or after the level's end
- translation.x = clamp(translation.x, 0, width - SCREEN_WIDTH);
- translation.y = clamp(translation.y, 0, height - SCREEN_HEIGHT);
-
- if (height < SCREEN_HEIGHT)
- translation.y = height/2.0 - SCREEN_HEIGHT/2.0;
- if (width < SCREEN_WIDTH)
- translation.x = width/2.0 - SCREEN_WIDTH/2.0;
-}
-
-void
-Camera::shake()
-{
- if(shaketimer.started()) {
- translation.x -= sin(shaketimer.get_timegone() * shakespeed) * shakedepth_x;
- translation.y -= sin(shaketimer.get_timegone() * shakespeed) * shakedepth_y;
- }
-}
-
-void
-Camera::update_scroll_normal(float elapsed_time)
-{
- const CameraConfig& config = *(this->config);
- Player* player = sector->player;
- const Vector& player_pos = player->get_bbox().get_middle();
- static Vector last_player_pos = player_pos;
- Vector player_delta = player_pos - last_player_pos;
- last_player_pos = player_pos;
-
- // check that we don't have division by zero later
- if(elapsed_time < EPSILON)
- return;
-
- /****** Vertical Scrolling part ******/
- int xmode = config.xmode;
- int ymode = config.ymode;
-
- if(player->is_dying() || sector->get_height() == 19*32) {
- ymode = 0;
- }
- if(player->is_dying())
- xmode = 0;
-
- if(ymode == 1) {
- translation.y = player_pos.y - SCREEN_HEIGHT * config.target_y;
- }
- if(ymode == 2) {
- // target_y is the high we target our scrolling at. This is not always the
- // high of the player, but if he is jumping upwards we should use the
- // position where he last touched the ground. (this probably needs
- // exceptions for trampolines and similar things in the future)
- float target_y;
- if(player->fall_mode == Player::JUMPING)
- target_y = player->last_ground_y + player->get_bbox().get_height();
- else
- target_y = player->get_bbox().p2.y;
- target_y -= SCREEN_HEIGHT * config.target_y;
-
- // delta_y is the distance we'd have to travel to directly reach target_y
- float delta_y = translation.y - target_y;
- // speed is the speed the camera would need to reach target_y in this frame
- float speed_y = delta_y / elapsed_time;
-
- // limit the camera speed when jumping upwards
- if(player->fall_mode != Player::FALLING
- && player->fall_mode != Player::TRAMPOLINE_JUMP) {
- speed_y = clamp(speed_y, -config.max_speed_y, config.max_speed_y);
- }
-
- // scroll with calculated speed
- translation.y -= speed_y * elapsed_time;
- }
- if(ymode == 3) {
- float halfsize = config.kirby_rectsize_y * 0.5f;
- translation.y = clamp(translation.y,
- player_pos.y - SCREEN_HEIGHT * (0.5f + halfsize),
- player_pos.y - SCREEN_HEIGHT * (0.5f - halfsize));
- }
- if(ymode == 4) {
- // TODO...
- }
-
- if(ymode != 0 && config.clamp_y > 0) {
- translation.y = clamp(translation.y,
- player_pos.y - SCREEN_HEIGHT * (1-config.clamp_y),
- player_pos.y - SCREEN_HEIGHT * config.clamp_y);
- }
-
- /****** Horizontal scrolling part *******/
-
- if(xmode == 1) {
- translation.x = player_pos.x - SCREEN_WIDTH * config.target_x;
- }
- if(xmode == 2) {
- // our camera is either in leftscrolling, rightscrolling or
- // nonscrollingmode.
- //
- // when suddenly changing directions while scrolling into the other
- // direction abort scrolling, since tux might be going left/right at a
- // relatively small part of the map (like when jumping upwards)
-
- // Find out direction in which the player moves
- LookaheadMode walkDirection;
- if (player_delta.x < -EPSILON) walkDirection = LOOKAHEAD_LEFT;
- else if (player_delta.x > EPSILON) walkDirection = LOOKAHEAD_RIGHT;
- else if (player->dir == ::LEFT) walkDirection = LOOKAHEAD_LEFT;
- else walkDirection = LOOKAHEAD_RIGHT;
-
- float LEFTEND, RIGHTEND;
- if(config.sensitive_x > 0) {
- LEFTEND = SCREEN_WIDTH * config.sensitive_x;
- RIGHTEND = SCREEN_WIDTH * (1-config.sensitive_x);
- } else {
- LEFTEND = SCREEN_WIDTH;
- RIGHTEND = 0;
- }
-
- if(lookahead_mode == LOOKAHEAD_NONE) {
- /* if we're undecided then look if we crossed the left or right
- * "sensitive" area */
- if(player_pos.x < translation.x + LEFTEND) {
- lookahead_mode = LOOKAHEAD_LEFT;
- } else if(player_pos.x > translation.x + RIGHTEND) {
- lookahead_mode = LOOKAHEAD_RIGHT;
- }
- /* at the ends of a level it's obvious which way we will go */
- if(player_pos.x < SCREEN_WIDTH*0.5) {
- lookahead_mode = LOOKAHEAD_RIGHT;
- } else if(player_pos.x >= sector->get_width() - SCREEN_WIDTH*0.5) {
- lookahead_mode = LOOKAHEAD_LEFT;
- }
-
- changetime = -1;
- } else if(lookahead_mode != walkDirection) {
- /* player changed direction while camera was scrolling...
- * he has to do this for a certain time to add robustness against
- * sudden changes */
- if(changetime < 0) {
- changetime = game_time;
- } else if(game_time - changetime > config.dirchange_time) {
- if(lookahead_mode == LOOKAHEAD_LEFT &&
- player_pos.x > translation.x + RIGHTEND) {
- lookahead_mode = LOOKAHEAD_RIGHT;
- } else if(lookahead_mode == LOOKAHEAD_RIGHT &&
- player_pos.x < translation.x + LEFTEND) {
- lookahead_mode = LOOKAHEAD_LEFT;
- } else {
- lookahead_mode = LOOKAHEAD_NONE;
- }
- }
- } else {
- changetime = -1;
- }
-
- LEFTEND = SCREEN_WIDTH * config.edge_x;
- RIGHTEND = SCREEN_WIDTH * (1-config.edge_x);
-
- // calculate our scroll target depending on scroll mode
- float target_x;
- if(lookahead_mode == LOOKAHEAD_LEFT)
- target_x = player_pos.x - RIGHTEND;
- else if(lookahead_mode == LOOKAHEAD_RIGHT)
- target_x = player_pos.x - LEFTEND;
- else
- target_x = translation.x;
-
- // that's the distance we would have to travel to reach target_x
- float delta_x = translation.x - target_x;
- // the speed we'd need to travel to reach target_x in this frame
- float speed_x = delta_x / elapsed_time;
-
- // limit our speed
- float player_speed_x = player_delta.x / elapsed_time;
- float maxv = config.max_speed_x + (fabsf(player_speed_x * config.dynamic_max_speed_x));
- speed_x = clamp(speed_x, -maxv, maxv);
-
- // If player is peeking scroll in that direction. Fast.
- if(player->peeking_direction() == ::LEFT) {
- speed_x = config.max_speed_x;
- }
- if(player->peeking_direction() == ::RIGHT) {
- speed_x = -config.max_speed_x;
- }
-
- // apply scrolling
- translation.x -= speed_x * elapsed_time;
- }
- if(xmode == 3) {
- float halfsize = config.kirby_rectsize_x * 0.5f;
- translation.x = clamp(translation.x,
- player_pos.x - SCREEN_WIDTH * (0.5f + halfsize),
- player_pos.x - SCREEN_WIDTH * (0.5f - halfsize));
- }
- if(xmode == 4) {
- float LEFTEND = SCREEN_WIDTH * config.edge_x;
- float RIGHTEND = SCREEN_WIDTH * (1 - config.edge_x);
-
- if (player_delta.x < -EPSILON) {
- // walking left
- lookahead_pos -= player_delta.x * config.dynamic_speed_sm;
-
- if(lookahead_pos > RIGHTEND) {
- lookahead_pos = RIGHTEND;
- }
- } else if (player_delta.x > EPSILON) {
- // walking right
- lookahead_pos -= player_delta.x * config.dynamic_speed_sm;
- if(lookahead_pos < LEFTEND) {
- lookahead_pos = LEFTEND;
- }
- }
-
- if(player->peeking_direction() == ::LEFT) {
- lookahead_pos += config.max_speed_x * elapsed_time * 3.0f;
- } else if(player->peeking_direction() == ::RIGHT) {
- lookahead_pos -= config.max_speed_x * elapsed_time * 3.0f;
- }
-
- // adjust for level ends
- if (player_pos.x < LEFTEND) {
- lookahead_pos = LEFTEND;
- }
- if (player_pos.x > sector->get_width() - LEFTEND) {
- lookahead_pos = RIGHTEND;
- }
-
- translation.x = player_pos.x - lookahead_pos;
- }
-
- if(xmode != 0 && config.clamp_x > 0) {
- translation.x = clamp(translation.x,
- player_pos.x - SCREEN_WIDTH * (1-config.clamp_x),
- player_pos.x - SCREEN_WIDTH * config.clamp_x);
- }
-
- keep_in_bounds(translation);
-}
-
-void
-Camera::update_scroll_autoscroll(float elapsed_time)
-{
- Player* player = sector->player;
- if(player->is_dying())
- return;
-
- translation = autoscroll_walker->advance(elapsed_time);
-
- keep_in_bounds(translation);
-}
-
-void
-Camera::update_scroll_to(float elapsed_time)
-{
- scroll_to_pos += elapsed_time * scrollspeed;
- if(scroll_to_pos >= 1.0) {
- mode = MANUAL;
- translation = scroll_goal;
- return;
- }
-
- translation = scroll_from + (scroll_goal - scroll_from) * scroll_to_pos;
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#ifndef SUPERTUX_CAMERA_H
-#define SUPERTUX_CAMERA_H
-
-#include <vector>
-#include <cassert>
-#include <memory>
-
-#include "math/vector.hpp"
-#include "game_object.hpp"
-#include "video/drawing_context.hpp"
-#include "serializable.hpp"
-#include "timer.hpp"
-#include "script_interface.hpp"
-
-namespace lisp {
-class Lisp;
-}
-
-class Sector;
-class Path;
-class PathWalker;
-class CameraConfig;
-
-class Camera : public GameObject, public Serializable, public ScriptInterface
-{
-public:
- Camera(Sector* sector, std::string name = "");
- virtual ~Camera();
-
- /// parse camera mode from lisp file
- void parse(const lisp::Lisp& reader);
- /// write camera mode to a lisp file
- virtual void write(lisp::Writer& writer);
-
- /// reset camera postion
- void reset(const Vector& tuxpos);
-
- /** return camera position */
- const Vector& get_translation() const;
-
- virtual void update(float elapsed_time);
-
- virtual void draw(DrawingContext& );
-
- virtual void expose(HSQUIRRELVM vm, SQInteger table_idx);
- virtual void unexpose(HSQUIRRELVM vm, SQInteger table_idx);
-
- // shake camera in a direction 1 time
- void shake(float speed, float x, float y);
-
- void set_scrolling(int scroll_x, int scroll_y)
- {
- translation.x = scroll_x;
- translation.y = scroll_y;
- }
-
- /**
- * scroll the upper left edge of the camera in scrolltime seconds
- * to the position goal
- */
- void scroll_to(const Vector& goal, float scrolltime);
-
- void reload_config();
-
- enum CameraMode
- {
- NORMAL, AUTOSCROLL, SCROLLTO, MANUAL
- };
- CameraMode mode;
-
-private:
- void update_scroll_normal(float elapsed_time);
- void update_scroll_autoscroll(float elapsed_time);
- void update_scroll_to(float elapsed_time);
- void keep_in_bounds(Vector& vector);
- void shake();
-
- /**
- * The camera basically provides lookeahead on the left or right side
- * or is undecided.
- */
- enum LookaheadMode {
- LOOKAHEAD_NONE, LOOKAHEAD_LEFT, LOOKAHEAD_RIGHT
- };
-
- Vector translation;
-
- Sector* sector;
-
- // normal mode
- LookaheadMode lookahead_mode;
- float changetime;
- float lookahead_pos;
-
- // autoscroll mode
- std::auto_ptr<Path> autoscroll_path;
- std::auto_ptr<PathWalker> autoscroll_walker;
-
- // shaking
- Timer shaketimer;
- float shakespeed;
- float shakedepth_x;
- float shakedepth_y;
-
- // scrollto mode
- Vector scroll_from;
- Vector scroll_goal;
- float scroll_to_pos;
- float scrollspeed;
-
- CameraConfig *config;
-};
-
-#endif /*SUPERTUX_CAMERA_H*/
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
-//
-// 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.
-
-#include <config.h>
-
-#include "candle.hpp"
-#include "scripting/candle.hpp"
-#include "scripting/squirrel_util.hpp"
-#include "sector.hpp"
-#include "object/sprite_particle.hpp"
-#include "object_factory.hpp"
-#include "random_generator.hpp"
-
-Candle::Candle(const lisp::Lisp& lisp)
- : MovingSprite(lisp, "images/objects/candle/candle.sprite", LAYER_BACKGROUNDTILES+1, COLGROUP_DISABLED), burning(true),
- candle_light_1("images/objects/candle/candle-light-1.png"),
- candle_light_2("images/objects/candle/candle-light-2.png")
-{
- lisp.get("name", name);
- lisp.get("burning", burning);
-
- if (burning) {
- sprite->set_action("on");
- } else {
- sprite->set_action("off");
- }
-
-}
-
-void
-Candle::draw(DrawingContext& context)
-{
- // draw regular sprite
- sprite->draw(context, get_pos(), layer);
-
- // draw on lightmap
- if (burning) {
- Vector pos = get_pos() + (bbox.get_size() - candle_light_1.get_size()) / 2;
- context.push_target();
- context.set_target(DrawingContext::LIGHTMAP);
- // draw approx. 1 in 10 frames darker. Makes the candle flicker
- if (systemRandom.rand(10) != 0) {
- context.draw_surface(&candle_light_1, pos, layer);
- } else {
- context.draw_surface(&candle_light_2, pos, layer);
- }
- context.pop_target();
- }
-}
-
-HitResponse
-Candle::collision(GameObject&, const CollisionHit& )
-{
- return FORCE_MOVE;
-}
-
-void
-Candle::expose(HSQUIRRELVM vm, SQInteger table_idx)
-{
- if (name.empty()) return;
- Scripting::Candle* interface = new Scripting::Candle(this);
- expose_object(vm, table_idx, interface, name, true);
-}
-
-void
-Candle::unexpose(HSQUIRRELVM vm, SQInteger table_idx)
-{
- if (name.empty()) return;
- Scripting::unexpose_object(vm, table_idx, name);
-}
-
-void
-Candle::puff_smoke()
-{
- Vector ppos = bbox.get_middle();
- Vector pspeed = Vector(0, -150);
- Vector paccel = Vector(0,0);
- Sector::current()->add_object(new SpriteParticle("images/objects/particles/smoke.sprite", "default", ppos, ANCHOR_MIDDLE, pspeed, paccel, LAYER_BACKGROUNDTILES+2));
-}
-
-bool
-Candle::get_burning()
-{
- return burning;
-}
-
-void
-Candle::set_burning(bool burning)
-{
- if (this->burning == burning) return;
- this->burning = burning;
- if (burning) {
- sprite->set_action("on");
- puff_smoke();
- } else {
- sprite->set_action("off");
- puff_smoke();
- }
-}
-
-IMPLEMENT_FACTORY(Candle, "candle");
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
-//
-// 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.
-
-#ifndef __CANDLE_H__
-#define __CANDLE_H__
-
-#include <string>
-
-#include "lisp/lisp.hpp"
-#include "object/moving_sprite.hpp"
-#include "script_interface.hpp"
-#include "video/surface.hpp"
-
-/**
- * A burning candle: Simple, scriptable level decoration.
- */
-class Candle : public MovingSprite, public ScriptInterface
-{
-public:
- Candle(const lisp::Lisp& lisp);
- virtual Candle* clone() const { return new Candle(*this); }
- virtual void draw(DrawingContext& context);
-
- HitResponse collision(GameObject& other, const CollisionHit& hit);
-
- virtual void expose(HSQUIRRELVM vm, SQInteger table_idx);
- virtual void unexpose(HSQUIRRELVM vm, SQInteger table_idx);
-
- /**
- * @name Scriptable Methods
- * @{
- */
- void puff_smoke(); /**< spawn a puff of smoke */
- bool get_burning(); /**< returns true if candle is lighted */
- void set_burning(bool burning); /**< true: light candle, false: extinguish candle */
- /**
- * @}
- */
-
-private:
- bool burning; /**< true if candle is currently lighted */
- Surface candle_light_1; /**< drawn to lightmap */
- Surface candle_light_2; /**< drawn to lightmap (alternative image) */
-
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include "coin.hpp"
-#include "resources.hpp"
-#include "video/drawing_context.hpp"
-#include "sprite/sprite_manager.hpp"
-#include "player.hpp"
-#include "sector.hpp"
-#include "player_status.hpp"
-#include "gameobjs.hpp"
-#include "statistics.hpp"
-#include "object_factory.hpp"
-#include "level.hpp"
-#include "random_generator.hpp"
-#include "audio/sound_source.hpp"
-#include "audio/sound_manager.hpp"
-#include "timer.hpp"
-
-Coin::Coin(const Vector& pos)
- : MovingSprite(pos, "images/objects/coin/coin.sprite", LAYER_TILES, COLGROUP_TOUCHABLE)
-{
- sound_manager->preload("sounds/coin.wav");
-}
-
-Coin::Coin(const lisp::Lisp& reader)
- : MovingSprite(reader, "images/objects/coin/coin.sprite", LAYER_TILES, COLGROUP_TOUCHABLE)
-{
- sound_manager->preload("sounds/coin.wav");
-}
-
-void
-Coin::collect()
-{
- // TODO: commented out musical code. Maybe fork this for a special "MusicalCoin" object?
- /*
- static Timer sound_timer;
- static int pitch_one = 128;
- static float last_pitch = 1;
- float pitch = 1;
-
- int tile = static_cast<int>(get_pos().y / 32);
-
- if (!sound_timer.started()) {
- pitch_one = tile;
- pitch = 1;
- last_pitch = 1;
- }
- else if (sound_timer.get_timegone() < 0.02) {
- pitch = last_pitch;
- }
- else
- {
- switch ((pitch_one - tile) % 7) {
- case -6:
- pitch = 1.0/2;
- break;
- case -5:
- pitch = 5.0/8;
- break;
- case -4:
- pitch = 4.0/6;
- break;
- case -3:
- pitch = 3.0/4;
- break;
- case -2:
- pitch = 5.0/6;
- break;
- case -1:
- pitch = 9.0/10;
- break;
- case 0:
- pitch = 1.0;
- break;
- case 1:
- pitch = 9.0/8;
- break;
- case 2:
- pitch = 5.0/4;
- break;
- case 3:
- pitch = 4.0/3;
- break;
- case 4:
- pitch = 3.0/2;
- break;
- case 5:
- pitch = 5.0/3;
- break;
- case 6:
- pitch = 9.0/5;
- break;
- }
- last_pitch = pitch;
- }
- sound_timer.start(1);
-
- SoundSource* soundSource = sound_manager->create_sound_source("sounds/coin.wav");
- soundSource->set_position(get_pos());
- soundSource->set_pitch(pitch);
- soundSource->play();
- sound_manager->manage_source(soundSource);
-*/
- Sector::current()->player->get_status()->add_coins(1);
- Sector::current()->add_object(new BouncyCoin(get_pos()));
- Sector::current()->get_level()->stats.coins++;
- remove_me();
-}
-
-HitResponse
-Coin::collision(GameObject& other, const CollisionHit& )
-{
- Player* player = dynamic_cast<Player*>(&other);
- if(player == 0)
- return ABORT_MOVE;
-
- collect();
- return ABORT_MOVE;
-}
-
-IMPLEMENT_FACTORY(Coin, "coin");
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __COIN_H__
-#define __COIN_H__
-
-#include "moving_sprite.hpp"
-#include "lisp/lisp.hpp"
-
-class Coin : public MovingSprite
-{
-public:
- Coin(const Vector& pos);
- Coin(const lisp::Lisp& reader);
-
- HitResponse collision(GameObject& other, const CollisionHit& hit);
-
- void collect();
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-#include "display_effect.hpp"
-
-#include <assert.h>
-#include "video/drawing_context.hpp"
-#include "scripting/squirrel_util.hpp"
-#include "main.hpp"
-
-static const float BORDER_SIZE = 75;
-
-DisplayEffect::DisplayEffect(std::string name)
- : screen_fade(NO_FADE), screen_fadetime(0), screen_fading(0),
- border_fade(NO_FADE), border_fadetime(0), border_size(0), black(false),
- borders(false)
-{
- this->name = name;
-}
-
-DisplayEffect::~DisplayEffect()
-{
-}
-
-void
-DisplayEffect::expose(HSQUIRRELVM vm, SQInteger table_idx)
-{
- if (name.empty()) return;
- expose_object(vm, table_idx, dynamic_cast<Scripting::DisplayEffect *>(this), name, false);
-}
-
-void
-DisplayEffect::unexpose(HSQUIRRELVM vm, SQInteger table_idx)
-{
- if (name.empty()) return;
- Scripting::unexpose_object(vm, table_idx, name);
-}
-
-void
-DisplayEffect::update(float elapsed_time)
-{
- switch(screen_fade) {
- case NO_FADE:
- break;
- case FADE_IN:
- screen_fading -= elapsed_time;
- if(screen_fading < 0) {
- screen_fade = NO_FADE;
- }
- break;
- case FADE_OUT:
- screen_fading -= elapsed_time;
- if(screen_fading < 0) {
- screen_fade = NO_FADE;
- black = true;
- }
- break;
- default:
- assert(false);
- }
-
- switch(border_fade) {
- case NO_FADE:
- break;
- case FADE_IN:
- border_fading -= elapsed_time;
- if(border_fading < 0) {
- border_fade = NO_FADE;
- }
- border_size = (border_fadetime - border_fading)
- / border_fadetime * BORDER_SIZE;
- break;
- case FADE_OUT:
- border_fading -= elapsed_time;
- if(border_fading < 0) {
- borders = false;
- border_fade = NO_FADE;
- }
- border_size = border_fading / border_fadetime * BORDER_SIZE;
- break;
- default:
- assert(false);
- }
-}
-
-void
-DisplayEffect::draw(DrawingContext& context)
-{
- context.push_transform();
- context.set_translation(Vector(0, 0));
-
- if(black || screen_fade != NO_FADE) {
- float alpha;
- if(black) {
- alpha = 1.0f;
- } else {
- switch(screen_fade) {
- case FADE_IN:
- alpha = screen_fading / screen_fadetime;
- break;
- case FADE_OUT:
- alpha = (screen_fadetime - screen_fading) / screen_fadetime;
- break;
- default:
- alpha = 0;
- assert(false);
- }
- }
- context.draw_filled_rect(Vector(0, 0), Vector(SCREEN_WIDTH, SCREEN_HEIGHT),
- Color(0, 0, 0, alpha), LAYER_GUI-10);
- }
-
- if (borders) {
- context.draw_filled_rect(Vector(0, 0), Vector(SCREEN_WIDTH, border_size),
- Color(0, 0, 0, 1.0f), LAYER_GUI-10);
- context.draw_filled_rect(Vector(0, SCREEN_HEIGHT - border_size), Vector(SCREEN_WIDTH, border_size),
- Color(0, 0, 0, 1.0f), LAYER_GUI-10);
- }
-
- context.pop_transform();
-}
-
-void
-DisplayEffect::fade_out(float fadetime)
-{
- black = false;
- screen_fadetime = fadetime;
- screen_fading = fadetime;
- screen_fade = FADE_OUT;
-}
-
-void
-DisplayEffect::fade_in(float fadetime)
-{
- black = false;
- this->screen_fadetime = fadetime;
- screen_fading = fadetime;
- screen_fade = FADE_IN;
-}
-
-void
-DisplayEffect::set_black(bool enabled)
-{
- black = enabled;
-}
-
-bool
-DisplayEffect::is_black()
-{
- return black;
-}
-
-void
-DisplayEffect::sixteen_to_nine(float fadetime)
-{
- if(fadetime == 0) {
- borders = true;
- border_size = BORDER_SIZE;
- } else {
- borders = true;
- border_size = 0;
- border_fade = FADE_IN;
- border_fadetime = fadetime;
- border_fading = border_fadetime;
- }
-}
-
-void
-DisplayEffect::four_to_three(float fadetime)
-{
- if(fadetime == 0) {
- borders = false;
- } else {
- border_size = BORDER_SIZE;
- border_fade = FADE_OUT;
- border_fadetime = fadetime;
- border_fading = border_fadetime;
- }
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __OBJECT_DISPLAY_EFFECT_H__
-#define __OBJECT_DISPLAY_EFFECT_H__
-
-#include "scripting/display_effect.hpp"
-#include "game_object.hpp"
-#include "script_interface.hpp"
-
-class DisplayEffect : public GameObject, public Scripting::DisplayEffect,
- public ScriptInterface
-{
-public:
- DisplayEffect(std::string name = "");
- virtual ~DisplayEffect();
-
- void expose(HSQUIRRELVM vm, SQInteger table_idx);
- void unexpose(HSQUIRRELVM vm, SQInteger table_idx);
-
- void update(float elapsed_time);
- void draw(DrawingContext& context);
-
-
- /**
- * @name Scriptable Methods
- * @{
- */
-
- void fade_out(float fadetime);
- void fade_in(float fadetime);
- void set_black(bool enabled);
- bool is_black();
- void sixteen_to_nine(float fadetime);
- void four_to_three(float fadetime);
-
- /**
- * @}
- */
-
-private:
- enum FadeType {
- NO_FADE, FADE_IN, FADE_OUT
- };
- FadeType screen_fade;
- float screen_fadetime;
- float screen_fading;
- FadeType border_fade;
- float border_fadetime;
- float border_fading;
- float border_size;
-
- bool black;
- bool borders;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-#include "electrifier.hpp"
-#include "sector.hpp"
-#include "object/tilemap.hpp"
-#include "tile.hpp"
-
-
-Electrifier::Electrifier(uint32_t oldtile, uint32_t newtile, float seconds)
-{
- duration.start(seconds);
- change_from = oldtile;
- change_to = newtile;
- Sector::current()->change_solid_tiles(change_from,change_to);
-}
-
-Electrifier::~Electrifier() {
-}
-
-void
-Electrifier::update(float )
-{
- if (duration.check()) {
- Sector::current()->change_solid_tiles(change_to,change_from);
- remove_me();
- }
-}
-
-void
-Electrifier::draw(DrawingContext& )
-{
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __ELECTRIFIER_H__
-#define __ELECTRIFIER_H__
-
-#include "resources.hpp"
-#include "game_object.hpp"
-#include "timer.hpp"
-#include <stdint.h>
-
-//Changes all tiles with the given ID to a new one for a given amount of time, then removes itself
-//Used by the Kugelblitz to electrify water - can be used for other effects, too
-class Electrifier : public GameObject
-{
-public:
- Electrifier(uint32_t oldtile, uint32_t newtile, float seconds);
- ~Electrifier();
-protected:
- virtual void update(float time);
- virtual void draw(DrawingContext& context);
-private:
- uint32_t change_from;
- uint32_t change_to;
- Timer duration;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux - End Sequence
-// Copyright (C) 2007 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
-//
-// 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.
-
-#include <config.h>
-
-#include "endsequence.hpp"
-
-#include <stdexcept>
-#include <iostream>
-#include <sstream>
-#include "main.hpp"
-#include "resources.hpp"
-#include "sector.hpp"
-#include "gettext.hpp"
-#include "object_factory.hpp"
-#include "object/player.hpp"
-#include "video/drawing_context.hpp"
-#include "lisp/list_iterator.hpp"
-#include "log.hpp"
-#include "scripting/level_time.hpp"
-#include "scripting/squirrel_util.hpp"
-
-EndSequence::EndSequence()
-: isrunning(false), isdone(false), tux_may_walk(true)
-{
- end_sequence_controller = 0;
-}
-
-EndSequence::~EndSequence()
-{
- delete end_sequence_controller;
-}
-
-void
-EndSequence::update(float elapsed_time)
-{
- if (!isrunning) return;
- running(elapsed_time);
-}
-
-void
-EndSequence::draw(DrawingContext& /*context*/)
-{
-}
-
-void
-EndSequence::start()
-{
- if (isrunning) return;
- isrunning = true;
- isdone = false;
-
- Player& tux = *Sector::current()->player;
- end_sequence_controller = new CodeController();
- tux.set_controller(end_sequence_controller);
- tux.set_speedlimit(230); //MAX_WALK_XM
-
- starting();
-}
-
-void
-EndSequence::stop_tux()
-{
- tux_may_walk = false;
-}
-
-void
-EndSequence::stop()
-{
- if (!isrunning) return;
- isrunning = false;
- isdone = true;
- stopping();
-}
-
-bool
-EndSequence::is_tux_stopped()
-{
- return !tux_may_walk;
-}
-
- bool
-EndSequence::is_done()
-{
- return isdone;
-}
-
-void
-EndSequence::starting()
-{
-}
-
-void
-EndSequence::running(float /*elapsed_time*/)
-{
-}
-
-void
-EndSequence::stopping()
-{
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux - End Sequence
-// Copyright (C) 2007 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
-//
-// 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.
-
-#ifndef __ENDSEQUENCE_H__
-#define __ENDSEQUENCE_H__
-
-#include <memory>
-#include "game_object.hpp"
-#include "timer.hpp"
-#include "lisp/lisp.hpp"
-#include "control/codecontroller.hpp"
-
-class EndSequence : public GameObject
-{
-public:
- EndSequence();
- virtual ~EndSequence();
-
- virtual void update(float elapsed_time);
- virtual void draw(DrawingContext& context);
-
- void start(); /**< play EndSequence */
- void stop_tux(); /**< called when Tux has reached his final position */
- void stop(); /**< stop playing EndSequence, mark it as done playing */
- bool is_tux_stopped(); /**< returns true if Tux has reached his final position */
- bool is_done(); /**< returns true if EndSequence has finished playing */
-
-protected:
- virtual void starting(); /**< called when EndSequence starts */
- virtual void running(float elapsed_time); /**< called while the EndSequence is running */
- virtual void stopping(); /**< called when EndSequence stops */
-
- bool isrunning; /**< true while EndSequence plays */
- bool isdone; /**< true if EndSequence has finished playing */
- bool tux_may_walk; /**< true while tux is allowed to walk */
- CodeController* end_sequence_controller;
-
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux - End Sequence: Tux walks right
-// Copyright (C) 2007 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
-//
-// 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.
-
-#include <config.h>
-#include "endsequence_fireworks.hpp"
-#include "sector.hpp"
-#include "mainloop.hpp"
-#include "object/player.hpp"
-#include "object/fireworks.hpp"
-
-EndSequenceFireworks::EndSequenceFireworks()
-: EndSequence()
-{
-}
-
-EndSequenceFireworks::~EndSequenceFireworks()
-{
-}
-
-void
-EndSequenceFireworks::draw(DrawingContext& /*context*/)
-{
-}
-
-void
-EndSequenceFireworks::starting()
-{
- EndSequence::starting();
- endsequence_timer.start(7.3f * main_loop->get_speed());
- Sector::current()->add_object(new Fireworks());
-}
-
-void
-EndSequenceFireworks::running(float elapsed_time)
-{
- EndSequence::running(elapsed_time);
- //Player& tux = *Sector::current()->player;
-
- if (tux_may_walk) {
- end_sequence_controller->press(Controller::JUMP);
- }
-
- if (endsequence_timer.check()) isdone = true;
-}
-
-void
-EndSequenceFireworks::stopping()
-{
- EndSequence::stopping();
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux - End Sequence: Tux walks right
-// Copyright (C) 2007 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
-//
-// 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.
-
-#ifndef __ENDSEQUENCE_FIREWORKS_H__
-#define __ENDSEQUENCE_FIREWORKS_H__
-
-#include <memory>
-#include "object/endsequence.hpp"
-#include "timer.hpp"
-
-class EndSequenceFireworks : public EndSequence
-{
-public:
- EndSequenceFireworks();
- virtual ~EndSequenceFireworks();
- virtual void draw(DrawingContext& context);
-
-protected:
- virtual void starting(); /**< called when EndSequence starts */
- virtual void running(float elapsed_time); /**< called while the EndSequence is running */
- virtual void stopping(); /**< called when EndSequence stops */
-
- Timer endsequence_timer;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux - End Sequence: Tux walks right
-// Copyright (C) 2007 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
-//
-// 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.
-
-#include <config.h>
-#include "endsequence_walkleft.hpp"
-#include "sector.hpp"
-#include "mainloop.hpp"
-#include "object/player.hpp"
-
-EndSequenceWalkLeft::EndSequenceWalkLeft()
-: EndSequence()
-{
-}
-
-EndSequenceWalkLeft::~EndSequenceWalkLeft()
-{
-}
-
-void
-EndSequenceWalkLeft::draw(DrawingContext& /*context*/)
-{
-}
-
-void
-EndSequenceWalkLeft::starting()
-{
- EndSequence::starting();
- last_x_pos = -1;
- endsequence_timer.start(7.3f * main_loop->get_speed());
-}
-
-void
-EndSequenceWalkLeft::running(float elapsed_time)
-{
- EndSequence::running(elapsed_time);
- Player& tux = *Sector::current()->player;
-
- if (tux_may_walk) {
- end_sequence_controller->press(Controller::LEFT);
- if (int(last_x_pos) == int(tux.get_pos().x)) {
- end_sequence_controller->press(Controller::JUMP);
- }
- }
-
- last_x_pos = tux.get_pos().x;
-
- if (endsequence_timer.check()) isdone = true;
-}
-
-void
-EndSequenceWalkLeft::stopping()
-{
- EndSequence::stopping();
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux - End Sequence: Tux walks right
-// Copyright (C) 2007 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
-//
-// 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.
-
-#ifndef __ENDSEQUENCE_WALKLEFT_H__
-#define __ENDSEQUENCE_WALKLEFT_H__
-
-#include <memory>
-#include "object/endsequence.hpp"
-#include "timer.hpp"
-
-class EndSequenceWalkLeft : public EndSequence
-{
-public:
- EndSequenceWalkLeft();
- virtual ~EndSequenceWalkLeft();
- virtual void draw(DrawingContext& context);
-
-protected:
- virtual void starting(); /**< called when EndSequence starts */
- virtual void running(float elapsed_time); /**< called while the EndSequence is running */
- virtual void stopping(); /**< called when EndSequence stops */
-
- float last_x_pos;
- Timer endsequence_timer;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux - End Sequence: Tux walks right
-// Copyright (C) 2007 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
-//
-// 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.
-
-#include <config.h>
-#include "endsequence_walkright.hpp"
-#include "sector.hpp"
-#include "mainloop.hpp"
-#include "object/player.hpp"
-
-EndSequenceWalkRight::EndSequenceWalkRight()
-: EndSequence()
-{
-}
-
-EndSequenceWalkRight::~EndSequenceWalkRight()
-{
-}
-
-void
-EndSequenceWalkRight::draw(DrawingContext& /*context*/)
-{
-}
-
-void
-EndSequenceWalkRight::starting()
-{
- EndSequence::starting();
- last_x_pos = -1;
- endsequence_timer.start(7.3f * main_loop->get_speed());
-}
-
-void
-EndSequenceWalkRight::running(float elapsed_time)
-{
- EndSequence::running(elapsed_time);
- Player& tux = *Sector::current()->player;
-
- if (tux_may_walk) {
- end_sequence_controller->press(Controller::RIGHT);
- if (int(last_x_pos) == int(tux.get_pos().x)) {
- end_sequence_controller->press(Controller::JUMP);
- }
- }
-
- last_x_pos = tux.get_pos().x;
-
- if (endsequence_timer.check()) isdone = true;
-}
-
-void
-EndSequenceWalkRight::stopping()
-{
- EndSequence::stopping();
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux - End Sequence: Tux walks right
-// Copyright (C) 2007 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
-//
-// 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.
-
-#ifndef __ENDSEQUENCE_WALKRIGHT_H__
-#define __ENDSEQUENCE_WALKRIGHT_H__
-
-#include <memory>
-#include "object/endsequence.hpp"
-#include "timer.hpp"
-
-class EndSequenceWalkRight : public EndSequence
-{
-public:
- EndSequenceWalkRight();
- virtual ~EndSequenceWalkRight();
- virtual void draw(DrawingContext& context);
-
-protected:
- virtual void starting(); /**< called when EndSequence starts */
- virtual void running(float elapsed_time); /**< called while the EndSequence is running */
- virtual void stopping(); /**< called when EndSequence stops */
-
- float last_x_pos;
- Timer endsequence_timer;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux -- Explosion object
-// Copyright (C) 2007 Christoph Sommer <christoph.sommer@2007.expires.deltadevelopment.de>
-//
-// 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.
-
-#include <config.h>
-
-#include "explosion.hpp"
-#include "badguy/badguy.hpp"
-#include "object/sprite_particle.hpp"
-#include "random_generator.hpp"
-
-Explosion::Explosion(const Vector& pos)
- : MovingSprite(pos, "images/objects/explosion/explosion.sprite", LAYER_OBJECTS+40, COLGROUP_TOUCHABLE), state(STATE_WAITING)
-{
- sound_manager->preload("sounds/explosion.wav");
- set_pos(get_pos() - (get_bbox().get_middle() - get_pos()));
-}
-
-Explosion::Explosion(const lisp::Lisp& reader)
- : MovingSprite(reader, "images/objects/explosion/explosion.sprite", LAYER_OBJECTS+40, COLGROUP_TOUCHABLE), state(STATE_WAITING)
-{
- sound_manager->preload("sounds/explosion.wav");
-}
-
-void
-Explosion::explode()
-{
- if (state != STATE_WAITING) return;
- state = STATE_EXPLODING;
-
- set_action("default", 1);
- sprite->set_animation_loops(1); //TODO: this is necessary because set_action will not set "loops" when "action" is the default action
- sound_manager->play("sounds/explosion.wav", get_pos());
-
- // spawn some particles
- // TODO: provide convenience function in MovingSprite or MovingObject?
- for (int i = 0; i < 100; i++) {
- Vector ppos = bbox.get_middle();
- float angle = systemRandom.randf(-M_PI_2, M_PI_2);
- float velocity = systemRandom.randf(450, 900);
- float vx = sin(angle)*velocity;
- float vy = -cos(angle)*velocity;
- Vector pspeed = Vector(vx, vy);
- Vector paccel = Vector(0, 1000);
- Sector::current()->add_object(new SpriteParticle("images/objects/particles/explosion.sprite", "default", ppos, ANCHOR_MIDDLE, pspeed, paccel, LAYER_OBJECTS-1));
- }
-}
-
-void
-Explosion::update(float )
-{
- switch(state) {
- case STATE_WAITING:
- explode();
- break;
- case STATE_EXPLODING:
- if(sprite->animation_done()) {
- remove_me();
- }
- break;
- }
-}
-
-HitResponse
-Explosion::collision(GameObject& other, const CollisionHit& )
-{
- if(state != STATE_EXPLODING) return ABORT_MOVE;
-
- Player* player = dynamic_cast<Player*>(&other);
- if(player != 0) {
- player->kill(false);
- }
-
- BadGuy* badguy = dynamic_cast<BadGuy*>(&other);
- if(badguy != 0) {
- badguy->kill_fall();
- }
-
- return ABORT_MOVE;
-}
-
-IMPLEMENT_FACTORY(Explosion, "explosion");
-
+++ /dev/null
-// $Id$
-//
-// SuperTux -- Explosion object
-// Copyright (C) 2007 Christoph Sommer <christoph.sommer@2007.expires.deltadevelopment.de>
-//
-// 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.
-
-#ifndef __EXPLOSION_H__
-#define __EXPLOSION_H__
-
-#include "moving_sprite.hpp"
-#include "lisp/lisp.hpp"
-
-/**
- * Just your average explosion - goes boom, hurts Tux
- */
-class Explosion : public MovingSprite
-{
-public:
- /**
- * Create new Explosion centered(!) at @c pos
- */
- Explosion(const Vector& pos);
- Explosion(const lisp::Lisp& reader);
-
- void update(float elapsed_time);
- HitResponse collision(GameObject& other, const CollisionHit& hit);
-
-protected:
- /**
- * plays sound, starts animation
- */
- void explode();
-
-private:
- enum State {
- STATE_WAITING,
- STATE_EXPLODING
- };
- State state;
-
-};
-
-#endif
-
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Ondrej Hosek <ondra.hosek@gmail.com>
-//
-// 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.
-
-#include <config.h>
-
-#include "falling_coin.hpp"
-#include "player.hpp"
-#include "sprite/sprite_manager.hpp"
-#include "resources.hpp"
-#include "main.hpp"
-
-FallingCoin::FallingCoin(const Vector& start_position, const int vel_x)
-{
- pos = start_position;
- sprite = sprite_manager->create("images/objects/coin/coin.sprite");
- physic.set_velocity_y(-800);
- physic.set_velocity_x(vel_x);
-}
-
-FallingCoin::~FallingCoin()
-{
- delete sprite;
-}
-
-void
-FallingCoin::draw(DrawingContext& context)
-{
- sprite->draw(context, pos, LAYER_FLOATINGOBJECTS + 5);
-}
-
-void
-FallingCoin::update(float elapsed_time)
-{
- pos += physic.get_movement(elapsed_time);
- if (pos.y > SCREEN_HEIGHT)
- remove_me();
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Ondrej Hosek <ondra.hosek@gmail.com>
-//
-// 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.
-
-#ifndef __FALLING_COIN_H__
-#define __FALLING_COIN_H__
-
-#include "game_object.hpp"
-#include "math/vector.hpp"
-#include "sprite/sprite.hpp"
-#include "video/drawing_context.hpp"
-#include "physic.hpp"
-
-class FallingCoin : public GameObject, private UsesPhysic
-{
-public:
- FallingCoin(const Vector& start_position, const int x_vel);
- ~FallingCoin();
-
- void draw(DrawingContext& context);
- void update(float elapsed_time);
-private:
- Vector pos;
- Sprite* sprite;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include "firefly.hpp"
-#include "resources.hpp"
-#include "sprite/sprite_manager.hpp"
-#include "video/drawing_context.hpp"
-#include "player.hpp"
-#include "object_factory.hpp"
-#include "game_session.hpp"
-#include "sector.hpp"
-#include "random_generator.hpp"
-#include "object/sprite_particle.hpp"
-
-Firefly::Firefly(const lisp::Lisp& lisp)
- : MovingSprite(lisp, "images/objects/resetpoints/default-resetpoint.sprite", LAYER_TILES, COLGROUP_TOUCHABLE), activated(false)
-{
- initial_position = get_pos();
- if( !lisp.get( "sprite", sprite_name ) ){
- reactivate();
- return;
- }
- if( sprite_name == "" ){
- sprite_name = "images/objects/resetpoints/default-resetpoint.sprite";
- reactivate();
- return;
- }
- //Replace sprite
- sprite = sprite_manager->create( sprite_name );
- bbox.set_size(sprite->get_current_hitbox_width(), sprite->get_current_hitbox_height());
- reactivate();
-}
-
-void
-Firefly::reactivate()
-{
- if(GameSession::current()->get_reset_point_pos() == initial_position){
- // TODO: && GameSession::current()->get_reset_point_sectorname() == <sector this firefly is in>
- // GameSession::current()->get_current_sector()->get_name() is not yet initialized.
- // Worst case a resetpoint in a different sector at the same position as the real
- // resetpoint the player is spawning is set to ringing, too. Until we can check the sector, too, dont set
- // activated = true; here.
- sprite->set_action("ringing");
- }
-}
-
-void
-Firefly::write(lisp::Writer& writer)
-{
- writer.start_list("firefly");
- writer.write_float("x", bbox.p1.x);
- writer.write_float("y", bbox.p1.y);
- writer.end_list("firefly");
-}
-
-HitResponse
-Firefly::collision(GameObject& other, const CollisionHit& )
-{
- if(activated)
- return ABORT_MOVE;
-
- Player* player = dynamic_cast<Player*> (&other);
- if(player) {
- activated = true;
-// spawn some particles
-// TODO: provide convenience function in MovingSprite or MovingObject?
- for (int i = 0; i < 5; i++) {
- Vector ppos = bbox.get_middle();
- float angle = systemRandom.randf(-M_PI_2, M_PI_2);
- float velocity = systemRandom.randf(450, 900);
- float vx = sin(angle)*velocity;
- float vy = -cos(angle)*velocity;
- Vector pspeed = Vector(vx, vy);
- Vector paccel = Vector(0, 1000);
- Sector::current()->add_object(new SpriteParticle("images/objects/particles/reset.sprite", "default", ppos, ANCHOR_MIDDLE, pspeed, paccel, LAYER_OBJECTS-1));
- }
- // TODO play sound
- sprite->set_action("ringing");
- GameSession::current()->set_reset_point(Sector::current()->get_name(),
- initial_position);
- }
-
- return ABORT_MOVE;
-}
-
-IMPLEMENT_FACTORY(Firefly, "firefly");
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __FIREFLY_H__
-#define __FIREFLY_H__
-
-#include "lisp/lisp.hpp"
-#include "object/moving_sprite.hpp"
-#include "serializable.hpp"
-#include "badguy/badguy.hpp"
-
-/**
- * A Firefly: When tux touches it, it begins buzzing and you will respawn at this
- * position.
- */
-class Firefly : public MovingSprite, public Serializable
-{
-public:
- Firefly(const lisp::Lisp& lisp);
- virtual Firefly* clone() const { return new Firefly(*this); }
-
- void write(lisp::Writer& writer);
- HitResponse collision(GameObject& other, const CollisionHit& hit);
-
-private:
- bool activated;
- Vector initial_position; /**< position as in level file. This is where Tux will have to respawn, as the level is reset every time */
- void reactivate();
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include "fireworks.hpp"
-#include "resources.hpp"
-#include "sector.hpp"
-#include "camera.hpp"
-#include "particles.hpp"
-#include "main.hpp"
-#include "video/drawing_context.hpp"
-#include "audio/sound_manager.hpp"
-#include "random_generator.hpp"
-
-Fireworks::Fireworks()
-{
- timer.start(.2f);
- sound_manager->preload("sounds/fireworks.wav");
-}
-
-Fireworks::~Fireworks()
-{
-}
-
-void
-Fireworks::update(float )
-{
- if(timer.check()) {
- Sector* sector = Sector::current();
- Vector pos = sector->camera->get_translation();
- pos += Vector(systemRandom.randf(SCREEN_WIDTH),
- systemRandom.randf(SCREEN_HEIGHT/2));
-
- float red = systemRandom.randf(1.0);
- float green = systemRandom.randf(1.0);
- //float red = 0.7;
- //float green = 0.9;
- (void) red;
- (void) green;
- sector->add_object(new Particles(pos, 0, 360, Vector(140, 140),
- Vector(0, 0), 45, Color(red, green, 0), 3, 1.3f,
- LAYER_FOREGROUND1+1));
- sound_manager->play("sounds/fireworks.wav");
- timer.start(systemRandom.randf(1.0, 1.5));
- }
-}
-
-void
-Fireworks::draw(DrawingContext& )
-{
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __FIREWORKS_H__
-#define __FIREWORKS_H__
-
-#include "video/drawing_context.hpp"
-#include "game_object.hpp"
-#include "timer.hpp"
-
-class Fireworks : public GameObject
-{
-public:
- Fireworks();
- ~Fireworks();
-
- virtual void update(float elapsed_time);
- virtual void draw(DrawingContext& context);
-
-private:
- Timer timer;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include <stdexcept>
-#include "resources.hpp"
-#include "main.hpp"
-#include "math/rect.hpp"
-#include "sprite/sprite_manager.hpp"
-#include "sprite/sprite.hpp"
-#include "video/drawing_context.hpp"
-#include "lisp/lisp.hpp"
-#include "floating_image.hpp"
-
-
-FloatingImage::FloatingImage(const std::string& spritefile)
- : layer(LAYER_FOREGROUND1 + 1), visible(false), anchor(ANCHOR_MIDDLE), fading(0), fadetime(0)
-{
- sprite.reset(sprite_manager->create(spritefile));
-}
-
-FloatingImage::~FloatingImage()
-{
-}
-
-void
-FloatingImage::update(float elapsed_time)
-{
- if(fading > 0) {
- fading -= elapsed_time;
- if(fading <= 0) {
- fading = 0;
- visible = true;
- }
- } else if(fading < 0) {
- fading += elapsed_time;
- if(fading >= 0) {
- fading = 0;
- visible = false;
- }
- }
-
-// (void) elapsed_time;
-}
-
-void
-FloatingImage::set_action(const std::string& action)
-{
- sprite->set_action(action);
-}
-
-std::string
-FloatingImage::get_action()
-{
- return sprite->get_action();
-}
-
-void
-FloatingImage::fade_in(float fadetime)
-{
- this->fadetime = fadetime;
- fading = fadetime;
-}
-
-void
-FloatingImage::fade_out(float fadetime)
-{
- this->fadetime = fadetime;
- fading = -fadetime;
-}
-
-
-void
-FloatingImage::draw(DrawingContext& context)
-{
- context.push_transform();
- context.set_translation(Vector(0, 0));
-
- if(fading > 0) {
- context.set_alpha((fadetime-fading) / fadetime);
- } else if(fading < 0) {
- context.set_alpha(-fading / fadetime);
- } else if(!visible) {
- context.pop_transform();
- return;
- }
-
- Vector spos = pos + get_anchor_pos(Rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT),
- sprite->get_width(), sprite->get_height(), anchor);
-
- sprite->draw(context, spos, layer);
-
- context.pop_transform();
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __FLOATING_IMAGE_H__
-#define __FLOATING_IMAGE_H__
-
-#include "game_object.hpp"
-#include "math/vector.hpp"
-#include "anchor_point.hpp"
-#include <memory>
-
-class Sprite;
-
-class FloatingImage : public GameObject
-{
-public:
- FloatingImage(const std::string& sprite);
- virtual ~FloatingImage();
-
- void set_layer(int layer) {
- this->layer = layer;
- }
-
- int get_layer() const {
- return layer;
- }
-
- void set_pos(const Vector& pos) {
- this->pos = pos;
- }
- const Vector& get_pos() const {
- return pos;
- }
-
- void set_anchor_point(AnchorPoint anchor) {
- this->anchor = anchor;
- }
- AnchorPoint get_anchor_point() const {
- return anchor;
- }
-
- void set_visible(bool visible) {
- this->visible = visible;
- }
- bool get_visible() const {
- return visible;
- }
-
- void set_action(const std::string& action);
- std::string get_action();
-
- void fade_in(float fadetime);
- void fade_out(float fadetime);
-
- void update(float elapsed_time);
- void draw(DrawingContext& context);
-
-private:
- std::auto_ptr<Sprite> sprite;
- int layer;
- bool visible;
- AnchorPoint anchor;
- Vector pos;
- float fading;
- float fadetime;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include <math.h>
-#include <assert.h>
-#include "flower.hpp"
-#include "resources.hpp"
-#include "camera.hpp"
-#include "sector.hpp"
-#include "player.hpp"
-#include "audio/sound_manager.hpp"
-#include "sprite/sprite_manager.hpp"
-
-Flower::Flower(BonusType _type)
- : type(_type)
-{
- bbox.set_size(32, 32);
-
- if(type == FIRE_BONUS) {
- sprite = sprite_manager->create("images/powerups/fireflower/fireflower.sprite");
- sound_manager->preload("sounds/fire-flower.wav");
- }
- else if(type == ICE_BONUS) {
- sprite = sprite_manager->create("images/powerups/iceflower/iceflower.sprite");
- } else {
- assert(false);
- }
-
- set_group(COLGROUP_TOUCHABLE);
-}
-
-Flower::~Flower()
-{
- delete sprite;
-}
-
-void
-Flower::update(float )
-{
-}
-
-void
-Flower::draw(DrawingContext& context)
-{
- sprite->draw(context, get_pos(), LAYER_OBJECTS);
-}
-
-HitResponse
-Flower::collision(GameObject& other, const CollisionHit& )
-{
- Player* player = dynamic_cast<Player*>(&other);
- if(!player)
- return ABORT_MOVE;
-
- if(!player->add_bonus(type, true))
- return FORCE_MOVE;
-
- sound_manager->play("sounds/fire-flower.wav");
- remove_me();
- return ABORT_MOVE;
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __FLOWER_H__
-#define __FLOWER_H__
-
-#include "moving_object.hpp"
-#include "sprite/sprite.hpp"
-#include "player_status.hpp"
-
-class Flower : public MovingObject
-{
-public:
- Flower(BonusType type);
- ~Flower();
-
- virtual void update(float elapsed_time);
- virtual void draw(DrawingContext& context);
- virtual HitResponse collision(GameObject& other, const CollisionHit& hit);
-
-private:
- BonusType type;
- Sprite* sprite;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include <algorithm>
-#include <iostream>
-#include <cmath>
-
-#include "tile.hpp"
-#include "tile_manager.hpp"
-#include "game_session.hpp"
-#include "gameobjs.hpp"
-#include "sprite/sprite_manager.hpp"
-#include "sprite/sprite.hpp"
-#include "resources.hpp"
-#include "sector.hpp"
-#include "tilemap.hpp"
-#include "video/drawing_context.hpp"
-#include "camera.hpp"
-#include "main.hpp"
-#include "random_generator.hpp"
-
-BouncyCoin::BouncyCoin(const Vector& pos)
- : position(pos)
-{
- timer.start(.3f);
- sprite = sprite_manager->create("images/objects/coin/coin.sprite");
- sprite->set_action("still");
-}
-
-BouncyCoin::~BouncyCoin()
-{
- delete sprite;
-}
-
-void
-BouncyCoin::update(float elapsed_time)
-{
- position.y += -200 * elapsed_time;
-
- if(timer.check())
- remove_me();
-}
-
-void
-BouncyCoin::draw(DrawingContext& context)
-{
- sprite->draw(context, position, LAYER_OBJECTS + 5);
-}
-
-//---------------------------------------------------------------------------
-
-BrokenBrick::BrokenBrick(Sprite* nsprite,
- const Vector& pos, const Vector& nmovement)
- : sprite(new Sprite(*nsprite)), position(pos), movement(nmovement)
-{
- timer.start(.2f);
-}
-
-BrokenBrick::~BrokenBrick()
-{
- delete sprite;
-}
-
-void
-BrokenBrick::update(float elapsed_time)
-{
- position += movement * elapsed_time;
-
- if (timer.check())
- remove_me();
-}
-
-void
-BrokenBrick::draw(DrawingContext& context)
-{
- sprite->draw_part(context,
- Vector(systemRandom.rand(16), systemRandom.rand(16)), Vector(16, 16),
- position, LAYER_OBJECTS + 1);
-}
-
-//---------------------------------------------------------------------------
-
-FloatingText::FloatingText(const Vector& pos, const std::string& text_)
- : position(pos), text(text_)
-{
- timer.start(.1f);
- position.x -= text.size() * 8;
-}
-
-FloatingText::FloatingText(const Vector& pos, int score)
- : position(pos)
-{
- timer.start(.1f);
-
- // turn int into a string
- char str[10];
- snprintf(str, 10, "%d", score);
- text = str;
-
- position.x -= text.size() * 8;
-}
-
-void
-FloatingText::update(float elapsed_time)
-{
- position.y -= 1.4 * elapsed_time;
-
- if(timer.check())
- remove_me();
-}
-
-#define FADING_TIME .350
-
-void
-FloatingText::draw(DrawingContext& context)
-{
- // make an alpha animation when disapearing
- int alpha;
- if(timer.get_timeleft() < FADING_TIME)
- alpha = int(timer.get_timeleft() * 255 / FADING_TIME);
- else
- alpha = 255;
-
- context.push_transform();
- context.set_alpha(alpha);
-
- context.draw_text(gold_text, text, position, ALIGN_LEFT, LAYER_OBJECTS+1);
-
- context.pop_transform();
-}
-
-Sprite *img_smoke_cloud = 0;
-
-SmokeCloud::SmokeCloud(const Vector& pos)
- : position(pos)
-{
- timer.start(.3f);
- sprite = sprite_manager->create("images/objects/particles/stomp.sprite");
-}
-
-SmokeCloud::~SmokeCloud()
-{
- delete sprite;
-}
-
-void
-SmokeCloud::update(float elapsed_time)
-{
- position.y -= 120 * elapsed_time;
-
- if(timer.check())
- remove_me();
-}
-
-void
-SmokeCloud::draw(DrawingContext& context)
-{
- sprite->draw(context, position, LAYER_OBJECTS+1);
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef SUPERTUX_GAMEOBJS_H
-#define SUPERTUX_GAMEOBJS_H
-
-#include "video/surface.hpp"
-#include "timer.hpp"
-#include "game_object.hpp"
-#include "moving_object.hpp"
-#include "serializable.hpp"
-#include "video/color.hpp"
-
-/* Bounciness of distros: */
-#define NO_BOUNCE 0
-#define BOUNCE 1
-
-class Sprite;
-
-class BouncyCoin : public GameObject
-{
-public:
- BouncyCoin(const Vector& pos);
- ~BouncyCoin();
- virtual void update(float elapsed_time);
- virtual void draw(DrawingContext& context);
-
-private:
- Sprite* sprite;
- Vector position;
- Timer timer;
-};
-
-class BrokenBrick : public GameObject
-{
-public:
- BrokenBrick(Sprite* sprite, const Vector& pos, const Vector& movement);
- ~BrokenBrick();
-
- virtual void update(float elapsed_time);
- virtual void draw(DrawingContext& context);
-
-private:
- Timer timer;
- Sprite* sprite;
- Vector position;
- Vector movement;
-};
-
-class FloatingText : public GameObject
-{
-public:
- FloatingText(const Vector& pos, const std::string& text_);
- FloatingText(const Vector& pos, int s); // use this for score, for instance
-
- virtual void update(float elapsed_time);
- virtual void draw(DrawingContext& context);
-
-private:
- Vector position;
- std::string text;
- Timer timer;
-};
-
-class SmokeCloud : public GameObject
-{
-public:
- SmokeCloud(const Vector& pos);
- ~SmokeCloud();
-
- virtual void update(float elapsed_time);
- virtual void draw(DrawingContext& context);
-
-private:
- Sprite* sprite;
- Timer timer;
- Vector position;
-};
-
-#endif
-
-/* Local Variables: */
-/* mode:c++ */
-/* End: */
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include <stdexcept>
-#include "gradient.hpp"
-#include "camera.hpp"
-#include "video/drawing_context.hpp"
-#include "lisp/lisp.hpp"
-#include "lisp/writer.hpp"
-#include "object_factory.hpp"
-#include "resources.hpp"
-#include "main.hpp"
-#include "log.hpp"
-
-Gradient::Gradient()
- : layer(LAYER_BACKGROUND0)
-{
-}
-
-Gradient::Gradient(const lisp::Lisp& reader)
- : layer(LAYER_BACKGROUND0)
-{
- reader.get("layer", layer);
- std::vector<float> bkgd_top_color, bkgd_bottom_color;
- if(!reader.get_vector("top_color", bkgd_top_color) ||
- !reader.get_vector("bottom_color", bkgd_bottom_color))
- throw std::runtime_error("Must specify top_color and bottom_color in gradient");
-
- gradient_top = Color(bkgd_top_color);
- gradient_bottom = Color(bkgd_bottom_color);
-}
-
-Gradient::~Gradient()
-{
-}
-
-void
-Gradient::write(lisp::Writer& writer)
-{
- writer.start_list("gradient");
-
- std::vector<float> bkgd_top_color, bkgd_bottom_color;
- bkgd_top_color.push_back(gradient_top.red);
- bkgd_top_color.push_back(gradient_top.green);
- bkgd_top_color.push_back(gradient_top.blue);
- bkgd_bottom_color.push_back(gradient_bottom.red);
- bkgd_bottom_color.push_back(gradient_bottom.green);
- bkgd_bottom_color.push_back(gradient_bottom.blue);
- writer.write_float_vector("top_color", bkgd_top_color);
- writer.write_float_vector("bottom_color", bkgd_bottom_color);
-
- writer.write_int("layer", layer);
-
- writer.end_list("gradient");
-}
-
-void
-Gradient::update(float)
-{
-}
-
-void
-Gradient::set_gradient(Color top, Color bottom)
-{
- gradient_top = top;
- gradient_bottom = bottom;
-
- if (gradient_top.red > 1.0 || gradient_top.green > 1.0
- || gradient_top.blue > 1.0 || gradient_top.alpha > 1.0)
- log_warning << "top gradient color has values above 1.0" << std::endl;
- if (gradient_bottom.red > 1.0 || gradient_bottom.green > 1.0
- || gradient_bottom.blue > 1.0 || gradient_bottom.alpha > 1.0)
- log_warning << "bottom gradient color has values above 1.0" << std::endl;
-}
-
-void
-Gradient::draw(DrawingContext& context)
-{
- context.push_transform();
- context.set_translation(Vector(0, 0));
- context.draw_gradient(gradient_top, gradient_bottom, layer);
- context.pop_transform();
-}
-
-IMPLEMENT_FACTORY(Gradient, "gradient");
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef SUPERTUX_GRADIENT_H
-#define SUPERTUX_GRADIENT_H
-
-#include <memory>
-#include "video/surface.hpp"
-#include "video/drawing_context.hpp"
-#include "game_object.hpp"
-#include "serializable.hpp"
-
-class DisplayManager;
-
-namespace lisp {
-class Lisp;
-}
-
-class Gradient : public GameObject, public Serializable
-{
-public:
- Gradient();
- Gradient(const lisp::Lisp& reader);
- virtual ~Gradient();
-
- virtual void write(lisp::Writer& writer);
-
- void set_gradient(Color top, Color bottom);
-
- Color get_gradient_top() const
- { return gradient_top; }
-
- Color get_gradient_bottom() const
- { return gradient_bottom; }
-
- virtual void update(float elapsed_time);
-
- virtual void draw(DrawingContext& context);
-
-private:
- int layer;
- Color gradient_top, gradient_bottom;
-};
-
-#endif /*SUPERTUX_BACKGROUND_H*/
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include <math.h>
-#include "growup.hpp"
-#include "resources.hpp"
-#include "camera.hpp"
-#include "sector.hpp"
-#include "player.hpp"
-#include "audio/sound_manager.hpp"
-
-GrowUp::GrowUp(Direction direction)
- : MovingSprite(Vector(0,0), "images/powerups/egg/egg.sprite", LAYER_OBJECTS, COLGROUP_MOVING)
-{
- physic.enable_gravity(true);
- physic.set_velocity_x((direction == LEFT)?-100:100);
- sound_manager->preload("sounds/grow.wav");
-}
-
-void
-GrowUp::update(float elapsed_time)
-{
- movement = physic.get_movement(elapsed_time);
-}
-
-void
-GrowUp::collision_solid(const CollisionHit& hit)
-{
- if(hit.top || hit.bottom)
- physic.set_velocity_y(0);
- if(hit.left || hit.right)
- physic.set_velocity_x(-physic.get_velocity_x());
-}
-
-HitResponse
-GrowUp::collision(GameObject& other, const CollisionHit& )
-{
- Player* player = dynamic_cast<Player*>(&other);
- if(player != 0) {
- if(!player->add_bonus(GROWUP_BONUS, true))
- return FORCE_MOVE;
-
- sound_manager->play("sounds/grow.wav");
- remove_me();
-
- return ABORT_MOVE;
- }
-
- return FORCE_MOVE;
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __GROWUP_H__
-#define __GROWUP_H__
-
-#include "object/moving_sprite.hpp"
-#include "physic.hpp"
-#include "direction.hpp"
-
-class GrowUp : public MovingSprite, private UsesPhysic
-{
-public:
- GrowUp(Direction direction = RIGHT);
- virtual GrowUp* clone() const { return new GrowUp(*this); }
-
- virtual void update(float elapsed_time);
- virtual void collision_solid(const CollisionHit& hit);
- virtual HitResponse collision(GameObject& other, const CollisionHit& hit);
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux - Hurting Platform
-// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
-//
-// 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.
-
-#include <config.h>
-#include <stdexcept>
-
-#include "hurting_platform.hpp"
-
-#include "log.hpp"
-#include "player.hpp"
-#include "badguy/badguy.hpp"
-#include "object_factory.hpp"
-
-HurtingPlatform::HurtingPlatform(const lisp::Lisp& reader)
- : Platform(reader)
-{
- set_group(COLGROUP_TOUCHABLE);
-}
-
-HitResponse
-HurtingPlatform::collision(GameObject& other, const CollisionHit& )
-{
- Player* player = dynamic_cast<Player*>(&other);
- if (player) {
- player->kill(false);
- }
- BadGuy* badguy = dynamic_cast<BadGuy*>(&other);
- if (badguy) {
- badguy->kill_fall();
- }
-
- return FORCE_MOVE;
-}
-
-IMPLEMENT_FACTORY(HurtingPlatform, "hurting_platform");
+++ /dev/null
-// $Id$
-//
-// SuperTux - Hurting Platform
-// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
-//
-// 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.
-
-#ifndef __HURTING_PLATFORM_H__
-#define __HURTING_PLATFORM_H__
-
-#include <memory>
-#include "object/platform.hpp"
-
-/**
- * Platform that hurts Tux and Badguys when touched
- */
-class HurtingPlatform : public Platform
-{
-public:
- HurtingPlatform(const lisp::Lisp& reader);
- virtual HurtingPlatform* clone() const { return new HurtingPlatform(*this); }
-
- virtual HitResponse collision(GameObject& other, const CollisionHit& hit);
-
-private:
-
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include "infoblock.hpp"
-#include "game_session.hpp"
-#include "resources.hpp"
-#include "sprite/sprite_manager.hpp"
-#include "object_factory.hpp"
-#include "lisp/lisp.hpp"
-#include "sector.hpp"
-#include "log.hpp"
-#include "object/player.hpp"
-#include "main.hpp"
-
-namespace {
- const float SCROLL_DELAY = 0.5;
- const float SCROLL_DISTANCE = 16;
- const float WIDTH = 400;
- const float HEIGHT = 200;
-}
-
-InfoBlock::InfoBlock(const lisp::Lisp& lisp)
- : Block(sprite_manager->create("images/objects/bonus_block/infoblock.sprite")), shown_pct(0), dest_pct(0)
-{
- Vector pos;
- lisp.get("x", pos.x);
- lisp.get("y", pos.y);
- bbox.set_pos(pos);
-
- if(!lisp.get("message", message)) {
- log_warning << "No message in InfoBlock" << std::endl;
- }
- //stopped = false;
- //ringing = new AmbientSound(get_pos(), 0.5, 300, 1, "sounds/phone.wav");
- //Sector::current()->add_object(ringing);
-
- // Split text string lines into a vector
- lines = InfoBoxLine::split(message, 400);
- lines_height = 0;
- for(size_t i = 0; i < lines.size(); ++i) lines_height+=lines[i]->get_height();
-}
-
-InfoBlock::~InfoBlock()
-{
- for(std::vector<InfoBoxLine*>::iterator i = lines.begin(); i != lines.end(); i++) {
- delete *i;
- }
-}
-
-void
-InfoBlock::hit(Player& )
-{
- start_bounce();
-
- //if (!stopped) {
- // ringing->remove_me();
- // stopped = true;
- //}
-
- if (dest_pct != 1) {
-
- // first hide all other InfoBlocks' messages in same sector
- Sector* parent = Sector::current();
- if (!parent) return;
- for (Sector::GameObjects::iterator i = parent->gameobjects.begin(); i != parent->gameobjects.end(); i++) {
- InfoBlock* block = dynamic_cast<InfoBlock*>(*i);
- if (!block) continue;
- if (block != this) block->hide_message();
- }
-
- // show our message
- show_message();
-
- } else {
- hide_message();
- }
-}
-
-Player*
-InfoBlock::get_nearest_player()
-{
- // FIXME: does not really return nearest player
-
- std::vector<Player*> players = Sector::current()->get_players();
- for (std::vector<Player*>::iterator playerIter = players.begin(); playerIter != players.end(); ++playerIter) {
- Player* player = *playerIter;
- return player;
- }
-
- return 0;
-}
-
-void
-InfoBlock::update(float delta)
-{
- Block::update(delta);
-
- if (delta == 0) return;
-
- // hide message if player is too far away or above infoblock
- if (dest_pct > 0) {
- Player* player = get_nearest_player();
- if (player) {
- Vector p1 = this->get_pos() + (this->get_bbox().p2 - this->get_bbox().p1) / 2;
- Vector p2 = player->get_pos() + (player->get_bbox().p2 - player->get_bbox().p1) / 2;
- Vector dist = (p2 - p1);
- float d = dist.norm();
- if (d > 128 || dist.y < 0) dest_pct = 0;
- }
- }
-
- // handle soft fade-in and fade-out
- if (shown_pct != dest_pct) {
- if (dest_pct > shown_pct) shown_pct = std::min(shown_pct + 2*delta, dest_pct);
- if (dest_pct < shown_pct) shown_pct = std::max(shown_pct - 2*delta, dest_pct);
- }
-}
-
-void
-InfoBlock::draw(DrawingContext& context)
-{
- Block::draw(context);
-
- if (shown_pct <= 0) return;
-
- context.push_transform();
- //context.set_translation(Vector(0, 0));
- context.set_alpha(shown_pct);
-
- //float x1 = SCREEN_WIDTH/2-200;
- //float y1 = SCREEN_HEIGHT/2-200;
- float border = 8;
- float width = 400; // this is the text width only
- float height = lines_height; // this is the text height only
- float x1 = (get_bbox().p1.x + get_bbox().p2.x)/2 - width/2;
- float x2 = (get_bbox().p1.x + get_bbox().p2.x)/2 + width/2;
- float y1 = original_y - height;
-
- // lines_height includes one ITEMS_SPACE too much, so the bottom border is reduced by 4px
- context.draw_filled_rect(Vector(x1-border, y1-border), Vector(width+2*border, height+2*border-4), Color(0.6f, 0.7f, 0.8f, 0.5f), LAYER_GUI-50);
-
- float y = y1;
- for(size_t i = 0; i < lines.size(); ++i) {
- if(y >= y1 + height) {
- //log_warning << "Too many lines of text in InfoBlock" << std::endl;
- //dest_pct = 0;
- //shown_pct = 0;
- break;
- }
-
- lines[i]->draw(context, Rect(x1, y, x2, y), LAYER_GUI-50+1);
- y += lines[i]->get_height();
- }
-
- context.pop_transform();
-}
-
-void
-InfoBlock::show_message()
-{
- dest_pct = 1;
-}
-
-void
-InfoBlock::hide_message()
-{
- dest_pct = 0;
-}
-
-IMPLEMENT_FACTORY(InfoBlock, "infoblock")
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __INFOBLOCK_H__
-#define __INFOBLOCK_H__
-
-#include "block.hpp"
-//#include "object/ambient_sound.hpp"
-#include "textscroller.hpp"
-
-class InfoBlock : public Block
-{
-public:
- InfoBlock(const lisp::Lisp& lisp);
- virtual ~InfoBlock();
- void update(float elapsed_time);
- void draw(DrawingContext& context);
-
- void show_message();
- void hide_message();
-
-protected:
- virtual void hit(Player& player);
- std::string message;
- //AmbientSound* ringing;
- //bool stopped;
- float shown_pct; /**< Value in the range of 0..1, depending on how much of the infobox is currently shown */
- float dest_pct; /**< With each call to update(), shown_pct will slowly transition to this value */
-
- Player* get_nearest_player();
-
- std::vector<InfoBoxLine*> lines; /**< lines of text (or images) to display */
- float lines_height;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include "invisible_block.hpp"
-#include "resources.hpp"
-#include "sprite/sprite.hpp"
-#include "sprite/sprite_manager.hpp"
-#include "video/drawing_context.hpp"
-#include "audio/sound_manager.hpp"
-#include "object_factory.hpp"
-#include "object/player.hpp"
-
-InvisibleBlock::InvisibleBlock(const Vector& pos)
- : Block(sprite_manager->create("images/objects/bonus_block/invisibleblock.sprite")), visible(false)
-{
- bbox.set_pos(pos);
- sound_manager->preload("sounds/brick.wav");
- sound_manager->preload("sounds/brick.wav");
-}
-
-void
-InvisibleBlock::draw(DrawingContext& context)
-{
- if(visible)
- sprite->draw(context, get_pos(), LAYER_OBJECTS);
-}
-
-bool
-InvisibleBlock::collides(GameObject& other, const CollisionHit& )
-{
- if(visible)
- return true;
-
- // if we're not visible, only register a collision if this will make us visible
- Player* player = dynamic_cast<Player*> (&other);
- if ((player)
- && (player->get_movement().y <= 0)
- && (player->get_bbox().get_top() > get_bbox().get_bottom() - 7.0)) {
- return true;
- }
-
- return false;
-}
-
-HitResponse
-InvisibleBlock::collision(GameObject& other, const CollisionHit& hit)
-{
- return Block::collision(other, hit);
-}
-
-void
-InvisibleBlock::hit(Player& )
-{
- sound_manager->play("sounds/brick.wav");
-
- if(visible)
- return;
-
- sprite->set_action("empty");
- start_bounce();
- set_group(COLGROUP_STATIC);
- visible = true;
-}
-
-//IMPLEMENT_FACTORY(InvisibleBlock, "invisible_block");
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __INVISIBLE_BLOCK_H__
-#define __INVISIBLE_BLOCK_H__
-
-#include "block.hpp"
-
-class InvisibleBlock : public Block
-{
-public:
- InvisibleBlock(const Vector& pos);
-
- virtual void draw(DrawingContext& context);
- virtual bool collides(GameObject& other, const CollisionHit& hit);
- virtual HitResponse collision(GameObject& other, const CollisionHit& hit);
-
-protected:
- virtual void hit(Player& player);
-
-private:
- bool visible;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include "invisible_wall.hpp"
-#include "lisp/lisp.hpp"
-#include "object_factory.hpp"
-#include "sprite/sprite.hpp"
-
-InvisibleWall::InvisibleWall(const lisp::Lisp& lisp)
- : MovingSprite(lisp, "images/objects/invisible/invisible.sprite", LAYER_TILES, COLGROUP_STATIC), width(32), height(32)
-{
- lisp.get("width", width);
- lisp.get("height", height);
- bbox.set_size(width, height);
-}
-
-HitResponse
-InvisibleWall::collision(GameObject& , const CollisionHit& )
-{
- return FORCE_MOVE;
-}
-
-IMPLEMENT_FACTORY(InvisibleWall, "invisible_wall");
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __INVISIBLE_WALL_H__
-#define __INVISIBLE_WALL_H__
-
-#include "object/moving_sprite.hpp"
-#include "lisp/lisp.hpp"
-#include "physic.hpp"
-#include "timer.hpp"
-
-class Player;
-
-/** A tile that starts falling down if tux stands to long on it */
-class InvisibleWall : public MovingSprite, private UsesPhysic
-{
-public:
- InvisibleWall(const lisp::Lisp& lisp);
- virtual InvisibleWall* clone() const { return new InvisibleWall(*this); }
-
- HitResponse collision(GameObject& other, const CollisionHit& hit);
-
-private:
- float width, height;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux - Ispy
-// Copyright (C) 2007 Christoph Sommer <christoph.sommer@2007.expires.deltadevelopment.de>
-//
-// 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.
-
-#include <config.h>
-
-#include "ispy.hpp"
-#include "resources.hpp"
-#include "sprite/sprite_manager.hpp"
-#include "video/drawing_context.hpp"
-#include "player.hpp"
-#include "object_factory.hpp"
-#include "game_session.hpp"
-#include "sector.hpp"
-#include "tile.hpp"
-#include "object/tilemap.hpp"
-#include "random_generator.hpp"
-#include "object/sprite_particle.hpp"
-
-Ispy::Ispy(const lisp::Lisp& reader)
- : MovingSprite(reader, "images/objects/ispy/ispy.sprite", LAYER_TILES+5, COLGROUP_DISABLED), state(ISPYSTATE_IDLE), dir(AUTO)
-{
- // read script to execute
- reader.get("script", script);
-
- // read direction to face in
- std::string dir_str;
- bool facing_down = false;
- reader.get("direction", dir_str);
- if( dir_str == "left" ) dir = LEFT;
- if( dir_str == "right" ) dir = RIGHT;
- reader.get("facing-down", facing_down);
- if (facing_down) dir = DOWN;
- if (dir == AUTO) log_warning << "Setting an Ispy's direction to AUTO is no good idea" << std::endl;
-
- // set initial sprite action
- sprite->set_action((dir == DOWN) ? "idle-down" : ((dir == LEFT) ? "idle-left" : "idle-right"));
-}
-
-void
-Ispy::write(lisp::Writer& writer)
-{
- writer.start_list("ispy");
- writer.write_float("x", bbox.p1.x);
- writer.write_float("y", bbox.p1.y);
- writer.write_string("script", script);
- switch (dir)
- {
- case DOWN:
- writer.write_string("direction", "down"); break;
- case LEFT:
- writer.write_string("direction", "left"); break;
- case RIGHT:
- writer.write_string("direction", "right"); break;
- default: break;
- }
- writer.end_list("ispy");
-}
-
-HitResponse
-Ispy::collision(GameObject& , const CollisionHit& )
-{
- return ABORT_MOVE;
-}
-
-bool
-Ispy::line_intersects_line(Vector line1_start, Vector line1_end, Vector line2_start, Vector line2_end) {
- // Adapted from Striker, (C) 1999 Joris van der Hoeven, GPL
-
- float a1 = line1_start.x, b1 = line1_start.y, a2 = line1_end.x, b2 = line1_end.y;
- float c1 = line2_start.x, d1 = line2_start.y, c2 = line2_end.x, d2 = line2_end.y;
-
- float num = (b2-b1)*(c2-c1) - (a2-a1)*(d2-d1);
- float den1 = (d2-b2)*(c1-c2) + (a2-c2)*(d1-d2);
- float den2 = (d2-b2)*(a1-a2) + (a2-c2)*(b1-b2);
-
- // normalize to positive numerator
- if (num < 0) {
- num =- num;
- den1 =- den1;
- den2 =- den2;
- }
-
- // numerator is zero -> Check for parallel or coinciding lines
- if (num == 0) {
- if ((b1-b2)*(c1-a2) != (a1-a2)*(d1-b2)) return false;
- if (a1 == a2) {
- std::swap(a1, b1);
- std::swap(a2, b2);
- std::swap(c1, d1);
- std::swap(c2, d2);
- }
- if (a1 > a2) std::swap(a1, a2);
- if (c1 > c2) std::swap(c1, c2);
- return ((a1 <= c2) && (a2 >= c1));
- }
-
- // Standard check
- return (den1>=0) && (den1<=num) && (den2>=0) && (den2<=num);
-
-}
-
-bool
-Ispy::intersects_line(Rect r, Vector line_start, Vector line_end)
-{
- Vector p1 = r.p1;
- Vector p2 = Vector(r.p2.x, r.p1.y);
- Vector p3 = r.p2;
- Vector p4 = Vector(r.p1.x, r.p2.y);
- if (line_intersects_line(p1, p2, line_start, line_end)) return true;
- if (line_intersects_line(p2, p3, line_start, line_end)) return true;
- if (line_intersects_line(p3, p4, line_start, line_end)) return true;
- if (line_intersects_line(p4, p1, line_start, line_end)) return true;
- return false;
-}
-
-bool
-Ispy::free_line_of_sight(Vector line_start, Vector line_end, const MovingObject* ignore_object)
-{
-
- // check if no tile is in the way
- float lsx = std::min(line_start.x, line_end.x);
- float lex = std::max(line_start.x, line_end.x);
- float lsy = std::min(line_start.y, line_end.y);
- float ley = std::max(line_start.y, line_end.y);
- std::list<TileMap*> solid_tilemaps = Sector::current()->solid_tilemaps;
- for (float test_x = lsx; test_x <= lex; test_x += 16) {
- for (float test_y = lsy; test_y <= ley; test_y += 16) {
- for(std::list<TileMap*>::const_iterator i = solid_tilemaps.begin(); i != solid_tilemaps.end(); i++) {
- TileMap* solids = *i;
- const Tile* tile = solids->get_tile_at(Vector(test_x, test_y));
- if(!tile) continue;
- // FIXME: check collision with slope tiles
- if((tile->getAttributes() & Tile::SOLID)) return false;
- }
- }
- }
-
- // check if no object is in the way
- using namespace collision;
- Sector::MovingObjects& moving_objects = Sector::current()->moving_objects;
- for(Sector::MovingObjects::const_iterator i = moving_objects.begin();
- i != moving_objects.end(); ++i) {
- const MovingObject* moving_object = *i;
- if (moving_object == ignore_object) continue;
- if (!moving_object->is_valid()) continue;
- if ((moving_object->get_group() == COLGROUP_MOVING)
- || (moving_object->get_group() == COLGROUP_MOVING_STATIC)
- || (moving_object->get_group() == COLGROUP_STATIC)) {
- if(intersects_line(moving_object->get_bbox(), line_start, line_end)) return false;
- }
- }
-
- return true;
-}
-
-void
-Ispy::update(float )
-{
-
- if (state == ISPYSTATE_IDLE) {
- // check if a player has been spotted
- bool playerSpotted = false;
- std::vector<Player*> players = Sector::current()->get_players();
- for (std::vector<Player*>::iterator playerIter = players.begin(); playerIter != players.end(); ++playerIter) {
- Player* player = *playerIter;
-
- Vector eye = get_bbox().get_middle();
- if (dir == LEFT) eye = Vector(get_bbox().p1.x, get_bbox().get_middle().y);
- if (dir == RIGHT) eye = Vector(get_bbox().p2.x, get_bbox().get_middle().y);
- if (dir == UP) eye = Vector(get_bbox().get_middle().x, get_bbox().p1.y);
- if (dir == DOWN) eye = Vector(get_bbox().get_middle().x, get_bbox().p2.y);
-
- // test for free line of sight to any of all four corners and the middle of a player's bounding box
- if (free_line_of_sight(eye, player->get_bbox().p1, player)) playerSpotted = true;
- if (free_line_of_sight(eye, Vector(player->get_bbox().p2.x, player->get_bbox().p1.y), player)) playerSpotted = true;
- if (free_line_of_sight(eye, player->get_bbox().p2, player)) playerSpotted = true;
- if (free_line_of_sight(eye, Vector(player->get_bbox().p1.x, player->get_bbox().p2.y), player)) playerSpotted = true;
- if (free_line_of_sight(eye, player->get_bbox().get_middle(), player)) playerSpotted = true;
- }
-
- if (playerSpotted) {
- sprite->set_action((dir == DOWN) ? "alert-down" : ((dir == LEFT) ? "alert-left" : "alert-right"), 1);
- state = ISPYSTATE_ALERT;
-
- std::istringstream stream(script);
- Sector::current()->run_script(stream, "Ispy");
- }
- }
- if (state == ISPYSTATE_ALERT) {
- if (sprite->animation_done()) {
- sprite->set_action((dir == DOWN) ? "hiding-down" : ((dir == LEFT) ? "hiding-left" : "hiding-right"), 1);
- state = ISPYSTATE_HIDING;
- }
- }
- if (state == ISPYSTATE_HIDING) {
- if (sprite->animation_done()) {
- sprite->set_action((dir == DOWN) ? "showing-down" : ((dir == LEFT) ? "showing-left" : "showing-right"), 1);
- state = ISPYSTATE_SHOWING;
- }
- }
- if (state == ISPYSTATE_SHOWING) {
- if (sprite->animation_done()) {
- sprite->set_action((dir == DOWN) ? "idle-down" : ((dir == LEFT) ? "idle-left" : "idle-right"));
- state = ISPYSTATE_IDLE;
- }
- }
-}
-
-IMPLEMENT_FACTORY(Ispy, "ispy");
-
-
+++ /dev/null
-// $Id$
-//
-// SuperTux - Ispy
-// Copyright (C) 2007 Christoph Sommer <christoph.sommer@2007.expires.deltadevelopment.de>
-//
-// 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.
-
-#ifndef __OBJECT_ISPY_H__
-#define __OBJECT_ISPY_H__
-
-#include "lisp/lisp.hpp"
-#include "object/moving_sprite.hpp"
-#include "serializable.hpp"
-#include "badguy/badguy.hpp"
-#include "direction.hpp"
-
-/**
- * An Ispy: When it spots Tux, a script will run.
- */
-class Ispy : public MovingSprite, public Serializable
-{
-public:
- Ispy(const lisp::Lisp& lisp);
-
- void write(lisp::Writer& writer);
- HitResponse collision(GameObject& other, const CollisionHit& hit);
-
- virtual void update(float elapsed_time);
-
-private:
- bool line_intersects_line(Vector line1_start, Vector line1_end, Vector line2_start, Vector line2_end);
- bool intersects_line(Rect r, Vector line_start, Vector line_end);
- bool free_line_of_sight(Vector p1, Vector p2, const MovingObject* ignore_object);
-
- enum IspyState {
- ISPYSTATE_IDLE,
- ISPYSTATE_ALERT,
- ISPYSTATE_HIDING,
- ISPYSTATE_SHOWING
- };
- IspyState state; /**< current state */
-
- std::string script; /**< script to execute when Tux is spotted */
- Direction dir;
-
-};
-
-#endif
-
+++ /dev/null
-// $Id$
-//
-// SuperTux - Lantern
-// Copyright (C) 2006 Wolfgang Becker <uafr@gmx.de>
-//
-// 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.
-
-#include <config.h>
-
-#include "lantern.hpp"
-#include "sprite/sprite_manager.hpp"
-#include "object_factory.hpp"
-#include "badguy/willowisp.hpp"
-#include "badguy/treewillowisp.hpp"
-
-Lantern::Lantern(const lisp::Lisp& reader)
- : Rock(reader, "images/objects/lantern/lantern.sprite"),
- lightcolor(1.0f, 1.0f, 1.0f)
-{
- //get color from lisp
- std::vector<float> vColor;
- reader.get_vector("color", vColor);
- lightcolor = Color(vColor);
- lightsprite = sprite_manager->create("images/objects/lightmap_light/lightmap_light.sprite");
- lightsprite->set_blend(Blend(GL_SRC_ALPHA, GL_ONE));
- updateColor();
- sound_manager->preload("sounds/willocatch.wav");
-}
-
-Lantern::Lantern(const Vector& pos)
- : Rock(pos, "images/objects/lantern/lantern.sprite"),
- lightcolor(0.0f, 0.0f, 0.0f)
-{
- lightsprite = sprite_manager->create("images/objects/lightmap_light/lightmap_light.sprite");
- lightsprite->set_blend(Blend(GL_SRC_ALPHA, GL_ONE));
- updateColor();
- sound_manager->preload("sounds/willocatch.wav");
-}
-
-Lantern::~Lantern()
-{
- delete lightsprite;
-}
-
-void
-Lantern::updateColor(){
- lightsprite->set_color(lightcolor);
- //Turn lantern off if light is black
- if(lightcolor.red == 0 && lightcolor.green == 0 && lightcolor.blue == 0){
- sprite->set_action("off");
- } else {
- sprite->set_action("normal");
- sprite->set_color(lightcolor);
- }
-}
-
-void
-Lantern::draw(DrawingContext& context){
- //Draw the Sprite.
- MovingSprite::draw(context);
- //Let there be light.
- context.push_target();
- context.set_target(DrawingContext::LIGHTMAP);
-
- lightsprite->draw(context, get_bbox().get_middle(), 0);
-
- context.pop_target();
-}
-
-HitResponse Lantern::collision(GameObject& other, const CollisionHit& hit) {
- if (is_open()) {
- WillOWisp* wow = dynamic_cast<WillOWisp*>(&other);
- if (wow) {
- // collided with WillOWisp while grabbed and unlit
- sound_manager->play("sounds/willocatch.wav");
- lightcolor = Color(0,1,0);
- updateColor();
- wow->vanish();
- }
- TreeWillOWisp* twow = dynamic_cast<TreeWillOWisp*>(&other);
- if (twow) {
- // collided with TreeWillOWisp while grabbed and unlit
- sound_manager->play("sounds/willocatch.wav");
- lightcolor = twow->get_color();
- updateColor();
- twow->vanish();
- }
- }
- return Rock::collision(other, hit);
-}
-
-void
-Lantern::grab(MovingObject& object, const Vector& pos, Direction dir)
-{
- Rock::grab(object, pos, dir);
-
- // if lantern is not lit, draw it as opened
- if (is_open()) {
- sprite->set_action("off-open");
- }
-
-}
-
-void
-Lantern::ungrab(MovingObject& object, Direction dir)
-{
- // if lantern is not lit, it was drawn as opened while grabbed. Now draw it as closed again
- if (is_open()) {
- sprite->set_action("off");
- }
-
- Rock::ungrab(object, dir);
-}
-
-bool
-Lantern::is_open()
-{
- return ((grabbed) && lightcolor.red == 0 && lightcolor.green == 0 && lightcolor.blue == 0);
-}
-
-IMPLEMENT_FACTORY(Lantern, "lantern");
-
+++ /dev/null
-// $Id$
-//
-// SuperTux - Lantern
-// Copyright (C) 2006 Wolfgang Becker <uafr@gmx.de>
-//
-// 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.
-
-#ifndef __SUPERTUX_LANTERN_H__
-#define __SUPERTUX_LANTERN_H___
-
-#include "object/moving_sprite.hpp"
-#include "object/rock.hpp"
-
-/**
- * Lantern. A portable Light Source.
- */
-class Lantern : public Rock
-{
-public:
- Lantern(const Vector& pos);
- Lantern(const lisp::Lisp& reader);
- void draw(DrawingContext& context);
- ~Lantern();
-
- HitResponse collision(GameObject& other, const CollisionHit& hit);
-
- void grab(MovingObject& object, const Vector& pos, Direction dir);
- void ungrab(MovingObject& object, Direction dir);
-
- /**
- * returns true if lamp is currently open
- */
- bool is_open();
-
- /**
- * returns the lamp's color
- */
- Color get_color() const {
- return lightcolor;
- }
-
-private:
- Color lightcolor;
- Sprite* lightsprite;
- void updateColor();
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include "level_time.hpp"
-
-#include <stdexcept>
-#include <iostream>
-#include <sstream>
-#include "main.hpp"
-#include "resources.hpp"
-#include "sector.hpp"
-#include "gettext.hpp"
-#include "object_factory.hpp"
-#include "object/player.hpp"
-#include "video/drawing_context.hpp"
-#include "lisp/list_iterator.hpp"
-#include "log.hpp"
-#include "scripting/level_time.hpp"
-#include "scripting/squirrel_util.hpp"
-
-/** When to alert player they're low on time! */
-static const float TIME_WARNING = 20;
-
-LevelTime::LevelTime(const lisp::Lisp& reader)
-: running(true), time_left(0)
-{
- reader.get("name", name);
- reader.get("time", time_left);
- if(time_left <= 0) throw std::runtime_error("No or invalid leveltime specified");
- time_surface.reset(new Surface("images/engine/hud/time-0.png"));
-}
-
-void
-LevelTime::expose(HSQUIRRELVM vm, SQInteger table_idx)
-{
- if (name.empty()) return;
- Scripting::LevelTime* interface = new Scripting::LevelTime(this);
- expose_object(vm, table_idx, interface, name, true);
-}
-
-void
-LevelTime::unexpose(HSQUIRRELVM vm, SQInteger table_idx)
-{
- if (name.empty()) return;
- Scripting::unexpose_object(vm, table_idx, name);
-}
-
-void
-LevelTime::update(float elapsed_time)
-{
- if (!running) return;
-
- int prev_time = (int) floor(time_left*5);
- time_left -= elapsed_time;
- if(time_left <= 0) {
- if(time_left <= -5 || !Sector::current()->player->get_coins())
- {
- Sector::current()->player->kill(true);
- stop();
- }
- if(prev_time != (int) floor(time_left*5))
- {
- Sector::current()->player->add_coins(-1);
- }
- }
-}
-
-void
-LevelTime::draw(DrawingContext& context)
-{
- context.push_transform();
- context.set_translation(Vector(0, 0));
-
- if ((time_left > TIME_WARNING) || (int(game_time * 2.5) % 2)) {
- std::stringstream ss;
- ss << int(time_left);
- std::string time_text = ss.str();
-
- Surface* time_surf = time_surface.get();
- if (time_surf) {
- float all_width = time_surf->get_width() + white_text->get_text_width(time_text);
- context.draw_surface(time_surf, Vector((SCREEN_WIDTH - all_width)/2, BORDER_Y + 1), LAYER_FOREGROUND1);
- context.draw_text(gold_text, time_text, Vector((SCREEN_WIDTH - all_width)/2 + time_surf->get_width(), BORDER_Y), ALIGN_LEFT, LAYER_FOREGROUND1);
- }
- }
-
- context.pop_transform();
-}
-
-void
-LevelTime::start()
-{
- running = true;
-}
-
-void
-LevelTime::stop()
-{
- running = false;
-}
-
-float
-LevelTime::get_time()
-{
- return time_left;
-}
-
-void
-LevelTime::set_time(float time_left)
-{
- this->time_left = std::min(std::max(time_left, 0.0f), 999.0f);
-}
-
-IMPLEMENT_FACTORY(LevelTime, "leveltime");
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __LEVELTIME_H__
-#define __LEVELTIME_H__
-
-#include <memory>
-#include "game_object.hpp"
-#include "timer.hpp"
-#include "lisp/lisp.hpp"
-#include "video/surface.hpp"
-#include "script_interface.hpp"
-
-class LevelTime : public GameObject, public ScriptInterface
-{
-public:
- LevelTime(const lisp::Lisp& reader);
-
- virtual void expose(HSQUIRRELVM vm, SQInteger table_idx);
- virtual void unexpose(HSQUIRRELVM vm, SQInteger table_idx);
-
- void update(float elapsed_time);
- void draw(DrawingContext& context);
-
- /**
- * @name Scriptable Methods
- * @{
- */
-
- /**
- * Resumes the countdown
- */
- void start();
-
- /**
- * Pauses the countdown
- */
- void stop();
-
- /**
- * Returns the number of seconds left on the clock
- */
- float get_time();
-
- /**
- * Changes the number of seconds left on the clock
- */
- void set_time(float time_left);
-
- /**
- * @}
- */
-
-private:
- std::auto_ptr<Surface> time_surface;
- bool running;
- float time_left;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include "light.hpp"
-#include "sprite/sprite_manager.hpp"
-#include "resources.hpp"
-#include "video/drawing_context.hpp"
-#include "object_factory.hpp"
-#include "player.hpp"
-#include "sector.hpp"
-
-Light::Light(const Vector& center, const Color& color) : position(center), color(color)
-{
- sprite = sprite_manager->create("images/objects/lightmap_light/lightmap_light.sprite");
-}
-
-Light::~Light()
-{
- delete sprite;
-}
-
-void
-Light::update(float )
-{
-}
-
-void
-Light::draw(DrawingContext& context)
-{
- context.push_target();
- context.set_target(DrawingContext::LIGHTMAP);
-
- sprite->set_color(color);
- sprite->set_blend(Blend(GL_SRC_ALPHA, GL_ONE));
- sprite->set_angle(90); // FIXME: color won't get applied for angle=0
- sprite->draw(context, position, 0);
-
- context.pop_target();
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __LIGHT_HPP__
-#define __LIGHT_HPP__
-
-#include "game_object.hpp"
-#include "lisp/lisp.hpp"
-#include "math/vector.hpp"
-#include "video/color.hpp"
-
-class Sprite;
-
-class Light : public GameObject
-{
-public:
- Light(const Vector& center, const Color& color = Color(1.0, 1.0, 1.0, 1.0));
- virtual ~Light();
-
- void update(float elapsed_time);
- void draw(DrawingContext& context);
-
-protected:
- Vector position;
- Color color;
- Sprite* sprite;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux - MagicBlock
-//
-// Magic Blocks are tile-like game objects that are sensitive to
-// lighting conditions. They are rendered in a color and
-// will only be solid as long as light of the same color shines
-// on the block.
-//
-// Copyright (C) 2006 Wolfgang Becker <uafr@gmx.de>
-//
-// 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.
-
-#include <config.h>
-#include <vector>
-
-#include "object/camera.hpp"
-#include "magicblock.hpp"
-#include "object_factory.hpp"
-#include "sprite/sprite_manager.hpp"
-#include "sector.hpp"
-#include "main.hpp"
-
-namespace {
- const float MIN_INTENSITY = 0.8f;
- const float ALPHA_SOLID = 0.7f;
- const float ALPHA_NONSOLID = 0.3f;
- const float MIN_SOLIDTIME = 1.0f;
- const float SWITCH_DELAY = 0.1f; /**< seconds to wait for stable conditions until switching solidity */
-}
-
-MagicBlock::MagicBlock(const lisp::Lisp& lisp)
- : MovingSprite(lisp, "images/objects/magicblock/magicblock.sprite"),
- is_solid(false), solid_time(0), switch_delay(0), light(1.0f,1.0f,1.0f)
-{
- set_group(COLGROUP_STATIC);
- //get color from lisp
- std::vector<float> vColor;
- lisp.get_vector("color", vColor );
- color = Color( vColor );
-
- //all alpha to make the sprite still visible
- color.alpha = ALPHA_SOLID;
-
- //set trigger
- if(color.red == 0 && color.green == 0 && color.blue == 0) { //is it black?
- black = true;
- trigger_red = MIN_INTENSITY;
- trigger_green = MIN_INTENSITY;
- trigger_blue = MIN_INTENSITY;
- } else {
- black = false;
- trigger_red = (color.red == 1.0f ? MIN_INTENSITY : 0);
- trigger_green = (color.green == 1.0f ? MIN_INTENSITY : 0);
- trigger_blue = (color.blue == 1.0f ? MIN_INTENSITY : 0);
- }
-
- center = get_bbox().get_middle();
-}
-
-void
-MagicBlock::update(float elapsed_time)
-{
- //Check if center of this block is on screen.
- //Don't update if not, because there is no light off screen.
- float screen_left = Sector::current()->camera->get_translation().x;
- float screen_top = Sector::current()->camera->get_translation().y;
- float screen_right = screen_left+ SCREEN_WIDTH;
- float screen_bottom = screen_top + SCREEN_HEIGHT;
- if((center.x > screen_right ) || ( center.y > screen_bottom) ||
- ( center.x < screen_left) || ( center.y < screen_top)) {
- switch_delay = SWITCH_DELAY;
- return;
- }
-
- bool lighting_ok;
- if(black) {
- lighting_ok = (light.red >= trigger_red || light.green >= trigger_green
- || light.blue >= trigger_blue);
- }else{
- lighting_ok = (light.red >= trigger_red && light.green >= trigger_green
- && light.blue >= trigger_blue);
- }
-
- // overrule lighting_ok if switch_delay has not yet passed
- if (lighting_ok == is_solid) {
- switch_delay = SWITCH_DELAY;
- } else {
- if (switch_delay > 0) {
- lighting_ok = is_solid;
- switch_delay -= elapsed_time;
- }
- }
-
- if (lighting_ok) {
- // lighting suggests going solid
-
- if (!is_solid) {
- if (Sector::current()->is_free_of_movingstatics(get_bbox(), this)) {
- is_solid = true;
- solid_time = 0;
- switch_delay = SWITCH_DELAY;
- }
- }
- } else {
- // lighting suggests going nonsolid
-
- if( solid_time >= MIN_SOLIDTIME ){
- is_solid = false;
- }
- }
-
- //Update Sprite.
- if(is_solid) {
- solid_time+=elapsed_time;
- color.alpha = ALPHA_SOLID;
- sprite->set_action("solid");
- } else {
- color.alpha = ALPHA_NONSOLID;
- sprite->set_action("normal");
- }
-}
-
-void
-MagicBlock::draw(DrawingContext& context){
- //Ask for update about lightmap at center of this block
- context.get_light( center, &light );
-
- //Draw the Sprite.
- MovingSprite::draw(context);
- //Add the color.
- context.draw_filled_rect( get_bbox(), color, layer);
-}
-
-bool
-MagicBlock::collides(GameObject& /*other*/, const CollisionHit& /*hit*/)
-{
- return is_solid;
-}
-
-HitResponse
-MagicBlock::collision(GameObject& /*other*/, const CollisionHit& /*hit*/)
-{
- return SOLID;
-}
-
-IMPLEMENT_FACTORY(MagicBlock, "magicblock");
+++ /dev/null
-// $Id$
-//
-// SuperTux - MagicBlock
-//
-// Magic Blocks are tile-like game objects that are sensitive to
-// lighting conditions. They are rendered in a color and
-// will only be solid as long as light of the same color shines
-// on the block. The black block becomes solid, if any kind of
-// light is above MIN_INTENSITY.
-//
-// Copyright (C) 2006 Wolfgang Becker <uafr@gmx.de>
-//
-// 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.
-
-#ifndef SUPERTUX_TRAMPOLINE_H
-#define SUPERTUX_TRAMPOLINE_H
-
-#include "moving_sprite.hpp"
-#include "lisp/lisp.hpp"
-
-class MagicBlock: public MovingSprite
-{
-public:
- MagicBlock(const lisp::Lisp& reader);
-
- bool collides(GameObject& other, const CollisionHit& hit);
- HitResponse collision(GameObject& other, const CollisionHit& hit);
- void update(float elapsed_time);
- void draw(DrawingContext& context);
-
-private:
- bool is_solid;
- float trigger_red;
- float trigger_green;
- float trigger_blue;
- float solid_time;
- float switch_delay; /**< seconds until switching solidity */
- Color color;
- Color light;
- Vector center;
- bool black;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux - MovingSprite Base Class
-// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
-//
-// 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.
-#include <config.h>
-
-#include <stdexcept>
-
-#include "moving_sprite.hpp"
-#include "video/drawing_context.hpp"
-#include "sprite/sprite_manager.hpp"
-#include "player.hpp"
-#include "sector.hpp"
-#include "player_status.hpp"
-#include "gameobjs.hpp"
-#include "statistics.hpp"
-#include "object_factory.hpp"
-#include "level.hpp"
-#include "random_generator.hpp"
-#include "audio/sound_source.hpp"
-#include "audio/sound_manager.hpp"
-#include "timer.hpp"
-
-MovingSprite::MovingSprite(const Vector& pos, const std::string& sprite_name, int layer, CollisionGroup collision_group)
- : sprite_name(sprite_name), layer(layer)
-{
- bbox.set_pos(pos);
- sprite = sprite_manager->create(sprite_name);
- bbox.set_size(sprite->get_current_hitbox_width(), sprite->get_current_hitbox_height());
- set_group(collision_group);
-}
-
-MovingSprite::MovingSprite(const lisp::Lisp& reader, const Vector& pos, int layer, CollisionGroup collision_group)
- : layer(layer)
-{
- bbox.set_pos(pos);
- if (!reader.get("sprite", sprite_name))
- throw std::runtime_error("no sprite name set");
-
- sprite = sprite_manager->create(sprite_name);
- bbox.set_size(sprite->get_current_hitbox_width(), sprite->get_current_hitbox_height());
- set_group(collision_group);
-}
-
-MovingSprite::MovingSprite(const lisp::Lisp& reader, const std::string& sprite_name, int layer, CollisionGroup collision_group)
- : sprite_name(sprite_name), layer(layer)
-{
- if (!reader.get("x", bbox.p1.x))
- throw std::runtime_error("no x position set");
- if (!reader.get("y", bbox.p1.y))
- throw std::runtime_error("no y position set");
-
- sprite = sprite_manager->create(sprite_name);
- bbox.set_size(sprite->get_current_hitbox_width(), sprite->get_current_hitbox_height());
- set_group(collision_group);
-}
-
-MovingSprite::MovingSprite(const lisp::Lisp& reader, int layer, CollisionGroup collision_group)
- : layer(layer)
-{
- if (!reader.get("x", bbox.p1.x))
- throw std::runtime_error("no x position set");
- if (!reader.get("y", bbox.p1.y))
- throw std::runtime_error("no y position set");
- if (!reader.get("sprite", sprite_name))
- throw std::runtime_error("no sprite name set");
-
- sprite = sprite_manager->create(sprite_name);
- bbox.set_size(sprite->get_current_hitbox_width(), sprite->get_current_hitbox_height());
- set_group(collision_group);
-}
-
-MovingSprite::MovingSprite(const MovingSprite& other)
- : MovingObject(other), layer(other.layer)
-{
- sprite = new Sprite(*other.sprite);
-}
-
-MovingSprite&
-MovingSprite::operator=(const MovingSprite& other)
-{
- if (this == &other)
- return *this;
-
- delete sprite;
- sprite = new Sprite(*other.sprite);
-
- layer = other.layer;
-
- return *this;
-}
-
-MovingSprite::~MovingSprite()
-{
- delete sprite;
-}
-
-void
-MovingSprite::draw(DrawingContext& context)
-{
- sprite->draw(context, get_pos(), layer);
-}
-
-void
-MovingSprite::update(float )
-{
-}
-
-void
-MovingSprite::set_action(const std::string& action, int loops)
-{
- sprite->set_action(action, loops);
- set_size(sprite->get_current_hitbox_width(), sprite->get_current_hitbox_height());
-}
-
-void
-MovingSprite::set_action_centered(const std::string& action, int loops)
-{
- Vector old_size = bbox.get_size();
- sprite->set_action(action, loops);
- set_size(sprite->get_current_hitbox_width(), sprite->get_current_hitbox_height());
- set_pos(get_pos() - (bbox.get_size() - old_size) / 2);
-}
-
-void
-MovingSprite::set_action(const std::string& action, int loops, AnchorPoint anchorPoint)
-{
- Rect old_bbox = bbox;
- sprite->set_action(action, loops);
- float w = sprite->get_current_hitbox_width();
- float h = sprite->get_current_hitbox_height();
- set_size(w, h);
- set_pos(get_anchor_pos(old_bbox, w, h, anchorPoint));
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux - MovingSprite Base Class
-// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
-//
-// 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.
-
-#ifndef __MOVING_SPRITE_H__
-#define __MOVING_SPRITE_H__
-
-#include <string>
-#include "moving_object.hpp"
-#include "sprite/sprite.hpp"
-#include "video/drawing_context.hpp"
-#include "object/anchor_point.hpp"
-
-/**
- * Abstract base class for MovingObjects that are represented by a Sprite
- */
-class MovingSprite : public MovingObject
-{
-public:
- MovingSprite(const Vector& pos, const std::string& sprite_name, int layer = LAYER_OBJECTS, CollisionGroup collision_group = COLGROUP_MOVING);
- MovingSprite(const lisp::Lisp& reader, const Vector& pos, int layer = LAYER_OBJECTS, CollisionGroup collision_group = COLGROUP_MOVING);
- MovingSprite(const lisp::Lisp& reader, const std::string& sprite_name, int layer = LAYER_OBJECTS, CollisionGroup collision_group = COLGROUP_MOVING);
- MovingSprite(const lisp::Lisp& reader, int layer = LAYER_OBJECTS, CollisionGroup collision_group = COLGROUP_MOVING);
- MovingSprite(const MovingSprite& moving_sprite);
- MovingSprite& operator=(const MovingSprite& moving_sprite);
- ~MovingSprite();
-
- virtual void draw(DrawingContext& context);
- virtual void update(float elapsed_time);
-
-protected:
- std::string sprite_name;
- Sprite* sprite;
- int layer; /**< Sprite's z-position. Refer to video/drawing_context.hpp for sensible values. */
-
- /**
- * set new action for sprite and resize bounding box.
- * use with care as you can easily get stuck when resizing the bounding box.
- */
- void set_action(const std::string& action, int loops);
-
- /**
- * set new action for sprite and re-center bounding box.
- * use with care as you can easily get stuck when resizing the bounding box.
- */
- void set_action_centered(const std::string& action, int loops);
-
- /**
- * set new action for sprite and align bounding boxes at anchorPoint.
- * use with care as you can easily get stuck when resizing the bounding box.
- */
- void set_action(const std::string& action, int loops, AnchorPoint anchorPoint);
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include "oneup.hpp"
-#include "resources.hpp"
-#include "player.hpp"
-#include "player_status.hpp"
-#include "sector.hpp"
-#include "level.hpp"
-#include "statistics.hpp"
-#include "video/drawing_context.hpp"
-
-OneUp::OneUp(const Vector& pos, Direction direction)
- : MovingSprite(pos, "images/powerups/1up/1up.sprite", LAYER_FLOATINGOBJECTS, COLGROUP_TOUCHABLE)
-{
- physic.set_velocity((direction == LEFT)?-100:100, -400);
-}
-
-void
-OneUp::update(float elapsed_time)
-{
- if(!Sector::current()->inside(bbox))
- remove_me();
-
- movement = physic.get_movement(elapsed_time);
-}
-
-HitResponse
-OneUp::collision(GameObject& other, const CollisionHit& )
-{
- Player* player = dynamic_cast<Player*> (&other);
- if(player) {
- player->get_status()->add_coins(100);
-#if 0
- // FIXME: do we want this? q.v. src/level.cpp
- Sector::current()->get_level()->stats.coins += 100;
-#endif
- remove_me();
- return ABORT_MOVE;
- }
- return FORCE_MOVE;
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __ONEUP_H__
-#define __ONEUP_H__
-
-#include "object/moving_sprite.hpp"
-#include "physic.hpp"
-#include "direction.hpp"
-
-class OneUp : public MovingSprite, private UsesPhysic
-{
-public:
- OneUp(const Vector& pos, Direction direction = RIGHT);
- virtual OneUp* clone() const { return new OneUp(*this); }
-
- virtual void update(float elapsed_time);
- virtual HitResponse collision(GameObject& other, const CollisionHit& hit);
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include <math.h>
-
-#include "particles.hpp"
-#include "sector.hpp"
-#include "camera.hpp"
-#include "main.hpp"
-#include "random_generator.hpp"
-
-Particles::Particles(const Vector& epicenter, int min_angle, int max_angle,
- const Vector& initial_velocity, const Vector& acceleration, int number,
- Color color_, int size_, float life_time, int drawing_layer_)
- : accel(acceleration), color(color_), size(size_), drawing_layer(drawing_layer_)
-{
- if(life_time == 0) {
- live_forever = true;
- } else {
- live_forever = false;
- timer.start(life_time);
- }
-
- // create particles
- for(int p = 0; p < number; p++)
- {
- Particle* particle = new Particle;
- particle->pos = epicenter;
-
- float angle = systemRandom.rand(min_angle, max_angle)
- * (M_PI / 180); // convert to radius (radians?)
- particle->vel.x = /*fabs*/(sin(angle)) * initial_velocity.x;
-// if(angle >= M_PI && angle < M_PI*2)
-// particle->vel.x *= -1; // work around to fix signal
- particle->vel.y = /*fabs*/(cos(angle)) * initial_velocity.y;
-// if(angle >= M_PI_2 && angle < 3*M_PI_2)
-// particle->vel.y *= -1;
-
- particles.push_back(particle);
- }
-}
-
-Particles::~Particles()
-{
- // free particles
- for(std::vector<Particle*>::iterator i = particles.begin();
- i < particles.end(); i++)
- delete (*i);
-}
-
-void
-Particles::update(float elapsed_time)
-{
- Vector camera = Sector::current()->camera->get_translation();
-
- // update particles
- for(std::vector<Particle*>::iterator i = particles.begin();
- i != particles.end(); ) {
- (*i)->pos.x += (*i)->vel.x * elapsed_time;
- (*i)->pos.y += (*i)->vel.y * elapsed_time;
-
- (*i)->vel.x += accel.x * elapsed_time;
- (*i)->vel.y += accel.y * elapsed_time;
-
- if((*i)->pos.x < camera.x || (*i)->pos.x > SCREEN_WIDTH + camera.x ||
- (*i)->pos.y < camera.y || (*i)->pos.y > SCREEN_HEIGHT + camera.y) {
- delete (*i);
- i = particles.erase(i);
- } else {
- ++i;
- }
- }
-
- if((timer.check() && !live_forever) || particles.size() == 0)
- remove_me();
-}
-
-void
-Particles::draw(DrawingContext& context)
-{
- // draw particles
- for(std::vector<Particle*>::iterator i = particles.begin();
- i != particles.end(); i++) {
- context.draw_filled_rect((*i)->pos, Vector(size,size), color,drawing_layer);
- }
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef SUPERTUX_PARTICLES_HPP
-#define SUPERTUX_PARTICLES_HPP
-
-#include "math/vector.hpp"
-#include "game_object.hpp"
-#include "timer.hpp"
-#include "video/color.hpp"
-
-class Particles : public GameObject
-{
-public:
- Particles(const Vector& epicenter, int min_angle, int max_angle,
- const Vector& initial_velocity, const Vector& acceleration,
- int number, Color color, int size, float life_time,
- int drawing_layer);
- ~Particles();
-
- virtual void update(float elapsed_time);
- virtual void draw(DrawingContext& context);
-
-private:
- Vector accel;
- Timer timer;
- bool live_forever;
-
- Color color;
- float size;
- int drawing_layer;
-
- struct Particle {
- Vector pos, vel;
-// float angle;
- };
- std::vector <Particle*> particles;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include <iostream>
-#include <cmath>
-
-#include "particlesystem.hpp"
-#include "video/drawing_context.hpp"
-#include "lisp/parser.hpp"
-#include "lisp/lisp.hpp"
-#include "lisp/writer.hpp"
-#include "resources.hpp"
-#include "main.hpp"
-#include "object/camera.hpp"
-#include "random_generator.hpp"
-
-ParticleSystem::ParticleSystem(float max_particle_size)
- : max_particle_size(max_particle_size)
-{
- virtual_width = SCREEN_WIDTH + max_particle_size * 2;
- virtual_height = SCREEN_HEIGHT + max_particle_size *2;
- z_pos = LAYER_BACKGROUND1;
-}
-
-ParticleSystem::~ParticleSystem()
-{
- std::vector<Particle*>::iterator i;
- for(i = particles.begin(); i != particles.end(); ++i) {
- delete *i;
- }
-}
-
-void ParticleSystem::draw(DrawingContext& context)
-{
- float scrollx = context.get_translation().x;
- float scrolly = context.get_translation().y;
-
- context.push_transform();
- context.set_translation(Vector(max_particle_size,max_particle_size));
-
- std::vector<Particle*>::iterator i;
- for(i = particles.begin(); i != particles.end(); ++i) {
- Particle* particle = *i;
-
- // remap x,y coordinates onto screencoordinates
- Vector pos;
-
- pos.x = fmodf(particle->pos.x - scrollx, virtual_width);
- if(pos.x < 0) pos.x += virtual_width;
-
- pos.y = fmodf(particle->pos.y - scrolly, virtual_height);
- if(pos.y < 0) pos.y += virtual_height;
-
-
- //if(pos.x > virtual_width) pos.x -= virtual_width;
- //if(pos.y > virtual_height) pos.y -= virtual_height;
-
- context.draw_surface(particle->texture, pos, z_pos);
- }
-
- context.pop_transform();
-}
-
-SnowParticleSystem::SnowParticleSystem()
-{
- snowimages[0] = new Surface("images/objects/particles/snow2.png");
- snowimages[1] = new Surface("images/objects/particles/snow1.png");
- snowimages[2] = new Surface("images/objects/particles/snow0.png");
-
- virtual_width = SCREEN_WIDTH * 2;
-
- // create some random snowflakes
- size_t snowflakecount = size_t(virtual_width/10.0);
- for(size_t i=0; i<snowflakecount; ++i) {
- SnowParticle* particle = new SnowParticle;
- int snowsize = systemRandom.rand(3);
-
- particle->pos.x = systemRandom.randf(virtual_width);
- particle->pos.y = systemRandom.randf(SCREEN_HEIGHT);
- particle->anchorx = particle->pos.x + (systemRandom.randf(-0.5, 0.5) * 16);
- particle->drift_speed = systemRandom.randf(-0.5, 0.5) * 0.3;
- particle->wobble = 0.0;
-
- particle->texture = snowimages[snowsize];
-
- particle->speed = 1 + (2 - snowsize)/2 + systemRandom.randf(1.8);
- particle->speed *= 20; // gravity
-
- particles.push_back(particle);
- }
-}
-
-void
-SnowParticleSystem::parse(const lisp::Lisp& reader)
-{
- reader.get("z-pos", z_pos);
-}
-
-void
-SnowParticleSystem::write(lisp::Writer& writer)
-{
- writer.start_list("particles-snow");
- writer.write_int("z-pos", z_pos);
- writer.end_list("particles-snow");
-}
-
-SnowParticleSystem::~SnowParticleSystem()
-{
- for(int i=0;i<3;++i)
- delete snowimages[i];
-}
-
-void SnowParticleSystem::update(float elapsed_time)
-{
- std::vector<Particle*>::iterator i;
-
- for(i = particles.begin(); i != particles.end(); ++i) {
- SnowParticle* particle = (SnowParticle*) *i;
- float anchor_delta;
-
- particle->pos.y += particle->speed * elapsed_time;
- particle->pos.x += particle->wobble * elapsed_time /* * particle->speed * 0.125*/;
-
- anchor_delta = (particle->anchorx - particle->pos.x);
- particle->wobble += (4 * anchor_delta * 0.05) + systemRandom.randf(-0.5, 0.5);
- particle->wobble *= 0.99f;
- particle->anchorx += particle->drift_speed * elapsed_time;
- }
-}
-
-//FIXME: Sometimes both ghosts have the same image
-// Ghosts don't change their movement pattern - not random
-GhostParticleSystem::GhostParticleSystem()
-{
- ghosts[0] = new Surface("images/objects/particles/ghost0.png");
- ghosts[1] = new Surface("images/objects/particles/ghost1.png");
-
- virtual_width = SCREEN_WIDTH * 2;
-
- // create two ghosts
- size_t ghostcount = 2;
- for(size_t i=0; i<ghostcount; ++i) {
- GhostParticle* particle = new GhostParticle;
- particle->pos.x = systemRandom.randf(virtual_width);
- particle->pos.y = systemRandom.randf(SCREEN_HEIGHT);
- int size = systemRandom.rand(2);
- particle->texture = ghosts[size];
- particle->speed = systemRandom.randf(std::max(50, (size * 10)), 180 + (size * 10));
- particles.push_back(particle);
- }
-}
-
-void
-GhostParticleSystem::parse(const lisp::Lisp& reader)
-{
- reader.get("z-pos", z_pos);
-}
-
-void
-GhostParticleSystem::write(lisp::Writer& writer)
-{
- writer.start_list("particles-ghosts");
- writer.write_int("z-pos", z_pos);
- writer.end_list("particles-ghosts");
-}
-
-GhostParticleSystem::~GhostParticleSystem()
-{
- for(int i=0;i<2;++i)
- delete ghosts[i];
-}
-
-void GhostParticleSystem::update(float elapsed_time)
-{
- std::vector<Particle*>::iterator i;
- for(i = particles.begin(); i != particles.end(); ++i) {
- GhostParticle* particle = (GhostParticle*) *i;
- particle->pos.y -= particle->speed * elapsed_time;
- particle->pos.x -= particle->speed * elapsed_time;
- if(particle->pos.y > SCREEN_HEIGHT) {
- particle->pos.y = fmodf(particle->pos.y , virtual_height);
- particle->pos.x = systemRandom.rand(static_cast<int>(virtual_width));
- }
- }
-}
-
-CloudParticleSystem::CloudParticleSystem()
- : ParticleSystem(128)
-{
- cloudimage = new Surface("images/objects/particles/cloud.png");
-
- virtual_width = 2000.0;
-
- // create some random clouds
- for(size_t i=0; i<15; ++i) {
- CloudParticle* particle = new CloudParticle;
- particle->pos.x = systemRandom.rand(static_cast<int>(virtual_width));
- particle->pos.y = systemRandom.rand(static_cast<int>(virtual_height));
- particle->texture = cloudimage;
- particle->speed = -systemRandom.randf(25.0, 54.0);
-
- particles.push_back(particle);
- }
-}
-
-void
-CloudParticleSystem::parse(const lisp::Lisp& reader)
-{
- reader.get("z-pos", z_pos);
-}
-
-void
-CloudParticleSystem::write(lisp::Writer& writer)
-{
- writer.start_list("particles-clouds");
- writer.write_int("z-pos", z_pos);
- writer.end_list("particles-clouds");
-}
-
-CloudParticleSystem::~CloudParticleSystem()
-{
- delete cloudimage;
-}
-
-void CloudParticleSystem::update(float elapsed_time)
-{
- std::vector<Particle*>::iterator i;
- for(i = particles.begin(); i != particles.end(); ++i) {
- CloudParticle* particle = (CloudParticle*) *i;
- particle->pos.x += particle->speed * elapsed_time;
- }
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef SUPERTUX_PARTICLESYSTEM_H
-#define SUPERTUX_PARTICLESYSTEM_H
-
-#include <vector>
-
-#include "video/surface.hpp"
-#include "game_object.hpp"
-#include "serializable.hpp"
-#include "sector.hpp"
-#include "math/vector.hpp"
-
-namespace lisp {
-class Lisp;
-}
-
-class DisplayManager;
-
-/**
- * This is the base class for particle systems. It is responsible for storing a
- * set of particles with each having an x- and y-coordinate the number of the
- * layer where it should be drawn and a texture.
- * The coordinate system used here is a virtual one. It would be a bad idea to
- * populate whole levels with particles. So we're using a virtual rectangle
- * here that is tiled onto the level when drawing. This rect.has the size
- * (virtual_width, virtual_height). We're using modulo on the particle
- * coordinates, so when a particle leaves left, it'll reenter at the right
- * side.
- *
- * Classes that implement a particle system should subclass from this class,
- * initialize particles in the constructor and move them in the simulate
- * function.
- */
-class ParticleSystem : public GameObject
-{
-public:
- ParticleSystem(float max_particle_size = 60);
- virtual ~ParticleSystem();
-
- virtual void draw(DrawingContext& context);
-
-protected:
- float max_particle_size;
- int z_pos;
-
- class Particle
- {
- public:
- virtual ~Particle()
- { }
-
- Vector pos;
- Surface* texture;
- };
-
- std::vector<Particle*> particles;
- float virtual_width, virtual_height;
-};
-
-class SnowParticleSystem : public ParticleSystem, public Serializable
-{
-public:
- SnowParticleSystem();
- virtual ~SnowParticleSystem();
-
- void parse(const lisp::Lisp& lisp);
- void write(lisp::Writer& writer);
-
- virtual void update(float elapsed_time);
-
- std::string type() const
- { return "SnowParticleSystem"; }
-
-private:
- class SnowParticle : public Particle
- {
- public:
- float speed;
- float wobble;
- float anchorx;
- float drift_speed;
- };
-
- Surface* snowimages[3];
-};
-
-class GhostParticleSystem : public ParticleSystem, public Serializable
-{
-public:
- GhostParticleSystem();
- virtual ~GhostParticleSystem();
-
- void parse(const lisp::Lisp& lisp);
- void write(lisp::Writer& writer);
-
- virtual void update(float elapsed_time);
-
- std::string type() const
- { return "GhostParticleSystem"; }
-
-private:
- class GhostParticle : public Particle
- {
- public:
- float speed;
- };
-
- Surface* ghosts[2];
-};
-
-class CloudParticleSystem : public ParticleSystem, public Serializable
-{
-public:
- CloudParticleSystem();
- virtual ~CloudParticleSystem();
-
- void parse(const lisp::Lisp& lisp);
- void write(lisp::Writer& writer);
-
- virtual void update(float elapsed_time);
-
- std::string type() const
- { return "CloudParticleSystem"; }
-
-private:
- class CloudParticle : public Particle
- {
- public:
- float speed;
- };
-
- Surface* cloudimage;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include <iostream>
-#include <cmath>
-
-#include "particlesystem_interactive.hpp"
-#include "video/drawing_context.hpp"
-#include "lisp/parser.hpp"
-#include "lisp/lisp.hpp"
-#include "lisp/writer.hpp"
-#include "resources.hpp"
-#include "main.hpp"
-
-#include "tile.hpp"
-#include "tilemap.hpp"
-#include "math/aatriangle.hpp"
-#include "collision.hpp"
-#include "collision_hit.hpp"
-#include "object/camera.hpp"
-#include "object/rainsplash.hpp"
-#include "badguy/bomb.hpp"
-#include "random_generator.hpp"
-
-//TODO: Find a way to make rain collide with objects like bonus blocks
-// Add an option to set rain strength
-// Fix rain being "respawned" over solid tiles
-ParticleSystem_Interactive::ParticleSystem_Interactive()
-{
- virtual_width = SCREEN_WIDTH;
- virtual_height = SCREEN_HEIGHT;
- z_pos = 0;
-}
-
-ParticleSystem_Interactive::~ParticleSystem_Interactive()
-{
- std::vector<Particle*>::iterator i;
- for(i = particles.begin(); i != particles.end(); ++i) {
- delete *i;
- }
-}
-
-void ParticleSystem_Interactive::draw(DrawingContext& context)
-{
- context.push_transform();
-
- std::vector<Particle*>::iterator i;
- for(i = particles.begin(); i != particles.end(); ++i) {
- Particle* particle = *i;
- context.draw_surface(particle->texture, particle->pos, z_pos);
- }
-
- context.pop_transform();
-}
-
-int
-ParticleSystem_Interactive::collision(Particle* object, Vector movement)
-{
- using namespace collision;
-
- // calculate rectangle where the object will move
- float x1, x2;
- float y1, y2;
- x1 = object->pos.x;
- x2 = x1 + 32 + movement.x;
- y1 = object->pos.y;
- y2 = y1 + 32 + movement.y;
- bool water = false;
-
- // test with all tiles in this rectangle
- int starttilex = int(x1-1) / 32;
- int starttiley = int(y1-1) / 32;
- int max_x = int(x2+1);
- int max_y = int(y2+1);
-
- Rect dest = Rect(x1, y1, x2, y2);
- dest.move(movement);
- Constraints constraints;
-
- for(std::list<TileMap*>::const_iterator i = Sector::current()->solid_tilemaps.begin(); i != Sector::current()->solid_tilemaps.end(); i++) {
- TileMap* solids = *i;
- for(int x = starttilex; x*32 < max_x; ++x) {
- for(int y = starttiley; y*32 < max_y; ++y) {
- const Tile* tile = solids->get_tile(x, y);
- if(!tile)
- continue;
- // skip non-solid tiles, except water
- if(! (tile->getAttributes() & (Tile::WATER | Tile::SOLID)))
- continue;
-
- if(tile->getAttributes() & Tile::SLOPE) { // slope tile
- AATriangle triangle;
- Vector p1(x*32, y*32);
- Vector p2((x+1)*32, (y+1)*32);
- triangle = AATriangle(p1, p2, tile->getData());
-
- if(rectangle_aatriangle(&constraints, dest, triangle)) {
- if(tile->getAttributes() & Tile::WATER)
- water = true;
- }
- } else { // normal rectangular tile
- Rect rect(x*32, y*32, (x+1)*32, (y+1)*32);
- if(intersects(dest, rect)) {
- if(tile->getAttributes() & Tile::WATER)
- water = true;
- set_rectangle_rectangle_constraints(&constraints, dest, rect);
- }
- }
- }
- }
- }
-
-
- // TODO don't use magic numbers here...
-
- // did we collide at all?
- if(!constraints.has_constraints())
- return -1;
-
- const CollisionHit& hit = constraints.hit;
- if (water) {
- return 0; //collision with water tile - don't draw splash
- } else {
- if (hit.right || hit.left) {
- return 2; //collision from right
- } else {
- return 1; //collision from above
- }
- }
-
- return 0;
-}
-
-RainParticleSystem::RainParticleSystem()
-{
- rainimages[0] = new Surface("images/objects/particles/rain0.png");
- rainimages[1] = new Surface("images/objects/particles/rain1.png");
-
- virtual_width = SCREEN_WIDTH * 2;
-
- // create some random raindrops
- size_t raindropcount = size_t(virtual_width/6.0);
- for(size_t i=0; i<raindropcount; ++i) {
- RainParticle* particle = new RainParticle;
- particle->pos.x = systemRandom.rand(int(virtual_width));
- particle->pos.y = systemRandom.rand(int(virtual_height));
- int rainsize = systemRandom.rand(2);
- particle->texture = rainimages[rainsize];
- do {
- particle->speed = (rainsize+1)*45 + systemRandom.randf(3.6);
- } while(particle->speed < 1);
- particle->speed *= 10; // gravity
-
- particles.push_back(particle);
- }
-}
-
-void
-RainParticleSystem::parse(const lisp::Lisp& reader)
-{
- reader.get("z-pos", z_pos);
-}
-
-void
-RainParticleSystem::write(lisp::Writer& writer)
-{
- writer.start_list("particles-rain");
- writer.write_int("z-pos", z_pos);
- writer.end_list("particles-rain");
-}
-
-RainParticleSystem::~RainParticleSystem()
-{
- for(int i=0;i<2;++i)
- delete rainimages[i];
-}
-
-void RainParticleSystem::update(float elapsed_time)
-{
- std::vector<Particle*>::iterator i;
- for(
- i = particles.begin(); i != particles.end(); ++i) {
- RainParticle* particle = (RainParticle*) *i;
- float movement = particle->speed * elapsed_time;
- float abs_x = Sector::current()->camera->get_translation().x;
- float abs_y = Sector::current()->camera->get_translation().y;
- particle->pos.y += movement;
- particle->pos.x -= movement;
- int col = collision(particle, Vector(-movement, movement));
- if ((particle->pos.y > SCREEN_HEIGHT + abs_y) || (col >= 0)) {
- //Create rainsplash
- if ((particle->pos.y <= SCREEN_HEIGHT + abs_y) && (col >= 1)){
- bool vertical = (col == 2);
- int splash_x, splash_y;
- if (!vertical) { //check if collision happened from above
- splash_x = int(particle->pos.x);
- splash_y = int(particle->pos.y) - (int(particle->pos.y) % 32) + 32;
- Sector::current()->add_object(new RainSplash(Vector(splash_x, splash_y),vertical));
- }
- // Uncomment the following to display vertical splashes, too
- /* else {
- splash_x = int(particle->pos.x) - (int(particle->pos.x) % 32) + 32;
- splash_y = int(particle->pos.y);
- Sector::current()->add_object(new RainSplash(Vector(splash_x, splash_y),vertical));
- } */
- }
- int new_x = systemRandom.rand(int(virtual_width)) + int(abs_x);
- int new_y = 0;
- //FIXME: Don't move particles over solid tiles
- particle->pos.x = new_x;
- particle->pos.y = new_y;
- }
- }
-}
-
-CometParticleSystem::CometParticleSystem()
-{
- cometimages[0] = new Surface("images/creatures/mr_bomb/exploding-left-0.png");
- cometimages[1] = new Surface("images/creatures/mr_bomb/exploding-left-0.png");
-
- virtual_width = SCREEN_WIDTH * 2;
-
- // create some random comets
- size_t cometcount = 2;
- for(size_t i=0; i<cometcount; ++i) {
- CometParticle* particle = new CometParticle;
- particle->pos.x = systemRandom.rand(int(virtual_width));
- particle->pos.y = systemRandom.rand(int(virtual_height));
- int cometsize = systemRandom.rand(2);
- particle->texture = cometimages[cometsize];
- do {
- particle->speed = (cometsize+1)*30 + systemRandom.randf(3.6);
- } while(particle->speed < 1);
- particle->speed *= 10; // gravity
-
- particles.push_back(particle);
- }
-}
-
-void
-CometParticleSystem::parse(const lisp::Lisp& reader)
-{
- reader.get("z-pos", z_pos);
-}
-
-void
-CometParticleSystem::write(lisp::Writer& writer)
-{
- writer.start_list("particles-comets");
- writer.write_int("z-pos", z_pos);
- writer.end_list("particles-comets");
-}
-
-CometParticleSystem::~CometParticleSystem()
-{
- for(int i=0;i<2;++i)
- delete cometimages[i];
-}
-
-void CometParticleSystem::update(float elapsed_time)
-{
- (void) elapsed_time;
-#if 0
- std::vector<Particle*>::iterator i;
- for(
- i = particles.begin(); i != particles.end(); ++i) {
- CometParticle* particle = (CometParticle*) *i;
- float movement = particle->speed * elapsed_time;
- float abs_x = Sector::current()->camera->get_translation().x;
- float abs_y = Sector::current()->camera->get_translation().y;
- particle->pos.y += movement;
- particle->pos.x -= movement;
- int col = collision(particle, Vector(-movement, movement));
- if ((particle->pos.y > SCREEN_HEIGHT + abs_y) || (col >= 0)) {
- if ((particle->pos.y <= SCREEN_HEIGHT + abs_y) && (col >= 1)) {
- Sector::current()->add_object(new Bomb(particle->pos, LEFT));
- }
- int new_x = systemRandom.rand(int(virtual_width)) + int(abs_x);
- int new_y = 0;
- //FIXME: Don't move particles over solid tiles
- particle->pos.x = new_x;
- particle->pos.y = new_y;
- }
- }
-#endif
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef SUPERTUX_PARTICLESYSTEM_INTERACTIVE_H
-#define SUPERTUX_PARTICLESYSTEM_INTERACTIVE_H
-
-#include <vector>
-
-#include "video/surface.hpp"
-#include "game_object.hpp"
-#include "serializable.hpp"
-#include "sector.hpp"
-#include "math/vector.hpp"
-
-namespace lisp {
-class Lisp;
-}
-
-class DisplayManager;
-
-/**
- * This is an alternative class for particle systems. It is responsible for storing a
- * set of particles with each having an x- and y-coordinate the number of the
- * layer where it should be drawn and a texture.
- * This version of the particle system class doesn't use virtual screen coordinates,
- * but Interactive ones. Particle systems which need Interactive levels coordinates, such
- * as rain, should be implemented here.
- * Classes that implement a particle system should subclass from this class,
- * initialize particles in the constructor and move them in the simulate
- * function.
- */
-class ParticleSystem_Interactive : public GameObject
-{
-public:
- ParticleSystem_Interactive();
- virtual ~ParticleSystem_Interactive();
-
- virtual void draw(DrawingContext& context);
-
-protected:
- int z_pos;
-
- class Particle
- {
- public:
- virtual ~Particle()
- { }
-
- Vector pos;
- Surface* texture;
- };
-
- std::vector<Particle*> particles;
- float virtual_width, virtual_height;
- int collision(Particle* particle, Vector movement);
-};
-
-class RainParticleSystem : public ParticleSystem_Interactive, public Serializable
-{
-public:
- RainParticleSystem();
- virtual ~RainParticleSystem();
-
- void parse(const lisp::Lisp& lisp);
- void write(lisp::Writer& writer);
-
- virtual void update(float elapsed_time);
-
- std::string type() const
- { return "RainParticleSystem"; }
-
-private:
- class RainParticle : public Particle
- {
- public:
- float speed;
- };
-
- Surface* rainimages[2];
-};
-
-class CometParticleSystem : public ParticleSystem_Interactive, public Serializable
-{
-public:
- CometParticleSystem();
- virtual ~CometParticleSystem();
-
- void parse(const lisp::Lisp& lisp);
- void write(lisp::Writer& writer);
-
- virtual void update(float elapsed_time);
-
- std::string type() const
- { return "CometParticleSystem"; }
-
-private:
- class CometParticle : public Particle
- {
- public:
- float speed;
- };
-
- Surface* cometimages[2];
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux Path
-// Copyright (C) 2005 Philipp <balinor@pnxs.de>
-// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#include <config.h>
-
-#include "path.hpp"
-
-#include "lisp/writer.hpp"
-#include "lisp/lisp.hpp"
-#include "lisp/list_iterator.hpp"
-#include "object_factory.hpp"
-#include "log.hpp"
-
-#include <assert.h>
-#include <iostream>
-#include <stdexcept>
-#include <sstream>
-
-Path::Path()
-{
-}
-
-Path::~Path()
-{
-}
-
-void
-Path::read(const lisp::Lisp& reader)
-{
- lisp::ListIterator iter(&reader);
-
- mode = CIRCULAR;
- while(iter.next()) {
- if(iter.item() == "mode") {
- std::string mode_string;
- if(!iter.value()->get(mode_string))
- throw std::runtime_error("Pathmode not a string");
-
- if(mode_string == "oneshot")
- mode = ONE_SHOT;
- else if(mode_string == "pingpong")
- mode = PING_PONG;
- else if(mode_string == "circular")
- mode = CIRCULAR;
- else {
- std::ostringstream msg;
- msg << "Unknown pathmode '" << mode_string << "' found";
- throw std::runtime_error(msg.str());
- }
- continue;
- }
-
- if(iter.item() != "node") {
- log_warning << "unknown token '" << iter.item() << "' in Path nodes list. Ignored." << std::endl;
- continue;
- }
- const lisp::Lisp* node_lisp = iter.lisp();
-
- // each new node will inherit all values from the last one
- Node node;
- node.time = 1;
- if( (!node_lisp->get("x", node.position.x) ||
- !node_lisp->get("y", node.position.y)))
- throw std::runtime_error("Path node without x and y coordinate specified");
- node_lisp->get("time", node.time);
-
- if(node.time <= 0)
- throw std::runtime_error("Path node with non-positive time");
-
- nodes.push_back(node);
- }
-
- if (nodes.empty())
- throw std::runtime_error("Path with zero nodes");
-}
-
-void
-Path::write(lisp::Writer& writer)
-{
- writer.start_list("path");
-
- switch(mode) {
- case ONE_SHOT:
- writer.write_string("mode", "oneshot");
- break;
- case PING_PONG:
- writer.write_string("mode", "pingpong");
- break;
- case CIRCULAR:
- writer.write_string("mode", "circular");
- break;
- default:
- log_warning << "Don't know how to write mode " << (int) mode << " ?!?" << std::endl;
- break;
- }
-
- for (size_t i=0; i < nodes.size(); i++) {
- const Node& node = nodes[i];
-
- writer.start_list("node");
- writer.write_float("x", node.position.x);
- writer.write_float("y", node.position.y);
- writer.write_float("time", node.time);
-
- writer.end_list("node");
- }
-
- writer.end_list("path");
-}
-
-Vector
-Path::get_base() const
-{
- if(nodes.empty())
- return Vector(0, 0);
-
- return nodes[0].position;
-}
-
-int
-Path::get_nearest_node_no(Vector reference_point) const
-{
- int nearest_node_id = -1;
- float nearest_node_dist = 0;
- int id = 0;
- for (std::vector<Node>::const_iterator i = nodes.begin(); i != nodes.end(); i++, id++) {
- float dist = (i->position - reference_point).norm();
- if ((nearest_node_id == -1) || (dist < nearest_node_dist)) {
- nearest_node_id = id;
- nearest_node_dist = dist;
- }
- }
- return nearest_node_id;
-}
-
-int
-Path::get_farthest_node_no(Vector reference_point) const
-{
- int farthest_node_id = -1;
- float farthest_node_dist = 0;
- int id = 0;
- for (std::vector<Node>::const_iterator i = nodes.begin(); i != nodes.end(); i++, id++) {
- float dist = (i->position - reference_point).norm();
- if ((farthest_node_id == -1) || (dist > farthest_node_dist)) {
- farthest_node_id = id;
- farthest_node_dist = dist;
- }
- }
- return farthest_node_id;
-}
-
+++ /dev/null
-// $Id$
-//
-// SuperTux Path
-// Copyright (C) 2005 Philipp <balinor@pnxs.de>
-// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#ifndef __PATH_HPP__
-#define __PATH_HPP__
-
-#include <vector>
-#include "math/vector.hpp"
-#include "lisp/lisp.hpp"
-#include "serializable.hpp"
-
-class Path : public Serializable
-{
-public:
- Path();
- ~Path();
-
- void read(const lisp::Lisp& reader);
- void write(lisp::Writer& writer);
-
- Vector get_base() const;
-
- /**
- * Helper class that stores an individual node of a Path
- */
- class Node
- {
- public:
- Vector position; /**< the position of this node */
- float time; /**< time (in seconds) to get from this node to next node */
- };
-
- std::vector<Node> nodes;
-
- /**
- * returns Node index nearest to reference_point or -1 if not applicable
- */
- int get_nearest_node_no(Vector reference_point) const;
-
- /**
- * returns Node index farthest from reference_point or -1 if not applicable
- */
- int get_farthest_node_no(Vector reference_point) const;
-
-private:
- friend class PathWalker;
-
- enum WalkMode {
- // moves from first to last path node and stops
- ONE_SHOT,
- // moves from first to last node then in reverse order back to first
- PING_PONG,
- // moves from last node back to the first node
- CIRCULAR
- };
-
- WalkMode mode;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include <math.h>
-#include <assert.h>
-#include "path_walker.hpp"
-
-PathWalker::PathWalker(const Path* path, bool running)
- : path(path), running(running), current_node_nr(0), next_node_nr(0), stop_at_node_nr(running?-1:0), node_time(0),
- walking_speed(1.0)
-{
- node_mult = 1 / path->nodes[0].time;
- next_node_nr = path->nodes.size() > 1 ? 1 : 0;
-}
-
-PathWalker::~PathWalker()
-{
-}
-
-Vector
-PathWalker::advance(float elapsed_time)
-{
- if (!running) return path->nodes[current_node_nr].position;
-
- assert(elapsed_time >= 0);
-
- elapsed_time *= fabsf(walking_speed);
-
- const Path::Node* current_node = & (path->nodes[current_node_nr]);
- while(node_time + elapsed_time * node_mult >= 1) {
- elapsed_time -= (1 - node_time) / node_mult;
-
- if(walking_speed > 0) {
- advance_node();
- } else if(walking_speed < 0) {
- goback_node();
- }
-
- current_node = & (path->nodes[current_node_nr]);
- node_time = 0;
- if(walking_speed > 0) {
- node_mult = 1 / current_node->time;
- } else {
- node_mult = 1 / path->nodes[next_node_nr].time;
- }
- }
-
- const Path::Node* next_node = & (path->nodes[next_node_nr]);
- node_time += elapsed_time * node_mult;
-
- Vector new_pos = current_node->position +
- (next_node->position - current_node->position) * node_time;
-
- return new_pos;
-}
-
-void
-PathWalker::goto_node(int node_no)
-{
- if (node_no == stop_at_node_nr) return;
- running = true;
- stop_at_node_nr = node_no;
-}
-
-void
-PathWalker::start_moving()
-{
- running = true;
- stop_at_node_nr = -1;
-}
-
-void
-PathWalker::stop_moving()
-{
- stop_at_node_nr = next_node_nr;
-}
-
-
-void
-PathWalker::advance_node()
-{
- current_node_nr = next_node_nr;
- if (static_cast<int>(current_node_nr) == stop_at_node_nr) running = false;
-
- if(next_node_nr + 1 < path->nodes.size()) {
- next_node_nr++;
- return;
- }
-
- switch(path->mode) {
- case Path::ONE_SHOT:
- next_node_nr = path->nodes.size() - 1;
- walking_speed = 0;
- return;
-
- case Path::PING_PONG:
- walking_speed = -walking_speed;
- next_node_nr = path->nodes.size() > 1 ? path->nodes.size() - 2 : 0;
- return;
-
- case Path::CIRCULAR:
- next_node_nr = 0;
- return;
- }
-
- // we shouldn't get here
- assert(false);
- next_node_nr = path->nodes.size() - 1;
- walking_speed = 0;
-}
-
-void
-PathWalker::goback_node()
-{
- current_node_nr = next_node_nr;
-
- if(next_node_nr > 0) {
- next_node_nr--;
- return;
- }
-
- switch(path->mode) {
- case Path::PING_PONG:
- walking_speed = -walking_speed;
- next_node_nr = path->nodes.size() > 1 ? 1 : 0;
- return;
- default:
- break;
- }
-
- assert(false);
- next_node_nr = 0;
- walking_speed = 0;
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __PATH_WALKER_HPP__
-#define __PATH_WALKER_HPP__
-
-#include "path.hpp"
-#include "math/vector.hpp"
-#include "game_object.hpp"
-#include "lisp/lisp.hpp"
-#include "serializable.hpp"
-
-/**
- * A walker that travels along a path
- */
-class PathWalker
-{
-public:
- PathWalker(const Path* path, bool running = true);
- virtual ~PathWalker();
-
- /**
- * advanves the path walker on the path and returns the position delta
- * to the last position
- */
- virtual Vector advance(float elapsed_time);
-
- /** advance until at given node, then stop */
- void goto_node(int node_no);
-
- /** start advancing automatically */
- void start_moving();
-
- /** stop advancing automatically */
- void stop_moving();
-
- /** returns true if PathWalker is currently moving */
- bool is_moving() {
- return running;
- }
-
- const Path* path;
-
-private:
- void advance_node();
- void goback_node();
-
- /**
- * set to false to immediately stop advancing
- */
- bool running;
-
- size_t current_node_nr;
- size_t next_node_nr;
-
- /**
- * stop advancing automatically when this node is reached
- */
- int stop_at_node_nr;
-
- /**
- * the position between the current node and the next node as fraction
- * between 0 and 1
- */
- float node_time;
- float node_mult;
-
- float walking_speed;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include "platform.hpp"
-
-#include <stdexcept>
-#include "log.hpp"
-#include "video/drawing_context.hpp"
-#include "resources.hpp"
-#include "player.hpp"
-#include "path.hpp"
-#include "path_walker.hpp"
-#include "sprite/sprite.hpp"
-#include "lisp/lisp.hpp"
-#include "object_factory.hpp"
-#include "scripting/platform.hpp"
-#include "scripting/squirrel_util.hpp"
-#include "sector.hpp"
-
-Platform::Platform(const lisp::Lisp& reader)
- : MovingSprite(reader, Vector(0,0), LAYER_OBJECTS, COLGROUP_STATIC),
- speed(Vector(0,0)),
- automatic(false), player_contact(false), last_player_contact(false)
-{
- bool running = true;
- reader.get("name", name);
- reader.get("running", running);
- if ((name == "") && (!running)) automatic=true;
- const lisp::Lisp* pathLisp = reader.get_lisp("path");
- if(pathLisp == NULL)
- throw std::runtime_error("No path specified for platform");
- path.reset(new Path());
- path->read(*pathLisp);
- walker.reset(new PathWalker(path.get(), running));
- bbox.set_pos(path->get_base());
-}
-
-Platform::Platform(const Platform& other)
- : MovingSprite(other), ScriptInterface(other),
- speed(other.speed),
- automatic(other.automatic), player_contact(false), last_player_contact(false)
-{
- name = other.name;
- path.reset(new Path(*other.path));
- walker.reset(new PathWalker(*other.walker));
- walker->path = &*path;
-}
-
-HitResponse
-Platform::collision(GameObject& other, const CollisionHit& )
-{
- if (dynamic_cast<Player*>(&other)) player_contact = true;
- return FORCE_MOVE;
-}
-
-void
-Platform::update(float elapsed_time)
-{
- // check if Platform should automatically pick a destination
- if (automatic) {
-
- if (!player_contact && !walker->is_moving()) {
- // Player doesn't touch platform and Platform is not moving
-
- // Travel to node nearest to nearest player
- // FIXME: does not really use nearest player
- Player* player = 0;
- std::vector<Player*> players = Sector::current()->get_players();
- for (std::vector<Player*>::iterator playerIter = players.begin(); playerIter != players.end(); ++playerIter) {
- player = *playerIter;
- }
- if (player) {
- int nearest_node_id = path->get_nearest_node_no(player->get_bbox().p2);
- if (nearest_node_id != -1) {
- goto_node(nearest_node_id);
- }
- }
- }
-
- if (player_contact && !last_player_contact && !walker->is_moving()) {
- // Player touched platform, didn't touch last frame and Platform is not moving
-
- // Travel to node farthest from current position
- int farthest_node_id = path->get_farthest_node_no(get_pos());
- if (farthest_node_id != -1) {
- goto_node(farthest_node_id);
- }
- }
-
- // Clear player_contact flag set by collision() method
- last_player_contact = player_contact;
- player_contact = false;
- }
-
- movement = walker->advance(elapsed_time) - get_pos();
- speed = movement / elapsed_time;
-}
-
-void
-Platform::goto_node(int node_no)
-{
- walker->goto_node(node_no);
-}
-
-void
-Platform::start_moving()
-{
- walker->start_moving();
-}
-
-void
-Platform::stop_moving()
-{
- walker->stop_moving();
-}
-
-void
-Platform::expose(HSQUIRRELVM vm, SQInteger table_idx)
-{
- if (name.empty()) return;
- Scripting::Platform* interface = new Scripting::Platform(this);
- expose_object(vm, table_idx, interface, name, true);
-}
-
-void
-Platform::unexpose(HSQUIRRELVM vm, SQInteger table_idx)
-{
- if (name.empty()) return;
- Scripting::unexpose_object(vm, table_idx, name);
-}
-
-IMPLEMENT_FACTORY(Platform, "platform");
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __PLATFORM_H__
-#define __PLATFORM_H__
-
-#include <memory>
-#include <string>
-#include "object/moving_sprite.hpp"
-#include "object/path.hpp"
-#include "object/path_walker.hpp"
-#include "script_interface.hpp"
-
-/**
- * This class is the base class for platforms that tux can stand on
- */
-class Platform : public MovingSprite, public ScriptInterface
-{
-public:
- Platform(const lisp::Lisp& reader);
- Platform(const Platform& platform);
- virtual Platform* clone() const { return new Platform(*this); }
-
- virtual HitResponse collision(GameObject& other, const CollisionHit& hit);
- virtual void update(float elapsed_time);
-
- const Vector& get_speed() const
- {
- return speed;
- }
-
- /**
- * @name Scriptable Methods
- * @{
- */
-
- /** Move platform until at given node, then stop */
- void goto_node(int node_no);
-
- /** Start moving platform */
- void start_moving();
-
- /** Stop platform at next node */
- void stop_moving();
-
- /**
- * @}
- */
-
- virtual void expose(HSQUIRRELVM vm, SQInteger table_idx);
- virtual void unexpose(HSQUIRRELVM vm, SQInteger table_idx);
-
- Path& get_path() {
- return *path.get();
- }
-
-private:
- std::auto_ptr<Path> path;
- std::auto_ptr<PathWalker> walker;
-
- Vector speed;
-
- bool automatic; /**< true if Platform will automatically pick a destination based on collisions and current Player position */
- bool player_contact; /**< true if a Player touched the Platform during the last round of collision detections */
- bool last_player_contact; /**< true if a Player touched the Platform during the round before the last round of collision detections */
-
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#include <config.h>
-
-#include <typeinfo>
-#include <cmath>
-#include <iostream>
-#include <cassert>
-
-#include "gettext.hpp"
-#include "sprite/sprite_manager.hpp"
-#include "audio/sound_manager.hpp"
-#include "player.hpp"
-#include "tile.hpp"
-#include "sprite/sprite.hpp"
-#include "sector.hpp"
-#include "resources.hpp"
-#include "statistics.hpp"
-#include "game_session.hpp"
-#include "object/tilemap.hpp"
-#include "object/camera.hpp"
-#include "object/particles.hpp"
-#include "object/portable.hpp"
-#include "object/bullet.hpp"
-#include "trigger/trigger_base.hpp"
-#include "control/joystickkeyboardcontroller.hpp"
-#include "scripting/squirrel_util.hpp"
-#include "main.hpp"
-#include "platform.hpp"
-#include "badguy/badguy.hpp"
-#include "player_status.hpp"
-#include "log.hpp"
-#include "falling_coin.hpp"
-#include "random_generator.hpp"
-#include "object/sprite_particle.hpp"
-#include "trigger/climbable.hpp"
-
-//#define SWIMMING
-
-static const int TILES_FOR_BUTTJUMP = 3;
-static const float SHOOTING_TIME = .150f;
-/// time before idle animation starts
-static const float IDLE_TIME = 2.5f;
-
-/** acceleration in horizontal direction when walking
- * (all acceleratiosn are in pixel/s^2) */
-static const float WALK_ACCELERATION_X = 300;
-/** acceleration in horizontal direction when running */
-static const float RUN_ACCELERATION_X = 400;
-/** acceleration when skidding */
-static const float SKID_XM = 200;
-/** time of skidding in seconds */
-static const float SKID_TIME = .3f;
-/** maximum walk velocity (pixel/s) */
-static const float MAX_WALK_XM = 230;
-/** maximum run velcoity (pixel/s) */
-static const float MAX_RUN_XM = 320;
-/** maximum horizontal climb velocity */
-static const float MAX_CLIMB_XM = 48;
-/** maximum vertical climb velocity */
-static const float MAX_CLIMB_YM = 128;
-/** instant velocity when tux starts to walk */
-static const float WALK_SPEED = 100;
-
-/** time of the kick (kicking mriceblock) animation */
-static const float KICK_TIME = .3f;
-/** time of tux cheering (currently unused) */
-static const float CHEER_TIME = 1.0f;
-
-/** if Tux cannot unduck for this long, he will get hurt */
-static const float UNDUCK_HURT_TIME = 0.25f;
-
-// growing animation
-Surface* growingtux_left[GROWING_FRAMES];
-Surface* growingtux_right[GROWING_FRAMES];
-
-Surface* tux_life = 0;
-
-TuxBodyParts* small_tux = 0;
-TuxBodyParts* big_tux = 0;
-TuxBodyParts* fire_tux = 0;
-TuxBodyParts* ice_tux = 0;
-
-namespace{
- bool no_water = true;
-}
-void
-TuxBodyParts::set_action(std::string action, int loops)
-{
- if(head != NULL)
- head->set_action(action, loops);
- if(body != NULL)
- body->set_action(action, loops);
- if(arms != NULL)
- arms->set_action(action, loops);
- if(feet != NULL)
- feet->set_action(action, loops);
-}
-
-void
-TuxBodyParts::draw(DrawingContext& context, const Vector& pos, int layer, Portable* grabbed_object)
-{
- if(head != NULL)
- head->draw(context, pos, layer-2);
- if(body != NULL)
- body->draw(context, pos, layer-4);
- if(arms != NULL)
- arms->draw(context, pos, layer-1 + (grabbed_object?10:0));
- if(feet != NULL)
- feet->draw(context, pos, layer-3);
-}
-
-Player::Player(PlayerStatus* _player_status, const std::string& name)
- : player_status(_player_status), grabbed_object(NULL), ghost_mode(false), climbing(0)
-{
- this->name = name;
- controller = main_controller;
- smalltux_gameover = sprite_manager->create("images/creatures/tux_small/smalltux-gameover.sprite");
- smalltux_star = sprite_manager->create("images/creatures/tux_small/smalltux-star.sprite");
- bigtux_star = sprite_manager->create("images/creatures/tux_big/bigtux-star.sprite");
- airarrow.reset(new Surface("images/engine/hud/airarrow.png"));
-
- sound_manager->preload("sounds/bigjump.wav");
- sound_manager->preload("sounds/jump.wav");
- sound_manager->preload("sounds/hurt.wav");
- sound_manager->preload("sounds/skid.wav");
- sound_manager->preload("sounds/flip.wav");
- sound_manager->preload("sounds/invincible.wav");
- sound_manager->preload("sounds/splash.ogg");
-
- init();
-}
-
-Player::~Player()
-{
- if (climbing) stop_climbing(*climbing);
- delete smalltux_gameover;
- delete smalltux_star;
- delete bigtux_star;
-}
-
-void
-Player::init()
-{
- if(is_big())
- set_size(31.8f, 62.8f);
- else
- set_size(31.8f, 30.8f);
-
- dir = RIGHT;
- old_dir = dir;
- duck = false;
- dead = false;
-
- dying = false;
- peeking = AUTO;
- last_ground_y = 0;
- fall_mode = ON_GROUND;
- jumping = false;
- can_jump = true;
- butt_jump = false;
- deactivated = false;
- backflipping = false;
- backflip_direction = 0;
- visible = true;
- swimming = false;
- speedlimit = 0; //no special limit
-
- on_ground_flag = false;
- grabbed_object = NULL;
-
- climbing = 0;
-
- physic.reset();
-}
-
-void
-Player::expose(HSQUIRRELVM vm, SQInteger table_idx)
-{
- if (name.empty())
- return;
-
- Scripting::expose_object(vm, table_idx, dynamic_cast<Scripting::Player *>(this), name, false);
-}
-
-void
-Player::unexpose(HSQUIRRELVM vm, SQInteger table_idx)
-{
- if (name.empty())
- return;
-
- Scripting::unexpose_object(vm, table_idx, name);
-}
-
-float
-Player::get_speedlimit()
-{
- return speedlimit;
-}
-
-void
-Player::set_speedlimit(float newlimit)
-{
- speedlimit=newlimit;
-}
-
-void
-Player::set_controller(Controller* controller)
-{
- this->controller = controller;
-}
-
-bool
-Player::adjust_height(float new_height)
-{
- Rect bbox2 = bbox;
- bbox2.move(Vector(0, bbox.get_height() - new_height));
- bbox2.set_height(new_height);
-
- if(new_height > bbox.get_height()) {
- Rect additional_space = bbox2;
- additional_space.set_height(new_height - bbox.get_height());
- if(!Sector::current()->is_free_of_statics(additional_space, this, true))
- return false;
- }
-
- // adjust bbox accordingly
- // note that we use members of moving_object for this, so we can run this during CD, too
- set_pos(bbox2.p1);
- set_size(bbox2.get_width(), bbox2.get_height());
- return true;
-}
-
-void
-Player::trigger_sequence(std::string sequence_name)
-{
- if (climbing) stop_climbing(*climbing);
- GameSession::current()->start_sequence(sequence_name);
-}
-
-void
-Player::update(float elapsed_time)
-{
- if( no_water ){
- swimming = false;
- }
- no_water = true;
-
- if(dying && dying_timer.check()) {
- dead = true;
- return;
- }
-
- if(!dying && !deactivated)
- handle_input();
-
- // handle_input() calls apply_friction() when Tux is not walking, so we'll have to do this ourselves
- if (deactivated)
- apply_friction();
-
- // extend/shrink tux collision rectangle so that we fall through/walk over 1
- // tile holes
- if(fabsf(physic.get_velocity_x()) > MAX_WALK_XM) {
- set_width(34);
- } else {
- set_width(31.8f);
- }
-
- // on downward slopes, adjust vertical velocity so tux walks smoothly down
- if (on_ground()) {
- if(floor_normal.y != 0) {
- if ((floor_normal.x * physic.get_velocity_x()) >= 0) {
- physic.set_velocity_y(250);
- }
- }
- }
-
- // handle backflipping
- if (backflipping) {
- //prevent player from changing direction when backflipping
- dir = (backflip_direction == 1) ? LEFT : RIGHT;
- if (backflip_timer.started()) physic.set_velocity_x(100 * backflip_direction);
- }
-
- // set fall mode...
- if(on_ground()) {
- fall_mode = ON_GROUND;
- last_ground_y = get_pos().y;
- } else {
- if(get_pos().y > last_ground_y)
- fall_mode = FALLING;
- else if(fall_mode == ON_GROUND)
- fall_mode = JUMPING;
- }
-
- // check if we landed
- if(on_ground()) {
- jumping = false;
- if (backflipping && (!backflip_timer.started())) {
- backflipping = false;
- backflip_direction = 0;
-
- // if controls are currently deactivated, we take care of standing up ourselves
- if (deactivated)
- do_standup();
- }
- }
-
- // calculate movement for this frame
- movement = physic.get_movement(elapsed_time);
-
- if(grabbed_object != NULL && !dying) {
- Vector pos = get_pos() +
- Vector(dir == LEFT ? -16 : 16, get_bbox().get_height()*0.66666 - 32);
- grabbed_object->grab(*this, pos, dir);
- }
-
- if(grabbed_object != NULL && dying){
- grabbed_object->ungrab(*this, dir);
- grabbed_object = NULL;
- }
-
- on_ground_flag = false;
-
- // when invincible, spawn particles
- if (invincible_timer.started() && !dying)
- {
- if (systemRandom.rand(0, 2) == 0) {
- float px = systemRandom.randf(bbox.p1.x+0, bbox.p2.x-0);
- float py = systemRandom.randf(bbox.p1.y+0, bbox.p2.y-0);
- Vector ppos = Vector(px, py);
- Vector pspeed = Vector(0, 0);
- Vector paccel = Vector(0, 0);
- // draw bright sparkle when there is lots of time left, dark sparkle when invincibility is about to end
- if (invincible_timer.get_timeleft() > TUX_INVINCIBLE_TIME_WARNING) {
- // make every other a longer sparkle to make trail a bit fuzzy
- if (size_t(game_time*20)%2) {
- Sector::current()->add_object(new SpriteParticle("images/objects/particles/sparkle.sprite", "small", ppos, ANCHOR_MIDDLE, pspeed, paccel, LAYER_OBJECTS+1+5));
- } else {
- Sector::current()->add_object(new SpriteParticle("images/objects/particles/sparkle.sprite", "medium", ppos, ANCHOR_MIDDLE, pspeed, paccel, LAYER_OBJECTS+1+5));
- }
- } else {
- Sector::current()->add_object(new SpriteParticle("images/objects/particles/sparkle.sprite", "dark", ppos, ANCHOR_MIDDLE, pspeed, paccel, LAYER_OBJECTS+1+5));
- }
- }
- }
-
-}
-
-bool
-Player::on_ground()
-{
- return on_ground_flag;
-}
-
-bool
-Player::is_big()
-{
- if(player_status->bonus == NO_BONUS)
- return false;
-
- return true;
-}
-
-void
-Player::apply_friction()
-{
- if ((on_ground()) && (fabs(physic.get_velocity_x()) < WALK_SPEED)) {
- physic.set_velocity_x(0);
- physic.set_acceleration_x(0);
- } else if(physic.get_velocity_x() < 0) {
- physic.set_acceleration_x(WALK_ACCELERATION_X * 1.5);
- } else if(physic.get_velocity_x() > 0) {
- physic.set_acceleration_x(WALK_ACCELERATION_X * -1.5);
- }
-}
-
-void
-Player::handle_horizontal_input()
-{
- float vx = physic.get_velocity_x();
- float vy = physic.get_velocity_y();
- float ax = physic.get_acceleration_x();
- float ay = physic.get_acceleration_y();
-
- float dirsign = 0;
- if(!duck || physic.get_velocity_y() != 0) {
- if(controller->hold(Controller::LEFT) && !controller->hold(Controller::RIGHT)) {
- old_dir = dir;
- dir = LEFT;
- dirsign = -1;
- } else if(!controller->hold(Controller::LEFT)
- && controller->hold(Controller::RIGHT)) {
- old_dir = dir;
- dir = RIGHT;
- dirsign = 1;
- }
- }
-
- // do not run if action key is pressed or we're holding something
- // so tux can only walk while shooting
- if ( controller->hold(Controller::ACTION) || grabbed_object ) {
- ax = dirsign * WALK_ACCELERATION_X;
- // limit speed
- if(vx >= MAX_WALK_XM && dirsign > 0) {
- vx = MAX_WALK_XM;
- ax = 0;
- } else if(vx <= -MAX_WALK_XM && dirsign < 0) {
- vx = -MAX_WALK_XM;
- ax = 0;
- }
- } else {
- if( vx * dirsign < MAX_WALK_XM ) {
- ax = dirsign * WALK_ACCELERATION_X;
- } else {
- ax = dirsign * RUN_ACCELERATION_X;
- }
- // limit speed
- if(vx >= MAX_RUN_XM && dirsign > 0) {
- vx = MAX_RUN_XM;
- ax = 0;
- } else if(vx <= -MAX_RUN_XM && dirsign < 0) {
- vx = -MAX_RUN_XM;
- ax = 0;
- }
- }
-
- // we can reach WALK_SPEED without any acceleration
- if(dirsign != 0 && fabs(vx) < WALK_SPEED) {
- vx = dirsign * WALK_SPEED;
- }
-
- //Check speedlimit.
- if( speedlimit > 0 && vx * dirsign >= speedlimit ) {
- vx = dirsign * speedlimit;
- ax = 0;
- }
-
- // changing directions?
- if(on_ground() && ((vx < 0 && dirsign >0) || (vx>0 && dirsign<0))) {
- // let's skid!
- if(fabs(vx)>SKID_XM && !skidding_timer.started()) {
- skidding_timer.start(SKID_TIME);
- sound_manager->play("sounds/skid.wav");
- // dust some particles
- Sector::current()->add_object(
- new Particles(
- Vector(dir == RIGHT ? get_bbox().p2.x : get_bbox().p1.x, get_bbox().p2.y),
- dir == RIGHT ? 270+20 : 90-40, dir == RIGHT ? 270+40 : 90-20,
- Vector(280, -260), Vector(0, 300), 3, Color(.4f, .4f, .4f), 3, .8f,
- LAYER_OBJECTS+1));
-
- ax *= 2.5;
- } else {
- ax *= 2;
- }
- }
-
- physic.set_velocity(vx, vy);
- physic.set_acceleration(ax, ay);
-
- // we get slower when not pressing any keys
- if(dirsign == 0) {
- apply_friction();
- }
-
-}
-
-void
-Player::do_cheer()
-{
- do_duck();
- do_backflip();
- do_standup();
-}
-
-void
-Player::do_duck() {
- if (duck)
- return;
- if (!is_big())
- return;
-
- if (physic.get_velocity_y() != 0)
- return;
- if (!on_ground())
- return;
-
- if (adjust_height(31.8f)) {
- duck = true;
- unduck_hurt_timer.stop();
- } else {
- // FIXME: what now?
- }
-}
-
-void
-Player::do_standup() {
- if (!duck)
- return;
- if (!is_big())
- return;
- if (backflipping)
- return;
-
- if (adjust_height(63.8f)) {
- duck = false;
- unduck_hurt_timer.stop();
- } else {
- // if timer is not already running, start it.
- if (unduck_hurt_timer.get_period() == 0) {
- unduck_hurt_timer.start(UNDUCK_HURT_TIME);
- }
- else if (unduck_hurt_timer.check()) {
- kill(false);
- }
- }
-
-}
-
-void
-Player::do_backflip() {
- if (!duck)
- return;
- if (!on_ground())
- return;
-
- backflip_direction = (dir == LEFT)?(+1):(-1);
- backflipping = true;
- do_jump(-580);
- sound_manager->play("sounds/flip.wav");
- backflip_timer.start(0.15f);
-}
-
-void
-Player::do_jump(float yspeed) {
- if (!on_ground())
- return;
-
- physic.set_velocity_y(yspeed);
- //bbox.move(Vector(0, -1));
- jumping = true;
- on_ground_flag = false;
- can_jump = false;
-
- // play sound
- if (is_big()) {
- sound_manager->play("sounds/bigjump.wav");
- } else {
- sound_manager->play("sounds/jump.wav");
- }
-}
-
-void
-Player::handle_vertical_input()
-{
- // Press jump key
- if(controller->pressed(Controller::JUMP) && (can_jump)) {
- if (duck) {
- // when running, only jump a little bit; else do a backflip
- if ((physic.get_velocity_x() != 0) || (controller->hold(Controller::LEFT)) || (controller->hold(Controller::RIGHT))) do_jump(-300); else do_backflip();
- } else {
- // jump a bit higher if we are running; else do a normal jump
- if (fabs(physic.get_velocity_x()) > MAX_WALK_XM) do_jump(-580); else do_jump(-520);
- }
- }
- // Let go of jump key
- else if(!controller->hold(Controller::JUMP)) {
- if (!backflipping && jumping && physic.get_velocity_y() < 0) {
- jumping = false;
- physic.set_velocity_y(0);
- }
- }
-
- /* In case the player has pressed Down while in a certain range of air,
- enable butt jump action */
- if (controller->hold(Controller::DOWN) && !butt_jump && !duck && is_big() && jumping) {
- butt_jump = true;
- }
-
- /* When Down is not held anymore, disable butt jump */
- if(butt_jump && !controller->hold(Controller::DOWN))
- butt_jump = false;
-
- // swimming
- physic.set_acceleration_y(0);
-#ifdef SWIMMING
- if (swimming) {
- if (controller->hold(Controller::UP) || controller->hold(Controller::JUMP))
- physic.set_acceleration_y(-2000);
- physic.set_velocity_y(physic.get_velocity_y() * 0.94);
- }
-#endif
-}
-
-void
-Player::handle_input()
-{
- if (ghost_mode) {
- handle_input_ghost();
- return;
- }
- if (climbing) {
- handle_input_climbing();
- return;
- }
-
- /* Peeking */
- if( controller->released( Controller::PEEK_LEFT ) ) {
- peeking = AUTO;
- }
- if( controller->released( Controller::PEEK_RIGHT ) ) {
- peeking = AUTO;
- }
- if( controller->released( Controller::UP ) ) {
- peeking = AUTO;
- }
- if( controller->released( Controller::DOWN ) ) {
- peeking = AUTO;
- }
- if( controller->pressed( Controller::PEEK_LEFT ) ) {
- peeking = LEFT;
- }
- if( controller->pressed( Controller::PEEK_RIGHT ) ) {
- peeking = RIGHT;
- }
- if( controller->pressed( Controller::UP ) ) {
- peeking = UP;
- }
- if( controller->pressed( Controller::DOWN ) ) {
- peeking = DOWN;
- }
-
- /* Handle horizontal movement: */
- if (!backflipping) handle_horizontal_input();
-
- /* Jump/jumping? */
- if (on_ground() && !controller->hold(Controller::JUMP))
- can_jump = true;
-
- /* Handle vertical movement: */
- handle_vertical_input();
-
- /* Shoot! */
- if (controller->pressed(Controller::ACTION) && (player_status->bonus == FIRE_BONUS || player_status->bonus == ICE_BONUS)) {
- if(Sector::current()->add_bullet(
- get_pos() + ((dir == LEFT)? Vector(0, bbox.get_height()/2)
- : Vector(32, bbox.get_height()/2)),
- physic.get_velocity_x(), dir))
- shooting_timer.start(SHOOTING_TIME);
- }
-
- /* Duck or Standup! */
- if (controller->hold(Controller::DOWN)) {
- do_duck();
- } else {
- do_standup();
- }
-
- /* grabbing */
- try_grab();
-
- if(!controller->hold(Controller::ACTION) && grabbed_object) {
- // move the grabbed object a bit away from tux
- Vector pos = get_pos() +
- Vector(dir == LEFT ? -bbox.get_width()-1 : bbox.get_width()+1,
- bbox.get_height()*0.66666 - 32);
- Rect dest(pos, pos + Vector(32, 32));
- if(Sector::current()->is_free_of_movingstatics(dest)) {
- MovingObject* moving_object = dynamic_cast<MovingObject*> (grabbed_object);
- if(moving_object) {
- moving_object->set_pos(pos);
- } else {
- log_debug << "Non MovingObject grabbed?!?" << std::endl;
- }
- if(controller->hold(Controller::UP)) {
- grabbed_object->ungrab(*this, UP);
- } else {
- grabbed_object->ungrab(*this, dir);
- }
- grabbed_object = NULL;
- }
- }
-}
-
-void
-Player::try_grab()
-{
- if(controller->hold(Controller::ACTION) && !grabbed_object
- && !duck) {
- Sector* sector = Sector::current();
- Vector pos;
- if(dir == LEFT) {
- pos = Vector(bbox.get_left() - 5, bbox.get_bottom() - 16);
- } else {
- pos = Vector(bbox.get_right() + 5, bbox.get_bottom() - 16);
- }
-
- for(Sector::Portables::iterator i = sector->portables.begin();
- i != sector->portables.end(); ++i) {
- Portable* portable = *i;
- if(!portable->is_portable())
- continue;
-
- // make sure the Portable is a MovingObject
- MovingObject* moving_object = dynamic_cast<MovingObject*> (portable);
- assert(moving_object);
- if(moving_object == NULL)
- continue;
-
- // make sure the Portable isn't currently non-solid
- if(moving_object->get_group() == COLGROUP_DISABLED) continue;
-
- // check if we are within reach
- if(moving_object->get_bbox().contains(pos)) {
- if (climbing) stop_climbing(*climbing);
- grabbed_object = portable;
- grabbed_object->grab(*this, get_pos(), dir);
- break;
- }
- }
- }
-}
-
-void
-Player::handle_input_ghost()
-{
- float vx = 0;
- float vy = 0;
- if (controller->hold(Controller::LEFT)) {
- dir = LEFT;
- vx -= MAX_RUN_XM * 2;
- }
- if (controller->hold(Controller::RIGHT)) {
- dir = RIGHT;
- vx += MAX_RUN_XM * 2;
- }
- if ((controller->hold(Controller::UP)) || (controller->hold(Controller::JUMP))) {
- vy -= MAX_RUN_XM * 2;
- }
- if (controller->hold(Controller::DOWN)) {
- vy += MAX_RUN_XM * 2;
- }
- if (controller->hold(Controller::ACTION)) {
- set_ghost_mode(false);
- }
- physic.set_velocity(vx, vy);
- physic.set_acceleration(0, 0);
-}
-
-void
-Player::add_coins(int count)
-{
- player_status->add_coins(count);
-}
-
-int
-Player::get_coins()
-{
- return player_status->coins;
-}
-
-bool
-Player::add_bonus(const std::string& bonustype)
-{
- BonusType type = NO_BONUS;
-
- if(bonustype == "grow") {
- type = GROWUP_BONUS;
- } else if(bonustype == "fireflower") {
- type = FIRE_BONUS;
- } else if(bonustype == "iceflower") {
- type = ICE_BONUS;
- } else if(bonustype == "none") {
- type = NO_BONUS;
- } else {
- std::ostringstream msg;
- msg << "Unknown bonus type " << bonustype;
- throw std::runtime_error(msg.str());
- }
-
- return add_bonus(type);
-}
-
-bool
-Player::add_bonus(BonusType type, bool animate)
-{
- // always ignore NO_BONUS
- if (type == NO_BONUS) {
- return true;
- }
-
- // ignore GROWUP_BONUS if we're already big
- if (type == GROWUP_BONUS) {
- if (player_status->bonus == GROWUP_BONUS)
- return true;
- if (player_status->bonus == FIRE_BONUS)
- return true;
- if (player_status->bonus == ICE_BONUS)
- return true;
- }
-
- return set_bonus(type, animate);
-}
-
-bool
-Player::set_bonus(BonusType type, bool animate)
-{
- if(player_status->bonus == NO_BONUS) {
- if (!adjust_height(62.8f)) {
- printf("can't adjust\n");
- return false;
- }
- if(animate)
- growing_timer.start(GROWING_TIME);
- if (climbing) stop_climbing(*climbing);
- }
-
- if ((type == NO_BONUS) || (type == GROWUP_BONUS)) {
- if ((player_status->bonus == FIRE_BONUS) && (animate)) {
- // visually lose helmet
- Vector ppos = Vector((bbox.p1.x + bbox.p2.x) / 2, bbox.p1.y);
- Vector pspeed = Vector(((dir==LEFT) ? +100 : -100), -300);
- Vector paccel = Vector(0, 1000);
- std::string action = (dir==LEFT)?"left":"right";
- Sector::current()->add_object(new SpriteParticle("images/objects/particles/firetux-helmet.sprite", action, ppos, ANCHOR_TOP, pspeed, paccel, LAYER_OBJECTS-1));
- if (climbing) stop_climbing(*climbing);
- }
- if ((player_status->bonus == ICE_BONUS) && (animate)) {
- // visually lose cap
- Vector ppos = Vector((bbox.p1.x + bbox.p2.x) / 2, bbox.p1.y);
- Vector pspeed = Vector(((dir==LEFT) ? +100 : -100), -300);
- Vector paccel = Vector(0, 1000);
- std::string action = (dir==LEFT)?"left":"right";
- Sector::current()->add_object(new SpriteParticle("images/objects/particles/icetux-cap.sprite", action, ppos, ANCHOR_TOP, pspeed, paccel, LAYER_OBJECTS-1));
- if (climbing) stop_climbing(*climbing);
- }
- player_status->max_fire_bullets = 0;
- player_status->max_ice_bullets = 0;
- }
- if (type == FIRE_BONUS) player_status->max_fire_bullets++;
- if (type == ICE_BONUS) player_status->max_ice_bullets++;
-
- player_status->bonus = type;
- return true;
-}
-
-void
-Player::set_visible(bool visible)
-{
- this->visible = visible;
- if( visible )
- set_group(COLGROUP_MOVING);
- else
- set_group(COLGROUP_DISABLED);
-}
-
-bool
-Player::get_visible()
-{
- return visible;
-}
-
-void
-Player::kick()
-{
- kick_timer.start(KICK_TIME);
-}
-
-void
-Player::draw(DrawingContext& context)
-{
- if(!visible)
- return;
-
- // if Tux is above camera, draw little "air arrow" to show where he is x-wise
- if (Sector::current() && Sector::current()->camera && (get_bbox().p2.y - 16 < Sector::current()->camera->get_translation().y)) {
- float px = get_pos().x + (get_bbox().p2.x - get_bbox().p1.x - airarrow.get()->get_width()) / 2;
- float py = Sector::current()->camera->get_translation().y;
- py += std::min(((py - (get_bbox().p2.y + 16)) / 4), 16.0f);
- context.draw_surface(airarrow.get(), Vector(px, py), LAYER_HUD - 1);
- }
-
- TuxBodyParts* tux_body;
-
- if (player_status->bonus == GROWUP_BONUS)
- tux_body = big_tux;
- else if (player_status->bonus == FIRE_BONUS)
- tux_body = fire_tux;
- else if (player_status->bonus == ICE_BONUS)
- tux_body = ice_tux;
- else
- tux_body = small_tux;
-
- int layer = LAYER_OBJECTS + 1;
-
- /* Set Tux sprite action */
- if (climbing)
- {
- tux_body->set_action("skid-left");
- }
- else if (backflipping)
- {
- if(dir == LEFT)
- tux_body->set_action("backflip-left");
- else // dir == RIGHT
- tux_body->set_action("backflip-right");
- }
- else if (duck && is_big())
- {
- if(dir == LEFT)
- tux_body->set_action("duck-left");
- else // dir == RIGHT
- tux_body->set_action("duck-right");
- }
- else if (skidding_timer.started() && !skidding_timer.check())
- {
- if(dir == LEFT)
- tux_body->set_action("skid-left");
- else // dir == RIGHT
- tux_body->set_action("skid-right");
- }
- else if (kick_timer.started() && !kick_timer.check())
- {
- if(dir == LEFT)
- tux_body->set_action("kick-left");
- else // dir == RIGHT
- tux_body->set_action("kick-right");
- }
- else if (butt_jump && is_big())
- {
- if(dir == LEFT)
- tux_body->set_action("buttjump-left");
- else // dir == RIGHT
- tux_body->set_action("buttjump-right");
- }
- else if (!on_ground())
- {
- if(dir == LEFT)
- tux_body->set_action("jump-left");
- else // dir == RIGHT
- tux_body->set_action("jump-right");
- }
- else
- {
- if (fabsf(physic.get_velocity_x()) < 1.0f) // standing
- {
- if(dir == LEFT)
- tux_body->set_action("stand-left");
- else // dir == RIGHT
- tux_body->set_action("stand-right");
- }
- else // moving
- {
- if(dir == LEFT)
- tux_body->set_action("walk-left");
- else // dir == RIGHT
- tux_body->set_action("walk-right");
- }
- }
-
- if(idle_timer.check())
- {
- if(is_big())
- {
- if(dir == LEFT)
- tux_body->head->set_action("idle-left", 1);
- else // dir == RIGHT
- tux_body->head->set_action("idle-right", 1);
- }
-
- }
-
- // Tux is holding something
- if ((grabbed_object != 0 && physic.get_velocity_y() == 0) ||
- (shooting_timer.get_timeleft() > 0 && !shooting_timer.check()))
- {
- if (duck)
- {
- if(dir == LEFT)
- tux_body->arms->set_action("duck+grab-left");
- else // dir == RIGHT
- tux_body->arms->set_action("duck+grab-right");
- }
- else
- {
- if(dir == LEFT)
- tux_body->arms->set_action("grab-left");
- else // dir == RIGHT
- tux_body->arms->set_action("grab-right");
- }
- }
-
- /* Draw Tux */
- if(dying) {
- smalltux_gameover->draw(context, get_pos(), LAYER_FLOATINGOBJECTS + 1);
- }
- else if ((growing_timer.get_timeleft() > 0) && (!duck)) {
- if (dir == RIGHT) {
- context.draw_surface(growingtux_right[int((growing_timer.get_timegone() *
- GROWING_FRAMES) / GROWING_TIME)], get_pos(), layer);
- } else {
- context.draw_surface(growingtux_left[int((growing_timer.get_timegone() *
- GROWING_FRAMES) / GROWING_TIME)], get_pos(), layer);
- }
- }
- else if (safe_timer.started() && size_t(game_time*40)%2)
- ; // don't draw Tux
- else
- tux_body->draw(context, get_pos(), layer, grabbed_object);
-
-}
-
-void
-Player::collision_tile(uint32_t tile_attributes)
-{
- if(tile_attributes & Tile::HURTS)
- kill(false);
-
-#ifdef SWIMMING
- if( swimming ){
- if( tile_attributes & Tile::WATER ){
- no_water = false;
- } else {
- swimming = false;
- }
- } else {
- if( tile_attributes & Tile::WATER ){
- swimming = true;
- no_water = false;
- sound_manager->play( "sounds/splash.ogg" );
- }
- }
-#endif
-}
-
-void
-Player::collision_solid(const CollisionHit& hit)
-{
- if(hit.bottom) {
- if(physic.get_velocity_y() > 0)
- physic.set_velocity_y(0);
-
- on_ground_flag = true;
- floor_normal = hit.slope_normal;
- } else if(hit.top) {
- if(physic.get_velocity_y() < 0)
- physic.set_velocity_y(.2f);
- }
-
- if(hit.left || hit.right) {
- physic.set_velocity_x(0);
- }
-
- // crushed?
- if(hit.crush) {
- if(hit.left || hit.right) {
- kill(true);
- } else if(hit.top || hit.bottom) {
- kill(false);
- }
- }
-}
-
-HitResponse
-Player::collision(GameObject& other, const CollisionHit& hit)
-{
- Bullet* bullet = dynamic_cast<Bullet*> (&other);
- if(bullet) {
- return FORCE_MOVE;
- }
-
- if(hit.left || hit.right) {
- try_grab(); //grab objects right now, in update it will be too late
- }
-#ifdef DEBUG
- assert(dynamic_cast<MovingObject*> (&other) != NULL);
-#endif
- MovingObject* moving_object = static_cast<MovingObject*> (&other);
- if(moving_object->get_group() == COLGROUP_TOUCHABLE) {
- TriggerBase* trigger = dynamic_cast<TriggerBase*> (&other);
- if(trigger) {
- if(controller->pressed(Controller::UP))
- trigger->event(*this, TriggerBase::EVENT_ACTIVATE);
- }
-
- return FORCE_MOVE;
- }
-
- BadGuy* badguy = dynamic_cast<BadGuy*> (&other);
- if(badguy != NULL) {
- if(safe_timer.started() || invincible_timer.started())
- return FORCE_MOVE;
-
- return CONTINUE;
- }
-
- return CONTINUE;
-}
-
-void
-Player::make_invincible()
-{
- sound_manager->play("sounds/invincible.wav");
- invincible_timer.start(TUX_INVINCIBLE_TIME);
- Sector::current()->play_music(HERRING_MUSIC);
-}
-
-/* Kill Player! */
-void
-Player::kill(bool completely)
-{
- if(dying || deactivated)
- return;
-
- if(!completely && (safe_timer.started() || invincible_timer.started()))
- return;
-
- sound_manager->play("sounds/hurt.wav");
- if (climbing) stop_climbing(*climbing);
-
- physic.set_velocity_x(0);
-
- if(!completely && (is_big() || growing_timer.started())) {
- if(player_status->bonus == FIRE_BONUS
- || player_status->bonus == ICE_BONUS) {
- safe_timer.start(TUX_SAFE_TIME);
- set_bonus(GROWUP_BONUS, true);
- } else if(player_status->bonus == GROWUP_BONUS) {
- //growing_timer.start(GROWING_TIME);
- safe_timer.start(TUX_SAFE_TIME /* + GROWING_TIME */);
- adjust_height(30.8f);
- duck = false;
- set_bonus(NO_BONUS, true);
- } else if(player_status->bonus == NO_BONUS) {
- growing_timer.stop();
- safe_timer.start(TUX_SAFE_TIME);
- adjust_height(30.8f);
- duck = false;
- }
- } else {
- if (player_status->coins >= 25 && !GameSession::current()->get_reset_point_sectorname().empty())
- {
- for (int i = 0; i < 5; i++)
- {
- // the numbers: starting x, starting y, velocity y
- Sector::current()->add_object(new FallingCoin(get_pos() +
- Vector(systemRandom.rand(5), systemRandom.rand(-32,18)),
- systemRandom.rand(-100,100)));
- }
- player_status->coins -= std::max(player_status->coins/10, 25);
- }
- else
- {
- GameSession::current()->set_reset_point("", Vector());
- }
- physic.enable_gravity(true);
- physic.set_acceleration(0, 0);
- physic.set_velocity(0, -700);
- set_bonus(NO_BONUS, true);
- dying = true;
- dying_timer.start(3.0);
- set_group(COLGROUP_DISABLED);
-
- DisplayEffect* effect = new DisplayEffect();
- effect->fade_out(3.0);
- Sector::current()->add_object(effect);
- sound_manager->stop_music(3.0);
- }
-}
-
-void
-Player::move(const Vector& vector)
-{
- set_pos(vector);
-
- // TODO: do we need the following? Seems irrelevant to moving the player
- if(is_big())
- set_size(31.8f, 63.8f);
- else
- set_size(31.8f, 31.8f);
- duck = false;
- last_ground_y = vector.y;
- if (climbing) stop_climbing(*climbing);
-
- physic.reset();
-}
-
-void
-Player::check_bounds(Camera* camera)
-{
- /* Keep tux in bounds: */
- if (get_pos().x < 0) {
- // Lock Tux to the size of the level, so that he doesn't fall of
- // on the left side
- set_pos(Vector(0, get_pos().y));
- }
-
- /* fallen out of the level? */
- if (get_pos().y > Sector::current()->get_height()) {
- kill(true);
- return;
- }
-
- // can happen if back scrolling is disabled
- if(get_pos().x < camera->get_translation().x) {
- set_pos(Vector(camera->get_translation().x, get_pos().y));
- }
- if(get_pos().x >= camera->get_translation().x + SCREEN_WIDTH - bbox.get_width())
- {
- set_pos(Vector(
- camera->get_translation().x + SCREEN_WIDTH - bbox.get_width(),
- get_pos().y));
- }
-}
-
-void
-Player::add_velocity(const Vector& velocity)
-{
- physic.set_velocity(physic.get_velocity() + velocity);
-}
-
-void
-Player::add_velocity(const Vector& velocity, const Vector& end_speed)
-{
- if (end_speed.x > 0)
- physic.set_velocity_x(std::min(physic.get_velocity_x() + velocity.x, end_speed.x));
- if (end_speed.x < 0)
- physic.set_velocity_x(std::max(physic.get_velocity_x() + velocity.x, end_speed.x));
- if (end_speed.y > 0)
- physic.set_velocity_y(std::min(physic.get_velocity_y() + velocity.y, end_speed.y));
- if (end_speed.y < 0)
- physic.set_velocity_y(std::max(physic.get_velocity_y() + velocity.y, end_speed.y));
-}
-
-void
-Player::bounce(BadGuy& )
-{
- if(controller->hold(Controller::JUMP))
- physic.set_velocity_y(-520);
- else
- physic.set_velocity_y(-300);
-}
-
-//Scripting Functions Below
-
-void
-Player::deactivate()
-{
- if (deactivated)
- return;
- deactivated = true;
- physic.set_velocity_x(0);
- physic.set_velocity_y(0);
- physic.set_acceleration_x(0);
- physic.set_acceleration_y(0);
- if (climbing) stop_climbing(*climbing);
-}
-
-void
-Player::activate()
-{
- if (!deactivated)
- return;
- deactivated = false;
-}
-
-void Player::walk(float speed)
-{
- physic.set_velocity_x(speed);
-}
-
-void
-Player::set_ghost_mode(bool enable)
-{
- if (ghost_mode == enable)
- return;
-
- if (climbing) stop_climbing(*climbing);
-
- if (enable) {
- ghost_mode = true;
- set_group(COLGROUP_DISABLED);
- physic.enable_gravity(false);
- log_debug << "You feel lightheaded. Use movement controls to float around, press ACTION to scare badguys." << std::endl;
- } else {
- ghost_mode = false;
- set_group(COLGROUP_MOVING);
- physic.enable_gravity(true);
- log_debug << "You feel solid again." << std::endl;
- }
-}
-
-
-void
-Player::start_climbing(Climbable& climbable)
-{
- if (climbing == &climbable) return;
-
- climbing = &climbable;
- physic.enable_gravity(false);
- physic.set_velocity(0, 0);
- physic.set_acceleration(0, 0);
-}
-
-void
-Player::stop_climbing(Climbable& /*climbable*/)
-{
- if (!climbing) return;
-
- climbing = 0;
-
- if (grabbed_object) {
- grabbed_object->ungrab(*this, dir);
- grabbed_object = NULL;
- }
-
- physic.enable_gravity(true);
- physic.set_velocity(0, 0);
- physic.set_acceleration(0, 0);
-
- if ((controller->hold(Controller::JUMP)) || (controller->hold(Controller::UP))) {
- on_ground_flag = true;
- // TODO: This won't help. Why?
- do_jump(-300);
- }
-}
-
-void
-Player::handle_input_climbing()
-{
- if (!climbing) {
- log_warning << "handle_input_climbing called with climbing set to 0. Input handling skipped" << std::endl;
- return;
- }
-
- float vx = 0;
- float vy = 0;
- if (controller->hold(Controller::LEFT)) {
- dir = LEFT;
- vx -= MAX_CLIMB_XM;
- }
- if (controller->hold(Controller::RIGHT)) {
- dir = RIGHT;
- vx += MAX_CLIMB_XM;
- }
- if (controller->hold(Controller::UP)) {
- vy -= MAX_CLIMB_YM;
- }
- if (controller->hold(Controller::DOWN)) {
- vy += MAX_CLIMB_YM;
- }
- if (controller->hold(Controller::JUMP)) {
- if (can_jump) {
- stop_climbing(*climbing);
- return;
- }
- } else {
- can_jump = true;
- }
- if (controller->hold(Controller::ACTION)) {
- stop_climbing(*climbing);
- return;
- }
- physic.set_velocity(vx, vy);
- physic.set_acceleration(0, 0);
-}
-
-
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef SUPERTUX_PLAYER_H
-#define SUPERTUX_PLAYER_H
-
-#include <vector>
-#include <SDL.h>
-
-#include "timer.hpp"
-#include "direction.hpp"
-#include "video/surface.hpp"
-#include "moving_object.hpp"
-#include "sprite/sprite.hpp"
-#include "physic.hpp"
-#include "control/controller.hpp"
-#include "scripting/player.hpp"
-#include "player_status.hpp"
-#include "display_effect.hpp"
-#include "script_interface.hpp"
-#include "console.hpp"
-#include "coin.hpp"
-
-class BadGuy;
-class Portable;
-class Climbable;
-
-/* Times: */
-static const float TUX_SAFE_TIME = 1.8f;
-static const float TUX_INVINCIBLE_TIME = 10.0f;
-static const float TUX_INVINCIBLE_TIME_WARNING = 2.0f;
-static const float GROWING_TIME = 0.35f;
-static const int GROWING_FRAMES = 7;
-
-class Camera;
-class PlayerStatus;
-
-extern Surface* growingtux_left[GROWING_FRAMES];
-extern Surface* growingtux_right[GROWING_FRAMES];
-
-class TuxBodyParts
-{
-public:
- TuxBodyParts()
- : head(0), body(0), arms(0), feet(0)
- { }
- ~TuxBodyParts() {
- delete head;
- delete body;
- delete arms;
- delete feet;
- }
-
- void set_action(std::string action, int loops = -1);
- void one_time_animation();
- void draw(DrawingContext& context, const Vector& pos, int layer, Portable* grabbed_object);
-
- Sprite* head;
- Sprite* body;
- Sprite* arms;
- Sprite* feet;
-};
-
-extern TuxBodyParts* small_tux;
-extern TuxBodyParts* big_tux;
-extern TuxBodyParts* fire_tux;
-extern TuxBodyParts* ice_tux;
-
-class Player : public MovingObject, public UsesPhysic, public Scripting::Player, public ScriptInterface
-{
-public:
- enum FallMode { ON_GROUND, JUMPING, TRAMPOLINE_JUMP, FALLING };
-
- Controller* controller;
- PlayerStatus* player_status;
- bool duck;
- bool dead;
- //Tux can only go this fast. If set to 0 no special limit is used, only the default limits.
- void set_speedlimit(float newlimit);
- float get_speedlimit();
-
-private:
- bool dying;
- bool backflipping;
- int backflip_direction;
- Direction peeking;
- bool swimming;
- float speedlimit;
-
-public:
- Direction dir;
- Direction old_dir;
-
- float last_ground_y;
- FallMode fall_mode;
-
- bool on_ground_flag;
- bool jumping;
- bool can_jump;
- bool butt_jump;
-
- Timer invincible_timer;
- Timer skidding_timer;
- Timer safe_timer;
- Timer kick_timer;
- Timer shooting_timer; // used to show the arm when Tux is shooting
- Timer dying_timer;
- Timer growing_timer;
- Timer idle_timer;
- Timer backflip_timer;
-
-public:
- Player(PlayerStatus* player_status, const std::string& name);
- virtual ~Player();
-
- virtual void expose(HSQUIRRELVM vm, SQInteger table_idx);
- virtual void unexpose(HSQUIRRELVM vm, SQInteger table_idx);
-
- void set_controller(Controller* controller);
- Controller* get_controller()
- {
- return controller;
- }
-
- virtual void update(float elapsed_time);
- virtual void draw(DrawingContext& context);
- virtual void collision_solid(const CollisionHit& hit);
- virtual HitResponse collision(GameObject& other, const CollisionHit& hit);
- virtual void collision_tile(uint32_t tile_attributes);
-
- void make_invincible();
- bool is_invincible() const
- {
- return invincible_timer.started();
- }
- bool is_dying() const
- {
- return dying;
- }
- Direction peeking_direction() const
- {
- return peeking;
- }
-
- void kill(bool completely);
- void check_bounds(Camera* camera);
- void move(const Vector& vector);
-
- virtual bool add_bonus(const std::string& bonus);
- virtual void add_coins(int count);
- virtual int get_coins();
-
- /**
- * picks up a bonus, taking care not to pick up lesser bonus items than we already have
- *
- * @returns true if the bonus has been set (or was already good enough)
- * false if the bonus could not be set (for example no space for big tux)
- */
- bool add_bonus(BonusType type, bool animate = false);
- /**
- * like add_bonus, but can also downgrade the bonus items carried
- */
- bool set_bonus(BonusType type, bool animate = false);
-
- PlayerStatus* get_status()
- {
- return player_status;
- }
- // set kick animation
- void kick();
-
- /**
- * play cheer animation.
- * This might need some space and behave in an unpredictable way. Best to use this at level end.
- */
- void do_cheer();
-
- /**
- * duck down if possible.
- * this won't last long as long as input is enabled.
- */
- void do_duck();
-
- /**
- * stand back up if possible.
- */
- void do_standup();
-
- /**
- * do a backflip if possible.
- */
- void do_backflip();
-
- /**
- * jump in the air if possible
- * sensible values for yspeed are negative - unless we want to jump into the ground of course
- */
- void do_jump(float yspeed);
-
- /**
- * Adds velocity to the player (be carefull when using this)
- */
- void add_velocity(const Vector& velocity);
-
- /**
- * Adds velocity to the player until given end speed is reached
- */
- void add_velocity(const Vector& velocity, const Vector& end_speed);
-
- void bounce(BadGuy& badguy);
-
- bool is_dead() const
- { return dead; }
- bool is_big();
-
- void set_visible(bool visible);
- bool get_visible();
-
- bool on_ground();
-
- Portable* get_grabbed_object() const
- {
- return grabbed_object;
- }
-
- /**
- * Switches ghost mode on/off.
- * Lets Tux float around and through solid objects.
- */
- void set_ghost_mode(bool enable);
-
- /**
- * Returns whether ghost mode is currently enabled
- */
- bool get_ghost_mode() { return ghost_mode; }
-
- /**
- * Changes height of bounding box.
- * Returns true if successful, false otherwise
- */
- bool adjust_height(float new_height);
-
- /**
- * Orders the current GameSession to start a sequence
- */
- void trigger_sequence(std::string sequence_name);
-
- /**
- * Requests that the player start climbing the given Climbable
- */
- void start_climbing(Climbable& climbable);
-
- /**
- * Requests that the player stop climbing the given Climbable
- */
- void stop_climbing(Climbable& climbable);
-
-private:
- void handle_input();
- void handle_input_ghost(); /**< input handling while in ghost mode */
- void handle_input_climbing(); /**< input handling while climbing */
- bool deactivated;
-
- void init();
-
- void handle_horizontal_input();
- void handle_vertical_input();
-
- void activate();
- void deactivate();
- void walk(float speed);
-
- /**
- * slows Tux down a little, based on where he's standing
- */
- void apply_friction();
-
- bool visible;
-
- Portable* grabbed_object;
-
- Sprite* smalltux_gameover;
- Sprite* smalltux_star;
- Sprite* bigtux_star;
-
- std::auto_ptr<Surface> airarrow; /**< arrow indicating Tux' position when he's above the camera */
-
- Vector floor_normal;
- void try_grab();
-
- bool ghost_mode; /**< indicates if Tux should float around and through solid objects */
-
- Timer unduck_hurt_timer; /**< if Tux wants to stand up again after ducking and cannot, this timer is started */
-
- Climbable* climbing; /**< Climbable object we are currently climbing, null if none */
-};
-
-#endif /*SUPERTUX_PLAYER_H*/
+++ /dev/null
-// $Id$
-//
-// SuperTux - PneumaticPlatform
-// Copyright (C) 2007 Christoph Sommer <christoph.sommer@2007.expires.deltadevelopment.de>
-//
-// 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.
-
-#include <config.h>
-
-#include "pneumatic_platform.hpp"
-
-#include <stdexcept>
-#include "log.hpp"
-#include "video/drawing_context.hpp"
-#include "resources.hpp"
-#include "player.hpp"
-#include "path.hpp"
-#include "path_walker.hpp"
-#include "sprite/sprite.hpp"
-#include "lisp/lisp.hpp"
-#include "object_factory.hpp"
-#include "sector.hpp"
-#include "object/portable.hpp"
-
-PneumaticPlatform::PneumaticPlatform(const lisp::Lisp& reader)
- : MovingSprite(reader, LAYER_OBJECTS, COLGROUP_STATIC),
- master(0), slave(0), start_y(0), offset_y(0), speed_y(0)
-{
- start_y = get_pos().y;
-}
-
-PneumaticPlatform::PneumaticPlatform(PneumaticPlatform* master)
- : MovingSprite(*master),
- master(master), slave(this), start_y(master->start_y), offset_y(-master->offset_y), speed_y(0)
-{
- set_pos(get_pos() + Vector(master->get_bbox().get_width(), 0));
- master->master = master;
- master->slave = this;
-}
-
-PneumaticPlatform::~PneumaticPlatform() {
- if ((this == master) && (master)) {
- slave->master = 0;
- slave->slave = 0;
- }
- if ((master) && (this == slave)) {
- master->master = 0;
- master->slave = 0;
- }
- master = 0;
- slave = 0;
-}
-
-HitResponse
-PneumaticPlatform::collision(GameObject& other, const CollisionHit& )
-{
-
- // somehow the hit parameter does not get filled in, so to determine (hit.top == true) we do this:
- MovingObject* mo = dynamic_cast<MovingObject*>(&other);
- if (!mo) return FORCE_MOVE;
- if ((mo->get_bbox().p2.y) > (get_bbox().p1.y + 2)) return FORCE_MOVE;
-
- Player* pl = dynamic_cast<Player*>(mo);
- if (pl) {
- if (pl->is_big()) contacts.insert(0);
- Portable* po = pl->get_grabbed_object();
- MovingObject* pomo = dynamic_cast<MovingObject*>(po);
- if (pomo) contacts.insert(pomo);
- }
-
- contacts.insert(&other);
- return FORCE_MOVE;
-}
-
-void
-PneumaticPlatform::update(float elapsed_time)
-{
- if (!slave) {
- Sector::current()->add_object(new PneumaticPlatform(this));
- return;
- }
- if (!master) {
- return;
- }
- if (this == slave) {
- offset_y = -master->offset_y;
- movement = Vector(0, (start_y + offset_y) - get_pos().y);
- }
- if (this == master) {
- int contact_diff = contacts.size() - slave->contacts.size();
- contacts.clear();
- slave->contacts.clear();
-
- speed_y += ((float)contact_diff * elapsed_time) * 128.0f;
- speed_y -= (offset_y * elapsed_time * 0.5f);
- speed_y *= 1 - elapsed_time;
- offset_y += speed_y * elapsed_time;
- if (offset_y < -256) { offset_y = -256; speed_y = 0; }
- if (offset_y > 256) { offset_y = 256; speed_y = -0; }
- movement = Vector(0, (start_y + offset_y) - get_pos().y);
- }
-}
-
-IMPLEMENT_FACTORY(PneumaticPlatform, "pneumatic-platform");
-
+++ /dev/null
-// $Id$
-//
-// SuperTux - PneumaticPlatform
-// Copyright (C) 2007 Christoph Sommer <christoph.sommer@2007.expires.deltadevelopment.de>
-//
-// 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.
-
-#ifndef __PNEUMATIC_PLATFORM_H__
-#define __PNEUMATIC_PLATFORM_H__
-
-#include <memory>
-#include <string>
-#include <set>
-#include "object/moving_sprite.hpp"
-#include "object/path.hpp"
-#include "object/path_walker.hpp"
-
-/**
- * Used to construct a pair of pneumatic platforms: If one is pushed down, the other one rises
- */
-class PneumaticPlatform : public MovingSprite
-{
-public:
- PneumaticPlatform(const lisp::Lisp& reader);
- PneumaticPlatform(PneumaticPlatform* master);
- virtual ~PneumaticPlatform();
-
- virtual HitResponse collision(GameObject& other, const CollisionHit& hit);
- virtual void update(float elapsed_time);
-
-protected:
- PneumaticPlatform* master; /**< pointer to PneumaticPlatform that does movement calculation */
- PneumaticPlatform* slave; /**< pointer to PneumaticPlatform that reacts to master platform's movement calculation */
- float start_y; /**< vertical start position */
- float offset_y; /**< vertical offset from the start position in px */
- float speed_y; /**< vertical speed */
- std::set<GameObject*> contacts; /**< objects that are currently pushing on the platform */
-
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __PORTABLE_H__
-#define __PORTABLE_H__
-
-#include "moving_object.hpp"
-#include "direction.hpp"
-#include "refcounter.hpp"
-
-/**
- * An object that inherits from this object is considered "portable" and can
- * be carried around by the player.
- * The object has to additionally set the PORTABLE flag (this allows to
- * make the object only temporarily portable by resetting the flag)
- */
-class Portable
-{
-public:
- virtual ~Portable()
- { }
-
- /**
- * called each frame when the object has been grabbed.
- */
- virtual void grab(MovingObject& object, const Vector& pos, Direction dir) = 0;
-
- virtual void ungrab(MovingObject& , Direction )
- {}
-
- virtual bool is_portable() const
- {
- return true;
- }
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include <stdexcept>
-#include <math.h>
-#include <stdexcept>
-#include "powerup.hpp"
-#include "resources.hpp"
-#include "player.hpp"
-#include "audio/sound_manager.hpp"
-#include "object_factory.hpp"
-#include "sector.hpp"
-#include "log.hpp"
-
-PowerUp::PowerUp(const lisp::Lisp& lisp)
- : MovingSprite(lisp, LAYER_OBJECTS, COLGROUP_MOVING)
-{
- lisp.get("script", script);
- no_physics = false;
- lisp.get("disable-physics", no_physics);
- physic.enable_gravity(true);
- sound_manager->preload("sounds/grow.wav");
- sound_manager->preload("sounds/fire-flower.wav");
-}
-
-void
-PowerUp::collision_solid(const CollisionHit& hit)
-{
- if(hit.bottom) {
- physic.set_velocity_y(0);
- }
- if(hit.right || hit.left) {
- physic.set_velocity_x(-physic.get_velocity_x());
- }
-}
-
-HitResponse
-PowerUp::collision(GameObject& other, const CollisionHit&)
-{
- Player* player = dynamic_cast<Player*>(&other);
- if(player == 0)
- return FORCE_MOVE;
-
- if (script != "") {
- std::istringstream stream(script);
- Sector::current()->run_script(stream, "powerup-script");
- remove_me();
- return ABORT_MOVE;
- }
-
- // some defaults if no script has been set
- if (sprite_name == "images/powerups/egg/egg.sprite") {
- if(!player->add_bonus(GROWUP_BONUS, true))
- return FORCE_MOVE;
- sound_manager->play("sounds/grow.wav");
- } else if (sprite_name == "images/powerups/fireflower/fireflower.sprite") {
- if(!player->add_bonus(FIRE_BONUS, true))
- return FORCE_MOVE;
- sound_manager->play("sounds/fire-flower.wav");
- } else if (sprite_name == "images/powerups/star/star.sprite") {
- player->make_invincible();
- } else if (sprite_name == "images/powerups/1up/1up.sprite") {
- player->get_status()->add_coins(100);
- }
-
- remove_me();
- return ABORT_MOVE;
-}
-
-void
-PowerUp::update(float elapsed_time)
-{
- if (!no_physics)
- movement = physic.get_movement(elapsed_time);
-}
-
-IMPLEMENT_FACTORY(PowerUp, "powerup");
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __POWERUP_H__
-#define __POWERUP_H__
-
-#include "object/moving_sprite.hpp"
-#include "lisp/lisp.hpp"
-#include "collision_hit.hpp"
-#include "physic.hpp"
-
-class PowerUp : public MovingSprite, private UsesPhysic
-{
-public:
- PowerUp(const lisp::Lisp& lisp);
-
- virtual void update(float elapsed_time);
- virtual void collision_solid(const CollisionHit& hit);
- virtual HitResponse collision(GameObject& other, const CollisionHit& hit);
-
-private:
- std::string script;
- bool no_physics;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux - Pulsing Light
-// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
-//
-// 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.
-
-#include <config.h>
-
-#include "pulsing_light.hpp"
-#include "video/color.hpp"
-#include <math.h>
-#include "random_generator.hpp"
-
-PulsingLight::PulsingLight(const Vector& center, float cycle_len, float min_alpha, float max_alpha, const Color& color)
- : Light(center, color), min_alpha(min_alpha), max_alpha(max_alpha), cycle_len(cycle_len), t(0)
-{
- assert(cycle_len > 0);
-
- // start with random phase offset
- t = systemRandom.randf(0.0, cycle_len);
-}
-
-PulsingLight::~PulsingLight()
-{
-}
-
-void
-PulsingLight::update(float elapsed_time)
-{
- Light::update(elapsed_time);
-
- t += elapsed_time;
- if (t > cycle_len) t -= cycle_len;
-}
-
-void
-PulsingLight::draw(DrawingContext& context)
-{
- Color old_color = color;
-
- color.alpha *= min_alpha + ((max_alpha - min_alpha) * cos(2 * M_PI * t / cycle_len));
- Light::draw(context);
-
- color = old_color;
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux - Pulsing Light
-// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
-//
-// 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.
-
-#ifndef __PULSING_LIGHT_HPP__
-#define __PULSING_LIGHT_HPP__
-
-#include "light.hpp"
-#include "game_object.hpp"
-#include "lisp/lisp.hpp"
-#include "math/vector.hpp"
-#include "video/color.hpp"
-
-class Sprite;
-
-/**
- * Light source that changes alpha value to give the impression of a pulsating light
- */
-class PulsingLight : public Light
-{
-public:
- PulsingLight(const Vector& center, float cycle_len = 5.0, float min_alpha = 0.0, float max_alpha = 1.0, const Color& color = Color(1.0, 1.0, 1.0, 1.0));
- virtual ~PulsingLight();
-
- void update(float elapsed_time);
- void draw(DrawingContext& context);
-
-protected:
- float min_alpha; /**< minimum alpha */
- float max_alpha; /**< maximum alpha */
- float cycle_len; /**< length in seconds of one cycle */
-
- float t; /**< local time in seconds */
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux - PushButton running a script
-// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
-//
-// 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.
-
-#include <config.h>
-#include <stdexcept>
-
-#include "pushbutton.hpp"
-#include "object_factory.hpp"
-#include "player.hpp"
-#include "audio/sound_manager.hpp"
-#include "sprite/sprite_manager.hpp"
-#include "sector.hpp"
-#include "log.hpp"
-
-namespace {
- const std::string BUTTON_SOUND = "sounds/switch.ogg";
- //14 -> 8
-}
-
-PushButton::PushButton(const lisp::Lisp& lisp)
- : MovingSprite(lisp, "images/objects/pushbutton/pushbutton.sprite", LAYER_BACKGROUNDTILES+1, COLGROUP_MOVING), state(OFF)
-{
- sound_manager->preload(BUTTON_SOUND);
- set_action("off", -1);
- bbox.set_size(sprite->get_current_hitbox_width(), sprite->get_current_hitbox_height());
-
- if (!lisp.get("script", script)) throw std::runtime_error("no script set");
-}
-
-void
-PushButton::update(float /*elapsed_time*/)
-{
-}
-
-HitResponse
-PushButton::collision(GameObject& other, const CollisionHit& hit)
-{
- Player* player = dynamic_cast<Player*>(&other);
- if (!player) return FORCE_MOVE;
- float vy = player->physic.get_velocity_y();
-
- //player->add_velocity(Vector(0, -150));
- player->physic.set_velocity_y(-150);
-
- if (state != OFF) return FORCE_MOVE;
- if (!hit.top) return FORCE_MOVE;
- if (vy <= 0) return FORCE_MOVE;
-
- // change appearance
- state = ON;
- float old_bbox_height = bbox.get_height();
- set_action("on", -1);
- float new_bbox_height = bbox.get_height();
- set_pos(get_pos() + Vector(0, old_bbox_height - new_bbox_height));
-
- // play sound
- sound_manager->play(BUTTON_SOUND);
-
- // run script
- std::istringstream stream(script);
- Sector::current()->run_script(stream, "PushButton");
-
- return FORCE_MOVE;
-}
-
-IMPLEMENT_FACTORY(PushButton, "pushbutton");
+++ /dev/null
-// $Id$
-//
-// SuperTux - PushButton running a script
-// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
-//
-// 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.
-
-#ifndef SUPERTUX_BUTTON_H
-#define SUPERTUX_BUTTON_H
-
-#include "moving_sprite.hpp"
-#include "lisp/lisp.hpp"
-
-/**
- * PushButton - jump on it to run a script
- */
-class PushButton : public MovingSprite
-{
-public:
- PushButton(const lisp::Lisp& reader);
-
- HitResponse collision(GameObject& other, const CollisionHit& hit);
- void update(float elapsed_time);
-
-private:
- enum PushButtonState {
- OFF,
- ON
- };
-
- std::string script;
- PushButtonState state;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#include <config.h>
-
-#include "rainsplash.hpp"
-#include "sector.hpp"
-
-RainSplash::RainSplash(Vector pos, bool vertical)
-{
- frame = 0;
- position = pos;
- if (vertical) sprite = sprite_manager->create("images/objects/particles/rainsplash-vertical.sprite");
- else sprite = sprite_manager->create("images/objects/particles/rainsplash.sprite");
-}
-
-RainSplash::~RainSplash() {
- remove_me();
-}
-
-void
-RainSplash::hit(Player& )
-{
-}
-
-void
-RainSplash::update(float time)
-{
- time = 0;//just so i don't get an "unused variable" error - don't know how to circumvent this
- frame++;
- if (frame >= 10) remove_me();
-}
-
-void
-RainSplash::draw(DrawingContext& context)
-{
- sprite->draw(context, position, LAYER_OBJECTS);
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __RAINSPLASH_H__
-#define __RAINSPLASH_H__
-
-
-#include "game_object.hpp"
-#include "resources.hpp"
-#include "player.hpp"
-#include "sprite/sprite.hpp"
-#include "sprite/sprite_manager.hpp"
-#include "video/drawing_context.hpp"
-
-class RainSplash : public GameObject
-{
-public:
- RainSplash(Vector pos, bool vertical);
- ~RainSplash();
-protected:
- virtual void hit(Player& );
- virtual void update(float time);
- virtual void draw(DrawingContext& context);
-private:
- Sprite* sprite;
- Vector position;
- int frame;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include "rock.hpp"
-#include "lisp/writer.hpp"
-#include "object_factory.hpp"
-#include "audio/sound_manager.hpp"
-#include "tile.hpp"
-
-namespace {
- const std::string ROCK_SOUND = "sounds/brick.wav"; //TODO use own sound.
-}
-
-Rock::Rock(const Vector& pos, std::string spritename)
- : MovingSprite(pos, spritename)
-{
- sound_manager->preload(ROCK_SOUND);
- on_ground = false;
- grabbed = false;
- set_group(COLGROUP_MOVING_STATIC);
-}
-
-Rock::Rock(const lisp::Lisp& reader)
- : MovingSprite(reader, "images/objects/rock/rock.sprite")
-{
- sound_manager->preload(ROCK_SOUND);
- on_ground = false;
- grabbed = false;
- set_group(COLGROUP_MOVING_STATIC);
-}
-
-Rock::Rock(const lisp::Lisp& reader, std::string spritename)
- : MovingSprite(reader, spritename)
-{
- sound_manager->preload(ROCK_SOUND);
- on_ground = false;
- grabbed = false;
- set_group(COLGROUP_MOVING_STATIC);
-}
-
-void
-Rock::write(lisp::Writer& writer)
-{
- writer.start_list("rock");
-
- writer.write_float("x", bbox.p1.x);
- writer.write_float("y", bbox.p1.y);
-
- writer.end_list("rock");
-}
-
-void
-Rock::update(float elapsed_time)
-{
- if( grabbed )
- return;
-
- if (on_ground) physic.set_velocity_x(0);
-
- movement = physic.get_movement(elapsed_time);
-}
-
-void
-Rock::collision_solid(const CollisionHit& hit)
-{
- if(grabbed) {
- return;
- }
- if(hit.top || hit.bottom)
- physic.set_velocity_y(0);
- if(hit.left || hit.right)
- physic.set_velocity_x(0);
- if(hit.crush)
- physic.set_velocity(0, 0);
-
- if(hit.bottom && !on_ground && !grabbed) {
- sound_manager->play(ROCK_SOUND, get_pos());
- on_ground = true;
- }
-}
-
-HitResponse
-Rock::collision(GameObject& other, const CollisionHit& hit)
-{
- if(grabbed) {
- return PASSTHROUGH;
- }
- if(!on_ground) {
- if(hit.bottom && physic.get_velocity_y() > 200) {
- MovingObject* moving_object = dynamic_cast<MovingObject*> (&other);
- if(moving_object) {
- //Getting a rock on the head hurts. A lot.
- moving_object->collision_tile(Tile::HURTS);
- }
- }
- return FORCE_MOVE;
- }
-
- return FORCE_MOVE;
-}
-
-void
-Rock::grab(MovingObject& , const Vector& pos, Direction)
-{
- movement = pos - get_pos();
- last_movement = movement;
- set_group(COLGROUP_TOUCHABLE);
- on_ground = false;
- grabbed = true;
-}
-
-void
-Rock::ungrab(MovingObject& , Direction dir)
-{
- set_group(COLGROUP_MOVING_STATIC);
- on_ground = false;
- if(dir == UP) {
- physic.set_velocity(0, -500);
- } else if (last_movement.norm() > 1) {
- physic.set_velocity((dir == RIGHT) ? 200 : -200, -200);
- } else {
- physic.set_velocity(0, 0);
- }
- grabbed = false;
-}
-
-IMPLEMENT_FACTORY(Rock, "rock");
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __ROCK_H__
-#define __ROCK_H__
-
-#include "object/moving_sprite.hpp"
-#include "physic.hpp"
-#include "lisp/lisp.hpp"
-#include "portable.hpp"
-#include "serializable.hpp"
-
-class Sprite;
-
-class Rock : public MovingSprite, public Portable, protected UsesPhysic, public Serializable
-{
-public:
- Rock(const Vector& pos, std::string spritename);
- Rock(const lisp::Lisp& reader);
- Rock(const lisp::Lisp& reader, std::string spritename);
- virtual Rock* clone() const { return new Rock(*this); }
-
- void collision_solid(const CollisionHit& hit);
- HitResponse collision(GameObject& other, const CollisionHit& hit);
- void update(float elapsed_time);
- void write(lisp::Writer& writer);
-
- void grab(MovingObject& object, const Vector& pos, Direction dir);
- void ungrab(MovingObject& object, Direction dir);
-
-protected:
- bool on_ground;
- bool grabbed;
- Vector last_movement;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#include <config.h>
-
-#include <stdexcept>
-#include <math.h>
-
-#include "scripted_object.hpp"
-#include "video/drawing_context.hpp"
-#include "scripting/squirrel_util.hpp"
-#include "resources.hpp"
-#include "object_factory.hpp"
-#include "math/vector.hpp"
-
-ScriptedObject::ScriptedObject(const lisp::Lisp& lisp)
- : MovingSprite(lisp, LAYER_OBJECTS, COLGROUP_MOVING_STATIC),
- solid(true), physic_enabled(true), visible(true), new_vel_set(false)
-{
- lisp.get("name", name);
- if(name == "")
- throw std::runtime_error("Scripted object must have a name specified");
-
- // FIXME: do we need this? bbox is already set via .sprite file
- float width = sprite->get_width();
- float height = sprite->get_height();
- lisp.get("width", width);
- lisp.get("height", height);
- bbox.set_size(width, height);
-
- lisp.get("solid", solid);
- lisp.get("physic-enabled", physic_enabled);
- lisp.get("visible", visible);
- lisp.get("z-pos", layer);
- if( solid ){
- set_group( COLGROUP_MOVING_STATIC );
- } else {
- set_group( COLGROUP_DISABLED );
- }
-}
-
-void
-ScriptedObject::expose(HSQUIRRELVM vm, SQInteger table_idx)
-{
- if (name.empty()) return;
- expose_object(vm, table_idx, dynamic_cast<Scripting::ScriptedObject *>(this), name, false);
-}
-
-void
-ScriptedObject::unexpose(HSQUIRRELVM vm, SQInteger table_idx)
-{
- if (name.empty()) return;
- Scripting::unexpose_object(vm, table_idx, name);
-}
-
-void
-ScriptedObject::move(float x, float y)
-{
- bbox.move(Vector(x, y));
-}
-
-void
-ScriptedObject::set_pos(float x, float y)
-{
- printf("SetPos: %f %f\n", x, y);
- bbox.set_pos(Vector(x, y));
- physic.reset();
-}
-
-float
-ScriptedObject::get_pos_x()
-{
- return get_pos().x;
-}
-
-float
-ScriptedObject::get_pos_y()
-{
- return get_pos().y;
-}
-
-void
-ScriptedObject::set_velocity(float x, float y)
-{
- new_vel = Vector(x, y);
- new_vel_set = true;
-}
-
-float
-ScriptedObject::get_velocity_x()
-{
- return physic.get_velocity_x();
-}
-
-float
-ScriptedObject::get_velocity_y()
-{
- return physic.get_velocity_y();
-}
-
-void
-ScriptedObject::set_visible(bool visible)
-{
- this->visible = visible;
-}
-
-bool
-ScriptedObject::is_visible()
-{
- return visible;
-}
-
-void
-ScriptedObject::set_solid(bool solid)
-{
- this->solid = solid;
- if( solid ){
- set_group( COLGROUP_MOVING_STATIC );
- } else {
- set_group( COLGROUP_DISABLED );
- }
-}
-
-bool
-ScriptedObject::is_solid()
-{
- return solid;
-}
-
-
-void
-ScriptedObject::set_action(const std::string& animation)
-{
- sprite->set_action(animation);
-}
-
-std::string
-ScriptedObject::get_action()
-{
- return sprite->get_action();
-}
-
-std::string
-ScriptedObject::get_name()
-{
- return name;
-}
-
-void
-ScriptedObject::update(float elapsed_time)
-{
- if(!physic_enabled)
- return;
-
- if(new_vel_set) {
- physic.set_velocity(new_vel.x, new_vel.y);
- new_vel_set = false;
- }
- movement = physic.get_movement(elapsed_time);
-}
-
-void
-ScriptedObject::draw(DrawingContext& context)
-{
- if(!visible)
- return;
-
- sprite->draw(context, get_pos(), layer);
-}
-
-void
-ScriptedObject::collision_solid(const CollisionHit& hit)
-{
- if(!physic_enabled)
- return;
-
- if(hit.bottom) {
- if(physic.get_velocity_y() > 0)
- physic.set_velocity_y(0);
- } else if(hit.top) {
- physic.set_velocity_y(.1f);
- }
-
- if(hit.left || hit.right) {
- physic.set_velocity_x(0);
- }
-}
-
-HitResponse
-ScriptedObject::collision(GameObject& , const CollisionHit& )
-{
- return FORCE_MOVE;
-}
-
-IMPLEMENT_FACTORY(ScriptedObject, "scriptedobject");
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __SCRIPTED_OBJECT_H__
-#define __SCRIPTED_OBJECT_H__
-
-#include <string>
-#include "physic.hpp"
-#include "lisp/lisp.hpp"
-#include "object/moving_sprite.hpp"
-#include "script_interface.hpp"
-#include "scripting/scripted_object.hpp"
-
-class ScriptedObject : public MovingSprite, public UsesPhysic,
- public Scripting::ScriptedObject, public ScriptInterface
-{
-public:
- ScriptedObject(const lisp::Lisp& lisp);
- virtual ScriptedObject* clone() const { return new ScriptedObject(*this); }
-
- virtual void expose(HSQUIRRELVM vm, SQInteger table_idx);
- virtual void unexpose(HSQUIRRELVM vm, SQInteger table_idx);
-
- void update(float elapsed_time);
- void draw(DrawingContext& context);
-
- void collision_solid(const CollisionHit& hit);
- HitResponse collision(GameObject& other, const CollisionHit& hit);
-
- // --- Scripting Interface stuff ---
-
- void set_action(const std::string& animation);
- std::string get_action();
-
- void move(float x, float y);
- void set_pos(float x, float y);
- float get_pos_x();
- float get_pos_y();
- void set_velocity(float x, float y);
- float get_velocity_x();
- float get_velocity_y();
- void set_visible(bool visible);
- bool is_visible();
- void set_solid(bool solid);
- bool is_solid();
-
- std::string get_name();
-
-private:
- std::string name;
- bool solid;
- bool physic_enabled;
- bool visible;
- bool new_vel_set;
- Vector new_vel;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include "skull_tile.hpp"
-#include "lisp/lisp.hpp"
-#include "object_factory.hpp"
-#include "player.hpp"
-#include "sector.hpp"
-#include "resources.hpp"
-#include "sprite/sprite.hpp"
-#include "random_generator.hpp"
-
-static const float CRACKTIME = 0.3f;
-static const float FALLTIME = 0.8f;
-
-SkullTile::SkullTile(const lisp::Lisp& lisp)
- : MovingSprite(lisp, "images/objects/skull_tile/skull_tile.sprite", LAYER_TILES, COLGROUP_STATIC), hit(false), falling(false)
-{
-}
-
-HitResponse
-SkullTile::collision(GameObject& other, const CollisionHit& )
-{
- Player* player = dynamic_cast<Player*> (&other);
- if(player)
- hit = true;
-
- return FORCE_MOVE;
-}
-
-void
-SkullTile::draw(DrawingContext& context)
-{
- Vector pos = get_pos();
- // shacking
- if(timer.get_timegone() > CRACKTIME) {
- pos.x += systemRandom.rand(-3, 3);
- }
-
- sprite->draw(context, pos, layer);
-}
-
-void
-SkullTile::update(float elapsed_time)
-{
- if(falling) {
- movement = physic.get_movement(elapsed_time);
- if(!Sector::current()->inside(bbox)) {
- remove_me();
- return;
- }
- } else if(hit) {
- if(timer.check()) {
- falling = true;
- physic.enable_gravity(true);
- timer.stop();
- } else if(!timer.started()) {
- timer.start(FALLTIME);
- }
- } else {
- timer.stop();
- }
- hit = false;
-}
-
-IMPLEMENT_FACTORY(SkullTile, "skull_tile");
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __SKULL_TILE_H__
-#define __SKULL_TILE_H__
-
-#include "object/moving_sprite.hpp"
-#include "lisp/lisp.hpp"
-#include "physic.hpp"
-#include "timer.hpp"
-
-class Player;
-
-/** A tile that starts falling down if tux stands to long on it */
-class SkullTile : public MovingSprite, private UsesPhysic
-{
-public:
- SkullTile(const lisp::Lisp& lisp);
- virtual SkullTile* clone() const { return new SkullTile(*this); }
-
- HitResponse collision(GameObject& other, const CollisionHit& hit);
- void update(float elapsed_time);
- void draw(DrawingContext& context);
-
-private:
- Timer timer;
- bool hit;
- bool falling;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include <math.h>
-#include "specialriser.hpp"
-#include "resources.hpp"
-#include "camera.hpp"
-#include "sector.hpp"
-#include "sprite/sprite_manager.hpp"
-
-SpecialRiser::SpecialRiser(Vector pos, MovingObject* _child)
- : child(_child)
-{
- _child->set_pos(pos - Vector(0, 32));
- offset = 0;
-}
-
-SpecialRiser::~SpecialRiser()
-{
-}
-
-void
-SpecialRiser::update(float elapsed_time)
-{
- offset += 50 * elapsed_time;
- if(offset > 32) {
- Sector::current()->add_object(child);
- remove_me();
- }
-}
-
-void
-SpecialRiser::draw(DrawingContext& context)
-{
- context.push_transform();
- context.set_translation(
- context.get_translation() + Vector(0, -32 + offset));
- child->draw(context);
- context.pop_transform();
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __SPECIALRISE_H__
-#define __SPECIALRISE_H__
-
-#include "moving_object.hpp"
-
-/**
- * special object that contains another object and slowly rises it out of a
- * bonus block.
- */
-class SpecialRiser : public GameObject
-{
-public:
- SpecialRiser(Vector pos, MovingObject* child);
- ~SpecialRiser();
-
- virtual void update(float elapsed_time);
- virtual void draw(DrawingContext& context);
-
-private:
- float offset;
- MovingObject* child;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Ingo Ruhnke <grumbel@gmx.de>
-//
-// 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.
-
-#include <config.h>
-
-#include "spotlight.hpp"
-#include "sprite/sprite_manager.hpp"
-#include "resources.hpp"
-#include "video/drawing_context.hpp"
-#include "object_factory.hpp"
-#include "player.hpp"
-#include "sector.hpp"
-
-Spotlight::Spotlight(const lisp::Lisp& lisp)
- : angle(0.0f),
- color(1.0f, 1.0f, 1.0f)
-{
- lisp.get("x", position.x);
- lisp.get("y", position.y);
-
- lisp.get("angle", angle);
-
- std::vector<float> vColor;
- if( lisp.get_vector( "color", vColor ) ){
- color = Color( vColor );
- }
-
- center = sprite_manager->create("images/objects/spotlight/spotlight_center.sprite");
- base = sprite_manager->create("images/objects/spotlight/spotlight_base.sprite");
- lights = sprite_manager->create("images/objects/spotlight/spotlight_lights.sprite");
- lightcone = sprite_manager->create("images/objects/spotlight/lightcone.sprite");
- light = sprite_manager->create("images/objects/spotlight/light.sprite");
-
-
-}
-
-Spotlight::~Spotlight()
-{
- delete center;
- delete base;
- delete lights;
- delete lightcone;
- delete light;
-}
-
-void
-Spotlight::update(float delta)
-{
- angle += delta * 50.0f;
-}
-
-void
-Spotlight::draw(DrawingContext& context)
-{
- context.push_target();
- context.set_target(DrawingContext::LIGHTMAP);
-
- light->set_color(color);
- light->set_blend(Blend(GL_SRC_ALPHA, GL_ONE));
- light->set_angle(angle);
- light->draw(context, position, 0);
-
- //lightcone->set_angle(angle);
- //lightcone->draw(context, position, 0);
-
- context.set_target(DrawingContext::NORMAL);
-
- lights->set_angle(angle);
- lights->draw(context, position, 0);
-
- base->set_angle(angle);
- base->draw(context, position, 0);
-
- center->draw(context, position, 0);
-
- lightcone->set_angle(angle);
- lightcone->draw(context, position, LAYER_FOREGROUND1 + 10);
-
- context.pop_target();
-}
-
-IMPLEMENT_FACTORY(Spotlight, "spotlight");
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __SPOTLIGHT_HPP__
-#define __SPOTLIGHT_HPP__
-
-#include "game_object.hpp"
-#include "math/vector.hpp"
-#include "lisp/lisp.hpp"
-#include "video/color.hpp"
-
-class Sprite;
-
-class Spotlight : public GameObject
-{
-public:
- Spotlight(const lisp::Lisp& reader);
- virtual ~Spotlight();
-
- void update(float elapsed_time);
- void draw(DrawingContext& context);
-
-private:
- Vector position;
- float angle;
- Sprite* center;
- Sprite* base;
- Sprite* lights;
- Sprite* light;
- Sprite* lightcone;
-
- Color color;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
-//
-// 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.
-#include <config.h>
-
-#include <stdexcept>
-#include "sprite_particle.hpp"
-#include "sector.hpp"
-#include "camera.hpp"
-#include "main.hpp"
-#include "log.hpp"
-
-SpriteParticle::SpriteParticle(std::string sprite_name, std::string action, Vector position, AnchorPoint anchor, Vector velocity, Vector acceleration, int drawing_layer)
- : position(position), velocity(velocity), acceleration(acceleration), drawing_layer(drawing_layer)
-{
- sprite = sprite_manager->create(sprite_name);
- if (!sprite) throw std::runtime_error("Could not load sprite "+sprite_name);
- sprite->set_action(action, 1);
- sprite->set_animation_loops(1); //TODO: this is necessary because set_action will not set "loops" when "action" is the default action
-
- this->position -= get_anchor_pos(sprite->get_current_hitbox(), anchor);
-}
-
-SpriteParticle::~SpriteParticle()
-{
- remove_me();
-}
-
-void
-SpriteParticle::hit(Player& )
-{
-}
-
-void
-SpriteParticle::update(float elapsed_time)
-{
- // die when animation is complete
- if (sprite->animation_done()) {
- remove_me();
- return;
- }
-
- // calculate new position and velocity
- position.x += velocity.x * elapsed_time;
- position.y += velocity.y * elapsed_time;
- velocity.x += acceleration.x * elapsed_time;
- velocity.y += acceleration.y * elapsed_time;
-
- // die when too far offscreen
- Vector camera = Sector::current()->camera->get_translation();
- if ((position.x < camera.x - 128) || (position.x > SCREEN_WIDTH + camera.x + 128) ||
- (position.y < camera.y - 128) || (position.y > SCREEN_HEIGHT + camera.y + 128)) {
- remove_me();
- return;
- }
-}
-
-void
-SpriteParticle::draw(DrawingContext& context)
-{
- sprite->draw(context, position, drawing_layer);
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
-//
-// 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.
-
-#ifndef __SPRITE_PARTICLE_H__
-#define __SPRITE_PARTICLE_H__
-
-
-#include "game_object.hpp"
-#include "resources.hpp"
-#include "player.hpp"
-#include "object/anchor_point.hpp"
-#include "sprite/sprite.hpp"
-#include "sprite/sprite_manager.hpp"
-#include "video/drawing_context.hpp"
-
-class SpriteParticle : public GameObject
-{
-public:
- SpriteParticle(std::string sprite_name, std::string action, Vector position, AnchorPoint anchor, Vector velocity, Vector acceleration, int drawing_layer = LAYER_OBJECTS-1);
- ~SpriteParticle();
-protected:
- virtual void hit(Player& player);
- virtual void update(float elapsed_time);
- virtual void draw(DrawingContext& context);
-private:
- Sprite* sprite;
- Vector position;
- Vector velocity;
- Vector acceleration;
- int drawing_layer;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include "star.hpp"
-#include "resources.hpp"
-#include "player.hpp"
-#include "player_status.hpp"
-#include "sprite/sprite_manager.hpp"
-#include "video/drawing_context.hpp"
-
-static const float INITIALJUMP = -400;
-static const float SPEED = 150;
-static const float JUMPSPEED = -300;
-
-Star::Star(const Vector& pos, Direction direction)
- : MovingSprite(pos, "images/powerups/star/star.sprite", LAYER_OBJECTS, COLGROUP_MOVING)
-{
- physic.set_velocity((direction == LEFT) ? -SPEED : SPEED, INITIALJUMP);
-}
-
-void
-Star::update(float elapsed_time)
-{
- movement = physic.get_movement(elapsed_time);
-}
-
-void
-Star::collision_solid(const CollisionHit& hit)
-{
- if(hit.bottom) {
- physic.set_velocity_y(JUMPSPEED);
- } else if(hit.top) {
- physic.set_velocity_y(0);
- } else if(hit.left || hit.right) {
- physic.set_velocity_x(-physic.get_velocity_x());
- }
-}
-
-HitResponse
-Star::collision(GameObject& other, const CollisionHit& )
-{
- Player* player = dynamic_cast<Player*> (&other);
- if(player) {
- player->make_invincible();
- remove_me();
- return ABORT_MOVE;
- }
-
- return FORCE_MOVE;
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __STAR_H__
-#define __STAR_H__
-
-#include "object/moving_sprite.hpp"
-#include "physic.hpp"
-#include "direction.hpp"
-
-class Star : public MovingSprite, private UsesPhysic
-{
-public:
- Star(const Vector& pos, Direction direction = RIGHT);
- virtual Star* clone() const { return new Star(*this); }
-
- virtual void update(float elapsed_time);
- virtual void collision_solid(const CollisionHit& hit);
- virtual HitResponse collision(GameObject& other, const CollisionHit& hit);
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include "text_object.hpp"
-
-#include <iostream>
-#include "resources.hpp"
-#include "main.hpp"
-#include "video/drawing_context.hpp"
-#include "scripting/squirrel_util.hpp"
-#include "log.hpp"
-
-TextObject::TextObject(std::string name)
- : fading(0), fadetime(0), visible(false), anchor(ANCHOR_MIDDLE),
- pos(0, 0)
-{
- this->name = name;
- font = blue_text;
- centered = false;
-}
-
-TextObject::~TextObject()
-{
-}
-
-void
-TextObject::expose(HSQUIRRELVM vm, SQInteger table_idx)
-{
- if (name.empty())
- return;
-
- Scripting::expose_object(vm, table_idx, dynamic_cast<Scripting::Text *>(this), name, false);
-}
-
-void
-TextObject::unexpose(HSQUIRRELVM vm, SQInteger table_idx)
-{
- if (name.empty())
- return;
-
- Scripting::unexpose_object(vm, table_idx, name);
-}
-
-void
-TextObject::set_font(const std::string& name)
-{
- if(name == "gold") {
- font = gold_text;
- } else if(name == "white") {
- font = white_text;
- } else if(name == "blue") {
- font = blue_text;
- } else if(name == "gray") {
- font = gray_text;
- } else if(name == "big") {
- font = white_big_text;
- } else if(name == "small") {
- font = white_small_text;
- } else {
- log_warning << "Unknown font '" << name << "'." << std::endl;
- }
-}
-
-void
-TextObject::set_text(const std::string& text)
-{
- this->text = text;
-}
-
-void
-TextObject::fade_in(float fadetime)
-{
- this->fadetime = fadetime;
- fading = fadetime;
-}
-
-void
-TextObject::fade_out(float fadetime)
-{
- this->fadetime = fadetime;
- fading = -fadetime;
-}
-
-void
-TextObject::set_visible(bool visible)
-{
- this->visible = visible;
- fading = 0;
-}
-
-void
-TextObject::set_centered(bool centered)
-{
- this->centered = centered;
-}
-
-void
-TextObject::draw(DrawingContext& context)
-{
- context.push_transform();
- context.set_translation(Vector(0, 0));
- if(fading > 0) {
- context.set_alpha((fadetime-fading) / fadetime);
- } else if(fading < 0) {
- context.set_alpha(-fading / fadetime);
- } else if(!visible) {
- context.pop_transform();
- return;
- }
-
- float width = 500;
- float height = 70;
- Vector spos = pos + get_anchor_pos(Rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT),
- width, height, anchor);
-
- context.draw_filled_rect(spos, Vector(width, height),
- Color(0.6f, 0.7f, 0.8f, 0.5f), LAYER_GUI-50);
- if (centered) {
- context.draw_center_text(font, text, spos, LAYER_GUI-40);
- } else {
- context.draw_text(font, text, spos + Vector(10, 10), ALIGN_LEFT, LAYER_GUI-40);
- }
-
- context.pop_transform();
-}
-
-void
-TextObject::update(float elapsed_time)
-{
- if(fading > 0) {
- fading -= elapsed_time;
- if(fading <= 0) {
- fading = 0;
- visible = true;
- }
- } else if(fading < 0) {
- fading += elapsed_time;
- if(fading >= 0) {
- fading = 0;
- visible = false;
- }
- }
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __TEXTOBJECT_H__
-#define __TEXTOBJECT_H__
-
-#include "game_object.hpp"
-#include "scripting/text.hpp"
-#include "script_interface.hpp"
-#include "anchor_point.hpp"
-
-class Font;
-
-/** A text object intended for scripts that want to tell a story */
-class TextObject : public GameObject, public Scripting::Text,
- public ScriptInterface
-{
-public:
- TextObject(std::string name = "");
- virtual ~TextObject();
-
- void expose(HSQUIRRELVM vm, SQInteger table_idx);
- void unexpose(HSQUIRRELVM vm, SQInteger table_idx);
-
- void set_text(const std::string& text);
- void set_font(const std::string& name);
- void fade_in(float fadetime);
- void fade_out(float fadetime);
- void set_visible(bool visible);
- void set_centered(bool centered);
- bool is_visible();
-
- void set_anchor_point(AnchorPoint anchor) {
- this->anchor = anchor;
- }
- AnchorPoint get_anchor_point() const {
- return anchor;
- }
-
- void set_pos(const Vector& pos) {
- this->pos = pos;
- }
- void set_pos(float x, float y) {
- set_pos(Vector(x, y));
- }
- const Vector& get_pos() const {
- return pos;
- }
- float get_pos_x() {
- return pos.x;
- }
- float get_pos_y() {
- return pos.y;
- }
-
- void set_anchor_point(int anchor) {
- set_anchor_point((AnchorPoint) anchor);
- }
- int get_anchor_point() {
- return (int) get_anchor_point();
- }
-
- void draw(DrawingContext& context);
- void update(float elapsed_time);
-
-private:
- Font* font;
- std::string text;
- float fading;
- float fadetime;
- bool visible;
- bool centered;
- AnchorPoint anchor;
- Vector pos;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux - Thunderstorm Game Object
-// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
-//
-// 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.
-
-#include <config.h>
-
-#include "thunderstorm.hpp"
-#include "scripting/squirrel_util.hpp"
-#include "audio/sound_manager.hpp"
-#include "video/drawing_context.hpp"
-#include "object_factory.hpp"
-#include "object/electrifier.hpp"
-
-#include <stdexcept>
-#include <iostream>
-#include "main.hpp"
-#include "resources.hpp"
-#include "sector.hpp"
-#include "gettext.hpp"
-#include "object/player.hpp"
-#include "lisp/list_iterator.hpp"
-#include "log.hpp"
-
-namespace {
- const float LIGHTNING_DELAY = 2.0f;
- const float FLASH_DISPLAY_TIME = 0.1f;
-}
-
-Thunderstorm::Thunderstorm(const lisp::Lisp& reader)
- : running(true), interval(10.0f)
-{
- reader.get("name", name);
- reader.get("running", running);
- reader.get("interval", interval);
- if(interval <= 0) {
- log_warning << "Running a thunderstorm with non-positive time interval is a bad idea" << std::endl;
- }
-
- sound_manager->preload("sounds/explosion.wav");
- sound_manager->preload("sounds/upgrade.wav");
-
- if (running) {
- running = false; // else start() is ignored
- start();
- }
-}
-
-void
-Thunderstorm::update(float )
-{
- if (!running) return;
- if (time_to_thunder.check()) {
- thunder();
- time_to_lightning.start(LIGHTNING_DELAY);
- }
- if (time_to_lightning.check()) {
- lightning();
- time_to_thunder.start(interval);
- }
-}
-
-void
-Thunderstorm::draw(DrawingContext& context)
-{
- if (!flash_display_timer.started()) return;
-
- float alpha = 0.33f;
- context.push_transform();
- context.set_translation(Vector(0, 0));
- context.draw_filled_rect(Vector(0, 0), Vector(SCREEN_WIDTH, SCREEN_HEIGHT), Color(1, 1, 1, alpha), LAYER_BACKGROUNDTILES-1);
- context.pop_transform();
-
-}
-
-void
-Thunderstorm::expose(HSQUIRRELVM vm, SQInteger table_idx)
-{
- if (name == "") return;
- Scripting::Thunderstorm* interface = new Scripting::Thunderstorm(this);
- expose_object(vm, table_idx, interface, name, true);
-}
-
-void
-Thunderstorm::unexpose(HSQUIRRELVM vm, SQInteger table_idx)
-{
- if (name == "") return;
- Scripting::unexpose_object(vm, table_idx, name);
-}
-
-void
-Thunderstorm::start()
-{
- if (running) return;
- running = true;
- time_to_thunder.start(interval);
- time_to_lightning.stop();
-}
-
-void
-Thunderstorm::stop()
-{
- if (!running) return;
- running = false;
- time_to_thunder.stop();
- time_to_lightning.stop();
-}
-
-void
-Thunderstorm::thunder()
-{
- sound_manager->play("sounds/explosion.wav");
-}
-
-void
-Thunderstorm::lightning()
-{
- flash();
- electrify();
-}
-
-void
-Thunderstorm::flash()
-{
- sound_manager->play("sounds/upgrade.wav");
- sound_manager->play("sounds/explosion.wav");
- flash_display_timer.start(FLASH_DISPLAY_TIME);
-}
-
-void
-Thunderstorm::electrify()
-{
- Sector::current()->add_object(new Electrifier(75, 1421, 0.5));
- Sector::current()->add_object(new Electrifier(76, 1422, 0.5));
-}
-
-IMPLEMENT_FACTORY(Thunderstorm, "thunderstorm");
+++ /dev/null
-// $Id$
-//
-// SuperTux - Thunderstorm Game Object
-// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
-//
-// 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.
-
-#ifndef __THUNDERSTORM_H__
-#define __THUNDERSTORM_H__
-
-#include "game_object.hpp"
-#include "timer.hpp"
-#include "lisp/lisp.hpp"
-#include "scripting/thunderstorm.hpp"
-#include "script_interface.hpp"
-
-/**
- * Thunderstorm scriptable GameObject; plays thunder, lightning and electrifies water at regular interval
- */
-class Thunderstorm : public GameObject, public ScriptInterface
-{
-public:
- Thunderstorm(const lisp::Lisp& reader);
-
- void update(float elapsed_time);
- void draw(DrawingContext& context);
-
- virtual void expose(HSQUIRRELVM vm, SQInteger table_idx);
- virtual void unexpose(HSQUIRRELVM vm, SQInteger table_idx);
-
- /**
- * @name Scriptable Methods
- * @{
- */
-
- /**
- * Start playing thunder and lightning at configured interval
- */
- void start();
-
- /**
- * Stop playing thunder and lightning at configured interval
- */
- void stop();
-
- /**
- * Play thunder
- */
- void thunder();
-
- /**
- * Play lightning, i.e. call flash() and electrify()
- */
- void lightning();
-
- /**
- * Display a nice flash
- */
- void flash();
-
- /**
- * Electrify water throughout the whole sector for a short time
- */
- void electrify();
-
- /**
- * @}
- */
-
-private:
- bool running; /**< whether we currently automatically trigger lightnings */
- float interval; /**< time between two lightnings */
-
- Timer time_to_thunder; /**< counts down until next thunder */
- Timer time_to_lightning; /**< counts down until next lightning */
- Timer flash_display_timer; /**< counts down while flash is displayed */
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include <cassert>
-#include <algorithm>
-#include <iostream>
-#include <stdexcept>
-#include <math.h>
-
-#include "tilemap.hpp"
-#include "video/drawing_context.hpp"
-#include "level.hpp"
-#include "tile.hpp"
-#include "resources.hpp"
-#include "tile_manager.hpp"
-#include "lisp/lisp.hpp"
-#include "lisp/writer.hpp"
-#include "object_factory.hpp"
-#include "main.hpp"
-#include "log.hpp"
-#include "scripting/tilemap.hpp"
-#include "scripting/squirrel_util.hpp"
-
-TileMap::TileMap()
- : solid(false), speed_x(1), speed_y(1), width(0), height(0), z_pos(0), x_offset(0), y_offset(0),
- drawing_effect(NO_EFFECT), alpha(1.0), current_alpha(1.0), remaining_fade_time(0),
- draw_target(DrawingContext::NORMAL)
-{
- tilemanager = tile_manager;
-}
-
-TileMap::TileMap(const lisp::Lisp& reader, TileManager* new_tile_manager)
- : solid(false), speed_x(1), speed_y(1), width(-1), height(-1), z_pos(0),
- x_offset(0), y_offset(0),
- drawing_effect(NO_EFFECT), alpha(1.0), current_alpha(1.0),
- remaining_fade_time(0),
- draw_target(DrawingContext::NORMAL)
-{
- tilemanager = new_tile_manager;
- if(tilemanager == 0)
- tilemanager = tile_manager;
-
- reader.get("name", name);
- reader.get("z-pos", z_pos);
- reader.get("solid", solid);
- reader.get("speed", speed_x);
- reader.get("speed-y", speed_y);
-
- if(solid && ((speed_x != 1) || (speed_y != 1))) {
- log_warning << "Speed of solid tilemap is not 1. fixing" << std::endl;
- speed_x = 1;
- speed_y = 1;
- }
-
- const lisp::Lisp* pathLisp = reader.get_lisp("path");
- if (pathLisp) {
- path.reset(new Path());
- path->read(*pathLisp);
- walker.reset(new PathWalker(path.get(), /*running*/false));
- Vector v = path->get_base();
- set_x_offset(v.x);
- set_y_offset(v.y);
- }
-
- std::string draw_target_s = "normal";
- reader.get("draw-target", draw_target_s);
- if (draw_target_s == "normal") draw_target = DrawingContext::NORMAL;
- if (draw_target_s == "lightmap") draw_target = DrawingContext::LIGHTMAP;
-
- if (reader.get("alpha", alpha)) {
- current_alpha = alpha;
- }
-
- reader.get("width", width);
- reader.get("height", height);
- if(width < 0 || height < 0)
- throw std::runtime_error("Invalid/No width/height specified in tilemap.");
-
- if(!reader.get_vector("tiles", tiles))
- throw std::runtime_error("No tiles in tilemap.");
-
- if(int(tiles.size()) != width*height) {
- throw std::runtime_error("wrong number of tiles in tilemap.");
- }
-
- // make sure all tiles are loaded
- for(Tiles::iterator i = tiles.begin(); i != tiles.end(); ++i)
- tilemanager->get(*i);
-}
-
-TileMap::TileMap(std::string name, int z_pos, bool solid, size_t width, size_t height)
- : solid(solid), speed_x(1), speed_y(1), width(0), height(0), z_pos(z_pos),
- x_offset(0), y_offset(0), drawing_effect(NO_EFFECT), alpha(1.0),
- current_alpha(1.0), remaining_fade_time(0),
- draw_target(DrawingContext::NORMAL)
-{
- this->name = name;
- tilemanager = tile_manager;
-
- resize(width, height);
-}
-
-TileMap::~TileMap()
-{
-}
-
-void
-TileMap::write(lisp::Writer& writer)
-{
- writer.start_list("tilemap");
-
- writer.write_int("z-pos", z_pos);
-
- writer.write_bool("solid", solid);
- writer.write_float("speed", speed_x);
- writer.write_float("speed-y", speed_y);
- writer.write_int("width", width);
- writer.write_int("height", height);
- writer.write_int_vector("tiles", tiles);
-
- writer.end_list("tilemap");
-}
-
-void
-TileMap::update(float elapsed_time)
-{
- // handle tilemap fading
- if (current_alpha != alpha) {
- remaining_fade_time = std::max(0.0f, remaining_fade_time - elapsed_time);
- if (remaining_fade_time == 0.0f) {
- current_alpha = alpha;
- } else {
- float amt = (alpha - current_alpha) / (remaining_fade_time / elapsed_time);
- if (amt > 0) current_alpha = std::min(current_alpha + amt, alpha);
- if (amt < 0) current_alpha = std::max(current_alpha + amt, alpha);
- }
- if ((alpha < 0.25) && (current_alpha < 0.25)) set_solid(false);
- if ((alpha > 0.75) && (current_alpha > 0.75)) set_solid(true);
- }
-
- // if we have a path to follow, follow it
- if (walker.get()) {
- Vector v = walker->advance(elapsed_time);
- set_x_offset(v.x);
- set_y_offset(v.y);
- }
-}
-
-void
-TileMap::draw(DrawingContext& context)
-{
- // skip draw if current opacity is set to 0.0
- if (current_alpha == 0.0) return;
-
- context.push_transform();
- context.push_target();
- context.set_target(draw_target);
-
- if(drawing_effect != 0) context.set_drawing_effect(drawing_effect);
- if(current_alpha != 1.0) context.set_alpha(current_alpha);
-
- float trans_x = roundf(context.get_translation().x);
- float trans_y = roundf(context.get_translation().y);
- context.set_translation(Vector(trans_x * speed_x, trans_y * speed_y));
-
- /** if we don't round here, we'll have a 1 pixel gap on screen sometimes.
- * I have no idea why */
- float start_x = int((roundf(context.get_translation().x) - roundf(x_offset)) / 32) * 32 + roundf(x_offset);
- float start_y = int((roundf(context.get_translation().y) - roundf(y_offset)) / 32) * 32 + roundf(y_offset);
- float end_x = std::min(start_x + SCREEN_WIDTH + 32, float(width * 32 + roundf(x_offset)));
- float end_y = std::min(start_y + SCREEN_HEIGHT + 32, float(height * 32 + roundf(y_offset)));
- int tsx = int((start_x - roundf(x_offset)) / 32); // tilestartindex x
- int tsy = int((start_y - roundf(y_offset)) / 32); // tilestartindex y
-
- Vector pos;
- int tx, ty;
- for(pos.x = start_x, tx = tsx; pos.x < end_x; pos.x += 32, ++tx) {
- for(pos.y = start_y, ty = tsy; pos.y < end_y; pos.y += 32, ++ty) {
- if ((tx < 0) || (ty < 0)) continue;
- const Tile* tile = tilemanager->get(tiles[ty*width + tx]);
- assert(tile != 0);
- tile->draw(context, pos, z_pos);
- }
- }
-
- context.pop_target();
- context.pop_transform();
-}
-
-void
-TileMap::goto_node(int node_no)
-{
- if (!walker.get()) return;
- walker->goto_node(node_no);
-}
-
-void
-TileMap::start_moving()
-{
- if (!walker.get()) return;
- walker->start_moving();
-}
-
-void
-TileMap::stop_moving()
-{
- if (!walker.get()) return;
- walker->stop_moving();
-}
-
-void
-TileMap::expose(HSQUIRRELVM vm, SQInteger table_idx)
-{
- if (name.empty()) return;
- Scripting::TileMap* interface = new Scripting::TileMap(this);
- expose_object(vm, table_idx, interface, name, true);
-}
-
-void
-TileMap::unexpose(HSQUIRRELVM vm, SQInteger table_idx)
-{
- if (name.empty()) return;
- Scripting::unexpose_object(vm, table_idx, name);
-}
-
-void
-TileMap::set(int newwidth, int newheight, const std::vector<unsigned int>&newt,
- int new_z_pos, bool newsolid)
-{
- if(int(newt.size()) != newwidth * newheight)
- throw std::runtime_error("Wrong tilecount count.");
-
- width = newwidth;
- height = newheight;
-
- tiles.resize(newt.size());
- tiles = newt;
-
- z_pos = new_z_pos;
- solid = newsolid;
-
- // make sure all tiles are loaded
- for(Tiles::iterator i = tiles.begin(); i != tiles.end(); ++i)
- tilemanager->get(*i);
-}
-
-void
-TileMap::resize(int new_width, int new_height, int fill_id)
-{
- if(new_width < width) {
- // remap tiles for new width
- for(int y = 0; y < height && y < new_height; ++y) {
- for(int x = 0; x < new_width; ++x) {
- tiles[y * new_width + x] = tiles[y * width + x];
- }
- }
- }
-
- tiles.resize(new_width * new_height, fill_id);
-
- if(new_width > width) {
- // remap tiles
- for(int y = std::min(height, new_height)-1; y >= 0; --y) {
- for(int x = new_width-1; x >= 0; --x) {
- if(x >= width) {
- tiles[y * new_width + x] = fill_id;
- continue;
- }
-
- tiles[y * new_width + x] = tiles[y * width + x];
- }
- }
- }
-
- height = new_height;
- width = new_width;
-}
-
-void
-TileMap::set_solid(bool solid)
-{
- this->solid = solid;
-}
-
-const Tile*
-TileMap::get_tile(int x, int y) const
-{
- if(x < 0 || x >= width || y < 0 || y >= height) {
- //log_warning << "tile outside tilemap requested" << std::endl;
- return tilemanager->get(0);
- }
-
- return tilemanager->get(tiles[y*width + x]);
-}
-
-const Tile*
-TileMap::get_tile_at(const Vector& pos) const
-{
- return get_tile(int(pos.x - x_offset)/32, int(pos.y - y_offset)/32);
-}
-
-void
-TileMap::change(int x, int y, uint32_t newtile)
-{
- assert(x >= 0 && x < width && y >= 0 && y < height);
- tiles[y*width + x] = newtile;
-}
-
-void
-TileMap::change_at(const Vector& pos, uint32_t newtile)
-{
- change(int(pos.x - x_offset)/32, int(pos.y - y_offset)/32, newtile);
-}
-
-void
-TileMap::change_all(uint32_t oldtile, uint32_t newtile)
-{
- for (size_t x = 0; x < get_width(); x++)
- for (size_t y = 0; y < get_height(); y++) {
- if (get_tile(x,y)->getID() == oldtile) change(x,y,newtile);
- }
-}
-
-void
-TileMap::fade(float alpha, float seconds)
-{
- this->alpha = alpha;
- this->remaining_fade_time = seconds;
-}
-
-
-void
-TileMap::set_alpha(float alpha)
-{
- this->alpha = alpha;
- this->current_alpha = alpha;
- this->remaining_fade_time = 0;
- if (current_alpha < 0.25) set_solid(false);
- if (current_alpha > 0.75) set_solid(true);
-}
-
-float
-TileMap::get_alpha()
-{
- return this->current_alpha;
-}
-
-IMPLEMENT_FACTORY(TileMap, "tilemap");
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef SUPERTUX_TILEMAP_H
-#define SUPERTUX_TILEMAP_H
-
-#include <vector>
-#include <stdint.h>
-#include <string>
-
-#include "game_object.hpp"
-#include "serializable.hpp"
-#include "math/vector.hpp"
-#include "video/drawing_context.hpp"
-#include "object/path.hpp"
-#include "object/path_walker.hpp"
-#include "script_interface.hpp"
-
-namespace lisp {
-class Lisp;
-}
-
-class Level;
-class TileManager;
-class Tile;
-
-/**
- * This class is reponsible for drawing the level tiles
- */
-class TileMap : public GameObject, public Serializable, public ScriptInterface
-{
-public:
- TileMap();
- TileMap(const lisp::Lisp& reader, TileManager* tile_manager = 0);
- TileMap(std::string name, int z_pos, bool solid_, size_t width_, size_t height_);
- virtual ~TileMap();
-
- virtual void write(lisp::Writer& writer);
-
- virtual void update(float elapsed_time);
- virtual void draw(DrawingContext& context);
-
- /** Move tilemap until at given node, then stop */
- void goto_node(int node_no);
-
- /** Start moving tilemap */
- void start_moving();
-
- /** Stop tilemap at next node */
- void stop_moving();
-
- virtual void expose(HSQUIRRELVM vm, SQInteger table_idx);
- virtual void unexpose(HSQUIRRELVM vm, SQInteger table_idx);
-
- void set(int width, int height, const std::vector<unsigned int>& vec,
- int z_pos, bool solid);
-
- /** resizes the tilemap to a new width and height (tries to not destroy the
- * existing map)
- */
- void resize(int newwidth, int newheight, int fill_id = 0);
-
- size_t get_width() const
- { return width; }
-
- size_t get_height() const
- { return height; }
-
- float get_x_offset() const
- { return x_offset; }
-
- float get_y_offset() const
- { return y_offset; }
-
- void set_x_offset(float x_offset)
- { this->x_offset = x_offset; }
-
- void set_y_offset(float y_offset)
- { this->y_offset = y_offset; }
-
- int get_layer() const
- { return z_pos; }
-
- bool is_solid() const
- { return solid; }
-
- /**
- * Changes Tilemap's solidity, i.e. whether to consider it when doing collision detection.
- */
- void set_solid(bool solid = true);
-
- /// returns tile in row y and column y (of the tilemap)
- const Tile* get_tile(int x, int y) const;
- /// returns tile at position pos (in world coordinates)
- const Tile* get_tile_at(const Vector& pos) const;
-
- void change(int x, int y, uint32_t newtile);
-
- void change_at(const Vector& pos, uint32_t newtile);
-
- /// changes all tiles with the given ID
- void change_all(uint32_t oldtile, uint32_t newtile);
-
- TileManager* get_tilemanager() const
- {
- return tilemanager;
- }
-
- void set_drawing_effect(DrawingEffect effect)
- {
- drawing_effect = effect;
- }
-
- DrawingEffect get_drawing_effect()
- {
- return drawing_effect;
- }
-
- /**
- * Start fading the tilemap to opacity given by @c alpha.
- * Destination opacity will be reached after @c seconds seconds. Also influences solidity.
- */
- void fade(float alpha, float seconds = 0);
-
- /**
- * Instantly switch tilemap's opacity to @c alpha. Also influences solidity.
- */
- void set_alpha(float alpha);
-
- /**
- * Return tilemap's opacity. Note that while the tilemap is fading in or out, this will return the current alpha value, not the target alpha.
- */
- float get_alpha();
-
-private:
- typedef std::vector<uint32_t> Tiles;
- Tiles tiles;
-
-private:
- TileManager* tilemanager;
- bool solid;
- float speed_x;
- float speed_y;
- int width, height;
- int z_pos;
- float x_offset;
- float y_offset;
-
- DrawingEffect drawing_effect;
- float alpha; /**< requested tilemap opacity */
- float current_alpha; /**< current tilemap opacity */
- float remaining_fade_time; /**< seconds until requested tilemap opacity is reached */
-
- std::auto_ptr<Path> path;
- std::auto_ptr<PathWalker> walker;
-
- DrawingContext::Target draw_target; /**< set to LIGHTMAP to draw to lightmap */
-};
-
-#endif /*SUPERTUX_TILEMAP_H*/
+++ /dev/null
-// $Id$
-//
-// SuperTux - Trampoline
-// Copyright (C) 2006 Wolfgang Becker <uafr@gmx.de>
-//
-// 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.
-
-#include <config.h>
-
-#include "trampoline.hpp"
-#include "object_factory.hpp"
-#include "player.hpp"
-#include "audio/sound_manager.hpp"
-#include "sprite/sprite_manager.hpp"
-#include "badguy/walking_badguy.hpp"
-
-/* Trampoline will accelerate player to to VY_INITIAL, if
- * he jumps on it to VY_MIN. */
-namespace {
- const std::string TRAMPOLINE_SOUND = "sounds/trampoline.wav";
- const float VY_MIN = -900; //negative, upwards
- const float VY_INITIAL = -500;
-}
-
-Trampoline::Trampoline(const lisp::Lisp& lisp)
- : Rock(lisp, "images/objects/trampoline/trampoline.sprite")
-{
- sound_manager->preload(TRAMPOLINE_SOUND);
-
- portable = true;
- //Check if this trampoline is not portable
- if(lisp.get("portable", portable)) {
- if(!portable) {
- //we need another sprite
- sprite_name = "images/objects/trampoline/trampoline_fix.sprite";
- sprite = sprite_manager->create(sprite_name);
- sprite->set_action("normal");
- }
- }
-}
-
-void
-Trampoline::update(float elapsed_time)
-{
- if(sprite->animation_done()) {
- sprite->set_action("normal");
- }
-
- Rock::update(elapsed_time);
-}
-
-HitResponse
-Trampoline::collision(GameObject& other, const CollisionHit& hit)
-{
-
- //Tramponine has to be on ground to work.
- if(on_ground) {
- Player* player = dynamic_cast<Player*> (&other);
- //Trampoline works for player
- if(player) {
- float vy = player->physic.get_velocity_y();
- //player is falling down on trampoline
- if(hit.top && vy >= 0) {
- if(player->get_controller()->hold(Controller::JUMP)) {
- vy = VY_MIN;
- } else {
- vy = VY_INITIAL;
- }
- player->physic.set_velocity_y(vy);
- sound_manager->play(TRAMPOLINE_SOUND);
- sprite->set_action("swinging", 1);
- return FORCE_MOVE;
- }
- }
- WalkingBadguy* walking_badguy = dynamic_cast<WalkingBadguy*> (&other);
- //Trampoline also works for WalkingBadguy
- if(walking_badguy) {
- float vy = walking_badguy->get_velocity_y();
- //walking_badguy is falling down on trampoline
- if(hit.top && vy >= 0) {
- vy = VY_INITIAL;
- walking_badguy->set_velocity_y(vy);
- sound_manager->play(TRAMPOLINE_SOUND);
- sprite->set_action("swinging", 1);
- return FORCE_MOVE;
- }
- }
- }
-
- return Rock::collision(other, hit);
-}
-
-void
-Trampoline::collision_solid(const CollisionHit& hit) {
- Rock::collision_solid(hit);
-}
-
-void
-Trampoline::grab(MovingObject& object, const Vector& pos, Direction dir) {
- sprite->set_animation_loops(0);
- Rock::grab(object, pos, dir);
-}
-
-void
-Trampoline::ungrab(MovingObject& object, Direction dir) {
- Rock::ungrab(object, dir);
-}
-
-bool
-Trampoline::is_portable() const
-{
- return Rock::is_portable() && portable;
-}
-
-IMPLEMENT_FACTORY(Trampoline, "trampoline");
+++ /dev/null
-// $Id$
-//
-// SuperTux - Trampolin
-// Copyright (C) 2006 Wolfgang Becker <uafr@gmx.de>
-//
-// 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.
-
-#ifndef SUPERTUX_TRAMPOLINE_H
-#define SUPERTUX_TRAMPOLINE_H
-
-#include "moving_sprite.hpp"
-#include "lisp/lisp.hpp"
-#include "object/rock.hpp"
-
-/**
- * Jumping on a trampolin makes tux jump higher.
- */
-class Trampoline : public Rock
-{
-public:
- Trampoline(const lisp::Lisp& reader);
-
- HitResponse collision(GameObject& other, const CollisionHit& hit);
- void collision_solid(const CollisionHit& hit);
- void update(float elapsed_time);
-
- void grab(MovingObject&, const Vector& pos, Direction);
- void ungrab(MovingObject&, Direction);
- bool is_portable() const;
-
-private:
- bool portable;
-
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux - Unstable Tile
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
-//
-// 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.
-
-#include <config.h>
-
-#include "unstable_tile.hpp"
-#include "lisp/lisp.hpp"
-#include "object_factory.hpp"
-#include "player.hpp"
-#include "sector.hpp"
-#include "resources.hpp"
-#include "sprite/sprite.hpp"
-#include "random_generator.hpp"
-#include "object/bullet.hpp"
-
-UnstableTile::UnstableTile(const lisp::Lisp& lisp)
- : MovingSprite(lisp, LAYER_TILES, COLGROUP_STATIC), state(STATE_NORMAL)
-{
- sprite->set_action("normal");
-}
-
-HitResponse
-UnstableTile::collision(GameObject& other, const CollisionHit& )
-{
- if(state == STATE_NORMAL) {
- Player* player = dynamic_cast<Player*> (&other);
- if(player != NULL &&
- player->get_bbox().get_bottom() < get_bbox().get_top() + 7.0) {
- state = STATE_CRUMBLING;
- sprite->set_action("crumbling", 1);
- }
- }
- return SOLID;
-}
-
-void
-UnstableTile::update(float elapsed_time)
-{
- switch (state) {
-
- case STATE_NORMAL:
- break;
-
- case STATE_CRUMBLING:
- if (sprite->animation_done()) {
- state = STATE_DISINTEGRATING;
- sprite->set_action("disintegrating", 1);
- set_group(COLGROUP_DISABLED);
- physic.enable_gravity(true);
- }
- break;
-
- case STATE_DISINTEGRATING:
- movement = physic.get_movement(elapsed_time);
- if (sprite->animation_done()) {
- remove_me();
- return;
- }
- break;
- }
-}
-
-IMPLEMENT_FACTORY(UnstableTile, "unstable_tile");
+++ /dev/null
-// $Id$
-//
-// SuperTux - Unstable Tile
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
-//
-// 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.
-
-#ifndef __UNSTABLE_TILE_H__
-#define __UNSTABLE_TILE_H__
-
-#include "object/moving_sprite.hpp"
-#include "lisp/lisp.hpp"
-#include "physic.hpp"
-#include "timer.hpp"
-
-/**
- * A block that disintegrates when stood on
- */
-class UnstableTile : public MovingSprite, public UsesPhysic
-{
-public:
- UnstableTile(const lisp::Lisp& lisp);
- virtual UnstableTile* clone() const { return new UnstableTile(*this); }
-
- HitResponse collision(GameObject& other, const CollisionHit& hit);
- void update(float elapsed_time);
-
-private:
- enum State {
- STATE_NORMAL, /**< default state */
- STATE_CRUMBLING, /**< crumbling, still solid */
- STATE_DISINTEGRATING /**< disintegrating, no longer solid */
- };
- State state;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux - Weak Block
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
-//
-// 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.
-
-#include <config.h>
-
-#include "weak_block.hpp"
-#include "lisp/lisp.hpp"
-#include "object_factory.hpp"
-#include "player.hpp"
-#include "sector.hpp"
-#include "resources.hpp"
-#include "sprite/sprite.hpp"
-#include "random_generator.hpp"
-#include "object/bullet.hpp"
-
-WeakBlock::WeakBlock(const lisp::Lisp& lisp)
- : MovingSprite(lisp, "images/objects/strawbox/strawbox.sprite", LAYER_TILES, COLGROUP_STATIC), state(STATE_NORMAL)
-{
- sprite->set_action("normal");
-}
-
-HitResponse
-WeakBlock::collision(GameObject& other, const CollisionHit& )
-{
- switch (state) {
-
- case STATE_NORMAL:
- if (dynamic_cast<Bullet*>(&other)) {
- startBurning();
- return FORCE_MOVE;
- }
- return FORCE_MOVE;
- break;
-
- case STATE_BURNING:
- return FORCE_MOVE;
- break;
-
- case STATE_DISINTEGRATING:
- return FORCE_MOVE;
- break;
-
- }
-
- log_debug << "unhandled state" << std::endl;
- return FORCE_MOVE;
-}
-
-void
-WeakBlock::update(float )
-{
- switch (state) {
-
- case STATE_NORMAL:
- break;
-
- case STATE_BURNING:
- if (sprite->animation_done()) {
- state = STATE_DISINTEGRATING;
- sprite->set_action("disintegrating", 1);
- spreadHit();
- set_group(COLGROUP_DISABLED);
- }
- break;
-
- case STATE_DISINTEGRATING:
- if (sprite->animation_done()) {
- remove_me();
- return;
- }
- break;
-
- }
-}
-
-void
-WeakBlock::startBurning()
-{
- if (state != STATE_NORMAL) return;
- state = STATE_BURNING;
- sprite->set_action("burning", 1);
-}
-
-void
-WeakBlock::spreadHit()
-{
- Sector* sector = Sector::current();
- if (!sector) {
- log_debug << "no current sector" << std::endl;
- return;
- }
- for(Sector::GameObjects::iterator i = sector->gameobjects.begin(); i != sector->gameobjects.end(); ++i) {
- WeakBlock* wb = dynamic_cast<WeakBlock*>(*i);
- if (!wb) continue;
- if (wb == this) continue;
- if (wb->state != STATE_NORMAL) continue;
- float dx = fabsf(wb->get_pos().x - this->get_pos().x);
- float dy = fabsf(wb->get_pos().y - this->get_pos().y);
- if ((dx <= 32.5) && (dy <= 32.5)) wb->startBurning();
- }
-}
-
-
-IMPLEMENT_FACTORY(WeakBlock, "weak_block");
+++ /dev/null
-// $Id$
-//
-// SuperTux - Weak Block
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
-//
-// 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.
-
-#ifndef __WEAK_BLOCK_H__
-#define __WEAK_BLOCK_H__
-
-#include "object/moving_sprite.hpp"
-#include "lisp/lisp.hpp"
-#include "physic.hpp"
-#include "timer.hpp"
-
-/**
- * A block that can be destroyed by Bullet hits
- */
-class WeakBlock : public MovingSprite, public UsesPhysic
-{
-public:
- WeakBlock(const lisp::Lisp& lisp);
-
- HitResponse collision(GameObject& other, const CollisionHit& hit);
- void update(float elapsed_time);
-
-protected:
- /**
- * called by self when hit by a bullet
- */
- void startBurning();
-
- /**
- * pass hit to nearby WeakBlock objects
- */
- void spreadHit();
-
-private:
- enum State {
- STATE_NORMAL, /**< default state */
- STATE_BURNING, /**< on fire, still solid */
- STATE_DISINTEGRATING /**< crumbling to dust, no longer solid */
- };
- State state;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux - Wind
-// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
-//
-// 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.
-
-#include <config.h>
-
-#include "wind.hpp"
-#include "video/drawing_context.hpp"
-#include "object/player.hpp"
-#include "object_factory.hpp"
-#include "random_generator.hpp"
-#include "sector.hpp"
-#include "particles.hpp"
-#include "scripting/wind.hpp"
-#include "scripting/squirrel_util.hpp"
-
-Wind::Wind(const lisp::Lisp& reader)
- : blowing(true), acceleration(100), elapsed_time(0)
-{
- reader.get("name", name);
- reader.get("x", bbox.p1.x);
- reader.get("y", bbox.p1.y);
- float w = 32, h = 32;
- reader.get("width", w);
- reader.get("height", h);
- bbox.set_size(w, h);
-
- reader.get("blowing", blowing);
-
- float speed_x = 0, speed_y = 0;
- reader.get("speed-x", speed_x);
- reader.get("speed-y", speed_y);
- speed = Vector(speed_x, speed_y);
-
- reader.get("acceleration", acceleration);
-
- set_group(COLGROUP_TOUCHABLE);
-}
-
-void
-Wind::update(float elapsed_time)
-{
- this->elapsed_time = elapsed_time;
-
- if (!blowing) return;
-
- // TODO: nicer, configurable particles for wind?
- if (systemRandom.rand(0, 100) < 20) {
- // emit a particle
- Vector ppos = Vector(systemRandom.randf(bbox.p1.x+8, bbox.p2.x-8), systemRandom.randf(bbox.p1.y+8, bbox.p2.y-8));
- Vector pspeed = Vector(speed.x, speed.y);
- Sector::current()->add_object(new Particles(ppos, 44, 46, pspeed, Vector(0,0), 1, Color(.4f, .4f, .4f), 3, .1f, LAYER_BACKGROUNDTILES+1));
- }
-}
-
-void
-Wind::draw(DrawingContext& )
-{
-}
-
-HitResponse
-Wind::collision(GameObject& other, const CollisionHit& )
-{
- if (!blowing) return ABORT_MOVE;
-
- Player* player = dynamic_cast<Player*> (&other);
- if (player) {
- if (!player->on_ground()) {
- player->add_velocity(speed * acceleration * elapsed_time, speed);
- }
- }
-
- return ABORT_MOVE;
-}
-
-void
-Wind::expose(HSQUIRRELVM vm, SQInteger table_idx)
-{
- if (name == "")
- return;
-
- Scripting::Wind* interface = new Scripting::Wind(this);
- expose_object(vm, table_idx, interface, name, true);
-}
-
-void
-Wind::unexpose(HSQUIRRELVM vm, SQInteger table_idx)
-{
- if (name == "")
- return;
-
- Scripting::unexpose_object(vm, table_idx, name);
-}
-
-void
-Wind::start()
-{
- blowing = true;
-}
-
-void
-Wind::stop()
-{
- blowing = false;
-}
-
-IMPLEMENT_FACTORY(Wind, "wind");
+++ /dev/null
-// $Id$
-//
-// SuperTux - Wind
-// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
-//
-// 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.
-
-#ifndef SUPERTUX_WIND_H
-#define SUPERTUX_WIND_H
-
-#include <set>
-#include "moving_object.hpp"
-#include "math/rect.hpp"
-#include "sprite/sprite.hpp"
-#include "script_interface.hpp"
-
-class Player;
-
-/**
- * Defines an area that will gently push Players in one direction
- */
-class Wind : public MovingObject, public ScriptInterface
-{
-public:
- Wind(const lisp::Lisp& reader);
-
- void update(float elapsed_time);
- void draw(DrawingContext& context);
- HitResponse collision(GameObject& other, const CollisionHit& hit);
-
- /**
- * @name Scriptable Methods
- * @{
- */
-
- /**
- * start blowing
- */
- void start();
-
- /**
- * stop blowing
- */
- void stop();
-
- /**
- * @}
- */
-
- virtual void expose(HSQUIRRELVM vm, SQInteger table_idx);
- virtual void unexpose(HSQUIRRELVM vm, SQInteger table_idx);
-
-private:
- bool blowing; /**< true if wind is currently switched on */
- Vector speed;
- float acceleration;
-
- float elapsed_time; /**< stores last elapsed_time gotten at update() */
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2004 Ricardo Cruz <rick2@aeiou.pt>
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#include <config.h>
-
-#include <sstream>
-#include <stdexcept>
-
-#include "lisp/lisp.hpp"
-#include "lisp/parser.hpp"
-#include "object_factory.hpp"
-#include "math/vector.hpp"
-
-GameObject* create_object(const std::string& name, const lisp::Lisp& reader)
-{
- Factory::Factories::iterator i = Factory::get_factories().find(name);
- if(i == Factory::get_factories().end()) {
- std::stringstream msg;
- msg << "No factory for object '" << name << "' found.";
- throw std::runtime_error(msg.str());
- }
-
- return i->second->create_object(reader);
-}
-
-GameObject* create_object(const std::string& name, const Vector& pos)
-{
- std::stringstream lisptext;
- lisptext << "(" << name
- << " (x " << pos.x << ")"
- << " (y " << pos.y << "))";
-
- lisp::Parser parser;
- const lisp::Lisp* lisp = parser.parse(lisptext, "create_object");
- GameObject* object = create_object(name, *lisp);
-
- return object;
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2004 Ricardo Cruz <rick2@aeiou.pt>
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#ifndef OBJECT_FACTORY_H
-#define OBJECT_FACTORY_H
-
-#include <string>
-#include <map>
-
-namespace lisp { class Lisp; }
-class Vector;
-class GameObject;
-
-class Factory
-{
-public:
- virtual ~Factory()
- { }
-
- /** Creates a new gameobject from a lisp node.
- * Remember to delete the objects later
- */
- virtual GameObject* create_object(const lisp::Lisp& reader) = 0;
-
- typedef std::map<std::string, Factory*> Factories;
- static Factories &get_factories()
- {
- static Factories object_factories;
- return object_factories;
- }
-};
-
-GameObject* create_object(const std::string& name, const lisp::Lisp& reader);
-GameObject* create_object(const std::string& name, const Vector& pos);
-
-/** comment from Matze:
- * Yes I know macros are evil, but in this specific case they save
- * A LOT of typing and evil code duplication.
- * I'll happily accept alternatives if someone can present me one that does
- * not involve typing 4 or more lines for each object class
- */
-#define IMPLEMENT_FACTORY(CLASS, NAME) \
-class INTERN_##CLASS##Factory : public Factory \
-{ \
-public: \
- INTERN_##CLASS##Factory() \
- { \
- get_factories()[NAME] = this; \
- } \
- \
- ~INTERN_##CLASS##Factory() \
- { \
- get_factories().erase(NAME); \
- } \
- \
- virtual GameObject* create_object(const lisp::Lisp& reader) \
- { \
- return new CLASS(reader); \
- } \
-}; \
-static INTERN_##CLASS##Factory factory_##CLASS;
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __OBJECT_REMOVE_LISTENER_H__
-#define __OBJECT_REMOVE_LISTENER_H__
-
-class GameObject;
-
-class ObjectRemoveListener
-{
-public:
- virtual ~ObjectRemoveListener()
- {}
-
- virtual void object_removed(GameObject* object) = 0;
-};
-
-#endif
+++ /dev/null
-/* obstack.c - subroutines used implicitly by object stack macros
- Copyright (C) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1996, 1997, 1998,
- 1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
- This file is part of the GNU C Library.
-
- The GNU C Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- The GNU C Library 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
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with the GNU C Library; if not, write to the Free
- Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- Boston, MA 02110-1301, USA. */
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-
-#include "obstack.h"
-
-/* NOTE BEFORE MODIFYING THIS FILE: This version number must be
- incremented whenever callers compiled using an old obstack.h can no
- longer properly call the functions in this obstack.c. */
-#define OBSTACK_INTERFACE_VERSION 1
-
-#include <stdio.h> /* Random thing to get __GNU_LIBRARY__. */
-#include <stddef.h>
-#include <stdint.h>
-
-/* Determine default alignment. */
-union fooround
-{
- uintmax_t i;
- long double d;
- void *p;
-};
-struct fooalign
-{
- char c;
- union fooround u;
-};
-/* If malloc were really smart, it would round addresses to DEFAULT_ALIGNMENT.
- But in fact it might be less smart and round addresses to as much as
- DEFAULT_ROUNDING. So we prepare for it to do that. */
-enum
- {
- DEFAULT_ALIGNMENT = offsetof (struct fooalign, u),
- DEFAULT_ROUNDING = sizeof (union fooround)
- };
-
-/* When we copy a long block of data, this is the unit to do it with.
- On some machines, copying successive ints does not work;
- in such a case, redefine COPYING_UNIT to `long' (if that works)
- or `char' as a last resort. */
-# ifndef COPYING_UNIT
-# define COPYING_UNIT int
-# endif
-
-
-/* The functions allocating more room by calling `obstack_chunk_alloc'
- jump to the handler pointed to by `obstack_alloc_failed_handler'.
- This can be set to a user defined function which should either
- abort gracefully or use longjump - but shouldn't return. This
- variable by default points to the internal function
- `print_and_abort'. */
-static void print_and_abort (void);
-void (*obstack_alloc_failed_handler) (void) = print_and_abort;
-
-/* Exit value used when `print_and_abort' is used. */
-# include <stdlib.h>
-int obstack_exit_failure = EXIT_FAILURE;
-
-/* Define a macro that either calls functions with the traditional malloc/free
- calling interface, or calls functions with the mmalloc/mfree interface
- (that adds an extra first argument), based on the state of use_extra_arg.
- For free, do not use ?:, since some compilers, like the MIPS compilers,
- do not allow (expr) ? void : void. */
-
-# define CALL_CHUNKFUN(h, size) \
- (((h) -> use_extra_arg) \
- ? (*(h)->chunkfun) ((h)->extra_arg, (size)) \
- : (*(struct _obstack_chunk *(*) (long)) (h)->chunkfun) ((size)))
-
-# define CALL_FREEFUN(h, old_chunk) \
- do { \
- if ((h) -> use_extra_arg) \
- (*(h)->freefun) ((h)->extra_arg, (old_chunk)); \
- else \
- (*(void (*) (void *)) (h)->freefun) ((old_chunk)); \
- } while (0)
-
-\f
-/* Initialize an obstack H for use. Specify chunk size SIZE (0 means default).
- Objects start on multiples of ALIGNMENT (0 means use default).
- CHUNKFUN is the function to use to allocate chunks,
- and FREEFUN the function to free them.
-
- Return nonzero if successful, calls obstack_alloc_failed_handler if
- allocation fails. */
-
-int
-_obstack_begin (struct obstack *h,
- int size, int alignment,
- void *(*chunkfun) (long),
- void (*freefun) (void *))
-{
- register struct _obstack_chunk *chunk; /* points to new chunk */
-
- if (alignment == 0)
- alignment = DEFAULT_ALIGNMENT;
- if (size == 0)
- /* Default size is what GNU malloc can fit in a 4096-byte block. */
- {
- /* 12 is sizeof (mhead) and 4 is EXTRA from GNU malloc.
- Use the values for range checking, because if range checking is off,
- the extra bytes won't be missed terribly, but if range checking is on
- and we used a larger request, a whole extra 4096 bytes would be
- allocated.
-
- These number are irrelevant to the new GNU malloc. I suspect it is
- less sensitive to the size of the request. */
- int extra = ((((12 + DEFAULT_ROUNDING - 1) & ~(DEFAULT_ROUNDING - 1))
- + 4 + DEFAULT_ROUNDING - 1)
- & ~(DEFAULT_ROUNDING - 1));
- size = 4096 - extra;
- }
-
- h->chunkfun = (struct _obstack_chunk * (*)(void *, long)) chunkfun;
- h->freefun = (void (*) (void *, struct _obstack_chunk *)) freefun;
- h->chunk_size = size;
- h->alignment_mask = alignment - 1;
- h->use_extra_arg = 0;
-
- chunk = h->chunk = CALL_CHUNKFUN (h, h -> chunk_size);
- if (!chunk)
- (*obstack_alloc_failed_handler) ();
- h->next_free = h->object_base = __PTR_ALIGN ((char *) chunk, chunk->contents,
- alignment - 1);
- h->chunk_limit = chunk->limit
- = (char *) chunk + h->chunk_size;
- chunk->prev = 0;
- /* The initial chunk now contains no empty object. */
- h->maybe_empty_object = 0;
- h->alloc_failed = 0;
- return 1;
-}
-
-int
-_obstack_begin_1 (struct obstack *h, int size, int alignment,
- void *(*chunkfun) (void *, long),
- void (*freefun) (void *, void *),
- void *arg)
-{
- register struct _obstack_chunk *chunk; /* points to new chunk */
-
- if (alignment == 0)
- alignment = DEFAULT_ALIGNMENT;
- if (size == 0)
- /* Default size is what GNU malloc can fit in a 4096-byte block. */
- {
- /* 12 is sizeof (mhead) and 4 is EXTRA from GNU malloc.
- Use the values for range checking, because if range checking is off,
- the extra bytes won't be missed terribly, but if range checking is on
- and we used a larger request, a whole extra 4096 bytes would be
- allocated.
-
- These number are irrelevant to the new GNU malloc. I suspect it is
- less sensitive to the size of the request. */
- int extra = ((((12 + DEFAULT_ROUNDING - 1) & ~(DEFAULT_ROUNDING - 1))
- + 4 + DEFAULT_ROUNDING - 1)
- & ~(DEFAULT_ROUNDING - 1));
- size = 4096 - extra;
- }
-
- h->chunkfun = (struct _obstack_chunk * (*)(void *,long)) chunkfun;
- h->freefun = (void (*) (void *, struct _obstack_chunk *)) freefun;
- h->chunk_size = size;
- h->alignment_mask = alignment - 1;
- h->extra_arg = arg;
- h->use_extra_arg = 1;
-
- chunk = h->chunk = CALL_CHUNKFUN (h, h -> chunk_size);
- if (!chunk)
- (*obstack_alloc_failed_handler) ();
- h->next_free = h->object_base = __PTR_ALIGN ((char *) chunk, chunk->contents,
- alignment - 1);
- h->chunk_limit = chunk->limit
- = (char *) chunk + h->chunk_size;
- chunk->prev = 0;
- /* The initial chunk now contains no empty object. */
- h->maybe_empty_object = 0;
- h->alloc_failed = 0;
- return 1;
-}
-
-/* Allocate a new current chunk for the obstack *H
- on the assumption that LENGTH bytes need to be added
- to the current object, or a new object of length LENGTH allocated.
- Copies any partial object from the end of the old chunk
- to the beginning of the new one. */
-
-void
-_obstack_newchunk (struct obstack *h, int length)
-{
- register struct _obstack_chunk *old_chunk = h->chunk;
- register struct _obstack_chunk *new_chunk;
- register long new_size;
- register long obj_size = h->next_free - h->object_base;
- register long i;
- long already;
- char *object_base;
-
- /* Compute size for new chunk. */
- new_size = (obj_size + length) + (obj_size >> 3) + h->alignment_mask + 100;
- if (new_size < h->chunk_size)
- new_size = h->chunk_size;
-
- /* Allocate and initialize the new chunk. */
- new_chunk = CALL_CHUNKFUN (h, new_size);
- if (!new_chunk)
- (*obstack_alloc_failed_handler) ();
- h->chunk = new_chunk;
- new_chunk->prev = old_chunk;
- new_chunk->limit = h->chunk_limit = (char *) new_chunk + new_size;
-
- /* Compute an aligned object_base in the new chunk */
- object_base =
- __PTR_ALIGN ((char *) new_chunk, new_chunk->contents, h->alignment_mask);
-
- /* Move the existing object to the new chunk.
- Word at a time is fast and is safe if the object
- is sufficiently aligned. */
- if (h->alignment_mask + 1 >= DEFAULT_ALIGNMENT)
- {
- for (i = obj_size / sizeof (COPYING_UNIT) - 1;
- i >= 0; i--)
- ((COPYING_UNIT *)object_base)[i]
- = ((COPYING_UNIT *)h->object_base)[i];
- /* We used to copy the odd few remaining bytes as one extra COPYING_UNIT,
- but that can cross a page boundary on a machine
- which does not do strict alignment for COPYING_UNITS. */
- already = obj_size / sizeof (COPYING_UNIT) * sizeof (COPYING_UNIT);
- }
- else
- already = 0;
- /* Copy remaining bytes one by one. */
- for (i = already; i < obj_size; i++)
- object_base[i] = h->object_base[i];
-
- /* If the object just copied was the only data in OLD_CHUNK,
- free that chunk and remove it from the chain.
- But not if that chunk might contain an empty object. */
- if (! h->maybe_empty_object
- && (h->object_base
- == __PTR_ALIGN ((char *) old_chunk, old_chunk->contents,
- h->alignment_mask)))
- {
- new_chunk->prev = old_chunk->prev;
- CALL_FREEFUN (h, old_chunk);
- }
-
- h->object_base = object_base;
- h->next_free = h->object_base + obj_size;
- /* The new chunk certainly contains no empty object yet. */
- h->maybe_empty_object = 0;
-}
-
-/* Return nonzero if object OBJ has been allocated from obstack H.
- This is here for debugging.
- If you use it in a program, you are probably losing. */
-
-/* Suppress -Wmissing-prototypes warning. We don't want to declare this in
- obstack.h because it is just for debugging. */
-int _obstack_allocated_p (struct obstack *h, void *obj);
-
-int
-_obstack_allocated_p (struct obstack *h, void *obj)
-{
- register struct _obstack_chunk *lp; /* below addr of any objects in this chunk */
- register struct _obstack_chunk *plp; /* point to previous chunk if any */
-
- lp = (h)->chunk;
- /* We use >= rather than > since the object cannot be exactly at
- the beginning of the chunk but might be an empty object exactly
- at the end of an adjacent chunk. */
- while (lp != 0 && ((void *) lp >= obj || (void *) (lp)->limit < obj))
- {
- plp = lp->prev;
- lp = plp;
- }
- return lp != 0;
-}
-\f
-/* Free objects in obstack H, including OBJ and everything allocate
- more recently than OBJ. If OBJ is zero, free everything in H. */
-
-# undef obstack_free
-
-void
-obstack_free (struct obstack *h, void *obj)
-{
- register struct _obstack_chunk *lp; /* below addr of any objects in this chunk */
- register struct _obstack_chunk *plp; /* point to previous chunk if any */
-
- lp = h->chunk;
- /* We use >= because there cannot be an object at the beginning of a chunk.
- But there can be an empty object at that address
- at the end of another chunk. */
- while (lp != 0 && ((void *) lp >= obj || (void *) (lp)->limit < obj))
- {
- plp = lp->prev;
- CALL_FREEFUN (h, lp);
- lp = plp;
- /* If we switch chunks, we can't tell whether the new current
- chunk contains an empty object, so assume that it may. */
- h->maybe_empty_object = 1;
- }
- if (lp)
- {
- h->object_base = h->next_free = (char *) (obj);
- h->chunk_limit = lp->limit;
- h->chunk = lp;
- }
- else if (obj != 0)
- /* obj is not in any of the chunks! */
- abort ();
-}
-
-int
-_obstack_memory_used (struct obstack *h)
-{
- register struct _obstack_chunk* lp;
- register int nbytes = 0;
-
- for (lp = h->chunk; lp != 0; lp = lp->prev)
- {
- nbytes += lp->limit - (char *) lp;
- }
- return nbytes;
-}
-
-static void
-__attribute__ ((noreturn))
-print_and_abort (void)
-{
- /* Don't change any of these strings. Yes, it would be possible to add
- the newline to the string and use fputs or so. But this must not
- happen because the "memory exhausted" message appears in other places
- like this and the translation should be reused instead of creating
- a very similar string which requires a separate translation. */
- fprintf (stderr, "%s\n", "memory exhausted");
- exit (obstack_exit_failure);
-}
-
+++ /dev/null
-/* obstack.h - object stack macros
- Copyright (C) 1988-1994,1996-1999,2003,2004,2005
- Free Software Foundation, Inc.
- This file is part of the GNU C Library.
-
- The GNU C Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- The GNU C Library 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
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with the GNU C Library; if not, write to the Free
- Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- Boston, MA 02110-1301, USA. */
-
-/* Summary:
-
-All the apparent functions defined here are macros. The idea
-is that you would use these pre-tested macros to solve a
-very specific set of problems, and they would run fast.
-Caution: no side-effects in arguments please!! They may be
-evaluated MANY times!!
-
-These macros operate a stack of objects. Each object starts life
-small, and may grow to maturity. (Consider building a word syllable
-by syllable.) An object can move while it is growing. Once it has
-been "finished" it never changes address again. So the "top of the
-stack" is typically an immature growing object, while the rest of the
-stack is of mature, fixed size and fixed address objects.
-
-These routines grab large chunks of memory, using a function you
-supply, called `obstack_chunk_alloc'. On occasion, they free chunks,
-by calling `obstack_chunk_free'. You must define them and declare
-them before using any obstack macros.
-
-Each independent stack is represented by a `struct obstack'.
-Each of the obstack macros expects a pointer to such a structure
-as the first argument.
-
-One motivation for this package is the problem of growing char strings
-in symbol tables. Unless you are "fascist pig with a read-only mind"
---Gosper's immortal quote from HAKMEM item 154, out of context--you
-would not like to put any arbitrary upper limit on the length of your
-symbols.
-
-In practice this often means you will build many short symbols and a
-few long symbols. At the time you are reading a symbol you don't know
-how long it is. One traditional method is to read a symbol into a
-buffer, realloc()ating the buffer every time you try to read a symbol
-that is longer than the buffer. This is beaut, but you still will
-want to copy the symbol from the buffer to a more permanent
-symbol-table entry say about half the time.
-
-With obstacks, you can work differently. Use one obstack for all symbol
-names. As you read a symbol, grow the name in the obstack gradually.
-When the name is complete, finalize it. Then, if the symbol exists already,
-free the newly read name.
-
-The way we do this is to take a large chunk, allocating memory from
-low addresses. When you want to build a symbol in the chunk you just
-add chars above the current "high water mark" in the chunk. When you
-have finished adding chars, because you got to the end of the symbol,
-you know how long the chars are, and you can create a new object.
-Mostly the chars will not burst over the highest address of the chunk,
-because you would typically expect a chunk to be (say) 100 times as
-long as an average object.
-
-In case that isn't clear, when we have enough chars to make up
-the object, THEY ARE ALREADY CONTIGUOUS IN THE CHUNK (guaranteed)
-so we just point to it where it lies. No moving of chars is
-needed and this is the second win: potentially long strings need
-never be explicitly shuffled. Once an object is formed, it does not
-change its address during its lifetime.
-
-When the chars burst over a chunk boundary, we allocate a larger
-chunk, and then copy the partly formed object from the end of the old
-chunk to the beginning of the new larger chunk. We then carry on
-accreting characters to the end of the object as we normally would.
-
-A special macro is provided to add a single char at a time to a
-growing object. This allows the use of register variables, which
-break the ordinary 'growth' macro.
-
-Summary:
- We allocate large chunks.
- We carve out one object at a time from the current chunk.
- Once carved, an object never moves.
- We are free to append data of any size to the currently
- growing object.
- Exactly one object is growing in an obstack at any one time.
- You can run one obstack per control block.
- You may have as many control blocks as you dare.
- Because of the way we do it, you can `unwind' an obstack
- back to a previous state. (You may remove objects much
- as you would with a stack.)
-*/
-
-
-/* Don't do the contents of this file more than once. */
-
-#ifndef _OBSTACK_H
-#define _OBSTACK_H 1
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-\f
-/* We need the type of a pointer subtraction. If __PTRDIFF_TYPE__ is
- defined, as with GNU C, use that; that way we don't pollute the
- namespace with <stddef.h>'s symbols. Otherwise, include <stddef.h>
- and use ptrdiff_t. */
-
-#ifdef __PTRDIFF_TYPE__
-# define PTR_INT_TYPE __PTRDIFF_TYPE__
-#else
-# include <stddef.h>
-# define PTR_INT_TYPE ptrdiff_t
-#endif
-
-/* If B is the base of an object addressed by P, return the result of
- aligning P to the next multiple of A + 1. B and P must be of type
- char *. A + 1 must be a power of 2. */
-
-#define __BPTR_ALIGN(B, P, A) ((B) + (((P) - (B) + (A)) & ~(A)))
-
-/* Similiar to _BPTR_ALIGN (B, P, A), except optimize the common case
- where pointers can be converted to integers, aligned as integers,
- and converted back again. If PTR_INT_TYPE is narrower than a
- pointer (e.g., the AS/400), play it safe and compute the alignment
- relative to B. Otherwise, use the faster strategy of computing the
- alignment relative to 0. */
-
-#define __PTR_ALIGN(B, P, A) \
- __BPTR_ALIGN (sizeof (PTR_INT_TYPE) < sizeof (void *) ? (B) : (char *) 0, \
- P, A)
-
-#include <string.h>
-
-struct _obstack_chunk /* Lives at front of each chunk. */
-{
- char *limit; /* 1 past end of this chunk */
- struct _obstack_chunk *prev; /* address of prior chunk or NULL */
- char contents[4]; /* objects begin here */
-};
-
-struct obstack /* control current object in current chunk */
-{
- long chunk_size; /* preferred size to allocate chunks in */
- struct _obstack_chunk *chunk; /* address of current struct obstack_chunk */
- char *object_base; /* address of object we are building */
- char *next_free; /* where to add next char to current object */
- char *chunk_limit; /* address of char after current chunk */
- union
- {
- PTR_INT_TYPE tempint;
- void *tempptr;
- } temp; /* Temporary for some macros. */
- int alignment_mask; /* Mask of alignment for each object. */
- /* These prototypes vary based on `use_extra_arg', and we use
- casts to the prototypeless function type in all assignments,
- but having prototypes here quiets -Wstrict-prototypes. */
- struct _obstack_chunk *(*chunkfun) (void *, long);
- void (*freefun) (void *, struct _obstack_chunk *);
- void *extra_arg; /* first arg for chunk alloc/dealloc funcs */
- unsigned use_extra_arg:1; /* chunk alloc/dealloc funcs take extra arg */
- unsigned maybe_empty_object:1;/* There is a possibility that the current
- chunk contains a zero-length object. This
- prevents freeing the chunk if we allocate
- a bigger chunk to replace it. */
- unsigned alloc_failed:1; /* No longer used, as we now call the failed
- handler on error, but retained for binary
- compatibility. */
-};
-
-/* Declare the external functions we use; they are in obstack.c. */
-
-extern void _obstack_newchunk (struct obstack *, int);
-extern int _obstack_begin (struct obstack *, int, int,
- void *(*) (long), void (*) (void *));
-extern int _obstack_begin_1 (struct obstack *, int, int,
- void *(*) (void *, long),
- void (*) (void *, void *), void *);
-extern int _obstack_memory_used (struct obstack *);
-
-void obstack_free (struct obstack *obstack, void *block);
-
-\f
-/* Error handler called when `obstack_chunk_alloc' failed to allocate
- more memory. This can be set to a user defined function which
- should either abort gracefully or use longjump - but shouldn't
- return. The default action is to print a message and abort. */
-extern void (*obstack_alloc_failed_handler) (void);
-
-/* Exit value used when `print_and_abort' is used. */
-extern int obstack_exit_failure;
-\f
-/* Pointer to beginning of object being allocated or to be allocated next.
- Note that this might not be the final address of the object
- because a new chunk might be needed to hold the final size. */
-
-#define obstack_base(h) ((void *) (h)->object_base)
-
-/* Size for allocating ordinary chunks. */
-
-#define obstack_chunk_size(h) ((h)->chunk_size)
-
-/* Pointer to next byte not yet allocated in current chunk. */
-
-#define obstack_next_free(h) ((h)->next_free)
-
-/* Mask specifying low bits that should be clear in address of an object. */
-
-#define obstack_alignment_mask(h) ((h)->alignment_mask)
-
-/* To prevent prototype warnings provide complete argument list. */
-#define obstack_init(h) \
- _obstack_begin ((h), 0, 0, \
- (void *(*) (long)) obstack_chunk_alloc, \
- (void (*) (void *)) obstack_chunk_free)
-
-#define obstack_begin(h, size) \
- _obstack_begin ((h), (size), 0, \
- (void *(*) (long)) obstack_chunk_alloc, \
- (void (*) (void *)) obstack_chunk_free)
-
-#define obstack_specify_allocation(h, size, alignment, chunkfun, freefun) \
- _obstack_begin ((h), (size), (alignment), \
- (void *(*) (long)) (chunkfun), \
- (void (*) (void *)) (freefun))
-
-#define obstack_specify_allocation_with_arg(h, size, alignment, chunkfun, freefun, arg) \
- _obstack_begin_1 ((h), (size), (alignment), \
- (void *(*) (void *, long)) (chunkfun), \
- (void (*) (void *, void *)) (freefun), (arg))
-
-#define obstack_chunkfun(h, newchunkfun) \
- ((h) -> chunkfun = (struct _obstack_chunk *(*)(void *, long)) (newchunkfun))
-
-#define obstack_freefun(h, newfreefun) \
- ((h) -> freefun = (void (*)(void *, struct _obstack_chunk *)) (newfreefun))
-
-#define obstack_1grow_fast(h,achar) (*((h)->next_free)++ = (achar))
-
-#define obstack_blank_fast(h,n) ((h)->next_free += (n))
-
-#define obstack_memory_used(h) _obstack_memory_used (h)
-\f
-#if defined __GNUC__ && defined __STDC__ && __STDC__
-/* NextStep 2.0 cc is really gcc 1.93 but it defines __GNUC__ = 2 and
- does not implement __extension__. But that compiler doesn't define
- __GNUC_MINOR__. */
-# if __GNUC__ < 2 || (__NeXT__ && !__GNUC_MINOR__)
-# define __extension__
-# endif
-
-/* For GNU C, if not -traditional,
- we can define these macros to compute all args only once
- without using a global variable.
- Also, we can avoid using the `temp' slot, to make faster code. */
-
-# define obstack_object_size(OBSTACK) \
- __extension__ \
- ({ struct obstack const *__o = (OBSTACK); \
- (unsigned) (__o->next_free - __o->object_base); })
-
-# define obstack_room(OBSTACK) \
- __extension__ \
- ({ struct obstack const *__o = (OBSTACK); \
- (unsigned) (__o->chunk_limit - __o->next_free); })
-
-# define obstack_make_room(OBSTACK,length) \
-__extension__ \
-({ struct obstack *__o = (OBSTACK); \
- int __len = (length); \
- if (__o->chunk_limit - __o->next_free < __len) \
- _obstack_newchunk (__o, __len); \
- (void) 0; })
-
-# define obstack_empty_p(OBSTACK) \
- __extension__ \
- ({ struct obstack const *__o = (OBSTACK); \
- (__o->chunk->prev == 0 \
- && __o->next_free == __PTR_ALIGN ((char *) __o->chunk, \
- __o->chunk->contents, \
- __o->alignment_mask)); })
-
-# define obstack_grow(OBSTACK,where,length) \
-__extension__ \
-({ struct obstack *__o = (OBSTACK); \
- int __len = (length); \
- if (__o->next_free + __len > __o->chunk_limit) \
- _obstack_newchunk (__o, __len); \
- memcpy (__o->next_free, where, __len); \
- __o->next_free += __len; \
- (void) 0; })
-
-# define obstack_grow0(OBSTACK,where,length) \
-__extension__ \
-({ struct obstack *__o = (OBSTACK); \
- int __len = (length); \
- if (__o->next_free + __len + 1 > __o->chunk_limit) \
- _obstack_newchunk (__o, __len + 1); \
- memcpy (__o->next_free, where, __len); \
- __o->next_free += __len; \
- *(__o->next_free)++ = 0; \
- (void) 0; })
-
-# define obstack_1grow(OBSTACK,datum) \
-__extension__ \
-({ struct obstack *__o = (OBSTACK); \
- if (__o->next_free + 1 > __o->chunk_limit) \
- _obstack_newchunk (__o, 1); \
- obstack_1grow_fast (__o, datum); \
- (void) 0; })
-
-/* These assume that the obstack alignment is good enough for pointers
- or ints, and that the data added so far to the current object
- shares that much alignment. */
-
-# define obstack_ptr_grow(OBSTACK,datum) \
-__extension__ \
-({ struct obstack *__o = (OBSTACK); \
- if (__o->next_free + sizeof (void *) > __o->chunk_limit) \
- _obstack_newchunk (__o, sizeof (void *)); \
- obstack_ptr_grow_fast (__o, datum); }) \
-
-# define obstack_int_grow(OBSTACK,datum) \
-__extension__ \
-({ struct obstack *__o = (OBSTACK); \
- if (__o->next_free + sizeof (int) > __o->chunk_limit) \
- _obstack_newchunk (__o, sizeof (int)); \
- obstack_int_grow_fast (__o, datum); })
-
-# define obstack_ptr_grow_fast(OBSTACK,aptr) \
-__extension__ \
-({ struct obstack *__o1 = (OBSTACK); \
- *(const void **) __o1->next_free = (aptr); \
- __o1->next_free += sizeof (const void *); \
- (void) 0; })
-
-# define obstack_int_grow_fast(OBSTACK,aint) \
-__extension__ \
-({ struct obstack *__o1 = (OBSTACK); \
- *(int *) __o1->next_free = (aint); \
- __o1->next_free += sizeof (int); \
- (void) 0; })
-
-# define obstack_blank(OBSTACK,length) \
-__extension__ \
-({ struct obstack *__o = (OBSTACK); \
- int __len = (length); \
- if (__o->chunk_limit - __o->next_free < __len) \
- _obstack_newchunk (__o, __len); \
- obstack_blank_fast (__o, __len); \
- (void) 0; })
-
-# define obstack_alloc(OBSTACK,length) \
-__extension__ \
-({ struct obstack *__h = (OBSTACK); \
- obstack_blank (__h, (length)); \
- obstack_finish (__h); })
-
-# define obstack_copy(OBSTACK,where,length) \
-__extension__ \
-({ struct obstack *__h = (OBSTACK); \
- obstack_grow (__h, (where), (length)); \
- obstack_finish (__h); })
-
-# define obstack_copy0(OBSTACK,where,length) \
-__extension__ \
-({ struct obstack *__h = (OBSTACK); \
- obstack_grow0 (__h, (where), (length)); \
- obstack_finish (__h); })
-
-/* The local variable is named __o1 to avoid a name conflict
- when obstack_blank is called. */
-# define obstack_finish(OBSTACK) \
-__extension__ \
-({ struct obstack *__o1 = (OBSTACK); \
- void *__value = (void *) __o1->object_base; \
- if (__o1->next_free == __value) \
- __o1->maybe_empty_object = 1; \
- __o1->next_free \
- = __PTR_ALIGN (__o1->object_base, __o1->next_free, \
- __o1->alignment_mask); \
- if (__o1->next_free - (char *)__o1->chunk \
- > __o1->chunk_limit - (char *)__o1->chunk) \
- __o1->next_free = __o1->chunk_limit; \
- __o1->object_base = __o1->next_free; \
- __value; })
-
-# define obstack_free(OBSTACK, OBJ) \
-__extension__ \
-({ struct obstack *__o = (OBSTACK); \
- void *__obj = (OBJ); \
- if (__obj > (void *)__o->chunk && __obj < (void *)__o->chunk_limit) \
- __o->next_free = __o->object_base = (char *)__obj; \
- else (obstack_free) (__o, __obj); })
-\f
-#else /* not __GNUC__ or not __STDC__ */
-
-# define obstack_object_size(h) \
- (unsigned) ((h)->next_free - (h)->object_base)
-
-# define obstack_room(h) \
- (unsigned) ((h)->chunk_limit - (h)->next_free)
-
-# define obstack_empty_p(h) \
- ((h)->chunk->prev == 0 \
- && (h)->next_free == __PTR_ALIGN ((char *) (h)->chunk, \
- (h)->chunk->contents, \
- (h)->alignment_mask))
-
-/* Note that the call to _obstack_newchunk is enclosed in (..., 0)
- so that we can avoid having void expressions
- in the arms of the conditional expression.
- Casting the third operand to void was tried before,
- but some compilers won't accept it. */
-
-# define obstack_make_room(h,length) \
-( (h)->temp.tempint = (length), \
- (((h)->next_free + (h)->temp.tempint > (h)->chunk_limit) \
- ? (_obstack_newchunk ((h), (h)->temp.tempint), 0) : 0))
-
-# define obstack_grow(h,where,length) \
-( (h)->temp.tempint = (length), \
- (((h)->next_free + (h)->temp.tempint > (h)->chunk_limit) \
- ? (_obstack_newchunk ((h), (h)->temp.tempint), 0) : 0), \
- memcpy ((h)->next_free, where, (h)->temp.tempint), \
- (h)->next_free += (h)->temp.tempint)
-
-# define obstack_grow0(h,where,length) \
-( (h)->temp.tempint = (length), \
- (((h)->next_free + (h)->temp.tempint + 1 > (h)->chunk_limit) \
- ? (_obstack_newchunk ((h), (h)->temp.tempint + 1), 0) : 0), \
- memcpy ((h)->next_free, where, (h)->temp.tempint), \
- (h)->next_free += (h)->temp.tempint, \
- *((h)->next_free)++ = 0)
-
-# define obstack_1grow(h,datum) \
-( (((h)->next_free + 1 > (h)->chunk_limit) \
- ? (_obstack_newchunk ((h), 1), 0) : 0), \
- obstack_1grow_fast (h, datum))
-
-# define obstack_ptr_grow(h,datum) \
-( (((h)->next_free + sizeof (char *) > (h)->chunk_limit) \
- ? (_obstack_newchunk ((h), sizeof (char *)), 0) : 0), \
- obstack_ptr_grow_fast (h, datum))
-
-# define obstack_int_grow(h,datum) \
-( (((h)->next_free + sizeof (int) > (h)->chunk_limit) \
- ? (_obstack_newchunk ((h), sizeof (int)), 0) : 0), \
- obstack_int_grow_fast (h, datum))
-
-# define obstack_ptr_grow_fast(h,aptr) \
- (((const void **) ((h)->next_free += sizeof (void *)))[-1] = (aptr))
-
-# define obstack_int_grow_fast(h,aint) \
- (((int *) ((h)->next_free += sizeof (int)))[-1] = (aint))
-
-# define obstack_blank(h,length) \
-( (h)->temp.tempint = (length), \
- (((h)->chunk_limit - (h)->next_free < (h)->temp.tempint) \
- ? (_obstack_newchunk ((h), (h)->temp.tempint), 0) : 0), \
- obstack_blank_fast (h, (h)->temp.tempint))
-
-# define obstack_alloc(h,length) \
- (obstack_blank ((h), (length)), obstack_finish ((h)))
-
-# define obstack_copy(h,where,length) \
- (obstack_grow ((h), (where), (length)), obstack_finish ((h)))
-
-# define obstack_copy0(h,where,length) \
- (obstack_grow0 ((h), (where), (length)), obstack_finish ((h)))
-
-# define obstack_finish(h) \
-( ((h)->next_free == (h)->object_base \
- ? (((h)->maybe_empty_object = 1), 0) \
- : 0), \
- (h)->temp.tempptr = (h)->object_base, \
- (h)->next_free \
- = __PTR_ALIGN ((h)->object_base, (h)->next_free, \
- (h)->alignment_mask), \
- (((h)->next_free - (char *) (h)->chunk \
- > (h)->chunk_limit - (char *) (h)->chunk) \
- ? ((h)->next_free = (h)->chunk_limit) : 0), \
- (h)->object_base = (h)->next_free, \
- (h)->temp.tempptr)
-
-# define obstack_free(h,obj) \
-( (h)->temp.tempint = (char *) (obj) - (char *) (h)->chunk, \
- ((((h)->temp.tempint > 0 \
- && (h)->temp.tempint < (h)->chunk_limit - (char *) (h)->chunk)) \
- ? (int) ((h)->next_free = (h)->object_base \
- = (h)->temp.tempint + (char *) (h)->chunk) \
- : (((obstack_free) ((h), (h)->temp.tempint + (char *) (h)->chunk), 0), 0)))
-
-#endif /* not __GNUC__ or not __STDC__ */
-
-#ifdef __cplusplus
-} /* C++ */
-#endif
-
-#endif /* obstack.h */
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2007 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#ifndef OBSTACKPP_H_
-#define OBSTACKPP_H_
-
-#include "obstack.h"
-
-inline void*
-operator new (size_t bytes, struct obstack& obst)
-{
- return obstack_alloc(&obst, bytes);
-}
-
-inline void*
-operator new[] (size_t bytes, struct obstack& obst)
-{
- return obstack_alloc(&obst, bytes);
-}
-
-static inline void* obstack_chunk_alloc(size_t size)
-{
- return new char[size];
-}
-
-static inline void obstack_chunk_free(void* data)
-{
- char* ptr = static_cast<char*> (data);
- delete[] ptr;
-}
-
-#endif
-
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2004 Tobas Glaesser <tobi.web@gmx.de>
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#include <config.h>
-
-#include "options_menu.hpp"
-#include "gui/menu.hpp"
-#include "audio/sound_manager.hpp"
-#include "control/joystickkeyboardcontroller.hpp"
-#include "main.hpp"
-#include "gettext.hpp"
-#include "gameconfig.hpp"
-
-Menu* options_menu = 0;
-
-enum OptionsMenuIDs {
- MNID_FULLSCREEN,
- MNID_SOUND,
- MNID_MUSIC
-};
-
-class LanguageMenu : public Menu
-{
-public:
- LanguageMenu() {
- add_label(_("Language"));
- add_hl();
- add_entry(0, std::string("(")+_("auto-detect language")+")");
- add_entry(1, "English");
-
- int mnid = 10;
- std::set<std::string> languages = dictionary_manager.get_languages();
- for (std::set<std::string>::iterator i = languages.begin(); i != languages.end(); i++) {
- std::string locale_name = *i;
- TinyGetText::LanguageDef ldef = TinyGetText::get_language_def(locale_name);
- std::string locale_fullname = locale_name;
- if (std::string(ldef.code) == locale_name) {
- locale_fullname = ldef.name;
- }
- add_entry(mnid++, locale_fullname);
- }
-
- add_hl();
- add_back(_("Back"));
- }
-
- virtual void menu_action(MenuItem* item) {
- if (item->id == 0) {
- config->locale = "";
- dictionary_manager.set_language(config->locale);
- config->save();
- Menu::set_current(0);
- }
- else if (item->id == 1) {
- config->locale = "en";
- dictionary_manager.set_language(config->locale);
- config->save();
- Menu::set_current(0);
- }
- int mnid = 10;
- std::set<std::string> languages = dictionary_manager.get_languages();
- for (std::set<std::string>::iterator i = languages.begin(); i != languages.end(); i++) {
- std::string locale_name = *i;
- if (item->id == mnid++) {
- config->locale = locale_name;
- dictionary_manager.set_language(config->locale);
- config->save();
- Menu::set_current(0);
- }
- }
- }
-};
-
-
-class OptionsMenu : public Menu
-{
-public:
- OptionsMenu();
- virtual ~OptionsMenu();
-
- virtual void menu_action(MenuItem* item);
-
-protected:
- std::auto_ptr<LanguageMenu> language_menu;
-
-};
-
-OptionsMenu::OptionsMenu()
-{
- language_menu.reset(new LanguageMenu());
-
- add_label(_("Options"));
- add_hl();
- add_toggle(MNID_FULLSCREEN,_("Fullscreen"), config->use_fullscreen);
- add_submenu(_("Language"), language_menu.get());
- if (sound_manager->is_audio_enabled()) {
- add_toggle(MNID_SOUND, _("Sound"), config->sound_enabled);
- add_toggle(MNID_MUSIC, _("Music"), config->music_enabled);
- } else {
- add_deactive(MNID_SOUND, _("Sound (disabled)"));
- add_deactive(MNID_SOUND, _("Music (disabled)"));
- }
- add_submenu(_("Setup Keyboard"), main_controller->get_key_options_menu());
- add_submenu(_("Setup Joystick"),main_controller->get_joystick_options_menu());
- add_hl();
- add_back(_("Back"));
-}
-
-OptionsMenu::~OptionsMenu()
-{
-}
-
-void
-OptionsMenu::menu_action(MenuItem* item)
-{
- switch (item->id) {
- case MNID_FULLSCREEN:
- if(config->use_fullscreen != options_menu->is_toggled(MNID_FULLSCREEN)) {
- config->use_fullscreen = !config->use_fullscreen;
- init_video();
- config->save();
- }
- break;
- case MNID_SOUND:
- if(config->sound_enabled != options_menu->is_toggled(MNID_SOUND)) {
- config->sound_enabled = !config->sound_enabled;
- sound_manager->enable_sound(config->sound_enabled);
- config->save();
- }
- break;
- case MNID_MUSIC:
- if(config->music_enabled != options_menu->is_toggled(MNID_MUSIC)) {
- config->music_enabled = !config->music_enabled;
- sound_manager->enable_music(config->music_enabled);
- config->save();
- }
- break;
- default:
- break;
- }
-}
-
-Menu* get_options_menu()
-{
- //static OptionsMenu menu;
- options_menu = new OptionsMenu();
- return options_menu;
-}
-
-void free_options_menu()
-{
- delete options_menu;
- options_menu = 0;
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2004 Tobas Glaesser <tobi.web@gmx.de>
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#ifndef __OPTIONS_MENU_HPP__
-#define __OPTIONS_MENU_HPP__
-
-class Menu;
-Menu* get_options_menu();
-void free_options_menu();
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <unison/vfs/stream.hpp>
-#include <unison/vfs/sdl/Utils.hpp>
-
-#include <stdexcept>
-
-SDL_RWops* get_physfs_SDLRWops(const std::string& filename)
-{
- // check this as PHYSFS seems to be buggy and still returns a
- // valid pointer in this case
- if(filename == "") {
- throw std::runtime_error("Couldn't open file: empty filename");
- }
- return Unison::VFS::SDL::Utils::open_physfs_in(filename);
-}
-
-#if 0
-#include <config.h>
-
-#include "physfs_sdl.hpp"
-
-#include <physfs.h>
-
-#include <stdexcept>
-#include <sstream>
-#include <iostream>
-
-#include <assert.h>
-#include "log.hpp"
-
-static int funcSeek(struct SDL_RWops* context, int offset, int whence)
-{
- PHYSFS_file* file = (PHYSFS_file*) context->hidden.unknown.data1;
- int res;
- switch(whence) {
- case SEEK_SET:
- res = PHYSFS_seek(file, offset);
- break;
- case SEEK_CUR:
- res = PHYSFS_seek(file, PHYSFS_tell(file) + offset);
- break;
- case SEEK_END:
- res = PHYSFS_seek(file, PHYSFS_fileLength(file) + offset);
- break;
- default:
- res = 0;
- assert(false);
- break;
- }
- if(res == 0) {
- log_warning << "Error seeking in file: " << PHYSFS_getLastError() << std::endl;
- return -1;
- }
-
- return (int) PHYSFS_tell(file);
-}
-
-static int funcRead(struct SDL_RWops* context, void* ptr, int size, int maxnum)
-{
- PHYSFS_file* file = (PHYSFS_file*) context->hidden.unknown.data1;
-
- int res = PHYSFS_read(file, ptr, size, maxnum);
- return res;
-}
-
-static int funcClose(struct SDL_RWops* context)
-{
- PHYSFS_file* file = (PHYSFS_file*) context->hidden.unknown.data1;
-
- PHYSFS_close(file);
- delete context;
-
- return 0;
-}
-
-SDL_RWops* get_physfs_SDLRWops(const std::string& filename)
-{
- // check this as PHYSFS seems to be buggy and still returns a
- // valid pointer in this case
- if(filename == "") {
- throw std::runtime_error("Couldn't open file: empty filename");
- }
-
- PHYSFS_file* file = (PHYSFS_file*) PHYSFS_openRead(filename.c_str());
- if(!file) {
- std::stringstream msg;
- msg << "Couldn't open '" << filename << "': "
- << PHYSFS_getLastError();
- throw std::runtime_error(msg.str());
- }
-
- SDL_RWops* ops = new SDL_RWops();
- ops->type = 0;
- ops->hidden.unknown.data1 = file;
- ops->seek = funcSeek;
- ops->read = funcRead;
- ops->write = 0;
- ops->close = funcClose;
- return ops;
-}
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __PHYSFSSDL_HPP__
-#define __PHYSFSSDL_HPP__
-
-#include <SDL.h>
-#include <string>
-
-SDL_RWops* get_physfs_SDLRWops(const std::string& filename);
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#if 0
-#include <config.h>
-
-#include "physfs_stream.hpp"
-
-#include <assert.h>
-#include <physfs.h>
-#include <stdexcept>
-#include <sstream>
-
-IFileStreambuf::IFileStreambuf(const std::string& filename)
-{
- // check this as PHYSFS seems to be buggy and still returns a
- // valid pointer in this case
- if(filename == "") {
- throw std::runtime_error("Couldn't open file: empty filename");
- }
- file = PHYSFS_openRead(filename.c_str());
- if(file == 0) {
- std::stringstream msg;
- msg << "Couldn't open file '" << filename << "': "
- << PHYSFS_getLastError();
- throw std::runtime_error(msg.str());
- }
-}
-
-IFileStreambuf::~IFileStreambuf()
-{
- PHYSFS_close(file);
-}
-
-int
-IFileStreambuf::underflow()
-{
- if(PHYSFS_eof(file)) {
- return traits_type::eof();
- }
-
- PHYSFS_sint64 bytesread = PHYSFS_read(file, buf, 1, sizeof(buf));
- if(bytesread <= 0) {
- return traits_type::eof();
- }
- setg(buf, buf, buf + bytesread);
-
- return buf[0];
-}
-
-IFileStreambuf::pos_type
-IFileStreambuf::seekpos(pos_type pos, std::ios_base::openmode)
-{
- if(PHYSFS_seek(file, static_cast<PHYSFS_uint64> (pos)) == 0) {
- return pos_type(off_type(-1));
- }
-
- // the seek invalidated the buffer
- setg(buf, buf, buf);
- return pos;
-}
-
-IFileStreambuf::pos_type
-IFileStreambuf::seekoff(off_type off, std::ios_base::seekdir dir,
- std::ios_base::openmode mode)
-{
- off_type pos = off;
- PHYSFS_sint64 ptell = PHYSFS_tell(file);
-
- switch(dir) {
- case std::ios_base::beg:
- break;
- case std::ios_base::cur:
- if(off == 0)
- return static_cast<pos_type> (ptell) - static_cast<pos_type> (egptr() - gptr());
- pos += static_cast<off_type> (ptell) - static_cast<off_type> (egptr() - gptr());
- break;
- case std::ios_base::end:
- pos += static_cast<off_type> (PHYSFS_fileLength(file));
- break;
- default:
-#ifdef DEBUG
- assert(false);
-#else
- return pos_type(off_type(-1));
-#endif
- }
-
- return seekpos(static_cast<pos_type> (pos), mode);
-}
-
-//---------------------------------------------------------------------------
-
-OFileStreambuf::OFileStreambuf(const std::string& filename)
-{
- file = PHYSFS_openWrite(filename.c_str());
- if(file == 0) {
- std::stringstream msg;
- msg << "Couldn't open file '" << filename << "': "
- << PHYSFS_getLastError();
- throw std::runtime_error(msg.str());
- }
-
- setp(buf, buf+sizeof(buf));
-}
-
-OFileStreambuf::~OFileStreambuf()
-{
- sync();
- PHYSFS_close(file);
-}
-
-int
-OFileStreambuf::overflow(int c)
-{
- char c2 = (char)c;
-
- if(pbase() == pptr())
- return 0;
-
- size_t size = pptr() - pbase();
- PHYSFS_sint64 res = PHYSFS_write(file, pbase(), 1, size);
- if(res <= 0)
- return traits_type::eof();
-
- if(c != traits_type::eof()) {
- PHYSFS_sint64 res = PHYSFS_write(file, &c2, 1, 1);
- if(res <= 0)
- return traits_type::eof();
- }
-
- setp(buf, buf + res);
- return 0;
-}
-
-int
-OFileStreambuf::sync()
-{
- return overflow(traits_type::eof());
-}
-
-//---------------------------------------------------------------------------
-
-IFileStream::IFileStream(const std::string& filename)
- : std::istream(new IFileStreambuf(filename))
-{
-}
-
-IFileStream::~IFileStream()
-{
- delete rdbuf();
-}
-
-//---------------------------------------------------------------------------
-
-OFileStream::OFileStream(const std::string& filename)
- : std::ostream(new OFileStreambuf(filename))
-{
-}
-
-OFileStream::~OFileStream()
-{
- delete rdbuf();
-}
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __PHYSFSSTREAM_HPP__
-#define __PHYSFSSTREAM_HPP__
-
-#include <unison/vfs/stream.hpp>
-
-typedef Unison::VFS::istream IFileStream;
-typedef Unison::VFS::ostream OFileStream;
-
-#if 0
-#include <stddef.h>
-#include <physfs.h>
-#include <string>
-#include <streambuf>
-#include <iostream>
-
-/** This class implements a C++ streambuf object for physfs files.
- * So that you can use normal istream operations on them
- */
-class IFileStreambuf : public std::streambuf
-{
-public:
- IFileStreambuf(const std::string& filename);
- ~IFileStreambuf();
-
-protected:
- virtual int underflow();
- virtual pos_type seekoff(off_type pos, std::ios_base::seekdir,
- std::ios_base::openmode);
- virtual pos_type seekpos(pos_type pos, std::ios_base::openmode);
-
-private:
- PHYSFS_file* file;
- char buf[1024];
-};
-
-class OFileStreambuf : public std::streambuf
-{
-public:
- OFileStreambuf(const std::string& filename);
- ~OFileStreambuf();
-
-protected:
- virtual int overflow(int c);
- virtual int sync();
-
-private:
- PHYSFS_file* file;
- char buf[1024];
-};
-
-class IFileStream : public std::istream
-{
-public:
- IFileStream(const std::string& filename);
- ~IFileStream();
-};
-
-class OFileStream : public std::ostream
-{
-public:
- OFileStream(const std::string& filename);
- ~OFileStream();
-};
-#endif
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2004 Tobias Glaesser <tobi.web@gmx.de>
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#include <config.h>
-
-#include "physic.hpp"
-
-Physic::Physic()
- : ax(0), ay(0), vx(0), vy(0), gravity_enabled_flag(true), gravity(10 * 100)
-{
-}
-
-Physic::~Physic()
-{
-}
-
-void
-Physic::reset()
-{
- ax = ay = vx = vy = 0;
- gravity_enabled_flag = true;
-}
-
-void
-Physic::set_velocity_x(float nvx)
-{
- vx = nvx;
-}
-
-void
-Physic::set_velocity_y(float nvy)
-{
- vy = nvy;
-}
-
-void
-Physic::set_velocity(float nvx, float nvy)
-{
- vx = nvx;
- vy = nvy;
-}
-
-void
-Physic::set_velocity(const Vector& vector)
-{
- vx = vector.x;
- vy = vector.y;
-}
-
-void Physic::inverse_velocity_x()
-{
- vx = -vx;
-}
-
-void Physic::inverse_velocity_y()
-{
- vy = -vy;
-}
-
-float
-Physic::get_velocity_x() const
-{
- return vx;
-}
-
-float
-Physic::get_velocity_y() const
-{
- return vy;
-}
-
-Vector
-Physic::get_velocity() const
-{
- return Vector(vx, vy);
-}
-
-void
-Physic::set_acceleration_x(float nax)
-{
- ax = nax;
-}
-
-void
-Physic::set_acceleration_y(float nay)
-{
- ay = nay;
-}
-
-void
-Physic::set_acceleration(float nax, float nay)
-{
- ax = nax;
- ay = nay;
-}
-
-float
-Physic::get_acceleration_x() const
-{
- return ax;
-}
-
-float
-Physic::get_acceleration_y() const
-{
- return ay;
-}
-
-Vector
-Physic::get_acceleration() const
-{
- return Vector(ax, ay);
-}
-
-void
-Physic::enable_gravity(bool enable_gravity)
-{
- gravity_enabled_flag = enable_gravity;
-}
-
-bool
-Physic::gravity_enabled() const
-{
- return gravity_enabled_flag;
-}
-
-void
-Physic::set_gravity(float gravity)
-{
- this->gravity = gravity * 100;
-}
-
-float
-Physic::get_gravity() const
-{
- return gravity / 100;
-}
-
-Vector
-Physic::get_movement(float elapsed_time)
-{
- float grav = gravity_enabled_flag ? gravity : 0;
-
- Vector result(
- vx * elapsed_time + ax * elapsed_time * elapsed_time,
- vy * elapsed_time + (ay + grav) * elapsed_time * elapsed_time
- );
- vx += ax * elapsed_time;
- vy += (ay + grav) * elapsed_time;
-
- return result;
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2004 Tobias Glaesser <tobi.web@gmx.de>
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#ifndef SUPERTUX_PHYSIC_H
-#define SUPERTUX_PHYSIC_H
-
-#include "math/vector.hpp"
-
-/// Physics engine.
-/** This is a very simplistic physics engine handling accelerated and constant
- * movement along with gravity.
- */
-class Physic
-{
-public:
- Physic();
- ~Physic();
-
- /// Resets all velocities and accelerations to 0.
- void reset();
-
- /// Sets velocity to a fixed value.
- void set_velocity(float vx, float vy);
- void set_velocity(const Vector& vector);
-
- void set_velocity_x(float vx);
- void set_velocity_y(float vy);
-
- /// Velocities invertion.
- void inverse_velocity_x();
- void inverse_velocity_y();
-
- Vector get_velocity() const;
- float get_velocity_x() const;
- float get_velocity_y() const;
-
- /// Set acceleration.
- /** Sets acceleration applied to the object. (Note that gravity is
- * eventually added to the vertical acceleration)
- */
- void set_acceleration(float ax, float ay);
-
- void set_acceleration_x(float ax);
- void set_acceleration_y(float ay);
-
- Vector get_acceleration() const;
- float get_acceleration_x() const;
- float get_acceleration_y() const;
-
- /// Enables or disables handling of gravity.
- void enable_gravity(bool gravity_enabled);
- bool gravity_enabled() const;
-
- /// Set gravity to apply to object when enabled
- void set_gravity(float gravity);
-
- /// Get gravity to apply to object when enabled
- float get_gravity() const;
-
- Vector get_movement(float elapsed_time);
-
-private:
- /// horizontal and vertical acceleration
- float ax, ay;
- /// horizontal and vertical velocity
- float vx, vy;
- /// should we respect gravity in our calculations?
- bool gravity_enabled_flag;
- /// current gravity (multiplied by 100) to apply to object, if enabled
- float gravity;
-};
-
-class UsesPhysic
-{
-public:
- Physic physic;
- friend class Sector;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2003 Tobias Glaesser <tobi.web@gmx.de>
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#include <config.h>
-
-#include <math.h>
-#include "lisp/writer.hpp"
-#include "lisp/lisp.hpp"
-#include "player_status.hpp"
-#include "resources.hpp"
-#include "gettext.hpp"
-#include "video/drawing_context.hpp"
-#include "audio/sound_manager.hpp"
-#include "sprite/sprite_manager.hpp"
-#include "math/vector.hpp"
-#include "main.hpp"
-#include "log.hpp"
-#include "timer.hpp"
-
-static const int START_COINS = 100;
-static const int MAX_COINS = 99999;
-
-PlayerStatus* player_status = 0;
-
-PlayerStatus::PlayerStatus()
- : coins(START_COINS),
- bonus(NO_BONUS),
- max_fire_bullets(0),
- max_ice_bullets(0),
- score_multiplier(1),
- max_score_multiplier(1)
-{
- reset();
-
- coin_surface.reset(new Surface("images/engine/hud/coins-0.png"));
-}
-
-PlayerStatus::~PlayerStatus()
-{
-}
-
-void PlayerStatus::reset()
-{
- coins = START_COINS;
- bonus = NO_BONUS;
- score_multiplier = 1;
- max_score_multiplier = 1;
-}
-
-void
-PlayerStatus::add_coins(int count, bool play_sound)
-{
- static float sound_played_time = 0;
- coins = std::min(coins + count, MAX_COINS);
- if(play_sound) {
- if(count >= 100)
- sound_manager->play("sounds/lifeup.wav");
- else if (real_time > sound_played_time + 0.010) {
- sound_manager->play("sounds/coin.wav");
- sound_played_time = real_time;
- }
- }
-}
-
-void
-PlayerStatus::write(lisp::Writer& writer)
-{
- switch(bonus) {
- case NO_BONUS:
- writer.write_string("bonus", "none");
- break;
- case GROWUP_BONUS:
- writer.write_string("bonus", "growup");
- break;
- case FIRE_BONUS:
- writer.write_string("bonus", "fireflower");
- break;
- case ICE_BONUS:
- writer.write_string("bonus", "iceflower");
- break;
- default:
- log_warning << "Unknown bonus type." << std::endl;
- writer.write_string("bonus", "none");
- }
- writer.write_int("fireflowers", max_fire_bullets);
- writer.write_int("iceflowers", max_ice_bullets);
-
- writer.write_int("coins", coins);
- writer.write_int("max-score-multiplier", max_score_multiplier);
-}
-
-void
-PlayerStatus::read(const lisp::Lisp& lisp)
-{
- reset();
-
- std::string bonusname;
- if(lisp.get("bonus", bonusname)) {
- if(bonusname == "none") {
- bonus = NO_BONUS;
- } else if(bonusname == "growup") {
- bonus = GROWUP_BONUS;
- } else if(bonusname == "fireflower") {
- bonus = FIRE_BONUS;
- } else if(bonusname == "iceflower") {
- bonus = ICE_BONUS;
- } else {
- log_warning << "Unknown bonus '" << bonusname << "' in savefile" << std::endl;
- bonus = NO_BONUS;
- }
- }
- lisp.get("fireflowers", max_fire_bullets);
- lisp.get("iceflowers", max_ice_bullets);
-
- lisp.get("coins", coins);
- lisp.get("max-score-multiplier", max_score_multiplier);
-}
-
-void
-PlayerStatus::draw(DrawingContext& context)
-{
- static int displayed_coins = -1;
- static int next_count = 0;
-
- if ((displayed_coins == -1) || (fabsf(displayed_coins - coins) > 100)) {
- displayed_coins = coins;
- }
- if (++next_count > 2) {
- next_count = 0;
- if (displayed_coins < coins) displayed_coins++;
- if (displayed_coins > coins) displayed_coins--;
- }
- displayed_coins = std::min(std::max(displayed_coins, 0), 9999);
-
- std::stringstream ss;
- ss << displayed_coins;
- std::string coins_text = ss.str();
-
- context.push_transform();
- context.set_translation(Vector(0, 0));
-
- Surface* coin_surf = coin_surface.get();
- if (coin_surf) {
- context.draw_surface(coin_surf, Vector(SCREEN_WIDTH - BORDER_X - coin_surf->get_width() - gold_fixed_text->get_text_width(coins_text), BORDER_Y + 1), LAYER_HUD);
- }
- context.draw_text(gold_fixed_text, coins_text, Vector(SCREEN_WIDTH - BORDER_X, BORDER_Y), ALIGN_RIGHT, LAYER_HUD);
-
- context.pop_transform();
-}
-
-void
-PlayerStatus::operator= (const PlayerStatus& other)
-{
- coins = other.coins;
- bonus = other.bonus;
- score_multiplier = other.score_multiplier;
- max_score_multiplier = other.max_score_multiplier;
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2003 Tobias Glaesser <tobi.web@gmx.de>
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#ifndef SUPERTUX_PLAYERSTATUS_H
-#define SUPERTUX_PLAYERSTATUS_H
-
-#include <memory>
-#include "serializable.hpp"
-
-namespace lisp{ class Writer; }
-namespace lisp{ class Lisp; }
-class Surface;
-
-static const float BORDER_X = 10;
-static const float BORDER_Y = 10;
-
-enum BonusType {
- NO_BONUS, GROWUP_BONUS, FIRE_BONUS, ICE_BONUS
-};
-class DrawingContext;
-
-/**
- * This class memorizes player status between different game sessions (for
- * example when switching maps in the worldmap)
- */
-class PlayerStatus : public Serializable
-{
-public:
- PlayerStatus();
- ~PlayerStatus();
- void reset();
- void add_coins(int count, bool play_sound = true);
-
- void write(lisp::Writer& writer);
- void read(const lisp::Lisp& lisp);
-
- void draw(DrawingContext& context);
-
- int coins;
- BonusType bonus;
- int max_fire_bullets; /**< maximum number of fire bullets in play */
- int max_ice_bullets; /**< maximum number of ice bullets in play */
-
- int score_multiplier;
- int max_score_multiplier;
-
- void operator= (const PlayerStatus& other);
-
-private:
- // don't use this
- PlayerStatus(const PlayerStatus& other);
-
- std::auto_ptr<Surface> coin_surface;
-};
-
-// global player state
-extern PlayerStatus* player_status;
-
-#endif
+++ /dev/null
-// $Id$
-//
-// A strong random number generator
-//
-// Copyright (C) 2006 Allen King
-// Copyright (C) 2002 Michael Ringgaard. All rights reserved.
-// Copyright (C) 1983, 1993 The Regents of the University of California.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions
-// are met:
-//
-// 1. Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// 2. Redistributions in binary form must reproduce the above copyright
-// notice, this list of conditions and the following disclaimer in the
-// documentation and/or other materials provided with the distribution.
-// 3. Neither the name of the project nor the names of its contributors
-// may be used to endorse or promote products derived from this software
-// without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
-// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-// OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-// SUCH DAMAGE.
-
-// Transliterated into C++ Allen King 060417, from sources on
-// http://www.jbox.dk/sanos/source/lib/random.c.html
-#include <config.h>
-
-
-#include <stdexcept>
-#include <time.h>
-#include <cassert>
-#include "random_generator.hpp"
-
-RandomGenerator systemRandom; // global random number generator
-
-RandomGenerator::RandomGenerator() {
- assert(sizeof(int) >= 4);
- initialized = 0;
- debug = 0; // change this by hand for debug
- initialize();
-}
-
-RandomGenerator::~RandomGenerator() {
-}
-
-int RandomGenerator::srand(int x) {
- int x0 = x;
- while (x <= 0) // random seed of zero means
- x = time(0) % RandomGenerator::rand_max; // randomize with time
-
- if (debug > 0)
- printf("==== srand(%10d) (%10d) rand_max=%x =====\n",
- x, x0, RandomGenerator::rand_max);
-
- RandomGenerator::srandom(x);
- return x; // let caller know seed used
-}
-
-int RandomGenerator::rand() {
- int rv; // a posative int
- while ((rv = RandomGenerator::random()) <= 0) // neg or zero causes probs
- ;
- if (debug > 0)
- printf("==== rand(): %10d =====\n", rv);
- return rv;
-}
-
-int RandomGenerator::rand(int v) {
- assert(v >= 0 && v <= RandomGenerator::rand_max); // illegal arg
-
- // remove biases, esp. when v is large (e.g. v == (rand_max/4)*3;)
- int rv, maxV =(RandomGenerator::rand_max / v) * v;
- assert(maxV <= RandomGenerator::rand_max);
- while ((rv = RandomGenerator::random()) >= maxV)
- ;
- return rv % v; // mod it down to 0..(maxV-1)
-}
-
-int RandomGenerator::rand(int u, int v) {
- assert(v > u);
- return u + RandomGenerator::rand(v-u);
-}
-
-double RandomGenerator::randf(double v) {
- float rv;
- do {
- rv = ((double)RandomGenerator::random())/RandomGenerator::rand_max * v;
- } while (rv >= v); // rounding might cause rv==v
-
- if (debug > 0)
- printf("==== rand(): %f =====\n", rv);
- return rv;
-}
-
-double RandomGenerator::randf(double u, double v) {
- return u + RandomGenerator::randf(v-u);
-}
-
-//-----------------------------------------------------------------------
-//
-// Copyright (C) 2002 Michael Ringgaard. All rights reserved.
-// Copyright (C) 1983, 1993 The Regents of the University of California.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions
-// are met:
-//
-// 1. Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// 2. Redistributions in binary form must reproduce the above copyright
-// notice, this list of conditions and the following disclaimer in the
-// documentation and/or other materials provided with the distribution.
-// 3. Neither the name of the project nor the names of its contributors
-// may be used to endorse or promote products derived from this software
-// without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
-// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-// OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-// SUCH DAMAGE.
-//
-
-//**#include <os.h>
-
-//
-// An improved random number generation package. In addition to the standard
-// rand()/srand() like interface, this package also has a special state info
-// interface. The initstate() routine is called with a seed, an array of
-// bytes, and a count of how many bytes are being passed in; this array is
-// then initialized to contain information for random number generation with
-// that much state information. Good sizes for the amount of state
-// information are 32, 64, 128, and 256 bytes. The state can be switched by
-// calling the setstate() routine with the same array as was initiallized
-// with initstate(). By default, the package runs with 128 bytes of state
-// information and generates far better random numbers than a linear
-// congruential generator. If the amount of state information is less than
-// 32 bytes, a simple linear congruential R.N.G. is used.
-//
-// Internally, the state information is treated as an array of longs; the
-// zeroeth element of the array is the type of R.N.G. being used (small
-// integer); the remainder of the array is the state information for the
-// R.N.G. Thus, 32 bytes of state information will give 7 longs worth of
-// state information, which will allow a degree seven polynomial. (Note:
-// the zeroeth word of state information also has some other information
-// stored in it -- see setstate() for details).
-//
-// The random number generation technique is a linear feedback shift register
-// approach, employing trinomials (since there are fewer terms to sum up that
-// way). In this approach, the least significant bit of all the numbers in
-// the state table will act as a linear feedback shift register, and will
-// have period 2^deg - 1 (where deg is the degree of the polynomial being
-// used, assuming that the polynomial is irreducible and primitive). The
-// higher order bits will have longer periods, since their values are also
-// influenced by pseudo-random carries out of the lower bits. The total
-// period of the generator is approximately deg*(2**deg - 1); thus doubling
-// the amount of state information has a vast influence on the period of the
-// generator. Note: the deg*(2**deg - 1) is an approximation only good for
-// large deg, when the period of the shift is the dominant factor.
-// With deg equal to seven, the period is actually much longer than the
-// 7*(2**7 - 1) predicted by this formula.
-//
-// Modified 28 December 1994 by Jacob S. Rosenberg.
-//
-
-//
-// For each of the currently supported random number generators, we have a
-// break value on the amount of state information (you need at least this
-// many bytes of state info to support this random number generator), a degree
-// for the polynomial (actually a trinomial) that the R.N.G. is based on, and
-// the separation between the two lower order coefficients of the trinomial.
-
-void RandomGenerator::initialize() {
-
-#define NSHUFF 100 // To drop part of seed -> 1st value correlation
-
-//static long degrees[MAX_TYPES] = { DEG_0, DEG_1, DEG_2, DEG_3, DEG_4 };
-//static long seps [MAX_TYPES] = { SEP_0, SEP_1, SEP_2, SEP_3, SEP_4 };
-
- degrees[0] = DEG_0;
- degrees[1] = DEG_1;
- degrees[2] = DEG_2;
- degrees[3] = DEG_3;
- degrees[4] = DEG_4;
-
- seps [0] = SEP_0;
- seps [1] = SEP_1;
- seps [2] = SEP_2;
- seps [3] = SEP_3;
- seps [4] = SEP_4;
-
-//
-// Initially, everything is set up as if from:
-//
-// initstate(1, randtbl, 128);
-//
-// Note that this initialization takes advantage of the fact that srandom()
-// advances the front and rear pointers 10*rand_deg times, and hence the
-// rear pointer which starts at 0 will also end up at zero; thus the zeroeth
-// element of the state information, which contains info about the current
-// position of the rear pointer is just
-//
-// MAX_TYPES * (rptr - state) + TYPE_3 == TYPE_3.
-
- randtbl[ 0] = TYPE_3;
- randtbl[ 1] = 0x991539b1;
- randtbl[ 2] = 0x16a5bce3;
- randtbl[ 3] = 0x6774a4cd;
- randtbl[ 4] = 0x3e01511e;
- randtbl[ 5] = 0x4e508aaa;
- randtbl[ 6] = 0x61048c05;
- randtbl[ 7] = 0xf5500617;
- randtbl[ 8] = 0x846b7115;
- randtbl[ 9] = 0x6a19892c;
- randtbl[10] = 0x896a97af;
- randtbl[11] = 0xdb48f936;
- randtbl[12] = 0x14898454;
- randtbl[13] = 0x37ffd106;
- randtbl[14] = 0xb58bff9c;
- randtbl[15] = 0x59e17104;
- randtbl[16] = 0xcf918a49;
- randtbl[17] = 0x09378c83;
- randtbl[18] = 0x52c7a471;
- randtbl[19] = 0x8d293ea9;
- randtbl[20] = 0x1f4fc301;
- randtbl[21] = 0xc3db71be;
- randtbl[22] = 0x39b44e1c;
- randtbl[23] = 0xf8a44ef9;
- randtbl[24] = 0x4c8b80b1;
- randtbl[25] = 0x19edc328;
- randtbl[26] = 0x87bf4bdd;
- randtbl[27] = 0xc9b240e5;
- randtbl[28] = 0xe9ee4b1b;
- randtbl[29] = 0x4382aee7;
- randtbl[30] = 0x535b6b41;
- randtbl[31] = 0xf3bec5da;
-
-// static long randtbl[DEG_3 + 1] =
-// {
-// TYPE_3;
-// 0x991539b1, 0x16a5bce3, 0x6774a4cd, 0x3e01511e, 0x4e508aaa, 0x61048c05,
-// 0xf5500617, 0x846b7115, 0x6a19892c, 0x896a97af, 0xdb48f936, 0x14898454,
-// 0x37ffd106, 0xb58bff9c, 0x59e17104, 0xcf918a49, 0x09378c83, 0x52c7a471,
-// 0x8d293ea9, 0x1f4fc301, 0xc3db71be, 0x39b44e1c, 0xf8a44ef9, 0x4c8b80b1,
-// 0x19edc328, 0x87bf4bdd, 0xc9b240e5, 0xe9ee4b1b, 0x4382aee7, 0x535b6b41,
-// 0xf3bec5da
-// };
-
-
-//
-// fptr and rptr are two pointers into the state info, a front and a rear
-// pointer. These two pointers are always rand_sep places aparts, as they
-// cycle cyclically through the state information. (Yes, this does mean we
-// could get away with just one pointer, but the code for random() is more
-// efficient this way). The pointers are left positioned as they would be
-// from the call
-//
-// initstate(1, randtbl, 128);
-//
-// (The position of the rear pointer, rptr, is really 0 (as explained above
-// in the initialization of randtbl) because the state table pointer is set
-// to point to randtbl[1] (as explained below).
-//
-
- fptr = &randtbl[SEP_3 + 1];
- rptr = &randtbl[1];
-
-//
-// The following things are the pointer to the state information table, the
-// type of the current generator, the degree of the current polynomial being
-// used, and the separation between the two pointers. Note that for efficiency
-// of random(), we remember the first location of the state information, not
-// the zeroeth. Hence it is valid to access state[-1], which is used to
-// store the type of the R.N.G. Also, we remember the last location, since
-// this is more efficient than indexing every time to find the address of
-// the last element to see if the front and rear pointers have wrapped.
-//
-
- state = &randtbl[1];
- rand_type = TYPE_3;
- rand_deg = DEG_3;
- rand_sep = SEP_3;
- end_ptr = &randtbl[DEG_3 + 1];
-
-}
-
-//
-// Compute x = (7^5 * x) mod (2^31 - 1)
-// wihout overflowing 31 bits:
-// (2^31 - 1) = 127773 * (7^5) + 2836
-// From "Random number generators: good ones are hard to find",
-// Park and Miller, Communications of the ACM, vol. 31, no. 10,
-// October 1988, p. 1195.
-//
-
-__inline static long good_rand(long x)
-{
- long hi, lo;
-
- // Can't be initialized with 0, so use another value.
- if (x == 0) x = 123459876;
- hi = x / 127773;
- lo = x % 127773;
- x = 16807 * lo - 2836 * hi;
- if (x < 0) x += 0x7fffffff;
- return x;
-}
-
-//
-// srandom
-//
-// Initialize the random number generator based on the given seed. If the
-// type is the trivial no-state-information type, just remember the seed.
-// Otherwise, initializes state[] based on the given "seed" via a linear
-// congruential generator. Then, the pointers are set to known locations
-// that are exactly rand_sep places apart. Lastly, it cycles the state
-// information a given number of times to get rid of any initial dependencies
-// introduced by the L.C.R.N.G. Note that the initialization of randtbl[]
-// for default usage relies on values produced by this routine.
-
-void RandomGenerator::srandom(unsigned long x)
-{
- long i, lim;
-
- state[0] = x;
- if (rand_type == TYPE_0)
- lim = NSHUFF;
- else
- {
- for (i = 1; i < rand_deg; i++) state[i] = good_rand(state[i - 1]);
- fptr = &state[rand_sep];
- rptr = &state[0];
- lim = 10 * rand_deg;
- }
-
- initialized = 1;
- for (i = 0; i < lim; i++) random();
-}
-
-#ifdef NOT_FOR_SUPERTUX // use in supertux doesn't require these methods,
- // which are not portable to as many platforms as
- // SDL. The cost is that the variability of the
- // initial seed is reduced to only 32 bits of
- // randomness, seemingly enough. PAK 060420
-//
-// srandomdev
-//
-// Many programs choose the seed value in a totally predictable manner.
-// This often causes problems. We seed the generator using the much more
-// secure random() interface. Note that this particular seeding
-// procedure can generate states which are impossible to reproduce by
-// calling srandom() with any value, since the succeeding terms in the
-// state buffer are no longer derived from the LC algorithm applied to
-// a fixed seed.
-
-void RandomGenerator::srandomdev()
-{
- int fd, done;
- size_t len;
-
- if (rand_type == TYPE_0)
- len = sizeof state[0];
- else
- len = rand_deg * sizeof state[0];
-
- done = 0;
- fd = open("/dev/urandom", O_RDONLY);
- if (fd >= 0)
- {
- if (read(fd, state, len) == len) done = 1;
- close(fd);
- }
-
- if (!done)
- {
- struct timeval tv;
-
- gettimeofday(&tv, NULL);
- srandom(tv.tv_sec ^ tv.tv_usec);
- return;
- }
-
- if (rand_type != TYPE_0)
- {
- fptr = &state[rand_sep];
- rptr = &state[0];
- }
- initialized = 1;
-}
-
-//
-// initstate
-//
-// Initialize the state information in the given array of n bytes for future
-// random number generation. Based on the number of bytes we are given, and
-// the break values for the different R.N.G.'s, we choose the best (largest)
-// one we can and set things up for it. srandom() is then called to
-// initialize the state information.
-//
-// Note that on return from srandom(), we set state[-1] to be the type
-// multiplexed with the current value of the rear pointer; this is so
-// successive calls to initstate() won't lose this information and will be
-// able to restart with setstate().
-//
-// Note: the first thing we do is save the current state, if any, just like
-// setstate() so that it doesn't matter when initstate is called.
-//
-// Returns a pointer to the old state.
-//
-
-char * RandomGenerator::initstate(unsigned long seed, char *arg_state, long n)
-{
- char *ostate = (char *) (&state[-1]);
- long *long_arg_state = (long *) arg_state;
-
- if (rand_type == TYPE_0)
- state[-1] = rand_type;
- else
- state[-1] = MAX_TYPES * (rptr - state) + rand_type;
-
- if (n < BREAK_0) return NULL;
-
- if (n < BREAK_1)
- {
- rand_type = TYPE_0;
- rand_deg = DEG_0;
- rand_sep = SEP_0;
- }
- else if (n < BREAK_2)
- {
- rand_type = TYPE_1;
- rand_deg = DEG_1;
- rand_sep = SEP_1;
- }
- else if (n < BREAK_3)
- {
- rand_type = TYPE_2;
- rand_deg = DEG_2;
- rand_sep = SEP_2;
- }
- else if (n < BREAK_4)
- {
- rand_type = TYPE_3;
- rand_deg = DEG_3;
- rand_sep = SEP_3;
- }
- else
- {
- rand_type = TYPE_4;
- rand_deg = DEG_4;
- rand_sep = SEP_4;
- }
-
- state = (long *) (long_arg_state + 1); // First location
- end_ptr = &state[rand_deg]; // Must set end_ptr before srandom
- srandom(seed);
-
- if (rand_type == TYPE_0)
- long_arg_state[0] = rand_type;
- else
- long_arg_state[0] = MAX_TYPES * (rptr - state) + rand_type;
-
- initialized = 1;
- return ostate;
-}
-
-//
-// setstate
-//
-// Restore the state from the given state array.
-//
-// Note: it is important that we also remember the locations of the pointers
-// in the current state information, and restore the locations of the pointers
-// from the old state information. This is done by multiplexing the pointer
-// location into the zeroeth word of the state information.
-//
-// Note that due to the order in which things are done, it is OK to call
-// setstate() with the same state as the current state.
-//
-// Returns a pointer to the old state information.
-//
-
-char * RandomGenerator::setstate(char *arg_state)
-{
- long *new_state = (long *) arg_state;
- long type = new_state[0] % MAX_TYPES;
- long rear = new_state[0] / MAX_TYPES;
- char *ostate = (char *) (&state[-1]);
-
- if (rand_type == TYPE_0)
- state[-1] = rand_type;
- else
- state[-1] = MAX_TYPES * (rptr - state) + rand_type;
-
- switch(type)
- {
- case TYPE_0:
- case TYPE_1:
- case TYPE_2:
- case TYPE_3:
- case TYPE_4:
- rand_type = type;
- rand_deg = degrees[type];
- rand_sep = seps[type];
- break;
- }
-
- state = (long *) (new_state + 1);
- if (rand_type != TYPE_0)
- {
- rptr = &state[rear];
- fptr = &state[(rear + rand_sep) % rand_deg];
- }
- end_ptr = &state[rand_deg]; // Set end_ptr too
-
- initialized = 1;
- return ostate;
-}
-#endif //NOT_FOR_SUPERTUX
-//
-// random:
-//
-// If we are using the trivial TYPE_0 R.N.G., just do the old linear
-// congruential bit. Otherwise, we do our fancy trinomial stuff, which is
-// the same in all the other cases due to all the global variables that have
-// been set up. The basic operation is to add the number at the rear pointer
-// into the one at the front pointer. Then both pointers are advanced to
-// the next location cyclically in the table. The value returned is the sum
-// generated, reduced to 31 bits by throwing away the "least random" low bit.
-//
-// Note: the code takes advantage of the fact that both the front and
-// rear pointers can't wrap on the same call by not testing the rear
-// pointer if the front one has wrapped.
-//
-// Returns a 31-bit random number.
-//
-
-long RandomGenerator::random()
-{
- long i;
- long *f, *r;
- if (!initialized) {
- throw std::runtime_error("uninitialized RandomGenerator object");
- }
-
- if (rand_type == TYPE_0)
- {
- i = state[0];
- state[0] = i = (good_rand(i)) & 0x7fffffff;
- }
- else
- {
- f = fptr; r = rptr;
- *f += *r;
- i = (*f >> 1) & 0x7fffffff; // Chucking least random bit
- if (++f >= end_ptr)
- {
- f = state;
- ++r;
- }
- else if (++r >= end_ptr)
- r = state;
-
- fptr = f; rptr = r;
- }
-
- return i;
-}
+++ /dev/null
-// $Id$
-//
-// A strong random number generator
-//
-// Copyright (C) 2006 Allen King
-// Copyright (C) 2002 Michael Ringgaard. All rights reserved.
-// Copyright (C) 1983, 1993 The Regents of the University of California.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions
-// are met:
-//
-// 1. Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// 2. Redistributions in binary form must reproduce the above copyright
-// notice, this list of conditions and the following disclaimer in the
-// documentation and/or other materials provided with the distribution.
-// 3. Neither the name of the project nor the names of its contributors
-// may be used to endorse or promote products derived from this software
-// without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
-// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-// OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-// SUCH DAMAGE.
-
-#ifndef __RANDOM_GENERATOR__
-#define __RANDOM_GENERATOR__
-
-class RandomGenerator
-{
-private:
-// Array versions of the above information to make code run faster --
-// relies on fact that TYPE_i == i.
- static const int TYPE_0 = 0; // Linear congruential
- static const int BREAK_0 = 8;
- static const int DEG_0 = 0;
- static const int SEP_0 = 0;
-
- static const int TYPE_1 = 1; // x**7 + x**3 + 1
- static const int BREAK_1 = 32;
- static const int DEG_1 = 7;
- static const int SEP_1 = 3;
-
- static const int TYPE_2 = 2; // x**15 + x + 1
- static const int BREAK_2 = 64;
- static const int DEG_2 = 15;
- static const int SEP_2 = 1;
-
- static const int TYPE_3 = 3; // x**31 + x**3 + 1
- static const int BREAK_3 = 128;
- static const int DEG_3 = 31;
- static const int SEP_3 = 3;
-
- static const int TYPE_4 = 4; // x**63 + x + 1
- static const int BREAK_4 = 256;
- static const int DEG_4 = 63;
- static const int SEP_4 = 1;
-
- static const int MAX_TYPES = 5; // Max number of types above
-
- bool initialized;
- long degrees[MAX_TYPES];
- long seps [MAX_TYPES];
- long randtbl[DEG_3 + 1];
-
- long *fptr;
- long *rptr;
-
- long *state;
- long rand_type;
- long rand_deg;
- long rand_sep;
- long *end_ptr;
- int debug;
- static const int rand_max = 0x7fffffff; // biggest signed Uint32
-
-public:
- RandomGenerator();
- ~RandomGenerator();
-
-// Documentation of user-visible calls:
-
- // Initialize the RNG with a 31-bit seed
- // if x is zero or absent, calls to time() will get a time-randomized seed
- // the value returned is the value of the seed used.
- int srand(int x=0);
-
- // generate random 31-bit numbers
- // calls to the following return a value evenly distributed between u (or
- // 0 if not specified) and v (or rand_max if not specified). Return
- // values may include u, but never v.
- int rand();
- int rand(int v);
- int rand(int u, int v);
- double randf(double v);
- double randf(double u, double v);
-
- // For Squirrel wrapper, since miniswig (and even squirrel?) doesn't
- // support function overloading or doubles
- int rand1i(int v) { return rand(v); }
- int rand2i(int u, int v) { return rand(u, v); }
- float rand1f(float v)
- { return static_cast<float>(randf(static_cast<double>(v))); }
- float rand2f(float u, float v)
- { return static_cast<float>(randf(static_cast<double>(u),
- static_cast<double>(v))); }
-
-//private:
- void initialize();
- void srandom(unsigned long x);
-// void srandomdev();
-// char *initstate(unsigned long seed, char *arg_state, long n);
-// char *setstate(char *arg_state);
- long random();
-};
-
-extern RandomGenerator systemRandom;
-
-#endif //__RANDOM_GENERATOR__
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#ifndef __REF_HPP__
-#define __REF_HPP__
-
-/** This class behaves like a pointer to a refcounted object, but increments the
- * reference count when new objects are assigned and decrements the refcounter
- * when it's lifetime has experied. (similar to std::auto_ptr)
- */
-template<typename T>
-class Ref
-{
-public:
- Ref(T* object = 0)
- : object(object)
- {
- if(object)
- object->ref();
- }
- Ref(const Ref<T>& other)
- : object(other.object)
- {
- if(object)
- object->ref();
- }
- ~Ref()
- {
- if(object)
- object->unref();
- }
-
- void operator= (const Ref<T>& other)
- {
- *this = other.get();
- }
-
- void operator= (T* object)
- {
- if(object)
- object->ref();
- if(this->object)
- this->object->unref();
- this->object = object;
- }
-
- T* operator ->() const
- {
- return object;
- }
-
- T& operator* () const
- {
- return *object;
- }
-
- operator const T* () const
- {
- return object;
- }
-
- T* get() const
- {
- return object;
- }
-
-private:
- T* object;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// Windstille - A Jump'n Shoot Game
-// Copyright (C) 2005 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#ifndef __REFCOUNTER_HPP__
-#define __REFCOUNTER_HPP__
-
-#include <assert.h>
-
-/**
- * A base class that provides reference counting facilities
- */
-class RefCounter
-{
-public:
- RefCounter()
- : refcount(0)
- { }
-
- /** increases reference count */
- void ref()
- {
- refcount++;
- }
- /** decreases reference count. Destroys the object if the reference count
- * reaches 0
- */
- void unref()
- {
- refcount--;
- if(refcount <= 0) {
- delete this;
- }
- }
-
-protected:
- virtual ~RefCounter()
- {
- assert(refcount == 0);
- }
-
-private:
- int refcount;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2003 Tobias Glaesser <tobi.web@gmx.de>
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#include <config.h>
-
-#include "sprite/sprite_manager.hpp"
-#include "gui/menu.hpp"
-#include "gui/button.hpp"
-#include "resources.hpp"
-#include "file_system.hpp"
-#include "tile_manager.hpp"
-#include "object/gameobjs.hpp"
-#include "object/player.hpp"
-
-MouseCursor* mouse_cursor = NULL;
-
-Font* gold_text = NULL;
-Font* gold_fixed_text = NULL;
-Font* blue_text = NULL;
-Font* gray_text = NULL;
-Font* white_text = NULL;
-Font* white_small_text = NULL;
-Font* white_big_text = NULL;
-
-/* Load graphics/sounds shared between all levels: */
-void load_shared()
-{
- /* Load the mouse-cursor */
- mouse_cursor = new MouseCursor("images/engine/menu/mousecursor.png");
- MouseCursor::set_current(mouse_cursor);
-
- /* Load global images: */
- gold_text = new Font(Font::VARIABLE,
- "images/engine/fonts/gold.png",
- "images/engine/fonts/shadow.png", 16, 18);
- gold_fixed_text = new Font(Font::FIXED,
- "images/engine/fonts/gold.png",
- "images/engine/fonts/shadow.png", 16, 18);
- blue_text = new Font(Font::VARIABLE,
- "images/engine/fonts/blue.png",
- "images/engine/fonts/shadow.png", 16, 18, 3);
- white_text = new Font(Font::VARIABLE,
- "images/engine/fonts/white.png",
- "images/engine/fonts/shadow.png", 16, 18);
- gray_text = new Font(Font::VARIABLE,
- "images/engine/fonts/gray.png",
- "images/engine/fonts/shadow.png", 16, 18);
- white_small_text = new Font(Font::VARIABLE,
- "images/engine/fonts/white-small.png",
- "images/engine/fonts/shadow-small.png", 8, 9, 1);
- white_big_text = new Font(Font::VARIABLE,
- "images/engine/fonts/white-big.png",
- "images/engine/fonts/shadow-big.png", 20, 22, 3);
-
- Menu::default_font = white_text;
- Menu::active_font = blue_text;
- Menu::deactive_font = gray_text;
- Menu::label_font = white_big_text;
- Menu::field_font = gold_text;
-
- Button::info_font = white_small_text;
-
- sprite_manager = new SpriteManager();
- tile_manager = new TileManager("images/tiles.strf");
-
- /* Tuxes: */
- char img_name[1024];
- for (int i = 0; i < GROWING_FRAMES; i++)
- {
- snprintf(img_name, sizeof(img_name), "images/creatures/tux_grow/left-%i.png", i+1);
- growingtux_left[i] = new Surface(img_name);
-
- snprintf(img_name, sizeof(img_name), "images/creatures/tux_grow/right-%i.png", i+1);
- growingtux_right[i] = new Surface(img_name);
- }
-
- small_tux = new TuxBodyParts();
- small_tux->head = 0;
- small_tux->body = sprite_manager->create("images/creatures/tux_small/small-tux-body.sprite");
- small_tux->arms = sprite_manager->create("images/creatures/tux_small/small-tux-arms.sprite");
- small_tux->feet = 0;
-
- big_tux = new TuxBodyParts();
- big_tux->head = sprite_manager->create("images/creatures/tux_big/big-tux-head.sprite");
- big_tux->body = sprite_manager->create("images/creatures/tux_big/big-tux-body.sprite");
- big_tux->arms = sprite_manager->create("images/creatures/tux_big/big-tux-arms.sprite");
- big_tux->feet = sprite_manager->create("images/creatures/tux_big/big-tux-feet.sprite");
-
- fire_tux = new TuxBodyParts();
- fire_tux->head = sprite_manager->create("images/creatures/tux_big/big-fire-tux-head.sprite");
- fire_tux->body = sprite_manager->create("images/creatures/tux_big/big-tux-body.sprite");
- fire_tux->arms = sprite_manager->create("images/creatures/tux_big/big-tux-arms.sprite");
- fire_tux->feet = sprite_manager->create("images/creatures/tux_big/big-tux-feet.sprite");
-
- ice_tux = new TuxBodyParts();
- ice_tux->head = sprite_manager->create("images/creatures/tux_big/big-ice-tux-head.sprite");
- ice_tux->body = sprite_manager->create("images/creatures/tux_big/big-tux-body.sprite");
- ice_tux->arms = sprite_manager->create("images/creatures/tux_big/big-tux-arms.sprite");
- ice_tux->feet = sprite_manager->create("images/creatures/tux_big/big-tux-feet.sprite");
-
- player_status = new PlayerStatus();
-}
-
-/* Free shared data: */
-void unload_shared()
-{
- /* Free global images: */
- delete gold_text;
- delete gold_fixed_text;
- delete white_text;
- delete blue_text;
- delete gray_text;
- delete white_small_text;
- delete white_big_text;
-
- delete small_tux;
- delete big_tux;
- delete fire_tux;
- delete ice_tux;
-
- for (int i = 0; i < GROWING_FRAMES; i++) {
- delete growingtux_left[i];
- delete growingtux_right[i];
- }
-
- delete sprite_manager;
- sprite_manager = NULL;
- delete tile_manager;
- tile_manager = NULL;
-
- /* Free mouse-cursor */
- delete mouse_cursor;
-
- delete player_status;
- player_status = NULL;
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2003 Tobias Glaesser <tobi.web@gmx.de>
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#ifndef SUPERTUX_RESOURCES_H
-#define SUPERTUX_RESOURCES_H
-
-class Font;
-class MouseCursor;
-
-extern MouseCursor* mouse_cursor;
-
-extern Font* gold_text;
-extern Font* gold_fixed_text;
-extern Font* white_text;
-extern Font* blue_text;
-extern Font* gray_text;
-extern Font* white_small_text;
-extern Font* white_big_text;
-
-void load_shared();
-void unload_shared();
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#ifndef __SCREEN_HPP__
-#define __SCREEN_HPP__
-
-class DrawingContext;
-
-class Screen
-{
-public:
- virtual ~Screen()
- {}
-
- /**
- * gets called before this screen gets activated (which is at least once
- * before the first draw or update call
- */
- virtual void setup()
- {}
- /** gets called when the current screen is temporarily suspended */
- virtual void leave()
- {}
-
- /**
- * gets called once per frame. The screen should draw itself in this function.
- * State changes should not be done in this function, but rather in update
- */
- virtual void draw(DrawingContext& context) = 0;
-
- /**
- * gets called for once (per logical) frame. Screens should do their state
- * updates and logic here
- */
- virtual void update(float elapsed_time) = 0;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#ifndef __SCREENFADE_HPP__
-#define __SCREENFADE_HPP__
-
-#include "screen.hpp"
-
-/**
- * A ScreenFade screen is displayed simultaneously with another screen. This
- * is intended to be used for transitional effects like fade-out or shrink-fade
- */
-class ScreenFade : public Screen
-{
-public:
- virtual ~ScreenFade()
- {}
-
- /// returns true if the effect is completed
- virtual bool done() = 0;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#ifndef __SCRIPT_INTERFACE_HPP__
-#define __SCRIPT_INTERFACE_HPP__
-
-#include <squirrel.h>
-
-/**
- * Objects that want to expose themself to the scripting environment
- * should implement this interface
- */
-class ScriptInterface
-{
-public:
- virtual ~ScriptInterface()
- {}
-
- virtual void expose(HSQUIRRELVM vm, SQInteger table_idx) = 0;
- virtual void unexpose(HSQUIRRELVM vm, SQInteger table_idx) = 0;
-};
-
-#endif
+++ /dev/null
-SubDir TOP src scripting ;
-
-if $(MINISWIG)
-{
- ## MiniSwigRule outputcppfile : inputfile : modulename : flags
- rule MiniSwigRule
- {
- local sources = [ SearchSource $(>) ] ;
- local cppfile = [ LocateTarget $(<) : $(SUBDIR) ] ;
- local headerfile = [ LocateTarget $(<:S=.hpp) : $(SUBDIR) ] ;
- SEARCH on $(headerfile) = $(SOURCH_SOURCE) ;
-
- MiniSwig $(cppfile) : $(sources) ;
-
- CPPFLAGS on $(cppfile) = $(CPPFLAGS) -DSCRIPTING_API ;
- headerfile on $(cppfile) = $(headerfile) ;
- modulename on $(cppfile) = $(3) ;
- FLAGS on $(cppfile) = $(4) ;
-
- local h = $(headerfile:G=) ;
- h = $(h:D=) ;
- Includes $(h) : $(headerfile) ;
- Includes $(headerfile) : $(cppfile) ;
-
- local object = [ CompileObject $(cppfile) ] ;
-
- return $(object) ;
- }
-
- rule MiniSwig
- {
- Depends $(<) : $(>) $(MINISWIG) ;
- }
-
- actions MiniSwig bind headerfile
- {
- $(CPP) -x c -CC $(CPPFLAGS) $(>) -o $(LOCATE_OBJECTS)/miniswig.tmp
- ./miniswig --output-cpp $(<) --input $(LOCATE_OBJECTS)/miniswig.tmp --output-hpp $(headerfile) --module $(modulename) $(FLAGS)
-# rm -f $(LOCATE_OBJECTS)/miniswig.tmp
- }
-}
-
-wrapper_sources = [ Filter [ Wildcard *.cpp *.hpp ] : wrapper.cpp wrapper.hpp ] ;
-if ! $(MINISWIG)
-{
- wrapper_sources += [ SearchSource wrapper.cpp ] ;
-}
-wrapper_objects = [ CompileObjects $(wrapper_sources) ] ;
-if $(MINISWIG)
-{
- wrapper_objects +=
- [ MiniSwigRule wrapper.cpp : wrapper.interface.hpp : supertux : --select-namespace Scripting ] ;
-}
-
+++ /dev/null
-#ifndef __SCRIPTING_AMBIENT_SOUND_H__
-#define __SCRIPTING_AMBIENT_SOUND_H__
-
-namespace Scripting
-{
-
-class AmbientSound
-{
-public:
-#ifndef SCRIPTING_API
- virtual ~AmbientSound()
- {}
-#endif
-
- virtual void set_pos(float x, float y) = 0;
- virtual float get_pos_x() const = 0;
- virtual float get_pos_y() const = 0;
-};
-
-}
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __ANCHOR_POINTS_HPP__
-#define __ANCHOR_POINTS_HPP__
-
-namespace Scripting {
-
-// TODO get these from the definitions in anchor.h (needs miniswig update)
-static const int ANCHOR_TOP = 0x0010;
-static const int ANCHOR_BOTTOM = 0x0020;
-static const int ANCHOR_LEFT = 0x0001;
-static const int ANCHOR_RIGHT = 0x0002;
-static const int ANCHOR_MIDDLE = 0x0000;
-static const int ANCHOR_TOP_LEFT = 0x0011;
-static const int ANCHOR_TOP_RIGHT = 0x0012;
-static const int ANCHOR_BOTTOM_LEFT = 0x0021;
-static const int ANCHOR_BOTTOM_RIGHT = 0x0022;
-
-}
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include <string>
-#include <stdio.h>
-#include "object/camera.hpp"
-#include "scripting/camera.hpp"
-#include "math/vector.hpp"
-
-#define NOIMPL log_fatal << __FUNCTION__ << " not implemented."
-
-namespace Scripting
-{
- Camera::Camera(::Camera* camera)
- : camera(camera)
- { }
-
- Camera::~Camera()
- { }
-
- void
- Camera::reload_config()
- {
- camera->reload_config();
- }
-
- void
- Camera::shake(float speed, float x, float y)
- {
- camera->shake(speed, x, y);
- }
-
- void
- Camera::set_pos(float , float )
- {
- }
-
- void
- Camera::set_mode(const std::string& mode)
- {
- if(mode == "normal") {
- camera->mode = ::Camera::NORMAL;
- } else if(mode == "manual") {
- camera->mode = ::Camera::MANUAL;
- } else {
- log_fatal << "Camera mode '" << mode << "' unknown.";
- }
- }
-
- void
- Camera::scroll_to(float x, float y, float scrolltime)
- {
- camera->scroll_to(Vector(x, y), scrolltime);
- }
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __CAMERA_H__
-#define __CAMERA_H__
-
-#ifndef SCRIPTING_API
-class Camera;
-typedef Camera _Camera;
-#endif
-
-namespace Scripting
-{
-
-class Camera
-{
-public:
-#ifndef SCRIPTING_API
- Camera(_Camera* camera);
- ~Camera();
-#endif
-
- void reload_config();
-
- /** Shake the camera */
- void shake(float speed, float x, float y);
- /** Set camera to a specific coordinate */
- void set_pos(float x, float y);
- /** Set camera to a specific mode, can be "normal", "manual" */
- void set_mode(const std::string& mode);
- /** Scroll camera to position x,y in scrolltime seconds */
- void scroll_to(float x, float y, float scrolltime);
-
-#ifndef SCRIPTING_API
- _Camera* camera;
-#endif
-};
-
-}
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include <string>
-#include <stdio.h>
-#include "object/candle.hpp"
-#include "scripting/candle.hpp"
-#include "math/vector.hpp"
-
-#define NOIMPL log_fatal << __PRETTY_FUNCTION__ << " not implemented."
-
-namespace Scripting
-{
-
- Candle::Candle(::Candle* candle)
- : candle(candle)
- { }
-
- Candle::~Candle()
- { }
-
- bool Candle::get_burning()
- {
- return candle->get_burning();
- }
-
- void Candle::set_burning(bool burning)
- {
- candle->set_burning(burning);
- }
-
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __SCRIPTING_CANDLE_H__
-#define __SCRIPTING_CANDLE_H__
-
-#ifndef SCRIPTING_API
-class Candle;
-typedef Candle _Candle;
-#endif
-
-namespace Scripting
-{
-
-class Candle
-{
-public:
-#ifndef SCRIPTING_API
- Candle(_Candle* candle);
- ~Candle();
-#endif
-
- bool get_burning(); /**< returns true if candle is lighted */
- void set_burning(bool burning); /**< true: light candle, false: extinguish candle */
-
-#ifndef SCRIPTING_API
- _Candle* candle;
-#endif
-};
-
-}
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __SCRIPTING_DISPLAY_EFFECT_H__
-#define __SCRIPTING_DISPLAY_EFFECT_H__
-
-namespace Scripting
-{
-
-class DisplayEffect
-{
-public:
-#ifndef SCRIPTING_API
- virtual ~DisplayEffect()
- {}
-#endif
-
- /// fade display to black
- virtual void fade_out(float fadetime) = 0;
- /// fade display from black to normal
- virtual void fade_in(float fadetime) = 0;
- /// set display black (or back to normal)
- virtual void set_black(bool enabled) = 0;
- /// check if display is set to black
- virtual bool is_black() = 0;
- /// set black borders for cutscenes
- virtual void sixteen_to_nine(float fadetime) = 0;
- /// deactivate borders
- virtual void four_to_three(float fadetime) = 0;
-
- // fade display until just a small visible circle is left
- // (like what happens in some cartoons at the end)
- // void shrink_fade(Vector goal, float radius, float fadetime);
-};
-
-}
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#include <config.h>
-
-#include <assert.h>
-#include <stdexcept>
-#include "floating_image.hpp"
-#include "sector.hpp"
-#include "object/floating_image.hpp"
-#include "worldmap/worldmap.hpp"
-
-namespace Scripting
-{
-
-FloatingImage::FloatingImage(const std::string& spritefile)
-{
- using namespace WorldMapNS;
-
- floating_image = new _FloatingImage(spritefile);
- if(Sector::current() != NULL) {
- Sector::current()->add_object(floating_image.get());
- } else if(WorldMap::current() != NULL) {
- WorldMap::current()->add_object(floating_image.get());
- } else {
- throw new std::runtime_error("Neither sector nor worldmap active");
- }
-}
-
-FloatingImage::~FloatingImage()
-{
- floating_image->remove_me();
-}
-
-void
-FloatingImage::set_layer(int layer)
-{
- floating_image->set_layer(layer);
-}
-
-int
-FloatingImage::get_layer()
-{
- return floating_image->get_layer();
-}
-
-void
-FloatingImage::set_pos(float x, float y)
-{
- floating_image->set_pos(Vector(x, y));
-}
-
-float
-FloatingImage::get_pos_x()
-{
- return floating_image->get_pos().x;
-}
-
-float
-FloatingImage::get_pos_y()
-{
- return floating_image->get_pos().y;
-}
-
-void
-FloatingImage::set_anchor_point(int anchor)
-{
- floating_image->set_anchor_point((AnchorPoint) anchor);
-}
-
-int
-FloatingImage::get_anchor_point()
-{
- return (int) floating_image->get_anchor_point();
-}
-
-bool
-FloatingImage::get_visible()
-{
- return floating_image->get_visible();
-}
-
-void
-FloatingImage::set_visible(bool visible)
-{
- floating_image->set_visible(visible);
-}
-
-void
-FloatingImage::set_action(const std::string& action)
-{
- floating_image->set_action(action);
-}
-
-std::string
-FloatingImage::get_action()
-{
- return floating_image->get_action();
-}
-
-void
-FloatingImage::fade_in(float fadetime)
-{
- floating_image->fade_in(fadetime);
-}
-
-void
-FloatingImage::fade_out(float fadetime)
-{
- floating_image->fade_out(fadetime);
-}
-
-
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __FLOATING_IMAGE_HPP__
-#define __FLOATING_IMAGE_HPP__
-
-#ifndef SCRIPTING_API
-#define __suspend
-#include <string>
-#include "ref.hpp"
-
-class FloatingImage;
-typedef FloatingImage _FloatingImage;
-#endif
-
-namespace Scripting
-{
-
-class FloatingImage
-{
-public:
- FloatingImage(const std::string& spritefile);
- ~FloatingImage();
-
- void set_layer(int layer);
- int get_layer();
- void set_pos(float x, float y);
- float get_pos_x();
- float get_pos_y();
- void set_anchor_point(int anchor);
- int get_anchor_point();
- void set_visible(bool visible);
- bool get_visible();
- void set_action(const std::string& action);
- std::string get_action();
- void fade_in(float fadetime);
- void fade_out(float fadetime);
-
-#ifndef SCRIPTING_API
-private:
- Ref<_FloatingImage> floating_image;
-#endif
-};
-
-}
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include <memory>
-#include <stdio.h>
-#include <string>
-#include <squirrel.h>
-#include <sqstdio.h>
-#include "textscroller.hpp"
-#include "functions.hpp"
-#include "game_session.hpp"
-#include "tinygettext/tinygettext.hpp"
-#include "physfs/physfs_stream.hpp"
-#include "resources.hpp"
-#include "gettext.hpp"
-#include "log.hpp"
-#include "mainloop.hpp"
-#include "worldmap/worldmap.hpp"
-#include "world.hpp"
-#include "sector.hpp"
-#include "gameconfig.hpp"
-#include "object/player.hpp"
-#include "object/tilemap.hpp"
-#include "main.hpp"
-#include "fadeout.hpp"
-#include "shrinkfade.hpp"
-#include "object/camera.hpp"
-#include "flip_level_transformer.hpp"
-#include "audio/sound_manager.hpp"
-#include "random_generator.hpp"
-
-#include "squirrel_error.hpp"
-#include "squirrel_util.hpp"
-#include "time_scheduler.hpp"
-
-namespace Scripting
-{
-
-SQInteger display(HSQUIRRELVM vm)
-{
- Console::output << squirrel2string(vm, -1) << std::endl;
- return 0;
-}
-
-void print_stacktrace(HSQUIRRELVM vm)
-{
- print_squirrel_stack(vm);
-}
-
-SQInteger get_current_thread(HSQUIRRELVM vm)
-{
- sq_pushobject(vm, vm_to_object(vm));
- return 1;
-}
-
-void wait(HSQUIRRELVM vm, float seconds)
-{
- TimeScheduler::instance->schedule_thread(vm, game_time + seconds);
-}
-
-void wait_for_screenswitch(HSQUIRRELVM vm)
-{
- main_loop->waiting_threads.add(vm);
-}
-
-void exit_screen()
-{
- main_loop->exit_screen();
-}
-
-void fadeout_screen(float seconds)
-{
- main_loop->set_screen_fade(new FadeOut(seconds));
-}
-
-void shrink_screen(float dest_x, float dest_y, float seconds)
-{
- main_loop->set_screen_fade(new ShrinkFade(Vector(dest_x, dest_y), seconds));
-}
-
-void abort_screenfade()
-{
- main_loop->set_screen_fade(NULL);
-}
-
-std::string translate(const std::string& text)
-{
- return dictionary_manager.get_dictionary().translate(text);
-}
-
-void display_text_file(const std::string& filename)
-{
- main_loop->push_screen(new TextScroller(filename));
-}
-
-void load_worldmap(const std::string& filename)
-{
- using namespace WorldMapNS;
-
- main_loop->push_screen(new WorldMap(filename));
-}
-
-void load_level(const std::string& filename)
-{
- main_loop->push_screen(new GameSession(filename));
-}
-
-static SQInteger squirrel_read_char(SQUserPointer file)
-{
- std::istream* in = reinterpret_cast<std::istream*> (file);
- char c = in->get();
- if(in->eof())
- return 0;
-
- return c;
-}
-
-void import(HSQUIRRELVM vm, const std::string& filename)
-{
- IFileStream in(filename);
-
- if(SQ_FAILED(sq_compile(vm, squirrel_read_char, &in,
- filename.c_str(), SQTrue)))
- throw SquirrelError(vm, "Couldn't parse script");
-
- sq_pushroottable(vm);
- if(SQ_FAILED(sq_call(vm, 1, SQFalse, SQTrue))) {
- sq_pop(vm, 1);
- throw SquirrelError(vm, "Couldn't execute script");
- }
- sq_pop(vm, 1);
-}
-
-void debug_collrects(bool enable)
-{
- Sector::show_collrects = enable;
-}
-
-void debug_show_fps(bool enable)
-{
- config->show_fps = enable;
-}
-
-void debug_draw_solids_only(bool enable)
-{
- Sector::draw_solids_only = enable;
-}
-
-void save_state()
-{
- using namespace WorldMapNS;
-
- if(World::current() == NULL || WorldMap::current() == NULL)
- throw std::runtime_error("Can't save state without active World");
-
- WorldMap::current()->save_state();
- World::current()->save_state();
-}
-
-void update_worldmap()
-{
- using namespace WorldMapNS;
-
- if(WorldMap::current() == NULL)
- throw std::runtime_error("Can't update Worldmap: none active");
-
- WorldMap::current()->load_state();
-}
-
-// not added to header, function to only be used by others
-// in this file
-bool validate_sector_player()
-{
- if (Sector::current() == 0)
- {
- log_info << "No current sector." << std::endl;
- return false;
- }
-
- if (Sector::current()->player == 0)
- {
- log_info << "No player." << std::endl;
- return false;
- }
- return true;
-}
-
-void play_music(const std::string& filename)
-{
- sound_manager->play_music(filename);
-}
-
-void play_sound(const std::string& filename)
-{
- sound_manager->play(filename);
-}
-
-void grease()
-{
- if (!validate_sector_player()) return;
- ::Player* tux = Sector::current()->player; // Scripting::Player != ::Player
- tux->physic.set_velocity_x(tux->physic.get_velocity_x()*3);
-}
-
-void invincible()
-{
- if (!validate_sector_player()) return;
- ::Player* tux = Sector::current()->player;
- tux->invincible_timer.start(10000);
-}
-
-void ghost()
-{
- if (!validate_sector_player()) return;
- ::Player* tux = Sector::current()->player;
- tux->set_ghost_mode(true);
-}
-
-void mortal()
-{
- if (!validate_sector_player()) return;
- ::Player* tux = Sector::current()->player;
- tux->invincible_timer.stop();
- tux->set_ghost_mode(false);
-}
-
-void restart()
-{
- if (GameSession::current() == 0)
- {
- log_info << "No game session" << std::endl;
- return;
- }
- GameSession::current()->restart_level();
-}
-
-void whereami()
-{
- if (!validate_sector_player()) return;
- ::Player* tux = Sector::current()->player;
- log_info << "You are at x " << tux->get_pos().x << ", y " << tux->get_pos().y << std::endl;
-}
-
-void gotoend()
-{
- if (!validate_sector_player()) return;
- ::Player* tux = Sector::current()->player;
- tux->move(Vector(
- (Sector::current()->get_width()) - (SCREEN_WIDTH*2), 0));
- Sector::current()->camera->reset(
- Vector(tux->get_pos().x, tux->get_pos().y));
-}
-
-void camera()
-{
- if (!validate_sector_player()) return;
- log_info << "Camera is at " << Sector::current()->camera->get_translation().x << "," << Sector::current()->camera->get_translation().y << std::endl;
-}
-
-void quit()
-{
- main_loop->quit();
-}
-
-int rand()
-{
- return systemRandom.rand();
-}
-
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __FUNCTIONS_H__
-#define __FUNCTIONS_H__
-
-#ifndef SCRIPTING_API
-#define __suspend
-#define __custom
-#include <string>
-#include "player_status.hpp"
-#endif
-
-namespace Scripting
-{
-
-/**
- * Display the value of the argument. This is usefull for inspecting tables.
- */
-SQInteger display(HSQUIRRELVM vm) __custom;
-
-/**
- * Displays contents of the current stack
- */
-void print_stacktrace(HSQUIRRELVM vm);
-
-/**
- * returns the currently running thread
- */
-SQInteger get_current_thread(HSQUIRRELVM vm) __custom;
-
-/**
- * Display a text file and scrolls it over the screen (on next screenswitch)
- */
-void display_text_file(const std::string& filename);
-
-/**
- * Load and display a worldmap (on next screenswitch)
- */
-void load_worldmap(const std::string& filename);
-
-/**
- * Load and display a level (on next screenswitch)
- */
-void load_level(const std::string& filename);
-
-/**
- * Suspend the script execution for the specified number of seconds
- */
-void wait(HSQUIRRELVM vm, float seconds) __suspend;
-
-/**
- * Suspend the script execution until the current screen has been changed
- */
-void wait_for_screenswitch(HSQUIRRELVM vm) __suspend;
-
-/**
- * Exits the currently running screen (force exit from worldmap or scrolling
- * text for example)
- */
-void exit_screen();
-
-/**
- * Does a fadeout for the specified number of seconds before next screenchange
- */
-void fadeout_screen(float seconds);
-
-/**
- * Does a shrinking fade towards the destposition for the specified number of
- * seconds before next screenchange
- */
-void shrink_screen(float dest_x, float dest_y, float seconds);
-
-/**
- * Aborts any kind of previous screen fade; the screenchange will happen
- * anyway.
- */
-void abort_screenfade();
-
-/**
- * Translate a text into the users language (by looking it up in the .po
- * files)
- */
-std::string translate(const std::string& text);
-
-/**
- * Load a script file and executes it. This is typically used to import
- * functions from external files.
- */
-void import(HSQUIRRELVM v, const std::string& filename);
-
-/**
- * Save world state to savegame
- */
-void save_state();
-
-/**
- * Update worldmap from worldmap state (state.world variable)
- */
-void update_worldmap();
-
-/**
- * enable/disable drawing of collision rectangles
- */
-void debug_collrects(bool enable);
-
-/**
- * enable/disable drawing of fps
- */
-void debug_show_fps(bool enable);
-
-/**
- * enable/disable drawing of non-solid layers
- */
-void debug_draw_solids_only(bool enable);
-
-/**
- * Changes music to musicfile
- */
-void play_music(const std::string& musicfile);
-
-/**
- * Plays a soundfile
- */
-void play_sound(const std::string& soundfile);
-
-/**
- * speeds Tux up
- */
-void grease();
-
-/**
- * makes Tux invincible for 10000 units of time
- */
-void invincible();
-
-/**
- * makes Tux a ghost, i.e. lets him float around and through solid objects
- */
-void ghost();
-
-/**
- * recall Tux's invincibility and ghost status
- */
-void mortal();
-
-/**
- * reinitialise and respawn Tux at the beginning of the current level
- */
-void restart();
-
-/**
- * print Tux's current coordinates in a level
- */
-void whereami();
-
-/**
- * move Tux near the end of the level
- */
-void gotoend();
-
-/**
- * show the camera's coordinates
- */
-void camera();
-
-/**
- * exit the game
- */
-void quit();
-
-/**
- * Returns a random integer
- */
-int rand();
-
-}
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include <string>
-#include <stdio.h>
-#include "level.hpp"
-#include "game_session.hpp"
-#include "flip_level_transformer.hpp"
-
-namespace Scripting
-{
- Level::Level()
- {}
-
- Level::~Level()
- {}
-
- void
- Level::finish(bool win)
- {
- if(GameSession::current() == NULL)
- return;
-
- GameSession::current()->finish(win);
- }
-
- void
- Level::spawn(const std::string& sector, const std::string& spawnpoint)
- {
- if(GameSession::current() == NULL)
- return;
-
- GameSession::current()->respawn(sector, spawnpoint);
- }
-
- void
- Level::flip_vertically()
- {
- FlipLevelTransformer flip_transformer;
- flip_transformer.transform(GameSession::current()->get_current_level());
- }
-
- void
- Level::toggle_pause()
- {
- if(GameSession::current() == NULL)
- return;
- GameSession::current()->toggle_pause();
- }
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __LEVEL_H__
-#define __LEVEL_H__
-
-namespace Scripting
-{
-
-class Level
-{
-public:
-#ifndef SCRIPTING_API
- Level();
- ~Level();
-#endif
-
- /** Instantly finish the currently played level */
- void finish(bool win);
- /** spawn tux at specified sector and spawnpoint */
- void spawn(const std::string& sector, const std::string& spawnpoint);
- /** Flip level vertically */
- void flip_vertically();
- /** toggle pause */
- void toggle_pause();
-};
-
-}
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include <string>
-#include <stdio.h>
-#include "object/level_time.hpp"
-#include "scripting/level_time.hpp"
-#include "math/vector.hpp"
-
-#define NOIMPL log_fatal << __PRETTY_FUNCTION__ << " not implemented."
-
-namespace Scripting
-{
-
- LevelTime::LevelTime(::LevelTime* level_time)
- : level_time(level_time)
- { }
-
- LevelTime::~LevelTime()
- { }
-
- void LevelTime::start()
- {
- level_time->start();
- }
-
- void LevelTime::stop()
- {
- level_time->stop();
- }
-
- float LevelTime::get_time()
- {
- return level_time->get_time();
- }
-
- void LevelTime::set_time(float time_left)
- {
- level_time->set_time(time_left);
- }
-
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __SCRIPTING_LEVELTIME_H__
-#define __SCRIPTING_LEVELTIME_H__
-
-#ifndef SCRIPTING_API
-class LevelTime;
-typedef LevelTime _LevelTime;
-#endif
-
-namespace Scripting
-{
-
-class LevelTime
-{
-public:
-#ifndef SCRIPTING_API
- LevelTime(_LevelTime* level_time);
- ~LevelTime();
-#endif
-
- /**
- * Resumes the countdown
- */
- void start();
-
- /**
- * Pauses the countdown
- */
- void stop();
-
- /**
- * Returns the number of seconds left on the clock
- */
- float get_time();
-
- /**
- * Changes the number of seconds left on the clock
- */
- void set_time(float time_left);
-
-#ifndef SCRIPTING_API
- _LevelTime* level_time;
-#endif
-};
-
-}
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include <string>
-#include <stdio.h>
-#include "object/platform.hpp"
-#include "scripting/platform.hpp"
-#include "math/vector.hpp"
-
-#define NOIMPL log_fatal << __PRETTY_FUNCTION__ << " not implemented."
-
-namespace Scripting
-{
-
- Platform::Platform(::Platform* platform)
- : platform(platform)
- { }
-
- Platform::~Platform()
- { }
-
- void Platform::goto_node(int node_no)
- {
- platform->goto_node(node_no);
- }
-
- void Platform::start_moving()
- {
- platform->start_moving();
- }
-
- void Platform::stop_moving()
- {
- platform->stop_moving();
- }
-
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __SCRIPTING_PLATFORM_H__
-#define __SCRIPTING_PLATFORM_H__
-
-#ifndef SCRIPTING_API
-class Platform;
-typedef Platform _Platform;
-#endif
-
-namespace Scripting
-{
-
-class Platform
-{
-public:
-#ifndef SCRIPTING_API
- Platform(_Platform* platform);
- ~Platform();
-#endif
-
- /** Move platform until at given node, then stop */
- void goto_node(int node_no);
-
- /** Start moving platform */
- void start_moving();
-
- /** Stop platform at next node */
- void stop_moving();
-
-#ifndef SCRIPTING_API
- _Platform* platform;
-#endif
-};
-
-}
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __SCRIPTING_PLAYER_H__
-#define __SCRIPTING_PLAYER_H__
-
-namespace Scripting
-{
-
-class Player
-{
-public:
-#ifndef SCRIPTING_API
- virtual ~Player()
- {}
-#endif
-
- /**
- * Set tux bonus.
- * This can be "grow", "fireflower" or "iceflower" at the moment
- */
- virtual bool add_bonus(const std::string& bonus) = 0;
- /**
- * Give tux more coins
- */
- virtual void add_coins(int count) = 0;
- /**
- * Make tux invicible for a short amount of time
- */
- virtual void make_invincible() = 0;
- /**
- * Deactivate user input for Tux
- */
- virtual void deactivate() = 0;
- /**
- * Give control back to user
- */
- virtual void activate() = 0;
- /**
- * Make Tux walk
- */
- virtual void walk(float speed) = 0;
- /**
- * Set player visible or not visible
- */
- virtual void set_visible(bool visible) = 0;
- /**
- * returns true if the player is currently visible (that is he was not set
- * inivisible by the set_visible method)
- */
- virtual bool get_visible() = 0;
-
- /**
- * Hurts a player, if completely=true then the player will be killed even
- * if he had grow or fireflower bonus
- */
- virtual void kill(bool completely) = 0;
-
- /**
- * Switches ghost mode on/off.
- * Lets Tux float around and through solid objects.
- */
- virtual void set_ghost_mode(bool enable) = 0;
-
- /**
- * Returns whether ghost mode is currently enabled
- */
- virtual bool get_ghost_mode() = 0;
-
- /**
- * play cheer animation.
- * This might need some space and behave in an unpredictable way. Best to use this at level end.
- */
- virtual void do_cheer() = 0;
-
- /**
- * duck down if possible.
- * this won't last long as long as input is enabled.
- */
- virtual void do_duck() = 0;
-
- /**
- * stand back up if possible.
- */
- virtual void do_standup() = 0;
-
- /**
- * do a backflip if possible.
- */
- virtual void do_backflip() = 0;
-
- /**
- * jump in the air if possible
- * sensible values for yspeed are negative - unless we want to jump into the ground of course
- */
- virtual void do_jump(float yspeed) = 0;
-
- /**
- * Orders the current GameSession to start a sequence
- */
- virtual void trigger_sequence(std::string sequence_name) = 0;
-
-};
-
-}
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __SCRIPTED_OBJECT_INTERFACE_H__
-#define __SCRIPTED_OBJECT_INTERFACE_H__
-
-namespace Scripting
-{
-
-class ScriptedObject
-{
-public:
-#ifndef SCRIPTING_API
- virtual ~ScriptedObject()
- {}
-#endif
-
- virtual void set_action(const std::string& animation) = 0;
- virtual std::string get_action() = 0;
-
- virtual void move(float x, float y) = 0;
- virtual void set_pos(float x, float y) = 0;
- virtual float get_pos_x() = 0;
- virtual float get_pos_y() = 0;
-
- virtual void set_velocity(float x, float y) = 0;
- virtual float get_velocity_x() = 0;
- virtual float get_velocity_y() = 0;
-
- virtual void set_visible(bool visible) = 0;
- virtual bool is_visible() = 0;
-
- virtual void set_solid(bool solid) = 0;
- virtual bool is_solid() = 0;
-
- virtual std::string get_name() = 0;
-};
-
-}
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#include <config.h>
-
-#include "serialize.hpp"
-
-#include <memory>
-#include <assert.h>
-#include "lisp/lisp.hpp"
-#include "lisp/list_iterator.hpp"
-#include "lisp/parser.hpp"
-#include "lisp/writer.hpp"
-#include "squirrel_error.hpp"
-
-namespace Scripting
-{
-
-void load_squirrel_table(HSQUIRRELVM vm, SQInteger table_idx, const lisp::Lisp* lisp)
-{
- using namespace lisp;
-
- if(table_idx < 0)
- table_idx -= 2;
-
- lisp::ListIterator iter(lisp);
- while(iter.next() && iter.lisp() != NULL) {
- const std::string& token = iter.item();
- sq_pushstring(vm, token.c_str(), token.size());
-
- const lisp::Lisp* value = iter.value();
- switch(value->get_type()) {
- case Lisp::TYPE_CONS:
- sq_newtable(vm);
- load_squirrel_table(vm, sq_gettop(vm), iter.lisp());
- break;
- case Lisp::TYPE_INTEGER:
- sq_pushinteger(vm, value->get_int());
- break;
- case Lisp::TYPE_REAL:
- sq_pushfloat(vm, value->get_float());
- break;
- case Lisp::TYPE_STRING:
- sq_pushstring(vm, value->get_string().c_str(), -1);
- break;
- case Lisp::TYPE_BOOLEAN:
- sq_pushbool(vm, value->get_bool() ? SQTrue : SQFalse);
- break;
- case Lisp::TYPE_SYMBOL:
- std::cerr << "Unexpected symbol in lisp file...";
- sq_pushnull(vm);
- break;
- default:
- assert(false);
- break;
- }
-
- if(SQ_FAILED(sq_createslot(vm, table_idx)))
- throw Scripting::SquirrelError(vm, "Couldn't create new index");
- }
-}
-
-void save_squirrel_table(HSQUIRRELVM vm, SQInteger table_idx, lisp::Writer& writer)
-{
- // offset because of sq_pushnull
- if(table_idx < 0)
- table_idx -= 1;
-
- //iterator table
- sq_pushnull(vm);
- while(SQ_SUCCEEDED(sq_next(vm, table_idx))) {
- if(sq_gettype(vm, -2) != OT_STRING) {
- std::cerr << "Table contains non-string key\n";
- continue;
- }
- const SQChar* key;
- sq_getstring(vm, -2, &key);
-
- switch(sq_gettype(vm, -1)) {
- case OT_INTEGER: {
- SQInteger val;
- sq_getinteger(vm, -1, &val);
- writer.write_int(key, static_cast<int> (val));
- break;
- }
- case OT_FLOAT: {
- SQFloat val;
- sq_getfloat(vm, -1, &val);
- writer.write_float(key, static_cast<float> (val));
- break;
- }
- case OT_BOOL: {
- SQBool val;
- sq_getbool(vm, -1, &val);
- writer.write_bool(key, val == SQTrue);
- break;
- }
- case OT_STRING: {
- const SQChar* str;
- sq_getstring(vm, -1, &str);
- writer.write_string(key, reinterpret_cast<const char*> (str));
- break;
- }
- case OT_TABLE: {
- writer.start_list(key, true);
- save_squirrel_table(vm, -1, writer);
- writer.end_list(key);
- break;
- }
- case OT_CLOSURE:
- break; // ignore
- case OT_NATIVECLOSURE:
- break;
- default:
- std::cerr << "Can't serialize key '" << key << "' in table.\n";
- break;
- }
- sq_pop(vm, 2);
- }
- sq_pop(vm, 1);
-}
-
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __SERIALIZE_HPP__
-#define __SERIALIZE_HPP__
-
-#include <squirrel.h>
-#include <string>
-#include "lisp/lisp.hpp"
-#include "lisp/writer.hpp"
-
-namespace Scripting
-{
-
- void save_squirrel_table(HSQUIRRELVM vm, SQInteger table_idx, lisp::Writer& writer);
- void load_squirrel_table(HSQUIRRELVM vm, SQInteger table_idx, const lisp::Lisp* lisp);
-
-}
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#include <config.h>
-
-#include "squirrel_error.hpp"
-#include <sstream>
-
-namespace Scripting
-{
-
-SquirrelError::SquirrelError(HSQUIRRELVM v, const std::string& message) throw()
-{
- std::ostringstream msg;
- msg << "Squirrel error: " << message << " (";
- const char* lasterr;
- sq_getlasterror(v);
- if(sq_gettype(v, -1) != OT_STRING)
- {
- lasterr = "no error info";
- }
- else
- {
- sq_getstring(v, -1, &lasterr);
- }
- msg << lasterr << ")";
- sq_pop(v, 1);
- this->message = msg.str();
-}
-
-SquirrelError::~SquirrelError() throw()
-{}
-
-const char*
-SquirrelError::what() const throw()
-{
- return message.c_str();
-}
-
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __SQUIRREL_ERROR_HPP__
-#define __SQUIRREL_ERROR_HPP__
-
-#include <squirrel.h>
-#include <stdexcept>
-
-namespace Scripting
-{
-
-/** Exception class for squirrel errors, it takes a squirrelvm and uses
- * sq_geterror() to retrieve additional information about the last error that
- * occured and creates a readable message from that.
- */
-class SquirrelError : public std::exception
-{
-public:
- SquirrelError(HSQUIRRELVM v, const std::string& message) throw();
- virtual ~SquirrelError() throw();
-
- const char* what() const throw();
-private:
- std::string message;
-};
-
-}
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#include <config.h>
-
-#include <stdexcept>
-#include <sstream>
-#include <stdarg.h>
-#include <squirrel.h>
-#include <sqstdmath.h>
-#include <sqstdblob.h>
-#include <sqstdstring.h>
-#include <sqstdaux.h>
-#include <sqstdio.h>
-#include "squirrel_util.hpp"
-#include "log.hpp"
-#include "level.hpp"
-#include "physfs/physfs_stream.hpp"
-#include "../random_generator.hpp"
-
-#ifdef ENABLE_SQDBG
-#include <sqdbg/sqrdbg.h>
-
-static HSQREMOTEDBG debugger = NULL;
-#endif
-
-namespace Scripting
-{
-
-HSQUIRRELVM global_vm = NULL;
-
-static void printfunc(HSQUIRRELVM, const char* str, ...)
-{
- char buf[4096];
- va_list arglist;
- va_start(arglist, str);
- vsprintf(buf, str, arglist);
- Console::output << (const char*) buf << std::flush;
- va_end(arglist);
-}
-
-void init_squirrel(bool enable_debugger)
-{
- global_vm = sq_open(64);
- if(global_vm == NULL)
- throw std::runtime_error("Couldn't initialize squirrel vm");
-
- if(enable_debugger) {
-#ifdef ENABLE_SQDBG
- sq_enabledebuginfo(global_vm, SQTrue);
- debugger = sq_rdbg_init(global_vm, 1234, SQFalse);
- if(debugger == NULL)
- throw SquirrelError(global_vm, "Couldn't initialize squirrel debugger");
-
- sq_enabledebuginfo(global_vm, SQTrue);
- log_info << "Waiting for debug client..." << std::endl;
- if(SQ_FAILED(sq_rdbg_waitforconnections(debugger)))
- throw SquirrelError(global_vm, "Waiting for debug clients failed");
- log_info << "debug client connected." << std::endl;
-#endif
- }
-
- sq_pushroottable(global_vm);
- if(SQ_FAILED(sqstd_register_bloblib(global_vm)))
- throw SquirrelError(global_vm, "Couldn't register blob lib");
- if(SQ_FAILED(sqstd_register_mathlib(global_vm)))
- throw SquirrelError(global_vm, "Couldn't register math lib");
- if(SQ_FAILED(sqstd_register_stringlib(global_vm)))
- throw SquirrelError(global_vm, "Couldn't register string lib");
-
- // remove rand and srand calls from sqstdmath, we'll provide our own
- sq_pushstring(global_vm, "srand", -1);
- sq_deleteslot(global_vm, -2, SQFalse);
- sq_pushstring(global_vm, "rand", -1);
- sq_deleteslot(global_vm, -2, SQFalse);
-
- // register supertux API
- register_supertux_wrapper(global_vm);
-
- // TODO remove this at some point... it shoud just be functions not an object
- expose_object(global_vm, -1, new Scripting::Level(), "Level", true);
-
- sq_pop(global_vm, 1);
-
- // register print function
- sq_setprintfunc(global_vm, printfunc);
- // register default error handlers
- sqstd_seterrorhandlers(global_vm);
-
- // try to load default script
- try {
- std::string filename = "scripts/default.nut";
- IFileStream stream(filename);
- Scripting::compile_and_run(global_vm, stream, filename);
- } catch(std::exception& e) {
- log_warning << "Couldn't load default.nut: " << e.what() << std::endl;
- }
-}
-
-void exit_squirrel()
-{
-#ifdef ENABLE_SQDBG
- if(debugger != NULL) {
- sq_rdbg_shutdown(debugger);
- debugger = NULL;
- }
-#endif
-
- if (global_vm)
- sq_close(global_vm);
-
- global_vm = NULL;
-}
-
-void update_debugger()
-{
-#ifdef ENABLE_SQDBG
- if(debugger != NULL)
- sq_rdbg_update(debugger);
-#endif
-}
-
-std::string squirrel2string(HSQUIRRELVM v, SQInteger i)
-{
- std::ostringstream os;
- switch(sq_gettype(v, i))
- {
- case OT_NULL:
- os << "<null>";
- break;
- case OT_BOOL: {
- SQBool p;
- sq_getbool(v, i, &p);
- if (p)
- os << "true";
- else
- os << "false";
- break;
- }
- case OT_INTEGER: {
- SQInteger val;
- sq_getinteger(v, i, &val);
- os << val;
- break;
- }
- case OT_FLOAT: {
- SQFloat val;
- sq_getfloat(v, i, &val);
- os << val;
- break;
- }
- case OT_STRING: {
- const SQChar* val;
- sq_getstring(v, i, &val);
- os << "\"" << val << "\"";
- break;
- }
- case OT_TABLE: {
- bool first = true;
- os << "{";
- sq_pushnull(v); //null iterator
- while(SQ_SUCCEEDED(sq_next(v,i-1)))
- {
- if (!first) {
- os << ", ";
- }
- first = false;
-
- //here -1 is the value and -2 is the key
- os << squirrel2string(v, -2) << " => "
- << squirrel2string(v, -1);
-
- sq_pop(v,2); //pops key and val before the nex iteration
- }
- sq_pop(v, 1);
- os << "}";
- break;
- }
- case OT_ARRAY: {
- bool first = true;
- os << "[";
- sq_pushnull(v); //null iterator
- while(SQ_SUCCEEDED(sq_next(v,i-1)))
- {
- if (!first) {
- os << ", ";
- }
- first = false;
-
- //here -1 is the value and -2 is the key
- // we ignore the key, since that is just the index in an array
- os << squirrel2string(v, -1);
-
- sq_pop(v,2); //pops key and val before the nex iteration
- }
- sq_pop(v, 1);
- os << "]";
- break;
- }
- case OT_USERDATA:
- os << "<userdata>";
- break;
- case OT_CLOSURE:
- os << "<closure>";
- break;
- case OT_NATIVECLOSURE:
- os << "<native closure>";
- break;
- case OT_GENERATOR:
- os << "<generator>";
- break;
- case OT_USERPOINTER:
- os << "userpointer";
- break;
- case OT_THREAD:
- os << "<thread>";
- break;
- case OT_CLASS:
- os << "<class>";
- break;
- case OT_INSTANCE:
- os << "<instance>";
- break;
- case OT_WEAKREF:
- os << "<weakref>";
- break;
- default:
- os << "<unknown>";
- break;
- }
- return os.str();
-}
-
-void print_squirrel_stack(HSQUIRRELVM v)
-{
- printf("--------------------------------------------------------------\n");
- int count = sq_gettop(v);
- for(int i = 1; i <= count; ++i) {
- printf("%d: ",i);
- switch(sq_gettype(v, i))
- {
- case OT_NULL:
- printf("null");
- break;
- case OT_INTEGER: {
- SQInteger val;
- sq_getinteger(v, i, &val);
- printf("integer (%d)", static_cast<int> (val));
- break;
- }
- case OT_FLOAT: {
- SQFloat val;
- sq_getfloat(v, i, &val);
- printf("float (%f)", val);
- break;
- }
- case OT_STRING: {
- const SQChar* val;
- sq_getstring(v, i, &val);
- printf("string (%s)", val);
- break;
- }
- case OT_TABLE:
- printf("table");
- break;
- case OT_ARRAY:
- printf("array");
- break;
- case OT_USERDATA:
- printf("userdata");
- break;
- case OT_CLOSURE:
- printf("closure(function)");
- break;
- case OT_NATIVECLOSURE:
- printf("native closure(C function)");
- break;
- case OT_GENERATOR:
- printf("generator");
- break;
- case OT_USERPOINTER:
- printf("userpointer");
- break;
- case OT_THREAD:
- printf("thread");
- break;
- case OT_CLASS:
- printf("class");
- break;
- case OT_INSTANCE:
- printf("instance");
- break;
- case OT_WEAKREF:
- printf("weakref");
- break;
- default:
- printf("unknown?!?");
- break;
- }
- printf("\n");
- }
- printf("--------------------------------------------------------------\n");
-}
-
-static SQInteger squirrel_read_char(SQUserPointer file)
-{
- std::istream* in = reinterpret_cast<std::istream*> (file);
- char c = in->get();
- if(in->eof())
- return 0;
- return c;
-}
-
-void compile_script(HSQUIRRELVM vm, std::istream& in, const std::string& sourcename)
-{
- if(SQ_FAILED(sq_compile(vm, squirrel_read_char, &in, sourcename.c_str(), true)))
- throw SquirrelError(vm, "Couldn't parse script");
-}
-
-void compile_and_run(HSQUIRRELVM vm, std::istream& in,
- const std::string& sourcename)
-{
- compile_script(vm, in, sourcename);
-
- SQInteger oldtop = sq_gettop(vm);
-
- try {
- sq_pushroottable(vm);
- if(SQ_FAILED(sq_call(vm, 1, SQFalse, SQTrue)))
- throw SquirrelError(vm, "Couldn't start script");
- } catch(...) {
- sq_settop(vm, oldtop);
- throw;
- }
-
- // we can remove the closure in case the script was not suspended
- if(sq_getvmstate(vm) != SQ_VMSTATE_SUSPENDED) {
- sq_settop(vm, oldtop-1);
- }
-}
-
-HSQOBJECT create_thread(HSQUIRRELVM vm)
-{
- HSQUIRRELVM new_vm = sq_newthread(vm, 64);
- if(new_vm == NULL)
- throw SquirrelError(vm, "Couldn't create new VM");
-
- HSQOBJECT vm_object;
- sq_resetobject(&vm_object);
- if(SQ_FAILED(sq_getstackobj(vm, -1, &vm_object)))
- throw SquirrelError(vm, "Couldn't get squirrel thread from stack");
- sq_addref(vm, &vm_object);
-
- sq_pop(vm, 1);
-
- return vm_object;
-}
-
-HSQOBJECT vm_to_object(HSQUIRRELVM vm)
-{
- HSQOBJECT object;
- sq_resetobject(&object);
- object._unVal.pThread = vm;
- object._type = OT_THREAD;
-
- return object;
-}
-
-HSQUIRRELVM object_to_vm(HSQOBJECT object)
-{
- if(object._type != OT_THREAD)
- return NULL;
-
- return object._unVal.pThread;
-}
-
-// begin: serialization functions
-
-void store_float(HSQUIRRELVM vm, const char* name, float val)
-{
- sq_pushstring(vm, name, -1);
- sq_pushfloat(vm, val);
- if(SQ_FAILED(sq_createslot(vm, -3)))
- throw Scripting::SquirrelError(vm, "Couldn't add float value to table");
-}
-
-void store_int(HSQUIRRELVM vm, const char* name, int val)
-{
- sq_pushstring(vm, name, -1);
- sq_pushinteger(vm, val);
- if(SQ_FAILED(sq_createslot(vm, -3)))
- throw Scripting::SquirrelError(vm, "Couldn't add int value to table");
-}
-
-void store_string(HSQUIRRELVM vm, const char* name, const std::string& val)
-{
- sq_pushstring(vm, name, -1);
- sq_pushstring(vm, val.c_str(), val.length());
- if(SQ_FAILED(sq_createslot(vm, -3)))
- throw Scripting::SquirrelError(vm, "Couldn't add float value to table");
-}
-
-void store_bool(HSQUIRRELVM vm, const char* name, bool val)
-{
- sq_pushstring(vm, name, -1);
- sq_pushbool(vm, val ? SQTrue : SQFalse);
- if(SQ_FAILED(sq_createslot(vm, -3)))
- throw Scripting::SquirrelError(vm, "Couldn't add float value to table");
-}
-
-bool has_float(HSQUIRRELVM vm, const char* name)
-{
- sq_pushstring(vm, name, -1);
- if (SQ_FAILED(sq_get(vm, -2))) return false;
- sq_pop(vm, 1);
- return true;
-}
-
-bool has_int(HSQUIRRELVM vm, const char* name)
-{
- return has_float(vm, name);
-}
-
-bool has_string(HSQUIRRELVM vm, const char* name)
-{
- return has_float(vm, name);
-}
-
-bool has_bool(HSQUIRRELVM vm, const char* name)
-{
- return has_float(vm, name);
-}
-
-float read_float(HSQUIRRELVM vm, const char* name)
-{
- sq_pushstring(vm, name, -1);
- if(SQ_FAILED(sq_get(vm, -2))) {
- std::ostringstream msg;
- msg << "Couldn't get float value for '" << name << "' from table";
- throw Scripting::SquirrelError(vm, msg.str());
- }
-
- float result;
- if(SQ_FAILED(sq_getfloat(vm, -1, &result))) {
- std::ostringstream msg;
- msg << "Couldn't get float value for '" << name << "' from table";
- throw Scripting::SquirrelError(vm, msg.str());
- }
- sq_pop(vm, 1);
-
- return result;
-}
-
-int read_int(HSQUIRRELVM vm, const char* name)
-{
- sq_pushstring(vm, name, -1);
- if(SQ_FAILED(sq_get(vm, -2))) {
- std::ostringstream msg;
- msg << "Couldn't get int value for '" << name << "' from table";
- throw Scripting::SquirrelError(vm, msg.str());
- }
-
- SQInteger result;
- if(SQ_FAILED(sq_getinteger(vm, -1, &result))) {
- std::ostringstream msg;
- msg << "Couldn't get int value for '" << name << "' from table";
- throw Scripting::SquirrelError(vm, msg.str());
- }
- sq_pop(vm, 1);
-
- return result;
-}
-
-
-std::string read_string(HSQUIRRELVM vm, const char* name)
-{
- sq_pushstring(vm, name, -1);
- if(SQ_FAILED(sq_get(vm, -2))) {
- std::ostringstream msg;
- msg << "Couldn't get string value for '" << name << "' from table";
- throw Scripting::SquirrelError(vm, msg.str());
- }
-
- const char* result;
- if(SQ_FAILED(sq_getstring(vm, -1, &result))) {
- std::ostringstream msg;
- msg << "Couldn't get string value for '" << name << "' from table";
- throw Scripting::SquirrelError(vm, msg.str());
- }
- sq_pop(vm, 1);
-
- return std::string(result);
-}
-
-bool read_bool(HSQUIRRELVM vm, const char* name)
-{
- sq_pushstring(vm, name, -1);
- if(SQ_FAILED(sq_get(vm, -2))) {
- std::ostringstream msg;
- msg << "Couldn't get bool value for '" << name << "' from table";
- throw Scripting::SquirrelError(vm, msg.str());
- }
-
- SQBool result;
- if(SQ_FAILED(sq_getbool(vm, -1, &result))) {
- std::ostringstream msg;
- msg << "Couldn't get bool value for '" << name << "' from table";
- throw Scripting::SquirrelError(vm, msg.str());
- }
- sq_pop(vm, 1);
-
- return result == SQTrue;
-}
-
-bool get_float(HSQUIRRELVM vm, const char* name, float& val) {
- if (!has_float(vm, name)) return false;
- val = read_float(vm, name);
- return true;
-}
-
-bool get_int(HSQUIRRELVM vm, const char* name, int& val) {
- if (!has_int(vm, name)) return false;
- val = read_int(vm, name);
- return true;
-}
-
-bool get_string(HSQUIRRELVM vm, const char* name, std::string& val) {
- if (!has_string(vm, name)) return false;
- val = read_string(vm, name);
- return true;
-}
-
-bool get_bool(HSQUIRRELVM vm, const char* name, bool& val) {
- if (!has_bool(vm, name)) return false;
- val = read_bool(vm, name);
- return true;
-}
-
-// end: serialization functions
-
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#ifndef __SQUIRREL_UTIL_HPP__
-#define __SQUIRREL_UTIL_HPP__
-
-#include <squirrel.h>
-#include <sstream>
-#include <stdexcept>
-#include <string>
-#include "wrapper.hpp"
-#include "squirrel_error.hpp"
-
-namespace Scripting
-{
-
- extern HSQUIRRELVM global_vm;
-
- void init_squirrel(bool enable_debugger);
- void exit_squirrel();
- void update_debugger();
-
- std::string squirrel2string(HSQUIRRELVM vm, SQInteger i);
- void print_squirrel_stack(HSQUIRRELVM vm);
-
- HSQOBJECT create_thread(HSQUIRRELVM vm);
- SQObject vm_to_object(HSQUIRRELVM vm);
- HSQUIRRELVM object_to_vm(HSQOBJECT object);
-
- void compile_script(HSQUIRRELVM vm, std::istream& in,
- const std::string& sourcename);
- void compile_and_run(HSQUIRRELVM vm, std::istream& in,
- const std::string& sourcename);
-
- template<typename T>
- void expose_object(HSQUIRRELVM v, SQInteger table_idx, T* object,
- const std::string& name, bool free = false)
- {
- sq_pushstring(v, name.c_str(), -1);
- Scripting::create_squirrel_instance(v, object, free);
-
- if(table_idx < 0)
- table_idx -= 2;
-
- // register instance in root table
- if(SQ_FAILED(sq_createslot(v, table_idx))) {
- std::ostringstream msg;
- msg << "Couldn't register object '" << name << "' in squirrel table";
- throw Scripting::SquirrelError(v, msg.str());
- }
- }
-
- static inline void unexpose_object(HSQUIRRELVM v, SQInteger table_idx,
- const std::string& name)
- {
- sq_pushstring(v, name.c_str(), name.length());
-
- if(table_idx < 0)
- table_idx -= 1;
-
- if(SQ_FAILED(sq_deleteslot(v, table_idx, SQFalse))) {
- std::ostringstream msg;
- msg << "Couldn't unregister object '" << name << "' in squirrel root table";
- throw Scripting::SquirrelError(v, msg.str());
- }
- }
-
- // begin serialization functions
- void store_float(HSQUIRRELVM vm, const char* name, float val);
- void store_int(HSQUIRRELVM vm, const char* name, int val);
- void store_string(HSQUIRRELVM vm, const char* name, const std::string& val);
- void store_bool(HSQUIRRELVM vm, const char* name, bool val);
-
- bool has_float(HSQUIRRELVM vm, const char* name);
- bool has_int(HSQUIRRELVM vm, const char* name);
- bool has_string(HSQUIRRELVM vm, const char* name);
- bool has_bool(HSQUIRRELVM vm, const char* name);
-
- bool get_float(HSQUIRRELVM vm, const char* name, float& val);
- bool get_int(HSQUIRRELVM vm, const char* name, int& val);
- bool get_string(HSQUIRRELVM vm, const char* name, std::string& val);
- bool get_bool(HSQUIRRELVM vm, const char* name, bool& val);
-
- float read_float(HSQUIRRELVM vm, const char* name);
- int read_int(HSQUIRRELVM vm, const char* name);
- std::string read_string(HSQUIRRELVM vm, const char* name);
- bool read_bool(HSQUIRRELVM vm, const char* name);
- // end serialization functions
-
-}
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux - Sector Scripting
-// Copyright (C) 2006 Wolfgang Becker <uafr@gmx.de>
-//
-// 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.
-
-#ifndef __SECTOR_H__
-#define __SECTOR_H__
-
-namespace Scripting
-{
-
-class SSector
-{
-public:
-#ifndef SCRIPTING_API
- virtual ~SSector()
- {}
-#endif
- virtual void set_ambient_light(float red, float green, float blue) = 0;
- virtual float get_ambient_red() = 0;
- virtual float get_ambient_green() = 0;
- virtual float get_ambient_blue() = 0;
-};
-
-}
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __TEXT_H__
-#define __TEXT_H__
-
-namespace Scripting
-{
-
-class Text
-{
-public:
-#ifndef SCRIPTING_API
- virtual ~Text()
- { }
-#endif
-
- virtual void set_text(const std::string& text) = 0;
- virtual void set_font(const std::string& fontname) = 0;
- virtual void fade_in(float fadetime) = 0;
- virtual void fade_out(float fadetime) = 0;
- virtual void set_visible(bool visible) = 0;
- virtual void set_centered(bool centered) = 0;
- virtual void set_pos(float x, float y) = 0;
- virtual float get_pos_x() = 0;
- virtual float get_pos_y() = 0;
- virtual void set_anchor_point(int anchor) = 0;
- virtual int get_anchor_point() = 0;
-};
-
-}
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#include <config.h>
-
-#include "thread_queue.hpp"
-#include "squirrel_util.hpp"
-#include "log.hpp"
-
-namespace Scripting
-{
-
-ThreadQueue::ThreadQueue()
-{
-}
-
-ThreadQueue::~ThreadQueue()
-{
-}
-
-void
-ThreadQueue::add(HSQUIRRELVM vm)
-{
- // create a weakref to the VM
- HSQOBJECT vm_obj = vm_to_object(vm);
- sq_pushobject(global_vm, vm_obj);
- sq_weakref(global_vm, -1);
-
- HSQOBJECT object;
- if(SQ_FAILED(sq_getstackobj(global_vm, -1, &object))) {
- sq_pop(global_vm, 2);
- throw SquirrelError(global_vm, "Couldn't get thread weakref from vm");
- }
- sq_addref(global_vm, &object);
- threads.push_back(object);
-
- sq_pop(global_vm, 2);
-}
-
-void
-ThreadQueue::wakeup()
-{
- // we traverse the list in reverse orders and use indices. This should be
- // robust for scripts that add new entries to the list while we're traversing
- // it
- size_t i = threads.size() - 1;
- size_t end = (size_t) 0 - 1;
- size_t size_begin = threads.size();
- while(i != end) {
- HSQOBJECT object = threads[i];
-
- sq_pushobject(global_vm, object);
- sq_getweakrefval(global_vm, -1);
-
- HSQUIRRELVM scheduled_vm;
- if(sq_gettype(global_vm, -1) == OT_THREAD &&
- SQ_SUCCEEDED(sq_getthread(global_vm, -1, &scheduled_vm))) {
- if(SQ_FAILED(sq_wakeupvm(scheduled_vm, SQFalse, SQFalse, SQTrue))) {
- log_warning << "Couldn't wakeup scheduled squirrel VM" << std::endl;
- }
- }
-
- sq_release(global_vm, &object);
- sq_pop(global_vm, 1);
- i--;
- }
-
- threads.erase(threads.begin(), threads.begin() + size_begin);
-}
-
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#ifndef __THREAD_QUEUE_HPP__
-#define __THREAD_QUEUE_HPP__
-
-#include <vector>
-#include <squirrel.h>
-
-namespace Scripting
-{
-
-/**
- * Keeps a list of SquirrelThreads that wait for a wakeup event
- */
-class ThreadQueue
-{
-public:
- ThreadQueue();
- virtual ~ThreadQueue();
-
- /// adds a thread (actually a weakref to the thread)
- void add(HSQUIRRELVM vm);
- /// wakes up threads in the list
- void wakeup();
-
-private:
- typedef std::vector<HSQOBJECT> ThreadList;
- ThreadList threads;
-};
-
-}
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include <string>
-#include <stdio.h>
-#include "object/thunderstorm.hpp"
-#include "scripting/thunderstorm.hpp"
-#include "math/vector.hpp"
-
-#define NOIMPL log_fatal << __PRETTY_FUNCTION__ << " not implemented."
-
-namespace Scripting
-{
-
- Thunderstorm::Thunderstorm(::Thunderstorm* thunderstorm)
- : thunderstorm(thunderstorm)
- {
- }
-
- Thunderstorm::~Thunderstorm()
- {
- }
-
- void Thunderstorm::start()
- {
- thunderstorm->start();
- }
-
- void Thunderstorm::stop()
- {
- thunderstorm->stop();
- }
-
- void Thunderstorm::thunder()
- {
- thunderstorm->thunder();
- }
-
- void Thunderstorm::lightning()
- {
- thunderstorm->lightning();
- }
-
- void Thunderstorm::flash()
- {
- thunderstorm->flash();
- }
-
- void Thunderstorm::electrify()
- {
- thunderstorm->electrify();
- }
-
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __SCRIPTING_THUNDERSTORM_H__
-#define __SCRIPTING_THUNDERSTORM_H__
-
-#ifndef SCRIPTING_API
-class Thunderstorm;
-typedef Thunderstorm _Thunderstorm;
-#endif
-
-namespace Scripting
-{
-
-class Thunderstorm
-{
-public:
-#ifndef SCRIPTING_API
- Thunderstorm(_Thunderstorm* thunderstorm);
- ~Thunderstorm();
-#endif
-
- /**
- * Start playing thunder and lightning at configured interval
- */
- void start();
-
- /**
- * Stop playing thunder and lightning at configured interval
- */
- void stop();
-
- /**
- * Play thunder
- */
- void thunder();
-
- /**
- * Play lightning, i.e. call flash() and electrify()
- */
- void lightning();
-
- /**
- * Display a nice flash
- */
- void flash();
-
- /**
- * Electrify water throughout the whole sector for a short time
- */
- void electrify();
-
-#ifndef SCRIPTING_API
- _Thunderstorm* thunderstorm;
-#endif
-};
-
-}
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include <string>
-#include <stdio.h>
-#include "object/tilemap.hpp"
-#include "scripting/tilemap.hpp"
-#include "math/vector.hpp"
-
-#define NOIMPL log_fatal << __PRETTY_FUNCTION__ << " not implemented."
-
-namespace Scripting
-{
-
- TileMap::TileMap(::TileMap* tilemap)
- : tilemap(tilemap)
- { }
-
- TileMap::~TileMap()
- { }
-
- void TileMap::goto_node(int node_no)
- {
- tilemap->goto_node(node_no);
- }
-
- void TileMap::start_moving()
- {
- tilemap->start_moving();
- }
-
- void TileMap::stop_moving()
- {
- tilemap->stop_moving();
- }
-
- void TileMap::fade(float alpha, float seconds)
- {
- tilemap->fade(alpha, seconds);
- }
-
- void TileMap::set_alpha(float alpha)
- {
- tilemap->set_alpha(alpha);
- }
-
- float TileMap::get_alpha()
- {
- return tilemap->get_alpha();
- }
-
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __SCRIPTING_TILEMAP_H__
-#define __SCRIPTING_TILEMAP_H__
-
-#ifndef SCRIPTING_API
-class TileMap;
-typedef TileMap _TileMap;
-#endif
-
-namespace Scripting
-{
-
-class TileMap
-{
-public:
-#ifndef SCRIPTING_API
- TileMap(_TileMap* tilemap);
- ~TileMap();
-#endif
-
- /** Move tilemap until at given node, then stop */
- void goto_node(int node_no);
-
- /** Start moving tilemap */
- void start_moving();
-
- /** Stop tilemap at next node */
- void stop_moving();
-
- /**
- * Start fading the tilemap to opacity given by @c alpha.
- * Destination opacity will be reached after @c seconds seconds. Also influences solidity.
- */
- void fade(float alpha, float seconds);
-
- /**
- * Instantly switch tilemap's opacity to @c alpha. Also influences solidity.
- */
- void set_alpha(float alpha);
-
- /**
- * Return tilemap's opacity. Note that while the tilemap is fading in or out, this will return the current alpha value, not the target alpha.
- */
- float get_alpha();
-
-#ifndef SCRIPTING_API
- _TileMap* tilemap;
-#endif
-};
-
-}
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#include <config.h>
-
-#include <algorithm>
-
-#include "time_scheduler.hpp"
-#include "squirrel_util.hpp"
-#include "squirrel_error.hpp"
-#include "log.hpp"
-
-namespace Scripting
-{
-
-TimeScheduler* TimeScheduler::instance = NULL;
-
-TimeScheduler::TimeScheduler()
-{
-}
-
-TimeScheduler::~TimeScheduler()
-{
-}
-
-void
-TimeScheduler::update(float time)
-{
- while(!schedule.empty() && schedule.front().wakeup_time < time) {
- HSQOBJECT thread_ref = schedule.front().thread_ref;
-
- sq_pushobject(global_vm, thread_ref);
- sq_getweakrefval(global_vm, -1);
-
- HSQUIRRELVM scheduled_vm;
- if(sq_gettype(global_vm, -1) == OT_THREAD &&
- SQ_SUCCEEDED(sq_getthread(global_vm, -1, &scheduled_vm))) {
- if(SQ_FAILED(sq_wakeupvm(scheduled_vm, SQFalse, SQFalse, SQTrue))) {
- std::ostringstream msg;
- msg << "Couldn't wakeup scheduled squirrel VM: ";
- sq_getlasterror(scheduled_vm);
- if(sq_gettype(scheduled_vm, -1) != OT_STRING) {
- msg << "(no info)";
- } else {
- const char* lasterr;
- sq_getstring(scheduled_vm, -1, &lasterr);
- msg << lasterr;
- }
- log_warning << msg.str() << std::endl;
- sq_pop(scheduled_vm, 1);
- }
- }
-
- sq_release(global_vm, &thread_ref);
- sq_pop(global_vm, 2);
-
- std::pop_heap(schedule.begin(), schedule.end());
- schedule.pop_back();
- }
-}
-
-void
-TimeScheduler::schedule_thread(HSQUIRRELVM scheduled_vm, float time)
-{
- // create a weakref to the VM
- SQObject vm_obj = vm_to_object(scheduled_vm);
- sq_pushobject(global_vm, vm_obj);
- sq_weakref(global_vm, -1);
-
- ScheduleEntry entry;
- if(SQ_FAILED(sq_getstackobj(global_vm, -1, & entry.thread_ref))) {
- sq_pop(global_vm, 2);
- throw SquirrelError(global_vm, "Couldn't get thread weakref from vm");
- }
- entry.wakeup_time = time;
-
- sq_addref(global_vm, & entry.thread_ref);
- sq_pop(global_vm, 2);
-
- schedule.push_back(entry);
- std::push_heap(schedule.begin(), schedule.end());
-}
-
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#ifndef __TIME_SCHEDULER_HPP__
-#define __TIME_SCHEDULER_HPP__
-
-#include <vector>
-#include <squirrel.h>
-
-namespace Scripting
-{
-
-/**
- * This class keeps a list of squirrel threads that are scheduled for a certain
- * time. (the typical result of a wait() command in a squirrel script)
- */
-class TimeScheduler
-{
-public:
- TimeScheduler();
- virtual ~TimeScheduler();
-
- void update(float time);
- void schedule_thread(HSQUIRRELVM vm, float time);
-
- static TimeScheduler* instance;
-
-private:
- struct ScheduleEntry {
- /// weak reference to the squirrel vm object
- HSQOBJECT thread_ref;
- /// time when the thread should be woken up
- float wakeup_time;
-
- bool operator<(const ScheduleEntry& other) const
- {
- // we need the smallest value on top
- return wakeup_time > other.wakeup_time;
- }
- };
-
- typedef std::vector<ScheduleEntry> ScheduleHeap;
- ScheduleHeap schedule;
-};
-
-}
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2007 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __SCRIPTING_WILLOWISP_H__
-#define __SCRIPTING_WILLOWISP_H__
-
-namespace Scripting
-{
-
-class WillOWisp
-{
-public:
-#ifndef SCRIPTING_API
- virtual ~WillOWisp()
- {}
-#endif
-
- /** Move willowisp to given node */
- virtual void goto_node(int node_no) = 0;
-
- /** set willowisp state can be:
- * -stopped willowisp doesn't move
- * -move_path willowisp moves along the path (call goto_node)
- * -move_path_track willowisp moves along path but catchs tux when he is near
- * -normal "normal" mode starts tracking tux when he is near enough
- * -vanish vanish
- */
- virtual void set_state(const std::string& state) = 0;
-
- virtual void start_moving() = 0;
- virtual void stop_moving() = 0;
-};
-
-}
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include <string>
-#include <stdio.h>
-#include "object/wind.hpp"
-#include "scripting/wind.hpp"
-#include "math/vector.hpp"
-
-#define NOIMPL log_fatal << __PRETTY_FUNCTION__ << " not implemented."
-
-namespace Scripting
-{
-
- Wind::Wind(::Wind* wind)
- : wind(wind)
- { }
-
- Wind::~Wind()
- { }
-
- void Wind::start()
- {
- wind->start();
- }
-
- void Wind::stop()
- {
- wind->stop();
- }
-
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __SCRIPTING_WIND_H__
-#define __SCRIPTING_WIND_H__
-
-#ifndef SCRIPTING_API
-class Wind;
-typedef Wind _Wind;
-#endif
-
-namespace Scripting
-{
-
-class Wind
-{
-public:
-#ifndef SCRIPTING_API
- Wind(_Wind* wind);
- ~Wind();
-#endif
-
- /** Start wind */
- void start();
-
- /** Stop wind */
- void stop();
-
-#ifndef SCRIPTING_API
- _Wind* wind;
-#endif
-};
-
-}
-
-#endif
+++ /dev/null
-/**
- * WARNING: This file is automatically generated from:
- * 'src/scripting/wrapper.interface.hpp'
- * DO NOT CHANGE
- */
-#include <config.h>
-
-#include <new>
-#include <assert.h>
-#include <string>
-#include <sstream>
-#include <squirrel.h>
-#include "squirrel_error.hpp"
-#include "wrapper.interface.hpp"
-
-namespace Scripting
-{
-namespace Wrapper
-{
-
-static SQInteger DisplayEffect_release_hook(SQUserPointer ptr, SQInteger )
-{
- Scripting::DisplayEffect* _this = reinterpret_cast<Scripting::DisplayEffect*> (ptr);
- delete _this;
- return 0;
-}
-
-static SQInteger DisplayEffect_fade_out_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'fade_out' called without instance"));
- return SQ_ERROR;
- }
- Scripting::DisplayEffect* _this = reinterpret_cast<Scripting::DisplayEffect*> (data);
- SQFloat arg0;
- if(SQ_FAILED(sq_getfloat(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not a float"));
- return SQ_ERROR;
- }
-
- try {
- _this->fade_out(static_cast<float> (arg0));
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'fade_out'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger DisplayEffect_fade_in_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'fade_in' called without instance"));
- return SQ_ERROR;
- }
- Scripting::DisplayEffect* _this = reinterpret_cast<Scripting::DisplayEffect*> (data);
- SQFloat arg0;
- if(SQ_FAILED(sq_getfloat(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not a float"));
- return SQ_ERROR;
- }
-
- try {
- _this->fade_in(static_cast<float> (arg0));
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'fade_in'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger DisplayEffect_set_black_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'set_black' called without instance"));
- return SQ_ERROR;
- }
- Scripting::DisplayEffect* _this = reinterpret_cast<Scripting::DisplayEffect*> (data);
- SQBool arg0;
- if(SQ_FAILED(sq_getbool(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not a bool"));
- return SQ_ERROR;
- }
-
- try {
- _this->set_black(arg0 == SQTrue);
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'set_black'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger DisplayEffect_is_black_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'is_black' called without instance"));
- return SQ_ERROR;
- }
- Scripting::DisplayEffect* _this = reinterpret_cast<Scripting::DisplayEffect*> (data);
-
- try {
- bool return_value = _this->is_black();
-
- sq_pushbool(vm, return_value);
- return 1;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'is_black'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger DisplayEffect_sixteen_to_nine_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'sixteen_to_nine' called without instance"));
- return SQ_ERROR;
- }
- Scripting::DisplayEffect* _this = reinterpret_cast<Scripting::DisplayEffect*> (data);
- SQFloat arg0;
- if(SQ_FAILED(sq_getfloat(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not a float"));
- return SQ_ERROR;
- }
-
- try {
- _this->sixteen_to_nine(static_cast<float> (arg0));
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'sixteen_to_nine'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger DisplayEffect_four_to_three_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'four_to_three' called without instance"));
- return SQ_ERROR;
- }
- Scripting::DisplayEffect* _this = reinterpret_cast<Scripting::DisplayEffect*> (data);
- SQFloat arg0;
- if(SQ_FAILED(sq_getfloat(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not a float"));
- return SQ_ERROR;
- }
-
- try {
- _this->four_to_three(static_cast<float> (arg0));
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'four_to_three'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger Camera_release_hook(SQUserPointer ptr, SQInteger )
-{
- Scripting::Camera* _this = reinterpret_cast<Scripting::Camera*> (ptr);
- delete _this;
- return 0;
-}
-
-static SQInteger Camera_reload_config_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'reload_config' called without instance"));
- return SQ_ERROR;
- }
- Scripting::Camera* _this = reinterpret_cast<Scripting::Camera*> (data);
-
- try {
- _this->reload_config();
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'reload_config'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger Camera_shake_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'shake' called without instance"));
- return SQ_ERROR;
- }
- Scripting::Camera* _this = reinterpret_cast<Scripting::Camera*> (data);
- SQFloat arg0;
- if(SQ_FAILED(sq_getfloat(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not a float"));
- return SQ_ERROR;
- }
- SQFloat arg1;
- if(SQ_FAILED(sq_getfloat(vm, 3, &arg1))) {
- sq_throwerror(vm, _SC("Argument 2 not a float"));
- return SQ_ERROR;
- }
- SQFloat arg2;
- if(SQ_FAILED(sq_getfloat(vm, 4, &arg2))) {
- sq_throwerror(vm, _SC("Argument 3 not a float"));
- return SQ_ERROR;
- }
-
- try {
- _this->shake(static_cast<float> (arg0), static_cast<float> (arg1), static_cast<float> (arg2));
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'shake'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger Camera_set_pos_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'set_pos' called without instance"));
- return SQ_ERROR;
- }
- Scripting::Camera* _this = reinterpret_cast<Scripting::Camera*> (data);
- SQFloat arg0;
- if(SQ_FAILED(sq_getfloat(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not a float"));
- return SQ_ERROR;
- }
- SQFloat arg1;
- if(SQ_FAILED(sq_getfloat(vm, 3, &arg1))) {
- sq_throwerror(vm, _SC("Argument 2 not a float"));
- return SQ_ERROR;
- }
-
- try {
- _this->set_pos(static_cast<float> (arg0), static_cast<float> (arg1));
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'set_pos'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger Camera_set_mode_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'set_mode' called without instance"));
- return SQ_ERROR;
- }
- Scripting::Camera* _this = reinterpret_cast<Scripting::Camera*> (data);
- const SQChar* arg0;
- if(SQ_FAILED(sq_getstring(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not a string"));
- return SQ_ERROR;
- }
-
- try {
- _this->set_mode(arg0);
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'set_mode'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger Camera_scroll_to_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'scroll_to' called without instance"));
- return SQ_ERROR;
- }
- Scripting::Camera* _this = reinterpret_cast<Scripting::Camera*> (data);
- SQFloat arg0;
- if(SQ_FAILED(sq_getfloat(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not a float"));
- return SQ_ERROR;
- }
- SQFloat arg1;
- if(SQ_FAILED(sq_getfloat(vm, 3, &arg1))) {
- sq_throwerror(vm, _SC("Argument 2 not a float"));
- return SQ_ERROR;
- }
- SQFloat arg2;
- if(SQ_FAILED(sq_getfloat(vm, 4, &arg2))) {
- sq_throwerror(vm, _SC("Argument 3 not a float"));
- return SQ_ERROR;
- }
-
- try {
- _this->scroll_to(static_cast<float> (arg0), static_cast<float> (arg1), static_cast<float> (arg2));
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'scroll_to'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger Level_release_hook(SQUserPointer ptr, SQInteger )
-{
- Scripting::Level* _this = reinterpret_cast<Scripting::Level*> (ptr);
- delete _this;
- return 0;
-}
-
-static SQInteger Level_finish_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'finish' called without instance"));
- return SQ_ERROR;
- }
- Scripting::Level* _this = reinterpret_cast<Scripting::Level*> (data);
- SQBool arg0;
- if(SQ_FAILED(sq_getbool(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not a bool"));
- return SQ_ERROR;
- }
-
- try {
- _this->finish(arg0 == SQTrue);
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'finish'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger Level_spawn_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'spawn' called without instance"));
- return SQ_ERROR;
- }
- Scripting::Level* _this = reinterpret_cast<Scripting::Level*> (data);
- const SQChar* arg0;
- if(SQ_FAILED(sq_getstring(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not a string"));
- return SQ_ERROR;
- }
- const SQChar* arg1;
- if(SQ_FAILED(sq_getstring(vm, 3, &arg1))) {
- sq_throwerror(vm, _SC("Argument 2 not a string"));
- return SQ_ERROR;
- }
-
- try {
- _this->spawn(arg0, arg1);
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'spawn'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger Level_flip_vertically_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'flip_vertically' called without instance"));
- return SQ_ERROR;
- }
- Scripting::Level* _this = reinterpret_cast<Scripting::Level*> (data);
-
- try {
- _this->flip_vertically();
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'flip_vertically'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger Level_toggle_pause_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'toggle_pause' called without instance"));
- return SQ_ERROR;
- }
- Scripting::Level* _this = reinterpret_cast<Scripting::Level*> (data);
-
- try {
- _this->toggle_pause();
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'toggle_pause'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger ScriptedObject_release_hook(SQUserPointer ptr, SQInteger )
-{
- Scripting::ScriptedObject* _this = reinterpret_cast<Scripting::ScriptedObject*> (ptr);
- delete _this;
- return 0;
-}
-
-static SQInteger ScriptedObject_set_action_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'set_action' called without instance"));
- return SQ_ERROR;
- }
- Scripting::ScriptedObject* _this = reinterpret_cast<Scripting::ScriptedObject*> (data);
- const SQChar* arg0;
- if(SQ_FAILED(sq_getstring(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not a string"));
- return SQ_ERROR;
- }
-
- try {
- _this->set_action(arg0);
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'set_action'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger ScriptedObject_get_action_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'get_action' called without instance"));
- return SQ_ERROR;
- }
- Scripting::ScriptedObject* _this = reinterpret_cast<Scripting::ScriptedObject*> (data);
-
- try {
- std::string return_value = _this->get_action();
-
- sq_pushstring(vm, return_value.c_str(), return_value.size());
- return 1;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'get_action'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger ScriptedObject_move_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'move' called without instance"));
- return SQ_ERROR;
- }
- Scripting::ScriptedObject* _this = reinterpret_cast<Scripting::ScriptedObject*> (data);
- SQFloat arg0;
- if(SQ_FAILED(sq_getfloat(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not a float"));
- return SQ_ERROR;
- }
- SQFloat arg1;
- if(SQ_FAILED(sq_getfloat(vm, 3, &arg1))) {
- sq_throwerror(vm, _SC("Argument 2 not a float"));
- return SQ_ERROR;
- }
-
- try {
- _this->move(static_cast<float> (arg0), static_cast<float> (arg1));
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'move'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger ScriptedObject_set_pos_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'set_pos' called without instance"));
- return SQ_ERROR;
- }
- Scripting::ScriptedObject* _this = reinterpret_cast<Scripting::ScriptedObject*> (data);
- SQFloat arg0;
- if(SQ_FAILED(sq_getfloat(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not a float"));
- return SQ_ERROR;
- }
- SQFloat arg1;
- if(SQ_FAILED(sq_getfloat(vm, 3, &arg1))) {
- sq_throwerror(vm, _SC("Argument 2 not a float"));
- return SQ_ERROR;
- }
-
- try {
- _this->set_pos(static_cast<float> (arg0), static_cast<float> (arg1));
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'set_pos'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger ScriptedObject_get_pos_x_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'get_pos_x' called without instance"));
- return SQ_ERROR;
- }
- Scripting::ScriptedObject* _this = reinterpret_cast<Scripting::ScriptedObject*> (data);
-
- try {
- float return_value = _this->get_pos_x();
-
- sq_pushfloat(vm, return_value);
- return 1;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'get_pos_x'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger ScriptedObject_get_pos_y_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'get_pos_y' called without instance"));
- return SQ_ERROR;
- }
- Scripting::ScriptedObject* _this = reinterpret_cast<Scripting::ScriptedObject*> (data);
-
- try {
- float return_value = _this->get_pos_y();
-
- sq_pushfloat(vm, return_value);
- return 1;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'get_pos_y'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger ScriptedObject_set_velocity_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'set_velocity' called without instance"));
- return SQ_ERROR;
- }
- Scripting::ScriptedObject* _this = reinterpret_cast<Scripting::ScriptedObject*> (data);
- SQFloat arg0;
- if(SQ_FAILED(sq_getfloat(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not a float"));
- return SQ_ERROR;
- }
- SQFloat arg1;
- if(SQ_FAILED(sq_getfloat(vm, 3, &arg1))) {
- sq_throwerror(vm, _SC("Argument 2 not a float"));
- return SQ_ERROR;
- }
-
- try {
- _this->set_velocity(static_cast<float> (arg0), static_cast<float> (arg1));
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'set_velocity'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger ScriptedObject_get_velocity_x_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'get_velocity_x' called without instance"));
- return SQ_ERROR;
- }
- Scripting::ScriptedObject* _this = reinterpret_cast<Scripting::ScriptedObject*> (data);
-
- try {
- float return_value = _this->get_velocity_x();
-
- sq_pushfloat(vm, return_value);
- return 1;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'get_velocity_x'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger ScriptedObject_get_velocity_y_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'get_velocity_y' called without instance"));
- return SQ_ERROR;
- }
- Scripting::ScriptedObject* _this = reinterpret_cast<Scripting::ScriptedObject*> (data);
-
- try {
- float return_value = _this->get_velocity_y();
-
- sq_pushfloat(vm, return_value);
- return 1;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'get_velocity_y'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger ScriptedObject_set_visible_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'set_visible' called without instance"));
- return SQ_ERROR;
- }
- Scripting::ScriptedObject* _this = reinterpret_cast<Scripting::ScriptedObject*> (data);
- SQBool arg0;
- if(SQ_FAILED(sq_getbool(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not a bool"));
- return SQ_ERROR;
- }
-
- try {
- _this->set_visible(arg0 == SQTrue);
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'set_visible'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger ScriptedObject_is_visible_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'is_visible' called without instance"));
- return SQ_ERROR;
- }
- Scripting::ScriptedObject* _this = reinterpret_cast<Scripting::ScriptedObject*> (data);
-
- try {
- bool return_value = _this->is_visible();
-
- sq_pushbool(vm, return_value);
- return 1;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'is_visible'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger ScriptedObject_set_solid_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'set_solid' called without instance"));
- return SQ_ERROR;
- }
- Scripting::ScriptedObject* _this = reinterpret_cast<Scripting::ScriptedObject*> (data);
- SQBool arg0;
- if(SQ_FAILED(sq_getbool(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not a bool"));
- return SQ_ERROR;
- }
-
- try {
- _this->set_solid(arg0 == SQTrue);
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'set_solid'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger ScriptedObject_is_solid_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'is_solid' called without instance"));
- return SQ_ERROR;
- }
- Scripting::ScriptedObject* _this = reinterpret_cast<Scripting::ScriptedObject*> (data);
-
- try {
- bool return_value = _this->is_solid();
-
- sq_pushbool(vm, return_value);
- return 1;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'is_solid'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger ScriptedObject_get_name_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'get_name' called without instance"));
- return SQ_ERROR;
- }
- Scripting::ScriptedObject* _this = reinterpret_cast<Scripting::ScriptedObject*> (data);
-
- try {
- std::string return_value = _this->get_name();
-
- sq_pushstring(vm, return_value.c_str(), return_value.size());
- return 1;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'get_name'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger Text_release_hook(SQUserPointer ptr, SQInteger )
-{
- Scripting::Text* _this = reinterpret_cast<Scripting::Text*> (ptr);
- delete _this;
- return 0;
-}
-
-static SQInteger Text_set_text_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'set_text' called without instance"));
- return SQ_ERROR;
- }
- Scripting::Text* _this = reinterpret_cast<Scripting::Text*> (data);
- const SQChar* arg0;
- if(SQ_FAILED(sq_getstring(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not a string"));
- return SQ_ERROR;
- }
-
- try {
- _this->set_text(arg0);
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'set_text'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger Text_set_font_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'set_font' called without instance"));
- return SQ_ERROR;
- }
- Scripting::Text* _this = reinterpret_cast<Scripting::Text*> (data);
- const SQChar* arg0;
- if(SQ_FAILED(sq_getstring(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not a string"));
- return SQ_ERROR;
- }
-
- try {
- _this->set_font(arg0);
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'set_font'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger Text_fade_in_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'fade_in' called without instance"));
- return SQ_ERROR;
- }
- Scripting::Text* _this = reinterpret_cast<Scripting::Text*> (data);
- SQFloat arg0;
- if(SQ_FAILED(sq_getfloat(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not a float"));
- return SQ_ERROR;
- }
-
- try {
- _this->fade_in(static_cast<float> (arg0));
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'fade_in'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger Text_fade_out_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'fade_out' called without instance"));
- return SQ_ERROR;
- }
- Scripting::Text* _this = reinterpret_cast<Scripting::Text*> (data);
- SQFloat arg0;
- if(SQ_FAILED(sq_getfloat(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not a float"));
- return SQ_ERROR;
- }
-
- try {
- _this->fade_out(static_cast<float> (arg0));
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'fade_out'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger Text_set_visible_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'set_visible' called without instance"));
- return SQ_ERROR;
- }
- Scripting::Text* _this = reinterpret_cast<Scripting::Text*> (data);
- SQBool arg0;
- if(SQ_FAILED(sq_getbool(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not a bool"));
- return SQ_ERROR;
- }
-
- try {
- _this->set_visible(arg0 == SQTrue);
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'set_visible'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger Text_set_centered_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'set_centered' called without instance"));
- return SQ_ERROR;
- }
- Scripting::Text* _this = reinterpret_cast<Scripting::Text*> (data);
- SQBool arg0;
- if(SQ_FAILED(sq_getbool(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not a bool"));
- return SQ_ERROR;
- }
-
- try {
- _this->set_centered(arg0 == SQTrue);
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'set_centered'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger Text_set_pos_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'set_pos' called without instance"));
- return SQ_ERROR;
- }
- Scripting::Text* _this = reinterpret_cast<Scripting::Text*> (data);
- SQFloat arg0;
- if(SQ_FAILED(sq_getfloat(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not a float"));
- return SQ_ERROR;
- }
- SQFloat arg1;
- if(SQ_FAILED(sq_getfloat(vm, 3, &arg1))) {
- sq_throwerror(vm, _SC("Argument 2 not a float"));
- return SQ_ERROR;
- }
-
- try {
- _this->set_pos(static_cast<float> (arg0), static_cast<float> (arg1));
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'set_pos'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger Text_get_pos_x_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'get_pos_x' called without instance"));
- return SQ_ERROR;
- }
- Scripting::Text* _this = reinterpret_cast<Scripting::Text*> (data);
-
- try {
- float return_value = _this->get_pos_x();
-
- sq_pushfloat(vm, return_value);
- return 1;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'get_pos_x'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger Text_get_pos_y_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'get_pos_y' called without instance"));
- return SQ_ERROR;
- }
- Scripting::Text* _this = reinterpret_cast<Scripting::Text*> (data);
-
- try {
- float return_value = _this->get_pos_y();
-
- sq_pushfloat(vm, return_value);
- return 1;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'get_pos_y'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger Text_set_anchor_point_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'set_anchor_point' called without instance"));
- return SQ_ERROR;
- }
- Scripting::Text* _this = reinterpret_cast<Scripting::Text*> (data);
- SQInteger arg0;
- if(SQ_FAILED(sq_getinteger(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not an integer"));
- return SQ_ERROR;
- }
-
- try {
- _this->set_anchor_point(static_cast<int> (arg0));
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'set_anchor_point'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger Text_get_anchor_point_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'get_anchor_point' called without instance"));
- return SQ_ERROR;
- }
- Scripting::Text* _this = reinterpret_cast<Scripting::Text*> (data);
-
- try {
- int return_value = _this->get_anchor_point();
-
- sq_pushinteger(vm, return_value);
- return 1;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'get_anchor_point'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger Player_release_hook(SQUserPointer ptr, SQInteger )
-{
- Scripting::Player* _this = reinterpret_cast<Scripting::Player*> (ptr);
- delete _this;
- return 0;
-}
-
-static SQInteger Player_add_bonus_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'add_bonus' called without instance"));
- return SQ_ERROR;
- }
- Scripting::Player* _this = reinterpret_cast<Scripting::Player*> (data);
- const SQChar* arg0;
- if(SQ_FAILED(sq_getstring(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not a string"));
- return SQ_ERROR;
- }
-
- try {
- bool return_value = _this->add_bonus(arg0);
-
- sq_pushbool(vm, return_value);
- return 1;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'add_bonus'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger Player_add_coins_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'add_coins' called without instance"));
- return SQ_ERROR;
- }
- Scripting::Player* _this = reinterpret_cast<Scripting::Player*> (data);
- SQInteger arg0;
- if(SQ_FAILED(sq_getinteger(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not an integer"));
- return SQ_ERROR;
- }
-
- try {
- _this->add_coins(static_cast<int> (arg0));
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'add_coins'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger Player_make_invincible_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'make_invincible' called without instance"));
- return SQ_ERROR;
- }
- Scripting::Player* _this = reinterpret_cast<Scripting::Player*> (data);
-
- try {
- _this->make_invincible();
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'make_invincible'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger Player_deactivate_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'deactivate' called without instance"));
- return SQ_ERROR;
- }
- Scripting::Player* _this = reinterpret_cast<Scripting::Player*> (data);
-
- try {
- _this->deactivate();
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'deactivate'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger Player_activate_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'activate' called without instance"));
- return SQ_ERROR;
- }
- Scripting::Player* _this = reinterpret_cast<Scripting::Player*> (data);
-
- try {
- _this->activate();
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'activate'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger Player_walk_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'walk' called without instance"));
- return SQ_ERROR;
- }
- Scripting::Player* _this = reinterpret_cast<Scripting::Player*> (data);
- SQFloat arg0;
- if(SQ_FAILED(sq_getfloat(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not a float"));
- return SQ_ERROR;
- }
-
- try {
- _this->walk(static_cast<float> (arg0));
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'walk'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger Player_set_visible_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'set_visible' called without instance"));
- return SQ_ERROR;
- }
- Scripting::Player* _this = reinterpret_cast<Scripting::Player*> (data);
- SQBool arg0;
- if(SQ_FAILED(sq_getbool(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not a bool"));
- return SQ_ERROR;
- }
-
- try {
- _this->set_visible(arg0 == SQTrue);
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'set_visible'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger Player_get_visible_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'get_visible' called without instance"));
- return SQ_ERROR;
- }
- Scripting::Player* _this = reinterpret_cast<Scripting::Player*> (data);
-
- try {
- bool return_value = _this->get_visible();
-
- sq_pushbool(vm, return_value);
- return 1;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'get_visible'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger Player_kill_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'kill' called without instance"));
- return SQ_ERROR;
- }
- Scripting::Player* _this = reinterpret_cast<Scripting::Player*> (data);
- SQBool arg0;
- if(SQ_FAILED(sq_getbool(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not a bool"));
- return SQ_ERROR;
- }
-
- try {
- _this->kill(arg0 == SQTrue);
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'kill'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger Player_set_ghost_mode_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'set_ghost_mode' called without instance"));
- return SQ_ERROR;
- }
- Scripting::Player* _this = reinterpret_cast<Scripting::Player*> (data);
- SQBool arg0;
- if(SQ_FAILED(sq_getbool(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not a bool"));
- return SQ_ERROR;
- }
-
- try {
- _this->set_ghost_mode(arg0 == SQTrue);
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'set_ghost_mode'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger Player_get_ghost_mode_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'get_ghost_mode' called without instance"));
- return SQ_ERROR;
- }
- Scripting::Player* _this = reinterpret_cast<Scripting::Player*> (data);
-
- try {
- bool return_value = _this->get_ghost_mode();
-
- sq_pushbool(vm, return_value);
- return 1;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'get_ghost_mode'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger Player_do_cheer_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'do_cheer' called without instance"));
- return SQ_ERROR;
- }
- Scripting::Player* _this = reinterpret_cast<Scripting::Player*> (data);
-
- try {
- _this->do_cheer();
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'do_cheer'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger Player_do_duck_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'do_duck' called without instance"));
- return SQ_ERROR;
- }
- Scripting::Player* _this = reinterpret_cast<Scripting::Player*> (data);
-
- try {
- _this->do_duck();
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'do_duck'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger Player_do_standup_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'do_standup' called without instance"));
- return SQ_ERROR;
- }
- Scripting::Player* _this = reinterpret_cast<Scripting::Player*> (data);
-
- try {
- _this->do_standup();
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'do_standup'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger Player_do_backflip_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'do_backflip' called without instance"));
- return SQ_ERROR;
- }
- Scripting::Player* _this = reinterpret_cast<Scripting::Player*> (data);
-
- try {
- _this->do_backflip();
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'do_backflip'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger Player_do_jump_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'do_jump' called without instance"));
- return SQ_ERROR;
- }
- Scripting::Player* _this = reinterpret_cast<Scripting::Player*> (data);
- SQFloat arg0;
- if(SQ_FAILED(sq_getfloat(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not a float"));
- return SQ_ERROR;
- }
-
- try {
- _this->do_jump(static_cast<float> (arg0));
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'do_jump'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger Player_trigger_sequence_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'trigger_sequence' called without instance"));
- return SQ_ERROR;
- }
- Scripting::Player* _this = reinterpret_cast<Scripting::Player*> (data);
- const SQChar* arg0;
- if(SQ_FAILED(sq_getstring(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not a string"));
- return SQ_ERROR;
- }
-
- try {
- _this->trigger_sequence(arg0);
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'trigger_sequence'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger FloatingImage_release_hook(SQUserPointer ptr, SQInteger )
-{
- Scripting::FloatingImage* _this = reinterpret_cast<Scripting::FloatingImage*> (ptr);
- delete _this;
- return 0;
-}
-
-static SQInteger FloatingImage_constructor_wrapper(HSQUIRRELVM vm)
-{
- const SQChar* arg0;
- if(SQ_FAILED(sq_getstring(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not a string"));
- return SQ_ERROR;
- }
-
- try {
- Scripting::FloatingImage* _this = new Scripting::FloatingImage(arg0);
- if(SQ_FAILED(sq_setinstanceup(vm, 1, _this))) {
- sq_throwerror(vm, _SC("Couldn't setup instance of 'FloatingImage' class"));
- return SQ_ERROR;
- }
- sq_setreleasehook(vm, 1, FloatingImage_release_hook);
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'constructor'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger FloatingImage_set_layer_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'set_layer' called without instance"));
- return SQ_ERROR;
- }
- Scripting::FloatingImage* _this = reinterpret_cast<Scripting::FloatingImage*> (data);
- SQInteger arg0;
- if(SQ_FAILED(sq_getinteger(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not an integer"));
- return SQ_ERROR;
- }
-
- try {
- _this->set_layer(static_cast<int> (arg0));
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'set_layer'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger FloatingImage_get_layer_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'get_layer' called without instance"));
- return SQ_ERROR;
- }
- Scripting::FloatingImage* _this = reinterpret_cast<Scripting::FloatingImage*> (data);
-
- try {
- int return_value = _this->get_layer();
-
- sq_pushinteger(vm, return_value);
- return 1;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'get_layer'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger FloatingImage_set_pos_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'set_pos' called without instance"));
- return SQ_ERROR;
- }
- Scripting::FloatingImage* _this = reinterpret_cast<Scripting::FloatingImage*> (data);
- SQFloat arg0;
- if(SQ_FAILED(sq_getfloat(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not a float"));
- return SQ_ERROR;
- }
- SQFloat arg1;
- if(SQ_FAILED(sq_getfloat(vm, 3, &arg1))) {
- sq_throwerror(vm, _SC("Argument 2 not a float"));
- return SQ_ERROR;
- }
-
- try {
- _this->set_pos(static_cast<float> (arg0), static_cast<float> (arg1));
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'set_pos'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger FloatingImage_get_pos_x_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'get_pos_x' called without instance"));
- return SQ_ERROR;
- }
- Scripting::FloatingImage* _this = reinterpret_cast<Scripting::FloatingImage*> (data);
-
- try {
- float return_value = _this->get_pos_x();
-
- sq_pushfloat(vm, return_value);
- return 1;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'get_pos_x'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger FloatingImage_get_pos_y_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'get_pos_y' called without instance"));
- return SQ_ERROR;
- }
- Scripting::FloatingImage* _this = reinterpret_cast<Scripting::FloatingImage*> (data);
-
- try {
- float return_value = _this->get_pos_y();
-
- sq_pushfloat(vm, return_value);
- return 1;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'get_pos_y'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger FloatingImage_set_anchor_point_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'set_anchor_point' called without instance"));
- return SQ_ERROR;
- }
- Scripting::FloatingImage* _this = reinterpret_cast<Scripting::FloatingImage*> (data);
- SQInteger arg0;
- if(SQ_FAILED(sq_getinteger(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not an integer"));
- return SQ_ERROR;
- }
-
- try {
- _this->set_anchor_point(static_cast<int> (arg0));
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'set_anchor_point'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger FloatingImage_get_anchor_point_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'get_anchor_point' called without instance"));
- return SQ_ERROR;
- }
- Scripting::FloatingImage* _this = reinterpret_cast<Scripting::FloatingImage*> (data);
-
- try {
- int return_value = _this->get_anchor_point();
-
- sq_pushinteger(vm, return_value);
- return 1;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'get_anchor_point'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger FloatingImage_set_visible_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'set_visible' called without instance"));
- return SQ_ERROR;
- }
- Scripting::FloatingImage* _this = reinterpret_cast<Scripting::FloatingImage*> (data);
- SQBool arg0;
- if(SQ_FAILED(sq_getbool(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not a bool"));
- return SQ_ERROR;
- }
-
- try {
- _this->set_visible(arg0 == SQTrue);
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'set_visible'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger FloatingImage_get_visible_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'get_visible' called without instance"));
- return SQ_ERROR;
- }
- Scripting::FloatingImage* _this = reinterpret_cast<Scripting::FloatingImage*> (data);
-
- try {
- bool return_value = _this->get_visible();
-
- sq_pushbool(vm, return_value);
- return 1;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'get_visible'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger FloatingImage_set_action_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'set_action' called without instance"));
- return SQ_ERROR;
- }
- Scripting::FloatingImage* _this = reinterpret_cast<Scripting::FloatingImage*> (data);
- const SQChar* arg0;
- if(SQ_FAILED(sq_getstring(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not a string"));
- return SQ_ERROR;
- }
-
- try {
- _this->set_action(arg0);
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'set_action'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger FloatingImage_get_action_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'get_action' called without instance"));
- return SQ_ERROR;
- }
- Scripting::FloatingImage* _this = reinterpret_cast<Scripting::FloatingImage*> (data);
-
- try {
- std::string return_value = _this->get_action();
-
- sq_pushstring(vm, return_value.c_str(), return_value.size());
- return 1;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'get_action'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger FloatingImage_fade_in_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'fade_in' called without instance"));
- return SQ_ERROR;
- }
- Scripting::FloatingImage* _this = reinterpret_cast<Scripting::FloatingImage*> (data);
- SQFloat arg0;
- if(SQ_FAILED(sq_getfloat(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not a float"));
- return SQ_ERROR;
- }
-
- try {
- _this->fade_in(static_cast<float> (arg0));
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'fade_in'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger FloatingImage_fade_out_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'fade_out' called without instance"));
- return SQ_ERROR;
- }
- Scripting::FloatingImage* _this = reinterpret_cast<Scripting::FloatingImage*> (data);
- SQFloat arg0;
- if(SQ_FAILED(sq_getfloat(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not a float"));
- return SQ_ERROR;
- }
-
- try {
- _this->fade_out(static_cast<float> (arg0));
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'fade_out'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger Platform_release_hook(SQUserPointer ptr, SQInteger )
-{
- Scripting::Platform* _this = reinterpret_cast<Scripting::Platform*> (ptr);
- delete _this;
- return 0;
-}
-
-static SQInteger Platform_goto_node_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'goto_node' called without instance"));
- return SQ_ERROR;
- }
- Scripting::Platform* _this = reinterpret_cast<Scripting::Platform*> (data);
- SQInteger arg0;
- if(SQ_FAILED(sq_getinteger(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not an integer"));
- return SQ_ERROR;
- }
-
- try {
- _this->goto_node(static_cast<int> (arg0));
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'goto_node'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger Platform_start_moving_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'start_moving' called without instance"));
- return SQ_ERROR;
- }
- Scripting::Platform* _this = reinterpret_cast<Scripting::Platform*> (data);
-
- try {
- _this->start_moving();
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'start_moving'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger Platform_stop_moving_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'stop_moving' called without instance"));
- return SQ_ERROR;
- }
- Scripting::Platform* _this = reinterpret_cast<Scripting::Platform*> (data);
-
- try {
- _this->stop_moving();
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'stop_moving'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger Candle_release_hook(SQUserPointer ptr, SQInteger )
-{
- Scripting::Candle* _this = reinterpret_cast<Scripting::Candle*> (ptr);
- delete _this;
- return 0;
-}
-
-static SQInteger Candle_get_burning_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'get_burning' called without instance"));
- return SQ_ERROR;
- }
- Scripting::Candle* _this = reinterpret_cast<Scripting::Candle*> (data);
-
- try {
- bool return_value = _this->get_burning();
-
- sq_pushbool(vm, return_value);
- return 1;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'get_burning'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger Candle_set_burning_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'set_burning' called without instance"));
- return SQ_ERROR;
- }
- Scripting::Candle* _this = reinterpret_cast<Scripting::Candle*> (data);
- SQBool arg0;
- if(SQ_FAILED(sq_getbool(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not a bool"));
- return SQ_ERROR;
- }
-
- try {
- _this->set_burning(arg0 == SQTrue);
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'set_burning'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger Wind_release_hook(SQUserPointer ptr, SQInteger )
-{
- Scripting::Wind* _this = reinterpret_cast<Scripting::Wind*> (ptr);
- delete _this;
- return 0;
-}
-
-static SQInteger Wind_start_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'start' called without instance"));
- return SQ_ERROR;
- }
- Scripting::Wind* _this = reinterpret_cast<Scripting::Wind*> (data);
-
- try {
- _this->start();
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'start'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger Wind_stop_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'stop' called without instance"));
- return SQ_ERROR;
- }
- Scripting::Wind* _this = reinterpret_cast<Scripting::Wind*> (data);
-
- try {
- _this->stop();
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'stop'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger AmbientSound_release_hook(SQUserPointer ptr, SQInteger )
-{
- Scripting::AmbientSound* _this = reinterpret_cast<Scripting::AmbientSound*> (ptr);
- delete _this;
- return 0;
-}
-
-static SQInteger AmbientSound_set_pos_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'set_pos' called without instance"));
- return SQ_ERROR;
- }
- Scripting::AmbientSound* _this = reinterpret_cast<Scripting::AmbientSound*> (data);
- SQFloat arg0;
- if(SQ_FAILED(sq_getfloat(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not a float"));
- return SQ_ERROR;
- }
- SQFloat arg1;
- if(SQ_FAILED(sq_getfloat(vm, 3, &arg1))) {
- sq_throwerror(vm, _SC("Argument 2 not a float"));
- return SQ_ERROR;
- }
-
- try {
- _this->set_pos(static_cast<float> (arg0), static_cast<float> (arg1));
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'set_pos'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger AmbientSound_get_pos_x_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'get_pos_x' called without instance"));
- return SQ_ERROR;
- }
- Scripting::AmbientSound* _this = reinterpret_cast<Scripting::AmbientSound*> (data);
-
- try {
- float return_value = _this->get_pos_x();
-
- sq_pushfloat(vm, return_value);
- return 1;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'get_pos_x'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger AmbientSound_get_pos_y_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'get_pos_y' called without instance"));
- return SQ_ERROR;
- }
- Scripting::AmbientSound* _this = reinterpret_cast<Scripting::AmbientSound*> (data);
-
- try {
- float return_value = _this->get_pos_y();
-
- sq_pushfloat(vm, return_value);
- return 1;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'get_pos_y'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger Thunderstorm_release_hook(SQUserPointer ptr, SQInteger )
-{
- Scripting::Thunderstorm* _this = reinterpret_cast<Scripting::Thunderstorm*> (ptr);
- delete _this;
- return 0;
-}
-
-static SQInteger Thunderstorm_start_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'start' called without instance"));
- return SQ_ERROR;
- }
- Scripting::Thunderstorm* _this = reinterpret_cast<Scripting::Thunderstorm*> (data);
-
- try {
- _this->start();
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'start'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger Thunderstorm_stop_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'stop' called without instance"));
- return SQ_ERROR;
- }
- Scripting::Thunderstorm* _this = reinterpret_cast<Scripting::Thunderstorm*> (data);
-
- try {
- _this->stop();
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'stop'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger Thunderstorm_thunder_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'thunder' called without instance"));
- return SQ_ERROR;
- }
- Scripting::Thunderstorm* _this = reinterpret_cast<Scripting::Thunderstorm*> (data);
-
- try {
- _this->thunder();
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'thunder'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger Thunderstorm_lightning_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'lightning' called without instance"));
- return SQ_ERROR;
- }
- Scripting::Thunderstorm* _this = reinterpret_cast<Scripting::Thunderstorm*> (data);
-
- try {
- _this->lightning();
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'lightning'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger Thunderstorm_flash_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'flash' called without instance"));
- return SQ_ERROR;
- }
- Scripting::Thunderstorm* _this = reinterpret_cast<Scripting::Thunderstorm*> (data);
-
- try {
- _this->flash();
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'flash'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger Thunderstorm_electrify_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'electrify' called without instance"));
- return SQ_ERROR;
- }
- Scripting::Thunderstorm* _this = reinterpret_cast<Scripting::Thunderstorm*> (data);
-
- try {
- _this->electrify();
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'electrify'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger TileMap_release_hook(SQUserPointer ptr, SQInteger )
-{
- Scripting::TileMap* _this = reinterpret_cast<Scripting::TileMap*> (ptr);
- delete _this;
- return 0;
-}
-
-static SQInteger TileMap_goto_node_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'goto_node' called without instance"));
- return SQ_ERROR;
- }
- Scripting::TileMap* _this = reinterpret_cast<Scripting::TileMap*> (data);
- SQInteger arg0;
- if(SQ_FAILED(sq_getinteger(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not an integer"));
- return SQ_ERROR;
- }
-
- try {
- _this->goto_node(static_cast<int> (arg0));
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'goto_node'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger TileMap_start_moving_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'start_moving' called without instance"));
- return SQ_ERROR;
- }
- Scripting::TileMap* _this = reinterpret_cast<Scripting::TileMap*> (data);
-
- try {
- _this->start_moving();
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'start_moving'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger TileMap_stop_moving_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'stop_moving' called without instance"));
- return SQ_ERROR;
- }
- Scripting::TileMap* _this = reinterpret_cast<Scripting::TileMap*> (data);
-
- try {
- _this->stop_moving();
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'stop_moving'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger TileMap_fade_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'fade' called without instance"));
- return SQ_ERROR;
- }
- Scripting::TileMap* _this = reinterpret_cast<Scripting::TileMap*> (data);
- SQFloat arg0;
- if(SQ_FAILED(sq_getfloat(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not a float"));
- return SQ_ERROR;
- }
- SQFloat arg1;
- if(SQ_FAILED(sq_getfloat(vm, 3, &arg1))) {
- sq_throwerror(vm, _SC("Argument 2 not a float"));
- return SQ_ERROR;
- }
-
- try {
- _this->fade(static_cast<float> (arg0), static_cast<float> (arg1));
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'fade'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger TileMap_set_alpha_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'set_alpha' called without instance"));
- return SQ_ERROR;
- }
- Scripting::TileMap* _this = reinterpret_cast<Scripting::TileMap*> (data);
- SQFloat arg0;
- if(SQ_FAILED(sq_getfloat(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not a float"));
- return SQ_ERROR;
- }
-
- try {
- _this->set_alpha(static_cast<float> (arg0));
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'set_alpha'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger TileMap_get_alpha_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'get_alpha' called without instance"));
- return SQ_ERROR;
- }
- Scripting::TileMap* _this = reinterpret_cast<Scripting::TileMap*> (data);
-
- try {
- float return_value = _this->get_alpha();
-
- sq_pushfloat(vm, return_value);
- return 1;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'get_alpha'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger SSector_release_hook(SQUserPointer ptr, SQInteger )
-{
- Scripting::SSector* _this = reinterpret_cast<Scripting::SSector*> (ptr);
- delete _this;
- return 0;
-}
-
-static SQInteger SSector_set_ambient_light_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'set_ambient_light' called without instance"));
- return SQ_ERROR;
- }
- Scripting::SSector* _this = reinterpret_cast<Scripting::SSector*> (data);
- SQFloat arg0;
- if(SQ_FAILED(sq_getfloat(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not a float"));
- return SQ_ERROR;
- }
- SQFloat arg1;
- if(SQ_FAILED(sq_getfloat(vm, 3, &arg1))) {
- sq_throwerror(vm, _SC("Argument 2 not a float"));
- return SQ_ERROR;
- }
- SQFloat arg2;
- if(SQ_FAILED(sq_getfloat(vm, 4, &arg2))) {
- sq_throwerror(vm, _SC("Argument 3 not a float"));
- return SQ_ERROR;
- }
-
- try {
- _this->set_ambient_light(static_cast<float> (arg0), static_cast<float> (arg1), static_cast<float> (arg2));
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'set_ambient_light'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger SSector_get_ambient_red_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'get_ambient_red' called without instance"));
- return SQ_ERROR;
- }
- Scripting::SSector* _this = reinterpret_cast<Scripting::SSector*> (data);
-
- try {
- float return_value = _this->get_ambient_red();
-
- sq_pushfloat(vm, return_value);
- return 1;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'get_ambient_red'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger SSector_get_ambient_green_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'get_ambient_green' called without instance"));
- return SQ_ERROR;
- }
- Scripting::SSector* _this = reinterpret_cast<Scripting::SSector*> (data);
-
- try {
- float return_value = _this->get_ambient_green();
-
- sq_pushfloat(vm, return_value);
- return 1;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'get_ambient_green'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger SSector_get_ambient_blue_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'get_ambient_blue' called without instance"));
- return SQ_ERROR;
- }
- Scripting::SSector* _this = reinterpret_cast<Scripting::SSector*> (data);
-
- try {
- float return_value = _this->get_ambient_blue();
-
- sq_pushfloat(vm, return_value);
- return 1;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'get_ambient_blue'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger LevelTime_release_hook(SQUserPointer ptr, SQInteger )
-{
- Scripting::LevelTime* _this = reinterpret_cast<Scripting::LevelTime*> (ptr);
- delete _this;
- return 0;
-}
-
-static SQInteger LevelTime_start_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'start' called without instance"));
- return SQ_ERROR;
- }
- Scripting::LevelTime* _this = reinterpret_cast<Scripting::LevelTime*> (data);
-
- try {
- _this->start();
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'start'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger LevelTime_stop_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'stop' called without instance"));
- return SQ_ERROR;
- }
- Scripting::LevelTime* _this = reinterpret_cast<Scripting::LevelTime*> (data);
-
- try {
- _this->stop();
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'stop'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger LevelTime_get_time_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'get_time' called without instance"));
- return SQ_ERROR;
- }
- Scripting::LevelTime* _this = reinterpret_cast<Scripting::LevelTime*> (data);
-
- try {
- float return_value = _this->get_time();
-
- sq_pushfloat(vm, return_value);
- return 1;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'get_time'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger LevelTime_set_time_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'set_time' called without instance"));
- return SQ_ERROR;
- }
- Scripting::LevelTime* _this = reinterpret_cast<Scripting::LevelTime*> (data);
- SQFloat arg0;
- if(SQ_FAILED(sq_getfloat(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not a float"));
- return SQ_ERROR;
- }
-
- try {
- _this->set_time(static_cast<float> (arg0));
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'set_time'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger WillOWisp_release_hook(SQUserPointer ptr, SQInteger )
-{
- Scripting::WillOWisp* _this = reinterpret_cast<Scripting::WillOWisp*> (ptr);
- delete _this;
- return 0;
-}
-
-static SQInteger WillOWisp_goto_node_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'goto_node' called without instance"));
- return SQ_ERROR;
- }
- Scripting::WillOWisp* _this = reinterpret_cast<Scripting::WillOWisp*> (data);
- SQInteger arg0;
- if(SQ_FAILED(sq_getinteger(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not an integer"));
- return SQ_ERROR;
- }
-
- try {
- _this->goto_node(static_cast<int> (arg0));
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'goto_node'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger WillOWisp_set_state_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'set_state' called without instance"));
- return SQ_ERROR;
- }
- Scripting::WillOWisp* _this = reinterpret_cast<Scripting::WillOWisp*> (data);
- const SQChar* arg0;
- if(SQ_FAILED(sq_getstring(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not a string"));
- return SQ_ERROR;
- }
-
- try {
- _this->set_state(arg0);
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'set_state'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger WillOWisp_start_moving_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'start_moving' called without instance"));
- return SQ_ERROR;
- }
- Scripting::WillOWisp* _this = reinterpret_cast<Scripting::WillOWisp*> (data);
-
- try {
- _this->start_moving();
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'start_moving'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger WillOWisp_stop_moving_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'stop_moving' called without instance"));
- return SQ_ERROR;
- }
- Scripting::WillOWisp* _this = reinterpret_cast<Scripting::WillOWisp*> (data);
-
- try {
- _this->stop_moving();
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'stop_moving'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger display_wrapper(HSQUIRRELVM vm)
-{
- return Scripting::display(vm);
-}
-
-static SQInteger print_stacktrace_wrapper(HSQUIRRELVM vm)
-{
- HSQUIRRELVM arg0 = vm;
-
- try {
- Scripting::print_stacktrace(arg0);
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'print_stacktrace'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger get_current_thread_wrapper(HSQUIRRELVM vm)
-{
- return Scripting::get_current_thread(vm);
-}
-
-static SQInteger display_text_file_wrapper(HSQUIRRELVM vm)
-{
- const SQChar* arg0;
- if(SQ_FAILED(sq_getstring(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not a string"));
- return SQ_ERROR;
- }
-
- try {
- Scripting::display_text_file(arg0);
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'display_text_file'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger load_worldmap_wrapper(HSQUIRRELVM vm)
-{
- const SQChar* arg0;
- if(SQ_FAILED(sq_getstring(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not a string"));
- return SQ_ERROR;
- }
-
- try {
- Scripting::load_worldmap(arg0);
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'load_worldmap'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger load_level_wrapper(HSQUIRRELVM vm)
-{
- const SQChar* arg0;
- if(SQ_FAILED(sq_getstring(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not a string"));
- return SQ_ERROR;
- }
-
- try {
- Scripting::load_level(arg0);
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'load_level'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger wait_wrapper(HSQUIRRELVM vm)
-{
- HSQUIRRELVM arg0 = vm;
- SQFloat arg1;
- if(SQ_FAILED(sq_getfloat(vm, 2, &arg1))) {
- sq_throwerror(vm, _SC("Argument 1 not a float"));
- return SQ_ERROR;
- }
-
- try {
- Scripting::wait(arg0, static_cast<float> (arg1));
-
- return sq_suspendvm(vm);
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'wait'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger wait_for_screenswitch_wrapper(HSQUIRRELVM vm)
-{
- HSQUIRRELVM arg0 = vm;
-
- try {
- Scripting::wait_for_screenswitch(arg0);
-
- return sq_suspendvm(vm);
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'wait_for_screenswitch'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger exit_screen_wrapper(HSQUIRRELVM vm)
-{
- (void) vm;
-
- try {
- Scripting::exit_screen();
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'exit_screen'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger fadeout_screen_wrapper(HSQUIRRELVM vm)
-{
- SQFloat arg0;
- if(SQ_FAILED(sq_getfloat(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not a float"));
- return SQ_ERROR;
- }
-
- try {
- Scripting::fadeout_screen(static_cast<float> (arg0));
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'fadeout_screen'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger shrink_screen_wrapper(HSQUIRRELVM vm)
-{
- SQFloat arg0;
- if(SQ_FAILED(sq_getfloat(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not a float"));
- return SQ_ERROR;
- }
- SQFloat arg1;
- if(SQ_FAILED(sq_getfloat(vm, 3, &arg1))) {
- sq_throwerror(vm, _SC("Argument 2 not a float"));
- return SQ_ERROR;
- }
- SQFloat arg2;
- if(SQ_FAILED(sq_getfloat(vm, 4, &arg2))) {
- sq_throwerror(vm, _SC("Argument 3 not a float"));
- return SQ_ERROR;
- }
-
- try {
- Scripting::shrink_screen(static_cast<float> (arg0), static_cast<float> (arg1), static_cast<float> (arg2));
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'shrink_screen'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger abort_screenfade_wrapper(HSQUIRRELVM vm)
-{
- (void) vm;
-
- try {
- Scripting::abort_screenfade();
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'abort_screenfade'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger translate_wrapper(HSQUIRRELVM vm)
-{
- const SQChar* arg0;
- if(SQ_FAILED(sq_getstring(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not a string"));
- return SQ_ERROR;
- }
-
- try {
- std::string return_value = Scripting::translate(arg0);
-
- sq_pushstring(vm, return_value.c_str(), return_value.size());
- return 1;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'translate'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger import_wrapper(HSQUIRRELVM vm)
-{
- HSQUIRRELVM arg0 = vm;
- const SQChar* arg1;
- if(SQ_FAILED(sq_getstring(vm, 2, &arg1))) {
- sq_throwerror(vm, _SC("Argument 1 not a string"));
- return SQ_ERROR;
- }
-
- try {
- Scripting::import(arg0, arg1);
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'import'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger save_state_wrapper(HSQUIRRELVM vm)
-{
- (void) vm;
-
- try {
- Scripting::save_state();
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'save_state'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger update_worldmap_wrapper(HSQUIRRELVM vm)
-{
- (void) vm;
-
- try {
- Scripting::update_worldmap();
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'update_worldmap'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger debug_collrects_wrapper(HSQUIRRELVM vm)
-{
- SQBool arg0;
- if(SQ_FAILED(sq_getbool(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not a bool"));
- return SQ_ERROR;
- }
-
- try {
- Scripting::debug_collrects(arg0 == SQTrue);
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'debug_collrects'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger debug_show_fps_wrapper(HSQUIRRELVM vm)
-{
- SQBool arg0;
- if(SQ_FAILED(sq_getbool(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not a bool"));
- return SQ_ERROR;
- }
-
- try {
- Scripting::debug_show_fps(arg0 == SQTrue);
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'debug_show_fps'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger debug_draw_solids_only_wrapper(HSQUIRRELVM vm)
-{
- SQBool arg0;
- if(SQ_FAILED(sq_getbool(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not a bool"));
- return SQ_ERROR;
- }
-
- try {
- Scripting::debug_draw_solids_only(arg0 == SQTrue);
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'debug_draw_solids_only'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger play_music_wrapper(HSQUIRRELVM vm)
-{
- const SQChar* arg0;
- if(SQ_FAILED(sq_getstring(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not a string"));
- return SQ_ERROR;
- }
-
- try {
- Scripting::play_music(arg0);
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'play_music'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger play_sound_wrapper(HSQUIRRELVM vm)
-{
- const SQChar* arg0;
- if(SQ_FAILED(sq_getstring(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not a string"));
- return SQ_ERROR;
- }
-
- try {
- Scripting::play_sound(arg0);
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'play_sound'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger grease_wrapper(HSQUIRRELVM vm)
-{
- (void) vm;
-
- try {
- Scripting::grease();
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'grease'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger invincible_wrapper(HSQUIRRELVM vm)
-{
- (void) vm;
-
- try {
- Scripting::invincible();
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'invincible'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger ghost_wrapper(HSQUIRRELVM vm)
-{
- (void) vm;
-
- try {
- Scripting::ghost();
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'ghost'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger mortal_wrapper(HSQUIRRELVM vm)
-{
- (void) vm;
-
- try {
- Scripting::mortal();
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'mortal'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger restart_wrapper(HSQUIRRELVM vm)
-{
- (void) vm;
-
- try {
- Scripting::restart();
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'restart'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger whereami_wrapper(HSQUIRRELVM vm)
-{
- (void) vm;
-
- try {
- Scripting::whereami();
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'whereami'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger gotoend_wrapper(HSQUIRRELVM vm)
-{
- (void) vm;
-
- try {
- Scripting::gotoend();
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'gotoend'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger camera_wrapper(HSQUIRRELVM vm)
-{
- (void) vm;
-
- try {
- Scripting::camera();
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'camera'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger quit_wrapper(HSQUIRRELVM vm)
-{
- (void) vm;
-
- try {
- Scripting::quit();
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'quit'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger rand_wrapper(HSQUIRRELVM vm)
-{
-
- try {
- int return_value = Scripting::rand();
-
- sq_pushinteger(vm, return_value);
- return 1;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'rand'"));
- return SQ_ERROR;
- }
-
-}
-
-} // end of namespace Wrapper
-void create_squirrel_instance(HSQUIRRELVM v, Scripting::DisplayEffect* object, bool setup_releasehook)
-{
- using namespace Wrapper;
-
- sq_pushroottable(v);
- sq_pushstring(v, "DisplayEffect", -1);
- if(SQ_FAILED(sq_get(v, -2))) {
- std::ostringstream msg;
- msg << "Couldn't resolved squirrel type 'DisplayEffect'";
- throw SquirrelError(v, msg.str());
- }
-
- if(SQ_FAILED(sq_createinstance(v, -1)) || SQ_FAILED(sq_setinstanceup(v, -1, object))) {
- std::ostringstream msg;
- msg << "Couldn't setup squirrel instance for object of type 'DisplayEffect'";
- throw SquirrelError(v, msg.str());
- }
- sq_remove(v, -2); // remove object name
-
- if(setup_releasehook) {
- sq_setreleasehook(v, -1, DisplayEffect_release_hook);
- }
-
- sq_remove(v, -2); // remove root table
-}
-
-void create_squirrel_instance(HSQUIRRELVM v, Scripting::Camera* object, bool setup_releasehook)
-{
- using namespace Wrapper;
-
- sq_pushroottable(v);
- sq_pushstring(v, "Camera", -1);
- if(SQ_FAILED(sq_get(v, -2))) {
- std::ostringstream msg;
- msg << "Couldn't resolved squirrel type 'Camera'";
- throw SquirrelError(v, msg.str());
- }
-
- if(SQ_FAILED(sq_createinstance(v, -1)) || SQ_FAILED(sq_setinstanceup(v, -1, object))) {
- std::ostringstream msg;
- msg << "Couldn't setup squirrel instance for object of type 'Camera'";
- throw SquirrelError(v, msg.str());
- }
- sq_remove(v, -2); // remove object name
-
- if(setup_releasehook) {
- sq_setreleasehook(v, -1, Camera_release_hook);
- }
-
- sq_remove(v, -2); // remove root table
-}
-
-void create_squirrel_instance(HSQUIRRELVM v, Scripting::Level* object, bool setup_releasehook)
-{
- using namespace Wrapper;
-
- sq_pushroottable(v);
- sq_pushstring(v, "Level", -1);
- if(SQ_FAILED(sq_get(v, -2))) {
- std::ostringstream msg;
- msg << "Couldn't resolved squirrel type 'Level'";
- throw SquirrelError(v, msg.str());
- }
-
- if(SQ_FAILED(sq_createinstance(v, -1)) || SQ_FAILED(sq_setinstanceup(v, -1, object))) {
- std::ostringstream msg;
- msg << "Couldn't setup squirrel instance for object of type 'Level'";
- throw SquirrelError(v, msg.str());
- }
- sq_remove(v, -2); // remove object name
-
- if(setup_releasehook) {
- sq_setreleasehook(v, -1, Level_release_hook);
- }
-
- sq_remove(v, -2); // remove root table
-}
-
-void create_squirrel_instance(HSQUIRRELVM v, Scripting::ScriptedObject* object, bool setup_releasehook)
-{
- using namespace Wrapper;
-
- sq_pushroottable(v);
- sq_pushstring(v, "ScriptedObject", -1);
- if(SQ_FAILED(sq_get(v, -2))) {
- std::ostringstream msg;
- msg << "Couldn't resolved squirrel type 'ScriptedObject'";
- throw SquirrelError(v, msg.str());
- }
-
- if(SQ_FAILED(sq_createinstance(v, -1)) || SQ_FAILED(sq_setinstanceup(v, -1, object))) {
- std::ostringstream msg;
- msg << "Couldn't setup squirrel instance for object of type 'ScriptedObject'";
- throw SquirrelError(v, msg.str());
- }
- sq_remove(v, -2); // remove object name
-
- if(setup_releasehook) {
- sq_setreleasehook(v, -1, ScriptedObject_release_hook);
- }
-
- sq_remove(v, -2); // remove root table
-}
-
-void create_squirrel_instance(HSQUIRRELVM v, Scripting::Text* object, bool setup_releasehook)
-{
- using namespace Wrapper;
-
- sq_pushroottable(v);
- sq_pushstring(v, "Text", -1);
- if(SQ_FAILED(sq_get(v, -2))) {
- std::ostringstream msg;
- msg << "Couldn't resolved squirrel type 'Text'";
- throw SquirrelError(v, msg.str());
- }
-
- if(SQ_FAILED(sq_createinstance(v, -1)) || SQ_FAILED(sq_setinstanceup(v, -1, object))) {
- std::ostringstream msg;
- msg << "Couldn't setup squirrel instance for object of type 'Text'";
- throw SquirrelError(v, msg.str());
- }
- sq_remove(v, -2); // remove object name
-
- if(setup_releasehook) {
- sq_setreleasehook(v, -1, Text_release_hook);
- }
-
- sq_remove(v, -2); // remove root table
-}
-
-void create_squirrel_instance(HSQUIRRELVM v, Scripting::Player* object, bool setup_releasehook)
-{
- using namespace Wrapper;
-
- sq_pushroottable(v);
- sq_pushstring(v, "Player", -1);
- if(SQ_FAILED(sq_get(v, -2))) {
- std::ostringstream msg;
- msg << "Couldn't resolved squirrel type 'Player'";
- throw SquirrelError(v, msg.str());
- }
-
- if(SQ_FAILED(sq_createinstance(v, -1)) || SQ_FAILED(sq_setinstanceup(v, -1, object))) {
- std::ostringstream msg;
- msg << "Couldn't setup squirrel instance for object of type 'Player'";
- throw SquirrelError(v, msg.str());
- }
- sq_remove(v, -2); // remove object name
-
- if(setup_releasehook) {
- sq_setreleasehook(v, -1, Player_release_hook);
- }
-
- sq_remove(v, -2); // remove root table
-}
-
-void create_squirrel_instance(HSQUIRRELVM v, Scripting::FloatingImage* object, bool setup_releasehook)
-{
- using namespace Wrapper;
-
- sq_pushroottable(v);
- sq_pushstring(v, "FloatingImage", -1);
- if(SQ_FAILED(sq_get(v, -2))) {
- std::ostringstream msg;
- msg << "Couldn't resolved squirrel type 'FloatingImage'";
- throw SquirrelError(v, msg.str());
- }
-
- if(SQ_FAILED(sq_createinstance(v, -1)) || SQ_FAILED(sq_setinstanceup(v, -1, object))) {
- std::ostringstream msg;
- msg << "Couldn't setup squirrel instance for object of type 'FloatingImage'";
- throw SquirrelError(v, msg.str());
- }
- sq_remove(v, -2); // remove object name
-
- if(setup_releasehook) {
- sq_setreleasehook(v, -1, FloatingImage_release_hook);
- }
-
- sq_remove(v, -2); // remove root table
-}
-
-void create_squirrel_instance(HSQUIRRELVM v, Scripting::Platform* object, bool setup_releasehook)
-{
- using namespace Wrapper;
-
- sq_pushroottable(v);
- sq_pushstring(v, "Platform", -1);
- if(SQ_FAILED(sq_get(v, -2))) {
- std::ostringstream msg;
- msg << "Couldn't resolved squirrel type 'Platform'";
- throw SquirrelError(v, msg.str());
- }
-
- if(SQ_FAILED(sq_createinstance(v, -1)) || SQ_FAILED(sq_setinstanceup(v, -1, object))) {
- std::ostringstream msg;
- msg << "Couldn't setup squirrel instance for object of type 'Platform'";
- throw SquirrelError(v, msg.str());
- }
- sq_remove(v, -2); // remove object name
-
- if(setup_releasehook) {
- sq_setreleasehook(v, -1, Platform_release_hook);
- }
-
- sq_remove(v, -2); // remove root table
-}
-
-void create_squirrel_instance(HSQUIRRELVM v, Scripting::Candle* object, bool setup_releasehook)
-{
- using namespace Wrapper;
-
- sq_pushroottable(v);
- sq_pushstring(v, "Candle", -1);
- if(SQ_FAILED(sq_get(v, -2))) {
- std::ostringstream msg;
- msg << "Couldn't resolved squirrel type 'Candle'";
- throw SquirrelError(v, msg.str());
- }
-
- if(SQ_FAILED(sq_createinstance(v, -1)) || SQ_FAILED(sq_setinstanceup(v, -1, object))) {
- std::ostringstream msg;
- msg << "Couldn't setup squirrel instance for object of type 'Candle'";
- throw SquirrelError(v, msg.str());
- }
- sq_remove(v, -2); // remove object name
-
- if(setup_releasehook) {
- sq_setreleasehook(v, -1, Candle_release_hook);
- }
-
- sq_remove(v, -2); // remove root table
-}
-
-void create_squirrel_instance(HSQUIRRELVM v, Scripting::Wind* object, bool setup_releasehook)
-{
- using namespace Wrapper;
-
- sq_pushroottable(v);
- sq_pushstring(v, "Wind", -1);
- if(SQ_FAILED(sq_get(v, -2))) {
- std::ostringstream msg;
- msg << "Couldn't resolved squirrel type 'Wind'";
- throw SquirrelError(v, msg.str());
- }
-
- if(SQ_FAILED(sq_createinstance(v, -1)) || SQ_FAILED(sq_setinstanceup(v, -1, object))) {
- std::ostringstream msg;
- msg << "Couldn't setup squirrel instance for object of type 'Wind'";
- throw SquirrelError(v, msg.str());
- }
- sq_remove(v, -2); // remove object name
-
- if(setup_releasehook) {
- sq_setreleasehook(v, -1, Wind_release_hook);
- }
-
- sq_remove(v, -2); // remove root table
-}
-
-void create_squirrel_instance(HSQUIRRELVM v, Scripting::AmbientSound* object, bool setup_releasehook)
-{
- using namespace Wrapper;
-
- sq_pushroottable(v);
- sq_pushstring(v, "AmbientSound", -1);
- if(SQ_FAILED(sq_get(v, -2))) {
- std::ostringstream msg;
- msg << "Couldn't resolved squirrel type 'AmbientSound'";
- throw SquirrelError(v, msg.str());
- }
-
- if(SQ_FAILED(sq_createinstance(v, -1)) || SQ_FAILED(sq_setinstanceup(v, -1, object))) {
- std::ostringstream msg;
- msg << "Couldn't setup squirrel instance for object of type 'AmbientSound'";
- throw SquirrelError(v, msg.str());
- }
- sq_remove(v, -2); // remove object name
-
- if(setup_releasehook) {
- sq_setreleasehook(v, -1, AmbientSound_release_hook);
- }
-
- sq_remove(v, -2); // remove root table
-}
-
-void create_squirrel_instance(HSQUIRRELVM v, Scripting::Thunderstorm* object, bool setup_releasehook)
-{
- using namespace Wrapper;
-
- sq_pushroottable(v);
- sq_pushstring(v, "Thunderstorm", -1);
- if(SQ_FAILED(sq_get(v, -2))) {
- std::ostringstream msg;
- msg << "Couldn't resolved squirrel type 'Thunderstorm'";
- throw SquirrelError(v, msg.str());
- }
-
- if(SQ_FAILED(sq_createinstance(v, -1)) || SQ_FAILED(sq_setinstanceup(v, -1, object))) {
- std::ostringstream msg;
- msg << "Couldn't setup squirrel instance for object of type 'Thunderstorm'";
- throw SquirrelError(v, msg.str());
- }
- sq_remove(v, -2); // remove object name
-
- if(setup_releasehook) {
- sq_setreleasehook(v, -1, Thunderstorm_release_hook);
- }
-
- sq_remove(v, -2); // remove root table
-}
-
-void create_squirrel_instance(HSQUIRRELVM v, Scripting::TileMap* object, bool setup_releasehook)
-{
- using namespace Wrapper;
-
- sq_pushroottable(v);
- sq_pushstring(v, "TileMap", -1);
- if(SQ_FAILED(sq_get(v, -2))) {
- std::ostringstream msg;
- msg << "Couldn't resolved squirrel type 'TileMap'";
- throw SquirrelError(v, msg.str());
- }
-
- if(SQ_FAILED(sq_createinstance(v, -1)) || SQ_FAILED(sq_setinstanceup(v, -1, object))) {
- std::ostringstream msg;
- msg << "Couldn't setup squirrel instance for object of type 'TileMap'";
- throw SquirrelError(v, msg.str());
- }
- sq_remove(v, -2); // remove object name
-
- if(setup_releasehook) {
- sq_setreleasehook(v, -1, TileMap_release_hook);
- }
-
- sq_remove(v, -2); // remove root table
-}
-
-void create_squirrel_instance(HSQUIRRELVM v, Scripting::SSector* object, bool setup_releasehook)
-{
- using namespace Wrapper;
-
- sq_pushroottable(v);
- sq_pushstring(v, "SSector", -1);
- if(SQ_FAILED(sq_get(v, -2))) {
- std::ostringstream msg;
- msg << "Couldn't resolved squirrel type 'SSector'";
- throw SquirrelError(v, msg.str());
- }
-
- if(SQ_FAILED(sq_createinstance(v, -1)) || SQ_FAILED(sq_setinstanceup(v, -1, object))) {
- std::ostringstream msg;
- msg << "Couldn't setup squirrel instance for object of type 'SSector'";
- throw SquirrelError(v, msg.str());
- }
- sq_remove(v, -2); // remove object name
-
- if(setup_releasehook) {
- sq_setreleasehook(v, -1, SSector_release_hook);
- }
-
- sq_remove(v, -2); // remove root table
-}
-
-void create_squirrel_instance(HSQUIRRELVM v, Scripting::LevelTime* object, bool setup_releasehook)
-{
- using namespace Wrapper;
-
- sq_pushroottable(v);
- sq_pushstring(v, "LevelTime", -1);
- if(SQ_FAILED(sq_get(v, -2))) {
- std::ostringstream msg;
- msg << "Couldn't resolved squirrel type 'LevelTime'";
- throw SquirrelError(v, msg.str());
- }
-
- if(SQ_FAILED(sq_createinstance(v, -1)) || SQ_FAILED(sq_setinstanceup(v, -1, object))) {
- std::ostringstream msg;
- msg << "Couldn't setup squirrel instance for object of type 'LevelTime'";
- throw SquirrelError(v, msg.str());
- }
- sq_remove(v, -2); // remove object name
-
- if(setup_releasehook) {
- sq_setreleasehook(v, -1, LevelTime_release_hook);
- }
-
- sq_remove(v, -2); // remove root table
-}
-
-void create_squirrel_instance(HSQUIRRELVM v, Scripting::WillOWisp* object, bool setup_releasehook)
-{
- using namespace Wrapper;
-
- sq_pushroottable(v);
- sq_pushstring(v, "WillOWisp", -1);
- if(SQ_FAILED(sq_get(v, -2))) {
- std::ostringstream msg;
- msg << "Couldn't resolved squirrel type 'WillOWisp'";
- throw SquirrelError(v, msg.str());
- }
-
- if(SQ_FAILED(sq_createinstance(v, -1)) || SQ_FAILED(sq_setinstanceup(v, -1, object))) {
- std::ostringstream msg;
- msg << "Couldn't setup squirrel instance for object of type 'WillOWisp'";
- throw SquirrelError(v, msg.str());
- }
- sq_remove(v, -2); // remove object name
-
- if(setup_releasehook) {
- sq_setreleasehook(v, -1, WillOWisp_release_hook);
- }
-
- sq_remove(v, -2); // remove root table
-}
-
-void register_supertux_wrapper(HSQUIRRELVM v)
-{
- using namespace Wrapper;
-
- sq_pushstring(v, "ANCHOR_TOP", -1);
- sq_pushinteger(v, 16);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register constant 'ANCHOR_TOP'");
- }
-
- sq_pushstring(v, "ANCHOR_BOTTOM", -1);
- sq_pushinteger(v, 32);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register constant 'ANCHOR_BOTTOM'");
- }
-
- sq_pushstring(v, "ANCHOR_LEFT", -1);
- sq_pushinteger(v, 1);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register constant 'ANCHOR_LEFT'");
- }
-
- sq_pushstring(v, "ANCHOR_RIGHT", -1);
- sq_pushinteger(v, 2);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register constant 'ANCHOR_RIGHT'");
- }
-
- sq_pushstring(v, "ANCHOR_MIDDLE", -1);
- sq_pushinteger(v, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register constant 'ANCHOR_MIDDLE'");
- }
-
- sq_pushstring(v, "ANCHOR_TOP_LEFT", -1);
- sq_pushinteger(v, 17);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register constant 'ANCHOR_TOP_LEFT'");
- }
-
- sq_pushstring(v, "ANCHOR_TOP_RIGHT", -1);
- sq_pushinteger(v, 18);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register constant 'ANCHOR_TOP_RIGHT'");
- }
-
- sq_pushstring(v, "ANCHOR_BOTTOM_LEFT", -1);
- sq_pushinteger(v, 33);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register constant 'ANCHOR_BOTTOM_LEFT'");
- }
-
- sq_pushstring(v, "ANCHOR_BOTTOM_RIGHT", -1);
- sq_pushinteger(v, 34);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register constant 'ANCHOR_BOTTOM_RIGHT'");
- }
-
- sq_pushstring(v, "display", -1);
- sq_newclosure(v, &display_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'display'");
- }
-
- sq_pushstring(v, "print_stacktrace", -1);
- sq_newclosure(v, &print_stacktrace_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'print_stacktrace'");
- }
-
- sq_pushstring(v, "get_current_thread", -1);
- sq_newclosure(v, &get_current_thread_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'get_current_thread'");
- }
-
- sq_pushstring(v, "display_text_file", -1);
- sq_newclosure(v, &display_text_file_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'display_text_file'");
- }
-
- sq_pushstring(v, "load_worldmap", -1);
- sq_newclosure(v, &load_worldmap_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'load_worldmap'");
- }
-
- sq_pushstring(v, "load_level", -1);
- sq_newclosure(v, &load_level_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'load_level'");
- }
-
- sq_pushstring(v, "wait", -1);
- sq_newclosure(v, &wait_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'wait'");
- }
-
- sq_pushstring(v, "wait_for_screenswitch", -1);
- sq_newclosure(v, &wait_for_screenswitch_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'wait_for_screenswitch'");
- }
-
- sq_pushstring(v, "exit_screen", -1);
- sq_newclosure(v, &exit_screen_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'exit_screen'");
- }
-
- sq_pushstring(v, "fadeout_screen", -1);
- sq_newclosure(v, &fadeout_screen_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'fadeout_screen'");
- }
-
- sq_pushstring(v, "shrink_screen", -1);
- sq_newclosure(v, &shrink_screen_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'shrink_screen'");
- }
-
- sq_pushstring(v, "abort_screenfade", -1);
- sq_newclosure(v, &abort_screenfade_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'abort_screenfade'");
- }
-
- sq_pushstring(v, "translate", -1);
- sq_newclosure(v, &translate_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'translate'");
- }
-
- sq_pushstring(v, "import", -1);
- sq_newclosure(v, &import_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'import'");
- }
-
- sq_pushstring(v, "save_state", -1);
- sq_newclosure(v, &save_state_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'save_state'");
- }
-
- sq_pushstring(v, "update_worldmap", -1);
- sq_newclosure(v, &update_worldmap_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'update_worldmap'");
- }
-
- sq_pushstring(v, "debug_collrects", -1);
- sq_newclosure(v, &debug_collrects_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'debug_collrects'");
- }
-
- sq_pushstring(v, "debug_show_fps", -1);
- sq_newclosure(v, &debug_show_fps_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'debug_show_fps'");
- }
-
- sq_pushstring(v, "debug_draw_solids_only", -1);
- sq_newclosure(v, &debug_draw_solids_only_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'debug_draw_solids_only'");
- }
-
- sq_pushstring(v, "play_music", -1);
- sq_newclosure(v, &play_music_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'play_music'");
- }
-
- sq_pushstring(v, "play_sound", -1);
- sq_newclosure(v, &play_sound_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'play_sound'");
- }
-
- sq_pushstring(v, "grease", -1);
- sq_newclosure(v, &grease_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'grease'");
- }
-
- sq_pushstring(v, "invincible", -1);
- sq_newclosure(v, &invincible_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'invincible'");
- }
-
- sq_pushstring(v, "ghost", -1);
- sq_newclosure(v, &ghost_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'ghost'");
- }
-
- sq_pushstring(v, "mortal", -1);
- sq_newclosure(v, &mortal_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'mortal'");
- }
-
- sq_pushstring(v, "restart", -1);
- sq_newclosure(v, &restart_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'restart'");
- }
-
- sq_pushstring(v, "whereami", -1);
- sq_newclosure(v, &whereami_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'whereami'");
- }
-
- sq_pushstring(v, "gotoend", -1);
- sq_newclosure(v, &gotoend_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'gotoend'");
- }
-
- sq_pushstring(v, "camera", -1);
- sq_newclosure(v, &camera_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'camera'");
- }
-
- sq_pushstring(v, "quit", -1);
- sq_newclosure(v, &quit_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'quit'");
- }
-
- sq_pushstring(v, "rand", -1);
- sq_newclosure(v, &rand_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'rand'");
- }
-
- // Register class DisplayEffect
- sq_pushstring(v, "DisplayEffect", -1);
- if(sq_newclass(v, SQFalse) < 0) {
- std::ostringstream msg;
- msg << "Couldn't create new class 'DisplayEffect'";
- throw SquirrelError(v, msg.str());
- }
- sq_pushstring(v, "fade_out", -1);
- sq_newclosure(v, &DisplayEffect_fade_out_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'fade_out'");
- }
-
- sq_pushstring(v, "fade_in", -1);
- sq_newclosure(v, &DisplayEffect_fade_in_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'fade_in'");
- }
-
- sq_pushstring(v, "set_black", -1);
- sq_newclosure(v, &DisplayEffect_set_black_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'set_black'");
- }
-
- sq_pushstring(v, "is_black", -1);
- sq_newclosure(v, &DisplayEffect_is_black_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'is_black'");
- }
-
- sq_pushstring(v, "sixteen_to_nine", -1);
- sq_newclosure(v, &DisplayEffect_sixteen_to_nine_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'sixteen_to_nine'");
- }
-
- sq_pushstring(v, "four_to_three", -1);
- sq_newclosure(v, &DisplayEffect_four_to_three_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'four_to_three'");
- }
-
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register class 'DisplayEffect'");
- }
-
- // Register class Camera
- sq_pushstring(v, "Camera", -1);
- if(sq_newclass(v, SQFalse) < 0) {
- std::ostringstream msg;
- msg << "Couldn't create new class 'Camera'";
- throw SquirrelError(v, msg.str());
- }
- sq_pushstring(v, "reload_config", -1);
- sq_newclosure(v, &Camera_reload_config_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'reload_config'");
- }
-
- sq_pushstring(v, "shake", -1);
- sq_newclosure(v, &Camera_shake_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'shake'");
- }
-
- sq_pushstring(v, "set_pos", -1);
- sq_newclosure(v, &Camera_set_pos_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'set_pos'");
- }
-
- sq_pushstring(v, "set_mode", -1);
- sq_newclosure(v, &Camera_set_mode_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'set_mode'");
- }
-
- sq_pushstring(v, "scroll_to", -1);
- sq_newclosure(v, &Camera_scroll_to_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'scroll_to'");
- }
-
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register class 'Camera'");
- }
-
- // Register class Level
- sq_pushstring(v, "Level", -1);
- if(sq_newclass(v, SQFalse) < 0) {
- std::ostringstream msg;
- msg << "Couldn't create new class 'Level'";
- throw SquirrelError(v, msg.str());
- }
- sq_pushstring(v, "finish", -1);
- sq_newclosure(v, &Level_finish_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'finish'");
- }
-
- sq_pushstring(v, "spawn", -1);
- sq_newclosure(v, &Level_spawn_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'spawn'");
- }
-
- sq_pushstring(v, "flip_vertically", -1);
- sq_newclosure(v, &Level_flip_vertically_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'flip_vertically'");
- }
-
- sq_pushstring(v, "toggle_pause", -1);
- sq_newclosure(v, &Level_toggle_pause_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'toggle_pause'");
- }
-
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register class 'Level'");
- }
-
- // Register class ScriptedObject
- sq_pushstring(v, "ScriptedObject", -1);
- if(sq_newclass(v, SQFalse) < 0) {
- std::ostringstream msg;
- msg << "Couldn't create new class 'ScriptedObject'";
- throw SquirrelError(v, msg.str());
- }
- sq_pushstring(v, "set_action", -1);
- sq_newclosure(v, &ScriptedObject_set_action_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'set_action'");
- }
-
- sq_pushstring(v, "get_action", -1);
- sq_newclosure(v, &ScriptedObject_get_action_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'get_action'");
- }
-
- sq_pushstring(v, "move", -1);
- sq_newclosure(v, &ScriptedObject_move_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'move'");
- }
-
- sq_pushstring(v, "set_pos", -1);
- sq_newclosure(v, &ScriptedObject_set_pos_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'set_pos'");
- }
-
- sq_pushstring(v, "get_pos_x", -1);
- sq_newclosure(v, &ScriptedObject_get_pos_x_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'get_pos_x'");
- }
-
- sq_pushstring(v, "get_pos_y", -1);
- sq_newclosure(v, &ScriptedObject_get_pos_y_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'get_pos_y'");
- }
-
- sq_pushstring(v, "set_velocity", -1);
- sq_newclosure(v, &ScriptedObject_set_velocity_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'set_velocity'");
- }
-
- sq_pushstring(v, "get_velocity_x", -1);
- sq_newclosure(v, &ScriptedObject_get_velocity_x_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'get_velocity_x'");
- }
-
- sq_pushstring(v, "get_velocity_y", -1);
- sq_newclosure(v, &ScriptedObject_get_velocity_y_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'get_velocity_y'");
- }
-
- sq_pushstring(v, "set_visible", -1);
- sq_newclosure(v, &ScriptedObject_set_visible_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'set_visible'");
- }
-
- sq_pushstring(v, "is_visible", -1);
- sq_newclosure(v, &ScriptedObject_is_visible_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'is_visible'");
- }
-
- sq_pushstring(v, "set_solid", -1);
- sq_newclosure(v, &ScriptedObject_set_solid_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'set_solid'");
- }
-
- sq_pushstring(v, "is_solid", -1);
- sq_newclosure(v, &ScriptedObject_is_solid_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'is_solid'");
- }
-
- sq_pushstring(v, "get_name", -1);
- sq_newclosure(v, &ScriptedObject_get_name_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'get_name'");
- }
-
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register class 'ScriptedObject'");
- }
-
- // Register class Text
- sq_pushstring(v, "Text", -1);
- if(sq_newclass(v, SQFalse) < 0) {
- std::ostringstream msg;
- msg << "Couldn't create new class 'Text'";
- throw SquirrelError(v, msg.str());
- }
- sq_pushstring(v, "set_text", -1);
- sq_newclosure(v, &Text_set_text_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'set_text'");
- }
-
- sq_pushstring(v, "set_font", -1);
- sq_newclosure(v, &Text_set_font_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'set_font'");
- }
-
- sq_pushstring(v, "fade_in", -1);
- sq_newclosure(v, &Text_fade_in_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'fade_in'");
- }
-
- sq_pushstring(v, "fade_out", -1);
- sq_newclosure(v, &Text_fade_out_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'fade_out'");
- }
-
- sq_pushstring(v, "set_visible", -1);
- sq_newclosure(v, &Text_set_visible_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'set_visible'");
- }
-
- sq_pushstring(v, "set_centered", -1);
- sq_newclosure(v, &Text_set_centered_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'set_centered'");
- }
-
- sq_pushstring(v, "set_pos", -1);
- sq_newclosure(v, &Text_set_pos_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'set_pos'");
- }
-
- sq_pushstring(v, "get_pos_x", -1);
- sq_newclosure(v, &Text_get_pos_x_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'get_pos_x'");
- }
-
- sq_pushstring(v, "get_pos_y", -1);
- sq_newclosure(v, &Text_get_pos_y_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'get_pos_y'");
- }
-
- sq_pushstring(v, "set_anchor_point", -1);
- sq_newclosure(v, &Text_set_anchor_point_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'set_anchor_point'");
- }
-
- sq_pushstring(v, "get_anchor_point", -1);
- sq_newclosure(v, &Text_get_anchor_point_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'get_anchor_point'");
- }
-
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register class 'Text'");
- }
-
- // Register class Player
- sq_pushstring(v, "Player", -1);
- if(sq_newclass(v, SQFalse) < 0) {
- std::ostringstream msg;
- msg << "Couldn't create new class 'Player'";
- throw SquirrelError(v, msg.str());
- }
- sq_pushstring(v, "add_bonus", -1);
- sq_newclosure(v, &Player_add_bonus_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'add_bonus'");
- }
-
- sq_pushstring(v, "add_coins", -1);
- sq_newclosure(v, &Player_add_coins_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'add_coins'");
- }
-
- sq_pushstring(v, "make_invincible", -1);
- sq_newclosure(v, &Player_make_invincible_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'make_invincible'");
- }
-
- sq_pushstring(v, "deactivate", -1);
- sq_newclosure(v, &Player_deactivate_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'deactivate'");
- }
-
- sq_pushstring(v, "activate", -1);
- sq_newclosure(v, &Player_activate_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'activate'");
- }
-
- sq_pushstring(v, "walk", -1);
- sq_newclosure(v, &Player_walk_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'walk'");
- }
-
- sq_pushstring(v, "set_visible", -1);
- sq_newclosure(v, &Player_set_visible_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'set_visible'");
- }
-
- sq_pushstring(v, "get_visible", -1);
- sq_newclosure(v, &Player_get_visible_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'get_visible'");
- }
-
- sq_pushstring(v, "kill", -1);
- sq_newclosure(v, &Player_kill_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'kill'");
- }
-
- sq_pushstring(v, "set_ghost_mode", -1);
- sq_newclosure(v, &Player_set_ghost_mode_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'set_ghost_mode'");
- }
-
- sq_pushstring(v, "get_ghost_mode", -1);
- sq_newclosure(v, &Player_get_ghost_mode_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'get_ghost_mode'");
- }
-
- sq_pushstring(v, "do_cheer", -1);
- sq_newclosure(v, &Player_do_cheer_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'do_cheer'");
- }
-
- sq_pushstring(v, "do_duck", -1);
- sq_newclosure(v, &Player_do_duck_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'do_duck'");
- }
-
- sq_pushstring(v, "do_standup", -1);
- sq_newclosure(v, &Player_do_standup_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'do_standup'");
- }
-
- sq_pushstring(v, "do_backflip", -1);
- sq_newclosure(v, &Player_do_backflip_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'do_backflip'");
- }
-
- sq_pushstring(v, "do_jump", -1);
- sq_newclosure(v, &Player_do_jump_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'do_jump'");
- }
-
- sq_pushstring(v, "trigger_sequence", -1);
- sq_newclosure(v, &Player_trigger_sequence_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'trigger_sequence'");
- }
-
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register class 'Player'");
- }
-
- // Register class FloatingImage
- sq_pushstring(v, "FloatingImage", -1);
- if(sq_newclass(v, SQFalse) < 0) {
- std::ostringstream msg;
- msg << "Couldn't create new class 'FloatingImage'";
- throw SquirrelError(v, msg.str());
- }
- sq_pushstring(v, "constructor", -1);
- sq_newclosure(v, &FloatingImage_constructor_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'constructor'");
- }
-
- sq_pushstring(v, "set_layer", -1);
- sq_newclosure(v, &FloatingImage_set_layer_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'set_layer'");
- }
-
- sq_pushstring(v, "get_layer", -1);
- sq_newclosure(v, &FloatingImage_get_layer_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'get_layer'");
- }
-
- sq_pushstring(v, "set_pos", -1);
- sq_newclosure(v, &FloatingImage_set_pos_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'set_pos'");
- }
-
- sq_pushstring(v, "get_pos_x", -1);
- sq_newclosure(v, &FloatingImage_get_pos_x_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'get_pos_x'");
- }
-
- sq_pushstring(v, "get_pos_y", -1);
- sq_newclosure(v, &FloatingImage_get_pos_y_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'get_pos_y'");
- }
-
- sq_pushstring(v, "set_anchor_point", -1);
- sq_newclosure(v, &FloatingImage_set_anchor_point_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'set_anchor_point'");
- }
-
- sq_pushstring(v, "get_anchor_point", -1);
- sq_newclosure(v, &FloatingImage_get_anchor_point_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'get_anchor_point'");
- }
-
- sq_pushstring(v, "set_visible", -1);
- sq_newclosure(v, &FloatingImage_set_visible_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'set_visible'");
- }
-
- sq_pushstring(v, "get_visible", -1);
- sq_newclosure(v, &FloatingImage_get_visible_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'get_visible'");
- }
-
- sq_pushstring(v, "set_action", -1);
- sq_newclosure(v, &FloatingImage_set_action_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'set_action'");
- }
-
- sq_pushstring(v, "get_action", -1);
- sq_newclosure(v, &FloatingImage_get_action_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'get_action'");
- }
-
- sq_pushstring(v, "fade_in", -1);
- sq_newclosure(v, &FloatingImage_fade_in_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'fade_in'");
- }
-
- sq_pushstring(v, "fade_out", -1);
- sq_newclosure(v, &FloatingImage_fade_out_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'fade_out'");
- }
-
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register class 'FloatingImage'");
- }
-
- // Register class Platform
- sq_pushstring(v, "Platform", -1);
- if(sq_newclass(v, SQFalse) < 0) {
- std::ostringstream msg;
- msg << "Couldn't create new class 'Platform'";
- throw SquirrelError(v, msg.str());
- }
- sq_pushstring(v, "goto_node", -1);
- sq_newclosure(v, &Platform_goto_node_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'goto_node'");
- }
-
- sq_pushstring(v, "start_moving", -1);
- sq_newclosure(v, &Platform_start_moving_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'start_moving'");
- }
-
- sq_pushstring(v, "stop_moving", -1);
- sq_newclosure(v, &Platform_stop_moving_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'stop_moving'");
- }
-
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register class 'Platform'");
- }
-
- // Register class Candle
- sq_pushstring(v, "Candle", -1);
- if(sq_newclass(v, SQFalse) < 0) {
- std::ostringstream msg;
- msg << "Couldn't create new class 'Candle'";
- throw SquirrelError(v, msg.str());
- }
- sq_pushstring(v, "get_burning", -1);
- sq_newclosure(v, &Candle_get_burning_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'get_burning'");
- }
-
- sq_pushstring(v, "set_burning", -1);
- sq_newclosure(v, &Candle_set_burning_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'set_burning'");
- }
-
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register class 'Candle'");
- }
-
- // Register class Wind
- sq_pushstring(v, "Wind", -1);
- if(sq_newclass(v, SQFalse) < 0) {
- std::ostringstream msg;
- msg << "Couldn't create new class 'Wind'";
- throw SquirrelError(v, msg.str());
- }
- sq_pushstring(v, "start", -1);
- sq_newclosure(v, &Wind_start_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'start'");
- }
-
- sq_pushstring(v, "stop", -1);
- sq_newclosure(v, &Wind_stop_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'stop'");
- }
-
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register class 'Wind'");
- }
-
- // Register class AmbientSound
- sq_pushstring(v, "AmbientSound", -1);
- if(sq_newclass(v, SQFalse) < 0) {
- std::ostringstream msg;
- msg << "Couldn't create new class 'AmbientSound'";
- throw SquirrelError(v, msg.str());
- }
- sq_pushstring(v, "set_pos", -1);
- sq_newclosure(v, &AmbientSound_set_pos_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'set_pos'");
- }
-
- sq_pushstring(v, "get_pos_x", -1);
- sq_newclosure(v, &AmbientSound_get_pos_x_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'get_pos_x'");
- }
-
- sq_pushstring(v, "get_pos_y", -1);
- sq_newclosure(v, &AmbientSound_get_pos_y_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'get_pos_y'");
- }
-
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register class 'AmbientSound'");
- }
-
- // Register class Thunderstorm
- sq_pushstring(v, "Thunderstorm", -1);
- if(sq_newclass(v, SQFalse) < 0) {
- std::ostringstream msg;
- msg << "Couldn't create new class 'Thunderstorm'";
- throw SquirrelError(v, msg.str());
- }
- sq_pushstring(v, "start", -1);
- sq_newclosure(v, &Thunderstorm_start_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'start'");
- }
-
- sq_pushstring(v, "stop", -1);
- sq_newclosure(v, &Thunderstorm_stop_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'stop'");
- }
-
- sq_pushstring(v, "thunder", -1);
- sq_newclosure(v, &Thunderstorm_thunder_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'thunder'");
- }
-
- sq_pushstring(v, "lightning", -1);
- sq_newclosure(v, &Thunderstorm_lightning_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'lightning'");
- }
-
- sq_pushstring(v, "flash", -1);
- sq_newclosure(v, &Thunderstorm_flash_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'flash'");
- }
-
- sq_pushstring(v, "electrify", -1);
- sq_newclosure(v, &Thunderstorm_electrify_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'electrify'");
- }
-
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register class 'Thunderstorm'");
- }
-
- // Register class TileMap
- sq_pushstring(v, "TileMap", -1);
- if(sq_newclass(v, SQFalse) < 0) {
- std::ostringstream msg;
- msg << "Couldn't create new class 'TileMap'";
- throw SquirrelError(v, msg.str());
- }
- sq_pushstring(v, "goto_node", -1);
- sq_newclosure(v, &TileMap_goto_node_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'goto_node'");
- }
-
- sq_pushstring(v, "start_moving", -1);
- sq_newclosure(v, &TileMap_start_moving_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'start_moving'");
- }
-
- sq_pushstring(v, "stop_moving", -1);
- sq_newclosure(v, &TileMap_stop_moving_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'stop_moving'");
- }
-
- sq_pushstring(v, "fade", -1);
- sq_newclosure(v, &TileMap_fade_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'fade'");
- }
-
- sq_pushstring(v, "set_alpha", -1);
- sq_newclosure(v, &TileMap_set_alpha_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'set_alpha'");
- }
-
- sq_pushstring(v, "get_alpha", -1);
- sq_newclosure(v, &TileMap_get_alpha_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'get_alpha'");
- }
-
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register class 'TileMap'");
- }
-
- // Register class SSector
- sq_pushstring(v, "SSector", -1);
- if(sq_newclass(v, SQFalse) < 0) {
- std::ostringstream msg;
- msg << "Couldn't create new class 'SSector'";
- throw SquirrelError(v, msg.str());
- }
- sq_pushstring(v, "set_ambient_light", -1);
- sq_newclosure(v, &SSector_set_ambient_light_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'set_ambient_light'");
- }
-
- sq_pushstring(v, "get_ambient_red", -1);
- sq_newclosure(v, &SSector_get_ambient_red_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'get_ambient_red'");
- }
-
- sq_pushstring(v, "get_ambient_green", -1);
- sq_newclosure(v, &SSector_get_ambient_green_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'get_ambient_green'");
- }
-
- sq_pushstring(v, "get_ambient_blue", -1);
- sq_newclosure(v, &SSector_get_ambient_blue_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'get_ambient_blue'");
- }
-
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register class 'SSector'");
- }
-
- // Register class LevelTime
- sq_pushstring(v, "LevelTime", -1);
- if(sq_newclass(v, SQFalse) < 0) {
- std::ostringstream msg;
- msg << "Couldn't create new class 'LevelTime'";
- throw SquirrelError(v, msg.str());
- }
- sq_pushstring(v, "start", -1);
- sq_newclosure(v, &LevelTime_start_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'start'");
- }
-
- sq_pushstring(v, "stop", -1);
- sq_newclosure(v, &LevelTime_stop_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'stop'");
- }
-
- sq_pushstring(v, "get_time", -1);
- sq_newclosure(v, &LevelTime_get_time_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'get_time'");
- }
-
- sq_pushstring(v, "set_time", -1);
- sq_newclosure(v, &LevelTime_set_time_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'set_time'");
- }
-
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register class 'LevelTime'");
- }
-
- // Register class WillOWisp
- sq_pushstring(v, "WillOWisp", -1);
- if(sq_newclass(v, SQFalse) < 0) {
- std::ostringstream msg;
- msg << "Couldn't create new class 'WillOWisp'";
- throw SquirrelError(v, msg.str());
- }
- sq_pushstring(v, "goto_node", -1);
- sq_newclosure(v, &WillOWisp_goto_node_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'goto_node'");
- }
-
- sq_pushstring(v, "set_state", -1);
- sq_newclosure(v, &WillOWisp_set_state_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'set_state'");
- }
-
- sq_pushstring(v, "start_moving", -1);
- sq_newclosure(v, &WillOWisp_start_moving_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'start_moving'");
- }
-
- sq_pushstring(v, "stop_moving", -1);
- sq_newclosure(v, &WillOWisp_stop_moving_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'stop_moving'");
- }
-
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register class 'WillOWisp'");
- }
-
-}
-
-} // end of namespace Scripting
+++ /dev/null
-/**
- * WARNING: This file is automatically generated from:
- * 'src/scripting/wrapper.interface.hpp'
- * DO NOT CHANGE
- */
-#ifndef __supertux_WRAPPER_H__
-#define __supertux_WRAPPER_H__
-
-#include <squirrel.h>
-#include "wrapper.interface.hpp"
-
-namespace Scripting
-{
-
-void register_supertux_wrapper(HSQUIRRELVM v);
-
-void create_squirrel_instance(HSQUIRRELVM v, Scripting::DisplayEffect* object, bool setup_releasehook = false);
-void create_squirrel_instance(HSQUIRRELVM v, Scripting::Camera* object, bool setup_releasehook = false);
-void create_squirrel_instance(HSQUIRRELVM v, Scripting::Level* object, bool setup_releasehook = false);
-void create_squirrel_instance(HSQUIRRELVM v, Scripting::ScriptedObject* object, bool setup_releasehook = false);
-void create_squirrel_instance(HSQUIRRELVM v, Scripting::Text* object, bool setup_releasehook = false);
-void create_squirrel_instance(HSQUIRRELVM v, Scripting::Player* object, bool setup_releasehook = false);
-void create_squirrel_instance(HSQUIRRELVM v, Scripting::FloatingImage* object, bool setup_releasehook = false);
-void create_squirrel_instance(HSQUIRRELVM v, Scripting::Platform* object, bool setup_releasehook = false);
-void create_squirrel_instance(HSQUIRRELVM v, Scripting::Candle* object, bool setup_releasehook = false);
-void create_squirrel_instance(HSQUIRRELVM v, Scripting::Wind* object, bool setup_releasehook = false);
-void create_squirrel_instance(HSQUIRRELVM v, Scripting::AmbientSound* object, bool setup_releasehook = false);
-void create_squirrel_instance(HSQUIRRELVM v, Scripting::Thunderstorm* object, bool setup_releasehook = false);
-void create_squirrel_instance(HSQUIRRELVM v, Scripting::TileMap* object, bool setup_releasehook = false);
-void create_squirrel_instance(HSQUIRRELVM v, Scripting::SSector* object, bool setup_releasehook = false);
-void create_squirrel_instance(HSQUIRRELVM v, Scripting::LevelTime* object, bool setup_releasehook = false);
-void create_squirrel_instance(HSQUIRRELVM v, Scripting::WillOWisp* object, bool setup_releasehook = false);
-
-}
-
-#endif
+++ /dev/null
-/* This file is processed by miniswig to produce the scripting API */
-#include "display_effect.hpp"
-#include "camera.hpp"
-#include "level.hpp"
-#include "scripted_object.hpp"
-#include "text.hpp"
-#include "functions.hpp"
-#include "player.hpp"
-#include "floating_image.hpp"
-#include "anchor_points.hpp"
-#include "platform.hpp"
-#include "candle.hpp"
-#include "wind.hpp"
-#include "ambient_sound.hpp"
-#include "thunderstorm.hpp"
-#include "tilemap.hpp"
-#include "ssector.hpp"
-#include "level_time.hpp"
-#include "willowisp.hpp"
+++ /dev/null
-// $Id$
-//
-// SuperTux - A Jump'n Run
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#include <config.h>
-
-#include <memory>
-#include <algorithm>
-#include <stdexcept>
-#include <iostream>
-#include <fstream>
-#include <sstream>
-#include <stdexcept>
-#include <float.h>
-#include <math.h>
-#include <limits>
-//#include <physfs.h>
-#include <unison/vfs/FileSystem.hpp>
-
-#include "sector.hpp"
-#include "object/player.hpp"
-#include "object/gameobjs.hpp"
-#include "object/camera.hpp"
-#include "object/background.hpp"
-#include "object/gradient.hpp"
-#include "object/particlesystem.hpp"
-#include "object/particlesystem_interactive.hpp"
-#include "object/tilemap.hpp"
-#include "lisp/parser.hpp"
-#include "lisp/lisp.hpp"
-#include "lisp/writer.hpp"
-#include "lisp/list_iterator.hpp"
-#include "tile.hpp"
-#include "audio/sound_manager.hpp"
-#include "game_session.hpp"
-#include "resources.hpp"
-#include "statistics.hpp"
-#include "object_factory.hpp"
-#include "collision.hpp"
-#include "spawn_point.hpp"
-#include "math/rect.hpp"
-#include "math/aatriangle.hpp"
-#include "object/coin.hpp"
-#include "object/block.hpp"
-#include "object/invisible_block.hpp"
-#include "object/light.hpp"
-#include "object/pulsing_light.hpp"
-#include "object/bullet.hpp"
-#include "object/text_object.hpp"
-#include "object/portable.hpp"
-#include "badguy/jumpy.hpp"
-#include "trigger/sequence_trigger.hpp"
-#include "player_status.hpp"
-#include "scripting/squirrel_util.hpp"
-#include "script_interface.hpp"
-#include "log.hpp"
-#include "main.hpp"
-
-Sector* Sector::_current = 0;
-
-bool Sector::show_collrects = false;
-bool Sector::draw_solids_only = false;
-
-Sector::Sector(Level* parent)
- : level(parent), currentmusic(LEVEL_MUSIC),
- ambient_light( 1.0f, 1.0f, 1.0f, 1.0f ), gravity(10.0), player(0), camera(0)
-{
- add_object(new Player(player_status, "Tux"));
- add_object(new DisplayEffect("Effect"));
- add_object(new TextObject("Text"));
-
- // create a new squirrel table for the sector
- using namespace Scripting;
-
- sq_collectgarbage(global_vm);
-
- sq_newtable(global_vm);
- sq_pushroottable(global_vm);
- if(SQ_FAILED(sq_setdelegate(global_vm, -2)))
- throw Scripting::SquirrelError(global_vm, "Couldn't set sector_table delegate");
-
- sq_resetobject(§or_table);
- if(SQ_FAILED(sq_getstackobj(global_vm, -1, §or_table)))
- throw Scripting::SquirrelError(global_vm, "Couldn't get sector table");
- sq_addref(global_vm, §or_table);
- sq_pop(global_vm, 1);
-}
-
-Sector::~Sector()
-{
- using namespace Scripting;
-
- deactivate();
-
- for(ScriptList::iterator i = scripts.begin();
- i != scripts.end(); ++i) {
- HSQOBJECT& object = *i;
- sq_release(global_vm, &object);
- }
- sq_release(global_vm, §or_table);
- sq_collectgarbage(global_vm);
-
- update_game_objects();
- assert(gameobjects_new.size() == 0);
-
- for(GameObjects::iterator i = gameobjects.begin();
- i != gameobjects.end(); ++i) {
- GameObject* object = *i;
- before_object_remove(object);
- object->unref();
- }
-
- for(SpawnPoints::iterator i = spawnpoints.begin(); i != spawnpoints.end();
- ++i)
- delete *i;
-}
-
-Level*
-Sector::get_level()
-{
- return level;
-}
-
-GameObject*
-Sector::parse_object(const std::string& name, const lisp::Lisp& reader)
-{
- if(name == "camera") {
- Camera* camera = new Camera(this, "Camera");
- camera->parse(reader);
- return camera;
- } else if(name == "particles-snow") {
- SnowParticleSystem* partsys = new SnowParticleSystem();
- partsys->parse(reader);
- return partsys;
- } else if(name == "particles-rain") {
- RainParticleSystem* partsys = new RainParticleSystem();
- partsys->parse(reader);
- return partsys;
- } else if(name == "particles-comets") {
- CometParticleSystem* partsys = new CometParticleSystem();
- partsys->parse(reader);
- return partsys;
- } else if(name == "particles-ghosts") {
- GhostParticleSystem* partsys = new GhostParticleSystem();
- partsys->parse(reader);
- return partsys;
- } else if(name == "particles-clouds") {
- CloudParticleSystem* partsys = new CloudParticleSystem();
- partsys->parse(reader);
- return partsys;
- } else if(name == "money") { // for compatibility with old maps
- return new Jumpy(reader);
- }
-
- try {
- return create_object(name, reader);
- } catch(std::exception& e) {
- log_warning << e.what() << "" << std::endl;
- }
-
- return 0;
-}
-
-void
-Sector::parse(const lisp::Lisp& sector)
-{
- bool has_background = false;
- lisp::ListIterator iter(§or);
- while(iter.next()) {
- const std::string& token = iter.item();
- if(token == "name") {
- iter.value()->get(name);
- } else if(token == "gravity") {
- iter.value()->get(gravity);
- } else if(token == "music") {
- iter.value()->get(music);
- } else if(token == "spawnpoint") {
- SpawnPoint* sp = new SpawnPoint(iter.lisp());
- spawnpoints.push_back(sp);
- } else if(token == "init-script") {
- iter.value()->get(init_script);
- } else if(token == "ambient-light") {
- std::vector<float> vColor;
- sector.get_vector( "ambient-light", vColor );
- if(vColor.size() < 3) {
- log_warning << "(ambient-light) requires a color as argument" << std::endl;
- } else {
- ambient_light = Color( vColor );
- }
- } else {
- GameObject* object = parse_object(token, *(iter.lisp()));
- if(object) {
- if(dynamic_cast<Background *>(object)) {
- has_background = true;
- } else if(dynamic_cast<Gradient *>(object)) {
- has_background = true;
- }
- add_object(object);
- }
- }
- }
-
- if(!has_background) {
- Gradient* gradient = new Gradient();
- gradient->set_gradient(Color(0.3, 0.4, 0.75), Color(1, 1, 1));
- add_object(gradient);
- }
-
- update_game_objects();
-
- if(solid_tilemaps.size() < 1) log_warning << "sector '" << name << "' does not contain a solid tile layer." << std::endl;
-
- fix_old_tiles();
- if(!camera) {
- log_warning << "sector '" << name << "' does not contain a camera." << std::endl;
- update_game_objects();
- add_object(new Camera(this, "Camera"));
- }
-
- update_game_objects();
-}
-
-void
-Sector::parse_old_format(const lisp::Lisp& reader)
-{
- name = "main";
- reader.get("gravity", gravity);
-
- std::string backgroundimage;
- if (reader.get("background", backgroundimage) && (backgroundimage != "")) {
- if (backgroundimage == "arctis.png") backgroundimage = "arctis.jpg";
- if (backgroundimage == "arctis2.jpg") backgroundimage = "arctis.jpg";
- if (backgroundimage == "ocean.png") backgroundimage = "ocean.jpg";
- backgroundimage = "images/background/" + backgroundimage;
- if (!Unison::VFS::FileSystem::get().exists(backgroundimage)) {
- log_warning << "Background image \"" << backgroundimage << "\" not found. Ignoring." << std::endl;
- backgroundimage = "";
- }
- }
-
- float bgspeed = .5;
- reader.get("bkgd_speed", bgspeed);
- bgspeed /= 100;
-
- Color bkgd_top, bkgd_bottom;
- int r = 0, g = 0, b = 128;
- reader.get("bkgd_red_top", r);
- reader.get("bkgd_green_top", g);
- reader.get("bkgd_blue_top", b);
- bkgd_top.red = static_cast<float> (r) / 255.0f;
- bkgd_top.green = static_cast<float> (g) / 255.0f;
- bkgd_top.blue = static_cast<float> (b) / 255.0f;
-
- reader.get("bkgd_red_bottom", r);
- reader.get("bkgd_green_bottom", g);
- reader.get("bkgd_blue_bottom", b);
- bkgd_bottom.red = static_cast<float> (r) / 255.0f;
- bkgd_bottom.green = static_cast<float> (g) / 255.0f;
- bkgd_bottom.blue = static_cast<float> (b) / 255.0f;
-
- if(backgroundimage != "") {
- Background* background = new Background();
- background->set_image(backgroundimage, bgspeed);
- add_object(background);
- } else {
- Gradient* gradient = new Gradient();
- gradient->set_gradient(bkgd_top, bkgd_bottom);
- add_object(gradient);
- }
-
- std::string particlesystem;
- reader.get("particle_system", particlesystem);
- if(particlesystem == "clouds")
- add_object(new CloudParticleSystem());
- else if(particlesystem == "snow")
- add_object(new SnowParticleSystem());
- else if(particlesystem == "rain")
- add_object(new RainParticleSystem());
-
- Vector startpos(100, 170);
- reader.get("start_pos_x", startpos.x);
- reader.get("start_pos_y", startpos.y);
-
- SpawnPoint* spawn = new SpawnPoint;
- spawn->pos = startpos;
- spawn->name = "main";
- spawnpoints.push_back(spawn);
-
- music = "chipdisko.ogg";
- // skip reading music filename. It's all .ogg now, anyway
- /*
- reader.get("music", music);
- */
- music = "music/" + music;
-
- int width = 30, height = 15;
- reader.get("width", width);
- reader.get("height", height);
-
- std::vector<unsigned int> tiles;
- if(reader.get_vector("interactive-tm", tiles)
- || reader.get_vector("tilemap", tiles)) {
- TileMap* tilemap = new TileMap();
- tilemap->set(width, height, tiles, LAYER_TILES, true);
-
- // replace tile id 112 (old invisible tile) with 1311 (new invisible tile)
- for(size_t x=0; x < tilemap->get_width(); ++x) {
- for(size_t y=0; y < tilemap->get_height(); ++y) {
- const Tile* tile = tilemap->get_tile(x, y);
- if(tile->getID() == 112) tilemap->change(x, y, 1311);
- }
- }
-
- if (height < 19) tilemap->resize(width, 19);
- add_object(tilemap);
- }
-
- if(reader.get_vector("background-tm", tiles)) {
- TileMap* tilemap = new TileMap();
- tilemap->set(width, height, tiles, LAYER_BACKGROUNDTILES, false);
- if (height < 19) tilemap->resize(width, 19);
- add_object(tilemap);
- }
-
- if(reader.get_vector("foreground-tm", tiles)) {
- TileMap* tilemap = new TileMap();
- tilemap->set(width, height, tiles, LAYER_FOREGROUNDTILES, false);
-
- // fill additional space in foreground with tiles of ID 2035 (lightmap/black)
- if (height < 19) tilemap->resize(width, 19, 2035);
-
- add_object(tilemap);
- }
-
- // read reset-points (now spawn-points)
- const lisp::Lisp* resetpoints = reader.get_lisp("reset-points");
- if(resetpoints) {
- lisp::ListIterator iter(resetpoints);
- while(iter.next()) {
- if(iter.item() == "point") {
- Vector sp_pos;
- if(reader.get("x", sp_pos.x) && reader.get("y", sp_pos.y))
- {
- SpawnPoint* sp = new SpawnPoint;
- sp->name = "main";
- sp->pos = sp_pos;
- spawnpoints.push_back(sp);
- }
- } else {
- log_warning << "Unknown token '" << iter.item() << "' in reset-points." << std::endl;
- }
- }
- }
-
- // read objects
- const lisp::Lisp* objects = reader.get_lisp("objects");
- if(objects) {
- lisp::ListIterator iter(objects);
- while(iter.next()) {
- GameObject* object = parse_object(iter.item(), *(iter.lisp()));
- if(object) {
- add_object(object);
- } else {
- log_warning << "Unknown object '" << iter.item() << "' in level." << std::endl;
- }
- }
- }
-
- // add a camera
- Camera* camera = new Camera(this, "Camera");
- add_object(camera);
-
- update_game_objects();
-
- if(solid_tilemaps.size() < 1) log_warning << "sector '" << name << "' does not contain a solid tile layer." << std::endl;
-
- fix_old_tiles();
- update_game_objects();
-}
-
-void
-Sector::fix_old_tiles()
-{
- for(std::list<TileMap*>::iterator i = solid_tilemaps.begin(); i != solid_tilemaps.end(); i++) {
- TileMap* solids = *i;
- for(size_t x=0; x < solids->get_width(); ++x) {
- for(size_t y=0; y < solids->get_height(); ++y) {
- const Tile* tile = solids->get_tile(x, y);
- Vector pos(solids->get_x_offset() + x*32, solids->get_y_offset() + y*32);
-
- if(tile->getID() == 112) {
- add_object(new InvisibleBlock(pos));
- solids->change(x, y, 0);
- } else if(tile->getAttributes() & Tile::COIN) {
- add_object(new Coin(pos));
- solids->change(x, y, 0);
- } else if(tile->getAttributes() & Tile::FULLBOX) {
- add_object(new BonusBlock(pos, tile->getData()));
- solids->change(x, y, 0);
- } else if(tile->getAttributes() & Tile::BRICK) {
- add_object(new Brick(pos, tile->getData()));
- solids->change(x, y, 0);
- } else if(tile->getAttributes() & Tile::GOAL) {
- std::string sequence = tile->getData() == 0 ? "endsequence" : "stoptux";
- add_object(new SequenceTrigger(pos, sequence));
- solids->change(x, y, 0);
- }
- }
- }
- }
-
- // add lights for special tiles
- for(GameObjects::iterator i = gameobjects.begin(); i != gameobjects.end(); i++) {
- TileMap* tm = dynamic_cast<TileMap*>(*i);
- if (!tm) continue;
- for(size_t x=0; x < tm->get_width(); ++x) {
- for(size_t y=0; y < tm->get_height(); ++y) {
- const Tile* tile = tm->get_tile(x, y);
- Vector pos(tm->get_x_offset() + x*32, tm->get_y_offset() + y*32);
- Vector center(pos.x + 16, pos.y + 16);
-
- // torch
- if (tile->getID() == 1517) {
- float pseudo_rnd = (float)((int)pos.x % 10) / 10;
- add_object(new PulsingLight(center, 1.0f + pseudo_rnd, 0.9f, 1.0f, Color(1.0f, 1.0f, 0.6f, 1.0f)));
- }
- // lava or lavaflow
- if ((tile->getID() == 173) || (tile->getID() == 1700) || (tile->getID() == 1705) || (tile->getID() == 1706)) {
- // space lights a bit
- if (((tm->get_tile(x-1, y)->getID() != tm->get_tile(x,y)->getID())
- && (tm->get_tile(x, y-1)->getID() != tm->get_tile(x,y)->getID()))
- || ((x % 3 == 0) && (y % 3 == 0))) {
- float pseudo_rnd = (float)((int)pos.x % 10) / 10;
- add_object(new PulsingLight(center, 1.0f + pseudo_rnd, 0.8f, 1.0f, Color(1.0f, 0.3f, 0.0f, 1.0f)));
- }
- }
-
- }
- }
- }
-
-
-}
-
-void
-Sector::write(lisp::Writer& writer)
-{
- writer.write_string("name", name);
- writer.write_float("gravity", gravity);
- writer.write_string("music", music);
-
- // write spawnpoints
- for(SpawnPoints::iterator i = spawnpoints.begin(); i != spawnpoints.end();
- ++i) {
- SpawnPoint* spawn = *i;
- writer.start_list("spawn-points");
- writer.write_string("name", spawn->name);
- writer.write_float("x", spawn->pos.x);
- writer.write_float("y", spawn->pos.y);
- writer.end_list("spawn-points");
- }
-
- // write objects
- for(GameObjects::iterator i = gameobjects.begin();
- i != gameobjects.end(); ++i) {
- Serializable* serializable = dynamic_cast<Serializable*> (*i);
- if(serializable)
- serializable->write(writer);
- }
-}
-
-HSQUIRRELVM
-Sector::run_script(std::istream& in, const std::string& sourcename)
-{
- using namespace Scripting;
-
- // garbage collect thread list
- for(ScriptList::iterator i = scripts.begin();
- i != scripts.end(); ) {
- HSQOBJECT& object = *i;
- HSQUIRRELVM vm = object_to_vm(object);
-
- if(sq_getvmstate(vm) != SQ_VMSTATE_SUSPENDED) {
- sq_release(global_vm, &object);
- i = scripts.erase(i);
- continue;
- }
-
- ++i;
- }
-
- HSQOBJECT object = create_thread(global_vm);
- scripts.push_back(object);
-
- HSQUIRRELVM vm = object_to_vm(object);
-
- // set sector_table as roottable for the thread
- sq_pushobject(vm, sector_table);
- sq_setroottable(vm);
-
- compile_and_run(vm, in, sourcename);
-
- return vm;
-}
-
-void
-Sector::add_object(GameObject* object)
-{
- // make sure the object isn't already in the list
-#ifdef DEBUG
- for(GameObjects::iterator i = gameobjects.begin(); i != gameobjects.end();
- ++i) {
- if(*i == object) {
- assert("object already added to sector" == 0);
- }
- }
- for(GameObjects::iterator i = gameobjects_new.begin();
- i != gameobjects_new.end(); ++i) {
- if(*i == object) {
- assert("object already added to sector" == 0);
- }
- }
-#endif
-
- object->ref();
- gameobjects_new.push_back(object);
-}
-
-void
-Sector::activate(const std::string& spawnpoint)
-{
- SpawnPoint* sp = 0;
- for(SpawnPoints::iterator i = spawnpoints.begin(); i != spawnpoints.end();
- ++i) {
- if((*i)->name == spawnpoint) {
- sp = *i;
- break;
- }
- }
- if(!sp) {
- log_warning << "Spawnpoint '" << spawnpoint << "' not found." << std::endl;
- if(spawnpoint != "main") {
- activate("main");
- } else {
- activate(Vector(0, 0));
- }
- } else {
- activate(sp->pos);
- }
-}
-
-void
-Sector::activate(const Vector& player_pos)
-{
- if(_current != this) {
- if(_current != NULL)
- _current->deactivate();
- _current = this;
-
- // register sectortable as sector in scripting
- HSQUIRRELVM vm = Scripting::global_vm;
- sq_pushroottable(vm);
- sq_pushstring(vm, "sector", -1);
- sq_pushobject(vm, sector_table);
- if(SQ_FAILED(sq_createslot(vm, -3)))
- throw Scripting::SquirrelError(vm, "Couldn't set sector in roottable");
- sq_pop(vm, 1);
-
- for(GameObjects::iterator i = gameobjects.begin();
- i != gameobjects.end(); ++i) {
- GameObject* object = *i;
-
- try_expose(object);
- }
- }
- try_expose_me();
-
- // spawn smalltux below spawnpoint
- if (!player->is_big()) {
- player->move(player_pos + Vector(0,32));
- } else {
- player->move(player_pos);
- }
-
- // spawning tux in the ground would kill him
- if(!is_free_of_tiles(player->get_bbox())) {
- log_warning << "Tried spawning Tux in solid matter. Compensating." << std::endl;
- Vector npos = player->get_bbox().p1;
- npos.y-=32;
- player->move(npos);
- }
-
- camera->reset(player->get_pos());
- update_game_objects();
-
- // Run init script
- if(init_script != "") {
- std::istringstream in(init_script);
- run_script(in, std::string("Sector(") + name + ") - init");
- }
-}
-
-void
-Sector::deactivate()
-{
- if(_current != this)
- return;
-
- // remove sector entry from global vm
- HSQUIRRELVM vm = Scripting::global_vm;
- sq_pushroottable(vm);
- sq_pushstring(vm, "sector", -1);
- if(SQ_FAILED(sq_deleteslot(vm, -2, SQFalse)))
- throw Scripting::SquirrelError(vm, "Couldn't unset sector in roottable");
- sq_pop(vm, 1);
-
- for(GameObjects::iterator i = gameobjects.begin();
- i != gameobjects.end(); ++i) {
- GameObject* object = *i;
-
- try_unexpose(object);
- }
-
- try_unexpose_me();
- _current = NULL;
-}
-
-Rect
-Sector::get_active_region()
-{
- return Rect(
- camera->get_translation() - Vector(1600, 1200),
- camera->get_translation() + Vector(1600, 1200) + Vector(SCREEN_WIDTH,SCREEN_HEIGHT));
-}
-
-void
-Sector::update(float elapsed_time)
-{
- player->check_bounds(camera);
-
- /* update objects */
- for(GameObjects::iterator i = gameobjects.begin();
- i != gameobjects.end(); ++i) {
- GameObject* object = *i;
- if(!object->is_valid())
- continue;
-
- object->update(elapsed_time);
- }
-
- /* Handle all possible collisions. */
- handle_collisions();
- update_game_objects();
-}
-
-void
-Sector::update_game_objects()
-{
- /** cleanup marked objects */
- for(std::vector<GameObject*>::iterator i = gameobjects.begin();
- i != gameobjects.end(); /* nothing */) {
- GameObject* object = *i;
-
- if(object->is_valid()) {
- ++i;
- continue;
- }
-
- before_object_remove(object);
-
- object->unref();
- i = gameobjects.erase(i);
- }
-
- /* add newly created objects */
- for(std::vector<GameObject*>::iterator i = gameobjects_new.begin();
- i != gameobjects_new.end(); ++i)
- {
- GameObject* object = *i;
-
- before_object_add(object);
-
- gameobjects.push_back(object);
- }
- gameobjects_new.clear();
-
- /* update solid_tilemaps list */
- //FIXME: this could be more efficient
- solid_tilemaps.clear();
- for(std::vector<GameObject*>::iterator i = gameobjects.begin();
- i != gameobjects.end(); ++i)
- {
- TileMap* tm = dynamic_cast<TileMap*>(*i);
- if (!tm) continue;
- if (tm->is_solid()) solid_tilemaps.push_back(tm);
- }
-
-}
-
-bool
-Sector::before_object_add(GameObject* object)
-{
- Bullet* bullet = dynamic_cast<Bullet*> (object);
- if(bullet != NULL) {
- bullets.push_back(bullet);
- }
-
- MovingObject* movingobject = dynamic_cast<MovingObject*> (object);
- if(movingobject != NULL) {
- moving_objects.push_back(movingobject);
- }
-
- Portable* portable = dynamic_cast<Portable*> (object);
- if(portable != NULL) {
- portables.push_back(portable);
- }
-
- TileMap* tilemap = dynamic_cast<TileMap*> (object);
- if(tilemap != NULL && tilemap->is_solid()) {
- solid_tilemaps.push_back(tilemap);
- }
-
- Camera* camera = dynamic_cast<Camera*> (object);
- if(camera != NULL) {
- if(this->camera != 0) {
- log_warning << "Multiple cameras added. Ignoring" << std::endl;
- return false;
- }
- this->camera = camera;
- }
-
- Player* player = dynamic_cast<Player*> (object);
- if(player != NULL) {
- if(this->player != 0) {
- log_warning << "Multiple players added. Ignoring" << std::endl;
- return false;
- }
- this->player = player;
- }
-
- UsesPhysic *physic_object = dynamic_cast<UsesPhysic *>(object);
- if(physic_object)
- {
- physic_object->physic.set_gravity(gravity);
- }
-
-
- if(_current == this) {
- try_expose(object);
- }
-
- return true;
-}
-
-void
-Sector::try_expose(GameObject* object)
-{
- ScriptInterface* interface = dynamic_cast<ScriptInterface*> (object);
- if(interface != NULL) {
- HSQUIRRELVM vm = Scripting::global_vm;
- sq_pushobject(vm, sector_table);
- interface->expose(vm, -1);
- sq_pop(vm, 1);
- }
-}
-
-void
-Sector::try_expose_me()
-{
- HSQUIRRELVM vm = Scripting::global_vm;
- sq_pushobject(vm, sector_table);
- Scripting::SSector* interface = static_cast<Scripting::SSector*> (this);
- expose_object(vm, -1, interface, "settings", false);
- sq_pop(vm, 1);
-}
-
-void
-Sector::before_object_remove(GameObject* object)
-{
- Portable* portable = dynamic_cast<Portable*> (object);
- if(portable != NULL) {
- portables.erase(std::find(portables.begin(), portables.end(), portable));
- }
- Bullet* bullet = dynamic_cast<Bullet*> (object);
- if(bullet != NULL) {
- bullets.erase(std::find(bullets.begin(), bullets.end(), bullet));
- }
- MovingObject* moving_object = dynamic_cast<MovingObject*> (object);
- if(moving_object != NULL) {
- moving_objects.erase(
- std::find(moving_objects.begin(), moving_objects.end(), moving_object));
- }
-
- if(_current == this)
- try_unexpose(object);
-}
-
-void
-Sector::try_unexpose(GameObject* object)
-{
- ScriptInterface* interface = dynamic_cast<ScriptInterface*> (object);
- if(interface != NULL) {
- HSQUIRRELVM vm = Scripting::global_vm;
- SQInteger oldtop = sq_gettop(vm);
- sq_pushobject(vm, sector_table);
- try {
- interface->unexpose(vm, -1);
- } catch(std::exception& e) {
- log_warning << "Couldn't unregister object: " << e.what() << std::endl;
- }
- sq_settop(vm, oldtop);
- }
-}
-
-void
-Sector::try_unexpose_me()
-{
- HSQUIRRELVM vm = Scripting::global_vm;
- SQInteger oldtop = sq_gettop(vm);
- sq_pushobject(vm, sector_table);
- try {
- Scripting::unexpose_object(vm, -1, "settings");
- } catch(std::exception& e) {
- log_warning << "Couldn't unregister object: " << e.what() << std::endl;
- }
- sq_settop(vm, oldtop);
-}
-void
-Sector::draw(DrawingContext& context)
-{
- context.set_ambient_color( ambient_light );
- context.push_transform();
- context.set_translation(camera->get_translation());
-
- for(GameObjects::iterator i = gameobjects.begin();
- i != gameobjects.end(); ++i) {
- GameObject* object = *i;
- if(!object->is_valid())
- continue;
-
- if (draw_solids_only)
- {
- TileMap* tm = dynamic_cast<TileMap*>(object);
- if (tm && !tm->is_solid())
- continue;
- }
-
- object->draw(context);
- }
-
- if(show_collrects) {
- Color col(0.2f, 0.2f, 0.2f, 0.7f);
- for(MovingObjects::iterator i = moving_objects.begin();
- i != moving_objects.end(); ++i) {
- MovingObject* object = *i;
- const Rect& rect = object->get_bbox();
-
- context.draw_filled_rect(rect, col, LAYER_FOREGROUND1 + 10);
- }
- }
-
- context.pop_transform();
-}
-
-/*-------------------------------------------------------------------------
- * Collision Detection
- *-------------------------------------------------------------------------*/
-
-static const float SHIFT_DELTA = 7.0f;
-
-/** r1 is supposed to be moving, r2 a solid object */
-void check_collisions(collision::Constraints* constraints,
- const Vector& movement, const Rect& r1, const Rect& r2,
- GameObject* object = NULL, MovingObject* other = NULL)
-{
- if(!collision::intersects(r1, r2))
- return;
-
- MovingObject *moving_object = dynamic_cast<MovingObject*> (object);
- CollisionHit dummy;
- if(other != NULL && !other->collides(*object, dummy))
- return;
- if(moving_object != NULL && !moving_object->collides(*other, dummy))
- return;
-
- // calculate intersection
- float itop = r1.get_bottom() - r2.get_top();
- float ibottom = r2.get_bottom() - r1.get_top();
- float ileft = r1.get_right() - r2.get_left();
- float iright = r2.get_right() - r1.get_left();
-
- if(fabsf(movement.y) > fabsf(movement.x)) {
- if(ileft < SHIFT_DELTA) {
- constraints->right = std::min(constraints->right, r2.get_left());
- return;
- } else if(iright < SHIFT_DELTA) {
- constraints->left = std::max(constraints->left, r2.get_right());
- return;
- }
- } else {
- // shiftout bottom/top
- if(itop < SHIFT_DELTA) {
- constraints->bottom = std::min(constraints->bottom, r2.get_top());
- return;
- } else if(ibottom < SHIFT_DELTA) {
- constraints->top = std::max(constraints->top, r2.get_bottom());
- return;
- }
- }
-
- if(other != NULL) {
- HitResponse response = other->collision(*object, dummy);
- if(response == PASSTHROUGH)
- return;
-
- if(other->get_movement() != Vector(0, 0)) {
- // TODO what todo when we collide with 2 moving objects?!?
- constraints->ground_movement = other->get_movement();
- }
- }
-
- float vert_penetration = std::min(itop, ibottom);
- float horiz_penetration = std::min(ileft, iright);
- if(vert_penetration < horiz_penetration) {
- if(itop < ibottom) {
- constraints->bottom = std::min(constraints->bottom, r2.get_top());
- constraints->hit.bottom = true;
- } else {
- constraints->top = std::max(constraints->top, r2.get_bottom());
- constraints->hit.top = true;
- }
- } else {
- if(ileft < iright) {
- constraints->right = std::min(constraints->right, r2.get_left());
- constraints->hit.right = true;
- } else {
- constraints->left = std::max(constraints->left, r2.get_right());
- constraints->hit.left = true;
- }
- }
-}
-
-static const float DELTA = .001f;
-
-void
-Sector::collision_tilemap(collision::Constraints* constraints,
- const Vector& movement, const Rect& dest) const
-{
- // calculate rectangle where the object will move
- float x1 = dest.get_left();
- float x2 = dest.get_right();
- float y1 = dest.get_top();
- float y2 = dest.get_bottom();
-
- for(std::list<TileMap*>::const_iterator i = solid_tilemaps.begin(); i != solid_tilemaps.end(); i++) {
- TileMap* solids = *i;
-
- // test with all tiles in this rectangle
- int starttilex = int(x1 - solids->get_x_offset()) / 32;
- int starttiley = int(y1 - solids->get_y_offset()) / 32;
- int max_x = int(x2 - solids->get_x_offset());
- int max_y = int(y2+1 - solids->get_y_offset());
-
- for(int x = starttilex; x*32 < max_x; ++x) {
- for(int y = starttiley; y*32 < max_y; ++y) {
- const Tile* tile = solids->get_tile(x, y);
- if(!tile)
- continue;
- // skip non-solid tiles
- if((tile->getAttributes() & Tile::SOLID) == 0)
- continue;
- // only handle unisolid when the player is falling down and when he was
- // above the tile before
- if(tile->getAttributes() & Tile::UNISOLID) {
- if(movement.y <= 0 || dest.get_bottom() - movement.y - SHIFT_DELTA > y*32)
- continue;
- }
-
- if(tile->getAttributes() & Tile::SLOPE) { // slope tile
- AATriangle triangle;
- Vector p1(x*32 + solids->get_x_offset(), y*32 + solids->get_y_offset());
- Vector p2((x+1)*32 + solids->get_x_offset(), (y+1)*32 + solids->get_y_offset());
- triangle = AATriangle(p1, p2, tile->getData());
-
- collision::rectangle_aatriangle(constraints, dest, triangle);
- } else { // normal rectangular tile
- Rect rect(x*32 + solids->get_x_offset(), y*32 + solids->get_y_offset(), (x+1)*32 + solids->get_x_offset(), (y+1)*32 + solids->get_y_offset());
- check_collisions(constraints, movement, dest, rect);
- }
- }
- }
- }
-}
-
-uint32_t
-Sector::collision_tile_attributes(const Rect& dest) const
-{
- float x1 = dest.p1.x;
- float y1 = dest.p1.y;
- float x2 = dest.p2.x;
- float y2 = dest.p2.y;
-
- uint32_t result = 0;
- for(std::list<TileMap*>::const_iterator i = solid_tilemaps.begin(); i != solid_tilemaps.end(); i++) {
- TileMap* solids = *i;
-
- // test with all tiles in this rectangle
- int starttilex = int(x1 - solids->get_x_offset()) / 32;
- int starttiley = int(y1 - solids->get_y_offset()) / 32;
- int max_x = int(x2 - solids->get_x_offset());
- int max_y = int(y2+1 - solids->get_y_offset());
-
- for(int x = starttilex; x*32 < max_x; ++x) {
- for(int y = starttiley; y*32 < max_y; ++y) {
- const Tile* tile = solids->get_tile(x, y);
- if(!tile)
- continue;
- result |= tile->getAttributes();
- }
- }
- }
-
- return result;
-}
-
-/** fills in CollisionHit and Normal vector of 2 intersecting rectangle */
-static void get_hit_normal(const Rect& r1, const Rect& r2, CollisionHit& hit,
- Vector& normal)
-{
- float itop = r1.get_bottom() - r2.get_top();
- float ibottom = r2.get_bottom() - r1.get_top();
- float ileft = r1.get_right() - r2.get_left();
- float iright = r2.get_right() - r1.get_left();
-
- float vert_penetration = std::min(itop, ibottom);
- float horiz_penetration = std::min(ileft, iright);
- if(vert_penetration < horiz_penetration) {
- if(itop < ibottom) {
- hit.bottom = true;
- normal.y = vert_penetration;
- } else {
- hit.top = true;
- normal.y = -vert_penetration;
- }
- } else {
- if(ileft < iright) {
- hit.right = true;
- normal.x = horiz_penetration;
- } else {
- hit.left = true;
- normal.x = -horiz_penetration;
- }
- }
-}
-
-void
-Sector::collision_object(MovingObject* object1, MovingObject* object2) const
-{
- using namespace collision;
-
- const Rect& r1 = object1->dest;
- const Rect& r2 = object2->dest;
-
- CollisionHit hit;
- if(intersects(object1->dest, object2->dest)) {
- Vector normal;
- get_hit_normal(r1, r2, hit, normal);
-
- if(!object1->collides(*object2, hit))
- return;
- std::swap(hit.left, hit.right);
- std::swap(hit.top, hit.bottom);
- if(!object2->collides(*object1, hit))
- return;
- std::swap(hit.left, hit.right);
- std::swap(hit.top, hit.bottom);
-
- HitResponse response1 = object1->collision(*object2, hit);
- std::swap(hit.left, hit.right);
- std::swap(hit.top, hit.bottom);
- HitResponse response2 = object2->collision(*object1, hit);
- if(response1 == CONTINUE && response2 == CONTINUE) {
- normal *= (0.5 + DELTA);
- object1->dest.move(-normal);
- object2->dest.move(normal);
- } else if (response1 == CONTINUE && response2 == FORCE_MOVE) {
- normal *= (1 + DELTA);
- object1->dest.move(-normal);
- } else if (response1 == FORCE_MOVE && response2 == CONTINUE) {
- normal *= (1 + DELTA);
- object2->dest.move(normal);
- }
- }
-}
-
-void
-Sector::collision_static(collision::Constraints* constraints,
- const Vector& movement, const Rect& dest,
- GameObject& object)
-{
- collision_tilemap(constraints, movement, dest);
-
- // collision with other (static) objects
- for(MovingObjects::iterator i = moving_objects.begin();
- i != moving_objects.end(); ++i) {
- MovingObject* moving_object = *i;
- if(moving_object->get_group() != COLGROUP_STATIC
- && moving_object->get_group() != COLGROUP_MOVING_STATIC)
- continue;
- if(!moving_object->is_valid())
- continue;
-
- if(moving_object != &object)
- check_collisions(constraints, movement, dest, moving_object->bbox,
- &object, moving_object);
- }
-}
-
-void
-Sector::collision_static_constrains(MovingObject& object)
-{
- using namespace collision;
- float infinity = (std::numeric_limits<float>::has_infinity ? std::numeric_limits<float>::infinity() : std::numeric_limits<float>::max());
-
- Constraints constraints;
- Vector movement = object.get_movement();
- Rect& dest = object.dest;
- float owidth = object.get_bbox().get_width();
- float oheight = object.get_bbox().get_height();
-
- for(int i = 0; i < 2; ++i) {
- collision_static(&constraints, Vector(0, movement.y), dest, object);
- if(!constraints.has_constraints())
- break;
-
- // apply calculated horizontal constraints
- if(constraints.bottom < infinity) {
- float height = constraints.bottom - constraints.top;
- if(height < oheight) {
- // we're crushed, but ignore this for now, we'll get this again
- // later if we're really crushed or things will solve itself when
- // looking at the vertical constraints
- }
- dest.p2.y = constraints.bottom - DELTA;
- dest.p1.y = dest.p2.y - oheight;
- } else if(constraints.top > -infinity) {
- dest.p1.y = constraints.top + DELTA;
- dest.p2.y = dest.p1.y + oheight;
- }
- }
- if(constraints.has_constraints()) {
- if(constraints.hit.bottom) {
- dest.move(constraints.ground_movement);
- }
- if(constraints.hit.top || constraints.hit.bottom) {
- constraints.hit.left = false;
- constraints.hit.right = false;
- object.collision_solid(constraints.hit);
- }
- }
-
- constraints = Constraints();
- for(int i = 0; i < 2; ++i) {
- collision_static(&constraints, movement, dest, object);
- if(!constraints.has_constraints())
- break;
-
- // apply calculated vertical constraints
- if(constraints.right < infinity) {
- float width = constraints.right - constraints.left;
- if(width + SHIFT_DELTA < owidth) {
-#if 0
- printf("Object %p crushed horizontally... L:%f R:%f\n", &object,
- constraints.left, constraints.right);
-#endif
- CollisionHit h;
- h.left = true;
- h.right = true;
- h.crush = true;
- object.collision_solid(h);
- } else {
- dest.p2.x = constraints.right - DELTA;
- dest.p1.x = dest.p2.x - owidth;
- }
- } else if(constraints.left > -infinity) {
- dest.p1.x = constraints.left + DELTA;
- dest.p2.x = dest.p1.x + owidth;
- }
- }
-
- if(constraints.has_constraints()) {
- if( constraints.hit.left || constraints.hit.right
- || constraints.hit.top || constraints.hit.bottom
- || constraints.hit.crush )
- object.collision_solid(constraints.hit);
- }
-
- // an extra pass to make sure we're not crushed horizontally
- constraints = Constraints();
- collision_static(&constraints, movement, dest, object);
- if(constraints.bottom < infinity) {
- float height = constraints.bottom - constraints.top;
- if(height + SHIFT_DELTA < oheight) {
-#if 0
- printf("Object %p crushed vertically...\n", &object);
-#endif
- CollisionHit h;
- h.top = true;
- h.bottom = true;
- h.crush = true;
- object.collision_solid(h);
- }
- }
-}
-
-namespace {
- const float MAX_SPEED = 16.0f;
-}
-
-void
-Sector::handle_collisions()
-{
- using namespace collision;
-
- // calculate destination positions of the objects
- for(MovingObjects::iterator i = moving_objects.begin();
- i != moving_objects.end(); ++i) {
- MovingObject* moving_object = *i;
- Vector mov = moving_object->get_movement();
-
- // make sure movement is never faster than MAX_SPEED. Norm is pretty fat, so two addl. checks are done before.
- if (((mov.x > MAX_SPEED * M_SQRT1_2) || (mov.y > MAX_SPEED * M_SQRT1_2)) && (mov.norm() > MAX_SPEED)) {
- moving_object->movement = mov.unit() * MAX_SPEED;
- //log_debug << "Temporarily reduced object's speed of " << mov.norm() << " to " << moving_object->movement.norm() << "." << std::endl;
- }
-
- moving_object->dest = moving_object->get_bbox();
- moving_object->dest.move(moving_object->get_movement());
- }
-
- // part1: COLGROUP_MOVING vs COLGROUP_STATIC and tilemap
- for(MovingObjects::iterator i = moving_objects.begin();
- i != moving_objects.end(); ++i) {
- MovingObject* moving_object = *i;
- if((moving_object->get_group() != COLGROUP_MOVING
- && moving_object->get_group() != COLGROUP_MOVING_STATIC
- && moving_object->get_group() != COLGROUP_MOVING_ONLY_STATIC)
- || !moving_object->is_valid())
- continue;
-
- collision_static_constrains(*moving_object);
- }
-
-
- // part2: COLGROUP_MOVING vs tile attributes
- for(MovingObjects::iterator i = moving_objects.begin();
- i != moving_objects.end(); ++i) {
- MovingObject* moving_object = *i;
- if((moving_object->get_group() != COLGROUP_MOVING
- && moving_object->get_group() != COLGROUP_MOVING_STATIC
- && moving_object->get_group() != COLGROUP_MOVING_ONLY_STATIC)
- || !moving_object->is_valid())
- continue;
-
- uint32_t tile_attributes = collision_tile_attributes(moving_object->dest);
- if(tile_attributes > Tile::FIRST_INTERESTING_FLAG) {
- moving_object->collision_tile(tile_attributes);
- }
- }
-
- // part2.5: COLGROUP_MOVING vs COLGROUP_TOUCHABLE
- for(MovingObjects::iterator i = moving_objects.begin();
- i != moving_objects.end(); ++i) {
- MovingObject* moving_object = *i;
- if((moving_object->get_group() != COLGROUP_MOVING
- && moving_object->get_group() != COLGROUP_MOVING_STATIC)
- || !moving_object->is_valid())
- continue;
-
- for(MovingObjects::iterator i2 = moving_objects.begin();
- i2 != moving_objects.end(); ++i2) {
- MovingObject* moving_object_2 = *i2;
- if(moving_object_2->get_group() != COLGROUP_TOUCHABLE
- || !moving_object_2->is_valid())
- continue;
-
- if(intersects(moving_object->dest, moving_object_2->dest)) {
- Vector normal;
- CollisionHit hit;
- get_hit_normal(moving_object->dest, moving_object_2->dest,
- hit, normal);
- if(!moving_object->collides(*moving_object_2, hit))
- continue;
- if(!moving_object_2->collides(*moving_object, hit))
- continue;
-
- moving_object->collision(*moving_object_2, hit);
- moving_object_2->collision(*moving_object, hit);
- }
- }
- }
-
- // part3: COLGROUP_MOVING vs COLGROUP_MOVING
- for(MovingObjects::iterator i = moving_objects.begin();
- i != moving_objects.end(); ++i) {
- MovingObject* moving_object = *i;
-
- if((moving_object->get_group() != COLGROUP_MOVING
- && moving_object->get_group() != COLGROUP_MOVING_STATIC)
- || !moving_object->is_valid())
- continue;
-
- for(MovingObjects::iterator i2 = i+1;
- i2 != moving_objects.end(); ++i2) {
- MovingObject* moving_object_2 = *i2;
- if((moving_object_2->get_group() != COLGROUP_MOVING
- && moving_object_2->get_group() != COLGROUP_MOVING_STATIC)
- || !moving_object_2->is_valid())
- continue;
-
- collision_object(moving_object, moving_object_2);
- }
- }
-
- // apply object movement
- for(MovingObjects::iterator i = moving_objects.begin();
- i != moving_objects.end(); ++i) {
- MovingObject* moving_object = *i;
-
- moving_object->bbox = moving_object->dest;
- moving_object->movement = Vector(0, 0);
- }
-}
-
-bool
-Sector::is_free_of_tiles(const Rect& rect, const bool ignoreUnisolid) const
-{
- using namespace collision;
-
- for(std::list<TileMap*>::const_iterator i = solid_tilemaps.begin(); i != solid_tilemaps.end(); i++) {
- TileMap* solids = *i;
-
- // test with all tiles in this rectangle
- int starttilex = int(rect.p1.x - solids->get_x_offset()) / 32;
- int starttiley = int(rect.p1.y - solids->get_y_offset()) / 32;
- int max_x = int(rect.p2.x - solids->get_x_offset());
- int max_y = int(rect.p2.y - solids->get_y_offset());
-
- for(int x = starttilex; x*32 <= max_x; ++x) {
- for(int y = starttiley; y*32 <= max_y; ++y) {
- const Tile* tile = solids->get_tile(x, y);
- if(!tile) continue;
- if(tile->getAttributes() & Tile::SLOPE) {
- AATriangle triangle;
- Vector p1(x*32 + solids->get_x_offset(), y*32 + solids->get_y_offset());
- Vector p2((x+1)*32 + solids->get_x_offset(), (y+1)*32 + solids->get_y_offset());
- triangle = AATriangle(p1, p2, tile->getData());
- Constraints constraints;
- return collision::rectangle_aatriangle(&constraints, rect, triangle);
- }
- if((tile->getAttributes() & Tile::SOLID) && !ignoreUnisolid) return false;
- if((tile->getAttributes() & Tile::SOLID) && !(tile->getAttributes() & Tile::UNISOLID)) return false;
- }
- }
- }
-
- return true;
-}
-
-bool
-Sector::is_free_of_statics(const Rect& rect, const MovingObject* ignore_object, const bool ignoreUnisolid) const
-{
- using namespace collision;
-
- if (!is_free_of_tiles(rect, ignoreUnisolid)) return false;
-
- for(MovingObjects::const_iterator i = moving_objects.begin();
- i != moving_objects.end(); ++i) {
- const MovingObject* moving_object = *i;
- if (moving_object == ignore_object) continue;
- if (!moving_object->is_valid()) continue;
- if (moving_object->get_group() == COLGROUP_STATIC) {
- if(intersects(rect, moving_object->get_bbox())) return false;
- }
- }
-
- return true;
-}
-
-bool
-Sector::is_free_of_movingstatics(const Rect& rect, const MovingObject* ignore_object) const
-{
- using namespace collision;
-
- if (!is_free_of_tiles(rect)) return false;
-
- for(MovingObjects::const_iterator i = moving_objects.begin();
- i != moving_objects.end(); ++i) {
- const MovingObject* moving_object = *i;
- if (moving_object == ignore_object) continue;
- if (!moving_object->is_valid()) continue;
- if ((moving_object->get_group() == COLGROUP_MOVING)
- || (moving_object->get_group() == COLGROUP_MOVING_STATIC)
- || (moving_object->get_group() == COLGROUP_STATIC)) {
- if(intersects(rect, moving_object->get_bbox())) return false;
- }
- }
-
- return true;
-}
-
-bool
-Sector::add_bullet(const Vector& pos, float xm, Direction dir)
-{
- // TODO remove this function and move these checks elsewhere...
-
- Bullet* new_bullet = 0;
- if((player_status->bonus == FIRE_BONUS &&
- (int)bullets.size() >= player_status->max_fire_bullets) ||
- (player_status->bonus == ICE_BONUS &&
- (int)bullets.size() >= player_status->max_ice_bullets))
- return false;
- new_bullet = new Bullet(pos, xm, dir, player_status->bonus);
- add_object(new_bullet);
-
- sound_manager->play("sounds/shoot.wav");
-
- return true;
-}
-
-bool
-Sector::add_smoke_cloud(const Vector& pos)
-{
- add_object(new SmokeCloud(pos));
- return true;
-}
-
-void
-Sector::play_music(MusicType type)
-{
- currentmusic = type;
- switch(currentmusic) {
- case LEVEL_MUSIC:
- sound_manager->play_music(music);
- break;
- case HERRING_MUSIC:
- sound_manager->play_music("music/salcon.ogg");
- break;
- case HERRING_WARNING_MUSIC:
- sound_manager->stop_music(TUX_INVINCIBLE_TIME_WARNING);
- break;
- default:
- sound_manager->play_music("");
- break;
- }
-}
-
-MusicType
-Sector::get_music_type()
-{
- return currentmusic;
-}
-
-int
-Sector::get_total_badguys()
-{
- int total_badguys = 0;
- for(GameObjects::iterator i = gameobjects.begin();
- i != gameobjects.end(); ++i) {
- BadGuy* badguy = dynamic_cast<BadGuy*> (*i);
- if (badguy && badguy->countMe)
- total_badguys++;
- }
-
- return total_badguys;
-}
-
-bool
-Sector::inside(const Rect& rect) const
-{
- for(std::list<TileMap*>::const_iterator i = solid_tilemaps.begin(); i != solid_tilemaps.end(); i++) {
- TileMap* solids = *i;
- bool horizontally = ((rect.p2.x >= 0 + solids->get_x_offset()) && (rect.p1.x <= solids->get_width() * 32 + solids->get_x_offset()));
- bool vertically = (rect.p1.y <= solids->get_height() * 32 + solids->get_y_offset());
-
- if (horizontally && vertically)
- return true;
- }
- return false;
-}
-
-float
-Sector::get_width() const
-{
- float width = 0;
- for(std::list<TileMap*>::const_iterator i = solid_tilemaps.begin();
- i != solid_tilemaps.end(); i++) {
- TileMap* solids = *i;
- if ((solids->get_width() * 32 + solids->get_x_offset()) > width) {
- width = solids->get_width() * 32 + solids->get_x_offset();
- }
- }
-
- return width;
-}
-
-float
-Sector::get_height() const
-{
- float height = 0;
- for(std::list<TileMap*>::const_iterator i = solid_tilemaps.begin();
- i != solid_tilemaps.end(); i++) {
- TileMap* solids = *i;
- if ((solids->get_height() * 32 + solids->get_y_offset()) > height) {
- height = solids->get_height() * 32 + solids->get_y_offset();
- }
- }
-
- return height;
-}
-
-void
-Sector::change_solid_tiles(uint32_t old_tile_id, uint32_t new_tile_id)
-{
- for(std::list<TileMap*>::const_iterator i = solid_tilemaps.begin(); i != solid_tilemaps.end(); i++) {
- TileMap* solids = *i;
- solids->change_all(old_tile_id, new_tile_id);
- }
-}
-
-
-void
-Sector::set_ambient_light(float red, float green, float blue)
-{
- ambient_light.red = red;
- ambient_light.green = green;
- ambient_light.blue = blue;
-}
-
-float
-Sector::get_ambient_red()
-{
- return ambient_light.red;
-}
-
-float
-Sector::get_ambient_green()
-{
- return ambient_light.green;
-}
-
-float
-Sector::get_ambient_blue()
-{
- return ambient_light.blue;
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux - A Jump'n Run
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#ifndef SUPERTUX_SECTOR_H
-#define SUPERTUX_SECTOR_H
-
-#include <vector>
-#include <list>
-#include <memory>
-#include <squirrel.h>
-
-#include "direction.hpp"
-#include "video/color.hpp"
-#include "scripting/ssector.hpp"
-
-namespace lisp {
-class Lisp;
-class Writer;
-}
-namespace collision {
-class Constraints;
-}
-
-class Vector;
-class Rect;
-class Sprite;
-class GameObject;
-class Player;
-class Camera;
-class TileMap;
-class Bullet;
-class ScriptInterpreter;
-class SpawnPoint;
-class MovingObject;
-class CollisionHit;
-class Level;
-class Portable;
-class DrawingContext;
-
-enum MusicType {
- LEVEL_MUSIC,
- HERRING_MUSIC,
- HERRING_WARNING_MUSIC
-};
-
-/**
- * This class holds a sector (a part of a level) and all the game objects in
- * the sector
- */
-class Sector : public Scripting::SSector
-{
-public:
- Sector(Level* parent);
- ~Sector();
-
- /// get parent level
- Level* get_level();
-
- /// read sector from lisp file
- void parse(const lisp::Lisp& lisp);
- void parse_old_format(const lisp::Lisp& lisp);
- /// write sector to lisp file
- void write(lisp::Writer& writer);
-
- /// activates this sector (change music, intialize player class, ...)
- void activate(const std::string& spawnpoint);
- void activate(const Vector& player_pos);
- void deactivate();
-
- void update(float elapsed_time);
- void update_game_objects();
-
- void draw(DrawingContext& context);
-
- /**
- * runs a script in the context of the sector (sector_table will be the
- * roottable of this squirrel VM)
- */
- HSQUIRRELVM run_script(std::istream& in, const std::string& sourcename);
-
- /// adds a gameobject
- void add_object(GameObject* object);
-
- void set_name(const std::string& name)
- { this->name = name; }
- const std::string& get_name() const
- { return name; }
-
- /**
- * tests if a given rectangle is inside the sector
- * (a rectangle that is on top of the sector is considered inside)
- */
- bool inside(const Rect& rectangle) const;
-
- void play_music(MusicType musictype);
- MusicType get_music_type();
-
- bool add_bullet(const Vector& pos, float xm, Direction dir);
- bool add_smoke_cloud(const Vector& pos);
-
- /** get currently activated sector. */
- static Sector* current()
- { return _current; }
-
- /** Get total number of badguys */
- int get_total_badguys();
-
- /** Get total number of GameObjects of given type */
- template<class T> int get_total_count()
- {
- int total = 0;
- for(GameObjects::iterator i = gameobjects.begin(); i != gameobjects.end(); ++i) {
- if (dynamic_cast<T*>(*i)) total++;
- }
- return total;
- }
-
- void collision_tilemap(collision::Constraints* constraints,
- const Vector& movement, const Rect& dest) const;
-
- /**
- * Checks if the specified rectangle is free of (solid) tiles.
- * Note that this does not include static objects, e.g. bonus blocks.
- */
- bool is_free_of_tiles(const Rect& rect, const bool ignoreUnisolid = false) const;
- /**
- * Checks if the specified rectangle is free of both
- * 1.) solid tiles and
- * 2.) MovingObjects in COLGROUP_STATIC.
- * Note that this does not include badguys or players.
- */
- bool is_free_of_statics(const Rect& rect, const MovingObject* ignore_object = 0, const bool ignoreUnisolid = false) const;
- /**
- * Checks if the specified rectangle is free of both
- * 1.) solid tiles and
- * 2.) MovingObjects in COLGROUP_STATIC, COLGROUP_MOVINGSTATIC or COLGROUP_MOVING.
- * This includes badguys and players.
- */
- bool is_free_of_movingstatics(const Rect& rect, const MovingObject* ignore_object = 0) const;
-
- /**
- * returns a list of players currently in the sector
- */
- std::vector<Player*> get_players() {
- return std::vector<Player*>(1, this->player);
- }
-
- Rect get_active_region();
-
- /**
- * returns the width (in px) of a sector)
- */
- float get_width() const;
-
- /**
- * returns the height (in px) of a sector)
- */
- float get_height() const;
-
- /**
- * globally changes solid tilemaps' tile ids
- */
- void change_solid_tiles(uint32_t old_tile_id, uint32_t new_tile_id);
-
- typedef std::vector<GameObject*> GameObjects;
- typedef std::vector<MovingObject*> MovingObjects;
- typedef std::vector<SpawnPoint*> SpawnPoints;
- typedef std::vector<Portable*> Portables;
-
- // --- Scripting ---
- /**
- * get/set color of ambient light
- */
- void set_ambient_light(float red, float green, float blue);
- float get_ambient_red();
- float get_ambient_green();
- float get_ambient_blue();
-
-private:
- Level* level; /**< Parent level containing this sector */
- uint32_t collision_tile_attributes(const Rect& dest) const;
-
- void before_object_remove(GameObject* object);
- bool before_object_add(GameObject* object);
-
- void try_expose(GameObject* object);
- void try_unexpose(GameObject* object);
- void try_expose_me();
- void try_unexpose_me();
-
- /** Checks for all possible collisions. And calls the
- collision_handlers, which the collision_objects provide for this
- case (or not). */
- void handle_collisions();
-
- /**
- * Does collision detection between 2 objects and does instant
- * collision response handling in case of a collision
- */
- void collision_object(MovingObject* object1, MovingObject* object2) const;
-
- /**
- * Does collision detection of an object against all other static
- * objects (and the tilemap) in the level. Collision response is done
- * for the first hit in time. (other hits get ignored, the function
- * should be called repeatedly to resolve those)
- *
- * returns true if the collision detection should be aborted for this object
- * (because of ABORT_MOVE in the collision response or no collisions)
- */
- void collision_static(collision::Constraints* constraints,
- const Vector& movement, const Rect& dest, GameObject& object);
-
- void collision_static_constrains(MovingObject& object);
-
- GameObject* parse_object(const std::string& name, const lisp::Lisp& lisp);
-
- void fix_old_tiles();
-
- static Sector* _current;
-
- std::string name;
-
- std::vector<Bullet*> bullets;
-
- std::string init_script;
-
- /// container for newly created objects, they'll be added in Sector::update
- GameObjects gameobjects_new;
-
- MusicType currentmusic;
-
- HSQOBJECT sector_table;
- /// sector scripts
- typedef std::vector<HSQOBJECT> ScriptList;
- ScriptList scripts;
-
- Color ambient_light;
-
-public: // TODO make this private again
- /// show collision rectangles of moving objects (for debugging)
- static bool show_collrects;
- static bool draw_solids_only;
-
- GameObjects gameobjects;
- MovingObjects moving_objects;
- SpawnPoints spawnpoints;
- Portables portables;
-
- std::string music;
- float gravity;
-
- // some special objects, where we need direct access
- // (try to avoid accessing them directly)
- Player* player;
- std::list<TileMap*> solid_tilemaps;
- Camera* camera;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux - A Jump'n Run
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#ifndef SUPERTUX_SERIALIZABLE_H
-#define SUPERTUX_SERIALIZABLE_H
-
-namespace lisp { class Writer; }
-
-class Serializable
-{
-public:
- virtual ~Serializable()
- { }
-
- virtual void write(lisp::Writer& writer) = 0;
-};
-
-#endif /*SUPERTUX_SERIALIZABLE_H*/
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#include <config.h>
-
-#include "shrinkfade.hpp"
-#include "main.hpp"
-#include "video/drawing_context.hpp"
-
-ShrinkFade::ShrinkFade(const Vector& dest, float fade_time)
- : dest(dest), fade_time(fade_time), accum_time(0)
-{
- speedleft = dest.x / fade_time;
- speedright = (SCREEN_WIDTH - dest.x) / fade_time;
- speedtop = dest.y / fade_time;
- speedbottom = (SCREEN_HEIGHT - dest.y) / fade_time;
-}
-
-ShrinkFade::~ShrinkFade()
-{
-}
-
-void
-ShrinkFade::update(float elapsed_time)
-{
- accum_time += elapsed_time;
- if(accum_time > fade_time)
- accum_time = fade_time;
-}
-
-void
-ShrinkFade::draw(DrawingContext& context)
-{
- Color black(0, 0, 0);
- float left = speedleft * accum_time;
- float top = speedtop * accum_time;
- float right = SCREEN_WIDTH - speedright * accum_time;
- float bottom = SCREEN_HEIGHT - speedbottom * accum_time;
-
- context.draw_filled_rect(Vector(0, 0),
- Vector(left, SCREEN_HEIGHT),
- black, LAYER_GUI+1);
- context.draw_filled_rect(Vector(0, 0),
- Vector(SCREEN_WIDTH, top),
- black, LAYER_GUI+1);
- context.draw_filled_rect(Vector(right, 0),
- Vector(SCREEN_WIDTH, SCREEN_HEIGHT),
- black, LAYER_GUI+1);
- context.draw_filled_rect(Vector(0, bottom),
- Vector(SCREEN_WIDTH, SCREEN_HEIGHT),
- black, LAYER_GUI+1);
-}
-
-bool
-ShrinkFade::done()
-{
- return accum_time >= fade_time;
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#ifndef __SHRINKFADE_HPP__
-#define __SHRINKFADE_HPP__
-
-#include "screen_fade.hpp"
-#include "math/vector.hpp"
-
-/**
- * Shrinks a rectangle screen towards a specific position
- */
-class ShrinkFade : public ScreenFade
-{
-public:
- ShrinkFade(const Vector& point, float fade_time);
- virtual ~ShrinkFade();
-
- virtual void update(float elapsed_time);
- virtual void draw(DrawingContext& context);
-
- virtual bool done();
-
-private:
- Vector dest;
- float fade_time;
- float accum_time;
- float speedleft, speedright, speedtop, speedbottom;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include <stdexcept>
-#include <iostream>
-#include "spawn_point.hpp"
-#include "lisp/lisp.hpp"
-#include "lisp/list_iterator.hpp"
-#include "log.hpp"
-
-SpawnPoint::SpawnPoint()
-{}
-
-SpawnPoint::SpawnPoint(const SpawnPoint& other)
- : name(other.name), pos(other.pos)
-{}
-
-SpawnPoint::SpawnPoint(const lisp::Lisp* slisp)
-{
- pos.x = -1;
- pos.y = -1;
- lisp::ListIterator iter(slisp);
- while(iter.next()) {
- const std::string& token = iter.item();
- if(token == "name") {
- iter.value()->get(name);
- } else if(token == "x") {
- iter.value()->get(pos.x);
- } else if(token == "y") {
- iter.value()->get(pos.y);
- } else {
- log_warning << "unknown token '" << token << "' in SpawnPoint" << std::endl;
- }
- }
-
- if(name == "")
- throw std::runtime_error("No name specified for spawnpoint");
- if(pos.x < 0 || pos.y < 0)
- throw std::runtime_error("Invalid coordinates for spawnpoint");
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#ifndef __SPAWN_POINT_H__
-#define __SPAWN_POINT_H__
-
-#include <string>
-#include "math/vector.hpp"
-namespace lisp { class Lisp; }
-
-class SpawnPoint
-{
-public:
- SpawnPoint();
- SpawnPoint(const SpawnPoint& other);
- SpawnPoint(const lisp::Lisp* lisp);
-
- std::string name;
- Vector pos;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include <iostream>
-#include <cmath>
-#include <cassert>
-#include <stdexcept>
-
-
-#include "video/surface.hpp"
-#include "sprite.hpp"
-#include "video/drawing_context.hpp"
-#include "log.hpp"
-#include "timer.hpp"
-
-Sprite::Sprite(SpriteData& newdata)
- : data(newdata),
- frame(0),
- animation_loops(-1),
- angle(0.0f),
- color(1.0f, 1.0f, 1.0f, 1.0f)
-{
- action = data.get_action("normal");
- if(!action)
- action = data.actions.begin()->second;
- last_ticks = game_time;
-}
-
-Sprite::Sprite(const Sprite& other)
- : data(other.data), frame(other.frame),
- animation_loops(other.animation_loops),
- angle(0.0f),
- color(1.0f, 1.0f, 1.0f, 1.0f),
- action(other.action)
-{
- last_ticks = game_time;
-}
-
-Sprite::~Sprite()
-{
-}
-
-void
-Sprite::set_action(const std::string& name, int loops)
-{
- if(action && action->name == name)
- return;
-
- SpriteData::Action* newaction = data.get_action(name);
- if(!newaction) {
- log_debug << "Action '" << name << "' not found." << std::endl;
- return;
- }
-
- action = newaction;
- animation_loops = loops;
- frame = 0;
-}
-
-bool
-Sprite::animation_done()
-{
- return animation_loops == 0;
-}
-
-void
-Sprite::update()
-{
- if(animation_done())
- return;
-
- float frame_inc = action->fps * (game_time - last_ticks);
- last_ticks = game_time;
-
- frame += frame_inc;
-
- if(frame >= get_frames()) {
- frame = fmodf(frame, get_frames());
-
- animation_loops--;
- if(animation_done())
- frame = get_frames()-1;
- }
-}
-
-void
-Sprite::draw(DrawingContext& context, const Vector& pos, int layer)
-{
- assert(action != 0);
- update();
-
- if((int)frame >= get_frames() || (int)frame < 0)
- log_warning << "frame out of range: " << (int)frame << "/" << get_frames() << " at " << get_name() << "/" << get_action() << std::endl;
- else
- context.draw_surface(action->surfaces[(int)frame],
- pos - Vector(action->x_offset, action->y_offset),
- angle,
- color,
- blend,
- layer + action->z_order);
-}
-
-void
-Sprite::draw_part(DrawingContext& context, const Vector& source,
- const Vector& size, const Vector& pos, int layer)
-{
- assert(action != 0);
- update();
-
- int frameidx = (int) frame;
-
- if(frameidx >= get_frames() || frameidx < 0) {
-#ifndef DEBUG
- // in optimized mode we get some small rounding errors in floating point
- // number sometimes...
- log_warning << "frame out of range: " << frameidx << "/" << get_frames() << " at sprite: " << get_name() << "/" << get_action() << std::endl;
-#endif
- frameidx = get_frames() - 1;
- }
-
- context.draw_surface_part(action->surfaces[frameidx], source, size,
- pos - Vector(action->x_offset, action->y_offset),
- layer + action->z_order);
-}
-
-int
-Sprite::get_width() const
-{
- return (int) action->surfaces[get_frame()]->get_width();
-}
-
-int
-Sprite::get_height() const
-{
- return (int) action->surfaces[get_frame()]->get_height();
-}
-
-float
-Sprite::get_current_hitbox_x_offset() const
-{
- return action->x_offset;
-}
-
-float
-Sprite::get_current_hitbox_y_offset() const
-{
- return action->y_offset;
-}
-
-float
-Sprite::get_current_hitbox_width() const
-{
- return action->hitbox_w;
-}
-
-float
-Sprite::get_current_hitbox_height() const
-{
- return action->hitbox_h;
-}
-
-Rect
-Sprite::get_current_hitbox() const
-{
- return Rect(action->x_offset, action->y_offset, action->x_offset + action->hitbox_w, action->y_offset + action->hitbox_h);
-}
-
-void
-Sprite::set_fps(float new_fps)
-{
- action->fps = new_fps;
-}
-
-void
-Sprite::set_angle(float a)
-{
- angle = a;
-}
-
-float
-Sprite::get_angle() const
-{
- return angle;
-}
-
-void
-Sprite::set_color(const Color& c)
-{
- color = c;
-}
-
-Color
-Sprite::get_color() const
-{
- return color;
-}
-
-void
-Sprite::set_blend(const Blend& b)
-{
- blend = b;
-}
-
-Blend
-Sprite::get_blend() const
-{
- return blend;
-}
-
-/* EOF */
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef SUPERTUX_SPRITE_H
-#define SUPERTUX_SPRITE_H
-
-#include <string>
-#include <assert.h>
-
-#include "math/vector.hpp"
-#include "math/rect.hpp"
-#include "sprite_data.hpp"
-#include "video/color.hpp"
-#include "video/drawing_context.hpp"
-
-class Surface;
-class DrawingContext;
-class Blend;
-
-class Sprite
-{
-public:
- Sprite(SpriteData& data);
- Sprite(const Sprite& other);
- ~Sprite();
-
- /** Draw sprite, automatically calculates next frame */
- void draw(DrawingContext& context, const Vector& pos, int layer);
-
- void draw_part(DrawingContext& context, const Vector& source,
- const Vector& size, const Vector& pos, int layer);
-
- /** Set action (or state) */
- void set_action(const std::string& act, int loops = -1);
-
- /** Set number of animation cycles until animation stops */
- void set_animation_loops(int loops = -1)
- { animation_loops = loops; }
-
- /** Set framerate */
- void set_fps(float new_fps);
-
- /* Stop animation */
- void stop_animation()
- { animation_loops = 0; }
- /** Check if animation is stopped or not */
- bool animation_done();
-
- float get_fps() const
- { return action->fps; }
- /** Get current action total frames */
- int get_frames() const
- { return action->surfaces.size(); }
- /** Get sprite's name */
- const std::string& get_name() const
- { return data.name; }
- /** Get current action name */
- const std::string& get_action() const
- { return action->name; }
-
- int get_width() const;
- int get_height() const;
-
- /** return x-offset of current action's hitbox, relative to start of image */
- float get_current_hitbox_x_offset() const;
- /** return y-offset of current action's hitbox, relative to start of image */
- float get_current_hitbox_y_offset() const;
- /** return width of current action's hitbox */
- float get_current_hitbox_width() const;
- /** return height of current action's hitbox */
- float get_current_hitbox_height() const;
- /** return current action's hitbox, relative to 0,0 */
- Rect get_current_hitbox() const;
-
- /** Set the angle of the sprite rotation in degree */
- void set_angle(float angle);
-
- /** Get the angle of the sprite rotation in degree */
- float get_angle() const;
-
- void set_color(const Color& color);
-
- Color get_color() const;
-
- void set_blend(const Blend& blend);
-
- Blend get_blend() const;
-
- /** Get current frame */
- int get_frame() const
- { return (int)frame; }
- /** Set current frame */
- void set_frame(int frame)
- {
- this->frame = (float) (frame % get_frames());
- }
- Surface* get_frame(unsigned int frame)
- {
- assert(frame < action->surfaces.size());
- return action->surfaces[frame];
- }
-
-private:
- void update();
-
- SpriteData& data;
-
- float frame;
- int animation_loops;
- float last_ticks;
- float angle;
- Color color;
- Blend blend;
-
- SpriteData::Action* action;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include <iostream>
-#include <cmath>
-#include <sstream>
-#include <stdexcept>
-
-#include "sprite_data.hpp"
-#include "resources.hpp"
-#include "video/drawing_context.hpp"
-#include "lisp/list_iterator.hpp"
-#include "log.hpp"
-
-SpriteData::Action::Action()
-{
- x_offset = 0;
- y_offset = 0;
- hitbox_w = 0;
- hitbox_h = 0;
- z_order = 0;
- fps = 10;
-}
-
-SpriteData::Action::~Action()
-{
- for(std::vector<Surface*>::iterator i = surfaces.begin();
- i != surfaces.end(); ++i)
- delete *i;
-}
-
-SpriteData::SpriteData(const lisp::Lisp* lisp, const std::string& basedir)
-{
- lisp::ListIterator iter(lisp);
- while(iter.next()) {
- if(iter.item() == "name") {
- iter.value()->get(name);
- } else if(iter.item() == "action") {
- parse_action(iter.lisp(), basedir);
- } else {
- log_warning << "Unknown sprite field: " << iter.item() << std::endl;
- }
- }
- if(actions.empty())
- throw std::runtime_error("Error: Sprite wihtout actions.");
-}
-
-SpriteData::~SpriteData()
-{
- for(Actions::iterator i=actions.begin(); i != actions.end(); ++i)
- delete i->second;
-}
-
-void
-SpriteData::parse_action(const lisp::Lisp* lisp, const std::string& basedir)
-{
- Action* action = new Action;
-
- if(!lisp->get("name", action->name)) {
- if(!actions.empty())
- throw std::runtime_error(
- "If there are more than one action, they need names!");
- }
- std::vector<float> hitbox;
- if (lisp->get_vector("hitbox", hitbox)) {
- if (hitbox.size() != 4) throw std::runtime_error("hitbox must specify exactly 4 coordinates");
- action->x_offset = hitbox[0];
- action->y_offset = hitbox[1];
- action->hitbox_w = hitbox[2];
- action->hitbox_h = hitbox[3];
- }
- lisp->get("z-order", action->z_order);
- lisp->get("fps", action->fps);
-
- std::string mirror_action;
- lisp->get("mirror-action", mirror_action);
- if(!mirror_action.empty()) {
- Action* act_tmp = get_action(mirror_action);
- if(act_tmp == NULL) {
- throw std::runtime_error("Could not mirror action. Action not found\n"
- "Mirror actions must be defined after the real one!");
- } else {
- float max_w = 0;
- float max_h = 0;
- for(int i = 0; static_cast<unsigned int>(i) < act_tmp->surfaces.size();
- i++) {
- Surface* surface = new Surface(*(act_tmp->surfaces[i]));
- surface->hflip();
- max_w = std::max(max_w, (float) surface->get_width());
- max_h = std::max(max_h, (float) surface->get_height());
- action->surfaces.push_back(surface);
- }
- if (action->hitbox_w < 1) action->hitbox_w = max_w;
- if (action->hitbox_h < 1) action->hitbox_h = max_h;
- }
- } else { // Load images
- std::vector<std::string> images;
- if(!lisp->get_vector("images", images)) {
- std::stringstream msg;
- msg << "Sprite '" << name << "' contains no images in action '"
- << action->name << "'.";
- throw std::runtime_error(msg.str());
- }
-
- float max_w = 0;
- float max_h = 0;
- for(std::vector<std::string>::size_type i = 0; i < images.size(); i++) {
- Surface* surface = new Surface(basedir + images[i]);
- max_w = std::max(max_w, (float) surface->get_width());
- max_h = std::max(max_h, (float) surface->get_height());
- action->surfaces.push_back(surface);
- }
- if (action->hitbox_w < 1) action->hitbox_w = max_w;
- if (action->hitbox_h < 1) action->hitbox_h = max_h;
- }
- actions[action->name] = action;
-}
-
-SpriteData::Action*
-SpriteData::get_action(std::string act)
-{
- Actions::iterator i = actions.find(act);
- if(i == actions.end()) {
- return 0;
- }
- return i->second;
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef SUPERTUX_SPRITE_DATA_H
-#define SUPERTUX_SPRITE_DATA_H
-
-#include <string>
-#include <vector>
-#include <map>
-
-#include "lisp/lisp.hpp"
-#include "video/surface.hpp"
-
-class SpriteData
-{
-public:
- /** cur has to be a pointer to data in the form of ((hitbox 5 10 0 0) ...) */
- SpriteData(const lisp::Lisp* cur, const std::string& basedir);
- ~SpriteData();
-
- const std::string& get_name() const
- {
- return name;
- }
-
-private:
- friend class Sprite;
-
- struct Action
- {
- Action();
- ~Action();
-
- std::string name;
-
- /** Position correction */
- float x_offset;
- float y_offset;
-
- /** Hitbox width */
- float hitbox_w;
-
- /** Hitbox height */
- float hitbox_h;
-
- /** Drawing priority in queue */
- int z_order;
-
- /** Frames per second */
- float fps;
-
- std::vector<Surface*> surfaces;
- };
-
- typedef std::map <std::string, Action*> Actions;
- Actions actions;
-
- void parse_action(const lisp::Lisp* lispreader, const std::string& basedir);
- /** Get an action */
- Action* get_action(std::string act);
-
- std::string name;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include <iostream>
-#include <sstream>
-#include <stdexcept>
-
-#include "sprite_manager.hpp"
-#include "sprite_data.hpp"
-#include "sprite.hpp"
-#include "lisp/lisp.hpp"
-#include "lisp/parser.hpp"
-#include "lisp/list_iterator.hpp"
-#include "file_system.hpp"
-#include "log.hpp"
-
-SpriteManager* sprite_manager = NULL;
-
-SpriteManager::SpriteManager()
-{
-}
-
-SpriteManager::~SpriteManager()
-{
- for(Sprites::iterator i = sprites.begin(); i != sprites.end(); ++i) {
- delete i->second;
- }
-}
-
-Sprite*
-SpriteManager::create(const std::string& name)
-{
- Sprites::iterator i = sprites.find(name);
- SpriteData* data;
- if(i == sprites.end()) {
- // try loading the spritefile
- data = load(name);
- if(data == NULL) {
- std::stringstream msg;
- msg << "Sprite '" << name << "' not found.";
- throw std::runtime_error(msg.str());
- }
- } else {
- data = i->second;
- }
-
- return new Sprite(*data);
-}
-
-SpriteData*
-SpriteManager::load(const std::string& filename)
-{
- lisp::Parser parser;
- const lisp::Lisp* root;
-
- try {
- root = parser.parse(filename);
- } catch(const std::exception& e) {
- std::ostringstream msg;
- msg << "Parse error when trying to load sprite '" << filename
- << "': " << e.what() << "\n";
- throw std::runtime_error(msg.str());
- }
-
- const lisp::Lisp* sprite = root->get_lisp("supertux-sprite");
- if(!sprite) {
- std::ostringstream msg;
- msg << "'" << filename << "' is not a supertux-sprite file";
- throw std::runtime_error(msg.str());
- }
-
- std::auto_ptr<SpriteData> data (
- new SpriteData(sprite, FileSystem::dirname(filename)) );
- sprites[filename] = data.release();
-
- return sprites[filename];
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef SUPERTUX_SPRITE_MANAGER_H
-#define SUPERTUX_SPRITE_MANAGER_H
-
-#include <map>
-
-class SpriteData;
-class Sprite;
-
-class SpriteManager
-{
-private:
- typedef std::map<std::string, SpriteData*> Sprites;
- Sprites sprites;
-
-public:
- SpriteManager();
- ~SpriteManager();
-
- /** loads a sprite. */
- Sprite* create(const std::string& filename);
-
-private:
- SpriteData* load(const std::string& filename);
-};
-
-extern SpriteManager* sprite_manager;
-
-#endif
+++ /dev/null
-#
-# SuperTux - squirrel library build script
-# Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
-#
-# 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
-#
-
-## Add include/ to include directories
-
-INCLUDE_DIRECTORIES(${SUPERTUX_SOURCE_DIR}/src/squirrel/include/)
-
-## build list of source files
-
-FILE(GLOB SQUIRREL_SOURCES squirrel/*.cpp sqstdlib/*.cpp sqstdlib/*.c)
-
-## add additional compiler switches
-
-ADD_DEFINITIONS(-include ${CMAKE_BINARY_DIR}/config.h)
-
-## define a target for building the library
-
-ADD_LIBRARY(squirrel ${SQUIRREL_SOURCES})
+++ /dev/null
-Copyright (c) 2003-2007 Alberto Demichelis\r
-\r
-This software is provided 'as-is', without any \r
-express or implied warranty. In no event will the \r
-authors be held liable for any damages arising from \r
-the use of this software.\r
-\r
-Permission is granted to anyone to use this software \r
-for any purpose, including commercial applications, \r
-and to alter it and redistribute it freely, subject \r
-to the following restrictions:\r
-\r
- 1. The origin of this software must not be \r
- misrepresented; you must not claim that \r
- you wrote the original software. If you \r
- use this software in a product, an \r
- acknowledgment in the product \r
- documentation would be appreciated but is \r
- not required.\r
-\r
- 2. Altered source versions must be plainly \r
- marked as such, and must not be \r
- misrepresented as being the original \r
- software.\r
-\r
- 3. This notice may not be removed or \r
- altered from any source distribution.\r
------------------------------------------------------\r
-END OF COPYRIGHT
\ No newline at end of file
+++ /dev/null
-***version 2.1.2 stable***\r
--new behaviour for generators iteration using foreach\r
-now when a generator is iterated by foreach the value returned by a 'return val' statement\r
-will terminate the iteration but will not be returned as foreach iteration\r
--added sq_setclassudsize()\r
--added sq_clear()\r
--added table.clear(), array.clear()\r
--fixed sq_cmp() (thx jyuill)\r
--fixed minor bugs\r
-\r
-***2006-08-21 ***\r
-***version 2.1.1 stable***\r
--vm refactoring\r
--optimized internal function memory layout\r
--new global symbol _version_ (is the version string)\r
--code size optimization for float literals(on 32bits float builts)\r
--now the raw ref API(sq_addref etc...) is fully reentrant.\r
--fixed a bug in sq_getdelegate() now pushes null if the object doesn't have a delegate(thx MatzeB)\r
--improved C reference performances in NO_GARBAGE_COLLECTOR builds\r
--sq_getlocal() now enumerates also outer values.\r
--fixed regexp library for GCC users.\r
-\r
-***2006-03-19 ***\r
-***version 2.1 stable***\r
--added static class fields, new keyword static\r
--added 64bits architecture support\r
--added global slot _intsize_ int the base lib to recognize 32bits and 64bits builds\r
--added functions with fixed environment, closure.bindenv() built-in function\r
--all types except userdata and null implement the tostring() method\r
--string concatenation now invokes metamethod _tostring\r
--new metamethods for class objects _newmember and _inherited\r
--sq_call() sq_resume() sq_wakeupvm() have a new signature\r
--new C referencing implementation(scales more with the amount of references)\r
--refactored hash table\r
--new api functions sq_newslot(),sq_tobool(),sq_getbase(), sq_instanceof(), sq_bindenv()\r
--the api func sq_createslot was deprecated but still supported in form of C macro on top of sq_newslot\r
--sq_setreleasehook() now also works for classes\r
--stream.readstr() and stream.writestr() have been deprecated(this affects file and blob)\r
--fixed squirrel.h undeclared api calls\r
--fixed few minor bugs\r
--SQChar is now defined as wchar_t\r
--removed warning when building with -Wall -pedantic for GCC users\r
--added new std io function writeclosuretofile()\r
--added new std string functions strip(),rstrip(),lstrip() and split()\r
--regular expressions operators (+,*) now have more POSIX greedyness behaviour\r
--class constructors are now invoked as normal functions\r
-\r
-***2005-10-02 ***\r
-***version 2.0.5 stable***\r
--fixed some 64bits incompatibilities (thx sarge)\r
--fixed minor bug in the stdlib format() function (thx Rick)\r
--fixed a bug in dofile() that was preventing to compile empty files\r
--added new API sq_poptop() & sq_getfreevariable()\r
--some performance improvements\r
-\r
-***2005-08-14 ***\r
-***version 2.0.4 stable***\r
--weak references and related API calls\r
--added sq_objtobool()\r
--class instances memory policies improved(1 mem allocation for the whole instance)\r
--typetags are now declared as SQUserPointer instead of unsigned int\r
--first pass for 64bits compatibility\r
--fixed minor bug in the stdio stream\r
--fixed a bug in format()\r
--fixed bug in string.tointeger() and string.tofloat()\r
-\r
-***2005-06-24 ***\r
-***version 2.0.3 stable***\r
--dofile() and loadfile() in the iolib now can decode ASCII, UTF8 files UCS2 big-endian and little-endian\r
--sq_setparamscheck() : now typemesk can check for null\r
--added string escape sequence \xhhhh\r
--fixed some C++ standard incompatibilities\r
-\r
-***2005-05-15 ***\r
-***version 2.0.2 stable***\r
--performances improvements (expecially for GCC users)\r
--removed all dependencies from C++ exception handling\r
--various bugfixes\r
-\r
-***2005-04-12 ***\r
-***version 2.0.1 stable***\r
--various bugfixes\r
--sq_setparamscheck() now allows spaces in the typemask\r
-\r
-***2005-04-03 ***\r
-***version 2.0 stable***\r
--added API sq_gettypetag()\r
--added built-in function to the bool type(tointeger, tostring etc...)\r
-\r
-***2005-02-27 ***\r
-***version 2.0 release candidate 1(RC 1)***\r
--added API sq_reseterror()\r
--modified sq_release()\r
--now class instances can be cloned\r
--various bufixes\r
-\r
-***2005-01-26 ***\r
-***version 2.0 beta 1***\r
--added bool type\r
--class properties can be redefined in a derived class\r
--added ops *= /= and %=\r
--new syntax for class attributes declaration </ and /> instead of ( and )\r
--increased the max number of literals per function from 65535 to 16777215\r
--now free variables have proper lexical scoping\r
--added API sq_createinstance(), sq_pushbool(), sq_getbool()\r
--added built-in function type()\r
--added built-in function obj.rawin(key) in table,class and instance\r
--sq_rawget() and sq_rawset() now work also on classes and instances\r
--the VM no longer uses C++ exception handling (more suitable for embedded devices)\r
--various bufixes\r
-\r
-***2004-12-21 ***\r
-***version 2.0 alpha 2***\r
--globals scoping changed, now if :: is omitted the VM automatically falls back on the root table\r
--various bufixes\r
--added class level attributes\r
-\r
-***2004-12-12 ***\r
-***version 2.0 alpha 1***\r
--codebase branch from version 1.x\r
--added classes\r
--added functions with variable number of parameters(vargc & vargv and the ...)\r
--0 and 0.0 are now considered 'false' by all conditional statements(if,while,for,?,do-while)\r
--added new api functions sq_newclass() sq_setinstanceup() sq_getinstanceup() sq_getattributes() sq_setattributes()\r
--modified api sq_settypetag()\r
-\r
-***2004-11-01 ***\r
-***version 1.0 stable***\r
--fixed some minor bug\r
--improoved operator 'delete' performances\r
--added scientific notation for float numbers( eg. 2.e16 or 2.e-2)\r
-\r
-***2004-08-30 ***\r
-***version 1.0 release candidate 2(RC 2)***\r
--fixed bug in the vm(thx Pierre Renaux)\r
--fixed bug in the optimizer(thx Pierre Renaux)\r
--fixed some bug in the documentation(thx JD)\r
--added new api functions for raw object handling\r
--removed nested multiline comments\r
--reduced memory footprint in C references\r
-\r
-***2004-08-23 ***\r
-***version 1.0 release candidate 1(RC 1)***\r
--fixed division by zero\r
--the 'in' operator and obj.rawget() do not query the default delegate anymore\r
--added function sq_getprintfunc()\r
--added new standard library 'auxlib'(implements default error handlers)\r
-\r
-***2004-07-12 ***\r
-***version 1.0 beta 4***\r
--fixed a bug in the integer.tochar() built-in method\r
--fixed unary minus operator\r
--fixed bug in dofile()\r
--fixed inconsistency between != and == operators(on float/integer comparison)\r
--added javascript style unsigned right shift operator '>>>'\r
--added array(size) constructor built-in function\r
--array.resize(size,[fill]) built-in function accepts an optional 'fill' value\r
--improved debug API, added sq_getclosureinfo() and sq_setnativeclosurename()\r
-\r
-***2004-05-23 ***\r
-***version 1.0 beta 3***\r
--minor vm bug fixes\r
--string allocation is now faster\r
--tables and array memory usage is now less conservative(they shrink)\r
--added regular expression routines in the standard library\r
--The 'c' expression now accepts only 1 character(thx irbrian)\r
--multiline strings <[ ]> have been substituted with C# style verbatim strings (eg. @"string")\r
--added new keyword 'parent' for accessing the delegate of tables and unserdata\r
--The metamethod '_clone' has been renamed '_cloned'\r
--the _delslot metamethod's behaviour and prototype have been changed\r
--new default function in the integer and float object 'tochar()'\r
--the built-in function chcode2string has been removed\r
--the default method [table].getdelegate() has been removed\r
--new api sq_rawdeleteslot()\r
--new table built-in method rawdelete(key)\r
--the dynamic mudule loading has been removed from the standard distribution\r
--some optimizations in the VM\r
-\r
-***2004-04-21 ***\r
-***version 1.0 beta 2***\r
--minor compiler/parser bug fixes\r
--sq_newclosure has a different prototype, the "paramscheck" of paramter has been moved to the new function sq_setparamscheck()\r
--sq_setparamscheck allows to add automatic parameters type checking in native closures\r
--sq_compile() lost the lineinfo parameter\r
--new api sq_enabledebuginfo() globally sets compiler's debug info generation\r
--added consistency check on bytecode serialization\r
--fixed += operator, now works on strings like +\r
--added global slot in the base lib _charsize_ to recognize unicode builds from ascii builds runtime\r
--added registry table\r
--new api call sq_pushregistrytable()\r
--added type tag to the userdata type sq_settypetag()\r
--sq_getuserdata now queries the userdata typetag\r
--the built in function collect_garbage() as been renamed collectgarbage() for consistency reasons\r
--new standard libraries(sqlibs are now obsolete)\r
-\r
-***2004-02-20 ***\r
-***version 1.0 beta 1***\r
--fixed a bug in the compiler (thanks Martin Kofler)\r
--fixed bug in the switch case statement\r
--fixed the _unm metamethod\r
--fixed minor bugs in the API\r
--fixed automatic stack resizing\r
--first beta version \r
- first pass code clean up in the VM and base lib\r
- first pass code coverege test has been done on VM and built-in lib\r
--new VM creation API sq_open() sq_close() (sq_newvm and sq_releasevm are now obsolete)\r
--new api allows to specifiy a "print" function to output text(sq_printfunc)\r
--added some small optimizations\r
--new cooperative multi-threading capabilities in the base library(coroutines), VMs are now a built in type("thread")\r
--new built in functions have been added for manipulating the new "thread" type\r
--friend virtual machines share the same root table, error handler and debug hook by default\r
--new compile time options\r
-\r
-***2004-01-19 ***\r
-***version 0.9 alpha***\r
--fixed a garbage collection bug\r
--fixed some API bugs(thanks to Joshua Jensen)\r
--fixed tail calls (in the version 0.8 the tail call optimization was erroneously disabled)\r
--new function parameters semantic, now passing a wrong number of parameters generates an exception\r
--native closures have now a built in parameter number checking\r
--sq_rawget and sq_rawset now work also on arrays\r
--sq_getsize now woks also on userdata\r
--the userdata release hook prototype is changed(now passes the size of the userdata)\r
--the lexer reader function now returns an integer instead of a char that allows better error checking on the input(thx Joshua Jensen)\r
--faster compiler\r
--try/catch blocks do not cause any runtime memory allocation anymore\r
-\r
-***2003-12-06 ***\r
-***version 0.8 alpha***\r
--fixed a bug that was preventing to have callable userdata throught the metamethod _call\r
--fixed a garbage collection bug\r
--fixed == operator now can compare correctly different types\r
--new built in method getstackinfos(level)\r
--improoved line informations precision for the debug hook\r
--new api call sq_compilebuffer()\r
--new built-in api function compilestring()\r
--new syntactic sugar for function declarations inside tables\r
--the debug API has been finalized\r
-\r
-***2003-11-17 ***\r
-***version 0.7 alpha***\r
--fixed critical bug SQInteger the tail call system\r
--fixed bug in the continue statement code generation\r
--fixed func call param issue(thanks to Rewoonenco Andrew)\r
--added _delslot metamethod(thanks to Rewoonenco Andrew)\r
--new multiline string expression ( delimited by <[ and ]> )\r
--normal strings ("") do not allow embedded new line anymore\r
--reduced vm memory footprint(C refs are shared between friend VMs)\r
--new api method sq_deleteslot()\r
--new debug hook event 'r' is triggered when a function returns\r
-\r
-***2003-11-04 ***\r
-***version 0.6 alpha***\r
--fixed switch statement(was executing the default case after a break)\r
--sq_call() doesn't pop the closure (just the params)\r
--the vm execution can be suspended from the C API anytime (micro-threads)\r
--new api calls sq_suspendvm() sq_wakeupvm() sq_getvmstate() and sq_reservestack()\r
-\r
-***2003-10-13 ***\r
-***version 0.5 alpha***\r
--fixed some minor bug\r
--tested with non ASCII identifiers in unicode mode(I've tried chinese chars)\r
--added built-in function string.find()\r
--the built-in function array.sort() optionally accepts a cmp(a,b) function\r
--the debug hook function now has a new prototype debug_hook(event_type,sourcefile,line,functionname)\r
--fixed some debug info imprecision\r
-\r
-***2003-10-01 ***\r
-***version 0.4 alpha***\r
--faster VM\r
--sq_call will pop arguments and closure also in case of failure\r
--fixed a bug in sq_remove\r
--now the VM detects delegation cycles(and throws an exception)\r
--new operators ++ and --\r
--new operator ',' comma operator\r
--fixed some expression precedence issue\r
--fixed bug in sq_arraypop\r
-\r
-***2003-09-15 ***\r
-***version 0.3 alpha***\r
--fixed a bug in array::insert()\r
--optional Unicode core(define SQUNICODE or _UNICODE on Win32)\r
--sq_compiler uses a new reader function SQLEXREADFUNC\r
--the debug hook passes 'l' instead of 'line' for line callbacks\r
- and 'c' instead of 'call' for call callbacks\r
--new array.extend() bulit-in function\r
--new API sq_clone()\r
-\r
-***2003-09-10 ***\r
-***version 0.2 pre-alpha***\r
--new completely reentrant VM (sq_open and sq_close are now obsolete)\r
--sq_newvm() has a new prototype\r
--allocators are now global and linked in the VM\r
--_newslot meta method added\r
--rawset creates a slot if doesn't exists\r
--the compiler error callback pass the vm handle(thanks Pierre Renaux)\r
--sq_setforeignptr() sq_getforeingptr() are now public\r
--sq_resume() now is possible to resume generators from C\r
--sq_getlasterror() retrieve the last thrown error\r
--improved docs\r
-\r
-***2003-09-06 ***\r
-***version 0.1 pre-alpha***\r
-first release\r
+++ /dev/null
-SubDir TOP src squirrel ;
-
-SQDBG_SOURCES = [ Wildcard sqdbg : *.cpp *.h *.inl ] ;
-if $(enable_sqdbg) = "yes" {
- EXTRA_SOURCES = $(SQDBG_SOURCES) ;
-} else {
- Package $(SQDBG_SOURCES) ;
-}
-
-Library squirrel
- : [ Wildcard squirrel : *.cpp *.h ]
- [ Wildcard sqstdlib : *.cpp *.c *.h ]
- $(EXTRA_SOURCES)
- : noinstall
-;
-
-for i in $(squirrel_OBJECTS) {
- CXXFLAGS on $(i) = [ Filter [ on $(i) GetVar CXXFLAGS ] : -Wall -W -Werror ] -include $(top_builddir)/config.h ;
- CFLAGS on $(i) = [ Filter [ on $(i) GetVar CFLAGS ] : -Wall -W -Werror ] -include $(top_builddir)/config.h ;
-}
-IncludeDir squirrel : include ;
-Package [ Wildcard include : *.h ] ;
+++ /dev/null
-The programming language SQUIRREL 2.1.2 stable\r
-\r
---------------------------------------------------\r
-The project has been compiled and run on Windows(Windows XP/2000 on Intel x86 Windows XP Pro on AMD x64) and\r
-Linux(Slackware 9.0 on Intel x86, Fedora Core 4 on AMD x64).\r
-\r
-Has been tested with the following compilers:\r
- MS Visual C++ 6.0,7.0,7.1 and 8.0 (32 and 64bits)\r
- MinGW gcc 3.2 (mingw special 20020817-1)\r
- Cygnus gcc 3.2\r
- Linux gcc 3.2.3\r
- Linux gcc 4.0.0 (x86 64bits)\r
- \r
-\r
-Feedback and suggestions are appreciated \r
-project page - http://www.squirrel-lang.org\r
-community forums - http://www.squirrel-lang.org/Forums\r
-wiki - http://wiki.squirrel-lang.org\r
-author - alberto@ademichelis.com\r
-\r
-END OF README\r
-\r
+++ /dev/null
-/* see copyright notice in squirrel.h */
-#ifndef _SQSTD_AUXLIB_H_
-#define _SQSTD_AUXLIB_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-SQUIRREL_API void sqstd_seterrorhandlers(HSQUIRRELVM v);
-SQUIRREL_API void sqstd_printcallstack(HSQUIRRELVM v);
-
-#ifdef __cplusplus
-} /*extern "C"*/
-#endif
-
-#endif /* _SQSTD_AUXLIB_H_ */
+++ /dev/null
-/* see copyright notice in squirrel.h */
-#ifndef _SQSTDBLOB_H_
-#define _SQSTDBLOB_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-SQUIRREL_API SQUserPointer sqstd_createblob(HSQUIRRELVM v, SQInteger size);
-SQUIRREL_API SQRESULT sqstd_getblob(HSQUIRRELVM v,SQInteger idx,SQUserPointer *ptr);
-SQUIRREL_API SQInteger sqstd_getblobsize(HSQUIRRELVM v,SQInteger idx);
-
-SQUIRREL_API SQRESULT sqstd_register_bloblib(HSQUIRRELVM v);
-
-#ifdef __cplusplus
-} /*extern "C"*/
-#endif
-
-#endif /*_SQSTDBLOB_H_*/
-
+++ /dev/null
-/* see copyright notice in squirrel.h */
-#ifndef _SQSTDIO_H_
-#define _SQSTDIO_H_
-
-#ifdef __cplusplus
-
-#define SQSTD_STREAM_TYPE_TAG 0x80000000
-
-struct SQStream {
-
- // [SuperTux] Added virtual destructor to avoid compiler warnings
- virtual ~SQStream() { };
-
- virtual SQInteger Read(void *buffer, SQInteger size) = 0;
- virtual SQInteger Write(void *buffer, SQInteger size) = 0;
- virtual SQInteger Flush() = 0;
- virtual SQInteger Tell() = 0;
- virtual SQInteger Len() = 0;
- virtual SQInteger Seek(SQInteger offset, SQInteger origin) = 0;
- virtual bool IsValid() = 0;
- virtual bool EOS() = 0;
-};
-
-extern "C" {
-#endif
-
-#define SQ_SEEK_CUR 0
-#define SQ_SEEK_END 1
-#define SQ_SEEK_SET 2
-
-typedef void* SQFILE;
-
-SQUIRREL_API SQFILE sqstd_fopen(const SQChar *,const SQChar *);
-SQUIRREL_API SQInteger sqstd_fread(SQUserPointer, SQInteger, SQInteger, SQFILE);
-SQUIRREL_API SQInteger sqstd_fwrite(const SQUserPointer, SQInteger, SQInteger, SQFILE);
-SQUIRREL_API SQInteger sqstd_fseek(SQFILE , SQInteger , SQInteger);
-SQUIRREL_API SQInteger sqstd_ftell(SQFILE);
-SQUIRREL_API SQInteger sqstd_fflush(SQFILE);
-SQUIRREL_API SQInteger sqstd_fclose(SQFILE);
-SQUIRREL_API SQInteger sqstd_feof(SQFILE);
-
-SQUIRREL_API SQRESULT sqstd_createfile(HSQUIRRELVM v, SQFILE file,SQBool own);
-SQUIRREL_API SQRESULT sqstd_getfile(HSQUIRRELVM v, SQInteger idx, SQFILE *file);
-
-//compiler helpers
-SQUIRREL_API SQRESULT sqstd_loadfile(HSQUIRRELVM v,const SQChar *filename,SQBool printerror);
-SQUIRREL_API SQRESULT sqstd_dofile(HSQUIRRELVM v,const SQChar *filename,SQBool retval,SQBool printerror);
-SQUIRREL_API SQRESULT sqstd_writeclosuretofile(HSQUIRRELVM v,const SQChar *filename);
-
-SQUIRREL_API SQRESULT sqstd_register_iolib(HSQUIRRELVM v);
-
-#ifdef __cplusplus
-} /*extern "C"*/
-#endif
-
-#endif /*_SQSTDIO_H_*/
-
+++ /dev/null
-/* see copyright notice in squirrel.h */
-#ifndef _SQSTD_MATH_H_
-#define _SQSTD_MATH_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-SQUIRREL_API SQRESULT sqstd_register_mathlib(HSQUIRRELVM v);
-
-#ifdef __cplusplus
-} /*extern "C"*/
-#endif
-
-#endif /*_SQSTD_MATH_H_*/
+++ /dev/null
-/* see copyright notice in squirrel.h */
-#ifndef _SQSTD_STRING_H_
-#define _SQSTD_STRING_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef unsigned int SQRexBool;
-typedef struct SQRex SQRex;
-
-typedef struct {
- const SQChar *begin;
- SQInteger len;
-} SQRexMatch;
-
-SQUIRREL_API SQRex *sqstd_rex_compile(const SQChar *pattern,const SQChar **error);
-SQUIRREL_API void sqstd_rex_free(SQRex *exp);
-SQUIRREL_API SQBool sqstd_rex_match(SQRex* exp,const SQChar* text);
-SQUIRREL_API SQBool sqstd_rex_search(SQRex* exp,const SQChar* text, const SQChar** out_begin, const SQChar** out_end);
-SQUIRREL_API SQBool sqstd_rex_searchrange(SQRex* exp,const SQChar* text_begin,const SQChar* text_end,const SQChar** out_begin, const SQChar** out_end);
-SQUIRREL_API SQInteger sqstd_rex_getsubexpcount(SQRex* exp);
-SQUIRREL_API SQBool sqstd_rex_getsubexp(SQRex* exp, SQInteger n, SQRexMatch *subexp);
-
-SQUIRREL_API SQRESULT sqstd_register_stringlib(HSQUIRRELVM v);
-
-#ifdef __cplusplus
-} /*extern "C"*/
-#endif
-
-#endif /*_SQSTD_STRING_H_*/
+++ /dev/null
-/* see copyright notice in squirrel.h */
-#ifndef _SQSTD_SYSTEMLIB_H_
-#define _SQSTD_SYSTEMLIB_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-SQUIRREL_API SQInteger sqstd_register_systemlib(HSQUIRRELVM v);
-
-#ifdef __cplusplus
-} /*extern "C"*/
-#endif
-
-#endif /* _SQSTD_SYSTEMLIB_H_ */
+++ /dev/null
-/*
-Copyright (c) 2003-2007 Alberto Demichelis
-
-This software is provided 'as-is', without any
-express or implied warranty. In no event will the
-authors be held liable for any damages arising from
-the use of this software.
-
-Permission is granted to anyone to use this software
-for any purpose, including commercial applications,
-and to alter it and redistribute it freely, subject
-to the following restrictions:
-
- 1. The origin of this software must not be
- misrepresented; you must not claim that
- you wrote the original software. If you
- use this software in a product, an
- acknowledgment in the product
- documentation would be appreciated but is
- not required.
-
- 2. Altered source versions must be plainly
- marked as such, and must not be
- misrepresented as being the original
- software.
-
- 3. This notice may not be removed or
- altered from any source distribution.
-
-*/
-#ifndef _SQUIRREL_H_
-#define _SQUIRREL_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#ifndef SQUIRREL_API
-#define SQUIRREL_API extern
-#endif
-
-#ifdef _SQ64
-#ifdef _MSC_VER
-typedef __int64 SQInteger;
-typedef unsigned __int64 SQUnsignedInteger;
-typedef unsigned __int64 SQHash; /*should be the same size of a pointer*/
-#else
-typedef long SQInteger;
-typedef unsigned long SQUnsignedInteger;
-typedef unsigned long SQHash; /*should be the same size of a pointer*/
-#endif
-typedef int SQInt32;
-#else
-typedef int SQInteger;
-typedef int SQInt32; /*must be 32 bits(also on 64bits processors)*/
-typedef unsigned int SQUnsignedInteger;
-typedef unsigned int SQHash; /*should be the same size of a pointer*/
-#endif
-
-typedef float SQFloat;
-typedef void* SQUserPointer;
-typedef SQUnsignedInteger SQBool;
-typedef SQInteger SQRESULT;
-
-#define SQTrue (1)
-#define SQFalse (0)
-
-
-struct SQVM;
-struct SQTable;
-struct SQArray;
-struct SQString;
-struct SQClosure;
-struct SQGenerator;
-struct SQNativeClosure;
-struct SQUserData;
-struct SQFunctionProto;
-struct SQRefCounted;
-struct SQClass;
-struct SQInstance;
-struct SQDelegable;
-
-#ifdef _UNICODE
-#define SQUNICODE
-#endif
-
-#ifdef SQUNICODE
-#if (defined(_MSC_VER) && _MSC_VER >= 1400) // 1400 = VS8
-
-#if defined(wchar_t) //this is if the compiler considers wchar_t as native type
-#define wchar_t unsigned short
-#endif
-
-#else
-typedef unsigned short wchar_t;
-#endif
-
-typedef wchar_t SQChar;
-#define _SC(a) L##a
-#define scstrcmp wcscmp
-#define scsprintf swprintf
-#define scstrlen wcslen
-#define scstrtod wcstod
-#define scstrtol wcstol
-#define scatoi _wtoi
-#define scstrtoul wcstoul
-#define scvsprintf vswprintf
-#define scstrstr wcsstr
-#define scisspace iswspace
-#define scisdigit iswdigit
-#define scisxdigit iswxdigit
-#define scisalpha iswalpha
-#define sciscntrl iswcntrl
-#define scisalnum iswalnum
-#define scprintf wprintf
-#define MAX_CHAR 0xFFFF
-#else
-typedef char SQChar;
-#define _SC(a) a
-#define scstrcmp strcmp
-#define scsprintf sprintf
-#define scstrlen strlen
-#define scstrtod strtod
-#define scstrtol strtol
-#define scatoi atoi
-#define scstrtoul strtoul
-#define scvsprintf vsprintf
-#define scstrstr strstr
-#define scisspace isspace
-#define scisdigit isdigit
-#define scisxdigit isxdigit
-#define sciscntrl iscntrl
-#define scisalpha isalpha
-#define scisalnum isalnum
-#define scprintf printf
-#define MAX_CHAR 0xFF
-#endif
-
-#define SQUIRREL_VERSION _SC("Squirrel 2.1.2 stable")
-#define SQUIRREL_COPYRIGHT _SC("Copyright (C) 2003-2007 Alberto Demichelis")
-#define SQUIRREL_AUTHOR _SC("Alberto Demichelis")
-
-#define SQ_VMSTATE_IDLE 0
-#define SQ_VMSTATE_RUNNING 1
-#define SQ_VMSTATE_SUSPENDED 2
-
-#define SQUIRREL_EOB 0
-#define SQ_BYTECODE_STREAM_TAG 0xFAFA
-
-#define SQOBJECT_REF_COUNTED 0x08000000
-#define SQOBJECT_NUMERIC 0x04000000
-#define SQOBJECT_DELEGABLE 0x02000000
-#define SQOBJECT_CANBEFALSE 0x01000000
-
-#define SQ_MATCHTYPEMASKSTRING (-99999)
-
-#define _RT_MASK 0x00FFFFFF
-#define _RAW_TYPE(type) (type&_RT_MASK)
-
-#define _RT_NULL 0x00000001
-#define _RT_INTEGER 0x00000002
-#define _RT_FLOAT 0x00000004
-#define _RT_BOOL 0x00000008
-#define _RT_STRING 0x00000010
-#define _RT_TABLE 0x00000020
-#define _RT_ARRAY 0x00000040
-#define _RT_USERDATA 0x00000080
-#define _RT_CLOSURE 0x00000100
-#define _RT_NATIVECLOSURE 0x00000200
-#define _RT_GENERATOR 0x00000400
-#define _RT_USERPOINTER 0x00000800
-#define _RT_THREAD 0x00001000
-#define _RT_FUNCPROTO 0x00002000
-#define _RT_CLASS 0x00004000
-#define _RT_INSTANCE 0x00008000
-#define _RT_WEAKREF 0x00010000
-
-typedef enum tagSQObjectType{
- OT_NULL = (_RT_NULL|SQOBJECT_CANBEFALSE),
- OT_INTEGER = (_RT_INTEGER|SQOBJECT_NUMERIC|SQOBJECT_CANBEFALSE),
- OT_FLOAT = (_RT_FLOAT|SQOBJECT_NUMERIC|SQOBJECT_CANBEFALSE),
- OT_BOOL = (_RT_BOOL|SQOBJECT_CANBEFALSE),
- OT_STRING = (_RT_STRING|SQOBJECT_REF_COUNTED),
- OT_TABLE = (_RT_TABLE|SQOBJECT_REF_COUNTED|SQOBJECT_DELEGABLE),
- OT_ARRAY = (_RT_ARRAY|SQOBJECT_REF_COUNTED),
- OT_USERDATA = (_RT_USERDATA|SQOBJECT_REF_COUNTED|SQOBJECT_DELEGABLE),
- OT_CLOSURE = (_RT_CLOSURE|SQOBJECT_REF_COUNTED),
- OT_NATIVECLOSURE = (_RT_NATIVECLOSURE|SQOBJECT_REF_COUNTED),
- OT_GENERATOR = (_RT_GENERATOR|SQOBJECT_REF_COUNTED),
- OT_USERPOINTER = _RT_USERPOINTER,
- OT_THREAD = (_RT_THREAD|SQOBJECT_REF_COUNTED) ,
- OT_FUNCPROTO = (_RT_FUNCPROTO|SQOBJECT_REF_COUNTED), //internal usage only
- OT_CLASS = (_RT_CLASS|SQOBJECT_REF_COUNTED),
- OT_INSTANCE = (_RT_INSTANCE|SQOBJECT_REF_COUNTED|SQOBJECT_DELEGABLE),
- OT_WEAKREF = (_RT_WEAKREF|SQOBJECT_REF_COUNTED)
-}SQObjectType;
-
-#define ISREFCOUNTED(t) (t&SQOBJECT_REF_COUNTED)
-
-
-typedef union tagSQObjectValue
-{
- struct SQTable *pTable;
- struct SQArray *pArray;
- struct SQClosure *pClosure;
- struct SQGenerator *pGenerator;
- struct SQNativeClosure *pNativeClosure;
- struct SQString *pString;
- struct SQUserData *pUserData;
- SQInteger nInteger;
- SQFloat fFloat;
- SQUserPointer pUserPointer;
- struct SQFunctionProto *pFunctionProto;
- struct SQRefCounted *pRefCounted;
- struct SQDelegable *pDelegable;
- struct SQVM *pThread;
- struct SQClass *pClass;
- struct SQInstance *pInstance;
- struct SQWeakRef *pWeakRef;
-}SQObjectValue;
-
-
-typedef struct tagSQObject
-{
- SQObjectType _type;
- SQObjectValue _unVal;
-}SQObject;
-
-typedef struct tagSQStackInfos{
- const SQChar* funcname;
- const SQChar* source;
- SQInteger line;
-}SQStackInfos;
-
-typedef struct SQVM* HSQUIRRELVM;
-typedef SQObject HSQOBJECT;
-typedef SQInteger (*SQFUNCTION)(HSQUIRRELVM);
-typedef SQInteger (*SQRELEASEHOOK)(SQUserPointer,SQInteger size);
-typedef void (*SQCOMPILERERROR)(HSQUIRRELVM,const SQChar * /*desc*/,const SQChar * /*source*/,SQInteger /*line*/,SQInteger /*column*/);
-typedef void (*SQPRINTFUNCTION)(HSQUIRRELVM,const SQChar * ,...);
-
-typedef SQInteger (*SQWRITEFUNC)(SQUserPointer,SQUserPointer,SQInteger);
-typedef SQInteger (*SQREADFUNC)(SQUserPointer,SQUserPointer,SQInteger);
-
-typedef SQInteger (*SQLEXREADFUNC)(SQUserPointer);
-
-typedef struct tagSQRegFunction{
- const SQChar *name;
- SQFUNCTION f;
- SQInteger nparamscheck;
- const SQChar *typemask;
-}SQRegFunction;
-
-/*vm*/
-SQUIRREL_API HSQUIRRELVM sq_open(SQInteger initialstacksize);
-SQUIRREL_API HSQUIRRELVM sq_newthread(HSQUIRRELVM friendvm, SQInteger initialstacksize);
-SQUIRREL_API void sq_seterrorhandler(HSQUIRRELVM v);
-SQUIRREL_API void sq_close(HSQUIRRELVM v);
-SQUIRREL_API void sq_setforeignptr(HSQUIRRELVM v,SQUserPointer p);
-SQUIRREL_API SQUserPointer sq_getforeignptr(HSQUIRRELVM v);
-SQUIRREL_API void sq_setprintfunc(HSQUIRRELVM v, SQPRINTFUNCTION printfunc);
-SQUIRREL_API SQPRINTFUNCTION sq_getprintfunc(HSQUIRRELVM v);
-SQUIRREL_API SQRESULT sq_suspendvm(HSQUIRRELVM v);
-SQUIRREL_API SQRESULT sq_wakeupvm(HSQUIRRELVM v,SQBool resumedret,SQBool retval,SQBool raiseerror);
-SQUIRREL_API SQInteger sq_getvmstate(HSQUIRRELVM v);
-
-/*compiler*/
-SQUIRREL_API SQRESULT sq_compile(HSQUIRRELVM v,SQLEXREADFUNC read,SQUserPointer p,const SQChar *sourcename,SQBool raiseerror);
-SQUIRREL_API SQRESULT sq_compilebuffer(HSQUIRRELVM v,const SQChar *s,SQInteger size,const SQChar *sourcename,SQBool raiseerror);
-SQUIRREL_API void sq_enabledebuginfo(HSQUIRRELVM v, SQBool enable);
-SQUIRREL_API void sq_notifyallexceptions(HSQUIRRELVM v, SQBool enable);
-SQUIRREL_API void sq_setcompilererrorhandler(HSQUIRRELVM v,SQCOMPILERERROR f);
-
-/*stack operations*/
-SQUIRREL_API void sq_push(HSQUIRRELVM v,SQInteger idx);
-SQUIRREL_API void sq_pop(HSQUIRRELVM v,SQInteger nelemstopop);
-SQUIRREL_API void sq_poptop(HSQUIRRELVM v);
-SQUIRREL_API void sq_remove(HSQUIRRELVM v,SQInteger idx);
-SQUIRREL_API SQInteger sq_gettop(HSQUIRRELVM v);
-SQUIRREL_API void sq_settop(HSQUIRRELVM v,SQInteger newtop);
-SQUIRREL_API void sq_reservestack(HSQUIRRELVM v,SQInteger nsize);
-SQUIRREL_API SQInteger sq_cmp(HSQUIRRELVM v);
-SQUIRREL_API void sq_move(HSQUIRRELVM dest,HSQUIRRELVM src,SQInteger idx);
-
-/*object creation handling*/
-SQUIRREL_API SQUserPointer sq_newuserdata(HSQUIRRELVM v,SQUnsignedInteger size);
-SQUIRREL_API void sq_newtable(HSQUIRRELVM v);
-SQUIRREL_API void sq_newarray(HSQUIRRELVM v,SQInteger size);
-SQUIRREL_API void sq_newclosure(HSQUIRRELVM v,SQFUNCTION func,SQUnsignedInteger nfreevars);
-SQUIRREL_API SQRESULT sq_setparamscheck(HSQUIRRELVM v,SQInteger nparamscheck,const SQChar *typemask);
-SQUIRREL_API SQRESULT sq_bindenv(HSQUIRRELVM v,SQInteger idx);
-SQUIRREL_API void sq_pushstring(HSQUIRRELVM v,const SQChar *s,SQInteger len);
-SQUIRREL_API void sq_pushfloat(HSQUIRRELVM v,SQFloat f);
-SQUIRREL_API void sq_pushinteger(HSQUIRRELVM v,SQInteger n);
-SQUIRREL_API void sq_pushbool(HSQUIRRELVM v,SQBool b);
-SQUIRREL_API void sq_pushuserpointer(HSQUIRRELVM v,SQUserPointer p);
-SQUIRREL_API void sq_pushnull(HSQUIRRELVM v);
-SQUIRREL_API SQObjectType sq_gettype(HSQUIRRELVM v,SQInteger idx);
-SQUIRREL_API SQInteger sq_getsize(HSQUIRRELVM v,SQInteger idx);
-SQUIRREL_API SQRESULT sq_getbase(HSQUIRRELVM v,SQInteger idx);
-SQUIRREL_API SQBool sq_instanceof(HSQUIRRELVM v);
-SQUIRREL_API void sq_tostring(HSQUIRRELVM v,SQInteger idx);
-SQUIRREL_API void sq_tobool(HSQUIRRELVM v, SQInteger idx, SQBool *b);
-SQUIRREL_API SQRESULT sq_getstring(HSQUIRRELVM v,SQInteger idx,const SQChar **c);
-SQUIRREL_API SQRESULT sq_getinteger(HSQUIRRELVM v,SQInteger idx,SQInteger *i);
-SQUIRREL_API SQRESULT sq_getfloat(HSQUIRRELVM v,SQInteger idx,SQFloat *f);
-SQUIRREL_API SQRESULT sq_getbool(HSQUIRRELVM v,SQInteger idx,SQBool *b);
-SQUIRREL_API SQRESULT sq_getthread(HSQUIRRELVM v,SQInteger idx,HSQUIRRELVM *thread);
-SQUIRREL_API SQRESULT sq_getuserpointer(HSQUIRRELVM v,SQInteger idx,SQUserPointer *p);
-SQUIRREL_API SQRESULT sq_getuserdata(HSQUIRRELVM v,SQInteger idx,SQUserPointer *p,SQUserPointer *typetag);
-SQUIRREL_API SQRESULT sq_settypetag(HSQUIRRELVM v,SQInteger idx,SQUserPointer typetag);
-SQUIRREL_API SQRESULT sq_gettypetag(HSQUIRRELVM v,SQInteger idx,SQUserPointer *typetag);
-SQUIRREL_API void sq_setreleasehook(HSQUIRRELVM v,SQInteger idx,SQRELEASEHOOK hook);
-SQUIRREL_API SQChar *sq_getscratchpad(HSQUIRRELVM v,SQInteger minsize);
-SQUIRREL_API SQRESULT sq_getclosureinfo(HSQUIRRELVM v,SQInteger idx,SQUnsignedInteger *nparams,SQUnsignedInteger *nfreevars);
-SQUIRREL_API SQRESULT sq_setnativeclosurename(HSQUIRRELVM v,SQInteger idx,const SQChar *name);
-SQUIRREL_API SQRESULT sq_setinstanceup(HSQUIRRELVM v, SQInteger idx, SQUserPointer p);
-SQUIRREL_API SQRESULT sq_getinstanceup(HSQUIRRELVM v, SQInteger idx, SQUserPointer *p,SQUserPointer typetag);
-SQUIRREL_API SQRESULT sq_newclass(HSQUIRRELVM v,SQBool hasbase);
-SQUIRREL_API SQRESULT sq_createinstance(HSQUIRRELVM v,SQInteger idx);
-SQUIRREL_API SQRESULT sq_setattributes(HSQUIRRELVM v,SQInteger idx);
-SQUIRREL_API SQRESULT sq_getattributes(HSQUIRRELVM v,SQInteger idx);
-SQUIRREL_API SQRESULT sq_getclass(HSQUIRRELVM v,SQInteger idx);
-SQUIRREL_API void sq_weakref(HSQUIRRELVM v,SQInteger idx);
-SQUIRREL_API SQRESULT sq_getdefaultdelegate(HSQUIRRELVM v,SQObjectType t);
-
-/*object manipulation*/
-SQUIRREL_API void sq_pushroottable(HSQUIRRELVM v);
-SQUIRREL_API void sq_pushregistrytable(HSQUIRRELVM v);
-SQUIRREL_API SQRESULT sq_setroottable(HSQUIRRELVM v);
-SQUIRREL_API SQRESULT sq_newslot(HSQUIRRELVM v, SQInteger idx, SQBool bstatic);
-SQUIRREL_API SQRESULT sq_deleteslot(HSQUIRRELVM v,SQInteger idx,SQBool pushval);
-SQUIRREL_API SQRESULT sq_set(HSQUIRRELVM v,SQInteger idx);
-SQUIRREL_API SQRESULT sq_get(HSQUIRRELVM v,SQInteger idx);
-SQUIRREL_API SQRESULT sq_rawget(HSQUIRRELVM v,SQInteger idx);
-SQUIRREL_API SQRESULT sq_rawset(HSQUIRRELVM v,SQInteger idx);
-SQUIRREL_API SQRESULT sq_rawdeleteslot(HSQUIRRELVM v,SQInteger idx,SQBool pushval);
-SQUIRREL_API SQRESULT sq_arrayappend(HSQUIRRELVM v,SQInteger idx);
-SQUIRREL_API SQRESULT sq_arraypop(HSQUIRRELVM v,SQInteger idx,SQBool pushval);
-SQUIRREL_API SQRESULT sq_arrayresize(HSQUIRRELVM v,SQInteger idx,SQInteger newsize);
-SQUIRREL_API SQRESULT sq_arrayreverse(HSQUIRRELVM v,SQInteger idx);
-SQUIRREL_API SQRESULT sq_setdelegate(HSQUIRRELVM v,SQInteger idx);
-SQUIRREL_API SQRESULT sq_getdelegate(HSQUIRRELVM v,SQInteger idx);
-SQUIRREL_API SQRESULT sq_clone(HSQUIRRELVM v,SQInteger idx);
-SQUIRREL_API SQRESULT sq_setfreevariable(HSQUIRRELVM v,SQInteger idx,SQUnsignedInteger nval);
-SQUIRREL_API SQRESULT sq_next(HSQUIRRELVM v,SQInteger idx);
-SQUIRREL_API SQRESULT sq_getweakrefval(HSQUIRRELVM v,SQInteger idx);
-SQUIRREL_API SQRESULT sq_clear(HSQUIRRELVM v,SQInteger idx);
-
-/*calls*/
-SQUIRREL_API SQRESULT sq_call(HSQUIRRELVM v,SQInteger params,SQBool retval,SQBool raiseerror);
-SQUIRREL_API SQRESULT sq_resume(HSQUIRRELVM v,SQBool retval,SQBool raiseerror);
-SQUIRREL_API const SQChar *sq_getlocal(HSQUIRRELVM v,SQUnsignedInteger level,SQUnsignedInteger idx);
-SQUIRREL_API const SQChar *sq_getfreevariable(HSQUIRRELVM v,SQInteger idx,SQUnsignedInteger nval);
-SQUIRREL_API SQRESULT sq_throwerror(HSQUIRRELVM v,const SQChar *err);
-SQUIRREL_API void sq_reseterror(HSQUIRRELVM v);
-SQUIRREL_API void sq_getlasterror(HSQUIRRELVM v);
-
-/*raw object handling*/
-SQUIRREL_API SQRESULT sq_getstackobj(HSQUIRRELVM v,SQInteger idx,HSQOBJECT *po);
-SQUIRREL_API void sq_pushobject(HSQUIRRELVM v,HSQOBJECT obj);
-SQUIRREL_API void sq_addref(HSQUIRRELVM v,HSQOBJECT *po);
-SQUIRREL_API SQBool sq_release(HSQUIRRELVM v,HSQOBJECT *po);
-SQUIRREL_API void sq_resetobject(HSQOBJECT *po);
-SQUIRREL_API const SQChar *sq_objtostring(HSQOBJECT *o);
-SQUIRREL_API SQBool sq_objtobool(HSQOBJECT *o);
-SQUIRREL_API SQInteger sq_objtointeger(HSQOBJECT *o);
-SQUIRREL_API SQFloat sq_objtofloat(HSQOBJECT *o);
-SQUIRREL_API SQRESULT sq_getobjtypetag(HSQOBJECT *o,SQUserPointer * typetag);
-
-/*GC*/
-SQUIRREL_API SQInteger sq_collectgarbage(HSQUIRRELVM v);
-
-/*serialization*/
-SQUIRREL_API SQRESULT sq_writeclosure(HSQUIRRELVM vm,SQWRITEFUNC writef,SQUserPointer up);
-SQUIRREL_API SQRESULT sq_readclosure(HSQUIRRELVM vm,SQREADFUNC readf,SQUserPointer up);
-
-/*mem allocation*/
-SQUIRREL_API void *sq_malloc(SQUnsignedInteger size);
-SQUIRREL_API void *sq_realloc(void* p,SQUnsignedInteger oldsize,SQUnsignedInteger newsize);
-SQUIRREL_API void sq_free(void *p,SQUnsignedInteger size);
-
-/*debug*/
-SQUIRREL_API SQRESULT sq_stackinfos(HSQUIRRELVM v,SQInteger level,SQStackInfos *si);
-SQUIRREL_API void sq_setdebughook(HSQUIRRELVM v);
-
-/*UTILITY MACRO*/
-#define sq_isnumeric(o) ((o)._type&SQOBJECT_NUMERIC)
-#define sq_istable(o) ((o)._type==OT_TABLE)
-#define sq_isarray(o) ((o)._type==OT_ARRAY)
-#define sq_isfunction(o) ((o)._type==OT_FUNCPROTO)
-#define sq_isclosure(o) ((o)._type==OT_CLOSURE)
-#define sq_isgenerator(o) ((o)._type==OT_GENERATOR)
-#define sq_isnativeclosure(o) ((o)._type==OT_NATIVECLOSURE)
-#define sq_isstring(o) ((o)._type==OT_STRING)
-#define sq_isinteger(o) ((o)._type==OT_INTEGER)
-#define sq_isfloat(o) ((o)._type==OT_FLOAT)
-#define sq_isuserpointer(o) ((o)._type==OT_USERPOINTER)
-#define sq_isuserdata(o) ((o)._type==OT_USERDATA)
-#define sq_isthread(o) ((o)._type==OT_THREAD)
-#define sq_isnull(o) ((o)._type==OT_NULL)
-#define sq_isclass(o) ((o)._type==OT_CLASS)
-#define sq_isinstance(o) ((o)._type==OT_INSTANCE)
-#define sq_isbool(o) ((o)._type==OT_BOOL)
-#define sq_isweakref(o) ((o)._type==OT_WEAKREF)
-#define sq_type(o) ((o)._type)
-
-/* deprecated */
-#define sq_createslot(v,n) sq_newslot(v,n,SQFalse)
-
-#define SQ_OK (0)
-#define SQ_ERROR (-1)
-
-#define SQ_FAILED(res) (res<0)
-#define SQ_SUCCEEDED(res) (res>=0)
-
-#ifdef __cplusplus
-} /*extern "C"*/
-#endif
-
-#endif /*_SQUIRREL_H_*/
+++ /dev/null
-static const SQChar serialize_state_nut[] = {
-0x74, 0x72, 0x79, 0x20, 0x7b, 0x0d, 0x0a, 0x09, 0x0d, 0x0a, 0x6c, 0x6f,
-0x63, 0x61, 0x6c, 0x20, 0x6f, 0x62, 0x6a, 0x73, 0x5f, 0x72, 0x65, 0x67,
-0x3d, 0x7b, 0x6d, 0x61, 0x78, 0x69, 0x64, 0x3d, 0x30, 0x2c, 0x72, 0x65,
-0x66, 0x73, 0x3d, 0x7b, 0x7d, 0x7d, 0x0d, 0x0a, 0x0d, 0x0a, 0x63, 0x6f,
-0x6d, 0x70, 0x6c, 0x65, 0x78, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x20,
-0x3c, 0x2d, 0x20, 0x7b, 0x0d, 0x0a, 0x09, 0x5b, 0x22, 0x74, 0x61, 0x62,
-0x6c, 0x65, 0x22, 0x5d, 0x20, 0x3d, 0x20, 0x6e, 0x75, 0x6c, 0x6c, 0x2c,
-0x0d, 0x0a, 0x09, 0x5b, 0x22, 0x61, 0x72, 0x72, 0x61, 0x79, 0x22, 0x5d,
-0x20, 0x3d, 0x20, 0x6e, 0x75, 0x6c, 0x6c, 0x2c, 0x0d, 0x0a, 0x09, 0x5b,
-0x22, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x22, 0x5d, 0x20, 0x3d, 0x20, 0x6e,
-0x75, 0x6c, 0x6c, 0x2c, 0x0d, 0x0a, 0x09, 0x5b, 0x22, 0x69, 0x6e, 0x73,
-0x74, 0x61, 0x6e, 0x63, 0x65, 0x22, 0x5d, 0x20, 0x3d, 0x20, 0x6e, 0x75,
-0x6c, 0x6c, 0x2c, 0x0d, 0x0a, 0x09, 0x5b, 0x22, 0x77, 0x65, 0x61, 0x6b,
-0x72, 0x65, 0x66, 0x22, 0x5d, 0x20, 0x3d, 0x20, 0x6e, 0x75, 0x6c, 0x6c,
-0x2c, 0x0d, 0x0a, 0x7d, 0x0d, 0x0a, 0x0d, 0x0a, 0x66, 0x75, 0x6e, 0x63,
-0x74, 0x69, 0x6f, 0x6e, 0x20, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x72,
-0x65, 0x66, 0x73, 0x28, 0x74, 0x29, 0x3a, 0x28, 0x6f, 0x62, 0x6a, 0x73,
-0x5f, 0x72, 0x65, 0x67, 0x29, 0x0d, 0x0a, 0x7b, 0x0d, 0x0a, 0x09, 0x69,
-0x66, 0x28, 0x74, 0x20, 0x3d, 0x3d, 0x20, 0x3a, 0x3a, 0x67, 0x65, 0x74,
-0x72, 0x6f, 0x6f, 0x74, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x28, 0x29, 0x29,
-0x0d, 0x0a, 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x3b, 0x0d,
-0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x6f, 0x74, 0x79, 0x70,
-0x65, 0x20, 0x3d, 0x20, 0x3a, 0x3a, 0x74, 0x79, 0x70, 0x65, 0x28, 0x74,
-0x29, 0x3b, 0x0d, 0x0a, 0x09, 0x69, 0x66, 0x28, 0x6f, 0x74, 0x79, 0x70,
-0x65, 0x20, 0x69, 0x6e, 0x20, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x78,
-0x5f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x29, 0x0d, 0x0a, 0x09, 0x7b, 0x0d,
-0x0a, 0x09, 0x09, 0x69, 0x66, 0x28, 0x21, 0x28, 0x74, 0x20, 0x69, 0x6e,
-0x20, 0x6f, 0x62, 0x6a, 0x73, 0x5f, 0x72, 0x65, 0x67, 0x2e, 0x72, 0x65,
-0x66, 0x73, 0x29, 0x29, 0x20, 0x7b, 0x0d, 0x0a, 0x09, 0x09, 0x09, 0x6f,
-0x62, 0x6a, 0x73, 0x5f, 0x72, 0x65, 0x67, 0x2e, 0x72, 0x65, 0x66, 0x73,
-0x5b, 0x74, 0x5d, 0x20, 0x3c, 0x2d, 0x20, 0x6f, 0x62, 0x6a, 0x73, 0x5f,
-0x72, 0x65, 0x67, 0x2e, 0x6d, 0x61, 0x78, 0x69, 0x64, 0x2b, 0x2b, 0x3b,
-0x0d, 0x0a, 0x09, 0x09, 0x0d, 0x0a, 0x09, 0x09, 0x20, 0x20, 0x20, 0x20,
-0x69, 0x74, 0x65, 0x72, 0x61, 0x74, 0x65, 0x6f, 0x62, 0x6a, 0x65, 0x63,
-0x74, 0x28, 0x74, 0x2c, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e,
-0x28, 0x6f, 0x2c, 0x69, 0x2c, 0x76, 0x61, 0x6c, 0x29, 0x3a, 0x28, 0x6f,
-0x62, 0x6a, 0x73, 0x5f, 0x72, 0x65, 0x67, 0x29, 0x0d, 0x0a, 0x09, 0x09,
-0x20, 0x20, 0x20, 0x20, 0x7b, 0x0d, 0x0a, 0x09, 0x09, 0x09, 0x20, 0x20,
-0x20, 0x20, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x72, 0x65, 0x66, 0x73,
-0x28, 0x76, 0x61, 0x6c, 0x29, 0x3b, 0x0d, 0x0a, 0x09, 0x09, 0x09, 0x20,
-0x20, 0x20, 0x20, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x72, 0x65, 0x66,
-0x73, 0x28, 0x69, 0x29, 0x3b, 0x0d, 0x0a, 0x09, 0x09, 0x20, 0x20, 0x20,
-0x20, 0x7d, 0x29, 0x0d, 0x0a, 0x09, 0x09, 0x7d, 0x0d, 0x0a, 0x09, 0x09,
-0x0d, 0x0a, 0x09, 0x7d, 0x0d, 0x0a, 0x7d, 0x0d, 0x0a, 0x0d, 0x0a, 0x66,
-0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x67, 0x65, 0x74, 0x76,
-0x61, 0x6c, 0x75, 0x65, 0x28, 0x76, 0x29, 0x3a, 0x28, 0x6f, 0x62, 0x6a,
-0x73, 0x5f, 0x72, 0x65, 0x67, 0x29, 0x0d, 0x0a, 0x7b, 0x0d, 0x0a, 0x09,
-0x73, 0x77, 0x69, 0x74, 0x63, 0x68, 0x28, 0x3a, 0x3a, 0x74, 0x79, 0x70,
-0x65, 0x28, 0x76, 0x29, 0x29, 0x0d, 0x0a, 0x09, 0x7b, 0x0d, 0x0a, 0x09,
-0x09, 0x63, 0x61, 0x73, 0x65, 0x20, 0x22, 0x74, 0x61, 0x62, 0x6c, 0x65,
-0x22, 0x3a, 0x0d, 0x0a, 0x09, 0x09, 0x63, 0x61, 0x73, 0x65, 0x20, 0x22,
-0x61, 0x72, 0x72, 0x61, 0x79, 0x22, 0x3a, 0x0d, 0x0a, 0x09, 0x09, 0x63,
-0x61, 0x73, 0x65, 0x20, 0x22, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x22, 0x3a,
-0x0d, 0x0a, 0x09, 0x09, 0x63, 0x61, 0x73, 0x65, 0x20, 0x22, 0x69, 0x6e,
-0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x22, 0x3a, 0x0d, 0x0a, 0x09, 0x09,
-0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6f, 0x62, 0x6a, 0x73,
-0x5f, 0x72, 0x65, 0x67, 0x2e, 0x72, 0x65, 0x66, 0x73, 0x5b, 0x76, 0x5d,
-0x2e, 0x74, 0x6f, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x28, 0x29, 0x3b,
-0x0d, 0x0a, 0x09, 0x09, 0x63, 0x61, 0x73, 0x65, 0x20, 0x22, 0x69, 0x6e,
-0x74, 0x65, 0x67, 0x65, 0x72, 0x22, 0x3a, 0x0d, 0x0a, 0x09, 0x09, 0x63,
-0x61, 0x73, 0x65, 0x20, 0x22, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x22, 0x3a,
-0x0d, 0x0a, 0x09, 0x09, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75,
-0x72, 0x6e, 0x20, 0x76, 0x3b, 0x0d, 0x0a, 0x09, 0x09, 0x63, 0x61, 0x73,
-0x65, 0x20, 0x22, 0x62, 0x6f, 0x6f, 0x6c, 0x22, 0x3a, 0x0d, 0x0a, 0x09,
-0x09, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20,
-0x76, 0x2e, 0x74, 0x6f, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x28, 0x29,
-0x3b, 0x0d, 0x0a, 0x09, 0x09, 0x63, 0x61, 0x73, 0x65, 0x20, 0x22, 0x73,
-0x74, 0x72, 0x69, 0x6e, 0x67, 0x22, 0x3a, 0x0d, 0x0a, 0x09, 0x09, 0x09,
-0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x76, 0x3b, 0x0d, 0x0a, 0x09,
-0x09, 0x63, 0x61, 0x73, 0x65, 0x20, 0x22, 0x6e, 0x75, 0x6c, 0x6c, 0x22,
-0x3a, 0x0d, 0x0a, 0x09, 0x09, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x74,
-0x75, 0x72, 0x6e, 0x20, 0x22, 0x6e, 0x75, 0x6c, 0x6c, 0x22, 0x3b, 0x0d,
-0x0a, 0x09, 0x09, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x3a, 0x0d,
-0x0a, 0x09, 0x09, 0x09, 0x0d, 0x0a, 0x09, 0x09, 0x09, 0x72, 0x65, 0x74,
-0x75, 0x72, 0x6e, 0x20, 0x70, 0x61, 0x63, 0x6b, 0x5f, 0x74, 0x79, 0x70,
-0x65, 0x28, 0x3a, 0x3a, 0x74, 0x79, 0x70, 0x65, 0x28, 0x76, 0x29, 0x29,
-0x3b, 0x0d, 0x0a, 0x09, 0x7d, 0x0d, 0x0a, 0x7d, 0x0d, 0x0a, 0x0d, 0x0a,
-0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x70, 0x61, 0x63, 0x6b, 0x65, 0x64,
-0x5f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x3d, 0x7b, 0x0d, 0x0a, 0x09, 0x5b,
-0x22, 0x6e, 0x75, 0x6c, 0x6c, 0x22, 0x5d, 0x3d, 0x22, 0x6e, 0x22, 0x2c,
-0x0d, 0x0a, 0x09, 0x5b, 0x22, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x22,
-0x5d, 0x3d, 0x22, 0x73, 0x22, 0x2c, 0x0d, 0x0a, 0x09, 0x5b, 0x22, 0x69,
-0x6e, 0x74, 0x65, 0x67, 0x65, 0x72, 0x22, 0x5d, 0x3d, 0x22, 0x69, 0x22,
-0x2c, 0x0d, 0x0a, 0x09, 0x5b, 0x22, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x22,
-0x5d, 0x3d, 0x22, 0x66, 0x22, 0x2c, 0x0d, 0x0a, 0x09, 0x5b, 0x22, 0x75,
-0x73, 0x65, 0x72, 0x64, 0x61, 0x74, 0x61, 0x22, 0x5d, 0x3d, 0x22, 0x75,
-0x22, 0x2c, 0x0d, 0x0a, 0x09, 0x5b, 0x22, 0x66, 0x75, 0x6e, 0x63, 0x74,
-0x69, 0x6f, 0x6e, 0x22, 0x5d, 0x3d, 0x22, 0x66, 0x6e, 0x22, 0x2c, 0x0d,
-0x0a, 0x09, 0x5b, 0x22, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x22, 0x5d, 0x3d,
-0x22, 0x74, 0x22, 0x2c, 0x0d, 0x0a, 0x09, 0x5b, 0x22, 0x61, 0x72, 0x72,
-0x61, 0x79, 0x22, 0x5d, 0x3d, 0x22, 0x61, 0x22, 0x2c, 0x0d, 0x0a, 0x09,
-0x5b, 0x22, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x22,
-0x5d, 0x3d, 0x22, 0x67, 0x22, 0x2c, 0x0d, 0x0a, 0x09, 0x5b, 0x22, 0x74,
-0x68, 0x72, 0x65, 0x61, 0x64, 0x22, 0x5d, 0x3d, 0x22, 0x68, 0x22, 0x2c,
-0x0d, 0x0a, 0x09, 0x5b, 0x22, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63,
-0x65, 0x22, 0x5d, 0x3d, 0x22, 0x78, 0x22, 0x2c, 0x20, 0x0d, 0x0a, 0x09,
-0x5b, 0x22, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x22, 0x5d, 0x3d, 0x22, 0x79,
-0x22, 0x2c, 0x20, 0x20, 0x0d, 0x0a, 0x09, 0x5b, 0x22, 0x62, 0x6f, 0x6f,
-0x6c, 0x22, 0x5d, 0x3d, 0x22, 0x62, 0x22, 0x2c, 0x0d, 0x0a, 0x09, 0x5b,
-0x22, 0x77, 0x65, 0x61, 0x6b, 0x72, 0x65, 0x66, 0x22, 0x5d, 0x3d, 0x22,
-0x77, 0x22, 0x20, 0x20, 0x0d, 0x0a, 0x7d, 0x0d, 0x0a, 0x0d, 0x0a, 0x66,
-0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x70, 0x61, 0x63, 0x6b,
-0x5f, 0x74, 0x79, 0x70, 0x65, 0x28, 0x74, 0x79, 0x70, 0x65, 0x29, 0x3a,
-0x28, 0x70, 0x61, 0x63, 0x6b, 0x65, 0x64, 0x5f, 0x74, 0x79, 0x70, 0x65,
-0x73, 0x29, 0x0d, 0x0a, 0x7b, 0x0d, 0x0a, 0x09, 0x69, 0x66, 0x28, 0x74,
-0x79, 0x70, 0x65, 0x20, 0x69, 0x6e, 0x20, 0x70, 0x61, 0x63, 0x6b, 0x65,
-0x64, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x29, 0x72, 0x65, 0x74, 0x75,
-0x72, 0x6e, 0x20, 0x70, 0x61, 0x63, 0x6b, 0x65, 0x64, 0x5f, 0x74, 0x79,
-0x70, 0x65, 0x73, 0x5b, 0x74, 0x79, 0x70, 0x65, 0x5d, 0x0d, 0x0a, 0x09,
-0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x79, 0x70, 0x65, 0x0d,
-0x0a, 0x7d, 0x20, 0x0d, 0x0a, 0x0d, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74,
-0x69, 0x6f, 0x6e, 0x20, 0x69, 0x74, 0x65, 0x72, 0x61, 0x74, 0x65, 0x6f,
-0x62, 0x6a, 0x65, 0x63, 0x74, 0x28, 0x6f, 0x62, 0x6a, 0x2c, 0x66, 0x75,
-0x6e, 0x63, 0x29, 0x0d, 0x0a, 0x7b, 0x0d, 0x0a, 0x09, 0x6c, 0x6f, 0x63,
-0x61, 0x6c, 0x20, 0x74, 0x79, 0x20, 0x3d, 0x20, 0x3a, 0x3a, 0x74, 0x79,
-0x70, 0x65, 0x28, 0x6f, 0x62, 0x6a, 0x29, 0x3b, 0x0d, 0x0a, 0x09, 0x69,
-0x66, 0x28, 0x74, 0x79, 0x20, 0x3d, 0x3d, 0x20, 0x22, 0x69, 0x6e, 0x73,
-0x74, 0x61, 0x6e, 0x63, 0x65, 0x22, 0x29, 0x20, 0x7b, 0x0d, 0x0a, 0x09,
-0x09, 0x74, 0x72, 0x79, 0x20, 0x7b, 0x20, 0x2f, 0x2f, 0x54, 0x52, 0x59,
-0x20, 0x54, 0x4f, 0x20, 0x55, 0x53, 0x45, 0x20, 0x5f, 0x6e, 0x65, 0x78,
-0x74, 0x69, 0x0d, 0x0a, 0x09, 0x09, 0x20, 0x20, 0x20, 0x20, 0x66, 0x6f,
-0x72, 0x65, 0x61, 0x63, 0x68, 0x28, 0x69, 0x64, 0x78, 0x2c, 0x76, 0x61,
-0x6c, 0x20, 0x69, 0x6e, 0x20, 0x6f, 0x62, 0x6a, 0x29, 0x0d, 0x0a, 0x09,
-0x09, 0x20, 0x20, 0x20, 0x20, 0x7b, 0x0d, 0x0a, 0x09, 0x09, 0x09, 0x09,
-0x66, 0x75, 0x6e, 0x63, 0x28, 0x6f, 0x62, 0x6a, 0x2c, 0x69, 0x64, 0x78,
-0x2c, 0x76, 0x61, 0x6c, 0x29, 0x3b, 0x0d, 0x0a, 0x09, 0x09, 0x20, 0x20,
-0x20, 0x20, 0x7d, 0x0d, 0x0a, 0x09, 0x09, 0x7d, 0x0d, 0x0a, 0x09, 0x09,
-0x63, 0x61, 0x74, 0x63, 0x68, 0x28, 0x65, 0x29, 0x20, 0x7b, 0x0d, 0x0a,
-0x09, 0x09, 0x20, 0x20, 0x20, 0x66, 0x6f, 0x72, 0x65, 0x61, 0x63, 0x68,
-0x28, 0x69, 0x64, 0x78, 0x2c, 0x76, 0x61, 0x6c, 0x20, 0x69, 0x6e, 0x20,
-0x6f, 0x62, 0x6a, 0x2e, 0x67, 0x65, 0x74, 0x63, 0x6c, 0x61, 0x73, 0x73,
-0x28, 0x29, 0x29, 0x0d, 0x0a, 0x09, 0x09, 0x20, 0x20, 0x20, 0x7b, 0x0d,
-0x0a, 0x09, 0x09, 0x09, 0x66, 0x75, 0x6e, 0x63, 0x28, 0x6f, 0x62, 0x6a,
-0x2c, 0x69, 0x64, 0x78, 0x2c, 0x6f, 0x62, 0x6a, 0x5b, 0x69, 0x64, 0x78,
-0x5d, 0x29, 0x3b, 0x0d, 0x0a, 0x09, 0x09, 0x20, 0x20, 0x20, 0x7d, 0x0d,
-0x0a, 0x09, 0x09, 0x7d, 0x0d, 0x0a, 0x09, 0x7d, 0x0d, 0x0a, 0x09, 0x65,
-0x6c, 0x73, 0x65, 0x20, 0x69, 0x66, 0x28, 0x74, 0x79, 0x20, 0x3d, 0x3d,
-0x20, 0x22, 0x77, 0x65, 0x61, 0x6b, 0x72, 0x65, 0x66, 0x22, 0x29, 0x20,
-0x7b, 0x0d, 0x0a, 0x09, 0x09, 0x66, 0x75, 0x6e, 0x63, 0x28, 0x6f, 0x62,
-0x6a, 0x2c, 0x22, 0x40, 0x72, 0x65, 0x66, 0x22, 0x2c, 0x6f, 0x62, 0x6a,
-0x2e, 0x72, 0x65, 0x66, 0x28, 0x29, 0x29, 0x3b, 0x0d, 0x0a, 0x09, 0x7d,
-0x0d, 0x0a, 0x09, 0x65, 0x6c, 0x73, 0x65, 0x20, 0x7b, 0x0d, 0x0a, 0x09,
-0x09, 0x66, 0x6f, 0x72, 0x65, 0x61, 0x63, 0x68, 0x28, 0x69, 0x64, 0x78,
-0x2c, 0x76, 0x61, 0x6c, 0x20, 0x69, 0x6e, 0x20, 0x6f, 0x62, 0x6a, 0x29,
-0x0d, 0x0a, 0x09, 0x09, 0x7b, 0x0d, 0x0a, 0x09, 0x09, 0x20, 0x20, 0x20,
-0x20, 0x66, 0x75, 0x6e, 0x63, 0x28, 0x6f, 0x62, 0x6a, 0x2c, 0x69, 0x64,
-0x78, 0x2c, 0x76, 0x61, 0x6c, 0x29, 0x3b, 0x0d, 0x0a, 0x09, 0x09, 0x7d,
-0x0d, 0x0a, 0x09, 0x7d, 0x0d, 0x0a, 0x09, 0x09, 0x09, 0x0d, 0x0a, 0x7d,
-0x0d, 0x0a, 0x0d, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e,
-0x20, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x74, 0x72, 0x65, 0x65, 0x28,
-0x29, 0x3a, 0x28, 0x6f, 0x62, 0x6a, 0x73, 0x5f, 0x72, 0x65, 0x67, 0x29,
-0x0d, 0x0a, 0x7b, 0x0d, 0x0a, 0x09, 0x66, 0x6f, 0x72, 0x65, 0x61, 0x63,
-0x68, 0x28, 0x69, 0x2c, 0x6f, 0x20, 0x69, 0x6e, 0x20, 0x6f, 0x62, 0x6a,
-0x73, 0x5f, 0x72, 0x65, 0x67, 0x2e, 0x72, 0x65, 0x66, 0x73, 0x29, 0x0d,
-0x0a, 0x09, 0x7b, 0x0d, 0x0a, 0x09, 0x09, 0x62, 0x65, 0x67, 0x69, 0x6e,
-0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x28, 0x22, 0x6f, 0x22, 0x29,
-0x3b, 0x0d, 0x0a, 0x09, 0x09, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75,
-0x74, 0x65, 0x28, 0x22, 0x74, 0x79, 0x70, 0x65, 0x22, 0x2c, 0x28, 0x69,
-0x3d, 0x3d, 0x3a, 0x3a, 0x67, 0x65, 0x74, 0x72, 0x6f, 0x6f, 0x74, 0x74,
-0x61, 0x62, 0x6c, 0x65, 0x28, 0x29, 0x3f, 0x22, 0x72, 0x22, 0x3a, 0x70,
-0x61, 0x63, 0x6b, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x28, 0x3a, 0x3a, 0x74,
-0x79, 0x70, 0x65, 0x28, 0x69, 0x29, 0x29, 0x29, 0x29, 0x3b, 0x0d, 0x0a,
-0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x5f, 0x74, 0x79, 0x70,
-0x65, 0x6f, 0x66, 0x20, 0x3d, 0x20, 0x74, 0x79, 0x70, 0x65, 0x6f, 0x66,
-0x20, 0x69, 0x3b, 0x0d, 0x0a, 0x09, 0x09, 0x69, 0x66, 0x28, 0x5f, 0x74,
-0x79, 0x70, 0x65, 0x6f, 0x66, 0x20, 0x21, 0x3d, 0x20, 0x3a, 0x3a, 0x74,
-0x79, 0x70, 0x65, 0x28, 0x69, 0x29, 0x29, 0x20, 0x7b, 0x0d, 0x0a, 0x09,
-0x09, 0x09, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x28,
-0x22, 0x74, 0x79, 0x70, 0x65, 0x6f, 0x66, 0x22, 0x2c, 0x5f, 0x74, 0x79,
-0x70, 0x65, 0x6f, 0x66, 0x29, 0x3b, 0x0d, 0x0a, 0x09, 0x09, 0x7d, 0x0d,
-0x0a, 0x09, 0x09, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65,
-0x28, 0x22, 0x72, 0x65, 0x66, 0x22, 0x2c, 0x6f, 0x2e, 0x74, 0x6f, 0x73,
-0x74, 0x72, 0x69, 0x6e, 0x67, 0x28, 0x29, 0x29, 0x3b, 0x0d, 0x0a, 0x09,
-0x09, 0x69, 0x66, 0x28, 0x69, 0x20, 0x21, 0x3d, 0x20, 0x3a, 0x3a, 0x67,
-0x65, 0x74, 0x72, 0x6f, 0x6f, 0x74, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x28,
-0x29, 0x29, 0x7b, 0x0d, 0x0a, 0x09, 0x09, 0x09, 0x69, 0x74, 0x65, 0x72,
-0x61, 0x74, 0x65, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x28, 0x69, 0x2c,
-0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x6f, 0x62,
-0x6a, 0x2c, 0x69, 0x64, 0x78, 0x2c, 0x76, 0x61, 0x6c, 0x29, 0x20, 0x7b,
-0x0d, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x69, 0x66, 0x28, 0x3a, 0x3a, 0x74,
-0x79, 0x70, 0x65, 0x28, 0x76, 0x61, 0x6c, 0x29, 0x20, 0x3d, 0x3d, 0x20,
-0x22, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x29, 0x0d,
-0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e,
-0x3b, 0x0d, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x0d, 0x0a, 0x09, 0x09,
-0x09, 0x09, 0x62, 0x65, 0x67, 0x69, 0x6e, 0x65, 0x6c, 0x65, 0x6d, 0x65,
-0x6e, 0x74, 0x28, 0x22, 0x65, 0x22, 0x29, 0x3b, 0x09, 0x0d, 0x0a, 0x09,
-0x09, 0x09, 0x09, 0x09, 0x65, 0x6d, 0x69, 0x74, 0x76, 0x61, 0x6c, 0x75,
-0x65, 0x28, 0x22, 0x6b, 0x74, 0x22, 0x2c, 0x22, 0x6b, 0x76, 0x22, 0x2c,
-0x69, 0x64, 0x78, 0x29, 0x3b, 0x0d, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09,
-0x65, 0x6d, 0x69, 0x74, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x28, 0x22, 0x76,
-0x74, 0x22, 0x2c, 0x22, 0x76, 0x22, 0x2c, 0x6f, 0x62, 0x6a, 0x5b, 0x69,
-0x64, 0x78, 0x5d, 0x29, 0x3b, 0x0d, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x65,
-0x6e, 0x64, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x28, 0x22, 0x65,
-0x22, 0x29, 0x3b, 0x09, 0x0d, 0x0a, 0x0d, 0x0a, 0x09, 0x09, 0x09, 0x7d,
-0x29, 0x0d, 0x0a, 0x09, 0x09, 0x7d, 0x0d, 0x0a, 0x09, 0x09, 0x65, 0x6e,
-0x64, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x28, 0x22, 0x6f, 0x22,
-0x29, 0x3b, 0x0d, 0x0a, 0x09, 0x7d, 0x0d, 0x0a, 0x7d, 0x0d, 0x0a, 0x0d,
-0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x65, 0x76,
-0x61, 0x6c, 0x75, 0x61, 0x74, 0x65, 0x5f, 0x77, 0x61, 0x74, 0x63, 0x68,
-0x28, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x73, 0x2c, 0x69, 0x64, 0x2c, 0x65,
-0x78, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x29, 0x0d, 0x0a,
-0x7b, 0x0d, 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x66, 0x75,
-0x6e, 0x63, 0x5f, 0x73, 0x72, 0x63, 0x3d, 0x22, 0x72, 0x65, 0x74, 0x75,
-0x72, 0x6e, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20,
-0x28, 0x22, 0x0d, 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x70,
-0x61, 0x72, 0x61, 0x6d, 0x73, 0x3d, 0x5b, 0x5d, 0x3b, 0x0d, 0x0a, 0x09,
-0x0d, 0x0a, 0x09, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x2e, 0x61, 0x70,
-0x70, 0x65, 0x6e, 0x64, 0x28, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x73, 0x5b,
-0x22, 0x74, 0x68, 0x69, 0x73, 0x22, 0x5d, 0x29, 0x0d, 0x0a, 0x09, 0x6c,
-0x6f, 0x63, 0x61, 0x6c, 0x20, 0x66, 0x69, 0x72, 0x73, 0x74, 0x3d, 0x31,
-0x3b, 0x0d, 0x0a, 0x09, 0x66, 0x6f, 0x72, 0x65, 0x61, 0x63, 0x68, 0x28,
-0x69, 0x2c, 0x76, 0x20, 0x69, 0x6e, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c,
-0x73, 0x29, 0x7b, 0x0d, 0x0a, 0x09, 0x09, 0x69, 0x66, 0x28, 0x69, 0x21,
-0x3d, 0x22, 0x74, 0x68, 0x69, 0x73, 0x22, 0x20, 0x26, 0x26, 0x20, 0x69,
-0x5b, 0x30, 0x5d, 0x20, 0x21, 0x3d, 0x20, 0x27, 0x40, 0x27, 0x29, 0x7b,
-0x20, 0x2f, 0x2f, 0x66, 0x6f, 0x72, 0x65, 0x61, 0x63, 0x68, 0x20, 0x69,
-0x74, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x73, 0x20, 0x73, 0x74, 0x61,
-0x72, 0x74, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x40, 0x0d, 0x0a, 0x09,
-0x09, 0x09, 0x69, 0x66, 0x28, 0x21, 0x66, 0x69, 0x72, 0x73, 0x74, 0x29,
-0x7b, 0x0d, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x66, 0x75, 0x6e, 0x63, 0x5f,
-0x73, 0x72, 0x63, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x5f, 0x73, 0x72, 0x63,
-0x2b, 0x22, 0x2c, 0x22, 0x0d, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x0d, 0x0a,
-0x09, 0x09, 0x09, 0x7d, 0x0d, 0x0a, 0x09, 0x09, 0x09, 0x66, 0x69, 0x72,
-0x73, 0x74, 0x3d, 0x6e, 0x75, 0x6c, 0x6c, 0x0d, 0x0a, 0x09, 0x09, 0x09,
-0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x2e, 0x61, 0x70, 0x70, 0x65, 0x6e,
-0x64, 0x28, 0x76, 0x29, 0x0d, 0x0a, 0x09, 0x09, 0x09, 0x66, 0x75, 0x6e,
-0x63, 0x5f, 0x73, 0x72, 0x63, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x5f, 0x73,
-0x72, 0x63, 0x2b, 0x69, 0x0d, 0x0a, 0x09, 0x09, 0x7d, 0x0d, 0x0a, 0x09,
-0x7d, 0x0d, 0x0a, 0x09, 0x66, 0x75, 0x6e, 0x63, 0x5f, 0x73, 0x72, 0x63,
-0x3d, 0x66, 0x75, 0x6e, 0x63, 0x5f, 0x73, 0x72, 0x63, 0x2b, 0x22, 0x29,
-0x7b, 0x5c, 0x6e, 0x22, 0x0d, 0x0a, 0x09, 0x66, 0x75, 0x6e, 0x63, 0x5f,
-0x73, 0x72, 0x63, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x5f, 0x73, 0x72, 0x63,
-0x2b, 0x22, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x28, 0x22, 0x2b,
-0x65, 0x78, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x2b, 0x22,
-0x29, 0x5c, 0x6e, 0x7d, 0x22, 0x0d, 0x0a, 0x09, 0x0d, 0x0a, 0x09, 0x74,
-0x72, 0x79, 0x20, 0x7b, 0x0d, 0x0a, 0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61,
-0x6c, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x3d, 0x3a, 0x3a, 0x63, 0x6f, 0x6d,
-0x70, 0x69, 0x6c, 0x65, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x28, 0x66,
-0x75, 0x6e, 0x63, 0x5f, 0x73, 0x72, 0x63, 0x29, 0x3b, 0x0d, 0x0a, 0x09,
-0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x7b, 0x73, 0x74, 0x61,
-0x74, 0x75, 0x73, 0x3d, 0x22, 0x6f, 0x6b, 0x22, 0x20, 0x2c, 0x20, 0x76,
-0x61, 0x6c, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x28, 0x29, 0x2e, 0x61, 0x63,
-0x61, 0x6c, 0x6c, 0x28, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x29, 0x7d,
-0x3b, 0x0d, 0x0a, 0x09, 0x7d, 0x0d, 0x0a, 0x09, 0x63, 0x61, 0x74, 0x63,
-0x68, 0x28, 0x65, 0x29, 0x0d, 0x0a, 0x09, 0x7b, 0x0d, 0x0a, 0x09, 0x09,
-0x0d, 0x0a, 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x7b,
-0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x3d, 0x22, 0x65, 0x72, 0x72, 0x6f,
-0x72, 0x22, 0x7d, 0x0d, 0x0a, 0x09, 0x7d, 0x0d, 0x0a, 0x7d, 0x0d, 0x0a,
-0x0d, 0x0a, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
-0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
-0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
-0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
-0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
-0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
-0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x0d, 0x0a, 0x2f, 0x2f, 0x2f,
-0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
-0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
-0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
-0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
-0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
-0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
-0x2f, 0x2f, 0x0d, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e,
-0x20, 0x65, 0x6d, 0x69, 0x74, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x28, 0x74,
-0x79, 0x70, 0x65, 0x5f, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x2c, 0x76,
-0x61, 0x6c, 0x75, 0x65, 0x5f, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x2c,
-0x76, 0x61, 0x6c, 0x29, 0x0d, 0x0a, 0x7b, 0x0d, 0x0a, 0x09, 0x61, 0x74,
-0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x28, 0x74, 0x79, 0x70, 0x65,
-0x5f, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x2c, 0x70, 0x61, 0x63, 0x6b,
-0x5f, 0x74, 0x79, 0x70, 0x65, 0x28, 0x3a, 0x3a, 0x74, 0x79, 0x70, 0x65,
-0x28, 0x76, 0x61, 0x6c, 0x29, 0x29, 0x29, 0x3b, 0x0d, 0x0a, 0x09, 0x61,
-0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x28, 0x76, 0x61, 0x6c,
-0x75, 0x65, 0x5f, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x2c, 0x67, 0x65,
-0x74, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x28, 0x76, 0x61, 0x6c, 0x29, 0x2e,
-0x74, 0x6f, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x28, 0x29, 0x29, 0x3b,
-0x0d, 0x0a, 0x7d, 0x0d, 0x0a, 0x0d, 0x0a, 0x6c, 0x6f, 0x63, 0x61, 0x6c,
-0x20, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x3d, 0x5b, 0x5d, 0x0d, 0x0a, 0x6c,
-0x6f, 0x63, 0x61, 0x6c, 0x20, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x3d, 0x33,
-0x3b, 0x0d, 0x0a, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x73, 0x69, 0x3b,
-0x0d, 0x0a, 0x0d, 0x0a, 0x2f, 0x2f, 0x74, 0x72, 0x79, 0x20, 0x7b, 0x0d,
-0x0a, 0x09, 0x2f, 0x2f, 0x45, 0x4e, 0x55, 0x4d, 0x45, 0x52, 0x41, 0x54,
-0x45, 0x20, 0x54, 0x48, 0x45, 0x20, 0x53, 0x54, 0x41, 0x43, 0x4b, 0x20,
-0x57, 0x41, 0x54, 0x43, 0x48, 0x45, 0x53, 0x0d, 0x0a, 0x09, 0x77, 0x68,
-0x69, 0x6c, 0x65, 0x28, 0x73, 0x69, 0x3d, 0x3a, 0x3a, 0x67, 0x65, 0x74,
-0x73, 0x74, 0x61, 0x63, 0x6b, 0x69, 0x6e, 0x66, 0x6f, 0x73, 0x28, 0x6c,
-0x65, 0x76, 0x65, 0x6c, 0x29, 0x29, 0x0d, 0x0a, 0x09, 0x7b, 0x0d, 0x0a,
-0x09, 0x09, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x61, 0x70, 0x70, 0x65,
-0x6e, 0x64, 0x28, 0x73, 0x69, 0x29, 0x3b, 0x0d, 0x0a, 0x09, 0x09, 0x6c,
-0x65, 0x76, 0x65, 0x6c, 0x2b, 0x2b, 0x3b, 0x0d, 0x0a, 0x09, 0x7d, 0x0d,
-0x0a, 0x0d, 0x0a, 0x09, 0x2f, 0x2f, 0x45, 0x56, 0x41, 0x4c, 0x55, 0x41,
-0x54, 0x45, 0x20, 0x41, 0x4c, 0x4c, 0x20, 0x57, 0x41, 0x54, 0x43, 0x48,
-0x45, 0x53, 0x0d, 0x0a, 0x09, 0x6f, 0x62, 0x6a, 0x73, 0x5f, 0x72, 0x65,
-0x67, 0x2e, 0x72, 0x65, 0x66, 0x73, 0x5b, 0x3a, 0x3a, 0x67, 0x65, 0x74,
-0x72, 0x6f, 0x6f, 0x74, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x28, 0x29, 0x5d,
-0x20, 0x3c, 0x2d, 0x20, 0x6f, 0x62, 0x6a, 0x73, 0x5f, 0x72, 0x65, 0x67,
-0x2e, 0x6d, 0x61, 0x78, 0x69, 0x64, 0x2b, 0x2b, 0x3b, 0x0d, 0x0a, 0x09,
-0x66, 0x6f, 0x72, 0x65, 0x61, 0x63, 0x68, 0x28, 0x69, 0x2c, 0x76, 0x61,
-0x6c, 0x20, 0x69, 0x6e, 0x20, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x29, 0x0d,
-0x0a, 0x09, 0x7b, 0x0d, 0x0a, 0x09, 0x09, 0x69, 0x66, 0x28, 0x76, 0x61,
-0x6c, 0x2e, 0x73, 0x72, 0x63, 0x21, 0x3d, 0x22, 0x4e, 0x41, 0x54, 0x49,
-0x56, 0x45, 0x22, 0x29, 0x20, 0x7b, 0x0d, 0x0a, 0x09, 0x09, 0x09, 0x69,
-0x66, 0x28, 0x22, 0x77, 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, 0x22, 0x20,
-0x69, 0x6e, 0x20, 0x74, 0x68, 0x69, 0x73, 0x29, 0x20, 0x7b, 0x0d, 0x0a,
-0x09, 0x09, 0x09, 0x09, 0x76, 0x61, 0x6c, 0x2e, 0x77, 0x61, 0x74, 0x63,
-0x68, 0x65, 0x73, 0x20, 0x3c, 0x2d, 0x20, 0x7b, 0x7d, 0x0d, 0x0a, 0x09,
-0x09, 0x09, 0x09, 0x66, 0x6f, 0x72, 0x65, 0x61, 0x63, 0x68, 0x28, 0x69,
-0x2c, 0x77, 0x61, 0x74, 0x63, 0x68, 0x20, 0x69, 0x6e, 0x20, 0x77, 0x61,
-0x74, 0x63, 0x68, 0x65, 0x73, 0x29, 0x0d, 0x0a, 0x09, 0x09, 0x09, 0x09,
-0x7b, 0x0d, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x69, 0x66, 0x28, 0x76,
-0x61, 0x6c, 0x2e, 0x73, 0x72, 0x63, 0x21, 0x3d, 0x22, 0x4e, 0x41, 0x54,
-0x49, 0x56, 0x45, 0x22, 0x29, 0x7b, 0x0d, 0x0a, 0x09, 0x09, 0x09, 0x09,
-0x09, 0x09, 0x76, 0x61, 0x6c, 0x2e, 0x77, 0x61, 0x74, 0x63, 0x68, 0x65,
-0x73, 0x5b, 0x69, 0x5d, 0x20, 0x3c, 0x2d, 0x20, 0x65, 0x76, 0x61, 0x6c,
-0x75, 0x61, 0x74, 0x65, 0x5f, 0x77, 0x61, 0x74, 0x63, 0x68, 0x28, 0x76,
-0x61, 0x6c, 0x2e, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x73, 0x2c, 0x69, 0x2c,
-0x77, 0x61, 0x74, 0x63, 0x68, 0x29, 0x3b, 0x0d, 0x0a, 0x09, 0x09, 0x09,
-0x09, 0x09, 0x09, 0x69, 0x66, 0x28, 0x76, 0x61, 0x6c, 0x2e, 0x77, 0x61,
-0x74, 0x63, 0x68, 0x65, 0x73, 0x5b, 0x69, 0x5d, 0x2e, 0x73, 0x74, 0x61,
-0x74, 0x75, 0x73, 0x21, 0x3d, 0x22, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x22,
-0x29, 0x0d, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x62, 0x75,
-0x69, 0x6c, 0x64, 0x5f, 0x72, 0x65, 0x66, 0x73, 0x28, 0x76, 0x61, 0x6c,
-0x2e, 0x77, 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, 0x5b, 0x69, 0x5d, 0x2e,
-0x76, 0x61, 0x6c, 0x29, 0x3b, 0x0d, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09,
-0x7d, 0x0d, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x65, 0x6c, 0x73, 0x65,
-0x7b, 0x0d, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x76, 0x61, 0x6c,
-0x2e, 0x77, 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, 0x5b, 0x69, 0x5d, 0x20,
-0x3c, 0x2d, 0x20, 0x7b, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x3d, 0x22,
-0x65, 0x72, 0x72, 0x6f, 0x72, 0x22, 0x7d, 0x0d, 0x0a, 0x09, 0x09, 0x09,
-0x09, 0x09, 0x7d, 0x0d, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x76, 0x61,
-0x6c, 0x2e, 0x77, 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, 0x5b, 0x69, 0x5d,
-0x2e, 0x65, 0x78, 0x70, 0x20, 0x3c, 0x2d, 0x20, 0x77, 0x61, 0x74, 0x63,
-0x68, 0x3b, 0x0d, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x7d, 0x0d, 0x0a, 0x09,
-0x09, 0x09, 0x09, 0x0d, 0x0a, 0x09, 0x09, 0x09, 0x7d, 0x0d, 0x0a, 0x09,
-0x09, 0x7d, 0x0d, 0x0a, 0x09, 0x09, 0x66, 0x6f, 0x72, 0x65, 0x61, 0x63,
-0x68, 0x28, 0x69, 0x2c, 0x6c, 0x20, 0x69, 0x6e, 0x20, 0x76, 0x61, 0x6c,
-0x2e, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x73, 0x29, 0x0d, 0x0a, 0x09, 0x09,
-0x09, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x72, 0x65, 0x66, 0x73, 0x28,
-0x6c, 0x29, 0x3b, 0x0d, 0x0a, 0x09, 0x7d, 0x0d, 0x0a, 0x0d, 0x0a, 0x0d,
-0x0a, 0x09, 0x62, 0x65, 0x67, 0x69, 0x6e, 0x65, 0x6c, 0x65, 0x6d, 0x65,
-0x6e, 0x74, 0x28, 0x22, 0x6f, 0x62, 0x6a, 0x73, 0x22, 0x29, 0x3b, 0x0d,
-0x0a, 0x09, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x74, 0x72, 0x65, 0x65,
-0x28, 0x29, 0x3b, 0x0d, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x65, 0x6c, 0x65,
-0x6d, 0x65, 0x6e, 0x74, 0x28, 0x22, 0x6f, 0x62, 0x6a, 0x73, 0x22, 0x29,
-0x3b, 0x0d, 0x0a, 0x0d, 0x0a, 0x09, 0x62, 0x65, 0x67, 0x69, 0x6e, 0x65,
-0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x28, 0x22, 0x63, 0x61, 0x6c, 0x6c,
-0x73, 0x22, 0x29, 0x3b, 0x0d, 0x0a, 0x0d, 0x0a, 0x09, 0x66, 0x6f, 0x72,
-0x65, 0x61, 0x63, 0x68, 0x28, 0x69, 0x2c, 0x76, 0x61, 0x6c, 0x20, 0x69,
-0x6e, 0x20, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x29, 0x0d, 0x0a, 0x09, 0x7b,
-0x0d, 0x0a, 0x0d, 0x0a, 0x09, 0x09, 0x62, 0x65, 0x67, 0x69, 0x6e, 0x65,
-0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x28, 0x22, 0x63, 0x61, 0x6c, 0x6c,
-0x22, 0x29, 0x3b, 0x0d, 0x0a, 0x09, 0x09, 0x61, 0x74, 0x74, 0x72, 0x69,
-0x62, 0x75, 0x74, 0x65, 0x28, 0x22, 0x66, 0x6e, 0x63, 0x22, 0x2c, 0x76,
-0x61, 0x6c, 0x2e, 0x66, 0x75, 0x6e, 0x63, 0x29, 0x3b, 0x0d, 0x0a, 0x09,
-0x09, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x28, 0x22,
-0x73, 0x72, 0x63, 0x22, 0x2c, 0x76, 0x61, 0x6c, 0x2e, 0x73, 0x72, 0x63,
-0x29, 0x3b, 0x0d, 0x0a, 0x09, 0x09, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62,
-0x75, 0x74, 0x65, 0x28, 0x22, 0x6c, 0x69, 0x6e, 0x65, 0x22, 0x2c, 0x76,
-0x61, 0x6c, 0x2e, 0x6c, 0x69, 0x6e, 0x65, 0x2e, 0x74, 0x6f, 0x73, 0x74,
-0x72, 0x69, 0x6e, 0x67, 0x28, 0x29, 0x29, 0x3b, 0x0d, 0x0a, 0x09, 0x09,
-0x66, 0x6f, 0x72, 0x65, 0x61, 0x63, 0x68, 0x28, 0x69, 0x2c, 0x76, 0x20,
-0x69, 0x6e, 0x20, 0x76, 0x61, 0x6c, 0x2e, 0x6c, 0x6f, 0x63, 0x61, 0x6c,
-0x73, 0x29, 0x0d, 0x0a, 0x09, 0x09, 0x7b, 0x0d, 0x0a, 0x09, 0x09, 0x09,
-0x62, 0x65, 0x67, 0x69, 0x6e, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74,
-0x28, 0x22, 0x6c, 0x22, 0x29, 0x3b, 0x0d, 0x0a, 0x09, 0x09, 0x09, 0x09,
-0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x28, 0x22, 0x6e,
-0x61, 0x6d, 0x65, 0x22, 0x2c, 0x67, 0x65, 0x74, 0x76, 0x61, 0x6c, 0x75,
-0x65, 0x28, 0x69, 0x29, 0x2e, 0x74, 0x6f, 0x73, 0x74, 0x72, 0x69, 0x6e,
-0x67, 0x28, 0x29, 0x29, 0x3b, 0x0d, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x65,
-0x6d, 0x69, 0x74, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x28, 0x22, 0x74, 0x79,
-0x70, 0x65, 0x22, 0x2c, 0x22, 0x76, 0x61, 0x6c, 0x22, 0x2c, 0x76, 0x29,
-0x3b, 0x0d, 0x0a, 0x09, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x65, 0x6c, 0x65,
-0x6d, 0x65, 0x6e, 0x74, 0x28, 0x22, 0x6c, 0x22, 0x29, 0x3b, 0x0d, 0x0a,
-0x09, 0x09, 0x7d, 0x0d, 0x0a, 0x09, 0x09, 0x69, 0x66, 0x28, 0x22, 0x77,
-0x61, 0x74, 0x63, 0x68, 0x65, 0x73, 0x22, 0x20, 0x69, 0x6e, 0x20, 0x76,
-0x61, 0x6c, 0x29, 0x20, 0x7b, 0x0d, 0x0a, 0x09, 0x09, 0x09, 0x66, 0x6f,
-0x72, 0x65, 0x61, 0x63, 0x68, 0x28, 0x69, 0x2c, 0x76, 0x20, 0x69, 0x6e,
-0x20, 0x76, 0x61, 0x6c, 0x2e, 0x77, 0x61, 0x74, 0x63, 0x68, 0x65, 0x73,
-0x29, 0x0d, 0x0a, 0x09, 0x09, 0x09, 0x7b, 0x0d, 0x0a, 0x09, 0x09, 0x09,
-0x09, 0x62, 0x65, 0x67, 0x69, 0x6e, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e,
-0x74, 0x28, 0x22, 0x77, 0x22, 0x29, 0x3b, 0x0d, 0x0a, 0x09, 0x09, 0x09,
-0x09, 0x09, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x28,
-0x22, 0x69, 0x64, 0x22, 0x2c, 0x69, 0x2e, 0x74, 0x6f, 0x73, 0x74, 0x72,
-0x69, 0x6e, 0x67, 0x28, 0x29, 0x29, 0x3b, 0x0d, 0x0a, 0x09, 0x09, 0x09,
-0x09, 0x09, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x28,
-0x22, 0x65, 0x78, 0x70, 0x22, 0x2c, 0x76, 0x2e, 0x65, 0x78, 0x70, 0x29,
-0x3b, 0x0d, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x61, 0x74, 0x74, 0x72,
-0x69, 0x62, 0x75, 0x74, 0x65, 0x28, 0x22, 0x73, 0x74, 0x61, 0x74, 0x75,
-0x73, 0x22, 0x2c, 0x76, 0x2e, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x29,
-0x3b, 0x0d, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x69, 0x66, 0x28, 0x76,
-0x2e, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x21, 0x3d, 0x22, 0x65, 0x72,
-0x72, 0x6f, 0x72, 0x22, 0x29, 0x20, 0x7b, 0x0d, 0x0a, 0x09, 0x09, 0x09,
-0x09, 0x09, 0x09, 0x65, 0x6d, 0x69, 0x74, 0x76, 0x61, 0x6c, 0x75, 0x65,
-0x28, 0x22, 0x74, 0x79, 0x70, 0x65, 0x22, 0x2c, 0x22, 0x76, 0x61, 0x6c,
-0x22, 0x2c, 0x76, 0x2e, 0x76, 0x61, 0x6c, 0x29, 0x3b, 0x0d, 0x0a, 0x09,
-0x09, 0x09, 0x09, 0x09, 0x7d, 0x0d, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x65,
-0x6e, 0x64, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x28, 0x22, 0x77,
-0x22, 0x29, 0x3b, 0x0d, 0x0a, 0x09, 0x09, 0x09, 0x7d, 0x0d, 0x0a, 0x09,
-0x09, 0x7d, 0x0d, 0x0a, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x65, 0x6c, 0x65,
-0x6d, 0x65, 0x6e, 0x74, 0x28, 0x22, 0x63, 0x61, 0x6c, 0x6c, 0x22, 0x29,
-0x3b, 0x0d, 0x0a, 0x09, 0x09, 0x20, 0x0d, 0x0a, 0x09, 0x7d, 0x0d, 0x0a,
-0x09, 0x65, 0x6e, 0x64, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x28,
-0x22, 0x63, 0x61, 0x6c, 0x6c, 0x73, 0x22, 0x29, 0x3b, 0x0d, 0x0a, 0x0d,
-0x0a, 0x0d, 0x0a, 0x09, 0x6f, 0x62, 0x6a, 0x73, 0x5f, 0x72, 0x65, 0x67,
-0x20, 0x3d, 0x20, 0x6e, 0x75, 0x6c, 0x6c, 0x3b, 0x0d, 0x0a, 0x09, 0x73,
-0x74, 0x61, 0x63, 0x6b, 0x20, 0x3d, 0x20, 0x6e, 0x75, 0x6c, 0x6c, 0x3b,
-0x0d, 0x0a, 0x09, 0x0d, 0x0a, 0x09, 0x69, 0x66, 0x28, 0x22, 0x63, 0x6f,
-0x6c, 0x6c, 0x65, 0x63, 0x74, 0x67, 0x61, 0x72, 0x62, 0x61, 0x67, 0x65,
-0x22, 0x20, 0x69, 0x6e, 0x20, 0x3a, 0x3a, 0x67, 0x65, 0x74, 0x72, 0x6f,
-0x6f, 0x74, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x28, 0x29, 0x29, 0x20, 0x3a,
-0x3a, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x67, 0x61, 0x72, 0x62,
-0x61, 0x67, 0x65, 0x28, 0x29, 0x3b, 0x0d, 0x0a, 0x7d, 0x63, 0x61, 0x74,
-0x63, 0x68, 0x28, 0x65, 0x29, 0x0d, 0x0a, 0x7b, 0x0d, 0x0a, 0x09, 0x3a,
-0x3a, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x28, 0x22, 0x45, 0x52, 0x52, 0x4f,
-0x52, 0x22, 0x2b, 0x65, 0x2b, 0x22, 0x5c, 0x6e, 0x22, 0x29, 0x3b, 0x0d,
-0x0a, 0x7d, 0x0d, 0x0a, 0x0d, 0x0a, 0x00,
-};
+++ /dev/null
-#include <squirrel.h>
-#include <assert.h>
-#include <sqstdblob.h>
-#include "sqrdbg.h"
-#include "sqdbgserver.h"
-
-
-#ifndef _UNICODE
-#define scstrcpy strcpy
-#else
-#define scstrcpy wcscpy
-#endif
-struct XMLEscape{
- const SQChar c;
- const SQChar *esc;
-};
-
-#define SQDBG_DEBUG_HOOK _SC("_sqdbg_debug_hook_")
-#define SQDBG_ERROR_HANDLER _SC("_sqdbg_error_handler_")
-
-XMLEscape g_escapes[]={
- {_SC('<'),_SC("<")},{'>',_SC(">")},{_SC('&'),_SC("&")},{_SC('\''),_SC("'")},{_SC('\"'),_SC(""")},{_SC('\n'),_SC(""n")},{_SC('\r'),_SC(""r")},{0, NULL}
-};
-
-const SQChar *IntToString(int n)
-{
- static SQChar temp[256];
- scsprintf(temp,_SC("%d"),n);
- return temp;
-}
-
-SQInteger debug_hook(HSQUIRRELVM v);
-SQInteger error_handler(HSQUIRRELVM v);
-
-SQInteger beginelement(HSQUIRRELVM v)
-{
- SQUserPointer up;
- const SQChar *name;
- sq_getuserpointer(v,-1,&up);
- SQDbgServer *self = (SQDbgServer*)up;
- sq_getuserpointer(v,-1,&up);
- sq_getstring(v,2,&name);
- self->BeginElement(name);
- return 0;
-}
-
-SQInteger endelement(HSQUIRRELVM v)
-{
- SQUserPointer up;
- const SQChar *name;
- sq_getuserpointer(v,-1,&up);
- SQDbgServer *self = (SQDbgServer*)up;
- sq_getuserpointer(v,-1,&up);
- sq_getstring(v,2,&name);
- self->EndElement(name);
- return 0;
-}
-
-SQInteger attribute(HSQUIRRELVM v)
-{
- SQUserPointer up;
- const SQChar *name,*value;
- sq_getuserpointer(v,-1,&up);
- SQDbgServer *self = (SQDbgServer*)up;
- sq_getuserpointer(v,-1,&up);
- sq_getstring(v,2,&name);
- sq_getstring(v,3,&value);
- self->Attribute(name,value);
- return 0;
-}
-
-const SQChar *EscapeXMLString(HSQUIRRELVM v,const SQChar *s)
-{
-
- SQChar *temp=sq_getscratchpad(v,((int)scstrlen(s)*6) + sizeof(SQChar));
- SQChar *dest=temp;
- while(*s!=_SC('\0')){
- int i=0;
- bool escaped=false;
- while(g_escapes[i].esc!=NULL){
- if(*s==g_escapes[i].c){
- scstrcpy(dest,g_escapes[i].esc);
- dest+=scstrlen(g_escapes[i].esc);
- escaped=true;
- break;
- }
- i++;
- }
- if(!escaped){*dest=*s;*dest++;}
- *s++;
- }
- *dest=_SC('\0');
- return temp;
-}
-
-SQDbgServer::SQDbgServer(HSQUIRRELVM v)
-{
- _ready = false;
- _nestedcalls = 0;
- _autoupdate = false;
- _v = v;
- _state = eDBG_Running;
- _accept = INVALID_SOCKET;
- _endpoint = INVALID_SOCKET;
- _maxrecursion = 10;
- sq_resetobject(&_debugroot);
-}
-
-SQDbgServer::~SQDbgServer()
-{
- sq_release(_v,&_debugroot);
- if(_accept != INVALID_SOCKET)
- sqdbg_closesocket(_accept);
- if(_endpoint != INVALID_SOCKET)
- sqdbg_closesocket(_endpoint);
-}
-
-bool SQDbgServer::Init()
-{
- //creates an environment table for the debugger
-
- sq_newtable(_v);
- sq_getstackobj(_v,-1,&_debugroot);
- sq_addref(_v,&_debugroot);
-
- //creates a emptyslot to store the watches
- sq_pushstring(_v,_SC("watches"),-1);
- sq_pushnull(_v);
- sq_createslot(_v,-3);
-
- sq_pushstring(_v,_SC("beginelement"),-1);
- sq_pushuserpointer(_v,this);
- sq_newclosure(_v,beginelement,1);
- sq_setparamscheck(_v,2,_SC(".s"));
- sq_createslot(_v,-3);
-
- sq_pushstring(_v,_SC("endelement"),-1);
- sq_pushuserpointer(_v,this);
- sq_newclosure(_v,endelement,1);
- sq_setparamscheck(_v,2,_SC(".s"));
- sq_createslot(_v,-3);
-
- sq_pushstring(_v,_SC("attribute"),-1);
- sq_pushuserpointer(_v,this);
- sq_newclosure(_v,attribute,1);
- sq_setparamscheck(_v,3,_SC(".ss"));
- sq_createslot(_v,-3);
-
- sq_pop(_v,1);
-
- //stores debug hook and error handler in the registry
- sq_pushregistrytable(_v);
-
- sq_pushstring(_v,SQDBG_DEBUG_HOOK,-1);
- sq_pushuserpointer(_v,this);
- sq_newclosure(_v,debug_hook,1);
- sq_createslot(_v,-3);
-
- sq_pushstring(_v,SQDBG_ERROR_HANDLER,-1);
- sq_pushuserpointer(_v,this);
- sq_newclosure(_v,error_handler,1);
- sq_createslot(_v,-3);
-
-
- sq_pop(_v,1);
-
- //sets the error handlers
- SetErrorHandlers();
- return true;
-}
-
-bool SQDbgServer::ReadMsg()
-{
- return false;
-}
-
-void SQDbgServer::BusyWait()
-{
- while( !ReadMsg() )
- sleep(0);
-}
-
-void SQDbgServer::SendChunk(const SQChar *chunk)
-{
- char *buf=NULL;
- int buf_len=0;
-#ifdef _UNICODE
- buf_len=(int)scstrlen(chunk)+1;
- buf=(char *)sq_getscratchpad(_v,(buf_len)*3);
- wcstombs((char *)buf,chunk,buf_len);
-#else
- buf_len=(int)scstrlen(chunk);
- buf=(char *)chunk;
-#endif
- send(_endpoint,(const char*)buf,(int)strlen((const char *)buf),0);
-}
-
-
-void SQDbgServer::Terminated()
-{
- BeginElement(_SC("terminated"));
- EndElement(_SC("terminated"));
- ::usleep(200);
-}
-
-void SQDbgServer::Hook(int type,int line,const SQChar *src,const SQChar *func)
-{
- switch(_state){
- case eDBG_Running:
- if(type==_SC('l') && _breakpoints.size()) {
- BreakPointSetItor itr = _breakpoints.find(BreakPoint(line,src));
- if(itr != _breakpoints.end()) {
- Break(line,src,_SC("breakpoint"));
- BreakExecution();
- }
- }
- break;
- case eDBG_Suspended:
- _nestedcalls=0;
- case eDBG_StepOver:
- switch(type){
- case _SC('l'):
- if(_nestedcalls==0) {
- Break(line,src,_SC("step"));
- BreakExecution();
- }
- break;
- case _SC('c'):
- _nestedcalls++;
- break;
- case _SC('r'):
- if(_nestedcalls==0){
- _nestedcalls=0;
-
- }else{
- _nestedcalls--;
- }
- break;
- }
- break;
- case eDBG_StepInto:
- switch(type){
- case _SC('l'):
- _nestedcalls=0;
- Break(line,src,_SC("step"));
- BreakExecution();
- break;
-
- }
- break;
- case eDBG_StepReturn:
- switch(type){
- case _SC('l'):
- break;
- case _SC('c'):
- _nestedcalls++;
- break;
- case _SC('r'):
- if(_nestedcalls==0){
- _nestedcalls=0;
- _state=eDBG_StepOver;
- }else{
- _nestedcalls--;
- }
-
- break;
- }
- break;
- case eDBG_Disabled:
- break;
- }
-}
-
-
-#define MSG_ID(x,y) ((y<<8)|x)
-//ab Add Breakpoint
-//rb Remove Breakpoint
-//sp Suspend
-void SQDbgServer::ParseMsg(const char *msg)
-{
-
- switch(*((unsigned short *)msg)){
- case MSG_ID('a','b'): {
- BreakPoint bp;
- if(ParseBreakpoint(msg+3,bp)){
- AddBreakpoint(bp);
- scprintf(_SC("added bp %d %s\n"),bp._line,bp._src.c_str());
- }
- else
- scprintf(_SC("error parsing add breakpoint"));
- }
- break;
- case MSG_ID('r','b'): {
- BreakPoint bp;
- if(ParseBreakpoint(msg+3,bp)){
- RemoveBreakpoint(bp);
- scprintf(_SC("removed bp %d %s\n"),bp._line,bp._src.c_str());
- }else
- scprintf(_SC("error parsing remove breakpoint"));
- }
- break;
- case MSG_ID('g','o'):
- if(_state!=eDBG_Running){
- _state=eDBG_Running;
- BeginDocument();
- BeginElement(_SC("resumed"));
- EndElement(_SC("resumed"));
- EndDocument();
-// Send(_SC("<resumed/>\r\n"));
- scprintf(_SC("go (execution resumed)\n"));
- }
- break;
- case MSG_ID('s','p'):
- if(_state!=eDBG_Suspended){
- _state=eDBG_Suspended;
- scprintf(_SC("suspend\n"));
- }
- break;
- case MSG_ID('s','o'):
- if(_state==eDBG_Suspended){
- _state=eDBG_StepOver;
- }
- break;
- case MSG_ID('s','i'):
- if(_state==eDBG_Suspended){
- _state=eDBG_StepInto;
- scprintf(_SC("step into\n"));
- }
- break;
- case MSG_ID('s','r'):
- if(_state==eDBG_Suspended){
- _state=eDBG_StepReturn;
- scprintf(_SC("step return\n"));
- }
- break;
- case MSG_ID('d','i'):
- if(_state!=eDBG_Disabled){
- _state=eDBG_Disabled;
- scprintf(_SC("disabled\n"));
- }
- break;
- case MSG_ID('a','w'): {
- Watch w;
- if(ParseWatch(msg+3,w))
- {
- AddWatch(w);
- scprintf(_SC("added watch %d %s\n"),w._id,w._exp.c_str());
- }
- else
- scprintf(_SC("error parsing add watch"));
- }
- break;
- case MSG_ID('r','w'): {
- int id;
- if(ParseRemoveWatch(msg+3,id))
- {
- RemoveWatch(id);
- scprintf(_SC("added watch %d\n"),id);
- }
- else
- scprintf(_SC("error parsing remove watch"));
- }
- break;
- case MSG_ID('t','r'):
- scprintf(_SC("terminate from user\n"));
- break;
- case MSG_ID('r','d'):
- scprintf(_SC("ready\n"));
- _ready=true;
- break;
- default:
- scprintf(_SC("unknown packet"));
-
- }
-}
-
-/*
- see copyright notice in sqrdbg.h
-*/
-bool SQDbgServer::ParseBreakpoint(const char *msg,BreakPoint &out)
-{
- static char stemp[MAX_BP_PATH];
- char *ep=NULL;
- out._line=strtoul(msg,&ep,16);
- if(ep==msg || (*ep)!=':')return false;
-
- char *dest=stemp;
- ep++;
- while((*ep)!='\n' && (*ep)!='\0')
- {
- *dest=*ep;
- *dest++;*ep++;
- }
- *dest='\0';
- *dest++;
- *dest='\0';
-#ifdef _UNICODE
- int len=(int)strlen(stemp);
- SQChar *p=sq_getscratchpad(_v,(SQInteger)(mbstowcs(NULL,stemp,len)+2)*sizeof(SQChar));
- size_t destlen=mbstowcs(p,stemp,len);
- p[destlen]=_SC('\0');
- out._src=p;
-#else
- out._src=stemp;
-#endif
- return true;
-}
-
-bool SQDbgServer::ParseWatch(const char *msg,Watch &out)
-{
- char *ep=NULL;
- out._id=strtoul(msg,&ep,16);
- if(ep==msg || (*ep)!=':')return false;
-
- //char *dest=out._src;
- ep++;
- while((*ep)!='\n' && (*ep)!='\0')
- {
- out._exp.append(1,*ep);
- *ep++;
- }
- return true;
-}
-
-bool SQDbgServer::ParseRemoveWatch(const char *msg,int &id)
-{
- char *ep=NULL;
- id=strtoul(msg,&ep,16);
- if(ep==msg)return false;
- return true;
-}
-
-
-void SQDbgServer::BreakExecution()
-{
- _state=eDBG_Suspended;
- while(_state==eDBG_Suspended){
- if(SQ_FAILED(sq_rdbg_update(this)))
- exit(0);
- usleep(10);
- }
-}
-
-//COMMANDS
-void SQDbgServer::AddBreakpoint(BreakPoint &bp)
-{
- _breakpoints.insert(bp);
- BeginDocument();
- BeginElement(_SC("addbreakpoint"));
- Attribute(_SC("line"),IntToString(bp._line));
- Attribute(_SC("src"),bp._src.c_str());
- EndElement(_SC("addbreakpoint"));
- EndDocument();
-}
-
-void SQDbgServer::AddWatch(Watch &w)
-{
- _watches.insert(w);
-}
-
-void SQDbgServer::RemoveWatch(int id)
-{
- WatchSetItor itor=_watches.find(Watch(id,_SC("")));
- if(itor==_watches.end()){
- BeginDocument();
- BeginElement(_SC("error"));
- Attribute(_SC("desc"),_SC("the watch does not exists"));
- EndElement(_SC("error"));
- EndDocument();
- }
- else{
- _watches.erase(itor);
- scprintf(_SC("removed watch %d\n"),id);
- }
-}
-
-void SQDbgServer::RemoveBreakpoint(BreakPoint &bp)
-{
- BreakPointSetItor itor=_breakpoints.find(bp);
- if(itor==_breakpoints.end()){
- BeginDocument();
- BeginElement(_SC("break"));
- Attribute(_SC("desc"),_SC("the breakpoint doesn't exists"));
- EndElement(_SC("break"));
- EndDocument();
- }
- else{
- BeginDocument();
- BeginElement(_SC("removebreakpoint"));
- Attribute(_SC("line"),IntToString(bp._line));
- Attribute(_SC("src"),bp._src.c_str());
- EndElement(_SC("removebreakpoint"));
- EndDocument();
- _breakpoints.erase(itor);
- }
-}
-
-void SQDbgServer::Break(int line,const SQChar *src,const SQChar *type,const SQChar *error)
-{
- if(!error){
- BeginDocument();
- BeginElement(_SC("break"));
- Attribute(_SC("line"),IntToString(line));
- Attribute(_SC("src"),src);
- Attribute(_SC("type"),type);
- SerializeState();
- EndElement(_SC("break"));
- EndDocument();
- }else{
- BeginDocument();
- BeginElement(_SC("break"));
- Attribute(_SC("line"),IntToString(line));
- Attribute(_SC("src"),src);
- Attribute(_SC("type"),type);
- Attribute(_SC("error"),error);
- SerializeState();
- EndElement(_SC("break"));
- EndDocument();
- }
-}
-
-void SQDbgServer::SerializeState()
-{
- sq_pushnull(_v);
- sq_setdebughook(_v);
- sq_pushnull(_v);
- sq_seterrorhandler(_v);
- const SQChar *sz;
- sq_pushobject(_v,_serializefunc);
- sq_pushobject(_v,_debugroot);
- sq_pushstring(_v,_SC("watches"),-1);
- sq_newtable(_v);
- for(WatchSetItor i=_watches.begin(); i!=_watches.end(); ++i)
- {
- sq_pushinteger(_v,i->_id);
- sq_pushstring(_v,i->_exp.c_str(),(int)i->_exp.length());
- sq_createslot(_v,-3);
- }
- sq_rawset(_v,-3);
- if(SQ_SUCCEEDED(sq_call(_v,1,SQTrue,SQTrue))){
- if(SQ_SUCCEEDED(sqstd_getblob(_v,-1,(SQUserPointer*)&sz)))
- SendChunk(sz);
- }
- sq_pop(_v,2);
-
- SetErrorHandlers();
-}
-
-
-void SQDbgServer::SetErrorHandlers()
-{
- sq_pushregistrytable(_v);
- sq_pushstring(_v,SQDBG_DEBUG_HOOK,-1);
- sq_rawget(_v,-2);
- sq_setdebughook(_v);
- sq_pushstring(_v,SQDBG_ERROR_HANDLER,-1);
- sq_rawget(_v,-2);
- sq_seterrorhandler(_v);
- sq_pop(_v,1);
-}
-
-void SQDbgServer::BeginElement(const SQChar *name)
-{
- _xmlcurrentement++;
- XMLElementState *self = &xmlstate[_xmlcurrentement];
- scstrcpy(self->name,name);
- self->haschildren = false;
- if(_xmlcurrentement > 0) {
- XMLElementState *parent = &xmlstate[_xmlcurrentement-1];
- if(!parent->haschildren) {
- SendChunk(_SC(">")); // closes the parent tag
- parent->haschildren = true;
- }
- }
- _scratchstring.resize(2+scstrlen(name));
- scsprintf(&_scratchstring[0],_SC("<%s"),name);
- SendChunk(&_scratchstring[0]);
-}
-
-void SQDbgServer::Attribute(const SQChar *name,const SQChar *value)
-{
- XMLElementState *self = &xmlstate[_xmlcurrentement];
- assert(!self->haschildren); //cannot have attributes if already has children
- const SQChar *escval = escape_xml(value);
- _scratchstring.resize(5+scstrlen(name)+scstrlen(escval));
- scsprintf(&_scratchstring[0],_SC(" %s=\"%s\""),name,escval);
- SendChunk(&_scratchstring[0]);
-}
-
-void SQDbgServer::EndElement(const SQChar *name)
-{
- XMLElementState *self = &xmlstate[_xmlcurrentement];
- assert(scstrcmp(self->name,name) == 0);
- if(self->haschildren) {
- _scratchstring.resize(4+scstrlen(name));
- scsprintf(&_scratchstring[0],_SC("</%s>"),name);
- SendChunk(&_scratchstring[0]);
-
- }
- else {
- SendChunk(_SC("/>"));
- }
- _xmlcurrentement--;
-}
-
-void SQDbgServer::EndDocument()
-{
- SendChunk(_SC("\r\n"));
-}
-
-//this can be done much better/faster(do we need that?)
-const SQChar *SQDbgServer::escape_xml(const SQChar *s)
-{
- SQChar *temp=sq_getscratchpad(_v,((int)scstrlen(s)*6) + sizeof(SQChar));
- SQChar *dest=temp;
- while(*s!=_SC('\0')){
- int i=0;
- bool escaped=false;
- while(g_escapes[i].esc!=NULL){
- if(*s==g_escapes[i].c){
- scstrcpy(dest,g_escapes[i].esc);
- dest+=scstrlen(g_escapes[i].esc);
- escaped=true;
- break;
- }
- i++;
- }
- if(!escaped){*dest=*s;*dest++;}
- *s++;
- }
- *dest=_SC('\0');
- return temp;
-
-}
+++ /dev/null
-#ifndef _SQ_DBGSERVER_H_
-#define _SQ_DBGSERVER_H_
-
-#define MAX_BP_PATH 512
-#define MAX_MSG_LEN 2049
-
-#include <set>
-#include <string>
-#include <vector>
-
-#ifdef _WIN32
-#include <winsock.h>
-#define sqdbg_closesocket(x) closesocket((x))
-typedef socklen_t int;
-#else
-#include <unistd.h>
-#include <errno.h>
-#include <sys/socket.h>
-#include <sys/types.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <netdb.h>
-#include <fcntl.h>
-
-#define sqdbg_closesocket(x) close((x))
-typedef int SOCKET;
-typedef struct timeval TIMEVAL;
-#define SOCKET_ERROR -1
-#define INVALID_SOCKET -1
-#endif
-
-typedef std::basic_string<SQChar> SQDBGString;
-
-inline bool dbg_less(const SQChar *x,const SQChar *y)
-{
- // [SuperTux] commented out to avoid compiler warning
- //int n = 0;
- do {
- int xl = *x == '\\' ? '/' : tolower(*x);
- int yl = *y == '\\' ? '/' : tolower(*y);
- int diff = xl - yl;
- if(diff != 0)
- return diff > 0?true:false;
- x++; y++;
- }while(*x != 0 && *y != 0);
- return false;
-}
-
-struct BreakPoint{
- BreakPoint(){_line=0;}
- BreakPoint(int line, const SQChar *src){ _line = line; _src = src; }
- BreakPoint(const BreakPoint& bp){ _line = bp._line; _src=bp._src; }
- inline bool operator<(const BreakPoint& bp) const
- {
- if(_line<bp._line)
- return true;
- if(_line==bp._line){
- return dbg_less(_src.c_str(),bp._src.c_str());
- }
- return false;
- }
-
- int _line;
- SQDBGString _src;
-};
-
-struct Watch{
- Watch() { _id = 0; }
- Watch(int id,const SQChar *exp) { _id = id; _exp = exp; }
- Watch(const Watch &w) { _id = w._id; _exp = w._exp; }
- bool operator<(const Watch& w) const { return _id<w._id; }
- bool operator==(const Watch& w) const { return _id == w._id; }
- int _id;
- SQDBGString _exp;
-};
-
-typedef std::set<BreakPoint> BreakPointSet;
-typedef BreakPointSet::iterator BreakPointSetItor;
-
-typedef std::set<Watch> WatchSet;
-typedef WatchSet::iterator WatchSetItor;
-
-typedef std::vector<SQChar> SQCharVec;
-struct SQDbgServer{
-public:
- enum eDbgState{
- eDBG_Running,
- eDBG_StepOver,
- eDBG_StepInto,
- eDBG_StepReturn,
- eDBG_Suspended,
- eDBG_Disabled,
- };
-
- SQDbgServer(HSQUIRRELVM v);
- ~SQDbgServer();
- bool Init();
- //returns true if a message has been received
- bool WaitForClient();
- bool ReadMsg();
- void BusyWait();
- void Hook(int type,int line,const SQChar *src,const SQChar *func);
- void ParseMsg(const char *msg);
- bool ParseBreakpoint(const char *msg,BreakPoint &out);
- bool ParseWatch(const char *msg,Watch &out);
- bool ParseRemoveWatch(const char *msg,int &id);
- void Terminated();
- //
- void BreakExecution();
- void Send(const SQChar *s,...);
- void SendChunk(const SQChar *chunk);
- void Break(int line,const SQChar *src,const SQChar *type,const SQChar *error=NULL);
-
-
- void SerializeState();
- //COMMANDS
- void AddBreakpoint(BreakPoint &bp);
- void AddWatch(Watch &w);
- void RemoveWatch(int id);
- void RemoveBreakpoint(BreakPoint &bp);
-
- //
- void SetErrorHandlers();
-
- //XML RELATED STUFF///////////////////////
- #define MAX_NESTING 10
- struct XMLElementState {
- SQChar name[256];
- bool haschildren;
- };
-
- XMLElementState xmlstate[MAX_NESTING];
- int _xmlcurrentement;
-
- void BeginDocument() { _xmlcurrentement = -1; }
- void BeginElement(const SQChar *name);
- void Attribute(const SQChar *name, const SQChar *value);
- void EndElement(const SQChar *name);
- void EndDocument();
-
- const SQChar *escape_xml(const SQChar *x);
- //////////////////////////////////////////////
- HSQUIRRELVM _v;
- HSQOBJECT _debugroot;
- eDbgState _state;
- SOCKET _accept;
- SOCKET _endpoint;
- BreakPointSet _breakpoints;
- WatchSet _watches;
- int _recursionlevel;
- int _maxrecursion;
- int _nestedcalls;
- bool _ready;
- bool _autoupdate;
- HSQOBJECT _serializefunc;
- SQCharVec _scratchstring;
-
-};
-
-#endif //_SQ_DBGSERVER_H_
+++ /dev/null
-/*
- see copyright notice in sqrdbg.h
-*/
-#include <squirrel.h>
-#include "sqrdbg.h"
-#include "sqdbgserver.h"
-SQInteger debug_hook(HSQUIRRELVM v);
-SQInteger error_handler(HSQUIRRELVM v);
-
-#include "serialize_state.inl"
-
-HSQREMOTEDBG sq_rdbg_init(HSQUIRRELVM v,unsigned short port,SQBool autoupdate)
-{
- sockaddr_in bindaddr;
-#ifdef _WIN32
- WSADATA wsadata;
- if (WSAStartup (MAKEWORD(1,1), &wsadata) != 0){
- return NULL;
- }
-#endif
-
- SQDbgServer *rdbg = new SQDbgServer(v);
- rdbg->_autoupdate = autoupdate?true:false;
- rdbg->_accept = socket(AF_INET,SOCK_STREAM,0);
- bindaddr.sin_family = AF_INET;
- bindaddr.sin_port = htons(port);
- bindaddr.sin_addr.s_addr = htonl (INADDR_ANY);
- if(bind(rdbg->_accept,(sockaddr*)&bindaddr,sizeof(bindaddr))==SOCKET_ERROR){
- delete rdbg;
- sq_throwerror(v,_SC("failed to bind the socket"));
- return NULL;
- }
- if(!rdbg->Init()) {
- delete rdbg;
- sq_throwerror(v,_SC("failed to initialize the debugger"));
- return NULL;
- }
-
- return rdbg;
-}
-
-SQRESULT sq_rdbg_waitforconnections(HSQREMOTEDBG rdbg)
-{
- if(SQ_FAILED(sq_compilebuffer(rdbg->_v,serialize_state_nut,(SQInteger)scstrlen(serialize_state_nut),_SC("SERIALIZE_STATE"),SQFalse))) {
- sq_throwerror(rdbg->_v,_SC("error compiling the serialization function"));
- }
- sq_getstackobj(rdbg->_v,-1,&rdbg->_serializefunc);
- sq_addref(rdbg->_v,&rdbg->_serializefunc);
- sq_pop(rdbg->_v,1);
-
- sockaddr_in cliaddr;
- socklen_t addrlen=sizeof(cliaddr);
- if(listen(rdbg->_accept,0)==SOCKET_ERROR)
- return sq_throwerror(rdbg->_v,_SC("error on listen(socket)"));
- rdbg->_endpoint = accept(rdbg->_accept,(sockaddr*)&cliaddr,&addrlen);
- //do not accept any other connection
- sqdbg_closesocket(rdbg->_accept);
- rdbg->_accept = INVALID_SOCKET;
- if(rdbg->_endpoint==INVALID_SOCKET){
- return sq_throwerror(rdbg->_v,_SC("error accept(socket)"));
- }
- while(!rdbg->_ready){
- sq_rdbg_update(rdbg);
- }
- return SQ_OK;
-}
-
-SQRESULT sq_rdbg_update(HSQREMOTEDBG rdbg)
-{
- TIMEVAL time;
- time.tv_sec=0;
- time.tv_usec=0;
- fd_set read_flags;
- FD_ZERO(&read_flags);
- FD_SET(rdbg->_endpoint, &read_flags);
- select(FD_SETSIZE, &read_flags, NULL, NULL, &time);
-
- if(FD_ISSET(rdbg->_endpoint,&read_flags)){
- char temp[1024];
- int size=0;
- char c,prev=0;
- memset(&temp,0,sizeof(temp));
- int res;
- FD_CLR(rdbg->_endpoint, &read_flags);
- while((res = recv(rdbg->_endpoint,&c,1,0))>0){
-
- if(c=='\n')break;
- if(c!='\r'){
- temp[size]=c;
- prev=c;
- size++;
- }
- }
- switch(res){
- case 0:
- return sq_throwerror(rdbg->_v,_SC("disconnected"));
- case SOCKET_ERROR:
- return sq_throwerror(rdbg->_v,_SC("socket error"));
- }
-
- temp[size]=0;
- temp[size+1]=0;
- rdbg->ParseMsg(temp);
- }
- return SQ_OK;
-}
-
-SQInteger debug_hook(HSQUIRRELVM v)
-{
- SQUserPointer up;
- SQInteger event_type,line;
- const SQChar *src,*func;
- sq_getinteger(v,2,&event_type);
- sq_getstring(v,3,&src);
- sq_getinteger(v,4,&line);
- sq_getstring(v,5,&func);
- sq_getuserpointer(v,-1,&up);
- HSQREMOTEDBG rdbg = (HSQREMOTEDBG)up;
- rdbg->Hook(event_type,line,src,func);
- if(rdbg->_autoupdate) {
- if(SQ_FAILED(sq_rdbg_update(rdbg)))
- return sq_throwerror(v,_SC("socket failed"));
- }
- return 0;
-}
-
-SQInteger error_handler(HSQUIRRELVM v)
-{
- SQUserPointer up;
- const SQChar *sErr=NULL;
- const SQChar *fn=_SC("unknown");
- const SQChar *src=_SC("unknown");
- int line=-1;
- SQStackInfos si;
- sq_getuserpointer(v,-1,&up);
- HSQREMOTEDBG rdbg=(HSQREMOTEDBG)up;
- if(SQ_SUCCEEDED(sq_stackinfos(v,1,&si)))
- {
- if(si.funcname)fn=si.funcname;
- if(si.source)src=si.source;
- line=si.line;
- scprintf(_SC("*FUNCTION [%s] %s line [%d]\n"),fn,src,si.line);
- }
- if(sq_gettop(v)>=1){
- if(SQ_SUCCEEDED(sq_getstring(v,2,&sErr))) {
- scprintf(_SC("\nAN ERROR HAS OCCURED [%s]\n"),sErr);
- rdbg->Break(si.line,src,_SC("error"),sErr);
- }
- else{
- scprintf(_SC("\nAN ERROR HAS OCCURED [unknown]\n"));
- rdbg->Break(si.line,src,_SC("error"),_SC("unknown"));
- }
- }
- rdbg->BreakExecution();
- return 0;
-}
-
-
-SQRESULT sq_rdbg_shutdown(HSQREMOTEDBG rdbg)
-{
- delete rdbg;
-#ifdef _WIN32
- WSACleanup();
-#endif
- return SQ_OK;
-}
+++ /dev/null
-/*
-Copyright (c) 2003-2005 Alberto Demichelis
-
-This software is provided 'as-is', without any
-express or implied warranty. In no event will the
-authors be held liable for any damages arising from
-the use of this software.
-
-Permission is granted to anyone to use this software
-for any purpose, including commercial applications,
-and to alter it and redistribute it freely, subject
-to the following restrictions:
-
- 1. The origin of this software must not be
- misrepresented; you must not claim that
- you wrote the original software. If you
- use this software in a product, an
- acknowledgment in the product
- documentation would be appreciated but is
- not required.
-
- 2. Altered source versions must be plainly
- marked as such, and must not be
- misrepresented as being the original
- software.
-
- 3. This notice may not be removed or
- altered from any source distribution.
-
-*/
-#ifndef _SQ_RDBG_H_
-#define _SQ_RDBG_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct SQDbgServer;
-typedef SQDbgServer* HSQREMOTEDBG;
-
-HSQREMOTEDBG sq_rdbg_init(HSQUIRRELVM v,unsigned short port,SQBool autoupdate);
-SQRESULT sq_rdbg_waitforconnections(HSQREMOTEDBG rdbg);
-SQRESULT sq_rdbg_shutdown(HSQREMOTEDBG rdbg);
-SQRESULT sq_rdbg_update(HSQREMOTEDBG rdbg);
-
-#ifdef __cplusplus
-} /*extern "C"*/
-#endif
-
-#endif //_SQ_RDBG_H_
+++ /dev/null
-/* see copyright notice in squirrel.h */
-#include <squirrel.h>
-#include <sqstdaux.h>
-#include <assert.h>
-
-void sqstd_printcallstack(HSQUIRRELVM v)
-{
- SQPRINTFUNCTION pf = sq_getprintfunc(v);
- if(pf) {
- SQStackInfos si;
- SQInteger i;
- SQFloat f;
- const SQChar *s;
- SQInteger level=1; //1 is to skip this function that is level 0
- const SQChar *name=0;
- SQInteger seq=0;
- pf(v,_SC("\nCALLSTACK\n"));
- while(SQ_SUCCEEDED(sq_stackinfos(v,level,&si)))
- {
- const SQChar *fn=_SC("unknown");
- const SQChar *src=_SC("unknown");
- if(si.funcname)fn=si.funcname;
- if(si.source)src=si.source;
- pf(v,_SC("*FUNCTION [%s()] %s line [%d]\n"),fn,src,si.line);
- level++;
- }
- level=0;
- pf(v,_SC("\nLOCALS\n"));
-
- for(level=0;level<10;level++){
- seq=0;
- while((name = sq_getlocal(v,level,seq)))
- {
- seq++;
- switch(sq_gettype(v,-1))
- {
- case OT_NULL:
- pf(v,_SC("[%s] NULL\n"),name);
- break;
- case OT_INTEGER:
- sq_getinteger(v,-1,&i);
- pf(v,_SC("[%s] %d\n"),name,i);
- break;
- case OT_FLOAT:
- sq_getfloat(v,-1,&f);
- pf(v,_SC("[%s] %.14g\n"),name,f);
- break;
- case OT_USERPOINTER:
- pf(v,_SC("[%s] USERPOINTER\n"),name);
- break;
- case OT_STRING:
- sq_getstring(v,-1,&s);
- pf(v,_SC("[%s] \"%s\"\n"),name,s);
- break;
- case OT_TABLE:
- pf(v,_SC("[%s] TABLE\n"),name);
- break;
- case OT_ARRAY:
- pf(v,_SC("[%s] ARRAY\n"),name);
- break;
- case OT_CLOSURE:
- pf(v,_SC("[%s] CLOSURE\n"),name);
- break;
- case OT_NATIVECLOSURE:
- pf(v,_SC("[%s] NATIVECLOSURE\n"),name);
- break;
- case OT_GENERATOR:
- pf(v,_SC("[%s] NATIVECLOSURE\n"),name);
- break;
- case OT_USERDATA:
- pf(v,_SC("[%s] USERDATA\n"),name);
- break;
- case OT_THREAD:
- pf(v,_SC("[%s] THREAD\n"),name);
- break;
- case OT_CLASS:
- pf(v,_SC("[%s] CLASS\n"),name);
- break;
- case OT_INSTANCE:
- pf(v,_SC("[%s] INSTANCE\n"),name);
- break;
- case OT_WEAKREF:
- pf(v,_SC("[%s] WEAKREF\n"),name);
- break;
- case OT_BOOL:{
- sq_getinteger(v,-1,&i);
- pf(v,_SC("[%s] %s\n"),name,i?_SC("true"):_SC("false"));
- }
- break;
- default: assert(0); break;
- }
- sq_pop(v,1);
- }
- }
- }
-}
-
-static SQInteger _sqstd_aux_printerror(HSQUIRRELVM v)
-{
- SQPRINTFUNCTION pf = sq_getprintfunc(v);
- if(pf) {
- const SQChar *sErr = 0;
- if(sq_gettop(v)>=1) {
- if(SQ_SUCCEEDED(sq_getstring(v,2,&sErr))) {
- pf(v,_SC("\nAN ERROR HAS OCCURED [%s]\n"),sErr);
- }
- else{
- pf(v,_SC("\nAN ERROR HAS OCCURED [unknown]\n"));
- }
- sqstd_printcallstack(v);
- }
- }
- return 0;
-}
-
-void _sqstd_compiler_error(HSQUIRRELVM v,const SQChar *sErr,const SQChar *sSource,SQInteger line,SQInteger column)
-{
- SQPRINTFUNCTION pf = sq_getprintfunc(v);
- if(pf) {
- pf(v,_SC("%s line = (%d) column = (%d) : error %s\n"),sSource,line,column,sErr);
- }
-}
-
-void sqstd_seterrorhandlers(HSQUIRRELVM v)
-{
- sq_setcompilererrorhandler(v,_sqstd_compiler_error);
- sq_newclosure(v,_sqstd_aux_printerror,0);
- sq_seterrorhandler(v);
-}
+++ /dev/null
-/* see copyright notice in squirrel.h */
-#include <new>
-#include <squirrel.h>
-#include <sqstdio.h>
-#include <string.h>
-#include <sqstdblob.h>
-#include "sqstdstream.h"
-#include "sqstdblobimpl.h"
-
-#define SQSTD_BLOB_TYPE_TAG (SQSTD_STREAM_TYPE_TAG | 0x00000002)
-
-//Blob
-
-
-#define SETUP_BLOB(v) \
- SQBlob *self = NULL; \
- { if(SQ_FAILED(sq_getinstanceup(v,1,(SQUserPointer*)&self,(SQUserPointer)SQSTD_BLOB_TYPE_TAG))) \
- return SQ_ERROR; }
-
-
-static SQInteger _blob_resize(HSQUIRRELVM v)
-{
- SETUP_BLOB(v);
- SQInteger size;
- sq_getinteger(v,2,&size);
- if(!self->Resize(size))
- return sq_throwerror(v,_SC("resize failed"));
- return 0;
-}
-
-static void __swap_dword(unsigned int *n)
-{
- *n=(unsigned int)(((*n&0xFF000000)>>24) |
- ((*n&0x00FF0000)>>8) |
- ((*n&0x0000FF00)<<8) |
- ((*n&0x000000FF)<<24));
-}
-
-static void __swap_word(unsigned short *n)
-{
- *n=(unsigned short)((*n>>8)&0x00FF)| ((*n<<8)&0xFF00);
-}
-
-static SQInteger _blob_swap4(HSQUIRRELVM v)
-{
- SETUP_BLOB(v);
- SQInteger num=(self->Len()-(self->Len()%4))>>2;
- unsigned int *t=(unsigned int *)self->GetBuf();
- for(SQInteger i = 0; i < num; i++) {
- __swap_dword(&t[i]);
- }
- return 0;
-}
-
-static SQInteger _blob_swap2(HSQUIRRELVM v)
-{
- SETUP_BLOB(v);
- SQInteger num=(self->Len()-(self->Len()%2))>>1;
- unsigned short *t = (unsigned short *)self->GetBuf();
- for(SQInteger i = 0; i < num; i++) {
- __swap_word(&t[i]);
- }
- return 0;
-}
-
-static SQInteger _blob__set(HSQUIRRELVM v)
-{
- SETUP_BLOB(v);
- SQInteger idx,val;
- sq_getinteger(v,2,&idx);
- sq_getinteger(v,3,&val);
- if(idx < 0 || idx >= self->Len())
- return sq_throwerror(v,_SC("index out of range"));
- ((unsigned char *)self->GetBuf())[idx] = (unsigned char) val;
- sq_push(v,3);
- return 1;
-}
-
-static SQInteger _blob__get(HSQUIRRELVM v)
-{
- SETUP_BLOB(v);
- SQInteger idx;
- sq_getinteger(v,2,&idx);
- if(idx < 0 || idx >= self->Len())
- return sq_throwerror(v,_SC("index out of range"));
- sq_pushinteger(v,((unsigned char *)self->GetBuf())[idx]);
- return 1;
-}
-
-static SQInteger _blob__nexti(HSQUIRRELVM v)
-{
- SETUP_BLOB(v);
- if(sq_gettype(v,2) == OT_NULL) {
- sq_pushinteger(v, 0);
- return 1;
- }
- SQInteger idx;
- if(SQ_SUCCEEDED(sq_getinteger(v, 2, &idx))) {
- if(idx+1 < self->Len()) {
- sq_pushinteger(v, idx+1);
- return 1;
- }
- sq_pushnull(v);
- return 1;
- }
- return sq_throwerror(v,_SC("internal error (_nexti) wrong argument type"));
-}
-
-static SQInteger _blob__typeof(HSQUIRRELVM v)
-{
- sq_pushstring(v,_SC("blob"),-1);
- return 1;
-}
-
-static SQInteger _blob_releasehook(SQUserPointer p, SQInteger size)
-{
- SQBlob *self = (SQBlob*)p;
- delete self;
- return 1;
-}
-
-static SQInteger _blob_constructor(HSQUIRRELVM v)
-{
- SQInteger nparam = sq_gettop(v);
- SQInteger size = 0;
- if(nparam == 2) {
- sq_getinteger(v, 2, &size);
- }
- if(size < 0) return sq_throwerror(v, _SC("cannot create blob with negative size"));
- SQBlob *b = new SQBlob(size);
- if(SQ_FAILED(sq_setinstanceup(v,1,b))) {
- delete b;
- return sq_throwerror(v, _SC("cannot create blob with negative size"));
- }
- sq_setreleasehook(v,1,_blob_releasehook);
- return 0;
-}
-
-#define _DECL_BLOB_FUNC(name,nparams,typecheck) {_SC(#name),_blob_##name,nparams,typecheck}
-static SQRegFunction _blob_methods[] = {
- _DECL_BLOB_FUNC(constructor,-1,_SC("xn")),
- _DECL_BLOB_FUNC(resize,2,_SC("xn")),
- _DECL_BLOB_FUNC(swap2,1,_SC("x")),
- _DECL_BLOB_FUNC(swap4,1,_SC("x")),
- _DECL_BLOB_FUNC(_set,3,_SC("xnn")),
- _DECL_BLOB_FUNC(_get,2,_SC("xn")),
- _DECL_BLOB_FUNC(_typeof,1,_SC("x")),
- _DECL_BLOB_FUNC(_nexti,2,_SC("x")),
- {0,0,0,0}
-};
-
-
-
-//GLOBAL FUNCTIONS
-
-static SQInteger _g_blob_casti2f(HSQUIRRELVM v)
-{
- SQInteger i;
- sq_getinteger(v,2,&i);
- sq_pushfloat(v,*((SQFloat *)&i));
- return 1;
-}
-
-static SQInteger _g_blob_castf2i(HSQUIRRELVM v)
-{
- SQFloat f;
- sq_getfloat(v,2,&f);
- sq_pushinteger(v,*((SQInteger *)&f));
- return 1;
-}
-
-static SQInteger _g_blob_swap2(HSQUIRRELVM v)
-{
- SQInteger i;
- sq_getinteger(v,2,&i);
- short s=(short)i;
- sq_pushinteger(v,(s<<8)|((s>>8)&0x00FF));
- return 1;
-}
-
-static SQInteger _g_blob_swap4(HSQUIRRELVM v)
-{
- SQInteger i;
- sq_getinteger(v,2,&i);
- unsigned int t4 = (unsigned int)i;
- __swap_dword(&t4);
- sq_pushinteger(v,(SQInteger)t4);
- return 1;
-}
-
-static SQInteger _g_blob_swapfloat(HSQUIRRELVM v)
-{
- SQFloat f;
- sq_getfloat(v,2,&f);
- __swap_dword((unsigned int *)&f);
- sq_pushfloat(v,f);
- return 1;
-}
-
-#define _DECL_GLOBALBLOB_FUNC(name,nparams,typecheck) {_SC(#name),_g_blob_##name,nparams,typecheck}
-static SQRegFunction bloblib_funcs[]={
- _DECL_GLOBALBLOB_FUNC(casti2f,2,_SC(".n")),
- _DECL_GLOBALBLOB_FUNC(castf2i,2,_SC(".n")),
- _DECL_GLOBALBLOB_FUNC(swap2,2,_SC(".n")),
- _DECL_GLOBALBLOB_FUNC(swap4,2,_SC(".n")),
- _DECL_GLOBALBLOB_FUNC(swapfloat,2,_SC(".n")),
- {0,0}
-};
-
-SQRESULT sqstd_getblob(HSQUIRRELVM v,SQInteger idx,SQUserPointer *ptr)
-{
- SQBlob *blob;
- if(SQ_FAILED(sq_getinstanceup(v,idx,(SQUserPointer *)&blob,(SQUserPointer)SQSTD_BLOB_TYPE_TAG)))
- return -1;
- *ptr = blob->GetBuf();
- return SQ_OK;
-}
-
-SQInteger sqstd_getblobsize(HSQUIRRELVM v,SQInteger idx)
-{
- SQBlob *blob;
- if(SQ_FAILED(sq_getinstanceup(v,idx,(SQUserPointer *)&blob,(SQUserPointer)SQSTD_BLOB_TYPE_TAG)))
- return -1;
- return blob->Len();
-}
-
-SQUserPointer sqstd_createblob(HSQUIRRELVM v, SQInteger size)
-{
- SQInteger top = sq_gettop(v);
- sq_pushregistrytable(v);
- sq_pushstring(v,_SC("std_blob"),-1);
- if(SQ_SUCCEEDED(sq_get(v,-2))) {
- sq_remove(v,-2); //removes the registry
- sq_push(v,1); // push the this
- sq_pushinteger(v,size); //size
- SQBlob *blob = NULL;
- if(SQ_SUCCEEDED(sq_call(v,2,SQTrue,SQFalse))
- && SQ_SUCCEEDED(sq_getinstanceup(v,-1,(SQUserPointer *)&blob,(SQUserPointer)SQSTD_BLOB_TYPE_TAG))) {
- sq_remove(v,-2);
- return blob->GetBuf();
- }
- }
- sq_settop(v,top);
- return NULL;
-}
-
-SQRESULT sqstd_register_bloblib(HSQUIRRELVM v)
-{
- return declare_stream(v,_SC("blob"),(SQUserPointer)SQSTD_BLOB_TYPE_TAG,_SC("std_blob"),_blob_methods,bloblib_funcs);
-}
-
+++ /dev/null
-/* see copyright notice in squirrel.h */
-#ifndef _SQSTD_BLOBIMPL_H_
-#define _SQSTD_BLOBIMPL_H_
-
-struct SQBlob : public SQStream
-{
- SQBlob(SQInteger size) {
- _size = size;
- _allocated = size;
- _buf = (unsigned char *)sq_malloc(size);
- memset(_buf, 0, _size);
- _ptr = 0;
- _owns = true;
- }
- virtual ~SQBlob() {
- sq_free(_buf, _allocated);
- }
- SQInteger Write(void *buffer, SQInteger size) {
- if(!CanAdvance(size)) {
- GrowBufOf(_ptr + size - _size);
- }
- memcpy(&_buf[_ptr], buffer, size);
- _ptr += size;
- return size;
- }
- SQInteger Read(void *buffer,SQInteger size) {
- SQInteger n = size;
- if(!CanAdvance(size)) {
- if((_size - _ptr) > 0)
- n = _size - _ptr;
- else return 0;
- }
- memcpy(buffer, &_buf[_ptr], n);
- _ptr += n;
- return n;
- }
- bool Resize(SQInteger n) {
- if(!_owns) return false;
- if(n != _allocated) {
- unsigned char *newbuf = (unsigned char *)sq_malloc(n);
- memset(newbuf,0,n);
- if(_size > n)
- memcpy(newbuf,_buf,n);
- else
- memcpy(newbuf,_buf,_size);
- sq_free(_buf,_allocated);
- _buf=newbuf;
- _allocated = n;
- if(_size > _allocated)
- _size = _allocated;
- if(_ptr > _allocated)
- _ptr = _allocated;
- }
- return true;
- }
- bool GrowBufOf(SQInteger n)
- {
- bool ret = true;
- if(_size + n > _allocated) {
- if(_size + n > _size * 2)
- ret = Resize(_size + n);
- else
- ret = Resize(_size * 2);
- }
- _size = _size + n;
- return ret;
- }
- bool CanAdvance(SQInteger n) {
- if(_ptr+n>_size)return false;
- return true;
- }
- SQInteger Seek(SQInteger offset, SQInteger origin) {
- switch(origin) {
- case SQ_SEEK_SET:
- if(offset > _size || offset < 0) return -1;
- _ptr = offset;
- break;
- case SQ_SEEK_CUR:
- if(_ptr + offset > _size || _ptr + offset < 0) return -1;
- _ptr += offset;
- break;
- case SQ_SEEK_END:
- if(_size + offset > _size || _size + offset < 0) return -1;
- _ptr = _size + offset;
- break;
- default: return -1;
- }
- return 0;
- }
- bool IsValid() {
- return _buf?true:false;
- }
- bool EOS() {
- return _ptr == _size;
- }
- SQInteger Flush() { return 0; }
- SQInteger Tell() { return _ptr; }
- SQInteger Len() { return _size; }
- SQUserPointer GetBuf(){ return _buf; }
-private:
- SQInteger _size;
- SQInteger _allocated;
- SQInteger _ptr;
- unsigned char *_buf;
- bool _owns;
-};
-
-#endif //_SQSTD_BLOBIMPL_H_
+++ /dev/null
-/* see copyright notice in squirrel.h */
-#include <new>
-#include <stdio.h>
-#include <squirrel.h>
-#include <sqstdio.h>
-#include "sqstdstream.h"
-
-#define SQSTD_FILE_TYPE_TAG (SQSTD_STREAM_TYPE_TAG | 0x00000001)
-//basic API
-SQFILE sqstd_fopen(const SQChar *filename ,const SQChar *mode)
-{
-#ifndef _UNICODE
- return (SQFILE)fopen(filename,mode);
-#else
- return (SQFILE)_wfopen(filename,mode);
-#endif
-}
-
-SQInteger sqstd_fread(void* buffer, SQInteger size, SQInteger count, SQFILE file)
-{
- return (SQInteger)fread(buffer,size,count,(FILE *)file);
-}
-
-SQInteger sqstd_fwrite(const SQUserPointer buffer, SQInteger size, SQInteger count, SQFILE file)
-{
- return (SQInteger)fwrite(buffer,size,count,(FILE *)file);
-}
-
-SQInteger sqstd_fseek(SQFILE file, SQInteger offset, SQInteger origin)
-{
- SQInteger realorigin;
- switch(origin) {
- case SQ_SEEK_CUR: realorigin = SEEK_CUR; break;
- case SQ_SEEK_END: realorigin = SEEK_END; break;
- case SQ_SEEK_SET: realorigin = SEEK_SET; break;
- default: return -1; //failed
- }
- return fseek((FILE *)file,(long)offset,(int)realorigin);
-}
-
-SQInteger sqstd_ftell(SQFILE file)
-{
- return ftell((FILE *)file);
-}
-
-SQInteger sqstd_fflush(SQFILE file)
-{
- return fflush((FILE *)file);
-}
-
-SQInteger sqstd_fclose(SQFILE file)
-{
- return fclose((FILE *)file);
-}
-
-SQInteger sqstd_feof(SQFILE file)
-{
- return feof((FILE *)file);
-}
-
-//File
-struct SQFile : public SQStream {
- SQFile() { _handle = NULL; _owns = false;}
- SQFile(SQFILE file, bool owns) { _handle = file; _owns = owns;}
- virtual ~SQFile() { Close(); }
- bool Open(const SQChar *filename ,const SQChar *mode) {
- Close();
- if( (_handle = sqstd_fopen(filename,mode)) ) {
- _owns = true;
- return true;
- }
- return false;
- }
- void Close() {
- if(_handle && _owns) {
- sqstd_fclose(_handle);
- _handle = NULL;
- _owns = false;
- }
- }
- SQInteger Read(void *buffer,SQInteger size) {
- return sqstd_fread(buffer,1,size,_handle);
- }
- SQInteger Write(void *buffer,SQInteger size) {
- return sqstd_fwrite(buffer,1,size,_handle);
- }
- SQInteger Flush() {
- return sqstd_fflush(_handle);
- }
- SQInteger Tell() {
- return sqstd_ftell(_handle);
- }
- SQInteger Len() {
- SQInteger prevpos=Tell();
- Seek(0,SQ_SEEK_END);
- SQInteger size=Tell();
- Seek(prevpos,SQ_SEEK_SET);
- return size;
- }
- SQInteger Seek(SQInteger offset, SQInteger origin) {
- return sqstd_fseek(_handle,offset,origin);
- }
- bool IsValid() { return _handle?true:false; }
- bool EOS() { return Tell()==Len()?true:false;}
- SQFILE GetHandle() {return _handle;}
-private:
- SQFILE _handle;
- bool _owns;
-};
-
-static SQInteger _file__typeof(HSQUIRRELVM v)
-{
- sq_pushstring(v,_SC("file"),-1);
- return 1;
-}
-
-static SQInteger _file_releasehook(SQUserPointer p, SQInteger size)
-{
- SQFile *self = (SQFile*)p;
- delete self;
- return 1;
-}
-
-static SQInteger _file_constructor(HSQUIRRELVM v)
-{
- const SQChar *filename,*mode;
- bool owns = true;
- SQFile *f;
- SQFILE newf;
- if(sq_gettype(v,2) == OT_STRING && sq_gettype(v,3) == OT_STRING) {
- sq_getstring(v, 2, &filename);
- sq_getstring(v, 3, &mode);
- newf = sqstd_fopen(filename, mode);
- if(!newf) return sq_throwerror(v, _SC("cannot open file"));
- } else if(sq_gettype(v,2) == OT_USERPOINTER) {
- owns = !(sq_gettype(v,3) == OT_NULL);
- sq_getuserpointer(v,2,&newf);
- } else {
- return sq_throwerror(v,_SC("wrong parameter"));
- }
- f = new SQFile(newf,owns);
- if(SQ_FAILED(sq_setinstanceup(v,1,f))) {
- delete f;
- return sq_throwerror(v, _SC("cannot create blob with negative size"));
- }
- sq_setreleasehook(v,1,_file_releasehook);
- return 0;
-}
-
-//bindings
-#define _DECL_FILE_FUNC(name,nparams,typecheck) {_SC(#name),_file_##name,nparams,typecheck}
-static SQRegFunction _file_methods[] = {
- _DECL_FILE_FUNC(constructor,3,_SC("x")),
- _DECL_FILE_FUNC(_typeof,1,_SC("x")),
- {0,0,0,0},
-};
-
-
-
-SQRESULT sqstd_createfile(HSQUIRRELVM v, SQFILE file,SQBool own)
-{
- SQInteger top = sq_gettop(v);
- sq_pushregistrytable(v);
- sq_pushstring(v,_SC("std_file"),-1);
- if(SQ_SUCCEEDED(sq_get(v,-2))) {
- sq_remove(v,-2); //removes the registry
- sq_pushroottable(v); // push the this
- sq_pushuserpointer(v,file); //file
- if(own){
- sq_pushinteger(v,1); //true
- }
- else{
- sq_pushnull(v); //false
- }
- if(SQ_SUCCEEDED( sq_call(v,3,SQTrue,SQFalse) )) {
- sq_remove(v,-2);
- return SQ_OK;
- }
- }
- sq_settop(v,top);
- return SQ_OK;
-}
-
-SQRESULT sqstd_getfile(HSQUIRRELVM v, SQInteger idx, SQFILE *file)
-{
- SQFile *fileobj = NULL;
- if(SQ_SUCCEEDED(sq_getinstanceup(v,idx,(SQUserPointer*)&fileobj,(SQUserPointer)SQSTD_FILE_TYPE_TAG))) {
- *file = fileobj->GetHandle();
- return SQ_OK;
- }
- return sq_throwerror(v,_SC("not a file"));
-}
-
-
-
-static SQInteger _io_file_lexfeed_ASCII(SQUserPointer file)
-{
- SQInteger ret;
- char c;
- if( ( ret=sqstd_fread(&c,sizeof(c),1,(FILE *)file )>0) )
- return c;
- return 0;
-}
-
-static SQInteger _io_file_lexfeed_UTF8(SQUserPointer file)
-{
-#define READ() \
- if(sqstd_fread(&inchar,sizeof(inchar),1,(FILE *)file) != 1) \
- return 0;
-
- static const SQInteger utf8_lengths[16] =
- {
- 1,1,1,1,1,1,1,1, /* 0000 to 0111 : 1 byte (plain ASCII) */
- 0,0,0,0, /* 1000 to 1011 : not valid */
- 2,2, /* 1100, 1101 : 2 bytes */
- 3, /* 1110 : 3 bytes */
- 4 /* 1111 :4 bytes */
- };
- static unsigned char byte_masks[5] = {0,0,0x1f,0x0f,0x07};
- unsigned char inchar;
- SQInteger c = 0;
- READ();
- c = inchar;
- //
- if(c >= 0x80) {
- SQInteger tmp;
- SQInteger codelen = utf8_lengths[c>>4];
- if(codelen == 0)
- return 0;
- //"invalid UTF-8 stream";
- tmp = c&byte_masks[codelen];
- for(SQInteger n = 0; n < codelen-1; n++) {
- tmp<<=6;
- READ();
- tmp |= inchar & 0x3F;
- }
- c = tmp;
- }
- return c;
-}
-
-static SQInteger _io_file_lexfeed_UCS2_LE(SQUserPointer file)
-{
- SQInteger ret;
- wchar_t c;
- if( ( ret=sqstd_fread(&c,sizeof(c),1,(FILE *)file )>0) )
- return (SQChar)c;
- return 0;
-}
-
-static SQInteger _io_file_lexfeed_UCS2_BE(SQUserPointer file)
-{
- SQInteger ret;
- unsigned short c;
- if( ( ret=sqstd_fread(&c,sizeof(c),1,(FILE *)file )>0) ) {
- c = ((c>>8)&0x00FF)| ((c<<8)&0xFF00);
- return (SQChar)c;
- }
- return 0;
-}
-
-SQInteger file_read(SQUserPointer file,SQUserPointer buf,SQInteger size)
-{
- SQInteger ret;
- if( ( ret = sqstd_fread(buf,1,size,(SQFILE)file ))!=0 )return ret;
- return -1;
-}
-
-SQInteger file_write(SQUserPointer file,SQUserPointer p,SQInteger size)
-{
- return sqstd_fwrite(p,1,size,(SQFILE)file);
-}
-
-SQRESULT sqstd_loadfile(HSQUIRRELVM v,const SQChar *filename,SQBool printerror)
-{
- SQFILE file = sqstd_fopen(filename,_SC("rb"));
- SQInteger ret;
- unsigned short us;
- unsigned char uc;
- SQLEXREADFUNC func = _io_file_lexfeed_ASCII;
- if(file){
- ret = sqstd_fread(&us,1,2,file);
- if(ret != 2) {
- //probably an empty file
- us = 0;
- }
- if(us == SQ_BYTECODE_STREAM_TAG) { //BYTECODE
- sqstd_fseek(file,0,SQ_SEEK_SET);
- if(SQ_SUCCEEDED(sq_readclosure(v,file_read,file))) {
- sqstd_fclose(file);
- return SQ_OK;
- }
- }
- else { //SCRIPT
- switch(us)
- {
- //gotta swap the next 2 lines on BIG endian machines
- case 0xFFFE: func = _io_file_lexfeed_UCS2_BE; break;//UTF-16 little endian;
- case 0xFEFF: func = _io_file_lexfeed_UCS2_LE; break;//UTF-16 big endian;
- case 0xBBEF:
- if(sqstd_fread(&uc,1,sizeof(uc),file) == 0) {
- sqstd_fclose(file);
- return sq_throwerror(v,_SC("io error"));
- }
- if(uc != 0xBF) {
- sqstd_fclose(file);
- return sq_throwerror(v,_SC("Unrecognozed ecoding"));
- }
- func = _io_file_lexfeed_UTF8;
- break;//UTF-8 ;
- default: sqstd_fseek(file,0,SQ_SEEK_SET); break; // ascii
- }
-
- if(SQ_SUCCEEDED(sq_compile(v,func,file,filename,printerror))){
- sqstd_fclose(file);
- return SQ_OK;
- }
- }
- sqstd_fclose(file);
- return SQ_ERROR;
- }
- return sq_throwerror(v,_SC("cannot open the file"));
-}
-
-SQRESULT sqstd_dofile(HSQUIRRELVM v,const SQChar *filename,SQBool retval,SQBool printerror)
-{
- if(SQ_SUCCEEDED(sqstd_loadfile(v,filename,printerror))) {
- sq_push(v,-2);
- if(SQ_SUCCEEDED(sq_call(v,1,retval,SQTrue))) {
- sq_remove(v,retval?-2:-1); //removes the closure
- return 1;
- }
- sq_pop(v,1); //removes the closure
- }
- return SQ_ERROR;
-}
-
-SQRESULT sqstd_writeclosuretofile(HSQUIRRELVM v,const SQChar *filename)
-{
- SQFILE file = sqstd_fopen(filename,_SC("wb+"));
- if(!file) return sq_throwerror(v,_SC("cannot open the file"));
- if(SQ_SUCCEEDED(sq_writeclosure(v,file_write,file))) {
- sqstd_fclose(file);
- return SQ_OK;
- }
- sqstd_fclose(file);
- return SQ_ERROR; //forward the error
-}
-
-SQInteger _g_io_loadfile(HSQUIRRELVM v)
-{
- const SQChar *filename;
- SQBool printerror = SQFalse;
- sq_getstring(v,2,&filename);
- if(sq_gettop(v) >= 3) {
- sq_getbool(v,3,&printerror);
- }
- if(SQ_SUCCEEDED(sqstd_loadfile(v,filename,printerror)))
- return 1;
- return SQ_ERROR; //propagates the error
-}
-
-SQInteger _g_io_writeclosuretofile(HSQUIRRELVM v)
-{
- const SQChar *filename;
- sq_getstring(v,2,&filename);
- if(SQ_SUCCEEDED(sqstd_writeclosuretofile(v,filename)))
- return 1;
- return SQ_ERROR; //propagates the error
-}
-
-SQInteger _g_io_dofile(HSQUIRRELVM v)
-{
- const SQChar *filename;
- SQBool printerror = SQFalse;
- sq_getstring(v,2,&filename);
- if(sq_gettop(v) >= 3) {
- sq_getbool(v,3,&printerror);
- }
- sq_push(v,1); //repush the this
- if(SQ_SUCCEEDED(sqstd_dofile(v,filename,SQTrue,printerror)))
- return 1;
- return SQ_ERROR; //propagates the error
-}
-
-#define _DECL_GLOBALIO_FUNC(name,nparams,typecheck) {_SC(#name),_g_io_##name,nparams,typecheck}
-static SQRegFunction iolib_funcs[]={
- _DECL_GLOBALIO_FUNC(loadfile,-2,_SC(".sb")),
- _DECL_GLOBALIO_FUNC(dofile,-2,_SC(".sb")),
- _DECL_GLOBALIO_FUNC(writeclosuretofile,3,_SC(".sc")),
- {0,0}
-};
-
-SQRESULT sqstd_register_iolib(HSQUIRRELVM v)
-{
- SQInteger top = sq_gettop(v);
- //create delegate
- declare_stream(v,_SC("file"),(SQUserPointer)SQSTD_FILE_TYPE_TAG,_SC("std_file"),_file_methods,iolib_funcs);
- sq_pushstring(v,_SC("stdout"),-1);
- sqstd_createfile(v,stdout,SQFalse);
- sq_createslot(v,-3);
- sq_pushstring(v,_SC("stdin"),-1);
- sqstd_createfile(v,stdin,SQFalse);
- sq_createslot(v,-3);
- sq_pushstring(v,_SC("stderr"),-1);
- sqstd_createfile(v,stderr,SQFalse);
- sq_createslot(v,-3);
- sq_settop(v,top);
- return SQ_OK;
-}
+++ /dev/null
-/* see copyright notice in squirrel.h */
-#include <squirrel.h>
-#include <math.h>
-#include <stdlib.h>
-#include <sqstdmath.h>
-
-#define SINGLE_ARG_FUNC(_funcname) static SQInteger math_##_funcname(HSQUIRRELVM v){ \
- SQFloat f; \
- sq_getfloat(v,2,&f); \
- sq_pushfloat(v,(SQFloat)_funcname(f)); \
- return 1; \
-}
-
-#define TWO_ARGS_FUNC(_funcname) static SQInteger math_##_funcname(HSQUIRRELVM v){ \
- SQFloat p1,p2; \
- sq_getfloat(v,2,&p1); \
- sq_getfloat(v,3,&p2); \
- sq_pushfloat(v,(SQFloat)_funcname(p1,p2)); \
- return 1; \
-}
-
-static SQInteger math_srand(HSQUIRRELVM v)
-{
- SQInteger i;
- if(!sq_getinteger(v,2,&i))return sq_throwerror(v,_SC("invalid param"));
- srand((unsigned int)i);
- return 0;
-}
-
-static SQInteger math_rand(HSQUIRRELVM v)
-{
- sq_pushinteger(v,rand());
- return 1;
-}
-
-static SQInteger math_abs(HSQUIRRELVM v)
-{
- SQInteger n;
- sq_getinteger(v,2,&n);
- sq_pushinteger(v,(SQInteger)abs((int)n));
- return 1;
-}
-
-SINGLE_ARG_FUNC(sqrt)
-SINGLE_ARG_FUNC(fabs)
-SINGLE_ARG_FUNC(sin)
-SINGLE_ARG_FUNC(cos)
-SINGLE_ARG_FUNC(asin)
-SINGLE_ARG_FUNC(acos)
-SINGLE_ARG_FUNC(log)
-SINGLE_ARG_FUNC(log10)
-SINGLE_ARG_FUNC(tan)
-SINGLE_ARG_FUNC(atan)
-TWO_ARGS_FUNC(atan2)
-TWO_ARGS_FUNC(pow)
-SINGLE_ARG_FUNC(floor)
-SINGLE_ARG_FUNC(ceil)
-SINGLE_ARG_FUNC(exp)
-
-#define _DECL_FUNC(name,nparams,tycheck) {_SC(#name),math_##name,nparams,tycheck}
-static SQRegFunction mathlib_funcs[] = {
- _DECL_FUNC(sqrt,2,_SC(".n")),
- _DECL_FUNC(sin,2,_SC(".n")),
- _DECL_FUNC(cos,2,_SC(".n")),
- _DECL_FUNC(asin,2,_SC(".n")),
- _DECL_FUNC(acos,2,_SC(".n")),
- _DECL_FUNC(log,2,_SC(".n")),
- _DECL_FUNC(log10,2,_SC(".n")),
- _DECL_FUNC(tan,2,_SC(".n")),
- _DECL_FUNC(atan,2,_SC(".n")),
- _DECL_FUNC(atan2,3,_SC(".nn")),
- _DECL_FUNC(pow,3,_SC(".nn")),
- _DECL_FUNC(floor,2,_SC(".n")),
- _DECL_FUNC(ceil,2,_SC(".n")),
- _DECL_FUNC(exp,2,_SC(".n")),
- _DECL_FUNC(srand,2,_SC(".n")),
- _DECL_FUNC(rand,1,NULL),
- _DECL_FUNC(fabs,2,_SC(".n")),
- _DECL_FUNC(abs,2,_SC(".n")),
- {0,0},
-};
-
-#ifndef M_PI
-#define M_PI (3.14159265358979323846)
-#endif
-
-SQRESULT sqstd_register_mathlib(HSQUIRRELVM v)
-{
- SQInteger i=0;
- while(mathlib_funcs[i].name!=0) {
- sq_pushstring(v,mathlib_funcs[i].name,-1);
- sq_newclosure(v,mathlib_funcs[i].f,0);
- sq_setparamscheck(v,mathlib_funcs[i].nparamscheck,mathlib_funcs[i].typemask);
- sq_setnativeclosurename(v,-1,mathlib_funcs[i].name);
- sq_createslot(v,-3);
- i++;
- }
- sq_pushstring(v,_SC("RAND_MAX"),-1);
- sq_pushinteger(v,RAND_MAX);
- sq_createslot(v,-3);
- sq_pushstring(v,_SC("PI"),-1);
- sq_pushfloat(v,(SQFloat)M_PI);
- sq_createslot(v,-3);
- return SQ_OK;
-}
+++ /dev/null
-/* see copyright notice in squirrel.h */
-#include <squirrel.h>
-#include <string.h>
-#include <ctype.h>
-#include <setjmp.h>
-#include "sqstdstring.h"
-
-#ifdef _UINCODE
-#define scisprint iswprint
-#else
-#define scisprint isprint
-#endif
-
-#ifdef _DEBUG
-#include <stdio.h>
-
-static const SQChar *g_nnames[] =
-{
- _SC("NONE"),_SC("OP_GREEDY"), _SC("OP_OR"),
- _SC("OP_EXPR"),_SC("OP_NOCAPEXPR"),_SC("OP_DOT"), _SC("OP_CLASS"),
- _SC("OP_CCLASS"),_SC("OP_NCLASS"),_SC("OP_RANGE"),_SC("OP_CHAR"),
- _SC("OP_EOL"),_SC("OP_BOL"),_SC("OP_WB")
-};
-
-#endif
-
-#define OP_GREEDY (MAX_CHAR+1) // * + ? {n}
-#define OP_OR (MAX_CHAR+2)
-#define OP_EXPR (MAX_CHAR+3) //parentesis ()
-#define OP_NOCAPEXPR (MAX_CHAR+4) //parentesis (?:)
-#define OP_DOT (MAX_CHAR+5)
-#define OP_CLASS (MAX_CHAR+6)
-#define OP_CCLASS (MAX_CHAR+7)
-#define OP_NCLASS (MAX_CHAR+8) //negates class the [^
-#define OP_RANGE (MAX_CHAR+9)
-#define OP_CHAR (MAX_CHAR+10)
-#define OP_EOL (MAX_CHAR+11)
-#define OP_BOL (MAX_CHAR+12)
-#define OP_WB (MAX_CHAR+13)
-
-#define SQREX_SYMBOL_ANY_CHAR ('.')
-#define SQREX_SYMBOL_GREEDY_ONE_OR_MORE ('+')
-#define SQREX_SYMBOL_GREEDY_ZERO_OR_MORE ('*')
-#define SQREX_SYMBOL_GREEDY_ZERO_OR_ONE ('?')
-#define SQREX_SYMBOL_BRANCH ('|')
-#define SQREX_SYMBOL_END_OF_STRING ('$')
-#define SQREX_SYMBOL_BEGINNING_OF_STRING ('^')
-#define SQREX_SYMBOL_ESCAPE_CHAR ('\\')
-
-
-typedef int SQRexNodeType;
-
-typedef struct tagSQRexNode{
- SQRexNodeType type;
- SQInteger left;
- SQInteger right;
- SQInteger next;
-}SQRexNode;
-
-struct SQRex{
- const SQChar *_eol;
- const SQChar *_bol;
- const SQChar *_p;
- SQInteger _first;
- SQInteger _op;
- SQRexNode *_nodes;
- SQInteger _nallocated;
- SQInteger _nsize;
- SQInteger _nsubexpr;
- SQRexMatch *_matches;
- SQInteger _currsubexp;
- void *_jmpbuf;
- const SQChar **_error;
-};
-
-static SQInteger sqstd_rex_list(SQRex *exp);
-
-static SQInteger sqstd_rex_newnode(SQRex *exp, SQRexNodeType type)
-{
- SQRexNode n;
- n.type = type;
- n.next = n.right = n.left = -1;
- if(type == OP_EXPR)
- n.right = exp->_nsubexpr++;
- if(exp->_nallocated < (exp->_nsize + 1)) {
- SQInteger oldsize = exp->_nallocated;
- exp->_nallocated *= 2;
- exp->_nodes = (SQRexNode *)sq_realloc(exp->_nodes, oldsize * sizeof(SQRexNode) ,exp->_nallocated * sizeof(SQRexNode));
- }
- exp->_nodes[exp->_nsize++] = n;
- SQInteger newid = exp->_nsize - 1;
- return (SQInteger)newid;
-}
-
-static void sqstd_rex_error(SQRex *exp,const SQChar *error)
-{
- if(exp->_error) *exp->_error = error;
- longjmp(*((jmp_buf*)exp->_jmpbuf),-1);
-}
-
-static void sqstd_rex_expect(SQRex *exp, SQInteger n){
- if((*exp->_p) != n)
- sqstd_rex_error(exp, _SC("expected paren"));
- exp->_p++;
-}
-
-static SQChar sqstd_rex_escapechar(SQRex *exp)
-{
- if(*exp->_p == SQREX_SYMBOL_ESCAPE_CHAR){
- exp->_p++;
- switch(*exp->_p) {
- case 'v': exp->_p++; return '\v';
- case 'n': exp->_p++; return '\n';
- case 't': exp->_p++; return '\t';
- case 'r': exp->_p++; return '\r';
- case 'f': exp->_p++; return '\f';
- default: return (*exp->_p++);
- }
- } else if(!scisprint(*exp->_p)) sqstd_rex_error(exp,_SC("letter expected"));
- return (*exp->_p++);
-}
-
-static SQInteger sqstd_rex_charclass(SQRex *exp,SQInteger classid)
-{
- SQInteger n = sqstd_rex_newnode(exp,OP_CCLASS);
- exp->_nodes[n].left = classid;
- return n;
-}
-
-static SQInteger sqstd_rex_charnode(SQRex *exp,SQBool isclass)
-{
- SQChar t;
- if(*exp->_p == SQREX_SYMBOL_ESCAPE_CHAR) {
- exp->_p++;
- switch(*exp->_p) {
- case 'n': exp->_p++; return sqstd_rex_newnode(exp,'\n');
- case 't': exp->_p++; return sqstd_rex_newnode(exp,'\t');
- case 'r': exp->_p++; return sqstd_rex_newnode(exp,'\r');
- case 'f': exp->_p++; return sqstd_rex_newnode(exp,'\f');
- case 'v': exp->_p++; return sqstd_rex_newnode(exp,'\v');
- case 'a': case 'A': case 'w': case 'W': case 's': case 'S':
- case 'd': case 'D': case 'x': case 'X': case 'c': case 'C':
- case 'p': case 'P': case 'l': case 'u':
- {
- t = *exp->_p; exp->_p++;
- return sqstd_rex_charclass(exp,t);
- }
- case 'b':
- case 'B':
- if(!isclass) {
- SQInteger node = sqstd_rex_newnode(exp,OP_WB);
- exp->_nodes[node].left = *exp->_p;
- exp->_p++;
- return node;
- } //else default
- default:
- t = *exp->_p; exp->_p++;
- return sqstd_rex_newnode(exp,t);
- }
- }
- else if(!scisprint(*exp->_p)) {
-
- sqstd_rex_error(exp,_SC("letter expected"));
- }
- t = *exp->_p; exp->_p++;
- return sqstd_rex_newnode(exp,t);
-}
-static SQInteger sqstd_rex_class(SQRex *exp)
-{
- SQInteger ret = -1;
- SQInteger first = -1,chain;
- if(*exp->_p == SQREX_SYMBOL_BEGINNING_OF_STRING){
- ret = sqstd_rex_newnode(exp,OP_NCLASS);
- exp->_p++;
- }else ret = sqstd_rex_newnode(exp,OP_CLASS);
-
- if(*exp->_p == ']') sqstd_rex_error(exp,_SC("empty class"));
- chain = ret;
- while(*exp->_p != ']' && exp->_p != exp->_eol) {
- if(*exp->_p == '-' && first != -1){
- SQInteger r;
- if(*exp->_p++ == ']') sqstd_rex_error(exp,_SC("unfinished range"));
- r = sqstd_rex_newnode(exp,OP_RANGE);
- if(first>*exp->_p) sqstd_rex_error(exp,_SC("invalid range"));
- if(exp->_nodes[first].type == OP_CCLASS) sqstd_rex_error(exp,_SC("cannot use character classes in ranges"));
- exp->_nodes[r].left = exp->_nodes[first].type;
- SQInteger t = sqstd_rex_escapechar(exp);
- exp->_nodes[r].right = t;
- exp->_nodes[chain].next = r;
- chain = r;
- first = -1;
- }
- else{
- if(first!=-1){
- SQInteger c = first;
- exp->_nodes[chain].next = c;
- chain = c;
- first = sqstd_rex_charnode(exp,SQTrue);
- }
- else{
- first = sqstd_rex_charnode(exp,SQTrue);
- }
- }
- }
- if(first!=-1){
- SQInteger c = first;
- exp->_nodes[chain].next = c;
- chain = c;
- first = -1;
- }
- /* hack? */
- exp->_nodes[ret].left = exp->_nodes[ret].next;
- exp->_nodes[ret].next = -1;
- return ret;
-}
-
-static SQInteger sqstd_rex_parsenumber(SQRex *exp)
-{
- SQInteger ret = *exp->_p-'0';
- SQInteger positions = 10;
- exp->_p++;
- while(isdigit(*exp->_p)) {
- ret = ret*10+(*exp->_p++-'0');
- if(positions==1000000000) sqstd_rex_error(exp,_SC("overflow in numeric constant"));
- positions *= 10;
- };
- return ret;
-}
-
-static SQInteger sqstd_rex_element(SQRex *exp)
-{
- SQInteger ret = -1;
- switch(*exp->_p)
- {
- case '(': {
- SQInteger expr;
- exp->_p++;
-
-
- if(*exp->_p =='?') {
- exp->_p++;
- sqstd_rex_expect(exp,':');
- expr = sqstd_rex_newnode(exp,OP_NOCAPEXPR);
- }
- else
- expr = sqstd_rex_newnode(exp,OP_EXPR);
- SQInteger newn = sqstd_rex_list(exp);
- exp->_nodes[expr].left = newn;
- ret = expr;
- sqstd_rex_expect(exp,')');
- }
- break;
- case '[':
- exp->_p++;
- ret = sqstd_rex_class(exp);
- sqstd_rex_expect(exp,']');
- break;
- case SQREX_SYMBOL_END_OF_STRING: exp->_p++; ret = sqstd_rex_newnode(exp,OP_EOL);break;
- case SQREX_SYMBOL_ANY_CHAR: exp->_p++; ret = sqstd_rex_newnode(exp,OP_DOT);break;
- default:
- ret = sqstd_rex_charnode(exp,SQFalse);
- break;
- }
-
-
- SQInteger op;
- SQBool isgreedy = SQFalse;
- unsigned short p0 = 0, p1 = 0;
- switch(*exp->_p){
- case SQREX_SYMBOL_GREEDY_ZERO_OR_MORE: p0 = 0; p1 = 0xFFFF; exp->_p++; isgreedy = SQTrue; break;
- case SQREX_SYMBOL_GREEDY_ONE_OR_MORE: p0 = 1; p1 = 0xFFFF; exp->_p++; isgreedy = SQTrue; break;
- case SQREX_SYMBOL_GREEDY_ZERO_OR_ONE: p0 = 0; p1 = 1; exp->_p++; isgreedy = SQTrue; break;
- case '{':
- exp->_p++;
- if(!isdigit(*exp->_p)) sqstd_rex_error(exp,_SC("number expected"));
- p0 = (unsigned short)sqstd_rex_parsenumber(exp);
- /*******************************/
- switch(*exp->_p) {
- case '}':
- p1 = p0; exp->_p++;
- break;
- case ',':
- exp->_p++;
- p1 = 0xFFFF;
- if(isdigit(*exp->_p)){
- p1 = (unsigned short)sqstd_rex_parsenumber(exp);
- }
- sqstd_rex_expect(exp,'}');
- break;
- default:
- sqstd_rex_error(exp,_SC(", or } expected"));
- }
- /*******************************/
- isgreedy = SQTrue;
- break;
-
- }
- if(isgreedy) {
- SQInteger nnode = sqstd_rex_newnode(exp,OP_GREEDY);
- op = OP_GREEDY;
- exp->_nodes[nnode].left = ret;
- exp->_nodes[nnode].right = ((p0)<<16)|p1;
- ret = nnode;
- }
-
- if((*exp->_p != SQREX_SYMBOL_BRANCH) && (*exp->_p != ')') && (*exp->_p != SQREX_SYMBOL_GREEDY_ZERO_OR_MORE) && (*exp->_p != SQREX_SYMBOL_GREEDY_ONE_OR_MORE) && (*exp->_p != '\0')) {
- SQInteger nnode = sqstd_rex_element(exp);
- exp->_nodes[ret].next = nnode;
- }
-
- return ret;
-}
-
-static SQInteger sqstd_rex_list(SQRex *exp)
-{
- SQInteger ret=-1,e;
- if(*exp->_p == SQREX_SYMBOL_BEGINNING_OF_STRING) {
- exp->_p++;
- ret = sqstd_rex_newnode(exp,OP_BOL);
- }
- e = sqstd_rex_element(exp);
- if(ret != -1) {
- exp->_nodes[ret].next = e;
- }
- else ret = e;
-
- if(*exp->_p == SQREX_SYMBOL_BRANCH) {
- SQInteger temp,tright;
- exp->_p++;
- temp = sqstd_rex_newnode(exp,OP_OR);
- exp->_nodes[temp].left = ret;
- tright = sqstd_rex_list(exp);
- exp->_nodes[temp].right = tright;
- ret = temp;
- }
- return ret;
-}
-
-static SQBool sqstd_rex_matchcclass(SQInteger cclass,SQChar c)
-{
- switch(cclass) {
- case 'a': return isalpha(c)?SQTrue:SQFalse;
- case 'A': return !isalpha(c)?SQTrue:SQFalse;
- case 'w': return (isalnum(c) || c == '_')?SQTrue:SQFalse;
- case 'W': return (!isalnum(c) && c != '_')?SQTrue:SQFalse;
- case 's': return isspace(c)?SQTrue:SQFalse;
- case 'S': return !isspace(c)?SQTrue:SQFalse;
- case 'd': return isdigit(c)?SQTrue:SQFalse;
- case 'D': return !isdigit(c)?SQTrue:SQFalse;
- case 'x': return isxdigit(c)?SQTrue:SQFalse;
- case 'X': return !isxdigit(c)?SQTrue:SQFalse;
- case 'c': return iscntrl(c)?SQTrue:SQFalse;
- case 'C': return !iscntrl(c)?SQTrue:SQFalse;
- case 'p': return ispunct(c)?SQTrue:SQFalse;
- case 'P': return !ispunct(c)?SQTrue:SQFalse;
- case 'l': return islower(c)?SQTrue:SQFalse;
- case 'u': return isupper(c)?SQTrue:SQFalse;
- }
- return SQFalse; /*cannot happen*/
-}
-
-static SQBool sqstd_rex_matchclass(SQRex* exp,SQRexNode *node,SQChar c)
-{
- do {
- switch(node->type) {
- case OP_RANGE:
- if(c >= node->left && c <= node->right) return SQTrue;
- break;
- case OP_CCLASS:
- if(sqstd_rex_matchcclass(node->left,c)) return SQTrue;
- break;
- default:
- if(c == node->type)return SQTrue;
- }
- } while((node->next != -1) && (node = &exp->_nodes[node->next]));
- return SQFalse;
-}
-
-static const SQChar *sqstd_rex_matchnode(SQRex* exp,SQRexNode *node,const SQChar *str,SQRexNode *next)
-{
-
- SQRexNodeType type = node->type;
- switch(type) {
- case OP_GREEDY: {
- //SQRexNode *greedystop = (node->next != -1) ? &exp->_nodes[node->next] : NULL;
- SQRexNode *greedystop = NULL;
- SQInteger p0 = (node->right >> 16)&0x0000FFFF, p1 = node->right&0x0000FFFF, nmaches = 0;
- const SQChar *s=str, *good = str;
-
- if(node->next != -1) {
- greedystop = &exp->_nodes[node->next];
- }
- else {
- greedystop = next;
- }
-
- while((nmaches == 0xFFFF || nmaches < p1)) {
-
- const SQChar *stop;
- if(!(s = sqstd_rex_matchnode(exp,&exp->_nodes[node->left],s,greedystop)))
- break;
- nmaches++;
- good=s;
- if(greedystop) {
- //checks that 0 matches satisfy the expression(if so skips)
- //if not would always stop(for instance if is a '?')
- if(greedystop->type != OP_GREEDY ||
- (greedystop->type == OP_GREEDY && ((greedystop->right >> 16)&0x0000FFFF) != 0))
- {
- SQRexNode *gnext = NULL;
- if(greedystop->next != -1) {
- gnext = &exp->_nodes[greedystop->next];
- }else if(next && next->next != -1){
- gnext = &exp->_nodes[next->next];
- }
- stop = sqstd_rex_matchnode(exp,greedystop,s,gnext);
- if(stop) {
- //if satisfied stop it
- if(p0 == p1 && p0 == nmaches) break;
- else if(nmaches >= p0 && p1 == 0xFFFF) break;
- else if(nmaches >= p0 && nmaches <= p1) break;
- }
- }
- }
-
- if(s >= exp->_eol)
- break;
- }
- if(p0 == p1 && p0 == nmaches) return good;
- else if(nmaches >= p0 && p1 == 0xFFFF) return good;
- else if(nmaches >= p0 && nmaches <= p1) return good;
- return NULL;
- }
- case OP_OR: {
- const SQChar *asd = str;
- SQRexNode *temp=&exp->_nodes[node->left];
- while( (asd = sqstd_rex_matchnode(exp,temp,asd,NULL)) ) {
- if(temp->next != -1)
- temp = &exp->_nodes[temp->next];
- else
- return asd;
- }
- asd = str;
- temp = &exp->_nodes[node->right];
- while( (asd = sqstd_rex_matchnode(exp,temp,asd,NULL)) ) {
- if(temp->next != -1)
- temp = &exp->_nodes[temp->next];
- else
- return asd;
- }
- return NULL;
- break;
- }
- case OP_EXPR:
- case OP_NOCAPEXPR:{
- SQRexNode *n = &exp->_nodes[node->left];
- const SQChar *cur = str;
- SQInteger capture = -1;
- if(node->type != OP_NOCAPEXPR && node->right == exp->_currsubexp) {
- capture = exp->_currsubexp;
- exp->_matches[capture].begin = cur;
- exp->_currsubexp++;
- }
-
- do {
- SQRexNode *subnext = NULL;
- if(n->next != -1) {
- subnext = &exp->_nodes[n->next];
- }else {
- subnext = next;
- }
- if(!(cur = sqstd_rex_matchnode(exp,n,cur,subnext))) {
- if(capture != -1){
- exp->_matches[capture].begin = 0;
- exp->_matches[capture].len = 0;
- }
- return NULL;
- }
- } while((n->next != -1) && (n = &exp->_nodes[n->next]));
-
- if(capture != -1)
- exp->_matches[capture].len = cur - exp->_matches[capture].begin;
- return cur;
- }
- case OP_WB:
- if(str == exp->_bol && !isspace(*str)
- || (str == exp->_eol && !isspace(*(str-1)))
- || (!isspace(*str) && isspace(*(str+1)))
- || (isspace(*str) && !isspace(*(str+1))) ) {
- return (node->left == 'b')?str:NULL;
- }
- return (node->left == 'b')?NULL:str;
- case OP_BOL:
- if(str == exp->_bol) return str;
- return NULL;
- case OP_EOL:
- if(str == exp->_eol) return str;
- return NULL;
- case OP_DOT:{
- *str++;
- }
- return str;
- case OP_NCLASS:
- case OP_CLASS:
- if(sqstd_rex_matchclass(exp,&exp->_nodes[node->left],*str)?(type == OP_CLASS?SQTrue:SQFalse):(type == OP_NCLASS?SQTrue:SQFalse)) {
- *str++;
- return str;
- }
- return NULL;
- case OP_CCLASS:
- if(sqstd_rex_matchcclass(node->left,*str)) {
- *str++;
- return str;
- }
- return NULL;
- default: /* char */
- if(*str != node->type) return NULL;
- *str++;
- return str;
- }
- return NULL;
-}
-
-/* public api */
-SQRex *sqstd_rex_compile(const SQChar *pattern,const SQChar **error)
-{
- SQRex *exp = (SQRex *)sq_malloc(sizeof(SQRex));
- exp->_eol = exp->_bol = NULL;
- exp->_p = pattern;
- exp->_nallocated = (SQInteger)scstrlen(pattern) * sizeof(SQChar);
- exp->_nodes = (SQRexNode *)sq_malloc(exp->_nallocated * sizeof(SQRexNode));
- exp->_nsize = 0;
- exp->_matches = 0;
- exp->_nsubexpr = 0;
- exp->_first = sqstd_rex_newnode(exp,OP_EXPR);
- exp->_error = error;
- exp->_jmpbuf = sq_malloc(sizeof(jmp_buf));
- if(setjmp(*((jmp_buf*)exp->_jmpbuf)) == 0) {
- SQInteger res = sqstd_rex_list(exp);
- exp->_nodes[exp->_first].left = res;
- if(*exp->_p!='\0')
- sqstd_rex_error(exp,_SC("unexpected character"));
-#ifdef _DEBUG
- {
- SQInteger nsize,i;
- SQRexNode *t;
- nsize = exp->_nsize;
- t = &exp->_nodes[0];
- scprintf(_SC("\n"));
- for(i = 0;i < nsize; i++) {
- if(exp->_nodes[i].type>MAX_CHAR)
- scprintf(_SC("[%02d] %10s "),i,g_nnames[exp->_nodes[i].type-MAX_CHAR]);
- else
- scprintf(_SC("[%02d] %10c "),i,exp->_nodes[i].type);
- scprintf(_SC("left %02d right %02d next %02d\n"),exp->_nodes[i].left,exp->_nodes[i].right,exp->_nodes[i].next);
- }
- scprintf(_SC("\n"));
- }
-#endif
- exp->_matches = (SQRexMatch *) sq_malloc(exp->_nsubexpr * sizeof(SQRexMatch));
- memset(exp->_matches,0,exp->_nsubexpr * sizeof(SQRexMatch));
- }
- else{
- sqstd_rex_free(exp);
- return NULL;
- }
- return exp;
-}
-
-void sqstd_rex_free(SQRex *exp)
-{
- if(exp) {
- if(exp->_nodes) sq_free(exp->_nodes,exp->_nallocated * sizeof(SQRexNode));
- if(exp->_jmpbuf) sq_free(exp->_jmpbuf,sizeof(jmp_buf));
- if(exp->_matches) sq_free(exp->_matches,exp->_nsubexpr * sizeof(SQRexMatch));
- sq_free(exp,sizeof(SQRex));
- }
-}
-
-SQBool sqstd_rex_match(SQRex* exp,const SQChar* text)
-{
- const SQChar* res = NULL;
- exp->_bol = text;
- exp->_eol = text + scstrlen(text);
- exp->_currsubexp = 0;
- res = sqstd_rex_matchnode(exp,exp->_nodes,text,NULL);
- if(res == NULL || res != exp->_eol)
- return SQFalse;
- return SQTrue;
-}
-
-SQBool sqstd_rex_searchrange(SQRex* exp,const SQChar* text_begin,const SQChar* text_end,const SQChar** out_begin, const SQChar** out_end)
-{
- const SQChar *cur = NULL;
- SQInteger node = exp->_first;
- if(text_begin >= text_end) return SQFalse;
- exp->_bol = text_begin;
- exp->_eol = text_end;
- do {
- cur = text_begin;
- while(node != -1) {
- exp->_currsubexp = 0;
- cur = sqstd_rex_matchnode(exp,&exp->_nodes[node],cur,NULL);
- if(!cur)
- break;
- node = exp->_nodes[node].next;
- }
- *text_begin++;
- } while(cur == NULL && text_begin != text_end);
-
- if(cur == NULL)
- return SQFalse;
-
- --text_begin;
-
- if(out_begin) *out_begin = text_begin;
- if(out_end) *out_end = cur;
- return SQTrue;
-}
-
-SQBool sqstd_rex_search(SQRex* exp,const SQChar* text, const SQChar** out_begin, const SQChar** out_end)
-{
- return sqstd_rex_searchrange(exp,text,text + scstrlen(text),out_begin,out_end);
-}
-
-SQInteger sqstd_rex_getsubexpcount(SQRex* exp)
-{
- return exp->_nsubexpr;
-}
-
-SQBool sqstd_rex_getsubexp(SQRex* exp, SQInteger n, SQRexMatch *subexp)
-{
- if( n<0 || n >= exp->_nsubexpr) return SQFalse;
- *subexp = exp->_matches[n];
- return SQTrue;
-}
-
+++ /dev/null
-/* see copyright notice in squirrel.h */
-#include <new>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <squirrel.h>
-#include <sqstdio.h>
-#include <sqstdblob.h>
-#include "sqstdstream.h"
-#include "sqstdblobimpl.h"
-
-#define SETUP_STREAM(v) \
- SQStream *self = NULL; \
- if(SQ_FAILED(sq_getinstanceup(v,1,(SQUserPointer*)&self,(SQUserPointer)SQSTD_STREAM_TYPE_TAG))) \
- return sq_throwerror(v,_SC("invalid type tag")); \
- if(!self->IsValid()) \
- return sq_throwerror(v,_SC("the stream is invalid"));
-
-SQInteger _stream_readblob(HSQUIRRELVM v)
-{
- SETUP_STREAM(v);
- SQUserPointer data,blobp;
- SQInteger size,res;
- sq_getinteger(v,2,&size);
- if(size > self->Len()) {
- size = self->Len();
- }
- data = sq_getscratchpad(v,size);
- res = self->Read(data,size);
- if(res <= 0)
- return sq_throwerror(v,_SC("no data left to read"));
- blobp = sqstd_createblob(v,res);
- memcpy(blobp,data,res);
- return 1;
-}
-
-#define SAFE_READN(ptr,len) { \
- if(self->Read(ptr,len) != len) return sq_throwerror(v,_SC("io error")); \
- }
-SQInteger _stream_readn(HSQUIRRELVM v)
-{
- SETUP_STREAM(v);
- SQInteger format;
- sq_getinteger(v, 2, &format);
- switch(format) {
- case 'l': {
- SQInteger i;
- SAFE_READN(&i, sizeof(i));
- sq_pushinteger(v, i);
- }
- break;
- case 'i': {
- SQInt32 i;
- SAFE_READN(&i, sizeof(i));
- sq_pushinteger(v, i);
- }
- break;
- case 's': {
- short s;
- SAFE_READN(&s, sizeof(short));
- sq_pushinteger(v, s);
- }
- break;
- case 'w': {
- unsigned short w;
- SAFE_READN(&w, sizeof(unsigned short));
- sq_pushinteger(v, w);
- }
- break;
- case 'c': {
- char c;
- SAFE_READN(&c, sizeof(char));
- sq_pushinteger(v, c);
- }
- break;
- case 'b': {
- unsigned char c;
- SAFE_READN(&c, sizeof(unsigned char));
- sq_pushinteger(v, c);
- }
- break;
- case 'f': {
- float f;
- SAFE_READN(&f, sizeof(float));
- sq_pushfloat(v, f);
- }
- break;
- case 'd': {
- double d;
- SAFE_READN(&d, sizeof(double));
- sq_pushfloat(v, (SQFloat)d);
- }
- break;
- default:
- return sq_throwerror(v, _SC("invalid format"));
- }
- return 1;
-}
-
-SQInteger _stream_writeblob(HSQUIRRELVM v)
-{
- SQUserPointer data;
- SQInteger size;
- SETUP_STREAM(v);
- if(SQ_FAILED(sqstd_getblob(v,2,&data)))
- return sq_throwerror(v,_SC("invalid parameter"));
- size = sqstd_getblobsize(v,2);
- if(self->Write(data,size) != size)
- return sq_throwerror(v,_SC("io error"));
- sq_pushinteger(v,size);
- return 1;
-}
-
-SQInteger _stream_writen(HSQUIRRELVM v)
-{
- SETUP_STREAM(v);
- SQInteger format, ti;
- SQFloat tf;
- sq_getinteger(v, 3, &format);
- switch(format) {
- case 'l': {
- SQInteger i;
- sq_getinteger(v, 2, &ti);
- i = ti;
- self->Write(&i, sizeof(SQInteger));
- }
- break;
- case 'i': {
- SQInt32 i;
- sq_getinteger(v, 2, &ti);
- i = (SQInt32)ti;
- self->Write(&i, sizeof(SQInt32));
- }
- break;
- case 's': {
- short s;
- sq_getinteger(v, 2, &ti);
- s = (short)ti;
- self->Write(&s, sizeof(short));
- }
- break;
- case 'w': {
- unsigned short w;
- sq_getinteger(v, 2, &ti);
- w = (unsigned short)ti;
- self->Write(&w, sizeof(unsigned short));
- }
- break;
- case 'c': {
- char c;
- sq_getinteger(v, 2, &ti);
- c = (char)ti;
- self->Write(&c, sizeof(char));
- }
- break;
- case 'b': {
- unsigned char b;
- sq_getinteger(v, 2, &ti);
- b = (unsigned char)ti;
- self->Write(&b, sizeof(unsigned char));
- }
- break;
- case 'f': {
- float f;
- sq_getfloat(v, 2, &tf);
- f = (float)tf;
- self->Write(&f, sizeof(float));
- }
- break;
- case 'd': {
- double d;
- sq_getfloat(v, 2, &tf);
- d = tf;
- self->Write(&d, sizeof(double));
- }
- break;
- default:
- return sq_throwerror(v, _SC("invalid format"));
- }
- return 0;
-}
-
-SQInteger _stream_seek(HSQUIRRELVM v)
-{
- SETUP_STREAM(v);
- SQInteger offset, origin = SQ_SEEK_SET;
- sq_getinteger(v, 2, &offset);
- if(sq_gettop(v) > 2) {
- SQInteger t;
- sq_getinteger(v, 3, &t);
- switch(t) {
- case 'b': origin = SQ_SEEK_SET; break;
- case 'c': origin = SQ_SEEK_CUR; break;
- case 'e': origin = SQ_SEEK_END; break;
- default: return sq_throwerror(v,_SC("invalid origin"));
- }
- }
- sq_pushinteger(v, self->Seek(offset, origin));
- return 1;
-}
-
-SQInteger _stream_tell(HSQUIRRELVM v)
-{
- SETUP_STREAM(v);
- sq_pushinteger(v, self->Tell());
- return 1;
-}
-
-SQInteger _stream_len(HSQUIRRELVM v)
-{
- SETUP_STREAM(v);
- sq_pushinteger(v, self->Len());
- return 1;
-}
-
-SQInteger _stream_flush(HSQUIRRELVM v)
-{
- SETUP_STREAM(v);
- if(!self->Flush())
- sq_pushinteger(v, 1);
- else
- sq_pushnull(v);
- return 1;
-}
-
-SQInteger _stream_eos(HSQUIRRELVM v)
-{
- SETUP_STREAM(v);
- if(self->EOS())
- sq_pushinteger(v, 1);
- else
- sq_pushnull(v);
- return 1;
-}
-
-static SQRegFunction _stream_methods[] = {
- _DECL_STREAM_FUNC(readblob,2,_SC("xn")),
- _DECL_STREAM_FUNC(readn,2,_SC("xn")),
- _DECL_STREAM_FUNC(writeblob,-2,_SC("xx")),
- _DECL_STREAM_FUNC(writen,3,_SC("xnn")),
- _DECL_STREAM_FUNC(seek,-2,_SC("xnn")),
- _DECL_STREAM_FUNC(tell,1,_SC("x")),
- _DECL_STREAM_FUNC(len,1,_SC("x")),
- _DECL_STREAM_FUNC(eos,1,_SC("x")),
- _DECL_STREAM_FUNC(flush,1,_SC("x")),
- {0,0}
-};
-
-void init_streamclass(HSQUIRRELVM v)
-{
- sq_pushregistrytable(v);
- sq_pushstring(v,_SC("std_stream"),-1);
- if(SQ_FAILED(sq_get(v,-2))) {
- sq_pushstring(v,_SC("std_stream"),-1);
- sq_newclass(v,SQFalse);
- sq_settypetag(v,-1,(SQUserPointer)SQSTD_STREAM_TYPE_TAG);
- SQInteger i = 0;
- while(_stream_methods[i].name != 0) {
- SQRegFunction &f = _stream_methods[i];
- sq_pushstring(v,f.name,-1);
- sq_newclosure(v,f.f,0);
- sq_setparamscheck(v,f.nparamscheck,f.typemask);
- sq_createslot(v,-3);
- i++;
- }
- sq_createslot(v,-3);
- sq_pushroottable(v);
- sq_pushstring(v,_SC("stream"),-1);
- sq_pushstring(v,_SC("std_stream"),-1);
- sq_get(v,-4);
- sq_createslot(v,-3);
- sq_pop(v,1);
- }
- else {
- sq_pop(v,1); //result
- }
- sq_pop(v,1);
-}
-
-SQRESULT declare_stream(HSQUIRRELVM v,SQChar* name,SQUserPointer typetag,SQChar* reg_name,SQRegFunction *methods,SQRegFunction *globals)
-{
- if(sq_gettype(v,-1) != OT_TABLE)
- return sq_throwerror(v,_SC("table expected"));
- SQInteger top = sq_gettop(v);
- //create delegate
- init_streamclass(v);
- sq_pushregistrytable(v);
- sq_pushstring(v,reg_name,-1);
- sq_pushstring(v,_SC("std_stream"),-1);
- if(SQ_SUCCEEDED(sq_get(v,-3))) {
- sq_newclass(v,SQTrue);
- sq_settypetag(v,-1,typetag);
- SQInteger i = 0;
- while(methods[i].name != 0) {
- SQRegFunction &f = methods[i];
- sq_pushstring(v,f.name,-1);
- sq_newclosure(v,f.f,0);
- sq_setparamscheck(v,f.nparamscheck,f.typemask);
- sq_setnativeclosurename(v,-1,f.name);
- sq_createslot(v,-3);
- i++;
- }
- sq_createslot(v,-3);
- sq_pop(v,1);
-
- i = 0;
- while(globals[i].name!=0)
- {
- SQRegFunction &f = globals[i];
- sq_pushstring(v,f.name,-1);
- sq_newclosure(v,f.f,0);
- sq_setparamscheck(v,f.nparamscheck,f.typemask);
- sq_setnativeclosurename(v,-1,f.name);
- sq_createslot(v,-3);
- i++;
- }
- //register the class in the target table
- sq_pushstring(v,name,-1);
- sq_pushregistrytable(v);
- sq_pushstring(v,reg_name,-1);
- sq_get(v,-2);
- sq_remove(v,-2);
- sq_createslot(v,-3);
-
- sq_settop(v,top);
- return SQ_OK;
- }
- sq_settop(v,top);
- return SQ_ERROR;
-}
+++ /dev/null
-/* see copyright notice in squirrel.h */
-#ifndef _SQSTD_STREAM_H_
-#define _SQSTD_STREAM_H_
-
-SQInteger _stream_readblob(HSQUIRRELVM v);
-SQInteger _stream_readline(HSQUIRRELVM v);
-SQInteger _stream_readn(HSQUIRRELVM v);
-SQInteger _stream_writeblob(HSQUIRRELVM v);
-SQInteger _stream_writen(HSQUIRRELVM v);
-SQInteger _stream_seek(HSQUIRRELVM v);
-SQInteger _stream_tell(HSQUIRRELVM v);
-SQInteger _stream_len(HSQUIRRELVM v);
-SQInteger _stream_eos(HSQUIRRELVM v);
-SQInteger _stream_flush(HSQUIRRELVM v);
-
-#define _DECL_STREAM_FUNC(name,nparams,typecheck) {_SC(#name),_stream_##name,nparams,typecheck}
-SQRESULT declare_stream(HSQUIRRELVM v,SQChar* name,SQUserPointer typetag,SQChar* reg_name,SQRegFunction *methods,SQRegFunction *globals);
-#endif /*_SQSTD_STREAM_H_*/
+++ /dev/null
-/* see copyright notice in squirrel.h */
-#include <squirrel.h>
-#include <sqstdstring.h>
-#include <string.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <ctype.h>
-#include <assert.h>
-
-#ifdef _UNICODE
-#define scstrchr wcschr
-#define scsnprintf wsnprintf
-#define scatoi _wtoi
-#define scstrtok wcstok
-#else
-#define scstrchr strchr
-#define scsnprintf snprintf
-#define scatoi atoi
-#define scstrtok strtok
-#endif
-#define MAX_FORMAT_LEN 20
-#define MAX_WFORMAT_LEN 3
-#define ADDITIONAL_FORMAT_SPACE (100*sizeof(SQChar))
-
-static SQInteger validate_format(HSQUIRRELVM v, SQChar *fmt, const SQChar *src, SQInteger n,SQInteger &width)
-{
- SQChar swidth[MAX_WFORMAT_LEN];
- SQInteger wc = 0;
- SQInteger start = n;
- fmt[0] = '%';
- while (scstrchr(_SC("-+ #0"), src[n])) n++;
- while (scisdigit(src[n])) {
- swidth[wc] = src[n];
- n++;
- wc++;
- if(wc>=MAX_WFORMAT_LEN)
- return sq_throwerror(v,_SC("width format too long"));
- }
- swidth[wc] = '\0';
- if(wc > 0) {
- width = scatoi(swidth);
- }
- else
- width = 0;
- if (src[n] == '.') {
- n++;
-
- wc = 0;
- while (scisdigit(src[n])) {
- swidth[wc] = src[n];
- n++;
- wc++;
- if(wc>=MAX_WFORMAT_LEN)
- return sq_throwerror(v,_SC("precision format too long"));
- }
- swidth[wc] = '\0';
- if(wc > 0) {
- width += scatoi(swidth);
- }
- }
- if (n-start > MAX_FORMAT_LEN )
- return sq_throwerror(v,_SC("format too long"));
- memcpy(&fmt[1],&src[start],((n-start)+1)*sizeof(SQChar));
- fmt[(n-start)+2] = '\0';
- return n;
-}
-
-static SQInteger _string_format(HSQUIRRELVM v)
-{
- const SQChar *format;
- SQChar *dest;
- SQChar fmt[MAX_FORMAT_LEN];
- sq_getstring(v,2,&format);
- SQInteger allocated = (sq_getsize(v,2)+1)*sizeof(SQChar);
- dest = sq_getscratchpad(v,allocated);
- SQInteger n = 0,i = 0, nparam = 3, w = 0;
- while(format[n] != '\0') {
- if(format[n] != '%') {
- assert(i < allocated);
- dest[i++] = format[n];
- n++;
- }
- else if(format[n+1] == '%') { //handles %%
- dest[i++] = '%';
- n += 2;
- }
- else {
- n++;
- if( nparam > sq_gettop(v) )
- return sq_throwerror(v,_SC("not enough paramters for the given format string"));
- n = validate_format(v,fmt,format,n,w);
- if(n < 0) return -1;
- SQInteger addlen = 0;
- SQInteger valtype = 0;
- const SQChar *ts;
- SQInteger ti;
- SQFloat tf;
- switch(format[n]) {
- case 's':
- if(SQ_FAILED(sq_getstring(v,nparam,&ts)))
- return sq_throwerror(v,_SC("string expected for the specified format"));
- addlen = (sq_getsize(v,nparam)*sizeof(SQChar))+((w+1)*sizeof(SQChar));
- valtype = 's';
- break;
- case 'i': case 'd': case 'c':case 'o': case 'u': case 'x': case 'X':
- if(SQ_FAILED(sq_getinteger(v,nparam,&ti)))
- return sq_throwerror(v,_SC("integer expected for the specified format"));
- addlen = (ADDITIONAL_FORMAT_SPACE)+((w+1)*sizeof(SQChar));
- valtype = 'i';
- break;
- case 'f': case 'g': case 'G': case 'e': case 'E':
- if(SQ_FAILED(sq_getfloat(v,nparam,&tf)))
- return sq_throwerror(v,_SC("float expected for the specified format"));
- addlen = (ADDITIONAL_FORMAT_SPACE)+((w+1)*sizeof(SQChar));
- valtype = 'f';
- break;
- default:
- return sq_throwerror(v,_SC("invalid format"));
- }
- n++;
- allocated += addlen;
- dest = sq_getscratchpad(v,allocated);
- switch(valtype) {
- case 's': i += scsprintf(&dest[i],fmt,ts); break;
- case 'i': i += scsprintf(&dest[i],fmt,ti); break;
- case 'f': i += scsprintf(&dest[i],fmt,tf); break;
- };
- nparam ++;
- }
- }
- sq_pushstring(v,dest,i);
- return 1;
-}
-
-static void __strip_l(const SQChar *str,const SQChar **start)
-{
- const SQChar *t = str;
- while(((*t) != '\0') && scisspace(*t)){ t++; }
- *start = t;
-}
-
-static void __strip_r(const SQChar *str,SQInteger len,const SQChar **end)
-{
- if(len == 0) {
- *end = str;
- return;
- }
- const SQChar *t = &str[len-1];
- while(t != str && scisspace(*t)) { t--; }
- *end = t+1;
-}
-
-static SQInteger _string_strip(HSQUIRRELVM v)
-{
- const SQChar *str,*start,*end;
- sq_getstring(v,2,&str);
- SQInteger len = sq_getsize(v,2);
- __strip_l(str,&start);
- __strip_r(str,len,&end);
- sq_pushstring(v,start,end - start);
- return 1;
-}
-
-static SQInteger _string_lstrip(HSQUIRRELVM v)
-{
- const SQChar *str,*start;
- sq_getstring(v,2,&str);
- __strip_l(str,&start);
- sq_pushstring(v,start,-1);
- return 1;
-}
-
-static SQInteger _string_rstrip(HSQUIRRELVM v)
-{
- const SQChar *str,*end;
- sq_getstring(v,2,&str);
- SQInteger len = sq_getsize(v,2);
- __strip_r(str,len,&end);
- sq_pushstring(v,str,end - str);
- return 1;
-}
-
-static SQInteger _string_split(HSQUIRRELVM v)
-{
- const SQChar *str,*seps;
- SQChar *stemp,*tok;
- sq_getstring(v,2,&str);
- sq_getstring(v,3,&seps);
- if(sq_getsize(v,3) == 0) return sq_throwerror(v,_SC("empty separators string"));
- SQInteger memsize = (sq_getsize(v,2)+1)*sizeof(SQChar);
- stemp = sq_getscratchpad(v,memsize);
- memcpy(stemp,str,memsize);
- tok = scstrtok(stemp,seps);
- sq_newarray(v,0);
- while( tok != NULL ) {
- sq_pushstring(v,tok,-1);
- sq_arrayappend(v,-2);
- tok = scstrtok( NULL, seps );
- }
- return 1;
-}
-
-#define SETUP_REX(v) \
- SQRex *self = NULL; \
- sq_getinstanceup(v,1,(SQUserPointer *)&self,0);
-
-static SQInteger _rexobj_releasehook(SQUserPointer p, SQInteger size)
-{
- SQRex *self = ((SQRex *)p);
- sqstd_rex_free(self);
- return 1;
-}
-
-static SQInteger _regexp_match(HSQUIRRELVM v)
-{
- SETUP_REX(v);
- const SQChar *str;
- sq_getstring(v,2,&str);
- if(sqstd_rex_match(self,str) == SQTrue)
- {
- sq_pushbool(v,SQTrue);
- return 1;
- }
- sq_pushbool(v,SQFalse);
- return 1;
-}
-
-static void _addrexmatch(HSQUIRRELVM v,const SQChar *str,const SQChar *begin,const SQChar *end)
-{
- sq_newtable(v);
- sq_pushstring(v,_SC("begin"),-1);
- sq_pushinteger(v,begin - str);
- sq_rawset(v,-3);
- sq_pushstring(v,_SC("end"),-1);
- sq_pushinteger(v,end - str);
- sq_rawset(v,-3);
-}
-
-static SQInteger _regexp_search(HSQUIRRELVM v)
-{
- SETUP_REX(v);
- const SQChar *str,*begin,*end;
- SQInteger start = 0;
- sq_getstring(v,2,&str);
- if(sq_gettop(v) > 2) sq_getinteger(v,3,&start);
- if(sqstd_rex_search(self,str+start,&begin,&end) == SQTrue) {
- _addrexmatch(v,str,begin,end);
- return 1;
- }
- return 0;
-}
-
-static SQInteger _regexp_capture(HSQUIRRELVM v)
-{
- SETUP_REX(v);
- const SQChar *str,*begin,*end;
- SQInteger start = 0;
- sq_getstring(v,2,&str);
- if(sq_gettop(v) > 2) sq_getinteger(v,3,&start);
- if(sqstd_rex_search(self,str+start,&begin,&end) == SQTrue) {
- SQInteger n = sqstd_rex_getsubexpcount(self);
- SQRexMatch match;
- sq_newarray(v,0);
- for(SQInteger i = 0;i < n; i++) {
- sqstd_rex_getsubexp(self,i,&match);
- if(match.len > 0)
- _addrexmatch(v,str,match.begin,match.begin+match.len);
- else
- _addrexmatch(v,str,str,str); //empty match
- sq_arrayappend(v,-2);
- }
- return 1;
- }
- return 0;
-}
-
-static SQInteger _regexp_subexpcount(HSQUIRRELVM v)
-{
- SETUP_REX(v);
- sq_pushinteger(v,sqstd_rex_getsubexpcount(self));
- return 1;
-}
-
-static SQInteger _regexp_constructor(HSQUIRRELVM v)
-{
- const SQChar *error,*pattern;
- sq_getstring(v,2,&pattern);
- SQRex *rex = sqstd_rex_compile(pattern,&error);
- if(!rex) return sq_throwerror(v,error);
- sq_setinstanceup(v,1,rex);
- sq_setreleasehook(v,1,_rexobj_releasehook);
- return 0;
-}
-
-static SQInteger _regexp__typeof(HSQUIRRELVM v)
-{
- sq_pushstring(v,_SC("regexp"),-1);
- return 1;
-}
-
-#define _DECL_REX_FUNC(name,nparams,pmask) {_SC(#name),_regexp_##name,nparams,pmask}
-static SQRegFunction rexobj_funcs[]={
- _DECL_REX_FUNC(constructor,2,_SC(".s")),
- _DECL_REX_FUNC(search,-2,_SC("xsn")),
- _DECL_REX_FUNC(match,2,_SC("xs")),
- _DECL_REX_FUNC(capture,-2,_SC("xsn")),
- _DECL_REX_FUNC(subexpcount,1,_SC("x")),
- _DECL_REX_FUNC(_typeof,1,_SC("x")),
- {0,0}
-};
-
-#define _DECL_FUNC(name,nparams,pmask) {_SC(#name),_string_##name,nparams,pmask}
-static SQRegFunction stringlib_funcs[]={
- _DECL_FUNC(format,-2,_SC(".s")),
- _DECL_FUNC(strip,2,_SC(".s")),
- _DECL_FUNC(lstrip,2,_SC(".s")),
- _DECL_FUNC(rstrip,2,_SC(".s")),
- _DECL_FUNC(split,3,_SC(".ss")),
- {0,0}
-};
-
-
-SQInteger sqstd_register_stringlib(HSQUIRRELVM v)
-{
- sq_pushstring(v,_SC("regexp"),-1);
- sq_newclass(v,SQFalse);
- SQInteger i = 0;
- while(rexobj_funcs[i].name != 0) {
- SQRegFunction &f = rexobj_funcs[i];
- sq_pushstring(v,f.name,-1);
- sq_newclosure(v,f.f,0);
- sq_setparamscheck(v,f.nparamscheck,f.typemask);
- sq_setnativeclosurename(v,-1,f.name);
- sq_createslot(v,-3);
- i++;
- }
- sq_createslot(v,-3);
-
- i = 0;
- while(stringlib_funcs[i].name!=0)
- {
- sq_pushstring(v,stringlib_funcs[i].name,-1);
- sq_newclosure(v,stringlib_funcs[i].f,0);
- sq_setparamscheck(v,stringlib_funcs[i].nparamscheck,stringlib_funcs[i].typemask);
- sq_setnativeclosurename(v,-1,stringlib_funcs[i].name);
- sq_createslot(v,-3);
- i++;
- }
- return 1;
-}
+++ /dev/null
-/* see copyright notice in squirrel.h */
-#include <squirrel.h>
-#include <time.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <sqstdsystem.h>
-
-#ifdef SQUNICODE
-#include <wchar.h>
-#define scgetenv _wgetenv
-#define scsystem _wsystem
-#define scasctime _wasctime
-#define scremove _wremove
-#define screname _wrename
-#else
-#define scgetenv getenv
-#define scsystem system
-#define scasctime asctime
-#define scremove remove
-#define screname rename
-#endif
-
-static SQInteger _system_getenv(HSQUIRRELVM v)
-{
- const SQChar *s;
- if(SQ_SUCCEEDED(sq_getstring(v,2,&s))){
- sq_pushstring(v,scgetenv(s),-1);
- return 1;
- }
- return 0;
-}
-
-
-static SQInteger _system_system(HSQUIRRELVM v)
-{
- const SQChar *s;
- if(SQ_SUCCEEDED(sq_getstring(v,2,&s))){
- sq_pushinteger(v,scsystem(s));
- return 1;
- }
- return sq_throwerror(v,_SC("wrong param"));
-}
-
-
-static SQInteger _system_clock(HSQUIRRELVM v)
-{
- sq_pushfloat(v,((SQFloat)clock())/(SQFloat)CLOCKS_PER_SEC);
- return 1;
-}
-
-static SQInteger _system_time(HSQUIRRELVM v)
-{
- time_t t;
- time(&t);
- sq_pushinteger(v,*((SQInteger *)&t));
- return 1;
-}
-
-static SQInteger _system_remove(HSQUIRRELVM v)
-{
- const SQChar *s;
- sq_getstring(v,2,&s);
- if(scremove(s)==-1)
- return sq_throwerror(v,_SC("remove() failed"));
- return 0;
-}
-
-static SQInteger _system_rename(HSQUIRRELVM v)
-{
- const SQChar *oldn,*newn;
- sq_getstring(v,2,&oldn);
- sq_getstring(v,3,&newn);
- if(screname(oldn,newn)==-1)
- return sq_throwerror(v,_SC("rename() failed"));
- return 0;
-}
-
-static void _set_integer_slot(HSQUIRRELVM v,const SQChar *name,SQInteger val)
-{
- sq_pushstring(v,name,-1);
- sq_pushinteger(v,val);
- sq_rawset(v,-3);
-}
-
-static SQInteger _system_date(HSQUIRRELVM v)
-{
- time_t t;
- SQInteger it;
- SQInteger format = 'l';
- if(sq_gettop(v) > 1) {
- sq_getinteger(v,2,&it);
- t = it;
- if(sq_gettop(v) > 2) {
- sq_getinteger(v,3,(SQInteger*)&format);
- }
- }
- else {
- time(&t);
- }
- tm *date;
- if(format == 'u')
- date = gmtime(&t);
- else
- date = localtime(&t);
- if(!date)
- return sq_throwerror(v,_SC("crt api failure"));
- sq_newtable(v);
- _set_integer_slot(v, _SC("sec"), date->tm_sec);
- _set_integer_slot(v, _SC("min"), date->tm_min);
- _set_integer_slot(v, _SC("hour"), date->tm_hour);
- _set_integer_slot(v, _SC("day"), date->tm_mday);
- _set_integer_slot(v, _SC("month"), date->tm_mon);
- _set_integer_slot(v, _SC("year"), date->tm_year+1900);
- _set_integer_slot(v, _SC("wday"), date->tm_wday);
- _set_integer_slot(v, _SC("yday"), date->tm_yday);
- return 1;
-}
-
-
-
-#define _DECL_FUNC(name,nparams,pmask) {_SC(#name),_system_##name,nparams,pmask}
-static SQRegFunction systemlib_funcs[]={
- _DECL_FUNC(getenv,2,_SC(".s")),
- _DECL_FUNC(system,2,_SC(".s")),
- _DECL_FUNC(clock,1,NULL),
- _DECL_FUNC(time,1,NULL),
- _DECL_FUNC(date,-1,_SC(".nn")),
- _DECL_FUNC(remove,2,_SC(".s")),
- _DECL_FUNC(rename,3,_SC(".ss")),
- {0,0}
-};
-
-
-SQInteger sqstd_register_systemlib(HSQUIRRELVM v)
-{
- SQInteger i=0;
- while(systemlib_funcs[i].name!=0)
- {
- sq_pushstring(v,systemlib_funcs[i].name,-1);
- sq_newclosure(v,systemlib_funcs[i].f,0);
- sq_setparamscheck(v,systemlib_funcs[i].nparamscheck,systemlib_funcs[i].typemask);
- sq_setnativeclosurename(v,-1,systemlib_funcs[i].name);
- sq_createslot(v,-3);
- i++;
- }
- return 1;
-}
+++ /dev/null
-/*
- see copyright notice in squirrel.h
-*/
-#include "sqpcheader.h"
-#include "sqvm.h"
-#include "sqstring.h"
-#include "sqtable.h"
-#include "sqarray.h"
-#include "sqfuncproto.h"
-#include "sqclosure.h"
-#include "squserdata.h"
-#include "sqcompiler.h"
-#include "sqfuncstate.h"
-#include "sqclass.h"
-
-bool sq_aux_gettypedarg(HSQUIRRELVM v,SQInteger idx,SQObjectType type,SQObjectPtr **o)
-{
- *o = &stack_get(v,idx);
- if(type(**o) != type){
- SQObjectPtr oval = v->PrintObjVal(**o);
- v->Raise_Error(_SC("wrong argument type, expected '%s' got '%.50s'"),IdType2Name(type),_stringval(oval));
- return false;
- }
- return true;
-}
-
-#define _GETSAFE_OBJ(v,idx,type,o) { if(!sq_aux_gettypedarg(v,idx,type,&o)) return SQ_ERROR; }
-
-#define sq_aux_paramscheck(v,count) \
-{ \
- if(sq_gettop(v) < count){ v->Raise_Error(_SC("not enough params in the stack")); return SQ_ERROR; }\
-}
-
-SQInteger sq_aux_throwobject(HSQUIRRELVM v,SQObjectPtr &e)
-{
- v->_lasterror = e;
- return SQ_ERROR;
-}
-
-SQInteger sq_aux_invalidtype(HSQUIRRELVM v,SQObjectType type)
-{
- scsprintf(_ss(v)->GetScratchPad(100), _SC("unexpected type %s"), IdType2Name(type));
- return sq_throwerror(v, _ss(v)->GetScratchPad(-1));
-}
-
-HSQUIRRELVM sq_open(SQInteger initialstacksize)
-{
- SQSharedState *ss;
- SQVM *v;
- sq_new(ss, SQSharedState);
- ss->Init();
- v = (SQVM *)SQ_MALLOC(sizeof(SQVM));
- new (v) SQVM(ss);
- ss->_root_vm = v;
- if(v->Init(NULL, initialstacksize)) {
- return v;
- } else {
- sq_delete(v, SQVM);
- return NULL;
- }
- return v;
-}
-
-HSQUIRRELVM sq_newthread(HSQUIRRELVM friendvm, SQInteger initialstacksize)
-{
- SQSharedState *ss;
- SQVM *v;
- ss=_ss(friendvm);
-
- v= (SQVM *)SQ_MALLOC(sizeof(SQVM));
- new (v) SQVM(ss);
-
- if(v->Init(friendvm, initialstacksize)) {
- friendvm->Push(v);
- return v;
- } else {
- sq_delete(v, SQVM);
- return NULL;
- }
-}
-
-SQInteger sq_getvmstate(HSQUIRRELVM v)
-{
- if(v->_suspended)
- return SQ_VMSTATE_SUSPENDED;
- else {
- if(v->_callsstacksize != 0) return SQ_VMSTATE_RUNNING;
- else return SQ_VMSTATE_IDLE;
- }
-}
-
-void sq_seterrorhandler(HSQUIRRELVM v)
-{
- SQObject o = stack_get(v, -1);
- if(sq_isclosure(o) || sq_isnativeclosure(o) || sq_isnull(o)) {
- v->_errorhandler = o;
- v->Pop();
- }
-}
-
-void sq_setdebughook(HSQUIRRELVM v)
-{
- SQObject o = stack_get(v,-1);
- if(sq_isclosure(o) || sq_isnativeclosure(o) || sq_isnull(o)) {
- v->_debughook = o;
- v->Pop();
- }
-}
-
-void sq_close(HSQUIRRELVM v)
-{
- SQSharedState *ss = _ss(v);
- _thread(ss->_root_vm)->Finalize();
- sq_delete(ss, SQSharedState);
-}
-
-SQRESULT sq_compile(HSQUIRRELVM v,SQLEXREADFUNC read,SQUserPointer p,const SQChar *sourcename,SQBool raiseerror)
-{
- SQObjectPtr o;
- if(Compile(v, read, p, sourcename, o, raiseerror?true:false, _ss(v)->_debuginfo)) {
- v->Push(SQClosure::Create(_ss(v), _funcproto(o)));
- return SQ_OK;
- }
- return SQ_ERROR;
-}
-
-void sq_enabledebuginfo(HSQUIRRELVM v, SQBool enable)
-{
- _ss(v)->_debuginfo = enable?true:false;
-}
-
-void sq_notifyallexceptions(HSQUIRRELVM v, SQBool enable)
-{
- _ss(v)->_notifyallexceptions = enable?true:false;
-}
-
-void sq_addref(HSQUIRRELVM v,HSQOBJECT *po)
-{
- if(!ISREFCOUNTED(type(*po))) return;
-#ifdef NO_GARBAGE_COLLECTOR
- __AddRef(po->_type,po->_unVal);
-#else
- _ss(v)->_refs_table.AddRef(*po);
-#endif
-}
-
-SQBool sq_release(HSQUIRRELVM v,HSQOBJECT *po)
-{
- if(!ISREFCOUNTED(type(*po))) return SQTrue;
-#ifdef NO_GARBAGE_COLLECTOR
- __Release(po->_type,po->_unVal);
- return SQFalse; //the ret val doesn't work(and cannot be fixed)
-#else
- return _ss(v)->_refs_table.Release(*po);
-#endif
-}
-
-const SQChar *sq_objtostring(HSQOBJECT *o)
-{
- if(sq_type(*o) == OT_STRING) {
- return _stringval(*o);
- }
- return NULL;
-}
-
-SQInteger sq_objtointeger(HSQOBJECT *o)
-{
- if(sq_isnumeric(*o)) {
- return tointeger(*o);
- }
- return 0;
-}
-
-SQFloat sq_objtofloat(HSQOBJECT *o)
-{
- if(sq_isnumeric(*o)) {
- return tofloat(*o);
- }
- return 0;
-}
-
-SQBool sq_objtobool(HSQOBJECT *o)
-{
- if(sq_isbool(*o)) {
- return _integer(*o);
- }
- return SQFalse;
-}
-
-void sq_pushnull(HSQUIRRELVM v)
-{
- v->Push(_null_);
-}
-
-void sq_pushstring(HSQUIRRELVM v,const SQChar *s,SQInteger len)
-{
- if(s)
- v->Push(SQObjectPtr(SQString::Create(_ss(v), s, len)));
- else v->Push(_null_);
-}
-
-void sq_pushinteger(HSQUIRRELVM v,SQInteger n)
-{
- v->Push(n);
-}
-
-void sq_pushbool(HSQUIRRELVM v,SQBool b)
-{
- v->Push(b?true:false);
-}
-
-void sq_pushfloat(HSQUIRRELVM v,SQFloat n)
-{
- v->Push(n);
-}
-
-void sq_pushuserpointer(HSQUIRRELVM v,SQUserPointer p)
-{
- v->Push(p);
-}
-
-SQUserPointer sq_newuserdata(HSQUIRRELVM v,SQUnsignedInteger size)
-{
- SQUserData *ud = SQUserData::Create(_ss(v), size);
- v->Push(ud);
- return ud->_val;
-}
-
-void sq_newtable(HSQUIRRELVM v)
-{
- v->Push(SQTable::Create(_ss(v), 0));
-}
-
-void sq_newarray(HSQUIRRELVM v,SQInteger size)
-{
- v->Push(SQArray::Create(_ss(v), size));
-}
-
-SQRESULT sq_newclass(HSQUIRRELVM v,SQBool hasbase)
-{
- SQClass *baseclass = NULL;
- if(hasbase) {
- SQObjectPtr &base = stack_get(v,-1);
- if(type(base) != OT_CLASS)
- return sq_throwerror(v,_SC("invalid base type"));
- baseclass = _class(base);
- }
- SQClass *newclass = SQClass::Create(_ss(v), baseclass);
- if(baseclass) v->Pop();
- v->Push(newclass);
- return SQ_OK;
-}
-
-SQBool sq_instanceof(HSQUIRRELVM v)
-{
- SQObjectPtr &inst = stack_get(v,-1);
- SQObjectPtr &cl = stack_get(v,-2);
- if(type(inst) != OT_INSTANCE || type(cl) != OT_CLASS)
- return sq_throwerror(v,_SC("invalid param type"));
- return _instance(inst)->InstanceOf(_class(cl))?SQTrue:SQFalse;
-}
-
-SQRESULT sq_arrayappend(HSQUIRRELVM v,SQInteger idx)
-{
- sq_aux_paramscheck(v,2);
- SQObjectPtr *arr;
- _GETSAFE_OBJ(v, idx, OT_ARRAY,arr);
- _array(*arr)->Append(v->GetUp(-1));
- v->Pop(1);
- return SQ_OK;
-}
-
-SQRESULT sq_arraypop(HSQUIRRELVM v,SQInteger idx,SQBool pushval)
-{
- sq_aux_paramscheck(v, 1);
- SQObjectPtr *arr;
- _GETSAFE_OBJ(v, idx, OT_ARRAY,arr);
- if(_array(*arr)->Size() > 0) {
- if(pushval != 0){ v->Push(_array(*arr)->Top()); }
- _array(*arr)->Pop();
- return SQ_OK;
- }
- return sq_throwerror(v, _SC("empty array"));
-}
-
-SQRESULT sq_arrayresize(HSQUIRRELVM v,SQInteger idx,SQInteger newsize)
-{
- sq_aux_paramscheck(v,1);
- SQObjectPtr *arr;
- _GETSAFE_OBJ(v, idx, OT_ARRAY,arr);
- if(_array(*arr)->Size() > 0) {
- _array(*arr)->Resize(newsize);
- return SQ_OK;
- }
- return SQ_OK;
-}
-
-
-SQRESULT sq_arrayreverse(HSQUIRRELVM v,SQInteger idx)
-{
- sq_aux_paramscheck(v, 1);
- SQObjectPtr *o;
- _GETSAFE_OBJ(v, idx, OT_ARRAY,o);
- SQArray *arr = _array(*o);
- if(arr->Size() > 0) {
- SQObjectPtr t;
- SQInteger size = arr->Size();
- SQInteger n = size >> 1; size -= 1;
- for(SQInteger i = 0; i < n; i++) {
- t = arr->_values[i];
- arr->_values[i] = arr->_values[size-i];
- arr->_values[size-i] = t;
- }
- return SQ_OK;
- }
- return SQ_OK;
-}
-
-void sq_newclosure(HSQUIRRELVM v,SQFUNCTION func,SQUnsignedInteger nfreevars)
-{
- SQNativeClosure *nc = SQNativeClosure::Create(_ss(v), func);
- nc->_nparamscheck = 0;
- for(SQUnsignedInteger i = 0; i < nfreevars; i++) {
- nc->_outervalues.push_back(v->Top());
- v->Pop();
- }
- v->Push(SQObjectPtr(nc));
-}
-
-SQRESULT sq_getclosureinfo(HSQUIRRELVM v,SQInteger idx,SQUnsignedInteger *nparams,SQUnsignedInteger *nfreevars)
-{
- SQObject o = stack_get(v, idx);
- if(sq_isclosure(o)) {
- SQClosure *c = _closure(o);
- SQFunctionProto *proto = _funcproto(c->_function);
- *nparams = (SQUnsignedInteger)proto->_nparameters;
- *nfreevars = (SQUnsignedInteger)c->_outervalues.size();
- return SQ_OK;
- }
- return sq_throwerror(v,_SC("the object is not a closure"));
-}
-
-SQRESULT sq_setnativeclosurename(HSQUIRRELVM v,SQInteger idx,const SQChar *name)
-{
- SQObject o = stack_get(v, idx);
- if(sq_isnativeclosure(o)) {
- SQNativeClosure *nc = _nativeclosure(o);
- nc->_name = SQString::Create(_ss(v),name);
- return SQ_OK;
- }
- return sq_throwerror(v,_SC("the object is not a nativeclosure"));
-}
-
-SQRESULT sq_setparamscheck(HSQUIRRELVM v,SQInteger nparamscheck,const SQChar *typemask)
-{
- SQObject o = stack_get(v, -1);
- if(!sq_isnativeclosure(o))
- return sq_throwerror(v, _SC("native closure expected"));
- SQNativeClosure *nc = _nativeclosure(o);
- nc->_nparamscheck = nparamscheck;
- if(typemask) {
- SQIntVec res;
- if(!CompileTypemask(res, typemask))
- return sq_throwerror(v, _SC("invalid typemask"));
- nc->_typecheck.copy(res);
- }
- else {
- nc->_typecheck.resize(0);
- }
- if(nparamscheck == SQ_MATCHTYPEMASKSTRING) {
- nc->_nparamscheck = nc->_typecheck.size();
- }
- return SQ_OK;
-}
-
-SQRESULT sq_bindenv(HSQUIRRELVM v,SQInteger idx)
-{
- SQObjectPtr &o = stack_get(v,idx);
- if(!sq_isnativeclosure(o) &&
- !sq_isclosure(o))
- return sq_throwerror(v,_SC("the target is not a closure"));
- SQObjectPtr &env = stack_get(v,-1);
- if(!sq_istable(env) &&
- !sq_isclass(env) &&
- !sq_isinstance(env))
- return sq_throwerror(v,_SC("invalid environment"));
- SQObjectPtr w = _refcounted(env)->GetWeakRef(type(env));
- SQObjectPtr ret;
- if(sq_isclosure(o)) {
- SQClosure *c = _closure(o)->Clone();
- c->_env = w;
- ret = c;
- }
- else { //then must be a native closure
- SQNativeClosure *c = _nativeclosure(o)->Clone();
- c->_env = w;
- ret = c;
- }
- v->Pop();
- v->Push(ret);
- return SQ_OK;
-}
-
-SQRESULT sq_clear(HSQUIRRELVM v,SQInteger idx)
-{
- SQObject &o=stack_get(v,idx);
- switch(type(o)) {
- case OT_TABLE: _table(o)->Clear(); break;
- case OT_ARRAY: _array(o)->Resize(0); break;
- default:
- return sq_throwerror(v, _SC("clear only works on table and array"));
- break;
-
- }
- return SQ_OK;
-}
-
-void sq_pushroottable(HSQUIRRELVM v)
-{
- v->Push(v->_roottable);
-}
-
-void sq_pushregistrytable(HSQUIRRELVM v)
-{
- v->Push(_ss(v)->_registry);
-}
-
-SQRESULT sq_setroottable(HSQUIRRELVM v)
-{
- SQObject o = stack_get(v, -1);
- if(sq_istable(o) || sq_isnull(o)) {
- v->_roottable = o;
- v->Pop();
- return SQ_OK;
- }
- return sq_throwerror(v, _SC("ivalid type"));
-}
-
-void sq_setforeignptr(HSQUIRRELVM v,SQUserPointer p)
-{
- v->_foreignptr = p;
-}
-
-SQUserPointer sq_getforeignptr(HSQUIRRELVM v)
-{
- return v->_foreignptr;
-}
-
-void sq_push(HSQUIRRELVM v,SQInteger idx)
-{
- v->Push(stack_get(v, idx));
-}
-
-SQObjectType sq_gettype(HSQUIRRELVM v,SQInteger idx)
-{
- return type(stack_get(v, idx));
-}
-
-
-void sq_tostring(HSQUIRRELVM v,SQInteger idx)
-{
- SQObjectPtr &o = stack_get(v, idx);
- SQObjectPtr res;
- v->ToString(o,res);
- v->Push(res);
-}
-
-void sq_tobool(HSQUIRRELVM v, SQInteger idx, SQBool *b)
-{
- SQObjectPtr &o = stack_get(v, idx);
- *b = v->IsFalse(o)?SQFalse:SQTrue;
-}
-
-SQRESULT sq_getinteger(HSQUIRRELVM v,SQInteger idx,SQInteger *i)
-{
- SQObjectPtr &o = stack_get(v, idx);
- if(sq_isnumeric(o)) {
- *i = tointeger(o);
- return SQ_OK;
- }
- return SQ_ERROR;
-}
-
-SQRESULT sq_getfloat(HSQUIRRELVM v,SQInteger idx,SQFloat *f)
-{
- SQObjectPtr &o = stack_get(v, idx);
- if(sq_isnumeric(o)) {
- *f = tofloat(o);
- return SQ_OK;
- }
- return SQ_ERROR;
-}
-
-SQRESULT sq_getbool(HSQUIRRELVM v,SQInteger idx,SQBool *b)
-{
- SQObjectPtr &o = stack_get(v, idx);
- if(sq_isbool(o)) {
- *b = _integer(o);
- return SQ_OK;
- }
- return SQ_ERROR;
-}
-
-SQRESULT sq_getstring(HSQUIRRELVM v,SQInteger idx,const SQChar **c)
-{
- SQObjectPtr *o = NULL;
- _GETSAFE_OBJ(v, idx, OT_STRING,o);
- *c = _stringval(*o);
- return SQ_OK;
-}
-
-SQRESULT sq_getthread(HSQUIRRELVM v,SQInteger idx,HSQUIRRELVM *thread)
-{
- SQObjectPtr *o = NULL;
- _GETSAFE_OBJ(v, idx, OT_THREAD,o);
- *thread = _thread(*o);
- return SQ_OK;
-}
-
-SQRESULT sq_clone(HSQUIRRELVM v,SQInteger idx)
-{
- SQObjectPtr &o = stack_get(v,idx);
- v->Push(_null_);
- if(!v->Clone(o, stack_get(v, -1))){
- v->Pop();
- return sq_aux_invalidtype(v, type(o));
- }
- return SQ_OK;
-}
-
-SQInteger sq_getsize(HSQUIRRELVM v, SQInteger idx)
-{
- SQObjectPtr &o = stack_get(v, idx);
- SQObjectType type = type(o);
- switch(type) {
- case OT_STRING: return _string(o)->_len;
- case OT_TABLE: return _table(o)->CountUsed();
- case OT_ARRAY: return _array(o)->Size();
- case OT_USERDATA: return _userdata(o)->_size;
- default:
- return sq_aux_invalidtype(v, type);
- }
-}
-
-SQRESULT sq_getuserdata(HSQUIRRELVM v,SQInteger idx,SQUserPointer *p,SQUserPointer *typetag)
-{
- SQObjectPtr *o = NULL;
- _GETSAFE_OBJ(v, idx, OT_USERDATA,o);
- (*p) = _userdataval(*o);
- if(typetag) *typetag = _userdata(*o)->_typetag;
- return SQ_OK;
-}
-
-SQRESULT sq_settypetag(HSQUIRRELVM v,SQInteger idx,SQUserPointer typetag)
-{
- SQObjectPtr &o = stack_get(v,idx);
- switch(type(o)) {
- case OT_USERDATA: _userdata(o)->_typetag = typetag; break;
- case OT_CLASS: _class(o)->_typetag = typetag; break;
- default: return sq_throwerror(v,_SC("invalid object type"));
- }
- return SQ_OK;
-}
-
-SQRESULT sq_getobjtypetag(HSQOBJECT *o,SQUserPointer * typetag)
-{
- switch(type(*o)) {
- case OT_INSTANCE: *typetag = _instance(*o)->_class->_typetag; break;
- case OT_USERDATA: *typetag = _userdata(*o)->_typetag; break;
- case OT_CLASS: *typetag = _class(*o)->_typetag; break;
- default: return SQ_ERROR;
- }
- return SQ_OK;
-}
-
-SQRESULT sq_gettypetag(HSQUIRRELVM v,SQInteger idx,SQUserPointer *typetag)
-{
- SQObjectPtr &o = stack_get(v,idx);
- if(SQ_FAILED(sq_getobjtypetag(&o,typetag)))
- return sq_throwerror(v,_SC("invalid object type"));
- return SQ_OK;
-}
-
-SQRESULT sq_getuserpointer(HSQUIRRELVM v, SQInteger idx, SQUserPointer *p)
-{
- SQObjectPtr *o = NULL;
- _GETSAFE_OBJ(v, idx, OT_USERPOINTER,o);
- (*p) = _userpointer(*o);
- return SQ_OK;
-}
-
-SQRESULT sq_setinstanceup(HSQUIRRELVM v, SQInteger idx, SQUserPointer p)
-{
- SQObjectPtr &o = stack_get(v,idx);
- if(type(o) != OT_INSTANCE) return sq_throwerror(v,_SC("the object is not a class instance"));
- _instance(o)->_userpointer = p;
- return SQ_OK;
-}
-
-SQRESULT sq_setclassudsize(HSQUIRRELVM v, SQInteger idx, SQInteger udsize)
-{
- SQObjectPtr &o = stack_get(v,idx);
- if(type(o) != OT_CLASS) return sq_throwerror(v,_SC("the object is not a class"));
- if(_class(o)->_locked) return sq_throwerror(v,_SC("the class is locked"));
- _class(o)->_udsize = udsize;
- return SQ_OK;
-}
-
-
-SQRESULT sq_getinstanceup(HSQUIRRELVM v, SQInteger idx, SQUserPointer *p,SQUserPointer typetag)
-{
- SQObjectPtr &o = stack_get(v,idx);
- if(type(o) != OT_INSTANCE) return sq_throwerror(v,_SC("the object is not a class instance"));
- (*p) = _instance(o)->_userpointer;
- if(typetag != 0) {
- SQClass *cl = _instance(o)->_class;
- do{
- if(cl->_typetag == typetag)
- return SQ_OK;
- cl = cl->_base;
- }while(cl != NULL);
- return sq_throwerror(v,_SC("invalid type tag"));
- }
- return SQ_OK;
-}
-
-SQInteger sq_gettop(HSQUIRRELVM v)
-{
- return (v->_top) - v->_stackbase;
-}
-
-void sq_settop(HSQUIRRELVM v, SQInteger newtop)
-{
- SQInteger top = sq_gettop(v);
- if(top > newtop)
- sq_pop(v, top - newtop);
- else
- while(top < newtop) sq_pushnull(v);
-}
-
-void sq_pop(HSQUIRRELVM v, SQInteger nelemstopop)
-{
- assert(v->_top >= nelemstopop);
- v->Pop(nelemstopop);
-}
-
-void sq_poptop(HSQUIRRELVM v)
-{
- assert(v->_top >= 1);
- v->Pop();
-}
-
-
-void sq_remove(HSQUIRRELVM v, SQInteger idx)
-{
- v->Remove(idx);
-}
-
-SQInteger sq_cmp(HSQUIRRELVM v)
-{
- SQInteger res;
- v->ObjCmp(stack_get(v, -1), stack_get(v, -2),res);
- return res;
-}
-
-SQRESULT sq_newslot(HSQUIRRELVM v, SQInteger idx, SQBool bstatic)
-{
- sq_aux_paramscheck(v, 3);
- SQObjectPtr &self = stack_get(v, idx);
- if(type(self) == OT_TABLE || type(self) == OT_CLASS) {
- SQObjectPtr &key = v->GetUp(-2);
- if(type(key) == OT_NULL) return sq_throwerror(v, _SC("null is not a valid key"));
- v->NewSlot(self, key, v->GetUp(-1),bstatic?true:false);
- v->Pop(2);
- }
- return SQ_OK;
-}
-
-SQRESULT sq_deleteslot(HSQUIRRELVM v,SQInteger idx,SQBool pushval)
-{
- sq_aux_paramscheck(v, 2);
- SQObjectPtr *self;
- _GETSAFE_OBJ(v, idx, OT_TABLE,self);
- SQObjectPtr &key = v->GetUp(-1);
- if(type(key) == OT_NULL) return sq_throwerror(v, _SC("null is not a valid key"));
- SQObjectPtr res;
- if(!v->DeleteSlot(*self, key, res)){
- return SQ_ERROR;
- }
- if(pushval) v->GetUp(-1) = res;
- else v->Pop(1);
- return SQ_OK;
-}
-
-SQRESULT sq_set(HSQUIRRELVM v,SQInteger idx)
-{
- SQObjectPtr &self = stack_get(v, idx);
- if(v->Set(self, v->GetUp(-2), v->GetUp(-1),false)) {
- v->Pop(2);
- return SQ_OK;
- }
- v->Raise_IdxError(v->GetUp(-2));return SQ_ERROR;
-}
-
-SQRESULT sq_rawset(HSQUIRRELVM v,SQInteger idx)
-{
- SQObjectPtr &self = stack_get(v, idx);
- if(type(v->GetUp(-2)) == OT_NULL) return sq_throwerror(v, _SC("null key"));
- switch(type(self)) {
- case OT_TABLE:
- _table(self)->NewSlot(v->GetUp(-2), v->GetUp(-1));
- v->Pop(2);
- return SQ_OK;
- break;
- case OT_CLASS:
- _class(self)->NewSlot(_ss(v), v->GetUp(-2), v->GetUp(-1),false);
- v->Pop(2);
- return SQ_OK;
- break;
- case OT_INSTANCE:
- if(_instance(self)->Set(v->GetUp(-2), v->GetUp(-1))) {
- v->Pop(2);
- return SQ_OK;
- }
- break;
- case OT_ARRAY:
- if(v->Set(self, v->GetUp(-2), v->GetUp(-1),false)) {
- v->Pop(2);
- return SQ_OK;
- }
- break;
- default:
- v->Pop(2);
- return sq_throwerror(v, _SC("rawset works only on array/table/class and instance"));
- }
- v->Raise_IdxError(v->GetUp(-2));return SQ_ERROR;
-}
-
-SQRESULT sq_setdelegate(HSQUIRRELVM v,SQInteger idx)
-{
- SQObjectPtr &self = stack_get(v, idx);
- SQObjectPtr &mt = v->GetUp(-1);
- SQObjectType type = type(self);
- switch(type) {
- case OT_TABLE:
- if(type(mt) == OT_TABLE) {
- if(!_table(self)->SetDelegate(_table(mt))) return sq_throwerror(v, _SC("delagate cycle")); v->Pop();}
- else if(type(mt)==OT_NULL) {
- _table(self)->SetDelegate(NULL); v->Pop(); }
- else return sq_aux_invalidtype(v,type);
- break;
- case OT_USERDATA:
- if(type(mt)==OT_TABLE) {
- _userdata(self)->SetDelegate(_table(mt)); v->Pop(); }
- else if(type(mt)==OT_NULL) {
- _userdata(self)->SetDelegate(NULL); v->Pop(); }
- else return sq_aux_invalidtype(v, type);
- break;
- default:
- return sq_aux_invalidtype(v, type);
- break;
- }
- return SQ_OK;
-}
-
-SQRESULT sq_rawdeleteslot(HSQUIRRELVM v,SQInteger idx,SQBool pushval)
-{
- sq_aux_paramscheck(v, 2);
- SQObjectPtr *self;
- _GETSAFE_OBJ(v, idx, OT_TABLE,self);
- SQObjectPtr &key = v->GetUp(-1);
- SQObjectPtr t;
- if(_table(*self)->Get(key,t)) {
- _table(*self)->Remove(key);
- }
- if(pushval != 0)
- if(pushval) v->GetUp(-1) = t;
- else
- v->Pop(1);
- return SQ_OK;
-}
-
-SQRESULT sq_getdelegate(HSQUIRRELVM v,SQInteger idx)
-{
- SQObjectPtr &self=stack_get(v,idx);
- switch(type(self)){
- case OT_TABLE:
- case OT_USERDATA:
- if(!_delegable(self)->_delegate){
- v->Push(_null_);
- break;
- }
- v->Push(SQObjectPtr(_delegable(self)->_delegate));
- break;
- default: return sq_throwerror(v,_SC("wrong type")); break;
- }
- return SQ_OK;
-
-}
-
-SQRESULT sq_get(HSQUIRRELVM v,SQInteger idx)
-{
- SQObjectPtr &self=stack_get(v,idx);
- if(v->Get(self,v->GetUp(-1),v->GetUp(-1),false,false))
- return SQ_OK;
- v->Pop(1);
- return sq_throwerror(v,_SC("the index doesn't exist"));
-}
-
-SQRESULT sq_rawget(HSQUIRRELVM v,SQInteger idx)
-{
- SQObjectPtr &self=stack_get(v,idx);
- switch(type(self)) {
- case OT_TABLE:
- if(_table(self)->Get(v->GetUp(-1),v->GetUp(-1)))
- return SQ_OK;
- break;
- case OT_CLASS:
- if(_class(self)->Get(v->GetUp(-1),v->GetUp(-1)))
- return SQ_OK;
- break;
- case OT_INSTANCE:
- if(_instance(self)->Get(v->GetUp(-1),v->GetUp(-1)))
- return SQ_OK;
- break;
- case OT_ARRAY:
- if(v->Get(self,v->GetUp(-1),v->GetUp(-1),false,false))
- return SQ_OK;
- break;
- default:
- v->Pop(1);
- return sq_throwerror(v,_SC("rawget works only on array/table/instance and class"));
- }
- v->Pop(1);
- return sq_throwerror(v,_SC("the index doesn't exist"));
-}
-
-SQRESULT sq_getstackobj(HSQUIRRELVM v,SQInteger idx,HSQOBJECT *po)
-{
- *po=stack_get(v,idx);
- return SQ_OK;
-}
-
-const SQChar *sq_getlocal(HSQUIRRELVM v,SQUnsignedInteger level,SQUnsignedInteger idx)
-{
- SQUnsignedInteger cstksize=v->_callsstacksize;
- SQUnsignedInteger lvl=(cstksize-level)-1;
- SQInteger stackbase=v->_stackbase;
- if(lvl<cstksize){
- for(SQUnsignedInteger i=0;i<level;i++){
- SQVM::CallInfo &ci=v->_callsstack[(cstksize-i)-1];
- stackbase-=ci._prevstkbase;
- }
- SQVM::CallInfo &ci=v->_callsstack[lvl];
- if(type(ci._closure)!=OT_CLOSURE)
- return NULL;
- SQClosure *c=_closure(ci._closure);
- SQFunctionProto *func=_funcproto(c->_function);
- if(func->_noutervalues > (SQInteger)idx) {
- v->Push(c->_outervalues[idx]);
- return _stringval(func->_outervalues[idx]._name);
- }
- idx -= func->_noutervalues;
- return func->GetLocal(v,stackbase,idx,(SQInteger)(ci._ip-func->_instructions)-1);
- }
- return NULL;
-}
-
-void sq_pushobject(HSQUIRRELVM v,HSQOBJECT obj)
-{
- v->Push(SQObjectPtr(obj));
-}
-
-void sq_resetobject(HSQOBJECT *po)
-{
- po->_unVal.pUserPointer=NULL;po->_type=OT_NULL;
-}
-
-SQRESULT sq_throwerror(HSQUIRRELVM v,const SQChar *err)
-{
- v->_lasterror=SQString::Create(_ss(v),err);
- return -1;
-}
-
-void sq_reseterror(HSQUIRRELVM v)
-{
- v->_lasterror = _null_;
-}
-
-void sq_getlasterror(HSQUIRRELVM v)
-{
- v->Push(v->_lasterror);
-}
-
-void sq_reservestack(HSQUIRRELVM v,SQInteger nsize)
-{
- if (((SQUnsignedInteger)v->_top + nsize) > v->_stack.size()) {
- v->_stack.resize(v->_stack.size() + ((v->_top + nsize) - v->_stack.size()));
- }
-}
-
-SQRESULT sq_resume(HSQUIRRELVM v,SQBool retval,SQBool raiseerror)
-{
- if(type(v->GetUp(-1))==OT_GENERATOR){
- v->Push(_null_); //retval
- if(!v->Execute(v->GetUp(-2),v->_top,0,v->_top,v->GetUp(-1),raiseerror,SQVM::ET_RESUME_GENERATOR))
- {v->Raise_Error(v->_lasterror); return SQ_ERROR;}
- if(!retval)
- v->Pop();
- return SQ_OK;
- }
- return sq_throwerror(v,_SC("only generators can be resumed"));
-}
-
-SQRESULT sq_call(HSQUIRRELVM v,SQInteger params,SQBool retval,SQBool raiseerror)
-{
- SQObjectPtr res;
- if(v->Call(v->GetUp(-(params+1)),params,v->_top-params,res,raiseerror?true:false)){
- v->Pop(params);//pop closure and args
- if(retval){
- v->Push(res); return SQ_OK;
- }
- return SQ_OK;
- }
- else {
- v->Pop(params);
- return SQ_ERROR;
- }
- if(!v->_suspended)
- v->Pop(params);
- return sq_throwerror(v,_SC("call failed"));
-}
-
-SQRESULT sq_suspendvm(HSQUIRRELVM v)
-{
- return v->Suspend();
-}
-
-SQRESULT sq_wakeupvm(HSQUIRRELVM v,SQBool wakeupret,SQBool retval,SQBool raiseerror)
-{
- SQObjectPtr ret;
- if(!v->_suspended)
- return sq_throwerror(v,_SC("cannot resume a vm that is not running any code"));
- if(wakeupret) {
- v->GetAt(v->_stackbase+v->_suspended_target)=v->GetUp(-1); //retval
- v->Pop();
- } else v->GetAt(v->_stackbase+v->_suspended_target)=_null_;
- if(!v->Execute(_null_,v->_top,-1,-1,ret,raiseerror,SQVM::ET_RESUME_VM))
- return SQ_ERROR;
- if(sq_getvmstate(v) == SQ_VMSTATE_IDLE) {
- while (v->_top > 1) v->_stack[--v->_top] = _null_;
- }
- if(retval)
- v->Push(ret);
- return SQ_OK;
-}
-
-void sq_setreleasehook(HSQUIRRELVM v,SQInteger idx,SQRELEASEHOOK hook)
-{
- if(sq_gettop(v) >= 1){
- SQObjectPtr &ud=stack_get(v,idx);
- switch( type(ud) ) {
- case OT_USERDATA: _userdata(ud)->_hook = hook; break;
- case OT_INSTANCE: _instance(ud)->_hook = hook; break;
- case OT_CLASS: _class(ud)->_hook = hook; break;
- default: break; //shutup compiler
- }
- }
-}
-
-void sq_setcompilererrorhandler(HSQUIRRELVM v,SQCOMPILERERROR f)
-{
- _ss(v)->_compilererrorhandler = f;
-}
-
-SQRESULT sq_writeclosure(HSQUIRRELVM v,SQWRITEFUNC w,SQUserPointer up)
-{
- SQObjectPtr *o = NULL;
- _GETSAFE_OBJ(v, -1, OT_CLOSURE,o);
- unsigned short tag = SQ_BYTECODE_STREAM_TAG;
- if(w(up,&tag,2) != 2)
- return sq_throwerror(v,_SC("io error"));
- if(!_closure(*o)->Save(v,up,w))
- return SQ_ERROR;
- return SQ_OK;
-}
-
-SQRESULT sq_readclosure(HSQUIRRELVM v,SQREADFUNC r,SQUserPointer up)
-{
- SQObjectPtr closure;
-
- unsigned short tag;
- if(r(up,&tag,2) != 2)
- return sq_throwerror(v,_SC("io error"));
- if(tag != SQ_BYTECODE_STREAM_TAG)
- return sq_throwerror(v,_SC("invalid stream"));
- if(!SQClosure::Load(v,up,r,closure))
- return SQ_ERROR;
- v->Push(closure);
- return SQ_OK;
-}
-
-SQChar *sq_getscratchpad(HSQUIRRELVM v,SQInteger minsize)
-{
- return _ss(v)->GetScratchPad(minsize);
-}
-
-SQInteger sq_collectgarbage(HSQUIRRELVM v)
-{
-#ifndef NO_GARBAGE_COLLECTOR
- return _ss(v)->CollectGarbage(v);
-#else
- return -1;
-#endif
-}
-
-const SQChar *sq_getfreevariable(HSQUIRRELVM v,SQInteger idx,SQUnsignedInteger nval)
-{
- SQObjectPtr &self = stack_get(v,idx);
- const SQChar *name = NULL;
- if(type(self) == OT_CLOSURE) {
- if(_closure(self)->_outervalues.size()>nval) {
- v->Push(_closure(self)->_outervalues[nval]);
- SQFunctionProto *fp = _funcproto(_closure(self)->_function);
- SQOuterVar &ov = fp->_outervalues[nval];
- name = _stringval(ov._name);
- }
- }
- return name;
-}
-
-SQRESULT sq_setfreevariable(HSQUIRRELVM v,SQInteger idx,SQUnsignedInteger nval)
-{
- SQObjectPtr &self=stack_get(v,idx);
- switch(type(self))
- {
- case OT_CLOSURE:
- if(_closure(self)->_outervalues.size()>nval){
- _closure(self)->_outervalues[nval]=stack_get(v,-1);
- }
- else return sq_throwerror(v,_SC("invalid free var index"));
- break;
- case OT_NATIVECLOSURE:
- if(_nativeclosure(self)->_outervalues.size()>nval){
- _nativeclosure(self)->_outervalues[nval]=stack_get(v,-1);
- }
- else return sq_throwerror(v,_SC("invalid free var index"));
- break;
- default:
- return sq_aux_invalidtype(v,type(self));
- }
- v->Pop(1);
- return SQ_OK;
-}
-
-SQRESULT sq_setattributes(HSQUIRRELVM v,SQInteger idx)
-{
- SQObjectPtr *o = NULL;
- _GETSAFE_OBJ(v, idx, OT_CLASS,o);
- SQObjectPtr &key = stack_get(v,-2);
- SQObjectPtr &val = stack_get(v,-1);
- SQObjectPtr attrs;
- if(type(key) == OT_NULL) {
- attrs = _class(*o)->_attributes;
- _class(*o)->_attributes = val;
- v->Pop(2);
- v->Push(attrs);
- return SQ_OK;
- }else if(_class(*o)->GetAttributes(key,attrs)) {
- _class(*o)->SetAttributes(key,val);
- v->Pop(2);
- v->Push(attrs);
- return SQ_OK;
- }
- return sq_throwerror(v,_SC("wrong index"));
-}
-
-SQRESULT sq_getattributes(HSQUIRRELVM v,SQInteger idx)
-{
- SQObjectPtr *o = NULL;
- _GETSAFE_OBJ(v, idx, OT_CLASS,o);
- SQObjectPtr &key = stack_get(v,-1);
- SQObjectPtr attrs;
- if(type(key) == OT_NULL) {
- attrs = _class(*o)->_attributes;
- v->Pop();
- v->Push(attrs);
- return SQ_OK;
- }
- else if(_class(*o)->GetAttributes(key,attrs)) {
- v->Pop();
- v->Push(attrs);
- return SQ_OK;
- }
- return sq_throwerror(v,_SC("wrong index"));
-}
-
-SQRESULT sq_getbase(HSQUIRRELVM v,SQInteger idx)
-{
- SQObjectPtr *o = NULL;
- _GETSAFE_OBJ(v, idx, OT_CLASS,o);
- if(_class(*o)->_base)
- v->Push(SQObjectPtr(_class(*o)->_base));
- else
- v->Push(_null_);
- return SQ_OK;
-}
-
-SQRESULT sq_getclass(HSQUIRRELVM v,SQInteger idx)
-{
- SQObjectPtr *o = NULL;
- _GETSAFE_OBJ(v, idx, OT_INSTANCE,o);
- v->Push(SQObjectPtr(_instance(*o)->_class));
- return SQ_OK;
-}
-
-SQRESULT sq_createinstance(HSQUIRRELVM v,SQInteger idx)
-{
- SQObjectPtr *o = NULL;
- _GETSAFE_OBJ(v, idx, OT_CLASS,o);
- v->Push(_class(*o)->CreateInstance());
- return SQ_OK;
-}
-
-void sq_weakref(HSQUIRRELVM v,SQInteger idx)
-{
- SQObject &o=stack_get(v,idx);
- if(ISREFCOUNTED(type(o))) {
- v->Push(_refcounted(o)->GetWeakRef(type(o)));
- return;
- }
- v->Push(o);
-}
-
-SQRESULT sq_getweakrefval(HSQUIRRELVM v,SQInteger idx)
-{
- SQObjectPtr &o = stack_get(v,idx);
- if(type(o) != OT_WEAKREF) {
- return sq_throwerror(v,_SC("the object must be a weakref"));
- }
- v->Push(_weakref(o)->_obj);
- return SQ_OK;
-}
-
-SQRESULT sq_getdefaultdelegate(HSQUIRRELVM v,SQObjectType t)
-{
- SQSharedState *ss = _ss(v);
- switch(t) {
- case OT_TABLE: v->Push(ss->_table_default_delegate); break;
- case OT_ARRAY: v->Push(ss->_array_default_delegate); break;
- case OT_STRING: v->Push(ss->_string_default_delegate); break;
- case OT_INTEGER: case OT_FLOAT: v->Push(ss->_number_default_delegate); break;
- case OT_GENERATOR: v->Push(ss->_generator_default_delegate); break;
- case OT_CLOSURE: case OT_NATIVECLOSURE: v->Push(ss->_closure_default_delegate); break;
- case OT_THREAD: v->Push(ss->_thread_default_delegate); break;
- case OT_CLASS: v->Push(ss->_class_default_delegate); break;
- case OT_INSTANCE: v->Push(ss->_instance_default_delegate); break;
- case OT_WEAKREF: v->Push(ss->_weakref_default_delegate); break;
- default: return sq_throwerror(v,_SC("the type doesn't have a default delegate"));
- }
- return SQ_OK;
-}
-
-SQRESULT sq_next(HSQUIRRELVM v,SQInteger idx)
-{
- SQObjectPtr o=stack_get(v,idx),&refpos = stack_get(v,-1),realkey,val;
- if(type(o) == OT_GENERATOR) {
- return sq_throwerror(v,_SC("cannot iterate a generator"));
- }
- int faketojump;
- if(!v->FOREACH_OP(o,realkey,val,refpos,0,666,faketojump))
- return SQ_ERROR;
- if(faketojump != 666) {
- v->Push(realkey);
- v->Push(val);
- return SQ_OK;
- }
- return SQ_ERROR;
-}
-
-struct BufState{
- const SQChar *buf;
- SQInteger ptr;
- SQInteger size;
-};
-
-SQInteger buf_lexfeed(SQUserPointer file)
-{
- BufState *buf=(BufState*)file;
- if(buf->size<(buf->ptr+1))
- return 0;
- return buf->buf[buf->ptr++];
-}
-
-SQRESULT sq_compilebuffer(HSQUIRRELVM v,const SQChar *s,SQInteger size,const SQChar *sourcename,SQBool raiseerror) {
- BufState buf;
- buf.buf = s;
- buf.size = size;
- buf.ptr = 0;
- return sq_compile(v, buf_lexfeed, &buf, sourcename, raiseerror);
-}
-
-void sq_move(HSQUIRRELVM dest,HSQUIRRELVM src,SQInteger idx)
-{
- dest->Push(stack_get(src,idx));
-}
-
-void sq_setprintfunc(HSQUIRRELVM v, SQPRINTFUNCTION printfunc)
-{
- _ss(v)->_printfunc = printfunc;
-}
-
-SQPRINTFUNCTION sq_getprintfunc(HSQUIRRELVM v)
-{
- return _ss(v)->_printfunc;
-}
-
-void *sq_malloc(SQUnsignedInteger size)
-{
- return SQ_MALLOC(size);
-}
-
-void *sq_realloc(void* p,SQUnsignedInteger oldsize,SQUnsignedInteger newsize)
-{
- return SQ_REALLOC(p,oldsize,newsize);
-}
-
-void sq_free(void *p,SQUnsignedInteger size)
-{
- SQ_FREE(p,size);
-}
+++ /dev/null
-/* see copyright notice in squirrel.h */
-#ifndef _SQARRAY_H_
-#define _SQARRAY_H_
-
-struct SQArray : public CHAINABLE_OBJ
-{
-private:
- SQArray(SQSharedState *ss,SQInteger nsize){_values.resize(nsize); INIT_CHAIN();ADD_TO_CHAIN(&_ss(this)->_gc_chain,this);}
- ~SQArray()
- {
- REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain,this);
- }
-public:
- static SQArray* Create(SQSharedState *ss,SQInteger nInitialSize){
- SQArray *newarray=(SQArray*)SQ_MALLOC(sizeof(SQArray));
- new (newarray) SQArray(ss,nInitialSize);
- return newarray;
- }
-#ifndef NO_GARBAGE_COLLECTOR
- void Mark(SQCollectable **chain);
-#endif
- void Finalize(){
- _values.resize(0);
- }
- bool Get(const SQInteger nidx,SQObjectPtr &val)
- {
- if(nidx>=0 && nidx<(SQInteger)_values.size()){
- SQObjectPtr &o = _values[nidx];
- val = _realval(o);
- return true;
- }
- else return false;
- }
- bool Set(const SQInteger nidx,const SQObjectPtr &val)
- {
- if(nidx>=0 && nidx<(SQInteger)_values.size()){
- _values[nidx]=val;
- return true;
- }
- else return false;
- }
- SQInteger Next(const SQObjectPtr &refpos,SQObjectPtr &outkey,SQObjectPtr &outval)
- {
- SQUnsignedInteger idx=TranslateIndex(refpos);
- while(idx<_values.size()){
- //first found
- outkey=(SQInteger)idx;
- SQObjectPtr &o = _values[idx];
- outval = _realval(o);
- //return idx for the next iteration
- return ++idx;
- }
- //nothing to iterate anymore
- return -1;
- }
- SQArray *Clone(){SQArray *anew=Create(_opt_ss(this),Size()); anew->_values.copy(_values); return anew; }
- SQInteger Size() const {return _values.size();}
- void Resize(SQInteger size,SQObjectPtr &fill = _null_) { _values.resize(size,fill); ShrinkIfNeeded(); }
- void Reserve(SQInteger size) { _values.reserve(size); }
- void Append(const SQObject &o){_values.push_back(o);}
- void Extend(const SQArray *a);
- SQObjectPtr &Top(){return _values.top();}
- void Pop(){_values.pop_back(); ShrinkIfNeeded(); }
- void Insert(const SQObject& idx,const SQObject &val){_values.insert((SQUnsignedInteger)tointeger(idx),val);}
- void ShrinkIfNeeded() {
- if(_values.size() <= _values.capacity()>>2) //shrink the array
- _values.shrinktofit();
- }
- void Remove(SQUnsignedInteger idx){
- _values.remove(idx);
- ShrinkIfNeeded();
- }
- void Release()
- {
- sq_delete(this,SQArray);
- }
- SQObjectPtrVec _values;
-};
-#endif //_SQARRAY_H_
+++ /dev/null
-/*
- see copyright notice in squirrel.h
-*/
-#include "sqpcheader.h"
-#include "sqvm.h"
-#include "sqstring.h"
-#include "sqtable.h"
-#include "sqarray.h"
-#include "sqfuncproto.h"
-#include "sqclosure.h"
-#include "sqclass.h"
-#include <stdlib.h>
-#include <stdarg.h>
-#include <ctype.h>
-
-bool str2num(const SQChar *s,SQObjectPtr &res)
-{
- SQChar *end;
- if(scstrstr(s,_SC("."))){
- SQFloat r = SQFloat(scstrtod(s,&end));
- if(s == end) return false;
- res = r;
- return true;
- }
- else{
- SQInteger r = SQInteger(scstrtol(s,&end,10));
- if(s == end) return false;
- res = r;
- return true;
- }
-}
-
-static SQInteger base_dummy(HSQUIRRELVM v)
-{
- return 0;
-}
-
-#ifndef NO_GARBAGE_COLLECTOR
-static SQInteger base_collectgarbage(HSQUIRRELVM v)
-{
- sq_pushinteger(v, sq_collectgarbage(v));
- return 1;
-}
-#endif
-
-static SQInteger base_getroottable(HSQUIRRELVM v)
-{
- v->Push(v->_roottable);
- return 1;
-}
-
-static SQInteger base_setroottable(HSQUIRRELVM v)
-{
- SQObjectPtr &o=stack_get(v,2);
- if(SQ_FAILED(sq_setroottable(v))) return SQ_ERROR;
- v->Push(o);
- return 1;
-}
-
-static SQInteger base_seterrorhandler(HSQUIRRELVM v)
-{
- sq_seterrorhandler(v);
- return 0;
-}
-
-static SQInteger base_setdebughook(HSQUIRRELVM v)
-{
- sq_setdebughook(v);
- return 0;
-}
-
-static SQInteger base_enabledebuginfo(HSQUIRRELVM v)
-{
- SQObjectPtr &o=stack_get(v,2);
- sq_enabledebuginfo(v,(type(o) != OT_NULL)?1:0);
- return 0;
-}
-
-static SQInteger base_getstackinfos(HSQUIRRELVM v)
-{
- SQInteger level;
- SQStackInfos si;
- SQInteger seq = 0;
- const SQChar *name = NULL;
- sq_getinteger(v, -1, &level);
- if (SQ_SUCCEEDED(sq_stackinfos(v, level, &si)))
- {
- const SQChar *fn = _SC("unknown");
- const SQChar *src = _SC("unknown");
- if(si.funcname)fn = si.funcname;
- if(si.source)src = si.source;
- sq_newtable(v);
- sq_pushstring(v, _SC("func"), -1);
- sq_pushstring(v, fn, -1);
- sq_createslot(v, -3);
- sq_pushstring(v, _SC("src"), -1);
- sq_pushstring(v, src, -1);
- sq_createslot(v, -3);
- sq_pushstring(v, _SC("line"), -1);
- sq_pushinteger(v, si.line);
- sq_createslot(v, -3);
- sq_pushstring(v, _SC("locals"), -1);
- sq_newtable(v);
- seq=0;
- while ((name = sq_getlocal(v, level, seq))) {
- sq_pushstring(v, name, -1);
- sq_push(v, -2);
- sq_createslot(v, -4);
- sq_pop(v, 1);
- seq++;
- }
- sq_createslot(v, -3);
- return 1;
- }
-
- return 0;
-}
-
-static SQInteger base_assert(HSQUIRRELVM v)
-{
- if(v->IsFalse(stack_get(v,2))){
- return sq_throwerror(v,_SC("assertion failed"));
- }
- return 0;
-}
-
-static SQInteger get_slice_params(HSQUIRRELVM v,SQInteger &sidx,SQInteger &eidx,SQObjectPtr &o)
-{
- SQInteger top = sq_gettop(v);
- sidx=0;
- eidx=0;
- o=stack_get(v,1);
- SQObjectPtr &start=stack_get(v,2);
- if(type(start)!=OT_NULL && sq_isnumeric(start)){
- sidx=tointeger(start);
- }
- if(top>2){
- SQObjectPtr &end=stack_get(v,3);
- if(sq_isnumeric(end)){
- eidx=tointeger(end);
- }
- }
- else {
- eidx = sq_getsize(v,1);
- }
- return 1;
-}
-
-static SQInteger base_print(HSQUIRRELVM v)
-{
- const SQChar *str;
- sq_tostring(v,2);
- sq_getstring(v,-1,&str);
- if(_ss(v)->_printfunc) _ss(v)->_printfunc(v,_SC("%s"),str);
- return 0;
-}
-
-static SQInteger base_compilestring(HSQUIRRELVM v)
-{
- SQInteger nargs=sq_gettop(v);
- const SQChar *src=NULL,*name=_SC("unnamedbuffer");
- SQInteger size;
- sq_getstring(v,2,&src);
- size=sq_getsize(v,2);
- if(nargs>2){
- sq_getstring(v,3,&name);
- }
- if(SQ_SUCCEEDED(sq_compilebuffer(v,src,size,name,SQFalse)))
- return 1;
- else
- return SQ_ERROR;
-}
-
-static SQInteger base_newthread(HSQUIRRELVM v)
-{
- SQObjectPtr &func = stack_get(v,2);
- SQInteger stksize = (_funcproto(_closure(func)->_function)->_stacksize << 1) +2;
- HSQUIRRELVM newv = sq_newthread(v, (stksize < MIN_STACK_OVERHEAD + 2)? MIN_STACK_OVERHEAD + 2 : stksize);
- sq_move(newv,v,-2);
- return 1;
-}
-
-static SQInteger base_suspend(HSQUIRRELVM v)
-{
- return sq_suspendvm(v);
-}
-
-static SQInteger base_array(HSQUIRRELVM v)
-{
- SQArray *a;
- SQObject &size = stack_get(v,2);
- if(sq_gettop(v) > 2) {
- a = SQArray::Create(_ss(v),0);
- a->Resize(tointeger(size),stack_get(v,3));
- }
- else {
- a = SQArray::Create(_ss(v),tointeger(size));
- }
- v->Push(a);
- return 1;
-}
-
-static SQInteger base_type(HSQUIRRELVM v)
-{
- SQObjectPtr &o = stack_get(v,2);
- v->Push(SQString::Create(_ss(v),GetTypeName(o),-1));
- return 1;
-}
-
-static SQRegFunction base_funcs[]={
- //generic
- {_SC("seterrorhandler"),base_seterrorhandler,2, NULL},
- {_SC("setdebughook"),base_setdebughook,2, NULL},
- {_SC("enabledebuginfo"),base_enabledebuginfo,2, NULL},
- {_SC("getstackinfos"),base_getstackinfos,2, _SC(".n")},
- {_SC("getroottable"),base_getroottable,1, NULL},
- {_SC("setroottable"),base_setroottable,2, NULL},
- {_SC("assert"),base_assert,2, NULL},
- {_SC("print"),base_print,2, NULL},
- {_SC("compilestring"),base_compilestring,-2, _SC(".ss")},
- {_SC("newthread"),base_newthread,2, _SC(".c")},
- {_SC("suspend"),base_suspend,-1, NULL},
- {_SC("array"),base_array,-2, _SC(".n")},
- {_SC("type"),base_type,2, NULL},
- {_SC("dummy"),base_dummy,0,NULL},
-#ifndef NO_GARBAGE_COLLECTOR
- {_SC("collectgarbage"),base_collectgarbage,1, _SC("t")},
-#endif
- {0,0}
-};
-
-void sq_base_register(HSQUIRRELVM v)
-{
- SQInteger i=0;
- sq_pushroottable(v);
- while(base_funcs[i].name!=0) {
- sq_pushstring(v,base_funcs[i].name,-1);
- sq_newclosure(v,base_funcs[i].f,0);
- sq_setnativeclosurename(v,-1,base_funcs[i].name);
- sq_setparamscheck(v,base_funcs[i].nparamscheck,base_funcs[i].typemask);
- sq_createslot(v,-3);
- i++;
- }
- sq_pushstring(v,_SC("_version_"),-1);
- sq_pushstring(v,SQUIRREL_VERSION,-1);
- sq_createslot(v,-3);
- sq_pushstring(v,_SC("_charsize_"),-1);
- sq_pushinteger(v,sizeof(SQChar));
- sq_createslot(v,-3);
- sq_pushstring(v,_SC("_intsize_"),-1);
- sq_pushinteger(v,sizeof(SQInteger));
- sq_createslot(v,-3);
- sq_pop(v,1);
-}
-
-static SQInteger default_delegate_len(HSQUIRRELVM v)
-{
- v->Push(SQInteger(sq_getsize(v,1)));
- return 1;
-}
-
-static SQInteger default_delegate_tofloat(HSQUIRRELVM v)
-{
- SQObjectPtr &o=stack_get(v,1);
- switch(type(o)){
- case OT_STRING:{
- SQObjectPtr res;
- if(str2num(_stringval(o),res)){
- v->Push(SQObjectPtr(tofloat(res)));
- break;
- }}
- return sq_throwerror(v, _SC("cannot convert the string"));
- break;
- case OT_INTEGER:case OT_FLOAT:
- v->Push(SQObjectPtr(tofloat(o)));
- break;
- case OT_BOOL:
- v->Push(SQObjectPtr((SQFloat)(_integer(o)?1:0)));
- break;
- default:
- v->Push(_null_);
- break;
- }
- return 1;
-}
-
-static SQInteger default_delegate_tointeger(HSQUIRRELVM v)
-{
- SQObjectPtr &o=stack_get(v,1);
- switch(type(o)){
- case OT_STRING:{
- SQObjectPtr res;
- if(str2num(_stringval(o),res)){
- v->Push(SQObjectPtr(tointeger(res)));
- break;
- }}
- return sq_throwerror(v, _SC("cannot convert the string"));
- break;
- case OT_INTEGER:case OT_FLOAT:
- v->Push(SQObjectPtr(tointeger(o)));
- break;
- case OT_BOOL:
- v->Push(SQObjectPtr(_integer(o)?(SQInteger)1:(SQInteger)0));
- break;
- default:
- v->Push(_null_);
- break;
- }
- return 1;
-}
-
-static SQInteger default_delegate_tostring(HSQUIRRELVM v)
-{
- sq_tostring(v,1);
- return 1;
-}
-
-static SQInteger obj_delegate_weakref(HSQUIRRELVM v)
-{
- sq_weakref(v,1);
- return 1;
-}
-
-static SQInteger obj_clear(HSQUIRRELVM v)
-{
- return sq_clear(v,-1);
-}
-
-
-static SQInteger number_delegate_tochar(HSQUIRRELVM v)
-{
- SQObject &o=stack_get(v,1);
- SQChar c = (SQChar)tointeger(o);
- v->Push(SQString::Create(_ss(v),(const SQChar *)&c,1));
- return 1;
-}
-
-
-/////////////////////////////////////////////////////////////////
-//TABLE DEFAULT DELEGATE
-
-static SQInteger table_rawdelete(HSQUIRRELVM v)
-{
- if(SQ_FAILED(sq_rawdeleteslot(v,1,SQTrue)))
- return SQ_ERROR;
- return 1;
-}
-
-
-static SQInteger container_rawexists(HSQUIRRELVM v)
-{
- if(SQ_SUCCEEDED(sq_rawget(v,-2))) {
- sq_pushbool(v,SQTrue);
- return 1;
- }
- sq_pushbool(v,SQFalse);
- return 1;
-}
-
-static SQInteger table_rawset(HSQUIRRELVM v)
-{
- return sq_rawset(v,-3);
-}
-
-
-static SQInteger table_rawget(HSQUIRRELVM v)
-{
- return SQ_SUCCEEDED(sq_rawget(v,-2))?1:SQ_ERROR;
-}
-
-
-SQRegFunction SQSharedState::_table_default_delegate_funcz[]={
- {_SC("len"),default_delegate_len,1, _SC("t")},
- {_SC("rawget"),table_rawget,2, _SC("t")},
- {_SC("rawset"),table_rawset,3, _SC("t")},
- {_SC("rawdelete"),table_rawdelete,2, _SC("t")},
- {_SC("rawin"),container_rawexists,2, _SC("t")},
- {_SC("weakref"),obj_delegate_weakref,1, NULL },
- {_SC("tostring"),default_delegate_tostring,1, _SC(".")},
- {_SC("clear"),obj_clear,1, _SC(".")},
- {0,0}
-};
-
-//ARRAY DEFAULT DELEGATE///////////////////////////////////////
-
-static SQInteger array_append(HSQUIRRELVM v)
-{
- return sq_arrayappend(v,-2);
-}
-
-static SQInteger array_extend(HSQUIRRELVM v)
-{
- _array(stack_get(v,1))->Extend(_array(stack_get(v,2)));
- return 0;
-}
-
-static SQInteger array_reverse(HSQUIRRELVM v)
-{
- return sq_arrayreverse(v,-1);
-}
-
-static SQInteger array_pop(HSQUIRRELVM v)
-{
- return SQ_SUCCEEDED(sq_arraypop(v,1,SQTrue))?1:SQ_ERROR;
-}
-
-static SQInteger array_top(HSQUIRRELVM v)
-{
- SQObject &o=stack_get(v,1);
- if(_array(o)->Size()>0){
- v->Push(_array(o)->Top());
- return 1;
- }
- else return sq_throwerror(v,_SC("top() on a empty array"));
-}
-
-static SQInteger array_insert(HSQUIRRELVM v)
-{
- SQObject &o=stack_get(v,1);
- SQObject &idx=stack_get(v,2);
- SQObject &val=stack_get(v,3);
- _array(o)->Insert(idx,val);
- return 0;
-}
-
-static SQInteger array_remove(HSQUIRRELVM v)
-{
- SQObject &o = stack_get(v, 1);
- SQObject &idx = stack_get(v, 2);
- if(!sq_isnumeric(idx)) return sq_throwerror(v, _SC("wrong type"));
- SQObjectPtr val;
- if(_array(o)->Get(tointeger(idx), val)) {
- _array(o)->Remove(tointeger(idx));
- v->Push(val);
- return 1;
- }
- return sq_throwerror(v, _SC("idx out of range"));
-}
-
-static SQInteger array_resize(HSQUIRRELVM v)
-{
- SQObject &o = stack_get(v, 1);
- SQObject &nsize = stack_get(v, 2);
- SQObjectPtr fill;
- if(sq_isnumeric(nsize)) {
- if(sq_gettop(v) > 2)
- fill = stack_get(v, 3);
- _array(o)->Resize(tointeger(nsize),fill);
- return 0;
- }
- return sq_throwerror(v, _SC("size must be a number"));
-}
-
-
-//QSORT ala Sedgewick
-bool _qsort_compare(HSQUIRRELVM v,SQObjectPtr &arr,SQObjectPtr &a,SQObjectPtr &b,SQInteger func,SQInteger &ret)
-{
- if(func < 0) {
- if(!v->ObjCmp(a,b,ret)) return false;
- }
- else {
- SQInteger top = sq_gettop(v);
- sq_push(v, func);
- sq_pushroottable(v);
- v->Push(a);
- v->Push(b);
- if(SQ_FAILED(sq_call(v, 3, SQTrue, SQFalse))) {
- v->Raise_Error(_SC("compare func failed"));
- return false;
- }
- sq_getinteger(v, -1, &ret);
- sq_settop(v, top);
- return true;
- }
- return true;
-}
-//QSORT ala Sedgewick
-bool _qsort(HSQUIRRELVM v,SQObjectPtr &arr, SQInteger l, SQInteger r,SQInteger func)
-{
- SQInteger i, j;
- SQArray *a=_array(arr);
- SQObjectPtr pivot,t;
- if( l < r ){
- pivot = a->_values[l];
- i = l; j = r+1;
- while(1){
- SQInteger ret;
- do {
- ++i;
- if(i > r) break;
- if(!_qsort_compare(v,arr,a->_values[i],pivot,func,ret))
- return false;
- } while( ret <= 0);
- do {
- --j;
- if(!_qsort_compare(v,arr,a->_values[j],pivot,func,ret))
- return false;
- }
- while( ret > 0 );
- if( i >= j ) break;
- t = a->_values[i]; a->_values[i] = a->_values[j]; a->_values[j] = t;
- }
- t = a->_values[l]; a->_values[l] = a->_values[j]; a->_values[j] = t;
- if(!_qsort( v, arr, l, j-1,func)) return false;
- if(!_qsort( v, arr, j+1, r,func)) return false;
- }
- return true;
-}
-
-static SQInteger array_sort(HSQUIRRELVM v)
-{
- SQInteger func = -1;
- SQObjectPtr &o = stack_get(v,1);
- SQObject &funcobj = stack_get(v,2);
- if(_array(o)->Size() > 1) {
- if(type(funcobj) == OT_CLOSURE || type(funcobj) == OT_NATIVECLOSURE) func = 2;
- if(!_qsort(v, o, 0, _array(o)->Size()-1, func))
- return SQ_ERROR;
-
- }
- return 0;
-}
-static SQInteger array_slice(HSQUIRRELVM v)
-{
- SQInteger sidx,eidx;
- SQObjectPtr o;
- if(get_slice_params(v,sidx,eidx,o)==-1)return -1;
- if(sidx<0)sidx=_array(o)->Size()+sidx;
- if(eidx<0)eidx=_array(o)->Size()+eidx;
- if(eidx < sidx)return sq_throwerror(v,_SC("wrong indexes"));
- SQArray *arr=SQArray::Create(_ss(v),eidx-sidx);
- SQObjectPtr t;
- SQInteger count=0;
- for(SQInteger i=sidx;i<eidx;i++){
- _array(o)->Get(i,t);
- arr->Set(count++,t);
- }
- v->Push(arr);
- return 1;
-
-}
-
-SQRegFunction SQSharedState::_array_default_delegate_funcz[]={
- {_SC("len"),default_delegate_len,1, _SC("a")},
- {_SC("append"),array_append,2, _SC("a")},
- {_SC("extend"),array_extend,2, _SC("aa")},
- {_SC("push"),array_append,2, _SC("a")},
- {_SC("pop"),array_pop,1, _SC("a")},
- {_SC("top"),array_top,1, _SC("a")},
- {_SC("insert"),array_insert,3, _SC("an")},
- {_SC("remove"),array_remove,2, _SC("an")},
- {_SC("resize"),array_resize,-2, _SC("an")},
- {_SC("reverse"),array_reverse,1, _SC("a")},
- {_SC("sort"),array_sort,-1, _SC("ac")},
- {_SC("slice"),array_slice,-1, _SC("ann")},
- {_SC("weakref"),obj_delegate_weakref,1, NULL },
- {_SC("tostring"),default_delegate_tostring,1, _SC(".")},
- {_SC("clear"),obj_clear,1, _SC(".")},
- {0,0}
-};
-
-//STRING DEFAULT DELEGATE//////////////////////////
-static SQInteger string_slice(HSQUIRRELVM v)
-{
- SQInteger sidx,eidx;
- SQObjectPtr o;
- if(SQ_FAILED(get_slice_params(v,sidx,eidx,o)))return -1;
- if(sidx<0)sidx=_string(o)->_len+sidx;
- if(eidx<0)eidx=_string(o)->_len+eidx;
- if(eidx<sidx)
- return sq_throwerror(v,_SC("wrong indexes"));
- v->Push(SQString::Create(_ss(v),&_stringval(o)[sidx],eidx-sidx));
- return 1;
-}
-
-static SQInteger string_find(HSQUIRRELVM v)
-{
- SQInteger top,start_idx=0;
- const SQChar *str,*substr,*ret;
- if(((top=sq_gettop(v))>1) && SQ_SUCCEEDED(sq_getstring(v,1,&str)) && SQ_SUCCEEDED(sq_getstring(v,2,&substr))){
- if(top>2)sq_getinteger(v,3,&start_idx);
- if((sq_getsize(v,1)>start_idx) && (start_idx>=0)){
- ret=scstrstr(&str[start_idx],substr);
- if(ret){
- sq_pushinteger(v,(SQInteger)(ret-str));
- return 1;
- }
- }
- return 0;
- }
- return sq_throwerror(v,_SC("invalid param"));
-}
-
-#define STRING_TOFUNCZ(func) static SQInteger string_##func(HSQUIRRELVM v) \
-{ \
- SQObject str=stack_get(v,1); \
- SQInteger len=_string(str)->_len; \
- const SQChar *sThis=_stringval(str); \
- SQChar *sNew=(_ss(v)->GetScratchPad(rsl(len))); \
- for(SQInteger i=0;i<len;i++) sNew[i]=func(sThis[i]); \
- v->Push(SQString::Create(_ss(v),sNew,len)); \
- return 1; \
-}
-
-
-STRING_TOFUNCZ(tolower)
-STRING_TOFUNCZ(toupper)
-
-SQRegFunction SQSharedState::_string_default_delegate_funcz[]={
- {_SC("len"),default_delegate_len,1, _SC("s")},
- {_SC("tointeger"),default_delegate_tointeger,1, _SC("s")},
- {_SC("tofloat"),default_delegate_tofloat,1, _SC("s")},
- {_SC("tostring"),default_delegate_tostring,1, _SC(".")},
- {_SC("slice"),string_slice,-1, _SC(" s n n")},
- {_SC("find"),string_find,-2, _SC("s s n ")},
- {_SC("tolower"),string_tolower,1, _SC("s")},
- {_SC("toupper"),string_toupper,1, _SC("s")},
- {_SC("weakref"),obj_delegate_weakref,1, NULL },
- {0,0}
-};
-
-//INTEGER DEFAULT DELEGATE//////////////////////////
-SQRegFunction SQSharedState::_number_default_delegate_funcz[]={
- {_SC("tointeger"),default_delegate_tointeger,1, _SC("n|b")},
- {_SC("tofloat"),default_delegate_tofloat,1, _SC("n|b")},
- {_SC("tostring"),default_delegate_tostring,1, _SC(".")},
- {_SC("tochar"),number_delegate_tochar,1, _SC("n|b")},
- {_SC("weakref"),obj_delegate_weakref,1, NULL },
- {0,0}
-};
-
-//CLOSURE DEFAULT DELEGATE//////////////////////////
-static SQInteger closure_pcall(HSQUIRRELVM v)
-{
- return SQ_SUCCEEDED(sq_call(v,sq_gettop(v)-1,SQTrue,SQFalse))?1:SQ_ERROR;
-}
-
-static SQInteger closure_call(HSQUIRRELVM v)
-{
- return SQ_SUCCEEDED(sq_call(v,sq_gettop(v)-1,SQTrue,SQTrue))?1:SQ_ERROR;
-}
-
-static SQInteger _closure_acall(HSQUIRRELVM v,SQBool raiseerror)
-{
- SQArray *aparams=_array(stack_get(v,2));
- SQInteger nparams=aparams->Size();
- v->Push(stack_get(v,1));
- for(SQInteger i=0;i<nparams;i++)v->Push(aparams->_values[i]);
- return SQ_SUCCEEDED(sq_call(v,nparams,SQTrue,raiseerror))?1:SQ_ERROR;
-}
-
-static SQInteger closure_acall(HSQUIRRELVM v)
-{
- return _closure_acall(v,SQTrue);
-}
-
-static SQInteger closure_pacall(HSQUIRRELVM v)
-{
- return _closure_acall(v,SQFalse);
-}
-
-static SQInteger closure_bindenv(HSQUIRRELVM v)
-{
- if(SQ_FAILED(sq_bindenv(v,1)))
- return SQ_ERROR;
- return 1;
-}
-
-static SQInteger closure_getinfos(HSQUIRRELVM v) {
- SQObject o = stack_get(v,1);
- SQTable *res = SQTable::Create(_ss(v),4);
- if(type(o) == OT_CLOSURE) {
- SQFunctionProto *f = _funcproto(_closure(o)->_function);
- SQInteger nparams = f->_nparameters + (f->_varparams?1:0);
- SQObjectPtr params = SQArray::Create(_ss(v),nparams);
- for(SQInteger n = 0; n<f->_nparameters; n++) {
- _array(params)->Set((SQInteger)n,f->_parameters[n]);
- }
- if(f->_varparams) {
- _array(params)->Set(nparams-1,SQString::Create(_ss(v),_SC("..."),-1));
- }
- res->NewSlot(SQString::Create(_ss(v),_SC("native"),-1),false);
- res->NewSlot(SQString::Create(_ss(v),_SC("name"),-1),f->_name);
- res->NewSlot(SQString::Create(_ss(v),_SC("src"),-1),f->_sourcename);
- res->NewSlot(SQString::Create(_ss(v),_SC("parameters"),-1),params);
- res->NewSlot(SQString::Create(_ss(v),_SC("varargs"),-1),f->_varparams);
- }
- else { //OT_NATIVECLOSURE
- SQNativeClosure *nc = _nativeclosure(o);
- res->NewSlot(SQString::Create(_ss(v),_SC("native"),-1),true);
- res->NewSlot(SQString::Create(_ss(v),_SC("name"),-1),nc->_name);
- res->NewSlot(SQString::Create(_ss(v),_SC("paramscheck"),-1),nc->_nparamscheck);
- SQObjectPtr typecheck;
- if(nc->_typecheck.size() > 0) {
- typecheck =
- SQArray::Create(_ss(v), nc->_typecheck.size());
- for(SQUnsignedInteger n = 0; n<nc->_typecheck.size(); n++) {
- _array(typecheck)->Set((SQInteger)n,nc->_typecheck[n]);
- }
- }
- res->NewSlot(SQString::Create(_ss(v),_SC("typecheck"),-1),typecheck);
- }
- v->Push(res);
- return 1;
-}
-
-
-SQRegFunction SQSharedState::_closure_default_delegate_funcz[]={
- {_SC("call"),closure_call,-1, _SC("c")},
- {_SC("pcall"),closure_pcall,-1, _SC("c")},
- {_SC("acall"),closure_acall,2, _SC("ca")},
- {_SC("pacall"),closure_pacall,2, _SC("ca")},
- {_SC("weakref"),obj_delegate_weakref,1, NULL },
- {_SC("tostring"),default_delegate_tostring,1, _SC(".")},
- {_SC("bindenv"),closure_bindenv,2, _SC("c x|y|t")},
- {_SC("getinfos"),closure_getinfos,1, _SC("c")},
- {0,0}
-};
-
-//GENERATOR DEFAULT DELEGATE
-static SQInteger generator_getstatus(HSQUIRRELVM v)
-{
- SQObject &o=stack_get(v,1);
- switch(_generator(o)->_state){
- case SQGenerator::eSuspended:v->Push(SQString::Create(_ss(v),_SC("suspended")));break;
- case SQGenerator::eRunning:v->Push(SQString::Create(_ss(v),_SC("running")));break;
- case SQGenerator::eDead:v->Push(SQString::Create(_ss(v),_SC("dead")));break;
- }
- return 1;
-}
-
-SQRegFunction SQSharedState::_generator_default_delegate_funcz[]={
- {_SC("getstatus"),generator_getstatus,1, _SC("g")},
- {_SC("weakref"),obj_delegate_weakref,1, NULL },
- {_SC("tostring"),default_delegate_tostring,1, _SC(".")},
- {0,0}
-};
-
-//THREAD DEFAULT DELEGATE
-
-static SQInteger thread_call(HSQUIRRELVM v)
-{
- SQObjectPtr o = stack_get(v,1);
- if(type(o) == OT_THREAD) {
- SQInteger nparams = sq_gettop(v);
- _thread(o)->Push(_thread(o)->_roottable);
- for(SQInteger i = 2; i<(nparams+1); i++)
- sq_move(_thread(o),v,i);
- if(SQ_SUCCEEDED(sq_call(_thread(o),nparams,SQTrue,SQFalse))) {
- sq_move(v,_thread(o),-1);
- return 1;
- }
- return SQ_ERROR;
- }
- return sq_throwerror(v,_SC("wrong parameter"));
-}
-
-static SQInteger thread_wakeup(HSQUIRRELVM v)
-{
- SQObjectPtr o = stack_get(v,1);
- if(type(o) == OT_THREAD) {
- SQVM *thread = _thread(o);
- SQInteger state = sq_getvmstate(thread);
- if(state != SQ_VMSTATE_SUSPENDED) {
- switch(state) {
- case SQ_VMSTATE_IDLE:
- return sq_throwerror(v,_SC("cannot wakeup a idle thread"));
- break;
- case SQ_VMSTATE_RUNNING:
- return sq_throwerror(v,_SC("cannot wakeup a running thread"));
- break;
- }
- }
-
- SQInteger wakeupret = sq_gettop(v)>1?1:0;
- if(wakeupret) {
- sq_move(thread,v,2);
- }
- if(SQ_SUCCEEDED(sq_wakeupvm(thread,wakeupret,1,SQFalse))) {
- sq_move(v,thread,-1);
- sq_pop(thread,1);
- if(sq_getvmstate(thread) == SQ_VMSTATE_IDLE) {
- sq_pop(thread,1);
- }
- return 1;
- }
- return SQ_ERROR;
- }
- return sq_throwerror(v,_SC("wrong parameter"));
-}
-
-static SQInteger thread_getstatus(HSQUIRRELVM v)
-{
- SQObjectPtr &o = stack_get(v,1);
- switch(sq_getvmstate(_thread(o))) {
- case SQ_VMSTATE_IDLE:
- sq_pushstring(v,_SC("idle"),-1);
- break;
- case SQ_VMSTATE_RUNNING:
- sq_pushstring(v,_SC("running"),-1);
- break;
- case SQ_VMSTATE_SUSPENDED:
- sq_pushstring(v,_SC("suspended"),-1);
- break;
- default:
- return sq_throwerror(v,_SC("internal VM error"));
- }
- return 1;
-}
-
-SQRegFunction SQSharedState::_thread_default_delegate_funcz[] = {
- {_SC("call"), thread_call, -1, _SC("v")},
- {_SC("wakeup"), thread_wakeup, -1, _SC("v")},
- {_SC("getstatus"), thread_getstatus, 1, _SC("v")},
- {_SC("weakref"),obj_delegate_weakref,1, NULL },
- {_SC("tostring"),default_delegate_tostring,1, _SC(".")},
- {0,0},
-};
-
-static SQInteger class_getattributes(HSQUIRRELVM v)
-{
- if(SQ_SUCCEEDED(sq_getattributes(v,-2)))
- return 1;
- return SQ_ERROR;
-}
-
-static SQInteger class_setattributes(HSQUIRRELVM v)
-{
- if(SQ_SUCCEEDED(sq_setattributes(v,-3)))
- return 1;
- return SQ_ERROR;
-}
-
-static SQInteger class_instance(HSQUIRRELVM v)
-{
- if(SQ_SUCCEEDED(sq_createinstance(v,-1)))
- return 1;
- return SQ_ERROR;
-}
-
-SQRegFunction SQSharedState::_class_default_delegate_funcz[] = {
- {_SC("getattributes"), class_getattributes, 2, _SC("y.")},
- {_SC("setattributes"), class_setattributes, 3, _SC("y..")},
- {_SC("rawin"),container_rawexists,2, _SC("y")},
- {_SC("weakref"),obj_delegate_weakref,1, NULL },
- {_SC("tostring"),default_delegate_tostring,1, _SC(".")},
- {_SC("instance"),class_instance,1, _SC("y")},
- {0,0}
-};
-
-static SQInteger instance_getclass(HSQUIRRELVM v)
-{
- if(SQ_SUCCEEDED(sq_getclass(v,1)))
- return 1;
- return SQ_ERROR;
-}
-
-SQRegFunction SQSharedState::_instance_default_delegate_funcz[] = {
- {_SC("getclass"), instance_getclass, 1, _SC("x")},
- {_SC("rawin"),container_rawexists,2, _SC("x")},
- {_SC("weakref"),obj_delegate_weakref,1, NULL },
- {_SC("tostring"),default_delegate_tostring,1, _SC(".")},
- {0,0}
-};
-
-static SQInteger weakref_ref(HSQUIRRELVM v)
-{
- if(SQ_FAILED(sq_getweakrefval(v,1)))
- return SQ_ERROR;
- return 1;
-}
-
-SQRegFunction SQSharedState::_weakref_default_delegate_funcz[] = {
- {_SC("ref"),weakref_ref,1, _SC("r")},
- {_SC("weakref"),obj_delegate_weakref,1, NULL },
- {_SC("tostring"),default_delegate_tostring,1, _SC(".")},
- {0,0}
-};
-
-
+++ /dev/null
-/*
- see copyright notice in squirrel.h
-*/
-#include "sqpcheader.h"
-#include "sqvm.h"
-#include "sqtable.h"
-#include "sqclass.h"
-#include "sqclosure.h"
-
-SQClass::SQClass(SQSharedState *ss,SQClass *base)
-{
- _base = base;
- _typetag = 0;
- _hook = NULL;
- _udsize = 0;
- _metamethods.resize(MT_LAST); //size it to max size
- if(_base) {
- _defaultvalues.copy(base->_defaultvalues);
- _methods.copy(base->_methods);
- _metamethods.copy(base->_metamethods);
- __ObjAddRef(_base);
- }
- _members = base?base->_members->Clone() : SQTable::Create(ss,0);
- __ObjAddRef(_members);
- _locked = false;
- INIT_CHAIN();
- ADD_TO_CHAIN(&_sharedstate->_gc_chain, this);
-}
-
-void SQClass::Finalize() {
- _attributes = _null_;
- _defaultvalues.resize(0);
- _methods.resize(0);
- _metamethods.resize(0);
- __ObjRelease(_members);
- if(_base) {
- __ObjRelease(_base);
- }
-}
-
-SQClass::~SQClass()
-{
- REMOVE_FROM_CHAIN(&_sharedstate->_gc_chain, this);
- Finalize();
-}
-
-bool SQClass::NewSlot(SQSharedState *ss,const SQObjectPtr &key,const SQObjectPtr &val,bool bstatic)
-{
- SQObjectPtr temp;
- if(_locked)
- return false; //the class already has an instance so cannot be modified
- if(_members->Get(key,temp) && _isfield(temp)) //overrides the default value
- {
- _defaultvalues[_member_idx(temp)].val = val;
- return true;
- }
- if(type(val) == OT_CLOSURE || type(val) == OT_NATIVECLOSURE || bstatic) {
- SQInteger mmidx;
- if((type(val) == OT_CLOSURE || type(val) == OT_NATIVECLOSURE) &&
- (mmidx = ss->GetMetaMethodIdxByName(key)) != -1) {
- _metamethods[mmidx] = val;
- }
- else {
- if(type(temp) == OT_NULL) {
- SQClassMember m;
- m.val = val;
- _members->NewSlot(key,SQObjectPtr(_make_method_idx(_methods.size())));
- _methods.push_back(m);
- }
- else {
- _methods[_member_idx(temp)].val = val;
- }
- }
- return true;
- }
- SQClassMember m;
- m.val = val;
- _members->NewSlot(key,SQObjectPtr(_make_field_idx(_defaultvalues.size())));
- _defaultvalues.push_back(m);
- return true;
-}
-
-SQInstance *SQClass::CreateInstance()
-{
- if(!_locked) Lock();
- return SQInstance::Create(_opt_ss(this),this);
-}
-
-SQInteger SQClass::Next(const SQObjectPtr &refpos, SQObjectPtr &outkey, SQObjectPtr &outval)
-{
- SQObjectPtr oval;
- SQInteger idx = _members->Next(false,refpos,outkey,oval);
- if(idx != -1) {
- if(_ismethod(oval)) {
- outval = _methods[_member_idx(oval)].val;
- }
- else {
- SQObjectPtr &o = _defaultvalues[_member_idx(oval)].val;
- outval = _realval(o);
- }
- }
- return idx;
-}
-
-bool SQClass::SetAttributes(const SQObjectPtr &key,const SQObjectPtr &val)
-{
- SQObjectPtr idx;
- if(_members->Get(key,idx)) {
- if(_isfield(idx))
- _defaultvalues[_member_idx(idx)].attrs = val;
- else
- _methods[_member_idx(idx)].attrs = val;
- return true;
- }
- return false;
-}
-
-bool SQClass::GetAttributes(const SQObjectPtr &key,SQObjectPtr &outval)
-{
- SQObjectPtr idx;
- if(_members->Get(key,idx)) {
- outval = (_isfield(idx)?_defaultvalues[_member_idx(idx)].attrs:_methods[_member_idx(idx)].attrs);
- return true;
- }
- return false;
-}
-
-///////////////////////////////////////////////////////////////////////
-void SQInstance::Init(SQSharedState *ss)
-{
- _userpointer = NULL;
- _hook = NULL;
- __ObjAddRef(_class);
- _delegate = _class->_members;
- INIT_CHAIN();
- ADD_TO_CHAIN(&_sharedstate->_gc_chain, this);
-}
-
-SQInstance::SQInstance(SQSharedState *ss, SQClass *c, SQInteger memsize)
-{
- _memsize = memsize;
- _class = c;
- SQUnsignedInteger nvalues = _class->_defaultvalues.size();
- for(SQUnsignedInteger n = 0; n < nvalues; n++) {
- new (&_values[n]) SQObjectPtr(_class->_defaultvalues[n].val);
- }
- Init(ss);
-}
-
-SQInstance::SQInstance(SQSharedState *ss, SQInstance *i, SQInteger memsize)
-{
- _memsize = memsize;
- _class = i->_class;
- SQUnsignedInteger nvalues = _class->_defaultvalues.size();
- for(SQUnsignedInteger n = 0; n < nvalues; n++) {
- new (&_values[n]) SQObjectPtr(i->_values[n]);
- }
- Init(ss);
-}
-
-void SQInstance::Finalize()
-{
- SQUnsignedInteger nvalues = _class->_defaultvalues.size();
- __ObjRelease(_class);
- for(SQUnsignedInteger i = 0; i < nvalues; i++) {
- _values[i] = _null_;
- }
-}
-
-SQInstance::~SQInstance()
-{
- REMOVE_FROM_CHAIN(&_sharedstate->_gc_chain, this);
- if(_class){ Finalize(); } //if _class is null it was already finalized by the GC
-}
-
-bool SQInstance::GetMetaMethod(SQVM *v,SQMetaMethod mm,SQObjectPtr &res)
-{
- if(type(_class->_metamethods[mm]) != OT_NULL) {
- res = _class->_metamethods[mm];
- return true;
- }
- return false;
-}
-
-bool SQInstance::InstanceOf(SQClass *trg)
-{
- SQClass *parent = _class;
- while(parent != NULL) {
- if(parent == trg)
- return true;
- parent = parent->_base;
- }
- return false;
-}
+++ /dev/null
-/* see copyright notice in squirrel.h */
-#ifndef _SQCLASS_H_
-#define _SQCLASS_H_
-
-struct SQInstance;
-
-struct SQClassMember {
- SQClassMember(){}
- SQClassMember(const SQClassMember &o) {
- val = o.val;
- attrs = o.attrs;
- }
- SQObjectPtr val;
- SQObjectPtr attrs;
-};
-
-typedef sqvector<SQClassMember> SQClassMemberVec;
-
-#define MEMBER_TYPE_METHOD 0x01000000
-#define MEMBER_TYPE_FIELD 0x02000000
-
-#define _ismethod(o) (_integer(o)&MEMBER_TYPE_METHOD)
-#define _isfield(o) (_integer(o)&MEMBER_TYPE_FIELD)
-#define _make_method_idx(i) ((SQInteger)(MEMBER_TYPE_METHOD|i))
-#define _make_field_idx(i) ((SQInteger)(MEMBER_TYPE_FIELD|i))
-#define _member_type(o) (_integer(o)&0xFF000000)
-#define _member_idx(o) (_integer(o)&0x00FFFFFF)
-
-struct SQClass : public CHAINABLE_OBJ
-{
- SQClass(SQSharedState *ss,SQClass *base);
-public:
- static SQClass* Create(SQSharedState *ss,SQClass *base) {
- SQClass *newclass = (SQClass *)SQ_MALLOC(sizeof(SQClass));
- new (newclass) SQClass(ss, base);
- return newclass;
- }
- ~SQClass();
- bool NewSlot(SQSharedState *ss, const SQObjectPtr &key,const SQObjectPtr &val,bool bstatic);
- bool Get(const SQObjectPtr &key,SQObjectPtr &val) {
- if(_members->Get(key,val)) {
- if(_isfield(val)) {
- SQObjectPtr &o = _defaultvalues[_member_idx(val)].val;
- val = _realval(o);
- }
- else {
- val = _methods[_member_idx(val)].val;
- }
- return true;
- }
- return false;
- }
- bool SetAttributes(const SQObjectPtr &key,const SQObjectPtr &val);
- bool GetAttributes(const SQObjectPtr &key,SQObjectPtr &outval);
- void Lock() { _locked = true; if(_base) _base->Lock(); }
- void Release() {
- if (_hook) { _hook(_typetag,0);}
- sq_delete(this, SQClass);
- }
- void Finalize();
-#ifndef NO_GARBAGE_COLLECTOR
- void Mark(SQCollectable ** );
-#endif
- SQInteger Next(const SQObjectPtr &refpos, SQObjectPtr &outkey, SQObjectPtr &outval);
- SQInstance *CreateInstance();
- SQTable *_members;
- SQClass *_base;
- SQClassMemberVec _defaultvalues;
- SQClassMemberVec _methods;
- SQObjectPtrVec _metamethods;
- SQObjectPtr _attributes;
- SQUserPointer _typetag;
- SQRELEASEHOOK _hook;
- bool _locked;
- SQInteger _udsize;
-};
-
-#define calcinstancesize(_theclass_) \
- (_theclass_->_udsize + sizeof(SQInstance) + (sizeof(SQObjectPtr)*(_theclass_->_defaultvalues.size()>0?_theclass_->_defaultvalues.size()-1:0)))
-
-struct SQInstance : public SQDelegable
-{
- void Init(SQSharedState *ss);
- SQInstance(SQSharedState *ss, SQClass *c, SQInteger memsize);
- SQInstance(SQSharedState *ss, SQInstance *c, SQInteger memsize);
-public:
- static SQInstance* Create(SQSharedState *ss,SQClass *theclass) {
-
- SQInteger size = calcinstancesize(theclass);
- SQInstance *newinst = (SQInstance *)SQ_MALLOC(size);
- new (newinst) SQInstance(ss, theclass,size);
- if(theclass->_udsize) {
- newinst->_userpointer = ((unsigned char *)newinst) + (size - theclass->_udsize);
- }
- return newinst;
- }
- SQInstance *Clone(SQSharedState *ss)
- {
- SQInteger size = calcinstancesize(_class);
- SQInstance *newinst = (SQInstance *)SQ_MALLOC(size);
- new (newinst) SQInstance(ss, this,size);
- if(_class->_udsize) {
- newinst->_userpointer = ((unsigned char *)newinst) + (size - _class->_udsize);
- }
- return newinst;
- }
- ~SQInstance();
- bool Get(const SQObjectPtr &key,SQObjectPtr &val) {
- if(_class->_members->Get(key,val)) {
- if(_isfield(val)) {
- SQObjectPtr &o = _values[_member_idx(val)];
- val = _realval(o);
- }
- else {
- val = _class->_methods[_member_idx(val)].val;
- }
- return true;
- }
- return false;
- }
- bool Set(const SQObjectPtr &key,const SQObjectPtr &val) {
- SQObjectPtr idx;
- if(_class->_members->Get(key,idx) && _isfield(idx)) {
- _values[_member_idx(idx)] = val;
- return true;
- }
- return false;
- }
- void Release() {
- _uiRef++;
- if (_hook) { _hook(_userpointer,0);}
- _uiRef--;
- if(_uiRef > 0) return;
- SQInteger size = _memsize;
- this->~SQInstance();
- SQ_FREE(this, size);
- }
- void Finalize();
-#ifndef NO_GARBAGE_COLLECTOR
- void Mark(SQCollectable ** );
-#endif
- bool InstanceOf(SQClass *trg);
- bool GetMetaMethod(SQVM *v,SQMetaMethod mm,SQObjectPtr &res);
-
- SQClass *_class;
- SQUserPointer _userpointer;
- SQRELEASEHOOK _hook;
- SQInteger _memsize;
- SQObjectPtr _values[1];
-};
-
-#endif //_SQCLASS_H_
+++ /dev/null
-/* see copyright notice in squirrel.h */
-#ifndef _SQCLOSURE_H_
-#define _SQCLOSURE_H_
-
-struct SQFunctionProto;
-
-struct SQClosure : public CHAINABLE_OBJ
-{
-private:
- SQClosure(SQSharedState *ss,SQFunctionProto *func){_function=func; INIT_CHAIN();ADD_TO_CHAIN(&_ss(this)->_gc_chain,this);}
-public:
- static SQClosure *Create(SQSharedState *ss,SQFunctionProto *func){
- SQClosure *nc=(SQClosure*)SQ_MALLOC(sizeof(SQClosure));
- new (nc) SQClosure(ss,func);
- return nc;
- }
- void Release(){
- sq_delete(this,SQClosure);
- }
- SQClosure *Clone()
- {
- SQClosure * ret = SQClosure::Create(_opt_ss(this),_funcproto(_function));
- ret->_env = _env;
- ret->_outervalues.copy(_outervalues);
- return ret;
- }
- ~SQClosure()
- {
- REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain,this);
- }
- bool Save(SQVM *v,SQUserPointer up,SQWRITEFUNC write);
- static bool Load(SQVM *v,SQUserPointer up,SQREADFUNC read,SQObjectPtr &ret);
-#ifndef NO_GARBAGE_COLLECTOR
- void Mark(SQCollectable **chain);
- void Finalize(){_outervalues.resize(0); }
-#endif
- SQObjectPtr _env;
- SQObjectPtr _function;
- SQObjectPtrVec _outervalues;
-};
-//////////////////////////////////////////////
-struct SQGenerator : public CHAINABLE_OBJ
-{
- enum SQGeneratorState{eRunning,eSuspended,eDead};
-private:
- SQGenerator(SQSharedState *ss,SQClosure *closure){_closure=closure;_state=eRunning;_ci._generator=_null_;INIT_CHAIN();ADD_TO_CHAIN(&_ss(this)->_gc_chain,this);}
-public:
- static SQGenerator *Create(SQSharedState *ss,SQClosure *closure){
- SQGenerator *nc=(SQGenerator*)SQ_MALLOC(sizeof(SQGenerator));
- new (nc) SQGenerator(ss,closure);
- return nc;
- }
- ~SQGenerator()
- {
- REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain,this);
- }
- void Kill(){
- _state=eDead;
- _stack.resize(0);
- _closure=_null_;}
- void Release(){
- sq_delete(this,SQGenerator);
- }
- bool Yield(SQVM *v);
- bool Resume(SQVM *v,SQInteger target);
-#ifndef NO_GARBAGE_COLLECTOR
- void Mark(SQCollectable **chain);
- void Finalize(){_stack.resize(0);_closure=_null_;}
-#endif
- SQObjectPtr _closure;
- SQObjectPtrVec _stack;
- SQObjectPtrVec _vargsstack;
- SQVM::CallInfo _ci;
- ExceptionsTraps _etraps;
- SQGeneratorState _state;
-};
-
-struct SQNativeClosure : public CHAINABLE_OBJ
-{
-private:
- SQNativeClosure(SQSharedState *ss,SQFUNCTION func){_function=func;INIT_CHAIN();ADD_TO_CHAIN(&_ss(this)->_gc_chain,this); }
-public:
- static SQNativeClosure *Create(SQSharedState *ss,SQFUNCTION func)
- {
- SQNativeClosure *nc=(SQNativeClosure*)SQ_MALLOC(sizeof(SQNativeClosure));
- new (nc) SQNativeClosure(ss,func);
- return nc;
- }
- SQNativeClosure *Clone()
- {
- SQNativeClosure * ret = SQNativeClosure::Create(_opt_ss(this),_function);
- ret->_env = _env;
- ret->_name = _name;
- ret->_outervalues.copy(_outervalues);
- ret->_typecheck.copy(_typecheck);
- ret->_nparamscheck = _nparamscheck;
- return ret;
- }
- ~SQNativeClosure()
- {
- REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain,this);
- }
- void Release(){
- sq_delete(this,SQNativeClosure);
- }
-#ifndef NO_GARBAGE_COLLECTOR
- void Mark(SQCollectable **chain);
- void Finalize(){_outervalues.resize(0);}
-#endif
- SQInteger _nparamscheck;
- SQIntVec _typecheck;
- SQObjectPtrVec _outervalues;
- SQObjectPtr _env;
- SQFUNCTION _function;
- SQObjectPtr _name;
-};
-
-
-
-#endif //_SQCLOSURE_H_
+++ /dev/null
-/*
- see copyright notice in squirrel.h
-*/
-#include "sqpcheader.h"
-#include <stdarg.h>
-#include <setjmp.h>
-#include "sqopcodes.h"
-#include "sqstring.h"
-#include "sqfuncproto.h"
-#include "sqcompiler.h"
-#include "sqfuncstate.h"
-#include "sqlexer.h"
-#include "sqvm.h"
-
-#define DEREF_NO_DEREF -1
-#define DEREF_FIELD -2
-
-struct ExpState
-{
- ExpState()
- {
- _deref = DEREF_NO_DEREF;
- _freevar = false;
- _class_or_delete = false;
- _funcarg = false;
- }
- bool _class_or_delete;
- bool _funcarg;
- bool _freevar;
- SQInteger _deref;
-};
-
-typedef sqvector<ExpState> ExpStateVec;
-
-#define _exst (_expstates.top())
-
-#define BEGIN_BREAKBLE_BLOCK() SQInteger __nbreaks__=_fs->_unresolvedbreaks.size(); \
- SQInteger __ncontinues__=_fs->_unresolvedcontinues.size(); \
- _fs->_breaktargets.push_back(0);_fs->_continuetargets.push_back(0);
-
-#define END_BREAKBLE_BLOCK(continue_target) {__nbreaks__=_fs->_unresolvedbreaks.size()-__nbreaks__; \
- __ncontinues__=_fs->_unresolvedcontinues.size()-__ncontinues__; \
- if(__ncontinues__>0)ResolveContinues(_fs,__ncontinues__,continue_target); \
- if(__nbreaks__>0)ResolveBreaks(_fs,__nbreaks__); \
- _fs->_breaktargets.pop_back();_fs->_continuetargets.pop_back();}
-
-class SQCompiler
-{
-public:
- SQCompiler(SQVM *v, SQLEXREADFUNC rg, SQUserPointer up, const SQChar* sourcename, bool raiseerror, bool lineinfo)
- {
- _vm=v;
- _lex.Init(_ss(v), rg, up,ThrowError,this);
- _sourcename = SQString::Create(_ss(v), sourcename);
- _lineinfo = lineinfo;_raiseerror = raiseerror;
- compilererror = NULL;
- }
- static void ThrowError(void *ud, const SQChar *s) {
- SQCompiler *c = (SQCompiler *)ud;
- c->Error(s);
- }
- void Error(const SQChar *s, ...)
- {
- static SQChar temp[256];
- va_list vl;
- va_start(vl, s);
- scvsprintf(temp, s, vl);
- va_end(vl);
- compilererror = temp;
- longjmp(_errorjmp,1);
- }
- void Lex(){ _token = _lex.Lex();}
- void PushExpState(){ _expstates.push_back(ExpState()); }
- bool IsDerefToken(SQInteger tok)
- {
- switch(tok){
- case _SC('='): case _SC('('): case TK_NEWSLOT:
- case TK_MODEQ: case TK_MULEQ: case TK_DIVEQ: case TK_MINUSEQ: case TK_PLUSEQ: case TK_PLUSPLUS: case TK_MINUSMINUS: return true;
- }
- return false;
- }
- ExpState PopExpState()
- {
- ExpState ret = _expstates.top();
- _expstates.pop_back();
- return ret;
- }
- SQObject Expect(SQInteger tok)
- {
-
- if(_token != tok) {
- if(_token == TK_CONSTRUCTOR && tok == TK_IDENTIFIER) {
- //ret = SQString::Create(_ss(_vm),_SC("constructor"));
- //do nothing
- }
- else {
- const SQChar *etypename;
- if(tok > 255) {
- switch(tok)
- {
- case TK_IDENTIFIER:
- etypename = _SC("IDENTIFIER");
- break;
- case TK_STRING_LITERAL:
- etypename = _SC("STRING_LITERAL");
- break;
- case TK_INTEGER:
- etypename = _SC("INTEGER");
- break;
- case TK_FLOAT:
- etypename = _SC("FLOAT");
- break;
- default:
- etypename = _lex.Tok2Str(tok);
- }
- Error(_SC("expected '%s'"), etypename);
- }
- Error(_SC("expected '%c'"), tok);
- }
- }
- SQObjectPtr ret;
- switch(tok)
- {
- case TK_IDENTIFIER:
- ret = _fs->CreateString(_lex._svalue);
- break;
- case TK_STRING_LITERAL:
- ret = _fs->CreateString(_lex._svalue,_lex._longstr.size()-1);
- break;
- case TK_INTEGER:
- ret = SQObjectPtr(_lex._nvalue);
- break;
- case TK_FLOAT:
- ret = SQObjectPtr(_lex._fvalue);
- break;
- }
- Lex();
- return ret;
- }
- bool IsEndOfStatement() { return ((_lex._prevtoken == _SC('\n')) || (_token == SQUIRREL_EOB) || (_token == _SC('}')) || (_token == _SC(';'))); }
- void OptionalSemicolon()
- {
- if(_token == _SC(';')) { Lex(); return; }
- if(!IsEndOfStatement()) {
- Error(_SC("end of statement expected (; or lf)"));
- }
- }
- void MoveIfCurrentTargetIsLocal() {
- SQInteger trg = _fs->TopTarget();
- if(_fs->IsLocal(trg)) {
- trg = _fs->PopTarget(); //no pops the target and move it
- _fs->AddInstruction(_OP_MOVE, _fs->PushTarget(), trg);
- }
- }
- bool Compile(SQObjectPtr &o)
- {
- _debugline = 1;
- _debugop = 0;
-
- SQFuncState funcstate(_ss(_vm), NULL,ThrowError,this);
- funcstate._name = SQString::Create(_ss(_vm), _SC("main"));
- _fs = &funcstate;
- _fs->AddParameter(_fs->CreateString(_SC("this")));
- _fs->_sourcename = _sourcename;
- SQInteger stacksize = _fs->GetStackSize();
- if(setjmp(_errorjmp) == 0) {
- Lex();
- while(_token > 0){
- Statement();
- if(_lex._prevtoken != _SC('}')) OptionalSemicolon();
- }
- CleanStack(stacksize);
- _fs->AddLineInfos(_lex._currentline, _lineinfo, true);
- _fs->AddInstruction(_OP_RETURN, 0xFF);
- _fs->SetStackSize(0);
- o =_fs->BuildProto();
-#ifdef _DEBUG_DUMP
- _fs->Dump(_funcproto(o));
-#endif
- }
- else {
- if(_raiseerror && _ss(_vm)->_compilererrorhandler) {
- _ss(_vm)->_compilererrorhandler(_vm, compilererror, type(_sourcename) == OT_STRING?_stringval(_sourcename):_SC("unknown"),
- _lex._currentline, _lex._currentcolumn);
- }
- _vm->_lasterror = SQString::Create(_ss(_vm), compilererror, -1);
- return false;
- }
- return true;
- }
- void Statements()
- {
- while(_token != _SC('}') && _token != TK_DEFAULT && _token != TK_CASE) {
- Statement();
- if(_lex._prevtoken != _SC('}') && _lex._prevtoken != _SC(';')) OptionalSemicolon();
- }
- }
- void Statement()
- {
- _fs->AddLineInfos(_lex._currentline, _lineinfo);
- switch(_token){
- case _SC(';'): Lex(); break;
- case TK_IF: IfStatement(); break;
- case TK_WHILE: WhileStatement(); break;
- case TK_DO: DoWhileStatement(); break;
- case TK_FOR: ForStatement(); break;
- case TK_FOREACH: ForEachStatement(); break;
- case TK_SWITCH: SwitchStatement(); break;
- case TK_LOCAL: LocalDeclStatement(); break;
- case TK_RETURN:
- case TK_YIELD: {
- SQOpcode op;
- if(_token == TK_RETURN) {
- op = _OP_RETURN;
-
- }
- else {
- op = _OP_YIELD;
- _fs->_bgenerator = true;
- }
- Lex();
- if(!IsEndOfStatement()) {
- SQInteger retexp = _fs->GetCurrentPos()+1;
- CommaExpr();
- if(op == _OP_RETURN && _fs->_traps > 0)
- _fs->AddInstruction(_OP_POPTRAP, _fs->_traps, 0);
- _fs->_returnexp = retexp;
- _fs->AddInstruction(op, 1, _fs->PopTarget());
- }
- else{
- if(op == _OP_RETURN && _fs->_traps > 0)
- _fs->AddInstruction(_OP_POPTRAP, _fs->_traps ,0);
- _fs->_returnexp = -1;
- _fs->AddInstruction(op, 0xFF);
- }
- break;}
- case TK_BREAK:
- if(_fs->_breaktargets.size() <= 0)Error(_SC("'break' has to be in a loop block"));
- if(_fs->_breaktargets.top() > 0){
- _fs->AddInstruction(_OP_POPTRAP, _fs->_breaktargets.top(), 0);
- }
- _fs->AddInstruction(_OP_JMP, 0, -1234);
- _fs->_unresolvedbreaks.push_back(_fs->GetCurrentPos());
- Lex();
- break;
- case TK_CONTINUE:
- if(_fs->_continuetargets.size() <= 0)Error(_SC("'continue' has to be in a loop block"));
- if(_fs->_continuetargets.top() > 0) {
- _fs->AddInstruction(_OP_POPTRAP, _fs->_continuetargets.top(), 0);
- }
- _fs->AddInstruction(_OP_JMP, 0, -1234);
- _fs->_unresolvedcontinues.push_back(_fs->GetCurrentPos());
- Lex();
- break;
- case TK_FUNCTION:
- FunctionStatement();
- break;
- case TK_CLASS:
- ClassStatement();
- break;
- case _SC('{'):{
- SQInteger stacksize = _fs->GetStackSize();
- Lex();
- Statements();
- Expect(_SC('}'));
- _fs->SetStackSize(stacksize);
- }
- break;
- case TK_TRY:
- TryCatchStatement();
- break;
- case TK_THROW:
- Lex();
- CommaExpr();
- _fs->AddInstruction(_OP_THROW, _fs->PopTarget());
- break;
- default:
- CommaExpr();
- _fs->PopTarget();
- break;
- }
- _fs->SnoozeOpt();
- }
- void EmitDerefOp(SQOpcode op)
- {
- SQInteger val = _fs->PopTarget();
- SQInteger key = _fs->PopTarget();
- SQInteger src = _fs->PopTarget();
- _fs->AddInstruction(op,_fs->PushTarget(),src,key,val);
- }
- void Emit2ArgsOP(SQOpcode op, SQInteger p3 = 0)
- {
- SQInteger p2 = _fs->PopTarget(); //src in OP_GET
- SQInteger p1 = _fs->PopTarget(); //key in OP_GET
- _fs->AddInstruction(op,_fs->PushTarget(), p1, p2, p3);
- }
- void EmitCompoundArith(SQInteger tok,bool deref)
- {
- SQInteger oper;
- switch(tok){
- case TK_MINUSEQ: oper = '-'; break;
- case TK_PLUSEQ: oper = '+'; break;
- case TK_MULEQ: oper = '*'; break;
- case TK_DIVEQ: oper = '/'; break;
- case TK_MODEQ: oper = '%'; break;
- default: oper = 0; //shut up compiler
- assert(0); break;
- };
- if(deref) {
- SQInteger val = _fs->PopTarget();
- SQInteger key = _fs->PopTarget();
- SQInteger src = _fs->PopTarget();
- //mixes dest obj and source val in the arg1(hack?)
- _fs->AddInstruction(_OP_COMPARITH,_fs->PushTarget(),(src<<16)|val,key,oper);
- }
- else {
- Emit2ArgsOP(_OP_COMPARITHL, oper);
- }
- }
- void CommaExpr()
- {
- for(Expression();_token == ',';_fs->PopTarget(), Lex(), CommaExpr());
- }
- ExpState Expression(bool funcarg = false)
- {
- PushExpState();
- _exst._class_or_delete = false;
- _exst._funcarg = funcarg;
- LogicalOrExp();
- switch(_token) {
- case _SC('='):
- case TK_NEWSLOT:
- case TK_MINUSEQ:
- case TK_PLUSEQ:
- case TK_MULEQ:
- case TK_DIVEQ:
- case TK_MODEQ:
- {
- SQInteger op = _token;
- SQInteger ds = _exst._deref;
- bool freevar = _exst._freevar;
- if(ds == DEREF_NO_DEREF) Error(_SC("can't assign expression"));
- Lex(); Expression();
-
- switch(op){
- case TK_NEWSLOT:
- if(freevar) Error(_SC("free variables cannot be modified"));
- if(ds == DEREF_FIELD)
- EmitDerefOp(_OP_NEWSLOT);
- else //if _derefstate != DEREF_NO_DEREF && DEREF_FIELD so is the index of a local
- Error(_SC("can't 'create' a local slot"));
- break;
- case _SC('='): //ASSIGN
- if(freevar) Error(_SC("free variables cannot be modified"));
- if(ds == DEREF_FIELD)
- EmitDerefOp(_OP_SET);
- else {//if _derefstate != DEREF_NO_DEREF && DEREF_FIELD so is the index of a local
- SQInteger p2 = _fs->PopTarget(); //src in OP_GET
- SQInteger p1 = _fs->TopTarget(); //key in OP_GET
- _fs->AddInstruction(_OP_MOVE, p1, p2);
- }
- break;
- case TK_MINUSEQ:
- case TK_PLUSEQ:
- case TK_MULEQ:
- case TK_DIVEQ:
- case TK_MODEQ:
- EmitCompoundArith(op,ds == DEREF_FIELD);
- break;
- }
- }
- break;
- case _SC('?'): {
- Lex();
- _fs->AddInstruction(_OP_JZ, _fs->PopTarget());
- SQInteger jzpos = _fs->GetCurrentPos();
- SQInteger trg = _fs->PushTarget();
- Expression();
- SQInteger first_exp = _fs->PopTarget();
- if(trg != first_exp) _fs->AddInstruction(_OP_MOVE, trg, first_exp);
- SQInteger endfirstexp = _fs->GetCurrentPos();
- _fs->AddInstruction(_OP_JMP, 0, 0);
- Expect(_SC(':'));
- SQInteger jmppos = _fs->GetCurrentPos();
- Expression();
- SQInteger second_exp = _fs->PopTarget();
- if(trg != second_exp) _fs->AddInstruction(_OP_MOVE, trg, second_exp);
- _fs->SetIntructionParam(jmppos, 1, _fs->GetCurrentPos() - jmppos);
- _fs->SetIntructionParam(jzpos, 1, endfirstexp - jzpos + 1);
- _fs->SnoozeOpt();
- }
- break;
- }
- return PopExpState();
- }
- void BIN_EXP(SQOpcode op, void (SQCompiler::*f)(void),SQInteger op3 = 0)
- {
- Lex(); (this->*f)();
- SQInteger op1 = _fs->PopTarget();SQInteger op2 = _fs->PopTarget();
- _fs->AddInstruction(op, _fs->PushTarget(), op1, op2, op3);
- }
- void LogicalOrExp()
- {
- LogicalAndExp();
- for(;;) if(_token == TK_OR) {
- SQInteger first_exp = _fs->PopTarget();
- SQInteger trg = _fs->PushTarget();
- _fs->AddInstruction(_OP_OR, trg, 0, first_exp, 0);
- SQInteger jpos = _fs->GetCurrentPos();
- if(trg != first_exp) _fs->AddInstruction(_OP_MOVE, trg, first_exp);
- Lex(); LogicalOrExp();
- _fs->SnoozeOpt();
- SQInteger second_exp = _fs->PopTarget();
- if(trg != second_exp) _fs->AddInstruction(_OP_MOVE, trg, second_exp);
- _fs->SnoozeOpt();
- _fs->SetIntructionParam(jpos, 1, (_fs->GetCurrentPos() - jpos));
- break;
- }else return;
- }
- void LogicalAndExp()
- {
- BitwiseOrExp();
- for(;;) switch(_token) {
- case TK_AND: {
- SQInteger first_exp = _fs->PopTarget();
- SQInteger trg = _fs->PushTarget();
- _fs->AddInstruction(_OP_AND, trg, 0, first_exp, 0);
- SQInteger jpos = _fs->GetCurrentPos();
- if(trg != first_exp) _fs->AddInstruction(_OP_MOVE, trg, first_exp);
- Lex(); LogicalAndExp();
- _fs->SnoozeOpt();
- SQInteger second_exp = _fs->PopTarget();
- if(trg != second_exp) _fs->AddInstruction(_OP_MOVE, trg, second_exp);
- _fs->SnoozeOpt();
- _fs->SetIntructionParam(jpos, 1, (_fs->GetCurrentPos() - jpos));
- break;
- }
- case TK_IN: BIN_EXP(_OP_EXISTS, &SQCompiler::BitwiseOrExp); break;
- case TK_INSTANCEOF: BIN_EXP(_OP_INSTANCEOF, &SQCompiler::BitwiseOrExp); break;
- default:
- return;
- }
- }
- void BitwiseOrExp()
- {
- BitwiseXorExp();
- for(;;) if(_token == _SC('|'))
- {BIN_EXP(_OP_BITW, &SQCompiler::BitwiseXorExp,BW_OR);
- }else return;
- }
- void BitwiseXorExp()
- {
- BitwiseAndExp();
- for(;;) if(_token == _SC('^'))
- {BIN_EXP(_OP_BITW, &SQCompiler::BitwiseAndExp,BW_XOR);
- }else return;
- }
- void BitwiseAndExp()
- {
- CompExp();
- for(;;) if(_token == _SC('&'))
- {BIN_EXP(_OP_BITW, &SQCompiler::CompExp,BW_AND);
- }else return;
- }
- void CompExp()
- {
- ShiftExp();
- for(;;) switch(_token) {
- case TK_EQ: BIN_EXP(_OP_EQ, &SQCompiler::ShiftExp); break;
- case _SC('>'): BIN_EXP(_OP_CMP, &SQCompiler::ShiftExp,CMP_G); break;
- case _SC('<'): BIN_EXP(_OP_CMP, &SQCompiler::ShiftExp,CMP_L); break;
- case TK_GE: BIN_EXP(_OP_CMP, &SQCompiler::ShiftExp,CMP_GE); break;
- case TK_LE: BIN_EXP(_OP_CMP, &SQCompiler::ShiftExp,CMP_LE); break;
- case TK_NE: BIN_EXP(_OP_NE, &SQCompiler::ShiftExp); break;
- default: return;
- }
- }
- void ShiftExp()
- {
- PlusExp();
- for(;;) switch(_token) {
- case TK_USHIFTR: BIN_EXP(_OP_BITW, &SQCompiler::PlusExp,BW_USHIFTR); break;
- case TK_SHIFTL: BIN_EXP(_OP_BITW, &SQCompiler::PlusExp,BW_SHIFTL); break;
- case TK_SHIFTR: BIN_EXP(_OP_BITW, &SQCompiler::PlusExp,BW_SHIFTR); break;
- default: return;
- }
- }
- void PlusExp()
- {
- MultExp();
- for(;;) switch(_token) {
- case _SC('+'): case _SC('-'):
- BIN_EXP(_OP_ARITH, &SQCompiler::MultExp,_token); break;
- default: return;
- }
- }
-
- void MultExp()
- {
- PrefixedExpr();
- for(;;) switch(_token) {
- case _SC('*'): case _SC('/'): case _SC('%'):
- BIN_EXP(_OP_ARITH, &SQCompiler::PrefixedExpr,_token); break;
- default: return;
- }
- }
- //if 'pos' != -1 the previous variable is a local variable
- void PrefixedExpr()
- {
- SQInteger pos = Factor();
- for(;;) {
- switch(_token) {
- case _SC('.'): {
- pos = -1;
- Lex();
- if(_token == TK_PARENT) {
- Lex();
- if(!NeedGet())
- Error(_SC("parent cannot be set"));
- SQInteger src = _fs->PopTarget();
- _fs->AddInstruction(_OP_GETPARENT, _fs->PushTarget(), src);
- }
- else {
- _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetConstant(Expect(TK_IDENTIFIER)));
- if(NeedGet()) Emit2ArgsOP(_OP_GET);
- }
- _exst._deref = DEREF_FIELD;
- _exst._freevar = false;
- }
- break;
- case _SC('['):
- if(_lex._prevtoken == _SC('\n')) Error(_SC("cannot brake deref/or comma needed after [exp]=exp slot declaration"));
- Lex(); Expression(); Expect(_SC(']'));
- pos = -1;
- if(NeedGet()) Emit2ArgsOP(_OP_GET);
- _exst._deref = DEREF_FIELD;
- _exst._freevar = false;
- break;
- case TK_MINUSMINUS:
- case TK_PLUSPLUS:
- if(_exst._deref != DEREF_NO_DEREF && !IsEndOfStatement()) {
- SQInteger tok = _token; Lex();
- if(pos < 0)
- Emit2ArgsOP(_OP_PINC,tok == TK_MINUSMINUS?-1:1);
- else {//if _derefstate != DEREF_NO_DEREF && DEREF_FIELD so is the index of a local
- SQInteger src = _fs->PopTarget();
- _fs->AddInstruction(_OP_PINCL, _fs->PushTarget(), src, 0, tok == TK_MINUSMINUS?-1:1);
- }
-
- }
- return;
- break;
- case _SC('('):
- {
- if(_exst._deref != DEREF_NO_DEREF) {
- if(pos<0) {
- SQInteger key = _fs->PopTarget(); //key
- SQInteger table = _fs->PopTarget(); //table etc...
- SQInteger closure = _fs->PushTarget();
- SQInteger ttarget = _fs->PushTarget();
- _fs->AddInstruction(_OP_PREPCALL, closure, key, table, ttarget);
- }
- else{
- _fs->AddInstruction(_OP_MOVE, _fs->PushTarget(), 0);
- }
- }
- else
- _fs->AddInstruction(_OP_MOVE, _fs->PushTarget(), 0);
- _exst._deref = DEREF_NO_DEREF;
- Lex();
- FunctionCallArgs();
- }
- break;
- default: return;
- }
- }
- }
- SQInteger Factor()
- {
- switch(_token)
- {
- case TK_STRING_LITERAL: {
- //SQObjectPtr id(SQString::Create(_ss(_vm), _lex._svalue,_lex._longstr.size()-1));
- _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetConstant(_fs->CreateString(_lex._svalue,_lex._longstr.size()-1)));
- Lex();
- }
- break;
- case TK_VARGC: Lex(); _fs->AddInstruction(_OP_VARGC, _fs->PushTarget()); break;
- case TK_VARGV: { Lex();
- Expect(_SC('['));
- Expression();
- Expect(_SC(']'));
- SQInteger src = _fs->PopTarget();
- _fs->AddInstruction(_OP_GETVARGV, _fs->PushTarget(), src);
- }
- break;
- case TK_IDENTIFIER:
- case TK_CONSTRUCTOR:
- case TK_THIS:{
- _exst._freevar = false;
- SQObject id;
- switch(_token) {
- case TK_IDENTIFIER: id = _fs->CreateString(_lex._svalue); break;
- case TK_THIS: id = _fs->CreateString(_SC("this")); break;
- case TK_CONSTRUCTOR: id = _fs->CreateString(_SC("constructor")); break;
- }
- SQInteger pos = -1;
- Lex();
- if((pos = _fs->GetLocalVariable(id)) == -1) {
- //checks if is a free variable
- if((pos = _fs->GetOuterVariable(id)) != -1) {
- _exst._deref = _fs->PushTarget();
- _fs->AddInstruction(_OP_LOADFREEVAR, _exst._deref ,pos);
- _exst._freevar = true;
- } else {
- _fs->PushTarget(0);
- _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetConstant(id));
- if(NeedGet()) Emit2ArgsOP(_OP_GET);
- _exst._deref = DEREF_FIELD;
- }
- }
- else{
- _fs->PushTarget(pos);
- _exst._deref = pos;
- }
- return _exst._deref;
- }
- break;
- case TK_PARENT: Lex();_fs->AddInstruction(_OP_GETPARENT, _fs->PushTarget(), 0); break;
- case TK_DOUBLE_COLON: // "::"
- _fs->AddInstruction(_OP_LOADROOTTABLE, _fs->PushTarget());
- _exst._deref = DEREF_FIELD;
- _token = _SC('.'); //hack
- return -1;
- break;
- case TK_NULL:
- _fs->AddInstruction(_OP_LOADNULLS, _fs->PushTarget(),1);
- Lex();
- break;
- case TK_INTEGER: {
- if((_lex._nvalue & (~0x7FFFFFFF)) == 0) { //does it fit in 32 bits?
- _fs->AddInstruction(_OP_LOADINT, _fs->PushTarget(),_lex._nvalue);
- }
- else {
- _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetNumericConstant(_lex._nvalue));
- }
- Lex();
- }
- break;
- case TK_FLOAT:
- if(sizeof(SQFloat) == sizeof(SQInt32)) {
- _fs->AddInstruction(_OP_LOADFLOAT, _fs->PushTarget(),*((SQInt32 *)&_lex._fvalue));
- }
- else {
- _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetNumericConstant(_lex._fvalue));
- }
- Lex();
- break;
- case TK_TRUE: case TK_FALSE:
- _fs->AddInstruction(_OP_LOADBOOL, _fs->PushTarget(),_token == TK_TRUE?1:0);
- Lex();
- break;
- case _SC('['): {
- _fs->AddInstruction(_OP_NEWARRAY, _fs->PushTarget());
- SQInteger apos = _fs->GetCurrentPos(),key = 0;
- Lex();
- while(_token != _SC(']')) {
- Expression();
- if(_token == _SC(',')) Lex();
- SQInteger val = _fs->PopTarget();
- SQInteger array = _fs->TopTarget();
- _fs->AddInstruction(_OP_APPENDARRAY, array, val);
- key++;
- }
- _fs->SetIntructionParam(apos, 1, key);
- Lex();
- }
- break;
- case _SC('{'):{
- _fs->AddInstruction(_OP_NEWTABLE, _fs->PushTarget());
- Lex();ParseTableOrClass(_SC(','));
- }
- break;
- case TK_FUNCTION: FunctionExp(_token);break;
- case TK_CLASS: Lex(); ClassExp();break;
- case _SC('-'): UnaryOP(_OP_NEG); break;
- case _SC('!'): UnaryOP(_OP_NOT); break;
- case _SC('~'): UnaryOP(_OP_BWNOT); break;
- case TK_TYPEOF : UnaryOP(_OP_TYPEOF); break;
- case TK_RESUME : UnaryOP(_OP_RESUME); break;
- case TK_CLONE : UnaryOP(_OP_CLONE); break;
- case TK_MINUSMINUS :
- case TK_PLUSPLUS :PrefixIncDec(_token); break;
- case TK_DELETE : DeleteExpr(); break;
- case TK_DELEGATE : DelegateExpr(); break;
- case _SC('('): Lex(); CommaExpr(); Expect(_SC(')'));
- break;
- default: Error(_SC("expression expected"));
- }
- return -1;
- }
- void UnaryOP(SQOpcode op)
- {
- Lex(); PrefixedExpr();
- SQInteger src = _fs->PopTarget();
- _fs->AddInstruction(op, _fs->PushTarget(), src);
- }
- bool NeedGet()
- {
- switch(_token) {
- case _SC('='): case _SC('('): case TK_NEWSLOT: case TK_PLUSPLUS: case TK_MINUSMINUS:
- case TK_PLUSEQ: case TK_MINUSEQ: case TK_MULEQ: case TK_DIVEQ: case TK_MODEQ:
- return false;
- }
- return (!_exst._class_or_delete) || (_exst._class_or_delete && (_token == _SC('.') || _token == _SC('[')));
- }
-
- void FunctionCallArgs()
- {
- SQInteger nargs = 1;//this
- while(_token != _SC(')')) {
- Expression(true);
- MoveIfCurrentTargetIsLocal();
- nargs++;
- if(_token == _SC(',')){
- Lex();
- if(_token == ')') Error(_SC("expression expected, found ')'"));
- }
- }
- Lex();
- for(SQInteger i = 0; i < (nargs - 1); i++) _fs->PopTarget();
- SQInteger stackbase = _fs->PopTarget();
- SQInteger closure = _fs->PopTarget();
- _fs->AddInstruction(_OP_CALL, _fs->PushTarget(), closure, stackbase, nargs);
- }
- void ParseTableOrClass(SQInteger separator,SQInteger terminator = '}')
- {
- SQInteger tpos = _fs->GetCurrentPos(),nkeys = 0;
-
- while(_token != terminator) {
- bool hasattrs = false;
- bool isstatic = false;
- //check if is an attribute
- if(separator == ';') {
- if(_token == TK_ATTR_OPEN) {
- _fs->AddInstruction(_OP_NEWTABLE, _fs->PushTarget()); Lex();
- ParseTableOrClass(',',TK_ATTR_CLOSE);
- hasattrs = true;
- }
- if(_token == TK_STATIC) {
- isstatic = true;
- Lex();
- }
- }
- switch(_token) {
- case TK_FUNCTION:
- case TK_CONSTRUCTOR:{
- SQInteger tk = _token;
- Lex();
- SQObject id = tk == TK_FUNCTION ? Expect(TK_IDENTIFIER) : _fs->CreateString(_SC("constructor"));
- Expect(_SC('('));
- _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetConstant(id));
- CreateFunction(id);
- _fs->AddInstruction(_OP_CLOSURE, _fs->PushTarget(), _fs->_functions.size() - 1, 0);
- }
- break;
- case _SC('['):
- Lex(); CommaExpr(); Expect(_SC(']'));
- Expect(_SC('=')); Expression();
- break;
- default :
- _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetConstant(Expect(TK_IDENTIFIER)));
- Expect(_SC('=')); Expression();
- }
-
- if(_token == separator) Lex();//optional comma/semicolon
- nkeys++;
- SQInteger val = _fs->PopTarget();
- SQInteger key = _fs->PopTarget();
- SQInteger attrs = hasattrs ? _fs->PopTarget():-1;
- assert(hasattrs && attrs == key-1 || !hasattrs);
- unsigned char flags = (hasattrs?NEW_SLOT_ATTRIBUTES_FLAG:0)|(isstatic?NEW_SLOT_STATIC_FLAG:0);
- SQInteger table = _fs->TopTarget(); //<<BECAUSE OF THIS NO COMMON EMIT FUNC IS POSSIBLE
- _fs->AddInstruction(_OP_NEWSLOTA, flags, table, key, val);
- //_fs->PopTarget();
- }
- if(separator == _SC(',')) //hack recognizes a table from the separator
- _fs->SetIntructionParam(tpos, 1, nkeys);
- Lex();
- }
- void LocalDeclStatement()
- {
- SQObject varname;
- do {
- Lex(); varname = Expect(TK_IDENTIFIER);
- if(_token == _SC('=')) {
- Lex(); Expression();
- SQInteger src = _fs->PopTarget();
- SQInteger dest = _fs->PushTarget();
- if(dest != src) _fs->AddInstruction(_OP_MOVE, dest, src);
- }
- else{
- _fs->AddInstruction(_OP_LOADNULLS, _fs->PushTarget(),1);
- }
- _fs->PopTarget();
- _fs->PushLocalVariable(varname);
-
- } while(_token == _SC(','));
- }
- void IfStatement()
- {
- SQInteger jmppos;
- bool haselse = false;
- Lex(); Expect(_SC('(')); CommaExpr(); Expect(_SC(')'));
- _fs->AddInstruction(_OP_JZ, _fs->PopTarget());
- SQInteger jnepos = _fs->GetCurrentPos();
- SQInteger stacksize = _fs->GetStackSize();
-
- Statement();
- //
- if(_token != _SC('}') && _token != TK_ELSE) OptionalSemicolon();
-
- CleanStack(stacksize);
- SQInteger endifblock = _fs->GetCurrentPos();
- if(_token == TK_ELSE){
- haselse = true;
- stacksize = _fs->GetStackSize();
- _fs->AddInstruction(_OP_JMP);
- jmppos = _fs->GetCurrentPos();
- Lex();
- Statement(); OptionalSemicolon();
- CleanStack(stacksize);
- _fs->SetIntructionParam(jmppos, 1, _fs->GetCurrentPos() - jmppos);
- }
- _fs->SetIntructionParam(jnepos, 1, endifblock - jnepos + (haselse?1:0));
- }
- void WhileStatement()
- {
- SQInteger jzpos, jmppos;
- SQInteger stacksize = _fs->GetStackSize();
- jmppos = _fs->GetCurrentPos();
- Lex(); Expect(_SC('(')); CommaExpr(); Expect(_SC(')'));
-
- BEGIN_BREAKBLE_BLOCK();
- _fs->AddInstruction(_OP_JZ, _fs->PopTarget());
- jzpos = _fs->GetCurrentPos();
- stacksize = _fs->GetStackSize();
-
- Statement();
-
- CleanStack(stacksize);
- _fs->AddInstruction(_OP_JMP, 0, jmppos - _fs->GetCurrentPos() - 1);
- _fs->SetIntructionParam(jzpos, 1, _fs->GetCurrentPos() - jzpos);
-
- END_BREAKBLE_BLOCK(jmppos);
- }
- void DoWhileStatement()
- {
- Lex();
- SQInteger jzpos = _fs->GetCurrentPos();
- SQInteger stacksize = _fs->GetStackSize();
- BEGIN_BREAKBLE_BLOCK()
- Statement();
- CleanStack(stacksize);
- Expect(TK_WHILE);
- SQInteger continuetrg = _fs->GetCurrentPos();
- Expect(_SC('(')); CommaExpr(); Expect(_SC(')'));
- _fs->AddInstruction(_OP_JNZ, _fs->PopTarget(), jzpos - _fs->GetCurrentPos() - 1);
- END_BREAKBLE_BLOCK(continuetrg);
- }
- void ForStatement()
- {
- Lex();
- SQInteger stacksize = _fs->GetStackSize();
- Expect(_SC('('));
- if(_token == TK_LOCAL) LocalDeclStatement();
- else if(_token != _SC(';')){
- CommaExpr();
- _fs->PopTarget();
- }
- Expect(_SC(';'));
- _fs->SnoozeOpt();
- SQInteger jmppos = _fs->GetCurrentPos();
- SQInteger jzpos = -1;
- if(_token != _SC(';')) { CommaExpr(); _fs->AddInstruction(_OP_JZ, _fs->PopTarget()); jzpos = _fs->GetCurrentPos(); }
- Expect(_SC(';'));
- _fs->SnoozeOpt();
- SQInteger expstart = _fs->GetCurrentPos() + 1;
- if(_token != _SC(')')) {
- CommaExpr();
- _fs->PopTarget();
- }
- Expect(_SC(')'));
- _fs->SnoozeOpt();
- SQInteger expend = _fs->GetCurrentPos();
- SQInteger expsize = (expend - expstart) + 1;
- SQInstructionVec exp;
- if(expsize > 0) {
- for(SQInteger i = 0; i < expsize; i++)
- exp.push_back(_fs->GetInstruction(expstart + i));
- _fs->PopInstructions(expsize);
- }
- BEGIN_BREAKBLE_BLOCK()
- Statement();
- SQInteger continuetrg = _fs->GetCurrentPos();
- if(expsize > 0) {
- for(SQInteger i = 0; i < expsize; i++)
- _fs->AddInstruction(exp[i]);
- }
- _fs->AddInstruction(_OP_JMP, 0, jmppos - _fs->GetCurrentPos() - 1, 0);
- if(jzpos> 0) _fs->SetIntructionParam(jzpos, 1, _fs->GetCurrentPos() - jzpos);
- CleanStack(stacksize);
-
- END_BREAKBLE_BLOCK(continuetrg);
- }
- void ForEachStatement()
- {
- SQObject idxname, valname;
- Lex(); Expect(_SC('(')); valname = Expect(TK_IDENTIFIER);
- if(_token == _SC(',')) {
- idxname = valname;
- Lex(); valname = Expect(TK_IDENTIFIER);
- }
- else{
- idxname = _fs->CreateString(_SC("@INDEX@"));
- }
- Expect(TK_IN);
-
- //save the stack size
- SQInteger stacksize = _fs->GetStackSize();
- //put the table in the stack(evaluate the table expression)
- Expression(); Expect(_SC(')'));
- SQInteger container = _fs->TopTarget();
- //push the index local var
- SQInteger indexpos = _fs->PushLocalVariable(idxname);
- _fs->AddInstruction(_OP_LOADNULLS, indexpos,1);
- //push the value local var
- SQInteger valuepos = _fs->PushLocalVariable(valname);
- _fs->AddInstruction(_OP_LOADNULLS, valuepos,1);
- //push reference index
- SQInteger itrpos = _fs->PushLocalVariable(_fs->CreateString(_SC("@ITERATOR@"))); //use invalid id to make it inaccessible
- _fs->AddInstruction(_OP_LOADNULLS, itrpos,1);
- SQInteger jmppos = _fs->GetCurrentPos();
- _fs->AddInstruction(_OP_FOREACH, container, 0, indexpos);
- SQInteger foreachpos = _fs->GetCurrentPos();
- _fs->AddInstruction(_OP_POSTFOREACH, container, 0, indexpos);
- //generate the statement code
- BEGIN_BREAKBLE_BLOCK()
- Statement();
- _fs->AddInstruction(_OP_JMP, 0, jmppos - _fs->GetCurrentPos() - 1);
- _fs->SetIntructionParam(foreachpos, 1, _fs->GetCurrentPos() - foreachpos);
- _fs->SetIntructionParam(foreachpos + 1, 1, _fs->GetCurrentPos() - foreachpos);
- //restore the local variable stack(remove index,val and ref idx)
- CleanStack(stacksize);
- END_BREAKBLE_BLOCK(foreachpos - 1);
- }
- void SwitchStatement()
- {
- Lex(); Expect(_SC('(')); CommaExpr(); Expect(_SC(')'));
- Expect(_SC('{'));
- SQInteger expr = _fs->TopTarget();
- bool bfirst = true;
- SQInteger tonextcondjmp = -1;
- SQInteger skipcondjmp = -1;
- SQInteger __nbreaks__ = _fs->_unresolvedbreaks.size();
- _fs->_breaktargets.push_back(0);
- while(_token == TK_CASE) {
- //_fs->AddLineInfos(_lex._currentline, _lineinfo); think about this one
- if(!bfirst) {
- _fs->AddInstruction(_OP_JMP, 0, 0);
- skipcondjmp = _fs->GetCurrentPos();
- _fs->SetIntructionParam(tonextcondjmp, 1, _fs->GetCurrentPos() - tonextcondjmp);
- }
- //condition
- Lex(); Expression(); Expect(_SC(':'));
- SQInteger trg = _fs->PopTarget();
- _fs->AddInstruction(_OP_EQ, trg, trg, expr);
- _fs->AddInstruction(_OP_JZ, trg, 0);
- //end condition
- if(skipcondjmp != -1) {
- _fs->SetIntructionParam(skipcondjmp, 1, (_fs->GetCurrentPos() - skipcondjmp));
- }
- tonextcondjmp = _fs->GetCurrentPos();
- SQInteger stacksize = _fs->GetStackSize();
- Statements();
- _fs->SetStackSize(stacksize);
- bfirst = false;
- }
- if(tonextcondjmp != -1)
- _fs->SetIntructionParam(tonextcondjmp, 1, _fs->GetCurrentPos() - tonextcondjmp);
- if(_token == TK_DEFAULT) {
- // _fs->AddLineInfos(_lex._currentline, _lineinfo);
- Lex(); Expect(_SC(':'));
- SQInteger stacksize = _fs->GetStackSize();
- Statements();
- _fs->SetStackSize(stacksize);
- }
- Expect(_SC('}'));
- _fs->PopTarget();
- __nbreaks__ = _fs->_unresolvedbreaks.size() - __nbreaks__;
- if(__nbreaks__ > 0)ResolveBreaks(_fs, __nbreaks__);
- _fs->_breaktargets.pop_back();
-
- }
- void FunctionStatement()
- {
- SQObject id;
- Lex(); id = Expect(TK_IDENTIFIER);
- _fs->PushTarget(0);
- _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetConstant(id));
- if(_token == TK_DOUBLE_COLON) Emit2ArgsOP(_OP_GET);
-
- while(_token == TK_DOUBLE_COLON) {
- Lex();
- id = Expect(TK_IDENTIFIER);
- _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetConstant(id));
- if(_token == TK_DOUBLE_COLON) Emit2ArgsOP(_OP_GET);
- }
- Expect(_SC('('));
- CreateFunction(id);
- _fs->AddInstruction(_OP_CLOSURE, _fs->PushTarget(), _fs->_functions.size() - 1, 0);
- EmitDerefOp(_OP_NEWSLOT);
- _fs->PopTarget();
- }
- void ClassStatement()
- {
- ExpState es;
- Lex(); PushExpState();
- _exst._class_or_delete = true;
- _exst._funcarg = false;
- PrefixedExpr();
- es = PopExpState();
- if(es._deref == DEREF_NO_DEREF) Error(_SC("invalid class name"));
- if(es._deref == DEREF_FIELD) {
- ClassExp();
- EmitDerefOp(_OP_NEWSLOT);
- _fs->PopTarget();
- }
- else Error(_SC("cannot create a class in a local with the syntax(class <local>)"));
- }
- void TryCatchStatement()
- {
- SQObject exid;
- Lex();
- _fs->AddInstruction(_OP_PUSHTRAP,0,0);
- _fs->_traps++;
- if(_fs->_breaktargets.size()) _fs->_breaktargets.top()++;
- if(_fs->_continuetargets.size()) _fs->_continuetargets.top()++;
- SQInteger trappos = _fs->GetCurrentPos();
- Statement();
- _fs->_traps--;
- _fs->AddInstruction(_OP_POPTRAP, 1, 0);
- if(_fs->_breaktargets.size()) _fs->_breaktargets.top()--;
- if(_fs->_continuetargets.size()) _fs->_continuetargets.top()--;
- _fs->AddInstruction(_OP_JMP, 0, 0);
- SQInteger jmppos = _fs->GetCurrentPos();
- _fs->SetIntructionParam(trappos, 1, (_fs->GetCurrentPos() - trappos));
- Expect(TK_CATCH); Expect(_SC('(')); exid = Expect(TK_IDENTIFIER); Expect(_SC(')'));
- SQInteger stacksize = _fs->GetStackSize();
- SQInteger ex_target = _fs->PushLocalVariable(exid);
- _fs->SetIntructionParam(trappos, 0, ex_target);
- Statement();
- _fs->SetIntructionParams(jmppos, 0, (_fs->GetCurrentPos() - jmppos), 0);
- CleanStack(stacksize);
- }
- void FunctionExp(SQInteger ftype)
- {
- Lex(); Expect(_SC('('));
- CreateFunction(_null_);
- _fs->AddInstruction(_OP_CLOSURE, _fs->PushTarget(), _fs->_functions.size() - 1, ftype == TK_FUNCTION?0:1);
- }
- void ClassExp()
- {
- SQInteger base = -1;
- SQInteger attrs = -1;
- if(_token == TK_EXTENDS) {
- Lex(); Expression();
- base = _fs->TopTarget();
- }
- if(_token == TK_ATTR_OPEN) {
- Lex();
- _fs->AddInstruction(_OP_NEWTABLE, _fs->PushTarget());
- ParseTableOrClass(_SC(','),TK_ATTR_CLOSE);
- attrs = _fs->TopTarget();
- }
- Expect(_SC('{'));
- if(attrs != -1) _fs->PopTarget();
- if(base != -1) _fs->PopTarget();
- _fs->AddInstruction(_OP_CLASS, _fs->PushTarget(), base, attrs);
- ParseTableOrClass(_SC(';'));
- }
- void DelegateExpr()
- {
- Lex(); CommaExpr();
- Expect(_SC(':'));
- CommaExpr();
- SQInteger table = _fs->PopTarget(), delegate = _fs->PopTarget();
- _fs->AddInstruction(_OP_DELEGATE, _fs->PushTarget(), table, delegate);
- }
- void DeleteExpr()
- {
- ExpState es;
- Lex(); PushExpState();
- _exst._class_or_delete = true;
- _exst._funcarg = false;
- PrefixedExpr();
- es = PopExpState();
- if(es._deref == DEREF_NO_DEREF) Error(_SC("can't delete an expression"));
- if(es._deref == DEREF_FIELD) Emit2ArgsOP(_OP_DELETE);
- else Error(_SC("cannot delete a local"));
- }
- void PrefixIncDec(SQInteger token)
- {
- ExpState es;
- Lex(); PushExpState();
- _exst._class_or_delete = true;
- _exst._funcarg = false;
- PrefixedExpr();
- es = PopExpState();
- if(es._deref == DEREF_FIELD) Emit2ArgsOP(_OP_INC,token == TK_MINUSMINUS?-1:1);
- else {
- SQInteger src = _fs->PopTarget();
- _fs->AddInstruction(_OP_INCL, _fs->PushTarget(), src, 0, token == TK_MINUSMINUS?-1:1);
- }
- }
- void CreateFunction(SQObject &name)
- {
-
- SQFuncState *funcstate = _fs->PushChildState(_ss(_vm));
- funcstate->_name = name;
- SQObject paramname;
- funcstate->AddParameter(_fs->CreateString(_SC("this")));
- funcstate->_sourcename = _sourcename;
- while(_token!=_SC(')')) {
- if(_token == TK_VARPARAMS) {
- funcstate->_varparams = true;
- Lex();
- if(_token != _SC(')')) Error(_SC("expected ')'"));
- break;
- }
- else {
- paramname = Expect(TK_IDENTIFIER);
- funcstate->AddParameter(paramname);
- if(_token == _SC(',')) Lex();
- else if(_token != _SC(')')) Error(_SC("expected ')' or ','"));
- }
- }
- Expect(_SC(')'));
- //outer values
- if(_token == _SC(':')) {
- Lex(); Expect(_SC('('));
- while(_token != _SC(')')) {
- paramname = Expect(TK_IDENTIFIER);
- //outers are treated as implicit local variables
- funcstate->AddOuterValue(paramname);
- if(_token == _SC(',')) Lex();
- else if(_token != _SC(')')) Error(_SC("expected ')' or ','"));
- }
- Lex();
- }
-
- SQFuncState *currchunk = _fs;
- _fs = funcstate;
- Statement();
- funcstate->AddLineInfos(_lex._prevtoken == _SC('\n')?_lex._lasttokenline:_lex._currentline, _lineinfo, true);
- funcstate->AddInstruction(_OP_RETURN, -1);
- funcstate->SetStackSize(0);
- //_fs->->_stacksize = _fs->_stacksize;
- SQFunctionProto *func = funcstate->BuildProto();
-#ifdef _DEBUG_DUMP
- funcstate->Dump(func);
-#endif
- _fs = currchunk;
- _fs->_functions.push_back(func);
- _fs->PopChildState();
- }
- void CleanStack(SQInteger stacksize)
- {
- if(_fs->GetStackSize() != stacksize)
- _fs->SetStackSize(stacksize);
- }
- void ResolveBreaks(SQFuncState *funcstate, SQInteger ntoresolve)
- {
- while(ntoresolve > 0) {
- SQInteger pos = funcstate->_unresolvedbreaks.back();
- funcstate->_unresolvedbreaks.pop_back();
- //set the jmp instruction
- funcstate->SetIntructionParams(pos, 0, funcstate->GetCurrentPos() - pos, 0);
- ntoresolve--;
- }
- }
- void ResolveContinues(SQFuncState *funcstate, SQInteger ntoresolve, SQInteger targetpos)
- {
- while(ntoresolve > 0) {
- SQInteger pos = funcstate->_unresolvedcontinues.back();
- funcstate->_unresolvedcontinues.pop_back();
- //set the jmp instruction
- funcstate->SetIntructionParams(pos, 0, targetpos - pos, 0);
- ntoresolve--;
- }
- }
-private:
- SQInteger _token;
- SQFuncState *_fs;
- SQObjectPtr _sourcename;
- SQLexer _lex;
- bool _lineinfo;
- bool _raiseerror;
- SQInteger _debugline;
- SQInteger _debugop;
- ExpStateVec _expstates;
- SQChar *compilererror;
- jmp_buf _errorjmp;
- SQVM *_vm;
-};
-
-bool Compile(SQVM *vm,SQLEXREADFUNC rg, SQUserPointer up, const SQChar *sourcename, SQObjectPtr &out, bool raiseerror, bool lineinfo)
-{
- SQCompiler p(vm, rg, up, sourcename, raiseerror, lineinfo);
- return p.Compile(out);
-}
+++ /dev/null
-/* see copyright notice in squirrel.h */
-#ifndef _SQCOMPILER_H_
-#define _SQCOMPILER_H_
-
-struct SQVM;
-
-#define TK_IDENTIFIER 258
-#define TK_STRING_LITERAL 259
-#define TK_INTEGER 260
-#define TK_FLOAT 261
-#define TK_DELEGATE 262
-#define TK_DELETE 263
-#define TK_EQ 264
-#define TK_NE 265
-#define TK_LE 266
-#define TK_GE 267
-#define TK_SWITCH 268
-#define TK_ARROW 269
-#define TK_AND 270
-#define TK_OR 271
-#define TK_IF 272
-#define TK_ELSE 273
-#define TK_WHILE 274
-#define TK_BREAK 275
-#define TK_FOR 276
-#define TK_DO 277
-#define TK_NULL 278
-#define TK_FOREACH 279
-#define TK_IN 280
-#define TK_NEWSLOT 281
-#define TK_MODULO 282
-#define TK_LOCAL 283
-#define TK_CLONE 284
-#define TK_FUNCTION 285
-#define TK_RETURN 286
-#define TK_TYPEOF 287
-#define TK_UMINUS 288
-#define TK_PLUSEQ 289
-#define TK_MINUSEQ 290
-#define TK_CONTINUE 291
-#define TK_YIELD 292
-#define TK_TRY 293
-#define TK_CATCH 294
-#define TK_THROW 295
-#define TK_SHIFTL 296
-#define TK_SHIFTR 297
-#define TK_RESUME 298
-#define TK_DOUBLE_COLON 299
-#define TK_CASE 300
-#define TK_DEFAULT 301
-#define TK_THIS 302
-#define TK_PLUSPLUS 303
-#define TK_MINUSMINUS 304
-#define TK_PARENT 305
-#define TK_USHIFTR 306
-#define TK_CLASS 307
-#define TK_EXTENDS 308
-#define TK_CONSTRUCTOR 310
-#define TK_INSTANCEOF 311
-#define TK_VARPARAMS 312
-#define TK_VARGC 313
-#define TK_VARGV 314
-#define TK_TRUE 315
-#define TK_FALSE 316
-#define TK_MULEQ 317
-#define TK_DIVEQ 318
-#define TK_MODEQ 319
-#define TK_ATTR_OPEN 320
-#define TK_ATTR_CLOSE 321
-#define TK_STATIC 322
-
-
-typedef void(*CompilerErrorFunc)(void *ud, const SQChar *s);
-bool Compile(SQVM *vm, SQLEXREADFUNC rg, SQUserPointer up, const SQChar *sourcename, SQObjectPtr &out, bool raiseerror, bool lineinfo);
-#endif //_SQCOMPILER_H_
+++ /dev/null
-/*
- see copyright notice in squirrel.h
-*/
-#include "sqpcheader.h"
-#include <stdarg.h>
-#include "sqvm.h"
-#include "sqfuncproto.h"
-#include "sqclosure.h"
-#include "sqstring.h"
-
-SQRESULT sq_stackinfos(HSQUIRRELVM v, SQInteger level, SQStackInfos *si)
-{
- SQInteger cssize = v->_callsstacksize;
- if (cssize > level) {
- memset(si, 0, sizeof(SQStackInfos));
- SQVM::CallInfo &ci = v->_callsstack[cssize-level-1];
- switch (type(ci._closure)) {
- case OT_CLOSURE:{
- SQFunctionProto *func = _funcproto(_closure(ci._closure)->_function);
- if (type(func->_name) == OT_STRING)
- si->funcname = _stringval(func->_name);
- if (type(func->_sourcename) == OT_STRING)
- si->source = _stringval(func->_sourcename);
- si->line = func->GetLine(ci._ip);
- }
- break;
- case OT_NATIVECLOSURE:
- si->source = _SC("NATIVE");
- si->funcname = _SC("unknown");
- if(type(_nativeclosure(ci._closure)->_name) == OT_STRING)
- si->funcname = _stringval(_nativeclosure(ci._closure)->_name);
- si->line = -1;
- break;
- default: break; //shutup compiler
- }
- return SQ_OK;
- }
- return SQ_ERROR;
-}
-
-void SQVM::Raise_Error(const SQChar *s, ...)
-{
- va_list vl;
- va_start(vl, s);
- scvsprintf(_sp(rsl((SQInteger)scstrlen(s)+(NUMBER_MAX_CHAR*2))), s, vl);
- va_end(vl);
- _lasterror = SQString::Create(_ss(this),_spval,-1);
-}
-
-void SQVM::Raise_Error(SQObjectPtr &desc)
-{
- _lasterror = desc;
-}
-
-SQString *SQVM::PrintObjVal(const SQObject &o)
-{
- switch(type(o)) {
- case OT_STRING: return _string(o);
- case OT_INTEGER:
- scsprintf(_sp(rsl(NUMBER_MAX_CHAR+1)), _SC("%d"), _integer(o));
- return SQString::Create(_ss(this), _spval);
- break;
- case OT_FLOAT:
- scsprintf(_sp(rsl(NUMBER_MAX_CHAR+1)), _SC("%.14g"), _float(o));
- return SQString::Create(_ss(this), _spval);
- break;
- default:
- return SQString::Create(_ss(this), GetTypeName(o));
- }
-}
-
-void SQVM::Raise_IdxError(SQObject &o)
-{
- SQObjectPtr oval = PrintObjVal(o);
- Raise_Error(_SC("the index '%.50s' does not exist"), _stringval(oval));
-}
-
-void SQVM::Raise_CompareError(const SQObject &o1, const SQObject &o2)
-{
- SQObjectPtr oval1 = PrintObjVal(o1), oval2 = PrintObjVal(o2);
- Raise_Error(_SC("comparsion between '%.50s' and '%.50s'"), _stringval(oval1), _stringval(oval2));
-}
-
-
-void SQVM::Raise_ParamTypeError(SQInteger nparam,SQInteger typemask,SQInteger type)
-{
- SQObjectPtr exptypes = SQString::Create(_ss(this), _SC(""), -1);
- SQInteger found = 0;
- for(SQInteger i=0; i<16; i++)
- {
- SQInteger mask = 0x00000001 << i;
- if(typemask & (mask)) {
- if(found>0) StringCat(exptypes,SQString::Create(_ss(this), _SC("|"), -1), exptypes);
- found ++;
- StringCat(exptypes,SQString::Create(_ss(this), IdType2Name((SQObjectType)mask), -1), exptypes);
- }
- }
- Raise_Error(_SC("parameter %d has an invalid type '%s' ; expected: '%s'"), nparam, IdType2Name((SQObjectType)type), _stringval(exptypes));
-}
+++ /dev/null
-/* see copyright notice in squirrel.h */
-#ifndef _SQFUNCTION_H_
-#define _SQFUNCTION_H_
-
-#include "sqopcodes.h"
-
-enum SQOuterType {
- otLOCAL = 0,
- otSYMBOL = 1,
- otOUTER = 2
-};
-
-struct SQOuterVar
-{
-
- SQOuterVar(){}
- SQOuterVar(const SQObjectPtr &name,const SQObjectPtr &src,SQOuterType t)
- {
- _name = name;
- _src=src;
- _type=t;
- }
- SQOuterVar(const SQOuterVar &ov)
- {
- _type=ov._type;
- _src=ov._src;
- _name=ov._name;
- }
- SQOuterType _type;
- SQObjectPtr _name;
- SQObjectPtr _src;
-};
-
-struct SQLocalVarInfo
-{
- SQLocalVarInfo():_start_op(0),_end_op(0){}
- SQLocalVarInfo(const SQLocalVarInfo &lvi)
- {
- _name=lvi._name;
- _start_op=lvi._start_op;
- _end_op=lvi._end_op;
- _pos=lvi._pos;
- }
- SQObjectPtr _name;
- SQUnsignedInteger _start_op;
- SQUnsignedInteger _end_op;
- SQUnsignedInteger _pos;
-};
-
-struct SQLineInfo { SQInteger _line;SQInteger _op; };
-
-typedef sqvector<SQOuterVar> SQOuterVarVec;
-typedef sqvector<SQLocalVarInfo> SQLocalVarInfoVec;
-typedef sqvector<SQLineInfo> SQLineInfoVec;
-
-#define _FUNC_SIZE(ni,nl,nparams,nfuncs,nouters,nlineinf,localinf) (sizeof(SQFunctionProto) \
- +((ni-1)*sizeof(SQInstruction))+(nl*sizeof(SQObjectPtr)) \
- +(nparams*sizeof(SQObjectPtr))+(nfuncs*sizeof(SQObjectPtr)) \
- +(nouters*sizeof(SQOuterVar))+(nlineinf*sizeof(SQLineInfo)) \
- +(localinf*sizeof(SQLocalVarInfo)))
-
-#define _CONSTRUCT_VECTOR(type,size,ptr) { \
- for(SQInteger n = 0; n < size; n++) { \
- new (&ptr[n]) type(); \
- } \
-}
-
-#define _DESTRUCT_VECTOR(type,size,ptr) { \
- for(SQInteger nl = 0; nl < size; nl++) { \
- ptr[nl].~type(); \
- } \
-}
-struct SQFunctionProto : public SQRefCounted
-{
-private:
- SQFunctionProto(){
- _stacksize=0;
- _bgenerator=false;}
-public:
- static SQFunctionProto *Create(SQInteger ninstructions,
- SQInteger nliterals,SQInteger nparameters,
- SQInteger nfunctions,SQInteger noutervalues,
- SQInteger nlineinfos,SQInteger nlocalvarinfos)
- {
- SQFunctionProto *f;
- //I compact the whole class and members in a single memory allocation
- f = (SQFunctionProto *)sq_vm_malloc(_FUNC_SIZE(ninstructions,nliterals,nparameters,nfunctions,noutervalues,nlineinfos,nlocalvarinfos));
- new (f) SQFunctionProto;
- f->_ninstructions = ninstructions;
- f->_literals = (SQObjectPtr*)&f->_instructions[ninstructions];
- f->_nliterals = nliterals;
- f->_parameters = (SQObjectPtr*)&f->_literals[nliterals];
- f->_nparameters = nparameters;
- f->_functions = (SQObjectPtr*)&f->_parameters[nparameters];
- f->_nfunctions = nfunctions;
- f->_outervalues = (SQOuterVar*)&f->_functions[nfunctions];
- f->_noutervalues = noutervalues;
- f->_lineinfos = (SQLineInfo *)&f->_outervalues[noutervalues];
- f->_nlineinfos = nlineinfos;
- f->_localvarinfos = (SQLocalVarInfo *)&f->_lineinfos[nlineinfos];
- f->_nlocalvarinfos = nlocalvarinfos;
-
- _CONSTRUCT_VECTOR(SQObjectPtr,f->_nliterals,f->_literals);
- _CONSTRUCT_VECTOR(SQObjectPtr,f->_nparameters,f->_parameters);
- _CONSTRUCT_VECTOR(SQObjectPtr,f->_nfunctions,f->_functions);
- _CONSTRUCT_VECTOR(SQOuterVar,f->_noutervalues,f->_outervalues);
- //_CONSTRUCT_VECTOR(SQLineInfo,f->_nlineinfos,f->_lineinfos); //not required are 2 integers
- _CONSTRUCT_VECTOR(SQLocalVarInfo,f->_nlocalvarinfos,f->_localvarinfos);
- return f;
- }
- void Release(){
- _DESTRUCT_VECTOR(SQObjectPtr,_nliterals,_literals);
- _DESTRUCT_VECTOR(SQObjectPtr,_nparameters,_parameters);
- _DESTRUCT_VECTOR(SQObjectPtr,_nfunctions,_functions);
- _DESTRUCT_VECTOR(SQOuterVar,_noutervalues,_outervalues);
- //_DESTRUCT_VECTOR(SQLineInfo,_nlineinfos,_lineinfos); //not required are 2 integers
- _DESTRUCT_VECTOR(SQLocalVarInfo,_nlocalvarinfos,_localvarinfos);
- SQInteger size = _FUNC_SIZE(_ninstructions,_nliterals,_nparameters,_nfunctions,_noutervalues,_nlineinfos,_nlocalvarinfos);
- this->~SQFunctionProto();
- sq_vm_free(this,size);
- }
- const SQChar* GetLocal(SQVM *v,SQUnsignedInteger stackbase,SQUnsignedInteger nseq,SQUnsignedInteger nop);
- SQInteger GetLine(SQInstruction *curr);
- bool Save(SQVM *v,SQUserPointer up,SQWRITEFUNC write);
- static bool Load(SQVM *v,SQUserPointer up,SQREADFUNC read,SQObjectPtr &ret);
-
- SQObjectPtr _sourcename;
- SQObjectPtr _name;
- SQInteger _stacksize;
- bool _bgenerator;
- bool _varparams;
-
- SQInteger _nlocalvarinfos;
- SQLocalVarInfo *_localvarinfos;
-
- SQInteger _nlineinfos;
- SQLineInfo *_lineinfos;
-
- SQInteger _nliterals;
- SQObjectPtr *_literals;
-
- SQInteger _nparameters;
- SQObjectPtr *_parameters;
-
- SQInteger _nfunctions;
- SQObjectPtr *_functions;
-
- SQInteger _noutervalues;
- SQOuterVar *_outervalues;
-
- SQInteger _ninstructions;
- SQInstruction _instructions[1];
-};
-
-#endif //_SQFUNCTION_H_
+++ /dev/null
-/*
- see copyright notice in squirrel.h
-*/
-#include "sqpcheader.h"
-#include "sqcompiler.h"
-#include "sqfuncproto.h"
-#include "sqstring.h"
-#include "sqtable.h"
-#include "sqopcodes.h"
-#include "sqfuncstate.h"
-
-#ifdef _DEBUG_DUMP
-SQInstructionDesc g_InstrDesc[]={
- {_SC("_OP_LINE")},
- {_SC("_OP_LOAD")},
- {_SC("_OP_LOADINT")},
- {_SC("_OP_LOADFLOAT")},
- {_SC("_OP_DLOAD")},
- {_SC("_OP_TAILCALL")},
- {_SC("_OP_CALL")},
- {_SC("_OP_PREPCALL")},
- {_SC("_OP_PREPCALLK")},
- {_SC("_OP_GETK")},
- {_SC("_OP_MOVE")},
- {_SC("_OP_NEWSLOT")},
- {_SC("_OP_DELETE")},
- {_SC("_OP_SET")},
- {_SC("_OP_GET")},
- {_SC("_OP_EQ")},
- {_SC("_OP_NE")},
- {_SC("_OP_ARITH")},
- {_SC("_OP_BITW")},
- {_SC("_OP_RETURN")},
- {_SC("_OP_LOADNULLS")},
- {_SC("_OP_LOADROOTTABLE")},
- {_SC("_OP_LOADBOOL")},
- {_SC("_OP_DMOVE")},
- {_SC("_OP_JMP")},
- {_SC("_OP_JNZ")},
- {_SC("_OP_JZ")},
- {_SC("_OP_LOADFREEVAR")},
- {_SC("_OP_VARGC")},
- {_SC("_OP_GETVARGV")},
- {_SC("_OP_NEWTABLE")},
- {_SC("_OP_NEWARRAY")},
- {_SC("_OP_APPENDARRAY")},
- {_SC("_OP_GETPARENT")},
- {_SC("_OP_COMPARITH")},
- {_SC("_OP_COMPARITHL")},
- {_SC("_OP_INC")},
- {_SC("_OP_INCL")},
- {_SC("_OP_PINC")},
- {_SC("_OP_PINCL")},
- {_SC("_OP_CMP")},
- {_SC("_OP_EXISTS")},
- {_SC("_OP_INSTANCEOF")},
- {_SC("_OP_AND")},
- {_SC("_OP_OR")},
- {_SC("_OP_NEG")},
- {_SC("_OP_NOT")},
- {_SC("_OP_BWNOT")},
- {_SC("_OP_CLOSURE")},
- {_SC("_OP_YIELD")},
- {_SC("_OP_RESUME")},
- {_SC("_OP_FOREACH")},
- {_SC("_OP_POSTFOREACH")},
- {_SC("_OP_DELEGATE")},
- {_SC("_OP_CLONE")},
- {_SC("_OP_TYPEOF")},
- {_SC("_OP_PUSHTRAP")},
- {_SC("_OP_POPTRAP")},
- {_SC("_OP_THROW")},
- {_SC("_OP_CLASS")},
- {_SC("_OP_NEWSLOTA")}
-};
-#endif
-void DumpLiteral(SQObjectPtr &o)
-{
- switch(type(o)){
- case OT_STRING: scprintf(_SC("\"%s\""),_stringval(o));break;
- case OT_FLOAT: scprintf(_SC("{%f}"),_float(o));break;
- case OT_INTEGER: scprintf(_SC("{%d}"),_integer(o));break;
- default: assert(0); break; //shut up compiler
- }
-}
-
-SQFuncState::SQFuncState(SQSharedState *ss,SQFuncState *parent,CompilerErrorFunc efunc,void *ed)
-{
- _nliterals = 0;
- _literals = SQTable::Create(ss,0);
- _strings = SQTable::Create(ss,0);
- _sharedstate = ss;
- _lastline = 0;
- _optimization = true;
- _parent = parent;
- _stacksize = 0;
- _traps = 0;
- _returnexp = 0;
- _varparams = false;
- _errfunc = efunc;
- _errtarget = ed;
- _bgenerator = false;
-
-}
-
-void SQFuncState::Error(const SQChar *err)
-{
- _errfunc(_errtarget,err);
-}
-
-#ifdef _DEBUG_DUMP
-void SQFuncState::Dump(SQFunctionProto *func)
-{
- SQUnsignedInteger n=0,i;
- SQInteger si;
- scprintf(_SC("SQInstruction sizeof %d\n"),sizeof(SQInstruction));
- scprintf(_SC("SQObject sizeof %d\n"),sizeof(SQObject));
- scprintf(_SC("--------------------------------------------------------------------\n"));
- scprintf(_SC("*****FUNCTION [%s]\n"),type(func->_name)==OT_STRING?_stringval(func->_name):_SC("unknown"));
- scprintf(_SC("-----LITERALS\n"));
- SQObjectPtr refidx,key,val;
- SQInteger idx;
- SQObjectPtrVec templiterals;
- templiterals.resize(_nliterals);
- while((idx=_table(_literals)->Next(false,refidx,key,val))!=-1) {
- refidx=idx;
- templiterals[_integer(val)]=key;
- }
- for(i=0;i<templiterals.size();i++){
- scprintf(_SC("[%d] "),n);
- DumpLiteral(templiterals[i]);
- scprintf(_SC("\n"));
- n++;
- }
- scprintf(_SC("-----PARAMS\n"));
- if(_varparams)
- scprintf(_SC("<<VARPARAMS>>\n"));
- n=0;
- for(i=0;i<_parameters.size();i++){
- scprintf(_SC("[%d] "),n);
- DumpLiteral(_parameters[i]);
- scprintf(_SC("\n"));
- n++;
- }
- scprintf(_SC("-----LOCALS\n"));
- for(si=0;si<func->_nlocalvarinfos;si++){
- SQLocalVarInfo lvi=func->_localvarinfos[si];
- scprintf(_SC("[%d] %s \t%d %d\n"),lvi._pos,_stringval(lvi._name),lvi._start_op,lvi._end_op);
- n++;
- }
- scprintf(_SC("-----LINE INFO\n"));
- for(i=0;i<_lineinfos.size();i++){
- SQLineInfo li=_lineinfos[i];
- scprintf(_SC("op [%d] line [%d] \n"),li._op,li._line);
- n++;
- }
- scprintf(_SC("-----dump\n"));
- n=0;
- for(i=0;i<_instructions.size();i++){
- SQInstruction &inst=_instructions[i];
- if(inst.op==_OP_LOAD || inst.op==_OP_DLOAD || inst.op==_OP_PREPCALLK || inst.op==_OP_GETK ){
-
- SQInteger lidx = inst._arg1;
- scprintf(_SC("[%03d] %15s %d "),n,g_InstrDesc[inst.op].name,inst._arg0);
- if(lidx >= 0xFFFFFFFF)
- scprintf(_SC("null"));
- else {
- SQInteger refidx;
- SQObjectPtr val,key,refo;
- while(((refidx=_table(_literals)->Next(false,refo,key,val))!= -1) && (_integer(val) != lidx)) {
- refo = refidx;
- }
- DumpLiteral(key);
- }
- if(inst.op != _OP_DLOAD) {
- scprintf(_SC(" %d %d \n"),inst._arg2,inst._arg3);
- }
- else {
- scprintf(_SC(" %d "),inst._arg2);
- lidx = inst._arg3;
- if(lidx >= 0xFFFFFFFF)
- scprintf(_SC("null"));
- else {
- SQInteger refidx;
- SQObjectPtr val,key,refo;
- while(((refidx=_table(_literals)->Next(false,refo,key,val))!= -1) && (_integer(val) != lidx)) {
- refo = refidx;
- }
- DumpLiteral(key);
- scprintf(_SC("\n"));
- }
- }
- }
- else if(inst.op==_OP_LOADFLOAT) {
- scprintf(_SC("[%03d] %15s %d %f %d %d\n"),n,g_InstrDesc[inst.op].name,inst._arg0,*((SQFloat*)&inst._arg1),inst._arg2,inst._arg3);
- }
- else if(inst.op==_OP_ARITH){
- scprintf(_SC("[%03d] %15s %d %d %d %c\n"),n,g_InstrDesc[inst.op].name,inst._arg0,inst._arg1,inst._arg2,inst._arg3);
- }
- else
- scprintf(_SC("[%03d] %15s %d %d %d %d\n"),n,g_InstrDesc[inst.op].name,inst._arg0,inst._arg1,inst._arg2,inst._arg3);
- n++;
- }
- scprintf(_SC("-----\n"));
- scprintf(_SC("stack size[%d]\n"),func->_stacksize);
- scprintf(_SC("--------------------------------------------------------------------\n\n"));
-}
-#endif
-
-SQInteger SQFuncState::GetNumericConstant(const SQInteger cons)
-{
- return GetConstant(SQObjectPtr(cons));
-}
-
-SQInteger SQFuncState::GetNumericConstant(const SQFloat cons)
-{
- return GetConstant(SQObjectPtr(cons));
-}
-
-SQInteger SQFuncState::GetConstant(const SQObject &cons)
-{
- SQObjectPtr val;
- if(!_table(_literals)->Get(cons,val))
- {
- val = _nliterals;
- _table(_literals)->NewSlot(cons,val);
- _nliterals++;
- if(_nliterals > MAX_LITERALS) {
- val.Null();
- Error(_SC("internal compiler error: too many literals"));
- }
- }
- return _integer(val);
-}
-
-void SQFuncState::SetIntructionParams(SQInteger pos,SQInteger arg0,SQInteger arg1,SQInteger arg2,SQInteger arg3)
-{
- _instructions[pos]._arg0=(unsigned char)*((SQUnsignedInteger *)&arg0);
- _instructions[pos]._arg1=(SQInt32)*((SQUnsignedInteger *)&arg1);
- _instructions[pos]._arg2=(unsigned char)*((SQUnsignedInteger *)&arg2);
- _instructions[pos]._arg3=(unsigned char)*((SQUnsignedInteger *)&arg3);
-}
-
-void SQFuncState::SetIntructionParam(SQInteger pos,SQInteger arg,SQInteger val)
-{
- switch(arg){
- case 0:_instructions[pos]._arg0=(unsigned char)*((SQUnsignedInteger *)&val);break;
- case 1:case 4:_instructions[pos]._arg1=(SQInt32)*((SQUnsignedInteger *)&val);break;
- case 2:_instructions[pos]._arg2=(unsigned char)*((SQUnsignedInteger *)&val);break;
- case 3:_instructions[pos]._arg3=(unsigned char)*((SQUnsignedInteger *)&val);break;
- };
-}
-
-SQInteger SQFuncState::AllocStackPos()
-{
- SQInteger npos=_vlocals.size();
- _vlocals.push_back(SQLocalVarInfo());
- if(_vlocals.size()>((SQUnsignedInteger)_stacksize)) {
- if(_stacksize>MAX_FUNC_STACKSIZE) Error(_SC("internal compiler error: too many locals"));
- _stacksize=_vlocals.size();
- }
- return npos;
-}
-
-SQInteger SQFuncState::PushTarget(SQInteger n)
-{
- if(n!=-1){
- _targetstack.push_back(n);
- return n;
- }
- n=AllocStackPos();
- _targetstack.push_back(n);
- return n;
-}
-
-SQInteger SQFuncState::GetUpTarget(SQInteger n){
- return _targetstack[((_targetstack.size()-1)-n)];
-}
-
-SQInteger SQFuncState::TopTarget(){
- return _targetstack.back();
-}
-SQInteger SQFuncState::PopTarget()
-{
- SQInteger npos=_targetstack.back();
- SQLocalVarInfo t=_vlocals[_targetstack.back()];
- if(type(t._name)==OT_NULL){
- _vlocals.pop_back();
- }
- _targetstack.pop_back();
- return npos;
-}
-
-SQInteger SQFuncState::GetStackSize()
-{
- return _vlocals.size();
-}
-
-void SQFuncState::SetStackSize(SQInteger n)
-{
- SQInteger size=_vlocals.size();
- while(size>n){
- size--;
- SQLocalVarInfo lvi=_vlocals.back();
- if(type(lvi._name)!=OT_NULL){
- lvi._end_op=GetCurrentPos();
- _localvarinfos.push_back(lvi);
- }
- _vlocals.pop_back();
- }
-}
-
-bool SQFuncState::IsLocal(SQUnsignedInteger stkpos)
-{
- if(stkpos>=_vlocals.size())return false;
- else if(type(_vlocals[stkpos]._name)!=OT_NULL)return true;
- return false;
-}
-
-SQInteger SQFuncState::PushLocalVariable(const SQObject &name)
-{
- SQInteger pos=_vlocals.size();
- SQLocalVarInfo lvi;
- lvi._name=name;
- lvi._start_op=GetCurrentPos()+1;
- lvi._pos=_vlocals.size();
- _vlocals.push_back(lvi);
- if(_vlocals.size()>((SQUnsignedInteger)_stacksize))_stacksize=_vlocals.size();
-
- return pos;
-}
-
-SQInteger SQFuncState::GetLocalVariable(const SQObject &name)
-{
- SQInteger locals=_vlocals.size();
- while(locals>=1){
- if(type(_vlocals[locals-1]._name)==OT_STRING && _string(_vlocals[locals-1]._name)==_string(name)){
- return locals-1;
- }
- locals--;
- }
- return -1;
-}
-
-SQInteger SQFuncState::GetOuterVariable(const SQObject &name)
-{
- SQInteger outers = _outervalues.size();
- for(SQInteger i = 0; i<outers; i++) {
- if(_string(_outervalues[i]._name) == _string(name))
- return i;
- }
- return -1;
-}
-
-void SQFuncState::AddOuterValue(const SQObject &name)
-{
- SQInteger pos=-1;
- if(_parent) {
- pos = _parent->GetLocalVariable(name);
- if(pos == -1) {
- pos = _parent->GetOuterVariable(name);
- if(pos != -1) {
- _outervalues.push_back(SQOuterVar(name,SQObjectPtr(SQInteger(pos)),otOUTER)); //local
- return;
- }
- }
- else {
- _outervalues.push_back(SQOuterVar(name,SQObjectPtr(SQInteger(pos)),otLOCAL)); //local
- return;
- }
- }
- _outervalues.push_back(SQOuterVar(name,name,otSYMBOL)); //global
-}
-
-void SQFuncState::AddParameter(const SQObject &name)
-{
- PushLocalVariable(name);
- _parameters.push_back(name);
-}
-
-void SQFuncState::AddLineInfos(SQInteger line,bool lineop,bool force)
-{
- if(_lastline!=line || force){
- SQLineInfo li;
- li._line=line;li._op=(GetCurrentPos()+1);
- if(lineop)AddInstruction(_OP_LINE,0,line);
- _lineinfos.push_back(li);
- _lastline=line;
- }
-}
-
-void SQFuncState::AddInstruction(SQInstruction &i)
-{
- SQInteger size = _instructions.size();
- if(size > 0 && _optimization){ //simple optimizer
- SQInstruction &pi = _instructions[size-1];//previous instruction
- switch(i.op) {
- case _OP_RETURN:
- if( _parent && i._arg0 != MAX_FUNC_STACKSIZE && pi.op == _OP_CALL && _returnexp < size-1) {
- pi.op = _OP_TAILCALL;
- }
- break;
- case _OP_GET:
- if( pi.op == _OP_LOAD && pi._arg0 == i._arg2 && (!IsLocal(pi._arg0))){
- pi._arg1 = pi._arg1;
- pi._arg2 = (unsigned char)i._arg1;
- pi.op = _OP_GETK;
- pi._arg0 = i._arg0;
-
- return;
- }
- break;
- case _OP_PREPCALL:
- if( pi.op == _OP_LOAD && pi._arg0 == i._arg1 && (!IsLocal(pi._arg0))){
- pi.op = _OP_PREPCALLK;
- pi._arg0 = i._arg0;
- pi._arg1 = pi._arg1;
- pi._arg2 = i._arg2;
- pi._arg3 = i._arg3;
- return;
- }
- break;
- case _OP_APPENDARRAY:
- if(pi.op == _OP_LOAD && pi._arg0 == i._arg1 && (!IsLocal(pi._arg0))){
- pi.op = _OP_APPENDARRAY;
- pi._arg0 = i._arg0;
- pi._arg1 = pi._arg1;
- pi._arg2 = MAX_FUNC_STACKSIZE;
- pi._arg3 = MAX_FUNC_STACKSIZE;
- return;
- }
- break;
- case _OP_MOVE:
- if((pi.op == _OP_GET || pi.op == _OP_ARITH || pi.op == _OP_BITW) && (pi._arg0 == i._arg1))
- {
- pi._arg0 = i._arg0;
- _optimization = false;
- return;
- }
-
- if(pi.op == _OP_MOVE)
- {
- pi.op = _OP_DMOVE;
- pi._arg2 = i._arg0;
- pi._arg3 = (unsigned char)i._arg1;
- return;
- }
- break;
- case _OP_LOAD:
- if(pi.op == _OP_LOAD && i._arg1 < 256) {
- pi.op = _OP_DLOAD;
- pi._arg2 = i._arg0;
- pi._arg3 = (unsigned char)i._arg1;
- return;
- }
- break;
- case _OP_EQ:case _OP_NE:
- if(pi.op == _OP_LOAD && pi._arg0 == i._arg1 && (!IsLocal(pi._arg0) ))
- {
- pi.op = i.op;
- pi._arg0 = i._arg0;
- pi._arg1 = pi._arg1;
- pi._arg2 = i._arg2;
- pi._arg3 = MAX_FUNC_STACKSIZE;
- return;
- }
- break;
- case _OP_LOADNULLS:
- if((pi.op == _OP_LOADNULLS && pi._arg0+pi._arg1 == i._arg0)) {
-
- pi._arg1 = pi._arg1 + 1;
- pi.op = _OP_LOADNULLS;
- return;
- }
- break;
- case _OP_LINE:
- if(pi.op == _OP_LINE) {
- _instructions.pop_back();
- _lineinfos.pop_back();
- }
- break;
- }
- }
- _optimization = true;
- _instructions.push_back(i);
-}
-
-SQObject SQFuncState::CreateString(const SQChar *s,SQInteger len)
-{
- SQObjectPtr ns(SQString::Create(_sharedstate,s,len));
- _table(_strings)->NewSlot(ns,(SQInteger)1);
- return ns;
-}
-
-SQFunctionProto *SQFuncState::BuildProto()
-{
- SQFunctionProto *f=SQFunctionProto::Create(_instructions.size(),
- _nliterals,_parameters.size(),_functions.size(),_outervalues.size(),
- _lineinfos.size(),_localvarinfos.size());
-
- SQObjectPtr refidx,key,val;
- SQInteger idx;
-
- f->_stacksize = _stacksize;
- f->_sourcename = _sourcename;
- f->_bgenerator = _bgenerator;
- f->_name = _name;
-
- while((idx=_table(_literals)->Next(false,refidx,key,val))!=-1) {
- f->_literals[_integer(val)]=key;
- refidx=idx;
- }
-
- for(SQUnsignedInteger nf = 0; nf < _functions.size(); nf++) f->_functions[nf] = _functions[nf];
- for(SQUnsignedInteger np = 0; np < _parameters.size(); np++) f->_parameters[np] = _parameters[np];
- for(SQUnsignedInteger no = 0; no < _outervalues.size(); no++) f->_outervalues[no] = _outervalues[no];
- for(SQUnsignedInteger no = 0; no < _localvarinfos.size(); no++) f->_localvarinfos[no] = _localvarinfos[no];
- for(SQUnsignedInteger no = 0; no < _lineinfos.size(); no++) f->_lineinfos[no] = _lineinfos[no];
-
- memcpy(f->_instructions,&_instructions[0],_instructions.size()*sizeof(SQInstruction));
-
- f->_varparams = _varparams;
-
- return f;
-}
-
-SQFuncState *SQFuncState::PushChildState(SQSharedState *ss)
-{
- SQFuncState *child = (SQFuncState *)sq_malloc(sizeof(SQFuncState));
- new (child) SQFuncState(ss,this,_errfunc,_errtarget);
- _childstates.push_back(child);
- return child;
-}
-
-void SQFuncState::PopChildState()
-{
- SQFuncState *child = _childstates.back();
- sq_delete(child,SQFuncState);
- _childstates.pop_back();
-}
-
-SQFuncState::~SQFuncState()
-{
- while(_childstates.size() > 0)
- {
- PopChildState();
- }
-}
+++ /dev/null
-/* see copyright notice in squirrel.h */
-#ifndef _SQFUNCSTATE_H_
-#define _SQFUNCSTATE_H_
-///////////////////////////////////
-#include "squtils.h"
-
-struct SQFuncState
-{
- SQFuncState(SQSharedState *ss,SQFuncState *parent,CompilerErrorFunc efunc,void *ed);
- ~SQFuncState();
-#ifdef _DEBUG_DUMP
- void Dump(SQFunctionProto *func);
-#endif
- void Error(const SQChar *err);
- SQFuncState *PushChildState(SQSharedState *ss);
- void PopChildState();
- void AddInstruction(SQOpcode _op,SQInteger arg0=0,SQInteger arg1=0,SQInteger arg2=0,SQInteger arg3=0){SQInstruction i(_op,arg0,arg1,arg2,arg3);AddInstruction(i);}
- void AddInstruction(SQInstruction &i);
- void SetIntructionParams(SQInteger pos,SQInteger arg0,SQInteger arg1,SQInteger arg2=0,SQInteger arg3=0);
- void SetIntructionParam(SQInteger pos,SQInteger arg,SQInteger val);
- SQInstruction &GetInstruction(SQInteger pos){return _instructions[pos];}
- void PopInstructions(SQInteger size){for(SQInteger i=0;i<size;i++)_instructions.pop_back();}
- void SetStackSize(SQInteger n);
- void SnoozeOpt(){_optimization=false;}
- SQInteger GetCurrentPos(){return _instructions.size()-1;}
- SQInteger GetNumericConstant(const SQInteger cons);
- SQInteger GetNumericConstant(const SQFloat cons);
- SQInteger PushLocalVariable(const SQObject &name);
- void AddParameter(const SQObject &name);
- void AddOuterValue(const SQObject &name);
- SQInteger GetLocalVariable(const SQObject &name);
- SQInteger GetOuterVariable(const SQObject &name);
- SQInteger GenerateCode();
- SQInteger GetStackSize();
- SQInteger CalcStackFrameSize();
- void AddLineInfos(SQInteger line,bool lineop,bool force=false);
- SQFunctionProto *BuildProto();
- SQInteger AllocStackPos();
- SQInteger PushTarget(SQInteger n=-1);
- SQInteger PopTarget();
- SQInteger TopTarget();
- SQInteger GetUpTarget(SQInteger n);
- bool IsLocal(SQUnsignedInteger stkpos);
- SQObject CreateString(const SQChar *s,SQInteger len = -1);
- SQInteger _returnexp;
- SQLocalVarInfoVec _vlocals;
- SQIntVec _targetstack;
- SQInteger _stacksize;
- bool _varparams;
- bool _bgenerator;
- SQIntVec _unresolvedbreaks;
- SQIntVec _unresolvedcontinues;
- SQObjectPtrVec _functions;
- SQObjectPtrVec _parameters;
- SQOuterVarVec _outervalues;
- SQInstructionVec _instructions;
- SQLocalVarInfoVec _localvarinfos;
- SQObjectPtr _literals;
- SQObjectPtr _strings;
- SQObjectPtr _name;
- SQObjectPtr _sourcename;
- SQInteger _nliterals;
- SQLineInfoVec _lineinfos;
- SQFuncState *_parent;
- SQIntVec _breaktargets;
- SQIntVec _continuetargets;
- SQInteger _lastline;
- SQInteger _traps; //contains number of nested exception traps
- bool _optimization;
- SQSharedState *_sharedstate;
- sqvector<SQFuncState*> _childstates;
- SQInteger GetConstant(const SQObject &cons);
-private:
- CompilerErrorFunc _errfunc;
- void *_errtarget;
-};
-
-
-#endif //_SQFUNCSTATE_H_
-
+++ /dev/null
-/*
- see copyright notice in squirrel.h
-*/
-#include "sqpcheader.h"
-#include <ctype.h>
-#include <stdlib.h>
-#include "sqtable.h"
-#include "sqstring.h"
-#include "sqcompiler.h"
-#include "sqlexer.h"
-
-#define CUR_CHAR (_currdata)
-#define RETURN_TOKEN(t) { _prevtoken = _curtoken; _curtoken = t; return t;}
-#define IS_EOB() (CUR_CHAR <= SQUIRREL_EOB)
-#define NEXT() {Next();_currentcolumn++;}
-#define INIT_TEMP_STRING() { _longstr.resize(0);}
-#define APPEND_CHAR(c) { _longstr.push_back(c);}
-#define TERMINATE_BUFFER() {_longstr.push_back(_SC('\0'));}
-#define ADD_KEYWORD(key,id) _keywords->NewSlot( SQString::Create(ss, _SC(#key)) ,SQInteger(id))
-
-SQLexer::SQLexer(){}
-SQLexer::~SQLexer()
-{
- _keywords->Release();
-}
-
-void SQLexer::Init(SQSharedState *ss, SQLEXREADFUNC rg, SQUserPointer up,CompilerErrorFunc efunc,void *ed)
-{
- _errfunc = efunc;
- _errtarget = ed;
- _sharedstate = ss;
- _keywords = SQTable::Create(ss, 26);
- ADD_KEYWORD(while, TK_WHILE);
- ADD_KEYWORD(do, TK_DO);
- ADD_KEYWORD(if, TK_IF);
- ADD_KEYWORD(else, TK_ELSE);
- ADD_KEYWORD(break, TK_BREAK);
- ADD_KEYWORD(continue, TK_CONTINUE);
- ADD_KEYWORD(return, TK_RETURN);
- ADD_KEYWORD(null, TK_NULL);
- ADD_KEYWORD(function, TK_FUNCTION);
- ADD_KEYWORD(local, TK_LOCAL);
- ADD_KEYWORD(for, TK_FOR);
- ADD_KEYWORD(foreach, TK_FOREACH);
- ADD_KEYWORD(in, TK_IN);
- ADD_KEYWORD(typeof, TK_TYPEOF);
- ADD_KEYWORD(delegate, TK_DELEGATE);
- ADD_KEYWORD(delete, TK_DELETE);
- ADD_KEYWORD(try, TK_TRY);
- ADD_KEYWORD(catch, TK_CATCH);
- ADD_KEYWORD(throw, TK_THROW);
- ADD_KEYWORD(clone, TK_CLONE);
- ADD_KEYWORD(yield, TK_YIELD);
- ADD_KEYWORD(resume, TK_RESUME);
- ADD_KEYWORD(switch, TK_SWITCH);
- ADD_KEYWORD(case, TK_CASE);
- ADD_KEYWORD(default, TK_DEFAULT);
- ADD_KEYWORD(this, TK_THIS);
- ADD_KEYWORD(parent,TK_PARENT);
- ADD_KEYWORD(class,TK_CLASS);
- ADD_KEYWORD(extends,TK_EXTENDS);
- ADD_KEYWORD(constructor,TK_CONSTRUCTOR);
- ADD_KEYWORD(instanceof,TK_INSTANCEOF);
- ADD_KEYWORD(vargc,TK_VARGC);
- ADD_KEYWORD(vargv,TK_VARGV);
- ADD_KEYWORD(true,TK_TRUE);
- ADD_KEYWORD(false,TK_FALSE);
- ADD_KEYWORD(static,TK_STATIC);
-
- _readf = rg;
- _up = up;
- _lasttokenline = _currentline = 1;
- _currentcolumn = 0;
- _prevtoken = -1;
- Next();
-}
-
-void SQLexer::Error(const SQChar *err)
-{
- _errfunc(_errtarget,err);
-}
-
-void SQLexer::Next()
-{
- SQInteger t = _readf(_up);
- if(t > MAX_CHAR) Error(_SC("Invalid character"));
- if(t != 0) {
- _currdata = (LexChar)t;
- return;
- }
- _currdata = SQUIRREL_EOB;
-}
-
-const SQChar *SQLexer::Tok2Str(SQInteger tok)
-{
- SQObjectPtr itr, key, val;
- SQInteger nitr;
- while((nitr = _keywords->Next(false,itr, key, val)) != -1) {
- itr = (SQInteger)nitr;
- if(((SQInteger)_integer(val)) == tok)
- return _stringval(key);
- }
- return NULL;
-}
-
-void SQLexer::LexBlockComment()
-{
- bool done = false;
- while(!done) {
- switch(CUR_CHAR) {
- case _SC('*'): { NEXT(); if(CUR_CHAR == _SC('/')) { done = true; NEXT(); }}; continue;
- case _SC('\n'): _currentline++; NEXT(); continue;
- case SQUIRREL_EOB: Error(_SC("missing \"*/\" in comment"));
- default: NEXT();
- }
- }
-}
-
-SQInteger SQLexer::Lex()
-{
- _lasttokenline = _currentline;
- while(CUR_CHAR != SQUIRREL_EOB) {
- switch(CUR_CHAR){
- case _SC('\t'): case _SC('\r'): case _SC(' '): NEXT(); continue;
- case _SC('\n'):
- _currentline++;
- _prevtoken=_curtoken;
- _curtoken=_SC('\n');
- NEXT();
- _currentcolumn=1;
- continue;
- case _SC('/'):
- NEXT();
- switch(CUR_CHAR){
- case _SC('*'):
- NEXT();
- LexBlockComment();
- continue;
- case _SC('/'):
- do { NEXT(); } while (CUR_CHAR != _SC('\n') && (!IS_EOB()));
- continue;
- case _SC('='):
- NEXT();
- RETURN_TOKEN(TK_DIVEQ);
- continue;
- case _SC('>'):
- NEXT();
- RETURN_TOKEN(TK_ATTR_CLOSE);
- continue;
- default:
- RETURN_TOKEN('/');
- }
- case _SC('='):
- NEXT();
- if (CUR_CHAR != _SC('=')){ RETURN_TOKEN('=') }
- else { NEXT(); RETURN_TOKEN(TK_EQ); }
- case _SC('<'):
- NEXT();
- if ( CUR_CHAR == _SC('=') ) { NEXT(); RETURN_TOKEN(TK_LE) }
- else if ( CUR_CHAR == _SC('-') ) { NEXT(); RETURN_TOKEN(TK_NEWSLOT); }
- else if ( CUR_CHAR == _SC('<') ) { NEXT(); RETURN_TOKEN(TK_SHIFTL); }
- else if ( CUR_CHAR == _SC('/') ) { NEXT(); RETURN_TOKEN(TK_ATTR_OPEN); }
- //else if ( CUR_CHAR == _SC('[') ) { NEXT(); ReadMultilineString(); RETURN_TOKEN(TK_STRING_LITERAL); }
- else { RETURN_TOKEN('<') }
- case _SC('>'):
- NEXT();
- if (CUR_CHAR == _SC('=')){ NEXT(); RETURN_TOKEN(TK_GE);}
- else if(CUR_CHAR == _SC('>')){
- NEXT();
- if(CUR_CHAR == _SC('>')){
- NEXT();
- RETURN_TOKEN(TK_USHIFTR);
- }
- RETURN_TOKEN(TK_SHIFTR);
- }
- else { RETURN_TOKEN('>') }
- case _SC('!'):
- NEXT();
- if (CUR_CHAR != _SC('=')){ RETURN_TOKEN('!')}
- else { NEXT(); RETURN_TOKEN(TK_NE); }
- case _SC('@'): {
- SQInteger stype;
- NEXT();
- if(CUR_CHAR != _SC('"'))
- Error(_SC("string expected"));
- if((stype=ReadString('"',true))!=-1) {
- RETURN_TOKEN(stype);
- }
- Error(_SC("error parsing the string"));
- }
- case _SC('"'):
- case _SC('\''): {
- SQInteger stype;
- if((stype=ReadString(CUR_CHAR,false))!=-1){
- RETURN_TOKEN(stype);
- }
- Error(_SC("error parsing the string"));
- }
- case _SC('{'): case _SC('}'): case _SC('('): case _SC(')'): case _SC('['): case _SC(']'):
- case _SC(';'): case _SC(','): case _SC('?'): case _SC('^'): case _SC('~'):
- {SQInteger ret = CUR_CHAR;
- NEXT(); RETURN_TOKEN(ret); }
- case _SC('.'):
- NEXT();
- if (CUR_CHAR != _SC('.')){ RETURN_TOKEN('.') }
- NEXT();
- if (CUR_CHAR != _SC('.')){ Error(_SC("invalid token '..'")); }
- NEXT();
- RETURN_TOKEN(TK_VARPARAMS);
- case _SC('&'):
- NEXT();
- if (CUR_CHAR != _SC('&')){ RETURN_TOKEN('&') }
- else { NEXT(); RETURN_TOKEN(TK_AND); }
- case _SC('|'):
- NEXT();
- if (CUR_CHAR != _SC('|')){ RETURN_TOKEN('|') }
- else { NEXT(); RETURN_TOKEN(TK_OR); }
- case _SC(':'):
- NEXT();
- if (CUR_CHAR != _SC(':')){ RETURN_TOKEN(':') }
- else { NEXT(); RETURN_TOKEN(TK_DOUBLE_COLON); }
- case _SC('*'):
- NEXT();
- if (CUR_CHAR == _SC('=')){ NEXT(); RETURN_TOKEN(TK_MULEQ);}
- else RETURN_TOKEN('*');
- case _SC('%'):
- NEXT();
- if (CUR_CHAR == _SC('=')){ NEXT(); RETURN_TOKEN(TK_MODEQ);}
- else RETURN_TOKEN('%');
- case _SC('-'):
- NEXT();
- if (CUR_CHAR == _SC('=')){ NEXT(); RETURN_TOKEN(TK_MINUSEQ);}
- else if (CUR_CHAR == _SC('-')){ NEXT(); RETURN_TOKEN(TK_MINUSMINUS);}
- else RETURN_TOKEN('-');
- case _SC('+'):
- NEXT();
- if (CUR_CHAR == _SC('=')){ NEXT(); RETURN_TOKEN(TK_PLUSEQ);}
- else if (CUR_CHAR == _SC('+')){ NEXT(); RETURN_TOKEN(TK_PLUSPLUS);}
- else RETURN_TOKEN('+');
- case SQUIRREL_EOB:
- return 0;
- default:{
- if (scisdigit(CUR_CHAR)) {
- SQInteger ret = ReadNumber();
- RETURN_TOKEN(ret);
- }
- else if (scisalpha(CUR_CHAR) || CUR_CHAR == _SC('_')) {
- SQInteger t = ReadID();
- RETURN_TOKEN(t);
- }
- else {
- SQInteger c = CUR_CHAR;
- if (sciscntrl((int)c)) Error(_SC("unexpected character(control)"));
- NEXT();
- RETURN_TOKEN(c);
- }
- RETURN_TOKEN(0);
- }
- }
- }
- return 0;
-}
-
-SQInteger SQLexer::GetIDType(SQChar *s)
-{
- SQObjectPtr t;
- if(_keywords->Get(SQString::Create(_sharedstate, s), t)) {
- return SQInteger(_integer(t));
- }
- return TK_IDENTIFIER;
-}
-
-
-SQInteger SQLexer::ReadString(SQInteger ndelim,bool verbatim)
-{
- INIT_TEMP_STRING();
- NEXT();
- if(IS_EOB()) return -1;
- for(;;) {
- while(CUR_CHAR != ndelim) {
- switch(CUR_CHAR) {
- case SQUIRREL_EOB:
- Error(_SC("unfinished string"));
- return -1;
- case _SC('\n'):
- if(!verbatim) Error(_SC("newline in a constant"));
- APPEND_CHAR(CUR_CHAR); NEXT();
- _currentline++;
- break;
- case _SC('\\'):
- if(verbatim) {
- APPEND_CHAR('\\'); NEXT();
- }
- else {
- NEXT();
- switch(CUR_CHAR) {
- case _SC('x'): NEXT(); {
- if(!isxdigit(CUR_CHAR)) Error(_SC("hexadecimal number expected"));
- const SQInteger maxdigits = 4;
- SQChar temp[maxdigits+1];
- SQInteger n = 0;
- while(isxdigit(CUR_CHAR) && n < maxdigits) {
- temp[n] = CUR_CHAR;
- n++;
- NEXT();
- }
- temp[n] = 0;
- SQChar *sTemp;
- APPEND_CHAR((SQChar)scstrtoul(temp,&sTemp,16));
- }
- break;
- case _SC('t'): APPEND_CHAR(_SC('\t')); NEXT(); break;
- case _SC('a'): APPEND_CHAR(_SC('\a')); NEXT(); break;
- case _SC('b'): APPEND_CHAR(_SC('\b')); NEXT(); break;
- case _SC('n'): APPEND_CHAR(_SC('\n')); NEXT(); break;
- case _SC('r'): APPEND_CHAR(_SC('\r')); NEXT(); break;
- case _SC('v'): APPEND_CHAR(_SC('\v')); NEXT(); break;
- case _SC('f'): APPEND_CHAR(_SC('\f')); NEXT(); break;
- case _SC('0'): APPEND_CHAR(_SC('\0')); NEXT(); break;
- case _SC('\\'): APPEND_CHAR(_SC('\\')); NEXT(); break;
- case _SC('"'): APPEND_CHAR(_SC('"')); NEXT(); break;
- case _SC('\''): APPEND_CHAR(_SC('\'')); NEXT(); break;
- default:
- Error(_SC("unrecognised escaper char"));
- break;
- }
- }
- break;
- default:
- APPEND_CHAR(CUR_CHAR);
- NEXT();
- }
- }
- NEXT();
- if(verbatim && CUR_CHAR == '"') { //double quotation
- APPEND_CHAR(CUR_CHAR);
- NEXT();
- }
- else {
- break;
- }
- }
- TERMINATE_BUFFER();
- SQInteger len = _longstr.size()-1;
- if(ndelim == _SC('\'')) {
- if(len == 0) Error(_SC("empty constant"));
- if(len > 1) Error(_SC("constant too long"));
- _nvalue = _longstr[0];
- return TK_INTEGER;
- }
- _svalue = &_longstr[0];
- return TK_STRING_LITERAL;
-}
-
-void LexHexadecimal(const SQChar *s,SQUnsignedInteger *res)
-{
- *res = 0;
- while(*s != 0)
- {
- if(scisdigit(*s)) *res = (*res)*16+((*s++)-'0');
- else if(scisxdigit(*s)) *res = (*res)*16+(toupper(*s++)-'A'+10);
- else { assert(0); }
- }
-}
-
-void LexInteger(const SQChar *s,SQUnsignedInteger *res)
-{
- *res = 0;
- while(*s != 0)
- {
- *res = (*res)*10+((*s++)-'0');
- }
-}
-
-SQInteger isexponent(SQInteger c) { return c == 'e' || c=='E'; }
-#define MAX_HEX_DIGITS (sizeof(SQInteger)*2)
-SQInteger SQLexer::ReadNumber()
-{
-#define TINT 1
-#define TFLOAT 2
-#define THEX 3
-#define TSCIENTIFIC 4
- SQInteger type = TINT, firstchar = CUR_CHAR;
- SQChar *sTemp;
- INIT_TEMP_STRING();
- NEXT();
- if(firstchar == _SC('0') && toupper(CUR_CHAR) == _SC('X')) {
- NEXT();
- type = THEX;
- while(isxdigit(CUR_CHAR)) {
- APPEND_CHAR(CUR_CHAR);
- NEXT();
- }
- if(_longstr.size() > MAX_HEX_DIGITS) Error(_SC("too many digits for an Hex number"));
- }
- else {
- APPEND_CHAR((int)firstchar);
- while (CUR_CHAR == _SC('.') || scisdigit(CUR_CHAR) || isexponent(CUR_CHAR)) {
- if(CUR_CHAR == _SC('.')) type = TFLOAT;
- if(isexponent(CUR_CHAR)) {
- if(type != TFLOAT) Error(_SC("invalid numeric format"));
- type = TSCIENTIFIC;
- APPEND_CHAR(CUR_CHAR);
- NEXT();
- if(CUR_CHAR == '+' || CUR_CHAR == '-'){
- APPEND_CHAR(CUR_CHAR);
- NEXT();
- }
- if(!scisdigit(CUR_CHAR)) Error(_SC("exponent expected"));
- }
-
- APPEND_CHAR(CUR_CHAR);
- NEXT();
- }
- }
- TERMINATE_BUFFER();
- switch(type) {
- case TSCIENTIFIC:
- case TFLOAT:
- _fvalue = (SQFloat)scstrtod(&_longstr[0],&sTemp);
- return TK_FLOAT;
- case TINT:
- LexInteger(&_longstr[0],(SQUnsignedInteger *)&_nvalue);
- return TK_INTEGER;
- case THEX:
- LexHexadecimal(&_longstr[0],(SQUnsignedInteger *)&_nvalue);
- return TK_INTEGER;
- }
- return 0;
-}
-
-SQInteger SQLexer::ReadID()
-{
- SQInteger res;
- INIT_TEMP_STRING();
- do {
- APPEND_CHAR(CUR_CHAR);
- NEXT();
- } while(scisalnum(CUR_CHAR) || CUR_CHAR == _SC('_'));
- TERMINATE_BUFFER();
- res = GetIDType(&_longstr[0]);
- if(res == TK_IDENTIFIER || res == TK_CONSTRUCTOR) {
- _svalue = &_longstr[0];
- }
- return res;
-}
+++ /dev/null
-/* see copyright notice in squirrel.h */
-#ifndef _SQLEXER_H_
-#define _SQLEXER_H_
-
-#ifdef _UNICODE
-typedef SQChar LexChar;
-#else
-typedef unsigned char LexChar;
-#endif
-
-struct SQLexer
-{
- SQLexer();
- ~SQLexer();
- void Init(SQSharedState *ss,SQLEXREADFUNC rg,SQUserPointer up,CompilerErrorFunc efunc,void *ed);
- void Error(const SQChar *err);
- SQInteger Lex();
- const SQChar *Tok2Str(SQInteger tok);
-private:
- SQInteger GetIDType(SQChar *s);
- SQInteger ReadString(SQInteger ndelim,bool verbatim);
- SQInteger ReadNumber();
- void LexBlockComment();
- SQInteger ReadID();
- void Next();
- SQInteger _curtoken;
- SQTable *_keywords;
-public:
- SQInteger _prevtoken;
- SQInteger _currentline;
- SQInteger _lasttokenline;
- SQInteger _currentcolumn;
- const SQChar *_svalue;
- SQInteger _nvalue;
- SQFloat _fvalue;
- SQLEXREADFUNC _readf;
- SQUserPointer _up;
- LexChar _currdata;
- SQSharedState *_sharedstate;
- sqvector<SQChar> _longstr;
- CompilerErrorFunc _errfunc;
- void *_errtarget;
-};
-
-#endif
+++ /dev/null
-/*
- see copyright notice in squirrel.h
-*/
-#include "sqpcheader.h"
-void *sq_vm_malloc(SQUnsignedInteger size){ return malloc(size); }
-
-void *sq_vm_realloc(void *p, SQUnsignedInteger oldsize, SQUnsignedInteger size){ return realloc(p, size); }
-
-void sq_vm_free(void *p, SQUnsignedInteger size){ free(p); }
+++ /dev/null
-/*
- see copyright notice in squirrel.h
-*/
-#include "sqpcheader.h"
-#include "sqvm.h"
-#include "sqstring.h"
-#include "sqarray.h"
-#include "sqtable.h"
-#include "squserdata.h"
-#include "sqfuncproto.h"
-#include "sqclass.h"
-#include "sqclosure.h"
-
-SQString *SQString::Create(SQSharedState *ss,const SQChar *s,SQInteger len)
-{
- SQString *str=ADD_STRING(ss,s,len);
- str->_sharedstate=ss;
- return str;
-}
-
-void SQString::Release()
-{
- REMOVE_STRING(_sharedstate,this);
-}
-
-SQInteger SQString::Next(const SQObjectPtr &refpos, SQObjectPtr &outkey, SQObjectPtr &outval)
-{
- SQInteger idx = (SQInteger)TranslateIndex(refpos);
- while(idx < _len){
- outkey = (SQInteger)idx;
- outval = SQInteger(_val[idx]);
- //return idx for the next iteration
- return ++idx;
- }
- //nothing to iterate anymore
- return -1;
-}
-
-SQUnsignedInteger TranslateIndex(const SQObjectPtr &idx)
-{
- switch(type(idx)){
- case OT_NULL:
- return 0;
- case OT_INTEGER:
- return (SQUnsignedInteger)_integer(idx);
- default: assert(0); break;
- }
- return 0;
-}
-
-SQWeakRef *SQRefCounted::GetWeakRef(SQObjectType type)
-{
- if(!_weakref) {
- sq_new(_weakref,SQWeakRef);
- _weakref->_obj._type = type;
- _weakref->_obj._unVal.pRefCounted = this;
- }
- return _weakref;
-}
-
-SQRefCounted::~SQRefCounted()
-{
- if(_weakref) {
- _weakref->_obj._type = OT_NULL;
- _weakref->_obj._unVal.pRefCounted = NULL;
- }
-}
-
-void SQWeakRef::Release() {
- if(ISREFCOUNTED(_obj._type)) {
- _obj._unVal.pRefCounted->_weakref = NULL;
- }
- sq_delete(this,SQWeakRef);
-}
-
-bool SQDelegable::GetMetaMethod(SQVM *v,SQMetaMethod mm,SQObjectPtr &res) {
- if(_delegate) {
- return _delegate->Get((*_ss(v)->_metamethods)[mm],res);
- }
- return false;
-}
-
-bool SQDelegable::SetDelegate(SQTable *mt)
-{
- SQTable *temp = mt;
- while (temp) {
- if (temp->_delegate == this) return false; //cycle detected
- temp = temp->_delegate;
- }
- if (mt) __ObjAddRef(mt);
- __ObjRelease(_delegate);
- _delegate = mt;
- return true;
-}
-
-bool SQGenerator::Yield(SQVM *v)
-{
- if(_state==eSuspended) { v->Raise_Error(_SC("internal vm error, yielding dead generator")); return false;}
- if(_state==eDead) { v->Raise_Error(_SC("internal vm error, yielding a dead generator")); return false; }
- SQInteger size = v->_top-v->_stackbase;
- _ci=*v->ci;
- _stack.resize(size);
- for(SQInteger n =0; n<size; n++) {
- _stack._vals[n] = v->_stack[v->_stackbase+n];
- v->_stack[v->_stackbase+n] = _null_;
- }
- SQInteger nvargs = v->ci->_vargs.size;
- SQInteger vargsbase = v->ci->_vargs.base;
- for(SQInteger j = nvargs - 1; j >= 0; j--) {
- _vargsstack.push_back(v->_vargsstack[vargsbase+j]);
- }
- _ci._generator=_null_;
- for(SQInteger i=0;i<_ci._etraps;i++) {
- _etraps.push_back(v->_etraps.top());
- v->_etraps.pop_back();
- }
- _state=eSuspended;
- return true;
-}
-
-bool SQGenerator::Resume(SQVM *v,SQInteger target)
-{
- SQInteger size=_stack.size();
- if(_state==eDead){ v->Raise_Error(_SC("resuming dead generator")); return false; }
- if(_state==eRunning){ v->Raise_Error(_SC("resuming active generator")); return false; }
- SQInteger prevtop=v->_top-v->_stackbase;
- PUSH_CALLINFO(v,_ci);
- SQInteger oldstackbase=v->_stackbase;
- v->_stackbase = v->_top;
- v->ci->_target = (SQInt32)target;
- v->ci->_generator = SQObjectPtr(this);
- v->ci->_vargs.size = (unsigned short)_vargsstack.size();
-
- for(SQInteger i=0;i<_ci._etraps;i++) {
- v->_etraps.push_back(_etraps.top());
- _etraps.pop_back();
- }
- for(SQInteger n =0; n<size; n++) {
- v->_stack[v->_stackbase+n] = _stack._vals[n];
- _stack._vals[0] = _null_;
- }
- while(_vargsstack.size()) {
- v->_vargsstack.push_back(_vargsstack.back());
- _vargsstack.pop_back();
- }
- v->ci->_vargs.base = (unsigned short)(v->_vargsstack.size() - v->ci->_vargs.size);
- v->_top=v->_stackbase+size;
- v->ci->_prevtop = (SQInt32)prevtop;
- v->ci->_prevstkbase = (SQInt32)(v->_stackbase - oldstackbase);
- _state=eRunning;
- return true;
-}
-
-void SQArray::Extend(const SQArray *a){
- SQInteger xlen;
- if((xlen=a->Size()))
- for(SQInteger i=0;i<xlen;i++)
- Append(a->_values[i]);
-}
-
-const SQChar* SQFunctionProto::GetLocal(SQVM *vm,SQUnsignedInteger stackbase,SQUnsignedInteger nseq,SQUnsignedInteger nop)
-{
- SQUnsignedInteger nvars=_nlocalvarinfos;
- const SQChar *res=NULL;
- if(nvars>=nseq){
- for(SQUnsignedInteger i=0;i<nvars;i++){
- if(_localvarinfos[i]._start_op<=nop && _localvarinfos[i]._end_op>=nop)
- {
- if(nseq==0){
- vm->Push(vm->_stack[stackbase+_localvarinfos[i]._pos]);
- res=_stringval(_localvarinfos[i]._name);
- break;
- }
- nseq--;
- }
- }
- }
- return res;
-}
-
-SQInteger SQFunctionProto::GetLine(SQInstruction *curr)
-{
- SQInteger op = (SQInteger)(curr-_instructions);
- SQInteger line=_lineinfos[0]._line;
- for(SQInteger i=1;i<_nlineinfos;i++){
- if(_lineinfos[i]._op>=op)
- return line;
- line=_lineinfos[i]._line;
- }
- return line;
-}
-
-#define _CHECK_IO(exp) { if(!exp)return false; }
-bool SafeWrite(HSQUIRRELVM v,SQWRITEFUNC write,SQUserPointer up,SQUserPointer dest,SQInteger size)
-{
- if(write(up,dest,size) != size) {
- v->Raise_Error(_SC("io error (write function failure)"));
- return false;
- }
- return true;
-}
-
-bool SafeRead(HSQUIRRELVM v,SQWRITEFUNC read,SQUserPointer up,SQUserPointer dest,SQInteger size)
-{
- if(size && read(up,dest,size) != size) {
- v->Raise_Error(_SC("io error, read function failure, the origin stream could be corrupted/trucated"));
- return false;
- }
- return true;
-}
-
-bool WriteTag(HSQUIRRELVM v,SQWRITEFUNC write,SQUserPointer up,SQInteger tag)
-{
- return SafeWrite(v,write,up,&tag,sizeof(tag));
-}
-
-bool CheckTag(HSQUIRRELVM v,SQWRITEFUNC read,SQUserPointer up,SQInteger tag)
-{
- SQInteger t;
- _CHECK_IO(SafeRead(v,read,up,&t,sizeof(t)));
- if(t != tag){
- v->Raise_Error(_SC("invalid or corrupted closure stream"));
- return false;
- }
- return true;
-}
-
-bool WriteObject(HSQUIRRELVM v,SQUserPointer up,SQWRITEFUNC write,SQObjectPtr &o)
-{
- _CHECK_IO(SafeWrite(v,write,up,&type(o),sizeof(SQObjectType)));
- switch(type(o)){
- case OT_STRING:
- _CHECK_IO(SafeWrite(v,write,up,&_string(o)->_len,sizeof(SQInteger)));
- _CHECK_IO(SafeWrite(v,write,up,_stringval(o),rsl(_string(o)->_len)));
- break;
- case OT_INTEGER:
- _CHECK_IO(SafeWrite(v,write,up,&_integer(o),sizeof(SQInteger)));break;
- case OT_FLOAT:
- _CHECK_IO(SafeWrite(v,write,up,&_float(o),sizeof(SQFloat)));break;
- case OT_NULL:
- break;
- default:
- v->Raise_Error(_SC("cannot serialize a %s"),GetTypeName(o));
- return false;
- }
- return true;
-}
-
-bool ReadObject(HSQUIRRELVM v,SQUserPointer up,SQREADFUNC read,SQObjectPtr &o)
-{
- SQObjectType t;
- _CHECK_IO(SafeRead(v,read,up,&t,sizeof(SQObjectType)));
- switch(t){
- case OT_STRING:{
- SQInteger len;
- _CHECK_IO(SafeRead(v,read,up,&len,sizeof(SQInteger)));
- _CHECK_IO(SafeRead(v,read,up,_ss(v)->GetScratchPad(rsl(len)),rsl(len)));
- o=SQString::Create(_ss(v),_ss(v)->GetScratchPad(-1),len);
- }
- break;
- case OT_INTEGER:{
- SQInteger i;
- _CHECK_IO(SafeRead(v,read,up,&i,sizeof(SQInteger))); o = i; break;
- }
- case OT_FLOAT:{
- SQFloat f;
- _CHECK_IO(SafeRead(v,read,up,&f,sizeof(SQFloat))); o = f; break;
- }
- case OT_NULL:
- o=_null_;
- break;
- default:
- v->Raise_Error(_SC("cannot serialize a %s"),IdType2Name(t));
- return false;
- }
- return true;
-}
-
-bool SQClosure::Save(SQVM *v,SQUserPointer up,SQWRITEFUNC write)
-{
- _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_HEAD));
- _CHECK_IO(WriteTag(v,write,up,sizeof(SQChar)));
- _CHECK_IO(_funcproto(_function)->Save(v,up,write));
- _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_TAIL));
- return true;
-}
-
-bool SQClosure::Load(SQVM *v,SQUserPointer up,SQREADFUNC read,SQObjectPtr &ret)
-{
- _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_HEAD));
- _CHECK_IO(CheckTag(v,read,up,sizeof(SQChar)));
- SQObjectPtr func;
- _CHECK_IO(SQFunctionProto::Load(v,up,read,func));
- _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_TAIL));
- ret = SQClosure::Create(_ss(v),_funcproto(func));
- return true;
-}
-
-bool SQFunctionProto::Save(SQVM *v,SQUserPointer up,SQWRITEFUNC write)
-{
- SQInteger i,nliterals = _nliterals,nparameters = _nparameters;
- SQInteger noutervalues = _noutervalues,nlocalvarinfos = _nlocalvarinfos;
- SQInteger nlineinfos=_nlineinfos,ninstructions = _ninstructions,nfunctions=_nfunctions;
- _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART));
- _CHECK_IO(WriteObject(v,up,write,_sourcename));
- _CHECK_IO(WriteObject(v,up,write,_name));
- _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART));
- _CHECK_IO(SafeWrite(v,write,up,&nliterals,sizeof(nliterals)));
- _CHECK_IO(SafeWrite(v,write,up,&nparameters,sizeof(nparameters)));
- _CHECK_IO(SafeWrite(v,write,up,&noutervalues,sizeof(noutervalues)));
- _CHECK_IO(SafeWrite(v,write,up,&nlocalvarinfos,sizeof(nlocalvarinfos)));
- _CHECK_IO(SafeWrite(v,write,up,&nlineinfos,sizeof(nlineinfos)));
- _CHECK_IO(SafeWrite(v,write,up,&ninstructions,sizeof(ninstructions)));
- _CHECK_IO(SafeWrite(v,write,up,&nfunctions,sizeof(nfunctions)));
- _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART));
- for(i=0;i<nliterals;i++){
- _CHECK_IO(WriteObject(v,up,write,_literals[i]));
- }
-
- _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART));
- for(i=0;i<nparameters;i++){
- _CHECK_IO(WriteObject(v,up,write,_parameters[i]));
- }
-
- _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART));
- for(i=0;i<noutervalues;i++){
- _CHECK_IO(SafeWrite(v,write,up,&_outervalues[i]._type,sizeof(SQUnsignedInteger)));
- _CHECK_IO(WriteObject(v,up,write,_outervalues[i]._src));
- _CHECK_IO(WriteObject(v,up,write,_outervalues[i]._name));
- }
-
- _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART));
- for(i=0;i<nlocalvarinfos;i++){
- SQLocalVarInfo &lvi=_localvarinfos[i];
- _CHECK_IO(WriteObject(v,up,write,lvi._name));
- _CHECK_IO(SafeWrite(v,write,up,&lvi._pos,sizeof(SQUnsignedInteger)));
- _CHECK_IO(SafeWrite(v,write,up,&lvi._start_op,sizeof(SQUnsignedInteger)));
- _CHECK_IO(SafeWrite(v,write,up,&lvi._end_op,sizeof(SQUnsignedInteger)));
- }
-
- _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART));
- _CHECK_IO(SafeWrite(v,write,up,_lineinfos,sizeof(SQLineInfo)*nlineinfos));
-
- _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART));
- _CHECK_IO(SafeWrite(v,write,up,_instructions,sizeof(SQInstruction)*ninstructions));
-
- _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART));
- for(i=0;i<nfunctions;i++){
- _CHECK_IO(_funcproto(_functions[i])->Save(v,up,write));
- }
- _CHECK_IO(SafeWrite(v,write,up,&_stacksize,sizeof(_stacksize)));
- _CHECK_IO(SafeWrite(v,write,up,&_bgenerator,sizeof(_bgenerator)));
- _CHECK_IO(SafeWrite(v,write,up,&_varparams,sizeof(_varparams)));
- return true;
-}
-
-bool SQFunctionProto::Load(SQVM *v,SQUserPointer up,SQREADFUNC read,SQObjectPtr &ret)
-{
- SQInteger i, nliterals,nparameters;
- SQInteger noutervalues ,nlocalvarinfos ;
- SQInteger nlineinfos,ninstructions ,nfunctions ;
- SQObjectPtr sourcename, name;
- SQObjectPtr o;
- _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART));
- _CHECK_IO(ReadObject(v, up, read, sourcename));
- _CHECK_IO(ReadObject(v, up, read, name));
-
- _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART));
- _CHECK_IO(SafeRead(v,read,up, &nliterals, sizeof(nliterals)));
- _CHECK_IO(SafeRead(v,read,up, &nparameters, sizeof(nparameters)));
- _CHECK_IO(SafeRead(v,read,up, &noutervalues, sizeof(noutervalues)));
- _CHECK_IO(SafeRead(v,read,up, &nlocalvarinfos, sizeof(nlocalvarinfos)));
- _CHECK_IO(SafeRead(v,read,up, &nlineinfos, sizeof(nlineinfos)));
- _CHECK_IO(SafeRead(v,read,up, &ninstructions, sizeof(ninstructions)));
- _CHECK_IO(SafeRead(v,read,up, &nfunctions, sizeof(nfunctions)));
-
- SQFunctionProto *f = SQFunctionProto::Create(ninstructions,nliterals,nparameters,nfunctions,noutervalues,nlineinfos,nlocalvarinfos);
- SQObjectPtr proto = f; //gets a ref in case of failure
- f->_sourcename = sourcename;
- f->_name = name;
-
- _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART));
-
- for(i = 0;i < nliterals; i++){
- _CHECK_IO(ReadObject(v, up, read, o));
- f->_literals[i] = o;
- }
- _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART));
-
- for(i = 0; i < nparameters; i++){
- _CHECK_IO(ReadObject(v, up, read, o));
- f->_parameters[i] = o;
- }
- _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART));
-
- for(i = 0; i < noutervalues; i++){
- SQUnsignedInteger type;
- SQObjectPtr name;
- _CHECK_IO(SafeRead(v,read,up, &type, sizeof(SQUnsignedInteger)));
- _CHECK_IO(ReadObject(v, up, read, o));
- _CHECK_IO(ReadObject(v, up, read, name));
- f->_outervalues[i] = SQOuterVar(name,o, (SQOuterType)type);
- }
- _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART));
-
- for(i = 0; i < nlocalvarinfos; i++){
- SQLocalVarInfo lvi;
- _CHECK_IO(ReadObject(v, up, read, lvi._name));
- _CHECK_IO(SafeRead(v,read,up, &lvi._pos, sizeof(SQUnsignedInteger)));
- _CHECK_IO(SafeRead(v,read,up, &lvi._start_op, sizeof(SQUnsignedInteger)));
- _CHECK_IO(SafeRead(v,read,up, &lvi._end_op, sizeof(SQUnsignedInteger)));
- f->_localvarinfos[i] = lvi;
- }
- _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART));
- _CHECK_IO(SafeRead(v,read,up, f->_lineinfos, sizeof(SQLineInfo)*nlineinfos));
-
- _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART));
- _CHECK_IO(SafeRead(v,read,up, f->_instructions, sizeof(SQInstruction)*ninstructions));
-
- _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART));
- for(i = 0; i < nfunctions; i++){
- _CHECK_IO(_funcproto(o)->Load(v, up, read, o));
- f->_functions[i] = o;
- }
- _CHECK_IO(SafeRead(v,read,up, &f->_stacksize, sizeof(f->_stacksize)));
- _CHECK_IO(SafeRead(v,read,up, &f->_bgenerator, sizeof(f->_bgenerator)));
- _CHECK_IO(SafeRead(v,read,up, &f->_varparams, sizeof(f->_varparams)));
- ret = f;
- return true;
-}
-
-#ifndef NO_GARBAGE_COLLECTOR
-
-#define START_MARK() if(!(_uiRef&MARK_FLAG)){ \
- _uiRef|=MARK_FLAG;
-
-#define END_MARK() RemoveFromChain(&_sharedstate->_gc_chain, this); \
- AddToChain(chain, this); }
-
-void SQVM::Mark(SQCollectable **chain)
-{
- START_MARK()
- SQSharedState::MarkObject(_lasterror,chain);
- SQSharedState::MarkObject(_errorhandler,chain);
- SQSharedState::MarkObject(_debughook,chain);
- SQSharedState::MarkObject(_roottable, chain);
- SQSharedState::MarkObject(temp_reg, chain);
- for(SQUnsignedInteger i = 0; i < _stack.size(); i++) SQSharedState::MarkObject(_stack[i], chain);
- for(SQUnsignedInteger j = 0; j < _vargsstack.size(); j++) SQSharedState::MarkObject(_vargsstack[j], chain);
- END_MARK()
-}
-
-void SQArray::Mark(SQCollectable **chain)
-{
- START_MARK()
- SQInteger len = _values.size();
- for(SQInteger i = 0;i < len; i++) SQSharedState::MarkObject(_values[i], chain);
- END_MARK()
-}
-void SQTable::Mark(SQCollectable **chain)
-{
- START_MARK()
- if(_delegate) _delegate->Mark(chain);
- SQInteger len = _numofnodes;
- for(SQInteger i = 0; i < len; i++){
- SQSharedState::MarkObject(_nodes[i].key, chain);
- SQSharedState::MarkObject(_nodes[i].val, chain);
- }
- END_MARK()
-}
-
-void SQClass::Mark(SQCollectable **chain)
-{
- START_MARK()
- _members->Mark(chain);
- if(_base) _base->Mark(chain);
- SQSharedState::MarkObject(_attributes, chain);
- for(SQUnsignedInteger i =0; i< _defaultvalues.size(); i++) {
- SQSharedState::MarkObject(_defaultvalues[i].val, chain);
- SQSharedState::MarkObject(_defaultvalues[i].attrs, chain);
- }
- for(SQUnsignedInteger j =0; j< _methods.size(); j++) {
- SQSharedState::MarkObject(_methods[j].val, chain);
- SQSharedState::MarkObject(_methods[j].attrs, chain);
- }
- for(SQUnsignedInteger k =0; k< _metamethods.size(); k++) {
- SQSharedState::MarkObject(_metamethods[k], chain);
- }
- END_MARK()
-}
-
-void SQInstance::Mark(SQCollectable **chain)
-{
- START_MARK()
- _class->Mark(chain);
- SQUnsignedInteger nvalues = _class->_defaultvalues.size();
- for(SQUnsignedInteger i =0; i< nvalues; i++) {
- SQSharedState::MarkObject(_values[i], chain);
- }
- END_MARK()
-}
-
-void SQGenerator::Mark(SQCollectable **chain)
-{
- START_MARK()
- for(SQUnsignedInteger i = 0; i < _stack.size(); i++) SQSharedState::MarkObject(_stack[i], chain);
- for(SQUnsignedInteger j = 0; j < _vargsstack.size(); j++) SQSharedState::MarkObject(_vargsstack[j], chain);
- SQSharedState::MarkObject(_closure, chain);
- END_MARK()
-}
-
-void SQClosure::Mark(SQCollectable **chain)
-{
- START_MARK()
- for(SQUnsignedInteger i = 0; i < _outervalues.size(); i++) SQSharedState::MarkObject(_outervalues[i], chain);
- END_MARK()
-}
-
-void SQNativeClosure::Mark(SQCollectable **chain)
-{
- START_MARK()
- for(SQUnsignedInteger i = 0; i < _outervalues.size(); i++) SQSharedState::MarkObject(_outervalues[i], chain);
- END_MARK()
-}
-
-void SQUserData::Mark(SQCollectable **chain){
- START_MARK()
- if(_delegate) _delegate->Mark(chain);
- END_MARK()
-}
-
-void SQCollectable::UnMark() { _uiRef&=~MARK_FLAG; }
-
-#endif
-
+++ /dev/null
-/* see copyright notice in squirrel.h */
-#ifndef _SQOBJECT_H_
-#define _SQOBJECT_H_
-
-#include "squtils.h"
-
-#define SQ_CLOSURESTREAM_HEAD (('S'<<24)|('Q'<<16)|('I'<<8)|('R'))
-#define SQ_CLOSURESTREAM_PART (('P'<<24)|('A'<<16)|('R'<<8)|('T'))
-#define SQ_CLOSURESTREAM_TAIL (('T'<<24)|('A'<<16)|('I'<<8)|('L'))
-
-struct SQSharedState;
-
-enum SQMetaMethod{
- MT_ADD=0,
- MT_SUB=1,
- MT_MUL=2,
- MT_DIV=3,
- MT_UNM=4,
- MT_MODULO=5,
- MT_SET=6,
- MT_GET=7,
- MT_TYPEOF=8,
- MT_NEXTI=9,
- MT_CMP=10,
- MT_CALL=11,
- MT_CLONED=12,
- MT_NEWSLOT=13,
- MT_DELSLOT=14,
- MT_TOSTRING=15,
- MT_NEWMEMBER=16,
- MT_INHERITED=17,
- MT_LAST = 18
-};
-
-#define MM_ADD _SC("_add")
-#define MM_SUB _SC("_sub")
-#define MM_MUL _SC("_mul")
-#define MM_DIV _SC("_div")
-#define MM_UNM _SC("_unm")
-#define MM_MODULO _SC("_modulo")
-#define MM_SET _SC("_set")
-#define MM_GET _SC("_get")
-#define MM_TYPEOF _SC("_typeof")
-#define MM_NEXTI _SC("_nexti")
-#define MM_CMP _SC("_cmp")
-#define MM_CALL _SC("_call")
-#define MM_CLONED _SC("_cloned")
-#define MM_NEWSLOT _SC("_newslot")
-#define MM_DELSLOT _SC("_delslot")
-#define MM_TOSTRING _SC("_tostring")
-#define MM_NEWMEMBER _SC("_newmember")
-#define MM_INHERITED _SC("_inherited")
-
-#define MINPOWER2 4
-
-struct SQRefCounted
-{
- SQRefCounted() { _uiRef = 0; _weakref = NULL; }
- virtual ~SQRefCounted();
- SQWeakRef *GetWeakRef(SQObjectType type);
- SQUnsignedInteger _uiRef;
- struct SQWeakRef *_weakref;
- virtual void Release()=0;
-};
-
-struct SQWeakRef : SQRefCounted
-{
- void Release();
- SQObject _obj;
-};
-
-#define _realval(o) (type((o)) != OT_WEAKREF?(SQObject)o:_weakref(o)->_obj)
-
-struct SQObjectPtr;
-
-#define __AddRef(type,unval) if(ISREFCOUNTED(type)) \
- { \
- unval.pRefCounted->_uiRef++; \
- }
-
-#define __Release(type,unval) if(ISREFCOUNTED(type) && ((--unval.pRefCounted->_uiRef)<=0)) \
- { \
- unval.pRefCounted->Release(); \
- }
-
-#define __ObjRelease(obj) { \
- if((obj)) { \
- (obj)->_uiRef--; \
- if((obj)->_uiRef == 0) \
- (obj)->Release(); \
- (obj) = NULL; \
- } \
-}
-
-#define __ObjAddRef(obj) { \
- (obj)->_uiRef++; \
-}
-
-#define type(obj) ((obj)._type)
-#define is_delegable(t) (type(t)&SQOBJECT_DELEGABLE)
-#define raw_type(obj) _RAW_TYPE((obj)._type)
-
-#define _integer(obj) ((obj)._unVal.nInteger)
-#define _float(obj) ((obj)._unVal.fFloat)
-#define _string(obj) ((obj)._unVal.pString)
-#define _table(obj) ((obj)._unVal.pTable)
-#define _array(obj) ((obj)._unVal.pArray)
-#define _closure(obj) ((obj)._unVal.pClosure)
-#define _generator(obj) ((obj)._unVal.pGenerator)
-#define _nativeclosure(obj) ((obj)._unVal.pNativeClosure)
-#define _userdata(obj) ((obj)._unVal.pUserData)
-#define _userpointer(obj) ((obj)._unVal.pUserPointer)
-#define _thread(obj) ((obj)._unVal.pThread)
-#define _funcproto(obj) ((obj)._unVal.pFunctionProto)
-#define _class(obj) ((obj)._unVal.pClass)
-#define _instance(obj) ((obj)._unVal.pInstance)
-#define _delegable(obj) ((SQDelegable *)(obj)._unVal.pDelegable)
-#define _weakref(obj) ((obj)._unVal.pWeakRef)
-#define _refcounted(obj) ((obj)._unVal.pRefCounted)
-#define _rawval(obj) ((obj)._unVal.pRefCounted)
-
-#define _stringval(obj) (obj)._unVal.pString->_val
-#define _userdataval(obj) (obj)._unVal.pUserData->_val
-
-#define tofloat(num) ((type(num)==OT_INTEGER)?(SQFloat)_integer(num):_float(num))
-#define tointeger(num) ((type(num)==OT_FLOAT)?(SQInteger)_float(num):_integer(num))
-/////////////////////////////////////////////////////////////////////////////////////
-/////////////////////////////////////////////////////////////////////////////////////
-struct SQObjectPtr : public SQObject
-{
- SQObjectPtr()
- {
- _type=OT_NULL;
- _unVal.pUserPointer=NULL;
- }
- SQObjectPtr(const SQObjectPtr &o)
- {
- _type=o._type;
- _unVal=o._unVal;
- __AddRef(_type,_unVal);
- }
- SQObjectPtr(const SQObject &o)
- {
- _type=o._type;
- _unVal=o._unVal;
- __AddRef(_type,_unVal);
- }
- SQObjectPtr(SQTable *pTable)
- {
- _type=OT_TABLE;
- _unVal.pTable=pTable;
- assert(_unVal.pTable);
- __AddRef(_type,_unVal);
- }
- SQObjectPtr(SQClass *pClass)
- {
- _type=OT_CLASS;
- _unVal.pClass=pClass;
- assert(_unVal.pClass);
- __AddRef(_type,_unVal);
- }
- SQObjectPtr(SQInstance *pInstance)
- {
- _type=OT_INSTANCE;
- _unVal.pInstance=pInstance;
- assert(_unVal.pInstance);
- __AddRef(_type,_unVal);
- }
- SQObjectPtr(SQArray *pArray)
- {
- _type=OT_ARRAY;
- _unVal.pArray=pArray;
- assert(_unVal.pArray);
- __AddRef(_type,_unVal);
- }
- SQObjectPtr(SQClosure *pClosure)
- {
- _type=OT_CLOSURE;
- _unVal.pClosure=pClosure;
- assert(_unVal.pClosure);
- __AddRef(_type,_unVal);
- }
- SQObjectPtr(SQGenerator *pGenerator)
- {
- _type=OT_GENERATOR;
- _unVal.pGenerator=pGenerator;
- assert(_unVal.pGenerator);
- __AddRef(_type,_unVal);
- }
- SQObjectPtr(SQNativeClosure *pNativeClosure)
- {
- _type=OT_NATIVECLOSURE;
- _unVal.pNativeClosure=pNativeClosure;
- assert(_unVal.pNativeClosure);
- __AddRef(_type,_unVal);
- }
- SQObjectPtr(SQString *pString)
- {
- _type=OT_STRING;
- _unVal.pString=pString;
- assert(_unVal.pString);
- __AddRef(_type,_unVal);
- }
- SQObjectPtr(SQUserData *pUserData)
- {
- _type=OT_USERDATA;
- _unVal.pUserData=pUserData;
- assert(_unVal.pUserData);
- __AddRef(_type,_unVal);
- }
- SQObjectPtr(SQVM *pThread)
- {
- _type=OT_THREAD;
- _unVal.pThread=pThread;
- assert(_unVal.pThread);
- __AddRef(_type,_unVal);
- }
- SQObjectPtr(SQWeakRef *pWeakRef)
- {
- _type=OT_WEAKREF;
- _unVal.pWeakRef=pWeakRef;
- assert(_unVal.pWeakRef);
- __AddRef(_type,_unVal);
- }
- SQObjectPtr(SQFunctionProto *pFunctionProto)
- {
- _type=OT_FUNCPROTO;
- _unVal.pFunctionProto=pFunctionProto;
- assert(_unVal.pFunctionProto);
- __AddRef(_type,_unVal);
- }
- SQObjectPtr(SQInteger nInteger)
- {
- _unVal.pUserPointer=NULL;
- _type=OT_INTEGER;
- _unVal.nInteger=nInteger;
- }
- SQObjectPtr(SQFloat fFloat)
- {
- _unVal.pUserPointer=NULL;
- _type=OT_FLOAT;
- _unVal.fFloat=fFloat;
- }
- SQObjectPtr(bool bBool)
- {
- _unVal.pUserPointer=NULL;
- _type = OT_BOOL;
- _unVal.nInteger = bBool?1:0;
- }
- SQObjectPtr(SQUserPointer pUserPointer)
- {
- _type=OT_USERPOINTER;
- _unVal.pUserPointer=pUserPointer;
- }
- ~SQObjectPtr()
- {
- __Release(_type,_unVal);
- }
- inline void Null()
- {
- SQObjectType tOldType;
- SQObjectValue unOldVal;
- tOldType = _type;
- unOldVal = _unVal;
- _type = OT_NULL;
- _unVal.pUserPointer = NULL;
- __Release(tOldType,unOldVal);
- }
- inline SQObjectPtr& operator=(SQInteger i)
- {
- __Release(_type,_unVal);
- _unVal.nInteger = i;
- _type = OT_INTEGER;
- return *this;
- }
- inline SQObjectPtr& operator=(SQFloat f)
- {
- __Release(_type,_unVal);
- _unVal.fFloat = f;
- _type = OT_FLOAT;
- return *this;
- }
- inline SQObjectPtr& operator=(const SQObjectPtr& obj)
- {
- SQObjectType tOldType;
- SQObjectValue unOldVal;
- tOldType=_type;
- unOldVal=_unVal;
- _unVal = obj._unVal;
- _type = obj._type;
- __AddRef(_type,_unVal);
- __Release(tOldType,unOldVal);
- return *this;
- }
- inline SQObjectPtr& operator=(const SQObject& obj)
- {
- SQObjectType tOldType;
- SQObjectValue unOldVal;
- tOldType=_type;
- unOldVal=_unVal;
- _unVal = obj._unVal;
- _type = obj._type;
- __AddRef(_type,_unVal);
- __Release(tOldType,unOldVal);
- return *this;
- }
- private:
- SQObjectPtr(const SQChar *){} //safety
-};
-/////////////////////////////////////////////////////////////////////////////////////
-#ifndef NO_GARBAGE_COLLECTOR
-#define MARK_FLAG 0x80000000
-struct SQCollectable : public SQRefCounted {
- SQCollectable *_next;
- SQCollectable *_prev;
- SQSharedState *_sharedstate;
- virtual void Release()=0;
- virtual void Mark(SQCollectable **chain)=0;
- void UnMark();
- virtual void Finalize()=0;
- static void AddToChain(SQCollectable **chain,SQCollectable *c);
- static void RemoveFromChain(SQCollectable **chain,SQCollectable *c);
-};
-
-
-#define ADD_TO_CHAIN(chain,obj) AddToChain(chain,obj)
-#define REMOVE_FROM_CHAIN(chain,obj) {if(!(_uiRef&MARK_FLAG))RemoveFromChain(chain,obj);}
-#define CHAINABLE_OBJ SQCollectable
-#define INIT_CHAIN() {_next=NULL;_prev=NULL;_sharedstate=ss;}
-#else
-
-#define ADD_TO_CHAIN(chain,obj) ((void)0)
-#define REMOVE_FROM_CHAIN(chain,obj) ((void)0)
-#define CHAINABLE_OBJ SQRefCounted
-#define INIT_CHAIN() ((void)0)
-#endif
-
-struct SQDelegable : public CHAINABLE_OBJ {
- bool SetDelegate(SQTable *m);
- virtual bool GetMetaMethod(SQVM *v,SQMetaMethod mm,SQObjectPtr &res);
- SQTable *_delegate;
-};
-
-SQUnsignedInteger TranslateIndex(const SQObjectPtr &idx);
-typedef sqvector<SQObjectPtr> SQObjectPtrVec;
-typedef sqvector<SQInteger> SQIntVec;
-
-
-#endif //_SQOBJECT_H_
+++ /dev/null
-/* see copyright notice in squirrel.h */
-#ifndef _SQOPCODES_H_
-#define _SQOPCODES_H_
-
-#define MAX_FUNC_STACKSIZE 0xFF
-#define MAX_LITERALS ((SQInteger)0x7FFFFFFF)
-
-enum BitWiseOP {
- BW_AND = 0,
- BW_OR = 2,
- BW_XOR = 3,
- BW_SHIFTL = 4,
- BW_SHIFTR = 5,
- BW_USHIFTR = 6
-};
-
-enum CmpOP {
- CMP_G = 0,
- CMP_GE = 2,
- CMP_L = 3,
- CMP_LE = 4
-};
-enum SQOpcode
-{
- _OP_LINE= 0x00,
- _OP_LOAD= 0x01,
- _OP_LOADINT= 0x02,
- _OP_LOADFLOAT= 0x03,
- _OP_DLOAD= 0x04,
- _OP_TAILCALL= 0x05,
- _OP_CALL= 0x06,
- _OP_PREPCALL= 0x07,
- _OP_PREPCALLK= 0x08,
- _OP_GETK= 0x09,
- _OP_MOVE= 0x0A,
- _OP_NEWSLOT= 0x0B,
- _OP_DELETE= 0x0C,
- _OP_SET= 0x0D,
- _OP_GET= 0x0E,
- _OP_EQ= 0x0F,
- _OP_NE= 0x10,
- _OP_ARITH= 0x11,
- _OP_BITW= 0x12,
- _OP_RETURN= 0x13,
- _OP_LOADNULLS= 0x14,
- _OP_LOADROOTTABLE= 0x15,
- _OP_LOADBOOL= 0x16,
- _OP_DMOVE= 0x17,
- _OP_JMP= 0x18,
- _OP_JNZ= 0x19,
- _OP_JZ= 0x1A,
- _OP_LOADFREEVAR= 0x1B,
- _OP_VARGC= 0x1C,
- _OP_GETVARGV= 0x1D,
- _OP_NEWTABLE= 0x1E,
- _OP_NEWARRAY= 0x1F,
- _OP_APPENDARRAY= 0x20,
- _OP_GETPARENT= 0x21,
- _OP_COMPARITH= 0x22,
- _OP_COMPARITHL= 0x23,
- _OP_INC= 0x24,
- _OP_INCL= 0x25,
- _OP_PINC= 0x26,
- _OP_PINCL= 0x27,
- _OP_CMP= 0x28,
- _OP_EXISTS= 0x29,
- _OP_INSTANCEOF= 0x2A,
- _OP_AND= 0x2B,
- _OP_OR= 0x2C,
- _OP_NEG= 0x2D,
- _OP_NOT= 0x2E,
- _OP_BWNOT= 0x2F,
- _OP_CLOSURE= 0x30,
- _OP_YIELD= 0x31,
- _OP_RESUME= 0x32,
- _OP_FOREACH= 0x33,
- _OP_POSTFOREACH= 0x34,
- _OP_DELEGATE= 0x35,
- _OP_CLONE= 0x36,
- _OP_TYPEOF= 0x37,
- _OP_PUSHTRAP= 0x38,
- _OP_POPTRAP= 0x39,
- _OP_THROW= 0x3A,
- _OP_CLASS= 0x3B,
- _OP_NEWSLOTA= 0x3C,
-};
-
-struct SQInstructionDesc {
- const SQChar *name;
-};
-
-struct SQInstruction
-{
- SQInstruction(){};
- SQInstruction(SQOpcode _op,SQInteger a0=0,SQInteger a1=0,SQInteger a2=0,SQInteger a3=0)
- { op = _op;
- _arg0 = (unsigned char)a0;_arg1 = (SQInt32)a1;
- _arg2 = (unsigned char)a2;_arg3 = (unsigned char)a3;
- }
-
-
- SQInt32 _arg1;
- unsigned char op;
- unsigned char _arg0;
- unsigned char _arg2;
- unsigned char _arg3;
-};
-
-#include "squtils.h"
-typedef sqvector<SQInstruction> SQInstructionVec;
-
-#define NEW_SLOT_ATTRIBUTES_FLAG 0x01
-#define NEW_SLOT_STATIC_FLAG 0x02
-
-#endif // _SQOPCODES_H_
+++ /dev/null
-/* see copyright notice in squirrel.h */
-#ifndef _SQPCHEADER_H_
-#define _SQPCHEADER_H_
-
-#if defined(_MSC_VER) && defined(_DEBUG)
-#include <crtdbg.h>
-#endif
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <assert.h>
-#include <new>
-//squirrel stuff
-#include <squirrel.h>
-#include "sqobject.h"
-#include "sqstate.h"
-
-#endif //_SQPCHEADER_H_
+++ /dev/null
-/*
- see copyright notice in squirrel.h
-*/
-#include "sqpcheader.h"
-#include "sqopcodes.h"
-#include "sqvm.h"
-#include "sqfuncproto.h"
-#include "sqclosure.h"
-#include "sqstring.h"
-#include "sqtable.h"
-#include "sqarray.h"
-#include "squserdata.h"
-#include "sqclass.h"
-
-SQObjectPtr _null_;
-SQObjectPtr _true_(true);
-SQObjectPtr _false_(false);
-SQObjectPtr _one_((SQInteger)1);
-SQObjectPtr _minusone_((SQInteger)-1);
-
-SQSharedState::SQSharedState()
-{
- _compilererrorhandler = NULL;
- _printfunc = NULL;
- _debuginfo = false;
- _notifyallexceptions = false;
-}
-
-#define newsysstring(s) { \
- _systemstrings->push_back(SQString::Create(this,s)); \
- }
-
-#define newmetamethod(s) { \
- _metamethods->push_back(SQString::Create(this,s)); \
- _table(_metamethodsmap)->NewSlot(_metamethods->back(),(SQInteger)(_metamethods->size()-1)); \
- }
-
-bool CompileTypemask(SQIntVec &res,const SQChar *typemask)
-{
- SQInteger i = 0;
-
- SQInteger mask = 0;
- while(typemask[i] != 0) {
-
- switch(typemask[i]){
- case 'o': mask |= _RT_NULL; break;
- case 'i': mask |= _RT_INTEGER; break;
- case 'f': mask |= _RT_FLOAT; break;
- case 'n': mask |= (_RT_FLOAT | _RT_INTEGER); break;
- case 's': mask |= _RT_STRING; break;
- case 't': mask |= _RT_TABLE; break;
- case 'a': mask |= _RT_ARRAY; break;
- case 'u': mask |= _RT_USERDATA; break;
- case 'c': mask |= (_RT_CLOSURE | _RT_NATIVECLOSURE); break;
- case 'b': mask |= _RT_BOOL; break;
- case 'g': mask |= _RT_GENERATOR; break;
- case 'p': mask |= _RT_USERPOINTER; break;
- case 'v': mask |= _RT_THREAD; break;
- case 'x': mask |= _RT_INSTANCE; break;
- case 'y': mask |= _RT_CLASS; break;
- case 'r': mask |= _RT_WEAKREF; break;
- case '.': mask = -1; res.push_back(mask); i++; mask = 0; continue;
- case ' ': i++; continue; //ignores spaces
- default:
- return false;
- }
- i++;
- if(typemask[i] == '|') {
- i++;
- if(typemask[i] == 0)
- return false;
- continue;
- }
- res.push_back(mask);
- mask = 0;
-
- }
- return true;
-}
-
-SQTable *CreateDefaultDelegate(SQSharedState *ss,SQRegFunction *funcz)
-{
- SQInteger i=0;
- SQTable *t=SQTable::Create(ss,0);
- while(funcz[i].name!=0){
- SQNativeClosure *nc = SQNativeClosure::Create(ss,funcz[i].f);
- nc->_nparamscheck = funcz[i].nparamscheck;
- nc->_name = SQString::Create(ss,funcz[i].name);
- if(funcz[i].typemask && !CompileTypemask(nc->_typecheck,funcz[i].typemask))
- return NULL;
- t->NewSlot(SQString::Create(ss,funcz[i].name),nc);
- i++;
- }
- return t;
-}
-
-void SQSharedState::Init()
-{
- _scratchpad=NULL;
- _scratchpadsize=0;
-#ifndef NO_GARBAGE_COLLECTOR
- _gc_chain=NULL;
-#endif
- sq_new(_stringtable,StringTable);
- sq_new(_metamethods,SQObjectPtrVec);
- sq_new(_systemstrings,SQObjectPtrVec);
- sq_new(_types,SQObjectPtrVec);
- _metamethodsmap = SQTable::Create(this,MT_LAST-1);
- //adding type strings to avoid memory trashing
- //types names
- newsysstring(_SC("null"));
- newsysstring(_SC("table"));
- newsysstring(_SC("array"));
- newsysstring(_SC("closure"));
- newsysstring(_SC("string"));
- newsysstring(_SC("userdata"));
- newsysstring(_SC("integer"));
- newsysstring(_SC("float"));
- newsysstring(_SC("userpointer"));
- newsysstring(_SC("function"));
- newsysstring(_SC("generator"));
- newsysstring(_SC("thread"));
- newsysstring(_SC("class"));
- newsysstring(_SC("instance"));
- newsysstring(_SC("bool"));
- //meta methods
- newmetamethod(MM_ADD);
- newmetamethod(MM_SUB);
- newmetamethod(MM_MUL);
- newmetamethod(MM_DIV);
- newmetamethod(MM_UNM);
- newmetamethod(MM_MODULO);
- newmetamethod(MM_SET);
- newmetamethod(MM_GET);
- newmetamethod(MM_TYPEOF);
- newmetamethod(MM_NEXTI);
- newmetamethod(MM_CMP);
- newmetamethod(MM_CALL);
- newmetamethod(MM_CLONED);
- newmetamethod(MM_NEWSLOT);
- newmetamethod(MM_DELSLOT);
- newmetamethod(MM_TOSTRING);
- newmetamethod(MM_NEWMEMBER);
- newmetamethod(MM_INHERITED);
-
- _constructoridx = SQString::Create(this,_SC("constructor"));
- _registry = SQTable::Create(this,0);
- _table_default_delegate=CreateDefaultDelegate(this,_table_default_delegate_funcz);
- _array_default_delegate=CreateDefaultDelegate(this,_array_default_delegate_funcz);
- _string_default_delegate=CreateDefaultDelegate(this,_string_default_delegate_funcz);
- _number_default_delegate=CreateDefaultDelegate(this,_number_default_delegate_funcz);
- _closure_default_delegate=CreateDefaultDelegate(this,_closure_default_delegate_funcz);
- _generator_default_delegate=CreateDefaultDelegate(this,_generator_default_delegate_funcz);
- _thread_default_delegate=CreateDefaultDelegate(this,_thread_default_delegate_funcz);
- _class_default_delegate=CreateDefaultDelegate(this,_class_default_delegate_funcz);
- _instance_default_delegate=CreateDefaultDelegate(this,_instance_default_delegate_funcz);
- _weakref_default_delegate=CreateDefaultDelegate(this,_weakref_default_delegate_funcz);
-
-}
-
-SQSharedState::~SQSharedState()
-{
- _constructoridx = _null_;
- _refs_table.Finalize();
- _table(_registry)->Finalize();
- _table(_metamethodsmap)->Finalize();
- _registry = _null_;
- _metamethodsmap = _null_;
- while(!_systemstrings->empty()) {
- _systemstrings->back()=_null_;
- _systemstrings->pop_back();
- }
- _thread(_root_vm)->Finalize();
- _root_vm = _null_;
- _table_default_delegate=_null_;
- _array_default_delegate=_null_;
- _string_default_delegate=_null_;
- _number_default_delegate=_null_;
- _closure_default_delegate=_null_;
- _generator_default_delegate=_null_;
- _thread_default_delegate=_null_;
- _class_default_delegate=_null_;
- _instance_default_delegate=_null_;
- _weakref_default_delegate=_null_;
-
-#ifndef NO_GARBAGE_COLLECTOR
- SQCollectable *t=_gc_chain;
- SQCollectable *nx=NULL;
- while(t) {
- t->_uiRef++;
- t->Finalize();
- nx=t->_next;
- if(--t->_uiRef == 0)
- t->Release();
- t=nx;
- }
- assert(_gc_chain==NULL); //just to proove a theory
- while(_gc_chain){
- _gc_chain->_uiRef++;
- _gc_chain->Release();
- }
-#endif
-
- sq_delete(_types,SQObjectPtrVec);
- sq_delete(_systemstrings,SQObjectPtrVec);
- sq_delete(_metamethods,SQObjectPtrVec);
- sq_delete(_stringtable,StringTable);
- if(_scratchpad)SQ_FREE(_scratchpad,_scratchpadsize);
-}
-
-
-SQInteger SQSharedState::GetMetaMethodIdxByName(const SQObjectPtr &name)
-{
- if(type(name) != OT_STRING)
- return -1;
- SQObjectPtr ret;
- if(_table(_metamethodsmap)->Get(name,ret)) {
- return _integer(ret);
- }
- return -1;
-}
-
-#ifndef NO_GARBAGE_COLLECTOR
-
-void SQSharedState::MarkObject(SQObjectPtr &o,SQCollectable **chain)
-{
- switch(type(o)){
- case OT_TABLE:_table(o)->Mark(chain);break;
- case OT_ARRAY:_array(o)->Mark(chain);break;
- case OT_USERDATA:_userdata(o)->Mark(chain);break;
- case OT_CLOSURE:_closure(o)->Mark(chain);break;
- case OT_NATIVECLOSURE:_nativeclosure(o)->Mark(chain);break;
- case OT_GENERATOR:_generator(o)->Mark(chain);break;
- case OT_THREAD:_thread(o)->Mark(chain);break;
- case OT_CLASS:_class(o)->Mark(chain);break;
- case OT_INSTANCE:_instance(o)->Mark(chain);break;
- default: break; //shutup compiler
- }
-}
-
-
-SQInteger SQSharedState::CollectGarbage(SQVM *vm)
-{
- SQInteger n=0;
- SQCollectable *tchain=NULL;
- SQVM *vms = _thread(_root_vm);
-
- vms->Mark(&tchain);
- SQInteger x = _table(_thread(_root_vm)->_roottable)->CountUsed();
- _refs_table.Mark(&tchain);
- MarkObject(_registry,&tchain);
- MarkObject(_metamethodsmap,&tchain);
- MarkObject(_table_default_delegate,&tchain);
- MarkObject(_array_default_delegate,&tchain);
- MarkObject(_string_default_delegate,&tchain);
- MarkObject(_number_default_delegate,&tchain);
- MarkObject(_generator_default_delegate,&tchain);
- MarkObject(_thread_default_delegate,&tchain);
- MarkObject(_closure_default_delegate,&tchain);
- MarkObject(_class_default_delegate,&tchain);
- MarkObject(_instance_default_delegate,&tchain);
- MarkObject(_weakref_default_delegate,&tchain);
-
- SQCollectable *t = _gc_chain;
- SQCollectable *nx = NULL;
- while(t) {
- t->_uiRef++;
- t->Finalize();
- nx = t->_next;
- if(--t->_uiRef == 0)
- t->Release();
- t = nx;
- n++;
- }
-
- t = tchain;
- while(t) {
- t->UnMark();
- t = t->_next;
- }
- _gc_chain = tchain;
- SQInteger z = _table(_thread(_root_vm)->_roottable)->CountUsed();
- assert(z == x);
- return n;
-}
-#endif
-
-#ifndef NO_GARBAGE_COLLECTOR
-void SQCollectable::AddToChain(SQCollectable **chain,SQCollectable *c)
-{
- c->_prev = NULL;
- c->_next = *chain;
- if(*chain) (*chain)->_prev = c;
- *chain = c;
-}
-
-void SQCollectable::RemoveFromChain(SQCollectable **chain,SQCollectable *c)
-{
- if(c->_prev) c->_prev->_next = c->_next;
- else *chain = c->_next;
- if(c->_next)
- c->_next->_prev = c->_prev;
- c->_next = NULL;
- c->_prev = NULL;
-}
-#endif
-
-SQChar* SQSharedState::GetScratchPad(SQInteger size)
-{
- SQInteger newsize;
- if(size>0) {
- if(_scratchpadsize < size) {
- newsize = size + (size>>1);
- _scratchpad = (SQChar *)SQ_REALLOC(_scratchpad,_scratchpadsize,newsize);
- _scratchpadsize = newsize;
-
- }else if(_scratchpadsize >= (size<<5)) {
- newsize = _scratchpadsize >> 1;
- _scratchpad = (SQChar *)SQ_REALLOC(_scratchpad,_scratchpadsize,newsize);
- _scratchpadsize = newsize;
- }
- }
- return _scratchpad;
-}
-
-RefTable::RefTable()
-{
- AllocNodes(4);
-}
-
-void RefTable::Finalize()
-{
- RefNode *nodes = _nodes;
- for(SQUnsignedInteger n = 0; n < _numofslots; n++) {
- nodes->obj = _null_;
- nodes++;
- }
-}
-
-RefTable::~RefTable()
-{
- SQ_FREE(_buckets,(_numofslots * sizeof(RefNode *)) + (_numofslots * sizeof(RefNode)));
-}
-
-#ifndef NO_GARBAGE_COLLECTOR
-void RefTable::Mark(SQCollectable **chain)
-{
- RefNode *nodes = (RefNode *)_nodes;
- for(SQUnsignedInteger n = 0; n < _numofslots; n++) {
- if(type(nodes->obj) != OT_NULL) {
- SQSharedState::MarkObject(nodes->obj,chain);
- }
- nodes++;
- }
-}
-#endif
-
-void RefTable::AddRef(SQObject &obj)
-{
- SQHash mainpos;
- RefNode *prev;
- RefNode *ref = Get(obj,mainpos,&prev,true);
- ref->refs++;
-}
-
-SQBool RefTable::Release(SQObject &obj)
-{
- SQHash mainpos;
- RefNode *prev;
- RefNode *ref = Get(obj,mainpos,&prev,false);
- if(ref) {
- if(--ref->refs == 0) {
- SQObjectPtr o = ref->obj;
- if(prev) {
- prev->next = ref->next;
- }
- else {
- _buckets[mainpos] = ref->next;
- }
- ref->next = _freelist;
- _freelist = ref;
- _slotused--;
- ref->obj = _null_;
- //<<FIXME>>test for shrink?
- return SQTrue;
- }
- }
- else {
- assert(0);
- }
- return SQFalse;
-}
-
-void RefTable::Resize(SQUnsignedInteger size)
-{
- RefNode **oldbucks = _buckets;
- RefNode *t = _nodes;
- SQUnsignedInteger oldnumofslots = _numofslots;
- AllocNodes(size);
- //rehash
- SQUnsignedInteger nfound = 0;
- for(SQUnsignedInteger n = 0; n < oldnumofslots; n++) {
- if(type(t->obj) != OT_NULL) {
- //add back;
- assert(t->refs != 0);
- RefNode *nn = Add(::HashObj(t->obj)&(_numofslots-1),t->obj);
- nn->refs = t->refs;
- t->obj = _null_;
- nfound++;
- }
- t++;
- }
- assert(nfound == oldnumofslots);
- SQ_FREE(oldbucks,(oldnumofslots * sizeof(RefNode *)) + (oldnumofslots * sizeof(RefNode)));
-}
-
-RefTable::RefNode *RefTable::Add(SQHash mainpos,SQObject &obj)
-{
- RefNode *t = _buckets[mainpos];
- RefNode *newnode = _freelist;
- newnode->obj = obj;
- _buckets[mainpos] = newnode;
- _freelist = _freelist->next;
- newnode->next = t;
- assert(newnode->refs == 0);
- _slotused++;
- return newnode;
-}
-
-RefTable::RefNode *RefTable::Get(SQObject &obj,SQHash &mainpos,RefNode **prev,bool add)
-{
- RefNode *ref;
- mainpos = ::HashObj(obj)&(_numofslots-1);
- *prev = NULL;
- for (ref = _buckets[mainpos]; ref; ) {
- if(_rawval(ref->obj) == _rawval(obj) && type(ref->obj) == type(obj))
- break;
- *prev = ref;
- ref = ref->next;
- }
- if(ref == NULL && add) {
- if(_numofslots == _slotused) {
- assert(_freelist == 0);
- Resize(_numofslots*2);
- mainpos = ::HashObj(obj)&(_numofslots-1);
- }
- ref = Add(mainpos,obj);
- }
- return ref;
-}
-
-void RefTable::AllocNodes(SQUnsignedInteger size)
-{
- RefNode **bucks;
- RefNode *nodes;
- bucks = (RefNode **)SQ_MALLOC((size * sizeof(RefNode *)) + (size * sizeof(RefNode)));
- nodes = (RefNode *)&bucks[size];
- RefNode *temp = nodes;
- SQUnsignedInteger n;
- for(n = 0; n < size - 1; n++) {
- bucks[n] = NULL;
- temp->refs = 0;
- new (&temp->obj) SQObjectPtr;
- temp->next = temp+1;
- temp++;
- }
- bucks[n] = NULL;
- temp->refs = 0;
- new (&temp->obj) SQObjectPtr;
- temp->next = NULL;
- _freelist = nodes;
- _nodes = nodes;
- _buckets = bucks;
- _slotused = 0;
- _numofslots = size;
-}
-//////////////////////////////////////////////////////////////////////////
-//StringTable
-/*
-* The following code is based on Lua 4.0 (Copyright 1994-2002 Tecgraf, PUC-Rio.)
-* http://www.lua.org/copyright.html#4
-* http://www.lua.org/source/4.0.1/src_lstring.c.html
-*/
-
-StringTable::StringTable()
-{
- AllocNodes(4);
- _slotused = 0;
-}
-
-StringTable::~StringTable()
-{
- SQ_FREE(_strings,sizeof(SQString*)*_numofslots);
- _strings = NULL;
-}
-
-void StringTable::AllocNodes(SQInteger size)
-{
- _numofslots = size;
- _strings = (SQString**)SQ_MALLOC(sizeof(SQString*)*_numofslots);
- memset(_strings,0,sizeof(SQString*)*_numofslots);
-}
-
-SQString *StringTable::Add(const SQChar *news,SQInteger len)
-{
- if(len<0)
- len = (SQInteger)scstrlen(news);
- SQHash h = ::_hashstr(news,len)&(_numofslots-1);
- SQString *s;
- for (s = _strings[h]; s; s = s->_next){
- if(s->_len == len && (!memcmp(news,s->_val,rsl(len))))
- return s; //found
- }
-
- SQString *t=(SQString *)SQ_MALLOC(rsl(len)+sizeof(SQString));
- new (t) SQString;
- memcpy(t->_val,news,rsl(len));
- t->_val[len] = _SC('\0');
- t->_len = len;
- t->_hash = ::_hashstr(news,len);
- t->_next = _strings[h];
- _strings[h] = t;
- _slotused++;
- if (_slotused > _numofslots) /* too crowded? */
- Resize(_numofslots*2);
- return t;
-}
-
-void StringTable::Resize(SQInteger size)
-{
- SQInteger oldsize=_numofslots;
- SQString **oldtable=_strings;
- AllocNodes(size);
- for (SQInteger i=0; i<oldsize; i++){
- SQString *p = oldtable[i];
- while(p){
- SQString *next = p->_next;
- SQHash h = p->_hash&(_numofslots-1);
- p->_next = _strings[h];
- _strings[h] = p;
- p = next;
- }
- }
- SQ_FREE(oldtable,oldsize*sizeof(SQString*));
-}
-
-void StringTable::Remove(SQString *bs)
-{
- SQString *s;
- SQString *prev=NULL;
- SQHash h = bs->_hash&(_numofslots - 1);
-
- for (s = _strings[h]; s; ){
- if(s == bs){
- if(prev)
- prev->_next = s->_next;
- else
- _strings[h] = s->_next;
- _slotused--;
- SQInteger slen = s->_len;
- s->~SQString();
- SQ_FREE(s,sizeof(SQString) + rsl(slen));
- return;
- }
- prev = s;
- s = s->_next;
- }
- assert(0);//if this fail something is wrong
-}
+++ /dev/null
-/* see copyright notice in squirrel.h */
-#ifndef _SQSTATE_H_
-#define _SQSTATE_H_
-
-#include "squtils.h"
-#include "sqobject.h"
-struct SQString;
-struct SQTable;
-//max number of character for a printed number
-#define NUMBER_MAX_CHAR 50
-
-struct StringTable
-{
- StringTable();
- ~StringTable();
- SQString *Add(const SQChar *,SQInteger len);
- void Remove(SQString *);
-private:
- void Resize(SQInteger size);
- void AllocNodes(SQInteger size);
- SQString **_strings;
- SQUnsignedInteger _numofslots;
- SQUnsignedInteger _slotused;
-};
-
-struct RefTable {
- struct RefNode {
- SQObjectPtr obj;
- SQUnsignedInteger refs;
- struct RefNode *next;
- };
- RefTable();
- ~RefTable();
- void AddRef(SQObject &obj);
- SQBool Release(SQObject &obj);
-#ifndef NO_GARBAGE_COLLECTOR
- void Mark(SQCollectable **chain);
-#endif
- void Finalize();
-private:
- RefNode *Get(SQObject &obj,SQHash &mainpos,RefNode **prev,bool add);
- RefNode *Add(SQHash mainpos,SQObject &obj);
- void Resize(SQUnsignedInteger size);
- void AllocNodes(SQUnsignedInteger size);
- SQUnsignedInteger _numofslots;
- SQUnsignedInteger _slotused;
- RefNode *_nodes;
- RefNode *_freelist;
- RefNode **_buckets;
-};
-
-#define ADD_STRING(ss,str,len) ss->_stringtable->Add(str,len)
-#define REMOVE_STRING(ss,bstr) ss->_stringtable->Remove(bstr)
-
-struct SQObjectPtr;
-
-struct SQSharedState
-{
- SQSharedState();
- ~SQSharedState();
- void Init();
-public:
- SQChar* GetScratchPad(SQInteger size);
- SQInteger GetMetaMethodIdxByName(const SQObjectPtr &name);
-#ifndef NO_GARBAGE_COLLECTOR
- SQInteger CollectGarbage(SQVM *vm);
- static void MarkObject(SQObjectPtr &o,SQCollectable **chain);
-#endif
- SQObjectPtrVec *_metamethods;
- SQObjectPtr _metamethodsmap;
- SQObjectPtrVec *_systemstrings;
- SQObjectPtrVec *_types;
- StringTable *_stringtable;
- RefTable _refs_table;
- SQObjectPtr _registry;
- SQObjectPtr _constructoridx;
-#ifndef NO_GARBAGE_COLLECTOR
- SQCollectable *_gc_chain;
-#endif
- SQObjectPtr _root_vm;
- SQObjectPtr _table_default_delegate;
- static SQRegFunction _table_default_delegate_funcz[];
- SQObjectPtr _array_default_delegate;
- static SQRegFunction _array_default_delegate_funcz[];
- SQObjectPtr _string_default_delegate;
- static SQRegFunction _string_default_delegate_funcz[];
- SQObjectPtr _number_default_delegate;
- static SQRegFunction _number_default_delegate_funcz[];
- SQObjectPtr _generator_default_delegate;
- static SQRegFunction _generator_default_delegate_funcz[];
- SQObjectPtr _closure_default_delegate;
- static SQRegFunction _closure_default_delegate_funcz[];
- SQObjectPtr _thread_default_delegate;
- static SQRegFunction _thread_default_delegate_funcz[];
- SQObjectPtr _class_default_delegate;
- static SQRegFunction _class_default_delegate_funcz[];
- SQObjectPtr _instance_default_delegate;
- static SQRegFunction _instance_default_delegate_funcz[];
- SQObjectPtr _weakref_default_delegate;
- static SQRegFunction _weakref_default_delegate_funcz[];
-
- SQCOMPILERERROR _compilererrorhandler;
- SQPRINTFUNCTION _printfunc;
- bool _debuginfo;
- bool _notifyallexceptions;
-private:
- SQChar *_scratchpad;
- SQInteger _scratchpadsize;
-};
-
-#define _sp(s) (_sharedstate->GetScratchPad(s))
-#define _spval (_sharedstate->GetScratchPad(-1))
-
-#define _table_ddel _table(_sharedstate->_table_default_delegate)
-#define _array_ddel _table(_sharedstate->_array_default_delegate)
-#define _string_ddel _table(_sharedstate->_string_default_delegate)
-#define _number_ddel _table(_sharedstate->_number_default_delegate)
-#define _generator_ddel _table(_sharedstate->_generator_default_delegate)
-#define _closure_ddel _table(_sharedstate->_closure_default_delegate)
-#define _thread_ddel _table(_sharedstate->_thread_default_delegate)
-#define _class_ddel _table(_sharedstate->_class_default_delegate)
-#define _instance_ddel _table(_sharedstate->_instance_default_delegate)
-#define _weakref_ddel _table(_sharedstate->_weakref_default_delegate)
-
-#ifdef SQUNICODE //rsl REAL STRING LEN
-#define rsl(l) ((l)<<1)
-#else
-#define rsl(l) (l)
-#endif
-
-extern SQObjectPtr _null_;
-extern SQObjectPtr _true_;
-extern SQObjectPtr _false_;
-extern SQObjectPtr _one_;
-extern SQObjectPtr _minusone_;
-
-bool CompileTypemask(SQIntVec &res,const SQChar *typemask);
-
-void *sq_vm_malloc(SQUnsignedInteger size);
-void *sq_vm_realloc(void *p,SQUnsignedInteger oldsize,SQUnsignedInteger size);
-void sq_vm_free(void *p,SQUnsignedInteger size);
-#endif //_SQSTATE_H_
+++ /dev/null
-/* see copyright notice in squirrel.h */
-#ifndef _SQSTRING_H_
-#define _SQSTRING_H_
-
-inline SQHash _hashstr (const SQChar *s, size_t l)
-{
- SQHash h = (SQHash)l; /* seed */
- size_t step = (l>>5)|1; /* if string is too long, don't hash all its chars */
- for (; l>=step; l-=step)
- h = h ^ ((h<<5)+(h>>2)+(unsigned short)*(s++));
- return h;
-}
-
-struct SQString : public SQRefCounted
-{
- SQString(){}
- ~SQString(){}
-public:
- static SQString *Create(SQSharedState *ss, const SQChar *, SQInteger len = -1 );
- SQInteger Next(const SQObjectPtr &refpos, SQObjectPtr &outkey, SQObjectPtr &outval);
- void Release();
- SQSharedState *_sharedstate;
- SQString *_next; //chain for the string table
- SQInteger _len;
- SQHash _hash;
- SQChar _val[1];
-};
-
-
-
-#endif //_SQSTRING_H_
+++ /dev/null
-/*
-see copyright notice in squirrel.h
-*/
-#include "sqpcheader.h"
-#include "sqvm.h"
-#include "sqtable.h"
-#include "sqfuncproto.h"
-#include "sqclosure.h"
-
-SQTable::SQTable(SQSharedState *ss,SQInteger nInitialSize)
-{
- SQInteger pow2size=MINPOWER2;
- while(nInitialSize>pow2size)pow2size=pow2size<<1;
- AllocNodes(pow2size);
- _usednodes = 0;
- _delegate = NULL;
- INIT_CHAIN();
- ADD_TO_CHAIN(&_sharedstate->_gc_chain,this);
-}
-
-void SQTable::Remove(const SQObjectPtr &key)
-{
-
- _HashNode *n = _Get(key, HashObj(key) & (_numofnodes - 1));
- if (n) {
- n->val = n->key = _null_;
- _usednodes--;
- Rehash(false);
- }
-}
-
-void SQTable::AllocNodes(SQInteger nSize)
-{
- _HashNode *nodes=(_HashNode *)SQ_MALLOC(sizeof(_HashNode)*nSize);
- for(SQInteger i=0;i<nSize;i++){
- new (&nodes[i]) _HashNode;
- nodes[i].next=NULL;
- }
- _numofnodes=nSize;
- _nodes=nodes;
- _firstfree=&_nodes[_numofnodes-1];
-}
-
-void SQTable::Rehash(bool force)
-{
- SQInteger oldsize=_numofnodes;
- //prevent problems with the integer division
- if(oldsize<4)oldsize=4;
- _HashNode *nold=_nodes;
- SQInteger nelems=CountUsed();
- if (nelems >= oldsize-oldsize/4) /* using more than 3/4? */
- AllocNodes(oldsize*2);
- else if (nelems <= oldsize/4 && /* less than 1/4? */
- oldsize > MINPOWER2)
- AllocNodes(oldsize/2);
- else if(force)
- AllocNodes(oldsize);
- else
- return;
- _usednodes = 0;
- for (SQInteger i=0; i<oldsize; i++) {
- _HashNode *old = nold+i;
- if (type(old->key) != OT_NULL)
- NewSlot(old->key,old->val);
- }
- for(SQInteger k=0;k<oldsize;k++)
- nold[k].~_HashNode();
- SQ_FREE(nold,oldsize*sizeof(_HashNode));
-}
-
-SQTable *SQTable::Clone()
-{
- SQTable *nt=Create(_opt_ss(this),_numofnodes);
- SQInteger ridx=0;
- SQObjectPtr key,val;
- while((ridx=Next(true,ridx,key,val))!=-1){
- nt->NewSlot(key,val);
- }
- nt->SetDelegate(_delegate);
- return nt;
-}
-
-bool SQTable::Get(const SQObjectPtr &key,SQObjectPtr &val)
-{
- if(type(key) == OT_NULL)
- return false;
- _HashNode *n = _Get(key, HashObj(key) & (_numofnodes - 1));
- if (n) {
- val = _realval(n->val);
- return true;
- }
- return false;
-}
-bool SQTable::NewSlot(const SQObjectPtr &key,const SQObjectPtr &val)
-{
- assert(type(key) != OT_NULL);
- SQHash h = HashObj(key) & (_numofnodes - 1);
- _HashNode *n = _Get(key, h);
- if (n) {
- n->val = val;
- return false;
- }
- _HashNode *mp = &_nodes[h];
- n = mp;
-
-
- //key not found I'll insert it
- //main pos is not free
-
- if(type(mp->key) != OT_NULL) {
- n = _firstfree; /* get a free place */
- SQHash mph = HashObj(mp->key) & (_numofnodes - 1);
- _HashNode *othern; /* main position of colliding node */
-
- if (mp > n && (othern = &_nodes[mph]) != mp){
- /* yes; move colliding node into free position */
- while (othern->next != mp){
- assert(othern->next != NULL);
- othern = othern->next; /* find previous */
- }
- othern->next = n; /* redo the chain with `n' in place of `mp' */
- n->key = mp->key;
- n->val = mp->val;/* copy colliding node into free pos. (mp->next also goes) */
- n->next = mp->next;
- mp->key = _null_;
- mp->val = _null_;
- mp->next = NULL; /* now `mp' is free */
- }
- else{
- /* new node will go into free position */
- n->next = mp->next; /* chain new position */
- mp->next = n;
- mp = n;
- }
- }
- mp->key = key;
-
- for (;;) { /* correct `firstfree' */
- if (type(_firstfree->key) == OT_NULL && _firstfree->next == NULL) {
- mp->val = val;
- _usednodes++;
- return true; /* OK; table still has a free place */
- }
- else if (_firstfree == _nodes) break; /* cannot decrement from here */
- else (_firstfree)--;
- }
- Rehash(true);
- return NewSlot(key, val);
-}
-
-SQInteger SQTable::Next(bool getweakrefs,const SQObjectPtr &refpos, SQObjectPtr &outkey, SQObjectPtr &outval)
-{
- SQInteger idx = (SQInteger)TranslateIndex(refpos);
- while (idx < _numofnodes) {
- if(type(_nodes[idx].key) != OT_NULL) {
- //first found
- _HashNode &n = _nodes[idx];
- outkey = n.key;
- outval = getweakrefs?(SQObject)n.val:_realval(n.val);
- //return idx for the next iteration
- return ++idx;
- }
- ++idx;
- }
- //nothing to iterate anymore
- return -1;
-}
-
-
-bool SQTable::Set(const SQObjectPtr &key, const SQObjectPtr &val)
-{
- _HashNode *n = _Get(key, HashObj(key) & (_numofnodes - 1));
- if (n) {
- n->val = val;
- return true;
- }
- return false;
-}
-
-void SQTable::_ClearNodes()
-{
- for(SQInteger i = 0;i < _numofnodes; i++) { _nodes[i].key = _null_; _nodes[i].val = _null_; }
-}
-
-void SQTable::Finalize()
-{
- _ClearNodes();
- SetDelegate(NULL);
-}
-
-void SQTable::Clear()
-{
- _ClearNodes();
- _usednodes = 0;
- Rehash(true);
-}
+++ /dev/null
-/* see copyright notice in squirrel.h */
-#ifndef _SQTABLE_H_
-#define _SQTABLE_H_
-/*
-* The following code is based on Lua 4.0 (Copyright 1994-2002 Tecgraf, PUC-Rio.)
-* http://www.lua.org/copyright.html#4
-* http://www.lua.org/source/4.0.1/src_ltable.c.html
-*/
-
-#include "sqstring.h"
-
-
-#define hashptr(p) ((SQHash)(((SQInteger)p) >> 3))
-
-inline SQHash HashObj(const SQObjectPtr &key)
-{
- switch(type(key)) {
- case OT_STRING: return _string(key)->_hash;
- case OT_FLOAT: return (SQHash)((SQInteger)_float(key));
- case OT_BOOL: case OT_INTEGER: return (SQHash)((SQInteger)_integer(key));
- default: return hashptr(key._unVal.pRefCounted);
- }
-}
-
-struct SQTable : public SQDelegable
-{
-private:
- struct _HashNode
- {
- _HashNode() { next = NULL; }
- SQObjectPtr val;
- SQObjectPtr key;
- _HashNode *next;
- };
- _HashNode *_firstfree;
- _HashNode *_nodes;
- SQInteger _numofnodes;
- SQInteger _usednodes;
-
-///////////////////////////
- void AllocNodes(SQInteger nSize);
- void Rehash(bool force);
- SQTable(SQSharedState *ss, SQInteger nInitialSize);
- void _ClearNodes();
-public:
- static SQTable* Create(SQSharedState *ss,SQInteger nInitialSize)
- {
- SQTable *newtable = (SQTable*)SQ_MALLOC(sizeof(SQTable));
- new (newtable) SQTable(ss, nInitialSize);
- newtable->_delegate = NULL;
- return newtable;
- }
- void Finalize();
- SQTable *Clone();
- ~SQTable()
- {
- SetDelegate(NULL);
- REMOVE_FROM_CHAIN(&_sharedstate->_gc_chain, this);
- for (SQInteger i = 0; i < _numofnodes; i++) _nodes[i].~_HashNode();
- SQ_FREE(_nodes, _numofnodes * sizeof(_HashNode));
- }
-#ifndef NO_GARBAGE_COLLECTOR
- void Mark(SQCollectable **chain);
-#endif
- inline _HashNode *_Get(const SQObjectPtr &key,SQHash hash)
- {
- _HashNode *n = &_nodes[hash];
- do{
- if(_rawval(n->key) == _rawval(key) && type(n->key) == type(key)){
- return n;
- }
- }while((n = n->next));
- return NULL;
- }
- bool Get(const SQObjectPtr &key,SQObjectPtr &val);
- void Remove(const SQObjectPtr &key);
- bool Set(const SQObjectPtr &key, const SQObjectPtr &val);
- //returns true if a new slot has been created false if it was already present
- bool NewSlot(const SQObjectPtr &key,const SQObjectPtr &val);
- SQInteger Next(bool getweakrefs,const SQObjectPtr &refpos, SQObjectPtr &outkey, SQObjectPtr &outval);
-
- SQInteger CountUsed(){ return _usednodes;}
- void Clear();
- void Release()
- {
- sq_delete(this, SQTable);
- }
-
-};
-
-#endif //_SQTABLE_H_
+++ /dev/null
-/* see copyright notice in squirrel.h */
-#ifndef _SQUSERDATA_H_
-#define _SQUSERDATA_H_
-
-struct SQUserData : SQDelegable
-{
- SQUserData(SQSharedState *ss){ _delegate = 0; _hook = NULL; INIT_CHAIN(); ADD_TO_CHAIN(&_ss(this)->_gc_chain, this); }
- ~SQUserData()
- {
- REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain, this);
- SetDelegate(NULL);
- }
- static SQUserData* Create(SQSharedState *ss, SQInteger size)
- {
- SQUserData* ud = (SQUserData*)SQ_MALLOC(sizeof(SQUserData)+(size-1));
- new (ud) SQUserData(ss);
- ud->_size = size;
- ud->_typetag = 0;
- return ud;
- }
-#ifndef NO_GARBAGE_COLLECTOR
- void Mark(SQCollectable **chain);
- void Finalize(){SetDelegate(NULL);}
-#endif
- void Release() {
- if (_hook) _hook(_val,_size);
- SQInteger tsize = _size - 1;
- this->~SQUserData();
- SQ_FREE(this, sizeof(SQUserData) + tsize);
- }
-
- SQInteger _size;
- SQRELEASEHOOK _hook;
- SQUserPointer _typetag;
- SQChar _val[1];
-};
-
-#endif //_SQUSERDATA_H_
+++ /dev/null
-/* see copyright notice in squirrel.h */
-#ifndef _SQUTILS_H_
-#define _SQUTILS_H_
-
-#define sq_new(__ptr,__type) {__ptr=(__type *)sq_vm_malloc(sizeof(__type));new (__ptr) __type;}
-#define sq_delete(__ptr,__type) {__ptr->~__type();sq_vm_free(__ptr,sizeof(__type));}
-#define SQ_MALLOC(__size) sq_vm_malloc((__size));
-#define SQ_FREE(__ptr,__size) sq_vm_free((__ptr),(__size));
-#define SQ_REALLOC(__ptr,__oldsize,__size) sq_vm_realloc((__ptr),(__oldsize),(__size));
-
-//sqvector mini vector class, supports objects by value
-template<typename T> class sqvector
-{
-public:
- sqvector()
- {
- _vals = NULL;
- _size = 0;
- _allocated = 0;
- }
- sqvector(const sqvector<T>& v)
- {
- copy(v);
- }
- void copy(const sqvector<T>& v)
- {
- resize(v._size);
- for(SQUnsignedInteger i = 0; i < v._size; i++) {
- new ((void *)&_vals[i]) T(v._vals[i]);
- }
- _size = v._size;
- }
- ~sqvector()
- {
- if(_allocated) {
- for(SQUnsignedInteger i = 0; i < _size; i++)
- _vals[i].~T();
- SQ_FREE(_vals, (_allocated * sizeof(T)));
- }
- }
- void reserve(SQUnsignedInteger newsize) { _realloc(newsize); }
- void resize(SQUnsignedInteger newsize, const T& fill = T())
- {
- if(newsize > _allocated)
- _realloc(newsize);
- if(newsize > _size) {
- while(_size < newsize) {
- new ((void *)&_vals[_size]) T(fill);
- _size++;
- }
- }
- else{
- for(SQUnsignedInteger i = newsize; i < _size; i++) {
- _vals[i].~T();
- }
- _size = newsize;
- }
- }
- void shrinktofit() { if(_size > 4) { _realloc(_size); } }
- T& top() const { return _vals[_size - 1]; }
- inline SQUnsignedInteger size() const { return _size; }
- bool empty() const { return (_size <= 0); }
- inline T &push_back(const T& val = T())
- {
- if(_allocated <= _size)
- _realloc(_size * 2);
- return *(new ((void *)&_vals[_size++]) T(val));
- }
- inline void pop_back()
- {
- _size--; _vals[_size].~T();
- }
- void insert(SQUnsignedInteger idx, const T& val)
- {
- resize(_size + 1);
- for(SQUnsignedInteger i = _size - 1; i > idx; i--) {
- _vals[i] = _vals[i - 1];
- }
- _vals[idx] = val;
- }
- void remove(SQUnsignedInteger idx)
- {
- _vals[idx].~T();
- if(idx < (_size - 1)) {
- memcpy(&_vals[idx], &_vals[idx+1], sizeof(T) * (_size - idx - 1));
- }
- _size--;
- }
- SQUnsignedInteger capacity() { return _allocated; }
- inline T &back() const { return _vals[_size - 1]; }
- inline T& operator[](SQUnsignedInteger pos) const{ return _vals[pos]; }
- T* _vals;
-private:
- void _realloc(SQUnsignedInteger newsize)
- {
- newsize = (newsize > 0)?newsize:4;
- _vals = (T*)SQ_REALLOC(_vals, _allocated * sizeof(T), newsize * sizeof(T));
- _allocated = newsize;
- }
- SQUnsignedInteger _size;
- SQUnsignedInteger _allocated;
-};
-
-#endif //_SQUTILS_H_
+++ /dev/null
-/*
- see copyright notice in squirrel.h
-*/
-#include "sqpcheader.h"
-#include <math.h>
-#include <stdlib.h>
-#include "sqopcodes.h"
-#include "sqfuncproto.h"
-#include "sqvm.h"
-#include "sqclosure.h"
-#include "sqstring.h"
-#include "sqtable.h"
-#include "squserdata.h"
-#include "sqarray.h"
-#include "sqclass.h"
-
-#define TOP() (_stack._vals[_top-1])
-
-bool SQVM::BW_OP(SQUnsignedInteger op,SQObjectPtr &trg,const SQObjectPtr &o1,const SQObjectPtr &o2)
-{
- SQInteger res;
- SQInteger i1 = _integer(o1), i2 = _integer(o2);
- if((type(o1)==OT_INTEGER) && (type(o2)==OT_INTEGER))
- {
- switch(op) {
- case BW_AND: res = i1 & i2; break;
- case BW_OR: res = i1 | i2; break;
- case BW_XOR: res = i1 ^ i2; break;
- case BW_SHIFTL: res = i1 << i2; break;
- case BW_SHIFTR: res = i1 >> i2; break;
- case BW_USHIFTR:res = (SQInteger)(*((SQUnsignedInteger*)&i1) >> i2); break;
- default: { Raise_Error(_SC("internal vm error bitwise op failed")); return false; }
- }
- }
- else { Raise_Error(_SC("bitwise op between '%s' and '%s'"),GetTypeName(o1),GetTypeName(o2)); return false;}
- trg = res;
- return true;
-}
-
-bool SQVM::ARITH_OP(SQUnsignedInteger op,SQObjectPtr &trg,const SQObjectPtr &o1,const SQObjectPtr &o2)
-{
- if(sq_isnumeric(o1) && sq_isnumeric(o2)) {
- if((type(o1)==OT_INTEGER) && (type(o2)==OT_INTEGER)) {
- SQInteger res, i1 = _integer(o1), i2 = _integer(o2);
- switch(op) {
- case '+': res = i1 + i2; break;
- case '-': res = i1 - i2; break;
- case '/': if(i2 == 0) { Raise_Error(_SC("division by zero")); return false; }
- res = i1 / i2;
- break;
- case '*': res = i1 * i2; break;
- case '%': res = i1 % i2; break;
- default: res = 0xDEADBEEF;
- }
- trg = res;
- }else{
- SQFloat res, f1 = tofloat(o1), f2 = tofloat(o2);
- switch(op) {
- case '+': res = f1 + f2; break;
- case '-': res = f1 - f2; break;
- case '/': res = f1 / f2; break;
- case '*': res = f1 * f2; break;
- case '%': res = SQFloat(fmod((double)f1,(double)f2)); break;
- default: res = 0x0f;
- }
- trg = res;
- }
- } else {
- if(op == '+' && (type(o1) == OT_STRING || type(o2) == OT_STRING)){
- if(!StringCat(o1, o2, trg)) return false;
- }
- else if(!ArithMetaMethod(op,o1,o2,trg)) {
- Raise_Error(_SC("arith op %c on between '%s' and '%s'"),op,GetTypeName(o1),GetTypeName(o2)); return false;
- }
- }
- return true;
-}
-
-SQVM::SQVM(SQSharedState *ss)
-{
- _sharedstate=ss;
- _suspended = SQFalse;
- _suspended_target=-1;
- _suspended_root = SQFalse;
- _suspended_traps=-1;
- _foreignptr=NULL;
- _nnativecalls=0;
- _lasterror = _null_;
- _errorhandler = _null_;
- _debughook = _null_;
- ci = NULL;
- INIT_CHAIN();ADD_TO_CHAIN(&_ss(this)->_gc_chain,this);
-}
-
-void SQVM::Finalize()
-{
- _roottable = _null_;
- _lasterror = _null_;
- _errorhandler = _null_;
- _debughook = _null_;
- temp_reg = _null_;
- SQInteger size=_stack.size();
- for(SQInteger i=0;i<size;i++)
- _stack[i]=_null_;
-}
-
-SQVM::~SQVM()
-{
- Finalize();
- sq_free(_callsstack,_alloccallsstacksize*sizeof(CallInfo));
- REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain,this);
-}
-
-bool SQVM::ArithMetaMethod(SQInteger op,const SQObjectPtr &o1,const SQObjectPtr &o2,SQObjectPtr &dest)
-{
- SQMetaMethod mm;
- switch(op){
- case _SC('+'): mm=MT_ADD; break;
- case _SC('-'): mm=MT_SUB; break;
- case _SC('/'): mm=MT_DIV; break;
- case _SC('*'): mm=MT_MUL; break;
- case _SC('%'): mm=MT_MODULO; break;
- default: mm = MT_ADD; assert(0); break; //shutup compiler
- }
- if(is_delegable(o1) && _delegable(o1)->_delegate) {
- Push(o1);Push(o2);
- return CallMetaMethod(_delegable(o1),mm,2,dest);
- }
- return false;
-}
-
-bool SQVM::NEG_OP(SQObjectPtr &trg,const SQObjectPtr &o)
-{
-
- switch(type(o)) {
- case OT_INTEGER:
- trg = -_integer(o);
- return true;
- case OT_FLOAT:
- trg = -_float(o);
- return true;
- case OT_TABLE:
- case OT_USERDATA:
- case OT_INSTANCE:
- if(_delegable(o)->_delegate) {
- Push(o);
- if(CallMetaMethod(_delegable(o), MT_UNM, 1, temp_reg)) {
- trg = temp_reg;
- return true;
- }
- }
- default:break; //shutup compiler
- }
- Raise_Error(_SC("attempt to negate a %s"), GetTypeName(o));
- return false;
-}
-
-#define _RET_SUCCEED(exp) { result = (exp); return true; }
-bool SQVM::ObjCmp(const SQObjectPtr &o1,const SQObjectPtr &o2,SQInteger &result)
-{
- if(type(o1)==type(o2)){
- if(_userpointer(o1)==_userpointer(o2))_RET_SUCCEED(0);
- SQObjectPtr res;
- switch(type(o1)){
- case OT_STRING:
- _RET_SUCCEED(scstrcmp(_stringval(o1),_stringval(o2)));
- case OT_INTEGER:
- _RET_SUCCEED(_integer(o1)-_integer(o2));
- case OT_FLOAT:
- _RET_SUCCEED((_float(o1)<_float(o2))?-1:1);
- case OT_TABLE:
- case OT_USERDATA:
- case OT_INSTANCE:
- if(_delegable(o1)->_delegate) {
- Push(o1);Push(o2);
- if(CallMetaMethod(_delegable(o1),MT_CMP,2,res)) break;
- }
- //continues through (no break needed)
- default:
- _RET_SUCCEED( _userpointer(o1) < _userpointer(o2)?-1:1 );
- }
- if(type(res)!=OT_INTEGER) { Raise_CompareError(o1,o2); return false; }
- _RET_SUCCEED(_integer(res));
-
- }
- else{
- if(sq_isnumeric(o1) && sq_isnumeric(o2)){
- if((type(o1)==OT_INTEGER) && (type(o2)==OT_FLOAT)) {
- if( _integer(o1)==_float(o2) ) { _RET_SUCCEED(0); }
- else if( _integer(o1)<_float(o2) ) { _RET_SUCCEED(-1); }
- _RET_SUCCEED(1);
- }
- else{
- if( _float(o1)==_integer(o2) ) { _RET_SUCCEED(0); }
- else if( _float(o1)<_integer(o2) ) { _RET_SUCCEED(-1); }
- _RET_SUCCEED(1);
- }
- }
- else if(type(o1)==OT_NULL) {_RET_SUCCEED(-1);}
- else if(type(o2)==OT_NULL) {_RET_SUCCEED(1);}
- else { Raise_CompareError(o1,o2); return false; }
-
- }
- assert(0);
- _RET_SUCCEED(0); //cannot happen
-}
-
-bool SQVM::CMP_OP(CmpOP op, const SQObjectPtr &o1,const SQObjectPtr &o2,SQObjectPtr &res)
-{
- SQInteger r;
- if(ObjCmp(o1,o2,r)) {
- switch(op) {
- case CMP_G: res = (r > 0)?_true_:_false_; return true;
- case CMP_GE: res = (r >= 0)?_true_:_false_; return true;
- case CMP_L: res = (r < 0)?_true_:_false_; return true;
- case CMP_LE: res = (r <= 0)?_true_:_false_; return true;
-
- }
- assert(0);
- }
- return false;
-}
-
-void SQVM::ToString(const SQObjectPtr &o,SQObjectPtr &res)
-{
- switch(type(o)) {
- case OT_STRING:
- res = o;
- return;
- case OT_FLOAT:
- scsprintf(_sp(rsl(NUMBER_MAX_CHAR+1)),_SC("%g"),_float(o));
- break;
- case OT_INTEGER:
- scsprintf(_sp(rsl(NUMBER_MAX_CHAR+1)),_SC("%d"),_integer(o));
- break;
- case OT_BOOL:
- scsprintf(_sp(rsl(6)),_integer(o)?_SC("true"):_SC("false"));
- break;
- case OT_TABLE:
- case OT_USERDATA:
- case OT_INSTANCE:
- if(_delegable(o)->_delegate) {
- Push(o);
- if(CallMetaMethod(_delegable(o),MT_TOSTRING,1,res)) {
- if(type(res) == OT_STRING)
- return;
- //else keeps going to the default
- }
- }
- default:
- scsprintf(_sp(rsl(sizeof(void*)+20)),_SC("(%s : 0x%p)"),GetTypeName(o),(void*)_rawval(o));
- }
- res = SQString::Create(_ss(this),_spval);
-}
-
-
-bool SQVM::StringCat(const SQObjectPtr &str,const SQObjectPtr &obj,SQObjectPtr &dest)
-{
- SQObjectPtr a, b;
- ToString(str, a);
- ToString(obj, b);
- SQInteger l = _string(a)->_len , ol = _string(b)->_len;
- SQChar *s = _sp(rsl(l + ol + 1));
- memcpy(s, _stringval(a), rsl(l));
- memcpy(s + l, _stringval(b), rsl(ol));
- dest = SQString::Create(_ss(this), _spval, l + ol);
- return true;
-}
-
-const SQChar *IdType2Name(SQObjectType type)
-{
- switch(_RAW_TYPE(type))
- {
- case _RT_NULL:return _SC("null");
- case _RT_INTEGER:return _SC("integer");
- case _RT_FLOAT:return _SC("float");
- case _RT_BOOL:return _SC("bool");
- case _RT_STRING:return _SC("string");
- case _RT_TABLE:return _SC("table");
- case _RT_ARRAY:return _SC("array");
- case _RT_GENERATOR:return _SC("generator");
- case _RT_CLOSURE:
- case _RT_NATIVECLOSURE:
- return _SC("function");
- case _RT_USERDATA:
- case _RT_USERPOINTER:
- return _SC("userdata");
- case _RT_THREAD: return _SC("thread");
- case _RT_FUNCPROTO: return _SC("function");
- case _RT_CLASS: return _SC("class");
- case _RT_INSTANCE: return _SC("instance");
- case _RT_WEAKREF: return _SC("weakref");
- default:
- return NULL;
- }
-}
-
-const SQChar *GetTypeName(const SQObjectPtr &obj1)
-{
- return IdType2Name(type(obj1));
-}
-
-void SQVM::TypeOf(const SQObjectPtr &obj1,SQObjectPtr &dest)
-{
- if(is_delegable(obj1) && _delegable(obj1)->_delegate) {
- Push(obj1);
- if(CallMetaMethod(_delegable(obj1),MT_TYPEOF,1,dest))
- return;
- }
- dest = SQString::Create(_ss(this),GetTypeName(obj1));
-}
-
-bool SQVM::Init(SQVM *friendvm, SQInteger stacksize)
-{
- _stack.resize(stacksize);
- //_callsstack.reserve(4);
- _alloccallsstacksize = 4;
- _callsstacksize = 0;
- _callsstack = (CallInfo*)sq_malloc(_alloccallsstacksize*sizeof(CallInfo));
- _stackbase = 0;
- _top = 0;
- if(!friendvm)
- _roottable = SQTable::Create(_ss(this), 0);
- else {
- _roottable = friendvm->_roottable;
- _errorhandler = friendvm->_errorhandler;
- _debughook = friendvm->_debughook;
- }
-
- sq_base_register(this);
- return true;
-}
-
-extern SQInstructionDesc g_InstrDesc[];
-
-bool SQVM::StartCall(SQClosure *closure,SQInteger target,SQInteger nargs,SQInteger stackbase,bool tailcall)
-{
- SQFunctionProto *func = _funcproto(closure->_function);
-
- const SQInteger paramssize = func->_nparameters;
- const SQInteger newtop = stackbase + func->_stacksize;
-
-
- if (paramssize != nargs) {
- if(func->_varparams)
- {
- if (nargs < paramssize) {
- Raise_Error(_SC("wrong number of parameters"));
- return false;
- }
- for(SQInteger n = 0; n < nargs - paramssize; n++) {
- _vargsstack.push_back(_stack._vals[stackbase+paramssize+n]);
- _stack._vals[stackbase+paramssize+n] = _null_;
- }
- }
- else {
- Raise_Error(_SC("wrong number of parameters"));
- return false;
- }
- }
-
- if(type(closure->_env) == OT_WEAKREF) {
- _stack._vals[stackbase] = _weakref(closure->_env)->_obj;
- }
-
- if (!tailcall) {
- CallInfo lc;
- lc._etraps = 0;
- lc._prevstkbase = (SQInt32) ( stackbase - _stackbase );
- lc._target = (SQInt32) target;
- lc._prevtop = (SQInt32) (_top - _stackbase);
- lc._ncalls = 1;
- lc._root = SQFalse;
- PUSH_CALLINFO(this, lc);
- }
- else {
- ci->_ncalls++;
- }
- ci->_vargs.size = (SQInt32)(nargs - paramssize);
- ci->_vargs.base = (SQInt32) (_vargsstack.size()-(ci->_vargs.size));
- ci->_closure._unVal.pClosure = closure;
- ci->_closure._type = OT_CLOSURE;
- ci->_literals = func->_literals;
- ci->_ip = func->_instructions;
- //grows the stack if needed
- if (((SQUnsignedInteger)newtop + (func->_stacksize<<1)) > _stack.size()) {
- _stack.resize(_stack.size() + (func->_stacksize<<1));
- }
-
- _top = newtop;
- _stackbase = stackbase;
- return true;
-}
-
-bool SQVM::Return(SQInteger _arg0, SQInteger _arg1, SQObjectPtr &retval)
-{
- if (type(_debughook) != OT_NULL && _rawval(_debughook) != _rawval(ci->_closure))
- for(SQInteger i=0;i<ci->_ncalls;i++)
- CallDebugHook(_SC('r'));
-
- SQBool broot = ci->_root;
- SQInteger last_top = _top;
- SQInteger target = ci->_target;
- SQInteger oldstackbase = _stackbase;
- _stackbase -= ci->_prevstkbase;
- _top = _stackbase + ci->_prevtop;
- if(ci->_vargs.size) PopVarArgs(ci->_vargs);
- POP_CALLINFO(this);
- if (broot) {
- if (_arg0 != MAX_FUNC_STACKSIZE) retval = _stack._vals[oldstackbase+_arg1];
- else retval = _null_;
- }
- else {
- if(target != -1) { //-1 is when a class contructor ret value has to be ignored
- if (_arg0 != MAX_FUNC_STACKSIZE)
- STK(target) = _stack._vals[oldstackbase+_arg1];
- else
- STK(target) = _null_;
- }
- }
-
- while (last_top >= _top) _stack._vals[last_top--].Null();
- assert(oldstackbase >= _stackbase);
- return broot?true:false;
-}
-
-#define _RET_ON_FAIL(exp) { if(!exp) return false; }
-
-bool SQVM::LOCAL_INC(SQInteger op,SQObjectPtr &target, SQObjectPtr &a, SQObjectPtr &incr)
-{
- _RET_ON_FAIL(ARITH_OP( op , target, a, incr));
- a = target;
- return true;
-}
-
-bool SQVM::PLOCAL_INC(SQInteger op,SQObjectPtr &target, SQObjectPtr &a, SQObjectPtr &incr)
-{
- SQObjectPtr trg;
- _RET_ON_FAIL(ARITH_OP( op , trg, a, incr));
- target = a;
- a = trg;
- return true;
-}
-
-bool SQVM::DerefInc(SQInteger op,SQObjectPtr &target, SQObjectPtr &self, SQObjectPtr &key, SQObjectPtr &incr, bool postfix)
-{
- SQObjectPtr tmp, tself = self, tkey = key;
- if (!Get(tself, tkey, tmp, false, true)) { Raise_IdxError(tkey); return false; }
- _RET_ON_FAIL(ARITH_OP( op , target, tmp, incr))
- Set(tself, tkey, target,true);
- if (postfix) target = tmp;
- return true;
-}
-
-#define arg0 (_i_._arg0)
-#define arg1 (_i_._arg1)
-#define sarg1 (*((SQInt32 *)&_i_._arg1))
-#define arg2 (_i_._arg2)
-#define arg3 (_i_._arg3)
-#define sarg3 ((SQInteger)*((signed char *)&_i_._arg3))
-
-SQRESULT SQVM::Suspend()
-{
- if (_suspended)
- return sq_throwerror(this, _SC("cannot suspend an already suspended vm"));
- if (_nnativecalls!=2)
- return sq_throwerror(this, _SC("cannot suspend through native calls/metamethods"));
- return SQ_SUSPEND_FLAG;
-}
-
-void SQVM::PopVarArgs(VarArgs &vargs)
-{
- for(SQInteger n = 0; n< vargs.size; n++)
- _vargsstack.pop_back();
-}
-
-#define _FINISH(howmuchtojump) {jump = howmuchtojump; return true; }
-bool SQVM::FOREACH_OP(SQObjectPtr &o1,SQObjectPtr &o2,SQObjectPtr
-&o3,SQObjectPtr &o4,SQInteger arg_2,int exitpos,int &jump)
-{
- SQInteger nrefidx;
- switch(type(o1)) {
- case OT_TABLE:
- if((nrefidx = _table(o1)->Next(false,o4, o2, o3)) == -1) _FINISH(exitpos);
- o4 = (SQInteger)nrefidx; _FINISH(1);
- case OT_ARRAY:
- if((nrefidx = _array(o1)->Next(o4, o2, o3)) == -1) _FINISH(exitpos);
- o4 = (SQInteger) nrefidx; _FINISH(1);
- case OT_STRING:
- if((nrefidx = _string(o1)->Next(o4, o2, o3)) == -1)_FINISH(exitpos);
- o4 = (SQInteger)nrefidx; _FINISH(1);
- case OT_CLASS:
- if((nrefidx = _class(o1)->Next(o4, o2, o3)) == -1)_FINISH(exitpos);
- o4 = (SQInteger)nrefidx; _FINISH(1);
- case OT_USERDATA:
- case OT_INSTANCE:
- if(_delegable(o1)->_delegate) {
- SQObjectPtr itr;
- Push(o1);
- Push(o4);
- if(CallMetaMethod(_delegable(o1), MT_NEXTI, 2, itr)){
- o4 = o2 = itr;
- if(type(itr) == OT_NULL) _FINISH(exitpos);
- if(!Get(o1, itr, o3, false,false)) {
- Raise_Error(_SC("_nexti returned an invalid idx"));
- return false;
- }
- _FINISH(1);
- }
- Raise_Error(_SC("_nexti failed"));
- return false;
- }
- break;
- case OT_GENERATOR:
- if(_generator(o1)->_state == SQGenerator::eDead) _FINISH(exitpos);
- if(_generator(o1)->_state == SQGenerator::eSuspended) {
- SQInteger idx = 0;
- if(type(o4) == OT_INTEGER) {
- idx = _integer(o4) + 1;
- }
- o2 = idx;
- o4 = idx;
- _generator(o1)->Resume(this, arg_2+1);
- _FINISH(0);
- }
- default:
- Raise_Error(_SC("cannot iterate %s"), GetTypeName(o1));
- }
- return false; //cannot be hit(just to avoid warnings)
-}
-
-bool SQVM::DELEGATE_OP(SQObjectPtr &trg,SQObjectPtr &o1,SQObjectPtr &o2)
-{
- if(type(o1) != OT_TABLE) { Raise_Error(_SC("delegating a '%s'"), GetTypeName(o1)); return false; }
- switch(type(o2)) {
- case OT_TABLE:
- if(!_table(o1)->SetDelegate(_table(o2))){
- Raise_Error(_SC("delegate cycle detected"));
- return false;
- }
- break;
- case OT_NULL:
- _table(o1)->SetDelegate(NULL);
- break;
- default:
- Raise_Error(_SC("using '%s' as delegate"), GetTypeName(o2));
- return false;
- break;
- }
- trg = o1;
- return true;
-}
-#define COND_LITERAL (arg3!=0?ci->_literals[arg1]:STK(arg1))
-
-#define _GUARD(exp) { if(!exp) { Raise_Error(_lasterror); SQ_THROW();} }
-
-#define SQ_THROW() { goto exception_trap; }
-
-bool SQVM::CLOSURE_OP(SQObjectPtr &target, SQFunctionProto *func)
-{
- SQInteger nouters;
- SQClosure *closure = SQClosure::Create(_ss(this), func);
- if((nouters = func->_noutervalues)) {
- closure->_outervalues.reserve(nouters);
- for(SQInteger i = 0; i<nouters; i++) {
- SQOuterVar &v = func->_outervalues[i];
- switch(v._type){
- case otSYMBOL:
- closure->_outervalues.push_back(_null_);
- if(!Get(_stack._vals[_stackbase]/*STK(0)*/, v._src, closure->_outervalues.top(), false,true))
- {Raise_IdxError(v._src); return false; }
- break;
- case otLOCAL:
- closure->_outervalues.push_back(_stack._vals[_stackbase+_integer(v._src)]);
- break;
- case otOUTER:
- closure->_outervalues.push_back(_closure(ci->_closure)->_outervalues[_integer(v._src)]);
- break;
- }
- }
- }
- target = closure;
- return true;
-
-}
-
-bool SQVM::GETVARGV_OP(SQObjectPtr &target,SQObjectPtr &index,CallInfo *ci)
-{
- if(ci->_vargs.size == 0) {
- Raise_Error(_SC("the function doesn't have var args"));
- return false;
- }
- if(!sq_isnumeric(index)){
- Raise_Error(_SC("indexing 'vargv' with %s"),GetTypeName(index));
- return false;
- }
- SQInteger idx = tointeger(index);
- if(idx < 0 || idx >= ci->_vargs.size){ Raise_Error(_SC("vargv index out of range")); return false; }
- target = _vargsstack[ci->_vargs.base+idx];
- return true;
-}
-
-bool SQVM::CLASS_OP(SQObjectPtr &target,SQInteger baseclass,SQInteger attributes)
-{
- SQClass *base = NULL;
- SQObjectPtr attrs;
- if(baseclass != -1) {
- if(type(_stack._vals[_stackbase+baseclass]) != OT_CLASS) { Raise_Error(_SC("trying to inherit from a %s"),GetTypeName(_stack._vals[_stackbase+baseclass])); return false; }
- base = _class(_stack._vals[_stackbase + baseclass]);
- }
- if(attributes != MAX_FUNC_STACKSIZE) {
- attrs = _stack._vals[_stackbase+attributes];
- }
- target = SQClass::Create(_ss(this),base);
- if(type(_class(target)->_metamethods[MT_INHERITED]) != OT_NULL) {
- int nparams = 2;
- SQObjectPtr ret;
- Push(target); Push(attrs);
- Call(_class(target)->_metamethods[MT_INHERITED],nparams,_top - nparams, ret, false);
- Pop(nparams);
- }
- _class(target)->_attributes = attrs;
- return true;
-}
-
-
-
-bool SQVM::IsEqual(SQObjectPtr &o1,SQObjectPtr &o2,bool &res)
-{
- if(type(o1) == type(o2)) {
- res = ((_userpointer(o1) == _userpointer(o2)?true:false));
- }
- else {
- if(sq_isnumeric(o1) && sq_isnumeric(o2)) {
- SQInteger cmpres;
- if(!ObjCmp(o1, o2,cmpres)) return false;
- res = (cmpres == 0);
- }
- else {
- res = false;
- }
- }
- return true;
-}
-
-bool SQVM::IsFalse(SQObjectPtr &o)
-{
- if((type(o) & SQOBJECT_CANBEFALSE) && ( (type(o) == OT_FLOAT) && (_float(o) == SQFloat(0.0)) )
- || (_integer(o) == 0) ) { //OT_NULL|OT_INTEGER|OT_BOOL
- return true;
- }
- return false;
-}
-
-bool SQVM::GETPARENT_OP(SQObjectPtr &o,SQObjectPtr &target)
-{
- switch(type(o)) {
- case OT_TABLE: target = _table(o)->_delegate?SQObjectPtr(_table(o)->_delegate):_null_;
- break;
- case OT_CLASS: target = _class(o)->_base?_class(o)->_base:_null_;
- break;
- default:
- Raise_Error(_SC("the %s type doesn't have a parent slot"), GetTypeName(o));
- return false;
- }
- return true;
-}
-
-bool SQVM::Execute(SQObjectPtr &closure, SQInteger target, SQInteger nargs, SQInteger stackbase,SQObjectPtr &outres, SQBool raiseerror,ExecutionType et)
-{
- if ((_nnativecalls + 1) > MAX_NATIVE_CALLS) { Raise_Error(_SC("Native stack overflow")); return false; }
- _nnativecalls++;
- AutoDec ad(&_nnativecalls);
- SQInteger traps = 0;
- //temp_reg vars for OP_CALL
- SQInteger ct_target;
- SQInteger ct_stackbase;
- bool ct_tailcall;
-
- switch(et) {
- case ET_CALL:
- if(!StartCall(_closure(closure), _top - nargs, nargs, stackbase, false)) {
- //call the handler if there are no calls in the stack, if not relies on the previous node
- if(ci == NULL) CallErrorHandler(_lasterror);
- return false;
- }
- ci->_root = SQTrue;
- break;
- case ET_RESUME_GENERATOR: _generator(closure)->Resume(this, target); ci->_root = SQTrue; traps += ci->_etraps; break;
- case ET_RESUME_VM:
- traps = _suspended_traps;
- ci->_root = _suspended_root;
- ci->_vargs = _suspend_varargs;
- _suspended = SQFalse;
- break;
- }
-
-exception_restore:
- //
- {
- for(;;)
- {
- const SQInstruction &_i_ = *ci->_ip++;
- //dumpstack(_stackbase);
- //scprintf("\n[%d] %s %d %d %d %d\n",ci->_ip-ci->_iv->_vals,g_InstrDesc[_i_.op].name,arg0,arg1,arg2,arg3);
- switch(_i_.op)
- {
- case _OP_LINE:
- if(type(_debughook) != OT_NULL && _rawval(_debughook) != _rawval(ci->_closure))
- CallDebugHook(_SC('l'),arg1);
- continue;
- case _OP_LOAD: TARGET = ci->_literals[arg1]; continue;
- case _OP_LOADINT: TARGET = (SQInteger)arg1; continue;
- case _OP_LOADFLOAT: TARGET = *((SQFloat *)&arg1); continue;
- case _OP_DLOAD: TARGET = ci->_literals[arg1]; STK(arg2) = ci->_literals[arg3];continue;
- case _OP_TAILCALL:
- temp_reg = STK(arg1);
- if (type(temp_reg) == OT_CLOSURE){
- ct_tailcall = true;
- if(ci->_vargs.size) PopVarArgs(ci->_vargs);
- for (SQInteger i = 0; i < arg3; i++) STK(i) = STK(arg2 + i);
- ct_target = ci->_target;
- ct_stackbase = _stackbase;
- goto common_call;
- }
- case _OP_CALL: {
- ct_tailcall = false;
- ct_target = arg0;
- temp_reg = STK(arg1);
- ct_stackbase = _stackbase+arg2;
-
-common_call:
- SQInteger last_top = _top;
- switch (type(temp_reg)) {
- case OT_CLOSURE:{
- _GUARD(StartCall(_closure(temp_reg), ct_target, arg3, ct_stackbase, ct_tailcall));
- if (_funcproto(_closure(temp_reg)->_function)->_bgenerator) {
- SQGenerator *gen = SQGenerator::Create(_ss(this), _closure(temp_reg));
- _GUARD(gen->Yield(this));
- Return(1, ct_target, temp_reg);
-
-
-
-
- STK(ct_target) = gen;
- while (last_top >= _top) _stack._vals[last_top--].Null();
- continue;
- }
- if (type(_debughook) != OT_NULL && _rawval(_debughook) != _rawval(ci->_closure))
- CallDebugHook(_SC('c'));
- }
- continue;
- case OT_NATIVECLOSURE: {
- bool suspend;
- _GUARD(CallNative(_nativeclosure(temp_reg), arg3, ct_stackbase, temp_reg,suspend));
- if(suspend){
- _suspended = SQTrue;
- _suspended_target = ct_target;
- _suspended_root = ci->_root;
- _suspended_traps = traps;
- _suspend_varargs = ci->_vargs;
- outres = temp_reg;
- return true;
- }
- if(ct_target != -1) { //skip return value for constructors
- STK(ct_target) = temp_reg;
- }
- }
- continue;
- case OT_CLASS:{
- SQObjectPtr inst;
- _GUARD(CreateClassInstance(_class(temp_reg),inst,temp_reg));
- STK(ct_target) = inst;
- ct_target = -1; //fakes return value target so that is not overwritten by the constructor
- if(type(temp_reg) != OT_NULL) {
- _stack._vals[ct_stackbase] = inst;
- goto common_call; //hard core spaghetti code(reissues the OP_CALL to invoke the constructor)
- }
- }
- break;
- case OT_TABLE:
- case OT_USERDATA:
- case OT_INSTANCE:
- {
- Push(temp_reg);
- for (SQInteger i = 0; i < arg3; i++) Push(STK(arg2 + i));
- if (_delegable(temp_reg) && CallMetaMethod(_delegable(temp_reg), MT_CALL, arg3+1, temp_reg)){
- STK(ct_target) = temp_reg;
- break;
- }
- Raise_Error(_SC("attempt to call '%s'"), GetTypeName(temp_reg));
- SQ_THROW();
- }
- default:
- Raise_Error(_SC("attempt to call '%s'"), GetTypeName(temp_reg));
- SQ_THROW();
- }
- }
- continue;
- case _OP_PREPCALL:
- case _OP_PREPCALLK:
- {
- SQObjectPtr &key = _i_.op == _OP_PREPCALLK?(ci->_literals)[arg1]:STK(arg1);
- SQObjectPtr &o = STK(arg2);
- if (!Get(o, key, temp_reg,false,true)) {
- if(type(o) == OT_CLASS) { //hack?
- if(_class_ddel->Get(key,temp_reg)) {
- STK(arg3) = o;
- TARGET = temp_reg;
- continue;
- }
- }
- { Raise_IdxError(key); SQ_THROW();}
- }
-
- STK(arg3) = type(o) == OT_CLASS?STK(0):o;
- TARGET = temp_reg;
- }
- continue;
- case _OP_GETK:
- if (!Get(STK(arg2), ci->_literals[arg1], temp_reg, false,true)) { Raise_IdxError(ci->_literals[arg1]); SQ_THROW();}
- TARGET = temp_reg;
- continue;
- case _OP_MOVE: TARGET = STK(arg1); continue;
- case _OP_NEWSLOT:
- _GUARD(NewSlot(STK(arg1), STK(arg2), STK(arg3),false));
- if(arg0 != arg3) TARGET = STK(arg3);
- continue;
- case _OP_DELETE: _GUARD(DeleteSlot(STK(arg1), STK(arg2), TARGET)); continue;
- case _OP_SET:
- if (!Set(STK(arg1), STK(arg2), STK(arg3),true)) { Raise_IdxError(STK(arg2)); SQ_THROW(); }
- if (arg0 != arg3) TARGET = STK(arg3);
- continue;
- case _OP_GET:
- if (!Get(STK(arg1), STK(arg2), temp_reg, false,true)) { Raise_IdxError(STK(arg2)); SQ_THROW(); }
- TARGET = temp_reg;
- continue;
- case _OP_EQ:{
- bool res;
- if(!IsEqual(STK(arg2),COND_LITERAL,res)) { SQ_THROW(); }
- TARGET = res?_true_:_false_;
- }continue;
- case _OP_NE:{
- bool res;
- if(!IsEqual(STK(arg2),COND_LITERAL,res)) { SQ_THROW(); }
- TARGET = (!res)?_true_:_false_;
- } continue;
- case _OP_ARITH: _GUARD(ARITH_OP( arg3 , temp_reg, STK(arg2), STK(arg1))); TARGET = temp_reg; continue;
- case _OP_BITW: _GUARD(BW_OP( arg3,TARGET,STK(arg2),STK(arg1))); continue;
- case _OP_RETURN:
- if(type((ci)->_generator) == OT_GENERATOR) {
- _generator((ci)->_generator)->Kill();
- }
- if(Return(arg0, arg1, temp_reg)){
- assert(traps==0);
- outres = temp_reg;
- return true;
- }
- continue;
- case _OP_LOADNULLS:{ for(SQInt32 n=0; n < arg1; n++) STK(arg0+n) = _null_; }continue;
- case _OP_LOADROOTTABLE: TARGET = _roottable; continue;
- case _OP_LOADBOOL: TARGET = arg1?_true_:_false_; continue;
- case _OP_DMOVE: STK(arg0) = STK(arg1); STK(arg2) = STK(arg3); continue;
- case _OP_JMP: ci->_ip += (sarg1); continue;
- case _OP_JNZ: if(!IsFalse(STK(arg0))) ci->_ip+=(sarg1); continue;
- case _OP_JZ: if(IsFalse(STK(arg0))) ci->_ip+=(sarg1); continue;
- case _OP_LOADFREEVAR: TARGET = _closure(ci->_closure)->_outervalues[arg1]; continue;
- case _OP_VARGC: TARGET = SQInteger(ci->_vargs.size); continue;
- case _OP_GETVARGV:
- if(!GETVARGV_OP(TARGET,STK(arg1),ci)) { SQ_THROW(); }
- continue;
- case _OP_NEWTABLE: TARGET = SQTable::Create(_ss(this), arg1); continue;
- case _OP_NEWARRAY: TARGET = SQArray::Create(_ss(this), 0); _array(TARGET)->Reserve(arg1); continue;
- case _OP_APPENDARRAY: _array(STK(arg0))->Append(COND_LITERAL); continue;
- case _OP_GETPARENT: _GUARD(GETPARENT_OP(STK(arg1),TARGET)); continue;
- case _OP_COMPARITH: _GUARD(DerefInc(arg3, TARGET, STK((((SQUnsignedInteger)arg1&0xFFFF0000)>>16)), STK(arg2), STK(arg1&0x0000FFFF), false)); continue;
- case _OP_COMPARITHL: _GUARD(LOCAL_INC(arg3, TARGET, STK(arg1), STK(arg2))); continue;
- case _OP_INC: {SQObjectPtr o(sarg3); _GUARD(DerefInc('+',TARGET, STK(arg1), STK(arg2), o, false));} continue;
- case _OP_INCL: {SQObjectPtr o(sarg3); _GUARD(LOCAL_INC('+',TARGET, STK(arg1), o));} continue;
- case _OP_PINC: {SQObjectPtr o(sarg3); _GUARD(DerefInc('+',TARGET, STK(arg1), STK(arg2), o, true));} continue;
- case _OP_PINCL: {SQObjectPtr o(sarg3); _GUARD(PLOCAL_INC('+',TARGET, STK(arg1), o));} continue;
- case _OP_CMP: _GUARD(CMP_OP((CmpOP)arg3,STK(arg2),STK(arg1),TARGET)) continue;
- case _OP_EXISTS: TARGET = Get(STK(arg1), STK(arg2), temp_reg, true,false)?_true_:_false_;continue;
- case _OP_INSTANCEOF:
- if(type(STK(arg1)) != OT_CLASS || type(STK(arg2)) != OT_INSTANCE)
- {Raise_Error(_SC("cannot apply instanceof between a %s and a %s"),GetTypeName(STK(arg1)),GetTypeName(STK(arg2))); SQ_THROW();}
- TARGET = _instance(STK(arg2))->InstanceOf(_class(STK(arg1)))?_true_:_false_;
- continue;
- case _OP_AND:
- if(IsFalse(STK(arg2))) {
- TARGET = STK(arg2);
- ci->_ip += (sarg1);
- }
- continue;
- case _OP_OR:
- if(!IsFalse(STK(arg2))) {
- TARGET = STK(arg2);
- ci->_ip += (sarg1);
- }
- continue;
- case _OP_NEG: _GUARD(NEG_OP(TARGET,STK(arg1))); continue;
- case _OP_NOT: TARGET = (IsFalse(STK(arg1))?_true_:_false_); continue;
- case _OP_BWNOT:
- if(type(STK(arg1)) == OT_INTEGER) {
- SQInteger t = _integer(STK(arg1));
- TARGET = SQInteger(~t);
- continue;
- }
- Raise_Error(_SC("attempt to perform a bitwise op on a %s"), GetTypeName(STK(arg1)));
- SQ_THROW();
- case _OP_CLOSURE: {
- SQClosure *c = ci->_closure._unVal.pClosure;
- SQFunctionProto *fp = c->_function._unVal.pFunctionProto;
- if(!CLOSURE_OP(TARGET,fp->_functions[arg1]._unVal.pFunctionProto)) { SQ_THROW(); }
- continue;
- }
- case _OP_YIELD:{
- if(type(ci->_generator) == OT_GENERATOR) {
- if(sarg1 != MAX_FUNC_STACKSIZE) temp_reg = STK(arg1);
- _GUARD(_generator(ci->_generator)->Yield(this));
- traps -= ci->_etraps;
- if(sarg1 != MAX_FUNC_STACKSIZE) STK(arg1) = temp_reg;
- }
- else { Raise_Error(_SC("trying to yield a '%s',only genenerator can be yielded"), GetTypeName(ci->_generator)); SQ_THROW();}
- if(Return(arg0, arg1, temp_reg)){
- assert(traps == 0);
- outres = temp_reg;
- return true;
- }
-
- }
- continue;
- case _OP_RESUME:
- if(type(STK(arg1)) != OT_GENERATOR){ Raise_Error(_SC("trying to resume a '%s',only genenerator can be resumed"), GetTypeName(STK(arg1))); SQ_THROW();}
- _GUARD(_generator(STK(arg1))->Resume(this, arg0));
- traps += ci->_etraps;
- continue;
- case _OP_FOREACH:{ int tojump;
- _GUARD(FOREACH_OP(STK(arg0),STK(arg2),STK(arg2+1),STK(arg2+2),arg2,sarg1,tojump));
- ci->_ip += tojump; }
- continue;
- case _OP_POSTFOREACH:
- assert(type(STK(arg0)) == OT_GENERATOR);
- if(_generator(STK(arg0))->_state == SQGenerator::eDead)
- ci->_ip += (sarg1 - 1);
- continue;
- case _OP_DELEGATE: _GUARD(DELEGATE_OP(TARGET,STK(arg1),STK(arg2))); continue;
- case _OP_CLONE:
- if(!Clone(STK(arg1), TARGET))
- { Raise_Error(_SC("cloning a %s"), GetTypeName(STK(arg1))); SQ_THROW();}
- continue;
- case _OP_TYPEOF: TypeOf(STK(arg1), TARGET); continue;
- case _OP_PUSHTRAP:{
- SQInstruction *_iv = _funcproto(_closure(ci->_closure)->_function)->_instructions;
- _etraps.push_back(SQExceptionTrap(_top,_stackbase, &_iv[(ci->_ip-_iv)+arg1], arg0)); traps++;
- ci->_etraps++;
- }
- continue;
- case _OP_POPTRAP: {
- for(SQInteger i = 0; i < arg0; i++) {
- _etraps.pop_back(); traps--;
- ci->_etraps--;
- }
- }
- continue;
- case _OP_THROW: Raise_Error(TARGET); SQ_THROW(); continue;
- case _OP_CLASS: _GUARD(CLASS_OP(TARGET,arg1,arg2)); continue;
- case _OP_NEWSLOTA:
- bool bstatic = (arg0&NEW_SLOT_STATIC_FLAG)?true:false;
- if(type(STK(arg1)) == OT_CLASS) {
- if(type(_class(STK(arg1))->_metamethods[MT_NEWMEMBER]) != OT_NULL ) {
- Push(STK(arg1)); Push(STK(arg2)); Push(STK(arg3));
- Push((arg0&NEW_SLOT_ATTRIBUTES_FLAG) ? STK(arg2-1) : _null_);
- int nparams = 4;
- if(Call(_class(STK(arg1))->_metamethods[MT_NEWMEMBER], nparams, _top - nparams, temp_reg,SQFalse)) {
- Pop(nparams);
- continue;
- }
- }
- }
- _GUARD(NewSlot(STK(arg1), STK(arg2), STK(arg3),bstatic));
- if((arg0&NEW_SLOT_ATTRIBUTES_FLAG)) {
- _class(STK(arg1))->SetAttributes(STK(arg2),STK(arg2-1));
- }
- continue;
- }
-
- }
- }
-exception_trap:
- {
- SQObjectPtr currerror = _lasterror;
-// dumpstack(_stackbase);
- SQInteger n = 0;
- SQInteger last_top = _top;
- if(ci) {
- if(_ss(this)->_notifyallexceptions) CallErrorHandler(currerror);
-
- if(traps) {
- do {
- if(ci->_etraps > 0) {
- SQExceptionTrap &et = _etraps.top();
- ci->_ip = et._ip;
- _top = et._stacksize;
- _stackbase = et._stackbase;
- _stack._vals[_stackbase+et._extarget] = currerror;
- _etraps.pop_back(); traps--; ci->_etraps--;
- while(last_top >= _top) _stack._vals[last_top--].Null();
- goto exception_restore;
- }
- //if is a native closure
- if(type(ci->_closure) != OT_CLOSURE && n)
- break;
- if(type(ci->_generator) == OT_GENERATOR) _generator(ci->_generator)->Kill();
- PopVarArgs(ci->_vargs);
- POP_CALLINFO(this);
- n++;
- } while(_callsstacksize);
- }
- else {
- //call the hook
- if(raiseerror && !_ss(this)->_notifyallexceptions)
- CallErrorHandler(currerror);
- }
- //remove call stack until a C function is found or the cstack is empty
- if(ci) do {
- SQBool exitafterthisone = ci->_root;
- if(type(ci->_generator) == OT_GENERATOR) _generator(ci->_generator)->Kill();
- _stackbase -= ci->_prevstkbase;
- _top = _stackbase + ci->_prevtop;
- PopVarArgs(ci->_vargs);
- POP_CALLINFO(this);
- if( (ci && type(ci->_closure) != OT_CLOSURE) || exitafterthisone) break;
- } while(_callsstacksize);
-
- while(last_top >= _top) _stack._vals[last_top--].Null();
- }
- _lasterror = currerror;
- return false;
- }
- assert(0);
-}
-
-bool SQVM::CreateClassInstance(SQClass *theclass, SQObjectPtr &inst, SQObjectPtr &constructor)
-{
- inst = theclass->CreateInstance();
- if(!theclass->Get(_ss(this)->_constructoridx,constructor)) {
- //if(!Call(constr,nargs,stackbase,constr,false))
- // return false;
- constructor = _null_;
- }
- return true;
-}
-
-void SQVM::CallErrorHandler(SQObjectPtr &error)
-{
- if(type(_errorhandler) != OT_NULL) {
- SQObjectPtr out;
- Push(_roottable); Push(error);
- Call(_errorhandler, 2, _top-2, out,SQFalse);
- Pop(2);
- }
-}
-
-void SQVM::CallDebugHook(SQInteger type,SQInteger forcedline)
-{
- SQObjectPtr temp_reg;
- SQInteger nparams=5;
- SQFunctionProto *func=_funcproto(_closure(ci->_closure)->_function);
- Push(_roottable); Push(type); Push(func->_sourcename); Push(forcedline?forcedline:func->GetLine(ci->_ip)); Push(func->_name);
- Call(_debughook,nparams,_top-nparams,temp_reg,SQFalse);
- Pop(nparams);
-}
-
-bool SQVM::CallNative(SQNativeClosure *nclosure,SQInteger nargs,SQInteger stackbase,SQObjectPtr &retval,bool &suspend)
-{
- if (_nnativecalls + 1 > MAX_NATIVE_CALLS) { Raise_Error(_SC("Native stack overflow")); return false; }
- SQInteger nparamscheck = nclosure->_nparamscheck;
- if(((nparamscheck > 0) && (nparamscheck != nargs))
- || ((nparamscheck < 0) && (nargs < (-nparamscheck)))) {
- Raise_Error(_SC("wrong number of parameters"));
- return false;
- }
-
- SQInteger tcs;
- if((tcs = nclosure->_typecheck.size())) {
- for(SQInteger i = 0; i < nargs && i < tcs; i++)
- if((nclosure->_typecheck._vals[i] != -1) && !(type(_stack._vals[stackbase+i]) & nclosure->_typecheck[i])) {
- Raise_ParamTypeError(i,nclosure->_typecheck._vals[i],type(_stack._vals[stackbase+i]));
- return false;
- }
- }
- _nnativecalls++;
- if ((_top + MIN_STACK_OVERHEAD) > (SQInteger)_stack.size()) {
- _stack.resize(_stack.size() + (MIN_STACK_OVERHEAD<<1));
- }
- SQInteger oldtop = _top;
- SQInteger oldstackbase = _stackbase;
- _top = stackbase + nargs;
- CallInfo lci;
- lci._etraps = 0;
- lci._closure._unVal.pNativeClosure = nclosure;
- lci._closure._type = OT_NATIVECLOSURE;
- lci._prevstkbase = (SQInt32) (stackbase - _stackbase);
- lci._ncalls = 1;
- lci._prevtop = (SQInt32) (oldtop - oldstackbase);
- PUSH_CALLINFO(this, lci);
- _stackbase = stackbase;
- //push free variables
- SQInteger outers = nclosure->_outervalues.size();
- for (SQInteger i = 0; i < outers; i++) {
- Push(nclosure->_outervalues[i]);
- }
-
- if(type(nclosure->_env) == OT_WEAKREF) {
- _stack[stackbase] = _weakref(nclosure->_env)->_obj;
- }
-
-
- SQInteger ret = (nclosure->_function)(this);
- _nnativecalls--;
- suspend = false;
- if( ret == SQ_SUSPEND_FLAG) suspend = true;
- else if (ret < 0) {
- _stackbase = oldstackbase;
- _top = oldtop;
- POP_CALLINFO(this);
- Raise_Error(_lasterror);
- return false;
- }
-
- if (ret != 0){ retval = TOP(); }
- else { retval = _null_; }
- _stackbase = oldstackbase;
- _top = oldtop;
- POP_CALLINFO(this);
- return true;
-}
-
-bool SQVM::Get(const SQObjectPtr &self,const SQObjectPtr &key,SQObjectPtr &dest,bool raw, bool fetchroot)
-{
- switch(type(self)){
- case OT_TABLE:
- if(_table(self)->Get(key,dest))return true;
- break;
- case OT_ARRAY:
- if(sq_isnumeric(key)){
- return _array(self)->Get(tointeger(key),dest);
- }
- break;
- case OT_INSTANCE:
- if(_instance(self)->Get(key,dest)) return true;
- break;
- default:break; //shut up compiler
- }
- if(FallBackGet(self,key,dest,raw)) return true;
-
- if(fetchroot) {
- if(_rawval(STK(0)) == _rawval(self) &&
- type(STK(0)) == type(self)) {
- return _table(_roottable)->Get(key,dest);
- }
- }
- return false;
-}
-
-bool SQVM::FallBackGet(const SQObjectPtr &self,const SQObjectPtr &key,SQObjectPtr &dest,bool raw)
-{
- switch(type(self)){
- case OT_CLASS:
- return _class(self)->Get(key,dest);
- break;
- case OT_TABLE:
- case OT_USERDATA:
- //delegation
- if(_delegable(self)->_delegate) {
- if(Get(SQObjectPtr(_delegable(self)->_delegate),key,dest,raw,false))
- return true;
- if(raw)return false;
- Push(self);Push(key);
- if(CallMetaMethod(_delegable(self),MT_GET,2,dest))
- return true;
- }
- if(type(self) == OT_TABLE) {
- if(raw) return false;
- return _table_ddel->Get(key,dest);
- }
- return false;
- break;
- case OT_ARRAY:
- if(raw)return false;
- return _array_ddel->Get(key,dest);
- case OT_STRING:
- if(sq_isnumeric(key)){
- SQInteger n=tointeger(key);
- if(abs((int)n)<_string(self)->_len){
- if(n<0)n=_string(self)->_len-n;
- dest=SQInteger(_stringval(self)[n]);
- return true;
- }
- return false;
- }
- else {
- if(raw)return false;
- return _string_ddel->Get(key,dest);
- }
- break;
- case OT_INSTANCE:
- if(raw)return false;
- Push(self);Push(key);
- if(!CallMetaMethod(_delegable(self),MT_GET,2,dest)) {
- return _instance_ddel->Get(key,dest);
- }
- return true;
- case OT_INTEGER:case OT_FLOAT:case OT_BOOL:
- if(raw)return false;
- return _number_ddel->Get(key,dest);
- case OT_GENERATOR:
- if(raw)return false;
- return _generator_ddel->Get(key,dest);
- case OT_CLOSURE: case OT_NATIVECLOSURE:
- if(raw)return false;
- return _closure_ddel->Get(key,dest);
- case OT_THREAD:
- if(raw)return false;
- return _thread_ddel->Get(key,dest);
- case OT_WEAKREF:
- if(raw)return false;
- return _weakref_ddel->Get(key,dest);
- default:return false;
- }
- return false;
-}
-
-bool SQVM::Set(const SQObjectPtr &self,const SQObjectPtr &key,const SQObjectPtr &val,bool fetchroot)
-{
- switch(type(self)){
- case OT_TABLE:
- if(_table(self)->Set(key,val))
- return true;
- if(_table(self)->_delegate) {
- if(Set(_table(self)->_delegate,key,val,false)) {
- return true;
- }
- }
- //keeps going
- case OT_USERDATA:
- if(_delegable(self)->_delegate) {
- SQObjectPtr t;
- Push(self);Push(key);Push(val);
- if(CallMetaMethod(_delegable(self),MT_SET,3,t)) return true;
- }
- break;
- case OT_INSTANCE:{
- if(_instance(self)->Set(key,val))
- return true;
- SQObjectPtr t;
- Push(self);Push(key);Push(val);
- if(CallMetaMethod(_delegable(self),MT_SET,3,t)) return true;
- }
- break;
- case OT_ARRAY:
- if(!sq_isnumeric(key)) {Raise_Error(_SC("indexing %s with %s"),GetTypeName(self),GetTypeName(key)); return false; }
- return _array(self)->Set(tointeger(key),val);
- default:
- Raise_Error(_SC("trying to set '%s'"),GetTypeName(self));
- return false;
- }
- if(fetchroot) {
- if(_rawval(STK(0)) == _rawval(self) &&
- type(STK(0)) == type(self)) {
- return _table(_roottable)->Set(key,val);
- }
- }
- return false;
-}
-
-bool SQVM::Clone(const SQObjectPtr &self,SQObjectPtr &target)
-{
- SQObjectPtr temp_reg;
- SQObjectPtr newobj;
- switch(type(self)){
- case OT_TABLE:
- newobj = _table(self)->Clone();
- goto cloned_mt;
- case OT_INSTANCE:
- newobj = _instance(self)->Clone(_ss(this));
-cloned_mt:
- if(_delegable(newobj)->_delegate){
- Push(newobj);
- Push(self);
- CallMetaMethod(_delegable(newobj),MT_CLONED,2,temp_reg);
- }
- target = newobj;
- return true;
- case OT_ARRAY:
- target = _array(self)->Clone();
- return true;
- default: return false;
- }
-}
-
-bool SQVM::NewSlot(const SQObjectPtr &self,const SQObjectPtr &key,const SQObjectPtr &val,bool bstatic)
-{
- if(type(key) == OT_NULL) { Raise_Error(_SC("null cannot be used as index")); return false; }
- switch(type(self)) {
- case OT_TABLE: {
- bool rawcall = true;
- if(_table(self)->_delegate) {
- SQObjectPtr res;
- if(!_table(self)->Get(key,res)) {
- Push(self);Push(key);Push(val);
- rawcall = !CallMetaMethod(_table(self),MT_NEWSLOT,3,res);
- }
- }
- if(rawcall) _table(self)->NewSlot(key,val); //cannot fail
-
- break;}
- case OT_CLASS:
- if(!_class(self)->NewSlot(_ss(this),key,val,bstatic)) {
- if(_class(self)->_locked) {
- Raise_Error(_SC("trying to modify a class that has already been instantiated"));
- return false;
- }
- else {
- SQObjectPtr oval = PrintObjVal(key);
- Raise_Error(_SC("the property '%s' already exists"),_stringval(oval));
- return false;
- }
- }
- break;
- default:
- Raise_Error(_SC("indexing %s with %s"),GetTypeName(self),GetTypeName(key));
- return false;
- break;
- }
- return true;
-}
-
-bool SQVM::DeleteSlot(const SQObjectPtr &self,const SQObjectPtr &key,SQObjectPtr &res)
-{
- switch(type(self)) {
- case OT_TABLE:
- case OT_INSTANCE:
- case OT_USERDATA: {
- SQObjectPtr t;
- bool handled = false;
- if(_delegable(self)->_delegate) {
- Push(self);Push(key);
- handled = CallMetaMethod(_delegable(self),MT_DELSLOT,2,t);
- }
-
- if(!handled) {
- if(type(self) == OT_TABLE) {
- if(_table(self)->Get(key,t)) {
- _table(self)->Remove(key);
- }
- else {
- Raise_IdxError((SQObject &)key);
- return false;
- }
- }
- else {
- Raise_Error(_SC("cannot delete a slot from %s"),GetTypeName(self));
- return false;
- }
- }
- res = t;
- }
- break;
- default:
- Raise_Error(_SC("attempt to delete a slot from a %s"),GetTypeName(self));
- return false;
- }
- return true;
-}
-
-bool SQVM::Call(SQObjectPtr &closure,SQInteger nparams,SQInteger stackbase,SQObjectPtr &outres,SQBool raiseerror)
-{
-#ifdef _DEBUG
-SQInteger prevstackbase = _stackbase;
-#endif
- switch(type(closure)) {
- case OT_CLOSURE:
- return Execute(closure, _top - nparams, nparams, stackbase,outres,raiseerror);
- break;
- case OT_NATIVECLOSURE:{
- bool suspend;
- return CallNative(_nativeclosure(closure), nparams, stackbase, outres,suspend);
-
- }
- break;
- case OT_CLASS: {
- SQObjectPtr constr;
- SQObjectPtr temp;
- CreateClassInstance(_class(closure),outres,constr);
- if(type(constr) != OT_NULL) {
- _stack[stackbase] = outres;
- return Call(constr,nparams,stackbase,temp,raiseerror);
- }
- return true;
- }
- break;
- default:
- return false;
- }
-#ifdef _DEBUG
- if(!_suspended) {
- assert(_stackbase == prevstackbase);
- }
-#endif
- return true;
-}
-
-bool SQVM::CallMetaMethod(SQDelegable *del,SQMetaMethod mm,SQInteger nparams,SQObjectPtr &outres)
-{
- SQObjectPtr closure;
- if(del->GetMetaMethod(this, mm, closure)) {
- if(Call(closure, nparams, _top - nparams, outres, SQFalse)) {
- Pop(nparams);
- return true;
- }
- }
- Pop(nparams);
- return false;
-}
-
-void SQVM::Remove(SQInteger n) {
- n = (n >= 0)?n + _stackbase - 1:_top + n;
- for(SQInteger i = n; i < _top; i++){
- _stack[i] = _stack[i+1];
- }
- _stack[_top] = _null_;
- _top--;
-}
-
-void SQVM::Pop() {
- _stack[--_top] = _null_;
-}
-
-void SQVM::Pop(SQInteger n) {
- for(SQInteger i = 0; i < n; i++){
- _stack[--_top] = _null_;
- }
-}
-
-void SQVM::Push(const SQObjectPtr &o) { _stack[_top++] = o; }
-SQObjectPtr &SQVM::Top() { return _stack[_top-1]; }
-SQObjectPtr &SQVM::PopGet() { return _stack[--_top]; }
-SQObjectPtr &SQVM::GetUp(SQInteger n) { return _stack[_top+n]; }
-SQObjectPtr &SQVM::GetAt(SQInteger n) { return _stack[n]; }
-
-#ifdef _DEBUG_DUMP
-void SQVM::dumpstack(SQInteger stackbase,bool dumpall)
-{
- SQInteger size=dumpall?_stack.size():_top;
- SQInteger n=0;
- scprintf(_SC("\n>>>>stack dump<<<<\n"));
- CallInfo &ci=_callsstack[_callsstacksize-1];
- scprintf(_SC("IP: %p\n"),ci._ip);
- scprintf(_SC("prev stack base: %d\n"),ci._prevstkbase);
- scprintf(_SC("prev top: %d\n"),ci._prevtop);
- for(SQInteger i=0;i<size;i++){
- SQObjectPtr &obj=_stack[i];
- if(stackbase==i)scprintf(_SC(">"));else scprintf(_SC(" "));
- scprintf(_SC("[%d]:"),n);
- switch(type(obj)){
- case OT_FLOAT: scprintf(_SC("FLOAT %.3f"),_float(obj));break;
- case OT_INTEGER: scprintf(_SC("INTEGER %d"),_integer(obj));break;
- case OT_BOOL: scprintf(_SC("BOOL %s"),_integer(obj)?"true":"false");break;
- case OT_STRING: scprintf(_SC("STRING %s"),_stringval(obj));break;
- case OT_NULL: scprintf(_SC("NULL")); break;
- case OT_TABLE: scprintf(_SC("TABLE %p[%p]"),_table(obj),_table(obj)->_delegate);break;
- case OT_ARRAY: scprintf(_SC("ARRAY %p"),_array(obj));break;
- case OT_CLOSURE: scprintf(_SC("CLOSURE [%p]"),_closure(obj));break;
- case OT_NATIVECLOSURE: scprintf(_SC("NATIVECLOSURE"));break;
- case OT_USERDATA: scprintf(_SC("USERDATA %p[%p]"),_userdataval(obj),_userdata(obj)->_delegate);break;
- case OT_GENERATOR: scprintf(_SC("GENERATOR"));break;
- case OT_THREAD: scprintf(_SC("THREAD [%p]"),_thread(obj));break;
- case OT_USERPOINTER: scprintf(_SC("USERPOINTER %p"),_userpointer(obj));break;
- case OT_CLASS: scprintf(_SC("CLASS %p"),_class(obj));break;
- case OT_INSTANCE: scprintf(_SC("INSTANCE %p"),_instance(obj));break;
- case OT_WEAKREF: scprintf(_SC("WEAKERF %p"),_weakref(obj));break;
- default:
- assert(0);
- break;
- };
- scprintf(_SC("\n"));
- ++n;
- }
-}
-
-
-
-#endif
+++ /dev/null
-/* see copyright notice in squirrel.h */
-#ifndef _SQVM_H_
-#define _SQVM_H_
-
-#include "sqopcodes.h"
-#include "sqobject.h"
-#define MAX_NATIVE_CALLS 100
-#define MIN_STACK_OVERHEAD 10
-
-#define SQ_SUSPEND_FLAG -666
-//base lib
-void sq_base_register(HSQUIRRELVM v);
-
-struct SQExceptionTrap{
- SQExceptionTrap() {}
- SQExceptionTrap(SQInteger ss, SQInteger stackbase,SQInstruction *ip, SQInteger ex_target){ _stacksize = ss; _stackbase = stackbase; _ip = ip; _extarget = ex_target;}
- SQExceptionTrap(const SQExceptionTrap &et) { (*this) = et; }
- SQInteger _stackbase;
- SQInteger _stacksize;
- SQInstruction *_ip;
- SQInteger _extarget;
-};
-
-#define _INLINE
-
-#define STK(a) _stack._vals[_stackbase+(a)]
-#define TARGET _stack._vals[_stackbase+arg0]
-
-typedef sqvector<SQExceptionTrap> ExceptionsTraps;
-
-struct SQVM : public CHAINABLE_OBJ
-{
- struct VarArgs {
- VarArgs() { size = 0; base = 0; }
- unsigned short size;
- unsigned short base;
- };
-
- struct CallInfo{
- CallInfo() { _generator._type = OT_NULL;}
- SQInstruction *_ip;
- SQObjectPtr *_literals;
- SQObject _closure;
- SQObject _generator;
- SQInt32 _etraps;
- SQInt32 _prevstkbase;
- SQInt32 _prevtop;
- SQInt32 _target;
- SQInt32 _ncalls;
- SQBool _root;
- VarArgs _vargs;
- };
-
-typedef sqvector<CallInfo> CallInfoVec;
-public:
- enum ExecutionType { ET_CALL, ET_RESUME_GENERATOR, ET_RESUME_VM };
- SQVM(SQSharedState *ss);
- ~SQVM();
- bool Init(SQVM *friendvm, SQInteger stacksize);
- bool Execute(SQObjectPtr &func, SQInteger target, SQInteger nargs, SQInteger stackbase, SQObjectPtr &outres, SQBool raiseerror, ExecutionType et = ET_CALL);
- //starts a native call return when the NATIVE closure returns
- bool CallNative(SQNativeClosure *nclosure, SQInteger nargs, SQInteger stackbase, SQObjectPtr &retval,bool &suspend);
- //starts a SQUIRREL call in the same "Execution loop"
- bool StartCall(SQClosure *closure, SQInteger target, SQInteger nargs, SQInteger stackbase, bool tailcall);
- bool CreateClassInstance(SQClass *theclass, SQObjectPtr &inst, SQObjectPtr &constructor);
- //call a generic closure pure SQUIRREL or NATIVE
- bool Call(SQObjectPtr &closure, SQInteger nparams, SQInteger stackbase, SQObjectPtr &outres,SQBool raiseerror);
- SQRESULT Suspend();
-
- void CallDebugHook(SQInteger type,SQInteger forcedline=0);
- void CallErrorHandler(SQObjectPtr &e);
- bool Get(const SQObjectPtr &self, const SQObjectPtr &key, SQObjectPtr &dest, bool raw, bool fetchroot);
- bool FallBackGet(const SQObjectPtr &self,const SQObjectPtr &key,SQObjectPtr &dest,bool raw);
- bool Set(const SQObjectPtr &self, const SQObjectPtr &key, const SQObjectPtr &val, bool fetchroot);
- bool NewSlot(const SQObjectPtr &self, const SQObjectPtr &key, const SQObjectPtr &val,bool bstatic);
- bool DeleteSlot(const SQObjectPtr &self, const SQObjectPtr &key, SQObjectPtr &res);
- bool Clone(const SQObjectPtr &self, SQObjectPtr &target);
- bool ObjCmp(const SQObjectPtr &o1, const SQObjectPtr &o2,SQInteger &res);
- bool StringCat(const SQObjectPtr &str, const SQObjectPtr &obj, SQObjectPtr &dest);
- bool IsEqual(SQObjectPtr &o1,SQObjectPtr &o2,bool &res);
- void ToString(const SQObjectPtr &o,SQObjectPtr &res);
- SQString *PrintObjVal(const SQObject &o);
-
-
- void Raise_Error(const SQChar *s, ...);
- void Raise_Error(SQObjectPtr &desc);
- void Raise_IdxError(SQObject &o);
- void Raise_CompareError(const SQObject &o1, const SQObject &o2);
- void Raise_ParamTypeError(SQInteger nparam,SQInteger typemask,SQInteger type);
-
- void TypeOf(const SQObjectPtr &obj1, SQObjectPtr &dest);
- bool CallMetaMethod(SQDelegable *del, SQMetaMethod mm, SQInteger nparams, SQObjectPtr &outres);
- bool ArithMetaMethod(SQInteger op, const SQObjectPtr &o1, const SQObjectPtr &o2, SQObjectPtr &dest);
- bool Return(SQInteger _arg0, SQInteger _arg1, SQObjectPtr &retval);
- //new stuff
- _INLINE bool ARITH_OP(SQUnsignedInteger op,SQObjectPtr &trg,const SQObjectPtr &o1,const SQObjectPtr &o2);
- _INLINE bool BW_OP(SQUnsignedInteger op,SQObjectPtr &trg,const SQObjectPtr &o1,const SQObjectPtr &o2);
- _INLINE bool NEG_OP(SQObjectPtr &trg,const SQObjectPtr &o1);
- _INLINE bool CMP_OP(CmpOP op, const SQObjectPtr &o1,const SQObjectPtr &o2,SQObjectPtr &res);
- bool CLOSURE_OP(SQObjectPtr &target, SQFunctionProto *func);
- bool GETVARGV_OP(SQObjectPtr &target,SQObjectPtr &idx,CallInfo *ci);
- bool CLASS_OP(SQObjectPtr &target,SQInteger base,SQInteger attrs);
- bool GETPARENT_OP(SQObjectPtr &o,SQObjectPtr &target);
- //return true if the loop is finished
- bool FOREACH_OP(SQObjectPtr &o1,SQObjectPtr &o2,SQObjectPtr &o3,SQObjectPtr &o4,SQInteger arg_2,int exitpos,int &jump);
- bool DELEGATE_OP(SQObjectPtr &trg,SQObjectPtr &o1,SQObjectPtr &o2);
- _INLINE bool LOCAL_INC(SQInteger op,SQObjectPtr &target, SQObjectPtr &a, SQObjectPtr &incr);
- _INLINE bool PLOCAL_INC(SQInteger op,SQObjectPtr &target, SQObjectPtr &a, SQObjectPtr &incr);
- _INLINE bool DerefInc(SQInteger op,SQObjectPtr &target, SQObjectPtr &self, SQObjectPtr &key, SQObjectPtr &incr, bool postfix);
- void PopVarArgs(VarArgs &vargs);
-#ifdef _DEBUG_DUMP
- void dumpstack(SQInteger stackbase=-1, bool dumpall = false);
-#endif
-
-#ifndef NO_GARBAGE_COLLECTOR
- void Mark(SQCollectable **chain);
-#endif
- void Finalize();
- void GrowCallStack() {
- SQInteger newsize = _alloccallsstacksize*2;
- _callsstack = (CallInfo*)sq_realloc(_callsstack,_alloccallsstacksize*sizeof(CallInfo),newsize*sizeof(CallInfo));
- _alloccallsstacksize = newsize;
- }
- void Release(){ sq_delete(this,SQVM); } //does nothing
-////////////////////////////////////////////////////////////////////////////
- //stack functions for the api
- void Remove(SQInteger n);
-
- bool IsFalse(SQObjectPtr &o);
-
- void Pop();
- void Pop(SQInteger n);
- void Push(const SQObjectPtr &o);
- SQObjectPtr &Top();
- SQObjectPtr &PopGet();
- SQObjectPtr &GetUp(SQInteger n);
- SQObjectPtr &GetAt(SQInteger n);
-
- SQObjectPtrVec _stack;
- SQObjectPtrVec _vargsstack;
- SQInteger _top;
- SQInteger _stackbase;
- SQObjectPtr _roottable;
- SQObjectPtr _lasterror;
- SQObjectPtr _errorhandler;
- SQObjectPtr _debughook;
-
- SQObjectPtr temp_reg;
-
-
- CallInfo* _callsstack;
- SQInteger _callsstacksize;
- SQInteger _alloccallsstacksize;
-
- ExceptionsTraps _etraps;
- CallInfo *ci;
- void *_foreignptr;
- //VMs sharing the same state
- SQSharedState *_sharedstate;
- SQInteger _nnativecalls;
- //suspend infos
- SQBool _suspended;
- SQBool _suspended_root;
- SQInteger _suspended_target;
- SQInteger _suspended_traps;
- VarArgs _suspend_varargs;
-};
-
-struct AutoDec{
- AutoDec(SQInteger *n) { _n = n; }
- ~AutoDec() { (*_n)--; }
- SQInteger *_n;
-};
-
-inline SQObjectPtr &stack_get(HSQUIRRELVM v,SQInteger idx){return ((idx>=0)?(v->GetAt(idx+v->_stackbase-1)):(v->GetUp(idx)));}
-const SQChar *GetTypeName(const SQObjectPtr &obj1);
-const SQChar *IdType2Name(SQObjectType type);
-
-#define _ss(_vm_) (_vm_)->_sharedstate
-
-#ifndef NO_GARBAGE_COLLECTOR
-#define _opt_ss(_vm_) (_vm_)->_sharedstate
-#else
-#define _opt_ss(_vm_) NULL
-#endif
-
-#define PUSH_CALLINFO(v,nci){ \
- if(v->_callsstacksize == v->_alloccallsstacksize) { \
- v->GrowCallStack(); \
- } \
- v->ci = &v->_callsstack[v->_callsstacksize]; \
- *(v->ci) = nci; \
- v->_callsstacksize++; \
-}
-
-#define POP_CALLINFO(v){ \
- v->_callsstacksize--; \
- if(v->_callsstacksize) \
- v->ci = &v->_callsstack[v->_callsstacksize-1] ; \
- else \
- v->ci = NULL; \
-}
-#endif //_SQVM_H_
+++ /dev/null
-SubDir TOP src ;
-
-SubInclude TOP src squirrel ;
-SubInclude TOP src scripting ;
-
-sources =
- [ Wildcard *.cpp *.hpp ]
- [ Wildcard audio : *.cpp *.hpp ]
- [ Wildcard audio/newapi : *.cpp *.hpp ]
- [ Wildcard badguy : *.cpp *.hpp ]
- [ Wildcard binreloc : *.c *.h ]
- [ Wildcard control : *.cpp *.hpp ]
- [ Wildcard gui : *.cpp *.hpp ]
- [ Wildcard lisp : *.cpp *.hpp ]
- [ Wildcard math : *.cpp *.hpp ]
- [ Wildcard object : *.cpp *.hpp ]
- [ Wildcard physfs : *.cpp *.hpp ]
- [ Wildcard sprite : *.cpp *.hpp ]
- [ Wildcard tinygettext : *.cpp *.hpp ]
- [ Wildcard trigger : *.cpp *.hpp ]
- [ Wildcard video : *.cpp *.hpp ]
- [ Wildcard worldmap : *.cpp *.hpp ]
- [ Wildcard obstack : *.c *.h *.hpp ]
-;
-TRANSLATABLE_SOURCES += [ SearchSource $(sources) ] ;
-
-#Application supertux : $(sources) $(wrapper_objects) ;
-Application supertux2 : $(sources) $(wrapper_objects) : linkerfile ;
-C++Flags supertux2 : -DAPPDATADIR=\'\"$(appdatadir)\"\' ;
-LinkWith supertux2 : squirrel ;
-ExternalLibs supertux2 : SDL SDLIMAGE GL OPENAL VORBIS VORBISFILE OGG ICONV PHYSFS BINRELOC LIBCURL ;
-Help supertux2 : "Build the supertux2 executable" ;
-IncludeDir supertux2 : squirrel/include squirrel ;
-Package [ Wildcard scripting : *.cpp *.hpp ] ;
-
+++ /dev/null
-// $Id$
-//
-// SuperTux - Add-on
-// Copyright (C) 2007 Christoph Sommer <christoph.sommer@2007.expires.deltadevelopment.de>
-//
-// 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.
-//
-
-#include <sstream>
-#include <stdexcept>
-#include "addon.hpp"
-#include "addon_manager.hpp"
-
-void
-Addon::install()
-{
- AddonManager& adm = AddonManager::get_instance();
- adm.install(*this);
-}
-
-void
-Addon::remove()
-{
- AddonManager& adm = AddonManager::get_instance();
- adm.remove(*this);
-}
-
-void
-Addon::parse(const lisp::Lisp& lisp)
-{
- try {
- lisp.get("kind", kind);
- lisp.get("title", title);
- lisp.get("author", author);
- lisp.get("license", license);
- lisp.get("http-url", http_url);
- lisp.get("file", file);
- lisp.get("md5", md5);
- } catch(std::exception& e) {
- std::stringstream msg;
- msg << "Problem when parsing addoninfo: " << e.what();
- throw std::runtime_error(msg.str());
- }
-}
-
-void
-Addon::parse(std::string fname)
-{
- try {
- lisp::Parser parser;
- const lisp::Lisp* root = parser.parse(fname);
- const lisp::Lisp* addon = root->get_lisp("supertux-addoninfo");
- if(!addon) throw std::runtime_error("file is not a supertux-addoninfo file.");
- parse(*addon);
- } catch(std::exception& e) {
- std::stringstream msg;
- msg << "Problem when reading addoninfo '" << fname << "': " << e.what();
- throw std::runtime_error(msg.str());
- }
-}
-
-void
-Addon::write(lisp::Writer& writer) const
-{
- writer.start_list("supertux-addoninfo");
- if (kind != "") writer.write_string("kind", kind);
- if (title != "") writer.write_string("title", title);
- if (author != "") writer.write_string("author", author);
- if (license != "") writer.write_string("license", license);
- if (http_url != "") writer.write_string("http-url", http_url);
- if (file != "") writer.write_string("file", file);
- if (md5 != "") writer.write_string("md5", md5);
- writer.end_list("supertux-addoninfo");
-}
-
-void
-Addon::write(std::string fname) const
-{
- lisp::Writer writer(fname);
- write(writer);
-}
-
-bool
-Addon::equals(const Addon& addon2) const
-{
- if ((this->md5 == "") || (addon2.md5 == "")) return (this->title == addon2.title);
- return (this->md5 == addon2.md5);
-}
-
+++ /dev/null
-// $Id$
-//
-// SuperTux - Add-on
-// Copyright (C) 2007 Christoph Sommer <christoph.sommer@2007.expires.deltadevelopment.de>
-//
-// 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.
-//
-#ifndef ADDON_H
-#define ADDON_H
-
-#include <string>
-#include <vector>
-#include "lisp/parser.hpp"
-#include "lisp/lisp.hpp"
-#include "lisp/writer.hpp"
-
-/**
- * Represents an (available or installed) Add-on, e.g. a level set
- */
-class Addon
-{
-public:
- std::string kind;
- std::string title;
- std::string author;
- std::string license;
- std::string http_url;
- std::string file;
- std::string md5;
-
- bool isInstalled;
-
- /**
- * Download and install Add-on
- */
- void install();
-
- /**
- * Physically delete Add-on
- */
- void remove();
-
- /**
- * Read additional information from given contents of a (supertux-addoninfo ...) block
- */
- void parse(const lisp::Lisp& lisp);
-
- /**
- * Read additional information from given file
- */
- void parse(std::string fname);
-
- /**
- * Writes out Add-on metainformation to a Lisp Writer
- */
- void write(lisp::Writer& writer) const;
-
- /**
- * Writes out Add-on metainformation to a file
- */
- void write(std::string fname) const;
-
- /**
- * Checks if Add-on is the same as given one.
- * If available, checks MD5 sum, else relies on title alone.
- */
- bool equals(const Addon& addon2) const;
-
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux - Add-on Manager
-// Copyright (C) 2007 Christoph Sommer <christoph.sommer@2007.expires.deltadevelopment.de>
-//
-// 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.
-//
-
-#include <sstream>
-#include <stdexcept>
-#include <list>
-#include <physfs.h>
-#include <sys/stat.h>
-#include <stdio.h>
-#include "addon_manager.hpp"
-#include "config.h"
-#include "log.hpp"
-#include "lisp/parser.hpp"
-#include "lisp/lisp.hpp"
-#include "lisp/list_iterator.hpp"
-
-#ifdef HAVE_LIBCURL
-#include <curl/curl.h>
-#include <curl/types.h>
-#include <curl/easy.h>
-#endif
-
-#ifdef HAVE_LIBCURL
-namespace {
-
- size_t my_curl_string_append(void *ptr, size_t size, size_t nmemb, void *string_ptr)
- {
- std::string& s = *static_cast<std::string*>(string_ptr);
- std::string buf(static_cast<char*>(ptr), size * nmemb);
- s += buf;
- log_debug << "read " << size * nmemb << " bytes of data..." << std::endl;
- return size * nmemb;
- }
-
- size_t my_curl_physfs_write(void *ptr, size_t size, size_t nmemb, void *f_p)
- {
- PHYSFS_file* f = static_cast<PHYSFS_file*>(f_p);
- PHYSFS_sint64 written = PHYSFS_write(f, ptr, size, nmemb);
- log_debug << "read " << size * nmemb << " bytes of data..." << std::endl;
- return size * written;
- }
-
-}
-#endif
-
-AddonManager&
-AddonManager::get_instance()
-{
- static AddonManager instance;
- return instance;
-}
-
-AddonManager::AddonManager()
-{
-#ifdef HAVE_LIBCURL
- curl_global_init(CURL_GLOBAL_ALL);
-#endif
-}
-
-AddonManager::~AddonManager()
-{
-#ifdef HAVE_LIBCURL
- curl_global_cleanup();
-#endif
-}
-
-std::vector<Addon>
-AddonManager::get_installed_addons() const
-{
- std::vector<Addon> addons;
-
- // iterate over complete search path (i.e. directories and archives)
- char **i = PHYSFS_getSearchPath();
- if (!i) throw std::runtime_error("Could not query physfs search path");
- for (; *i != NULL; i++) {
-
- // get filename of potential archive
- std::string fileName = *i;
-
- // make sure it's in the writeDir
- static const std::string writeDir = PHYSFS_getWriteDir();
- if (fileName.compare(0, writeDir.length(), writeDir) != 0) continue;
-
- // make sure it looks like an archive
- static const std::string archiveExt = ".zip";
- if (fileName.compare(fileName.length()-archiveExt.length(), archiveExt.length(), archiveExt) != 0) continue;
-
- // make sure it exists
- struct stat stats;
- if (stat(fileName.c_str(), &stats) != 0) continue;
-
- // make sure it's an actual file
- if (!S_ISREG(stats.st_mode)) continue;
-
- Addon addon;
-
- // extract nice title as fallback for when the Add-on has no addoninfo file
- static const char* dirSep = PHYSFS_getDirSeparator();
- std::string::size_type n = fileName.rfind(dirSep) + 1;
- if (n == std::string::npos) n = 0;
- addon.title = fileName.substr(n, fileName.length() - n - archiveExt.length());
- std::string shortFileName = fileName.substr(n, fileName.length() - n);
- addon.file = shortFileName;
-
- // read an accompaining .nfo file, if it exists
- static const std::string infoExt = ".nfo";
- std::string infoFileName = fileName.substr(n, fileName.length() - n - archiveExt.length()) + infoExt;
- if (PHYSFS_exists(infoFileName.c_str())) {
- addon.parse(infoFileName);
- if (addon.file != shortFileName) {
- log_warning << "Add-on \"" << addon.title << "\", contained in file \"" << shortFileName << "\" is accompained by an addoninfo file that specifies \"" << addon.file << "\" as the Add-on's file name. Skipping." << std::endl;
- }
- }
-
- // make sure the Add-on's file name does not contain weird characters
- if (addon.file.find_first_not_of("match.quiz-proxy_gwenblvdjfks0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ") != std::string::npos) {
- log_warning << "Add-on \"" << addon.title << "\" contains unsafe file name. Skipping." << std::endl;
- continue;
- }
-
- addon.isInstalled = true;
- addons.push_back(addon);
- }
-
- return addons;
-}
-
-std::vector<Addon>
-AddonManager::get_available_addons() const
-{
- std::vector<Addon> addons;
-
-#ifdef HAVE_LIBCURL
-
- char error_buffer[CURL_ERROR_SIZE+1];
-
- const char* baseUrl = "http://supertux.lethargik.org/addons/index.nfo";
- std::string addoninfos = "";
-
- CURL *curl_handle;
- curl_handle = curl_easy_init();
- curl_easy_setopt(curl_handle, CURLOPT_URL, baseUrl);
- curl_easy_setopt(curl_handle, CURLOPT_USERAGENT, "SuperTux/" PACKAGE_VERSION " libcURL");
- curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, my_curl_string_append);
- curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, &addoninfos);
- curl_easy_setopt(curl_handle, CURLOPT_ERRORBUFFER, error_buffer);
- curl_easy_setopt(curl_handle, CURLOPT_NOPROGRESS, 1);
- curl_easy_setopt(curl_handle, CURLOPT_NOSIGNAL, 1);
- curl_easy_setopt(curl_handle, CURLOPT_FAILONERROR, 1);
- CURLcode result = curl_easy_perform(curl_handle);
- curl_easy_cleanup(curl_handle);
-
- if (result != CURLE_OK) {
- std::string why = error_buffer[0] ? error_buffer : "unhandled error";
- throw std::runtime_error("Downloading Add-on list failed: " + why);
- }
-
- try {
- lisp::Parser parser;
- std::stringstream addoninfos_stream(addoninfos);
- const lisp::Lisp* root = parser.parse(addoninfos_stream, "supertux-addons");
-
- const lisp::Lisp* addons_lisp = root->get_lisp("supertux-addons");
- if(!addons_lisp) throw std::runtime_error("Downloaded file is not an Add-on list");
-
- lisp::ListIterator iter(addons_lisp);
- while(iter.next()) {
- const std::string& token = iter.item();
- if(token == "supertux-addoninfo") {
- Addon addon;
- addon.parse(*(iter.lisp()));
-
- // make sure the Add-on's file name does not contain weird characters
- if (addon.file.find_first_not_of("match.quiz-proxy_gwenblvdjfks0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ") != std::string::npos) {
- log_warning << "Add-on \"" << addon.title << "\" contains unsafe file name. Skipping." << std::endl;
- continue;
- }
-
- addon.isInstalled = false;
- addons.push_back(addon);
- } else {
- log_warning << "Unknown token '" << token << "' in Add-on list" << std::endl;
- }
- }
- } catch(std::exception& e) {
- std::stringstream msg;
- msg << "Problem when reading Add-on list: " << e.what();
- throw std::runtime_error(msg.str());
- }
-
-#endif
-
- return addons;
-}
-
-
-void
-AddonManager::install(const Addon& addon)
-{
- // make sure the Add-on's file name does not contain weird characters
- if (addon.file.find_first_not_of("match.quiz-proxy_gwenblvdjfks0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ") != std::string::npos) {
- throw std::runtime_error("Add-on has unsafe file name (\""+addon.file+"\")");
- }
-
-#ifdef HAVE_LIBCURL
-
- char error_buffer[CURL_ERROR_SIZE+1];
-
- char* url = (char*)malloc(addon.http_url.length() + 1);
- strncpy(url, addon.http_url.c_str(), addon.http_url.length() + 1);
-
- PHYSFS_file* f = PHYSFS_openWrite(addon.file.c_str());
-
- log_debug << "Downloading \"" << url << "\"" << std::endl;
-
- CURL *curl_handle;
- curl_handle = curl_easy_init();
- curl_easy_setopt(curl_handle, CURLOPT_URL, url);
- curl_easy_setopt(curl_handle, CURLOPT_USERAGENT, "SuperTux/" PACKAGE_VERSION " libcURL");
- curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, my_curl_physfs_write);
- curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, f);
- curl_easy_setopt(curl_handle, CURLOPT_ERRORBUFFER, error_buffer);
- curl_easy_setopt(curl_handle, CURLOPT_NOPROGRESS, 1);
- curl_easy_setopt(curl_handle, CURLOPT_NOSIGNAL, 1);
- curl_easy_setopt(curl_handle, CURLOPT_FAILONERROR, 1);
- CURLcode result = curl_easy_perform(curl_handle);
- curl_easy_cleanup(curl_handle);
-
- PHYSFS_close(f);
-
- free(url);
-
- if (result != CURLE_OK) {
- PHYSFS_delete(addon.file.c_str());
- std::string why = error_buffer[0] ? error_buffer : "unhandled error";
- throw std::runtime_error("Downloading Add-on failed: " + why);
- }
-
- // write an accompaining .nfo file
- static const std::string archiveExt = ".zip";
- static const std::string infoExt = ".nfo";
- std::string infoFileName = addon.file.substr(0, addon.file.length()-archiveExt.length()) + infoExt;
- addon.write(infoFileName);
-
- static const std::string writeDir = PHYSFS_getWriteDir();
- static const std::string dirSep = PHYSFS_getDirSeparator();
- std::string fullFilename = writeDir + dirSep + addon.file;
- log_debug << "Finished downloading \"" << fullFilename << "\"" << std::endl;
- PHYSFS_addToSearchPath(fullFilename.c_str(), 1);
-#else
- (void) addon;
-#endif
-
-}
-
-void
-AddonManager::remove(const Addon& addon)
-{
- // make sure the Add-on's file name does not contain weird characters
- if (addon.file.find_first_not_of("match.quiz-proxy_gwenblvdjfks0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ") != std::string::npos) {
- throw std::runtime_error("Add-on has unsafe file name (\""+addon.file+"\")");
- }
-
- log_debug << "deleting file \"" << addon.file << "\"" << std::endl;
- PHYSFS_removeFromSearchPath(addon.file.c_str());
- PHYSFS_delete(addon.file.c_str());
-
- // remove an accompaining .nfo file
- static const std::string archiveExt = ".zip";
- static const std::string infoExt = ".nfo";
- std::string infoFileName = addon.file.substr(0, addon.file.length()-archiveExt.length()) + infoExt;
- if (PHYSFS_exists(infoFileName.c_str())) {
- log_debug << "deleting file \"" << infoFileName << "\"" << std::endl;
- PHYSFS_delete(infoFileName.c_str());
- }
-}
-
+++ /dev/null
-// $Id$
-//
-// SuperTux - Add-on Manager
-// Copyright (C) 2007 Christoph Sommer <christoph.sommer@2007.expires.deltadevelopment.de>
-//
-// 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.
-//
-#ifndef ADDON_MANAGER_H
-#define ADDON_MANAGER_H
-
-#include <string>
-#include <vector>
-#include "addon.hpp"
-
-/**
- * Checks for, installs and removes Add-ons
- */
-class AddonManager
-{
-public:
- /**
- * returns a list of installed Add-ons
- */
- std::vector<Addon> get_installed_addons() const;
-
- /**
- * returns a list of available Add-ons
- */
- std::vector<Addon> get_available_addons() const;
-
- /**
- * Download and install Add-on
- */
- void install(const Addon& addon);
-
- /**
- * Physically delete Add-on
- */
- void remove(const Addon& addon);
-
- static AddonManager& get_instance();
-
-protected:
- AddonManager();
- ~AddonManager();
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#include <config.h>
-
-#include "dummy_sound_source.hpp"
-
-class DummySoundSource : public SoundSource
-{
-public:
- DummySoundSource()
- {}
- virtual ~DummySoundSource()
- {}
-
- virtual void play()
- {
- is_playing = true;
- }
-
- virtual void stop()
- {
- is_playing = false;
- }
-
- virtual bool playing()
- {
- return is_playing;
- }
-
- virtual void set_looping(bool )
- {
- }
-
- virtual void set_gain(float )
- {
- }
-
- virtual void set_pitch(float )
- {
- }
-
- virtual void set_position(const Vector& )
- {
- }
-
- virtual void set_velocity(const Vector& )
- {
- }
-
- virtual void set_reference_distance(float )
- {
- }
-
- virtual void set_rollof_factor(float )
- {
- }
-
-private:
- bool is_playing;
-};
-
-SoundSource* create_dummy_sound_source()
-{
- return new DummySoundSource();
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#ifndef __DUMMY_SOUND_SOURCE_HPP__
-#define __DUMMY_SOUND_SOURCE_HPP__
-
-#include "sound_source.hpp"
-
-SoundSource* create_dummy_sound_source();
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#include <config.h>
-
-#include "openal_sound_source.hpp"
-#include "sound_manager.hpp"
-
-OpenALSoundSource::OpenALSoundSource()
-{
- alGenSources(1, &source);
- SoundManager::check_al_error("Couldn't create audio source: ");
- set_reference_distance(128);
-}
-
-OpenALSoundSource::~OpenALSoundSource()
-{
- stop();
- alDeleteSources(1, &source);
-}
-
-void
-OpenALSoundSource::stop()
-{
- alSourceStop(source);
- alSourcei(source, AL_BUFFER, AL_NONE);
- SoundManager::check_al_error("Problem stopping audio source: ");
-}
-
-void
-OpenALSoundSource::play()
-{
- alSourcePlay(source);
- SoundManager::check_al_error("Couldn't start audio source: ");
-}
-
-bool
-OpenALSoundSource::playing()
-{
- ALint state = AL_PLAYING;
- alGetSourcei(source, AL_SOURCE_STATE, &state);
- return state != AL_STOPPED;
-}
-
-void
-OpenALSoundSource::update()
-{
-}
-
-void
-OpenALSoundSource::set_looping(bool looping)
-{
- alSourcei(source, AL_LOOPING, looping ? AL_TRUE : AL_FALSE);
-}
-
-void
-OpenALSoundSource::set_position(const Vector& position)
-{
- alSource3f(source, AL_POSITION, position.x, position.y, 0);
-}
-
-void
-OpenALSoundSource::set_velocity(const Vector& velocity)
-{
- alSource3f(source, AL_VELOCITY, velocity.x, velocity.y, 0);
-}
-
-void
-OpenALSoundSource::set_gain(float gain)
-{
- alSourcef(source, AL_GAIN, gain);
-}
-
-void
-OpenALSoundSource::set_pitch(float pitch)
-{
- alSourcef(source, AL_PITCH, pitch);
-}
-
-void
-OpenALSoundSource::set_reference_distance(float distance)
-{
- alSourcef(source, AL_REFERENCE_DISTANCE, distance);
-}
-
-void
-OpenALSoundSource::set_rollof_factor(float factor)
-{
- alSourcef(source, AL_ROLLOFF_FACTOR, factor);
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#ifndef __OPENAL_SOUND_SOURCE_H__
-#define __OPENAL_SOUND_SOURCE_H__
-
-#ifndef MACOSX
-#include <AL/al.h>
-#else
-#include <OpenAL/al.h>
-#endif
-
-#include "math/vector.hpp"
-#include "sound_source.hpp"
-
-class OpenALSoundSource : public SoundSource
-{
-public:
- OpenALSoundSource();
- virtual ~OpenALSoundSource();
-
- virtual void play();
- virtual void stop();
- virtual bool playing();
-
- virtual void update();
-
- virtual void set_looping(bool looping);
- virtual void set_gain(float gain);
- virtual void set_pitch(float pitch);
- virtual void set_position(const Vector& position);
- virtual void set_velocity(const Vector& position);
- virtual void set_reference_distance(float distance);
- virtual void set_rollof_factor(float factor);
-
-protected:
- friend class SoundManager;
-
- ALuint source;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-/** Used SDL_mixer and glest source as reference */
-#include <config.h>
-
-#include "sound_file.hpp"
-
-#include <stdio.h>
-#include <stdint.h>
-#include <algorithm>
-#include <stdexcept>
-#include <sstream>
-#include <assert.h>
-#include <physfs.h>
-#include <vorbis/codec.h>
-#include <vorbis/vorbisfile.h>
-#include "log.hpp"
-#include "lisp/parser.hpp"
-#include "lisp/lisp.hpp"
-#include "file_system.hpp"
-
-class WavSoundFile : public SoundFile
-{
-public:
- WavSoundFile(PHYSFS_file* file);
- ~WavSoundFile();
-
- size_t read(void* buffer, size_t buffer_size);
- void reset();
-
-private:
- PHYSFS_file* file;
-
- PHYSFS_sint64 datastart;
-};
-
-static inline uint32_t read32LE(PHYSFS_file* file)
-{
- uint32_t result;
- if(PHYSFS_readULE32(file, &result) == 0)
- throw std::runtime_error("file too short");
-
- return result;
-}
-
-static inline uint16_t read16LE(PHYSFS_file* file)
-{
- uint16_t result;
- if(PHYSFS_readULE16(file, &result) == 0)
- throw std::runtime_error("file too short");
-
- return result;
-}
-
-WavSoundFile::WavSoundFile(PHYSFS_file* file)
-{
- this->file = file;
-
- char magic[4];
- if(PHYSFS_read(file, magic, sizeof(magic), 1) != 1)
- throw std::runtime_error("Couldn't read file magic (not a wave file)");
- if(strncmp(magic, "RIFF", 4) != 0) {
- log_debug << "MAGIC: " << magic << std::endl;
- throw std::runtime_error("file is not a RIFF wav file");
- }
-
- uint32_t wavelen = read32LE(file);
- (void) wavelen;
-
- if(PHYSFS_read(file, magic, sizeof(magic), 1) != 1)
- throw std::runtime_error("Couldn't read chunk header (not a wav file?)");
- if(strncmp(magic, "WAVE", 4) != 0)
- throw std::runtime_error("file is not a valid RIFF/WAVE file");
-
- char chunkmagic[4];
- uint32_t chunklen;
-
- // search audio data format chunk
- do {
- if(PHYSFS_read(file, chunkmagic, sizeof(chunkmagic), 1) != 1)
- throw std::runtime_error("EOF while searching format chunk");
- chunklen = read32LE(file);
-
- if(strncmp(chunkmagic, "fmt ", 4) == 0)
- break;
-
- if(strncmp(chunkmagic, "fact", 4) == 0
- || strncmp(chunkmagic, "LIST", 4) == 0) {
- // skip chunk
- if(PHYSFS_seek(file, PHYSFS_tell(file) + chunklen) == 0)
- throw std::runtime_error("EOF while searching fmt chunk");
- } else {
- throw std::runtime_error("complex WAVE files not supported");
- }
- } while(true);
-
- if(chunklen < 16)
- throw std::runtime_error("Format chunk too short");
-
- // parse format
- uint16_t encoding = read16LE(file);
- if(encoding != 1)
- throw std::runtime_error("only PCM encoding supported");
- channels = read16LE(file);
- rate = read32LE(file);
- uint32_t byterate = read32LE(file);
- (void) byterate;
- uint16_t blockalign = read16LE(file);
- (void) blockalign;
- bits_per_sample = read16LE(file);
-
- if(chunklen > 16) {
- if(PHYSFS_seek(file, PHYSFS_tell(file) + (chunklen-16)) == 0)
- throw std::runtime_error("EOF while reading reast of format chunk");
- }
-
- // set file offset to DATA chunk data
- do {
- if(PHYSFS_read(file, chunkmagic, sizeof(chunkmagic), 1) != 1)
- throw std::runtime_error("EOF while searching data chunk");
- chunklen = read32LE(file);
-
- if(strncmp(chunkmagic, "data", 4) == 0)
- break;
-
- // skip chunk
- if(PHYSFS_seek(file, PHYSFS_tell(file) + chunklen) == 0)
- throw std::runtime_error("EOF while searching fmt chunk");
- } while(true);
-
- datastart = PHYSFS_tell(file);
- size = static_cast<size_t> (chunklen);
-}
-
-WavSoundFile::~WavSoundFile()
-{
- PHYSFS_close(file);
-}
-
-void
-WavSoundFile::reset()
-{
- if(PHYSFS_seek(file, datastart) == 0)
- throw std::runtime_error("Couldn't seek to data start");
-}
-
-size_t
-WavSoundFile::read(void* buffer, size_t buffer_size)
-{
- PHYSFS_sint64 end = datastart + size;
- PHYSFS_sint64 cur = PHYSFS_tell(file);
- if(cur >= end)
- return 0;
-
- size_t readsize = std::min(static_cast<size_t> (end - cur), buffer_size);
- if(PHYSFS_read(file, buffer, readsize, 1) != 1)
- throw std::runtime_error("read error while reading samples");
-
-#ifdef WORDS_BIGENDIAN
- if (bits_per_sample != 16)
- return readsize;
- char *tmp = (char*)buffer;
-
- size_t i;
- char c;
- for (i = 0; i < readsize / 2; i++)
- {
- c = tmp[2*i];
- tmp[2*i] = tmp[2*i+1];
- tmp[2*i+1] = c;
- }
-
- buffer = tmp;
-#endif
-
- return readsize;
-}
-
-//---------------------------------------------------------------------------
-
-class OggSoundFile : public SoundFile
-{
-public:
- OggSoundFile(PHYSFS_file* file, double loop_begin, double loop_at);
- ~OggSoundFile();
-
- size_t read(void* buffer, size_t buffer_size);
- void reset();
-
-private:
- static size_t cb_read(void* ptr, size_t size, size_t nmemb, void* source);
- static int cb_seek(void* source, ogg_int64_t offset, int whence);
- static int cb_close(void* source);
- static long cb_tell(void* source);
-
- PHYSFS_file* file;
- OggVorbis_File vorbis_file;
- ogg_int64_t loop_begin;
- ogg_int64_t loop_at;
- size_t normal_buffer_loop;
-};
-
-OggSoundFile::OggSoundFile(PHYSFS_file* file, double loop_begin, double loop_at)
-{
- this->file = file;
-
- ov_callbacks callbacks = { cb_read, cb_seek, cb_close, cb_tell };
- ov_open_callbacks(file, &vorbis_file, 0, 0, callbacks);
-
- vorbis_info* vi = ov_info(&vorbis_file, -1);
-
- channels = vi->channels;
- rate = vi->rate;
- bits_per_sample = 16;
- size = static_cast<size_t> (ov_pcm_total(&vorbis_file, -1) * 2);
-
- double sample_len = 1.0f / rate;
- double samples_begin = loop_begin / sample_len;
- double sample_loop = loop_at / sample_len;
-
- this->loop_begin = (ogg_int64_t) samples_begin;
- if(loop_begin < 0) {
- this->loop_at = (ogg_int64_t) -1;
- } else {
- this->loop_at = (ogg_int64_t) sample_loop;
- }
-}
-
-OggSoundFile::~OggSoundFile()
-{
- ov_clear(&vorbis_file);
-}
-
-size_t
-OggSoundFile::read(void* _buffer, size_t buffer_size)
-{
- char* buffer = reinterpret_cast<char*> (_buffer);
- int section = 0;
- size_t totalBytesRead = 0;
-
- while(buffer_size>0) {
-#ifdef WORDS_BIGENDIAN
- int bigendian = 1;
-#else
- int bigendian = 0;
-#endif
-
- size_t bytes_to_read = buffer_size;
- if(loop_at > 0) {
- size_t bytes_per_sample = 2;
- ogg_int64_t time = ov_pcm_tell(&vorbis_file);
- ogg_int64_t samples_left_till_loop = loop_at - time;
- ogg_int64_t bytes_left_till_loop
- = samples_left_till_loop * bytes_per_sample;
- if(bytes_left_till_loop <= 4)
- break;
-
- if(bytes_left_till_loop < (ogg_int64_t) bytes_to_read) {
- bytes_to_read = (size_t) bytes_left_till_loop;
- }
- }
-
- long bytesRead
- = ov_read(&vorbis_file, buffer, bytes_to_read, bigendian,
- 2, 1, §ion);
- if(bytesRead == 0) {
- break;
- }
- buffer_size -= bytesRead;
- buffer += bytesRead;
- totalBytesRead += bytesRead;
- }
-
- return totalBytesRead;
-}
-
-void
-OggSoundFile::reset()
-{
- ov_pcm_seek(&vorbis_file, loop_begin);
-}
-
-size_t
-OggSoundFile::cb_read(void* ptr, size_t size, size_t nmemb, void* source)
-{
- PHYSFS_file* file = reinterpret_cast<PHYSFS_file*> (source);
-
- PHYSFS_sint64 res
- = PHYSFS_read(file, ptr, static_cast<PHYSFS_uint32> (size),
- static_cast<PHYSFS_uint32> (nmemb));
- if(res <= 0)
- return 0;
-
- return static_cast<size_t> (res);
-}
-
-int
-OggSoundFile::cb_seek(void* source, ogg_int64_t offset, int whence)
-{
- PHYSFS_file* file = reinterpret_cast<PHYSFS_file*> (source);
-
- switch(whence) {
- case SEEK_SET:
- if(PHYSFS_seek(file, static_cast<PHYSFS_uint64> (offset)) == 0)
- return -1;
- break;
- case SEEK_CUR:
- if(PHYSFS_seek(file, PHYSFS_tell(file) + offset) == 0)
- return -1;
- break;
- case SEEK_END:
- if(PHYSFS_seek(file, PHYSFS_fileLength(file) + offset) == 0)
- return -1;
- break;
- default:
-#ifdef DEBUG
- assert(false);
-#else
- return -1;
-#endif
- }
- return 0;
-}
-
-int
-OggSoundFile::cb_close(void* source)
-{
- PHYSFS_file* file = reinterpret_cast<PHYSFS_file*> (source);
- PHYSFS_close(file);
- return 0;
-}
-
-long
-OggSoundFile::cb_tell(void* source)
-{
- PHYSFS_file* file = reinterpret_cast<PHYSFS_file*> (source);
- return static_cast<long> (PHYSFS_tell(file));
-}
-
-//---------------------------------------------------------------------------
-
-SoundFile* load_music_file(const std::string& filename)
-{
- lisp::Parser parser(false);
- const lisp::Lisp* root = parser.parse(filename);
- const lisp::Lisp* music = root->get_lisp("supertux-music");
- if(music == NULL)
- throw std::runtime_error("file is not a supertux-music file.");
-
- std::string raw_music_file;
- float loop_begin = 0;
- float loop_at = -1;
-
- music->get("file", raw_music_file);
- music->get("loop-begin", loop_begin);
- music->get("loop-at", loop_at);
-
- if(loop_begin < 0) {
- throw std::runtime_error("can't loop from negative value");
- }
-
- std::string basedir = FileSystem::dirname(filename);
- raw_music_file = FileSystem::normalize(basedir + raw_music_file);
-
- PHYSFS_file* file = PHYSFS_openRead(raw_music_file.c_str());
- if(!file) {
- std::stringstream msg;
- msg << "Couldn't open '" << raw_music_file << "': " << PHYSFS_getLastError();
- throw std::runtime_error(msg.str());
- }
-
- return new OggSoundFile(file, loop_begin, loop_at);
-}
-
-SoundFile* load_sound_file(const std::string& filename)
-{
- if(filename.length() > 6
- && filename.compare(filename.length()-6, 6, ".music") == 0) {
- return load_music_file(filename);
- }
-
- PHYSFS_file* file = PHYSFS_openRead(filename.c_str());
- if(!file) {
- std::stringstream msg;
- msg << "Couldn't open '" << filename << "': " << PHYSFS_getLastError();
- throw std::runtime_error(msg.str());
- }
-
- try {
- char magic[4];
- if(PHYSFS_read(file, magic, sizeof(magic), 1) != 1)
- throw std::runtime_error("Couldn't read magic, file too short");
- PHYSFS_seek(file, 0);
- if(strncmp(magic, "RIFF", 4) == 0)
- return new WavSoundFile(file);
- else if(strncmp(magic, "OggS", 4) == 0)
- return new OggSoundFile(file, 0, -1);
- else
- throw std::runtime_error("Unknown file format");
- } catch(std::exception& e) {
- std::stringstream msg;
- msg << "Couldn't read '" << filename << "': " << e.what();
- throw std::runtime_error(msg.str());
- }
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __SOUND_FILE_H__
-#define __SOUND_FILE_H__
-
-#include <stdio.h>
-#include <iostream>
-
-class SoundFile
-{
-public:
- virtual ~SoundFile()
- { }
-
- virtual size_t read(void* buffer, size_t buffer_size) = 0;
- virtual void reset() = 0;
-
- int channels;
- int rate;
- int bits_per_sample;
- /// size in bytes
- size_t size;
-};
-
-SoundFile* load_sound_file(const std::string& filename);
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#include <config.h>
-
-#include "sound_manager.hpp"
-
-#include <stdexcept>
-#include <iostream>
-#include <sstream>
-#include <memory>
-#include <assert.h>
-#include <SDL.h>
-
-#include "sound_file.hpp"
-#include "sound_source.hpp"
-#include "openal_sound_source.hpp"
-#include "stream_sound_source.hpp"
-#include "dummy_sound_source.hpp"
-#include "log.hpp"
-#include "timer.hpp"
-
-#ifndef DEBUG
- /** Older openal versions often miss this function and it isn't that vital for
- * supertux...
- */
-#ifdef alcGetString
-#undef alcGetString
-#endif
-#define alcGetString(x,y) ""
-#endif
-
-SoundManager* sound_manager = 0;
-
-SoundManager::SoundManager()
- : device(0), context(0), sound_enabled(false), music_source(0),
- music_enabled(false)
-{
- try {
- device = alcOpenDevice(0);
- if (device == NULL) {
- throw std::runtime_error("Couldn't open audio device.");
- }
-
- int attributes[] = { 0 };
- context = alcCreateContext(device, attributes);
- check_alc_error("Couldn't create audio context: ");
- alcMakeContextCurrent(context);
- check_alc_error("Couldn't select audio context: ");
-
- check_al_error("Audio error after init: ");
- sound_enabled = true;
- music_enabled = true;
- } catch(std::exception& e) {
- if(context != NULL)
- alcDestroyContext(context);
- context = NULL;
- if(device != NULL)
- alcCloseDevice(device);
- device = NULL;
- log_warning << "Couldn't initialize audio device: " << e.what() << std::endl;
- print_openal_version();
- }
-}
-
-SoundManager::~SoundManager()
-{
- delete music_source;
-
- for(SoundSources::iterator i = sources.begin(); i != sources.end(); ++i) {
- delete *i;
- }
-
- for(SoundBuffers::iterator i = buffers.begin(); i != buffers.end(); ++i) {
- ALuint buffer = i->second;
- alDeleteBuffers(1, &buffer);
- }
-
- if(context != NULL) {
- alcDestroyContext(context);
- }
- if(device != NULL) {
- alcCloseDevice(device);
- }
-}
-
-ALuint
-SoundManager::load_file_into_buffer(SoundFile* file)
-{
- ALenum format = get_sample_format(file);
- ALuint buffer;
- alGenBuffers(1, &buffer);
- check_al_error("Couldn't create audio buffer: ");
- char* samples = new char[file->size];
- try {
- file->read(samples, file->size);
- alBufferData(buffer, format, samples,
- static_cast<ALsizei> (file->size),
- static_cast<ALsizei> (file->rate));
- check_al_error("Couldn't fill audio buffer: ");
- } catch(...) {
- delete[] samples;
- throw;
- }
- delete[] samples;
-
- return buffer;
-}
-
-OpenALSoundSource*
-SoundManager::intern_create_sound_source(const std::string& filename)
-{
- if(!sound_enabled)
- throw std::runtime_error("sound disabled");
-
- std::auto_ptr<OpenALSoundSource> source (new OpenALSoundSource());
-
- ALuint buffer;
-
- // reuse an existing static sound buffer
- SoundBuffers::iterator i = buffers.find(filename);
- if(i != buffers.end()) {
- buffer = i->second;
- } else {
- // Load sound file
- std::auto_ptr<SoundFile> file (load_sound_file(filename));
-
- if(file->size < 100000) {
- buffer = load_file_into_buffer(file.get());
- buffers.insert(std::make_pair(filename, buffer));
- } else {
- StreamSoundSource* source = new StreamSoundSource();
- source->set_sound_file(file.release());
- return source;
- }
- }
-
- alSourcei(source->source, AL_BUFFER, buffer);
- return source.release();
-}
-
-SoundSource*
-SoundManager::create_sound_source(const std::string& filename)
-{
- if(!sound_enabled)
- return create_dummy_sound_source();
-
- try {
- return intern_create_sound_source(filename);
- } catch(std::exception &e) {
- log_warning << "Couldn't create audio source: " << e.what() << std::endl;
- return create_dummy_sound_source();
- }
-}
-
-void
-SoundManager::preload(const std::string& filename)
-{
- if(!sound_enabled)
- return;
-
- SoundBuffers::iterator i = buffers.find(filename);
- // already loaded?
- if(i != buffers.end())
- return;
-
- std::auto_ptr<SoundFile> file (load_sound_file(filename));
- // only keep small files
- if(file->size >= 100000)
- return;
-
- ALuint buffer = load_file_into_buffer(file.get());
- buffers.insert(std::make_pair(filename, buffer));
-}
-
-void
-SoundManager::play(const std::string& filename, const Vector& pos)
-{
- if(!sound_enabled)
- return;
-
- try {
- std::auto_ptr<OpenALSoundSource> source
- (intern_create_sound_source(filename));
-
- if(pos == Vector(-1, -1)) {
- source->set_rollof_factor(0);
- } else {
- source->set_position(pos);
- }
- source->play();
- sources.push_back(source.release());
- } catch(std::exception& e) {
- log_warning << "Couldn't play sound " << filename << ": " << e.what() << std::endl;
- }
-}
-
-void
-SoundManager::manage_source(SoundSource* source)
-{
- assert(source != NULL);
-
- OpenALSoundSource* openal_source = dynamic_cast<OpenALSoundSource*> (source);
- if(openal_source != NULL) {
- sources.push_back(openal_source);
- }
-}
-
-void
-SoundManager::register_for_update( StreamSoundSource* sss ){
- if( sss != NULL ){
- update_list.push_back( sss );
- }
-}
-
-void
-SoundManager::remove_from_update( StreamSoundSource* sss ){
- if( sss != NULL ){
- StreamSoundSources::iterator i = update_list.begin();
- while( i != update_list.end() ){
- if( *i == sss ){
- i = update_list.erase(i);
- } else {
- i++;
- }
- }
- }
-}
-
-void
-SoundManager::enable_sound(bool enable)
-{
- if(device == NULL)
- return;
-
- sound_enabled = enable;
-}
-
-void
-SoundManager::enable_music(bool enable)
-{
- if(device == NULL)
- return;
-
- music_enabled = enable;
- if(music_enabled) {
- play_music(current_music);
- } else {
- if(music_source) {
- delete music_source;
- music_source = 0;
- }
- }
-}
-
-void
-SoundManager::stop_music(float fadetime)
-{
- if(fadetime > 0) {
- if(music_source
- && music_source->get_fade_state() != StreamSoundSource::FadingOff)
- music_source->set_fading(StreamSoundSource::FadingOff, fadetime);
- } else {
- delete music_source;
- music_source = NULL;
- }
- current_music = "";
-}
-
-void
-SoundManager::play_music(const std::string& filename, bool fade)
-{
- if(filename == current_music && music_source != NULL)
- return;
- current_music = filename;
- if(!music_enabled)
- return;
-
- if(filename == "") {
- delete music_source;
- music_source = NULL;
- return;
- }
-
- try {
- std::auto_ptr<StreamSoundSource> newmusic (new StreamSoundSource());
- alSourcef(newmusic->source, AL_ROLLOFF_FACTOR, 0);
- newmusic->set_sound_file(load_sound_file(filename));
- newmusic->set_looping(true);
- if(fade)
- newmusic->set_fading(StreamSoundSource::FadingOn, .5f);
- newmusic->play();
-
- delete music_source;
- music_source = newmusic.release();
- } catch(std::exception& e) {
- log_warning << "Couldn't play music file '" << filename << "': " << e.what() << std::endl;
- }
-}
-
-void
-SoundManager::set_listener_position(const Vector& pos)
-{
- static Uint32 lastticks = SDL_GetTicks();
-
- Uint32 current_ticks = SDL_GetTicks();
- if(current_ticks - lastticks < 300)
- return;
- lastticks = current_ticks;
-
- alListener3f(AL_POSITION, pos.x, pos.y, 0);
-}
-
-void
-SoundManager::set_listener_velocity(const Vector& vel)
-{
- alListener3f(AL_VELOCITY, vel.x, vel.y, 0);
-}
-
-void
-SoundManager::update()
-{
- static Uint32 lasttime = SDL_GetTicks();
- Uint32 now = SDL_GetTicks();
-
- if(now - lasttime < 300)
- return;
- lasttime = now;
-
- // update and check for finished sound sources
- for(SoundSources::iterator i = sources.begin(); i != sources.end(); ) {
- OpenALSoundSource* source = *i;
-
- source->update();
-
- if(!source->playing()) {
- delete source;
- i = sources.erase(i);
- } else {
- ++i;
- }
- }
- // check streaming sounds
- if(music_source) {
- music_source->update();
- }
-
- if (context)
- {
- alcProcessContext(context);
- check_alc_error("Error while processing audio context: ");
- }
-
- //run update() for stream_sound_source
- StreamSoundSources::iterator s = update_list.begin();
- while( s != update_list.end() ){
- (*s)->update();
- s++;
- }
-}
-
-ALenum
-SoundManager::get_sample_format(SoundFile* file)
-{
- if(file->channels == 2) {
- if(file->bits_per_sample == 16) {
- return AL_FORMAT_STEREO16;
- } else if(file->bits_per_sample == 8) {
- return AL_FORMAT_STEREO8;
- } else {
- throw std::runtime_error("Only 16 and 8 bit samples supported");
- }
- } else if(file->channels == 1) {
- if(file->bits_per_sample == 16) {
- return AL_FORMAT_MONO16;
- } else if(file->bits_per_sample == 8) {
- return AL_FORMAT_MONO8;
- } else {
- throw std::runtime_error("Only 16 and 8 bit samples supported");
- }
- }
-
- throw std::runtime_error("Only 1 and 2 channel samples supported");
-}
-
-void
-SoundManager::print_openal_version()
-{
- log_info << "OpenAL Vendor: " << alGetString(AL_VENDOR) << std::endl;
- log_info << "OpenAL Version: " << alGetString(AL_VERSION) << std::endl;
- log_info << "OpenAL Renderer: " << alGetString(AL_RENDERER) << std::endl;
- log_info << "OpenAl Extensions: " << alGetString(AL_EXTENSIONS) << std::endl;
-}
-
-void
-SoundManager::check_alc_error(const char* message)
-{
- int err = alcGetError(device);
- if(err != ALC_NO_ERROR) {
- std::stringstream msg;
- msg << message << alcGetString(device, err);
- throw std::runtime_error(msg.str());
- }
-}
-
-void
-SoundManager::check_al_error(const char* message)
-{
- int err = alGetError();
- if(err != AL_NO_ERROR) {
- std::stringstream msg;
- msg << message << alGetString(err);
- throw std::runtime_error(msg.str());
- }
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#ifndef __SOUND_MANAGER_H__
-#define __SOUND_MANAGER_H__
-
-#include <string>
-#include <vector>
-#include <map>
-
-#ifndef MACOSX
-#include <AL/alc.h>
-#include <AL/al.h>
-#else
-#include <OpenAL/alc.h>
-#include <OpenAL/al.h>
-#endif
-
-#include "math/vector.hpp"
-
-class SoundFile;
-class SoundSource;
-class StreamSoundSource;
-class OpenALSoundSource;
-
-class SoundManager
-{
-public:
- SoundManager();
- virtual ~SoundManager();
-
- void enable_sound(bool sound_enabled);
- /**
- * Creates a new sound source object which plays the specified soundfile.
- * You are responsible for deleting the sound source later (this will stop the
- * sound).
- * This function never throws exceptions, but might return a DummySoundSource
- */
- SoundSource* create_sound_source(const std::string& filename);
- /**
- * Convenience function to simply play a sound at a given position.
- */
- void play(const std::string& name, const Vector& pos = Vector(-1, -1));
- /**
- * Adds the source to the list of managed sources (= the source gets deleted
- * when it finished playing)
- */
- void manage_source(SoundSource* source);
- /// preloads a sound, so that you don't get a lag later when playing it
- void preload(const std::string& name);
-
- void set_listener_position(const Vector& position);
- void set_listener_velocity(const Vector& velocity);
-
- void enable_music(bool music_enabled);
- void play_music(const std::string& filename, bool fade = false);
- void stop_music(float fadetime = 0);
-
- bool is_music_enabled() { return music_enabled; }
- bool is_sound_enabled() { return sound_enabled; }
-
- bool is_audio_enabled() {
- return device != 0 && context != 0;
- }
-
- void update();
-
- /*
- * Tell soundmanager to call update() for stream_sound_source.
- */
- void register_for_update( StreamSoundSource* sss );
- /*
- * Unsubscribe from updates for stream_sound_source.
- */
- void remove_from_update( StreamSoundSource* sss );
-
-private:
- friend class OpenALSoundSource;
- friend class StreamSoundSource;
-
- /** creates a new sound source, might throw exceptions, never returns NULL */
- OpenALSoundSource* intern_create_sound_source(const std::string& filename);
- static ALuint load_file_into_buffer(SoundFile* file);
- static ALenum get_sample_format(SoundFile* file);
-
- void print_openal_version();
- void check_alc_error(const char* message);
- static void check_al_error(const char* message);
-
- ALCdevice* device;
- ALCcontext* context;
- bool sound_enabled;
-
- typedef std::map<std::string, ALuint> SoundBuffers;
- SoundBuffers buffers;
- typedef std::vector<OpenALSoundSource*> SoundSources;
- SoundSources sources;
-
- typedef std::vector<StreamSoundSource*> StreamSoundSources;
- StreamSoundSources update_list;
-
- StreamSoundSource* music_source;
-
- bool music_enabled;
- std::string current_music;
-};
-
-extern SoundManager* sound_manager;
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#ifndef __SOUND_SOURCE_H__
-#define __SOUND_SOURCE_H__
-
-#include "math/vector.hpp"
-
-/**
- * A sound source represents the source of audio output. You can place
- * sources at certain points in your world or set their velocity to produce
- * doppler effects
- */
-class SoundSource
-{
-public:
- virtual ~SoundSource()
- { }
-
- virtual void play() = 0;
- virtual void stop() = 0;
- virtual bool playing() = 0;
-
- virtual void set_looping(bool looping) = 0;
- /// Set volume (0.0 is silent, 1.0 is normal)
- virtual void set_gain(float gain) = 0;
- virtual void set_pitch(float pitch) = 0;
- virtual void set_position(const Vector& position) = 0;
- virtual void set_velocity(const Vector& position) = 0;
- virtual void set_reference_distance(float distance) = 0;
- virtual void set_rollof_factor(float factor) = 0;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-#include <assert.h>
-
-#include <SDL.h>
-
-#include "stream_sound_source.hpp"
-#include "sound_manager.hpp"
-#include "sound_file.hpp"
-#include "timer.hpp"
-#include "log.hpp"
-
-StreamSoundSource::StreamSoundSource()
- : file(0), fade_state(NoFading), looping(false)
-{
- alGenBuffers(STREAMFRAGMENTS, buffers);
- SoundManager::check_al_error("Couldn't allocate audio buffers: ");
- //add me to update list
- sound_manager->register_for_update( this );
-}
-
-StreamSoundSource::~StreamSoundSource()
-{
- //don't update me any longer
- sound_manager->remove_from_update( this );
- delete file;
- stop();
- alDeleteBuffers(STREAMFRAGMENTS, buffers);
- SoundManager::check_al_error("Couldn't delete audio buffers: ");
-}
-
-void
-StreamSoundSource::set_sound_file(SoundFile* newfile)
-{
- delete file;
- file = newfile;
-
- ALint queued;
- alGetSourcei(source, AL_BUFFERS_QUEUED, &queued);
- for(size_t i = 0; i < STREAMFRAGMENTS - queued; ++i) {
- if(fillBufferAndQueue(buffers[i]) == false)
- break;
- }
-}
-
-void
-StreamSoundSource::update()
-{
- ALint processed = 0;
- alGetSourcei(source, AL_BUFFERS_PROCESSED, &processed);
- for(ALint i = 0; i < processed; ++i) {
- ALuint buffer;
- alSourceUnqueueBuffers(source, 1, &buffer);
- SoundManager::check_al_error("Couldn't unqueu audio buffer: ");
-
- if(fillBufferAndQueue(buffer) == false)
- break;
- }
-
- if(!playing()) {
- if(processed == 0 || !looping)
- return;
-
- // we might have to restart the source if we had a buffer underrun
- log_info << "Restarting audio source because of buffer underrun" << std::endl;
- play();
- }
-
- if(fade_state == FadingOn) {
- float time = real_time - fade_start_time;
- if(time >= fade_time) {
- set_gain(1.0);
- fade_state = NoFading;
- } else {
- set_gain(time / fade_time);
- }
- } else if(fade_state == FadingOff) {
- float time = real_time - fade_start_time;
- if(time >= fade_time) {
- stop();
- fade_state = NoFading;
- } else {
- set_gain( (fade_time-time) / fade_time);
- }
- }
-}
-
-void
-StreamSoundSource::set_fading(FadeState state, float fade_time)
-{
- this->fade_state = state;
- this->fade_time = fade_time;
- this->fade_start_time = real_time;
-}
-
-bool
-StreamSoundSource::fillBufferAndQueue(ALuint buffer)
-{
- // fill buffer
- char* bufferdata = new char[STREAMFRAGMENTSIZE];
- size_t bytesread = 0;
- do {
- bytesread += file->read(bufferdata + bytesread,
- STREAMFRAGMENTSIZE - bytesread);
- // end of sound file
- if(bytesread < STREAMFRAGMENTSIZE) {
- if(looping)
- file->reset();
- else
- break;
- }
- } while(bytesread < STREAMFRAGMENTSIZE);
-
- if(bytesread > 0) {
- ALenum format = SoundManager::get_sample_format(file);
- alBufferData(buffer, format, bufferdata, bytesread, file->rate);
- SoundManager::check_al_error("Couldn't refill audio buffer: ");
-
- alSourceQueueBuffers(source, 1, &buffer);
- SoundManager::check_al_error("Couldn't queue audio buffer: ");
- }
- delete[] bufferdata;
-
- // return false if there aren't more buffers to fill
- return bytesread >= STREAMFRAGMENTSIZE;
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __STREAM_SOUND_SOURCE_H__
-#define __STREAM_SOUND_SOURCE_H__
-
-#include <stdio.h>
-#include <SDL.h>
-#include "openal_sound_source.hpp"
-
-class SoundFile;
-
-class StreamSoundSource : public OpenALSoundSource
-{
-public:
- StreamSoundSource();
- virtual ~StreamSoundSource();
-
- void set_sound_file(SoundFile* file);
-
- enum FadeState { NoFading, FadingOn, FadingOff };
-
- void set_fading(FadeState state, float fadetime);
- FadeState get_fade_state() const
- {
- return fade_state;
- }
- void update();
-
- void set_looping(bool looping)
- {
- this->looping = looping;
- }
- bool get_looping() const
- {
- return looping;
- }
-
-private:
- static const size_t STREAMBUFFERSIZE = 1024 * 500;
- static const size_t STREAMFRAGMENTS = 5;
- static const size_t STREAMFRAGMENTSIZE
- = STREAMBUFFERSIZE / STREAMFRAGMENTS;
-
- bool fillBufferAndQueue(ALuint buffer);
- SoundFile* file;
- ALuint buffers[STREAMFRAGMENTS];
-
- FadeState fade_state;
- float fade_start_time;
- float fade_time;
- bool looping;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// AngryStone - A spiked block that charges towards the player
-// Copyright (C) 2006 Christoph Sommer <supertux@2006.expires.deltadevelopment.de>
-//
-// 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.
-
-#include <config.h>
-
-#include "angrystone.hpp"
-
-static const float SPEED = 240;
-
-static const float CHARGE_TIME = .5;
-static const float ATTACK_TIME = 1;
-static const float RECOVER_TIME = .5;
-
-AngryStone::AngryStone(const lisp::Lisp& reader)
- : BadGuy(reader, "images/creatures/angrystone/angrystone.sprite"), state(IDLE)
-{
-}
-
-void
-AngryStone::write(lisp::Writer& writer)
-{
- writer.start_list("angrystone");
-
- writer.write_float("x", start_position.x);
- writer.write_float("y", start_position.y);
-
- writer.end_list("angrystone");
-}
-
-void
-AngryStone::activate()
-{
- physic.set_velocity_x(0);
- physic.set_velocity_y(0);
- physic.enable_gravity(true);
- sprite->set_action("idle");
-}
-
-void
-AngryStone::collision_solid(const CollisionHit& hit)
-{
- // TODO
- (void) hit;
-#if 0
- if ((state == ATTACKING) &&
- (hit.normal.x == -attackDirection.x) && (hit.normal.y == attackDirection.y)) {
- state = IDLE;
- sprite->set_action("idle");
- physic.set_velocity_x(0);
- physic.set_velocity_y(0);
- physic.enable_gravity(true);
- oldWallDirection.x = attackDirection.x;
- oldWallDirection.y = attackDirection.y;
- }
-#endif
-}
-
-void
-AngryStone::kill_fall()
-{
- //prevents AngryStone from getting killed by other enemies or the player
-}
-
-HitResponse
-AngryStone::collision_badguy(BadGuy& badguy, const CollisionHit& )
-{
- if (state == ATTACKING) {
- badguy.kill_fall();
- return FORCE_MOVE;
- }
-
- return FORCE_MOVE;
-}
-
-void
-AngryStone::active_update(float elapsed_time) {
- BadGuy::active_update(elapsed_time);
-
- if (state == IDLE) {
- MovingObject* player = this->get_nearest_player();
- MovingObject* badguy = this;
- const Vector playerPos = player->get_pos();
- const Vector badguyPos = badguy->get_pos();
- float dx = (playerPos.x - badguyPos.x);
- float dy = (playerPos.y - badguyPos.y);
-
- float playerHeight = player->get_bbox().p2.y - player->get_bbox().p1.y;
- float badguyHeight = badguy->get_bbox().p2.y - badguy->get_bbox().p1.y;
-
- float playerWidth = player->get_bbox().p2.x - player->get_bbox().p1.x;
- float badguyWidth = badguy->get_bbox().p2.x - badguy->get_bbox().p1.x;
-
- if ((dx > -playerWidth) && (dx < badguyWidth)) {
- if (dy > 0) {
- attackDirection.x = 0;
- attackDirection.y = 1;
- } else {
- attackDirection.x = 0;
- attackDirection.y = -1;
- }
- if ((attackDirection.x != oldWallDirection.x) || (attackDirection.y != oldWallDirection.y)) {
- sprite->set_action("charging");
- timer.start(CHARGE_TIME);
- state = CHARGING;
- }
- } else
- if ((dy > -playerHeight) && (dy < badguyHeight)) {
- if (dx > 0) {
- attackDirection.x = 1;
- attackDirection.y = 0;
- } else {
- attackDirection.x = -1;
- attackDirection.y = 0;
- }
- if ((attackDirection.x != oldWallDirection.x) || (attackDirection.y != oldWallDirection.y)) {
- sprite->set_action("charging");
- timer.start(CHARGE_TIME);
- state = CHARGING;
- }
- }
-
- }
-
- if (state == CHARGING) {
- if (timer.check()) {
- sprite->set_action("attacking");
- timer.start(ATTACK_TIME);
- state = ATTACKING;
- physic.enable_gravity(false);
- physic.set_velocity_x(SPEED * attackDirection.x);
- physic.set_velocity_y(SPEED * attackDirection.y);
- oldWallDirection.x = 0;
- oldWallDirection.y = 0;
- }
- }
-
- if (state == ATTACKING) {
- if (timer.check()) {
- timer.start(RECOVER_TIME);
- state = RECOVERING;
- sprite->set_action("idle");
- physic.enable_gravity(true);
- physic.set_velocity_x(0);
- physic.set_velocity_y(0);
- }
- }
-
- if (state == RECOVERING) {
- if (timer.check()) {
- state = IDLE;
- sprite->set_action("idle");
- physic.enable_gravity(true);
- physic.set_velocity_x(0);
- physic.set_velocity_y(0);
- }
- }
-
-}
-
-IMPLEMENT_FACTORY(AngryStone, "angrystone")
+++ /dev/null
-// $Id$
-//
-// AngryStone - A spiked block that charges towards the player
-// Copyright (C) 2006 Christoph Sommer <supertux@2006.expires.deltadevelopment.de>
-//
-// 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.
-
-#ifndef __ANGRYSTONE_H__
-#define __ANGRYSTONE_H__
-
-#include "badguy.hpp"
-
-class AngryStone : public BadGuy
-{
-public:
- AngryStone(const lisp::Lisp& reader);
-
- void activate();
- void write(lisp::Writer& writer);
- void collision_solid(const CollisionHit& hit);
- HitResponse collision_badguy(BadGuy& badguy, const CollisionHit& hit);
- void active_update(float elapsed_time);
- void kill_fall();
-
- virtual AngryStone* clone() const { return new AngryStone(*this); }
-
-protected:
- Vector attackDirection; /**< 1-normalized vector of current attack direction */
- Vector oldWallDirection; /**< if wall was hit during last attack: 1-normalized vector of last attack direction, (0,0) otherwise */
-
- Timer timer;
-
- enum AngryStoneState {
- IDLE,
- CHARGING,
- ATTACKING,
- RECOVERING
- };
- AngryStoneState state;
-
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#include <config.h>
-
-#include "badguy.hpp"
-#include "object/camera.hpp"
-#include "object/tilemap.hpp"
-#include "tile.hpp"
-#include "statistics.hpp"
-#include "game_session.hpp"
-#include "log.hpp"
-#include "level.hpp"
-#include "object/bullet.hpp"
-#include "main.hpp"
-#include "object/particles.hpp"
-#include "random_generator.hpp"
-
-static const float SQUISH_TIME = 2;
-static const float X_OFFSCREEN_DISTANCE = 1600;
-static const float Y_OFFSCREEN_DISTANCE = 1200;
-
-BadGuy::BadGuy(const Vector& pos, const std::string& sprite_name, int layer)
- : MovingSprite(pos, sprite_name, layer, COLGROUP_DISABLED), countMe(true),
- dir(LEFT), start_dir(AUTO), frozen(false), ignited(false),
- state(STATE_INIT), on_ground_flag(false)
-{
- start_position = bbox.p1;
-
- sound_manager->preload("sounds/squish.wav");
- sound_manager->preload("sounds/fall.wav");
-}
-
-BadGuy::BadGuy(const Vector& pos, Direction direction, const std::string& sprite_name, int layer)
- : MovingSprite(pos, sprite_name, layer, COLGROUP_DISABLED), countMe(true),
- dir(direction), start_dir(direction), frozen(false), ignited(false),
- state(STATE_INIT), on_ground_flag(false)
-{
- start_position = bbox.p1;
-
- sound_manager->preload("sounds/squish.wav");
- sound_manager->preload("sounds/fall.wav");
-}
-
-BadGuy::BadGuy(const lisp::Lisp& reader, const std::string& sprite_name, int layer)
- : MovingSprite(reader, sprite_name, layer, COLGROUP_DISABLED), countMe(true), dir(LEFT), start_dir(AUTO), frozen(false), ignited(false), state(STATE_INIT), on_ground_flag(false)
-{
- start_position = bbox.p1;
-
- std::string dir_str = "auto";
- reader.get("direction", dir_str);
- start_dir = str2dir( dir_str );
- dir = start_dir;
-
- reader.get("dead-script", dead_script);
-
- sound_manager->preload("sounds/squish.wav");
- sound_manager->preload("sounds/fall.wav");
-}
-
-void
-BadGuy::draw(DrawingContext& context)
-{
- if(!sprite)
- return;
- if(state == STATE_INIT || state == STATE_INACTIVE)
- return;
- if(state == STATE_FALLING) {
- DrawingEffect old_effect = context.get_drawing_effect();
- context.set_drawing_effect((DrawingEffect) (old_effect | VERTICAL_FLIP));
- sprite->draw(context, get_pos(), layer);
- context.set_drawing_effect(old_effect);
- } else {
- sprite->draw(context, get_pos(), layer);
- }
-}
-
-void
-BadGuy::update(float elapsed_time)
-{
- if(!Sector::current()->inside(bbox)) {
- remove_me();
- return;
- }
- if(is_offscreen()) {
- if (state == STATE_ACTIVE) deactivate();
- set_state(STATE_INACTIVE);
- }
-
- switch(state) {
- case STATE_ACTIVE:
- active_update(elapsed_time);
- break;
- case STATE_INIT:
- case STATE_INACTIVE:
- inactive_update(elapsed_time);
- try_activate();
- break;
- case STATE_SQUISHED:
- if(state_timer.check()) {
- remove_me();
- break;
- }
- movement = physic.get_movement(elapsed_time);
- break;
- case STATE_FALLING:
- movement = physic.get_movement(elapsed_time);
- break;
- }
-
- on_ground_flag = false;
-}
-
-Direction
-BadGuy::str2dir( std::string dir_str )
-{
- if( dir_str == "auto" )
- return AUTO;
- if( dir_str == "left" )
- return LEFT;
- if( dir_str == "right" )
- return RIGHT;
-
- //default to "auto"
- log_warning << "Badguy::str2dir: unknown direction \"" << dir_str << "\"" << std::endl;;
- return AUTO;
-}
-
-void
-BadGuy::activate()
-{
-}
-
-void
-BadGuy::deactivate()
-{
-}
-
-void
-BadGuy::write(lisp::Writer& )
-{
- log_warning << "tried to write out a generic badguy" << std::endl;
-}
-
-void
-BadGuy::active_update(float elapsed_time)
-{
- movement = physic.get_movement(elapsed_time);
-}
-
-void
-BadGuy::inactive_update(float )
-{
-}
-
-void
-BadGuy::collision_tile(uint32_t tile_attributes)
-{
- if(tile_attributes & Tile::HURTS) {
- if (tile_attributes & Tile::FIRE) {
- if (is_flammable()) ignite();
- }
- else if (tile_attributes & Tile::ICE) {
- if (is_freezable()) freeze();
- }
- else {
- kill_fall();
- }
- }
-}
-
-HitResponse
-BadGuy::collision(GameObject& other, const CollisionHit& hit)
-{
- switch(state) {
- case STATE_INIT:
- case STATE_INACTIVE:
- return ABORT_MOVE;
- case STATE_ACTIVE: {
- BadGuy* badguy = dynamic_cast<BadGuy*> (&other);
- if(badguy && badguy->state == STATE_ACTIVE && badguy->get_group() == COLGROUP_MOVING) {
-
- // hit from above?
- if (badguy->get_bbox().p2.y < (bbox.p1.y + 16)) {
- if(collision_squished(*badguy)) {
- return ABORT_MOVE;
- }
- }
-
- return collision_badguy(*badguy, hit);
- }
-
- Player* player = dynamic_cast<Player*> (&other);
- if(player) {
-
- // hit from above?
- if (player->get_bbox().p2.y < (bbox.p1.y + 16)) {
- if(collision_squished(*player)) {
- return ABORT_MOVE;
- }
- }
-
- return collision_player(*player, hit);
- }
-
- Bullet* bullet = dynamic_cast<Bullet*> (&other);
- if(bullet)
- return collision_bullet(*bullet, hit);
-
- return FORCE_MOVE;
- }
- case STATE_SQUISHED:
- return FORCE_MOVE;
- case STATE_FALLING:
- return FORCE_MOVE;
- }
-
- return ABORT_MOVE;
-}
-
-void
-BadGuy::collision_solid(const CollisionHit& hit)
-{
- physic.set_velocity_x(0);
- physic.set_velocity_y(0);
- update_on_ground_flag(hit);
-}
-
-HitResponse
-BadGuy::collision_player(Player& player, const CollisionHit& )
-{
- if(player.is_invincible()) {
- kill_fall();
- return ABORT_MOVE;
- }
-
- if(frozen)
- unfreeze();
- player.kill(false);
- return FORCE_MOVE;
-}
-
-HitResponse
-BadGuy::collision_badguy(BadGuy& , const CollisionHit& )
-{
- return FORCE_MOVE;
-}
-
-bool
-BadGuy::collision_squished(GameObject& )
-{
- return false;
-}
-
-HitResponse
-BadGuy::collision_bullet(Bullet& bullet, const CollisionHit& hit)
-{
- if (is_frozen()) {
- if(bullet.get_type() == FIRE_BONUS) {
- // fire bullet thaws frozen badguys
- unfreeze();
- bullet.remove_me();
- return ABORT_MOVE;
- } else {
- // other bullets ricochet
- bullet.ricochet(*this, hit);
- return FORCE_MOVE;
- }
- }
- else if (is_ignited()) {
- if(bullet.get_type() == ICE_BONUS) {
- // ice bullets extinguish ignited badguys
- extinguish();
- bullet.remove_me();
- return ABORT_MOVE;
- } else {
- // other bullets are absorbed by ignited badguys
- bullet.remove_me();
- return FORCE_MOVE;
- }
- }
- else if(bullet.get_type() == FIRE_BONUS && is_flammable()) {
- // fire bullets ignite flammable badguys
- ignite();
- bullet.remove_me();
- return ABORT_MOVE;
- }
- else if(bullet.get_type() == ICE_BONUS && is_freezable()) {
- // ice bullets freeze freezable badguys
- freeze();
- bullet.remove_me();
- return ABORT_MOVE;
- }
- else {
- // in all other cases, bullets ricochet
- bullet.ricochet(*this, hit);
- return FORCE_MOVE;
- }
-}
-
-void
-BadGuy::kill_squished(GameObject& object)
-{
- sound_manager->play("sounds/squish.wav", get_pos());
- physic.enable_gravity(true);
- physic.set_velocity_x(0);
- physic.set_velocity_y(0);
- set_state(STATE_SQUISHED);
- set_group(COLGROUP_MOVING_ONLY_STATIC);
- Player* player = dynamic_cast<Player*>(&object);
- if (player) {
- if (countMe) Sector::current()->get_level()->stats.badguys++;
- player->bounce(*this);
- }
-
- // start dead-script
- if(dead_script != "") {
- std::istringstream stream(dead_script);
- Sector::current()->run_script(stream, "dead-script");
- }
-}
-
-void
-BadGuy::kill_fall()
-{
- sound_manager->play("sounds/fall.wav", get_pos());
- if (countMe) Sector::current()->get_level()->stats.badguys++;
- physic.set_velocity_y(0);
- physic.enable_gravity(true);
- set_state(STATE_FALLING);
-
- // start dead-script
- if(dead_script != "") {
- std::istringstream stream(dead_script);
- Sector::current()->run_script(stream, "dead-script");
- }
-}
-
-void
-BadGuy::run_dead_script()
-{
- if (countMe)
- Sector::current()->get_level()->stats.badguys++;
-
- // start dead-script
- if(dead_script != "") {
- std::istringstream stream(dead_script);
- Sector::current()->run_script(stream, "dead-script");
- }
-}
-
-void
-BadGuy::set_state(State state)
-{
- if(this->state == state)
- return;
-
- State laststate = this->state;
- this->state = state;
- switch(state) {
- case STATE_SQUISHED:
- state_timer.start(SQUISH_TIME);
- break;
- case STATE_ACTIVE:
- set_group(COLGROUP_MOVING);
- bbox.set_pos(start_position);
- break;
- case STATE_INACTIVE:
- // was the badguy dead anyway?
- if(laststate == STATE_SQUISHED || laststate == STATE_FALLING) {
- remove_me();
- }
- set_group(COLGROUP_DISABLED);
- break;
- case STATE_FALLING:
- set_group(COLGROUP_DISABLED);
- break;
- default:
- break;
- }
-}
-
-bool
-BadGuy::is_offscreen()
-{
- float scroll_x = Sector::current()->camera->get_translation().x;
- float scroll_y = Sector::current()->camera->get_translation().y;
-
- if(bbox.p2.x < scroll_x - X_OFFSCREEN_DISTANCE
- || bbox.p1.x > scroll_x + X_OFFSCREEN_DISTANCE + SCREEN_WIDTH
- || bbox.p2.y < scroll_y - Y_OFFSCREEN_DISTANCE
- || bbox.p1.y > scroll_y + Y_OFFSCREEN_DISTANCE + SCREEN_HEIGHT)
- return true;
-
- return false;
-}
-
-void
-BadGuy::try_activate()
-{
- float scroll_x = Sector::current()->camera->get_translation().x;
- float scroll_y = Sector::current()->camera->get_translation().y;
-
- /* Activate badguys if they're just around the screen to avoid
- * the effect of having badguys suddenly popping up from nowhere.
- */
- //Badguy left of screen
- if (start_position.x > scroll_x - X_OFFSCREEN_DISTANCE &&
- start_position.x < scroll_x - bbox.get_width() &&
- start_position.y > scroll_y - Y_OFFSCREEN_DISTANCE &&
- start_position.y < scroll_y + SCREEN_HEIGHT + Y_OFFSCREEN_DISTANCE) {
- if (start_dir != AUTO) dir = start_dir; else dir = RIGHT;
- set_state(STATE_ACTIVE);
- activate();
- //Badguy right of screen
- } else if (start_position.x > scroll_x + SCREEN_WIDTH &&
- start_position.x < scroll_x + SCREEN_WIDTH + X_OFFSCREEN_DISTANCE &&
- start_position.y > scroll_y - Y_OFFSCREEN_DISTANCE &&
- start_position.y < scroll_y + SCREEN_HEIGHT + Y_OFFSCREEN_DISTANCE) {
- if (start_dir != AUTO) dir = start_dir; else dir = LEFT;
- set_state(STATE_ACTIVE);
- activate();
- //Badguy over or under screen
- } else if (start_position.x > scroll_x - X_OFFSCREEN_DISTANCE &&
- start_position.x < scroll_x + SCREEN_WIDTH + X_OFFSCREEN_DISTANCE &&
- ((start_position.y > scroll_y + SCREEN_HEIGHT &&
- start_position.y < scroll_y + SCREEN_HEIGHT + Y_OFFSCREEN_DISTANCE) ||
- (start_position.y > scroll_y - Y_OFFSCREEN_DISTANCE &&
- start_position.y < scroll_y - bbox.get_height() ))) {
- if (start_dir != AUTO) dir = start_dir;
- else{
- // if nearest player is to our right, start facing right
- Player* player = get_nearest_player();
- if (player && (player->get_bbox().p1.x > get_bbox().p2.x)) {
- dir = RIGHT;
- } else {
- dir = LEFT;
- }
- }
- set_state(STATE_ACTIVE);
- activate();
- } else if(state == STATE_INIT
- && start_position.x > scroll_x - X_OFFSCREEN_DISTANCE
- && start_position.x < scroll_x + X_OFFSCREEN_DISTANCE + SCREEN_WIDTH
- && start_position.y > scroll_y - Y_OFFSCREEN_DISTANCE
- && start_position.y < scroll_y + Y_OFFSCREEN_DISTANCE + SCREEN_HEIGHT ) {
- if (start_dir != AUTO) {
- dir = start_dir;
- } else {
- // if nearest player is to our right, start facing right
- Player* player = get_nearest_player();
- if (player && (player->get_bbox().p1.x > get_bbox().p2.x)) {
- dir = RIGHT;
- } else {
- dir = LEFT;
- }
- }
- set_state(STATE_ACTIVE);
- activate();
- }
-}
-
-bool
-BadGuy::might_fall(int height)
-{
- // make sure we check for at least a 1-pixel fall
- assert(height > 0);
-
- float x1;
- float x2;
- float y1 = bbox.p2.y + 1;
- float y2 = bbox.p2.y + 1 + height;
- if (dir == LEFT) {
- x1 = bbox.p1.x - 1;
- x2 = bbox.p1.x - 1;
- } else {
- x1 = bbox.p2.x + 1;
- x2 = bbox.p2.x + 1;
- }
- return Sector::current()->is_free_of_statics(Rect(x1, y1, x2, y2));
-}
-
-Player*
-BadGuy::get_nearest_player()
-{
- // FIXME: does not really return nearest player
-
- std::vector<Player*> players = Sector::current()->get_players();
- for (std::vector<Player*>::iterator playerIter = players.begin(); playerIter != players.end(); ++playerIter) {
- Player* player = *playerIter;
- return player;
- }
-
- return 0;
-}
-
-void
-BadGuy::update_on_ground_flag(const CollisionHit& hit)
-{
- if (hit.bottom) {
- on_ground_flag = true;
- floor_normal = hit.slope_normal;
- }
-}
-
-bool
-BadGuy::on_ground()
-{
- return on_ground_flag;
-}
-
-Vector
-BadGuy::get_floor_normal()
-{
- return floor_normal;
-}
-
-void
-BadGuy::freeze()
-{
- set_group(COLGROUP_MOVING_STATIC);
- frozen = true;
-}
-
-void
-BadGuy::unfreeze()
-{
- set_group(COLGROUP_MOVING);
- frozen = false;
-}
-
-bool
-BadGuy::is_freezable() const
-{
- return false;
-}
-
-bool
-BadGuy::is_frozen() const
-{
- return frozen;
-}
-
-void
-BadGuy::ignite()
-{
- kill_fall();
-}
-
-void
-BadGuy::extinguish()
-{
-}
-
-bool
-BadGuy::is_flammable() const
-{
- return true;
-}
-
-bool
-BadGuy::is_ignited() const
-{
- return ignited;
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __BADGUY_H__
-#define __BADGUY_H__
-
-// moved them here to make it less typing when implementing new badguys
-#include <math.h>
-#include "timer.hpp"
-#include "object/moving_sprite.hpp"
-#include "physic.hpp"
-#include "object/player.hpp"
-#include "serializable.hpp"
-#include "resources.hpp"
-#include "sector.hpp"
-#include "direction.hpp"
-#include "object_factory.hpp"
-#include "lisp/parser.hpp"
-#include "lisp/lisp.hpp"
-#include "lisp/writer.hpp"
-#include "video/drawing_context.hpp"
-#include "audio/sound_manager.hpp"
-#include "audio/sound_source.hpp"
-
-class BadGuy : public MovingSprite, protected UsesPhysic, public Serializable
-{
-public:
- BadGuy(const Vector& pos, const std::string& sprite_name, int layer = LAYER_OBJECTS);
- BadGuy(const Vector& pos, Direction direction, const std::string& sprite_name, int layer = LAYER_OBJECTS);
- BadGuy(const lisp::Lisp& reader, const std::string& sprite_name, int layer = LAYER_OBJECTS);
-
- /** Called when the badguy is drawn. The default implementation simply draws
- * the badguy sprite on screen
- */
- virtual void draw(DrawingContext& context);
- /** Called each frame. The default implementation checks badguy state and
- * calls active_update and inactive_update
- */
- virtual void update(float elapsed_time);
- /** Called when a collision with another object occured. The default
- * implemetnation calls collision_player, collision_solid, collision_badguy
- * and collision_squished
- */
- virtual HitResponse collision(GameObject& other, const CollisionHit& hit);
-
- /** Called when a collision with tile with special attributes occured */
- virtual void collision_tile(uint32_t tile_attributes);
-
- /** Set the badguy to kill/falling state, which makes him falling of the
- * screen (his sprite is turned upside-down)
- */
- virtual void kill_fall();
-
- /** Call this, if you use custom kill_fall() or kill_squashed(GameObject& object) */
- virtual void run_dead_script();
-
- /** Writes out the badguy into the included lisp::Writer. Useful e.g. when
- * converting an old-format level to the new format.
- */
- virtual void write(lisp::Writer& writer);
-
- /**
- * True if this badguy can break bricks or open bonusblocks in his current form.
- */
- virtual bool can_break()
- {
- return false;
- }
-
- Vector get_start_position() const
- {
- return start_position;
- }
- void set_start_position(const Vector& vec)
- {
- start_position = vec;
- }
-
- /** Count this badguy to the statistics? This value should not be changed
- * during runtime. */
- bool countMe;
-
- /**
- * Called when hit by a fire bullet, and is_flammable() returns true
- */
- virtual void ignite();
-
- /**
- * Called to revert a badguy when is_ignited() returns true
- */
- virtual void extinguish();
-
- /**
- * Returns whether to call ignite() when a badguy gets hit by a fire bullet
- */
- virtual bool is_flammable() const;
-
- /**
- * Returns whether this badguys is currently on fire
- */
- bool is_ignited() const;
-
- /**
- * Called when hit by an ice bullet, and is_freezable() returns true.
- */
- virtual void freeze();
-
- /**
- * Called to unfreeze the badguy.
- */
- virtual void unfreeze();
-
- virtual bool is_freezable() const;
-
- bool is_frozen() const;
-
-protected:
- enum State {
- STATE_INIT,
- STATE_INACTIVE,
- STATE_ACTIVE,
- STATE_SQUISHED,
- STATE_FALLING
- };
-
- /** Called when the badguy collided with a player */
- virtual HitResponse collision_player(Player& player, const CollisionHit& hit);
- /** Called when the badguy collided with solid ground */
- virtual void collision_solid(const CollisionHit& hit);
- /** Called when the badguy collided with another badguy */
- virtual HitResponse collision_badguy(BadGuy& other, const CollisionHit& hit);
-
- /** Called when the player hit the badguy from above. You should return true
- * if the badguy was squished, false if squishing wasn't possible
- */
- virtual bool collision_squished(GameObject& object);
-
- /** Called when the badguy collided with a bullet */
- virtual HitResponse collision_bullet(Bullet& bullet, const CollisionHit& hit);
-
- /** called each frame when the badguy is activated. */
- virtual void active_update(float elapsed_time);
- /** called each frame when the badguy is not activated. */
- virtual void inactive_update(float elapsed_time);
-
- /**
- * called when the badguy has been activated. (As a side effect the dir
- * variable might have been changed so that it faces towards the player.
- */
- virtual void activate();
- /** called when the badguy has been deactivated */
- virtual void deactivate();
-
- void kill_squished(GameObject& object);
-
- void set_state(State state);
- State get_state() const
- { return state; }
-
- /**
- * returns a pointer to the nearest player or 0 if no player is available
- */
- Player* get_nearest_player();
-
- /// is the enemy activated
- bool activated;
- /**
- * initial position of the enemy. Also the position where enemy respawns when
- * after being deactivated.
- */
- bool is_offscreen();
- /**
- * Returns true if we might soon fall at least @c height pixels. Minimum
- * value for height is 1 pixel
- */
- bool might_fall(int height = 1);
-
- Vector start_position;
-
- /**
- * The direction we currently face in
- */
- Direction dir;
-
- /**
- * The direction we initially faced in
- */
- Direction start_dir;
-
- /**
- * Get Direction from String.
- */
- Direction str2dir( std::string dir_str );
-
- /**
- * Update on_ground_flag judging by solid collision @c hit.
- * This gets called from the base implementation of collision_solid, so call this when overriding collision_solid's default behaviour.
- */
- void update_on_ground_flag(const CollisionHit& hit);
-
- /**
- * Returns true if we touched ground in the past frame
- * This only works if update_on_ground_flag() gets called in collision_solid.
- */
- bool on_ground();
-
- /**
- * Returns floor normal stored the last time when update_on_ground_flag was called and we touched something solid from above.
- */
- Vector get_floor_normal();
-
- bool frozen;
- bool ignited; /**< true if this badguy is currently on fire */
-
- std::string dead_script; /**< script to execute when badguy is killed */
-
-private:
- void try_activate();
-
- State state;
- Timer state_timer;
- bool on_ground_flag; /**< true if we touched something solid from above and update_on_ground_flag was called last frame */
- Vector floor_normal; /**< floor normal stored the last time when update_on_ground_flag was called and we touched something solid from above */
-
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include "bomb.hpp"
-#include "random_generator.hpp"
-#include "object/explosion.hpp"
-
-Bomb::Bomb(const Vector& pos, Direction dir, std::string custom_sprite /*= "images/creatures/mr_bomb/mr_bomb.sprite"*/ )
- : BadGuy( pos, dir, custom_sprite )
-{
- state = STATE_TICKING;
- set_action(dir == LEFT ? "ticking-left" : "ticking-right", 1);
- countMe = false;
-
- ticking.reset(sound_manager->create_sound_source("sounds/fizz.wav"));
- ticking->set_position(get_pos());
- ticking->set_looping(true);
- ticking->set_gain(2.0);
- ticking->set_reference_distance(32);
- ticking->play();
-}
-
-Bomb::Bomb(const Bomb& other)
- : BadGuy(other), state(other.state)
-{
- if (state == STATE_TICKING) {
- ticking.reset(sound_manager->create_sound_source("sounds/fizz.wav"));
- ticking->set_position(get_pos());
- ticking->set_looping(true);
- ticking->set_gain(2.0);
- ticking->set_reference_distance(32);
- ticking->play();
- }
-}
-
-void
-Bomb::write(lisp::Writer& )
-{
- // bombs are only temporarily so don't write them out...
-}
-
-void
-Bomb::collision_solid(const CollisionHit& hit)
-{
- if(hit.bottom)
- physic.set_velocity_y(0);
-}
-
-HitResponse
-Bomb::collision_player(Player& , const CollisionHit& )
-{
- return ABORT_MOVE;
-}
-
-HitResponse
-Bomb::collision_badguy(BadGuy& , const CollisionHit& )
-{
- return ABORT_MOVE;
-}
-
-void
-Bomb::active_update(float )
-{
- ticking->set_position(get_pos());
- if(sprite->animation_done()) {
- explode();
- }
-}
-
-void
-Bomb::explode()
-{
- ticking->stop();
-
- remove_me();
- Explosion* explosion = new Explosion(get_bbox().get_middle());
- Sector::current()->add_object(explosion);
-
- run_dead_script();
-}
-
-void
-Bomb::kill_fall()
-{
- explode();
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __BOMB_H__
-#define __BOMB_H__
-
-#include "badguy.hpp"
-
-class Bomb : public BadGuy
-{
-public:
- Bomb(const Vector& pos, Direction dir, std::string custom_sprite = "images/creatures/mr_bomb/bomb.sprite" );
- Bomb(const Bomb& bomb);
-
- void write(lisp::Writer& writer);
- void collision_solid(const CollisionHit& hit);
- HitResponse collision_player(Player& player, const CollisionHit& hit);
- HitResponse collision_badguy(BadGuy& badguy, const CollisionHit& hit);
- void active_update(float elapsed_time);
- void kill_fall();
- void explode();
-
-private:
- enum State {
- STATE_TICKING
- };
-
- State state;
-
- std::auto_ptr<SoundSource> ticking;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include "bouncing_snowball.hpp"
-
-static const float JUMPSPEED = -450;
-static const float WALKSPEED = 80;
-
-BouncingSnowball::BouncingSnowball(const lisp::Lisp& reader)
- : BadGuy(reader, "images/creatures/bouncing_snowball/bouncing_snowball.sprite")
-{
-}
-
-BouncingSnowball::BouncingSnowball(const Vector& pos, Direction d)
- : BadGuy(pos, d, "images/creatures/bouncing_snowball/bouncing_snowball.sprite")
-{
-}
-
-void
-BouncingSnowball::write(lisp::Writer& writer)
-{
- writer.start_list("bouncingsnowball");
-
- writer.write_float("x", start_position.x);
- writer.write_float("y", start_position.y);
-
- writer.end_list("bouncingsnowball");
-}
-
-void
-BouncingSnowball::activate()
-{
- physic.set_velocity_x(dir == LEFT ? -WALKSPEED : WALKSPEED);
- sprite->set_action(dir == LEFT ? "left" : "right");
-}
-
-bool
-BouncingSnowball::collision_squished(GameObject& object)
-{
- sprite->set_action("squished");
- kill_squished(object);
- return true;
-}
-
-void
-BouncingSnowball::collision_solid(const CollisionHit& hit)
-{
- if(hit.bottom) {
- if(get_state() == STATE_ACTIVE) {
- physic.set_velocity_y(JUMPSPEED);
- } else {
- physic.set_velocity_y(0);
- }
- } else if(hit.top) {
- physic.set_velocity_y(0);
- }
-
- if(hit.left || hit.right) { // left or right collision
- dir = dir == LEFT ? RIGHT : LEFT;
- sprite->set_action(dir == LEFT ? "left" : "right");
- physic.set_velocity_x(-physic.get_velocity_x());
- }
-}
-
-HitResponse
-BouncingSnowball::collision_badguy(BadGuy& , const CollisionHit& hit)
-{
- collision_solid(hit);
- return CONTINUE;
-}
-
-IMPLEMENT_FACTORY(BouncingSnowball, "bouncingsnowball")
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __BOUNCING_SNOWBALL_H__
-#define __BOUNCING_SNOWBALL_H__
-
-#include "badguy.hpp"
-
-class BouncingSnowball : public BadGuy
-{
-public:
- BouncingSnowball(const lisp::Lisp& reader);
- BouncingSnowball(const Vector& pos, Direction d);
-
- void activate();
- void write(lisp::Writer& writer);
- void collision_solid(const CollisionHit& hit);
- HitResponse collision_badguy(BadGuy& badguy, const CollisionHit& hit);
-
- virtual BouncingSnowball* clone() const { return new BouncingSnowball(*this); }
-
-protected:
- bool collision_squished(GameObject& object);
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// Dart - Your average poison dart
-// Copyright (C) 2006 Christoph Sommer <supertux@2006.expires.deltadevelopment.de>
-//
-// 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.
-
-#include <config.h>
-
-#include "dart.hpp"
-
-namespace {
- const float SPEED = 200;
-}
-
-static const std::string SOUNDFILE = "sounds/flame.wav";
-
-Dart::Dart(const lisp::Lisp& reader)
- : BadGuy(reader, "images/creatures/dart/dart.sprite"), parent(0)
-{
- physic.enable_gravity(false);
- countMe = false;
- sound_manager->preload("sounds/darthit.wav");
- sound_manager->preload("sounds/stomp.wav");
-}
-
-Dart::Dart(const Vector& pos, Direction d, const BadGuy* parent = 0)
- : BadGuy(pos, d, "images/creatures/dart/dart.sprite"), parent(parent)
-{
- physic.enable_gravity(false);
- countMe = false;
- sound_manager->preload("sounds/darthit.wav");
- sound_manager->preload("sounds/stomp.wav");
-}
-
-Dart::Dart(const Dart& other)
- : BadGuy(other), parent(other.parent)
-{
- sound_source.reset(sound_manager->create_sound_source(SOUNDFILE));
- sound_manager->preload("sounds/darthit.wav");
- sound_manager->preload("sounds/stomp.wav");
-}
-
-Dart::~Dart()
-{
-}
-
-bool
-Dart::updatePointers(const GameObject* from_object, GameObject* to_object)
-{
- if (from_object == parent) {
- parent = dynamic_cast<Dart*>(to_object);
- return true;
- }
- return false;
-}
-
-void
-Dart::write(lisp::Writer& writer)
-{
- writer.start_list("dart");
- writer.write_float("x", start_position.x);
- writer.write_float("y", start_position.y);
- writer.end_list("dart");
-}
-
-void
-Dart::activate()
-{
- physic.set_velocity_x(dir == LEFT ? -::SPEED : ::SPEED);
- sprite->set_action(dir == LEFT ? "flying-left" : "flying-right");
-
- sound_source.reset(sound_manager->create_sound_source(SOUNDFILE));
- sound_source->set_position(get_pos());
- sound_source->set_looping(true);
- sound_source->set_gain(1.0);
- sound_source->set_reference_distance(32);
- sound_source->play();
-}
-
-void
-Dart::deactivate()
-{
- sound_source.reset();
- remove_me();
-}
-
-void
-Dart::active_update(float elapsed_time)
-{
- BadGuy::active_update(elapsed_time);
- sound_source->set_position(get_pos());
-}
-
-void
-Dart::collision_solid(const CollisionHit& )
-{
- sound_manager->play("sounds/darthit.wav", get_pos());
- remove_me();
-}
-
-HitResponse
-Dart::collision_badguy(BadGuy& badguy, const CollisionHit& )
-{
- // ignore collisions with parent
- if (&badguy == parent) {
- return FORCE_MOVE;
- }
- sound_manager->play("sounds/stomp.wav", get_pos());
- remove_me();
- badguy.kill_fall();
- return ABORT_MOVE;
-}
-
-HitResponse
-Dart::collision_player(Player& player, const CollisionHit& hit)
-{
- sound_manager->play("sounds/stomp.wav", get_pos());
- remove_me();
- return BadGuy::collision_player(player, hit);
-}
-
-IMPLEMENT_FACTORY(Dart, "dart")
+++ /dev/null
-// $Id$
-//
-// Dart - Your average poison dart
-// Copyright (C) 2006 Christoph Sommer <supertux@2006.expires.deltadevelopment.de>
-//
-// 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.
-
-#ifndef __DART_H__
-#define __DART_H__
-
-#include "badguy.hpp"
-
-/**
- * Badguy "Dart" - Your average poison dart
- */
-class Dart : public BadGuy
-{
-public:
- Dart(const lisp::Lisp& reader);
- Dart(const Vector& pos, Direction d, const BadGuy* parent);
- Dart(const Dart& dart);
- ~Dart();
-
- void activate();
- void deactivate();
- void write(lisp::Writer& writer);
-
- void active_update(float elapsed_time);
-
- void collision_solid(const CollisionHit& hit);
- HitResponse collision_badguy(BadGuy& badguy, const CollisionHit& hit);
- HitResponse collision_player(Player& player, const CollisionHit& hit);
-
- virtual Dart* clone() const { return new Dart(*this); }
-
- virtual bool updatePointers(const GameObject* from_object, GameObject* to_object);
-
-protected:
- const BadGuy* parent; /**< collisions with this BadGuy will be ignored */
- std::auto_ptr<SoundSource> sound_source; /**< SoundSource for ambient sound */
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// DartTrap - Shoots a Dart at regular intervals
-// Copyright (C) 2006 Christoph Sommer <supertux@2006.expires.deltadevelopment.de>
-//
-// 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.
-
-#include <config.h>
-
-#include "darttrap.hpp"
-#include "dart.hpp"
-
-namespace {
- const float MUZZLE_Y = 25; /**< [px] muzzle y-offset from top */
-}
-
-DartTrap::DartTrap(const lisp::Lisp& reader)
- : BadGuy(reader, "images/creatures/darttrap/darttrap.sprite", LAYER_TILES-1), initial_delay(0), fire_delay(2), ammo(-1), state(IDLE)
-{
- reader.get("initial-delay", initial_delay);
- reader.get("fire-delay", fire_delay);
- reader.get("ammo", ammo);
- countMe = false;
- sound_manager->preload("sounds/dartfire.wav");
- if (start_dir == AUTO) log_warning << "Setting a DartTrap's direction to AUTO is no good idea" << std::endl;
-}
-
-void
-DartTrap::write(lisp::Writer& writer)
-{
- writer.start_list("darttrap");
- writer.write_float("x", start_position.x);
- writer.write_float("y", start_position.y);
- writer.write_float("initial-delay", initial_delay);
- writer.write_float("fire-delay", fire_delay);
- writer.write_int("ammo", ammo);
- writer.end_list("darttrap");
-}
-
-void
-DartTrap::activate()
-{
- state = IDLE;
- sprite->set_action(dir == LEFT ? "idle-left" : "idle-right");
- set_group(COLGROUP_DISABLED);
-
- if (initial_delay == 0) initial_delay = 0.1f;
- fire_timer.start(initial_delay);
-}
-
-HitResponse
-DartTrap::collision_player(Player& , const CollisionHit& )
-{
- return ABORT_MOVE;
-}
-
-void
-DartTrap::active_update(float )
-{
- if (state == IDLE) {
- if ((ammo != 0) && (fire_timer.check())) {
- if (ammo > 0) ammo--;
- load();
- fire_timer.start(fire_delay);
- }
- }
- if (state == LOADING) {
- if (sprite->animation_done()) {
- fire();
- }
- }
-}
-
-void
-DartTrap::load()
-{
- state = LOADING;
- sprite->set_action(dir == LEFT ? "loading-left" : "loading-right", 1);
-}
-
-void
-DartTrap::fire()
-{
- float px = get_pos().x;
- if (dir == RIGHT) px += 5;
- float py = get_pos().y;
- py += MUZZLE_Y;
-
- sound_manager->play("sounds/dartfire.wav", get_pos());
- Sector::current()->add_object(new Dart(Vector(px, py), dir, this));
- state = IDLE;
- sprite->set_action(dir == LEFT ? "idle-left" : "idle-right");
-}
-
-IMPLEMENT_FACTORY(DartTrap, "darttrap")
+++ /dev/null
-// $Id$
-//
-// DartTrap - Shoots a Dart at regular intervals
-// Copyright (C) 2006 Christoph Sommer <supertux@2006.expires.deltadevelopment.de>
-//
-// 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.
-
-#ifndef __DARTTRAP_H__
-#define __DARTTRAP_H__
-
-#include "badguy.hpp"
-#include "timer.hpp"
-
-/**
- * Badguy "DartTrap" - Shoots a Dart at regular intervals
- */
-class DartTrap : public BadGuy
-{
-public:
- DartTrap(const lisp::Lisp& reader);
-
- void activate();
- void write(lisp::Writer& writer);
- void active_update(float elapsed_time);
- HitResponse collision_player(Player& player, const CollisionHit& hit);
-
- virtual DartTrap* clone() const { return new DartTrap(*this); }
-
-protected:
- enum State {
- IDLE, LOADING
- };
-
- void load(); /**< load a shot */
- void fire(); /**< fire a shot */
-
- float initial_delay; /**< time to wait before firing first shot */
- float fire_delay; /**< reload time */
- int ammo; /**< ammo left (-1 means unlimited) */
-
- State state; /**< current state */
- Timer fire_timer; /**< time until new shot is fired */
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include "dispenser.hpp"
-#include "badguy/bouncing_snowball.hpp"
-#include "badguy/snowball.hpp"
-#include "badguy/mrbomb.hpp"
-#include "badguy/mriceblock.hpp"
-#include "badguy/mrrocket.hpp"
-#include "badguy/poisonivy.hpp"
-#include "badguy/snail.hpp"
-#include "badguy/skullyhop.hpp"
-#include "random_generator.hpp"
-
-Dispenser::Dispenser(const lisp::Lisp& reader)
- : BadGuy(reader, "images/creatures/dispenser/dispenser.sprite")
-{
- reader.get("cycle", cycle);
- reader.get("badguy", badguy);
- if (badguy == "mrrocket") {
- if (start_dir == AUTO) log_warning << "Setting a Dispenser's direction to AUTO is no good idea" << std::endl;
- sprite->set_action(dir == LEFT ? "working-left" : "working-right");
- }
- else {sprite->set_action("dropper");}
- bbox.set_size(sprite->get_current_hitbox_width(), sprite->get_current_hitbox_height());
- countMe = false;
-}
-
-void
-Dispenser::write(lisp::Writer& writer)
-{
- writer.start_list("dispenser");
-
- writer.write_float("x", start_position.x);
- writer.write_float("y", start_position.y);
- writer.write_float("cycle", cycle);
- writer.write_string("badguy", badguy);
-
- writer.end_list("dispenser");
-}
-
-void
-Dispenser::activate()
-{
- if(frozen)
- return;
- dispense_timer.start(cycle, true);
- launch_badguy();
-}
-
-void
-Dispenser::deactivate()
-{
- dispense_timer.stop();
-}
-
-//TODO: Add launching velocity to certain badguys
-bool
-Dispenser::collision_squished(GameObject& object)
-{
- //TODO: Should it act like a normal tile when killed?
- sprite->set_action(dir == LEFT ? "broken-left" : "broken-right");
- dispense_timer.start(0);
- Player* player = dynamic_cast<Player*>(&object);
- if (player) player->bounce(*this);
- kill_squished(object);
- return true;
-}
-
-void
-Dispenser::active_update(float )
-{
- if (dispense_timer.check()) {
- launch_badguy();
- }
-}
-
-// Add themed randomizer
-void
-Dispenser::launch_badguy()
-{
- //FIXME: Does is_offscreen() work right here?
- if (!is_offscreen()) {
- if (badguy == "snowball")
- Sector::current()->add_object(new SnowBall(Vector(get_pos().x, get_pos().y+32), dir));
- else if (badguy == "bouncingsnowball")
- Sector::current()->add_object(new BouncingSnowball(Vector(get_pos().x, get_pos().y+32), dir));
- else if (badguy == "mrbomb")
- Sector::current()->add_object(new MrBomb(Vector(get_pos().x, get_pos().y+32), dir));
- else if (badguy == "mriceblock")
- Sector::current()->add_object(new MrIceBlock(Vector(get_pos().x, get_pos().y+32), dir));
- else if (badguy == "snail")
- Sector::current()->add_object(new Snail(Vector(get_pos().x, get_pos().y+32), dir));
- else if (badguy == "mrrocket") {
- Sector::current()->add_object(new MrRocket(Vector(get_pos().x+(dir == LEFT ? -32 : 32), get_pos().y), dir));}
- else if (badguy == "poisonivy")
- Sector::current()->add_object(new PoisonIvy(Vector(get_pos().x, get_pos().y+32), dir));
- else if (badguy == "skullyhop")
- Sector::current()->add_object(new SkullyHop(Vector(get_pos().x, get_pos().y+44), dir));
- else if (badguy == "random")
- {
- switch (systemRandom.rand(7))
- {
- case 0: Sector::current()->add_object(new SnowBall(Vector(get_pos().x, get_pos().y+32), dir)); break;
- case 1: Sector::current()->add_object(new BouncingSnowball(Vector(get_pos().x, get_pos().y+32), dir)); break;
- case 2: Sector::current()->add_object(new MrBomb(Vector(get_pos().x, get_pos().y+32), dir)); break;
- case 3: Sector::current()->add_object(new MrIceBlock(Vector(get_pos().x, get_pos().y+32), dir)); break;
- case 4: Sector::current()->add_object(new PoisonIvy(Vector(get_pos().x, get_pos().y+32), dir)); break;
- case 5: Sector::current()->add_object(new Snail(Vector(get_pos().x, get_pos().y+32), dir)); break;
- case 6: Sector::current()->add_object(new SkullyHop(Vector(get_pos().x, get_pos().y+44), dir)); break;
- }
- }
- }
-}
-
-void
-Dispenser::freeze()
-{
- BadGuy::freeze();
- dispense_timer.stop();
-}
-
-void
-Dispenser::unfreeze()
-{
- BadGuy::unfreeze();
- activate();
-}
-
-bool
-Dispenser::is_freezable() const
-{
- return true;
-}
-IMPLEMENT_FACTORY(Dispenser, "dispenser")
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __DISPENSER_H__
-#define __DISPENSER_H__
-
-#include "badguy.hpp"
-#include "timer.hpp"
-
-class Dispenser : public BadGuy
-{
-public:
- Dispenser(const lisp::Lisp& reader);
-
- void activate();
- void deactivate();
- void write(lisp::Writer& writer);
- void active_update(float elapsed_time);
-
- void freeze();
- void unfreeze();
- bool is_freezable() const;
-
- virtual Dispenser* clone() const { return new Dispenser(*this); }
-
-protected:
- bool collision_squished(GameObject& object);
- void launch_badguy();
- float cycle;
- std::string badguy;
- Timer dispense_timer;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include "fish.hpp"
-#include "tile.hpp"
-#include "object/tilemap.hpp"
-#include "log.hpp"
-
-static const float FISH_JUMP_POWER = -600;
-static const float FISH_WAIT_TIME = 1;
-
-Fish::Fish(const lisp::Lisp& reader)
- : BadGuy(reader, "images/creatures/fish/fish.sprite", LAYER_TILES-1), stop_y(0)
-{
- physic.enable_gravity(true);
-}
-
-Fish::Fish(const Vector& pos)
- : BadGuy(pos, "images/creatures/fish/fish.sprite", LAYER_TILES-1), stop_y(0)
-{
- physic.enable_gravity(true);
-}
-
-void
-Fish::write(lisp::Writer& writer)
-{
- writer.start_list("fish");
-
- writer.write_float("x", start_position.x);
- writer.write_float("y", start_position.y);
-
- writer.end_list("fish");
-}
-
-void
-Fish::collision_solid(const CollisionHit& chit)
-{
- hit(chit);
-}
-
-HitResponse
-Fish::collision_badguy(BadGuy& , const CollisionHit& chit)
-{
- return hit(chit);
-}
-
-void
-Fish::draw(DrawingContext& context)
-{
- if(waiting.started())
- return;
-
- BadGuy::draw(context);
-}
-
-HitResponse
-Fish::hit(const CollisionHit& hit)
-{
- if(hit.top) {
- physic.set_velocity_y(0);
- }
-
- return CONTINUE;
-}
-
-void
-Fish::collision_tile(uint32_t tile_attributes)
-{
- if ((tile_attributes & Tile::WATER) && (physic.get_velocity_y() >= 0)) {
-
- // initialize stop position if uninitialized
- if (stop_y == 0) stop_y = get_pos().y + get_bbox().get_height();
-
- // stop when we have reached the stop position
- if (get_pos().y >= stop_y) {
- if(!frozen)
- start_waiting();
- movement = Vector(0, 0);
- }
-
- }
-}
-
-void
-Fish::active_update(float elapsed_time)
-{
- BadGuy::active_update(elapsed_time);
-
- // waited long enough?
- if(waiting.check()) {
- jump();
- }
-
- // set sprite
- if(!frozen)
- sprite->set_action(physic.get_velocity_y() < 0 ? "normal" : "down");
-
- // we can't afford flying out of the tilemap, 'cause the engine would remove us.
- if ((get_pos().y - 31.8) < 0) // too high, let us fall
- {
- physic.set_velocity_y(0);
- physic.enable_gravity(true);
- }
-}
-
-void
-Fish::start_waiting()
-{
- waiting.start(FISH_WAIT_TIME);
- set_group(COLGROUP_DISABLED);
- physic.enable_gravity(false);
- physic.set_velocity_y(0);
-}
-
-void
-Fish::jump()
-{
- physic.set_velocity_y(FISH_JUMP_POWER);
- physic.enable_gravity(true);
- set_group(COLGROUP_MOVING);
-}
-
-void
-Fish::freeze()
-{
- BadGuy::freeze();
- sprite->set_action(physic.get_velocity_y() < 0 ? "iced" : "iced-down");
- waiting.stop();
-}
-
-void
-Fish::unfreeze()
-{ // does this happen at all? (or do fishes die when they fall frozen?)
- BadGuy::unfreeze();
- start_waiting();
-}
-
-bool
-Fish::is_freezable() const
-{
- return true;
-}
-
-IMPLEMENT_FACTORY(Fish, "fish")
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __FISH_H__
-#define __FISH_H__
-
-#include "badguy.hpp"
-
-class Fish : public BadGuy
-{
-public:
- Fish(const lisp::Lisp& );
- Fish(const Vector& pos);
-
- void draw(DrawingContext& context);
-
- void collision_solid(const CollisionHit& hit);
- HitResponse collision_badguy(BadGuy& , const CollisionHit& );
- void collision_tile(uint32_t tile_attributes);
-
- void write(lisp::Writer& );
- void active_update(float);
-
- void freeze();
- void unfreeze();
- bool is_freezable() const;
-
- virtual Fish* clone() const { return new Fish(*this); }
-
-private:
- HitResponse hit(const CollisionHit& );
- void start_waiting();
- void jump();
-
- Timer waiting;
- float stop_y; /**< y-coordinate to stop at */
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include "flame.hpp"
-#include "log.hpp"
-
-static const std::string SOUNDFILE = "sounds/flame.wav";
-
-Flame::Flame(const lisp::Lisp& reader)
- : BadGuy(reader, "images/creatures/flame/flame.sprite", LAYER_FLOATINGOBJECTS), angle(0), radius(100), speed(2)
-{
- reader.get("radius", radius);
- reader.get("speed", speed);
- bbox.set_pos(Vector(start_position.x + cos(angle) * radius,
- start_position.y + sin(angle) * radius));
- countMe = false;
- sound_manager->preload(SOUNDFILE);
-}
-
-void
-Flame::write(lisp::Writer& writer)
-{
- writer.start_list("flame");
-
- writer.write_float("x", start_position.x);
- writer.write_float("y", start_position.y);
- writer.write_float("radius", radius);
- writer.write_float("speed", speed);
-
- writer.end_list("flame");
-}
-
-void
-Flame::active_update(float elapsed_time)
-{
- angle = fmodf(angle + elapsed_time * speed, (float) (2*M_PI));
- Vector newpos(start_position.x + cos(angle) * radius,
- start_position.y + sin(angle) * radius);
- movement = newpos - get_pos();
-
- sound_source->set_position(get_pos());
-}
-
-void
-Flame::activate()
-{
- set_group(COLGROUP_TOUCHABLE);
-
- sound_source.reset(sound_manager->create_sound_source(SOUNDFILE));
- sound_source->set_position(get_pos());
- sound_source->set_looping(true);
- sound_source->set_gain(2.0);
- sound_source->set_reference_distance(32);
- sound_source->play();
-}
-
-void
-Flame::deactivate()
-{
- sound_source.reset();
-}
-
-void
-Flame::kill_fall()
-{
-}
-
-IMPLEMENT_FACTORY(Flame, "flame")
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#ifndef __FLAME_H__
-#define __FLAME_H__
-
-#include "badguy.hpp"
-
-class Flame : public BadGuy
-{
-public:
- Flame(const lisp::Lisp& reader);
- Flame(const Flame& flame);
-
- void activate();
- void deactivate();
-
- void write(lisp::Writer& write);
- void active_update(float elapsed_time);
- void kill_fall();
-
-private:
- float angle;
- float radius;
- float speed;
-
- std::auto_ptr<SoundSource> sound_source;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include <stdio.h>
-
-#include "flyingsnowball.hpp"
-#include "random_generator.hpp"
-#include "object/sprite_particle.hpp"
-
-static const float FLYTIME = 1.0f;
-static const float FLYSPEED = -100.0f;
-
-namespace {
- const float PUFF_PROBABILITY = 0.1f; /**< chanche of puffs being spawned in the current cycle */
- const float PUFF_INTERVAL_MIN = 0.1f; /**< spawn new puff of smoke at most that often */
- const float PUFF_INTERVAL_MAX = 1.1f; /**< spawn new puff of smoke at least that often */
-}
-
-FlyingSnowBall::FlyingSnowBall(const lisp::Lisp& reader)
- : BadGuy(reader, "images/creatures/flying_snowball/flying_snowball.sprite")
-{
- physic.enable_gravity(false);
-}
-
-FlyingSnowBall::FlyingSnowBall(const Vector& pos)
- : BadGuy(pos, "images/creatures/flying_snowball/flying_snowball.sprite")
-{
- physic.enable_gravity(false);
-}
-
-void
-FlyingSnowBall::write(lisp::Writer& writer)
-{
- writer.start_list("flyingsnowball");
-
- writer.write_float("x", start_position.x);
- writer.write_float("y", start_position.y);
-
- writer.end_list("flyingsnowball");
-}
-
-void
-FlyingSnowBall::activate()
-{
- sprite->set_action(dir == LEFT ? "left" : "right");
- mode = FLY_UP;
- physic.set_velocity_y(FLYSPEED);
- timer.start(FLYTIME/2);
- puff_timer.start(systemRandom.randf(PUFF_INTERVAL_MIN, PUFF_INTERVAL_MAX));
-}
-
-bool
-FlyingSnowBall::collision_squished(GameObject& object)
-{
- sprite->set_action(dir == LEFT ? "squished-left" : "squished-right");
- kill_squished(object);
- return true;
-}
-
-void
-FlyingSnowBall::collision_solid(const CollisionHit& hit)
-{
- if(hit.top || hit.bottom) {
- physic.set_velocity_y(0);
- }
-}
-
-void
-FlyingSnowBall::active_update(float elapsed_time)
-{
- if(timer.check()) {
- if(mode == FLY_UP) {
- mode = FLY_DOWN;
- physic.set_velocity_y(-FLYSPEED);
-
- // stop puffing
- puff_timer.stop();
-
- } else if(mode == FLY_DOWN) {
- mode = FLY_UP;
- physic.set_velocity_y(FLYSPEED);
-
- // roll a dice whether to start puffing
- if (systemRandom.randf(0, 1) < PUFF_PROBABILITY) {
- puff_timer.start(systemRandom.randf(PUFF_INTERVAL_MIN, PUFF_INTERVAL_MAX));
- }
-
- }
- timer.start(FLYTIME);
- }
- movement=physic.get_movement(elapsed_time);
-
- Player* player = this->get_nearest_player();
- if (player) {
- dir = (player->get_pos().x > get_pos().x) ? RIGHT : LEFT;
- sprite->set_action(dir == LEFT ? "left" : "right");
- }
-
- // spawn smoke puffs
- if (puff_timer.check()) {
- Vector ppos = bbox.get_middle();
- Vector pspeed = Vector(systemRandom.randf(-10, 10), 150);
- Vector paccel = Vector(0,0);
- Sector::current()->add_object(new SpriteParticle("images/objects/particles/smoke.sprite", "default", ppos, ANCHOR_MIDDLE, pspeed, paccel, LAYER_OBJECTS-1));
- puff_timer.start(systemRandom.randf(PUFF_INTERVAL_MIN, PUFF_INTERVAL_MAX));
- }
-}
-
-IMPLEMENT_FACTORY(FlyingSnowBall, "flyingsnowball")
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __FLYINGSNOWBALL_H__
-#define __FLYINGSNOWBALL_H__
-
-#include "badguy.hpp"
-
-class FlyingSnowBall : public BadGuy
-{
-public:
- FlyingSnowBall(const lisp::Lisp& reader);
- FlyingSnowBall(const Vector& pos);
-
- void activate();
- void write(lisp::Writer& writer);
- void active_update(float elapsed_time);
- void collision_solid(const CollisionHit& hit);
-
- virtual FlyingSnowBall* clone() const { return new FlyingSnowBall(*this); }
-
-protected:
- enum FlyingSnowballMode {
- FLY_UP,
- FLY_DOWN
- };
- FlyingSnowballMode mode;
- bool collision_squished(GameObject& object);
-private:
- Timer timer;
- Timer puff_timer; /**< time until the next smoke puff is spawned */
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux - Boss "GhostTree"
-// Copyright (C) 2007 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#include <config.h>
-
-#include "ghosttree.hpp"
-#include "treewillowisp.hpp"
-#include "sprite/sprite_manager.hpp"
-#include "root.hpp"
-#include "random_generator.hpp"
-#include "object/lantern.hpp"
-
-static const size_t WILLOWISP_COUNT = 10;
-static const float ROOT_TOP_OFFSET = 64;
-static const float WILLOWISP_TOP_OFFSET = -64;
-static const Vector SUCK_TARGET_OFFSET = Vector(-16,-16);
-static const float SUCK_TARGET_SPREAD = 8;
-
-GhostTree::GhostTree(const lisp::Lisp& lisp)
- : BadGuy(lisp, "images/creatures/ghosttree/ghosttree.sprite",
- LAYER_OBJECTS - 10), mystate(STATE_IDLE),
- willo_spawn_y(0), willo_radius(200), willo_speed(1.8f), willo_color(0),
- treecolor(0), suck_lantern(0)
-{
- glow_sprite.reset(sprite_manager->create("images/creatures/ghosttree/ghosttree-glow.sprite"));
-}
-
-GhostTree::~GhostTree()
-{
-}
-
-void
-GhostTree::die()
-{
- mystate = STATE_DYING;
- sprite->set_action("dying", 1);
- glow_sprite->set_action("dying", 1);
-
- std::vector<TreeWillOWisp*>::iterator iter;
- for(iter = willowisps.begin(); iter != willowisps.end(); ++iter) {
- TreeWillOWisp *willo = *iter;
- willo->vanish();
- }
-}
-
-void
-GhostTree::activate()
-{
- willowisp_timer.start(1.0f, true);
- colorchange_timer.start(13, true);
- root_timer.start(5, true);
- set_group(COLGROUP_TOUCHABLE);
-}
-
-void
-GhostTree::active_update(float elapsed_time)
-{
- (void) elapsed_time;
-
- if (mystate == STATE_IDLE) {
- if(colorchange_timer.check()) {
- sound_manager->play("sounds/tree_howling.ogg", get_pos());
- suck_timer.start(3);
- treecolor = (treecolor + 1) % 3;
-
- Color col;
- switch(treecolor) {
- case 0: col = Color(1, 0, 0); break;
- case 1: col = Color(0, 1, 0); break;
- case 2: col = Color(0, 0, 1); break;
- case 3: col = Color(1, 1, 0); break;
- case 4: col = Color(1, 0, 1); break;
- case 5: col = Color(0, 1, 1); break;
- default: assert(false);
- }
- glow_sprite->set_color(col);
- }
-
- if(suck_timer.check()) {
- Color col = glow_sprite->get_color();
- sound_manager->play("sounds/tree_suck.ogg", get_pos());
- std::vector<TreeWillOWisp*>::iterator iter;
- for(iter = willowisps.begin(); iter != willowisps.end(); ++iter) {
- TreeWillOWisp *willo = *iter;
- if(willo->get_color() == col) {
- willo->start_sucking(get_bbox().get_middle() + SUCK_TARGET_OFFSET + Vector(systemRandom.randf(-SUCK_TARGET_SPREAD, SUCK_TARGET_SPREAD), systemRandom.randf(-SUCK_TARGET_SPREAD, SUCK_TARGET_SPREAD)));
- }
- }
- mystate = STATE_SUCKING;
- }
-
- if(willowisp_timer.check()) {
- if(willowisps.size() < WILLOWISP_COUNT) {
- Vector pos = Vector(bbox.get_width() / 2, bbox.get_height() / 2 + willo_spawn_y + WILLOWISP_TOP_OFFSET);
- TreeWillOWisp *willowisp
- = new TreeWillOWisp(this, pos, 200 + willo_radius, willo_speed);
-
- Sector::current()->add_object(willowisp);
- willowisps.push_back(willowisp);
-
- willo_spawn_y -= 40;
- if(willo_spawn_y < -160)
- willo_spawn_y = 0;
-
- willo_radius += 20;
- if(willo_radius > 120)
- willo_radius = 0;
-
- if(willo_speed == 1.8f) {
- willo_speed = 1.5f;
- } else {
- willo_speed = 1.8f;
- }
-
- do {
- willo_color = (willo_color + 1) % 3;
- } while(willo_color == treecolor);
-
- switch(willo_color) {
- case 0: willowisp->set_color(Color(1, 0, 0)); break;
- case 1: willowisp->set_color(Color(0, 1, 0)); break;
- case 2: willowisp->set_color(Color(0, 0, 1)); break;
- case 3: willowisp->set_color(Color(1, 1, 0)); break;
- case 4: willowisp->set_color(Color(1, 0, 1)); break;
- case 5: willowisp->set_color(Color(0, 1, 1)); break;
- default: assert(false);
- }
- }
- }
-
- if(root_timer.check()) {
- /* TODO indicate root with an animation */
- Player* player = get_nearest_player();
- Root* root = new Root(Vector(player->get_bbox().get_left(), get_bbox().get_bottom()+ROOT_TOP_OFFSET));
- Sector::current()->add_object(root);
- }
- } else if (mystate == STATE_SWALLOWING) {
- if (suck_lantern) {
- // suck in lantern
- assert (suck_lantern);
- Vector pos = suck_lantern->get_pos();
- Vector delta = get_bbox().get_middle() + SUCK_TARGET_OFFSET - pos;
- Vector dir = delta.unit();
- if (delta.norm() < 1) {
- dir = delta;
- suck_lantern->ungrab(*this, RIGHT);
- suck_lantern->remove_me();
- suck_lantern = 0;
- sprite->set_action("swallow", 1);
- } else {
- pos += dir;
- suck_lantern->grab(*this, pos, RIGHT);
- }
- } else {
- // wait until lantern is swallowed
- if (sprite->animation_done()) {
- if (is_color_deadly(suck_lantern_color)) {
- die();
- } else {
- sprite->set_action("default");
- mystate = STATE_IDLE;
- spawn_lantern();
- }
- }
- }
- }
-}
-
-bool
-GhostTree::is_color_deadly(Color color) const {
- if (color == Color(0,0,0)) return false;
- Color my_color = glow_sprite->get_color();
- return ((my_color.red != color.red) || (my_color.green != color.green) || (my_color.blue != color.blue));
-}
-
-void
-GhostTree::willowisp_died(TreeWillOWisp *willowisp)
-{
- if ((mystate == STATE_SUCKING) && (willowisp->was_sucked)) {
- mystate = STATE_IDLE;
- }
- willowisps.erase(std::find(willowisps.begin(), willowisps.end(), willowisp));
-}
-
-void
-GhostTree::draw(DrawingContext& context)
-{
- BadGuy::draw(context);
-
- context.push_target();
- context.push_transform();
- context.set_target(DrawingContext::LIGHTMAP);
- if (mystate == STATE_SUCKING) {
- context.set_alpha(0.5 + fmodf(game_time, 0.5));
- } else {
- context.set_alpha(0.5);
- }
- glow_sprite->draw(context, get_pos(), layer);
- context.pop_transform();
- context.pop_target();
-}
-
-bool
-GhostTree::collides(GameObject& other, const CollisionHit& ) {
- if (mystate != STATE_SUCKING) return false;
- if (dynamic_cast<Lantern*>(&other)) return true;
- if (dynamic_cast<Player*>(&other)) return true;
- return false;
-}
-
-HitResponse
-GhostTree::collision(GameObject& other, const CollisionHit& ) {
- if(mystate != STATE_SUCKING) return ABORT_MOVE;
-
- Player* player = dynamic_cast<Player*>(&other);
- if (player) {
- player->kill(false);
- }
-
- Lantern* lantern = dynamic_cast<Lantern*>(&other);
- if (lantern) {
- suck_lantern = lantern;
- suck_lantern->grab(*this, suck_lantern->get_pos(), RIGHT);
- suck_lantern_color = lantern->get_color();
- mystate = STATE_SWALLOWING;
- }
-
- return ABORT_MOVE;
-}
-
-void
-GhostTree::spawn_lantern() {
- Lantern* lantern = new Lantern(get_bbox().get_middle() + SUCK_TARGET_OFFSET);
- Sector::current()->add_object(lantern);
-}
-
-IMPLEMENT_FACTORY(GhostTree, "ghosttree");
-
+++ /dev/null
-// $Id$
-//
-// SuperTux - Boss "GhostTree"
-// Copyright (C) 2007 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#ifndef __GHOSTTREE_H__
-#define __GHOSTTREE_H__
-
-#include <vector>
-#include "badguy.hpp"
-
-class TreeWillOWisp;
-class Lantern;
-
-class GhostTree : public BadGuy
-{
-public:
- GhostTree(const lisp::Lisp& lisp);
- ~GhostTree();
-
- virtual bool is_flammable() const { return false; }
- virtual bool is_freezable() const { return false; }
- virtual void kill_fall() { }
-
- void activate();
- void active_update(float elapsed_time);
- void willowisp_died(TreeWillOWisp* willowisp);
- virtual void draw(DrawingContext& context);
-
- virtual bool collides(GameObject& other, const CollisionHit& hit);
- virtual HitResponse collision(GameObject& other, const CollisionHit& hit);
-
- void die();
-
-private:
- enum MyState {
- STATE_IDLE, STATE_SUCKING, STATE_SWALLOWING, STATE_DYING
- };
- MyState mystate;
- Timer willowisp_timer;
- float willo_spawn_y;
- float willo_radius;
- float willo_speed;
- int willo_color;
-
- std::auto_ptr<Sprite> glow_sprite;
- Timer colorchange_timer;
- Timer suck_timer;
- Timer root_timer;
- int treecolor;
- Color suck_lantern_color;
-
- Lantern* suck_lantern; /**< Lantern that is currently being sucked in */
-
- std::vector<TreeWillOWisp*> willowisps;
-
- bool is_color_deadly(Color color) const;
- void spawn_lantern();
-};
-
-#endif
-
+++ /dev/null
-// $Id$
-//
-// SuperTux - Badguy "Igel"
-// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
-//
-// 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.
-
-#include <config.h>
-
-#include "igel.hpp"
-#include "object/block.hpp"
-#include "sector.hpp"
-#include "object/bullet.hpp"
-
-namespace {
- const float WALKSPEED = 80; /**< speed at which we walk around */
- const float TURN_RECOVER_TIME = 0.5; /**< seconds before we will again turn around when shot at */
- const float RANGE_OF_VISION = 256; /**< range in px at which we can see bullets */
-}
-
-Igel::Igel(const lisp::Lisp& reader)
- : WalkingBadguy(reader, "images/creatures/igel/igel.sprite", "walking-left", "walking-right")
-{
- walk_speed = WALKSPEED;
- max_drop_height = 16;
-}
-
-Igel::Igel(const Vector& pos, Direction d)
- : WalkingBadguy(pos, d, "images/creatures/igel/igel.sprite", "walking-left", "walking-right")
-{
- walk_speed = WALKSPEED;
- max_drop_height = 16;
-}
-
-void
-Igel::write(lisp::Writer& writer)
-{
- writer.start_list("igel");
- WalkingBadguy::write(writer);
- writer.end_list("igel");
-}
-
-void
-Igel::be_normal()
-{
- activate();
-}
-
-void
-Igel::turn_around()
-{
- WalkingBadguy::turn_around();
- turn_recover_timer.start(TURN_RECOVER_TIME);
-}
-
-bool
-Igel::can_see(const MovingObject& o)
-{
- Rect mb = get_bbox();
- Rect ob = o.get_bbox();
-
- bool inReach_left = ((ob.p2.x < mb.p1.x) && (ob.p2.x >= mb.p1.x-((dir == LEFT) ? RANGE_OF_VISION : 0)));
- bool inReach_right = ((ob.p1.x > mb.p2.x) && (ob.p1.x <= mb.p2.x+((dir == RIGHT) ? RANGE_OF_VISION : 0)));
- bool inReach_top = (ob.p2.y >= mb.p1.y);
- bool inReach_bottom = (ob.p1.y <= mb.p2.y);
-
- return ((inReach_left || inReach_right) && inReach_top && inReach_bottom);
-}
-
-void
-Igel::active_update(float elapsed_time)
-{
- bool wants_to_flee = false;
-
- // check if we see a fire bullet
- Sector* sector = Sector::current();
- for (Sector::GameObjects::iterator i = sector->gameobjects.begin(); i != sector->gameobjects.end(); ++i) {
- Bullet* bullet = dynamic_cast<Bullet*>(*i);
- if (!bullet) continue;
- if (bullet->get_type() != FIRE_BONUS) continue;
- if (can_see(*bullet)) wants_to_flee = true;
- }
-
- // if we flee, handle this ourselves
- if (wants_to_flee && (!turn_recover_timer.started())) {
- turn_around();
- BadGuy::active_update(elapsed_time);
- return;
- }
-
- // else adhere to default behaviour
- WalkingBadguy::active_update(elapsed_time);
-}
-
-HitResponse
-Igel::collision_bullet(Bullet& bullet, const CollisionHit& hit)
-{
- // default reaction if hit on front side
- if (((dir == LEFT) && hit.left) || ((dir == RIGHT) && hit.right)) {
- return BadGuy::collision_bullet(bullet, hit);
- }
-
- // else make bullet ricochet and ignore the hit
- bullet.ricochet(*this, hit);
- return FORCE_MOVE;
-}
-
-bool
-Igel::collision_squished(GameObject& )
-{
- // this will hurt
- return false;
-}
-
-IMPLEMENT_FACTORY(Igel, "igel")
+++ /dev/null
-// $Id$
-//
-// SuperTux - Badguy "Igel"
-// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
-//
-// 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.
-
-#ifndef __IGEL_H__
-#define __IGEL_H__
-
-#include "walking_badguy.hpp"
-#include "moving_object.hpp"
-
-/**
- * Badguy "Igel" - a hedgehog that can absorb bullets
- */
-class Igel : public WalkingBadguy
-{
-public:
- Igel(const lisp::Lisp& reader);
- Igel(const Vector& pos, Direction d);
-
- void write(lisp::Writer& writer);
- HitResponse collision_bullet(Bullet& bullet, const CollisionHit& hit);
-
- void active_update(float elapsed_time);
-
- virtual Igel* clone() const { return new Igel(*this); }
-
-protected:
- bool collision_squished(GameObject& object);
- void be_normal(); /**< switch to state STATE_NORMAL */
- void turn_around(); /**< reverse direction, assumes we are in STATE_NORMAL */
- bool can_see(const MovingObject& o); /**< check if we can see o */
-
-private:
- Timer turn_recover_timer; /**< wait time until we will turn around again when shot at */
-
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include "jumpy.hpp"
-
-static const float JUMPSPEED=-600;
-static const float JUMPY_MID_TOLERANCE=4;
-static const float JUMPY_LOW_TOLERANCE=2;
-
-Jumpy::Jumpy(const lisp::Lisp& reader)
- : BadGuy(reader, "images/creatures/jumpy/jumpy.sprite"), groundhit_pos_set(false)
-{
-}
-
-void
-Jumpy::write(lisp::Writer& writer)
-{
- writer.start_list("jumpy");
-
- writer.write_float("x", start_position.x);
- writer.write_float("y", start_position.y);
-
- writer.end_list("jumpy");
-}
-
-void
-Jumpy::collision_solid(const CollisionHit& chit)
-{
- hit(chit);
-}
-
-HitResponse
-Jumpy::collision_badguy(BadGuy& , const CollisionHit& chit)
-{
- return hit(chit);
-}
-
-HitResponse
-Jumpy::hit(const CollisionHit& chit)
-{
- if(chit.bottom) {
- if (!groundhit_pos_set)
- {
- pos_groundhit = get_pos();
- groundhit_pos_set = true;
- }
-
- physic.set_velocity_y(frozen ? 0 : JUMPSPEED);
- // TODO create a nice sound for this...
- //sound_manager->play("sounds/skid.wav");
- } else if(chit.top) {
- physic.set_velocity_y(0);
- }
-
- return CONTINUE;
-}
-
-void
-Jumpy::active_update(float elapsed_time)
-{
- BadGuy::active_update(elapsed_time);
-
- if(frozen)
- return;
-
- Player* player = this->get_nearest_player();
- if (player)
- {
- dir = (player->get_pos().x > get_pos().x) ? RIGHT : LEFT;
- }
-
- if (!groundhit_pos_set)
- {
- sprite->set_action(dir == LEFT ? "left-middle" : "right-middle");
- return;
- }
-
- if ( get_pos().y < (pos_groundhit.y - JUMPY_MID_TOLERANCE ) )
- sprite->set_action(dir == LEFT ? "left-up" : "right-up");
- else if ( get_pos().y >= (pos_groundhit.y - JUMPY_MID_TOLERANCE) &&
- get_pos().y < (pos_groundhit.y - JUMPY_LOW_TOLERANCE) )
- sprite->set_action(dir == LEFT ? "left-middle" : "right-middle");
- else
- sprite->set_action(dir == LEFT ? "left-down" : "right-down");
-}
-
-void
-Jumpy::freeze()
-{
- BadGuy::freeze();
- physic.set_velocity_y(std::max(0.0f, physic.get_velocity_y()));
- sprite->set_action(dir == LEFT ? "left-iced" : "right-iced");
-}
-
-bool
-Jumpy::is_freezable() const
-{
- return true;
-}
-
-IMPLEMENT_FACTORY(Jumpy, "jumpy")
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __JUMPY_H__
-#define __JUMPY_H__
-
-#include "badguy.hpp"
-
-class Jumpy : public BadGuy
-{
-public:
- Jumpy(const lisp::Lisp& reader);
-
- void collision_solid(const CollisionHit& hit);
- HitResponse collision_badguy(BadGuy& other, const CollisionHit& hit);
-
- void write(lisp::Writer& writer);
- void active_update(float);
-
- void freeze();
- bool is_freezable() const;
-
- virtual Jumpy* clone() const { return new Jumpy(*this); }
-
-private:
- HitResponse hit(const CollisionHit& hit);
- Vector pos_groundhit;
- bool groundhit_pos_set;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include "kugelblitz.hpp"
-#include "object/tilemap.hpp"
-#include "object/camera.hpp"
-#include "tile.hpp"
-#include "random_generator.hpp"
-
-#define LIFETIME 5
-#define MOVETIME 0.75
-#define BASE_SPEED 200
-#define RAND_SPEED 150
-
-static const float X_OFFSCREEN_DISTANCE = 1600;
-static const float Y_OFFSCREEN_DISTANCE = 1200;
-
-Kugelblitz::Kugelblitz(const lisp::Lisp& reader)
- : BadGuy(Vector(0,0), "images/creatures/kugelblitz/kugelblitz.sprite"), groundhit_pos_set(false)
-{
- reader.get("x", start_position.x);
- sprite->set_action("falling");
- physic.enable_gravity(false);
-}
-
-void
-Kugelblitz::write(lisp::Writer& writer)
-{
- writer.start_list("kugelblitz");
-
- writer.write_float("x", start_position.x);
-
- writer.end_list("kugelblitz");
-}
-
-void
-Kugelblitz::activate()
-{
- physic.set_velocity_y(300);
- physic.set_velocity_x(-20); //fall a little to the left
- direction = 1;
- dying = false;
-}
-
-void
-Kugelblitz::collision_solid(const CollisionHit& chit)
-{
- hit(chit);
-}
-
-HitResponse
-Kugelblitz::collision_player(Player& player, const CollisionHit& )
-{
- if(player.is_invincible()) {
- explode();
- return ABORT_MOVE;
- }
- // hit from above?
- if(player.get_movement().y - get_movement().y > 0 && player.get_bbox().p2.y <
- (get_bbox().p1.y + get_bbox().p2.y) / 2) {
- // if it's not is it possible to squish us, then this will hurt
- if(!collision_squished(player))
- player.kill(false);
- explode();
- return FORCE_MOVE;
- }
- player.kill(false);
- explode();
- return FORCE_MOVE;
-}
-
-HitResponse
-Kugelblitz::collision_badguy(BadGuy& other , const CollisionHit& chit)
-{
- //Let the Kugelblitz explode, too? The problem with that is that
- //two Kugelblitzes would cancel each other out on contact...
- other.kill_fall();
- return hit(chit);
-}
-
-HitResponse
-Kugelblitz::hit(const CollisionHit& hit)
-{
- // hit floor?
- if(hit.bottom) {
- if (!groundhit_pos_set)
- {
- pos_groundhit = get_pos();
- groundhit_pos_set = true;
- }
- sprite->set_action("flying");
- physic.set_velocity_y(0);
- //Set random initial speed and direction
- direction = systemRandom.rand(2)? 1: -1;
- int speed = (BASE_SPEED + (systemRandom.rand(RAND_SPEED))) * direction;
- physic.set_velocity_x(speed);
- movement_timer.start(MOVETIME);
- lifetime.start(LIFETIME);
-
- } else if(hit.top) { // bumped on roof
- physic.set_velocity_y(0);
- }
-
- return CONTINUE;
-}
-
-void
-Kugelblitz::active_update(float elapsed_time)
-{
- if (lifetime.check()) {
- explode();
- }
- else {
- if (groundhit_pos_set) {
- if (movement_timer.check()) {
- if (direction == 1) direction = -1; else direction = 1;
- int speed = (BASE_SPEED + (systemRandom.rand(RAND_SPEED))) * direction;
- physic.set_velocity_x(speed);
- movement_timer.start(MOVETIME);
- }
- }
- /*
- if (Sector::current()->solids->get_tile_at(get_pos())->getAttributes() == 16) {
- //HIT WATER
- Sector::current()->add_object(new Electrifier(75,1421,1.5));
- Sector::current()->add_object(new Electrifier(76,1422,1.5));
- explode();
- }
- if (Sector::current()->solids->get_tile_at(get_pos())->getAttributes() == 48) {
- //HIT ELECTRIFIED WATER
- explode();
- }
- */
- }
- BadGuy::active_update(elapsed_time);
-}
-
-void
-Kugelblitz::kill_fall()
-{
-}
-
-void
-Kugelblitz::explode()
-{
- if (!dying) {
- sprite->set_action("pop");
- lifetime.start(0.2f);
- dying = true;
- }
- else remove_me();
-}
-
-void
-Kugelblitz::try_activate()
-{
- //FIXME: Don't activate Kugelblitz before it's on-screen
- float scroll_x = Sector::current()->camera->get_translation().x;
- float scroll_y = Sector::current()->camera->get_translation().y;
-
- /* Activate badguys if they're just around the screen to avoid
- * the effect of having badguys suddenly popping up from nowhere.
- */
- if (start_position.x > scroll_x - X_OFFSCREEN_DISTANCE &&
- start_position.x < scroll_x - bbox.get_width() &&
- start_position.y > scroll_y - Y_OFFSCREEN_DISTANCE &&
- start_position.y < scroll_y + Y_OFFSCREEN_DISTANCE) {
- dir = RIGHT;
- set_state(STATE_ACTIVE);
- activate();
- } else if (start_position.x > scroll_x &&
- start_position.x < scroll_x + X_OFFSCREEN_DISTANCE &&
- start_position.y > scroll_y - Y_OFFSCREEN_DISTANCE &&
- start_position.y < scroll_y + Y_OFFSCREEN_DISTANCE) {
- dir = LEFT;
- set_state(STATE_ACTIVE);
- activate();
- } else if (start_position.x > scroll_x - X_OFFSCREEN_DISTANCE &&
- start_position.x < scroll_x + X_OFFSCREEN_DISTANCE &&
- ((start_position.y > scroll_y &&
- start_position.y < scroll_y + Y_OFFSCREEN_DISTANCE) ||
- (start_position.y > scroll_y - Y_OFFSCREEN_DISTANCE &&
- start_position.y < scroll_y))) {
- dir = start_position.x < scroll_x ? RIGHT : LEFT;
- set_state(STATE_ACTIVE);
- activate();
- } else if(state == STATE_INIT
- && start_position.x > scroll_x - X_OFFSCREEN_DISTANCE
- && start_position.x < scroll_x + X_OFFSCREEN_DISTANCE
- && start_position.y > scroll_y - Y_OFFSCREEN_DISTANCE
- && start_position.y < scroll_y + Y_OFFSCREEN_DISTANCE) {
- dir = LEFT;
- set_state(STATE_ACTIVE);
- activate();
- }
-}
-
-IMPLEMENT_FACTORY(Kugelblitz, "kugelblitz")
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __KUGELBLITZ_H__
-#define __KUGELBLITZ_H__
-
-#include "badguy.hpp"
-#include "timer.hpp"
-#include "object/electrifier.hpp"
-
-class Kugelblitz : public BadGuy
-{
-public:
- Kugelblitz(const lisp::Lisp& reader);
-
- void activate();
- HitResponse collision_badguy(BadGuy& other, const CollisionHit& hit);
- void collision_solid(const CollisionHit& hit);
- HitResponse collision_player(Player& player, const CollisionHit& hit);
-
- void write(lisp::Writer& writer);
- void active_update(float);
- void kill_fall();
- void explode();
-
- virtual Kugelblitz* clone() const { return new Kugelblitz(*this); }
-
-private:
- void try_activate();
- HitResponse hit(const CollisionHit& hit);
- Vector pos_groundhit;
- bool groundhit_pos_set;
- bool dying;
- Timer movement_timer;
- Timer lifetime;
- int direction;
- State state;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux - Mole Badguy
-// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
-//
-// 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.
-
-#include <config.h>
-
-#include "mole.hpp"
-#include "mole_rock.hpp"
-#include "tile.hpp"
-#include "object/tilemap.hpp"
-#include "random_generator.hpp"
-#include "log.hpp"
-#include "level.hpp"
-
-static const float IDLE_TIME = 0.2f; /**< time to wait before and after throwing */
-static const float THROW_TIME = 4.6f; /**< time to spend throwing */
-static const float THROW_INTERVAL = 1; /**< time between two thrown rocks */
-static const float THROW_VELOCITY = 400; /**< initial velocity of thrown rocks */
-
-Mole::Mole(const lisp::Lisp& reader)
- : BadGuy(reader, "images/creatures/mole/mole.sprite", LAYER_TILES-1), state(PRE_THROWING)
-{
- physic.enable_gravity(false);
-}
-
-Mole::Mole(const Vector& pos)
- : BadGuy(pos, "images/creatures/mole/mole.sprite", LAYER_TILES-1), state(PRE_THROWING)
-{
- physic.enable_gravity(false);
-}
-
-void
-Mole::write(lisp::Writer& writer)
-{
- writer.start_list("mole");
- writer.write_float("x", start_position.x);
- writer.write_float("y", start_position.y);
- writer.end_list("mole");
-}
-
-void
-Mole::activate()
-{
- if (state != DEAD) set_state(PRE_THROWING);
-}
-
-void
-Mole::kill_fall()
-{
- set_state(DEAD);
- sound_manager->play("sounds/fall.wav", get_pos());
- if (countMe) Sector::current()->get_level()->stats.badguys++;
-}
-
-HitResponse
-Mole::collision_badguy(BadGuy& , const CollisionHit& )
-{
- return FORCE_MOVE;
-}
-
-bool
-Mole::collision_squished(GameObject& )
-{
- set_state(DEAD);
- sound_manager->play("sounds/squish.wav", get_pos());
- if (countMe) Sector::current()->get_level()->stats.badguys++;
- return true;
-}
-
-void
-Mole::throw_rock()
-{
- float px = get_bbox().get_middle().x;
- float py = get_bbox().get_middle().y;
-
- float angle = systemRandom.rand(90 - 15, 90 + 15) * (M_PI / 180);
- float vx = cos(angle) * THROW_VELOCITY;
- float vy = -sin(angle) * THROW_VELOCITY;
-
- sound_manager->play("sounds/dartfire.wav", get_pos());
- Sector::current()->add_object(new MoleRock(Vector(px, py), Vector(vx, vy), this));
-}
-
-void
-Mole::active_update(float elapsed_time)
-{
- BadGuy::active_update(elapsed_time);
-
- switch (state) {
- case PRE_THROWING:
- if (timer.check()) {
- set_state(THROWING);
- }
- break;
- case THROWING:
- if (throw_timer.check()) {
- throw_rock();
- throw_timer.start(THROW_INTERVAL);
- }
- if (timer.check()) {
- set_state(POST_THROWING);
- }
- break;
- case POST_THROWING:
- if (timer.check()) {
- set_state(PEEKING);
- }
- break;
- case PEEKING:
- if (sprite->animation_done()) {
- set_state(PRE_THROWING);
- }
- break;
- case DEAD:
- break;
- }
-
-}
-
-void
-Mole::set_state(MoleState new_state)
-{
- switch (new_state) {
- case PRE_THROWING:
- sprite->set_action("idle");
- set_group(COLGROUP_DISABLED);
- timer.start(IDLE_TIME);
- break;
- case THROWING:
- sprite->set_action("idle");
- set_group(COLGROUP_DISABLED);
- timer.start(THROW_TIME);
- throw_timer.start(THROW_INTERVAL);
- break;
- case POST_THROWING:
- sprite->set_action("idle");
- set_group(COLGROUP_DISABLED);
- timer.start(IDLE_TIME);
- break;
- case PEEKING:
- sprite->set_action("peeking", 1);
- set_group(COLGROUP_STATIC);
- break;
- case DEAD:
- sprite->set_action("idle");
- set_group(COLGROUP_DISABLED);
- break;
- }
-
- state = new_state;
-}
-
-IMPLEMENT_FACTORY(Mole, "mole")
+++ /dev/null
-// $Id$
-//
-// SuperTux - Mole Badguy
-// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
-//
-// 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.
-
-#ifndef __MOLE_H__
-#define __MOLE_H__
-
-#include "badguy.hpp"
-
-class Mole : public BadGuy
-{
-public:
- Mole(const lisp::Lisp& );
- Mole(const Vector& pos);
-
- void kill_fall();
- HitResponse collision_badguy(BadGuy& , const CollisionHit& );
- bool collision_squished(GameObject& object);
-
- void activate();
- void write(lisp::Writer& );
- void active_update(float);
-
- virtual Mole* clone() const { return new Mole(*this); }
-
-private:
- enum MoleState {
- PRE_THROWING,
- THROWING,
- POST_THROWING,
- PEEKING,
- DEAD
- };
-
- MoleState state;
- Timer timer;
- Timer throw_timer;
-
- void set_state(MoleState new_state);
- void throw_rock();
-
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// MoleRock - Rock thrown by "Mole" Badguy
-// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
-//
-// 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.
-
-#include <config.h>
-
-#include "mole_rock.hpp"
-
-MoleRock::MoleRock(const lisp::Lisp& reader)
- : BadGuy(reader, "images/creatures/mole/mole_rock.sprite", LAYER_TILES - 2), parent(0), initial_velocity(Vector(0, -400))
-{
- physic.enable_gravity(true);
- countMe = false;
-}
-
-MoleRock::MoleRock(const Vector& pos, const Vector& velocity, const BadGuy* parent = 0)
- : BadGuy(pos, LEFT, "images/creatures/mole/mole_rock.sprite", LAYER_TILES - 2), parent(parent), initial_velocity(velocity)
-{
- physic.enable_gravity(true);
- countMe = false;
-}
-
-MoleRock::MoleRock(const MoleRock& other)
- : BadGuy(other), parent(other.parent), initial_velocity(Vector(0, -400))
-{
-}
-
-MoleRock::~MoleRock()
-{
-}
-
-bool
-MoleRock::updatePointers(const GameObject* from_object, GameObject* to_object)
-{
- if (from_object == parent) {
- parent = dynamic_cast<MoleRock*>(to_object);
- return true;
- }
- return false;
-}
-
-void
-MoleRock::write(lisp::Writer& writer)
-{
- writer.start_list("mole_rock");
- writer.write_float("x", start_position.x);
- writer.write_float("y", start_position.y);
- writer.end_list("mole_rock");
-}
-
-void
-MoleRock::activate()
-{
- physic.set_velocity(initial_velocity);
- sprite->set_action("default");
-}
-
-void
-MoleRock::deactivate()
-{
- remove_me();
-}
-
-void
-MoleRock::active_update(float elapsed_time)
-{
- BadGuy::active_update(elapsed_time);
-}
-
-void
-MoleRock::collision_solid(const CollisionHit& )
-{
- sound_manager->play("sounds/darthit.wav", get_pos());
- remove_me();
-}
-
-HitResponse
-MoleRock::collision_badguy(BadGuy& badguy, const CollisionHit& )
-{
- // ignore collisions with parent
- if (&badguy == parent) {
- return FORCE_MOVE;
- }
- sound_manager->play("sounds/stomp.wav", get_pos());
- remove_me();
- badguy.kill_fall();
- return ABORT_MOVE;
-}
-
-HitResponse
-MoleRock::collision_player(Player& player, const CollisionHit& hit)
-{
- sound_manager->play("sounds/stomp.wav", get_pos());
- remove_me();
- return BadGuy::collision_player(player, hit);
-}
-
-IMPLEMENT_FACTORY(MoleRock, "mole_rock")
+++ /dev/null
-// $Id$
-//
-// MoleRock - Rock thrown by "Mole" Badguy
-// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
-//
-// 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.
-
-#ifndef __MOLE_ROCK_H__
-#define __MOLE_ROCK_H__
-
-#include "badguy.hpp"
-
-/**
- * Badguy "MoleRock" - Rock thrown by "Mole" Badguy
- */
-class MoleRock : public BadGuy
-{
-public:
- MoleRock(const lisp::Lisp& reader);
- MoleRock(const Vector& pos, const Vector& velocity, const BadGuy* parent);
- MoleRock(const MoleRock& mole_rock);
- ~MoleRock();
-
- void activate();
- void deactivate();
- void write(lisp::Writer& writer);
-
- void active_update(float elapsed_time);
-
- void collision_solid(const CollisionHit& hit);
- HitResponse collision_badguy(BadGuy& badguy, const CollisionHit& hit);
- HitResponse collision_player(Player& player, const CollisionHit& hit);
-
- virtual MoleRock* clone() const { return new MoleRock(*this); }
-
- virtual bool updatePointers(const GameObject* from_object, GameObject* to_object);
-
-protected:
- const BadGuy* parent; /**< collisions with this BadGuy will be ignored */
- const Vector initial_velocity; /**< velocity at time of creation */
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include "mrbomb.hpp"
-#include "bomb.hpp"
-#include "object/explosion.hpp"
-#include "sprite/sprite_manager.hpp"
-#include "audio/sound_manager.hpp"
-
-MrBomb::MrBomb(const lisp::Lisp& reader)
- : WalkingBadguy(reader, "images/creatures/mr_bomb/mr_bomb.sprite", "left", "right")
-{
- walk_speed = 80;
- max_drop_height = 16;
- grabbed = false;
-
- //Prevent stutter when Tux jumps on Mr Bomb
- sound_manager->preload("sounds/explosion.wav");
-
- //Check if we need another sprite
- if( !reader.get( "sprite", sprite_name ) ){
- return;
- }
- if( sprite_name == "" ){
- sprite_name = "images/creatures/mr_bomb/mr_bomb.sprite";
- return;
- }
- //Replace sprite
- sprite = sprite_manager->create( sprite_name );
-}
-
-/* MrBomb created by a despencer always gets default sprite atm.*/
-MrBomb::MrBomb(const Vector& pos, Direction d)
- : WalkingBadguy(pos, d, "images/creatures/mr_bomb/mr_bomb.sprite", "left", "right")
-{
- walk_speed = 80;
- max_drop_height = 16;
- grabbed = false;
- sound_manager->preload("sounds/explosion.wav");
-}
-
-void
-MrBomb::write(lisp::Writer& writer)
-{
- writer.start_list("mrbomb");
- WalkingBadguy::write(writer);
- writer.end_list("mrbomb");
-}
-
-HitResponse
-MrBomb::collision(GameObject& object, const CollisionHit& hit)
-{
- if(grabbed)
- return FORCE_MOVE;
- return WalkingBadguy::collision(object, hit);
-}
-
-HitResponse
-MrBomb::collision_player(Player& player, const CollisionHit& hit)
-{
- if(grabbed)
- return FORCE_MOVE;
- return WalkingBadguy::collision_player(player, hit);
-}
-
-bool
-MrBomb::collision_squished(GameObject& object)
-{
- remove_me();
- Sector::current()->add_object(new Bomb(get_pos(), dir, sprite_name ));
- kill_squished(object);
- return true;
-}
-
-void
-MrBomb::active_update(float elapsed_time)
-{
- if(grabbed)
- return;
- WalkingBadguy::active_update(elapsed_time);
-}
-
-void
-MrBomb::kill_fall()
-{
- remove_me();
- Explosion* explosion = new Explosion(get_bbox().get_middle());
- Sector::current()->add_object(explosion);
-
- run_dead_script();
-}
-
-void
-MrBomb::grab(MovingObject&, const Vector& pos, Direction dir)
-{
- assert(frozen);
- movement = pos - get_pos();
- this->dir = dir;
- sprite->set_action(dir == LEFT ? "iced-left" : "iced-right");
- set_group(COLGROUP_DISABLED);
- grabbed = true;
-}
-
-void
-MrBomb::ungrab(MovingObject& , Direction dir)
-{
- this->dir = dir;
- set_group(COLGROUP_MOVING);
- grabbed = false;
-}
-
-void
-MrBomb::freeze()
-{
- WalkingBadguy::freeze();
- sprite->set_action(dir == LEFT ? "iced-left" : "iced-right");
-}
-
-bool
-MrBomb::is_freezable() const
-{
- return true;
-}
-
-bool
-MrBomb::is_portable() const
-{
- return frozen;
-}
-
-IMPLEMENT_FACTORY(MrBomb, "mrbomb")
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __MRBOMB_H__
-#define __MRBOMB_H__
-
-#include "walking_badguy.hpp"
-#include "object/portable.hpp"
-
-class MrBomb : public WalkingBadguy, public Portable
-{
-public:
- MrBomb(const lisp::Lisp& reader);
- MrBomb(const Vector& pos, Direction d);
-
- void write(lisp::Writer& writer);
- void kill_fall();
- HitResponse collision(GameObject& object, const CollisionHit& hit);
- HitResponse collision_player(Player& player, const CollisionHit& hit);
-
- void active_update(float elapsed_time);
-
- void grab(MovingObject& object, const Vector& pos, Direction dir);
- void ungrab(MovingObject& object, Direction dir);
- bool is_portable() const;
-
- void freeze();
- bool is_freezable() const;
-
- virtual MrBomb* clone() const { return new MrBomb(*this); }
-
-protected:
- bool collision_squished(GameObject& object);
-
-private:
- bool grabbed;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include "mriceblock.hpp"
-#include "object/block.hpp"
-
-namespace {
- const float KICKSPEED = 500;
- const int MAXSQUISHES = 10;
-}
-
-MrIceBlock::MrIceBlock(const lisp::Lisp& reader)
- : WalkingBadguy(reader, "images/creatures/mr_iceblock/mr_iceblock.sprite", "left", "right"), ice_state(ICESTATE_NORMAL), squishcount(0)
-{
- walk_speed = 80;
- max_drop_height = 600;
- sound_manager->preload("sounds/iceblock_bump.wav");
- sound_manager->preload("sounds/stomp.wav");
- sound_manager->preload("sounds/kick.wav");
-}
-
-MrIceBlock::MrIceBlock(const Vector& pos, Direction d)
- : WalkingBadguy(pos, d, "images/creatures/mr_iceblock/mr_iceblock.sprite", "left", "right"), ice_state(ICESTATE_NORMAL), squishcount(0)
-{
- walk_speed = 80;
- max_drop_height = 600;
- sound_manager->preload("sounds/iceblock_bump.wav");
- sound_manager->preload("sounds/stomp.wav");
- sound_manager->preload("sounds/kick.wav");
-}
-
-void
-MrIceBlock::write(lisp::Writer& writer)
-{
- writer.start_list("mriceblock");
- WalkingBadguy::write(writer);
- writer.end_list("mriceblock");
-}
-
-void
-MrIceBlock::activate()
-{
- WalkingBadguy::activate();
- set_state(ICESTATE_NORMAL);
-}
-
-void
-MrIceBlock::active_update(float elapsed_time)
-{
- if(ice_state == ICESTATE_GRABBED)
- return;
-
- if(ice_state == ICESTATE_FLAT && flat_timer.check()) {
- set_state(ICESTATE_NORMAL);
- }
-
- if (ice_state == ICESTATE_NORMAL)
- {
- WalkingBadguy::active_update(elapsed_time);
- return;
- }
-
- BadGuy::active_update(elapsed_time);
-}
-
-bool
-MrIceBlock::can_break(){
- return ice_state == ICESTATE_KICKED;
-}
-
-void
-MrIceBlock::collision_solid(const CollisionHit& hit)
-{
- update_on_ground_flag(hit);
-
- if(hit.top || hit.bottom) { // floor or roof
- physic.set_velocity_y(0);
- return;
- }
-
- // hit left or right
- switch(ice_state) {
- case ICESTATE_NORMAL:
- WalkingBadguy::collision_solid(hit);
- break;
- case ICESTATE_KICKED: {
- if(hit.right && dir == RIGHT) {
- dir = LEFT;
- sound_manager->play("sounds/iceblock_bump.wav", get_pos());
- physic.set_velocity_x(-KICKSPEED);
- } else if(hit.left && dir == LEFT) {
- dir = RIGHT;
- sound_manager->play("sounds/iceblock_bump.wav", get_pos());
- physic.set_velocity_x(KICKSPEED);
- }
- sprite->set_action(dir == LEFT ? "flat-left" : "flat-right");
- break;
- }
- case ICESTATE_FLAT:
- physic.set_velocity_x(0);
- break;
- case ICESTATE_GRABBED:
- break;
- }
-}
-
-HitResponse
-MrIceBlock::collision(GameObject& object, const CollisionHit& hit)
-{
- if(ice_state == ICESTATE_GRABBED)
- return FORCE_MOVE;
-
- return BadGuy::collision(object, hit);
-}
-
-HitResponse
-MrIceBlock::collision_player(Player& player, const CollisionHit& hit)
-{
- if(ice_state == ICESTATE_GRABBED)
- return FORCE_MOVE;
-
- if(dir == UP) {
- return FORCE_MOVE;
- }
-
- // handle kicks from left or right side
- if(ice_state == ICESTATE_FLAT && get_state() == STATE_ACTIVE) {
- if(hit.left) {
- dir = RIGHT;
- player.kick();
- set_state(ICESTATE_KICKED);
- return FORCE_MOVE;
- } else if(hit.right) {
- dir = LEFT;
- player.kick();
- set_state(ICESTATE_KICKED);
- return FORCE_MOVE;
- }
- }
-
- return BadGuy::collision_player(player, hit);
-}
-
-HitResponse
-MrIceBlock::collision_badguy(BadGuy& badguy, const CollisionHit& hit)
-{
- switch(ice_state) {
- case ICESTATE_NORMAL:
- return WalkingBadguy::collision_badguy(badguy, hit);
- case ICESTATE_FLAT:
- return FORCE_MOVE;
- case ICESTATE_KICKED:
- badguy.kill_fall();
- return FORCE_MOVE;
- default:
- assert(false);
- }
-
- return ABORT_MOVE;
-}
-
-bool
-MrIceBlock::collision_squished(GameObject& object)
-{
- switch(ice_state) {
- case ICESTATE_KICKED:
- case ICESTATE_NORMAL:
- squishcount++;
- if(squishcount >= MAXSQUISHES) {
- kill_fall();
- return true;
- }
-
- set_state(ICESTATE_FLAT);
- break;
- case ICESTATE_FLAT:
- {
- MovingObject* movingobject = dynamic_cast<MovingObject*>(&object);
- if (movingobject && (movingobject->get_pos().x < get_pos().x)) {
- dir = RIGHT;
- } else {
- dir = LEFT;
- }
- }
- set_state(ICESTATE_KICKED);
- break;
- case ICESTATE_GRABBED:
- assert(false);
- break;
- }
-
- Player* player = dynamic_cast<Player*>(&object);
- if (player) player->bounce(*this);
- return true;
-}
-
-void
-MrIceBlock::set_state(IceState state)
-{
- if(ice_state == state)
- return;
-
- switch(state) {
- case ICESTATE_NORMAL:
- WalkingBadguy::activate();
- break;
- case ICESTATE_FLAT:
- if(dir == UP) {
- physic.set_velocity_y(-KICKSPEED);
- bbox.set_size(34, 31.8f);
- } else {
- sound_manager->play("sounds/stomp.wav", get_pos());
- physic.set_velocity_x(0);
- physic.set_velocity_y(0);
-
- sprite->set_action(dir == LEFT ? "flat-left" : "flat-right");
- }
- flat_timer.start(4);
- break;
- case ICESTATE_KICKED:
- sound_manager->play("sounds/kick.wav", get_pos());
-
- physic.set_velocity_x(dir == LEFT ? -KICKSPEED : KICKSPEED);
- sprite->set_action(dir == LEFT ? "flat-left" : "flat-right");
- // we should slide above 1 block holes now...
- bbox.set_size(34, 31.8f);
- break;
- case ICESTATE_GRABBED:
- flat_timer.stop();
- break;
- default:
- assert(false);
- }
- ice_state = state;
-}
-
-void
-MrIceBlock::grab(MovingObject&, const Vector& pos, Direction dir)
-{
- movement = pos - get_pos();
- this->dir = dir;
- sprite->set_action(dir == LEFT ? "flat-left" : "flat-right");
- set_state(ICESTATE_GRABBED);
- set_group(COLGROUP_DISABLED);
-}
-
-void
-MrIceBlock::ungrab(MovingObject& , Direction dir)
-{
- this->dir = dir;
- set_state(dir == UP ? ICESTATE_FLAT : ICESTATE_KICKED);
- set_group(COLGROUP_MOVING);
-}
-
-bool
-MrIceBlock::is_portable() const
-{
- return ice_state == ICESTATE_FLAT;
-}
-
-IMPLEMENT_FACTORY(MrIceBlock, "mriceblock")
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __MRICEBLOCK_H__
-#define __MRICEBLOCK_H__
-
-#include "walking_badguy.hpp"
-#include "object/portable.hpp"
-
-class MrIceBlock : public WalkingBadguy, public Portable
-{
-public:
- MrIceBlock(const lisp::Lisp& reader);
- MrIceBlock(const Vector& pos, Direction d);
-
- void activate();
- void write(lisp::Writer& writer);
- HitResponse collision(GameObject& object, const CollisionHit& hit);
- void collision_solid(const CollisionHit& hit);
- HitResponse collision_badguy(BadGuy& badguy, const CollisionHit& hit);
- HitResponse collision_player(Player& player, const CollisionHit& hit);
-
- void active_update(float elapsed_time);
-
- void grab(MovingObject& object, const Vector& pos, Direction dir);
- void ungrab(MovingObject& object, Direction dir);
- bool is_portable() const;
-
- bool can_break();
-
- virtual MrIceBlock* clone() const { return new MrIceBlock(*this); }
-
-protected:
- bool collision_squished(GameObject& object);
-
-private:
- enum IceState {
- ICESTATE_NORMAL,
- ICESTATE_FLAT,
- ICESTATE_GRABBED,
- ICESTATE_KICKED
- };
-
- void set_state(IceState state);
-
- IceState ice_state;
- Timer flat_timer;
- int squishcount;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include "mrrocket.hpp"
-#include "object/explosion.hpp"
-
-static const float SPEED = 200;
-
-MrRocket::MrRocket(const lisp::Lisp& reader)
- : BadGuy(reader, "images/creatures/mr_rocket/mr_rocket.sprite")
-{
-}
-
-MrRocket::MrRocket(const Vector& pos, Direction d)
- : BadGuy(pos, d, "images/creatures/mr_rocket/mr_rocket.sprite")
-{
-}
-
-void
-MrRocket::write(lisp::Writer& writer)
-{
- writer.start_list("mrrocket");
-
- writer.write_float("x", start_position.x);
- writer.write_float("y", start_position.y);
-
- writer.end_list("mrrocket");
-}
-
-void
-MrRocket::activate()
-{
- physic.set_velocity_x(dir == LEFT ? -SPEED : SPEED);
- physic.enable_gravity(false);
- sprite->set_action(dir == LEFT ? "left" : "right");
-}
-
-void
-MrRocket::active_update(float elapsed_time)
-{
- if (collision_timer.check()) {
- Sector::current()->add_object(new Explosion(get_bbox().get_middle()));
- remove_me();
- }
- else if (!collision_timer.started()) {
- movement=physic.get_movement(elapsed_time);
- sprite->set_action(dir == LEFT ? "left" : "right");
- }
-}
-
-bool
-MrRocket::collision_squished(GameObject& object)
-{
- sprite->set_action(dir == LEFT ? "squished-left" : "squished-right");
- kill_squished(object);
- kill_fall();
- return true;
-}
-
-void
-MrRocket::collision_solid(const CollisionHit& hit)
-{
- if(hit.top || hit.bottom) {
- physic.set_velocity_y(0);
- } else if(hit.left || hit.right) {
- sprite->set_action(dir == LEFT ? "collision-left" : "collision-right");
- physic.set_velocity_x(0);
- collision_timer.start(0.2f, true);
- }
-}
-
-IMPLEMENT_FACTORY(MrRocket, "mrrocket")
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __MRROCKET_H__
-#define __MRROCKET_H__
-
-#include "badguy.hpp"
-#include "timer.hpp"
-
-class MrRocket : public BadGuy
-{
-public:
- MrRocket(const lisp::Lisp& reader);
- MrRocket(const Vector& pos, Direction d);
-
- void activate();
- void active_update(float elapsed_time);
- void write(lisp::Writer& writer);
- void collision_solid(const CollisionHit& hit);
-
- virtual MrRocket* clone() const { return new MrRocket(*this); }
-
-protected:
- bool collision_squished(GameObject& object);
- Timer collision_timer;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include "mrtree.hpp"
-#include "stumpy.hpp"
-#include "poisonivy.hpp"
-#include "random_generator.hpp"
-#include "object/sprite_particle.hpp"
-#include "sector.hpp"
-
-static const float WALKSPEED = 100;
-
-static const float POISONIVY_WIDTH = 32;
-static const float POISONIVY_HEIGHT = 32;
-static const float POISONIVY_Y_OFFSET = 24;
-
-
-MrTree::MrTree(const lisp::Lisp& reader)
- : WalkingBadguy(reader, "images/creatures/mr_tree/mr_tree.sprite","left","right")
-{
- walk_speed = WALKSPEED;
- max_drop_height = 16;
- sound_manager->preload("sounds/mr_tree.ogg");
-}
-
-void
-MrTree::write(lisp::Writer& writer)
-{
- writer.start_list("mrtree");
- WalkingBadguy::write(writer);
- writer.end_list("mrtree");
-}
-
-bool
-MrTree::collision_squished(GameObject& object)
-{
- // replace with Stumpy
- Vector stumpy_pos = get_pos();
- stumpy_pos.x += 20;
- stumpy_pos.y += 25;
- Stumpy* stumpy = new Stumpy(stumpy_pos, dir);
- remove_me();
- Sector::current()->add_object(stumpy);
-
- // give Feedback
- sound_manager->play("sounds/mr_tree.ogg", get_pos());
- Player* player = dynamic_cast<Player*>(&object);
- if (player) player->bounce(*this);
-
- // spawn some particles
- // TODO: provide convenience function in MovingSprite or MovingObject?
- for (int px = (int)stumpy->get_bbox().p1.x; px < (int)stumpy->get_bbox().p2.x; px+=10) {
- Vector ppos = Vector(px, stumpy->get_bbox().p1.y-5);
- float angle = systemRandom.randf(-M_PI_2, M_PI_2);
- float velocity = systemRandom.randf(45, 90);
- float vx = sin(angle)*velocity;
- float vy = -cos(angle)*velocity;
- Vector pspeed = Vector(vx, vy);
- Vector paccel = Vector(0, 100);
- Sector::current()->add_object(new SpriteParticle("images/objects/particles/leaf.sprite", "default", ppos, ANCHOR_MIDDLE, pspeed, paccel, LAYER_OBJECTS-1));
- }
-
- // spawn PoisonIvy
- Vector leaf1_pos = Vector(stumpy_pos.x - POISONIVY_WIDTH - 1, stumpy_pos.y - POISONIVY_Y_OFFSET);
- Rect leaf1_bbox = Rect(leaf1_pos.x, leaf1_pos.y, leaf1_pos.x + POISONIVY_WIDTH, leaf1_pos.y + POISONIVY_HEIGHT);
- if (Sector::current()->is_free_of_movingstatics(leaf1_bbox, this)) {
- PoisonIvy* leaf1 = new PoisonIvy(leaf1_bbox.p1, LEFT);
- leaf1 = leaf1;
- Sector::current()->add_object(leaf1);
- }
-
- // spawn PoisonIvy
- Vector leaf2_pos = Vector(stumpy_pos.x + sprite->get_current_hitbox_width() + 1, stumpy_pos.y - POISONIVY_Y_OFFSET);
- Rect leaf2_bbox = Rect(leaf2_pos.x, leaf2_pos.y, leaf2_pos.x + POISONIVY_WIDTH, leaf2_pos.y + POISONIVY_HEIGHT);
- if (Sector::current()->is_free_of_movingstatics(leaf2_bbox, this)) {
- PoisonIvy* leaf2 = new PoisonIvy(leaf2_bbox.p1, RIGHT);
- leaf2 = leaf2;
- Sector::current()->add_object(leaf2);
- }
-
- return true;
-}
-
-IMPLEMENT_FACTORY(MrTree, "mrtree")
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __MRTREE_H__
-#define __MRTREE_H__
-
-#include "walking_badguy.hpp"
-
-class MrTree : public WalkingBadguy
-{
-public:
- MrTree(const lisp::Lisp& reader);
- void write(lisp::Writer& writer);
- virtual MrTree* clone() const { return new MrTree(*this); }
-
-protected:
- bool collision_squished(GameObject& object);
-
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include "plant.hpp"
-
-static const float WALKSPEED = 80;
-static const float WAKE_TIME = .5;
-
-Plant::Plant(const lisp::Lisp& reader)
- : BadGuy(reader, "images/creatures/plant/plant.sprite")
-{
- state = PLANT_SLEEPING;
-}
-
-void
-Plant::write(lisp::Writer& writer)
-{
- writer.start_list("plant");
-
- writer.write_float("x", start_position.x);
- writer.write_float("y", start_position.y);
-
- writer.end_list("plant");
-}
-
-void
-Plant::activate()
-{
- //FIXME: turns sspiky around for debugging
- dir = dir == LEFT ? RIGHT : LEFT;
-
- state = PLANT_SLEEPING;
- physic.set_velocity_x(0);
- sprite->set_action(dir == LEFT ? "sleeping-left" : "sleeping-right");
-}
-
-void
-Plant::collision_solid(const CollisionHit& hit)
-{
- if(hit.top || hit.bottom) {
- physic.set_velocity_y(0);
- } else if(hit.left || hit.right) {
- dir = dir == LEFT ? RIGHT : LEFT;
- sprite->set_action(dir == LEFT ? "left" : "right");
- physic.set_velocity_x(-physic.get_velocity_x());
- }
-}
-
-HitResponse
-Plant::collision_badguy(BadGuy& , const CollisionHit& hit)
-{
- if(state != PLANT_WALKING) return CONTINUE;
-
- if(hit.left || hit.right) {
- dir = dir == LEFT ? RIGHT : LEFT;
- sprite->set_action(dir == LEFT ? "left" : "right");
- physic.set_velocity_x(-physic.get_velocity_x());
- }
-
- return CONTINUE;
-}
-
-void
-Plant::active_update(float elapsed_time) {
- BadGuy::active_update(elapsed_time);
-
- if(state == PLANT_SLEEPING) {
-
- Player* player = this->get_nearest_player();
- if (player) {
- Rect mb = this->get_bbox();
- Rect pb = player->get_bbox();
-
- bool inReach_left = (pb.p2.x >= mb.p2.x-((dir == LEFT) ? 256 : 0));
- bool inReach_right = (pb.p1.x <= mb.p1.x+((dir == RIGHT) ? 256 : 0));
- bool inReach_top = (pb.p2.y >= mb.p2.y);
- bool inReach_bottom = (pb.p1.y <= mb.p1.y);
-
- if (inReach_left && inReach_right && inReach_top && inReach_bottom) {
- // wake up
- sprite->set_action(dir == LEFT ? "waking-left" : "waking-right");
- if(!timer.started()) timer.start(WAKE_TIME);
- state = PLANT_WAKING;
- }
- }
- }
-
- if(state == PLANT_WAKING) {
- if(timer.check()) {
- // start walking
- sprite->set_action(dir == LEFT ? "left" : "right");
- physic.set_velocity_x(dir == LEFT ? -WALKSPEED : WALKSPEED);
- state = PLANT_WALKING;
- }
- }
-
-}
-
-IMPLEMENT_FACTORY(Plant, "plant")
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __PLANT_H__
-#define __PLANT_H__
-
-#include "badguy.hpp"
-
-class Plant : public BadGuy
-{
-public:
- Plant(const lisp::Lisp& reader);
-
- void activate();
- void write(lisp::Writer& writer);
- void collision_solid(const CollisionHit& hit);
- HitResponse collision_badguy(BadGuy& badguy, const CollisionHit& hit);
- void active_update(float elapsed_time);
-
- virtual Plant* clone() const { return new Plant(*this); }
-
-protected:
- Timer timer;
-
- enum PlantState {
- PLANT_SLEEPING,
- PLANT_WAKING,
- PLANT_WALKING
- };
- PlantState state;
-
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include "poisonivy.hpp"
-#include "random_generator.hpp"
-#include "object/sprite_particle.hpp"
-
-PoisonIvy::PoisonIvy(const lisp::Lisp& reader)
- : WalkingBadguy(reader, "images/creatures/poison_ivy/poison_ivy.sprite", "left", "right")
-{
- walk_speed = 80;
-}
-
-PoisonIvy::PoisonIvy(const Vector& pos, Direction d)
- : WalkingBadguy(pos, d, "images/creatures/poison_ivy/poison_ivy.sprite", "left", "right")
-{
- walk_speed = 80;
-}
-
-void
-PoisonIvy::write(lisp::Writer& writer)
-{
- writer.start_list("poisonivy");
- WalkingBadguy::write(writer);
- writer.end_list("poisonivy");
-}
-
-bool
-PoisonIvy::collision_squished(GameObject& object)
-{
- sprite->set_action(dir == LEFT ? "squished-left" : "squished-right");
- // spawn some particles
- // TODO: provide convenience function in MovingSprite or MovingObject?
- for (int i = 0; i < 3; i++) {
- Vector ppos = bbox.get_middle();
- float angle = systemRandom.randf(-M_PI_2, M_PI_2);
- float velocity = systemRandom.randf(350, 400);
- float vx = sin(angle)*velocity;
- float vy = -cos(angle)*velocity;
- Vector pspeed = Vector(vx, vy);
- Vector paccel = Vector(0, 100);
- Sector::current()->add_object(new SpriteParticle("images/objects/particles/poisonivy.sprite", "default", ppos, ANCHOR_MIDDLE, pspeed, paccel, LAYER_OBJECTS-1));
- }
- kill_squished(object);
- return true;
-}
-
-IMPLEMENT_FACTORY(PoisonIvy, "poisonivy")
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __POISONIVY_H__
-#define __POISONIVY_H__
-
-#include "walking_badguy.hpp"
-
-class PoisonIvy : public WalkingBadguy
-{
-public:
- PoisonIvy(const lisp::Lisp& reader);
- PoisonIvy(const Vector& pos, Direction d);
-
- void write(lisp::Writer& writer);
- virtual PoisonIvy* clone() const { return new PoisonIvy(*this); }
-
-protected:
- bool collision_squished(GameObject& object);
-
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux - "Will-O-Wisp" Badguy
-// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
-//
-// 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.
-#include <config.h>
-
-#include "root.hpp"
-#include "sprite/sprite_manager.hpp"
-#include "timer.hpp"
-
-static const float SPEED_GROW = 256;
-static const float SPEED_SHRINK = 128;
-static const float HATCH_TIME = 0.75;
-
-Root::Root(const Vector& pos)
- : BadGuy(pos, "images/creatures/ghosttree/root.sprite", LAYER_TILES-1),
- mystate(STATE_APPEARING), offset_y(0)
-{
- base_sprite.reset(sprite_manager->create("images/creatures/ghosttree/root-base.sprite"));
- base_sprite->set_action("appearing", 1);
- base_sprite->set_animation_loops(1); // TODO: necessary because set_action ignores loops for default action
- physic.enable_gravity(false);
-}
-
-Root::~Root()
-{
-}
-
-void
-Root::activate()
-{
- set_group(COLGROUP_TOUCHABLE);
-}
-
-void
-Root::deactivate()
-{
- remove_me();
-}
-
-void
-Root::active_update(float elapsed_time)
-{
- if (mystate == STATE_APPEARING) {
- if (base_sprite->animation_done()) {
- hatch_timer.start(HATCH_TIME);
- mystate = STATE_HATCHING;
- }
- }
- if (mystate == STATE_HATCHING) {
- if (!hatch_timer.started()) mystate = STATE_GROWING;
- }
- else if (mystate == STATE_GROWING) {
- offset_y -= elapsed_time * SPEED_GROW;
- if (offset_y < -sprite->get_height()) {
- offset_y = -sprite->get_height();
- mystate = STATE_SHRINKING;
- }
- set_pos(start_position + Vector(0, offset_y));
- }
- else if (mystate == STATE_SHRINKING) {
- offset_y += elapsed_time * SPEED_SHRINK;
- if (offset_y > 0) {
- offset_y = 0;
- mystate = STATE_VANISHING;
- base_sprite->set_action("vanishing", 2);
- base_sprite->set_animation_loops(2); // TODO: doesn't seem to work for loops=1
- }
- set_pos(start_position + Vector(0, offset_y));
- }
- else if (mystate == STATE_VANISHING) {
- if (base_sprite->animation_done()) remove_me();
- }
- BadGuy::active_update(elapsed_time);
-}
-
-void
-Root::draw(DrawingContext& context)
-{
- base_sprite->draw(context, start_position, LAYER_TILES+1);
- if ((mystate != STATE_APPEARING) && (mystate != STATE_VANISHING)) BadGuy::draw(context);
-}
-
+++ /dev/null
-// $Id$
-//
-// SuperTux - Boss "GhostTree"
-// Copyright (C) 2007 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#ifndef __ROOT_H__
-#define __ROOT_H__
-
-#include <memory>
-#include "badguy.hpp"
-
-class Timer;
-
-class Root : public BadGuy
-{
-public:
- Root(const Vector& pos);
- ~Root();
-
- void activate();
- void deactivate();
- void active_update(float elapsed_time);
- virtual void draw(DrawingContext& context);
- virtual bool is_flammable() const { return false; }
- virtual bool is_freezable() const { return false; }
- virtual void kill_fall() { }
-
-protected:
- enum MyState {
- STATE_APPEARING, STATE_HATCHING, STATE_GROWING, STATE_SHRINKING, STATE_VANISHING
- };
- MyState mystate;
- std::auto_ptr<Sprite> base_sprite;
- float offset_y;
- Timer hatch_timer;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SkullyHop - A Hopping Skull
-// Copyright (C) 2006 Christoph Sommer <supertux@2006.expires.deltadevelopment.de>
-//
-// 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.
-#include <config.h>
-
-#include "skullyhop.hpp"
-#include "random_generator.hpp"
-
-namespace {
- const float VERTICAL_SPEED = -450; /**< y-speed when jumping */
- const float HORIZONTAL_SPEED = 220; /**< x-speed when jumping */
- const float MIN_RECOVER_TIME = 0.1f; /**< minimum time to stand still before starting a (new) jump */
- const float MAX_RECOVER_TIME = 1.0f; /**< maximum time to stand still before starting a (new) jump */
- static const std::string HOP_SOUND = "sounds/hop.ogg";
-}
-
-SkullyHop::SkullyHop(const lisp::Lisp& reader)
- : BadGuy(reader, "images/creatures/skullyhop/skullyhop.sprite")
-{
- sound_manager->preload( HOP_SOUND );
-}
-
-SkullyHop::SkullyHop(const Vector& pos, Direction d)
- : BadGuy(pos, d, "images/creatures/skullyhop/skullyhop.sprite")
-{
- sound_manager->preload( HOP_SOUND );
-}
-
-void
-SkullyHop::write(lisp::Writer& writer)
-{
- writer.start_list("skullyhop");
- writer.write_float("x", start_position.x);
- writer.write_float("y", start_position.y);
- writer.end_list("skullyhop");
-}
-
-void
-SkullyHop::activate()
-{
- // initial state is JUMPING, because we might start airborne
- state = JUMPING;
- sprite->set_action(dir == LEFT ? "jumping-left" : "jumping-right");
-}
-
-void
-SkullyHop::set_state(SkullyHopState newState)
-{
- if (newState == STANDING) {
- physic.set_velocity_x(0);
- physic.set_velocity_y(0);
- sprite->set_action(dir == LEFT ? "standing-left" : "standing-right");
-
- float recover_time = systemRandom.randf(MIN_RECOVER_TIME,MAX_RECOVER_TIME);
- recover_timer.start(recover_time);
- } else
- if (newState == CHARGING) {
- sprite->set_action(dir == LEFT ? "charging-left" : "charging-right", 1);
- } else
- if (newState == JUMPING) {
- sprite->set_action(dir == LEFT ? "jumping-left" : "jumping-right");
- physic.set_velocity_x(dir == LEFT ? -HORIZONTAL_SPEED : HORIZONTAL_SPEED);
- physic.set_velocity_y(VERTICAL_SPEED);
- sound_manager->play( HOP_SOUND, get_pos());
- }
-
- state = newState;
-}
-
-bool
-SkullyHop::collision_squished(GameObject& object)
-{
- sprite->set_action(dir == LEFT ? "squished-left" : "squished-right");
- kill_squished(object);
- return true;
-}
-
-void
-SkullyHop::collision_solid(const CollisionHit& hit)
-{
- // just default behaviour (i.e. stop at floor/walls) when squished
- if (BadGuy::get_state() == STATE_SQUISHED) {
- BadGuy::collision_solid(hit);
- }
-
- // ignore collisions while standing still
- if(state != JUMPING)
- return;
-
- // check if we hit the floor while falling
- if(hit.bottom && physic.get_velocity_y() > 0 ) {
- set_state(STANDING);
- }
- // check if we hit the roof while climbing
- if(hit.top) {
- physic.set_velocity_y(0);
- }
-
- // check if we hit left or right while moving in either direction
- if(hit.left || hit.right) {
- dir = dir == LEFT ? RIGHT : LEFT;
- sprite->set_action(dir == LEFT ? "jumping-left" : "jumping-right");
- physic.set_velocity_x(-0.25*physic.get_velocity_x());
- }
-}
-
-HitResponse
-SkullyHop::collision_badguy(BadGuy& , const CollisionHit& hit)
-{
- // behaviour for badguy collisions is the same as for collisions with solids
- collision_solid(hit);
-
- return CONTINUE;
-}
-
-void
-SkullyHop::active_update(float elapsed_time)
-{
- BadGuy::active_update(elapsed_time);
-
- // charge when fully recovered
- if ((state == STANDING) && (recover_timer.check())) {
- set_state(CHARGING);
- return;
- }
-
- // jump as soon as charging animation completed
- if ((state == CHARGING) && (sprite->animation_done())) {
- set_state(JUMPING);
- return;
- }
-}
-
-IMPLEMENT_FACTORY(SkullyHop, "skullyhop")
+++ /dev/null
-// $Id$
-//
-// SkullyHop - A Hopping Skull
-// Copyright (C) 2006 Christoph Sommer <supertux@2006.expires.deltadevelopment.de>
-//
-// 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.
-
-#ifndef __SKULLYHOP_H__
-#define __SKULLYHOP_H__
-
-#include "badguy.hpp"
-
-/**
- * Badguy "SkullyHop" - A Hopping Skull
- */
-class SkullyHop : public BadGuy
-{
-public:
- SkullyHop(const lisp::Lisp& reader);
- SkullyHop(const Vector& pos, Direction d);
-
- void activate();
- void write(lisp::Writer& writer);
- void collision_solid(const CollisionHit& hit);
- HitResponse collision_badguy(BadGuy& badguy, const CollisionHit& hit);
- bool collision_squished(GameObject& object);
- void active_update(float elapsed_time);
-
- virtual SkullyHop* clone() const { return new SkullyHop(*this); }
-
-protected:
- enum SkullyHopState {
- STANDING,
- CHARGING,
- JUMPING
- };
-
- Timer recover_timer;
- SkullyHopState state;
-
- void set_state(SkullyHopState newState);
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux - Badguy "Snail"
-// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
-//
-// 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.
-
-#include <config.h>
-
-#include "snail.hpp"
-#include "object/block.hpp"
-
-namespace {
- const float KICKSPEED = 500;
- const int MAXSQUISHES = 10;
- const float KICKSPEED_Y = -500; /**< y-velocity gained when kicked */
-}
-
-Snail::Snail(const lisp::Lisp& reader)
- : WalkingBadguy(reader, "images/creatures/snail/snail.sprite", "left", "right"), state(STATE_NORMAL), squishcount(0)
-{
- walk_speed = 80;
- max_drop_height = 600;
- sound_manager->preload("sounds/iceblock_bump.wav");
- sound_manager->preload("sounds/stomp.wav");
- sound_manager->preload("sounds/kick.wav");
-}
-
-Snail::Snail(const Vector& pos, Direction d)
- : WalkingBadguy(pos, d, "images/creatures/snail/snail.sprite", "left", "right"), state(STATE_NORMAL), squishcount(0)
-{
- walk_speed = 80;
- max_drop_height = 600;
- sound_manager->preload("sounds/iceblock_bump.wav");
- sound_manager->preload("sounds/stomp.wav");
- sound_manager->preload("sounds/kick.wav");
-}
-
-void
-Snail::write(lisp::Writer& writer)
-{
- writer.start_list("snail");
- WalkingBadguy::write(writer);
- writer.end_list("snail");
-}
-
-void
-Snail::activate()
-{
- WalkingBadguy::activate();
- be_normal();
-}
-
-void
-Snail::be_normal()
-{
- if (state == STATE_NORMAL) return;
-
- state = STATE_NORMAL;
- WalkingBadguy::activate();
-}
-
-void
-Snail::be_flat()
-{
- state = STATE_FLAT;
- sprite->set_action(dir == LEFT ? "flat-left" : "flat-right");
- sprite->set_fps(64);
-
- physic.set_velocity_x(0);
- physic.set_velocity_y(0);
-
- flat_timer.start(4);
-}
-
-void
-Snail::be_kicked()
-{
- state = STATE_KICKED_DELAY;
- sprite->set_action(dir == LEFT ? "flat-left" : "flat-right");
- sprite->set_fps(64);
-
- physic.set_velocity_x(0);
- physic.set_velocity_y(0);
-
- // start a timer to delay addition of upward movement until we are (hopefully) out from under the player
- kicked_delay_timer.start(0.05f);
-}
-
-bool
-Snail::can_break(){
- return state == STATE_KICKED;
-}
-
-void
-Snail::active_update(float elapsed_time)
-{
- switch (state) {
-
- case STATE_NORMAL:
- WalkingBadguy::active_update(elapsed_time);
- break;
-
- case STATE_FLAT:
- if (flat_timer.started()) {
- sprite->set_fps(64 - 15 * flat_timer.get_timegone());
- }
- if (flat_timer.check()) {
- be_normal();
- }
- BadGuy::active_update(elapsed_time);
- break;
-
- case STATE_KICKED_DELAY:
- if (kicked_delay_timer.check()) {
- physic.set_velocity_x(dir == LEFT ? -KICKSPEED : KICKSPEED);
- physic.set_velocity_y(KICKSPEED_Y);
- state = STATE_KICKED;
- }
- BadGuy::active_update(elapsed_time);
- break;
-
- case STATE_KICKED:
- physic.set_velocity_x(physic.get_velocity_x() * pow(0.99, elapsed_time/0.02));
- if (fabsf(physic.get_velocity_x()) < walk_speed) be_normal();
- BadGuy::active_update(elapsed_time);
- break;
-
- }
-}
-
-void
-Snail::collision_solid(const CollisionHit& hit)
-{
- update_on_ground_flag(hit);
-
- switch (state) {
- case STATE_NORMAL:
- WalkingBadguy::collision_solid(hit);
- break;
- case STATE_FLAT:
- if(hit.top || hit.bottom) {
- physic.set_velocity_y(0);
- }
- if(hit.left || hit.right) {
- }
- break;
- case STATE_KICKED_DELAY:
- if(hit.top || hit.bottom) {
- physic.set_velocity_y(0);
- }
- if(hit.left || hit.right) {
- physic.set_velocity_x(0);
- }
- break;
- case STATE_KICKED:
- if(hit.top || hit.bottom) {
- physic.set_velocity_y(0);
- }
- if(hit.left || hit.right) {
- sound_manager->play("sounds/iceblock_bump.wav", get_pos());
-
- if( ( dir == LEFT && hit.left ) || ( dir == RIGHT && hit.right) ){
- dir = (dir == LEFT) ? RIGHT : LEFT;
- sprite->set_action(dir == LEFT ? "flat-left" : "flat-right");
-
- physic.set_velocity_x(-physic.get_velocity_x()*0.75);
- if (fabsf(physic.get_velocity_x()) < walk_speed) be_normal();
- }
-
- }
- break;
- }
-
-}
-
-HitResponse
-Snail::collision_badguy(BadGuy& badguy, const CollisionHit& hit)
-{
- switch(state) {
- case STATE_NORMAL:
- return WalkingBadguy::collision_badguy(badguy, hit);
- case STATE_FLAT:
- case STATE_KICKED_DELAY:
- return FORCE_MOVE;
- case STATE_KICKED:
- badguy.kill_fall();
- return FORCE_MOVE;
- default:
- assert(false);
- }
-
- return ABORT_MOVE;
-}
-
-bool
-Snail::collision_squished(GameObject& object)
-{
- switch(state) {
-
- case STATE_KICKED:
- case STATE_NORMAL:
- squishcount++;
- if(squishcount >= MAXSQUISHES) {
- kill_fall();
- return true;
- }
-
- sound_manager->play("sounds/stomp.wav", get_pos());
- be_flat();
- break;
-
- case STATE_FLAT:
- sound_manager->play("sounds/kick.wav", get_pos());
- {
- MovingObject* movingobject = dynamic_cast<MovingObject*>(&object);
- if (movingobject && (movingobject->get_pos().x < get_pos().x)) {
- dir = RIGHT;
- } else {
- dir = LEFT;
- }
- }
- be_kicked();
- break;
-
- case STATE_KICKED_DELAY:
- break;
-
- }
-
- Player* player = dynamic_cast<Player*>(&object);
- if (player) player->bounce(*this);
- return true;
-}
-
-IMPLEMENT_FACTORY(Snail, "snail")
+++ /dev/null
-// $Id$
-//
-// SuperTux - Badguy "Snail"
-// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
-//
-// 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.
-
-#ifndef __SNAIL_H__
-#define __SNAIL_H__
-
-#include "walking_badguy.hpp"
-
-/**
- * Badguy "Snail" - a snail-like creature that can be flipped and tossed around at an angle
- */
-class Snail : public WalkingBadguy
-{
-public:
- Snail(const lisp::Lisp& reader);
- Snail(const Vector& pos, Direction d);
-
- void activate();
- void write(lisp::Writer& writer);
- void collision_solid(const CollisionHit& hit);
- HitResponse collision_badguy(BadGuy& badguy, const CollisionHit& hit);
- bool can_break();
-
- void active_update(float elapsed_time);
-
- virtual Snail* clone() const { return new Snail(*this); }
-
-protected:
- bool collision_squished(GameObject& object);
- void be_normal(); /**< switch to state STATE_NORMAL */
- void be_flat(); /**< switch to state STATE_FLAT */
- void be_kicked(); /**< switch to state STATE_KICKED_DELAY */
-
-private:
- enum State {
- STATE_NORMAL, /**< walking around */
- STATE_FLAT, /**< flipped upside-down */
- STATE_KICKED_DELAY, /**< short delay before being launched */
- STATE_KICKED /**< launched */
- };
- State state;
- Timer flat_timer; /**< wait time until flipping right-side-up again */
- Timer kicked_delay_timer; /**< wait time until switching from STATE_KICKED_DELAY to STATE_KICKED */
- int squishcount;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include "snowball.hpp"
-
-SnowBall::SnowBall(const lisp::Lisp& reader)
- : WalkingBadguy(reader, "images/creatures/snowball/snowball.sprite", "left", "right")
-{
- walk_speed = 80;
-}
-
-SnowBall::SnowBall(const Vector& pos, Direction d)
- : WalkingBadguy(pos, d, "images/creatures/snowball/snowball.sprite", "left", "right")
-{
- walk_speed = 80;
-}
-
-void
-SnowBall::write(lisp::Writer& writer)
-{
- writer.start_list("snowball");
- WalkingBadguy::write(writer);
- writer.end_list("snowball");
-}
-
-bool
-SnowBall::collision_squished(GameObject& object)
-{
- sprite->set_action(dir == LEFT ? "squished-left" : "squished-right");
- kill_squished(object);
- return true;
-}
-
-IMPLEMENT_FACTORY(SnowBall, "snowball")
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __SNOWBALL_H__
-#define __SNOWBALL_H__
-
-#include "walking_badguy.hpp"
-
-class SnowBall : public WalkingBadguy
-{
-public:
- SnowBall(const lisp::Lisp& reader);
- SnowBall(const Vector& pos, Direction d);
-
- void write(lisp::Writer& writer);
- virtual SnowBall* clone() const { return new SnowBall(*this); }
-
-protected:
- bool collision_squished(GameObject& object);
-
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-#include <stdio.h>
-
-#include "spidermite.hpp"
-
-static const float FLYTIME = 1.2f;
-static const float FLYSPEED = -100.0f;
-
-SpiderMite::SpiderMite(const lisp::Lisp& reader)
- : BadGuy(reader, "images/creatures/spidermite/spidermite.sprite")
-{
- physic.enable_gravity(false);
-}
-
-SpiderMite::SpiderMite(const Vector& pos)
- : BadGuy(pos, "images/creatures/spidermite/spidermite.sprite")
-{
- physic.enable_gravity(false);
-}
-
-void
-SpiderMite::write(lisp::Writer& writer)
-{
- writer.start_list("spidermite");
-
- writer.write_float("x", start_position.x);
- writer.write_float("y", start_position.y);
-
- writer.end_list("spidermite");
-}
-
-void
-SpiderMite::activate()
-{
- sprite->set_action(dir == LEFT ? "left" : "right");
- mode = FLY_UP;
- physic.set_velocity_y(FLYSPEED);
- timer.start(FLYTIME/2);
-}
-
-bool
-SpiderMite::collision_squished(GameObject& object)
-{
- sprite->set_action(dir == LEFT ? "squished-left" : "squished-right");
- kill_squished(object);
- return true;
-}
-
-void
-SpiderMite::collision_solid(const CollisionHit& hit)
-{
- if(hit.top || hit.bottom) { // hit floor or roof?
- physic.set_velocity_y(0);
- }
-}
-
-void
-SpiderMite::active_update(float elapsed_time)
-{
- if(timer.check()) {
- if(mode == FLY_UP) {
- mode = FLY_DOWN;
- physic.set_velocity_y(-FLYSPEED);
- } else if(mode == FLY_DOWN) {
- mode = FLY_UP;
- physic.set_velocity_y(FLYSPEED);
- }
- timer.start(FLYTIME);
- }
- movement=physic.get_movement(elapsed_time);
-
- Player* player = this->get_nearest_player();
- if (player) {
- dir = (player->get_pos().x > get_pos().x) ? RIGHT : LEFT;
- sprite->set_action(dir == LEFT ? "left" : "right");
- }
-}
-
-IMPLEMENT_FACTORY(SpiderMite, "spidermite")
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __SPIDERMITE_H__
-#define __SPIDERMITE_H__
-
-#include "badguy.hpp"
-
-class SpiderMite : public BadGuy
-{
-public:
- SpiderMite(const lisp::Lisp& reader);
- SpiderMite(const Vector& pos);
-
- void activate();
- void write(lisp::Writer& writer);
- void active_update(float elapsed_time);
- void collision_solid(const CollisionHit& hit);
-
- virtual SpiderMite* clone() const { return new SpiderMite(*this); }
-
-protected:
- enum SpiderMiteMode {
- FLY_UP,
- FLY_DOWN
- };
- SpiderMiteMode mode;
- bool collision_squished(GameObject& object);
-private:
- Timer timer;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include "spiky.hpp"
-
-Spiky::Spiky(const lisp::Lisp& reader)
- : WalkingBadguy(reader, "images/creatures/spiky/spiky.sprite", "left", "right")
-{
- walk_speed = 80;
- max_drop_height = 600;
-}
-
-void
-Spiky::write(lisp::Writer& writer)
-{
- writer.start_list("spiky");
- WalkingBadguy::write(writer);
- writer.end_list("spiky");
-}
-
-void
-Spiky::freeze()
-{
- WalkingBadguy::freeze();
- sprite->set_action(dir == LEFT ? "iced-left" : "iced-right");
-}
-
-bool
-Spiky::is_freezable() const
-{
- return true;
-}
-
-IMPLEMENT_FACTORY(Spiky, "spiky")
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __SPIKY_H__
-#define __SPIKY_H__
-
-#include "walking_badguy.hpp"
-
-class Spiky : public WalkingBadguy
-{
-public:
- Spiky(const lisp::Lisp& reader);
-
- void write(lisp::Writer& writer);
- virtual Spiky* clone() const { return new Spiky(*this); }
-
- void freeze();
- bool is_freezable() const;
-
-private:
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include "sspiky.hpp"
-
-static const float WALKSPEED = 80;
-
-SSpiky::SSpiky(const lisp::Lisp& reader)
- : WalkingBadguy(reader, "images/creatures/spiky/sleepingspiky.sprite", "left", "right"), state(SSPIKY_SLEEPING)
-{
- walk_speed = WALKSPEED;
- max_drop_height = -1;
-}
-
-void
-SSpiky::write(lisp::Writer& writer)
-{
- writer.start_list("sspiky");
- WalkingBadguy::write(writer);
- writer.end_list("sspiky");
-}
-
-void
-SSpiky::activate()
-{
- state = SSPIKY_SLEEPING;
- physic.set_velocity_x(0);
- sprite->set_action(dir == LEFT ? "sleeping-left" : "sleeping-right");
-}
-
-void
-SSpiky::collision_solid(const CollisionHit& hit)
-{
- if(state != SSPIKY_WALKING) {
- BadGuy::collision_solid(hit);
- return;
- }
- WalkingBadguy::collision_solid(hit);
-}
-
-HitResponse
-SSpiky::collision_badguy(BadGuy& badguy, const CollisionHit& hit)
-{
- if(state != SSPIKY_WALKING) {
- return BadGuy::collision_badguy(badguy, hit);
- }
- return WalkingBadguy::collision_badguy(badguy, hit);
-}
-
-void
-SSpiky::active_update(float elapsed_time) {
-
- if(state == SSPIKY_WALKING) {
- WalkingBadguy::active_update(elapsed_time);
- return;
- }
-
- if(state == SSPIKY_SLEEPING) {
-
- Player* player = this->get_nearest_player();
- if (player) {
- Rect mb = this->get_bbox();
- Rect pb = player->get_bbox();
-
- bool inReach_left = (pb.p2.x >= mb.p2.x-((dir == LEFT) ? 256 : 0));
- bool inReach_right = (pb.p1.x <= mb.p1.x+((dir == RIGHT) ? 256 : 0));
- bool inReach_top = (pb.p2.y >= mb.p1.y);
- bool inReach_bottom = (pb.p1.y <= mb.p2.y);
-
- if (inReach_left && inReach_right && inReach_top && inReach_bottom) {
- // wake up
- sprite->set_action(dir == LEFT ? "waking-left" : "waking-right", 1);
- state = SSPIKY_WAKING;
- }
- }
-
- BadGuy::active_update(elapsed_time);
- }
-
- if(state == SSPIKY_WAKING) {
- if(sprite->animation_done()) {
- // start walking
- state = SSPIKY_WALKING;
- WalkingBadguy::activate();
- }
-
- BadGuy::active_update(elapsed_time);
- }
-}
-
-void
-SSpiky::freeze()
-{
- WalkingBadguy::freeze();
- sprite->set_action(dir == LEFT ? "iced-left" : "iced-right");
- state = SSPIKY_WALKING; // if we get hit while sleeping, wake up :)
-}
-
-bool
-SSpiky::is_freezable() const
-{
- return true;
-}
-
-IMPLEMENT_FACTORY(SSpiky, "sspiky")
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __SSPIKY_H__
-#define __SSPIKY_H__
-
-#include "walking_badguy.hpp"
-
-class SSpiky : public WalkingBadguy
-{
-public:
- SSpiky(const lisp::Lisp& reader);
-
- void activate();
- void write(lisp::Writer& writer);
- void collision_solid(const CollisionHit& hit);
- HitResponse collision_badguy(BadGuy& badguy, const CollisionHit& hit);
- void active_update(float elapsed_time);
-
- void freeze();
- bool is_freezable() const;
-
- virtual SSpiky* clone() const { return new SSpiky(*this); }
-
-protected:
- enum SSpikyState {
- SSPIKY_SLEEPING,
- SSPIKY_WAKING,
- SSPIKY_WALKING
- };
- SSpikyState state;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include "stalactite.hpp"
-#include "random_generator.hpp"
-
-static const int SHAKE_RANGE_X = 40;
-static const float SHAKE_TIME = .8f;
-static const float SQUISH_TIME = 2;
-static const float SHAKE_RANGE_Y = 400;
-
-Stalactite::Stalactite(const lisp::Lisp& lisp)
- : BadGuy(lisp, "images/creatures/stalactite/stalactite.sprite", LAYER_TILES - 1), state(STALACTITE_HANGING)
-{
- countMe = false;
-}
-
-void
-Stalactite::write(lisp::Writer& writer)
-{
- writer.start_list("stalactite");
- writer.write_float("x", start_position.x);
- writer.write_float("y", start_position.y);
- writer.end_list("stalactite");
-}
-
-void
-Stalactite::active_update(float elapsed_time)
-{
- if(state == STALACTITE_HANGING) {
- Player* player = this->get_nearest_player();
- if (player) {
- if(player->get_bbox().p2.x > bbox.p1.x - SHAKE_RANGE_X
- && player->get_bbox().p1.x < bbox.p2.x + SHAKE_RANGE_X
- && player->get_bbox().p2.y > bbox.p1.y
- && player->get_bbox().p1.y < bbox.p2.y + SHAKE_RANGE_Y) {
- timer.start(SHAKE_TIME);
- state = STALACTITE_SHAKING;
- }
- }
- } else if(state == STALACTITE_SHAKING) {
- if(timer.check()) {
- state = STALACTITE_FALLING;
- physic.enable_gravity(true);
- }
- } else if(state == STALACTITE_FALLING || state == STALACTITE_SQUISHED) {
- movement = physic.get_movement(elapsed_time);
- if(state == STALACTITE_SQUISHED && timer.check())
- remove_me();
- }
-}
-
-void
-Stalactite::squish()
-{
- state = STALACTITE_SQUISHED;
- set_group(COLGROUP_MOVING_ONLY_STATIC);
- sprite->set_action("squished");
- if(!timer.started())
- timer.start(SQUISH_TIME);
-}
-
-void
-Stalactite::collision_solid(const CollisionHit& hit)
-{
- if(state == STALACTITE_FALLING) {
- if (hit.bottom) squish();
- }
- if(state == STALACTITE_SQUISHED) {
- physic.set_velocity_y(0);
- }
-}
-
-HitResponse
-Stalactite::collision_player(Player& player)
-{
- if(state != STALACTITE_SQUISHED) {
- player.kill(false);
- }
-
- return FORCE_MOVE;
-}
-
-HitResponse
-Stalactite::collision_badguy(BadGuy& other, const CollisionHit& hit)
-{
- if (state == STALACTITE_SQUISHED) return FORCE_MOVE;
- if (state != STALACTITE_FALLING) return BadGuy::collision_badguy(other, hit);
-
- // ignore other Stalactites
- if (dynamic_cast<Stalactite*>(&other)) return FORCE_MOVE;
-
- if (other.is_freezable()) {
- other.freeze();
- } else {
- other.kill_fall();
- }
-
- remove_me();
-
- return FORCE_MOVE;
-}
-
-void
-Stalactite::kill_fall()
-{
-}
-
-void
-Stalactite::draw(DrawingContext& context)
-{
- if(get_state() != STATE_ACTIVE)
- return;
-
-
- if(state == STALACTITE_SQUISHED) {
- sprite->draw(context, get_pos(), LAYER_OBJECTS);
- return;
- }
-
- if(state == STALACTITE_SHAKING) {
- sprite->draw(context, get_pos() + Vector(systemRandom.rand(-3,3), 0), layer);
- } else {
- sprite->draw(context, get_pos(), layer);
- }
-}
-
-void
-Stalactite::deactivate()
-{
- if(state != STALACTITE_HANGING)
- remove_me();
-}
-
-IMPLEMENT_FACTORY(Stalactite, "stalactite")
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __STALACTITE_H__
-#define __STALACTITE_H__
-
-#include "badguy.hpp"
-
-class Stalactite : public BadGuy
-{
-public:
- Stalactite(const lisp::Lisp& reader);
-
- void active_update(float elapsed_time);
- void write(lisp::Writer& writer);
- void collision_solid(const CollisionHit& hit);
- HitResponse collision_player(Player& player);
- HitResponse collision_badguy(BadGuy& other, const CollisionHit& hit);
-
- void kill_fall();
- void draw(DrawingContext& context);
- void deactivate();
-
- virtual Stalactite* clone() const { return new Stalactite(*this); }
-
- void squish();
-
-protected:
- Timer timer;
-
- enum StalactiteState {
- STALACTITE_HANGING,
- STALACTITE_SHAKING,
- STALACTITE_FALLING,
- STALACTITE_SQUISHED
- };
- StalactiteState state;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include "stumpy.hpp"
-#include "poisonivy.hpp"
-#include "random_generator.hpp"
-#include "object/sprite_particle.hpp"
-
-static const float WALKSPEED = 120;
-static const float INVINCIBLE_TIME = 1;
-
-Stumpy::Stumpy(const lisp::Lisp& reader)
- : WalkingBadguy(reader, "images/creatures/mr_tree/stumpy.sprite","left","right"), mystate(STATE_NORMAL)
-{
- walk_speed = WALKSPEED;
- max_drop_height = 16;
- sound_manager->preload("sounds/mr_tree.ogg");
- sound_manager->preload("sounds/mr_treehit.ogg");
-}
-
-Stumpy::Stumpy(const Vector& pos, Direction d)
- : WalkingBadguy(pos, d, "images/creatures/mr_tree/stumpy.sprite","left","right"), mystate(STATE_INVINCIBLE)
-{
- walk_speed = WALKSPEED;
- max_drop_height = 16;
- sound_manager->preload("sounds/mr_treehit.ogg");
- invincible_timer.start(INVINCIBLE_TIME);
-}
-
-
-void
-Stumpy::write(lisp::Writer& writer)
-{
- writer.start_list("stumpy");
- WalkingBadguy::write(writer);
- writer.end_list("stumpy");
-}
-
-void
-Stumpy::activate()
-{
- switch (mystate) {
- case STATE_INVINCIBLE:
- sprite->set_action(dir == LEFT ? "dizzy-left" : "dizzy-right");
- bbox.set_size(sprite->get_current_hitbox_width(), sprite->get_current_hitbox_height());
- physic.set_velocity_x(0);
- break;
- case STATE_NORMAL:
- WalkingBadguy::activate();
- break;
- }
-}
-
-void
-Stumpy::active_update(float elapsed_time)
-{
- switch (mystate) {
- case STATE_INVINCIBLE:
- if (invincible_timer.check()) {
- mystate = STATE_NORMAL;
- WalkingBadguy::activate();
- }
- BadGuy::active_update(elapsed_time);
- break;
- case STATE_NORMAL:
- WalkingBadguy::active_update(elapsed_time);
- break;
- }
-}
-
-bool
-Stumpy::collision_squished(GameObject& object)
-{
-
- // if we're still invincible, we ignore the hit
- if (mystate == STATE_INVINCIBLE) {
- sound_manager->play("sounds/mr_treehit.ogg", get_pos());
- Player* player = dynamic_cast<Player*>(&object);
- if (player) player->bounce(*this);
- return true;
- }
-
- // if we can die, we do
- if (mystate == STATE_NORMAL) {
- sprite->set_action(dir == LEFT ? "squished-left" : "squished-right");
- set_size(sprite->get_current_hitbox_width(), sprite->get_current_hitbox_height());
- kill_squished(object);
- // spawn some particles
- // TODO: provide convenience function in MovingSprite or MovingObject?
- for (int i = 0; i < 25; i++) {
- Vector ppos = bbox.get_middle();
- float angle = systemRandom.randf(-M_PI_2, M_PI_2);
- float velocity = systemRandom.randf(45, 90);
- float vx = sin(angle)*velocity;
- float vy = -cos(angle)*velocity;
- Vector pspeed = Vector(vx, vy);
- Vector paccel = Vector(0, 100);
- Sector::current()->add_object(new SpriteParticle("images/objects/particles/bark.sprite", "default", ppos, ANCHOR_MIDDLE, pspeed, paccel, LAYER_OBJECTS-1));
- }
-
- return true;
-
- }
-
- //TODO: exception?
- return true;
-}
-
-void
-Stumpy::collision_solid(const CollisionHit& hit)
-{
- update_on_ground_flag(hit);
-
- switch (mystate) {
- case STATE_INVINCIBLE:
- if(hit.top || hit.bottom) {
- physic.set_velocity_y(0);
- }
- if(hit.left || hit.right) {
- physic.set_velocity_x(0);
- }
- break;
- case STATE_NORMAL:
- WalkingBadguy::collision_solid(hit);
- break;
- }
-}
-
-HitResponse
-Stumpy::collision_badguy(BadGuy& badguy, const CollisionHit& hit)
-{
- switch (mystate) {
- case STATE_INVINCIBLE:
- if(hit.top || hit.bottom) {
- physic.set_velocity_y(0);
- }
- if(hit.left || hit.right) {
- physic.set_velocity_x(0);
- }
- return CONTINUE;
- break;
- case STATE_NORMAL:
- return WalkingBadguy::collision_badguy(badguy, hit);
- break;
- }
- return CONTINUE;
-}
-
-IMPLEMENT_FACTORY(Stumpy, "stumpy")
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __STUMPY_H__
-#define __STUMPY_H__
-
-#include "walking_badguy.hpp"
-
-class Stumpy : public WalkingBadguy
-{
-public:
- Stumpy(const lisp::Lisp& reader);
- Stumpy(const Vector& pos, Direction d);
-
- void activate();
- void active_update(float elapsed_time);
- void write(lisp::Writer& writer);
- void collision_solid(const CollisionHit& hit);
- HitResponse collision_badguy(BadGuy& badguy, const CollisionHit& hit);
-
- virtual Stumpy* clone() const { return new Stumpy(*this); }
-
-protected:
- enum MyState {
- STATE_INVINCIBLE, STATE_NORMAL
- };
- MyState mystate;
-
- Timer invincible_timer;
-
- bool collision_squished(GameObject& object);
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// Toad - A jumping toad
-// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
-//
-// 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.
-#include <config.h>
-
-#include "toad.hpp"
-#include "random_generator.hpp"
-
-namespace {
- const float VERTICAL_SPEED = -450; /**< y-speed when jumping */
- const float HORIZONTAL_SPEED = 320; /**< x-speed when jumping */
- const float RECOVER_TIME = 0.5; /**< time to stand still before starting a (new) jump */
- static const std::string HOP_SOUND = "sounds/hop.ogg";
-}
-
-Toad::Toad(const lisp::Lisp& reader)
- : BadGuy(reader, "images/creatures/toad/toad.sprite")
-{
- sound_manager->preload(HOP_SOUND);
-}
-
-Toad::Toad(const Vector& pos, Direction d)
- : BadGuy(pos, d, "images/creatures/toad/toad.sprite")
-{
- sound_manager->preload(HOP_SOUND);
-}
-
-void
-Toad::write(lisp::Writer& writer)
-{
- writer.start_list("toad");
- writer.write_float("x", start_position.x);
- writer.write_float("y", start_position.y);
- writer.end_list("toad");
-}
-
-void
-Toad::activate()
-{
- // initial state is JUMPING, because we might start airborne
- state = JUMPING;
- sprite->set_action(dir == LEFT ? "jumping-left" : "jumping-right");
-}
-
-void
-Toad::set_state(ToadState newState)
-{
- if (newState == IDLE) {
- physic.set_velocity_x(0);
- physic.set_velocity_y(0);
- sprite->set_action(dir == LEFT ? "idle-left" : "idle-right");
-
- recover_timer.start(RECOVER_TIME);
- } else
- if (newState == JUMPING) {
- sprite->set_action(dir == LEFT ? "jumping-left" : "jumping-right");
- physic.set_velocity_x(dir == LEFT ? -HORIZONTAL_SPEED : HORIZONTAL_SPEED);
- physic.set_velocity_y(VERTICAL_SPEED);
- sound_manager->play( HOP_SOUND, get_pos());
- } else
- if (newState == FALLING) {
- Player* player = get_nearest_player();
- // face player
- if (player && (player->get_bbox().p2.x < get_bbox().p1.x) && (dir == RIGHT)) dir = LEFT;
- if (player && (player->get_bbox().p1.x > get_bbox().p2.x) && (dir == LEFT)) dir = RIGHT;
- sprite->set_action(dir == LEFT ? "idle-left" : "idle-right");
- }
-
- state = newState;
-}
-
-bool
-Toad::collision_squished(GameObject& object)
-{
- sprite->set_action(dir == LEFT ? "squished-left" : "squished-right");
- kill_squished(object);
- return true;
-}
-
-void
-Toad::collision_solid(const CollisionHit& hit)
-{
- // just default behaviour (i.e. stop at floor/walls) when squished
- if (BadGuy::get_state() == STATE_SQUISHED) {
- BadGuy::collision_solid(hit);
- return;
- }
-
- // ignore collisions while standing still
- if(state == IDLE) {
- return;
- }
-
- // check if we hit left or right while moving in either direction
- if(((physic.get_velocity_x() < 0) && hit.left) || ((physic.get_velocity_x() > 0) && hit.right)) {
- /*
- dir = dir == LEFT ? RIGHT : LEFT;
- if (state == JUMPING) {
- sprite->set_action(dir == LEFT ? "jumping-left" : "jumping-right");
- } else {
- sprite->set_action(dir == LEFT ? "idle-left" : "idle-right");
- }
- */
- physic.set_velocity_x(-0.25*physic.get_velocity_x());
- }
-
- // check if we hit the floor while falling
- if ((state == FALLING) && hit.bottom) {
- set_state(IDLE);
- return;
- }
-
- // check if we hit the roof while climbing
- if ((state == JUMPING) && hit.top) {
- physic.set_velocity_y(0);
- }
-
-}
-
-HitResponse
-Toad::collision_badguy(BadGuy& , const CollisionHit& hit)
-{
- // behaviour for badguy collisions is the same as for collisions with solids
- collision_solid(hit);
-
- return CONTINUE;
-}
-
-void
-Toad::active_update(float elapsed_time)
-{
- BadGuy::active_update(elapsed_time);
-
- // change sprite when we are falling
- if ((state == JUMPING) && (physic.get_velocity_y() > 0)) {
- set_state(FALLING);
- return;
- }
-
- // jump when fully recovered
- if ((state == IDLE) && (recover_timer.check())) {
- set_state(JUMPING);
- return;
- }
-
-}
-
-IMPLEMENT_FACTORY(Toad, "toad")
+++ /dev/null
-// $Id$
-//
-// Toad - A jumping toad
-// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
-//
-// 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.
-
-#ifndef __TOAD_H__
-#define __TOAD_H__
-
-#include "badguy.hpp"
-
-/**
- * Badguy "Toad" - A jumping toad
- */
-class Toad : public BadGuy
-{
-public:
- Toad(const lisp::Lisp& reader);
- Toad(const Vector& pos, Direction d);
-
- void activate();
- void write(lisp::Writer& writer);
- void collision_solid(const CollisionHit& hit);
- HitResponse collision_badguy(BadGuy& badguy, const CollisionHit& hit);
- bool collision_squished(GameObject& object);
- void active_update(float elapsed_time);
-
- virtual Toad* clone() const { return new Toad(*this); }
-
-protected:
- enum ToadState {
- IDLE,
- JUMPING,
- FALLING
- };
-
- Timer recover_timer;
- ToadState state;
-
- void set_state(ToadState newState);
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux - "Totem" Badguy
-// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
-//
-// 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.
-
-#include <config.h>
-
-#include "totem.hpp"
-#include "log.hpp"
-
-static const float WALKSPEED = 100;
-static const float JUMP_ON_SPEED_Y = -400;
-static const float JUMP_OFF_SPEED_Y = -500;
-static const std::string LAND_ON_TOTEM_SOUND = "sounds/totem.ogg";
-
-Totem::Totem(const lisp::Lisp& reader)
- : BadGuy(reader, "images/creatures/totem/totem.sprite")
-{
- carrying = 0;
- carried_by = 0;
- sound_manager->preload( LAND_ON_TOTEM_SOUND );
-}
-
-Totem::Totem(const Totem& other)
- : BadGuy(other), carrying(other.carrying), carried_by(other.carried_by)
-{
- sound_manager->preload( LAND_ON_TOTEM_SOUND );
-}
-
-Totem::~Totem()
-{
- if (carrying) carrying->jump_off();
- if (carried_by) jump_off();
-}
-
-bool
-Totem::updatePointers(const GameObject* from_object, GameObject* to_object)
-{
- if (from_object == carrying) {
- carrying = dynamic_cast<Totem*>(to_object);
- return true;
- }
- if (from_object == carried_by) {
- carried_by = dynamic_cast<Totem*>(to_object);
- return true;
- }
- return false;
-}
-
-void
-Totem::write(lisp::Writer& writer)
-{
- writer.start_list("totem");
-
- writer.write_float("x", start_position.x);
- writer.write_float("y", start_position.y);
-
- writer.end_list("totem");
-}
-
-void
-Totem::activate()
-{
- if (!carried_by) {
- physic.set_velocity_x(dir == LEFT ? -WALKSPEED : WALKSPEED);
- sprite->set_action(dir == LEFT ? "walking-left" : "walking-right");
- return;
- } else {
- synchronize_with(carried_by);
- sprite->set_action(dir == LEFT ? "stacked-left" : "stacked-right");
- return;
- }
-}
-
-void
-Totem::active_update(float elapsed_time)
-{
- BadGuy::active_update(elapsed_time);
-
- if (!carried_by) {
- if (on_ground() && might_fall())
- {
- dir = (dir == LEFT ? RIGHT : LEFT);
- activate();
- }
-
- Sector* s = Sector::current();
- if (s) {
- // jump a bit if we find a suitable totem
- for (std::vector<MovingObject*>::iterator i = s->moving_objects.begin(); i != s->moving_objects.end(); i++) {
- Totem* t = dynamic_cast<Totem*>(*i);
- if (!t) continue;
-
- // skip if we are not approaching each other
- if (!((this->dir == LEFT) && (t->dir == RIGHT))) continue;
-
- Vector p1 = this->get_pos();
- Vector p2 = t->get_pos();
-
- // skip if not on same height
- float dy = (p1.y - p2.y);
- if (fabsf(dy - 0) > 2) continue;
-
- // skip if too far away
- float dx = (p1.x - p2.x);
- if (fabsf(dx - 128) > 2) continue;
-
- physic.set_velocity_y(JUMP_ON_SPEED_Y);
- p1.y -= 1;
- this->set_pos(p1);
- break;
- }
- }
- }
-
- if (carried_by) {
- this->synchronize_with(carried_by);
- }
-
- if (carrying) {
- carrying->synchronize_with(this);
- }
-
-}
-
-bool
-Totem::collision_squished(GameObject& object)
-{
- if (carrying) carrying->jump_off();
- if (carried_by) {
- Player* player = dynamic_cast<Player*>(&object);
- if (player) player->bounce(*this);
- jump_off();
- }
-
- sprite->set_action(dir == LEFT ? "squished-left" : "squished-right");
- bbox.set_size(sprite->get_current_hitbox_width(), sprite->get_current_hitbox_height());
-
- kill_squished(object);
- return true;
-}
-
-void
-Totem::collision_solid(const CollisionHit& hit)
-{
- update_on_ground_flag(hit);
-
- // if we are being carried around, pass event to bottom of stack and ignore it
- if (carried_by) {
- carried_by->collision_solid(hit);
- return;
- }
-
- // If we hit something from above or below: stop moving in this direction
- if (hit.top || hit.bottom) {
- physic.set_velocity_y(0);
- }
-
- // If we are hit from the direction we are facing: turn around
- if (hit.left && (dir == LEFT)) {
- dir = RIGHT;
- activate();
- }
- if (hit.right && (dir == RIGHT)) {
- dir = LEFT;
- activate();
- }
-}
-
-HitResponse
-Totem::collision_badguy(BadGuy& badguy, const CollisionHit& hit)
-{
- // if we are being carried around, pass event to bottom of stack and ignore it
- if (carried_by) {
- carried_by->collision_badguy(badguy, hit);
- return CONTINUE;
- }
-
- // if we hit a Totem that is not from our stack: have our base jump on its top
- Totem* totem = dynamic_cast<Totem*>(&badguy);
- if (totem) {
- Totem* thisBase = this; while (thisBase->carried_by) thisBase=thisBase->carried_by;
- Totem* srcBase = totem; while (srcBase->carried_by) srcBase=srcBase->carried_by;
- Totem* thisTop = this; while (thisTop->carrying) thisTop=thisTop->carrying;
- if (srcBase != thisBase) {
- srcBase->jump_on(thisTop);
- }
- }
-
- // If we are hit from the direction we are facing: turn around
- if(hit.left && (dir == LEFT)) {
- dir = RIGHT;
- activate();
- }
- if(hit.right && (dir == RIGHT)) {
- dir = LEFT;
- activate();
- }
-
- return CONTINUE;
-}
-
-void
-Totem::kill_fall()
-{
- if (carrying) carrying->jump_off();
- if (carried_by) jump_off();
-
- BadGuy::kill_fall();
-}
-
-void
-Totem::jump_on(Totem* target)
-{
- if (target->carrying) {
- log_warning << "target is already carrying someone" << std::endl;
- return;
- }
-
- target->carrying = this;
-
- this->carried_by = target;
- this->activate();
- bbox.set_size(sprite->get_current_hitbox_width(), sprite->get_current_hitbox_height());
-
- sound_manager->play( LAND_ON_TOTEM_SOUND , get_pos());
-
-
- this->synchronize_with(target);
-}
-
-void
-Totem::jump_off() {
- if (!carried_by) {
- log_warning << "not carried by anyone" << std::endl;
- return;
- }
-
- carried_by->carrying = 0;
-
- this->carried_by = 0;
-
- this->activate();
- bbox.set_size(sprite->get_current_hitbox_width(), sprite->get_current_hitbox_height());
-
-
- physic.set_velocity_y(JUMP_OFF_SPEED_Y);
-}
-
-void
-Totem::synchronize_with(Totem* base)
-{
-
- if (dir != base->dir) {
- dir = base->dir;
- sprite->set_action(dir == LEFT ? "stacked-left" : "stacked-right");
- }
-
- Vector pos = base->get_pos();
- pos.y -= sprite->get_current_hitbox_height();
- set_pos(pos);
-
- physic.set_velocity_x(base->physic.get_velocity_x());
- physic.set_velocity_y(base->physic.get_velocity_y());
-}
-
-
-IMPLEMENT_FACTORY(Totem, "totem")
+++ /dev/null
-// $Id$
-//
-// SuperTux - "Totem" Badguy
-// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
-//
-// 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.
-
-#ifndef __TOTEM_H__
-#define __TOTEM_H__
-
-#include "badguy.hpp"
-
-/**
- * "Totem" Badguy - A variable-height stack of wooden blocks
- */
-class Totem : public BadGuy
-{
-public:
- Totem(const lisp::Lisp& reader);
- Totem(const Totem& totem);
- ~Totem();
-
- void activate();
- void active_update(float elapsed_time);
- void write(lisp::Writer& writer);
- void collision_solid(const CollisionHit& hit);
- HitResponse collision_badguy(BadGuy& badguy, const CollisionHit& hit);
-
- virtual Totem* clone() const { return new Totem(*this); }
- virtual bool updatePointers(const GameObject* from_object, GameObject* to_object);
-
-protected:
- Totem* carrying; /**< Totem we are currently carrying (or 0) */
- Totem* carried_by; /**< Totem by which we are currently carried (or 0) */
-
- bool collision_squished(GameObject& object);
- void kill_fall();
-
- void jump_on(Totem* target); /**< jump on target */
- void jump_off(); /**< jump off current base */
-
- void synchronize_with(Totem* baseTotem); /**< synchronize position and movement with baseTotem */
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux - "Will-O-Wisp" Badguy
-// Copyright (C) 2007 Matthias Braun
-//
-// 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.
-#include <config.h>
-
-#include "treewillowisp.hpp"
-#include "ghosttree.hpp"
-#include "object/lantern.hpp"
-
-static const std::string SOUNDFILE = "sounds/willowisp.wav";
-static const float SUCKSPEED = 25;
-
-TreeWillOWisp::TreeWillOWisp(GhostTree* tree, const Vector& pos,
- float radius, float speed)
- : BadGuy(Vector(0, 0), "images/creatures/willowisp/willowisp.sprite",
- LAYER_OBJECTS - 20), was_sucked(false), mystate(STATE_DEFAULT), tree(tree)
-{
- treepos_delta = pos;
- sound_manager->preload(SOUNDFILE);
-
- this->radius = radius;
- this->angle = 0;
- this->speed = speed;
- start_position = tree->get_pos() + treepos_delta;
-}
-
-TreeWillOWisp::~TreeWillOWisp()
-{
-}
-
-void
-TreeWillOWisp::activate()
-{
- sound_source.reset(sound_manager->create_sound_source(SOUNDFILE));
- sound_source->set_position(get_pos());
- sound_source->set_looping(true);
- sound_source->set_gain(2.0);
- sound_source->set_reference_distance(32);
- sound_source->play();
-
- set_group(COLGROUP_MOVING);
-}
-
-void
-TreeWillOWisp::vanish()
-{
- mystate = STATE_VANISHING;
- sprite->set_action("vanishing", 1);
- set_group(COLGROUP_DISABLED);
-}
-
-void
-TreeWillOWisp::start_sucking(Vector suck_target)
-{
- mystate = STATE_SUCKED;
- this->suck_target = suck_target;
- was_sucked = true;
-}
-
-HitResponse
-TreeWillOWisp::collision_player(Player& player, const CollisionHit& hit)
-{
- //TODO: basically a no-op. Remove if this doesn't change.
- return BadGuy::collision_player(player, hit);
-}
-
-bool
-TreeWillOWisp::collides(GameObject& other, const CollisionHit& ) {
- Lantern* lantern = dynamic_cast<Lantern*>(&other);
- if (lantern && lantern->is_open())
- return true;
- if (dynamic_cast<Player*>(&other))
- return true;
-
- return false;
-}
-
-void
-TreeWillOWisp::draw(DrawingContext& context)
-{
- sprite->draw(context, get_pos(), layer);
-
- context.push_target();
- context.set_target(DrawingContext::LIGHTMAP);
-
- sprite->draw(context, get_pos(), layer);
-
- context.pop_target();
-}
-
-void
-TreeWillOWisp::active_update(float elapsed_time)
-{
- // remove TreeWillOWisp if it has completely vanished
- if (mystate == STATE_VANISHING) {
- if(sprite->animation_done()) {
- remove_me();
- tree->willowisp_died(this);
- }
- return;
- }
-
- if (mystate == STATE_SUCKED) {
- Vector dir = suck_target - get_pos();
- if(dir.norm() < 5) {
- vanish();
- return;
- }
- Vector newpos = get_pos() + dir * elapsed_time;
- movement = newpos - get_pos();
- return;
- }
-
- angle = fmodf(angle + elapsed_time * speed, (float) (2*M_PI));
- Vector newpos(tree->get_pos() + treepos_delta + Vector(sin(angle) * radius, 0));
- movement = newpos - get_pos();
- float sizemod = cos(angle) * 0.8f;
- /* TODO: modify sprite size */
-
- sound_source->set_position(get_pos());
-
- if(sizemod < 0) {
- layer = LAYER_OBJECTS + 5;
- } else {
- layer = LAYER_OBJECTS - 20;
- }
-}
-
-void
-TreeWillOWisp::set_color(const Color& color)
-{
- this->color = color;
- sprite->set_color(color);
-}
-
-Color
-TreeWillOWisp::get_color() const
-{
- return color;
-}
-
+++ /dev/null
-// $Id$
-//
-// SuperTux - "Will-O-Wisp" Badguy
-// Copyright (C) 2007 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __TREEWILLOWISP_H__
-#define __TREEWILLOWISP_H__
-
-#include "badguy.hpp"
-
-class GhostTree;
-
-class TreeWillOWisp : public BadGuy
-{
-public:
- TreeWillOWisp(GhostTree* tree, const Vector& pos, float radius, float speed);
- virtual ~TreeWillOWisp();
-
- void activate();
-
- /**
- * make TreeWillOWisp vanish
- */
- void vanish();
- void start_sucking(Vector suck_target);
- bool was_sucked;
-
- void active_update(float elapsed_time);
- void set_color(const Color& color);
- Color get_color() const;
-
- virtual bool is_flammable() const { return false; }
- virtual bool is_freezable() const { return false; }
- virtual void kill_fall() { vanish(); }
-
- virtual void draw(DrawingContext& context);
-
-protected:
- virtual bool collides(GameObject& other, const CollisionHit& hit);
- HitResponse collision_player(Player& player, const CollisionHit& hit);
-
-private:
- enum MyState {
- STATE_DEFAULT, STATE_VANISHING, STATE_SUCKED
- };
- MyState mystate;
-
- Color color;
- float angle;
- float radius;
- float speed;
-
- std::auto_ptr<SoundSource> sound_source;
- Vector treepos_delta;
- GhostTree* tree;
-
- Vector suck_target;
-};
-
-#endif
-
+++ /dev/null
-// $Id$
-//
-// SuperTux - WalkingBadguy
-// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
-//
-// 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.
-
-#include <config.h>
-
-#include "walking_badguy.hpp"
-#include "log.hpp"
-#include "timer.hpp"
-
-WalkingBadguy::WalkingBadguy(const Vector& pos, const std::string& sprite_name, const std::string& walk_left_action, const std::string& walk_right_action, int layer)
- : BadGuy(pos, sprite_name, layer), walk_left_action(walk_left_action), walk_right_action(walk_right_action), walk_speed(80), max_drop_height(-1)
-{
-}
-
-WalkingBadguy::WalkingBadguy(const Vector& pos, Direction direction, const std::string& sprite_name, const std::string& walk_left_action, const std::string& walk_right_action, int layer)
- : BadGuy(pos, direction, sprite_name, layer), walk_left_action(walk_left_action), walk_right_action(walk_right_action), walk_speed(80), max_drop_height(-1)
-{
-}
-
-WalkingBadguy::WalkingBadguy(const lisp::Lisp& reader, const std::string& sprite_name, const std::string& walk_left_action, const std::string& walk_right_action, int layer)
- : BadGuy(reader, sprite_name, layer), walk_left_action(walk_left_action), walk_right_action(walk_right_action), walk_speed(80), max_drop_height(-1)
-{
-}
-
-void
-WalkingBadguy::write(lisp::Writer& writer)
-{
- writer.write_float("x", start_position.x);
- writer.write_float("y", start_position.y);
-}
-
-void
-WalkingBadguy::activate()
-{
- if(frozen)
- return;
- sprite->set_action(dir == LEFT ? walk_left_action : walk_right_action);
- bbox.set_size(sprite->get_current_hitbox_width(), sprite->get_current_hitbox_height());
- physic.set_velocity_x(dir == LEFT ? -walk_speed : walk_speed);
-}
-
-void
-WalkingBadguy::active_update(float elapsed_time)
-{
- BadGuy::active_update(elapsed_time);
-
- if (max_drop_height > -1) {
- if (on_ground() && might_fall(max_drop_height+1))
- {
- turn_around();
- }
- }
-
-}
-
-void
-WalkingBadguy::collision_solid(const CollisionHit& hit)
-{
-
- update_on_ground_flag(hit);
-
- if (hit.top) {
- if (physic.get_velocity_y() < 0) physic.set_velocity_y(0);
- }
- if (hit.bottom) {
- if (physic.get_velocity_y() > 0) physic.set_velocity_y(0);
- }
-
- if ((hit.left && (hit.slope_normal.y == 0) && (dir == LEFT)) || (hit.right && (hit.slope_normal.y == 0) && (dir == RIGHT))) {
- turn_around();
- }
-
-}
-
-HitResponse
-WalkingBadguy::collision_badguy(BadGuy& , const CollisionHit& hit)
-{
-
- if ((hit.left && (dir == LEFT)) || (hit.right && (dir == RIGHT))) {
- turn_around();
- }
-
- return CONTINUE;
-}
-
-void
-WalkingBadguy::turn_around()
-{
- if(frozen)
- return;
- dir = dir == LEFT ? RIGHT : LEFT;
- sprite->set_action(dir == LEFT ? walk_left_action : walk_right_action);
- physic.set_velocity_x(-physic.get_velocity_x());
-
- // if we get dizzy, we fall off the screen
- if (turn_around_timer.started()) {
- if (turn_around_counter++ > 10) kill_fall();
- } else {
- turn_around_timer.start(1);
- turn_around_counter = 0;
- }
-
-}
-
-void
-WalkingBadguy::freeze()
-{
- BadGuy::freeze();
- physic.set_velocity_x(0);
-}
-
-void
-WalkingBadguy::unfreeze()
-{
- BadGuy::unfreeze();
- WalkingBadguy::activate();
-}
-
-
-float
-WalkingBadguy::get_velocity_y() const
-{
- return physic.get_velocity_y();
-}
-
-void
-WalkingBadguy::set_velocity_y(float vy)
-{
- physic.set_velocity_y(vy);
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux - WalkingBadguy
-// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
-//
-// 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.
-
-#ifndef __WALKING_BADGUY_H__
-#define __WALKING_BADGUY_H__
-
-#include "badguy.hpp"
-
-class Timer;
-
-/**
- * Baseclass for a Badguy that just walks around.
- */
-class WalkingBadguy : public BadGuy
-{
-public:
- WalkingBadguy(const Vector& pos, const std::string& sprite_name, const std::string& walk_left_action, const std::string& walk_right_action, int layer = LAYER_OBJECTS);
- WalkingBadguy(const Vector& pos, Direction direction, const std::string& sprite_name, const std::string& walk_left_action, const std::string& walk_right_action, int layer = LAYER_OBJECTS);
- WalkingBadguy(const lisp::Lisp& reader, const std::string& sprite_name, const std::string& walk_left_action, const std::string& walk_right_action, int layer = LAYER_OBJECTS);
-
- void activate();
- void write(lisp::Writer& writer);
- void active_update(float elapsed_time);
- void collision_solid(const CollisionHit& hit);
- HitResponse collision_badguy(BadGuy& badguy, const CollisionHit& hit);
- void freeze();
- void unfreeze();
-
- float get_velocity_y() const;
- void set_velocity_y(float vy);
-
-protected:
- void turn_around();
-
- std::string walk_left_action;
- std::string walk_right_action;
- float walk_speed;
- int max_drop_height; /**< Maximum height of drop before we will turn around, or -1 to just drop from any ledge */
- Timer turn_around_timer;
- int turn_around_counter; /**< counts number of turns since turn_around_timer was started */
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux - Walking Leaf
-// Copyright (C) 2006 Wolfgang Becker <uafr@gmx.de>
-//
-// 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.
-
-#include <config.h>
-
-#include "walkingleaf.hpp"
-#include "random_generator.hpp"
-#include "object/sprite_particle.hpp"
-
-WalkingLeaf::WalkingLeaf(const lisp::Lisp& reader)
- : WalkingBadguy(reader, "images/creatures/walkingleaf/walkingleaf.sprite", "left", "right")
-{
- walk_speed = 60;
- max_drop_height = 16;
-}
-
-WalkingLeaf::WalkingLeaf(const Vector& pos, Direction d)
- : WalkingBadguy(pos, d, "images/creatures/walkingleaf/walkingleaf.sprite", "left", "right")
-{
- walk_speed = 60;
- max_drop_height = 16;
-}
-
-bool
-WalkingLeaf::collision_squished(GameObject& object)
-{
- sprite->set_action(dir == LEFT ? "squished-left" : "squished-right");
- kill_squished(object);
- return true;
-}
-
-IMPLEMENT_FACTORY(WalkingLeaf, "walkingleaf")
+++ /dev/null
-// $Id$
-//
-// SuperTux - Walking Leaf
-// Copyright (C) 2006 Wolfgang Becker <uafr@gmx.de>
-//
-// 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.
-
-#ifndef __WALKINGLEAF_H__
-#define __WALKINGLEAF_H__
-
-#include "walking_badguy.hpp"
-
-/*
- * Easy to kill badguy that does not jump down from it's ledge.
- */
-class WalkingLeaf : public WalkingBadguy
-{
-public:
- WalkingLeaf(const lisp::Lisp& reader);
- WalkingLeaf(const Vector& pos, Direction d);
-
- virtual WalkingLeaf* clone() const { return new WalkingLeaf(*this); }
-
-protected:
- bool collision_squished(GameObject& object);
-
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux - "Will-O-Wisp" Badguy
-// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
-//
-// 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.
-#include <config.h>
-
-#include "willowisp.hpp"
-#include "log.hpp"
-#include "game_session.hpp"
-#include "object/lantern.hpp"
-#include "object/player.hpp"
-#include "scripting/squirrel_util.hpp"
-
-static const float FLYSPEED = 64; /**< speed in px per second */
-static const float TRACK_RANGE = 384; /**< at what distance to start tracking the player */
-static const float VANISH_RANGE = 512; /**< at what distance to stop tracking and vanish */
-static const std::string SOUNDFILE = "sounds/willowisp.wav";
-
-WillOWisp::WillOWisp(const lisp::Lisp& reader)
- : BadGuy(reader, "images/creatures/willowisp/willowisp.sprite", LAYER_FLOATINGOBJECTS), mystate(STATE_IDLE), target_sector("main"), target_spawnpoint("main")
-{
- bool running = false;
- flyspeed = FLYSPEED;
- track_range = TRACK_RANGE;
- vanish_range = VANISH_RANGE;
-
- reader.get("sector", target_sector);
- reader.get("spawnpoint", target_spawnpoint);
- reader.get("name", name);
- reader.get("flyspeed", flyspeed);
- reader.get("track-range", track_range);
- reader.get("vanish-range", vanish_range);
- reader.get("hit-script", hit_script);
- reader.get("running", running);
-
- const lisp::Lisp* pathLisp = reader.get_lisp("path");
- if(pathLisp != NULL) {
- path.reset(new Path());
- path->read(*pathLisp);
- walker.reset(new PathWalker(path.get(), running));
- if(running)
- mystate = STATE_PATHMOVING_TRACK;
- }
-
- countMe = false;
- sound_manager->preload(SOUNDFILE);
-}
-
-void
-WillOWisp::draw(DrawingContext& context)
-{
- sprite->draw(context, get_pos(), layer);
-
- context.push_target();
- context.set_target(DrawingContext::LIGHTMAP);
-
- sprite->draw(context, get_pos(), layer);
-
- context.pop_target();
-}
-
-void
-WillOWisp::active_update(float elapsed_time)
-{
- Player* player = get_nearest_player();
- if (!player) return;
- Vector p1 = this->get_pos() + (this->get_bbox().p2 - this->get_bbox().p1) / 2;
- Vector p2 = player->get_pos() + (player->get_bbox().p2 - player->get_bbox().p1) / 2;
- Vector dist = (p2 - p1);
-
- switch(mystate) {
- case STATE_STOPPED:
- break;
-
- case STATE_IDLE:
- if (dist.norm() <= track_range) {
- mystate = STATE_TRACKING;
- }
- break;
-
- case STATE_TRACKING:
- if (dist.norm() <= vanish_range) {
- Vector dir = dist.unit();
- movement = dir * elapsed_time * flyspeed;
- } else {
- vanish();
- }
- sound_source->set_position(get_pos());
- break;
-
- case STATE_WARPING:
- if(sprite->animation_done()) {
- remove_me();
- }
-
- case STATE_VANISHING: {
- Vector dir = dist.unit();
- movement = dir * elapsed_time * flyspeed;
- if(sprite->animation_done()) {
- remove_me();
- }
- break;
- }
-
- case STATE_PATHMOVING:
- case STATE_PATHMOVING_TRACK:
- if(walker.get() == NULL)
- return;
- movement = walker->advance(elapsed_time) - get_pos();
- if(mystate == STATE_PATHMOVING_TRACK && dist.norm() <= track_range) {
- mystate = STATE_TRACKING;
- }
- break;
-
- default:
- assert(false);
- }
-}
-
-void
-WillOWisp::activate()
-{
- sprite->set_action("idle");
-
- sound_source.reset(sound_manager->create_sound_source(SOUNDFILE));
- sound_source->set_position(get_pos());
- sound_source->set_looping(true);
- sound_source->set_gain(2.0);
- sound_source->set_reference_distance(32);
- sound_source->play();
-}
-
-void
-WillOWisp::deactivate()
-{
- sound_source.reset(NULL);
-
- switch (mystate) {
- case STATE_STOPPED:
- case STATE_IDLE:
- case STATE_PATHMOVING:
- case STATE_PATHMOVING_TRACK:
- break;
- case STATE_TRACKING:
- mystate = STATE_IDLE;
- break;
- case STATE_WARPING:
- case STATE_VANISHING:
- remove_me();
- break;
- }
-}
-
-void
-WillOWisp::vanish()
-{
- mystate = STATE_VANISHING;
- sprite->set_action("vanishing", 1);
- set_group(COLGROUP_DISABLED);
-}
-
-bool
-WillOWisp::collides(GameObject& other, const CollisionHit& ) {
- Lantern* lantern = dynamic_cast<Lantern*>(&other);
-
- if (lantern && lantern->is_open())
- return true;
-
- if (dynamic_cast<Player*>(&other))
- return true;
-
- return false;
-}
-
-HitResponse
-WillOWisp::collision_player(Player& player, const CollisionHit& ) {
- if(player.is_invincible())
- return ABORT_MOVE;
-
- if (mystate != STATE_TRACKING)
- return ABORT_MOVE;
-
- mystate = STATE_WARPING;
- sprite->set_action("warping", 1);
-
- if(hit_script != "") {
- std::istringstream stream(hit_script);
- Sector::current()->run_script(stream, "hit-script");
- } else {
- GameSession::current()->respawn(target_sector, target_spawnpoint);
- }
- sound_manager->play("sounds/warp.wav");
-
- return CONTINUE;
-}
-
-void
-WillOWisp::goto_node(int node_no)
-{
- walker->goto_node(node_no);
- if(mystate != STATE_PATHMOVING && mystate != STATE_PATHMOVING_TRACK) {
- mystate = STATE_PATHMOVING;
- }
-}
-
-void
-WillOWisp::start_moving()
-{
- walker->start_moving();
-}
-
-void
-WillOWisp::stop_moving()
-{
- walker->stop_moving();
-}
-
-void
-WillOWisp::set_state(const std::string& new_state)
-{
- if(new_state == "stopped") {
- mystate = STATE_STOPPED;
- } else if(new_state == "idle") {
- mystate = STATE_IDLE;
- } else if(new_state == "move_path") {
- mystate = STATE_PATHMOVING;
- walker->start_moving();
- } else if(new_state == "move_path_track") {
- mystate = STATE_PATHMOVING_TRACK;
- walker->start_moving();
- } else if(new_state == "normal") {
- mystate = STATE_IDLE;
- } else if(new_state == "vanish") {
- vanish();
- } else {
- std::ostringstream msg;
- msg << "Can't set unknown willowisp state '" << new_state << "', should "
- "be stopped, move_path, move_path_track or normal";
- throw new std::runtime_error(msg.str());
- }
-}
-
-void
-WillOWisp::expose(HSQUIRRELVM vm, SQInteger table_idx)
-{
- if (name.empty())
- return;
-
- std::cout << "Expose me '" << name << "'\n";
- Scripting::WillOWisp* interface = static_cast<Scripting::WillOWisp*> (this);
- expose_object(vm, table_idx, interface, name);
-}
-
-void
-WillOWisp::unexpose(HSQUIRRELVM vm, SQInteger table_idx)
-{
- if (name.empty())
- return;
-
- std::cout << "UnExpose me '" << name << "'\n";
- Scripting::unexpose_object(vm, table_idx, name);
-}
-
-IMPLEMENT_FACTORY(WillOWisp, "willowisp")
+++ /dev/null
-// $Id$
-//
-// SuperTux - "Will-O-Wisp" Badguy
-// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
-//
-// 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.
-
-#ifndef __WILLOWISP_H__
-#define __WILLOWISP_H__
-
-#include "badguy.hpp"
-#include "object/path.hpp"
-#include "object/path_walker.hpp"
-#include "script_interface.hpp"
-#include "scripting/willowisp.hpp"
-
-class WillOWisp : public BadGuy, public Scripting::WillOWisp,
- public ScriptInterface
-{
-public:
- WillOWisp(const lisp::Lisp& reader);
-
- void activate();
- void deactivate();
-
- void active_update(float elapsed_time);
- virtual bool is_flammable() const { return false; }
- virtual bool is_freezable() const { return false; }
- virtual void kill_fall() { vanish(); }
-
- /**
- * make WillOWisp vanish
- */
- void vanish();
-
- virtual void draw(DrawingContext& context);
-
- virtual void goto_node(int node_no);
- virtual void set_state(const std::string& state);
- virtual void start_moving();
- virtual void stop_moving();
-
- virtual void expose(HSQUIRRELVM vm, SQInteger table_idx);
- virtual void unexpose(HSQUIRRELVM vm, SQInteger table_idx);
-
-protected:
- virtual bool collides(GameObject& other, const CollisionHit& hit);
- HitResponse collision_player(Player& player, const CollisionHit& hit);
-
-private:
- enum MyState {
- STATE_STOPPED, STATE_IDLE, STATE_TRACKING, STATE_VANISHING, STATE_WARPING,
- STATE_PATHMOVING, STATE_PATHMOVING_TRACK
- };
- MyState mystate;
-
- std::string target_sector;
- std::string target_spawnpoint;
- std::string hit_script;
-
- std::auto_ptr<SoundSource> sound_source;
-
- std::auto_ptr<Path> path;
- std::auto_ptr<PathWalker> walker;
-
- float flyspeed;
- float track_range;
- float vanish_range;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux - Boss "Yeti"
-// Copyright (C) 2005 Matthias Braun <matze@braunis.de>
-// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
-//
-// 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.
-#include <config.h>
-
-#include <float.h>
-#include <sstream>
-#include <memory>
-#include "yeti.hpp"
-#include "object/camera.hpp"
-#include "yeti_stalactite.hpp"
-#include "bouncing_snowball.hpp"
-#include "game_session.hpp"
-#include "level.hpp"
-
-namespace {
- const float JUMP_DOWN_VX = 250; /**< horizontal speed while jumping off the dais */
- const float JUMP_DOWN_VY = -250; /**< vertical speed while jumping off the dais */
-
- const float RUN_VX = 350; /**< horizontal speed while running */
-
- const float JUMP_UP_VX = 350; /**< horizontal speed while jumping on the dais */
- const float JUMP_UP_VY = -800; /**< vertical speed while jumping on the dais */
-
- const float STOMP_VY = -250; /** vertical speed while stomping on the dais */
-
- const float LEFT_STAND_X = 16; /**< x-coordinate of left dais' end position */
- const float RIGHT_STAND_X = 800-60-16; /**< x-coordinate of right dais' end position */
- const float LEFT_JUMP_X = LEFT_STAND_X+224; /**< x-coordinate of from where to jump on the left dais */
- const float RIGHT_JUMP_X = RIGHT_STAND_X-224; /**< x-coordinate of from where to jump on the right dais */
- const float STOMP_WAIT = .5; /**< time we stay on the dais before jumping again */
- const float SAFE_TIME = .5; /**< the time we are safe when tux just hit us */
- const int INITIAL_HITPOINTS = 3; /**< number of hits we can take */
-
- const float SQUISH_TIME = 5;
-}
-
-Yeti::Yeti(const lisp::Lisp& reader)
- : BadGuy(reader, "images/creatures/yeti/yeti.sprite")
-{
- hit_points = INITIAL_HITPOINTS;
- countMe = false;
- sound_manager->preload("sounds/yeti_gna.wav");
- sound_manager->preload("sounds/yeti_roar.wav");
- hud_head.reset(new Surface("images/creatures/yeti/hudlife.png"));
-}
-
-Yeti::~Yeti()
-{
-}
-
-void
-Yeti::activate()
-{
- dir = RIGHT;
- jump_down();
-}
-
-void
-Yeti::draw(DrawingContext& context)
-{
- // we blink when we are safe
- if(safe_timer.started() && size_t(game_time*40)%2)
- return;
-
- draw_hit_points(context);
-
- BadGuy::draw(context);
-}
-
-void
-Yeti::draw_hit_points(DrawingContext& context)
-{
- int i;
-
- Surface *hh = hud_head.get();
- if (!hh)
- return;
-
- context.push_transform();
- context.set_translation(Vector(0, 0));
-
- for (i = 0; i < hit_points; ++i)
- {
- context.draw_surface(hh, Vector(BORDER_X + (i * hh->get_width()), BORDER_Y + 1), LAYER_FOREGROUND1);
- }
-
- context.pop_transform();
-}
-
-void
-Yeti::active_update(float elapsed_time)
-{
- switch(state) {
- case JUMP_DOWN:
- physic.set_velocity_x((dir==RIGHT)?+JUMP_DOWN_VX:-JUMP_DOWN_VX);
- break;
- case RUN:
- physic.set_velocity_x((dir==RIGHT)?+RUN_VX:-RUN_VX);
- if (((dir == RIGHT) && (get_pos().x >= RIGHT_JUMP_X)) || ((dir == LEFT) && (get_pos().x <= LEFT_JUMP_X))) jump_up();
- break;
- case JUMP_UP:
- physic.set_velocity_x((dir==RIGHT)?+JUMP_UP_VX:-JUMP_UP_VX);
- if (((dir == RIGHT) && (get_pos().x >= RIGHT_STAND_X)) || ((dir == LEFT) && (get_pos().x <= LEFT_STAND_X))) be_angry();
- break;
- case BE_ANGRY:
- if(state_timer.check()) {
- sound_manager->play("sounds/yeti_gna.wav");
- physic.set_velocity_y(STOMP_VY);
- sprite->set_action((dir==RIGHT)?"stomp-right":"stomp-left");
- }
- break;
- case SQUISHED:
- if (state_timer.check()) {
- remove_me();
- }
- break;
- }
-
- movement = physic.get_movement(elapsed_time);
-}
-
-void
-Yeti::jump_down()
-{
- sprite->set_action((dir==RIGHT)?"jump-right":"jump-left");
- physic.set_velocity_x((dir==RIGHT)?(+JUMP_DOWN_VX):(-JUMP_DOWN_VX));
- physic.set_velocity_y(JUMP_DOWN_VY);
- state = JUMP_DOWN;
-}
-
-void
-Yeti::run()
-{
- sprite->set_action((dir==RIGHT)?"run-right":"run-left");
- physic.set_velocity_x((dir==RIGHT)?(+RUN_VX):(-RUN_VX));
- physic.set_velocity_y(0);
- state = RUN;
-}
-
-void
-Yeti::jump_up()
-{
- sprite->set_action((dir==RIGHT)?"jump-right":"jump-left");
- physic.set_velocity_x((dir==RIGHT)?(+JUMP_UP_VX):(-JUMP_UP_VX));
- physic.set_velocity_y(JUMP_UP_VY);
- state = JUMP_UP;
-}
-
-void
-Yeti::be_angry()
-{
- //turn around
- dir = (dir==RIGHT)?LEFT:RIGHT;
-
- sprite->set_action((dir==RIGHT)?"stand-right":"stand-left");
- physic.set_velocity_x(0);
- physic.set_velocity_y(0);
- if (hit_points < INITIAL_HITPOINTS) summon_snowball();
- stomp_count = 0;
- state = BE_ANGRY;
- state_timer.start(STOMP_WAIT);
-}
-
-void
-Yeti::summon_snowball()
-{
- Sector::current()->add_object(new BouncingSnowball(Vector(get_pos().x+(dir == RIGHT ? 64 : -64), get_pos().y), dir));
-}
-
-bool
-Yeti::collision_squished(GameObject& object)
-{
- kill_squished(object);
-
- return true;
-}
-
-void
-Yeti::kill_squished(GameObject& object)
-{
- Player* player = dynamic_cast<Player*>(&object);
- if (player) {
- player->bounce(*this);
- take_hit(*player);
- }
-}
-
-void Yeti::take_hit(Player& )
-{
- if(safe_timer.started())
- return;
-
- sound_manager->play("sounds/yeti_roar.wav");
- hit_points--;
-
- if(hit_points <= 0) {
- // We're dead
- physic.enable_gravity(true);
- physic.set_velocity_x(0);
- physic.set_velocity_y(0);
-
- state = SQUISHED;
- state_timer.start(SQUISH_TIME);
- set_group(COLGROUP_MOVING_ONLY_STATIC);
- sprite->set_action("dead");
-
- if (countMe) Sector::current()->get_level()->stats.badguys++;
-
- if(dead_script != "") {
- std::istringstream stream(dead_script);
- Sector::current()->run_script(stream, "Yeti - dead-script");
- }
- }
- else {
- safe_timer.start(SAFE_TIME);
- }
-}
-
-void
-Yeti::kill_fall()
-{
- // shooting bullets or being invincible won't work :)
- take_hit(*get_nearest_player()); // FIXME: debug only(?)
-}
-
-void
-Yeti::write(lisp::Writer& writer)
-{
- writer.start_list("yeti");
-
- writer.write_float("x", start_position.x);
- writer.write_float("y", start_position.y);
-
- writer.end_list("yeti");
-}
-
-void
-Yeti::drop_stalactite()
-{
- // make a stalactite falling down and shake camera a bit
- Sector::current()->camera->shake(.1f, 0, 10);
-
- YetiStalactite* nearest = 0;
- float dist = FLT_MAX;
-
- Player* player = this->get_nearest_player();
- if (!player) return;
-
- Sector* sector = Sector::current();
- for(Sector::GameObjects::iterator i = sector->gameobjects.begin();
- i != sector->gameobjects.end(); ++i) {
- YetiStalactite* stalactite = dynamic_cast<YetiStalactite*> (*i);
- if(stalactite && stalactite->is_hanging()) {
- float sdist
- = fabsf(stalactite->get_pos().x - player->get_pos().x);
- if(sdist < dist) {
- nearest = stalactite;
- dist = sdist;
- }
- }
- }
-
- if(nearest)
- nearest->start_shaking();
-}
-
-void
-Yeti::collision_solid(const CollisionHit& hit)
-{
- if(hit.top || hit.bottom) {
- // hit floor or roof
- physic.set_velocity_y(0);
- switch (state) {
- case JUMP_DOWN:
- run();
- break;
- case RUN:
- break;
- case JUMP_UP:
- break;
- case BE_ANGRY:
- // we just landed
- if(!state_timer.started()) {
- sprite->set_action((dir==RIGHT)?"stand-right":"stand-left");
- stomp_count++;
- drop_stalactite();
-
- // go to other side after 3 jumps
- if(stomp_count == 3) {
- jump_down();
- } else {
- // jump again
- state_timer.start(STOMP_WAIT);
- }
- }
- break;
- case SQUISHED:
- break;
- }
- } else if(hit.left || hit.right) {
- // hit wall
- jump_up();
- }
-}
-
-IMPLEMENT_FACTORY(Yeti, "yeti")
+++ /dev/null
-// $Id$
-//
-// SuperTux - Boss "Yeti"
-// Copyright (C) 2005 Matthias Braun <matze@braunis.de>
-// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
-//
-// 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.
-
-#ifndef __YETI_H__
-#define __YETI_H__
-
-#include <memory>
-
-#include "badguy.hpp"
-
-class Yeti : public BadGuy
-{
-public:
- Yeti(const lisp::Lisp& lisp);
- ~Yeti();
-
- void draw(DrawingContext& context);
- void write(lisp::Writer& writer);
- void activate();
- void active_update(float elapsed_time);
- void collision_solid(const CollisionHit& hit);
- bool collision_squished(GameObject& object);
- void kill_squished(GameObject& object);
- void kill_fall();
-
- virtual Yeti* clone() const { return new Yeti((Yeti&)*this); }
-
-private:
- void run();
- void jump_up();
- void be_angry();
- void drop_stalactite();
- void summon_snowball();
- void jump_down();
-
- void draw_hit_points(DrawingContext& context);
-
- void take_hit(Player& player);
-
- enum YetiState {
- JUMP_DOWN,
- RUN,
- JUMP_UP,
- BE_ANGRY,
- SQUISHED
- };
- YetiState state;
- Timer state_timer;
- Timer safe_timer;
- int stomp_count;
- int hit_points;
- std::auto_ptr<Surface> hud_head;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include "yeti_stalactite.hpp"
-
-static const float SHAKE_TIME = .8f;
-
-YetiStalactite::YetiStalactite(const lisp::Lisp& lisp)
- : Stalactite(lisp)
-{
-}
-
-YetiStalactite::~YetiStalactite()
-{
-}
-
-void
-YetiStalactite::write(lisp::Writer& writer)
-{
- writer.start_list("yeti_stalactite");
- writer.write_float("x", start_position.x);
- writer.write_float("y", start_position.y);
- writer.end_list("yeti_stalactite");
-}
-
-void
-YetiStalactite::start_shaking()
-{
- timer.start(SHAKE_TIME);
- state = STALACTITE_SHAKING;
-}
-
-bool
-YetiStalactite::is_hanging()
-{
- return state == STALACTITE_HANGING;
-}
-
-void
-YetiStalactite::active_update(float elapsed_time)
-{
- if(state == STALACTITE_HANGING)
- return;
-
- Stalactite::active_update(elapsed_time);
-}
-
-IMPLEMENT_FACTORY(YetiStalactite, "yeti_stalactite")
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-
-#ifndef __YETI_STALACTITE_H__
-#define __YETI_STALACTITE_H__
-
-#include "stalactite.hpp"
-
-class YetiStalactite : public Stalactite
-{
-public:
- YetiStalactite(const lisp::Lisp& lisp);
- virtual ~YetiStalactite();
-
- void write(lisp::Writer& );
- void active_update(float elapsed_time);
- void start_shaking();
- bool is_hanging();
-
- virtual YetiStalactite* clone() const { return new YetiStalactite(*this); }
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// Zeekling - flyer that swoops down when she spots the player
-// Copyright (C) 2005 Matthias Braun <matze@braunis.de>
-// Copyright (C) 2006 Christoph Sommer <supertux@2006.expires.deltadevelopment.de>
-//
-// 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.
-
-#include <config.h>
-#include <math.h>
-
-#include "zeekling.hpp"
-#include "random_generator.hpp"
-
-Zeekling::Zeekling(const lisp::Lisp& reader)
- : BadGuy(reader, "images/creatures/zeekling/zeekling.sprite"), last_player(0)
-{
- state = FLYING;
-}
-
-Zeekling::Zeekling(const Vector& pos, Direction d)
- : BadGuy(pos, d, "images/creatures/zeekling/zeekling.sprite"), last_player(0)
-{
- state = FLYING;
-}
-
-void
-Zeekling::write(lisp::Writer& writer)
-{
- writer.start_list("zeekling");
-
- writer.write_float("x", start_position.x);
- writer.write_float("y", start_position.y);
-
- writer.end_list("zeekling");
-}
-
-void
-Zeekling::activate()
-{
- speed = systemRandom.rand(130, 171);
- physic.set_velocity_x(dir == LEFT ? -speed : speed);
- physic.enable_gravity(false);
- sprite->set_action(dir == LEFT ? "left" : "right");
-}
-
-bool
-Zeekling::collision_squished(GameObject& object)
-{
- sprite->set_action(dir == LEFT ? "squished-left" : "squished-right");
- kill_squished(object);
- kill_fall();
- return true;
-}
-
-void
-Zeekling::onBumpHorizontal() {
- if (state == FLYING) {
- dir = (dir == LEFT ? RIGHT : LEFT);
- sprite->set_action(dir == LEFT ? "left" : "right");
- physic.set_velocity_x(dir == LEFT ? -speed : speed);
- } else
- if (state == DIVING) {
- dir = (dir == LEFT ? RIGHT : LEFT);
- state = FLYING;
- sprite->set_action(dir == LEFT ? "left" : "right");
- physic.set_velocity_x(dir == LEFT ? -speed : speed);
- physic.set_velocity_y(0);
- } else
- if (state == CLIMBING) {
- dir = (dir == LEFT ? RIGHT : LEFT);
- sprite->set_action(dir == LEFT ? "left" : "right");
- physic.set_velocity_x(dir == LEFT ? -speed : speed);
- } else {
- assert(false);
- }
-}
-
-void
-Zeekling::onBumpVertical() {
- if (state == FLYING) {
- physic.set_velocity_y(0);
- } else
- if (state == DIVING) {
- state = CLIMBING;
- physic.set_velocity_y(-speed);
- sprite->set_action(dir == LEFT ? "left" : "right");
- } else
- if (state == CLIMBING) {
- state = FLYING;
- physic.set_velocity_y(0);
- }
-}
-
-void
-Zeekling::collision_solid(const CollisionHit& hit)
-{
- if(hit.top || hit.bottom) {
- onBumpVertical();
- } else if(hit.left || hit.right) {
- onBumpHorizontal();
- }
-}
-
-/**
- * linear prediction of player and badguy positions to decide if we should enter the DIVING state
- */
-bool
-Zeekling::should_we_dive() {
-
- const MovingObject* player = this->get_nearest_player();
- if (player && last_player && (player == last_player)) {
-
- // get positions, calculate movement
- const Vector player_pos = player->get_pos();
- const Vector player_mov = (player_pos - last_player_pos);
- const Vector self_pos = this->get_pos();
- const Vector self_mov = (self_pos - last_self_pos);
-
- // new vertical speed to test with
- float vy = 2*fabsf(self_mov.x);
-
- // do not dive if we are not above the player
- float height = player_pos.y - self_pos.y;
- if (height <= 0) return false;
-
- // do not dive if we are too far above the player
- if (height > 512) return false;
-
- // do not dive if we would not descend faster than the player
- float relSpeed = vy - player_mov.y;
- if (relSpeed <= 0) return false;
-
- // guess number of frames to descend to same height as player
- float estFrames = height / relSpeed;
-
- // guess where the player would be at this time
- float estPx = (player_pos.x + (estFrames * player_mov.x));
-
- // guess where we would be at this time
- float estBx = (self_pos.x + (estFrames * self_mov.x));
-
- // near misses are OK, too
- if (fabsf(estPx - estBx) < 8) return true;
- }
-
- // update last player tracked, as well as our positions
- last_player = player;
- if (player) {
- last_player_pos = player->get_pos();
- last_self_pos = this->get_pos();
- }
-
- return false;
-}
-
-void
-Zeekling::active_update(float elapsed_time) {
- if (state == FLYING) {
- if (should_we_dive()) {
- state = DIVING;
- physic.set_velocity_y(2*fabsf(physic.get_velocity_x()));
- sprite->set_action(dir == LEFT ? "diving-left" : "diving-right");
- }
- BadGuy::active_update(elapsed_time);
- return;
- } else if (state == DIVING) {
- BadGuy::active_update(elapsed_time);
- return;
- } else if (state == CLIMBING) {
- // stop climbing when we're back at initial height
- if (get_pos().y <= start_position.y) {
- state = FLYING;
- physic.set_velocity_y(0);
- }
- BadGuy::active_update(elapsed_time);
- return;
- } else {
- assert(false);
- }
-}
-
-IMPLEMENT_FACTORY(Zeekling, "zeekling")
+++ /dev/null
-// $Id$
-//
-// Zeekling - flyer that swoops down when she spots the player
-// Copyright (C) 2005 Matthias Braun <matze@braunis.de>
-// Copyright (C) 2006 Christoph Sommer <supertux@2006.expires.deltadevelopment.de>
-//
-// 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.
-
-#ifndef __ZEEKLING_H__
-#define __ZEEKLING_H__
-
-#include "badguy.hpp"
-
-class Zeekling : public BadGuy
-{
-public:
- Zeekling(const lisp::Lisp& reader);
- Zeekling(const Vector& pos, Direction d);
-
- void activate();
- void write(lisp::Writer& writer);
- void collision_solid(const CollisionHit& hit);
- void active_update(float elapsed_time);
-
- virtual Zeekling* clone() const { return new Zeekling(*this); }
-
-protected:
- bool collision_squished(GameObject& object);
- float speed;
-
- Timer diveRecoverTimer;
-
- enum ZeeklingState {
- FLYING,
- DIVING,
- CLIMBING
- };
- ZeeklingState state;
-
-private:
- const MovingObject* last_player; /**< last player we tracked */
- Vector last_player_pos; /**< position we last spotted the player at */
- Vector last_self_pos; /**< position we last were at */
-
- bool should_we_dive();
- void onBumpHorizontal();
- void onBumpVertical();
-};
-
-#endif
+++ /dev/null
-/*
- * BinReloc - a library for creating relocatable executables
- * Written by: Hongli Lai <h.lai@chello.nl>
- * http://autopackage.org/
- *
- * This source code is public domain. You can relicense this code
- * under whatever license you want.
- *
- * See http://autopackage.org/docs/binreloc/ for
- * more information and how to use this.
- */
-
-#ifndef __BINRELOC_C__
-#define __BINRELOC_C__
-
-// [Christoph] use config.h, which defines ENABLE_BINRELOC
-#include <config.h>
-
-#ifdef ENABLE_BINRELOC
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <unistd.h>
-#endif /* ENABLE_BINRELOC */
-#include <stdio.h>
-#include <stdlib.h>
-#include <limits.h>
-#include <string.h>
-#include "binreloc.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif /* __cplusplus */
-
-
-
-/** @internal
- * Find the canonical filename of the executable. Returns the filename
- * (which must be freed) or NULL on error. If the parameter 'error' is
- * not NULL, the error code will be stored there, if an error occured.
- */
-static char *
-_br_find_exe (BrInitError *error)
-{
-#ifndef ENABLE_BINRELOC
- if (error)
- *error = BR_INIT_ERROR_DISABLED;
- return NULL;
-#else
- char *path, *path2, *line, *result;
- size_t buf_size;
- ssize_t size;
- struct stat stat_buf;
- FILE *f;
-
- /* Read from /proc/self/exe (symlink) */
- if (sizeof (path) > SSIZE_MAX)
- buf_size = SSIZE_MAX - 1;
- else
- buf_size = PATH_MAX - 1;
- path = (char *) malloc (buf_size);
- if (path == NULL) {
- /* Cannot allocate memory. */
- if (error)
- *error = BR_INIT_ERROR_NOMEM;
- return NULL;
- }
- path2 = (char *) malloc (buf_size);
- if (path2 == NULL) {
- /* Cannot allocate memory. */
- if (error)
- *error = BR_INIT_ERROR_NOMEM;
- free (path);
- return NULL;
- }
-
- strncpy (path2, "/proc/self/exe", buf_size - 1);
-
- while (1) {
- int i;
-
- size = readlink (path2, path, buf_size - 1);
- if (size == -1) {
- /* Error. */
- free (path2);
- break;
- }
-
- /* readlink() success. */
- path[size] = '\0';
-
- /* Check whether the symlink's target is also a symlink.
- * We want to get the final target. */
- i = stat (path, &stat_buf);
- if (i == -1) {
- /* Error. */
- free (path2);
- break;
- }
-
- /* stat() success. */
- if (!S_ISLNK (stat_buf.st_mode)) {
- /* path is not a symlink. Done. */
- free (path2);
- return path;
- }
-
- /* path is a symlink. Continue loop and resolve this. */
- strncpy (path, path2, buf_size - 1);
- }
-
-
- /* readlink() or stat() failed; this can happen when the program is
- * running in Valgrind 2.2. Read from /proc/self/maps as fallback. */
-
- buf_size = PATH_MAX + 128;
- line = (char *) realloc (path, buf_size);
- if (line == NULL) {
- /* Cannot allocate memory. */
- free (path);
- if (error)
- *error = BR_INIT_ERROR_NOMEM;
- return NULL;
- }
-
- f = fopen ("/proc/self/maps", "r");
- if (f == NULL) {
- free (line);
- if (error)
- *error = BR_INIT_ERROR_OPEN_MAPS;
- return NULL;
- }
-
- /* The first entry should be the executable name. */
- result = fgets (line, (int) buf_size, f);
- if (result == NULL) {
- fclose (f);
- free (line);
- if (error)
- *error = BR_INIT_ERROR_READ_MAPS;
- return NULL;
- }
-
- /* Get rid of newline character. */
- buf_size = strlen (line);
- if (buf_size <= 0) {
- /* Huh? An empty string? */
- fclose (f);
- free (line);
- if (error)
- *error = BR_INIT_ERROR_INVALID_MAPS;
- return NULL;
- }
- if (line[buf_size - 1] == 10)
- line[buf_size - 1] = 0;
-
- /* Extract the filename; it is always an absolute path. */
- path = strchr (line, '/');
-
- /* Sanity check. */
- if (strstr (line, " r-xp ") == NULL || path == NULL) {
- fclose (f);
- free (line);
- if (error)
- *error = BR_INIT_ERROR_INVALID_MAPS;
- return NULL;
- }
-
- path = strdup (path);
- free (line);
- fclose (f);
- return path;
-#endif /* ENABLE_BINRELOC */
-}
-
-
-/** @internal
- * Find the canonical filename of the executable which owns symbol.
- * Returns a filename which must be freed, or NULL on error.
- */
-static char *
-_br_find_exe_for_symbol (const void *symbol, BrInitError *error)
-{
- symbol = symbol; // [Christoph] mark it as used
-#ifndef ENABLE_BINRELOC
- if (error)
- *error = BR_INIT_ERROR_DISABLED;
- return (char *) NULL;
-#else
- #define SIZE PATH_MAX + 100
- FILE *f;
- size_t address_string_len;
- char *address_string, line[SIZE], *found;
-
- if (symbol == NULL)
- return (char *) NULL;
-
- f = fopen ("/proc/self/maps", "r");
- if (f == NULL)
- return (char *) NULL;
-
- address_string_len = 4;
- address_string = (char *) malloc (address_string_len);
- found = (char *) NULL;
-
- while (!feof (f)) {
- char *start_addr, *end_addr, *end_addr_end, *file;
- void *start_addr_p, *end_addr_p;
- size_t len;
-
- if (fgets (line, SIZE, f) == NULL)
- break;
-
- /* Sanity check. */
- if (strstr (line, " r-xp ") == NULL || strchr (line, '/') == NULL)
- continue;
-
- /* Parse line. */
- start_addr = line;
- end_addr = strchr (line, '-');
- file = strchr (line, '/');
-
- /* More sanity check. */
- if (!(file > end_addr && end_addr != NULL && end_addr[0] == '-'))
- continue;
-
- end_addr[0] = '\0';
- end_addr++;
- end_addr_end = strchr (end_addr, ' ');
- if (end_addr_end == NULL)
- continue;
-
- end_addr_end[0] = '\0';
- len = strlen (file);
- if (len == 0)
- continue;
- if (file[len - 1] == '\n')
- file[len - 1] = '\0';
-
- /* Get rid of "(deleted)" from the filename. */
- len = strlen (file);
- if (len > 10 && strcmp (file + len - 10, " (deleted)") == 0)
- file[len - 10] = '\0';
-
- /* I don't know whether this can happen but better safe than sorry. */
- len = strlen (start_addr);
- if (len != strlen (end_addr))
- continue;
-
-
- /* Transform the addresses into a string in the form of 0xdeadbeef,
- * then transform that into a pointer. */
- if (address_string_len < len + 3) {
- address_string_len = len + 3;
- address_string = (char *) realloc (address_string, address_string_len);
- }
-
- memcpy (address_string, "0x", 2);
- memcpy (address_string + 2, start_addr, len);
- address_string[2 + len] = '\0';
- sscanf (address_string, "%p", &start_addr_p);
-
- memcpy (address_string, "0x", 2);
- memcpy (address_string + 2, end_addr, len);
- address_string[2 + len] = '\0';
- sscanf (address_string, "%p", &end_addr_p);
-
-
- if (symbol >= start_addr_p && symbol < end_addr_p) {
- found = file;
- break;
- }
- }
-
- free (address_string);
- fclose (f);
-
- if (found == NULL)
- return (char *) NULL;
- else
- return strdup (found);
-#endif /* ENABLE_BINRELOC */
-}
-
-
-#ifndef BINRELOC_RUNNING_DOXYGEN
- #undef NULL
- #define NULL ((void *) 0) /* typecasted as char* for C++ type safeness */
-#endif
-
-static char *exe = (char *) NULL;
-
-
-/** Initialize the BinReloc library (for applications).
- *
- * This function must be called before using any other BinReloc functions.
- * It attempts to locate the application's canonical filename.
- *
- * @note If you want to use BinReloc for a library, then you should call
- * br_init_lib() instead.
- *
- * @param error If BinReloc failed to initialize, then the error code will
- * be stored in this variable. Set to NULL if you want to
- * ignore this. See #BrInitError for a list of error codes.
- *
- * @returns 1 on success, 0 if BinReloc failed to initialize.
- */
-int
-br_init (BrInitError *error)
-{
- exe = _br_find_exe (error);
- return exe != NULL;
-}
-
-
-/** Initialize the BinReloc library (for libraries).
- *
- * This function must be called before using any other BinReloc functions.
- * It attempts to locate the calling library's canonical filename.
- *
- * @note The BinReloc source code MUST be included in your library, or this
- * function won't work correctly.
- *
- * @param error If BinReloc failed to initialize, then the error code will
- * be stored in this variable. Set to NULL if you want to
- * ignore this. See #BrInitError for a list of error codes.
- *
- * @returns 1 on success, 0 if a filename cannot be found.
- */
-int
-br_init_lib (BrInitError *error)
-{
- exe = _br_find_exe_for_symbol ((const void *) "", error);
- return exe != NULL;
-}
-
-
-/** Find the canonical filename of the current application.
- *
- * @param default_exe A default filename which will be used as fallback.
- * @returns A string containing the application's canonical filename,
- * which must be freed when no longer necessary. If BinReloc is
- * not initialized, or if br_init() failed, then a copy of
- * default_exe will be returned. If default_exe is NULL, then
- * NULL will be returned.
- */
-char *
-br_find_exe (const char *default_exe)
-{
- if (exe == (char *) NULL) {
- /* BinReloc is not initialized. */
- if (default_exe != (const char *) NULL)
- return strdup (default_exe);
- else
- return (char *) NULL;
- }
- return strdup (exe);
-}
-
-
-/** Locate the directory in which the current application is installed.
- *
- * The prefix is generated by the following pseudo-code evaluation:
- * \code
- * dirname(exename)
- * \endcode
- *
- * @param default_dir A default directory which will used as fallback.
- * @return A string containing the directory, which must be freed when no
- * longer necessary. If BinReloc is not initialized, or if the
- * initialization function failed, then a copy of default_dir
- * will be returned. If default_dir is NULL, then NULL will be
- * returned.
- */
-char *
-br_find_exe_dir (const char *default_dir)
-{
- if (exe == NULL) {
- /* BinReloc not initialized. */
- if (default_dir != NULL)
- return strdup (default_dir);
- else
- return NULL;
- }
-
- return br_dirname (exe);
-}
-
-
-/** Locate the prefix in which the current application is installed.
- *
- * The prefix is generated by the following pseudo-code evaluation:
- * \code
- * dirname(dirname(exename))
- * \endcode
- *
- * @param default_prefix A default prefix which will used as fallback.
- * @return A string containing the prefix, which must be freed when no
- * longer necessary. If BinReloc is not initialized, or if
- * the initialization function failed, then a copy of default_prefix
- * will be returned. If default_prefix is NULL, then NULL will be returned.
- */
-char *
-br_find_prefix (const char *default_prefix)
-{
- char *dir1, *dir2;
-
- if (exe == (char *) NULL) {
- /* BinReloc not initialized. */
- if (default_prefix != (const char *) NULL)
- return strdup (default_prefix);
- else
- return (char *) NULL;
- }
-
- dir1 = br_dirname (exe);
- dir2 = br_dirname (dir1);
- free (dir1);
- return dir2;
-}
-
-
-/** Locate the application's binary folder.
- *
- * The path is generated by the following pseudo-code evaluation:
- * \code
- * prefix + "/bin"
- * \endcode
- *
- * @param default_bin_dir A default path which will used as fallback.
- * @return A string containing the bin folder's path, which must be freed when
- * no longer necessary. If BinReloc is not initialized, or if
- * the initialization function failed, then a copy of default_bin_dir will
- * be returned. If default_bin_dir is NULL, then NULL will be returned.
- */
-char *
-br_find_bin_dir (const char *default_bin_dir)
-{
- char *prefix, *dir;
-
- prefix = br_find_prefix ((const char *) NULL);
- if (prefix == (char *) NULL) {
- /* BinReloc not initialized. */
- if (default_bin_dir != (const char *) NULL)
- return strdup (default_bin_dir);
- else
- return (char *) NULL;
- }
-
- dir = br_build_path (prefix, "bin");
- free (prefix);
- return dir;
-}
-
-
-/** Locate the application's superuser binary folder.
- *
- * The path is generated by the following pseudo-code evaluation:
- * \code
- * prefix + "/sbin"
- * \endcode
- *
- * @param default_sbin_dir A default path which will used as fallback.
- * @return A string containing the sbin folder's path, which must be freed when
- * no longer necessary. If BinReloc is not initialized, or if the
- * initialization function failed, then a copy of default_sbin_dir will
- * be returned. If default_bin_dir is NULL, then NULL will be returned.
- */
-char *
-br_find_sbin_dir (const char *default_sbin_dir)
-{
- char *prefix, *dir;
-
- prefix = br_find_prefix ((const char *) NULL);
- if (prefix == (char *) NULL) {
- /* BinReloc not initialized. */
- if (default_sbin_dir != (const char *) NULL)
- return strdup (default_sbin_dir);
- else
- return (char *) NULL;
- }
-
- dir = br_build_path (prefix, "sbin");
- free (prefix);
- return dir;
-}
-
-
-/** Locate the application's data folder.
- *
- * The path is generated by the following pseudo-code evaluation:
- * \code
- * prefix + "/share"
- * \endcode
- *
- * @param default_data_dir A default path which will used as fallback.
- * @return A string containing the data folder's path, which must be freed when
- * no longer necessary. If BinReloc is not initialized, or if the
- * initialization function failed, then a copy of default_data_dir
- * will be returned. If default_data_dir is NULL, then NULL will be
- * returned.
- */
-char *
-br_find_data_dir (const char *default_data_dir)
-{
- char *prefix, *dir;
-
- prefix = br_find_prefix ((const char *) NULL);
- if (prefix == (char *) NULL) {
- /* BinReloc not initialized. */
- if (default_data_dir != (const char *) NULL)
- return strdup (default_data_dir);
- else
- return (char *) NULL;
- }
-
- dir = br_build_path (prefix, "share");
- free (prefix);
- return dir;
-}
-
-
-/** Locate the application's localization folder.
- *
- * The path is generated by the following pseudo-code evaluation:
- * \code
- * prefix + "/share/locale"
- * \endcode
- *
- * @param default_locale_dir A default path which will used as fallback.
- * @return A string containing the localization folder's path, which must be freed when
- * no longer necessary. If BinReloc is not initialized, or if the
- * initialization function failed, then a copy of default_locale_dir will be returned.
- * If default_locale_dir is NULL, then NULL will be returned.
- */
-char *
-br_find_locale_dir (const char *default_locale_dir)
-{
- char *data_dir, *dir;
-
- data_dir = br_find_data_dir ((const char *) NULL);
- if (data_dir == (char *) NULL) {
- /* BinReloc not initialized. */
- if (default_locale_dir != (const char *) NULL)
- return strdup (default_locale_dir);
- else
- return (char *) NULL;
- }
-
- dir = br_build_path (data_dir, "locale");
- free (data_dir);
- return dir;
-}
-
-
-/** Locate the application's library folder.
- *
- * The path is generated by the following pseudo-code evaluation:
- * \code
- * prefix + "/lib"
- * \endcode
- *
- * @param default_lib_dir A default path which will used as fallback.
- * @return A string containing the library folder's path, which must be freed when
- * no longer necessary. If BinReloc is not initialized, or if the initialization
- * function failed, then a copy of default_lib_dir will be returned.
- * If default_lib_dir is NULL, then NULL will be returned.
- */
-char *
-br_find_lib_dir (const char *default_lib_dir)
-{
- char *prefix, *dir;
-
- prefix = br_find_prefix ((const char *) NULL);
- if (prefix == (char *) NULL) {
- /* BinReloc not initialized. */
- if (default_lib_dir != (const char *) NULL)
- return strdup (default_lib_dir);
- else
- return (char *) NULL;
- }
-
- dir = br_build_path (prefix, "lib");
- free (prefix);
- return dir;
-}
-
-
-/** Locate the application's libexec folder.
- *
- * The path is generated by the following pseudo-code evaluation:
- * \code
- * prefix + "/libexec"
- * \endcode
- *
- * @param default_libexec_dir A default path which will used as fallback.
- * @return A string containing the libexec folder's path, which must be freed when
- * no longer necessary. If BinReloc is not initialized, or if the initialization
- * function failed, then a copy of default_libexec_dir will be returned.
- * If default_libexec_dir is NULL, then NULL will be returned.
- */
-char *
-br_find_libexec_dir (const char *default_libexec_dir)
-{
- char *prefix, *dir;
-
- prefix = br_find_prefix ((const char *) NULL);
- if (prefix == (char *) NULL) {
- /* BinReloc not initialized. */
- if (default_libexec_dir != (const char *) NULL)
- return strdup (default_libexec_dir);
- else
- return (char *) NULL;
- }
-
- dir = br_build_path (prefix, "libexec");
- free (prefix);
- return dir;
-}
-
-
-/** Locate the application's configuration files folder.
- *
- * The path is generated by the following pseudo-code evaluation:
- * \code
- * prefix + "/etc"
- * \endcode
- *
- * @param default_etc_dir A default path which will used as fallback.
- * @return A string containing the etc folder's path, which must be freed when
- * no longer necessary. If BinReloc is not initialized, or if the initialization
- * function failed, then a copy of default_etc_dir will be returned.
- * If default_etc_dir is NULL, then NULL will be returned.
- */
-char *
-br_find_etc_dir (const char *default_etc_dir)
-{
- char *prefix, *dir;
-
- prefix = br_find_prefix ((const char *) NULL);
- if (prefix == (char *) NULL) {
- /* BinReloc not initialized. */
- if (default_etc_dir != (const char *) NULL)
- return strdup (default_etc_dir);
- else
- return (char *) NULL;
- }
-
- dir = br_build_path (prefix, "etc");
- free (prefix);
- return dir;
-}
-
-
-/***********************
- * Utility functions
- ***********************/
-
-/** Concatenate str1 and str2 to a newly allocated string.
- *
- * @param str1 A string.
- * @param str2 Another string.
- * @returns A newly-allocated string. This string should be freed when no longer needed.
- */
-char *
-br_strcat (const char *str1, const char *str2)
-{
- char *result;
- size_t len1, len2;
-
- if (str1 == NULL)
- str1 = "";
- if (str2 == NULL)
- str2 = "";
-
- len1 = strlen (str1);
- len2 = strlen (str2);
-
- result = (char *) malloc (len1 + len2 + 1);
- memcpy (result, str1, len1);
- memcpy (result + len1, str2, len2);
- result[len1 + len2] = '\0';
-
- return result;
-}
-
-
-char *
-br_build_path (const char *dir, const char *file)
-{
- char *dir2, *result;
- size_t len;
- int must_free = 0;
-
- len = strlen (dir);
- if (len > 0 && dir[len - 1] != '/') {
- dir2 = br_strcat (dir, "/");
- must_free = 1;
- } else
- dir2 = (char *) dir;
-
- result = br_strcat (dir2, file);
- if (must_free)
- free (dir2);
- return result;
-}
-
-
-/* Emulates glibc's strndup() */
-static char *
-br_strndup (const char *str, size_t size)
-{
- char *result = (char *) NULL;
- size_t len;
-
- if (str == (const char *) NULL)
- return (char *) NULL;
-
- len = strlen (str);
- if (len == 0)
- return strdup ("");
- if (size > len)
- size = len;
-
- result = (char *) malloc (len + 1);
- memcpy (result, str, size);
- result[size] = '\0';
- return result;
-}
-
-
-/** Extracts the directory component of a path.
- *
- * Similar to g_dirname() or the dirname commandline application.
- *
- * Example:
- * \code
- * br_dirname ("/usr/local/foobar"); --> Returns: "/usr/local"
- * \endcode
- *
- * @param path A path.
- * @returns A directory name. This string should be freed when no longer needed.
- */
-char *
-br_dirname (const char *path)
-{
- char *end, *result;
-
- if (path == (const char *) NULL)
- return (char *) NULL;
-
- end = strrchr (path, '/');
- if (end == (const char *) NULL)
- return strdup (".");
-
- while (end > path && *end == '/')
- end--;
- result = br_strndup (path, end - path + 1);
- if (result[0] == 0) {
- free (result);
- return strdup ("/");
- } else
- return result;
-}
-
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-#endif /* __BINRELOC_C__ */
+++ /dev/null
-/*
- * BinReloc - a library for creating relocatable executables
- * Written by: Hongli Lai <h.lai@chello.nl>
- * http://autopackage.org/
- *
- * This source code is public domain. You can relicense this code
- * under whatever license you want.
- *
- * See http://autopackage.org/docs/binreloc/ for
- * more information and how to use this.
- */
-
-#ifndef __BINRELOC_H__
-#define __BINRELOC_H__
-
-#ifdef __cplusplus
-extern "C" {
-#endif /* __cplusplus */
-
-
-/** These error codes can be returned by br_init(), br_init_lib(), gbr_init() or gbr_init_lib(). */
-typedef enum {
- /** Cannot allocate memory. */
- BR_INIT_ERROR_NOMEM,
- /** Unable to open /proc/self/maps; see errno for details. */
- BR_INIT_ERROR_OPEN_MAPS,
- /** Unable to read from /proc/self/maps; see errno for details. */
- BR_INIT_ERROR_READ_MAPS,
- /** The file format of /proc/self/maps is invalid; kernel bug? */
- BR_INIT_ERROR_INVALID_MAPS,
- /** BinReloc is disabled (the ENABLE_BINRELOC macro is not defined). */
- BR_INIT_ERROR_DISABLED
-} BrInitError;
-
-
-#ifndef BINRELOC_RUNNING_DOXYGEN
-/* Mangle symbol names to avoid symbol collisions with other ELF objects. */
- #define br_init PTeH3518859728963_br_init
- #define br_init_lib PTeH3518859728963_br_init_lib
- #define br_find_exe PTeH3518859728963_br_find_exe
- #define br_find_exe_dir PTeH3518859728963_br_find_exe_dir
- #define br_find_prefix PTeH3518859728963_br_find_prefix
- #define br_find_bin_dir PTeH3518859728963_br_find_bin_dir
- #define br_find_sbin_dir PTeH3518859728963_br_find_sbin_dir
- #define br_find_data_dir PTeH3518859728963_br_find_data_dir
- #define br_find_locale_dir PTeH3518859728963_br_find_locale_dir
- #define br_find_lib_dir PTeH3518859728963_br_find_lib_dir
- #define br_find_libexec_dir PTeH3518859728963_br_find_libexec_dir
- #define br_find_etc_dir PTeH3518859728963_br_find_etc_dir
- #define br_strcat PTeH3518859728963_br_strcat
- #define br_build_path PTeH3518859728963_br_build_path
- #define br_dirname PTeH3518859728963_br_dirname
-
-
-#endif
-int br_init (BrInitError *error);
-int br_init_lib (BrInitError *error);
-
-char *br_find_exe (const char *default_exe);
-char *br_find_exe_dir (const char *default_dir);
-char *br_find_prefix (const char *default_prefix);
-char *br_find_bin_dir (const char *default_bin_dir);
-char *br_find_sbin_dir (const char *default_sbin_dir);
-char *br_find_data_dir (const char *default_data_dir);
-char *br_find_locale_dir (const char *default_locale_dir);
-char *br_find_lib_dir (const char *default_lib_dir);
-char *br_find_libexec_dir (const char *default_libexec_dir);
-char *br_find_etc_dir (const char *default_etc_dir);
-
-/* Utility functions */
-char *br_strcat (const char *str1, const char *str2);
-char *br_build_path (const char *dir, const char *file);
-char *br_dirname (const char *path);
-
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-#endif /* __BINRELOC_H__ */
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#include <config.h>
-
-#include "collision.hpp"
-
-#include <algorithm>
-#include <iostream>
-#include <stdio.h>
-#include <float.h>
-#include <math.h>
-#include "math/vector.hpp"
-#include "math/aatriangle.hpp"
-#include "math/rect.hpp"
-#include "collision_hit.hpp"
-#include "log.hpp"
-
-namespace collision
-{
-
-bool intersects(const Rect& r1, const Rect& r2)
-{
- if(r1.p2.x < r2.p1.x || r1.p1.x > r2.p2.x)
- return false;
- if(r1.p2.y < r2.p1.y || r1.p1.y > r2.p2.y)
- return false;
-
- return true;
-}
-
-//---------------------------------------------------------------------------
-
-namespace {
- inline void makePlane(const Vector& p1, const Vector& p2, Vector& n, float& c)
- {
- n = Vector(p2.y-p1.y, p1.x-p2.x);
- c = -(p2 * n);
- float nval = n.norm();
- n /= nval;
- c /= nval;
- }
-
- static const float DELTA = .0001f;
-}
-
-bool rectangle_aatriangle(Constraints* constraints, const Rect& rect,
- const AATriangle& triangle)
-{
- if(!intersects(rect, (const Rect&) triangle))
- return false;
-
- Vector normal;
- float c;
- Vector p1;
- Rect area;
- switch(triangle.dir & AATriangle::DEFORM_MASK) {
- case 0:
- area.p1 = triangle.p1;
- area.p2 = triangle.p2;
- break;
- case AATriangle::DEFORM1:
- area.p1 = Vector(triangle.p1.x, triangle.p1.y + triangle.get_height()/2);
- area.p2 = triangle.p2;
- break;
- case AATriangle::DEFORM2:
- area.p1 = triangle.p1;
- area.p2 = Vector(triangle.p2.x, triangle.p1.y + triangle.get_height()/2);
- break;
- case AATriangle::DEFORM3:
- area.p1 = triangle.p1;
- area.p2 = Vector(triangle.p1.x + triangle.get_width()/2, triangle.p2.y);
- break;
- case AATriangle::DEFORM4:
- area.p1 = Vector(triangle.p1.x + triangle.get_width()/2, triangle.p1.y);
- area.p2 = triangle.p2;
- break;
- default:
- assert(false);
- }
-
- switch(triangle.dir & AATriangle::DIRECTION_MASK) {
- case AATriangle::SOUTHWEST:
- p1 = Vector(rect.p1.x, rect.p2.y);
- makePlane(area.p1, area.p2, normal, c);
- break;
- case AATriangle::NORTHEAST:
- p1 = Vector(rect.p2.x, rect.p1.y);
- makePlane(area.p2, area.p1, normal, c);
- break;
- case AATriangle::SOUTHEAST:
- p1 = rect.p2;
- makePlane(Vector(area.p1.x, area.p2.y),
- Vector(area.p2.x, area.p1.y), normal, c);
- break;
- case AATriangle::NORTHWEST:
- p1 = rect.p1;
- makePlane(Vector(area.p2.x, area.p1.y),
- Vector(area.p1.x, area.p2.y), normal, c);
- break;
- default:
- assert(false);
- }
-
- float n_p1 = -(normal * p1);
- float depth = n_p1 - c;
- if(depth < 0)
- return false;
-
-#if 0
- std::cout << "R: " << rect << " Tri: " << triangle << "\n";
- std::cout << "Norm: " << normal << " Depth: " << depth << "\n";
-#endif
-
- Vector outvec = normal * (depth + 0.2f);
-
- const float RDELTA = 3;
- if(p1.x < area.p1.x - RDELTA || p1.x > area.p2.x + RDELTA
- || p1.y < area.p1.y - RDELTA || p1.y > area.p2.y + RDELTA) {
- set_rectangle_rectangle_constraints(constraints, rect, area);
- constraints->hit.left = false;
- constraints->hit.right = false;
- } else {
- if(outvec.x < 0) {
- constraints->right = rect.get_right() + outvec.x;
- } else {
- constraints->left = rect.get_left() + outvec.x;
- }
-
- if(outvec.y < 0) {
- constraints->bottom = rect.get_bottom() + outvec.y;
- constraints->hit.bottom = true;
- } else {
- constraints->top = rect.get_top() + outvec.y;
- constraints->hit.top = true;
- }
- constraints->hit.slope_normal = normal;
- }
-
- return true;
-}
-
-void set_rectangle_rectangle_constraints(Constraints* constraints,
- const Rect& r1, const Rect& r2)
-{
- float itop = r1.get_bottom() - r2.get_top();
- float ibottom = r2.get_bottom() - r1.get_top();
- float ileft = r1.get_right() - r2.get_left();
- float iright = r2.get_right() - r1.get_left();
-
- float vert_penetration = std::min(itop, ibottom);
- float horiz_penetration = std::min(ileft, iright);
- if(vert_penetration < horiz_penetration) {
- if(itop < ibottom) {
- constraints->bottom = std::min(constraints->bottom, r2.get_top());
- constraints->hit.bottom = true;
- } else {
- constraints->top = std::max(constraints->top, r2.get_bottom());
- constraints->hit.top = true;
- }
- } else {
- if(ileft < iright) {
- constraints->right = std::min(constraints->right, r2.get_left());
- constraints->hit.right = true;
- } else {
- constraints->left = std::max(constraints->left, r2.get_right());
- constraints->hit.left = true;
- }
- }
-}
-
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#ifndef __COLLISION_H__
-#define __COLLISION_H__
-
-#include <float.h>
-#include "collision_hit.hpp"
-#include <limits>
-
-class Vector;
-class Rect;
-class AATriangle;
-
-namespace collision
-{
-
-class Constraints
-{
-public:
- Constraints() {
- float infinity = (std::numeric_limits<float>::has_infinity ? std::numeric_limits<float>::infinity() : std::numeric_limits<float>::max());
- left = -infinity;
- right = infinity;
- top = -infinity;
- bottom = infinity;
- }
-
- bool has_constraints() const {
- float infinity = (std::numeric_limits<float>::has_infinity ? std::numeric_limits<float>::infinity() : std::numeric_limits<float>::max());
- return left > -infinity || right < infinity
- || top > -infinity || bottom < infinity;
- }
-
- float left;
- float right;
- float top;
- float bottom;
- Vector ground_movement;
- CollisionHit hit;
-};
-
-/** checks if 2 rectangle intersect each other */
-bool intersects(const Rect& r1, const Rect& r2);
-
-/** does collision detection between a rectangle and an axis aligned triangle
- * Returns true in case of a collision and fills in the hit structure then.
- */
-bool rectangle_aatriangle(Constraints* constraints, const Rect& rect,
- const AATriangle& triangle);
-
-void set_rectangle_rectangle_constraints(Constraints* constraints,
- const Rect& r1, const Rect& r2);
-
-}
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#ifndef SUPERTUX_COLLISION_HIT_H
-#define SUPERTUX_COLLISION_HIT_H
-
-#include <float.h>
-#include <math.h>
-#include "math/vector.hpp"
-
-/**
- * Used as return value for the collision functions, to indicate how the
- * collision should be handled
- */
-enum HitResponse
-{
- /// don't move the object
- ABORT_MOVE = 0,
- /// move object out of collision and check for collisions again
- /// if this happens to often then the move will just be aborted
- CONTINUE,
- /// do the move ignoring the collision
- FORCE_MOVE,
- /// passes movement to collided object
- PASS_MOVEMENT,
-
- /// the object should not appear solid
- PASSTHROUGH,
- /// the object should appear solid
- SOLID,
-};
-
-/**
- * This class collects data about a collision
- */
-class CollisionHit
-{
-public:
- CollisionHit() {
- left = false;
- right = false;
- top = false;
- bottom = false;
- crush = false;
- }
-
- bool left, right;
- bool top, bottom;
- bool crush;
-
- Vector slope_normal;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux - Console
-// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
-//
-// 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.
-#include <config.h>
-
-#include <iostream>
-#include <math.h>
-#include <SDL_timer.h>
-#include <SDL_keyboard.h>
-#include "console.hpp"
-#include "video/drawing_context.hpp"
-#include "video/surface.hpp"
-#include "scripting/squirrel_error.hpp"
-#include "scripting/squirrel_util.hpp"
-#include "physfs/physfs_stream.hpp"
-#include "player_status.hpp"
-#include "main.hpp"
-#include "log.hpp"
-#include "resources.hpp"
-#include "gameconfig.hpp"
-
-/// speed (pixels/s) the console closes
-static const float FADE_SPEED = 1;
-
-Console::Console()
- : history_position(history.end()), vm(NULL), backgroundOffset(0),
- height(0), alpha(1.0), offset(0), focused(false), stayOpen(0) {
- fontheight = 8;
-}
-
-Console::~Console()
-{
- if(vm != NULL) {
- sq_release(Scripting::global_vm, &vm_object);
- }
-}
-
-void
-Console::init_graphics()
-{
- font.reset(new Font(Font::FIXED,
- "images/engine/fonts/andale12.png",
- "images/engine/fonts/andale12-shadow.png", 7, 14, 1));
- fontheight = font->get_height();
- background.reset(new Surface("images/engine/console.png"));
- background2.reset(new Surface("images/engine/console2.png"));
-}
-
-void
-Console::flush(ConsoleStreamBuffer* buffer)
-{
- if (buffer == &outputBuffer) {
- std::string s = outputBuffer.str();
- if ((s.length() > 0) && ((s[s.length()-1] == '\n') || (s[s.length()-1] == '\r'))) {
- while ((s[s.length()-1] == '\n') || (s[s.length()-1] == '\r')) s.erase(s.length()-1);
- addLines(s);
- outputBuffer.str(std::string());
- }
- }
-}
-
-void
-Console::ready_vm()
-{
- if(vm == NULL) {
- vm = Scripting::global_vm;
- HSQUIRRELVM new_vm = sq_newthread(vm, 16);
- if(new_vm == NULL)
- throw Scripting::SquirrelError(vm, "Couldn't create new VM thread for console");
-
- // store reference to thread
- sq_resetobject(&vm_object);
- if(SQ_FAILED(sq_getstackobj(vm, -1, &vm_object)))
- throw Scripting::SquirrelError(vm, "Couldn't get vm object for console");
- sq_addref(vm, &vm_object);
- sq_pop(vm, 1);
-
- // create new roottable for thread
- sq_newtable(new_vm);
- sq_pushroottable(new_vm);
- if(SQ_FAILED(sq_setdelegate(new_vm, -2)))
- throw Scripting::SquirrelError(new_vm, "Couldn't set console_table delegate");
-
- sq_setroottable(new_vm);
-
- vm = new_vm;
-
- try {
- std::string filename = "scripts/console.nut";
- IFileStream stream(filename);
- Scripting::compile_and_run(vm, stream, filename);
- } catch(std::exception& e) {
- log_warning << "Couldn't load console.nut: " << e.what() << std::endl;
- }
- }
-}
-
-void
-Console::execute_script(const std::string& command)
-{
- using namespace Scripting;
-
- ready_vm();
-
- SQInteger oldtop = sq_gettop(vm);
- try {
- if(SQ_FAILED(sq_compilebuffer(vm, command.c_str(), command.length(),
- "", SQTrue)))
- throw SquirrelError(vm, "Couldn't compile command");
-
- sq_pushroottable(vm);
- if(SQ_FAILED(sq_call(vm, 1, SQTrue, SQTrue)))
- throw SquirrelError(vm, "Problem while executing command");
-
- if(sq_gettype(vm, -1) != OT_NULL)
- addLines(squirrel2string(vm, -1));
- } catch(std::exception& e) {
- addLines(e.what());
- }
- SQInteger newtop = sq_gettop(vm);
- if(newtop < oldtop) {
- log_fatal << "Script destroyed squirrel stack..." << std::endl;
- } else {
- sq_settop(vm, oldtop);
- }
-}
-
-void
-Console::input(char c)
-{
- inputBuffer.insert(inputBufferPosition, 1, c);
- inputBufferPosition++;
-}
-
-void
-Console::backspace()
-{
- if ((inputBufferPosition > 0) && (inputBuffer.length() > 0)) {
- inputBuffer.erase(inputBufferPosition-1, 1);
- inputBufferPosition--;
- }
-}
-
-void
-Console::eraseChar()
-{
- if (inputBufferPosition < (int)inputBuffer.length()) {
- inputBuffer.erase(inputBufferPosition, 1);
- }
-}
-
-void
-Console::enter()
-{
- addLines("> "+inputBuffer);
- parse(inputBuffer);
- inputBuffer = "";
- inputBufferPosition = 0;
-}
-
-void
-Console::scroll(int numLines)
-{
- offset += numLines;
- if (offset > 0) offset = 0;
-}
-
-void
-Console::show_history(int offset)
-{
- while ((offset > 0) && (history_position != history.end())) {
- history_position++;
- offset--;
- }
- while ((offset < 0) && (history_position != history.begin())) {
- history_position--;
- offset++;
- }
- if (history_position == history.end()) {
- inputBuffer = "";
- inputBufferPosition = 0;
- } else {
- inputBuffer = *history_position;
- inputBufferPosition = inputBuffer.length();
- }
-}
-
-void
-Console::move_cursor(int offset)
-{
- if (offset == -65535) inputBufferPosition = 0;
- if (offset == +65535) inputBufferPosition = inputBuffer.length();
- inputBufferPosition+=offset;
- if (inputBufferPosition < 0) inputBufferPosition = 0;
- if (inputBufferPosition > (int)inputBuffer.length()) inputBufferPosition = inputBuffer.length();
-}
-
-// Helper functions for Console::autocomplete
-// TODO: Fix rough documentation
-namespace {
-
-void sq_insert_commands(std::list<std::string>& cmds, HSQUIRRELVM vm, std::string table_prefix, std::string search_prefix);
-
-/**
- * Acts upon key,value on top of stack:
- * Appends key (plus type-dependent suffix) to cmds if table_prefix+key starts with search_prefix;
- * Calls sq_insert_commands if search_prefix starts with table_prefix+key (and value is a table/class/instance);
- */
-void
-sq_insert_command(std::list<std::string>& cmds, HSQUIRRELVM vm, std::string table_prefix, std::string search_prefix)
-{
- const SQChar* key_chars;
- if (SQ_FAILED(sq_getstring(vm, -2, &key_chars))) return;
- std::string key_string = table_prefix + key_chars;
-
- switch (sq_gettype(vm, -1)) {
- case OT_INSTANCE:
- key_string+=".";
- if (search_prefix.substr(0, key_string.length()) == key_string) {
- sq_getclass(vm, -1);
- sq_insert_commands(cmds, vm, key_string, search_prefix);
- sq_pop(vm, 1);
- }
- break;
- case OT_TABLE:
- case OT_CLASS:
- key_string+=".";
- if (search_prefix.substr(0, key_string.length()) == key_string) {
- sq_insert_commands(cmds, vm, key_string, search_prefix);
- }
- break;
- case OT_CLOSURE:
- case OT_NATIVECLOSURE:
- key_string+="()";
- break;
- default:
- break;
- }
-
- if (key_string.substr(0, search_prefix.length()) == search_prefix) {
- cmds.push_back(key_string);
- }
-
-}
-
-/**
- * calls sq_insert_command for all entries of table/class on top of stack
- */
-void
-sq_insert_commands(std::list<std::string>& cmds, HSQUIRRELVM vm, std::string table_prefix, std::string search_prefix)
-{
- sq_pushnull(vm); // push iterator
- while (SQ_SUCCEEDED(sq_next(vm,-2))) {
- sq_insert_command(cmds, vm, table_prefix, search_prefix);
- sq_pop(vm, 2); // pop key, val
- }
- sq_pop(vm, 1); // pop iterator
-}
-
-
-}
-// End of Console::autocomplete helper functions
-
-void
-Console::autocomplete()
-{
- //int autocompleteFrom = inputBuffer.find_last_of(" ();+", inputBufferPosition);
- int autocompleteFrom = inputBuffer.find_last_not_of("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_->.", inputBufferPosition);
- if (autocompleteFrom != (int)std::string::npos) {
- autocompleteFrom += 1;
- } else {
- autocompleteFrom = 0;
- }
- std::string prefix = inputBuffer.substr(autocompleteFrom, inputBufferPosition - autocompleteFrom);
- addLines("> "+prefix);
-
- std::list<std::string> cmds;
-
- ready_vm();
-
- // append all keys of the current root table to list
- sq_pushroottable(vm); // push root table
- while(true) {
- // check all keys (and their children) for matches
- sq_insert_commands(cmds, vm, "", prefix);
-
- // cycle through parent(delegate) table
- SQInteger oldtop = sq_gettop(vm);
- if(SQ_FAILED(sq_getdelegate(vm, -1)) || oldtop == sq_gettop(vm)) {
- break;
- }
- sq_remove(vm, -2); // remove old table
- }
- sq_pop(vm, 1); // remove table
-
- // depending on number of hits, show matches or autocomplete
- if (cmds.size() == 0) addLines("No known command starts with \""+prefix+"\"");
- if (cmds.size() == 1) {
- // one match: just replace input buffer with full command
- std::string replaceWith = cmds.front();
- inputBuffer.replace(autocompleteFrom, prefix.length(), replaceWith);
- inputBufferPosition += (replaceWith.length() - prefix.length());
- }
- if (cmds.size() > 1) {
- // multiple matches: show all matches and set input buffer to longest common prefix
- std::string commonPrefix = cmds.front();
- while (cmds.begin() != cmds.end()) {
- std::string cmd = cmds.front();
- cmds.pop_front();
- addLines(cmd);
- for (int n = commonPrefix.length(); n >= 1; n--) {
- if (cmd.compare(0, n, commonPrefix) != 0) commonPrefix.resize(n-1); else break;
- }
- }
- std::string replaceWith = commonPrefix;
- inputBuffer.replace(autocompleteFrom, prefix.length(), replaceWith);
- inputBufferPosition += (replaceWith.length() - prefix.length());
- }
-}
-
-void
-Console::addLines(std::string s)
-{
- std::istringstream iss(s);
- std::string line;
- while (std::getline(iss, line, '\n')) addLine(line);
-}
-
-void
-Console::addLine(std::string s)
-{
- // output line to stderr
- std::cerr << s << std::endl;
-
- // wrap long lines
- std::string overflow;
- unsigned int line_count = 0;
- do {
- lines.push_front(Font::wrap_to_chars(s, 99, &overflow));
- line_count++;
- s = overflow;
- } while (s.length() > 0);
-
- // trim scrollback buffer
- while (lines.size() >= 1000)
- lines.pop_back();
-
- // increase console height if necessary
- if (height < 64) {
- if(height < 4)
- height = 4;
- height += fontheight * line_count;
- }
-
- // reset console to full opacity
- alpha = 1.0;
-
- // increase time that console stays open
- if(stayOpen < 6)
- stayOpen += 1.5;
-}
-
-void
-Console::parse(std::string s)
-{
- // make sure we actually have something to parse
- if (s.length() == 0) return;
-
- // add line to history
- history.push_back(s);
- history_position = history.end();
-
- // split line into list of args
- std::vector<std::string> args;
- size_t start = 0;
- size_t end = 0;
- while (1) {
- start = s.find_first_not_of(" ,", end);
- end = s.find_first_of(" ,", start);
- if (start == s.npos) break;
- args.push_back(s.substr(start, end-start));
- }
-
- // command is args[0]
- if (args.size() == 0) return;
- std::string command = args.front();
- args.erase(args.begin());
-
- // ignore if it's an internal command
- if (consoleCommand(command,args)) return;
-
- try {
- execute_script(s);
- } catch(std::exception& e) {
- addLines(e.what());
- }
-
-}
-
-bool
-Console::consoleCommand(std::string /*command*/, std::vector<std::string> /*arguments*/)
-{
- return false;
-}
-
-bool
-Console::hasFocus()
-{
- return focused;
-}
-
-void
-Console::show()
-{
- if(!config->console_enabled)
- return;
-
- focused = true;
- height = 256;
- alpha = 1.0;
- SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);
-}
-
-void
-Console::hide()
-{
- focused = false;
- height = 0;
- stayOpen = 0;
-
- // clear input buffer
- inputBuffer = "";
- inputBufferPosition = 0;
- SDL_EnableKeyRepeat(0, SDL_DEFAULT_REPEAT_INTERVAL);
-}
-
-void
-Console::toggle()
-{
- if (Console::hasFocus()) {
- Console::hide();
- }
- else {
- Console::show();
- }
-}
-
-void
-Console::update(float elapsed_time)
-{
- if(stayOpen > 0) {
- stayOpen -= elapsed_time;
- if(stayOpen < 0)
- stayOpen = 0;
- } else if(!focused && height > 0) {
- alpha -= elapsed_time * FADE_SPEED;
- if(alpha < 0) {
- alpha = 0;
- height = 0;
- }
- }
-}
-
-void
-Console::draw(DrawingContext& context)
-{
- if (height == 0)
- return;
-
- int layer = LAYER_GUI + 1;
-
- context.push_transform();
- context.set_alpha(alpha);
- context.draw_surface(background2.get(), Vector(SCREEN_WIDTH/2 - background->get_width()/2 - background->get_width() + backgroundOffset, height - background->get_height()), layer);
- context.draw_surface(background2.get(), Vector(SCREEN_WIDTH/2 - background->get_width()/2 + backgroundOffset, height - background->get_height()), layer);
- for (int x = (SCREEN_WIDTH/2 - background->get_width()/2 - (static_cast<int>(ceilf((float)SCREEN_WIDTH / (float)background->get_width()) - 1) * background->get_width())); x < SCREEN_WIDTH; x+=background->get_width()) {
- context.draw_surface(background.get(), Vector(x, height - background->get_height()), layer);
- }
- backgroundOffset+=10;
- if (backgroundOffset > (int)background->get_width()) backgroundOffset -= (int)background->get_width();
-
- int lineNo = 0;
-
- if (focused) {
- lineNo++;
- float py = height-4-1 * font->get_height();
- context.draw_text(font.get(), "> "+inputBuffer, Vector(4, py), ALIGN_LEFT, layer);
- if (SDL_GetTicks() % 1000 < 750) {
- int cursor_px = 2 + inputBufferPosition;
- context.draw_text(font.get(), "_", Vector(4 + (cursor_px * font->get_text_width("X")), py), ALIGN_LEFT, layer);
- }
- }
-
- int skipLines = -offset;
- for (std::list<std::string>::iterator i = lines.begin(); i != lines.end(); i++) {
- if (skipLines-- > 0) continue;
- lineNo++;
- float py = height - 4 - lineNo*font->get_height();
- if (py < -font->get_height()) break;
- context.draw_text(font.get(), *i, Vector(4, py), ALIGN_LEFT, layer);
- }
- context.pop_transform();
-}
-
-Console* Console::instance = NULL;
-int Console::inputBufferPosition = 0;
-std::string Console::inputBuffer;
-ConsoleStreamBuffer Console::outputBuffer;
-std::ostream Console::output(&Console::outputBuffer);
-
+++ /dev/null
-// $Id$
-//
-// SuperTux - Console
-// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
-//
-// 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.
-
-#ifndef SUPERTUX_CONSOLE_H
-#define SUPERTUX_CONSOLE_H
-
-#include <list>
-#include <map>
-#include <vector>
-#include <string>
-#include <sstream>
-#include <iostream>
-#include <squirrel.h>
-
-class Console;
-class ConsoleStreamBuffer;
-class ConsoleCommandReceiver;
-class DrawingContext;
-class Surface;
-class Font;
-
-class Console
-{
-public:
- Console();
- ~Console();
-
- static Console* instance;
-
- static std::ostream output; /**< stream of characters to output to the console. Do not forget to send std::endl or to flush the stream. */
-
- void init_graphics();
-
- void input(char c); /**< add character to inputBuffer */
- void backspace(); /**< delete character left of inputBufferPosition */
- void eraseChar(); /**< delete character at inputBufferPosition */
- void enter(); /**< process and clear input stream */
- void scroll(int offset); /**< scroll console text up or down by @c offset lines */
- void autocomplete(); /**< autocomplete current command */
- void show_history(int offset); /**< move @c offset lines forward through history; Negative offset moves backward */
- void move_cursor(int offset); /**< move the cursor @c offset chars to the right; Negative offset moves backward; 0xFFFF moves to the end */
-
- void draw(DrawingContext& context); /**< draw the console in a DrawingContext */
- void update(float elapsed_time);
-
- void show(); /**< display the console */
- void hide(); /**< hide the console */
- void toggle(); /**< display the console if hidden, hide otherwise */
-
- bool hasFocus(); /**< true if characters should be sent to the console instead of their normal target */
-
- template<typename T> static bool string_is(std::string s) {
- std::istringstream iss(s);
- T i;
- if ((iss >> i) && iss.eof()) {
- return true;
- } else {
- return false;
- }
- }
-
- template<typename T> static T string_to(std::string s) {
- std::istringstream iss(s);
- T i;
- if ((iss >> i) && iss.eof()) {
- return i;
- } else {
- return T();
- }
- }
-
-private:
- std::list<std::string> history; /**< command history. New lines get added to back. */
- std::list<std::string>::iterator history_position; /**< item of command history that is currently displayed */
- std::list<std::string> lines; /**< backbuffer of lines sent to the console. New lines get added to front. */
-
- std::auto_ptr<Surface> background; /**< console background image */
- std::auto_ptr<Surface> background2; /**< second, moving console background image */
-
- HSQUIRRELVM vm; /**< squirrel thread for the console (with custom roottable) */
- HSQOBJECT vm_object;
-
- int backgroundOffset; /**< current offset of scrolling background image */
- float height; /**< height of the console in px */
- float alpha;
- int offset; /**< decrease to scroll text up */
- bool focused; /**< true if console has input focus */
- std::auto_ptr<Font> font;
- float fontheight; /**< height of the font (this is a separate var, because the font could not be initialized yet but is needed in the addLine message */
-
- float stayOpen;
-
- static int inputBufferPosition; /**< position in inputBuffer before which to append new characters */
- static std::string inputBuffer; /**< string used for keyboard input */
- static ConsoleStreamBuffer outputBuffer; /**< stream buffer used by output stream */
-
- void addLines(std::string s); /**< display a string of (potentially) multiple lines in the console */
- void addLine(std::string s); /**< display a line in the console */
- void parse(std::string s); /**< react to a given command */
-
- /** ready a virtual machine instance, creating a new thread and loading default .nut files if needed */
- void ready_vm();
-
- /** execute squirrel script and output result */
- void execute_script(const std::string& s);
-
- bool consoleCommand(std::string command, std::vector<std::string> arguments); /**< process internal command; return false if command was unknown, true otherwise */
-
- friend class ConsoleStreamBuffer;
- void flush(ConsoleStreamBuffer* buffer); /**< act upon changes in a ConsoleStreamBuffer */
-};
-
-class ConsoleStreamBuffer : public std::stringbuf
-{
- public:
- int sync()
- {
- int result = std::stringbuf::sync();
- if(Console::instance != NULL)
- Console::instance->flush(this);
- return result;
- }
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include "codecontroller.hpp"
-
-CodeController::CodeController()
-{}
-
-CodeController::~CodeController()
-{}
-
-void
-CodeController::press(Control c, bool pressed)
-{
- controls[c] = pressed;
-}
-
-void
-CodeController::update()
-{
- Controller::update();
-
- for(int i = 0; i < CONTROLCOUNT; ++i)
- controls[i] = false;
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __CODECONTROLLER_H__
-#define __CODECONTROLLER_H__
-
-#include "controller.hpp"
-
-/**
- * This is a dummy controler that doesn't react to any user input but should
- * be controlled by code
- */
-class CodeController : public Controller
-{
-public:
- CodeController();
- virtual ~CodeController();
-
- void press(Control c, bool pressed = true);
- void update();
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include "controller.hpp"
-
-const char* Controller::controlNames[] = {
- "left",
- "right",
- "up",
- "down",
- "jump",
- "action",
- "pause-menu",
- "menu-select",
- "console",
- "peek-left",
- "peek-right",
- 0
-};
-
-Controller::Controller()
-{
- reset();
-}
-
-Controller::~Controller()
-{}
-
-void
-Controller::reset()
-{
- for(int i = 0; i < CONTROLCOUNT; ++i) {
- controls[i] = false;
- oldControls[i] = false;
- }
-}
-
-bool
-Controller::hold(Control control)
-{
- return controls[control];
-}
-
-bool
-Controller::pressed(Control control)
-{
- return !oldControls[control] && controls[control];
-}
-
-bool
-Controller::released(Control control)
-{
- return oldControls[control] && !controls[control];
-}
-
-void
-Controller::update()
-{
- for(int i = 0; i < CONTROLCOUNT; ++i)
- oldControls[i] = controls[i];
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __CONTROLLER_H__
-#define __CONTROLLER_H__
-
-class Controller
-{
-public:
- static const char* controlNames[];
-
- enum Control {
- LEFT = 0,
- RIGHT,
- UP,
- DOWN,
-
- JUMP,
- ACTION,
-
- PAUSE_MENU,
- MENU_SELECT,
-
- CONSOLE,
-
- PEEK_LEFT,
- PEEK_RIGHT,
-
- CONTROLCOUNT
- };
-
- Controller();
- virtual ~Controller();
-
- /** returns true if the control is pressed down */
- bool hold(Control control);
- /** returns true if the control has just been pressed down this frame */
- bool pressed(Control control);
- /** returns true if the control has just been released this frame */
- bool released(Control control);
-
- virtual void reset();
- virtual void update();
-
-protected:
- /** current control status */
- bool controls[CONTROLCOUNT];
- /** control status at last frame */
- bool oldControls[CONTROLCOUNT];
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>,
-// 2007 Ingo Ruhnke <grumbel@gmx.de>
-//
-// 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.
-
-#include <config.h>
-
-#include <sstream>
-#include "joystickkeyboardcontroller.hpp"
-#include "log.hpp"
-#include "gui/menu.hpp"
-#include "gettext.hpp"
-#include "lisp/lisp.hpp"
-#include "lisp/list_iterator.hpp"
-#include "game_session.hpp"
-#include "console.hpp"
-#include "gameconfig.hpp"
-
-class JoystickKeyboardController::JoystickMenu : public Menu
-{
-public:
- JoystickMenu(JoystickKeyboardController* controller);
- virtual ~JoystickMenu();
-
- void update();
- std::string get_button_name(int button);
- void update_menu_item(Control id);
- virtual void menu_action(MenuItem* item);
- JoystickKeyboardController* controller;
-};
-
-class JoystickKeyboardController::KeyboardMenu : public Menu
-{
-public:
- KeyboardMenu(JoystickKeyboardController* controller);
- ~KeyboardMenu();
-
- void update();
- std::string get_key_name(SDLKey key);
- virtual void menu_action(MenuItem* item);
- JoystickKeyboardController* controller;
-};
-
-JoystickKeyboardController::JoystickKeyboardController()
- : hat_state(0),
- wait_for_key(-1), wait_for_joystick(-1),
- key_options_menu(0), joystick_options_menu(0)
-{
- // initialize default keyboard map
- keymap[SDLK_LEFT] = LEFT;
- keymap[SDLK_RIGHT] = RIGHT;
- keymap[SDLK_UP] = UP;
- keymap[SDLK_DOWN] = DOWN;
- keymap[SDLK_SPACE] = JUMP;
- keymap[SDLK_LCTRL] = ACTION;
- keymap[SDLK_LALT] = ACTION;
- keymap[SDLK_ESCAPE] = PAUSE_MENU;
- keymap[SDLK_p] = PAUSE_MENU;
- keymap[SDLK_PAUSE] = PAUSE_MENU;
- keymap[SDLK_RETURN] = MENU_SELECT;
- keymap[SDLK_KP_ENTER] = MENU_SELECT;
- keymap[SDLK_CARET] = CONSOLE;
- keymap[SDLK_DELETE] = PEEK_LEFT;
- keymap[SDLK_END] = PEEK_RIGHT;
-
- jump_with_up = false;
-
- int joystick_count = SDL_NumJoysticks();
- min_joybuttons = -1;
- max_joybuttons = -1;
- max_joyaxis = -1;
- max_joyhats = -1;
-
- for(int i = 0; i < joystick_count; ++i) {
- SDL_Joystick* joystick = SDL_JoystickOpen(i);
- bool good = true;
- if(SDL_JoystickNumButtons(joystick) < 2) {
- log_info << "Joystick " << i << " has less than 2 buttons" << std::endl;
- good = false;
- }
- if(SDL_JoystickNumAxes(joystick) < 2
- && SDL_JoystickNumHats(joystick) == 0) {
- log_info << "Joystick " << i << " has less than 2 axes and no hat" << std::endl;
- good = false;
- }
- if(!good) {
- SDL_JoystickClose(joystick);
- continue;
- }
-
- if(min_joybuttons < 0 || SDL_JoystickNumButtons(joystick) < min_joybuttons)
- min_joybuttons = SDL_JoystickNumButtons(joystick);
-
- if(SDL_JoystickNumButtons(joystick) > max_joybuttons)
- max_joybuttons = SDL_JoystickNumButtons(joystick);
-
- if(SDL_JoystickNumAxes(joystick) > max_joyaxis)
- max_joyaxis = SDL_JoystickNumAxes(joystick);
-
- if(SDL_JoystickNumHats(joystick) > max_joyhats)
- max_joyhats = SDL_JoystickNumHats(joystick);
-
- joysticks.push_back(joystick);
- }
-
- dead_zone = 1000;
-
- // Default joystick button configuration
- joy_button_map[0] = JUMP;
- joy_button_map[1] = ACTION;
- // 6 or more Buttons
- if( min_joybuttons > 5 ){
- joy_button_map[4] = PEEK_LEFT;
- joy_button_map[5] = PEEK_RIGHT;
- // 8 or more
- if(min_joybuttons > 7)
- joy_button_map[min_joybuttons-1] = PAUSE_MENU;
- } else {
- // map the last 2 buttons to menu and pause
- if(min_joybuttons > 2)
- joy_button_map[min_joybuttons-1] = PAUSE_MENU;
- // map all remaining joystick buttons to MENU_SELECT
- for(int i = 2; i < max_joybuttons; ++i) {
- if(i != min_joybuttons-1)
- joy_button_map[i] = MENU_SELECT;
- }
- }
-
- // Default joystick axis configuration
- joy_axis_map[-1] = LEFT;
- joy_axis_map[ 1] = RIGHT;
- joy_axis_map[-2] = UP;
- joy_axis_map[ 2] = DOWN;
-
- // some joysticks or SDL seem to produce some bogus events after being opened
- Uint32 ticks = SDL_GetTicks();
- while(SDL_GetTicks() - ticks < 200) {
- SDL_Event event;
- SDL_PollEvent(&event);
- }
-}
-
-JoystickKeyboardController::~JoystickKeyboardController()
-{
- for(std::vector<SDL_Joystick*>::iterator i = joysticks.begin();
- i != joysticks.end(); ++i) {
- if(*i != 0)
- SDL_JoystickClose(*i);
- }
-
- delete key_options_menu;
- delete joystick_options_menu;
-}
-
-void
-JoystickKeyboardController::read(const lisp::Lisp& lisp)
-{
- const lisp::Lisp* keymap_lisp = lisp.get_lisp("keymap");
- if(keymap_lisp) {
- keymap.clear();
- lisp::ListIterator iter(keymap_lisp);
- while(iter.next()) {
- if(iter.item() == "map") {
- int key = -1;
- std::string control;
- const lisp::Lisp* map = iter.lisp();
- map->get("key", key);
- map->get("control", control);
- if(key < SDLK_FIRST || key >= SDLK_LAST) {
- log_info << "Invalid key '" << key << "' in keymap" << std::endl;
- continue;
- }
-
- int i = 0;
- for(i = 0; controlNames[i] != 0; ++i) {
- if(control == controlNames[i])
- break;
- }
- if(controlNames[i] == 0) {
- log_info << "Invalid control '" << control << "' in keymap" << std::endl;
- continue;
- }
- keymap[(SDLKey) key] = (Control)i;
- } else {
- log_info << "Invalid lisp element '" << iter.item() << "' in keymap" << std::endl;
- }
- }
- }
-
- const lisp::Lisp* joystick_lisp = lisp.get_lisp("joystick");
- if(joystick_lisp) {
- joystick_lisp->get("dead-zone", dead_zone);
- joystick_lisp->get("jump-with-up", jump_with_up);
- lisp::ListIterator iter(joystick_lisp);
- while(iter.next()) {
- if(iter.item() == "map") {
- int button = -1;
- int axis = 0;
- int hat = -1;
- std::string control;
- const lisp::Lisp* map = iter.lisp();
-
- map->get("control", control);
- int i = 0;
- for(i = 0; controlNames[i] != 0; ++i) {
- if(control == controlNames[i])
- break;
- }
- if(controlNames[i] == 0) {
- log_info << "Invalid control '" << control << "' in buttonmap" << std::endl;
- continue;
- }
-
- if (map->get("button", button)) {
- if(button < 0 || button >= max_joybuttons) {
- log_info << "Invalid button '" << button << "' in buttonmap" << std::endl;
- continue;
- }
- bind_joybutton(button, (Control) i);
- }
-
- if (map->get("axis", axis)) {
- if (axis == 0 || abs(axis) > max_joyaxis) {
- log_info << "Invalid axis '" << axis << "' in axismap" << std::endl;
- continue;
- }
- bind_joyaxis(axis, (Control) i);
- }
-
- if (map->get("hat", hat)) {
- if (hat != SDL_HAT_UP &&
- hat != SDL_HAT_DOWN &&
- hat != SDL_HAT_LEFT &&
- hat != SDL_HAT_RIGHT) {
- log_info << "Invalid axis '" << axis << "' in axismap" << std::endl;
- continue;
- } else {
- bind_joyhat(hat, (Control) i);
- }
- }
- }
- }
- }
-}
-
-void
-JoystickKeyboardController::write(lisp::Writer& writer)
-{
- writer.start_list("keymap");
- for(KeyMap::iterator i = keymap.begin(); i != keymap.end(); ++i) {
- writer.start_list("map");
- writer.write_int("key", (int) i->first);
- writer.write_string("control", controlNames[i->second]);
- writer.end_list("map");
- }
- writer.end_list("keymap");
-
- writer.start_list("joystick");
- writer.write_int("dead-zone", dead_zone);
- writer.write_bool("jump-with-up", jump_with_up);
-
- for(ButtonMap::iterator i = joy_button_map.begin(); i != joy_button_map.end();
- ++i) {
- writer.start_list("map");
- writer.write_int("button", i->first);
- writer.write_string("control", controlNames[i->second]);
- writer.end_list("map");
- }
-
- for(HatMap::iterator i = joy_hat_map.begin(); i != joy_hat_map.end(); ++i) {
- writer.start_list("map");
- writer.write_int("hat", i->first);
- writer.write_string("control", controlNames[i->second]);
- writer.end_list("map");
- }
-
- for(AxisMap::iterator i = joy_axis_map.begin(); i != joy_axis_map.end(); ++i) {
- writer.start_list("map");
- writer.write_int("axis", i->first);
- writer.write_string("control", controlNames[i->second]);
- writer.end_list("map");
- }
-
- writer.end_list("joystick");
-}
-
-void
-JoystickKeyboardController::reset()
-{
- Controller::reset();
-}
-
-void
-JoystickKeyboardController::set_joy_controls(Control id, bool value)
-{
- if (jump_with_up && id == Controller::UP)
- controls[Controller::JUMP] = value;
-
- controls[(Control)id] = value;
-}
-
-void
-JoystickKeyboardController::process_event(const SDL_Event& event)
-{
- switch(event.type) {
- case SDL_KEYUP:
- case SDL_KEYDOWN:
- process_key_event(event);
- break;
-
- case SDL_JOYAXISMOTION:
- process_axis_event(event.jaxis);
- break;
-
- case SDL_JOYHATMOTION:
- process_hat_event(event.jhat);
- break;
-
- case SDL_JOYBUTTONDOWN:
- case SDL_JOYBUTTONUP:
- process_button_event(event.jbutton);
- break;
-
- default:
- break;
- }
-}
-
-void
-JoystickKeyboardController::process_button_event(const SDL_JoyButtonEvent& jbutton)
-{
- if(wait_for_joystick >= 0)
- {
- if(jbutton.state == SDL_PRESSED)
- {
- bind_joybutton(jbutton.button, (Control)wait_for_joystick);
- joystick_options_menu->update();
- reset();
- wait_for_joystick = -1;
- }
- }
- else
- {
- ButtonMap::iterator i = joy_button_map.find(jbutton.button);
- if(i == joy_button_map.end()) {
- log_debug << "Unmapped joybutton " << (int)jbutton.button << " pressed" << std::endl;
- } else {
- set_joy_controls(i->second, (jbutton.state == SDL_PRESSED));
- }
- }
-}
-
-void
-JoystickKeyboardController::process_axis_event(const SDL_JoyAxisEvent& jaxis)
-{
- if (wait_for_joystick >= 0)
- {
- if (abs(jaxis.value) > dead_zone) {
- if (jaxis.value < 0)
- bind_joyaxis(-(jaxis.axis + 1), Control(wait_for_joystick));
- else
- bind_joyaxis(jaxis.axis + 1, Control(wait_for_joystick));
-
- joystick_options_menu->update();
- wait_for_joystick = -1;
- }
- }
- else
- {
- // Split the axis into left and right, so that both can be
- // mapped seperatly (needed for jump/down vs up/down)
- int axis = jaxis.axis + 1;
-
- AxisMap::iterator left = joy_axis_map.find(-axis);
- AxisMap::iterator right = joy_axis_map.find(axis);
-
- if(left == joy_axis_map.end()) {
- std::cout << "Unmapped joyaxis " << (int)jaxis.axis << " moved" << std::endl;
- } else {
- if (jaxis.value < -dead_zone)
- set_joy_controls(left->second, true);
- else if (jaxis.value > dead_zone)
- set_joy_controls(left->second, false);
- else
- set_joy_controls(left->second, false);
- }
-
- if(right == joy_axis_map.end()) {
- std::cout << "Unmapped joyaxis " << (int)jaxis.axis << " moved" << std::endl;
- } else {
- if (jaxis.value < -dead_zone)
- set_joy_controls(right->second, false);
- else if (jaxis.value > dead_zone)
- set_joy_controls(right->second, true);
- else
- set_joy_controls(right->second, false);
- }
- }
-}
-
-void
-JoystickKeyboardController::process_hat_event(const SDL_JoyHatEvent& jhat)
-{
- Uint8 changed = hat_state ^ jhat.value;
-
- if (wait_for_joystick >= 0)
- {
- if (changed & SDL_HAT_UP && jhat.value & SDL_HAT_UP)
- bind_joyhat(SDL_HAT_UP, (Control)wait_for_joystick);
-
- if (changed & SDL_HAT_DOWN && jhat.value & SDL_HAT_DOWN)
- bind_joyhat(SDL_HAT_DOWN, (Control)wait_for_joystick);
-
- if (changed & SDL_HAT_LEFT && jhat.value & SDL_HAT_LEFT)
- bind_joyhat(SDL_HAT_LEFT, (Control)wait_for_joystick);
-
- if (changed & SDL_HAT_RIGHT && jhat.value & SDL_HAT_RIGHT)
- bind_joyhat(SDL_HAT_RIGHT, (Control)wait_for_joystick);
-
- joystick_options_menu->update();
- wait_for_joystick = -1;
- }
- else
- {
- if (changed & SDL_HAT_UP)
- {
- HatMap::iterator it = joy_hat_map.find(SDL_HAT_UP);
- if (it != joy_hat_map.end())
- set_joy_controls(it->second, jhat.value & SDL_HAT_UP);
- }
-
- if (changed & SDL_HAT_DOWN)
- {
- HatMap::iterator it = joy_hat_map.find(SDL_HAT_DOWN);
- if (it != joy_hat_map.end())
- set_joy_controls(it->second, jhat.value & SDL_HAT_DOWN);
- }
-
- if (changed & SDL_HAT_LEFT)
- {
- HatMap::iterator it = joy_hat_map.find(SDL_HAT_LEFT);
- if (it != joy_hat_map.end())
- set_joy_controls(it->second, jhat.value & SDL_HAT_LEFT);
- }
-
- if (changed & SDL_HAT_RIGHT)
- {
- HatMap::iterator it = joy_hat_map.find(SDL_HAT_RIGHT);
- if (it != joy_hat_map.end())
- set_joy_controls(it->second, jhat.value & SDL_HAT_RIGHT);
- }
- }
-
- hat_state = jhat.value;
-}
-
-void
-JoystickKeyboardController::process_key_event(const SDL_Event& event)
-{
- KeyMap::iterator key_mapping = keymap.find(event.key.keysym.sym);
-
- // if console key was pressed: toggle console
- if ((key_mapping != keymap.end()) && (key_mapping->second == CONSOLE)) {
- if (event.type == SDL_KEYDOWN)
- Console::instance->toggle();
- } else {
- if (Console::instance->hasFocus()) {
- // if console is open: send key there
- process_console_key_event(event);
- } else if (Menu::current()) {
- // if menu mode: send key there
- process_menu_key_event(event);
- } else if(key_mapping == keymap.end()) {
- // default action: update controls
- log_debug << "Key " << event.key.keysym.sym << " is unbound" << std::endl;
- } else {
- Control control = key_mapping->second;
- controls[control] = (event.type == SDL_KEYDOWN);
- }
- }
-}
-
-void
-JoystickKeyboardController::process_console_key_event(const SDL_Event& event)
-{
- if (event.type != SDL_KEYDOWN) return;
-
- switch (event.key.keysym.sym) {
- case SDLK_RETURN:
- Console::instance->enter();
- break;
- case SDLK_BACKSPACE:
- Console::instance->backspace();
- break;
- case SDLK_TAB:
- Console::instance->autocomplete();
- break;
- case SDLK_PAGEUP:
- Console::instance->scroll(-1);
- break;
- case SDLK_PAGEDOWN:
- Console::instance->scroll(+1);
- break;
- case SDLK_HOME:
- Console::instance->move_cursor(-65535);
- break;
- case SDLK_END:
- Console::instance->move_cursor(+65535);
- break;
- case SDLK_UP:
- Console::instance->show_history(-1);
- break;
- case SDLK_DOWN:
- Console::instance->show_history(+1);
- break;
- case SDLK_LEFT:
- Console::instance->move_cursor(-1);
- break;
- case SDLK_RIGHT:
- Console::instance->move_cursor(+1);
- break;
- default:
- int c = event.key.keysym.unicode;
- if ((c >= 32) && (c <= 126)) {
- Console::instance->input((char)c);
- }
- break;
- }
-}
-
-void
-JoystickKeyboardController::process_menu_key_event(const SDL_Event& event)
-{
- // wait for key mode?
- if(wait_for_key >= 0) {
- if(event.type == SDL_KEYUP)
- return;
-
- if(event.key.keysym.sym != SDLK_ESCAPE
- && event.key.keysym.sym != SDLK_PAUSE) {
- bind_key(event.key.keysym.sym, (Control) wait_for_key);
- }
- reset();
- key_options_menu->update();
- wait_for_key = -1;
- return;
- }
- if(wait_for_joystick >= 0) {
- if(event.key.keysym.sym == SDLK_ESCAPE) {
- reset();
- joystick_options_menu->update();
- wait_for_joystick = -1;
- }
- return;
- }
-
- Control control;
- /* we use default keys when the menu is open (to avoid problems when
- * redefining keys to invalid settings
- */
- switch(event.key.keysym.sym) {
- case SDLK_UP:
- control = UP;
- break;
- case SDLK_DOWN:
- control = DOWN;
- break;
- case SDLK_LEFT:
- control = LEFT;
- break;
- case SDLK_RIGHT:
- control = RIGHT;
- break;
- case SDLK_SPACE:
- case SDLK_RETURN:
- case SDLK_KP_ENTER:
- control = MENU_SELECT;
- break;
- case SDLK_ESCAPE:
- case SDLK_PAUSE:
- control = PAUSE_MENU;
- break;
- default:
- return;
- break;
- }
-
- controls[control] = (event.type == SDL_KEYDOWN);
-}
-
-void
-JoystickKeyboardController::unbind_joystick_control(Control control)
-{
- // remove all previous mappings for that control
- for(AxisMap::iterator i = joy_axis_map.begin(); i != joy_axis_map.end(); /* no ++i */) {
- if(i->second == control)
- joy_axis_map.erase(i++);
- else
- ++i;
- }
-
- for(ButtonMap::iterator i = joy_button_map.begin(); i != joy_button_map.end(); /* no ++i */) {
- if(i->second == control)
- joy_button_map.erase(i++);
- else
- ++i;
- }
-
- for(HatMap::iterator i = joy_hat_map.begin(); i != joy_hat_map.end(); /* no ++i */) {
- if(i->second == control)
- joy_hat_map.erase(i++);
- else
- ++i;
- }
-}
-
-void
-JoystickKeyboardController::bind_joyaxis(int axis, Control control)
-{
- // axis isn't the SDL axis number, but axisnumber + 1 with sign
- // changed depending on if the positive or negative end is to be
- // used (negative axis 0 becomes -1, positive axis 2 becomes +3,
- // etc.)
-
- unbind_joystick_control(control);
-
- // add new mapping
- joy_axis_map[axis] = control;
-}
-
-void
-JoystickKeyboardController::bind_joyhat(int dir, Control c)
-{
- unbind_joystick_control(c);
-
- // add new mapping
- joy_hat_map[dir] = c;
-}
-
-void
-JoystickKeyboardController::bind_joybutton(int button, Control control)
-{
- unbind_joystick_control(control);
-
- // add new mapping
- joy_button_map[button] = control;
-}
-
-void
-JoystickKeyboardController::bind_key(SDLKey key, Control control)
-{
- // remove all previous mappings for that control and for that key
- for(KeyMap::iterator i = keymap.begin();
- i != keymap.end(); /* no ++i */) {
- if(i->second == control) {
- KeyMap::iterator e = i;
- ++i;
- keymap.erase(e);
- } else {
- ++i;
- }
- }
-
- KeyMap::iterator i = keymap.find(key);
- if(i != keymap.end())
- keymap.erase(i);
-
- // add new mapping
- keymap[key]= control;
-}
-
-void
-JoystickKeyboardController::print_joystick_mappings()
-{
- std::cout << "Joystick Mappings" << std::endl;
- std::cout << "-----------------" << std::endl;
- for(AxisMap::iterator i = joy_axis_map.begin(); i != joy_axis_map.end(); ++i) {
- std::cout << "Axis: " << i->first << " -> " << i->second << std::endl;
- }
-
- for(ButtonMap::iterator i = joy_button_map.begin(); i != joy_button_map.end(); ++i) {
- std::cout << "Button: " << i->first << " -> " << i->second << std::endl;
- }
-
- for(HatMap::iterator i = joy_hat_map.begin(); i != joy_hat_map.end(); ++i) {
- std::cout << "Hat: " << i->first << " -> " << i->second << std::endl;
- }
- std::cout << std::endl;
-}
-
-SDLKey
-JoystickKeyboardController::reversemap_key(Control c)
-{
- for(KeyMap::iterator i = keymap.begin(); i != keymap.end(); ++i) {
- if(i->second == c)
- return i->first;
- }
-
- return SDLK_UNKNOWN;
-}
-
-int
-JoystickKeyboardController::reversemap_joyaxis(Control c)
-{
- for(AxisMap::iterator i = joy_axis_map.begin(); i != joy_axis_map.end(); ++i) {
- if(i->second == c)
- return i->first;
- }
-
- return 0;
-}
-
-int
-JoystickKeyboardController::reversemap_joybutton(Control c)
-{
- for(ButtonMap::iterator i = joy_button_map.begin(); i != joy_button_map.end(); ++i) {
- if(i->second == c)
- return i->first;
- }
-
- return -1;
-}
-
-int
-JoystickKeyboardController::reversemap_joyhat(Control c)
-{
- for(HatMap::iterator i = joy_hat_map.begin(); i != joy_hat_map.end(); ++i) {
- if(i->second == c)
- return i->first;
- }
-
- return -1;
-}
-
-Menu*
-JoystickKeyboardController::get_key_options_menu()
-{
- if(key_options_menu == 0) {
- key_options_menu = new KeyboardMenu(this);
- }
-
- return key_options_menu;
-}
-
-Menu*
-JoystickKeyboardController::get_joystick_options_menu()
-{
- if(joystick_options_menu == 0) {
- joystick_options_menu = new JoystickMenu(this);
- }
-
- return joystick_options_menu;
-}
-
-//----------------------------------------------------------------------------
-
-JoystickKeyboardController::KeyboardMenu::KeyboardMenu(
- JoystickKeyboardController* _controller)
- : controller(_controller)
-{
- add_label(_("Setup Keyboard"));
- add_hl();
- add_controlfield(Controller::UP, _("Up"));
- add_controlfield(Controller::DOWN, _("Down"));
- add_controlfield(Controller::LEFT, _("Left"));
- add_controlfield(Controller::RIGHT, _("Right"));
- add_controlfield(Controller::JUMP, _("Jump"));
- add_controlfield(Controller::ACTION, _("Action"));
- add_controlfield(Controller::PEEK_LEFT, _("Peek Left"));
- add_controlfield(Controller::PEEK_RIGHT, _("Peek Right"));
- if (config->console_enabled) {
- add_controlfield(Controller::CONSOLE, _("Console"));
- }
- add_hl();
- add_back(_("Back"));
- update();
-}
-
-JoystickKeyboardController::KeyboardMenu::~KeyboardMenu()
-{}
-
-std::string
-JoystickKeyboardController::KeyboardMenu::get_key_name(SDLKey key)
-{
- switch(key) {
- case SDLK_UNKNOWN:
- return _("None");
- case SDLK_UP:
- return _("Up cursor");
- case SDLK_DOWN:
- return _("Down cursor");
- case SDLK_LEFT:
- return _("Left cursor");
- case SDLK_RIGHT:
- return _("Right cursor");
- case SDLK_RETURN:
- return _("Return");
- case SDLK_SPACE:
- return _("Space");
- case SDLK_RSHIFT:
- return _("Right Shift");
- case SDLK_LSHIFT:
- return _("Left Shift");
- case SDLK_RCTRL:
- return _("Right Control");
- case SDLK_LCTRL:
- return _("Left Control");
- case SDLK_RALT:
- return _("Right Alt");
- case SDLK_LALT:
- return _("Left Alt");
- default:
- return SDL_GetKeyName((SDLKey) key);
- }
-}
-
-void
-JoystickKeyboardController::KeyboardMenu::menu_action(MenuItem* item)
-{
- assert(item->id >= 0 && item->id < Controller::CONTROLCOUNT);
- item->change_input(_("Press Key"));
- controller->wait_for_key = item->id;
-}
-
-void
-JoystickKeyboardController::KeyboardMenu::update()
-{
- // update menu
- get_item_by_id((int) Controller::UP).change_input(get_key_name(
- controller->reversemap_key(Controller::UP)));
- get_item_by_id((int) Controller::DOWN).change_input(get_key_name(
- controller->reversemap_key(Controller::DOWN)));
- get_item_by_id((int) Controller::LEFT).change_input(get_key_name(
- controller->reversemap_key(Controller::LEFT)));
- get_item_by_id((int) Controller::RIGHT).change_input(get_key_name(
- controller->reversemap_key(Controller::RIGHT)));
- get_item_by_id((int) Controller::JUMP).change_input(get_key_name(
- controller->reversemap_key(Controller::JUMP)));
- get_item_by_id((int) Controller::ACTION).change_input(get_key_name(
- controller->reversemap_key(Controller::ACTION)));
- get_item_by_id((int) Controller::PEEK_LEFT).change_input(get_key_name(
- controller->reversemap_key(Controller::PEEK_LEFT)));
- get_item_by_id((int) Controller::PEEK_RIGHT).change_input(get_key_name(
- controller->reversemap_key(Controller::PEEK_RIGHT)));
- if (config->console_enabled) {
- get_item_by_id((int) Controller::CONSOLE).change_input(get_key_name(
- controller->reversemap_key(Controller::CONSOLE)));
- }
-}
-
-//---------------------------------------------------------------------------
-
-JoystickKeyboardController::JoystickMenu::JoystickMenu(
- JoystickKeyboardController* _controller)
- : controller(_controller)
-{
- add_label(_("Setup Joystick"));
- add_hl();
- if(controller->joysticks.size() > 0) {
- add_controlfield(Controller::UP, _("Up"));
- add_controlfield(Controller::DOWN, _("Down"));
- add_controlfield(Controller::LEFT, _("Left"));
- add_controlfield(Controller::RIGHT, _("Right"));
- add_controlfield(Controller::JUMP, _("Jump"));
- add_controlfield(Controller::ACTION, _("Action"));
- add_controlfield(Controller::PAUSE_MENU, _("Pause/Menu"));
- add_controlfield(Controller::PEEK_LEFT, _("Peek Left"));
- add_controlfield(Controller::PEEK_RIGHT, _("Peek Right"));
-
- add_toggle(Controller::CONTROLCOUNT, _("Jump with Up"), controller->jump_with_up);
- } else {
- add_deactive(-1, _("No Joysticks found"));
- }
- add_hl();
- add_back(_("Back"));
- update();
-}
-
-JoystickKeyboardController::JoystickMenu::~JoystickMenu()
-{}
-
-std::string
-JoystickKeyboardController::JoystickMenu::get_button_name(int button)
-{
- if(button < 0)
- return _("None");
-
- std::ostringstream name;
- name << "Button " << button;
- return name.str();
-}
-
-void
-JoystickKeyboardController::JoystickMenu::menu_action(MenuItem* item)
-{
- if (item->id >= 0 && item->id < Controller::CONTROLCOUNT) {
- item->change_input(_("Press Button"));
- controller->wait_for_joystick = item->id;
- } else if (item->id == Controller::CONTROLCOUNT) {
- controller->jump_with_up = item->toggled;
- }
-}
-
-void
-JoystickKeyboardController::JoystickMenu::update_menu_item(Control id)
-{
- int button = controller->reversemap_joybutton(id);
- int axis = controller->reversemap_joyaxis(id);
- int hat_dir = controller->reversemap_joyhat(id);
-
- if (button != -1) {
- get_item_by_id((int)id).change_input(get_button_name(button));
- } else if (axis != 0) {
- std::ostringstream name;
-
- name << "Axis ";
-
- if (axis < 0)
- name << "-";
- else
- name << "+";
-
- if (abs(axis) == 1)
- name << "X";
- else if (abs(axis) == 2)
- name << "Y";
- else if (abs(axis) == 2)
- name << "X2";
- else if (abs(axis) == 3)
- name << "Y2";
- else
- name << abs(axis);
-
- get_item_by_id((int)id).change_input(name.str());
- } else if (hat_dir != -1) {
- std::string name;
-
- switch (hat_dir)
- {
- case SDL_HAT_UP:
- name = "Hat Up";
- break;
-
- case SDL_HAT_DOWN:
- name = "Hat Down";
- break;
-
- case SDL_HAT_LEFT:
- name = "Hat Left";
- break;
-
- case SDL_HAT_RIGHT:
- name = "Hat Right";
- break;
-
- default:
- name = "Unknown hat_dir";
- break;
- }
-
- get_item_by_id((int)id).change_input(name);
- } else {
- get_item_by_id((int)id).change_input("None");
- }
-}
-
-void
-JoystickKeyboardController::JoystickMenu::update()
-{
- if(controller->joysticks.size() == 0)
- return;
-
- update_menu_item(Controller::UP);
- update_menu_item(Controller::DOWN);
- update_menu_item(Controller::LEFT);
- update_menu_item(Controller::RIGHT);
-
- update_menu_item(Controller::JUMP);
- update_menu_item(Controller::ACTION);
- update_menu_item(Controller::PAUSE_MENU);
- update_menu_item(Controller::PEEK_LEFT);
- update_menu_item(Controller::PEEK_RIGHT);
-
- get_item_by_id(Controller::CONTROLCOUNT).toggled = controller->jump_with_up;
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __JOYSTICKKEYBOARDCONTROLLER_H__
-#define __JOYSTICKKEYBOARDCONTROLLER_H__
-
-#include "controller.hpp"
-#include "lisp/lisp.hpp"
-#include "lisp/writer.hpp"
-#include <SDL.h>
-#include <string>
-#include <map>
-
-class Menu;
-
-class JoystickKeyboardController : public Controller
-{
-public:
- JoystickKeyboardController();
- virtual ~JoystickKeyboardController();
-
- /** Process an SDL Event and return true if the event has been used
- */
- void process_event(const SDL_Event& event);
-
- void write(lisp::Writer& writer);
- void read(const lisp::Lisp& lisp);
- void reset();
-
- Menu* get_key_options_menu();
- Menu* get_joystick_options_menu();
-
-private:
- void process_key_event(const SDL_Event& event);
- void process_hat_event(const SDL_JoyHatEvent& jhat);
- void process_axis_event(const SDL_JoyAxisEvent& jaxis);
- void process_button_event(const SDL_JoyButtonEvent& jbutton);
- void process_console_key_event(const SDL_Event& event);
- void process_menu_key_event(const SDL_Event& event);
-
- void print_joystick_mappings();
-
- typedef std::map<SDLKey, Control> KeyMap;
- KeyMap keymap;
-
- typedef std::map<int, Control> ButtonMap;
- ButtonMap joy_button_map;
-
- typedef std::map<int, Control> AxisMap;
- AxisMap joy_axis_map;
-
- typedef std::map<int, Control> HatMap;
- HatMap joy_hat_map;
-
- std::vector<SDL_Joystick*> joysticks;
-
- std::string name;
-
- int dead_zone;
- /// the number of buttons all joysticks have
- int min_joybuttons;
- /// the max number of buttons a joystick has
- int max_joybuttons;
-
- int max_joyaxis;
-
- int max_joyhats;
-
- Uint8 hat_state;
-
- bool jump_with_up;
-
- SDLKey reversemap_key(Control c);
- int reversemap_joybutton(Control c);
- int reversemap_joyaxis(Control c);
- int reversemap_joyhat(Control c);
-
- void unbind_joystick_control(Control c);
-
- void bind_joybutton(int button, Control c);
- void bind_joyaxis(int axis, Control c);
- void bind_joyhat(int dir, Control c);
- void bind_key(SDLKey key, Control c);
-
- void set_joy_controls(Control id, bool value);
-
- int wait_for_key;
- int wait_for_joystick;
-
- class KeyboardMenu;
- class JoystickMenu;
-
- KeyboardMenu* key_options_menu;
- JoystickMenu* joystick_options_menu;
- friend class KeyboardMenu;
- friend class JoystickMenu;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#ifndef SUPERTUX_DIRECTION_H
-#define SUPERTUX_DIRECTION_H
-
-enum Direction { AUTO, LEFT, RIGHT, UP, DOWN };
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#include <config.h>
-
-#include "fadeout.hpp"
-#include "main.hpp"
-#include "video/drawing_context.hpp"
-
-FadeOut::FadeOut(float fade_time, Color color)
- : color(color), fade_time(fade_time), accum_time(0)
-{
-}
-
-FadeOut::~FadeOut()
-{
-}
-
-void
-FadeOut::update(float elapsed_time)
-{
- accum_time += elapsed_time;
- if(accum_time > fade_time)
- accum_time = fade_time;
-}
-
-void
-FadeOut::draw(DrawingContext& context)
-{
- Color col = color;
- col.alpha = accum_time / fade_time;
- context.draw_filled_rect(Vector(0, 0),
- Vector(SCREEN_WIDTH, SCREEN_HEIGHT),
- col, LAYER_GUI+1);
-}
-
-bool
-FadeOut::done()
-{
- return accum_time >= fade_time;
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#ifndef __FADEOUT_HPP__
-#define __FADEOUT_HPP__
-
-#include "video/color.hpp"
-#include "screen_fade.hpp"
-
-/**
- * Fades a screen towards a specific color
- */
-class FadeOut : public ScreenFade
-{
-public:
- FadeOut(float fade_time, Color dest_color = Color(0, 0, 0));
- virtual ~FadeOut();
-
- virtual void update(float elapsed_time);
- virtual void draw(DrawingContext& context);
-
- /// returns true if the effect is completed
- virtual bool done();
-
-private:
- Color color;
- float fade_time;
- float accum_time;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include "log.hpp"
-#include "file_system.hpp"
-
-#include <string>
-#include <vector>
-#include <sstream>
-
-namespace FileSystem
-{
-
-std::string dirname(const std::string& filename)
-{
- std::string::size_type p = filename.find_last_of('/');
- if(p == std::string::npos)
- return "";
-
- return filename.substr(0, p+1);
-}
-
-std::string basename(const std::string& filename)
-{
- std::string::size_type p = filename.find_last_of('/');
- if(p == std::string::npos)
- return filename;
-
- return filename.substr(p+1, filename.size()-p-1);
-}
-
-std::string strip_extension(const std::string& filename)
-{
- std::string::size_type p = filename.find_last_of('.');
- if(p == std::string::npos)
- return filename;
-
- return filename.substr(0, p);
-}
-
-std::string normalize(const std::string& filename)
-{
- std::vector<std::string> path_stack;
-
- const char* p = filename.c_str();
-
- while(true) {
- while(*p == '/') {
- p++;
- continue;
- }
-
- const char* pstart = p;
- while(*p != '/' && *p != 0) {
- ++p;
- }
-
- size_t len = p - pstart;
- if(len == 0)
- break;
-
- std::string pathelem(pstart, p-pstart);
- if(pathelem == ".")
- continue;
-
- if(pathelem == "..") {
- if(path_stack.empty()) {
-
- log_warning << "Invalid '..' in path '" << filename << "'" << std::endl;
- // push it into the result path so that the users sees his error...
- path_stack.push_back(pathelem);
- } else {
- path_stack.pop_back();
- }
- } else {
- path_stack.push_back(pathelem);
- }
- }
-
- // construct path
- std::ostringstream result;
- for(std::vector<std::string>::iterator i = path_stack.begin();
- i != path_stack.end(); ++i) {
- result << '/' << *i;
- }
- if(path_stack.empty())
- result << '/';
-
- return result.str();
-}
-
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __FILESYSTEM_H__
-#define __FILESYSTEM_H__
-
-#include <set>
-#include <string>
-
-namespace FileSystem
-{
- std::string dirname(const std::string& filename);
- std::string basename(const std::string& filename);
-
- /**
- * remove everything starting from and including the last dot
- */
- std::string strip_extension(const std::string& filename);
-
- /**
- * normalize filename so that "blup/bla/blo/../../bar" will become
- * "blup/bar"
- */
- std::string normalize(const std::string& filename);
-}
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#include <config.h>
-
-#include "flip_level_transformer.hpp"
-#include "object/tilemap.hpp"
-#include "object/camera.hpp"
-#include "badguy/badguy.hpp"
-#include "sector.hpp"
-#include "tile_manager.hpp"
-#include "spawn_point.hpp"
-#include "object/platform.hpp"
-#include "object/block.hpp"
-
-void
-FlipLevelTransformer::transform_sector(Sector* sector)
-{
- float height = sector->get_height();
-
- for(Sector::GameObjects::iterator i = sector->gameobjects.begin();
- i != sector->gameobjects.end(); ++i) {
- GameObject* object = *i;
-
- TileMap* tilemap = dynamic_cast<TileMap*> (object);
- if(tilemap) {
- transform_tilemap(tilemap);
- }
- Player* player = dynamic_cast<Player*> (object);
- if(player) {
- Vector pos = player->get_pos();
- pos.y = height - pos.y - player->get_bbox().get_height();
- player->move(pos);
- continue;
- }
- BadGuy* badguy = dynamic_cast<BadGuy*> (object);
- if(badguy) {
- transform_badguy(height, badguy);
- }
- Platform* platform = dynamic_cast<Platform*> (object);
- if(platform) {
- transform_platform(height, *platform);
- }
- Block* block = dynamic_cast<Block*> (object);
- if(block) {
- transform_block(height, *block);
- }
- MovingObject* mobject = dynamic_cast<MovingObject*> (object);
- if(mobject) {
- transform_moving_object(height, mobject);
- }
- }
- for(Sector::SpawnPoints::iterator i = sector->spawnpoints.begin();
- i != sector->spawnpoints.end(); ++i) {
- transform_spawnpoint(height, *i);
- }
-
- if(sector->camera != 0 && sector->player != 0)
- sector->camera->reset(sector->player->get_pos());
-}
-
-void
-FlipLevelTransformer::transform_tilemap(TileMap* tilemap)
-{
- for(size_t x = 0; x < tilemap->get_width(); ++x) {
- for(size_t y = 0; y < tilemap->get_height()/2; ++y) {
- // swap tiles
- int y2 = tilemap->get_height()-1-y;
- const Tile* t1 = tilemap->get_tile(x, y);
- const Tile* t2 = tilemap->get_tile(x, y2);
- tilemap->change(x, y, t2->getID());
- tilemap->change(x, y2, t1->getID());
- }
- }
- if(tilemap->get_drawing_effect() != 0) {
- tilemap->set_drawing_effect(NO_EFFECT);
- } else {
- tilemap->set_drawing_effect(VERTICAL_FLIP);
- }
-}
-
-void
-FlipLevelTransformer::transform_badguy(float height, BadGuy* badguy)
-{
- Vector pos = badguy->get_start_position();
- pos.y = height - pos.y;
- badguy->set_start_position(pos);
-}
-
-void
-FlipLevelTransformer::transform_spawnpoint(float height, SpawnPoint* spawn)
-{
- Vector pos = spawn->pos;
- pos.y = height - pos.y;
- spawn->pos = pos;
-}
-
-void
-FlipLevelTransformer::transform_moving_object(float height, MovingObject*object)
-{
- Vector pos = object->get_pos();
- pos.y = height - pos.y - object->get_bbox().get_height();
- object->set_pos(pos);
-}
-
-void
-FlipLevelTransformer::transform_platform(float height, Platform& platform)
-{
- Path& path = platform.get_path();
- for (std::vector<Path::Node>::iterator i = path.nodes.begin(); i != path.nodes.end(); i++) {
- Vector& pos = i->position;
- pos.y = height - pos.y - platform.get_bbox().get_height();
- }
-}
-
-void
-FlipLevelTransformer::transform_block(float height, Block& block)
-{
- block.original_y = height - block.original_y - block.get_bbox().get_height();
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#ifndef __FLIP_LEVEL_TRANSFORMER_H__
-#define __FLIP_LEVEL_TRANSFORMER_H__
-
-#include "level_transformer.hpp"
-
-class TileMap;
-class BadGuy;
-class SpawnPoint;
-class MovingObject;
-class Platform;
-class Block;
-
-/** Vertically or horizontally flip a level */
-class FlipLevelTransformer : public LevelTransformer
-{
-public:
- virtual void transform_sector(Sector* sector);
-
-private:
- void transform_tilemap(TileMap* tilemap);
- void transform_moving_object(float height, MovingObject* object);
- void transform_badguy(float height, BadGuy* badguy);
- void transform_spawnpoint(float height, SpawnPoint* spawnpoint);
- void transform_platform(float height, Platform& platform);
- void transform_block(float height, Block& block);
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-#include "log.hpp"
-#include "game_object.hpp"
-#include "object_remove_listener.hpp"
-
-GameObject::GameObject()
- : wants_to_die(false), remove_listeners(NULL)
-{
-}
-
-GameObject::~GameObject()
-{
- // call remove listeners (and remove them from the list)
- RemoveListenerListEntry* entry = remove_listeners;
- while(entry != NULL) {
- RemoveListenerListEntry* next = entry->next;
- entry->listener->object_removed(this);
- delete entry;
- entry = next;
- }
-}
-
-
-void
-GameObject::add_remove_listener(ObjectRemoveListener* listener)
-{
- RemoveListenerListEntry* entry = new RemoveListenerListEntry();
- entry->next = remove_listeners;
- entry->listener = listener;
- remove_listeners = entry;
-}
-
-void
-GameObject::del_remove_listener(ObjectRemoveListener* listener)
-{
- RemoveListenerListEntry* entry = remove_listeners;
- if (entry->listener == listener) {
- remove_listeners = entry->next;
- delete entry;
- return;
- }
- RemoveListenerListEntry* next = entry->next;
- while(next != NULL) {
- if (next->listener == listener) {
- entry->next = next->next;
- delete next;
- break;
- }
- entry = next;
- next = next->next;
- }
-}
-
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#ifndef SUPERTUX_GAMEOBJECT_H
-#define SUPERTUX_GAMEOBJECT_H
-
-#include <string>
-#include "refcounter.hpp"
-
-class DrawingContext;
-class ObjectRemoveListener;
-
-/**
- * This is a base class for all game objects. Each sector of a level will hold a
- * list of active GameObject while the game is played.
- *
- * This class is responsible for:
- * - Updating and Drawing the object. This should happen in the update() and
- * draw() functions. Both are called once per frame.
- * - Providing a safe way to remove the object by calling the remove_me
- * functions.
- */
-class GameObject : public RefCounter
-{
-public:
- GameObject();
- virtual ~GameObject();
-
- /** This function is called once per frame and allows the object to update
- * it's state. The elapsed_time is the time since the last frame in
- * seconds and should be the base for all timed calculations (don't use
- * SDL_GetTicks directly as this will fail in pause mode)
- */
- virtual void update(float elapsed_time) = 0;
-
- /** The GameObject should draw itself onto the provided DrawingContext if this
- * function is called.
- */
- virtual void draw(DrawingContext& context) = 0;
-
- /** returns true if the object is not scheduled to be removed yet */
- bool is_valid() const
- {
- return !wants_to_die;
- }
-
- /** schedules this object to be removed at the end of the frame */
- void remove_me()
- {
- wants_to_die = true;
- }
-
- /** registers a remove listener which will be called if the object
- * gets removed/destroyed
- */
- void add_remove_listener(ObjectRemoveListener* listener);
-
- /**
- * unregisters a remove listener, so it will no longer be called if the object
- * gets removed/destroyed
- */
- void del_remove_listener(ObjectRemoveListener* listener);
-
- const std::string& get_name() const
- {
- return name;
- }
-
-private:
- /** this flag indicates if the object should be removed at the end of the
- * frame
- */
- bool wants_to_die;
-
- struct RemoveListenerListEntry
- {
- RemoveListenerListEntry* next;
- ObjectRemoveListener* listener;
- };
- RemoveListenerListEntry* remove_listeners;
-
-protected:
- /**
- * a name for the gameobject, this is mostly a hint for scripts and for
- * debugging, don't rely on names being set or being unique
- */
- std::string name;
-};
-
-#endif /*SUPERTUX_GAMEOBJECT_H*/
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#include <config.h>
-
-#include <fstream>
-#include <sstream>
-#include <assert.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <math.h>
-#include <string.h>
-#include <errno.h>
-#include <unistd.h>
-#include <time.h>
-#include <stdexcept>
-
-#include <SDL.h>
-
-#include "game_session.hpp"
-#include "log.hpp"
-#include "console.hpp"
-#include "worldmap/worldmap.hpp"
-#include "mainloop.hpp"
-#include "audio/sound_manager.hpp"
-#include "gui/menu.hpp"
-#include "sector.hpp"
-#include "level.hpp"
-#include "tile.hpp"
-#include "player_status.hpp"
-#include "object/particlesystem.hpp"
-#include "object/background.hpp"
-#include "object/gradient.hpp"
-#include "object/tilemap.hpp"
-#include "object/camera.hpp"
-#include "object/player.hpp"
-#include "object/level_time.hpp"
-#include "lisp/lisp.hpp"
-#include "lisp/parser.hpp"
-#include "resources.hpp"
-#include "statistics.hpp"
-#include "timer.hpp"
-#include "options_menu.hpp"
-#include "textscroller.hpp"
-#include "control/codecontroller.hpp"
-#include "control/joystickkeyboardcontroller.hpp"
-#include "main.hpp"
-#include "file_system.hpp"
-#include "gameconfig.hpp"
-#include "gettext.hpp"
-#include "console.hpp"
-#include "flip_level_transformer.hpp"
-#include "trigger/secretarea_trigger.hpp"
-#include "trigger/sequence_trigger.hpp"
-#include "random_generator.hpp"
-#include "scripting/squirrel_util.hpp"
-#include "object/endsequence_walkright.hpp"
-#include "object/endsequence_walkleft.hpp"
-#include "object/endsequence_fireworks.hpp"
-#include "direction.hpp"
-#include "scripting/time_scheduler.hpp"
-
-// the engine will be run with a logical framerate of 64fps.
-// We chose 64fps here because it is a power of 2, so 1/64 gives an "even"
-// binary fraction...
-static const float LOGICAL_FPS = 64.0;
-
-enum GameMenuIDs {
- MNID_CONTINUE,
- MNID_ABORTLEVEL
-};
-
-GameSession* GameSession::current_ = NULL;
-
-GameSession::GameSession(const std::string& levelfile_, Statistics* statistics)
- : level(0), currentsector(0),
- end_sequence(0),
- levelfile(levelfile_), best_level_statistics(statistics),
- capture_demo_stream(0), playback_demo_stream(0), demo_controller(0),
- play_time(0)
-{
- current_ = this;
- currentsector = NULL;
-
- game_pause = false;
- speed_before_pause = main_loop->get_speed();
-
- statistics_backdrop.reset(new Surface("images/engine/menu/score-backdrop.png"));
-
- restart_level();
-
- game_menu.reset(new Menu());
- game_menu->add_label(_("Pause"));
- game_menu->add_hl();
- game_menu->add_entry(MNID_CONTINUE, _("Continue"));
- game_menu->add_submenu(_("Options"), get_options_menu());
- game_menu->add_hl();
- game_menu->add_entry(MNID_ABORTLEVEL, _("Abort Level"));
-}
-
-void
-GameSession::restart_level()
-{
- game_pause = false;
- end_sequence = 0;
-
- main_controller->reset();
-
- currentsector = 0;
-
- level.reset(new Level);
- level->load(levelfile);
- level->stats.total_coins = level->get_total_coins();
- level->stats.total_badguys = level->get_total_badguys();
- level->stats.total_secrets = level->get_total_count<SecretAreaTrigger>();
- level->stats.reset();
- if(reset_sector != "")level->stats.declare_invalid();
-
- if(reset_sector != "") {
- currentsector = level->get_sector(reset_sector);
- if(!currentsector) {
- std::stringstream msg;
- msg << "Couldn't find sector '" << reset_sector << "' for resetting tux.";
- throw std::runtime_error(msg.str());
- }
- currentsector->activate(reset_pos);
- } else {
- currentsector = level->get_sector("main");
- if(!currentsector)
- throw std::runtime_error("Couldn't find main sector");
- currentsector->activate("main");
- }
-
- //levelintro();
-
- sound_manager->stop_music();
- currentsector->play_music(LEVEL_MUSIC);
-
- if(capture_file != "") {
- int newSeed=0; // next run uses a new seed
- while (newSeed == 0) // which is the next non-zero random num.
- newSeed = systemRandom.rand();
- config->random_seed = systemRandom.srand(newSeed);
- log_info << "Next run uses random seed " <<config->random_seed <<std::endl;
- record_demo(capture_file);
- }
-}
-
-GameSession::~GameSession()
-{
- delete capture_demo_stream;
- delete playback_demo_stream;
- delete demo_controller;
- free_options_menu();
-
- current_ = NULL;
-}
-
-void
-GameSession::record_demo(const std::string& filename)
-{
- delete capture_demo_stream;
-
- capture_demo_stream = new std::ofstream(filename.c_str());
- if(!capture_demo_stream->good()) {
- std::stringstream msg;
- msg << "Couldn't open demo file '" << filename << "' for writing.";
- throw std::runtime_error(msg.str());
- }
- capture_file = filename;
-
- char buf[30]; // save the seed in the demo file
- snprintf(buf, sizeof(buf), "random_seed=%10d", config->random_seed);
- for (int i=0; i==0 || buf[i-1]; i++)
- capture_demo_stream->put(buf[i]);
-}
-
-int
-GameSession::get_demo_random_seed(const std::string& filename)
-{
- std::istream* test_stream = new std::ifstream(filename.c_str());
- if(test_stream->good()) {
- char buf[30]; // recall the seed from the demo file
- int seed;
- for (int i=0; i<30 && (i==0 || buf[i-1]); i++)
- test_stream->get(buf[i]);
- if (sscanf(buf, "random_seed=%10d", &seed) == 1) {
- log_info << "Random seed " << seed << " from demo file" << std::endl;
- return seed;
- }
- else
- log_info << "Demo file contains no random number" << std::endl;
- }
- return 0;
-}
-
-void
-GameSession::play_demo(const std::string& filename)
-{
- delete playback_demo_stream;
- delete demo_controller;
-
- playback_demo_stream = new std::ifstream(filename.c_str());
- if(!playback_demo_stream->good()) {
- std::stringstream msg;
- msg << "Couldn't open demo file '" << filename << "' for reading.";
- throw std::runtime_error(msg.str());
- }
-
- Player& tux = *currentsector->player;
- demo_controller = new CodeController();
- tux.set_controller(demo_controller);
-
- // skip over random seed, if it exists in the file
- char buf[30]; // ascii decimal seed
- int seed;
- for (int i=0; i<30 && (i==0 || buf[i-1]); i++)
- playback_demo_stream->get(buf[i]);
- if (sscanf(buf, "random_seed=%010d", &seed) != 1)
- playback_demo_stream->seekg(0); // old style w/o seed, restart at beg
-}
-
-void
-GameSession::levelintro()
-{
- sound_manager->stop_music();
-
- DrawingContext context;
- for(Sector::GameObjects::iterator i = currentsector->gameobjects.begin();
- i != currentsector->gameobjects.end(); ++i) {
- Background* background = dynamic_cast<Background*> (*i);
- if(background) {
- background->draw(context);
- }
- Gradient* gradient = dynamic_cast<Gradient*> (*i);
- if(gradient) {
- gradient->draw(context);
- }
- }
-
-// context.draw_text(gold_text, level->get_name(), Vector(SCREEN_WIDTH/2, 160),
-// ALIGN_CENTER, LAYER_FOREGROUND1);
- context.draw_center_text(gold_text, level->get_name(), Vector(0, 160),
- LAYER_FOREGROUND1);
-
- std::stringstream ss_coins;
- ss_coins << _("Coins") << ": " << player_status->coins;
- context.draw_text(white_text, ss_coins.str(), Vector(SCREEN_WIDTH/2, 210),
- ALIGN_CENTER, LAYER_FOREGROUND1);
-
- if((level->get_author().size()) && (level->get_author() != "SuperTux Team"))
- context.draw_text(white_small_text,
- std::string(_("contributed by ")) + level->get_author(),
- Vector(SCREEN_WIDTH/2, 350), ALIGN_CENTER, LAYER_FOREGROUND1);
-
- if(best_level_statistics != NULL)
- best_level_statistics->draw_message_info(context, _("Best Level Statistics"));
-
- wait_for_event(1.0, 3.0);
-}
-
-void
-GameSession::on_escape_press()
-{
- if(currentsector->player->is_dying() || end_sequence)
- {
- // Let the timers run out, we fast-forward them to force past a sequence
- if (end_sequence)
- end_sequence->stop();
-
- currentsector->player->dying_timer.start(FLT_EPSILON);
- return; // don't let the player open the menu, when he is dying
- }
-
- if(level->on_menukey_script != "") {
- std::istringstream in(level->on_menukey_script);
- run_script(in, "OnMenuKeyScript");
- } else {
- toggle_pause();
- }
-}
-
-void
-GameSession::toggle_pause()
-{
- if(!game_pause) {
- speed_before_pause = main_loop->get_speed();
- main_loop->set_speed(0);
- Menu::set_current(game_menu.get());
- game_menu->set_active_item(MNID_CONTINUE);
- game_pause = true;
- } else {
- main_loop->set_speed(speed_before_pause);
- Menu::set_current(NULL);
- game_pause = false;
- }
-}
-
-HSQUIRRELVM
-GameSession::run_script(std::istream& in, const std::string& sourcename)
-{
- using namespace Scripting;
-
- // garbage collect thread list
- for(ScriptList::iterator i = scripts.begin();
- i != scripts.end(); ) {
- HSQOBJECT& object = *i;
- HSQUIRRELVM vm = object_to_vm(object);
-
- if(sq_getvmstate(vm) != SQ_VMSTATE_SUSPENDED) {
- sq_release(global_vm, &object);
- i = scripts.erase(i);
- continue;
- }
-
- ++i;
- }
-
- HSQOBJECT object = create_thread(global_vm);
- scripts.push_back(object);
-
- HSQUIRRELVM vm = object_to_vm(object);
-
- compile_and_run(vm, in, sourcename);
-
- return vm;
-}
-
-void
-GameSession::process_events()
-{
- // end of pause mode?
- if(!Menu::current() && game_pause) {
- game_pause = false;
- }
-
- // playback a demo?
- if(playback_demo_stream != 0) {
- demo_controller->update();
- char left = false;
- char right = false;
- char up = false;
- char down = false;
- char jump = false;
- char action = false;
- playback_demo_stream->get(left);
- playback_demo_stream->get(right);
- playback_demo_stream->get(up);
- playback_demo_stream->get(down);
- playback_demo_stream->get(jump);
- playback_demo_stream->get(action);
- demo_controller->press(Controller::LEFT, left);
- demo_controller->press(Controller::RIGHT, right);
- demo_controller->press(Controller::UP, up);
- demo_controller->press(Controller::DOWN, down);
- demo_controller->press(Controller::JUMP, jump);
- demo_controller->press(Controller::ACTION, action);
- }
-
- // save input for demo?
- if(capture_demo_stream != 0) {
- capture_demo_stream ->put(main_controller->hold(Controller::LEFT));
- capture_demo_stream ->put(main_controller->hold(Controller::RIGHT));
- capture_demo_stream ->put(main_controller->hold(Controller::UP));
- capture_demo_stream ->put(main_controller->hold(Controller::DOWN));
- capture_demo_stream ->put(main_controller->hold(Controller::JUMP));
- capture_demo_stream ->put(main_controller->hold(Controller::ACTION));
- }
-}
-
-void
-GameSession::check_end_conditions()
-{
- Player* tux = currentsector->player;
-
- /* End of level? */
- if(end_sequence && end_sequence->is_done()) {
- finish(true);
- } else if (!end_sequence && tux->is_dead()) {
- restart_level();
- }
-}
-
-void
-GameSession::draw(DrawingContext& context)
-{
- currentsector->draw(context);
- drawstatus(context);
-
- if(game_pause)
- draw_pause(context);
-}
-
-void
-GameSession::draw_pause(DrawingContext& context)
-{
- context.draw_filled_rect(
- Vector(0,0), Vector(SCREEN_WIDTH, SCREEN_HEIGHT),
- Color(.2f, .2f, .2f, .5f), LAYER_FOREGROUND1);
-}
-
-void
-GameSession::process_menu()
-{
- Menu* menu = Menu::current();
- if(menu) {
- menu->update();
-
- if(menu == game_menu.get()) {
- switch (game_menu->check()) {
- case MNID_CONTINUE:
- Menu::set_current(0);
- toggle_pause();
- break;
- case MNID_ABORTLEVEL:
- Menu::set_current(0);
- main_loop->exit_screen();
- break;
- }
- }
- }
-}
-
-void
-GameSession::setup()
-{
- Menu::set_current(NULL);
- current_ = this;
-
- if(currentsector != Sector::current()) {
- currentsector->activate(currentsector->player->get_pos());
- }
- currentsector->play_music(LEVEL_MUSIC);
-
- // Eat unneeded events
- SDL_Event event;
- while(SDL_PollEvent(&event))
- {}
-}
-
-void
-GameSession::update(float elapsed_time)
-{
- // handle controller
- if(main_controller->pressed(Controller::PAUSE_MENU))
- on_escape_press();
-
- process_events();
- process_menu();
-
- check_end_conditions();
-
- // respawning in new sector?
- if(newsector != "" && newspawnpoint != "") {
- Sector* sector = level->get_sector(newsector);
- if(sector == 0) {
- log_warning << "Sector '" << newsector << "' not found" << std::endl;
- }
- sector->activate(newspawnpoint);
- sector->play_music(LEVEL_MUSIC);
- currentsector = sector;
- newsector = "";
- newspawnpoint = "";
- }
-
- // Update the world state and all objects in the world
- if(!game_pause) {
- // Update the world
- if (!end_sequence) {
- play_time += elapsed_time; //TODO: make sure we don't count cutscene time
- level->stats.time = play_time;
- currentsector->update(elapsed_time);
- } else {
- if (!end_sequence->is_tux_stopped()) {
- currentsector->update(elapsed_time);
- } else {
- end_sequence->update(elapsed_time);
- }
- }
- }
-
- // update sounds
- sound_manager->set_listener_position(currentsector->player->get_pos());
-
- /* Handle music: */
- if (end_sequence)
- return;
-
- if(currentsector->player->invincible_timer.started()) {
- if(currentsector->player->invincible_timer.get_timeleft() <=
- TUX_INVINCIBLE_TIME_WARNING) {
- currentsector->play_music(HERRING_WARNING_MUSIC);
- } else {
- currentsector->play_music(HERRING_MUSIC);
- }
- } else if(currentsector->get_music_type() != LEVEL_MUSIC) {
- currentsector->play_music(LEVEL_MUSIC);
- }
-}
-
-void
-GameSession::finish(bool win)
-{
- using namespace WorldMapNS;
-
- if(win) {
- if(WorldMap::current())
- WorldMap::current()->finished_level(level.get());
- }
-
- main_loop->exit_screen();
-}
-
-void
-GameSession::respawn(const std::string& sector, const std::string& spawnpoint)
-{
- newsector = sector;
- newspawnpoint = spawnpoint;
-}
-
-void
-GameSession::set_reset_point(const std::string& sector, const Vector& pos)
-{
- reset_sector = sector;
- reset_pos = pos;
-}
-
-std::string
-GameSession::get_working_directory()
-{
- return FileSystem::dirname(levelfile);
-}
-
-void
-GameSession::display_info_box(const std::string& text)
-{
- InfoBox* box = new InfoBox(text);
-
- bool running = true;
- DrawingContext context;
-
- while(running) {
-
- // TODO make a screen out of this, another mainloop is ugly
- main_controller->update();
- SDL_Event event;
- while (SDL_PollEvent(&event)) {
- main_controller->process_event(event);
- if(event.type == SDL_QUIT)
- main_loop->quit();
- }
-
- if(main_controller->pressed(Controller::JUMP)
- || main_controller->pressed(Controller::ACTION)
- || main_controller->pressed(Controller::PAUSE_MENU)
- || main_controller->pressed(Controller::MENU_SELECT))
- running = false;
- else if(main_controller->pressed(Controller::DOWN))
- box->scrolldown();
- else if(main_controller->pressed(Controller::UP))
- box->scrollup();
- box->draw(context);
- draw(context);
- context.do_drawing();
- sound_manager->update();
- }
-
- delete box;
-}
-
-void
-GameSession::start_sequence(const std::string& sequencename)
-{
- // handle special "stoptux" sequence
- if (sequencename == "stoptux") {
- if (!end_sequence) {
- log_warning << "Final target reached without an active end sequence" << std::endl;
- this->start_sequence("endsequence");
- }
- if (end_sequence) end_sequence->stop_tux();
- return;
- }
-
- // abort if a sequence is already playing
- if (end_sequence)
- return;
-
- if (sequencename == "endsequence") {
- if (currentsector->get_players()[0]->physic.get_velocity_x() < 0) {
- end_sequence = new EndSequenceWalkLeft();
- } else {
- end_sequence = new EndSequenceWalkRight();
- }
- } else if (sequencename == "fireworks") {
- end_sequence = new EndSequenceFireworks();
- } else {
- log_warning << "Unknown sequence '" << sequencename << "'. Ignoring." << std::endl;
- return;
- }
-
- /* slow down the game for end-sequence */
- main_loop->set_speed(0.5f);
-
- currentsector->add_object(end_sequence);
- end_sequence->start();
-
- sound_manager->play_music("music/leveldone.ogg", false);
- currentsector->player->invincible_timer.start(10000.0f);
-
- // Stop all clocks.
- for(std::vector<GameObject*>::iterator i = currentsector->gameobjects.begin();
- i != currentsector->gameobjects.end(); ++i)
- {
- GameObject* obj = *i;
-
- LevelTime* lt = dynamic_cast<LevelTime*> (obj);
- if(lt)
- lt->stop();
- }
-}
-
-/* (Status): */
-void
-GameSession::drawstatus(DrawingContext& context)
-{
- player_status->draw(context);
-
- // draw level stats while end_sequence is running
- if (end_sequence) {
- level->stats.draw_endseq_panel(context, best_level_statistics, statistics_backdrop.get());
- }
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#ifndef SUPERTUX_GAMELOOP_H
-#define SUPERTUX_GAMELOOP_H
-
-#include <string>
-#include <SDL.h>
-#include <squirrel.h>
-#include "screen.hpp"
-#include "math/vector.hpp"
-#include "video/surface.hpp"
-#include "object/endsequence.hpp"
-
-class Level;
-class Sector;
-class Statistics;
-class DrawingContext;
-class CodeController;
-class Menu;
-
-/**
- * The GameSession class controlls the controll flow of the Game (the part
- * where you actually play a level)
- */
-class GameSession : public Screen
-{
-public:
- GameSession(const std::string& levelfile, Statistics* statistics = NULL);
- ~GameSession();
-
- void record_demo(const std::string& filename);
- int get_demo_random_seed(const std::string& filename);
- void play_demo(const std::string& filename);
-
- void draw(DrawingContext& context);
- void update(float frame_ratio);
- void setup();
-
- void set_current()
- { current_ = this; }
- static GameSession* current()
- { return current_; }
-
- /// ends the current level
- void finish(bool win = true);
- void respawn(const std::string& sectorname, const std::string& spawnpointname);
- void set_reset_point(const std::string& sectorname, const Vector& pos);
- std::string get_reset_point_sectorname()
- { return reset_sector; }
-
- Vector get_reset_point_pos()
- { return reset_pos; }
-
- void display_info_box(const std::string& text);
-
- Sector* get_current_sector()
- { return currentsector; }
-
- Level* get_current_level()
- { return level.get(); }
-
- void start_sequence(const std::string& sequencename);
-
- /**
- * returns the "working directory" usually this is the directory where the
- * currently played level resides. This is used when locating additional
- * resources for the current level/world
- */
- std::string get_working_directory();
- void restart_level();
-
- void toggle_pause();
-
-private:
- void check_end_conditions();
- void process_events();
- void capture_demo_step();
-
- void levelintro();
- void drawstatus(DrawingContext& context);
- void draw_pause(DrawingContext& context);
-
- HSQUIRRELVM run_script(std::istream& in, const std::string& sourcename);
- void on_escape_press();
- void process_menu();
-
- std::auto_ptr<Level> level;
- std::auto_ptr<Surface> statistics_backdrop;
-
- // scripts
- typedef std::vector<HSQOBJECT> ScriptList;
- ScriptList scripts;
-
- Sector* currentsector;
-
- int levelnb;
- int pause_menu_frame;
-
- EndSequence* end_sequence;
-
- bool game_pause;
- float speed_before_pause;
-
- std::string levelfile;
-
- // reset point (the point where tux respawns if he dies)
- std::string reset_sector;
- Vector reset_pos;
-
- // the sector and spawnpoint we should spawn after this frame
- std::string newsector;
- std::string newspawnpoint;
-
- static GameSession* current_;
-
- Statistics* best_level_statistics;
-
- std::ostream* capture_demo_stream;
- std::string capture_file;
- std::istream* playback_demo_stream;
- CodeController* demo_controller;
-
- std::auto_ptr<Menu> game_menu;
-
- float play_time; /**< total time in seconds that this session ran interactively */
-};
-
-#endif /*SUPERTUX_GAMELOOP_H*/
+++ /dev/null
-// $Id$
-//
-// SuperTux - A Jump'n Run
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#include <config.h>
-
-#include "gameconfig.hpp"
-
-#include <stdlib.h>
-#include <string>
-#include <stdexcept>
-
-#include "lisp/parser.hpp"
-#include "lisp/lisp.hpp"
-#include "lisp/writer.hpp"
-#include "control/joystickkeyboardcontroller.hpp"
-#include "resources.hpp"
-#include "main.hpp"
-
-Config* config = 0;
-
-Config::Config()
-{
- use_fullscreen = true;
- video = AUTO_VIDEO;
- try_vsync = true;
- show_fps = false;
- sound_enabled = true;
- music_enabled = true;
- console_enabled = false;
- random_seed = 0; // set by time(), by default (unless in config)
-
- screenwidth = 800;
- screenheight = 600;
- aspect_ratio = -1; // autodetect
-
- enable_script_debugger = false;
-
- locale = ""; // autodetect
-}
-
-Config::~Config()
-{}
-
-void
-Config::load()
-{
- lisp::Parser parser;
- const lisp::Lisp* root = parser.parse("config");
-
- const lisp::Lisp* config_lisp = root->get_lisp("supertux-config");
- if(!config_lisp)
- throw std::runtime_error("File is not a supertux-config file");
-
- config_lisp->get("show_fps", show_fps);
- config_lisp->get("console", console_enabled);
- config_lisp->get("locale", locale);
- config_lisp->get("random_seed", random_seed);
-
- const lisp::Lisp* config_video_lisp = config_lisp->get_lisp("video");
- if(config_video_lisp) {
- config_video_lisp->get("fullscreen", use_fullscreen);
- std::string video_string;
- config_video_lisp->get("video", video_string);
- video = get_video_system(video_string);
- config_video_lisp->get("vsync", try_vsync);
- config_video_lisp->get("width", screenwidth);
- config_video_lisp->get("height", screenheight);
- config_video_lisp->get("aspect_ratio", aspect_ratio);
- }
-
- const lisp::Lisp* config_audio_lisp = config_lisp->get_lisp("audio");
- if(config_audio_lisp) {
- config_audio_lisp->get("sound_enabled", sound_enabled);
- config_audio_lisp->get("music_enabled", music_enabled);
- }
-
- const lisp::Lisp* config_control_lisp = config_lisp->get_lisp("control");
- if(config_control_lisp && main_controller) {
- main_controller->read(*config_control_lisp);
- }
-}
-
-void
-Config::save()
-{
- lisp::Writer writer("config");
-
- writer.start_list("supertux-config");
-
- writer.write_bool("show_fps", show_fps);
- writer.write_bool("console", console_enabled);
- writer.write_string("locale", locale);
-
- writer.start_list("video");
- writer.write_bool("fullscreen", use_fullscreen);
- writer.write_string("video", get_video_string(video));
- writer.write_bool("vsync", try_vsync);
- writer.write_int("width", screenwidth);
- writer.write_int("height", screenheight);
- writer.write_float("aspect_ratio", aspect_ratio);
- writer.end_list("video");
-
- writer.start_list("audio");
- writer.write_bool("sound_enabled", sound_enabled);
- writer.write_bool("music_enabled", music_enabled);
- writer.end_list("audio");
-
- if(main_controller) {
- writer.start_list("control");
- main_controller->write(writer);
- writer.end_list("control");
- }
-
- writer.end_list("supertux-config");
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux=
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#ifndef SUPERTUX_CONFIG_H
-#define SUPERTUX_CONFIG_H
-
-#include <config.h>
-
-#include <string>
-
-#include "video/video_systems.hpp"
-
-class Config
-{
-public:
- Config();
- ~Config();
-
- void load();
- void save();
-
- /** screen width in pixel (warning: this is the real screen width+height,
- * you should use the logical SCREEN_WIDTH and SCREEN_HEIGHT for your
- * rendering code.)
- */
- int screenwidth;
- int screenheight;
- float aspect_ratio;
-
- bool use_fullscreen;
- VideoSystem video;
- bool try_vsync;
- bool show_fps;
- bool sound_enabled;
- bool music_enabled;
- bool console_enabled;
-
- int random_seed; // initial random seed. 0 ==> set from time()
-
- /** this variable is set if supertux should start in a specific level */
- std::string start_level;
- bool enable_script_debugger;
- std::string start_demo;
- std::string record_demo;
-
- std::string locale; /**< force SuperTux language to this locale, e.g. "de". A file "data/locale/xx.po" must exist for this to work. An empty string means autodetect. */
-};
-
-extern Config* config;
-
-#endif
+++ /dev/null
-/*
- This program is free software; you can redistribute it and/or modify it
- under the terms of the GNU Library General Public License as published
- by the Free Software Foundation; either version 2, 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
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library 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. */
-#ifndef _LIBGETTEXT_H
-#define _LIBGETTEXT_H
-
-#include "tinygettext/tinygettext.hpp"
-
-extern TinyGetText::DictionaryManager dictionary_manager;
-
-static inline const char* _(const char* message)
-{
- return dictionary_manager.get_dictionary().translate(message);
-}
-
-static inline std::string _(const std::string& message)
-{
- return dictionary_manager.get_dictionary().translate(message);
-}
-
-static inline const char* N_(const char* id, const char* id2, int num)
-{
- return dictionary_manager.get_dictionary().translate(id, id2, num).c_str();
-}
-
-#endif /* _LIBGETTEXT_H */
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include <SDL.h>
-#include <iostream>
-
-#include "main.hpp"
-#include "button.hpp"
-#include "mousecursor.hpp"
-#include "video/font.hpp"
-#include "video/surface.hpp"
-
-Font* Button::info_font = 0;
-extern SDL_Surface* screen;
-
-/* Buttons */
-
-Button::Button(Surface* image_, std::string info_, SDLKey binding_)
- : binding(binding_)
-{
- image = image_;
- size = Vector(image->get_width(), image->get_height());
- id = 0;
- info = info_;
-}
-
-Button::~Button()
-{
-}
-
-void Button::draw(DrawingContext &context, bool selected)
-{
-if(selected)
- context.draw_filled_rect(pos, size, Color (200,240,220), LAYER_GUI);
-else
- context.draw_filled_rect(pos, size, Color (200,200,220), LAYER_GUI);
-
-Vector tanslation = -context.get_translation();
-if(state == BT_SHOW_INFO)
- {
- Vector offset;
- if(pos.x + tanslation.x < 100 && pos.y + tanslation.y > SCREEN_HEIGHT - 20)
- offset = Vector(size.x, - 10);
- else if(pos.x + tanslation.x < 100)
- offset = Vector(size.x, 0);
- else
- offset = Vector(-30, -size.y/2);
- context.draw_text(info_font, info, pos + offset, ALIGN_LEFT, LAYER_GUI+2);
- if(binding != 0)
- context.draw_text(info_font, "(" + std::string(SDL_GetKeyName(binding)) +
- ")", pos + offset + Vector(0,12),
- ALIGN_LEFT, LAYER_GUI+2);
- }
-
-context.draw_surface_part(image, Vector(0,0), size, pos, LAYER_GUI+1);
-}
-
-int Button::event(SDL_Event &event, int x_offset, int y_offset)
-{
-state = BT_NONE;
-switch(event.type)
- {
- case SDL_MOUSEBUTTONDOWN:
- if(event.button.x > pos.x + x_offset && event.button.x < pos.x + x_offset + size.x &&
- event.button.y > pos.y + y_offset && event.button.y < pos.y + y_offset + size.y)
- {
- if(event.button.button == SDL_BUTTON_RIGHT)
- state = BT_SHOW_INFO;
- }
- break;
- case SDL_MOUSEBUTTONUP:
- if(event.button.x > pos.x + x_offset && event.button.x < pos.x + x_offset + size.x &&
- event.button.y > pos.y + y_offset && event.button.y < pos.y + y_offset + size.y)
- {
- if(event.button.button == SDL_BUTTON_LEFT)
- state = BT_SELECTED;
- }
- break;
- case SDL_KEYDOWN: // key pressed
- if(event.key.keysym.sym == binding)
- state = BT_SELECTED;
- break;
- default:
- break;
- }
-return state;
-}
-
-/* Group of buttons */
-
-ButtonGroup::ButtonGroup(Vector pos_, Vector buttons_size_, Vector buttons_box_)
- : pos(pos_), buttons_size(buttons_size_), buttons_box(buttons_box_)
-{
-buttons.clear();
-row = 0;
-button_selected = -1;
-mouse_hover = false;
-mouse_left_button = false;
-buttons_pair_nb = 0;
-}
-
-ButtonGroup::~ButtonGroup()
-{
-}
-
-void ButtonGroup::add_button(Button button, int id, bool select)
-{
-button.pos.x = ((buttons.size()-buttons_pair_nb) % (int)buttons_box.x) * buttons_size.x;
-button.pos.y = ((int)((buttons.size()-buttons_pair_nb) / buttons_box.x)) * buttons_size.y;
-button.size = buttons_size;
-button.id = id;
-if(select)
- button_selected = id;
-
-buttons.push_back(button);
-}
-
-void ButtonGroup::add_pair_of_buttons(Button button1, int id1, Button button2, int id2)
-{
-button1.pos.x = button2.pos.x = ((buttons.size()-buttons_pair_nb) % (int)buttons_box.x) * buttons_size.x;
-button1.pos.y = button2.pos.y = ((int)((buttons.size()-buttons_pair_nb) / buttons_box.x)) * buttons_size.y;
-button1.size.x = button2.size.x = buttons_size.x;
-button1.size.y = button2.size.y = buttons_size.y / 2;
-button2.pos.y += buttons_size.y / 2;
-button1.id = id1;
-button2.id = id2;
-
-buttons_pair_nb++;
-buttons.push_back(button1);
-buttons.push_back(button2);
-}
-
-void ButtonGroup::draw(DrawingContext &context)
-{
-context.draw_filled_rect(pos - Vector(12,4),
- Vector(buttons_size.x*buttons_box.x + 16, buttons_size.y*buttons_box.y + 8),
- Color (0,0,0, 128), LAYER_GUI-1);
-
-context.push_transform();
-context.set_translation(Vector(-pos.x, -pos.y + buttons_size.y*row));
-for(Buttons::iterator i = buttons.begin(); i != buttons.end(); ++i)
- {
- if(i->pos.y < row*buttons_size.y ||
- i->pos.y + i->size.y > (row + buttons_box.y) * buttons_size.y)
- continue;
-
- i->draw(context, i->id == button_selected);
- }
-context.pop_transform();
-}
-
-bool ButtonGroup::event(SDL_Event &event)
-{
-bool caught_event = false;
-
-switch(event.type)
- {
- case SDL_MOUSEMOTION:
- mouse_hover = false;
-
- if(mouse_left_button)
- {
- pos.x += int(event.motion.xrel * float(SCREEN_WIDTH)/screen->w);
- pos.y += int(event.motion.yrel * float(SCREEN_HEIGHT)/screen->h);
- caught_event = true;
- }
- if(event.button.x > pos.x-12 && event.button.x < pos.x+16 + buttons_box.x*buttons_size.x &&
- event.button.y > pos.y-4 && event.button.y < pos.y+8 + buttons_box.y*buttons_size.y)
- mouse_hover = true;
- break;
- case SDL_MOUSEBUTTONDOWN:
- if(event.button.x < pos.x-12 || event.button.x > pos.x+16 +
- buttons_box.x*buttons_size.x || event.button.y < pos.y-4 ||
- event.button.y > pos.y+8 + buttons_box.y*buttons_size.y)
- break;
-
- caught_event = true;
-
- if(event.button.button == SDL_BUTTON_WHEELUP)
- {
- row--;
- if(row < 0)
- row = 0;
- }
- else if(event.button.button == SDL_BUTTON_WHEELDOWN)
- {
- row++;
- if(row > (int)((buttons.size()-buttons_pair_nb)/buttons_box.x) - (int)buttons_box.y +
- ((int)(buttons.size()-buttons_pair_nb)%(int)buttons_box.x != 0 ? 1 : 0))
- row = (int)((buttons.size()-buttons_pair_nb)/buttons_box.x) - (int)buttons_box.y +
- ((int)(buttons.size()-buttons_pair_nb)%(int)buttons_box.x != 0 ? 1 : 0);
- }
- else if(event.button.button == SDL_BUTTON_LEFT)
- mouse_left_button = true;
- else
- caught_event = false;
- break;
- case SDL_MOUSEBUTTONUP:
- mouse_left_button = false;
- break;
- default:
- break;
- }
-
-if(caught_event)
- return true;
-
-for(Buttons::iterator i = buttons.begin(); i != buttons.end(); ++i)
- {
- if(i->pos.y < row*buttons_size.y ||
- i->pos.y + i->size.y > (row + buttons_box.y) * buttons_size.y)
- continue;
-
- if(i->event(event, (int)pos.x,
- (int)pos.y - row*(int)buttons_size.y) == BT_SELECTED)
- {
- button_selected = i->id;
- caught_event = true;
- break;
- }
- }
-
-return caught_event;
-}
-
-int ButtonGroup::selected_id()
-{
-return button_selected;
-}
-
-void ButtonGroup::set_unselected()
-{
-button_selected = -1;
-}
-
-bool ButtonGroup::is_hover()
-{
-return mouse_hover;
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef SUPERTUX_BUTTON_H
-#define SUPERTUX_BUTTON_H
-
-#include <vector>
-#include <string>
-
-#include "math/vector.hpp"
-#include "video/drawing_context.hpp"
-
-class Surface;
-
-class ButtonGroup;
-
-enum {
- BT_NONE,
- BT_HOVER,
- BT_SELECTED,
- BT_SHOW_INFO
- };
-
-class Button
-{
-public:
- Button(Surface* image_, std::string info_, SDLKey binding_);
- ~Button();
-
- void draw(DrawingContext& context, bool selected);
- int event(SDL_Event& event, int x_offset = 0, int y_offset = 0);
-
- static Font* info_font;
-
-private:
- friend class ButtonGroup;
-
- Vector pos, size;
-
- Surface* image;
- SDLKey binding;
-
- int id;
- int state;
- std::string info;
-};
-
-class ButtonGroup
-{
-public:
- ButtonGroup(Vector pos_, Vector size_, Vector button_box_);
- ~ButtonGroup();
-
- void draw(DrawingContext& context);
- bool event(SDL_Event& event);
-
- void add_button(Button button, int id, bool select = false);
- void add_pair_of_buttons(Button button1, int id1, Button button2, int id2);
-
- int selected_id();
- void set_unselected();
- bool is_hover();
-
-private:
- Vector pos, buttons_size, buttons_box;
- typedef std::vector <Button> Buttons;
- Buttons buttons;
-
- int button_selected, row;
- bool mouse_hover, mouse_left_button;
-
- int buttons_pair_nb;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include <sys/types.h>
-#include <ctype.h>
-
-#include <iostream>
-#include <sstream>
-#include <cstdlib>
-#include <cstdio>
-#include <string>
-#include <cassert>
-#include <stdexcept>
-
-#include "menu.hpp"
-#include "mainloop.hpp"
-#include "video/drawing_context.hpp"
-#include "gettext.hpp"
-#include "math/vector.hpp"
-#include "main.hpp"
-#include "resources.hpp"
-#include "timer.hpp"
-#include "control/joystickkeyboardcontroller.hpp"
-
-static const float MENU_REPEAT_INITIAL = 0.4f;
-static const float MENU_REPEAT_RATE = 0.2f;
-static const float FLICK_CURSOR_TIME = 0.5f;
-
-extern SDL_Surface* screen;
-
-std::vector<Menu*> Menu::last_menus;
-Menu* Menu::current_ = 0;
-Font* Menu::default_font;
-Font* Menu::active_font;
-Font* Menu::deactive_font;
-Font* Menu::label_font;
-Font* Menu::field_font;
-
-/* just displays a Yes/No text that can be used to confirm stuff */
-bool confirm_dialog(Surface *background, std::string text)
-{
- //Surface* cap_screen = Surface::CaptureScreen();
- Menu* dialog = new Menu;
- dialog->add_deactive(-1, text);
- dialog->add_hl();
- dialog->add_entry(true, _("Yes"));
- dialog->add_entry(false, _("No"));
- dialog->add_hl();
-
- Menu::set_current(dialog);
-
- DrawingContext context;
-
- // TODO make this a screen and not another mainloop...
- while(true)
- {
- SDL_Event event;
- while (SDL_PollEvent(&event)) {
- if(event.type == SDL_QUIT)
- main_loop->quit();
- main_controller->process_event(event);
- dialog->event(event);
- }
-
- if(background == NULL)
- context.draw_gradient(Color(0.8f, 0.95f, 0.85f), Color(0.8f, 0.8f, 0.8f),
- LAYER_BACKGROUND0);
- else
- context.draw_surface(background, Vector(0,0), LAYER_BACKGROUND0);
-
- dialog->draw(context);
- dialog->update();
-
- switch (dialog->check())
- {
- case true:
- //delete cap_screen;
- Menu::set_current(0);
- delete dialog;
- return true;
- break;
- case false:
- //delete cap_screen;
- Menu::set_current(0);
- delete dialog;
- return false;
- break;
- default:
- break;
- }
-
- mouse_cursor->draw(context);
- context.do_drawing();
- SDL_Delay(25);
- }
-
- return false;
-}
-
-void
-Menu::push_current(Menu* pmenu)
-{
- if (current_)
- last_menus.push_back(current_);
-
- current_ = pmenu;
- current_->effect_time = real_time;
-}
-
-void
-Menu::pop_current()
-{
- if (last_menus.size() >= 1) {
- current_ = last_menus.back();
- current_->effect_time = real_time;
- last_menus.pop_back();
- } else {
- current_ = 0;
- }
-}
-
-void
-Menu::set_current(Menu* menu)
-{
- last_menus.clear();
-
- if (menu)
- menu->effect_time = real_time;
-
- current_ = menu;
- // just to be sure...
- main_controller->reset();
-}
-
-MenuItem::MenuItem(MenuItemKind _kind, int _id)
- : kind(_kind) , id(_id)
-{
- toggled = false;
- selected = false;
- target_menu = 0;
-}
-
-void
-MenuItem::change_text(const std::string& text_)
-{
- text = text_;
-}
-
-void
-MenuItem::change_input(const std::string& text_)
-{
- input = text_;
-}
-
-std::string MenuItem::get_input_with_symbol(bool active_item)
-{
- if(!active_item) {
- input_flickering = true;
- } else {
- input_flickering = ((int) (real_time / FLICK_CURSOR_TIME)) % 2;
- }
-
- char str[1024];
- if(input_flickering)
- snprintf(str, sizeof(str), "%s ",input.c_str());
- else
- snprintf(str, sizeof(str), "%s_",input.c_str());
-
- std::string string = str;
-
- return string;
-}
-
-Menu::~Menu()
-{
- for(std::vector<MenuItem*>::iterator i = items.begin();
- i != items.end(); ++i)
- delete *i;
- if(current_ == this)
- current_ = NULL;
-}
-
-Menu::Menu()
-{
- hit_item = -1;
- menuaction = MENU_ACTION_NONE;
- delete_character = 0;
- mn_input_char = '\0';
-
- pos_x = SCREEN_WIDTH/2;
- pos_y = SCREEN_HEIGHT/2;
- arrange_left = 0;
- active_item = -1;
-
- checkbox.reset(new Surface("images/engine/menu/checkbox-unchecked.png"));
- checkbox_checked.reset(new Surface("images/engine/menu/checkbox-checked.png"));
- back.reset(new Surface("images/engine/menu/arrow-back.png"));
- arrow_left.reset(new Surface("images/engine/menu/arrow-left.png"));
- arrow_right.reset(new Surface("images/engine/menu/arrow-right.png"));
-}
-
-void Menu::set_pos(float x, float y, float rw, float rh)
-{
- pos_x = x + get_width() * rw;
- pos_y = y + get_height() * rh;
-}
-
-/* Add an item to a menu */
-void
-Menu::additem(MenuItem* item)
-{
- items.push_back(item);
-
- /* If a new menu is being built, the active item shouldn't be set to
- * something that isnt selectable. Set the active_item to the first
- * selectable item added
- */
- if (active_item == -1
- && item->kind != MN_HL
- && item->kind != MN_LABEL
- && item->kind != MN_DEACTIVE) {
- active_item = items.size() - 1;
- }
-}
-
-void
-Menu::add_hl()
-{
- additem(new MenuItem(MN_HL));
-}
-
-void
-Menu::add_label(const std::string& text)
-{
- MenuItem* item = new MenuItem(MN_LABEL);
- item->text = text;
- additem(item);
-}
-
-void
-Menu::add_controlfield(int id, const std::string& text,
- const std::string& mapping)
-{
- MenuItem* item = new MenuItem(MN_CONTROLFIELD, id);
- item->change_text(text);
- item->change_input(mapping);
- additem(item);
-}
-
-void
-Menu::add_entry(int id, const std::string& text)
-{
- MenuItem* item = new MenuItem(MN_ACTION, id);
- item->text = text;
- additem(item);
-}
-
-void
-Menu::add_deactive(int id, const std::string& text)
-{
- MenuItem* item = new MenuItem(MN_DEACTIVE, id);
- item->text = text;
- additem(item);
-}
-
-void
-Menu::add_toggle(int id, const std::string& text, bool toogled)
-{
- MenuItem* item = new MenuItem(MN_TOGGLE, id);
- item->text = text;
- item->toggled = toogled;
- additem(item);
-}
-
-void
-Menu::add_back(const std::string& text)
-{
- MenuItem* item = new MenuItem(MN_BACK);
- item->text = text;
- additem(item);
-}
-
-void
-Menu::add_submenu(const std::string& text, Menu* submenu, int id)
-{
- MenuItem* item = new MenuItem(MN_GOTO, id);
- item->text = text;
- item->target_menu = submenu;
- additem(item);
-}
-
-void
-Menu::clear()
-{
- for(std::vector<MenuItem*>::iterator i = items.begin();
- i != items.end(); ++i) {
- delete *i;
- }
- items.clear();
- active_item = -1;
-}
-
-/* Process actions done on the menu */
-void
-Menu::update()
-{
- /** check main input controller... */
- if(main_controller->pressed(Controller::UP)) {
- menuaction = MENU_ACTION_UP;
- menu_repeat_time = real_time + MENU_REPEAT_INITIAL;
- }
- if(main_controller->hold(Controller::UP) &&
- menu_repeat_time != 0 && real_time > menu_repeat_time) {
- menuaction = MENU_ACTION_UP;
- menu_repeat_time = real_time + MENU_REPEAT_RATE;
- }
- if(main_controller->pressed(Controller::DOWN)) {
- menuaction = MENU_ACTION_DOWN;
- menu_repeat_time = real_time + MENU_REPEAT_INITIAL;
- }
- if(main_controller->hold(Controller::DOWN) &&
- menu_repeat_time != 0 && real_time > menu_repeat_time) {
- menuaction = MENU_ACTION_DOWN;
- menu_repeat_time = real_time + MENU_REPEAT_RATE;
- }
- if(main_controller->pressed(Controller::ACTION)
- || main_controller->pressed(Controller::MENU_SELECT)) {
- menuaction = MENU_ACTION_HIT;
- }
- if(main_controller->pressed(Controller::PAUSE_MENU)) {
- menuaction = MENU_ACTION_BACK;
- }
-
- hit_item = -1;
- if(items.size() == 0)
- return;
-
- int last_active_item = active_item;
- switch(menuaction) {
- case MENU_ACTION_UP:
- do {
- if (active_item > 0)
- --active_item;
- else
- active_item = int(items.size())-1;
- } while ((items[active_item]->kind == MN_HL
- || items[active_item]->kind == MN_LABEL
- || items[active_item]->kind == MN_DEACTIVE)
- && (active_item != last_active_item));
-
- break;
-
- case MENU_ACTION_DOWN:
- do {
- if(active_item < int(items.size())-1 )
- ++active_item;
- else
- active_item = 0;
- } while ((items[active_item]->kind == MN_HL
- || items[active_item]->kind == MN_LABEL
- || items[active_item]->kind == MN_DEACTIVE)
- && (active_item != last_active_item));
-
- break;
-
- case MENU_ACTION_LEFT:
- if(items[active_item]->kind == MN_STRINGSELECT) {
- if(items[active_item]->selected > 0)
- items[active_item]->selected--;
- else
- items[active_item]->selected = items[active_item]->list.size()-1;
- }
- break;
-
- case MENU_ACTION_RIGHT:
- if(items[active_item]->kind == MN_STRINGSELECT) {
- if(items[active_item]->selected+1 < items[active_item]->list.size())
- items[active_item]->selected++;
- else
- items[active_item]->selected = 0;
- }
- break;
-
- case MENU_ACTION_HIT: {
- hit_item = active_item;
- switch (items[active_item]->kind) {
- case MN_GOTO:
- assert(items[active_item]->target_menu != 0);
- Menu::push_current(items[active_item]->target_menu);
- break;
-
- case MN_TOGGLE:
- items[active_item]->toggled = !items[active_item]->toggled;
- menu_action(items[active_item]);
- break;
-
- case MN_CONTROLFIELD:
- menu_action(items[active_item]);
- break;
-
- case MN_ACTION:
- menu_action(items[active_item]);
- break;
-
- case MN_TEXTFIELD:
- case MN_NUMFIELD:
- menuaction = MENU_ACTION_DOWN;
- update();
- break;
-
- case MN_BACK:
- Menu::pop_current();
- break;
- default:
- break;
- }
- break;
- }
-
- case MENU_ACTION_REMOVE:
- if(items[active_item]->kind == MN_TEXTFIELD
- || items[active_item]->kind == MN_NUMFIELD)
- {
- if(!items[active_item]->input.empty())
- {
- int i = items[active_item]->input.size();
-
- while(delete_character > 0) /* remove charactes */
- {
- items[active_item]->input.resize(i-1);
- delete_character--;
- }
- }
- }
- break;
-
- case MENU_ACTION_INPUT:
- if(items[active_item]->kind == MN_TEXTFIELD
- || (items[active_item]->kind == MN_NUMFIELD
- && mn_input_char >= '0' && mn_input_char <= '9'))
- {
- items[active_item]->input.push_back(mn_input_char);
- }
- break;
-
- case MENU_ACTION_BACK:
- Menu::pop_current();
- break;
-
- case MENU_ACTION_NONE:
- break;
- }
- menuaction = MENU_ACTION_NONE;
-
- assert(active_item < int(items.size()));
-}
-
-int
-Menu::check()
-{
- if (hit_item != -1)
- return items[hit_item]->id;
- else
- return -1;
-}
-
-void
-Menu::menu_action(MenuItem* )
-{}
-
-void
-Menu::draw_item(DrawingContext& context, int index)
-{
- float menu_height = get_height();
- float menu_width = get_width();
-
- MenuItem& pitem = *(items[index]);
-
- int effect_offset = 0;
- if(effect_time != 0) {
- if(real_time - effect_time > 0.5) {
- effect_time = 0;
- } else {
- float effect_delta = (0.5 - (real_time - effect_time)) * 250;
- effect_offset = (int) ((index % 2) ? effect_delta : -effect_delta);
- }
- }
-
- Font* text_font = default_font;
- float x_pos = pos_x;
- float y_pos = pos_y + 24*index - menu_height/2 + 12 + effect_offset;
- int shadow_size = 2;
- int text_width = int(text_font->get_text_width(pitem.text));
- int input_width = int(text_font->get_text_width(pitem.input) + 10);
- int list_width = 0;
- if(pitem.list.size() > 0) {
- list_width = (int) text_font->get_text_width(pitem.list[pitem.selected]);
- }
-
- if (arrange_left)
- x_pos += 24 - menu_width/2 + (text_width + input_width + list_width)/2;
-
- if(index == active_item)
- {
- shadow_size = 3;
- text_font = active_font;
- }
-
- switch (pitem.kind)
- {
- case MN_DEACTIVE:
- {
- context.draw_text(deactive_font, pitem.text,
- Vector(SCREEN_WIDTH/2, y_pos - int(deactive_font->get_height()/2)),
- ALIGN_CENTER, LAYER_GUI);
- break;
- }
-
- case MN_HL:
- {
- // TODO
- float x = pos_x - menu_width/2;
- float y = y_pos - 12 - effect_offset;
- /* Draw a horizontal line with a little 3d effect */
- context.draw_filled_rect(Vector(x, y + 6),
- Vector(menu_width, 4),
- Color(0.6f, 0.7f, 1.0f, 1.0f), LAYER_GUI);
- context.draw_filled_rect(Vector(x, y + 6),
- Vector(menu_width, 2),
- Color(1.0f, 1.0f, 1.0f, 1.0f), LAYER_GUI);
- break;
- }
- case MN_LABEL:
- {
- context.draw_text(label_font, pitem.text,
- Vector(SCREEN_WIDTH/2, y_pos - int(label_font->get_height()/2)),
- ALIGN_CENTER, LAYER_GUI);
- break;
- }
- case MN_TEXTFIELD:
- case MN_NUMFIELD:
- case MN_CONTROLFIELD:
- {
- float width = text_width + input_width + 5;
- float text_pos = SCREEN_WIDTH/2 - width/2;
- float input_pos = text_pos + text_width + 10;
-
- context.draw_filled_rect(
- Vector(input_pos - 5, y_pos - 10),
- Vector(input_width + 10, 20),
- Color(1.0f, 1.0f, 1.0f, 1.0f), LAYER_GUI-5);
- context.draw_filled_rect(
- Vector(input_pos - 4, y_pos - 9),
- Vector(input_width + 8, 18),
- Color(0, 0, 0, 0.5f), LAYER_GUI-4);
-
- if(pitem.kind == MN_TEXTFIELD || pitem.kind == MN_NUMFIELD)
- {
- if(active_item == index)
- context.draw_text(field_font,
- pitem.get_input_with_symbol(true),
- Vector(input_pos, y_pos - int(field_font->get_height()/2)),
- ALIGN_LEFT, LAYER_GUI);
- else
- context.draw_text(field_font,
- pitem.get_input_with_symbol(false),
- Vector(input_pos, y_pos - int(field_font->get_height()/2)),
- ALIGN_LEFT, LAYER_GUI);
- }
- else
- context.draw_text(field_font, pitem.input,
- Vector(input_pos, y_pos - int(field_font->get_height()/2)),
- ALIGN_LEFT, LAYER_GUI);
-
- context.draw_text(text_font, pitem.text,
- Vector(text_pos, y_pos - int(text_font->get_height()/2)),
- ALIGN_LEFT, LAYER_GUI);
- break;
- }
- case MN_STRINGSELECT:
- {
- int list_pos_2 = list_width + 16;
- int list_pos = list_width/2;
- int text_pos = (text_width + 16)/2;
-
- /* Draw arrows */
- context.draw_surface(arrow_left.get(),
- Vector(x_pos - list_pos + text_pos - 17, y_pos - 8),
- LAYER_GUI);
- context.draw_surface(arrow_right.get(),
- Vector(x_pos - list_pos + text_pos - 1 + list_pos_2, y_pos - 8),
- LAYER_GUI);
-
- /* Draw input background */
- context.draw_filled_rect(
- Vector(x_pos - list_pos + text_pos - 1, y_pos - 10),
- Vector(list_pos_2 + 2, 20),
- Color(1.0f, 1.0f, 1.0f, 1.0f), LAYER_GUI - 4);
- context.draw_filled_rect(
- Vector(x_pos - list_pos + text_pos, y_pos - 9),
- Vector(list_pos_2, 18),
- Color(0, 0, 0, 0.5f), LAYER_GUI - 5);
-
- context.draw_text(text_font, pitem.list[pitem.selected],
- Vector(SCREEN_WIDTH/2 + text_pos, y_pos - int(text_font->get_height()/2)),
- ALIGN_CENTER, LAYER_GUI);
- context.draw_text(text_font, pitem.text,
- Vector(SCREEN_WIDTH/2 + list_pos_2/2, y_pos - int(text_font->get_height()/2)),
- ALIGN_CENTER, LAYER_GUI);
- break;
- }
- case MN_BACK:
- {
- context.draw_text(text_font, pitem.text,
- Vector(SCREEN_WIDTH/2, y_pos - int(text_font->get_height()/2)),
- ALIGN_CENTER, LAYER_GUI);
- context.draw_surface(back.get(),
- Vector(x_pos + text_width/2 + 16, y_pos - 8),
- LAYER_GUI);
- break;
- }
-
- case MN_TOGGLE:
- {
- context.draw_text(text_font, pitem.text,
- Vector(SCREEN_WIDTH/2, y_pos - (text_font->get_height()/2)),
- ALIGN_CENTER, LAYER_GUI);
-
- if(pitem.toggled)
- context.draw_surface(checkbox_checked.get(),
- Vector(x_pos + (text_width+16)/2, y_pos - 8),
- LAYER_GUI + 1);
- else
- context.draw_surface(checkbox.get(),
- Vector(x_pos + (text_width+16)/2, y_pos - 8),
- LAYER_GUI + 1);
- break;
- }
- case MN_ACTION:
- context.draw_text(text_font, pitem.text,
- Vector(SCREEN_WIDTH/2, y_pos - int(text_font->get_height()/2)),
- ALIGN_CENTER, LAYER_GUI);
- break;
-
- case MN_GOTO:
- context.draw_text(text_font, pitem.text,
- Vector(SCREEN_WIDTH/2, y_pos - int(text_font->get_height()/2)),
- ALIGN_CENTER, LAYER_GUI);
- break;
- }
-}
-
-float Menu::get_width() const
-{
- /* The width of the menu has to be more than the width of the text
- with the most characters */
- float menu_width = 0;
- for(unsigned int i = 0; i < items.size(); ++i)
- {
- Font* font = default_font;
- if(items[i]->kind == MN_LABEL)
- font = label_font;
-
- float w = font->get_text_width(items[i]->text) +
- label_font->get_text_width(items[i]->input) + 16;
- if(items[i]->kind == MN_TOGGLE)
- w += 32;
-
- if(w > menu_width)
- menu_width = w;
- }
-
- return menu_width + 24;
-}
-
-float Menu::get_height() const
-{
- return items.size() * 24;
-}
-
-/* Draw the current menu. */
-void
-Menu::draw(DrawingContext& context)
-{
- if(MouseCursor::current()) {
- MouseCursor::current()->draw(context);
- }
-
- float menu_height = get_height();
- float menu_width = get_width();
-
- /* Draw a transparent background */
- context.draw_filled_rect(
- Vector(pos_x - menu_width/2, pos_y - 24*items.size()/2 - 10),
- Vector(menu_width,menu_height + 20),
- Color(0.6f, 0.7f, 0.8f, 0.5f), LAYER_GUI-10);
-
- for(unsigned int i = 0; i < items.size(); ++i)
- {
- draw_item(context, i);
- }
-}
-
-MenuItem&
-Menu::get_item_by_id(int id)
-{
- for(std::vector<MenuItem*>::iterator i = items.begin();
- i != items.end(); ++i) {
- MenuItem& item = **i;
-
- if(item.id == id)
- return item;
- }
-
- throw std::runtime_error("MenuItem not found");
-}
-
-const MenuItem&
-Menu::get_item_by_id(int id) const
-{
- for(std::vector<MenuItem*>::const_iterator i = items.begin();
- i != items.end(); ++i) {
- const MenuItem& item = **i;
-
- if(item.id == id)
- return item;
- }
-
- throw std::runtime_error("MenuItem not found");
-}
-
-int Menu::get_active_item_id()
-{
- return items[active_item]->id;
-}
-
-bool
-Menu::is_toggled(int id) const
-{
- return get_item_by_id(id).toggled;
-}
-
-/* Check for menu event */
-void
-Menu::event(const SDL_Event& event)
-{
- if(effect_time != 0)
- return;
-
- switch(event.type) {
- case SDL_MOUSEBUTTONDOWN:
- {
- int x = int(event.motion.x * float(SCREEN_WIDTH)/screen->w);
- int y = int(event.motion.y * float(SCREEN_HEIGHT)/screen->h);
-
- if(x > pos_x - get_width()/2 &&
- x < pos_x + get_width()/2 &&
- y > pos_y - get_height()/2 &&
- y < pos_y + get_height()/2)
- {
- menuaction = MENU_ACTION_HIT;
- }
- }
- break;
-
- case SDL_MOUSEMOTION:
- {
- float x = event.motion.x * SCREEN_WIDTH/screen->w;
- float y = event.motion.y * SCREEN_HEIGHT/screen->h;
-
- if(x > pos_x - get_width()/2 &&
- x < pos_x + get_width()/2 &&
- y > pos_y - get_height()/2 &&
- y < pos_y + get_height()/2)
- {
- int new_active_item
- = static_cast<int> ((y - (pos_y - get_height()/2)) / 24);
-
- /* only change the mouse focus to a selectable item */
- if ((items[new_active_item]->kind != MN_HL)
- && (items[new_active_item]->kind != MN_LABEL)
- && (items[new_active_item]->kind != MN_DEACTIVE))
- active_item = new_active_item;
-
- if(MouseCursor::current())
- MouseCursor::current()->set_state(MC_LINK);
- }
- else
- {
- if(MouseCursor::current())
- MouseCursor::current()->set_state(MC_NORMAL);
- }
- }
- break;
-
- default:
- break;
- }
-}
-
-void
-Menu::set_active_item(int id)
-{
- for(size_t i = 0; i < items.size(); ++i) {
- MenuItem* item = items[i];
- if(item->id == id) {
- active_item = i;
- break;
- }
- }
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef SUPERTUX_MENU_H
-#define SUPERTUX_MENU_H
-
-#include <vector>
-#include <memory>
-#include <set>
-#include <string>
-#include <utility>
-#include <assert.h>
-
-#include <SDL.h>
-
-#include "video/surface.hpp"
-#include "video/font.hpp"
-#include "mousecursor.hpp"
-
-bool confirm_dialog(Surface* background, std::string text);
-
-/* Kinds of menu items */
-enum MenuItemKind {
- MN_ACTION,
- MN_GOTO,
- MN_TOGGLE,
- MN_BACK,
- MN_DEACTIVE,
- MN_TEXTFIELD,
- MN_NUMFIELD,
- MN_CONTROLFIELD,
- MN_STRINGSELECT,
- MN_LABEL,
- MN_HL, /* horizontal line */
-};
-
-class Menu;
-
-class MenuItem
-{
-public:
- MenuItem(MenuItemKind kind, int id = -1);
- MenuItemKind kind;
- int id; // item id
- bool toggled;
- std::string text;
- std::string input;
-
- std::vector<std::string> list; // list of values for a STRINGSELECT item
- size_t selected; // currently selected item
-
- Menu* target_menu;
-
- void change_text (const std::string& text);
- void change_input(const std::string& text);
-
- static MenuItem* create(MenuItemKind kind, const std::string& text,
- int init_toggle, Menu* target_menu, int id, int key);
-
- std::string get_input_with_symbol(bool active_item); // returns the text with an input symbol
-
-private:
- /// copy-construction not allowed
- MenuItem(const MenuItem& ) { assert(false); }
- /// assignment not allowed
- void operator= (const MenuItem& ) { assert(false); }
-
- /// keyboard key or joystick button
- bool input_flickering;
-};
-
-class Menu
-{
-private:
- static std::vector<Menu*> last_menus;
- static Menu* current_;
-
- static void pop_current();
-
-public:
- /** Set the current menu, if pmenu is NULL, hide the current menu */
- static void set_current(Menu* pmenu);
-
- static void push_current(Menu* pmenu);
-
- /** Return the current active menu or NULL if none is active */
- static Menu* current()
- {
- return current_;
- }
-
-private:
- /* Action done on the menu */
- enum MenuAction {
- MENU_ACTION_NONE = -1,
- MENU_ACTION_UP,
- MENU_ACTION_DOWN,
- MENU_ACTION_LEFT,
- MENU_ACTION_RIGHT,
- MENU_ACTION_HIT,
- MENU_ACTION_INPUT,
- MENU_ACTION_REMOVE,
- MENU_ACTION_BACK
- };
-
- /** Number of the item that got 'hit' (ie. pressed) in the last
- event()/update() call, -1 if none */
- int hit_item;
-
- // position of the menu (ie. center of the menu, not top/left)
- float pos_x;
- float pos_y;
-
- /** input event for the menu (up, down, left, right, etc.) */
- MenuAction menuaction;
-
- /* input implementation variables */
- int delete_character;
- char mn_input_char;
- float menu_repeat_time;
-
-public:
- static Font* default_font;
- static Font* active_font;
- static Font* deactive_font;
- static Font* label_font;
- static Font* field_font;
-
- std::vector<MenuItem*> items;
-
- Menu();
- virtual ~Menu();
-
- void add_hl();
- void add_label(const std::string& text);
- void add_entry(int id, const std::string& text);
- void add_toggle(int id, const std::string& text, bool toggled = false);
- void add_deactive(int id, const std::string& text);
- void add_back(const std::string& text);
- void add_submenu(const std::string& text, Menu* submenu, int id = -1);
- void add_controlfield(int id, const std::string& text,
- const std::string& mapping = "");
-
- virtual void menu_action(MenuItem* item);
-
- void update();
-
- /** Remove all entries from the menu */
- void clear();
-
- /** Return the index of the menu item that was 'hit' (ie. the user
- clicked on it) in the last event() call */
- int check ();
-
- MenuItem& get_item(int index)
- {
- return *(items[index]);
- }
- MenuItem& get_item_by_id(int id);
- const MenuItem& get_item_by_id(int id) const;
-
- int get_active_item_id();
- void set_active_item(int id);
-
- void draw(DrawingContext& context);
- void set_pos(float x, float y, float rw = 0, float rh = 0);
-
- void event(const SDL_Event& event);
-
- bool is_toggled(int id) const;
-
-protected:
- void additem(MenuItem* pmenu_item);
- float get_width() const;
- float get_height() const;
-
-private:
- void check_controlfield_change_event(const SDL_Event& event);
- void draw_item(DrawingContext& context, int index);
- float effect_time;
- int arrange_left;
- int active_item;
-
- std::auto_ptr<Surface> checkbox;
- std::auto_ptr<Surface> checkbox_checked;
- std::auto_ptr<Surface> back;
- std::auto_ptr<Surface> arrow_left;
- std::auto_ptr<Surface> arrow_right;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include <SDL_events.h>
-#include <SDL_mouse.h>
-
-#include "video/drawing_context.hpp"
-#include "gui/mousecursor.hpp"
-#include "main.hpp"
-
-MouseCursor* MouseCursor::current_ = 0;
-extern SDL_Surface* screen;
-
-MouseCursor::MouseCursor(std::string cursor_file) : mid_x(0), mid_y(0)
-{
- cursor = new Surface(cursor_file);
-
- cur_state = MC_NORMAL;
-}
-
-MouseCursor::~MouseCursor()
-{
- delete cursor;
-}
-
-int MouseCursor::state()
-{
- return cur_state;
-}
-
-void MouseCursor::set_state(int nstate)
-{
- cur_state = nstate;
-}
-
-void MouseCursor::set_mid(int x, int y)
-{
- mid_x = x;
- mid_y = y;
-}
-
-void MouseCursor::draw(DrawingContext& context)
-{
- if(cur_state == MC_HIDE)
- return;
-
- int x,y,w,h;
- Uint8 ispressed = SDL_GetMouseState(&x,&y);
-
- x = int(x * float(SCREEN_WIDTH)/screen->w);
- y = int(y * float(SCREEN_HEIGHT)/screen->h);
-
- w = (int) cursor->get_width();
- h = (int) (cursor->get_height() / MC_STATES_NB);
- if(ispressed &SDL_BUTTON(1) || ispressed &SDL_BUTTON(2)) {
- if(cur_state != MC_CLICK) {
- state_before_click = cur_state;
- cur_state = MC_CLICK;
- }
- } else {
- if(cur_state == MC_CLICK)
- cur_state = state_before_click;
- }
-
- context.draw_surface_part(cursor, Vector(0, h*cur_state),
- Vector(w, h), Vector(x-mid_x, y-mid_y), LAYER_GUI+100);
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef SUPERTUX_MOUSECURSOR_H
-#define SUPERTUX_MOUSECURSOR_H
-
-#include <string>
-
-#include "video/surface.hpp"
-
-#define MC_STATES_NB 3
-
-enum {
- MC_NORMAL = 0,
- MC_CLICK,
- MC_LINK,
- MC_HIDE
-};
-
-class DrawingContext;
-
-/// Mouse cursor.
-/** Used to create mouse cursors.
- The mouse cursors can be animated
- and can be used in four different states.
- (MC_NORMAL, MC_CLICK, MC_LINK or MC_HIDE) */
-class MouseCursor
-{
-public:
- /// Constructor of MouseCursor.
- /** Expects an imagefile for the cursor and the number of animation frames it contains. */
- MouseCursor(std::string cursor_file);
- ~MouseCursor();
- /// Get MouseCursor state.
- /** (MC_NORMAL, MC_CLICK, MC_LINK or MC_HIDE) */
- int state();
- /// Set MouseCursor state.
- /** (MC_NORMAL, MC_CLICK, MC_LINK or MC_HIDE) */
- void set_state(int nstate);
- /// Define the middle of a MouseCursor.
- /** Useful for cross mouse cursor images in example. */
- void set_mid(int x, int y);
-
- /// Draw MouseCursor on screen.
- void draw(DrawingContext& context);
-
- /// Return the current cursor.
- static MouseCursor* current()
- { return current_; };
- /// Set current cursor.
- static void set_current(MouseCursor* pcursor)
- { current_ = pcursor; };
-
-private:
- int mid_x, mid_y;
- static MouseCursor* current_;
- int state_before_click;
- int cur_state;
- Surface* cursor;
-};
-
-#endif /*SUPERTUX_MOUSECURSOR_H*/
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#include <config.h>
-
-#include <map>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <iostream>
-#include <fstream>
-#include <sstream>
-#include <memory>
-#include <stdexcept>
-
-#include "log.hpp"
-#include "lisp/parser.hpp"
-#include "lisp/lisp.hpp"
-#include "lisp/list_iterator.hpp"
-#include "lisp/writer.hpp"
-#include "level.hpp"
-#include "physic.hpp"
-#include "sector.hpp"
-#include "tile.hpp"
-#include "resources.hpp"
-#include "file_system.hpp"
-#include "object/gameobjs.hpp"
-#include "object/camera.hpp"
-#include "object/tilemap.hpp"
-#include "object/coin.hpp"
-#include "object/block.hpp"
-
-using namespace std;
-
-Level::Level()
- : name("noname"), author("Mr. X")
-{
-}
-
-void
-Level::load(const std::string& filepath)
-{
- try {
- lisp::Parser parser;
- const lisp::Lisp* root = parser.parse(filepath);
-
- const lisp::Lisp* level = root->get_lisp("supertux-level");
- if(!level)
- throw std::runtime_error("file is not a supertux-level file.");
-
- int version = 1;
- level->get("version", version);
- if(version == 1) {
- load_old_format(*level);
- return;
- }
-
- contact = "";
- license = "";
-
- lisp::ListIterator iter(level);
- while(iter.next()) {
- const std::string& token = iter.item();
- if(token == "version") {
- iter.value()->get(version);
- if(version > 2) {
- log_warning << "level format newer than application" << std::endl;
- }
- } else if(token == "name") {
- iter.value()->get(name);
- } else if(token == "author") {
- iter.value()->get(author);
- } else if(token == "contact") {
- iter.value()->get(contact);
- } else if(token == "license") {
- iter.value()->get(license);
- } else if(token == "on-menukey-script") {
- iter.value()->get(on_menukey_script);
- } else if(token == "sector") {
- Sector* sector = new Sector(this);
- sector->parse(*(iter.lisp()));
- add_sector(sector);
- } else {
- log_warning << "Unknown token '" << token << "' in level file" << std::endl;
- }
- }
-
- if (license == "") log_warning << "The level author did not specify a license for this level. You might not be allowed to share it." << std::endl;
-
- } catch(std::exception& e) {
- std::stringstream msg;
- msg << "Problem when reading level '" << filepath << "': " << e.what();
- throw std::runtime_error(msg.str());
- }
-}
-
-void
-Level::load_old_format(const lisp::Lisp& reader)
-{
- reader.get("name", name);
- reader.get("author", author);
-
- Sector* sector = new Sector(this);
- sector->parse_old_format(reader);
- add_sector(sector);
-}
-
-void
-Level::save(const std::string& filename)
-{
- lisp::Writer* writer = new lisp::Writer(filename);
-
- writer->write_comment("Level made using SuperTux's built-in Level Editor");
-
- writer->start_list("supertux-level");
-
- int version = 2;
- writer->write_int("version", version);
-
- writer->write_string("name", name, true);
- writer->write_string("author", author);
- if(on_menukey_script != "")
- writer->write_string("on-menukey-script", on_menukey_script);
-
- for(Sectors::iterator i = sectors.begin(); i != sectors.end(); ++i) {
- Sector* sector = *i;
- writer->start_list("sector");
- sector->write(*writer);
- writer->end_list("sector");
- }
-
- writer->end_list("supertux-level");
-
- delete writer;
-}
-
-Level::~Level()
-{
- for(Sectors::iterator i = sectors.begin(); i != sectors.end(); ++i)
- delete *i;
-}
-
-void
-Level::add_sector(Sector* sector)
-{
- Sector* test = get_sector(sector->get_name());
- if(test != 0) {
- throw std::runtime_error("Trying to add 2 sectors with same name");
- }
- sectors.push_back(sector);
-}
-
-Sector*
-Level::get_sector(const std::string& name)
-{
- for(Sectors::iterator i = sectors.begin(); i != sectors.end(); ++i) {
- Sector* sector = *i;
- if(sector->get_name() == name)
- return sector;
- }
-
- return 0;
-}
-
-size_t
-Level::get_sector_count()
-{
- return sectors.size();
-}
-
-Sector*
-Level::get_sector(size_t num)
-{
- return sectors.at(num);
-}
-
-int
-Level::get_total_coins()
-{
- int total_coins = 0;
- for(Sectors::iterator i = sectors.begin(); i != sectors.end(); ++i) {
- Sector* sector = *i;
- for(Sector::GameObjects::iterator o = sector->gameobjects.begin();
- o != sector->gameobjects.end(); ++o) {
- Coin* coin = dynamic_cast<Coin*> (*o);
- if(coin)
- {
- total_coins++;
- continue;
- }
- BonusBlock *block = dynamic_cast<BonusBlock*> (*o);
- if(block)
- {
- if (block->contents == BonusBlock::CONTENT_COIN)
- {
- total_coins++;
- continue;
- }
-#if 0
- // FIXME: do we want this? q.v. src/object/oneup.cpp
- else if (block->contents == BonusBlock::CONTENT_1UP)
- {
- total_coins += 100;
- continue;
- }
-#endif
- }
- }
- }
- return total_coins;
-}
-
-int
-Level::get_total_badguys()
-{
- int total_badguys = 0;
- for(Sectors::iterator i = sectors.begin(); i != sectors.end(); ++i)
- total_badguys += (*i)->get_total_badguys();
- return total_badguys;
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef SUPERTUX_LEVEL_H
-#define SUPERTUX_LEVEL_H
-
-#include <vector>
-#include <string>
-#include "statistics.hpp"
-#include "sector.hpp"
-
-namespace lisp {
-class Lisp;
-}
-
-class Level
-{
-public:
- std::string name;
- std::string author;
- std::string contact;
- std::string license;
- std::string on_menukey_script;
- typedef std::vector<Sector*> Sectors;
- Sectors sectors;
- Statistics stats;
-
-public:
- Level();
- ~Level();
-
- // loads a levelfile
- void load(const std::string& filename);
- void save(const std::string& filename);
-
- const std::string& get_name() const
- { return name; }
-
- const std::string& get_author() const
- { return author; }
-
- void add_sector(Sector* sector);
-
- Sector* get_sector(const std::string& name);
-
- size_t get_sector_count();
- Sector* get_sector(size_t num);
-
- int get_total_coins();
- int get_total_badguys();
-
- /** Get total number of GameObjects of given type */
- template<class T> int get_total_count()
- {
- int total = 0;
- for(Sectors::iterator i = sectors.begin(); i != sectors.end(); ++i) {
- total += (*i)->get_total_count<T>();
- }
- return total;
- }
-
-private:
- void load_old_format(const lisp::Lisp& reader);
-};
-
-#endif /*SUPERTUX_LEVEL_H*/
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include "level_transformer.hpp"
-#include "level.hpp"
-
-LevelTransformer::~LevelTransformer()
-{
-}
-
-void
-LevelTransformer::transform(Level* level)
-{
- for(size_t i = 0; i < level->get_sector_count(); ++i) {
- transform_sector(level->get_sector(i));
- }
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __LEVEL_TRANSFORMER_H__
-#define __LEVEL_TRANSFORMER_H__
-
-class Level;
-class Sector;
-
-/**
- * This class is an abstract interface for algorithms that transform levels in
- * some way before they are played.
- */
-class LevelTransformer
-{
-public:
- virtual ~LevelTransformer();
-
- /** transform a complete Level, the standard implementation just calls
- * transformSector on each sector in the level.
- */
- virtual void transform(Level* level);
-
- virtual void transform_sector(Sector* sector) = 0;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#include <config.h>
-
-#include <sstream>
-#include <stdexcept>
-#include <iostream>
-
-#include "lexer.hpp"
-
-namespace lisp
-{
-
-class EOFException
-{
-};
-
-Lexer::Lexer(std::istream& newstream)
- : stream(newstream), eof(false), linenumber(0)
-{
- try {
- // trigger a refill of the buffer
- c = 0;
- bufend = 0;
- nextChar();
- } catch(EOFException& ) {
- }
-}
-
-Lexer::~Lexer()
-{
-}
-
-void
-Lexer::nextChar()
-{
- ++c;
- if(c >= bufend) {
- if(eof)
- throw EOFException();
- stream.read(buffer, BUFFER_SIZE);
- size_t bytes_read = stream.gcount();
-
- c = buffer;
- bufend = buffer + bytes_read;
-
- // the following is a hack that appends an additional ' ' at the end of
- // the file to avoid problems when parsing symbols/elements and a sudden
- // EOF. This is faster than relying on unget and IMO also nicer.
- if(bytes_read == 0 || stream.eof()) {
- eof = true;
- *bufend = ' ';
- ++bufend;
- }
- }
-}
-
-Lexer::TokenType
-Lexer::getNextToken()
-{
- static const char* delims = "\"();";
-
- try {
- while(isspace(*c)) {
- if(*c == '\n')
- ++linenumber;
- nextChar();
- };
-
- token_length = 0;
-
- switch(*c) {
- case ';': // comment
- while(true) {
- nextChar();
- if(*c == '\n') {
- ++linenumber;
- break;
- }
- }
- return getNextToken(); // and again
- case '(':
- nextChar();
- return TOKEN_OPEN_PAREN;
- case ')':
- nextChar();
- return TOKEN_CLOSE_PAREN;
- case '"': { // string
- int startline = linenumber;
- try {
- while(1) {
- nextChar();
- if(*c == '"')
- break;
- else if (*c == '\r') // XXX this breaks with pure \r EOL
- continue;
- else if(*c == '\n')
- linenumber++;
- else if(*c == '\\') {
- nextChar();
- switch(*c) {
- case 'n':
- *c = '\n';
- break;
- case 't':
- *c = '\t';
- break;
- }
- }
- if(token_length < MAX_TOKEN_LENGTH)
- token_string[token_length++] = *c;
- }
- token_string[token_length] = 0;
- } catch(EOFException& ) {
- std::stringstream msg;
- msg << "Parse error in line " << startline << ": "
- << "EOF while parsing string.";
- throw std::runtime_error(msg.str());
- }
- nextChar();
- return TOKEN_STRING;
- }
- case '#': // constant
- try {
- nextChar();
-
- while(isalnum(*c) || *c == '_') {
- if(token_length < MAX_TOKEN_LENGTH)
- token_string[token_length++] = *c;
- nextChar();
- }
- token_string[token_length] = 0;
- } catch(EOFException& ) {
- std::stringstream msg;
- msg << "Parse Error in line " << linenumber << ": "
- << "EOF while parsing constant.";
- throw std::runtime_error(msg.str());
- }
-
- if(strcmp(token_string, "t") == 0)
- return TOKEN_TRUE;
- if(strcmp(token_string, "f") == 0)
- return TOKEN_FALSE;
-
- // we only handle #t and #f constants at the moment...
-
- {
- std::stringstream msg;
- msg << "Parse Error in line " << linenumber << ": "
- << "Unknown constant '" << token_string << "'.";
- throw std::runtime_error(msg.str());
- }
-
- default:
- if(isdigit(*c) || *c == '-') {
- bool have_nondigits = false;
- bool have_digits = false;
- int have_floating_point = 0;
-
- do {
- if(isdigit(*c))
- have_digits = true;
- else if(*c == '.')
- ++have_floating_point;
- else if(isalnum(*c) || *c == '_')
- have_nondigits = true;
-
- if(token_length < MAX_TOKEN_LENGTH)
- token_string[token_length++] = *c;
-
- nextChar();
- } while(!isspace(*c) && !strchr(delims, *c));
-
- token_string[token_length] = 0;
-
- // no nextChar
-
- if(have_nondigits || !have_digits || have_floating_point > 1)
- return TOKEN_SYMBOL;
- else if(have_floating_point == 1)
- return TOKEN_REAL;
- else
- return TOKEN_INTEGER;
- } else {
- do {
- if(token_length < MAX_TOKEN_LENGTH)
- token_string[token_length++] = *c;
- nextChar();
- } while(!isspace(*c) && !strchr(delims, *c));
- token_string[token_length] = 0;
-
- // no nextChar
-
- return TOKEN_SYMBOL;
- }
- }
- } catch(EOFException& ) {
- return TOKEN_EOF;
- }
-}
-
-} // end of namespace lisp
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#ifndef __LISPLEXER_H__
-#define __LISPLEXER_H__
-
-namespace lisp
-{
-
-class Lexer
-{
-public:
- enum TokenType {
- TOKEN_EOF,
- TOKEN_OPEN_PAREN,
- TOKEN_CLOSE_PAREN,
- TOKEN_SYMBOL,
- TOKEN_STRING,
- TOKEN_INTEGER,
- TOKEN_REAL,
- TOKEN_TRUE,
- TOKEN_FALSE
- };
-
- Lexer(std::istream& stream);
- ~Lexer();
-
- TokenType getNextToken();
- const char* getString() const
- { return token_string; }
- int getLineNumber() const
- { return linenumber; }
-
-private:
- enum {
- MAX_TOKEN_LENGTH = 16384,
- BUFFER_SIZE = 1024
- };
-
- inline void nextChar();
-
- std::istream& stream;
- bool eof;
- int linenumber;
- char buffer[BUFFER_SIZE+1];
- char* bufend;
- char* c;
- char token_string[MAX_TOKEN_LENGTH + 1];
- int token_length;
-};
-
-} // end of namespace lisp
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include "lisp.hpp"
-
-namespace lisp
-{
-
-Lisp::Lisp(LispType newtype)
- : type(newtype)
-{
-}
-
-Lisp::~Lisp()
-{
- // resources should be on parser obstack, so no need to delete anything
-}
-
-const Lisp*
-Lisp::get_lisp(const char* name) const
-{
- for(const Lisp* p = this; p != 0; p = p->get_cdr()) {
- const Lisp* child = p->get_car();
- if(!child || child->get_type() != TYPE_CONS)
- continue;
- const Lisp* childname = child->get_car();
- if(!childname)
- continue;
- std::string childName;
- if(!childname->get(childName))
- continue;
- if(childName == name) {
- return child->get_cdr();
- }
- }
-
- return 0;
-}
-
-void
-Lisp::print(int indent) const
-{
- for(int i = 0; i < indent; ++i)
- printf(" ");
-
- if(type == TYPE_CONS) {
- printf("(\n");
- const Lisp* lisp = this;
- while(lisp) {
- if(lisp->v.cons.car)
- lisp->v.cons.car->print(indent + 1);
- lisp = lisp->v.cons.cdr;
- }
- for(int i = 0; i < indent; ++i)
- printf(" ");
- printf(")");
- }
- if(type == TYPE_STRING) {
- printf("'%s' ", v.string);
- }
- if(type == TYPE_INTEGER) {
- printf("%d", v.integer);
- }
- if(type == TYPE_REAL) {
- printf("%f", v.real);
- }
- if(type == TYPE_SYMBOL) {
- printf("%s ", v.string);
- }
- if(type == TYPE_BOOLEAN) {
- printf("%s ", v.boolean ? "true" : "false");
- }
- printf("\n");
-}
-
-} // end of namespace lisp
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __LISPREADER_H__
-#define __LISPREADER_H__
-
-#include <string>
-#include <vector>
-#include <assert.h>
-
-namespace lisp
-{
-
-class Lisp
-{
-public:
- ~Lisp();
-
- enum LispType {
- TYPE_CONS,
- TYPE_SYMBOL,
- TYPE_INTEGER,
- TYPE_STRING,
- TYPE_REAL,
- TYPE_BOOLEAN
- };
-
- LispType get_type() const
- { return type; }
-
- const Lisp* get_car() const
- { return v.cons.car; }
- const Lisp* get_cdr() const
- { return v.cons.cdr; }
-
- bool get(std::string& val) const
- {
- if(type != TYPE_STRING && type != TYPE_SYMBOL)
- return false;
- val = v.string;
- return true;
- }
-
- std::string get_symbol() const
- {
- assert(type == TYPE_SYMBOL);
- return v.string;
- }
-
- std::string get_string() const
- {
- assert(type == TYPE_STRING);
- return v.string;
- }
-
- bool get(unsigned int& val) const
- {
- if(type != TYPE_INTEGER)
- return false;
- val = v.integer;
- return true;
- }
-
- bool get(int& val) const
- {
- if(type != TYPE_INTEGER)
- return false;
- val = v.integer;
- return true;
- }
-
- int get_int() const
- {
- assert(type == TYPE_INTEGER);
- return v.integer;
- }
-
- bool get(float& val) const
- {
- if(type != TYPE_REAL) {
- if(type == TYPE_INTEGER) {
- val = (float) v.integer;
- return true;
- }
- return false;
- }
- val = v.real;
- return true;
- }
-
- float get_float() const
- {
- assert(type == TYPE_REAL);
- return v.real;
- }
-
- bool get(bool& val) const
- {
- if(type != TYPE_BOOLEAN)
- return false;
- val = v.boolean;
- return true;
- }
-
- bool get_bool() const
- {
- assert(type == TYPE_BOOLEAN);
- return v.boolean;
- }
-
- /** conveniance functions which traverse the list until a child with a
- * specified name is found. The value part is then interpreted in a specific
- * way. The functions return true, if a child was found and could be
- * interpreted correctly, otherwise false is returned and the variable value
- * is not changed.
- * (Please note that searching the lisp structure is O(n) so these functions
- * are no good idea for performance critical areas)
- */
- template<class T>
- bool get(const char* name, T& val) const
- {
- const Lisp* lisp = get_lisp(name);
- if(!lisp)
- return false;
-
- if(lisp->get_type() != TYPE_CONS)
- return false;
- lisp = lisp->get_car();
- if(!lisp)
- return false;
- return lisp->get(val);
- }
-
- template<class T>
- bool get_vector(const char* name, std::vector<T>& vec) const
- {
- vec.clear();
-
- const Lisp* child = get_lisp(name);
- if(!child)
- return false;
-
- for( ; child != 0; child = child->get_cdr()) {
- T val;
- if(!child->get_car())
- continue;
- if(child->get_car()->get(val)) {
- vec.push_back(val);
- }
- }
-
- return true;
- }
-
- const Lisp* get_lisp(const char* name) const;
- const Lisp* get_lisp(const std::string& name) const
- { return get_lisp(name.c_str()); }
-
- // for debugging
- void print(int indent = 0) const;
-
-private:
- friend class Parser;
- Lisp(LispType newtype);
-
- LispType type;
- union
- {
- struct
- {
- const Lisp* car;
- const Lisp* cdr;
- } cons;
-
- char* string;
- int integer;
- bool boolean;
- float real;
- } v;
-};
-
-} // end of namespace lisp
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include "list_iterator.hpp"
-#include <stdexcept>
-
-namespace lisp
-{
-
-ListIterator::ListIterator(const lisp::Lisp* newlisp)
- : current_lisp(0), cur(newlisp)
-{
-}
-
-bool
-ListIterator::next()
-{
- if(cur == 0)
- return false;
-
- const lisp::Lisp* child = cur->get_car();
- if(!child)
- throw std::runtime_error("child is 0 in list entry");
- if(child->get_type() != lisp::Lisp::TYPE_CONS)
- throw std::runtime_error("Expected CONS");
- const lisp::Lisp* name = child->get_car();
- if(!name || (
- name->get_type() != lisp::Lisp::TYPE_SYMBOL
- && name->get_type() != lisp::Lisp::TYPE_STRING))
- throw std::runtime_error("Expected symbol");
- name->get(current_item);
- current_lisp = child->get_cdr();
-
- cur = cur->get_cdr();
- return true;
-}
-
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __LISP_ITERATOR_H__
-#define __LISP_ITERATOR_H__
-
-#include "lisp/lisp.hpp"
-
-namespace lisp
-{
-
-/**
- * Small and a bit hacky helper class that helps parsing lisp lists where all
- * entries are lists again themselves
- */
-class ListIterator
-{
-public:
- ListIterator(const lisp::Lisp* cur);
-
- const std::string& item() const
- { return current_item; }
- const lisp::Lisp* lisp() const
- { return current_lisp; }
- const lisp::Lisp* value() const
- { return current_lisp->get_car(); }
- bool next();
-
-private:
- std::string current_item;
- const lisp::Lisp* current_lisp;
- const lisp::Lisp* cur;
-};
-
-}
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#include <config.h>
-
-#include <sstream>
-#include <stdexcept>
-#include <fstream>
-#include <cassert>
-#include <iostream>
-
-#include "tinygettext/tinygettext.hpp"
-#include "physfs/physfs_stream.hpp"
-#include "parser.hpp"
-#include "lisp.hpp"
-#include "obstack/obstackpp.hpp"
-
-#include "gameconfig.hpp"
-
-namespace lisp
-{
-
-Parser::Parser(bool translate)
- : lexer(0), dictionary_manager(0), dictionary(0)
-{
- if(translate) {
- dictionary_manager = new TinyGetText::DictionaryManager();
- dictionary_manager->set_charset("UTF-8");
- if (config && (config->locale != "")) dictionary_manager->set_language(config->locale);
- }
-
- obstack_init(&obst);
-}
-
-Parser::~Parser()
-{
- obstack_free(&obst, NULL);
- delete lexer;
- delete dictionary_manager;
-}
-
-static std::string dirname(const std::string& filename)
-{
- std::string::size_type p = filename.find_last_of('/');
- if(p == std::string::npos)
- return "";
-
- return filename.substr(0, p+1);
-}
-
-const Lisp*
-Parser::parse(const std::string& filename)
-{
- IFileStreambuf ins(filename);
- std::istream in(&ins);
-
- if(!in.good()) {
- std::stringstream msg;
- msg << "Parser problem: Couldn't open file '" << filename << "'.";
- throw std::runtime_error(msg.str());
- }
-
- if(dictionary_manager) {
- dictionary_manager->add_directory(dirname(filename));
- dictionary = & (dictionary_manager->get_dictionary());
- }
-
- return parse(in, filename);
-}
-
-const Lisp*
-Parser::parse(std::istream& stream, const std::string& sourcename)
-{
- delete lexer;
- lexer = new Lexer(stream);
-
- this->filename = sourcename;
- token = lexer->getNextToken();
-
- Lisp* result = new(obst) Lisp(Lisp::TYPE_CONS);
- result->v.cons.car = read();
- result->v.cons.cdr = 0;
-
- delete lexer;
- lexer = 0;
-
- return result;
-}
-
-void
-Parser::parse_error(const char* msg) const
-{
- std::stringstream emsg;
- emsg << "Parse Error at '" << filename << "' line " << lexer->getLineNumber()
- << ": " << msg;
- throw std::runtime_error(emsg.str());
-}
-
-const Lisp*
-Parser::read()
-{
- Lisp* result;
- switch(token) {
- case Lexer::TOKEN_EOF: {
- parse_error("Unexpected EOF.");
- }
- case Lexer::TOKEN_CLOSE_PAREN: {
- parse_error("Unexpected ')'.");
- }
- case Lexer::TOKEN_OPEN_PAREN: {
- result = new(obst) Lisp(Lisp::TYPE_CONS);
-
- token = lexer->getNextToken();
- if(token == Lexer::TOKEN_CLOSE_PAREN) {
- result->v.cons.car = 0;
- result->v.cons.cdr = 0;
- break;
- }
-
- if(token == Lexer::TOKEN_SYMBOL &&
- strcmp(lexer->getString(), "_") == 0) {
- // evaluate translation function (_ str) in place here
- token = lexer->getNextToken();
- if(token != Lexer::TOKEN_STRING)
- parse_error("Expected string after '(_'");
-
- result = new(obst) Lisp(Lisp::TYPE_STRING);
- if(dictionary) {
- std::string translation = dictionary->translate(lexer->getString());
- result->v.string = new(obst) char[translation.size()+1];
- memcpy(result->v.string, translation.c_str(), translation.size()+1);
- } else {
- size_t len = strlen(lexer->getString()) + 1;
- result->v.string = new(obst) char[len];
- memcpy(result->v.string, lexer->getString(), len);
- }
- token = lexer->getNextToken();
- if(token != Lexer::TOKEN_CLOSE_PAREN)
- parse_error("Expected ')' after '(_ string'");
- break;
- }
-
- Lisp* cur = result;
- do {
- cur->v.cons.car = read();
- if(token == Lexer::TOKEN_CLOSE_PAREN) {
- cur->v.cons.cdr = 0;
- break;
- }
- Lisp *newcur = new(obst) Lisp(Lisp::TYPE_CONS);
- cur->v.cons.cdr = newcur;
- cur = newcur;
- } while(1);
-
- break;
- }
- case Lexer::TOKEN_SYMBOL: {
- result = new(obst) Lisp(Lisp::TYPE_SYMBOL);
- size_t len = strlen(lexer->getString()) + 1;
- result->v.string = new(obst) char[len];
- memcpy(result->v.string, lexer->getString(), len);
- break;
- }
- case Lexer::TOKEN_STRING: {
- result = new(obst) Lisp(Lisp::TYPE_STRING);
- size_t len = strlen(lexer->getString()) + 1;
- result->v.string = new(obst) char[len];
- memcpy(result->v.string, lexer->getString(), len);
- break;
- }
- case Lexer::TOKEN_INTEGER:
- result = new(obst) Lisp(Lisp::TYPE_INTEGER);
- sscanf(lexer->getString(), "%d", &result->v.integer);
- break;
- case Lexer::TOKEN_REAL:
- result = new(obst) Lisp(Lisp::TYPE_REAL);
- sscanf(lexer->getString(), "%f", &result->v.real);
- break;
- case Lexer::TOKEN_TRUE:
- result = new(obst) Lisp(Lisp::TYPE_BOOLEAN);
- result->v.boolean = true;
- break;
- case Lexer::TOKEN_FALSE:
- result = new(obst) Lisp(Lisp::TYPE_BOOLEAN);
- result->v.boolean = false;
- break;
-
- default:
- // this should never happen
- assert(false);
- }
-
- token = lexer->getNextToken();
- return result;
-}
-
-} // end of namespace lisp
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __LISPPARSER_H__
-#define __LISPPARSER_H__
-
-#include <string>
-#include "lexer.hpp"
-#include "obstack/obstack.h"
-
-namespace TinyGetText {
-class Dictionary;
-class DictionaryManager;
-}
-
-namespace lisp
-{
-
-class Lisp;
-class LispFile;
-
-class Parser
-{
-public:
- Parser(bool translate = true);
- ~Parser();
-
- /**
- * Parses a lispfile and returns the s-expression structure.
- * Note that all memory is held by the parser so don't destroy the parser
- * before you are finished with the lisp tree
- */
- const Lisp* parse(const std::string& filename);
- /**
- * Same as parse but reads from a generic std::istream. The sourcename is
- * used for errormessages to indicate the source of the data.
- */
- const Lisp* parse(std::istream& stream, const std::string& sourcename);
-
-private:
- void parse_error(const char* msg) const;
- const Lisp* read();
-
- Lexer* lexer;
- std::string filename;
- TinyGetText::DictionaryManager* dictionary_manager;
- TinyGetText::Dictionary* dictionary;
- Lexer::TokenType token;
-
- struct obstack obst;
-};
-
-} // end of namespace lisp
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include <iostream>
-
-#include "writer.hpp"
-#include "physfs/physfs_stream.hpp"
-#include "log.hpp"
-
-namespace lisp
-{
-
-Writer::Writer(const std::string& filename)
-{
- out = new OFileStream(filename);
- out_owned = true;
- indent_depth = 0;
- out->precision(10);
-}
-
-Writer::Writer(std::ostream* newout)
-{
- out = newout;
- out_owned = false;
- indent_depth = 0;
- out->precision(10);
-}
-
-Writer::~Writer()
-{
- if(lists.size() > 0) {
- log_warning << "Not all sections closed in lispwriter" << std::endl;
- }
- if(out_owned)
- delete out;
-}
-
-void
-Writer::write_comment(const std::string& comment)
-{
- *out << "; " << comment << "\n";
-}
-
-void
-Writer::start_list(const std::string& listname, bool string)
-{
- indent();
- *out << '(';
- if(string)
- write_escaped_string(listname);
- else
- *out << listname;
- *out << '\n';
- indent_depth += 2;
-
- lists.push_back(listname);
-}
-
-void
-Writer::end_list(const std::string& listname)
-{
- if(lists.size() == 0) {
- log_warning << "Trying to close list '" << listname << "', which is not open" << std::endl;
- return;
- }
- if(lists.back() != listname) {
- log_warning << "trying to close list '" << listname << "' while list '" << lists.back() << "' is open" << std::endl;
- return;
- }
- lists.pop_back();
-
- indent_depth -= 2;
- indent();
- *out << ")\n";
-}
-
-void
-Writer::write_int(const std::string& name, int value)
-{
- indent();
- *out << '(' << name << ' ' << value << ")\n";
-}
-
-void
-Writer::write_float(const std::string& name, float value)
-{
- indent();
- *out << '(' << name << ' ' << value << ")\n";
-}
-
-void
-Writer::write_string(const std::string& name, const std::string& value,
- bool translatable)
-{
- indent();
- *out << '(' << name;
- if(translatable) {
- *out << " (_ ";
- write_escaped_string(value);
- *out << "))\n";
- } else {
- *out << " ";
- write_escaped_string(value);
- *out << ")\n";
- }
-}
-
-void
-Writer::write_bool(const std::string& name, bool value)
-{
- indent();
- *out << '(' << name << ' ' << (value ? "#t" : "#f") << ")\n";
-}
-
-void
-Writer::write_int_vector(const std::string& name,
- const std::vector<int>& value)
-{
- indent();
- *out << '(' << name;
- for(std::vector<int>::const_iterator i = value.begin(); i != value.end(); ++i)
- *out << " " << *i;
- *out << ")\n";
-}
-
-void
-Writer::write_int_vector(const std::string& name,
- const std::vector<unsigned int>& value)
-{
- indent();
- *out << '(' << name;
- for(std::vector<unsigned int>::const_iterator i = value.begin(); i != value.end(); ++i)
- *out << " " << *i;
- *out << ")\n";
-}
-
-void
-Writer::write_float_vector(const std::string& name,
- const std::vector<float>& value)
-{
- indent();
- *out << '(' << name;
- for(std::vector<float>::const_iterator i = value.begin(); i != value.end(); ++i)
- *out << " " << *i;
- *out << ")\n";
-}
-
-void
-Writer::write_escaped_string(const std::string& str)
-{
- *out << '"';
- for(const char* c = str.c_str(); *c != 0; ++c) {
- if(*c == '\"')
- *out << "\\\"";
- else if(*c == '\\')
- *out << "\\\\";
- else
- *out << *c;
- }
- *out << '"';
-}
-
-void
-Writer::indent()
-{
- for(int i = 0; i<indent_depth; ++i)
- *out << ' ';
-}
-
-} // end of namespace lisp
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef SUPERTUX_LISPWRITER_H
-#define SUPERTUX_LISPWRITER_H
-
-#include <iostream>
-#include <string>
-#include <vector>
-
-namespace lisp
-{
-
- class Writer
- {
- public:
- Writer(const std::string& filename);
- Writer(std::ostream* out);
- ~Writer();
-
- void write_comment(const std::string& comment);
-
- void start_list(const std::string& listname, bool string = false);
-
- void write_int(const std::string& name, int value);
- void write_float(const std::string& name, float value);
- void write_string(const std::string& name, const std::string& value,
- bool translatable = false);
- void write_bool(const std::string& name, bool value);
- void write_int_vector(const std::string& name, const std::vector<int>& value);
- void write_int_vector(const std::string& name, const std::vector<unsigned int>& value);
- void write_float_vector(const std::string& name, const std::vector<float>& value);
- // add more write-functions when needed...
-
- void end_list(const std::string& listname);
-
- private:
- void write_escaped_string(const std::string& str);
- void indent();
-
- std::ostream* out;
- bool out_owned;
- int indent_depth;
- std::vector<std::string> lists;
- };
-
-} //namespace lisp
-
-#endif //SUPERTUX_LISPWRITER_H
+++ /dev/null
-// $Id$
-//
-// SuperTux Debug Helper Functions
-// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
-//
-// 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.
-#include <config.h>
-
-#include "log.hpp"
-#include "math/vector.hpp"
-#include "math/rect.hpp"
-
-std::ostream& operator<<(std::ostream& out, const Vector& vector)
-{
- out << '[' << vector.x << ',' << vector.y << ']';
- return out;
-}
-
-std::ostream& operator<<(std::ostream& out, const Rect& rect)
-{
- out << "[" << rect.get_left() << "," << rect.get_top() << " "
- << rect.get_right() << "," << rect.get_bottom() << "]";
- return out;
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux Debug Helper Functions
-// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
-//
-// 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.
-#ifndef __SUPERTUX_MSG_H__
-#define __SUPERTUX_MSG_H__
-
-#include <iostream>
-#include <stdio.h>
-
-#include "console.hpp"
-
-#ifdef DEBUG
-
-namespace {
-
-inline std::ostream& log_debug_f(const char* file, int line) {
- Console::output << "[DEBUG] " << file << ":" << line << " ";
- return Console::output;
-}
-
-inline std::ostream& log_info_f(const char* file, int line) {
- Console::output << "[INFO] " << file << ":" << line << " ";
- return Console::output;
-}
-
-inline std::ostream& log_warning_f(const char* file, int line) {
- Console::output << "[WARNING] " << file << ":" << line << " ";
- return Console::output;
-}
-
-inline std::ostream& log_fatal_f(const char* file, int line) {
- Console::output << "[FATAL] " << file << ":" << line << " ";
- return Console::output;
-}
-
-}
-
-#define log_debug log_debug_f(__FILE__, __LINE__)
-#define log_info log_info_f(__FILE__, __LINE__)
-#define log_warning log_warning_f(__FILE__, __LINE__)
-#define log_fatal log_fatal_f(__FILE__, __LINE__)
-
-#else
-
-namespace {
-
-inline std::ostream& log_warning_f() {
- Console::output << "Warning: ";
- return Console::output;
-}
-
-inline std::ostream& log_fatal_f() {
- Console::output << "Fatal: ";
- return Console::output;
-}
-
-}
-
-#define log_debug if (0) std::cerr
-#define log_info std::cout
-#define log_warning log_warning_f()
-#define log_fatal log_fatal_f()
-
-#endif
-
-class Vector;
-std::ostream& operator<< (std::ostream& str, const Vector& vector);
-class Rect;
-std::ostream& operator<< (std::ostream& str, const Rect& rect);
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#include <config.h>
-#include <assert.h>
-
-#include "log.hpp"
-#include "main.hpp"
-
-#include <stdexcept>
-#include <sstream>
-#include <ctime>
-#include <cstdlib>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <unistd.h>
-#include <physfs.h>
-#include <SDL.h>
-#include <SDL_image.h>
-
-#ifdef MACOSX
-namespace supertux_apple {
-#include <CoreFoundation/CoreFoundation.h>
-}
-#endif
-
-#include "gameconfig.hpp"
-#include "resources.hpp"
-#include "gettext.hpp"
-#include "audio/sound_manager.hpp"
-#include "video/surface.hpp"
-#include "video/texture_manager.hpp"
-#include "video/drawing_context.hpp"
-#include "video/glutil.hpp"
-#include "control/joystickkeyboardcontroller.hpp"
-#include "options_menu.hpp"
-#include "mainloop.hpp"
-#include "title.hpp"
-#include "game_session.hpp"
-#include "scripting/level.hpp"
-#include "scripting/squirrel_util.hpp"
-#include "file_system.hpp"
-#include "physfs/physfs_sdl.hpp"
-#include "random_generator.hpp"
-#include "worldmap/worldmap.hpp"
-#include "binreloc/binreloc.h"
-
-namespace { DrawingContext *context_pointer; }
-SDL_Surface *screen;
-JoystickKeyboardController* main_controller = 0;
-TinyGetText::DictionaryManager dictionary_manager;
-
-int SCREEN_WIDTH;
-int SCREEN_HEIGHT;
-
-static void init_config()
-{
- config = new Config();
- try {
- config->load();
- } catch(std::exception& e) {
- log_info << "Couldn't load config file: " << e.what() << ", using default settings" << std::endl;
- }
-}
-
-static void init_tinygettext()
-{
- dictionary_manager.add_directory("locale");
- dictionary_manager.set_charset("UTF-8");
-
- // Config setting "locale" overrides language detection
- if (config->locale != "") {
- dictionary_manager.set_language( config->locale );
- }
-}
-
-static void init_physfs(const char* argv0)
-{
- if(!PHYSFS_init(argv0)) {
- std::stringstream msg;
- msg << "Couldn't initialize physfs: " << PHYSFS_getLastError();
- throw std::runtime_error(msg.str());
- }
-
- // Initialize physfs (this is a slightly modified version of
- // PHYSFS_setSaneConfig
- const char* application = "supertux2"; //instead of PACKAGE_NAME so we can coexist with MS1
- const char* userdir = PHYSFS_getUserDir();
- const char* dirsep = PHYSFS_getDirSeparator();
- char* writedir = new char[strlen(userdir) + strlen(application) + 2];
-
- // Set configuration directory
- sprintf(writedir, "%s.%s", userdir, application);
- if(!PHYSFS_setWriteDir(writedir)) {
- // try to create the directory
- char* mkdir = new char[strlen(application) + 2];
- sprintf(mkdir, ".%s", application);
- if(!PHYSFS_setWriteDir(userdir) || !PHYSFS_mkdir(mkdir)) {
- std::ostringstream msg;
- msg << "Failed creating configuration directory '"
- << writedir << "': " << PHYSFS_getLastError();
- delete[] writedir;
- delete[] mkdir;
- throw std::runtime_error(msg.str());
- }
- delete[] mkdir;
-
- if(!PHYSFS_setWriteDir(writedir)) {
- std::ostringstream msg;
- msg << "Failed to use configuration directory '"
- << writedir << "': " << PHYSFS_getLastError();
- delete[] writedir;
- throw std::runtime_error(msg.str());
- }
- }
- PHYSFS_addToSearchPath(writedir, 0);
- delete[] writedir;
-
- // Search for archives and add them to the search path
- const char* archiveExt = "zip";
- char** rc = PHYSFS_enumerateFiles("/");
- size_t extlen = strlen(archiveExt);
-
- for(char** i = rc; *i != 0; ++i) {
- size_t l = strlen(*i);
- if((l > extlen) && ((*i)[l - extlen - 1] == '.')) {
- const char* ext = (*i) + (l - extlen);
- if(strcasecmp(ext, archiveExt) == 0) {
- const char* d = PHYSFS_getRealDir(*i);
- char* str = new char[strlen(d) + strlen(dirsep) + l + 1];
- sprintf(str, "%s%s%s", d, dirsep, *i);
- PHYSFS_addToSearchPath(str, 1);
- delete[] str;
- }
- }
- }
-
- PHYSFS_freeList(rc);
-
- // when started from source dir...
- std::string dir = PHYSFS_getBaseDir();
- dir += "/data";
- std::string testfname = dir;
- testfname += "/credits.txt";
- bool sourcedir = false;
- FILE* f = fopen(testfname.c_str(), "r");
- if(f) {
- fclose(f);
- if(!PHYSFS_addToSearchPath(dir.c_str(), 1)) {
- log_warning << "Couldn't add '" << dir << "' to physfs searchpath: " << PHYSFS_getLastError() << std::endl;
- } else {
- sourcedir = true;
- }
- }
-
-#ifdef MACOSX
-{
- using namespace supertux_apple;
-
- // when started from Application file on Mac OS X...
- char path[PATH_MAX];
- CFBundleRef mainBundle = CFBundleGetMainBundle();
- assert(mainBundle != 0);
- CFURLRef mainBundleURL = CFBundleCopyBundleURL(mainBundle);
- assert(mainBundleURL != 0);
- CFStringRef pathStr = CFURLCopyFileSystemPath(mainBundleURL, kCFURLPOSIXPathStyle);
- assert(pathStr != 0);
- CFStringGetCString(pathStr, path, PATH_MAX, kCFStringEncodingUTF8);
- CFRelease(mainBundleURL);
- CFRelease(pathStr);
-
- dir = std::string(path) + "/Contents/Resources/data";
- testfname = dir + "/credits.txt";
- sourcedir = false;
- f = fopen(testfname.c_str(), "r");
- if(f) {
- fclose(f);
- if(!PHYSFS_addToSearchPath(dir.c_str(), 1)) {
- log_warning << "Couldn't add '" << dir << "' to physfs searchpath: " << PHYSFS_getLastError() << std::endl;
- } else {
- sourcedir = true;
- }
- }
-}
-#endif
-
-#ifdef _WIN32
- PHYSFS_addToSearchPath(".\\data", 1);
-#endif
-
- if(!sourcedir) {
-#if defined(APPDATADIR) || defined(ENABLE_BINRELOC)
- std::string datadir;
-#ifdef ENABLE_BINRELOC
-
- char* dir;
- br_init (NULL);
- dir = br_find_data_dir(APPDATADIR);
- datadir = dir;
- free(dir);
-
-#else
- datadir = APPDATADIR;
-#endif
- datadir += "/";
- datadir += application;
- if(!PHYSFS_addToSearchPath(datadir.c_str(), 1)) {
- log_warning << "Couldn't add '" << datadir << "' to physfs searchpath: " << PHYSFS_getLastError() << std::endl;
- }
-#endif
- }
-
- // allow symbolic links
- PHYSFS_permitSymbolicLinks(1);
-
- //show search Path
- char** searchpath = PHYSFS_getSearchPath();
- for(char** i = searchpath; *i != NULL; i++)
- log_info << "[" << *i << "] is in the search path" << std::endl;
- PHYSFS_freeList(searchpath);
-}
-
-static void print_usage(const char* argv0)
-{
- fprintf(stderr, _("Usage: %s [OPTIONS] [LEVELFILE]\n\n"), argv0);
- fprintf(stderr,
- _("Options:\n"
- " -f, --fullscreen Run in fullscreen mode\n"
- " -w, --window Run in window mode\n"
- " -g, --geometry WIDTHxHEIGHT Run SuperTux in given resolution\n"
- " -a, --aspect WIDTH:HEIGHT Run SuperTux with given aspect ratio\n"
- " --disable-sfx Disable sound effects\n"
- " --disable-music Disable music\n"
- " --help Show this help message\n"
- " --version Display SuperTux version and quit\n"
- " --console Enable ingame scripting console\n"
- " --noconsole Disable ingame scripting console\n"
- " --show-fps Display framerate in levels\n"
- " --no-show-fps Do not display framerate in levels\n"
- " --record-demo FILE LEVEL Record a demo to FILE\n"
- " --play-demo FILE LEVEL Play a recorded demo\n"
- "\n"));
-}
-
-/**
- * Options that should be evaluated prior to any initializations at all go here
- */
-static bool pre_parse_commandline(int argc, char** argv)
-{
- for(int i = 1; i < argc; ++i) {
- std::string arg = argv[i];
-
- if(arg == "--version") {
- std::cout << PACKAGE_NAME << " " << PACKAGE_VERSION << std::endl;
- return true;
- }
- }
-
- return false;
-}
-
-/**
- * Options that should be evaluated after config is read go here
- */
-static bool parse_commandline(int argc, char** argv)
-{
- for(int i = 1; i < argc; ++i) {
- std::string arg = argv[i];
-
- if(arg == "--help") {
- print_usage(argv[0]);
- return true;
- } else if(arg == "--fullscreen" || arg == "-f") {
- config->use_fullscreen = true;
- } else if(arg == "--window" || arg == "-w") {
- config->use_fullscreen = false;
- } else if(arg == "--geometry" || arg == "-g") {
- if(i+1 >= argc) {
- print_usage(argv[0]);
- throw std::runtime_error("Need to specify a parameter for geometry switch");
- }
- if(sscanf(argv[++i], "%dx%d", &config->screenwidth, &config->screenheight)
- != 2) {
- print_usage(argv[0]);
- throw std::runtime_error("Invalid geometry spec, should be WIDTHxHEIGHT");
- }
- } else if(arg == "--aspect" || arg == "-a") {
- if(i+1 >= argc) {
- print_usage(argv[0]);
- throw std::runtime_error("Need to specify a parameter for aspect switch");
- }
- if(strcasecmp(argv[i+1], "auto") == 0) {
- i++;
- config->aspect_ratio = -1;
- } else {
- int aspect_width, aspect_height;
- if(sscanf(argv[++i], "%d:%d", &aspect_width, &aspect_height) != 2) {
- print_usage(argv[0]);
- throw std::runtime_error("Invalid aspect spec, should be WIDTH:HEIGHT");
- }
- config->aspect_ratio = static_cast<double>(aspect_width) /
- static_cast<double>(aspect_height);
- }
- } else if(arg == "--show-fps") {
- config->show_fps = true;
- } else if(arg == "--no-show-fps") {
- config->show_fps = false;
- } else if(arg == "--console") {
- config->console_enabled = true;
- } else if(arg == "--noconsole") {
- config->console_enabled = false;
- } else if(arg == "--disable-sfx") {
- config->sound_enabled = false;
- } else if(arg == "--disable-music") {
- config->music_enabled = false;
- } else if(arg == "--play-demo") {
- if(i+1 >= argc) {
- print_usage(argv[0]);
- throw std::runtime_error("Need to specify a demo filename");
- }
- config->start_demo = argv[++i];
- } else if(arg == "--record-demo") {
- if(i+1 >= argc) {
- print_usage(argv[0]);
- throw std::runtime_error("Need to specify a demo filename");
- }
- config->record_demo = argv[++i];
- } else if(arg == "-d") {
- config->enable_script_debugger = true;
- } else if(arg[0] != '-') {
- config->start_level = arg;
- } else {
- log_warning << "Unknown option '" << arg << "'. Use --help to see a list of options" << std::endl;
- return true;
- }
- }
-
- return false;
-}
-
-static void init_sdl()
-{
- if(SDL_Init(SDL_INIT_TIMER | SDL_INIT_VIDEO | SDL_INIT_JOYSTICK) < 0) {
- std::stringstream msg;
- msg << "Couldn't initialize SDL: " << SDL_GetError();
- throw std::runtime_error(msg.str());
- }
- // just to be sure
- atexit(SDL_Quit);
-
- SDL_EnableUNICODE(1);
-
- // wait 100ms and clear SDL event queue because sometimes we have random
- // joystick events in the queue on startup...
- SDL_Delay(100);
- SDL_Event dummy;
- while(SDL_PollEvent(&dummy))
- ;
-}
-
-static void init_rand()
-{
- config->random_seed = systemRandom.srand(config->random_seed);
-
- //const char *how = config->random_seed? ", user fixed.": ", from time().";
- //log_info << "Using random seed " << config->random_seed << how << std::endl;
-}
-
-void init_video()
-{
- static int desktop_width = 0;
- static int desktop_height = 0;
-
-/* unfortunately only newer SDLs have these infos */
-#if SDL_MAJOR_VERSION > 1 || SDL_MINOR_VERSION > 2 || (SDL_MINOR_VERSION == 2 && SDL_PATCHLEVEL >= 10)
- /* find which resolution the user normally uses */
- if(desktop_width == 0) {
- const SDL_VideoInfo *info = SDL_GetVideoInfo();
- desktop_width = info->current_w;
- desktop_height = info->current_h;
- }
-#endif
-
- double aspect_ratio = config->aspect_ratio;
-
- // try to guess aspect ratio of monitor if needed
- if (aspect_ratio <= 0) {
-// TODO: commented out because
-// 1) it tends to guess wrong if widescreen-monitors don't stretch 800x600 to fit, but just display black borders
-// 2) aspect ratios other than 4:3 are largely untested
-/*
- if(config->use_fullscreen && desktop_width > 0) {
- aspect_ratio = static_cast<double>(desktop_width) / static_cast<double>(desktop_height);
- } else {
-*/
- aspect_ratio = 4.0 / 3.0;
-/*
- }
-*/
- }
-
- // use aspect ratio to calculate logical resolution
- if (aspect_ratio > 1) {
- SCREEN_WIDTH = static_cast<int> (600 * aspect_ratio + 0.5);
- SCREEN_HEIGHT = 600;
- } else {
- SCREEN_WIDTH = 600;
- SCREEN_HEIGHT = static_cast<int> (600 * 1/aspect_ratio + 0.5);
- }
-
- context_pointer->init_renderer();
- screen = SDL_GetVideoSurface();
-
- SDL_WM_SetCaption(PACKAGE_NAME " " PACKAGE_VERSION, 0);
-
- // set icon
- SDL_Surface* icon = IMG_Load_RW(
- get_physfs_SDLRWops("images/engine/icons/supertux.xpm"), true);
- if(icon != 0) {
- SDL_WM_SetIcon(icon, 0);
- SDL_FreeSurface(icon);
- }
-#ifdef DEBUG
- else {
- log_warning << "Couldn't find icon 'images/engine/icons/supertux.xpm'" << std::endl;
- }
-#endif
-
- SDL_ShowCursor(0);
-
- log_info << (config->use_fullscreen?"fullscreen ":"window ") << SCREEN_WIDTH << "x" << SCREEN_HEIGHT << " Ratio: " << aspect_ratio << "\n";
-}
-
-static void init_audio()
-{
- sound_manager = new SoundManager();
-
- sound_manager->enable_sound(config->sound_enabled);
- sound_manager->enable_music(config->music_enabled);
-}
-
-static void quit_audio()
-{
- if(sound_manager != NULL) {
- delete sound_manager;
- sound_manager = NULL;
- }
-}
-
-void wait_for_event(float min_delay, float max_delay)
-{
- assert(min_delay <= max_delay);
-
- Uint32 min = (Uint32) (min_delay * 1000);
- Uint32 max = (Uint32) (max_delay * 1000);
-
- Uint32 ticks = SDL_GetTicks();
- while(SDL_GetTicks() - ticks < min) {
- SDL_Delay(10);
- sound_manager->update();
- }
-
- // clear event queue
- SDL_Event event;
- while (SDL_PollEvent(&event))
- {}
-
- /* Handle events: */
- bool running = false;
- ticks = SDL_GetTicks();
- while(running) {
- while(SDL_PollEvent(&event)) {
- switch(event.type) {
- case SDL_QUIT:
- main_loop->quit();
- break;
- case SDL_KEYDOWN:
- case SDL_JOYBUTTONDOWN:
- case SDL_MOUSEBUTTONDOWN:
- running = false;
- }
- }
- if(SDL_GetTicks() - ticks >= (max - min))
- running = false;
- sound_manager->update();
- SDL_Delay(10);
- }
-}
-
-#ifdef DEBUG
-static Uint32 last_timelog_ticks = 0;
-static const char* last_timelog_component = 0;
-
-static inline void timelog(const char* component)
-{
- Uint32 current_ticks = SDL_GetTicks();
-
- if(last_timelog_component != 0) {
- log_info << "Component '" << last_timelog_component << "' finished after " << (current_ticks - last_timelog_ticks) / 1000.0 << " seconds" << std::endl;
- }
-
- last_timelog_ticks = current_ticks;
- last_timelog_component = component;
-}
-#else
-static inline void timelog(const char* )
-{
-}
-#endif
-
-int main(int argc, char** argv)
-{
- int result = 0;
-
-#ifndef NO_CATCH
- try {
-#endif
-
- if(pre_parse_commandline(argc, argv))
- return 0;
-
- Console::instance = new Console();
- init_physfs(argv[0]);
- init_sdl();
-
- timelog("controller");
- main_controller = new JoystickKeyboardController();
- timelog("config");
- init_config();
- timelog("tinygettext");
- init_tinygettext();
- timelog("commandline");
- if(parse_commandline(argc, argv))
- return 0;
- timelog("audio");
- init_audio();
- timelog("video");
- DrawingContext context;
- context_pointer = &context;
- init_video();
- Console::instance->init_graphics();
- timelog("scripting");
- Scripting::init_squirrel(config->enable_script_debugger);
- timelog("resources");
- load_shared();
- timelog(0);
-
- main_loop = new MainLoop();
- if(config->start_level != "") {
- // we have a normal path specified at commandline not physfs paths.
- // So we simply mount that path here...
- std::string dir = FileSystem::dirname(config->start_level);
- PHYSFS_addToSearchPath(dir.c_str(), true);
-
- if(config->start_level.size() > 4 &&
- config->start_level.compare(config->start_level.size() - 5, 5, ".stwm") == 0) {
- init_rand();
- main_loop->push_screen(new WorldMapNS::WorldMap(
- FileSystem::basename(config->start_level)));
- } else {
- init_rand();//If level uses random eg. for
- // rain particles before we do this:
- std::auto_ptr<GameSession> session (
- new GameSession(FileSystem::basename(config->start_level)));
-
- config->random_seed =session->get_demo_random_seed(config->start_demo);
- init_rand();//initialise generator with seed from session
-
- if(config->start_demo != "")
- session->play_demo(config->start_demo);
-
- if(config->record_demo != "")
- session->record_demo(config->record_demo);
- main_loop->push_screen(session.release());
- }
- } else {
- init_rand();
- main_loop->push_screen(new TitleScreen());
- }
-
- //init_rand(); PAK: this call might subsume the above 3, but I'm chicken!
- main_loop->run(context);
-#ifndef NO_CATCH
- } catch(std::exception& e) {
- log_fatal << "Unexpected exception: " << e.what() << std::endl;
- result = 1;
- } catch(...) {
- log_fatal << "Unexpected exception" << std::endl;
- result = 1;
- }
-#endif
-
- delete main_loop;
- main_loop = NULL;
-
- unload_shared();
- quit_audio();
-
- if(config)
- config->save();
- delete config;
- config = NULL;
- delete main_controller;
- main_controller = NULL;
- delete Console::instance;
- Console::instance = NULL;
- Scripting::exit_squirrel();
- delete texture_manager;
- texture_manager = NULL;
- SDL_Quit();
- PHYSFS_deinit();
-
- return result;
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#ifndef __MAIN_H__
-#define __MAIN_H__
-
-void init_video();
-void wait_for_event(float min_delay, float max_delay);
-
-/// The width of the display (this is a logical value, not the physical value)
-extern int SCREEN_WIDTH;
-/// The height of the display (this is a logical value, not the physical value)
-extern int SCREEN_HEIGHT;
-
-// global variables
-class JoystickKeyboardController;
-extern JoystickKeyboardController* main_controller;
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#include <config.h>
-
-#include "mainloop.hpp"
-
-#include <stdlib.h>
-#include <SDL.h>
-#include "video/drawing_context.hpp"
-#include "control/joystickkeyboardcontroller.hpp"
-#include "gui/menu.hpp"
-#include "audio/sound_manager.hpp"
-#include "scripting/time_scheduler.hpp"
-#include "scripting/squirrel_util.hpp"
-#include "gameconfig.hpp"
-#include "main.hpp"
-#include "resources.hpp"
-#include "screen.hpp"
-#include "screen_fade.hpp"
-#include "timer.hpp"
-#include "player_status.hpp"
-#include "random_generator.hpp"
-
-// the engine will be run with a logical framerate of 64fps.
-// We chose 64fps here because it is a power of 2, so 1/64 gives an "even"
-// binary fraction...
-static const float LOGICAL_FPS = 64.0;
-/** ticks (as returned from SDL_GetTicks) per frame */
-static const Uint32 TICKS_PER_FRAME = (Uint32) (1000.0 / LOGICAL_FPS);
-/** don't skip more than every 2nd frame */
-static const int MAX_FRAME_SKIP = 2;
-
-MainLoop* main_loop = NULL;
-
-MainLoop::MainLoop()
- : speed(1.0), nextpop(false), nextpush(false), fps(0), screenshot_requested(false)
-{
- using namespace Scripting;
- TimeScheduler::instance = new TimeScheduler();
-}
-
-MainLoop::~MainLoop()
-{
- using namespace Scripting;
- delete TimeScheduler::instance;
- TimeScheduler::instance = NULL;
-
- for(std::vector<Screen*>::iterator i = screen_stack.begin();
- i != screen_stack.end(); ++i) {
- delete *i;
- }
-}
-
-void
-MainLoop::push_screen(Screen* screen, ScreenFade* screen_fade)
-{
- this->next_screen.reset(screen);
- this->screen_fade.reset(screen_fade);
- nextpush = !nextpop;
- nextpop = false;
- speed = 1.0;
-}
-
-void
-MainLoop::exit_screen(ScreenFade* screen_fade)
-{
- next_screen.reset(NULL);
- this->screen_fade.reset(screen_fade);
- nextpop = true;
- nextpush = false;
-}
-
-void
-MainLoop::set_screen_fade(ScreenFade* screen_fade)
-{
- this->screen_fade.reset(screen_fade);
-}
-
-void
-MainLoop::quit(ScreenFade* screen_fade)
-{
- for(std::vector<Screen*>::iterator i = screen_stack.begin();
- i != screen_stack.end(); ++i)
- delete *i;
- screen_stack.clear();
-
- exit_screen(screen_fade);
-}
-
-void
-MainLoop::set_speed(float speed)
-{
- this->speed = speed;
-}
-
-float
-MainLoop::get_speed() const
-{
- return speed;
-}
-
-void
-MainLoop::draw_fps(DrawingContext& context, float fps_fps)
-{
- char str[60];
- snprintf(str, sizeof(str), "%3.1f", fps_fps);
- const char* fpstext = "FPS";
- context.draw_text(white_text, fpstext, Vector(SCREEN_WIDTH - white_text->get_text_width(fpstext) - gold_text->get_text_width(" 99999") - BORDER_X, BORDER_Y + 20), ALIGN_LEFT, LAYER_HUD);
- context.draw_text(gold_text, str, Vector(SCREEN_WIDTH - BORDER_X, BORDER_Y + 20), ALIGN_RIGHT, LAYER_HUD);
-}
-
-void
-MainLoop::draw(DrawingContext& context)
-{
- static Uint32 fps_ticks = SDL_GetTicks();
- static int frame_count = 0;
-
- current_screen->draw(context);
- if(Menu::current() != NULL)
- Menu::current()->draw(context);
- if(screen_fade.get() != NULL)
- screen_fade->draw(context);
- Console::instance->draw(context);
-
- if(config->show_fps)
- draw_fps(context, fps);
-
- // if a screenshot was requested, pass request on to drawing_context
- if (screenshot_requested) {
- context.take_screenshot();
- screenshot_requested = false;
- }
- context.do_drawing();
-
- /* Calculate frames per second */
- if(config->show_fps)
- {
- ++frame_count;
-
- if(SDL_GetTicks() - fps_ticks >= 500)
- {
- fps = (float) frame_count / .5;
- frame_count = 0;
- fps_ticks = SDL_GetTicks();
- }
- }
-}
-
-void
-MainLoop::update_gamelogic(float elapsed_time)
-{
- Scripting::update_debugger();
- Scripting::TimeScheduler::instance->update(game_time);
- current_screen->update(elapsed_time);
- if(screen_fade.get() != NULL)
- screen_fade->update(elapsed_time);
- Console::instance->update(elapsed_time);
-}
-
-void
-MainLoop::process_events()
-{
- main_controller->update();
- SDL_Event event;
- while(SDL_PollEvent(&event)) {
- main_controller->process_event(event);
- if(Menu::current() != NULL)
- Menu::current()->event(event);
- if(event.type == SDL_QUIT)
- quit();
- else if (event.type == SDL_KEYDOWN && event.key.keysym.sym == SDLK_F11) {
- config->use_fullscreen = !config->use_fullscreen;
- init_video();
- }
- else if (event.type == SDL_KEYDOWN && event.key.keysym.sym == SDLK_PRINT) {
- take_screenshot();
- }
- }
-}
-
-void
-MainLoop::handle_screen_switch()
-{
- while( (next_screen.get() != NULL || nextpop) &&
- (screen_fade.get() == NULL || screen_fade->done())) {
- if(current_screen.get() != NULL) {
- current_screen->leave();
- }
-
- if(nextpop) {
- if(screen_stack.empty()) {
- running = false;
- break;
- }
- next_screen.reset(screen_stack.back());
- screen_stack.pop_back();
- }
- if(nextpush && current_screen.get() != NULL) {
- screen_stack.push_back(current_screen.release());
- }
-
- nextpush = false;
- nextpop = false;
- speed = 1.0;
- if(next_screen.get() != NULL)
- next_screen->setup();
- current_screen.reset(next_screen.release());
- screen_fade.reset(NULL);
-
- waiting_threads.wakeup();
- }
-}
-
-void
-MainLoop::run(DrawingContext &context)
-{
- Uint32 last_ticks = 0;
- Uint32 elapsed_ticks = 0;
-
- running = true;
- while(running) {
-
- handle_screen_switch();
- if(!running || current_screen.get() == NULL)
- break;
-
- Uint32 ticks = SDL_GetTicks();
- elapsed_ticks += ticks - last_ticks;
- last_ticks = ticks;
-
- if (elapsed_ticks > TICKS_PER_FRAME*4) {
- // when the game loads up or levels are switched the
- // elapsed_ticks grows extremly large, so we just ignore those
- // large time jumps
- elapsed_ticks = 0;
- }
-
- int frames = 0;
-
- if (elapsed_ticks > TICKS_PER_FRAME) {
- while(elapsed_ticks > TICKS_PER_FRAME && frames < MAX_FRAME_SKIP) {
- elapsed_ticks -= TICKS_PER_FRAME;
- float timestep = 1.0 / LOGICAL_FPS;
- real_time += timestep;
- timestep *= speed;
- game_time += timestep;
-
- process_events();
- update_gamelogic(timestep);
- frames += 1;
- }
-
- draw(context);
- }
-
- sound_manager->update();
-
- SDL_Delay(0);
- }
-}
-
-void
-MainLoop::take_screenshot()
-{
- screenshot_requested = true;
-}
-
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#ifndef __MAINLOOP_HPP__
-#define __MAINLOOP_HPP__
-
-#include <memory>
-#include <vector>
-#include "scripting/thread_queue.hpp"
-
-class Screen;
-class Console;
-class ScreenFade;
-class DrawingContext;
-
-class MainLoop
-{
-public:
- MainLoop();
- ~MainLoop();
-
- void run(DrawingContext &context);
- void exit_screen(ScreenFade* fade = NULL);
- void quit(ScreenFade* fade = NULL);
- void set_speed(float speed);
- float get_speed() const;
-
- /**
- * requests that a screenshot be taken after the next frame has been rendered
- */
- void take_screenshot();
-
- // push new screen on screen_stack
- void push_screen(Screen* screen, ScreenFade* fade = NULL);
- void set_screen_fade(ScreenFade* fade);
-
- /// threads that wait for a screenswitch
- Scripting::ThreadQueue waiting_threads;
-
-private:
- void draw_fps(DrawingContext& context, float fps);
- void draw(DrawingContext& context);
- void update_gamelogic(float elapsed_time);
- void process_events();
- void handle_screen_switch();
-
- bool running;
- float speed;
- bool nextpop;
- bool nextpush;
- /// measured fps
- float fps;
- std::auto_ptr<Screen> next_screen;
- std::auto_ptr<Screen> current_screen;
- std::auto_ptr<Console> console;
- std::auto_ptr<ScreenFade> screen_fade;
- std::vector<Screen*> screen_stack;
- bool screenshot_requested; /**< true if a screenshot should be taken after the next frame has been rendered */
-};
-
-extern MainLoop* main_loop;
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __AATRIANGLE_H__
-#define __AATRIANGLE_H__
-
-#include "rect.hpp"
-
-/**
- * An axis aligned triangle (ie. a triangle where 2 sides are parallel to the x-
- * and y-axis.
- */
-class AATriangle : public Rect
-{
-public:
- /** Directions:
- *
- * SOUTHEWEST NORTHEAST SOUTHEAST NORTHWEST
- * * or *---* or * or *---*
- * | \ \ | / | | /
- * | \ \ | / | | /
- * *---* * *---* *
- *
- * Deform flags: (see docs/aatriangletypes.png for details)
- */
- enum Direction {
- SOUTHWEST = 0,
- NORTHEAST,
- SOUTHEAST,
- NORTHWEST,
- DIRECTION_MASK = 0x0003,
- DEFORM1 = 0x0010,
- DEFORM2 = 0x0020,
- DEFORM3 = 0x0030,
- DEFORM4 = 0x0040,
- DEFORM_MASK = 0x0070
- };
-
- AATriangle()
- : dir(SOUTHWEST)
- {
- }
- AATriangle(const Vector& v1, const Vector& v2, int newdir)
- : Rect(v1, v2), dir(newdir)
- {
- }
-
- int dir;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __RECT_H__
-#define __RECT_H__
-
-#include <assert.h>
-#include "vector.hpp"
-
-/** This class represents a rectangle.
- * (Implementation Note) We're using upper left and lower right point instead of
- * upper left and width/height here, because that makes the collision dectection
- * a little bit efficienter.
- */
-class Rect
-{
-public:
- Rect()
- { }
-
- Rect(const Vector& np1, const Vector& np2)
- : p1(np1), p2(np2)
- {
- }
-
- Rect(float x1, float y1, float x2, float y2)
- : p1(x1, y1), p2(x2, y2)
- {
- assert(p1.x <= p2.x && p1.y <= p2.y);
- }
-
- float get_left() const
- { return p1.x; }
-
- float get_right() const
- { return p2.x; }
-
- float get_top() const
- { return p1.y; }
-
- float get_bottom() const
- { return p2.y; }
-
- float get_width() const
- { return p2.x - p1.x; }
-
- float get_height() const
- { return p2.y - p1.y; }
-
- Vector get_middle() const
- { return Vector((p1.x+p2.x)/2, (p1.y+p2.y)/2); }
-
- void set_pos(const Vector& v)
- {
- move(v-p1);
- }
-
- void set_height(float height)
- {
- p2.y = p1.y + height;
- }
- void set_width(float width)
- {
- p2.x = p1.x + width;
- }
- void set_size(float width, float height)
- {
- set_width(width);
- set_height(height);
- }
- Vector get_size()
- {
- return Vector(get_width(), get_height());
- }
-
- void move(const Vector& v)
- {
- p1 += v;
- p2 += v;
- }
-
- bool contains(const Vector& v) const
- {
- return v.x >= p1.x && v.y >= p1.y && v.x < p2.x && v.y < p2.y;
- }
- bool contains(const Rect& other) const
- {
- if(p1.x >= other.p2.x || other.p1.x >= p2.x)
- return false;
- if(p1.y >= other.p2.y || other.p1.y >= p2.y)
- return false;
-
- return true;
- }
-
- // leave these 2 public to safe the headaches of set/get functions for such
- // simple things :)
-
- /// upper left edge
- Vector p1;
- /// lower right edge
- Vector p2;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include <cmath>
-
-#include "math/vector.hpp"
-
-Vector Vector::unit() const
-{
- return *this / norm();
-}
-
-float Vector::norm() const
-{
- return sqrt(x*x + y*y);
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef SUPERTUX_VECTOR_H
-#define SUPERTUX_VECTOR_H
-
-/** Simple two dimensional vector. */
-class Vector
-{
-public:
- Vector(float nx, float ny)
- : x(nx), y(ny)
- { }
- Vector(const Vector& other)
- : x(other.x), y(other.y)
- { }
- Vector()
- : x(0), y(0)
- { }
-
- bool operator ==(const Vector& other) const
- {
- return x == other.x && y == other.y;
- }
-
- bool operator !=(const Vector& other) const
- {
- return !(x == other.x && y == other.y);
- }
-
- const Vector& operator=(const Vector& other)
- {
- x = other.x;
- y = other.y;
- return *this;
- }
-
- Vector operator+(const Vector& other) const
- {
- return Vector(x + other.x, y + other.y);
- }
-
- Vector operator-(const Vector& other) const
- {
- return Vector(x - other.x, y - other.y);
- }
-
- Vector operator*(float s) const
- {
- return Vector(x * s, y * s);
- }
-
- Vector operator/(float s) const
- {
- return Vector(x / s, y / s);
- }
-
- Vector operator-() const
- {
- return Vector(-x, -y);
- }
-
- const Vector& operator +=(const Vector& other)
- {
- x += other.x;
- y += other.y;
- return *this;
- }
-
- const Vector& operator -=(const Vector& other)
- {
- x -= other.x;
- y -= other.y;
- return *this;
- }
-
- const Vector& operator *=(float val)
- {
- x *= val;
- y *= val;
- return *this;
- }
-
- const Vector& operator /=(float val)
- {
- x /= val;
- y /= val;
- return *this;
- }
-
- /// Scalar product of 2 vectors
- float operator*(const Vector& other) const
- {
- return x*other.x + y*other.y;
- }
-
- float norm() const;
- Vector unit() const;
-
- // ... add the other operators as needed, I'm too lazy now ...
-
- float x, y; // leave this public, get/set methods just give me headaches
- // for such simple stuff :)
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#include <config.h>
-
-#include "moving_object.hpp"
-
-MovingObject::MovingObject()
-{
- group = COLGROUP_MOVING;
-}
-
-MovingObject::~MovingObject()
-{
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#ifndef SUPERTUX_MOVING_OBJECT_H
-#define SUPERTUX_MOVING_OBJECT_H
-
-#include <stdint.h>
-
-#include "game_object.hpp"
-#include "collision_hit.hpp"
-#include "math/vector.hpp"
-#include "math/rect.hpp"
-
-class Sector;
-class CollisionGrid;
-
-enum CollisionGroup {
- /** Objects in DISABLED group are not tested for collisions */
- COLGROUP_DISABLED = 0,
- /**
- * "default" is moving object. MovingObjects get tested against all other
- * objects and against other movingobjects
- */
- COLGROUP_MOVING,
- /**
- * a Moving object, that is not tested against other MovingObjects (or other
- * MovingOnlyStatic objects), but is tested against all other objects.
- */
- COLGROUP_MOVING_ONLY_STATIC,
- /** TODO write docu :-/ */
- COLGROUP_MOVING_STATIC,
- /**
- * Doesn't move and isn't explicitely checked for collisions with other
- * objects (but other objects might check with this)
- * The difference to COLGROUP_TOUCHABLE is that we can do multiple
- * collision response tests in a row which is needed for static object
- * that tux walks on. The results for collisions with STATIC objects
- * are also sorted by time (so that the first hit gets handled first).
- *
- * Use this for static obstacles
- */
- COLGROUP_STATIC,
- /**
- * Isn't explicitely checked for collisions with other objects. But other
- * objects might check with this object.
- * Difference to COLGROUP_STATIC is that collisions with this object are
- * only tested once and collision response is typically not handled
- *
- * Use this for touchable things like spikes/areas or collectibles like
- * coins
- */
- COLGROUP_TOUCHABLE,
-
- /**
- * Should be used for tilemaps
- */
- COLGROUP_TILEMAP
-};
-
-/**
- * Base class for all dynamic/moving game objects. This class contains things
- * for handling the bounding boxes and collision feedback.
- */
-class MovingObject : public GameObject
-{
-public:
- MovingObject();
- virtual ~MovingObject();
-
- /** this function is called when the object collided with something solid */
- virtual void collision_solid(const CollisionHit& hit)
- {
- (void) hit;
- }
- /**
- * when 2 objects collided, we will first call the pre_collision_check
- * functions of both objects that can decide on how to react to the collision.
- */
- virtual bool collides(GameObject& other, const CollisionHit& hit)
- {
- (void) other;
- (void) hit;
- return true;
- }
- /** this function is called when the object collided with any other object */
- virtual HitResponse collision(GameObject& other, const CollisionHit& hit) = 0;
- /** called when tiles with special attributes have been touched */
- virtual void collision_tile(uint32_t tile_attributes)
- {
- (void) tile_attributes;
- }
-
- const Vector& get_pos() const
- {
- return bbox.p1;
- }
-
- /** returns the bounding box of the Object */
- const Rect& get_bbox() const
- {
- return bbox;
- }
-
- const Vector& get_movement() const
- {
- return movement;
- }
-
- /** places the moving object at a specific position. Be carefull when
- * using this function. There are no collision detection checks performed
- * here so bad things could happen.
- */
- virtual void set_pos(const Vector& pos)
- {
- dest.move(pos-get_pos());
- bbox.set_pos(pos);
- }
-
- /**
- * sets the moving object's bbox to a specific width. Be careful when
- * using this function. There are no collision detection checks performed
- * here so bad things could happen.
- */
- virtual void set_width(float w)
- {
- dest.set_width(w);
- bbox.set_width(w);
- }
-
- /**
- * sets the moving object's bbox to a specific size. Be careful when
- * using this function. There are no collision detection checks performed
- * here so bad things could happen.
- */
- virtual void set_size(float w, float h)
- {
- dest.set_size(w, h);
- bbox.set_size(w, h);
- }
-
- CollisionGroup get_group() const
- {
- return group;
- }
-
-protected:
- friend class Sector;
- friend class CollisionGrid;
- friend class Platform;
-
- void set_group(CollisionGroup group)
- {
- this->group = group;
- }
-
- /** The bounding box of the object (as used for collision detection, this
- * isn't necessarily the bounding box for graphics)
- */
- Rect bbox;
- /** The movement that will happen till next frame
- */
- Vector movement;
- /** The collision group */
- CollisionGroup group;
-
-private:
- /**
- * this is only here for internal collision detection use (don't touch this
- * from outside collision detection code)
- *
- * This field holds the currently anticipated destination of the object
- * during collision detection
- */
- Rect dest;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include <math.h>
-#include <stdexcept>
-#include <iostream>
-#include <limits>
-
-#include "ambient_sound.hpp"
-#include "object_factory.hpp"
-#include "lisp/lisp.hpp"
-#include "sector.hpp"
-#include "audio/sound_manager.hpp"
-#include "audio/sound_source.hpp"
-#include "log.hpp"
-#include "scripting/squirrel_util.hpp"
-
-AmbientSound::AmbientSound(const lisp::Lisp& lisp)
-{
- name="";
- position.x = 0;
- position.y = 0;
-
- dimension.x = 0;
- dimension.y = 0;
-
- distance_factor = 0;
- distance_bias = 0;
- maximumvolume = 1;
- sample = "";
- currentvolume = 0;
-
- if (!(lisp.get("x", position.x)&&lisp.get("y", position.y))) {
- log_warning << "No Position in ambient_sound" << std::endl;
- }
-
- lisp.get("name" , name);
- lisp.get("width" , dimension.x);
- lisp.get("height", dimension.y);
-
- lisp.get("distance_factor",distance_factor);
- lisp.get("distance_bias" ,distance_bias );
- lisp.get("sample" ,sample );
- lisp.get("volume" ,maximumvolume );
-
- // set dimension to zero if smaller than 64, which is default size in flexlay
-
- if ((dimension.x <= 64) || (dimension.y <= 64)) {
- dimension.x = 0;
- dimension.y = 0;
- }
-
- // square all distances (saves us a sqrt later)
-
- distance_bias*=distance_bias;
- distance_factor*=distance_factor;
-
- // set default silence_distance
-
- if (distance_factor == 0)
- silence_distance = std::numeric_limits<float>::max();
- else
- silence_distance = 1/distance_factor;
-
- lisp.get("silence_distance",silence_distance);
-
- sound_source = 0; // not playing at the beginning
- latency=0;
-}
-
-AmbientSound::AmbientSound(Vector pos, float factor, float bias, float vol, std::string file)
-{
- position.x=pos.x;
- position.y=pos.y;
-
- dimension.x=0;
- dimension.y=0;
-
- distance_factor=factor*factor;
- distance_bias=bias*bias;
- maximumvolume=vol;
- sample=file;
-
- // set default silence_distance
-
- if (distance_factor == 0)
- silence_distance = std::numeric_limits<float>::max();
- else
- silence_distance = 1/distance_factor;
-
- sound_source = 0; // not playing at the beginning
- latency=0;
-}
-
-AmbientSound::~AmbientSound() {
- stop_playing();
-}
-
-void
-AmbientSound::hit(Player& )
-{
-}
-
-void
-AmbientSound::stop_playing() {
- delete sound_source;
- sound_source = 0;
-}
-
-void
-AmbientSound::start_playing()
-{
- try {
- sound_source = sound_manager->create_sound_source(sample);
- if(!sound_source)
- throw std::runtime_error("file not found");
-
- sound_source->set_gain(0);
- sound_source->set_looping(true);
- currentvolume=targetvolume=1e-20f;
- sound_source->play();
- } catch(std::exception& e) {
- log_warning << "Couldn't play '" << sample << "': " << e.what() << "" << std::endl;
- delete sound_source;
- sound_source = 0;
- remove_me();
- }
-}
-
-void
-AmbientSound::update(float deltat)
-{
- if (latency-- <= 0) {
- float px,py;
- float rx,ry;
-
- // Player position
- px=Sector::current()->player->get_pos().x;
- py=Sector::current()->player->get_pos().y;
-
- // Relate to which point in the area
- rx=px<position.x?position.x:
- (px<position.x+dimension.x?px:position.x+dimension.x);
- ry=py<position.y?position.y:
- (py<position.y+dimension.y?py:position.y+dimension.y);
-
- // calculate square of distance
- float sqrdistance=(px-rx)*(px-rx)+(py-ry)*(py-ry);
- sqrdistance-=distance_bias;
-
- // inside the bias: full volume (distance 0)
- if (sqrdistance<0)
- sqrdistance=0;
-
- // calculate target volume - will never become 0
- targetvolume=1/(1+sqrdistance*distance_factor);
- float rise=targetvolume/currentvolume;
-
- // rise/fall half life?
- currentvolume*=pow(rise,deltat*10);
- currentvolume += 1e-6f; // volume is at least 1e-6 (0 would never rise)
-
- if (sound_source != 0) {
-
- // set the volume
- sound_source->set_gain(currentvolume*maximumvolume);
-
- if (sqrdistance>=silence_distance && currentvolume<1e-3)
- stop_playing();
- latency=0;
- } else {
- if (sqrdistance<silence_distance) {
- start_playing();
- latency=0;
- }
- else // set a reasonable latency
- latency=(int)(0.001/distance_factor);
- //(int)(10*((sqrdistance-silence_distance)/silence_distance));
- }
- }
-
- // heuristically measured "good" latency maximum
-
- // if (latency>0.001/distance_factor)
- // latency=
-}
-
-void
-AmbientSound::draw(DrawingContext &)
-{
-}
-
-void
-AmbientSound::expose(HSQUIRRELVM vm, SQInteger table_idx)
-{
- Scripting::AmbientSound* interface = static_cast<Scripting::AmbientSound*> (this);
- expose_object(vm, table_idx, interface, name, false);
-}
-
-void
-AmbientSound::unexpose(HSQUIRRELVM vm, SQInteger table_idx)
-{
- Scripting::unexpose_object(vm, table_idx, name);
-}
-
-void
-AmbientSound::set_pos(float x, float y)
-{
- position.x = x;
- position.y = y;
-}
-
-float
-AmbientSound::get_pos_x() const
-{
- return position.x;
-}
-
-float
-AmbientSound::get_pos_y() const
-{
- return position.y;
-}
-
-IMPLEMENT_FACTORY(AmbientSound, "ambient_sound");
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-
-/**
- * Ambient Sound Source, gamma version. Features:
- *
- * - "rounded rectancle" geometry with position, dimension and
- * "rounding radius" (extending in all directions) of a 100%
- * volume area, adjustable maximum volume, inverse square
- * falloff outside area.
- *
- * - degenerates gracefully to a disc for dimension=0
- *
- * - parameters:
- *
- * x, y position
- * width, height dimension
- * distance_factor high = steep fallofff
- * distance_bias high = big "100% disc"
- * silence_distance defaults reasonably.
- * sample sample to be played back in loop mode
- *
- * basti_
- */
-
-#ifndef __AMBIENT_SOUND_H__
-#define __AMBIENT_SOUND_H__
-
-#include "game_object.hpp"
-#include "resources.hpp"
-#include "player.hpp"
-#include "script_interface.hpp"
-#include "scripting/ambient_sound.hpp"
-
-class SoundSource;
-
-class AmbientSound : public GameObject, public ScriptInterface, public Scripting::AmbientSound
-{
-public:
- AmbientSound(const lisp::Lisp& lisp);
- AmbientSound(Vector pos, float factor, float bias, float vol, std::string file);
- ~AmbientSound();
-
- void set_pos(Vector newpos)
- {
- position=newpos;
- }
- const Vector get_pos() const
- {
- return position;
- }
-
- /**
- * @name Scriptable Methods
- * @{
- */
- void set_pos(float x, float y);
- float get_pos_x() const;
- float get_pos_y() const;
- /**
- * @}
- */
-
-protected:
- virtual void hit(Player& player);
- virtual void update(float time);
- virtual void draw(DrawingContext&);
- virtual void start_playing();
- virtual void stop_playing();
- virtual void expose(HSQUIRRELVM vm, SQInteger table_idx);
- virtual void unexpose(HSQUIRRELVM vm, SQInteger table_idx);
-private:
- std::string name; /**< user-defined name for use in scripts or empty string if not scriptable */
- Vector position;
- Vector dimension;
-
- std::string sample;
- SoundSource* sound_source;
- int latency;
-
- float distance_factor; /// distance scaling
- float distance_bias; /// 100% volume disc radius
- float silence_distance; /// not implemented yet
-
- float maximumvolume; /// maximum volume
- float targetvolume; /// how loud we want to be
- float currentvolume; /// how loud we are
-
- float * volume_ptr; /// this will be used by the volume adjustment effect.
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include <stdexcept>
-#include <sstream>
-#include "anchor_point.hpp"
-#include "math/rect.hpp"
-#include "log.hpp"
-
-std::string anchor_point_to_string(AnchorPoint point)
-{
- switch(point) {
- case ANCHOR_TOP_LEFT:
- return "topleft";
- case ANCHOR_TOP:
- return "top";
- case ANCHOR_TOP_RIGHT:
- return "topright";
- case ANCHOR_LEFT:
- return "left";
- case ANCHOR_MIDDLE:
- return "middle";
- case ANCHOR_RIGHT:
- return "right";
- case ANCHOR_BOTTOM_LEFT:
- return "bottomleft";
- case ANCHOR_BOTTOM:
- return "bottom";
- case ANCHOR_BOTTOM_RIGHT:
- return "bottomright";
- default:
- throw std::runtime_error("Invalid anchor point");
- }
-}
-
-AnchorPoint string_to_anchor_point(const std::string& str)
-{
- if(str == "topleft")
- return ANCHOR_TOP_LEFT;
- else if(str == "top")
- return ANCHOR_TOP;
- else if(str == "topright")
- return ANCHOR_TOP_RIGHT;
- else if(str == "left")
- return ANCHOR_LEFT;
- else if(str == "middle")
- return ANCHOR_MIDDLE;
- else if(str == "right")
- return ANCHOR_RIGHT;
- else if(str == "bottomleft")
- return ANCHOR_BOTTOM_LEFT;
- else if(str == "bottom")
- return ANCHOR_BOTTOM;
- else if(str == "bottomright")
- return ANCHOR_BOTTOM_RIGHT;
-
- std::ostringstream msg;
- msg << "Unknown anchor '" << str << "'";
- throw std::runtime_error(msg.str());
-}
-
-Vector get_anchor_pos(const Rect& rect, AnchorPoint point)
-{
- Vector result;
-
- switch(point & ANCHOR_V_MASK) {
- case ANCHOR_LEFT:
- result.x = rect.get_left();
- break;
- case ANCHOR_MIDDLE:
- result.x = rect.get_left() + (rect.get_right() - rect.get_left()) / 2.0;
- break;
- case ANCHOR_RIGHT:
- result.x = rect.get_right();
- break;
- default:
-#ifdef DEBUG
- throw std::runtime_error("Invalid anchor point found");
-#endif
- log_warning << "Invalid anchor point found" << std::endl;
- result.x = rect.get_left();
- break;
- }
-
- switch(point & ANCHOR_H_MASK) {
- case ANCHOR_TOP:
- result.y = rect.get_top();
- break;
- case ANCHOR_MIDDLE:
- result.y = rect.get_top() + (rect.get_bottom() - rect.get_top()) / 2.0;
- break;
- case ANCHOR_BOTTOM:
- result.y = rect.get_bottom();
- break;
- default:
-#ifdef DEBUG
- throw std::runtime_error("Invalid anchor point found");
-#endif
- log_warning << "Invalid anchor point found" << std::endl;
- result.y = rect.get_top();
- break;
- }
-
- return result;
-}
-
-Vector get_anchor_pos(const Rect& destrect, float width, float height,
- AnchorPoint point)
-{
- Vector result;
-
- switch(point & ANCHOR_V_MASK) {
- case ANCHOR_LEFT:
- result.x = destrect.get_left();
- break;
- case ANCHOR_MIDDLE:
- result.x = destrect.get_middle().x - width/2.0;
- break;
- case ANCHOR_RIGHT:
- result.x = destrect.get_right() - width;
- break;
- default:
-#ifdef DEBUG
- throw std::runtime_error("Invalid anchor point found");
-#endif
- log_warning << "Invalid anchor point found" << std::endl;
- result.x = destrect.get_left();
- break;
- }
-
- switch(point & ANCHOR_H_MASK) {
- case ANCHOR_TOP:
- result.y = destrect.get_top();
- break;
- case ANCHOR_MIDDLE:
- result.y = destrect.get_middle().y - height/2.0;
- break;
- case ANCHOR_BOTTOM:
- result.y = destrect.get_bottom() - height;
- break;
- default:
-#ifdef DEBUG
- throw std::runtime_error("Invalid anchor point found");
-#endif
- log_warning << "Invalid anchor point found" << std::endl;
- result.y = destrect.get_top();
- break;
- }
-
- return result;
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __ANCHOR_POINT_HPP__
-#define __ANCHOR_POINT_HPP__
-
-#include <string>
-#include "math/vector.hpp"
-
-class Rect;
-
-enum AnchorPoint {
- ANCHOR_H_MASK = 0x00f0,
- ANCHOR_TOP = 0x0010,
- ANCHOR_BOTTOM = 0x0020,
- ANCHOR_V_MASK = 0x000f,
- ANCHOR_LEFT = 0x0001,
- ANCHOR_RIGHT = 0x0002,
- ANCHOR_MIDDLE = 0x0000,
-
- ANCHOR_TOP_LEFT = ANCHOR_TOP | ANCHOR_LEFT,
- ANCHOR_TOP_RIGHT = ANCHOR_TOP | ANCHOR_RIGHT,
- ANCHOR_BOTTOM_LEFT = ANCHOR_BOTTOM | ANCHOR_LEFT,
- ANCHOR_BOTTOM_RIGHT = ANCHOR_BOTTOM | ANCHOR_RIGHT,
-};
-
-std::string anchor_point_to_string(AnchorPoint point);
-AnchorPoint string_to_anchor_point(const std::string& str);
-Vector get_anchor_pos(const Rect& rect, AnchorPoint point);
-Vector get_anchor_pos(const Rect& destrect, float width, float height,
- AnchorPoint point);
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include <stdexcept>
-#include "background.hpp"
-#include "camera.hpp"
-#include "video/drawing_context.hpp"
-#include "lisp/lisp.hpp"
-#include "lisp/writer.hpp"
-#include "object_factory.hpp"
-#include "resources.hpp"
-#include "main.hpp"
-#include "log.hpp"
-
-Background::Background()
- : layer(LAYER_BACKGROUND0)
-{
-}
-
-Background::Background(const lisp::Lisp& reader)
- : layer(LAYER_BACKGROUND0)
-{
- // read position, defaults to (0,0)
- float px = 0;
- float py = 0;
- reader.get("x", px);
- reader.get("y", py);
- this->pos = Vector(px,py);
-
- speed = 1.0;
- speed_y = 1.0;
-
- reader.get("layer", layer);
- if(!reader.get("image", imagefile) || !reader.get("speed", speed))
- throw std::runtime_error("Must specify image and speed for background");
-
- set_image(imagefile, speed);
- reader.get("speed-y", speed_y);
- if (reader.get("image-top", imagefile_top)) {
- image_top.reset(new Surface(imagefile_top));
- }
- if (reader.get("image-bottom", imagefile_bottom)) {
- image_bottom.reset(new Surface(imagefile_bottom));
- }
-}
-
-Background::~Background()
-{
-}
-
-void
-Background::write(lisp::Writer& writer)
-{
- writer.start_list("background");
-
- if (image_top.get() != NULL)
- writer.write_string("image-top", imagefile_top);
-
- writer.write_string("image", imagefile);
- if (image_bottom.get() != NULL)
- writer.write_string("image-bottom", imagefile_bottom);
-
- writer.write_float("speed", speed);
- writer.write_float("speed-y", speed_y);
- writer.write_int("layer", layer);
-
- writer.end_list("background");
-}
-
-void
-Background::update(float)
-{
-}
-
-void
-Background::set_image(const std::string& name, float speed)
-{
- this->imagefile = name;
- this->speed = speed;
-
- image.reset(new Surface(name));
-}
-
-void
-Background::draw(DrawingContext& context)
-{
- if(image.get() == NULL)
- return;
-
- int w = (int) image->get_width();
- int h = (int) image->get_height();
- int sx = int(pos.x-context.get_translation().x * speed) % w - w;
- int sy = int(pos.y-context.get_translation().y * speed_y) % h - h;
- int center_image_py = int(pos.y-context.get_translation().y * speed_y);
- int bottom_image_py = int(pos.y-context.get_translation().y * speed_y) + h;
- context.push_transform();
- context.set_translation(Vector(0, 0));
- for(int x = sx; x < SCREEN_WIDTH; x += w) {
- for(int y = sy; y < SCREEN_HEIGHT; y += h) {
- if (image_top.get() != NULL && (y < center_image_py)) {
- context.draw_surface(image_top.get(), Vector(x, y), layer);
- continue;
- }
- if (image_bottom.get() != NULL && (y >= bottom_image_py)) {
- context.draw_surface(image_bottom.get(), Vector(x, y), layer);
- continue;
- }
- context.draw_surface(image.get(), Vector(x, y), layer);
- }
- }
- context.pop_transform();
-}
-
-IMPLEMENT_FACTORY(Background, "background");
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef SUPERTUX_BACKGROUND_H
-#define SUPERTUX_BACKGROUND_H
-
-#include <memory>
-#include "video/surface.hpp"
-#include "video/drawing_context.hpp"
-#include "game_object.hpp"
-#include "serializable.hpp"
-
-class DisplayManager;
-
-namespace lisp {
-class Lisp;
-}
-
-class Background : public GameObject, public Serializable
-{
-public:
- Background();
- Background(const lisp::Lisp& reader);
- virtual ~Background();
-
- virtual void write(lisp::Writer& writer);
-
- void set_image(const std::string& name, float bkgd_speed);
-
- std::string get_image() const
- { return imagefile; }
- float get_speed() const
- { return speed; }
-
- virtual void update(float elapsed_time);
-
- virtual void draw(DrawingContext& context);
-
-private:
- int layer;
- std::string imagefile_top;
- std::string imagefile;
- std::string imagefile_bottom;
- Vector pos; /**< coordinates of upper-left corner of image */
- float speed; /**< scroll-speed in horizontal direction */
- float speed_y; /**< scroll-speed in vertical direction */
- std::auto_ptr<Surface> image_top; /**< image to draw above pos */
- std::auto_ptr<Surface> image; /**< image to draw, anchored at pos */
- std::auto_ptr<Surface> image_bottom; /**< image to draw below pos+screenheight */
-};
-
-#endif /*SUPERTUX_BACKGROUND_H*/
+++ /dev/null
-// $Id$
-//
-// SuperTux - BicyclePlatform
-// Copyright (C) 2007 Christoph Sommer <christoph.sommer@2007.expires.deltadevelopment.de>
-//
-// 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.
-
-#include <config.h>
-
-#include "bicycle_platform.hpp"
-
-#include <math.h>
-#include <stdexcept>
-#include "log.hpp"
-#include "video/drawing_context.hpp"
-#include "resources.hpp"
-#include "player.hpp"
-#include "path.hpp"
-#include "path_walker.hpp"
-#include "sprite/sprite.hpp"
-#include "lisp/lisp.hpp"
-#include "object_factory.hpp"
-#include "sector.hpp"
-#include "object/portable.hpp"
-
-BicyclePlatform::BicyclePlatform(const lisp::Lisp& reader)
- : MovingSprite(reader, LAYER_OBJECTS, COLGROUP_STATIC),
- master(0), slave(0), radius(128), angle(0), angular_speed(0), momentum(0)
-{
- center = get_pos();
-}
-
-BicyclePlatform::BicyclePlatform(BicyclePlatform* master)
- : MovingSprite(*master),
- master(master), slave(this), center(master->center), radius(master->radius), angle(master->angle + M_PI), angular_speed(0), momentum(0)
-{
- set_pos(get_pos() + Vector(master->get_bbox().get_width(), 0));
- master->master = master;
- master->slave = this;
-}
-
-BicyclePlatform::~BicyclePlatform() {
- if ((this == master) && (master)) {
- slave->master = 0;
- slave->slave = 0;
- }
- if ((master) && (this == slave)) {
- master->master = 0;
- master->slave = 0;
- }
- master = 0;
- slave = 0;
-}
-
-HitResponse
-BicyclePlatform::collision(GameObject& other, const CollisionHit& )
-{
-
- // somehow the hit parameter does not get filled in, so to determine (hit.top == true) we do this:
- MovingObject* mo = dynamic_cast<MovingObject*>(&other);
- if (!mo) return FORCE_MOVE;
- if ((mo->get_bbox().p2.y) > (get_bbox().p1.y + 2)) return FORCE_MOVE;
-
- Player* pl = dynamic_cast<Player*>(mo);
- if (pl) {
- if (pl->is_big()) momentum += 1;
- Portable* po = pl->get_grabbed_object();
- MovingObject* pomo = dynamic_cast<MovingObject*>(po);
- if (contacts.insert(pomo).second) momentum += 1;
- }
-
- if (contacts.insert(&other).second) momentum += 1;
- return FORCE_MOVE;
-}
-
-void
-BicyclePlatform::update(float elapsed_time)
-{
- if (!slave) {
- Sector::current()->add_object(new BicyclePlatform(this));
- return;
- }
- if (!master) {
- return;
- }
- if (this == slave) {
- angle = master->angle + M_PI;
- while (angle < 0) { angle += 2*M_PI; }
- while (angle > 2*M_PI) { angle -= 2*M_PI; }
- Vector dest = center + Vector(cosf(angle), sinf(angle)) * radius - (bbox.get_size() * 0.5);
- movement = dest - get_pos();
- }
- if (this == master) {
- float momentum_diff = momentum - slave->momentum;
- contacts.clear(); momentum = 0;
- slave->contacts.clear(); slave->momentum = 0;
-
- float angular_momentum = cosf(angle) * momentum_diff;
-
- angular_speed += (angular_momentum * elapsed_time) * M_PI;
- angular_speed *= 1 - elapsed_time * 0.2;
- angle += angular_speed * elapsed_time;
- while (angle < 0) { angle += 2*M_PI; }
- while (angle > 2*M_PI) { angle -= 2*M_PI; }
- angular_speed = std::min(std::max(angular_speed, static_cast<float>(-128*M_PI*elapsed_time)), static_cast<float>(128*M_PI*elapsed_time));
- Vector dest = center + Vector(cosf(angle), sinf(angle)) * radius - (bbox.get_size() * 0.5);
- movement = dest - get_pos();
-
- center += Vector(angular_speed, 0) * elapsed_time * 32;
- slave->center += Vector(angular_speed, 0) * elapsed_time * 32;
-
- }
-}
-
-IMPLEMENT_FACTORY(BicyclePlatform, "bicycle-platform");
-
+++ /dev/null
-// $Id$
-//
-// SuperTux - BicyclePlatform
-// Copyright (C) 2007 Christoph Sommer <christoph.sommer@2007.expires.deltadevelopment.de>
-//
-// 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.
-
-#ifndef __BICYCLE_PLATFORM_H__
-#define __BICYCLE_PLATFORM_H__
-
-#include <memory>
-#include <string>
-#include <set>
-#include "object/moving_sprite.hpp"
-#include "object/path.hpp"
-#include "object/path_walker.hpp"
-
-/**
- * Used to construct a pair of bicycle platforms: If one is pushed down, the other one rises
- */
-class BicyclePlatform : public MovingSprite
-{
-public:
- BicyclePlatform(const lisp::Lisp& reader);
- BicyclePlatform(BicyclePlatform* master);
- virtual ~BicyclePlatform();
-
- virtual HitResponse collision(GameObject& other, const CollisionHit& hit);
- virtual void update(float elapsed_time);
-
-protected:
- BicyclePlatform* master; /**< pointer to BicyclePlatform that does movement calculation */
- BicyclePlatform* slave; /**< pointer to BicyclePlatform that reacts to master platform's movement calculation */
- Vector center; /**< pivot point */
- float radius; /**< radius of circle */
- float angle; /**< current angle */
- float angular_speed; /**< angular speed in rad per second */
- std::set<GameObject*> contacts; /**< objects that are currently pushing on the platform */
- float momentum; /** angular momentum in rad per second per second*/
-
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include "block.hpp"
-#include "log.hpp"
-
-#include <stdexcept>
-
-#include "resources.hpp"
-#include "player.hpp"
-#include "sector.hpp"
-#include "sprite/sprite.hpp"
-#include "sprite/sprite_manager.hpp"
-#include "video/drawing_context.hpp"
-#include "lisp/lisp.hpp"
-#include "gameobjs.hpp"
-#include "portable.hpp"
-#include "specialriser.hpp"
-#include "growup.hpp"
-#include "flower.hpp"
-#include "oneup.hpp"
-#include "star.hpp"
-#include "player_status.hpp"
-#include "badguy/badguy.hpp"
-#include "coin.hpp"
-#include "object_factory.hpp"
-#include "lisp/list_iterator.hpp"
-#include "object_factory.hpp"
-#include "level.hpp"
-
-static const float BOUNCY_BRICK_MAX_OFFSET = 8;
-static const float BOUNCY_BRICK_SPEED = 90;
-static const float EPSILON = .0001f;
-
-Block::Block(Sprite* newsprite)
- : sprite(newsprite), bouncing(false), breaking(false), bounce_dir(0), bounce_offset(0)
-{
- bbox.set_size(32, 32.1f);
- set_group(COLGROUP_STATIC);
- sound_manager->preload("sounds/upgrade.wav");
- sound_manager->preload("sounds/brick.wav");
-}
-
-Block::~Block()
-{
- delete sprite;
-}
-
-HitResponse
-Block::collision(GameObject& other, const CollisionHit& )
-{
- Player* player = dynamic_cast<Player*> (&other);
- if(player) {
- if(player->get_bbox().get_top() > get_bbox().get_bottom() - 7.0) {
- hit(*player);
- }
- }
-
- // only interact with other objects if...
- // 1) we are bouncing
- // and
- // 2) the object is not portable (either never or not currently)
- Portable* portable = dynamic_cast<Portable*> (&other);
- if(bouncing && (portable == 0 || (!portable->is_portable()))) {
-
- // Badguys get killed
- BadGuy* badguy = dynamic_cast<BadGuy*> (&other);
- if(badguy) {
- badguy->kill_fall();
- }
-
- // Coins get collected
- Coin* coin = dynamic_cast<Coin*> (&other);
- if(coin) {
- coin->collect();
- }
-
- }
-
- return SOLID;
-}
-
-void
-Block::update(float elapsed_time)
-{
- if(!bouncing)
- return;
-
- float offset = original_y - get_pos().y;
- if(offset > BOUNCY_BRICK_MAX_OFFSET) {
- bounce_dir = BOUNCY_BRICK_SPEED;
- movement = Vector(0, bounce_dir * elapsed_time);
- if(breaking){
- break_me();
- }
- } else if(offset < BOUNCY_BRICK_SPEED * elapsed_time && bounce_dir > 0) {
- movement = Vector(0, offset);
- bounce_dir = 0;
- bouncing = false;
- } else {
- movement = Vector(0, bounce_dir * elapsed_time);
- }
-}
-
-void
-Block::draw(DrawingContext& context)
-{
- sprite->draw(context, get_pos(), LAYER_OBJECTS+1);
-}
-
-void
-Block::start_bounce()
-{
- original_y = bbox.p1.y;
- bouncing = true;
- bounce_dir = -BOUNCY_BRICK_SPEED;
- bounce_offset = 0;
-}
-
-void
-Block::start_break()
-{
- start_bounce();
- breaking = true;
-}
-
-//---------------------------------------------------------------------------
-
-BonusBlock::BonusBlock(const Vector& pos, int data)
- : Block(sprite_manager->create("images/objects/bonus_block/bonusblock.sprite")), object(0)
-{
- bbox.set_pos(pos);
- sprite->set_action("normal");
- switch(data) {
- case 1: contents = CONTENT_COIN; break;
- case 2: contents = CONTENT_FIREGROW; break;
- case 3: contents = CONTENT_STAR; break;
- case 4: contents = CONTENT_1UP; break;
- case 5: contents = CONTENT_ICEGROW; break;
- default:
- log_warning << "Invalid box contents" << std::endl;
- contents = CONTENT_COIN;
- break;
- }
-}
-
-BonusBlock::BonusBlock(const lisp::Lisp& lisp)
- : Block(sprite_manager->create("images/objects/bonus_block/bonusblock.sprite"))
-{
- Vector pos;
-
- contents = CONTENT_COIN;
- lisp::ListIterator iter(&lisp);
- while(iter.next()) {
- const std::string& token = iter.item();
- if(token == "x") {
- iter.value()->get(pos.x);
- } else if(token == "y") {
- iter.value()->get(pos.y);
- } else if(token == "contents") {
- std::string contentstring;
- iter.value()->get(contentstring);
- if(contentstring == "coin") {
- contents = CONTENT_COIN;
- } else if(contentstring == "firegrow") {
- contents = CONTENT_FIREGROW;
- } else if(contentstring == "icegrow") {
- contents = CONTENT_ICEGROW;
- } else if(contentstring == "star") {
- contents = CONTENT_STAR;
- } else if(contentstring == "1up") {
- contents = CONTENT_1UP;
- } else if(contentstring == "custom") {
- contents = CONTENT_CUSTOM;
- } else {
- log_warning << "Invalid box contents '" << contentstring << "'" << std::endl;
- }
- } else {
- if(contents == CONTENT_CUSTOM) {
- GameObject* game_object = create_object(token, *(iter.lisp()));
- object = dynamic_cast<MovingObject*> (game_object);
- if(object == 0)
- throw std::runtime_error(
- "Only MovingObjects are allowed inside BonusBlocks");
- } else {
- log_warning << "Invalid element '" << token << "' in bonusblock" << std::endl;
- }
- }
- }
-
- if(contents == CONTENT_CUSTOM && object == 0)
- throw std::runtime_error("Need to specify content object for custom block");
-
- bbox.set_pos(pos);
-}
-
-BonusBlock::~BonusBlock()
-{
- delete object;
-}
-
-void
-BonusBlock::hit(Player& )
-{
- try_open();
-}
-
-HitResponse
-BonusBlock::collision(GameObject& other, const CollisionHit& hit){
- BadGuy* badguy = dynamic_cast<BadGuy*> (&other);
- if(badguy) {
- // hit contains no information for collisions with blocks.
- // Badguy's bottom has to be below the top of the bonusblock
- // +7 is required to slide over one tile gaps.
- if( badguy->can_break() && ( badguy->get_bbox().get_bottom() > get_bbox().get_top() + 7.0) ){
- try_open();
- }
- }
- Portable* portable = dynamic_cast<Portable*> (&other);
- if(portable) {
- MovingObject* moving = dynamic_cast<MovingObject*> (&other);
- if(moving->get_bbox().get_top() > get_bbox().get_bottom() - 7.0) {
- try_open();
- }
- }
- return Block::collision(other, hit);
-}
-
-void
-BonusBlock::try_open()
-{
- if(sprite->get_action() == "empty") {
- sound_manager->play("sounds/brick.wav");
- return;
- }
-
- Sector* sector = Sector::current();
- assert(sector);
- assert(sector->player);
- Player& player = *(sector->player);
- Direction direction = (player.get_bbox().get_middle().x > get_bbox().get_middle().x) ? LEFT : RIGHT;
-
- switch(contents) {
- case CONTENT_COIN:
- Sector::current()->add_object(new BouncyCoin(get_pos()));
- player.get_status()->add_coins(1);
- Sector::current()->get_level()->stats.coins++;
- break;
-
- case CONTENT_FIREGROW:
- if(player.get_status()->bonus == NO_BONUS) {
- SpecialRiser* riser = new SpecialRiser(get_pos(), new GrowUp(direction));
- sector->add_object(riser);
- } else {
- SpecialRiser* riser = new SpecialRiser(
- get_pos(), new Flower(FIRE_BONUS));
- sector->add_object(riser);
- }
- sound_manager->play("sounds/upgrade.wav");
- break;
-
- case CONTENT_ICEGROW:
- if(player.get_status()->bonus == NO_BONUS) {
- SpecialRiser* riser = new SpecialRiser(get_pos(), new GrowUp(direction));
- sector->add_object(riser);
- } else {
- SpecialRiser* riser = new SpecialRiser(
- get_pos(), new Flower(ICE_BONUS));
- sector->add_object(riser);
- }
- sound_manager->play("sounds/upgrade.wav");
- break;
-
- case CONTENT_STAR:
- sector->add_object(new Star(get_pos() + Vector(0, -32), direction));
- break;
-
- case CONTENT_1UP:
- sector->add_object(new OneUp(get_pos(), direction));
- break;
-
- case CONTENT_CUSTOM:
- SpecialRiser* riser = new SpecialRiser(get_pos(), object);
- object = 0;
- sector->add_object(riser);
- sound_manager->play("sounds/upgrade.wav");
- break;
- }
-
- start_bounce();
- sprite->set_action("empty");
-}
-
-void
-Block::break_me()
-{
- Sector* sector = Sector::current();
- sector->add_object(
- new BrokenBrick(new Sprite(*sprite), get_pos(), Vector(-100, -400)));
- sector->add_object(
- new BrokenBrick(new Sprite(*sprite), get_pos() + Vector(0, 16),
- Vector(-150, -300)));
- sector->add_object(
- new BrokenBrick(new Sprite(*sprite), get_pos() + Vector(16, 0),
- Vector(100, -400)));
- sector->add_object(
- new BrokenBrick(new Sprite(*sprite), get_pos() + Vector(16, 16),
- Vector(150, -300)));
- remove_me();
-}
-
-IMPLEMENT_FACTORY(BonusBlock, "bonusblock");
-
-//---------------------------------------------------------------------------
-
-Brick::Brick(const Vector& pos, int data)
- : Block(sprite_manager->create("images/objects/bonus_block/brick.sprite")), breakable(false),
- coin_counter(0)
-{
- bbox.set_pos(pos);
- if(data == 1)
- coin_counter = 5;
- else
- breakable = true;
-}
-
-void
-Brick::hit(Player& )
-{
- if(sprite->get_action() == "empty")
- return;
-
- try_break(true);
-}
-
-HitResponse
-Brick::collision(GameObject& other, const CollisionHit& hit){
- BadGuy* badguy = dynamic_cast<BadGuy*> (&other);
- if(badguy) {
- // hit contains no information for collisions with blocks.
- // Badguy's bottom has to be below the top of the brick
- // +7 is required to slide over one tile gaps.
- if( badguy->can_break() && ( badguy->get_bbox().get_bottom() > get_bbox().get_top() + 7.0 ) ){
- try_break(false);
- }
- }
- Portable* portable = dynamic_cast<Portable*> (&other);
- if(portable) {
- MovingObject* moving = dynamic_cast<MovingObject*> (&other);
- if(moving->get_bbox().get_top() > get_bbox().get_bottom() - 7.0) {
- try_break();
- }
- }
- return Block::collision(other, hit);
-}
-
-void
-Brick::try_break(bool playerhit)
-{
- if(sprite->get_action() == "empty")
- return;
-
- sound_manager->play("sounds/brick.wav");
- Sector* sector = Sector::current();
- Player& player = *(sector->player);
- if(coin_counter > 0) {
- sector->add_object(new BouncyCoin(get_pos()));
- coin_counter--;
- player.get_status()->add_coins(1);
- if(coin_counter == 0)
- sprite->set_action("empty");
- start_bounce();
- } else if(breakable) {
- if(playerhit){
- if(player.is_big()){
- start_break();
- return;
- } else {
- start_bounce();
- return;
- }
- }
- break_me();
- }
-}
-
-//IMPLEMENT_FACTORY(Brick, "brick");
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __BLOCK_H__
-#define __BLOCK_H__
-
-#include "moving_object.hpp"
-#include "lisp/lisp.hpp"
-
-class Sprite;
-class Player;
-
-class Block : public MovingObject
-{
-public:
- Block(Sprite* sprite = 0);
- ~Block();
-
- virtual HitResponse collision(GameObject& other, const CollisionHit& hit);
- virtual void update(float elapsed_time);
- virtual void draw(DrawingContext& context);
-
-protected:
- friend class FlipLevelTransformer;
-
- virtual void hit(Player& player) = 0;
- void start_bounce();
- void start_break();
- void break_me();
-
- Sprite* sprite;
- bool bouncing;
- bool breaking;
- float bounce_dir;
- float bounce_offset;
- float original_y;
-
-};
-
-class BonusBlock : public Block
-{
-public:
- BonusBlock(const Vector& pos, int data);
- BonusBlock(const lisp::Lisp& lisp);
- virtual ~BonusBlock();
- HitResponse collision(GameObject& other, const CollisionHit& hit);
-
- void try_open();
-
- enum Contents {
- CONTENT_COIN,
- CONTENT_FIREGROW,
- CONTENT_ICEGROW,
- CONTENT_STAR,
- CONTENT_1UP,
- CONTENT_CUSTOM
- };
-
- Contents contents;
-protected:
- virtual void hit(Player& player);
-
-private:
- MovingObject* object;
-};
-
-class Brick : public Block
-{
-public:
- Brick(const Vector& pos, int data);
-
- void try_break(bool playerhit = false);
- HitResponse collision(GameObject& other, const CollisionHit& hit);
-
-protected:
- virtual void hit(Player& player);
-
-private:
- bool breakable;
- int coin_counter;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include <math.h>
-#include "bullet.hpp"
-#include "resources.hpp"
-#include "camera.hpp"
-#include "sector.hpp"
-#include "sprite/sprite_manager.hpp"
-#include "badguy/badguy.hpp"
-#include "main.hpp"
-
-namespace {
- const float BULLET_XM = 600;
- const float BULLET_STARTING_YM = 0;
-}
-
-Bullet::Bullet(const Vector& pos, float xm, int dir, BonusType type)
- : life_count(3), type(type)
-{
- float speed = dir == RIGHT ? BULLET_XM : -BULLET_XM;
- physic.set_velocity_x(speed + xm);
-
- if(type == FIRE_BONUS) {
- sprite.reset(sprite_manager->create("images/objects/bullets/firebullet.sprite"));
- } else if(type == ICE_BONUS) {
- life_count = 10;
- sprite.reset(sprite_manager->create("images/objects/bullets/icebullet.sprite"));
- }
-
- bbox.set_pos(pos);
- bbox.set_size(sprite->get_current_hitbox_width(), sprite->get_current_hitbox_height());
-}
-
-Bullet::~Bullet()
-{
-}
-
-void
-Bullet::update(float elapsed_time)
-{
- // remove bullet when it's offscreen
- float scroll_x =
- Sector::current()->camera->get_translation().x;
- float scroll_y =
- Sector::current()->camera->get_translation().y;
- if (get_pos().x < scroll_x ||
- get_pos().x > scroll_x + SCREEN_WIDTH ||
-// get_pos().y < scroll_y ||
- get_pos().y > scroll_y + SCREEN_HEIGHT ||
- life_count <= 0) {
- remove_me();
- return;
- }
-
- movement = physic.get_movement(elapsed_time);
-}
-
-void
-Bullet::draw(DrawingContext& context)
-{
- sprite->draw(context, get_pos(), LAYER_OBJECTS);
-}
-
-void
-Bullet::collision_solid(const CollisionHit& hit)
-{
- if(hit.top || hit.bottom) {
- physic.set_velocity_y(-physic.get_velocity_y());
- life_count--;
- } else if(hit.left || hit.right) {
- if(type == ICE_BONUS) {
- physic.set_velocity_x(-physic.get_velocity_x());
- life_count--;
- } else
- remove_me();
- }
-}
-
-void
-Bullet::ricochet(GameObject& , const CollisionHit& hit)
-{
- collision_solid(hit);
-}
-
-HitResponse
-Bullet::collision(GameObject& , const CollisionHit& )
-{
- return FORCE_MOVE;
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __BULLET_H__
-#define __BULLET_H__
-
-#include "moving_object.hpp"
-#include "physic.hpp"
-#include "sprite/sprite.hpp"
-#include "player_status.hpp"
-
-class Bullet : public MovingObject, private UsesPhysic
-{
-public:
- Bullet(const Vector& pos, float xm, int dir, BonusType type);
- ~Bullet();
-
- void update(float elapsed_time);
- void draw(DrawingContext& context);
- void collision_solid(const CollisionHit& hit);
- HitResponse collision(GameObject& other, const CollisionHit& hit);
-
- /**
- * Makes bullet bounce off an object (that got hit).
- * To be called by the collision handler of that object.
- * Note that the @c hit parameter is filled in as perceived by the object, not by the bullet.
- */
- void ricochet(GameObject& other, const CollisionHit& hit);
-
- BonusType get_type()
- {
- return type;
- }
-
-private:
- int life_count;
- std::auto_ptr<Sprite> sprite;
- BonusType type;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#include <config.h>
-
-#include <stdexcept>
-#include <sstream>
-#include <cmath>
-
-#include "lisp/lisp.hpp"
-#include "lisp/writer.hpp"
-#include "lisp/list_iterator.hpp"
-#include "lisp/parser.hpp"
-#include "scripting/camera.hpp"
-#include "scripting/squirrel_util.hpp"
-#include "camera.hpp"
-#include "player.hpp"
-#include "tilemap.hpp"
-#include "game_session.hpp"
-#include "sector.hpp"
-#include "main.hpp"
-#include "object_factory.hpp"
-#include "log.hpp"
-#include "path.hpp"
-#include "path_walker.hpp"
-
-class CameraConfig
-{
-public:
- // 0 = No, 1 = Fix, 2 = Mario/Yoshi, 3 = Kirby
- int ymode;
- // as above, 4 = super metroid like
- int xmode;
- float kirby_rectsize_x;
- float kirby_rectsize_y;
- // where to fix the player (used for Yoshi and Fix camera)
- float target_y;
- float target_x;
- // maximum scrolling speed in Y direction
- float max_speed_y;
- float max_speed_x;
- // factor to dynamically increase max_speed_x based on player speed
- float dynamic_max_speed_x;
-
- // time the player has to face into the other direction before we assume a
- // changed direction
- float dirchange_time;
- // edge_x
- float edge_x;
- // when too change from noscroll mode back to lookahead left/right mode
- // set to <= 0 to disable noscroll mode
- float sensitive_x;
-
- float clamp_y;
- float clamp_x;
-
- float dynamic_speed_sm;
-
- CameraConfig() {
- xmode = 1;
- ymode = 1;
- target_x = .5f;
- target_y = 2.f/3.f;
- max_speed_y = 140;
- max_speed_x = 130;
- clamp_x = 1.f/6.f;
- clamp_y = 1.f/6.f;
- kirby_rectsize_x = 0.2f;
- kirby_rectsize_y = 0.34f;
- edge_x = 1.f/3.f;
- sensitive_x = 1.f/4.f;
- dynamic_max_speed_x = 1.0;
- dirchange_time = 0.2f;
- dynamic_speed_sm = 1.0f;
- }
-
- void load(const std::string& filename)
- {
- lisp::Parser parser;
- const lisp::Lisp* root = parser.parse(filename);
- const lisp::Lisp* camconfig = root->get_lisp("camera-config");
- if(camconfig == NULL)
- throw std::runtime_error("file is not a camera config file.");
-
- camconfig->get("xmode", xmode);
- camconfig->get("ymode", ymode);
- camconfig->get("target-x", target_x);
- camconfig->get("target-y", target_y);
- camconfig->get("max-speed-x", max_speed_x);
- camconfig->get("max-speed-y", max_speed_y);
- camconfig->get("dynamic-max-speed-x", dynamic_max_speed_x);
- camconfig->get("dirchange-time", dirchange_time);
- camconfig->get("clamp-x", clamp_x);
- camconfig->get("clamp-y", clamp_y);
- camconfig->get("kirby-rectsize-x", kirby_rectsize_x);
- camconfig->get("kirby-rectsize-y", kirby_rectsize_y);
- camconfig->get("edge-x", edge_x);
- camconfig->get("sensitive-x", sensitive_x);
- camconfig->get("dynamic-speed-sm", dynamic_speed_sm);
- }
-};
-
-Camera::Camera(Sector* newsector, std::string name)
- : mode(NORMAL), sector(newsector), lookahead_mode(LOOKAHEAD_NONE),
- lookahead_pos(0)
-{
- this->name = name;
- config = new CameraConfig();
- reload_config();
-}
-
-Camera::~Camera()
-{
- delete config;
-}
-
-void
-Camera::expose(HSQUIRRELVM vm, SQInteger table_idx)
-{
- if(name.empty()) return;
- Scripting::Camera* interface = new Scripting::Camera(this);
- expose_object(vm, table_idx, interface, name, true);
-}
-
-void
-Camera::unexpose(HSQUIRRELVM vm, SQInteger table_idx)
-{
- if(name.empty()) return;
- Scripting::unexpose_object(vm, table_idx, name);
-}
-
-void
-Camera::draw(DrawingContext& )
-{
-}
-
-const Vector&
-Camera::get_translation() const
-{
- return translation;
-}
-
-void
-Camera::parse(const lisp::Lisp& reader)
-{
- std::string modename;
-
- reader.get("mode", modename);
- if(modename == "normal") {
- mode = NORMAL;
- } else if(modename == "autoscroll") {
- mode = AUTOSCROLL;
-
- const lisp::Lisp* pathLisp = reader.get_lisp("path");
- if(pathLisp == NULL)
- throw std::runtime_error("No path specified in autoscroll camera.");
-
- autoscroll_path.reset(new Path());
- autoscroll_path->read(*pathLisp);
- autoscroll_walker.reset(new PathWalker(autoscroll_path.get()));
- } else if(modename == "manual") {
- mode = MANUAL;
- } else {
- std::stringstream str;
- str << "invalid camera mode '" << modename << "'found in worldfile.";
- throw std::runtime_error(str.str());
- }
-}
-
-void
-Camera::write(lisp::Writer& writer)
-{
- writer.start_list("camera");
-
- if(mode == NORMAL) {
- writer.write_string("mode", "normal");
- } else if(mode == AUTOSCROLL) {
- writer.write_string("mode", "autoscroll");
- autoscroll_path->write(writer);
- } else if(mode == MANUAL) {
- writer.write_string("mode", "manual");
- }
-
- writer.end_list("camera");
-}
-
-void
-Camera::reset(const Vector& tuxpos)
-{
- translation.x = tuxpos.x - SCREEN_WIDTH/3 * 2;
- translation.y = tuxpos.y - SCREEN_HEIGHT/2;
- shakespeed = 0;
- shaketimer.stop();
- keep_in_bounds(translation);
-}
-
-void
-Camera::shake(float time, float x, float y)
-{
- shaketimer.start(time);
- shakedepth_x = x;
- shakedepth_y = y;
- shakespeed = M_PI/2 / time;
-}
-
-void
-Camera::scroll_to(const Vector& goal, float scrolltime)
-{
- scroll_from = translation;
- scroll_goal = goal;
- keep_in_bounds(scroll_goal);
-
- scroll_to_pos = 0;
- scrollspeed = 1.0 / scrolltime;
- mode = SCROLLTO;
-}
-
-static const float EPSILON = .00001f;
-static const float MAX_SPEED_Y = 140;
-
-void
-Camera::update(float elapsed_time)
-{
- switch(mode) {
- case NORMAL:
- update_scroll_normal(elapsed_time);
- break;
- case AUTOSCROLL:
- update_scroll_autoscroll(elapsed_time);
- break;
- case SCROLLTO:
- update_scroll_to(elapsed_time);
- break;
- default:
- break;
- }
- shake();
-}
-
-void
-Camera::reload_config()
-{
- config->load("camera.cfg");
-}
-
-float clamp(float val, float min, float max)
-{
- if(val < min)
- return min;
- if(val > max)
- return max;
-
- return val;
-}
-
-void
-Camera::keep_in_bounds(Vector& translation)
-{
- float width = sector->get_width();
- float height = sector->get_height();
-
- // don't scroll before the start or after the level's end
- translation.x = clamp(translation.x, 0, width - SCREEN_WIDTH);
- translation.y = clamp(translation.y, 0, height - SCREEN_HEIGHT);
-
- if (height < SCREEN_HEIGHT)
- translation.y = height/2.0 - SCREEN_HEIGHT/2.0;
- if (width < SCREEN_WIDTH)
- translation.x = width/2.0 - SCREEN_WIDTH/2.0;
-}
-
-void
-Camera::shake()
-{
- if(shaketimer.started()) {
- translation.x -= sin(shaketimer.get_timegone() * shakespeed) * shakedepth_x;
- translation.y -= sin(shaketimer.get_timegone() * shakespeed) * shakedepth_y;
- }
-}
-
-void
-Camera::update_scroll_normal(float elapsed_time)
-{
- const CameraConfig& config = *(this->config);
- Player* player = sector->player;
- const Vector& player_pos = player->get_bbox().get_middle();
- static Vector last_player_pos = player_pos;
- Vector player_delta = player_pos - last_player_pos;
- last_player_pos = player_pos;
-
- // check that we don't have division by zero later
- if(elapsed_time < EPSILON)
- return;
-
- /****** Vertical Scrolling part ******/
- int xmode = config.xmode;
- int ymode = config.ymode;
-
- if(player->is_dying() || sector->get_height() == 19*32) {
- ymode = 0;
- }
- if(player->is_dying())
- xmode = 0;
-
- if(ymode == 1) {
- translation.y = player_pos.y - SCREEN_HEIGHT * config.target_y;
- }
- if(ymode == 2) {
- // target_y is the high we target our scrolling at. This is not always the
- // high of the player, but if he is jumping upwards we should use the
- // position where he last touched the ground. (this probably needs
- // exceptions for trampolines and similar things in the future)
- float target_y;
- if(player->fall_mode == Player::JUMPING)
- target_y = player->last_ground_y + player->get_bbox().get_height();
- else
- target_y = player->get_bbox().p2.y;
- target_y -= SCREEN_HEIGHT * config.target_y;
-
- // delta_y is the distance we'd have to travel to directly reach target_y
- float delta_y = translation.y - target_y;
- // speed is the speed the camera would need to reach target_y in this frame
- float speed_y = delta_y / elapsed_time;
-
- // limit the camera speed when jumping upwards
- if(player->fall_mode != Player::FALLING
- && player->fall_mode != Player::TRAMPOLINE_JUMP) {
- speed_y = clamp(speed_y, -config.max_speed_y, config.max_speed_y);
- }
-
- // scroll with calculated speed
- translation.y -= speed_y * elapsed_time;
- }
- if(ymode == 3) {
- float halfsize = config.kirby_rectsize_y * 0.5f;
- translation.y = clamp(translation.y,
- player_pos.y - SCREEN_HEIGHT * (0.5f + halfsize),
- player_pos.y - SCREEN_HEIGHT * (0.5f - halfsize));
- }
- if(ymode == 4) {
- // TODO...
- }
-
- if(ymode != 0 && config.clamp_y > 0) {
- translation.y = clamp(translation.y,
- player_pos.y - SCREEN_HEIGHT * (1-config.clamp_y),
- player_pos.y - SCREEN_HEIGHT * config.clamp_y);
- }
-
- /****** Horizontal scrolling part *******/
-
- if(xmode == 1) {
- translation.x = player_pos.x - SCREEN_WIDTH * config.target_x;
- }
- if(xmode == 2) {
- // our camera is either in leftscrolling, rightscrolling or
- // nonscrollingmode.
- //
- // when suddenly changing directions while scrolling into the other
- // direction abort scrolling, since tux might be going left/right at a
- // relatively small part of the map (like when jumping upwards)
-
- // Find out direction in which the player moves
- LookaheadMode walkDirection;
- if (player_delta.x < -EPSILON) walkDirection = LOOKAHEAD_LEFT;
- else if (player_delta.x > EPSILON) walkDirection = LOOKAHEAD_RIGHT;
- else if (player->dir == ::LEFT) walkDirection = LOOKAHEAD_LEFT;
- else walkDirection = LOOKAHEAD_RIGHT;
-
- float LEFTEND, RIGHTEND;
- if(config.sensitive_x > 0) {
- LEFTEND = SCREEN_WIDTH * config.sensitive_x;
- RIGHTEND = SCREEN_WIDTH * (1-config.sensitive_x);
- } else {
- LEFTEND = SCREEN_WIDTH;
- RIGHTEND = 0;
- }
-
- if(lookahead_mode == LOOKAHEAD_NONE) {
- /* if we're undecided then look if we crossed the left or right
- * "sensitive" area */
- if(player_pos.x < translation.x + LEFTEND) {
- lookahead_mode = LOOKAHEAD_LEFT;
- } else if(player_pos.x > translation.x + RIGHTEND) {
- lookahead_mode = LOOKAHEAD_RIGHT;
- }
- /* at the ends of a level it's obvious which way we will go */
- if(player_pos.x < SCREEN_WIDTH*0.5) {
- lookahead_mode = LOOKAHEAD_RIGHT;
- } else if(player_pos.x >= sector->get_width() - SCREEN_WIDTH*0.5) {
- lookahead_mode = LOOKAHEAD_LEFT;
- }
-
- changetime = -1;
- } else if(lookahead_mode != walkDirection) {
- /* player changed direction while camera was scrolling...
- * he has to do this for a certain time to add robustness against
- * sudden changes */
- if(changetime < 0) {
- changetime = game_time;
- } else if(game_time - changetime > config.dirchange_time) {
- if(lookahead_mode == LOOKAHEAD_LEFT &&
- player_pos.x > translation.x + RIGHTEND) {
- lookahead_mode = LOOKAHEAD_RIGHT;
- } else if(lookahead_mode == LOOKAHEAD_RIGHT &&
- player_pos.x < translation.x + LEFTEND) {
- lookahead_mode = LOOKAHEAD_LEFT;
- } else {
- lookahead_mode = LOOKAHEAD_NONE;
- }
- }
- } else {
- changetime = -1;
- }
-
- LEFTEND = SCREEN_WIDTH * config.edge_x;
- RIGHTEND = SCREEN_WIDTH * (1-config.edge_x);
-
- // calculate our scroll target depending on scroll mode
- float target_x;
- if(lookahead_mode == LOOKAHEAD_LEFT)
- target_x = player_pos.x - RIGHTEND;
- else if(lookahead_mode == LOOKAHEAD_RIGHT)
- target_x = player_pos.x - LEFTEND;
- else
- target_x = translation.x;
-
- // that's the distance we would have to travel to reach target_x
- float delta_x = translation.x - target_x;
- // the speed we'd need to travel to reach target_x in this frame
- float speed_x = delta_x / elapsed_time;
-
- // limit our speed
- float player_speed_x = player_delta.x / elapsed_time;
- float maxv = config.max_speed_x + (fabsf(player_speed_x * config.dynamic_max_speed_x));
- speed_x = clamp(speed_x, -maxv, maxv);
-
- // If player is peeking scroll in that direction. Fast.
- if(player->peeking_direction() == ::LEFT) {
- speed_x = config.max_speed_x;
- }
- if(player->peeking_direction() == ::RIGHT) {
- speed_x = -config.max_speed_x;
- }
-
- // apply scrolling
- translation.x -= speed_x * elapsed_time;
- }
- if(xmode == 3) {
- float halfsize = config.kirby_rectsize_x * 0.5f;
- translation.x = clamp(translation.x,
- player_pos.x - SCREEN_WIDTH * (0.5f + halfsize),
- player_pos.x - SCREEN_WIDTH * (0.5f - halfsize));
- }
- if(xmode == 4) {
- float LEFTEND = SCREEN_WIDTH * config.edge_x;
- float RIGHTEND = SCREEN_WIDTH * (1 - config.edge_x);
-
- if (player_delta.x < -EPSILON) {
- // walking left
- lookahead_pos -= player_delta.x * config.dynamic_speed_sm;
-
- if(lookahead_pos > RIGHTEND) {
- lookahead_pos = RIGHTEND;
- }
- } else if (player_delta.x > EPSILON) {
- // walking right
- lookahead_pos -= player_delta.x * config.dynamic_speed_sm;
- if(lookahead_pos < LEFTEND) {
- lookahead_pos = LEFTEND;
- }
- }
-
- if(player->peeking_direction() == ::LEFT) {
- lookahead_pos += config.max_speed_x * elapsed_time * 3.0f;
- } else if(player->peeking_direction() == ::RIGHT) {
- lookahead_pos -= config.max_speed_x * elapsed_time * 3.0f;
- }
-
- // adjust for level ends
- if (player_pos.x < LEFTEND) {
- lookahead_pos = LEFTEND;
- }
- if (player_pos.x > sector->get_width() - LEFTEND) {
- lookahead_pos = RIGHTEND;
- }
-
- translation.x = player_pos.x - lookahead_pos;
- }
-
- if(xmode != 0 && config.clamp_x > 0) {
- translation.x = clamp(translation.x,
- player_pos.x - SCREEN_WIDTH * (1-config.clamp_x),
- player_pos.x - SCREEN_WIDTH * config.clamp_x);
- }
-
- keep_in_bounds(translation);
-}
-
-void
-Camera::update_scroll_autoscroll(float elapsed_time)
-{
- Player* player = sector->player;
- if(player->is_dying())
- return;
-
- translation = autoscroll_walker->advance(elapsed_time);
-
- keep_in_bounds(translation);
-}
-
-void
-Camera::update_scroll_to(float elapsed_time)
-{
- scroll_to_pos += elapsed_time * scrollspeed;
- if(scroll_to_pos >= 1.0) {
- mode = MANUAL;
- translation = scroll_goal;
- return;
- }
-
- translation = scroll_from + (scroll_goal - scroll_from) * scroll_to_pos;
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#ifndef SUPERTUX_CAMERA_H
-#define SUPERTUX_CAMERA_H
-
-#include <vector>
-#include <cassert>
-#include <memory>
-
-#include "math/vector.hpp"
-#include "game_object.hpp"
-#include "video/drawing_context.hpp"
-#include "serializable.hpp"
-#include "timer.hpp"
-#include "script_interface.hpp"
-
-namespace lisp {
-class Lisp;
-}
-
-class Sector;
-class Path;
-class PathWalker;
-class CameraConfig;
-
-class Camera : public GameObject, public Serializable, public ScriptInterface
-{
-public:
- Camera(Sector* sector, std::string name = "");
- virtual ~Camera();
-
- /// parse camera mode from lisp file
- void parse(const lisp::Lisp& reader);
- /// write camera mode to a lisp file
- virtual void write(lisp::Writer& writer);
-
- /// reset camera postion
- void reset(const Vector& tuxpos);
-
- /** return camera position */
- const Vector& get_translation() const;
-
- virtual void update(float elapsed_time);
-
- virtual void draw(DrawingContext& );
-
- virtual void expose(HSQUIRRELVM vm, SQInteger table_idx);
- virtual void unexpose(HSQUIRRELVM vm, SQInteger table_idx);
-
- // shake camera in a direction 1 time
- void shake(float speed, float x, float y);
-
- void set_scrolling(int scroll_x, int scroll_y)
- {
- translation.x = scroll_x;
- translation.y = scroll_y;
- }
-
- /**
- * scroll the upper left edge of the camera in scrolltime seconds
- * to the position goal
- */
- void scroll_to(const Vector& goal, float scrolltime);
-
- void reload_config();
-
- enum CameraMode
- {
- NORMAL, AUTOSCROLL, SCROLLTO, MANUAL
- };
- CameraMode mode;
-
-private:
- void update_scroll_normal(float elapsed_time);
- void update_scroll_autoscroll(float elapsed_time);
- void update_scroll_to(float elapsed_time);
- void keep_in_bounds(Vector& vector);
- void shake();
-
- /**
- * The camera basically provides lookeahead on the left or right side
- * or is undecided.
- */
- enum LookaheadMode {
- LOOKAHEAD_NONE, LOOKAHEAD_LEFT, LOOKAHEAD_RIGHT
- };
-
- Vector translation;
-
- Sector* sector;
-
- // normal mode
- LookaheadMode lookahead_mode;
- float changetime;
- float lookahead_pos;
-
- // autoscroll mode
- std::auto_ptr<Path> autoscroll_path;
- std::auto_ptr<PathWalker> autoscroll_walker;
-
- // shaking
- Timer shaketimer;
- float shakespeed;
- float shakedepth_x;
- float shakedepth_y;
-
- // scrollto mode
- Vector scroll_from;
- Vector scroll_goal;
- float scroll_to_pos;
- float scrollspeed;
-
- CameraConfig *config;
-};
-
-#endif /*SUPERTUX_CAMERA_H*/
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
-//
-// 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.
-
-#include <config.h>
-
-#include "candle.hpp"
-#include "scripting/candle.hpp"
-#include "scripting/squirrel_util.hpp"
-#include "sector.hpp"
-#include "object/sprite_particle.hpp"
-#include "object_factory.hpp"
-#include "random_generator.hpp"
-
-Candle::Candle(const lisp::Lisp& lisp)
- : MovingSprite(lisp, "images/objects/candle/candle.sprite", LAYER_BACKGROUNDTILES+1, COLGROUP_DISABLED), burning(true),
- candle_light_1("images/objects/candle/candle-light-1.png"),
- candle_light_2("images/objects/candle/candle-light-2.png")
-{
- lisp.get("name", name);
- lisp.get("burning", burning);
-
- if (burning) {
- sprite->set_action("on");
- } else {
- sprite->set_action("off");
- }
-
-}
-
-void
-Candle::draw(DrawingContext& context)
-{
- // draw regular sprite
- sprite->draw(context, get_pos(), layer);
-
- // draw on lightmap
- if (burning) {
- Vector pos = get_pos() + (bbox.get_size() - candle_light_1.get_size()) / 2;
- context.push_target();
- context.set_target(DrawingContext::LIGHTMAP);
- // draw approx. 1 in 10 frames darker. Makes the candle flicker
- if (systemRandom.rand(10) != 0) {
- context.draw_surface(&candle_light_1, pos, layer);
- } else {
- context.draw_surface(&candle_light_2, pos, layer);
- }
- context.pop_target();
- }
-}
-
-HitResponse
-Candle::collision(GameObject&, const CollisionHit& )
-{
- return FORCE_MOVE;
-}
-
-void
-Candle::expose(HSQUIRRELVM vm, SQInteger table_idx)
-{
- if (name.empty()) return;
- Scripting::Candle* interface = new Scripting::Candle(this);
- expose_object(vm, table_idx, interface, name, true);
-}
-
-void
-Candle::unexpose(HSQUIRRELVM vm, SQInteger table_idx)
-{
- if (name.empty()) return;
- Scripting::unexpose_object(vm, table_idx, name);
-}
-
-void
-Candle::puff_smoke()
-{
- Vector ppos = bbox.get_middle();
- Vector pspeed = Vector(0, -150);
- Vector paccel = Vector(0,0);
- Sector::current()->add_object(new SpriteParticle("images/objects/particles/smoke.sprite", "default", ppos, ANCHOR_MIDDLE, pspeed, paccel, LAYER_BACKGROUNDTILES+2));
-}
-
-bool
-Candle::get_burning()
-{
- return burning;
-}
-
-void
-Candle::set_burning(bool burning)
-{
- if (this->burning == burning) return;
- this->burning = burning;
- if (burning) {
- sprite->set_action("on");
- puff_smoke();
- } else {
- sprite->set_action("off");
- puff_smoke();
- }
-}
-
-IMPLEMENT_FACTORY(Candle, "candle");
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
-//
-// 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.
-
-#ifndef __CANDLE_H__
-#define __CANDLE_H__
-
-#include <string>
-
-#include "lisp/lisp.hpp"
-#include "object/moving_sprite.hpp"
-#include "script_interface.hpp"
-#include "video/surface.hpp"
-
-/**
- * A burning candle: Simple, scriptable level decoration.
- */
-class Candle : public MovingSprite, public ScriptInterface
-{
-public:
- Candle(const lisp::Lisp& lisp);
- virtual Candle* clone() const { return new Candle(*this); }
- virtual void draw(DrawingContext& context);
-
- HitResponse collision(GameObject& other, const CollisionHit& hit);
-
- virtual void expose(HSQUIRRELVM vm, SQInteger table_idx);
- virtual void unexpose(HSQUIRRELVM vm, SQInteger table_idx);
-
- /**
- * @name Scriptable Methods
- * @{
- */
- void puff_smoke(); /**< spawn a puff of smoke */
- bool get_burning(); /**< returns true if candle is lighted */
- void set_burning(bool burning); /**< true: light candle, false: extinguish candle */
- /**
- * @}
- */
-
-private:
- bool burning; /**< true if candle is currently lighted */
- Surface candle_light_1; /**< drawn to lightmap */
- Surface candle_light_2; /**< drawn to lightmap (alternative image) */
-
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include "coin.hpp"
-#include "resources.hpp"
-#include "video/drawing_context.hpp"
-#include "sprite/sprite_manager.hpp"
-#include "player.hpp"
-#include "sector.hpp"
-#include "player_status.hpp"
-#include "gameobjs.hpp"
-#include "statistics.hpp"
-#include "object_factory.hpp"
-#include "level.hpp"
-#include "random_generator.hpp"
-#include "audio/sound_source.hpp"
-#include "audio/sound_manager.hpp"
-#include "timer.hpp"
-
-Coin::Coin(const Vector& pos)
- : MovingSprite(pos, "images/objects/coin/coin.sprite", LAYER_TILES, COLGROUP_TOUCHABLE)
-{
- sound_manager->preload("sounds/coin.wav");
-}
-
-Coin::Coin(const lisp::Lisp& reader)
- : MovingSprite(reader, "images/objects/coin/coin.sprite", LAYER_TILES, COLGROUP_TOUCHABLE)
-{
- sound_manager->preload("sounds/coin.wav");
-}
-
-void
-Coin::collect()
-{
- // TODO: commented out musical code. Maybe fork this for a special "MusicalCoin" object?
- /*
- static Timer sound_timer;
- static int pitch_one = 128;
- static float last_pitch = 1;
- float pitch = 1;
-
- int tile = static_cast<int>(get_pos().y / 32);
-
- if (!sound_timer.started()) {
- pitch_one = tile;
- pitch = 1;
- last_pitch = 1;
- }
- else if (sound_timer.get_timegone() < 0.02) {
- pitch = last_pitch;
- }
- else
- {
- switch ((pitch_one - tile) % 7) {
- case -6:
- pitch = 1.0/2;
- break;
- case -5:
- pitch = 5.0/8;
- break;
- case -4:
- pitch = 4.0/6;
- break;
- case -3:
- pitch = 3.0/4;
- break;
- case -2:
- pitch = 5.0/6;
- break;
- case -1:
- pitch = 9.0/10;
- break;
- case 0:
- pitch = 1.0;
- break;
- case 1:
- pitch = 9.0/8;
- break;
- case 2:
- pitch = 5.0/4;
- break;
- case 3:
- pitch = 4.0/3;
- break;
- case 4:
- pitch = 3.0/2;
- break;
- case 5:
- pitch = 5.0/3;
- break;
- case 6:
- pitch = 9.0/5;
- break;
- }
- last_pitch = pitch;
- }
- sound_timer.start(1);
-
- SoundSource* soundSource = sound_manager->create_sound_source("sounds/coin.wav");
- soundSource->set_position(get_pos());
- soundSource->set_pitch(pitch);
- soundSource->play();
- sound_manager->manage_source(soundSource);
-*/
- Sector::current()->player->get_status()->add_coins(1);
- Sector::current()->add_object(new BouncyCoin(get_pos()));
- Sector::current()->get_level()->stats.coins++;
- remove_me();
-}
-
-HitResponse
-Coin::collision(GameObject& other, const CollisionHit& )
-{
- Player* player = dynamic_cast<Player*>(&other);
- if(player == 0)
- return ABORT_MOVE;
-
- collect();
- return ABORT_MOVE;
-}
-
-IMPLEMENT_FACTORY(Coin, "coin");
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __COIN_H__
-#define __COIN_H__
-
-#include "moving_sprite.hpp"
-#include "lisp/lisp.hpp"
-
-class Coin : public MovingSprite
-{
-public:
- Coin(const Vector& pos);
- Coin(const lisp::Lisp& reader);
-
- HitResponse collision(GameObject& other, const CollisionHit& hit);
-
- void collect();
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-#include "display_effect.hpp"
-
-#include <assert.h>
-#include "video/drawing_context.hpp"
-#include "scripting/squirrel_util.hpp"
-#include "main.hpp"
-
-static const float BORDER_SIZE = 75;
-
-DisplayEffect::DisplayEffect(std::string name)
- : screen_fade(NO_FADE), screen_fadetime(0), screen_fading(0),
- border_fade(NO_FADE), border_fadetime(0), border_size(0), black(false),
- borders(false)
-{
- this->name = name;
-}
-
-DisplayEffect::~DisplayEffect()
-{
-}
-
-void
-DisplayEffect::expose(HSQUIRRELVM vm, SQInteger table_idx)
-{
- if (name.empty()) return;
- expose_object(vm, table_idx, dynamic_cast<Scripting::DisplayEffect *>(this), name, false);
-}
-
-void
-DisplayEffect::unexpose(HSQUIRRELVM vm, SQInteger table_idx)
-{
- if (name.empty()) return;
- Scripting::unexpose_object(vm, table_idx, name);
-}
-
-void
-DisplayEffect::update(float elapsed_time)
-{
- switch(screen_fade) {
- case NO_FADE:
- break;
- case FADE_IN:
- screen_fading -= elapsed_time;
- if(screen_fading < 0) {
- screen_fade = NO_FADE;
- }
- break;
- case FADE_OUT:
- screen_fading -= elapsed_time;
- if(screen_fading < 0) {
- screen_fade = NO_FADE;
- black = true;
- }
- break;
- default:
- assert(false);
- }
-
- switch(border_fade) {
- case NO_FADE:
- break;
- case FADE_IN:
- border_fading -= elapsed_time;
- if(border_fading < 0) {
- border_fade = NO_FADE;
- }
- border_size = (border_fadetime - border_fading)
- / border_fadetime * BORDER_SIZE;
- break;
- case FADE_OUT:
- border_fading -= elapsed_time;
- if(border_fading < 0) {
- borders = false;
- border_fade = NO_FADE;
- }
- border_size = border_fading / border_fadetime * BORDER_SIZE;
- break;
- default:
- assert(false);
- }
-}
-
-void
-DisplayEffect::draw(DrawingContext& context)
-{
- context.push_transform();
- context.set_translation(Vector(0, 0));
-
- if(black || screen_fade != NO_FADE) {
- float alpha;
- if(black) {
- alpha = 1.0f;
- } else {
- switch(screen_fade) {
- case FADE_IN:
- alpha = screen_fading / screen_fadetime;
- break;
- case FADE_OUT:
- alpha = (screen_fadetime - screen_fading) / screen_fadetime;
- break;
- default:
- alpha = 0;
- assert(false);
- }
- }
- context.draw_filled_rect(Vector(0, 0), Vector(SCREEN_WIDTH, SCREEN_HEIGHT),
- Color(0, 0, 0, alpha), LAYER_GUI-10);
- }
-
- if (borders) {
- context.draw_filled_rect(Vector(0, 0), Vector(SCREEN_WIDTH, border_size),
- Color(0, 0, 0, 1.0f), LAYER_GUI-10);
- context.draw_filled_rect(Vector(0, SCREEN_HEIGHT - border_size), Vector(SCREEN_WIDTH, border_size),
- Color(0, 0, 0, 1.0f), LAYER_GUI-10);
- }
-
- context.pop_transform();
-}
-
-void
-DisplayEffect::fade_out(float fadetime)
-{
- black = false;
- screen_fadetime = fadetime;
- screen_fading = fadetime;
- screen_fade = FADE_OUT;
-}
-
-void
-DisplayEffect::fade_in(float fadetime)
-{
- black = false;
- this->screen_fadetime = fadetime;
- screen_fading = fadetime;
- screen_fade = FADE_IN;
-}
-
-void
-DisplayEffect::set_black(bool enabled)
-{
- black = enabled;
-}
-
-bool
-DisplayEffect::is_black()
-{
- return black;
-}
-
-void
-DisplayEffect::sixteen_to_nine(float fadetime)
-{
- if(fadetime == 0) {
- borders = true;
- border_size = BORDER_SIZE;
- } else {
- borders = true;
- border_size = 0;
- border_fade = FADE_IN;
- border_fadetime = fadetime;
- border_fading = border_fadetime;
- }
-}
-
-void
-DisplayEffect::four_to_three(float fadetime)
-{
- if(fadetime == 0) {
- borders = false;
- } else {
- border_size = BORDER_SIZE;
- border_fade = FADE_OUT;
- border_fadetime = fadetime;
- border_fading = border_fadetime;
- }
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __OBJECT_DISPLAY_EFFECT_H__
-#define __OBJECT_DISPLAY_EFFECT_H__
-
-#include "scripting/display_effect.hpp"
-#include "game_object.hpp"
-#include "script_interface.hpp"
-
-class DisplayEffect : public GameObject, public Scripting::DisplayEffect,
- public ScriptInterface
-{
-public:
- DisplayEffect(std::string name = "");
- virtual ~DisplayEffect();
-
- void expose(HSQUIRRELVM vm, SQInteger table_idx);
- void unexpose(HSQUIRRELVM vm, SQInteger table_idx);
-
- void update(float elapsed_time);
- void draw(DrawingContext& context);
-
-
- /**
- * @name Scriptable Methods
- * @{
- */
-
- void fade_out(float fadetime);
- void fade_in(float fadetime);
- void set_black(bool enabled);
- bool is_black();
- void sixteen_to_nine(float fadetime);
- void four_to_three(float fadetime);
-
- /**
- * @}
- */
-
-private:
- enum FadeType {
- NO_FADE, FADE_IN, FADE_OUT
- };
- FadeType screen_fade;
- float screen_fadetime;
- float screen_fading;
- FadeType border_fade;
- float border_fadetime;
- float border_fading;
- float border_size;
-
- bool black;
- bool borders;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-#include "electrifier.hpp"
-#include "sector.hpp"
-#include "object/tilemap.hpp"
-#include "tile.hpp"
-
-
-Electrifier::Electrifier(uint32_t oldtile, uint32_t newtile, float seconds)
-{
- duration.start(seconds);
- change_from = oldtile;
- change_to = newtile;
- Sector::current()->change_solid_tiles(change_from,change_to);
-}
-
-Electrifier::~Electrifier() {
-}
-
-void
-Electrifier::update(float )
-{
- if (duration.check()) {
- Sector::current()->change_solid_tiles(change_to,change_from);
- remove_me();
- }
-}
-
-void
-Electrifier::draw(DrawingContext& )
-{
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __ELECTRIFIER_H__
-#define __ELECTRIFIER_H__
-
-#include "resources.hpp"
-#include "game_object.hpp"
-#include "timer.hpp"
-#include <stdint.h>
-
-//Changes all tiles with the given ID to a new one for a given amount of time, then removes itself
-//Used by the Kugelblitz to electrify water - can be used for other effects, too
-class Electrifier : public GameObject
-{
-public:
- Electrifier(uint32_t oldtile, uint32_t newtile, float seconds);
- ~Electrifier();
-protected:
- virtual void update(float time);
- virtual void draw(DrawingContext& context);
-private:
- uint32_t change_from;
- uint32_t change_to;
- Timer duration;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux - End Sequence
-// Copyright (C) 2007 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
-//
-// 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.
-
-#include <config.h>
-
-#include "endsequence.hpp"
-
-#include <stdexcept>
-#include <iostream>
-#include <sstream>
-#include "main.hpp"
-#include "resources.hpp"
-#include "sector.hpp"
-#include "gettext.hpp"
-#include "object_factory.hpp"
-#include "object/player.hpp"
-#include "video/drawing_context.hpp"
-#include "lisp/list_iterator.hpp"
-#include "log.hpp"
-#include "scripting/level_time.hpp"
-#include "scripting/squirrel_util.hpp"
-
-EndSequence::EndSequence()
-: isrunning(false), isdone(false), tux_may_walk(true)
-{
- end_sequence_controller = 0;
-}
-
-EndSequence::~EndSequence()
-{
- delete end_sequence_controller;
-}
-
-void
-EndSequence::update(float elapsed_time)
-{
- if (!isrunning) return;
- running(elapsed_time);
-}
-
-void
-EndSequence::draw(DrawingContext& /*context*/)
-{
-}
-
-void
-EndSequence::start()
-{
- if (isrunning) return;
- isrunning = true;
- isdone = false;
-
- Player& tux = *Sector::current()->player;
- end_sequence_controller = new CodeController();
- tux.set_controller(end_sequence_controller);
- tux.set_speedlimit(230); //MAX_WALK_XM
-
- starting();
-}
-
-void
-EndSequence::stop_tux()
-{
- tux_may_walk = false;
-}
-
-void
-EndSequence::stop()
-{
- if (!isrunning) return;
- isrunning = false;
- isdone = true;
- stopping();
-}
-
-bool
-EndSequence::is_tux_stopped()
-{
- return !tux_may_walk;
-}
-
- bool
-EndSequence::is_done()
-{
- return isdone;
-}
-
-void
-EndSequence::starting()
-{
-}
-
-void
-EndSequence::running(float /*elapsed_time*/)
-{
-}
-
-void
-EndSequence::stopping()
-{
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux - End Sequence
-// Copyright (C) 2007 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
-//
-// 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.
-
-#ifndef __ENDSEQUENCE_H__
-#define __ENDSEQUENCE_H__
-
-#include <memory>
-#include "game_object.hpp"
-#include "timer.hpp"
-#include "lisp/lisp.hpp"
-#include "control/codecontroller.hpp"
-
-class EndSequence : public GameObject
-{
-public:
- EndSequence();
- virtual ~EndSequence();
-
- virtual void update(float elapsed_time);
- virtual void draw(DrawingContext& context);
-
- void start(); /**< play EndSequence */
- void stop_tux(); /**< called when Tux has reached his final position */
- void stop(); /**< stop playing EndSequence, mark it as done playing */
- bool is_tux_stopped(); /**< returns true if Tux has reached his final position */
- bool is_done(); /**< returns true if EndSequence has finished playing */
-
-protected:
- virtual void starting(); /**< called when EndSequence starts */
- virtual void running(float elapsed_time); /**< called while the EndSequence is running */
- virtual void stopping(); /**< called when EndSequence stops */
-
- bool isrunning; /**< true while EndSequence plays */
- bool isdone; /**< true if EndSequence has finished playing */
- bool tux_may_walk; /**< true while tux is allowed to walk */
- CodeController* end_sequence_controller;
-
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux - End Sequence: Tux walks right
-// Copyright (C) 2007 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
-//
-// 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.
-
-#include <config.h>
-#include "endsequence_fireworks.hpp"
-#include "sector.hpp"
-#include "mainloop.hpp"
-#include "object/player.hpp"
-#include "object/fireworks.hpp"
-
-EndSequenceFireworks::EndSequenceFireworks()
-: EndSequence()
-{
-}
-
-EndSequenceFireworks::~EndSequenceFireworks()
-{
-}
-
-void
-EndSequenceFireworks::draw(DrawingContext& /*context*/)
-{
-}
-
-void
-EndSequenceFireworks::starting()
-{
- EndSequence::starting();
- endsequence_timer.start(7.3f * main_loop->get_speed());
- Sector::current()->add_object(new Fireworks());
-}
-
-void
-EndSequenceFireworks::running(float elapsed_time)
-{
- EndSequence::running(elapsed_time);
- //Player& tux = *Sector::current()->player;
-
- if (tux_may_walk) {
- end_sequence_controller->press(Controller::JUMP);
- }
-
- if (endsequence_timer.check()) isdone = true;
-}
-
-void
-EndSequenceFireworks::stopping()
-{
- EndSequence::stopping();
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux - End Sequence: Tux walks right
-// Copyright (C) 2007 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
-//
-// 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.
-
-#ifndef __ENDSEQUENCE_FIREWORKS_H__
-#define __ENDSEQUENCE_FIREWORKS_H__
-
-#include <memory>
-#include "object/endsequence.hpp"
-#include "timer.hpp"
-
-class EndSequenceFireworks : public EndSequence
-{
-public:
- EndSequenceFireworks();
- virtual ~EndSequenceFireworks();
- virtual void draw(DrawingContext& context);
-
-protected:
- virtual void starting(); /**< called when EndSequence starts */
- virtual void running(float elapsed_time); /**< called while the EndSequence is running */
- virtual void stopping(); /**< called when EndSequence stops */
-
- Timer endsequence_timer;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux - End Sequence: Tux walks right
-// Copyright (C) 2007 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
-//
-// 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.
-
-#include <config.h>
-#include "endsequence_walkleft.hpp"
-#include "sector.hpp"
-#include "mainloop.hpp"
-#include "object/player.hpp"
-
-EndSequenceWalkLeft::EndSequenceWalkLeft()
-: EndSequence()
-{
-}
-
-EndSequenceWalkLeft::~EndSequenceWalkLeft()
-{
-}
-
-void
-EndSequenceWalkLeft::draw(DrawingContext& /*context*/)
-{
-}
-
-void
-EndSequenceWalkLeft::starting()
-{
- EndSequence::starting();
- last_x_pos = -1;
- endsequence_timer.start(7.3f * main_loop->get_speed());
-}
-
-void
-EndSequenceWalkLeft::running(float elapsed_time)
-{
- EndSequence::running(elapsed_time);
- Player& tux = *Sector::current()->player;
-
- if (tux_may_walk) {
- end_sequence_controller->press(Controller::LEFT);
- if (int(last_x_pos) == int(tux.get_pos().x)) {
- end_sequence_controller->press(Controller::JUMP);
- }
- }
-
- last_x_pos = tux.get_pos().x;
-
- if (endsequence_timer.check()) isdone = true;
-}
-
-void
-EndSequenceWalkLeft::stopping()
-{
- EndSequence::stopping();
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux - End Sequence: Tux walks right
-// Copyright (C) 2007 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
-//
-// 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.
-
-#ifndef __ENDSEQUENCE_WALKLEFT_H__
-#define __ENDSEQUENCE_WALKLEFT_H__
-
-#include <memory>
-#include "object/endsequence.hpp"
-#include "timer.hpp"
-
-class EndSequenceWalkLeft : public EndSequence
-{
-public:
- EndSequenceWalkLeft();
- virtual ~EndSequenceWalkLeft();
- virtual void draw(DrawingContext& context);
-
-protected:
- virtual void starting(); /**< called when EndSequence starts */
- virtual void running(float elapsed_time); /**< called while the EndSequence is running */
- virtual void stopping(); /**< called when EndSequence stops */
-
- float last_x_pos;
- Timer endsequence_timer;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux - End Sequence: Tux walks right
-// Copyright (C) 2007 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
-//
-// 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.
-
-#include <config.h>
-#include "endsequence_walkright.hpp"
-#include "sector.hpp"
-#include "mainloop.hpp"
-#include "object/player.hpp"
-
-EndSequenceWalkRight::EndSequenceWalkRight()
-: EndSequence()
-{
-}
-
-EndSequenceWalkRight::~EndSequenceWalkRight()
-{
-}
-
-void
-EndSequenceWalkRight::draw(DrawingContext& /*context*/)
-{
-}
-
-void
-EndSequenceWalkRight::starting()
-{
- EndSequence::starting();
- last_x_pos = -1;
- endsequence_timer.start(7.3f * main_loop->get_speed());
-}
-
-void
-EndSequenceWalkRight::running(float elapsed_time)
-{
- EndSequence::running(elapsed_time);
- Player& tux = *Sector::current()->player;
-
- if (tux_may_walk) {
- end_sequence_controller->press(Controller::RIGHT);
- if (int(last_x_pos) == int(tux.get_pos().x)) {
- end_sequence_controller->press(Controller::JUMP);
- }
- }
-
- last_x_pos = tux.get_pos().x;
-
- if (endsequence_timer.check()) isdone = true;
-}
-
-void
-EndSequenceWalkRight::stopping()
-{
- EndSequence::stopping();
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux - End Sequence: Tux walks right
-// Copyright (C) 2007 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
-//
-// 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.
-
-#ifndef __ENDSEQUENCE_WALKRIGHT_H__
-#define __ENDSEQUENCE_WALKRIGHT_H__
-
-#include <memory>
-#include "object/endsequence.hpp"
-#include "timer.hpp"
-
-class EndSequenceWalkRight : public EndSequence
-{
-public:
- EndSequenceWalkRight();
- virtual ~EndSequenceWalkRight();
- virtual void draw(DrawingContext& context);
-
-protected:
- virtual void starting(); /**< called when EndSequence starts */
- virtual void running(float elapsed_time); /**< called while the EndSequence is running */
- virtual void stopping(); /**< called when EndSequence stops */
-
- float last_x_pos;
- Timer endsequence_timer;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux -- Explosion object
-// Copyright (C) 2007 Christoph Sommer <christoph.sommer@2007.expires.deltadevelopment.de>
-//
-// 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.
-
-#include <config.h>
-
-#include "explosion.hpp"
-#include "badguy/badguy.hpp"
-#include "object/sprite_particle.hpp"
-#include "random_generator.hpp"
-
-Explosion::Explosion(const Vector& pos)
- : MovingSprite(pos, "images/objects/explosion/explosion.sprite", LAYER_OBJECTS+40, COLGROUP_TOUCHABLE), state(STATE_WAITING)
-{
- sound_manager->preload("sounds/explosion.wav");
- set_pos(get_pos() - (get_bbox().get_middle() - get_pos()));
-}
-
-Explosion::Explosion(const lisp::Lisp& reader)
- : MovingSprite(reader, "images/objects/explosion/explosion.sprite", LAYER_OBJECTS+40, COLGROUP_TOUCHABLE), state(STATE_WAITING)
-{
- sound_manager->preload("sounds/explosion.wav");
-}
-
-void
-Explosion::explode()
-{
- if (state != STATE_WAITING) return;
- state = STATE_EXPLODING;
-
- set_action("default", 1);
- sprite->set_animation_loops(1); //TODO: this is necessary because set_action will not set "loops" when "action" is the default action
- sound_manager->play("sounds/explosion.wav", get_pos());
-
- // spawn some particles
- // TODO: provide convenience function in MovingSprite or MovingObject?
- for (int i = 0; i < 100; i++) {
- Vector ppos = bbox.get_middle();
- float angle = systemRandom.randf(-M_PI_2, M_PI_2);
- float velocity = systemRandom.randf(450, 900);
- float vx = sin(angle)*velocity;
- float vy = -cos(angle)*velocity;
- Vector pspeed = Vector(vx, vy);
- Vector paccel = Vector(0, 1000);
- Sector::current()->add_object(new SpriteParticle("images/objects/particles/explosion.sprite", "default", ppos, ANCHOR_MIDDLE, pspeed, paccel, LAYER_OBJECTS-1));
- }
-}
-
-void
-Explosion::update(float )
-{
- switch(state) {
- case STATE_WAITING:
- explode();
- break;
- case STATE_EXPLODING:
- if(sprite->animation_done()) {
- remove_me();
- }
- break;
- }
-}
-
-HitResponse
-Explosion::collision(GameObject& other, const CollisionHit& )
-{
- if(state != STATE_EXPLODING) return ABORT_MOVE;
-
- Player* player = dynamic_cast<Player*>(&other);
- if(player != 0) {
- player->kill(false);
- }
-
- BadGuy* badguy = dynamic_cast<BadGuy*>(&other);
- if(badguy != 0) {
- badguy->kill_fall();
- }
-
- return ABORT_MOVE;
-}
-
-IMPLEMENT_FACTORY(Explosion, "explosion");
-
+++ /dev/null
-// $Id$
-//
-// SuperTux -- Explosion object
-// Copyright (C) 2007 Christoph Sommer <christoph.sommer@2007.expires.deltadevelopment.de>
-//
-// 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.
-
-#ifndef __EXPLOSION_H__
-#define __EXPLOSION_H__
-
-#include "moving_sprite.hpp"
-#include "lisp/lisp.hpp"
-
-/**
- * Just your average explosion - goes boom, hurts Tux
- */
-class Explosion : public MovingSprite
-{
-public:
- /**
- * Create new Explosion centered(!) at @c pos
- */
- Explosion(const Vector& pos);
- Explosion(const lisp::Lisp& reader);
-
- void update(float elapsed_time);
- HitResponse collision(GameObject& other, const CollisionHit& hit);
-
-protected:
- /**
- * plays sound, starts animation
- */
- void explode();
-
-private:
- enum State {
- STATE_WAITING,
- STATE_EXPLODING
- };
- State state;
-
-};
-
-#endif
-
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Ondrej Hosek <ondra.hosek@gmail.com>
-//
-// 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.
-
-#include <config.h>
-
-#include "falling_coin.hpp"
-#include "player.hpp"
-#include "sprite/sprite_manager.hpp"
-#include "resources.hpp"
-#include "main.hpp"
-
-FallingCoin::FallingCoin(const Vector& start_position, const int vel_x)
-{
- pos = start_position;
- sprite = sprite_manager->create("images/objects/coin/coin.sprite");
- physic.set_velocity_y(-800);
- physic.set_velocity_x(vel_x);
-}
-
-FallingCoin::~FallingCoin()
-{
- delete sprite;
-}
-
-void
-FallingCoin::draw(DrawingContext& context)
-{
- sprite->draw(context, pos, LAYER_FLOATINGOBJECTS + 5);
-}
-
-void
-FallingCoin::update(float elapsed_time)
-{
- pos += physic.get_movement(elapsed_time);
- if (pos.y > SCREEN_HEIGHT)
- remove_me();
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Ondrej Hosek <ondra.hosek@gmail.com>
-//
-// 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.
-
-#ifndef __FALLING_COIN_H__
-#define __FALLING_COIN_H__
-
-#include "game_object.hpp"
-#include "math/vector.hpp"
-#include "sprite/sprite.hpp"
-#include "video/drawing_context.hpp"
-#include "physic.hpp"
-
-class FallingCoin : public GameObject, private UsesPhysic
-{
-public:
- FallingCoin(const Vector& start_position, const int x_vel);
- ~FallingCoin();
-
- void draw(DrawingContext& context);
- void update(float elapsed_time);
-private:
- Vector pos;
- Sprite* sprite;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include "firefly.hpp"
-#include "resources.hpp"
-#include "sprite/sprite_manager.hpp"
-#include "video/drawing_context.hpp"
-#include "player.hpp"
-#include "object_factory.hpp"
-#include "game_session.hpp"
-#include "sector.hpp"
-#include "random_generator.hpp"
-#include "object/sprite_particle.hpp"
-
-Firefly::Firefly(const lisp::Lisp& lisp)
- : MovingSprite(lisp, "images/objects/resetpoints/default-resetpoint.sprite", LAYER_TILES, COLGROUP_TOUCHABLE), activated(false)
-{
- initial_position = get_pos();
- if( !lisp.get( "sprite", sprite_name ) ){
- reactivate();
- return;
- }
- if( sprite_name == "" ){
- sprite_name = "images/objects/resetpoints/default-resetpoint.sprite";
- reactivate();
- return;
- }
- //Replace sprite
- sprite = sprite_manager->create( sprite_name );
- bbox.set_size(sprite->get_current_hitbox_width(), sprite->get_current_hitbox_height());
- reactivate();
-}
-
-void
-Firefly::reactivate()
-{
- if(GameSession::current()->get_reset_point_pos() == initial_position){
- // TODO: && GameSession::current()->get_reset_point_sectorname() == <sector this firefly is in>
- // GameSession::current()->get_current_sector()->get_name() is not yet initialized.
- // Worst case a resetpoint in a different sector at the same position as the real
- // resetpoint the player is spawning is set to ringing, too. Until we can check the sector, too, dont set
- // activated = true; here.
- sprite->set_action("ringing");
- }
-}
-
-void
-Firefly::write(lisp::Writer& writer)
-{
- writer.start_list("firefly");
- writer.write_float("x", bbox.p1.x);
- writer.write_float("y", bbox.p1.y);
- writer.end_list("firefly");
-}
-
-HitResponse
-Firefly::collision(GameObject& other, const CollisionHit& )
-{
- if(activated)
- return ABORT_MOVE;
-
- Player* player = dynamic_cast<Player*> (&other);
- if(player) {
- activated = true;
-// spawn some particles
-// TODO: provide convenience function in MovingSprite or MovingObject?
- for (int i = 0; i < 5; i++) {
- Vector ppos = bbox.get_middle();
- float angle = systemRandom.randf(-M_PI_2, M_PI_2);
- float velocity = systemRandom.randf(450, 900);
- float vx = sin(angle)*velocity;
- float vy = -cos(angle)*velocity;
- Vector pspeed = Vector(vx, vy);
- Vector paccel = Vector(0, 1000);
- Sector::current()->add_object(new SpriteParticle("images/objects/particles/reset.sprite", "default", ppos, ANCHOR_MIDDLE, pspeed, paccel, LAYER_OBJECTS-1));
- }
- // TODO play sound
- sprite->set_action("ringing");
- GameSession::current()->set_reset_point(Sector::current()->get_name(),
- initial_position);
- }
-
- return ABORT_MOVE;
-}
-
-IMPLEMENT_FACTORY(Firefly, "firefly");
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __FIREFLY_H__
-#define __FIREFLY_H__
-
-#include "lisp/lisp.hpp"
-#include "object/moving_sprite.hpp"
-#include "serializable.hpp"
-#include "badguy/badguy.hpp"
-
-/**
- * A Firefly: When tux touches it, it begins buzzing and you will respawn at this
- * position.
- */
-class Firefly : public MovingSprite, public Serializable
-{
-public:
- Firefly(const lisp::Lisp& lisp);
- virtual Firefly* clone() const { return new Firefly(*this); }
-
- void write(lisp::Writer& writer);
- HitResponse collision(GameObject& other, const CollisionHit& hit);
-
-private:
- bool activated;
- Vector initial_position; /**< position as in level file. This is where Tux will have to respawn, as the level is reset every time */
- void reactivate();
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include "fireworks.hpp"
-#include "resources.hpp"
-#include "sector.hpp"
-#include "camera.hpp"
-#include "particles.hpp"
-#include "main.hpp"
-#include "video/drawing_context.hpp"
-#include "audio/sound_manager.hpp"
-#include "random_generator.hpp"
-
-Fireworks::Fireworks()
-{
- timer.start(.2f);
- sound_manager->preload("sounds/fireworks.wav");
-}
-
-Fireworks::~Fireworks()
-{
-}
-
-void
-Fireworks::update(float )
-{
- if(timer.check()) {
- Sector* sector = Sector::current();
- Vector pos = sector->camera->get_translation();
- pos += Vector(systemRandom.randf(SCREEN_WIDTH),
- systemRandom.randf(SCREEN_HEIGHT/2));
-
- float red = systemRandom.randf(1.0);
- float green = systemRandom.randf(1.0);
- //float red = 0.7;
- //float green = 0.9;
- (void) red;
- (void) green;
- sector->add_object(new Particles(pos, 0, 360, Vector(140, 140),
- Vector(0, 0), 45, Color(red, green, 0), 3, 1.3f,
- LAYER_FOREGROUND1+1));
- sound_manager->play("sounds/fireworks.wav");
- timer.start(systemRandom.randf(1.0, 1.5));
- }
-}
-
-void
-Fireworks::draw(DrawingContext& )
-{
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __FIREWORKS_H__
-#define __FIREWORKS_H__
-
-#include "video/drawing_context.hpp"
-#include "game_object.hpp"
-#include "timer.hpp"
-
-class Fireworks : public GameObject
-{
-public:
- Fireworks();
- ~Fireworks();
-
- virtual void update(float elapsed_time);
- virtual void draw(DrawingContext& context);
-
-private:
- Timer timer;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include <stdexcept>
-#include "resources.hpp"
-#include "main.hpp"
-#include "math/rect.hpp"
-#include "sprite/sprite_manager.hpp"
-#include "sprite/sprite.hpp"
-#include "video/drawing_context.hpp"
-#include "lisp/lisp.hpp"
-#include "floating_image.hpp"
-
-
-FloatingImage::FloatingImage(const std::string& spritefile)
- : layer(LAYER_FOREGROUND1 + 1), visible(false), anchor(ANCHOR_MIDDLE), fading(0), fadetime(0)
-{
- sprite.reset(sprite_manager->create(spritefile));
-}
-
-FloatingImage::~FloatingImage()
-{
-}
-
-void
-FloatingImage::update(float elapsed_time)
-{
- if(fading > 0) {
- fading -= elapsed_time;
- if(fading <= 0) {
- fading = 0;
- visible = true;
- }
- } else if(fading < 0) {
- fading += elapsed_time;
- if(fading >= 0) {
- fading = 0;
- visible = false;
- }
- }
-
-// (void) elapsed_time;
-}
-
-void
-FloatingImage::set_action(const std::string& action)
-{
- sprite->set_action(action);
-}
-
-std::string
-FloatingImage::get_action()
-{
- return sprite->get_action();
-}
-
-void
-FloatingImage::fade_in(float fadetime)
-{
- this->fadetime = fadetime;
- fading = fadetime;
-}
-
-void
-FloatingImage::fade_out(float fadetime)
-{
- this->fadetime = fadetime;
- fading = -fadetime;
-}
-
-
-void
-FloatingImage::draw(DrawingContext& context)
-{
- context.push_transform();
- context.set_translation(Vector(0, 0));
-
- if(fading > 0) {
- context.set_alpha((fadetime-fading) / fadetime);
- } else if(fading < 0) {
- context.set_alpha(-fading / fadetime);
- } else if(!visible) {
- context.pop_transform();
- return;
- }
-
- Vector spos = pos + get_anchor_pos(Rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT),
- sprite->get_width(), sprite->get_height(), anchor);
-
- sprite->draw(context, spos, layer);
-
- context.pop_transform();
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __FLOATING_IMAGE_H__
-#define __FLOATING_IMAGE_H__
-
-#include "game_object.hpp"
-#include "math/vector.hpp"
-#include "anchor_point.hpp"
-#include <memory>
-
-class Sprite;
-
-class FloatingImage : public GameObject
-{
-public:
- FloatingImage(const std::string& sprite);
- virtual ~FloatingImage();
-
- void set_layer(int layer) {
- this->layer = layer;
- }
-
- int get_layer() const {
- return layer;
- }
-
- void set_pos(const Vector& pos) {
- this->pos = pos;
- }
- const Vector& get_pos() const {
- return pos;
- }
-
- void set_anchor_point(AnchorPoint anchor) {
- this->anchor = anchor;
- }
- AnchorPoint get_anchor_point() const {
- return anchor;
- }
-
- void set_visible(bool visible) {
- this->visible = visible;
- }
- bool get_visible() const {
- return visible;
- }
-
- void set_action(const std::string& action);
- std::string get_action();
-
- void fade_in(float fadetime);
- void fade_out(float fadetime);
-
- void update(float elapsed_time);
- void draw(DrawingContext& context);
-
-private:
- std::auto_ptr<Sprite> sprite;
- int layer;
- bool visible;
- AnchorPoint anchor;
- Vector pos;
- float fading;
- float fadetime;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include <math.h>
-#include <assert.h>
-#include "flower.hpp"
-#include "resources.hpp"
-#include "camera.hpp"
-#include "sector.hpp"
-#include "player.hpp"
-#include "audio/sound_manager.hpp"
-#include "sprite/sprite_manager.hpp"
-
-Flower::Flower(BonusType _type)
- : type(_type)
-{
- bbox.set_size(32, 32);
-
- if(type == FIRE_BONUS) {
- sprite = sprite_manager->create("images/powerups/fireflower/fireflower.sprite");
- sound_manager->preload("sounds/fire-flower.wav");
- }
- else if(type == ICE_BONUS) {
- sprite = sprite_manager->create("images/powerups/iceflower/iceflower.sprite");
- } else {
- assert(false);
- }
-
- set_group(COLGROUP_TOUCHABLE);
-}
-
-Flower::~Flower()
-{
- delete sprite;
-}
-
-void
-Flower::update(float )
-{
-}
-
-void
-Flower::draw(DrawingContext& context)
-{
- sprite->draw(context, get_pos(), LAYER_OBJECTS);
-}
-
-HitResponse
-Flower::collision(GameObject& other, const CollisionHit& )
-{
- Player* player = dynamic_cast<Player*>(&other);
- if(!player)
- return ABORT_MOVE;
-
- if(!player->add_bonus(type, true))
- return FORCE_MOVE;
-
- sound_manager->play("sounds/fire-flower.wav");
- remove_me();
- return ABORT_MOVE;
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __FLOWER_H__
-#define __FLOWER_H__
-
-#include "moving_object.hpp"
-#include "sprite/sprite.hpp"
-#include "player_status.hpp"
-
-class Flower : public MovingObject
-{
-public:
- Flower(BonusType type);
- ~Flower();
-
- virtual void update(float elapsed_time);
- virtual void draw(DrawingContext& context);
- virtual HitResponse collision(GameObject& other, const CollisionHit& hit);
-
-private:
- BonusType type;
- Sprite* sprite;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include <algorithm>
-#include <iostream>
-#include <cmath>
-
-#include "tile.hpp"
-#include "tile_manager.hpp"
-#include "game_session.hpp"
-#include "gameobjs.hpp"
-#include "sprite/sprite_manager.hpp"
-#include "sprite/sprite.hpp"
-#include "resources.hpp"
-#include "sector.hpp"
-#include "tilemap.hpp"
-#include "video/drawing_context.hpp"
-#include "camera.hpp"
-#include "main.hpp"
-#include "random_generator.hpp"
-
-BouncyCoin::BouncyCoin(const Vector& pos)
- : position(pos)
-{
- timer.start(.3f);
- sprite = sprite_manager->create("images/objects/coin/coin.sprite");
- sprite->set_action("still");
-}
-
-BouncyCoin::~BouncyCoin()
-{
- delete sprite;
-}
-
-void
-BouncyCoin::update(float elapsed_time)
-{
- position.y += -200 * elapsed_time;
-
- if(timer.check())
- remove_me();
-}
-
-void
-BouncyCoin::draw(DrawingContext& context)
-{
- sprite->draw(context, position, LAYER_OBJECTS + 5);
-}
-
-//---------------------------------------------------------------------------
-
-BrokenBrick::BrokenBrick(Sprite* nsprite,
- const Vector& pos, const Vector& nmovement)
- : sprite(new Sprite(*nsprite)), position(pos), movement(nmovement)
-{
- timer.start(.2f);
-}
-
-BrokenBrick::~BrokenBrick()
-{
- delete sprite;
-}
-
-void
-BrokenBrick::update(float elapsed_time)
-{
- position += movement * elapsed_time;
-
- if (timer.check())
- remove_me();
-}
-
-void
-BrokenBrick::draw(DrawingContext& context)
-{
- sprite->draw_part(context,
- Vector(systemRandom.rand(16), systemRandom.rand(16)), Vector(16, 16),
- position, LAYER_OBJECTS + 1);
-}
-
-//---------------------------------------------------------------------------
-
-FloatingText::FloatingText(const Vector& pos, const std::string& text_)
- : position(pos), text(text_)
-{
- timer.start(.1f);
- position.x -= text.size() * 8;
-}
-
-FloatingText::FloatingText(const Vector& pos, int score)
- : position(pos)
-{
- timer.start(.1f);
-
- // turn int into a string
- char str[10];
- snprintf(str, 10, "%d", score);
- text = str;
-
- position.x -= text.size() * 8;
-}
-
-void
-FloatingText::update(float elapsed_time)
-{
- position.y -= 1.4 * elapsed_time;
-
- if(timer.check())
- remove_me();
-}
-
-#define FADING_TIME .350
-
-void
-FloatingText::draw(DrawingContext& context)
-{
- // make an alpha animation when disapearing
- int alpha;
- if(timer.get_timeleft() < FADING_TIME)
- alpha = int(timer.get_timeleft() * 255 / FADING_TIME);
- else
- alpha = 255;
-
- context.push_transform();
- context.set_alpha(alpha);
-
- context.draw_text(gold_text, text, position, ALIGN_LEFT, LAYER_OBJECTS+1);
-
- context.pop_transform();
-}
-
-Sprite *img_smoke_cloud = 0;
-
-SmokeCloud::SmokeCloud(const Vector& pos)
- : position(pos)
-{
- timer.start(.3f);
- sprite = sprite_manager->create("images/objects/particles/stomp.sprite");
-}
-
-SmokeCloud::~SmokeCloud()
-{
- delete sprite;
-}
-
-void
-SmokeCloud::update(float elapsed_time)
-{
- position.y -= 120 * elapsed_time;
-
- if(timer.check())
- remove_me();
-}
-
-void
-SmokeCloud::draw(DrawingContext& context)
-{
- sprite->draw(context, position, LAYER_OBJECTS+1);
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef SUPERTUX_GAMEOBJS_H
-#define SUPERTUX_GAMEOBJS_H
-
-#include "video/surface.hpp"
-#include "timer.hpp"
-#include "game_object.hpp"
-#include "moving_object.hpp"
-#include "serializable.hpp"
-#include "video/color.hpp"
-
-/* Bounciness of distros: */
-#define NO_BOUNCE 0
-#define BOUNCE 1
-
-class Sprite;
-
-class BouncyCoin : public GameObject
-{
-public:
- BouncyCoin(const Vector& pos);
- ~BouncyCoin();
- virtual void update(float elapsed_time);
- virtual void draw(DrawingContext& context);
-
-private:
- Sprite* sprite;
- Vector position;
- Timer timer;
-};
-
-class BrokenBrick : public GameObject
-{
-public:
- BrokenBrick(Sprite* sprite, const Vector& pos, const Vector& movement);
- ~BrokenBrick();
-
- virtual void update(float elapsed_time);
- virtual void draw(DrawingContext& context);
-
-private:
- Timer timer;
- Sprite* sprite;
- Vector position;
- Vector movement;
-};
-
-class FloatingText : public GameObject
-{
-public:
- FloatingText(const Vector& pos, const std::string& text_);
- FloatingText(const Vector& pos, int s); // use this for score, for instance
-
- virtual void update(float elapsed_time);
- virtual void draw(DrawingContext& context);
-
-private:
- Vector position;
- std::string text;
- Timer timer;
-};
-
-class SmokeCloud : public GameObject
-{
-public:
- SmokeCloud(const Vector& pos);
- ~SmokeCloud();
-
- virtual void update(float elapsed_time);
- virtual void draw(DrawingContext& context);
-
-private:
- Sprite* sprite;
- Timer timer;
- Vector position;
-};
-
-#endif
-
-/* Local Variables: */
-/* mode:c++ */
-/* End: */
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include <stdexcept>
-#include "gradient.hpp"
-#include "camera.hpp"
-#include "video/drawing_context.hpp"
-#include "lisp/lisp.hpp"
-#include "lisp/writer.hpp"
-#include "object_factory.hpp"
-#include "resources.hpp"
-#include "main.hpp"
-#include "log.hpp"
-
-Gradient::Gradient()
- : layer(LAYER_BACKGROUND0)
-{
-}
-
-Gradient::Gradient(const lisp::Lisp& reader)
- : layer(LAYER_BACKGROUND0)
-{
- reader.get("layer", layer);
- std::vector<float> bkgd_top_color, bkgd_bottom_color;
- if(!reader.get_vector("top_color", bkgd_top_color) ||
- !reader.get_vector("bottom_color", bkgd_bottom_color))
- throw std::runtime_error("Must specify top_color and bottom_color in gradient");
-
- gradient_top = Color(bkgd_top_color);
- gradient_bottom = Color(bkgd_bottom_color);
-}
-
-Gradient::~Gradient()
-{
-}
-
-void
-Gradient::write(lisp::Writer& writer)
-{
- writer.start_list("gradient");
-
- std::vector<float> bkgd_top_color, bkgd_bottom_color;
- bkgd_top_color.push_back(gradient_top.red);
- bkgd_top_color.push_back(gradient_top.green);
- bkgd_top_color.push_back(gradient_top.blue);
- bkgd_bottom_color.push_back(gradient_bottom.red);
- bkgd_bottom_color.push_back(gradient_bottom.green);
- bkgd_bottom_color.push_back(gradient_bottom.blue);
- writer.write_float_vector("top_color", bkgd_top_color);
- writer.write_float_vector("bottom_color", bkgd_bottom_color);
-
- writer.write_int("layer", layer);
-
- writer.end_list("gradient");
-}
-
-void
-Gradient::update(float)
-{
-}
-
-void
-Gradient::set_gradient(Color top, Color bottom)
-{
- gradient_top = top;
- gradient_bottom = bottom;
-
- if (gradient_top.red > 1.0 || gradient_top.green > 1.0
- || gradient_top.blue > 1.0 || gradient_top.alpha > 1.0)
- log_warning << "top gradient color has values above 1.0" << std::endl;
- if (gradient_bottom.red > 1.0 || gradient_bottom.green > 1.0
- || gradient_bottom.blue > 1.0 || gradient_bottom.alpha > 1.0)
- log_warning << "bottom gradient color has values above 1.0" << std::endl;
-}
-
-void
-Gradient::draw(DrawingContext& context)
-{
- context.push_transform();
- context.set_translation(Vector(0, 0));
- context.draw_gradient(gradient_top, gradient_bottom, layer);
- context.pop_transform();
-}
-
-IMPLEMENT_FACTORY(Gradient, "gradient");
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef SUPERTUX_GRADIENT_H
-#define SUPERTUX_GRADIENT_H
-
-#include <memory>
-#include "video/surface.hpp"
-#include "video/drawing_context.hpp"
-#include "game_object.hpp"
-#include "serializable.hpp"
-
-class DisplayManager;
-
-namespace lisp {
-class Lisp;
-}
-
-class Gradient : public GameObject, public Serializable
-{
-public:
- Gradient();
- Gradient(const lisp::Lisp& reader);
- virtual ~Gradient();
-
- virtual void write(lisp::Writer& writer);
-
- void set_gradient(Color top, Color bottom);
-
- Color get_gradient_top() const
- { return gradient_top; }
-
- Color get_gradient_bottom() const
- { return gradient_bottom; }
-
- virtual void update(float elapsed_time);
-
- virtual void draw(DrawingContext& context);
-
-private:
- int layer;
- Color gradient_top, gradient_bottom;
-};
-
-#endif /*SUPERTUX_BACKGROUND_H*/
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include <math.h>
-#include "growup.hpp"
-#include "resources.hpp"
-#include "camera.hpp"
-#include "sector.hpp"
-#include "player.hpp"
-#include "audio/sound_manager.hpp"
-
-GrowUp::GrowUp(Direction direction)
- : MovingSprite(Vector(0,0), "images/powerups/egg/egg.sprite", LAYER_OBJECTS, COLGROUP_MOVING)
-{
- physic.enable_gravity(true);
- physic.set_velocity_x((direction == LEFT)?-100:100);
- sound_manager->preload("sounds/grow.wav");
-}
-
-void
-GrowUp::update(float elapsed_time)
-{
- movement = physic.get_movement(elapsed_time);
-}
-
-void
-GrowUp::collision_solid(const CollisionHit& hit)
-{
- if(hit.top || hit.bottom)
- physic.set_velocity_y(0);
- if(hit.left || hit.right)
- physic.set_velocity_x(-physic.get_velocity_x());
-}
-
-HitResponse
-GrowUp::collision(GameObject& other, const CollisionHit& )
-{
- Player* player = dynamic_cast<Player*>(&other);
- if(player != 0) {
- if(!player->add_bonus(GROWUP_BONUS, true))
- return FORCE_MOVE;
-
- sound_manager->play("sounds/grow.wav");
- remove_me();
-
- return ABORT_MOVE;
- }
-
- return FORCE_MOVE;
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __GROWUP_H__
-#define __GROWUP_H__
-
-#include "object/moving_sprite.hpp"
-#include "physic.hpp"
-#include "direction.hpp"
-
-class GrowUp : public MovingSprite, private UsesPhysic
-{
-public:
- GrowUp(Direction direction = RIGHT);
- virtual GrowUp* clone() const { return new GrowUp(*this); }
-
- virtual void update(float elapsed_time);
- virtual void collision_solid(const CollisionHit& hit);
- virtual HitResponse collision(GameObject& other, const CollisionHit& hit);
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux - Hurting Platform
-// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
-//
-// 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.
-
-#include <config.h>
-#include <stdexcept>
-
-#include "hurting_platform.hpp"
-
-#include "log.hpp"
-#include "player.hpp"
-#include "badguy/badguy.hpp"
-#include "object_factory.hpp"
-
-HurtingPlatform::HurtingPlatform(const lisp::Lisp& reader)
- : Platform(reader)
-{
- set_group(COLGROUP_TOUCHABLE);
-}
-
-HitResponse
-HurtingPlatform::collision(GameObject& other, const CollisionHit& )
-{
- Player* player = dynamic_cast<Player*>(&other);
- if (player) {
- player->kill(false);
- }
- BadGuy* badguy = dynamic_cast<BadGuy*>(&other);
- if (badguy) {
- badguy->kill_fall();
- }
-
- return FORCE_MOVE;
-}
-
-IMPLEMENT_FACTORY(HurtingPlatform, "hurting_platform");
+++ /dev/null
-// $Id$
-//
-// SuperTux - Hurting Platform
-// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
-//
-// 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.
-
-#ifndef __HURTING_PLATFORM_H__
-#define __HURTING_PLATFORM_H__
-
-#include <memory>
-#include "object/platform.hpp"
-
-/**
- * Platform that hurts Tux and Badguys when touched
- */
-class HurtingPlatform : public Platform
-{
-public:
- HurtingPlatform(const lisp::Lisp& reader);
- virtual HurtingPlatform* clone() const { return new HurtingPlatform(*this); }
-
- virtual HitResponse collision(GameObject& other, const CollisionHit& hit);
-
-private:
-
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include "infoblock.hpp"
-#include "game_session.hpp"
-#include "resources.hpp"
-#include "sprite/sprite_manager.hpp"
-#include "object_factory.hpp"
-#include "lisp/lisp.hpp"
-#include "sector.hpp"
-#include "log.hpp"
-#include "object/player.hpp"
-#include "main.hpp"
-
-namespace {
- const float SCROLL_DELAY = 0.5;
- const float SCROLL_DISTANCE = 16;
- const float WIDTH = 400;
- const float HEIGHT = 200;
-}
-
-InfoBlock::InfoBlock(const lisp::Lisp& lisp)
- : Block(sprite_manager->create("images/objects/bonus_block/infoblock.sprite")), shown_pct(0), dest_pct(0)
-{
- Vector pos;
- lisp.get("x", pos.x);
- lisp.get("y", pos.y);
- bbox.set_pos(pos);
-
- if(!lisp.get("message", message)) {
- log_warning << "No message in InfoBlock" << std::endl;
- }
- //stopped = false;
- //ringing = new AmbientSound(get_pos(), 0.5, 300, 1, "sounds/phone.wav");
- //Sector::current()->add_object(ringing);
-
- // Split text string lines into a vector
- lines = InfoBoxLine::split(message, 400);
- lines_height = 0;
- for(size_t i = 0; i < lines.size(); ++i) lines_height+=lines[i]->get_height();
-}
-
-InfoBlock::~InfoBlock()
-{
- for(std::vector<InfoBoxLine*>::iterator i = lines.begin(); i != lines.end(); i++) {
- delete *i;
- }
-}
-
-void
-InfoBlock::hit(Player& )
-{
- start_bounce();
-
- //if (!stopped) {
- // ringing->remove_me();
- // stopped = true;
- //}
-
- if (dest_pct != 1) {
-
- // first hide all other InfoBlocks' messages in same sector
- Sector* parent = Sector::current();
- if (!parent) return;
- for (Sector::GameObjects::iterator i = parent->gameobjects.begin(); i != parent->gameobjects.end(); i++) {
- InfoBlock* block = dynamic_cast<InfoBlock*>(*i);
- if (!block) continue;
- if (block != this) block->hide_message();
- }
-
- // show our message
- show_message();
-
- } else {
- hide_message();
- }
-}
-
-Player*
-InfoBlock::get_nearest_player()
-{
- // FIXME: does not really return nearest player
-
- std::vector<Player*> players = Sector::current()->get_players();
- for (std::vector<Player*>::iterator playerIter = players.begin(); playerIter != players.end(); ++playerIter) {
- Player* player = *playerIter;
- return player;
- }
-
- return 0;
-}
-
-void
-InfoBlock::update(float delta)
-{
- Block::update(delta);
-
- if (delta == 0) return;
-
- // hide message if player is too far away or above infoblock
- if (dest_pct > 0) {
- Player* player = get_nearest_player();
- if (player) {
- Vector p1 = this->get_pos() + (this->get_bbox().p2 - this->get_bbox().p1) / 2;
- Vector p2 = player->get_pos() + (player->get_bbox().p2 - player->get_bbox().p1) / 2;
- Vector dist = (p2 - p1);
- float d = dist.norm();
- if (d > 128 || dist.y < 0) dest_pct = 0;
- }
- }
-
- // handle soft fade-in and fade-out
- if (shown_pct != dest_pct) {
- if (dest_pct > shown_pct) shown_pct = std::min(shown_pct + 2*delta, dest_pct);
- if (dest_pct < shown_pct) shown_pct = std::max(shown_pct - 2*delta, dest_pct);
- }
-}
-
-void
-InfoBlock::draw(DrawingContext& context)
-{
- Block::draw(context);
-
- if (shown_pct <= 0) return;
-
- context.push_transform();
- //context.set_translation(Vector(0, 0));
- context.set_alpha(shown_pct);
-
- //float x1 = SCREEN_WIDTH/2-200;
- //float y1 = SCREEN_HEIGHT/2-200;
- float border = 8;
- float width = 400; // this is the text width only
- float height = lines_height; // this is the text height only
- float x1 = (get_bbox().p1.x + get_bbox().p2.x)/2 - width/2;
- float x2 = (get_bbox().p1.x + get_bbox().p2.x)/2 + width/2;
- float y1 = original_y - height;
-
- // lines_height includes one ITEMS_SPACE too much, so the bottom border is reduced by 4px
- context.draw_filled_rect(Vector(x1-border, y1-border), Vector(width+2*border, height+2*border-4), Color(0.6f, 0.7f, 0.8f, 0.5f), LAYER_GUI-50);
-
- float y = y1;
- for(size_t i = 0; i < lines.size(); ++i) {
- if(y >= y1 + height) {
- //log_warning << "Too many lines of text in InfoBlock" << std::endl;
- //dest_pct = 0;
- //shown_pct = 0;
- break;
- }
-
- lines[i]->draw(context, Rect(x1, y, x2, y), LAYER_GUI-50+1);
- y += lines[i]->get_height();
- }
-
- context.pop_transform();
-}
-
-void
-InfoBlock::show_message()
-{
- dest_pct = 1;
-}
-
-void
-InfoBlock::hide_message()
-{
- dest_pct = 0;
-}
-
-IMPLEMENT_FACTORY(InfoBlock, "infoblock")
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __INFOBLOCK_H__
-#define __INFOBLOCK_H__
-
-#include "block.hpp"
-//#include "object/ambient_sound.hpp"
-#include "textscroller.hpp"
-
-class InfoBlock : public Block
-{
-public:
- InfoBlock(const lisp::Lisp& lisp);
- virtual ~InfoBlock();
- void update(float elapsed_time);
- void draw(DrawingContext& context);
-
- void show_message();
- void hide_message();
-
-protected:
- virtual void hit(Player& player);
- std::string message;
- //AmbientSound* ringing;
- //bool stopped;
- float shown_pct; /**< Value in the range of 0..1, depending on how much of the infobox is currently shown */
- float dest_pct; /**< With each call to update(), shown_pct will slowly transition to this value */
-
- Player* get_nearest_player();
-
- std::vector<InfoBoxLine*> lines; /**< lines of text (or images) to display */
- float lines_height;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include "invisible_block.hpp"
-#include "resources.hpp"
-#include "sprite/sprite.hpp"
-#include "sprite/sprite_manager.hpp"
-#include "video/drawing_context.hpp"
-#include "audio/sound_manager.hpp"
-#include "object_factory.hpp"
-#include "object/player.hpp"
-
-InvisibleBlock::InvisibleBlock(const Vector& pos)
- : Block(sprite_manager->create("images/objects/bonus_block/invisibleblock.sprite")), visible(false)
-{
- bbox.set_pos(pos);
- sound_manager->preload("sounds/brick.wav");
- sound_manager->preload("sounds/brick.wav");
-}
-
-void
-InvisibleBlock::draw(DrawingContext& context)
-{
- if(visible)
- sprite->draw(context, get_pos(), LAYER_OBJECTS);
-}
-
-bool
-InvisibleBlock::collides(GameObject& other, const CollisionHit& )
-{
- if(visible)
- return true;
-
- // if we're not visible, only register a collision if this will make us visible
- Player* player = dynamic_cast<Player*> (&other);
- if ((player)
- && (player->get_movement().y <= 0)
- && (player->get_bbox().get_top() > get_bbox().get_bottom() - 7.0)) {
- return true;
- }
-
- return false;
-}
-
-HitResponse
-InvisibleBlock::collision(GameObject& other, const CollisionHit& hit)
-{
- return Block::collision(other, hit);
-}
-
-void
-InvisibleBlock::hit(Player& )
-{
- sound_manager->play("sounds/brick.wav");
-
- if(visible)
- return;
-
- sprite->set_action("empty");
- start_bounce();
- set_group(COLGROUP_STATIC);
- visible = true;
-}
-
-//IMPLEMENT_FACTORY(InvisibleBlock, "invisible_block");
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __INVISIBLE_BLOCK_H__
-#define __INVISIBLE_BLOCK_H__
-
-#include "block.hpp"
-
-class InvisibleBlock : public Block
-{
-public:
- InvisibleBlock(const Vector& pos);
-
- virtual void draw(DrawingContext& context);
- virtual bool collides(GameObject& other, const CollisionHit& hit);
- virtual HitResponse collision(GameObject& other, const CollisionHit& hit);
-
-protected:
- virtual void hit(Player& player);
-
-private:
- bool visible;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include "invisible_wall.hpp"
-#include "lisp/lisp.hpp"
-#include "object_factory.hpp"
-#include "sprite/sprite.hpp"
-
-InvisibleWall::InvisibleWall(const lisp::Lisp& lisp)
- : MovingSprite(lisp, "images/objects/invisible/invisible.sprite", LAYER_TILES, COLGROUP_STATIC), width(32), height(32)
-{
- lisp.get("width", width);
- lisp.get("height", height);
- bbox.set_size(width, height);
-}
-
-HitResponse
-InvisibleWall::collision(GameObject& , const CollisionHit& )
-{
- return FORCE_MOVE;
-}
-
-IMPLEMENT_FACTORY(InvisibleWall, "invisible_wall");
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __INVISIBLE_WALL_H__
-#define __INVISIBLE_WALL_H__
-
-#include "object/moving_sprite.hpp"
-#include "lisp/lisp.hpp"
-#include "physic.hpp"
-#include "timer.hpp"
-
-class Player;
-
-/** A tile that starts falling down if tux stands to long on it */
-class InvisibleWall : public MovingSprite, private UsesPhysic
-{
-public:
- InvisibleWall(const lisp::Lisp& lisp);
- virtual InvisibleWall* clone() const { return new InvisibleWall(*this); }
-
- HitResponse collision(GameObject& other, const CollisionHit& hit);
-
-private:
- float width, height;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux - Ispy
-// Copyright (C) 2007 Christoph Sommer <christoph.sommer@2007.expires.deltadevelopment.de>
-//
-// 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.
-
-#include <config.h>
-
-#include "ispy.hpp"
-#include "resources.hpp"
-#include "sprite/sprite_manager.hpp"
-#include "video/drawing_context.hpp"
-#include "player.hpp"
-#include "object_factory.hpp"
-#include "game_session.hpp"
-#include "sector.hpp"
-#include "tile.hpp"
-#include "object/tilemap.hpp"
-#include "random_generator.hpp"
-#include "object/sprite_particle.hpp"
-
-Ispy::Ispy(const lisp::Lisp& reader)
- : MovingSprite(reader, "images/objects/ispy/ispy.sprite", LAYER_TILES+5, COLGROUP_DISABLED), state(ISPYSTATE_IDLE), dir(AUTO)
-{
- // read script to execute
- reader.get("script", script);
-
- // read direction to face in
- std::string dir_str;
- bool facing_down = false;
- reader.get("direction", dir_str);
- if( dir_str == "left" ) dir = LEFT;
- if( dir_str == "right" ) dir = RIGHT;
- reader.get("facing-down", facing_down);
- if (facing_down) dir = DOWN;
- if (dir == AUTO) log_warning << "Setting an Ispy's direction to AUTO is no good idea" << std::endl;
-
- // set initial sprite action
- sprite->set_action((dir == DOWN) ? "idle-down" : ((dir == LEFT) ? "idle-left" : "idle-right"));
-}
-
-void
-Ispy::write(lisp::Writer& writer)
-{
- writer.start_list("ispy");
- writer.write_float("x", bbox.p1.x);
- writer.write_float("y", bbox.p1.y);
- writer.write_string("script", script);
- switch (dir)
- {
- case DOWN:
- writer.write_string("direction", "down"); break;
- case LEFT:
- writer.write_string("direction", "left"); break;
- case RIGHT:
- writer.write_string("direction", "right"); break;
- default: break;
- }
- writer.end_list("ispy");
-}
-
-HitResponse
-Ispy::collision(GameObject& , const CollisionHit& )
-{
- return ABORT_MOVE;
-}
-
-bool
-Ispy::line_intersects_line(Vector line1_start, Vector line1_end, Vector line2_start, Vector line2_end) {
- // Adapted from Striker, (C) 1999 Joris van der Hoeven, GPL
-
- float a1 = line1_start.x, b1 = line1_start.y, a2 = line1_end.x, b2 = line1_end.y;
- float c1 = line2_start.x, d1 = line2_start.y, c2 = line2_end.x, d2 = line2_end.y;
-
- float num = (b2-b1)*(c2-c1) - (a2-a1)*(d2-d1);
- float den1 = (d2-b2)*(c1-c2) + (a2-c2)*(d1-d2);
- float den2 = (d2-b2)*(a1-a2) + (a2-c2)*(b1-b2);
-
- // normalize to positive numerator
- if (num < 0) {
- num =- num;
- den1 =- den1;
- den2 =- den2;
- }
-
- // numerator is zero -> Check for parallel or coinciding lines
- if (num == 0) {
- if ((b1-b2)*(c1-a2) != (a1-a2)*(d1-b2)) return false;
- if (a1 == a2) {
- std::swap(a1, b1);
- std::swap(a2, b2);
- std::swap(c1, d1);
- std::swap(c2, d2);
- }
- if (a1 > a2) std::swap(a1, a2);
- if (c1 > c2) std::swap(c1, c2);
- return ((a1 <= c2) && (a2 >= c1));
- }
-
- // Standard check
- return (den1>=0) && (den1<=num) && (den2>=0) && (den2<=num);
-
-}
-
-bool
-Ispy::intersects_line(Rect r, Vector line_start, Vector line_end)
-{
- Vector p1 = r.p1;
- Vector p2 = Vector(r.p2.x, r.p1.y);
- Vector p3 = r.p2;
- Vector p4 = Vector(r.p1.x, r.p2.y);
- if (line_intersects_line(p1, p2, line_start, line_end)) return true;
- if (line_intersects_line(p2, p3, line_start, line_end)) return true;
- if (line_intersects_line(p3, p4, line_start, line_end)) return true;
- if (line_intersects_line(p4, p1, line_start, line_end)) return true;
- return false;
-}
-
-bool
-Ispy::free_line_of_sight(Vector line_start, Vector line_end, const MovingObject* ignore_object)
-{
-
- // check if no tile is in the way
- float lsx = std::min(line_start.x, line_end.x);
- float lex = std::max(line_start.x, line_end.x);
- float lsy = std::min(line_start.y, line_end.y);
- float ley = std::max(line_start.y, line_end.y);
- std::list<TileMap*> solid_tilemaps = Sector::current()->solid_tilemaps;
- for (float test_x = lsx; test_x <= lex; test_x += 16) {
- for (float test_y = lsy; test_y <= ley; test_y += 16) {
- for(std::list<TileMap*>::const_iterator i = solid_tilemaps.begin(); i != solid_tilemaps.end(); i++) {
- TileMap* solids = *i;
- const Tile* tile = solids->get_tile_at(Vector(test_x, test_y));
- if(!tile) continue;
- // FIXME: check collision with slope tiles
- if((tile->getAttributes() & Tile::SOLID)) return false;
- }
- }
- }
-
- // check if no object is in the way
- using namespace collision;
- Sector::MovingObjects& moving_objects = Sector::current()->moving_objects;
- for(Sector::MovingObjects::const_iterator i = moving_objects.begin();
- i != moving_objects.end(); ++i) {
- const MovingObject* moving_object = *i;
- if (moving_object == ignore_object) continue;
- if (!moving_object->is_valid()) continue;
- if ((moving_object->get_group() == COLGROUP_MOVING)
- || (moving_object->get_group() == COLGROUP_MOVING_STATIC)
- || (moving_object->get_group() == COLGROUP_STATIC)) {
- if(intersects_line(moving_object->get_bbox(), line_start, line_end)) return false;
- }
- }
-
- return true;
-}
-
-void
-Ispy::update(float )
-{
-
- if (state == ISPYSTATE_IDLE) {
- // check if a player has been spotted
- bool playerSpotted = false;
- std::vector<Player*> players = Sector::current()->get_players();
- for (std::vector<Player*>::iterator playerIter = players.begin(); playerIter != players.end(); ++playerIter) {
- Player* player = *playerIter;
-
- Vector eye = get_bbox().get_middle();
- if (dir == LEFT) eye = Vector(get_bbox().p1.x, get_bbox().get_middle().y);
- if (dir == RIGHT) eye = Vector(get_bbox().p2.x, get_bbox().get_middle().y);
- if (dir == UP) eye = Vector(get_bbox().get_middle().x, get_bbox().p1.y);
- if (dir == DOWN) eye = Vector(get_bbox().get_middle().x, get_bbox().p2.y);
-
- // test for free line of sight to any of all four corners and the middle of a player's bounding box
- if (free_line_of_sight(eye, player->get_bbox().p1, player)) playerSpotted = true;
- if (free_line_of_sight(eye, Vector(player->get_bbox().p2.x, player->get_bbox().p1.y), player)) playerSpotted = true;
- if (free_line_of_sight(eye, player->get_bbox().p2, player)) playerSpotted = true;
- if (free_line_of_sight(eye, Vector(player->get_bbox().p1.x, player->get_bbox().p2.y), player)) playerSpotted = true;
- if (free_line_of_sight(eye, player->get_bbox().get_middle(), player)) playerSpotted = true;
- }
-
- if (playerSpotted) {
- sprite->set_action((dir == DOWN) ? "alert-down" : ((dir == LEFT) ? "alert-left" : "alert-right"), 1);
- state = ISPYSTATE_ALERT;
-
- std::istringstream stream(script);
- Sector::current()->run_script(stream, "Ispy");
- }
- }
- if (state == ISPYSTATE_ALERT) {
- if (sprite->animation_done()) {
- sprite->set_action((dir == DOWN) ? "hiding-down" : ((dir == LEFT) ? "hiding-left" : "hiding-right"), 1);
- state = ISPYSTATE_HIDING;
- }
- }
- if (state == ISPYSTATE_HIDING) {
- if (sprite->animation_done()) {
- sprite->set_action((dir == DOWN) ? "showing-down" : ((dir == LEFT) ? "showing-left" : "showing-right"), 1);
- state = ISPYSTATE_SHOWING;
- }
- }
- if (state == ISPYSTATE_SHOWING) {
- if (sprite->animation_done()) {
- sprite->set_action((dir == DOWN) ? "idle-down" : ((dir == LEFT) ? "idle-left" : "idle-right"));
- state = ISPYSTATE_IDLE;
- }
- }
-}
-
-IMPLEMENT_FACTORY(Ispy, "ispy");
-
-
+++ /dev/null
-// $Id$
-//
-// SuperTux - Ispy
-// Copyright (C) 2007 Christoph Sommer <christoph.sommer@2007.expires.deltadevelopment.de>
-//
-// 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.
-
-#ifndef __OBJECT_ISPY_H__
-#define __OBJECT_ISPY_H__
-
-#include "lisp/lisp.hpp"
-#include "object/moving_sprite.hpp"
-#include "serializable.hpp"
-#include "badguy/badguy.hpp"
-#include "direction.hpp"
-
-/**
- * An Ispy: When it spots Tux, a script will run.
- */
-class Ispy : public MovingSprite, public Serializable
-{
-public:
- Ispy(const lisp::Lisp& lisp);
-
- void write(lisp::Writer& writer);
- HitResponse collision(GameObject& other, const CollisionHit& hit);
-
- virtual void update(float elapsed_time);
-
-private:
- bool line_intersects_line(Vector line1_start, Vector line1_end, Vector line2_start, Vector line2_end);
- bool intersects_line(Rect r, Vector line_start, Vector line_end);
- bool free_line_of_sight(Vector p1, Vector p2, const MovingObject* ignore_object);
-
- enum IspyState {
- ISPYSTATE_IDLE,
- ISPYSTATE_ALERT,
- ISPYSTATE_HIDING,
- ISPYSTATE_SHOWING
- };
- IspyState state; /**< current state */
-
- std::string script; /**< script to execute when Tux is spotted */
- Direction dir;
-
-};
-
-#endif
-
+++ /dev/null
-// $Id$
-//
-// SuperTux - Lantern
-// Copyright (C) 2006 Wolfgang Becker <uafr@gmx.de>
-//
-// 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.
-
-#include <config.h>
-
-#include "lantern.hpp"
-#include "sprite/sprite_manager.hpp"
-#include "object_factory.hpp"
-#include "badguy/willowisp.hpp"
-#include "badguy/treewillowisp.hpp"
-
-Lantern::Lantern(const lisp::Lisp& reader)
- : Rock(reader, "images/objects/lantern/lantern.sprite"),
- lightcolor(1.0f, 1.0f, 1.0f)
-{
- //get color from lisp
- std::vector<float> vColor;
- reader.get_vector("color", vColor);
- lightcolor = Color(vColor);
- lightsprite = sprite_manager->create("images/objects/lightmap_light/lightmap_light.sprite");
- lightsprite->set_blend(Blend(GL_SRC_ALPHA, GL_ONE));
- updateColor();
- sound_manager->preload("sounds/willocatch.wav");
-}
-
-Lantern::Lantern(const Vector& pos)
- : Rock(pos, "images/objects/lantern/lantern.sprite"),
- lightcolor(0.0f, 0.0f, 0.0f)
-{
- lightsprite = sprite_manager->create("images/objects/lightmap_light/lightmap_light.sprite");
- lightsprite->set_blend(Blend(GL_SRC_ALPHA, GL_ONE));
- updateColor();
- sound_manager->preload("sounds/willocatch.wav");
-}
-
-Lantern::~Lantern()
-{
- delete lightsprite;
-}
-
-void
-Lantern::updateColor(){
- lightsprite->set_color(lightcolor);
- //Turn lantern off if light is black
- if(lightcolor.red == 0 && lightcolor.green == 0 && lightcolor.blue == 0){
- sprite->set_action("off");
- } else {
- sprite->set_action("normal");
- sprite->set_color(lightcolor);
- }
-}
-
-void
-Lantern::draw(DrawingContext& context){
- //Draw the Sprite.
- MovingSprite::draw(context);
- //Let there be light.
- context.push_target();
- context.set_target(DrawingContext::LIGHTMAP);
-
- lightsprite->draw(context, get_bbox().get_middle(), 0);
-
- context.pop_target();
-}
-
-HitResponse Lantern::collision(GameObject& other, const CollisionHit& hit) {
- if (is_open()) {
- WillOWisp* wow = dynamic_cast<WillOWisp*>(&other);
- if (wow) {
- // collided with WillOWisp while grabbed and unlit
- sound_manager->play("sounds/willocatch.wav");
- lightcolor = Color(0,1,0);
- updateColor();
- wow->vanish();
- }
- TreeWillOWisp* twow = dynamic_cast<TreeWillOWisp*>(&other);
- if (twow) {
- // collided with TreeWillOWisp while grabbed and unlit
- sound_manager->play("sounds/willocatch.wav");
- lightcolor = twow->get_color();
- updateColor();
- twow->vanish();
- }
- }
- return Rock::collision(other, hit);
-}
-
-void
-Lantern::grab(MovingObject& object, const Vector& pos, Direction dir)
-{
- Rock::grab(object, pos, dir);
-
- // if lantern is not lit, draw it as opened
- if (is_open()) {
- sprite->set_action("off-open");
- }
-
-}
-
-void
-Lantern::ungrab(MovingObject& object, Direction dir)
-{
- // if lantern is not lit, it was drawn as opened while grabbed. Now draw it as closed again
- if (is_open()) {
- sprite->set_action("off");
- }
-
- Rock::ungrab(object, dir);
-}
-
-bool
-Lantern::is_open()
-{
- return ((grabbed) && lightcolor.red == 0 && lightcolor.green == 0 && lightcolor.blue == 0);
-}
-
-IMPLEMENT_FACTORY(Lantern, "lantern");
-
+++ /dev/null
-// $Id$
-//
-// SuperTux - Lantern
-// Copyright (C) 2006 Wolfgang Becker <uafr@gmx.de>
-//
-// 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.
-
-#ifndef __SUPERTUX_LANTERN_H__
-#define __SUPERTUX_LANTERN_H___
-
-#include "object/moving_sprite.hpp"
-#include "object/rock.hpp"
-
-/**
- * Lantern. A portable Light Source.
- */
-class Lantern : public Rock
-{
-public:
- Lantern(const Vector& pos);
- Lantern(const lisp::Lisp& reader);
- void draw(DrawingContext& context);
- ~Lantern();
-
- HitResponse collision(GameObject& other, const CollisionHit& hit);
-
- void grab(MovingObject& object, const Vector& pos, Direction dir);
- void ungrab(MovingObject& object, Direction dir);
-
- /**
- * returns true if lamp is currently open
- */
- bool is_open();
-
- /**
- * returns the lamp's color
- */
- Color get_color() const {
- return lightcolor;
- }
-
-private:
- Color lightcolor;
- Sprite* lightsprite;
- void updateColor();
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include "level_time.hpp"
-
-#include <stdexcept>
-#include <iostream>
-#include <sstream>
-#include "main.hpp"
-#include "resources.hpp"
-#include "sector.hpp"
-#include "gettext.hpp"
-#include "object_factory.hpp"
-#include "object/player.hpp"
-#include "video/drawing_context.hpp"
-#include "lisp/list_iterator.hpp"
-#include "log.hpp"
-#include "scripting/level_time.hpp"
-#include "scripting/squirrel_util.hpp"
-
-/** When to alert player they're low on time! */
-static const float TIME_WARNING = 20;
-
-LevelTime::LevelTime(const lisp::Lisp& reader)
-: running(true), time_left(0)
-{
- reader.get("name", name);
- reader.get("time", time_left);
- if(time_left <= 0) throw std::runtime_error("No or invalid leveltime specified");
- time_surface.reset(new Surface("images/engine/hud/time-0.png"));
-}
-
-void
-LevelTime::expose(HSQUIRRELVM vm, SQInteger table_idx)
-{
- if (name.empty()) return;
- Scripting::LevelTime* interface = new Scripting::LevelTime(this);
- expose_object(vm, table_idx, interface, name, true);
-}
-
-void
-LevelTime::unexpose(HSQUIRRELVM vm, SQInteger table_idx)
-{
- if (name.empty()) return;
- Scripting::unexpose_object(vm, table_idx, name);
-}
-
-void
-LevelTime::update(float elapsed_time)
-{
- if (!running) return;
-
- int prev_time = (int) floor(time_left*5);
- time_left -= elapsed_time;
- if(time_left <= 0) {
- if(time_left <= -5 || !Sector::current()->player->get_coins())
- {
- Sector::current()->player->kill(true);
- stop();
- }
- if(prev_time != (int) floor(time_left*5))
- {
- Sector::current()->player->add_coins(-1);
- }
- }
-}
-
-void
-LevelTime::draw(DrawingContext& context)
-{
- context.push_transform();
- context.set_translation(Vector(0, 0));
-
- if ((time_left > TIME_WARNING) || (int(game_time * 2.5) % 2)) {
- std::stringstream ss;
- ss << int(time_left);
- std::string time_text = ss.str();
-
- Surface* time_surf = time_surface.get();
- if (time_surf) {
- float all_width = time_surf->get_width() + white_text->get_text_width(time_text);
- context.draw_surface(time_surf, Vector((SCREEN_WIDTH - all_width)/2, BORDER_Y + 1), LAYER_FOREGROUND1);
- context.draw_text(gold_text, time_text, Vector((SCREEN_WIDTH - all_width)/2 + time_surf->get_width(), BORDER_Y), ALIGN_LEFT, LAYER_FOREGROUND1);
- }
- }
-
- context.pop_transform();
-}
-
-void
-LevelTime::start()
-{
- running = true;
-}
-
-void
-LevelTime::stop()
-{
- running = false;
-}
-
-float
-LevelTime::get_time()
-{
- return time_left;
-}
-
-void
-LevelTime::set_time(float time_left)
-{
- this->time_left = std::min(std::max(time_left, 0.0f), 999.0f);
-}
-
-IMPLEMENT_FACTORY(LevelTime, "leveltime");
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __LEVELTIME_H__
-#define __LEVELTIME_H__
-
-#include <memory>
-#include "game_object.hpp"
-#include "timer.hpp"
-#include "lisp/lisp.hpp"
-#include "video/surface.hpp"
-#include "script_interface.hpp"
-
-class LevelTime : public GameObject, public ScriptInterface
-{
-public:
- LevelTime(const lisp::Lisp& reader);
-
- virtual void expose(HSQUIRRELVM vm, SQInteger table_idx);
- virtual void unexpose(HSQUIRRELVM vm, SQInteger table_idx);
-
- void update(float elapsed_time);
- void draw(DrawingContext& context);
-
- /**
- * @name Scriptable Methods
- * @{
- */
-
- /**
- * Resumes the countdown
- */
- void start();
-
- /**
- * Pauses the countdown
- */
- void stop();
-
- /**
- * Returns the number of seconds left on the clock
- */
- float get_time();
-
- /**
- * Changes the number of seconds left on the clock
- */
- void set_time(float time_left);
-
- /**
- * @}
- */
-
-private:
- std::auto_ptr<Surface> time_surface;
- bool running;
- float time_left;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include "light.hpp"
-#include "sprite/sprite_manager.hpp"
-#include "resources.hpp"
-#include "video/drawing_context.hpp"
-#include "object_factory.hpp"
-#include "player.hpp"
-#include "sector.hpp"
-
-Light::Light(const Vector& center, const Color& color) : position(center), color(color)
-{
- sprite = sprite_manager->create("images/objects/lightmap_light/lightmap_light.sprite");
-}
-
-Light::~Light()
-{
- delete sprite;
-}
-
-void
-Light::update(float )
-{
-}
-
-void
-Light::draw(DrawingContext& context)
-{
- context.push_target();
- context.set_target(DrawingContext::LIGHTMAP);
-
- sprite->set_color(color);
- sprite->set_blend(Blend(GL_SRC_ALPHA, GL_ONE));
- sprite->set_angle(90); // FIXME: color won't get applied for angle=0
- sprite->draw(context, position, 0);
-
- context.pop_target();
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __LIGHT_HPP__
-#define __LIGHT_HPP__
-
-#include "game_object.hpp"
-#include "lisp/lisp.hpp"
-#include "math/vector.hpp"
-#include "video/color.hpp"
-
-class Sprite;
-
-class Light : public GameObject
-{
-public:
- Light(const Vector& center, const Color& color = Color(1.0, 1.0, 1.0, 1.0));
- virtual ~Light();
-
- void update(float elapsed_time);
- void draw(DrawingContext& context);
-
-protected:
- Vector position;
- Color color;
- Sprite* sprite;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux - MagicBlock
-//
-// Magic Blocks are tile-like game objects that are sensitive to
-// lighting conditions. They are rendered in a color and
-// will only be solid as long as light of the same color shines
-// on the block.
-//
-// Copyright (C) 2006 Wolfgang Becker <uafr@gmx.de>
-//
-// 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.
-
-#include <config.h>
-#include <vector>
-
-#include "object/camera.hpp"
-#include "magicblock.hpp"
-#include "object_factory.hpp"
-#include "sprite/sprite_manager.hpp"
-#include "sector.hpp"
-#include "main.hpp"
-
-namespace {
- const float MIN_INTENSITY = 0.8f;
- const float ALPHA_SOLID = 0.7f;
- const float ALPHA_NONSOLID = 0.3f;
- const float MIN_SOLIDTIME = 1.0f;
- const float SWITCH_DELAY = 0.1f; /**< seconds to wait for stable conditions until switching solidity */
-}
-
-MagicBlock::MagicBlock(const lisp::Lisp& lisp)
- : MovingSprite(lisp, "images/objects/magicblock/magicblock.sprite"),
- is_solid(false), solid_time(0), switch_delay(0), light(1.0f,1.0f,1.0f)
-{
- set_group(COLGROUP_STATIC);
- //get color from lisp
- std::vector<float> vColor;
- lisp.get_vector("color", vColor );
- color = Color( vColor );
-
- //all alpha to make the sprite still visible
- color.alpha = ALPHA_SOLID;
-
- //set trigger
- if(color.red == 0 && color.green == 0 && color.blue == 0) { //is it black?
- black = true;
- trigger_red = MIN_INTENSITY;
- trigger_green = MIN_INTENSITY;
- trigger_blue = MIN_INTENSITY;
- } else {
- black = false;
- trigger_red = (color.red == 1.0f ? MIN_INTENSITY : 0);
- trigger_green = (color.green == 1.0f ? MIN_INTENSITY : 0);
- trigger_blue = (color.blue == 1.0f ? MIN_INTENSITY : 0);
- }
-
- center = get_bbox().get_middle();
-}
-
-void
-MagicBlock::update(float elapsed_time)
-{
- //Check if center of this block is on screen.
- //Don't update if not, because there is no light off screen.
- float screen_left = Sector::current()->camera->get_translation().x;
- float screen_top = Sector::current()->camera->get_translation().y;
- float screen_right = screen_left+ SCREEN_WIDTH;
- float screen_bottom = screen_top + SCREEN_HEIGHT;
- if((center.x > screen_right ) || ( center.y > screen_bottom) ||
- ( center.x < screen_left) || ( center.y < screen_top)) {
- switch_delay = SWITCH_DELAY;
- return;
- }
-
- bool lighting_ok;
- if(black) {
- lighting_ok = (light.red >= trigger_red || light.green >= trigger_green
- || light.blue >= trigger_blue);
- }else{
- lighting_ok = (light.red >= trigger_red && light.green >= trigger_green
- && light.blue >= trigger_blue);
- }
-
- // overrule lighting_ok if switch_delay has not yet passed
- if (lighting_ok == is_solid) {
- switch_delay = SWITCH_DELAY;
- } else {
- if (switch_delay > 0) {
- lighting_ok = is_solid;
- switch_delay -= elapsed_time;
- }
- }
-
- if (lighting_ok) {
- // lighting suggests going solid
-
- if (!is_solid) {
- if (Sector::current()->is_free_of_movingstatics(get_bbox(), this)) {
- is_solid = true;
- solid_time = 0;
- switch_delay = SWITCH_DELAY;
- }
- }
- } else {
- // lighting suggests going nonsolid
-
- if( solid_time >= MIN_SOLIDTIME ){
- is_solid = false;
- }
- }
-
- //Update Sprite.
- if(is_solid) {
- solid_time+=elapsed_time;
- color.alpha = ALPHA_SOLID;
- sprite->set_action("solid");
- } else {
- color.alpha = ALPHA_NONSOLID;
- sprite->set_action("normal");
- }
-}
-
-void
-MagicBlock::draw(DrawingContext& context){
- //Ask for update about lightmap at center of this block
- context.get_light( center, &light );
-
- //Draw the Sprite.
- MovingSprite::draw(context);
- //Add the color.
- context.draw_filled_rect( get_bbox(), color, layer);
-}
-
-bool
-MagicBlock::collides(GameObject& /*other*/, const CollisionHit& /*hit*/)
-{
- return is_solid;
-}
-
-HitResponse
-MagicBlock::collision(GameObject& /*other*/, const CollisionHit& /*hit*/)
-{
- return SOLID;
-}
-
-IMPLEMENT_FACTORY(MagicBlock, "magicblock");
+++ /dev/null
-// $Id$
-//
-// SuperTux - MagicBlock
-//
-// Magic Blocks are tile-like game objects that are sensitive to
-// lighting conditions. They are rendered in a color and
-// will only be solid as long as light of the same color shines
-// on the block. The black block becomes solid, if any kind of
-// light is above MIN_INTENSITY.
-//
-// Copyright (C) 2006 Wolfgang Becker <uafr@gmx.de>
-//
-// 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.
-
-#ifndef SUPERTUX_TRAMPOLINE_H
-#define SUPERTUX_TRAMPOLINE_H
-
-#include "moving_sprite.hpp"
-#include "lisp/lisp.hpp"
-
-class MagicBlock: public MovingSprite
-{
-public:
- MagicBlock(const lisp::Lisp& reader);
-
- bool collides(GameObject& other, const CollisionHit& hit);
- HitResponse collision(GameObject& other, const CollisionHit& hit);
- void update(float elapsed_time);
- void draw(DrawingContext& context);
-
-private:
- bool is_solid;
- float trigger_red;
- float trigger_green;
- float trigger_blue;
- float solid_time;
- float switch_delay; /**< seconds until switching solidity */
- Color color;
- Color light;
- Vector center;
- bool black;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux - MovingSprite Base Class
-// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
-//
-// 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.
-#include <config.h>
-
-#include <stdexcept>
-
-#include "moving_sprite.hpp"
-#include "video/drawing_context.hpp"
-#include "sprite/sprite_manager.hpp"
-#include "player.hpp"
-#include "sector.hpp"
-#include "player_status.hpp"
-#include "gameobjs.hpp"
-#include "statistics.hpp"
-#include "object_factory.hpp"
-#include "level.hpp"
-#include "random_generator.hpp"
-#include "audio/sound_source.hpp"
-#include "audio/sound_manager.hpp"
-#include "timer.hpp"
-
-MovingSprite::MovingSprite(const Vector& pos, const std::string& sprite_name, int layer, CollisionGroup collision_group)
- : sprite_name(sprite_name), layer(layer)
-{
- bbox.set_pos(pos);
- sprite = sprite_manager->create(sprite_name);
- bbox.set_size(sprite->get_current_hitbox_width(), sprite->get_current_hitbox_height());
- set_group(collision_group);
-}
-
-MovingSprite::MovingSprite(const lisp::Lisp& reader, const Vector& pos, int layer, CollisionGroup collision_group)
- : layer(layer)
-{
- bbox.set_pos(pos);
- if (!reader.get("sprite", sprite_name))
- throw std::runtime_error("no sprite name set");
-
- sprite = sprite_manager->create(sprite_name);
- bbox.set_size(sprite->get_current_hitbox_width(), sprite->get_current_hitbox_height());
- set_group(collision_group);
-}
-
-MovingSprite::MovingSprite(const lisp::Lisp& reader, const std::string& sprite_name, int layer, CollisionGroup collision_group)
- : sprite_name(sprite_name), layer(layer)
-{
- if (!reader.get("x", bbox.p1.x))
- throw std::runtime_error("no x position set");
- if (!reader.get("y", bbox.p1.y))
- throw std::runtime_error("no y position set");
-
- sprite = sprite_manager->create(sprite_name);
- bbox.set_size(sprite->get_current_hitbox_width(), sprite->get_current_hitbox_height());
- set_group(collision_group);
-}
-
-MovingSprite::MovingSprite(const lisp::Lisp& reader, int layer, CollisionGroup collision_group)
- : layer(layer)
-{
- if (!reader.get("x", bbox.p1.x))
- throw std::runtime_error("no x position set");
- if (!reader.get("y", bbox.p1.y))
- throw std::runtime_error("no y position set");
- if (!reader.get("sprite", sprite_name))
- throw std::runtime_error("no sprite name set");
-
- sprite = sprite_manager->create(sprite_name);
- bbox.set_size(sprite->get_current_hitbox_width(), sprite->get_current_hitbox_height());
- set_group(collision_group);
-}
-
-MovingSprite::MovingSprite(const MovingSprite& other)
- : MovingObject(other), layer(other.layer)
-{
- sprite = new Sprite(*other.sprite);
-}
-
-MovingSprite&
-MovingSprite::operator=(const MovingSprite& other)
-{
- if (this == &other)
- return *this;
-
- delete sprite;
- sprite = new Sprite(*other.sprite);
-
- layer = other.layer;
-
- return *this;
-}
-
-MovingSprite::~MovingSprite()
-{
- delete sprite;
-}
-
-void
-MovingSprite::draw(DrawingContext& context)
-{
- sprite->draw(context, get_pos(), layer);
-}
-
-void
-MovingSprite::update(float )
-{
-}
-
-void
-MovingSprite::set_action(const std::string& action, int loops)
-{
- sprite->set_action(action, loops);
- set_size(sprite->get_current_hitbox_width(), sprite->get_current_hitbox_height());
-}
-
-void
-MovingSprite::set_action_centered(const std::string& action, int loops)
-{
- Vector old_size = bbox.get_size();
- sprite->set_action(action, loops);
- set_size(sprite->get_current_hitbox_width(), sprite->get_current_hitbox_height());
- set_pos(get_pos() - (bbox.get_size() - old_size) / 2);
-}
-
-void
-MovingSprite::set_action(const std::string& action, int loops, AnchorPoint anchorPoint)
-{
- Rect old_bbox = bbox;
- sprite->set_action(action, loops);
- float w = sprite->get_current_hitbox_width();
- float h = sprite->get_current_hitbox_height();
- set_size(w, h);
- set_pos(get_anchor_pos(old_bbox, w, h, anchorPoint));
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux - MovingSprite Base Class
-// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
-//
-// 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.
-
-#ifndef __MOVING_SPRITE_H__
-#define __MOVING_SPRITE_H__
-
-#include <string>
-#include "moving_object.hpp"
-#include "sprite/sprite.hpp"
-#include "video/drawing_context.hpp"
-#include "object/anchor_point.hpp"
-
-/**
- * Abstract base class for MovingObjects that are represented by a Sprite
- */
-class MovingSprite : public MovingObject
-{
-public:
- MovingSprite(const Vector& pos, const std::string& sprite_name, int layer = LAYER_OBJECTS, CollisionGroup collision_group = COLGROUP_MOVING);
- MovingSprite(const lisp::Lisp& reader, const Vector& pos, int layer = LAYER_OBJECTS, CollisionGroup collision_group = COLGROUP_MOVING);
- MovingSprite(const lisp::Lisp& reader, const std::string& sprite_name, int layer = LAYER_OBJECTS, CollisionGroup collision_group = COLGROUP_MOVING);
- MovingSprite(const lisp::Lisp& reader, int layer = LAYER_OBJECTS, CollisionGroup collision_group = COLGROUP_MOVING);
- MovingSprite(const MovingSprite& moving_sprite);
- MovingSprite& operator=(const MovingSprite& moving_sprite);
- ~MovingSprite();
-
- virtual void draw(DrawingContext& context);
- virtual void update(float elapsed_time);
-
-protected:
- std::string sprite_name;
- Sprite* sprite;
- int layer; /**< Sprite's z-position. Refer to video/drawing_context.hpp for sensible values. */
-
- /**
- * set new action for sprite and resize bounding box.
- * use with care as you can easily get stuck when resizing the bounding box.
- */
- void set_action(const std::string& action, int loops);
-
- /**
- * set new action for sprite and re-center bounding box.
- * use with care as you can easily get stuck when resizing the bounding box.
- */
- void set_action_centered(const std::string& action, int loops);
-
- /**
- * set new action for sprite and align bounding boxes at anchorPoint.
- * use with care as you can easily get stuck when resizing the bounding box.
- */
- void set_action(const std::string& action, int loops, AnchorPoint anchorPoint);
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include "oneup.hpp"
-#include "resources.hpp"
-#include "player.hpp"
-#include "player_status.hpp"
-#include "sector.hpp"
-#include "level.hpp"
-#include "statistics.hpp"
-#include "video/drawing_context.hpp"
-
-OneUp::OneUp(const Vector& pos, Direction direction)
- : MovingSprite(pos, "images/powerups/1up/1up.sprite", LAYER_FLOATINGOBJECTS, COLGROUP_TOUCHABLE)
-{
- physic.set_velocity((direction == LEFT)?-100:100, -400);
-}
-
-void
-OneUp::update(float elapsed_time)
-{
- if(!Sector::current()->inside(bbox))
- remove_me();
-
- movement = physic.get_movement(elapsed_time);
-}
-
-HitResponse
-OneUp::collision(GameObject& other, const CollisionHit& )
-{
- Player* player = dynamic_cast<Player*> (&other);
- if(player) {
- player->get_status()->add_coins(100);
-#if 0
- // FIXME: do we want this? q.v. src/level.cpp
- Sector::current()->get_level()->stats.coins += 100;
-#endif
- remove_me();
- return ABORT_MOVE;
- }
- return FORCE_MOVE;
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __ONEUP_H__
-#define __ONEUP_H__
-
-#include "object/moving_sprite.hpp"
-#include "physic.hpp"
-#include "direction.hpp"
-
-class OneUp : public MovingSprite, private UsesPhysic
-{
-public:
- OneUp(const Vector& pos, Direction direction = RIGHT);
- virtual OneUp* clone() const { return new OneUp(*this); }
-
- virtual void update(float elapsed_time);
- virtual HitResponse collision(GameObject& other, const CollisionHit& hit);
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include <math.h>
-
-#include "particles.hpp"
-#include "sector.hpp"
-#include "camera.hpp"
-#include "main.hpp"
-#include "random_generator.hpp"
-
-Particles::Particles(const Vector& epicenter, int min_angle, int max_angle,
- const Vector& initial_velocity, const Vector& acceleration, int number,
- Color color_, int size_, float life_time, int drawing_layer_)
- : accel(acceleration), color(color_), size(size_), drawing_layer(drawing_layer_)
-{
- if(life_time == 0) {
- live_forever = true;
- } else {
- live_forever = false;
- timer.start(life_time);
- }
-
- // create particles
- for(int p = 0; p < number; p++)
- {
- Particle* particle = new Particle;
- particle->pos = epicenter;
-
- float angle = systemRandom.rand(min_angle, max_angle)
- * (M_PI / 180); // convert to radius (radians?)
- particle->vel.x = /*fabs*/(sin(angle)) * initial_velocity.x;
-// if(angle >= M_PI && angle < M_PI*2)
-// particle->vel.x *= -1; // work around to fix signal
- particle->vel.y = /*fabs*/(cos(angle)) * initial_velocity.y;
-// if(angle >= M_PI_2 && angle < 3*M_PI_2)
-// particle->vel.y *= -1;
-
- particles.push_back(particle);
- }
-}
-
-Particles::~Particles()
-{
- // free particles
- for(std::vector<Particle*>::iterator i = particles.begin();
- i < particles.end(); i++)
- delete (*i);
-}
-
-void
-Particles::update(float elapsed_time)
-{
- Vector camera = Sector::current()->camera->get_translation();
-
- // update particles
- for(std::vector<Particle*>::iterator i = particles.begin();
- i != particles.end(); ) {
- (*i)->pos.x += (*i)->vel.x * elapsed_time;
- (*i)->pos.y += (*i)->vel.y * elapsed_time;
-
- (*i)->vel.x += accel.x * elapsed_time;
- (*i)->vel.y += accel.y * elapsed_time;
-
- if((*i)->pos.x < camera.x || (*i)->pos.x > SCREEN_WIDTH + camera.x ||
- (*i)->pos.y < camera.y || (*i)->pos.y > SCREEN_HEIGHT + camera.y) {
- delete (*i);
- i = particles.erase(i);
- } else {
- ++i;
- }
- }
-
- if((timer.check() && !live_forever) || particles.size() == 0)
- remove_me();
-}
-
-void
-Particles::draw(DrawingContext& context)
-{
- // draw particles
- for(std::vector<Particle*>::iterator i = particles.begin();
- i != particles.end(); i++) {
- context.draw_filled_rect((*i)->pos, Vector(size,size), color,drawing_layer);
- }
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef SUPERTUX_PARTICLES_HPP
-#define SUPERTUX_PARTICLES_HPP
-
-#include "math/vector.hpp"
-#include "game_object.hpp"
-#include "timer.hpp"
-#include "video/color.hpp"
-
-class Particles : public GameObject
-{
-public:
- Particles(const Vector& epicenter, int min_angle, int max_angle,
- const Vector& initial_velocity, const Vector& acceleration,
- int number, Color color, int size, float life_time,
- int drawing_layer);
- ~Particles();
-
- virtual void update(float elapsed_time);
- virtual void draw(DrawingContext& context);
-
-private:
- Vector accel;
- Timer timer;
- bool live_forever;
-
- Color color;
- float size;
- int drawing_layer;
-
- struct Particle {
- Vector pos, vel;
-// float angle;
- };
- std::vector <Particle*> particles;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include <iostream>
-#include <cmath>
-
-#include "particlesystem.hpp"
-#include "video/drawing_context.hpp"
-#include "lisp/parser.hpp"
-#include "lisp/lisp.hpp"
-#include "lisp/writer.hpp"
-#include "resources.hpp"
-#include "main.hpp"
-#include "object/camera.hpp"
-#include "random_generator.hpp"
-
-ParticleSystem::ParticleSystem(float max_particle_size)
- : max_particle_size(max_particle_size)
-{
- virtual_width = SCREEN_WIDTH + max_particle_size * 2;
- virtual_height = SCREEN_HEIGHT + max_particle_size *2;
- z_pos = LAYER_BACKGROUND1;
-}
-
-ParticleSystem::~ParticleSystem()
-{
- std::vector<Particle*>::iterator i;
- for(i = particles.begin(); i != particles.end(); ++i) {
- delete *i;
- }
-}
-
-void ParticleSystem::draw(DrawingContext& context)
-{
- float scrollx = context.get_translation().x;
- float scrolly = context.get_translation().y;
-
- context.push_transform();
- context.set_translation(Vector(max_particle_size,max_particle_size));
-
- std::vector<Particle*>::iterator i;
- for(i = particles.begin(); i != particles.end(); ++i) {
- Particle* particle = *i;
-
- // remap x,y coordinates onto screencoordinates
- Vector pos;
-
- pos.x = fmodf(particle->pos.x - scrollx, virtual_width);
- if(pos.x < 0) pos.x += virtual_width;
-
- pos.y = fmodf(particle->pos.y - scrolly, virtual_height);
- if(pos.y < 0) pos.y += virtual_height;
-
-
- //if(pos.x > virtual_width) pos.x -= virtual_width;
- //if(pos.y > virtual_height) pos.y -= virtual_height;
-
- context.draw_surface(particle->texture, pos, z_pos);
- }
-
- context.pop_transform();
-}
-
-SnowParticleSystem::SnowParticleSystem()
-{
- snowimages[0] = new Surface("images/objects/particles/snow2.png");
- snowimages[1] = new Surface("images/objects/particles/snow1.png");
- snowimages[2] = new Surface("images/objects/particles/snow0.png");
-
- virtual_width = SCREEN_WIDTH * 2;
-
- // create some random snowflakes
- size_t snowflakecount = size_t(virtual_width/10.0);
- for(size_t i=0; i<snowflakecount; ++i) {
- SnowParticle* particle = new SnowParticle;
- int snowsize = systemRandom.rand(3);
-
- particle->pos.x = systemRandom.randf(virtual_width);
- particle->pos.y = systemRandom.randf(SCREEN_HEIGHT);
- particle->anchorx = particle->pos.x + (systemRandom.randf(-0.5, 0.5) * 16);
- particle->drift_speed = systemRandom.randf(-0.5, 0.5) * 0.3;
- particle->wobble = 0.0;
-
- particle->texture = snowimages[snowsize];
-
- particle->speed = 1 + (2 - snowsize)/2 + systemRandom.randf(1.8);
- particle->speed *= 20; // gravity
-
- particles.push_back(particle);
- }
-}
-
-void
-SnowParticleSystem::parse(const lisp::Lisp& reader)
-{
- reader.get("z-pos", z_pos);
-}
-
-void
-SnowParticleSystem::write(lisp::Writer& writer)
-{
- writer.start_list("particles-snow");
- writer.write_int("z-pos", z_pos);
- writer.end_list("particles-snow");
-}
-
-SnowParticleSystem::~SnowParticleSystem()
-{
- for(int i=0;i<3;++i)
- delete snowimages[i];
-}
-
-void SnowParticleSystem::update(float elapsed_time)
-{
- std::vector<Particle*>::iterator i;
-
- for(i = particles.begin(); i != particles.end(); ++i) {
- SnowParticle* particle = (SnowParticle*) *i;
- float anchor_delta;
-
- particle->pos.y += particle->speed * elapsed_time;
- particle->pos.x += particle->wobble * elapsed_time /* * particle->speed * 0.125*/;
-
- anchor_delta = (particle->anchorx - particle->pos.x);
- particle->wobble += (4 * anchor_delta * 0.05) + systemRandom.randf(-0.5, 0.5);
- particle->wobble *= 0.99f;
- particle->anchorx += particle->drift_speed * elapsed_time;
- }
-}
-
-//FIXME: Sometimes both ghosts have the same image
-// Ghosts don't change their movement pattern - not random
-GhostParticleSystem::GhostParticleSystem()
-{
- ghosts[0] = new Surface("images/objects/particles/ghost0.png");
- ghosts[1] = new Surface("images/objects/particles/ghost1.png");
-
- virtual_width = SCREEN_WIDTH * 2;
-
- // create two ghosts
- size_t ghostcount = 2;
- for(size_t i=0; i<ghostcount; ++i) {
- GhostParticle* particle = new GhostParticle;
- particle->pos.x = systemRandom.randf(virtual_width);
- particle->pos.y = systemRandom.randf(SCREEN_HEIGHT);
- int size = systemRandom.rand(2);
- particle->texture = ghosts[size];
- particle->speed = systemRandom.randf(std::max(50, (size * 10)), 180 + (size * 10));
- particles.push_back(particle);
- }
-}
-
-void
-GhostParticleSystem::parse(const lisp::Lisp& reader)
-{
- reader.get("z-pos", z_pos);
-}
-
-void
-GhostParticleSystem::write(lisp::Writer& writer)
-{
- writer.start_list("particles-ghosts");
- writer.write_int("z-pos", z_pos);
- writer.end_list("particles-ghosts");
-}
-
-GhostParticleSystem::~GhostParticleSystem()
-{
- for(int i=0;i<2;++i)
- delete ghosts[i];
-}
-
-void GhostParticleSystem::update(float elapsed_time)
-{
- std::vector<Particle*>::iterator i;
- for(i = particles.begin(); i != particles.end(); ++i) {
- GhostParticle* particle = (GhostParticle*) *i;
- particle->pos.y -= particle->speed * elapsed_time;
- particle->pos.x -= particle->speed * elapsed_time;
- if(particle->pos.y > SCREEN_HEIGHT) {
- particle->pos.y = fmodf(particle->pos.y , virtual_height);
- particle->pos.x = systemRandom.rand(static_cast<int>(virtual_width));
- }
- }
-}
-
-CloudParticleSystem::CloudParticleSystem()
- : ParticleSystem(128)
-{
- cloudimage = new Surface("images/objects/particles/cloud.png");
-
- virtual_width = 2000.0;
-
- // create some random clouds
- for(size_t i=0; i<15; ++i) {
- CloudParticle* particle = new CloudParticle;
- particle->pos.x = systemRandom.rand(static_cast<int>(virtual_width));
- particle->pos.y = systemRandom.rand(static_cast<int>(virtual_height));
- particle->texture = cloudimage;
- particle->speed = -systemRandom.randf(25.0, 54.0);
-
- particles.push_back(particle);
- }
-}
-
-void
-CloudParticleSystem::parse(const lisp::Lisp& reader)
-{
- reader.get("z-pos", z_pos);
-}
-
-void
-CloudParticleSystem::write(lisp::Writer& writer)
-{
- writer.start_list("particles-clouds");
- writer.write_int("z-pos", z_pos);
- writer.end_list("particles-clouds");
-}
-
-CloudParticleSystem::~CloudParticleSystem()
-{
- delete cloudimage;
-}
-
-void CloudParticleSystem::update(float elapsed_time)
-{
- std::vector<Particle*>::iterator i;
- for(i = particles.begin(); i != particles.end(); ++i) {
- CloudParticle* particle = (CloudParticle*) *i;
- particle->pos.x += particle->speed * elapsed_time;
- }
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef SUPERTUX_PARTICLESYSTEM_H
-#define SUPERTUX_PARTICLESYSTEM_H
-
-#include <vector>
-
-#include "video/surface.hpp"
-#include "game_object.hpp"
-#include "serializable.hpp"
-#include "sector.hpp"
-#include "math/vector.hpp"
-
-namespace lisp {
-class Lisp;
-}
-
-class DisplayManager;
-
-/**
- * This is the base class for particle systems. It is responsible for storing a
- * set of particles with each having an x- and y-coordinate the number of the
- * layer where it should be drawn and a texture.
- * The coordinate system used here is a virtual one. It would be a bad idea to
- * populate whole levels with particles. So we're using a virtual rectangle
- * here that is tiled onto the level when drawing. This rect.has the size
- * (virtual_width, virtual_height). We're using modulo on the particle
- * coordinates, so when a particle leaves left, it'll reenter at the right
- * side.
- *
- * Classes that implement a particle system should subclass from this class,
- * initialize particles in the constructor and move them in the simulate
- * function.
- */
-class ParticleSystem : public GameObject
-{
-public:
- ParticleSystem(float max_particle_size = 60);
- virtual ~ParticleSystem();
-
- virtual void draw(DrawingContext& context);
-
-protected:
- float max_particle_size;
- int z_pos;
-
- class Particle
- {
- public:
- virtual ~Particle()
- { }
-
- Vector pos;
- Surface* texture;
- };
-
- std::vector<Particle*> particles;
- float virtual_width, virtual_height;
-};
-
-class SnowParticleSystem : public ParticleSystem, public Serializable
-{
-public:
- SnowParticleSystem();
- virtual ~SnowParticleSystem();
-
- void parse(const lisp::Lisp& lisp);
- void write(lisp::Writer& writer);
-
- virtual void update(float elapsed_time);
-
- std::string type() const
- { return "SnowParticleSystem"; }
-
-private:
- class SnowParticle : public Particle
- {
- public:
- float speed;
- float wobble;
- float anchorx;
- float drift_speed;
- };
-
- Surface* snowimages[3];
-};
-
-class GhostParticleSystem : public ParticleSystem, public Serializable
-{
-public:
- GhostParticleSystem();
- virtual ~GhostParticleSystem();
-
- void parse(const lisp::Lisp& lisp);
- void write(lisp::Writer& writer);
-
- virtual void update(float elapsed_time);
-
- std::string type() const
- { return "GhostParticleSystem"; }
-
-private:
- class GhostParticle : public Particle
- {
- public:
- float speed;
- };
-
- Surface* ghosts[2];
-};
-
-class CloudParticleSystem : public ParticleSystem, public Serializable
-{
-public:
- CloudParticleSystem();
- virtual ~CloudParticleSystem();
-
- void parse(const lisp::Lisp& lisp);
- void write(lisp::Writer& writer);
-
- virtual void update(float elapsed_time);
-
- std::string type() const
- { return "CloudParticleSystem"; }
-
-private:
- class CloudParticle : public Particle
- {
- public:
- float speed;
- };
-
- Surface* cloudimage;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include <iostream>
-#include <cmath>
-
-#include "particlesystem_interactive.hpp"
-#include "video/drawing_context.hpp"
-#include "lisp/parser.hpp"
-#include "lisp/lisp.hpp"
-#include "lisp/writer.hpp"
-#include "resources.hpp"
-#include "main.hpp"
-
-#include "tile.hpp"
-#include "tilemap.hpp"
-#include "math/aatriangle.hpp"
-#include "collision.hpp"
-#include "collision_hit.hpp"
-#include "object/camera.hpp"
-#include "object/rainsplash.hpp"
-#include "badguy/bomb.hpp"
-#include "random_generator.hpp"
-
-//TODO: Find a way to make rain collide with objects like bonus blocks
-// Add an option to set rain strength
-// Fix rain being "respawned" over solid tiles
-ParticleSystem_Interactive::ParticleSystem_Interactive()
-{
- virtual_width = SCREEN_WIDTH;
- virtual_height = SCREEN_HEIGHT;
- z_pos = 0;
-}
-
-ParticleSystem_Interactive::~ParticleSystem_Interactive()
-{
- std::vector<Particle*>::iterator i;
- for(i = particles.begin(); i != particles.end(); ++i) {
- delete *i;
- }
-}
-
-void ParticleSystem_Interactive::draw(DrawingContext& context)
-{
- context.push_transform();
-
- std::vector<Particle*>::iterator i;
- for(i = particles.begin(); i != particles.end(); ++i) {
- Particle* particle = *i;
- context.draw_surface(particle->texture, particle->pos, z_pos);
- }
-
- context.pop_transform();
-}
-
-int
-ParticleSystem_Interactive::collision(Particle* object, Vector movement)
-{
- using namespace collision;
-
- // calculate rectangle where the object will move
- float x1, x2;
- float y1, y2;
- x1 = object->pos.x;
- x2 = x1 + 32 + movement.x;
- y1 = object->pos.y;
- y2 = y1 + 32 + movement.y;
- bool water = false;
-
- // test with all tiles in this rectangle
- int starttilex = int(x1-1) / 32;
- int starttiley = int(y1-1) / 32;
- int max_x = int(x2+1);
- int max_y = int(y2+1);
-
- Rect dest = Rect(x1, y1, x2, y2);
- dest.move(movement);
- Constraints constraints;
-
- for(std::list<TileMap*>::const_iterator i = Sector::current()->solid_tilemaps.begin(); i != Sector::current()->solid_tilemaps.end(); i++) {
- TileMap* solids = *i;
- for(int x = starttilex; x*32 < max_x; ++x) {
- for(int y = starttiley; y*32 < max_y; ++y) {
- const Tile* tile = solids->get_tile(x, y);
- if(!tile)
- continue;
- // skip non-solid tiles, except water
- if(! (tile->getAttributes() & (Tile::WATER | Tile::SOLID)))
- continue;
-
- if(tile->getAttributes() & Tile::SLOPE) { // slope tile
- AATriangle triangle;
- Vector p1(x*32, y*32);
- Vector p2((x+1)*32, (y+1)*32);
- triangle = AATriangle(p1, p2, tile->getData());
-
- if(rectangle_aatriangle(&constraints, dest, triangle)) {
- if(tile->getAttributes() & Tile::WATER)
- water = true;
- }
- } else { // normal rectangular tile
- Rect rect(x*32, y*32, (x+1)*32, (y+1)*32);
- if(intersects(dest, rect)) {
- if(tile->getAttributes() & Tile::WATER)
- water = true;
- set_rectangle_rectangle_constraints(&constraints, dest, rect);
- }
- }
- }
- }
- }
-
-
- // TODO don't use magic numbers here...
-
- // did we collide at all?
- if(!constraints.has_constraints())
- return -1;
-
- const CollisionHit& hit = constraints.hit;
- if (water) {
- return 0; //collision with water tile - don't draw splash
- } else {
- if (hit.right || hit.left) {
- return 2; //collision from right
- } else {
- return 1; //collision from above
- }
- }
-
- return 0;
-}
-
-RainParticleSystem::RainParticleSystem()
-{
- rainimages[0] = new Surface("images/objects/particles/rain0.png");
- rainimages[1] = new Surface("images/objects/particles/rain1.png");
-
- virtual_width = SCREEN_WIDTH * 2;
-
- // create some random raindrops
- size_t raindropcount = size_t(virtual_width/6.0);
- for(size_t i=0; i<raindropcount; ++i) {
- RainParticle* particle = new RainParticle;
- particle->pos.x = systemRandom.rand(int(virtual_width));
- particle->pos.y = systemRandom.rand(int(virtual_height));
- int rainsize = systemRandom.rand(2);
- particle->texture = rainimages[rainsize];
- do {
- particle->speed = (rainsize+1)*45 + systemRandom.randf(3.6);
- } while(particle->speed < 1);
- particle->speed *= 10; // gravity
-
- particles.push_back(particle);
- }
-}
-
-void
-RainParticleSystem::parse(const lisp::Lisp& reader)
-{
- reader.get("z-pos", z_pos);
-}
-
-void
-RainParticleSystem::write(lisp::Writer& writer)
-{
- writer.start_list("particles-rain");
- writer.write_int("z-pos", z_pos);
- writer.end_list("particles-rain");
-}
-
-RainParticleSystem::~RainParticleSystem()
-{
- for(int i=0;i<2;++i)
- delete rainimages[i];
-}
-
-void RainParticleSystem::update(float elapsed_time)
-{
- std::vector<Particle*>::iterator i;
- for(
- i = particles.begin(); i != particles.end(); ++i) {
- RainParticle* particle = (RainParticle*) *i;
- float movement = particle->speed * elapsed_time;
- float abs_x = Sector::current()->camera->get_translation().x;
- float abs_y = Sector::current()->camera->get_translation().y;
- particle->pos.y += movement;
- particle->pos.x -= movement;
- int col = collision(particle, Vector(-movement, movement));
- if ((particle->pos.y > SCREEN_HEIGHT + abs_y) || (col >= 0)) {
- //Create rainsplash
- if ((particle->pos.y <= SCREEN_HEIGHT + abs_y) && (col >= 1)){
- bool vertical = (col == 2);
- int splash_x, splash_y;
- if (!vertical) { //check if collision happened from above
- splash_x = int(particle->pos.x);
- splash_y = int(particle->pos.y) - (int(particle->pos.y) % 32) + 32;
- Sector::current()->add_object(new RainSplash(Vector(splash_x, splash_y),vertical));
- }
- // Uncomment the following to display vertical splashes, too
- /* else {
- splash_x = int(particle->pos.x) - (int(particle->pos.x) % 32) + 32;
- splash_y = int(particle->pos.y);
- Sector::current()->add_object(new RainSplash(Vector(splash_x, splash_y),vertical));
- } */
- }
- int new_x = systemRandom.rand(int(virtual_width)) + int(abs_x);
- int new_y = 0;
- //FIXME: Don't move particles over solid tiles
- particle->pos.x = new_x;
- particle->pos.y = new_y;
- }
- }
-}
-
-CometParticleSystem::CometParticleSystem()
-{
- cometimages[0] = new Surface("images/creatures/mr_bomb/exploding-left-0.png");
- cometimages[1] = new Surface("images/creatures/mr_bomb/exploding-left-0.png");
-
- virtual_width = SCREEN_WIDTH * 2;
-
- // create some random comets
- size_t cometcount = 2;
- for(size_t i=0; i<cometcount; ++i) {
- CometParticle* particle = new CometParticle;
- particle->pos.x = systemRandom.rand(int(virtual_width));
- particle->pos.y = systemRandom.rand(int(virtual_height));
- int cometsize = systemRandom.rand(2);
- particle->texture = cometimages[cometsize];
- do {
- particle->speed = (cometsize+1)*30 + systemRandom.randf(3.6);
- } while(particle->speed < 1);
- particle->speed *= 10; // gravity
-
- particles.push_back(particle);
- }
-}
-
-void
-CometParticleSystem::parse(const lisp::Lisp& reader)
-{
- reader.get("z-pos", z_pos);
-}
-
-void
-CometParticleSystem::write(lisp::Writer& writer)
-{
- writer.start_list("particles-comets");
- writer.write_int("z-pos", z_pos);
- writer.end_list("particles-comets");
-}
-
-CometParticleSystem::~CometParticleSystem()
-{
- for(int i=0;i<2;++i)
- delete cometimages[i];
-}
-
-void CometParticleSystem::update(float elapsed_time)
-{
- (void) elapsed_time;
-#if 0
- std::vector<Particle*>::iterator i;
- for(
- i = particles.begin(); i != particles.end(); ++i) {
- CometParticle* particle = (CometParticle*) *i;
- float movement = particle->speed * elapsed_time;
- float abs_x = Sector::current()->camera->get_translation().x;
- float abs_y = Sector::current()->camera->get_translation().y;
- particle->pos.y += movement;
- particle->pos.x -= movement;
- int col = collision(particle, Vector(-movement, movement));
- if ((particle->pos.y > SCREEN_HEIGHT + abs_y) || (col >= 0)) {
- if ((particle->pos.y <= SCREEN_HEIGHT + abs_y) && (col >= 1)) {
- Sector::current()->add_object(new Bomb(particle->pos, LEFT));
- }
- int new_x = systemRandom.rand(int(virtual_width)) + int(abs_x);
- int new_y = 0;
- //FIXME: Don't move particles over solid tiles
- particle->pos.x = new_x;
- particle->pos.y = new_y;
- }
- }
-#endif
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef SUPERTUX_PARTICLESYSTEM_INTERACTIVE_H
-#define SUPERTUX_PARTICLESYSTEM_INTERACTIVE_H
-
-#include <vector>
-
-#include "video/surface.hpp"
-#include "game_object.hpp"
-#include "serializable.hpp"
-#include "sector.hpp"
-#include "math/vector.hpp"
-
-namespace lisp {
-class Lisp;
-}
-
-class DisplayManager;
-
-/**
- * This is an alternative class for particle systems. It is responsible for storing a
- * set of particles with each having an x- and y-coordinate the number of the
- * layer where it should be drawn and a texture.
- * This version of the particle system class doesn't use virtual screen coordinates,
- * but Interactive ones. Particle systems which need Interactive levels coordinates, such
- * as rain, should be implemented here.
- * Classes that implement a particle system should subclass from this class,
- * initialize particles in the constructor and move them in the simulate
- * function.
- */
-class ParticleSystem_Interactive : public GameObject
-{
-public:
- ParticleSystem_Interactive();
- virtual ~ParticleSystem_Interactive();
-
- virtual void draw(DrawingContext& context);
-
-protected:
- int z_pos;
-
- class Particle
- {
- public:
- virtual ~Particle()
- { }
-
- Vector pos;
- Surface* texture;
- };
-
- std::vector<Particle*> particles;
- float virtual_width, virtual_height;
- int collision(Particle* particle, Vector movement);
-};
-
-class RainParticleSystem : public ParticleSystem_Interactive, public Serializable
-{
-public:
- RainParticleSystem();
- virtual ~RainParticleSystem();
-
- void parse(const lisp::Lisp& lisp);
- void write(lisp::Writer& writer);
-
- virtual void update(float elapsed_time);
-
- std::string type() const
- { return "RainParticleSystem"; }
-
-private:
- class RainParticle : public Particle
- {
- public:
- float speed;
- };
-
- Surface* rainimages[2];
-};
-
-class CometParticleSystem : public ParticleSystem_Interactive, public Serializable
-{
-public:
- CometParticleSystem();
- virtual ~CometParticleSystem();
-
- void parse(const lisp::Lisp& lisp);
- void write(lisp::Writer& writer);
-
- virtual void update(float elapsed_time);
-
- std::string type() const
- { return "CometParticleSystem"; }
-
-private:
- class CometParticle : public Particle
- {
- public:
- float speed;
- };
-
- Surface* cometimages[2];
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux Path
-// Copyright (C) 2005 Philipp <balinor@pnxs.de>
-// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#include <config.h>
-
-#include "path.hpp"
-
-#include "lisp/writer.hpp"
-#include "lisp/lisp.hpp"
-#include "lisp/list_iterator.hpp"
-#include "object_factory.hpp"
-#include "log.hpp"
-
-#include <assert.h>
-#include <iostream>
-#include <stdexcept>
-#include <sstream>
-
-Path::Path()
-{
-}
-
-Path::~Path()
-{
-}
-
-void
-Path::read(const lisp::Lisp& reader)
-{
- lisp::ListIterator iter(&reader);
-
- mode = CIRCULAR;
- while(iter.next()) {
- if(iter.item() == "mode") {
- std::string mode_string;
- if(!iter.value()->get(mode_string))
- throw std::runtime_error("Pathmode not a string");
-
- if(mode_string == "oneshot")
- mode = ONE_SHOT;
- else if(mode_string == "pingpong")
- mode = PING_PONG;
- else if(mode_string == "circular")
- mode = CIRCULAR;
- else {
- std::ostringstream msg;
- msg << "Unknown pathmode '" << mode_string << "' found";
- throw std::runtime_error(msg.str());
- }
- continue;
- }
-
- if(iter.item() != "node") {
- log_warning << "unknown token '" << iter.item() << "' in Path nodes list. Ignored." << std::endl;
- continue;
- }
- const lisp::Lisp* node_lisp = iter.lisp();
-
- // each new node will inherit all values from the last one
- Node node;
- node.time = 1;
- if( (!node_lisp->get("x", node.position.x) ||
- !node_lisp->get("y", node.position.y)))
- throw std::runtime_error("Path node without x and y coordinate specified");
- node_lisp->get("time", node.time);
-
- if(node.time <= 0)
- throw std::runtime_error("Path node with non-positive time");
-
- nodes.push_back(node);
- }
-
- if (nodes.empty())
- throw std::runtime_error("Path with zero nodes");
-}
-
-void
-Path::write(lisp::Writer& writer)
-{
- writer.start_list("path");
-
- switch(mode) {
- case ONE_SHOT:
- writer.write_string("mode", "oneshot");
- break;
- case PING_PONG:
- writer.write_string("mode", "pingpong");
- break;
- case CIRCULAR:
- writer.write_string("mode", "circular");
- break;
- default:
- log_warning << "Don't know how to write mode " << (int) mode << " ?!?" << std::endl;
- break;
- }
-
- for (size_t i=0; i < nodes.size(); i++) {
- const Node& node = nodes[i];
-
- writer.start_list("node");
- writer.write_float("x", node.position.x);
- writer.write_float("y", node.position.y);
- writer.write_float("time", node.time);
-
- writer.end_list("node");
- }
-
- writer.end_list("path");
-}
-
-Vector
-Path::get_base() const
-{
- if(nodes.empty())
- return Vector(0, 0);
-
- return nodes[0].position;
-}
-
-int
-Path::get_nearest_node_no(Vector reference_point) const
-{
- int nearest_node_id = -1;
- float nearest_node_dist = 0;
- int id = 0;
- for (std::vector<Node>::const_iterator i = nodes.begin(); i != nodes.end(); i++, id++) {
- float dist = (i->position - reference_point).norm();
- if ((nearest_node_id == -1) || (dist < nearest_node_dist)) {
- nearest_node_id = id;
- nearest_node_dist = dist;
- }
- }
- return nearest_node_id;
-}
-
-int
-Path::get_farthest_node_no(Vector reference_point) const
-{
- int farthest_node_id = -1;
- float farthest_node_dist = 0;
- int id = 0;
- for (std::vector<Node>::const_iterator i = nodes.begin(); i != nodes.end(); i++, id++) {
- float dist = (i->position - reference_point).norm();
- if ((farthest_node_id == -1) || (dist > farthest_node_dist)) {
- farthest_node_id = id;
- farthest_node_dist = dist;
- }
- }
- return farthest_node_id;
-}
-
+++ /dev/null
-// $Id$
-//
-// SuperTux Path
-// Copyright (C) 2005 Philipp <balinor@pnxs.de>
-// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#ifndef __PATH_HPP__
-#define __PATH_HPP__
-
-#include <vector>
-#include "math/vector.hpp"
-#include "lisp/lisp.hpp"
-#include "serializable.hpp"
-
-class Path : public Serializable
-{
-public:
- Path();
- ~Path();
-
- void read(const lisp::Lisp& reader);
- void write(lisp::Writer& writer);
-
- Vector get_base() const;
-
- /**
- * Helper class that stores an individual node of a Path
- */
- class Node
- {
- public:
- Vector position; /**< the position of this node */
- float time; /**< time (in seconds) to get from this node to next node */
- };
-
- std::vector<Node> nodes;
-
- /**
- * returns Node index nearest to reference_point or -1 if not applicable
- */
- int get_nearest_node_no(Vector reference_point) const;
-
- /**
- * returns Node index farthest from reference_point or -1 if not applicable
- */
- int get_farthest_node_no(Vector reference_point) const;
-
-private:
- friend class PathWalker;
-
- enum WalkMode {
- // moves from first to last path node and stops
- ONE_SHOT,
- // moves from first to last node then in reverse order back to first
- PING_PONG,
- // moves from last node back to the first node
- CIRCULAR
- };
-
- WalkMode mode;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include <math.h>
-#include <assert.h>
-#include "path_walker.hpp"
-
-PathWalker::PathWalker(const Path* path, bool running)
- : path(path), running(running), current_node_nr(0), next_node_nr(0), stop_at_node_nr(running?-1:0), node_time(0),
- walking_speed(1.0)
-{
- node_mult = 1 / path->nodes[0].time;
- next_node_nr = path->nodes.size() > 1 ? 1 : 0;
-}
-
-PathWalker::~PathWalker()
-{
-}
-
-Vector
-PathWalker::advance(float elapsed_time)
-{
- if (!running) return path->nodes[current_node_nr].position;
-
- assert(elapsed_time >= 0);
-
- elapsed_time *= fabsf(walking_speed);
-
- const Path::Node* current_node = & (path->nodes[current_node_nr]);
- while(node_time + elapsed_time * node_mult >= 1) {
- elapsed_time -= (1 - node_time) / node_mult;
-
- if(walking_speed > 0) {
- advance_node();
- } else if(walking_speed < 0) {
- goback_node();
- }
-
- current_node = & (path->nodes[current_node_nr]);
- node_time = 0;
- if(walking_speed > 0) {
- node_mult = 1 / current_node->time;
- } else {
- node_mult = 1 / path->nodes[next_node_nr].time;
- }
- }
-
- const Path::Node* next_node = & (path->nodes[next_node_nr]);
- node_time += elapsed_time * node_mult;
-
- Vector new_pos = current_node->position +
- (next_node->position - current_node->position) * node_time;
-
- return new_pos;
-}
-
-void
-PathWalker::goto_node(int node_no)
-{
- if (node_no == stop_at_node_nr) return;
- running = true;
- stop_at_node_nr = node_no;
-}
-
-void
-PathWalker::start_moving()
-{
- running = true;
- stop_at_node_nr = -1;
-}
-
-void
-PathWalker::stop_moving()
-{
- stop_at_node_nr = next_node_nr;
-}
-
-
-void
-PathWalker::advance_node()
-{
- current_node_nr = next_node_nr;
- if (static_cast<int>(current_node_nr) == stop_at_node_nr) running = false;
-
- if(next_node_nr + 1 < path->nodes.size()) {
- next_node_nr++;
- return;
- }
-
- switch(path->mode) {
- case Path::ONE_SHOT:
- next_node_nr = path->nodes.size() - 1;
- walking_speed = 0;
- return;
-
- case Path::PING_PONG:
- walking_speed = -walking_speed;
- next_node_nr = path->nodes.size() > 1 ? path->nodes.size() - 2 : 0;
- return;
-
- case Path::CIRCULAR:
- next_node_nr = 0;
- return;
- }
-
- // we shouldn't get here
- assert(false);
- next_node_nr = path->nodes.size() - 1;
- walking_speed = 0;
-}
-
-void
-PathWalker::goback_node()
-{
- current_node_nr = next_node_nr;
-
- if(next_node_nr > 0) {
- next_node_nr--;
- return;
- }
-
- switch(path->mode) {
- case Path::PING_PONG:
- walking_speed = -walking_speed;
- next_node_nr = path->nodes.size() > 1 ? 1 : 0;
- return;
- default:
- break;
- }
-
- assert(false);
- next_node_nr = 0;
- walking_speed = 0;
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __PATH_WALKER_HPP__
-#define __PATH_WALKER_HPP__
-
-#include "path.hpp"
-#include "math/vector.hpp"
-#include "game_object.hpp"
-#include "lisp/lisp.hpp"
-#include "serializable.hpp"
-
-/**
- * A walker that travels along a path
- */
-class PathWalker
-{
-public:
- PathWalker(const Path* path, bool running = true);
- virtual ~PathWalker();
-
- /**
- * advanves the path walker on the path and returns the position delta
- * to the last position
- */
- virtual Vector advance(float elapsed_time);
-
- /** advance until at given node, then stop */
- void goto_node(int node_no);
-
- /** start advancing automatically */
- void start_moving();
-
- /** stop advancing automatically */
- void stop_moving();
-
- /** returns true if PathWalker is currently moving */
- bool is_moving() {
- return running;
- }
-
- const Path* path;
-
-private:
- void advance_node();
- void goback_node();
-
- /**
- * set to false to immediately stop advancing
- */
- bool running;
-
- size_t current_node_nr;
- size_t next_node_nr;
-
- /**
- * stop advancing automatically when this node is reached
- */
- int stop_at_node_nr;
-
- /**
- * the position between the current node and the next node as fraction
- * between 0 and 1
- */
- float node_time;
- float node_mult;
-
- float walking_speed;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include "platform.hpp"
-
-#include <stdexcept>
-#include "log.hpp"
-#include "video/drawing_context.hpp"
-#include "resources.hpp"
-#include "player.hpp"
-#include "path.hpp"
-#include "path_walker.hpp"
-#include "sprite/sprite.hpp"
-#include "lisp/lisp.hpp"
-#include "object_factory.hpp"
-#include "scripting/platform.hpp"
-#include "scripting/squirrel_util.hpp"
-#include "sector.hpp"
-
-Platform::Platform(const lisp::Lisp& reader)
- : MovingSprite(reader, Vector(0,0), LAYER_OBJECTS, COLGROUP_STATIC),
- speed(Vector(0,0)),
- automatic(false), player_contact(false), last_player_contact(false)
-{
- bool running = true;
- reader.get("name", name);
- reader.get("running", running);
- if ((name == "") && (!running)) automatic=true;
- const lisp::Lisp* pathLisp = reader.get_lisp("path");
- if(pathLisp == NULL)
- throw std::runtime_error("No path specified for platform");
- path.reset(new Path());
- path->read(*pathLisp);
- walker.reset(new PathWalker(path.get(), running));
- bbox.set_pos(path->get_base());
-}
-
-Platform::Platform(const Platform& other)
- : MovingSprite(other), ScriptInterface(other),
- speed(other.speed),
- automatic(other.automatic), player_contact(false), last_player_contact(false)
-{
- name = other.name;
- path.reset(new Path(*other.path));
- walker.reset(new PathWalker(*other.walker));
- walker->path = &*path;
-}
-
-HitResponse
-Platform::collision(GameObject& other, const CollisionHit& )
-{
- if (dynamic_cast<Player*>(&other)) player_contact = true;
- return FORCE_MOVE;
-}
-
-void
-Platform::update(float elapsed_time)
-{
- // check if Platform should automatically pick a destination
- if (automatic) {
-
- if (!player_contact && !walker->is_moving()) {
- // Player doesn't touch platform and Platform is not moving
-
- // Travel to node nearest to nearest player
- // FIXME: does not really use nearest player
- Player* player = 0;
- std::vector<Player*> players = Sector::current()->get_players();
- for (std::vector<Player*>::iterator playerIter = players.begin(); playerIter != players.end(); ++playerIter) {
- player = *playerIter;
- }
- if (player) {
- int nearest_node_id = path->get_nearest_node_no(player->get_bbox().p2);
- if (nearest_node_id != -1) {
- goto_node(nearest_node_id);
- }
- }
- }
-
- if (player_contact && !last_player_contact && !walker->is_moving()) {
- // Player touched platform, didn't touch last frame and Platform is not moving
-
- // Travel to node farthest from current position
- int farthest_node_id = path->get_farthest_node_no(get_pos());
- if (farthest_node_id != -1) {
- goto_node(farthest_node_id);
- }
- }
-
- // Clear player_contact flag set by collision() method
- last_player_contact = player_contact;
- player_contact = false;
- }
-
- movement = walker->advance(elapsed_time) - get_pos();
- speed = movement / elapsed_time;
-}
-
-void
-Platform::goto_node(int node_no)
-{
- walker->goto_node(node_no);
-}
-
-void
-Platform::start_moving()
-{
- walker->start_moving();
-}
-
-void
-Platform::stop_moving()
-{
- walker->stop_moving();
-}
-
-void
-Platform::expose(HSQUIRRELVM vm, SQInteger table_idx)
-{
- if (name.empty()) return;
- Scripting::Platform* interface = new Scripting::Platform(this);
- expose_object(vm, table_idx, interface, name, true);
-}
-
-void
-Platform::unexpose(HSQUIRRELVM vm, SQInteger table_idx)
-{
- if (name.empty()) return;
- Scripting::unexpose_object(vm, table_idx, name);
-}
-
-IMPLEMENT_FACTORY(Platform, "platform");
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __PLATFORM_H__
-#define __PLATFORM_H__
-
-#include <memory>
-#include <string>
-#include "object/moving_sprite.hpp"
-#include "object/path.hpp"
-#include "object/path_walker.hpp"
-#include "script_interface.hpp"
-
-/**
- * This class is the base class for platforms that tux can stand on
- */
-class Platform : public MovingSprite, public ScriptInterface
-{
-public:
- Platform(const lisp::Lisp& reader);
- Platform(const Platform& platform);
- virtual Platform* clone() const { return new Platform(*this); }
-
- virtual HitResponse collision(GameObject& other, const CollisionHit& hit);
- virtual void update(float elapsed_time);
-
- const Vector& get_speed() const
- {
- return speed;
- }
-
- /**
- * @name Scriptable Methods
- * @{
- */
-
- /** Move platform until at given node, then stop */
- void goto_node(int node_no);
-
- /** Start moving platform */
- void start_moving();
-
- /** Stop platform at next node */
- void stop_moving();
-
- /**
- * @}
- */
-
- virtual void expose(HSQUIRRELVM vm, SQInteger table_idx);
- virtual void unexpose(HSQUIRRELVM vm, SQInteger table_idx);
-
- Path& get_path() {
- return *path.get();
- }
-
-private:
- std::auto_ptr<Path> path;
- std::auto_ptr<PathWalker> walker;
-
- Vector speed;
-
- bool automatic; /**< true if Platform will automatically pick a destination based on collisions and current Player position */
- bool player_contact; /**< true if a Player touched the Platform during the last round of collision detections */
- bool last_player_contact; /**< true if a Player touched the Platform during the round before the last round of collision detections */
-
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#include <config.h>
-
-#include <typeinfo>
-#include <cmath>
-#include <iostream>
-#include <cassert>
-
-#include "gettext.hpp"
-#include "sprite/sprite_manager.hpp"
-#include "audio/sound_manager.hpp"
-#include "player.hpp"
-#include "tile.hpp"
-#include "sprite/sprite.hpp"
-#include "sector.hpp"
-#include "resources.hpp"
-#include "statistics.hpp"
-#include "game_session.hpp"
-#include "object/tilemap.hpp"
-#include "object/camera.hpp"
-#include "object/particles.hpp"
-#include "object/portable.hpp"
-#include "object/bullet.hpp"
-#include "trigger/trigger_base.hpp"
-#include "control/joystickkeyboardcontroller.hpp"
-#include "scripting/squirrel_util.hpp"
-#include "main.hpp"
-#include "platform.hpp"
-#include "badguy/badguy.hpp"
-#include "player_status.hpp"
-#include "log.hpp"
-#include "falling_coin.hpp"
-#include "random_generator.hpp"
-#include "object/sprite_particle.hpp"
-#include "trigger/climbable.hpp"
-
-//#define SWIMMING
-
-static const int TILES_FOR_BUTTJUMP = 3;
-static const float SHOOTING_TIME = .150f;
-/// time before idle animation starts
-static const float IDLE_TIME = 2.5f;
-
-/** acceleration in horizontal direction when walking
- * (all acceleratiosn are in pixel/s^2) */
-static const float WALK_ACCELERATION_X = 300;
-/** acceleration in horizontal direction when running */
-static const float RUN_ACCELERATION_X = 400;
-/** acceleration when skidding */
-static const float SKID_XM = 200;
-/** time of skidding in seconds */
-static const float SKID_TIME = .3f;
-/** maximum walk velocity (pixel/s) */
-static const float MAX_WALK_XM = 230;
-/** maximum run velcoity (pixel/s) */
-static const float MAX_RUN_XM = 320;
-/** maximum horizontal climb velocity */
-static const float MAX_CLIMB_XM = 48;
-/** maximum vertical climb velocity */
-static const float MAX_CLIMB_YM = 128;
-/** instant velocity when tux starts to walk */
-static const float WALK_SPEED = 100;
-
-/** time of the kick (kicking mriceblock) animation */
-static const float KICK_TIME = .3f;
-/** time of tux cheering (currently unused) */
-static const float CHEER_TIME = 1.0f;
-
-/** if Tux cannot unduck for this long, he will get hurt */
-static const float UNDUCK_HURT_TIME = 0.25f;
-
-// growing animation
-Surface* growingtux_left[GROWING_FRAMES];
-Surface* growingtux_right[GROWING_FRAMES];
-
-Surface* tux_life = 0;
-
-TuxBodyParts* small_tux = 0;
-TuxBodyParts* big_tux = 0;
-TuxBodyParts* fire_tux = 0;
-TuxBodyParts* ice_tux = 0;
-
-namespace{
- bool no_water = true;
-}
-void
-TuxBodyParts::set_action(std::string action, int loops)
-{
- if(head != NULL)
- head->set_action(action, loops);
- if(body != NULL)
- body->set_action(action, loops);
- if(arms != NULL)
- arms->set_action(action, loops);
- if(feet != NULL)
- feet->set_action(action, loops);
-}
-
-void
-TuxBodyParts::draw(DrawingContext& context, const Vector& pos, int layer, Portable* grabbed_object)
-{
- if(head != NULL)
- head->draw(context, pos, layer-2);
- if(body != NULL)
- body->draw(context, pos, layer-4);
- if(arms != NULL)
- arms->draw(context, pos, layer-1 + (grabbed_object?10:0));
- if(feet != NULL)
- feet->draw(context, pos, layer-3);
-}
-
-Player::Player(PlayerStatus* _player_status, const std::string& name)
- : player_status(_player_status), grabbed_object(NULL), ghost_mode(false), climbing(0)
-{
- this->name = name;
- controller = main_controller;
- smalltux_gameover = sprite_manager->create("images/creatures/tux_small/smalltux-gameover.sprite");
- smalltux_star = sprite_manager->create("images/creatures/tux_small/smalltux-star.sprite");
- bigtux_star = sprite_manager->create("images/creatures/tux_big/bigtux-star.sprite");
- airarrow.reset(new Surface("images/engine/hud/airarrow.png"));
-
- sound_manager->preload("sounds/bigjump.wav");
- sound_manager->preload("sounds/jump.wav");
- sound_manager->preload("sounds/hurt.wav");
- sound_manager->preload("sounds/skid.wav");
- sound_manager->preload("sounds/flip.wav");
- sound_manager->preload("sounds/invincible.wav");
- sound_manager->preload("sounds/splash.ogg");
-
- init();
-}
-
-Player::~Player()
-{
- if (climbing) stop_climbing(*climbing);
- delete smalltux_gameover;
- delete smalltux_star;
- delete bigtux_star;
-}
-
-void
-Player::init()
-{
- if(is_big())
- set_size(31.8f, 62.8f);
- else
- set_size(31.8f, 30.8f);
-
- dir = RIGHT;
- old_dir = dir;
- duck = false;
- dead = false;
-
- dying = false;
- peeking = AUTO;
- last_ground_y = 0;
- fall_mode = ON_GROUND;
- jumping = false;
- can_jump = true;
- butt_jump = false;
- deactivated = false;
- backflipping = false;
- backflip_direction = 0;
- visible = true;
- swimming = false;
- speedlimit = 0; //no special limit
-
- on_ground_flag = false;
- grabbed_object = NULL;
-
- climbing = 0;
-
- physic.reset();
-}
-
-void
-Player::expose(HSQUIRRELVM vm, SQInteger table_idx)
-{
- if (name.empty())
- return;
-
- Scripting::expose_object(vm, table_idx, dynamic_cast<Scripting::Player *>(this), name, false);
-}
-
-void
-Player::unexpose(HSQUIRRELVM vm, SQInteger table_idx)
-{
- if (name.empty())
- return;
-
- Scripting::unexpose_object(vm, table_idx, name);
-}
-
-float
-Player::get_speedlimit()
-{
- return speedlimit;
-}
-
-void
-Player::set_speedlimit(float newlimit)
-{
- speedlimit=newlimit;
-}
-
-void
-Player::set_controller(Controller* controller)
-{
- this->controller = controller;
-}
-
-bool
-Player::adjust_height(float new_height)
-{
- Rect bbox2 = bbox;
- bbox2.move(Vector(0, bbox.get_height() - new_height));
- bbox2.set_height(new_height);
-
- if(new_height > bbox.get_height()) {
- Rect additional_space = bbox2;
- additional_space.set_height(new_height - bbox.get_height());
- if(!Sector::current()->is_free_of_statics(additional_space, this, true))
- return false;
- }
-
- // adjust bbox accordingly
- // note that we use members of moving_object for this, so we can run this during CD, too
- set_pos(bbox2.p1);
- set_size(bbox2.get_width(), bbox2.get_height());
- return true;
-}
-
-void
-Player::trigger_sequence(std::string sequence_name)
-{
- if (climbing) stop_climbing(*climbing);
- GameSession::current()->start_sequence(sequence_name);
-}
-
-void
-Player::update(float elapsed_time)
-{
- if( no_water ){
- swimming = false;
- }
- no_water = true;
-
- if(dying && dying_timer.check()) {
- dead = true;
- return;
- }
-
- if(!dying && !deactivated)
- handle_input();
-
- // handle_input() calls apply_friction() when Tux is not walking, so we'll have to do this ourselves
- if (deactivated)
- apply_friction();
-
- // extend/shrink tux collision rectangle so that we fall through/walk over 1
- // tile holes
- if(fabsf(physic.get_velocity_x()) > MAX_WALK_XM) {
- set_width(34);
- } else {
- set_width(31.8f);
- }
-
- // on downward slopes, adjust vertical velocity so tux walks smoothly down
- if (on_ground()) {
- if(floor_normal.y != 0) {
- if ((floor_normal.x * physic.get_velocity_x()) >= 0) {
- physic.set_velocity_y(250);
- }
- }
- }
-
- // handle backflipping
- if (backflipping) {
- //prevent player from changing direction when backflipping
- dir = (backflip_direction == 1) ? LEFT : RIGHT;
- if (backflip_timer.started()) physic.set_velocity_x(100 * backflip_direction);
- }
-
- // set fall mode...
- if(on_ground()) {
- fall_mode = ON_GROUND;
- last_ground_y = get_pos().y;
- } else {
- if(get_pos().y > last_ground_y)
- fall_mode = FALLING;
- else if(fall_mode == ON_GROUND)
- fall_mode = JUMPING;
- }
-
- // check if we landed
- if(on_ground()) {
- jumping = false;
- if (backflipping && (!backflip_timer.started())) {
- backflipping = false;
- backflip_direction = 0;
-
- // if controls are currently deactivated, we take care of standing up ourselves
- if (deactivated)
- do_standup();
- }
- }
-
- // calculate movement for this frame
- movement = physic.get_movement(elapsed_time);
-
- if(grabbed_object != NULL && !dying) {
- Vector pos = get_pos() +
- Vector(dir == LEFT ? -16 : 16, get_bbox().get_height()*0.66666 - 32);
- grabbed_object->grab(*this, pos, dir);
- }
-
- if(grabbed_object != NULL && dying){
- grabbed_object->ungrab(*this, dir);
- grabbed_object = NULL;
- }
-
- on_ground_flag = false;
-
- // when invincible, spawn particles
- if (invincible_timer.started() && !dying)
- {
- if (systemRandom.rand(0, 2) == 0) {
- float px = systemRandom.randf(bbox.p1.x+0, bbox.p2.x-0);
- float py = systemRandom.randf(bbox.p1.y+0, bbox.p2.y-0);
- Vector ppos = Vector(px, py);
- Vector pspeed = Vector(0, 0);
- Vector paccel = Vector(0, 0);
- // draw bright sparkle when there is lots of time left, dark sparkle when invincibility is about to end
- if (invincible_timer.get_timeleft() > TUX_INVINCIBLE_TIME_WARNING) {
- // make every other a longer sparkle to make trail a bit fuzzy
- if (size_t(game_time*20)%2) {
- Sector::current()->add_object(new SpriteParticle("images/objects/particles/sparkle.sprite", "small", ppos, ANCHOR_MIDDLE, pspeed, paccel, LAYER_OBJECTS+1+5));
- } else {
- Sector::current()->add_object(new SpriteParticle("images/objects/particles/sparkle.sprite", "medium", ppos, ANCHOR_MIDDLE, pspeed, paccel, LAYER_OBJECTS+1+5));
- }
- } else {
- Sector::current()->add_object(new SpriteParticle("images/objects/particles/sparkle.sprite", "dark", ppos, ANCHOR_MIDDLE, pspeed, paccel, LAYER_OBJECTS+1+5));
- }
- }
- }
-
-}
-
-bool
-Player::on_ground()
-{
- return on_ground_flag;
-}
-
-bool
-Player::is_big()
-{
- if(player_status->bonus == NO_BONUS)
- return false;
-
- return true;
-}
-
-void
-Player::apply_friction()
-{
- if ((on_ground()) && (fabs(physic.get_velocity_x()) < WALK_SPEED)) {
- physic.set_velocity_x(0);
- physic.set_acceleration_x(0);
- } else if(physic.get_velocity_x() < 0) {
- physic.set_acceleration_x(WALK_ACCELERATION_X * 1.5);
- } else if(physic.get_velocity_x() > 0) {
- physic.set_acceleration_x(WALK_ACCELERATION_X * -1.5);
- }
-}
-
-void
-Player::handle_horizontal_input()
-{
- float vx = physic.get_velocity_x();
- float vy = physic.get_velocity_y();
- float ax = physic.get_acceleration_x();
- float ay = physic.get_acceleration_y();
-
- float dirsign = 0;
- if(!duck || physic.get_velocity_y() != 0) {
- if(controller->hold(Controller::LEFT) && !controller->hold(Controller::RIGHT)) {
- old_dir = dir;
- dir = LEFT;
- dirsign = -1;
- } else if(!controller->hold(Controller::LEFT)
- && controller->hold(Controller::RIGHT)) {
- old_dir = dir;
- dir = RIGHT;
- dirsign = 1;
- }
- }
-
- // do not run if action key is pressed or we're holding something
- // so tux can only walk while shooting
- if ( controller->hold(Controller::ACTION) || grabbed_object ) {
- ax = dirsign * WALK_ACCELERATION_X;
- // limit speed
- if(vx >= MAX_WALK_XM && dirsign > 0) {
- vx = MAX_WALK_XM;
- ax = 0;
- } else if(vx <= -MAX_WALK_XM && dirsign < 0) {
- vx = -MAX_WALK_XM;
- ax = 0;
- }
- } else {
- if( vx * dirsign < MAX_WALK_XM ) {
- ax = dirsign * WALK_ACCELERATION_X;
- } else {
- ax = dirsign * RUN_ACCELERATION_X;
- }
- // limit speed
- if(vx >= MAX_RUN_XM && dirsign > 0) {
- vx = MAX_RUN_XM;
- ax = 0;
- } else if(vx <= -MAX_RUN_XM && dirsign < 0) {
- vx = -MAX_RUN_XM;
- ax = 0;
- }
- }
-
- // we can reach WALK_SPEED without any acceleration
- if(dirsign != 0 && fabs(vx) < WALK_SPEED) {
- vx = dirsign * WALK_SPEED;
- }
-
- //Check speedlimit.
- if( speedlimit > 0 && vx * dirsign >= speedlimit ) {
- vx = dirsign * speedlimit;
- ax = 0;
- }
-
- // changing directions?
- if(on_ground() && ((vx < 0 && dirsign >0) || (vx>0 && dirsign<0))) {
- // let's skid!
- if(fabs(vx)>SKID_XM && !skidding_timer.started()) {
- skidding_timer.start(SKID_TIME);
- sound_manager->play("sounds/skid.wav");
- // dust some particles
- Sector::current()->add_object(
- new Particles(
- Vector(dir == RIGHT ? get_bbox().p2.x : get_bbox().p1.x, get_bbox().p2.y),
- dir == RIGHT ? 270+20 : 90-40, dir == RIGHT ? 270+40 : 90-20,
- Vector(280, -260), Vector(0, 300), 3, Color(.4f, .4f, .4f), 3, .8f,
- LAYER_OBJECTS+1));
-
- ax *= 2.5;
- } else {
- ax *= 2;
- }
- }
-
- physic.set_velocity(vx, vy);
- physic.set_acceleration(ax, ay);
-
- // we get slower when not pressing any keys
- if(dirsign == 0) {
- apply_friction();
- }
-
-}
-
-void
-Player::do_cheer()
-{
- do_duck();
- do_backflip();
- do_standup();
-}
-
-void
-Player::do_duck() {
- if (duck)
- return;
- if (!is_big())
- return;
-
- if (physic.get_velocity_y() != 0)
- return;
- if (!on_ground())
- return;
-
- if (adjust_height(31.8f)) {
- duck = true;
- unduck_hurt_timer.stop();
- } else {
- // FIXME: what now?
- }
-}
-
-void
-Player::do_standup() {
- if (!duck)
- return;
- if (!is_big())
- return;
- if (backflipping)
- return;
-
- if (adjust_height(63.8f)) {
- duck = false;
- unduck_hurt_timer.stop();
- } else {
- // if timer is not already running, start it.
- if (unduck_hurt_timer.get_period() == 0) {
- unduck_hurt_timer.start(UNDUCK_HURT_TIME);
- }
- else if (unduck_hurt_timer.check()) {
- kill(false);
- }
- }
-
-}
-
-void
-Player::do_backflip() {
- if (!duck)
- return;
- if (!on_ground())
- return;
-
- backflip_direction = (dir == LEFT)?(+1):(-1);
- backflipping = true;
- do_jump(-580);
- sound_manager->play("sounds/flip.wav");
- backflip_timer.start(0.15f);
-}
-
-void
-Player::do_jump(float yspeed) {
- if (!on_ground())
- return;
-
- physic.set_velocity_y(yspeed);
- //bbox.move(Vector(0, -1));
- jumping = true;
- on_ground_flag = false;
- can_jump = false;
-
- // play sound
- if (is_big()) {
- sound_manager->play("sounds/bigjump.wav");
- } else {
- sound_manager->play("sounds/jump.wav");
- }
-}
-
-void
-Player::handle_vertical_input()
-{
- // Press jump key
- if(controller->pressed(Controller::JUMP) && (can_jump)) {
- if (duck) {
- // when running, only jump a little bit; else do a backflip
- if ((physic.get_velocity_x() != 0) || (controller->hold(Controller::LEFT)) || (controller->hold(Controller::RIGHT))) do_jump(-300); else do_backflip();
- } else {
- // jump a bit higher if we are running; else do a normal jump
- if (fabs(physic.get_velocity_x()) > MAX_WALK_XM) do_jump(-580); else do_jump(-520);
- }
- }
- // Let go of jump key
- else if(!controller->hold(Controller::JUMP)) {
- if (!backflipping && jumping && physic.get_velocity_y() < 0) {
- jumping = false;
- physic.set_velocity_y(0);
- }
- }
-
- /* In case the player has pressed Down while in a certain range of air,
- enable butt jump action */
- if (controller->hold(Controller::DOWN) && !butt_jump && !duck && is_big() && jumping) {
- butt_jump = true;
- }
-
- /* When Down is not held anymore, disable butt jump */
- if(butt_jump && !controller->hold(Controller::DOWN))
- butt_jump = false;
-
- // swimming
- physic.set_acceleration_y(0);
-#ifdef SWIMMING
- if (swimming) {
- if (controller->hold(Controller::UP) || controller->hold(Controller::JUMP))
- physic.set_acceleration_y(-2000);
- physic.set_velocity_y(physic.get_velocity_y() * 0.94);
- }
-#endif
-}
-
-void
-Player::handle_input()
-{
- if (ghost_mode) {
- handle_input_ghost();
- return;
- }
- if (climbing) {
- handle_input_climbing();
- return;
- }
-
- /* Peeking */
- if( controller->released( Controller::PEEK_LEFT ) ) {
- peeking = AUTO;
- }
- if( controller->released( Controller::PEEK_RIGHT ) ) {
- peeking = AUTO;
- }
- if( controller->released( Controller::UP ) ) {
- peeking = AUTO;
- }
- if( controller->released( Controller::DOWN ) ) {
- peeking = AUTO;
- }
- if( controller->pressed( Controller::PEEK_LEFT ) ) {
- peeking = LEFT;
- }
- if( controller->pressed( Controller::PEEK_RIGHT ) ) {
- peeking = RIGHT;
- }
- if( controller->pressed( Controller::UP ) ) {
- peeking = UP;
- }
- if( controller->pressed( Controller::DOWN ) ) {
- peeking = DOWN;
- }
-
- /* Handle horizontal movement: */
- if (!backflipping) handle_horizontal_input();
-
- /* Jump/jumping? */
- if (on_ground() && !controller->hold(Controller::JUMP))
- can_jump = true;
-
- /* Handle vertical movement: */
- handle_vertical_input();
-
- /* Shoot! */
- if (controller->pressed(Controller::ACTION) && (player_status->bonus == FIRE_BONUS || player_status->bonus == ICE_BONUS)) {
- if(Sector::current()->add_bullet(
- get_pos() + ((dir == LEFT)? Vector(0, bbox.get_height()/2)
- : Vector(32, bbox.get_height()/2)),
- physic.get_velocity_x(), dir))
- shooting_timer.start(SHOOTING_TIME);
- }
-
- /* Duck or Standup! */
- if (controller->hold(Controller::DOWN)) {
- do_duck();
- } else {
- do_standup();
- }
-
- /* grabbing */
- try_grab();
-
- if(!controller->hold(Controller::ACTION) && grabbed_object) {
- // move the grabbed object a bit away from tux
- Vector pos = get_pos() +
- Vector(dir == LEFT ? -bbox.get_width()-1 : bbox.get_width()+1,
- bbox.get_height()*0.66666 - 32);
- Rect dest(pos, pos + Vector(32, 32));
- if(Sector::current()->is_free_of_movingstatics(dest)) {
- MovingObject* moving_object = dynamic_cast<MovingObject*> (grabbed_object);
- if(moving_object) {
- moving_object->set_pos(pos);
- } else {
- log_debug << "Non MovingObject grabbed?!?" << std::endl;
- }
- if(controller->hold(Controller::UP)) {
- grabbed_object->ungrab(*this, UP);
- } else {
- grabbed_object->ungrab(*this, dir);
- }
- grabbed_object = NULL;
- }
- }
-}
-
-void
-Player::try_grab()
-{
- if(controller->hold(Controller::ACTION) && !grabbed_object
- && !duck) {
- Sector* sector = Sector::current();
- Vector pos;
- if(dir == LEFT) {
- pos = Vector(bbox.get_left() - 5, bbox.get_bottom() - 16);
- } else {
- pos = Vector(bbox.get_right() + 5, bbox.get_bottom() - 16);
- }
-
- for(Sector::Portables::iterator i = sector->portables.begin();
- i != sector->portables.end(); ++i) {
- Portable* portable = *i;
- if(!portable->is_portable())
- continue;
-
- // make sure the Portable is a MovingObject
- MovingObject* moving_object = dynamic_cast<MovingObject*> (portable);
- assert(moving_object);
- if(moving_object == NULL)
- continue;
-
- // make sure the Portable isn't currently non-solid
- if(moving_object->get_group() == COLGROUP_DISABLED) continue;
-
- // check if we are within reach
- if(moving_object->get_bbox().contains(pos)) {
- if (climbing) stop_climbing(*climbing);
- grabbed_object = portable;
- grabbed_object->grab(*this, get_pos(), dir);
- break;
- }
- }
- }
-}
-
-void
-Player::handle_input_ghost()
-{
- float vx = 0;
- float vy = 0;
- if (controller->hold(Controller::LEFT)) {
- dir = LEFT;
- vx -= MAX_RUN_XM * 2;
- }
- if (controller->hold(Controller::RIGHT)) {
- dir = RIGHT;
- vx += MAX_RUN_XM * 2;
- }
- if ((controller->hold(Controller::UP)) || (controller->hold(Controller::JUMP))) {
- vy -= MAX_RUN_XM * 2;
- }
- if (controller->hold(Controller::DOWN)) {
- vy += MAX_RUN_XM * 2;
- }
- if (controller->hold(Controller::ACTION)) {
- set_ghost_mode(false);
- }
- physic.set_velocity(vx, vy);
- physic.set_acceleration(0, 0);
-}
-
-void
-Player::add_coins(int count)
-{
- player_status->add_coins(count);
-}
-
-int
-Player::get_coins()
-{
- return player_status->coins;
-}
-
-bool
-Player::add_bonus(const std::string& bonustype)
-{
- BonusType type = NO_BONUS;
-
- if(bonustype == "grow") {
- type = GROWUP_BONUS;
- } else if(bonustype == "fireflower") {
- type = FIRE_BONUS;
- } else if(bonustype == "iceflower") {
- type = ICE_BONUS;
- } else if(bonustype == "none") {
- type = NO_BONUS;
- } else {
- std::ostringstream msg;
- msg << "Unknown bonus type " << bonustype;
- throw std::runtime_error(msg.str());
- }
-
- return add_bonus(type);
-}
-
-bool
-Player::add_bonus(BonusType type, bool animate)
-{
- // always ignore NO_BONUS
- if (type == NO_BONUS) {
- return true;
- }
-
- // ignore GROWUP_BONUS if we're already big
- if (type == GROWUP_BONUS) {
- if (player_status->bonus == GROWUP_BONUS)
- return true;
- if (player_status->bonus == FIRE_BONUS)
- return true;
- if (player_status->bonus == ICE_BONUS)
- return true;
- }
-
- return set_bonus(type, animate);
-}
-
-bool
-Player::set_bonus(BonusType type, bool animate)
-{
- if(player_status->bonus == NO_BONUS) {
- if (!adjust_height(62.8f)) {
- printf("can't adjust\n");
- return false;
- }
- if(animate)
- growing_timer.start(GROWING_TIME);
- if (climbing) stop_climbing(*climbing);
- }
-
- if ((type == NO_BONUS) || (type == GROWUP_BONUS)) {
- if ((player_status->bonus == FIRE_BONUS) && (animate)) {
- // visually lose helmet
- Vector ppos = Vector((bbox.p1.x + bbox.p2.x) / 2, bbox.p1.y);
- Vector pspeed = Vector(((dir==LEFT) ? +100 : -100), -300);
- Vector paccel = Vector(0, 1000);
- std::string action = (dir==LEFT)?"left":"right";
- Sector::current()->add_object(new SpriteParticle("images/objects/particles/firetux-helmet.sprite", action, ppos, ANCHOR_TOP, pspeed, paccel, LAYER_OBJECTS-1));
- if (climbing) stop_climbing(*climbing);
- }
- if ((player_status->bonus == ICE_BONUS) && (animate)) {
- // visually lose cap
- Vector ppos = Vector((bbox.p1.x + bbox.p2.x) / 2, bbox.p1.y);
- Vector pspeed = Vector(((dir==LEFT) ? +100 : -100), -300);
- Vector paccel = Vector(0, 1000);
- std::string action = (dir==LEFT)?"left":"right";
- Sector::current()->add_object(new SpriteParticle("images/objects/particles/icetux-cap.sprite", action, ppos, ANCHOR_TOP, pspeed, paccel, LAYER_OBJECTS-1));
- if (climbing) stop_climbing(*climbing);
- }
- player_status->max_fire_bullets = 0;
- player_status->max_ice_bullets = 0;
- }
- if (type == FIRE_BONUS) player_status->max_fire_bullets++;
- if (type == ICE_BONUS) player_status->max_ice_bullets++;
-
- player_status->bonus = type;
- return true;
-}
-
-void
-Player::set_visible(bool visible)
-{
- this->visible = visible;
- if( visible )
- set_group(COLGROUP_MOVING);
- else
- set_group(COLGROUP_DISABLED);
-}
-
-bool
-Player::get_visible()
-{
- return visible;
-}
-
-void
-Player::kick()
-{
- kick_timer.start(KICK_TIME);
-}
-
-void
-Player::draw(DrawingContext& context)
-{
- if(!visible)
- return;
-
- // if Tux is above camera, draw little "air arrow" to show where he is x-wise
- if (Sector::current() && Sector::current()->camera && (get_bbox().p2.y - 16 < Sector::current()->camera->get_translation().y)) {
- float px = get_pos().x + (get_bbox().p2.x - get_bbox().p1.x - airarrow.get()->get_width()) / 2;
- float py = Sector::current()->camera->get_translation().y;
- py += std::min(((py - (get_bbox().p2.y + 16)) / 4), 16.0f);
- context.draw_surface(airarrow.get(), Vector(px, py), LAYER_HUD - 1);
- }
-
- TuxBodyParts* tux_body;
-
- if (player_status->bonus == GROWUP_BONUS)
- tux_body = big_tux;
- else if (player_status->bonus == FIRE_BONUS)
- tux_body = fire_tux;
- else if (player_status->bonus == ICE_BONUS)
- tux_body = ice_tux;
- else
- tux_body = small_tux;
-
- int layer = LAYER_OBJECTS + 1;
-
- /* Set Tux sprite action */
- if (climbing)
- {
- tux_body->set_action("skid-left");
- }
- else if (backflipping)
- {
- if(dir == LEFT)
- tux_body->set_action("backflip-left");
- else // dir == RIGHT
- tux_body->set_action("backflip-right");
- }
- else if (duck && is_big())
- {
- if(dir == LEFT)
- tux_body->set_action("duck-left");
- else // dir == RIGHT
- tux_body->set_action("duck-right");
- }
- else if (skidding_timer.started() && !skidding_timer.check())
- {
- if(dir == LEFT)
- tux_body->set_action("skid-left");
- else // dir == RIGHT
- tux_body->set_action("skid-right");
- }
- else if (kick_timer.started() && !kick_timer.check())
- {
- if(dir == LEFT)
- tux_body->set_action("kick-left");
- else // dir == RIGHT
- tux_body->set_action("kick-right");
- }
- else if (butt_jump && is_big())
- {
- if(dir == LEFT)
- tux_body->set_action("buttjump-left");
- else // dir == RIGHT
- tux_body->set_action("buttjump-right");
- }
- else if (!on_ground())
- {
- if(dir == LEFT)
- tux_body->set_action("jump-left");
- else // dir == RIGHT
- tux_body->set_action("jump-right");
- }
- else
- {
- if (fabsf(physic.get_velocity_x()) < 1.0f) // standing
- {
- if(dir == LEFT)
- tux_body->set_action("stand-left");
- else // dir == RIGHT
- tux_body->set_action("stand-right");
- }
- else // moving
- {
- if(dir == LEFT)
- tux_body->set_action("walk-left");
- else // dir == RIGHT
- tux_body->set_action("walk-right");
- }
- }
-
- if(idle_timer.check())
- {
- if(is_big())
- {
- if(dir == LEFT)
- tux_body->head->set_action("idle-left", 1);
- else // dir == RIGHT
- tux_body->head->set_action("idle-right", 1);
- }
-
- }
-
- // Tux is holding something
- if ((grabbed_object != 0 && physic.get_velocity_y() == 0) ||
- (shooting_timer.get_timeleft() > 0 && !shooting_timer.check()))
- {
- if (duck)
- {
- if(dir == LEFT)
- tux_body->arms->set_action("duck+grab-left");
- else // dir == RIGHT
- tux_body->arms->set_action("duck+grab-right");
- }
- else
- {
- if(dir == LEFT)
- tux_body->arms->set_action("grab-left");
- else // dir == RIGHT
- tux_body->arms->set_action("grab-right");
- }
- }
-
- /* Draw Tux */
- if(dying) {
- smalltux_gameover->draw(context, get_pos(), LAYER_FLOATINGOBJECTS + 1);
- }
- else if ((growing_timer.get_timeleft() > 0) && (!duck)) {
- if (dir == RIGHT) {
- context.draw_surface(growingtux_right[int((growing_timer.get_timegone() *
- GROWING_FRAMES) / GROWING_TIME)], get_pos(), layer);
- } else {
- context.draw_surface(growingtux_left[int((growing_timer.get_timegone() *
- GROWING_FRAMES) / GROWING_TIME)], get_pos(), layer);
- }
- }
- else if (safe_timer.started() && size_t(game_time*40)%2)
- ; // don't draw Tux
- else
- tux_body->draw(context, get_pos(), layer, grabbed_object);
-
-}
-
-void
-Player::collision_tile(uint32_t tile_attributes)
-{
- if(tile_attributes & Tile::HURTS)
- kill(false);
-
-#ifdef SWIMMING
- if( swimming ){
- if( tile_attributes & Tile::WATER ){
- no_water = false;
- } else {
- swimming = false;
- }
- } else {
- if( tile_attributes & Tile::WATER ){
- swimming = true;
- no_water = false;
- sound_manager->play( "sounds/splash.ogg" );
- }
- }
-#endif
-}
-
-void
-Player::collision_solid(const CollisionHit& hit)
-{
- if(hit.bottom) {
- if(physic.get_velocity_y() > 0)
- physic.set_velocity_y(0);
-
- on_ground_flag = true;
- floor_normal = hit.slope_normal;
- } else if(hit.top) {
- if(physic.get_velocity_y() < 0)
- physic.set_velocity_y(.2f);
- }
-
- if(hit.left || hit.right) {
- physic.set_velocity_x(0);
- }
-
- // crushed?
- if(hit.crush) {
- if(hit.left || hit.right) {
- kill(true);
- } else if(hit.top || hit.bottom) {
- kill(false);
- }
- }
-}
-
-HitResponse
-Player::collision(GameObject& other, const CollisionHit& hit)
-{
- Bullet* bullet = dynamic_cast<Bullet*> (&other);
- if(bullet) {
- return FORCE_MOVE;
- }
-
- if(hit.left || hit.right) {
- try_grab(); //grab objects right now, in update it will be too late
- }
-#ifdef DEBUG
- assert(dynamic_cast<MovingObject*> (&other) != NULL);
-#endif
- MovingObject* moving_object = static_cast<MovingObject*> (&other);
- if(moving_object->get_group() == COLGROUP_TOUCHABLE) {
- TriggerBase* trigger = dynamic_cast<TriggerBase*> (&other);
- if(trigger) {
- if(controller->pressed(Controller::UP))
- trigger->event(*this, TriggerBase::EVENT_ACTIVATE);
- }
-
- return FORCE_MOVE;
- }
-
- BadGuy* badguy = dynamic_cast<BadGuy*> (&other);
- if(badguy != NULL) {
- if(safe_timer.started() || invincible_timer.started())
- return FORCE_MOVE;
-
- return CONTINUE;
- }
-
- return CONTINUE;
-}
-
-void
-Player::make_invincible()
-{
- sound_manager->play("sounds/invincible.wav");
- invincible_timer.start(TUX_INVINCIBLE_TIME);
- Sector::current()->play_music(HERRING_MUSIC);
-}
-
-/* Kill Player! */
-void
-Player::kill(bool completely)
-{
- if(dying || deactivated)
- return;
-
- if(!completely && (safe_timer.started() || invincible_timer.started()))
- return;
-
- sound_manager->play("sounds/hurt.wav");
- if (climbing) stop_climbing(*climbing);
-
- physic.set_velocity_x(0);
-
- if(!completely && (is_big() || growing_timer.started())) {
- if(player_status->bonus == FIRE_BONUS
- || player_status->bonus == ICE_BONUS) {
- safe_timer.start(TUX_SAFE_TIME);
- set_bonus(GROWUP_BONUS, true);
- } else if(player_status->bonus == GROWUP_BONUS) {
- //growing_timer.start(GROWING_TIME);
- safe_timer.start(TUX_SAFE_TIME /* + GROWING_TIME */);
- adjust_height(30.8f);
- duck = false;
- set_bonus(NO_BONUS, true);
- } else if(player_status->bonus == NO_BONUS) {
- growing_timer.stop();
- safe_timer.start(TUX_SAFE_TIME);
- adjust_height(30.8f);
- duck = false;
- }
- } else {
- if (player_status->coins >= 25 && !GameSession::current()->get_reset_point_sectorname().empty())
- {
- for (int i = 0; i < 5; i++)
- {
- // the numbers: starting x, starting y, velocity y
- Sector::current()->add_object(new FallingCoin(get_pos() +
- Vector(systemRandom.rand(5), systemRandom.rand(-32,18)),
- systemRandom.rand(-100,100)));
- }
- player_status->coins -= std::max(player_status->coins/10, 25);
- }
- else
- {
- GameSession::current()->set_reset_point("", Vector());
- }
- physic.enable_gravity(true);
- physic.set_acceleration(0, 0);
- physic.set_velocity(0, -700);
- set_bonus(NO_BONUS, true);
- dying = true;
- dying_timer.start(3.0);
- set_group(COLGROUP_DISABLED);
-
- DisplayEffect* effect = new DisplayEffect();
- effect->fade_out(3.0);
- Sector::current()->add_object(effect);
- sound_manager->stop_music(3.0);
- }
-}
-
-void
-Player::move(const Vector& vector)
-{
- set_pos(vector);
-
- // TODO: do we need the following? Seems irrelevant to moving the player
- if(is_big())
- set_size(31.8f, 63.8f);
- else
- set_size(31.8f, 31.8f);
- duck = false;
- last_ground_y = vector.y;
- if (climbing) stop_climbing(*climbing);
-
- physic.reset();
-}
-
-void
-Player::check_bounds(Camera* camera)
-{
- /* Keep tux in bounds: */
- if (get_pos().x < 0) {
- // Lock Tux to the size of the level, so that he doesn't fall of
- // on the left side
- set_pos(Vector(0, get_pos().y));
- }
-
- /* fallen out of the level? */
- if (get_pos().y > Sector::current()->get_height()) {
- kill(true);
- return;
- }
-
- // can happen if back scrolling is disabled
- if(get_pos().x < camera->get_translation().x) {
- set_pos(Vector(camera->get_translation().x, get_pos().y));
- }
- if(get_pos().x >= camera->get_translation().x + SCREEN_WIDTH - bbox.get_width())
- {
- set_pos(Vector(
- camera->get_translation().x + SCREEN_WIDTH - bbox.get_width(),
- get_pos().y));
- }
-}
-
-void
-Player::add_velocity(const Vector& velocity)
-{
- physic.set_velocity(physic.get_velocity() + velocity);
-}
-
-void
-Player::add_velocity(const Vector& velocity, const Vector& end_speed)
-{
- if (end_speed.x > 0)
- physic.set_velocity_x(std::min(physic.get_velocity_x() + velocity.x, end_speed.x));
- if (end_speed.x < 0)
- physic.set_velocity_x(std::max(physic.get_velocity_x() + velocity.x, end_speed.x));
- if (end_speed.y > 0)
- physic.set_velocity_y(std::min(physic.get_velocity_y() + velocity.y, end_speed.y));
- if (end_speed.y < 0)
- physic.set_velocity_y(std::max(physic.get_velocity_y() + velocity.y, end_speed.y));
-}
-
-void
-Player::bounce(BadGuy& )
-{
- if(controller->hold(Controller::JUMP))
- physic.set_velocity_y(-520);
- else
- physic.set_velocity_y(-300);
-}
-
-//Scripting Functions Below
-
-void
-Player::deactivate()
-{
- if (deactivated)
- return;
- deactivated = true;
- physic.set_velocity_x(0);
- physic.set_velocity_y(0);
- physic.set_acceleration_x(0);
- physic.set_acceleration_y(0);
- if (climbing) stop_climbing(*climbing);
-}
-
-void
-Player::activate()
-{
- if (!deactivated)
- return;
- deactivated = false;
-}
-
-void Player::walk(float speed)
-{
- physic.set_velocity_x(speed);
-}
-
-void
-Player::set_ghost_mode(bool enable)
-{
- if (ghost_mode == enable)
- return;
-
- if (climbing) stop_climbing(*climbing);
-
- if (enable) {
- ghost_mode = true;
- set_group(COLGROUP_DISABLED);
- physic.enable_gravity(false);
- log_debug << "You feel lightheaded. Use movement controls to float around, press ACTION to scare badguys." << std::endl;
- } else {
- ghost_mode = false;
- set_group(COLGROUP_MOVING);
- physic.enable_gravity(true);
- log_debug << "You feel solid again." << std::endl;
- }
-}
-
-
-void
-Player::start_climbing(Climbable& climbable)
-{
- if (climbing == &climbable) return;
-
- climbing = &climbable;
- physic.enable_gravity(false);
- physic.set_velocity(0, 0);
- physic.set_acceleration(0, 0);
-}
-
-void
-Player::stop_climbing(Climbable& /*climbable*/)
-{
- if (!climbing) return;
-
- climbing = 0;
-
- if (grabbed_object) {
- grabbed_object->ungrab(*this, dir);
- grabbed_object = NULL;
- }
-
- physic.enable_gravity(true);
- physic.set_velocity(0, 0);
- physic.set_acceleration(0, 0);
-
- if ((controller->hold(Controller::JUMP)) || (controller->hold(Controller::UP))) {
- on_ground_flag = true;
- // TODO: This won't help. Why?
- do_jump(-300);
- }
-}
-
-void
-Player::handle_input_climbing()
-{
- if (!climbing) {
- log_warning << "handle_input_climbing called with climbing set to 0. Input handling skipped" << std::endl;
- return;
- }
-
- float vx = 0;
- float vy = 0;
- if (controller->hold(Controller::LEFT)) {
- dir = LEFT;
- vx -= MAX_CLIMB_XM;
- }
- if (controller->hold(Controller::RIGHT)) {
- dir = RIGHT;
- vx += MAX_CLIMB_XM;
- }
- if (controller->hold(Controller::UP)) {
- vy -= MAX_CLIMB_YM;
- }
- if (controller->hold(Controller::DOWN)) {
- vy += MAX_CLIMB_YM;
- }
- if (controller->hold(Controller::JUMP)) {
- if (can_jump) {
- stop_climbing(*climbing);
- return;
- }
- } else {
- can_jump = true;
- }
- if (controller->hold(Controller::ACTION)) {
- stop_climbing(*climbing);
- return;
- }
- physic.set_velocity(vx, vy);
- physic.set_acceleration(0, 0);
-}
-
-
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef SUPERTUX_PLAYER_H
-#define SUPERTUX_PLAYER_H
-
-#include <vector>
-#include <SDL.h>
-
-#include "timer.hpp"
-#include "direction.hpp"
-#include "video/surface.hpp"
-#include "moving_object.hpp"
-#include "sprite/sprite.hpp"
-#include "physic.hpp"
-#include "control/controller.hpp"
-#include "scripting/player.hpp"
-#include "player_status.hpp"
-#include "display_effect.hpp"
-#include "script_interface.hpp"
-#include "console.hpp"
-#include "coin.hpp"
-
-class BadGuy;
-class Portable;
-class Climbable;
-
-/* Times: */
-static const float TUX_SAFE_TIME = 1.8f;
-static const float TUX_INVINCIBLE_TIME = 10.0f;
-static const float TUX_INVINCIBLE_TIME_WARNING = 2.0f;
-static const float GROWING_TIME = 0.35f;
-static const int GROWING_FRAMES = 7;
-
-class Camera;
-class PlayerStatus;
-
-extern Surface* growingtux_left[GROWING_FRAMES];
-extern Surface* growingtux_right[GROWING_FRAMES];
-
-class TuxBodyParts
-{
-public:
- TuxBodyParts()
- : head(0), body(0), arms(0), feet(0)
- { }
- ~TuxBodyParts() {
- delete head;
- delete body;
- delete arms;
- delete feet;
- }
-
- void set_action(std::string action, int loops = -1);
- void one_time_animation();
- void draw(DrawingContext& context, const Vector& pos, int layer, Portable* grabbed_object);
-
- Sprite* head;
- Sprite* body;
- Sprite* arms;
- Sprite* feet;
-};
-
-extern TuxBodyParts* small_tux;
-extern TuxBodyParts* big_tux;
-extern TuxBodyParts* fire_tux;
-extern TuxBodyParts* ice_tux;
-
-class Player : public MovingObject, public UsesPhysic, public Scripting::Player, public ScriptInterface
-{
-public:
- enum FallMode { ON_GROUND, JUMPING, TRAMPOLINE_JUMP, FALLING };
-
- Controller* controller;
- PlayerStatus* player_status;
- bool duck;
- bool dead;
- //Tux can only go this fast. If set to 0 no special limit is used, only the default limits.
- void set_speedlimit(float newlimit);
- float get_speedlimit();
-
-private:
- bool dying;
- bool backflipping;
- int backflip_direction;
- Direction peeking;
- bool swimming;
- float speedlimit;
-
-public:
- Direction dir;
- Direction old_dir;
-
- float last_ground_y;
- FallMode fall_mode;
-
- bool on_ground_flag;
- bool jumping;
- bool can_jump;
- bool butt_jump;
-
- Timer invincible_timer;
- Timer skidding_timer;
- Timer safe_timer;
- Timer kick_timer;
- Timer shooting_timer; // used to show the arm when Tux is shooting
- Timer dying_timer;
- Timer growing_timer;
- Timer idle_timer;
- Timer backflip_timer;
-
-public:
- Player(PlayerStatus* player_status, const std::string& name);
- virtual ~Player();
-
- virtual void expose(HSQUIRRELVM vm, SQInteger table_idx);
- virtual void unexpose(HSQUIRRELVM vm, SQInteger table_idx);
-
- void set_controller(Controller* controller);
- Controller* get_controller()
- {
- return controller;
- }
-
- virtual void update(float elapsed_time);
- virtual void draw(DrawingContext& context);
- virtual void collision_solid(const CollisionHit& hit);
- virtual HitResponse collision(GameObject& other, const CollisionHit& hit);
- virtual void collision_tile(uint32_t tile_attributes);
-
- void make_invincible();
- bool is_invincible() const
- {
- return invincible_timer.started();
- }
- bool is_dying() const
- {
- return dying;
- }
- Direction peeking_direction() const
- {
- return peeking;
- }
-
- void kill(bool completely);
- void check_bounds(Camera* camera);
- void move(const Vector& vector);
-
- virtual bool add_bonus(const std::string& bonus);
- virtual void add_coins(int count);
- virtual int get_coins();
-
- /**
- * picks up a bonus, taking care not to pick up lesser bonus items than we already have
- *
- * @returns true if the bonus has been set (or was already good enough)
- * false if the bonus could not be set (for example no space for big tux)
- */
- bool add_bonus(BonusType type, bool animate = false);
- /**
- * like add_bonus, but can also downgrade the bonus items carried
- */
- bool set_bonus(BonusType type, bool animate = false);
-
- PlayerStatus* get_status()
- {
- return player_status;
- }
- // set kick animation
- void kick();
-
- /**
- * play cheer animation.
- * This might need some space and behave in an unpredictable way. Best to use this at level end.
- */
- void do_cheer();
-
- /**
- * duck down if possible.
- * this won't last long as long as input is enabled.
- */
- void do_duck();
-
- /**
- * stand back up if possible.
- */
- void do_standup();
-
- /**
- * do a backflip if possible.
- */
- void do_backflip();
-
- /**
- * jump in the air if possible
- * sensible values for yspeed are negative - unless we want to jump into the ground of course
- */
- void do_jump(float yspeed);
-
- /**
- * Adds velocity to the player (be carefull when using this)
- */
- void add_velocity(const Vector& velocity);
-
- /**
- * Adds velocity to the player until given end speed is reached
- */
- void add_velocity(const Vector& velocity, const Vector& end_speed);
-
- void bounce(BadGuy& badguy);
-
- bool is_dead() const
- { return dead; }
- bool is_big();
-
- void set_visible(bool visible);
- bool get_visible();
-
- bool on_ground();
-
- Portable* get_grabbed_object() const
- {
- return grabbed_object;
- }
-
- /**
- * Switches ghost mode on/off.
- * Lets Tux float around and through solid objects.
- */
- void set_ghost_mode(bool enable);
-
- /**
- * Returns whether ghost mode is currently enabled
- */
- bool get_ghost_mode() { return ghost_mode; }
-
- /**
- * Changes height of bounding box.
- * Returns true if successful, false otherwise
- */
- bool adjust_height(float new_height);
-
- /**
- * Orders the current GameSession to start a sequence
- */
- void trigger_sequence(std::string sequence_name);
-
- /**
- * Requests that the player start climbing the given Climbable
- */
- void start_climbing(Climbable& climbable);
-
- /**
- * Requests that the player stop climbing the given Climbable
- */
- void stop_climbing(Climbable& climbable);
-
-private:
- void handle_input();
- void handle_input_ghost(); /**< input handling while in ghost mode */
- void handle_input_climbing(); /**< input handling while climbing */
- bool deactivated;
-
- void init();
-
- void handle_horizontal_input();
- void handle_vertical_input();
-
- void activate();
- void deactivate();
- void walk(float speed);
-
- /**
- * slows Tux down a little, based on where he's standing
- */
- void apply_friction();
-
- bool visible;
-
- Portable* grabbed_object;
-
- Sprite* smalltux_gameover;
- Sprite* smalltux_star;
- Sprite* bigtux_star;
-
- std::auto_ptr<Surface> airarrow; /**< arrow indicating Tux' position when he's above the camera */
-
- Vector floor_normal;
- void try_grab();
-
- bool ghost_mode; /**< indicates if Tux should float around and through solid objects */
-
- Timer unduck_hurt_timer; /**< if Tux wants to stand up again after ducking and cannot, this timer is started */
-
- Climbable* climbing; /**< Climbable object we are currently climbing, null if none */
-};
-
-#endif /*SUPERTUX_PLAYER_H*/
+++ /dev/null
-// $Id$
-//
-// SuperTux - PneumaticPlatform
-// Copyright (C) 2007 Christoph Sommer <christoph.sommer@2007.expires.deltadevelopment.de>
-//
-// 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.
-
-#include <config.h>
-
-#include "pneumatic_platform.hpp"
-
-#include <stdexcept>
-#include "log.hpp"
-#include "video/drawing_context.hpp"
-#include "resources.hpp"
-#include "player.hpp"
-#include "path.hpp"
-#include "path_walker.hpp"
-#include "sprite/sprite.hpp"
-#include "lisp/lisp.hpp"
-#include "object_factory.hpp"
-#include "sector.hpp"
-#include "object/portable.hpp"
-
-PneumaticPlatform::PneumaticPlatform(const lisp::Lisp& reader)
- : MovingSprite(reader, LAYER_OBJECTS, COLGROUP_STATIC),
- master(0), slave(0), start_y(0), offset_y(0), speed_y(0)
-{
- start_y = get_pos().y;
-}
-
-PneumaticPlatform::PneumaticPlatform(PneumaticPlatform* master)
- : MovingSprite(*master),
- master(master), slave(this), start_y(master->start_y), offset_y(-master->offset_y), speed_y(0)
-{
- set_pos(get_pos() + Vector(master->get_bbox().get_width(), 0));
- master->master = master;
- master->slave = this;
-}
-
-PneumaticPlatform::~PneumaticPlatform() {
- if ((this == master) && (master)) {
- slave->master = 0;
- slave->slave = 0;
- }
- if ((master) && (this == slave)) {
- master->master = 0;
- master->slave = 0;
- }
- master = 0;
- slave = 0;
-}
-
-HitResponse
-PneumaticPlatform::collision(GameObject& other, const CollisionHit& )
-{
-
- // somehow the hit parameter does not get filled in, so to determine (hit.top == true) we do this:
- MovingObject* mo = dynamic_cast<MovingObject*>(&other);
- if (!mo) return FORCE_MOVE;
- if ((mo->get_bbox().p2.y) > (get_bbox().p1.y + 2)) return FORCE_MOVE;
-
- Player* pl = dynamic_cast<Player*>(mo);
- if (pl) {
- if (pl->is_big()) contacts.insert(0);
- Portable* po = pl->get_grabbed_object();
- MovingObject* pomo = dynamic_cast<MovingObject*>(po);
- if (pomo) contacts.insert(pomo);
- }
-
- contacts.insert(&other);
- return FORCE_MOVE;
-}
-
-void
-PneumaticPlatform::update(float elapsed_time)
-{
- if (!slave) {
- Sector::current()->add_object(new PneumaticPlatform(this));
- return;
- }
- if (!master) {
- return;
- }
- if (this == slave) {
- offset_y = -master->offset_y;
- movement = Vector(0, (start_y + offset_y) - get_pos().y);
- }
- if (this == master) {
- int contact_diff = contacts.size() - slave->contacts.size();
- contacts.clear();
- slave->contacts.clear();
-
- speed_y += ((float)contact_diff * elapsed_time) * 128.0f;
- speed_y -= (offset_y * elapsed_time * 0.5f);
- speed_y *= 1 - elapsed_time;
- offset_y += speed_y * elapsed_time;
- if (offset_y < -256) { offset_y = -256; speed_y = 0; }
- if (offset_y > 256) { offset_y = 256; speed_y = -0; }
- movement = Vector(0, (start_y + offset_y) - get_pos().y);
- }
-}
-
-IMPLEMENT_FACTORY(PneumaticPlatform, "pneumatic-platform");
-
+++ /dev/null
-// $Id$
-//
-// SuperTux - PneumaticPlatform
-// Copyright (C) 2007 Christoph Sommer <christoph.sommer@2007.expires.deltadevelopment.de>
-//
-// 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.
-
-#ifndef __PNEUMATIC_PLATFORM_H__
-#define __PNEUMATIC_PLATFORM_H__
-
-#include <memory>
-#include <string>
-#include <set>
-#include "object/moving_sprite.hpp"
-#include "object/path.hpp"
-#include "object/path_walker.hpp"
-
-/**
- * Used to construct a pair of pneumatic platforms: If one is pushed down, the other one rises
- */
-class PneumaticPlatform : public MovingSprite
-{
-public:
- PneumaticPlatform(const lisp::Lisp& reader);
- PneumaticPlatform(PneumaticPlatform* master);
- virtual ~PneumaticPlatform();
-
- virtual HitResponse collision(GameObject& other, const CollisionHit& hit);
- virtual void update(float elapsed_time);
-
-protected:
- PneumaticPlatform* master; /**< pointer to PneumaticPlatform that does movement calculation */
- PneumaticPlatform* slave; /**< pointer to PneumaticPlatform that reacts to master platform's movement calculation */
- float start_y; /**< vertical start position */
- float offset_y; /**< vertical offset from the start position in px */
- float speed_y; /**< vertical speed */
- std::set<GameObject*> contacts; /**< objects that are currently pushing on the platform */
-
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __PORTABLE_H__
-#define __PORTABLE_H__
-
-#include "moving_object.hpp"
-#include "direction.hpp"
-#include "refcounter.hpp"
-
-/**
- * An object that inherits from this object is considered "portable" and can
- * be carried around by the player.
- * The object has to additionally set the PORTABLE flag (this allows to
- * make the object only temporarily portable by resetting the flag)
- */
-class Portable
-{
-public:
- virtual ~Portable()
- { }
-
- /**
- * called each frame when the object has been grabbed.
- */
- virtual void grab(MovingObject& object, const Vector& pos, Direction dir) = 0;
-
- virtual void ungrab(MovingObject& , Direction )
- {}
-
- virtual bool is_portable() const
- {
- return true;
- }
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include <stdexcept>
-#include <math.h>
-#include <stdexcept>
-#include "powerup.hpp"
-#include "resources.hpp"
-#include "player.hpp"
-#include "audio/sound_manager.hpp"
-#include "object_factory.hpp"
-#include "sector.hpp"
-#include "log.hpp"
-
-PowerUp::PowerUp(const lisp::Lisp& lisp)
- : MovingSprite(lisp, LAYER_OBJECTS, COLGROUP_MOVING)
-{
- lisp.get("script", script);
- no_physics = false;
- lisp.get("disable-physics", no_physics);
- physic.enable_gravity(true);
- sound_manager->preload("sounds/grow.wav");
- sound_manager->preload("sounds/fire-flower.wav");
-}
-
-void
-PowerUp::collision_solid(const CollisionHit& hit)
-{
- if(hit.bottom) {
- physic.set_velocity_y(0);
- }
- if(hit.right || hit.left) {
- physic.set_velocity_x(-physic.get_velocity_x());
- }
-}
-
-HitResponse
-PowerUp::collision(GameObject& other, const CollisionHit&)
-{
- Player* player = dynamic_cast<Player*>(&other);
- if(player == 0)
- return FORCE_MOVE;
-
- if (script != "") {
- std::istringstream stream(script);
- Sector::current()->run_script(stream, "powerup-script");
- remove_me();
- return ABORT_MOVE;
- }
-
- // some defaults if no script has been set
- if (sprite_name == "images/powerups/egg/egg.sprite") {
- if(!player->add_bonus(GROWUP_BONUS, true))
- return FORCE_MOVE;
- sound_manager->play("sounds/grow.wav");
- } else if (sprite_name == "images/powerups/fireflower/fireflower.sprite") {
- if(!player->add_bonus(FIRE_BONUS, true))
- return FORCE_MOVE;
- sound_manager->play("sounds/fire-flower.wav");
- } else if (sprite_name == "images/powerups/star/star.sprite") {
- player->make_invincible();
- } else if (sprite_name == "images/powerups/1up/1up.sprite") {
- player->get_status()->add_coins(100);
- }
-
- remove_me();
- return ABORT_MOVE;
-}
-
-void
-PowerUp::update(float elapsed_time)
-{
- if (!no_physics)
- movement = physic.get_movement(elapsed_time);
-}
-
-IMPLEMENT_FACTORY(PowerUp, "powerup");
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __POWERUP_H__
-#define __POWERUP_H__
-
-#include "object/moving_sprite.hpp"
-#include "lisp/lisp.hpp"
-#include "collision_hit.hpp"
-#include "physic.hpp"
-
-class PowerUp : public MovingSprite, private UsesPhysic
-{
-public:
- PowerUp(const lisp::Lisp& lisp);
-
- virtual void update(float elapsed_time);
- virtual void collision_solid(const CollisionHit& hit);
- virtual HitResponse collision(GameObject& other, const CollisionHit& hit);
-
-private:
- std::string script;
- bool no_physics;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux - Pulsing Light
-// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
-//
-// 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.
-
-#include <config.h>
-
-#include "pulsing_light.hpp"
-#include "video/color.hpp"
-#include <math.h>
-#include "random_generator.hpp"
-
-PulsingLight::PulsingLight(const Vector& center, float cycle_len, float min_alpha, float max_alpha, const Color& color)
- : Light(center, color), min_alpha(min_alpha), max_alpha(max_alpha), cycle_len(cycle_len), t(0)
-{
- assert(cycle_len > 0);
-
- // start with random phase offset
- t = systemRandom.randf(0.0, cycle_len);
-}
-
-PulsingLight::~PulsingLight()
-{
-}
-
-void
-PulsingLight::update(float elapsed_time)
-{
- Light::update(elapsed_time);
-
- t += elapsed_time;
- if (t > cycle_len) t -= cycle_len;
-}
-
-void
-PulsingLight::draw(DrawingContext& context)
-{
- Color old_color = color;
-
- color.alpha *= min_alpha + ((max_alpha - min_alpha) * cos(2 * M_PI * t / cycle_len));
- Light::draw(context);
-
- color = old_color;
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux - Pulsing Light
-// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
-//
-// 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.
-
-#ifndef __PULSING_LIGHT_HPP__
-#define __PULSING_LIGHT_HPP__
-
-#include "light.hpp"
-#include "game_object.hpp"
-#include "lisp/lisp.hpp"
-#include "math/vector.hpp"
-#include "video/color.hpp"
-
-class Sprite;
-
-/**
- * Light source that changes alpha value to give the impression of a pulsating light
- */
-class PulsingLight : public Light
-{
-public:
- PulsingLight(const Vector& center, float cycle_len = 5.0, float min_alpha = 0.0, float max_alpha = 1.0, const Color& color = Color(1.0, 1.0, 1.0, 1.0));
- virtual ~PulsingLight();
-
- void update(float elapsed_time);
- void draw(DrawingContext& context);
-
-protected:
- float min_alpha; /**< minimum alpha */
- float max_alpha; /**< maximum alpha */
- float cycle_len; /**< length in seconds of one cycle */
-
- float t; /**< local time in seconds */
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux - PushButton running a script
-// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
-//
-// 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.
-
-#include <config.h>
-#include <stdexcept>
-
-#include "pushbutton.hpp"
-#include "object_factory.hpp"
-#include "player.hpp"
-#include "audio/sound_manager.hpp"
-#include "sprite/sprite_manager.hpp"
-#include "sector.hpp"
-#include "log.hpp"
-
-namespace {
- const std::string BUTTON_SOUND = "sounds/switch.ogg";
- //14 -> 8
-}
-
-PushButton::PushButton(const lisp::Lisp& lisp)
- : MovingSprite(lisp, "images/objects/pushbutton/pushbutton.sprite", LAYER_BACKGROUNDTILES+1, COLGROUP_MOVING), state(OFF)
-{
- sound_manager->preload(BUTTON_SOUND);
- set_action("off", -1);
- bbox.set_size(sprite->get_current_hitbox_width(), sprite->get_current_hitbox_height());
-
- if (!lisp.get("script", script)) throw std::runtime_error("no script set");
-}
-
-void
-PushButton::update(float /*elapsed_time*/)
-{
-}
-
-HitResponse
-PushButton::collision(GameObject& other, const CollisionHit& hit)
-{
- Player* player = dynamic_cast<Player*>(&other);
- if (!player) return FORCE_MOVE;
- float vy = player->physic.get_velocity_y();
-
- //player->add_velocity(Vector(0, -150));
- player->physic.set_velocity_y(-150);
-
- if (state != OFF) return FORCE_MOVE;
- if (!hit.top) return FORCE_MOVE;
- if (vy <= 0) return FORCE_MOVE;
-
- // change appearance
- state = ON;
- float old_bbox_height = bbox.get_height();
- set_action("on", -1);
- float new_bbox_height = bbox.get_height();
- set_pos(get_pos() + Vector(0, old_bbox_height - new_bbox_height));
-
- // play sound
- sound_manager->play(BUTTON_SOUND);
-
- // run script
- std::istringstream stream(script);
- Sector::current()->run_script(stream, "PushButton");
-
- return FORCE_MOVE;
-}
-
-IMPLEMENT_FACTORY(PushButton, "pushbutton");
+++ /dev/null
-// $Id$
-//
-// SuperTux - PushButton running a script
-// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
-//
-// 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.
-
-#ifndef SUPERTUX_BUTTON_H
-#define SUPERTUX_BUTTON_H
-
-#include "moving_sprite.hpp"
-#include "lisp/lisp.hpp"
-
-/**
- * PushButton - jump on it to run a script
- */
-class PushButton : public MovingSprite
-{
-public:
- PushButton(const lisp::Lisp& reader);
-
- HitResponse collision(GameObject& other, const CollisionHit& hit);
- void update(float elapsed_time);
-
-private:
- enum PushButtonState {
- OFF,
- ON
- };
-
- std::string script;
- PushButtonState state;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#include <config.h>
-
-#include "rainsplash.hpp"
-#include "sector.hpp"
-
-RainSplash::RainSplash(Vector pos, bool vertical)
-{
- frame = 0;
- position = pos;
- if (vertical) sprite = sprite_manager->create("images/objects/particles/rainsplash-vertical.sprite");
- else sprite = sprite_manager->create("images/objects/particles/rainsplash.sprite");
-}
-
-RainSplash::~RainSplash() {
- remove_me();
-}
-
-void
-RainSplash::hit(Player& )
-{
-}
-
-void
-RainSplash::update(float time)
-{
- time = 0;//just so i don't get an "unused variable" error - don't know how to circumvent this
- frame++;
- if (frame >= 10) remove_me();
-}
-
-void
-RainSplash::draw(DrawingContext& context)
-{
- sprite->draw(context, position, LAYER_OBJECTS);
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __RAINSPLASH_H__
-#define __RAINSPLASH_H__
-
-
-#include "game_object.hpp"
-#include "resources.hpp"
-#include "player.hpp"
-#include "sprite/sprite.hpp"
-#include "sprite/sprite_manager.hpp"
-#include "video/drawing_context.hpp"
-
-class RainSplash : public GameObject
-{
-public:
- RainSplash(Vector pos, bool vertical);
- ~RainSplash();
-protected:
- virtual void hit(Player& );
- virtual void update(float time);
- virtual void draw(DrawingContext& context);
-private:
- Sprite* sprite;
- Vector position;
- int frame;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include "rock.hpp"
-#include "lisp/writer.hpp"
-#include "object_factory.hpp"
-#include "audio/sound_manager.hpp"
-#include "tile.hpp"
-
-namespace {
- const std::string ROCK_SOUND = "sounds/brick.wav"; //TODO use own sound.
-}
-
-Rock::Rock(const Vector& pos, std::string spritename)
- : MovingSprite(pos, spritename)
-{
- sound_manager->preload(ROCK_SOUND);
- on_ground = false;
- grabbed = false;
- set_group(COLGROUP_MOVING_STATIC);
-}
-
-Rock::Rock(const lisp::Lisp& reader)
- : MovingSprite(reader, "images/objects/rock/rock.sprite")
-{
- sound_manager->preload(ROCK_SOUND);
- on_ground = false;
- grabbed = false;
- set_group(COLGROUP_MOVING_STATIC);
-}
-
-Rock::Rock(const lisp::Lisp& reader, std::string spritename)
- : MovingSprite(reader, spritename)
-{
- sound_manager->preload(ROCK_SOUND);
- on_ground = false;
- grabbed = false;
- set_group(COLGROUP_MOVING_STATIC);
-}
-
-void
-Rock::write(lisp::Writer& writer)
-{
- writer.start_list("rock");
-
- writer.write_float("x", bbox.p1.x);
- writer.write_float("y", bbox.p1.y);
-
- writer.end_list("rock");
-}
-
-void
-Rock::update(float elapsed_time)
-{
- if( grabbed )
- return;
-
- if (on_ground) physic.set_velocity_x(0);
-
- movement = physic.get_movement(elapsed_time);
-}
-
-void
-Rock::collision_solid(const CollisionHit& hit)
-{
- if(grabbed) {
- return;
- }
- if(hit.top || hit.bottom)
- physic.set_velocity_y(0);
- if(hit.left || hit.right)
- physic.set_velocity_x(0);
- if(hit.crush)
- physic.set_velocity(0, 0);
-
- if(hit.bottom && !on_ground && !grabbed) {
- sound_manager->play(ROCK_SOUND, get_pos());
- on_ground = true;
- }
-}
-
-HitResponse
-Rock::collision(GameObject& other, const CollisionHit& hit)
-{
- if(grabbed) {
- return PASSTHROUGH;
- }
- if(!on_ground) {
- if(hit.bottom && physic.get_velocity_y() > 200) {
- MovingObject* moving_object = dynamic_cast<MovingObject*> (&other);
- if(moving_object) {
- //Getting a rock on the head hurts. A lot.
- moving_object->collision_tile(Tile::HURTS);
- }
- }
- return FORCE_MOVE;
- }
-
- return FORCE_MOVE;
-}
-
-void
-Rock::grab(MovingObject& , const Vector& pos, Direction)
-{
- movement = pos - get_pos();
- last_movement = movement;
- set_group(COLGROUP_TOUCHABLE);
- on_ground = false;
- grabbed = true;
-}
-
-void
-Rock::ungrab(MovingObject& , Direction dir)
-{
- set_group(COLGROUP_MOVING_STATIC);
- on_ground = false;
- if(dir == UP) {
- physic.set_velocity(0, -500);
- } else if (last_movement.norm() > 1) {
- physic.set_velocity((dir == RIGHT) ? 200 : -200, -200);
- } else {
- physic.set_velocity(0, 0);
- }
- grabbed = false;
-}
-
-IMPLEMENT_FACTORY(Rock, "rock");
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __ROCK_H__
-#define __ROCK_H__
-
-#include "object/moving_sprite.hpp"
-#include "physic.hpp"
-#include "lisp/lisp.hpp"
-#include "portable.hpp"
-#include "serializable.hpp"
-
-class Sprite;
-
-class Rock : public MovingSprite, public Portable, protected UsesPhysic, public Serializable
-{
-public:
- Rock(const Vector& pos, std::string spritename);
- Rock(const lisp::Lisp& reader);
- Rock(const lisp::Lisp& reader, std::string spritename);
- virtual Rock* clone() const { return new Rock(*this); }
-
- void collision_solid(const CollisionHit& hit);
- HitResponse collision(GameObject& other, const CollisionHit& hit);
- void update(float elapsed_time);
- void write(lisp::Writer& writer);
-
- void grab(MovingObject& object, const Vector& pos, Direction dir);
- void ungrab(MovingObject& object, Direction dir);
-
-protected:
- bool on_ground;
- bool grabbed;
- Vector last_movement;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#include <config.h>
-
-#include <stdexcept>
-#include <math.h>
-
-#include "scripted_object.hpp"
-#include "video/drawing_context.hpp"
-#include "scripting/squirrel_util.hpp"
-#include "resources.hpp"
-#include "object_factory.hpp"
-#include "math/vector.hpp"
-
-ScriptedObject::ScriptedObject(const lisp::Lisp& lisp)
- : MovingSprite(lisp, LAYER_OBJECTS, COLGROUP_MOVING_STATIC),
- solid(true), physic_enabled(true), visible(true), new_vel_set(false)
-{
- lisp.get("name", name);
- if(name == "")
- throw std::runtime_error("Scripted object must have a name specified");
-
- // FIXME: do we need this? bbox is already set via .sprite file
- float width = sprite->get_width();
- float height = sprite->get_height();
- lisp.get("width", width);
- lisp.get("height", height);
- bbox.set_size(width, height);
-
- lisp.get("solid", solid);
- lisp.get("physic-enabled", physic_enabled);
- lisp.get("visible", visible);
- lisp.get("z-pos", layer);
- if( solid ){
- set_group( COLGROUP_MOVING_STATIC );
- } else {
- set_group( COLGROUP_DISABLED );
- }
-}
-
-void
-ScriptedObject::expose(HSQUIRRELVM vm, SQInteger table_idx)
-{
- if (name.empty()) return;
- expose_object(vm, table_idx, dynamic_cast<Scripting::ScriptedObject *>(this), name, false);
-}
-
-void
-ScriptedObject::unexpose(HSQUIRRELVM vm, SQInteger table_idx)
-{
- if (name.empty()) return;
- Scripting::unexpose_object(vm, table_idx, name);
-}
-
-void
-ScriptedObject::move(float x, float y)
-{
- bbox.move(Vector(x, y));
-}
-
-void
-ScriptedObject::set_pos(float x, float y)
-{
- printf("SetPos: %f %f\n", x, y);
- bbox.set_pos(Vector(x, y));
- physic.reset();
-}
-
-float
-ScriptedObject::get_pos_x()
-{
- return get_pos().x;
-}
-
-float
-ScriptedObject::get_pos_y()
-{
- return get_pos().y;
-}
-
-void
-ScriptedObject::set_velocity(float x, float y)
-{
- new_vel = Vector(x, y);
- new_vel_set = true;
-}
-
-float
-ScriptedObject::get_velocity_x()
-{
- return physic.get_velocity_x();
-}
-
-float
-ScriptedObject::get_velocity_y()
-{
- return physic.get_velocity_y();
-}
-
-void
-ScriptedObject::set_visible(bool visible)
-{
- this->visible = visible;
-}
-
-bool
-ScriptedObject::is_visible()
-{
- return visible;
-}
-
-void
-ScriptedObject::set_solid(bool solid)
-{
- this->solid = solid;
- if( solid ){
- set_group( COLGROUP_MOVING_STATIC );
- } else {
- set_group( COLGROUP_DISABLED );
- }
-}
-
-bool
-ScriptedObject::is_solid()
-{
- return solid;
-}
-
-
-void
-ScriptedObject::set_action(const std::string& animation)
-{
- sprite->set_action(animation);
-}
-
-std::string
-ScriptedObject::get_action()
-{
- return sprite->get_action();
-}
-
-std::string
-ScriptedObject::get_name()
-{
- return name;
-}
-
-void
-ScriptedObject::update(float elapsed_time)
-{
- if(!physic_enabled)
- return;
-
- if(new_vel_set) {
- physic.set_velocity(new_vel.x, new_vel.y);
- new_vel_set = false;
- }
- movement = physic.get_movement(elapsed_time);
-}
-
-void
-ScriptedObject::draw(DrawingContext& context)
-{
- if(!visible)
- return;
-
- sprite->draw(context, get_pos(), layer);
-}
-
-void
-ScriptedObject::collision_solid(const CollisionHit& hit)
-{
- if(!physic_enabled)
- return;
-
- if(hit.bottom) {
- if(physic.get_velocity_y() > 0)
- physic.set_velocity_y(0);
- } else if(hit.top) {
- physic.set_velocity_y(.1f);
- }
-
- if(hit.left || hit.right) {
- physic.set_velocity_x(0);
- }
-}
-
-HitResponse
-ScriptedObject::collision(GameObject& , const CollisionHit& )
-{
- return FORCE_MOVE;
-}
-
-IMPLEMENT_FACTORY(ScriptedObject, "scriptedobject");
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __SCRIPTED_OBJECT_H__
-#define __SCRIPTED_OBJECT_H__
-
-#include <string>
-#include "physic.hpp"
-#include "lisp/lisp.hpp"
-#include "object/moving_sprite.hpp"
-#include "script_interface.hpp"
-#include "scripting/scripted_object.hpp"
-
-class ScriptedObject : public MovingSprite, public UsesPhysic,
- public Scripting::ScriptedObject, public ScriptInterface
-{
-public:
- ScriptedObject(const lisp::Lisp& lisp);
- virtual ScriptedObject* clone() const { return new ScriptedObject(*this); }
-
- virtual void expose(HSQUIRRELVM vm, SQInteger table_idx);
- virtual void unexpose(HSQUIRRELVM vm, SQInteger table_idx);
-
- void update(float elapsed_time);
- void draw(DrawingContext& context);
-
- void collision_solid(const CollisionHit& hit);
- HitResponse collision(GameObject& other, const CollisionHit& hit);
-
- // --- Scripting Interface stuff ---
-
- void set_action(const std::string& animation);
- std::string get_action();
-
- void move(float x, float y);
- void set_pos(float x, float y);
- float get_pos_x();
- float get_pos_y();
- void set_velocity(float x, float y);
- float get_velocity_x();
- float get_velocity_y();
- void set_visible(bool visible);
- bool is_visible();
- void set_solid(bool solid);
- bool is_solid();
-
- std::string get_name();
-
-private:
- std::string name;
- bool solid;
- bool physic_enabled;
- bool visible;
- bool new_vel_set;
- Vector new_vel;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include "skull_tile.hpp"
-#include "lisp/lisp.hpp"
-#include "object_factory.hpp"
-#include "player.hpp"
-#include "sector.hpp"
-#include "resources.hpp"
-#include "sprite/sprite.hpp"
-#include "random_generator.hpp"
-
-static const float CRACKTIME = 0.3f;
-static const float FALLTIME = 0.8f;
-
-SkullTile::SkullTile(const lisp::Lisp& lisp)
- : MovingSprite(lisp, "images/objects/skull_tile/skull_tile.sprite", LAYER_TILES, COLGROUP_STATIC), hit(false), falling(false)
-{
-}
-
-HitResponse
-SkullTile::collision(GameObject& other, const CollisionHit& )
-{
- Player* player = dynamic_cast<Player*> (&other);
- if(player)
- hit = true;
-
- return FORCE_MOVE;
-}
-
-void
-SkullTile::draw(DrawingContext& context)
-{
- Vector pos = get_pos();
- // shacking
- if(timer.get_timegone() > CRACKTIME) {
- pos.x += systemRandom.rand(-3, 3);
- }
-
- sprite->draw(context, pos, layer);
-}
-
-void
-SkullTile::update(float elapsed_time)
-{
- if(falling) {
- movement = physic.get_movement(elapsed_time);
- if(!Sector::current()->inside(bbox)) {
- remove_me();
- return;
- }
- } else if(hit) {
- if(timer.check()) {
- falling = true;
- physic.enable_gravity(true);
- timer.stop();
- } else if(!timer.started()) {
- timer.start(FALLTIME);
- }
- } else {
- timer.stop();
- }
- hit = false;
-}
-
-IMPLEMENT_FACTORY(SkullTile, "skull_tile");
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __SKULL_TILE_H__
-#define __SKULL_TILE_H__
-
-#include "object/moving_sprite.hpp"
-#include "lisp/lisp.hpp"
-#include "physic.hpp"
-#include "timer.hpp"
-
-class Player;
-
-/** A tile that starts falling down if tux stands to long on it */
-class SkullTile : public MovingSprite, private UsesPhysic
-{
-public:
- SkullTile(const lisp::Lisp& lisp);
- virtual SkullTile* clone() const { return new SkullTile(*this); }
-
- HitResponse collision(GameObject& other, const CollisionHit& hit);
- void update(float elapsed_time);
- void draw(DrawingContext& context);
-
-private:
- Timer timer;
- bool hit;
- bool falling;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include <math.h>
-#include "specialriser.hpp"
-#include "resources.hpp"
-#include "camera.hpp"
-#include "sector.hpp"
-#include "sprite/sprite_manager.hpp"
-
-SpecialRiser::SpecialRiser(Vector pos, MovingObject* _child)
- : child(_child)
-{
- _child->set_pos(pos - Vector(0, 32));
- offset = 0;
-}
-
-SpecialRiser::~SpecialRiser()
-{
-}
-
-void
-SpecialRiser::update(float elapsed_time)
-{
- offset += 50 * elapsed_time;
- if(offset > 32) {
- Sector::current()->add_object(child);
- remove_me();
- }
-}
-
-void
-SpecialRiser::draw(DrawingContext& context)
-{
- context.push_transform();
- context.set_translation(
- context.get_translation() + Vector(0, -32 + offset));
- child->draw(context);
- context.pop_transform();
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __SPECIALRISE_H__
-#define __SPECIALRISE_H__
-
-#include "moving_object.hpp"
-
-/**
- * special object that contains another object and slowly rises it out of a
- * bonus block.
- */
-class SpecialRiser : public GameObject
-{
-public:
- SpecialRiser(Vector pos, MovingObject* child);
- ~SpecialRiser();
-
- virtual void update(float elapsed_time);
- virtual void draw(DrawingContext& context);
-
-private:
- float offset;
- MovingObject* child;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Ingo Ruhnke <grumbel@gmx.de>
-//
-// 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.
-
-#include <config.h>
-
-#include "spotlight.hpp"
-#include "sprite/sprite_manager.hpp"
-#include "resources.hpp"
-#include "video/drawing_context.hpp"
-#include "object_factory.hpp"
-#include "player.hpp"
-#include "sector.hpp"
-
-Spotlight::Spotlight(const lisp::Lisp& lisp)
- : angle(0.0f),
- color(1.0f, 1.0f, 1.0f)
-{
- lisp.get("x", position.x);
- lisp.get("y", position.y);
-
- lisp.get("angle", angle);
-
- std::vector<float> vColor;
- if( lisp.get_vector( "color", vColor ) ){
- color = Color( vColor );
- }
-
- center = sprite_manager->create("images/objects/spotlight/spotlight_center.sprite");
- base = sprite_manager->create("images/objects/spotlight/spotlight_base.sprite");
- lights = sprite_manager->create("images/objects/spotlight/spotlight_lights.sprite");
- lightcone = sprite_manager->create("images/objects/spotlight/lightcone.sprite");
- light = sprite_manager->create("images/objects/spotlight/light.sprite");
-
-
-}
-
-Spotlight::~Spotlight()
-{
- delete center;
- delete base;
- delete lights;
- delete lightcone;
- delete light;
-}
-
-void
-Spotlight::update(float delta)
-{
- angle += delta * 50.0f;
-}
-
-void
-Spotlight::draw(DrawingContext& context)
-{
- context.push_target();
- context.set_target(DrawingContext::LIGHTMAP);
-
- light->set_color(color);
- light->set_blend(Blend(GL_SRC_ALPHA, GL_ONE));
- light->set_angle(angle);
- light->draw(context, position, 0);
-
- //lightcone->set_angle(angle);
- //lightcone->draw(context, position, 0);
-
- context.set_target(DrawingContext::NORMAL);
-
- lights->set_angle(angle);
- lights->draw(context, position, 0);
-
- base->set_angle(angle);
- base->draw(context, position, 0);
-
- center->draw(context, position, 0);
-
- lightcone->set_angle(angle);
- lightcone->draw(context, position, LAYER_FOREGROUND1 + 10);
-
- context.pop_target();
-}
-
-IMPLEMENT_FACTORY(Spotlight, "spotlight");
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __SPOTLIGHT_HPP__
-#define __SPOTLIGHT_HPP__
-
-#include "game_object.hpp"
-#include "math/vector.hpp"
-#include "lisp/lisp.hpp"
-#include "video/color.hpp"
-
-class Sprite;
-
-class Spotlight : public GameObject
-{
-public:
- Spotlight(const lisp::Lisp& reader);
- virtual ~Spotlight();
-
- void update(float elapsed_time);
- void draw(DrawingContext& context);
-
-private:
- Vector position;
- float angle;
- Sprite* center;
- Sprite* base;
- Sprite* lights;
- Sprite* light;
- Sprite* lightcone;
-
- Color color;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
-//
-// 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.
-#include <config.h>
-
-#include <stdexcept>
-#include "sprite_particle.hpp"
-#include "sector.hpp"
-#include "camera.hpp"
-#include "main.hpp"
-#include "log.hpp"
-
-SpriteParticle::SpriteParticle(std::string sprite_name, std::string action, Vector position, AnchorPoint anchor, Vector velocity, Vector acceleration, int drawing_layer)
- : position(position), velocity(velocity), acceleration(acceleration), drawing_layer(drawing_layer)
-{
- sprite = sprite_manager->create(sprite_name);
- if (!sprite) throw std::runtime_error("Could not load sprite "+sprite_name);
- sprite->set_action(action, 1);
- sprite->set_animation_loops(1); //TODO: this is necessary because set_action will not set "loops" when "action" is the default action
-
- this->position -= get_anchor_pos(sprite->get_current_hitbox(), anchor);
-}
-
-SpriteParticle::~SpriteParticle()
-{
- remove_me();
-}
-
-void
-SpriteParticle::hit(Player& )
-{
-}
-
-void
-SpriteParticle::update(float elapsed_time)
-{
- // die when animation is complete
- if (sprite->animation_done()) {
- remove_me();
- return;
- }
-
- // calculate new position and velocity
- position.x += velocity.x * elapsed_time;
- position.y += velocity.y * elapsed_time;
- velocity.x += acceleration.x * elapsed_time;
- velocity.y += acceleration.y * elapsed_time;
-
- // die when too far offscreen
- Vector camera = Sector::current()->camera->get_translation();
- if ((position.x < camera.x - 128) || (position.x > SCREEN_WIDTH + camera.x + 128) ||
- (position.y < camera.y - 128) || (position.y > SCREEN_HEIGHT + camera.y + 128)) {
- remove_me();
- return;
- }
-}
-
-void
-SpriteParticle::draw(DrawingContext& context)
-{
- sprite->draw(context, position, drawing_layer);
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
-//
-// 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.
-
-#ifndef __SPRITE_PARTICLE_H__
-#define __SPRITE_PARTICLE_H__
-
-
-#include "game_object.hpp"
-#include "resources.hpp"
-#include "player.hpp"
-#include "object/anchor_point.hpp"
-#include "sprite/sprite.hpp"
-#include "sprite/sprite_manager.hpp"
-#include "video/drawing_context.hpp"
-
-class SpriteParticle : public GameObject
-{
-public:
- SpriteParticle(std::string sprite_name, std::string action, Vector position, AnchorPoint anchor, Vector velocity, Vector acceleration, int drawing_layer = LAYER_OBJECTS-1);
- ~SpriteParticle();
-protected:
- virtual void hit(Player& player);
- virtual void update(float elapsed_time);
- virtual void draw(DrawingContext& context);
-private:
- Sprite* sprite;
- Vector position;
- Vector velocity;
- Vector acceleration;
- int drawing_layer;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include "star.hpp"
-#include "resources.hpp"
-#include "player.hpp"
-#include "player_status.hpp"
-#include "sprite/sprite_manager.hpp"
-#include "video/drawing_context.hpp"
-
-static const float INITIALJUMP = -400;
-static const float SPEED = 150;
-static const float JUMPSPEED = -300;
-
-Star::Star(const Vector& pos, Direction direction)
- : MovingSprite(pos, "images/powerups/star/star.sprite", LAYER_OBJECTS, COLGROUP_MOVING)
-{
- physic.set_velocity((direction == LEFT) ? -SPEED : SPEED, INITIALJUMP);
-}
-
-void
-Star::update(float elapsed_time)
-{
- movement = physic.get_movement(elapsed_time);
-}
-
-void
-Star::collision_solid(const CollisionHit& hit)
-{
- if(hit.bottom) {
- physic.set_velocity_y(JUMPSPEED);
- } else if(hit.top) {
- physic.set_velocity_y(0);
- } else if(hit.left || hit.right) {
- physic.set_velocity_x(-physic.get_velocity_x());
- }
-}
-
-HitResponse
-Star::collision(GameObject& other, const CollisionHit& )
-{
- Player* player = dynamic_cast<Player*> (&other);
- if(player) {
- player->make_invincible();
- remove_me();
- return ABORT_MOVE;
- }
-
- return FORCE_MOVE;
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __STAR_H__
-#define __STAR_H__
-
-#include "object/moving_sprite.hpp"
-#include "physic.hpp"
-#include "direction.hpp"
-
-class Star : public MovingSprite, private UsesPhysic
-{
-public:
- Star(const Vector& pos, Direction direction = RIGHT);
- virtual Star* clone() const { return new Star(*this); }
-
- virtual void update(float elapsed_time);
- virtual void collision_solid(const CollisionHit& hit);
- virtual HitResponse collision(GameObject& other, const CollisionHit& hit);
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include "text_object.hpp"
-
-#include <iostream>
-#include "resources.hpp"
-#include "main.hpp"
-#include "video/drawing_context.hpp"
-#include "scripting/squirrel_util.hpp"
-#include "log.hpp"
-
-TextObject::TextObject(std::string name)
- : fading(0), fadetime(0), visible(false), anchor(ANCHOR_MIDDLE),
- pos(0, 0)
-{
- this->name = name;
- font = blue_text;
- centered = false;
-}
-
-TextObject::~TextObject()
-{
-}
-
-void
-TextObject::expose(HSQUIRRELVM vm, SQInteger table_idx)
-{
- if (name.empty())
- return;
-
- Scripting::expose_object(vm, table_idx, dynamic_cast<Scripting::Text *>(this), name, false);
-}
-
-void
-TextObject::unexpose(HSQUIRRELVM vm, SQInteger table_idx)
-{
- if (name.empty())
- return;
-
- Scripting::unexpose_object(vm, table_idx, name);
-}
-
-void
-TextObject::set_font(const std::string& name)
-{
- if(name == "gold") {
- font = gold_text;
- } else if(name == "white") {
- font = white_text;
- } else if(name == "blue") {
- font = blue_text;
- } else if(name == "gray") {
- font = gray_text;
- } else if(name == "big") {
- font = white_big_text;
- } else if(name == "small") {
- font = white_small_text;
- } else {
- log_warning << "Unknown font '" << name << "'." << std::endl;
- }
-}
-
-void
-TextObject::set_text(const std::string& text)
-{
- this->text = text;
-}
-
-void
-TextObject::fade_in(float fadetime)
-{
- this->fadetime = fadetime;
- fading = fadetime;
-}
-
-void
-TextObject::fade_out(float fadetime)
-{
- this->fadetime = fadetime;
- fading = -fadetime;
-}
-
-void
-TextObject::set_visible(bool visible)
-{
- this->visible = visible;
- fading = 0;
-}
-
-void
-TextObject::set_centered(bool centered)
-{
- this->centered = centered;
-}
-
-void
-TextObject::draw(DrawingContext& context)
-{
- context.push_transform();
- context.set_translation(Vector(0, 0));
- if(fading > 0) {
- context.set_alpha((fadetime-fading) / fadetime);
- } else if(fading < 0) {
- context.set_alpha(-fading / fadetime);
- } else if(!visible) {
- context.pop_transform();
- return;
- }
-
- float width = 500;
- float height = 70;
- Vector spos = pos + get_anchor_pos(Rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT),
- width, height, anchor);
-
- context.draw_filled_rect(spos, Vector(width, height),
- Color(0.6f, 0.7f, 0.8f, 0.5f), LAYER_GUI-50);
- if (centered) {
- context.draw_center_text(font, text, spos, LAYER_GUI-40);
- } else {
- context.draw_text(font, text, spos + Vector(10, 10), ALIGN_LEFT, LAYER_GUI-40);
- }
-
- context.pop_transform();
-}
-
-void
-TextObject::update(float elapsed_time)
-{
- if(fading > 0) {
- fading -= elapsed_time;
- if(fading <= 0) {
- fading = 0;
- visible = true;
- }
- } else if(fading < 0) {
- fading += elapsed_time;
- if(fading >= 0) {
- fading = 0;
- visible = false;
- }
- }
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __TEXTOBJECT_H__
-#define __TEXTOBJECT_H__
-
-#include "game_object.hpp"
-#include "scripting/text.hpp"
-#include "script_interface.hpp"
-#include "anchor_point.hpp"
-
-class Font;
-
-/** A text object intended for scripts that want to tell a story */
-class TextObject : public GameObject, public Scripting::Text,
- public ScriptInterface
-{
-public:
- TextObject(std::string name = "");
- virtual ~TextObject();
-
- void expose(HSQUIRRELVM vm, SQInteger table_idx);
- void unexpose(HSQUIRRELVM vm, SQInteger table_idx);
-
- void set_text(const std::string& text);
- void set_font(const std::string& name);
- void fade_in(float fadetime);
- void fade_out(float fadetime);
- void set_visible(bool visible);
- void set_centered(bool centered);
- bool is_visible();
-
- void set_anchor_point(AnchorPoint anchor) {
- this->anchor = anchor;
- }
- AnchorPoint get_anchor_point() const {
- return anchor;
- }
-
- void set_pos(const Vector& pos) {
- this->pos = pos;
- }
- void set_pos(float x, float y) {
- set_pos(Vector(x, y));
- }
- const Vector& get_pos() const {
- return pos;
- }
- float get_pos_x() {
- return pos.x;
- }
- float get_pos_y() {
- return pos.y;
- }
-
- void set_anchor_point(int anchor) {
- set_anchor_point((AnchorPoint) anchor);
- }
- int get_anchor_point() {
- return (int) get_anchor_point();
- }
-
- void draw(DrawingContext& context);
- void update(float elapsed_time);
-
-private:
- Font* font;
- std::string text;
- float fading;
- float fadetime;
- bool visible;
- bool centered;
- AnchorPoint anchor;
- Vector pos;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux - Thunderstorm Game Object
-// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
-//
-// 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.
-
-#include <config.h>
-
-#include "thunderstorm.hpp"
-#include "scripting/squirrel_util.hpp"
-#include "audio/sound_manager.hpp"
-#include "video/drawing_context.hpp"
-#include "object_factory.hpp"
-#include "object/electrifier.hpp"
-
-#include <stdexcept>
-#include <iostream>
-#include "main.hpp"
-#include "resources.hpp"
-#include "sector.hpp"
-#include "gettext.hpp"
-#include "object/player.hpp"
-#include "lisp/list_iterator.hpp"
-#include "log.hpp"
-
-namespace {
- const float LIGHTNING_DELAY = 2.0f;
- const float FLASH_DISPLAY_TIME = 0.1f;
-}
-
-Thunderstorm::Thunderstorm(const lisp::Lisp& reader)
- : running(true), interval(10.0f)
-{
- reader.get("name", name);
- reader.get("running", running);
- reader.get("interval", interval);
- if(interval <= 0) {
- log_warning << "Running a thunderstorm with non-positive time interval is a bad idea" << std::endl;
- }
-
- sound_manager->preload("sounds/explosion.wav");
- sound_manager->preload("sounds/upgrade.wav");
-
- if (running) {
- running = false; // else start() is ignored
- start();
- }
-}
-
-void
-Thunderstorm::update(float )
-{
- if (!running) return;
- if (time_to_thunder.check()) {
- thunder();
- time_to_lightning.start(LIGHTNING_DELAY);
- }
- if (time_to_lightning.check()) {
- lightning();
- time_to_thunder.start(interval);
- }
-}
-
-void
-Thunderstorm::draw(DrawingContext& context)
-{
- if (!flash_display_timer.started()) return;
-
- float alpha = 0.33f;
- context.push_transform();
- context.set_translation(Vector(0, 0));
- context.draw_filled_rect(Vector(0, 0), Vector(SCREEN_WIDTH, SCREEN_HEIGHT), Color(1, 1, 1, alpha), LAYER_BACKGROUNDTILES-1);
- context.pop_transform();
-
-}
-
-void
-Thunderstorm::expose(HSQUIRRELVM vm, SQInteger table_idx)
-{
- if (name == "") return;
- Scripting::Thunderstorm* interface = new Scripting::Thunderstorm(this);
- expose_object(vm, table_idx, interface, name, true);
-}
-
-void
-Thunderstorm::unexpose(HSQUIRRELVM vm, SQInteger table_idx)
-{
- if (name == "") return;
- Scripting::unexpose_object(vm, table_idx, name);
-}
-
-void
-Thunderstorm::start()
-{
- if (running) return;
- running = true;
- time_to_thunder.start(interval);
- time_to_lightning.stop();
-}
-
-void
-Thunderstorm::stop()
-{
- if (!running) return;
- running = false;
- time_to_thunder.stop();
- time_to_lightning.stop();
-}
-
-void
-Thunderstorm::thunder()
-{
- sound_manager->play("sounds/explosion.wav");
-}
-
-void
-Thunderstorm::lightning()
-{
- flash();
- electrify();
-}
-
-void
-Thunderstorm::flash()
-{
- sound_manager->play("sounds/upgrade.wav");
- sound_manager->play("sounds/explosion.wav");
- flash_display_timer.start(FLASH_DISPLAY_TIME);
-}
-
-void
-Thunderstorm::electrify()
-{
- Sector::current()->add_object(new Electrifier(75, 1421, 0.5));
- Sector::current()->add_object(new Electrifier(76, 1422, 0.5));
-}
-
-IMPLEMENT_FACTORY(Thunderstorm, "thunderstorm");
+++ /dev/null
-// $Id$
-//
-// SuperTux - Thunderstorm Game Object
-// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
-//
-// 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.
-
-#ifndef __THUNDERSTORM_H__
-#define __THUNDERSTORM_H__
-
-#include "game_object.hpp"
-#include "timer.hpp"
-#include "lisp/lisp.hpp"
-#include "scripting/thunderstorm.hpp"
-#include "script_interface.hpp"
-
-/**
- * Thunderstorm scriptable GameObject; plays thunder, lightning and electrifies water at regular interval
- */
-class Thunderstorm : public GameObject, public ScriptInterface
-{
-public:
- Thunderstorm(const lisp::Lisp& reader);
-
- void update(float elapsed_time);
- void draw(DrawingContext& context);
-
- virtual void expose(HSQUIRRELVM vm, SQInteger table_idx);
- virtual void unexpose(HSQUIRRELVM vm, SQInteger table_idx);
-
- /**
- * @name Scriptable Methods
- * @{
- */
-
- /**
- * Start playing thunder and lightning at configured interval
- */
- void start();
-
- /**
- * Stop playing thunder and lightning at configured interval
- */
- void stop();
-
- /**
- * Play thunder
- */
- void thunder();
-
- /**
- * Play lightning, i.e. call flash() and electrify()
- */
- void lightning();
-
- /**
- * Display a nice flash
- */
- void flash();
-
- /**
- * Electrify water throughout the whole sector for a short time
- */
- void electrify();
-
- /**
- * @}
- */
-
-private:
- bool running; /**< whether we currently automatically trigger lightnings */
- float interval; /**< time between two lightnings */
-
- Timer time_to_thunder; /**< counts down until next thunder */
- Timer time_to_lightning; /**< counts down until next lightning */
- Timer flash_display_timer; /**< counts down while flash is displayed */
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include <cassert>
-#include <algorithm>
-#include <iostream>
-#include <stdexcept>
-#include <math.h>
-
-#include "tilemap.hpp"
-#include "video/drawing_context.hpp"
-#include "level.hpp"
-#include "tile.hpp"
-#include "resources.hpp"
-#include "tile_manager.hpp"
-#include "lisp/lisp.hpp"
-#include "lisp/writer.hpp"
-#include "object_factory.hpp"
-#include "main.hpp"
-#include "log.hpp"
-#include "scripting/tilemap.hpp"
-#include "scripting/squirrel_util.hpp"
-
-TileMap::TileMap()
- : solid(false), speed_x(1), speed_y(1), width(0), height(0), z_pos(0), x_offset(0), y_offset(0),
- drawing_effect(NO_EFFECT), alpha(1.0), current_alpha(1.0), remaining_fade_time(0),
- draw_target(DrawingContext::NORMAL)
-{
- tilemanager = tile_manager;
-}
-
-TileMap::TileMap(const lisp::Lisp& reader, TileManager* new_tile_manager)
- : solid(false), speed_x(1), speed_y(1), width(-1), height(-1), z_pos(0),
- x_offset(0), y_offset(0),
- drawing_effect(NO_EFFECT), alpha(1.0), current_alpha(1.0),
- remaining_fade_time(0),
- draw_target(DrawingContext::NORMAL)
-{
- tilemanager = new_tile_manager;
- if(tilemanager == 0)
- tilemanager = tile_manager;
-
- reader.get("name", name);
- reader.get("z-pos", z_pos);
- reader.get("solid", solid);
- reader.get("speed", speed_x);
- reader.get("speed-y", speed_y);
-
- if(solid && ((speed_x != 1) || (speed_y != 1))) {
- log_warning << "Speed of solid tilemap is not 1. fixing" << std::endl;
- speed_x = 1;
- speed_y = 1;
- }
-
- const lisp::Lisp* pathLisp = reader.get_lisp("path");
- if (pathLisp) {
- path.reset(new Path());
- path->read(*pathLisp);
- walker.reset(new PathWalker(path.get(), /*running*/false));
- Vector v = path->get_base();
- set_x_offset(v.x);
- set_y_offset(v.y);
- }
-
- std::string draw_target_s = "normal";
- reader.get("draw-target", draw_target_s);
- if (draw_target_s == "normal") draw_target = DrawingContext::NORMAL;
- if (draw_target_s == "lightmap") draw_target = DrawingContext::LIGHTMAP;
-
- if (reader.get("alpha", alpha)) {
- current_alpha = alpha;
- }
-
- reader.get("width", width);
- reader.get("height", height);
- if(width < 0 || height < 0)
- throw std::runtime_error("Invalid/No width/height specified in tilemap.");
-
- if(!reader.get_vector("tiles", tiles))
- throw std::runtime_error("No tiles in tilemap.");
-
- if(int(tiles.size()) != width*height) {
- throw std::runtime_error("wrong number of tiles in tilemap.");
- }
-
- // make sure all tiles are loaded
- for(Tiles::iterator i = tiles.begin(); i != tiles.end(); ++i)
- tilemanager->get(*i);
-}
-
-TileMap::TileMap(std::string name, int z_pos, bool solid, size_t width, size_t height)
- : solid(solid), speed_x(1), speed_y(1), width(0), height(0), z_pos(z_pos),
- x_offset(0), y_offset(0), drawing_effect(NO_EFFECT), alpha(1.0),
- current_alpha(1.0), remaining_fade_time(0),
- draw_target(DrawingContext::NORMAL)
-{
- this->name = name;
- tilemanager = tile_manager;
-
- resize(width, height);
-}
-
-TileMap::~TileMap()
-{
-}
-
-void
-TileMap::write(lisp::Writer& writer)
-{
- writer.start_list("tilemap");
-
- writer.write_int("z-pos", z_pos);
-
- writer.write_bool("solid", solid);
- writer.write_float("speed", speed_x);
- writer.write_float("speed-y", speed_y);
- writer.write_int("width", width);
- writer.write_int("height", height);
- writer.write_int_vector("tiles", tiles);
-
- writer.end_list("tilemap");
-}
-
-void
-TileMap::update(float elapsed_time)
-{
- // handle tilemap fading
- if (current_alpha != alpha) {
- remaining_fade_time = std::max(0.0f, remaining_fade_time - elapsed_time);
- if (remaining_fade_time == 0.0f) {
- current_alpha = alpha;
- } else {
- float amt = (alpha - current_alpha) / (remaining_fade_time / elapsed_time);
- if (amt > 0) current_alpha = std::min(current_alpha + amt, alpha);
- if (amt < 0) current_alpha = std::max(current_alpha + amt, alpha);
- }
- if ((alpha < 0.25) && (current_alpha < 0.25)) set_solid(false);
- if ((alpha > 0.75) && (current_alpha > 0.75)) set_solid(true);
- }
-
- // if we have a path to follow, follow it
- if (walker.get()) {
- Vector v = walker->advance(elapsed_time);
- set_x_offset(v.x);
- set_y_offset(v.y);
- }
-}
-
-void
-TileMap::draw(DrawingContext& context)
-{
- // skip draw if current opacity is set to 0.0
- if (current_alpha == 0.0) return;
-
- context.push_transform();
- context.push_target();
- context.set_target(draw_target);
-
- if(drawing_effect != 0) context.set_drawing_effect(drawing_effect);
- if(current_alpha != 1.0) context.set_alpha(current_alpha);
-
- float trans_x = roundf(context.get_translation().x);
- float trans_y = roundf(context.get_translation().y);
- context.set_translation(Vector(trans_x * speed_x, trans_y * speed_y));
-
- /** if we don't round here, we'll have a 1 pixel gap on screen sometimes.
- * I have no idea why */
- float start_x = int((roundf(context.get_translation().x) - roundf(x_offset)) / 32) * 32 + roundf(x_offset);
- float start_y = int((roundf(context.get_translation().y) - roundf(y_offset)) / 32) * 32 + roundf(y_offset);
- float end_x = std::min(start_x + SCREEN_WIDTH + 32, float(width * 32 + roundf(x_offset)));
- float end_y = std::min(start_y + SCREEN_HEIGHT + 32, float(height * 32 + roundf(y_offset)));
- int tsx = int((start_x - roundf(x_offset)) / 32); // tilestartindex x
- int tsy = int((start_y - roundf(y_offset)) / 32); // tilestartindex y
-
- Vector pos;
- int tx, ty;
- for(pos.x = start_x, tx = tsx; pos.x < end_x; pos.x += 32, ++tx) {
- for(pos.y = start_y, ty = tsy; pos.y < end_y; pos.y += 32, ++ty) {
- if ((tx < 0) || (ty < 0)) continue;
- const Tile* tile = tilemanager->get(tiles[ty*width + tx]);
- assert(tile != 0);
- tile->draw(context, pos, z_pos);
- }
- }
-
- context.pop_target();
- context.pop_transform();
-}
-
-void
-TileMap::goto_node(int node_no)
-{
- if (!walker.get()) return;
- walker->goto_node(node_no);
-}
-
-void
-TileMap::start_moving()
-{
- if (!walker.get()) return;
- walker->start_moving();
-}
-
-void
-TileMap::stop_moving()
-{
- if (!walker.get()) return;
- walker->stop_moving();
-}
-
-void
-TileMap::expose(HSQUIRRELVM vm, SQInteger table_idx)
-{
- if (name.empty()) return;
- Scripting::TileMap* interface = new Scripting::TileMap(this);
- expose_object(vm, table_idx, interface, name, true);
-}
-
-void
-TileMap::unexpose(HSQUIRRELVM vm, SQInteger table_idx)
-{
- if (name.empty()) return;
- Scripting::unexpose_object(vm, table_idx, name);
-}
-
-void
-TileMap::set(int newwidth, int newheight, const std::vector<unsigned int>&newt,
- int new_z_pos, bool newsolid)
-{
- if(int(newt.size()) != newwidth * newheight)
- throw std::runtime_error("Wrong tilecount count.");
-
- width = newwidth;
- height = newheight;
-
- tiles.resize(newt.size());
- tiles = newt;
-
- z_pos = new_z_pos;
- solid = newsolid;
-
- // make sure all tiles are loaded
- for(Tiles::iterator i = tiles.begin(); i != tiles.end(); ++i)
- tilemanager->get(*i);
-}
-
-void
-TileMap::resize(int new_width, int new_height, int fill_id)
-{
- if(new_width < width) {
- // remap tiles for new width
- for(int y = 0; y < height && y < new_height; ++y) {
- for(int x = 0; x < new_width; ++x) {
- tiles[y * new_width + x] = tiles[y * width + x];
- }
- }
- }
-
- tiles.resize(new_width * new_height, fill_id);
-
- if(new_width > width) {
- // remap tiles
- for(int y = std::min(height, new_height)-1; y >= 0; --y) {
- for(int x = new_width-1; x >= 0; --x) {
- if(x >= width) {
- tiles[y * new_width + x] = fill_id;
- continue;
- }
-
- tiles[y * new_width + x] = tiles[y * width + x];
- }
- }
- }
-
- height = new_height;
- width = new_width;
-}
-
-void
-TileMap::set_solid(bool solid)
-{
- this->solid = solid;
-}
-
-const Tile*
-TileMap::get_tile(int x, int y) const
-{
- if(x < 0 || x >= width || y < 0 || y >= height) {
- //log_warning << "tile outside tilemap requested" << std::endl;
- return tilemanager->get(0);
- }
-
- return tilemanager->get(tiles[y*width + x]);
-}
-
-const Tile*
-TileMap::get_tile_at(const Vector& pos) const
-{
- return get_tile(int(pos.x - x_offset)/32, int(pos.y - y_offset)/32);
-}
-
-void
-TileMap::change(int x, int y, uint32_t newtile)
-{
- assert(x >= 0 && x < width && y >= 0 && y < height);
- tiles[y*width + x] = newtile;
-}
-
-void
-TileMap::change_at(const Vector& pos, uint32_t newtile)
-{
- change(int(pos.x - x_offset)/32, int(pos.y - y_offset)/32, newtile);
-}
-
-void
-TileMap::change_all(uint32_t oldtile, uint32_t newtile)
-{
- for (size_t x = 0; x < get_width(); x++)
- for (size_t y = 0; y < get_height(); y++) {
- if (get_tile(x,y)->getID() == oldtile) change(x,y,newtile);
- }
-}
-
-void
-TileMap::fade(float alpha, float seconds)
-{
- this->alpha = alpha;
- this->remaining_fade_time = seconds;
-}
-
-
-void
-TileMap::set_alpha(float alpha)
-{
- this->alpha = alpha;
- this->current_alpha = alpha;
- this->remaining_fade_time = 0;
- if (current_alpha < 0.25) set_solid(false);
- if (current_alpha > 0.75) set_solid(true);
-}
-
-float
-TileMap::get_alpha()
-{
- return this->current_alpha;
-}
-
-IMPLEMENT_FACTORY(TileMap, "tilemap");
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef SUPERTUX_TILEMAP_H
-#define SUPERTUX_TILEMAP_H
-
-#include <vector>
-#include <stdint.h>
-#include <string>
-
-#include "game_object.hpp"
-#include "serializable.hpp"
-#include "math/vector.hpp"
-#include "video/drawing_context.hpp"
-#include "object/path.hpp"
-#include "object/path_walker.hpp"
-#include "script_interface.hpp"
-
-namespace lisp {
-class Lisp;
-}
-
-class Level;
-class TileManager;
-class Tile;
-
-/**
- * This class is reponsible for drawing the level tiles
- */
-class TileMap : public GameObject, public Serializable, public ScriptInterface
-{
-public:
- TileMap();
- TileMap(const lisp::Lisp& reader, TileManager* tile_manager = 0);
- TileMap(std::string name, int z_pos, bool solid_, size_t width_, size_t height_);
- virtual ~TileMap();
-
- virtual void write(lisp::Writer& writer);
-
- virtual void update(float elapsed_time);
- virtual void draw(DrawingContext& context);
-
- /** Move tilemap until at given node, then stop */
- void goto_node(int node_no);
-
- /** Start moving tilemap */
- void start_moving();
-
- /** Stop tilemap at next node */
- void stop_moving();
-
- virtual void expose(HSQUIRRELVM vm, SQInteger table_idx);
- virtual void unexpose(HSQUIRRELVM vm, SQInteger table_idx);
-
- void set(int width, int height, const std::vector<unsigned int>& vec,
- int z_pos, bool solid);
-
- /** resizes the tilemap to a new width and height (tries to not destroy the
- * existing map)
- */
- void resize(int newwidth, int newheight, int fill_id = 0);
-
- size_t get_width() const
- { return width; }
-
- size_t get_height() const
- { return height; }
-
- float get_x_offset() const
- { return x_offset; }
-
- float get_y_offset() const
- { return y_offset; }
-
- void set_x_offset(float x_offset)
- { this->x_offset = x_offset; }
-
- void set_y_offset(float y_offset)
- { this->y_offset = y_offset; }
-
- int get_layer() const
- { return z_pos; }
-
- bool is_solid() const
- { return solid; }
-
- /**
- * Changes Tilemap's solidity, i.e. whether to consider it when doing collision detection.
- */
- void set_solid(bool solid = true);
-
- /// returns tile in row y and column y (of the tilemap)
- const Tile* get_tile(int x, int y) const;
- /// returns tile at position pos (in world coordinates)
- const Tile* get_tile_at(const Vector& pos) const;
-
- void change(int x, int y, uint32_t newtile);
-
- void change_at(const Vector& pos, uint32_t newtile);
-
- /// changes all tiles with the given ID
- void change_all(uint32_t oldtile, uint32_t newtile);
-
- TileManager* get_tilemanager() const
- {
- return tilemanager;
- }
-
- void set_drawing_effect(DrawingEffect effect)
- {
- drawing_effect = effect;
- }
-
- DrawingEffect get_drawing_effect()
- {
- return drawing_effect;
- }
-
- /**
- * Start fading the tilemap to opacity given by @c alpha.
- * Destination opacity will be reached after @c seconds seconds. Also influences solidity.
- */
- void fade(float alpha, float seconds = 0);
-
- /**
- * Instantly switch tilemap's opacity to @c alpha. Also influences solidity.
- */
- void set_alpha(float alpha);
-
- /**
- * Return tilemap's opacity. Note that while the tilemap is fading in or out, this will return the current alpha value, not the target alpha.
- */
- float get_alpha();
-
-private:
- typedef std::vector<uint32_t> Tiles;
- Tiles tiles;
-
-private:
- TileManager* tilemanager;
- bool solid;
- float speed_x;
- float speed_y;
- int width, height;
- int z_pos;
- float x_offset;
- float y_offset;
-
- DrawingEffect drawing_effect;
- float alpha; /**< requested tilemap opacity */
- float current_alpha; /**< current tilemap opacity */
- float remaining_fade_time; /**< seconds until requested tilemap opacity is reached */
-
- std::auto_ptr<Path> path;
- std::auto_ptr<PathWalker> walker;
-
- DrawingContext::Target draw_target; /**< set to LIGHTMAP to draw to lightmap */
-};
-
-#endif /*SUPERTUX_TILEMAP_H*/
+++ /dev/null
-// $Id$
-//
-// SuperTux - Trampoline
-// Copyright (C) 2006 Wolfgang Becker <uafr@gmx.de>
-//
-// 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.
-
-#include <config.h>
-
-#include "trampoline.hpp"
-#include "object_factory.hpp"
-#include "player.hpp"
-#include "audio/sound_manager.hpp"
-#include "sprite/sprite_manager.hpp"
-#include "badguy/walking_badguy.hpp"
-
-/* Trampoline will accelerate player to to VY_INITIAL, if
- * he jumps on it to VY_MIN. */
-namespace {
- const std::string TRAMPOLINE_SOUND = "sounds/trampoline.wav";
- const float VY_MIN = -900; //negative, upwards
- const float VY_INITIAL = -500;
-}
-
-Trampoline::Trampoline(const lisp::Lisp& lisp)
- : Rock(lisp, "images/objects/trampoline/trampoline.sprite")
-{
- sound_manager->preload(TRAMPOLINE_SOUND);
-
- portable = true;
- //Check if this trampoline is not portable
- if(lisp.get("portable", portable)) {
- if(!portable) {
- //we need another sprite
- sprite_name = "images/objects/trampoline/trampoline_fix.sprite";
- sprite = sprite_manager->create(sprite_name);
- sprite->set_action("normal");
- }
- }
-}
-
-void
-Trampoline::update(float elapsed_time)
-{
- if(sprite->animation_done()) {
- sprite->set_action("normal");
- }
-
- Rock::update(elapsed_time);
-}
-
-HitResponse
-Trampoline::collision(GameObject& other, const CollisionHit& hit)
-{
-
- //Tramponine has to be on ground to work.
- if(on_ground) {
- Player* player = dynamic_cast<Player*> (&other);
- //Trampoline works for player
- if(player) {
- float vy = player->physic.get_velocity_y();
- //player is falling down on trampoline
- if(hit.top && vy >= 0) {
- if(player->get_controller()->hold(Controller::JUMP)) {
- vy = VY_MIN;
- } else {
- vy = VY_INITIAL;
- }
- player->physic.set_velocity_y(vy);
- sound_manager->play(TRAMPOLINE_SOUND);
- sprite->set_action("swinging", 1);
- return FORCE_MOVE;
- }
- }
- WalkingBadguy* walking_badguy = dynamic_cast<WalkingBadguy*> (&other);
- //Trampoline also works for WalkingBadguy
- if(walking_badguy) {
- float vy = walking_badguy->get_velocity_y();
- //walking_badguy is falling down on trampoline
- if(hit.top && vy >= 0) {
- vy = VY_INITIAL;
- walking_badguy->set_velocity_y(vy);
- sound_manager->play(TRAMPOLINE_SOUND);
- sprite->set_action("swinging", 1);
- return FORCE_MOVE;
- }
- }
- }
-
- return Rock::collision(other, hit);
-}
-
-void
-Trampoline::collision_solid(const CollisionHit& hit) {
- Rock::collision_solid(hit);
-}
-
-void
-Trampoline::grab(MovingObject& object, const Vector& pos, Direction dir) {
- sprite->set_animation_loops(0);
- Rock::grab(object, pos, dir);
-}
-
-void
-Trampoline::ungrab(MovingObject& object, Direction dir) {
- Rock::ungrab(object, dir);
-}
-
-bool
-Trampoline::is_portable() const
-{
- return Rock::is_portable() && portable;
-}
-
-IMPLEMENT_FACTORY(Trampoline, "trampoline");
+++ /dev/null
-// $Id$
-//
-// SuperTux - Trampolin
-// Copyright (C) 2006 Wolfgang Becker <uafr@gmx.de>
-//
-// 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.
-
-#ifndef SUPERTUX_TRAMPOLINE_H
-#define SUPERTUX_TRAMPOLINE_H
-
-#include "moving_sprite.hpp"
-#include "lisp/lisp.hpp"
-#include "object/rock.hpp"
-
-/**
- * Jumping on a trampolin makes tux jump higher.
- */
-class Trampoline : public Rock
-{
-public:
- Trampoline(const lisp::Lisp& reader);
-
- HitResponse collision(GameObject& other, const CollisionHit& hit);
- void collision_solid(const CollisionHit& hit);
- void update(float elapsed_time);
-
- void grab(MovingObject&, const Vector& pos, Direction);
- void ungrab(MovingObject&, Direction);
- bool is_portable() const;
-
-private:
- bool portable;
-
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux - Unstable Tile
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
-//
-// 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.
-
-#include <config.h>
-
-#include "unstable_tile.hpp"
-#include "lisp/lisp.hpp"
-#include "object_factory.hpp"
-#include "player.hpp"
-#include "sector.hpp"
-#include "resources.hpp"
-#include "sprite/sprite.hpp"
-#include "random_generator.hpp"
-#include "object/bullet.hpp"
-
-UnstableTile::UnstableTile(const lisp::Lisp& lisp)
- : MovingSprite(lisp, LAYER_TILES, COLGROUP_STATIC), state(STATE_NORMAL)
-{
- sprite->set_action("normal");
-}
-
-HitResponse
-UnstableTile::collision(GameObject& other, const CollisionHit& )
-{
- if(state == STATE_NORMAL) {
- Player* player = dynamic_cast<Player*> (&other);
- if(player != NULL &&
- player->get_bbox().get_bottom() < get_bbox().get_top() + 7.0) {
- state = STATE_CRUMBLING;
- sprite->set_action("crumbling", 1);
- }
- }
- return SOLID;
-}
-
-void
-UnstableTile::update(float elapsed_time)
-{
- switch (state) {
-
- case STATE_NORMAL:
- break;
-
- case STATE_CRUMBLING:
- if (sprite->animation_done()) {
- state = STATE_DISINTEGRATING;
- sprite->set_action("disintegrating", 1);
- set_group(COLGROUP_DISABLED);
- physic.enable_gravity(true);
- }
- break;
-
- case STATE_DISINTEGRATING:
- movement = physic.get_movement(elapsed_time);
- if (sprite->animation_done()) {
- remove_me();
- return;
- }
- break;
- }
-}
-
-IMPLEMENT_FACTORY(UnstableTile, "unstable_tile");
+++ /dev/null
-// $Id$
-//
-// SuperTux - Unstable Tile
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
-//
-// 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.
-
-#ifndef __UNSTABLE_TILE_H__
-#define __UNSTABLE_TILE_H__
-
-#include "object/moving_sprite.hpp"
-#include "lisp/lisp.hpp"
-#include "physic.hpp"
-#include "timer.hpp"
-
-/**
- * A block that disintegrates when stood on
- */
-class UnstableTile : public MovingSprite, public UsesPhysic
-{
-public:
- UnstableTile(const lisp::Lisp& lisp);
- virtual UnstableTile* clone() const { return new UnstableTile(*this); }
-
- HitResponse collision(GameObject& other, const CollisionHit& hit);
- void update(float elapsed_time);
-
-private:
- enum State {
- STATE_NORMAL, /**< default state */
- STATE_CRUMBLING, /**< crumbling, still solid */
- STATE_DISINTEGRATING /**< disintegrating, no longer solid */
- };
- State state;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux - Weak Block
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
-//
-// 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.
-
-#include <config.h>
-
-#include "weak_block.hpp"
-#include "lisp/lisp.hpp"
-#include "object_factory.hpp"
-#include "player.hpp"
-#include "sector.hpp"
-#include "resources.hpp"
-#include "sprite/sprite.hpp"
-#include "random_generator.hpp"
-#include "object/bullet.hpp"
-
-WeakBlock::WeakBlock(const lisp::Lisp& lisp)
- : MovingSprite(lisp, "images/objects/strawbox/strawbox.sprite", LAYER_TILES, COLGROUP_STATIC), state(STATE_NORMAL)
-{
- sprite->set_action("normal");
-}
-
-HitResponse
-WeakBlock::collision(GameObject& other, const CollisionHit& )
-{
- switch (state) {
-
- case STATE_NORMAL:
- if (dynamic_cast<Bullet*>(&other)) {
- startBurning();
- return FORCE_MOVE;
- }
- return FORCE_MOVE;
- break;
-
- case STATE_BURNING:
- return FORCE_MOVE;
- break;
-
- case STATE_DISINTEGRATING:
- return FORCE_MOVE;
- break;
-
- }
-
- log_debug << "unhandled state" << std::endl;
- return FORCE_MOVE;
-}
-
-void
-WeakBlock::update(float )
-{
- switch (state) {
-
- case STATE_NORMAL:
- break;
-
- case STATE_BURNING:
- if (sprite->animation_done()) {
- state = STATE_DISINTEGRATING;
- sprite->set_action("disintegrating", 1);
- spreadHit();
- set_group(COLGROUP_DISABLED);
- }
- break;
-
- case STATE_DISINTEGRATING:
- if (sprite->animation_done()) {
- remove_me();
- return;
- }
- break;
-
- }
-}
-
-void
-WeakBlock::startBurning()
-{
- if (state != STATE_NORMAL) return;
- state = STATE_BURNING;
- sprite->set_action("burning", 1);
-}
-
-void
-WeakBlock::spreadHit()
-{
- Sector* sector = Sector::current();
- if (!sector) {
- log_debug << "no current sector" << std::endl;
- return;
- }
- for(Sector::GameObjects::iterator i = sector->gameobjects.begin(); i != sector->gameobjects.end(); ++i) {
- WeakBlock* wb = dynamic_cast<WeakBlock*>(*i);
- if (!wb) continue;
- if (wb == this) continue;
- if (wb->state != STATE_NORMAL) continue;
- float dx = fabsf(wb->get_pos().x - this->get_pos().x);
- float dy = fabsf(wb->get_pos().y - this->get_pos().y);
- if ((dx <= 32.5) && (dy <= 32.5)) wb->startBurning();
- }
-}
-
-
-IMPLEMENT_FACTORY(WeakBlock, "weak_block");
+++ /dev/null
-// $Id$
-//
-// SuperTux - Weak Block
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
-//
-// 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.
-
-#ifndef __WEAK_BLOCK_H__
-#define __WEAK_BLOCK_H__
-
-#include "object/moving_sprite.hpp"
-#include "lisp/lisp.hpp"
-#include "physic.hpp"
-#include "timer.hpp"
-
-/**
- * A block that can be destroyed by Bullet hits
- */
-class WeakBlock : public MovingSprite, public UsesPhysic
-{
-public:
- WeakBlock(const lisp::Lisp& lisp);
-
- HitResponse collision(GameObject& other, const CollisionHit& hit);
- void update(float elapsed_time);
-
-protected:
- /**
- * called by self when hit by a bullet
- */
- void startBurning();
-
- /**
- * pass hit to nearby WeakBlock objects
- */
- void spreadHit();
-
-private:
- enum State {
- STATE_NORMAL, /**< default state */
- STATE_BURNING, /**< on fire, still solid */
- STATE_DISINTEGRATING /**< crumbling to dust, no longer solid */
- };
- State state;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux - Wind
-// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
-//
-// 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.
-
-#include <config.h>
-
-#include "wind.hpp"
-#include "video/drawing_context.hpp"
-#include "object/player.hpp"
-#include "object_factory.hpp"
-#include "random_generator.hpp"
-#include "sector.hpp"
-#include "particles.hpp"
-#include "scripting/wind.hpp"
-#include "scripting/squirrel_util.hpp"
-
-Wind::Wind(const lisp::Lisp& reader)
- : blowing(true), acceleration(100), elapsed_time(0)
-{
- reader.get("name", name);
- reader.get("x", bbox.p1.x);
- reader.get("y", bbox.p1.y);
- float w = 32, h = 32;
- reader.get("width", w);
- reader.get("height", h);
- bbox.set_size(w, h);
-
- reader.get("blowing", blowing);
-
- float speed_x = 0, speed_y = 0;
- reader.get("speed-x", speed_x);
- reader.get("speed-y", speed_y);
- speed = Vector(speed_x, speed_y);
-
- reader.get("acceleration", acceleration);
-
- set_group(COLGROUP_TOUCHABLE);
-}
-
-void
-Wind::update(float elapsed_time)
-{
- this->elapsed_time = elapsed_time;
-
- if (!blowing) return;
-
- // TODO: nicer, configurable particles for wind?
- if (systemRandom.rand(0, 100) < 20) {
- // emit a particle
- Vector ppos = Vector(systemRandom.randf(bbox.p1.x+8, bbox.p2.x-8), systemRandom.randf(bbox.p1.y+8, bbox.p2.y-8));
- Vector pspeed = Vector(speed.x, speed.y);
- Sector::current()->add_object(new Particles(ppos, 44, 46, pspeed, Vector(0,0), 1, Color(.4f, .4f, .4f), 3, .1f, LAYER_BACKGROUNDTILES+1));
- }
-}
-
-void
-Wind::draw(DrawingContext& )
-{
-}
-
-HitResponse
-Wind::collision(GameObject& other, const CollisionHit& )
-{
- if (!blowing) return ABORT_MOVE;
-
- Player* player = dynamic_cast<Player*> (&other);
- if (player) {
- if (!player->on_ground()) {
- player->add_velocity(speed * acceleration * elapsed_time, speed);
- }
- }
-
- return ABORT_MOVE;
-}
-
-void
-Wind::expose(HSQUIRRELVM vm, SQInteger table_idx)
-{
- if (name == "")
- return;
-
- Scripting::Wind* interface = new Scripting::Wind(this);
- expose_object(vm, table_idx, interface, name, true);
-}
-
-void
-Wind::unexpose(HSQUIRRELVM vm, SQInteger table_idx)
-{
- if (name == "")
- return;
-
- Scripting::unexpose_object(vm, table_idx, name);
-}
-
-void
-Wind::start()
-{
- blowing = true;
-}
-
-void
-Wind::stop()
-{
- blowing = false;
-}
-
-IMPLEMENT_FACTORY(Wind, "wind");
+++ /dev/null
-// $Id$
-//
-// SuperTux - Wind
-// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
-//
-// 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.
-
-#ifndef SUPERTUX_WIND_H
-#define SUPERTUX_WIND_H
-
-#include <set>
-#include "moving_object.hpp"
-#include "math/rect.hpp"
-#include "sprite/sprite.hpp"
-#include "script_interface.hpp"
-
-class Player;
-
-/**
- * Defines an area that will gently push Players in one direction
- */
-class Wind : public MovingObject, public ScriptInterface
-{
-public:
- Wind(const lisp::Lisp& reader);
-
- void update(float elapsed_time);
- void draw(DrawingContext& context);
- HitResponse collision(GameObject& other, const CollisionHit& hit);
-
- /**
- * @name Scriptable Methods
- * @{
- */
-
- /**
- * start blowing
- */
- void start();
-
- /**
- * stop blowing
- */
- void stop();
-
- /**
- * @}
- */
-
- virtual void expose(HSQUIRRELVM vm, SQInteger table_idx);
- virtual void unexpose(HSQUIRRELVM vm, SQInteger table_idx);
-
-private:
- bool blowing; /**< true if wind is currently switched on */
- Vector speed;
- float acceleration;
-
- float elapsed_time; /**< stores last elapsed_time gotten at update() */
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2004 Ricardo Cruz <rick2@aeiou.pt>
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#include <config.h>
-
-#include <sstream>
-#include <stdexcept>
-
-#include "lisp/lisp.hpp"
-#include "lisp/parser.hpp"
-#include "object_factory.hpp"
-#include "math/vector.hpp"
-
-GameObject* create_object(const std::string& name, const lisp::Lisp& reader)
-{
- Factory::Factories::iterator i = Factory::get_factories().find(name);
- if(i == Factory::get_factories().end()) {
- std::stringstream msg;
- msg << "No factory for object '" << name << "' found.";
- throw std::runtime_error(msg.str());
- }
-
- return i->second->create_object(reader);
-}
-
-GameObject* create_object(const std::string& name, const Vector& pos)
-{
- std::stringstream lisptext;
- lisptext << "(" << name
- << " (x " << pos.x << ")"
- << " (y " << pos.y << "))";
-
- lisp::Parser parser;
- const lisp::Lisp* lisp = parser.parse(lisptext, "create_object");
- GameObject* object = create_object(name, *lisp);
-
- return object;
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2004 Ricardo Cruz <rick2@aeiou.pt>
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#ifndef OBJECT_FACTORY_H
-#define OBJECT_FACTORY_H
-
-#include <string>
-#include <map>
-
-namespace lisp { class Lisp; }
-class Vector;
-class GameObject;
-
-class Factory
-{
-public:
- virtual ~Factory()
- { }
-
- /** Creates a new gameobject from a lisp node.
- * Remember to delete the objects later
- */
- virtual GameObject* create_object(const lisp::Lisp& reader) = 0;
-
- typedef std::map<std::string, Factory*> Factories;
- static Factories &get_factories()
- {
- static Factories object_factories;
- return object_factories;
- }
-};
-
-GameObject* create_object(const std::string& name, const lisp::Lisp& reader);
-GameObject* create_object(const std::string& name, const Vector& pos);
-
-/** comment from Matze:
- * Yes I know macros are evil, but in this specific case they save
- * A LOT of typing and evil code duplication.
- * I'll happily accept alternatives if someone can present me one that does
- * not involve typing 4 or more lines for each object class
- */
-#define IMPLEMENT_FACTORY(CLASS, NAME) \
-class INTERN_##CLASS##Factory : public Factory \
-{ \
-public: \
- INTERN_##CLASS##Factory() \
- { \
- get_factories()[NAME] = this; \
- } \
- \
- ~INTERN_##CLASS##Factory() \
- { \
- get_factories().erase(NAME); \
- } \
- \
- virtual GameObject* create_object(const lisp::Lisp& reader) \
- { \
- return new CLASS(reader); \
- } \
-}; \
-static INTERN_##CLASS##Factory factory_##CLASS;
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __OBJECT_REMOVE_LISTENER_H__
-#define __OBJECT_REMOVE_LISTENER_H__
-
-class GameObject;
-
-class ObjectRemoveListener
-{
-public:
- virtual ~ObjectRemoveListener()
- {}
-
- virtual void object_removed(GameObject* object) = 0;
-};
-
-#endif
+++ /dev/null
-/* obstack.c - subroutines used implicitly by object stack macros
- Copyright (C) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1996, 1997, 1998,
- 1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
- This file is part of the GNU C Library.
-
- The GNU C Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- The GNU C Library 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
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with the GNU C Library; if not, write to the Free
- Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- Boston, MA 02110-1301, USA. */
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-
-#include "obstack.h"
-
-/* NOTE BEFORE MODIFYING THIS FILE: This version number must be
- incremented whenever callers compiled using an old obstack.h can no
- longer properly call the functions in this obstack.c. */
-#define OBSTACK_INTERFACE_VERSION 1
-
-#include <stdio.h> /* Random thing to get __GNU_LIBRARY__. */
-#include <stddef.h>
-#include <stdint.h>
-
-/* Determine default alignment. */
-union fooround
-{
- uintmax_t i;
- long double d;
- void *p;
-};
-struct fooalign
-{
- char c;
- union fooround u;
-};
-/* If malloc were really smart, it would round addresses to DEFAULT_ALIGNMENT.
- But in fact it might be less smart and round addresses to as much as
- DEFAULT_ROUNDING. So we prepare for it to do that. */
-enum
- {
- DEFAULT_ALIGNMENT = offsetof (struct fooalign, u),
- DEFAULT_ROUNDING = sizeof (union fooround)
- };
-
-/* When we copy a long block of data, this is the unit to do it with.
- On some machines, copying successive ints does not work;
- in such a case, redefine COPYING_UNIT to `long' (if that works)
- or `char' as a last resort. */
-# ifndef COPYING_UNIT
-# define COPYING_UNIT int
-# endif
-
-
-/* The functions allocating more room by calling `obstack_chunk_alloc'
- jump to the handler pointed to by `obstack_alloc_failed_handler'.
- This can be set to a user defined function which should either
- abort gracefully or use longjump - but shouldn't return. This
- variable by default points to the internal function
- `print_and_abort'. */
-static void print_and_abort (void);
-void (*obstack_alloc_failed_handler) (void) = print_and_abort;
-
-/* Exit value used when `print_and_abort' is used. */
-# include <stdlib.h>
-int obstack_exit_failure = EXIT_FAILURE;
-
-/* Define a macro that either calls functions with the traditional malloc/free
- calling interface, or calls functions with the mmalloc/mfree interface
- (that adds an extra first argument), based on the state of use_extra_arg.
- For free, do not use ?:, since some compilers, like the MIPS compilers,
- do not allow (expr) ? void : void. */
-
-# define CALL_CHUNKFUN(h, size) \
- (((h) -> use_extra_arg) \
- ? (*(h)->chunkfun) ((h)->extra_arg, (size)) \
- : (*(struct _obstack_chunk *(*) (long)) (h)->chunkfun) ((size)))
-
-# define CALL_FREEFUN(h, old_chunk) \
- do { \
- if ((h) -> use_extra_arg) \
- (*(h)->freefun) ((h)->extra_arg, (old_chunk)); \
- else \
- (*(void (*) (void *)) (h)->freefun) ((old_chunk)); \
- } while (0)
-
-\f
-/* Initialize an obstack H for use. Specify chunk size SIZE (0 means default).
- Objects start on multiples of ALIGNMENT (0 means use default).
- CHUNKFUN is the function to use to allocate chunks,
- and FREEFUN the function to free them.
-
- Return nonzero if successful, calls obstack_alloc_failed_handler if
- allocation fails. */
-
-int
-_obstack_begin (struct obstack *h,
- int size, int alignment,
- void *(*chunkfun) (long),
- void (*freefun) (void *))
-{
- register struct _obstack_chunk *chunk; /* points to new chunk */
-
- if (alignment == 0)
- alignment = DEFAULT_ALIGNMENT;
- if (size == 0)
- /* Default size is what GNU malloc can fit in a 4096-byte block. */
- {
- /* 12 is sizeof (mhead) and 4 is EXTRA from GNU malloc.
- Use the values for range checking, because if range checking is off,
- the extra bytes won't be missed terribly, but if range checking is on
- and we used a larger request, a whole extra 4096 bytes would be
- allocated.
-
- These number are irrelevant to the new GNU malloc. I suspect it is
- less sensitive to the size of the request. */
- int extra = ((((12 + DEFAULT_ROUNDING - 1) & ~(DEFAULT_ROUNDING - 1))
- + 4 + DEFAULT_ROUNDING - 1)
- & ~(DEFAULT_ROUNDING - 1));
- size = 4096 - extra;
- }
-
- h->chunkfun = (struct _obstack_chunk * (*)(void *, long)) chunkfun;
- h->freefun = (void (*) (void *, struct _obstack_chunk *)) freefun;
- h->chunk_size = size;
- h->alignment_mask = alignment - 1;
- h->use_extra_arg = 0;
-
- chunk = h->chunk = CALL_CHUNKFUN (h, h -> chunk_size);
- if (!chunk)
- (*obstack_alloc_failed_handler) ();
- h->next_free = h->object_base = __PTR_ALIGN ((char *) chunk, chunk->contents,
- alignment - 1);
- h->chunk_limit = chunk->limit
- = (char *) chunk + h->chunk_size;
- chunk->prev = 0;
- /* The initial chunk now contains no empty object. */
- h->maybe_empty_object = 0;
- h->alloc_failed = 0;
- return 1;
-}
-
-int
-_obstack_begin_1 (struct obstack *h, int size, int alignment,
- void *(*chunkfun) (void *, long),
- void (*freefun) (void *, void *),
- void *arg)
-{
- register struct _obstack_chunk *chunk; /* points to new chunk */
-
- if (alignment == 0)
- alignment = DEFAULT_ALIGNMENT;
- if (size == 0)
- /* Default size is what GNU malloc can fit in a 4096-byte block. */
- {
- /* 12 is sizeof (mhead) and 4 is EXTRA from GNU malloc.
- Use the values for range checking, because if range checking is off,
- the extra bytes won't be missed terribly, but if range checking is on
- and we used a larger request, a whole extra 4096 bytes would be
- allocated.
-
- These number are irrelevant to the new GNU malloc. I suspect it is
- less sensitive to the size of the request. */
- int extra = ((((12 + DEFAULT_ROUNDING - 1) & ~(DEFAULT_ROUNDING - 1))
- + 4 + DEFAULT_ROUNDING - 1)
- & ~(DEFAULT_ROUNDING - 1));
- size = 4096 - extra;
- }
-
- h->chunkfun = (struct _obstack_chunk * (*)(void *,long)) chunkfun;
- h->freefun = (void (*) (void *, struct _obstack_chunk *)) freefun;
- h->chunk_size = size;
- h->alignment_mask = alignment - 1;
- h->extra_arg = arg;
- h->use_extra_arg = 1;
-
- chunk = h->chunk = CALL_CHUNKFUN (h, h -> chunk_size);
- if (!chunk)
- (*obstack_alloc_failed_handler) ();
- h->next_free = h->object_base = __PTR_ALIGN ((char *) chunk, chunk->contents,
- alignment - 1);
- h->chunk_limit = chunk->limit
- = (char *) chunk + h->chunk_size;
- chunk->prev = 0;
- /* The initial chunk now contains no empty object. */
- h->maybe_empty_object = 0;
- h->alloc_failed = 0;
- return 1;
-}
-
-/* Allocate a new current chunk for the obstack *H
- on the assumption that LENGTH bytes need to be added
- to the current object, or a new object of length LENGTH allocated.
- Copies any partial object from the end of the old chunk
- to the beginning of the new one. */
-
-void
-_obstack_newchunk (struct obstack *h, int length)
-{
- register struct _obstack_chunk *old_chunk = h->chunk;
- register struct _obstack_chunk *new_chunk;
- register long new_size;
- register long obj_size = h->next_free - h->object_base;
- register long i;
- long already;
- char *object_base;
-
- /* Compute size for new chunk. */
- new_size = (obj_size + length) + (obj_size >> 3) + h->alignment_mask + 100;
- if (new_size < h->chunk_size)
- new_size = h->chunk_size;
-
- /* Allocate and initialize the new chunk. */
- new_chunk = CALL_CHUNKFUN (h, new_size);
- if (!new_chunk)
- (*obstack_alloc_failed_handler) ();
- h->chunk = new_chunk;
- new_chunk->prev = old_chunk;
- new_chunk->limit = h->chunk_limit = (char *) new_chunk + new_size;
-
- /* Compute an aligned object_base in the new chunk */
- object_base =
- __PTR_ALIGN ((char *) new_chunk, new_chunk->contents, h->alignment_mask);
-
- /* Move the existing object to the new chunk.
- Word at a time is fast and is safe if the object
- is sufficiently aligned. */
- if (h->alignment_mask + 1 >= DEFAULT_ALIGNMENT)
- {
- for (i = obj_size / sizeof (COPYING_UNIT) - 1;
- i >= 0; i--)
- ((COPYING_UNIT *)object_base)[i]
- = ((COPYING_UNIT *)h->object_base)[i];
- /* We used to copy the odd few remaining bytes as one extra COPYING_UNIT,
- but that can cross a page boundary on a machine
- which does not do strict alignment for COPYING_UNITS. */
- already = obj_size / sizeof (COPYING_UNIT) * sizeof (COPYING_UNIT);
- }
- else
- already = 0;
- /* Copy remaining bytes one by one. */
- for (i = already; i < obj_size; i++)
- object_base[i] = h->object_base[i];
-
- /* If the object just copied was the only data in OLD_CHUNK,
- free that chunk and remove it from the chain.
- But not if that chunk might contain an empty object. */
- if (! h->maybe_empty_object
- && (h->object_base
- == __PTR_ALIGN ((char *) old_chunk, old_chunk->contents,
- h->alignment_mask)))
- {
- new_chunk->prev = old_chunk->prev;
- CALL_FREEFUN (h, old_chunk);
- }
-
- h->object_base = object_base;
- h->next_free = h->object_base + obj_size;
- /* The new chunk certainly contains no empty object yet. */
- h->maybe_empty_object = 0;
-}
-
-/* Return nonzero if object OBJ has been allocated from obstack H.
- This is here for debugging.
- If you use it in a program, you are probably losing. */
-
-/* Suppress -Wmissing-prototypes warning. We don't want to declare this in
- obstack.h because it is just for debugging. */
-int _obstack_allocated_p (struct obstack *h, void *obj);
-
-int
-_obstack_allocated_p (struct obstack *h, void *obj)
-{
- register struct _obstack_chunk *lp; /* below addr of any objects in this chunk */
- register struct _obstack_chunk *plp; /* point to previous chunk if any */
-
- lp = (h)->chunk;
- /* We use >= rather than > since the object cannot be exactly at
- the beginning of the chunk but might be an empty object exactly
- at the end of an adjacent chunk. */
- while (lp != 0 && ((void *) lp >= obj || (void *) (lp)->limit < obj))
- {
- plp = lp->prev;
- lp = plp;
- }
- return lp != 0;
-}
-\f
-/* Free objects in obstack H, including OBJ and everything allocate
- more recently than OBJ. If OBJ is zero, free everything in H. */
-
-# undef obstack_free
-
-void
-obstack_free (struct obstack *h, void *obj)
-{
- register struct _obstack_chunk *lp; /* below addr of any objects in this chunk */
- register struct _obstack_chunk *plp; /* point to previous chunk if any */
-
- lp = h->chunk;
- /* We use >= because there cannot be an object at the beginning of a chunk.
- But there can be an empty object at that address
- at the end of another chunk. */
- while (lp != 0 && ((void *) lp >= obj || (void *) (lp)->limit < obj))
- {
- plp = lp->prev;
- CALL_FREEFUN (h, lp);
- lp = plp;
- /* If we switch chunks, we can't tell whether the new current
- chunk contains an empty object, so assume that it may. */
- h->maybe_empty_object = 1;
- }
- if (lp)
- {
- h->object_base = h->next_free = (char *) (obj);
- h->chunk_limit = lp->limit;
- h->chunk = lp;
- }
- else if (obj != 0)
- /* obj is not in any of the chunks! */
- abort ();
-}
-
-int
-_obstack_memory_used (struct obstack *h)
-{
- register struct _obstack_chunk* lp;
- register int nbytes = 0;
-
- for (lp = h->chunk; lp != 0; lp = lp->prev)
- {
- nbytes += lp->limit - (char *) lp;
- }
- return nbytes;
-}
-
-static void
-__attribute__ ((noreturn))
-print_and_abort (void)
-{
- /* Don't change any of these strings. Yes, it would be possible to add
- the newline to the string and use fputs or so. But this must not
- happen because the "memory exhausted" message appears in other places
- like this and the translation should be reused instead of creating
- a very similar string which requires a separate translation. */
- fprintf (stderr, "%s\n", "memory exhausted");
- exit (obstack_exit_failure);
-}
-
+++ /dev/null
-/* obstack.h - object stack macros
- Copyright (C) 1988-1994,1996-1999,2003,2004,2005
- Free Software Foundation, Inc.
- This file is part of the GNU C Library.
-
- The GNU C Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- The GNU C Library 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
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with the GNU C Library; if not, write to the Free
- Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- Boston, MA 02110-1301, USA. */
-
-/* Summary:
-
-All the apparent functions defined here are macros. The idea
-is that you would use these pre-tested macros to solve a
-very specific set of problems, and they would run fast.
-Caution: no side-effects in arguments please!! They may be
-evaluated MANY times!!
-
-These macros operate a stack of objects. Each object starts life
-small, and may grow to maturity. (Consider building a word syllable
-by syllable.) An object can move while it is growing. Once it has
-been "finished" it never changes address again. So the "top of the
-stack" is typically an immature growing object, while the rest of the
-stack is of mature, fixed size and fixed address objects.
-
-These routines grab large chunks of memory, using a function you
-supply, called `obstack_chunk_alloc'. On occasion, they free chunks,
-by calling `obstack_chunk_free'. You must define them and declare
-them before using any obstack macros.
-
-Each independent stack is represented by a `struct obstack'.
-Each of the obstack macros expects a pointer to such a structure
-as the first argument.
-
-One motivation for this package is the problem of growing char strings
-in symbol tables. Unless you are "fascist pig with a read-only mind"
---Gosper's immortal quote from HAKMEM item 154, out of context--you
-would not like to put any arbitrary upper limit on the length of your
-symbols.
-
-In practice this often means you will build many short symbols and a
-few long symbols. At the time you are reading a symbol you don't know
-how long it is. One traditional method is to read a symbol into a
-buffer, realloc()ating the buffer every time you try to read a symbol
-that is longer than the buffer. This is beaut, but you still will
-want to copy the symbol from the buffer to a more permanent
-symbol-table entry say about half the time.
-
-With obstacks, you can work differently. Use one obstack for all symbol
-names. As you read a symbol, grow the name in the obstack gradually.
-When the name is complete, finalize it. Then, if the symbol exists already,
-free the newly read name.
-
-The way we do this is to take a large chunk, allocating memory from
-low addresses. When you want to build a symbol in the chunk you just
-add chars above the current "high water mark" in the chunk. When you
-have finished adding chars, because you got to the end of the symbol,
-you know how long the chars are, and you can create a new object.
-Mostly the chars will not burst over the highest address of the chunk,
-because you would typically expect a chunk to be (say) 100 times as
-long as an average object.
-
-In case that isn't clear, when we have enough chars to make up
-the object, THEY ARE ALREADY CONTIGUOUS IN THE CHUNK (guaranteed)
-so we just point to it where it lies. No moving of chars is
-needed and this is the second win: potentially long strings need
-never be explicitly shuffled. Once an object is formed, it does not
-change its address during its lifetime.
-
-When the chars burst over a chunk boundary, we allocate a larger
-chunk, and then copy the partly formed object from the end of the old
-chunk to the beginning of the new larger chunk. We then carry on
-accreting characters to the end of the object as we normally would.
-
-A special macro is provided to add a single char at a time to a
-growing object. This allows the use of register variables, which
-break the ordinary 'growth' macro.
-
-Summary:
- We allocate large chunks.
- We carve out one object at a time from the current chunk.
- Once carved, an object never moves.
- We are free to append data of any size to the currently
- growing object.
- Exactly one object is growing in an obstack at any one time.
- You can run one obstack per control block.
- You may have as many control blocks as you dare.
- Because of the way we do it, you can `unwind' an obstack
- back to a previous state. (You may remove objects much
- as you would with a stack.)
-*/
-
-
-/* Don't do the contents of this file more than once. */
-
-#ifndef _OBSTACK_H
-#define _OBSTACK_H 1
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-\f
-/* We need the type of a pointer subtraction. If __PTRDIFF_TYPE__ is
- defined, as with GNU C, use that; that way we don't pollute the
- namespace with <stddef.h>'s symbols. Otherwise, include <stddef.h>
- and use ptrdiff_t. */
-
-#ifdef __PTRDIFF_TYPE__
-# define PTR_INT_TYPE __PTRDIFF_TYPE__
-#else
-# include <stddef.h>
-# define PTR_INT_TYPE ptrdiff_t
-#endif
-
-/* If B is the base of an object addressed by P, return the result of
- aligning P to the next multiple of A + 1. B and P must be of type
- char *. A + 1 must be a power of 2. */
-
-#define __BPTR_ALIGN(B, P, A) ((B) + (((P) - (B) + (A)) & ~(A)))
-
-/* Similiar to _BPTR_ALIGN (B, P, A), except optimize the common case
- where pointers can be converted to integers, aligned as integers,
- and converted back again. If PTR_INT_TYPE is narrower than a
- pointer (e.g., the AS/400), play it safe and compute the alignment
- relative to B. Otherwise, use the faster strategy of computing the
- alignment relative to 0. */
-
-#define __PTR_ALIGN(B, P, A) \
- __BPTR_ALIGN (sizeof (PTR_INT_TYPE) < sizeof (void *) ? (B) : (char *) 0, \
- P, A)
-
-#include <string.h>
-
-struct _obstack_chunk /* Lives at front of each chunk. */
-{
- char *limit; /* 1 past end of this chunk */
- struct _obstack_chunk *prev; /* address of prior chunk or NULL */
- char contents[4]; /* objects begin here */
-};
-
-struct obstack /* control current object in current chunk */
-{
- long chunk_size; /* preferred size to allocate chunks in */
- struct _obstack_chunk *chunk; /* address of current struct obstack_chunk */
- char *object_base; /* address of object we are building */
- char *next_free; /* where to add next char to current object */
- char *chunk_limit; /* address of char after current chunk */
- union
- {
- PTR_INT_TYPE tempint;
- void *tempptr;
- } temp; /* Temporary for some macros. */
- int alignment_mask; /* Mask of alignment for each object. */
- /* These prototypes vary based on `use_extra_arg', and we use
- casts to the prototypeless function type in all assignments,
- but having prototypes here quiets -Wstrict-prototypes. */
- struct _obstack_chunk *(*chunkfun) (void *, long);
- void (*freefun) (void *, struct _obstack_chunk *);
- void *extra_arg; /* first arg for chunk alloc/dealloc funcs */
- unsigned use_extra_arg:1; /* chunk alloc/dealloc funcs take extra arg */
- unsigned maybe_empty_object:1;/* There is a possibility that the current
- chunk contains a zero-length object. This
- prevents freeing the chunk if we allocate
- a bigger chunk to replace it. */
- unsigned alloc_failed:1; /* No longer used, as we now call the failed
- handler on error, but retained for binary
- compatibility. */
-};
-
-/* Declare the external functions we use; they are in obstack.c. */
-
-extern void _obstack_newchunk (struct obstack *, int);
-extern int _obstack_begin (struct obstack *, int, int,
- void *(*) (long), void (*) (void *));
-extern int _obstack_begin_1 (struct obstack *, int, int,
- void *(*) (void *, long),
- void (*) (void *, void *), void *);
-extern int _obstack_memory_used (struct obstack *);
-
-void obstack_free (struct obstack *obstack, void *block);
-
-\f
-/* Error handler called when `obstack_chunk_alloc' failed to allocate
- more memory. This can be set to a user defined function which
- should either abort gracefully or use longjump - but shouldn't
- return. The default action is to print a message and abort. */
-extern void (*obstack_alloc_failed_handler) (void);
-
-/* Exit value used when `print_and_abort' is used. */
-extern int obstack_exit_failure;
-\f
-/* Pointer to beginning of object being allocated or to be allocated next.
- Note that this might not be the final address of the object
- because a new chunk might be needed to hold the final size. */
-
-#define obstack_base(h) ((void *) (h)->object_base)
-
-/* Size for allocating ordinary chunks. */
-
-#define obstack_chunk_size(h) ((h)->chunk_size)
-
-/* Pointer to next byte not yet allocated in current chunk. */
-
-#define obstack_next_free(h) ((h)->next_free)
-
-/* Mask specifying low bits that should be clear in address of an object. */
-
-#define obstack_alignment_mask(h) ((h)->alignment_mask)
-
-/* To prevent prototype warnings provide complete argument list. */
-#define obstack_init(h) \
- _obstack_begin ((h), 0, 0, \
- (void *(*) (long)) obstack_chunk_alloc, \
- (void (*) (void *)) obstack_chunk_free)
-
-#define obstack_begin(h, size) \
- _obstack_begin ((h), (size), 0, \
- (void *(*) (long)) obstack_chunk_alloc, \
- (void (*) (void *)) obstack_chunk_free)
-
-#define obstack_specify_allocation(h, size, alignment, chunkfun, freefun) \
- _obstack_begin ((h), (size), (alignment), \
- (void *(*) (long)) (chunkfun), \
- (void (*) (void *)) (freefun))
-
-#define obstack_specify_allocation_with_arg(h, size, alignment, chunkfun, freefun, arg) \
- _obstack_begin_1 ((h), (size), (alignment), \
- (void *(*) (void *, long)) (chunkfun), \
- (void (*) (void *, void *)) (freefun), (arg))
-
-#define obstack_chunkfun(h, newchunkfun) \
- ((h) -> chunkfun = (struct _obstack_chunk *(*)(void *, long)) (newchunkfun))
-
-#define obstack_freefun(h, newfreefun) \
- ((h) -> freefun = (void (*)(void *, struct _obstack_chunk *)) (newfreefun))
-
-#define obstack_1grow_fast(h,achar) (*((h)->next_free)++ = (achar))
-
-#define obstack_blank_fast(h,n) ((h)->next_free += (n))
-
-#define obstack_memory_used(h) _obstack_memory_used (h)
-\f
-#if defined __GNUC__ && defined __STDC__ && __STDC__
-/* NextStep 2.0 cc is really gcc 1.93 but it defines __GNUC__ = 2 and
- does not implement __extension__. But that compiler doesn't define
- __GNUC_MINOR__. */
-# if __GNUC__ < 2 || (__NeXT__ && !__GNUC_MINOR__)
-# define __extension__
-# endif
-
-/* For GNU C, if not -traditional,
- we can define these macros to compute all args only once
- without using a global variable.
- Also, we can avoid using the `temp' slot, to make faster code. */
-
-# define obstack_object_size(OBSTACK) \
- __extension__ \
- ({ struct obstack const *__o = (OBSTACK); \
- (unsigned) (__o->next_free - __o->object_base); })
-
-# define obstack_room(OBSTACK) \
- __extension__ \
- ({ struct obstack const *__o = (OBSTACK); \
- (unsigned) (__o->chunk_limit - __o->next_free); })
-
-# define obstack_make_room(OBSTACK,length) \
-__extension__ \
-({ struct obstack *__o = (OBSTACK); \
- int __len = (length); \
- if (__o->chunk_limit - __o->next_free < __len) \
- _obstack_newchunk (__o, __len); \
- (void) 0; })
-
-# define obstack_empty_p(OBSTACK) \
- __extension__ \
- ({ struct obstack const *__o = (OBSTACK); \
- (__o->chunk->prev == 0 \
- && __o->next_free == __PTR_ALIGN ((char *) __o->chunk, \
- __o->chunk->contents, \
- __o->alignment_mask)); })
-
-# define obstack_grow(OBSTACK,where,length) \
-__extension__ \
-({ struct obstack *__o = (OBSTACK); \
- int __len = (length); \
- if (__o->next_free + __len > __o->chunk_limit) \
- _obstack_newchunk (__o, __len); \
- memcpy (__o->next_free, where, __len); \
- __o->next_free += __len; \
- (void) 0; })
-
-# define obstack_grow0(OBSTACK,where,length) \
-__extension__ \
-({ struct obstack *__o = (OBSTACK); \
- int __len = (length); \
- if (__o->next_free + __len + 1 > __o->chunk_limit) \
- _obstack_newchunk (__o, __len + 1); \
- memcpy (__o->next_free, where, __len); \
- __o->next_free += __len; \
- *(__o->next_free)++ = 0; \
- (void) 0; })
-
-# define obstack_1grow(OBSTACK,datum) \
-__extension__ \
-({ struct obstack *__o = (OBSTACK); \
- if (__o->next_free + 1 > __o->chunk_limit) \
- _obstack_newchunk (__o, 1); \
- obstack_1grow_fast (__o, datum); \
- (void) 0; })
-
-/* These assume that the obstack alignment is good enough for pointers
- or ints, and that the data added so far to the current object
- shares that much alignment. */
-
-# define obstack_ptr_grow(OBSTACK,datum) \
-__extension__ \
-({ struct obstack *__o = (OBSTACK); \
- if (__o->next_free + sizeof (void *) > __o->chunk_limit) \
- _obstack_newchunk (__o, sizeof (void *)); \
- obstack_ptr_grow_fast (__o, datum); }) \
-
-# define obstack_int_grow(OBSTACK,datum) \
-__extension__ \
-({ struct obstack *__o = (OBSTACK); \
- if (__o->next_free + sizeof (int) > __o->chunk_limit) \
- _obstack_newchunk (__o, sizeof (int)); \
- obstack_int_grow_fast (__o, datum); })
-
-# define obstack_ptr_grow_fast(OBSTACK,aptr) \
-__extension__ \
-({ struct obstack *__o1 = (OBSTACK); \
- *(const void **) __o1->next_free = (aptr); \
- __o1->next_free += sizeof (const void *); \
- (void) 0; })
-
-# define obstack_int_grow_fast(OBSTACK,aint) \
-__extension__ \
-({ struct obstack *__o1 = (OBSTACK); \
- *(int *) __o1->next_free = (aint); \
- __o1->next_free += sizeof (int); \
- (void) 0; })
-
-# define obstack_blank(OBSTACK,length) \
-__extension__ \
-({ struct obstack *__o = (OBSTACK); \
- int __len = (length); \
- if (__o->chunk_limit - __o->next_free < __len) \
- _obstack_newchunk (__o, __len); \
- obstack_blank_fast (__o, __len); \
- (void) 0; })
-
-# define obstack_alloc(OBSTACK,length) \
-__extension__ \
-({ struct obstack *__h = (OBSTACK); \
- obstack_blank (__h, (length)); \
- obstack_finish (__h); })
-
-# define obstack_copy(OBSTACK,where,length) \
-__extension__ \
-({ struct obstack *__h = (OBSTACK); \
- obstack_grow (__h, (where), (length)); \
- obstack_finish (__h); })
-
-# define obstack_copy0(OBSTACK,where,length) \
-__extension__ \
-({ struct obstack *__h = (OBSTACK); \
- obstack_grow0 (__h, (where), (length)); \
- obstack_finish (__h); })
-
-/* The local variable is named __o1 to avoid a name conflict
- when obstack_blank is called. */
-# define obstack_finish(OBSTACK) \
-__extension__ \
-({ struct obstack *__o1 = (OBSTACK); \
- void *__value = (void *) __o1->object_base; \
- if (__o1->next_free == __value) \
- __o1->maybe_empty_object = 1; \
- __o1->next_free \
- = __PTR_ALIGN (__o1->object_base, __o1->next_free, \
- __o1->alignment_mask); \
- if (__o1->next_free - (char *)__o1->chunk \
- > __o1->chunk_limit - (char *)__o1->chunk) \
- __o1->next_free = __o1->chunk_limit; \
- __o1->object_base = __o1->next_free; \
- __value; })
-
-# define obstack_free(OBSTACK, OBJ) \
-__extension__ \
-({ struct obstack *__o = (OBSTACK); \
- void *__obj = (OBJ); \
- if (__obj > (void *)__o->chunk && __obj < (void *)__o->chunk_limit) \
- __o->next_free = __o->object_base = (char *)__obj; \
- else (obstack_free) (__o, __obj); })
-\f
-#else /* not __GNUC__ or not __STDC__ */
-
-# define obstack_object_size(h) \
- (unsigned) ((h)->next_free - (h)->object_base)
-
-# define obstack_room(h) \
- (unsigned) ((h)->chunk_limit - (h)->next_free)
-
-# define obstack_empty_p(h) \
- ((h)->chunk->prev == 0 \
- && (h)->next_free == __PTR_ALIGN ((char *) (h)->chunk, \
- (h)->chunk->contents, \
- (h)->alignment_mask))
-
-/* Note that the call to _obstack_newchunk is enclosed in (..., 0)
- so that we can avoid having void expressions
- in the arms of the conditional expression.
- Casting the third operand to void was tried before,
- but some compilers won't accept it. */
-
-# define obstack_make_room(h,length) \
-( (h)->temp.tempint = (length), \
- (((h)->next_free + (h)->temp.tempint > (h)->chunk_limit) \
- ? (_obstack_newchunk ((h), (h)->temp.tempint), 0) : 0))
-
-# define obstack_grow(h,where,length) \
-( (h)->temp.tempint = (length), \
- (((h)->next_free + (h)->temp.tempint > (h)->chunk_limit) \
- ? (_obstack_newchunk ((h), (h)->temp.tempint), 0) : 0), \
- memcpy ((h)->next_free, where, (h)->temp.tempint), \
- (h)->next_free += (h)->temp.tempint)
-
-# define obstack_grow0(h,where,length) \
-( (h)->temp.tempint = (length), \
- (((h)->next_free + (h)->temp.tempint + 1 > (h)->chunk_limit) \
- ? (_obstack_newchunk ((h), (h)->temp.tempint + 1), 0) : 0), \
- memcpy ((h)->next_free, where, (h)->temp.tempint), \
- (h)->next_free += (h)->temp.tempint, \
- *((h)->next_free)++ = 0)
-
-# define obstack_1grow(h,datum) \
-( (((h)->next_free + 1 > (h)->chunk_limit) \
- ? (_obstack_newchunk ((h), 1), 0) : 0), \
- obstack_1grow_fast (h, datum))
-
-# define obstack_ptr_grow(h,datum) \
-( (((h)->next_free + sizeof (char *) > (h)->chunk_limit) \
- ? (_obstack_newchunk ((h), sizeof (char *)), 0) : 0), \
- obstack_ptr_grow_fast (h, datum))
-
-# define obstack_int_grow(h,datum) \
-( (((h)->next_free + sizeof (int) > (h)->chunk_limit) \
- ? (_obstack_newchunk ((h), sizeof (int)), 0) : 0), \
- obstack_int_grow_fast (h, datum))
-
-# define obstack_ptr_grow_fast(h,aptr) \
- (((const void **) ((h)->next_free += sizeof (void *)))[-1] = (aptr))
-
-# define obstack_int_grow_fast(h,aint) \
- (((int *) ((h)->next_free += sizeof (int)))[-1] = (aint))
-
-# define obstack_blank(h,length) \
-( (h)->temp.tempint = (length), \
- (((h)->chunk_limit - (h)->next_free < (h)->temp.tempint) \
- ? (_obstack_newchunk ((h), (h)->temp.tempint), 0) : 0), \
- obstack_blank_fast (h, (h)->temp.tempint))
-
-# define obstack_alloc(h,length) \
- (obstack_blank ((h), (length)), obstack_finish ((h)))
-
-# define obstack_copy(h,where,length) \
- (obstack_grow ((h), (where), (length)), obstack_finish ((h)))
-
-# define obstack_copy0(h,where,length) \
- (obstack_grow0 ((h), (where), (length)), obstack_finish ((h)))
-
-# define obstack_finish(h) \
-( ((h)->next_free == (h)->object_base \
- ? (((h)->maybe_empty_object = 1), 0) \
- : 0), \
- (h)->temp.tempptr = (h)->object_base, \
- (h)->next_free \
- = __PTR_ALIGN ((h)->object_base, (h)->next_free, \
- (h)->alignment_mask), \
- (((h)->next_free - (char *) (h)->chunk \
- > (h)->chunk_limit - (char *) (h)->chunk) \
- ? ((h)->next_free = (h)->chunk_limit) : 0), \
- (h)->object_base = (h)->next_free, \
- (h)->temp.tempptr)
-
-# define obstack_free(h,obj) \
-( (h)->temp.tempint = (char *) (obj) - (char *) (h)->chunk, \
- ((((h)->temp.tempint > 0 \
- && (h)->temp.tempint < (h)->chunk_limit - (char *) (h)->chunk)) \
- ? (int) ((h)->next_free = (h)->object_base \
- = (h)->temp.tempint + (char *) (h)->chunk) \
- : (((obstack_free) ((h), (h)->temp.tempint + (char *) (h)->chunk), 0), 0)))
-
-#endif /* not __GNUC__ or not __STDC__ */
-
-#ifdef __cplusplus
-} /* C++ */
-#endif
-
-#endif /* obstack.h */
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2007 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#ifndef OBSTACKPP_H_
-#define OBSTACKPP_H_
-
-#include "obstack.h"
-
-inline void*
-operator new (size_t bytes, struct obstack& obst)
-{
- return obstack_alloc(&obst, bytes);
-}
-
-inline void*
-operator new[] (size_t bytes, struct obstack& obst)
-{
- return obstack_alloc(&obst, bytes);
-}
-
-static inline void* obstack_chunk_alloc(size_t size)
-{
- return new char[size];
-}
-
-static inline void obstack_chunk_free(void* data)
-{
- char* ptr = static_cast<char*> (data);
- delete[] ptr;
-}
-
-#endif
-
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2004 Tobas Glaesser <tobi.web@gmx.de>
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#include <config.h>
-
-#include "options_menu.hpp"
-#include "gui/menu.hpp"
-#include "audio/sound_manager.hpp"
-#include "control/joystickkeyboardcontroller.hpp"
-#include "main.hpp"
-#include "gettext.hpp"
-#include "gameconfig.hpp"
-
-Menu* options_menu = 0;
-
-enum OptionsMenuIDs {
- MNID_FULLSCREEN,
- MNID_SOUND,
- MNID_MUSIC
-};
-
-class LanguageMenu : public Menu
-{
-public:
- LanguageMenu() {
- add_label(_("Language"));
- add_hl();
- add_entry(0, std::string("(")+_("auto-detect language")+")");
- add_entry(1, "English");
-
- int mnid = 10;
- std::set<std::string> languages = dictionary_manager.get_languages();
- for (std::set<std::string>::iterator i = languages.begin(); i != languages.end(); i++) {
- std::string locale_name = *i;
- TinyGetText::LanguageDef ldef = TinyGetText::get_language_def(locale_name);
- std::string locale_fullname = locale_name;
- if (std::string(ldef.code) == locale_name) {
- locale_fullname = ldef.name;
- }
- add_entry(mnid++, locale_fullname);
- }
-
- add_hl();
- add_back(_("Back"));
- }
-
- virtual void menu_action(MenuItem* item) {
- if (item->id == 0) {
- config->locale = "";
- dictionary_manager.set_language(config->locale);
- config->save();
- Menu::set_current(0);
- }
- else if (item->id == 1) {
- config->locale = "en";
- dictionary_manager.set_language(config->locale);
- config->save();
- Menu::set_current(0);
- }
- int mnid = 10;
- std::set<std::string> languages = dictionary_manager.get_languages();
- for (std::set<std::string>::iterator i = languages.begin(); i != languages.end(); i++) {
- std::string locale_name = *i;
- if (item->id == mnid++) {
- config->locale = locale_name;
- dictionary_manager.set_language(config->locale);
- config->save();
- Menu::set_current(0);
- }
- }
- }
-};
-
-
-class OptionsMenu : public Menu
-{
-public:
- OptionsMenu();
- virtual ~OptionsMenu();
-
- virtual void menu_action(MenuItem* item);
-
-protected:
- std::auto_ptr<LanguageMenu> language_menu;
-
-};
-
-OptionsMenu::OptionsMenu()
-{
- language_menu.reset(new LanguageMenu());
-
- add_label(_("Options"));
- add_hl();
- add_toggle(MNID_FULLSCREEN,_("Fullscreen"), config->use_fullscreen);
- add_submenu(_("Language"), language_menu.get());
- if (sound_manager->is_audio_enabled()) {
- add_toggle(MNID_SOUND, _("Sound"), config->sound_enabled);
- add_toggle(MNID_MUSIC, _("Music"), config->music_enabled);
- } else {
- add_deactive(MNID_SOUND, _("Sound (disabled)"));
- add_deactive(MNID_SOUND, _("Music (disabled)"));
- }
- add_submenu(_("Setup Keyboard"), main_controller->get_key_options_menu());
- add_submenu(_("Setup Joystick"),main_controller->get_joystick_options_menu());
- add_hl();
- add_back(_("Back"));
-}
-
-OptionsMenu::~OptionsMenu()
-{
-}
-
-void
-OptionsMenu::menu_action(MenuItem* item)
-{
- switch (item->id) {
- case MNID_FULLSCREEN:
- if(config->use_fullscreen != options_menu->is_toggled(MNID_FULLSCREEN)) {
- config->use_fullscreen = !config->use_fullscreen;
- init_video();
- config->save();
- }
- break;
- case MNID_SOUND:
- if(config->sound_enabled != options_menu->is_toggled(MNID_SOUND)) {
- config->sound_enabled = !config->sound_enabled;
- sound_manager->enable_sound(config->sound_enabled);
- config->save();
- }
- break;
- case MNID_MUSIC:
- if(config->music_enabled != options_menu->is_toggled(MNID_MUSIC)) {
- config->music_enabled = !config->music_enabled;
- sound_manager->enable_music(config->music_enabled);
- config->save();
- }
- break;
- default:
- break;
- }
-}
-
-Menu* get_options_menu()
-{
- //static OptionsMenu menu;
- options_menu = new OptionsMenu();
- return options_menu;
-}
-
-void free_options_menu()
-{
- delete options_menu;
- options_menu = 0;
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2004 Tobas Glaesser <tobi.web@gmx.de>
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#ifndef __OPTIONS_MENU_HPP__
-#define __OPTIONS_MENU_HPP__
-
-class Menu;
-Menu* get_options_menu();
-void free_options_menu();
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include "physfs_sdl.hpp"
-
-#include <physfs.h>
-
-#include <stdexcept>
-#include <sstream>
-#include <iostream>
-
-#include <assert.h>
-#include "log.hpp"
-
-static int funcSeek(struct SDL_RWops* context, int offset, int whence)
-{
- PHYSFS_file* file = (PHYSFS_file*) context->hidden.unknown.data1;
- int res;
- switch(whence) {
- case SEEK_SET:
- res = PHYSFS_seek(file, offset);
- break;
- case SEEK_CUR:
- res = PHYSFS_seek(file, PHYSFS_tell(file) + offset);
- break;
- case SEEK_END:
- res = PHYSFS_seek(file, PHYSFS_fileLength(file) + offset);
- break;
- default:
- res = 0;
- assert(false);
- break;
- }
- if(res == 0) {
- log_warning << "Error seeking in file: " << PHYSFS_getLastError() << std::endl;
- return -1;
- }
-
- return (int) PHYSFS_tell(file);
-}
-
-static int funcRead(struct SDL_RWops* context, void* ptr, int size, int maxnum)
-{
- PHYSFS_file* file = (PHYSFS_file*) context->hidden.unknown.data1;
-
- int res = PHYSFS_read(file, ptr, size, maxnum);
- return res;
-}
-
-static int funcClose(struct SDL_RWops* context)
-{
- PHYSFS_file* file = (PHYSFS_file*) context->hidden.unknown.data1;
-
- PHYSFS_close(file);
- delete context;
-
- return 0;
-}
-
-SDL_RWops* get_physfs_SDLRWops(const std::string& filename)
-{
- // check this as PHYSFS seems to be buggy and still returns a
- // valid pointer in this case
- if(filename == "") {
- throw std::runtime_error("Couldn't open file: empty filename");
- }
-
- PHYSFS_file* file = (PHYSFS_file*) PHYSFS_openRead(filename.c_str());
- if(!file) {
- std::stringstream msg;
- msg << "Couldn't open '" << filename << "': "
- << PHYSFS_getLastError();
- throw std::runtime_error(msg.str());
- }
-
- SDL_RWops* ops = new SDL_RWops();
- ops->type = 0;
- ops->hidden.unknown.data1 = file;
- ops->seek = funcSeek;
- ops->read = funcRead;
- ops->write = 0;
- ops->close = funcClose;
- return ops;
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __PHYSFSSDL_HPP__
-#define __PHYSFSSDL_HPP__
-
-#include <SDL.h>
-#include <string>
-
-SDL_RWops* get_physfs_SDLRWops(const std::string& filename);
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include "physfs_stream.hpp"
-
-#include <assert.h>
-#include <physfs.h>
-#include <stdexcept>
-#include <sstream>
-
-IFileStreambuf::IFileStreambuf(const std::string& filename)
-{
- // check this as PHYSFS seems to be buggy and still returns a
- // valid pointer in this case
- if(filename == "") {
- throw std::runtime_error("Couldn't open file: empty filename");
- }
- file = PHYSFS_openRead(filename.c_str());
- if(file == 0) {
- std::stringstream msg;
- msg << "Couldn't open file '" << filename << "': "
- << PHYSFS_getLastError();
- throw std::runtime_error(msg.str());
- }
-}
-
-IFileStreambuf::~IFileStreambuf()
-{
- PHYSFS_close(file);
-}
-
-int
-IFileStreambuf::underflow()
-{
- if(PHYSFS_eof(file)) {
- return traits_type::eof();
- }
-
- PHYSFS_sint64 bytesread = PHYSFS_read(file, buf, 1, sizeof(buf));
- if(bytesread <= 0) {
- return traits_type::eof();
- }
- setg(buf, buf, buf + bytesread);
-
- return buf[0];
-}
-
-IFileStreambuf::pos_type
-IFileStreambuf::seekpos(pos_type pos, std::ios_base::openmode)
-{
- if(PHYSFS_seek(file, static_cast<PHYSFS_uint64> (pos)) == 0) {
- return pos_type(off_type(-1));
- }
-
- // the seek invalidated the buffer
- setg(buf, buf, buf);
- return pos;
-}
-
-IFileStreambuf::pos_type
-IFileStreambuf::seekoff(off_type off, std::ios_base::seekdir dir,
- std::ios_base::openmode mode)
-{
- off_type pos = off;
- PHYSFS_sint64 ptell = PHYSFS_tell(file);
-
- switch(dir) {
- case std::ios_base::beg:
- break;
- case std::ios_base::cur:
- if(off == 0)
- return static_cast<pos_type> (ptell) - static_cast<pos_type> (egptr() - gptr());
- pos += static_cast<off_type> (ptell) - static_cast<off_type> (egptr() - gptr());
- break;
- case std::ios_base::end:
- pos += static_cast<off_type> (PHYSFS_fileLength(file));
- break;
- default:
-#ifdef DEBUG
- assert(false);
-#else
- return pos_type(off_type(-1));
-#endif
- }
-
- return seekpos(static_cast<pos_type> (pos), mode);
-}
-
-//---------------------------------------------------------------------------
-
-OFileStreambuf::OFileStreambuf(const std::string& filename)
-{
- file = PHYSFS_openWrite(filename.c_str());
- if(file == 0) {
- std::stringstream msg;
- msg << "Couldn't open file '" << filename << "': "
- << PHYSFS_getLastError();
- throw std::runtime_error(msg.str());
- }
-
- setp(buf, buf+sizeof(buf));
-}
-
-OFileStreambuf::~OFileStreambuf()
-{
- sync();
- PHYSFS_close(file);
-}
-
-int
-OFileStreambuf::overflow(int c)
-{
- char c2 = (char)c;
-
- if(pbase() == pptr())
- return 0;
-
- size_t size = pptr() - pbase();
- PHYSFS_sint64 res = PHYSFS_write(file, pbase(), 1, size);
- if(res <= 0)
- return traits_type::eof();
-
- if(c != traits_type::eof()) {
- PHYSFS_sint64 res = PHYSFS_write(file, &c2, 1, 1);
- if(res <= 0)
- return traits_type::eof();
- }
-
- setp(buf, buf + res);
- return 0;
-}
-
-int
-OFileStreambuf::sync()
-{
- return overflow(traits_type::eof());
-}
-
-//---------------------------------------------------------------------------
-
-IFileStream::IFileStream(const std::string& filename)
- : std::istream(new IFileStreambuf(filename))
-{
-}
-
-IFileStream::~IFileStream()
-{
- delete rdbuf();
-}
-
-//---------------------------------------------------------------------------
-
-OFileStream::OFileStream(const std::string& filename)
- : std::ostream(new OFileStreambuf(filename))
-{
-}
-
-OFileStream::~OFileStream()
-{
- delete rdbuf();
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __PHYSFSSTREAM_HPP__
-#define __PHYSFSSTREAM_HPP__
-
-#include <stddef.h>
-#include <physfs.h>
-#include <string>
-#include <streambuf>
-#include <iostream>
-
-/** This class implements a C++ streambuf object for physfs files.
- * So that you can use normal istream operations on them
- */
-class IFileStreambuf : public std::streambuf
-{
-public:
- IFileStreambuf(const std::string& filename);
- ~IFileStreambuf();
-
-protected:
- virtual int underflow();
- virtual pos_type seekoff(off_type pos, std::ios_base::seekdir,
- std::ios_base::openmode);
- virtual pos_type seekpos(pos_type pos, std::ios_base::openmode);
-
-private:
- PHYSFS_file* file;
- char buf[1024];
-};
-
-class OFileStreambuf : public std::streambuf
-{
-public:
- OFileStreambuf(const std::string& filename);
- ~OFileStreambuf();
-
-protected:
- virtual int overflow(int c);
- virtual int sync();
-
-private:
- PHYSFS_file* file;
- char buf[1024];
-};
-
-class IFileStream : public std::istream
-{
-public:
- IFileStream(const std::string& filename);
- ~IFileStream();
-};
-
-class OFileStream : public std::ostream
-{
-public:
- OFileStream(const std::string& filename);
- ~OFileStream();
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2004 Tobias Glaesser <tobi.web@gmx.de>
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#include <config.h>
-
-#include "physic.hpp"
-
-Physic::Physic()
- : ax(0), ay(0), vx(0), vy(0), gravity_enabled_flag(true), gravity(10 * 100)
-{
-}
-
-Physic::~Physic()
-{
-}
-
-void
-Physic::reset()
-{
- ax = ay = vx = vy = 0;
- gravity_enabled_flag = true;
-}
-
-void
-Physic::set_velocity_x(float nvx)
-{
- vx = nvx;
-}
-
-void
-Physic::set_velocity_y(float nvy)
-{
- vy = nvy;
-}
-
-void
-Physic::set_velocity(float nvx, float nvy)
-{
- vx = nvx;
- vy = nvy;
-}
-
-void
-Physic::set_velocity(const Vector& vector)
-{
- vx = vector.x;
- vy = vector.y;
-}
-
-void Physic::inverse_velocity_x()
-{
- vx = -vx;
-}
-
-void Physic::inverse_velocity_y()
-{
- vy = -vy;
-}
-
-float
-Physic::get_velocity_x() const
-{
- return vx;
-}
-
-float
-Physic::get_velocity_y() const
-{
- return vy;
-}
-
-Vector
-Physic::get_velocity() const
-{
- return Vector(vx, vy);
-}
-
-void
-Physic::set_acceleration_x(float nax)
-{
- ax = nax;
-}
-
-void
-Physic::set_acceleration_y(float nay)
-{
- ay = nay;
-}
-
-void
-Physic::set_acceleration(float nax, float nay)
-{
- ax = nax;
- ay = nay;
-}
-
-float
-Physic::get_acceleration_x() const
-{
- return ax;
-}
-
-float
-Physic::get_acceleration_y() const
-{
- return ay;
-}
-
-Vector
-Physic::get_acceleration() const
-{
- return Vector(ax, ay);
-}
-
-void
-Physic::enable_gravity(bool enable_gravity)
-{
- gravity_enabled_flag = enable_gravity;
-}
-
-bool
-Physic::gravity_enabled() const
-{
- return gravity_enabled_flag;
-}
-
-void
-Physic::set_gravity(float gravity)
-{
- this->gravity = gravity * 100;
-}
-
-float
-Physic::get_gravity() const
-{
- return gravity / 100;
-}
-
-Vector
-Physic::get_movement(float elapsed_time)
-{
- float grav = gravity_enabled_flag ? gravity : 0;
-
- Vector result(
- vx * elapsed_time + ax * elapsed_time * elapsed_time,
- vy * elapsed_time + (ay + grav) * elapsed_time * elapsed_time
- );
- vx += ax * elapsed_time;
- vy += (ay + grav) * elapsed_time;
-
- return result;
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2004 Tobias Glaesser <tobi.web@gmx.de>
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#ifndef SUPERTUX_PHYSIC_H
-#define SUPERTUX_PHYSIC_H
-
-#include "math/vector.hpp"
-
-/// Physics engine.
-/** This is a very simplistic physics engine handling accelerated and constant
- * movement along with gravity.
- */
-class Physic
-{
-public:
- Physic();
- ~Physic();
-
- /// Resets all velocities and accelerations to 0.
- void reset();
-
- /// Sets velocity to a fixed value.
- void set_velocity(float vx, float vy);
- void set_velocity(const Vector& vector);
-
- void set_velocity_x(float vx);
- void set_velocity_y(float vy);
-
- /// Velocities invertion.
- void inverse_velocity_x();
- void inverse_velocity_y();
-
- Vector get_velocity() const;
- float get_velocity_x() const;
- float get_velocity_y() const;
-
- /// Set acceleration.
- /** Sets acceleration applied to the object. (Note that gravity is
- * eventually added to the vertical acceleration)
- */
- void set_acceleration(float ax, float ay);
-
- void set_acceleration_x(float ax);
- void set_acceleration_y(float ay);
-
- Vector get_acceleration() const;
- float get_acceleration_x() const;
- float get_acceleration_y() const;
-
- /// Enables or disables handling of gravity.
- void enable_gravity(bool gravity_enabled);
- bool gravity_enabled() const;
-
- /// Set gravity to apply to object when enabled
- void set_gravity(float gravity);
-
- /// Get gravity to apply to object when enabled
- float get_gravity() const;
-
- Vector get_movement(float elapsed_time);
-
-private:
- /// horizontal and vertical acceleration
- float ax, ay;
- /// horizontal and vertical velocity
- float vx, vy;
- /// should we respect gravity in our calculations?
- bool gravity_enabled_flag;
- /// current gravity (multiplied by 100) to apply to object, if enabled
- float gravity;
-};
-
-class UsesPhysic
-{
-public:
- Physic physic;
- friend class Sector;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2003 Tobias Glaesser <tobi.web@gmx.de>
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#include <config.h>
-
-#include <math.h>
-#include "lisp/writer.hpp"
-#include "lisp/lisp.hpp"
-#include "player_status.hpp"
-#include "resources.hpp"
-#include "gettext.hpp"
-#include "video/drawing_context.hpp"
-#include "audio/sound_manager.hpp"
-#include "sprite/sprite_manager.hpp"
-#include "math/vector.hpp"
-#include "main.hpp"
-#include "log.hpp"
-#include "timer.hpp"
-
-static const int START_COINS = 100;
-static const int MAX_COINS = 99999;
-
-PlayerStatus* player_status = 0;
-
-PlayerStatus::PlayerStatus()
- : coins(START_COINS),
- bonus(NO_BONUS),
- max_fire_bullets(0),
- max_ice_bullets(0),
- score_multiplier(1),
- max_score_multiplier(1)
-{
- reset();
-
- coin_surface.reset(new Surface("images/engine/hud/coins-0.png"));
-}
-
-PlayerStatus::~PlayerStatus()
-{
-}
-
-void PlayerStatus::reset()
-{
- coins = START_COINS;
- bonus = NO_BONUS;
- score_multiplier = 1;
- max_score_multiplier = 1;
-}
-
-void
-PlayerStatus::add_coins(int count, bool play_sound)
-{
- static float sound_played_time = 0;
- coins = std::min(coins + count, MAX_COINS);
- if(play_sound) {
- if(count >= 100)
- sound_manager->play("sounds/lifeup.wav");
- else if (real_time > sound_played_time + 0.010) {
- sound_manager->play("sounds/coin.wav");
- sound_played_time = real_time;
- }
- }
-}
-
-void
-PlayerStatus::write(lisp::Writer& writer)
-{
- switch(bonus) {
- case NO_BONUS:
- writer.write_string("bonus", "none");
- break;
- case GROWUP_BONUS:
- writer.write_string("bonus", "growup");
- break;
- case FIRE_BONUS:
- writer.write_string("bonus", "fireflower");
- break;
- case ICE_BONUS:
- writer.write_string("bonus", "iceflower");
- break;
- default:
- log_warning << "Unknown bonus type." << std::endl;
- writer.write_string("bonus", "none");
- }
- writer.write_int("fireflowers", max_fire_bullets);
- writer.write_int("iceflowers", max_ice_bullets);
-
- writer.write_int("coins", coins);
- writer.write_int("max-score-multiplier", max_score_multiplier);
-}
-
-void
-PlayerStatus::read(const lisp::Lisp& lisp)
-{
- reset();
-
- std::string bonusname;
- if(lisp.get("bonus", bonusname)) {
- if(bonusname == "none") {
- bonus = NO_BONUS;
- } else if(bonusname == "growup") {
- bonus = GROWUP_BONUS;
- } else if(bonusname == "fireflower") {
- bonus = FIRE_BONUS;
- } else if(bonusname == "iceflower") {
- bonus = ICE_BONUS;
- } else {
- log_warning << "Unknown bonus '" << bonusname << "' in savefile" << std::endl;
- bonus = NO_BONUS;
- }
- }
- lisp.get("fireflowers", max_fire_bullets);
- lisp.get("iceflowers", max_ice_bullets);
-
- lisp.get("coins", coins);
- lisp.get("max-score-multiplier", max_score_multiplier);
-}
-
-void
-PlayerStatus::draw(DrawingContext& context)
-{
- static int displayed_coins = -1;
- static int next_count = 0;
-
- if ((displayed_coins == -1) || (fabsf(displayed_coins - coins) > 100)) {
- displayed_coins = coins;
- }
- if (++next_count > 2) {
- next_count = 0;
- if (displayed_coins < coins) displayed_coins++;
- if (displayed_coins > coins) displayed_coins--;
- }
- displayed_coins = std::min(std::max(displayed_coins, 0), 9999);
-
- std::stringstream ss;
- ss << displayed_coins;
- std::string coins_text = ss.str();
-
- context.push_transform();
- context.set_translation(Vector(0, 0));
-
- Surface* coin_surf = coin_surface.get();
- if (coin_surf) {
- context.draw_surface(coin_surf, Vector(SCREEN_WIDTH - BORDER_X - coin_surf->get_width() - gold_fixed_text->get_text_width(coins_text), BORDER_Y + 1), LAYER_HUD);
- }
- context.draw_text(gold_fixed_text, coins_text, Vector(SCREEN_WIDTH - BORDER_X, BORDER_Y), ALIGN_RIGHT, LAYER_HUD);
-
- context.pop_transform();
-}
-
-void
-PlayerStatus::operator= (const PlayerStatus& other)
-{
- coins = other.coins;
- bonus = other.bonus;
- score_multiplier = other.score_multiplier;
- max_score_multiplier = other.max_score_multiplier;
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2003 Tobias Glaesser <tobi.web@gmx.de>
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#ifndef SUPERTUX_PLAYERSTATUS_H
-#define SUPERTUX_PLAYERSTATUS_H
-
-#include <memory>
-#include "serializable.hpp"
-
-namespace lisp{ class Writer; }
-namespace lisp{ class Lisp; }
-class Surface;
-
-static const float BORDER_X = 10;
-static const float BORDER_Y = 10;
-
-enum BonusType {
- NO_BONUS, GROWUP_BONUS, FIRE_BONUS, ICE_BONUS
-};
-class DrawingContext;
-
-/**
- * This class memorizes player status between different game sessions (for
- * example when switching maps in the worldmap)
- */
-class PlayerStatus : public Serializable
-{
-public:
- PlayerStatus();
- ~PlayerStatus();
- void reset();
- void add_coins(int count, bool play_sound = true);
-
- void write(lisp::Writer& writer);
- void read(const lisp::Lisp& lisp);
-
- void draw(DrawingContext& context);
-
- int coins;
- BonusType bonus;
- int max_fire_bullets; /**< maximum number of fire bullets in play */
- int max_ice_bullets; /**< maximum number of ice bullets in play */
-
- int score_multiplier;
- int max_score_multiplier;
-
- void operator= (const PlayerStatus& other);
-
-private:
- // don't use this
- PlayerStatus(const PlayerStatus& other);
-
- std::auto_ptr<Surface> coin_surface;
-};
-
-// global player state
-extern PlayerStatus* player_status;
-
-#endif
+++ /dev/null
-// $Id$
-//
-// A strong random number generator
-//
-// Copyright (C) 2006 Allen King
-// Copyright (C) 2002 Michael Ringgaard. All rights reserved.
-// Copyright (C) 1983, 1993 The Regents of the University of California.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions
-// are met:
-//
-// 1. Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// 2. Redistributions in binary form must reproduce the above copyright
-// notice, this list of conditions and the following disclaimer in the
-// documentation and/or other materials provided with the distribution.
-// 3. Neither the name of the project nor the names of its contributors
-// may be used to endorse or promote products derived from this software
-// without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
-// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-// OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-// SUCH DAMAGE.
-
-// Transliterated into C++ Allen King 060417, from sources on
-// http://www.jbox.dk/sanos/source/lib/random.c.html
-#include <config.h>
-
-
-#include <stdexcept>
-#include <time.h>
-#include <cassert>
-#include "random_generator.hpp"
-
-RandomGenerator systemRandom; // global random number generator
-
-RandomGenerator::RandomGenerator() {
- assert(sizeof(int) >= 4);
- initialized = 0;
- debug = 0; // change this by hand for debug
- initialize();
-}
-
-RandomGenerator::~RandomGenerator() {
-}
-
-int RandomGenerator::srand(int x) {
- int x0 = x;
- while (x <= 0) // random seed of zero means
- x = time(0) % RandomGenerator::rand_max; // randomize with time
-
- if (debug > 0)
- printf("==== srand(%10d) (%10d) rand_max=%x =====\n",
- x, x0, RandomGenerator::rand_max);
-
- RandomGenerator::srandom(x);
- return x; // let caller know seed used
-}
-
-int RandomGenerator::rand() {
- int rv; // a posative int
- while ((rv = RandomGenerator::random()) <= 0) // neg or zero causes probs
- ;
- if (debug > 0)
- printf("==== rand(): %10d =====\n", rv);
- return rv;
-}
-
-int RandomGenerator::rand(int v) {
- assert(v >= 0 && v <= RandomGenerator::rand_max); // illegal arg
-
- // remove biases, esp. when v is large (e.g. v == (rand_max/4)*3;)
- int rv, maxV =(RandomGenerator::rand_max / v) * v;
- assert(maxV <= RandomGenerator::rand_max);
- while ((rv = RandomGenerator::random()) >= maxV)
- ;
- return rv % v; // mod it down to 0..(maxV-1)
-}
-
-int RandomGenerator::rand(int u, int v) {
- assert(v > u);
- return u + RandomGenerator::rand(v-u);
-}
-
-double RandomGenerator::randf(double v) {
- float rv;
- do {
- rv = ((double)RandomGenerator::random())/RandomGenerator::rand_max * v;
- } while (rv >= v); // rounding might cause rv==v
-
- if (debug > 0)
- printf("==== rand(): %f =====\n", rv);
- return rv;
-}
-
-double RandomGenerator::randf(double u, double v) {
- return u + RandomGenerator::randf(v-u);
-}
-
-//-----------------------------------------------------------------------
-//
-// Copyright (C) 2002 Michael Ringgaard. All rights reserved.
-// Copyright (C) 1983, 1993 The Regents of the University of California.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions
-// are met:
-//
-// 1. Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// 2. Redistributions in binary form must reproduce the above copyright
-// notice, this list of conditions and the following disclaimer in the
-// documentation and/or other materials provided with the distribution.
-// 3. Neither the name of the project nor the names of its contributors
-// may be used to endorse or promote products derived from this software
-// without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
-// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-// OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-// SUCH DAMAGE.
-//
-
-//**#include <os.h>
-
-//
-// An improved random number generation package. In addition to the standard
-// rand()/srand() like interface, this package also has a special state info
-// interface. The initstate() routine is called with a seed, an array of
-// bytes, and a count of how many bytes are being passed in; this array is
-// then initialized to contain information for random number generation with
-// that much state information. Good sizes for the amount of state
-// information are 32, 64, 128, and 256 bytes. The state can be switched by
-// calling the setstate() routine with the same array as was initiallized
-// with initstate(). By default, the package runs with 128 bytes of state
-// information and generates far better random numbers than a linear
-// congruential generator. If the amount of state information is less than
-// 32 bytes, a simple linear congruential R.N.G. is used.
-//
-// Internally, the state information is treated as an array of longs; the
-// zeroeth element of the array is the type of R.N.G. being used (small
-// integer); the remainder of the array is the state information for the
-// R.N.G. Thus, 32 bytes of state information will give 7 longs worth of
-// state information, which will allow a degree seven polynomial. (Note:
-// the zeroeth word of state information also has some other information
-// stored in it -- see setstate() for details).
-//
-// The random number generation technique is a linear feedback shift register
-// approach, employing trinomials (since there are fewer terms to sum up that
-// way). In this approach, the least significant bit of all the numbers in
-// the state table will act as a linear feedback shift register, and will
-// have period 2^deg - 1 (where deg is the degree of the polynomial being
-// used, assuming that the polynomial is irreducible and primitive). The
-// higher order bits will have longer periods, since their values are also
-// influenced by pseudo-random carries out of the lower bits. The total
-// period of the generator is approximately deg*(2**deg - 1); thus doubling
-// the amount of state information has a vast influence on the period of the
-// generator. Note: the deg*(2**deg - 1) is an approximation only good for
-// large deg, when the period of the shift is the dominant factor.
-// With deg equal to seven, the period is actually much longer than the
-// 7*(2**7 - 1) predicted by this formula.
-//
-// Modified 28 December 1994 by Jacob S. Rosenberg.
-//
-
-//
-// For each of the currently supported random number generators, we have a
-// break value on the amount of state information (you need at least this
-// many bytes of state info to support this random number generator), a degree
-// for the polynomial (actually a trinomial) that the R.N.G. is based on, and
-// the separation between the two lower order coefficients of the trinomial.
-
-void RandomGenerator::initialize() {
-
-#define NSHUFF 100 // To drop part of seed -> 1st value correlation
-
-//static long degrees[MAX_TYPES] = { DEG_0, DEG_1, DEG_2, DEG_3, DEG_4 };
-//static long seps [MAX_TYPES] = { SEP_0, SEP_1, SEP_2, SEP_3, SEP_4 };
-
- degrees[0] = DEG_0;
- degrees[1] = DEG_1;
- degrees[2] = DEG_2;
- degrees[3] = DEG_3;
- degrees[4] = DEG_4;
-
- seps [0] = SEP_0;
- seps [1] = SEP_1;
- seps [2] = SEP_2;
- seps [3] = SEP_3;
- seps [4] = SEP_4;
-
-//
-// Initially, everything is set up as if from:
-//
-// initstate(1, randtbl, 128);
-//
-// Note that this initialization takes advantage of the fact that srandom()
-// advances the front and rear pointers 10*rand_deg times, and hence the
-// rear pointer which starts at 0 will also end up at zero; thus the zeroeth
-// element of the state information, which contains info about the current
-// position of the rear pointer is just
-//
-// MAX_TYPES * (rptr - state) + TYPE_3 == TYPE_3.
-
- randtbl[ 0] = TYPE_3;
- randtbl[ 1] = 0x991539b1;
- randtbl[ 2] = 0x16a5bce3;
- randtbl[ 3] = 0x6774a4cd;
- randtbl[ 4] = 0x3e01511e;
- randtbl[ 5] = 0x4e508aaa;
- randtbl[ 6] = 0x61048c05;
- randtbl[ 7] = 0xf5500617;
- randtbl[ 8] = 0x846b7115;
- randtbl[ 9] = 0x6a19892c;
- randtbl[10] = 0x896a97af;
- randtbl[11] = 0xdb48f936;
- randtbl[12] = 0x14898454;
- randtbl[13] = 0x37ffd106;
- randtbl[14] = 0xb58bff9c;
- randtbl[15] = 0x59e17104;
- randtbl[16] = 0xcf918a49;
- randtbl[17] = 0x09378c83;
- randtbl[18] = 0x52c7a471;
- randtbl[19] = 0x8d293ea9;
- randtbl[20] = 0x1f4fc301;
- randtbl[21] = 0xc3db71be;
- randtbl[22] = 0x39b44e1c;
- randtbl[23] = 0xf8a44ef9;
- randtbl[24] = 0x4c8b80b1;
- randtbl[25] = 0x19edc328;
- randtbl[26] = 0x87bf4bdd;
- randtbl[27] = 0xc9b240e5;
- randtbl[28] = 0xe9ee4b1b;
- randtbl[29] = 0x4382aee7;
- randtbl[30] = 0x535b6b41;
- randtbl[31] = 0xf3bec5da;
-
-// static long randtbl[DEG_3 + 1] =
-// {
-// TYPE_3;
-// 0x991539b1, 0x16a5bce3, 0x6774a4cd, 0x3e01511e, 0x4e508aaa, 0x61048c05,
-// 0xf5500617, 0x846b7115, 0x6a19892c, 0x896a97af, 0xdb48f936, 0x14898454,
-// 0x37ffd106, 0xb58bff9c, 0x59e17104, 0xcf918a49, 0x09378c83, 0x52c7a471,
-// 0x8d293ea9, 0x1f4fc301, 0xc3db71be, 0x39b44e1c, 0xf8a44ef9, 0x4c8b80b1,
-// 0x19edc328, 0x87bf4bdd, 0xc9b240e5, 0xe9ee4b1b, 0x4382aee7, 0x535b6b41,
-// 0xf3bec5da
-// };
-
-
-//
-// fptr and rptr are two pointers into the state info, a front and a rear
-// pointer. These two pointers are always rand_sep places aparts, as they
-// cycle cyclically through the state information. (Yes, this does mean we
-// could get away with just one pointer, but the code for random() is more
-// efficient this way). The pointers are left positioned as they would be
-// from the call
-//
-// initstate(1, randtbl, 128);
-//
-// (The position of the rear pointer, rptr, is really 0 (as explained above
-// in the initialization of randtbl) because the state table pointer is set
-// to point to randtbl[1] (as explained below).
-//
-
- fptr = &randtbl[SEP_3 + 1];
- rptr = &randtbl[1];
-
-//
-// The following things are the pointer to the state information table, the
-// type of the current generator, the degree of the current polynomial being
-// used, and the separation between the two pointers. Note that for efficiency
-// of random(), we remember the first location of the state information, not
-// the zeroeth. Hence it is valid to access state[-1], which is used to
-// store the type of the R.N.G. Also, we remember the last location, since
-// this is more efficient than indexing every time to find the address of
-// the last element to see if the front and rear pointers have wrapped.
-//
-
- state = &randtbl[1];
- rand_type = TYPE_3;
- rand_deg = DEG_3;
- rand_sep = SEP_3;
- end_ptr = &randtbl[DEG_3 + 1];
-
-}
-
-//
-// Compute x = (7^5 * x) mod (2^31 - 1)
-// wihout overflowing 31 bits:
-// (2^31 - 1) = 127773 * (7^5) + 2836
-// From "Random number generators: good ones are hard to find",
-// Park and Miller, Communications of the ACM, vol. 31, no. 10,
-// October 1988, p. 1195.
-//
-
-__inline static long good_rand(long x)
-{
- long hi, lo;
-
- // Can't be initialized with 0, so use another value.
- if (x == 0) x = 123459876;
- hi = x / 127773;
- lo = x % 127773;
- x = 16807 * lo - 2836 * hi;
- if (x < 0) x += 0x7fffffff;
- return x;
-}
-
-//
-// srandom
-//
-// Initialize the random number generator based on the given seed. If the
-// type is the trivial no-state-information type, just remember the seed.
-// Otherwise, initializes state[] based on the given "seed" via a linear
-// congruential generator. Then, the pointers are set to known locations
-// that are exactly rand_sep places apart. Lastly, it cycles the state
-// information a given number of times to get rid of any initial dependencies
-// introduced by the L.C.R.N.G. Note that the initialization of randtbl[]
-// for default usage relies on values produced by this routine.
-
-void RandomGenerator::srandom(unsigned long x)
-{
- long i, lim;
-
- state[0] = x;
- if (rand_type == TYPE_0)
- lim = NSHUFF;
- else
- {
- for (i = 1; i < rand_deg; i++) state[i] = good_rand(state[i - 1]);
- fptr = &state[rand_sep];
- rptr = &state[0];
- lim = 10 * rand_deg;
- }
-
- initialized = 1;
- for (i = 0; i < lim; i++) random();
-}
-
-#ifdef NOT_FOR_SUPERTUX // use in supertux doesn't require these methods,
- // which are not portable to as many platforms as
- // SDL. The cost is that the variability of the
- // initial seed is reduced to only 32 bits of
- // randomness, seemingly enough. PAK 060420
-//
-// srandomdev
-//
-// Many programs choose the seed value in a totally predictable manner.
-// This often causes problems. We seed the generator using the much more
-// secure random() interface. Note that this particular seeding
-// procedure can generate states which are impossible to reproduce by
-// calling srandom() with any value, since the succeeding terms in the
-// state buffer are no longer derived from the LC algorithm applied to
-// a fixed seed.
-
-void RandomGenerator::srandomdev()
-{
- int fd, done;
- size_t len;
-
- if (rand_type == TYPE_0)
- len = sizeof state[0];
- else
- len = rand_deg * sizeof state[0];
-
- done = 0;
- fd = open("/dev/urandom", O_RDONLY);
- if (fd >= 0)
- {
- if (read(fd, state, len) == len) done = 1;
- close(fd);
- }
-
- if (!done)
- {
- struct timeval tv;
-
- gettimeofday(&tv, NULL);
- srandom(tv.tv_sec ^ tv.tv_usec);
- return;
- }
-
- if (rand_type != TYPE_0)
- {
- fptr = &state[rand_sep];
- rptr = &state[0];
- }
- initialized = 1;
-}
-
-//
-// initstate
-//
-// Initialize the state information in the given array of n bytes for future
-// random number generation. Based on the number of bytes we are given, and
-// the break values for the different R.N.G.'s, we choose the best (largest)
-// one we can and set things up for it. srandom() is then called to
-// initialize the state information.
-//
-// Note that on return from srandom(), we set state[-1] to be the type
-// multiplexed with the current value of the rear pointer; this is so
-// successive calls to initstate() won't lose this information and will be
-// able to restart with setstate().
-//
-// Note: the first thing we do is save the current state, if any, just like
-// setstate() so that it doesn't matter when initstate is called.
-//
-// Returns a pointer to the old state.
-//
-
-char * RandomGenerator::initstate(unsigned long seed, char *arg_state, long n)
-{
- char *ostate = (char *) (&state[-1]);
- long *long_arg_state = (long *) arg_state;
-
- if (rand_type == TYPE_0)
- state[-1] = rand_type;
- else
- state[-1] = MAX_TYPES * (rptr - state) + rand_type;
-
- if (n < BREAK_0) return NULL;
-
- if (n < BREAK_1)
- {
- rand_type = TYPE_0;
- rand_deg = DEG_0;
- rand_sep = SEP_0;
- }
- else if (n < BREAK_2)
- {
- rand_type = TYPE_1;
- rand_deg = DEG_1;
- rand_sep = SEP_1;
- }
- else if (n < BREAK_3)
- {
- rand_type = TYPE_2;
- rand_deg = DEG_2;
- rand_sep = SEP_2;
- }
- else if (n < BREAK_4)
- {
- rand_type = TYPE_3;
- rand_deg = DEG_3;
- rand_sep = SEP_3;
- }
- else
- {
- rand_type = TYPE_4;
- rand_deg = DEG_4;
- rand_sep = SEP_4;
- }
-
- state = (long *) (long_arg_state + 1); // First location
- end_ptr = &state[rand_deg]; // Must set end_ptr before srandom
- srandom(seed);
-
- if (rand_type == TYPE_0)
- long_arg_state[0] = rand_type;
- else
- long_arg_state[0] = MAX_TYPES * (rptr - state) + rand_type;
-
- initialized = 1;
- return ostate;
-}
-
-//
-// setstate
-//
-// Restore the state from the given state array.
-//
-// Note: it is important that we also remember the locations of the pointers
-// in the current state information, and restore the locations of the pointers
-// from the old state information. This is done by multiplexing the pointer
-// location into the zeroeth word of the state information.
-//
-// Note that due to the order in which things are done, it is OK to call
-// setstate() with the same state as the current state.
-//
-// Returns a pointer to the old state information.
-//
-
-char * RandomGenerator::setstate(char *arg_state)
-{
- long *new_state = (long *) arg_state;
- long type = new_state[0] % MAX_TYPES;
- long rear = new_state[0] / MAX_TYPES;
- char *ostate = (char *) (&state[-1]);
-
- if (rand_type == TYPE_0)
- state[-1] = rand_type;
- else
- state[-1] = MAX_TYPES * (rptr - state) + rand_type;
-
- switch(type)
- {
- case TYPE_0:
- case TYPE_1:
- case TYPE_2:
- case TYPE_3:
- case TYPE_4:
- rand_type = type;
- rand_deg = degrees[type];
- rand_sep = seps[type];
- break;
- }
-
- state = (long *) (new_state + 1);
- if (rand_type != TYPE_0)
- {
- rptr = &state[rear];
- fptr = &state[(rear + rand_sep) % rand_deg];
- }
- end_ptr = &state[rand_deg]; // Set end_ptr too
-
- initialized = 1;
- return ostate;
-}
-#endif //NOT_FOR_SUPERTUX
-//
-// random:
-//
-// If we are using the trivial TYPE_0 R.N.G., just do the old linear
-// congruential bit. Otherwise, we do our fancy trinomial stuff, which is
-// the same in all the other cases due to all the global variables that have
-// been set up. The basic operation is to add the number at the rear pointer
-// into the one at the front pointer. Then both pointers are advanced to
-// the next location cyclically in the table. The value returned is the sum
-// generated, reduced to 31 bits by throwing away the "least random" low bit.
-//
-// Note: the code takes advantage of the fact that both the front and
-// rear pointers can't wrap on the same call by not testing the rear
-// pointer if the front one has wrapped.
-//
-// Returns a 31-bit random number.
-//
-
-long RandomGenerator::random()
-{
- long i;
- long *f, *r;
- if (!initialized) {
- throw std::runtime_error("uninitialized RandomGenerator object");
- }
-
- if (rand_type == TYPE_0)
- {
- i = state[0];
- state[0] = i = (good_rand(i)) & 0x7fffffff;
- }
- else
- {
- f = fptr; r = rptr;
- *f += *r;
- i = (*f >> 1) & 0x7fffffff; // Chucking least random bit
- if (++f >= end_ptr)
- {
- f = state;
- ++r;
- }
- else if (++r >= end_ptr)
- r = state;
-
- fptr = f; rptr = r;
- }
-
- return i;
-}
+++ /dev/null
-// $Id$
-//
-// A strong random number generator
-//
-// Copyright (C) 2006 Allen King
-// Copyright (C) 2002 Michael Ringgaard. All rights reserved.
-// Copyright (C) 1983, 1993 The Regents of the University of California.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions
-// are met:
-//
-// 1. Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// 2. Redistributions in binary form must reproduce the above copyright
-// notice, this list of conditions and the following disclaimer in the
-// documentation and/or other materials provided with the distribution.
-// 3. Neither the name of the project nor the names of its contributors
-// may be used to endorse or promote products derived from this software
-// without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
-// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-// OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-// SUCH DAMAGE.
-
-#ifndef __RANDOM_GENERATOR__
-#define __RANDOM_GENERATOR__
-
-class RandomGenerator
-{
-private:
-// Array versions of the above information to make code run faster --
-// relies on fact that TYPE_i == i.
- static const int TYPE_0 = 0; // Linear congruential
- static const int BREAK_0 = 8;
- static const int DEG_0 = 0;
- static const int SEP_0 = 0;
-
- static const int TYPE_1 = 1; // x**7 + x**3 + 1
- static const int BREAK_1 = 32;
- static const int DEG_1 = 7;
- static const int SEP_1 = 3;
-
- static const int TYPE_2 = 2; // x**15 + x + 1
- static const int BREAK_2 = 64;
- static const int DEG_2 = 15;
- static const int SEP_2 = 1;
-
- static const int TYPE_3 = 3; // x**31 + x**3 + 1
- static const int BREAK_3 = 128;
- static const int DEG_3 = 31;
- static const int SEP_3 = 3;
-
- static const int TYPE_4 = 4; // x**63 + x + 1
- static const int BREAK_4 = 256;
- static const int DEG_4 = 63;
- static const int SEP_4 = 1;
-
- static const int MAX_TYPES = 5; // Max number of types above
-
- bool initialized;
- long degrees[MAX_TYPES];
- long seps [MAX_TYPES];
- long randtbl[DEG_3 + 1];
-
- long *fptr;
- long *rptr;
-
- long *state;
- long rand_type;
- long rand_deg;
- long rand_sep;
- long *end_ptr;
- int debug;
- static const int rand_max = 0x7fffffff; // biggest signed Uint32
-
-public:
- RandomGenerator();
- ~RandomGenerator();
-
-// Documentation of user-visible calls:
-
- // Initialize the RNG with a 31-bit seed
- // if x is zero or absent, calls to time() will get a time-randomized seed
- // the value returned is the value of the seed used.
- int srand(int x=0);
-
- // generate random 31-bit numbers
- // calls to the following return a value evenly distributed between u (or
- // 0 if not specified) and v (or rand_max if not specified). Return
- // values may include u, but never v.
- int rand();
- int rand(int v);
- int rand(int u, int v);
- double randf(double v);
- double randf(double u, double v);
-
- // For Squirrel wrapper, since miniswig (and even squirrel?) doesn't
- // support function overloading or doubles
- int rand1i(int v) { return rand(v); }
- int rand2i(int u, int v) { return rand(u, v); }
- float rand1f(float v)
- { return static_cast<float>(randf(static_cast<double>(v))); }
- float rand2f(float u, float v)
- { return static_cast<float>(randf(static_cast<double>(u),
- static_cast<double>(v))); }
-
-//private:
- void initialize();
- void srandom(unsigned long x);
-// void srandomdev();
-// char *initstate(unsigned long seed, char *arg_state, long n);
-// char *setstate(char *arg_state);
- long random();
-};
-
-extern RandomGenerator systemRandom;
-
-#endif //__RANDOM_GENERATOR__
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#ifndef __REF_HPP__
-#define __REF_HPP__
-
-/** This class behaves like a pointer to a refcounted object, but increments the
- * reference count when new objects are assigned and decrements the refcounter
- * when it's lifetime has experied. (similar to std::auto_ptr)
- */
-template<typename T>
-class Ref
-{
-public:
- Ref(T* object = 0)
- : object(object)
- {
- if(object)
- object->ref();
- }
- Ref(const Ref<T>& other)
- : object(other.object)
- {
- if(object)
- object->ref();
- }
- ~Ref()
- {
- if(object)
- object->unref();
- }
-
- void operator= (const Ref<T>& other)
- {
- *this = other.get();
- }
-
- void operator= (T* object)
- {
- if(object)
- object->ref();
- if(this->object)
- this->object->unref();
- this->object = object;
- }
-
- T* operator ->() const
- {
- return object;
- }
-
- T& operator* () const
- {
- return *object;
- }
-
- operator const T* () const
- {
- return object;
- }
-
- T* get() const
- {
- return object;
- }
-
-private:
- T* object;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// Windstille - A Jump'n Shoot Game
-// Copyright (C) 2005 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#ifndef __REFCOUNTER_HPP__
-#define __REFCOUNTER_HPP__
-
-#include <assert.h>
-
-/**
- * A base class that provides reference counting facilities
- */
-class RefCounter
-{
-public:
- RefCounter()
- : refcount(0)
- { }
-
- /** increases reference count */
- void ref()
- {
- refcount++;
- }
- /** decreases reference count. Destroys the object if the reference count
- * reaches 0
- */
- void unref()
- {
- refcount--;
- if(refcount <= 0) {
- delete this;
- }
- }
-
-protected:
- virtual ~RefCounter()
- {
- assert(refcount == 0);
- }
-
-private:
- int refcount;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2003 Tobias Glaesser <tobi.web@gmx.de>
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#include <config.h>
-
-#include "sprite/sprite_manager.hpp"
-#include "gui/menu.hpp"
-#include "gui/button.hpp"
-#include "resources.hpp"
-#include "file_system.hpp"
-#include "tile_manager.hpp"
-#include "object/gameobjs.hpp"
-#include "object/player.hpp"
-
-MouseCursor* mouse_cursor = NULL;
-
-Font* gold_text = NULL;
-Font* gold_fixed_text = NULL;
-Font* blue_text = NULL;
-Font* gray_text = NULL;
-Font* white_text = NULL;
-Font* white_small_text = NULL;
-Font* white_big_text = NULL;
-
-/* Load graphics/sounds shared between all levels: */
-void load_shared()
-{
- /* Load the mouse-cursor */
- mouse_cursor = new MouseCursor("images/engine/menu/mousecursor.png");
- MouseCursor::set_current(mouse_cursor);
-
- /* Load global images: */
- gold_text = new Font(Font::VARIABLE,
- "images/engine/fonts/gold.png",
- "images/engine/fonts/shadow.png", 16, 18);
- gold_fixed_text = new Font(Font::FIXED,
- "images/engine/fonts/gold.png",
- "images/engine/fonts/shadow.png", 16, 18);
- blue_text = new Font(Font::VARIABLE,
- "images/engine/fonts/blue.png",
- "images/engine/fonts/shadow.png", 16, 18, 3);
- white_text = new Font(Font::VARIABLE,
- "images/engine/fonts/white.png",
- "images/engine/fonts/shadow.png", 16, 18);
- gray_text = new Font(Font::VARIABLE,
- "images/engine/fonts/gray.png",
- "images/engine/fonts/shadow.png", 16, 18);
- white_small_text = new Font(Font::VARIABLE,
- "images/engine/fonts/white-small.png",
- "images/engine/fonts/shadow-small.png", 8, 9, 1);
- white_big_text = new Font(Font::VARIABLE,
- "images/engine/fonts/white-big.png",
- "images/engine/fonts/shadow-big.png", 20, 22, 3);
-
- Menu::default_font = white_text;
- Menu::active_font = blue_text;
- Menu::deactive_font = gray_text;
- Menu::label_font = white_big_text;
- Menu::field_font = gold_text;
-
- Button::info_font = white_small_text;
-
- sprite_manager = new SpriteManager();
- tile_manager = new TileManager("images/tiles.strf");
-
- /* Tuxes: */
- char img_name[1024];
- for (int i = 0; i < GROWING_FRAMES; i++)
- {
- snprintf(img_name, sizeof(img_name), "images/creatures/tux_grow/left-%i.png", i+1);
- growingtux_left[i] = new Surface(img_name);
-
- snprintf(img_name, sizeof(img_name), "images/creatures/tux_grow/right-%i.png", i+1);
- growingtux_right[i] = new Surface(img_name);
- }
-
- small_tux = new TuxBodyParts();
- small_tux->head = 0;
- small_tux->body = sprite_manager->create("images/creatures/tux_small/small-tux-body.sprite");
- small_tux->arms = sprite_manager->create("images/creatures/tux_small/small-tux-arms.sprite");
- small_tux->feet = 0;
-
- big_tux = new TuxBodyParts();
- big_tux->head = sprite_manager->create("images/creatures/tux_big/big-tux-head.sprite");
- big_tux->body = sprite_manager->create("images/creatures/tux_big/big-tux-body.sprite");
- big_tux->arms = sprite_manager->create("images/creatures/tux_big/big-tux-arms.sprite");
- big_tux->feet = sprite_manager->create("images/creatures/tux_big/big-tux-feet.sprite");
-
- fire_tux = new TuxBodyParts();
- fire_tux->head = sprite_manager->create("images/creatures/tux_big/big-fire-tux-head.sprite");
- fire_tux->body = sprite_manager->create("images/creatures/tux_big/big-tux-body.sprite");
- fire_tux->arms = sprite_manager->create("images/creatures/tux_big/big-tux-arms.sprite");
- fire_tux->feet = sprite_manager->create("images/creatures/tux_big/big-tux-feet.sprite");
-
- ice_tux = new TuxBodyParts();
- ice_tux->head = sprite_manager->create("images/creatures/tux_big/big-ice-tux-head.sprite");
- ice_tux->body = sprite_manager->create("images/creatures/tux_big/big-tux-body.sprite");
- ice_tux->arms = sprite_manager->create("images/creatures/tux_big/big-tux-arms.sprite");
- ice_tux->feet = sprite_manager->create("images/creatures/tux_big/big-tux-feet.sprite");
-
- player_status = new PlayerStatus();
-}
-
-/* Free shared data: */
-void unload_shared()
-{
- /* Free global images: */
- delete gold_text;
- delete gold_fixed_text;
- delete white_text;
- delete blue_text;
- delete gray_text;
- delete white_small_text;
- delete white_big_text;
-
- delete small_tux;
- delete big_tux;
- delete fire_tux;
- delete ice_tux;
-
- for (int i = 0; i < GROWING_FRAMES; i++) {
- delete growingtux_left[i];
- delete growingtux_right[i];
- }
-
- delete sprite_manager;
- sprite_manager = NULL;
- delete tile_manager;
- tile_manager = NULL;
-
- /* Free mouse-cursor */
- delete mouse_cursor;
-
- delete player_status;
- player_status = NULL;
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2003 Tobias Glaesser <tobi.web@gmx.de>
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#ifndef SUPERTUX_RESOURCES_H
-#define SUPERTUX_RESOURCES_H
-
-class Font;
-class MouseCursor;
-
-extern MouseCursor* mouse_cursor;
-
-extern Font* gold_text;
-extern Font* gold_fixed_text;
-extern Font* white_text;
-extern Font* blue_text;
-extern Font* gray_text;
-extern Font* white_small_text;
-extern Font* white_big_text;
-
-void load_shared();
-void unload_shared();
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#ifndef __SCREEN_HPP__
-#define __SCREEN_HPP__
-
-class DrawingContext;
-
-class Screen
-{
-public:
- virtual ~Screen()
- {}
-
- /**
- * gets called before this screen gets activated (which is at least once
- * before the first draw or update call
- */
- virtual void setup()
- {}
- /** gets called when the current screen is temporarily suspended */
- virtual void leave()
- {}
-
- /**
- * gets called once per frame. The screen should draw itself in this function.
- * State changes should not be done in this function, but rather in update
- */
- virtual void draw(DrawingContext& context) = 0;
-
- /**
- * gets called for once (per logical) frame. Screens should do their state
- * updates and logic here
- */
- virtual void update(float elapsed_time) = 0;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#ifndef __SCREENFADE_HPP__
-#define __SCREENFADE_HPP__
-
-#include "screen.hpp"
-
-/**
- * A ScreenFade screen is displayed simultaneously with another screen. This
- * is intended to be used for transitional effects like fade-out or shrink-fade
- */
-class ScreenFade : public Screen
-{
-public:
- virtual ~ScreenFade()
- {}
-
- /// returns true if the effect is completed
- virtual bool done() = 0;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#ifndef __SCRIPT_INTERFACE_HPP__
-#define __SCRIPT_INTERFACE_HPP__
-
-#include <squirrel.h>
-
-/**
- * Objects that want to expose themself to the scripting environment
- * should implement this interface
- */
-class ScriptInterface
-{
-public:
- virtual ~ScriptInterface()
- {}
-
- virtual void expose(HSQUIRRELVM vm, SQInteger table_idx) = 0;
- virtual void unexpose(HSQUIRRELVM vm, SQInteger table_idx) = 0;
-};
-
-#endif
+++ /dev/null
-SubDir TOP src scripting ;
-
-if $(MINISWIG)
-{
- ## MiniSwigRule outputcppfile : inputfile : modulename : flags
- rule MiniSwigRule
- {
- local sources = [ SearchSource $(>) ] ;
- local cppfile = [ LocateTarget $(<) : $(SUBDIR) ] ;
- local headerfile = [ LocateTarget $(<:S=.hpp) : $(SUBDIR) ] ;
- SEARCH on $(headerfile) = $(SOURCH_SOURCE) ;
-
- MiniSwig $(cppfile) : $(sources) ;
-
- CPPFLAGS on $(cppfile) = $(CPPFLAGS) -DSCRIPTING_API ;
- headerfile on $(cppfile) = $(headerfile) ;
- modulename on $(cppfile) = $(3) ;
- FLAGS on $(cppfile) = $(4) ;
-
- local h = $(headerfile:G=) ;
- h = $(h:D=) ;
- Includes $(h) : $(headerfile) ;
- Includes $(headerfile) : $(cppfile) ;
-
- local object = [ CompileObject $(cppfile) ] ;
-
- return $(object) ;
- }
-
- rule MiniSwig
- {
- Depends $(<) : $(>) $(MINISWIG) ;
- }
-
- actions MiniSwig bind headerfile
- {
- $(CPP) -x c -CC $(CPPFLAGS) $(>) -o $(LOCATE_OBJECTS)/miniswig.tmp
- ./miniswig --output-cpp $(<) --input $(LOCATE_OBJECTS)/miniswig.tmp --output-hpp $(headerfile) --module $(modulename) $(FLAGS)
-# rm -f $(LOCATE_OBJECTS)/miniswig.tmp
- }
-}
-
-wrapper_sources = [ Filter [ Wildcard *.cpp *.hpp ] : wrapper.cpp wrapper.hpp ] ;
-if ! $(MINISWIG)
-{
- wrapper_sources += [ SearchSource wrapper.cpp ] ;
-}
-wrapper_objects = [ CompileObjects $(wrapper_sources) ] ;
-if $(MINISWIG)
-{
- wrapper_objects +=
- [ MiniSwigRule wrapper.cpp : wrapper.interface.hpp : supertux : --select-namespace Scripting ] ;
-}
-
+++ /dev/null
-#ifndef __SCRIPTING_AMBIENT_SOUND_H__
-#define __SCRIPTING_AMBIENT_SOUND_H__
-
-namespace Scripting
-{
-
-class AmbientSound
-{
-public:
-#ifndef SCRIPTING_API
- virtual ~AmbientSound()
- {}
-#endif
-
- virtual void set_pos(float x, float y) = 0;
- virtual float get_pos_x() const = 0;
- virtual float get_pos_y() const = 0;
-};
-
-}
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __ANCHOR_POINTS_HPP__
-#define __ANCHOR_POINTS_HPP__
-
-namespace Scripting {
-
-// TODO get these from the definitions in anchor.h (needs miniswig update)
-static const int ANCHOR_TOP = 0x0010;
-static const int ANCHOR_BOTTOM = 0x0020;
-static const int ANCHOR_LEFT = 0x0001;
-static const int ANCHOR_RIGHT = 0x0002;
-static const int ANCHOR_MIDDLE = 0x0000;
-static const int ANCHOR_TOP_LEFT = 0x0011;
-static const int ANCHOR_TOP_RIGHT = 0x0012;
-static const int ANCHOR_BOTTOM_LEFT = 0x0021;
-static const int ANCHOR_BOTTOM_RIGHT = 0x0022;
-
-}
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include <string>
-#include <stdio.h>
-#include "object/camera.hpp"
-#include "scripting/camera.hpp"
-#include "math/vector.hpp"
-
-#define NOIMPL log_fatal << __FUNCTION__ << " not implemented."
-
-namespace Scripting
-{
- Camera::Camera(::Camera* camera)
- : camera(camera)
- { }
-
- Camera::~Camera()
- { }
-
- void
- Camera::reload_config()
- {
- camera->reload_config();
- }
-
- void
- Camera::shake(float speed, float x, float y)
- {
- camera->shake(speed, x, y);
- }
-
- void
- Camera::set_pos(float , float )
- {
- }
-
- void
- Camera::set_mode(const std::string& mode)
- {
- if(mode == "normal") {
- camera->mode = ::Camera::NORMAL;
- } else if(mode == "manual") {
- camera->mode = ::Camera::MANUAL;
- } else {
- log_fatal << "Camera mode '" << mode << "' unknown.";
- }
- }
-
- void
- Camera::scroll_to(float x, float y, float scrolltime)
- {
- camera->scroll_to(Vector(x, y), scrolltime);
- }
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __CAMERA_H__
-#define __CAMERA_H__
-
-#ifndef SCRIPTING_API
-class Camera;
-typedef Camera _Camera;
-#endif
-
-namespace Scripting
-{
-
-class Camera
-{
-public:
-#ifndef SCRIPTING_API
- Camera(_Camera* camera);
- ~Camera();
-#endif
-
- void reload_config();
-
- /** Shake the camera */
- void shake(float speed, float x, float y);
- /** Set camera to a specific coordinate */
- void set_pos(float x, float y);
- /** Set camera to a specific mode, can be "normal", "manual" */
- void set_mode(const std::string& mode);
- /** Scroll camera to position x,y in scrolltime seconds */
- void scroll_to(float x, float y, float scrolltime);
-
-#ifndef SCRIPTING_API
- _Camera* camera;
-#endif
-};
-
-}
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include <string>
-#include <stdio.h>
-#include "object/candle.hpp"
-#include "scripting/candle.hpp"
-#include "math/vector.hpp"
-
-#define NOIMPL log_fatal << __PRETTY_FUNCTION__ << " not implemented."
-
-namespace Scripting
-{
-
- Candle::Candle(::Candle* candle)
- : candle(candle)
- { }
-
- Candle::~Candle()
- { }
-
- bool Candle::get_burning()
- {
- return candle->get_burning();
- }
-
- void Candle::set_burning(bool burning)
- {
- candle->set_burning(burning);
- }
-
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __SCRIPTING_CANDLE_H__
-#define __SCRIPTING_CANDLE_H__
-
-#ifndef SCRIPTING_API
-class Candle;
-typedef Candle _Candle;
-#endif
-
-namespace Scripting
-{
-
-class Candle
-{
-public:
-#ifndef SCRIPTING_API
- Candle(_Candle* candle);
- ~Candle();
-#endif
-
- bool get_burning(); /**< returns true if candle is lighted */
- void set_burning(bool burning); /**< true: light candle, false: extinguish candle */
-
-#ifndef SCRIPTING_API
- _Candle* candle;
-#endif
-};
-
-}
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __SCRIPTING_DISPLAY_EFFECT_H__
-#define __SCRIPTING_DISPLAY_EFFECT_H__
-
-namespace Scripting
-{
-
-class DisplayEffect
-{
-public:
-#ifndef SCRIPTING_API
- virtual ~DisplayEffect()
- {}
-#endif
-
- /// fade display to black
- virtual void fade_out(float fadetime) = 0;
- /// fade display from black to normal
- virtual void fade_in(float fadetime) = 0;
- /// set display black (or back to normal)
- virtual void set_black(bool enabled) = 0;
- /// check if display is set to black
- virtual bool is_black() = 0;
- /// set black borders for cutscenes
- virtual void sixteen_to_nine(float fadetime) = 0;
- /// deactivate borders
- virtual void four_to_three(float fadetime) = 0;
-
- // fade display until just a small visible circle is left
- // (like what happens in some cartoons at the end)
- // void shrink_fade(Vector goal, float radius, float fadetime);
-};
-
-}
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#include <config.h>
-
-#include <assert.h>
-#include <stdexcept>
-#include "floating_image.hpp"
-#include "sector.hpp"
-#include "object/floating_image.hpp"
-#include "worldmap/worldmap.hpp"
-
-namespace Scripting
-{
-
-FloatingImage::FloatingImage(const std::string& spritefile)
-{
- using namespace WorldMapNS;
-
- floating_image = new _FloatingImage(spritefile);
- if(Sector::current() != NULL) {
- Sector::current()->add_object(floating_image.get());
- } else if(WorldMap::current() != NULL) {
- WorldMap::current()->add_object(floating_image.get());
- } else {
- throw new std::runtime_error("Neither sector nor worldmap active");
- }
-}
-
-FloatingImage::~FloatingImage()
-{
- floating_image->remove_me();
-}
-
-void
-FloatingImage::set_layer(int layer)
-{
- floating_image->set_layer(layer);
-}
-
-int
-FloatingImage::get_layer()
-{
- return floating_image->get_layer();
-}
-
-void
-FloatingImage::set_pos(float x, float y)
-{
- floating_image->set_pos(Vector(x, y));
-}
-
-float
-FloatingImage::get_pos_x()
-{
- return floating_image->get_pos().x;
-}
-
-float
-FloatingImage::get_pos_y()
-{
- return floating_image->get_pos().y;
-}
-
-void
-FloatingImage::set_anchor_point(int anchor)
-{
- floating_image->set_anchor_point((AnchorPoint) anchor);
-}
-
-int
-FloatingImage::get_anchor_point()
-{
- return (int) floating_image->get_anchor_point();
-}
-
-bool
-FloatingImage::get_visible()
-{
- return floating_image->get_visible();
-}
-
-void
-FloatingImage::set_visible(bool visible)
-{
- floating_image->set_visible(visible);
-}
-
-void
-FloatingImage::set_action(const std::string& action)
-{
- floating_image->set_action(action);
-}
-
-std::string
-FloatingImage::get_action()
-{
- return floating_image->get_action();
-}
-
-void
-FloatingImage::fade_in(float fadetime)
-{
- floating_image->fade_in(fadetime);
-}
-
-void
-FloatingImage::fade_out(float fadetime)
-{
- floating_image->fade_out(fadetime);
-}
-
-
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __FLOATING_IMAGE_HPP__
-#define __FLOATING_IMAGE_HPP__
-
-#ifndef SCRIPTING_API
-#define __suspend
-#include <string>
-#include "ref.hpp"
-
-class FloatingImage;
-typedef FloatingImage _FloatingImage;
-#endif
-
-namespace Scripting
-{
-
-class FloatingImage
-{
-public:
- FloatingImage(const std::string& spritefile);
- ~FloatingImage();
-
- void set_layer(int layer);
- int get_layer();
- void set_pos(float x, float y);
- float get_pos_x();
- float get_pos_y();
- void set_anchor_point(int anchor);
- int get_anchor_point();
- void set_visible(bool visible);
- bool get_visible();
- void set_action(const std::string& action);
- std::string get_action();
- void fade_in(float fadetime);
- void fade_out(float fadetime);
-
-#ifndef SCRIPTING_API
-private:
- Ref<_FloatingImage> floating_image;
-#endif
-};
-
-}
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include <memory>
-#include <stdio.h>
-#include <string>
-#include <squirrel.h>
-#include <sqstdio.h>
-#include "textscroller.hpp"
-#include "functions.hpp"
-#include "game_session.hpp"
-#include "tinygettext/tinygettext.hpp"
-#include "physfs/physfs_stream.hpp"
-#include "resources.hpp"
-#include "gettext.hpp"
-#include "log.hpp"
-#include "mainloop.hpp"
-#include "worldmap/worldmap.hpp"
-#include "world.hpp"
-#include "sector.hpp"
-#include "gameconfig.hpp"
-#include "object/player.hpp"
-#include "object/tilemap.hpp"
-#include "main.hpp"
-#include "fadeout.hpp"
-#include "shrinkfade.hpp"
-#include "object/camera.hpp"
-#include "flip_level_transformer.hpp"
-#include "audio/sound_manager.hpp"
-#include "random_generator.hpp"
-
-#include "squirrel_error.hpp"
-#include "squirrel_util.hpp"
-#include "time_scheduler.hpp"
-
-namespace Scripting
-{
-
-SQInteger display(HSQUIRRELVM vm)
-{
- Console::output << squirrel2string(vm, -1) << std::endl;
- return 0;
-}
-
-void print_stacktrace(HSQUIRRELVM vm)
-{
- print_squirrel_stack(vm);
-}
-
-SQInteger get_current_thread(HSQUIRRELVM vm)
-{
- sq_pushobject(vm, vm_to_object(vm));
- return 1;
-}
-
-void wait(HSQUIRRELVM vm, float seconds)
-{
- TimeScheduler::instance->schedule_thread(vm, game_time + seconds);
-}
-
-void wait_for_screenswitch(HSQUIRRELVM vm)
-{
- main_loop->waiting_threads.add(vm);
-}
-
-void exit_screen()
-{
- main_loop->exit_screen();
-}
-
-void fadeout_screen(float seconds)
-{
- main_loop->set_screen_fade(new FadeOut(seconds));
-}
-
-void shrink_screen(float dest_x, float dest_y, float seconds)
-{
- main_loop->set_screen_fade(new ShrinkFade(Vector(dest_x, dest_y), seconds));
-}
-
-void abort_screenfade()
-{
- main_loop->set_screen_fade(NULL);
-}
-
-std::string translate(const std::string& text)
-{
- return dictionary_manager.get_dictionary().translate(text);
-}
-
-void display_text_file(const std::string& filename)
-{
- main_loop->push_screen(new TextScroller(filename));
-}
-
-void load_worldmap(const std::string& filename)
-{
- using namespace WorldMapNS;
-
- main_loop->push_screen(new WorldMap(filename));
-}
-
-void load_level(const std::string& filename)
-{
- main_loop->push_screen(new GameSession(filename));
-}
-
-static SQInteger squirrel_read_char(SQUserPointer file)
-{
- std::istream* in = reinterpret_cast<std::istream*> (file);
- char c = in->get();
- if(in->eof())
- return 0;
-
- return c;
-}
-
-void import(HSQUIRRELVM vm, const std::string& filename)
-{
- IFileStream in(filename);
-
- if(SQ_FAILED(sq_compile(vm, squirrel_read_char, &in,
- filename.c_str(), SQTrue)))
- throw SquirrelError(vm, "Couldn't parse script");
-
- sq_pushroottable(vm);
- if(SQ_FAILED(sq_call(vm, 1, SQFalse, SQTrue))) {
- sq_pop(vm, 1);
- throw SquirrelError(vm, "Couldn't execute script");
- }
- sq_pop(vm, 1);
-}
-
-void debug_collrects(bool enable)
-{
- Sector::show_collrects = enable;
-}
-
-void debug_show_fps(bool enable)
-{
- config->show_fps = enable;
-}
-
-void debug_draw_solids_only(bool enable)
-{
- Sector::draw_solids_only = enable;
-}
-
-void save_state()
-{
- using namespace WorldMapNS;
-
- if(World::current() == NULL || WorldMap::current() == NULL)
- throw std::runtime_error("Can't save state without active World");
-
- WorldMap::current()->save_state();
- World::current()->save_state();
-}
-
-void update_worldmap()
-{
- using namespace WorldMapNS;
-
- if(WorldMap::current() == NULL)
- throw std::runtime_error("Can't update Worldmap: none active");
-
- WorldMap::current()->load_state();
-}
-
-// not added to header, function to only be used by others
-// in this file
-bool validate_sector_player()
-{
- if (Sector::current() == 0)
- {
- log_info << "No current sector." << std::endl;
- return false;
- }
-
- if (Sector::current()->player == 0)
- {
- log_info << "No player." << std::endl;
- return false;
- }
- return true;
-}
-
-void play_music(const std::string& filename)
-{
- sound_manager->play_music(filename);
-}
-
-void play_sound(const std::string& filename)
-{
- sound_manager->play(filename);
-}
-
-void grease()
-{
- if (!validate_sector_player()) return;
- ::Player* tux = Sector::current()->player; // Scripting::Player != ::Player
- tux->physic.set_velocity_x(tux->physic.get_velocity_x()*3);
-}
-
-void invincible()
-{
- if (!validate_sector_player()) return;
- ::Player* tux = Sector::current()->player;
- tux->invincible_timer.start(10000);
-}
-
-void ghost()
-{
- if (!validate_sector_player()) return;
- ::Player* tux = Sector::current()->player;
- tux->set_ghost_mode(true);
-}
-
-void mortal()
-{
- if (!validate_sector_player()) return;
- ::Player* tux = Sector::current()->player;
- tux->invincible_timer.stop();
- tux->set_ghost_mode(false);
-}
-
-void restart()
-{
- if (GameSession::current() == 0)
- {
- log_info << "No game session" << std::endl;
- return;
- }
- GameSession::current()->restart_level();
-}
-
-void whereami()
-{
- if (!validate_sector_player()) return;
- ::Player* tux = Sector::current()->player;
- log_info << "You are at x " << tux->get_pos().x << ", y " << tux->get_pos().y << std::endl;
-}
-
-void gotoend()
-{
- if (!validate_sector_player()) return;
- ::Player* tux = Sector::current()->player;
- tux->move(Vector(
- (Sector::current()->get_width()) - (SCREEN_WIDTH*2), 0));
- Sector::current()->camera->reset(
- Vector(tux->get_pos().x, tux->get_pos().y));
-}
-
-void camera()
-{
- if (!validate_sector_player()) return;
- log_info << "Camera is at " << Sector::current()->camera->get_translation().x << "," << Sector::current()->camera->get_translation().y << std::endl;
-}
-
-void quit()
-{
- main_loop->quit();
-}
-
-int rand()
-{
- return systemRandom.rand();
-}
-
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __FUNCTIONS_H__
-#define __FUNCTIONS_H__
-
-#ifndef SCRIPTING_API
-#define __suspend
-#define __custom
-#include <string>
-#include "player_status.hpp"
-#endif
-
-namespace Scripting
-{
-
-/**
- * Display the value of the argument. This is usefull for inspecting tables.
- */
-SQInteger display(HSQUIRRELVM vm) __custom;
-
-/**
- * Displays contents of the current stack
- */
-void print_stacktrace(HSQUIRRELVM vm);
-
-/**
- * returns the currently running thread
- */
-SQInteger get_current_thread(HSQUIRRELVM vm) __custom;
-
-/**
- * Display a text file and scrolls it over the screen (on next screenswitch)
- */
-void display_text_file(const std::string& filename);
-
-/**
- * Load and display a worldmap (on next screenswitch)
- */
-void load_worldmap(const std::string& filename);
-
-/**
- * Load and display a level (on next screenswitch)
- */
-void load_level(const std::string& filename);
-
-/**
- * Suspend the script execution for the specified number of seconds
- */
-void wait(HSQUIRRELVM vm, float seconds) __suspend;
-
-/**
- * Suspend the script execution until the current screen has been changed
- */
-void wait_for_screenswitch(HSQUIRRELVM vm) __suspend;
-
-/**
- * Exits the currently running screen (force exit from worldmap or scrolling
- * text for example)
- */
-void exit_screen();
-
-/**
- * Does a fadeout for the specified number of seconds before next screenchange
- */
-void fadeout_screen(float seconds);
-
-/**
- * Does a shrinking fade towards the destposition for the specified number of
- * seconds before next screenchange
- */
-void shrink_screen(float dest_x, float dest_y, float seconds);
-
-/**
- * Aborts any kind of previous screen fade; the screenchange will happen
- * anyway.
- */
-void abort_screenfade();
-
-/**
- * Translate a text into the users language (by looking it up in the .po
- * files)
- */
-std::string translate(const std::string& text);
-
-/**
- * Load a script file and executes it. This is typically used to import
- * functions from external files.
- */
-void import(HSQUIRRELVM v, const std::string& filename);
-
-/**
- * Save world state to savegame
- */
-void save_state();
-
-/**
- * Update worldmap from worldmap state (state.world variable)
- */
-void update_worldmap();
-
-/**
- * enable/disable drawing of collision rectangles
- */
-void debug_collrects(bool enable);
-
-/**
- * enable/disable drawing of fps
- */
-void debug_show_fps(bool enable);
-
-/**
- * enable/disable drawing of non-solid layers
- */
-void debug_draw_solids_only(bool enable);
-
-/**
- * Changes music to musicfile
- */
-void play_music(const std::string& musicfile);
-
-/**
- * Plays a soundfile
- */
-void play_sound(const std::string& soundfile);
-
-/**
- * speeds Tux up
- */
-void grease();
-
-/**
- * makes Tux invincible for 10000 units of time
- */
-void invincible();
-
-/**
- * makes Tux a ghost, i.e. lets him float around and through solid objects
- */
-void ghost();
-
-/**
- * recall Tux's invincibility and ghost status
- */
-void mortal();
-
-/**
- * reinitialise and respawn Tux at the beginning of the current level
- */
-void restart();
-
-/**
- * print Tux's current coordinates in a level
- */
-void whereami();
-
-/**
- * move Tux near the end of the level
- */
-void gotoend();
-
-/**
- * show the camera's coordinates
- */
-void camera();
-
-/**
- * exit the game
- */
-void quit();
-
-/**
- * Returns a random integer
- */
-int rand();
-
-}
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include <string>
-#include <stdio.h>
-#include "level.hpp"
-#include "game_session.hpp"
-#include "flip_level_transformer.hpp"
-
-namespace Scripting
-{
- Level::Level()
- {}
-
- Level::~Level()
- {}
-
- void
- Level::finish(bool win)
- {
- if(GameSession::current() == NULL)
- return;
-
- GameSession::current()->finish(win);
- }
-
- void
- Level::spawn(const std::string& sector, const std::string& spawnpoint)
- {
- if(GameSession::current() == NULL)
- return;
-
- GameSession::current()->respawn(sector, spawnpoint);
- }
-
- void
- Level::flip_vertically()
- {
- FlipLevelTransformer flip_transformer;
- flip_transformer.transform(GameSession::current()->get_current_level());
- }
-
- void
- Level::toggle_pause()
- {
- if(GameSession::current() == NULL)
- return;
- GameSession::current()->toggle_pause();
- }
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __LEVEL_H__
-#define __LEVEL_H__
-
-namespace Scripting
-{
-
-class Level
-{
-public:
-#ifndef SCRIPTING_API
- Level();
- ~Level();
-#endif
-
- /** Instantly finish the currently played level */
- void finish(bool win);
- /** spawn tux at specified sector and spawnpoint */
- void spawn(const std::string& sector, const std::string& spawnpoint);
- /** Flip level vertically */
- void flip_vertically();
- /** toggle pause */
- void toggle_pause();
-};
-
-}
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include <string>
-#include <stdio.h>
-#include "object/level_time.hpp"
-#include "scripting/level_time.hpp"
-#include "math/vector.hpp"
-
-#define NOIMPL log_fatal << __PRETTY_FUNCTION__ << " not implemented."
-
-namespace Scripting
-{
-
- LevelTime::LevelTime(::LevelTime* level_time)
- : level_time(level_time)
- { }
-
- LevelTime::~LevelTime()
- { }
-
- void LevelTime::start()
- {
- level_time->start();
- }
-
- void LevelTime::stop()
- {
- level_time->stop();
- }
-
- float LevelTime::get_time()
- {
- return level_time->get_time();
- }
-
- void LevelTime::set_time(float time_left)
- {
- level_time->set_time(time_left);
- }
-
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __SCRIPTING_LEVELTIME_H__
-#define __SCRIPTING_LEVELTIME_H__
-
-#ifndef SCRIPTING_API
-class LevelTime;
-typedef LevelTime _LevelTime;
-#endif
-
-namespace Scripting
-{
-
-class LevelTime
-{
-public:
-#ifndef SCRIPTING_API
- LevelTime(_LevelTime* level_time);
- ~LevelTime();
-#endif
-
- /**
- * Resumes the countdown
- */
- void start();
-
- /**
- * Pauses the countdown
- */
- void stop();
-
- /**
- * Returns the number of seconds left on the clock
- */
- float get_time();
-
- /**
- * Changes the number of seconds left on the clock
- */
- void set_time(float time_left);
-
-#ifndef SCRIPTING_API
- _LevelTime* level_time;
-#endif
-};
-
-}
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include <string>
-#include <stdio.h>
-#include "object/platform.hpp"
-#include "scripting/platform.hpp"
-#include "math/vector.hpp"
-
-#define NOIMPL log_fatal << __PRETTY_FUNCTION__ << " not implemented."
-
-namespace Scripting
-{
-
- Platform::Platform(::Platform* platform)
- : platform(platform)
- { }
-
- Platform::~Platform()
- { }
-
- void Platform::goto_node(int node_no)
- {
- platform->goto_node(node_no);
- }
-
- void Platform::start_moving()
- {
- platform->start_moving();
- }
-
- void Platform::stop_moving()
- {
- platform->stop_moving();
- }
-
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __SCRIPTING_PLATFORM_H__
-#define __SCRIPTING_PLATFORM_H__
-
-#ifndef SCRIPTING_API
-class Platform;
-typedef Platform _Platform;
-#endif
-
-namespace Scripting
-{
-
-class Platform
-{
-public:
-#ifndef SCRIPTING_API
- Platform(_Platform* platform);
- ~Platform();
-#endif
-
- /** Move platform until at given node, then stop */
- void goto_node(int node_no);
-
- /** Start moving platform */
- void start_moving();
-
- /** Stop platform at next node */
- void stop_moving();
-
-#ifndef SCRIPTING_API
- _Platform* platform;
-#endif
-};
-
-}
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __SCRIPTING_PLAYER_H__
-#define __SCRIPTING_PLAYER_H__
-
-namespace Scripting
-{
-
-class Player
-{
-public:
-#ifndef SCRIPTING_API
- virtual ~Player()
- {}
-#endif
-
- /**
- * Set tux bonus.
- * This can be "grow", "fireflower" or "iceflower" at the moment
- */
- virtual bool add_bonus(const std::string& bonus) = 0;
- /**
- * Give tux more coins
- */
- virtual void add_coins(int count) = 0;
- /**
- * Make tux invicible for a short amount of time
- */
- virtual void make_invincible() = 0;
- /**
- * Deactivate user input for Tux
- */
- virtual void deactivate() = 0;
- /**
- * Give control back to user
- */
- virtual void activate() = 0;
- /**
- * Make Tux walk
- */
- virtual void walk(float speed) = 0;
- /**
- * Set player visible or not visible
- */
- virtual void set_visible(bool visible) = 0;
- /**
- * returns true if the player is currently visible (that is he was not set
- * inivisible by the set_visible method)
- */
- virtual bool get_visible() = 0;
-
- /**
- * Hurts a player, if completely=true then the player will be killed even
- * if he had grow or fireflower bonus
- */
- virtual void kill(bool completely) = 0;
-
- /**
- * Switches ghost mode on/off.
- * Lets Tux float around and through solid objects.
- */
- virtual void set_ghost_mode(bool enable) = 0;
-
- /**
- * Returns whether ghost mode is currently enabled
- */
- virtual bool get_ghost_mode() = 0;
-
- /**
- * play cheer animation.
- * This might need some space and behave in an unpredictable way. Best to use this at level end.
- */
- virtual void do_cheer() = 0;
-
- /**
- * duck down if possible.
- * this won't last long as long as input is enabled.
- */
- virtual void do_duck() = 0;
-
- /**
- * stand back up if possible.
- */
- virtual void do_standup() = 0;
-
- /**
- * do a backflip if possible.
- */
- virtual void do_backflip() = 0;
-
- /**
- * jump in the air if possible
- * sensible values for yspeed are negative - unless we want to jump into the ground of course
- */
- virtual void do_jump(float yspeed) = 0;
-
- /**
- * Orders the current GameSession to start a sequence
- */
- virtual void trigger_sequence(std::string sequence_name) = 0;
-
-};
-
-}
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __SCRIPTED_OBJECT_INTERFACE_H__
-#define __SCRIPTED_OBJECT_INTERFACE_H__
-
-namespace Scripting
-{
-
-class ScriptedObject
-{
-public:
-#ifndef SCRIPTING_API
- virtual ~ScriptedObject()
- {}
-#endif
-
- virtual void set_action(const std::string& animation) = 0;
- virtual std::string get_action() = 0;
-
- virtual void move(float x, float y) = 0;
- virtual void set_pos(float x, float y) = 0;
- virtual float get_pos_x() = 0;
- virtual float get_pos_y() = 0;
-
- virtual void set_velocity(float x, float y) = 0;
- virtual float get_velocity_x() = 0;
- virtual float get_velocity_y() = 0;
-
- virtual void set_visible(bool visible) = 0;
- virtual bool is_visible() = 0;
-
- virtual void set_solid(bool solid) = 0;
- virtual bool is_solid() = 0;
-
- virtual std::string get_name() = 0;
-};
-
-}
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#include <config.h>
-
-#include "serialize.hpp"
-
-#include <memory>
-#include <assert.h>
-#include "lisp/lisp.hpp"
-#include "lisp/list_iterator.hpp"
-#include "lisp/parser.hpp"
-#include "lisp/writer.hpp"
-#include "squirrel_error.hpp"
-
-namespace Scripting
-{
-
-void load_squirrel_table(HSQUIRRELVM vm, SQInteger table_idx, const lisp::Lisp* lisp)
-{
- using namespace lisp;
-
- if(table_idx < 0)
- table_idx -= 2;
-
- lisp::ListIterator iter(lisp);
- while(iter.next() && iter.lisp() != NULL) {
- const std::string& token = iter.item();
- sq_pushstring(vm, token.c_str(), token.size());
-
- const lisp::Lisp* value = iter.value();
- switch(value->get_type()) {
- case Lisp::TYPE_CONS:
- sq_newtable(vm);
- load_squirrel_table(vm, sq_gettop(vm), iter.lisp());
- break;
- case Lisp::TYPE_INTEGER:
- sq_pushinteger(vm, value->get_int());
- break;
- case Lisp::TYPE_REAL:
- sq_pushfloat(vm, value->get_float());
- break;
- case Lisp::TYPE_STRING:
- sq_pushstring(vm, value->get_string().c_str(), -1);
- break;
- case Lisp::TYPE_BOOLEAN:
- sq_pushbool(vm, value->get_bool() ? SQTrue : SQFalse);
- break;
- case Lisp::TYPE_SYMBOL:
- std::cerr << "Unexpected symbol in lisp file...";
- sq_pushnull(vm);
- break;
- default:
- assert(false);
- break;
- }
-
- if(SQ_FAILED(sq_createslot(vm, table_idx)))
- throw Scripting::SquirrelError(vm, "Couldn't create new index");
- }
-}
-
-void save_squirrel_table(HSQUIRRELVM vm, SQInteger table_idx, lisp::Writer& writer)
-{
- // offset because of sq_pushnull
- if(table_idx < 0)
- table_idx -= 1;
-
- //iterator table
- sq_pushnull(vm);
- while(SQ_SUCCEEDED(sq_next(vm, table_idx))) {
- if(sq_gettype(vm, -2) != OT_STRING) {
- std::cerr << "Table contains non-string key\n";
- continue;
- }
- const SQChar* key;
- sq_getstring(vm, -2, &key);
-
- switch(sq_gettype(vm, -1)) {
- case OT_INTEGER: {
- SQInteger val;
- sq_getinteger(vm, -1, &val);
- writer.write_int(key, static_cast<int> (val));
- break;
- }
- case OT_FLOAT: {
- SQFloat val;
- sq_getfloat(vm, -1, &val);
- writer.write_float(key, static_cast<float> (val));
- break;
- }
- case OT_BOOL: {
- SQBool val;
- sq_getbool(vm, -1, &val);
- writer.write_bool(key, val == SQTrue);
- break;
- }
- case OT_STRING: {
- const SQChar* str;
- sq_getstring(vm, -1, &str);
- writer.write_string(key, reinterpret_cast<const char*> (str));
- break;
- }
- case OT_TABLE: {
- writer.start_list(key, true);
- save_squirrel_table(vm, -1, writer);
- writer.end_list(key);
- break;
- }
- case OT_CLOSURE:
- break; // ignore
- case OT_NATIVECLOSURE:
- break;
- default:
- std::cerr << "Can't serialize key '" << key << "' in table.\n";
- break;
- }
- sq_pop(vm, 2);
- }
- sq_pop(vm, 1);
-}
-
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __SERIALIZE_HPP__
-#define __SERIALIZE_HPP__
-
-#include <squirrel.h>
-#include <string>
-#include "lisp/lisp.hpp"
-#include "lisp/writer.hpp"
-
-namespace Scripting
-{
-
- void save_squirrel_table(HSQUIRRELVM vm, SQInteger table_idx, lisp::Writer& writer);
- void load_squirrel_table(HSQUIRRELVM vm, SQInteger table_idx, const lisp::Lisp* lisp);
-
-}
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#include <config.h>
-
-#include "squirrel_error.hpp"
-#include <sstream>
-
-namespace Scripting
-{
-
-SquirrelError::SquirrelError(HSQUIRRELVM v, const std::string& message) throw()
-{
- std::ostringstream msg;
- msg << "Squirrel error: " << message << " (";
- const char* lasterr;
- sq_getlasterror(v);
- if(sq_gettype(v, -1) != OT_STRING)
- {
- lasterr = "no error info";
- }
- else
- {
- sq_getstring(v, -1, &lasterr);
- }
- msg << lasterr << ")";
- sq_pop(v, 1);
- this->message = msg.str();
-}
-
-SquirrelError::~SquirrelError() throw()
-{}
-
-const char*
-SquirrelError::what() const throw()
-{
- return message.c_str();
-}
-
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __SQUIRREL_ERROR_HPP__
-#define __SQUIRREL_ERROR_HPP__
-
-#include <squirrel.h>
-#include <stdexcept>
-
-namespace Scripting
-{
-
-/** Exception class for squirrel errors, it takes a squirrelvm and uses
- * sq_geterror() to retrieve additional information about the last error that
- * occured and creates a readable message from that.
- */
-class SquirrelError : public std::exception
-{
-public:
- SquirrelError(HSQUIRRELVM v, const std::string& message) throw();
- virtual ~SquirrelError() throw();
-
- const char* what() const throw();
-private:
- std::string message;
-};
-
-}
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#include <config.h>
-
-#include <stdexcept>
-#include <sstream>
-#include <stdarg.h>
-#include <squirrel.h>
-#include <sqstdmath.h>
-#include <sqstdblob.h>
-#include <sqstdstring.h>
-#include <sqstdaux.h>
-#include <sqstdio.h>
-#include "squirrel_util.hpp"
-#include "log.hpp"
-#include "level.hpp"
-#include "physfs/physfs_stream.hpp"
-#include "../random_generator.hpp"
-
-#ifdef ENABLE_SQDBG
-#include <sqdbg/sqrdbg.h>
-
-static HSQREMOTEDBG debugger = NULL;
-#endif
-
-namespace Scripting
-{
-
-HSQUIRRELVM global_vm = NULL;
-
-static void printfunc(HSQUIRRELVM, const char* str, ...)
-{
- char buf[4096];
- va_list arglist;
- va_start(arglist, str);
- vsprintf(buf, str, arglist);
- Console::output << (const char*) buf << std::flush;
- va_end(arglist);
-}
-
-void init_squirrel(bool enable_debugger)
-{
- global_vm = sq_open(64);
- if(global_vm == NULL)
- throw std::runtime_error("Couldn't initialize squirrel vm");
-
- if(enable_debugger) {
-#ifdef ENABLE_SQDBG
- sq_enabledebuginfo(global_vm, SQTrue);
- debugger = sq_rdbg_init(global_vm, 1234, SQFalse);
- if(debugger == NULL)
- throw SquirrelError(global_vm, "Couldn't initialize squirrel debugger");
-
- sq_enabledebuginfo(global_vm, SQTrue);
- log_info << "Waiting for debug client..." << std::endl;
- if(SQ_FAILED(sq_rdbg_waitforconnections(debugger)))
- throw SquirrelError(global_vm, "Waiting for debug clients failed");
- log_info << "debug client connected." << std::endl;
-#endif
- }
-
- sq_pushroottable(global_vm);
- if(SQ_FAILED(sqstd_register_bloblib(global_vm)))
- throw SquirrelError(global_vm, "Couldn't register blob lib");
- if(SQ_FAILED(sqstd_register_mathlib(global_vm)))
- throw SquirrelError(global_vm, "Couldn't register math lib");
- if(SQ_FAILED(sqstd_register_stringlib(global_vm)))
- throw SquirrelError(global_vm, "Couldn't register string lib");
-
- // remove rand and srand calls from sqstdmath, we'll provide our own
- sq_pushstring(global_vm, "srand", -1);
- sq_deleteslot(global_vm, -2, SQFalse);
- sq_pushstring(global_vm, "rand", -1);
- sq_deleteslot(global_vm, -2, SQFalse);
-
- // register supertux API
- register_supertux_wrapper(global_vm);
-
- // TODO remove this at some point... it shoud just be functions not an object
- expose_object(global_vm, -1, new Scripting::Level(), "Level", true);
-
- sq_pop(global_vm, 1);
-
- // register print function
- sq_setprintfunc(global_vm, printfunc);
- // register default error handlers
- sqstd_seterrorhandlers(global_vm);
-
- // try to load default script
- try {
- std::string filename = "scripts/default.nut";
- IFileStream stream(filename);
- Scripting::compile_and_run(global_vm, stream, filename);
- } catch(std::exception& e) {
- log_warning << "Couldn't load default.nut: " << e.what() << std::endl;
- }
-}
-
-void exit_squirrel()
-{
-#ifdef ENABLE_SQDBG
- if(debugger != NULL) {
- sq_rdbg_shutdown(debugger);
- debugger = NULL;
- }
-#endif
-
- if (global_vm)
- sq_close(global_vm);
-
- global_vm = NULL;
-}
-
-void update_debugger()
-{
-#ifdef ENABLE_SQDBG
- if(debugger != NULL)
- sq_rdbg_update(debugger);
-#endif
-}
-
-std::string squirrel2string(HSQUIRRELVM v, SQInteger i)
-{
- std::ostringstream os;
- switch(sq_gettype(v, i))
- {
- case OT_NULL:
- os << "<null>";
- break;
- case OT_BOOL: {
- SQBool p;
- sq_getbool(v, i, &p);
- if (p)
- os << "true";
- else
- os << "false";
- break;
- }
- case OT_INTEGER: {
- SQInteger val;
- sq_getinteger(v, i, &val);
- os << val;
- break;
- }
- case OT_FLOAT: {
- SQFloat val;
- sq_getfloat(v, i, &val);
- os << val;
- break;
- }
- case OT_STRING: {
- const SQChar* val;
- sq_getstring(v, i, &val);
- os << "\"" << val << "\"";
- break;
- }
- case OT_TABLE: {
- bool first = true;
- os << "{";
- sq_pushnull(v); //null iterator
- while(SQ_SUCCEEDED(sq_next(v,i-1)))
- {
- if (!first) {
- os << ", ";
- }
- first = false;
-
- //here -1 is the value and -2 is the key
- os << squirrel2string(v, -2) << " => "
- << squirrel2string(v, -1);
-
- sq_pop(v,2); //pops key and val before the nex iteration
- }
- sq_pop(v, 1);
- os << "}";
- break;
- }
- case OT_ARRAY: {
- bool first = true;
- os << "[";
- sq_pushnull(v); //null iterator
- while(SQ_SUCCEEDED(sq_next(v,i-1)))
- {
- if (!first) {
- os << ", ";
- }
- first = false;
-
- //here -1 is the value and -2 is the key
- // we ignore the key, since that is just the index in an array
- os << squirrel2string(v, -1);
-
- sq_pop(v,2); //pops key and val before the nex iteration
- }
- sq_pop(v, 1);
- os << "]";
- break;
- }
- case OT_USERDATA:
- os << "<userdata>";
- break;
- case OT_CLOSURE:
- os << "<closure>";
- break;
- case OT_NATIVECLOSURE:
- os << "<native closure>";
- break;
- case OT_GENERATOR:
- os << "<generator>";
- break;
- case OT_USERPOINTER:
- os << "userpointer";
- break;
- case OT_THREAD:
- os << "<thread>";
- break;
- case OT_CLASS:
- os << "<class>";
- break;
- case OT_INSTANCE:
- os << "<instance>";
- break;
- case OT_WEAKREF:
- os << "<weakref>";
- break;
- default:
- os << "<unknown>";
- break;
- }
- return os.str();
-}
-
-void print_squirrel_stack(HSQUIRRELVM v)
-{
- printf("--------------------------------------------------------------\n");
- int count = sq_gettop(v);
- for(int i = 1; i <= count; ++i) {
- printf("%d: ",i);
- switch(sq_gettype(v, i))
- {
- case OT_NULL:
- printf("null");
- break;
- case OT_INTEGER: {
- SQInteger val;
- sq_getinteger(v, i, &val);
- printf("integer (%d)", static_cast<int> (val));
- break;
- }
- case OT_FLOAT: {
- SQFloat val;
- sq_getfloat(v, i, &val);
- printf("float (%f)", val);
- break;
- }
- case OT_STRING: {
- const SQChar* val;
- sq_getstring(v, i, &val);
- printf("string (%s)", val);
- break;
- }
- case OT_TABLE:
- printf("table");
- break;
- case OT_ARRAY:
- printf("array");
- break;
- case OT_USERDATA:
- printf("userdata");
- break;
- case OT_CLOSURE:
- printf("closure(function)");
- break;
- case OT_NATIVECLOSURE:
- printf("native closure(C function)");
- break;
- case OT_GENERATOR:
- printf("generator");
- break;
- case OT_USERPOINTER:
- printf("userpointer");
- break;
- case OT_THREAD:
- printf("thread");
- break;
- case OT_CLASS:
- printf("class");
- break;
- case OT_INSTANCE:
- printf("instance");
- break;
- case OT_WEAKREF:
- printf("weakref");
- break;
- default:
- printf("unknown?!?");
- break;
- }
- printf("\n");
- }
- printf("--------------------------------------------------------------\n");
-}
-
-static SQInteger squirrel_read_char(SQUserPointer file)
-{
- std::istream* in = reinterpret_cast<std::istream*> (file);
- char c = in->get();
- if(in->eof())
- return 0;
- return c;
-}
-
-void compile_script(HSQUIRRELVM vm, std::istream& in, const std::string& sourcename)
-{
- if(SQ_FAILED(sq_compile(vm, squirrel_read_char, &in, sourcename.c_str(), true)))
- throw SquirrelError(vm, "Couldn't parse script");
-}
-
-void compile_and_run(HSQUIRRELVM vm, std::istream& in,
- const std::string& sourcename)
-{
- compile_script(vm, in, sourcename);
-
- SQInteger oldtop = sq_gettop(vm);
-
- try {
- sq_pushroottable(vm);
- if(SQ_FAILED(sq_call(vm, 1, SQFalse, SQTrue)))
- throw SquirrelError(vm, "Couldn't start script");
- } catch(...) {
- sq_settop(vm, oldtop);
- throw;
- }
-
- // we can remove the closure in case the script was not suspended
- if(sq_getvmstate(vm) != SQ_VMSTATE_SUSPENDED) {
- sq_settop(vm, oldtop-1);
- }
-}
-
-HSQOBJECT create_thread(HSQUIRRELVM vm)
-{
- HSQUIRRELVM new_vm = sq_newthread(vm, 64);
- if(new_vm == NULL)
- throw SquirrelError(vm, "Couldn't create new VM");
-
- HSQOBJECT vm_object;
- sq_resetobject(&vm_object);
- if(SQ_FAILED(sq_getstackobj(vm, -1, &vm_object)))
- throw SquirrelError(vm, "Couldn't get squirrel thread from stack");
- sq_addref(vm, &vm_object);
-
- sq_pop(vm, 1);
-
- return vm_object;
-}
-
-HSQOBJECT vm_to_object(HSQUIRRELVM vm)
-{
- HSQOBJECT object;
- sq_resetobject(&object);
- object._unVal.pThread = vm;
- object._type = OT_THREAD;
-
- return object;
-}
-
-HSQUIRRELVM object_to_vm(HSQOBJECT object)
-{
- if(object._type != OT_THREAD)
- return NULL;
-
- return object._unVal.pThread;
-}
-
-// begin: serialization functions
-
-void store_float(HSQUIRRELVM vm, const char* name, float val)
-{
- sq_pushstring(vm, name, -1);
- sq_pushfloat(vm, val);
- if(SQ_FAILED(sq_createslot(vm, -3)))
- throw Scripting::SquirrelError(vm, "Couldn't add float value to table");
-}
-
-void store_int(HSQUIRRELVM vm, const char* name, int val)
-{
- sq_pushstring(vm, name, -1);
- sq_pushinteger(vm, val);
- if(SQ_FAILED(sq_createslot(vm, -3)))
- throw Scripting::SquirrelError(vm, "Couldn't add int value to table");
-}
-
-void store_string(HSQUIRRELVM vm, const char* name, const std::string& val)
-{
- sq_pushstring(vm, name, -1);
- sq_pushstring(vm, val.c_str(), val.length());
- if(SQ_FAILED(sq_createslot(vm, -3)))
- throw Scripting::SquirrelError(vm, "Couldn't add float value to table");
-}
-
-void store_bool(HSQUIRRELVM vm, const char* name, bool val)
-{
- sq_pushstring(vm, name, -1);
- sq_pushbool(vm, val ? SQTrue : SQFalse);
- if(SQ_FAILED(sq_createslot(vm, -3)))
- throw Scripting::SquirrelError(vm, "Couldn't add float value to table");
-}
-
-bool has_float(HSQUIRRELVM vm, const char* name)
-{
- sq_pushstring(vm, name, -1);
- if (SQ_FAILED(sq_get(vm, -2))) return false;
- sq_pop(vm, 1);
- return true;
-}
-
-bool has_int(HSQUIRRELVM vm, const char* name)
-{
- return has_float(vm, name);
-}
-
-bool has_string(HSQUIRRELVM vm, const char* name)
-{
- return has_float(vm, name);
-}
-
-bool has_bool(HSQUIRRELVM vm, const char* name)
-{
- return has_float(vm, name);
-}
-
-float read_float(HSQUIRRELVM vm, const char* name)
-{
- sq_pushstring(vm, name, -1);
- if(SQ_FAILED(sq_get(vm, -2))) {
- std::ostringstream msg;
- msg << "Couldn't get float value for '" << name << "' from table";
- throw Scripting::SquirrelError(vm, msg.str());
- }
-
- float result;
- if(SQ_FAILED(sq_getfloat(vm, -1, &result))) {
- std::ostringstream msg;
- msg << "Couldn't get float value for '" << name << "' from table";
- throw Scripting::SquirrelError(vm, msg.str());
- }
- sq_pop(vm, 1);
-
- return result;
-}
-
-int read_int(HSQUIRRELVM vm, const char* name)
-{
- sq_pushstring(vm, name, -1);
- if(SQ_FAILED(sq_get(vm, -2))) {
- std::ostringstream msg;
- msg << "Couldn't get int value for '" << name << "' from table";
- throw Scripting::SquirrelError(vm, msg.str());
- }
-
- SQInteger result;
- if(SQ_FAILED(sq_getinteger(vm, -1, &result))) {
- std::ostringstream msg;
- msg << "Couldn't get int value for '" << name << "' from table";
- throw Scripting::SquirrelError(vm, msg.str());
- }
- sq_pop(vm, 1);
-
- return result;
-}
-
-
-std::string read_string(HSQUIRRELVM vm, const char* name)
-{
- sq_pushstring(vm, name, -1);
- if(SQ_FAILED(sq_get(vm, -2))) {
- std::ostringstream msg;
- msg << "Couldn't get string value for '" << name << "' from table";
- throw Scripting::SquirrelError(vm, msg.str());
- }
-
- const char* result;
- if(SQ_FAILED(sq_getstring(vm, -1, &result))) {
- std::ostringstream msg;
- msg << "Couldn't get string value for '" << name << "' from table";
- throw Scripting::SquirrelError(vm, msg.str());
- }
- sq_pop(vm, 1);
-
- return std::string(result);
-}
-
-bool read_bool(HSQUIRRELVM vm, const char* name)
-{
- sq_pushstring(vm, name, -1);
- if(SQ_FAILED(sq_get(vm, -2))) {
- std::ostringstream msg;
- msg << "Couldn't get bool value for '" << name << "' from table";
- throw Scripting::SquirrelError(vm, msg.str());
- }
-
- SQBool result;
- if(SQ_FAILED(sq_getbool(vm, -1, &result))) {
- std::ostringstream msg;
- msg << "Couldn't get bool value for '" << name << "' from table";
- throw Scripting::SquirrelError(vm, msg.str());
- }
- sq_pop(vm, 1);
-
- return result == SQTrue;
-}
-
-bool get_float(HSQUIRRELVM vm, const char* name, float& val) {
- if (!has_float(vm, name)) return false;
- val = read_float(vm, name);
- return true;
-}
-
-bool get_int(HSQUIRRELVM vm, const char* name, int& val) {
- if (!has_int(vm, name)) return false;
- val = read_int(vm, name);
- return true;
-}
-
-bool get_string(HSQUIRRELVM vm, const char* name, std::string& val) {
- if (!has_string(vm, name)) return false;
- val = read_string(vm, name);
- return true;
-}
-
-bool get_bool(HSQUIRRELVM vm, const char* name, bool& val) {
- if (!has_bool(vm, name)) return false;
- val = read_bool(vm, name);
- return true;
-}
-
-// end: serialization functions
-
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#ifndef __SQUIRREL_UTIL_HPP__
-#define __SQUIRREL_UTIL_HPP__
-
-#include <squirrel.h>
-#include <sstream>
-#include <stdexcept>
-#include <string>
-#include "wrapper.hpp"
-#include "squirrel_error.hpp"
-
-namespace Scripting
-{
-
- extern HSQUIRRELVM global_vm;
-
- void init_squirrel(bool enable_debugger);
- void exit_squirrel();
- void update_debugger();
-
- std::string squirrel2string(HSQUIRRELVM vm, SQInteger i);
- void print_squirrel_stack(HSQUIRRELVM vm);
-
- HSQOBJECT create_thread(HSQUIRRELVM vm);
- SQObject vm_to_object(HSQUIRRELVM vm);
- HSQUIRRELVM object_to_vm(HSQOBJECT object);
-
- void compile_script(HSQUIRRELVM vm, std::istream& in,
- const std::string& sourcename);
- void compile_and_run(HSQUIRRELVM vm, std::istream& in,
- const std::string& sourcename);
-
- template<typename T>
- void expose_object(HSQUIRRELVM v, SQInteger table_idx, T* object,
- const std::string& name, bool free = false)
- {
- sq_pushstring(v, name.c_str(), -1);
- Scripting::create_squirrel_instance(v, object, free);
-
- if(table_idx < 0)
- table_idx -= 2;
-
- // register instance in root table
- if(SQ_FAILED(sq_createslot(v, table_idx))) {
- std::ostringstream msg;
- msg << "Couldn't register object '" << name << "' in squirrel table";
- throw Scripting::SquirrelError(v, msg.str());
- }
- }
-
- static inline void unexpose_object(HSQUIRRELVM v, SQInteger table_idx,
- const std::string& name)
- {
- sq_pushstring(v, name.c_str(), name.length());
-
- if(table_idx < 0)
- table_idx -= 1;
-
- if(SQ_FAILED(sq_deleteslot(v, table_idx, SQFalse))) {
- std::ostringstream msg;
- msg << "Couldn't unregister object '" << name << "' in squirrel root table";
- throw Scripting::SquirrelError(v, msg.str());
- }
- }
-
- // begin serialization functions
- void store_float(HSQUIRRELVM vm, const char* name, float val);
- void store_int(HSQUIRRELVM vm, const char* name, int val);
- void store_string(HSQUIRRELVM vm, const char* name, const std::string& val);
- void store_bool(HSQUIRRELVM vm, const char* name, bool val);
-
- bool has_float(HSQUIRRELVM vm, const char* name);
- bool has_int(HSQUIRRELVM vm, const char* name);
- bool has_string(HSQUIRRELVM vm, const char* name);
- bool has_bool(HSQUIRRELVM vm, const char* name);
-
- bool get_float(HSQUIRRELVM vm, const char* name, float& val);
- bool get_int(HSQUIRRELVM vm, const char* name, int& val);
- bool get_string(HSQUIRRELVM vm, const char* name, std::string& val);
- bool get_bool(HSQUIRRELVM vm, const char* name, bool& val);
-
- float read_float(HSQUIRRELVM vm, const char* name);
- int read_int(HSQUIRRELVM vm, const char* name);
- std::string read_string(HSQUIRRELVM vm, const char* name);
- bool read_bool(HSQUIRRELVM vm, const char* name);
- // end serialization functions
-
-}
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux - Sector Scripting
-// Copyright (C) 2006 Wolfgang Becker <uafr@gmx.de>
-//
-// 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.
-
-#ifndef __SECTOR_H__
-#define __SECTOR_H__
-
-namespace Scripting
-{
-
-class SSector
-{
-public:
-#ifndef SCRIPTING_API
- virtual ~SSector()
- {}
-#endif
- virtual void set_ambient_light(float red, float green, float blue) = 0;
- virtual float get_ambient_red() = 0;
- virtual float get_ambient_green() = 0;
- virtual float get_ambient_blue() = 0;
-};
-
-}
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __TEXT_H__
-#define __TEXT_H__
-
-namespace Scripting
-{
-
-class Text
-{
-public:
-#ifndef SCRIPTING_API
- virtual ~Text()
- { }
-#endif
-
- virtual void set_text(const std::string& text) = 0;
- virtual void set_font(const std::string& fontname) = 0;
- virtual void fade_in(float fadetime) = 0;
- virtual void fade_out(float fadetime) = 0;
- virtual void set_visible(bool visible) = 0;
- virtual void set_centered(bool centered) = 0;
- virtual void set_pos(float x, float y) = 0;
- virtual float get_pos_x() = 0;
- virtual float get_pos_y() = 0;
- virtual void set_anchor_point(int anchor) = 0;
- virtual int get_anchor_point() = 0;
-};
-
-}
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#include <config.h>
-
-#include "thread_queue.hpp"
-#include "squirrel_util.hpp"
-#include "log.hpp"
-
-namespace Scripting
-{
-
-ThreadQueue::ThreadQueue()
-{
-}
-
-ThreadQueue::~ThreadQueue()
-{
-}
-
-void
-ThreadQueue::add(HSQUIRRELVM vm)
-{
- // create a weakref to the VM
- HSQOBJECT vm_obj = vm_to_object(vm);
- sq_pushobject(global_vm, vm_obj);
- sq_weakref(global_vm, -1);
-
- HSQOBJECT object;
- if(SQ_FAILED(sq_getstackobj(global_vm, -1, &object))) {
- sq_pop(global_vm, 2);
- throw SquirrelError(global_vm, "Couldn't get thread weakref from vm");
- }
- sq_addref(global_vm, &object);
- threads.push_back(object);
-
- sq_pop(global_vm, 2);
-}
-
-void
-ThreadQueue::wakeup()
-{
- // we traverse the list in reverse orders and use indices. This should be
- // robust for scripts that add new entries to the list while we're traversing
- // it
- size_t i = threads.size() - 1;
- size_t end = (size_t) 0 - 1;
- size_t size_begin = threads.size();
- while(i != end) {
- HSQOBJECT object = threads[i];
-
- sq_pushobject(global_vm, object);
- sq_getweakrefval(global_vm, -1);
-
- HSQUIRRELVM scheduled_vm;
- if(sq_gettype(global_vm, -1) == OT_THREAD &&
- SQ_SUCCEEDED(sq_getthread(global_vm, -1, &scheduled_vm))) {
- if(SQ_FAILED(sq_wakeupvm(scheduled_vm, SQFalse, SQFalse, SQTrue))) {
- log_warning << "Couldn't wakeup scheduled squirrel VM" << std::endl;
- }
- }
-
- sq_release(global_vm, &object);
- sq_pop(global_vm, 1);
- i--;
- }
-
- threads.erase(threads.begin(), threads.begin() + size_begin);
-}
-
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#ifndef __THREAD_QUEUE_HPP__
-#define __THREAD_QUEUE_HPP__
-
-#include <vector>
-#include <squirrel.h>
-
-namespace Scripting
-{
-
-/**
- * Keeps a list of SquirrelThreads that wait for a wakeup event
- */
-class ThreadQueue
-{
-public:
- ThreadQueue();
- virtual ~ThreadQueue();
-
- /// adds a thread (actually a weakref to the thread)
- void add(HSQUIRRELVM vm);
- /// wakes up threads in the list
- void wakeup();
-
-private:
- typedef std::vector<HSQOBJECT> ThreadList;
- ThreadList threads;
-};
-
-}
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include <string>
-#include <stdio.h>
-#include "object/thunderstorm.hpp"
-#include "scripting/thunderstorm.hpp"
-#include "math/vector.hpp"
-
-#define NOIMPL log_fatal << __PRETTY_FUNCTION__ << " not implemented."
-
-namespace Scripting
-{
-
- Thunderstorm::Thunderstorm(::Thunderstorm* thunderstorm)
- : thunderstorm(thunderstorm)
- {
- }
-
- Thunderstorm::~Thunderstorm()
- {
- }
-
- void Thunderstorm::start()
- {
- thunderstorm->start();
- }
-
- void Thunderstorm::stop()
- {
- thunderstorm->stop();
- }
-
- void Thunderstorm::thunder()
- {
- thunderstorm->thunder();
- }
-
- void Thunderstorm::lightning()
- {
- thunderstorm->lightning();
- }
-
- void Thunderstorm::flash()
- {
- thunderstorm->flash();
- }
-
- void Thunderstorm::electrify()
- {
- thunderstorm->electrify();
- }
-
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __SCRIPTING_THUNDERSTORM_H__
-#define __SCRIPTING_THUNDERSTORM_H__
-
-#ifndef SCRIPTING_API
-class Thunderstorm;
-typedef Thunderstorm _Thunderstorm;
-#endif
-
-namespace Scripting
-{
-
-class Thunderstorm
-{
-public:
-#ifndef SCRIPTING_API
- Thunderstorm(_Thunderstorm* thunderstorm);
- ~Thunderstorm();
-#endif
-
- /**
- * Start playing thunder and lightning at configured interval
- */
- void start();
-
- /**
- * Stop playing thunder and lightning at configured interval
- */
- void stop();
-
- /**
- * Play thunder
- */
- void thunder();
-
- /**
- * Play lightning, i.e. call flash() and electrify()
- */
- void lightning();
-
- /**
- * Display a nice flash
- */
- void flash();
-
- /**
- * Electrify water throughout the whole sector for a short time
- */
- void electrify();
-
-#ifndef SCRIPTING_API
- _Thunderstorm* thunderstorm;
-#endif
-};
-
-}
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include <string>
-#include <stdio.h>
-#include "object/tilemap.hpp"
-#include "scripting/tilemap.hpp"
-#include "math/vector.hpp"
-
-#define NOIMPL log_fatal << __PRETTY_FUNCTION__ << " not implemented."
-
-namespace Scripting
-{
-
- TileMap::TileMap(::TileMap* tilemap)
- : tilemap(tilemap)
- { }
-
- TileMap::~TileMap()
- { }
-
- void TileMap::goto_node(int node_no)
- {
- tilemap->goto_node(node_no);
- }
-
- void TileMap::start_moving()
- {
- tilemap->start_moving();
- }
-
- void TileMap::stop_moving()
- {
- tilemap->stop_moving();
- }
-
- void TileMap::fade(float alpha, float seconds)
- {
- tilemap->fade(alpha, seconds);
- }
-
- void TileMap::set_alpha(float alpha)
- {
- tilemap->set_alpha(alpha);
- }
-
- float TileMap::get_alpha()
- {
- return tilemap->get_alpha();
- }
-
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __SCRIPTING_TILEMAP_H__
-#define __SCRIPTING_TILEMAP_H__
-
-#ifndef SCRIPTING_API
-class TileMap;
-typedef TileMap _TileMap;
-#endif
-
-namespace Scripting
-{
-
-class TileMap
-{
-public:
-#ifndef SCRIPTING_API
- TileMap(_TileMap* tilemap);
- ~TileMap();
-#endif
-
- /** Move tilemap until at given node, then stop */
- void goto_node(int node_no);
-
- /** Start moving tilemap */
- void start_moving();
-
- /** Stop tilemap at next node */
- void stop_moving();
-
- /**
- * Start fading the tilemap to opacity given by @c alpha.
- * Destination opacity will be reached after @c seconds seconds. Also influences solidity.
- */
- void fade(float alpha, float seconds);
-
- /**
- * Instantly switch tilemap's opacity to @c alpha. Also influences solidity.
- */
- void set_alpha(float alpha);
-
- /**
- * Return tilemap's opacity. Note that while the tilemap is fading in or out, this will return the current alpha value, not the target alpha.
- */
- float get_alpha();
-
-#ifndef SCRIPTING_API
- _TileMap* tilemap;
-#endif
-};
-
-}
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#include <config.h>
-
-#include <algorithm>
-
-#include "time_scheduler.hpp"
-#include "squirrel_util.hpp"
-#include "squirrel_error.hpp"
-#include "log.hpp"
-
-namespace Scripting
-{
-
-TimeScheduler* TimeScheduler::instance = NULL;
-
-TimeScheduler::TimeScheduler()
-{
-}
-
-TimeScheduler::~TimeScheduler()
-{
-}
-
-void
-TimeScheduler::update(float time)
-{
- while(!schedule.empty() && schedule.front().wakeup_time < time) {
- HSQOBJECT thread_ref = schedule.front().thread_ref;
-
- sq_pushobject(global_vm, thread_ref);
- sq_getweakrefval(global_vm, -1);
-
- HSQUIRRELVM scheduled_vm;
- if(sq_gettype(global_vm, -1) == OT_THREAD &&
- SQ_SUCCEEDED(sq_getthread(global_vm, -1, &scheduled_vm))) {
- if(SQ_FAILED(sq_wakeupvm(scheduled_vm, SQFalse, SQFalse, SQTrue))) {
- std::ostringstream msg;
- msg << "Couldn't wakeup scheduled squirrel VM: ";
- sq_getlasterror(scheduled_vm);
- if(sq_gettype(scheduled_vm, -1) != OT_STRING) {
- msg << "(no info)";
- } else {
- const char* lasterr;
- sq_getstring(scheduled_vm, -1, &lasterr);
- msg << lasterr;
- }
- log_warning << msg.str() << std::endl;
- sq_pop(scheduled_vm, 1);
- }
- }
-
- sq_release(global_vm, &thread_ref);
- sq_pop(global_vm, 2);
-
- std::pop_heap(schedule.begin(), schedule.end());
- schedule.pop_back();
- }
-}
-
-void
-TimeScheduler::schedule_thread(HSQUIRRELVM scheduled_vm, float time)
-{
- // create a weakref to the VM
- SQObject vm_obj = vm_to_object(scheduled_vm);
- sq_pushobject(global_vm, vm_obj);
- sq_weakref(global_vm, -1);
-
- ScheduleEntry entry;
- if(SQ_FAILED(sq_getstackobj(global_vm, -1, & entry.thread_ref))) {
- sq_pop(global_vm, 2);
- throw SquirrelError(global_vm, "Couldn't get thread weakref from vm");
- }
- entry.wakeup_time = time;
-
- sq_addref(global_vm, & entry.thread_ref);
- sq_pop(global_vm, 2);
-
- schedule.push_back(entry);
- std::push_heap(schedule.begin(), schedule.end());
-}
-
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#ifndef __TIME_SCHEDULER_HPP__
-#define __TIME_SCHEDULER_HPP__
-
-#include <vector>
-#include <squirrel.h>
-
-namespace Scripting
-{
-
-/**
- * This class keeps a list of squirrel threads that are scheduled for a certain
- * time. (the typical result of a wait() command in a squirrel script)
- */
-class TimeScheduler
-{
-public:
- TimeScheduler();
- virtual ~TimeScheduler();
-
- void update(float time);
- void schedule_thread(HSQUIRRELVM vm, float time);
-
- static TimeScheduler* instance;
-
-private:
- struct ScheduleEntry {
- /// weak reference to the squirrel vm object
- HSQOBJECT thread_ref;
- /// time when the thread should be woken up
- float wakeup_time;
-
- bool operator<(const ScheduleEntry& other) const
- {
- // we need the smallest value on top
- return wakeup_time > other.wakeup_time;
- }
- };
-
- typedef std::vector<ScheduleEntry> ScheduleHeap;
- ScheduleHeap schedule;
-};
-
-}
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2007 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __SCRIPTING_WILLOWISP_H__
-#define __SCRIPTING_WILLOWISP_H__
-
-namespace Scripting
-{
-
-class WillOWisp
-{
-public:
-#ifndef SCRIPTING_API
- virtual ~WillOWisp()
- {}
-#endif
-
- /** Move willowisp to given node */
- virtual void goto_node(int node_no) = 0;
-
- /** set willowisp state can be:
- * -stopped willowisp doesn't move
- * -move_path willowisp moves along the path (call goto_node)
- * -move_path_track willowisp moves along path but catchs tux when he is near
- * -normal "normal" mode starts tracking tux when he is near enough
- * -vanish vanish
- */
- virtual void set_state(const std::string& state) = 0;
-
- virtual void start_moving() = 0;
- virtual void stop_moving() = 0;
-};
-
-}
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include <string>
-#include <stdio.h>
-#include "object/wind.hpp"
-#include "scripting/wind.hpp"
-#include "math/vector.hpp"
-
-#define NOIMPL log_fatal << __PRETTY_FUNCTION__ << " not implemented."
-
-namespace Scripting
-{
-
- Wind::Wind(::Wind* wind)
- : wind(wind)
- { }
-
- Wind::~Wind()
- { }
-
- void Wind::start()
- {
- wind->start();
- }
-
- void Wind::stop()
- {
- wind->stop();
- }
-
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __SCRIPTING_WIND_H__
-#define __SCRIPTING_WIND_H__
-
-#ifndef SCRIPTING_API
-class Wind;
-typedef Wind _Wind;
-#endif
-
-namespace Scripting
-{
-
-class Wind
-{
-public:
-#ifndef SCRIPTING_API
- Wind(_Wind* wind);
- ~Wind();
-#endif
-
- /** Start wind */
- void start();
-
- /** Stop wind */
- void stop();
-
-#ifndef SCRIPTING_API
- _Wind* wind;
-#endif
-};
-
-}
-
-#endif
+++ /dev/null
-/**
- * WARNING: This file is automatically generated from:
- * 'src/scripting/wrapper.interface.hpp'
- * DO NOT CHANGE
- */
-#include <config.h>
-
-#include <new>
-#include <assert.h>
-#include <string>
-#include <sstream>
-#include <squirrel.h>
-#include "squirrel_error.hpp"
-#include "wrapper.interface.hpp"
-
-namespace Scripting
-{
-namespace Wrapper
-{
-
-static SQInteger DisplayEffect_release_hook(SQUserPointer ptr, SQInteger )
-{
- Scripting::DisplayEffect* _this = reinterpret_cast<Scripting::DisplayEffect*> (ptr);
- delete _this;
- return 0;
-}
-
-static SQInteger DisplayEffect_fade_out_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'fade_out' called without instance"));
- return SQ_ERROR;
- }
- Scripting::DisplayEffect* _this = reinterpret_cast<Scripting::DisplayEffect*> (data);
- SQFloat arg0;
- if(SQ_FAILED(sq_getfloat(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not a float"));
- return SQ_ERROR;
- }
-
- try {
- _this->fade_out(static_cast<float> (arg0));
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'fade_out'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger DisplayEffect_fade_in_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'fade_in' called without instance"));
- return SQ_ERROR;
- }
- Scripting::DisplayEffect* _this = reinterpret_cast<Scripting::DisplayEffect*> (data);
- SQFloat arg0;
- if(SQ_FAILED(sq_getfloat(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not a float"));
- return SQ_ERROR;
- }
-
- try {
- _this->fade_in(static_cast<float> (arg0));
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'fade_in'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger DisplayEffect_set_black_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'set_black' called without instance"));
- return SQ_ERROR;
- }
- Scripting::DisplayEffect* _this = reinterpret_cast<Scripting::DisplayEffect*> (data);
- SQBool arg0;
- if(SQ_FAILED(sq_getbool(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not a bool"));
- return SQ_ERROR;
- }
-
- try {
- _this->set_black(arg0 == SQTrue);
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'set_black'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger DisplayEffect_is_black_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'is_black' called without instance"));
- return SQ_ERROR;
- }
- Scripting::DisplayEffect* _this = reinterpret_cast<Scripting::DisplayEffect*> (data);
-
- try {
- bool return_value = _this->is_black();
-
- sq_pushbool(vm, return_value);
- return 1;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'is_black'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger DisplayEffect_sixteen_to_nine_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'sixteen_to_nine' called without instance"));
- return SQ_ERROR;
- }
- Scripting::DisplayEffect* _this = reinterpret_cast<Scripting::DisplayEffect*> (data);
- SQFloat arg0;
- if(SQ_FAILED(sq_getfloat(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not a float"));
- return SQ_ERROR;
- }
-
- try {
- _this->sixteen_to_nine(static_cast<float> (arg0));
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'sixteen_to_nine'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger DisplayEffect_four_to_three_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'four_to_three' called without instance"));
- return SQ_ERROR;
- }
- Scripting::DisplayEffect* _this = reinterpret_cast<Scripting::DisplayEffect*> (data);
- SQFloat arg0;
- if(SQ_FAILED(sq_getfloat(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not a float"));
- return SQ_ERROR;
- }
-
- try {
- _this->four_to_three(static_cast<float> (arg0));
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'four_to_three'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger Camera_release_hook(SQUserPointer ptr, SQInteger )
-{
- Scripting::Camera* _this = reinterpret_cast<Scripting::Camera*> (ptr);
- delete _this;
- return 0;
-}
-
-static SQInteger Camera_reload_config_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'reload_config' called without instance"));
- return SQ_ERROR;
- }
- Scripting::Camera* _this = reinterpret_cast<Scripting::Camera*> (data);
-
- try {
- _this->reload_config();
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'reload_config'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger Camera_shake_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'shake' called without instance"));
- return SQ_ERROR;
- }
- Scripting::Camera* _this = reinterpret_cast<Scripting::Camera*> (data);
- SQFloat arg0;
- if(SQ_FAILED(sq_getfloat(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not a float"));
- return SQ_ERROR;
- }
- SQFloat arg1;
- if(SQ_FAILED(sq_getfloat(vm, 3, &arg1))) {
- sq_throwerror(vm, _SC("Argument 2 not a float"));
- return SQ_ERROR;
- }
- SQFloat arg2;
- if(SQ_FAILED(sq_getfloat(vm, 4, &arg2))) {
- sq_throwerror(vm, _SC("Argument 3 not a float"));
- return SQ_ERROR;
- }
-
- try {
- _this->shake(static_cast<float> (arg0), static_cast<float> (arg1), static_cast<float> (arg2));
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'shake'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger Camera_set_pos_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'set_pos' called without instance"));
- return SQ_ERROR;
- }
- Scripting::Camera* _this = reinterpret_cast<Scripting::Camera*> (data);
- SQFloat arg0;
- if(SQ_FAILED(sq_getfloat(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not a float"));
- return SQ_ERROR;
- }
- SQFloat arg1;
- if(SQ_FAILED(sq_getfloat(vm, 3, &arg1))) {
- sq_throwerror(vm, _SC("Argument 2 not a float"));
- return SQ_ERROR;
- }
-
- try {
- _this->set_pos(static_cast<float> (arg0), static_cast<float> (arg1));
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'set_pos'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger Camera_set_mode_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'set_mode' called without instance"));
- return SQ_ERROR;
- }
- Scripting::Camera* _this = reinterpret_cast<Scripting::Camera*> (data);
- const SQChar* arg0;
- if(SQ_FAILED(sq_getstring(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not a string"));
- return SQ_ERROR;
- }
-
- try {
- _this->set_mode(arg0);
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'set_mode'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger Camera_scroll_to_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'scroll_to' called without instance"));
- return SQ_ERROR;
- }
- Scripting::Camera* _this = reinterpret_cast<Scripting::Camera*> (data);
- SQFloat arg0;
- if(SQ_FAILED(sq_getfloat(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not a float"));
- return SQ_ERROR;
- }
- SQFloat arg1;
- if(SQ_FAILED(sq_getfloat(vm, 3, &arg1))) {
- sq_throwerror(vm, _SC("Argument 2 not a float"));
- return SQ_ERROR;
- }
- SQFloat arg2;
- if(SQ_FAILED(sq_getfloat(vm, 4, &arg2))) {
- sq_throwerror(vm, _SC("Argument 3 not a float"));
- return SQ_ERROR;
- }
-
- try {
- _this->scroll_to(static_cast<float> (arg0), static_cast<float> (arg1), static_cast<float> (arg2));
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'scroll_to'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger Level_release_hook(SQUserPointer ptr, SQInteger )
-{
- Scripting::Level* _this = reinterpret_cast<Scripting::Level*> (ptr);
- delete _this;
- return 0;
-}
-
-static SQInteger Level_finish_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'finish' called without instance"));
- return SQ_ERROR;
- }
- Scripting::Level* _this = reinterpret_cast<Scripting::Level*> (data);
- SQBool arg0;
- if(SQ_FAILED(sq_getbool(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not a bool"));
- return SQ_ERROR;
- }
-
- try {
- _this->finish(arg0 == SQTrue);
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'finish'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger Level_spawn_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'spawn' called without instance"));
- return SQ_ERROR;
- }
- Scripting::Level* _this = reinterpret_cast<Scripting::Level*> (data);
- const SQChar* arg0;
- if(SQ_FAILED(sq_getstring(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not a string"));
- return SQ_ERROR;
- }
- const SQChar* arg1;
- if(SQ_FAILED(sq_getstring(vm, 3, &arg1))) {
- sq_throwerror(vm, _SC("Argument 2 not a string"));
- return SQ_ERROR;
- }
-
- try {
- _this->spawn(arg0, arg1);
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'spawn'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger Level_flip_vertically_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'flip_vertically' called without instance"));
- return SQ_ERROR;
- }
- Scripting::Level* _this = reinterpret_cast<Scripting::Level*> (data);
-
- try {
- _this->flip_vertically();
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'flip_vertically'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger Level_toggle_pause_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'toggle_pause' called without instance"));
- return SQ_ERROR;
- }
- Scripting::Level* _this = reinterpret_cast<Scripting::Level*> (data);
-
- try {
- _this->toggle_pause();
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'toggle_pause'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger ScriptedObject_release_hook(SQUserPointer ptr, SQInteger )
-{
- Scripting::ScriptedObject* _this = reinterpret_cast<Scripting::ScriptedObject*> (ptr);
- delete _this;
- return 0;
-}
-
-static SQInteger ScriptedObject_set_action_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'set_action' called without instance"));
- return SQ_ERROR;
- }
- Scripting::ScriptedObject* _this = reinterpret_cast<Scripting::ScriptedObject*> (data);
- const SQChar* arg0;
- if(SQ_FAILED(sq_getstring(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not a string"));
- return SQ_ERROR;
- }
-
- try {
- _this->set_action(arg0);
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'set_action'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger ScriptedObject_get_action_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'get_action' called without instance"));
- return SQ_ERROR;
- }
- Scripting::ScriptedObject* _this = reinterpret_cast<Scripting::ScriptedObject*> (data);
-
- try {
- std::string return_value = _this->get_action();
-
- sq_pushstring(vm, return_value.c_str(), return_value.size());
- return 1;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'get_action'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger ScriptedObject_move_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'move' called without instance"));
- return SQ_ERROR;
- }
- Scripting::ScriptedObject* _this = reinterpret_cast<Scripting::ScriptedObject*> (data);
- SQFloat arg0;
- if(SQ_FAILED(sq_getfloat(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not a float"));
- return SQ_ERROR;
- }
- SQFloat arg1;
- if(SQ_FAILED(sq_getfloat(vm, 3, &arg1))) {
- sq_throwerror(vm, _SC("Argument 2 not a float"));
- return SQ_ERROR;
- }
-
- try {
- _this->move(static_cast<float> (arg0), static_cast<float> (arg1));
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'move'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger ScriptedObject_set_pos_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'set_pos' called without instance"));
- return SQ_ERROR;
- }
- Scripting::ScriptedObject* _this = reinterpret_cast<Scripting::ScriptedObject*> (data);
- SQFloat arg0;
- if(SQ_FAILED(sq_getfloat(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not a float"));
- return SQ_ERROR;
- }
- SQFloat arg1;
- if(SQ_FAILED(sq_getfloat(vm, 3, &arg1))) {
- sq_throwerror(vm, _SC("Argument 2 not a float"));
- return SQ_ERROR;
- }
-
- try {
- _this->set_pos(static_cast<float> (arg0), static_cast<float> (arg1));
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'set_pos'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger ScriptedObject_get_pos_x_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'get_pos_x' called without instance"));
- return SQ_ERROR;
- }
- Scripting::ScriptedObject* _this = reinterpret_cast<Scripting::ScriptedObject*> (data);
-
- try {
- float return_value = _this->get_pos_x();
-
- sq_pushfloat(vm, return_value);
- return 1;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'get_pos_x'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger ScriptedObject_get_pos_y_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'get_pos_y' called without instance"));
- return SQ_ERROR;
- }
- Scripting::ScriptedObject* _this = reinterpret_cast<Scripting::ScriptedObject*> (data);
-
- try {
- float return_value = _this->get_pos_y();
-
- sq_pushfloat(vm, return_value);
- return 1;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'get_pos_y'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger ScriptedObject_set_velocity_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'set_velocity' called without instance"));
- return SQ_ERROR;
- }
- Scripting::ScriptedObject* _this = reinterpret_cast<Scripting::ScriptedObject*> (data);
- SQFloat arg0;
- if(SQ_FAILED(sq_getfloat(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not a float"));
- return SQ_ERROR;
- }
- SQFloat arg1;
- if(SQ_FAILED(sq_getfloat(vm, 3, &arg1))) {
- sq_throwerror(vm, _SC("Argument 2 not a float"));
- return SQ_ERROR;
- }
-
- try {
- _this->set_velocity(static_cast<float> (arg0), static_cast<float> (arg1));
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'set_velocity'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger ScriptedObject_get_velocity_x_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'get_velocity_x' called without instance"));
- return SQ_ERROR;
- }
- Scripting::ScriptedObject* _this = reinterpret_cast<Scripting::ScriptedObject*> (data);
-
- try {
- float return_value = _this->get_velocity_x();
-
- sq_pushfloat(vm, return_value);
- return 1;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'get_velocity_x'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger ScriptedObject_get_velocity_y_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'get_velocity_y' called without instance"));
- return SQ_ERROR;
- }
- Scripting::ScriptedObject* _this = reinterpret_cast<Scripting::ScriptedObject*> (data);
-
- try {
- float return_value = _this->get_velocity_y();
-
- sq_pushfloat(vm, return_value);
- return 1;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'get_velocity_y'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger ScriptedObject_set_visible_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'set_visible' called without instance"));
- return SQ_ERROR;
- }
- Scripting::ScriptedObject* _this = reinterpret_cast<Scripting::ScriptedObject*> (data);
- SQBool arg0;
- if(SQ_FAILED(sq_getbool(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not a bool"));
- return SQ_ERROR;
- }
-
- try {
- _this->set_visible(arg0 == SQTrue);
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'set_visible'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger ScriptedObject_is_visible_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'is_visible' called without instance"));
- return SQ_ERROR;
- }
- Scripting::ScriptedObject* _this = reinterpret_cast<Scripting::ScriptedObject*> (data);
-
- try {
- bool return_value = _this->is_visible();
-
- sq_pushbool(vm, return_value);
- return 1;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'is_visible'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger ScriptedObject_set_solid_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'set_solid' called without instance"));
- return SQ_ERROR;
- }
- Scripting::ScriptedObject* _this = reinterpret_cast<Scripting::ScriptedObject*> (data);
- SQBool arg0;
- if(SQ_FAILED(sq_getbool(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not a bool"));
- return SQ_ERROR;
- }
-
- try {
- _this->set_solid(arg0 == SQTrue);
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'set_solid'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger ScriptedObject_is_solid_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'is_solid' called without instance"));
- return SQ_ERROR;
- }
- Scripting::ScriptedObject* _this = reinterpret_cast<Scripting::ScriptedObject*> (data);
-
- try {
- bool return_value = _this->is_solid();
-
- sq_pushbool(vm, return_value);
- return 1;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'is_solid'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger ScriptedObject_get_name_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'get_name' called without instance"));
- return SQ_ERROR;
- }
- Scripting::ScriptedObject* _this = reinterpret_cast<Scripting::ScriptedObject*> (data);
-
- try {
- std::string return_value = _this->get_name();
-
- sq_pushstring(vm, return_value.c_str(), return_value.size());
- return 1;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'get_name'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger Text_release_hook(SQUserPointer ptr, SQInteger )
-{
- Scripting::Text* _this = reinterpret_cast<Scripting::Text*> (ptr);
- delete _this;
- return 0;
-}
-
-static SQInteger Text_set_text_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'set_text' called without instance"));
- return SQ_ERROR;
- }
- Scripting::Text* _this = reinterpret_cast<Scripting::Text*> (data);
- const SQChar* arg0;
- if(SQ_FAILED(sq_getstring(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not a string"));
- return SQ_ERROR;
- }
-
- try {
- _this->set_text(arg0);
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'set_text'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger Text_set_font_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'set_font' called without instance"));
- return SQ_ERROR;
- }
- Scripting::Text* _this = reinterpret_cast<Scripting::Text*> (data);
- const SQChar* arg0;
- if(SQ_FAILED(sq_getstring(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not a string"));
- return SQ_ERROR;
- }
-
- try {
- _this->set_font(arg0);
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'set_font'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger Text_fade_in_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'fade_in' called without instance"));
- return SQ_ERROR;
- }
- Scripting::Text* _this = reinterpret_cast<Scripting::Text*> (data);
- SQFloat arg0;
- if(SQ_FAILED(sq_getfloat(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not a float"));
- return SQ_ERROR;
- }
-
- try {
- _this->fade_in(static_cast<float> (arg0));
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'fade_in'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger Text_fade_out_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'fade_out' called without instance"));
- return SQ_ERROR;
- }
- Scripting::Text* _this = reinterpret_cast<Scripting::Text*> (data);
- SQFloat arg0;
- if(SQ_FAILED(sq_getfloat(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not a float"));
- return SQ_ERROR;
- }
-
- try {
- _this->fade_out(static_cast<float> (arg0));
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'fade_out'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger Text_set_visible_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'set_visible' called without instance"));
- return SQ_ERROR;
- }
- Scripting::Text* _this = reinterpret_cast<Scripting::Text*> (data);
- SQBool arg0;
- if(SQ_FAILED(sq_getbool(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not a bool"));
- return SQ_ERROR;
- }
-
- try {
- _this->set_visible(arg0 == SQTrue);
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'set_visible'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger Text_set_centered_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'set_centered' called without instance"));
- return SQ_ERROR;
- }
- Scripting::Text* _this = reinterpret_cast<Scripting::Text*> (data);
- SQBool arg0;
- if(SQ_FAILED(sq_getbool(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not a bool"));
- return SQ_ERROR;
- }
-
- try {
- _this->set_centered(arg0 == SQTrue);
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'set_centered'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger Text_set_pos_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'set_pos' called without instance"));
- return SQ_ERROR;
- }
- Scripting::Text* _this = reinterpret_cast<Scripting::Text*> (data);
- SQFloat arg0;
- if(SQ_FAILED(sq_getfloat(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not a float"));
- return SQ_ERROR;
- }
- SQFloat arg1;
- if(SQ_FAILED(sq_getfloat(vm, 3, &arg1))) {
- sq_throwerror(vm, _SC("Argument 2 not a float"));
- return SQ_ERROR;
- }
-
- try {
- _this->set_pos(static_cast<float> (arg0), static_cast<float> (arg1));
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'set_pos'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger Text_get_pos_x_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'get_pos_x' called without instance"));
- return SQ_ERROR;
- }
- Scripting::Text* _this = reinterpret_cast<Scripting::Text*> (data);
-
- try {
- float return_value = _this->get_pos_x();
-
- sq_pushfloat(vm, return_value);
- return 1;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'get_pos_x'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger Text_get_pos_y_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'get_pos_y' called without instance"));
- return SQ_ERROR;
- }
- Scripting::Text* _this = reinterpret_cast<Scripting::Text*> (data);
-
- try {
- float return_value = _this->get_pos_y();
-
- sq_pushfloat(vm, return_value);
- return 1;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'get_pos_y'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger Text_set_anchor_point_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'set_anchor_point' called without instance"));
- return SQ_ERROR;
- }
- Scripting::Text* _this = reinterpret_cast<Scripting::Text*> (data);
- SQInteger arg0;
- if(SQ_FAILED(sq_getinteger(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not an integer"));
- return SQ_ERROR;
- }
-
- try {
- _this->set_anchor_point(static_cast<int> (arg0));
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'set_anchor_point'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger Text_get_anchor_point_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'get_anchor_point' called without instance"));
- return SQ_ERROR;
- }
- Scripting::Text* _this = reinterpret_cast<Scripting::Text*> (data);
-
- try {
- int return_value = _this->get_anchor_point();
-
- sq_pushinteger(vm, return_value);
- return 1;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'get_anchor_point'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger Player_release_hook(SQUserPointer ptr, SQInteger )
-{
- Scripting::Player* _this = reinterpret_cast<Scripting::Player*> (ptr);
- delete _this;
- return 0;
-}
-
-static SQInteger Player_add_bonus_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'add_bonus' called without instance"));
- return SQ_ERROR;
- }
- Scripting::Player* _this = reinterpret_cast<Scripting::Player*> (data);
- const SQChar* arg0;
- if(SQ_FAILED(sq_getstring(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not a string"));
- return SQ_ERROR;
- }
-
- try {
- bool return_value = _this->add_bonus(arg0);
-
- sq_pushbool(vm, return_value);
- return 1;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'add_bonus'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger Player_add_coins_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'add_coins' called without instance"));
- return SQ_ERROR;
- }
- Scripting::Player* _this = reinterpret_cast<Scripting::Player*> (data);
- SQInteger arg0;
- if(SQ_FAILED(sq_getinteger(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not an integer"));
- return SQ_ERROR;
- }
-
- try {
- _this->add_coins(static_cast<int> (arg0));
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'add_coins'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger Player_make_invincible_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'make_invincible' called without instance"));
- return SQ_ERROR;
- }
- Scripting::Player* _this = reinterpret_cast<Scripting::Player*> (data);
-
- try {
- _this->make_invincible();
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'make_invincible'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger Player_deactivate_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'deactivate' called without instance"));
- return SQ_ERROR;
- }
- Scripting::Player* _this = reinterpret_cast<Scripting::Player*> (data);
-
- try {
- _this->deactivate();
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'deactivate'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger Player_activate_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'activate' called without instance"));
- return SQ_ERROR;
- }
- Scripting::Player* _this = reinterpret_cast<Scripting::Player*> (data);
-
- try {
- _this->activate();
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'activate'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger Player_walk_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'walk' called without instance"));
- return SQ_ERROR;
- }
- Scripting::Player* _this = reinterpret_cast<Scripting::Player*> (data);
- SQFloat arg0;
- if(SQ_FAILED(sq_getfloat(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not a float"));
- return SQ_ERROR;
- }
-
- try {
- _this->walk(static_cast<float> (arg0));
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'walk'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger Player_set_visible_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'set_visible' called without instance"));
- return SQ_ERROR;
- }
- Scripting::Player* _this = reinterpret_cast<Scripting::Player*> (data);
- SQBool arg0;
- if(SQ_FAILED(sq_getbool(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not a bool"));
- return SQ_ERROR;
- }
-
- try {
- _this->set_visible(arg0 == SQTrue);
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'set_visible'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger Player_get_visible_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'get_visible' called without instance"));
- return SQ_ERROR;
- }
- Scripting::Player* _this = reinterpret_cast<Scripting::Player*> (data);
-
- try {
- bool return_value = _this->get_visible();
-
- sq_pushbool(vm, return_value);
- return 1;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'get_visible'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger Player_kill_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'kill' called without instance"));
- return SQ_ERROR;
- }
- Scripting::Player* _this = reinterpret_cast<Scripting::Player*> (data);
- SQBool arg0;
- if(SQ_FAILED(sq_getbool(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not a bool"));
- return SQ_ERROR;
- }
-
- try {
- _this->kill(arg0 == SQTrue);
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'kill'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger Player_set_ghost_mode_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'set_ghost_mode' called without instance"));
- return SQ_ERROR;
- }
- Scripting::Player* _this = reinterpret_cast<Scripting::Player*> (data);
- SQBool arg0;
- if(SQ_FAILED(sq_getbool(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not a bool"));
- return SQ_ERROR;
- }
-
- try {
- _this->set_ghost_mode(arg0 == SQTrue);
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'set_ghost_mode'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger Player_get_ghost_mode_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'get_ghost_mode' called without instance"));
- return SQ_ERROR;
- }
- Scripting::Player* _this = reinterpret_cast<Scripting::Player*> (data);
-
- try {
- bool return_value = _this->get_ghost_mode();
-
- sq_pushbool(vm, return_value);
- return 1;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'get_ghost_mode'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger Player_do_cheer_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'do_cheer' called without instance"));
- return SQ_ERROR;
- }
- Scripting::Player* _this = reinterpret_cast<Scripting::Player*> (data);
-
- try {
- _this->do_cheer();
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'do_cheer'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger Player_do_duck_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'do_duck' called without instance"));
- return SQ_ERROR;
- }
- Scripting::Player* _this = reinterpret_cast<Scripting::Player*> (data);
-
- try {
- _this->do_duck();
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'do_duck'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger Player_do_standup_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'do_standup' called without instance"));
- return SQ_ERROR;
- }
- Scripting::Player* _this = reinterpret_cast<Scripting::Player*> (data);
-
- try {
- _this->do_standup();
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'do_standup'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger Player_do_backflip_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'do_backflip' called without instance"));
- return SQ_ERROR;
- }
- Scripting::Player* _this = reinterpret_cast<Scripting::Player*> (data);
-
- try {
- _this->do_backflip();
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'do_backflip'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger Player_do_jump_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'do_jump' called without instance"));
- return SQ_ERROR;
- }
- Scripting::Player* _this = reinterpret_cast<Scripting::Player*> (data);
- SQFloat arg0;
- if(SQ_FAILED(sq_getfloat(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not a float"));
- return SQ_ERROR;
- }
-
- try {
- _this->do_jump(static_cast<float> (arg0));
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'do_jump'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger Player_trigger_sequence_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'trigger_sequence' called without instance"));
- return SQ_ERROR;
- }
- Scripting::Player* _this = reinterpret_cast<Scripting::Player*> (data);
- const SQChar* arg0;
- if(SQ_FAILED(sq_getstring(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not a string"));
- return SQ_ERROR;
- }
-
- try {
- _this->trigger_sequence(arg0);
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'trigger_sequence'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger FloatingImage_release_hook(SQUserPointer ptr, SQInteger )
-{
- Scripting::FloatingImage* _this = reinterpret_cast<Scripting::FloatingImage*> (ptr);
- delete _this;
- return 0;
-}
-
-static SQInteger FloatingImage_constructor_wrapper(HSQUIRRELVM vm)
-{
- const SQChar* arg0;
- if(SQ_FAILED(sq_getstring(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not a string"));
- return SQ_ERROR;
- }
-
- try {
- Scripting::FloatingImage* _this = new Scripting::FloatingImage(arg0);
- if(SQ_FAILED(sq_setinstanceup(vm, 1, _this))) {
- sq_throwerror(vm, _SC("Couldn't setup instance of 'FloatingImage' class"));
- return SQ_ERROR;
- }
- sq_setreleasehook(vm, 1, FloatingImage_release_hook);
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'constructor'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger FloatingImage_set_layer_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'set_layer' called without instance"));
- return SQ_ERROR;
- }
- Scripting::FloatingImage* _this = reinterpret_cast<Scripting::FloatingImage*> (data);
- SQInteger arg0;
- if(SQ_FAILED(sq_getinteger(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not an integer"));
- return SQ_ERROR;
- }
-
- try {
- _this->set_layer(static_cast<int> (arg0));
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'set_layer'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger FloatingImage_get_layer_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'get_layer' called without instance"));
- return SQ_ERROR;
- }
- Scripting::FloatingImage* _this = reinterpret_cast<Scripting::FloatingImage*> (data);
-
- try {
- int return_value = _this->get_layer();
-
- sq_pushinteger(vm, return_value);
- return 1;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'get_layer'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger FloatingImage_set_pos_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'set_pos' called without instance"));
- return SQ_ERROR;
- }
- Scripting::FloatingImage* _this = reinterpret_cast<Scripting::FloatingImage*> (data);
- SQFloat arg0;
- if(SQ_FAILED(sq_getfloat(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not a float"));
- return SQ_ERROR;
- }
- SQFloat arg1;
- if(SQ_FAILED(sq_getfloat(vm, 3, &arg1))) {
- sq_throwerror(vm, _SC("Argument 2 not a float"));
- return SQ_ERROR;
- }
-
- try {
- _this->set_pos(static_cast<float> (arg0), static_cast<float> (arg1));
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'set_pos'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger FloatingImage_get_pos_x_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'get_pos_x' called without instance"));
- return SQ_ERROR;
- }
- Scripting::FloatingImage* _this = reinterpret_cast<Scripting::FloatingImage*> (data);
-
- try {
- float return_value = _this->get_pos_x();
-
- sq_pushfloat(vm, return_value);
- return 1;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'get_pos_x'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger FloatingImage_get_pos_y_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'get_pos_y' called without instance"));
- return SQ_ERROR;
- }
- Scripting::FloatingImage* _this = reinterpret_cast<Scripting::FloatingImage*> (data);
-
- try {
- float return_value = _this->get_pos_y();
-
- sq_pushfloat(vm, return_value);
- return 1;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'get_pos_y'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger FloatingImage_set_anchor_point_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'set_anchor_point' called without instance"));
- return SQ_ERROR;
- }
- Scripting::FloatingImage* _this = reinterpret_cast<Scripting::FloatingImage*> (data);
- SQInteger arg0;
- if(SQ_FAILED(sq_getinteger(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not an integer"));
- return SQ_ERROR;
- }
-
- try {
- _this->set_anchor_point(static_cast<int> (arg0));
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'set_anchor_point'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger FloatingImage_get_anchor_point_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'get_anchor_point' called without instance"));
- return SQ_ERROR;
- }
- Scripting::FloatingImage* _this = reinterpret_cast<Scripting::FloatingImage*> (data);
-
- try {
- int return_value = _this->get_anchor_point();
-
- sq_pushinteger(vm, return_value);
- return 1;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'get_anchor_point'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger FloatingImage_set_visible_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'set_visible' called without instance"));
- return SQ_ERROR;
- }
- Scripting::FloatingImage* _this = reinterpret_cast<Scripting::FloatingImage*> (data);
- SQBool arg0;
- if(SQ_FAILED(sq_getbool(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not a bool"));
- return SQ_ERROR;
- }
-
- try {
- _this->set_visible(arg0 == SQTrue);
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'set_visible'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger FloatingImage_get_visible_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'get_visible' called without instance"));
- return SQ_ERROR;
- }
- Scripting::FloatingImage* _this = reinterpret_cast<Scripting::FloatingImage*> (data);
-
- try {
- bool return_value = _this->get_visible();
-
- sq_pushbool(vm, return_value);
- return 1;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'get_visible'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger FloatingImage_set_action_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'set_action' called without instance"));
- return SQ_ERROR;
- }
- Scripting::FloatingImage* _this = reinterpret_cast<Scripting::FloatingImage*> (data);
- const SQChar* arg0;
- if(SQ_FAILED(sq_getstring(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not a string"));
- return SQ_ERROR;
- }
-
- try {
- _this->set_action(arg0);
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'set_action'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger FloatingImage_get_action_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'get_action' called without instance"));
- return SQ_ERROR;
- }
- Scripting::FloatingImage* _this = reinterpret_cast<Scripting::FloatingImage*> (data);
-
- try {
- std::string return_value = _this->get_action();
-
- sq_pushstring(vm, return_value.c_str(), return_value.size());
- return 1;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'get_action'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger FloatingImage_fade_in_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'fade_in' called without instance"));
- return SQ_ERROR;
- }
- Scripting::FloatingImage* _this = reinterpret_cast<Scripting::FloatingImage*> (data);
- SQFloat arg0;
- if(SQ_FAILED(sq_getfloat(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not a float"));
- return SQ_ERROR;
- }
-
- try {
- _this->fade_in(static_cast<float> (arg0));
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'fade_in'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger FloatingImage_fade_out_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'fade_out' called without instance"));
- return SQ_ERROR;
- }
- Scripting::FloatingImage* _this = reinterpret_cast<Scripting::FloatingImage*> (data);
- SQFloat arg0;
- if(SQ_FAILED(sq_getfloat(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not a float"));
- return SQ_ERROR;
- }
-
- try {
- _this->fade_out(static_cast<float> (arg0));
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'fade_out'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger Platform_release_hook(SQUserPointer ptr, SQInteger )
-{
- Scripting::Platform* _this = reinterpret_cast<Scripting::Platform*> (ptr);
- delete _this;
- return 0;
-}
-
-static SQInteger Platform_goto_node_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'goto_node' called without instance"));
- return SQ_ERROR;
- }
- Scripting::Platform* _this = reinterpret_cast<Scripting::Platform*> (data);
- SQInteger arg0;
- if(SQ_FAILED(sq_getinteger(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not an integer"));
- return SQ_ERROR;
- }
-
- try {
- _this->goto_node(static_cast<int> (arg0));
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'goto_node'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger Platform_start_moving_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'start_moving' called without instance"));
- return SQ_ERROR;
- }
- Scripting::Platform* _this = reinterpret_cast<Scripting::Platform*> (data);
-
- try {
- _this->start_moving();
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'start_moving'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger Platform_stop_moving_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'stop_moving' called without instance"));
- return SQ_ERROR;
- }
- Scripting::Platform* _this = reinterpret_cast<Scripting::Platform*> (data);
-
- try {
- _this->stop_moving();
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'stop_moving'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger Candle_release_hook(SQUserPointer ptr, SQInteger )
-{
- Scripting::Candle* _this = reinterpret_cast<Scripting::Candle*> (ptr);
- delete _this;
- return 0;
-}
-
-static SQInteger Candle_get_burning_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'get_burning' called without instance"));
- return SQ_ERROR;
- }
- Scripting::Candle* _this = reinterpret_cast<Scripting::Candle*> (data);
-
- try {
- bool return_value = _this->get_burning();
-
- sq_pushbool(vm, return_value);
- return 1;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'get_burning'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger Candle_set_burning_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'set_burning' called without instance"));
- return SQ_ERROR;
- }
- Scripting::Candle* _this = reinterpret_cast<Scripting::Candle*> (data);
- SQBool arg0;
- if(SQ_FAILED(sq_getbool(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not a bool"));
- return SQ_ERROR;
- }
-
- try {
- _this->set_burning(arg0 == SQTrue);
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'set_burning'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger Wind_release_hook(SQUserPointer ptr, SQInteger )
-{
- Scripting::Wind* _this = reinterpret_cast<Scripting::Wind*> (ptr);
- delete _this;
- return 0;
-}
-
-static SQInteger Wind_start_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'start' called without instance"));
- return SQ_ERROR;
- }
- Scripting::Wind* _this = reinterpret_cast<Scripting::Wind*> (data);
-
- try {
- _this->start();
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'start'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger Wind_stop_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'stop' called without instance"));
- return SQ_ERROR;
- }
- Scripting::Wind* _this = reinterpret_cast<Scripting::Wind*> (data);
-
- try {
- _this->stop();
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'stop'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger AmbientSound_release_hook(SQUserPointer ptr, SQInteger )
-{
- Scripting::AmbientSound* _this = reinterpret_cast<Scripting::AmbientSound*> (ptr);
- delete _this;
- return 0;
-}
-
-static SQInteger AmbientSound_set_pos_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'set_pos' called without instance"));
- return SQ_ERROR;
- }
- Scripting::AmbientSound* _this = reinterpret_cast<Scripting::AmbientSound*> (data);
- SQFloat arg0;
- if(SQ_FAILED(sq_getfloat(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not a float"));
- return SQ_ERROR;
- }
- SQFloat arg1;
- if(SQ_FAILED(sq_getfloat(vm, 3, &arg1))) {
- sq_throwerror(vm, _SC("Argument 2 not a float"));
- return SQ_ERROR;
- }
-
- try {
- _this->set_pos(static_cast<float> (arg0), static_cast<float> (arg1));
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'set_pos'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger AmbientSound_get_pos_x_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'get_pos_x' called without instance"));
- return SQ_ERROR;
- }
- Scripting::AmbientSound* _this = reinterpret_cast<Scripting::AmbientSound*> (data);
-
- try {
- float return_value = _this->get_pos_x();
-
- sq_pushfloat(vm, return_value);
- return 1;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'get_pos_x'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger AmbientSound_get_pos_y_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'get_pos_y' called without instance"));
- return SQ_ERROR;
- }
- Scripting::AmbientSound* _this = reinterpret_cast<Scripting::AmbientSound*> (data);
-
- try {
- float return_value = _this->get_pos_y();
-
- sq_pushfloat(vm, return_value);
- return 1;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'get_pos_y'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger Thunderstorm_release_hook(SQUserPointer ptr, SQInteger )
-{
- Scripting::Thunderstorm* _this = reinterpret_cast<Scripting::Thunderstorm*> (ptr);
- delete _this;
- return 0;
-}
-
-static SQInteger Thunderstorm_start_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'start' called without instance"));
- return SQ_ERROR;
- }
- Scripting::Thunderstorm* _this = reinterpret_cast<Scripting::Thunderstorm*> (data);
-
- try {
- _this->start();
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'start'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger Thunderstorm_stop_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'stop' called without instance"));
- return SQ_ERROR;
- }
- Scripting::Thunderstorm* _this = reinterpret_cast<Scripting::Thunderstorm*> (data);
-
- try {
- _this->stop();
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'stop'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger Thunderstorm_thunder_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'thunder' called without instance"));
- return SQ_ERROR;
- }
- Scripting::Thunderstorm* _this = reinterpret_cast<Scripting::Thunderstorm*> (data);
-
- try {
- _this->thunder();
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'thunder'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger Thunderstorm_lightning_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'lightning' called without instance"));
- return SQ_ERROR;
- }
- Scripting::Thunderstorm* _this = reinterpret_cast<Scripting::Thunderstorm*> (data);
-
- try {
- _this->lightning();
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'lightning'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger Thunderstorm_flash_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'flash' called without instance"));
- return SQ_ERROR;
- }
- Scripting::Thunderstorm* _this = reinterpret_cast<Scripting::Thunderstorm*> (data);
-
- try {
- _this->flash();
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'flash'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger Thunderstorm_electrify_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'electrify' called without instance"));
- return SQ_ERROR;
- }
- Scripting::Thunderstorm* _this = reinterpret_cast<Scripting::Thunderstorm*> (data);
-
- try {
- _this->electrify();
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'electrify'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger TileMap_release_hook(SQUserPointer ptr, SQInteger )
-{
- Scripting::TileMap* _this = reinterpret_cast<Scripting::TileMap*> (ptr);
- delete _this;
- return 0;
-}
-
-static SQInteger TileMap_goto_node_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'goto_node' called without instance"));
- return SQ_ERROR;
- }
- Scripting::TileMap* _this = reinterpret_cast<Scripting::TileMap*> (data);
- SQInteger arg0;
- if(SQ_FAILED(sq_getinteger(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not an integer"));
- return SQ_ERROR;
- }
-
- try {
- _this->goto_node(static_cast<int> (arg0));
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'goto_node'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger TileMap_start_moving_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'start_moving' called without instance"));
- return SQ_ERROR;
- }
- Scripting::TileMap* _this = reinterpret_cast<Scripting::TileMap*> (data);
-
- try {
- _this->start_moving();
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'start_moving'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger TileMap_stop_moving_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'stop_moving' called without instance"));
- return SQ_ERROR;
- }
- Scripting::TileMap* _this = reinterpret_cast<Scripting::TileMap*> (data);
-
- try {
- _this->stop_moving();
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'stop_moving'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger TileMap_fade_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'fade' called without instance"));
- return SQ_ERROR;
- }
- Scripting::TileMap* _this = reinterpret_cast<Scripting::TileMap*> (data);
- SQFloat arg0;
- if(SQ_FAILED(sq_getfloat(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not a float"));
- return SQ_ERROR;
- }
- SQFloat arg1;
- if(SQ_FAILED(sq_getfloat(vm, 3, &arg1))) {
- sq_throwerror(vm, _SC("Argument 2 not a float"));
- return SQ_ERROR;
- }
-
- try {
- _this->fade(static_cast<float> (arg0), static_cast<float> (arg1));
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'fade'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger TileMap_set_alpha_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'set_alpha' called without instance"));
- return SQ_ERROR;
- }
- Scripting::TileMap* _this = reinterpret_cast<Scripting::TileMap*> (data);
- SQFloat arg0;
- if(SQ_FAILED(sq_getfloat(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not a float"));
- return SQ_ERROR;
- }
-
- try {
- _this->set_alpha(static_cast<float> (arg0));
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'set_alpha'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger TileMap_get_alpha_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'get_alpha' called without instance"));
- return SQ_ERROR;
- }
- Scripting::TileMap* _this = reinterpret_cast<Scripting::TileMap*> (data);
-
- try {
- float return_value = _this->get_alpha();
-
- sq_pushfloat(vm, return_value);
- return 1;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'get_alpha'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger SSector_release_hook(SQUserPointer ptr, SQInteger )
-{
- Scripting::SSector* _this = reinterpret_cast<Scripting::SSector*> (ptr);
- delete _this;
- return 0;
-}
-
-static SQInteger SSector_set_ambient_light_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'set_ambient_light' called without instance"));
- return SQ_ERROR;
- }
- Scripting::SSector* _this = reinterpret_cast<Scripting::SSector*> (data);
- SQFloat arg0;
- if(SQ_FAILED(sq_getfloat(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not a float"));
- return SQ_ERROR;
- }
- SQFloat arg1;
- if(SQ_FAILED(sq_getfloat(vm, 3, &arg1))) {
- sq_throwerror(vm, _SC("Argument 2 not a float"));
- return SQ_ERROR;
- }
- SQFloat arg2;
- if(SQ_FAILED(sq_getfloat(vm, 4, &arg2))) {
- sq_throwerror(vm, _SC("Argument 3 not a float"));
- return SQ_ERROR;
- }
-
- try {
- _this->set_ambient_light(static_cast<float> (arg0), static_cast<float> (arg1), static_cast<float> (arg2));
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'set_ambient_light'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger SSector_get_ambient_red_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'get_ambient_red' called without instance"));
- return SQ_ERROR;
- }
- Scripting::SSector* _this = reinterpret_cast<Scripting::SSector*> (data);
-
- try {
- float return_value = _this->get_ambient_red();
-
- sq_pushfloat(vm, return_value);
- return 1;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'get_ambient_red'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger SSector_get_ambient_green_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'get_ambient_green' called without instance"));
- return SQ_ERROR;
- }
- Scripting::SSector* _this = reinterpret_cast<Scripting::SSector*> (data);
-
- try {
- float return_value = _this->get_ambient_green();
-
- sq_pushfloat(vm, return_value);
- return 1;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'get_ambient_green'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger SSector_get_ambient_blue_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'get_ambient_blue' called without instance"));
- return SQ_ERROR;
- }
- Scripting::SSector* _this = reinterpret_cast<Scripting::SSector*> (data);
-
- try {
- float return_value = _this->get_ambient_blue();
-
- sq_pushfloat(vm, return_value);
- return 1;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'get_ambient_blue'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger LevelTime_release_hook(SQUserPointer ptr, SQInteger )
-{
- Scripting::LevelTime* _this = reinterpret_cast<Scripting::LevelTime*> (ptr);
- delete _this;
- return 0;
-}
-
-static SQInteger LevelTime_start_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'start' called without instance"));
- return SQ_ERROR;
- }
- Scripting::LevelTime* _this = reinterpret_cast<Scripting::LevelTime*> (data);
-
- try {
- _this->start();
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'start'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger LevelTime_stop_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'stop' called without instance"));
- return SQ_ERROR;
- }
- Scripting::LevelTime* _this = reinterpret_cast<Scripting::LevelTime*> (data);
-
- try {
- _this->stop();
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'stop'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger LevelTime_get_time_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'get_time' called without instance"));
- return SQ_ERROR;
- }
- Scripting::LevelTime* _this = reinterpret_cast<Scripting::LevelTime*> (data);
-
- try {
- float return_value = _this->get_time();
-
- sq_pushfloat(vm, return_value);
- return 1;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'get_time'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger LevelTime_set_time_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'set_time' called without instance"));
- return SQ_ERROR;
- }
- Scripting::LevelTime* _this = reinterpret_cast<Scripting::LevelTime*> (data);
- SQFloat arg0;
- if(SQ_FAILED(sq_getfloat(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not a float"));
- return SQ_ERROR;
- }
-
- try {
- _this->set_time(static_cast<float> (arg0));
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'set_time'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger WillOWisp_release_hook(SQUserPointer ptr, SQInteger )
-{
- Scripting::WillOWisp* _this = reinterpret_cast<Scripting::WillOWisp*> (ptr);
- delete _this;
- return 0;
-}
-
-static SQInteger WillOWisp_goto_node_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'goto_node' called without instance"));
- return SQ_ERROR;
- }
- Scripting::WillOWisp* _this = reinterpret_cast<Scripting::WillOWisp*> (data);
- SQInteger arg0;
- if(SQ_FAILED(sq_getinteger(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not an integer"));
- return SQ_ERROR;
- }
-
- try {
- _this->goto_node(static_cast<int> (arg0));
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'goto_node'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger WillOWisp_set_state_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'set_state' called without instance"));
- return SQ_ERROR;
- }
- Scripting::WillOWisp* _this = reinterpret_cast<Scripting::WillOWisp*> (data);
- const SQChar* arg0;
- if(SQ_FAILED(sq_getstring(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not a string"));
- return SQ_ERROR;
- }
-
- try {
- _this->set_state(arg0);
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'set_state'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger WillOWisp_start_moving_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'start_moving' called without instance"));
- return SQ_ERROR;
- }
- Scripting::WillOWisp* _this = reinterpret_cast<Scripting::WillOWisp*> (data);
-
- try {
- _this->start_moving();
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'start_moving'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger WillOWisp_stop_moving_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) {
- sq_throwerror(vm, _SC("'stop_moving' called without instance"));
- return SQ_ERROR;
- }
- Scripting::WillOWisp* _this = reinterpret_cast<Scripting::WillOWisp*> (data);
-
- try {
- _this->stop_moving();
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'stop_moving'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger display_wrapper(HSQUIRRELVM vm)
-{
- return Scripting::display(vm);
-}
-
-static SQInteger print_stacktrace_wrapper(HSQUIRRELVM vm)
-{
- HSQUIRRELVM arg0 = vm;
-
- try {
- Scripting::print_stacktrace(arg0);
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'print_stacktrace'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger get_current_thread_wrapper(HSQUIRRELVM vm)
-{
- return Scripting::get_current_thread(vm);
-}
-
-static SQInteger display_text_file_wrapper(HSQUIRRELVM vm)
-{
- const SQChar* arg0;
- if(SQ_FAILED(sq_getstring(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not a string"));
- return SQ_ERROR;
- }
-
- try {
- Scripting::display_text_file(arg0);
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'display_text_file'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger load_worldmap_wrapper(HSQUIRRELVM vm)
-{
- const SQChar* arg0;
- if(SQ_FAILED(sq_getstring(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not a string"));
- return SQ_ERROR;
- }
-
- try {
- Scripting::load_worldmap(arg0);
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'load_worldmap'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger load_level_wrapper(HSQUIRRELVM vm)
-{
- const SQChar* arg0;
- if(SQ_FAILED(sq_getstring(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not a string"));
- return SQ_ERROR;
- }
-
- try {
- Scripting::load_level(arg0);
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'load_level'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger wait_wrapper(HSQUIRRELVM vm)
-{
- HSQUIRRELVM arg0 = vm;
- SQFloat arg1;
- if(SQ_FAILED(sq_getfloat(vm, 2, &arg1))) {
- sq_throwerror(vm, _SC("Argument 1 not a float"));
- return SQ_ERROR;
- }
-
- try {
- Scripting::wait(arg0, static_cast<float> (arg1));
-
- return sq_suspendvm(vm);
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'wait'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger wait_for_screenswitch_wrapper(HSQUIRRELVM vm)
-{
- HSQUIRRELVM arg0 = vm;
-
- try {
- Scripting::wait_for_screenswitch(arg0);
-
- return sq_suspendvm(vm);
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'wait_for_screenswitch'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger exit_screen_wrapper(HSQUIRRELVM vm)
-{
- (void) vm;
-
- try {
- Scripting::exit_screen();
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'exit_screen'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger fadeout_screen_wrapper(HSQUIRRELVM vm)
-{
- SQFloat arg0;
- if(SQ_FAILED(sq_getfloat(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not a float"));
- return SQ_ERROR;
- }
-
- try {
- Scripting::fadeout_screen(static_cast<float> (arg0));
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'fadeout_screen'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger shrink_screen_wrapper(HSQUIRRELVM vm)
-{
- SQFloat arg0;
- if(SQ_FAILED(sq_getfloat(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not a float"));
- return SQ_ERROR;
- }
- SQFloat arg1;
- if(SQ_FAILED(sq_getfloat(vm, 3, &arg1))) {
- sq_throwerror(vm, _SC("Argument 2 not a float"));
- return SQ_ERROR;
- }
- SQFloat arg2;
- if(SQ_FAILED(sq_getfloat(vm, 4, &arg2))) {
- sq_throwerror(vm, _SC("Argument 3 not a float"));
- return SQ_ERROR;
- }
-
- try {
- Scripting::shrink_screen(static_cast<float> (arg0), static_cast<float> (arg1), static_cast<float> (arg2));
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'shrink_screen'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger abort_screenfade_wrapper(HSQUIRRELVM vm)
-{
- (void) vm;
-
- try {
- Scripting::abort_screenfade();
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'abort_screenfade'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger translate_wrapper(HSQUIRRELVM vm)
-{
- const SQChar* arg0;
- if(SQ_FAILED(sq_getstring(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not a string"));
- return SQ_ERROR;
- }
-
- try {
- std::string return_value = Scripting::translate(arg0);
-
- sq_pushstring(vm, return_value.c_str(), return_value.size());
- return 1;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'translate'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger import_wrapper(HSQUIRRELVM vm)
-{
- HSQUIRRELVM arg0 = vm;
- const SQChar* arg1;
- if(SQ_FAILED(sq_getstring(vm, 2, &arg1))) {
- sq_throwerror(vm, _SC("Argument 1 not a string"));
- return SQ_ERROR;
- }
-
- try {
- Scripting::import(arg0, arg1);
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'import'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger save_state_wrapper(HSQUIRRELVM vm)
-{
- (void) vm;
-
- try {
- Scripting::save_state();
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'save_state'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger update_worldmap_wrapper(HSQUIRRELVM vm)
-{
- (void) vm;
-
- try {
- Scripting::update_worldmap();
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'update_worldmap'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger debug_collrects_wrapper(HSQUIRRELVM vm)
-{
- SQBool arg0;
- if(SQ_FAILED(sq_getbool(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not a bool"));
- return SQ_ERROR;
- }
-
- try {
- Scripting::debug_collrects(arg0 == SQTrue);
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'debug_collrects'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger debug_show_fps_wrapper(HSQUIRRELVM vm)
-{
- SQBool arg0;
- if(SQ_FAILED(sq_getbool(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not a bool"));
- return SQ_ERROR;
- }
-
- try {
- Scripting::debug_show_fps(arg0 == SQTrue);
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'debug_show_fps'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger debug_draw_solids_only_wrapper(HSQUIRRELVM vm)
-{
- SQBool arg0;
- if(SQ_FAILED(sq_getbool(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not a bool"));
- return SQ_ERROR;
- }
-
- try {
- Scripting::debug_draw_solids_only(arg0 == SQTrue);
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'debug_draw_solids_only'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger play_music_wrapper(HSQUIRRELVM vm)
-{
- const SQChar* arg0;
- if(SQ_FAILED(sq_getstring(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not a string"));
- return SQ_ERROR;
- }
-
- try {
- Scripting::play_music(arg0);
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'play_music'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger play_sound_wrapper(HSQUIRRELVM vm)
-{
- const SQChar* arg0;
- if(SQ_FAILED(sq_getstring(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not a string"));
- return SQ_ERROR;
- }
-
- try {
- Scripting::play_sound(arg0);
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'play_sound'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger grease_wrapper(HSQUIRRELVM vm)
-{
- (void) vm;
-
- try {
- Scripting::grease();
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'grease'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger invincible_wrapper(HSQUIRRELVM vm)
-{
- (void) vm;
-
- try {
- Scripting::invincible();
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'invincible'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger ghost_wrapper(HSQUIRRELVM vm)
-{
- (void) vm;
-
- try {
- Scripting::ghost();
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'ghost'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger mortal_wrapper(HSQUIRRELVM vm)
-{
- (void) vm;
-
- try {
- Scripting::mortal();
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'mortal'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger restart_wrapper(HSQUIRRELVM vm)
-{
- (void) vm;
-
- try {
- Scripting::restart();
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'restart'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger whereami_wrapper(HSQUIRRELVM vm)
-{
- (void) vm;
-
- try {
- Scripting::whereami();
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'whereami'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger gotoend_wrapper(HSQUIRRELVM vm)
-{
- (void) vm;
-
- try {
- Scripting::gotoend();
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'gotoend'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger camera_wrapper(HSQUIRRELVM vm)
-{
- (void) vm;
-
- try {
- Scripting::camera();
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'camera'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger quit_wrapper(HSQUIRRELVM vm)
-{
- (void) vm;
-
- try {
- Scripting::quit();
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'quit'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger rand_wrapper(HSQUIRRELVM vm)
-{
-
- try {
- int return_value = Scripting::rand();
-
- sq_pushinteger(vm, return_value);
- return 1;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'rand'"));
- return SQ_ERROR;
- }
-
-}
-
-} // end of namespace Wrapper
-void create_squirrel_instance(HSQUIRRELVM v, Scripting::DisplayEffect* object, bool setup_releasehook)
-{
- using namespace Wrapper;
-
- sq_pushroottable(v);
- sq_pushstring(v, "DisplayEffect", -1);
- if(SQ_FAILED(sq_get(v, -2))) {
- std::ostringstream msg;
- msg << "Couldn't resolved squirrel type 'DisplayEffect'";
- throw SquirrelError(v, msg.str());
- }
-
- if(SQ_FAILED(sq_createinstance(v, -1)) || SQ_FAILED(sq_setinstanceup(v, -1, object))) {
- std::ostringstream msg;
- msg << "Couldn't setup squirrel instance for object of type 'DisplayEffect'";
- throw SquirrelError(v, msg.str());
- }
- sq_remove(v, -2); // remove object name
-
- if(setup_releasehook) {
- sq_setreleasehook(v, -1, DisplayEffect_release_hook);
- }
-
- sq_remove(v, -2); // remove root table
-}
-
-void create_squirrel_instance(HSQUIRRELVM v, Scripting::Camera* object, bool setup_releasehook)
-{
- using namespace Wrapper;
-
- sq_pushroottable(v);
- sq_pushstring(v, "Camera", -1);
- if(SQ_FAILED(sq_get(v, -2))) {
- std::ostringstream msg;
- msg << "Couldn't resolved squirrel type 'Camera'";
- throw SquirrelError(v, msg.str());
- }
-
- if(SQ_FAILED(sq_createinstance(v, -1)) || SQ_FAILED(sq_setinstanceup(v, -1, object))) {
- std::ostringstream msg;
- msg << "Couldn't setup squirrel instance for object of type 'Camera'";
- throw SquirrelError(v, msg.str());
- }
- sq_remove(v, -2); // remove object name
-
- if(setup_releasehook) {
- sq_setreleasehook(v, -1, Camera_release_hook);
- }
-
- sq_remove(v, -2); // remove root table
-}
-
-void create_squirrel_instance(HSQUIRRELVM v, Scripting::Level* object, bool setup_releasehook)
-{
- using namespace Wrapper;
-
- sq_pushroottable(v);
- sq_pushstring(v, "Level", -1);
- if(SQ_FAILED(sq_get(v, -2))) {
- std::ostringstream msg;
- msg << "Couldn't resolved squirrel type 'Level'";
- throw SquirrelError(v, msg.str());
- }
-
- if(SQ_FAILED(sq_createinstance(v, -1)) || SQ_FAILED(sq_setinstanceup(v, -1, object))) {
- std::ostringstream msg;
- msg << "Couldn't setup squirrel instance for object of type 'Level'";
- throw SquirrelError(v, msg.str());
- }
- sq_remove(v, -2); // remove object name
-
- if(setup_releasehook) {
- sq_setreleasehook(v, -1, Level_release_hook);
- }
-
- sq_remove(v, -2); // remove root table
-}
-
-void create_squirrel_instance(HSQUIRRELVM v, Scripting::ScriptedObject* object, bool setup_releasehook)
-{
- using namespace Wrapper;
-
- sq_pushroottable(v);
- sq_pushstring(v, "ScriptedObject", -1);
- if(SQ_FAILED(sq_get(v, -2))) {
- std::ostringstream msg;
- msg << "Couldn't resolved squirrel type 'ScriptedObject'";
- throw SquirrelError(v, msg.str());
- }
-
- if(SQ_FAILED(sq_createinstance(v, -1)) || SQ_FAILED(sq_setinstanceup(v, -1, object))) {
- std::ostringstream msg;
- msg << "Couldn't setup squirrel instance for object of type 'ScriptedObject'";
- throw SquirrelError(v, msg.str());
- }
- sq_remove(v, -2); // remove object name
-
- if(setup_releasehook) {
- sq_setreleasehook(v, -1, ScriptedObject_release_hook);
- }
-
- sq_remove(v, -2); // remove root table
-}
-
-void create_squirrel_instance(HSQUIRRELVM v, Scripting::Text* object, bool setup_releasehook)
-{
- using namespace Wrapper;
-
- sq_pushroottable(v);
- sq_pushstring(v, "Text", -1);
- if(SQ_FAILED(sq_get(v, -2))) {
- std::ostringstream msg;
- msg << "Couldn't resolved squirrel type 'Text'";
- throw SquirrelError(v, msg.str());
- }
-
- if(SQ_FAILED(sq_createinstance(v, -1)) || SQ_FAILED(sq_setinstanceup(v, -1, object))) {
- std::ostringstream msg;
- msg << "Couldn't setup squirrel instance for object of type 'Text'";
- throw SquirrelError(v, msg.str());
- }
- sq_remove(v, -2); // remove object name
-
- if(setup_releasehook) {
- sq_setreleasehook(v, -1, Text_release_hook);
- }
-
- sq_remove(v, -2); // remove root table
-}
-
-void create_squirrel_instance(HSQUIRRELVM v, Scripting::Player* object, bool setup_releasehook)
-{
- using namespace Wrapper;
-
- sq_pushroottable(v);
- sq_pushstring(v, "Player", -1);
- if(SQ_FAILED(sq_get(v, -2))) {
- std::ostringstream msg;
- msg << "Couldn't resolved squirrel type 'Player'";
- throw SquirrelError(v, msg.str());
- }
-
- if(SQ_FAILED(sq_createinstance(v, -1)) || SQ_FAILED(sq_setinstanceup(v, -1, object))) {
- std::ostringstream msg;
- msg << "Couldn't setup squirrel instance for object of type 'Player'";
- throw SquirrelError(v, msg.str());
- }
- sq_remove(v, -2); // remove object name
-
- if(setup_releasehook) {
- sq_setreleasehook(v, -1, Player_release_hook);
- }
-
- sq_remove(v, -2); // remove root table
-}
-
-void create_squirrel_instance(HSQUIRRELVM v, Scripting::FloatingImage* object, bool setup_releasehook)
-{
- using namespace Wrapper;
-
- sq_pushroottable(v);
- sq_pushstring(v, "FloatingImage", -1);
- if(SQ_FAILED(sq_get(v, -2))) {
- std::ostringstream msg;
- msg << "Couldn't resolved squirrel type 'FloatingImage'";
- throw SquirrelError(v, msg.str());
- }
-
- if(SQ_FAILED(sq_createinstance(v, -1)) || SQ_FAILED(sq_setinstanceup(v, -1, object))) {
- std::ostringstream msg;
- msg << "Couldn't setup squirrel instance for object of type 'FloatingImage'";
- throw SquirrelError(v, msg.str());
- }
- sq_remove(v, -2); // remove object name
-
- if(setup_releasehook) {
- sq_setreleasehook(v, -1, FloatingImage_release_hook);
- }
-
- sq_remove(v, -2); // remove root table
-}
-
-void create_squirrel_instance(HSQUIRRELVM v, Scripting::Platform* object, bool setup_releasehook)
-{
- using namespace Wrapper;
-
- sq_pushroottable(v);
- sq_pushstring(v, "Platform", -1);
- if(SQ_FAILED(sq_get(v, -2))) {
- std::ostringstream msg;
- msg << "Couldn't resolved squirrel type 'Platform'";
- throw SquirrelError(v, msg.str());
- }
-
- if(SQ_FAILED(sq_createinstance(v, -1)) || SQ_FAILED(sq_setinstanceup(v, -1, object))) {
- std::ostringstream msg;
- msg << "Couldn't setup squirrel instance for object of type 'Platform'";
- throw SquirrelError(v, msg.str());
- }
- sq_remove(v, -2); // remove object name
-
- if(setup_releasehook) {
- sq_setreleasehook(v, -1, Platform_release_hook);
- }
-
- sq_remove(v, -2); // remove root table
-}
-
-void create_squirrel_instance(HSQUIRRELVM v, Scripting::Candle* object, bool setup_releasehook)
-{
- using namespace Wrapper;
-
- sq_pushroottable(v);
- sq_pushstring(v, "Candle", -1);
- if(SQ_FAILED(sq_get(v, -2))) {
- std::ostringstream msg;
- msg << "Couldn't resolved squirrel type 'Candle'";
- throw SquirrelError(v, msg.str());
- }
-
- if(SQ_FAILED(sq_createinstance(v, -1)) || SQ_FAILED(sq_setinstanceup(v, -1, object))) {
- std::ostringstream msg;
- msg << "Couldn't setup squirrel instance for object of type 'Candle'";
- throw SquirrelError(v, msg.str());
- }
- sq_remove(v, -2); // remove object name
-
- if(setup_releasehook) {
- sq_setreleasehook(v, -1, Candle_release_hook);
- }
-
- sq_remove(v, -2); // remove root table
-}
-
-void create_squirrel_instance(HSQUIRRELVM v, Scripting::Wind* object, bool setup_releasehook)
-{
- using namespace Wrapper;
-
- sq_pushroottable(v);
- sq_pushstring(v, "Wind", -1);
- if(SQ_FAILED(sq_get(v, -2))) {
- std::ostringstream msg;
- msg << "Couldn't resolved squirrel type 'Wind'";
- throw SquirrelError(v, msg.str());
- }
-
- if(SQ_FAILED(sq_createinstance(v, -1)) || SQ_FAILED(sq_setinstanceup(v, -1, object))) {
- std::ostringstream msg;
- msg << "Couldn't setup squirrel instance for object of type 'Wind'";
- throw SquirrelError(v, msg.str());
- }
- sq_remove(v, -2); // remove object name
-
- if(setup_releasehook) {
- sq_setreleasehook(v, -1, Wind_release_hook);
- }
-
- sq_remove(v, -2); // remove root table
-}
-
-void create_squirrel_instance(HSQUIRRELVM v, Scripting::AmbientSound* object, bool setup_releasehook)
-{
- using namespace Wrapper;
-
- sq_pushroottable(v);
- sq_pushstring(v, "AmbientSound", -1);
- if(SQ_FAILED(sq_get(v, -2))) {
- std::ostringstream msg;
- msg << "Couldn't resolved squirrel type 'AmbientSound'";
- throw SquirrelError(v, msg.str());
- }
-
- if(SQ_FAILED(sq_createinstance(v, -1)) || SQ_FAILED(sq_setinstanceup(v, -1, object))) {
- std::ostringstream msg;
- msg << "Couldn't setup squirrel instance for object of type 'AmbientSound'";
- throw SquirrelError(v, msg.str());
- }
- sq_remove(v, -2); // remove object name
-
- if(setup_releasehook) {
- sq_setreleasehook(v, -1, AmbientSound_release_hook);
- }
-
- sq_remove(v, -2); // remove root table
-}
-
-void create_squirrel_instance(HSQUIRRELVM v, Scripting::Thunderstorm* object, bool setup_releasehook)
-{
- using namespace Wrapper;
-
- sq_pushroottable(v);
- sq_pushstring(v, "Thunderstorm", -1);
- if(SQ_FAILED(sq_get(v, -2))) {
- std::ostringstream msg;
- msg << "Couldn't resolved squirrel type 'Thunderstorm'";
- throw SquirrelError(v, msg.str());
- }
-
- if(SQ_FAILED(sq_createinstance(v, -1)) || SQ_FAILED(sq_setinstanceup(v, -1, object))) {
- std::ostringstream msg;
- msg << "Couldn't setup squirrel instance for object of type 'Thunderstorm'";
- throw SquirrelError(v, msg.str());
- }
- sq_remove(v, -2); // remove object name
-
- if(setup_releasehook) {
- sq_setreleasehook(v, -1, Thunderstorm_release_hook);
- }
-
- sq_remove(v, -2); // remove root table
-}
-
-void create_squirrel_instance(HSQUIRRELVM v, Scripting::TileMap* object, bool setup_releasehook)
-{
- using namespace Wrapper;
-
- sq_pushroottable(v);
- sq_pushstring(v, "TileMap", -1);
- if(SQ_FAILED(sq_get(v, -2))) {
- std::ostringstream msg;
- msg << "Couldn't resolved squirrel type 'TileMap'";
- throw SquirrelError(v, msg.str());
- }
-
- if(SQ_FAILED(sq_createinstance(v, -1)) || SQ_FAILED(sq_setinstanceup(v, -1, object))) {
- std::ostringstream msg;
- msg << "Couldn't setup squirrel instance for object of type 'TileMap'";
- throw SquirrelError(v, msg.str());
- }
- sq_remove(v, -2); // remove object name
-
- if(setup_releasehook) {
- sq_setreleasehook(v, -1, TileMap_release_hook);
- }
-
- sq_remove(v, -2); // remove root table
-}
-
-void create_squirrel_instance(HSQUIRRELVM v, Scripting::SSector* object, bool setup_releasehook)
-{
- using namespace Wrapper;
-
- sq_pushroottable(v);
- sq_pushstring(v, "SSector", -1);
- if(SQ_FAILED(sq_get(v, -2))) {
- std::ostringstream msg;
- msg << "Couldn't resolved squirrel type 'SSector'";
- throw SquirrelError(v, msg.str());
- }
-
- if(SQ_FAILED(sq_createinstance(v, -1)) || SQ_FAILED(sq_setinstanceup(v, -1, object))) {
- std::ostringstream msg;
- msg << "Couldn't setup squirrel instance for object of type 'SSector'";
- throw SquirrelError(v, msg.str());
- }
- sq_remove(v, -2); // remove object name
-
- if(setup_releasehook) {
- sq_setreleasehook(v, -1, SSector_release_hook);
- }
-
- sq_remove(v, -2); // remove root table
-}
-
-void create_squirrel_instance(HSQUIRRELVM v, Scripting::LevelTime* object, bool setup_releasehook)
-{
- using namespace Wrapper;
-
- sq_pushroottable(v);
- sq_pushstring(v, "LevelTime", -1);
- if(SQ_FAILED(sq_get(v, -2))) {
- std::ostringstream msg;
- msg << "Couldn't resolved squirrel type 'LevelTime'";
- throw SquirrelError(v, msg.str());
- }
-
- if(SQ_FAILED(sq_createinstance(v, -1)) || SQ_FAILED(sq_setinstanceup(v, -1, object))) {
- std::ostringstream msg;
- msg << "Couldn't setup squirrel instance for object of type 'LevelTime'";
- throw SquirrelError(v, msg.str());
- }
- sq_remove(v, -2); // remove object name
-
- if(setup_releasehook) {
- sq_setreleasehook(v, -1, LevelTime_release_hook);
- }
-
- sq_remove(v, -2); // remove root table
-}
-
-void create_squirrel_instance(HSQUIRRELVM v, Scripting::WillOWisp* object, bool setup_releasehook)
-{
- using namespace Wrapper;
-
- sq_pushroottable(v);
- sq_pushstring(v, "WillOWisp", -1);
- if(SQ_FAILED(sq_get(v, -2))) {
- std::ostringstream msg;
- msg << "Couldn't resolved squirrel type 'WillOWisp'";
- throw SquirrelError(v, msg.str());
- }
-
- if(SQ_FAILED(sq_createinstance(v, -1)) || SQ_FAILED(sq_setinstanceup(v, -1, object))) {
- std::ostringstream msg;
- msg << "Couldn't setup squirrel instance for object of type 'WillOWisp'";
- throw SquirrelError(v, msg.str());
- }
- sq_remove(v, -2); // remove object name
-
- if(setup_releasehook) {
- sq_setreleasehook(v, -1, WillOWisp_release_hook);
- }
-
- sq_remove(v, -2); // remove root table
-}
-
-void register_supertux_wrapper(HSQUIRRELVM v)
-{
- using namespace Wrapper;
-
- sq_pushstring(v, "ANCHOR_TOP", -1);
- sq_pushinteger(v, 16);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register constant 'ANCHOR_TOP'");
- }
-
- sq_pushstring(v, "ANCHOR_BOTTOM", -1);
- sq_pushinteger(v, 32);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register constant 'ANCHOR_BOTTOM'");
- }
-
- sq_pushstring(v, "ANCHOR_LEFT", -1);
- sq_pushinteger(v, 1);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register constant 'ANCHOR_LEFT'");
- }
-
- sq_pushstring(v, "ANCHOR_RIGHT", -1);
- sq_pushinteger(v, 2);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register constant 'ANCHOR_RIGHT'");
- }
-
- sq_pushstring(v, "ANCHOR_MIDDLE", -1);
- sq_pushinteger(v, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register constant 'ANCHOR_MIDDLE'");
- }
-
- sq_pushstring(v, "ANCHOR_TOP_LEFT", -1);
- sq_pushinteger(v, 17);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register constant 'ANCHOR_TOP_LEFT'");
- }
-
- sq_pushstring(v, "ANCHOR_TOP_RIGHT", -1);
- sq_pushinteger(v, 18);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register constant 'ANCHOR_TOP_RIGHT'");
- }
-
- sq_pushstring(v, "ANCHOR_BOTTOM_LEFT", -1);
- sq_pushinteger(v, 33);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register constant 'ANCHOR_BOTTOM_LEFT'");
- }
-
- sq_pushstring(v, "ANCHOR_BOTTOM_RIGHT", -1);
- sq_pushinteger(v, 34);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register constant 'ANCHOR_BOTTOM_RIGHT'");
- }
-
- sq_pushstring(v, "display", -1);
- sq_newclosure(v, &display_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'display'");
- }
-
- sq_pushstring(v, "print_stacktrace", -1);
- sq_newclosure(v, &print_stacktrace_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'print_stacktrace'");
- }
-
- sq_pushstring(v, "get_current_thread", -1);
- sq_newclosure(v, &get_current_thread_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'get_current_thread'");
- }
-
- sq_pushstring(v, "display_text_file", -1);
- sq_newclosure(v, &display_text_file_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'display_text_file'");
- }
-
- sq_pushstring(v, "load_worldmap", -1);
- sq_newclosure(v, &load_worldmap_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'load_worldmap'");
- }
-
- sq_pushstring(v, "load_level", -1);
- sq_newclosure(v, &load_level_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'load_level'");
- }
-
- sq_pushstring(v, "wait", -1);
- sq_newclosure(v, &wait_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'wait'");
- }
-
- sq_pushstring(v, "wait_for_screenswitch", -1);
- sq_newclosure(v, &wait_for_screenswitch_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'wait_for_screenswitch'");
- }
-
- sq_pushstring(v, "exit_screen", -1);
- sq_newclosure(v, &exit_screen_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'exit_screen'");
- }
-
- sq_pushstring(v, "fadeout_screen", -1);
- sq_newclosure(v, &fadeout_screen_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'fadeout_screen'");
- }
-
- sq_pushstring(v, "shrink_screen", -1);
- sq_newclosure(v, &shrink_screen_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'shrink_screen'");
- }
-
- sq_pushstring(v, "abort_screenfade", -1);
- sq_newclosure(v, &abort_screenfade_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'abort_screenfade'");
- }
-
- sq_pushstring(v, "translate", -1);
- sq_newclosure(v, &translate_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'translate'");
- }
-
- sq_pushstring(v, "import", -1);
- sq_newclosure(v, &import_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'import'");
- }
-
- sq_pushstring(v, "save_state", -1);
- sq_newclosure(v, &save_state_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'save_state'");
- }
-
- sq_pushstring(v, "update_worldmap", -1);
- sq_newclosure(v, &update_worldmap_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'update_worldmap'");
- }
-
- sq_pushstring(v, "debug_collrects", -1);
- sq_newclosure(v, &debug_collrects_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'debug_collrects'");
- }
-
- sq_pushstring(v, "debug_show_fps", -1);
- sq_newclosure(v, &debug_show_fps_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'debug_show_fps'");
- }
-
- sq_pushstring(v, "debug_draw_solids_only", -1);
- sq_newclosure(v, &debug_draw_solids_only_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'debug_draw_solids_only'");
- }
-
- sq_pushstring(v, "play_music", -1);
- sq_newclosure(v, &play_music_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'play_music'");
- }
-
- sq_pushstring(v, "play_sound", -1);
- sq_newclosure(v, &play_sound_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'play_sound'");
- }
-
- sq_pushstring(v, "grease", -1);
- sq_newclosure(v, &grease_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'grease'");
- }
-
- sq_pushstring(v, "invincible", -1);
- sq_newclosure(v, &invincible_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'invincible'");
- }
-
- sq_pushstring(v, "ghost", -1);
- sq_newclosure(v, &ghost_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'ghost'");
- }
-
- sq_pushstring(v, "mortal", -1);
- sq_newclosure(v, &mortal_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'mortal'");
- }
-
- sq_pushstring(v, "restart", -1);
- sq_newclosure(v, &restart_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'restart'");
- }
-
- sq_pushstring(v, "whereami", -1);
- sq_newclosure(v, &whereami_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'whereami'");
- }
-
- sq_pushstring(v, "gotoend", -1);
- sq_newclosure(v, &gotoend_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'gotoend'");
- }
-
- sq_pushstring(v, "camera", -1);
- sq_newclosure(v, &camera_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'camera'");
- }
-
- sq_pushstring(v, "quit", -1);
- sq_newclosure(v, &quit_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'quit'");
- }
-
- sq_pushstring(v, "rand", -1);
- sq_newclosure(v, &rand_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'rand'");
- }
-
- // Register class DisplayEffect
- sq_pushstring(v, "DisplayEffect", -1);
- if(sq_newclass(v, SQFalse) < 0) {
- std::ostringstream msg;
- msg << "Couldn't create new class 'DisplayEffect'";
- throw SquirrelError(v, msg.str());
- }
- sq_pushstring(v, "fade_out", -1);
- sq_newclosure(v, &DisplayEffect_fade_out_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'fade_out'");
- }
-
- sq_pushstring(v, "fade_in", -1);
- sq_newclosure(v, &DisplayEffect_fade_in_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'fade_in'");
- }
-
- sq_pushstring(v, "set_black", -1);
- sq_newclosure(v, &DisplayEffect_set_black_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'set_black'");
- }
-
- sq_pushstring(v, "is_black", -1);
- sq_newclosure(v, &DisplayEffect_is_black_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'is_black'");
- }
-
- sq_pushstring(v, "sixteen_to_nine", -1);
- sq_newclosure(v, &DisplayEffect_sixteen_to_nine_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'sixteen_to_nine'");
- }
-
- sq_pushstring(v, "four_to_three", -1);
- sq_newclosure(v, &DisplayEffect_four_to_three_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'four_to_three'");
- }
-
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register class 'DisplayEffect'");
- }
-
- // Register class Camera
- sq_pushstring(v, "Camera", -1);
- if(sq_newclass(v, SQFalse) < 0) {
- std::ostringstream msg;
- msg << "Couldn't create new class 'Camera'";
- throw SquirrelError(v, msg.str());
- }
- sq_pushstring(v, "reload_config", -1);
- sq_newclosure(v, &Camera_reload_config_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'reload_config'");
- }
-
- sq_pushstring(v, "shake", -1);
- sq_newclosure(v, &Camera_shake_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'shake'");
- }
-
- sq_pushstring(v, "set_pos", -1);
- sq_newclosure(v, &Camera_set_pos_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'set_pos'");
- }
-
- sq_pushstring(v, "set_mode", -1);
- sq_newclosure(v, &Camera_set_mode_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'set_mode'");
- }
-
- sq_pushstring(v, "scroll_to", -1);
- sq_newclosure(v, &Camera_scroll_to_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'scroll_to'");
- }
-
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register class 'Camera'");
- }
-
- // Register class Level
- sq_pushstring(v, "Level", -1);
- if(sq_newclass(v, SQFalse) < 0) {
- std::ostringstream msg;
- msg << "Couldn't create new class 'Level'";
- throw SquirrelError(v, msg.str());
- }
- sq_pushstring(v, "finish", -1);
- sq_newclosure(v, &Level_finish_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'finish'");
- }
-
- sq_pushstring(v, "spawn", -1);
- sq_newclosure(v, &Level_spawn_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'spawn'");
- }
-
- sq_pushstring(v, "flip_vertically", -1);
- sq_newclosure(v, &Level_flip_vertically_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'flip_vertically'");
- }
-
- sq_pushstring(v, "toggle_pause", -1);
- sq_newclosure(v, &Level_toggle_pause_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'toggle_pause'");
- }
-
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register class 'Level'");
- }
-
- // Register class ScriptedObject
- sq_pushstring(v, "ScriptedObject", -1);
- if(sq_newclass(v, SQFalse) < 0) {
- std::ostringstream msg;
- msg << "Couldn't create new class 'ScriptedObject'";
- throw SquirrelError(v, msg.str());
- }
- sq_pushstring(v, "set_action", -1);
- sq_newclosure(v, &ScriptedObject_set_action_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'set_action'");
- }
-
- sq_pushstring(v, "get_action", -1);
- sq_newclosure(v, &ScriptedObject_get_action_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'get_action'");
- }
-
- sq_pushstring(v, "move", -1);
- sq_newclosure(v, &ScriptedObject_move_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'move'");
- }
-
- sq_pushstring(v, "set_pos", -1);
- sq_newclosure(v, &ScriptedObject_set_pos_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'set_pos'");
- }
-
- sq_pushstring(v, "get_pos_x", -1);
- sq_newclosure(v, &ScriptedObject_get_pos_x_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'get_pos_x'");
- }
-
- sq_pushstring(v, "get_pos_y", -1);
- sq_newclosure(v, &ScriptedObject_get_pos_y_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'get_pos_y'");
- }
-
- sq_pushstring(v, "set_velocity", -1);
- sq_newclosure(v, &ScriptedObject_set_velocity_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'set_velocity'");
- }
-
- sq_pushstring(v, "get_velocity_x", -1);
- sq_newclosure(v, &ScriptedObject_get_velocity_x_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'get_velocity_x'");
- }
-
- sq_pushstring(v, "get_velocity_y", -1);
- sq_newclosure(v, &ScriptedObject_get_velocity_y_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'get_velocity_y'");
- }
-
- sq_pushstring(v, "set_visible", -1);
- sq_newclosure(v, &ScriptedObject_set_visible_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'set_visible'");
- }
-
- sq_pushstring(v, "is_visible", -1);
- sq_newclosure(v, &ScriptedObject_is_visible_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'is_visible'");
- }
-
- sq_pushstring(v, "set_solid", -1);
- sq_newclosure(v, &ScriptedObject_set_solid_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'set_solid'");
- }
-
- sq_pushstring(v, "is_solid", -1);
- sq_newclosure(v, &ScriptedObject_is_solid_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'is_solid'");
- }
-
- sq_pushstring(v, "get_name", -1);
- sq_newclosure(v, &ScriptedObject_get_name_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'get_name'");
- }
-
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register class 'ScriptedObject'");
- }
-
- // Register class Text
- sq_pushstring(v, "Text", -1);
- if(sq_newclass(v, SQFalse) < 0) {
- std::ostringstream msg;
- msg << "Couldn't create new class 'Text'";
- throw SquirrelError(v, msg.str());
- }
- sq_pushstring(v, "set_text", -1);
- sq_newclosure(v, &Text_set_text_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'set_text'");
- }
-
- sq_pushstring(v, "set_font", -1);
- sq_newclosure(v, &Text_set_font_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'set_font'");
- }
-
- sq_pushstring(v, "fade_in", -1);
- sq_newclosure(v, &Text_fade_in_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'fade_in'");
- }
-
- sq_pushstring(v, "fade_out", -1);
- sq_newclosure(v, &Text_fade_out_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'fade_out'");
- }
-
- sq_pushstring(v, "set_visible", -1);
- sq_newclosure(v, &Text_set_visible_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'set_visible'");
- }
-
- sq_pushstring(v, "set_centered", -1);
- sq_newclosure(v, &Text_set_centered_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'set_centered'");
- }
-
- sq_pushstring(v, "set_pos", -1);
- sq_newclosure(v, &Text_set_pos_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'set_pos'");
- }
-
- sq_pushstring(v, "get_pos_x", -1);
- sq_newclosure(v, &Text_get_pos_x_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'get_pos_x'");
- }
-
- sq_pushstring(v, "get_pos_y", -1);
- sq_newclosure(v, &Text_get_pos_y_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'get_pos_y'");
- }
-
- sq_pushstring(v, "set_anchor_point", -1);
- sq_newclosure(v, &Text_set_anchor_point_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'set_anchor_point'");
- }
-
- sq_pushstring(v, "get_anchor_point", -1);
- sq_newclosure(v, &Text_get_anchor_point_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'get_anchor_point'");
- }
-
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register class 'Text'");
- }
-
- // Register class Player
- sq_pushstring(v, "Player", -1);
- if(sq_newclass(v, SQFalse) < 0) {
- std::ostringstream msg;
- msg << "Couldn't create new class 'Player'";
- throw SquirrelError(v, msg.str());
- }
- sq_pushstring(v, "add_bonus", -1);
- sq_newclosure(v, &Player_add_bonus_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'add_bonus'");
- }
-
- sq_pushstring(v, "add_coins", -1);
- sq_newclosure(v, &Player_add_coins_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'add_coins'");
- }
-
- sq_pushstring(v, "make_invincible", -1);
- sq_newclosure(v, &Player_make_invincible_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'make_invincible'");
- }
-
- sq_pushstring(v, "deactivate", -1);
- sq_newclosure(v, &Player_deactivate_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'deactivate'");
- }
-
- sq_pushstring(v, "activate", -1);
- sq_newclosure(v, &Player_activate_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'activate'");
- }
-
- sq_pushstring(v, "walk", -1);
- sq_newclosure(v, &Player_walk_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'walk'");
- }
-
- sq_pushstring(v, "set_visible", -1);
- sq_newclosure(v, &Player_set_visible_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'set_visible'");
- }
-
- sq_pushstring(v, "get_visible", -1);
- sq_newclosure(v, &Player_get_visible_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'get_visible'");
- }
-
- sq_pushstring(v, "kill", -1);
- sq_newclosure(v, &Player_kill_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'kill'");
- }
-
- sq_pushstring(v, "set_ghost_mode", -1);
- sq_newclosure(v, &Player_set_ghost_mode_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'set_ghost_mode'");
- }
-
- sq_pushstring(v, "get_ghost_mode", -1);
- sq_newclosure(v, &Player_get_ghost_mode_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'get_ghost_mode'");
- }
-
- sq_pushstring(v, "do_cheer", -1);
- sq_newclosure(v, &Player_do_cheer_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'do_cheer'");
- }
-
- sq_pushstring(v, "do_duck", -1);
- sq_newclosure(v, &Player_do_duck_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'do_duck'");
- }
-
- sq_pushstring(v, "do_standup", -1);
- sq_newclosure(v, &Player_do_standup_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'do_standup'");
- }
-
- sq_pushstring(v, "do_backflip", -1);
- sq_newclosure(v, &Player_do_backflip_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'do_backflip'");
- }
-
- sq_pushstring(v, "do_jump", -1);
- sq_newclosure(v, &Player_do_jump_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'do_jump'");
- }
-
- sq_pushstring(v, "trigger_sequence", -1);
- sq_newclosure(v, &Player_trigger_sequence_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'trigger_sequence'");
- }
-
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register class 'Player'");
- }
-
- // Register class FloatingImage
- sq_pushstring(v, "FloatingImage", -1);
- if(sq_newclass(v, SQFalse) < 0) {
- std::ostringstream msg;
- msg << "Couldn't create new class 'FloatingImage'";
- throw SquirrelError(v, msg.str());
- }
- sq_pushstring(v, "constructor", -1);
- sq_newclosure(v, &FloatingImage_constructor_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'constructor'");
- }
-
- sq_pushstring(v, "set_layer", -1);
- sq_newclosure(v, &FloatingImage_set_layer_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'set_layer'");
- }
-
- sq_pushstring(v, "get_layer", -1);
- sq_newclosure(v, &FloatingImage_get_layer_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'get_layer'");
- }
-
- sq_pushstring(v, "set_pos", -1);
- sq_newclosure(v, &FloatingImage_set_pos_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'set_pos'");
- }
-
- sq_pushstring(v, "get_pos_x", -1);
- sq_newclosure(v, &FloatingImage_get_pos_x_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'get_pos_x'");
- }
-
- sq_pushstring(v, "get_pos_y", -1);
- sq_newclosure(v, &FloatingImage_get_pos_y_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'get_pos_y'");
- }
-
- sq_pushstring(v, "set_anchor_point", -1);
- sq_newclosure(v, &FloatingImage_set_anchor_point_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'set_anchor_point'");
- }
-
- sq_pushstring(v, "get_anchor_point", -1);
- sq_newclosure(v, &FloatingImage_get_anchor_point_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'get_anchor_point'");
- }
-
- sq_pushstring(v, "set_visible", -1);
- sq_newclosure(v, &FloatingImage_set_visible_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'set_visible'");
- }
-
- sq_pushstring(v, "get_visible", -1);
- sq_newclosure(v, &FloatingImage_get_visible_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'get_visible'");
- }
-
- sq_pushstring(v, "set_action", -1);
- sq_newclosure(v, &FloatingImage_set_action_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'set_action'");
- }
-
- sq_pushstring(v, "get_action", -1);
- sq_newclosure(v, &FloatingImage_get_action_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'get_action'");
- }
-
- sq_pushstring(v, "fade_in", -1);
- sq_newclosure(v, &FloatingImage_fade_in_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'fade_in'");
- }
-
- sq_pushstring(v, "fade_out", -1);
- sq_newclosure(v, &FloatingImage_fade_out_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'fade_out'");
- }
-
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register class 'FloatingImage'");
- }
-
- // Register class Platform
- sq_pushstring(v, "Platform", -1);
- if(sq_newclass(v, SQFalse) < 0) {
- std::ostringstream msg;
- msg << "Couldn't create new class 'Platform'";
- throw SquirrelError(v, msg.str());
- }
- sq_pushstring(v, "goto_node", -1);
- sq_newclosure(v, &Platform_goto_node_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'goto_node'");
- }
-
- sq_pushstring(v, "start_moving", -1);
- sq_newclosure(v, &Platform_start_moving_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'start_moving'");
- }
-
- sq_pushstring(v, "stop_moving", -1);
- sq_newclosure(v, &Platform_stop_moving_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'stop_moving'");
- }
-
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register class 'Platform'");
- }
-
- // Register class Candle
- sq_pushstring(v, "Candle", -1);
- if(sq_newclass(v, SQFalse) < 0) {
- std::ostringstream msg;
- msg << "Couldn't create new class 'Candle'";
- throw SquirrelError(v, msg.str());
- }
- sq_pushstring(v, "get_burning", -1);
- sq_newclosure(v, &Candle_get_burning_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'get_burning'");
- }
-
- sq_pushstring(v, "set_burning", -1);
- sq_newclosure(v, &Candle_set_burning_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'set_burning'");
- }
-
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register class 'Candle'");
- }
-
- // Register class Wind
- sq_pushstring(v, "Wind", -1);
- if(sq_newclass(v, SQFalse) < 0) {
- std::ostringstream msg;
- msg << "Couldn't create new class 'Wind'";
- throw SquirrelError(v, msg.str());
- }
- sq_pushstring(v, "start", -1);
- sq_newclosure(v, &Wind_start_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'start'");
- }
-
- sq_pushstring(v, "stop", -1);
- sq_newclosure(v, &Wind_stop_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'stop'");
- }
-
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register class 'Wind'");
- }
-
- // Register class AmbientSound
- sq_pushstring(v, "AmbientSound", -1);
- if(sq_newclass(v, SQFalse) < 0) {
- std::ostringstream msg;
- msg << "Couldn't create new class 'AmbientSound'";
- throw SquirrelError(v, msg.str());
- }
- sq_pushstring(v, "set_pos", -1);
- sq_newclosure(v, &AmbientSound_set_pos_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'set_pos'");
- }
-
- sq_pushstring(v, "get_pos_x", -1);
- sq_newclosure(v, &AmbientSound_get_pos_x_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'get_pos_x'");
- }
-
- sq_pushstring(v, "get_pos_y", -1);
- sq_newclosure(v, &AmbientSound_get_pos_y_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'get_pos_y'");
- }
-
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register class 'AmbientSound'");
- }
-
- // Register class Thunderstorm
- sq_pushstring(v, "Thunderstorm", -1);
- if(sq_newclass(v, SQFalse) < 0) {
- std::ostringstream msg;
- msg << "Couldn't create new class 'Thunderstorm'";
- throw SquirrelError(v, msg.str());
- }
- sq_pushstring(v, "start", -1);
- sq_newclosure(v, &Thunderstorm_start_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'start'");
- }
-
- sq_pushstring(v, "stop", -1);
- sq_newclosure(v, &Thunderstorm_stop_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'stop'");
- }
-
- sq_pushstring(v, "thunder", -1);
- sq_newclosure(v, &Thunderstorm_thunder_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'thunder'");
- }
-
- sq_pushstring(v, "lightning", -1);
- sq_newclosure(v, &Thunderstorm_lightning_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'lightning'");
- }
-
- sq_pushstring(v, "flash", -1);
- sq_newclosure(v, &Thunderstorm_flash_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'flash'");
- }
-
- sq_pushstring(v, "electrify", -1);
- sq_newclosure(v, &Thunderstorm_electrify_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'electrify'");
- }
-
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register class 'Thunderstorm'");
- }
-
- // Register class TileMap
- sq_pushstring(v, "TileMap", -1);
- if(sq_newclass(v, SQFalse) < 0) {
- std::ostringstream msg;
- msg << "Couldn't create new class 'TileMap'";
- throw SquirrelError(v, msg.str());
- }
- sq_pushstring(v, "goto_node", -1);
- sq_newclosure(v, &TileMap_goto_node_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'goto_node'");
- }
-
- sq_pushstring(v, "start_moving", -1);
- sq_newclosure(v, &TileMap_start_moving_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'start_moving'");
- }
-
- sq_pushstring(v, "stop_moving", -1);
- sq_newclosure(v, &TileMap_stop_moving_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'stop_moving'");
- }
-
- sq_pushstring(v, "fade", -1);
- sq_newclosure(v, &TileMap_fade_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'fade'");
- }
-
- sq_pushstring(v, "set_alpha", -1);
- sq_newclosure(v, &TileMap_set_alpha_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'set_alpha'");
- }
-
- sq_pushstring(v, "get_alpha", -1);
- sq_newclosure(v, &TileMap_get_alpha_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'get_alpha'");
- }
-
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register class 'TileMap'");
- }
-
- // Register class SSector
- sq_pushstring(v, "SSector", -1);
- if(sq_newclass(v, SQFalse) < 0) {
- std::ostringstream msg;
- msg << "Couldn't create new class 'SSector'";
- throw SquirrelError(v, msg.str());
- }
- sq_pushstring(v, "set_ambient_light", -1);
- sq_newclosure(v, &SSector_set_ambient_light_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'set_ambient_light'");
- }
-
- sq_pushstring(v, "get_ambient_red", -1);
- sq_newclosure(v, &SSector_get_ambient_red_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'get_ambient_red'");
- }
-
- sq_pushstring(v, "get_ambient_green", -1);
- sq_newclosure(v, &SSector_get_ambient_green_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'get_ambient_green'");
- }
-
- sq_pushstring(v, "get_ambient_blue", -1);
- sq_newclosure(v, &SSector_get_ambient_blue_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'get_ambient_blue'");
- }
-
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register class 'SSector'");
- }
-
- // Register class LevelTime
- sq_pushstring(v, "LevelTime", -1);
- if(sq_newclass(v, SQFalse) < 0) {
- std::ostringstream msg;
- msg << "Couldn't create new class 'LevelTime'";
- throw SquirrelError(v, msg.str());
- }
- sq_pushstring(v, "start", -1);
- sq_newclosure(v, &LevelTime_start_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'start'");
- }
-
- sq_pushstring(v, "stop", -1);
- sq_newclosure(v, &LevelTime_stop_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'stop'");
- }
-
- sq_pushstring(v, "get_time", -1);
- sq_newclosure(v, &LevelTime_get_time_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'get_time'");
- }
-
- sq_pushstring(v, "set_time", -1);
- sq_newclosure(v, &LevelTime_set_time_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'set_time'");
- }
-
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register class 'LevelTime'");
- }
-
- // Register class WillOWisp
- sq_pushstring(v, "WillOWisp", -1);
- if(sq_newclass(v, SQFalse) < 0) {
- std::ostringstream msg;
- msg << "Couldn't create new class 'WillOWisp'";
- throw SquirrelError(v, msg.str());
- }
- sq_pushstring(v, "goto_node", -1);
- sq_newclosure(v, &WillOWisp_goto_node_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'goto_node'");
- }
-
- sq_pushstring(v, "set_state", -1);
- sq_newclosure(v, &WillOWisp_set_state_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'set_state'");
- }
-
- sq_pushstring(v, "start_moving", -1);
- sq_newclosure(v, &WillOWisp_start_moving_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'start_moving'");
- }
-
- sq_pushstring(v, "stop_moving", -1);
- sq_newclosure(v, &WillOWisp_stop_moving_wrapper, 0);
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'stop_moving'");
- }
-
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register class 'WillOWisp'");
- }
-
-}
-
-} // end of namespace Scripting
+++ /dev/null
-/**
- * WARNING: This file is automatically generated from:
- * 'src/scripting/wrapper.interface.hpp'
- * DO NOT CHANGE
- */
-#ifndef __supertux_WRAPPER_H__
-#define __supertux_WRAPPER_H__
-
-#include <squirrel.h>
-#include "wrapper.interface.hpp"
-
-namespace Scripting
-{
-
-void register_supertux_wrapper(HSQUIRRELVM v);
-
-void create_squirrel_instance(HSQUIRRELVM v, Scripting::DisplayEffect* object, bool setup_releasehook = false);
-void create_squirrel_instance(HSQUIRRELVM v, Scripting::Camera* object, bool setup_releasehook = false);
-void create_squirrel_instance(HSQUIRRELVM v, Scripting::Level* object, bool setup_releasehook = false);
-void create_squirrel_instance(HSQUIRRELVM v, Scripting::ScriptedObject* object, bool setup_releasehook = false);
-void create_squirrel_instance(HSQUIRRELVM v, Scripting::Text* object, bool setup_releasehook = false);
-void create_squirrel_instance(HSQUIRRELVM v, Scripting::Player* object, bool setup_releasehook = false);
-void create_squirrel_instance(HSQUIRRELVM v, Scripting::FloatingImage* object, bool setup_releasehook = false);
-void create_squirrel_instance(HSQUIRRELVM v, Scripting::Platform* object, bool setup_releasehook = false);
-void create_squirrel_instance(HSQUIRRELVM v, Scripting::Candle* object, bool setup_releasehook = false);
-void create_squirrel_instance(HSQUIRRELVM v, Scripting::Wind* object, bool setup_releasehook = false);
-void create_squirrel_instance(HSQUIRRELVM v, Scripting::AmbientSound* object, bool setup_releasehook = false);
-void create_squirrel_instance(HSQUIRRELVM v, Scripting::Thunderstorm* object, bool setup_releasehook = false);
-void create_squirrel_instance(HSQUIRRELVM v, Scripting::TileMap* object, bool setup_releasehook = false);
-void create_squirrel_instance(HSQUIRRELVM v, Scripting::SSector* object, bool setup_releasehook = false);
-void create_squirrel_instance(HSQUIRRELVM v, Scripting::LevelTime* object, bool setup_releasehook = false);
-void create_squirrel_instance(HSQUIRRELVM v, Scripting::WillOWisp* object, bool setup_releasehook = false);
-
-}
-
-#endif
+++ /dev/null
-/* This file is processed by miniswig to produce the scripting API */
-#include "display_effect.hpp"
-#include "camera.hpp"
-#include "level.hpp"
-#include "scripted_object.hpp"
-#include "text.hpp"
-#include "functions.hpp"
-#include "player.hpp"
-#include "floating_image.hpp"
-#include "anchor_points.hpp"
-#include "platform.hpp"
-#include "candle.hpp"
-#include "wind.hpp"
-#include "ambient_sound.hpp"
-#include "thunderstorm.hpp"
-#include "tilemap.hpp"
-#include "ssector.hpp"
-#include "level_time.hpp"
-#include "willowisp.hpp"
+++ /dev/null
-// $Id$
-//
-// SuperTux - A Jump'n Run
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#include <config.h>
-
-#include <memory>
-#include <algorithm>
-#include <stdexcept>
-#include <iostream>
-#include <fstream>
-#include <sstream>
-#include <stdexcept>
-#include <float.h>
-#include <math.h>
-#include <limits>
-#include <physfs.h>
-
-#include "sector.hpp"
-#include "object/player.hpp"
-#include "object/gameobjs.hpp"
-#include "object/camera.hpp"
-#include "object/background.hpp"
-#include "object/gradient.hpp"
-#include "object/particlesystem.hpp"
-#include "object/particlesystem_interactive.hpp"
-#include "object/tilemap.hpp"
-#include "lisp/parser.hpp"
-#include "lisp/lisp.hpp"
-#include "lisp/writer.hpp"
-#include "lisp/list_iterator.hpp"
-#include "tile.hpp"
-#include "audio/sound_manager.hpp"
-#include "game_session.hpp"
-#include "resources.hpp"
-#include "statistics.hpp"
-#include "object_factory.hpp"
-#include "collision.hpp"
-#include "spawn_point.hpp"
-#include "math/rect.hpp"
-#include "math/aatriangle.hpp"
-#include "object/coin.hpp"
-#include "object/block.hpp"
-#include "object/invisible_block.hpp"
-#include "object/light.hpp"
-#include "object/pulsing_light.hpp"
-#include "object/bullet.hpp"
-#include "object/text_object.hpp"
-#include "object/portable.hpp"
-#include "badguy/jumpy.hpp"
-#include "trigger/sequence_trigger.hpp"
-#include "player_status.hpp"
-#include "scripting/squirrel_util.hpp"
-#include "script_interface.hpp"
-#include "log.hpp"
-#include "main.hpp"
-
-Sector* Sector::_current = 0;
-
-bool Sector::show_collrects = false;
-bool Sector::draw_solids_only = false;
-
-Sector::Sector(Level* parent)
- : level(parent), currentmusic(LEVEL_MUSIC),
- ambient_light( 1.0f, 1.0f, 1.0f, 1.0f ), gravity(10.0), player(0), camera(0)
-{
- add_object(new Player(player_status, "Tux"));
- add_object(new DisplayEffect("Effect"));
- add_object(new TextObject("Text"));
-
- // create a new squirrel table for the sector
- using namespace Scripting;
-
- sq_collectgarbage(global_vm);
-
- sq_newtable(global_vm);
- sq_pushroottable(global_vm);
- if(SQ_FAILED(sq_setdelegate(global_vm, -2)))
- throw Scripting::SquirrelError(global_vm, "Couldn't set sector_table delegate");
-
- sq_resetobject(§or_table);
- if(SQ_FAILED(sq_getstackobj(global_vm, -1, §or_table)))
- throw Scripting::SquirrelError(global_vm, "Couldn't get sector table");
- sq_addref(global_vm, §or_table);
- sq_pop(global_vm, 1);
-}
-
-Sector::~Sector()
-{
- using namespace Scripting;
-
- deactivate();
-
- for(ScriptList::iterator i = scripts.begin();
- i != scripts.end(); ++i) {
- HSQOBJECT& object = *i;
- sq_release(global_vm, &object);
- }
- sq_release(global_vm, §or_table);
- sq_collectgarbage(global_vm);
-
- update_game_objects();
- assert(gameobjects_new.size() == 0);
-
- for(GameObjects::iterator i = gameobjects.begin();
- i != gameobjects.end(); ++i) {
- GameObject* object = *i;
- before_object_remove(object);
- object->unref();
- }
-
- for(SpawnPoints::iterator i = spawnpoints.begin(); i != spawnpoints.end();
- ++i)
- delete *i;
-}
-
-Level*
-Sector::get_level()
-{
- return level;
-}
-
-GameObject*
-Sector::parse_object(const std::string& name, const lisp::Lisp& reader)
-{
- if(name == "camera") {
- Camera* camera = new Camera(this, "Camera");
- camera->parse(reader);
- return camera;
- } else if(name == "particles-snow") {
- SnowParticleSystem* partsys = new SnowParticleSystem();
- partsys->parse(reader);
- return partsys;
- } else if(name == "particles-rain") {
- RainParticleSystem* partsys = new RainParticleSystem();
- partsys->parse(reader);
- return partsys;
- } else if(name == "particles-comets") {
- CometParticleSystem* partsys = new CometParticleSystem();
- partsys->parse(reader);
- return partsys;
- } else if(name == "particles-ghosts") {
- GhostParticleSystem* partsys = new GhostParticleSystem();
- partsys->parse(reader);
- return partsys;
- } else if(name == "particles-clouds") {
- CloudParticleSystem* partsys = new CloudParticleSystem();
- partsys->parse(reader);
- return partsys;
- } else if(name == "money") { // for compatibility with old maps
- return new Jumpy(reader);
- }
-
- try {
- return create_object(name, reader);
- } catch(std::exception& e) {
- log_warning << e.what() << "" << std::endl;
- }
-
- return 0;
-}
-
-void
-Sector::parse(const lisp::Lisp& sector)
-{
- bool has_background = false;
- lisp::ListIterator iter(§or);
- while(iter.next()) {
- const std::string& token = iter.item();
- if(token == "name") {
- iter.value()->get(name);
- } else if(token == "gravity") {
- iter.value()->get(gravity);
- } else if(token == "music") {
- iter.value()->get(music);
- } else if(token == "spawnpoint") {
- SpawnPoint* sp = new SpawnPoint(iter.lisp());
- spawnpoints.push_back(sp);
- } else if(token == "init-script") {
- iter.value()->get(init_script);
- } else if(token == "ambient-light") {
- std::vector<float> vColor;
- sector.get_vector( "ambient-light", vColor );
- if(vColor.size() < 3) {
- log_warning << "(ambient-light) requires a color as argument" << std::endl;
- } else {
- ambient_light = Color( vColor );
- }
- } else {
- GameObject* object = parse_object(token, *(iter.lisp()));
- if(object) {
- if(dynamic_cast<Background *>(object)) {
- has_background = true;
- } else if(dynamic_cast<Gradient *>(object)) {
- has_background = true;
- }
- add_object(object);
- }
- }
- }
-
- if(!has_background) {
- Gradient* gradient = new Gradient();
- gradient->set_gradient(Color(0.3, 0.4, 0.75), Color(1, 1, 1));
- add_object(gradient);
- }
-
- update_game_objects();
-
- if(solid_tilemaps.size() < 1) log_warning << "sector '" << name << "' does not contain a solid tile layer." << std::endl;
-
- fix_old_tiles();
- if(!camera) {
- log_warning << "sector '" << name << "' does not contain a camera." << std::endl;
- update_game_objects();
- add_object(new Camera(this, "Camera"));
- }
-
- update_game_objects();
-}
-
-void
-Sector::parse_old_format(const lisp::Lisp& reader)
-{
- name = "main";
- reader.get("gravity", gravity);
-
- std::string backgroundimage;
- if (reader.get("background", backgroundimage) && (backgroundimage != "")) {
- if (backgroundimage == "arctis.png") backgroundimage = "arctis.jpg";
- if (backgroundimage == "arctis2.jpg") backgroundimage = "arctis.jpg";
- if (backgroundimage == "ocean.png") backgroundimage = "ocean.jpg";
- backgroundimage = "images/background/" + backgroundimage;
- if (!PHYSFS_exists(backgroundimage.c_str())) {
- log_warning << "Background image \"" << backgroundimage << "\" not found. Ignoring." << std::endl;
- backgroundimage = "";
- }
- }
-
- float bgspeed = .5;
- reader.get("bkgd_speed", bgspeed);
- bgspeed /= 100;
-
- Color bkgd_top, bkgd_bottom;
- int r = 0, g = 0, b = 128;
- reader.get("bkgd_red_top", r);
- reader.get("bkgd_green_top", g);
- reader.get("bkgd_blue_top", b);
- bkgd_top.red = static_cast<float> (r) / 255.0f;
- bkgd_top.green = static_cast<float> (g) / 255.0f;
- bkgd_top.blue = static_cast<float> (b) / 255.0f;
-
- reader.get("bkgd_red_bottom", r);
- reader.get("bkgd_green_bottom", g);
- reader.get("bkgd_blue_bottom", b);
- bkgd_bottom.red = static_cast<float> (r) / 255.0f;
- bkgd_bottom.green = static_cast<float> (g) / 255.0f;
- bkgd_bottom.blue = static_cast<float> (b) / 255.0f;
-
- if(backgroundimage != "") {
- Background* background = new Background();
- background->set_image(backgroundimage, bgspeed);
- add_object(background);
- } else {
- Gradient* gradient = new Gradient();
- gradient->set_gradient(bkgd_top, bkgd_bottom);
- add_object(gradient);
- }
-
- std::string particlesystem;
- reader.get("particle_system", particlesystem);
- if(particlesystem == "clouds")
- add_object(new CloudParticleSystem());
- else if(particlesystem == "snow")
- add_object(new SnowParticleSystem());
- else if(particlesystem == "rain")
- add_object(new RainParticleSystem());
-
- Vector startpos(100, 170);
- reader.get("start_pos_x", startpos.x);
- reader.get("start_pos_y", startpos.y);
-
- SpawnPoint* spawn = new SpawnPoint;
- spawn->pos = startpos;
- spawn->name = "main";
- spawnpoints.push_back(spawn);
-
- music = "chipdisko.ogg";
- // skip reading music filename. It's all .ogg now, anyway
- /*
- reader.get("music", music);
- */
- music = "music/" + music;
-
- int width = 30, height = 15;
- reader.get("width", width);
- reader.get("height", height);
-
- std::vector<unsigned int> tiles;
- if(reader.get_vector("interactive-tm", tiles)
- || reader.get_vector("tilemap", tiles)) {
- TileMap* tilemap = new TileMap();
- tilemap->set(width, height, tiles, LAYER_TILES, true);
-
- // replace tile id 112 (old invisible tile) with 1311 (new invisible tile)
- for(size_t x=0; x < tilemap->get_width(); ++x) {
- for(size_t y=0; y < tilemap->get_height(); ++y) {
- const Tile* tile = tilemap->get_tile(x, y);
- if(tile->getID() == 112) tilemap->change(x, y, 1311);
- }
- }
-
- if (height < 19) tilemap->resize(width, 19);
- add_object(tilemap);
- }
-
- if(reader.get_vector("background-tm", tiles)) {
- TileMap* tilemap = new TileMap();
- tilemap->set(width, height, tiles, LAYER_BACKGROUNDTILES, false);
- if (height < 19) tilemap->resize(width, 19);
- add_object(tilemap);
- }
-
- if(reader.get_vector("foreground-tm", tiles)) {
- TileMap* tilemap = new TileMap();
- tilemap->set(width, height, tiles, LAYER_FOREGROUNDTILES, false);
-
- // fill additional space in foreground with tiles of ID 2035 (lightmap/black)
- if (height < 19) tilemap->resize(width, 19, 2035);
-
- add_object(tilemap);
- }
-
- // read reset-points (now spawn-points)
- const lisp::Lisp* resetpoints = reader.get_lisp("reset-points");
- if(resetpoints) {
- lisp::ListIterator iter(resetpoints);
- while(iter.next()) {
- if(iter.item() == "point") {
- Vector sp_pos;
- if(reader.get("x", sp_pos.x) && reader.get("y", sp_pos.y))
- {
- SpawnPoint* sp = new SpawnPoint;
- sp->name = "main";
- sp->pos = sp_pos;
- spawnpoints.push_back(sp);
- }
- } else {
- log_warning << "Unknown token '" << iter.item() << "' in reset-points." << std::endl;
- }
- }
- }
-
- // read objects
- const lisp::Lisp* objects = reader.get_lisp("objects");
- if(objects) {
- lisp::ListIterator iter(objects);
- while(iter.next()) {
- GameObject* object = parse_object(iter.item(), *(iter.lisp()));
- if(object) {
- add_object(object);
- } else {
- log_warning << "Unknown object '" << iter.item() << "' in level." << std::endl;
- }
- }
- }
-
- // add a camera
- Camera* camera = new Camera(this, "Camera");
- add_object(camera);
-
- update_game_objects();
-
- if(solid_tilemaps.size() < 1) log_warning << "sector '" << name << "' does not contain a solid tile layer." << std::endl;
-
- fix_old_tiles();
- update_game_objects();
-}
-
-void
-Sector::fix_old_tiles()
-{
- for(std::list<TileMap*>::iterator i = solid_tilemaps.begin(); i != solid_tilemaps.end(); i++) {
- TileMap* solids = *i;
- for(size_t x=0; x < solids->get_width(); ++x) {
- for(size_t y=0; y < solids->get_height(); ++y) {
- const Tile* tile = solids->get_tile(x, y);
- Vector pos(solids->get_x_offset() + x*32, solids->get_y_offset() + y*32);
-
- if(tile->getID() == 112) {
- add_object(new InvisibleBlock(pos));
- solids->change(x, y, 0);
- } else if(tile->getAttributes() & Tile::COIN) {
- add_object(new Coin(pos));
- solids->change(x, y, 0);
- } else if(tile->getAttributes() & Tile::FULLBOX) {
- add_object(new BonusBlock(pos, tile->getData()));
- solids->change(x, y, 0);
- } else if(tile->getAttributes() & Tile::BRICK) {
- add_object(new Brick(pos, tile->getData()));
- solids->change(x, y, 0);
- } else if(tile->getAttributes() & Tile::GOAL) {
- std::string sequence = tile->getData() == 0 ? "endsequence" : "stoptux";
- add_object(new SequenceTrigger(pos, sequence));
- solids->change(x, y, 0);
- }
- }
- }
- }
-
- // add lights for special tiles
- for(GameObjects::iterator i = gameobjects.begin(); i != gameobjects.end(); i++) {
- TileMap* tm = dynamic_cast<TileMap*>(*i);
- if (!tm) continue;
- for(size_t x=0; x < tm->get_width(); ++x) {
- for(size_t y=0; y < tm->get_height(); ++y) {
- const Tile* tile = tm->get_tile(x, y);
- Vector pos(tm->get_x_offset() + x*32, tm->get_y_offset() + y*32);
- Vector center(pos.x + 16, pos.y + 16);
-
- // torch
- if (tile->getID() == 1517) {
- float pseudo_rnd = (float)((int)pos.x % 10) / 10;
- add_object(new PulsingLight(center, 1.0f + pseudo_rnd, 0.9f, 1.0f, Color(1.0f, 1.0f, 0.6f, 1.0f)));
- }
- // lava or lavaflow
- if ((tile->getID() == 173) || (tile->getID() == 1700) || (tile->getID() == 1705) || (tile->getID() == 1706)) {
- // space lights a bit
- if (((tm->get_tile(x-1, y)->getID() != tm->get_tile(x,y)->getID())
- && (tm->get_tile(x, y-1)->getID() != tm->get_tile(x,y)->getID()))
- || ((x % 3 == 0) && (y % 3 == 0))) {
- float pseudo_rnd = (float)((int)pos.x % 10) / 10;
- add_object(new PulsingLight(center, 1.0f + pseudo_rnd, 0.8f, 1.0f, Color(1.0f, 0.3f, 0.0f, 1.0f)));
- }
- }
-
- }
- }
- }
-
-
-}
-
-void
-Sector::write(lisp::Writer& writer)
-{
- writer.write_string("name", name);
- writer.write_float("gravity", gravity);
- writer.write_string("music", music);
-
- // write spawnpoints
- for(SpawnPoints::iterator i = spawnpoints.begin(); i != spawnpoints.end();
- ++i) {
- SpawnPoint* spawn = *i;
- writer.start_list("spawn-points");
- writer.write_string("name", spawn->name);
- writer.write_float("x", spawn->pos.x);
- writer.write_float("y", spawn->pos.y);
- writer.end_list("spawn-points");
- }
-
- // write objects
- for(GameObjects::iterator i = gameobjects.begin();
- i != gameobjects.end(); ++i) {
- Serializable* serializable = dynamic_cast<Serializable*> (*i);
- if(serializable)
- serializable->write(writer);
- }
-}
-
-HSQUIRRELVM
-Sector::run_script(std::istream& in, const std::string& sourcename)
-{
- using namespace Scripting;
-
- // garbage collect thread list
- for(ScriptList::iterator i = scripts.begin();
- i != scripts.end(); ) {
- HSQOBJECT& object = *i;
- HSQUIRRELVM vm = object_to_vm(object);
-
- if(sq_getvmstate(vm) != SQ_VMSTATE_SUSPENDED) {
- sq_release(global_vm, &object);
- i = scripts.erase(i);
- continue;
- }
-
- ++i;
- }
-
- HSQOBJECT object = create_thread(global_vm);
- scripts.push_back(object);
-
- HSQUIRRELVM vm = object_to_vm(object);
-
- // set sector_table as roottable for the thread
- sq_pushobject(vm, sector_table);
- sq_setroottable(vm);
-
- compile_and_run(vm, in, sourcename);
-
- return vm;
-}
-
-void
-Sector::add_object(GameObject* object)
-{
- // make sure the object isn't already in the list
-#ifdef DEBUG
- for(GameObjects::iterator i = gameobjects.begin(); i != gameobjects.end();
- ++i) {
- if(*i == object) {
- assert("object already added to sector" == 0);
- }
- }
- for(GameObjects::iterator i = gameobjects_new.begin();
- i != gameobjects_new.end(); ++i) {
- if(*i == object) {
- assert("object already added to sector" == 0);
- }
- }
-#endif
-
- object->ref();
- gameobjects_new.push_back(object);
-}
-
-void
-Sector::activate(const std::string& spawnpoint)
-{
- SpawnPoint* sp = 0;
- for(SpawnPoints::iterator i = spawnpoints.begin(); i != spawnpoints.end();
- ++i) {
- if((*i)->name == spawnpoint) {
- sp = *i;
- break;
- }
- }
- if(!sp) {
- log_warning << "Spawnpoint '" << spawnpoint << "' not found." << std::endl;
- if(spawnpoint != "main") {
- activate("main");
- } else {
- activate(Vector(0, 0));
- }
- } else {
- activate(sp->pos);
- }
-}
-
-void
-Sector::activate(const Vector& player_pos)
-{
- if(_current != this) {
- if(_current != NULL)
- _current->deactivate();
- _current = this;
-
- // register sectortable as sector in scripting
- HSQUIRRELVM vm = Scripting::global_vm;
- sq_pushroottable(vm);
- sq_pushstring(vm, "sector", -1);
- sq_pushobject(vm, sector_table);
- if(SQ_FAILED(sq_createslot(vm, -3)))
- throw Scripting::SquirrelError(vm, "Couldn't set sector in roottable");
- sq_pop(vm, 1);
-
- for(GameObjects::iterator i = gameobjects.begin();
- i != gameobjects.end(); ++i) {
- GameObject* object = *i;
-
- try_expose(object);
- }
- }
- try_expose_me();
-
- // spawn smalltux below spawnpoint
- if (!player->is_big()) {
- player->move(player_pos + Vector(0,32));
- } else {
- player->move(player_pos);
- }
-
- // spawning tux in the ground would kill him
- if(!is_free_of_tiles(player->get_bbox())) {
- log_warning << "Tried spawning Tux in solid matter. Compensating." << std::endl;
- Vector npos = player->get_bbox().p1;
- npos.y-=32;
- player->move(npos);
- }
-
- camera->reset(player->get_pos());
- update_game_objects();
-
- // Run init script
- if(init_script != "") {
- std::istringstream in(init_script);
- run_script(in, std::string("Sector(") + name + ") - init");
- }
-}
-
-void
-Sector::deactivate()
-{
- if(_current != this)
- return;
-
- // remove sector entry from global vm
- HSQUIRRELVM vm = Scripting::global_vm;
- sq_pushroottable(vm);
- sq_pushstring(vm, "sector", -1);
- if(SQ_FAILED(sq_deleteslot(vm, -2, SQFalse)))
- throw Scripting::SquirrelError(vm, "Couldn't unset sector in roottable");
- sq_pop(vm, 1);
-
- for(GameObjects::iterator i = gameobjects.begin();
- i != gameobjects.end(); ++i) {
- GameObject* object = *i;
-
- try_unexpose(object);
- }
-
- try_unexpose_me();
- _current = NULL;
-}
-
-Rect
-Sector::get_active_region()
-{
- return Rect(
- camera->get_translation() - Vector(1600, 1200),
- camera->get_translation() + Vector(1600, 1200) + Vector(SCREEN_WIDTH,SCREEN_HEIGHT));
-}
-
-void
-Sector::update(float elapsed_time)
-{
- player->check_bounds(camera);
-
- /* update objects */
- for(GameObjects::iterator i = gameobjects.begin();
- i != gameobjects.end(); ++i) {
- GameObject* object = *i;
- if(!object->is_valid())
- continue;
-
- object->update(elapsed_time);
- }
-
- /* Handle all possible collisions. */
- handle_collisions();
- update_game_objects();
-}
-
-void
-Sector::update_game_objects()
-{
- /** cleanup marked objects */
- for(std::vector<GameObject*>::iterator i = gameobjects.begin();
- i != gameobjects.end(); /* nothing */) {
- GameObject* object = *i;
-
- if(object->is_valid()) {
- ++i;
- continue;
- }
-
- before_object_remove(object);
-
- object->unref();
- i = gameobjects.erase(i);
- }
-
- /* add newly created objects */
- for(std::vector<GameObject*>::iterator i = gameobjects_new.begin();
- i != gameobjects_new.end(); ++i)
- {
- GameObject* object = *i;
-
- before_object_add(object);
-
- gameobjects.push_back(object);
- }
- gameobjects_new.clear();
-
- /* update solid_tilemaps list */
- //FIXME: this could be more efficient
- solid_tilemaps.clear();
- for(std::vector<GameObject*>::iterator i = gameobjects.begin();
- i != gameobjects.end(); ++i)
- {
- TileMap* tm = dynamic_cast<TileMap*>(*i);
- if (!tm) continue;
- if (tm->is_solid()) solid_tilemaps.push_back(tm);
- }
-
-}
-
-bool
-Sector::before_object_add(GameObject* object)
-{
- Bullet* bullet = dynamic_cast<Bullet*> (object);
- if(bullet != NULL) {
- bullets.push_back(bullet);
- }
-
- MovingObject* movingobject = dynamic_cast<MovingObject*> (object);
- if(movingobject != NULL) {
- moving_objects.push_back(movingobject);
- }
-
- Portable* portable = dynamic_cast<Portable*> (object);
- if(portable != NULL) {
- portables.push_back(portable);
- }
-
- TileMap* tilemap = dynamic_cast<TileMap*> (object);
- if(tilemap != NULL && tilemap->is_solid()) {
- solid_tilemaps.push_back(tilemap);
- }
-
- Camera* camera = dynamic_cast<Camera*> (object);
- if(camera != NULL) {
- if(this->camera != 0) {
- log_warning << "Multiple cameras added. Ignoring" << std::endl;
- return false;
- }
- this->camera = camera;
- }
-
- Player* player = dynamic_cast<Player*> (object);
- if(player != NULL) {
- if(this->player != 0) {
- log_warning << "Multiple players added. Ignoring" << std::endl;
- return false;
- }
- this->player = player;
- }
-
- UsesPhysic *physic_object = dynamic_cast<UsesPhysic *>(object);
- if(physic_object)
- {
- physic_object->physic.set_gravity(gravity);
- }
-
-
- if(_current == this) {
- try_expose(object);
- }
-
- return true;
-}
-
-void
-Sector::try_expose(GameObject* object)
-{
- ScriptInterface* interface = dynamic_cast<ScriptInterface*> (object);
- if(interface != NULL) {
- HSQUIRRELVM vm = Scripting::global_vm;
- sq_pushobject(vm, sector_table);
- interface->expose(vm, -1);
- sq_pop(vm, 1);
- }
-}
-
-void
-Sector::try_expose_me()
-{
- HSQUIRRELVM vm = Scripting::global_vm;
- sq_pushobject(vm, sector_table);
- Scripting::SSector* interface = static_cast<Scripting::SSector*> (this);
- expose_object(vm, -1, interface, "settings", false);
- sq_pop(vm, 1);
-}
-
-void
-Sector::before_object_remove(GameObject* object)
-{
- Portable* portable = dynamic_cast<Portable*> (object);
- if(portable != NULL) {
- portables.erase(std::find(portables.begin(), portables.end(), portable));
- }
- Bullet* bullet = dynamic_cast<Bullet*> (object);
- if(bullet != NULL) {
- bullets.erase(std::find(bullets.begin(), bullets.end(), bullet));
- }
- MovingObject* moving_object = dynamic_cast<MovingObject*> (object);
- if(moving_object != NULL) {
- moving_objects.erase(
- std::find(moving_objects.begin(), moving_objects.end(), moving_object));
- }
-
- if(_current == this)
- try_unexpose(object);
-}
-
-void
-Sector::try_unexpose(GameObject* object)
-{
- ScriptInterface* interface = dynamic_cast<ScriptInterface*> (object);
- if(interface != NULL) {
- HSQUIRRELVM vm = Scripting::global_vm;
- SQInteger oldtop = sq_gettop(vm);
- sq_pushobject(vm, sector_table);
- try {
- interface->unexpose(vm, -1);
- } catch(std::exception& e) {
- log_warning << "Couldn't unregister object: " << e.what() << std::endl;
- }
- sq_settop(vm, oldtop);
- }
-}
-
-void
-Sector::try_unexpose_me()
-{
- HSQUIRRELVM vm = Scripting::global_vm;
- SQInteger oldtop = sq_gettop(vm);
- sq_pushobject(vm, sector_table);
- try {
- Scripting::unexpose_object(vm, -1, "settings");
- } catch(std::exception& e) {
- log_warning << "Couldn't unregister object: " << e.what() << std::endl;
- }
- sq_settop(vm, oldtop);
-}
-void
-Sector::draw(DrawingContext& context)
-{
- context.set_ambient_color( ambient_light );
- context.push_transform();
- context.set_translation(camera->get_translation());
-
- for(GameObjects::iterator i = gameobjects.begin();
- i != gameobjects.end(); ++i) {
- GameObject* object = *i;
- if(!object->is_valid())
- continue;
-
- if (draw_solids_only)
- {
- TileMap* tm = dynamic_cast<TileMap*>(object);
- if (tm && !tm->is_solid())
- continue;
- }
-
- object->draw(context);
- }
-
- if(show_collrects) {
- Color col(0.2f, 0.2f, 0.2f, 0.7f);
- for(MovingObjects::iterator i = moving_objects.begin();
- i != moving_objects.end(); ++i) {
- MovingObject* object = *i;
- const Rect& rect = object->get_bbox();
-
- context.draw_filled_rect(rect, col, LAYER_FOREGROUND1 + 10);
- }
- }
-
- context.pop_transform();
-}
-
-/*-------------------------------------------------------------------------
- * Collision Detection
- *-------------------------------------------------------------------------*/
-
-static const float SHIFT_DELTA = 7.0f;
-
-/** r1 is supposed to be moving, r2 a solid object */
-void check_collisions(collision::Constraints* constraints,
- const Vector& movement, const Rect& r1, const Rect& r2,
- GameObject* object = NULL, MovingObject* other = NULL)
-{
- if(!collision::intersects(r1, r2))
- return;
-
- MovingObject *moving_object = dynamic_cast<MovingObject*> (object);
- CollisionHit dummy;
- if(other != NULL && !other->collides(*object, dummy))
- return;
- if(moving_object != NULL && !moving_object->collides(*other, dummy))
- return;
-
- // calculate intersection
- float itop = r1.get_bottom() - r2.get_top();
- float ibottom = r2.get_bottom() - r1.get_top();
- float ileft = r1.get_right() - r2.get_left();
- float iright = r2.get_right() - r1.get_left();
-
- if(fabsf(movement.y) > fabsf(movement.x)) {
- if(ileft < SHIFT_DELTA) {
- constraints->right = std::min(constraints->right, r2.get_left());
- return;
- } else if(iright < SHIFT_DELTA) {
- constraints->left = std::max(constraints->left, r2.get_right());
- return;
- }
- } else {
- // shiftout bottom/top
- if(itop < SHIFT_DELTA) {
- constraints->bottom = std::min(constraints->bottom, r2.get_top());
- return;
- } else if(ibottom < SHIFT_DELTA) {
- constraints->top = std::max(constraints->top, r2.get_bottom());
- return;
- }
- }
-
- if(other != NULL) {
- HitResponse response = other->collision(*object, dummy);
- if(response == PASSTHROUGH)
- return;
-
- if(other->get_movement() != Vector(0, 0)) {
- // TODO what todo when we collide with 2 moving objects?!?
- constraints->ground_movement = other->get_movement();
- }
- }
-
- float vert_penetration = std::min(itop, ibottom);
- float horiz_penetration = std::min(ileft, iright);
- if(vert_penetration < horiz_penetration) {
- if(itop < ibottom) {
- constraints->bottom = std::min(constraints->bottom, r2.get_top());
- constraints->hit.bottom = true;
- } else {
- constraints->top = std::max(constraints->top, r2.get_bottom());
- constraints->hit.top = true;
- }
- } else {
- if(ileft < iright) {
- constraints->right = std::min(constraints->right, r2.get_left());
- constraints->hit.right = true;
- } else {
- constraints->left = std::max(constraints->left, r2.get_right());
- constraints->hit.left = true;
- }
- }
-}
-
-static const float DELTA = .001f;
-
-void
-Sector::collision_tilemap(collision::Constraints* constraints,
- const Vector& movement, const Rect& dest) const
-{
- // calculate rectangle where the object will move
- float x1 = dest.get_left();
- float x2 = dest.get_right();
- float y1 = dest.get_top();
- float y2 = dest.get_bottom();
-
- for(std::list<TileMap*>::const_iterator i = solid_tilemaps.begin(); i != solid_tilemaps.end(); i++) {
- TileMap* solids = *i;
-
- // test with all tiles in this rectangle
- int starttilex = int(x1 - solids->get_x_offset()) / 32;
- int starttiley = int(y1 - solids->get_y_offset()) / 32;
- int max_x = int(x2 - solids->get_x_offset());
- int max_y = int(y2+1 - solids->get_y_offset());
-
- for(int x = starttilex; x*32 < max_x; ++x) {
- for(int y = starttiley; y*32 < max_y; ++y) {
- const Tile* tile = solids->get_tile(x, y);
- if(!tile)
- continue;
- // skip non-solid tiles
- if((tile->getAttributes() & Tile::SOLID) == 0)
- continue;
- // only handle unisolid when the player is falling down and when he was
- // above the tile before
- if(tile->getAttributes() & Tile::UNISOLID) {
- if(movement.y <= 0 || dest.get_bottom() - movement.y - SHIFT_DELTA > y*32)
- continue;
- }
-
- if(tile->getAttributes() & Tile::SLOPE) { // slope tile
- AATriangle triangle;
- Vector p1(x*32 + solids->get_x_offset(), y*32 + solids->get_y_offset());
- Vector p2((x+1)*32 + solids->get_x_offset(), (y+1)*32 + solids->get_y_offset());
- triangle = AATriangle(p1, p2, tile->getData());
-
- collision::rectangle_aatriangle(constraints, dest, triangle);
- } else { // normal rectangular tile
- Rect rect(x*32 + solids->get_x_offset(), y*32 + solids->get_y_offset(), (x+1)*32 + solids->get_x_offset(), (y+1)*32 + solids->get_y_offset());
- check_collisions(constraints, movement, dest, rect);
- }
- }
- }
- }
-}
-
-uint32_t
-Sector::collision_tile_attributes(const Rect& dest) const
-{
- float x1 = dest.p1.x;
- float y1 = dest.p1.y;
- float x2 = dest.p2.x;
- float y2 = dest.p2.y;
-
- uint32_t result = 0;
- for(std::list<TileMap*>::const_iterator i = solid_tilemaps.begin(); i != solid_tilemaps.end(); i++) {
- TileMap* solids = *i;
-
- // test with all tiles in this rectangle
- int starttilex = int(x1 - solids->get_x_offset()) / 32;
- int starttiley = int(y1 - solids->get_y_offset()) / 32;
- int max_x = int(x2 - solids->get_x_offset());
- int max_y = int(y2+1 - solids->get_y_offset());
-
- for(int x = starttilex; x*32 < max_x; ++x) {
- for(int y = starttiley; y*32 < max_y; ++y) {
- const Tile* tile = solids->get_tile(x, y);
- if(!tile)
- continue;
- result |= tile->getAttributes();
- }
- }
- }
-
- return result;
-}
-
-/** fills in CollisionHit and Normal vector of 2 intersecting rectangle */
-static void get_hit_normal(const Rect& r1, const Rect& r2, CollisionHit& hit,
- Vector& normal)
-{
- float itop = r1.get_bottom() - r2.get_top();
- float ibottom = r2.get_bottom() - r1.get_top();
- float ileft = r1.get_right() - r2.get_left();
- float iright = r2.get_right() - r1.get_left();
-
- float vert_penetration = std::min(itop, ibottom);
- float horiz_penetration = std::min(ileft, iright);
- if(vert_penetration < horiz_penetration) {
- if(itop < ibottom) {
- hit.bottom = true;
- normal.y = vert_penetration;
- } else {
- hit.top = true;
- normal.y = -vert_penetration;
- }
- } else {
- if(ileft < iright) {
- hit.right = true;
- normal.x = horiz_penetration;
- } else {
- hit.left = true;
- normal.x = -horiz_penetration;
- }
- }
-}
-
-void
-Sector::collision_object(MovingObject* object1, MovingObject* object2) const
-{
- using namespace collision;
-
- const Rect& r1 = object1->dest;
- const Rect& r2 = object2->dest;
-
- CollisionHit hit;
- if(intersects(object1->dest, object2->dest)) {
- Vector normal;
- get_hit_normal(r1, r2, hit, normal);
-
- if(!object1->collides(*object2, hit))
- return;
- std::swap(hit.left, hit.right);
- std::swap(hit.top, hit.bottom);
- if(!object2->collides(*object1, hit))
- return;
- std::swap(hit.left, hit.right);
- std::swap(hit.top, hit.bottom);
-
- HitResponse response1 = object1->collision(*object2, hit);
- std::swap(hit.left, hit.right);
- std::swap(hit.top, hit.bottom);
- HitResponse response2 = object2->collision(*object1, hit);
- if(response1 == CONTINUE && response2 == CONTINUE) {
- normal *= (0.5 + DELTA);
- object1->dest.move(-normal);
- object2->dest.move(normal);
- } else if (response1 == CONTINUE && response2 == FORCE_MOVE) {
- normal *= (1 + DELTA);
- object1->dest.move(-normal);
- } else if (response1 == FORCE_MOVE && response2 == CONTINUE) {
- normal *= (1 + DELTA);
- object2->dest.move(normal);
- }
- }
-}
-
-void
-Sector::collision_static(collision::Constraints* constraints,
- const Vector& movement, const Rect& dest,
- GameObject& object)
-{
- collision_tilemap(constraints, movement, dest);
-
- // collision with other (static) objects
- for(MovingObjects::iterator i = moving_objects.begin();
- i != moving_objects.end(); ++i) {
- MovingObject* moving_object = *i;
- if(moving_object->get_group() != COLGROUP_STATIC
- && moving_object->get_group() != COLGROUP_MOVING_STATIC)
- continue;
- if(!moving_object->is_valid())
- continue;
-
- if(moving_object != &object)
- check_collisions(constraints, movement, dest, moving_object->bbox,
- &object, moving_object);
- }
-}
-
-void
-Sector::collision_static_constrains(MovingObject& object)
-{
- using namespace collision;
- float infinity = (std::numeric_limits<float>::has_infinity ? std::numeric_limits<float>::infinity() : std::numeric_limits<float>::max());
-
- Constraints constraints;
- Vector movement = object.get_movement();
- Rect& dest = object.dest;
- float owidth = object.get_bbox().get_width();
- float oheight = object.get_bbox().get_height();
-
- for(int i = 0; i < 2; ++i) {
- collision_static(&constraints, Vector(0, movement.y), dest, object);
- if(!constraints.has_constraints())
- break;
-
- // apply calculated horizontal constraints
- if(constraints.bottom < infinity) {
- float height = constraints.bottom - constraints.top;
- if(height < oheight) {
- // we're crushed, but ignore this for now, we'll get this again
- // later if we're really crushed or things will solve itself when
- // looking at the vertical constraints
- }
- dest.p2.y = constraints.bottom - DELTA;
- dest.p1.y = dest.p2.y - oheight;
- } else if(constraints.top > -infinity) {
- dest.p1.y = constraints.top + DELTA;
- dest.p2.y = dest.p1.y + oheight;
- }
- }
- if(constraints.has_constraints()) {
- if(constraints.hit.bottom) {
- dest.move(constraints.ground_movement);
- }
- if(constraints.hit.top || constraints.hit.bottom) {
- constraints.hit.left = false;
- constraints.hit.right = false;
- object.collision_solid(constraints.hit);
- }
- }
-
- constraints = Constraints();
- for(int i = 0; i < 2; ++i) {
- collision_static(&constraints, movement, dest, object);
- if(!constraints.has_constraints())
- break;
-
- // apply calculated vertical constraints
- if(constraints.right < infinity) {
- float width = constraints.right - constraints.left;
- if(width + SHIFT_DELTA < owidth) {
-#if 0
- printf("Object %p crushed horizontally... L:%f R:%f\n", &object,
- constraints.left, constraints.right);
-#endif
- CollisionHit h;
- h.left = true;
- h.right = true;
- h.crush = true;
- object.collision_solid(h);
- } else {
- dest.p2.x = constraints.right - DELTA;
- dest.p1.x = dest.p2.x - owidth;
- }
- } else if(constraints.left > -infinity) {
- dest.p1.x = constraints.left + DELTA;
- dest.p2.x = dest.p1.x + owidth;
- }
- }
-
- if(constraints.has_constraints()) {
- if( constraints.hit.left || constraints.hit.right
- || constraints.hit.top || constraints.hit.bottom
- || constraints.hit.crush )
- object.collision_solid(constraints.hit);
- }
-
- // an extra pass to make sure we're not crushed horizontally
- constraints = Constraints();
- collision_static(&constraints, movement, dest, object);
- if(constraints.bottom < infinity) {
- float height = constraints.bottom - constraints.top;
- if(height + SHIFT_DELTA < oheight) {
-#if 0
- printf("Object %p crushed vertically...\n", &object);
-#endif
- CollisionHit h;
- h.top = true;
- h.bottom = true;
- h.crush = true;
- object.collision_solid(h);
- }
- }
-}
-
-namespace {
- const float MAX_SPEED = 16.0f;
-}
-
-void
-Sector::handle_collisions()
-{
- using namespace collision;
-
- // calculate destination positions of the objects
- for(MovingObjects::iterator i = moving_objects.begin();
- i != moving_objects.end(); ++i) {
- MovingObject* moving_object = *i;
- Vector mov = moving_object->get_movement();
-
- // make sure movement is never faster than MAX_SPEED. Norm is pretty fat, so two addl. checks are done before.
- if (((mov.x > MAX_SPEED * M_SQRT1_2) || (mov.y > MAX_SPEED * M_SQRT1_2)) && (mov.norm() > MAX_SPEED)) {
- moving_object->movement = mov.unit() * MAX_SPEED;
- //log_debug << "Temporarily reduced object's speed of " << mov.norm() << " to " << moving_object->movement.norm() << "." << std::endl;
- }
-
- moving_object->dest = moving_object->get_bbox();
- moving_object->dest.move(moving_object->get_movement());
- }
-
- // part1: COLGROUP_MOVING vs COLGROUP_STATIC and tilemap
- for(MovingObjects::iterator i = moving_objects.begin();
- i != moving_objects.end(); ++i) {
- MovingObject* moving_object = *i;
- if((moving_object->get_group() != COLGROUP_MOVING
- && moving_object->get_group() != COLGROUP_MOVING_STATIC
- && moving_object->get_group() != COLGROUP_MOVING_ONLY_STATIC)
- || !moving_object->is_valid())
- continue;
-
- collision_static_constrains(*moving_object);
- }
-
-
- // part2: COLGROUP_MOVING vs tile attributes
- for(MovingObjects::iterator i = moving_objects.begin();
- i != moving_objects.end(); ++i) {
- MovingObject* moving_object = *i;
- if((moving_object->get_group() != COLGROUP_MOVING
- && moving_object->get_group() != COLGROUP_MOVING_STATIC
- && moving_object->get_group() != COLGROUP_MOVING_ONLY_STATIC)
- || !moving_object->is_valid())
- continue;
-
- uint32_t tile_attributes = collision_tile_attributes(moving_object->dest);
- if(tile_attributes > Tile::FIRST_INTERESTING_FLAG) {
- moving_object->collision_tile(tile_attributes);
- }
- }
-
- // part2.5: COLGROUP_MOVING vs COLGROUP_TOUCHABLE
- for(MovingObjects::iterator i = moving_objects.begin();
- i != moving_objects.end(); ++i) {
- MovingObject* moving_object = *i;
- if((moving_object->get_group() != COLGROUP_MOVING
- && moving_object->get_group() != COLGROUP_MOVING_STATIC)
- || !moving_object->is_valid())
- continue;
-
- for(MovingObjects::iterator i2 = moving_objects.begin();
- i2 != moving_objects.end(); ++i2) {
- MovingObject* moving_object_2 = *i2;
- if(moving_object_2->get_group() != COLGROUP_TOUCHABLE
- || !moving_object_2->is_valid())
- continue;
-
- if(intersects(moving_object->dest, moving_object_2->dest)) {
- Vector normal;
- CollisionHit hit;
- get_hit_normal(moving_object->dest, moving_object_2->dest,
- hit, normal);
- if(!moving_object->collides(*moving_object_2, hit))
- continue;
- if(!moving_object_2->collides(*moving_object, hit))
- continue;
-
- moving_object->collision(*moving_object_2, hit);
- moving_object_2->collision(*moving_object, hit);
- }
- }
- }
-
- // part3: COLGROUP_MOVING vs COLGROUP_MOVING
- for(MovingObjects::iterator i = moving_objects.begin();
- i != moving_objects.end(); ++i) {
- MovingObject* moving_object = *i;
-
- if((moving_object->get_group() != COLGROUP_MOVING
- && moving_object->get_group() != COLGROUP_MOVING_STATIC)
- || !moving_object->is_valid())
- continue;
-
- for(MovingObjects::iterator i2 = i+1;
- i2 != moving_objects.end(); ++i2) {
- MovingObject* moving_object_2 = *i2;
- if((moving_object_2->get_group() != COLGROUP_MOVING
- && moving_object_2->get_group() != COLGROUP_MOVING_STATIC)
- || !moving_object_2->is_valid())
- continue;
-
- collision_object(moving_object, moving_object_2);
- }
- }
-
- // apply object movement
- for(MovingObjects::iterator i = moving_objects.begin();
- i != moving_objects.end(); ++i) {
- MovingObject* moving_object = *i;
-
- moving_object->bbox = moving_object->dest;
- moving_object->movement = Vector(0, 0);
- }
-}
-
-bool
-Sector::is_free_of_tiles(const Rect& rect, const bool ignoreUnisolid) const
-{
- using namespace collision;
-
- for(std::list<TileMap*>::const_iterator i = solid_tilemaps.begin(); i != solid_tilemaps.end(); i++) {
- TileMap* solids = *i;
-
- // test with all tiles in this rectangle
- int starttilex = int(rect.p1.x - solids->get_x_offset()) / 32;
- int starttiley = int(rect.p1.y - solids->get_y_offset()) / 32;
- int max_x = int(rect.p2.x - solids->get_x_offset());
- int max_y = int(rect.p2.y - solids->get_y_offset());
-
- for(int x = starttilex; x*32 <= max_x; ++x) {
- for(int y = starttiley; y*32 <= max_y; ++y) {
- const Tile* tile = solids->get_tile(x, y);
- if(!tile) continue;
- if(tile->getAttributes() & Tile::SLOPE) {
- AATriangle triangle;
- Vector p1(x*32 + solids->get_x_offset(), y*32 + solids->get_y_offset());
- Vector p2((x+1)*32 + solids->get_x_offset(), (y+1)*32 + solids->get_y_offset());
- triangle = AATriangle(p1, p2, tile->getData());
- Constraints constraints;
- return collision::rectangle_aatriangle(&constraints, rect, triangle);
- }
- if((tile->getAttributes() & Tile::SOLID) && !ignoreUnisolid) return false;
- if((tile->getAttributes() & Tile::SOLID) && !(tile->getAttributes() & Tile::UNISOLID)) return false;
- }
- }
- }
-
- return true;
-}
-
-bool
-Sector::is_free_of_statics(const Rect& rect, const MovingObject* ignore_object, const bool ignoreUnisolid) const
-{
- using namespace collision;
-
- if (!is_free_of_tiles(rect, ignoreUnisolid)) return false;
-
- for(MovingObjects::const_iterator i = moving_objects.begin();
- i != moving_objects.end(); ++i) {
- const MovingObject* moving_object = *i;
- if (moving_object == ignore_object) continue;
- if (!moving_object->is_valid()) continue;
- if (moving_object->get_group() == COLGROUP_STATIC) {
- if(intersects(rect, moving_object->get_bbox())) return false;
- }
- }
-
- return true;
-}
-
-bool
-Sector::is_free_of_movingstatics(const Rect& rect, const MovingObject* ignore_object) const
-{
- using namespace collision;
-
- if (!is_free_of_tiles(rect)) return false;
-
- for(MovingObjects::const_iterator i = moving_objects.begin();
- i != moving_objects.end(); ++i) {
- const MovingObject* moving_object = *i;
- if (moving_object == ignore_object) continue;
- if (!moving_object->is_valid()) continue;
- if ((moving_object->get_group() == COLGROUP_MOVING)
- || (moving_object->get_group() == COLGROUP_MOVING_STATIC)
- || (moving_object->get_group() == COLGROUP_STATIC)) {
- if(intersects(rect, moving_object->get_bbox())) return false;
- }
- }
-
- return true;
-}
-
-bool
-Sector::add_bullet(const Vector& pos, float xm, Direction dir)
-{
- // TODO remove this function and move these checks elsewhere...
-
- Bullet* new_bullet = 0;
- if((player_status->bonus == FIRE_BONUS &&
- (int)bullets.size() >= player_status->max_fire_bullets) ||
- (player_status->bonus == ICE_BONUS &&
- (int)bullets.size() >= player_status->max_ice_bullets))
- return false;
- new_bullet = new Bullet(pos, xm, dir, player_status->bonus);
- add_object(new_bullet);
-
- sound_manager->play("sounds/shoot.wav");
-
- return true;
-}
-
-bool
-Sector::add_smoke_cloud(const Vector& pos)
-{
- add_object(new SmokeCloud(pos));
- return true;
-}
-
-void
-Sector::play_music(MusicType type)
-{
- currentmusic = type;
- switch(currentmusic) {
- case LEVEL_MUSIC:
- sound_manager->play_music(music);
- break;
- case HERRING_MUSIC:
- sound_manager->play_music("music/salcon.ogg");
- break;
- case HERRING_WARNING_MUSIC:
- sound_manager->stop_music(TUX_INVINCIBLE_TIME_WARNING);
- break;
- default:
- sound_manager->play_music("");
- break;
- }
-}
-
-MusicType
-Sector::get_music_type()
-{
- return currentmusic;
-}
-
-int
-Sector::get_total_badguys()
-{
- int total_badguys = 0;
- for(GameObjects::iterator i = gameobjects.begin();
- i != gameobjects.end(); ++i) {
- BadGuy* badguy = dynamic_cast<BadGuy*> (*i);
- if (badguy && badguy->countMe)
- total_badguys++;
- }
-
- return total_badguys;
-}
-
-bool
-Sector::inside(const Rect& rect) const
-{
- for(std::list<TileMap*>::const_iterator i = solid_tilemaps.begin(); i != solid_tilemaps.end(); i++) {
- TileMap* solids = *i;
- bool horizontally = ((rect.p2.x >= 0 + solids->get_x_offset()) && (rect.p1.x <= solids->get_width() * 32 + solids->get_x_offset()));
- bool vertically = (rect.p1.y <= solids->get_height() * 32 + solids->get_y_offset());
-
- if (horizontally && vertically)
- return true;
- }
- return false;
-}
-
-float
-Sector::get_width() const
-{
- float width = 0;
- for(std::list<TileMap*>::const_iterator i = solid_tilemaps.begin();
- i != solid_tilemaps.end(); i++) {
- TileMap* solids = *i;
- if ((solids->get_width() * 32 + solids->get_x_offset()) > width) {
- width = solids->get_width() * 32 + solids->get_x_offset();
- }
- }
-
- return width;
-}
-
-float
-Sector::get_height() const
-{
- float height = 0;
- for(std::list<TileMap*>::const_iterator i = solid_tilemaps.begin();
- i != solid_tilemaps.end(); i++) {
- TileMap* solids = *i;
- if ((solids->get_height() * 32 + solids->get_y_offset()) > height) {
- height = solids->get_height() * 32 + solids->get_y_offset();
- }
- }
-
- return height;
-}
-
-void
-Sector::change_solid_tiles(uint32_t old_tile_id, uint32_t new_tile_id)
-{
- for(std::list<TileMap*>::const_iterator i = solid_tilemaps.begin(); i != solid_tilemaps.end(); i++) {
- TileMap* solids = *i;
- solids->change_all(old_tile_id, new_tile_id);
- }
-}
-
-
-void
-Sector::set_ambient_light(float red, float green, float blue)
-{
- ambient_light.red = red;
- ambient_light.green = green;
- ambient_light.blue = blue;
-}
-
-float
-Sector::get_ambient_red()
-{
- return ambient_light.red;
-}
-
-float
-Sector::get_ambient_green()
-{
- return ambient_light.green;
-}
-
-float
-Sector::get_ambient_blue()
-{
- return ambient_light.blue;
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux - A Jump'n Run
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#ifndef SUPERTUX_SECTOR_H
-#define SUPERTUX_SECTOR_H
-
-#include <vector>
-#include <list>
-#include <memory>
-#include <squirrel.h>
-
-#include "direction.hpp"
-#include "video/color.hpp"
-#include "scripting/ssector.hpp"
-
-namespace lisp {
-class Lisp;
-class Writer;
-}
-namespace collision {
-class Constraints;
-}
-
-class Vector;
-class Rect;
-class Sprite;
-class GameObject;
-class Player;
-class Camera;
-class TileMap;
-class Bullet;
-class ScriptInterpreter;
-class SpawnPoint;
-class MovingObject;
-class CollisionHit;
-class Level;
-class Portable;
-class DrawingContext;
-
-enum MusicType {
- LEVEL_MUSIC,
- HERRING_MUSIC,
- HERRING_WARNING_MUSIC
-};
-
-/**
- * This class holds a sector (a part of a level) and all the game objects in
- * the sector
- */
-class Sector : public Scripting::SSector
-{
-public:
- Sector(Level* parent);
- ~Sector();
-
- /// get parent level
- Level* get_level();
-
- /// read sector from lisp file
- void parse(const lisp::Lisp& lisp);
- void parse_old_format(const lisp::Lisp& lisp);
- /// write sector to lisp file
- void write(lisp::Writer& writer);
-
- /// activates this sector (change music, intialize player class, ...)
- void activate(const std::string& spawnpoint);
- void activate(const Vector& player_pos);
- void deactivate();
-
- void update(float elapsed_time);
- void update_game_objects();
-
- void draw(DrawingContext& context);
-
- /**
- * runs a script in the context of the sector (sector_table will be the
- * roottable of this squirrel VM)
- */
- HSQUIRRELVM run_script(std::istream& in, const std::string& sourcename);
-
- /// adds a gameobject
- void add_object(GameObject* object);
-
- void set_name(const std::string& name)
- { this->name = name; }
- const std::string& get_name() const
- { return name; }
-
- /**
- * tests if a given rectangle is inside the sector
- * (a rectangle that is on top of the sector is considered inside)
- */
- bool inside(const Rect& rectangle) const;
-
- void play_music(MusicType musictype);
- MusicType get_music_type();
-
- bool add_bullet(const Vector& pos, float xm, Direction dir);
- bool add_smoke_cloud(const Vector& pos);
-
- /** get currently activated sector. */
- static Sector* current()
- { return _current; }
-
- /** Get total number of badguys */
- int get_total_badguys();
-
- /** Get total number of GameObjects of given type */
- template<class T> int get_total_count()
- {
- int total = 0;
- for(GameObjects::iterator i = gameobjects.begin(); i != gameobjects.end(); ++i) {
- if (dynamic_cast<T*>(*i)) total++;
- }
- return total;
- }
-
- void collision_tilemap(collision::Constraints* constraints,
- const Vector& movement, const Rect& dest) const;
-
- /**
- * Checks if the specified rectangle is free of (solid) tiles.
- * Note that this does not include static objects, e.g. bonus blocks.
- */
- bool is_free_of_tiles(const Rect& rect, const bool ignoreUnisolid = false) const;
- /**
- * Checks if the specified rectangle is free of both
- * 1.) solid tiles and
- * 2.) MovingObjects in COLGROUP_STATIC.
- * Note that this does not include badguys or players.
- */
- bool is_free_of_statics(const Rect& rect, const MovingObject* ignore_object = 0, const bool ignoreUnisolid = false) const;
- /**
- * Checks if the specified rectangle is free of both
- * 1.) solid tiles and
- * 2.) MovingObjects in COLGROUP_STATIC, COLGROUP_MOVINGSTATIC or COLGROUP_MOVING.
- * This includes badguys and players.
- */
- bool is_free_of_movingstatics(const Rect& rect, const MovingObject* ignore_object = 0) const;
-
- /**
- * returns a list of players currently in the sector
- */
- std::vector<Player*> get_players() {
- return std::vector<Player*>(1, this->player);
- }
-
- Rect get_active_region();
-
- /**
- * returns the width (in px) of a sector)
- */
- float get_width() const;
-
- /**
- * returns the height (in px) of a sector)
- */
- float get_height() const;
-
- /**
- * globally changes solid tilemaps' tile ids
- */
- void change_solid_tiles(uint32_t old_tile_id, uint32_t new_tile_id);
-
- typedef std::vector<GameObject*> GameObjects;
- typedef std::vector<MovingObject*> MovingObjects;
- typedef std::vector<SpawnPoint*> SpawnPoints;
- typedef std::vector<Portable*> Portables;
-
- // --- Scripting ---
- /**
- * get/set color of ambient light
- */
- void set_ambient_light(float red, float green, float blue);
- float get_ambient_red();
- float get_ambient_green();
- float get_ambient_blue();
-
-private:
- Level* level; /**< Parent level containing this sector */
- uint32_t collision_tile_attributes(const Rect& dest) const;
-
- void before_object_remove(GameObject* object);
- bool before_object_add(GameObject* object);
-
- void try_expose(GameObject* object);
- void try_unexpose(GameObject* object);
- void try_expose_me();
- void try_unexpose_me();
-
- /** Checks for all possible collisions. And calls the
- collision_handlers, which the collision_objects provide for this
- case (or not). */
- void handle_collisions();
-
- /**
- * Does collision detection between 2 objects and does instant
- * collision response handling in case of a collision
- */
- void collision_object(MovingObject* object1, MovingObject* object2) const;
-
- /**
- * Does collision detection of an object against all other static
- * objects (and the tilemap) in the level. Collision response is done
- * for the first hit in time. (other hits get ignored, the function
- * should be called repeatedly to resolve those)
- *
- * returns true if the collision detection should be aborted for this object
- * (because of ABORT_MOVE in the collision response or no collisions)
- */
- void collision_static(collision::Constraints* constraints,
- const Vector& movement, const Rect& dest, GameObject& object);
-
- void collision_static_constrains(MovingObject& object);
-
- GameObject* parse_object(const std::string& name, const lisp::Lisp& lisp);
-
- void fix_old_tiles();
-
- static Sector* _current;
-
- std::string name;
-
- std::vector<Bullet*> bullets;
-
- std::string init_script;
-
- /// container for newly created objects, they'll be added in Sector::update
- GameObjects gameobjects_new;
-
- MusicType currentmusic;
-
- HSQOBJECT sector_table;
- /// sector scripts
- typedef std::vector<HSQOBJECT> ScriptList;
- ScriptList scripts;
-
- Color ambient_light;
-
-public: // TODO make this private again
- /// show collision rectangles of moving objects (for debugging)
- static bool show_collrects;
- static bool draw_solids_only;
-
- GameObjects gameobjects;
- MovingObjects moving_objects;
- SpawnPoints spawnpoints;
- Portables portables;
-
- std::string music;
- float gravity;
-
- // some special objects, where we need direct access
- // (try to avoid accessing them directly)
- Player* player;
- std::list<TileMap*> solid_tilemaps;
- Camera* camera;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux - A Jump'n Run
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#ifndef SUPERTUX_SERIALIZABLE_H
-#define SUPERTUX_SERIALIZABLE_H
-
-namespace lisp { class Writer; }
-
-class Serializable
-{
-public:
- virtual ~Serializable()
- { }
-
- virtual void write(lisp::Writer& writer) = 0;
-};
-
-#endif /*SUPERTUX_SERIALIZABLE_H*/
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#include <config.h>
-
-#include "shrinkfade.hpp"
-#include "main.hpp"
-#include "video/drawing_context.hpp"
-
-ShrinkFade::ShrinkFade(const Vector& dest, float fade_time)
- : dest(dest), fade_time(fade_time), accum_time(0)
-{
- speedleft = dest.x / fade_time;
- speedright = (SCREEN_WIDTH - dest.x) / fade_time;
- speedtop = dest.y / fade_time;
- speedbottom = (SCREEN_HEIGHT - dest.y) / fade_time;
-}
-
-ShrinkFade::~ShrinkFade()
-{
-}
-
-void
-ShrinkFade::update(float elapsed_time)
-{
- accum_time += elapsed_time;
- if(accum_time > fade_time)
- accum_time = fade_time;
-}
-
-void
-ShrinkFade::draw(DrawingContext& context)
-{
- Color black(0, 0, 0);
- float left = speedleft * accum_time;
- float top = speedtop * accum_time;
- float right = SCREEN_WIDTH - speedright * accum_time;
- float bottom = SCREEN_HEIGHT - speedbottom * accum_time;
-
- context.draw_filled_rect(Vector(0, 0),
- Vector(left, SCREEN_HEIGHT),
- black, LAYER_GUI+1);
- context.draw_filled_rect(Vector(0, 0),
- Vector(SCREEN_WIDTH, top),
- black, LAYER_GUI+1);
- context.draw_filled_rect(Vector(right, 0),
- Vector(SCREEN_WIDTH, SCREEN_HEIGHT),
- black, LAYER_GUI+1);
- context.draw_filled_rect(Vector(0, bottom),
- Vector(SCREEN_WIDTH, SCREEN_HEIGHT),
- black, LAYER_GUI+1);
-}
-
-bool
-ShrinkFade::done()
-{
- return accum_time >= fade_time;
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#ifndef __SHRINKFADE_HPP__
-#define __SHRINKFADE_HPP__
-
-#include "screen_fade.hpp"
-#include "math/vector.hpp"
-
-/**
- * Shrinks a rectangle screen towards a specific position
- */
-class ShrinkFade : public ScreenFade
-{
-public:
- ShrinkFade(const Vector& point, float fade_time);
- virtual ~ShrinkFade();
-
- virtual void update(float elapsed_time);
- virtual void draw(DrawingContext& context);
-
- virtual bool done();
-
-private:
- Vector dest;
- float fade_time;
- float accum_time;
- float speedleft, speedright, speedtop, speedbottom;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include <stdexcept>
-#include <iostream>
-#include "spawn_point.hpp"
-#include "lisp/lisp.hpp"
-#include "lisp/list_iterator.hpp"
-#include "log.hpp"
-
-SpawnPoint::SpawnPoint()
-{}
-
-SpawnPoint::SpawnPoint(const SpawnPoint& other)
- : name(other.name), pos(other.pos)
-{}
-
-SpawnPoint::SpawnPoint(const lisp::Lisp* slisp)
-{
- pos.x = -1;
- pos.y = -1;
- lisp::ListIterator iter(slisp);
- while(iter.next()) {
- const std::string& token = iter.item();
- if(token == "name") {
- iter.value()->get(name);
- } else if(token == "x") {
- iter.value()->get(pos.x);
- } else if(token == "y") {
- iter.value()->get(pos.y);
- } else {
- log_warning << "unknown token '" << token << "' in SpawnPoint" << std::endl;
- }
- }
-
- if(name == "")
- throw std::runtime_error("No name specified for spawnpoint");
- if(pos.x < 0 || pos.y < 0)
- throw std::runtime_error("Invalid coordinates for spawnpoint");
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#ifndef __SPAWN_POINT_H__
-#define __SPAWN_POINT_H__
-
-#include <string>
-#include "math/vector.hpp"
-namespace lisp { class Lisp; }
-
-class SpawnPoint
-{
-public:
- SpawnPoint();
- SpawnPoint(const SpawnPoint& other);
- SpawnPoint(const lisp::Lisp* lisp);
-
- std::string name;
- Vector pos;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include <iostream>
-#include <cmath>
-#include <cassert>
-#include <stdexcept>
-
-
-#include "video/surface.hpp"
-#include "sprite.hpp"
-#include "video/drawing_context.hpp"
-#include "log.hpp"
-#include "timer.hpp"
-
-Sprite::Sprite(SpriteData& newdata)
- : data(newdata),
- frame(0),
- animation_loops(-1),
- angle(0.0f),
- color(1.0f, 1.0f, 1.0f, 1.0f)
-{
- action = data.get_action("normal");
- if(!action)
- action = data.actions.begin()->second;
- last_ticks = game_time;
-}
-
-Sprite::Sprite(const Sprite& other)
- : data(other.data), frame(other.frame),
- animation_loops(other.animation_loops),
- angle(0.0f),
- color(1.0f, 1.0f, 1.0f, 1.0f),
- action(other.action)
-{
- last_ticks = game_time;
-}
-
-Sprite::~Sprite()
-{
-}
-
-void
-Sprite::set_action(const std::string& name, int loops)
-{
- if(action && action->name == name)
- return;
-
- SpriteData::Action* newaction = data.get_action(name);
- if(!newaction) {
- log_debug << "Action '" << name << "' not found." << std::endl;
- return;
- }
-
- action = newaction;
- animation_loops = loops;
- frame = 0;
-}
-
-bool
-Sprite::animation_done()
-{
- return animation_loops == 0;
-}
-
-void
-Sprite::update()
-{
- if(animation_done())
- return;
-
- float frame_inc = action->fps * (game_time - last_ticks);
- last_ticks = game_time;
-
- frame += frame_inc;
-
- if(frame >= get_frames()) {
- frame = fmodf(frame, get_frames());
-
- animation_loops--;
- if(animation_done())
- frame = get_frames()-1;
- }
-}
-
-void
-Sprite::draw(DrawingContext& context, const Vector& pos, int layer)
-{
- assert(action != 0);
- update();
-
- if((int)frame >= get_frames() || (int)frame < 0)
- log_warning << "frame out of range: " << (int)frame << "/" << get_frames() << " at " << get_name() << "/" << get_action() << std::endl;
- else
- context.draw_surface(action->surfaces[(int)frame],
- pos - Vector(action->x_offset, action->y_offset),
- angle,
- color,
- blend,
- layer + action->z_order);
-}
-
-void
-Sprite::draw_part(DrawingContext& context, const Vector& source,
- const Vector& size, const Vector& pos, int layer)
-{
- assert(action != 0);
- update();
-
- int frameidx = (int) frame;
-
- if(frameidx >= get_frames() || frameidx < 0) {
-#ifndef DEBUG
- // in optimized mode we get some small rounding errors in floating point
- // number sometimes...
- log_warning << "frame out of range: " << frameidx << "/" << get_frames() << " at sprite: " << get_name() << "/" << get_action() << std::endl;
-#endif
- frameidx = get_frames() - 1;
- }
-
- context.draw_surface_part(action->surfaces[frameidx], source, size,
- pos - Vector(action->x_offset, action->y_offset),
- layer + action->z_order);
-}
-
-int
-Sprite::get_width() const
-{
- return (int) action->surfaces[get_frame()]->get_width();
-}
-
-int
-Sprite::get_height() const
-{
- return (int) action->surfaces[get_frame()]->get_height();
-}
-
-float
-Sprite::get_current_hitbox_x_offset() const
-{
- return action->x_offset;
-}
-
-float
-Sprite::get_current_hitbox_y_offset() const
-{
- return action->y_offset;
-}
-
-float
-Sprite::get_current_hitbox_width() const
-{
- return action->hitbox_w;
-}
-
-float
-Sprite::get_current_hitbox_height() const
-{
- return action->hitbox_h;
-}
-
-Rect
-Sprite::get_current_hitbox() const
-{
- return Rect(action->x_offset, action->y_offset, action->x_offset + action->hitbox_w, action->y_offset + action->hitbox_h);
-}
-
-void
-Sprite::set_fps(float new_fps)
-{
- action->fps = new_fps;
-}
-
-void
-Sprite::set_angle(float a)
-{
- angle = a;
-}
-
-float
-Sprite::get_angle() const
-{
- return angle;
-}
-
-void
-Sprite::set_color(const Color& c)
-{
- color = c;
-}
-
-Color
-Sprite::get_color() const
-{
- return color;
-}
-
-void
-Sprite::set_blend(const Blend& b)
-{
- blend = b;
-}
-
-Blend
-Sprite::get_blend() const
-{
- return blend;
-}
-
-/* EOF */
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef SUPERTUX_SPRITE_H
-#define SUPERTUX_SPRITE_H
-
-#include <string>
-#include <assert.h>
-
-#include "math/vector.hpp"
-#include "math/rect.hpp"
-#include "sprite_data.hpp"
-#include "video/color.hpp"
-#include "video/drawing_context.hpp"
-
-class Surface;
-class DrawingContext;
-class Blend;
-
-class Sprite
-{
-public:
- Sprite(SpriteData& data);
- Sprite(const Sprite& other);
- ~Sprite();
-
- /** Draw sprite, automatically calculates next frame */
- void draw(DrawingContext& context, const Vector& pos, int layer);
-
- void draw_part(DrawingContext& context, const Vector& source,
- const Vector& size, const Vector& pos, int layer);
-
- /** Set action (or state) */
- void set_action(const std::string& act, int loops = -1);
-
- /** Set number of animation cycles until animation stops */
- void set_animation_loops(int loops = -1)
- { animation_loops = loops; }
-
- /** Set framerate */
- void set_fps(float new_fps);
-
- /* Stop animation */
- void stop_animation()
- { animation_loops = 0; }
- /** Check if animation is stopped or not */
- bool animation_done();
-
- float get_fps() const
- { return action->fps; }
- /** Get current action total frames */
- int get_frames() const
- { return action->surfaces.size(); }
- /** Get sprite's name */
- const std::string& get_name() const
- { return data.name; }
- /** Get current action name */
- const std::string& get_action() const
- { return action->name; }
-
- int get_width() const;
- int get_height() const;
-
- /** return x-offset of current action's hitbox, relative to start of image */
- float get_current_hitbox_x_offset() const;
- /** return y-offset of current action's hitbox, relative to start of image */
- float get_current_hitbox_y_offset() const;
- /** return width of current action's hitbox */
- float get_current_hitbox_width() const;
- /** return height of current action's hitbox */
- float get_current_hitbox_height() const;
- /** return current action's hitbox, relative to 0,0 */
- Rect get_current_hitbox() const;
-
- /** Set the angle of the sprite rotation in degree */
- void set_angle(float angle);
-
- /** Get the angle of the sprite rotation in degree */
- float get_angle() const;
-
- void set_color(const Color& color);
-
- Color get_color() const;
-
- void set_blend(const Blend& blend);
-
- Blend get_blend() const;
-
- /** Get current frame */
- int get_frame() const
- { return (int)frame; }
- /** Set current frame */
- void set_frame(int frame)
- {
- this->frame = (float) (frame % get_frames());
- }
- Surface* get_frame(unsigned int frame)
- {
- assert(frame < action->surfaces.size());
- return action->surfaces[frame];
- }
-
-private:
- void update();
-
- SpriteData& data;
-
- float frame;
- int animation_loops;
- float last_ticks;
- float angle;
- Color color;
- Blend blend;
-
- SpriteData::Action* action;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include <iostream>
-#include <cmath>
-#include <sstream>
-#include <stdexcept>
-
-#include "sprite_data.hpp"
-#include "resources.hpp"
-#include "video/drawing_context.hpp"
-#include "lisp/list_iterator.hpp"
-#include "log.hpp"
-
-SpriteData::Action::Action()
-{
- x_offset = 0;
- y_offset = 0;
- hitbox_w = 0;
- hitbox_h = 0;
- z_order = 0;
- fps = 10;
-}
-
-SpriteData::Action::~Action()
-{
- for(std::vector<Surface*>::iterator i = surfaces.begin();
- i != surfaces.end(); ++i)
- delete *i;
-}
-
-SpriteData::SpriteData(const lisp::Lisp* lisp, const std::string& basedir)
-{
- lisp::ListIterator iter(lisp);
- while(iter.next()) {
- if(iter.item() == "name") {
- iter.value()->get(name);
- } else if(iter.item() == "action") {
- parse_action(iter.lisp(), basedir);
- } else {
- log_warning << "Unknown sprite field: " << iter.item() << std::endl;
- }
- }
- if(actions.empty())
- throw std::runtime_error("Error: Sprite wihtout actions.");
-}
-
-SpriteData::~SpriteData()
-{
- for(Actions::iterator i=actions.begin(); i != actions.end(); ++i)
- delete i->second;
-}
-
-void
-SpriteData::parse_action(const lisp::Lisp* lisp, const std::string& basedir)
-{
- Action* action = new Action;
-
- if(!lisp->get("name", action->name)) {
- if(!actions.empty())
- throw std::runtime_error(
- "If there are more than one action, they need names!");
- }
- std::vector<float> hitbox;
- if (lisp->get_vector("hitbox", hitbox)) {
- if (hitbox.size() != 4) throw std::runtime_error("hitbox must specify exactly 4 coordinates");
- action->x_offset = hitbox[0];
- action->y_offset = hitbox[1];
- action->hitbox_w = hitbox[2];
- action->hitbox_h = hitbox[3];
- }
- lisp->get("z-order", action->z_order);
- lisp->get("fps", action->fps);
-
- std::string mirror_action;
- lisp->get("mirror-action", mirror_action);
- if(!mirror_action.empty()) {
- Action* act_tmp = get_action(mirror_action);
- if(act_tmp == NULL) {
- throw std::runtime_error("Could not mirror action. Action not found\n"
- "Mirror actions must be defined after the real one!");
- } else {
- float max_w = 0;
- float max_h = 0;
- for(int i = 0; static_cast<unsigned int>(i) < act_tmp->surfaces.size();
- i++) {
- Surface* surface = new Surface(*(act_tmp->surfaces[i]));
- surface->hflip();
- max_w = std::max(max_w, (float) surface->get_width());
- max_h = std::max(max_h, (float) surface->get_height());
- action->surfaces.push_back(surface);
- }
- if (action->hitbox_w < 1) action->hitbox_w = max_w;
- if (action->hitbox_h < 1) action->hitbox_h = max_h;
- }
- } else { // Load images
- std::vector<std::string> images;
- if(!lisp->get_vector("images", images)) {
- std::stringstream msg;
- msg << "Sprite '" << name << "' contains no images in action '"
- << action->name << "'.";
- throw std::runtime_error(msg.str());
- }
-
- float max_w = 0;
- float max_h = 0;
- for(std::vector<std::string>::size_type i = 0; i < images.size(); i++) {
- Surface* surface = new Surface(basedir + images[i]);
- max_w = std::max(max_w, (float) surface->get_width());
- max_h = std::max(max_h, (float) surface->get_height());
- action->surfaces.push_back(surface);
- }
- if (action->hitbox_w < 1) action->hitbox_w = max_w;
- if (action->hitbox_h < 1) action->hitbox_h = max_h;
- }
- actions[action->name] = action;
-}
-
-SpriteData::Action*
-SpriteData::get_action(std::string act)
-{
- Actions::iterator i = actions.find(act);
- if(i == actions.end()) {
- return 0;
- }
- return i->second;
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef SUPERTUX_SPRITE_DATA_H
-#define SUPERTUX_SPRITE_DATA_H
-
-#include <string>
-#include <vector>
-#include <map>
-
-#include "lisp/lisp.hpp"
-#include "video/surface.hpp"
-
-class SpriteData
-{
-public:
- /** cur has to be a pointer to data in the form of ((hitbox 5 10 0 0) ...) */
- SpriteData(const lisp::Lisp* cur, const std::string& basedir);
- ~SpriteData();
-
- const std::string& get_name() const
- {
- return name;
- }
-
-private:
- friend class Sprite;
-
- struct Action
- {
- Action();
- ~Action();
-
- std::string name;
-
- /** Position correction */
- float x_offset;
- float y_offset;
-
- /** Hitbox width */
- float hitbox_w;
-
- /** Hitbox height */
- float hitbox_h;
-
- /** Drawing priority in queue */
- int z_order;
-
- /** Frames per second */
- float fps;
-
- std::vector<Surface*> surfaces;
- };
-
- typedef std::map <std::string, Action*> Actions;
- Actions actions;
-
- void parse_action(const lisp::Lisp* lispreader, const std::string& basedir);
- /** Get an action */
- Action* get_action(std::string act);
-
- std::string name;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include <iostream>
-#include <sstream>
-#include <stdexcept>
-
-#include "sprite_manager.hpp"
-#include "sprite_data.hpp"
-#include "sprite.hpp"
-#include "lisp/lisp.hpp"
-#include "lisp/parser.hpp"
-#include "lisp/list_iterator.hpp"
-#include "file_system.hpp"
-#include "log.hpp"
-
-SpriteManager* sprite_manager = NULL;
-
-SpriteManager::SpriteManager()
-{
-}
-
-SpriteManager::~SpriteManager()
-{
- for(Sprites::iterator i = sprites.begin(); i != sprites.end(); ++i) {
- delete i->second;
- }
-}
-
-Sprite*
-SpriteManager::create(const std::string& name)
-{
- Sprites::iterator i = sprites.find(name);
- SpriteData* data;
- if(i == sprites.end()) {
- // try loading the spritefile
- data = load(name);
- if(data == NULL) {
- std::stringstream msg;
- msg << "Sprite '" << name << "' not found.";
- throw std::runtime_error(msg.str());
- }
- } else {
- data = i->second;
- }
-
- return new Sprite(*data);
-}
-
-SpriteData*
-SpriteManager::load(const std::string& filename)
-{
- lisp::Parser parser;
- const lisp::Lisp* root;
-
- try {
- root = parser.parse(filename);
- } catch(const std::exception& e) {
- std::ostringstream msg;
- msg << "Parse error when trying to load sprite '" << filename
- << "': " << e.what() << "\n";
- throw std::runtime_error(msg.str());
- }
-
- const lisp::Lisp* sprite = root->get_lisp("supertux-sprite");
- if(!sprite) {
- std::ostringstream msg;
- msg << "'" << filename << "' is not a supertux-sprite file";
- throw std::runtime_error(msg.str());
- }
-
- std::auto_ptr<SpriteData> data (
- new SpriteData(sprite, FileSystem::dirname(filename)) );
- sprites[filename] = data.release();
-
- return sprites[filename];
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef SUPERTUX_SPRITE_MANAGER_H
-#define SUPERTUX_SPRITE_MANAGER_H
-
-#include <map>
-
-class SpriteData;
-class Sprite;
-
-class SpriteManager
-{
-private:
- typedef std::map<std::string, SpriteData*> Sprites;
- Sprites sprites;
-
-public:
- SpriteManager();
- ~SpriteManager();
-
- /** loads a sprite. */
- Sprite* create(const std::string& filename);
-
-private:
- SpriteData* load(const std::string& filename);
-};
-
-extern SpriteManager* sprite_manager;
-
-#endif
+++ /dev/null
-#
-# SuperTux - squirrel library build script
-# Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
-#
-# 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
-#
-
-## Add include/ to include directories
-
-INCLUDE_DIRECTORIES(${SUPERTUX_SOURCE_DIR}/src/squirrel/include/)
-
-## build list of source files
-
-FILE(GLOB SQUIRREL_SOURCES squirrel/*.cpp sqstdlib/*.cpp sqstdlib/*.c)
-
-## add additional compiler switches
-
-ADD_DEFINITIONS(-include ${CMAKE_BINARY_DIR}/config.h)
-
-## define a target for building the library
-
-ADD_LIBRARY(squirrel ${SQUIRREL_SOURCES})
+++ /dev/null
-Copyright (c) 2003-2007 Alberto Demichelis\r
-\r
-This software is provided 'as-is', without any \r
-express or implied warranty. In no event will the \r
-authors be held liable for any damages arising from \r
-the use of this software.\r
-\r
-Permission is granted to anyone to use this software \r
-for any purpose, including commercial applications, \r
-and to alter it and redistribute it freely, subject \r
-to the following restrictions:\r
-\r
- 1. The origin of this software must not be \r
- misrepresented; you must not claim that \r
- you wrote the original software. If you \r
- use this software in a product, an \r
- acknowledgment in the product \r
- documentation would be appreciated but is \r
- not required.\r
-\r
- 2. Altered source versions must be plainly \r
- marked as such, and must not be \r
- misrepresented as being the original \r
- software.\r
-\r
- 3. This notice may not be removed or \r
- altered from any source distribution.\r
------------------------------------------------------\r
-END OF COPYRIGHT
\ No newline at end of file
+++ /dev/null
-***version 2.1.2 stable***\r
--new behaviour for generators iteration using foreach\r
-now when a generator is iterated by foreach the value returned by a 'return val' statement\r
-will terminate the iteration but will not be returned as foreach iteration\r
--added sq_setclassudsize()\r
--added sq_clear()\r
--added table.clear(), array.clear()\r
--fixed sq_cmp() (thx jyuill)\r
--fixed minor bugs\r
-\r
-***2006-08-21 ***\r
-***version 2.1.1 stable***\r
--vm refactoring\r
--optimized internal function memory layout\r
--new global symbol _version_ (is the version string)\r
--code size optimization for float literals(on 32bits float builts)\r
--now the raw ref API(sq_addref etc...) is fully reentrant.\r
--fixed a bug in sq_getdelegate() now pushes null if the object doesn't have a delegate(thx MatzeB)\r
--improved C reference performances in NO_GARBAGE_COLLECTOR builds\r
--sq_getlocal() now enumerates also outer values.\r
--fixed regexp library for GCC users.\r
-\r
-***2006-03-19 ***\r
-***version 2.1 stable***\r
--added static class fields, new keyword static\r
--added 64bits architecture support\r
--added global slot _intsize_ int the base lib to recognize 32bits and 64bits builds\r
--added functions with fixed environment, closure.bindenv() built-in function\r
--all types except userdata and null implement the tostring() method\r
--string concatenation now invokes metamethod _tostring\r
--new metamethods for class objects _newmember and _inherited\r
--sq_call() sq_resume() sq_wakeupvm() have a new signature\r
--new C referencing implementation(scales more with the amount of references)\r
--refactored hash table\r
--new api functions sq_newslot(),sq_tobool(),sq_getbase(), sq_instanceof(), sq_bindenv()\r
--the api func sq_createslot was deprecated but still supported in form of C macro on top of sq_newslot\r
--sq_setreleasehook() now also works for classes\r
--stream.readstr() and stream.writestr() have been deprecated(this affects file and blob)\r
--fixed squirrel.h undeclared api calls\r
--fixed few minor bugs\r
--SQChar is now defined as wchar_t\r
--removed warning when building with -Wall -pedantic for GCC users\r
--added new std io function writeclosuretofile()\r
--added new std string functions strip(),rstrip(),lstrip() and split()\r
--regular expressions operators (+,*) now have more POSIX greedyness behaviour\r
--class constructors are now invoked as normal functions\r
-\r
-***2005-10-02 ***\r
-***version 2.0.5 stable***\r
--fixed some 64bits incompatibilities (thx sarge)\r
--fixed minor bug in the stdlib format() function (thx Rick)\r
--fixed a bug in dofile() that was preventing to compile empty files\r
--added new API sq_poptop() & sq_getfreevariable()\r
--some performance improvements\r
-\r
-***2005-08-14 ***\r
-***version 2.0.4 stable***\r
--weak references and related API calls\r
--added sq_objtobool()\r
--class instances memory policies improved(1 mem allocation for the whole instance)\r
--typetags are now declared as SQUserPointer instead of unsigned int\r
--first pass for 64bits compatibility\r
--fixed minor bug in the stdio stream\r
--fixed a bug in format()\r
--fixed bug in string.tointeger() and string.tofloat()\r
-\r
-***2005-06-24 ***\r
-***version 2.0.3 stable***\r
--dofile() and loadfile() in the iolib now can decode ASCII, UTF8 files UCS2 big-endian and little-endian\r
--sq_setparamscheck() : now typemesk can check for null\r
--added string escape sequence \xhhhh\r
--fixed some C++ standard incompatibilities\r
-\r
-***2005-05-15 ***\r
-***version 2.0.2 stable***\r
--performances improvements (expecially for GCC users)\r
--removed all dependencies from C++ exception handling\r
--various bugfixes\r
-\r
-***2005-04-12 ***\r
-***version 2.0.1 stable***\r
--various bugfixes\r
--sq_setparamscheck() now allows spaces in the typemask\r
-\r
-***2005-04-03 ***\r
-***version 2.0 stable***\r
--added API sq_gettypetag()\r
--added built-in function to the bool type(tointeger, tostring etc...)\r
-\r
-***2005-02-27 ***\r
-***version 2.0 release candidate 1(RC 1)***\r
--added API sq_reseterror()\r
--modified sq_release()\r
--now class instances can be cloned\r
--various bufixes\r
-\r
-***2005-01-26 ***\r
-***version 2.0 beta 1***\r
--added bool type\r
--class properties can be redefined in a derived class\r
--added ops *= /= and %=\r
--new syntax for class attributes declaration </ and /> instead of ( and )\r
--increased the max number of literals per function from 65535 to 16777215\r
--now free variables have proper lexical scoping\r
--added API sq_createinstance(), sq_pushbool(), sq_getbool()\r
--added built-in function type()\r
--added built-in function obj.rawin(key) in table,class and instance\r
--sq_rawget() and sq_rawset() now work also on classes and instances\r
--the VM no longer uses C++ exception handling (more suitable for embedded devices)\r
--various bufixes\r
-\r
-***2004-12-21 ***\r
-***version 2.0 alpha 2***\r
--globals scoping changed, now if :: is omitted the VM automatically falls back on the root table\r
--various bufixes\r
--added class level attributes\r
-\r
-***2004-12-12 ***\r
-***version 2.0 alpha 1***\r
--codebase branch from version 1.x\r
--added classes\r
--added functions with variable number of parameters(vargc & vargv and the ...)\r
--0 and 0.0 are now considered 'false' by all conditional statements(if,while,for,?,do-while)\r
--added new api functions sq_newclass() sq_setinstanceup() sq_getinstanceup() sq_getattributes() sq_setattributes()\r
--modified api sq_settypetag()\r
-\r
-***2004-11-01 ***\r
-***version 1.0 stable***\r
--fixed some minor bug\r
--improoved operator 'delete' performances\r
--added scientific notation for float numbers( eg. 2.e16 or 2.e-2)\r
-\r
-***2004-08-30 ***\r
-***version 1.0 release candidate 2(RC 2)***\r
--fixed bug in the vm(thx Pierre Renaux)\r
--fixed bug in the optimizer(thx Pierre Renaux)\r
--fixed some bug in the documentation(thx JD)\r
--added new api functions for raw object handling\r
--removed nested multiline comments\r
--reduced memory footprint in C references\r
-\r
-***2004-08-23 ***\r
-***version 1.0 release candidate 1(RC 1)***\r
--fixed division by zero\r
--the 'in' operator and obj.rawget() do not query the default delegate anymore\r
--added function sq_getprintfunc()\r
--added new standard library 'auxlib'(implements default error handlers)\r
-\r
-***2004-07-12 ***\r
-***version 1.0 beta 4***\r
--fixed a bug in the integer.tochar() built-in method\r
--fixed unary minus operator\r
--fixed bug in dofile()\r
--fixed inconsistency between != and == operators(on float/integer comparison)\r
--added javascript style unsigned right shift operator '>>>'\r
--added array(size) constructor built-in function\r
--array.resize(size,[fill]) built-in function accepts an optional 'fill' value\r
--improved debug API, added sq_getclosureinfo() and sq_setnativeclosurename()\r
-\r
-***2004-05-23 ***\r
-***version 1.0 beta 3***\r
--minor vm bug fixes\r
--string allocation is now faster\r
--tables and array memory usage is now less conservative(they shrink)\r
--added regular expression routines in the standard library\r
--The 'c' expression now accepts only 1 character(thx irbrian)\r
--multiline strings <[ ]> have been substituted with C# style verbatim strings (eg. @"string")\r
--added new keyword 'parent' for accessing the delegate of tables and unserdata\r
--The metamethod '_clone' has been renamed '_cloned'\r
--the _delslot metamethod's behaviour and prototype have been changed\r
--new default function in the integer and float object 'tochar()'\r
--the built-in function chcode2string has been removed\r
--the default method [table].getdelegate() has been removed\r
--new api sq_rawdeleteslot()\r
--new table built-in method rawdelete(key)\r
--the dynamic mudule loading has been removed from the standard distribution\r
--some optimizations in the VM\r
-\r
-***2004-04-21 ***\r
-***version 1.0 beta 2***\r
--minor compiler/parser bug fixes\r
--sq_newclosure has a different prototype, the "paramscheck" of paramter has been moved to the new function sq_setparamscheck()\r
--sq_setparamscheck allows to add automatic parameters type checking in native closures\r
--sq_compile() lost the lineinfo parameter\r
--new api sq_enabledebuginfo() globally sets compiler's debug info generation\r
--added consistency check on bytecode serialization\r
--fixed += operator, now works on strings like +\r
--added global slot in the base lib _charsize_ to recognize unicode builds from ascii builds runtime\r
--added registry table\r
--new api call sq_pushregistrytable()\r
--added type tag to the userdata type sq_settypetag()\r
--sq_getuserdata now queries the userdata typetag\r
--the built in function collect_garbage() as been renamed collectgarbage() for consistency reasons\r
--new standard libraries(sqlibs are now obsolete)\r
-\r
-***2004-02-20 ***\r
-***version 1.0 beta 1***\r
--fixed a bug in the compiler (thanks Martin Kofler)\r
--fixed bug in the switch case statement\r
--fixed the _unm metamethod\r
--fixed minor bugs in the API\r
--fixed automatic stack resizing\r
--first beta version \r
- first pass code clean up in the VM and base lib\r
- first pass code coverege test has been done on VM and built-in lib\r
--new VM creation API sq_open() sq_close() (sq_newvm and sq_releasevm are now obsolete)\r
--new api allows to specifiy a "print" function to output text(sq_printfunc)\r
--added some small optimizations\r
--new cooperative multi-threading capabilities in the base library(coroutines), VMs are now a built in type("thread")\r
--new built in functions have been added for manipulating the new "thread" type\r
--friend virtual machines share the same root table, error handler and debug hook by default\r
--new compile time options\r
-\r
-***2004-01-19 ***\r
-***version 0.9 alpha***\r
--fixed a garbage collection bug\r
--fixed some API bugs(thanks to Joshua Jensen)\r
--fixed tail calls (in the version 0.8 the tail call optimization was erroneously disabled)\r
--new function parameters semantic, now passing a wrong number of parameters generates an exception\r
--native closures have now a built in parameter number checking\r
--sq_rawget and sq_rawset now work also on arrays\r
--sq_getsize now woks also on userdata\r
--the userdata release hook prototype is changed(now passes the size of the userdata)\r
--the lexer reader function now returns an integer instead of a char that allows better error checking on the input(thx Joshua Jensen)\r
--faster compiler\r
--try/catch blocks do not cause any runtime memory allocation anymore\r
-\r
-***2003-12-06 ***\r
-***version 0.8 alpha***\r
--fixed a bug that was preventing to have callable userdata throught the metamethod _call\r
--fixed a garbage collection bug\r
--fixed == operator now can compare correctly different types\r
--new built in method getstackinfos(level)\r
--improoved line informations precision for the debug hook\r
--new api call sq_compilebuffer()\r
--new built-in api function compilestring()\r
--new syntactic sugar for function declarations inside tables\r
--the debug API has been finalized\r
-\r
-***2003-11-17 ***\r
-***version 0.7 alpha***\r
--fixed critical bug SQInteger the tail call system\r
--fixed bug in the continue statement code generation\r
--fixed func call param issue(thanks to Rewoonenco Andrew)\r
--added _delslot metamethod(thanks to Rewoonenco Andrew)\r
--new multiline string expression ( delimited by <[ and ]> )\r
--normal strings ("") do not allow embedded new line anymore\r
--reduced vm memory footprint(C refs are shared between friend VMs)\r
--new api method sq_deleteslot()\r
--new debug hook event 'r' is triggered when a function returns\r
-\r
-***2003-11-04 ***\r
-***version 0.6 alpha***\r
--fixed switch statement(was executing the default case after a break)\r
--sq_call() doesn't pop the closure (just the params)\r
--the vm execution can be suspended from the C API anytime (micro-threads)\r
--new api calls sq_suspendvm() sq_wakeupvm() sq_getvmstate() and sq_reservestack()\r
-\r
-***2003-10-13 ***\r
-***version 0.5 alpha***\r
--fixed some minor bug\r
--tested with non ASCII identifiers in unicode mode(I've tried chinese chars)\r
--added built-in function string.find()\r
--the built-in function array.sort() optionally accepts a cmp(a,b) function\r
--the debug hook function now has a new prototype debug_hook(event_type,sourcefile,line,functionname)\r
--fixed some debug info imprecision\r
-\r
-***2003-10-01 ***\r
-***version 0.4 alpha***\r
--faster VM\r
--sq_call will pop arguments and closure also in case of failure\r
--fixed a bug in sq_remove\r
--now the VM detects delegation cycles(and throws an exception)\r
--new operators ++ and --\r
--new operator ',' comma operator\r
--fixed some expression precedence issue\r
--fixed bug in sq_arraypop\r
-\r
-***2003-09-15 ***\r
-***version 0.3 alpha***\r
--fixed a bug in array::insert()\r
--optional Unicode core(define SQUNICODE or _UNICODE on Win32)\r
--sq_compiler uses a new reader function SQLEXREADFUNC\r
--the debug hook passes 'l' instead of 'line' for line callbacks\r
- and 'c' instead of 'call' for call callbacks\r
--new array.extend() bulit-in function\r
--new API sq_clone()\r
-\r
-***2003-09-10 ***\r
-***version 0.2 pre-alpha***\r
--new completely reentrant VM (sq_open and sq_close are now obsolete)\r
--sq_newvm() has a new prototype\r
--allocators are now global and linked in the VM\r
--_newslot meta method added\r
--rawset creates a slot if doesn't exists\r
--the compiler error callback pass the vm handle(thanks Pierre Renaux)\r
--sq_setforeignptr() sq_getforeingptr() are now public\r
--sq_resume() now is possible to resume generators from C\r
--sq_getlasterror() retrieve the last thrown error\r
--improved docs\r
-\r
-***2003-09-06 ***\r
-***version 0.1 pre-alpha***\r
-first release\r
+++ /dev/null
-SubDir TOP src squirrel ;
-
-SQDBG_SOURCES = [ Wildcard sqdbg : *.cpp *.h *.inl ] ;
-if $(enable_sqdbg) = "yes" {
- EXTRA_SOURCES = $(SQDBG_SOURCES) ;
-} else {
- Package $(SQDBG_SOURCES) ;
-}
-
-Library squirrel
- : [ Wildcard squirrel : *.cpp *.h ]
- [ Wildcard sqstdlib : *.cpp *.c *.h ]
- $(EXTRA_SOURCES)
- : noinstall
-;
-
-for i in $(squirrel_OBJECTS) {
- CXXFLAGS on $(i) = [ Filter [ on $(i) GetVar CXXFLAGS ] : -Wall -W -Werror ] -include $(top_builddir)/config.h ;
- CFLAGS on $(i) = [ Filter [ on $(i) GetVar CFLAGS ] : -Wall -W -Werror ] -include $(top_builddir)/config.h ;
-}
-IncludeDir squirrel : include ;
-Package [ Wildcard include : *.h ] ;
+++ /dev/null
-The programming language SQUIRREL 2.1.2 stable\r
-\r
---------------------------------------------------\r
-The project has been compiled and run on Windows(Windows XP/2000 on Intel x86 Windows XP Pro on AMD x64) and\r
-Linux(Slackware 9.0 on Intel x86, Fedora Core 4 on AMD x64).\r
-\r
-Has been tested with the following compilers:\r
- MS Visual C++ 6.0,7.0,7.1 and 8.0 (32 and 64bits)\r
- MinGW gcc 3.2 (mingw special 20020817-1)\r
- Cygnus gcc 3.2\r
- Linux gcc 3.2.3\r
- Linux gcc 4.0.0 (x86 64bits)\r
- \r
-\r
-Feedback and suggestions are appreciated \r
-project page - http://www.squirrel-lang.org\r
-community forums - http://www.squirrel-lang.org/Forums\r
-wiki - http://wiki.squirrel-lang.org\r
-author - alberto@ademichelis.com\r
-\r
-END OF README\r
-\r
+++ /dev/null
-/* see copyright notice in squirrel.h */
-#ifndef _SQSTD_AUXLIB_H_
-#define _SQSTD_AUXLIB_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-SQUIRREL_API void sqstd_seterrorhandlers(HSQUIRRELVM v);
-SQUIRREL_API void sqstd_printcallstack(HSQUIRRELVM v);
-
-#ifdef __cplusplus
-} /*extern "C"*/
-#endif
-
-#endif /* _SQSTD_AUXLIB_H_ */
+++ /dev/null
-/* see copyright notice in squirrel.h */
-#ifndef _SQSTDBLOB_H_
-#define _SQSTDBLOB_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-SQUIRREL_API SQUserPointer sqstd_createblob(HSQUIRRELVM v, SQInteger size);
-SQUIRREL_API SQRESULT sqstd_getblob(HSQUIRRELVM v,SQInteger idx,SQUserPointer *ptr);
-SQUIRREL_API SQInteger sqstd_getblobsize(HSQUIRRELVM v,SQInteger idx);
-
-SQUIRREL_API SQRESULT sqstd_register_bloblib(HSQUIRRELVM v);
-
-#ifdef __cplusplus
-} /*extern "C"*/
-#endif
-
-#endif /*_SQSTDBLOB_H_*/
-
+++ /dev/null
-/* see copyright notice in squirrel.h */
-#ifndef _SQSTDIO_H_
-#define _SQSTDIO_H_
-
-#ifdef __cplusplus
-
-#define SQSTD_STREAM_TYPE_TAG 0x80000000
-
-struct SQStream {
-
- // [SuperTux] Added virtual destructor to avoid compiler warnings
- virtual ~SQStream() { };
-
- virtual SQInteger Read(void *buffer, SQInteger size) = 0;
- virtual SQInteger Write(void *buffer, SQInteger size) = 0;
- virtual SQInteger Flush() = 0;
- virtual SQInteger Tell() = 0;
- virtual SQInteger Len() = 0;
- virtual SQInteger Seek(SQInteger offset, SQInteger origin) = 0;
- virtual bool IsValid() = 0;
- virtual bool EOS() = 0;
-};
-
-extern "C" {
-#endif
-
-#define SQ_SEEK_CUR 0
-#define SQ_SEEK_END 1
-#define SQ_SEEK_SET 2
-
-typedef void* SQFILE;
-
-SQUIRREL_API SQFILE sqstd_fopen(const SQChar *,const SQChar *);
-SQUIRREL_API SQInteger sqstd_fread(SQUserPointer, SQInteger, SQInteger, SQFILE);
-SQUIRREL_API SQInteger sqstd_fwrite(const SQUserPointer, SQInteger, SQInteger, SQFILE);
-SQUIRREL_API SQInteger sqstd_fseek(SQFILE , SQInteger , SQInteger);
-SQUIRREL_API SQInteger sqstd_ftell(SQFILE);
-SQUIRREL_API SQInteger sqstd_fflush(SQFILE);
-SQUIRREL_API SQInteger sqstd_fclose(SQFILE);
-SQUIRREL_API SQInteger sqstd_feof(SQFILE);
-
-SQUIRREL_API SQRESULT sqstd_createfile(HSQUIRRELVM v, SQFILE file,SQBool own);
-SQUIRREL_API SQRESULT sqstd_getfile(HSQUIRRELVM v, SQInteger idx, SQFILE *file);
-
-//compiler helpers
-SQUIRREL_API SQRESULT sqstd_loadfile(HSQUIRRELVM v,const SQChar *filename,SQBool printerror);
-SQUIRREL_API SQRESULT sqstd_dofile(HSQUIRRELVM v,const SQChar *filename,SQBool retval,SQBool printerror);
-SQUIRREL_API SQRESULT sqstd_writeclosuretofile(HSQUIRRELVM v,const SQChar *filename);
-
-SQUIRREL_API SQRESULT sqstd_register_iolib(HSQUIRRELVM v);
-
-#ifdef __cplusplus
-} /*extern "C"*/
-#endif
-
-#endif /*_SQSTDIO_H_*/
-
+++ /dev/null
-/* see copyright notice in squirrel.h */
-#ifndef _SQSTD_MATH_H_
-#define _SQSTD_MATH_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-SQUIRREL_API SQRESULT sqstd_register_mathlib(HSQUIRRELVM v);
-
-#ifdef __cplusplus
-} /*extern "C"*/
-#endif
-
-#endif /*_SQSTD_MATH_H_*/
+++ /dev/null
-/* see copyright notice in squirrel.h */
-#ifndef _SQSTD_STRING_H_
-#define _SQSTD_STRING_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef unsigned int SQRexBool;
-typedef struct SQRex SQRex;
-
-typedef struct {
- const SQChar *begin;
- SQInteger len;
-} SQRexMatch;
-
-SQUIRREL_API SQRex *sqstd_rex_compile(const SQChar *pattern,const SQChar **error);
-SQUIRREL_API void sqstd_rex_free(SQRex *exp);
-SQUIRREL_API SQBool sqstd_rex_match(SQRex* exp,const SQChar* text);
-SQUIRREL_API SQBool sqstd_rex_search(SQRex* exp,const SQChar* text, const SQChar** out_begin, const SQChar** out_end);
-SQUIRREL_API SQBool sqstd_rex_searchrange(SQRex* exp,const SQChar* text_begin,const SQChar* text_end,const SQChar** out_begin, const SQChar** out_end);
-SQUIRREL_API SQInteger sqstd_rex_getsubexpcount(SQRex* exp);
-SQUIRREL_API SQBool sqstd_rex_getsubexp(SQRex* exp, SQInteger n, SQRexMatch *subexp);
-
-SQUIRREL_API SQRESULT sqstd_register_stringlib(HSQUIRRELVM v);
-
-#ifdef __cplusplus
-} /*extern "C"*/
-#endif
-
-#endif /*_SQSTD_STRING_H_*/
+++ /dev/null
-/* see copyright notice in squirrel.h */
-#ifndef _SQSTD_SYSTEMLIB_H_
-#define _SQSTD_SYSTEMLIB_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-SQUIRREL_API SQInteger sqstd_register_systemlib(HSQUIRRELVM v);
-
-#ifdef __cplusplus
-} /*extern "C"*/
-#endif
-
-#endif /* _SQSTD_SYSTEMLIB_H_ */
+++ /dev/null
-/*
-Copyright (c) 2003-2007 Alberto Demichelis
-
-This software is provided 'as-is', without any
-express or implied warranty. In no event will the
-authors be held liable for any damages arising from
-the use of this software.
-
-Permission is granted to anyone to use this software
-for any purpose, including commercial applications,
-and to alter it and redistribute it freely, subject
-to the following restrictions:
-
- 1. The origin of this software must not be
- misrepresented; you must not claim that
- you wrote the original software. If you
- use this software in a product, an
- acknowledgment in the product
- documentation would be appreciated but is
- not required.
-
- 2. Altered source versions must be plainly
- marked as such, and must not be
- misrepresented as being the original
- software.
-
- 3. This notice may not be removed or
- altered from any source distribution.
-
-*/
-#ifndef _SQUIRREL_H_
-#define _SQUIRREL_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#ifndef SQUIRREL_API
-#define SQUIRREL_API extern
-#endif
-
-#ifdef _SQ64
-#ifdef _MSC_VER
-typedef __int64 SQInteger;
-typedef unsigned __int64 SQUnsignedInteger;
-typedef unsigned __int64 SQHash; /*should be the same size of a pointer*/
-#else
-typedef long SQInteger;
-typedef unsigned long SQUnsignedInteger;
-typedef unsigned long SQHash; /*should be the same size of a pointer*/
-#endif
-typedef int SQInt32;
-#else
-typedef int SQInteger;
-typedef int SQInt32; /*must be 32 bits(also on 64bits processors)*/
-typedef unsigned int SQUnsignedInteger;
-typedef unsigned int SQHash; /*should be the same size of a pointer*/
-#endif
-
-typedef float SQFloat;
-typedef void* SQUserPointer;
-typedef SQUnsignedInteger SQBool;
-typedef SQInteger SQRESULT;
-
-#define SQTrue (1)
-#define SQFalse (0)
-
-
-struct SQVM;
-struct SQTable;
-struct SQArray;
-struct SQString;
-struct SQClosure;
-struct SQGenerator;
-struct SQNativeClosure;
-struct SQUserData;
-struct SQFunctionProto;
-struct SQRefCounted;
-struct SQClass;
-struct SQInstance;
-struct SQDelegable;
-
-#ifdef _UNICODE
-#define SQUNICODE
-#endif
-
-#ifdef SQUNICODE
-#if (defined(_MSC_VER) && _MSC_VER >= 1400) // 1400 = VS8
-
-#if defined(wchar_t) //this is if the compiler considers wchar_t as native type
-#define wchar_t unsigned short
-#endif
-
-#else
-typedef unsigned short wchar_t;
-#endif
-
-typedef wchar_t SQChar;
-#define _SC(a) L##a
-#define scstrcmp wcscmp
-#define scsprintf swprintf
-#define scstrlen wcslen
-#define scstrtod wcstod
-#define scstrtol wcstol
-#define scatoi _wtoi
-#define scstrtoul wcstoul
-#define scvsprintf vswprintf
-#define scstrstr wcsstr
-#define scisspace iswspace
-#define scisdigit iswdigit
-#define scisxdigit iswxdigit
-#define scisalpha iswalpha
-#define sciscntrl iswcntrl
-#define scisalnum iswalnum
-#define scprintf wprintf
-#define MAX_CHAR 0xFFFF
-#else
-typedef char SQChar;
-#define _SC(a) a
-#define scstrcmp strcmp
-#define scsprintf sprintf
-#define scstrlen strlen
-#define scstrtod strtod
-#define scstrtol strtol
-#define scatoi atoi
-#define scstrtoul strtoul
-#define scvsprintf vsprintf
-#define scstrstr strstr
-#define scisspace isspace
-#define scisdigit isdigit
-#define scisxdigit isxdigit
-#define sciscntrl iscntrl
-#define scisalpha isalpha
-#define scisalnum isalnum
-#define scprintf printf
-#define MAX_CHAR 0xFF
-#endif
-
-#define SQUIRREL_VERSION _SC("Squirrel 2.1.2 stable")
-#define SQUIRREL_COPYRIGHT _SC("Copyright (C) 2003-2007 Alberto Demichelis")
-#define SQUIRREL_AUTHOR _SC("Alberto Demichelis")
-
-#define SQ_VMSTATE_IDLE 0
-#define SQ_VMSTATE_RUNNING 1
-#define SQ_VMSTATE_SUSPENDED 2
-
-#define SQUIRREL_EOB 0
-#define SQ_BYTECODE_STREAM_TAG 0xFAFA
-
-#define SQOBJECT_REF_COUNTED 0x08000000
-#define SQOBJECT_NUMERIC 0x04000000
-#define SQOBJECT_DELEGABLE 0x02000000
-#define SQOBJECT_CANBEFALSE 0x01000000
-
-#define SQ_MATCHTYPEMASKSTRING (-99999)
-
-#define _RT_MASK 0x00FFFFFF
-#define _RAW_TYPE(type) (type&_RT_MASK)
-
-#define _RT_NULL 0x00000001
-#define _RT_INTEGER 0x00000002
-#define _RT_FLOAT 0x00000004
-#define _RT_BOOL 0x00000008
-#define _RT_STRING 0x00000010
-#define _RT_TABLE 0x00000020
-#define _RT_ARRAY 0x00000040
-#define _RT_USERDATA 0x00000080
-#define _RT_CLOSURE 0x00000100
-#define _RT_NATIVECLOSURE 0x00000200
-#define _RT_GENERATOR 0x00000400
-#define _RT_USERPOINTER 0x00000800
-#define _RT_THREAD 0x00001000
-#define _RT_FUNCPROTO 0x00002000
-#define _RT_CLASS 0x00004000
-#define _RT_INSTANCE 0x00008000
-#define _RT_WEAKREF 0x00010000
-
-typedef enum tagSQObjectType{
- OT_NULL = (_RT_NULL|SQOBJECT_CANBEFALSE),
- OT_INTEGER = (_RT_INTEGER|SQOBJECT_NUMERIC|SQOBJECT_CANBEFALSE),
- OT_FLOAT = (_RT_FLOAT|SQOBJECT_NUMERIC|SQOBJECT_CANBEFALSE),
- OT_BOOL = (_RT_BOOL|SQOBJECT_CANBEFALSE),
- OT_STRING = (_RT_STRING|SQOBJECT_REF_COUNTED),
- OT_TABLE = (_RT_TABLE|SQOBJECT_REF_COUNTED|SQOBJECT_DELEGABLE),
- OT_ARRAY = (_RT_ARRAY|SQOBJECT_REF_COUNTED),
- OT_USERDATA = (_RT_USERDATA|SQOBJECT_REF_COUNTED|SQOBJECT_DELEGABLE),
- OT_CLOSURE = (_RT_CLOSURE|SQOBJECT_REF_COUNTED),
- OT_NATIVECLOSURE = (_RT_NATIVECLOSURE|SQOBJECT_REF_COUNTED),
- OT_GENERATOR = (_RT_GENERATOR|SQOBJECT_REF_COUNTED),
- OT_USERPOINTER = _RT_USERPOINTER,
- OT_THREAD = (_RT_THREAD|SQOBJECT_REF_COUNTED) ,
- OT_FUNCPROTO = (_RT_FUNCPROTO|SQOBJECT_REF_COUNTED), //internal usage only
- OT_CLASS = (_RT_CLASS|SQOBJECT_REF_COUNTED),
- OT_INSTANCE = (_RT_INSTANCE|SQOBJECT_REF_COUNTED|SQOBJECT_DELEGABLE),
- OT_WEAKREF = (_RT_WEAKREF|SQOBJECT_REF_COUNTED)
-}SQObjectType;
-
-#define ISREFCOUNTED(t) (t&SQOBJECT_REF_COUNTED)
-
-
-typedef union tagSQObjectValue
-{
- struct SQTable *pTable;
- struct SQArray *pArray;
- struct SQClosure *pClosure;
- struct SQGenerator *pGenerator;
- struct SQNativeClosure *pNativeClosure;
- struct SQString *pString;
- struct SQUserData *pUserData;
- SQInteger nInteger;
- SQFloat fFloat;
- SQUserPointer pUserPointer;
- struct SQFunctionProto *pFunctionProto;
- struct SQRefCounted *pRefCounted;
- struct SQDelegable *pDelegable;
- struct SQVM *pThread;
- struct SQClass *pClass;
- struct SQInstance *pInstance;
- struct SQWeakRef *pWeakRef;
-}SQObjectValue;
-
-
-typedef struct tagSQObject
-{
- SQObjectType _type;
- SQObjectValue _unVal;
-}SQObject;
-
-typedef struct tagSQStackInfos{
- const SQChar* funcname;
- const SQChar* source;
- SQInteger line;
-}SQStackInfos;
-
-typedef struct SQVM* HSQUIRRELVM;
-typedef SQObject HSQOBJECT;
-typedef SQInteger (*SQFUNCTION)(HSQUIRRELVM);
-typedef SQInteger (*SQRELEASEHOOK)(SQUserPointer,SQInteger size);
-typedef void (*SQCOMPILERERROR)(HSQUIRRELVM,const SQChar * /*desc*/,const SQChar * /*source*/,SQInteger /*line*/,SQInteger /*column*/);
-typedef void (*SQPRINTFUNCTION)(HSQUIRRELVM,const SQChar * ,...);
-
-typedef SQInteger (*SQWRITEFUNC)(SQUserPointer,SQUserPointer,SQInteger);
-typedef SQInteger (*SQREADFUNC)(SQUserPointer,SQUserPointer,SQInteger);
-
-typedef SQInteger (*SQLEXREADFUNC)(SQUserPointer);
-
-typedef struct tagSQRegFunction{
- const SQChar *name;
- SQFUNCTION f;
- SQInteger nparamscheck;
- const SQChar *typemask;
-}SQRegFunction;
-
-/*vm*/
-SQUIRREL_API HSQUIRRELVM sq_open(SQInteger initialstacksize);
-SQUIRREL_API HSQUIRRELVM sq_newthread(HSQUIRRELVM friendvm, SQInteger initialstacksize);
-SQUIRREL_API void sq_seterrorhandler(HSQUIRRELVM v);
-SQUIRREL_API void sq_close(HSQUIRRELVM v);
-SQUIRREL_API void sq_setforeignptr(HSQUIRRELVM v,SQUserPointer p);
-SQUIRREL_API SQUserPointer sq_getforeignptr(HSQUIRRELVM v);
-SQUIRREL_API void sq_setprintfunc(HSQUIRRELVM v, SQPRINTFUNCTION printfunc);
-SQUIRREL_API SQPRINTFUNCTION sq_getprintfunc(HSQUIRRELVM v);
-SQUIRREL_API SQRESULT sq_suspendvm(HSQUIRRELVM v);
-SQUIRREL_API SQRESULT sq_wakeupvm(HSQUIRRELVM v,SQBool resumedret,SQBool retval,SQBool raiseerror);
-SQUIRREL_API SQInteger sq_getvmstate(HSQUIRRELVM v);
-
-/*compiler*/
-SQUIRREL_API SQRESULT sq_compile(HSQUIRRELVM v,SQLEXREADFUNC read,SQUserPointer p,const SQChar *sourcename,SQBool raiseerror);
-SQUIRREL_API SQRESULT sq_compilebuffer(HSQUIRRELVM v,const SQChar *s,SQInteger size,const SQChar *sourcename,SQBool raiseerror);
-SQUIRREL_API void sq_enabledebuginfo(HSQUIRRELVM v, SQBool enable);
-SQUIRREL_API void sq_notifyallexceptions(HSQUIRRELVM v, SQBool enable);
-SQUIRREL_API void sq_setcompilererrorhandler(HSQUIRRELVM v,SQCOMPILERERROR f);
-
-/*stack operations*/
-SQUIRREL_API void sq_push(HSQUIRRELVM v,SQInteger idx);
-SQUIRREL_API void sq_pop(HSQUIRRELVM v,SQInteger nelemstopop);
-SQUIRREL_API void sq_poptop(HSQUIRRELVM v);
-SQUIRREL_API void sq_remove(HSQUIRRELVM v,SQInteger idx);
-SQUIRREL_API SQInteger sq_gettop(HSQUIRRELVM v);
-SQUIRREL_API void sq_settop(HSQUIRRELVM v,SQInteger newtop);
-SQUIRREL_API void sq_reservestack(HSQUIRRELVM v,SQInteger nsize);
-SQUIRREL_API SQInteger sq_cmp(HSQUIRRELVM v);
-SQUIRREL_API void sq_move(HSQUIRRELVM dest,HSQUIRRELVM src,SQInteger idx);
-
-/*object creation handling*/
-SQUIRREL_API SQUserPointer sq_newuserdata(HSQUIRRELVM v,SQUnsignedInteger size);
-SQUIRREL_API void sq_newtable(HSQUIRRELVM v);
-SQUIRREL_API void sq_newarray(HSQUIRRELVM v,SQInteger size);
-SQUIRREL_API void sq_newclosure(HSQUIRRELVM v,SQFUNCTION func,SQUnsignedInteger nfreevars);
-SQUIRREL_API SQRESULT sq_setparamscheck(HSQUIRRELVM v,SQInteger nparamscheck,const SQChar *typemask);
-SQUIRREL_API SQRESULT sq_bindenv(HSQUIRRELVM v,SQInteger idx);
-SQUIRREL_API void sq_pushstring(HSQUIRRELVM v,const SQChar *s,SQInteger len);
-SQUIRREL_API void sq_pushfloat(HSQUIRRELVM v,SQFloat f);
-SQUIRREL_API void sq_pushinteger(HSQUIRRELVM v,SQInteger n);
-SQUIRREL_API void sq_pushbool(HSQUIRRELVM v,SQBool b);
-SQUIRREL_API void sq_pushuserpointer(HSQUIRRELVM v,SQUserPointer p);
-SQUIRREL_API void sq_pushnull(HSQUIRRELVM v);
-SQUIRREL_API SQObjectType sq_gettype(HSQUIRRELVM v,SQInteger idx);
-SQUIRREL_API SQInteger sq_getsize(HSQUIRRELVM v,SQInteger idx);
-SQUIRREL_API SQRESULT sq_getbase(HSQUIRRELVM v,SQInteger idx);
-SQUIRREL_API SQBool sq_instanceof(HSQUIRRELVM v);
-SQUIRREL_API void sq_tostring(HSQUIRRELVM v,SQInteger idx);
-SQUIRREL_API void sq_tobool(HSQUIRRELVM v, SQInteger idx, SQBool *b);
-SQUIRREL_API SQRESULT sq_getstring(HSQUIRRELVM v,SQInteger idx,const SQChar **c);
-SQUIRREL_API SQRESULT sq_getinteger(HSQUIRRELVM v,SQInteger idx,SQInteger *i);
-SQUIRREL_API SQRESULT sq_getfloat(HSQUIRRELVM v,SQInteger idx,SQFloat *f);
-SQUIRREL_API SQRESULT sq_getbool(HSQUIRRELVM v,SQInteger idx,SQBool *b);
-SQUIRREL_API SQRESULT sq_getthread(HSQUIRRELVM v,SQInteger idx,HSQUIRRELVM *thread);
-SQUIRREL_API SQRESULT sq_getuserpointer(HSQUIRRELVM v,SQInteger idx,SQUserPointer *p);
-SQUIRREL_API SQRESULT sq_getuserdata(HSQUIRRELVM v,SQInteger idx,SQUserPointer *p,SQUserPointer *typetag);
-SQUIRREL_API SQRESULT sq_settypetag(HSQUIRRELVM v,SQInteger idx,SQUserPointer typetag);
-SQUIRREL_API SQRESULT sq_gettypetag(HSQUIRRELVM v,SQInteger idx,SQUserPointer *typetag);
-SQUIRREL_API void sq_setreleasehook(HSQUIRRELVM v,SQInteger idx,SQRELEASEHOOK hook);
-SQUIRREL_API SQChar *sq_getscratchpad(HSQUIRRELVM v,SQInteger minsize);
-SQUIRREL_API SQRESULT sq_getclosureinfo(HSQUIRRELVM v,SQInteger idx,SQUnsignedInteger *nparams,SQUnsignedInteger *nfreevars);
-SQUIRREL_API SQRESULT sq_setnativeclosurename(HSQUIRRELVM v,SQInteger idx,const SQChar *name);
-SQUIRREL_API SQRESULT sq_setinstanceup(HSQUIRRELVM v, SQInteger idx, SQUserPointer p);
-SQUIRREL_API SQRESULT sq_getinstanceup(HSQUIRRELVM v, SQInteger idx, SQUserPointer *p,SQUserPointer typetag);
-SQUIRREL_API SQRESULT sq_newclass(HSQUIRRELVM v,SQBool hasbase);
-SQUIRREL_API SQRESULT sq_createinstance(HSQUIRRELVM v,SQInteger idx);
-SQUIRREL_API SQRESULT sq_setattributes(HSQUIRRELVM v,SQInteger idx);
-SQUIRREL_API SQRESULT sq_getattributes(HSQUIRRELVM v,SQInteger idx);
-SQUIRREL_API SQRESULT sq_getclass(HSQUIRRELVM v,SQInteger idx);
-SQUIRREL_API void sq_weakref(HSQUIRRELVM v,SQInteger idx);
-SQUIRREL_API SQRESULT sq_getdefaultdelegate(HSQUIRRELVM v,SQObjectType t);
-
-/*object manipulation*/
-SQUIRREL_API void sq_pushroottable(HSQUIRRELVM v);
-SQUIRREL_API void sq_pushregistrytable(HSQUIRRELVM v);
-SQUIRREL_API SQRESULT sq_setroottable(HSQUIRRELVM v);
-SQUIRREL_API SQRESULT sq_newslot(HSQUIRRELVM v, SQInteger idx, SQBool bstatic);
-SQUIRREL_API SQRESULT sq_deleteslot(HSQUIRRELVM v,SQInteger idx,SQBool pushval);
-SQUIRREL_API SQRESULT sq_set(HSQUIRRELVM v,SQInteger idx);
-SQUIRREL_API SQRESULT sq_get(HSQUIRRELVM v,SQInteger idx);
-SQUIRREL_API SQRESULT sq_rawget(HSQUIRRELVM v,SQInteger idx);
-SQUIRREL_API SQRESULT sq_rawset(HSQUIRRELVM v,SQInteger idx);
-SQUIRREL_API SQRESULT sq_rawdeleteslot(HSQUIRRELVM v,SQInteger idx,SQBool pushval);
-SQUIRREL_API SQRESULT sq_arrayappend(HSQUIRRELVM v,SQInteger idx);
-SQUIRREL_API SQRESULT sq_arraypop(HSQUIRRELVM v,SQInteger idx,SQBool pushval);
-SQUIRREL_API SQRESULT sq_arrayresize(HSQUIRRELVM v,SQInteger idx,SQInteger newsize);
-SQUIRREL_API SQRESULT sq_arrayreverse(HSQUIRRELVM v,SQInteger idx);
-SQUIRREL_API SQRESULT sq_setdelegate(HSQUIRRELVM v,SQInteger idx);
-SQUIRREL_API SQRESULT sq_getdelegate(HSQUIRRELVM v,SQInteger idx);
-SQUIRREL_API SQRESULT sq_clone(HSQUIRRELVM v,SQInteger idx);
-SQUIRREL_API SQRESULT sq_setfreevariable(HSQUIRRELVM v,SQInteger idx,SQUnsignedInteger nval);
-SQUIRREL_API SQRESULT sq_next(HSQUIRRELVM v,SQInteger idx);
-SQUIRREL_API SQRESULT sq_getweakrefval(HSQUIRRELVM v,SQInteger idx);
-SQUIRREL_API SQRESULT sq_clear(HSQUIRRELVM v,SQInteger idx);
-
-/*calls*/
-SQUIRREL_API SQRESULT sq_call(HSQUIRRELVM v,SQInteger params,SQBool retval,SQBool raiseerror);
-SQUIRREL_API SQRESULT sq_resume(HSQUIRRELVM v,SQBool retval,SQBool raiseerror);
-SQUIRREL_API const SQChar *sq_getlocal(HSQUIRRELVM v,SQUnsignedInteger level,SQUnsignedInteger idx);
-SQUIRREL_API const SQChar *sq_getfreevariable(HSQUIRRELVM v,SQInteger idx,SQUnsignedInteger nval);
-SQUIRREL_API SQRESULT sq_throwerror(HSQUIRRELVM v,const SQChar *err);
-SQUIRREL_API void sq_reseterror(HSQUIRRELVM v);
-SQUIRREL_API void sq_getlasterror(HSQUIRRELVM v);
-
-/*raw object handling*/
-SQUIRREL_API SQRESULT sq_getstackobj(HSQUIRRELVM v,SQInteger idx,HSQOBJECT *po);
-SQUIRREL_API void sq_pushobject(HSQUIRRELVM v,HSQOBJECT obj);
-SQUIRREL_API void sq_addref(HSQUIRRELVM v,HSQOBJECT *po);
-SQUIRREL_API SQBool sq_release(HSQUIRRELVM v,HSQOBJECT *po);
-SQUIRREL_API void sq_resetobject(HSQOBJECT *po);
-SQUIRREL_API const SQChar *sq_objtostring(HSQOBJECT *o);
-SQUIRREL_API SQBool sq_objtobool(HSQOBJECT *o);
-SQUIRREL_API SQInteger sq_objtointeger(HSQOBJECT *o);
-SQUIRREL_API SQFloat sq_objtofloat(HSQOBJECT *o);
-SQUIRREL_API SQRESULT sq_getobjtypetag(HSQOBJECT *o,SQUserPointer * typetag);
-
-/*GC*/
-SQUIRREL_API SQInteger sq_collectgarbage(HSQUIRRELVM v);
-
-/*serialization*/
-SQUIRREL_API SQRESULT sq_writeclosure(HSQUIRRELVM vm,SQWRITEFUNC writef,SQUserPointer up);
-SQUIRREL_API SQRESULT sq_readclosure(HSQUIRRELVM vm,SQREADFUNC readf,SQUserPointer up);
-
-/*mem allocation*/
-SQUIRREL_API void *sq_malloc(SQUnsignedInteger size);
-SQUIRREL_API void *sq_realloc(void* p,SQUnsignedInteger oldsize,SQUnsignedInteger newsize);
-SQUIRREL_API void sq_free(void *p,SQUnsignedInteger size);
-
-/*debug*/
-SQUIRREL_API SQRESULT sq_stackinfos(HSQUIRRELVM v,SQInteger level,SQStackInfos *si);
-SQUIRREL_API void sq_setdebughook(HSQUIRRELVM v);
-
-/*UTILITY MACRO*/
-#define sq_isnumeric(o) ((o)._type&SQOBJECT_NUMERIC)
-#define sq_istable(o) ((o)._type==OT_TABLE)
-#define sq_isarray(o) ((o)._type==OT_ARRAY)
-#define sq_isfunction(o) ((o)._type==OT_FUNCPROTO)
-#define sq_isclosure(o) ((o)._type==OT_CLOSURE)
-#define sq_isgenerator(o) ((o)._type==OT_GENERATOR)
-#define sq_isnativeclosure(o) ((o)._type==OT_NATIVECLOSURE)
-#define sq_isstring(o) ((o)._type==OT_STRING)
-#define sq_isinteger(o) ((o)._type==OT_INTEGER)
-#define sq_isfloat(o) ((o)._type==OT_FLOAT)
-#define sq_isuserpointer(o) ((o)._type==OT_USERPOINTER)
-#define sq_isuserdata(o) ((o)._type==OT_USERDATA)
-#define sq_isthread(o) ((o)._type==OT_THREAD)
-#define sq_isnull(o) ((o)._type==OT_NULL)
-#define sq_isclass(o) ((o)._type==OT_CLASS)
-#define sq_isinstance(o) ((o)._type==OT_INSTANCE)
-#define sq_isbool(o) ((o)._type==OT_BOOL)
-#define sq_isweakref(o) ((o)._type==OT_WEAKREF)
-#define sq_type(o) ((o)._type)
-
-/* deprecated */
-#define sq_createslot(v,n) sq_newslot(v,n,SQFalse)
-
-#define SQ_OK (0)
-#define SQ_ERROR (-1)
-
-#define SQ_FAILED(res) (res<0)
-#define SQ_SUCCEEDED(res) (res>=0)
-
-#ifdef __cplusplus
-} /*extern "C"*/
-#endif
-
-#endif /*_SQUIRREL_H_*/
+++ /dev/null
-static const SQChar serialize_state_nut[] = {
-0x74, 0x72, 0x79, 0x20, 0x7b, 0x0d, 0x0a, 0x09, 0x0d, 0x0a, 0x6c, 0x6f,
-0x63, 0x61, 0x6c, 0x20, 0x6f, 0x62, 0x6a, 0x73, 0x5f, 0x72, 0x65, 0x67,
-0x3d, 0x7b, 0x6d, 0x61, 0x78, 0x69, 0x64, 0x3d, 0x30, 0x2c, 0x72, 0x65,
-0x66, 0x73, 0x3d, 0x7b, 0x7d, 0x7d, 0x0d, 0x0a, 0x0d, 0x0a, 0x63, 0x6f,
-0x6d, 0x70, 0x6c, 0x65, 0x78, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x20,
-0x3c, 0x2d, 0x20, 0x7b, 0x0d, 0x0a, 0x09, 0x5b, 0x22, 0x74, 0x61, 0x62,
-0x6c, 0x65, 0x22, 0x5d, 0x20, 0x3d, 0x20, 0x6e, 0x75, 0x6c, 0x6c, 0x2c,
-0x0d, 0x0a, 0x09, 0x5b, 0x22, 0x61, 0x72, 0x72, 0x61, 0x79, 0x22, 0x5d,
-0x20, 0x3d, 0x20, 0x6e, 0x75, 0x6c, 0x6c, 0x2c, 0x0d, 0x0a, 0x09, 0x5b,
-0x22, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x22, 0x5d, 0x20, 0x3d, 0x20, 0x6e,
-0x75, 0x6c, 0x6c, 0x2c, 0x0d, 0x0a, 0x09, 0x5b, 0x22, 0x69, 0x6e, 0x73,
-0x74, 0x61, 0x6e, 0x63, 0x65, 0x22, 0x5d, 0x20, 0x3d, 0x20, 0x6e, 0x75,
-0x6c, 0x6c, 0x2c, 0x0d, 0x0a, 0x09, 0x5b, 0x22, 0x77, 0x65, 0x61, 0x6b,
-0x72, 0x65, 0x66, 0x22, 0x5d, 0x20, 0x3d, 0x20, 0x6e, 0x75, 0x6c, 0x6c,
-0x2c, 0x0d, 0x0a, 0x7d, 0x0d, 0x0a, 0x0d, 0x0a, 0x66, 0x75, 0x6e, 0x63,
-0x74, 0x69, 0x6f, 0x6e, 0x20, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x72,
-0x65, 0x66, 0x73, 0x28, 0x74, 0x29, 0x3a, 0x28, 0x6f, 0x62, 0x6a, 0x73,
-0x5f, 0x72, 0x65, 0x67, 0x29, 0x0d, 0x0a, 0x7b, 0x0d, 0x0a, 0x09, 0x69,
-0x66, 0x28, 0x74, 0x20, 0x3d, 0x3d, 0x20, 0x3a, 0x3a, 0x67, 0x65, 0x74,
-0x72, 0x6f, 0x6f, 0x74, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x28, 0x29, 0x29,
-0x0d, 0x0a, 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x3b, 0x0d,
-0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x6f, 0x74, 0x79, 0x70,
-0x65, 0x20, 0x3d, 0x20, 0x3a, 0x3a, 0x74, 0x79, 0x70, 0x65, 0x28, 0x74,
-0x29, 0x3b, 0x0d, 0x0a, 0x09, 0x69, 0x66, 0x28, 0x6f, 0x74, 0x79, 0x70,
-0x65, 0x20, 0x69, 0x6e, 0x20, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x78,
-0x5f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x29, 0x0d, 0x0a, 0x09, 0x7b, 0x0d,
-0x0a, 0x09, 0x09, 0x69, 0x66, 0x28, 0x21, 0x28, 0x74, 0x20, 0x69, 0x6e,
-0x20, 0x6f, 0x62, 0x6a, 0x73, 0x5f, 0x72, 0x65, 0x67, 0x2e, 0x72, 0x65,
-0x66, 0x73, 0x29, 0x29, 0x20, 0x7b, 0x0d, 0x0a, 0x09, 0x09, 0x09, 0x6f,
-0x62, 0x6a, 0x73, 0x5f, 0x72, 0x65, 0x67, 0x2e, 0x72, 0x65, 0x66, 0x73,
-0x5b, 0x74, 0x5d, 0x20, 0x3c, 0x2d, 0x20, 0x6f, 0x62, 0x6a, 0x73, 0x5f,
-0x72, 0x65, 0x67, 0x2e, 0x6d, 0x61, 0x78, 0x69, 0x64, 0x2b, 0x2b, 0x3b,
-0x0d, 0x0a, 0x09, 0x09, 0x0d, 0x0a, 0x09, 0x09, 0x20, 0x20, 0x20, 0x20,
-0x69, 0x74, 0x65, 0x72, 0x61, 0x74, 0x65, 0x6f, 0x62, 0x6a, 0x65, 0x63,
-0x74, 0x28, 0x74, 0x2c, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e,
-0x28, 0x6f, 0x2c, 0x69, 0x2c, 0x76, 0x61, 0x6c, 0x29, 0x3a, 0x28, 0x6f,
-0x62, 0x6a, 0x73, 0x5f, 0x72, 0x65, 0x67, 0x29, 0x0d, 0x0a, 0x09, 0x09,
-0x20, 0x20, 0x20, 0x20, 0x7b, 0x0d, 0x0a, 0x09, 0x09, 0x09, 0x20, 0x20,
-0x20, 0x20, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x72, 0x65, 0x66, 0x73,
-0x28, 0x76, 0x61, 0x6c, 0x29, 0x3b, 0x0d, 0x0a, 0x09, 0x09, 0x09, 0x20,
-0x20, 0x20, 0x20, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x72, 0x65, 0x66,
-0x73, 0x28, 0x69, 0x29, 0x3b, 0x0d, 0x0a, 0x09, 0x09, 0x20, 0x20, 0x20,
-0x20, 0x7d, 0x29, 0x0d, 0x0a, 0x09, 0x09, 0x7d, 0x0d, 0x0a, 0x09, 0x09,
-0x0d, 0x0a, 0x09, 0x7d, 0x0d, 0x0a, 0x7d, 0x0d, 0x0a, 0x0d, 0x0a, 0x66,
-0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x67, 0x65, 0x74, 0x76,
-0x61, 0x6c, 0x75, 0x65, 0x28, 0x76, 0x29, 0x3a, 0x28, 0x6f, 0x62, 0x6a,
-0x73, 0x5f, 0x72, 0x65, 0x67, 0x29, 0x0d, 0x0a, 0x7b, 0x0d, 0x0a, 0x09,
-0x73, 0x77, 0x69, 0x74, 0x63, 0x68, 0x28, 0x3a, 0x3a, 0x74, 0x79, 0x70,
-0x65, 0x28, 0x76, 0x29, 0x29, 0x0d, 0x0a, 0x09, 0x7b, 0x0d, 0x0a, 0x09,
-0x09, 0x63, 0x61, 0x73, 0x65, 0x20, 0x22, 0x74, 0x61, 0x62, 0x6c, 0x65,
-0x22, 0x3a, 0x0d, 0x0a, 0x09, 0x09, 0x63, 0x61, 0x73, 0x65, 0x20, 0x22,
-0x61, 0x72, 0x72, 0x61, 0x79, 0x22, 0x3a, 0x0d, 0x0a, 0x09, 0x09, 0x63,
-0x61, 0x73, 0x65, 0x20, 0x22, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x22, 0x3a,
-0x0d, 0x0a, 0x09, 0x09, 0x63, 0x61, 0x73, 0x65, 0x20, 0x22, 0x69, 0x6e,
-0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x22, 0x3a, 0x0d, 0x0a, 0x09, 0x09,
-0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6f, 0x62, 0x6a, 0x73,
-0x5f, 0x72, 0x65, 0x67, 0x2e, 0x72, 0x65, 0x66, 0x73, 0x5b, 0x76, 0x5d,
-0x2e, 0x74, 0x6f, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x28, 0x29, 0x3b,
-0x0d, 0x0a, 0x09, 0x09, 0x63, 0x61, 0x73, 0x65, 0x20, 0x22, 0x69, 0x6e,
-0x74, 0x65, 0x67, 0x65, 0x72, 0x22, 0x3a, 0x0d, 0x0a, 0x09, 0x09, 0x63,
-0x61, 0x73, 0x65, 0x20, 0x22, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x22, 0x3a,
-0x0d, 0x0a, 0x09, 0x09, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75,
-0x72, 0x6e, 0x20, 0x76, 0x3b, 0x0d, 0x0a, 0x09, 0x09, 0x63, 0x61, 0x73,
-0x65, 0x20, 0x22, 0x62, 0x6f, 0x6f, 0x6c, 0x22, 0x3a, 0x0d, 0x0a, 0x09,
-0x09, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20,
-0x76, 0x2e, 0x74, 0x6f, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x28, 0x29,
-0x3b, 0x0d, 0x0a, 0x09, 0x09, 0x63, 0x61, 0x73, 0x65, 0x20, 0x22, 0x73,
-0x74, 0x72, 0x69, 0x6e, 0x67, 0x22, 0x3a, 0x0d, 0x0a, 0x09, 0x09, 0x09,
-0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x76, 0x3b, 0x0d, 0x0a, 0x09,
-0x09, 0x63, 0x61, 0x73, 0x65, 0x20, 0x22, 0x6e, 0x75, 0x6c, 0x6c, 0x22,
-0x3a, 0x0d, 0x0a, 0x09, 0x09, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x74,
-0x75, 0x72, 0x6e, 0x20, 0x22, 0x6e, 0x75, 0x6c, 0x6c, 0x22, 0x3b, 0x0d,
-0x0a, 0x09, 0x09, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x3a, 0x0d,
-0x0a, 0x09, 0x09, 0x09, 0x0d, 0x0a, 0x09, 0x09, 0x09, 0x72, 0x65, 0x74,
-0x75, 0x72, 0x6e, 0x20, 0x70, 0x61, 0x63, 0x6b, 0x5f, 0x74, 0x79, 0x70,
-0x65, 0x28, 0x3a, 0x3a, 0x74, 0x79, 0x70, 0x65, 0x28, 0x76, 0x29, 0x29,
-0x3b, 0x0d, 0x0a, 0x09, 0x7d, 0x0d, 0x0a, 0x7d, 0x0d, 0x0a, 0x0d, 0x0a,
-0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x70, 0x61, 0x63, 0x6b, 0x65, 0x64,
-0x5f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x3d, 0x7b, 0x0d, 0x0a, 0x09, 0x5b,
-0x22, 0x6e, 0x75, 0x6c, 0x6c, 0x22, 0x5d, 0x3d, 0x22, 0x6e, 0x22, 0x2c,
-0x0d, 0x0a, 0x09, 0x5b, 0x22, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x22,
-0x5d, 0x3d, 0x22, 0x73, 0x22, 0x2c, 0x0d, 0x0a, 0x09, 0x5b, 0x22, 0x69,
-0x6e, 0x74, 0x65, 0x67, 0x65, 0x72, 0x22, 0x5d, 0x3d, 0x22, 0x69, 0x22,
-0x2c, 0x0d, 0x0a, 0x09, 0x5b, 0x22, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x22,
-0x5d, 0x3d, 0x22, 0x66, 0x22, 0x2c, 0x0d, 0x0a, 0x09, 0x5b, 0x22, 0x75,
-0x73, 0x65, 0x72, 0x64, 0x61, 0x74, 0x61, 0x22, 0x5d, 0x3d, 0x22, 0x75,
-0x22, 0x2c, 0x0d, 0x0a, 0x09, 0x5b, 0x22, 0x66, 0x75, 0x6e, 0x63, 0x74,
-0x69, 0x6f, 0x6e, 0x22, 0x5d, 0x3d, 0x22, 0x66, 0x6e, 0x22, 0x2c, 0x0d,
-0x0a, 0x09, 0x5b, 0x22, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x22, 0x5d, 0x3d,
-0x22, 0x74, 0x22, 0x2c, 0x0d, 0x0a, 0x09, 0x5b, 0x22, 0x61, 0x72, 0x72,
-0x61, 0x79, 0x22, 0x5d, 0x3d, 0x22, 0x61, 0x22, 0x2c, 0x0d, 0x0a, 0x09,
-0x5b, 0x22, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x22,
-0x5d, 0x3d, 0x22, 0x67, 0x22, 0x2c, 0x0d, 0x0a, 0x09, 0x5b, 0x22, 0x74,
-0x68, 0x72, 0x65, 0x61, 0x64, 0x22, 0x5d, 0x3d, 0x22, 0x68, 0x22, 0x2c,
-0x0d, 0x0a, 0x09, 0x5b, 0x22, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63,
-0x65, 0x22, 0x5d, 0x3d, 0x22, 0x78, 0x22, 0x2c, 0x20, 0x0d, 0x0a, 0x09,
-0x5b, 0x22, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x22, 0x5d, 0x3d, 0x22, 0x79,
-0x22, 0x2c, 0x20, 0x20, 0x0d, 0x0a, 0x09, 0x5b, 0x22, 0x62, 0x6f, 0x6f,
-0x6c, 0x22, 0x5d, 0x3d, 0x22, 0x62, 0x22, 0x2c, 0x0d, 0x0a, 0x09, 0x5b,
-0x22, 0x77, 0x65, 0x61, 0x6b, 0x72, 0x65, 0x66, 0x22, 0x5d, 0x3d, 0x22,
-0x77, 0x22, 0x20, 0x20, 0x0d, 0x0a, 0x7d, 0x0d, 0x0a, 0x0d, 0x0a, 0x66,
-0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x70, 0x61, 0x63, 0x6b,
-0x5f, 0x74, 0x79, 0x70, 0x65, 0x28, 0x74, 0x79, 0x70, 0x65, 0x29, 0x3a,
-0x28, 0x70, 0x61, 0x63, 0x6b, 0x65, 0x64, 0x5f, 0x74, 0x79, 0x70, 0x65,
-0x73, 0x29, 0x0d, 0x0a, 0x7b, 0x0d, 0x0a, 0x09, 0x69, 0x66, 0x28, 0x74,
-0x79, 0x70, 0x65, 0x20, 0x69, 0x6e, 0x20, 0x70, 0x61, 0x63, 0x6b, 0x65,
-0x64, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x29, 0x72, 0x65, 0x74, 0x75,
-0x72, 0x6e, 0x20, 0x70, 0x61, 0x63, 0x6b, 0x65, 0x64, 0x5f, 0x74, 0x79,
-0x70, 0x65, 0x73, 0x5b, 0x74, 0x79, 0x70, 0x65, 0x5d, 0x0d, 0x0a, 0x09,
-0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x79, 0x70, 0x65, 0x0d,
-0x0a, 0x7d, 0x20, 0x0d, 0x0a, 0x0d, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74,
-0x69, 0x6f, 0x6e, 0x20, 0x69, 0x74, 0x65, 0x72, 0x61, 0x74, 0x65, 0x6f,
-0x62, 0x6a, 0x65, 0x63, 0x74, 0x28, 0x6f, 0x62, 0x6a, 0x2c, 0x66, 0x75,
-0x6e, 0x63, 0x29, 0x0d, 0x0a, 0x7b, 0x0d, 0x0a, 0x09, 0x6c, 0x6f, 0x63,
-0x61, 0x6c, 0x20, 0x74, 0x79, 0x20, 0x3d, 0x20, 0x3a, 0x3a, 0x74, 0x79,
-0x70, 0x65, 0x28, 0x6f, 0x62, 0x6a, 0x29, 0x3b, 0x0d, 0x0a, 0x09, 0x69,
-0x66, 0x28, 0x74, 0x79, 0x20, 0x3d, 0x3d, 0x20, 0x22, 0x69, 0x6e, 0x73,
-0x74, 0x61, 0x6e, 0x63, 0x65, 0x22, 0x29, 0x20, 0x7b, 0x0d, 0x0a, 0x09,
-0x09, 0x74, 0x72, 0x79, 0x20, 0x7b, 0x20, 0x2f, 0x2f, 0x54, 0x52, 0x59,
-0x20, 0x54, 0x4f, 0x20, 0x55, 0x53, 0x45, 0x20, 0x5f, 0x6e, 0x65, 0x78,
-0x74, 0x69, 0x0d, 0x0a, 0x09, 0x09, 0x20, 0x20, 0x20, 0x20, 0x66, 0x6f,
-0x72, 0x65, 0x61, 0x63, 0x68, 0x28, 0x69, 0x64, 0x78, 0x2c, 0x76, 0x61,
-0x6c, 0x20, 0x69, 0x6e, 0x20, 0x6f, 0x62, 0x6a, 0x29, 0x0d, 0x0a, 0x09,
-0x09, 0x20, 0x20, 0x20, 0x20, 0x7b, 0x0d, 0x0a, 0x09, 0x09, 0x09, 0x09,
-0x66, 0x75, 0x6e, 0x63, 0x28, 0x6f, 0x62, 0x6a, 0x2c, 0x69, 0x64, 0x78,
-0x2c, 0x76, 0x61, 0x6c, 0x29, 0x3b, 0x0d, 0x0a, 0x09, 0x09, 0x20, 0x20,
-0x20, 0x20, 0x7d, 0x0d, 0x0a, 0x09, 0x09, 0x7d, 0x0d, 0x0a, 0x09, 0x09,
-0x63, 0x61, 0x74, 0x63, 0x68, 0x28, 0x65, 0x29, 0x20, 0x7b, 0x0d, 0x0a,
-0x09, 0x09, 0x20, 0x20, 0x20, 0x66, 0x6f, 0x72, 0x65, 0x61, 0x63, 0x68,
-0x28, 0x69, 0x64, 0x78, 0x2c, 0x76, 0x61, 0x6c, 0x20, 0x69, 0x6e, 0x20,
-0x6f, 0x62, 0x6a, 0x2e, 0x67, 0x65, 0x74, 0x63, 0x6c, 0x61, 0x73, 0x73,
-0x28, 0x29, 0x29, 0x0d, 0x0a, 0x09, 0x09, 0x20, 0x20, 0x20, 0x7b, 0x0d,
-0x0a, 0x09, 0x09, 0x09, 0x66, 0x75, 0x6e, 0x63, 0x28, 0x6f, 0x62, 0x6a,
-0x2c, 0x69, 0x64, 0x78, 0x2c, 0x6f, 0x62, 0x6a, 0x5b, 0x69, 0x64, 0x78,
-0x5d, 0x29, 0x3b, 0x0d, 0x0a, 0x09, 0x09, 0x20, 0x20, 0x20, 0x7d, 0x0d,
-0x0a, 0x09, 0x09, 0x7d, 0x0d, 0x0a, 0x09, 0x7d, 0x0d, 0x0a, 0x09, 0x65,
-0x6c, 0x73, 0x65, 0x20, 0x69, 0x66, 0x28, 0x74, 0x79, 0x20, 0x3d, 0x3d,
-0x20, 0x22, 0x77, 0x65, 0x61, 0x6b, 0x72, 0x65, 0x66, 0x22, 0x29, 0x20,
-0x7b, 0x0d, 0x0a, 0x09, 0x09, 0x66, 0x75, 0x6e, 0x63, 0x28, 0x6f, 0x62,
-0x6a, 0x2c, 0x22, 0x40, 0x72, 0x65, 0x66, 0x22, 0x2c, 0x6f, 0x62, 0x6a,
-0x2e, 0x72, 0x65, 0x66, 0x28, 0x29, 0x29, 0x3b, 0x0d, 0x0a, 0x09, 0x7d,
-0x0d, 0x0a, 0x09, 0x65, 0x6c, 0x73, 0x65, 0x20, 0x7b, 0x0d, 0x0a, 0x09,
-0x09, 0x66, 0x6f, 0x72, 0x65, 0x61, 0x63, 0x68, 0x28, 0x69, 0x64, 0x78,
-0x2c, 0x76, 0x61, 0x6c, 0x20, 0x69, 0x6e, 0x20, 0x6f, 0x62, 0x6a, 0x29,
-0x0d, 0x0a, 0x09, 0x09, 0x7b, 0x0d, 0x0a, 0x09, 0x09, 0x20, 0x20, 0x20,
-0x20, 0x66, 0x75, 0x6e, 0x63, 0x28, 0x6f, 0x62, 0x6a, 0x2c, 0x69, 0x64,
-0x78, 0x2c, 0x76, 0x61, 0x6c, 0x29, 0x3b, 0x0d, 0x0a, 0x09, 0x09, 0x7d,
-0x0d, 0x0a, 0x09, 0x7d, 0x0d, 0x0a, 0x09, 0x09, 0x09, 0x0d, 0x0a, 0x7d,
-0x0d, 0x0a, 0x0d, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e,
-0x20, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x74, 0x72, 0x65, 0x65, 0x28,
-0x29, 0x3a, 0x28, 0x6f, 0x62, 0x6a, 0x73, 0x5f, 0x72, 0x65, 0x67, 0x29,
-0x0d, 0x0a, 0x7b, 0x0d, 0x0a, 0x09, 0x66, 0x6f, 0x72, 0x65, 0x61, 0x63,
-0x68, 0x28, 0x69, 0x2c, 0x6f, 0x20, 0x69, 0x6e, 0x20, 0x6f, 0x62, 0x6a,
-0x73, 0x5f, 0x72, 0x65, 0x67, 0x2e, 0x72, 0x65, 0x66, 0x73, 0x29, 0x0d,
-0x0a, 0x09, 0x7b, 0x0d, 0x0a, 0x09, 0x09, 0x62, 0x65, 0x67, 0x69, 0x6e,
-0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x28, 0x22, 0x6f, 0x22, 0x29,
-0x3b, 0x0d, 0x0a, 0x09, 0x09, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75,
-0x74, 0x65, 0x28, 0x22, 0x74, 0x79, 0x70, 0x65, 0x22, 0x2c, 0x28, 0x69,
-0x3d, 0x3d, 0x3a, 0x3a, 0x67, 0x65, 0x74, 0x72, 0x6f, 0x6f, 0x74, 0x74,
-0x61, 0x62, 0x6c, 0x65, 0x28, 0x29, 0x3f, 0x22, 0x72, 0x22, 0x3a, 0x70,
-0x61, 0x63, 0x6b, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x28, 0x3a, 0x3a, 0x74,
-0x79, 0x70, 0x65, 0x28, 0x69, 0x29, 0x29, 0x29, 0x29, 0x3b, 0x0d, 0x0a,
-0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x5f, 0x74, 0x79, 0x70,
-0x65, 0x6f, 0x66, 0x20, 0x3d, 0x20, 0x74, 0x79, 0x70, 0x65, 0x6f, 0x66,
-0x20, 0x69, 0x3b, 0x0d, 0x0a, 0x09, 0x09, 0x69, 0x66, 0x28, 0x5f, 0x74,
-0x79, 0x70, 0x65, 0x6f, 0x66, 0x20, 0x21, 0x3d, 0x20, 0x3a, 0x3a, 0x74,
-0x79, 0x70, 0x65, 0x28, 0x69, 0x29, 0x29, 0x20, 0x7b, 0x0d, 0x0a, 0x09,
-0x09, 0x09, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x28,
-0x22, 0x74, 0x79, 0x70, 0x65, 0x6f, 0x66, 0x22, 0x2c, 0x5f, 0x74, 0x79,
-0x70, 0x65, 0x6f, 0x66, 0x29, 0x3b, 0x0d, 0x0a, 0x09, 0x09, 0x7d, 0x0d,
-0x0a, 0x09, 0x09, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65,
-0x28, 0x22, 0x72, 0x65, 0x66, 0x22, 0x2c, 0x6f, 0x2e, 0x74, 0x6f, 0x73,
-0x74, 0x72, 0x69, 0x6e, 0x67, 0x28, 0x29, 0x29, 0x3b, 0x0d, 0x0a, 0x09,
-0x09, 0x69, 0x66, 0x28, 0x69, 0x20, 0x21, 0x3d, 0x20, 0x3a, 0x3a, 0x67,
-0x65, 0x74, 0x72, 0x6f, 0x6f, 0x74, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x28,
-0x29, 0x29, 0x7b, 0x0d, 0x0a, 0x09, 0x09, 0x09, 0x69, 0x74, 0x65, 0x72,
-0x61, 0x74, 0x65, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x28, 0x69, 0x2c,
-0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x6f, 0x62,
-0x6a, 0x2c, 0x69, 0x64, 0x78, 0x2c, 0x76, 0x61, 0x6c, 0x29, 0x20, 0x7b,
-0x0d, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x69, 0x66, 0x28, 0x3a, 0x3a, 0x74,
-0x79, 0x70, 0x65, 0x28, 0x76, 0x61, 0x6c, 0x29, 0x20, 0x3d, 0x3d, 0x20,
-0x22, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x29, 0x0d,
-0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e,
-0x3b, 0x0d, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x0d, 0x0a, 0x09, 0x09,
-0x09, 0x09, 0x62, 0x65, 0x67, 0x69, 0x6e, 0x65, 0x6c, 0x65, 0x6d, 0x65,
-0x6e, 0x74, 0x28, 0x22, 0x65, 0x22, 0x29, 0x3b, 0x09, 0x0d, 0x0a, 0x09,
-0x09, 0x09, 0x09, 0x09, 0x65, 0x6d, 0x69, 0x74, 0x76, 0x61, 0x6c, 0x75,
-0x65, 0x28, 0x22, 0x6b, 0x74, 0x22, 0x2c, 0x22, 0x6b, 0x76, 0x22, 0x2c,
-0x69, 0x64, 0x78, 0x29, 0x3b, 0x0d, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09,
-0x65, 0x6d, 0x69, 0x74, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x28, 0x22, 0x76,
-0x74, 0x22, 0x2c, 0x22, 0x76, 0x22, 0x2c, 0x6f, 0x62, 0x6a, 0x5b, 0x69,
-0x64, 0x78, 0x5d, 0x29, 0x3b, 0x0d, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x65,
-0x6e, 0x64, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x28, 0x22, 0x65,
-0x22, 0x29, 0x3b, 0x09, 0x0d, 0x0a, 0x0d, 0x0a, 0x09, 0x09, 0x09, 0x7d,
-0x29, 0x0d, 0x0a, 0x09, 0x09, 0x7d, 0x0d, 0x0a, 0x09, 0x09, 0x65, 0x6e,
-0x64, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x28, 0x22, 0x6f, 0x22,
-0x29, 0x3b, 0x0d, 0x0a, 0x09, 0x7d, 0x0d, 0x0a, 0x7d, 0x0d, 0x0a, 0x0d,
-0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x65, 0x76,
-0x61, 0x6c, 0x75, 0x61, 0x74, 0x65, 0x5f, 0x77, 0x61, 0x74, 0x63, 0x68,
-0x28, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x73, 0x2c, 0x69, 0x64, 0x2c, 0x65,
-0x78, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x29, 0x0d, 0x0a,
-0x7b, 0x0d, 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x66, 0x75,
-0x6e, 0x63, 0x5f, 0x73, 0x72, 0x63, 0x3d, 0x22, 0x72, 0x65, 0x74, 0x75,
-0x72, 0x6e, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20,
-0x28, 0x22, 0x0d, 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x70,
-0x61, 0x72, 0x61, 0x6d, 0x73, 0x3d, 0x5b, 0x5d, 0x3b, 0x0d, 0x0a, 0x09,
-0x0d, 0x0a, 0x09, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x2e, 0x61, 0x70,
-0x70, 0x65, 0x6e, 0x64, 0x28, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x73, 0x5b,
-0x22, 0x74, 0x68, 0x69, 0x73, 0x22, 0x5d, 0x29, 0x0d, 0x0a, 0x09, 0x6c,
-0x6f, 0x63, 0x61, 0x6c, 0x20, 0x66, 0x69, 0x72, 0x73, 0x74, 0x3d, 0x31,
-0x3b, 0x0d, 0x0a, 0x09, 0x66, 0x6f, 0x72, 0x65, 0x61, 0x63, 0x68, 0x28,
-0x69, 0x2c, 0x76, 0x20, 0x69, 0x6e, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c,
-0x73, 0x29, 0x7b, 0x0d, 0x0a, 0x09, 0x09, 0x69, 0x66, 0x28, 0x69, 0x21,
-0x3d, 0x22, 0x74, 0x68, 0x69, 0x73, 0x22, 0x20, 0x26, 0x26, 0x20, 0x69,
-0x5b, 0x30, 0x5d, 0x20, 0x21, 0x3d, 0x20, 0x27, 0x40, 0x27, 0x29, 0x7b,
-0x20, 0x2f, 0x2f, 0x66, 0x6f, 0x72, 0x65, 0x61, 0x63, 0x68, 0x20, 0x69,
-0x74, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x73, 0x20, 0x73, 0x74, 0x61,
-0x72, 0x74, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x40, 0x0d, 0x0a, 0x09,
-0x09, 0x09, 0x69, 0x66, 0x28, 0x21, 0x66, 0x69, 0x72, 0x73, 0x74, 0x29,
-0x7b, 0x0d, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x66, 0x75, 0x6e, 0x63, 0x5f,
-0x73, 0x72, 0x63, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x5f, 0x73, 0x72, 0x63,
-0x2b, 0x22, 0x2c, 0x22, 0x0d, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x0d, 0x0a,
-0x09, 0x09, 0x09, 0x7d, 0x0d, 0x0a, 0x09, 0x09, 0x09, 0x66, 0x69, 0x72,
-0x73, 0x74, 0x3d, 0x6e, 0x75, 0x6c, 0x6c, 0x0d, 0x0a, 0x09, 0x09, 0x09,
-0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x2e, 0x61, 0x70, 0x70, 0x65, 0x6e,
-0x64, 0x28, 0x76, 0x29, 0x0d, 0x0a, 0x09, 0x09, 0x09, 0x66, 0x75, 0x6e,
-0x63, 0x5f, 0x73, 0x72, 0x63, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x5f, 0x73,
-0x72, 0x63, 0x2b, 0x69, 0x0d, 0x0a, 0x09, 0x09, 0x7d, 0x0d, 0x0a, 0x09,
-0x7d, 0x0d, 0x0a, 0x09, 0x66, 0x75, 0x6e, 0x63, 0x5f, 0x73, 0x72, 0x63,
-0x3d, 0x66, 0x75, 0x6e, 0x63, 0x5f, 0x73, 0x72, 0x63, 0x2b, 0x22, 0x29,
-0x7b, 0x5c, 0x6e, 0x22, 0x0d, 0x0a, 0x09, 0x66, 0x75, 0x6e, 0x63, 0x5f,
-0x73, 0x72, 0x63, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x5f, 0x73, 0x72, 0x63,
-0x2b, 0x22, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x28, 0x22, 0x2b,
-0x65, 0x78, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x2b, 0x22,
-0x29, 0x5c, 0x6e, 0x7d, 0x22, 0x0d, 0x0a, 0x09, 0x0d, 0x0a, 0x09, 0x74,
-0x72, 0x79, 0x20, 0x7b, 0x0d, 0x0a, 0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61,
-0x6c, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x3d, 0x3a, 0x3a, 0x63, 0x6f, 0x6d,
-0x70, 0x69, 0x6c, 0x65, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x28, 0x66,
-0x75, 0x6e, 0x63, 0x5f, 0x73, 0x72, 0x63, 0x29, 0x3b, 0x0d, 0x0a, 0x09,
-0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x7b, 0x73, 0x74, 0x61,
-0x74, 0x75, 0x73, 0x3d, 0x22, 0x6f, 0x6b, 0x22, 0x20, 0x2c, 0x20, 0x76,
-0x61, 0x6c, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x28, 0x29, 0x2e, 0x61, 0x63,
-0x61, 0x6c, 0x6c, 0x28, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x29, 0x7d,
-0x3b, 0x0d, 0x0a, 0x09, 0x7d, 0x0d, 0x0a, 0x09, 0x63, 0x61, 0x74, 0x63,
-0x68, 0x28, 0x65, 0x29, 0x0d, 0x0a, 0x09, 0x7b, 0x0d, 0x0a, 0x09, 0x09,
-0x0d, 0x0a, 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x7b,
-0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x3d, 0x22, 0x65, 0x72, 0x72, 0x6f,
-0x72, 0x22, 0x7d, 0x0d, 0x0a, 0x09, 0x7d, 0x0d, 0x0a, 0x7d, 0x0d, 0x0a,
-0x0d, 0x0a, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
-0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
-0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
-0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
-0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
-0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
-0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x0d, 0x0a, 0x2f, 0x2f, 0x2f,
-0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
-0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
-0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
-0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
-0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
-0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
-0x2f, 0x2f, 0x0d, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e,
-0x20, 0x65, 0x6d, 0x69, 0x74, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x28, 0x74,
-0x79, 0x70, 0x65, 0x5f, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x2c, 0x76,
-0x61, 0x6c, 0x75, 0x65, 0x5f, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x2c,
-0x76, 0x61, 0x6c, 0x29, 0x0d, 0x0a, 0x7b, 0x0d, 0x0a, 0x09, 0x61, 0x74,
-0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x28, 0x74, 0x79, 0x70, 0x65,
-0x5f, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x2c, 0x70, 0x61, 0x63, 0x6b,
-0x5f, 0x74, 0x79, 0x70, 0x65, 0x28, 0x3a, 0x3a, 0x74, 0x79, 0x70, 0x65,
-0x28, 0x76, 0x61, 0x6c, 0x29, 0x29, 0x29, 0x3b, 0x0d, 0x0a, 0x09, 0x61,
-0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x28, 0x76, 0x61, 0x6c,
-0x75, 0x65, 0x5f, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x2c, 0x67, 0x65,
-0x74, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x28, 0x76, 0x61, 0x6c, 0x29, 0x2e,
-0x74, 0x6f, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x28, 0x29, 0x29, 0x3b,
-0x0d, 0x0a, 0x7d, 0x0d, 0x0a, 0x0d, 0x0a, 0x6c, 0x6f, 0x63, 0x61, 0x6c,
-0x20, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x3d, 0x5b, 0x5d, 0x0d, 0x0a, 0x6c,
-0x6f, 0x63, 0x61, 0x6c, 0x20, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x3d, 0x33,
-0x3b, 0x0d, 0x0a, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x73, 0x69, 0x3b,
-0x0d, 0x0a, 0x0d, 0x0a, 0x2f, 0x2f, 0x74, 0x72, 0x79, 0x20, 0x7b, 0x0d,
-0x0a, 0x09, 0x2f, 0x2f, 0x45, 0x4e, 0x55, 0x4d, 0x45, 0x52, 0x41, 0x54,
-0x45, 0x20, 0x54, 0x48, 0x45, 0x20, 0x53, 0x54, 0x41, 0x43, 0x4b, 0x20,
-0x57, 0x41, 0x54, 0x43, 0x48, 0x45, 0x53, 0x0d, 0x0a, 0x09, 0x77, 0x68,
-0x69, 0x6c, 0x65, 0x28, 0x73, 0x69, 0x3d, 0x3a, 0x3a, 0x67, 0x65, 0x74,
-0x73, 0x74, 0x61, 0x63, 0x6b, 0x69, 0x6e, 0x66, 0x6f, 0x73, 0x28, 0x6c,
-0x65, 0x76, 0x65, 0x6c, 0x29, 0x29, 0x0d, 0x0a, 0x09, 0x7b, 0x0d, 0x0a,
-0x09, 0x09, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x61, 0x70, 0x70, 0x65,
-0x6e, 0x64, 0x28, 0x73, 0x69, 0x29, 0x3b, 0x0d, 0x0a, 0x09, 0x09, 0x6c,
-0x65, 0x76, 0x65, 0x6c, 0x2b, 0x2b, 0x3b, 0x0d, 0x0a, 0x09, 0x7d, 0x0d,
-0x0a, 0x0d, 0x0a, 0x09, 0x2f, 0x2f, 0x45, 0x56, 0x41, 0x4c, 0x55, 0x41,
-0x54, 0x45, 0x20, 0x41, 0x4c, 0x4c, 0x20, 0x57, 0x41, 0x54, 0x43, 0x48,
-0x45, 0x53, 0x0d, 0x0a, 0x09, 0x6f, 0x62, 0x6a, 0x73, 0x5f, 0x72, 0x65,
-0x67, 0x2e, 0x72, 0x65, 0x66, 0x73, 0x5b, 0x3a, 0x3a, 0x67, 0x65, 0x74,
-0x72, 0x6f, 0x6f, 0x74, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x28, 0x29, 0x5d,
-0x20, 0x3c, 0x2d, 0x20, 0x6f, 0x62, 0x6a, 0x73, 0x5f, 0x72, 0x65, 0x67,
-0x2e, 0x6d, 0x61, 0x78, 0x69, 0x64, 0x2b, 0x2b, 0x3b, 0x0d, 0x0a, 0x09,
-0x66, 0x6f, 0x72, 0x65, 0x61, 0x63, 0x68, 0x28, 0x69, 0x2c, 0x76, 0x61,
-0x6c, 0x20, 0x69, 0x6e, 0x20, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x29, 0x0d,
-0x0a, 0x09, 0x7b, 0x0d, 0x0a, 0x09, 0x09, 0x69, 0x66, 0x28, 0x76, 0x61,
-0x6c, 0x2e, 0x73, 0x72, 0x63, 0x21, 0x3d, 0x22, 0x4e, 0x41, 0x54, 0x49,
-0x56, 0x45, 0x22, 0x29, 0x20, 0x7b, 0x0d, 0x0a, 0x09, 0x09, 0x09, 0x69,
-0x66, 0x28, 0x22, 0x77, 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, 0x22, 0x20,
-0x69, 0x6e, 0x20, 0x74, 0x68, 0x69, 0x73, 0x29, 0x20, 0x7b, 0x0d, 0x0a,
-0x09, 0x09, 0x09, 0x09, 0x76, 0x61, 0x6c, 0x2e, 0x77, 0x61, 0x74, 0x63,
-0x68, 0x65, 0x73, 0x20, 0x3c, 0x2d, 0x20, 0x7b, 0x7d, 0x0d, 0x0a, 0x09,
-0x09, 0x09, 0x09, 0x66, 0x6f, 0x72, 0x65, 0x61, 0x63, 0x68, 0x28, 0x69,
-0x2c, 0x77, 0x61, 0x74, 0x63, 0x68, 0x20, 0x69, 0x6e, 0x20, 0x77, 0x61,
-0x74, 0x63, 0x68, 0x65, 0x73, 0x29, 0x0d, 0x0a, 0x09, 0x09, 0x09, 0x09,
-0x7b, 0x0d, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x69, 0x66, 0x28, 0x76,
-0x61, 0x6c, 0x2e, 0x73, 0x72, 0x63, 0x21, 0x3d, 0x22, 0x4e, 0x41, 0x54,
-0x49, 0x56, 0x45, 0x22, 0x29, 0x7b, 0x0d, 0x0a, 0x09, 0x09, 0x09, 0x09,
-0x09, 0x09, 0x76, 0x61, 0x6c, 0x2e, 0x77, 0x61, 0x74, 0x63, 0x68, 0x65,
-0x73, 0x5b, 0x69, 0x5d, 0x20, 0x3c, 0x2d, 0x20, 0x65, 0x76, 0x61, 0x6c,
-0x75, 0x61, 0x74, 0x65, 0x5f, 0x77, 0x61, 0x74, 0x63, 0x68, 0x28, 0x76,
-0x61, 0x6c, 0x2e, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x73, 0x2c, 0x69, 0x2c,
-0x77, 0x61, 0x74, 0x63, 0x68, 0x29, 0x3b, 0x0d, 0x0a, 0x09, 0x09, 0x09,
-0x09, 0x09, 0x09, 0x69, 0x66, 0x28, 0x76, 0x61, 0x6c, 0x2e, 0x77, 0x61,
-0x74, 0x63, 0x68, 0x65, 0x73, 0x5b, 0x69, 0x5d, 0x2e, 0x73, 0x74, 0x61,
-0x74, 0x75, 0x73, 0x21, 0x3d, 0x22, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x22,
-0x29, 0x0d, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x62, 0x75,
-0x69, 0x6c, 0x64, 0x5f, 0x72, 0x65, 0x66, 0x73, 0x28, 0x76, 0x61, 0x6c,
-0x2e, 0x77, 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, 0x5b, 0x69, 0x5d, 0x2e,
-0x76, 0x61, 0x6c, 0x29, 0x3b, 0x0d, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09,
-0x7d, 0x0d, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x65, 0x6c, 0x73, 0x65,
-0x7b, 0x0d, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x76, 0x61, 0x6c,
-0x2e, 0x77, 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, 0x5b, 0x69, 0x5d, 0x20,
-0x3c, 0x2d, 0x20, 0x7b, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x3d, 0x22,
-0x65, 0x72, 0x72, 0x6f, 0x72, 0x22, 0x7d, 0x0d, 0x0a, 0x09, 0x09, 0x09,
-0x09, 0x09, 0x7d, 0x0d, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x76, 0x61,
-0x6c, 0x2e, 0x77, 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, 0x5b, 0x69, 0x5d,
-0x2e, 0x65, 0x78, 0x70, 0x20, 0x3c, 0x2d, 0x20, 0x77, 0x61, 0x74, 0x63,
-0x68, 0x3b, 0x0d, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x7d, 0x0d, 0x0a, 0x09,
-0x09, 0x09, 0x09, 0x0d, 0x0a, 0x09, 0x09, 0x09, 0x7d, 0x0d, 0x0a, 0x09,
-0x09, 0x7d, 0x0d, 0x0a, 0x09, 0x09, 0x66, 0x6f, 0x72, 0x65, 0x61, 0x63,
-0x68, 0x28, 0x69, 0x2c, 0x6c, 0x20, 0x69, 0x6e, 0x20, 0x76, 0x61, 0x6c,
-0x2e, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x73, 0x29, 0x0d, 0x0a, 0x09, 0x09,
-0x09, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x72, 0x65, 0x66, 0x73, 0x28,
-0x6c, 0x29, 0x3b, 0x0d, 0x0a, 0x09, 0x7d, 0x0d, 0x0a, 0x0d, 0x0a, 0x0d,
-0x0a, 0x09, 0x62, 0x65, 0x67, 0x69, 0x6e, 0x65, 0x6c, 0x65, 0x6d, 0x65,
-0x6e, 0x74, 0x28, 0x22, 0x6f, 0x62, 0x6a, 0x73, 0x22, 0x29, 0x3b, 0x0d,
-0x0a, 0x09, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x74, 0x72, 0x65, 0x65,
-0x28, 0x29, 0x3b, 0x0d, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x65, 0x6c, 0x65,
-0x6d, 0x65, 0x6e, 0x74, 0x28, 0x22, 0x6f, 0x62, 0x6a, 0x73, 0x22, 0x29,
-0x3b, 0x0d, 0x0a, 0x0d, 0x0a, 0x09, 0x62, 0x65, 0x67, 0x69, 0x6e, 0x65,
-0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x28, 0x22, 0x63, 0x61, 0x6c, 0x6c,
-0x73, 0x22, 0x29, 0x3b, 0x0d, 0x0a, 0x0d, 0x0a, 0x09, 0x66, 0x6f, 0x72,
-0x65, 0x61, 0x63, 0x68, 0x28, 0x69, 0x2c, 0x76, 0x61, 0x6c, 0x20, 0x69,
-0x6e, 0x20, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x29, 0x0d, 0x0a, 0x09, 0x7b,
-0x0d, 0x0a, 0x0d, 0x0a, 0x09, 0x09, 0x62, 0x65, 0x67, 0x69, 0x6e, 0x65,
-0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x28, 0x22, 0x63, 0x61, 0x6c, 0x6c,
-0x22, 0x29, 0x3b, 0x0d, 0x0a, 0x09, 0x09, 0x61, 0x74, 0x74, 0x72, 0x69,
-0x62, 0x75, 0x74, 0x65, 0x28, 0x22, 0x66, 0x6e, 0x63, 0x22, 0x2c, 0x76,
-0x61, 0x6c, 0x2e, 0x66, 0x75, 0x6e, 0x63, 0x29, 0x3b, 0x0d, 0x0a, 0x09,
-0x09, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x28, 0x22,
-0x73, 0x72, 0x63, 0x22, 0x2c, 0x76, 0x61, 0x6c, 0x2e, 0x73, 0x72, 0x63,
-0x29, 0x3b, 0x0d, 0x0a, 0x09, 0x09, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62,
-0x75, 0x74, 0x65, 0x28, 0x22, 0x6c, 0x69, 0x6e, 0x65, 0x22, 0x2c, 0x76,
-0x61, 0x6c, 0x2e, 0x6c, 0x69, 0x6e, 0x65, 0x2e, 0x74, 0x6f, 0x73, 0x74,
-0x72, 0x69, 0x6e, 0x67, 0x28, 0x29, 0x29, 0x3b, 0x0d, 0x0a, 0x09, 0x09,
-0x66, 0x6f, 0x72, 0x65, 0x61, 0x63, 0x68, 0x28, 0x69, 0x2c, 0x76, 0x20,
-0x69, 0x6e, 0x20, 0x76, 0x61, 0x6c, 0x2e, 0x6c, 0x6f, 0x63, 0x61, 0x6c,
-0x73, 0x29, 0x0d, 0x0a, 0x09, 0x09, 0x7b, 0x0d, 0x0a, 0x09, 0x09, 0x09,
-0x62, 0x65, 0x67, 0x69, 0x6e, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74,
-0x28, 0x22, 0x6c, 0x22, 0x29, 0x3b, 0x0d, 0x0a, 0x09, 0x09, 0x09, 0x09,
-0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x28, 0x22, 0x6e,
-0x61, 0x6d, 0x65, 0x22, 0x2c, 0x67, 0x65, 0x74, 0x76, 0x61, 0x6c, 0x75,
-0x65, 0x28, 0x69, 0x29, 0x2e, 0x74, 0x6f, 0x73, 0x74, 0x72, 0x69, 0x6e,
-0x67, 0x28, 0x29, 0x29, 0x3b, 0x0d, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x65,
-0x6d, 0x69, 0x74, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x28, 0x22, 0x74, 0x79,
-0x70, 0x65, 0x22, 0x2c, 0x22, 0x76, 0x61, 0x6c, 0x22, 0x2c, 0x76, 0x29,
-0x3b, 0x0d, 0x0a, 0x09, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x65, 0x6c, 0x65,
-0x6d, 0x65, 0x6e, 0x74, 0x28, 0x22, 0x6c, 0x22, 0x29, 0x3b, 0x0d, 0x0a,
-0x09, 0x09, 0x7d, 0x0d, 0x0a, 0x09, 0x09, 0x69, 0x66, 0x28, 0x22, 0x77,
-0x61, 0x74, 0x63, 0x68, 0x65, 0x73, 0x22, 0x20, 0x69, 0x6e, 0x20, 0x76,
-0x61, 0x6c, 0x29, 0x20, 0x7b, 0x0d, 0x0a, 0x09, 0x09, 0x09, 0x66, 0x6f,
-0x72, 0x65, 0x61, 0x63, 0x68, 0x28, 0x69, 0x2c, 0x76, 0x20, 0x69, 0x6e,
-0x20, 0x76, 0x61, 0x6c, 0x2e, 0x77, 0x61, 0x74, 0x63, 0x68, 0x65, 0x73,
-0x29, 0x0d, 0x0a, 0x09, 0x09, 0x09, 0x7b, 0x0d, 0x0a, 0x09, 0x09, 0x09,
-0x09, 0x62, 0x65, 0x67, 0x69, 0x6e, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e,
-0x74, 0x28, 0x22, 0x77, 0x22, 0x29, 0x3b, 0x0d, 0x0a, 0x09, 0x09, 0x09,
-0x09, 0x09, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x28,
-0x22, 0x69, 0x64, 0x22, 0x2c, 0x69, 0x2e, 0x74, 0x6f, 0x73, 0x74, 0x72,
-0x69, 0x6e, 0x67, 0x28, 0x29, 0x29, 0x3b, 0x0d, 0x0a, 0x09, 0x09, 0x09,
-0x09, 0x09, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x28,
-0x22, 0x65, 0x78, 0x70, 0x22, 0x2c, 0x76, 0x2e, 0x65, 0x78, 0x70, 0x29,
-0x3b, 0x0d, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x61, 0x74, 0x74, 0x72,
-0x69, 0x62, 0x75, 0x74, 0x65, 0x28, 0x22, 0x73, 0x74, 0x61, 0x74, 0x75,
-0x73, 0x22, 0x2c, 0x76, 0x2e, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x29,
-0x3b, 0x0d, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x69, 0x66, 0x28, 0x76,
-0x2e, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x21, 0x3d, 0x22, 0x65, 0x72,
-0x72, 0x6f, 0x72, 0x22, 0x29, 0x20, 0x7b, 0x0d, 0x0a, 0x09, 0x09, 0x09,
-0x09, 0x09, 0x09, 0x65, 0x6d, 0x69, 0x74, 0x76, 0x61, 0x6c, 0x75, 0x65,
-0x28, 0x22, 0x74, 0x79, 0x70, 0x65, 0x22, 0x2c, 0x22, 0x76, 0x61, 0x6c,
-0x22, 0x2c, 0x76, 0x2e, 0x76, 0x61, 0x6c, 0x29, 0x3b, 0x0d, 0x0a, 0x09,
-0x09, 0x09, 0x09, 0x09, 0x7d, 0x0d, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x65,
-0x6e, 0x64, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x28, 0x22, 0x77,
-0x22, 0x29, 0x3b, 0x0d, 0x0a, 0x09, 0x09, 0x09, 0x7d, 0x0d, 0x0a, 0x09,
-0x09, 0x7d, 0x0d, 0x0a, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x65, 0x6c, 0x65,
-0x6d, 0x65, 0x6e, 0x74, 0x28, 0x22, 0x63, 0x61, 0x6c, 0x6c, 0x22, 0x29,
-0x3b, 0x0d, 0x0a, 0x09, 0x09, 0x20, 0x0d, 0x0a, 0x09, 0x7d, 0x0d, 0x0a,
-0x09, 0x65, 0x6e, 0x64, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x28,
-0x22, 0x63, 0x61, 0x6c, 0x6c, 0x73, 0x22, 0x29, 0x3b, 0x0d, 0x0a, 0x0d,
-0x0a, 0x0d, 0x0a, 0x09, 0x6f, 0x62, 0x6a, 0x73, 0x5f, 0x72, 0x65, 0x67,
-0x20, 0x3d, 0x20, 0x6e, 0x75, 0x6c, 0x6c, 0x3b, 0x0d, 0x0a, 0x09, 0x73,
-0x74, 0x61, 0x63, 0x6b, 0x20, 0x3d, 0x20, 0x6e, 0x75, 0x6c, 0x6c, 0x3b,
-0x0d, 0x0a, 0x09, 0x0d, 0x0a, 0x09, 0x69, 0x66, 0x28, 0x22, 0x63, 0x6f,
-0x6c, 0x6c, 0x65, 0x63, 0x74, 0x67, 0x61, 0x72, 0x62, 0x61, 0x67, 0x65,
-0x22, 0x20, 0x69, 0x6e, 0x20, 0x3a, 0x3a, 0x67, 0x65, 0x74, 0x72, 0x6f,
-0x6f, 0x74, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x28, 0x29, 0x29, 0x20, 0x3a,
-0x3a, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x67, 0x61, 0x72, 0x62,
-0x61, 0x67, 0x65, 0x28, 0x29, 0x3b, 0x0d, 0x0a, 0x7d, 0x63, 0x61, 0x74,
-0x63, 0x68, 0x28, 0x65, 0x29, 0x0d, 0x0a, 0x7b, 0x0d, 0x0a, 0x09, 0x3a,
-0x3a, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x28, 0x22, 0x45, 0x52, 0x52, 0x4f,
-0x52, 0x22, 0x2b, 0x65, 0x2b, 0x22, 0x5c, 0x6e, 0x22, 0x29, 0x3b, 0x0d,
-0x0a, 0x7d, 0x0d, 0x0a, 0x0d, 0x0a, 0x00,
-};
+++ /dev/null
-#include <squirrel.h>
-#include <assert.h>
-#include <sqstdblob.h>
-#include "sqrdbg.h"
-#include "sqdbgserver.h"
-
-
-#ifndef _UNICODE
-#define scstrcpy strcpy
-#else
-#define scstrcpy wcscpy
-#endif
-struct XMLEscape{
- const SQChar c;
- const SQChar *esc;
-};
-
-#define SQDBG_DEBUG_HOOK _SC("_sqdbg_debug_hook_")
-#define SQDBG_ERROR_HANDLER _SC("_sqdbg_error_handler_")
-
-XMLEscape g_escapes[]={
- {_SC('<'),_SC("<")},{'>',_SC(">")},{_SC('&'),_SC("&")},{_SC('\''),_SC("'")},{_SC('\"'),_SC(""")},{_SC('\n'),_SC(""n")},{_SC('\r'),_SC(""r")},{0, NULL}
-};
-
-const SQChar *IntToString(int n)
-{
- static SQChar temp[256];
- scsprintf(temp,_SC("%d"),n);
- return temp;
-}
-
-SQInteger debug_hook(HSQUIRRELVM v);
-SQInteger error_handler(HSQUIRRELVM v);
-
-SQInteger beginelement(HSQUIRRELVM v)
-{
- SQUserPointer up;
- const SQChar *name;
- sq_getuserpointer(v,-1,&up);
- SQDbgServer *self = (SQDbgServer*)up;
- sq_getuserpointer(v,-1,&up);
- sq_getstring(v,2,&name);
- self->BeginElement(name);
- return 0;
-}
-
-SQInteger endelement(HSQUIRRELVM v)
-{
- SQUserPointer up;
- const SQChar *name;
- sq_getuserpointer(v,-1,&up);
- SQDbgServer *self = (SQDbgServer*)up;
- sq_getuserpointer(v,-1,&up);
- sq_getstring(v,2,&name);
- self->EndElement(name);
- return 0;
-}
-
-SQInteger attribute(HSQUIRRELVM v)
-{
- SQUserPointer up;
- const SQChar *name,*value;
- sq_getuserpointer(v,-1,&up);
- SQDbgServer *self = (SQDbgServer*)up;
- sq_getuserpointer(v,-1,&up);
- sq_getstring(v,2,&name);
- sq_getstring(v,3,&value);
- self->Attribute(name,value);
- return 0;
-}
-
-const SQChar *EscapeXMLString(HSQUIRRELVM v,const SQChar *s)
-{
-
- SQChar *temp=sq_getscratchpad(v,((int)scstrlen(s)*6) + sizeof(SQChar));
- SQChar *dest=temp;
- while(*s!=_SC('\0')){
- int i=0;
- bool escaped=false;
- while(g_escapes[i].esc!=NULL){
- if(*s==g_escapes[i].c){
- scstrcpy(dest,g_escapes[i].esc);
- dest+=scstrlen(g_escapes[i].esc);
- escaped=true;
- break;
- }
- i++;
- }
- if(!escaped){*dest=*s;*dest++;}
- *s++;
- }
- *dest=_SC('\0');
- return temp;
-}
-
-SQDbgServer::SQDbgServer(HSQUIRRELVM v)
-{
- _ready = false;
- _nestedcalls = 0;
- _autoupdate = false;
- _v = v;
- _state = eDBG_Running;
- _accept = INVALID_SOCKET;
- _endpoint = INVALID_SOCKET;
- _maxrecursion = 10;
- sq_resetobject(&_debugroot);
-}
-
-SQDbgServer::~SQDbgServer()
-{
- sq_release(_v,&_debugroot);
- if(_accept != INVALID_SOCKET)
- sqdbg_closesocket(_accept);
- if(_endpoint != INVALID_SOCKET)
- sqdbg_closesocket(_endpoint);
-}
-
-bool SQDbgServer::Init()
-{
- //creates an environment table for the debugger
-
- sq_newtable(_v);
- sq_getstackobj(_v,-1,&_debugroot);
- sq_addref(_v,&_debugroot);
-
- //creates a emptyslot to store the watches
- sq_pushstring(_v,_SC("watches"),-1);
- sq_pushnull(_v);
- sq_createslot(_v,-3);
-
- sq_pushstring(_v,_SC("beginelement"),-1);
- sq_pushuserpointer(_v,this);
- sq_newclosure(_v,beginelement,1);
- sq_setparamscheck(_v,2,_SC(".s"));
- sq_createslot(_v,-3);
-
- sq_pushstring(_v,_SC("endelement"),-1);
- sq_pushuserpointer(_v,this);
- sq_newclosure(_v,endelement,1);
- sq_setparamscheck(_v,2,_SC(".s"));
- sq_createslot(_v,-3);
-
- sq_pushstring(_v,_SC("attribute"),-1);
- sq_pushuserpointer(_v,this);
- sq_newclosure(_v,attribute,1);
- sq_setparamscheck(_v,3,_SC(".ss"));
- sq_createslot(_v,-3);
-
- sq_pop(_v,1);
-
- //stores debug hook and error handler in the registry
- sq_pushregistrytable(_v);
-
- sq_pushstring(_v,SQDBG_DEBUG_HOOK,-1);
- sq_pushuserpointer(_v,this);
- sq_newclosure(_v,debug_hook,1);
- sq_createslot(_v,-3);
-
- sq_pushstring(_v,SQDBG_ERROR_HANDLER,-1);
- sq_pushuserpointer(_v,this);
- sq_newclosure(_v,error_handler,1);
- sq_createslot(_v,-3);
-
-
- sq_pop(_v,1);
-
- //sets the error handlers
- SetErrorHandlers();
- return true;
-}
-
-bool SQDbgServer::ReadMsg()
-{
- return false;
-}
-
-void SQDbgServer::BusyWait()
-{
- while( !ReadMsg() )
- sleep(0);
-}
-
-void SQDbgServer::SendChunk(const SQChar *chunk)
-{
- char *buf=NULL;
- int buf_len=0;
-#ifdef _UNICODE
- buf_len=(int)scstrlen(chunk)+1;
- buf=(char *)sq_getscratchpad(_v,(buf_len)*3);
- wcstombs((char *)buf,chunk,buf_len);
-#else
- buf_len=(int)scstrlen(chunk);
- buf=(char *)chunk;
-#endif
- send(_endpoint,(const char*)buf,(int)strlen((const char *)buf),0);
-}
-
-
-void SQDbgServer::Terminated()
-{
- BeginElement(_SC("terminated"));
- EndElement(_SC("terminated"));
- ::usleep(200);
-}
-
-void SQDbgServer::Hook(int type,int line,const SQChar *src,const SQChar *func)
-{
- switch(_state){
- case eDBG_Running:
- if(type==_SC('l') && _breakpoints.size()) {
- BreakPointSetItor itr = _breakpoints.find(BreakPoint(line,src));
- if(itr != _breakpoints.end()) {
- Break(line,src,_SC("breakpoint"));
- BreakExecution();
- }
- }
- break;
- case eDBG_Suspended:
- _nestedcalls=0;
- case eDBG_StepOver:
- switch(type){
- case _SC('l'):
- if(_nestedcalls==0) {
- Break(line,src,_SC("step"));
- BreakExecution();
- }
- break;
- case _SC('c'):
- _nestedcalls++;
- break;
- case _SC('r'):
- if(_nestedcalls==0){
- _nestedcalls=0;
-
- }else{
- _nestedcalls--;
- }
- break;
- }
- break;
- case eDBG_StepInto:
- switch(type){
- case _SC('l'):
- _nestedcalls=0;
- Break(line,src,_SC("step"));
- BreakExecution();
- break;
-
- }
- break;
- case eDBG_StepReturn:
- switch(type){
- case _SC('l'):
- break;
- case _SC('c'):
- _nestedcalls++;
- break;
- case _SC('r'):
- if(_nestedcalls==0){
- _nestedcalls=0;
- _state=eDBG_StepOver;
- }else{
- _nestedcalls--;
- }
-
- break;
- }
- break;
- case eDBG_Disabled:
- break;
- }
-}
-
-
-#define MSG_ID(x,y) ((y<<8)|x)
-//ab Add Breakpoint
-//rb Remove Breakpoint
-//sp Suspend
-void SQDbgServer::ParseMsg(const char *msg)
-{
-
- switch(*((unsigned short *)msg)){
- case MSG_ID('a','b'): {
- BreakPoint bp;
- if(ParseBreakpoint(msg+3,bp)){
- AddBreakpoint(bp);
- scprintf(_SC("added bp %d %s\n"),bp._line,bp._src.c_str());
- }
- else
- scprintf(_SC("error parsing add breakpoint"));
- }
- break;
- case MSG_ID('r','b'): {
- BreakPoint bp;
- if(ParseBreakpoint(msg+3,bp)){
- RemoveBreakpoint(bp);
- scprintf(_SC("removed bp %d %s\n"),bp._line,bp._src.c_str());
- }else
- scprintf(_SC("error parsing remove breakpoint"));
- }
- break;
- case MSG_ID('g','o'):
- if(_state!=eDBG_Running){
- _state=eDBG_Running;
- BeginDocument();
- BeginElement(_SC("resumed"));
- EndElement(_SC("resumed"));
- EndDocument();
-// Send(_SC("<resumed/>\r\n"));
- scprintf(_SC("go (execution resumed)\n"));
- }
- break;
- case MSG_ID('s','p'):
- if(_state!=eDBG_Suspended){
- _state=eDBG_Suspended;
- scprintf(_SC("suspend\n"));
- }
- break;
- case MSG_ID('s','o'):
- if(_state==eDBG_Suspended){
- _state=eDBG_StepOver;
- }
- break;
- case MSG_ID('s','i'):
- if(_state==eDBG_Suspended){
- _state=eDBG_StepInto;
- scprintf(_SC("step into\n"));
- }
- break;
- case MSG_ID('s','r'):
- if(_state==eDBG_Suspended){
- _state=eDBG_StepReturn;
- scprintf(_SC("step return\n"));
- }
- break;
- case MSG_ID('d','i'):
- if(_state!=eDBG_Disabled){
- _state=eDBG_Disabled;
- scprintf(_SC("disabled\n"));
- }
- break;
- case MSG_ID('a','w'): {
- Watch w;
- if(ParseWatch(msg+3,w))
- {
- AddWatch(w);
- scprintf(_SC("added watch %d %s\n"),w._id,w._exp.c_str());
- }
- else
- scprintf(_SC("error parsing add watch"));
- }
- break;
- case MSG_ID('r','w'): {
- int id;
- if(ParseRemoveWatch(msg+3,id))
- {
- RemoveWatch(id);
- scprintf(_SC("added watch %d\n"),id);
- }
- else
- scprintf(_SC("error parsing remove watch"));
- }
- break;
- case MSG_ID('t','r'):
- scprintf(_SC("terminate from user\n"));
- break;
- case MSG_ID('r','d'):
- scprintf(_SC("ready\n"));
- _ready=true;
- break;
- default:
- scprintf(_SC("unknown packet"));
-
- }
-}
-
-/*
- see copyright notice in sqrdbg.h
-*/
-bool SQDbgServer::ParseBreakpoint(const char *msg,BreakPoint &out)
-{
- static char stemp[MAX_BP_PATH];
- char *ep=NULL;
- out._line=strtoul(msg,&ep,16);
- if(ep==msg || (*ep)!=':')return false;
-
- char *dest=stemp;
- ep++;
- while((*ep)!='\n' && (*ep)!='\0')
- {
- *dest=*ep;
- *dest++;*ep++;
- }
- *dest='\0';
- *dest++;
- *dest='\0';
-#ifdef _UNICODE
- int len=(int)strlen(stemp);
- SQChar *p=sq_getscratchpad(_v,(SQInteger)(mbstowcs(NULL,stemp,len)+2)*sizeof(SQChar));
- size_t destlen=mbstowcs(p,stemp,len);
- p[destlen]=_SC('\0');
- out._src=p;
-#else
- out._src=stemp;
-#endif
- return true;
-}
-
-bool SQDbgServer::ParseWatch(const char *msg,Watch &out)
-{
- char *ep=NULL;
- out._id=strtoul(msg,&ep,16);
- if(ep==msg || (*ep)!=':')return false;
-
- //char *dest=out._src;
- ep++;
- while((*ep)!='\n' && (*ep)!='\0')
- {
- out._exp.append(1,*ep);
- *ep++;
- }
- return true;
-}
-
-bool SQDbgServer::ParseRemoveWatch(const char *msg,int &id)
-{
- char *ep=NULL;
- id=strtoul(msg,&ep,16);
- if(ep==msg)return false;
- return true;
-}
-
-
-void SQDbgServer::BreakExecution()
-{
- _state=eDBG_Suspended;
- while(_state==eDBG_Suspended){
- if(SQ_FAILED(sq_rdbg_update(this)))
- exit(0);
- usleep(10);
- }
-}
-
-//COMMANDS
-void SQDbgServer::AddBreakpoint(BreakPoint &bp)
-{
- _breakpoints.insert(bp);
- BeginDocument();
- BeginElement(_SC("addbreakpoint"));
- Attribute(_SC("line"),IntToString(bp._line));
- Attribute(_SC("src"),bp._src.c_str());
- EndElement(_SC("addbreakpoint"));
- EndDocument();
-}
-
-void SQDbgServer::AddWatch(Watch &w)
-{
- _watches.insert(w);
-}
-
-void SQDbgServer::RemoveWatch(int id)
-{
- WatchSetItor itor=_watches.find(Watch(id,_SC("")));
- if(itor==_watches.end()){
- BeginDocument();
- BeginElement(_SC("error"));
- Attribute(_SC("desc"),_SC("the watch does not exists"));
- EndElement(_SC("error"));
- EndDocument();
- }
- else{
- _watches.erase(itor);
- scprintf(_SC("removed watch %d\n"),id);
- }
-}
-
-void SQDbgServer::RemoveBreakpoint(BreakPoint &bp)
-{
- BreakPointSetItor itor=_breakpoints.find(bp);
- if(itor==_breakpoints.end()){
- BeginDocument();
- BeginElement(_SC("break"));
- Attribute(_SC("desc"),_SC("the breakpoint doesn't exists"));
- EndElement(_SC("break"));
- EndDocument();
- }
- else{
- BeginDocument();
- BeginElement(_SC("removebreakpoint"));
- Attribute(_SC("line"),IntToString(bp._line));
- Attribute(_SC("src"),bp._src.c_str());
- EndElement(_SC("removebreakpoint"));
- EndDocument();
- _breakpoints.erase(itor);
- }
-}
-
-void SQDbgServer::Break(int line,const SQChar *src,const SQChar *type,const SQChar *error)
-{
- if(!error){
- BeginDocument();
- BeginElement(_SC("break"));
- Attribute(_SC("line"),IntToString(line));
- Attribute(_SC("src"),src);
- Attribute(_SC("type"),type);
- SerializeState();
- EndElement(_SC("break"));
- EndDocument();
- }else{
- BeginDocument();
- BeginElement(_SC("break"));
- Attribute(_SC("line"),IntToString(line));
- Attribute(_SC("src"),src);
- Attribute(_SC("type"),type);
- Attribute(_SC("error"),error);
- SerializeState();
- EndElement(_SC("break"));
- EndDocument();
- }
-}
-
-void SQDbgServer::SerializeState()
-{
- sq_pushnull(_v);
- sq_setdebughook(_v);
- sq_pushnull(_v);
- sq_seterrorhandler(_v);
- const SQChar *sz;
- sq_pushobject(_v,_serializefunc);
- sq_pushobject(_v,_debugroot);
- sq_pushstring(_v,_SC("watches"),-1);
- sq_newtable(_v);
- for(WatchSetItor i=_watches.begin(); i!=_watches.end(); ++i)
- {
- sq_pushinteger(_v,i->_id);
- sq_pushstring(_v,i->_exp.c_str(),(int)i->_exp.length());
- sq_createslot(_v,-3);
- }
- sq_rawset(_v,-3);
- if(SQ_SUCCEEDED(sq_call(_v,1,SQTrue,SQTrue))){
- if(SQ_SUCCEEDED(sqstd_getblob(_v,-1,(SQUserPointer*)&sz)))
- SendChunk(sz);
- }
- sq_pop(_v,2);
-
- SetErrorHandlers();
-}
-
-
-void SQDbgServer::SetErrorHandlers()
-{
- sq_pushregistrytable(_v);
- sq_pushstring(_v,SQDBG_DEBUG_HOOK,-1);
- sq_rawget(_v,-2);
- sq_setdebughook(_v);
- sq_pushstring(_v,SQDBG_ERROR_HANDLER,-1);
- sq_rawget(_v,-2);
- sq_seterrorhandler(_v);
- sq_pop(_v,1);
-}
-
-void SQDbgServer::BeginElement(const SQChar *name)
-{
- _xmlcurrentement++;
- XMLElementState *self = &xmlstate[_xmlcurrentement];
- scstrcpy(self->name,name);
- self->haschildren = false;
- if(_xmlcurrentement > 0) {
- XMLElementState *parent = &xmlstate[_xmlcurrentement-1];
- if(!parent->haschildren) {
- SendChunk(_SC(">")); // closes the parent tag
- parent->haschildren = true;
- }
- }
- _scratchstring.resize(2+scstrlen(name));
- scsprintf(&_scratchstring[0],_SC("<%s"),name);
- SendChunk(&_scratchstring[0]);
-}
-
-void SQDbgServer::Attribute(const SQChar *name,const SQChar *value)
-{
- XMLElementState *self = &xmlstate[_xmlcurrentement];
- assert(!self->haschildren); //cannot have attributes if already has children
- const SQChar *escval = escape_xml(value);
- _scratchstring.resize(5+scstrlen(name)+scstrlen(escval));
- scsprintf(&_scratchstring[0],_SC(" %s=\"%s\""),name,escval);
- SendChunk(&_scratchstring[0]);
-}
-
-void SQDbgServer::EndElement(const SQChar *name)
-{
- XMLElementState *self = &xmlstate[_xmlcurrentement];
- assert(scstrcmp(self->name,name) == 0);
- if(self->haschildren) {
- _scratchstring.resize(4+scstrlen(name));
- scsprintf(&_scratchstring[0],_SC("</%s>"),name);
- SendChunk(&_scratchstring[0]);
-
- }
- else {
- SendChunk(_SC("/>"));
- }
- _xmlcurrentement--;
-}
-
-void SQDbgServer::EndDocument()
-{
- SendChunk(_SC("\r\n"));
-}
-
-//this can be done much better/faster(do we need that?)
-const SQChar *SQDbgServer::escape_xml(const SQChar *s)
-{
- SQChar *temp=sq_getscratchpad(_v,((int)scstrlen(s)*6) + sizeof(SQChar));
- SQChar *dest=temp;
- while(*s!=_SC('\0')){
- int i=0;
- bool escaped=false;
- while(g_escapes[i].esc!=NULL){
- if(*s==g_escapes[i].c){
- scstrcpy(dest,g_escapes[i].esc);
- dest+=scstrlen(g_escapes[i].esc);
- escaped=true;
- break;
- }
- i++;
- }
- if(!escaped){*dest=*s;*dest++;}
- *s++;
- }
- *dest=_SC('\0');
- return temp;
-
-}
+++ /dev/null
-#ifndef _SQ_DBGSERVER_H_
-#define _SQ_DBGSERVER_H_
-
-#define MAX_BP_PATH 512
-#define MAX_MSG_LEN 2049
-
-#include <set>
-#include <string>
-#include <vector>
-
-#ifdef _WIN32
-#include <winsock.h>
-#define sqdbg_closesocket(x) closesocket((x))
-typedef socklen_t int;
-#else
-#include <unistd.h>
-#include <errno.h>
-#include <sys/socket.h>
-#include <sys/types.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <netdb.h>
-#include <fcntl.h>
-
-#define sqdbg_closesocket(x) close((x))
-typedef int SOCKET;
-typedef struct timeval TIMEVAL;
-#define SOCKET_ERROR -1
-#define INVALID_SOCKET -1
-#endif
-
-typedef std::basic_string<SQChar> SQDBGString;
-
-inline bool dbg_less(const SQChar *x,const SQChar *y)
-{
- // [SuperTux] commented out to avoid compiler warning
- //int n = 0;
- do {
- int xl = *x == '\\' ? '/' : tolower(*x);
- int yl = *y == '\\' ? '/' : tolower(*y);
- int diff = xl - yl;
- if(diff != 0)
- return diff > 0?true:false;
- x++; y++;
- }while(*x != 0 && *y != 0);
- return false;
-}
-
-struct BreakPoint{
- BreakPoint(){_line=0;}
- BreakPoint(int line, const SQChar *src){ _line = line; _src = src; }
- BreakPoint(const BreakPoint& bp){ _line = bp._line; _src=bp._src; }
- inline bool operator<(const BreakPoint& bp) const
- {
- if(_line<bp._line)
- return true;
- if(_line==bp._line){
- return dbg_less(_src.c_str(),bp._src.c_str());
- }
- return false;
- }
-
- int _line;
- SQDBGString _src;
-};
-
-struct Watch{
- Watch() { _id = 0; }
- Watch(int id,const SQChar *exp) { _id = id; _exp = exp; }
- Watch(const Watch &w) { _id = w._id; _exp = w._exp; }
- bool operator<(const Watch& w) const { return _id<w._id; }
- bool operator==(const Watch& w) const { return _id == w._id; }
- int _id;
- SQDBGString _exp;
-};
-
-typedef std::set<BreakPoint> BreakPointSet;
-typedef BreakPointSet::iterator BreakPointSetItor;
-
-typedef std::set<Watch> WatchSet;
-typedef WatchSet::iterator WatchSetItor;
-
-typedef std::vector<SQChar> SQCharVec;
-struct SQDbgServer{
-public:
- enum eDbgState{
- eDBG_Running,
- eDBG_StepOver,
- eDBG_StepInto,
- eDBG_StepReturn,
- eDBG_Suspended,
- eDBG_Disabled,
- };
-
- SQDbgServer(HSQUIRRELVM v);
- ~SQDbgServer();
- bool Init();
- //returns true if a message has been received
- bool WaitForClient();
- bool ReadMsg();
- void BusyWait();
- void Hook(int type,int line,const SQChar *src,const SQChar *func);
- void ParseMsg(const char *msg);
- bool ParseBreakpoint(const char *msg,BreakPoint &out);
- bool ParseWatch(const char *msg,Watch &out);
- bool ParseRemoveWatch(const char *msg,int &id);
- void Terminated();
- //
- void BreakExecution();
- void Send(const SQChar *s,...);
- void SendChunk(const SQChar *chunk);
- void Break(int line,const SQChar *src,const SQChar *type,const SQChar *error=NULL);
-
-
- void SerializeState();
- //COMMANDS
- void AddBreakpoint(BreakPoint &bp);
- void AddWatch(Watch &w);
- void RemoveWatch(int id);
- void RemoveBreakpoint(BreakPoint &bp);
-
- //
- void SetErrorHandlers();
-
- //XML RELATED STUFF///////////////////////
- #define MAX_NESTING 10
- struct XMLElementState {
- SQChar name[256];
- bool haschildren;
- };
-
- XMLElementState xmlstate[MAX_NESTING];
- int _xmlcurrentement;
-
- void BeginDocument() { _xmlcurrentement = -1; }
- void BeginElement(const SQChar *name);
- void Attribute(const SQChar *name, const SQChar *value);
- void EndElement(const SQChar *name);
- void EndDocument();
-
- const SQChar *escape_xml(const SQChar *x);
- //////////////////////////////////////////////
- HSQUIRRELVM _v;
- HSQOBJECT _debugroot;
- eDbgState _state;
- SOCKET _accept;
- SOCKET _endpoint;
- BreakPointSet _breakpoints;
- WatchSet _watches;
- int _recursionlevel;
- int _maxrecursion;
- int _nestedcalls;
- bool _ready;
- bool _autoupdate;
- HSQOBJECT _serializefunc;
- SQCharVec _scratchstring;
-
-};
-
-#endif //_SQ_DBGSERVER_H_
+++ /dev/null
-/*
- see copyright notice in sqrdbg.h
-*/
-#include <squirrel.h>
-#include "sqrdbg.h"
-#include "sqdbgserver.h"
-SQInteger debug_hook(HSQUIRRELVM v);
-SQInteger error_handler(HSQUIRRELVM v);
-
-#include "serialize_state.inl"
-
-HSQREMOTEDBG sq_rdbg_init(HSQUIRRELVM v,unsigned short port,SQBool autoupdate)
-{
- sockaddr_in bindaddr;
-#ifdef _WIN32
- WSADATA wsadata;
- if (WSAStartup (MAKEWORD(1,1), &wsadata) != 0){
- return NULL;
- }
-#endif
-
- SQDbgServer *rdbg = new SQDbgServer(v);
- rdbg->_autoupdate = autoupdate?true:false;
- rdbg->_accept = socket(AF_INET,SOCK_STREAM,0);
- bindaddr.sin_family = AF_INET;
- bindaddr.sin_port = htons(port);
- bindaddr.sin_addr.s_addr = htonl (INADDR_ANY);
- if(bind(rdbg->_accept,(sockaddr*)&bindaddr,sizeof(bindaddr))==SOCKET_ERROR){
- delete rdbg;
- sq_throwerror(v,_SC("failed to bind the socket"));
- return NULL;
- }
- if(!rdbg->Init()) {
- delete rdbg;
- sq_throwerror(v,_SC("failed to initialize the debugger"));
- return NULL;
- }
-
- return rdbg;
-}
-
-SQRESULT sq_rdbg_waitforconnections(HSQREMOTEDBG rdbg)
-{
- if(SQ_FAILED(sq_compilebuffer(rdbg->_v,serialize_state_nut,(SQInteger)scstrlen(serialize_state_nut),_SC("SERIALIZE_STATE"),SQFalse))) {
- sq_throwerror(rdbg->_v,_SC("error compiling the serialization function"));
- }
- sq_getstackobj(rdbg->_v,-1,&rdbg->_serializefunc);
- sq_addref(rdbg->_v,&rdbg->_serializefunc);
- sq_pop(rdbg->_v,1);
-
- sockaddr_in cliaddr;
- socklen_t addrlen=sizeof(cliaddr);
- if(listen(rdbg->_accept,0)==SOCKET_ERROR)
- return sq_throwerror(rdbg->_v,_SC("error on listen(socket)"));
- rdbg->_endpoint = accept(rdbg->_accept,(sockaddr*)&cliaddr,&addrlen);
- //do not accept any other connection
- sqdbg_closesocket(rdbg->_accept);
- rdbg->_accept = INVALID_SOCKET;
- if(rdbg->_endpoint==INVALID_SOCKET){
- return sq_throwerror(rdbg->_v,_SC("error accept(socket)"));
- }
- while(!rdbg->_ready){
- sq_rdbg_update(rdbg);
- }
- return SQ_OK;
-}
-
-SQRESULT sq_rdbg_update(HSQREMOTEDBG rdbg)
-{
- TIMEVAL time;
- time.tv_sec=0;
- time.tv_usec=0;
- fd_set read_flags;
- FD_ZERO(&read_flags);
- FD_SET(rdbg->_endpoint, &read_flags);
- select(FD_SETSIZE, &read_flags, NULL, NULL, &time);
-
- if(FD_ISSET(rdbg->_endpoint,&read_flags)){
- char temp[1024];
- int size=0;
- char c,prev=0;
- memset(&temp,0,sizeof(temp));
- int res;
- FD_CLR(rdbg->_endpoint, &read_flags);
- while((res = recv(rdbg->_endpoint,&c,1,0))>0){
-
- if(c=='\n')break;
- if(c!='\r'){
- temp[size]=c;
- prev=c;
- size++;
- }
- }
- switch(res){
- case 0:
- return sq_throwerror(rdbg->_v,_SC("disconnected"));
- case SOCKET_ERROR:
- return sq_throwerror(rdbg->_v,_SC("socket error"));
- }
-
- temp[size]=0;
- temp[size+1]=0;
- rdbg->ParseMsg(temp);
- }
- return SQ_OK;
-}
-
-SQInteger debug_hook(HSQUIRRELVM v)
-{
- SQUserPointer up;
- SQInteger event_type,line;
- const SQChar *src,*func;
- sq_getinteger(v,2,&event_type);
- sq_getstring(v,3,&src);
- sq_getinteger(v,4,&line);
- sq_getstring(v,5,&func);
- sq_getuserpointer(v,-1,&up);
- HSQREMOTEDBG rdbg = (HSQREMOTEDBG)up;
- rdbg->Hook(event_type,line,src,func);
- if(rdbg->_autoupdate) {
- if(SQ_FAILED(sq_rdbg_update(rdbg)))
- return sq_throwerror(v,_SC("socket failed"));
- }
- return 0;
-}
-
-SQInteger error_handler(HSQUIRRELVM v)
-{
- SQUserPointer up;
- const SQChar *sErr=NULL;
- const SQChar *fn=_SC("unknown");
- const SQChar *src=_SC("unknown");
- int line=-1;
- SQStackInfos si;
- sq_getuserpointer(v,-1,&up);
- HSQREMOTEDBG rdbg=(HSQREMOTEDBG)up;
- if(SQ_SUCCEEDED(sq_stackinfos(v,1,&si)))
- {
- if(si.funcname)fn=si.funcname;
- if(si.source)src=si.source;
- line=si.line;
- scprintf(_SC("*FUNCTION [%s] %s line [%d]\n"),fn,src,si.line);
- }
- if(sq_gettop(v)>=1){
- if(SQ_SUCCEEDED(sq_getstring(v,2,&sErr))) {
- scprintf(_SC("\nAN ERROR HAS OCCURED [%s]\n"),sErr);
- rdbg->Break(si.line,src,_SC("error"),sErr);
- }
- else{
- scprintf(_SC("\nAN ERROR HAS OCCURED [unknown]\n"));
- rdbg->Break(si.line,src,_SC("error"),_SC("unknown"));
- }
- }
- rdbg->BreakExecution();
- return 0;
-}
-
-
-SQRESULT sq_rdbg_shutdown(HSQREMOTEDBG rdbg)
-{
- delete rdbg;
-#ifdef _WIN32
- WSACleanup();
-#endif
- return SQ_OK;
-}
+++ /dev/null
-/*
-Copyright (c) 2003-2005 Alberto Demichelis
-
-This software is provided 'as-is', without any
-express or implied warranty. In no event will the
-authors be held liable for any damages arising from
-the use of this software.
-
-Permission is granted to anyone to use this software
-for any purpose, including commercial applications,
-and to alter it and redistribute it freely, subject
-to the following restrictions:
-
- 1. The origin of this software must not be
- misrepresented; you must not claim that
- you wrote the original software. If you
- use this software in a product, an
- acknowledgment in the product
- documentation would be appreciated but is
- not required.
-
- 2. Altered source versions must be plainly
- marked as such, and must not be
- misrepresented as being the original
- software.
-
- 3. This notice may not be removed or
- altered from any source distribution.
-
-*/
-#ifndef _SQ_RDBG_H_
-#define _SQ_RDBG_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct SQDbgServer;
-typedef SQDbgServer* HSQREMOTEDBG;
-
-HSQREMOTEDBG sq_rdbg_init(HSQUIRRELVM v,unsigned short port,SQBool autoupdate);
-SQRESULT sq_rdbg_waitforconnections(HSQREMOTEDBG rdbg);
-SQRESULT sq_rdbg_shutdown(HSQREMOTEDBG rdbg);
-SQRESULT sq_rdbg_update(HSQREMOTEDBG rdbg);
-
-#ifdef __cplusplus
-} /*extern "C"*/
-#endif
-
-#endif //_SQ_RDBG_H_
+++ /dev/null
-/* see copyright notice in squirrel.h */
-#include <squirrel.h>
-#include <sqstdaux.h>
-#include <assert.h>
-
-void sqstd_printcallstack(HSQUIRRELVM v)
-{
- SQPRINTFUNCTION pf = sq_getprintfunc(v);
- if(pf) {
- SQStackInfos si;
- SQInteger i;
- SQFloat f;
- const SQChar *s;
- SQInteger level=1; //1 is to skip this function that is level 0
- const SQChar *name=0;
- SQInteger seq=0;
- pf(v,_SC("\nCALLSTACK\n"));
- while(SQ_SUCCEEDED(sq_stackinfos(v,level,&si)))
- {
- const SQChar *fn=_SC("unknown");
- const SQChar *src=_SC("unknown");
- if(si.funcname)fn=si.funcname;
- if(si.source)src=si.source;
- pf(v,_SC("*FUNCTION [%s()] %s line [%d]\n"),fn,src,si.line);
- level++;
- }
- level=0;
- pf(v,_SC("\nLOCALS\n"));
-
- for(level=0;level<10;level++){
- seq=0;
- while((name = sq_getlocal(v,level,seq)))
- {
- seq++;
- switch(sq_gettype(v,-1))
- {
- case OT_NULL:
- pf(v,_SC("[%s] NULL\n"),name);
- break;
- case OT_INTEGER:
- sq_getinteger(v,-1,&i);
- pf(v,_SC("[%s] %d\n"),name,i);
- break;
- case OT_FLOAT:
- sq_getfloat(v,-1,&f);
- pf(v,_SC("[%s] %.14g\n"),name,f);
- break;
- case OT_USERPOINTER:
- pf(v,_SC("[%s] USERPOINTER\n"),name);
- break;
- case OT_STRING:
- sq_getstring(v,-1,&s);
- pf(v,_SC("[%s] \"%s\"\n"),name,s);
- break;
- case OT_TABLE:
- pf(v,_SC("[%s] TABLE\n"),name);
- break;
- case OT_ARRAY:
- pf(v,_SC("[%s] ARRAY\n"),name);
- break;
- case OT_CLOSURE:
- pf(v,_SC("[%s] CLOSURE\n"),name);
- break;
- case OT_NATIVECLOSURE:
- pf(v,_SC("[%s] NATIVECLOSURE\n"),name);
- break;
- case OT_GENERATOR:
- pf(v,_SC("[%s] NATIVECLOSURE\n"),name);
- break;
- case OT_USERDATA:
- pf(v,_SC("[%s] USERDATA\n"),name);
- break;
- case OT_THREAD:
- pf(v,_SC("[%s] THREAD\n"),name);
- break;
- case OT_CLASS:
- pf(v,_SC("[%s] CLASS\n"),name);
- break;
- case OT_INSTANCE:
- pf(v,_SC("[%s] INSTANCE\n"),name);
- break;
- case OT_WEAKREF:
- pf(v,_SC("[%s] WEAKREF\n"),name);
- break;
- case OT_BOOL:{
- sq_getinteger(v,-1,&i);
- pf(v,_SC("[%s] %s\n"),name,i?_SC("true"):_SC("false"));
- }
- break;
- default: assert(0); break;
- }
- sq_pop(v,1);
- }
- }
- }
-}
-
-static SQInteger _sqstd_aux_printerror(HSQUIRRELVM v)
-{
- SQPRINTFUNCTION pf = sq_getprintfunc(v);
- if(pf) {
- const SQChar *sErr = 0;
- if(sq_gettop(v)>=1) {
- if(SQ_SUCCEEDED(sq_getstring(v,2,&sErr))) {
- pf(v,_SC("\nAN ERROR HAS OCCURED [%s]\n"),sErr);
- }
- else{
- pf(v,_SC("\nAN ERROR HAS OCCURED [unknown]\n"));
- }
- sqstd_printcallstack(v);
- }
- }
- return 0;
-}
-
-void _sqstd_compiler_error(HSQUIRRELVM v,const SQChar *sErr,const SQChar *sSource,SQInteger line,SQInteger column)
-{
- SQPRINTFUNCTION pf = sq_getprintfunc(v);
- if(pf) {
- pf(v,_SC("%s line = (%d) column = (%d) : error %s\n"),sSource,line,column,sErr);
- }
-}
-
-void sqstd_seterrorhandlers(HSQUIRRELVM v)
-{
- sq_setcompilererrorhandler(v,_sqstd_compiler_error);
- sq_newclosure(v,_sqstd_aux_printerror,0);
- sq_seterrorhandler(v);
-}
+++ /dev/null
-/* see copyright notice in squirrel.h */
-#include <new>
-#include <squirrel.h>
-#include <sqstdio.h>
-#include <string.h>
-#include <sqstdblob.h>
-#include "sqstdstream.h"
-#include "sqstdblobimpl.h"
-
-#define SQSTD_BLOB_TYPE_TAG (SQSTD_STREAM_TYPE_TAG | 0x00000002)
-
-//Blob
-
-
-#define SETUP_BLOB(v) \
- SQBlob *self = NULL; \
- { if(SQ_FAILED(sq_getinstanceup(v,1,(SQUserPointer*)&self,(SQUserPointer)SQSTD_BLOB_TYPE_TAG))) \
- return SQ_ERROR; }
-
-
-static SQInteger _blob_resize(HSQUIRRELVM v)
-{
- SETUP_BLOB(v);
- SQInteger size;
- sq_getinteger(v,2,&size);
- if(!self->Resize(size))
- return sq_throwerror(v,_SC("resize failed"));
- return 0;
-}
-
-static void __swap_dword(unsigned int *n)
-{
- *n=(unsigned int)(((*n&0xFF000000)>>24) |
- ((*n&0x00FF0000)>>8) |
- ((*n&0x0000FF00)<<8) |
- ((*n&0x000000FF)<<24));
-}
-
-static void __swap_word(unsigned short *n)
-{
- *n=(unsigned short)((*n>>8)&0x00FF)| ((*n<<8)&0xFF00);
-}
-
-static SQInteger _blob_swap4(HSQUIRRELVM v)
-{
- SETUP_BLOB(v);
- SQInteger num=(self->Len()-(self->Len()%4))>>2;
- unsigned int *t=(unsigned int *)self->GetBuf();
- for(SQInteger i = 0; i < num; i++) {
- __swap_dword(&t[i]);
- }
- return 0;
-}
-
-static SQInteger _blob_swap2(HSQUIRRELVM v)
-{
- SETUP_BLOB(v);
- SQInteger num=(self->Len()-(self->Len()%2))>>1;
- unsigned short *t = (unsigned short *)self->GetBuf();
- for(SQInteger i = 0; i < num; i++) {
- __swap_word(&t[i]);
- }
- return 0;
-}
-
-static SQInteger _blob__set(HSQUIRRELVM v)
-{
- SETUP_BLOB(v);
- SQInteger idx,val;
- sq_getinteger(v,2,&idx);
- sq_getinteger(v,3,&val);
- if(idx < 0 || idx >= self->Len())
- return sq_throwerror(v,_SC("index out of range"));
- ((unsigned char *)self->GetBuf())[idx] = (unsigned char) val;
- sq_push(v,3);
- return 1;
-}
-
-static SQInteger _blob__get(HSQUIRRELVM v)
-{
- SETUP_BLOB(v);
- SQInteger idx;
- sq_getinteger(v,2,&idx);
- if(idx < 0 || idx >= self->Len())
- return sq_throwerror(v,_SC("index out of range"));
- sq_pushinteger(v,((unsigned char *)self->GetBuf())[idx]);
- return 1;
-}
-
-static SQInteger _blob__nexti(HSQUIRRELVM v)
-{
- SETUP_BLOB(v);
- if(sq_gettype(v,2) == OT_NULL) {
- sq_pushinteger(v, 0);
- return 1;
- }
- SQInteger idx;
- if(SQ_SUCCEEDED(sq_getinteger(v, 2, &idx))) {
- if(idx+1 < self->Len()) {
- sq_pushinteger(v, idx+1);
- return 1;
- }
- sq_pushnull(v);
- return 1;
- }
- return sq_throwerror(v,_SC("internal error (_nexti) wrong argument type"));
-}
-
-static SQInteger _blob__typeof(HSQUIRRELVM v)
-{
- sq_pushstring(v,_SC("blob"),-1);
- return 1;
-}
-
-static SQInteger _blob_releasehook(SQUserPointer p, SQInteger size)
-{
- SQBlob *self = (SQBlob*)p;
- delete self;
- return 1;
-}
-
-static SQInteger _blob_constructor(HSQUIRRELVM v)
-{
- SQInteger nparam = sq_gettop(v);
- SQInteger size = 0;
- if(nparam == 2) {
- sq_getinteger(v, 2, &size);
- }
- if(size < 0) return sq_throwerror(v, _SC("cannot create blob with negative size"));
- SQBlob *b = new SQBlob(size);
- if(SQ_FAILED(sq_setinstanceup(v,1,b))) {
- delete b;
- return sq_throwerror(v, _SC("cannot create blob with negative size"));
- }
- sq_setreleasehook(v,1,_blob_releasehook);
- return 0;
-}
-
-#define _DECL_BLOB_FUNC(name,nparams,typecheck) {_SC(#name),_blob_##name,nparams,typecheck}
-static SQRegFunction _blob_methods[] = {
- _DECL_BLOB_FUNC(constructor,-1,_SC("xn")),
- _DECL_BLOB_FUNC(resize,2,_SC("xn")),
- _DECL_BLOB_FUNC(swap2,1,_SC("x")),
- _DECL_BLOB_FUNC(swap4,1,_SC("x")),
- _DECL_BLOB_FUNC(_set,3,_SC("xnn")),
- _DECL_BLOB_FUNC(_get,2,_SC("xn")),
- _DECL_BLOB_FUNC(_typeof,1,_SC("x")),
- _DECL_BLOB_FUNC(_nexti,2,_SC("x")),
- {0,0,0,0}
-};
-
-
-
-//GLOBAL FUNCTIONS
-
-static SQInteger _g_blob_casti2f(HSQUIRRELVM v)
-{
- SQInteger i;
- sq_getinteger(v,2,&i);
- sq_pushfloat(v,*((SQFloat *)&i));
- return 1;
-}
-
-static SQInteger _g_blob_castf2i(HSQUIRRELVM v)
-{
- SQFloat f;
- sq_getfloat(v,2,&f);
- sq_pushinteger(v,*((SQInteger *)&f));
- return 1;
-}
-
-static SQInteger _g_blob_swap2(HSQUIRRELVM v)
-{
- SQInteger i;
- sq_getinteger(v,2,&i);
- short s=(short)i;
- sq_pushinteger(v,(s<<8)|((s>>8)&0x00FF));
- return 1;
-}
-
-static SQInteger _g_blob_swap4(HSQUIRRELVM v)
-{
- SQInteger i;
- sq_getinteger(v,2,&i);
- unsigned int t4 = (unsigned int)i;
- __swap_dword(&t4);
- sq_pushinteger(v,(SQInteger)t4);
- return 1;
-}
-
-static SQInteger _g_blob_swapfloat(HSQUIRRELVM v)
-{
- SQFloat f;
- sq_getfloat(v,2,&f);
- __swap_dword((unsigned int *)&f);
- sq_pushfloat(v,f);
- return 1;
-}
-
-#define _DECL_GLOBALBLOB_FUNC(name,nparams,typecheck) {_SC(#name),_g_blob_##name,nparams,typecheck}
-static SQRegFunction bloblib_funcs[]={
- _DECL_GLOBALBLOB_FUNC(casti2f,2,_SC(".n")),
- _DECL_GLOBALBLOB_FUNC(castf2i,2,_SC(".n")),
- _DECL_GLOBALBLOB_FUNC(swap2,2,_SC(".n")),
- _DECL_GLOBALBLOB_FUNC(swap4,2,_SC(".n")),
- _DECL_GLOBALBLOB_FUNC(swapfloat,2,_SC(".n")),
- {0,0}
-};
-
-SQRESULT sqstd_getblob(HSQUIRRELVM v,SQInteger idx,SQUserPointer *ptr)
-{
- SQBlob *blob;
- if(SQ_FAILED(sq_getinstanceup(v,idx,(SQUserPointer *)&blob,(SQUserPointer)SQSTD_BLOB_TYPE_TAG)))
- return -1;
- *ptr = blob->GetBuf();
- return SQ_OK;
-}
-
-SQInteger sqstd_getblobsize(HSQUIRRELVM v,SQInteger idx)
-{
- SQBlob *blob;
- if(SQ_FAILED(sq_getinstanceup(v,idx,(SQUserPointer *)&blob,(SQUserPointer)SQSTD_BLOB_TYPE_TAG)))
- return -1;
- return blob->Len();
-}
-
-SQUserPointer sqstd_createblob(HSQUIRRELVM v, SQInteger size)
-{
- SQInteger top = sq_gettop(v);
- sq_pushregistrytable(v);
- sq_pushstring(v,_SC("std_blob"),-1);
- if(SQ_SUCCEEDED(sq_get(v,-2))) {
- sq_remove(v,-2); //removes the registry
- sq_push(v,1); // push the this
- sq_pushinteger(v,size); //size
- SQBlob *blob = NULL;
- if(SQ_SUCCEEDED(sq_call(v,2,SQTrue,SQFalse))
- && SQ_SUCCEEDED(sq_getinstanceup(v,-1,(SQUserPointer *)&blob,(SQUserPointer)SQSTD_BLOB_TYPE_TAG))) {
- sq_remove(v,-2);
- return blob->GetBuf();
- }
- }
- sq_settop(v,top);
- return NULL;
-}
-
-SQRESULT sqstd_register_bloblib(HSQUIRRELVM v)
-{
- return declare_stream(v,_SC("blob"),(SQUserPointer)SQSTD_BLOB_TYPE_TAG,_SC("std_blob"),_blob_methods,bloblib_funcs);
-}
-
+++ /dev/null
-/* see copyright notice in squirrel.h */
-#ifndef _SQSTD_BLOBIMPL_H_
-#define _SQSTD_BLOBIMPL_H_
-
-struct SQBlob : public SQStream
-{
- SQBlob(SQInteger size) {
- _size = size;
- _allocated = size;
- _buf = (unsigned char *)sq_malloc(size);
- memset(_buf, 0, _size);
- _ptr = 0;
- _owns = true;
- }
- virtual ~SQBlob() {
- sq_free(_buf, _allocated);
- }
- SQInteger Write(void *buffer, SQInteger size) {
- if(!CanAdvance(size)) {
- GrowBufOf(_ptr + size - _size);
- }
- memcpy(&_buf[_ptr], buffer, size);
- _ptr += size;
- return size;
- }
- SQInteger Read(void *buffer,SQInteger size) {
- SQInteger n = size;
- if(!CanAdvance(size)) {
- if((_size - _ptr) > 0)
- n = _size - _ptr;
- else return 0;
- }
- memcpy(buffer, &_buf[_ptr], n);
- _ptr += n;
- return n;
- }
- bool Resize(SQInteger n) {
- if(!_owns) return false;
- if(n != _allocated) {
- unsigned char *newbuf = (unsigned char *)sq_malloc(n);
- memset(newbuf,0,n);
- if(_size > n)
- memcpy(newbuf,_buf,n);
- else
- memcpy(newbuf,_buf,_size);
- sq_free(_buf,_allocated);
- _buf=newbuf;
- _allocated = n;
- if(_size > _allocated)
- _size = _allocated;
- if(_ptr > _allocated)
- _ptr = _allocated;
- }
- return true;
- }
- bool GrowBufOf(SQInteger n)
- {
- bool ret = true;
- if(_size + n > _allocated) {
- if(_size + n > _size * 2)
- ret = Resize(_size + n);
- else
- ret = Resize(_size * 2);
- }
- _size = _size + n;
- return ret;
- }
- bool CanAdvance(SQInteger n) {
- if(_ptr+n>_size)return false;
- return true;
- }
- SQInteger Seek(SQInteger offset, SQInteger origin) {
- switch(origin) {
- case SQ_SEEK_SET:
- if(offset > _size || offset < 0) return -1;
- _ptr = offset;
- break;
- case SQ_SEEK_CUR:
- if(_ptr + offset > _size || _ptr + offset < 0) return -1;
- _ptr += offset;
- break;
- case SQ_SEEK_END:
- if(_size + offset > _size || _size + offset < 0) return -1;
- _ptr = _size + offset;
- break;
- default: return -1;
- }
- return 0;
- }
- bool IsValid() {
- return _buf?true:false;
- }
- bool EOS() {
- return _ptr == _size;
- }
- SQInteger Flush() { return 0; }
- SQInteger Tell() { return _ptr; }
- SQInteger Len() { return _size; }
- SQUserPointer GetBuf(){ return _buf; }
-private:
- SQInteger _size;
- SQInteger _allocated;
- SQInteger _ptr;
- unsigned char *_buf;
- bool _owns;
-};
-
-#endif //_SQSTD_BLOBIMPL_H_
+++ /dev/null
-/* see copyright notice in squirrel.h */
-#include <new>
-#include <stdio.h>
-#include <squirrel.h>
-#include <sqstdio.h>
-#include "sqstdstream.h"
-
-#define SQSTD_FILE_TYPE_TAG (SQSTD_STREAM_TYPE_TAG | 0x00000001)
-//basic API
-SQFILE sqstd_fopen(const SQChar *filename ,const SQChar *mode)
-{
-#ifndef _UNICODE
- return (SQFILE)fopen(filename,mode);
-#else
- return (SQFILE)_wfopen(filename,mode);
-#endif
-}
-
-SQInteger sqstd_fread(void* buffer, SQInteger size, SQInteger count, SQFILE file)
-{
- return (SQInteger)fread(buffer,size,count,(FILE *)file);
-}
-
-SQInteger sqstd_fwrite(const SQUserPointer buffer, SQInteger size, SQInteger count, SQFILE file)
-{
- return (SQInteger)fwrite(buffer,size,count,(FILE *)file);
-}
-
-SQInteger sqstd_fseek(SQFILE file, SQInteger offset, SQInteger origin)
-{
- SQInteger realorigin;
- switch(origin) {
- case SQ_SEEK_CUR: realorigin = SEEK_CUR; break;
- case SQ_SEEK_END: realorigin = SEEK_END; break;
- case SQ_SEEK_SET: realorigin = SEEK_SET; break;
- default: return -1; //failed
- }
- return fseek((FILE *)file,(long)offset,(int)realorigin);
-}
-
-SQInteger sqstd_ftell(SQFILE file)
-{
- return ftell((FILE *)file);
-}
-
-SQInteger sqstd_fflush(SQFILE file)
-{
- return fflush((FILE *)file);
-}
-
-SQInteger sqstd_fclose(SQFILE file)
-{
- return fclose((FILE *)file);
-}
-
-SQInteger sqstd_feof(SQFILE file)
-{
- return feof((FILE *)file);
-}
-
-//File
-struct SQFile : public SQStream {
- SQFile() { _handle = NULL; _owns = false;}
- SQFile(SQFILE file, bool owns) { _handle = file; _owns = owns;}
- virtual ~SQFile() { Close(); }
- bool Open(const SQChar *filename ,const SQChar *mode) {
- Close();
- if( (_handle = sqstd_fopen(filename,mode)) ) {
- _owns = true;
- return true;
- }
- return false;
- }
- void Close() {
- if(_handle && _owns) {
- sqstd_fclose(_handle);
- _handle = NULL;
- _owns = false;
- }
- }
- SQInteger Read(void *buffer,SQInteger size) {
- return sqstd_fread(buffer,1,size,_handle);
- }
- SQInteger Write(void *buffer,SQInteger size) {
- return sqstd_fwrite(buffer,1,size,_handle);
- }
- SQInteger Flush() {
- return sqstd_fflush(_handle);
- }
- SQInteger Tell() {
- return sqstd_ftell(_handle);
- }
- SQInteger Len() {
- SQInteger prevpos=Tell();
- Seek(0,SQ_SEEK_END);
- SQInteger size=Tell();
- Seek(prevpos,SQ_SEEK_SET);
- return size;
- }
- SQInteger Seek(SQInteger offset, SQInteger origin) {
- return sqstd_fseek(_handle,offset,origin);
- }
- bool IsValid() { return _handle?true:false; }
- bool EOS() { return Tell()==Len()?true:false;}
- SQFILE GetHandle() {return _handle;}
-private:
- SQFILE _handle;
- bool _owns;
-};
-
-static SQInteger _file__typeof(HSQUIRRELVM v)
-{
- sq_pushstring(v,_SC("file"),-1);
- return 1;
-}
-
-static SQInteger _file_releasehook(SQUserPointer p, SQInteger size)
-{
- SQFile *self = (SQFile*)p;
- delete self;
- return 1;
-}
-
-static SQInteger _file_constructor(HSQUIRRELVM v)
-{
- const SQChar *filename,*mode;
- bool owns = true;
- SQFile *f;
- SQFILE newf;
- if(sq_gettype(v,2) == OT_STRING && sq_gettype(v,3) == OT_STRING) {
- sq_getstring(v, 2, &filename);
- sq_getstring(v, 3, &mode);
- newf = sqstd_fopen(filename, mode);
- if(!newf) return sq_throwerror(v, _SC("cannot open file"));
- } else if(sq_gettype(v,2) == OT_USERPOINTER) {
- owns = !(sq_gettype(v,3) == OT_NULL);
- sq_getuserpointer(v,2,&newf);
- } else {
- return sq_throwerror(v,_SC("wrong parameter"));
- }
- f = new SQFile(newf,owns);
- if(SQ_FAILED(sq_setinstanceup(v,1,f))) {
- delete f;
- return sq_throwerror(v, _SC("cannot create blob with negative size"));
- }
- sq_setreleasehook(v,1,_file_releasehook);
- return 0;
-}
-
-//bindings
-#define _DECL_FILE_FUNC(name,nparams,typecheck) {_SC(#name),_file_##name,nparams,typecheck}
-static SQRegFunction _file_methods[] = {
- _DECL_FILE_FUNC(constructor,3,_SC("x")),
- _DECL_FILE_FUNC(_typeof,1,_SC("x")),
- {0,0,0,0},
-};
-
-
-
-SQRESULT sqstd_createfile(HSQUIRRELVM v, SQFILE file,SQBool own)
-{
- SQInteger top = sq_gettop(v);
- sq_pushregistrytable(v);
- sq_pushstring(v,_SC("std_file"),-1);
- if(SQ_SUCCEEDED(sq_get(v,-2))) {
- sq_remove(v,-2); //removes the registry
- sq_pushroottable(v); // push the this
- sq_pushuserpointer(v,file); //file
- if(own){
- sq_pushinteger(v,1); //true
- }
- else{
- sq_pushnull(v); //false
- }
- if(SQ_SUCCEEDED( sq_call(v,3,SQTrue,SQFalse) )) {
- sq_remove(v,-2);
- return SQ_OK;
- }
- }
- sq_settop(v,top);
- return SQ_OK;
-}
-
-SQRESULT sqstd_getfile(HSQUIRRELVM v, SQInteger idx, SQFILE *file)
-{
- SQFile *fileobj = NULL;
- if(SQ_SUCCEEDED(sq_getinstanceup(v,idx,(SQUserPointer*)&fileobj,(SQUserPointer)SQSTD_FILE_TYPE_TAG))) {
- *file = fileobj->GetHandle();
- return SQ_OK;
- }
- return sq_throwerror(v,_SC("not a file"));
-}
-
-
-
-static SQInteger _io_file_lexfeed_ASCII(SQUserPointer file)
-{
- SQInteger ret;
- char c;
- if( ( ret=sqstd_fread(&c,sizeof(c),1,(FILE *)file )>0) )
- return c;
- return 0;
-}
-
-static SQInteger _io_file_lexfeed_UTF8(SQUserPointer file)
-{
-#define READ() \
- if(sqstd_fread(&inchar,sizeof(inchar),1,(FILE *)file) != 1) \
- return 0;
-
- static const SQInteger utf8_lengths[16] =
- {
- 1,1,1,1,1,1,1,1, /* 0000 to 0111 : 1 byte (plain ASCII) */
- 0,0,0,0, /* 1000 to 1011 : not valid */
- 2,2, /* 1100, 1101 : 2 bytes */
- 3, /* 1110 : 3 bytes */
- 4 /* 1111 :4 bytes */
- };
- static unsigned char byte_masks[5] = {0,0,0x1f,0x0f,0x07};
- unsigned char inchar;
- SQInteger c = 0;
- READ();
- c = inchar;
- //
- if(c >= 0x80) {
- SQInteger tmp;
- SQInteger codelen = utf8_lengths[c>>4];
- if(codelen == 0)
- return 0;
- //"invalid UTF-8 stream";
- tmp = c&byte_masks[codelen];
- for(SQInteger n = 0; n < codelen-1; n++) {
- tmp<<=6;
- READ();
- tmp |= inchar & 0x3F;
- }
- c = tmp;
- }
- return c;
-}
-
-static SQInteger _io_file_lexfeed_UCS2_LE(SQUserPointer file)
-{
- SQInteger ret;
- wchar_t c;
- if( ( ret=sqstd_fread(&c,sizeof(c),1,(FILE *)file )>0) )
- return (SQChar)c;
- return 0;
-}
-
-static SQInteger _io_file_lexfeed_UCS2_BE(SQUserPointer file)
-{
- SQInteger ret;
- unsigned short c;
- if( ( ret=sqstd_fread(&c,sizeof(c),1,(FILE *)file )>0) ) {
- c = ((c>>8)&0x00FF)| ((c<<8)&0xFF00);
- return (SQChar)c;
- }
- return 0;
-}
-
-SQInteger file_read(SQUserPointer file,SQUserPointer buf,SQInteger size)
-{
- SQInteger ret;
- if( ( ret = sqstd_fread(buf,1,size,(SQFILE)file ))!=0 )return ret;
- return -1;
-}
-
-SQInteger file_write(SQUserPointer file,SQUserPointer p,SQInteger size)
-{
- return sqstd_fwrite(p,1,size,(SQFILE)file);
-}
-
-SQRESULT sqstd_loadfile(HSQUIRRELVM v,const SQChar *filename,SQBool printerror)
-{
- SQFILE file = sqstd_fopen(filename,_SC("rb"));
- SQInteger ret;
- unsigned short us;
- unsigned char uc;
- SQLEXREADFUNC func = _io_file_lexfeed_ASCII;
- if(file){
- ret = sqstd_fread(&us,1,2,file);
- if(ret != 2) {
- //probably an empty file
- us = 0;
- }
- if(us == SQ_BYTECODE_STREAM_TAG) { //BYTECODE
- sqstd_fseek(file,0,SQ_SEEK_SET);
- if(SQ_SUCCEEDED(sq_readclosure(v,file_read,file))) {
- sqstd_fclose(file);
- return SQ_OK;
- }
- }
- else { //SCRIPT
- switch(us)
- {
- //gotta swap the next 2 lines on BIG endian machines
- case 0xFFFE: func = _io_file_lexfeed_UCS2_BE; break;//UTF-16 little endian;
- case 0xFEFF: func = _io_file_lexfeed_UCS2_LE; break;//UTF-16 big endian;
- case 0xBBEF:
- if(sqstd_fread(&uc,1,sizeof(uc),file) == 0) {
- sqstd_fclose(file);
- return sq_throwerror(v,_SC("io error"));
- }
- if(uc != 0xBF) {
- sqstd_fclose(file);
- return sq_throwerror(v,_SC("Unrecognozed ecoding"));
- }
- func = _io_file_lexfeed_UTF8;
- break;//UTF-8 ;
- default: sqstd_fseek(file,0,SQ_SEEK_SET); break; // ascii
- }
-
- if(SQ_SUCCEEDED(sq_compile(v,func,file,filename,printerror))){
- sqstd_fclose(file);
- return SQ_OK;
- }
- }
- sqstd_fclose(file);
- return SQ_ERROR;
- }
- return sq_throwerror(v,_SC("cannot open the file"));
-}
-
-SQRESULT sqstd_dofile(HSQUIRRELVM v,const SQChar *filename,SQBool retval,SQBool printerror)
-{
- if(SQ_SUCCEEDED(sqstd_loadfile(v,filename,printerror))) {
- sq_push(v,-2);
- if(SQ_SUCCEEDED(sq_call(v,1,retval,SQTrue))) {
- sq_remove(v,retval?-2:-1); //removes the closure
- return 1;
- }
- sq_pop(v,1); //removes the closure
- }
- return SQ_ERROR;
-}
-
-SQRESULT sqstd_writeclosuretofile(HSQUIRRELVM v,const SQChar *filename)
-{
- SQFILE file = sqstd_fopen(filename,_SC("wb+"));
- if(!file) return sq_throwerror(v,_SC("cannot open the file"));
- if(SQ_SUCCEEDED(sq_writeclosure(v,file_write,file))) {
- sqstd_fclose(file);
- return SQ_OK;
- }
- sqstd_fclose(file);
- return SQ_ERROR; //forward the error
-}
-
-SQInteger _g_io_loadfile(HSQUIRRELVM v)
-{
- const SQChar *filename;
- SQBool printerror = SQFalse;
- sq_getstring(v,2,&filename);
- if(sq_gettop(v) >= 3) {
- sq_getbool(v,3,&printerror);
- }
- if(SQ_SUCCEEDED(sqstd_loadfile(v,filename,printerror)))
- return 1;
- return SQ_ERROR; //propagates the error
-}
-
-SQInteger _g_io_writeclosuretofile(HSQUIRRELVM v)
-{
- const SQChar *filename;
- sq_getstring(v,2,&filename);
- if(SQ_SUCCEEDED(sqstd_writeclosuretofile(v,filename)))
- return 1;
- return SQ_ERROR; //propagates the error
-}
-
-SQInteger _g_io_dofile(HSQUIRRELVM v)
-{
- const SQChar *filename;
- SQBool printerror = SQFalse;
- sq_getstring(v,2,&filename);
- if(sq_gettop(v) >= 3) {
- sq_getbool(v,3,&printerror);
- }
- sq_push(v,1); //repush the this
- if(SQ_SUCCEEDED(sqstd_dofile(v,filename,SQTrue,printerror)))
- return 1;
- return SQ_ERROR; //propagates the error
-}
-
-#define _DECL_GLOBALIO_FUNC(name,nparams,typecheck) {_SC(#name),_g_io_##name,nparams,typecheck}
-static SQRegFunction iolib_funcs[]={
- _DECL_GLOBALIO_FUNC(loadfile,-2,_SC(".sb")),
- _DECL_GLOBALIO_FUNC(dofile,-2,_SC(".sb")),
- _DECL_GLOBALIO_FUNC(writeclosuretofile,3,_SC(".sc")),
- {0,0}
-};
-
-SQRESULT sqstd_register_iolib(HSQUIRRELVM v)
-{
- SQInteger top = sq_gettop(v);
- //create delegate
- declare_stream(v,_SC("file"),(SQUserPointer)SQSTD_FILE_TYPE_TAG,_SC("std_file"),_file_methods,iolib_funcs);
- sq_pushstring(v,_SC("stdout"),-1);
- sqstd_createfile(v,stdout,SQFalse);
- sq_createslot(v,-3);
- sq_pushstring(v,_SC("stdin"),-1);
- sqstd_createfile(v,stdin,SQFalse);
- sq_createslot(v,-3);
- sq_pushstring(v,_SC("stderr"),-1);
- sqstd_createfile(v,stderr,SQFalse);
- sq_createslot(v,-3);
- sq_settop(v,top);
- return SQ_OK;
-}
+++ /dev/null
-/* see copyright notice in squirrel.h */
-#include <squirrel.h>
-#include <math.h>
-#include <stdlib.h>
-#include <sqstdmath.h>
-
-#define SINGLE_ARG_FUNC(_funcname) static SQInteger math_##_funcname(HSQUIRRELVM v){ \
- SQFloat f; \
- sq_getfloat(v,2,&f); \
- sq_pushfloat(v,(SQFloat)_funcname(f)); \
- return 1; \
-}
-
-#define TWO_ARGS_FUNC(_funcname) static SQInteger math_##_funcname(HSQUIRRELVM v){ \
- SQFloat p1,p2; \
- sq_getfloat(v,2,&p1); \
- sq_getfloat(v,3,&p2); \
- sq_pushfloat(v,(SQFloat)_funcname(p1,p2)); \
- return 1; \
-}
-
-static SQInteger math_srand(HSQUIRRELVM v)
-{
- SQInteger i;
- if(!sq_getinteger(v,2,&i))return sq_throwerror(v,_SC("invalid param"));
- srand((unsigned int)i);
- return 0;
-}
-
-static SQInteger math_rand(HSQUIRRELVM v)
-{
- sq_pushinteger(v,rand());
- return 1;
-}
-
-static SQInteger math_abs(HSQUIRRELVM v)
-{
- SQInteger n;
- sq_getinteger(v,2,&n);
- sq_pushinteger(v,(SQInteger)abs((int)n));
- return 1;
-}
-
-SINGLE_ARG_FUNC(sqrt)
-SINGLE_ARG_FUNC(fabs)
-SINGLE_ARG_FUNC(sin)
-SINGLE_ARG_FUNC(cos)
-SINGLE_ARG_FUNC(asin)
-SINGLE_ARG_FUNC(acos)
-SINGLE_ARG_FUNC(log)
-SINGLE_ARG_FUNC(log10)
-SINGLE_ARG_FUNC(tan)
-SINGLE_ARG_FUNC(atan)
-TWO_ARGS_FUNC(atan2)
-TWO_ARGS_FUNC(pow)
-SINGLE_ARG_FUNC(floor)
-SINGLE_ARG_FUNC(ceil)
-SINGLE_ARG_FUNC(exp)
-
-#define _DECL_FUNC(name,nparams,tycheck) {_SC(#name),math_##name,nparams,tycheck}
-static SQRegFunction mathlib_funcs[] = {
- _DECL_FUNC(sqrt,2,_SC(".n")),
- _DECL_FUNC(sin,2,_SC(".n")),
- _DECL_FUNC(cos,2,_SC(".n")),
- _DECL_FUNC(asin,2,_SC(".n")),
- _DECL_FUNC(acos,2,_SC(".n")),
- _DECL_FUNC(log,2,_SC(".n")),
- _DECL_FUNC(log10,2,_SC(".n")),
- _DECL_FUNC(tan,2,_SC(".n")),
- _DECL_FUNC(atan,2,_SC(".n")),
- _DECL_FUNC(atan2,3,_SC(".nn")),
- _DECL_FUNC(pow,3,_SC(".nn")),
- _DECL_FUNC(floor,2,_SC(".n")),
- _DECL_FUNC(ceil,2,_SC(".n")),
- _DECL_FUNC(exp,2,_SC(".n")),
- _DECL_FUNC(srand,2,_SC(".n")),
- _DECL_FUNC(rand,1,NULL),
- _DECL_FUNC(fabs,2,_SC(".n")),
- _DECL_FUNC(abs,2,_SC(".n")),
- {0,0},
-};
-
-#ifndef M_PI
-#define M_PI (3.14159265358979323846)
-#endif
-
-SQRESULT sqstd_register_mathlib(HSQUIRRELVM v)
-{
- SQInteger i=0;
- while(mathlib_funcs[i].name!=0) {
- sq_pushstring(v,mathlib_funcs[i].name,-1);
- sq_newclosure(v,mathlib_funcs[i].f,0);
- sq_setparamscheck(v,mathlib_funcs[i].nparamscheck,mathlib_funcs[i].typemask);
- sq_setnativeclosurename(v,-1,mathlib_funcs[i].name);
- sq_createslot(v,-3);
- i++;
- }
- sq_pushstring(v,_SC("RAND_MAX"),-1);
- sq_pushinteger(v,RAND_MAX);
- sq_createslot(v,-3);
- sq_pushstring(v,_SC("PI"),-1);
- sq_pushfloat(v,(SQFloat)M_PI);
- sq_createslot(v,-3);
- return SQ_OK;
-}
+++ /dev/null
-/* see copyright notice in squirrel.h */
-#include <squirrel.h>
-#include <string.h>
-#include <ctype.h>
-#include <setjmp.h>
-#include "sqstdstring.h"
-
-#ifdef _UINCODE
-#define scisprint iswprint
-#else
-#define scisprint isprint
-#endif
-
-#ifdef _DEBUG
-#include <stdio.h>
-
-static const SQChar *g_nnames[] =
-{
- _SC("NONE"),_SC("OP_GREEDY"), _SC("OP_OR"),
- _SC("OP_EXPR"),_SC("OP_NOCAPEXPR"),_SC("OP_DOT"), _SC("OP_CLASS"),
- _SC("OP_CCLASS"),_SC("OP_NCLASS"),_SC("OP_RANGE"),_SC("OP_CHAR"),
- _SC("OP_EOL"),_SC("OP_BOL"),_SC("OP_WB")
-};
-
-#endif
-
-#define OP_GREEDY (MAX_CHAR+1) // * + ? {n}
-#define OP_OR (MAX_CHAR+2)
-#define OP_EXPR (MAX_CHAR+3) //parentesis ()
-#define OP_NOCAPEXPR (MAX_CHAR+4) //parentesis (?:)
-#define OP_DOT (MAX_CHAR+5)
-#define OP_CLASS (MAX_CHAR+6)
-#define OP_CCLASS (MAX_CHAR+7)
-#define OP_NCLASS (MAX_CHAR+8) //negates class the [^
-#define OP_RANGE (MAX_CHAR+9)
-#define OP_CHAR (MAX_CHAR+10)
-#define OP_EOL (MAX_CHAR+11)
-#define OP_BOL (MAX_CHAR+12)
-#define OP_WB (MAX_CHAR+13)
-
-#define SQREX_SYMBOL_ANY_CHAR ('.')
-#define SQREX_SYMBOL_GREEDY_ONE_OR_MORE ('+')
-#define SQREX_SYMBOL_GREEDY_ZERO_OR_MORE ('*')
-#define SQREX_SYMBOL_GREEDY_ZERO_OR_ONE ('?')
-#define SQREX_SYMBOL_BRANCH ('|')
-#define SQREX_SYMBOL_END_OF_STRING ('$')
-#define SQREX_SYMBOL_BEGINNING_OF_STRING ('^')
-#define SQREX_SYMBOL_ESCAPE_CHAR ('\\')
-
-
-typedef int SQRexNodeType;
-
-typedef struct tagSQRexNode{
- SQRexNodeType type;
- SQInteger left;
- SQInteger right;
- SQInteger next;
-}SQRexNode;
-
-struct SQRex{
- const SQChar *_eol;
- const SQChar *_bol;
- const SQChar *_p;
- SQInteger _first;
- SQInteger _op;
- SQRexNode *_nodes;
- SQInteger _nallocated;
- SQInteger _nsize;
- SQInteger _nsubexpr;
- SQRexMatch *_matches;
- SQInteger _currsubexp;
- void *_jmpbuf;
- const SQChar **_error;
-};
-
-static SQInteger sqstd_rex_list(SQRex *exp);
-
-static SQInteger sqstd_rex_newnode(SQRex *exp, SQRexNodeType type)
-{
- SQRexNode n;
- n.type = type;
- n.next = n.right = n.left = -1;
- if(type == OP_EXPR)
- n.right = exp->_nsubexpr++;
- if(exp->_nallocated < (exp->_nsize + 1)) {
- SQInteger oldsize = exp->_nallocated;
- exp->_nallocated *= 2;
- exp->_nodes = (SQRexNode *)sq_realloc(exp->_nodes, oldsize * sizeof(SQRexNode) ,exp->_nallocated * sizeof(SQRexNode));
- }
- exp->_nodes[exp->_nsize++] = n;
- SQInteger newid = exp->_nsize - 1;
- return (SQInteger)newid;
-}
-
-static void sqstd_rex_error(SQRex *exp,const SQChar *error)
-{
- if(exp->_error) *exp->_error = error;
- longjmp(*((jmp_buf*)exp->_jmpbuf),-1);
-}
-
-static void sqstd_rex_expect(SQRex *exp, SQInteger n){
- if((*exp->_p) != n)
- sqstd_rex_error(exp, _SC("expected paren"));
- exp->_p++;
-}
-
-static SQChar sqstd_rex_escapechar(SQRex *exp)
-{
- if(*exp->_p == SQREX_SYMBOL_ESCAPE_CHAR){
- exp->_p++;
- switch(*exp->_p) {
- case 'v': exp->_p++; return '\v';
- case 'n': exp->_p++; return '\n';
- case 't': exp->_p++; return '\t';
- case 'r': exp->_p++; return '\r';
- case 'f': exp->_p++; return '\f';
- default: return (*exp->_p++);
- }
- } else if(!scisprint(*exp->_p)) sqstd_rex_error(exp,_SC("letter expected"));
- return (*exp->_p++);
-}
-
-static SQInteger sqstd_rex_charclass(SQRex *exp,SQInteger classid)
-{
- SQInteger n = sqstd_rex_newnode(exp,OP_CCLASS);
- exp->_nodes[n].left = classid;
- return n;
-}
-
-static SQInteger sqstd_rex_charnode(SQRex *exp,SQBool isclass)
-{
- SQChar t;
- if(*exp->_p == SQREX_SYMBOL_ESCAPE_CHAR) {
- exp->_p++;
- switch(*exp->_p) {
- case 'n': exp->_p++; return sqstd_rex_newnode(exp,'\n');
- case 't': exp->_p++; return sqstd_rex_newnode(exp,'\t');
- case 'r': exp->_p++; return sqstd_rex_newnode(exp,'\r');
- case 'f': exp->_p++; return sqstd_rex_newnode(exp,'\f');
- case 'v': exp->_p++; return sqstd_rex_newnode(exp,'\v');
- case 'a': case 'A': case 'w': case 'W': case 's': case 'S':
- case 'd': case 'D': case 'x': case 'X': case 'c': case 'C':
- case 'p': case 'P': case 'l': case 'u':
- {
- t = *exp->_p; exp->_p++;
- return sqstd_rex_charclass(exp,t);
- }
- case 'b':
- case 'B':
- if(!isclass) {
- SQInteger node = sqstd_rex_newnode(exp,OP_WB);
- exp->_nodes[node].left = *exp->_p;
- exp->_p++;
- return node;
- } //else default
- default:
- t = *exp->_p; exp->_p++;
- return sqstd_rex_newnode(exp,t);
- }
- }
- else if(!scisprint(*exp->_p)) {
-
- sqstd_rex_error(exp,_SC("letter expected"));
- }
- t = *exp->_p; exp->_p++;
- return sqstd_rex_newnode(exp,t);
-}
-static SQInteger sqstd_rex_class(SQRex *exp)
-{
- SQInteger ret = -1;
- SQInteger first = -1,chain;
- if(*exp->_p == SQREX_SYMBOL_BEGINNING_OF_STRING){
- ret = sqstd_rex_newnode(exp,OP_NCLASS);
- exp->_p++;
- }else ret = sqstd_rex_newnode(exp,OP_CLASS);
-
- if(*exp->_p == ']') sqstd_rex_error(exp,_SC("empty class"));
- chain = ret;
- while(*exp->_p != ']' && exp->_p != exp->_eol) {
- if(*exp->_p == '-' && first != -1){
- SQInteger r;
- if(*exp->_p++ == ']') sqstd_rex_error(exp,_SC("unfinished range"));
- r = sqstd_rex_newnode(exp,OP_RANGE);
- if(first>*exp->_p) sqstd_rex_error(exp,_SC("invalid range"));
- if(exp->_nodes[first].type == OP_CCLASS) sqstd_rex_error(exp,_SC("cannot use character classes in ranges"));
- exp->_nodes[r].left = exp->_nodes[first].type;
- SQInteger t = sqstd_rex_escapechar(exp);
- exp->_nodes[r].right = t;
- exp->_nodes[chain].next = r;
- chain = r;
- first = -1;
- }
- else{
- if(first!=-1){
- SQInteger c = first;
- exp->_nodes[chain].next = c;
- chain = c;
- first = sqstd_rex_charnode(exp,SQTrue);
- }
- else{
- first = sqstd_rex_charnode(exp,SQTrue);
- }
- }
- }
- if(first!=-1){
- SQInteger c = first;
- exp->_nodes[chain].next = c;
- chain = c;
- first = -1;
- }
- /* hack? */
- exp->_nodes[ret].left = exp->_nodes[ret].next;
- exp->_nodes[ret].next = -1;
- return ret;
-}
-
-static SQInteger sqstd_rex_parsenumber(SQRex *exp)
-{
- SQInteger ret = *exp->_p-'0';
- SQInteger positions = 10;
- exp->_p++;
- while(isdigit(*exp->_p)) {
- ret = ret*10+(*exp->_p++-'0');
- if(positions==1000000000) sqstd_rex_error(exp,_SC("overflow in numeric constant"));
- positions *= 10;
- };
- return ret;
-}
-
-static SQInteger sqstd_rex_element(SQRex *exp)
-{
- SQInteger ret = -1;
- switch(*exp->_p)
- {
- case '(': {
- SQInteger expr;
- exp->_p++;
-
-
- if(*exp->_p =='?') {
- exp->_p++;
- sqstd_rex_expect(exp,':');
- expr = sqstd_rex_newnode(exp,OP_NOCAPEXPR);
- }
- else
- expr = sqstd_rex_newnode(exp,OP_EXPR);
- SQInteger newn = sqstd_rex_list(exp);
- exp->_nodes[expr].left = newn;
- ret = expr;
- sqstd_rex_expect(exp,')');
- }
- break;
- case '[':
- exp->_p++;
- ret = sqstd_rex_class(exp);
- sqstd_rex_expect(exp,']');
- break;
- case SQREX_SYMBOL_END_OF_STRING: exp->_p++; ret = sqstd_rex_newnode(exp,OP_EOL);break;
- case SQREX_SYMBOL_ANY_CHAR: exp->_p++; ret = sqstd_rex_newnode(exp,OP_DOT);break;
- default:
- ret = sqstd_rex_charnode(exp,SQFalse);
- break;
- }
-
-
- SQInteger op;
- SQBool isgreedy = SQFalse;
- unsigned short p0 = 0, p1 = 0;
- switch(*exp->_p){
- case SQREX_SYMBOL_GREEDY_ZERO_OR_MORE: p0 = 0; p1 = 0xFFFF; exp->_p++; isgreedy = SQTrue; break;
- case SQREX_SYMBOL_GREEDY_ONE_OR_MORE: p0 = 1; p1 = 0xFFFF; exp->_p++; isgreedy = SQTrue; break;
- case SQREX_SYMBOL_GREEDY_ZERO_OR_ONE: p0 = 0; p1 = 1; exp->_p++; isgreedy = SQTrue; break;
- case '{':
- exp->_p++;
- if(!isdigit(*exp->_p)) sqstd_rex_error(exp,_SC("number expected"));
- p0 = (unsigned short)sqstd_rex_parsenumber(exp);
- /*******************************/
- switch(*exp->_p) {
- case '}':
- p1 = p0; exp->_p++;
- break;
- case ',':
- exp->_p++;
- p1 = 0xFFFF;
- if(isdigit(*exp->_p)){
- p1 = (unsigned short)sqstd_rex_parsenumber(exp);
- }
- sqstd_rex_expect(exp,'}');
- break;
- default:
- sqstd_rex_error(exp,_SC(", or } expected"));
- }
- /*******************************/
- isgreedy = SQTrue;
- break;
-
- }
- if(isgreedy) {
- SQInteger nnode = sqstd_rex_newnode(exp,OP_GREEDY);
- op = OP_GREEDY;
- exp->_nodes[nnode].left = ret;
- exp->_nodes[nnode].right = ((p0)<<16)|p1;
- ret = nnode;
- }
-
- if((*exp->_p != SQREX_SYMBOL_BRANCH) && (*exp->_p != ')') && (*exp->_p != SQREX_SYMBOL_GREEDY_ZERO_OR_MORE) && (*exp->_p != SQREX_SYMBOL_GREEDY_ONE_OR_MORE) && (*exp->_p != '\0')) {
- SQInteger nnode = sqstd_rex_element(exp);
- exp->_nodes[ret].next = nnode;
- }
-
- return ret;
-}
-
-static SQInteger sqstd_rex_list(SQRex *exp)
-{
- SQInteger ret=-1,e;
- if(*exp->_p == SQREX_SYMBOL_BEGINNING_OF_STRING) {
- exp->_p++;
- ret = sqstd_rex_newnode(exp,OP_BOL);
- }
- e = sqstd_rex_element(exp);
- if(ret != -1) {
- exp->_nodes[ret].next = e;
- }
- else ret = e;
-
- if(*exp->_p == SQREX_SYMBOL_BRANCH) {
- SQInteger temp,tright;
- exp->_p++;
- temp = sqstd_rex_newnode(exp,OP_OR);
- exp->_nodes[temp].left = ret;
- tright = sqstd_rex_list(exp);
- exp->_nodes[temp].right = tright;
- ret = temp;
- }
- return ret;
-}
-
-static SQBool sqstd_rex_matchcclass(SQInteger cclass,SQChar c)
-{
- switch(cclass) {
- case 'a': return isalpha(c)?SQTrue:SQFalse;
- case 'A': return !isalpha(c)?SQTrue:SQFalse;
- case 'w': return (isalnum(c) || c == '_')?SQTrue:SQFalse;
- case 'W': return (!isalnum(c) && c != '_')?SQTrue:SQFalse;
- case 's': return isspace(c)?SQTrue:SQFalse;
- case 'S': return !isspace(c)?SQTrue:SQFalse;
- case 'd': return isdigit(c)?SQTrue:SQFalse;
- case 'D': return !isdigit(c)?SQTrue:SQFalse;
- case 'x': return isxdigit(c)?SQTrue:SQFalse;
- case 'X': return !isxdigit(c)?SQTrue:SQFalse;
- case 'c': return iscntrl(c)?SQTrue:SQFalse;
- case 'C': return !iscntrl(c)?SQTrue:SQFalse;
- case 'p': return ispunct(c)?SQTrue:SQFalse;
- case 'P': return !ispunct(c)?SQTrue:SQFalse;
- case 'l': return islower(c)?SQTrue:SQFalse;
- case 'u': return isupper(c)?SQTrue:SQFalse;
- }
- return SQFalse; /*cannot happen*/
-}
-
-static SQBool sqstd_rex_matchclass(SQRex* exp,SQRexNode *node,SQChar c)
-{
- do {
- switch(node->type) {
- case OP_RANGE:
- if(c >= node->left && c <= node->right) return SQTrue;
- break;
- case OP_CCLASS:
- if(sqstd_rex_matchcclass(node->left,c)) return SQTrue;
- break;
- default:
- if(c == node->type)return SQTrue;
- }
- } while((node->next != -1) && (node = &exp->_nodes[node->next]));
- return SQFalse;
-}
-
-static const SQChar *sqstd_rex_matchnode(SQRex* exp,SQRexNode *node,const SQChar *str,SQRexNode *next)
-{
-
- SQRexNodeType type = node->type;
- switch(type) {
- case OP_GREEDY: {
- //SQRexNode *greedystop = (node->next != -1) ? &exp->_nodes[node->next] : NULL;
- SQRexNode *greedystop = NULL;
- SQInteger p0 = (node->right >> 16)&0x0000FFFF, p1 = node->right&0x0000FFFF, nmaches = 0;
- const SQChar *s=str, *good = str;
-
- if(node->next != -1) {
- greedystop = &exp->_nodes[node->next];
- }
- else {
- greedystop = next;
- }
-
- while((nmaches == 0xFFFF || nmaches < p1)) {
-
- const SQChar *stop;
- if(!(s = sqstd_rex_matchnode(exp,&exp->_nodes[node->left],s,greedystop)))
- break;
- nmaches++;
- good=s;
- if(greedystop) {
- //checks that 0 matches satisfy the expression(if so skips)
- //if not would always stop(for instance if is a '?')
- if(greedystop->type != OP_GREEDY ||
- (greedystop->type == OP_GREEDY && ((greedystop->right >> 16)&0x0000FFFF) != 0))
- {
- SQRexNode *gnext = NULL;
- if(greedystop->next != -1) {
- gnext = &exp->_nodes[greedystop->next];
- }else if(next && next->next != -1){
- gnext = &exp->_nodes[next->next];
- }
- stop = sqstd_rex_matchnode(exp,greedystop,s,gnext);
- if(stop) {
- //if satisfied stop it
- if(p0 == p1 && p0 == nmaches) break;
- else if(nmaches >= p0 && p1 == 0xFFFF) break;
- else if(nmaches >= p0 && nmaches <= p1) break;
- }
- }
- }
-
- if(s >= exp->_eol)
- break;
- }
- if(p0 == p1 && p0 == nmaches) return good;
- else if(nmaches >= p0 && p1 == 0xFFFF) return good;
- else if(nmaches >= p0 && nmaches <= p1) return good;
- return NULL;
- }
- case OP_OR: {
- const SQChar *asd = str;
- SQRexNode *temp=&exp->_nodes[node->left];
- while( (asd = sqstd_rex_matchnode(exp,temp,asd,NULL)) ) {
- if(temp->next != -1)
- temp = &exp->_nodes[temp->next];
- else
- return asd;
- }
- asd = str;
- temp = &exp->_nodes[node->right];
- while( (asd = sqstd_rex_matchnode(exp,temp,asd,NULL)) ) {
- if(temp->next != -1)
- temp = &exp->_nodes[temp->next];
- else
- return asd;
- }
- return NULL;
- break;
- }
- case OP_EXPR:
- case OP_NOCAPEXPR:{
- SQRexNode *n = &exp->_nodes[node->left];
- const SQChar *cur = str;
- SQInteger capture = -1;
- if(node->type != OP_NOCAPEXPR && node->right == exp->_currsubexp) {
- capture = exp->_currsubexp;
- exp->_matches[capture].begin = cur;
- exp->_currsubexp++;
- }
-
- do {
- SQRexNode *subnext = NULL;
- if(n->next != -1) {
- subnext = &exp->_nodes[n->next];
- }else {
- subnext = next;
- }
- if(!(cur = sqstd_rex_matchnode(exp,n,cur,subnext))) {
- if(capture != -1){
- exp->_matches[capture].begin = 0;
- exp->_matches[capture].len = 0;
- }
- return NULL;
- }
- } while((n->next != -1) && (n = &exp->_nodes[n->next]));
-
- if(capture != -1)
- exp->_matches[capture].len = cur - exp->_matches[capture].begin;
- return cur;
- }
- case OP_WB:
- if(str == exp->_bol && !isspace(*str)
- || (str == exp->_eol && !isspace(*(str-1)))
- || (!isspace(*str) && isspace(*(str+1)))
- || (isspace(*str) && !isspace(*(str+1))) ) {
- return (node->left == 'b')?str:NULL;
- }
- return (node->left == 'b')?NULL:str;
- case OP_BOL:
- if(str == exp->_bol) return str;
- return NULL;
- case OP_EOL:
- if(str == exp->_eol) return str;
- return NULL;
- case OP_DOT:{
- *str++;
- }
- return str;
- case OP_NCLASS:
- case OP_CLASS:
- if(sqstd_rex_matchclass(exp,&exp->_nodes[node->left],*str)?(type == OP_CLASS?SQTrue:SQFalse):(type == OP_NCLASS?SQTrue:SQFalse)) {
- *str++;
- return str;
- }
- return NULL;
- case OP_CCLASS:
- if(sqstd_rex_matchcclass(node->left,*str)) {
- *str++;
- return str;
- }
- return NULL;
- default: /* char */
- if(*str != node->type) return NULL;
- *str++;
- return str;
- }
- return NULL;
-}
-
-/* public api */
-SQRex *sqstd_rex_compile(const SQChar *pattern,const SQChar **error)
-{
- SQRex *exp = (SQRex *)sq_malloc(sizeof(SQRex));
- exp->_eol = exp->_bol = NULL;
- exp->_p = pattern;
- exp->_nallocated = (SQInteger)scstrlen(pattern) * sizeof(SQChar);
- exp->_nodes = (SQRexNode *)sq_malloc(exp->_nallocated * sizeof(SQRexNode));
- exp->_nsize = 0;
- exp->_matches = 0;
- exp->_nsubexpr = 0;
- exp->_first = sqstd_rex_newnode(exp,OP_EXPR);
- exp->_error = error;
- exp->_jmpbuf = sq_malloc(sizeof(jmp_buf));
- if(setjmp(*((jmp_buf*)exp->_jmpbuf)) == 0) {
- SQInteger res = sqstd_rex_list(exp);
- exp->_nodes[exp->_first].left = res;
- if(*exp->_p!='\0')
- sqstd_rex_error(exp,_SC("unexpected character"));
-#ifdef _DEBUG
- {
- SQInteger nsize,i;
- SQRexNode *t;
- nsize = exp->_nsize;
- t = &exp->_nodes[0];
- scprintf(_SC("\n"));
- for(i = 0;i < nsize; i++) {
- if(exp->_nodes[i].type>MAX_CHAR)
- scprintf(_SC("[%02d] %10s "),i,g_nnames[exp->_nodes[i].type-MAX_CHAR]);
- else
- scprintf(_SC("[%02d] %10c "),i,exp->_nodes[i].type);
- scprintf(_SC("left %02d right %02d next %02d\n"),exp->_nodes[i].left,exp->_nodes[i].right,exp->_nodes[i].next);
- }
- scprintf(_SC("\n"));
- }
-#endif
- exp->_matches = (SQRexMatch *) sq_malloc(exp->_nsubexpr * sizeof(SQRexMatch));
- memset(exp->_matches,0,exp->_nsubexpr * sizeof(SQRexMatch));
- }
- else{
- sqstd_rex_free(exp);
- return NULL;
- }
- return exp;
-}
-
-void sqstd_rex_free(SQRex *exp)
-{
- if(exp) {
- if(exp->_nodes) sq_free(exp->_nodes,exp->_nallocated * sizeof(SQRexNode));
- if(exp->_jmpbuf) sq_free(exp->_jmpbuf,sizeof(jmp_buf));
- if(exp->_matches) sq_free(exp->_matches,exp->_nsubexpr * sizeof(SQRexMatch));
- sq_free(exp,sizeof(SQRex));
- }
-}
-
-SQBool sqstd_rex_match(SQRex* exp,const SQChar* text)
-{
- const SQChar* res = NULL;
- exp->_bol = text;
- exp->_eol = text + scstrlen(text);
- exp->_currsubexp = 0;
- res = sqstd_rex_matchnode(exp,exp->_nodes,text,NULL);
- if(res == NULL || res != exp->_eol)
- return SQFalse;
- return SQTrue;
-}
-
-SQBool sqstd_rex_searchrange(SQRex* exp,const SQChar* text_begin,const SQChar* text_end,const SQChar** out_begin, const SQChar** out_end)
-{
- const SQChar *cur = NULL;
- SQInteger node = exp->_first;
- if(text_begin >= text_end) return SQFalse;
- exp->_bol = text_begin;
- exp->_eol = text_end;
- do {
- cur = text_begin;
- while(node != -1) {
- exp->_currsubexp = 0;
- cur = sqstd_rex_matchnode(exp,&exp->_nodes[node],cur,NULL);
- if(!cur)
- break;
- node = exp->_nodes[node].next;
- }
- *text_begin++;
- } while(cur == NULL && text_begin != text_end);
-
- if(cur == NULL)
- return SQFalse;
-
- --text_begin;
-
- if(out_begin) *out_begin = text_begin;
- if(out_end) *out_end = cur;
- return SQTrue;
-}
-
-SQBool sqstd_rex_search(SQRex* exp,const SQChar* text, const SQChar** out_begin, const SQChar** out_end)
-{
- return sqstd_rex_searchrange(exp,text,text + scstrlen(text),out_begin,out_end);
-}
-
-SQInteger sqstd_rex_getsubexpcount(SQRex* exp)
-{
- return exp->_nsubexpr;
-}
-
-SQBool sqstd_rex_getsubexp(SQRex* exp, SQInteger n, SQRexMatch *subexp)
-{
- if( n<0 || n >= exp->_nsubexpr) return SQFalse;
- *subexp = exp->_matches[n];
- return SQTrue;
-}
-
+++ /dev/null
-/* see copyright notice in squirrel.h */
-#include <new>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <squirrel.h>
-#include <sqstdio.h>
-#include <sqstdblob.h>
-#include "sqstdstream.h"
-#include "sqstdblobimpl.h"
-
-#define SETUP_STREAM(v) \
- SQStream *self = NULL; \
- if(SQ_FAILED(sq_getinstanceup(v,1,(SQUserPointer*)&self,(SQUserPointer)SQSTD_STREAM_TYPE_TAG))) \
- return sq_throwerror(v,_SC("invalid type tag")); \
- if(!self->IsValid()) \
- return sq_throwerror(v,_SC("the stream is invalid"));
-
-SQInteger _stream_readblob(HSQUIRRELVM v)
-{
- SETUP_STREAM(v);
- SQUserPointer data,blobp;
- SQInteger size,res;
- sq_getinteger(v,2,&size);
- if(size > self->Len()) {
- size = self->Len();
- }
- data = sq_getscratchpad(v,size);
- res = self->Read(data,size);
- if(res <= 0)
- return sq_throwerror(v,_SC("no data left to read"));
- blobp = sqstd_createblob(v,res);
- memcpy(blobp,data,res);
- return 1;
-}
-
-#define SAFE_READN(ptr,len) { \
- if(self->Read(ptr,len) != len) return sq_throwerror(v,_SC("io error")); \
- }
-SQInteger _stream_readn(HSQUIRRELVM v)
-{
- SETUP_STREAM(v);
- SQInteger format;
- sq_getinteger(v, 2, &format);
- switch(format) {
- case 'l': {
- SQInteger i;
- SAFE_READN(&i, sizeof(i));
- sq_pushinteger(v, i);
- }
- break;
- case 'i': {
- SQInt32 i;
- SAFE_READN(&i, sizeof(i));
- sq_pushinteger(v, i);
- }
- break;
- case 's': {
- short s;
- SAFE_READN(&s, sizeof(short));
- sq_pushinteger(v, s);
- }
- break;
- case 'w': {
- unsigned short w;
- SAFE_READN(&w, sizeof(unsigned short));
- sq_pushinteger(v, w);
- }
- break;
- case 'c': {
- char c;
- SAFE_READN(&c, sizeof(char));
- sq_pushinteger(v, c);
- }
- break;
- case 'b': {
- unsigned char c;
- SAFE_READN(&c, sizeof(unsigned char));
- sq_pushinteger(v, c);
- }
- break;
- case 'f': {
- float f;
- SAFE_READN(&f, sizeof(float));
- sq_pushfloat(v, f);
- }
- break;
- case 'd': {
- double d;
- SAFE_READN(&d, sizeof(double));
- sq_pushfloat(v, (SQFloat)d);
- }
- break;
- default:
- return sq_throwerror(v, _SC("invalid format"));
- }
- return 1;
-}
-
-SQInteger _stream_writeblob(HSQUIRRELVM v)
-{
- SQUserPointer data;
- SQInteger size;
- SETUP_STREAM(v);
- if(SQ_FAILED(sqstd_getblob(v,2,&data)))
- return sq_throwerror(v,_SC("invalid parameter"));
- size = sqstd_getblobsize(v,2);
- if(self->Write(data,size) != size)
- return sq_throwerror(v,_SC("io error"));
- sq_pushinteger(v,size);
- return 1;
-}
-
-SQInteger _stream_writen(HSQUIRRELVM v)
-{
- SETUP_STREAM(v);
- SQInteger format, ti;
- SQFloat tf;
- sq_getinteger(v, 3, &format);
- switch(format) {
- case 'l': {
- SQInteger i;
- sq_getinteger(v, 2, &ti);
- i = ti;
- self->Write(&i, sizeof(SQInteger));
- }
- break;
- case 'i': {
- SQInt32 i;
- sq_getinteger(v, 2, &ti);
- i = (SQInt32)ti;
- self->Write(&i, sizeof(SQInt32));
- }
- break;
- case 's': {
- short s;
- sq_getinteger(v, 2, &ti);
- s = (short)ti;
- self->Write(&s, sizeof(short));
- }
- break;
- case 'w': {
- unsigned short w;
- sq_getinteger(v, 2, &ti);
- w = (unsigned short)ti;
- self->Write(&w, sizeof(unsigned short));
- }
- break;
- case 'c': {
- char c;
- sq_getinteger(v, 2, &ti);
- c = (char)ti;
- self->Write(&c, sizeof(char));
- }
- break;
- case 'b': {
- unsigned char b;
- sq_getinteger(v, 2, &ti);
- b = (unsigned char)ti;
- self->Write(&b, sizeof(unsigned char));
- }
- break;
- case 'f': {
- float f;
- sq_getfloat(v, 2, &tf);
- f = (float)tf;
- self->Write(&f, sizeof(float));
- }
- break;
- case 'd': {
- double d;
- sq_getfloat(v, 2, &tf);
- d = tf;
- self->Write(&d, sizeof(double));
- }
- break;
- default:
- return sq_throwerror(v, _SC("invalid format"));
- }
- return 0;
-}
-
-SQInteger _stream_seek(HSQUIRRELVM v)
-{
- SETUP_STREAM(v);
- SQInteger offset, origin = SQ_SEEK_SET;
- sq_getinteger(v, 2, &offset);
- if(sq_gettop(v) > 2) {
- SQInteger t;
- sq_getinteger(v, 3, &t);
- switch(t) {
- case 'b': origin = SQ_SEEK_SET; break;
- case 'c': origin = SQ_SEEK_CUR; break;
- case 'e': origin = SQ_SEEK_END; break;
- default: return sq_throwerror(v,_SC("invalid origin"));
- }
- }
- sq_pushinteger(v, self->Seek(offset, origin));
- return 1;
-}
-
-SQInteger _stream_tell(HSQUIRRELVM v)
-{
- SETUP_STREAM(v);
- sq_pushinteger(v, self->Tell());
- return 1;
-}
-
-SQInteger _stream_len(HSQUIRRELVM v)
-{
- SETUP_STREAM(v);
- sq_pushinteger(v, self->Len());
- return 1;
-}
-
-SQInteger _stream_flush(HSQUIRRELVM v)
-{
- SETUP_STREAM(v);
- if(!self->Flush())
- sq_pushinteger(v, 1);
- else
- sq_pushnull(v);
- return 1;
-}
-
-SQInteger _stream_eos(HSQUIRRELVM v)
-{
- SETUP_STREAM(v);
- if(self->EOS())
- sq_pushinteger(v, 1);
- else
- sq_pushnull(v);
- return 1;
-}
-
-static SQRegFunction _stream_methods[] = {
- _DECL_STREAM_FUNC(readblob,2,_SC("xn")),
- _DECL_STREAM_FUNC(readn,2,_SC("xn")),
- _DECL_STREAM_FUNC(writeblob,-2,_SC("xx")),
- _DECL_STREAM_FUNC(writen,3,_SC("xnn")),
- _DECL_STREAM_FUNC(seek,-2,_SC("xnn")),
- _DECL_STREAM_FUNC(tell,1,_SC("x")),
- _DECL_STREAM_FUNC(len,1,_SC("x")),
- _DECL_STREAM_FUNC(eos,1,_SC("x")),
- _DECL_STREAM_FUNC(flush,1,_SC("x")),
- {0,0}
-};
-
-void init_streamclass(HSQUIRRELVM v)
-{
- sq_pushregistrytable(v);
- sq_pushstring(v,_SC("std_stream"),-1);
- if(SQ_FAILED(sq_get(v,-2))) {
- sq_pushstring(v,_SC("std_stream"),-1);
- sq_newclass(v,SQFalse);
- sq_settypetag(v,-1,(SQUserPointer)SQSTD_STREAM_TYPE_TAG);
- SQInteger i = 0;
- while(_stream_methods[i].name != 0) {
- SQRegFunction &f = _stream_methods[i];
- sq_pushstring(v,f.name,-1);
- sq_newclosure(v,f.f,0);
- sq_setparamscheck(v,f.nparamscheck,f.typemask);
- sq_createslot(v,-3);
- i++;
- }
- sq_createslot(v,-3);
- sq_pushroottable(v);
- sq_pushstring(v,_SC("stream"),-1);
- sq_pushstring(v,_SC("std_stream"),-1);
- sq_get(v,-4);
- sq_createslot(v,-3);
- sq_pop(v,1);
- }
- else {
- sq_pop(v,1); //result
- }
- sq_pop(v,1);
-}
-
-SQRESULT declare_stream(HSQUIRRELVM v,SQChar* name,SQUserPointer typetag,SQChar* reg_name,SQRegFunction *methods,SQRegFunction *globals)
-{
- if(sq_gettype(v,-1) != OT_TABLE)
- return sq_throwerror(v,_SC("table expected"));
- SQInteger top = sq_gettop(v);
- //create delegate
- init_streamclass(v);
- sq_pushregistrytable(v);
- sq_pushstring(v,reg_name,-1);
- sq_pushstring(v,_SC("std_stream"),-1);
- if(SQ_SUCCEEDED(sq_get(v,-3))) {
- sq_newclass(v,SQTrue);
- sq_settypetag(v,-1,typetag);
- SQInteger i = 0;
- while(methods[i].name != 0) {
- SQRegFunction &f = methods[i];
- sq_pushstring(v,f.name,-1);
- sq_newclosure(v,f.f,0);
- sq_setparamscheck(v,f.nparamscheck,f.typemask);
- sq_setnativeclosurename(v,-1,f.name);
- sq_createslot(v,-3);
- i++;
- }
- sq_createslot(v,-3);
- sq_pop(v,1);
-
- i = 0;
- while(globals[i].name!=0)
- {
- SQRegFunction &f = globals[i];
- sq_pushstring(v,f.name,-1);
- sq_newclosure(v,f.f,0);
- sq_setparamscheck(v,f.nparamscheck,f.typemask);
- sq_setnativeclosurename(v,-1,f.name);
- sq_createslot(v,-3);
- i++;
- }
- //register the class in the target table
- sq_pushstring(v,name,-1);
- sq_pushregistrytable(v);
- sq_pushstring(v,reg_name,-1);
- sq_get(v,-2);
- sq_remove(v,-2);
- sq_createslot(v,-3);
-
- sq_settop(v,top);
- return SQ_OK;
- }
- sq_settop(v,top);
- return SQ_ERROR;
-}
+++ /dev/null
-/* see copyright notice in squirrel.h */
-#ifndef _SQSTD_STREAM_H_
-#define _SQSTD_STREAM_H_
-
-SQInteger _stream_readblob(HSQUIRRELVM v);
-SQInteger _stream_readline(HSQUIRRELVM v);
-SQInteger _stream_readn(HSQUIRRELVM v);
-SQInteger _stream_writeblob(HSQUIRRELVM v);
-SQInteger _stream_writen(HSQUIRRELVM v);
-SQInteger _stream_seek(HSQUIRRELVM v);
-SQInteger _stream_tell(HSQUIRRELVM v);
-SQInteger _stream_len(HSQUIRRELVM v);
-SQInteger _stream_eos(HSQUIRRELVM v);
-SQInteger _stream_flush(HSQUIRRELVM v);
-
-#define _DECL_STREAM_FUNC(name,nparams,typecheck) {_SC(#name),_stream_##name,nparams,typecheck}
-SQRESULT declare_stream(HSQUIRRELVM v,SQChar* name,SQUserPointer typetag,SQChar* reg_name,SQRegFunction *methods,SQRegFunction *globals);
-#endif /*_SQSTD_STREAM_H_*/
+++ /dev/null
-/* see copyright notice in squirrel.h */
-#include <squirrel.h>
-#include <sqstdstring.h>
-#include <string.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <ctype.h>
-#include <assert.h>
-
-#ifdef _UNICODE
-#define scstrchr wcschr
-#define scsnprintf wsnprintf
-#define scatoi _wtoi
-#define scstrtok wcstok
-#else
-#define scstrchr strchr
-#define scsnprintf snprintf
-#define scatoi atoi
-#define scstrtok strtok
-#endif
-#define MAX_FORMAT_LEN 20
-#define MAX_WFORMAT_LEN 3
-#define ADDITIONAL_FORMAT_SPACE (100*sizeof(SQChar))
-
-static SQInteger validate_format(HSQUIRRELVM v, SQChar *fmt, const SQChar *src, SQInteger n,SQInteger &width)
-{
- SQChar swidth[MAX_WFORMAT_LEN];
- SQInteger wc = 0;
- SQInteger start = n;
- fmt[0] = '%';
- while (scstrchr(_SC("-+ #0"), src[n])) n++;
- while (scisdigit(src[n])) {
- swidth[wc] = src[n];
- n++;
- wc++;
- if(wc>=MAX_WFORMAT_LEN)
- return sq_throwerror(v,_SC("width format too long"));
- }
- swidth[wc] = '\0';
- if(wc > 0) {
- width = scatoi(swidth);
- }
- else
- width = 0;
- if (src[n] == '.') {
- n++;
-
- wc = 0;
- while (scisdigit(src[n])) {
- swidth[wc] = src[n];
- n++;
- wc++;
- if(wc>=MAX_WFORMAT_LEN)
- return sq_throwerror(v,_SC("precision format too long"));
- }
- swidth[wc] = '\0';
- if(wc > 0) {
- width += scatoi(swidth);
- }
- }
- if (n-start > MAX_FORMAT_LEN )
- return sq_throwerror(v,_SC("format too long"));
- memcpy(&fmt[1],&src[start],((n-start)+1)*sizeof(SQChar));
- fmt[(n-start)+2] = '\0';
- return n;
-}
-
-static SQInteger _string_format(HSQUIRRELVM v)
-{
- const SQChar *format;
- SQChar *dest;
- SQChar fmt[MAX_FORMAT_LEN];
- sq_getstring(v,2,&format);
- SQInteger allocated = (sq_getsize(v,2)+1)*sizeof(SQChar);
- dest = sq_getscratchpad(v,allocated);
- SQInteger n = 0,i = 0, nparam = 3, w = 0;
- while(format[n] != '\0') {
- if(format[n] != '%') {
- assert(i < allocated);
- dest[i++] = format[n];
- n++;
- }
- else if(format[n+1] == '%') { //handles %%
- dest[i++] = '%';
- n += 2;
- }
- else {
- n++;
- if( nparam > sq_gettop(v) )
- return sq_throwerror(v,_SC("not enough paramters for the given format string"));
- n = validate_format(v,fmt,format,n,w);
- if(n < 0) return -1;
- SQInteger addlen = 0;
- SQInteger valtype = 0;
- const SQChar *ts;
- SQInteger ti;
- SQFloat tf;
- switch(format[n]) {
- case 's':
- if(SQ_FAILED(sq_getstring(v,nparam,&ts)))
- return sq_throwerror(v,_SC("string expected for the specified format"));
- addlen = (sq_getsize(v,nparam)*sizeof(SQChar))+((w+1)*sizeof(SQChar));
- valtype = 's';
- break;
- case 'i': case 'd': case 'c':case 'o': case 'u': case 'x': case 'X':
- if(SQ_FAILED(sq_getinteger(v,nparam,&ti)))
- return sq_throwerror(v,_SC("integer expected for the specified format"));
- addlen = (ADDITIONAL_FORMAT_SPACE)+((w+1)*sizeof(SQChar));
- valtype = 'i';
- break;
- case 'f': case 'g': case 'G': case 'e': case 'E':
- if(SQ_FAILED(sq_getfloat(v,nparam,&tf)))
- return sq_throwerror(v,_SC("float expected for the specified format"));
- addlen = (ADDITIONAL_FORMAT_SPACE)+((w+1)*sizeof(SQChar));
- valtype = 'f';
- break;
- default:
- return sq_throwerror(v,_SC("invalid format"));
- }
- n++;
- allocated += addlen;
- dest = sq_getscratchpad(v,allocated);
- switch(valtype) {
- case 's': i += scsprintf(&dest[i],fmt,ts); break;
- case 'i': i += scsprintf(&dest[i],fmt,ti); break;
- case 'f': i += scsprintf(&dest[i],fmt,tf); break;
- };
- nparam ++;
- }
- }
- sq_pushstring(v,dest,i);
- return 1;
-}
-
-static void __strip_l(const SQChar *str,const SQChar **start)
-{
- const SQChar *t = str;
- while(((*t) != '\0') && scisspace(*t)){ t++; }
- *start = t;
-}
-
-static void __strip_r(const SQChar *str,SQInteger len,const SQChar **end)
-{
- if(len == 0) {
- *end = str;
- return;
- }
- const SQChar *t = &str[len-1];
- while(t != str && scisspace(*t)) { t--; }
- *end = t+1;
-}
-
-static SQInteger _string_strip(HSQUIRRELVM v)
-{
- const SQChar *str,*start,*end;
- sq_getstring(v,2,&str);
- SQInteger len = sq_getsize(v,2);
- __strip_l(str,&start);
- __strip_r(str,len,&end);
- sq_pushstring(v,start,end - start);
- return 1;
-}
-
-static SQInteger _string_lstrip(HSQUIRRELVM v)
-{
- const SQChar *str,*start;
- sq_getstring(v,2,&str);
- __strip_l(str,&start);
- sq_pushstring(v,start,-1);
- return 1;
-}
-
-static SQInteger _string_rstrip(HSQUIRRELVM v)
-{
- const SQChar *str,*end;
- sq_getstring(v,2,&str);
- SQInteger len = sq_getsize(v,2);
- __strip_r(str,len,&end);
- sq_pushstring(v,str,end - str);
- return 1;
-}
-
-static SQInteger _string_split(HSQUIRRELVM v)
-{
- const SQChar *str,*seps;
- SQChar *stemp,*tok;
- sq_getstring(v,2,&str);
- sq_getstring(v,3,&seps);
- if(sq_getsize(v,3) == 0) return sq_throwerror(v,_SC("empty separators string"));
- SQInteger memsize = (sq_getsize(v,2)+1)*sizeof(SQChar);
- stemp = sq_getscratchpad(v,memsize);
- memcpy(stemp,str,memsize);
- tok = scstrtok(stemp,seps);
- sq_newarray(v,0);
- while( tok != NULL ) {
- sq_pushstring(v,tok,-1);
- sq_arrayappend(v,-2);
- tok = scstrtok( NULL, seps );
- }
- return 1;
-}
-
-#define SETUP_REX(v) \
- SQRex *self = NULL; \
- sq_getinstanceup(v,1,(SQUserPointer *)&self,0);
-
-static SQInteger _rexobj_releasehook(SQUserPointer p, SQInteger size)
-{
- SQRex *self = ((SQRex *)p);
- sqstd_rex_free(self);
- return 1;
-}
-
-static SQInteger _regexp_match(HSQUIRRELVM v)
-{
- SETUP_REX(v);
- const SQChar *str;
- sq_getstring(v,2,&str);
- if(sqstd_rex_match(self,str) == SQTrue)
- {
- sq_pushbool(v,SQTrue);
- return 1;
- }
- sq_pushbool(v,SQFalse);
- return 1;
-}
-
-static void _addrexmatch(HSQUIRRELVM v,const SQChar *str,const SQChar *begin,const SQChar *end)
-{
- sq_newtable(v);
- sq_pushstring(v,_SC("begin"),-1);
- sq_pushinteger(v,begin - str);
- sq_rawset(v,-3);
- sq_pushstring(v,_SC("end"),-1);
- sq_pushinteger(v,end - str);
- sq_rawset(v,-3);
-}
-
-static SQInteger _regexp_search(HSQUIRRELVM v)
-{
- SETUP_REX(v);
- const SQChar *str,*begin,*end;
- SQInteger start = 0;
- sq_getstring(v,2,&str);
- if(sq_gettop(v) > 2) sq_getinteger(v,3,&start);
- if(sqstd_rex_search(self,str+start,&begin,&end) == SQTrue) {
- _addrexmatch(v,str,begin,end);
- return 1;
- }
- return 0;
-}
-
-static SQInteger _regexp_capture(HSQUIRRELVM v)
-{
- SETUP_REX(v);
- const SQChar *str,*begin,*end;
- SQInteger start = 0;
- sq_getstring(v,2,&str);
- if(sq_gettop(v) > 2) sq_getinteger(v,3,&start);
- if(sqstd_rex_search(self,str+start,&begin,&end) == SQTrue) {
- SQInteger n = sqstd_rex_getsubexpcount(self);
- SQRexMatch match;
- sq_newarray(v,0);
- for(SQInteger i = 0;i < n; i++) {
- sqstd_rex_getsubexp(self,i,&match);
- if(match.len > 0)
- _addrexmatch(v,str,match.begin,match.begin+match.len);
- else
- _addrexmatch(v,str,str,str); //empty match
- sq_arrayappend(v,-2);
- }
- return 1;
- }
- return 0;
-}
-
-static SQInteger _regexp_subexpcount(HSQUIRRELVM v)
-{
- SETUP_REX(v);
- sq_pushinteger(v,sqstd_rex_getsubexpcount(self));
- return 1;
-}
-
-static SQInteger _regexp_constructor(HSQUIRRELVM v)
-{
- const SQChar *error,*pattern;
- sq_getstring(v,2,&pattern);
- SQRex *rex = sqstd_rex_compile(pattern,&error);
- if(!rex) return sq_throwerror(v,error);
- sq_setinstanceup(v,1,rex);
- sq_setreleasehook(v,1,_rexobj_releasehook);
- return 0;
-}
-
-static SQInteger _regexp__typeof(HSQUIRRELVM v)
-{
- sq_pushstring(v,_SC("regexp"),-1);
- return 1;
-}
-
-#define _DECL_REX_FUNC(name,nparams,pmask) {_SC(#name),_regexp_##name,nparams,pmask}
-static SQRegFunction rexobj_funcs[]={
- _DECL_REX_FUNC(constructor,2,_SC(".s")),
- _DECL_REX_FUNC(search,-2,_SC("xsn")),
- _DECL_REX_FUNC(match,2,_SC("xs")),
- _DECL_REX_FUNC(capture,-2,_SC("xsn")),
- _DECL_REX_FUNC(subexpcount,1,_SC("x")),
- _DECL_REX_FUNC(_typeof,1,_SC("x")),
- {0,0}
-};
-
-#define _DECL_FUNC(name,nparams,pmask) {_SC(#name),_string_##name,nparams,pmask}
-static SQRegFunction stringlib_funcs[]={
- _DECL_FUNC(format,-2,_SC(".s")),
- _DECL_FUNC(strip,2,_SC(".s")),
- _DECL_FUNC(lstrip,2,_SC(".s")),
- _DECL_FUNC(rstrip,2,_SC(".s")),
- _DECL_FUNC(split,3,_SC(".ss")),
- {0,0}
-};
-
-
-SQInteger sqstd_register_stringlib(HSQUIRRELVM v)
-{
- sq_pushstring(v,_SC("regexp"),-1);
- sq_newclass(v,SQFalse);
- SQInteger i = 0;
- while(rexobj_funcs[i].name != 0) {
- SQRegFunction &f = rexobj_funcs[i];
- sq_pushstring(v,f.name,-1);
- sq_newclosure(v,f.f,0);
- sq_setparamscheck(v,f.nparamscheck,f.typemask);
- sq_setnativeclosurename(v,-1,f.name);
- sq_createslot(v,-3);
- i++;
- }
- sq_createslot(v,-3);
-
- i = 0;
- while(stringlib_funcs[i].name!=0)
- {
- sq_pushstring(v,stringlib_funcs[i].name,-1);
- sq_newclosure(v,stringlib_funcs[i].f,0);
- sq_setparamscheck(v,stringlib_funcs[i].nparamscheck,stringlib_funcs[i].typemask);
- sq_setnativeclosurename(v,-1,stringlib_funcs[i].name);
- sq_createslot(v,-3);
- i++;
- }
- return 1;
-}
+++ /dev/null
-/* see copyright notice in squirrel.h */
-#include <squirrel.h>
-#include <time.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <sqstdsystem.h>
-
-#ifdef SQUNICODE
-#include <wchar.h>
-#define scgetenv _wgetenv
-#define scsystem _wsystem
-#define scasctime _wasctime
-#define scremove _wremove
-#define screname _wrename
-#else
-#define scgetenv getenv
-#define scsystem system
-#define scasctime asctime
-#define scremove remove
-#define screname rename
-#endif
-
-static SQInteger _system_getenv(HSQUIRRELVM v)
-{
- const SQChar *s;
- if(SQ_SUCCEEDED(sq_getstring(v,2,&s))){
- sq_pushstring(v,scgetenv(s),-1);
- return 1;
- }
- return 0;
-}
-
-
-static SQInteger _system_system(HSQUIRRELVM v)
-{
- const SQChar *s;
- if(SQ_SUCCEEDED(sq_getstring(v,2,&s))){
- sq_pushinteger(v,scsystem(s));
- return 1;
- }
- return sq_throwerror(v,_SC("wrong param"));
-}
-
-
-static SQInteger _system_clock(HSQUIRRELVM v)
-{
- sq_pushfloat(v,((SQFloat)clock())/(SQFloat)CLOCKS_PER_SEC);
- return 1;
-}
-
-static SQInteger _system_time(HSQUIRRELVM v)
-{
- time_t t;
- time(&t);
- sq_pushinteger(v,*((SQInteger *)&t));
- return 1;
-}
-
-static SQInteger _system_remove(HSQUIRRELVM v)
-{
- const SQChar *s;
- sq_getstring(v,2,&s);
- if(scremove(s)==-1)
- return sq_throwerror(v,_SC("remove() failed"));
- return 0;
-}
-
-static SQInteger _system_rename(HSQUIRRELVM v)
-{
- const SQChar *oldn,*newn;
- sq_getstring(v,2,&oldn);
- sq_getstring(v,3,&newn);
- if(screname(oldn,newn)==-1)
- return sq_throwerror(v,_SC("rename() failed"));
- return 0;
-}
-
-static void _set_integer_slot(HSQUIRRELVM v,const SQChar *name,SQInteger val)
-{
- sq_pushstring(v,name,-1);
- sq_pushinteger(v,val);
- sq_rawset(v,-3);
-}
-
-static SQInteger _system_date(HSQUIRRELVM v)
-{
- time_t t;
- SQInteger it;
- SQInteger format = 'l';
- if(sq_gettop(v) > 1) {
- sq_getinteger(v,2,&it);
- t = it;
- if(sq_gettop(v) > 2) {
- sq_getinteger(v,3,(SQInteger*)&format);
- }
- }
- else {
- time(&t);
- }
- tm *date;
- if(format == 'u')
- date = gmtime(&t);
- else
- date = localtime(&t);
- if(!date)
- return sq_throwerror(v,_SC("crt api failure"));
- sq_newtable(v);
- _set_integer_slot(v, _SC("sec"), date->tm_sec);
- _set_integer_slot(v, _SC("min"), date->tm_min);
- _set_integer_slot(v, _SC("hour"), date->tm_hour);
- _set_integer_slot(v, _SC("day"), date->tm_mday);
- _set_integer_slot(v, _SC("month"), date->tm_mon);
- _set_integer_slot(v, _SC("year"), date->tm_year+1900);
- _set_integer_slot(v, _SC("wday"), date->tm_wday);
- _set_integer_slot(v, _SC("yday"), date->tm_yday);
- return 1;
-}
-
-
-
-#define _DECL_FUNC(name,nparams,pmask) {_SC(#name),_system_##name,nparams,pmask}
-static SQRegFunction systemlib_funcs[]={
- _DECL_FUNC(getenv,2,_SC(".s")),
- _DECL_FUNC(system,2,_SC(".s")),
- _DECL_FUNC(clock,1,NULL),
- _DECL_FUNC(time,1,NULL),
- _DECL_FUNC(date,-1,_SC(".nn")),
- _DECL_FUNC(remove,2,_SC(".s")),
- _DECL_FUNC(rename,3,_SC(".ss")),
- {0,0}
-};
-
-
-SQInteger sqstd_register_systemlib(HSQUIRRELVM v)
-{
- SQInteger i=0;
- while(systemlib_funcs[i].name!=0)
- {
- sq_pushstring(v,systemlib_funcs[i].name,-1);
- sq_newclosure(v,systemlib_funcs[i].f,0);
- sq_setparamscheck(v,systemlib_funcs[i].nparamscheck,systemlib_funcs[i].typemask);
- sq_setnativeclosurename(v,-1,systemlib_funcs[i].name);
- sq_createslot(v,-3);
- i++;
- }
- return 1;
-}
+++ /dev/null
-/*
- see copyright notice in squirrel.h
-*/
-#include "sqpcheader.h"
-#include "sqvm.h"
-#include "sqstring.h"
-#include "sqtable.h"
-#include "sqarray.h"
-#include "sqfuncproto.h"
-#include "sqclosure.h"
-#include "squserdata.h"
-#include "sqcompiler.h"
-#include "sqfuncstate.h"
-#include "sqclass.h"
-
-bool sq_aux_gettypedarg(HSQUIRRELVM v,SQInteger idx,SQObjectType type,SQObjectPtr **o)
-{
- *o = &stack_get(v,idx);
- if(type(**o) != type){
- SQObjectPtr oval = v->PrintObjVal(**o);
- v->Raise_Error(_SC("wrong argument type, expected '%s' got '%.50s'"),IdType2Name(type),_stringval(oval));
- return false;
- }
- return true;
-}
-
-#define _GETSAFE_OBJ(v,idx,type,o) { if(!sq_aux_gettypedarg(v,idx,type,&o)) return SQ_ERROR; }
-
-#define sq_aux_paramscheck(v,count) \
-{ \
- if(sq_gettop(v) < count){ v->Raise_Error(_SC("not enough params in the stack")); return SQ_ERROR; }\
-}
-
-SQInteger sq_aux_throwobject(HSQUIRRELVM v,SQObjectPtr &e)
-{
- v->_lasterror = e;
- return SQ_ERROR;
-}
-
-SQInteger sq_aux_invalidtype(HSQUIRRELVM v,SQObjectType type)
-{
- scsprintf(_ss(v)->GetScratchPad(100), _SC("unexpected type %s"), IdType2Name(type));
- return sq_throwerror(v, _ss(v)->GetScratchPad(-1));
-}
-
-HSQUIRRELVM sq_open(SQInteger initialstacksize)
-{
- SQSharedState *ss;
- SQVM *v;
- sq_new(ss, SQSharedState);
- ss->Init();
- v = (SQVM *)SQ_MALLOC(sizeof(SQVM));
- new (v) SQVM(ss);
- ss->_root_vm = v;
- if(v->Init(NULL, initialstacksize)) {
- return v;
- } else {
- sq_delete(v, SQVM);
- return NULL;
- }
- return v;
-}
-
-HSQUIRRELVM sq_newthread(HSQUIRRELVM friendvm, SQInteger initialstacksize)
-{
- SQSharedState *ss;
- SQVM *v;
- ss=_ss(friendvm);
-
- v= (SQVM *)SQ_MALLOC(sizeof(SQVM));
- new (v) SQVM(ss);
-
- if(v->Init(friendvm, initialstacksize)) {
- friendvm->Push(v);
- return v;
- } else {
- sq_delete(v, SQVM);
- return NULL;
- }
-}
-
-SQInteger sq_getvmstate(HSQUIRRELVM v)
-{
- if(v->_suspended)
- return SQ_VMSTATE_SUSPENDED;
- else {
- if(v->_callsstacksize != 0) return SQ_VMSTATE_RUNNING;
- else return SQ_VMSTATE_IDLE;
- }
-}
-
-void sq_seterrorhandler(HSQUIRRELVM v)
-{
- SQObject o = stack_get(v, -1);
- if(sq_isclosure(o) || sq_isnativeclosure(o) || sq_isnull(o)) {
- v->_errorhandler = o;
- v->Pop();
- }
-}
-
-void sq_setdebughook(HSQUIRRELVM v)
-{
- SQObject o = stack_get(v,-1);
- if(sq_isclosure(o) || sq_isnativeclosure(o) || sq_isnull(o)) {
- v->_debughook = o;
- v->Pop();
- }
-}
-
-void sq_close(HSQUIRRELVM v)
-{
- SQSharedState *ss = _ss(v);
- _thread(ss->_root_vm)->Finalize();
- sq_delete(ss, SQSharedState);
-}
-
-SQRESULT sq_compile(HSQUIRRELVM v,SQLEXREADFUNC read,SQUserPointer p,const SQChar *sourcename,SQBool raiseerror)
-{
- SQObjectPtr o;
- if(Compile(v, read, p, sourcename, o, raiseerror?true:false, _ss(v)->_debuginfo)) {
- v->Push(SQClosure::Create(_ss(v), _funcproto(o)));
- return SQ_OK;
- }
- return SQ_ERROR;
-}
-
-void sq_enabledebuginfo(HSQUIRRELVM v, SQBool enable)
-{
- _ss(v)->_debuginfo = enable?true:false;
-}
-
-void sq_notifyallexceptions(HSQUIRRELVM v, SQBool enable)
-{
- _ss(v)->_notifyallexceptions = enable?true:false;
-}
-
-void sq_addref(HSQUIRRELVM v,HSQOBJECT *po)
-{
- if(!ISREFCOUNTED(type(*po))) return;
-#ifdef NO_GARBAGE_COLLECTOR
- __AddRef(po->_type,po->_unVal);
-#else
- _ss(v)->_refs_table.AddRef(*po);
-#endif
-}
-
-SQBool sq_release(HSQUIRRELVM v,HSQOBJECT *po)
-{
- if(!ISREFCOUNTED(type(*po))) return SQTrue;
-#ifdef NO_GARBAGE_COLLECTOR
- __Release(po->_type,po->_unVal);
- return SQFalse; //the ret val doesn't work(and cannot be fixed)
-#else
- return _ss(v)->_refs_table.Release(*po);
-#endif
-}
-
-const SQChar *sq_objtostring(HSQOBJECT *o)
-{
- if(sq_type(*o) == OT_STRING) {
- return _stringval(*o);
- }
- return NULL;
-}
-
-SQInteger sq_objtointeger(HSQOBJECT *o)
-{
- if(sq_isnumeric(*o)) {
- return tointeger(*o);
- }
- return 0;
-}
-
-SQFloat sq_objtofloat(HSQOBJECT *o)
-{
- if(sq_isnumeric(*o)) {
- return tofloat(*o);
- }
- return 0;
-}
-
-SQBool sq_objtobool(HSQOBJECT *o)
-{
- if(sq_isbool(*o)) {
- return _integer(*o);
- }
- return SQFalse;
-}
-
-void sq_pushnull(HSQUIRRELVM v)
-{
- v->Push(_null_);
-}
-
-void sq_pushstring(HSQUIRRELVM v,const SQChar *s,SQInteger len)
-{
- if(s)
- v->Push(SQObjectPtr(SQString::Create(_ss(v), s, len)));
- else v->Push(_null_);
-}
-
-void sq_pushinteger(HSQUIRRELVM v,SQInteger n)
-{
- v->Push(n);
-}
-
-void sq_pushbool(HSQUIRRELVM v,SQBool b)
-{
- v->Push(b?true:false);
-}
-
-void sq_pushfloat(HSQUIRRELVM v,SQFloat n)
-{
- v->Push(n);
-}
-
-void sq_pushuserpointer(HSQUIRRELVM v,SQUserPointer p)
-{
- v->Push(p);
-}
-
-SQUserPointer sq_newuserdata(HSQUIRRELVM v,SQUnsignedInteger size)
-{
- SQUserData *ud = SQUserData::Create(_ss(v), size);
- v->Push(ud);
- return ud->_val;
-}
-
-void sq_newtable(HSQUIRRELVM v)
-{
- v->Push(SQTable::Create(_ss(v), 0));
-}
-
-void sq_newarray(HSQUIRRELVM v,SQInteger size)
-{
- v->Push(SQArray::Create(_ss(v), size));
-}
-
-SQRESULT sq_newclass(HSQUIRRELVM v,SQBool hasbase)
-{
- SQClass *baseclass = NULL;
- if(hasbase) {
- SQObjectPtr &base = stack_get(v,-1);
- if(type(base) != OT_CLASS)
- return sq_throwerror(v,_SC("invalid base type"));
- baseclass = _class(base);
- }
- SQClass *newclass = SQClass::Create(_ss(v), baseclass);
- if(baseclass) v->Pop();
- v->Push(newclass);
- return SQ_OK;
-}
-
-SQBool sq_instanceof(HSQUIRRELVM v)
-{
- SQObjectPtr &inst = stack_get(v,-1);
- SQObjectPtr &cl = stack_get(v,-2);
- if(type(inst) != OT_INSTANCE || type(cl) != OT_CLASS)
- return sq_throwerror(v,_SC("invalid param type"));
- return _instance(inst)->InstanceOf(_class(cl))?SQTrue:SQFalse;
-}
-
-SQRESULT sq_arrayappend(HSQUIRRELVM v,SQInteger idx)
-{
- sq_aux_paramscheck(v,2);
- SQObjectPtr *arr;
- _GETSAFE_OBJ(v, idx, OT_ARRAY,arr);
- _array(*arr)->Append(v->GetUp(-1));
- v->Pop(1);
- return SQ_OK;
-}
-
-SQRESULT sq_arraypop(HSQUIRRELVM v,SQInteger idx,SQBool pushval)
-{
- sq_aux_paramscheck(v, 1);
- SQObjectPtr *arr;
- _GETSAFE_OBJ(v, idx, OT_ARRAY,arr);
- if(_array(*arr)->Size() > 0) {
- if(pushval != 0){ v->Push(_array(*arr)->Top()); }
- _array(*arr)->Pop();
- return SQ_OK;
- }
- return sq_throwerror(v, _SC("empty array"));
-}
-
-SQRESULT sq_arrayresize(HSQUIRRELVM v,SQInteger idx,SQInteger newsize)
-{
- sq_aux_paramscheck(v,1);
- SQObjectPtr *arr;
- _GETSAFE_OBJ(v, idx, OT_ARRAY,arr);
- if(_array(*arr)->Size() > 0) {
- _array(*arr)->Resize(newsize);
- return SQ_OK;
- }
- return SQ_OK;
-}
-
-
-SQRESULT sq_arrayreverse(HSQUIRRELVM v,SQInteger idx)
-{
- sq_aux_paramscheck(v, 1);
- SQObjectPtr *o;
- _GETSAFE_OBJ(v, idx, OT_ARRAY,o);
- SQArray *arr = _array(*o);
- if(arr->Size() > 0) {
- SQObjectPtr t;
- SQInteger size = arr->Size();
- SQInteger n = size >> 1; size -= 1;
- for(SQInteger i = 0; i < n; i++) {
- t = arr->_values[i];
- arr->_values[i] = arr->_values[size-i];
- arr->_values[size-i] = t;
- }
- return SQ_OK;
- }
- return SQ_OK;
-}
-
-void sq_newclosure(HSQUIRRELVM v,SQFUNCTION func,SQUnsignedInteger nfreevars)
-{
- SQNativeClosure *nc = SQNativeClosure::Create(_ss(v), func);
- nc->_nparamscheck = 0;
- for(SQUnsignedInteger i = 0; i < nfreevars; i++) {
- nc->_outervalues.push_back(v->Top());
- v->Pop();
- }
- v->Push(SQObjectPtr(nc));
-}
-
-SQRESULT sq_getclosureinfo(HSQUIRRELVM v,SQInteger idx,SQUnsignedInteger *nparams,SQUnsignedInteger *nfreevars)
-{
- SQObject o = stack_get(v, idx);
- if(sq_isclosure(o)) {
- SQClosure *c = _closure(o);
- SQFunctionProto *proto = _funcproto(c->_function);
- *nparams = (SQUnsignedInteger)proto->_nparameters;
- *nfreevars = (SQUnsignedInteger)c->_outervalues.size();
- return SQ_OK;
- }
- return sq_throwerror(v,_SC("the object is not a closure"));
-}
-
-SQRESULT sq_setnativeclosurename(HSQUIRRELVM v,SQInteger idx,const SQChar *name)
-{
- SQObject o = stack_get(v, idx);
- if(sq_isnativeclosure(o)) {
- SQNativeClosure *nc = _nativeclosure(o);
- nc->_name = SQString::Create(_ss(v),name);
- return SQ_OK;
- }
- return sq_throwerror(v,_SC("the object is not a nativeclosure"));
-}
-
-SQRESULT sq_setparamscheck(HSQUIRRELVM v,SQInteger nparamscheck,const SQChar *typemask)
-{
- SQObject o = stack_get(v, -1);
- if(!sq_isnativeclosure(o))
- return sq_throwerror(v, _SC("native closure expected"));
- SQNativeClosure *nc = _nativeclosure(o);
- nc->_nparamscheck = nparamscheck;
- if(typemask) {
- SQIntVec res;
- if(!CompileTypemask(res, typemask))
- return sq_throwerror(v, _SC("invalid typemask"));
- nc->_typecheck.copy(res);
- }
- else {
- nc->_typecheck.resize(0);
- }
- if(nparamscheck == SQ_MATCHTYPEMASKSTRING) {
- nc->_nparamscheck = nc->_typecheck.size();
- }
- return SQ_OK;
-}
-
-SQRESULT sq_bindenv(HSQUIRRELVM v,SQInteger idx)
-{
- SQObjectPtr &o = stack_get(v,idx);
- if(!sq_isnativeclosure(o) &&
- !sq_isclosure(o))
- return sq_throwerror(v,_SC("the target is not a closure"));
- SQObjectPtr &env = stack_get(v,-1);
- if(!sq_istable(env) &&
- !sq_isclass(env) &&
- !sq_isinstance(env))
- return sq_throwerror(v,_SC("invalid environment"));
- SQObjectPtr w = _refcounted(env)->GetWeakRef(type(env));
- SQObjectPtr ret;
- if(sq_isclosure(o)) {
- SQClosure *c = _closure(o)->Clone();
- c->_env = w;
- ret = c;
- }
- else { //then must be a native closure
- SQNativeClosure *c = _nativeclosure(o)->Clone();
- c->_env = w;
- ret = c;
- }
- v->Pop();
- v->Push(ret);
- return SQ_OK;
-}
-
-SQRESULT sq_clear(HSQUIRRELVM v,SQInteger idx)
-{
- SQObject &o=stack_get(v,idx);
- switch(type(o)) {
- case OT_TABLE: _table(o)->Clear(); break;
- case OT_ARRAY: _array(o)->Resize(0); break;
- default:
- return sq_throwerror(v, _SC("clear only works on table and array"));
- break;
-
- }
- return SQ_OK;
-}
-
-void sq_pushroottable(HSQUIRRELVM v)
-{
- v->Push(v->_roottable);
-}
-
-void sq_pushregistrytable(HSQUIRRELVM v)
-{
- v->Push(_ss(v)->_registry);
-}
-
-SQRESULT sq_setroottable(HSQUIRRELVM v)
-{
- SQObject o = stack_get(v, -1);
- if(sq_istable(o) || sq_isnull(o)) {
- v->_roottable = o;
- v->Pop();
- return SQ_OK;
- }
- return sq_throwerror(v, _SC("ivalid type"));
-}
-
-void sq_setforeignptr(HSQUIRRELVM v,SQUserPointer p)
-{
- v->_foreignptr = p;
-}
-
-SQUserPointer sq_getforeignptr(HSQUIRRELVM v)
-{
- return v->_foreignptr;
-}
-
-void sq_push(HSQUIRRELVM v,SQInteger idx)
-{
- v->Push(stack_get(v, idx));
-}
-
-SQObjectType sq_gettype(HSQUIRRELVM v,SQInteger idx)
-{
- return type(stack_get(v, idx));
-}
-
-
-void sq_tostring(HSQUIRRELVM v,SQInteger idx)
-{
- SQObjectPtr &o = stack_get(v, idx);
- SQObjectPtr res;
- v->ToString(o,res);
- v->Push(res);
-}
-
-void sq_tobool(HSQUIRRELVM v, SQInteger idx, SQBool *b)
-{
- SQObjectPtr &o = stack_get(v, idx);
- *b = v->IsFalse(o)?SQFalse:SQTrue;
-}
-
-SQRESULT sq_getinteger(HSQUIRRELVM v,SQInteger idx,SQInteger *i)
-{
- SQObjectPtr &o = stack_get(v, idx);
- if(sq_isnumeric(o)) {
- *i = tointeger(o);
- return SQ_OK;
- }
- return SQ_ERROR;
-}
-
-SQRESULT sq_getfloat(HSQUIRRELVM v,SQInteger idx,SQFloat *f)
-{
- SQObjectPtr &o = stack_get(v, idx);
- if(sq_isnumeric(o)) {
- *f = tofloat(o);
- return SQ_OK;
- }
- return SQ_ERROR;
-}
-
-SQRESULT sq_getbool(HSQUIRRELVM v,SQInteger idx,SQBool *b)
-{
- SQObjectPtr &o = stack_get(v, idx);
- if(sq_isbool(o)) {
- *b = _integer(o);
- return SQ_OK;
- }
- return SQ_ERROR;
-}
-
-SQRESULT sq_getstring(HSQUIRRELVM v,SQInteger idx,const SQChar **c)
-{
- SQObjectPtr *o = NULL;
- _GETSAFE_OBJ(v, idx, OT_STRING,o);
- *c = _stringval(*o);
- return SQ_OK;
-}
-
-SQRESULT sq_getthread(HSQUIRRELVM v,SQInteger idx,HSQUIRRELVM *thread)
-{
- SQObjectPtr *o = NULL;
- _GETSAFE_OBJ(v, idx, OT_THREAD,o);
- *thread = _thread(*o);
- return SQ_OK;
-}
-
-SQRESULT sq_clone(HSQUIRRELVM v,SQInteger idx)
-{
- SQObjectPtr &o = stack_get(v,idx);
- v->Push(_null_);
- if(!v->Clone(o, stack_get(v, -1))){
- v->Pop();
- return sq_aux_invalidtype(v, type(o));
- }
- return SQ_OK;
-}
-
-SQInteger sq_getsize(HSQUIRRELVM v, SQInteger idx)
-{
- SQObjectPtr &o = stack_get(v, idx);
- SQObjectType type = type(o);
- switch(type) {
- case OT_STRING: return _string(o)->_len;
- case OT_TABLE: return _table(o)->CountUsed();
- case OT_ARRAY: return _array(o)->Size();
- case OT_USERDATA: return _userdata(o)->_size;
- default:
- return sq_aux_invalidtype(v, type);
- }
-}
-
-SQRESULT sq_getuserdata(HSQUIRRELVM v,SQInteger idx,SQUserPointer *p,SQUserPointer *typetag)
-{
- SQObjectPtr *o = NULL;
- _GETSAFE_OBJ(v, idx, OT_USERDATA,o);
- (*p) = _userdataval(*o);
- if(typetag) *typetag = _userdata(*o)->_typetag;
- return SQ_OK;
-}
-
-SQRESULT sq_settypetag(HSQUIRRELVM v,SQInteger idx,SQUserPointer typetag)
-{
- SQObjectPtr &o = stack_get(v,idx);
- switch(type(o)) {
- case OT_USERDATA: _userdata(o)->_typetag = typetag; break;
- case OT_CLASS: _class(o)->_typetag = typetag; break;
- default: return sq_throwerror(v,_SC("invalid object type"));
- }
- return SQ_OK;
-}
-
-SQRESULT sq_getobjtypetag(HSQOBJECT *o,SQUserPointer * typetag)
-{
- switch(type(*o)) {
- case OT_INSTANCE: *typetag = _instance(*o)->_class->_typetag; break;
- case OT_USERDATA: *typetag = _userdata(*o)->_typetag; break;
- case OT_CLASS: *typetag = _class(*o)->_typetag; break;
- default: return SQ_ERROR;
- }
- return SQ_OK;
-}
-
-SQRESULT sq_gettypetag(HSQUIRRELVM v,SQInteger idx,SQUserPointer *typetag)
-{
- SQObjectPtr &o = stack_get(v,idx);
- if(SQ_FAILED(sq_getobjtypetag(&o,typetag)))
- return sq_throwerror(v,_SC("invalid object type"));
- return SQ_OK;
-}
-
-SQRESULT sq_getuserpointer(HSQUIRRELVM v, SQInteger idx, SQUserPointer *p)
-{
- SQObjectPtr *o = NULL;
- _GETSAFE_OBJ(v, idx, OT_USERPOINTER,o);
- (*p) = _userpointer(*o);
- return SQ_OK;
-}
-
-SQRESULT sq_setinstanceup(HSQUIRRELVM v, SQInteger idx, SQUserPointer p)
-{
- SQObjectPtr &o = stack_get(v,idx);
- if(type(o) != OT_INSTANCE) return sq_throwerror(v,_SC("the object is not a class instance"));
- _instance(o)->_userpointer = p;
- return SQ_OK;
-}
-
-SQRESULT sq_setclassudsize(HSQUIRRELVM v, SQInteger idx, SQInteger udsize)
-{
- SQObjectPtr &o = stack_get(v,idx);
- if(type(o) != OT_CLASS) return sq_throwerror(v,_SC("the object is not a class"));
- if(_class(o)->_locked) return sq_throwerror(v,_SC("the class is locked"));
- _class(o)->_udsize = udsize;
- return SQ_OK;
-}
-
-
-SQRESULT sq_getinstanceup(HSQUIRRELVM v, SQInteger idx, SQUserPointer *p,SQUserPointer typetag)
-{
- SQObjectPtr &o = stack_get(v,idx);
- if(type(o) != OT_INSTANCE) return sq_throwerror(v,_SC("the object is not a class instance"));
- (*p) = _instance(o)->_userpointer;
- if(typetag != 0) {
- SQClass *cl = _instance(o)->_class;
- do{
- if(cl->_typetag == typetag)
- return SQ_OK;
- cl = cl->_base;
- }while(cl != NULL);
- return sq_throwerror(v,_SC("invalid type tag"));
- }
- return SQ_OK;
-}
-
-SQInteger sq_gettop(HSQUIRRELVM v)
-{
- return (v->_top) - v->_stackbase;
-}
-
-void sq_settop(HSQUIRRELVM v, SQInteger newtop)
-{
- SQInteger top = sq_gettop(v);
- if(top > newtop)
- sq_pop(v, top - newtop);
- else
- while(top < newtop) sq_pushnull(v);
-}
-
-void sq_pop(HSQUIRRELVM v, SQInteger nelemstopop)
-{
- assert(v->_top >= nelemstopop);
- v->Pop(nelemstopop);
-}
-
-void sq_poptop(HSQUIRRELVM v)
-{
- assert(v->_top >= 1);
- v->Pop();
-}
-
-
-void sq_remove(HSQUIRRELVM v, SQInteger idx)
-{
- v->Remove(idx);
-}
-
-SQInteger sq_cmp(HSQUIRRELVM v)
-{
- SQInteger res;
- v->ObjCmp(stack_get(v, -1), stack_get(v, -2),res);
- return res;
-}
-
-SQRESULT sq_newslot(HSQUIRRELVM v, SQInteger idx, SQBool bstatic)
-{
- sq_aux_paramscheck(v, 3);
- SQObjectPtr &self = stack_get(v, idx);
- if(type(self) == OT_TABLE || type(self) == OT_CLASS) {
- SQObjectPtr &key = v->GetUp(-2);
- if(type(key) == OT_NULL) return sq_throwerror(v, _SC("null is not a valid key"));
- v->NewSlot(self, key, v->GetUp(-1),bstatic?true:false);
- v->Pop(2);
- }
- return SQ_OK;
-}
-
-SQRESULT sq_deleteslot(HSQUIRRELVM v,SQInteger idx,SQBool pushval)
-{
- sq_aux_paramscheck(v, 2);
- SQObjectPtr *self;
- _GETSAFE_OBJ(v, idx, OT_TABLE,self);
- SQObjectPtr &key = v->GetUp(-1);
- if(type(key) == OT_NULL) return sq_throwerror(v, _SC("null is not a valid key"));
- SQObjectPtr res;
- if(!v->DeleteSlot(*self, key, res)){
- return SQ_ERROR;
- }
- if(pushval) v->GetUp(-1) = res;
- else v->Pop(1);
- return SQ_OK;
-}
-
-SQRESULT sq_set(HSQUIRRELVM v,SQInteger idx)
-{
- SQObjectPtr &self = stack_get(v, idx);
- if(v->Set(self, v->GetUp(-2), v->GetUp(-1),false)) {
- v->Pop(2);
- return SQ_OK;
- }
- v->Raise_IdxError(v->GetUp(-2));return SQ_ERROR;
-}
-
-SQRESULT sq_rawset(HSQUIRRELVM v,SQInteger idx)
-{
- SQObjectPtr &self = stack_get(v, idx);
- if(type(v->GetUp(-2)) == OT_NULL) return sq_throwerror(v, _SC("null key"));
- switch(type(self)) {
- case OT_TABLE:
- _table(self)->NewSlot(v->GetUp(-2), v->GetUp(-1));
- v->Pop(2);
- return SQ_OK;
- break;
- case OT_CLASS:
- _class(self)->NewSlot(_ss(v), v->GetUp(-2), v->GetUp(-1),false);
- v->Pop(2);
- return SQ_OK;
- break;
- case OT_INSTANCE:
- if(_instance(self)->Set(v->GetUp(-2), v->GetUp(-1))) {
- v->Pop(2);
- return SQ_OK;
- }
- break;
- case OT_ARRAY:
- if(v->Set(self, v->GetUp(-2), v->GetUp(-1),false)) {
- v->Pop(2);
- return SQ_OK;
- }
- break;
- default:
- v->Pop(2);
- return sq_throwerror(v, _SC("rawset works only on array/table/class and instance"));
- }
- v->Raise_IdxError(v->GetUp(-2));return SQ_ERROR;
-}
-
-SQRESULT sq_setdelegate(HSQUIRRELVM v,SQInteger idx)
-{
- SQObjectPtr &self = stack_get(v, idx);
- SQObjectPtr &mt = v->GetUp(-1);
- SQObjectType type = type(self);
- switch(type) {
- case OT_TABLE:
- if(type(mt) == OT_TABLE) {
- if(!_table(self)->SetDelegate(_table(mt))) return sq_throwerror(v, _SC("delagate cycle")); v->Pop();}
- else if(type(mt)==OT_NULL) {
- _table(self)->SetDelegate(NULL); v->Pop(); }
- else return sq_aux_invalidtype(v,type);
- break;
- case OT_USERDATA:
- if(type(mt)==OT_TABLE) {
- _userdata(self)->SetDelegate(_table(mt)); v->Pop(); }
- else if(type(mt)==OT_NULL) {
- _userdata(self)->SetDelegate(NULL); v->Pop(); }
- else return sq_aux_invalidtype(v, type);
- break;
- default:
- return sq_aux_invalidtype(v, type);
- break;
- }
- return SQ_OK;
-}
-
-SQRESULT sq_rawdeleteslot(HSQUIRRELVM v,SQInteger idx,SQBool pushval)
-{
- sq_aux_paramscheck(v, 2);
- SQObjectPtr *self;
- _GETSAFE_OBJ(v, idx, OT_TABLE,self);
- SQObjectPtr &key = v->GetUp(-1);
- SQObjectPtr t;
- if(_table(*self)->Get(key,t)) {
- _table(*self)->Remove(key);
- }
- if(pushval != 0)
- if(pushval) v->GetUp(-1) = t;
- else
- v->Pop(1);
- return SQ_OK;
-}
-
-SQRESULT sq_getdelegate(HSQUIRRELVM v,SQInteger idx)
-{
- SQObjectPtr &self=stack_get(v,idx);
- switch(type(self)){
- case OT_TABLE:
- case OT_USERDATA:
- if(!_delegable(self)->_delegate){
- v->Push(_null_);
- break;
- }
- v->Push(SQObjectPtr(_delegable(self)->_delegate));
- break;
- default: return sq_throwerror(v,_SC("wrong type")); break;
- }
- return SQ_OK;
-
-}
-
-SQRESULT sq_get(HSQUIRRELVM v,SQInteger idx)
-{
- SQObjectPtr &self=stack_get(v,idx);
- if(v->Get(self,v->GetUp(-1),v->GetUp(-1),false,false))
- return SQ_OK;
- v->Pop(1);
- return sq_throwerror(v,_SC("the index doesn't exist"));
-}
-
-SQRESULT sq_rawget(HSQUIRRELVM v,SQInteger idx)
-{
- SQObjectPtr &self=stack_get(v,idx);
- switch(type(self)) {
- case OT_TABLE:
- if(_table(self)->Get(v->GetUp(-1),v->GetUp(-1)))
- return SQ_OK;
- break;
- case OT_CLASS:
- if(_class(self)->Get(v->GetUp(-1),v->GetUp(-1)))
- return SQ_OK;
- break;
- case OT_INSTANCE:
- if(_instance(self)->Get(v->GetUp(-1),v->GetUp(-1)))
- return SQ_OK;
- break;
- case OT_ARRAY:
- if(v->Get(self,v->GetUp(-1),v->GetUp(-1),false,false))
- return SQ_OK;
- break;
- default:
- v->Pop(1);
- return sq_throwerror(v,_SC("rawget works only on array/table/instance and class"));
- }
- v->Pop(1);
- return sq_throwerror(v,_SC("the index doesn't exist"));
-}
-
-SQRESULT sq_getstackobj(HSQUIRRELVM v,SQInteger idx,HSQOBJECT *po)
-{
- *po=stack_get(v,idx);
- return SQ_OK;
-}
-
-const SQChar *sq_getlocal(HSQUIRRELVM v,SQUnsignedInteger level,SQUnsignedInteger idx)
-{
- SQUnsignedInteger cstksize=v->_callsstacksize;
- SQUnsignedInteger lvl=(cstksize-level)-1;
- SQInteger stackbase=v->_stackbase;
- if(lvl<cstksize){
- for(SQUnsignedInteger i=0;i<level;i++){
- SQVM::CallInfo &ci=v->_callsstack[(cstksize-i)-1];
- stackbase-=ci._prevstkbase;
- }
- SQVM::CallInfo &ci=v->_callsstack[lvl];
- if(type(ci._closure)!=OT_CLOSURE)
- return NULL;
- SQClosure *c=_closure(ci._closure);
- SQFunctionProto *func=_funcproto(c->_function);
- if(func->_noutervalues > (SQInteger)idx) {
- v->Push(c->_outervalues[idx]);
- return _stringval(func->_outervalues[idx]._name);
- }
- idx -= func->_noutervalues;
- return func->GetLocal(v,stackbase,idx,(SQInteger)(ci._ip-func->_instructions)-1);
- }
- return NULL;
-}
-
-void sq_pushobject(HSQUIRRELVM v,HSQOBJECT obj)
-{
- v->Push(SQObjectPtr(obj));
-}
-
-void sq_resetobject(HSQOBJECT *po)
-{
- po->_unVal.pUserPointer=NULL;po->_type=OT_NULL;
-}
-
-SQRESULT sq_throwerror(HSQUIRRELVM v,const SQChar *err)
-{
- v->_lasterror=SQString::Create(_ss(v),err);
- return -1;
-}
-
-void sq_reseterror(HSQUIRRELVM v)
-{
- v->_lasterror = _null_;
-}
-
-void sq_getlasterror(HSQUIRRELVM v)
-{
- v->Push(v->_lasterror);
-}
-
-void sq_reservestack(HSQUIRRELVM v,SQInteger nsize)
-{
- if (((SQUnsignedInteger)v->_top + nsize) > v->_stack.size()) {
- v->_stack.resize(v->_stack.size() + ((v->_top + nsize) - v->_stack.size()));
- }
-}
-
-SQRESULT sq_resume(HSQUIRRELVM v,SQBool retval,SQBool raiseerror)
-{
- if(type(v->GetUp(-1))==OT_GENERATOR){
- v->Push(_null_); //retval
- if(!v->Execute(v->GetUp(-2),v->_top,0,v->_top,v->GetUp(-1),raiseerror,SQVM::ET_RESUME_GENERATOR))
- {v->Raise_Error(v->_lasterror); return SQ_ERROR;}
- if(!retval)
- v->Pop();
- return SQ_OK;
- }
- return sq_throwerror(v,_SC("only generators can be resumed"));
-}
-
-SQRESULT sq_call(HSQUIRRELVM v,SQInteger params,SQBool retval,SQBool raiseerror)
-{
- SQObjectPtr res;
- if(v->Call(v->GetUp(-(params+1)),params,v->_top-params,res,raiseerror?true:false)){
- v->Pop(params);//pop closure and args
- if(retval){
- v->Push(res); return SQ_OK;
- }
- return SQ_OK;
- }
- else {
- v->Pop(params);
- return SQ_ERROR;
- }
- if(!v->_suspended)
- v->Pop(params);
- return sq_throwerror(v,_SC("call failed"));
-}
-
-SQRESULT sq_suspendvm(HSQUIRRELVM v)
-{
- return v->Suspend();
-}
-
-SQRESULT sq_wakeupvm(HSQUIRRELVM v,SQBool wakeupret,SQBool retval,SQBool raiseerror)
-{
- SQObjectPtr ret;
- if(!v->_suspended)
- return sq_throwerror(v,_SC("cannot resume a vm that is not running any code"));
- if(wakeupret) {
- v->GetAt(v->_stackbase+v->_suspended_target)=v->GetUp(-1); //retval
- v->Pop();
- } else v->GetAt(v->_stackbase+v->_suspended_target)=_null_;
- if(!v->Execute(_null_,v->_top,-1,-1,ret,raiseerror,SQVM::ET_RESUME_VM))
- return SQ_ERROR;
- if(sq_getvmstate(v) == SQ_VMSTATE_IDLE) {
- while (v->_top > 1) v->_stack[--v->_top] = _null_;
- }
- if(retval)
- v->Push(ret);
- return SQ_OK;
-}
-
-void sq_setreleasehook(HSQUIRRELVM v,SQInteger idx,SQRELEASEHOOK hook)
-{
- if(sq_gettop(v) >= 1){
- SQObjectPtr &ud=stack_get(v,idx);
- switch( type(ud) ) {
- case OT_USERDATA: _userdata(ud)->_hook = hook; break;
- case OT_INSTANCE: _instance(ud)->_hook = hook; break;
- case OT_CLASS: _class(ud)->_hook = hook; break;
- default: break; //shutup compiler
- }
- }
-}
-
-void sq_setcompilererrorhandler(HSQUIRRELVM v,SQCOMPILERERROR f)
-{
- _ss(v)->_compilererrorhandler = f;
-}
-
-SQRESULT sq_writeclosure(HSQUIRRELVM v,SQWRITEFUNC w,SQUserPointer up)
-{
- SQObjectPtr *o = NULL;
- _GETSAFE_OBJ(v, -1, OT_CLOSURE,o);
- unsigned short tag = SQ_BYTECODE_STREAM_TAG;
- if(w(up,&tag,2) != 2)
- return sq_throwerror(v,_SC("io error"));
- if(!_closure(*o)->Save(v,up,w))
- return SQ_ERROR;
- return SQ_OK;
-}
-
-SQRESULT sq_readclosure(HSQUIRRELVM v,SQREADFUNC r,SQUserPointer up)
-{
- SQObjectPtr closure;
-
- unsigned short tag;
- if(r(up,&tag,2) != 2)
- return sq_throwerror(v,_SC("io error"));
- if(tag != SQ_BYTECODE_STREAM_TAG)
- return sq_throwerror(v,_SC("invalid stream"));
- if(!SQClosure::Load(v,up,r,closure))
- return SQ_ERROR;
- v->Push(closure);
- return SQ_OK;
-}
-
-SQChar *sq_getscratchpad(HSQUIRRELVM v,SQInteger minsize)
-{
- return _ss(v)->GetScratchPad(minsize);
-}
-
-SQInteger sq_collectgarbage(HSQUIRRELVM v)
-{
-#ifndef NO_GARBAGE_COLLECTOR
- return _ss(v)->CollectGarbage(v);
-#else
- return -1;
-#endif
-}
-
-const SQChar *sq_getfreevariable(HSQUIRRELVM v,SQInteger idx,SQUnsignedInteger nval)
-{
- SQObjectPtr &self = stack_get(v,idx);
- const SQChar *name = NULL;
- if(type(self) == OT_CLOSURE) {
- if(_closure(self)->_outervalues.size()>nval) {
- v->Push(_closure(self)->_outervalues[nval]);
- SQFunctionProto *fp = _funcproto(_closure(self)->_function);
- SQOuterVar &ov = fp->_outervalues[nval];
- name = _stringval(ov._name);
- }
- }
- return name;
-}
-
-SQRESULT sq_setfreevariable(HSQUIRRELVM v,SQInteger idx,SQUnsignedInteger nval)
-{
- SQObjectPtr &self=stack_get(v,idx);
- switch(type(self))
- {
- case OT_CLOSURE:
- if(_closure(self)->_outervalues.size()>nval){
- _closure(self)->_outervalues[nval]=stack_get(v,-1);
- }
- else return sq_throwerror(v,_SC("invalid free var index"));
- break;
- case OT_NATIVECLOSURE:
- if(_nativeclosure(self)->_outervalues.size()>nval){
- _nativeclosure(self)->_outervalues[nval]=stack_get(v,-1);
- }
- else return sq_throwerror(v,_SC("invalid free var index"));
- break;
- default:
- return sq_aux_invalidtype(v,type(self));
- }
- v->Pop(1);
- return SQ_OK;
-}
-
-SQRESULT sq_setattributes(HSQUIRRELVM v,SQInteger idx)
-{
- SQObjectPtr *o = NULL;
- _GETSAFE_OBJ(v, idx, OT_CLASS,o);
- SQObjectPtr &key = stack_get(v,-2);
- SQObjectPtr &val = stack_get(v,-1);
- SQObjectPtr attrs;
- if(type(key) == OT_NULL) {
- attrs = _class(*o)->_attributes;
- _class(*o)->_attributes = val;
- v->Pop(2);
- v->Push(attrs);
- return SQ_OK;
- }else if(_class(*o)->GetAttributes(key,attrs)) {
- _class(*o)->SetAttributes(key,val);
- v->Pop(2);
- v->Push(attrs);
- return SQ_OK;
- }
- return sq_throwerror(v,_SC("wrong index"));
-}
-
-SQRESULT sq_getattributes(HSQUIRRELVM v,SQInteger idx)
-{
- SQObjectPtr *o = NULL;
- _GETSAFE_OBJ(v, idx, OT_CLASS,o);
- SQObjectPtr &key = stack_get(v,-1);
- SQObjectPtr attrs;
- if(type(key) == OT_NULL) {
- attrs = _class(*o)->_attributes;
- v->Pop();
- v->Push(attrs);
- return SQ_OK;
- }
- else if(_class(*o)->GetAttributes(key,attrs)) {
- v->Pop();
- v->Push(attrs);
- return SQ_OK;
- }
- return sq_throwerror(v,_SC("wrong index"));
-}
-
-SQRESULT sq_getbase(HSQUIRRELVM v,SQInteger idx)
-{
- SQObjectPtr *o = NULL;
- _GETSAFE_OBJ(v, idx, OT_CLASS,o);
- if(_class(*o)->_base)
- v->Push(SQObjectPtr(_class(*o)->_base));
- else
- v->Push(_null_);
- return SQ_OK;
-}
-
-SQRESULT sq_getclass(HSQUIRRELVM v,SQInteger idx)
-{
- SQObjectPtr *o = NULL;
- _GETSAFE_OBJ(v, idx, OT_INSTANCE,o);
- v->Push(SQObjectPtr(_instance(*o)->_class));
- return SQ_OK;
-}
-
-SQRESULT sq_createinstance(HSQUIRRELVM v,SQInteger idx)
-{
- SQObjectPtr *o = NULL;
- _GETSAFE_OBJ(v, idx, OT_CLASS,o);
- v->Push(_class(*o)->CreateInstance());
- return SQ_OK;
-}
-
-void sq_weakref(HSQUIRRELVM v,SQInteger idx)
-{
- SQObject &o=stack_get(v,idx);
- if(ISREFCOUNTED(type(o))) {
- v->Push(_refcounted(o)->GetWeakRef(type(o)));
- return;
- }
- v->Push(o);
-}
-
-SQRESULT sq_getweakrefval(HSQUIRRELVM v,SQInteger idx)
-{
- SQObjectPtr &o = stack_get(v,idx);
- if(type(o) != OT_WEAKREF) {
- return sq_throwerror(v,_SC("the object must be a weakref"));
- }
- v->Push(_weakref(o)->_obj);
- return SQ_OK;
-}
-
-SQRESULT sq_getdefaultdelegate(HSQUIRRELVM v,SQObjectType t)
-{
- SQSharedState *ss = _ss(v);
- switch(t) {
- case OT_TABLE: v->Push(ss->_table_default_delegate); break;
- case OT_ARRAY: v->Push(ss->_array_default_delegate); break;
- case OT_STRING: v->Push(ss->_string_default_delegate); break;
- case OT_INTEGER: case OT_FLOAT: v->Push(ss->_number_default_delegate); break;
- case OT_GENERATOR: v->Push(ss->_generator_default_delegate); break;
- case OT_CLOSURE: case OT_NATIVECLOSURE: v->Push(ss->_closure_default_delegate); break;
- case OT_THREAD: v->Push(ss->_thread_default_delegate); break;
- case OT_CLASS: v->Push(ss->_class_default_delegate); break;
- case OT_INSTANCE: v->Push(ss->_instance_default_delegate); break;
- case OT_WEAKREF: v->Push(ss->_weakref_default_delegate); break;
- default: return sq_throwerror(v,_SC("the type doesn't have a default delegate"));
- }
- return SQ_OK;
-}
-
-SQRESULT sq_next(HSQUIRRELVM v,SQInteger idx)
-{
- SQObjectPtr o=stack_get(v,idx),&refpos = stack_get(v,-1),realkey,val;
- if(type(o) == OT_GENERATOR) {
- return sq_throwerror(v,_SC("cannot iterate a generator"));
- }
- int faketojump;
- if(!v->FOREACH_OP(o,realkey,val,refpos,0,666,faketojump))
- return SQ_ERROR;
- if(faketojump != 666) {
- v->Push(realkey);
- v->Push(val);
- return SQ_OK;
- }
- return SQ_ERROR;
-}
-
-struct BufState{
- const SQChar *buf;
- SQInteger ptr;
- SQInteger size;
-};
-
-SQInteger buf_lexfeed(SQUserPointer file)
-{
- BufState *buf=(BufState*)file;
- if(buf->size<(buf->ptr+1))
- return 0;
- return buf->buf[buf->ptr++];
-}
-
-SQRESULT sq_compilebuffer(HSQUIRRELVM v,const SQChar *s,SQInteger size,const SQChar *sourcename,SQBool raiseerror) {
- BufState buf;
- buf.buf = s;
- buf.size = size;
- buf.ptr = 0;
- return sq_compile(v, buf_lexfeed, &buf, sourcename, raiseerror);
-}
-
-void sq_move(HSQUIRRELVM dest,HSQUIRRELVM src,SQInteger idx)
-{
- dest->Push(stack_get(src,idx));
-}
-
-void sq_setprintfunc(HSQUIRRELVM v, SQPRINTFUNCTION printfunc)
-{
- _ss(v)->_printfunc = printfunc;
-}
-
-SQPRINTFUNCTION sq_getprintfunc(HSQUIRRELVM v)
-{
- return _ss(v)->_printfunc;
-}
-
-void *sq_malloc(SQUnsignedInteger size)
-{
- return SQ_MALLOC(size);
-}
-
-void *sq_realloc(void* p,SQUnsignedInteger oldsize,SQUnsignedInteger newsize)
-{
- return SQ_REALLOC(p,oldsize,newsize);
-}
-
-void sq_free(void *p,SQUnsignedInteger size)
-{
- SQ_FREE(p,size);
-}
+++ /dev/null
-/* see copyright notice in squirrel.h */
-#ifndef _SQARRAY_H_
-#define _SQARRAY_H_
-
-struct SQArray : public CHAINABLE_OBJ
-{
-private:
- SQArray(SQSharedState *ss,SQInteger nsize){_values.resize(nsize); INIT_CHAIN();ADD_TO_CHAIN(&_ss(this)->_gc_chain,this);}
- ~SQArray()
- {
- REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain,this);
- }
-public:
- static SQArray* Create(SQSharedState *ss,SQInteger nInitialSize){
- SQArray *newarray=(SQArray*)SQ_MALLOC(sizeof(SQArray));
- new (newarray) SQArray(ss,nInitialSize);
- return newarray;
- }
-#ifndef NO_GARBAGE_COLLECTOR
- void Mark(SQCollectable **chain);
-#endif
- void Finalize(){
- _values.resize(0);
- }
- bool Get(const SQInteger nidx,SQObjectPtr &val)
- {
- if(nidx>=0 && nidx<(SQInteger)_values.size()){
- SQObjectPtr &o = _values[nidx];
- val = _realval(o);
- return true;
- }
- else return false;
- }
- bool Set(const SQInteger nidx,const SQObjectPtr &val)
- {
- if(nidx>=0 && nidx<(SQInteger)_values.size()){
- _values[nidx]=val;
- return true;
- }
- else return false;
- }
- SQInteger Next(const SQObjectPtr &refpos,SQObjectPtr &outkey,SQObjectPtr &outval)
- {
- SQUnsignedInteger idx=TranslateIndex(refpos);
- while(idx<_values.size()){
- //first found
- outkey=(SQInteger)idx;
- SQObjectPtr &o = _values[idx];
- outval = _realval(o);
- //return idx for the next iteration
- return ++idx;
- }
- //nothing to iterate anymore
- return -1;
- }
- SQArray *Clone(){SQArray *anew=Create(_opt_ss(this),Size()); anew->_values.copy(_values); return anew; }
- SQInteger Size() const {return _values.size();}
- void Resize(SQInteger size,SQObjectPtr &fill = _null_) { _values.resize(size,fill); ShrinkIfNeeded(); }
- void Reserve(SQInteger size) { _values.reserve(size); }
- void Append(const SQObject &o){_values.push_back(o);}
- void Extend(const SQArray *a);
- SQObjectPtr &Top(){return _values.top();}
- void Pop(){_values.pop_back(); ShrinkIfNeeded(); }
- void Insert(const SQObject& idx,const SQObject &val){_values.insert((SQUnsignedInteger)tointeger(idx),val);}
- void ShrinkIfNeeded() {
- if(_values.size() <= _values.capacity()>>2) //shrink the array
- _values.shrinktofit();
- }
- void Remove(SQUnsignedInteger idx){
- _values.remove(idx);
- ShrinkIfNeeded();
- }
- void Release()
- {
- sq_delete(this,SQArray);
- }
- SQObjectPtrVec _values;
-};
-#endif //_SQARRAY_H_
+++ /dev/null
-/*
- see copyright notice in squirrel.h
-*/
-#include "sqpcheader.h"
-#include "sqvm.h"
-#include "sqstring.h"
-#include "sqtable.h"
-#include "sqarray.h"
-#include "sqfuncproto.h"
-#include "sqclosure.h"
-#include "sqclass.h"
-#include <stdlib.h>
-#include <stdarg.h>
-#include <ctype.h>
-
-bool str2num(const SQChar *s,SQObjectPtr &res)
-{
- SQChar *end;
- if(scstrstr(s,_SC("."))){
- SQFloat r = SQFloat(scstrtod(s,&end));
- if(s == end) return false;
- res = r;
- return true;
- }
- else{
- SQInteger r = SQInteger(scstrtol(s,&end,10));
- if(s == end) return false;
- res = r;
- return true;
- }
-}
-
-static SQInteger base_dummy(HSQUIRRELVM v)
-{
- return 0;
-}
-
-#ifndef NO_GARBAGE_COLLECTOR
-static SQInteger base_collectgarbage(HSQUIRRELVM v)
-{
- sq_pushinteger(v, sq_collectgarbage(v));
- return 1;
-}
-#endif
-
-static SQInteger base_getroottable(HSQUIRRELVM v)
-{
- v->Push(v->_roottable);
- return 1;
-}
-
-static SQInteger base_setroottable(HSQUIRRELVM v)
-{
- SQObjectPtr &o=stack_get(v,2);
- if(SQ_FAILED(sq_setroottable(v))) return SQ_ERROR;
- v->Push(o);
- return 1;
-}
-
-static SQInteger base_seterrorhandler(HSQUIRRELVM v)
-{
- sq_seterrorhandler(v);
- return 0;
-}
-
-static SQInteger base_setdebughook(HSQUIRRELVM v)
-{
- sq_setdebughook(v);
- return 0;
-}
-
-static SQInteger base_enabledebuginfo(HSQUIRRELVM v)
-{
- SQObjectPtr &o=stack_get(v,2);
- sq_enabledebuginfo(v,(type(o) != OT_NULL)?1:0);
- return 0;
-}
-
-static SQInteger base_getstackinfos(HSQUIRRELVM v)
-{
- SQInteger level;
- SQStackInfos si;
- SQInteger seq = 0;
- const SQChar *name = NULL;
- sq_getinteger(v, -1, &level);
- if (SQ_SUCCEEDED(sq_stackinfos(v, level, &si)))
- {
- const SQChar *fn = _SC("unknown");
- const SQChar *src = _SC("unknown");
- if(si.funcname)fn = si.funcname;
- if(si.source)src = si.source;
- sq_newtable(v);
- sq_pushstring(v, _SC("func"), -1);
- sq_pushstring(v, fn, -1);
- sq_createslot(v, -3);
- sq_pushstring(v, _SC("src"), -1);
- sq_pushstring(v, src, -1);
- sq_createslot(v, -3);
- sq_pushstring(v, _SC("line"), -1);
- sq_pushinteger(v, si.line);
- sq_createslot(v, -3);
- sq_pushstring(v, _SC("locals"), -1);
- sq_newtable(v);
- seq=0;
- while ((name = sq_getlocal(v, level, seq))) {
- sq_pushstring(v, name, -1);
- sq_push(v, -2);
- sq_createslot(v, -4);
- sq_pop(v, 1);
- seq++;
- }
- sq_createslot(v, -3);
- return 1;
- }
-
- return 0;
-}
-
-static SQInteger base_assert(HSQUIRRELVM v)
-{
- if(v->IsFalse(stack_get(v,2))){
- return sq_throwerror(v,_SC("assertion failed"));
- }
- return 0;
-}
-
-static SQInteger get_slice_params(HSQUIRRELVM v,SQInteger &sidx,SQInteger &eidx,SQObjectPtr &o)
-{
- SQInteger top = sq_gettop(v);
- sidx=0;
- eidx=0;
- o=stack_get(v,1);
- SQObjectPtr &start=stack_get(v,2);
- if(type(start)!=OT_NULL && sq_isnumeric(start)){
- sidx=tointeger(start);
- }
- if(top>2){
- SQObjectPtr &end=stack_get(v,3);
- if(sq_isnumeric(end)){
- eidx=tointeger(end);
- }
- }
- else {
- eidx = sq_getsize(v,1);
- }
- return 1;
-}
-
-static SQInteger base_print(HSQUIRRELVM v)
-{
- const SQChar *str;
- sq_tostring(v,2);
- sq_getstring(v,-1,&str);
- if(_ss(v)->_printfunc) _ss(v)->_printfunc(v,_SC("%s"),str);
- return 0;
-}
-
-static SQInteger base_compilestring(HSQUIRRELVM v)
-{
- SQInteger nargs=sq_gettop(v);
- const SQChar *src=NULL,*name=_SC("unnamedbuffer");
- SQInteger size;
- sq_getstring(v,2,&src);
- size=sq_getsize(v,2);
- if(nargs>2){
- sq_getstring(v,3,&name);
- }
- if(SQ_SUCCEEDED(sq_compilebuffer(v,src,size,name,SQFalse)))
- return 1;
- else
- return SQ_ERROR;
-}
-
-static SQInteger base_newthread(HSQUIRRELVM v)
-{
- SQObjectPtr &func = stack_get(v,2);
- SQInteger stksize = (_funcproto(_closure(func)->_function)->_stacksize << 1) +2;
- HSQUIRRELVM newv = sq_newthread(v, (stksize < MIN_STACK_OVERHEAD + 2)? MIN_STACK_OVERHEAD + 2 : stksize);
- sq_move(newv,v,-2);
- return 1;
-}
-
-static SQInteger base_suspend(HSQUIRRELVM v)
-{
- return sq_suspendvm(v);
-}
-
-static SQInteger base_array(HSQUIRRELVM v)
-{
- SQArray *a;
- SQObject &size = stack_get(v,2);
- if(sq_gettop(v) > 2) {
- a = SQArray::Create(_ss(v),0);
- a->Resize(tointeger(size),stack_get(v,3));
- }
- else {
- a = SQArray::Create(_ss(v),tointeger(size));
- }
- v->Push(a);
- return 1;
-}
-
-static SQInteger base_type(HSQUIRRELVM v)
-{
- SQObjectPtr &o = stack_get(v,2);
- v->Push(SQString::Create(_ss(v),GetTypeName(o),-1));
- return 1;
-}
-
-static SQRegFunction base_funcs[]={
- //generic
- {_SC("seterrorhandler"),base_seterrorhandler,2, NULL},
- {_SC("setdebughook"),base_setdebughook,2, NULL},
- {_SC("enabledebuginfo"),base_enabledebuginfo,2, NULL},
- {_SC("getstackinfos"),base_getstackinfos,2, _SC(".n")},
- {_SC("getroottable"),base_getroottable,1, NULL},
- {_SC("setroottable"),base_setroottable,2, NULL},
- {_SC("assert"),base_assert,2, NULL},
- {_SC("print"),base_print,2, NULL},
- {_SC("compilestring"),base_compilestring,-2, _SC(".ss")},
- {_SC("newthread"),base_newthread,2, _SC(".c")},
- {_SC("suspend"),base_suspend,-1, NULL},
- {_SC("array"),base_array,-2, _SC(".n")},
- {_SC("type"),base_type,2, NULL},
- {_SC("dummy"),base_dummy,0,NULL},
-#ifndef NO_GARBAGE_COLLECTOR
- {_SC("collectgarbage"),base_collectgarbage,1, _SC("t")},
-#endif
- {0,0}
-};
-
-void sq_base_register(HSQUIRRELVM v)
-{
- SQInteger i=0;
- sq_pushroottable(v);
- while(base_funcs[i].name!=0) {
- sq_pushstring(v,base_funcs[i].name,-1);
- sq_newclosure(v,base_funcs[i].f,0);
- sq_setnativeclosurename(v,-1,base_funcs[i].name);
- sq_setparamscheck(v,base_funcs[i].nparamscheck,base_funcs[i].typemask);
- sq_createslot(v,-3);
- i++;
- }
- sq_pushstring(v,_SC("_version_"),-1);
- sq_pushstring(v,SQUIRREL_VERSION,-1);
- sq_createslot(v,-3);
- sq_pushstring(v,_SC("_charsize_"),-1);
- sq_pushinteger(v,sizeof(SQChar));
- sq_createslot(v,-3);
- sq_pushstring(v,_SC("_intsize_"),-1);
- sq_pushinteger(v,sizeof(SQInteger));
- sq_createslot(v,-3);
- sq_pop(v,1);
-}
-
-static SQInteger default_delegate_len(HSQUIRRELVM v)
-{
- v->Push(SQInteger(sq_getsize(v,1)));
- return 1;
-}
-
-static SQInteger default_delegate_tofloat(HSQUIRRELVM v)
-{
- SQObjectPtr &o=stack_get(v,1);
- switch(type(o)){
- case OT_STRING:{
- SQObjectPtr res;
- if(str2num(_stringval(o),res)){
- v->Push(SQObjectPtr(tofloat(res)));
- break;
- }}
- return sq_throwerror(v, _SC("cannot convert the string"));
- break;
- case OT_INTEGER:case OT_FLOAT:
- v->Push(SQObjectPtr(tofloat(o)));
- break;
- case OT_BOOL:
- v->Push(SQObjectPtr((SQFloat)(_integer(o)?1:0)));
- break;
- default:
- v->Push(_null_);
- break;
- }
- return 1;
-}
-
-static SQInteger default_delegate_tointeger(HSQUIRRELVM v)
-{
- SQObjectPtr &o=stack_get(v,1);
- switch(type(o)){
- case OT_STRING:{
- SQObjectPtr res;
- if(str2num(_stringval(o),res)){
- v->Push(SQObjectPtr(tointeger(res)));
- break;
- }}
- return sq_throwerror(v, _SC("cannot convert the string"));
- break;
- case OT_INTEGER:case OT_FLOAT:
- v->Push(SQObjectPtr(tointeger(o)));
- break;
- case OT_BOOL:
- v->Push(SQObjectPtr(_integer(o)?(SQInteger)1:(SQInteger)0));
- break;
- default:
- v->Push(_null_);
- break;
- }
- return 1;
-}
-
-static SQInteger default_delegate_tostring(HSQUIRRELVM v)
-{
- sq_tostring(v,1);
- return 1;
-}
-
-static SQInteger obj_delegate_weakref(HSQUIRRELVM v)
-{
- sq_weakref(v,1);
- return 1;
-}
-
-static SQInteger obj_clear(HSQUIRRELVM v)
-{
- return sq_clear(v,-1);
-}
-
-
-static SQInteger number_delegate_tochar(HSQUIRRELVM v)
-{
- SQObject &o=stack_get(v,1);
- SQChar c = (SQChar)tointeger(o);
- v->Push(SQString::Create(_ss(v),(const SQChar *)&c,1));
- return 1;
-}
-
-
-/////////////////////////////////////////////////////////////////
-//TABLE DEFAULT DELEGATE
-
-static SQInteger table_rawdelete(HSQUIRRELVM v)
-{
- if(SQ_FAILED(sq_rawdeleteslot(v,1,SQTrue)))
- return SQ_ERROR;
- return 1;
-}
-
-
-static SQInteger container_rawexists(HSQUIRRELVM v)
-{
- if(SQ_SUCCEEDED(sq_rawget(v,-2))) {
- sq_pushbool(v,SQTrue);
- return 1;
- }
- sq_pushbool(v,SQFalse);
- return 1;
-}
-
-static SQInteger table_rawset(HSQUIRRELVM v)
-{
- return sq_rawset(v,-3);
-}
-
-
-static SQInteger table_rawget(HSQUIRRELVM v)
-{
- return SQ_SUCCEEDED(sq_rawget(v,-2))?1:SQ_ERROR;
-}
-
-
-SQRegFunction SQSharedState::_table_default_delegate_funcz[]={
- {_SC("len"),default_delegate_len,1, _SC("t")},
- {_SC("rawget"),table_rawget,2, _SC("t")},
- {_SC("rawset"),table_rawset,3, _SC("t")},
- {_SC("rawdelete"),table_rawdelete,2, _SC("t")},
- {_SC("rawin"),container_rawexists,2, _SC("t")},
- {_SC("weakref"),obj_delegate_weakref,1, NULL },
- {_SC("tostring"),default_delegate_tostring,1, _SC(".")},
- {_SC("clear"),obj_clear,1, _SC(".")},
- {0,0}
-};
-
-//ARRAY DEFAULT DELEGATE///////////////////////////////////////
-
-static SQInteger array_append(HSQUIRRELVM v)
-{
- return sq_arrayappend(v,-2);
-}
-
-static SQInteger array_extend(HSQUIRRELVM v)
-{
- _array(stack_get(v,1))->Extend(_array(stack_get(v,2)));
- return 0;
-}
-
-static SQInteger array_reverse(HSQUIRRELVM v)
-{
- return sq_arrayreverse(v,-1);
-}
-
-static SQInteger array_pop(HSQUIRRELVM v)
-{
- return SQ_SUCCEEDED(sq_arraypop(v,1,SQTrue))?1:SQ_ERROR;
-}
-
-static SQInteger array_top(HSQUIRRELVM v)
-{
- SQObject &o=stack_get(v,1);
- if(_array(o)->Size()>0){
- v->Push(_array(o)->Top());
- return 1;
- }
- else return sq_throwerror(v,_SC("top() on a empty array"));
-}
-
-static SQInteger array_insert(HSQUIRRELVM v)
-{
- SQObject &o=stack_get(v,1);
- SQObject &idx=stack_get(v,2);
- SQObject &val=stack_get(v,3);
- _array(o)->Insert(idx,val);
- return 0;
-}
-
-static SQInteger array_remove(HSQUIRRELVM v)
-{
- SQObject &o = stack_get(v, 1);
- SQObject &idx = stack_get(v, 2);
- if(!sq_isnumeric(idx)) return sq_throwerror(v, _SC("wrong type"));
- SQObjectPtr val;
- if(_array(o)->Get(tointeger(idx), val)) {
- _array(o)->Remove(tointeger(idx));
- v->Push(val);
- return 1;
- }
- return sq_throwerror(v, _SC("idx out of range"));
-}
-
-static SQInteger array_resize(HSQUIRRELVM v)
-{
- SQObject &o = stack_get(v, 1);
- SQObject &nsize = stack_get(v, 2);
- SQObjectPtr fill;
- if(sq_isnumeric(nsize)) {
- if(sq_gettop(v) > 2)
- fill = stack_get(v, 3);
- _array(o)->Resize(tointeger(nsize),fill);
- return 0;
- }
- return sq_throwerror(v, _SC("size must be a number"));
-}
-
-
-//QSORT ala Sedgewick
-bool _qsort_compare(HSQUIRRELVM v,SQObjectPtr &arr,SQObjectPtr &a,SQObjectPtr &b,SQInteger func,SQInteger &ret)
-{
- if(func < 0) {
- if(!v->ObjCmp(a,b,ret)) return false;
- }
- else {
- SQInteger top = sq_gettop(v);
- sq_push(v, func);
- sq_pushroottable(v);
- v->Push(a);
- v->Push(b);
- if(SQ_FAILED(sq_call(v, 3, SQTrue, SQFalse))) {
- v->Raise_Error(_SC("compare func failed"));
- return false;
- }
- sq_getinteger(v, -1, &ret);
- sq_settop(v, top);
- return true;
- }
- return true;
-}
-//QSORT ala Sedgewick
-bool _qsort(HSQUIRRELVM v,SQObjectPtr &arr, SQInteger l, SQInteger r,SQInteger func)
-{
- SQInteger i, j;
- SQArray *a=_array(arr);
- SQObjectPtr pivot,t;
- if( l < r ){
- pivot = a->_values[l];
- i = l; j = r+1;
- while(1){
- SQInteger ret;
- do {
- ++i;
- if(i > r) break;
- if(!_qsort_compare(v,arr,a->_values[i],pivot,func,ret))
- return false;
- } while( ret <= 0);
- do {
- --j;
- if(!_qsort_compare(v,arr,a->_values[j],pivot,func,ret))
- return false;
- }
- while( ret > 0 );
- if( i >= j ) break;
- t = a->_values[i]; a->_values[i] = a->_values[j]; a->_values[j] = t;
- }
- t = a->_values[l]; a->_values[l] = a->_values[j]; a->_values[j] = t;
- if(!_qsort( v, arr, l, j-1,func)) return false;
- if(!_qsort( v, arr, j+1, r,func)) return false;
- }
- return true;
-}
-
-static SQInteger array_sort(HSQUIRRELVM v)
-{
- SQInteger func = -1;
- SQObjectPtr &o = stack_get(v,1);
- SQObject &funcobj = stack_get(v,2);
- if(_array(o)->Size() > 1) {
- if(type(funcobj) == OT_CLOSURE || type(funcobj) == OT_NATIVECLOSURE) func = 2;
- if(!_qsort(v, o, 0, _array(o)->Size()-1, func))
- return SQ_ERROR;
-
- }
- return 0;
-}
-static SQInteger array_slice(HSQUIRRELVM v)
-{
- SQInteger sidx,eidx;
- SQObjectPtr o;
- if(get_slice_params(v,sidx,eidx,o)==-1)return -1;
- if(sidx<0)sidx=_array(o)->Size()+sidx;
- if(eidx<0)eidx=_array(o)->Size()+eidx;
- if(eidx < sidx)return sq_throwerror(v,_SC("wrong indexes"));
- SQArray *arr=SQArray::Create(_ss(v),eidx-sidx);
- SQObjectPtr t;
- SQInteger count=0;
- for(SQInteger i=sidx;i<eidx;i++){
- _array(o)->Get(i,t);
- arr->Set(count++,t);
- }
- v->Push(arr);
- return 1;
-
-}
-
-SQRegFunction SQSharedState::_array_default_delegate_funcz[]={
- {_SC("len"),default_delegate_len,1, _SC("a")},
- {_SC("append"),array_append,2, _SC("a")},
- {_SC("extend"),array_extend,2, _SC("aa")},
- {_SC("push"),array_append,2, _SC("a")},
- {_SC("pop"),array_pop,1, _SC("a")},
- {_SC("top"),array_top,1, _SC("a")},
- {_SC("insert"),array_insert,3, _SC("an")},
- {_SC("remove"),array_remove,2, _SC("an")},
- {_SC("resize"),array_resize,-2, _SC("an")},
- {_SC("reverse"),array_reverse,1, _SC("a")},
- {_SC("sort"),array_sort,-1, _SC("ac")},
- {_SC("slice"),array_slice,-1, _SC("ann")},
- {_SC("weakref"),obj_delegate_weakref,1, NULL },
- {_SC("tostring"),default_delegate_tostring,1, _SC(".")},
- {_SC("clear"),obj_clear,1, _SC(".")},
- {0,0}
-};
-
-//STRING DEFAULT DELEGATE//////////////////////////
-static SQInteger string_slice(HSQUIRRELVM v)
-{
- SQInteger sidx,eidx;
- SQObjectPtr o;
- if(SQ_FAILED(get_slice_params(v,sidx,eidx,o)))return -1;
- if(sidx<0)sidx=_string(o)->_len+sidx;
- if(eidx<0)eidx=_string(o)->_len+eidx;
- if(eidx<sidx)
- return sq_throwerror(v,_SC("wrong indexes"));
- v->Push(SQString::Create(_ss(v),&_stringval(o)[sidx],eidx-sidx));
- return 1;
-}
-
-static SQInteger string_find(HSQUIRRELVM v)
-{
- SQInteger top,start_idx=0;
- const SQChar *str,*substr,*ret;
- if(((top=sq_gettop(v))>1) && SQ_SUCCEEDED(sq_getstring(v,1,&str)) && SQ_SUCCEEDED(sq_getstring(v,2,&substr))){
- if(top>2)sq_getinteger(v,3,&start_idx);
- if((sq_getsize(v,1)>start_idx) && (start_idx>=0)){
- ret=scstrstr(&str[start_idx],substr);
- if(ret){
- sq_pushinteger(v,(SQInteger)(ret-str));
- return 1;
- }
- }
- return 0;
- }
- return sq_throwerror(v,_SC("invalid param"));
-}
-
-#define STRING_TOFUNCZ(func) static SQInteger string_##func(HSQUIRRELVM v) \
-{ \
- SQObject str=stack_get(v,1); \
- SQInteger len=_string(str)->_len; \
- const SQChar *sThis=_stringval(str); \
- SQChar *sNew=(_ss(v)->GetScratchPad(rsl(len))); \
- for(SQInteger i=0;i<len;i++) sNew[i]=func(sThis[i]); \
- v->Push(SQString::Create(_ss(v),sNew,len)); \
- return 1; \
-}
-
-
-STRING_TOFUNCZ(tolower)
-STRING_TOFUNCZ(toupper)
-
-SQRegFunction SQSharedState::_string_default_delegate_funcz[]={
- {_SC("len"),default_delegate_len,1, _SC("s")},
- {_SC("tointeger"),default_delegate_tointeger,1, _SC("s")},
- {_SC("tofloat"),default_delegate_tofloat,1, _SC("s")},
- {_SC("tostring"),default_delegate_tostring,1, _SC(".")},
- {_SC("slice"),string_slice,-1, _SC(" s n n")},
- {_SC("find"),string_find,-2, _SC("s s n ")},
- {_SC("tolower"),string_tolower,1, _SC("s")},
- {_SC("toupper"),string_toupper,1, _SC("s")},
- {_SC("weakref"),obj_delegate_weakref,1, NULL },
- {0,0}
-};
-
-//INTEGER DEFAULT DELEGATE//////////////////////////
-SQRegFunction SQSharedState::_number_default_delegate_funcz[]={
- {_SC("tointeger"),default_delegate_tointeger,1, _SC("n|b")},
- {_SC("tofloat"),default_delegate_tofloat,1, _SC("n|b")},
- {_SC("tostring"),default_delegate_tostring,1, _SC(".")},
- {_SC("tochar"),number_delegate_tochar,1, _SC("n|b")},
- {_SC("weakref"),obj_delegate_weakref,1, NULL },
- {0,0}
-};
-
-//CLOSURE DEFAULT DELEGATE//////////////////////////
-static SQInteger closure_pcall(HSQUIRRELVM v)
-{
- return SQ_SUCCEEDED(sq_call(v,sq_gettop(v)-1,SQTrue,SQFalse))?1:SQ_ERROR;
-}
-
-static SQInteger closure_call(HSQUIRRELVM v)
-{
- return SQ_SUCCEEDED(sq_call(v,sq_gettop(v)-1,SQTrue,SQTrue))?1:SQ_ERROR;
-}
-
-static SQInteger _closure_acall(HSQUIRRELVM v,SQBool raiseerror)
-{
- SQArray *aparams=_array(stack_get(v,2));
- SQInteger nparams=aparams->Size();
- v->Push(stack_get(v,1));
- for(SQInteger i=0;i<nparams;i++)v->Push(aparams->_values[i]);
- return SQ_SUCCEEDED(sq_call(v,nparams,SQTrue,raiseerror))?1:SQ_ERROR;
-}
-
-static SQInteger closure_acall(HSQUIRRELVM v)
-{
- return _closure_acall(v,SQTrue);
-}
-
-static SQInteger closure_pacall(HSQUIRRELVM v)
-{
- return _closure_acall(v,SQFalse);
-}
-
-static SQInteger closure_bindenv(HSQUIRRELVM v)
-{
- if(SQ_FAILED(sq_bindenv(v,1)))
- return SQ_ERROR;
- return 1;
-}
-
-static SQInteger closure_getinfos(HSQUIRRELVM v) {
- SQObject o = stack_get(v,1);
- SQTable *res = SQTable::Create(_ss(v),4);
- if(type(o) == OT_CLOSURE) {
- SQFunctionProto *f = _funcproto(_closure(o)->_function);
- SQInteger nparams = f->_nparameters + (f->_varparams?1:0);
- SQObjectPtr params = SQArray::Create(_ss(v),nparams);
- for(SQInteger n = 0; n<f->_nparameters; n++) {
- _array(params)->Set((SQInteger)n,f->_parameters[n]);
- }
- if(f->_varparams) {
- _array(params)->Set(nparams-1,SQString::Create(_ss(v),_SC("..."),-1));
- }
- res->NewSlot(SQString::Create(_ss(v),_SC("native"),-1),false);
- res->NewSlot(SQString::Create(_ss(v),_SC("name"),-1),f->_name);
- res->NewSlot(SQString::Create(_ss(v),_SC("src"),-1),f->_sourcename);
- res->NewSlot(SQString::Create(_ss(v),_SC("parameters"),-1),params);
- res->NewSlot(SQString::Create(_ss(v),_SC("varargs"),-1),f->_varparams);
- }
- else { //OT_NATIVECLOSURE
- SQNativeClosure *nc = _nativeclosure(o);
- res->NewSlot(SQString::Create(_ss(v),_SC("native"),-1),true);
- res->NewSlot(SQString::Create(_ss(v),_SC("name"),-1),nc->_name);
- res->NewSlot(SQString::Create(_ss(v),_SC("paramscheck"),-1),nc->_nparamscheck);
- SQObjectPtr typecheck;
- if(nc->_typecheck.size() > 0) {
- typecheck =
- SQArray::Create(_ss(v), nc->_typecheck.size());
- for(SQUnsignedInteger n = 0; n<nc->_typecheck.size(); n++) {
- _array(typecheck)->Set((SQInteger)n,nc->_typecheck[n]);
- }
- }
- res->NewSlot(SQString::Create(_ss(v),_SC("typecheck"),-1),typecheck);
- }
- v->Push(res);
- return 1;
-}
-
-
-SQRegFunction SQSharedState::_closure_default_delegate_funcz[]={
- {_SC("call"),closure_call,-1, _SC("c")},
- {_SC("pcall"),closure_pcall,-1, _SC("c")},
- {_SC("acall"),closure_acall,2, _SC("ca")},
- {_SC("pacall"),closure_pacall,2, _SC("ca")},
- {_SC("weakref"),obj_delegate_weakref,1, NULL },
- {_SC("tostring"),default_delegate_tostring,1, _SC(".")},
- {_SC("bindenv"),closure_bindenv,2, _SC("c x|y|t")},
- {_SC("getinfos"),closure_getinfos,1, _SC("c")},
- {0,0}
-};
-
-//GENERATOR DEFAULT DELEGATE
-static SQInteger generator_getstatus(HSQUIRRELVM v)
-{
- SQObject &o=stack_get(v,1);
- switch(_generator(o)->_state){
- case SQGenerator::eSuspended:v->Push(SQString::Create(_ss(v),_SC("suspended")));break;
- case SQGenerator::eRunning:v->Push(SQString::Create(_ss(v),_SC("running")));break;
- case SQGenerator::eDead:v->Push(SQString::Create(_ss(v),_SC("dead")));break;
- }
- return 1;
-}
-
-SQRegFunction SQSharedState::_generator_default_delegate_funcz[]={
- {_SC("getstatus"),generator_getstatus,1, _SC("g")},
- {_SC("weakref"),obj_delegate_weakref,1, NULL },
- {_SC("tostring"),default_delegate_tostring,1, _SC(".")},
- {0,0}
-};
-
-//THREAD DEFAULT DELEGATE
-
-static SQInteger thread_call(HSQUIRRELVM v)
-{
- SQObjectPtr o = stack_get(v,1);
- if(type(o) == OT_THREAD) {
- SQInteger nparams = sq_gettop(v);
- _thread(o)->Push(_thread(o)->_roottable);
- for(SQInteger i = 2; i<(nparams+1); i++)
- sq_move(_thread(o),v,i);
- if(SQ_SUCCEEDED(sq_call(_thread(o),nparams,SQTrue,SQFalse))) {
- sq_move(v,_thread(o),-1);
- return 1;
- }
- return SQ_ERROR;
- }
- return sq_throwerror(v,_SC("wrong parameter"));
-}
-
-static SQInteger thread_wakeup(HSQUIRRELVM v)
-{
- SQObjectPtr o = stack_get(v,1);
- if(type(o) == OT_THREAD) {
- SQVM *thread = _thread(o);
- SQInteger state = sq_getvmstate(thread);
- if(state != SQ_VMSTATE_SUSPENDED) {
- switch(state) {
- case SQ_VMSTATE_IDLE:
- return sq_throwerror(v,_SC("cannot wakeup a idle thread"));
- break;
- case SQ_VMSTATE_RUNNING:
- return sq_throwerror(v,_SC("cannot wakeup a running thread"));
- break;
- }
- }
-
- SQInteger wakeupret = sq_gettop(v)>1?1:0;
- if(wakeupret) {
- sq_move(thread,v,2);
- }
- if(SQ_SUCCEEDED(sq_wakeupvm(thread,wakeupret,1,SQFalse))) {
- sq_move(v,thread,-1);
- sq_pop(thread,1);
- if(sq_getvmstate(thread) == SQ_VMSTATE_IDLE) {
- sq_pop(thread,1);
- }
- return 1;
- }
- return SQ_ERROR;
- }
- return sq_throwerror(v,_SC("wrong parameter"));
-}
-
-static SQInteger thread_getstatus(HSQUIRRELVM v)
-{
- SQObjectPtr &o = stack_get(v,1);
- switch(sq_getvmstate(_thread(o))) {
- case SQ_VMSTATE_IDLE:
- sq_pushstring(v,_SC("idle"),-1);
- break;
- case SQ_VMSTATE_RUNNING:
- sq_pushstring(v,_SC("running"),-1);
- break;
- case SQ_VMSTATE_SUSPENDED:
- sq_pushstring(v,_SC("suspended"),-1);
- break;
- default:
- return sq_throwerror(v,_SC("internal VM error"));
- }
- return 1;
-}
-
-SQRegFunction SQSharedState::_thread_default_delegate_funcz[] = {
- {_SC("call"), thread_call, -1, _SC("v")},
- {_SC("wakeup"), thread_wakeup, -1, _SC("v")},
- {_SC("getstatus"), thread_getstatus, 1, _SC("v")},
- {_SC("weakref"),obj_delegate_weakref,1, NULL },
- {_SC("tostring"),default_delegate_tostring,1, _SC(".")},
- {0,0},
-};
-
-static SQInteger class_getattributes(HSQUIRRELVM v)
-{
- if(SQ_SUCCEEDED(sq_getattributes(v,-2)))
- return 1;
- return SQ_ERROR;
-}
-
-static SQInteger class_setattributes(HSQUIRRELVM v)
-{
- if(SQ_SUCCEEDED(sq_setattributes(v,-3)))
- return 1;
- return SQ_ERROR;
-}
-
-static SQInteger class_instance(HSQUIRRELVM v)
-{
- if(SQ_SUCCEEDED(sq_createinstance(v,-1)))
- return 1;
- return SQ_ERROR;
-}
-
-SQRegFunction SQSharedState::_class_default_delegate_funcz[] = {
- {_SC("getattributes"), class_getattributes, 2, _SC("y.")},
- {_SC("setattributes"), class_setattributes, 3, _SC("y..")},
- {_SC("rawin"),container_rawexists,2, _SC("y")},
- {_SC("weakref"),obj_delegate_weakref,1, NULL },
- {_SC("tostring"),default_delegate_tostring,1, _SC(".")},
- {_SC("instance"),class_instance,1, _SC("y")},
- {0,0}
-};
-
-static SQInteger instance_getclass(HSQUIRRELVM v)
-{
- if(SQ_SUCCEEDED(sq_getclass(v,1)))
- return 1;
- return SQ_ERROR;
-}
-
-SQRegFunction SQSharedState::_instance_default_delegate_funcz[] = {
- {_SC("getclass"), instance_getclass, 1, _SC("x")},
- {_SC("rawin"),container_rawexists,2, _SC("x")},
- {_SC("weakref"),obj_delegate_weakref,1, NULL },
- {_SC("tostring"),default_delegate_tostring,1, _SC(".")},
- {0,0}
-};
-
-static SQInteger weakref_ref(HSQUIRRELVM v)
-{
- if(SQ_FAILED(sq_getweakrefval(v,1)))
- return SQ_ERROR;
- return 1;
-}
-
-SQRegFunction SQSharedState::_weakref_default_delegate_funcz[] = {
- {_SC("ref"),weakref_ref,1, _SC("r")},
- {_SC("weakref"),obj_delegate_weakref,1, NULL },
- {_SC("tostring"),default_delegate_tostring,1, _SC(".")},
- {0,0}
-};
-
-
+++ /dev/null
-/*
- see copyright notice in squirrel.h
-*/
-#include "sqpcheader.h"
-#include "sqvm.h"
-#include "sqtable.h"
-#include "sqclass.h"
-#include "sqclosure.h"
-
-SQClass::SQClass(SQSharedState *ss,SQClass *base)
-{
- _base = base;
- _typetag = 0;
- _hook = NULL;
- _udsize = 0;
- _metamethods.resize(MT_LAST); //size it to max size
- if(_base) {
- _defaultvalues.copy(base->_defaultvalues);
- _methods.copy(base->_methods);
- _metamethods.copy(base->_metamethods);
- __ObjAddRef(_base);
- }
- _members = base?base->_members->Clone() : SQTable::Create(ss,0);
- __ObjAddRef(_members);
- _locked = false;
- INIT_CHAIN();
- ADD_TO_CHAIN(&_sharedstate->_gc_chain, this);
-}
-
-void SQClass::Finalize() {
- _attributes = _null_;
- _defaultvalues.resize(0);
- _methods.resize(0);
- _metamethods.resize(0);
- __ObjRelease(_members);
- if(_base) {
- __ObjRelease(_base);
- }
-}
-
-SQClass::~SQClass()
-{
- REMOVE_FROM_CHAIN(&_sharedstate->_gc_chain, this);
- Finalize();
-}
-
-bool SQClass::NewSlot(SQSharedState *ss,const SQObjectPtr &key,const SQObjectPtr &val,bool bstatic)
-{
- SQObjectPtr temp;
- if(_locked)
- return false; //the class already has an instance so cannot be modified
- if(_members->Get(key,temp) && _isfield(temp)) //overrides the default value
- {
- _defaultvalues[_member_idx(temp)].val = val;
- return true;
- }
- if(type(val) == OT_CLOSURE || type(val) == OT_NATIVECLOSURE || bstatic) {
- SQInteger mmidx;
- if((type(val) == OT_CLOSURE || type(val) == OT_NATIVECLOSURE) &&
- (mmidx = ss->GetMetaMethodIdxByName(key)) != -1) {
- _metamethods[mmidx] = val;
- }
- else {
- if(type(temp) == OT_NULL) {
- SQClassMember m;
- m.val = val;
- _members->NewSlot(key,SQObjectPtr(_make_method_idx(_methods.size())));
- _methods.push_back(m);
- }
- else {
- _methods[_member_idx(temp)].val = val;
- }
- }
- return true;
- }
- SQClassMember m;
- m.val = val;
- _members->NewSlot(key,SQObjectPtr(_make_field_idx(_defaultvalues.size())));
- _defaultvalues.push_back(m);
- return true;
-}
-
-SQInstance *SQClass::CreateInstance()
-{
- if(!_locked) Lock();
- return SQInstance::Create(_opt_ss(this),this);
-}
-
-SQInteger SQClass::Next(const SQObjectPtr &refpos, SQObjectPtr &outkey, SQObjectPtr &outval)
-{
- SQObjectPtr oval;
- SQInteger idx = _members->Next(false,refpos,outkey,oval);
- if(idx != -1) {
- if(_ismethod(oval)) {
- outval = _methods[_member_idx(oval)].val;
- }
- else {
- SQObjectPtr &o = _defaultvalues[_member_idx(oval)].val;
- outval = _realval(o);
- }
- }
- return idx;
-}
-
-bool SQClass::SetAttributes(const SQObjectPtr &key,const SQObjectPtr &val)
-{
- SQObjectPtr idx;
- if(_members->Get(key,idx)) {
- if(_isfield(idx))
- _defaultvalues[_member_idx(idx)].attrs = val;
- else
- _methods[_member_idx(idx)].attrs = val;
- return true;
- }
- return false;
-}
-
-bool SQClass::GetAttributes(const SQObjectPtr &key,SQObjectPtr &outval)
-{
- SQObjectPtr idx;
- if(_members->Get(key,idx)) {
- outval = (_isfield(idx)?_defaultvalues[_member_idx(idx)].attrs:_methods[_member_idx(idx)].attrs);
- return true;
- }
- return false;
-}
-
-///////////////////////////////////////////////////////////////////////
-void SQInstance::Init(SQSharedState *ss)
-{
- _userpointer = NULL;
- _hook = NULL;
- __ObjAddRef(_class);
- _delegate = _class->_members;
- INIT_CHAIN();
- ADD_TO_CHAIN(&_sharedstate->_gc_chain, this);
-}
-
-SQInstance::SQInstance(SQSharedState *ss, SQClass *c, SQInteger memsize)
-{
- _memsize = memsize;
- _class = c;
- SQUnsignedInteger nvalues = _class->_defaultvalues.size();
- for(SQUnsignedInteger n = 0; n < nvalues; n++) {
- new (&_values[n]) SQObjectPtr(_class->_defaultvalues[n].val);
- }
- Init(ss);
-}
-
-SQInstance::SQInstance(SQSharedState *ss, SQInstance *i, SQInteger memsize)
-{
- _memsize = memsize;
- _class = i->_class;
- SQUnsignedInteger nvalues = _class->_defaultvalues.size();
- for(SQUnsignedInteger n = 0; n < nvalues; n++) {
- new (&_values[n]) SQObjectPtr(i->_values[n]);
- }
- Init(ss);
-}
-
-void SQInstance::Finalize()
-{
- SQUnsignedInteger nvalues = _class->_defaultvalues.size();
- __ObjRelease(_class);
- for(SQUnsignedInteger i = 0; i < nvalues; i++) {
- _values[i] = _null_;
- }
-}
-
-SQInstance::~SQInstance()
-{
- REMOVE_FROM_CHAIN(&_sharedstate->_gc_chain, this);
- if(_class){ Finalize(); } //if _class is null it was already finalized by the GC
-}
-
-bool SQInstance::GetMetaMethod(SQVM *v,SQMetaMethod mm,SQObjectPtr &res)
-{
- if(type(_class->_metamethods[mm]) != OT_NULL) {
- res = _class->_metamethods[mm];
- return true;
- }
- return false;
-}
-
-bool SQInstance::InstanceOf(SQClass *trg)
-{
- SQClass *parent = _class;
- while(parent != NULL) {
- if(parent == trg)
- return true;
- parent = parent->_base;
- }
- return false;
-}
+++ /dev/null
-/* see copyright notice in squirrel.h */
-#ifndef _SQCLASS_H_
-#define _SQCLASS_H_
-
-struct SQInstance;
-
-struct SQClassMember {
- SQClassMember(){}
- SQClassMember(const SQClassMember &o) {
- val = o.val;
- attrs = o.attrs;
- }
- SQObjectPtr val;
- SQObjectPtr attrs;
-};
-
-typedef sqvector<SQClassMember> SQClassMemberVec;
-
-#define MEMBER_TYPE_METHOD 0x01000000
-#define MEMBER_TYPE_FIELD 0x02000000
-
-#define _ismethod(o) (_integer(o)&MEMBER_TYPE_METHOD)
-#define _isfield(o) (_integer(o)&MEMBER_TYPE_FIELD)
-#define _make_method_idx(i) ((SQInteger)(MEMBER_TYPE_METHOD|i))
-#define _make_field_idx(i) ((SQInteger)(MEMBER_TYPE_FIELD|i))
-#define _member_type(o) (_integer(o)&0xFF000000)
-#define _member_idx(o) (_integer(o)&0x00FFFFFF)
-
-struct SQClass : public CHAINABLE_OBJ
-{
- SQClass(SQSharedState *ss,SQClass *base);
-public:
- static SQClass* Create(SQSharedState *ss,SQClass *base) {
- SQClass *newclass = (SQClass *)SQ_MALLOC(sizeof(SQClass));
- new (newclass) SQClass(ss, base);
- return newclass;
- }
- ~SQClass();
- bool NewSlot(SQSharedState *ss, const SQObjectPtr &key,const SQObjectPtr &val,bool bstatic);
- bool Get(const SQObjectPtr &key,SQObjectPtr &val) {
- if(_members->Get(key,val)) {
- if(_isfield(val)) {
- SQObjectPtr &o = _defaultvalues[_member_idx(val)].val;
- val = _realval(o);
- }
- else {
- val = _methods[_member_idx(val)].val;
- }
- return true;
- }
- return false;
- }
- bool SetAttributes(const SQObjectPtr &key,const SQObjectPtr &val);
- bool GetAttributes(const SQObjectPtr &key,SQObjectPtr &outval);
- void Lock() { _locked = true; if(_base) _base->Lock(); }
- void Release() {
- if (_hook) { _hook(_typetag,0);}
- sq_delete(this, SQClass);
- }
- void Finalize();
-#ifndef NO_GARBAGE_COLLECTOR
- void Mark(SQCollectable ** );
-#endif
- SQInteger Next(const SQObjectPtr &refpos, SQObjectPtr &outkey, SQObjectPtr &outval);
- SQInstance *CreateInstance();
- SQTable *_members;
- SQClass *_base;
- SQClassMemberVec _defaultvalues;
- SQClassMemberVec _methods;
- SQObjectPtrVec _metamethods;
- SQObjectPtr _attributes;
- SQUserPointer _typetag;
- SQRELEASEHOOK _hook;
- bool _locked;
- SQInteger _udsize;
-};
-
-#define calcinstancesize(_theclass_) \
- (_theclass_->_udsize + sizeof(SQInstance) + (sizeof(SQObjectPtr)*(_theclass_->_defaultvalues.size()>0?_theclass_->_defaultvalues.size()-1:0)))
-
-struct SQInstance : public SQDelegable
-{
- void Init(SQSharedState *ss);
- SQInstance(SQSharedState *ss, SQClass *c, SQInteger memsize);
- SQInstance(SQSharedState *ss, SQInstance *c, SQInteger memsize);
-public:
- static SQInstance* Create(SQSharedState *ss,SQClass *theclass) {
-
- SQInteger size = calcinstancesize(theclass);
- SQInstance *newinst = (SQInstance *)SQ_MALLOC(size);
- new (newinst) SQInstance(ss, theclass,size);
- if(theclass->_udsize) {
- newinst->_userpointer = ((unsigned char *)newinst) + (size - theclass->_udsize);
- }
- return newinst;
- }
- SQInstance *Clone(SQSharedState *ss)
- {
- SQInteger size = calcinstancesize(_class);
- SQInstance *newinst = (SQInstance *)SQ_MALLOC(size);
- new (newinst) SQInstance(ss, this,size);
- if(_class->_udsize) {
- newinst->_userpointer = ((unsigned char *)newinst) + (size - _class->_udsize);
- }
- return newinst;
- }
- ~SQInstance();
- bool Get(const SQObjectPtr &key,SQObjectPtr &val) {
- if(_class->_members->Get(key,val)) {
- if(_isfield(val)) {
- SQObjectPtr &o = _values[_member_idx(val)];
- val = _realval(o);
- }
- else {
- val = _class->_methods[_member_idx(val)].val;
- }
- return true;
- }
- return false;
- }
- bool Set(const SQObjectPtr &key,const SQObjectPtr &val) {
- SQObjectPtr idx;
- if(_class->_members->Get(key,idx) && _isfield(idx)) {
- _values[_member_idx(idx)] = val;
- return true;
- }
- return false;
- }
- void Release() {
- _uiRef++;
- if (_hook) { _hook(_userpointer,0);}
- _uiRef--;
- if(_uiRef > 0) return;
- SQInteger size = _memsize;
- this->~SQInstance();
- SQ_FREE(this, size);
- }
- void Finalize();
-#ifndef NO_GARBAGE_COLLECTOR
- void Mark(SQCollectable ** );
-#endif
- bool InstanceOf(SQClass *trg);
- bool GetMetaMethod(SQVM *v,SQMetaMethod mm,SQObjectPtr &res);
-
- SQClass *_class;
- SQUserPointer _userpointer;
- SQRELEASEHOOK _hook;
- SQInteger _memsize;
- SQObjectPtr _values[1];
-};
-
-#endif //_SQCLASS_H_
+++ /dev/null
-/* see copyright notice in squirrel.h */
-#ifndef _SQCLOSURE_H_
-#define _SQCLOSURE_H_
-
-struct SQFunctionProto;
-
-struct SQClosure : public CHAINABLE_OBJ
-{
-private:
- SQClosure(SQSharedState *ss,SQFunctionProto *func){_function=func; INIT_CHAIN();ADD_TO_CHAIN(&_ss(this)->_gc_chain,this);}
-public:
- static SQClosure *Create(SQSharedState *ss,SQFunctionProto *func){
- SQClosure *nc=(SQClosure*)SQ_MALLOC(sizeof(SQClosure));
- new (nc) SQClosure(ss,func);
- return nc;
- }
- void Release(){
- sq_delete(this,SQClosure);
- }
- SQClosure *Clone()
- {
- SQClosure * ret = SQClosure::Create(_opt_ss(this),_funcproto(_function));
- ret->_env = _env;
- ret->_outervalues.copy(_outervalues);
- return ret;
- }
- ~SQClosure()
- {
- REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain,this);
- }
- bool Save(SQVM *v,SQUserPointer up,SQWRITEFUNC write);
- static bool Load(SQVM *v,SQUserPointer up,SQREADFUNC read,SQObjectPtr &ret);
-#ifndef NO_GARBAGE_COLLECTOR
- void Mark(SQCollectable **chain);
- void Finalize(){_outervalues.resize(0); }
-#endif
- SQObjectPtr _env;
- SQObjectPtr _function;
- SQObjectPtrVec _outervalues;
-};
-//////////////////////////////////////////////
-struct SQGenerator : public CHAINABLE_OBJ
-{
- enum SQGeneratorState{eRunning,eSuspended,eDead};
-private:
- SQGenerator(SQSharedState *ss,SQClosure *closure){_closure=closure;_state=eRunning;_ci._generator=_null_;INIT_CHAIN();ADD_TO_CHAIN(&_ss(this)->_gc_chain,this);}
-public:
- static SQGenerator *Create(SQSharedState *ss,SQClosure *closure){
- SQGenerator *nc=(SQGenerator*)SQ_MALLOC(sizeof(SQGenerator));
- new (nc) SQGenerator(ss,closure);
- return nc;
- }
- ~SQGenerator()
- {
- REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain,this);
- }
- void Kill(){
- _state=eDead;
- _stack.resize(0);
- _closure=_null_;}
- void Release(){
- sq_delete(this,SQGenerator);
- }
- bool Yield(SQVM *v);
- bool Resume(SQVM *v,SQInteger target);
-#ifndef NO_GARBAGE_COLLECTOR
- void Mark(SQCollectable **chain);
- void Finalize(){_stack.resize(0);_closure=_null_;}
-#endif
- SQObjectPtr _closure;
- SQObjectPtrVec _stack;
- SQObjectPtrVec _vargsstack;
- SQVM::CallInfo _ci;
- ExceptionsTraps _etraps;
- SQGeneratorState _state;
-};
-
-struct SQNativeClosure : public CHAINABLE_OBJ
-{
-private:
- SQNativeClosure(SQSharedState *ss,SQFUNCTION func){_function=func;INIT_CHAIN();ADD_TO_CHAIN(&_ss(this)->_gc_chain,this); }
-public:
- static SQNativeClosure *Create(SQSharedState *ss,SQFUNCTION func)
- {
- SQNativeClosure *nc=(SQNativeClosure*)SQ_MALLOC(sizeof(SQNativeClosure));
- new (nc) SQNativeClosure(ss,func);
- return nc;
- }
- SQNativeClosure *Clone()
- {
- SQNativeClosure * ret = SQNativeClosure::Create(_opt_ss(this),_function);
- ret->_env = _env;
- ret->_name = _name;
- ret->_outervalues.copy(_outervalues);
- ret->_typecheck.copy(_typecheck);
- ret->_nparamscheck = _nparamscheck;
- return ret;
- }
- ~SQNativeClosure()
- {
- REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain,this);
- }
- void Release(){
- sq_delete(this,SQNativeClosure);
- }
-#ifndef NO_GARBAGE_COLLECTOR
- void Mark(SQCollectable **chain);
- void Finalize(){_outervalues.resize(0);}
-#endif
- SQInteger _nparamscheck;
- SQIntVec _typecheck;
- SQObjectPtrVec _outervalues;
- SQObjectPtr _env;
- SQFUNCTION _function;
- SQObjectPtr _name;
-};
-
-
-
-#endif //_SQCLOSURE_H_
+++ /dev/null
-/*
- see copyright notice in squirrel.h
-*/
-#include "sqpcheader.h"
-#include <stdarg.h>
-#include <setjmp.h>
-#include "sqopcodes.h"
-#include "sqstring.h"
-#include "sqfuncproto.h"
-#include "sqcompiler.h"
-#include "sqfuncstate.h"
-#include "sqlexer.h"
-#include "sqvm.h"
-
-#define DEREF_NO_DEREF -1
-#define DEREF_FIELD -2
-
-struct ExpState
-{
- ExpState()
- {
- _deref = DEREF_NO_DEREF;
- _freevar = false;
- _class_or_delete = false;
- _funcarg = false;
- }
- bool _class_or_delete;
- bool _funcarg;
- bool _freevar;
- SQInteger _deref;
-};
-
-typedef sqvector<ExpState> ExpStateVec;
-
-#define _exst (_expstates.top())
-
-#define BEGIN_BREAKBLE_BLOCK() SQInteger __nbreaks__=_fs->_unresolvedbreaks.size(); \
- SQInteger __ncontinues__=_fs->_unresolvedcontinues.size(); \
- _fs->_breaktargets.push_back(0);_fs->_continuetargets.push_back(0);
-
-#define END_BREAKBLE_BLOCK(continue_target) {__nbreaks__=_fs->_unresolvedbreaks.size()-__nbreaks__; \
- __ncontinues__=_fs->_unresolvedcontinues.size()-__ncontinues__; \
- if(__ncontinues__>0)ResolveContinues(_fs,__ncontinues__,continue_target); \
- if(__nbreaks__>0)ResolveBreaks(_fs,__nbreaks__); \
- _fs->_breaktargets.pop_back();_fs->_continuetargets.pop_back();}
-
-class SQCompiler
-{
-public:
- SQCompiler(SQVM *v, SQLEXREADFUNC rg, SQUserPointer up, const SQChar* sourcename, bool raiseerror, bool lineinfo)
- {
- _vm=v;
- _lex.Init(_ss(v), rg, up,ThrowError,this);
- _sourcename = SQString::Create(_ss(v), sourcename);
- _lineinfo = lineinfo;_raiseerror = raiseerror;
- compilererror = NULL;
- }
- static void ThrowError(void *ud, const SQChar *s) {
- SQCompiler *c = (SQCompiler *)ud;
- c->Error(s);
- }
- void Error(const SQChar *s, ...)
- {
- static SQChar temp[256];
- va_list vl;
- va_start(vl, s);
- scvsprintf(temp, s, vl);
- va_end(vl);
- compilererror = temp;
- longjmp(_errorjmp,1);
- }
- void Lex(){ _token = _lex.Lex();}
- void PushExpState(){ _expstates.push_back(ExpState()); }
- bool IsDerefToken(SQInteger tok)
- {
- switch(tok){
- case _SC('='): case _SC('('): case TK_NEWSLOT:
- case TK_MODEQ: case TK_MULEQ: case TK_DIVEQ: case TK_MINUSEQ: case TK_PLUSEQ: case TK_PLUSPLUS: case TK_MINUSMINUS: return true;
- }
- return false;
- }
- ExpState PopExpState()
- {
- ExpState ret = _expstates.top();
- _expstates.pop_back();
- return ret;
- }
- SQObject Expect(SQInteger tok)
- {
-
- if(_token != tok) {
- if(_token == TK_CONSTRUCTOR && tok == TK_IDENTIFIER) {
- //ret = SQString::Create(_ss(_vm),_SC("constructor"));
- //do nothing
- }
- else {
- const SQChar *etypename;
- if(tok > 255) {
- switch(tok)
- {
- case TK_IDENTIFIER:
- etypename = _SC("IDENTIFIER");
- break;
- case TK_STRING_LITERAL:
- etypename = _SC("STRING_LITERAL");
- break;
- case TK_INTEGER:
- etypename = _SC("INTEGER");
- break;
- case TK_FLOAT:
- etypename = _SC("FLOAT");
- break;
- default:
- etypename = _lex.Tok2Str(tok);
- }
- Error(_SC("expected '%s'"), etypename);
- }
- Error(_SC("expected '%c'"), tok);
- }
- }
- SQObjectPtr ret;
- switch(tok)
- {
- case TK_IDENTIFIER:
- ret = _fs->CreateString(_lex._svalue);
- break;
- case TK_STRING_LITERAL:
- ret = _fs->CreateString(_lex._svalue,_lex._longstr.size()-1);
- break;
- case TK_INTEGER:
- ret = SQObjectPtr(_lex._nvalue);
- break;
- case TK_FLOAT:
- ret = SQObjectPtr(_lex._fvalue);
- break;
- }
- Lex();
- return ret;
- }
- bool IsEndOfStatement() { return ((_lex._prevtoken == _SC('\n')) || (_token == SQUIRREL_EOB) || (_token == _SC('}')) || (_token == _SC(';'))); }
- void OptionalSemicolon()
- {
- if(_token == _SC(';')) { Lex(); return; }
- if(!IsEndOfStatement()) {
- Error(_SC("end of statement expected (; or lf)"));
- }
- }
- void MoveIfCurrentTargetIsLocal() {
- SQInteger trg = _fs->TopTarget();
- if(_fs->IsLocal(trg)) {
- trg = _fs->PopTarget(); //no pops the target and move it
- _fs->AddInstruction(_OP_MOVE, _fs->PushTarget(), trg);
- }
- }
- bool Compile(SQObjectPtr &o)
- {
- _debugline = 1;
- _debugop = 0;
-
- SQFuncState funcstate(_ss(_vm), NULL,ThrowError,this);
- funcstate._name = SQString::Create(_ss(_vm), _SC("main"));
- _fs = &funcstate;
- _fs->AddParameter(_fs->CreateString(_SC("this")));
- _fs->_sourcename = _sourcename;
- SQInteger stacksize = _fs->GetStackSize();
- if(setjmp(_errorjmp) == 0) {
- Lex();
- while(_token > 0){
- Statement();
- if(_lex._prevtoken != _SC('}')) OptionalSemicolon();
- }
- CleanStack(stacksize);
- _fs->AddLineInfos(_lex._currentline, _lineinfo, true);
- _fs->AddInstruction(_OP_RETURN, 0xFF);
- _fs->SetStackSize(0);
- o =_fs->BuildProto();
-#ifdef _DEBUG_DUMP
- _fs->Dump(_funcproto(o));
-#endif
- }
- else {
- if(_raiseerror && _ss(_vm)->_compilererrorhandler) {
- _ss(_vm)->_compilererrorhandler(_vm, compilererror, type(_sourcename) == OT_STRING?_stringval(_sourcename):_SC("unknown"),
- _lex._currentline, _lex._currentcolumn);
- }
- _vm->_lasterror = SQString::Create(_ss(_vm), compilererror, -1);
- return false;
- }
- return true;
- }
- void Statements()
- {
- while(_token != _SC('}') && _token != TK_DEFAULT && _token != TK_CASE) {
- Statement();
- if(_lex._prevtoken != _SC('}') && _lex._prevtoken != _SC(';')) OptionalSemicolon();
- }
- }
- void Statement()
- {
- _fs->AddLineInfos(_lex._currentline, _lineinfo);
- switch(_token){
- case _SC(';'): Lex(); break;
- case TK_IF: IfStatement(); break;
- case TK_WHILE: WhileStatement(); break;
- case TK_DO: DoWhileStatement(); break;
- case TK_FOR: ForStatement(); break;
- case TK_FOREACH: ForEachStatement(); break;
- case TK_SWITCH: SwitchStatement(); break;
- case TK_LOCAL: LocalDeclStatement(); break;
- case TK_RETURN:
- case TK_YIELD: {
- SQOpcode op;
- if(_token == TK_RETURN) {
- op = _OP_RETURN;
-
- }
- else {
- op = _OP_YIELD;
- _fs->_bgenerator = true;
- }
- Lex();
- if(!IsEndOfStatement()) {
- SQInteger retexp = _fs->GetCurrentPos()+1;
- CommaExpr();
- if(op == _OP_RETURN && _fs->_traps > 0)
- _fs->AddInstruction(_OP_POPTRAP, _fs->_traps, 0);
- _fs->_returnexp = retexp;
- _fs->AddInstruction(op, 1, _fs->PopTarget());
- }
- else{
- if(op == _OP_RETURN && _fs->_traps > 0)
- _fs->AddInstruction(_OP_POPTRAP, _fs->_traps ,0);
- _fs->_returnexp = -1;
- _fs->AddInstruction(op, 0xFF);
- }
- break;}
- case TK_BREAK:
- if(_fs->_breaktargets.size() <= 0)Error(_SC("'break' has to be in a loop block"));
- if(_fs->_breaktargets.top() > 0){
- _fs->AddInstruction(_OP_POPTRAP, _fs->_breaktargets.top(), 0);
- }
- _fs->AddInstruction(_OP_JMP, 0, -1234);
- _fs->_unresolvedbreaks.push_back(_fs->GetCurrentPos());
- Lex();
- break;
- case TK_CONTINUE:
- if(_fs->_continuetargets.size() <= 0)Error(_SC("'continue' has to be in a loop block"));
- if(_fs->_continuetargets.top() > 0) {
- _fs->AddInstruction(_OP_POPTRAP, _fs->_continuetargets.top(), 0);
- }
- _fs->AddInstruction(_OP_JMP, 0, -1234);
- _fs->_unresolvedcontinues.push_back(_fs->GetCurrentPos());
- Lex();
- break;
- case TK_FUNCTION:
- FunctionStatement();
- break;
- case TK_CLASS:
- ClassStatement();
- break;
- case _SC('{'):{
- SQInteger stacksize = _fs->GetStackSize();
- Lex();
- Statements();
- Expect(_SC('}'));
- _fs->SetStackSize(stacksize);
- }
- break;
- case TK_TRY:
- TryCatchStatement();
- break;
- case TK_THROW:
- Lex();
- CommaExpr();
- _fs->AddInstruction(_OP_THROW, _fs->PopTarget());
- break;
- default:
- CommaExpr();
- _fs->PopTarget();
- break;
- }
- _fs->SnoozeOpt();
- }
- void EmitDerefOp(SQOpcode op)
- {
- SQInteger val = _fs->PopTarget();
- SQInteger key = _fs->PopTarget();
- SQInteger src = _fs->PopTarget();
- _fs->AddInstruction(op,_fs->PushTarget(),src,key,val);
- }
- void Emit2ArgsOP(SQOpcode op, SQInteger p3 = 0)
- {
- SQInteger p2 = _fs->PopTarget(); //src in OP_GET
- SQInteger p1 = _fs->PopTarget(); //key in OP_GET
- _fs->AddInstruction(op,_fs->PushTarget(), p1, p2, p3);
- }
- void EmitCompoundArith(SQInteger tok,bool deref)
- {
- SQInteger oper;
- switch(tok){
- case TK_MINUSEQ: oper = '-'; break;
- case TK_PLUSEQ: oper = '+'; break;
- case TK_MULEQ: oper = '*'; break;
- case TK_DIVEQ: oper = '/'; break;
- case TK_MODEQ: oper = '%'; break;
- default: oper = 0; //shut up compiler
- assert(0); break;
- };
- if(deref) {
- SQInteger val = _fs->PopTarget();
- SQInteger key = _fs->PopTarget();
- SQInteger src = _fs->PopTarget();
- //mixes dest obj and source val in the arg1(hack?)
- _fs->AddInstruction(_OP_COMPARITH,_fs->PushTarget(),(src<<16)|val,key,oper);
- }
- else {
- Emit2ArgsOP(_OP_COMPARITHL, oper);
- }
- }
- void CommaExpr()
- {
- for(Expression();_token == ',';_fs->PopTarget(), Lex(), CommaExpr());
- }
- ExpState Expression(bool funcarg = false)
- {
- PushExpState();
- _exst._class_or_delete = false;
- _exst._funcarg = funcarg;
- LogicalOrExp();
- switch(_token) {
- case _SC('='):
- case TK_NEWSLOT:
- case TK_MINUSEQ:
- case TK_PLUSEQ:
- case TK_MULEQ:
- case TK_DIVEQ:
- case TK_MODEQ:
- {
- SQInteger op = _token;
- SQInteger ds = _exst._deref;
- bool freevar = _exst._freevar;
- if(ds == DEREF_NO_DEREF) Error(_SC("can't assign expression"));
- Lex(); Expression();
-
- switch(op){
- case TK_NEWSLOT:
- if(freevar) Error(_SC("free variables cannot be modified"));
- if(ds == DEREF_FIELD)
- EmitDerefOp(_OP_NEWSLOT);
- else //if _derefstate != DEREF_NO_DEREF && DEREF_FIELD so is the index of a local
- Error(_SC("can't 'create' a local slot"));
- break;
- case _SC('='): //ASSIGN
- if(freevar) Error(_SC("free variables cannot be modified"));
- if(ds == DEREF_FIELD)
- EmitDerefOp(_OP_SET);
- else {//if _derefstate != DEREF_NO_DEREF && DEREF_FIELD so is the index of a local
- SQInteger p2 = _fs->PopTarget(); //src in OP_GET
- SQInteger p1 = _fs->TopTarget(); //key in OP_GET
- _fs->AddInstruction(_OP_MOVE, p1, p2);
- }
- break;
- case TK_MINUSEQ:
- case TK_PLUSEQ:
- case TK_MULEQ:
- case TK_DIVEQ:
- case TK_MODEQ:
- EmitCompoundArith(op,ds == DEREF_FIELD);
- break;
- }
- }
- break;
- case _SC('?'): {
- Lex();
- _fs->AddInstruction(_OP_JZ, _fs->PopTarget());
- SQInteger jzpos = _fs->GetCurrentPos();
- SQInteger trg = _fs->PushTarget();
- Expression();
- SQInteger first_exp = _fs->PopTarget();
- if(trg != first_exp) _fs->AddInstruction(_OP_MOVE, trg, first_exp);
- SQInteger endfirstexp = _fs->GetCurrentPos();
- _fs->AddInstruction(_OP_JMP, 0, 0);
- Expect(_SC(':'));
- SQInteger jmppos = _fs->GetCurrentPos();
- Expression();
- SQInteger second_exp = _fs->PopTarget();
- if(trg != second_exp) _fs->AddInstruction(_OP_MOVE, trg, second_exp);
- _fs->SetIntructionParam(jmppos, 1, _fs->GetCurrentPos() - jmppos);
- _fs->SetIntructionParam(jzpos, 1, endfirstexp - jzpos + 1);
- _fs->SnoozeOpt();
- }
- break;
- }
- return PopExpState();
- }
- void BIN_EXP(SQOpcode op, void (SQCompiler::*f)(void),SQInteger op3 = 0)
- {
- Lex(); (this->*f)();
- SQInteger op1 = _fs->PopTarget();SQInteger op2 = _fs->PopTarget();
- _fs->AddInstruction(op, _fs->PushTarget(), op1, op2, op3);
- }
- void LogicalOrExp()
- {
- LogicalAndExp();
- for(;;) if(_token == TK_OR) {
- SQInteger first_exp = _fs->PopTarget();
- SQInteger trg = _fs->PushTarget();
- _fs->AddInstruction(_OP_OR, trg, 0, first_exp, 0);
- SQInteger jpos = _fs->GetCurrentPos();
- if(trg != first_exp) _fs->AddInstruction(_OP_MOVE, trg, first_exp);
- Lex(); LogicalOrExp();
- _fs->SnoozeOpt();
- SQInteger second_exp = _fs->PopTarget();
- if(trg != second_exp) _fs->AddInstruction(_OP_MOVE, trg, second_exp);
- _fs->SnoozeOpt();
- _fs->SetIntructionParam(jpos, 1, (_fs->GetCurrentPos() - jpos));
- break;
- }else return;
- }
- void LogicalAndExp()
- {
- BitwiseOrExp();
- for(;;) switch(_token) {
- case TK_AND: {
- SQInteger first_exp = _fs->PopTarget();
- SQInteger trg = _fs->PushTarget();
- _fs->AddInstruction(_OP_AND, trg, 0, first_exp, 0);
- SQInteger jpos = _fs->GetCurrentPos();
- if(trg != first_exp) _fs->AddInstruction(_OP_MOVE, trg, first_exp);
- Lex(); LogicalAndExp();
- _fs->SnoozeOpt();
- SQInteger second_exp = _fs->PopTarget();
- if(trg != second_exp) _fs->AddInstruction(_OP_MOVE, trg, second_exp);
- _fs->SnoozeOpt();
- _fs->SetIntructionParam(jpos, 1, (_fs->GetCurrentPos() - jpos));
- break;
- }
- case TK_IN: BIN_EXP(_OP_EXISTS, &SQCompiler::BitwiseOrExp); break;
- case TK_INSTANCEOF: BIN_EXP(_OP_INSTANCEOF, &SQCompiler::BitwiseOrExp); break;
- default:
- return;
- }
- }
- void BitwiseOrExp()
- {
- BitwiseXorExp();
- for(;;) if(_token == _SC('|'))
- {BIN_EXP(_OP_BITW, &SQCompiler::BitwiseXorExp,BW_OR);
- }else return;
- }
- void BitwiseXorExp()
- {
- BitwiseAndExp();
- for(;;) if(_token == _SC('^'))
- {BIN_EXP(_OP_BITW, &SQCompiler::BitwiseAndExp,BW_XOR);
- }else return;
- }
- void BitwiseAndExp()
- {
- CompExp();
- for(;;) if(_token == _SC('&'))
- {BIN_EXP(_OP_BITW, &SQCompiler::CompExp,BW_AND);
- }else return;
- }
- void CompExp()
- {
- ShiftExp();
- for(;;) switch(_token) {
- case TK_EQ: BIN_EXP(_OP_EQ, &SQCompiler::ShiftExp); break;
- case _SC('>'): BIN_EXP(_OP_CMP, &SQCompiler::ShiftExp,CMP_G); break;
- case _SC('<'): BIN_EXP(_OP_CMP, &SQCompiler::ShiftExp,CMP_L); break;
- case TK_GE: BIN_EXP(_OP_CMP, &SQCompiler::ShiftExp,CMP_GE); break;
- case TK_LE: BIN_EXP(_OP_CMP, &SQCompiler::ShiftExp,CMP_LE); break;
- case TK_NE: BIN_EXP(_OP_NE, &SQCompiler::ShiftExp); break;
- default: return;
- }
- }
- void ShiftExp()
- {
- PlusExp();
- for(;;) switch(_token) {
- case TK_USHIFTR: BIN_EXP(_OP_BITW, &SQCompiler::PlusExp,BW_USHIFTR); break;
- case TK_SHIFTL: BIN_EXP(_OP_BITW, &SQCompiler::PlusExp,BW_SHIFTL); break;
- case TK_SHIFTR: BIN_EXP(_OP_BITW, &SQCompiler::PlusExp,BW_SHIFTR); break;
- default: return;
- }
- }
- void PlusExp()
- {
- MultExp();
- for(;;) switch(_token) {
- case _SC('+'): case _SC('-'):
- BIN_EXP(_OP_ARITH, &SQCompiler::MultExp,_token); break;
- default: return;
- }
- }
-
- void MultExp()
- {
- PrefixedExpr();
- for(;;) switch(_token) {
- case _SC('*'): case _SC('/'): case _SC('%'):
- BIN_EXP(_OP_ARITH, &SQCompiler::PrefixedExpr,_token); break;
- default: return;
- }
- }
- //if 'pos' != -1 the previous variable is a local variable
- void PrefixedExpr()
- {
- SQInteger pos = Factor();
- for(;;) {
- switch(_token) {
- case _SC('.'): {
- pos = -1;
- Lex();
- if(_token == TK_PARENT) {
- Lex();
- if(!NeedGet())
- Error(_SC("parent cannot be set"));
- SQInteger src = _fs->PopTarget();
- _fs->AddInstruction(_OP_GETPARENT, _fs->PushTarget(), src);
- }
- else {
- _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetConstant(Expect(TK_IDENTIFIER)));
- if(NeedGet()) Emit2ArgsOP(_OP_GET);
- }
- _exst._deref = DEREF_FIELD;
- _exst._freevar = false;
- }
- break;
- case _SC('['):
- if(_lex._prevtoken == _SC('\n')) Error(_SC("cannot brake deref/or comma needed after [exp]=exp slot declaration"));
- Lex(); Expression(); Expect(_SC(']'));
- pos = -1;
- if(NeedGet()) Emit2ArgsOP(_OP_GET);
- _exst._deref = DEREF_FIELD;
- _exst._freevar = false;
- break;
- case TK_MINUSMINUS:
- case TK_PLUSPLUS:
- if(_exst._deref != DEREF_NO_DEREF && !IsEndOfStatement()) {
- SQInteger tok = _token; Lex();
- if(pos < 0)
- Emit2ArgsOP(_OP_PINC,tok == TK_MINUSMINUS?-1:1);
- else {//if _derefstate != DEREF_NO_DEREF && DEREF_FIELD so is the index of a local
- SQInteger src = _fs->PopTarget();
- _fs->AddInstruction(_OP_PINCL, _fs->PushTarget(), src, 0, tok == TK_MINUSMINUS?-1:1);
- }
-
- }
- return;
- break;
- case _SC('('):
- {
- if(_exst._deref != DEREF_NO_DEREF) {
- if(pos<0) {
- SQInteger key = _fs->PopTarget(); //key
- SQInteger table = _fs->PopTarget(); //table etc...
- SQInteger closure = _fs->PushTarget();
- SQInteger ttarget = _fs->PushTarget();
- _fs->AddInstruction(_OP_PREPCALL, closure, key, table, ttarget);
- }
- else{
- _fs->AddInstruction(_OP_MOVE, _fs->PushTarget(), 0);
- }
- }
- else
- _fs->AddInstruction(_OP_MOVE, _fs->PushTarget(), 0);
- _exst._deref = DEREF_NO_DEREF;
- Lex();
- FunctionCallArgs();
- }
- break;
- default: return;
- }
- }
- }
- SQInteger Factor()
- {
- switch(_token)
- {
- case TK_STRING_LITERAL: {
- //SQObjectPtr id(SQString::Create(_ss(_vm), _lex._svalue,_lex._longstr.size()-1));
- _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetConstant(_fs->CreateString(_lex._svalue,_lex._longstr.size()-1)));
- Lex();
- }
- break;
- case TK_VARGC: Lex(); _fs->AddInstruction(_OP_VARGC, _fs->PushTarget()); break;
- case TK_VARGV: { Lex();
- Expect(_SC('['));
- Expression();
- Expect(_SC(']'));
- SQInteger src = _fs->PopTarget();
- _fs->AddInstruction(_OP_GETVARGV, _fs->PushTarget(), src);
- }
- break;
- case TK_IDENTIFIER:
- case TK_CONSTRUCTOR:
- case TK_THIS:{
- _exst._freevar = false;
- SQObject id;
- switch(_token) {
- case TK_IDENTIFIER: id = _fs->CreateString(_lex._svalue); break;
- case TK_THIS: id = _fs->CreateString(_SC("this")); break;
- case TK_CONSTRUCTOR: id = _fs->CreateString(_SC("constructor")); break;
- }
- SQInteger pos = -1;
- Lex();
- if((pos = _fs->GetLocalVariable(id)) == -1) {
- //checks if is a free variable
- if((pos = _fs->GetOuterVariable(id)) != -1) {
- _exst._deref = _fs->PushTarget();
- _fs->AddInstruction(_OP_LOADFREEVAR, _exst._deref ,pos);
- _exst._freevar = true;
- } else {
- _fs->PushTarget(0);
- _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetConstant(id));
- if(NeedGet()) Emit2ArgsOP(_OP_GET);
- _exst._deref = DEREF_FIELD;
- }
- }
- else{
- _fs->PushTarget(pos);
- _exst._deref = pos;
- }
- return _exst._deref;
- }
- break;
- case TK_PARENT: Lex();_fs->AddInstruction(_OP_GETPARENT, _fs->PushTarget(), 0); break;
- case TK_DOUBLE_COLON: // "::"
- _fs->AddInstruction(_OP_LOADROOTTABLE, _fs->PushTarget());
- _exst._deref = DEREF_FIELD;
- _token = _SC('.'); //hack
- return -1;
- break;
- case TK_NULL:
- _fs->AddInstruction(_OP_LOADNULLS, _fs->PushTarget(),1);
- Lex();
- break;
- case TK_INTEGER: {
- if((_lex._nvalue & (~0x7FFFFFFF)) == 0) { //does it fit in 32 bits?
- _fs->AddInstruction(_OP_LOADINT, _fs->PushTarget(),_lex._nvalue);
- }
- else {
- _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetNumericConstant(_lex._nvalue));
- }
- Lex();
- }
- break;
- case TK_FLOAT:
- if(sizeof(SQFloat) == sizeof(SQInt32)) {
- _fs->AddInstruction(_OP_LOADFLOAT, _fs->PushTarget(),*((SQInt32 *)&_lex._fvalue));
- }
- else {
- _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetNumericConstant(_lex._fvalue));
- }
- Lex();
- break;
- case TK_TRUE: case TK_FALSE:
- _fs->AddInstruction(_OP_LOADBOOL, _fs->PushTarget(),_token == TK_TRUE?1:0);
- Lex();
- break;
- case _SC('['): {
- _fs->AddInstruction(_OP_NEWARRAY, _fs->PushTarget());
- SQInteger apos = _fs->GetCurrentPos(),key = 0;
- Lex();
- while(_token != _SC(']')) {
- Expression();
- if(_token == _SC(',')) Lex();
- SQInteger val = _fs->PopTarget();
- SQInteger array = _fs->TopTarget();
- _fs->AddInstruction(_OP_APPENDARRAY, array, val);
- key++;
- }
- _fs->SetIntructionParam(apos, 1, key);
- Lex();
- }
- break;
- case _SC('{'):{
- _fs->AddInstruction(_OP_NEWTABLE, _fs->PushTarget());
- Lex();ParseTableOrClass(_SC(','));
- }
- break;
- case TK_FUNCTION: FunctionExp(_token);break;
- case TK_CLASS: Lex(); ClassExp();break;
- case _SC('-'): UnaryOP(_OP_NEG); break;
- case _SC('!'): UnaryOP(_OP_NOT); break;
- case _SC('~'): UnaryOP(_OP_BWNOT); break;
- case TK_TYPEOF : UnaryOP(_OP_TYPEOF); break;
- case TK_RESUME : UnaryOP(_OP_RESUME); break;
- case TK_CLONE : UnaryOP(_OP_CLONE); break;
- case TK_MINUSMINUS :
- case TK_PLUSPLUS :PrefixIncDec(_token); break;
- case TK_DELETE : DeleteExpr(); break;
- case TK_DELEGATE : DelegateExpr(); break;
- case _SC('('): Lex(); CommaExpr(); Expect(_SC(')'));
- break;
- default: Error(_SC("expression expected"));
- }
- return -1;
- }
- void UnaryOP(SQOpcode op)
- {
- Lex(); PrefixedExpr();
- SQInteger src = _fs->PopTarget();
- _fs->AddInstruction(op, _fs->PushTarget(), src);
- }
- bool NeedGet()
- {
- switch(_token) {
- case _SC('='): case _SC('('): case TK_NEWSLOT: case TK_PLUSPLUS: case TK_MINUSMINUS:
- case TK_PLUSEQ: case TK_MINUSEQ: case TK_MULEQ: case TK_DIVEQ: case TK_MODEQ:
- return false;
- }
- return (!_exst._class_or_delete) || (_exst._class_or_delete && (_token == _SC('.') || _token == _SC('[')));
- }
-
- void FunctionCallArgs()
- {
- SQInteger nargs = 1;//this
- while(_token != _SC(')')) {
- Expression(true);
- MoveIfCurrentTargetIsLocal();
- nargs++;
- if(_token == _SC(',')){
- Lex();
- if(_token == ')') Error(_SC("expression expected, found ')'"));
- }
- }
- Lex();
- for(SQInteger i = 0; i < (nargs - 1); i++) _fs->PopTarget();
- SQInteger stackbase = _fs->PopTarget();
- SQInteger closure = _fs->PopTarget();
- _fs->AddInstruction(_OP_CALL, _fs->PushTarget(), closure, stackbase, nargs);
- }
- void ParseTableOrClass(SQInteger separator,SQInteger terminator = '}')
- {
- SQInteger tpos = _fs->GetCurrentPos(),nkeys = 0;
-
- while(_token != terminator) {
- bool hasattrs = false;
- bool isstatic = false;
- //check if is an attribute
- if(separator == ';') {
- if(_token == TK_ATTR_OPEN) {
- _fs->AddInstruction(_OP_NEWTABLE, _fs->PushTarget()); Lex();
- ParseTableOrClass(',',TK_ATTR_CLOSE);
- hasattrs = true;
- }
- if(_token == TK_STATIC) {
- isstatic = true;
- Lex();
- }
- }
- switch(_token) {
- case TK_FUNCTION:
- case TK_CONSTRUCTOR:{
- SQInteger tk = _token;
- Lex();
- SQObject id = tk == TK_FUNCTION ? Expect(TK_IDENTIFIER) : _fs->CreateString(_SC("constructor"));
- Expect(_SC('('));
- _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetConstant(id));
- CreateFunction(id);
- _fs->AddInstruction(_OP_CLOSURE, _fs->PushTarget(), _fs->_functions.size() - 1, 0);
- }
- break;
- case _SC('['):
- Lex(); CommaExpr(); Expect(_SC(']'));
- Expect(_SC('=')); Expression();
- break;
- default :
- _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetConstant(Expect(TK_IDENTIFIER)));
- Expect(_SC('=')); Expression();
- }
-
- if(_token == separator) Lex();//optional comma/semicolon
- nkeys++;
- SQInteger val = _fs->PopTarget();
- SQInteger key = _fs->PopTarget();
- SQInteger attrs = hasattrs ? _fs->PopTarget():-1;
- assert(hasattrs && attrs == key-1 || !hasattrs);
- unsigned char flags = (hasattrs?NEW_SLOT_ATTRIBUTES_FLAG:0)|(isstatic?NEW_SLOT_STATIC_FLAG:0);
- SQInteger table = _fs->TopTarget(); //<<BECAUSE OF THIS NO COMMON EMIT FUNC IS POSSIBLE
- _fs->AddInstruction(_OP_NEWSLOTA, flags, table, key, val);
- //_fs->PopTarget();
- }
- if(separator == _SC(',')) //hack recognizes a table from the separator
- _fs->SetIntructionParam(tpos, 1, nkeys);
- Lex();
- }
- void LocalDeclStatement()
- {
- SQObject varname;
- do {
- Lex(); varname = Expect(TK_IDENTIFIER);
- if(_token == _SC('=')) {
- Lex(); Expression();
- SQInteger src = _fs->PopTarget();
- SQInteger dest = _fs->PushTarget();
- if(dest != src) _fs->AddInstruction(_OP_MOVE, dest, src);
- }
- else{
- _fs->AddInstruction(_OP_LOADNULLS, _fs->PushTarget(),1);
- }
- _fs->PopTarget();
- _fs->PushLocalVariable(varname);
-
- } while(_token == _SC(','));
- }
- void IfStatement()
- {
- SQInteger jmppos;
- bool haselse = false;
- Lex(); Expect(_SC('(')); CommaExpr(); Expect(_SC(')'));
- _fs->AddInstruction(_OP_JZ, _fs->PopTarget());
- SQInteger jnepos = _fs->GetCurrentPos();
- SQInteger stacksize = _fs->GetStackSize();
-
- Statement();
- //
- if(_token != _SC('}') && _token != TK_ELSE) OptionalSemicolon();
-
- CleanStack(stacksize);
- SQInteger endifblock = _fs->GetCurrentPos();
- if(_token == TK_ELSE){
- haselse = true;
- stacksize = _fs->GetStackSize();
- _fs->AddInstruction(_OP_JMP);
- jmppos = _fs->GetCurrentPos();
- Lex();
- Statement(); OptionalSemicolon();
- CleanStack(stacksize);
- _fs->SetIntructionParam(jmppos, 1, _fs->GetCurrentPos() - jmppos);
- }
- _fs->SetIntructionParam(jnepos, 1, endifblock - jnepos + (haselse?1:0));
- }
- void WhileStatement()
- {
- SQInteger jzpos, jmppos;
- SQInteger stacksize = _fs->GetStackSize();
- jmppos = _fs->GetCurrentPos();
- Lex(); Expect(_SC('(')); CommaExpr(); Expect(_SC(')'));
-
- BEGIN_BREAKBLE_BLOCK();
- _fs->AddInstruction(_OP_JZ, _fs->PopTarget());
- jzpos = _fs->GetCurrentPos();
- stacksize = _fs->GetStackSize();
-
- Statement();
-
- CleanStack(stacksize);
- _fs->AddInstruction(_OP_JMP, 0, jmppos - _fs->GetCurrentPos() - 1);
- _fs->SetIntructionParam(jzpos, 1, _fs->GetCurrentPos() - jzpos);
-
- END_BREAKBLE_BLOCK(jmppos);
- }
- void DoWhileStatement()
- {
- Lex();
- SQInteger jzpos = _fs->GetCurrentPos();
- SQInteger stacksize = _fs->GetStackSize();
- BEGIN_BREAKBLE_BLOCK()
- Statement();
- CleanStack(stacksize);
- Expect(TK_WHILE);
- SQInteger continuetrg = _fs->GetCurrentPos();
- Expect(_SC('(')); CommaExpr(); Expect(_SC(')'));
- _fs->AddInstruction(_OP_JNZ, _fs->PopTarget(), jzpos - _fs->GetCurrentPos() - 1);
- END_BREAKBLE_BLOCK(continuetrg);
- }
- void ForStatement()
- {
- Lex();
- SQInteger stacksize = _fs->GetStackSize();
- Expect(_SC('('));
- if(_token == TK_LOCAL) LocalDeclStatement();
- else if(_token != _SC(';')){
- CommaExpr();
- _fs->PopTarget();
- }
- Expect(_SC(';'));
- _fs->SnoozeOpt();
- SQInteger jmppos = _fs->GetCurrentPos();
- SQInteger jzpos = -1;
- if(_token != _SC(';')) { CommaExpr(); _fs->AddInstruction(_OP_JZ, _fs->PopTarget()); jzpos = _fs->GetCurrentPos(); }
- Expect(_SC(';'));
- _fs->SnoozeOpt();
- SQInteger expstart = _fs->GetCurrentPos() + 1;
- if(_token != _SC(')')) {
- CommaExpr();
- _fs->PopTarget();
- }
- Expect(_SC(')'));
- _fs->SnoozeOpt();
- SQInteger expend = _fs->GetCurrentPos();
- SQInteger expsize = (expend - expstart) + 1;
- SQInstructionVec exp;
- if(expsize > 0) {
- for(SQInteger i = 0; i < expsize; i++)
- exp.push_back(_fs->GetInstruction(expstart + i));
- _fs->PopInstructions(expsize);
- }
- BEGIN_BREAKBLE_BLOCK()
- Statement();
- SQInteger continuetrg = _fs->GetCurrentPos();
- if(expsize > 0) {
- for(SQInteger i = 0; i < expsize; i++)
- _fs->AddInstruction(exp[i]);
- }
- _fs->AddInstruction(_OP_JMP, 0, jmppos - _fs->GetCurrentPos() - 1, 0);
- if(jzpos> 0) _fs->SetIntructionParam(jzpos, 1, _fs->GetCurrentPos() - jzpos);
- CleanStack(stacksize);
-
- END_BREAKBLE_BLOCK(continuetrg);
- }
- void ForEachStatement()
- {
- SQObject idxname, valname;
- Lex(); Expect(_SC('(')); valname = Expect(TK_IDENTIFIER);
- if(_token == _SC(',')) {
- idxname = valname;
- Lex(); valname = Expect(TK_IDENTIFIER);
- }
- else{
- idxname = _fs->CreateString(_SC("@INDEX@"));
- }
- Expect(TK_IN);
-
- //save the stack size
- SQInteger stacksize = _fs->GetStackSize();
- //put the table in the stack(evaluate the table expression)
- Expression(); Expect(_SC(')'));
- SQInteger container = _fs->TopTarget();
- //push the index local var
- SQInteger indexpos = _fs->PushLocalVariable(idxname);
- _fs->AddInstruction(_OP_LOADNULLS, indexpos,1);
- //push the value local var
- SQInteger valuepos = _fs->PushLocalVariable(valname);
- _fs->AddInstruction(_OP_LOADNULLS, valuepos,1);
- //push reference index
- SQInteger itrpos = _fs->PushLocalVariable(_fs->CreateString(_SC("@ITERATOR@"))); //use invalid id to make it inaccessible
- _fs->AddInstruction(_OP_LOADNULLS, itrpos,1);
- SQInteger jmppos = _fs->GetCurrentPos();
- _fs->AddInstruction(_OP_FOREACH, container, 0, indexpos);
- SQInteger foreachpos = _fs->GetCurrentPos();
- _fs->AddInstruction(_OP_POSTFOREACH, container, 0, indexpos);
- //generate the statement code
- BEGIN_BREAKBLE_BLOCK()
- Statement();
- _fs->AddInstruction(_OP_JMP, 0, jmppos - _fs->GetCurrentPos() - 1);
- _fs->SetIntructionParam(foreachpos, 1, _fs->GetCurrentPos() - foreachpos);
- _fs->SetIntructionParam(foreachpos + 1, 1, _fs->GetCurrentPos() - foreachpos);
- //restore the local variable stack(remove index,val and ref idx)
- CleanStack(stacksize);
- END_BREAKBLE_BLOCK(foreachpos - 1);
- }
- void SwitchStatement()
- {
- Lex(); Expect(_SC('(')); CommaExpr(); Expect(_SC(')'));
- Expect(_SC('{'));
- SQInteger expr = _fs->TopTarget();
- bool bfirst = true;
- SQInteger tonextcondjmp = -1;
- SQInteger skipcondjmp = -1;
- SQInteger __nbreaks__ = _fs->_unresolvedbreaks.size();
- _fs->_breaktargets.push_back(0);
- while(_token == TK_CASE) {
- //_fs->AddLineInfos(_lex._currentline, _lineinfo); think about this one
- if(!bfirst) {
- _fs->AddInstruction(_OP_JMP, 0, 0);
- skipcondjmp = _fs->GetCurrentPos();
- _fs->SetIntructionParam(tonextcondjmp, 1, _fs->GetCurrentPos() - tonextcondjmp);
- }
- //condition
- Lex(); Expression(); Expect(_SC(':'));
- SQInteger trg = _fs->PopTarget();
- _fs->AddInstruction(_OP_EQ, trg, trg, expr);
- _fs->AddInstruction(_OP_JZ, trg, 0);
- //end condition
- if(skipcondjmp != -1) {
- _fs->SetIntructionParam(skipcondjmp, 1, (_fs->GetCurrentPos() - skipcondjmp));
- }
- tonextcondjmp = _fs->GetCurrentPos();
- SQInteger stacksize = _fs->GetStackSize();
- Statements();
- _fs->SetStackSize(stacksize);
- bfirst = false;
- }
- if(tonextcondjmp != -1)
- _fs->SetIntructionParam(tonextcondjmp, 1, _fs->GetCurrentPos() - tonextcondjmp);
- if(_token == TK_DEFAULT) {
- // _fs->AddLineInfos(_lex._currentline, _lineinfo);
- Lex(); Expect(_SC(':'));
- SQInteger stacksize = _fs->GetStackSize();
- Statements();
- _fs->SetStackSize(stacksize);
- }
- Expect(_SC('}'));
- _fs->PopTarget();
- __nbreaks__ = _fs->_unresolvedbreaks.size() - __nbreaks__;
- if(__nbreaks__ > 0)ResolveBreaks(_fs, __nbreaks__);
- _fs->_breaktargets.pop_back();
-
- }
- void FunctionStatement()
- {
- SQObject id;
- Lex(); id = Expect(TK_IDENTIFIER);
- _fs->PushTarget(0);
- _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetConstant(id));
- if(_token == TK_DOUBLE_COLON) Emit2ArgsOP(_OP_GET);
-
- while(_token == TK_DOUBLE_COLON) {
- Lex();
- id = Expect(TK_IDENTIFIER);
- _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetConstant(id));
- if(_token == TK_DOUBLE_COLON) Emit2ArgsOP(_OP_GET);
- }
- Expect(_SC('('));
- CreateFunction(id);
- _fs->AddInstruction(_OP_CLOSURE, _fs->PushTarget(), _fs->_functions.size() - 1, 0);
- EmitDerefOp(_OP_NEWSLOT);
- _fs->PopTarget();
- }
- void ClassStatement()
- {
- ExpState es;
- Lex(); PushExpState();
- _exst._class_or_delete = true;
- _exst._funcarg = false;
- PrefixedExpr();
- es = PopExpState();
- if(es._deref == DEREF_NO_DEREF) Error(_SC("invalid class name"));
- if(es._deref == DEREF_FIELD) {
- ClassExp();
- EmitDerefOp(_OP_NEWSLOT);
- _fs->PopTarget();
- }
- else Error(_SC("cannot create a class in a local with the syntax(class <local>)"));
- }
- void TryCatchStatement()
- {
- SQObject exid;
- Lex();
- _fs->AddInstruction(_OP_PUSHTRAP,0,0);
- _fs->_traps++;
- if(_fs->_breaktargets.size()) _fs->_breaktargets.top()++;
- if(_fs->_continuetargets.size()) _fs->_continuetargets.top()++;
- SQInteger trappos = _fs->GetCurrentPos();
- Statement();
- _fs->_traps--;
- _fs->AddInstruction(_OP_POPTRAP, 1, 0);
- if(_fs->_breaktargets.size()) _fs->_breaktargets.top()--;
- if(_fs->_continuetargets.size()) _fs->_continuetargets.top()--;
- _fs->AddInstruction(_OP_JMP, 0, 0);
- SQInteger jmppos = _fs->GetCurrentPos();
- _fs->SetIntructionParam(trappos, 1, (_fs->GetCurrentPos() - trappos));
- Expect(TK_CATCH); Expect(_SC('(')); exid = Expect(TK_IDENTIFIER); Expect(_SC(')'));
- SQInteger stacksize = _fs->GetStackSize();
- SQInteger ex_target = _fs->PushLocalVariable(exid);
- _fs->SetIntructionParam(trappos, 0, ex_target);
- Statement();
- _fs->SetIntructionParams(jmppos, 0, (_fs->GetCurrentPos() - jmppos), 0);
- CleanStack(stacksize);
- }
- void FunctionExp(SQInteger ftype)
- {
- Lex(); Expect(_SC('('));
- CreateFunction(_null_);
- _fs->AddInstruction(_OP_CLOSURE, _fs->PushTarget(), _fs->_functions.size() - 1, ftype == TK_FUNCTION?0:1);
- }
- void ClassExp()
- {
- SQInteger base = -1;
- SQInteger attrs = -1;
- if(_token == TK_EXTENDS) {
- Lex(); Expression();
- base = _fs->TopTarget();
- }
- if(_token == TK_ATTR_OPEN) {
- Lex();
- _fs->AddInstruction(_OP_NEWTABLE, _fs->PushTarget());
- ParseTableOrClass(_SC(','),TK_ATTR_CLOSE);
- attrs = _fs->TopTarget();
- }
- Expect(_SC('{'));
- if(attrs != -1) _fs->PopTarget();
- if(base != -1) _fs->PopTarget();
- _fs->AddInstruction(_OP_CLASS, _fs->PushTarget(), base, attrs);
- ParseTableOrClass(_SC(';'));
- }
- void DelegateExpr()
- {
- Lex(); CommaExpr();
- Expect(_SC(':'));
- CommaExpr();
- SQInteger table = _fs->PopTarget(), delegate = _fs->PopTarget();
- _fs->AddInstruction(_OP_DELEGATE, _fs->PushTarget(), table, delegate);
- }
- void DeleteExpr()
- {
- ExpState es;
- Lex(); PushExpState();
- _exst._class_or_delete = true;
- _exst._funcarg = false;
- PrefixedExpr();
- es = PopExpState();
- if(es._deref == DEREF_NO_DEREF) Error(_SC("can't delete an expression"));
- if(es._deref == DEREF_FIELD) Emit2ArgsOP(_OP_DELETE);
- else Error(_SC("cannot delete a local"));
- }
- void PrefixIncDec(SQInteger token)
- {
- ExpState es;
- Lex(); PushExpState();
- _exst._class_or_delete = true;
- _exst._funcarg = false;
- PrefixedExpr();
- es = PopExpState();
- if(es._deref == DEREF_FIELD) Emit2ArgsOP(_OP_INC,token == TK_MINUSMINUS?-1:1);
- else {
- SQInteger src = _fs->PopTarget();
- _fs->AddInstruction(_OP_INCL, _fs->PushTarget(), src, 0, token == TK_MINUSMINUS?-1:1);
- }
- }
- void CreateFunction(SQObject &name)
- {
-
- SQFuncState *funcstate = _fs->PushChildState(_ss(_vm));
- funcstate->_name = name;
- SQObject paramname;
- funcstate->AddParameter(_fs->CreateString(_SC("this")));
- funcstate->_sourcename = _sourcename;
- while(_token!=_SC(')')) {
- if(_token == TK_VARPARAMS) {
- funcstate->_varparams = true;
- Lex();
- if(_token != _SC(')')) Error(_SC("expected ')'"));
- break;
- }
- else {
- paramname = Expect(TK_IDENTIFIER);
- funcstate->AddParameter(paramname);
- if(_token == _SC(',')) Lex();
- else if(_token != _SC(')')) Error(_SC("expected ')' or ','"));
- }
- }
- Expect(_SC(')'));
- //outer values
- if(_token == _SC(':')) {
- Lex(); Expect(_SC('('));
- while(_token != _SC(')')) {
- paramname = Expect(TK_IDENTIFIER);
- //outers are treated as implicit local variables
- funcstate->AddOuterValue(paramname);
- if(_token == _SC(',')) Lex();
- else if(_token != _SC(')')) Error(_SC("expected ')' or ','"));
- }
- Lex();
- }
-
- SQFuncState *currchunk = _fs;
- _fs = funcstate;
- Statement();
- funcstate->AddLineInfos(_lex._prevtoken == _SC('\n')?_lex._lasttokenline:_lex._currentline, _lineinfo, true);
- funcstate->AddInstruction(_OP_RETURN, -1);
- funcstate->SetStackSize(0);
- //_fs->->_stacksize = _fs->_stacksize;
- SQFunctionProto *func = funcstate->BuildProto();
-#ifdef _DEBUG_DUMP
- funcstate->Dump(func);
-#endif
- _fs = currchunk;
- _fs->_functions.push_back(func);
- _fs->PopChildState();
- }
- void CleanStack(SQInteger stacksize)
- {
- if(_fs->GetStackSize() != stacksize)
- _fs->SetStackSize(stacksize);
- }
- void ResolveBreaks(SQFuncState *funcstate, SQInteger ntoresolve)
- {
- while(ntoresolve > 0) {
- SQInteger pos = funcstate->_unresolvedbreaks.back();
- funcstate->_unresolvedbreaks.pop_back();
- //set the jmp instruction
- funcstate->SetIntructionParams(pos, 0, funcstate->GetCurrentPos() - pos, 0);
- ntoresolve--;
- }
- }
- void ResolveContinues(SQFuncState *funcstate, SQInteger ntoresolve, SQInteger targetpos)
- {
- while(ntoresolve > 0) {
- SQInteger pos = funcstate->_unresolvedcontinues.back();
- funcstate->_unresolvedcontinues.pop_back();
- //set the jmp instruction
- funcstate->SetIntructionParams(pos, 0, targetpos - pos, 0);
- ntoresolve--;
- }
- }
-private:
- SQInteger _token;
- SQFuncState *_fs;
- SQObjectPtr _sourcename;
- SQLexer _lex;
- bool _lineinfo;
- bool _raiseerror;
- SQInteger _debugline;
- SQInteger _debugop;
- ExpStateVec _expstates;
- SQChar *compilererror;
- jmp_buf _errorjmp;
- SQVM *_vm;
-};
-
-bool Compile(SQVM *vm,SQLEXREADFUNC rg, SQUserPointer up, const SQChar *sourcename, SQObjectPtr &out, bool raiseerror, bool lineinfo)
-{
- SQCompiler p(vm, rg, up, sourcename, raiseerror, lineinfo);
- return p.Compile(out);
-}
+++ /dev/null
-/* see copyright notice in squirrel.h */
-#ifndef _SQCOMPILER_H_
-#define _SQCOMPILER_H_
-
-struct SQVM;
-
-#define TK_IDENTIFIER 258
-#define TK_STRING_LITERAL 259
-#define TK_INTEGER 260
-#define TK_FLOAT 261
-#define TK_DELEGATE 262
-#define TK_DELETE 263
-#define TK_EQ 264
-#define TK_NE 265
-#define TK_LE 266
-#define TK_GE 267
-#define TK_SWITCH 268
-#define TK_ARROW 269
-#define TK_AND 270
-#define TK_OR 271
-#define TK_IF 272
-#define TK_ELSE 273
-#define TK_WHILE 274
-#define TK_BREAK 275
-#define TK_FOR 276
-#define TK_DO 277
-#define TK_NULL 278
-#define TK_FOREACH 279
-#define TK_IN 280
-#define TK_NEWSLOT 281
-#define TK_MODULO 282
-#define TK_LOCAL 283
-#define TK_CLONE 284
-#define TK_FUNCTION 285
-#define TK_RETURN 286
-#define TK_TYPEOF 287
-#define TK_UMINUS 288
-#define TK_PLUSEQ 289
-#define TK_MINUSEQ 290
-#define TK_CONTINUE 291
-#define TK_YIELD 292
-#define TK_TRY 293
-#define TK_CATCH 294
-#define TK_THROW 295
-#define TK_SHIFTL 296
-#define TK_SHIFTR 297
-#define TK_RESUME 298
-#define TK_DOUBLE_COLON 299
-#define TK_CASE 300
-#define TK_DEFAULT 301
-#define TK_THIS 302
-#define TK_PLUSPLUS 303
-#define TK_MINUSMINUS 304
-#define TK_PARENT 305
-#define TK_USHIFTR 306
-#define TK_CLASS 307
-#define TK_EXTENDS 308
-#define TK_CONSTRUCTOR 310
-#define TK_INSTANCEOF 311
-#define TK_VARPARAMS 312
-#define TK_VARGC 313
-#define TK_VARGV 314
-#define TK_TRUE 315
-#define TK_FALSE 316
-#define TK_MULEQ 317
-#define TK_DIVEQ 318
-#define TK_MODEQ 319
-#define TK_ATTR_OPEN 320
-#define TK_ATTR_CLOSE 321
-#define TK_STATIC 322
-
-
-typedef void(*CompilerErrorFunc)(void *ud, const SQChar *s);
-bool Compile(SQVM *vm, SQLEXREADFUNC rg, SQUserPointer up, const SQChar *sourcename, SQObjectPtr &out, bool raiseerror, bool lineinfo);
-#endif //_SQCOMPILER_H_
+++ /dev/null
-/*
- see copyright notice in squirrel.h
-*/
-#include "sqpcheader.h"
-#include <stdarg.h>
-#include "sqvm.h"
-#include "sqfuncproto.h"
-#include "sqclosure.h"
-#include "sqstring.h"
-
-SQRESULT sq_stackinfos(HSQUIRRELVM v, SQInteger level, SQStackInfos *si)
-{
- SQInteger cssize = v->_callsstacksize;
- if (cssize > level) {
- memset(si, 0, sizeof(SQStackInfos));
- SQVM::CallInfo &ci = v->_callsstack[cssize-level-1];
- switch (type(ci._closure)) {
- case OT_CLOSURE:{
- SQFunctionProto *func = _funcproto(_closure(ci._closure)->_function);
- if (type(func->_name) == OT_STRING)
- si->funcname = _stringval(func->_name);
- if (type(func->_sourcename) == OT_STRING)
- si->source = _stringval(func->_sourcename);
- si->line = func->GetLine(ci._ip);
- }
- break;
- case OT_NATIVECLOSURE:
- si->source = _SC("NATIVE");
- si->funcname = _SC("unknown");
- if(type(_nativeclosure(ci._closure)->_name) == OT_STRING)
- si->funcname = _stringval(_nativeclosure(ci._closure)->_name);
- si->line = -1;
- break;
- default: break; //shutup compiler
- }
- return SQ_OK;
- }
- return SQ_ERROR;
-}
-
-void SQVM::Raise_Error(const SQChar *s, ...)
-{
- va_list vl;
- va_start(vl, s);
- scvsprintf(_sp(rsl((SQInteger)scstrlen(s)+(NUMBER_MAX_CHAR*2))), s, vl);
- va_end(vl);
- _lasterror = SQString::Create(_ss(this),_spval,-1);
-}
-
-void SQVM::Raise_Error(SQObjectPtr &desc)
-{
- _lasterror = desc;
-}
-
-SQString *SQVM::PrintObjVal(const SQObject &o)
-{
- switch(type(o)) {
- case OT_STRING: return _string(o);
- case OT_INTEGER:
- scsprintf(_sp(rsl(NUMBER_MAX_CHAR+1)), _SC("%d"), _integer(o));
- return SQString::Create(_ss(this), _spval);
- break;
- case OT_FLOAT:
- scsprintf(_sp(rsl(NUMBER_MAX_CHAR+1)), _SC("%.14g"), _float(o));
- return SQString::Create(_ss(this), _spval);
- break;
- default:
- return SQString::Create(_ss(this), GetTypeName(o));
- }
-}
-
-void SQVM::Raise_IdxError(SQObject &o)
-{
- SQObjectPtr oval = PrintObjVal(o);
- Raise_Error(_SC("the index '%.50s' does not exist"), _stringval(oval));
-}
-
-void SQVM::Raise_CompareError(const SQObject &o1, const SQObject &o2)
-{
- SQObjectPtr oval1 = PrintObjVal(o1), oval2 = PrintObjVal(o2);
- Raise_Error(_SC("comparsion between '%.50s' and '%.50s'"), _stringval(oval1), _stringval(oval2));
-}
-
-
-void SQVM::Raise_ParamTypeError(SQInteger nparam,SQInteger typemask,SQInteger type)
-{
- SQObjectPtr exptypes = SQString::Create(_ss(this), _SC(""), -1);
- SQInteger found = 0;
- for(SQInteger i=0; i<16; i++)
- {
- SQInteger mask = 0x00000001 << i;
- if(typemask & (mask)) {
- if(found>0) StringCat(exptypes,SQString::Create(_ss(this), _SC("|"), -1), exptypes);
- found ++;
- StringCat(exptypes,SQString::Create(_ss(this), IdType2Name((SQObjectType)mask), -1), exptypes);
- }
- }
- Raise_Error(_SC("parameter %d has an invalid type '%s' ; expected: '%s'"), nparam, IdType2Name((SQObjectType)type), _stringval(exptypes));
-}
+++ /dev/null
-/* see copyright notice in squirrel.h */
-#ifndef _SQFUNCTION_H_
-#define _SQFUNCTION_H_
-
-#include "sqopcodes.h"
-
-enum SQOuterType {
- otLOCAL = 0,
- otSYMBOL = 1,
- otOUTER = 2
-};
-
-struct SQOuterVar
-{
-
- SQOuterVar(){}
- SQOuterVar(const SQObjectPtr &name,const SQObjectPtr &src,SQOuterType t)
- {
- _name = name;
- _src=src;
- _type=t;
- }
- SQOuterVar(const SQOuterVar &ov)
- {
- _type=ov._type;
- _src=ov._src;
- _name=ov._name;
- }
- SQOuterType _type;
- SQObjectPtr _name;
- SQObjectPtr _src;
-};
-
-struct SQLocalVarInfo
-{
- SQLocalVarInfo():_start_op(0),_end_op(0){}
- SQLocalVarInfo(const SQLocalVarInfo &lvi)
- {
- _name=lvi._name;
- _start_op=lvi._start_op;
- _end_op=lvi._end_op;
- _pos=lvi._pos;
- }
- SQObjectPtr _name;
- SQUnsignedInteger _start_op;
- SQUnsignedInteger _end_op;
- SQUnsignedInteger _pos;
-};
-
-struct SQLineInfo { SQInteger _line;SQInteger _op; };
-
-typedef sqvector<SQOuterVar> SQOuterVarVec;
-typedef sqvector<SQLocalVarInfo> SQLocalVarInfoVec;
-typedef sqvector<SQLineInfo> SQLineInfoVec;
-
-#define _FUNC_SIZE(ni,nl,nparams,nfuncs,nouters,nlineinf,localinf) (sizeof(SQFunctionProto) \
- +((ni-1)*sizeof(SQInstruction))+(nl*sizeof(SQObjectPtr)) \
- +(nparams*sizeof(SQObjectPtr))+(nfuncs*sizeof(SQObjectPtr)) \
- +(nouters*sizeof(SQOuterVar))+(nlineinf*sizeof(SQLineInfo)) \
- +(localinf*sizeof(SQLocalVarInfo)))
-
-#define _CONSTRUCT_VECTOR(type,size,ptr) { \
- for(SQInteger n = 0; n < size; n++) { \
- new (&ptr[n]) type(); \
- } \
-}
-
-#define _DESTRUCT_VECTOR(type,size,ptr) { \
- for(SQInteger nl = 0; nl < size; nl++) { \
- ptr[nl].~type(); \
- } \
-}
-struct SQFunctionProto : public SQRefCounted
-{
-private:
- SQFunctionProto(){
- _stacksize=0;
- _bgenerator=false;}
-public:
- static SQFunctionProto *Create(SQInteger ninstructions,
- SQInteger nliterals,SQInteger nparameters,
- SQInteger nfunctions,SQInteger noutervalues,
- SQInteger nlineinfos,SQInteger nlocalvarinfos)
- {
- SQFunctionProto *f;
- //I compact the whole class and members in a single memory allocation
- f = (SQFunctionProto *)sq_vm_malloc(_FUNC_SIZE(ninstructions,nliterals,nparameters,nfunctions,noutervalues,nlineinfos,nlocalvarinfos));
- new (f) SQFunctionProto;
- f->_ninstructions = ninstructions;
- f->_literals = (SQObjectPtr*)&f->_instructions[ninstructions];
- f->_nliterals = nliterals;
- f->_parameters = (SQObjectPtr*)&f->_literals[nliterals];
- f->_nparameters = nparameters;
- f->_functions = (SQObjectPtr*)&f->_parameters[nparameters];
- f->_nfunctions = nfunctions;
- f->_outervalues = (SQOuterVar*)&f->_functions[nfunctions];
- f->_noutervalues = noutervalues;
- f->_lineinfos = (SQLineInfo *)&f->_outervalues[noutervalues];
- f->_nlineinfos = nlineinfos;
- f->_localvarinfos = (SQLocalVarInfo *)&f->_lineinfos[nlineinfos];
- f->_nlocalvarinfos = nlocalvarinfos;
-
- _CONSTRUCT_VECTOR(SQObjectPtr,f->_nliterals,f->_literals);
- _CONSTRUCT_VECTOR(SQObjectPtr,f->_nparameters,f->_parameters);
- _CONSTRUCT_VECTOR(SQObjectPtr,f->_nfunctions,f->_functions);
- _CONSTRUCT_VECTOR(SQOuterVar,f->_noutervalues,f->_outervalues);
- //_CONSTRUCT_VECTOR(SQLineInfo,f->_nlineinfos,f->_lineinfos); //not required are 2 integers
- _CONSTRUCT_VECTOR(SQLocalVarInfo,f->_nlocalvarinfos,f->_localvarinfos);
- return f;
- }
- void Release(){
- _DESTRUCT_VECTOR(SQObjectPtr,_nliterals,_literals);
- _DESTRUCT_VECTOR(SQObjectPtr,_nparameters,_parameters);
- _DESTRUCT_VECTOR(SQObjectPtr,_nfunctions,_functions);
- _DESTRUCT_VECTOR(SQOuterVar,_noutervalues,_outervalues);
- //_DESTRUCT_VECTOR(SQLineInfo,_nlineinfos,_lineinfos); //not required are 2 integers
- _DESTRUCT_VECTOR(SQLocalVarInfo,_nlocalvarinfos,_localvarinfos);
- SQInteger size = _FUNC_SIZE(_ninstructions,_nliterals,_nparameters,_nfunctions,_noutervalues,_nlineinfos,_nlocalvarinfos);
- this->~SQFunctionProto();
- sq_vm_free(this,size);
- }
- const SQChar* GetLocal(SQVM *v,SQUnsignedInteger stackbase,SQUnsignedInteger nseq,SQUnsignedInteger nop);
- SQInteger GetLine(SQInstruction *curr);
- bool Save(SQVM *v,SQUserPointer up,SQWRITEFUNC write);
- static bool Load(SQVM *v,SQUserPointer up,SQREADFUNC read,SQObjectPtr &ret);
-
- SQObjectPtr _sourcename;
- SQObjectPtr _name;
- SQInteger _stacksize;
- bool _bgenerator;
- bool _varparams;
-
- SQInteger _nlocalvarinfos;
- SQLocalVarInfo *_localvarinfos;
-
- SQInteger _nlineinfos;
- SQLineInfo *_lineinfos;
-
- SQInteger _nliterals;
- SQObjectPtr *_literals;
-
- SQInteger _nparameters;
- SQObjectPtr *_parameters;
-
- SQInteger _nfunctions;
- SQObjectPtr *_functions;
-
- SQInteger _noutervalues;
- SQOuterVar *_outervalues;
-
- SQInteger _ninstructions;
- SQInstruction _instructions[1];
-};
-
-#endif //_SQFUNCTION_H_
+++ /dev/null
-/*
- see copyright notice in squirrel.h
-*/
-#include "sqpcheader.h"
-#include "sqcompiler.h"
-#include "sqfuncproto.h"
-#include "sqstring.h"
-#include "sqtable.h"
-#include "sqopcodes.h"
-#include "sqfuncstate.h"
-
-#ifdef _DEBUG_DUMP
-SQInstructionDesc g_InstrDesc[]={
- {_SC("_OP_LINE")},
- {_SC("_OP_LOAD")},
- {_SC("_OP_LOADINT")},
- {_SC("_OP_LOADFLOAT")},
- {_SC("_OP_DLOAD")},
- {_SC("_OP_TAILCALL")},
- {_SC("_OP_CALL")},
- {_SC("_OP_PREPCALL")},
- {_SC("_OP_PREPCALLK")},
- {_SC("_OP_GETK")},
- {_SC("_OP_MOVE")},
- {_SC("_OP_NEWSLOT")},
- {_SC("_OP_DELETE")},
- {_SC("_OP_SET")},
- {_SC("_OP_GET")},
- {_SC("_OP_EQ")},
- {_SC("_OP_NE")},
- {_SC("_OP_ARITH")},
- {_SC("_OP_BITW")},
- {_SC("_OP_RETURN")},
- {_SC("_OP_LOADNULLS")},
- {_SC("_OP_LOADROOTTABLE")},
- {_SC("_OP_LOADBOOL")},
- {_SC("_OP_DMOVE")},
- {_SC("_OP_JMP")},
- {_SC("_OP_JNZ")},
- {_SC("_OP_JZ")},
- {_SC("_OP_LOADFREEVAR")},
- {_SC("_OP_VARGC")},
- {_SC("_OP_GETVARGV")},
- {_SC("_OP_NEWTABLE")},
- {_SC("_OP_NEWARRAY")},
- {_SC("_OP_APPENDARRAY")},
- {_SC("_OP_GETPARENT")},
- {_SC("_OP_COMPARITH")},
- {_SC("_OP_COMPARITHL")},
- {_SC("_OP_INC")},
- {_SC("_OP_INCL")},
- {_SC("_OP_PINC")},
- {_SC("_OP_PINCL")},
- {_SC("_OP_CMP")},
- {_SC("_OP_EXISTS")},
- {_SC("_OP_INSTANCEOF")},
- {_SC("_OP_AND")},
- {_SC("_OP_OR")},
- {_SC("_OP_NEG")},
- {_SC("_OP_NOT")},
- {_SC("_OP_BWNOT")},
- {_SC("_OP_CLOSURE")},
- {_SC("_OP_YIELD")},
- {_SC("_OP_RESUME")},
- {_SC("_OP_FOREACH")},
- {_SC("_OP_POSTFOREACH")},
- {_SC("_OP_DELEGATE")},
- {_SC("_OP_CLONE")},
- {_SC("_OP_TYPEOF")},
- {_SC("_OP_PUSHTRAP")},
- {_SC("_OP_POPTRAP")},
- {_SC("_OP_THROW")},
- {_SC("_OP_CLASS")},
- {_SC("_OP_NEWSLOTA")}
-};
-#endif
-void DumpLiteral(SQObjectPtr &o)
-{
- switch(type(o)){
- case OT_STRING: scprintf(_SC("\"%s\""),_stringval(o));break;
- case OT_FLOAT: scprintf(_SC("{%f}"),_float(o));break;
- case OT_INTEGER: scprintf(_SC("{%d}"),_integer(o));break;
- default: assert(0); break; //shut up compiler
- }
-}
-
-SQFuncState::SQFuncState(SQSharedState *ss,SQFuncState *parent,CompilerErrorFunc efunc,void *ed)
-{
- _nliterals = 0;
- _literals = SQTable::Create(ss,0);
- _strings = SQTable::Create(ss,0);
- _sharedstate = ss;
- _lastline = 0;
- _optimization = true;
- _parent = parent;
- _stacksize = 0;
- _traps = 0;
- _returnexp = 0;
- _varparams = false;
- _errfunc = efunc;
- _errtarget = ed;
- _bgenerator = false;
-
-}
-
-void SQFuncState::Error(const SQChar *err)
-{
- _errfunc(_errtarget,err);
-}
-
-#ifdef _DEBUG_DUMP
-void SQFuncState::Dump(SQFunctionProto *func)
-{
- SQUnsignedInteger n=0,i;
- SQInteger si;
- scprintf(_SC("SQInstruction sizeof %d\n"),sizeof(SQInstruction));
- scprintf(_SC("SQObject sizeof %d\n"),sizeof(SQObject));
- scprintf(_SC("--------------------------------------------------------------------\n"));
- scprintf(_SC("*****FUNCTION [%s]\n"),type(func->_name)==OT_STRING?_stringval(func->_name):_SC("unknown"));
- scprintf(_SC("-----LITERALS\n"));
- SQObjectPtr refidx,key,val;
- SQInteger idx;
- SQObjectPtrVec templiterals;
- templiterals.resize(_nliterals);
- while((idx=_table(_literals)->Next(false,refidx,key,val))!=-1) {
- refidx=idx;
- templiterals[_integer(val)]=key;
- }
- for(i=0;i<templiterals.size();i++){
- scprintf(_SC("[%d] "),n);
- DumpLiteral(templiterals[i]);
- scprintf(_SC("\n"));
- n++;
- }
- scprintf(_SC("-----PARAMS\n"));
- if(_varparams)
- scprintf(_SC("<<VARPARAMS>>\n"));
- n=0;
- for(i=0;i<_parameters.size();i++){
- scprintf(_SC("[%d] "),n);
- DumpLiteral(_parameters[i]);
- scprintf(_SC("\n"));
- n++;
- }
- scprintf(_SC("-----LOCALS\n"));
- for(si=0;si<func->_nlocalvarinfos;si++){
- SQLocalVarInfo lvi=func->_localvarinfos[si];
- scprintf(_SC("[%d] %s \t%d %d\n"),lvi._pos,_stringval(lvi._name),lvi._start_op,lvi._end_op);
- n++;
- }
- scprintf(_SC("-----LINE INFO\n"));
- for(i=0;i<_lineinfos.size();i++){
- SQLineInfo li=_lineinfos[i];
- scprintf(_SC("op [%d] line [%d] \n"),li._op,li._line);
- n++;
- }
- scprintf(_SC("-----dump\n"));
- n=0;
- for(i=0;i<_instructions.size();i++){
- SQInstruction &inst=_instructions[i];
- if(inst.op==_OP_LOAD || inst.op==_OP_DLOAD || inst.op==_OP_PREPCALLK || inst.op==_OP_GETK ){
-
- SQInteger lidx = inst._arg1;
- scprintf(_SC("[%03d] %15s %d "),n,g_InstrDesc[inst.op].name,inst._arg0);
- if(lidx >= 0xFFFFFFFF)
- scprintf(_SC("null"));
- else {
- SQInteger refidx;
- SQObjectPtr val,key,refo;
- while(((refidx=_table(_literals)->Next(false,refo,key,val))!= -1) && (_integer(val) != lidx)) {
- refo = refidx;
- }
- DumpLiteral(key);
- }
- if(inst.op != _OP_DLOAD) {
- scprintf(_SC(" %d %d \n"),inst._arg2,inst._arg3);
- }
- else {
- scprintf(_SC(" %d "),inst._arg2);
- lidx = inst._arg3;
- if(lidx >= 0xFFFFFFFF)
- scprintf(_SC("null"));
- else {
- SQInteger refidx;
- SQObjectPtr val,key,refo;
- while(((refidx=_table(_literals)->Next(false,refo,key,val))!= -1) && (_integer(val) != lidx)) {
- refo = refidx;
- }
- DumpLiteral(key);
- scprintf(_SC("\n"));
- }
- }
- }
- else if(inst.op==_OP_LOADFLOAT) {
- scprintf(_SC("[%03d] %15s %d %f %d %d\n"),n,g_InstrDesc[inst.op].name,inst._arg0,*((SQFloat*)&inst._arg1),inst._arg2,inst._arg3);
- }
- else if(inst.op==_OP_ARITH){
- scprintf(_SC("[%03d] %15s %d %d %d %c\n"),n,g_InstrDesc[inst.op].name,inst._arg0,inst._arg1,inst._arg2,inst._arg3);
- }
- else
- scprintf(_SC("[%03d] %15s %d %d %d %d\n"),n,g_InstrDesc[inst.op].name,inst._arg0,inst._arg1,inst._arg2,inst._arg3);
- n++;
- }
- scprintf(_SC("-----\n"));
- scprintf(_SC("stack size[%d]\n"),func->_stacksize);
- scprintf(_SC("--------------------------------------------------------------------\n\n"));
-}
-#endif
-
-SQInteger SQFuncState::GetNumericConstant(const SQInteger cons)
-{
- return GetConstant(SQObjectPtr(cons));
-}
-
-SQInteger SQFuncState::GetNumericConstant(const SQFloat cons)
-{
- return GetConstant(SQObjectPtr(cons));
-}
-
-SQInteger SQFuncState::GetConstant(const SQObject &cons)
-{
- SQObjectPtr val;
- if(!_table(_literals)->Get(cons,val))
- {
- val = _nliterals;
- _table(_literals)->NewSlot(cons,val);
- _nliterals++;
- if(_nliterals > MAX_LITERALS) {
- val.Null();
- Error(_SC("internal compiler error: too many literals"));
- }
- }
- return _integer(val);
-}
-
-void SQFuncState::SetIntructionParams(SQInteger pos,SQInteger arg0,SQInteger arg1,SQInteger arg2,SQInteger arg3)
-{
- _instructions[pos]._arg0=(unsigned char)*((SQUnsignedInteger *)&arg0);
- _instructions[pos]._arg1=(SQInt32)*((SQUnsignedInteger *)&arg1);
- _instructions[pos]._arg2=(unsigned char)*((SQUnsignedInteger *)&arg2);
- _instructions[pos]._arg3=(unsigned char)*((SQUnsignedInteger *)&arg3);
-}
-
-void SQFuncState::SetIntructionParam(SQInteger pos,SQInteger arg,SQInteger val)
-{
- switch(arg){
- case 0:_instructions[pos]._arg0=(unsigned char)*((SQUnsignedInteger *)&val);break;
- case 1:case 4:_instructions[pos]._arg1=(SQInt32)*((SQUnsignedInteger *)&val);break;
- case 2:_instructions[pos]._arg2=(unsigned char)*((SQUnsignedInteger *)&val);break;
- case 3:_instructions[pos]._arg3=(unsigned char)*((SQUnsignedInteger *)&val);break;
- };
-}
-
-SQInteger SQFuncState::AllocStackPos()
-{
- SQInteger npos=_vlocals.size();
- _vlocals.push_back(SQLocalVarInfo());
- if(_vlocals.size()>((SQUnsignedInteger)_stacksize)) {
- if(_stacksize>MAX_FUNC_STACKSIZE) Error(_SC("internal compiler error: too many locals"));
- _stacksize=_vlocals.size();
- }
- return npos;
-}
-
-SQInteger SQFuncState::PushTarget(SQInteger n)
-{
- if(n!=-1){
- _targetstack.push_back(n);
- return n;
- }
- n=AllocStackPos();
- _targetstack.push_back(n);
- return n;
-}
-
-SQInteger SQFuncState::GetUpTarget(SQInteger n){
- return _targetstack[((_targetstack.size()-1)-n)];
-}
-
-SQInteger SQFuncState::TopTarget(){
- return _targetstack.back();
-}
-SQInteger SQFuncState::PopTarget()
-{
- SQInteger npos=_targetstack.back();
- SQLocalVarInfo t=_vlocals[_targetstack.back()];
- if(type(t._name)==OT_NULL){
- _vlocals.pop_back();
- }
- _targetstack.pop_back();
- return npos;
-}
-
-SQInteger SQFuncState::GetStackSize()
-{
- return _vlocals.size();
-}
-
-void SQFuncState::SetStackSize(SQInteger n)
-{
- SQInteger size=_vlocals.size();
- while(size>n){
- size--;
- SQLocalVarInfo lvi=_vlocals.back();
- if(type(lvi._name)!=OT_NULL){
- lvi._end_op=GetCurrentPos();
- _localvarinfos.push_back(lvi);
- }
- _vlocals.pop_back();
- }
-}
-
-bool SQFuncState::IsLocal(SQUnsignedInteger stkpos)
-{
- if(stkpos>=_vlocals.size())return false;
- else if(type(_vlocals[stkpos]._name)!=OT_NULL)return true;
- return false;
-}
-
-SQInteger SQFuncState::PushLocalVariable(const SQObject &name)
-{
- SQInteger pos=_vlocals.size();
- SQLocalVarInfo lvi;
- lvi._name=name;
- lvi._start_op=GetCurrentPos()+1;
- lvi._pos=_vlocals.size();
- _vlocals.push_back(lvi);
- if(_vlocals.size()>((SQUnsignedInteger)_stacksize))_stacksize=_vlocals.size();
-
- return pos;
-}
-
-SQInteger SQFuncState::GetLocalVariable(const SQObject &name)
-{
- SQInteger locals=_vlocals.size();
- while(locals>=1){
- if(type(_vlocals[locals-1]._name)==OT_STRING && _string(_vlocals[locals-1]._name)==_string(name)){
- return locals-1;
- }
- locals--;
- }
- return -1;
-}
-
-SQInteger SQFuncState::GetOuterVariable(const SQObject &name)
-{
- SQInteger outers = _outervalues.size();
- for(SQInteger i = 0; i<outers; i++) {
- if(_string(_outervalues[i]._name) == _string(name))
- return i;
- }
- return -1;
-}
-
-void SQFuncState::AddOuterValue(const SQObject &name)
-{
- SQInteger pos=-1;
- if(_parent) {
- pos = _parent->GetLocalVariable(name);
- if(pos == -1) {
- pos = _parent->GetOuterVariable(name);
- if(pos != -1) {
- _outervalues.push_back(SQOuterVar(name,SQObjectPtr(SQInteger(pos)),otOUTER)); //local
- return;
- }
- }
- else {
- _outervalues.push_back(SQOuterVar(name,SQObjectPtr(SQInteger(pos)),otLOCAL)); //local
- return;
- }
- }
- _outervalues.push_back(SQOuterVar(name,name,otSYMBOL)); //global
-}
-
-void SQFuncState::AddParameter(const SQObject &name)
-{
- PushLocalVariable(name);
- _parameters.push_back(name);
-}
-
-void SQFuncState::AddLineInfos(SQInteger line,bool lineop,bool force)
-{
- if(_lastline!=line || force){
- SQLineInfo li;
- li._line=line;li._op=(GetCurrentPos()+1);
- if(lineop)AddInstruction(_OP_LINE,0,line);
- _lineinfos.push_back(li);
- _lastline=line;
- }
-}
-
-void SQFuncState::AddInstruction(SQInstruction &i)
-{
- SQInteger size = _instructions.size();
- if(size > 0 && _optimization){ //simple optimizer
- SQInstruction &pi = _instructions[size-1];//previous instruction
- switch(i.op) {
- case _OP_RETURN:
- if( _parent && i._arg0 != MAX_FUNC_STACKSIZE && pi.op == _OP_CALL && _returnexp < size-1) {
- pi.op = _OP_TAILCALL;
- }
- break;
- case _OP_GET:
- if( pi.op == _OP_LOAD && pi._arg0 == i._arg2 && (!IsLocal(pi._arg0))){
- pi._arg1 = pi._arg1;
- pi._arg2 = (unsigned char)i._arg1;
- pi.op = _OP_GETK;
- pi._arg0 = i._arg0;
-
- return;
- }
- break;
- case _OP_PREPCALL:
- if( pi.op == _OP_LOAD && pi._arg0 == i._arg1 && (!IsLocal(pi._arg0))){
- pi.op = _OP_PREPCALLK;
- pi._arg0 = i._arg0;
- pi._arg1 = pi._arg1;
- pi._arg2 = i._arg2;
- pi._arg3 = i._arg3;
- return;
- }
- break;
- case _OP_APPENDARRAY:
- if(pi.op == _OP_LOAD && pi._arg0 == i._arg1 && (!IsLocal(pi._arg0))){
- pi.op = _OP_APPENDARRAY;
- pi._arg0 = i._arg0;
- pi._arg1 = pi._arg1;
- pi._arg2 = MAX_FUNC_STACKSIZE;
- pi._arg3 = MAX_FUNC_STACKSIZE;
- return;
- }
- break;
- case _OP_MOVE:
- if((pi.op == _OP_GET || pi.op == _OP_ARITH || pi.op == _OP_BITW) && (pi._arg0 == i._arg1))
- {
- pi._arg0 = i._arg0;
- _optimization = false;
- return;
- }
-
- if(pi.op == _OP_MOVE)
- {
- pi.op = _OP_DMOVE;
- pi._arg2 = i._arg0;
- pi._arg3 = (unsigned char)i._arg1;
- return;
- }
- break;
- case _OP_LOAD:
- if(pi.op == _OP_LOAD && i._arg1 < 256) {
- pi.op = _OP_DLOAD;
- pi._arg2 = i._arg0;
- pi._arg3 = (unsigned char)i._arg1;
- return;
- }
- break;
- case _OP_EQ:case _OP_NE:
- if(pi.op == _OP_LOAD && pi._arg0 == i._arg1 && (!IsLocal(pi._arg0) ))
- {
- pi.op = i.op;
- pi._arg0 = i._arg0;
- pi._arg1 = pi._arg1;
- pi._arg2 = i._arg2;
- pi._arg3 = MAX_FUNC_STACKSIZE;
- return;
- }
- break;
- case _OP_LOADNULLS:
- if((pi.op == _OP_LOADNULLS && pi._arg0+pi._arg1 == i._arg0)) {
-
- pi._arg1 = pi._arg1 + 1;
- pi.op = _OP_LOADNULLS;
- return;
- }
- break;
- case _OP_LINE:
- if(pi.op == _OP_LINE) {
- _instructions.pop_back();
- _lineinfos.pop_back();
- }
- break;
- }
- }
- _optimization = true;
- _instructions.push_back(i);
-}
-
-SQObject SQFuncState::CreateString(const SQChar *s,SQInteger len)
-{
- SQObjectPtr ns(SQString::Create(_sharedstate,s,len));
- _table(_strings)->NewSlot(ns,(SQInteger)1);
- return ns;
-}
-
-SQFunctionProto *SQFuncState::BuildProto()
-{
- SQFunctionProto *f=SQFunctionProto::Create(_instructions.size(),
- _nliterals,_parameters.size(),_functions.size(),_outervalues.size(),
- _lineinfos.size(),_localvarinfos.size());
-
- SQObjectPtr refidx,key,val;
- SQInteger idx;
-
- f->_stacksize = _stacksize;
- f->_sourcename = _sourcename;
- f->_bgenerator = _bgenerator;
- f->_name = _name;
-
- while((idx=_table(_literals)->Next(false,refidx,key,val))!=-1) {
- f->_literals[_integer(val)]=key;
- refidx=idx;
- }
-
- for(SQUnsignedInteger nf = 0; nf < _functions.size(); nf++) f->_functions[nf] = _functions[nf];
- for(SQUnsignedInteger np = 0; np < _parameters.size(); np++) f->_parameters[np] = _parameters[np];
- for(SQUnsignedInteger no = 0; no < _outervalues.size(); no++) f->_outervalues[no] = _outervalues[no];
- for(SQUnsignedInteger no = 0; no < _localvarinfos.size(); no++) f->_localvarinfos[no] = _localvarinfos[no];
- for(SQUnsignedInteger no = 0; no < _lineinfos.size(); no++) f->_lineinfos[no] = _lineinfos[no];
-
- memcpy(f->_instructions,&_instructions[0],_instructions.size()*sizeof(SQInstruction));
-
- f->_varparams = _varparams;
-
- return f;
-}
-
-SQFuncState *SQFuncState::PushChildState(SQSharedState *ss)
-{
- SQFuncState *child = (SQFuncState *)sq_malloc(sizeof(SQFuncState));
- new (child) SQFuncState(ss,this,_errfunc,_errtarget);
- _childstates.push_back(child);
- return child;
-}
-
-void SQFuncState::PopChildState()
-{
- SQFuncState *child = _childstates.back();
- sq_delete(child,SQFuncState);
- _childstates.pop_back();
-}
-
-SQFuncState::~SQFuncState()
-{
- while(_childstates.size() > 0)
- {
- PopChildState();
- }
-}
+++ /dev/null
-/* see copyright notice in squirrel.h */
-#ifndef _SQFUNCSTATE_H_
-#define _SQFUNCSTATE_H_
-///////////////////////////////////
-#include "squtils.h"
-
-struct SQFuncState
-{
- SQFuncState(SQSharedState *ss,SQFuncState *parent,CompilerErrorFunc efunc,void *ed);
- ~SQFuncState();
-#ifdef _DEBUG_DUMP
- void Dump(SQFunctionProto *func);
-#endif
- void Error(const SQChar *err);
- SQFuncState *PushChildState(SQSharedState *ss);
- void PopChildState();
- void AddInstruction(SQOpcode _op,SQInteger arg0=0,SQInteger arg1=0,SQInteger arg2=0,SQInteger arg3=0){SQInstruction i(_op,arg0,arg1,arg2,arg3);AddInstruction(i);}
- void AddInstruction(SQInstruction &i);
- void SetIntructionParams(SQInteger pos,SQInteger arg0,SQInteger arg1,SQInteger arg2=0,SQInteger arg3=0);
- void SetIntructionParam(SQInteger pos,SQInteger arg,SQInteger val);
- SQInstruction &GetInstruction(SQInteger pos){return _instructions[pos];}
- void PopInstructions(SQInteger size){for(SQInteger i=0;i<size;i++)_instructions.pop_back();}
- void SetStackSize(SQInteger n);
- void SnoozeOpt(){_optimization=false;}
- SQInteger GetCurrentPos(){return _instructions.size()-1;}
- SQInteger GetNumericConstant(const SQInteger cons);
- SQInteger GetNumericConstant(const SQFloat cons);
- SQInteger PushLocalVariable(const SQObject &name);
- void AddParameter(const SQObject &name);
- void AddOuterValue(const SQObject &name);
- SQInteger GetLocalVariable(const SQObject &name);
- SQInteger GetOuterVariable(const SQObject &name);
- SQInteger GenerateCode();
- SQInteger GetStackSize();
- SQInteger CalcStackFrameSize();
- void AddLineInfos(SQInteger line,bool lineop,bool force=false);
- SQFunctionProto *BuildProto();
- SQInteger AllocStackPos();
- SQInteger PushTarget(SQInteger n=-1);
- SQInteger PopTarget();
- SQInteger TopTarget();
- SQInteger GetUpTarget(SQInteger n);
- bool IsLocal(SQUnsignedInteger stkpos);
- SQObject CreateString(const SQChar *s,SQInteger len = -1);
- SQInteger _returnexp;
- SQLocalVarInfoVec _vlocals;
- SQIntVec _targetstack;
- SQInteger _stacksize;
- bool _varparams;
- bool _bgenerator;
- SQIntVec _unresolvedbreaks;
- SQIntVec _unresolvedcontinues;
- SQObjectPtrVec _functions;
- SQObjectPtrVec _parameters;
- SQOuterVarVec _outervalues;
- SQInstructionVec _instructions;
- SQLocalVarInfoVec _localvarinfos;
- SQObjectPtr _literals;
- SQObjectPtr _strings;
- SQObjectPtr _name;
- SQObjectPtr _sourcename;
- SQInteger _nliterals;
- SQLineInfoVec _lineinfos;
- SQFuncState *_parent;
- SQIntVec _breaktargets;
- SQIntVec _continuetargets;
- SQInteger _lastline;
- SQInteger _traps; //contains number of nested exception traps
- bool _optimization;
- SQSharedState *_sharedstate;
- sqvector<SQFuncState*> _childstates;
- SQInteger GetConstant(const SQObject &cons);
-private:
- CompilerErrorFunc _errfunc;
- void *_errtarget;
-};
-
-
-#endif //_SQFUNCSTATE_H_
-
+++ /dev/null
-/*
- see copyright notice in squirrel.h
-*/
-#include "sqpcheader.h"
-#include <ctype.h>
-#include <stdlib.h>
-#include "sqtable.h"
-#include "sqstring.h"
-#include "sqcompiler.h"
-#include "sqlexer.h"
-
-#define CUR_CHAR (_currdata)
-#define RETURN_TOKEN(t) { _prevtoken = _curtoken; _curtoken = t; return t;}
-#define IS_EOB() (CUR_CHAR <= SQUIRREL_EOB)
-#define NEXT() {Next();_currentcolumn++;}
-#define INIT_TEMP_STRING() { _longstr.resize(0);}
-#define APPEND_CHAR(c) { _longstr.push_back(c);}
-#define TERMINATE_BUFFER() {_longstr.push_back(_SC('\0'));}
-#define ADD_KEYWORD(key,id) _keywords->NewSlot( SQString::Create(ss, _SC(#key)) ,SQInteger(id))
-
-SQLexer::SQLexer(){}
-SQLexer::~SQLexer()
-{
- _keywords->Release();
-}
-
-void SQLexer::Init(SQSharedState *ss, SQLEXREADFUNC rg, SQUserPointer up,CompilerErrorFunc efunc,void *ed)
-{
- _errfunc = efunc;
- _errtarget = ed;
- _sharedstate = ss;
- _keywords = SQTable::Create(ss, 26);
- ADD_KEYWORD(while, TK_WHILE);
- ADD_KEYWORD(do, TK_DO);
- ADD_KEYWORD(if, TK_IF);
- ADD_KEYWORD(else, TK_ELSE);
- ADD_KEYWORD(break, TK_BREAK);
- ADD_KEYWORD(continue, TK_CONTINUE);
- ADD_KEYWORD(return, TK_RETURN);
- ADD_KEYWORD(null, TK_NULL);
- ADD_KEYWORD(function, TK_FUNCTION);
- ADD_KEYWORD(local, TK_LOCAL);
- ADD_KEYWORD(for, TK_FOR);
- ADD_KEYWORD(foreach, TK_FOREACH);
- ADD_KEYWORD(in, TK_IN);
- ADD_KEYWORD(typeof, TK_TYPEOF);
- ADD_KEYWORD(delegate, TK_DELEGATE);
- ADD_KEYWORD(delete, TK_DELETE);
- ADD_KEYWORD(try, TK_TRY);
- ADD_KEYWORD(catch, TK_CATCH);
- ADD_KEYWORD(throw, TK_THROW);
- ADD_KEYWORD(clone, TK_CLONE);
- ADD_KEYWORD(yield, TK_YIELD);
- ADD_KEYWORD(resume, TK_RESUME);
- ADD_KEYWORD(switch, TK_SWITCH);
- ADD_KEYWORD(case, TK_CASE);
- ADD_KEYWORD(default, TK_DEFAULT);
- ADD_KEYWORD(this, TK_THIS);
- ADD_KEYWORD(parent,TK_PARENT);
- ADD_KEYWORD(class,TK_CLASS);
- ADD_KEYWORD(extends,TK_EXTENDS);
- ADD_KEYWORD(constructor,TK_CONSTRUCTOR);
- ADD_KEYWORD(instanceof,TK_INSTANCEOF);
- ADD_KEYWORD(vargc,TK_VARGC);
- ADD_KEYWORD(vargv,TK_VARGV);
- ADD_KEYWORD(true,TK_TRUE);
- ADD_KEYWORD(false,TK_FALSE);
- ADD_KEYWORD(static,TK_STATIC);
-
- _readf = rg;
- _up = up;
- _lasttokenline = _currentline = 1;
- _currentcolumn = 0;
- _prevtoken = -1;
- Next();
-}
-
-void SQLexer::Error(const SQChar *err)
-{
- _errfunc(_errtarget,err);
-}
-
-void SQLexer::Next()
-{
- SQInteger t = _readf(_up);
- if(t > MAX_CHAR) Error(_SC("Invalid character"));
- if(t != 0) {
- _currdata = (LexChar)t;
- return;
- }
- _currdata = SQUIRREL_EOB;
-}
-
-const SQChar *SQLexer::Tok2Str(SQInteger tok)
-{
- SQObjectPtr itr, key, val;
- SQInteger nitr;
- while((nitr = _keywords->Next(false,itr, key, val)) != -1) {
- itr = (SQInteger)nitr;
- if(((SQInteger)_integer(val)) == tok)
- return _stringval(key);
- }
- return NULL;
-}
-
-void SQLexer::LexBlockComment()
-{
- bool done = false;
- while(!done) {
- switch(CUR_CHAR) {
- case _SC('*'): { NEXT(); if(CUR_CHAR == _SC('/')) { done = true; NEXT(); }}; continue;
- case _SC('\n'): _currentline++; NEXT(); continue;
- case SQUIRREL_EOB: Error(_SC("missing \"*/\" in comment"));
- default: NEXT();
- }
- }
-}
-
-SQInteger SQLexer::Lex()
-{
- _lasttokenline = _currentline;
- while(CUR_CHAR != SQUIRREL_EOB) {
- switch(CUR_CHAR){
- case _SC('\t'): case _SC('\r'): case _SC(' '): NEXT(); continue;
- case _SC('\n'):
- _currentline++;
- _prevtoken=_curtoken;
- _curtoken=_SC('\n');
- NEXT();
- _currentcolumn=1;
- continue;
- case _SC('/'):
- NEXT();
- switch(CUR_CHAR){
- case _SC('*'):
- NEXT();
- LexBlockComment();
- continue;
- case _SC('/'):
- do { NEXT(); } while (CUR_CHAR != _SC('\n') && (!IS_EOB()));
- continue;
- case _SC('='):
- NEXT();
- RETURN_TOKEN(TK_DIVEQ);
- continue;
- case _SC('>'):
- NEXT();
- RETURN_TOKEN(TK_ATTR_CLOSE);
- continue;
- default:
- RETURN_TOKEN('/');
- }
- case _SC('='):
- NEXT();
- if (CUR_CHAR != _SC('=')){ RETURN_TOKEN('=') }
- else { NEXT(); RETURN_TOKEN(TK_EQ); }
- case _SC('<'):
- NEXT();
- if ( CUR_CHAR == _SC('=') ) { NEXT(); RETURN_TOKEN(TK_LE) }
- else if ( CUR_CHAR == _SC('-') ) { NEXT(); RETURN_TOKEN(TK_NEWSLOT); }
- else if ( CUR_CHAR == _SC('<') ) { NEXT(); RETURN_TOKEN(TK_SHIFTL); }
- else if ( CUR_CHAR == _SC('/') ) { NEXT(); RETURN_TOKEN(TK_ATTR_OPEN); }
- //else if ( CUR_CHAR == _SC('[') ) { NEXT(); ReadMultilineString(); RETURN_TOKEN(TK_STRING_LITERAL); }
- else { RETURN_TOKEN('<') }
- case _SC('>'):
- NEXT();
- if (CUR_CHAR == _SC('=')){ NEXT(); RETURN_TOKEN(TK_GE);}
- else if(CUR_CHAR == _SC('>')){
- NEXT();
- if(CUR_CHAR == _SC('>')){
- NEXT();
- RETURN_TOKEN(TK_USHIFTR);
- }
- RETURN_TOKEN(TK_SHIFTR);
- }
- else { RETURN_TOKEN('>') }
- case _SC('!'):
- NEXT();
- if (CUR_CHAR != _SC('=')){ RETURN_TOKEN('!')}
- else { NEXT(); RETURN_TOKEN(TK_NE); }
- case _SC('@'): {
- SQInteger stype;
- NEXT();
- if(CUR_CHAR != _SC('"'))
- Error(_SC("string expected"));
- if((stype=ReadString('"',true))!=-1) {
- RETURN_TOKEN(stype);
- }
- Error(_SC("error parsing the string"));
- }
- case _SC('"'):
- case _SC('\''): {
- SQInteger stype;
- if((stype=ReadString(CUR_CHAR,false))!=-1){
- RETURN_TOKEN(stype);
- }
- Error(_SC("error parsing the string"));
- }
- case _SC('{'): case _SC('}'): case _SC('('): case _SC(')'): case _SC('['): case _SC(']'):
- case _SC(';'): case _SC(','): case _SC('?'): case _SC('^'): case _SC('~'):
- {SQInteger ret = CUR_CHAR;
- NEXT(); RETURN_TOKEN(ret); }
- case _SC('.'):
- NEXT();
- if (CUR_CHAR != _SC('.')){ RETURN_TOKEN('.') }
- NEXT();
- if (CUR_CHAR != _SC('.')){ Error(_SC("invalid token '..'")); }
- NEXT();
- RETURN_TOKEN(TK_VARPARAMS);
- case _SC('&'):
- NEXT();
- if (CUR_CHAR != _SC('&')){ RETURN_TOKEN('&') }
- else { NEXT(); RETURN_TOKEN(TK_AND); }
- case _SC('|'):
- NEXT();
- if (CUR_CHAR != _SC('|')){ RETURN_TOKEN('|') }
- else { NEXT(); RETURN_TOKEN(TK_OR); }
- case _SC(':'):
- NEXT();
- if (CUR_CHAR != _SC(':')){ RETURN_TOKEN(':') }
- else { NEXT(); RETURN_TOKEN(TK_DOUBLE_COLON); }
- case _SC('*'):
- NEXT();
- if (CUR_CHAR == _SC('=')){ NEXT(); RETURN_TOKEN(TK_MULEQ);}
- else RETURN_TOKEN('*');
- case _SC('%'):
- NEXT();
- if (CUR_CHAR == _SC('=')){ NEXT(); RETURN_TOKEN(TK_MODEQ);}
- else RETURN_TOKEN('%');
- case _SC('-'):
- NEXT();
- if (CUR_CHAR == _SC('=')){ NEXT(); RETURN_TOKEN(TK_MINUSEQ);}
- else if (CUR_CHAR == _SC('-')){ NEXT(); RETURN_TOKEN(TK_MINUSMINUS);}
- else RETURN_TOKEN('-');
- case _SC('+'):
- NEXT();
- if (CUR_CHAR == _SC('=')){ NEXT(); RETURN_TOKEN(TK_PLUSEQ);}
- else if (CUR_CHAR == _SC('+')){ NEXT(); RETURN_TOKEN(TK_PLUSPLUS);}
- else RETURN_TOKEN('+');
- case SQUIRREL_EOB:
- return 0;
- default:{
- if (scisdigit(CUR_CHAR)) {
- SQInteger ret = ReadNumber();
- RETURN_TOKEN(ret);
- }
- else if (scisalpha(CUR_CHAR) || CUR_CHAR == _SC('_')) {
- SQInteger t = ReadID();
- RETURN_TOKEN(t);
- }
- else {
- SQInteger c = CUR_CHAR;
- if (sciscntrl((int)c)) Error(_SC("unexpected character(control)"));
- NEXT();
- RETURN_TOKEN(c);
- }
- RETURN_TOKEN(0);
- }
- }
- }
- return 0;
-}
-
-SQInteger SQLexer::GetIDType(SQChar *s)
-{
- SQObjectPtr t;
- if(_keywords->Get(SQString::Create(_sharedstate, s), t)) {
- return SQInteger(_integer(t));
- }
- return TK_IDENTIFIER;
-}
-
-
-SQInteger SQLexer::ReadString(SQInteger ndelim,bool verbatim)
-{
- INIT_TEMP_STRING();
- NEXT();
- if(IS_EOB()) return -1;
- for(;;) {
- while(CUR_CHAR != ndelim) {
- switch(CUR_CHAR) {
- case SQUIRREL_EOB:
- Error(_SC("unfinished string"));
- return -1;
- case _SC('\n'):
- if(!verbatim) Error(_SC("newline in a constant"));
- APPEND_CHAR(CUR_CHAR); NEXT();
- _currentline++;
- break;
- case _SC('\\'):
- if(verbatim) {
- APPEND_CHAR('\\'); NEXT();
- }
- else {
- NEXT();
- switch(CUR_CHAR) {
- case _SC('x'): NEXT(); {
- if(!isxdigit(CUR_CHAR)) Error(_SC("hexadecimal number expected"));
- const SQInteger maxdigits = 4;
- SQChar temp[maxdigits+1];
- SQInteger n = 0;
- while(isxdigit(CUR_CHAR) && n < maxdigits) {
- temp[n] = CUR_CHAR;
- n++;
- NEXT();
- }
- temp[n] = 0;
- SQChar *sTemp;
- APPEND_CHAR((SQChar)scstrtoul(temp,&sTemp,16));
- }
- break;
- case _SC('t'): APPEND_CHAR(_SC('\t')); NEXT(); break;
- case _SC('a'): APPEND_CHAR(_SC('\a')); NEXT(); break;
- case _SC('b'): APPEND_CHAR(_SC('\b')); NEXT(); break;
- case _SC('n'): APPEND_CHAR(_SC('\n')); NEXT(); break;
- case _SC('r'): APPEND_CHAR(_SC('\r')); NEXT(); break;
- case _SC('v'): APPEND_CHAR(_SC('\v')); NEXT(); break;
- case _SC('f'): APPEND_CHAR(_SC('\f')); NEXT(); break;
- case _SC('0'): APPEND_CHAR(_SC('\0')); NEXT(); break;
- case _SC('\\'): APPEND_CHAR(_SC('\\')); NEXT(); break;
- case _SC('"'): APPEND_CHAR(_SC('"')); NEXT(); break;
- case _SC('\''): APPEND_CHAR(_SC('\'')); NEXT(); break;
- default:
- Error(_SC("unrecognised escaper char"));
- break;
- }
- }
- break;
- default:
- APPEND_CHAR(CUR_CHAR);
- NEXT();
- }
- }
- NEXT();
- if(verbatim && CUR_CHAR == '"') { //double quotation
- APPEND_CHAR(CUR_CHAR);
- NEXT();
- }
- else {
- break;
- }
- }
- TERMINATE_BUFFER();
- SQInteger len = _longstr.size()-1;
- if(ndelim == _SC('\'')) {
- if(len == 0) Error(_SC("empty constant"));
- if(len > 1) Error(_SC("constant too long"));
- _nvalue = _longstr[0];
- return TK_INTEGER;
- }
- _svalue = &_longstr[0];
- return TK_STRING_LITERAL;
-}
-
-void LexHexadecimal(const SQChar *s,SQUnsignedInteger *res)
-{
- *res = 0;
- while(*s != 0)
- {
- if(scisdigit(*s)) *res = (*res)*16+((*s++)-'0');
- else if(scisxdigit(*s)) *res = (*res)*16+(toupper(*s++)-'A'+10);
- else { assert(0); }
- }
-}
-
-void LexInteger(const SQChar *s,SQUnsignedInteger *res)
-{
- *res = 0;
- while(*s != 0)
- {
- *res = (*res)*10+((*s++)-'0');
- }
-}
-
-SQInteger isexponent(SQInteger c) { return c == 'e' || c=='E'; }
-#define MAX_HEX_DIGITS (sizeof(SQInteger)*2)
-SQInteger SQLexer::ReadNumber()
-{
-#define TINT 1
-#define TFLOAT 2
-#define THEX 3
-#define TSCIENTIFIC 4
- SQInteger type = TINT, firstchar = CUR_CHAR;
- SQChar *sTemp;
- INIT_TEMP_STRING();
- NEXT();
- if(firstchar == _SC('0') && toupper(CUR_CHAR) == _SC('X')) {
- NEXT();
- type = THEX;
- while(isxdigit(CUR_CHAR)) {
- APPEND_CHAR(CUR_CHAR);
- NEXT();
- }
- if(_longstr.size() > MAX_HEX_DIGITS) Error(_SC("too many digits for an Hex number"));
- }
- else {
- APPEND_CHAR((int)firstchar);
- while (CUR_CHAR == _SC('.') || scisdigit(CUR_CHAR) || isexponent(CUR_CHAR)) {
- if(CUR_CHAR == _SC('.')) type = TFLOAT;
- if(isexponent(CUR_CHAR)) {
- if(type != TFLOAT) Error(_SC("invalid numeric format"));
- type = TSCIENTIFIC;
- APPEND_CHAR(CUR_CHAR);
- NEXT();
- if(CUR_CHAR == '+' || CUR_CHAR == '-'){
- APPEND_CHAR(CUR_CHAR);
- NEXT();
- }
- if(!scisdigit(CUR_CHAR)) Error(_SC("exponent expected"));
- }
-
- APPEND_CHAR(CUR_CHAR);
- NEXT();
- }
- }
- TERMINATE_BUFFER();
- switch(type) {
- case TSCIENTIFIC:
- case TFLOAT:
- _fvalue = (SQFloat)scstrtod(&_longstr[0],&sTemp);
- return TK_FLOAT;
- case TINT:
- LexInteger(&_longstr[0],(SQUnsignedInteger *)&_nvalue);
- return TK_INTEGER;
- case THEX:
- LexHexadecimal(&_longstr[0],(SQUnsignedInteger *)&_nvalue);
- return TK_INTEGER;
- }
- return 0;
-}
-
-SQInteger SQLexer::ReadID()
-{
- SQInteger res;
- INIT_TEMP_STRING();
- do {
- APPEND_CHAR(CUR_CHAR);
- NEXT();
- } while(scisalnum(CUR_CHAR) || CUR_CHAR == _SC('_'));
- TERMINATE_BUFFER();
- res = GetIDType(&_longstr[0]);
- if(res == TK_IDENTIFIER || res == TK_CONSTRUCTOR) {
- _svalue = &_longstr[0];
- }
- return res;
-}
+++ /dev/null
-/* see copyright notice in squirrel.h */
-#ifndef _SQLEXER_H_
-#define _SQLEXER_H_
-
-#ifdef _UNICODE
-typedef SQChar LexChar;
-#else
-typedef unsigned char LexChar;
-#endif
-
-struct SQLexer
-{
- SQLexer();
- ~SQLexer();
- void Init(SQSharedState *ss,SQLEXREADFUNC rg,SQUserPointer up,CompilerErrorFunc efunc,void *ed);
- void Error(const SQChar *err);
- SQInteger Lex();
- const SQChar *Tok2Str(SQInteger tok);
-private:
- SQInteger GetIDType(SQChar *s);
- SQInteger ReadString(SQInteger ndelim,bool verbatim);
- SQInteger ReadNumber();
- void LexBlockComment();
- SQInteger ReadID();
- void Next();
- SQInteger _curtoken;
- SQTable *_keywords;
-public:
- SQInteger _prevtoken;
- SQInteger _currentline;
- SQInteger _lasttokenline;
- SQInteger _currentcolumn;
- const SQChar *_svalue;
- SQInteger _nvalue;
- SQFloat _fvalue;
- SQLEXREADFUNC _readf;
- SQUserPointer _up;
- LexChar _currdata;
- SQSharedState *_sharedstate;
- sqvector<SQChar> _longstr;
- CompilerErrorFunc _errfunc;
- void *_errtarget;
-};
-
-#endif
+++ /dev/null
-/*
- see copyright notice in squirrel.h
-*/
-#include "sqpcheader.h"
-void *sq_vm_malloc(SQUnsignedInteger size){ return malloc(size); }
-
-void *sq_vm_realloc(void *p, SQUnsignedInteger oldsize, SQUnsignedInteger size){ return realloc(p, size); }
-
-void sq_vm_free(void *p, SQUnsignedInteger size){ free(p); }
+++ /dev/null
-/*
- see copyright notice in squirrel.h
-*/
-#include "sqpcheader.h"
-#include "sqvm.h"
-#include "sqstring.h"
-#include "sqarray.h"
-#include "sqtable.h"
-#include "squserdata.h"
-#include "sqfuncproto.h"
-#include "sqclass.h"
-#include "sqclosure.h"
-
-SQString *SQString::Create(SQSharedState *ss,const SQChar *s,SQInteger len)
-{
- SQString *str=ADD_STRING(ss,s,len);
- str->_sharedstate=ss;
- return str;
-}
-
-void SQString::Release()
-{
- REMOVE_STRING(_sharedstate,this);
-}
-
-SQInteger SQString::Next(const SQObjectPtr &refpos, SQObjectPtr &outkey, SQObjectPtr &outval)
-{
- SQInteger idx = (SQInteger)TranslateIndex(refpos);
- while(idx < _len){
- outkey = (SQInteger)idx;
- outval = SQInteger(_val[idx]);
- //return idx for the next iteration
- return ++idx;
- }
- //nothing to iterate anymore
- return -1;
-}
-
-SQUnsignedInteger TranslateIndex(const SQObjectPtr &idx)
-{
- switch(type(idx)){
- case OT_NULL:
- return 0;
- case OT_INTEGER:
- return (SQUnsignedInteger)_integer(idx);
- default: assert(0); break;
- }
- return 0;
-}
-
-SQWeakRef *SQRefCounted::GetWeakRef(SQObjectType type)
-{
- if(!_weakref) {
- sq_new(_weakref,SQWeakRef);
- _weakref->_obj._type = type;
- _weakref->_obj._unVal.pRefCounted = this;
- }
- return _weakref;
-}
-
-SQRefCounted::~SQRefCounted()
-{
- if(_weakref) {
- _weakref->_obj._type = OT_NULL;
- _weakref->_obj._unVal.pRefCounted = NULL;
- }
-}
-
-void SQWeakRef::Release() {
- if(ISREFCOUNTED(_obj._type)) {
- _obj._unVal.pRefCounted->_weakref = NULL;
- }
- sq_delete(this,SQWeakRef);
-}
-
-bool SQDelegable::GetMetaMethod(SQVM *v,SQMetaMethod mm,SQObjectPtr &res) {
- if(_delegate) {
- return _delegate->Get((*_ss(v)->_metamethods)[mm],res);
- }
- return false;
-}
-
-bool SQDelegable::SetDelegate(SQTable *mt)
-{
- SQTable *temp = mt;
- while (temp) {
- if (temp->_delegate == this) return false; //cycle detected
- temp = temp->_delegate;
- }
- if (mt) __ObjAddRef(mt);
- __ObjRelease(_delegate);
- _delegate = mt;
- return true;
-}
-
-bool SQGenerator::Yield(SQVM *v)
-{
- if(_state==eSuspended) { v->Raise_Error(_SC("internal vm error, yielding dead generator")); return false;}
- if(_state==eDead) { v->Raise_Error(_SC("internal vm error, yielding a dead generator")); return false; }
- SQInteger size = v->_top-v->_stackbase;
- _ci=*v->ci;
- _stack.resize(size);
- for(SQInteger n =0; n<size; n++) {
- _stack._vals[n] = v->_stack[v->_stackbase+n];
- v->_stack[v->_stackbase+n] = _null_;
- }
- SQInteger nvargs = v->ci->_vargs.size;
- SQInteger vargsbase = v->ci->_vargs.base;
- for(SQInteger j = nvargs - 1; j >= 0; j--) {
- _vargsstack.push_back(v->_vargsstack[vargsbase+j]);
- }
- _ci._generator=_null_;
- for(SQInteger i=0;i<_ci._etraps;i++) {
- _etraps.push_back(v->_etraps.top());
- v->_etraps.pop_back();
- }
- _state=eSuspended;
- return true;
-}
-
-bool SQGenerator::Resume(SQVM *v,SQInteger target)
-{
- SQInteger size=_stack.size();
- if(_state==eDead){ v->Raise_Error(_SC("resuming dead generator")); return false; }
- if(_state==eRunning){ v->Raise_Error(_SC("resuming active generator")); return false; }
- SQInteger prevtop=v->_top-v->_stackbase;
- PUSH_CALLINFO(v,_ci);
- SQInteger oldstackbase=v->_stackbase;
- v->_stackbase = v->_top;
- v->ci->_target = (SQInt32)target;
- v->ci->_generator = SQObjectPtr(this);
- v->ci->_vargs.size = (unsigned short)_vargsstack.size();
-
- for(SQInteger i=0;i<_ci._etraps;i++) {
- v->_etraps.push_back(_etraps.top());
- _etraps.pop_back();
- }
- for(SQInteger n =0; n<size; n++) {
- v->_stack[v->_stackbase+n] = _stack._vals[n];
- _stack._vals[0] = _null_;
- }
- while(_vargsstack.size()) {
- v->_vargsstack.push_back(_vargsstack.back());
- _vargsstack.pop_back();
- }
- v->ci->_vargs.base = (unsigned short)(v->_vargsstack.size() - v->ci->_vargs.size);
- v->_top=v->_stackbase+size;
- v->ci->_prevtop = (SQInt32)prevtop;
- v->ci->_prevstkbase = (SQInt32)(v->_stackbase - oldstackbase);
- _state=eRunning;
- return true;
-}
-
-void SQArray::Extend(const SQArray *a){
- SQInteger xlen;
- if((xlen=a->Size()))
- for(SQInteger i=0;i<xlen;i++)
- Append(a->_values[i]);
-}
-
-const SQChar* SQFunctionProto::GetLocal(SQVM *vm,SQUnsignedInteger stackbase,SQUnsignedInteger nseq,SQUnsignedInteger nop)
-{
- SQUnsignedInteger nvars=_nlocalvarinfos;
- const SQChar *res=NULL;
- if(nvars>=nseq){
- for(SQUnsignedInteger i=0;i<nvars;i++){
- if(_localvarinfos[i]._start_op<=nop && _localvarinfos[i]._end_op>=nop)
- {
- if(nseq==0){
- vm->Push(vm->_stack[stackbase+_localvarinfos[i]._pos]);
- res=_stringval(_localvarinfos[i]._name);
- break;
- }
- nseq--;
- }
- }
- }
- return res;
-}
-
-SQInteger SQFunctionProto::GetLine(SQInstruction *curr)
-{
- SQInteger op = (SQInteger)(curr-_instructions);
- SQInteger line=_lineinfos[0]._line;
- for(SQInteger i=1;i<_nlineinfos;i++){
- if(_lineinfos[i]._op>=op)
- return line;
- line=_lineinfos[i]._line;
- }
- return line;
-}
-
-#define _CHECK_IO(exp) { if(!exp)return false; }
-bool SafeWrite(HSQUIRRELVM v,SQWRITEFUNC write,SQUserPointer up,SQUserPointer dest,SQInteger size)
-{
- if(write(up,dest,size) != size) {
- v->Raise_Error(_SC("io error (write function failure)"));
- return false;
- }
- return true;
-}
-
-bool SafeRead(HSQUIRRELVM v,SQWRITEFUNC read,SQUserPointer up,SQUserPointer dest,SQInteger size)
-{
- if(size && read(up,dest,size) != size) {
- v->Raise_Error(_SC("io error, read function failure, the origin stream could be corrupted/trucated"));
- return false;
- }
- return true;
-}
-
-bool WriteTag(HSQUIRRELVM v,SQWRITEFUNC write,SQUserPointer up,SQInteger tag)
-{
- return SafeWrite(v,write,up,&tag,sizeof(tag));
-}
-
-bool CheckTag(HSQUIRRELVM v,SQWRITEFUNC read,SQUserPointer up,SQInteger tag)
-{
- SQInteger t;
- _CHECK_IO(SafeRead(v,read,up,&t,sizeof(t)));
- if(t != tag){
- v->Raise_Error(_SC("invalid or corrupted closure stream"));
- return false;
- }
- return true;
-}
-
-bool WriteObject(HSQUIRRELVM v,SQUserPointer up,SQWRITEFUNC write,SQObjectPtr &o)
-{
- _CHECK_IO(SafeWrite(v,write,up,&type(o),sizeof(SQObjectType)));
- switch(type(o)){
- case OT_STRING:
- _CHECK_IO(SafeWrite(v,write,up,&_string(o)->_len,sizeof(SQInteger)));
- _CHECK_IO(SafeWrite(v,write,up,_stringval(o),rsl(_string(o)->_len)));
- break;
- case OT_INTEGER:
- _CHECK_IO(SafeWrite(v,write,up,&_integer(o),sizeof(SQInteger)));break;
- case OT_FLOAT:
- _CHECK_IO(SafeWrite(v,write,up,&_float(o),sizeof(SQFloat)));break;
- case OT_NULL:
- break;
- default:
- v->Raise_Error(_SC("cannot serialize a %s"),GetTypeName(o));
- return false;
- }
- return true;
-}
-
-bool ReadObject(HSQUIRRELVM v,SQUserPointer up,SQREADFUNC read,SQObjectPtr &o)
-{
- SQObjectType t;
- _CHECK_IO(SafeRead(v,read,up,&t,sizeof(SQObjectType)));
- switch(t){
- case OT_STRING:{
- SQInteger len;
- _CHECK_IO(SafeRead(v,read,up,&len,sizeof(SQInteger)));
- _CHECK_IO(SafeRead(v,read,up,_ss(v)->GetScratchPad(rsl(len)),rsl(len)));
- o=SQString::Create(_ss(v),_ss(v)->GetScratchPad(-1),len);
- }
- break;
- case OT_INTEGER:{
- SQInteger i;
- _CHECK_IO(SafeRead(v,read,up,&i,sizeof(SQInteger))); o = i; break;
- }
- case OT_FLOAT:{
- SQFloat f;
- _CHECK_IO(SafeRead(v,read,up,&f,sizeof(SQFloat))); o = f; break;
- }
- case OT_NULL:
- o=_null_;
- break;
- default:
- v->Raise_Error(_SC("cannot serialize a %s"),IdType2Name(t));
- return false;
- }
- return true;
-}
-
-bool SQClosure::Save(SQVM *v,SQUserPointer up,SQWRITEFUNC write)
-{
- _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_HEAD));
- _CHECK_IO(WriteTag(v,write,up,sizeof(SQChar)));
- _CHECK_IO(_funcproto(_function)->Save(v,up,write));
- _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_TAIL));
- return true;
-}
-
-bool SQClosure::Load(SQVM *v,SQUserPointer up,SQREADFUNC read,SQObjectPtr &ret)
-{
- _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_HEAD));
- _CHECK_IO(CheckTag(v,read,up,sizeof(SQChar)));
- SQObjectPtr func;
- _CHECK_IO(SQFunctionProto::Load(v,up,read,func));
- _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_TAIL));
- ret = SQClosure::Create(_ss(v),_funcproto(func));
- return true;
-}
-
-bool SQFunctionProto::Save(SQVM *v,SQUserPointer up,SQWRITEFUNC write)
-{
- SQInteger i,nliterals = _nliterals,nparameters = _nparameters;
- SQInteger noutervalues = _noutervalues,nlocalvarinfos = _nlocalvarinfos;
- SQInteger nlineinfos=_nlineinfos,ninstructions = _ninstructions,nfunctions=_nfunctions;
- _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART));
- _CHECK_IO(WriteObject(v,up,write,_sourcename));
- _CHECK_IO(WriteObject(v,up,write,_name));
- _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART));
- _CHECK_IO(SafeWrite(v,write,up,&nliterals,sizeof(nliterals)));
- _CHECK_IO(SafeWrite(v,write,up,&nparameters,sizeof(nparameters)));
- _CHECK_IO(SafeWrite(v,write,up,&noutervalues,sizeof(noutervalues)));
- _CHECK_IO(SafeWrite(v,write,up,&nlocalvarinfos,sizeof(nlocalvarinfos)));
- _CHECK_IO(SafeWrite(v,write,up,&nlineinfos,sizeof(nlineinfos)));
- _CHECK_IO(SafeWrite(v,write,up,&ninstructions,sizeof(ninstructions)));
- _CHECK_IO(SafeWrite(v,write,up,&nfunctions,sizeof(nfunctions)));
- _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART));
- for(i=0;i<nliterals;i++){
- _CHECK_IO(WriteObject(v,up,write,_literals[i]));
- }
-
- _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART));
- for(i=0;i<nparameters;i++){
- _CHECK_IO(WriteObject(v,up,write,_parameters[i]));
- }
-
- _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART));
- for(i=0;i<noutervalues;i++){
- _CHECK_IO(SafeWrite(v,write,up,&_outervalues[i]._type,sizeof(SQUnsignedInteger)));
- _CHECK_IO(WriteObject(v,up,write,_outervalues[i]._src));
- _CHECK_IO(WriteObject(v,up,write,_outervalues[i]._name));
- }
-
- _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART));
- for(i=0;i<nlocalvarinfos;i++){
- SQLocalVarInfo &lvi=_localvarinfos[i];
- _CHECK_IO(WriteObject(v,up,write,lvi._name));
- _CHECK_IO(SafeWrite(v,write,up,&lvi._pos,sizeof(SQUnsignedInteger)));
- _CHECK_IO(SafeWrite(v,write,up,&lvi._start_op,sizeof(SQUnsignedInteger)));
- _CHECK_IO(SafeWrite(v,write,up,&lvi._end_op,sizeof(SQUnsignedInteger)));
- }
-
- _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART));
- _CHECK_IO(SafeWrite(v,write,up,_lineinfos,sizeof(SQLineInfo)*nlineinfos));
-
- _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART));
- _CHECK_IO(SafeWrite(v,write,up,_instructions,sizeof(SQInstruction)*ninstructions));
-
- _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART));
- for(i=0;i<nfunctions;i++){
- _CHECK_IO(_funcproto(_functions[i])->Save(v,up,write));
- }
- _CHECK_IO(SafeWrite(v,write,up,&_stacksize,sizeof(_stacksize)));
- _CHECK_IO(SafeWrite(v,write,up,&_bgenerator,sizeof(_bgenerator)));
- _CHECK_IO(SafeWrite(v,write,up,&_varparams,sizeof(_varparams)));
- return true;
-}
-
-bool SQFunctionProto::Load(SQVM *v,SQUserPointer up,SQREADFUNC read,SQObjectPtr &ret)
-{
- SQInteger i, nliterals,nparameters;
- SQInteger noutervalues ,nlocalvarinfos ;
- SQInteger nlineinfos,ninstructions ,nfunctions ;
- SQObjectPtr sourcename, name;
- SQObjectPtr o;
- _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART));
- _CHECK_IO(ReadObject(v, up, read, sourcename));
- _CHECK_IO(ReadObject(v, up, read, name));
-
- _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART));
- _CHECK_IO(SafeRead(v,read,up, &nliterals, sizeof(nliterals)));
- _CHECK_IO(SafeRead(v,read,up, &nparameters, sizeof(nparameters)));
- _CHECK_IO(SafeRead(v,read,up, &noutervalues, sizeof(noutervalues)));
- _CHECK_IO(SafeRead(v,read,up, &nlocalvarinfos, sizeof(nlocalvarinfos)));
- _CHECK_IO(SafeRead(v,read,up, &nlineinfos, sizeof(nlineinfos)));
- _CHECK_IO(SafeRead(v,read,up, &ninstructions, sizeof(ninstructions)));
- _CHECK_IO(SafeRead(v,read,up, &nfunctions, sizeof(nfunctions)));
-
- SQFunctionProto *f = SQFunctionProto::Create(ninstructions,nliterals,nparameters,nfunctions,noutervalues,nlineinfos,nlocalvarinfos);
- SQObjectPtr proto = f; //gets a ref in case of failure
- f->_sourcename = sourcename;
- f->_name = name;
-
- _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART));
-
- for(i = 0;i < nliterals; i++){
- _CHECK_IO(ReadObject(v, up, read, o));
- f->_literals[i] = o;
- }
- _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART));
-
- for(i = 0; i < nparameters; i++){
- _CHECK_IO(ReadObject(v, up, read, o));
- f->_parameters[i] = o;
- }
- _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART));
-
- for(i = 0; i < noutervalues; i++){
- SQUnsignedInteger type;
- SQObjectPtr name;
- _CHECK_IO(SafeRead(v,read,up, &type, sizeof(SQUnsignedInteger)));
- _CHECK_IO(ReadObject(v, up, read, o));
- _CHECK_IO(ReadObject(v, up, read, name));
- f->_outervalues[i] = SQOuterVar(name,o, (SQOuterType)type);
- }
- _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART));
-
- for(i = 0; i < nlocalvarinfos; i++){
- SQLocalVarInfo lvi;
- _CHECK_IO(ReadObject(v, up, read, lvi._name));
- _CHECK_IO(SafeRead(v,read,up, &lvi._pos, sizeof(SQUnsignedInteger)));
- _CHECK_IO(SafeRead(v,read,up, &lvi._start_op, sizeof(SQUnsignedInteger)));
- _CHECK_IO(SafeRead(v,read,up, &lvi._end_op, sizeof(SQUnsignedInteger)));
- f->_localvarinfos[i] = lvi;
- }
- _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART));
- _CHECK_IO(SafeRead(v,read,up, f->_lineinfos, sizeof(SQLineInfo)*nlineinfos));
-
- _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART));
- _CHECK_IO(SafeRead(v,read,up, f->_instructions, sizeof(SQInstruction)*ninstructions));
-
- _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART));
- for(i = 0; i < nfunctions; i++){
- _CHECK_IO(_funcproto(o)->Load(v, up, read, o));
- f->_functions[i] = o;
- }
- _CHECK_IO(SafeRead(v,read,up, &f->_stacksize, sizeof(f->_stacksize)));
- _CHECK_IO(SafeRead(v,read,up, &f->_bgenerator, sizeof(f->_bgenerator)));
- _CHECK_IO(SafeRead(v,read,up, &f->_varparams, sizeof(f->_varparams)));
- ret = f;
- return true;
-}
-
-#ifndef NO_GARBAGE_COLLECTOR
-
-#define START_MARK() if(!(_uiRef&MARK_FLAG)){ \
- _uiRef|=MARK_FLAG;
-
-#define END_MARK() RemoveFromChain(&_sharedstate->_gc_chain, this); \
- AddToChain(chain, this); }
-
-void SQVM::Mark(SQCollectable **chain)
-{
- START_MARK()
- SQSharedState::MarkObject(_lasterror,chain);
- SQSharedState::MarkObject(_errorhandler,chain);
- SQSharedState::MarkObject(_debughook,chain);
- SQSharedState::MarkObject(_roottable, chain);
- SQSharedState::MarkObject(temp_reg, chain);
- for(SQUnsignedInteger i = 0; i < _stack.size(); i++) SQSharedState::MarkObject(_stack[i], chain);
- for(SQUnsignedInteger j = 0; j < _vargsstack.size(); j++) SQSharedState::MarkObject(_vargsstack[j], chain);
- END_MARK()
-}
-
-void SQArray::Mark(SQCollectable **chain)
-{
- START_MARK()
- SQInteger len = _values.size();
- for(SQInteger i = 0;i < len; i++) SQSharedState::MarkObject(_values[i], chain);
- END_MARK()
-}
-void SQTable::Mark(SQCollectable **chain)
-{
- START_MARK()
- if(_delegate) _delegate->Mark(chain);
- SQInteger len = _numofnodes;
- for(SQInteger i = 0; i < len; i++){
- SQSharedState::MarkObject(_nodes[i].key, chain);
- SQSharedState::MarkObject(_nodes[i].val, chain);
- }
- END_MARK()
-}
-
-void SQClass::Mark(SQCollectable **chain)
-{
- START_MARK()
- _members->Mark(chain);
- if(_base) _base->Mark(chain);
- SQSharedState::MarkObject(_attributes, chain);
- for(SQUnsignedInteger i =0; i< _defaultvalues.size(); i++) {
- SQSharedState::MarkObject(_defaultvalues[i].val, chain);
- SQSharedState::MarkObject(_defaultvalues[i].attrs, chain);
- }
- for(SQUnsignedInteger j =0; j< _methods.size(); j++) {
- SQSharedState::MarkObject(_methods[j].val, chain);
- SQSharedState::MarkObject(_methods[j].attrs, chain);
- }
- for(SQUnsignedInteger k =0; k< _metamethods.size(); k++) {
- SQSharedState::MarkObject(_metamethods[k], chain);
- }
- END_MARK()
-}
-
-void SQInstance::Mark(SQCollectable **chain)
-{
- START_MARK()
- _class->Mark(chain);
- SQUnsignedInteger nvalues = _class->_defaultvalues.size();
- for(SQUnsignedInteger i =0; i< nvalues; i++) {
- SQSharedState::MarkObject(_values[i], chain);
- }
- END_MARK()
-}
-
-void SQGenerator::Mark(SQCollectable **chain)
-{
- START_MARK()
- for(SQUnsignedInteger i = 0; i < _stack.size(); i++) SQSharedState::MarkObject(_stack[i], chain);
- for(SQUnsignedInteger j = 0; j < _vargsstack.size(); j++) SQSharedState::MarkObject(_vargsstack[j], chain);
- SQSharedState::MarkObject(_closure, chain);
- END_MARK()
-}
-
-void SQClosure::Mark(SQCollectable **chain)
-{
- START_MARK()
- for(SQUnsignedInteger i = 0; i < _outervalues.size(); i++) SQSharedState::MarkObject(_outervalues[i], chain);
- END_MARK()
-}
-
-void SQNativeClosure::Mark(SQCollectable **chain)
-{
- START_MARK()
- for(SQUnsignedInteger i = 0; i < _outervalues.size(); i++) SQSharedState::MarkObject(_outervalues[i], chain);
- END_MARK()
-}
-
-void SQUserData::Mark(SQCollectable **chain){
- START_MARK()
- if(_delegate) _delegate->Mark(chain);
- END_MARK()
-}
-
-void SQCollectable::UnMark() { _uiRef&=~MARK_FLAG; }
-
-#endif
-
+++ /dev/null
-/* see copyright notice in squirrel.h */
-#ifndef _SQOBJECT_H_
-#define _SQOBJECT_H_
-
-#include "squtils.h"
-
-#define SQ_CLOSURESTREAM_HEAD (('S'<<24)|('Q'<<16)|('I'<<8)|('R'))
-#define SQ_CLOSURESTREAM_PART (('P'<<24)|('A'<<16)|('R'<<8)|('T'))
-#define SQ_CLOSURESTREAM_TAIL (('T'<<24)|('A'<<16)|('I'<<8)|('L'))
-
-struct SQSharedState;
-
-enum SQMetaMethod{
- MT_ADD=0,
- MT_SUB=1,
- MT_MUL=2,
- MT_DIV=3,
- MT_UNM=4,
- MT_MODULO=5,
- MT_SET=6,
- MT_GET=7,
- MT_TYPEOF=8,
- MT_NEXTI=9,
- MT_CMP=10,
- MT_CALL=11,
- MT_CLONED=12,
- MT_NEWSLOT=13,
- MT_DELSLOT=14,
- MT_TOSTRING=15,
- MT_NEWMEMBER=16,
- MT_INHERITED=17,
- MT_LAST = 18
-};
-
-#define MM_ADD _SC("_add")
-#define MM_SUB _SC("_sub")
-#define MM_MUL _SC("_mul")
-#define MM_DIV _SC("_div")
-#define MM_UNM _SC("_unm")
-#define MM_MODULO _SC("_modulo")
-#define MM_SET _SC("_set")
-#define MM_GET _SC("_get")
-#define MM_TYPEOF _SC("_typeof")
-#define MM_NEXTI _SC("_nexti")
-#define MM_CMP _SC("_cmp")
-#define MM_CALL _SC("_call")
-#define MM_CLONED _SC("_cloned")
-#define MM_NEWSLOT _SC("_newslot")
-#define MM_DELSLOT _SC("_delslot")
-#define MM_TOSTRING _SC("_tostring")
-#define MM_NEWMEMBER _SC("_newmember")
-#define MM_INHERITED _SC("_inherited")
-
-#define MINPOWER2 4
-
-struct SQRefCounted
-{
- SQRefCounted() { _uiRef = 0; _weakref = NULL; }
- virtual ~SQRefCounted();
- SQWeakRef *GetWeakRef(SQObjectType type);
- SQUnsignedInteger _uiRef;
- struct SQWeakRef *_weakref;
- virtual void Release()=0;
-};
-
-struct SQWeakRef : SQRefCounted
-{
- void Release();
- SQObject _obj;
-};
-
-#define _realval(o) (type((o)) != OT_WEAKREF?(SQObject)o:_weakref(o)->_obj)
-
-struct SQObjectPtr;
-
-#define __AddRef(type,unval) if(ISREFCOUNTED(type)) \
- { \
- unval.pRefCounted->_uiRef++; \
- }
-
-#define __Release(type,unval) if(ISREFCOUNTED(type) && ((--unval.pRefCounted->_uiRef)<=0)) \
- { \
- unval.pRefCounted->Release(); \
- }
-
-#define __ObjRelease(obj) { \
- if((obj)) { \
- (obj)->_uiRef--; \
- if((obj)->_uiRef == 0) \
- (obj)->Release(); \
- (obj) = NULL; \
- } \
-}
-
-#define __ObjAddRef(obj) { \
- (obj)->_uiRef++; \
-}
-
-#define type(obj) ((obj)._type)
-#define is_delegable(t) (type(t)&SQOBJECT_DELEGABLE)
-#define raw_type(obj) _RAW_TYPE((obj)._type)
-
-#define _integer(obj) ((obj)._unVal.nInteger)
-#define _float(obj) ((obj)._unVal.fFloat)
-#define _string(obj) ((obj)._unVal.pString)
-#define _table(obj) ((obj)._unVal.pTable)
-#define _array(obj) ((obj)._unVal.pArray)
-#define _closure(obj) ((obj)._unVal.pClosure)
-#define _generator(obj) ((obj)._unVal.pGenerator)
-#define _nativeclosure(obj) ((obj)._unVal.pNativeClosure)
-#define _userdata(obj) ((obj)._unVal.pUserData)
-#define _userpointer(obj) ((obj)._unVal.pUserPointer)
-#define _thread(obj) ((obj)._unVal.pThread)
-#define _funcproto(obj) ((obj)._unVal.pFunctionProto)
-#define _class(obj) ((obj)._unVal.pClass)
-#define _instance(obj) ((obj)._unVal.pInstance)
-#define _delegable(obj) ((SQDelegable *)(obj)._unVal.pDelegable)
-#define _weakref(obj) ((obj)._unVal.pWeakRef)
-#define _refcounted(obj) ((obj)._unVal.pRefCounted)
-#define _rawval(obj) ((obj)._unVal.pRefCounted)
-
-#define _stringval(obj) (obj)._unVal.pString->_val
-#define _userdataval(obj) (obj)._unVal.pUserData->_val
-
-#define tofloat(num) ((type(num)==OT_INTEGER)?(SQFloat)_integer(num):_float(num))
-#define tointeger(num) ((type(num)==OT_FLOAT)?(SQInteger)_float(num):_integer(num))
-/////////////////////////////////////////////////////////////////////////////////////
-/////////////////////////////////////////////////////////////////////////////////////
-struct SQObjectPtr : public SQObject
-{
- SQObjectPtr()
- {
- _type=OT_NULL;
- _unVal.pUserPointer=NULL;
- }
- SQObjectPtr(const SQObjectPtr &o)
- {
- _type=o._type;
- _unVal=o._unVal;
- __AddRef(_type,_unVal);
- }
- SQObjectPtr(const SQObject &o)
- {
- _type=o._type;
- _unVal=o._unVal;
- __AddRef(_type,_unVal);
- }
- SQObjectPtr(SQTable *pTable)
- {
- _type=OT_TABLE;
- _unVal.pTable=pTable;
- assert(_unVal.pTable);
- __AddRef(_type,_unVal);
- }
- SQObjectPtr(SQClass *pClass)
- {
- _type=OT_CLASS;
- _unVal.pClass=pClass;
- assert(_unVal.pClass);
- __AddRef(_type,_unVal);
- }
- SQObjectPtr(SQInstance *pInstance)
- {
- _type=OT_INSTANCE;
- _unVal.pInstance=pInstance;
- assert(_unVal.pInstance);
- __AddRef(_type,_unVal);
- }
- SQObjectPtr(SQArray *pArray)
- {
- _type=OT_ARRAY;
- _unVal.pArray=pArray;
- assert(_unVal.pArray);
- __AddRef(_type,_unVal);
- }
- SQObjectPtr(SQClosure *pClosure)
- {
- _type=OT_CLOSURE;
- _unVal.pClosure=pClosure;
- assert(_unVal.pClosure);
- __AddRef(_type,_unVal);
- }
- SQObjectPtr(SQGenerator *pGenerator)
- {
- _type=OT_GENERATOR;
- _unVal.pGenerator=pGenerator;
- assert(_unVal.pGenerator);
- __AddRef(_type,_unVal);
- }
- SQObjectPtr(SQNativeClosure *pNativeClosure)
- {
- _type=OT_NATIVECLOSURE;
- _unVal.pNativeClosure=pNativeClosure;
- assert(_unVal.pNativeClosure);
- __AddRef(_type,_unVal);
- }
- SQObjectPtr(SQString *pString)
- {
- _type=OT_STRING;
- _unVal.pString=pString;
- assert(_unVal.pString);
- __AddRef(_type,_unVal);
- }
- SQObjectPtr(SQUserData *pUserData)
- {
- _type=OT_USERDATA;
- _unVal.pUserData=pUserData;
- assert(_unVal.pUserData);
- __AddRef(_type,_unVal);
- }
- SQObjectPtr(SQVM *pThread)
- {
- _type=OT_THREAD;
- _unVal.pThread=pThread;
- assert(_unVal.pThread);
- __AddRef(_type,_unVal);
- }
- SQObjectPtr(SQWeakRef *pWeakRef)
- {
- _type=OT_WEAKREF;
- _unVal.pWeakRef=pWeakRef;
- assert(_unVal.pWeakRef);
- __AddRef(_type,_unVal);
- }
- SQObjectPtr(SQFunctionProto *pFunctionProto)
- {
- _type=OT_FUNCPROTO;
- _unVal.pFunctionProto=pFunctionProto;
- assert(_unVal.pFunctionProto);
- __AddRef(_type,_unVal);
- }
- SQObjectPtr(SQInteger nInteger)
- {
- _unVal.pUserPointer=NULL;
- _type=OT_INTEGER;
- _unVal.nInteger=nInteger;
- }
- SQObjectPtr(SQFloat fFloat)
- {
- _unVal.pUserPointer=NULL;
- _type=OT_FLOAT;
- _unVal.fFloat=fFloat;
- }
- SQObjectPtr(bool bBool)
- {
- _unVal.pUserPointer=NULL;
- _type = OT_BOOL;
- _unVal.nInteger = bBool?1:0;
- }
- SQObjectPtr(SQUserPointer pUserPointer)
- {
- _type=OT_USERPOINTER;
- _unVal.pUserPointer=pUserPointer;
- }
- ~SQObjectPtr()
- {
- __Release(_type,_unVal);
- }
- inline void Null()
- {
- SQObjectType tOldType;
- SQObjectValue unOldVal;
- tOldType = _type;
- unOldVal = _unVal;
- _type = OT_NULL;
- _unVal.pUserPointer = NULL;
- __Release(tOldType,unOldVal);
- }
- inline SQObjectPtr& operator=(SQInteger i)
- {
- __Release(_type,_unVal);
- _unVal.nInteger = i;
- _type = OT_INTEGER;
- return *this;
- }
- inline SQObjectPtr& operator=(SQFloat f)
- {
- __Release(_type,_unVal);
- _unVal.fFloat = f;
- _type = OT_FLOAT;
- return *this;
- }
- inline SQObjectPtr& operator=(const SQObjectPtr& obj)
- {
- SQObjectType tOldType;
- SQObjectValue unOldVal;
- tOldType=_type;
- unOldVal=_unVal;
- _unVal = obj._unVal;
- _type = obj._type;
- __AddRef(_type,_unVal);
- __Release(tOldType,unOldVal);
- return *this;
- }
- inline SQObjectPtr& operator=(const SQObject& obj)
- {
- SQObjectType tOldType;
- SQObjectValue unOldVal;
- tOldType=_type;
- unOldVal=_unVal;
- _unVal = obj._unVal;
- _type = obj._type;
- __AddRef(_type,_unVal);
- __Release(tOldType,unOldVal);
- return *this;
- }
- private:
- SQObjectPtr(const SQChar *){} //safety
-};
-/////////////////////////////////////////////////////////////////////////////////////
-#ifndef NO_GARBAGE_COLLECTOR
-#define MARK_FLAG 0x80000000
-struct SQCollectable : public SQRefCounted {
- SQCollectable *_next;
- SQCollectable *_prev;
- SQSharedState *_sharedstate;
- virtual void Release()=0;
- virtual void Mark(SQCollectable **chain)=0;
- void UnMark();
- virtual void Finalize()=0;
- static void AddToChain(SQCollectable **chain,SQCollectable *c);
- static void RemoveFromChain(SQCollectable **chain,SQCollectable *c);
-};
-
-
-#define ADD_TO_CHAIN(chain,obj) AddToChain(chain,obj)
-#define REMOVE_FROM_CHAIN(chain,obj) {if(!(_uiRef&MARK_FLAG))RemoveFromChain(chain,obj);}
-#define CHAINABLE_OBJ SQCollectable
-#define INIT_CHAIN() {_next=NULL;_prev=NULL;_sharedstate=ss;}
-#else
-
-#define ADD_TO_CHAIN(chain,obj) ((void)0)
-#define REMOVE_FROM_CHAIN(chain,obj) ((void)0)
-#define CHAINABLE_OBJ SQRefCounted
-#define INIT_CHAIN() ((void)0)
-#endif
-
-struct SQDelegable : public CHAINABLE_OBJ {
- bool SetDelegate(SQTable *m);
- virtual bool GetMetaMethod(SQVM *v,SQMetaMethod mm,SQObjectPtr &res);
- SQTable *_delegate;
-};
-
-SQUnsignedInteger TranslateIndex(const SQObjectPtr &idx);
-typedef sqvector<SQObjectPtr> SQObjectPtrVec;
-typedef sqvector<SQInteger> SQIntVec;
-
-
-#endif //_SQOBJECT_H_
+++ /dev/null
-/* see copyright notice in squirrel.h */
-#ifndef _SQOPCODES_H_
-#define _SQOPCODES_H_
-
-#define MAX_FUNC_STACKSIZE 0xFF
-#define MAX_LITERALS ((SQInteger)0x7FFFFFFF)
-
-enum BitWiseOP {
- BW_AND = 0,
- BW_OR = 2,
- BW_XOR = 3,
- BW_SHIFTL = 4,
- BW_SHIFTR = 5,
- BW_USHIFTR = 6
-};
-
-enum CmpOP {
- CMP_G = 0,
- CMP_GE = 2,
- CMP_L = 3,
- CMP_LE = 4
-};
-enum SQOpcode
-{
- _OP_LINE= 0x00,
- _OP_LOAD= 0x01,
- _OP_LOADINT= 0x02,
- _OP_LOADFLOAT= 0x03,
- _OP_DLOAD= 0x04,
- _OP_TAILCALL= 0x05,
- _OP_CALL= 0x06,
- _OP_PREPCALL= 0x07,
- _OP_PREPCALLK= 0x08,
- _OP_GETK= 0x09,
- _OP_MOVE= 0x0A,
- _OP_NEWSLOT= 0x0B,
- _OP_DELETE= 0x0C,
- _OP_SET= 0x0D,
- _OP_GET= 0x0E,
- _OP_EQ= 0x0F,
- _OP_NE= 0x10,
- _OP_ARITH= 0x11,
- _OP_BITW= 0x12,
- _OP_RETURN= 0x13,
- _OP_LOADNULLS= 0x14,
- _OP_LOADROOTTABLE= 0x15,
- _OP_LOADBOOL= 0x16,
- _OP_DMOVE= 0x17,
- _OP_JMP= 0x18,
- _OP_JNZ= 0x19,
- _OP_JZ= 0x1A,
- _OP_LOADFREEVAR= 0x1B,
- _OP_VARGC= 0x1C,
- _OP_GETVARGV= 0x1D,
- _OP_NEWTABLE= 0x1E,
- _OP_NEWARRAY= 0x1F,
- _OP_APPENDARRAY= 0x20,
- _OP_GETPARENT= 0x21,
- _OP_COMPARITH= 0x22,
- _OP_COMPARITHL= 0x23,
- _OP_INC= 0x24,
- _OP_INCL= 0x25,
- _OP_PINC= 0x26,
- _OP_PINCL= 0x27,
- _OP_CMP= 0x28,
- _OP_EXISTS= 0x29,
- _OP_INSTANCEOF= 0x2A,
- _OP_AND= 0x2B,
- _OP_OR= 0x2C,
- _OP_NEG= 0x2D,
- _OP_NOT= 0x2E,
- _OP_BWNOT= 0x2F,
- _OP_CLOSURE= 0x30,
- _OP_YIELD= 0x31,
- _OP_RESUME= 0x32,
- _OP_FOREACH= 0x33,
- _OP_POSTFOREACH= 0x34,
- _OP_DELEGATE= 0x35,
- _OP_CLONE= 0x36,
- _OP_TYPEOF= 0x37,
- _OP_PUSHTRAP= 0x38,
- _OP_POPTRAP= 0x39,
- _OP_THROW= 0x3A,
- _OP_CLASS= 0x3B,
- _OP_NEWSLOTA= 0x3C,
-};
-
-struct SQInstructionDesc {
- const SQChar *name;
-};
-
-struct SQInstruction
-{
- SQInstruction(){};
- SQInstruction(SQOpcode _op,SQInteger a0=0,SQInteger a1=0,SQInteger a2=0,SQInteger a3=0)
- { op = _op;
- _arg0 = (unsigned char)a0;_arg1 = (SQInt32)a1;
- _arg2 = (unsigned char)a2;_arg3 = (unsigned char)a3;
- }
-
-
- SQInt32 _arg1;
- unsigned char op;
- unsigned char _arg0;
- unsigned char _arg2;
- unsigned char _arg3;
-};
-
-#include "squtils.h"
-typedef sqvector<SQInstruction> SQInstructionVec;
-
-#define NEW_SLOT_ATTRIBUTES_FLAG 0x01
-#define NEW_SLOT_STATIC_FLAG 0x02
-
-#endif // _SQOPCODES_H_
+++ /dev/null
-/* see copyright notice in squirrel.h */
-#ifndef _SQPCHEADER_H_
-#define _SQPCHEADER_H_
-
-#if defined(_MSC_VER) && defined(_DEBUG)
-#include <crtdbg.h>
-#endif
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <assert.h>
-#include <new>
-//squirrel stuff
-#include <squirrel.h>
-#include "sqobject.h"
-#include "sqstate.h"
-
-#endif //_SQPCHEADER_H_
+++ /dev/null
-/*
- see copyright notice in squirrel.h
-*/
-#include "sqpcheader.h"
-#include "sqopcodes.h"
-#include "sqvm.h"
-#include "sqfuncproto.h"
-#include "sqclosure.h"
-#include "sqstring.h"
-#include "sqtable.h"
-#include "sqarray.h"
-#include "squserdata.h"
-#include "sqclass.h"
-
-SQObjectPtr _null_;
-SQObjectPtr _true_(true);
-SQObjectPtr _false_(false);
-SQObjectPtr _one_((SQInteger)1);
-SQObjectPtr _minusone_((SQInteger)-1);
-
-SQSharedState::SQSharedState()
-{
- _compilererrorhandler = NULL;
- _printfunc = NULL;
- _debuginfo = false;
- _notifyallexceptions = false;
-}
-
-#define newsysstring(s) { \
- _systemstrings->push_back(SQString::Create(this,s)); \
- }
-
-#define newmetamethod(s) { \
- _metamethods->push_back(SQString::Create(this,s)); \
- _table(_metamethodsmap)->NewSlot(_metamethods->back(),(SQInteger)(_metamethods->size()-1)); \
- }
-
-bool CompileTypemask(SQIntVec &res,const SQChar *typemask)
-{
- SQInteger i = 0;
-
- SQInteger mask = 0;
- while(typemask[i] != 0) {
-
- switch(typemask[i]){
- case 'o': mask |= _RT_NULL; break;
- case 'i': mask |= _RT_INTEGER; break;
- case 'f': mask |= _RT_FLOAT; break;
- case 'n': mask |= (_RT_FLOAT | _RT_INTEGER); break;
- case 's': mask |= _RT_STRING; break;
- case 't': mask |= _RT_TABLE; break;
- case 'a': mask |= _RT_ARRAY; break;
- case 'u': mask |= _RT_USERDATA; break;
- case 'c': mask |= (_RT_CLOSURE | _RT_NATIVECLOSURE); break;
- case 'b': mask |= _RT_BOOL; break;
- case 'g': mask |= _RT_GENERATOR; break;
- case 'p': mask |= _RT_USERPOINTER; break;
- case 'v': mask |= _RT_THREAD; break;
- case 'x': mask |= _RT_INSTANCE; break;
- case 'y': mask |= _RT_CLASS; break;
- case 'r': mask |= _RT_WEAKREF; break;
- case '.': mask = -1; res.push_back(mask); i++; mask = 0; continue;
- case ' ': i++; continue; //ignores spaces
- default:
- return false;
- }
- i++;
- if(typemask[i] == '|') {
- i++;
- if(typemask[i] == 0)
- return false;
- continue;
- }
- res.push_back(mask);
- mask = 0;
-
- }
- return true;
-}
-
-SQTable *CreateDefaultDelegate(SQSharedState *ss,SQRegFunction *funcz)
-{
- SQInteger i=0;
- SQTable *t=SQTable::Create(ss,0);
- while(funcz[i].name!=0){
- SQNativeClosure *nc = SQNativeClosure::Create(ss,funcz[i].f);
- nc->_nparamscheck = funcz[i].nparamscheck;
- nc->_name = SQString::Create(ss,funcz[i].name);
- if(funcz[i].typemask && !CompileTypemask(nc->_typecheck,funcz[i].typemask))
- return NULL;
- t->NewSlot(SQString::Create(ss,funcz[i].name),nc);
- i++;
- }
- return t;
-}
-
-void SQSharedState::Init()
-{
- _scratchpad=NULL;
- _scratchpadsize=0;
-#ifndef NO_GARBAGE_COLLECTOR
- _gc_chain=NULL;
-#endif
- sq_new(_stringtable,StringTable);
- sq_new(_metamethods,SQObjectPtrVec);
- sq_new(_systemstrings,SQObjectPtrVec);
- sq_new(_types,SQObjectPtrVec);
- _metamethodsmap = SQTable::Create(this,MT_LAST-1);
- //adding type strings to avoid memory trashing
- //types names
- newsysstring(_SC("null"));
- newsysstring(_SC("table"));
- newsysstring(_SC("array"));
- newsysstring(_SC("closure"));
- newsysstring(_SC("string"));
- newsysstring(_SC("userdata"));
- newsysstring(_SC("integer"));
- newsysstring(_SC("float"));
- newsysstring(_SC("userpointer"));
- newsysstring(_SC("function"));
- newsysstring(_SC("generator"));
- newsysstring(_SC("thread"));
- newsysstring(_SC("class"));
- newsysstring(_SC("instance"));
- newsysstring(_SC("bool"));
- //meta methods
- newmetamethod(MM_ADD);
- newmetamethod(MM_SUB);
- newmetamethod(MM_MUL);
- newmetamethod(MM_DIV);
- newmetamethod(MM_UNM);
- newmetamethod(MM_MODULO);
- newmetamethod(MM_SET);
- newmetamethod(MM_GET);
- newmetamethod(MM_TYPEOF);
- newmetamethod(MM_NEXTI);
- newmetamethod(MM_CMP);
- newmetamethod(MM_CALL);
- newmetamethod(MM_CLONED);
- newmetamethod(MM_NEWSLOT);
- newmetamethod(MM_DELSLOT);
- newmetamethod(MM_TOSTRING);
- newmetamethod(MM_NEWMEMBER);
- newmetamethod(MM_INHERITED);
-
- _constructoridx = SQString::Create(this,_SC("constructor"));
- _registry = SQTable::Create(this,0);
- _table_default_delegate=CreateDefaultDelegate(this,_table_default_delegate_funcz);
- _array_default_delegate=CreateDefaultDelegate(this,_array_default_delegate_funcz);
- _string_default_delegate=CreateDefaultDelegate(this,_string_default_delegate_funcz);
- _number_default_delegate=CreateDefaultDelegate(this,_number_default_delegate_funcz);
- _closure_default_delegate=CreateDefaultDelegate(this,_closure_default_delegate_funcz);
- _generator_default_delegate=CreateDefaultDelegate(this,_generator_default_delegate_funcz);
- _thread_default_delegate=CreateDefaultDelegate(this,_thread_default_delegate_funcz);
- _class_default_delegate=CreateDefaultDelegate(this,_class_default_delegate_funcz);
- _instance_default_delegate=CreateDefaultDelegate(this,_instance_default_delegate_funcz);
- _weakref_default_delegate=CreateDefaultDelegate(this,_weakref_default_delegate_funcz);
-
-}
-
-SQSharedState::~SQSharedState()
-{
- _constructoridx = _null_;
- _refs_table.Finalize();
- _table(_registry)->Finalize();
- _table(_metamethodsmap)->Finalize();
- _registry = _null_;
- _metamethodsmap = _null_;
- while(!_systemstrings->empty()) {
- _systemstrings->back()=_null_;
- _systemstrings->pop_back();
- }
- _thread(_root_vm)->Finalize();
- _root_vm = _null_;
- _table_default_delegate=_null_;
- _array_default_delegate=_null_;
- _string_default_delegate=_null_;
- _number_default_delegate=_null_;
- _closure_default_delegate=_null_;
- _generator_default_delegate=_null_;
- _thread_default_delegate=_null_;
- _class_default_delegate=_null_;
- _instance_default_delegate=_null_;
- _weakref_default_delegate=_null_;
-
-#ifndef NO_GARBAGE_COLLECTOR
- SQCollectable *t=_gc_chain;
- SQCollectable *nx=NULL;
- while(t) {
- t->_uiRef++;
- t->Finalize();
- nx=t->_next;
- if(--t->_uiRef == 0)
- t->Release();
- t=nx;
- }
- assert(_gc_chain==NULL); //just to proove a theory
- while(_gc_chain){
- _gc_chain->_uiRef++;
- _gc_chain->Release();
- }
-#endif
-
- sq_delete(_types,SQObjectPtrVec);
- sq_delete(_systemstrings,SQObjectPtrVec);
- sq_delete(_metamethods,SQObjectPtrVec);
- sq_delete(_stringtable,StringTable);
- if(_scratchpad)SQ_FREE(_scratchpad,_scratchpadsize);
-}
-
-
-SQInteger SQSharedState::GetMetaMethodIdxByName(const SQObjectPtr &name)
-{
- if(type(name) != OT_STRING)
- return -1;
- SQObjectPtr ret;
- if(_table(_metamethodsmap)->Get(name,ret)) {
- return _integer(ret);
- }
- return -1;
-}
-
-#ifndef NO_GARBAGE_COLLECTOR
-
-void SQSharedState::MarkObject(SQObjectPtr &o,SQCollectable **chain)
-{
- switch(type(o)){
- case OT_TABLE:_table(o)->Mark(chain);break;
- case OT_ARRAY:_array(o)->Mark(chain);break;
- case OT_USERDATA:_userdata(o)->Mark(chain);break;
- case OT_CLOSURE:_closure(o)->Mark(chain);break;
- case OT_NATIVECLOSURE:_nativeclosure(o)->Mark(chain);break;
- case OT_GENERATOR:_generator(o)->Mark(chain);break;
- case OT_THREAD:_thread(o)->Mark(chain);break;
- case OT_CLASS:_class(o)->Mark(chain);break;
- case OT_INSTANCE:_instance(o)->Mark(chain);break;
- default: break; //shutup compiler
- }
-}
-
-
-SQInteger SQSharedState::CollectGarbage(SQVM *vm)
-{
- SQInteger n=0;
- SQCollectable *tchain=NULL;
- SQVM *vms = _thread(_root_vm);
-
- vms->Mark(&tchain);
- SQInteger x = _table(_thread(_root_vm)->_roottable)->CountUsed();
- _refs_table.Mark(&tchain);
- MarkObject(_registry,&tchain);
- MarkObject(_metamethodsmap,&tchain);
- MarkObject(_table_default_delegate,&tchain);
- MarkObject(_array_default_delegate,&tchain);
- MarkObject(_string_default_delegate,&tchain);
- MarkObject(_number_default_delegate,&tchain);
- MarkObject(_generator_default_delegate,&tchain);
- MarkObject(_thread_default_delegate,&tchain);
- MarkObject(_closure_default_delegate,&tchain);
- MarkObject(_class_default_delegate,&tchain);
- MarkObject(_instance_default_delegate,&tchain);
- MarkObject(_weakref_default_delegate,&tchain);
-
- SQCollectable *t = _gc_chain;
- SQCollectable *nx = NULL;
- while(t) {
- t->_uiRef++;
- t->Finalize();
- nx = t->_next;
- if(--t->_uiRef == 0)
- t->Release();
- t = nx;
- n++;
- }
-
- t = tchain;
- while(t) {
- t->UnMark();
- t = t->_next;
- }
- _gc_chain = tchain;
- SQInteger z = _table(_thread(_root_vm)->_roottable)->CountUsed();
- assert(z == x);
- return n;
-}
-#endif
-
-#ifndef NO_GARBAGE_COLLECTOR
-void SQCollectable::AddToChain(SQCollectable **chain,SQCollectable *c)
-{
- c->_prev = NULL;
- c->_next = *chain;
- if(*chain) (*chain)->_prev = c;
- *chain = c;
-}
-
-void SQCollectable::RemoveFromChain(SQCollectable **chain,SQCollectable *c)
-{
- if(c->_prev) c->_prev->_next = c->_next;
- else *chain = c->_next;
- if(c->_next)
- c->_next->_prev = c->_prev;
- c->_next = NULL;
- c->_prev = NULL;
-}
-#endif
-
-SQChar* SQSharedState::GetScratchPad(SQInteger size)
-{
- SQInteger newsize;
- if(size>0) {
- if(_scratchpadsize < size) {
- newsize = size + (size>>1);
- _scratchpad = (SQChar *)SQ_REALLOC(_scratchpad,_scratchpadsize,newsize);
- _scratchpadsize = newsize;
-
- }else if(_scratchpadsize >= (size<<5)) {
- newsize = _scratchpadsize >> 1;
- _scratchpad = (SQChar *)SQ_REALLOC(_scratchpad,_scratchpadsize,newsize);
- _scratchpadsize = newsize;
- }
- }
- return _scratchpad;
-}
-
-RefTable::RefTable()
-{
- AllocNodes(4);
-}
-
-void RefTable::Finalize()
-{
- RefNode *nodes = _nodes;
- for(SQUnsignedInteger n = 0; n < _numofslots; n++) {
- nodes->obj = _null_;
- nodes++;
- }
-}
-
-RefTable::~RefTable()
-{
- SQ_FREE(_buckets,(_numofslots * sizeof(RefNode *)) + (_numofslots * sizeof(RefNode)));
-}
-
-#ifndef NO_GARBAGE_COLLECTOR
-void RefTable::Mark(SQCollectable **chain)
-{
- RefNode *nodes = (RefNode *)_nodes;
- for(SQUnsignedInteger n = 0; n < _numofslots; n++) {
- if(type(nodes->obj) != OT_NULL) {
- SQSharedState::MarkObject(nodes->obj,chain);
- }
- nodes++;
- }
-}
-#endif
-
-void RefTable::AddRef(SQObject &obj)
-{
- SQHash mainpos;
- RefNode *prev;
- RefNode *ref = Get(obj,mainpos,&prev,true);
- ref->refs++;
-}
-
-SQBool RefTable::Release(SQObject &obj)
-{
- SQHash mainpos;
- RefNode *prev;
- RefNode *ref = Get(obj,mainpos,&prev,false);
- if(ref) {
- if(--ref->refs == 0) {
- SQObjectPtr o = ref->obj;
- if(prev) {
- prev->next = ref->next;
- }
- else {
- _buckets[mainpos] = ref->next;
- }
- ref->next = _freelist;
- _freelist = ref;
- _slotused--;
- ref->obj = _null_;
- //<<FIXME>>test for shrink?
- return SQTrue;
- }
- }
- else {
- assert(0);
- }
- return SQFalse;
-}
-
-void RefTable::Resize(SQUnsignedInteger size)
-{
- RefNode **oldbucks = _buckets;
- RefNode *t = _nodes;
- SQUnsignedInteger oldnumofslots = _numofslots;
- AllocNodes(size);
- //rehash
- SQUnsignedInteger nfound = 0;
- for(SQUnsignedInteger n = 0; n < oldnumofslots; n++) {
- if(type(t->obj) != OT_NULL) {
- //add back;
- assert(t->refs != 0);
- RefNode *nn = Add(::HashObj(t->obj)&(_numofslots-1),t->obj);
- nn->refs = t->refs;
- t->obj = _null_;
- nfound++;
- }
- t++;
- }
- assert(nfound == oldnumofslots);
- SQ_FREE(oldbucks,(oldnumofslots * sizeof(RefNode *)) + (oldnumofslots * sizeof(RefNode)));
-}
-
-RefTable::RefNode *RefTable::Add(SQHash mainpos,SQObject &obj)
-{
- RefNode *t = _buckets[mainpos];
- RefNode *newnode = _freelist;
- newnode->obj = obj;
- _buckets[mainpos] = newnode;
- _freelist = _freelist->next;
- newnode->next = t;
- assert(newnode->refs == 0);
- _slotused++;
- return newnode;
-}
-
-RefTable::RefNode *RefTable::Get(SQObject &obj,SQHash &mainpos,RefNode **prev,bool add)
-{
- RefNode *ref;
- mainpos = ::HashObj(obj)&(_numofslots-1);
- *prev = NULL;
- for (ref = _buckets[mainpos]; ref; ) {
- if(_rawval(ref->obj) == _rawval(obj) && type(ref->obj) == type(obj))
- break;
- *prev = ref;
- ref = ref->next;
- }
- if(ref == NULL && add) {
- if(_numofslots == _slotused) {
- assert(_freelist == 0);
- Resize(_numofslots*2);
- mainpos = ::HashObj(obj)&(_numofslots-1);
- }
- ref = Add(mainpos,obj);
- }
- return ref;
-}
-
-void RefTable::AllocNodes(SQUnsignedInteger size)
-{
- RefNode **bucks;
- RefNode *nodes;
- bucks = (RefNode **)SQ_MALLOC((size * sizeof(RefNode *)) + (size * sizeof(RefNode)));
- nodes = (RefNode *)&bucks[size];
- RefNode *temp = nodes;
- SQUnsignedInteger n;
- for(n = 0; n < size - 1; n++) {
- bucks[n] = NULL;
- temp->refs = 0;
- new (&temp->obj) SQObjectPtr;
- temp->next = temp+1;
- temp++;
- }
- bucks[n] = NULL;
- temp->refs = 0;
- new (&temp->obj) SQObjectPtr;
- temp->next = NULL;
- _freelist = nodes;
- _nodes = nodes;
- _buckets = bucks;
- _slotused = 0;
- _numofslots = size;
-}
-//////////////////////////////////////////////////////////////////////////
-//StringTable
-/*
-* The following code is based on Lua 4.0 (Copyright 1994-2002 Tecgraf, PUC-Rio.)
-* http://www.lua.org/copyright.html#4
-* http://www.lua.org/source/4.0.1/src_lstring.c.html
-*/
-
-StringTable::StringTable()
-{
- AllocNodes(4);
- _slotused = 0;
-}
-
-StringTable::~StringTable()
-{
- SQ_FREE(_strings,sizeof(SQString*)*_numofslots);
- _strings = NULL;
-}
-
-void StringTable::AllocNodes(SQInteger size)
-{
- _numofslots = size;
- _strings = (SQString**)SQ_MALLOC(sizeof(SQString*)*_numofslots);
- memset(_strings,0,sizeof(SQString*)*_numofslots);
-}
-
-SQString *StringTable::Add(const SQChar *news,SQInteger len)
-{
- if(len<0)
- len = (SQInteger)scstrlen(news);
- SQHash h = ::_hashstr(news,len)&(_numofslots-1);
- SQString *s;
- for (s = _strings[h]; s; s = s->_next){
- if(s->_len == len && (!memcmp(news,s->_val,rsl(len))))
- return s; //found
- }
-
- SQString *t=(SQString *)SQ_MALLOC(rsl(len)+sizeof(SQString));
- new (t) SQString;
- memcpy(t->_val,news,rsl(len));
- t->_val[len] = _SC('\0');
- t->_len = len;
- t->_hash = ::_hashstr(news,len);
- t->_next = _strings[h];
- _strings[h] = t;
- _slotused++;
- if (_slotused > _numofslots) /* too crowded? */
- Resize(_numofslots*2);
- return t;
-}
-
-void StringTable::Resize(SQInteger size)
-{
- SQInteger oldsize=_numofslots;
- SQString **oldtable=_strings;
- AllocNodes(size);
- for (SQInteger i=0; i<oldsize; i++){
- SQString *p = oldtable[i];
- while(p){
- SQString *next = p->_next;
- SQHash h = p->_hash&(_numofslots-1);
- p->_next = _strings[h];
- _strings[h] = p;
- p = next;
- }
- }
- SQ_FREE(oldtable,oldsize*sizeof(SQString*));
-}
-
-void StringTable::Remove(SQString *bs)
-{
- SQString *s;
- SQString *prev=NULL;
- SQHash h = bs->_hash&(_numofslots - 1);
-
- for (s = _strings[h]; s; ){
- if(s == bs){
- if(prev)
- prev->_next = s->_next;
- else
- _strings[h] = s->_next;
- _slotused--;
- SQInteger slen = s->_len;
- s->~SQString();
- SQ_FREE(s,sizeof(SQString) + rsl(slen));
- return;
- }
- prev = s;
- s = s->_next;
- }
- assert(0);//if this fail something is wrong
-}
+++ /dev/null
-/* see copyright notice in squirrel.h */
-#ifndef _SQSTATE_H_
-#define _SQSTATE_H_
-
-#include "squtils.h"
-#include "sqobject.h"
-struct SQString;
-struct SQTable;
-//max number of character for a printed number
-#define NUMBER_MAX_CHAR 50
-
-struct StringTable
-{
- StringTable();
- ~StringTable();
- SQString *Add(const SQChar *,SQInteger len);
- void Remove(SQString *);
-private:
- void Resize(SQInteger size);
- void AllocNodes(SQInteger size);
- SQString **_strings;
- SQUnsignedInteger _numofslots;
- SQUnsignedInteger _slotused;
-};
-
-struct RefTable {
- struct RefNode {
- SQObjectPtr obj;
- SQUnsignedInteger refs;
- struct RefNode *next;
- };
- RefTable();
- ~RefTable();
- void AddRef(SQObject &obj);
- SQBool Release(SQObject &obj);
-#ifndef NO_GARBAGE_COLLECTOR
- void Mark(SQCollectable **chain);
-#endif
- void Finalize();
-private:
- RefNode *Get(SQObject &obj,SQHash &mainpos,RefNode **prev,bool add);
- RefNode *Add(SQHash mainpos,SQObject &obj);
- void Resize(SQUnsignedInteger size);
- void AllocNodes(SQUnsignedInteger size);
- SQUnsignedInteger _numofslots;
- SQUnsignedInteger _slotused;
- RefNode *_nodes;
- RefNode *_freelist;
- RefNode **_buckets;
-};
-
-#define ADD_STRING(ss,str,len) ss->_stringtable->Add(str,len)
-#define REMOVE_STRING(ss,bstr) ss->_stringtable->Remove(bstr)
-
-struct SQObjectPtr;
-
-struct SQSharedState
-{
- SQSharedState();
- ~SQSharedState();
- void Init();
-public:
- SQChar* GetScratchPad(SQInteger size);
- SQInteger GetMetaMethodIdxByName(const SQObjectPtr &name);
-#ifndef NO_GARBAGE_COLLECTOR
- SQInteger CollectGarbage(SQVM *vm);
- static void MarkObject(SQObjectPtr &o,SQCollectable **chain);
-#endif
- SQObjectPtrVec *_metamethods;
- SQObjectPtr _metamethodsmap;
- SQObjectPtrVec *_systemstrings;
- SQObjectPtrVec *_types;
- StringTable *_stringtable;
- RefTable _refs_table;
- SQObjectPtr _registry;
- SQObjectPtr _constructoridx;
-#ifndef NO_GARBAGE_COLLECTOR
- SQCollectable *_gc_chain;
-#endif
- SQObjectPtr _root_vm;
- SQObjectPtr _table_default_delegate;
- static SQRegFunction _table_default_delegate_funcz[];
- SQObjectPtr _array_default_delegate;
- static SQRegFunction _array_default_delegate_funcz[];
- SQObjectPtr _string_default_delegate;
- static SQRegFunction _string_default_delegate_funcz[];
- SQObjectPtr _number_default_delegate;
- static SQRegFunction _number_default_delegate_funcz[];
- SQObjectPtr _generator_default_delegate;
- static SQRegFunction _generator_default_delegate_funcz[];
- SQObjectPtr _closure_default_delegate;
- static SQRegFunction _closure_default_delegate_funcz[];
- SQObjectPtr _thread_default_delegate;
- static SQRegFunction _thread_default_delegate_funcz[];
- SQObjectPtr _class_default_delegate;
- static SQRegFunction _class_default_delegate_funcz[];
- SQObjectPtr _instance_default_delegate;
- static SQRegFunction _instance_default_delegate_funcz[];
- SQObjectPtr _weakref_default_delegate;
- static SQRegFunction _weakref_default_delegate_funcz[];
-
- SQCOMPILERERROR _compilererrorhandler;
- SQPRINTFUNCTION _printfunc;
- bool _debuginfo;
- bool _notifyallexceptions;
-private:
- SQChar *_scratchpad;
- SQInteger _scratchpadsize;
-};
-
-#define _sp(s) (_sharedstate->GetScratchPad(s))
-#define _spval (_sharedstate->GetScratchPad(-1))
-
-#define _table_ddel _table(_sharedstate->_table_default_delegate)
-#define _array_ddel _table(_sharedstate->_array_default_delegate)
-#define _string_ddel _table(_sharedstate->_string_default_delegate)
-#define _number_ddel _table(_sharedstate->_number_default_delegate)
-#define _generator_ddel _table(_sharedstate->_generator_default_delegate)
-#define _closure_ddel _table(_sharedstate->_closure_default_delegate)
-#define _thread_ddel _table(_sharedstate->_thread_default_delegate)
-#define _class_ddel _table(_sharedstate->_class_default_delegate)
-#define _instance_ddel _table(_sharedstate->_instance_default_delegate)
-#define _weakref_ddel _table(_sharedstate->_weakref_default_delegate)
-
-#ifdef SQUNICODE //rsl REAL STRING LEN
-#define rsl(l) ((l)<<1)
-#else
-#define rsl(l) (l)
-#endif
-
-extern SQObjectPtr _null_;
-extern SQObjectPtr _true_;
-extern SQObjectPtr _false_;
-extern SQObjectPtr _one_;
-extern SQObjectPtr _minusone_;
-
-bool CompileTypemask(SQIntVec &res,const SQChar *typemask);
-
-void *sq_vm_malloc(SQUnsignedInteger size);
-void *sq_vm_realloc(void *p,SQUnsignedInteger oldsize,SQUnsignedInteger size);
-void sq_vm_free(void *p,SQUnsignedInteger size);
-#endif //_SQSTATE_H_
+++ /dev/null
-/* see copyright notice in squirrel.h */
-#ifndef _SQSTRING_H_
-#define _SQSTRING_H_
-
-inline SQHash _hashstr (const SQChar *s, size_t l)
-{
- SQHash h = (SQHash)l; /* seed */
- size_t step = (l>>5)|1; /* if string is too long, don't hash all its chars */
- for (; l>=step; l-=step)
- h = h ^ ((h<<5)+(h>>2)+(unsigned short)*(s++));
- return h;
-}
-
-struct SQString : public SQRefCounted
-{
- SQString(){}
- ~SQString(){}
-public:
- static SQString *Create(SQSharedState *ss, const SQChar *, SQInteger len = -1 );
- SQInteger Next(const SQObjectPtr &refpos, SQObjectPtr &outkey, SQObjectPtr &outval);
- void Release();
- SQSharedState *_sharedstate;
- SQString *_next; //chain for the string table
- SQInteger _len;
- SQHash _hash;
- SQChar _val[1];
-};
-
-
-
-#endif //_SQSTRING_H_
+++ /dev/null
-/*
-see copyright notice in squirrel.h
-*/
-#include "sqpcheader.h"
-#include "sqvm.h"
-#include "sqtable.h"
-#include "sqfuncproto.h"
-#include "sqclosure.h"
-
-SQTable::SQTable(SQSharedState *ss,SQInteger nInitialSize)
-{
- SQInteger pow2size=MINPOWER2;
- while(nInitialSize>pow2size)pow2size=pow2size<<1;
- AllocNodes(pow2size);
- _usednodes = 0;
- _delegate = NULL;
- INIT_CHAIN();
- ADD_TO_CHAIN(&_sharedstate->_gc_chain,this);
-}
-
-void SQTable::Remove(const SQObjectPtr &key)
-{
-
- _HashNode *n = _Get(key, HashObj(key) & (_numofnodes - 1));
- if (n) {
- n->val = n->key = _null_;
- _usednodes--;
- Rehash(false);
- }
-}
-
-void SQTable::AllocNodes(SQInteger nSize)
-{
- _HashNode *nodes=(_HashNode *)SQ_MALLOC(sizeof(_HashNode)*nSize);
- for(SQInteger i=0;i<nSize;i++){
- new (&nodes[i]) _HashNode;
- nodes[i].next=NULL;
- }
- _numofnodes=nSize;
- _nodes=nodes;
- _firstfree=&_nodes[_numofnodes-1];
-}
-
-void SQTable::Rehash(bool force)
-{
- SQInteger oldsize=_numofnodes;
- //prevent problems with the integer division
- if(oldsize<4)oldsize=4;
- _HashNode *nold=_nodes;
- SQInteger nelems=CountUsed();
- if (nelems >= oldsize-oldsize/4) /* using more than 3/4? */
- AllocNodes(oldsize*2);
- else if (nelems <= oldsize/4 && /* less than 1/4? */
- oldsize > MINPOWER2)
- AllocNodes(oldsize/2);
- else if(force)
- AllocNodes(oldsize);
- else
- return;
- _usednodes = 0;
- for (SQInteger i=0; i<oldsize; i++) {
- _HashNode *old = nold+i;
- if (type(old->key) != OT_NULL)
- NewSlot(old->key,old->val);
- }
- for(SQInteger k=0;k<oldsize;k++)
- nold[k].~_HashNode();
- SQ_FREE(nold,oldsize*sizeof(_HashNode));
-}
-
-SQTable *SQTable::Clone()
-{
- SQTable *nt=Create(_opt_ss(this),_numofnodes);
- SQInteger ridx=0;
- SQObjectPtr key,val;
- while((ridx=Next(true,ridx,key,val))!=-1){
- nt->NewSlot(key,val);
- }
- nt->SetDelegate(_delegate);
- return nt;
-}
-
-bool SQTable::Get(const SQObjectPtr &key,SQObjectPtr &val)
-{
- if(type(key) == OT_NULL)
- return false;
- _HashNode *n = _Get(key, HashObj(key) & (_numofnodes - 1));
- if (n) {
- val = _realval(n->val);
- return true;
- }
- return false;
-}
-bool SQTable::NewSlot(const SQObjectPtr &key,const SQObjectPtr &val)
-{
- assert(type(key) != OT_NULL);
- SQHash h = HashObj(key) & (_numofnodes - 1);
- _HashNode *n = _Get(key, h);
- if (n) {
- n->val = val;
- return false;
- }
- _HashNode *mp = &_nodes[h];
- n = mp;
-
-
- //key not found I'll insert it
- //main pos is not free
-
- if(type(mp->key) != OT_NULL) {
- n = _firstfree; /* get a free place */
- SQHash mph = HashObj(mp->key) & (_numofnodes - 1);
- _HashNode *othern; /* main position of colliding node */
-
- if (mp > n && (othern = &_nodes[mph]) != mp){
- /* yes; move colliding node into free position */
- while (othern->next != mp){
- assert(othern->next != NULL);
- othern = othern->next; /* find previous */
- }
- othern->next = n; /* redo the chain with `n' in place of `mp' */
- n->key = mp->key;
- n->val = mp->val;/* copy colliding node into free pos. (mp->next also goes) */
- n->next = mp->next;
- mp->key = _null_;
- mp->val = _null_;
- mp->next = NULL; /* now `mp' is free */
- }
- else{
- /* new node will go into free position */
- n->next = mp->next; /* chain new position */
- mp->next = n;
- mp = n;
- }
- }
- mp->key = key;
-
- for (;;) { /* correct `firstfree' */
- if (type(_firstfree->key) == OT_NULL && _firstfree->next == NULL) {
- mp->val = val;
- _usednodes++;
- return true; /* OK; table still has a free place */
- }
- else if (_firstfree == _nodes) break; /* cannot decrement from here */
- else (_firstfree)--;
- }
- Rehash(true);
- return NewSlot(key, val);
-}
-
-SQInteger SQTable::Next(bool getweakrefs,const SQObjectPtr &refpos, SQObjectPtr &outkey, SQObjectPtr &outval)
-{
- SQInteger idx = (SQInteger)TranslateIndex(refpos);
- while (idx < _numofnodes) {
- if(type(_nodes[idx].key) != OT_NULL) {
- //first found
- _HashNode &n = _nodes[idx];
- outkey = n.key;
- outval = getweakrefs?(SQObject)n.val:_realval(n.val);
- //return idx for the next iteration
- return ++idx;
- }
- ++idx;
- }
- //nothing to iterate anymore
- return -1;
-}
-
-
-bool SQTable::Set(const SQObjectPtr &key, const SQObjectPtr &val)
-{
- _HashNode *n = _Get(key, HashObj(key) & (_numofnodes - 1));
- if (n) {
- n->val = val;
- return true;
- }
- return false;
-}
-
-void SQTable::_ClearNodes()
-{
- for(SQInteger i = 0;i < _numofnodes; i++) { _nodes[i].key = _null_; _nodes[i].val = _null_; }
-}
-
-void SQTable::Finalize()
-{
- _ClearNodes();
- SetDelegate(NULL);
-}
-
-void SQTable::Clear()
-{
- _ClearNodes();
- _usednodes = 0;
- Rehash(true);
-}
+++ /dev/null
-/* see copyright notice in squirrel.h */
-#ifndef _SQTABLE_H_
-#define _SQTABLE_H_
-/*
-* The following code is based on Lua 4.0 (Copyright 1994-2002 Tecgraf, PUC-Rio.)
-* http://www.lua.org/copyright.html#4
-* http://www.lua.org/source/4.0.1/src_ltable.c.html
-*/
-
-#include "sqstring.h"
-
-
-#define hashptr(p) ((SQHash)(((SQInteger)p) >> 3))
-
-inline SQHash HashObj(const SQObjectPtr &key)
-{
- switch(type(key)) {
- case OT_STRING: return _string(key)->_hash;
- case OT_FLOAT: return (SQHash)((SQInteger)_float(key));
- case OT_BOOL: case OT_INTEGER: return (SQHash)((SQInteger)_integer(key));
- default: return hashptr(key._unVal.pRefCounted);
- }
-}
-
-struct SQTable : public SQDelegable
-{
-private:
- struct _HashNode
- {
- _HashNode() { next = NULL; }
- SQObjectPtr val;
- SQObjectPtr key;
- _HashNode *next;
- };
- _HashNode *_firstfree;
- _HashNode *_nodes;
- SQInteger _numofnodes;
- SQInteger _usednodes;
-
-///////////////////////////
- void AllocNodes(SQInteger nSize);
- void Rehash(bool force);
- SQTable(SQSharedState *ss, SQInteger nInitialSize);
- void _ClearNodes();
-public:
- static SQTable* Create(SQSharedState *ss,SQInteger nInitialSize)
- {
- SQTable *newtable = (SQTable*)SQ_MALLOC(sizeof(SQTable));
- new (newtable) SQTable(ss, nInitialSize);
- newtable->_delegate = NULL;
- return newtable;
- }
- void Finalize();
- SQTable *Clone();
- ~SQTable()
- {
- SetDelegate(NULL);
- REMOVE_FROM_CHAIN(&_sharedstate->_gc_chain, this);
- for (SQInteger i = 0; i < _numofnodes; i++) _nodes[i].~_HashNode();
- SQ_FREE(_nodes, _numofnodes * sizeof(_HashNode));
- }
-#ifndef NO_GARBAGE_COLLECTOR
- void Mark(SQCollectable **chain);
-#endif
- inline _HashNode *_Get(const SQObjectPtr &key,SQHash hash)
- {
- _HashNode *n = &_nodes[hash];
- do{
- if(_rawval(n->key) == _rawval(key) && type(n->key) == type(key)){
- return n;
- }
- }while((n = n->next));
- return NULL;
- }
- bool Get(const SQObjectPtr &key,SQObjectPtr &val);
- void Remove(const SQObjectPtr &key);
- bool Set(const SQObjectPtr &key, const SQObjectPtr &val);
- //returns true if a new slot has been created false if it was already present
- bool NewSlot(const SQObjectPtr &key,const SQObjectPtr &val);
- SQInteger Next(bool getweakrefs,const SQObjectPtr &refpos, SQObjectPtr &outkey, SQObjectPtr &outval);
-
- SQInteger CountUsed(){ return _usednodes;}
- void Clear();
- void Release()
- {
- sq_delete(this, SQTable);
- }
-
-};
-
-#endif //_SQTABLE_H_
+++ /dev/null
-/* see copyright notice in squirrel.h */
-#ifndef _SQUSERDATA_H_
-#define _SQUSERDATA_H_
-
-struct SQUserData : SQDelegable
-{
- SQUserData(SQSharedState *ss){ _delegate = 0; _hook = NULL; INIT_CHAIN(); ADD_TO_CHAIN(&_ss(this)->_gc_chain, this); }
- ~SQUserData()
- {
- REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain, this);
- SetDelegate(NULL);
- }
- static SQUserData* Create(SQSharedState *ss, SQInteger size)
- {
- SQUserData* ud = (SQUserData*)SQ_MALLOC(sizeof(SQUserData)+(size-1));
- new (ud) SQUserData(ss);
- ud->_size = size;
- ud->_typetag = 0;
- return ud;
- }
-#ifndef NO_GARBAGE_COLLECTOR
- void Mark(SQCollectable **chain);
- void Finalize(){SetDelegate(NULL);}
-#endif
- void Release() {
- if (_hook) _hook(_val,_size);
- SQInteger tsize = _size - 1;
- this->~SQUserData();
- SQ_FREE(this, sizeof(SQUserData) + tsize);
- }
-
- SQInteger _size;
- SQRELEASEHOOK _hook;
- SQUserPointer _typetag;
- SQChar _val[1];
-};
-
-#endif //_SQUSERDATA_H_
+++ /dev/null
-/* see copyright notice in squirrel.h */
-#ifndef _SQUTILS_H_
-#define _SQUTILS_H_
-
-#define sq_new(__ptr,__type) {__ptr=(__type *)sq_vm_malloc(sizeof(__type));new (__ptr) __type;}
-#define sq_delete(__ptr,__type) {__ptr->~__type();sq_vm_free(__ptr,sizeof(__type));}
-#define SQ_MALLOC(__size) sq_vm_malloc((__size));
-#define SQ_FREE(__ptr,__size) sq_vm_free((__ptr),(__size));
-#define SQ_REALLOC(__ptr,__oldsize,__size) sq_vm_realloc((__ptr),(__oldsize),(__size));
-
-//sqvector mini vector class, supports objects by value
-template<typename T> class sqvector
-{
-public:
- sqvector()
- {
- _vals = NULL;
- _size = 0;
- _allocated = 0;
- }
- sqvector(const sqvector<T>& v)
- {
- copy(v);
- }
- void copy(const sqvector<T>& v)
- {
- resize(v._size);
- for(SQUnsignedInteger i = 0; i < v._size; i++) {
- new ((void *)&_vals[i]) T(v._vals[i]);
- }
- _size = v._size;
- }
- ~sqvector()
- {
- if(_allocated) {
- for(SQUnsignedInteger i = 0; i < _size; i++)
- _vals[i].~T();
- SQ_FREE(_vals, (_allocated * sizeof(T)));
- }
- }
- void reserve(SQUnsignedInteger newsize) { _realloc(newsize); }
- void resize(SQUnsignedInteger newsize, const T& fill = T())
- {
- if(newsize > _allocated)
- _realloc(newsize);
- if(newsize > _size) {
- while(_size < newsize) {
- new ((void *)&_vals[_size]) T(fill);
- _size++;
- }
- }
- else{
- for(SQUnsignedInteger i = newsize; i < _size; i++) {
- _vals[i].~T();
- }
- _size = newsize;
- }
- }
- void shrinktofit() { if(_size > 4) { _realloc(_size); } }
- T& top() const { return _vals[_size - 1]; }
- inline SQUnsignedInteger size() const { return _size; }
- bool empty() const { return (_size <= 0); }
- inline T &push_back(const T& val = T())
- {
- if(_allocated <= _size)
- _realloc(_size * 2);
- return *(new ((void *)&_vals[_size++]) T(val));
- }
- inline void pop_back()
- {
- _size--; _vals[_size].~T();
- }
- void insert(SQUnsignedInteger idx, const T& val)
- {
- resize(_size + 1);
- for(SQUnsignedInteger i = _size - 1; i > idx; i--) {
- _vals[i] = _vals[i - 1];
- }
- _vals[idx] = val;
- }
- void remove(SQUnsignedInteger idx)
- {
- _vals[idx].~T();
- if(idx < (_size - 1)) {
- memcpy(&_vals[idx], &_vals[idx+1], sizeof(T) * (_size - idx - 1));
- }
- _size--;
- }
- SQUnsignedInteger capacity() { return _allocated; }
- inline T &back() const { return _vals[_size - 1]; }
- inline T& operator[](SQUnsignedInteger pos) const{ return _vals[pos]; }
- T* _vals;
-private:
- void _realloc(SQUnsignedInteger newsize)
- {
- newsize = (newsize > 0)?newsize:4;
- _vals = (T*)SQ_REALLOC(_vals, _allocated * sizeof(T), newsize * sizeof(T));
- _allocated = newsize;
- }
- SQUnsignedInteger _size;
- SQUnsignedInteger _allocated;
-};
-
-#endif //_SQUTILS_H_
+++ /dev/null
-/*
- see copyright notice in squirrel.h
-*/
-#include "sqpcheader.h"
-#include <math.h>
-#include <stdlib.h>
-#include "sqopcodes.h"
-#include "sqfuncproto.h"
-#include "sqvm.h"
-#include "sqclosure.h"
-#include "sqstring.h"
-#include "sqtable.h"
-#include "squserdata.h"
-#include "sqarray.h"
-#include "sqclass.h"
-
-#define TOP() (_stack._vals[_top-1])
-
-bool SQVM::BW_OP(SQUnsignedInteger op,SQObjectPtr &trg,const SQObjectPtr &o1,const SQObjectPtr &o2)
-{
- SQInteger res;
- SQInteger i1 = _integer(o1), i2 = _integer(o2);
- if((type(o1)==OT_INTEGER) && (type(o2)==OT_INTEGER))
- {
- switch(op) {
- case BW_AND: res = i1 & i2; break;
- case BW_OR: res = i1 | i2; break;
- case BW_XOR: res = i1 ^ i2; break;
- case BW_SHIFTL: res = i1 << i2; break;
- case BW_SHIFTR: res = i1 >> i2; break;
- case BW_USHIFTR:res = (SQInteger)(*((SQUnsignedInteger*)&i1) >> i2); break;
- default: { Raise_Error(_SC("internal vm error bitwise op failed")); return false; }
- }
- }
- else { Raise_Error(_SC("bitwise op between '%s' and '%s'"),GetTypeName(o1),GetTypeName(o2)); return false;}
- trg = res;
- return true;
-}
-
-bool SQVM::ARITH_OP(SQUnsignedInteger op,SQObjectPtr &trg,const SQObjectPtr &o1,const SQObjectPtr &o2)
-{
- if(sq_isnumeric(o1) && sq_isnumeric(o2)) {
- if((type(o1)==OT_INTEGER) && (type(o2)==OT_INTEGER)) {
- SQInteger res, i1 = _integer(o1), i2 = _integer(o2);
- switch(op) {
- case '+': res = i1 + i2; break;
- case '-': res = i1 - i2; break;
- case '/': if(i2 == 0) { Raise_Error(_SC("division by zero")); return false; }
- res = i1 / i2;
- break;
- case '*': res = i1 * i2; break;
- case '%': res = i1 % i2; break;
- default: res = 0xDEADBEEF;
- }
- trg = res;
- }else{
- SQFloat res, f1 = tofloat(o1), f2 = tofloat(o2);
- switch(op) {
- case '+': res = f1 + f2; break;
- case '-': res = f1 - f2; break;
- case '/': res = f1 / f2; break;
- case '*': res = f1 * f2; break;
- case '%': res = SQFloat(fmod((double)f1,(double)f2)); break;
- default: res = 0x0f;
- }
- trg = res;
- }
- } else {
- if(op == '+' && (type(o1) == OT_STRING || type(o2) == OT_STRING)){
- if(!StringCat(o1, o2, trg)) return false;
- }
- else if(!ArithMetaMethod(op,o1,o2,trg)) {
- Raise_Error(_SC("arith op %c on between '%s' and '%s'"),op,GetTypeName(o1),GetTypeName(o2)); return false;
- }
- }
- return true;
-}
-
-SQVM::SQVM(SQSharedState *ss)
-{
- _sharedstate=ss;
- _suspended = SQFalse;
- _suspended_target=-1;
- _suspended_root = SQFalse;
- _suspended_traps=-1;
- _foreignptr=NULL;
- _nnativecalls=0;
- _lasterror = _null_;
- _errorhandler = _null_;
- _debughook = _null_;
- ci = NULL;
- INIT_CHAIN();ADD_TO_CHAIN(&_ss(this)->_gc_chain,this);
-}
-
-void SQVM::Finalize()
-{
- _roottable = _null_;
- _lasterror = _null_;
- _errorhandler = _null_;
- _debughook = _null_;
- temp_reg = _null_;
- SQInteger size=_stack.size();
- for(SQInteger i=0;i<size;i++)
- _stack[i]=_null_;
-}
-
-SQVM::~SQVM()
-{
- Finalize();
- sq_free(_callsstack,_alloccallsstacksize*sizeof(CallInfo));
- REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain,this);
-}
-
-bool SQVM::ArithMetaMethod(SQInteger op,const SQObjectPtr &o1,const SQObjectPtr &o2,SQObjectPtr &dest)
-{
- SQMetaMethod mm;
- switch(op){
- case _SC('+'): mm=MT_ADD; break;
- case _SC('-'): mm=MT_SUB; break;
- case _SC('/'): mm=MT_DIV; break;
- case _SC('*'): mm=MT_MUL; break;
- case _SC('%'): mm=MT_MODULO; break;
- default: mm = MT_ADD; assert(0); break; //shutup compiler
- }
- if(is_delegable(o1) && _delegable(o1)->_delegate) {
- Push(o1);Push(o2);
- return CallMetaMethod(_delegable(o1),mm,2,dest);
- }
- return false;
-}
-
-bool SQVM::NEG_OP(SQObjectPtr &trg,const SQObjectPtr &o)
-{
-
- switch(type(o)) {
- case OT_INTEGER:
- trg = -_integer(o);
- return true;
- case OT_FLOAT:
- trg = -_float(o);
- return true;
- case OT_TABLE:
- case OT_USERDATA:
- case OT_INSTANCE:
- if(_delegable(o)->_delegate) {
- Push(o);
- if(CallMetaMethod(_delegable(o), MT_UNM, 1, temp_reg)) {
- trg = temp_reg;
- return true;
- }
- }
- default:break; //shutup compiler
- }
- Raise_Error(_SC("attempt to negate a %s"), GetTypeName(o));
- return false;
-}
-
-#define _RET_SUCCEED(exp) { result = (exp); return true; }
-bool SQVM::ObjCmp(const SQObjectPtr &o1,const SQObjectPtr &o2,SQInteger &result)
-{
- if(type(o1)==type(o2)){
- if(_userpointer(o1)==_userpointer(o2))_RET_SUCCEED(0);
- SQObjectPtr res;
- switch(type(o1)){
- case OT_STRING:
- _RET_SUCCEED(scstrcmp(_stringval(o1),_stringval(o2)));
- case OT_INTEGER:
- _RET_SUCCEED(_integer(o1)-_integer(o2));
- case OT_FLOAT:
- _RET_SUCCEED((_float(o1)<_float(o2))?-1:1);
- case OT_TABLE:
- case OT_USERDATA:
- case OT_INSTANCE:
- if(_delegable(o1)->_delegate) {
- Push(o1);Push(o2);
- if(CallMetaMethod(_delegable(o1),MT_CMP,2,res)) break;
- }
- //continues through (no break needed)
- default:
- _RET_SUCCEED( _userpointer(o1) < _userpointer(o2)?-1:1 );
- }
- if(type(res)!=OT_INTEGER) { Raise_CompareError(o1,o2); return false; }
- _RET_SUCCEED(_integer(res));
-
- }
- else{
- if(sq_isnumeric(o1) && sq_isnumeric(o2)){
- if((type(o1)==OT_INTEGER) && (type(o2)==OT_FLOAT)) {
- if( _integer(o1)==_float(o2) ) { _RET_SUCCEED(0); }
- else if( _integer(o1)<_float(o2) ) { _RET_SUCCEED(-1); }
- _RET_SUCCEED(1);
- }
- else{
- if( _float(o1)==_integer(o2) ) { _RET_SUCCEED(0); }
- else if( _float(o1)<_integer(o2) ) { _RET_SUCCEED(-1); }
- _RET_SUCCEED(1);
- }
- }
- else if(type(o1)==OT_NULL) {_RET_SUCCEED(-1);}
- else if(type(o2)==OT_NULL) {_RET_SUCCEED(1);}
- else { Raise_CompareError(o1,o2); return false; }
-
- }
- assert(0);
- _RET_SUCCEED(0); //cannot happen
-}
-
-bool SQVM::CMP_OP(CmpOP op, const SQObjectPtr &o1,const SQObjectPtr &o2,SQObjectPtr &res)
-{
- SQInteger r;
- if(ObjCmp(o1,o2,r)) {
- switch(op) {
- case CMP_G: res = (r > 0)?_true_:_false_; return true;
- case CMP_GE: res = (r >= 0)?_true_:_false_; return true;
- case CMP_L: res = (r < 0)?_true_:_false_; return true;
- case CMP_LE: res = (r <= 0)?_true_:_false_; return true;
-
- }
- assert(0);
- }
- return false;
-}
-
-void SQVM::ToString(const SQObjectPtr &o,SQObjectPtr &res)
-{
- switch(type(o)) {
- case OT_STRING:
- res = o;
- return;
- case OT_FLOAT:
- scsprintf(_sp(rsl(NUMBER_MAX_CHAR+1)),_SC("%g"),_float(o));
- break;
- case OT_INTEGER:
- scsprintf(_sp(rsl(NUMBER_MAX_CHAR+1)),_SC("%d"),_integer(o));
- break;
- case OT_BOOL:
- scsprintf(_sp(rsl(6)),_integer(o)?_SC("true"):_SC("false"));
- break;
- case OT_TABLE:
- case OT_USERDATA:
- case OT_INSTANCE:
- if(_delegable(o)->_delegate) {
- Push(o);
- if(CallMetaMethod(_delegable(o),MT_TOSTRING,1,res)) {
- if(type(res) == OT_STRING)
- return;
- //else keeps going to the default
- }
- }
- default:
- scsprintf(_sp(rsl(sizeof(void*)+20)),_SC("(%s : 0x%p)"),GetTypeName(o),(void*)_rawval(o));
- }
- res = SQString::Create(_ss(this),_spval);
-}
-
-
-bool SQVM::StringCat(const SQObjectPtr &str,const SQObjectPtr &obj,SQObjectPtr &dest)
-{
- SQObjectPtr a, b;
- ToString(str, a);
- ToString(obj, b);
- SQInteger l = _string(a)->_len , ol = _string(b)->_len;
- SQChar *s = _sp(rsl(l + ol + 1));
- memcpy(s, _stringval(a), rsl(l));
- memcpy(s + l, _stringval(b), rsl(ol));
- dest = SQString::Create(_ss(this), _spval, l + ol);
- return true;
-}
-
-const SQChar *IdType2Name(SQObjectType type)
-{
- switch(_RAW_TYPE(type))
- {
- case _RT_NULL:return _SC("null");
- case _RT_INTEGER:return _SC("integer");
- case _RT_FLOAT:return _SC("float");
- case _RT_BOOL:return _SC("bool");
- case _RT_STRING:return _SC("string");
- case _RT_TABLE:return _SC("table");
- case _RT_ARRAY:return _SC("array");
- case _RT_GENERATOR:return _SC("generator");
- case _RT_CLOSURE:
- case _RT_NATIVECLOSURE:
- return _SC("function");
- case _RT_USERDATA:
- case _RT_USERPOINTER:
- return _SC("userdata");
- case _RT_THREAD: return _SC("thread");
- case _RT_FUNCPROTO: return _SC("function");
- case _RT_CLASS: return _SC("class");
- case _RT_INSTANCE: return _SC("instance");
- case _RT_WEAKREF: return _SC("weakref");
- default:
- return NULL;
- }
-}
-
-const SQChar *GetTypeName(const SQObjectPtr &obj1)
-{
- return IdType2Name(type(obj1));
-}
-
-void SQVM::TypeOf(const SQObjectPtr &obj1,SQObjectPtr &dest)
-{
- if(is_delegable(obj1) && _delegable(obj1)->_delegate) {
- Push(obj1);
- if(CallMetaMethod(_delegable(obj1),MT_TYPEOF,1,dest))
- return;
- }
- dest = SQString::Create(_ss(this),GetTypeName(obj1));
-}
-
-bool SQVM::Init(SQVM *friendvm, SQInteger stacksize)
-{
- _stack.resize(stacksize);
- //_callsstack.reserve(4);
- _alloccallsstacksize = 4;
- _callsstacksize = 0;
- _callsstack = (CallInfo*)sq_malloc(_alloccallsstacksize*sizeof(CallInfo));
- _stackbase = 0;
- _top = 0;
- if(!friendvm)
- _roottable = SQTable::Create(_ss(this), 0);
- else {
- _roottable = friendvm->_roottable;
- _errorhandler = friendvm->_errorhandler;
- _debughook = friendvm->_debughook;
- }
-
- sq_base_register(this);
- return true;
-}
-
-extern SQInstructionDesc g_InstrDesc[];
-
-bool SQVM::StartCall(SQClosure *closure,SQInteger target,SQInteger nargs,SQInteger stackbase,bool tailcall)
-{
- SQFunctionProto *func = _funcproto(closure->_function);
-
- const SQInteger paramssize = func->_nparameters;
- const SQInteger newtop = stackbase + func->_stacksize;
-
-
- if (paramssize != nargs) {
- if(func->_varparams)
- {
- if (nargs < paramssize) {
- Raise_Error(_SC("wrong number of parameters"));
- return false;
- }
- for(SQInteger n = 0; n < nargs - paramssize; n++) {
- _vargsstack.push_back(_stack._vals[stackbase+paramssize+n]);
- _stack._vals[stackbase+paramssize+n] = _null_;
- }
- }
- else {
- Raise_Error(_SC("wrong number of parameters"));
- return false;
- }
- }
-
- if(type(closure->_env) == OT_WEAKREF) {
- _stack._vals[stackbase] = _weakref(closure->_env)->_obj;
- }
-
- if (!tailcall) {
- CallInfo lc;
- lc._etraps = 0;
- lc._prevstkbase = (SQInt32) ( stackbase - _stackbase );
- lc._target = (SQInt32) target;
- lc._prevtop = (SQInt32) (_top - _stackbase);
- lc._ncalls = 1;
- lc._root = SQFalse;
- PUSH_CALLINFO(this, lc);
- }
- else {
- ci->_ncalls++;
- }
- ci->_vargs.size = (SQInt32)(nargs - paramssize);
- ci->_vargs.base = (SQInt32) (_vargsstack.size()-(ci->_vargs.size));
- ci->_closure._unVal.pClosure = closure;
- ci->_closure._type = OT_CLOSURE;
- ci->_literals = func->_literals;
- ci->_ip = func->_instructions;
- //grows the stack if needed
- if (((SQUnsignedInteger)newtop + (func->_stacksize<<1)) > _stack.size()) {
- _stack.resize(_stack.size() + (func->_stacksize<<1));
- }
-
- _top = newtop;
- _stackbase = stackbase;
- return true;
-}
-
-bool SQVM::Return(SQInteger _arg0, SQInteger _arg1, SQObjectPtr &retval)
-{
- if (type(_debughook) != OT_NULL && _rawval(_debughook) != _rawval(ci->_closure))
- for(SQInteger i=0;i<ci->_ncalls;i++)
- CallDebugHook(_SC('r'));
-
- SQBool broot = ci->_root;
- SQInteger last_top = _top;
- SQInteger target = ci->_target;
- SQInteger oldstackbase = _stackbase;
- _stackbase -= ci->_prevstkbase;
- _top = _stackbase + ci->_prevtop;
- if(ci->_vargs.size) PopVarArgs(ci->_vargs);
- POP_CALLINFO(this);
- if (broot) {
- if (_arg0 != MAX_FUNC_STACKSIZE) retval = _stack._vals[oldstackbase+_arg1];
- else retval = _null_;
- }
- else {
- if(target != -1) { //-1 is when a class contructor ret value has to be ignored
- if (_arg0 != MAX_FUNC_STACKSIZE)
- STK(target) = _stack._vals[oldstackbase+_arg1];
- else
- STK(target) = _null_;
- }
- }
-
- while (last_top >= _top) _stack._vals[last_top--].Null();
- assert(oldstackbase >= _stackbase);
- return broot?true:false;
-}
-
-#define _RET_ON_FAIL(exp) { if(!exp) return false; }
-
-bool SQVM::LOCAL_INC(SQInteger op,SQObjectPtr &target, SQObjectPtr &a, SQObjectPtr &incr)
-{
- _RET_ON_FAIL(ARITH_OP( op , target, a, incr));
- a = target;
- return true;
-}
-
-bool SQVM::PLOCAL_INC(SQInteger op,SQObjectPtr &target, SQObjectPtr &a, SQObjectPtr &incr)
-{
- SQObjectPtr trg;
- _RET_ON_FAIL(ARITH_OP( op , trg, a, incr));
- target = a;
- a = trg;
- return true;
-}
-
-bool SQVM::DerefInc(SQInteger op,SQObjectPtr &target, SQObjectPtr &self, SQObjectPtr &key, SQObjectPtr &incr, bool postfix)
-{
- SQObjectPtr tmp, tself = self, tkey = key;
- if (!Get(tself, tkey, tmp, false, true)) { Raise_IdxError(tkey); return false; }
- _RET_ON_FAIL(ARITH_OP( op , target, tmp, incr))
- Set(tself, tkey, target,true);
- if (postfix) target = tmp;
- return true;
-}
-
-#define arg0 (_i_._arg0)
-#define arg1 (_i_._arg1)
-#define sarg1 (*((SQInt32 *)&_i_._arg1))
-#define arg2 (_i_._arg2)
-#define arg3 (_i_._arg3)
-#define sarg3 ((SQInteger)*((signed char *)&_i_._arg3))
-
-SQRESULT SQVM::Suspend()
-{
- if (_suspended)
- return sq_throwerror(this, _SC("cannot suspend an already suspended vm"));
- if (_nnativecalls!=2)
- return sq_throwerror(this, _SC("cannot suspend through native calls/metamethods"));
- return SQ_SUSPEND_FLAG;
-}
-
-void SQVM::PopVarArgs(VarArgs &vargs)
-{
- for(SQInteger n = 0; n< vargs.size; n++)
- _vargsstack.pop_back();
-}
-
-#define _FINISH(howmuchtojump) {jump = howmuchtojump; return true; }
-bool SQVM::FOREACH_OP(SQObjectPtr &o1,SQObjectPtr &o2,SQObjectPtr
-&o3,SQObjectPtr &o4,SQInteger arg_2,int exitpos,int &jump)
-{
- SQInteger nrefidx;
- switch(type(o1)) {
- case OT_TABLE:
- if((nrefidx = _table(o1)->Next(false,o4, o2, o3)) == -1) _FINISH(exitpos);
- o4 = (SQInteger)nrefidx; _FINISH(1);
- case OT_ARRAY:
- if((nrefidx = _array(o1)->Next(o4, o2, o3)) == -1) _FINISH(exitpos);
- o4 = (SQInteger) nrefidx; _FINISH(1);
- case OT_STRING:
- if((nrefidx = _string(o1)->Next(o4, o2, o3)) == -1)_FINISH(exitpos);
- o4 = (SQInteger)nrefidx; _FINISH(1);
- case OT_CLASS:
- if((nrefidx = _class(o1)->Next(o4, o2, o3)) == -1)_FINISH(exitpos);
- o4 = (SQInteger)nrefidx; _FINISH(1);
- case OT_USERDATA:
- case OT_INSTANCE:
- if(_delegable(o1)->_delegate) {
- SQObjectPtr itr;
- Push(o1);
- Push(o4);
- if(CallMetaMethod(_delegable(o1), MT_NEXTI, 2, itr)){
- o4 = o2 = itr;
- if(type(itr) == OT_NULL) _FINISH(exitpos);
- if(!Get(o1, itr, o3, false,false)) {
- Raise_Error(_SC("_nexti returned an invalid idx"));
- return false;
- }
- _FINISH(1);
- }
- Raise_Error(_SC("_nexti failed"));
- return false;
- }
- break;
- case OT_GENERATOR:
- if(_generator(o1)->_state == SQGenerator::eDead) _FINISH(exitpos);
- if(_generator(o1)->_state == SQGenerator::eSuspended) {
- SQInteger idx = 0;
- if(type(o4) == OT_INTEGER) {
- idx = _integer(o4) + 1;
- }
- o2 = idx;
- o4 = idx;
- _generator(o1)->Resume(this, arg_2+1);
- _FINISH(0);
- }
- default:
- Raise_Error(_SC("cannot iterate %s"), GetTypeName(o1));
- }
- return false; //cannot be hit(just to avoid warnings)
-}
-
-bool SQVM::DELEGATE_OP(SQObjectPtr &trg,SQObjectPtr &o1,SQObjectPtr &o2)
-{
- if(type(o1) != OT_TABLE) { Raise_Error(_SC("delegating a '%s'"), GetTypeName(o1)); return false; }
- switch(type(o2)) {
- case OT_TABLE:
- if(!_table(o1)->SetDelegate(_table(o2))){
- Raise_Error(_SC("delegate cycle detected"));
- return false;
- }
- break;
- case OT_NULL:
- _table(o1)->SetDelegate(NULL);
- break;
- default:
- Raise_Error(_SC("using '%s' as delegate"), GetTypeName(o2));
- return false;
- break;
- }
- trg = o1;
- return true;
-}
-#define COND_LITERAL (arg3!=0?ci->_literals[arg1]:STK(arg1))
-
-#define _GUARD(exp) { if(!exp) { Raise_Error(_lasterror); SQ_THROW();} }
-
-#define SQ_THROW() { goto exception_trap; }
-
-bool SQVM::CLOSURE_OP(SQObjectPtr &target, SQFunctionProto *func)
-{
- SQInteger nouters;
- SQClosure *closure = SQClosure::Create(_ss(this), func);
- if((nouters = func->_noutervalues)) {
- closure->_outervalues.reserve(nouters);
- for(SQInteger i = 0; i<nouters; i++) {
- SQOuterVar &v = func->_outervalues[i];
- switch(v._type){
- case otSYMBOL:
- closure->_outervalues.push_back(_null_);
- if(!Get(_stack._vals[_stackbase]/*STK(0)*/, v._src, closure->_outervalues.top(), false,true))
- {Raise_IdxError(v._src); return false; }
- break;
- case otLOCAL:
- closure->_outervalues.push_back(_stack._vals[_stackbase+_integer(v._src)]);
- break;
- case otOUTER:
- closure->_outervalues.push_back(_closure(ci->_closure)->_outervalues[_integer(v._src)]);
- break;
- }
- }
- }
- target = closure;
- return true;
-
-}
-
-bool SQVM::GETVARGV_OP(SQObjectPtr &target,SQObjectPtr &index,CallInfo *ci)
-{
- if(ci->_vargs.size == 0) {
- Raise_Error(_SC("the function doesn't have var args"));
- return false;
- }
- if(!sq_isnumeric(index)){
- Raise_Error(_SC("indexing 'vargv' with %s"),GetTypeName(index));
- return false;
- }
- SQInteger idx = tointeger(index);
- if(idx < 0 || idx >= ci->_vargs.size){ Raise_Error(_SC("vargv index out of range")); return false; }
- target = _vargsstack[ci->_vargs.base+idx];
- return true;
-}
-
-bool SQVM::CLASS_OP(SQObjectPtr &target,SQInteger baseclass,SQInteger attributes)
-{
- SQClass *base = NULL;
- SQObjectPtr attrs;
- if(baseclass != -1) {
- if(type(_stack._vals[_stackbase+baseclass]) != OT_CLASS) { Raise_Error(_SC("trying to inherit from a %s"),GetTypeName(_stack._vals[_stackbase+baseclass])); return false; }
- base = _class(_stack._vals[_stackbase + baseclass]);
- }
- if(attributes != MAX_FUNC_STACKSIZE) {
- attrs = _stack._vals[_stackbase+attributes];
- }
- target = SQClass::Create(_ss(this),base);
- if(type(_class(target)->_metamethods[MT_INHERITED]) != OT_NULL) {
- int nparams = 2;
- SQObjectPtr ret;
- Push(target); Push(attrs);
- Call(_class(target)->_metamethods[MT_INHERITED],nparams,_top - nparams, ret, false);
- Pop(nparams);
- }
- _class(target)->_attributes = attrs;
- return true;
-}
-
-
-
-bool SQVM::IsEqual(SQObjectPtr &o1,SQObjectPtr &o2,bool &res)
-{
- if(type(o1) == type(o2)) {
- res = ((_userpointer(o1) == _userpointer(o2)?true:false));
- }
- else {
- if(sq_isnumeric(o1) && sq_isnumeric(o2)) {
- SQInteger cmpres;
- if(!ObjCmp(o1, o2,cmpres)) return false;
- res = (cmpres == 0);
- }
- else {
- res = false;
- }
- }
- return true;
-}
-
-bool SQVM::IsFalse(SQObjectPtr &o)
-{
- if((type(o) & SQOBJECT_CANBEFALSE) && ( (type(o) == OT_FLOAT) && (_float(o) == SQFloat(0.0)) )
- || (_integer(o) == 0) ) { //OT_NULL|OT_INTEGER|OT_BOOL
- return true;
- }
- return false;
-}
-
-bool SQVM::GETPARENT_OP(SQObjectPtr &o,SQObjectPtr &target)
-{
- switch(type(o)) {
- case OT_TABLE: target = _table(o)->_delegate?SQObjectPtr(_table(o)->_delegate):_null_;
- break;
- case OT_CLASS: target = _class(o)->_base?_class(o)->_base:_null_;
- break;
- default:
- Raise_Error(_SC("the %s type doesn't have a parent slot"), GetTypeName(o));
- return false;
- }
- return true;
-}
-
-bool SQVM::Execute(SQObjectPtr &closure, SQInteger target, SQInteger nargs, SQInteger stackbase,SQObjectPtr &outres, SQBool raiseerror,ExecutionType et)
-{
- if ((_nnativecalls + 1) > MAX_NATIVE_CALLS) { Raise_Error(_SC("Native stack overflow")); return false; }
- _nnativecalls++;
- AutoDec ad(&_nnativecalls);
- SQInteger traps = 0;
- //temp_reg vars for OP_CALL
- SQInteger ct_target;
- SQInteger ct_stackbase;
- bool ct_tailcall;
-
- switch(et) {
- case ET_CALL:
- if(!StartCall(_closure(closure), _top - nargs, nargs, stackbase, false)) {
- //call the handler if there are no calls in the stack, if not relies on the previous node
- if(ci == NULL) CallErrorHandler(_lasterror);
- return false;
- }
- ci->_root = SQTrue;
- break;
- case ET_RESUME_GENERATOR: _generator(closure)->Resume(this, target); ci->_root = SQTrue; traps += ci->_etraps; break;
- case ET_RESUME_VM:
- traps = _suspended_traps;
- ci->_root = _suspended_root;
- ci->_vargs = _suspend_varargs;
- _suspended = SQFalse;
- break;
- }
-
-exception_restore:
- //
- {
- for(;;)
- {
- const SQInstruction &_i_ = *ci->_ip++;
- //dumpstack(_stackbase);
- //scprintf("\n[%d] %s %d %d %d %d\n",ci->_ip-ci->_iv->_vals,g_InstrDesc[_i_.op].name,arg0,arg1,arg2,arg3);
- switch(_i_.op)
- {
- case _OP_LINE:
- if(type(_debughook) != OT_NULL && _rawval(_debughook) != _rawval(ci->_closure))
- CallDebugHook(_SC('l'),arg1);
- continue;
- case _OP_LOAD: TARGET = ci->_literals[arg1]; continue;
- case _OP_LOADINT: TARGET = (SQInteger)arg1; continue;
- case _OP_LOADFLOAT: TARGET = *((SQFloat *)&arg1); continue;
- case _OP_DLOAD: TARGET = ci->_literals[arg1]; STK(arg2) = ci->_literals[arg3];continue;
- case _OP_TAILCALL:
- temp_reg = STK(arg1);
- if (type(temp_reg) == OT_CLOSURE){
- ct_tailcall = true;
- if(ci->_vargs.size) PopVarArgs(ci->_vargs);
- for (SQInteger i = 0; i < arg3; i++) STK(i) = STK(arg2 + i);
- ct_target = ci->_target;
- ct_stackbase = _stackbase;
- goto common_call;
- }
- case _OP_CALL: {
- ct_tailcall = false;
- ct_target = arg0;
- temp_reg = STK(arg1);
- ct_stackbase = _stackbase+arg2;
-
-common_call:
- SQInteger last_top = _top;
- switch (type(temp_reg)) {
- case OT_CLOSURE:{
- _GUARD(StartCall(_closure(temp_reg), ct_target, arg3, ct_stackbase, ct_tailcall));
- if (_funcproto(_closure(temp_reg)->_function)->_bgenerator) {
- SQGenerator *gen = SQGenerator::Create(_ss(this), _closure(temp_reg));
- _GUARD(gen->Yield(this));
- Return(1, ct_target, temp_reg);
-
-
-
-
- STK(ct_target) = gen;
- while (last_top >= _top) _stack._vals[last_top--].Null();
- continue;
- }
- if (type(_debughook) != OT_NULL && _rawval(_debughook) != _rawval(ci->_closure))
- CallDebugHook(_SC('c'));
- }
- continue;
- case OT_NATIVECLOSURE: {
- bool suspend;
- _GUARD(CallNative(_nativeclosure(temp_reg), arg3, ct_stackbase, temp_reg,suspend));
- if(suspend){
- _suspended = SQTrue;
- _suspended_target = ct_target;
- _suspended_root = ci->_root;
- _suspended_traps = traps;
- _suspend_varargs = ci->_vargs;
- outres = temp_reg;
- return true;
- }
- if(ct_target != -1) { //skip return value for constructors
- STK(ct_target) = temp_reg;
- }
- }
- continue;
- case OT_CLASS:{
- SQObjectPtr inst;
- _GUARD(CreateClassInstance(_class(temp_reg),inst,temp_reg));
- STK(ct_target) = inst;
- ct_target = -1; //fakes return value target so that is not overwritten by the constructor
- if(type(temp_reg) != OT_NULL) {
- _stack._vals[ct_stackbase] = inst;
- goto common_call; //hard core spaghetti code(reissues the OP_CALL to invoke the constructor)
- }
- }
- break;
- case OT_TABLE:
- case OT_USERDATA:
- case OT_INSTANCE:
- {
- Push(temp_reg);
- for (SQInteger i = 0; i < arg3; i++) Push(STK(arg2 + i));
- if (_delegable(temp_reg) && CallMetaMethod(_delegable(temp_reg), MT_CALL, arg3+1, temp_reg)){
- STK(ct_target) = temp_reg;
- break;
- }
- Raise_Error(_SC("attempt to call '%s'"), GetTypeName(temp_reg));
- SQ_THROW();
- }
- default:
- Raise_Error(_SC("attempt to call '%s'"), GetTypeName(temp_reg));
- SQ_THROW();
- }
- }
- continue;
- case _OP_PREPCALL:
- case _OP_PREPCALLK:
- {
- SQObjectPtr &key = _i_.op == _OP_PREPCALLK?(ci->_literals)[arg1]:STK(arg1);
- SQObjectPtr &o = STK(arg2);
- if (!Get(o, key, temp_reg,false,true)) {
- if(type(o) == OT_CLASS) { //hack?
- if(_class_ddel->Get(key,temp_reg)) {
- STK(arg3) = o;
- TARGET = temp_reg;
- continue;
- }
- }
- { Raise_IdxError(key); SQ_THROW();}
- }
-
- STK(arg3) = type(o) == OT_CLASS?STK(0):o;
- TARGET = temp_reg;
- }
- continue;
- case _OP_GETK:
- if (!Get(STK(arg2), ci->_literals[arg1], temp_reg, false,true)) { Raise_IdxError(ci->_literals[arg1]); SQ_THROW();}
- TARGET = temp_reg;
- continue;
- case _OP_MOVE: TARGET = STK(arg1); continue;
- case _OP_NEWSLOT:
- _GUARD(NewSlot(STK(arg1), STK(arg2), STK(arg3),false));
- if(arg0 != arg3) TARGET = STK(arg3);
- continue;
- case _OP_DELETE: _GUARD(DeleteSlot(STK(arg1), STK(arg2), TARGET)); continue;
- case _OP_SET:
- if (!Set(STK(arg1), STK(arg2), STK(arg3),true)) { Raise_IdxError(STK(arg2)); SQ_THROW(); }
- if (arg0 != arg3) TARGET = STK(arg3);
- continue;
- case _OP_GET:
- if (!Get(STK(arg1), STK(arg2), temp_reg, false,true)) { Raise_IdxError(STK(arg2)); SQ_THROW(); }
- TARGET = temp_reg;
- continue;
- case _OP_EQ:{
- bool res;
- if(!IsEqual(STK(arg2),COND_LITERAL,res)) { SQ_THROW(); }
- TARGET = res?_true_:_false_;
- }continue;
- case _OP_NE:{
- bool res;
- if(!IsEqual(STK(arg2),COND_LITERAL,res)) { SQ_THROW(); }
- TARGET = (!res)?_true_:_false_;
- } continue;
- case _OP_ARITH: _GUARD(ARITH_OP( arg3 , temp_reg, STK(arg2), STK(arg1))); TARGET = temp_reg; continue;
- case _OP_BITW: _GUARD(BW_OP( arg3,TARGET,STK(arg2),STK(arg1))); continue;
- case _OP_RETURN:
- if(type((ci)->_generator) == OT_GENERATOR) {
- _generator((ci)->_generator)->Kill();
- }
- if(Return(arg0, arg1, temp_reg)){
- assert(traps==0);
- outres = temp_reg;
- return true;
- }
- continue;
- case _OP_LOADNULLS:{ for(SQInt32 n=0; n < arg1; n++) STK(arg0+n) = _null_; }continue;
- case _OP_LOADROOTTABLE: TARGET = _roottable; continue;
- case _OP_LOADBOOL: TARGET = arg1?_true_:_false_; continue;
- case _OP_DMOVE: STK(arg0) = STK(arg1); STK(arg2) = STK(arg3); continue;
- case _OP_JMP: ci->_ip += (sarg1); continue;
- case _OP_JNZ: if(!IsFalse(STK(arg0))) ci->_ip+=(sarg1); continue;
- case _OP_JZ: if(IsFalse(STK(arg0))) ci->_ip+=(sarg1); continue;
- case _OP_LOADFREEVAR: TARGET = _closure(ci->_closure)->_outervalues[arg1]; continue;
- case _OP_VARGC: TARGET = SQInteger(ci->_vargs.size); continue;
- case _OP_GETVARGV:
- if(!GETVARGV_OP(TARGET,STK(arg1),ci)) { SQ_THROW(); }
- continue;
- case _OP_NEWTABLE: TARGET = SQTable::Create(_ss(this), arg1); continue;
- case _OP_NEWARRAY: TARGET = SQArray::Create(_ss(this), 0); _array(TARGET)->Reserve(arg1); continue;
- case _OP_APPENDARRAY: _array(STK(arg0))->Append(COND_LITERAL); continue;
- case _OP_GETPARENT: _GUARD(GETPARENT_OP(STK(arg1),TARGET)); continue;
- case _OP_COMPARITH: _GUARD(DerefInc(arg3, TARGET, STK((((SQUnsignedInteger)arg1&0xFFFF0000)>>16)), STK(arg2), STK(arg1&0x0000FFFF), false)); continue;
- case _OP_COMPARITHL: _GUARD(LOCAL_INC(arg3, TARGET, STK(arg1), STK(arg2))); continue;
- case _OP_INC: {SQObjectPtr o(sarg3); _GUARD(DerefInc('+',TARGET, STK(arg1), STK(arg2), o, false));} continue;
- case _OP_INCL: {SQObjectPtr o(sarg3); _GUARD(LOCAL_INC('+',TARGET, STK(arg1), o));} continue;
- case _OP_PINC: {SQObjectPtr o(sarg3); _GUARD(DerefInc('+',TARGET, STK(arg1), STK(arg2), o, true));} continue;
- case _OP_PINCL: {SQObjectPtr o(sarg3); _GUARD(PLOCAL_INC('+',TARGET, STK(arg1), o));} continue;
- case _OP_CMP: _GUARD(CMP_OP((CmpOP)arg3,STK(arg2),STK(arg1),TARGET)) continue;
- case _OP_EXISTS: TARGET = Get(STK(arg1), STK(arg2), temp_reg, true,false)?_true_:_false_;continue;
- case _OP_INSTANCEOF:
- if(type(STK(arg1)) != OT_CLASS || type(STK(arg2)) != OT_INSTANCE)
- {Raise_Error(_SC("cannot apply instanceof between a %s and a %s"),GetTypeName(STK(arg1)),GetTypeName(STK(arg2))); SQ_THROW();}
- TARGET = _instance(STK(arg2))->InstanceOf(_class(STK(arg1)))?_true_:_false_;
- continue;
- case _OP_AND:
- if(IsFalse(STK(arg2))) {
- TARGET = STK(arg2);
- ci->_ip += (sarg1);
- }
- continue;
- case _OP_OR:
- if(!IsFalse(STK(arg2))) {
- TARGET = STK(arg2);
- ci->_ip += (sarg1);
- }
- continue;
- case _OP_NEG: _GUARD(NEG_OP(TARGET,STK(arg1))); continue;
- case _OP_NOT: TARGET = (IsFalse(STK(arg1))?_true_:_false_); continue;
- case _OP_BWNOT:
- if(type(STK(arg1)) == OT_INTEGER) {
- SQInteger t = _integer(STK(arg1));
- TARGET = SQInteger(~t);
- continue;
- }
- Raise_Error(_SC("attempt to perform a bitwise op on a %s"), GetTypeName(STK(arg1)));
- SQ_THROW();
- case _OP_CLOSURE: {
- SQClosure *c = ci->_closure._unVal.pClosure;
- SQFunctionProto *fp = c->_function._unVal.pFunctionProto;
- if(!CLOSURE_OP(TARGET,fp->_functions[arg1]._unVal.pFunctionProto)) { SQ_THROW(); }
- continue;
- }
- case _OP_YIELD:{
- if(type(ci->_generator) == OT_GENERATOR) {
- if(sarg1 != MAX_FUNC_STACKSIZE) temp_reg = STK(arg1);
- _GUARD(_generator(ci->_generator)->Yield(this));
- traps -= ci->_etraps;
- if(sarg1 != MAX_FUNC_STACKSIZE) STK(arg1) = temp_reg;
- }
- else { Raise_Error(_SC("trying to yield a '%s',only genenerator can be yielded"), GetTypeName(ci->_generator)); SQ_THROW();}
- if(Return(arg0, arg1, temp_reg)){
- assert(traps == 0);
- outres = temp_reg;
- return true;
- }
-
- }
- continue;
- case _OP_RESUME:
- if(type(STK(arg1)) != OT_GENERATOR){ Raise_Error(_SC("trying to resume a '%s',only genenerator can be resumed"), GetTypeName(STK(arg1))); SQ_THROW();}
- _GUARD(_generator(STK(arg1))->Resume(this, arg0));
- traps += ci->_etraps;
- continue;
- case _OP_FOREACH:{ int tojump;
- _GUARD(FOREACH_OP(STK(arg0),STK(arg2),STK(arg2+1),STK(arg2+2),arg2,sarg1,tojump));
- ci->_ip += tojump; }
- continue;
- case _OP_POSTFOREACH:
- assert(type(STK(arg0)) == OT_GENERATOR);
- if(_generator(STK(arg0))->_state == SQGenerator::eDead)
- ci->_ip += (sarg1 - 1);
- continue;
- case _OP_DELEGATE: _GUARD(DELEGATE_OP(TARGET,STK(arg1),STK(arg2))); continue;
- case _OP_CLONE:
- if(!Clone(STK(arg1), TARGET))
- { Raise_Error(_SC("cloning a %s"), GetTypeName(STK(arg1))); SQ_THROW();}
- continue;
- case _OP_TYPEOF: TypeOf(STK(arg1), TARGET); continue;
- case _OP_PUSHTRAP:{
- SQInstruction *_iv = _funcproto(_closure(ci->_closure)->_function)->_instructions;
- _etraps.push_back(SQExceptionTrap(_top,_stackbase, &_iv[(ci->_ip-_iv)+arg1], arg0)); traps++;
- ci->_etraps++;
- }
- continue;
- case _OP_POPTRAP: {
- for(SQInteger i = 0; i < arg0; i++) {
- _etraps.pop_back(); traps--;
- ci->_etraps--;
- }
- }
- continue;
- case _OP_THROW: Raise_Error(TARGET); SQ_THROW(); continue;
- case _OP_CLASS: _GUARD(CLASS_OP(TARGET,arg1,arg2)); continue;
- case _OP_NEWSLOTA:
- bool bstatic = (arg0&NEW_SLOT_STATIC_FLAG)?true:false;
- if(type(STK(arg1)) == OT_CLASS) {
- if(type(_class(STK(arg1))->_metamethods[MT_NEWMEMBER]) != OT_NULL ) {
- Push(STK(arg1)); Push(STK(arg2)); Push(STK(arg3));
- Push((arg0&NEW_SLOT_ATTRIBUTES_FLAG) ? STK(arg2-1) : _null_);
- int nparams = 4;
- if(Call(_class(STK(arg1))->_metamethods[MT_NEWMEMBER], nparams, _top - nparams, temp_reg,SQFalse)) {
- Pop(nparams);
- continue;
- }
- }
- }
- _GUARD(NewSlot(STK(arg1), STK(arg2), STK(arg3),bstatic));
- if((arg0&NEW_SLOT_ATTRIBUTES_FLAG)) {
- _class(STK(arg1))->SetAttributes(STK(arg2),STK(arg2-1));
- }
- continue;
- }
-
- }
- }
-exception_trap:
- {
- SQObjectPtr currerror = _lasterror;
-// dumpstack(_stackbase);
- SQInteger n = 0;
- SQInteger last_top = _top;
- if(ci) {
- if(_ss(this)->_notifyallexceptions) CallErrorHandler(currerror);
-
- if(traps) {
- do {
- if(ci->_etraps > 0) {
- SQExceptionTrap &et = _etraps.top();
- ci->_ip = et._ip;
- _top = et._stacksize;
- _stackbase = et._stackbase;
- _stack._vals[_stackbase+et._extarget] = currerror;
- _etraps.pop_back(); traps--; ci->_etraps--;
- while(last_top >= _top) _stack._vals[last_top--].Null();
- goto exception_restore;
- }
- //if is a native closure
- if(type(ci->_closure) != OT_CLOSURE && n)
- break;
- if(type(ci->_generator) == OT_GENERATOR) _generator(ci->_generator)->Kill();
- PopVarArgs(ci->_vargs);
- POP_CALLINFO(this);
- n++;
- } while(_callsstacksize);
- }
- else {
- //call the hook
- if(raiseerror && !_ss(this)->_notifyallexceptions)
- CallErrorHandler(currerror);
- }
- //remove call stack until a C function is found or the cstack is empty
- if(ci) do {
- SQBool exitafterthisone = ci->_root;
- if(type(ci->_generator) == OT_GENERATOR) _generator(ci->_generator)->Kill();
- _stackbase -= ci->_prevstkbase;
- _top = _stackbase + ci->_prevtop;
- PopVarArgs(ci->_vargs);
- POP_CALLINFO(this);
- if( (ci && type(ci->_closure) != OT_CLOSURE) || exitafterthisone) break;
- } while(_callsstacksize);
-
- while(last_top >= _top) _stack._vals[last_top--].Null();
- }
- _lasterror = currerror;
- return false;
- }
- assert(0);
-}
-
-bool SQVM::CreateClassInstance(SQClass *theclass, SQObjectPtr &inst, SQObjectPtr &constructor)
-{
- inst = theclass->CreateInstance();
- if(!theclass->Get(_ss(this)->_constructoridx,constructor)) {
- //if(!Call(constr,nargs,stackbase,constr,false))
- // return false;
- constructor = _null_;
- }
- return true;
-}
-
-void SQVM::CallErrorHandler(SQObjectPtr &error)
-{
- if(type(_errorhandler) != OT_NULL) {
- SQObjectPtr out;
- Push(_roottable); Push(error);
- Call(_errorhandler, 2, _top-2, out,SQFalse);
- Pop(2);
- }
-}
-
-void SQVM::CallDebugHook(SQInteger type,SQInteger forcedline)
-{
- SQObjectPtr temp_reg;
- SQInteger nparams=5;
- SQFunctionProto *func=_funcproto(_closure(ci->_closure)->_function);
- Push(_roottable); Push(type); Push(func->_sourcename); Push(forcedline?forcedline:func->GetLine(ci->_ip)); Push(func->_name);
- Call(_debughook,nparams,_top-nparams,temp_reg,SQFalse);
- Pop(nparams);
-}
-
-bool SQVM::CallNative(SQNativeClosure *nclosure,SQInteger nargs,SQInteger stackbase,SQObjectPtr &retval,bool &suspend)
-{
- if (_nnativecalls + 1 > MAX_NATIVE_CALLS) { Raise_Error(_SC("Native stack overflow")); return false; }
- SQInteger nparamscheck = nclosure->_nparamscheck;
- if(((nparamscheck > 0) && (nparamscheck != nargs))
- || ((nparamscheck < 0) && (nargs < (-nparamscheck)))) {
- Raise_Error(_SC("wrong number of parameters"));
- return false;
- }
-
- SQInteger tcs;
- if((tcs = nclosure->_typecheck.size())) {
- for(SQInteger i = 0; i < nargs && i < tcs; i++)
- if((nclosure->_typecheck._vals[i] != -1) && !(type(_stack._vals[stackbase+i]) & nclosure->_typecheck[i])) {
- Raise_ParamTypeError(i,nclosure->_typecheck._vals[i],type(_stack._vals[stackbase+i]));
- return false;
- }
- }
- _nnativecalls++;
- if ((_top + MIN_STACK_OVERHEAD) > (SQInteger)_stack.size()) {
- _stack.resize(_stack.size() + (MIN_STACK_OVERHEAD<<1));
- }
- SQInteger oldtop = _top;
- SQInteger oldstackbase = _stackbase;
- _top = stackbase + nargs;
- CallInfo lci;
- lci._etraps = 0;
- lci._closure._unVal.pNativeClosure = nclosure;
- lci._closure._type = OT_NATIVECLOSURE;
- lci._prevstkbase = (SQInt32) (stackbase - _stackbase);
- lci._ncalls = 1;
- lci._prevtop = (SQInt32) (oldtop - oldstackbase);
- PUSH_CALLINFO(this, lci);
- _stackbase = stackbase;
- //push free variables
- SQInteger outers = nclosure->_outervalues.size();
- for (SQInteger i = 0; i < outers; i++) {
- Push(nclosure->_outervalues[i]);
- }
-
- if(type(nclosure->_env) == OT_WEAKREF) {
- _stack[stackbase] = _weakref(nclosure->_env)->_obj;
- }
-
-
- SQInteger ret = (nclosure->_function)(this);
- _nnativecalls--;
- suspend = false;
- if( ret == SQ_SUSPEND_FLAG) suspend = true;
- else if (ret < 0) {
- _stackbase = oldstackbase;
- _top = oldtop;
- POP_CALLINFO(this);
- Raise_Error(_lasterror);
- return false;
- }
-
- if (ret != 0){ retval = TOP(); }
- else { retval = _null_; }
- _stackbase = oldstackbase;
- _top = oldtop;
- POP_CALLINFO(this);
- return true;
-}
-
-bool SQVM::Get(const SQObjectPtr &self,const SQObjectPtr &key,SQObjectPtr &dest,bool raw, bool fetchroot)
-{
- switch(type(self)){
- case OT_TABLE:
- if(_table(self)->Get(key,dest))return true;
- break;
- case OT_ARRAY:
- if(sq_isnumeric(key)){
- return _array(self)->Get(tointeger(key),dest);
- }
- break;
- case OT_INSTANCE:
- if(_instance(self)->Get(key,dest)) return true;
- break;
- default:break; //shut up compiler
- }
- if(FallBackGet(self,key,dest,raw)) return true;
-
- if(fetchroot) {
- if(_rawval(STK(0)) == _rawval(self) &&
- type(STK(0)) == type(self)) {
- return _table(_roottable)->Get(key,dest);
- }
- }
- return false;
-}
-
-bool SQVM::FallBackGet(const SQObjectPtr &self,const SQObjectPtr &key,SQObjectPtr &dest,bool raw)
-{
- switch(type(self)){
- case OT_CLASS:
- return _class(self)->Get(key,dest);
- break;
- case OT_TABLE:
- case OT_USERDATA:
- //delegation
- if(_delegable(self)->_delegate) {
- if(Get(SQObjectPtr(_delegable(self)->_delegate),key,dest,raw,false))
- return true;
- if(raw)return false;
- Push(self);Push(key);
- if(CallMetaMethod(_delegable(self),MT_GET,2,dest))
- return true;
- }
- if(type(self) == OT_TABLE) {
- if(raw) return false;
- return _table_ddel->Get(key,dest);
- }
- return false;
- break;
- case OT_ARRAY:
- if(raw)return false;
- return _array_ddel->Get(key,dest);
- case OT_STRING:
- if(sq_isnumeric(key)){
- SQInteger n=tointeger(key);
- if(abs((int)n)<_string(self)->_len){
- if(n<0)n=_string(self)->_len-n;
- dest=SQInteger(_stringval(self)[n]);
- return true;
- }
- return false;
- }
- else {
- if(raw)return false;
- return _string_ddel->Get(key,dest);
- }
- break;
- case OT_INSTANCE:
- if(raw)return false;
- Push(self);Push(key);
- if(!CallMetaMethod(_delegable(self),MT_GET,2,dest)) {
- return _instance_ddel->Get(key,dest);
- }
- return true;
- case OT_INTEGER:case OT_FLOAT:case OT_BOOL:
- if(raw)return false;
- return _number_ddel->Get(key,dest);
- case OT_GENERATOR:
- if(raw)return false;
- return _generator_ddel->Get(key,dest);
- case OT_CLOSURE: case OT_NATIVECLOSURE:
- if(raw)return false;
- return _closure_ddel->Get(key,dest);
- case OT_THREAD:
- if(raw)return false;
- return _thread_ddel->Get(key,dest);
- case OT_WEAKREF:
- if(raw)return false;
- return _weakref_ddel->Get(key,dest);
- default:return false;
- }
- return false;
-}
-
-bool SQVM::Set(const SQObjectPtr &self,const SQObjectPtr &key,const SQObjectPtr &val,bool fetchroot)
-{
- switch(type(self)){
- case OT_TABLE:
- if(_table(self)->Set(key,val))
- return true;
- if(_table(self)->_delegate) {
- if(Set(_table(self)->_delegate,key,val,false)) {
- return true;
- }
- }
- //keeps going
- case OT_USERDATA:
- if(_delegable(self)->_delegate) {
- SQObjectPtr t;
- Push(self);Push(key);Push(val);
- if(CallMetaMethod(_delegable(self),MT_SET,3,t)) return true;
- }
- break;
- case OT_INSTANCE:{
- if(_instance(self)->Set(key,val))
- return true;
- SQObjectPtr t;
- Push(self);Push(key);Push(val);
- if(CallMetaMethod(_delegable(self),MT_SET,3,t)) return true;
- }
- break;
- case OT_ARRAY:
- if(!sq_isnumeric(key)) {Raise_Error(_SC("indexing %s with %s"),GetTypeName(self),GetTypeName(key)); return false; }
- return _array(self)->Set(tointeger(key),val);
- default:
- Raise_Error(_SC("trying to set '%s'"),GetTypeName(self));
- return false;
- }
- if(fetchroot) {
- if(_rawval(STK(0)) == _rawval(self) &&
- type(STK(0)) == type(self)) {
- return _table(_roottable)->Set(key,val);
- }
- }
- return false;
-}
-
-bool SQVM::Clone(const SQObjectPtr &self,SQObjectPtr &target)
-{
- SQObjectPtr temp_reg;
- SQObjectPtr newobj;
- switch(type(self)){
- case OT_TABLE:
- newobj = _table(self)->Clone();
- goto cloned_mt;
- case OT_INSTANCE:
- newobj = _instance(self)->Clone(_ss(this));
-cloned_mt:
- if(_delegable(newobj)->_delegate){
- Push(newobj);
- Push(self);
- CallMetaMethod(_delegable(newobj),MT_CLONED,2,temp_reg);
- }
- target = newobj;
- return true;
- case OT_ARRAY:
- target = _array(self)->Clone();
- return true;
- default: return false;
- }
-}
-
-bool SQVM::NewSlot(const SQObjectPtr &self,const SQObjectPtr &key,const SQObjectPtr &val,bool bstatic)
-{
- if(type(key) == OT_NULL) { Raise_Error(_SC("null cannot be used as index")); return false; }
- switch(type(self)) {
- case OT_TABLE: {
- bool rawcall = true;
- if(_table(self)->_delegate) {
- SQObjectPtr res;
- if(!_table(self)->Get(key,res)) {
- Push(self);Push(key);Push(val);
- rawcall = !CallMetaMethod(_table(self),MT_NEWSLOT,3,res);
- }
- }
- if(rawcall) _table(self)->NewSlot(key,val); //cannot fail
-
- break;}
- case OT_CLASS:
- if(!_class(self)->NewSlot(_ss(this),key,val,bstatic)) {
- if(_class(self)->_locked) {
- Raise_Error(_SC("trying to modify a class that has already been instantiated"));
- return false;
- }
- else {
- SQObjectPtr oval = PrintObjVal(key);
- Raise_Error(_SC("the property '%s' already exists"),_stringval(oval));
- return false;
- }
- }
- break;
- default:
- Raise_Error(_SC("indexing %s with %s"),GetTypeName(self),GetTypeName(key));
- return false;
- break;
- }
- return true;
-}
-
-bool SQVM::DeleteSlot(const SQObjectPtr &self,const SQObjectPtr &key,SQObjectPtr &res)
-{
- switch(type(self)) {
- case OT_TABLE:
- case OT_INSTANCE:
- case OT_USERDATA: {
- SQObjectPtr t;
- bool handled = false;
- if(_delegable(self)->_delegate) {
- Push(self);Push(key);
- handled = CallMetaMethod(_delegable(self),MT_DELSLOT,2,t);
- }
-
- if(!handled) {
- if(type(self) == OT_TABLE) {
- if(_table(self)->Get(key,t)) {
- _table(self)->Remove(key);
- }
- else {
- Raise_IdxError((SQObject &)key);
- return false;
- }
- }
- else {
- Raise_Error(_SC("cannot delete a slot from %s"),GetTypeName(self));
- return false;
- }
- }
- res = t;
- }
- break;
- default:
- Raise_Error(_SC("attempt to delete a slot from a %s"),GetTypeName(self));
- return false;
- }
- return true;
-}
-
-bool SQVM::Call(SQObjectPtr &closure,SQInteger nparams,SQInteger stackbase,SQObjectPtr &outres,SQBool raiseerror)
-{
-#ifdef _DEBUG
-SQInteger prevstackbase = _stackbase;
-#endif
- switch(type(closure)) {
- case OT_CLOSURE:
- return Execute(closure, _top - nparams, nparams, stackbase,outres,raiseerror);
- break;
- case OT_NATIVECLOSURE:{
- bool suspend;
- return CallNative(_nativeclosure(closure), nparams, stackbase, outres,suspend);
-
- }
- break;
- case OT_CLASS: {
- SQObjectPtr constr;
- SQObjectPtr temp;
- CreateClassInstance(_class(closure),outres,constr);
- if(type(constr) != OT_NULL) {
- _stack[stackbase] = outres;
- return Call(constr,nparams,stackbase,temp,raiseerror);
- }
- return true;
- }
- break;
- default:
- return false;
- }
-#ifdef _DEBUG
- if(!_suspended) {
- assert(_stackbase == prevstackbase);
- }
-#endif
- return true;
-}
-
-bool SQVM::CallMetaMethod(SQDelegable *del,SQMetaMethod mm,SQInteger nparams,SQObjectPtr &outres)
-{
- SQObjectPtr closure;
- if(del->GetMetaMethod(this, mm, closure)) {
- if(Call(closure, nparams, _top - nparams, outres, SQFalse)) {
- Pop(nparams);
- return true;
- }
- }
- Pop(nparams);
- return false;
-}
-
-void SQVM::Remove(SQInteger n) {
- n = (n >= 0)?n + _stackbase - 1:_top + n;
- for(SQInteger i = n; i < _top; i++){
- _stack[i] = _stack[i+1];
- }
- _stack[_top] = _null_;
- _top--;
-}
-
-void SQVM::Pop() {
- _stack[--_top] = _null_;
-}
-
-void SQVM::Pop(SQInteger n) {
- for(SQInteger i = 0; i < n; i++){
- _stack[--_top] = _null_;
- }
-}
-
-void SQVM::Push(const SQObjectPtr &o) { _stack[_top++] = o; }
-SQObjectPtr &SQVM::Top() { return _stack[_top-1]; }
-SQObjectPtr &SQVM::PopGet() { return _stack[--_top]; }
-SQObjectPtr &SQVM::GetUp(SQInteger n) { return _stack[_top+n]; }
-SQObjectPtr &SQVM::GetAt(SQInteger n) { return _stack[n]; }
-
-#ifdef _DEBUG_DUMP
-void SQVM::dumpstack(SQInteger stackbase,bool dumpall)
-{
- SQInteger size=dumpall?_stack.size():_top;
- SQInteger n=0;
- scprintf(_SC("\n>>>>stack dump<<<<\n"));
- CallInfo &ci=_callsstack[_callsstacksize-1];
- scprintf(_SC("IP: %p\n"),ci._ip);
- scprintf(_SC("prev stack base: %d\n"),ci._prevstkbase);
- scprintf(_SC("prev top: %d\n"),ci._prevtop);
- for(SQInteger i=0;i<size;i++){
- SQObjectPtr &obj=_stack[i];
- if(stackbase==i)scprintf(_SC(">"));else scprintf(_SC(" "));
- scprintf(_SC("[%d]:"),n);
- switch(type(obj)){
- case OT_FLOAT: scprintf(_SC("FLOAT %.3f"),_float(obj));break;
- case OT_INTEGER: scprintf(_SC("INTEGER %d"),_integer(obj));break;
- case OT_BOOL: scprintf(_SC("BOOL %s"),_integer(obj)?"true":"false");break;
- case OT_STRING: scprintf(_SC("STRING %s"),_stringval(obj));break;
- case OT_NULL: scprintf(_SC("NULL")); break;
- case OT_TABLE: scprintf(_SC("TABLE %p[%p]"),_table(obj),_table(obj)->_delegate);break;
- case OT_ARRAY: scprintf(_SC("ARRAY %p"),_array(obj));break;
- case OT_CLOSURE: scprintf(_SC("CLOSURE [%p]"),_closure(obj));break;
- case OT_NATIVECLOSURE: scprintf(_SC("NATIVECLOSURE"));break;
- case OT_USERDATA: scprintf(_SC("USERDATA %p[%p]"),_userdataval(obj),_userdata(obj)->_delegate);break;
- case OT_GENERATOR: scprintf(_SC("GENERATOR"));break;
- case OT_THREAD: scprintf(_SC("THREAD [%p]"),_thread(obj));break;
- case OT_USERPOINTER: scprintf(_SC("USERPOINTER %p"),_userpointer(obj));break;
- case OT_CLASS: scprintf(_SC("CLASS %p"),_class(obj));break;
- case OT_INSTANCE: scprintf(_SC("INSTANCE %p"),_instance(obj));break;
- case OT_WEAKREF: scprintf(_SC("WEAKERF %p"),_weakref(obj));break;
- default:
- assert(0);
- break;
- };
- scprintf(_SC("\n"));
- ++n;
- }
-}
-
-
-
-#endif
+++ /dev/null
-/* see copyright notice in squirrel.h */
-#ifndef _SQVM_H_
-#define _SQVM_H_
-
-#include "sqopcodes.h"
-#include "sqobject.h"
-#define MAX_NATIVE_CALLS 100
-#define MIN_STACK_OVERHEAD 10
-
-#define SQ_SUSPEND_FLAG -666
-//base lib
-void sq_base_register(HSQUIRRELVM v);
-
-struct SQExceptionTrap{
- SQExceptionTrap() {}
- SQExceptionTrap(SQInteger ss, SQInteger stackbase,SQInstruction *ip, SQInteger ex_target){ _stacksize = ss; _stackbase = stackbase; _ip = ip; _extarget = ex_target;}
- SQExceptionTrap(const SQExceptionTrap &et) { (*this) = et; }
- SQInteger _stackbase;
- SQInteger _stacksize;
- SQInstruction *_ip;
- SQInteger _extarget;
-};
-
-#define _INLINE
-
-#define STK(a) _stack._vals[_stackbase+(a)]
-#define TARGET _stack._vals[_stackbase+arg0]
-
-typedef sqvector<SQExceptionTrap> ExceptionsTraps;
-
-struct SQVM : public CHAINABLE_OBJ
-{
- struct VarArgs {
- VarArgs() { size = 0; base = 0; }
- unsigned short size;
- unsigned short base;
- };
-
- struct CallInfo{
- CallInfo() { _generator._type = OT_NULL;}
- SQInstruction *_ip;
- SQObjectPtr *_literals;
- SQObject _closure;
- SQObject _generator;
- SQInt32 _etraps;
- SQInt32 _prevstkbase;
- SQInt32 _prevtop;
- SQInt32 _target;
- SQInt32 _ncalls;
- SQBool _root;
- VarArgs _vargs;
- };
-
-typedef sqvector<CallInfo> CallInfoVec;
-public:
- enum ExecutionType { ET_CALL, ET_RESUME_GENERATOR, ET_RESUME_VM };
- SQVM(SQSharedState *ss);
- ~SQVM();
- bool Init(SQVM *friendvm, SQInteger stacksize);
- bool Execute(SQObjectPtr &func, SQInteger target, SQInteger nargs, SQInteger stackbase, SQObjectPtr &outres, SQBool raiseerror, ExecutionType et = ET_CALL);
- //starts a native call return when the NATIVE closure returns
- bool CallNative(SQNativeClosure *nclosure, SQInteger nargs, SQInteger stackbase, SQObjectPtr &retval,bool &suspend);
- //starts a SQUIRREL call in the same "Execution loop"
- bool StartCall(SQClosure *closure, SQInteger target, SQInteger nargs, SQInteger stackbase, bool tailcall);
- bool CreateClassInstance(SQClass *theclass, SQObjectPtr &inst, SQObjectPtr &constructor);
- //call a generic closure pure SQUIRREL or NATIVE
- bool Call(SQObjectPtr &closure, SQInteger nparams, SQInteger stackbase, SQObjectPtr &outres,SQBool raiseerror);
- SQRESULT Suspend();
-
- void CallDebugHook(SQInteger type,SQInteger forcedline=0);
- void CallErrorHandler(SQObjectPtr &e);
- bool Get(const SQObjectPtr &self, const SQObjectPtr &key, SQObjectPtr &dest, bool raw, bool fetchroot);
- bool FallBackGet(const SQObjectPtr &self,const SQObjectPtr &key,SQObjectPtr &dest,bool raw);
- bool Set(const SQObjectPtr &self, const SQObjectPtr &key, const SQObjectPtr &val, bool fetchroot);
- bool NewSlot(const SQObjectPtr &self, const SQObjectPtr &key, const SQObjectPtr &val,bool bstatic);
- bool DeleteSlot(const SQObjectPtr &self, const SQObjectPtr &key, SQObjectPtr &res);
- bool Clone(const SQObjectPtr &self, SQObjectPtr &target);
- bool ObjCmp(const SQObjectPtr &o1, const SQObjectPtr &o2,SQInteger &res);
- bool StringCat(const SQObjectPtr &str, const SQObjectPtr &obj, SQObjectPtr &dest);
- bool IsEqual(SQObjectPtr &o1,SQObjectPtr &o2,bool &res);
- void ToString(const SQObjectPtr &o,SQObjectPtr &res);
- SQString *PrintObjVal(const SQObject &o);
-
-
- void Raise_Error(const SQChar *s, ...);
- void Raise_Error(SQObjectPtr &desc);
- void Raise_IdxError(SQObject &o);
- void Raise_CompareError(const SQObject &o1, const SQObject &o2);
- void Raise_ParamTypeError(SQInteger nparam,SQInteger typemask,SQInteger type);
-
- void TypeOf(const SQObjectPtr &obj1, SQObjectPtr &dest);
- bool CallMetaMethod(SQDelegable *del, SQMetaMethod mm, SQInteger nparams, SQObjectPtr &outres);
- bool ArithMetaMethod(SQInteger op, const SQObjectPtr &o1, const SQObjectPtr &o2, SQObjectPtr &dest);
- bool Return(SQInteger _arg0, SQInteger _arg1, SQObjectPtr &retval);
- //new stuff
- _INLINE bool ARITH_OP(SQUnsignedInteger op,SQObjectPtr &trg,const SQObjectPtr &o1,const SQObjectPtr &o2);
- _INLINE bool BW_OP(SQUnsignedInteger op,SQObjectPtr &trg,const SQObjectPtr &o1,const SQObjectPtr &o2);
- _INLINE bool NEG_OP(SQObjectPtr &trg,const SQObjectPtr &o1);
- _INLINE bool CMP_OP(CmpOP op, const SQObjectPtr &o1,const SQObjectPtr &o2,SQObjectPtr &res);
- bool CLOSURE_OP(SQObjectPtr &target, SQFunctionProto *func);
- bool GETVARGV_OP(SQObjectPtr &target,SQObjectPtr &idx,CallInfo *ci);
- bool CLASS_OP(SQObjectPtr &target,SQInteger base,SQInteger attrs);
- bool GETPARENT_OP(SQObjectPtr &o,SQObjectPtr &target);
- //return true if the loop is finished
- bool FOREACH_OP(SQObjectPtr &o1,SQObjectPtr &o2,SQObjectPtr &o3,SQObjectPtr &o4,SQInteger arg_2,int exitpos,int &jump);
- bool DELEGATE_OP(SQObjectPtr &trg,SQObjectPtr &o1,SQObjectPtr &o2);
- _INLINE bool LOCAL_INC(SQInteger op,SQObjectPtr &target, SQObjectPtr &a, SQObjectPtr &incr);
- _INLINE bool PLOCAL_INC(SQInteger op,SQObjectPtr &target, SQObjectPtr &a, SQObjectPtr &incr);
- _INLINE bool DerefInc(SQInteger op,SQObjectPtr &target, SQObjectPtr &self, SQObjectPtr &key, SQObjectPtr &incr, bool postfix);
- void PopVarArgs(VarArgs &vargs);
-#ifdef _DEBUG_DUMP
- void dumpstack(SQInteger stackbase=-1, bool dumpall = false);
-#endif
-
-#ifndef NO_GARBAGE_COLLECTOR
- void Mark(SQCollectable **chain);
-#endif
- void Finalize();
- void GrowCallStack() {
- SQInteger newsize = _alloccallsstacksize*2;
- _callsstack = (CallInfo*)sq_realloc(_callsstack,_alloccallsstacksize*sizeof(CallInfo),newsize*sizeof(CallInfo));
- _alloccallsstacksize = newsize;
- }
- void Release(){ sq_delete(this,SQVM); } //does nothing
-////////////////////////////////////////////////////////////////////////////
- //stack functions for the api
- void Remove(SQInteger n);
-
- bool IsFalse(SQObjectPtr &o);
-
- void Pop();
- void Pop(SQInteger n);
- void Push(const SQObjectPtr &o);
- SQObjectPtr &Top();
- SQObjectPtr &PopGet();
- SQObjectPtr &GetUp(SQInteger n);
- SQObjectPtr &GetAt(SQInteger n);
-
- SQObjectPtrVec _stack;
- SQObjectPtrVec _vargsstack;
- SQInteger _top;
- SQInteger _stackbase;
- SQObjectPtr _roottable;
- SQObjectPtr _lasterror;
- SQObjectPtr _errorhandler;
- SQObjectPtr _debughook;
-
- SQObjectPtr temp_reg;
-
-
- CallInfo* _callsstack;
- SQInteger _callsstacksize;
- SQInteger _alloccallsstacksize;
-
- ExceptionsTraps _etraps;
- CallInfo *ci;
- void *_foreignptr;
- //VMs sharing the same state
- SQSharedState *_sharedstate;
- SQInteger _nnativecalls;
- //suspend infos
- SQBool _suspended;
- SQBool _suspended_root;
- SQInteger _suspended_target;
- SQInteger _suspended_traps;
- VarArgs _suspend_varargs;
-};
-
-struct AutoDec{
- AutoDec(SQInteger *n) { _n = n; }
- ~AutoDec() { (*_n)--; }
- SQInteger *_n;
-};
-
-inline SQObjectPtr &stack_get(HSQUIRRELVM v,SQInteger idx){return ((idx>=0)?(v->GetAt(idx+v->_stackbase-1)):(v->GetUp(idx)));}
-const SQChar *GetTypeName(const SQObjectPtr &obj1);
-const SQChar *IdType2Name(SQObjectType type);
-
-#define _ss(_vm_) (_vm_)->_sharedstate
-
-#ifndef NO_GARBAGE_COLLECTOR
-#define _opt_ss(_vm_) (_vm_)->_sharedstate
-#else
-#define _opt_ss(_vm_) NULL
-#endif
-
-#define PUSH_CALLINFO(v,nci){ \
- if(v->_callsstacksize == v->_alloccallsstacksize) { \
- v->GrowCallStack(); \
- } \
- v->ci = &v->_callsstack[v->_callsstacksize]; \
- *(v->ci) = nci; \
- v->_callsstacksize++; \
-}
-
-#define POP_CALLINFO(v){ \
- v->_callsstacksize--; \
- if(v->_callsstacksize) \
- v->ci = &v->_callsstack[v->_callsstacksize-1] ; \
- else \
- v->ci = NULL; \
-}
-#endif //_SQVM_H_
+++ /dev/null
-// $Id$
-//
-// SuperTux (Statistics module)
-// Copyright (C) 2004 Ricardo Cruz <rick2@aeiou.pt>
-// Copyright (C) 2006 Ondrej Hosek <ondra.hosek@gmail.com>
-// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
-//
-// 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.
-#include <config.h>
-
-#include <assert.h>
-#include <math.h>
-#include <sstream>
-#include <limits>
-#include "video/drawing_context.hpp"
-#include "gettext.hpp"
-#include "lisp/writer.hpp"
-#include "lisp/lisp.hpp"
-#include "resources.hpp"
-#include "main.hpp"
-#include "statistics.hpp"
-#include "log.hpp"
-#include "scripting/squirrel_util.hpp"
-
-namespace {
- const int nv_coins = std::numeric_limits<int>::min();
- const int nv_badguys = std::numeric_limits<int>::min();
- const float nv_time = std::numeric_limits<float>::max();
- const int nv_secrets = std::numeric_limits<int>::min();
-}
-
-float WMAP_INFO_LEFT_X;
-float WMAP_INFO_RIGHT_X;
-float WMAP_INFO_TOP_Y1;
-float WMAP_INFO_TOP_Y2;
-
-Statistics::Statistics() : coins(nv_coins), total_coins(nv_coins), badguys(nv_badguys), total_badguys(nv_badguys), time(nv_time), secrets(nv_secrets), total_secrets(nv_secrets), valid(true), display_stat(0)
-{
- WMAP_INFO_LEFT_X = (SCREEN_WIDTH/2 + 80) + 32;
- WMAP_INFO_RIGHT_X = SCREEN_WIDTH/2 + 368;
- WMAP_INFO_TOP_Y1 = SCREEN_HEIGHT/2 + 172 - 16;
- WMAP_INFO_TOP_Y2 = SCREEN_HEIGHT/2 + 172;
-}
-
-Statistics::~Statistics()
-{
-}
-
-/*
-void
-Statistics::parse(const lisp::Lisp& reader)
-{
- reader.get("coins-collected", coins);
- reader.get("coins-collected-total", total_coins);
- reader.get("badguys-killed", badguys);
- reader.get("badguys-killed-total", total_badguys);
- reader.get("time-needed", time);
- reader.get("secrets-found", secrets);
- reader.get("secrets-found-total", total_secrets);
-}
-
-void
-Statistics::write(lisp::Writer& writer)
-{
- writer.write_int("coins-collected", coins);
- writer.write_int("coins-collected-total", total_coins);
- writer.write_int("badguys-killed", badguys);
- writer.write_int("badguys-killed-total", total_badguys);
- writer.write_float("time-needed", time);
- writer.write_int("secrets-found", secrets);
- writer.write_int("secrets-found-total", total_secrets);
-}
-*/
-
-void
-Statistics::serialize_to_squirrel(HSQUIRRELVM vm)
-{
- // TODO: there's some bug in the unserialization routines that breaks stuff when an empty statistics table is written, so -- as a workaround -- let's make sure we will actually write something first
- if (!((coins != nv_coins) || (total_coins != nv_coins) || (badguys != nv_badguys) || (total_badguys != nv_badguys) || (time != nv_time) || (secrets != nv_secrets) || (total_secrets != nv_secrets))) return;
-
- sq_pushstring(vm, "statistics", -1);
- sq_newtable(vm);
- if (coins != nv_coins) Scripting::store_int(vm, "coins-collected", coins);
- if (total_coins != nv_coins) Scripting::store_int(vm, "coins-collected-total", total_coins);
- if (badguys != nv_badguys) Scripting::store_int(vm, "badguys-killed", badguys);
- if (total_badguys != nv_badguys) Scripting::store_int(vm, "badguys-killed-total", total_badguys);
- if (time != nv_time) Scripting::store_float(vm, "time-needed", time);
- if (secrets != nv_secrets) Scripting::store_int(vm, "secrets-found", secrets);
- if (total_secrets != nv_secrets) Scripting::store_int(vm, "secrets-found-total", total_secrets);
- sq_createslot(vm, -3);
-}
-
-void
-Statistics::unserialize_from_squirrel(HSQUIRRELVM vm)
-{
- sq_pushstring(vm, "statistics", -1);
- if(SQ_FAILED(sq_get(vm, -2))) {
- return;
- }
- Scripting::get_int(vm, "coins-collected", coins);
- Scripting::get_int(vm, "coins-collected-total", total_coins);
- Scripting::get_int(vm, "badguys-killed", badguys);
- Scripting::get_int(vm, "badguys-killed-total", total_badguys);
- Scripting::get_float(vm, "time-needed", time);
- Scripting::get_int(vm, "secrets-found", secrets);
- Scripting::get_int(vm, "secrets-found-total", total_secrets);
- sq_pop(vm, 1);
-}
-
-//define TOTAL_DISPLAY_TIME 3400
-//define FADING_TIME 600
-
-#define TOTAL_DISPLAY_TIME 5
-#define FADING_TIME 1
-
-void
-Statistics::draw_worldmap_info(DrawingContext& context)
-{
- // skip draw if level was never played
- if (coins == nv_coins) return;
-
- // skip draw if stats were declared invalid
- if (!valid) return;
-
- context.draw_text(white_small_text, std::string("- ") + _("Best Level Statistics") + " -", Vector((WMAP_INFO_LEFT_X + WMAP_INFO_RIGHT_X) / 2, WMAP_INFO_TOP_Y1), ALIGN_CENTER, LAYER_GUI);
-
- float alpha;
- if(timer.get_timegone() < FADING_TIME)
- alpha = (timer.get_timegone() * 1.0f / FADING_TIME);
- else if(timer.get_timeleft() < FADING_TIME)
- alpha = (timer.get_timeleft() * 1.0f / FADING_TIME);
- else
- alpha = 1.0f;
-
- context.push_transform();
- context.set_alpha(alpha);
-
- char caption_buf[128];
- char stat_buf[128];
- switch (display_stat)
- {
- case 0:
- snprintf(caption_buf, sizeof(caption_buf), _("Max coins collected:"));
- snprintf(stat_buf, sizeof(stat_buf), "%d/%d", coins, total_coins);
- break;
- case 1:
- snprintf(caption_buf, sizeof(caption_buf), _("Max fragging:"));
- snprintf(stat_buf, sizeof(stat_buf), "%d/%d", badguys, total_badguys);
- break;
- case 2:
- snprintf(caption_buf, sizeof(caption_buf), _("Min time needed:"));
- {
- int csecs = (int)(time * 100);
- int mins = (int)(csecs / 6000);
- int secs = (csecs % 6000) / 100;
- snprintf(stat_buf, sizeof(stat_buf), "%02d:%02d", mins,secs);
- }
- break;
- case 3:
- snprintf(caption_buf, sizeof(caption_buf), _("Max secrets found:"));
- snprintf(stat_buf, sizeof(stat_buf), "%d/%d", secrets, total_secrets);
- break;
- default:
- log_debug << "Invalid stat requested to be drawn" << std::endl;
- break;
- }
-
- if (!timer.started())
- {
- timer.start(TOTAL_DISPLAY_TIME);
- display_stat++;
- if (display_stat > 3) display_stat = 0;
- }
-
- context.draw_text(white_small_text, caption_buf, Vector(WMAP_INFO_LEFT_X, WMAP_INFO_TOP_Y2), ALIGN_LEFT, LAYER_GUI);
- context.draw_text(white_small_text, stat_buf, Vector(WMAP_INFO_RIGHT_X, WMAP_INFO_TOP_Y2), ALIGN_RIGHT, LAYER_GUI);
- context.pop_transform();
-}
-
-void
-Statistics::draw_message_info(DrawingContext& context, std::string title)
-{
- // skip draw if level was never played
- // TODO: do we need this?
- if (coins == nv_coins) return;
-
- // skip draw if stats were declared invalid
- if (!valid) return;
-
- const float width = white_small_text->get_text_width("Max coins collected: 1111 / 1111");
- const float left = (SCREEN_WIDTH - width) / 2;
- const float right = (SCREEN_WIDTH + width) / 2;
-
- context.draw_text(gold_text, title, Vector(SCREEN_WIDTH/2, 410), ALIGN_CENTER, LAYER_GUI);
-
- char stat_buf[128];
- int py = 450 + 18;
-
- snprintf(stat_buf, sizeof(stat_buf), "%d/%d", coins, total_coins);
- context.draw_text(white_small_text, _("Max coins collected:"), Vector(left, py), ALIGN_LEFT, LAYER_GUI);
- context.draw_text(white_small_text, "%d / %d", Vector(right, py), ALIGN_RIGHT, LAYER_GUI);
- py+=18;
-
- snprintf(stat_buf, sizeof(stat_buf), "%d/%d", badguys, total_badguys);
- context.draw_text(white_small_text, _("Max fragging:"), Vector(left, py), ALIGN_LEFT, LAYER_GUI);
- context.draw_text(white_small_text, "%d / %d", Vector(right, py), ALIGN_RIGHT, LAYER_GUI);
- py+=18;
-
- int csecs = (int)(time * 100);
- int mins = (int)(csecs / 6000);
- int secs = (csecs % 6000) / 100;
- snprintf(stat_buf, sizeof(stat_buf), "%02d:%02d", mins,secs);
- context.draw_text(white_small_text, _("Min time needed:"), Vector(left, py), ALIGN_LEFT, LAYER_GUI);
- context.draw_text(white_small_text, "%02d:%02d", Vector(right, py), ALIGN_RIGHT, LAYER_GUI);
- py+=18;
-
- snprintf(stat_buf, sizeof(stat_buf), "%d/%d", secrets, total_secrets);
- context.draw_text(white_small_text, _("Max secrets found:"), Vector(left, py), ALIGN_LEFT, LAYER_GUI);
- context.draw_text(white_small_text, "%d / %d", Vector(right, py), ALIGN_RIGHT, LAYER_GUI);
- py+=18;
-}
-
-void
-Statistics::draw_endseq_panel(DrawingContext& context, Statistics* best_stats, Surface* backdrop)
-{
- // skip draw if level was never played
- // TODO: do we need this?
- if (coins == nv_coins) return;
-
- // skip draw if stats were declared invalid
- if (!valid) return;
-
- // abort if we have no backdrop
- if (!backdrop) return;
-
- int box_w = 220+110+110;
- int box_h = 30+20+20+20;
- int box_x = (int)((SCREEN_WIDTH - box_w) / 2);
- int box_y = (int)(SCREEN_HEIGHT / 2) - box_h;
-
- int bd_w = (int)backdrop->get_width();
- int bd_h = (int)backdrop->get_height();
- int bd_x = (int)((SCREEN_WIDTH - bd_w) / 2);
- int bd_y = box_y + (box_h / 2) - (bd_h / 2);
-
- int col1_x = box_x;
- int col2_x = col1_x+200;
- int col3_x = col2_x+130;
-
- int row1_y = box_y;
- int row2_y = row1_y+30;
- int row3_y = row2_y+20;
- int row4_y = row3_y+20;
-
- context.push_transform();
- context.set_alpha(0.5);
- context.draw_surface(backdrop, Vector(bd_x, bd_y), LAYER_GUI);
- context.pop_transform();
-
- char buf[129];
- context.draw_text(white_text, _("You"), Vector(col2_x, row1_y), ALIGN_LEFT, LAYER_GUI);
- context.draw_text(white_text, _("Best"), Vector(col3_x, row1_y), ALIGN_LEFT, LAYER_GUI);
-
- context.draw_text(white_text, _("Coins"), Vector(col2_x-16, row2_y), ALIGN_RIGHT, LAYER_GUI);
- snprintf(buf, sizeof(buf), "%d/%d", std::min(coins, 999), std::min(total_coins, 999));
- context.draw_text(gold_text, buf, Vector(col2_x, row2_y), ALIGN_LEFT, LAYER_GUI);
- if (best_stats && (best_stats->coins > coins)) {
- snprintf(buf, sizeof(buf), "%d/%d", std::min(best_stats->coins, 999), std::min(best_stats->total_coins, 999));
- }
- context.draw_text(gold_text, buf, Vector(col3_x, row2_y), ALIGN_LEFT, LAYER_GUI);
-
- context.draw_text(white_text, _("Secrets"), Vector(col2_x-16, row4_y), ALIGN_RIGHT, LAYER_GUI);
- snprintf(buf, sizeof(buf), "%d/%d", secrets, total_secrets);
- context.draw_text(gold_text, buf, Vector(col2_x, row4_y), ALIGN_LEFT, LAYER_GUI);
- if (best_stats && (best_stats->secrets > secrets)) {
- snprintf(buf, sizeof(buf), "%d/%d", best_stats->secrets, best_stats->total_secrets);
- }
- context.draw_text(gold_text, buf, Vector(col3_x, row4_y), ALIGN_LEFT, LAYER_GUI);
-
- context.draw_text(white_text, _("Time"), Vector(col2_x-16, row3_y), ALIGN_RIGHT, LAYER_GUI);
- int csecs = (int)(time * 100);
- int mins = (int)(csecs / 6000);
- int secs = (csecs % 6000) / 100;
- snprintf(buf, sizeof(buf), "%02d:%02d", mins,secs);
- context.draw_text(gold_text, buf, Vector(col2_x, row3_y), ALIGN_LEFT, LAYER_GUI);
- if (best_stats && (best_stats->time < time)) {
- int csecs = (int)(best_stats->time * 100);
- int mins = (int)(csecs / 6000);
- int secs = (csecs % 6000) / 100;
- snprintf(buf, sizeof(buf), "%02d:%02d", mins,secs);
- }
- context.draw_text(gold_text, buf, Vector(col3_x, row3_y), ALIGN_LEFT, LAYER_GUI);
-}
-
-void
-Statistics::zero()
-{
- reset();
- total_coins = 0;
- total_badguys = 0;
- total_secrets = 0;
-}
-
-void
-Statistics::reset()
-{
- coins = 0;
- badguys = 0;
- time = 0;
- secrets = 0;
-}
-
-void
-Statistics::merge(Statistics& s2)
-{
- if (!s2.valid) return;
- coins = std::max(coins, s2.coins);
- total_coins = s2.total_coins;
- badguys = std::max(badguys, s2.badguys);
- total_badguys = s2.total_badguys;
- time = std::min(time, s2.time);
- secrets = std::max(secrets, s2.secrets);
- total_secrets = s2.total_secrets;
-}
-
-void
-Statistics::operator+=(const Statistics& s2)
-{
- if (!s2.valid) return;
- if (s2.coins != nv_coins) coins += s2.coins;
- if (s2.total_coins != nv_coins) total_coins += s2.total_coins;
- if (s2.badguys != nv_badguys) badguys += s2.badguys;
- if (s2.total_badguys != nv_badguys) total_badguys += s2.total_badguys;
- if (s2.time != nv_time) time += s2.time;
- if (s2.secrets != nv_secrets) secrets += s2.secrets;
- if (s2.total_secrets != nv_secrets) total_secrets += s2.total_secrets;
-}
-
-void
-Statistics::declare_invalid()
-{
- valid = false;
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux (Statistics module)
-// Copyright (C) 2004 Ricardo Cruz <rick2@aeiou.pt>
-// Copyright (C) 2006 Ondrej Hosek <ondra.hosek@gmail.com>
-// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
-//
-// 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.
-
-#ifndef SUPERTUX_STATISTICS_H
-#define SUPERTUX_STATISTICS_H
-
-#include <squirrel.h>
-#include "timer.hpp"
-
-namespace lisp { class Writer; }
-namespace lisp { class Lisp; }
-class Surface;
-class DrawingContext;
-
-/** This class is a layer between level and worldmap to keep
- * track of stuff like scores, and minor, but funny things, like
- * number of jumps and stuff */
-class Statistics
-{
-public:
- int coins; /**< coins collected */
- int total_coins; /**< coins in level */
- int badguys; /**< badguys actively killed */
- int total_badguys; /**< (vincible) badguys in level */
- float time; /**< seconds needed */
- int secrets; /**< secret areas found */
- int total_secrets; /**< secret areas in level */
-
-public:
- Statistics(); /**< Creates new statistics, call reset() before counting */
- ~Statistics();
-
- /// read statistics from lisp file
- //void parse(const lisp::Lisp& lisp);
- /// write statistics to lisp file
- //void write(lisp::Writer& writer);
-
- /**
- * serialize statistics object as squirrel table "statistics"
- */
- void serialize_to_squirrel(HSQUIRRELVM vm);
-
- /**
- * unserialize statistics object from squirrel table "statistics"
- */
- void unserialize_from_squirrel(HSQUIRRELVM vm);
-
- void draw_worldmap_info(DrawingContext& context); /**< draw worldmap stat HUD */
- void draw_message_info(DrawingContext& context, std::string title); /**< draw stats at level start */
- void draw_endseq_panel(DrawingContext& context, Statistics* best_stats, Surface* backdrop); /**< draw panel shown during level's end sequence */
-
- void zero(); /**< Set stats to zero */
- void reset(); /**< Set stats (but not totals) to zero */
- void merge(Statistics& stats); /**< Given another Statistics object finds the best of each one */
- void operator+=(const Statistics& o); /**< Add two Statistics objects */
-
- void declare_invalid(); /**< marks statistics as invalid for their entire lifetime (e.g. after cheating). Invalid statistics will not be merged or drawn. */
-
-private:
- bool valid; /**< stores whether this statistics can be trusted */
- Timer timer; /**< for draw_worldmap_info: time until switching to next stat */
- int display_stat; /**< for draw_worldmap_info: which stat is currently displayed */
-};
-
-#endif /*SUPERTUX_STATISTICS_H*/
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#include <config.h>
-
-#include "textscroller.hpp"
-
-#include <stdexcept>
-#include "log.hpp"
-#include "mainloop.hpp"
-#include "resources.hpp"
-#include "video/font.hpp"
-#include "video/drawing_context.hpp"
-#include "video/surface.hpp"
-#include "gui/menu.hpp"
-#include "lisp/parser.hpp"
-#include "lisp/lisp.hpp"
-#include "audio/sound_manager.hpp"
-#include "main.hpp"
-#include "fadeout.hpp"
-#include "control/joystickkeyboardcontroller.hpp"
-
-static const float DEFAULT_SPEED = 20;
-static const float LEFT_BORDER = 50;
-static const float SCROLL = 60;
-static const float ITEMS_SPACE = 4;
-
-TextScroller::TextScroller(const std::string& filename)
-{
- defaultspeed = DEFAULT_SPEED;
- speed = defaultspeed;
-
- std::string text;
- std::string background_file;
-
- lisp::Parser parser;
- try {
- const lisp::Lisp* root = parser.parse(filename);
-
- const lisp::Lisp* text_lisp = root->get_lisp("supertux-text");
- if(!text_lisp)
- throw std::runtime_error("File isn't a supertux-text file");
-
- if(!text_lisp->get("text", text))
- throw std::runtime_error("file doesn't contain a text field");
- if(!text_lisp->get("background", background_file))
- throw std::runtime_error("file doesn't contain a background file");
- text_lisp->get("speed", defaultspeed);
- text_lisp->get("music", music);
- } catch(std::exception& e) {
- std::ostringstream msg;
- msg << "Couldn't load file '" << filename << "': " << e.what() << std::endl;
- throw std::runtime_error(msg.str());
- }
-
- // Split text string lines into a vector
- lines = InfoBoxLine::split(text, SCREEN_WIDTH - 2*LEFT_BORDER);
-
- // load background image
- background.reset(new Surface("images/background/" + background_file));
-
- scroll = 0;
- fading = false;
-}
-
-TextScroller::~TextScroller()
-{
- for(std::vector<InfoBoxLine*>::iterator i = lines.begin(); i != lines.end(); i++) delete *i;
-}
-
-void
-TextScroller::setup()
-{
- sound_manager->play_music(music);
- Menu::set_current(NULL);
-}
-
-void
-TextScroller::update(float elapsed_time)
-{
- if(main_controller->hold(Controller::UP)) {
- speed = -defaultspeed*5;
- } else if(main_controller->hold(Controller::DOWN)) {
- speed = defaultspeed*5;
- } else {
- speed = defaultspeed;
- }
- if(main_controller->pressed(Controller::JUMP)
- || main_controller->pressed(Controller::ACTION)
- || main_controller->pressed(Controller::MENU_SELECT))
- scroll += SCROLL;
- if(main_controller->pressed(Controller::PAUSE_MENU)) {
- main_loop->exit_screen(new FadeOut(0.5));
- }
-
- scroll += speed * elapsed_time;
-
- if(scroll < 0)
- scroll = 0;
-}
-
-void
-TextScroller::draw(DrawingContext& context)
-{
- context.draw_filled_rect(Vector(0, 0), Vector(SCREEN_WIDTH, SCREEN_HEIGHT),
- Color(0.6f, 0.7f, 0.8f, 0.5f), 0);
- context.draw_surface(background.get(), Vector(SCREEN_WIDTH/2 - background->get_width()/2 , SCREEN_HEIGHT/2 - background->get_height()/2), 0);
-
- float y = SCREEN_HEIGHT - scroll;
- for(size_t i = 0; i < lines.size(); i++) {
- lines[i]->draw(context, Rect(LEFT_BORDER, y, SCREEN_WIDTH - 2*LEFT_BORDER, y), LAYER_GUI);
- y += lines[i]->get_height();
- }
-
- if(y < 0 && !fading ) {
- fading = true;
- main_loop->exit_screen(new FadeOut(0.5));
- }
-}
-
-InfoBox::InfoBox(const std::string& text)
- : firstline(0)
-{
- // Split text string lines into a vector
- lines = InfoBoxLine::split(text, 400);
-
- try
- {
- // get the arrow sprites
- arrow_scrollup = new Surface("images/engine/menu/scroll-up.png");
- arrow_scrolldown = new Surface("images/engine/menu/scroll-down.png");
- }
- catch (std::exception& e)
- {
- log_warning << "Could not load scrolling images: " << e.what() << std::endl;
- arrow_scrollup = 0;
- arrow_scrolldown = 0;
- }
-}
-
-InfoBox::~InfoBox()
-{
- for(std::vector<InfoBoxLine*>::iterator i = lines.begin();
- i != lines.end(); i++)
- delete *i;
- delete arrow_scrollup;
- delete arrow_scrolldown;
-}
-
-void
-InfoBox::draw(DrawingContext& context)
-{
- float x1 = SCREEN_WIDTH/2-200;
- float y1 = SCREEN_HEIGHT/2-200;
- float width = 400;
- float height = 200;
-
- context.draw_filled_rect(Vector(x1, y1), Vector(width, height),
- Color(0.6f, 0.7f, 0.8f, 0.5f), LAYER_GUI-1);
-
- float y = y1;
- bool linesLeft = false;
- for(size_t i = firstline; i < lines.size(); ++i) {
- if(y >= y1 + height) {
- linesLeft = true;
- break;
- }
-
- lines[i]->draw(context, Rect(x1, y, x1+width, y), LAYER_GUI);
- y += lines[i]->get_height();
- }
-
- {
- // draw the scrolling arrows
- if (arrow_scrollup && firstline > 0)
- context.draw_surface(arrow_scrollup,
- Vector( x1 + width - arrow_scrollup->get_width(), // top-right corner of box
- y1), LAYER_GUI);
-
- if (arrow_scrolldown && linesLeft && firstline < lines.size()-1)
- context.draw_surface(arrow_scrolldown,
- Vector( x1 + width - arrow_scrolldown->get_width(), // bottom-light corner of box
- y1 + height - arrow_scrolldown->get_height()),
- LAYER_GUI);
- }
-}
-
-void
-InfoBox::scrollup()
-{
- if(firstline > 0)
- firstline--;
-}
-
-void
-InfoBox::scrolldown()
-{
- if(firstline < lines.size()-1)
- firstline++;
-}
-
-void
-InfoBox::pageup()
-{
-}
-
-void
-InfoBox::pagedown()
-{
-}
-
-namespace {
-Font* get_font_by_format_char(char format_char) {
- switch(format_char)
- {
- case ' ':
- return white_small_text;
- break;
- case '\t':
- return white_text;
- break;
- case '-':
- return white_big_text;
- break;
- case '*':
- return blue_text;
- break;
- case '#':
- return white_text;
- break;
- case '!':
- return 0;
- break;
- default:
- return 0;
- log_warning << "Unknown format_char: '" << format_char << "'" << std::endl;
- break;
- }
-}
-
-InfoBoxLine::LineType get_linetype_by_format_char(char format_char) {
- switch(format_char)
- {
- case ' ':
- return InfoBoxLine::SMALL;
- break;
- case '\t':
- return InfoBoxLine::NORMAL;
- break;
- case '-':
- return InfoBoxLine::HEADING;
- break;
- case '*':
- return InfoBoxLine::REFERENCE;
- break;
- case '#':
- return InfoBoxLine::NORMAL_LEFT;
- break;
- case '!':
- return InfoBoxLine::IMAGE;
- break;
- default:
- return InfoBoxLine::SMALL;
- log_warning << "Unknown format_char: '" << format_char << "'" << std::endl;
- break;
- }
-}
-}
-
-InfoBoxLine::InfoBoxLine(char format_char, const std::string& text) : lineType(NORMAL), font(white_text), text(text), image(0)
-{
- font = get_font_by_format_char(format_char);
- lineType = get_linetype_by_format_char(format_char);
- if (lineType == IMAGE) image = new Surface(text);
-}
-
-InfoBoxLine::~InfoBoxLine()
-{
- delete image;
-}
-
-const std::vector<InfoBoxLine*>
-InfoBoxLine::split(const std::string& text, float width)
-{
- std::vector<InfoBoxLine*> lines;
-
- std::string::size_type i = 0;
- std::string::size_type l;
- char format_char = '#';
- while(i < text.size()) {
- // take care of empty lines - represent them as blank lines of normal text
- if (text[i] == '\n') {
- lines.push_back(new InfoBoxLine('\t', ""));
- i++;
- continue;
- }
-
- // extract the format_char
- format_char = text[i];
- i++;
- if (i >= text.size()) break;
-
- // extract one line
- l = text.find("\n", i);
- if (l == std::string::npos) l=text.size();
- std::string s = text.substr(i, l-i);
- i = l+1;
-
- // if we are dealing with an image, just store the line
- if (format_char == '!') {
- lines.push_back(new InfoBoxLine(format_char, s));
- continue;
- }
-
- // append wrapped parts of line into list
- std::string overflow;
- do {
- Font* font = get_font_by_format_char(format_char);
- std::string s2 = s;
- if (font) s2 = font->wrap_to_width(s2, width, &overflow);
- lines.push_back(new InfoBoxLine(format_char, s2));
- s = overflow;
- } while (s.length() > 0);
-
- }
-
- return lines;
-}
-
-void
-InfoBoxLine::draw(DrawingContext& context, const Rect& bbox, int layer)
-{
- Vector position = bbox.p1;
- switch (lineType) {
- case IMAGE:
- context.draw_surface(image, Vector( (bbox.p1.x + bbox.p2.x - image->get_width()) / 2, position.y), layer);
- break;
- case NORMAL_LEFT:
- context.draw_text(font, text, Vector(position.x, position.y), ALIGN_LEFT, layer);
- break;
- default:
- context.draw_text(font, text, Vector((bbox.p1.x + bbox.p2.x) / 2, position.y), ALIGN_CENTER, layer);
- break;
- }
-}
-
-float
-InfoBoxLine::get_height()
-{
- switch (lineType) {
- case IMAGE:
- return image->get_height() + ITEMS_SPACE;
- case NORMAL_LEFT:
- return font->get_height() + ITEMS_SPACE;
- default:
- return font->get_height() + ITEMS_SPACE;
- }
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __TEXTSCROLLER_H__
-#define __TEXTSCROLLER_H__
-
-#include <vector>
-#include <string>
-#include <map>
-
-#include "screen.hpp"
-#include "math/vector.hpp"
-#include "math/rect.hpp"
-
-class DrawingContext;
-class Surface;
-class Font;
-
-/**
- * Helper class for InfoBox: Represents a line of text
- */
-class InfoBoxLine
-{
-public:
- enum LineType { NORMAL, NORMAL_LEFT, SMALL, HEADING, REFERENCE, IMAGE};
-
- InfoBoxLine(char format_char, const std::string& text);
- ~InfoBoxLine();
-
- void draw(DrawingContext& context, const Rect& bbox, int layer);
- float get_height();
-
- static const std::vector<InfoBoxLine*> split(const std::string& text, float width);
-
-private:
- InfoBoxLine::LineType lineType;
- Font* font;
- std::string text;
- Surface* image;
-};
-
-/** This class is displaying a box with information text inside the game
- */
-class InfoBox
-{
-public:
- InfoBox(const std::string& text);
- ~InfoBox();
-
- void draw(DrawingContext& context);
- void scrolldown();
- void scrollup();
- void pagedown();
- void pageup();
-
-private:
- size_t firstline;
- std::vector<InfoBoxLine*> lines;
- std::map<std::string, Surface*> images;
- Surface* arrow_scrollup;
- Surface* arrow_scrolldown;
-};
-
-class TextScroller : public Screen
-{
-public:
- TextScroller(const std::string& file);
- virtual ~TextScroller();
-
- void setup();
- void draw(DrawingContext& context);
- void update(float elapsed_time);
-
-private:
- float defaultspeed;
- float speed;
- std::string music;
- std::auto_ptr<Surface> background;
- std::vector<InfoBoxLine*> lines;
- float scroll;
- bool fading;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2004 Tobias Glaesser <tobi.web@gmx.de>
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#include <config.h>
-
-#include <math.h>
-#include <assert.h>
-#include <iostream>
-#include <stdexcept>
-
-#include "lisp/lisp.hpp"
-#include "tile.hpp"
-#include "resources.hpp"
-#include "timer.hpp"
-#include "math/vector.hpp"
-#include "video/drawing_context.hpp"
-#include "log.hpp"
-
-
-Tile::Tile()
- : id(0), attributes(0), data(0), anim_fps(1)
-{
-}
-
-Tile::Tile(unsigned int id, Uint32 attributes, const ImageSpec& imagespec)
- : id(id), attributes(attributes), data(0), anim_fps(1)
-{
- imagespecs.push_back(imagespec);
-}
-
-Tile::~Tile()
-{
- for(std::vector<Surface*>::iterator i = images.begin(); i != images.end();
- ++i) {
- delete *i;
- }
-}
-
-void
-Tile::parse(const lisp::Lisp& reader)
-{
- if(!reader.get("id", id)) {
- throw std::runtime_error("Missing tile-id.");
- }
-
- bool value = false;
- if(reader.get("solid", value) && value)
- attributes |= SOLID;
- if(reader.get("unisolid", value) && value)
- attributes |= UNISOLID | SOLID;
- if(reader.get("brick", value) && value)
- attributes |= BRICK;
- if(reader.get("ice", value) && value)
- attributes |= ICE;
- if(reader.get("water", value) && value)
- attributes |= WATER;
- if(reader.get("hurts", value) && value)
- attributes |= HURTS;
- if(reader.get("fire", value) && value)
- attributes |= FIRE;
- if(reader.get("fullbox", value) && value)
- attributes |= FULLBOX;
- if(reader.get("coin", value) && value)
- attributes |= COIN;
- if(reader.get("goal", value) && value)
- attributes |= GOAL;
-
- if(reader.get("north", value) && value)
- data |= WORLDMAP_NORTH;
- if(reader.get("south", value) && value)
- data |= WORLDMAP_SOUTH;
- if(reader.get("west", value) && value)
- data |= WORLDMAP_WEST;
- if(reader.get("east", value) && value)
- data |= WORLDMAP_EAST;
- if(reader.get("stop", value) && value)
- data |= WORLDMAP_STOP;
-
- reader.get("data", data);
- reader.get("anim-fps", anim_fps);
-
- if(reader.get("slope-type", data)) {
- attributes |= SOLID | SLOPE;
- }
-
- const lisp::Lisp* images = reader.get_lisp("images");
- if(images)
- parse_images(*images);
-}
-
-void
-Tile::parse_images(const lisp::Lisp& images_lisp)
-{
- const lisp::Lisp* list = &images_lisp;
- while(list) {
- const lisp::Lisp* cur = list->get_car();
- if(cur->get_type() == lisp::Lisp::TYPE_STRING) {
- std::string file;
- cur->get(file);
- imagespecs.push_back(ImageSpec(file, Rect(0, 0, 0, 0)));
- } else if(cur->get_type() == lisp::Lisp::TYPE_CONS &&
- cur->get_car()->get_type() == lisp::Lisp::TYPE_SYMBOL &&
- cur->get_car()->get_symbol() == "region") {
- const lisp::Lisp* ptr = cur->get_cdr();
-
- std::string file;
- float x = 0, y = 0, w = 0, h = 0;
- ptr->get_car()->get(file); ptr = ptr->get_cdr();
- ptr->get_car()->get(x); ptr = ptr->get_cdr();
- ptr->get_car()->get(y); ptr = ptr->get_cdr();
- ptr->get_car()->get(w); ptr = ptr->get_cdr();
- ptr->get_car()->get(h);
- imagespecs.push_back(ImageSpec(file, Rect(x, y, x+w, y+h)));
- } else {
- log_warning << "Expected string or list in images tag" << std::endl;
- continue;
- }
-
- list = list->get_cdr();
- }
-}
-
-void
-Tile::load_images(const std::string& tilesetpath)
-{
- assert(images.size() == 0);
- for(std::vector<ImageSpec>::iterator i = imagespecs.begin(); i !=
- imagespecs.end(); ++i) {
- const ImageSpec& spec = *i;
- Surface* surface;
- std::string file = tilesetpath + spec.file;
- if(spec.rect.get_width() <= 0) {
- surface = new Surface(file);
- } else {
- surface = new Surface(file,
- (int) spec.rect.p1.x,
- (int) spec.rect.p1.y,
- (int) spec.rect.get_width(),
- (int) spec.rect.get_height());
- }
- images.push_back(surface);
- }
-}
-
-void
-Tile::draw(DrawingContext& context, const Vector& pos, int z_pos) const
-{
- if(images.size() > 1) {
- size_t frame = size_t(game_time * anim_fps) % images.size();
- context.draw_surface(images[frame], pos, z_pos);
- } else if (images.size() == 1) {
- context.draw_surface(images[0], pos, z_pos);
- }
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2004 Tobias Glaesser <tobi.web@gmx.de>
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#ifndef TILE_H
-#define TILE_H
-
-#include <vector>
-#include <SDL.h>
-#include <stdint.h>
-#include "video/surface.hpp"
-#include "math/rect.hpp"
-
-namespace lisp { class Lisp; }
-
-class DrawingContext;
-
-/**
-Tile Class
-*/
-class Tile
-{
-public:
- /// bitset for tile attributes
- enum {
- /** solid tile that is indestructable by Tux */
- SOLID = 0x0001,
- /** uni-directional solid tile */
- UNISOLID = 0x0002,
- /** a brick that can be destroyed by jumping under it */
- BRICK = 0x0004,
- /** the level should be finished when touching a goaltile.
- * if data is 0 then the endsequence should be triggered, if data is 1
- * then we can finish the level instantly.
- */
- GOAL = 0x0008,
- /** slope tile */
- SLOPE = 0x0010,
- /** Bonusbox, content is stored in \a data */
- FULLBOX = 0x0020,
- /** Tile is a coin */
- COIN = 0x0040,
-
- /* interesting flags (the following are passed to gameobjects) */
- FIRST_INTERESTING_FLAG = 0x0100,
-
- /** an ice brick that makes tux sliding more than usual */
- ICE = 0x0100,
- /** a water tile in which tux starts to swim */
- WATER = 0x0200,
- /** a tile that hurts the player if he touches it */
- HURTS = 0x0400,
- /** for lava: WATER, HURTS, FIRE */
- FIRE = 0x0800
- };
-
- /// worldmap flags
- enum {
- WORLDMAP_NORTH = 0x0001,
- WORLDMAP_SOUTH = 0x0002,
- WORLDMAP_EAST = 0x0004,
- WORLDMAP_WEST = 0x0008,
- WORLDMAP_DIR_MASK = 0x000f,
-
- WORLDMAP_STOP = 0x0010,
-
- // convenience values ("C" stands for crossroads)
- WORLDMAP_CNSE = WORLDMAP_NORTH | WORLDMAP_SOUTH | WORLDMAP_EAST,
- WORLDMAP_CNSW = WORLDMAP_NORTH | WORLDMAP_SOUTH | WORLDMAP_WEST,
- WORLDMAP_CNEW = WORLDMAP_NORTH | WORLDMAP_EAST | WORLDMAP_WEST,
- WORLDMAP_CSEW = WORLDMAP_SOUTH | WORLDMAP_EAST | WORLDMAP_WEST,
- WORLDMAP_CNSEW = WORLDMAP_NORTH | WORLDMAP_SOUTH | WORLDMAP_EAST | WORLDMAP_WEST
- };
-
- struct ImageSpec {
- ImageSpec(const std::string& newfile, const Rect& newrect)
- : file(newfile), rect(newrect)
- { }
-
- std::string file;
- Rect rect;
- };
-
-private:
- unsigned int id;
-
- std::vector<ImageSpec> imagespecs;
- std::vector<Surface*> images;
-
- /// tile attributes
- uint32_t attributes;
-
- /** General purpose data attached to a tile (content of a box, type of coin)*/
- int data;
-
- float anim_fps;
-
-public:
- ~Tile();
-
- /** Draw a tile on the screen */
- void draw(DrawingContext& context, const Vector& pos, int z_pos) const;
-
- unsigned int getID() const
- { return id; }
-
- uint32_t getAttributes() const
- { return attributes; }
-
- int getData() const
- { return data; }
-
- /// returns the width of the tile in pixels
- int getWidth() const
- {
- if(!images.size())
- return 0;
- return (int) images[0]->get_width();
- }
-
- /// returns the height of the tiles in pixels
- int getHeight() const
- {
- if(!images.size())
- return 0;
- return (int) images[0]->get_height();
- }
-
-protected:
- friend class TileManager;
- Tile();
- Tile(unsigned int id, Uint32 attributes, const ImageSpec& imagespec);
-
- void load_images(const std::string& tilesetpath);
-
- /// parses the tile and returns it's id number
- void parse(const lisp::Lisp& reader);
- void parse_images(const lisp::Lisp& cur);
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2004 Tobias Glaesser <tobi.web@gmx.de>
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#include <config.h>
-
-#include <memory>
-#include <stdexcept>
-#include <sstream>
-#include <iostream>
-#include <assert.h>
-#include <SDL.h>
-#include "video/drawing_context.hpp"
-#include "log.hpp"
-#include "lisp/lisp.hpp"
-#include "lisp/parser.hpp"
-#include "lisp/list_iterator.hpp"
-#include "tile.hpp"
-#include "tile_manager.hpp"
-#include "resources.hpp"
-
-TileManager* tile_manager = NULL;
-
-TileManager::TileManager(const std::string& filename)
-{
-#ifdef DEBUG
- Uint32 ticks = SDL_GetTicks();
-#endif
- load_tileset(filename);
-#ifdef DEBUG
- log_debug << "Tiles loaded in " << (SDL_GetTicks() - ticks) / 1000.0 << " seconds" << std::endl;
-#endif
-}
-
-TileManager::~TileManager()
-{
- for(Tiles::iterator i = tiles.begin(); i != tiles.end(); ++i)
- delete *i;
-}
-
-void TileManager::load_tileset(std::string filename)
-{
- // free old tiles
- for(Tiles::iterator i = tiles.begin(); i != tiles.end(); ++i)
- delete *i;
- tiles.clear();
-
- std::string::size_type t = filename.rfind('/');
- if(t == std::string::npos) {
- tiles_path = "";
- } else {
- tiles_path = filename.substr(0, t+1);
- }
-
- lisp::Parser parser;
- const lisp::Lisp* root = parser.parse(filename);
-
- const lisp::Lisp* tiles_lisp = root->get_lisp("supertux-tiles");
- if(!tiles_lisp)
- throw std::runtime_error("file is not a supertux tiles file.");
-
- lisp::ListIterator iter(tiles_lisp);
- while(iter.next()) {
- if(iter.item() == "tile") {
- Tile* tile = new Tile();
- tile->parse(*(iter.lisp()));
-
- if(tile->id >= tiles.size())
- tiles.resize(tile->id+1, 0);
-
- if(tiles[tile->id] != 0) {
- log_warning << "Tile with ID " << tile->id << " redefined" << std::endl;
- delete tile;
- } else {
- tiles[tile->id] = tile;
- }
- } else if(iter.item() == "tilegroup") {
- TileGroup tilegroup;
- const lisp::Lisp* tilegroup_lisp = iter.lisp();
- tilegroup_lisp->get("name", tilegroup.name);
- tilegroup_lisp->get_vector("tiles", tilegroup.tiles);
- tilegroups.insert(tilegroup);
- } else if (iter.item() == "tiles") {
- // List of ids (use 0 if the tile should be ignored)
- std::vector<unsigned int> ids;
- // List of attributes of the tile
- std::vector<unsigned int> attributes;
- std::string image;
-
- // width and height of the image in tile units, this is used for two
- // purposes:
- // a) so we don't have to load the image here to know its dimensions
- // b) so that the resulting 'tiles' entry is more robust,
- // ie. enlarging the image won't break the tile id mapping
- // FIXME: height is actually not used, since width might be enough for
- // all purposes, still feels somewhat more natural this way
- unsigned int width = 0;
- unsigned int height = 0;
-
- iter.lisp()->get_vector("ids", ids);
- iter.lisp()->get_vector("attributes", attributes);
- iter.lisp()->get("image", image);
- iter.lisp()->get("width", width);
- iter.lisp()->get("height", height);
-
- if (ids.size() != attributes.size())
- {
- std::ostringstream err;
- err << "Number of ids (" << ids.size() << ") and attributes (" << attributes.size()
- << ") missmatch for image '" << image << "', but must be equal";
- throw std::runtime_error(err.str());
- }
-
- for(std::vector<unsigned int>::size_type i = 0; i < ids.size() && i < width*height; ++i)
- {
- if (ids[i])
- {
- if(ids[i] >= tiles.size())
- tiles.resize(ids[i]+1, 0);
-
- int x = 32*(i % width);
- int y = 32*(i / width);
- Tile* tile = new Tile(ids[i], attributes[i], Tile::ImageSpec(image, Rect(x, y, x + 32, y + 32)));
- if (tiles[ids[i]] == 0) {
- tiles[ids[i]] = tile;
- } else {
- log_warning << "Tile with ID " << ids[i] << " redefined" << std::endl;
- delete tile;
- }
- }
- }
-
- } else if(iter.item() == "properties") {
- // deprecated
- } else {
- log_warning << "Unknown symbol '" << iter.item() << "' tile defintion file" << std::endl;
- }
- }
-
- if (0)
- { // enable this if you want to see a list of free tiles
- log_info << "Last Tile ID is " << tiles.size()-1 << std::endl;
- int last = -1;
- for(int i = 0; i < int(tiles.size()); ++i)
- {
- if (tiles[i] == 0 && last == -1)
- {
- last = i;
- }
- else if (tiles[i] && last != -1)
- {
- log_info << "Free Tile IDs (" << i - last << "): " << last << " - " << i-1 << std::endl;
- last = -1;
- }
- }
- }
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2004 Tobias Glaesser <tobi.web@gmx.de>
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef HEADER_TILE_MANAGER_HXX
-#define HEADER_TILE_MANAGER_HXX
-
-#include <set>
-#include <vector>
-#include <string>
-#include <map>
-#include <iostream>
-#include <stdint.h>
-#include <assert.h>
-#include "log.hpp"
-#include "tile.hpp"
-
-struct TileGroup
-{
- friend bool operator<(const TileGroup& lhs, const TileGroup& rhs)
- { return lhs.name < rhs.name; };
- friend bool operator>(const TileGroup& lhs, const TileGroup& rhs)
- { return lhs.name > rhs.name; };
-
- std::string name;
- std::vector<int> tiles;
-};
-
-class TileManager
-{
-private:
- typedef std::vector<Tile*> Tiles;
- Tiles tiles;
-
- static TileManager* instance_ ;
- std::set<TileGroup> tilegroups;
-
- std::string tiles_path;
-
- void load_tileset(std::string filename);
-
-public:
- TileManager(const std::string& filename);
- ~TileManager();
-
- const std::set<TileGroup>& get_tilegroups() const
- {
- return tilegroups;
- }
-
- const Tile* get(uint32_t id) const
- {
- //FIXME: Commenting out tiles in sprites.strf makes tiles.size() fail - it's being set to the first tile commented out.
- assert(id < tiles.size());
- Tile* tile = tiles[id];
- if(!tile) {
- log_warning << "Invalid tile: " << id << std::endl;
- return tiles[0];
- }
-
- if(tile->images.size() == 0 && tile->imagespecs.size() != 0)
- tile->load_images(tiles_path);
-
- return tile;
- }
-
- uint32_t get_max_tileid() const
- {
- return tiles.size();
- }
-
- int get_default_width() const
- {
- return 32;
- }
-
- int get_default_height() const
- {
- return 32;
- }
-};
-
-extern TileManager* tile_manager;
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#include <config.h>
-
-#include <math.h>
-#include "timer.hpp"
-
-float game_time = 0;
-float real_time = 0;
-
-Timer::Timer()
- : period(0), cycle_start(0), cyclic(false)
-{
-}
-
-Timer::~Timer()
-{
-}
-
-void
-Timer::start(float period, bool cyclic)
-{
- this->period = period;
- this->cyclic = cyclic;
- cycle_start = game_time;
-}
-
-bool
-Timer::check()
-{
- if(period == 0)
- return false;
-
- if(game_time - cycle_start >= period) {
- if(cyclic) {
- cycle_start = game_time - fmodf(game_time - cycle_start, period);
- } else {
- period = 0;
- }
- return true;
- }
-
- return false;
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#ifndef __SUPERTUX_TIMER_H__
-#define __SUPERTUX_TIMER_H__
-
-extern float game_time;
-extern float real_time;
-
-/**
- * Simple timer designed to be used in the update functions of objects
- */
-class Timer
-{
-public:
- Timer();
- ~Timer();
-
- /** start the timer with the given period (in seconds).
- * If cyclic=true then the timer willl be reset after each period.
- * Set period to zero if you want to disable the timer.
- */
- void start(float period, bool cyclic = false);
- /** returns true if a period (or more) passed since start call or last
- * successfull check
- */
- bool check();
- /** stop the timer */
- void stop()
- { start(0); }
-
- /** returns the period of the timer or 0 if it isn't started */
- float get_period() const
- { return period; }
- float get_timeleft() const
- { return period - (game_time - cycle_start); }
- float get_timegone() const
- { return game_time - cycle_start; }
- bool started() const
- { return period != 0 && get_timeleft() > 0; }
-
-private:
- float period;
- float cycle_start;
- bool cyclic;
-};
-
-#endif
+++ /dev/null
-/*
- findlocale-0.46.tar.gz from http://icculus.org/~aspirin/findlocale/
-
-Copyright (C) 2004 Adam D. Moss (the "Author"). All Rights Reserved.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is fur-
-nished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FIT-
-NESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
-IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CON-
-NECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-Except as contained in this notice, the name of the Author of the
-Software shall not be used in advertising or otherwise to promote the sale,
-use or other dealings in this Software without prior written authorization
-from the Author.
-
-*/
-#include <config.h>
-
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-
-#ifdef WIN32
-#include <windows.h>
-#include <winnt.h>
-#endif
-
-#ifdef MACOSX
-#include <CoreFoundation/CoreFoundation.h>
-#endif
-
-#include "findlocale.hpp"
-
-static int
-is_lcchar(const int c) {
- return isalnum(c);
-}
-
-static void
-lang_country_variant_from_envstring(const char *str,
- char **lang,
- char **country,
- char **variant) {
- int end = 0;
- int start;
-
- /* get lang, if any */
- start = end;
- while (is_lcchar(str[end])) {
- ++end;
- }
- if (start != end) {
- int i;
- int len = end - start;
- char *s = (char*) malloc(len + 1);
- for (i=0; i<len; ++i) {
- s[i] = tolower(str[start + i]);
- }
- s[i] = '\0';
- *lang = s;
- } else {
- *lang = NULL;
- }
-
- if (str[end] && str[end]!=':') { /* not at end of str */
- ++end;
- }
-
- /* get country, if any */
- start = end;
- while (is_lcchar(str[end])) {
- ++end;
- }
- if (start != end) {
- int i;
- int len = end - start;
- char *s = (char*) malloc(len + 1);
- for (i=0; i<len; ++i) {
- s[i] = toupper(str[start + i]);
- }
- s[i] = '\0';
- *country = s;
- } else {
- *country = NULL;
- }
-
- if (str[end] && str[end]!=':') { /* not at end of str */
- ++end;
- }
-
- /* get variant, if any */
- start = end;
- while (str[end] && str[end]!=':') {
- ++end;
- }
- if (start != end) {
- int i;
- int len = end - start;
- char *s = (char*) malloc(len + 1);
- for (i=0; i<len; ++i) {
- s[i] = str[start + i];
- }
- s[i] = '\0';
- *variant = s;
- } else {
- *variant = NULL;
- }
-}
-
-
-static int
-accumulate_locstring(const char *str, FL_Locale *l) {
- char *lang = NULL;
- char *country = NULL;
- char *variant = NULL;
- if (str) {
- lang_country_variant_from_envstring(str, &lang, &country, &variant);
- if (lang) {
- l->lang = lang;
- l->country = country;
- l->variant = variant;
- return 1;
- }
- }
- free(lang); free(country); free(variant);
- return 0;
-}
-
-
-#ifndef WIN32
-static int
-accumulate_env(const char *name, FL_Locale *l) {
- char *env;
- char *lang = NULL;
- char *country = NULL;
- char *variant = NULL;
- env = getenv(name);
- if (env) {
- return accumulate_locstring(env, l);
- }
- free(lang); free(country); free(variant);
- return 0;
-}
-#endif
-
-static void
-canonise_fl(FL_Locale *l) {
- /* this function fixes some common locale-specifying mistakes */
- /* en_UK -> en_GB */
- if (l->lang && 0 == strcmp(l->lang, "en")) {
- if (l->country && 0 == strcmp(l->country, "UK")) {
- free((void*)l->country);
- l->country = strdup("GB");
- }
- }
- /* ja_JA -> ja_JP */
- if (l->lang && 0 == strcmp(l->lang, "ja")) {
- if (l->country && 0 == strcmp(l->country, "JA")) {
- free((void*)l->country);
- l->country = strdup("JP");
- }
- }
-}
-
-
-#ifdef WIN32
-#include <stdio.h>
-#define ML(pn,sn) MAKELANGID(LANG_##pn, SUBLANG_##pn##_##sn)
-#define MLN(pn) MAKELANGID(LANG_##pn, SUBLANG_DEFAULT)
-#define RML(pn,sn) MAKELANGID(LANG_##pn, SUBLANG_##sn)
-typedef struct {
- LANGID id;
- char* code;
-} IDToCode;
-static const IDToCode both_to_code[] = {
- {ML(ENGLISH,US), "en_US.ISO_8859-1"},
- {ML(ENGLISH,CAN), "en_CA"}, /* english / canadian */
- {ML(ENGLISH,UK), "en_GB"},
- {ML(ENGLISH,EIRE), "en_IE"},
- {ML(ENGLISH,AUS), "en_AU"},
- {MLN(GERMAN), "de_DE"},
- {MLN(SPANISH), "es_ES"},
- {ML(SPANISH,MEXICAN), "es_MX"},
- {MLN(FRENCH), "fr_FR"},
- {ML(FRENCH,CANADIAN), "fr_CA"},
- {ML(FRENCH,BELGIAN), "fr_BE"}, /* ? */
- {ML(DUTCH,BELGIAN), "nl_BE"}, /* ? */
- {ML(PORTUGUESE,BRAZILIAN), "pt_BR"},
- {MLN(PORTUGUESE), "pt_PT"},
- {MLN(SWEDISH), "sv_SE"},
- {ML(CHINESE,HONGKONG), "zh_HK"},
- /* these are machine-generated and not yet verified */
- {RML(AFRIKAANS,DEFAULT), "af_ZA"},
- {RML(ALBANIAN,DEFAULT), "sq_AL"},
- {RML(ARABIC,ARABIC_ALGERIA), "ar_DZ"},
- {RML(ARABIC,ARABIC_BAHRAIN), "ar_BH"},
- {RML(ARABIC,ARABIC_EGYPT), "ar_EG"},
- {RML(ARABIC,ARABIC_IRAQ), "ar_IQ"},
- {RML(ARABIC,ARABIC_JORDAN), "ar_JO"},
- {RML(ARABIC,ARABIC_KUWAIT), "ar_KW"},
- {RML(ARABIC,ARABIC_LEBANON), "ar_LB"},
- {RML(ARABIC,ARABIC_LIBYA), "ar_LY"},
- {RML(ARABIC,ARABIC_MOROCCO), "ar_MA"},
- {RML(ARABIC,ARABIC_OMAN), "ar_OM"},
- {RML(ARABIC,ARABIC_QATAR), "ar_QA"},
- {RML(ARABIC,ARABIC_SAUDI_ARABIA), "ar_SA"},
- {RML(ARABIC,ARABIC_SYRIA), "ar_SY"},
- {RML(ARABIC,ARABIC_TUNISIA), "ar_TN"},
- {RML(ARABIC,ARABIC_UAE), "ar_AE"},
- {RML(ARABIC,ARABIC_YEMEN), "ar_YE"},
- {RML(ARMENIAN,DEFAULT), "hy_AM"},
- {RML(AZERI,AZERI_CYRILLIC), "az_AZ"},
- {RML(AZERI,AZERI_LATIN), "az_AZ"},
- {RML(BASQUE,DEFAULT), "eu_ES"},
- {RML(BELARUSIAN,DEFAULT), "be_BY"},
-/*{RML(BRETON,DEFAULT), "br_FR"},*/
- {RML(BULGARIAN,DEFAULT), "bg_BG"},
- {RML(CATALAN,DEFAULT), "ca_ES"},
- {RML(CHINESE,CHINESE_HONGKONG), "zh_HK"},
- {RML(CHINESE,CHINESE_MACAU), "zh_MO"},
- {RML(CHINESE,CHINESE_SIMPLIFIED), "zh_CN"},
- {RML(CHINESE,CHINESE_SINGAPORE), "zh_SG"},
- {RML(CHINESE,CHINESE_TRADITIONAL), "zh_TW"},
-/*{RML(CORNISH,DEFAULT), "kw_GB"},*/
- {RML(CZECH,DEFAULT), "cs_CZ"},
- {RML(DANISH,DEFAULT), "da_DK"},
- {RML(DUTCH,DUTCH), "nl_NL"},
- {RML(DUTCH,DUTCH_BELGIAN), "nl_BE"},
-/*{RML(DUTCH,DUTCH_SURINAM), "nl_SR"},*/
- {RML(ENGLISH,ENGLISH_AUS), "en_AU"},
- {RML(ENGLISH,ENGLISH_BELIZE), "en_BZ"},
- {RML(ENGLISH,ENGLISH_CAN), "en_CA"},
- {RML(ENGLISH,ENGLISH_CARIBBEAN), "en_CB"},
- {RML(ENGLISH,ENGLISH_EIRE), "en_IE"},
- {RML(ENGLISH,ENGLISH_JAMAICA), "en_JM"},
- {RML(ENGLISH,ENGLISH_NZ), "en_NZ"},
- {RML(ENGLISH,ENGLISH_PHILIPPINES), "en_PH"},
- {RML(ENGLISH,ENGLISH_SOUTH_AFRICA), "en_ZA"},
- {RML(ENGLISH,ENGLISH_TRINIDAD), "en_TT"},
- {RML(ENGLISH,ENGLISH_UK), "en_GB"},
- {RML(ENGLISH,ENGLISH_US), "en_US"},
- {RML(ENGLISH,ENGLISH_ZIMBABWE), "en_ZW"},
-/*{RML(ESPERANTO,DEFAULT), "eo_"},*/
- {RML(ESTONIAN,DEFAULT), "et_EE"},
- {RML(FAEROESE,DEFAULT), "fo_FO"},
- {RML(FARSI,DEFAULT), "fa_IR"},
- {RML(FINNISH,DEFAULT), "fi_FI"},
- {RML(FRENCH,FRENCH), "fr_FR"},
- {RML(FRENCH,FRENCH_BELGIAN), "fr_BE"},
- {RML(FRENCH,FRENCH_CANADIAN), "fr_CA"},
- {RML(FRENCH,FRENCH_LUXEMBOURG), "fr_LU"},
- {RML(FRENCH,FRENCH_MONACO), "fr_MC"},
- {RML(FRENCH,FRENCH_SWISS), "fr_CH"},
-/*{RML(GAELIC,GAELIC), "ga_IE"},*/
-/*{RML(GAELIC,GAELIC_MANX), "gv_GB"},*/
-/*{RML(GAELIC,GAELIC_SCOTTISH), "gd_GB"},*/
-/*{RML(GALICIAN,DEFAULT), "gl_ES"},*/
- {RML(GEORGIAN,DEFAULT), "ka_GE"},
- {RML(GERMAN,GERMAN), "de_DE"},
- {RML(GERMAN,GERMAN_AUSTRIAN), "de_AT"},
- {RML(GERMAN,GERMAN_LIECHTENSTEIN), "de_LI"},
- {RML(GERMAN,GERMAN_LUXEMBOURG), "de_LU"},
- {RML(GERMAN,GERMAN_SWISS), "de_CH"},
- {RML(GREEK,DEFAULT), "el_GR"},
- {RML(GUJARATI,DEFAULT), "gu_IN"},
- {RML(HEBREW,DEFAULT), "he_IL"},
- {RML(HINDI,DEFAULT), "hi_IN"},
- {RML(HUNGARIAN,DEFAULT), "hu_HU"},
- {RML(ICELANDIC,DEFAULT), "is_IS"},
- {RML(INDONESIAN,DEFAULT), "id_ID"},
- {RML(ITALIAN,ITALIAN), "it_IT"},
- {RML(ITALIAN,ITALIAN_SWISS), "it_CH"},
- {RML(JAPANESE,DEFAULT), "ja_JP"},
- {RML(KANNADA,DEFAULT), "kn_IN"},
- {RML(KAZAK,DEFAULT), "kk_KZ"},
- {RML(KONKANI,DEFAULT), "kok_IN"},
- {RML(KOREAN,KOREAN), "ko_KR"},
-/*{RML(KYRGYZ,DEFAULT), "ky_KG"},*/
- {RML(LATVIAN,DEFAULT), "lv_LV"},
- {RML(LITHUANIAN,LITHUANIAN), "lt_LT"},
- {RML(MACEDONIAN,DEFAULT), "mk_MK"},
- {RML(MALAY,MALAY_BRUNEI_DARUSSALAM), "ms_BN"},
- {RML(MALAY,MALAY_MALAYSIA), "ms_MY"},
- {RML(MARATHI,DEFAULT), "mr_IN"},
-/*{RML(MONGOLIAN,DEFAULT), "mn_MN"},*/
- {RML(NORWEGIAN,NORWEGIAN_BOKMAL), "nb_NO"},
- {RML(NORWEGIAN,NORWEGIAN_NYNORSK), "nn_NO"},
- {RML(POLISH,DEFAULT), "pl_PL"},
- {RML(PORTUGUESE,PORTUGUESE), "pt_PT"},
- {RML(PORTUGUESE,PORTUGUESE_BRAZILIAN), "pt_BR"},
- {RML(PUNJABI,DEFAULT), "pa_IN"},
- {RML(ROMANIAN,DEFAULT), "ro_RO"},
- {RML(RUSSIAN,DEFAULT), "ru_RU"},
- {RML(SANSKRIT,DEFAULT), "sa_IN"},
- {RML(SERBIAN,DEFAULT), "hr_HR"},
- {RML(SERBIAN,SERBIAN_CYRILLIC), "sr_SP"},
- {RML(SERBIAN,SERBIAN_LATIN), "sr_SP"},
- {RML(SLOVAK,DEFAULT), "sk_SK"},
- {RML(SLOVENIAN,DEFAULT), "sl_SI"},
- {RML(SPANISH,SPANISH), "es_ES"},
- {RML(SPANISH,SPANISH_ARGENTINA), "es_AR"},
- {RML(SPANISH,SPANISH_BOLIVIA), "es_BO"},
- {RML(SPANISH,SPANISH_CHILE), "es_CL"},
- {RML(SPANISH,SPANISH_COLOMBIA), "es_CO"},
- {RML(SPANISH,SPANISH_COSTA_RICA), "es_CR"},
- {RML(SPANISH,SPANISH_DOMINICAN_REPUBLIC), "es_DO"},
- {RML(SPANISH,SPANISH_ECUADOR), "es_EC"},
- {RML(SPANISH,SPANISH_EL_SALVADOR), "es_SV"},
- {RML(SPANISH,SPANISH_GUATEMALA), "es_GT"},
- {RML(SPANISH,SPANISH_HONDURAS), "es_HN"},
- {RML(SPANISH,SPANISH_MEXICAN), "es_MX"},
- {RML(SPANISH,SPANISH_MODERN), "es_ES"},
- {RML(SPANISH,SPANISH_NICARAGUA), "es_NI"},
- {RML(SPANISH,SPANISH_PANAMA), "es_PA"},
- {RML(SPANISH,SPANISH_PARAGUAY), "es_PY"},
- {RML(SPANISH,SPANISH_PERU), "es_PE"},
- {RML(SPANISH,SPANISH_PUERTO_RICO), "es_PR"},
- {RML(SPANISH,SPANISH_URUGUAY), "es_UY"},
- {RML(SPANISH,SPANISH_VENEZUELA), "es_VE"},
- {RML(SWAHILI,DEFAULT), "sw_KE"},
- {RML(SWEDISH,SWEDISH), "sv_SE"},
- {RML(SWEDISH,SWEDISH_FINLAND), "sv_FI"},
-/*{RML(SYRIAC,DEFAULT), "syr_SY"},*/
- {RML(TAMIL,DEFAULT), "ta_IN"},
- {RML(TATAR,DEFAULT), "tt_TA"},
- {RML(TELUGU,DEFAULT), "te_IN"},
- {RML(THAI,DEFAULT), "th_TH"},
- {RML(TURKISH,DEFAULT), "tr_TR"},
- {RML(UKRAINIAN,DEFAULT), "uk_UA"},
- {RML(URDU,URDU_PAKISTAN), "ur_PK"},
- {RML(UZBEK,UZBEK_CYRILLIC), "uz_UZ"},
- {RML(UZBEK,UZBEK_LATIN), "uz_UZ"},
- {RML(VIETNAMESE,DEFAULT), "vi_VN"},
-/*{RML(WALON,DEFAULT), "wa_BE"},*/
-/*{RML(WELSH,DEFAULT), "cy_GB"},*/
-};
-static const IDToCode primary_to_code[] = {
- {LANG_AFRIKAANS, "af"},
- {LANG_ARABIC, "ar"},
- {LANG_AZERI, "az"},
- {LANG_BULGARIAN, "bg"},
-/*{LANG_BRETON, "br"},*/
- {LANG_BELARUSIAN, "by"},
- {LANG_CATALAN, "ca"},
- {LANG_CZECH, "cs"},
-/*{LANG_WELSH, "cy"},*/
- {LANG_DANISH, "da"},
- {LANG_GERMAN, "de"},
- {LANG_GREEK, "el"},
- {LANG_ENGLISH, "en"},
-/*{LANG_ESPERANTO, "eo"},*/
- {LANG_SPANISH, "es"},
- {LANG_ESTONIAN, "et"},
- {LANG_BASQUE, "eu"},
- {LANG_FARSI, "fa"},
- {LANG_FINNISH, "fi"},
- {LANG_FAEROESE, "fo"},
- {LANG_FRENCH, "fr"},
-/*{LANG_GAELIC, "ga"},*/
-/*{LANG_GALICIAN, "gl"},*/
- {LANG_GUJARATI, "gu"},
- {LANG_HEBREW, "he"},
- {LANG_HINDI, "hi"},
- {LANG_SERBIAN, "hr"},
- {LANG_HUNGARIAN, "hu"},
- {LANG_ARMENIAN, "hy"},
- {LANG_INDONESIAN, "id"},
- {LANG_ITALIAN, "it"},
- {LANG_JAPANESE, "ja"},
- {LANG_GEORGIAN, "ka"},
- {LANG_KAZAK, "kk"},
- {LANG_KANNADA, "kn"},
- {LANG_KOREAN, "ko"},
-/*{LANG_KYRGYZ, "ky"},*/
- {LANG_LITHUANIAN, "lt"},
- {LANG_LATVIAN, "lv"},
- {LANG_MACEDONIAN, "mk"},
-/*{LANG_MONGOLIAN, "mn"},*/
- {LANG_MARATHI, "mr"},
- {LANG_MALAY, "ms"},
- {LANG_NORWEGIAN, "nb"},
- {LANG_DUTCH, "nl"},
- {LANG_NORWEGIAN, "nn"},
- {LANG_NORWEGIAN, "no"},/* unofficial? */
- {LANG_PUNJABI, "pa"},
- {LANG_POLISH, "pl"},
- {LANG_PORTUGUESE, "pt"},
- {LANG_ROMANIAN, "ro"},
- {LANG_RUSSIAN, "ru"},
- {LANG_SLOVAK, "sk"},
- {LANG_SLOVENIAN, "sl"},
- {LANG_ALBANIAN, "sq"},
- {LANG_SERBIAN, "sr"},
- {LANG_SWEDISH, "sv"},
- {LANG_SWAHILI, "sw"},
- {LANG_TAMIL, "ta"},
- {LANG_THAI, "th"},
- {LANG_TURKISH, "tr"},
- {LANG_TATAR, "tt"},
- {LANG_UKRAINIAN, "uk"},
- {LANG_URDU, "ur"},
- {LANG_UZBEK, "uz"},
- {LANG_VIETNAMESE, "vi"},
-/*{LANG_WALON, "wa"},*/
- {LANG_CHINESE, "zh"},
-};
-static int num_primary_to_code =
- sizeof(primary_to_code) / sizeof(*primary_to_code);
-static int num_both_to_code =
- sizeof(both_to_code) / sizeof(*both_to_code);
-
-static const int
-lcid_to_fl(LCID lcid,
- FL_Locale *rtn) {
- LANGID langid = LANGIDFROMLCID(lcid);
- LANGID primary_lang = PRIMARYLANGID(langid);
-#if 0
- LANGID sub_lang = SUBLANGID(langid);
-#endif
- int i;
- /* try to find an exact primary/sublanguage combo that we know about */
- for (i=0; i<num_both_to_code; ++i) {
- if (both_to_code[i].id == langid) {
- accumulate_locstring(both_to_code[i].code, rtn);
- return 1;
- }
- }
- /* fallback to just checking the primary language id */
- for (i=0; i<num_primary_to_code; ++i) {
- if (primary_to_code[i].id == primary_lang) {
- accumulate_locstring(primary_to_code[i].code, rtn);
- return 1;
- }
- }
- return 0;
-}
-#endif
-
-
-FL_Success
-FL_FindLocale(FL_Locale **locale, FL_Domain /*domain*/) {
- FL_Success success = FL_FAILED;
- FL_Locale *rtn = (FL_Locale*) malloc(sizeof(FL_Locale));
- rtn->lang = NULL;
- rtn->country = NULL;
- rtn->variant = NULL;
-
-#ifdef WIN32
- /* win32 >= mswindows95 */
- {
- LCID lcid = GetThreadLocale();
- if (lcid_to_fl(lcid, rtn)) {
- success = FL_CONFIDENT;
- }
- if (success == FL_FAILED) {
- /* assume US English on mswindows systems unless we know otherwise */
- if (accumulate_locstring("en_US.ISO_8859-1", rtn)) {
- success = FL_DEFAULT_GUESS;
- }
- }
- }
-#else
- /* assume unixoid */
- {
-#ifdef MACOSX
- CFIndex sz;
- CFArrayRef languages;
- CFStringRef uxstylelangs;
- char *uxsl;
-
- /* get the languages from the user's presets */
- languages = (CFArrayRef)CFPreferencesCopyValue(CFSTR("AppleLanguages"),
- kCFPreferencesAnyApplication, kCFPreferencesCurrentUser,
- kCFPreferencesAnyHost);
-
- /* join the returned string array into a string separated by colons */
- uxstylelangs = CFStringCreateByCombiningStrings(kCFAllocatorDefault,
- languages, CFSTR(":"));
-
- /* convert this string into a C string */
- sz = CFStringGetLength(uxstylelangs) + 1;
- uxsl = (char*)malloc(sz);
- CFStringGetCString(uxstylelangs, uxsl, sz, kCFStringEncodingISOLatin1);
-
- /* add it to the list */
- if (accumulate_locstring(uxsl, rtn)) {
- success = FL_CONFIDENT;
- }
- /* continue the UNIX method */
-#endif
- /* examples: */
- /* sv_SE.ISO_8859-1 */
- /* fr_FR.ISO8859-1 */
- /* no_NO_NB */
- /* no_NO_NY */
- /* no_NO */
- /* de_DE */
- /* try the various vars in decreasing order of authority */
- if (accumulate_env("LC_ALL", rtn) ||
- accumulate_env("LC_MESSAGES", rtn) ||
- accumulate_env("LANG", rtn) ||
- accumulate_env("LANGUAGE", rtn)) {
- success = FL_CONFIDENT;
- }
- if (success == FL_FAILED) {
- /* assume US English on unixoid systems unless we know otherwise */
- if (accumulate_locstring("en_US.ISO_8859-1", rtn)) {
- success = FL_DEFAULT_GUESS;
- }
- }
- }
-#endif
-
- if (success != FL_FAILED) {
- canonise_fl(rtn);
- }
-
- *locale = rtn;
- return success;
-}
-
-
-void
-FL_FreeLocale(FL_Locale **locale) {
- if (locale) {
- FL_Locale *l = *locale;
- if (l) {
- if (l->lang) {
- free((void*)l->lang);
- }
- if (l->country) {
- free((void*)l->country);
- }
- if (l->variant) {
- free((void*)l->variant);
- }
- free(l);
- *locale = NULL;
- }
- }
-}
+++ /dev/null
-/*
- findlocale-0.46.tar.gz from http://icculus.org/~aspirin/findlocale/
-
-Copyright (C) 2004 Adam D. Moss (the "Author"). All Rights Reserved.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is fur-
-nished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FIT-
-NESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
-IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CON-
-NECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-Except as contained in this notice, the name of the Author of the
-Software shall not be used in advertising or otherwise to promote the sale,
-use or other dealings in this Software without prior written authorization
-from the Author.
-
-*/
-
-#ifndef __findlocale_h_
-#define __findlocale_h_
-
-typedef const char* FL_Lang;
-typedef const char* FL_Country;
-typedef const char* FL_Variant;
-
-typedef struct {
- FL_Lang lang;
- FL_Country country;
- FL_Variant variant;
-} FL_Locale;
-
-typedef enum {
- /* for some reason we failed to even guess: this should never happen */
- FL_FAILED = 0,
- /* couldn't query locale -- returning a guess (almost always English) */
- FL_DEFAULT_GUESS = 1,
- /* the returned locale type was found by successfully asking the system */
- FL_CONFIDENT = 2
-} FL_Success;
-
-typedef enum {
- FL_MESSAGES = 0
-} FL_Domain;
-
-/* This allocates/fills in a FL_Locale structure with pointers to
- strings (which should be treated as static), or NULL for inappropriate /
- undetected fields. */
-FL_Success FL_FindLocale(FL_Locale **locale, FL_Domain domain);
-/* This should be used to free the struct written by FL_FindLocale */
-void FL_FreeLocale(FL_Locale **locale);
-
-#endif /*__findlocale_h_*/
+++ /dev/null
-// $Id$
-//
-// TinyGetText
-// Copyright (C) 2006 Ingo Ruhnke <grumbel@gmx.de>
-//
-// 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.
-
-#include <config.h>
-
-#include <sys/types.h>
-#include <fstream>
-#include <iostream>
-#include <algorithm>
-#include <ctype.h>
-#include <errno.h>
-
-#include "SDL.h"
-
-#include "tinygettext.hpp"
-#include "log.hpp"
-#include "physfs/physfs_stream.hpp"
-#include "log.hpp"
-#include "findlocale.hpp"
-
-//#define TRANSLATION_DEBUG
-
-namespace TinyGetText {
-
-/** Convert \a which is in \a from_charset to \a to_charset and return it */
-std::string convert(const std::string& text,
- const std::string& from_charset,
- const std::string& to_charset)
-{
- if (from_charset == to_charset)
- return text;
-
- char *in = new char[text.length() + 1];
- strcpy(in, text.c_str());
- char *out = SDL_iconv_string(to_charset.c_str(), from_charset.c_str(), in, text.length() + 1);
- delete[] in;
- if(out == 0)
- {
- log_warning << "Error: conversion from " << from_charset << " to " << to_charset << " failed" << std::endl;
- return "";
- }
- std::string ret(out);
- SDL_free(out);
- return ret;
-#if 0
- iconv_t cd = SDL_iconv_open(to_charset.c_str(), from_charset.c_str());
-
- size_t in_len = text.length();
- size_t out_len = text.length()*3; // FIXME: cross fingers that this is enough
-
- char* out_orig = new char[out_len];
- char* in_orig = new char[in_len+1];
- strcpy(in_orig, text.c_str());
-
- char* out = out_orig;
- ICONV_CONST char* in = in_orig;
- size_t out_len_temp = out_len; // iconv is counting down the bytes it has
- // written from this...
-
- size_t retval = SDL_iconv(cd, &in, &in_len, &out, &out_len_temp);
- out_len -= out_len_temp; // see above
- if (retval == (size_t) -1)
- {
- log_warning << strerror(errno) << std::endl;
- log_warning << "Error: conversion from " << from_charset << " to " << to_charset << " went wrong: " << retval << std::endl;
- return "";
- }
- SDL_iconv_close(cd);
-
- std::string ret(out_orig, out_len);
- delete[] out_orig;
- delete[] in_orig;
- return ret;
-#endif
-}
-
-bool has_suffix(const std::string& lhs, const std::string rhs)
-{
- if (lhs.length() < rhs.length())
- return false;
- else
- return lhs.compare(lhs.length() - rhs.length(), rhs.length(), rhs) == 0;
-}
-
-bool has_prefix(const std::string& lhs, const std::string rhs)
-{
- if (lhs.length() < rhs.length())
- return false;
- else
- return lhs.compare(0, rhs.length(), rhs) == 0;
-}
-
-int plural1(int ) { return 0; }
-int plural2_1(int n) { return (n != 1); }
-int plural2_2(int n) { return (n > 1); }
-int plural3_lv(int n) { return (n%10==1 && n%100!=11 ? 0 : n != 0 ? 1 : 2); }
-int plural3_ga(int n) { return n==1 ? 0 : n==2 ? 1 : 2; }
-int plural3_lt(int n) { return (n%10==1 && n%100!=11 ? 0 : n%10>=2 && (n%100<10 || n%100>=20) ? 1 : 2); }
-int plural3_1(int n) { return (n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2); }
-int plural3_sk(int n) { return (n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2; }
-int plural3_pl(int n) { return (n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2); }
-int plural3_sl(int n) { return (n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n%100==4 ? 2 : 3); }
-
-/** Language Definitions */
-//*{
-LanguageDef lang_hu("hu", "Hungarian", 1, plural1); // "nplurals=1; plural=0;"
-LanguageDef lang_ja("ja", "Japanese", 1, plural1); // "nplurals=1; plural=0;"
-LanguageDef lang_ko("ko", "Korean", 1, plural1); // "nplurals=1; plural=0;"
-LanguageDef lang_tr("tr", "Turkish", 1, plural1); // "nplurals=1; plural=0;"
-LanguageDef lang_da("da", "Danish", 2, plural2_1); // "nplurals=2; plural=(n != 1);"
-LanguageDef lang_nl("nl", "Dutch", 2, plural2_1); // "nplurals=2; plural=(n != 1);"
-LanguageDef lang_en("en", "English", 2, plural2_1); // "nplurals=2; plural=(n != 1);"
-LanguageDef lang_fo("fo", "Faroese", 2, plural2_1); // "nplurals=2; plural=(n != 1);"
-LanguageDef lang_de("de", "German", 2, plural2_1); // "nplurals=2; plural=(n != 1);"
-LanguageDef lang_nb("nb", "Norwegian Bokmal", 2, plural2_1); // "nplurals=2; plural=(n != 1);"
-LanguageDef lang_no("no", "Norwegian", 2, plural2_1); // "nplurals=2; plural=(n != 1);"
-LanguageDef lang_nn("nn", "Norwegian Nynorsk", 2, plural2_1); // "nplurals=2; plural=(n != 1);"
-LanguageDef lang_sv("sv", "Swedish", 2, plural2_1); // "nplurals=2; plural=(n != 1);"
-LanguageDef lang_et("et", "Estonian", 2, plural2_1); // "nplurals=2; plural=(n != 1);"
-LanguageDef lang_fi("fi", "Finnish", 2, plural2_1); // "nplurals=2; plural=(n != 1);"
-LanguageDef lang_el("el", "Greek", 2, plural2_1); // "nplurals=2; plural=(n != 1);"
-LanguageDef lang_he("he", "Hebrew", 2, plural2_1); // "nplurals=2; plural=(n != 1);"
-LanguageDef lang_it("it", "Italian", 2, plural2_1); // "nplurals=2; plural=(n != 1);"
-LanguageDef lang_pt("pt", "Portuguese", 2, plural2_1); // "nplurals=2; plural=(n != 1);"
-LanguageDef lang_es("es", "Spanish", 2, plural2_1); // "nplurals=2; plural=(n != 1);"
-LanguageDef lang_eo("eo", "Esperanto", 2, plural2_1); // "nplurals=2; plural=(n != 1);"
-LanguageDef lang_fr("fr", "French", 2, plural2_2); // "nplurals=2; plural=(n > 1);"
-LanguageDef lang_pt_BR("pt_BR", "Brazilian", 2, plural2_2); // "nplurals=2; plural=(n > 1);"
-LanguageDef lang_lv("lv", "Latvian", 3, plural3_lv); // "nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n != 0 ? 1 : 2);"
-LanguageDef lang_ga("ga", "Irish", 3, plural3_ga); // "nplurals=3; plural=n==1 ? 0 : n==2 ? 1 : 2;"
-LanguageDef lang_lt("lt", "Lithuanian", 3, plural3_lt); // "nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && (n%100<10 || n%100>=20) ? 1 : 2);"
-LanguageDef lang_hr("hr", "Croatian", 3, plural3_1); // "nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);"
-LanguageDef lang_cs("cs", "Czech", 3, plural3_1); // "nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);"
-LanguageDef lang_ru("ru", "Russian", 3, plural3_1); // "nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);"
-LanguageDef lang_uk("uk", "Ukrainian", 3, plural3_1); // "nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);"
-LanguageDef lang_sk("sk", "Slovak", 3, plural3_sk); // "nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;"
-LanguageDef lang_pl("pl", "Polish", 3, plural3_pl); // "nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);
-LanguageDef lang_sl("sl", "Slovenian", 3, plural3_sl); // "nplurals=4; plural=(n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n%100==4 ? 2 : 3);"
-//*}
-
-LanguageDef&
-get_language_def(const std::string& name)
-{
- if (name == "hu") return lang_hu;
- else if (name == "ja") return lang_ja;
- else if (name == "ko") return lang_ko;
- else if (name == "tr") return lang_tr;
- else if (name == "da") return lang_da;
- else if (name == "nl") return lang_nl;
- else if (name == "en") return lang_en;
- else if (name == "fo") return lang_fo;
- else if (name == "de") return lang_de;
- else if (name == "nb") return lang_nb;
- else if (name == "no") return lang_no;
- else if (name == "nn") return lang_nn;
- else if (name == "sv") return lang_sv;
- else if (name == "et") return lang_et;
- else if (name == "fi") return lang_fi;
- else if (name == "el") return lang_el;
- else if (name == "he") return lang_he;
- else if (name == "it") return lang_it;
- else if (name == "pt") return lang_pt;
- else if (name == "es") return lang_es;
- else if (name == "eo") return lang_eo;
- else if (name == "fr") return lang_fr;
- else if (name == "pt_BR") return lang_pt_BR;
- else if (name == "lv") return lang_lv;
- else if (name == "ga") return lang_ga;
- else if (name == "lt") return lang_lt;
- else if (name == "hr") return lang_hr;
- else if (name == "cs") return lang_cs;
- else if (name == "ru") return lang_ru;
- else if (name == "uk") return lang_uk;
- else if (name == "sk") return lang_sk;
- else if (name == "pl") return lang_pl;
- else if (name == "sl") return lang_sl;
- else return lang_en;
-}
-
-DictionaryManager::DictionaryManager()
- : current_dict(&empty_dict)
-{
- parseLocaleAliases();
- // Environment variable SUPERTUX_LANG overrides language settings.
- const char* lang = getenv( "SUPERTUX_LANG" );
- if( lang ){
- set_language( lang );
- return;
- }
- // use findlocale to setup language
- FL_Locale *locale;
- FL_FindLocale( &locale, FL_MESSAGES );
- if(locale->lang) {
- if (locale->country) {
- set_language( std::string(locale->lang)+"_"+std::string(locale->country) );
- } else {
- set_language( std::string(locale->lang) );
- }
- }
- FL_FreeLocale( &locale );
-}
-
-void
-DictionaryManager::parseLocaleAliases()
-{
- // try to parse language alias list
- std::ifstream in("/usr/share/locale/locale.alias");
-
- char c = ' ';
- while(in.good() && !in.eof()) {
- while(isspace(c) && !in.eof())
- in.get(c);
-
- if(c == '#') { // skip comments
- while(c != '\n' && !in.eof())
- in.get(c);
- continue;
- }
-
- std::string alias;
- while(!isspace(c) && !in.eof()) {
- alias += c;
- in.get(c);
- }
- while(isspace(c) && !in.eof())
- in.get(c);
- std::string language;
- while(!isspace(c) && !in.eof()) {
- language += c;
- in.get(c);
- }
-
- if(in.eof())
- break;
- set_language_alias(alias, language);
- }
-}
-
-Dictionary&
-DictionaryManager::get_dictionary(const std::string& spec)
-{
-
- //log_debug << "Dictionary for language \"" << spec << "\" requested" << std::endl;
-
- std::string lang = get_language_from_spec(spec);
-
- //log_debug << "...normalized as \"" << lang << "\"" << std::endl;
-
- Dictionaries::iterator i = dictionaries.find(get_language_from_spec(lang));
- if (i != dictionaries.end())
- {
- return i->second;
- }
- else // Dictionary for languages lang isn't loaded, so we load it
- {
- //log_debug << "get_dictionary: " << lang << std::endl;
- Dictionary& dict = dictionaries[lang];
-
- dict.set_language(get_language_def(lang));
- if(charset != "")
- dict.set_charset(charset);
-
- for (SearchPath::iterator p = search_path.begin(); p != search_path.end(); ++p)
- {
- char** files = PHYSFS_enumerateFiles(p->c_str());
- if(!files)
- {
- log_warning << "Error: enumerateFiles() failed on " << *p << std::endl;
- }
- else
- {
- for(const char* const* filename = files;
- *filename != 0; filename++) {
-
- // check if filename matches requested language
- std::string fname = std::string(*filename);
- std::string load_from_file = "";
- if(fname == lang + ".po") {
- load_from_file = fname;
- } else {
- std::string::size_type s = lang.find("_");
- if(s != std::string::npos) {
- std::string lang_short = std::string(lang, 0, s);
- if (fname == lang_short + ".po") {
- load_from_file = lang_short;
- }
- }
- }
-
- // if it matched, load dictionary
- if (load_from_file != "") {
- //log_debug << "Loading dictionary for language \"" << lang << "\" from \"" << filename << "\"" << std::endl;
- std::string pofile = *p + "/" + *filename;
- try {
- IFileStream in(pofile);
- read_po_file(dict, in);
- } catch(std::exception& e) {
- log_warning << "Error: Failure file opening: " << pofile << std::endl;
- log_warning << e.what() << "" << std::endl;
- }
- }
-
- }
- PHYSFS_freeList(files);
- }
- }
-
- return dict;
- }
-}
-
-std::set<std::string>
-DictionaryManager::get_languages()
-{
- std::set<std::string> languages;
-
- for (SearchPath::iterator p = search_path.begin(); p != search_path.end(); ++p)
- {
- char** files = PHYSFS_enumerateFiles(p->c_str());
- if (!files)
- {
- log_warning << "Error: opendir() failed on " << *p << std::endl;
- }
- else
- {
- for(const char* const* file = files; *file != 0; file++) {
- if(has_suffix(*file, ".po")) {
- std::string filename = *file;
- languages.insert(filename.substr(0, filename.length()-3));
- }
- }
- PHYSFS_freeList(files);
- }
- }
- return languages;
-}
-
-void
-DictionaryManager::set_language(const std::string& lang)
-{
- //log_debug << "set_language \"" << lang << "\"" << std::endl;
- language = get_language_from_spec(lang);
- //log_debug << "==> \"" << language << "\"" << std::endl;
- current_dict = & (get_dictionary(language));
-}
-
-const std::string&
-DictionaryManager::get_language() const
-{
- return language;
-}
-
-void
-DictionaryManager::set_charset(const std::string& charset)
-{
- dictionaries.clear(); // changing charset invalidates cache
- this->charset = charset;
- set_language(language);
-}
-
-void
-DictionaryManager::set_language_alias(const std::string& alias,
- const std::string& language)
-{
- language_aliases.insert(std::make_pair(alias, language));
-}
-
-std::string
-DictionaryManager::get_language_from_spec(const std::string& spec)
-{
- std::string lang = spec;
- Aliases::iterator i = language_aliases.find(lang);
- if(i != language_aliases.end()) {
- lang = i->second;
- }
-
- std::string::size_type s = lang.find(".");
- if(s != std::string::npos) {
- lang = std::string(lang, 0, s);
- }
-
- s = lang.find("_");
- if(s == std::string::npos) {
- std::string lang_big = lang;
- std::transform (lang_big.begin(), lang_big.end(), lang_big.begin(), toupper);
- lang += "_" + lang_big;
- }
-
- return lang;
-
-}
-
-void
-DictionaryManager::add_directory(const std::string& pathname)
-{
- dictionaries.clear(); // adding directories invalidates cache
- search_path.push_back(pathname);
- set_language(language);
-}
-
-//---------------------------------------------------------------------------
-
-Dictionary::Dictionary(const LanguageDef& language_, const std::string& charset_)
- : language(language_), charset(charset_)
-{
-}
-
-Dictionary::Dictionary()
- : language(lang_en)
-{
-}
-
-std::string
-Dictionary::get_charset() const
-{
- return charset;
-}
-
-void
-Dictionary::set_charset(const std::string& charset_)
-{
- charset = charset_;
-}
-
-void
-Dictionary::set_language(const LanguageDef& lang)
-{
- language = lang;
-}
-
-std::string
-Dictionary::translate(const std::string& msgid, const std::string& msgid2, int num)
-{
- PluralEntries::iterator i = plural_entries.find(msgid);
- std::map<int, std::string>& msgstrs = i->second;
-
- if (i != plural_entries.end() && !msgstrs.empty())
- {
- int g = language.plural(num);
- std::map<int, std::string>::iterator j = msgstrs.find(g);
- if (j != msgstrs.end())
- {
- return j->second;
- }
- else
- {
- // Return the first translation, in case we can't translate the specific number
- return msgstrs.begin()->second;
- }
- }
- else
- {
-#ifdef TRANSLATION_DEBUG
- log_warning << "Couldn't translate: " << msgid << std::endl;
- log_warning << "Candidates: " << std::endl;
- for (PluralEntries::iterator i = plural_entries.begin(); i != plural_entries.end(); ++i)
- log_debug << "'" << i->first << "'" << std::endl;
-#endif
-
- if (plural2_1(num)) // default to english rules
- return msgid2;
- else
- return msgid;
- }
-}
-
-const char*
-Dictionary::translate(const char* msgid)
-{
- Entries::iterator i = entries.find(msgid);
- if (i != entries.end() && !i->second.empty())
- {
- return i->second.c_str();
- }
- else
- {
-#ifdef TRANSLATION_DBEUG
- log_warning << "Couldn't translate: " << msgid << std::endl;
-#endif
- return msgid;
- }
-}
-
-std::string
-Dictionary::translate(const std::string& msgid)
-{
- Entries::iterator i = entries.find(msgid);
- if (i != entries.end() && !i->second.empty())
- {
- return i->second;
- }
- else
- {
-#ifdef TRANSLATION_DBEUG
- log_warning << "Couldn't translate: " << msgid << std::endl;
-#endif
- return msgid;
- }
-}
-
-void
-Dictionary::add_translation(const std::string& msgid, const std::string& ,
- const std::map<int, std::string>& msgstrs)
-{
- // Do we need msgid2 for anything? its after all supplied to the
- // translate call, so we just throw it away
- plural_entries[msgid] = msgstrs;
-}
-
-void
-Dictionary::add_translation(const std::string& msgid, const std::string& msgstr)
-{
- entries[msgid] = msgstr;
-}
-
-class POFileReader
-{
-private:
- struct Token
- {
- std::string keyword;
- std::string content;
- };
-
- Dictionary& dict;
-
- std::string from_charset;
- std::string to_charset;
-
- std::string current_msgid;
- std::string current_msgid_plural;
- std::map<int, std::string> msgstr_plural;
-
- int line_num;
-
- enum { WANT_MSGID, WANT_MSGSTR, WANT_MSGSTR_PLURAL, WANT_MSGID_PLURAL } state;
-
-public:
- POFileReader(std::istream& in, Dictionary& dict_)
- : dict(dict_)
- {
- state = WANT_MSGID;
- line_num = 0;
- char c = in.get();
- if(c == (char) 0xef) { // skip UTF-8 intro that some texteditors produce
- in.get();
- in.get();
- } else {
- in.unget();
- }
- tokenize_po(in);
- }
-
- void parse_header(const std::string& header)
- {
- // Seperate the header in lines
- typedef std::vector<std::string> Lines;
- Lines lines;
-
- std::string::size_type start = 0;
- for(std::string::size_type i = 0; i < header.length(); ++i)
- {
- if (header[i] == '\n')
- {
- lines.push_back(header.substr(start, i - start));
- start = i+1;
- }
- }
-
- for(Lines::iterator i = lines.begin(); i != lines.end(); ++i)
- {
- if (has_prefix(*i, "Content-Type: text/plain; charset=")) {
- from_charset = i->substr(strlen("Content-Type: text/plain; charset="));
- }
- }
-
- if (from_charset.empty() || from_charset == "CHARSET")
- {
- log_warning << "Error: Charset not specified for .po, fallback to ISO-8859-1" << std::endl;
- from_charset = "ISO-8859-1";
- }
-
- to_charset = dict.get_charset();
- if (to_charset.empty())
- { // No charset requested from the dict, use utf-8
- to_charset = "utf-8";
- dict.set_charset(from_charset);
- }
- }
-
- void add_token(const Token& token)
- {
- switch(state)
- {
- case WANT_MSGID:
- if (token.keyword == "msgid")
- {
- current_msgid = token.content;
- state = WANT_MSGID_PLURAL;
- }
- else if (token.keyword.empty())
- {
- //log_warning << "Got EOF, everything looks ok." << std::endl;
- }
- else
- {
- log_warning << "tinygettext: expected 'msgid' keyword, got " << token.keyword << " at line " << line_num << std::endl;
- }
- break;
-
- case WANT_MSGID_PLURAL:
- if (token.keyword == "msgid_plural")
- {
- current_msgid_plural = token.content;
- state = WANT_MSGSTR_PLURAL;
- }
- else
- {
- state = WANT_MSGSTR;
- add_token(token);
- }
- break;
-
- case WANT_MSGSTR:
- if (token.keyword == "msgstr")
- {
- if (current_msgid == "")
- { // .po Header is hidden in the msgid with the empty string
- parse_header(token.content);
- }
- else
- {
- dict.add_translation(current_msgid, convert(token.content, from_charset, to_charset));
- }
- state = WANT_MSGID;
- }
- else
- {
- log_warning << "tinygettext: expected 'msgstr' keyword, got " << token.keyword << " at line " << line_num << std::endl;
- }
- break;
-
- case WANT_MSGSTR_PLURAL:
- if (has_prefix(token.keyword, "msgstr["))
- {
- int num;
- if (sscanf(token.keyword.c_str(), "msgstr[%d]", &num) != 1)
- {
- log_warning << "Error: Couldn't parse: " << token.keyword << std::endl;
- }
- else
- {
- msgstr_plural[num] = convert(token.content, from_charset, to_charset);
- }
- }
- else
- {
- dict.add_translation(current_msgid, current_msgid_plural, msgstr_plural);
-
- state = WANT_MSGID;
- add_token(token);
- }
- break;
- }
- }
-
- inline int getchar(std::istream& in)
- {
- int c = in.get();
- if (c == '\n')
- line_num += 1;
- return c;
- }
-
- void tokenize_po(std::istream& in)
- {
- enum State { READ_KEYWORD,
- READ_CONTENT,
- READ_CONTENT_IN_STRING,
- SKIP_COMMENT };
-
- State state = READ_KEYWORD;
- int c;
- Token token;
-
- while((c = getchar(in)) != EOF)
- {
- //log_debug << "Lexing char: " << char(c) << " " << state << std::endl;
- switch(state)
- {
- case READ_KEYWORD:
- if (c == '#')
- {
- state = SKIP_COMMENT;
- }
- else
- {
- // Read a new token
- token = Token();
-
- do { // Read keyword
- token.keyword += c;
- } while((c = getchar(in)) != EOF && !isspace(c));
- in.unget();
-
- state = READ_CONTENT;
- }
- break;
-
- case READ_CONTENT:
- while((c = getchar(in)) != EOF)
- {
- if (c == '"') {
- // Found start of content
- state = READ_CONTENT_IN_STRING;
- break;
- } else if (isspace(c)) {
- // skip
- } else { // Read something that may be a keyword
- in.unget();
- state = READ_KEYWORD;
- add_token(token);
- break;
- }
- }
- break;
-
- case READ_CONTENT_IN_STRING:
- if (c == '\\') {
- c = getchar(in);
- if (c != EOF)
- {
- if (c == 'n') token.content += '\n';
- else if (c == 't') token.content += '\t';
- else if (c == 'r') token.content += '\r';
- else if (c == '"') token.content += '"';
- else if (c == '\\') token.content += '\\';
- else
- {
- log_warning << "Unhandled escape character: " << char(c) << std::endl;
- }
- }
- else
- {
- log_warning << "Unterminated string" << std::endl;
- }
- } else if (c == '"') { // Content string is terminated
- state = READ_CONTENT;
- } else {
- token.content += c;
- }
- break;
-
- case SKIP_COMMENT:
- if (c == '\n')
- state = READ_KEYWORD;
- break;
- }
- }
- add_token(token);
- }
-};
-
-void read_po_file(Dictionary& dict_, std::istream& in)
-{
- POFileReader reader(in, dict_);
-}
-
-} // namespace TinyGetText
-
-/* EOF */
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef HEADER_TINYGETTEXT_H
-#define HEADER_TINYGETTEXT_H
-
-#include <map>
-#include <vector>
-#include <set>
-#include <string>
-
-namespace TinyGetText {
-
-typedef int (*PluralFunc)(int n);
-
-struct LanguageDef {
- const char* code;
- const char* name;
- int nplural;
- PluralFunc plural;
-
- LanguageDef(const char* code_, const char* name_, int nplural_, PluralFunc plural_)
- : code(code_), name(name_), nplural(nplural_), plural(plural_)
- {}
-};
-
-/** A simple dictionary class that mimics gettext() behaviour. Each
- Dictionary only works for a single language, for managing multiple
- languages and .po files at once use the DictionaryManager. */
-class Dictionary
-{
-private:
- typedef std::map<std::string, std::string> Entries;
- Entries entries;
-
- typedef std::map<std::string, std::map<int, std::string> > PluralEntries;
- PluralEntries plural_entries;
-
- LanguageDef language;
- std::string charset;
-public:
- /** */
- Dictionary(const LanguageDef& language_, const std::string& charset = "");
-
- Dictionary();
-
- /** Return the charset used for this dictionary */
- std::string get_charset() const;
-
- /** Set a charset for this dictionary, this will NOT convert stuff,
- it is for information only, you have to convert stuff yourself
- when you add it with \a add_translation() */
- void set_charset(const std::string& charset);
-
- /** Set the language that is used for this dictionary, this is
- mainly needed to evaluate plural forms */
- void set_language(const LanguageDef& lang);
-
- /** Translate the string \a msgid to its correct plural form, based
- on the number of items given by \a num. \a msgid2 is \a msgid in
- plural form. */
- std::string translate(const std::string& msgid, const std::string& msgid2, int num);
-
- /** Translate the string \a msgid. */
- std::string translate(const std::string& msgid);
- /** Translate the string \a msgid. */
- const char* translate(const char* msgid);
-
- /** Add a translation from \a msgid to \a msgstr to the dictionary,
- where \a msgid is the singular form of the message, msgid2 the
- plural form and msgstrs a table of translations. The right
- translation will be calculated based on the \a num argument to
- translate(). */
- void add_translation(const std::string& msgid, const std::string& msgid2,
- const std::map<int, std::string>& msgstrs);
-
- /** Add a translation from \a msgid to \a msgstr to the
- dictionary */
- void add_translation(const std::string& msgid, const std::string& msgstr);
-};
-
-/** Manager class for dictionaries, you give it a bunch of directories
- with .po files and it will then automatically load the right file
- on demand depending on which language was set. */
-class DictionaryManager
-{
-private:
- typedef std::map<std::string, Dictionary> Dictionaries;
- Dictionaries dictionaries;
- typedef std::vector<std::string> SearchPath;
- SearchPath search_path;
- typedef std::map<std::string, std::string> Aliases;
- Aliases language_aliases;
- std::string charset;
- std::string language;
- Dictionary* current_dict;
- Dictionary empty_dict;
-
-public:
- DictionaryManager();
-
- /** Return the currently active dictionary, if none is set, an empty
- dictionary is returned. */
- Dictionary& get_dictionary()
- { return *current_dict; }
-
- /** Get dictionary for lang */
- Dictionary& get_dictionary(const std::string& langspec);
-
- /** Set a language based on a four? letter country code */
- void set_language(const std::string& langspec);
-
- /** returns the (normalized) country code of the currently used language */
- const std::string& get_language() const;
-
- /** Set a charset that will be set on the returned dictionaries */
- void set_charset(const std::string& charset);
-
- /** Define an alias for a language */
- void set_language_alias(const std::string& alias, const std::string& lang);
-
- /** Add a directory to the search path for dictionaries */
- void add_directory(const std::string& pathname);
-
- /** Return a set of the available languages in their country code */
- std::set<std::string> get_languages();
-
-private:
- void parseLocaleAliases();
- /// returns the language part in a language spec (like de_DE.UTF-8 -> de)
- std::string get_language_from_spec(const std::string& spec);
-};
-
-/** Read the content of the .po file given as \a in into the
- dictionary given as \a dict */
-void read_po_file(Dictionary& dict, std::istream& in);
-LanguageDef& get_language_def(const std::string& name);
-
-} // namespace TinyGetText
-
-#endif
-
-/* EOF */
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2004 Tobias Glaesser <tobi.web@gmx.de>
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#include <config.h>
-
-#include <iostream>
-#include <sstream>
-#include <stdexcept>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <math.h>
-#include <errno.h>
-#include <unistd.h>
-#include <SDL.h>
-#include <SDL_image.h>
-#include <physfs.h>
-
-#include "title.hpp"
-#include "mainloop.hpp"
-#include "video/drawing_context.hpp"
-#include "video/surface.hpp"
-#include "audio/sound_manager.hpp"
-#include "gui/menu.hpp"
-#include "timer.hpp"
-#include "lisp/lisp.hpp"
-#include "lisp/parser.hpp"
-#include "level.hpp"
-#include "world.hpp"
-#include "game_session.hpp"
-#include "worldmap/worldmap.hpp"
-#include "player_status.hpp"
-#include "tile.hpp"
-#include "sector.hpp"
-#include "object/tilemap.hpp"
-#include "object/camera.hpp"
-#include "object/player.hpp"
-#include "resources.hpp"
-#include "gettext.hpp"
-#include "textscroller.hpp"
-#include "fadeout.hpp"
-#include "file_system.hpp"
-#include "control/joystickkeyboardcontroller.hpp"
-#include "control/codecontroller.hpp"
-#include "main.hpp"
-#include "log.hpp"
-#include "options_menu.hpp"
-#include "console.hpp"
-#include "random_generator.hpp"
-#include "addon_manager.hpp"
-
-enum MainMenuIDs {
- MNID_STARTGAME,
- MNID_LEVELS_CONTRIB,
- MNID_ADDONS,
- MNID_OPTIONMENU,
- MNID_LEVELEDITOR,
- MNID_CREDITS,
- MNID_QUITMAINMENU
-};
-
-void
-TitleScreen::update_load_game_menu()
-{
- load_game_menu.reset(new Menu());
-
- load_game_menu->add_label(_("Start Game"));
- load_game_menu->add_hl();
- for(int i = 1; i <= 5; ++i) {
- load_game_menu->add_entry(i, get_slotinfo(i));
- }
- load_game_menu->add_hl();
- load_game_menu->add_back(_("Back"));
-}
-
-void
-TitleScreen::free_contrib_menu()
-{
- for(std::vector<World*>::iterator i = contrib_worlds.begin();
- i != contrib_worlds.end(); ++i)
- delete *i;
-
- contrib_worlds.clear();
-}
-
-void
-TitleScreen::generate_contrib_menu()
-{
- /** Generating contrib levels list by making use of Level Subset */
- std::vector<std::string> level_worlds;
- char** files = PHYSFS_enumerateFiles("levels/");
- for(const char* const* filename = files; *filename != 0; ++filename) {
- std::string filepath = std::string("levels/") + *filename;
- if(PHYSFS_isDirectory(filepath.c_str()))
- level_worlds.push_back(filepath);
- }
- PHYSFS_freeList(files);
-
- free_contrib_menu();
- contrib_menu.reset(new Menu());
-
- contrib_menu->add_label(_("Contrib Levels"));
- contrib_menu->add_hl();
-
- int i = 0;
- for (std::vector<std::string>::iterator it = level_worlds.begin();
- it != level_worlds.end(); ++it) {
- try {
- std::auto_ptr<World> world (new World());
- world->load(*it + "/info");
- if(world->hide_from_contribs) {
- continue;
- }
- contrib_menu->add_entry(i++, world->title);
- contrib_worlds.push_back(world.release());
- } catch(std::exception& e) {
-#ifdef DEBUG
- log_warning << "Couldn't parse levelset info for '" << *it << "': " << e.what() << std::endl;
-#endif
- }
- }
-
- contrib_menu->add_hl();
- contrib_menu->add_back(_("Back"));
-}
-
-std::string
-TitleScreen::get_level_name(const std::string& filename)
-{
- try {
- lisp::Parser parser;
- const lisp::Lisp* root = parser.parse(filename);
-
- const lisp::Lisp* level = root->get_lisp("supertux-level");
- if(!level)
- return "";
-
- std::string name;
- level->get("name", name);
- return name;
- } catch(std::exception& e) {
- log_warning << "Problem getting name of '" << filename << "': "
- << e.what() << std::endl;
- return "";
- }
-}
-
-void
-TitleScreen::check_levels_contrib_menu()
-{
- int index = contrib_menu->check();
- if (index == -1)
- return;
-
- current_world = contrib_worlds[index];
-
- if(!current_world->is_levelset) {
- update_load_game_menu();
- Menu::push_current(load_game_menu.get());
- } else {
- contrib_world_menu.reset(new Menu());
-
- contrib_world_menu->add_label(current_world->title);
- contrib_world_menu->add_hl();
-
- for (unsigned int i = 0; i < current_world->get_num_levels(); ++i)
- {
- /** get level's title */
- std::string filename = current_world->get_level_filename(i);
- std::string title = get_level_name(filename);
- contrib_world_menu->add_entry(i, title);
- }
-
- contrib_world_menu->add_hl();
- contrib_world_menu->add_back(_("Back"));
-
- Menu::push_current(contrib_world_menu.get());
- }
-}
-
-void
-TitleScreen::check_contrib_world_menu()
-{
- int index = contrib_world_menu->check();
- if (index != -1) {
- if (contrib_world_menu->get_item_by_id(index).kind == MN_ACTION) {
- sound_manager->stop_music();
- GameSession* session =
- new GameSession(current_world->get_level_filename(index));
- main_loop->push_screen(session);
- }
- }
-}
-
-namespace {
- bool generate_addons_menu_sorter(const Addon& a1, const Addon& a2)
- {
- return a1.title < a2.title;
- }
-
- const int ADDON_LIST_START_ID = 10;
-}
-
-void
-TitleScreen::generate_addons_menu()
-{
- AddonManager& adm = AddonManager::get_instance();
-
- // refresh list of installed addons
- installed_addons = adm.get_installed_addons();
-
- // build new Add-on list
- addons.clear();
-
- // add installed addons to list
- addons.insert(addons.end(), installed_addons.begin(), installed_addons.end());
-
- // add available addons to list
- addons.insert(addons.end(), available_addons.begin(), available_addons.end());
-
- // sort list
- std::sort(addons.begin(), addons.end(), generate_addons_menu_sorter);
-
- // remove available addons that are already installed
- std::vector<Addon>::iterator it2 = addons.begin();
- while (it2 != addons.end()) {
- Addon addon = *it2;
- if (addon.isInstalled) {
- bool restart = false;
- for (std::vector<Addon>::iterator it = addons.begin(); it != addons.end(); ++it) {
- Addon addon2 = *it;
- if ((addon2.equals(addon)) && (!addon2.isInstalled)) {
- addons.erase(it);
- restart = true;
- break;
- }
- }
- if (restart) {
- it2 = addons.begin();
- continue;
- }
- }
- it2++;
- }
-
- // (re)generate menu
- free_addons_menu();
- addons_menu.reset(new Menu());
-
- addons_menu->add_label(_("Add-ons"));
- addons_menu->add_hl();
-
-#ifdef HAVE_LIBCURL
- addons_menu->add_entry(0, std::string(_("Check Online")));
-#else
- addons_menu->add_deactive(0, std::string(_("Check Online (disabled)")));
-#endif
-
- //addons_menu->add_hl();
-
- for (unsigned int i = 0; i < addons.size(); i++) {
- Addon addon = addons[i];
- std::string text = "";
- if (addon.kind != "") text += addon.kind + " ";
- text += std::string("\"") + addon.title + "\"";
- if (addon.author != "") text += " by \"" + addon.author + "\"";
- addons_menu->add_toggle(ADDON_LIST_START_ID + i, text, addon.isInstalled);
- }
-
- addons_menu->add_hl();
- addons_menu->add_back(_("Back"));
-}
-
-void
-TitleScreen::check_addons_menu()
-{
- int index = addons_menu->check();
- if (index == -1) return;
-
- // check if "Check Online" was chosen
- if (index == 0) {
- try {
- available_addons = AddonManager::get_instance().get_available_addons();
- generate_addons_menu();
- Menu::set_current(addons_menu.get());
- addons_menu->set_active_item(index);
- }
- catch (std::runtime_error e) {
- log_warning << "Check for available Add-ons failed: " << e.what() << std::endl;
- }
- return;
- }
-
- // if one of the Addons listed was chosen, take appropriate action
- if ((index >= ADDON_LIST_START_ID) && (index < ADDON_LIST_START_ID) + addons.size()) {
- Addon addon = addons[index - ADDON_LIST_START_ID];
- if (!addon.isInstalled) {
- try {
- addon.install();
- //generate_addons_menu();
- //Menu::set_current(addons_menu.get());
- //addons_menu->set_active_item(index);
- Menu::set_current(0);
- }
- catch (std::runtime_error e) {
- log_warning << "Installation of Add-on failed: " << e.what() << std::endl;
- }
- } else {
- try {
- addon.remove();
- //generate_addons_menu();
- //Menu::set_current(addons_menu.get());
- //addons_menu->set_active_item(index);
- Menu::set_current(0);
- }
- catch (std::runtime_error e) {
- log_warning << "Removal of Add-on failed: " << e.what() << std::endl;
- }
- }
- }
-
-}
-
-void
-TitleScreen::free_addons_menu()
-{
-}
-
-void
-TitleScreen::make_tux_jump()
-{
- static bool jumpWasReleased = true;
- Sector* sector = titlesession->get_current_sector();
- Player* tux = sector->player;
-
- controller->update();
- controller->press(Controller::RIGHT);
-
- // Check if we should press the jump button
- Rect lookahead = tux->get_bbox();
- lookahead.p2.x += 96;
- bool pathBlocked = !sector->is_free_of_statics(lookahead);
- if ((pathBlocked && jumpWasReleased) || !tux->on_ground()) {
- controller->press(Controller::JUMP);
- jumpWasReleased = false;
- } else {
- jumpWasReleased = true;
- }
-
- // Wrap around at the end of the level back to the beginnig
- if(sector->get_width() - 320 < tux->get_pos().x) {
- sector->activate("main");
- sector->camera->reset(tux->get_pos());
- }
-}
-
-TitleScreen::TitleScreen()
-{
- controller.reset(new CodeController());
- titlesession.reset(new GameSession("levels/misc/menu.stl"));
-
- Player* player = titlesession->get_current_sector()->player;
- player->set_controller(controller.get());
- player->set_speedlimit(230); //MAX_WALK_XM
-
- generate_main_menu();
-}
-
-void
-TitleScreen::generate_main_menu()
-{
- main_menu.reset(new Menu());
- main_menu->set_pos(SCREEN_WIDTH/2, SCREEN_HEIGHT/2 + 35);
- main_menu->add_entry(MNID_STARTGAME, _("Start Game"));
- main_menu->add_entry(MNID_LEVELS_CONTRIB, _("Contrib Levels"));
- main_menu->add_entry(MNID_ADDONS, _("Add-ons"));
- main_menu->add_submenu(_("Options"), get_options_menu());
- main_menu->add_entry(MNID_CREDITS, _("Credits"));
- main_menu->add_entry(MNID_QUITMAINMENU, _("Quit"));
-}
-
-TitleScreen::~TitleScreen()
-{
-}
-
-void
-TitleScreen::setup()
-{
- player_status->reset();
-
- Sector* sector = titlesession->get_current_sector();
- if(Sector::current() != sector) {
- sector->play_music(LEVEL_MUSIC);
- sector->activate(sector->player->get_pos());
- }
-
- Menu::set_current(main_menu.get());
-}
-
-void
-TitleScreen::leave()
-{
- Sector* sector = titlesession->get_current_sector();
- sector->deactivate();
- Menu::set_current(NULL);
-}
-
-void
-TitleScreen::draw(DrawingContext& context)
-{
- Sector* sector = titlesession->get_current_sector();
- sector->draw(context);
-
- context.draw_text(white_small_text, "SuperTux " PACKAGE_VERSION "\n",
- Vector(5, SCREEN_HEIGHT - 50), ALIGN_LEFT, LAYER_FOREGROUND1);
- context.draw_text(white_small_text,
- _(
-"Copyright (c) 2007 SuperTux Devel Team\n"
-"This game comes with ABSOLUTELY NO WARRANTY. This is free software, and you are welcome to\n"
-"redistribute it under certain conditions; see the file COPYING for details.\n"
-),
- Vector(5, SCREEN_HEIGHT - 50 + white_small_text->get_height() + 5),
- ALIGN_LEFT, LAYER_FOREGROUND1);
-}
-
-void
-TitleScreen::update(float elapsed_time)
-{
- main_loop->set_speed(0.6f);
- Sector* sector = titlesession->get_current_sector();
- sector->update(elapsed_time);
-
- make_tux_jump();
-
- Menu* menu = Menu::current();
- if(menu) {
- menu->update();
-
- if(menu == main_menu.get()) {
- switch (main_menu->check()) {
- case MNID_STARTGAME:
- // Start Game, ie. goto the slots menu
- if(main_world.get() == NULL) {
- main_world.reset(new World());
- main_world->load("levels/world1/info");
- }
- current_world = main_world.get();
- update_load_game_menu();
- Menu::push_current(load_game_menu.get());
- break;
- case MNID_LEVELS_CONTRIB:
- // Contrib Menu
- generate_contrib_menu();
- Menu::push_current(contrib_menu.get());
- break;
- case MNID_ADDONS:
- // Add-ons Menu
- generate_addons_menu();
- Menu::push_current(addons_menu.get());
- break;
- case MNID_CREDITS:
- main_loop->push_screen(new TextScroller("credits.txt"),
- new FadeOut(0.5));
- break;
- case MNID_QUITMAINMENU:
- main_loop->quit(new FadeOut(0.25));
- sound_manager->stop_music(0.25);
- break;
- }
- } else if(menu == load_game_menu.get()) {
- /*
- if(event.key.keysym.sym == SDLK_DELETE) {
- int slot = menu->get_active_item_id();
- std::stringstream stream;
- stream << slot;
- std::string str = _("Are you sure you want to delete slot") + stream.str() + "?";
-
- if(confirm_dialog(bkg_title, str.c_str())) {
- str = "save/slot" + stream.str() + ".stsg";
- log_debug << "Removing: " << str << std::endl;
- PHYSFS_delete(str.c_str());
- }
-
- update_load_save_game_menu(load_game_menu);
- Menu::set_current(main_menu.get());
- }*/
- process_load_game_menu();
- } else if(menu == contrib_menu.get()) {
- check_levels_contrib_menu();
- } else if(menu == addons_menu.get()) {
- check_addons_menu();
- } else if (menu == contrib_world_menu.get()) {
- check_contrib_world_menu();
- }
- }
-
- // reopen menu of user closed it (so that the app doesn't close when user
- // accidently hit ESC)
- if(Menu::current() == 0) {
- generate_main_menu();
- Menu::set_current(main_menu.get());
- }
-}
-
-std::string
-TitleScreen::get_slotinfo(int slot)
-{
- std::string tmp;
- std::string title;
-
- std::string basename = current_world->get_basedir();
- basename = basename.substr(0, basename.length()-1);
- std::string worlddirname = FileSystem::basename(basename);
- std::ostringstream stream;
- stream << "save/" << worlddirname << "_" << slot << ".stsg";
- std::string slotfile = stream.str();
-
- try {
- lisp::Parser parser;
- const lisp::Lisp* root = parser.parse(slotfile);
-
- const lisp::Lisp* savegame = root->get_lisp("supertux-savegame");
- if(!savegame)
- throw std::runtime_error("file is not a supertux-savegame.");
-
- savegame->get("title", title);
- } catch(std::exception& ) {
- std::ostringstream slottitle;
- slottitle << _("Slot") << " " << slot << " - " << _("Free");
- return slottitle.str();
- }
-
- std::ostringstream slottitle;
- slottitle << _("Slot") << " " << slot << " - " << title;
- return slottitle.str();
-}
-
-bool
-TitleScreen::process_load_game_menu()
-{
- int slot = load_game_menu->check();
-
- if(slot == -1)
- return false;
-
- if(load_game_menu->get_item_by_id(slot).kind != MN_ACTION)
- return false;
-
- std::string basename = current_world->get_basedir();
- basename = basename.substr(0, basename.length()-1);
- std::string worlddirname = FileSystem::basename(basename);
- std::stringstream stream;
- stream << "save/" << worlddirname << "_" << slot << ".stsg";
- std::string slotfile = stream.str();
-
- try {
- current_world->set_savegame_filename(slotfile);
- current_world->run();
- } catch(std::exception& e) {
- log_fatal << "Couldn't start world: " << e.what() << std::endl;
- }
-
- return true;
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2004 Tobias Glaesser <tobi.web@gmx.de>
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#ifndef SUPERTUX_TITLE_H
-#define SUPERTUX_TITLE_H
-
-#include <memory>
-#include <vector>
-#include "screen.hpp"
-#include "game_session.hpp"
-#include "addon.hpp"
-
-class Menu;
-class World;
-class CodeController;
-
-class TitleScreen : public Screen
-{
-public:
- TitleScreen();
- virtual ~TitleScreen();
-
- virtual void setup();
- virtual void leave();
-
- virtual void draw(DrawingContext& context);
-
- virtual void update(float elapsed_time);
-
-private:
- std::string get_slotinfo(int slot);
- std::string get_level_name(const std::string& levelfile);
- bool process_load_game_menu();
- void make_tux_jump();
- void update_load_game_menu();
- void generate_main_menu();
- void generate_contrib_menu();
- void check_levels_contrib_menu();
- void check_contrib_world_menu();
- void free_contrib_menu();
- void generate_addons_menu();
- void check_addons_menu();
- void free_addons_menu();
-
- std::auto_ptr<Menu> main_menu;
- std::auto_ptr<Menu> load_game_menu;
- std::auto_ptr<Menu> contrib_menu;
- std::auto_ptr<Menu> contrib_world_menu;
- std::auto_ptr<World> main_world;
- std::vector<World*> contrib_worlds;
- std::auto_ptr<Menu> addons_menu;
- std::vector<Addon> addons; /**< shown list of Add-ons */
- std::vector<Addon> available_addons; /**< list of downloadable Add-ons */
- std::vector<Addon> installed_addons; /**< list of currently installed Add-ons */
- World* current_world;
-
- std::auto_ptr<CodeController> controller;
- std::auto_ptr<GameSession> titlesession;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux - Climbable area
-// Copyright (C) 2007 Christoph Sommer <christoph.sommer@2007.expires.deltadevelopment.de>
-//
-// 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.
-
-#include <config.h>
-
-#include "climbable.hpp"
-#include "game_session.hpp"
-#include "lisp/lisp.hpp"
-#include "lisp/writer.hpp"
-#include "object_factory.hpp"
-#include "main.hpp"
-#include "sector.hpp"
-#include "level.hpp"
-#include "gettext.hpp"
-#include "object/tilemap.hpp"
-
-namespace {
- const float GRACE_DX = 8; // how far off may the player's bounding-box be x-wise
- const float GRACE_DY = 8; // how far off may the player's bounding-box be y-wise
- const float ACTIVATE_TRY_FOR = 1; // how long to try correcting mis-alignment of player and climbable before giving up
- const float POSITION_FIX_AX = 50; // x-wise acceleration applied to player when trying to align player and Climbable
- const float POSITION_FIX_AY = 50; // y-wise acceleration applied to player when trying to align player and Climbable
-}
-
-Climbable::Climbable(const lisp::Lisp& reader)
- : climbed_by(0)
-{
- reader.get("x", bbox.p1.x);
- reader.get("y", bbox.p1.y);
- float w = 32, h = 32;
- reader.get("width", w);
- reader.get("height", h);
- bbox.set_size(w, h);
-}
-
-Climbable::Climbable(const Rect& area)
- : climbed_by(0)
-{
- bbox = area;
-}
-
-Climbable::~Climbable()
-{
- if (climbed_by) {
- climbed_by->stop_climbing(*this);
- climbed_by = 0;
- }
-}
-
-void
-Climbable::write(lisp::Writer& writer)
-{
- writer.start_list("climbable");
-
- writer.write_float("x", bbox.p1.x);
- writer.write_float("y", bbox.p1.y);
- writer.write_float("width", bbox.get_width());
- writer.write_float("height", bbox.get_height());
-
- writer.end_list("climbable");
-}
-
-void
-Climbable::update(float /*elapsed_time*/)
-{
- if (!climbed_by) return;
-
- if (!may_climb(*climbed_by)) {
- climbed_by->stop_climbing(*this);
- climbed_by = 0;
- }
-}
-
-void
-Climbable::draw(DrawingContext& context)
-{
- if (climbed_by) {
- context.push_transform();
- context.set_translation(Vector(0, 0));
- Vector pos = Vector(0, SCREEN_HEIGHT/2 - gold_text->get_height()/2);
- context.draw_center_text(gold_text, "Up we go...", pos, LAYER_GUI);
- context.pop_transform();
- }
-}
-
-void
-Climbable::event(Player& player, EventType type)
-{
- if ((type == EVENT_ACTIVATE) || (activate_try_timer.started())) {
- if (may_climb(player)) {
- climbed_by = &player;
- player.start_climbing(*this);
- activate_try_timer.stop();
- } else {
- if (type == EVENT_ACTIVATE) activate_try_timer.start(ACTIVATE_TRY_FOR);
- if (player.get_bbox().p1.x < get_bbox().p1.x - GRACE_DX) player.add_velocity(Vector(POSITION_FIX_AX,0));
- if (player.get_bbox().p2.x > get_bbox().p2.x + GRACE_DX) player.add_velocity(Vector(-POSITION_FIX_AX,0));
- if (player.get_bbox().p1.y < get_bbox().p1.y - GRACE_DY) player.add_velocity(Vector(0,POSITION_FIX_AY));
- if (player.get_bbox().p2.y > get_bbox().p2.y + GRACE_DY) player.add_velocity(Vector(0,-POSITION_FIX_AY));
- }
- }
- if(type == EVENT_LOSETOUCH) {
- player.stop_climbing(*this);
- climbed_by = 0;
- }
-}
-
-bool
-Climbable::may_climb(Player& player)
-{
- if (player.get_bbox().p1.x < get_bbox().p1.x - GRACE_DX) return false;
- if (player.get_bbox().p2.x > get_bbox().p2.x + GRACE_DX) return false;
- if (player.get_bbox().p1.y < get_bbox().p1.y - GRACE_DY) return false;
- if (player.get_bbox().p2.y > get_bbox().p2.y + GRACE_DY) return false;
- return true;
-}
-
-IMPLEMENT_FACTORY(Climbable, "climbable");
-
+++ /dev/null
-// $Id$
-//
-// SuperTux - Climbable area
-// Copyright (C) 2007 Christoph Sommer <christoph.sommer@2007.expires.deltadevelopment.de>
-//
-// 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.
-
-#ifndef __CLIMBABLE_H__
-#define __CLIMBABLE_H__
-
-#include "trigger_base.hpp"
-#include "serializable.hpp"
-#include "resources.hpp"
-#include "video/drawing_context.hpp"
-#include "timer.hpp"
-#include "object/player.hpp"
-
-class Climbable : public TriggerBase, public Serializable
-{
-public:
- Climbable(const lisp::Lisp& reader);
- Climbable(const Rect& area);
- ~Climbable();
-
- void write(lisp::Writer& writer);
- void event(Player& player, EventType type);
- void update(float elapsed_time);
- void draw(DrawingContext& context);
-
- /**
- * returns true if the player is within bounds of the Climbable
- */
- bool may_climb(Player& player);
-
-protected:
- Player* climbed_by; /**< set to player who's currently climbing us, null if nobody is */
- Timer activate_try_timer; /**< try to correct mis-alignment while this timer runs */
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include "door.hpp"
-#include "game_session.hpp"
-#include "resources.hpp"
-#include "object_factory.hpp"
-#include "sprite/sprite.hpp"
-#include "sprite/sprite_manager.hpp"
-#include "video/drawing_context.hpp"
-#include "lisp/lisp.hpp"
-#include "lisp/writer.hpp"
-#include "audio/sound_manager.hpp"
-
-Door::Door(const lisp::Lisp& reader)
- : state(CLOSED)
-{
- reader.get("x", bbox.p1.x);
- reader.get("y", bbox.p1.y);
- reader.get("sector", target_sector);
- reader.get("spawnpoint", target_spawnpoint);
-
- sprite = sprite_manager->create("images/objects/door/door.sprite");
- sprite->set_action("closed");
- bbox.set_size(sprite->get_current_hitbox_width(), sprite->get_current_hitbox_height());
-}
-
-Door::Door(int x, int y, std::string sector, std::string spawnpoint)
- : state(CLOSED)
-{
- bbox.set_pos(Vector(x, y));
- target_sector = sector;
- target_spawnpoint = spawnpoint;
-
- sprite = sprite_manager->create("images/objects/door/door.sprite");
- sprite->set_action("closed");
- bbox.set_size(sprite->get_current_hitbox_width(), sprite->get_current_hitbox_height());
-}
-
-Door::~Door()
-{
- delete sprite;
-}
-
-void
-Door::write(lisp::Writer& writer)
-{
- writer.start_list("door");
-
- writer.write_float("x", bbox.p1.x);
- writer.write_float("y", bbox.p1.y);
- writer.write_float("width", bbox.get_width());
- writer.write_float("height", bbox.get_height());
-
- writer.write_string("sector", target_sector);
- writer.write_string("spawnpoint", target_spawnpoint);
- sound_manager->preload("sounds/door.wav");
- writer.end_list("door");
-}
-
-void
-Door::update(float )
-{
- switch (state) {
- case CLOSED:
- break;
- case OPENING:
- // if door has finished opening, start timer and keep door open
- if(sprite->animation_done()) {
- state = OPEN;
- sprite->set_action("open");
- stay_open_timer.start(1.0);
- }
- break;
- case OPEN:
- // if door was open long enough, start closing it
- if (stay_open_timer.check()) {
- state = CLOSING;
- sprite->set_action("closing", 1);
- }
- break;
- case CLOSING:
- // if door has finished closing, keep it shut
- if(sprite->animation_done()) {
- state = CLOSED;
- sprite->set_action("closed");
- }
- break;
- }
-}
-
-void
-Door::draw(DrawingContext& context)
-{
- sprite->draw(context, bbox.p1, LAYER_BACKGROUNDTILES+1);
-}
-
-void
-Door::event(Player& , EventType type)
-{
- switch (state) {
- case CLOSED:
- // if door was activated, start opening it
- if (type == EVENT_ACTIVATE) {
- state = OPENING;
- sound_manager->play("sounds/door.wav");
- sprite->set_action("opening", 1);
- }
- break;
- case OPENING:
- break;
- case OPEN:
- break;
- case CLOSING:
- break;
- }
-}
-
-HitResponse
-Door::collision(GameObject& other, const CollisionHit& hit)
-{
- switch (state) {
- case CLOSED:
- break;
- case OPENING:
- break;
- case OPEN:
- {
- // if door is open and was touched by a player, teleport the player
- Player* player = dynamic_cast<Player*> (&other);
- if (player) {
- state = CLOSING;
- sprite->set_action("closing", 1);
- GameSession::current()->respawn(target_sector, target_spawnpoint);
- }
- }
- break;
- case CLOSING:
- break;
- }
-
- return TriggerBase::collision(other, hit);
-}
-
-IMPLEMENT_FACTORY(Door, "door");
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef SUPERTUX_DOOR_H
-#define SUPERTUX_DOOR_H
-
-#include <string>
-
-#include "video/surface.hpp"
-#include "sprite/sprite.hpp"
-#include "trigger_base.hpp"
-#include "serializable.hpp"
-#include "timer.hpp"
-#include "object/player.hpp"
-
-class Door : public TriggerBase, public Serializable
-{
-public:
- Door(const lisp::Lisp& reader);
- Door(int x, int y, std::string sector, std::string spawnpoint);
- virtual ~Door();
-
- virtual void write(lisp::Writer& writer);
-
- virtual void update(float elapsed_time);
- virtual void draw(DrawingContext& context);
- virtual void event(Player& player, EventType type);
- virtual HitResponse collision(GameObject& other, const CollisionHit& hit);
-
-private:
- enum DoorState {
- CLOSED,
- OPENING,
- OPEN,
- CLOSING
- };
-
- DoorState state; /**< current state of the door */
- std::string target_sector; /**< target sector to teleport to */
- std::string target_spawnpoint; /**< target spawnpoint to teleport to */
- Sprite* sprite; /**< "door" sprite to render */
- Timer stay_open_timer; /**< time until door will close again */
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include <sstream>
-#include <stdexcept>
-#include <memory>
-
-#include "scripttrigger.hpp"
-#include "game_session.hpp"
-#include "lisp/lisp.hpp"
-#include "lisp/writer.hpp"
-#include "object_factory.hpp"
-#include "sector.hpp"
-
-ScriptTrigger::ScriptTrigger(const lisp::Lisp& reader)
-{
- bool must_activate = false;
-
- reader.get("x", bbox.p1.x);
- reader.get("y", bbox.p1.y);
- float w = 0, h = 0;
- reader.get("width", w);
- reader.get("height", h);
- bbox.set_size(w, h);
- reader.get("script", script);
- reader.get("button", must_activate);
- if(script == "") {
- throw std::runtime_error("Need to specify a script for trigger object");
- }
-
- if (must_activate)
- triggerevent = EVENT_ACTIVATE;
- else
- triggerevent = EVENT_TOUCH;
-}
-
-ScriptTrigger::ScriptTrigger(const Vector& pos, const std::string& script)
-{
- bbox.set_pos(pos);
- bbox.set_size(32, 32);
- this->script = script;
- triggerevent = EVENT_TOUCH;
-}
-
-ScriptTrigger::~ScriptTrigger()
-{
-}
-
-void
-ScriptTrigger::write(lisp::Writer& writer)
-{
- writer.start_list("scripttrigger");
-
- writer.write_float("x", bbox.p1.x);
- writer.write_float("y", bbox.p1.y);
- writer.write_float("width", bbox.get_width());
- writer.write_float("height", bbox.get_height());
- writer.write_string("script", script);
- writer.write_bool("button", triggerevent == EVENT_ACTIVATE);
-
- writer.end_list("scripttrigger");
-}
-
-void
-ScriptTrigger::event(Player& , EventType type)
-{
- if(type != triggerevent)
- return;
-
- std::istringstream stream(script);
- Sector::current()->run_script(stream, "ScriptTrigger");
-}
-
-IMPLEMENT_FACTORY(ScriptTrigger, "scripttrigger");
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __SCRIPTTRIGGER_H__
-#define __SCRIPTTRIGGER_H__
-
-#include "trigger_base.hpp"
-#include "serializable.hpp"
-
-class ScriptTrigger : public TriggerBase, public Serializable
-{
-public:
- ScriptTrigger(const lisp::Lisp& reader);
- ScriptTrigger(const Vector& pos, const std::string& script);
- ~ScriptTrigger();
-
- void write(lisp::Writer& writer);
- void event(Player& player, EventType type);
-
-private:
- EventType triggerevent;
- std::string script;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include "secretarea_trigger.hpp"
-#include "game_session.hpp"
-#include "lisp/lisp.hpp"
-#include "lisp/writer.hpp"
-#include "object_factory.hpp"
-#include "main.hpp"
-#include "sector.hpp"
-#include "level.hpp"
-#include "gettext.hpp"
-#include "object/tilemap.hpp"
-
-static const float MESSAGE_TIME=3.5;
-
-SecretAreaTrigger::SecretAreaTrigger(const lisp::Lisp& reader)
- : fade_tilemap("")
-{
- reader.get("x", bbox.p1.x);
- reader.get("y", bbox.p1.y);
- float w = 32, h = 32;
- reader.get("width", w);
- reader.get("height", h);
- bbox.set_size(w, h);
- reader.get("fade-tilemap", fade_tilemap);
-
- message_displayed = false;
-}
-
-SecretAreaTrigger::SecretAreaTrigger(const Rect& area, std::string fade_tilemap)
- : fade_tilemap(fade_tilemap)
-{
- bbox = area;
- message_displayed = false;
-}
-
-SecretAreaTrigger::~SecretAreaTrigger()
-{
-}
-
-void
-SecretAreaTrigger::write(lisp::Writer& writer)
-{
- writer.start_list("secretarea");
-
- writer.write_float("x", bbox.p1.x);
- writer.write_float("y", bbox.p1.y);
- writer.write_float("width", bbox.get_width());
- writer.write_float("height", bbox.get_height());
- writer.write_string("fade-tilemap", fade_tilemap);
-
- writer.end_list("secretarea");
-}
-
-void
-SecretAreaTrigger::draw(DrawingContext& context)
-{
- if (message_timer.started()) {
- context.push_transform();
- context.set_translation(Vector(0, 0));
- Vector pos = Vector(0, SCREEN_HEIGHT/2 - gold_text->get_height()/2);
- context.draw_center_text(gold_text, _("You found a secret area!"), pos, LAYER_GUI);
- context.pop_transform();
- }
- if (message_timer.check()) {
- remove_me();
- }
-}
-
-void
-SecretAreaTrigger::event(Player& , EventType type)
-{
- if(type == EVENT_TOUCH) {
- if (!message_displayed) {
- message_timer.start(MESSAGE_TIME);
- message_displayed = true;
- Sector::current()->get_level()->stats.secrets++;
-
- if (fade_tilemap != "") {
- // fade away tilemaps
- Sector& sector = *Sector::current();
- for(Sector::GameObjects::iterator i = sector.gameobjects.begin(); i != sector.gameobjects.end(); ++i) {
- TileMap* tm = dynamic_cast<TileMap*>(*i);
- if (!tm) continue;
- if (tm->get_name() != fade_tilemap) continue;
- tm->fade(0.0, 1.0);
- }
- }
-
- }
- }
-}
-
-IMPLEMENT_FACTORY(SecretAreaTrigger, "secretarea");
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __SECRETAREA_TRIGGER_H__
-#define __SECRETAREA_TRIGGER_H__
-
-#include "trigger_base.hpp"
-#include "serializable.hpp"
-#include "resources.hpp"
-#include "video/drawing_context.hpp"
-#include "timer.hpp"
-
-class SecretAreaTrigger : public TriggerBase, public Serializable
-{
-public:
- SecretAreaTrigger(const lisp::Lisp& reader);
- SecretAreaTrigger(const Rect& area, std::string fade_tilemap = "");
- ~SecretAreaTrigger();
-
- void write(lisp::Writer& writer);
- void event(Player& player, EventType type);
- void draw(DrawingContext& context);
-
-private:
- Timer message_timer;
- bool message_displayed;
- std::string fade_tilemap; /**< tilemap to fade away when trigger is activated, or empty if you don't care */
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-
-#include <config.h>
-
-#include "sequence_trigger.hpp"
-#include "game_session.hpp"
-#include "lisp/lisp.hpp"
-#include "lisp/writer.hpp"
-#include "object_factory.hpp"
-
-SequenceTrigger::SequenceTrigger(const lisp::Lisp& reader)
-{
- reader.get("x", bbox.p1.x);
- reader.get("y", bbox.p1.y);
- float w = 0, h = 0;
- reader.get("width", w);
- reader.get("height", h);
- bbox.set_size(w, h);
- reader.get("sequence", sequence_name);
- triggerevent = EVENT_TOUCH;
-}
-
-SequenceTrigger::SequenceTrigger(const Vector& pos, const std::string& sequence)
-{
- bbox.set_pos(pos);
- bbox.set_size(32, 32);
- sequence_name = sequence;
- triggerevent = EVENT_TOUCH;
-}
-
-SequenceTrigger::~SequenceTrigger()
-{
-}
-
-void
-SequenceTrigger::write(lisp::Writer& writer)
-{
- writer.start_list("sequencetrigger");
-
- writer.write_float("x", bbox.p1.x);
- writer.write_float("y", bbox.p1.y);
- writer.write_float("width", bbox.get_width());
- writer.write_float("height", bbox.get_height());
- writer.write_string("sequence", sequence_name);
-
- writer.end_list("sequencetrigger");
-}
-
-void
-SequenceTrigger::event(Player& player, EventType type)
-{
- if(type == triggerevent) {
- player.trigger_sequence(sequence_name);
- }
-}
-
-IMPLEMENT_FACTORY(SequenceTrigger, "sequencetrigger")
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-
-#ifndef __SEQUENCE_TRIGGER_H__
-#define __SEQUENCE_TRIGGER_H__
-
-#include "trigger_base.hpp"
-#include "serializable.hpp"
-#include "object/player.hpp"
-
-class SequenceTrigger : public TriggerBase, public Serializable
-{
-public:
- SequenceTrigger(const lisp::Lisp& reader);
- SequenceTrigger(const Vector& pos, const std::string& sequence);
- ~SequenceTrigger();
-
- void write(lisp::Writer& writer);
- void event(Player& player, EventType type);
-
- std::string get_sequence_name() const { return sequence_name; }
-
-private:
- EventType triggerevent;
- std::string sequence_name;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux - Switch Trigger
-// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
-//
-// 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.
-
-#include <config.h>
-#include <stdexcept>
-
-#include "switch.hpp"
-#include "object_factory.hpp"
-#include "sprite/sprite.hpp"
-#include "sprite/sprite_manager.hpp"
-#include "sector.hpp"
-#include "audio/sound_manager.hpp"
-
-namespace {
- const std::string SWITCH_SOUND = "sounds/switch.ogg";
-}
-
-Switch::Switch(const lisp::Lisp& reader)
- : state(OFF)
-{
- if (!reader.get("x", bbox.p1.x)) throw std::runtime_error("no x position set");
- if (!reader.get("y", bbox.p1.y)) throw std::runtime_error("no y position set");
- if (!reader.get("sprite", sprite_name)) throw std::runtime_error("no sprite name set");
- sprite = sprite_manager->create(sprite_name);
- bbox.set_size(sprite->get_current_hitbox_width(), sprite->get_current_hitbox_height());
-
- if (!reader.get("script", script)) throw std::runtime_error("no script set");
- sound_manager->preload( SWITCH_SOUND );
-}
-
-Switch::~Switch()
-{
- delete sprite;
-}
-
-void
-Switch::write(lisp::Writer& writer)
-{
- writer.start_list("switch");
- writer.write_float("x", bbox.p1.x);
- writer.write_float("y", bbox.p1.y);
- writer.write_string("sprite", sprite_name);
- writer.write_string("script", script);
- writer.end_list("switch");
-}
-
-void
-Switch::update(float )
-{
- switch (state) {
- case OFF:
- break;
- case TURN_ON:
- if(sprite->animation_done()) {
- std::istringstream stream(script);
- Sector::current()->run_script(stream, "Switch");
-
- sprite->set_action("on", 1);
- state = ON;
- }
- break;
- case ON:
- if(sprite->animation_done()) {
- sprite->set_action("turnoff", 1);
- state = TURN_OFF;
- }
- break;
- case TURN_OFF:
- if(sprite->animation_done()) {
- sprite->set_action("off");
- state = OFF;
- }
- break;
- }
-}
-
-void
-Switch::draw(DrawingContext& context)
-{
- sprite->draw(context, bbox.p1, LAYER_TILES);
-}
-
-void
-Switch::event(Player& , EventType type)
-{
- if(type != EVENT_ACTIVATE) return;
-
- switch (state) {
- case OFF:
- sprite->set_action("turnon", 1);
- sound_manager->play( SWITCH_SOUND );
- state = TURN_ON;
- break;
- case TURN_ON:
- break;
- case ON:
- break;
- case TURN_OFF:
- break;
- }
-
-}
-
-IMPLEMENT_FACTORY(Switch, "switch");
+++ /dev/null
-// $Id$
-//
-// SuperTux - Switch Trigger
-// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
-//
-// 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.
-
-#ifndef SUPERTUX_SWITCH_H
-#define SUPERTUX_SWITCH_H
-
-#include <string>
-
-#include "trigger_base.hpp"
-#include "serializable.hpp"
-#include "lisp/lisp.hpp"
-#include "lisp/writer.hpp"
-#include "video/drawing_context.hpp"
-#include "sprite/sprite.hpp"
-
-class Switch : public TriggerBase, public Serializable
-{
-public:
- Switch(const lisp::Lisp& reader);
- virtual ~Switch();
-
- virtual void write(lisp::Writer& writer);
-
- virtual void update(float elapsed_time);
- virtual void draw(DrawingContext& context);
- virtual void event(Player& player, EventType type);
-
-private:
- enum SwitchState {
- OFF,
- TURN_ON,
- ON,
- TURN_OFF
- };
-
- std::string sprite_name;
- Sprite* sprite;
- std::string script;
-
- SwitchState state;
-
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include "trigger_base.hpp"
-#include "video/drawing_context.hpp"
-#include "object/player.hpp"
-#include "log.hpp"
-
-TriggerBase::TriggerBase()
- : sprite(0), lasthit(false), hit(false)
-{
- set_group(COLGROUP_TOUCHABLE);
-}
-
-TriggerBase::~TriggerBase()
-{
- // unregister remove_listener hooks, so nobody will try to call us after we've been destroyed
- for (std::list<Player*>::iterator i = losetouch_listeners.begin(); i != losetouch_listeners.end(); i++) {
- Player* p = *i;
- p->del_remove_listener(this);
- }
- losetouch_listeners.clear();
-}
-
-void
-TriggerBase::update(float )
-{
- if (lasthit && !hit) {
- for (std::list<Player*>::iterator i = losetouch_listeners.begin(); i != losetouch_listeners.end(); i++) {
- Player* p = *i;
- event(*p, EVENT_LOSETOUCH);
- p->del_remove_listener(this);
- }
- losetouch_listeners.clear();
- }
- lasthit = hit;
- hit = false;
-}
-
-void
-TriggerBase::draw(DrawingContext& context)
-{
- if(!sprite)
- return;
-
- sprite->draw(context, get_pos(), LAYER_TILES+1);
-}
-
-HitResponse
-TriggerBase::collision(GameObject& other, const CollisionHit& )
-{
- Player* player = dynamic_cast<Player*> (&other);
- if(player) {
- hit = true;
- if(!lasthit) {
- losetouch_listeners.push_back(player);
- player->add_remove_listener(this);
- event(*player, EVENT_TOUCH);
- }
- }
-
- return ABORT_MOVE;
-}
-
-void
-TriggerBase::object_removed(GameObject* object)
-{
- for (std::list<Player*>::iterator i = losetouch_listeners.begin(); i != losetouch_listeners.end(); i++) {
- Player* p = *i;
- if (p == object) {
- losetouch_listeners.erase(i);
- break;
- }
- }
-}
-
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef SUPERTUX_TRIGGER_BASE_H
-#define SUPERTUX_TRIGGER_BASE_H
-
-#include <list>
-#include "moving_object.hpp"
-#include "math/rect.hpp"
-#include "sprite/sprite.hpp"
-#include "object_remove_listener.hpp"
-
-class Player;
-
-/** This class is the base class for all objects you can interact with in some
- * way. There are several interaction types defined like touch and activate
- */
-class TriggerBase : public MovingObject, public ObjectRemoveListener
-{
-public:
- enum EventType {
- EVENT_TOUCH, /**< Object came into contact */
- EVENT_LOSETOUCH, /**< Lost contact with object */
- EVENT_ACTIVATE /**< Action button pressed */
- };
-
- TriggerBase();
- ~TriggerBase();
-
- void update(float elapsed_time);
- void draw(DrawingContext& context);
- HitResponse collision(GameObject& other, const CollisionHit& hit);
-
- /**
- * Receive trigger events
- */
- virtual void event(Player& player, EventType type) = 0;
-
- /**
- * Called by GameObject destructor of an object in losetouch_listeners
- */
- virtual void object_removed(GameObject* object);
-
-private:
- Sprite* sprite;
- bool lasthit;
- bool hit;
-
- std::list<Player*> losetouch_listeners; /**< Players that will be informed when we lose touch with them */
-};
-
-#endif /*SUPERTUX_INTERACTIVE_OBJECT_H*/
+++ /dev/null
-// $Id: color.cpp 5063 2007-05-27 11:32:00Z matzeb $
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#include <config.h>
-
-#include "color.hpp"
-
-const Color Color::BLACK(0.0, 0.0, 0.0);
-const Color Color::RED(1.0, 0.0, 0.0);
-const Color Color::GREEN(0.0, 1.0, 0.0);
-const Color Color::BLUE(0.0, 0.0, 1.0);
-const Color Color::CYAN(0.0, 1.0, 1.0);
-const Color Color::MAGENTA(1.0, 0.0, 1.0);
-const Color Color::YELLOW(1.0, 1.0, 0.0);
-const Color Color::WHITE(1.0, 1.0, 1.0);
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __COLOR_HPP__
-#define __COLOR_HPP__
-
-#include <vector>
-#include <assert.h>
-#include "log.hpp"
-
-class Color
-{
-public:
- Color()
- : red(0), green(0), blue(0), alpha(1.0)
- { }
- Color(float red, float green, float blue, float alpha = 1.0)
- : red(red), green(green), blue(blue), alpha(alpha)
- {
-#ifdef DEBUG
- check_color_ranges();
-#endif
- }
- Color(const std::vector<float>& vals)
- {
- assert(vals.size() >= 3);
- red = vals[0];
- green = vals[1];
- blue = vals[2];
- if(vals.size() > 3)
- alpha = vals[3];
- else
- alpha = 1.0;
-#ifdef DEBUG
- check_color_ranges();
-#endif
- }
-
- bool operator==(const Color& other) const
- {
- return red == other.red && green == other.green && blue == other.blue
- && alpha == other.alpha;
- }
-
- void check_color_ranges()
- {
- if(red < 0 || red > 1.0 || green < 0 || green > 1.0
- || blue < 0 || blue > 1.0
- || alpha < 0 || alpha > 1.0)
- log_warning << "color value out of range: " << red << ", " << green << ", " << blue << ", " << alpha << std::endl;
- }
-
- float greyscale() const
- {
- return red * 0.30 + green * 0.59 + blue * 0.11;
- }
-
- bool operator < (const Color& other) const
- {
- return greyscale() < other.greyscale();
- }
-
- float red, green, blue, alpha;
-
- static const Color BLACK;
- static const Color RED;
- static const Color GREEN;
- static const Color BLUE;
- static const Color CYAN;
- static const Color MAGENTA;
- static const Color YELLOW;
- static const Color WHITE;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#include <config.h>
-
-#include <functional>
-#include <algorithm>
-#include <cassert>
-#include <iostream>
-#include <SDL_image.h>
-#include <sstream>
-#include <iomanip>
-#include <physfs.h>
-
-#include "drawing_context.hpp"
-#include "drawing_request.hpp"
-#include "video_systems.hpp"
-#include "renderer.hpp"
-#include "lightmap.hpp"
-#include "surface.hpp"
-#include "main.hpp"
-#include "gameconfig.hpp"
-#include "texture.hpp"
-#include "texture_manager.hpp"
-#include "obstack/obstackpp.hpp"
-
-static inline int next_po2(int val)
-{
- int result = 1;
- while(result < val)
- result *= 2;
-
- return result;
-}
-
-DrawingContext::DrawingContext() :
- renderer(0), lightmap(0), ambient_color(1.0f, 1.0f, 1.0f, 1.0f), target(NORMAL), screenshot_requested(false)
-{
- requests = &drawing_requests;
- obstack_init(&obst);
-}
-
-DrawingContext::~DrawingContext()
-{
- delete renderer;
- delete lightmap;
-
- obstack_free(&obst, NULL);
-}
-
-void
-DrawingContext::init_renderer()
-{
- delete renderer;
- delete lightmap;
-
- renderer = new_renderer();
- lightmap = new_lightmap();
-}
-
-void
-DrawingContext::draw_surface(const Surface* surface, const Vector& position,
- float angle, const Color& color, const Blend& blend,
- int layer)
-{
- assert(surface != 0);
-
- DrawingRequest* request = new(obst) DrawingRequest();
-
- request->target = target;
- request->type = SURFACE;
- request->pos = transform.apply(position);
-
- if(request->pos.x >= SCREEN_WIDTH || request->pos.y >= SCREEN_HEIGHT
- || request->pos.x + surface->get_width() < 0
- || request->pos.y + surface->get_height() < 0)
- return;
-
- request->layer = layer;
- request->drawing_effect = transform.drawing_effect;
- request->alpha = transform.alpha;
- request->angle = angle;
- request->color = color;
- request->blend = blend;
-
- request->request_data = const_cast<Surface*> (surface);
-
- requests->push_back(request);
-}
-
-void
-DrawingContext::draw_surface(const Surface* surface, const Vector& position,
- int layer)
-{
- draw_surface(surface, position, 0.0f, Color(1.0f, 1.0f, 1.0f), Blend(), layer);
-}
-
-void
-DrawingContext::draw_surface_part(const Surface* surface, const Vector& source,
- const Vector& size, const Vector& dest, int layer)
-{
- assert(surface != 0);
-
- DrawingRequest* request = new(obst) DrawingRequest();
-
- request->target = target;
- request->type = SURFACE_PART;
- request->pos = transform.apply(dest);
- request->layer = layer;
- request->drawing_effect = transform.drawing_effect;
- request->alpha = transform.alpha;
-
- SurfacePartRequest* surfacepartrequest = new(obst) SurfacePartRequest();
- surfacepartrequest->size = size;
- surfacepartrequest->source = source;
- surfacepartrequest->surface = surface;
-
- // clip on screen borders
- if(request->pos.x < 0) {
- surfacepartrequest->size.x += request->pos.x;
- if(surfacepartrequest->size.x <= 0)
- return;
- surfacepartrequest->source.x -= request->pos.x;
- request->pos.x = 0;
- }
- if(request->pos.y < 0) {
- surfacepartrequest->size.y += request->pos.y;
- if(surfacepartrequest->size.y <= 0)
- return;
- surfacepartrequest->source.y -= request->pos.y;
- request->pos.y = 0;
- }
- request->request_data = surfacepartrequest;
-
- requests->push_back(request);
-}
-
-void
-DrawingContext::draw_text(const Font* font, const std::string& text,
- const Vector& position, FontAlignment alignment, int layer)
-{
- DrawingRequest* request = new(obst) DrawingRequest();
-
- request->target = target;
- request->type = TEXT;
- request->pos = transform.apply(position);
- request->layer = layer;
- request->drawing_effect = transform.drawing_effect;
- request->alpha = transform.alpha;
-
- TextRequest* textrequest = new(obst) TextRequest();
- textrequest->font = font;
- textrequest->text = text;
- textrequest->alignment = alignment;
- request->request_data = textrequest;
-
- requests->push_back(request);
-}
-
-void
-DrawingContext::draw_center_text(const Font* font, const std::string& text,
- const Vector& position, int layer)
-{
- draw_text(font, text, Vector(position.x + SCREEN_WIDTH/2, position.y),
- ALIGN_CENTER, layer);
-}
-
-void
-DrawingContext::draw_gradient(const Color& top, const Color& bottom, int layer)
-{
- DrawingRequest* request = new(obst) DrawingRequest();
-
- request->target = target;
- request->type = GRADIENT;
- request->pos = Vector(0,0);
- request->layer = layer;
-
- request->drawing_effect = transform.drawing_effect;
- request->alpha = transform.alpha;
-
- GradientRequest* gradientrequest = new(obst) GradientRequest();
- gradientrequest->top = top;
- gradientrequest->bottom = bottom;
- request->request_data = gradientrequest;
-
- requests->push_back(request);
-}
-
-void
-DrawingContext::draw_filled_rect(const Vector& topleft, const Vector& size,
- const Color& color, int layer)
-{
- DrawingRequest* request = new(obst) DrawingRequest();
-
- request->target = target;
- request->type = FILLRECT;
- request->pos = transform.apply(topleft);
- request->layer = layer;
-
- request->drawing_effect = transform.drawing_effect;
- request->alpha = transform.alpha;
-
- FillRectRequest* fillrectrequest = new(obst) FillRectRequest();
- fillrectrequest->size = size;
- fillrectrequest->color = color;
- fillrectrequest->color.alpha = color.alpha * transform.alpha;
- request->request_data = fillrectrequest;
-
- requests->push_back(request);
-}
-
-void
-DrawingContext::draw_filled_rect(const Rect& rect, const Color& color,
- int layer)
-{
- DrawingRequest* request = new(obst) DrawingRequest();
-
- request->target = target;
- request->type = FILLRECT;
- request->pos = transform.apply(rect.p1);
- request->layer = layer;
-
- request->drawing_effect = transform.drawing_effect;
- request->alpha = transform.alpha;
-
- FillRectRequest* fillrectrequest = new(obst) FillRectRequest;
- fillrectrequest->size = Vector(rect.get_width(), rect.get_height());
- fillrectrequest->color = color;
- fillrectrequest->color.alpha = color.alpha * transform.alpha;
- request->request_data = fillrectrequest;
-
- requests->push_back(request);
-}
-
-void
-DrawingContext::get_light(const Vector& position, Color* color)
-{
- if( ambient_color.red == 1.0f && ambient_color.green == 1.0f
- && ambient_color.blue == 1.0f ) {
- *color = Color( 1.0f, 1.0f, 1.0f);
- return;
- }
-
- DrawingRequest* request = new(obst) DrawingRequest();
- request->target = target;
- request->type = GETLIGHT;
- request->pos = transform.apply(position);
-
- //There is no light offscreen.
- if(request->pos.x >= SCREEN_WIDTH || request->pos.y >= SCREEN_HEIGHT
- || request->pos.x < 0 || request->pos.y < 0){
- *color = Color( 0, 0, 0);
- return;
- }
-
- request->layer = LAYER_GUI; //make sure all get_light requests are handled last.
- GetLightRequest* getlightrequest = new(obst) GetLightRequest();
- getlightrequest->color_ptr = color;
- request->request_data = getlightrequest;
- lightmap_requests.push_back(request);
-}
-
-void
-DrawingContext::do_drawing()
-{
-#ifdef DEBUG
- assert(transformstack.empty());
- assert(target_stack.empty());
-#endif
- transformstack.clear();
- target_stack.clear();
-
- //Use Lightmap if ambient color is not white.
- bool use_lightmap = ( ambient_color.red != 1.0f || ambient_color.green != 1.0f ||
- ambient_color.blue != 1.0f );
-
- // PART1: create lightmap
- if(use_lightmap) {
- lightmap->start_draw(ambient_color);
- handle_drawing_requests(lightmap_requests);
- lightmap->end_draw();
- }
-
- handle_drawing_requests(drawing_requests);
- if(use_lightmap) {
- lightmap->do_draw();
- }
- obstack_free(&obst, NULL);
- obstack_init(&obst);
-
- // if a screenshot was requested, take one
- if (screenshot_requested) {
- renderer->do_take_screenshot();
- screenshot_requested = false;
- }
-
- renderer->flip();
-}
-
-class RequestPtrCompare
- : public std::binary_function<const DrawingRequest*,
- const DrawingRequest*,
- bool>
-{
-public:
- bool operator()(const DrawingRequest* r1, const DrawingRequest* r2) const
- {
- return *r1 < *r2;
- }
-};
-
-void
-DrawingContext::handle_drawing_requests(DrawingRequests& requests)
-{
- std::stable_sort(requests.begin(), requests.end(), RequestPtrCompare());
-
- DrawingRequests::const_iterator i;
- for(i = requests.begin(); i != requests.end(); ++i) {
- const DrawingRequest& request = **i;
-
- switch(request.target) {
- case NORMAL:
- switch(request.type) {
- case SURFACE:
- renderer->draw_surface(request);
- break;
- case SURFACE_PART:
- renderer->draw_surface_part(request);
- break;
- case GRADIENT:
- renderer->draw_gradient(request);
- break;
- case TEXT:
- {
- const TextRequest* textrequest = (TextRequest*) request.request_data;
- textrequest->font->draw(renderer, textrequest->text, request.pos,
- textrequest->alignment, request.drawing_effect, request.alpha);
- }
- break;
- case FILLRECT:
- renderer->draw_filled_rect(request);
- break;
- case GETLIGHT:
- lightmap->get_light(request);
- break;
- }
- break;
- case LIGHTMAP:
- switch(request.type) {
- case SURFACE:
- lightmap->draw_surface(request);
- break;
- case SURFACE_PART:
- lightmap->draw_surface_part(request);
- break;
- case GRADIENT:
- lightmap->draw_gradient(request);
- break;
- case TEXT:
- {
- const TextRequest* textrequest = (TextRequest*) request.request_data;
- textrequest->font->draw(renderer, textrequest->text, request.pos,
- textrequest->alignment, request.drawing_effect, request.alpha);
- }
- break;
- case FILLRECT:
- lightmap->draw_filled_rect(request);
- break;
- case GETLIGHT:
- lightmap->get_light(request);
- break;
- }
- break;
- }
- }
- requests.clear();
-}
-
-void
-DrawingContext::push_transform()
-{
- transformstack.push_back(transform);
-}
-
-void
-DrawingContext::pop_transform()
-{
- assert(!transformstack.empty());
-
- transform = transformstack.back();
- transformstack.pop_back();
-}
-
-void
-DrawingContext::set_drawing_effect(DrawingEffect effect)
-{
- transform.drawing_effect = effect;
-}
-
-DrawingEffect
-DrawingContext::get_drawing_effect() const
-{
- return transform.drawing_effect;
-}
-
-void
-DrawingContext::set_alpha(float alpha)
-{
- transform.alpha = alpha;
-}
-
-float
-DrawingContext::get_alpha() const
-{
- return transform.alpha;
-}
-
-void
-DrawingContext::push_target()
-{
- target_stack.push_back(target);
-}
-
-void
-DrawingContext::pop_target()
-{
- set_target(target_stack.back());
- target_stack.pop_back();
-}
-
-void
-DrawingContext::set_target(Target target)
-{
- this->target = target;
- if(target == LIGHTMAP) {
- requests = &lightmap_requests;
- } else {
- assert(target == NORMAL);
- requests = &drawing_requests;
- }
-}
-
-void
-DrawingContext::set_ambient_color( Color new_color )
-{
- ambient_color = new_color;
-}
-
-void
-DrawingContext::take_screenshot()
-{
- screenshot_requested = true;
-}
-
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#ifndef SUPERTUX_DRAWINGCONTEXT_H
-#define SUPERTUX_DRAWINGCONTEXT_H
-
-#include <vector>
-#include <string>
-#include <memory>
-
-#include <stdint.h>
-
-#include <SDL_video.h>
-
-#include "glutil.hpp"
-#include "obstack/obstack.h"
-#include "math/vector.hpp"
-#include "math/rect.hpp"
-#include "drawing_request.hpp"
-#include "font.hpp"
-#include "color.hpp"
-
-class Surface;
-class Texture;
-struct DrawingRequest;
-class Renderer;
-class Lightmap;
-
-/**
- * This class provides functions for drawing things on screen. It also
- * maintains a stack of transforms that are applied to graphics.
- */
-class DrawingContext
-{
-public:
- DrawingContext();
- ~DrawingContext();
-
- void init_renderer();
-
- /// Adds a drawing request for a surface into the request list.
- void draw_surface(const Surface* surface, const Vector& position,
- int layer);
- /// Adds a drawing request for a surface into the request list.
- void draw_surface(const Surface* surface, const Vector& position,
- float angle, const Color& color, const Blend& blend,
- int layer);
- /// Adds a drawing request for part of a surface.
- void draw_surface_part(const Surface* surface, const Vector& source,
- const Vector& size, const Vector& dest, int layer);
- /// Draws a text.
- void draw_text(const Font* font, const std::string& text,
- const Vector& position, FontAlignment alignment, int layer);
-
- /// Draws text on screen center (feed Vector.x with a 0).
- /// This is the same as draw_text() with a SCREEN_WIDTH/2 position and
- /// alignment set to LEFT_ALLIGN
- void draw_center_text(const Font* font, const std::string& text,
- const Vector& position, int layer);
- /// Draws a color gradient onto the whole screen */
- void draw_gradient(const Color& from, const Color& to, int layer);
- /// Fills a rectangle.
- void draw_filled_rect(const Vector& topleft, const Vector& size,
- const Color& color, int layer);
- void draw_filled_rect(const Rect& rect, const Color& color, int layer);
-
- /// Processes all pending drawing requests and flushes the list.
- void do_drawing();
-
- const Vector& get_translation() const
- { return transform.translation; }
-
- void set_translation(const Vector& newtranslation)
- { transform.translation = newtranslation; }
-
- void push_transform();
- void pop_transform();
-
- /// Apply that effect in the next draws (effects are listed on surface.h).
- void set_drawing_effect(DrawingEffect effect);
- /// return currently applied drawing effect
- DrawingEffect get_drawing_effect() const;
- /// apply that alpha in the next draws (1.0 means fully opaque) */
- void set_alpha(float alpha);
- /// return currently set alpha
- float get_alpha() const;
-
- /// on next update, set color to lightmap's color at position
- void get_light(const Vector& position, Color* color );
-
- typedef ::Target Target;
- static const Target NORMAL = ::NORMAL;
- static const Target LIGHTMAP = ::LIGHTMAP;
- void push_target();
- void pop_target();
- void set_target(Target target);
-
- void set_ambient_color( Color new_color );
-
- /**
- * requests that a screenshot be taken after the next frame has been rendered
- */
- void take_screenshot();
-
-private:
- class Transform
- {
- public:
- Vector translation;
- DrawingEffect drawing_effect;
- float alpha;
-
- Transform()
- : drawing_effect(NO_EFFECT), alpha(1.0f)
- { }
-
- Vector apply(const Vector& v) const
- {
- return v - translation;
- }
- };
-
- Renderer *renderer;
- Lightmap *lightmap;
-
- /// the transform stack
- std::vector<Transform> transformstack;
- /// the currently active transform
- Transform transform;
-
- std::vector<Blend> blend_stack;
- Blend blend_mode;
-
- typedef std::vector<DrawingRequest*> DrawingRequests;
-
- void handle_drawing_requests(DrawingRequests& requests);
-
- DrawingRequests drawing_requests;
- DrawingRequests lightmap_requests;
-
- DrawingRequests* requests;
- Color ambient_color;
-
- Target target;
- std::vector<Target> target_stack;
-
- /* obstack holding the memory of the drawing requests */
- struct obstack obst;
-
- bool screenshot_requested; /**< true if a screenshot should be taken after the next frame has been rendered */
-};
-
-#endif
-
+++ /dev/null
-// $Id: drawing_request.hpp 4986 2007-04-16 17:48:28Z matzeb $
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#ifndef SUPERTUX_DRAWINGREQUEST_H
-#define SUPERTUX_DRAWINGREQUEST_H
-
-#include <vector>
-#include <string>
-#include <memory>
-
-#include <stdint.h>
-
-#include <SDL_video.h>
-
-#include "glutil.hpp"
-#include "math/vector.hpp"
-#include "color.hpp"
-#include "font.hpp"
-
-class Surface;
-
-// some constants for predefined layer values
-enum {
- LAYER_BACKGROUND0 = -300,
- LAYER_BACKGROUND1 = -200,
- LAYER_BACKGROUNDTILES = -100,
- LAYER_TILES = 0,
- LAYER_OBJECTS = 50,
- LAYER_FLOATINGOBJECTS = 150,
- LAYER_FOREGROUNDTILES = 200,
- LAYER_FOREGROUND0 = 300,
- LAYER_FOREGROUND1 = 400,
- LAYER_HUD = 500,
- LAYER_GUI = 600
-};
-
-class Blend
-{
-public:
- GLenum sfactor;
- GLenum dfactor;
-
- Blend()
- : sfactor(GL_SRC_ALPHA), dfactor(GL_ONE_MINUS_SRC_ALPHA)
- {}
-
- Blend(GLenum s, GLenum d)
- : sfactor(s), dfactor(d)
- {}
-};
-
-enum Target {
- NORMAL, LIGHTMAP
-};
-
-enum RequestType
-{
- SURFACE, SURFACE_PART, TEXT, GRADIENT, FILLRECT, GETLIGHT
-};
-
-struct SurfacePartRequest
-{
- const Surface* surface;
- Vector source, size;
-};
-
-struct TextRequest
-{
- const Font* font;
- std::string text;
- FontAlignment alignment;
-};
-
-struct GradientRequest
-{
- Color top, bottom;
- Vector size;
-};
-
-struct FillRectRequest
-{
- Color color;
- Vector size;
-};
-
-struct DrawingRequest
-{
- Target target;
- RequestType type;
- Vector pos;
-
- int layer;
- DrawingEffect drawing_effect;
- float alpha;
- Blend blend;
- float angle;
- Color color;
-
- void* request_data;
-
- DrawingRequest()
- : angle(0.0f),
- color(1.0f, 1.0f, 1.0f, 1.0f)
- {}
-
- bool operator<(const DrawingRequest& other) const
- {
- return layer < other.layer;
- }
-};
-
-struct GetLightRequest
-{
- Color* color_ptr;
-};
-
-#endif
-
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-// Ingo Ruhnke <grumbel@gmx.de>
-//
-// 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.
-
-#include <config.h>
-
-#include <cstdlib>
-#include <cstring>
-#include <stdexcept>
-
-#include <SDL_image.h>
-#include "physfs/physfs_sdl.hpp"
-
-#include "lisp/parser.hpp"
-#include "lisp/lisp.hpp"
-#include "screen.hpp"
-#include "font.hpp"
-#include "renderer.hpp"
-#include "drawing_context.hpp"
-#include "log.hpp"
-
-namespace {
-bool has_multibyte_mark(unsigned char c);
-uint32_t decode_utf8(const std::string& text, size_t& p);
-
-struct UTF8Iterator
-{
- const std::string& text;
- std::string::size_type pos;
- uint32_t chr;
-
- UTF8Iterator(const std::string& text_)
- : text(text_),
- pos(0)
- {
- chr = decode_utf8(text, pos);
- }
-
- bool done() const
- {
- return pos > text.size();
- }
-
- UTF8Iterator& operator++() {
- try {
- chr = decode_utf8(text, pos);
- } catch (std::runtime_error) {
- log_debug << "Malformed utf-8 sequence beginning with " << *((uint32_t*)(text.c_str() + pos)) << " found " << std::endl;
- chr = 0;
- ++pos;
- }
-
- return *this;
- }
-
- uint32_t operator*() const {
- return chr;
- }
-};
-
-bool vline_empty(SDL_Surface* surface, int x, int start_y, int end_y, Uint8 threshold)
-{
- Uint8* pixels = (Uint8*)surface->pixels;
-
- for(int y = start_y; y < end_y; ++y)
- {
- const Uint8& p = pixels[surface->pitch*y + x*surface->format->BytesPerPixel + 3];
- if (p > threshold)
- {
- return false;
- }
- }
- return true;
-}
-} // namespace
-
-Font::Font(GlyphWidth glyph_width_,
- const std::string& filename,
- const std::string& shadowfile,
- int char_width, int char_height_,
- int shadowsize_)
- : glyph_width(glyph_width_),
- glyph_surface(0), shadow_glyph_surface(0),
- char_height(char_height_),
- shadowsize(shadowsize_)
-{
- glyph_surface = new Surface(filename);
- shadow_glyph_surface = new Surface(shadowfile);
-
- first_char = 32;
- char_count = ((int) glyph_surface->get_height() / char_height) * 16;
-
- if (glyph_width == FIXED)
- {
- for(uint32_t i = 0; i < char_count; ++i)
- {
- float x = (i % 16) * char_width;
- float y = (i / 16) * char_height;
-
- Glyph glyph;
- glyph.advance = char_width;
- glyph.offset = Vector(0, 0);
- glyph.rect = Rect(x, y, x + char_width, y + char_height);
-
- glyphs.push_back(glyph);
- shadow_glyphs.push_back(glyph);
- }
- }
- else // glyph_width == VARIABLE
- {
- // Load the surface into RAM and scan the pixel data for characters
- SDL_Surface* surface = IMG_Load_RW(get_physfs_SDLRWops(filename), 1);
- if(surface == NULL) {
- std::ostringstream msg;
- msg << "Couldn't load image '" << filename << "' :" << SDL_GetError();
- throw std::runtime_error(msg.str());
- }
-
- SDL_LockSurface(surface);
-
- for(uint32_t i = 0; i < char_count; ++i)
- {
- int x = (i % 16) * char_width;
- int y = (i / 16) * char_height;
-
- int left = x;
- while (left < x + char_width &&
- vline_empty(surface, left, y, y + char_height, 64))
- left += 1;
-
- int right = x + char_width - 1;
- while (right > left &&
- vline_empty(surface, right, y, y + char_height, 64))
- right -= 1;
-
- Glyph glyph;
- glyph.offset = Vector(0, 0);
-
- if (left <= right)
- glyph.rect = Rect(left, y, right+1, y + char_height);
- else // glyph is completly transparent
- glyph.rect = Rect(x, y, x + char_width, y + char_height);
-
- glyph.advance = glyph.rect.get_width() + 1; // FIXME: might be usefull to make spacing configurable
-
- glyphs.push_back(glyph);
- shadow_glyphs.push_back(glyph);
- }
-
- SDL_UnlockSurface(surface);
-
- SDL_FreeSurface(surface);
- }
-}
-
-Font::~Font()
-{
- delete glyph_surface;
- delete shadow_glyph_surface;
-}
-
-float
-Font::get_text_width(const std::string& text) const
-{
- float curr_width = 0;
- float last_width = 0;
-
- for(UTF8Iterator it(text); !it.done(); ++it)
- {
- if (*it == '\n')
- {
- last_width = std::max(last_width, curr_width);
- curr_width = 0;
- }
- else
- {
- int idx = chr2glyph(*it);
- curr_width += glyphs[idx].advance;
- }
- }
-
- return std::max(curr_width, last_width);
-}
-
-float
-Font::get_text_height(const std::string& text) const
-{
- std::string::size_type text_height = char_height;
-
- for(std::string::const_iterator it = text.begin(); it != text.end(); ++it)
- { // since UTF8 multibyte characters are decoded with values
- // outside the ASCII range there is no risk of overlapping and
- // thus we don't need to decode the utf-8 string
- if (*it == '\n')
- text_height += char_height + 2;
- }
-
- return text_height;
-}
-
-float
-Font::get_height() const
-{
- return char_height;
-}
-
-std::string
-Font::wrap_to_chars(const std::string& s, int line_length, std::string* overflow)
-{
- // if text is already smaller, return full text
- if ((int)s.length() <= line_length) {
- if (overflow) *overflow = "";
- return s;
- }
-
- // if we can find a whitespace character to break at, return text up to this character
- int i = line_length;
- while ((i > 0) && (s[i] != ' ')) i--;
- if (i > 0) {
- if (overflow) *overflow = s.substr(i+1);
- return s.substr(0, i);
- }
-
- // FIXME: wrap at line_length, taking care of multibyte characters
- if (overflow) *overflow = "";
- return s;
-}
-
-std::string
-Font::wrap_to_width(const std::string& s, float width, std::string* overflow)
-{
- // if text is already smaller, return full text
- if (get_text_width(s) <= width) {
- if (overflow) *overflow = "";
- return s;
- }
-
- // if we can find a whitespace character to break at, return text up to this character
- for (int i = s.length()-1; i >= 0; i--) {
- std::string s2 = s.substr(0,i);
- if (s[i] != ' ') continue;
- if (get_text_width(s2) <= width) {
- if (overflow) *overflow = s.substr(i+1);
- return s.substr(0, i);
- }
- }
-
- // FIXME: hard-wrap at width, taking care of multibyte characters
- if (overflow) *overflow = "";
- return s;
-}
-
-void
-Font::draw(Renderer *renderer, const std::string& text, const Vector& pos_,
- FontAlignment alignment, DrawingEffect drawing_effect,
- float alpha) const
-{
- float x = pos_.x;
- float y = pos_.y;
-
- std::string::size_type last = 0;
- for(std::string::size_type i = 0;; ++i)
- {
- if (text[i] == '\n' || i == text.size())
- {
- std::string temp = text.substr(last, i - last);
-
- // calculate X positions based on the alignment type
- Vector pos = Vector(x, y);
-
- if(alignment == ALIGN_CENTER)
- pos.x -= get_text_width(temp) / 2;
- else if(alignment == ALIGN_RIGHT)
- pos.x -= get_text_width(temp);
-
- // Cast font position to integer to get a clean drawing result and
- // no bluring as we would get with subpixel positions
- pos.x = static_cast<int>(pos.x);
-
- draw_text(renderer, temp, pos, drawing_effect, alpha);
-
- if (i == text.size())
- break;
-
- y += char_height + 2;
- last = i + 1;
- }
- }
-}
-
-void
-Font::draw_text(Renderer *renderer, const std::string& text, const Vector& pos,
- DrawingEffect drawing_effect, float alpha) const
-{
- if(shadowsize > 0)
- {
- // FIXME: shadow_glyph_surface and glyph_surface do currently
- // share the same glyph array, this is incorrect and should be
- // fixed, it is however hardly noticable
- draw_chars(renderer, shadow_glyph_surface, text,
- pos + Vector(shadowsize, shadowsize), drawing_effect, alpha);
- }
-
- draw_chars(renderer, glyph_surface, text, pos, drawing_effect, alpha);
-}
-
-int
-Font::chr2glyph(uint32_t chr) const
-{
- int glyph_index = chr - first_char;
-
- // we don't have the control chars 0x80-0xa0 in the font
- if (chr >= 0x80) { // non-ascii character
- glyph_index -= 32;
- if(chr <= 0xa0) {
- log_debug << "Unsupported utf-8 character '" << chr << "' found" << std::endl;
- glyph_index = 0;
- }
- }
-
- if(glyph_index < 0 || glyph_index >= (int) char_count) {
- log_debug << "Unsupported utf-8 character found" << std::endl;
- glyph_index = 0;
- }
-
- return glyph_index;
-}
-
-void
-Font::draw_chars(Renderer *renderer, Surface* pchars, const std::string& text,
- const Vector& pos, DrawingEffect drawing_effect,
- float alpha) const
-{
- Vector p = pos;
-
- for(UTF8Iterator it(text); !it.done(); ++it)
- {
- int font_index = chr2glyph(*it);
-
- if(*it == '\n')
- {
- p.x = pos.x;
- p.y += char_height + 2;
- }
- else if(*it == ' ')
- {
- p.x += glyphs[font_index].advance;
- }
- else
- {
- const Glyph& glyph = glyphs[font_index];
- DrawingRequest request;
-
- request.pos = p + glyph.offset;
- request.drawing_effect = drawing_effect;
- request.alpha = alpha;
-
- SurfacePartRequest surfacepartrequest;
- surfacepartrequest.size = glyph.rect.p2 - glyph.rect.p1;
- surfacepartrequest.source = glyph.rect.p1;
- surfacepartrequest.surface = pchars;
-
- request.request_data = &surfacepartrequest;
- renderer->draw_surface_part(request);
-
- p.x += glyphs[font_index].advance;
- }
- }
-}
-
-
-namespace {
-
-/**
- * returns true if this byte matches a bitmask of 10xx.xxxx, i.e. it is the 2nd, 3rd or 4th byte of a multibyte utf8 string
- */
-bool has_multibyte_mark(unsigned char c) {
- return ((c & 0300) == 0200);
-}
-
-/**
- * gets unicode character at byte position @a p of UTF-8 encoded @a
- * text, then advances @a p to the next character.
- *
- * @throws std::runtime_error if decoding fails.
- * See unicode standard section 3.10 table 3-5 and 3-6 for details.
- */
-uint32_t decode_utf8(const std::string& text, size_t& p)
-{
- uint32_t c1 = (unsigned char) text[p+0];
-
- if (has_multibyte_mark(c1)) std::runtime_error("Malformed utf-8 sequence");
-
- if ((c1 & 0200) == 0000) {
- // 0xxx.xxxx: 1 byte sequence
- p+=1;
- return c1;
- }
- else if ((c1 & 0340) == 0300) {
- // 110x.xxxx: 2 byte sequence
- if(p+1 >= text.size()) throw std::range_error("Malformed utf-8 sequence");
- uint32_t c2 = (unsigned char) text[p+1];
- if (!has_multibyte_mark(c2)) throw std::runtime_error("Malformed utf-8 sequence");
- p+=2;
- return (c1 & 0037) << 6 | (c2 & 0077);
- }
- else if ((c1 & 0360) == 0340) {
- // 1110.xxxx: 3 byte sequence
- if(p+2 >= text.size()) throw std::range_error("Malformed utf-8 sequence");
- uint32_t c2 = (unsigned char) text[p+1];
- uint32_t c3 = (unsigned char) text[p+2];
- if (!has_multibyte_mark(c2)) throw std::runtime_error("Malformed utf-8 sequence");
- if (!has_multibyte_mark(c3)) throw std::runtime_error("Malformed utf-8 sequence");
- p+=3;
- return (c1 & 0017) << 12 | (c2 & 0077) << 6 | (c3 & 0077);
- }
- else if ((c1 & 0370) == 0360) {
- // 1111.0xxx: 4 byte sequence
- if(p+3 >= text.size()) throw std::range_error("Malformed utf-8 sequence");
- uint32_t c2 = (unsigned char) text[p+1];
- uint32_t c3 = (unsigned char) text[p+2];
- uint32_t c4 = (unsigned char) text[p+4];
- if (!has_multibyte_mark(c2)) throw std::runtime_error("Malformed utf-8 sequence");
- if (!has_multibyte_mark(c3)) throw std::runtime_error("Malformed utf-8 sequence");
- if (!has_multibyte_mark(c4)) throw std::runtime_error("Malformed utf-8 sequence");
- p+=4;
- return (c1 & 0007) << 18 | (c2 & 0077) << 12 | (c3 & 0077) << 6 | (c4 & 0077);
- }
- throw std::runtime_error("Malformed utf-8 sequence");
-}
-
-} // namespace
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>,
-// Ingo Ruhnke <grumbel@gmx.de>
-//
-// 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.
-
-#ifndef SUPERTUX_FONT_H
-#define SUPERTUX_FONT_H
-
-#include <string>
-#include <stdint.h>
-
-#include "video/surface.hpp"
-#include "math/vector.hpp"
-#include "math/rect.hpp"
-
-class Renderer;
-
-enum FontAlignment {
- ALIGN_LEFT,
- ALIGN_CENTER,
- ALIGN_RIGHT
-};
-
-class Font
-{
-public:
- enum GlyphWidth {
- FIXED,
- VARIABLE
- };
-
- /** Construct a fixed-width font
- *
- * @param glyph_width VARIABLE for proportional fonts, VARIABLE for monospace ones
- * @param filename image file containing the characters
- * @param shadowfile image file containing the characters shadows
- * @param char_width width of a character
- * @param char_height height of a character
- */
- Font(GlyphWidth glyph_width,
- const std::string& filename, const std::string& shadowfile,
- int char_width, int char_height, int shadowsize = 2);
- ~Font();
-
- /** returns the width of a given text. (Note that I won't add a normal
- * get_width function here, as we might switch to variable width fonts in the
- * future.)
- * Supports breaklines.
- */
- float get_text_width(const std::string& text) const;
-
- /** returns the height of a given text. This function supports breaklines.
- * In case, you are positive that your text doesn't use break lines, you can
- * just use get_height().
- */
- float get_text_height(const std::string& text) const;
-
- /**
- * returns the height of the font.
- */
- float get_height() const;
-
- /**
- * returns the given string, truncated (preferrably at whitespace) to be at most max_chars characters long
- */
- static std::string wrap_to_chars(const std::string& text, int max_chars, std::string* overflow);
-
- /**
- * returns the given string, truncated (preferrably at whitespace) to be at most "width" pixels wide
- */
- std::string wrap_to_width(const std::string& text, float width, std::string* overflow);
-
- /** Draws the given text to the screen. Also needs the position.
- * Type of alignment, drawing effect and alpha are optional. */
- void draw(Renderer *renderer, const std::string& text, const Vector& pos,
- FontAlignment allignment = ALIGN_LEFT,
- DrawingEffect drawing_effect = NO_EFFECT,
- float alpha = 1.0f) const;
-
-private:
- friend class DrawingContext;
-
- void draw_text(Renderer *renderer, const std::string& text, const Vector& pos,
- DrawingEffect drawing_effect = NO_EFFECT,
- float alpha = 1.0f) const;
-
- void draw_chars(Renderer *renderer, Surface* pchars, const std::string& text,
- const Vector& position, DrawingEffect drawing_effect,
- float alpha) const;
-
- /** Convert a Unicode character code to the index of its glyph */
- int chr2glyph(uint32_t chr) const;
-
- GlyphWidth glyph_width;
- Surface* glyph_surface;
- Surface* shadow_glyph_surface;
- int char_height;
- int shadowsize;
-
- /// the number of the first character that is represented in the font
- uint32_t first_char;
- /// the number of the last character that is represented in the font
- uint32_t char_count;
-
- struct Glyph {
- /** How many pixels should the cursor advance after printing the
- glyph */
- float advance;
-
- /** Offset that is used when drawing the glyph */
- Vector offset;
-
- /** Position of the glyph inside the surface */
- Rect rect;
- };
-
- /** Location of the characters inside the surface */
- std::vector<Glyph> glyphs;
- std::vector<Glyph> shadow_glyphs;
-};
-
-#endif
+++ /dev/null
-// $Id: gl_lightmap.cpp 5063 2007-05-27 11:32:00Z matzeb $
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#include <config.h>
-
-#ifdef HAVE_OPENGL
-
-#include <functional>
-#include <algorithm>
-#include <cassert>
-#include <math.h>
-#include <iostream>
-#include <SDL_image.h>
-#include <sstream>
-#include <iomanip>
-#include <physfs.h>
-
-#include "glutil.hpp"
-#include "gl_lightmap.hpp"
-#include "gl_surface_data.hpp"
-#include "drawing_context.hpp"
-#include "drawing_request.hpp"
-#include "renderer.hpp"
-#include "surface.hpp"
-#include "font.hpp"
-#include "main.hpp"
-#include "gameconfig.hpp"
-#include "gl_texture.hpp"
-#include "texture_manager.hpp"
-#include "obstack/obstackpp.hpp"
-
-namespace
-{
- inline void intern_draw(float left, float top, float right, float bottom,
- float uv_left, float uv_top,
- float uv_right, float uv_bottom,
- float angle, float alpha,
- const Color& color,
- const Blend& blend,
- DrawingEffect effect)
- {
- if(effect & HORIZONTAL_FLIP)
- std::swap(uv_left, uv_right);
- if(effect & VERTICAL_FLIP) {
- std::swap(uv_top, uv_bottom);
- }
-
- float center_x = (left + right) / 2;
- float center_y = (top + bottom) / 2;
-
- float sa = sinf(angle/180.0f*M_PI);
- float ca = cosf(angle/180.0f*M_PI);
-
- left -= center_x;
- right -= center_x;
-
- top -= center_y;
- bottom -= center_y;
-
- glBlendFunc(blend.sfactor, blend.dfactor);
- glColor4f(color.red, color.green, color.blue, color.alpha * alpha);
- glBegin(GL_QUADS);
- glTexCoord2f(uv_left, uv_top);
- glVertex2f(left*ca - top*sa + center_x,
- left*sa + top*ca + center_y);
-
- glTexCoord2f(uv_right, uv_top);
- glVertex2f(right*ca - top*sa + center_x,
- right*sa + top*ca + center_y);
-
- glTexCoord2f(uv_right, uv_bottom);
- glVertex2f(right*ca - bottom*sa + center_x,
- right*sa + bottom*ca + center_y);
-
- glTexCoord2f(uv_left, uv_bottom);
- glVertex2f(left*ca - bottom*sa + center_x,
- left*sa + bottom*ca + center_y);
- glEnd();
-
- // FIXME: find a better way to restore the blend mode
- glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- }
-}
-
-namespace GL
-{
- static inline int next_po2(int val)
- {
- int result = 1;
- while(result < val)
- result *= 2;
-
- return result;
- }
-
- Lightmap::Lightmap()
- {
- screen = SDL_GetVideoSurface();
-
- lightmap_width = screen->w / LIGHTMAP_DIV;
- lightmap_height = screen->h / LIGHTMAP_DIV;
- unsigned int width = next_po2(lightmap_width);
- unsigned int height = next_po2(lightmap_height);
-
- lightmap = new Texture(width, height);
-
- lightmap_uv_right = static_cast<float>(lightmap_width) / static_cast<float>(width);
- lightmap_uv_bottom = static_cast<float>(lightmap_height) / static_cast<float>(height);
- texture_manager->register_texture(lightmap);
- }
-
- Lightmap::~Lightmap()
- {
- texture_manager->remove_texture(lightmap);
- delete lightmap;
- }
-
- void
- Lightmap::start_draw(const Color &ambient_color)
- {
- glViewport(0, screen->h - lightmap_height, lightmap_width, lightmap_height);
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- glOrtho(0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, -1.0, 1.0);
- glMatrixMode(GL_MODELVIEW);
- glLoadIdentity();
-
- glClearColor( ambient_color.red, ambient_color.green, ambient_color.blue, 1 );
- glClear(GL_COLOR_BUFFER_BIT);
- }
-
- void
- Lightmap::end_draw()
- {
- glDisable(GL_BLEND);
- glBindTexture(GL_TEXTURE_2D, lightmap->get_handle());
- glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, screen->h - lightmap_height, lightmap_width, lightmap_height);
-
- glViewport(0, 0, screen->w, screen->h);
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- glOrtho(0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, -1.0, 1.0);
- glMatrixMode(GL_MODELVIEW);
- glLoadIdentity();
- glEnable(GL_BLEND);
- //glClear(GL_COLOR_BUFFER_BIT);
- }
-
- void
- Lightmap::do_draw()
- {
- const Texture* texture = lightmap;
-
- // multiple the lightmap with the framebuffer
- glBlendFunc(GL_DST_COLOR, GL_ZERO);
-
- glBindTexture(GL_TEXTURE_2D, texture->get_handle());
- glBegin(GL_QUADS);
-
- glTexCoord2f(0, lightmap_uv_bottom);
- glVertex2f(0, 0);
-
- glTexCoord2f(lightmap_uv_right, lightmap_uv_bottom);
- glVertex2f(SCREEN_WIDTH, 0);
-
- glTexCoord2f(lightmap_uv_right, 0);
- glVertex2f(SCREEN_WIDTH, SCREEN_HEIGHT);
-
- glTexCoord2f(0, 0);
- glVertex2f(0, SCREEN_HEIGHT);
-
- glEnd();
-
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- }
-
- void
- Lightmap::draw_surface(const DrawingRequest& request)
- {
- const Surface* surface = (const Surface*) request.request_data;
- GL::Texture *gltexture = dynamic_cast<GL::Texture *>(surface->get_texture());
- GL::SurfaceData *surface_data = reinterpret_cast<GL::SurfaceData *>(surface->get_surface_data());
-
- glBindTexture(GL_TEXTURE_2D, gltexture->get_handle());
- intern_draw(request.pos.x, request.pos.y,
- request.pos.x + surface->get_width(),
- request.pos.y + surface->get_height(),
- surface_data->get_uv_left(),
- surface_data->get_uv_top(),
- surface_data->get_uv_right(),
- surface_data->get_uv_bottom(),
- request.angle,
- request.alpha,
- request.color,
- request.blend,
- request.drawing_effect);
- }
-
- void
- Lightmap::draw_surface_part(const DrawingRequest& request)
- {
- const SurfacePartRequest* surfacepartrequest
- = (SurfacePartRequest*) request.request_data;
- const Surface *surface = surfacepartrequest->surface;
- GL::Texture *gltexture = dynamic_cast<GL::Texture *>(surface->get_texture());
- GL::SurfaceData *surface_data = reinterpret_cast<GL::SurfaceData *>(surface->get_surface_data());
-
- float uv_width = surface_data->get_uv_right() - surface_data->get_uv_left();
- float uv_height = surface_data->get_uv_bottom() - surface_data->get_uv_top();
-
- float uv_left = surface_data->get_uv_left() + (uv_width * surfacepartrequest->source.x) / surface->get_width();
- float uv_top = surface_data->get_uv_top() + (uv_height * surfacepartrequest->source.y) / surface->get_height();
- float uv_right = surface_data->get_uv_left() + (uv_width * (surfacepartrequest->source.x + surfacepartrequest->size.x)) / surface->get_width();
- float uv_bottom = surface_data->get_uv_top() + (uv_height * (surfacepartrequest->source.y + surfacepartrequest->size.y)) / surface->get_height();
-
- glBindTexture(GL_TEXTURE_2D, gltexture->get_handle());
- intern_draw(request.pos.x, request.pos.y,
- request.pos.x + surfacepartrequest->size.x,
- request.pos.y + surfacepartrequest->size.y,
- uv_left,
- uv_top,
- uv_right,
- uv_bottom,
- 0.0,
- request.alpha,
- Color(1.0, 1.0, 1.0),
- Blend(),
- request.drawing_effect);
- }
-
- void
- Lightmap::draw_gradient(const DrawingRequest& request)
- {
- const GradientRequest* gradientrequest
- = (GradientRequest*) request.request_data;
- const Color& top = gradientrequest->top;
- const Color& bottom = gradientrequest->bottom;
-
- glDisable(GL_TEXTURE_2D);
- glBegin(GL_QUADS);
- glColor4f(top.red, top.green, top.blue, top.alpha);
- glVertex2f(0, 0);
- glVertex2f(SCREEN_WIDTH, 0);
- glColor4f(bottom.red, bottom.green, bottom.blue, bottom.alpha);
- glVertex2f(SCREEN_WIDTH, SCREEN_HEIGHT);
- glVertex2f(0, SCREEN_HEIGHT);
- glEnd();
- glEnable(GL_TEXTURE_2D);
- glColor4f(1, 1, 1, 1);
- }
-
- void
- Lightmap::draw_filled_rect(const DrawingRequest& request)
- {
- const FillRectRequest* fillrectrequest
- = (FillRectRequest*) request.request_data;
-
- float x = request.pos.x;
- float y = request.pos.y;
- float w = fillrectrequest->size.x;
- float h = fillrectrequest->size.y;
-
- glDisable(GL_TEXTURE_2D);
- glColor4f(fillrectrequest->color.red, fillrectrequest->color.green,
- fillrectrequest->color.blue, fillrectrequest->color.alpha);
-
- glBegin(GL_QUADS);
- glVertex2f(x, y);
- glVertex2f(x+w, y);
- glVertex2f(x+w, y+h);
- glVertex2f(x, y+h);
- glEnd();
- glEnable(GL_TEXTURE_2D);
- glColor4f(1, 1, 1, 1);
- }
-
- void
- Lightmap::get_light(const DrawingRequest& request) const
- {
- const GetLightRequest* getlightrequest
- = (GetLightRequest*) request.request_data;
-
- float pixels[3];
- for( int i = 0; i<3; i++)
- pixels[i] = 0.0f; //set to black
-
- float posX = request.pos.x * lightmap_width / SCREEN_WIDTH;
- float posY = screen->h - request.pos.y * lightmap_height / SCREEN_HEIGHT;
- glReadPixels((GLint) posX, (GLint) posY , 1, 1, GL_RGB, GL_FLOAT, pixels);
- *(getlightrequest->color_ptr) = Color( pixels[0], pixels[1], pixels[2]);
- //printf("get_light %f/%f =>%f/%f r%f g%f b%f\n", request.pos.x, request.pos.y, posX, posY, pixels[0], pixels[1], pixels[2]);
- }
-}
-
-#endif
+++ /dev/null
-// $Id: gl_lightmap.hpp 4986 2007-04-16 17:48:28Z matzeb $
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#include <config.h>
-
-#ifdef HAVE_OPENGL
-
-#ifndef SUPERTUX_GL_LIGHTMAP_H
-#define SUPERTUX_GL_LIGHTMAP_H
-
-#include <SDL_video.h>
-
-#include "lightmap.hpp"
-
-struct DrawingRequest;
-
-namespace GL
-{
- class Texture;
- class Lightmap : public ::Lightmap
- {
- public:
- Lightmap();
- ~Lightmap();
-
- void start_draw(const Color &ambient_color);
- void end_draw();
- void do_draw();
- void draw_surface(const DrawingRequest& request);
- void draw_surface_part(const DrawingRequest& request);
- void draw_text(const DrawingRequest& request);
- void draw_gradient(const DrawingRequest& request);
- void draw_filled_rect(const DrawingRequest& request);
- void get_light(const DrawingRequest& request) const;
-
- private:
- static const int LIGHTMAP_DIV = 5;
-
- SDL_Surface* screen;
- Texture* lightmap;
- int lightmap_width, lightmap_height;
- float lightmap_uv_right, lightmap_uv_bottom;
- };
-}
-
-#endif
-
-#endif
+++ /dev/null
-// $Id: gl_renderer.cpp 5063 2007-05-27 11:32:00Z matzeb $
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#include <config.h>
-
-#ifdef HAVE_OPENGL
-
-#include <functional>
-#include <algorithm>
-#include <cassert>
-#include <math.h>
-#include <iostream>
-#include <SDL_image.h>
-#include <sstream>
-#include <iomanip>
-#include <physfs.h>
-
-#include "glutil.hpp"
-#include "gl_renderer.hpp"
-#include "gl_texture.hpp"
-#include "gl_surface_data.hpp"
-#include "drawing_context.hpp"
-#include "drawing_request.hpp"
-#include "surface.hpp"
-#include "font.hpp"
-#include "main.hpp"
-#include "gameconfig.hpp"
-#include "texture.hpp"
-#include "texture_manager.hpp"
-#include "obstack/obstackpp.hpp"
-#define LIGHTMAP_DIV 5
-
-namespace
-{
- inline void intern_draw(float left, float top, float right, float bottom,
- float uv_left, float uv_top,
- float uv_right, float uv_bottom,
- float angle, float alpha,
- const Color& color,
- const Blend& blend,
- DrawingEffect effect)
- {
- if(effect & HORIZONTAL_FLIP)
- std::swap(uv_left, uv_right);
- if(effect & VERTICAL_FLIP) {
- std::swap(uv_top, uv_bottom);
- }
-
- float center_x = (left + right) / 2;
- float center_y = (top + bottom) / 2;
-
- float sa = sinf(angle/180.0f*M_PI);
- float ca = cosf(angle/180.0f*M_PI);
-
- left -= center_x;
- right -= center_x;
-
- top -= center_y;
- bottom -= center_y;
-
- glBlendFunc(blend.sfactor, blend.dfactor);
- glColor4f(color.red, color.green, color.blue, color.alpha * alpha);
- glBegin(GL_QUADS);
- glTexCoord2f(uv_left, uv_top);
- glVertex2f(left*ca - top*sa + center_x,
- left*sa + top*ca + center_y);
-
- glTexCoord2f(uv_right, uv_top);
- glVertex2f(right*ca - top*sa + center_x,
- right*sa + top*ca + center_y);
-
- glTexCoord2f(uv_right, uv_bottom);
- glVertex2f(right*ca - bottom*sa + center_x,
- right*sa + bottom*ca + center_y);
-
- glTexCoord2f(uv_left, uv_bottom);
- glVertex2f(left*ca - bottom*sa + center_x,
- left*sa + bottom*ca + center_y);
- glEnd();
-
- // FIXME: find a better way to restore the blend mode
- glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- }
-}
-
-namespace GL
-{
- Renderer::Renderer()
- {
- if(texture_manager != 0)
- texture_manager->save_textures();
-
- if(config->try_vsync) {
- /* we want vsync for smooth scrolling */
- SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL, 1);
- }
-
- SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
- SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 5);
- SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 5);
- SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 5);
-
- int flags = SDL_OPENGL;
- if(config->use_fullscreen)
- flags |= SDL_FULLSCREEN;
- int width = config->screenwidth;
- int height = config->screenheight;
- int bpp = 0;
-
- SDL_Surface *screen = SDL_SetVideoMode(width, height, bpp, flags);
- if(screen == 0) {
- std::stringstream msg;
- msg << "Couldn't set video mode (" << width << "x" << height
- << "-" << bpp << "bpp): " << SDL_GetError();
- throw std::runtime_error(msg.str());
- }
-
- // setup opengl state and transform
- glDisable(GL_DEPTH_TEST);
- glDisable(GL_CULL_FACE);
- glEnable(GL_TEXTURE_2D);
- glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-
- glViewport(0, 0, screen->w, screen->h);
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- // logical resolution here not real monitor resolution
- glOrtho(0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, -1.0, 1.0);
- glMatrixMode(GL_MODELVIEW);
- glLoadIdentity();
- glTranslatef(0, 0, 0);
-
- check_gl_error("Setting up view matrices");
-
-
- if(texture_manager == 0)
- texture_manager = new TextureManager();
- else
- texture_manager->reload_textures();
- }
-
- Renderer::~Renderer()
- {
- }
-
- void
- Renderer::draw_surface(const DrawingRequest& request)
- {
- const Surface* surface = (const Surface*) request.request_data;
- GL::Texture *gltexture = dynamic_cast<GL::Texture *>(surface->get_texture());
- GL::SurfaceData *surface_data = reinterpret_cast<GL::SurfaceData *>(surface->get_surface_data());
-
- glBindTexture(GL_TEXTURE_2D, gltexture->get_handle());
- intern_draw(request.pos.x, request.pos.y,
- request.pos.x + surface->get_width(),
- request.pos.y + surface->get_height(),
- surface_data->get_uv_left(),
- surface_data->get_uv_top(),
- surface_data->get_uv_right(),
- surface_data->get_uv_bottom(),
- request.angle,
- request.alpha,
- request.color,
- request.blend,
- request.drawing_effect);
- }
-
- void
- Renderer::draw_surface_part(const DrawingRequest& request)
- {
- const SurfacePartRequest* surfacepartrequest
- = (SurfacePartRequest*) request.request_data;
- const Surface *surface = surfacepartrequest->surface;
- GL::Texture *gltexture = dynamic_cast<GL::Texture *>(surface->get_texture());
- GL::SurfaceData *surface_data = reinterpret_cast<GL::SurfaceData *>(surface->get_surface_data());
-
- float uv_width = surface_data->get_uv_right() - surface_data->get_uv_left();
- float uv_height = surface_data->get_uv_bottom() - surface_data->get_uv_top();
-
- float uv_left = surface_data->get_uv_left() + (uv_width * surfacepartrequest->source.x) / surface->get_width();
- float uv_top = surface_data->get_uv_top() + (uv_height * surfacepartrequest->source.y) / surface->get_height();
- float uv_right = surface_data->get_uv_left() + (uv_width * (surfacepartrequest->source.x + surfacepartrequest->size.x)) / surface->get_width();
- float uv_bottom = surface_data->get_uv_top() + (uv_height * (surfacepartrequest->source.y + surfacepartrequest->size.y)) / surface->get_height();
-
- glBindTexture(GL_TEXTURE_2D, gltexture->get_handle());
- intern_draw(request.pos.x, request.pos.y,
- request.pos.x + surfacepartrequest->size.x,
- request.pos.y + surfacepartrequest->size.y,
- uv_left,
- uv_top,
- uv_right,
- uv_bottom,
- 0.0,
- request.alpha,
- Color(1.0, 1.0, 1.0),
- Blend(),
- request.drawing_effect);
- }
-
- void
- Renderer::draw_gradient(const DrawingRequest& request)
- {
- const GradientRequest* gradientrequest
- = (GradientRequest*) request.request_data;
- const Color& top = gradientrequest->top;
- const Color& bottom = gradientrequest->bottom;
-
- glDisable(GL_TEXTURE_2D);
- glBegin(GL_QUADS);
- glColor4f(top.red, top.green, top.blue, top.alpha);
- glVertex2f(0, 0);
- glVertex2f(SCREEN_WIDTH, 0);
- glColor4f(bottom.red, bottom.green, bottom.blue, bottom.alpha);
- glVertex2f(SCREEN_WIDTH, SCREEN_HEIGHT);
- glVertex2f(0, SCREEN_HEIGHT);
- glEnd();
- glEnable(GL_TEXTURE_2D);
- glColor4f(1, 1, 1, 1);
- }
-
- void
- Renderer::draw_filled_rect(const DrawingRequest& request)
- {
- const FillRectRequest* fillrectrequest
- = (FillRectRequest*) request.request_data;
-
- float x = request.pos.x;
- float y = request.pos.y;
- float w = fillrectrequest->size.x;
- float h = fillrectrequest->size.y;
-
- glDisable(GL_TEXTURE_2D);
- glColor4f(fillrectrequest->color.red, fillrectrequest->color.green,
- fillrectrequest->color.blue, fillrectrequest->color.alpha);
-
- glBegin(GL_QUADS);
- glVertex2f(x, y);
- glVertex2f(x+w, y);
- glVertex2f(x+w, y+h);
- glVertex2f(x, y+h);
- glEnd();
- glEnable(GL_TEXTURE_2D);
- glColor4f(1, 1, 1, 1);
- }
-
- void
- Renderer::do_take_screenshot()
- {
- // [Christoph] TODO: Yes, this method also takes care of the actual disk I/O. Split it?
-
- SDL_Surface *shot_surf;
- // create surface to hold screenshot
- #if SDL_BYTEORDER == SDL_BIG_ENDIAN
- shot_surf = SDL_CreateRGBSurface(SDL_SWSURFACE, SCREEN_WIDTH, SCREEN_HEIGHT, 24, 0x00FF0000, 0x0000FF00, 0x000000FF, 0);
- #else
- shot_surf = SDL_CreateRGBSurface(SDL_SWSURFACE, SCREEN_WIDTH, SCREEN_HEIGHT, 24, 0x000000FF, 0x0000FF00, 0x00FF0000, 0);
- #endif
- if (!shot_surf) {
- log_warning << "Could not create RGB Surface to contain screenshot" << std::endl;
- return;
- }
-
- // read pixels into array
- char* pixels = new char[3 * SCREEN_WIDTH * SCREEN_HEIGHT];
- if (!pixels) {
- log_warning << "Could not allocate memory to store screenshot" << std::endl;
- SDL_FreeSurface(shot_surf);
- return;
- }
- glReadPixels(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, GL_RGB, GL_UNSIGNED_BYTE, pixels);
-
- // copy array line-by-line
- for (int i = 0; i < SCREEN_HEIGHT; i++) {
- char* src = pixels + (3 * SCREEN_WIDTH * (SCREEN_HEIGHT - i - 1));
- if(SDL_MUSTLOCK(shot_surf))
- {
- SDL_LockSurface(shot_surf);
- }
- char* dst = ((char*)shot_surf->pixels) + i * shot_surf->pitch;
- memcpy(dst, src, 3 * SCREEN_WIDTH);
- if(SDL_MUSTLOCK(shot_surf))
- {
- SDL_UnlockSurface(shot_surf);
- }
- }
-
- // free array
- delete[](pixels);
-
- // save screenshot
- static const std::string writeDir = PHYSFS_getWriteDir();
- static const std::string dirSep = PHYSFS_getDirSeparator();
- static const std::string baseName = "screenshot";
- static const std::string fileExt = ".bmp";
- std::string fullFilename;
- for (int num = 0; num < 1000; num++) {
- std::ostringstream oss;
- oss << baseName;
- oss << std::setw(3) << std::setfill('0') << num;
- oss << fileExt;
- std::string fileName = oss.str();
- fullFilename = writeDir + dirSep + fileName;
- if (!PHYSFS_exists(fileName.c_str())) {
- SDL_SaveBMP(shot_surf, fullFilename.c_str());
- log_debug << "Wrote screenshot to \"" << fullFilename << "\"" << std::endl;
- SDL_FreeSurface(shot_surf);
- return;
- }
- }
- log_warning << "Did not save screenshot, because all files up to \"" << fullFilename << "\" already existed" << std::endl;
- SDL_FreeSurface(shot_surf);
- }
-
- void
- Renderer::flip()
- {
- assert_gl("drawing");
- SDL_GL_SwapBuffers();
- }
-}
-
-#endif
+++ /dev/null
-// $Id: gl_renderer.hpp 4986 2007-04-16 17:48:28Z matzeb $
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#include <config.h>
-
-#ifdef HAVE_OPENGL
-
-#ifndef SUPERTUX_GL_RENDERER_H
-#define SUPERTUX_GL_RENDERER_H
-
-#include "renderer.hpp"
-
-namespace GL
-{
- class Renderer : public ::Renderer
- {
- public:
- Renderer();
- ~Renderer();
-
- void draw_surface(const DrawingRequest& request);
- void draw_surface_part(const DrawingRequest& request);
- void draw_text(const DrawingRequest& request);
- void draw_gradient(const DrawingRequest& request);
- void draw_filled_rect(const DrawingRequest& request);
- void do_take_screenshot();
- void flip();
- };
-}
-
-#endif
-
-#endif
+++ /dev/null
-// $Id: gl_surface_data.hpp 4063 2006-07-21 21:05:23Z anmaster $
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#include <config.h>
-
-#ifdef HAVE_OPENGL
-
-#ifndef __GL_SURFACE_DATA_HPP__
-#define __GL_SURFACE_DATA_HPP__
-
-#include "surface.hpp"
-
-namespace GL
-{
- class SurfaceData
- {
- private:
- const Surface &surface;
- float uv_left;
- float uv_top;
- float uv_right;
- float uv_bottom;
-
- public:
- SurfaceData(const Surface &surface) :
- surface(surface)
- {
- uv_left = (float) surface.get_x() / surface.get_texture()->get_texture_width();
- uv_top = (float) surface.get_y() / surface.get_texture()->get_texture_height();
- uv_right = (float) (surface.get_x() + surface.get_width()) / surface.get_texture()->get_texture_width();
- uv_bottom = (float) (surface.get_y() + surface.get_height()) / surface.get_texture()->get_texture_height();
- }
-
- float get_uv_left() const
- {
- return surface.get_flipx() ? uv_right : uv_left;
- }
-
- float get_uv_top() const
- {
- return uv_top;
- }
-
- float get_uv_right() const
- {
- return surface.get_flipx() ? uv_left : uv_right;
- }
-
- float get_uv_bottom() const
- {
- return uv_bottom;
- }
- };
-}
-
-#endif
-
-#endif
+++ /dev/null
-// $Id: gl_texture.cpp 4063 2006-07-21 21:05:23Z anmaster $
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#ifdef HAVE_OPENGL
-
-#include "gl_texture.hpp"
-#include "gameconfig.hpp"
-#include "glutil.hpp"
-#include "log.hpp"
-
-#include <assert.h>
-#include <stdexcept>
-
-namespace
-{
- inline bool is_power_of_2(int v)
- {
- return (v & (v-1)) == 0;
- }
-
- inline int next_power_of_two(int val)
- {
- int result = 1;
- while(result < val)
- result *= 2;
- return result;
- }
-}
-
-namespace GL
-{
- Texture::Texture(unsigned int width, unsigned int height)
- {
- assert(is_power_of_2(width));
- assert(is_power_of_2(height));
- texture_width = width;
- texture_height = height;
- image_width = width;
- image_height = height;
-
- assert_gl("before creating texture");
- glGenTextures(1, &handle);
-
- try {
- glBindTexture(GL_TEXTURE_2D, handle);
-
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texture_width,
- texture_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
-
- set_texture_params();
- } catch(...) {
- glDeleteTextures(1, &handle);
- throw;
- }
- }
-
- Texture::Texture(SDL_Surface* image)
- {
- texture_width = next_power_of_two(image->w);
- texture_height = next_power_of_two(image->h);
- image_width = image->w;
- image_height = image->h;
-
-#if SDL_BYTEORDER == SDL_BIG_ENDIAN
- SDL_Surface* convert = SDL_CreateRGBSurface(SDL_SWSURFACE,
- texture_width, texture_height, 32,
- 0xff000000, 0x00ff0000, 0x0000ff00, 0x000000ff);
-#else
- SDL_Surface* convert = SDL_CreateRGBSurface(SDL_SWSURFACE,
- texture_width, texture_height, 32,
- 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000);
-#endif
-
- if(convert == 0) {
- throw std::runtime_error("Couldn't create texture: out of memory");
- }
-
- SDL_SetAlpha(image, 0, 0);
- SDL_BlitSurface(image, 0, convert, 0);
-
- assert_gl("before creating texture");
- glGenTextures(1, &handle);
-
- try {
- GLenum sdl_format;
- if(convert->format->BytesPerPixel == 3)
- sdl_format = GL_RGB;
- else if(convert->format->BytesPerPixel == 4)
- sdl_format = GL_RGBA;
- else
- assert(false);
-
- glBindTexture(GL_TEXTURE_2D, handle);
- glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
- glPixelStorei(GL_UNPACK_ROW_LENGTH, convert->pitch/convert->format->BytesPerPixel);
- if(SDL_MUSTLOCK(convert))
- {
- SDL_LockSurface(convert);
- }
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texture_width,
- texture_height, 0, sdl_format,
- GL_UNSIGNED_BYTE, convert->pixels);
- if(SDL_MUSTLOCK(convert))
- {
- SDL_UnlockSurface(convert);
- }
-
- assert_gl("creating texture");
-
- set_texture_params();
- } catch(...) {
- glDeleteTextures(1, &handle);
- SDL_FreeSurface(convert);
- throw;
- }
- SDL_FreeSurface(convert);
- }
-
- Texture::~Texture()
- {
- glDeleteTextures(1, &handle);
- }
-
- void
- Texture::set_texture_params()
- {
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
-
- assert_gl("set texture params");
- }
-}
-
-#endif
+++ /dev/null
-// $Id: gl_texture.hpp 4063 2006-07-21 21:05:23Z anmaster $
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#include <config.h>
-
-#ifdef HAVE_OPENGL
-
-#ifndef __GL_TEXTURE_HPP__
-#define __GL_TEXTURE_HPP__
-
-#include <SDL.h>
-
-#include "texture.hpp"
-#include "glutil.hpp"
-
-/**
- * This class is a wrapper around a texture handle. It stores the texture width
- * and height and provides convenience functions for uploading SDL_Surfaces
- * into the texture
- */
-namespace GL
-{
- class Texture : public ::Texture
- {
- protected:
- GLuint handle;
- unsigned int texture_width;
- unsigned int texture_height;
- unsigned int image_width;
- unsigned int image_height;
-
- public:
- Texture(unsigned int width, unsigned int height);
- Texture(SDL_Surface* image);
- ~Texture();
-
- const GLuint &get_handle() const {
- return handle;
- }
-
- void set_handle(GLuint handle) {
- this->handle = handle;
- }
-
- unsigned int get_texture_width() const
- {
- return texture_width;
- }
-
- unsigned int get_texture_height() const
- {
- return texture_height;
- }
-
- unsigned int get_image_width() const
- {
- return image_width;
- }
-
- unsigned int get_image_height() const
- {
- return image_height;
- }
-
- void set_image_width(unsigned int width)
- {
- image_width = width;
- }
-
- void set_image_height(unsigned int height)
- {
- image_height = height;
- }
-
- private:
- void set_texture_params();
- };
-}
-
-#endif
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#ifndef __GLUTIL_HPP__
-#define __GLUTIL_HPP__
-
-#include <config.h>
-
-#ifdef HAVE_OPENGL
-
-#include <sstream>
-#include <stdexcept>
-
-#ifndef MACOSX
-#include <GL/gl.h>
-#include <GL/glext.h>
-#else
-#include <OpenGL/gl.h>
-#include <OpenGL/glext.h>
-#endif
-
-static inline void check_gl_error(const char* message)
-{
-#ifdef DEBUG
- GLenum error = glGetError();
- if(error != GL_NO_ERROR) {
- std::ostringstream msg;
- msg << "OpenGLError while '" << message << "': ";
- switch(error) {
- case GL_INVALID_ENUM:
- msg << "INVALID_ENUM: An unacceptable value is specified for an "
- "enumerated argument.";
- break;
- case GL_INVALID_VALUE:
- msg << "INVALID_VALUE: A numeric argument is out of range.";
- break;
- case GL_INVALID_OPERATION:
- msg << "INVALID_OPERATION: The specified operation is not allowed "
- "in the current state.";
- break;
- case GL_STACK_OVERFLOW:
- msg << "STACK_OVERFLOW: This command would cause a stack overflow.";
- break;
- case GL_STACK_UNDERFLOW:
- msg << "STACK_UNDERFLOW: This command would cause a stack underflow.";
- break;
- case GL_OUT_OF_MEMORY:
- msg << "OUT_OF_MEMORY: There is not enough memory left to execute the "
- "command.";
- break;
-#ifdef GL_TABLE_TOO_LARGE
- case GL_TABLE_TOO_LARGE:
- msg << "TABLE_TOO_LARGE: table is too large";
- break;
-#endif
- default:
- msg << "Unknown error (code " << error << ")";
- }
-
- throw std::runtime_error(msg.str());
- }
-#else
- (void) message;
-#endif
-}
-
-static inline void assert_gl(const char* message)
-{
-#ifdef DEBUG
- check_gl_error(message);
-#else
- (void) message;
-#endif
-}
-
-#else
-
-#define GLenum int
-#define GLint int
-#define GL_SRC_ALPHA 0
-#define GL_ONE_MINUS_SRC_ALPHA 1
-#define GL_RGBA 2
-#define GL_ONE 3
-
-#endif
-
-#endif
+++ /dev/null
-// $Id: lightmap.hpp 4986 2007-04-16 17:48:28Z matzeb $
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#ifndef SUPERTUX_LIGHTMAP_H
-#define SUPERTUX_LIGHTMAP_H
-
-#include <vector>
-#include <string>
-#include <memory>
-
-#include <stdint.h>
-
-#include <SDL_video.h>
-
-#include "glutil.hpp"
-#include "obstack/obstack.h"
-#include "math/vector.hpp"
-#include "math/rect.hpp"
-#include "drawing_request.hpp"
-#include "surface.hpp"
-#include "font.hpp"
-#include "color.hpp"
-
-class Texture;
-struct DrawingRequest;
-
-class Lightmap
-{
-public:
- virtual ~Lightmap() {}
-
- virtual void start_draw(const Color &ambient_color) = 0;
- virtual void end_draw() = 0;
- virtual void do_draw() = 0;
- virtual void draw_surface(const DrawingRequest& request) = 0;
- virtual void draw_surface_part(const DrawingRequest& request) = 0;
- virtual void draw_gradient(const DrawingRequest& request) = 0;
- virtual void draw_filled_rect(const DrawingRequest& request) = 0;
- virtual void get_light(const DrawingRequest& request) const = 0;
-};
-
-#endif
-
+++ /dev/null
-// $Id: drawing_context.hpp 4986 2007-04-16 17:48:28Z matzeb $
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#ifndef SUPERTUX_RENDERER_H
-#define SUPERTUX_RENDERER_H
-
-#include <vector>
-#include <string>
-#include <memory>
-
-#include <stdint.h>
-
-#include <SDL_video.h>
-
-#include "glutil.hpp"
-#include "obstack/obstack.h"
-#include "math/vector.hpp"
-#include "math/rect.hpp"
-#include "surface.hpp"
-#include "font.hpp"
-#include "color.hpp"
-
-class Surface;
-class Texture;
-struct DrawingRequest;
-
-class Renderer
-{
-public:
- virtual ~Renderer() {}
-
- virtual void draw_surface(const DrawingRequest& request) = 0;
- virtual void draw_surface_part(const DrawingRequest& request) = 0;
- virtual void draw_gradient(const DrawingRequest& request) = 0;
- virtual void draw_filled_rect(const DrawingRequest& request)= 0;
- virtual void do_take_screenshot() = 0;
- virtual void flip() = 0;
-};
-
-#endif
-
+++ /dev/null
-// $Id: sdl_lightmap.cpp 5063 2007-05-27 11:32:00Z matzeb $
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#include <config.h>
-
-#include <functional>
-#include <algorithm>
-#include <cassert>
-#include <iostream>
-#include <SDL_image.h>
-#include <sstream>
-#include <iomanip>
-#include <physfs.h>
-
-#include "glutil.hpp"
-#include "sdl_lightmap.hpp"
-#include "sdl_texture.hpp"
-#include "sdl_surface_data.hpp"
-#include "drawing_context.hpp"
-#include "drawing_request.hpp"
-#include "renderer.hpp"
-#include "surface.hpp"
-#include "font.hpp"
-#include "main.hpp"
-#include "gameconfig.hpp"
-#include "texture.hpp"
-#include "texture_manager.hpp"
-#include "obstack/obstackpp.hpp"
-
-namespace SDL
-{
- Lightmap::Lightmap()
- {
- screen = SDL_GetVideoSurface();
-
- float xfactor = (float) config->screenwidth / SCREEN_WIDTH;
- float yfactor = (float) config->screenheight / SCREEN_HEIGHT;
- if(xfactor < yfactor)
- {
- numerator = config->screenwidth;
- denominator = SCREEN_WIDTH;
- }
- else
- {
- numerator = config->screenheight;
- denominator = SCREEN_HEIGHT;
- }
-
- LIGHTMAP_DIV = 8 * numerator / denominator;
-
- width = screen->w / LIGHTMAP_DIV;
- height = screen->h / LIGHTMAP_DIV;
-
- red_channel = (Uint8 *)malloc(width * height * sizeof(Uint8));
- green_channel = (Uint8 *)malloc(width * height * sizeof(Uint8));
- blue_channel = (Uint8 *)malloc(width * height * sizeof(Uint8));
- }
-
- Lightmap::~Lightmap()
- {
- free(red_channel);
- free(green_channel);
- free(blue_channel);
- }
-
- void
- Lightmap::start_draw(const Color &ambient_color)
- {
- memset(red_channel, (Uint8) (ambient_color.red * 255), width * height * sizeof(Uint8));
- memset(green_channel, (Uint8) (ambient_color.green * 255), width * height * sizeof(Uint8));
- memset(blue_channel, (Uint8) (ambient_color.blue * 255), width * height * sizeof(Uint8));
- }
-
- void
- Lightmap::end_draw()
- {
- }
-
-//#define BILINEAR
-
-#ifdef BILINEAR
- namespace
- {
- void merge(Uint8 color[3], Uint8 color0[3], Uint8 color1[3], int rem, int total)
- {
- color[0] = (color0[0] * (total - rem) + color1[0] * rem) / total;
- color[1] = (color0[1] * (total - rem) + color1[1] * rem) / total;
- color[2] = (color0[2] * (total - rem) + color1[2] * rem) / total;
- }
- }
-#endif
-
- void
- Lightmap::do_draw()
- {
- // FIXME: This is really slow
- if(LIGHTMAP_DIV == 1)
- {
- int bpp = screen->format->BytesPerPixel;
- if(SDL_MUSTLOCK(screen))
- {
- SDL_LockSurface(screen);
- }
- Uint8 *pixel = (Uint8 *) screen->pixels;
- int loc = 0;
- for(int y = 0;y < height;y++) {
- for(int x = 0;x < width;x++, pixel += bpp, loc++) {
- if(red_channel[loc] == 0xff && green_channel[loc] == 0xff && blue_channel[loc] == 0xff)
- {
- continue;
- }
- Uint32 mapped = 0;
- switch(bpp) {
- case 1:
- mapped = *pixel;
- break;
- case 2:
- mapped = *(Uint16 *)pixel;
- break;
- case 3:
-#if SDL_BYTEORDER == SDL_BIG_ENDIAN
- mapped |= pixel[0] << 16;
- mapped |= pixel[1] << 8;
- mapped |= pixel[2] << 0;
-#else
- mapped |= pixel[0] << 0;
- mapped |= pixel[1] << 8;
- mapped |= pixel[2] << 16;
-#endif
- break;
- case 4:
- mapped = *(Uint32 *)pixel;
- break;
- }
- Uint8 red, green, blue, alpha;
- SDL_GetRGBA(mapped, screen->format, &red, &green, &blue, &alpha);
- red = (red * red_channel[loc]) >> 8;
- green = (green * green_channel[loc]) >> 8;
- blue = (blue * blue_channel[loc]) >> 8;
- mapped = SDL_MapRGBA(screen->format, red, green, blue, alpha);
- switch(bpp) {
- case 1:
- *pixel = mapped;
- break;
- case 2:
- *(Uint16 *)pixel = mapped;
- break;
- case 3:
-#if SDL_BYTEORDER == SDL_BIG_ENDIAN
- pixel[0] = (mapped >> 16) & 0xff;
- pixel[1] = (mapped >> 8) & 0xff;
- pixel[2] = (mapped >> 0) & 0xff;
-#else
- pixel[0] = (mapped >> 0) & 0xff;
- pixel[1] = (mapped >> 8) & 0xff;
- pixel[2] = (mapped >> 16) & 0xff;
-#endif
- break;
- case 4:
- *(Uint32 *)pixel = mapped;
- break;
- }
- }
- pixel += screen->pitch - width * bpp;
- }
- if(SDL_MUSTLOCK(screen))
- {
- SDL_UnlockSurface(screen);
- }
- }
- else
- {
- int bpp = screen->format->BytesPerPixel;
- if(SDL_MUSTLOCK(screen))
- {
- SDL_LockSurface(screen);
- }
- Uint8 *div_pixel = (Uint8 *) screen->pixels;
- int loc = 0;
- for(int y = 0;y < height;y++) {
- for(int x = 0;x < width;x++, div_pixel += bpp * LIGHTMAP_DIV, loc++) {
- if(red_channel[loc] == 0xff && green_channel[loc] == 0xff && blue_channel[loc] == 0xff)
- {
- continue;
- }
- Uint8 *pixel = div_pixel;
- for(int div_y = 0;div_y < LIGHTMAP_DIV;div_y++) {
- for(int div_x = 0;div_x < LIGHTMAP_DIV;pixel += bpp, div_x++) {
- Uint32 mapped = 0;
- switch(bpp) {
- case 1:
- mapped = *pixel;
- break;
- case 2:
- mapped = *(Uint16 *)pixel;
- break;
- case 3:
-#if SDL_BYTEORDER == SDL_BIG_ENDIAN
- mapped |= pixel[0] << 16;
- mapped |= pixel[1] << 8;
- mapped |= pixel[2] << 0;
-#else
- mapped |= pixel[0] << 0;
- mapped |= pixel[1] << 8;
- mapped |= pixel[2] << 16;
-#endif
- break;
- case 4:
- mapped = *(Uint32 *)pixel;
- break;
- }
- Uint8 red, green, blue, alpha;
- SDL_GetRGBA(mapped, screen->format, &red, &green, &blue, &alpha);
-
-#ifdef BILINEAR
- int xinc = (x + 1 != width ? 1 : 0);
- int yinc = (y + 1 != height ? width : 0);
- Uint8 color00[3], color01[3], color10[3], color11[3];
- {
- color00[0] = red_channel[loc];
- color00[1] = green_channel[loc];
- color00[2] = blue_channel[loc];
- }
- {
- color01[0] = red_channel[loc + xinc];
- color01[1] = green_channel[loc + xinc];
- color01[2] = blue_channel[loc + xinc];
- }
- {
- color10[0] = red_channel[loc + yinc];
- color10[1] = green_channel[loc + yinc];
- color10[2] = blue_channel[loc + yinc];
- }
- {
- color11[0] = red_channel[loc + yinc + xinc];
- color11[1] = green_channel[loc + yinc + xinc];
- color11[2] = blue_channel[loc + yinc + xinc];
- }
- Uint8 color0[3], color1[3], color[3];
- merge(color0, color00, color01, div_x, LIGHTMAP_DIV);
- merge(color1, color10, color11, div_x, LIGHTMAP_DIV);
- merge(color, color0, color1, div_y, LIGHTMAP_DIV);
- red = (red * color[0]) >> 8;
- green = (green * color[1]) >> 8;
- blue = (blue * color[2]) >> 8;
-#else
- red = (red * red_channel[loc]) >> 8;
- green = (green * green_channel[loc]) >> 8;
- blue = (blue * blue_channel[loc]) >> 8;
-#endif
-
- mapped = SDL_MapRGBA(screen->format, red, green, blue, alpha);
- switch(bpp) {
- case 1:
- *pixel = mapped;
- break;
- case 2:
- *(Uint16 *)pixel = mapped;
- break;
- case 3:
-#if SDL_BYTEORDER == SDL_BIG_ENDIAN
- pixel[0] = (mapped >> 16) & 0xff;
- pixel[1] = (mapped >> 8) & 0xff;
- pixel[2] = (mapped >> 0) & 0xff;
-#else
- pixel[0] = (mapped >> 0) & 0xff;
- pixel[1] = (mapped >> 8) & 0xff;
- pixel[2] = (mapped >> 16) & 0xff;
-#endif
- break;
- case 4:
- *(Uint32 *)pixel = mapped;
- break;
- }
- }
- pixel += screen->pitch - LIGHTMAP_DIV * bpp;
- }
- }
- div_pixel += (screen->pitch - width * bpp) * LIGHTMAP_DIV;
- }
- if(SDL_MUSTLOCK(screen))
- {
- SDL_UnlockSurface(screen);
- }
- }
- }
-
- void Lightmap::light_blit(SDL_Surface *src, SDL_Rect *src_rect, int dstx, int dsty)
- {
- dstx /= LIGHTMAP_DIV;
- dsty /= LIGHTMAP_DIV;
- int srcx = src_rect->x / LIGHTMAP_DIV;
- int srcy = src_rect->y / LIGHTMAP_DIV;
- int blit_width = src_rect->w / LIGHTMAP_DIV;
- int blit_height = src_rect->h / LIGHTMAP_DIV;
- int bpp = src->format->BytesPerPixel;
- if(SDL_MUSTLOCK(src))
- {
- SDL_LockSurface(src);
- }
- Uint8 *pixel = (Uint8 *) src->pixels + srcy * src->pitch + srcx * bpp;
- int loc = dsty * width + dstx;
- for(int y = 0;y < blit_height;y++) {
- for(int x = 0;x < blit_width;x++, pixel += bpp * LIGHTMAP_DIV, loc++) {
- if(x + dstx < 0 || y + dsty < 0 || x + dstx >= width || y + dsty >= height)
- {
- continue;
- }
- if(red_channel[loc] == 0xff && green_channel[loc] == 0xff && blue_channel[loc] == 0xff)
- {
- continue;
- }
-
- Uint32 mapped = 0;
- switch(bpp) {
- case 1:
- mapped = *pixel;
- break;
- case 2:
- mapped = *(Uint16 *)pixel;
- break;
- case 3:
-#if SDL_BYTEORDER == SDL_BIG_ENDIAN
- mapped |= pixel[0] << 16;
- mapped |= pixel[1] << 8;
- mapped |= pixel[2] << 0;
-#else
- mapped |= pixel[0] << 0;
- mapped |= pixel[1] << 8;
- mapped |= pixel[2] << 16;
-#endif
- break;
- case 4:
- mapped = *(Uint32 *)pixel;
- break;
- }
- Uint8 red, green, blue, alpha;
- SDL_GetRGBA(mapped, src->format, &red, &green, &blue, &alpha);
-
- if(red != 0)
- {
- int redsum = red_channel[loc] + (red * alpha >> 8);
- red_channel[loc] = redsum & ~0xff ? 0xff : redsum;
- }
- if(green != 0)
- {
- int greensum = green_channel[loc] + (green * alpha >> 8);
- green_channel[loc] = greensum & ~0xff ? 0xff : greensum;
- }
- if(blue != 0)
- {
- int bluesum = blue_channel[loc] + (blue * alpha >> 8);
- blue_channel[loc] = bluesum & ~0xff ? 0xff : bluesum;
- }
- }
- pixel += (src->pitch - blit_width * bpp) * LIGHTMAP_DIV;
- loc += width - blit_width;
- }
- if(SDL_MUSTLOCK(src))
- {
- SDL_UnlockSurface(src);
- }
- }
-
- /*void Lightmap::light_blit(SDL_Surface *src, SDL_Rect *src_rect, int dstx, int dsty)
- {
- int bpp = src->format->BytesPerPixel;
- if(SDL_MUSTLOCK(src))
- {
- SDL_LockSurface(src);
- }
- Uint8 *pixel = (Uint8 *) src->pixels + src_rect->y * src->pitch + src_rect->x * bpp;
- int loc = dsty * width + dstx;
- for(int y = 0;y < src_rect->h;y++) {
- for(int x = 0;x < src_rect->w;x++, pixel += bpp, loc++) {
- if(x + dstx < 0 || y + dsty < 0 || x + dstx >= width || y + dsty >= height)
- {
- continue;
- }
- if(red_channel[loc] == 0xff && green_channel[loc] == 0xff && blue_channel[loc] == 0xff)
- {
- continue;
- }
-
- Uint32 mapped = 0;
- switch(bpp) {
- case 1:
- mapped = *pixel;
- break;
- case 2:
- mapped = *(Uint16 *)pixel;
- break;
- case 3:
-#if SDL_BYTEORDER == SDL_BIG_ENDIAN
- mapped |= pixel[0] << 16;
- mapped |= pixel[1] << 8;
- mapped |= pixel[2] << 0;
-#else
- mapped |= pixel[0] << 0;
- mapped |= pixel[1] << 8;
- mapped |= pixel[2] << 16;
-#endif
- break;
- case 4:
- mapped = *(Uint32 *)pixel;
- break;
- }
- Uint8 red, green, blue, alpha;
- SDL_GetRGBA(mapped, src->format, &red, &green, &blue, &alpha);
-
- if(red != 0)
- {
- int redsum = red_channel[loc] + (red * alpha >> 8);
- red_channel[loc] = redsum & ~0xff ? 0xff : redsum;
- }
- if(green != 0)
- {
- int greensum = green_channel[loc] + (green * alpha >> 8);
- green_channel[loc] = greensum & ~0xff ? 0xff : greensum;
- }
- if(blue != 0)
- {
- int bluesum = blue_channel[loc] + (blue * alpha >> 8);
- blue_channel[loc] = bluesum & ~0xff ? 0xff : bluesum;
- }
- }
- pixel += src->pitch - src_rect->w * bpp;
- loc += width - src_rect->w;
- }
- if(SDL_MUSTLOCK(src))
- {
- SDL_UnlockSurface(src);
- }
- }*/
-
- void
- Lightmap::draw_surface(const DrawingRequest& request)
- {
- if((request.color.red == 0.0 && request.color.green == 0.0 && request.color.blue == 0.0) || request.color.alpha == 0.0 || request.alpha == 0.0)
- {
- return;
- }
- //FIXME: support parameters request.alpha, request.angle, request.blend
-
- const Surface* surface = (const Surface*) request.request_data;
- SDL::Texture *sdltexture = dynamic_cast<SDL::Texture *>(surface->get_texture());
- SDL::SurfaceData *surface_data = reinterpret_cast<SDL::SurfaceData *>(surface->get_surface_data());
-
- DrawingEffect effect = request.drawing_effect;
- if (surface->get_flipx()) effect = HORIZONTAL_FLIP;
-
- SDL_Surface *transform = sdltexture->get_transform(request.color, effect);
-
- // get and check SDL_Surface
- if (transform == 0) {
- std::cerr << "Warning: Tried to draw NULL surface, skipped draw" << std::endl;
- return;
- }
-
- SDL_Rect *src_rect = surface_data->get_src_rect(effect);
- int dstx = (int) request.pos.x * numerator / denominator;
- int dsty = (int) request.pos.y * numerator / denominator;
- light_blit(transform, src_rect, dstx, dsty);
- }
-
- void
- Lightmap::draw_surface_part(const DrawingRequest& request)
- {
- const SurfacePartRequest* surfacepartrequest
- = (SurfacePartRequest*) request.request_data;
-
- const Surface* surface = surfacepartrequest->surface;
- SDL::Texture *sdltexture = dynamic_cast<SDL::Texture *>(surface->get_texture());
-
- DrawingEffect effect = request.drawing_effect;
- if (surface->get_flipx()) effect = HORIZONTAL_FLIP;
-
- SDL_Surface *transform = sdltexture->get_transform(Color(1.0, 1.0, 1.0), effect);
-
- // get and check SDL_Surface
- if (transform == 0) {
- std::cerr << "Warning: Tried to draw NULL surface, skipped draw" << std::endl;
- return;
- }
-
- int ox, oy;
- if (effect == HORIZONTAL_FLIP)
- {
- ox = sdltexture->get_texture_width() - surface->get_x() - (int) surfacepartrequest->size.x;
- }
- else
- {
- ox = surface->get_x();
- }
- if (effect == VERTICAL_FLIP)
- {
- oy = sdltexture->get_texture_height() - surface->get_y() - (int) surfacepartrequest->size.y;
- }
- else
- {
- oy = surface->get_y();
- }
-
- SDL_Rect src_rect;
- src_rect.x = (ox + (int) surfacepartrequest->source.x) * numerator / denominator;
- src_rect.y = (oy + (int) surfacepartrequest->source.y) * numerator / denominator;
- src_rect.w = (int) surfacepartrequest->size.x * numerator / denominator;
- src_rect.h = (int) surfacepartrequest->size.y * numerator / denominator;
- int dstx = (int) request.pos.x * numerator / denominator;
- int dsty = (int) request.pos.y * numerator / denominator;
- light_blit(transform, &src_rect, dstx, dsty);
- }
-
- void
- Lightmap::draw_gradient(const DrawingRequest& request)
- {
- const GradientRequest* gradientrequest
- = (GradientRequest*) request.request_data;
- const Color& top = gradientrequest->top;
- const Color& bottom = gradientrequest->bottom;
-
- int loc = 0;
- for(int y = 0;y < height;++y)
- {
- Uint8 red = (Uint8)((((float)(top.red-bottom.red)/(0-height)) * y + top.red) * 255);
- Uint8 green = (Uint8)((((float)(top.green-bottom.green)/(0-height)) * y + top.green) * 255);
- Uint8 blue = (Uint8)((((float)(top.blue-bottom.blue)/(0-height)) * y + top.blue) * 255);
- Uint8 alpha = (Uint8)((((float)(top.alpha-bottom.alpha)/(0-height)) * y + top.alpha) * 255);
- for(int x = 0;x < width;x++, loc++) {
- if(red != 0)
- {
- int redsum = red_channel[loc] + (red * alpha >> 8);
- red_channel[loc] = redsum & ~0xff ? 0xff : redsum;
- }
- if(green != 0)
- {
- int greensum = green_channel[loc] + (green * alpha >> 8);
- green_channel[loc] = greensum & ~0xff ? 0xff : greensum;
- }
- if(blue != 0)
- {
- int bluesum = blue_channel[loc] + (blue * alpha >> 8);
- blue_channel[loc] = bluesum & ~0xff ? 0xff : bluesum;
- }
- }
- }
- }
-
- void
- Lightmap::draw_filled_rect(const DrawingRequest& request)
- {
- const FillRectRequest* fillrectrequest
- = (FillRectRequest*) request.request_data;
-
- int rect_x = (int) (request.pos.x * width / SCREEN_WIDTH);
- int rect_y = (int) (request.pos.y * height / SCREEN_HEIGHT);
- int rect_w = (int) (fillrectrequest->size.x * width / SCREEN_WIDTH);
- int rect_h = (int) (fillrectrequest->size.y * height / SCREEN_HEIGHT);
- Uint8 red = (Uint8) (fillrectrequest->color.red * fillrectrequest->color.alpha * 255);
- Uint8 green = (Uint8) (fillrectrequest->color.green * fillrectrequest->color.alpha * 255);
- Uint8 blue = (Uint8) (fillrectrequest->color.blue * fillrectrequest->color.alpha * 255);
- if(red == 0 && green == 0 && blue == 0)
- {
- return;
- }
- for(int y = rect_y;y < rect_y + rect_h;y++) {
- for(int x = rect_x;x < rect_x + rect_w;x++) {
- int loc = y * width + x;
- if(red != 0)
- {
- int redsum = red_channel[loc] + red;
- red_channel[loc] = redsum & ~0xff ? 0xff : redsum;
- }
- if(green != 0)
- {
- int greensum = green_channel[loc] + green;
- green_channel[loc] = greensum & ~0xff ? 0xff : greensum;
- }
- if(blue != 0)
- {
- int bluesum = blue_channel[loc] + blue;
- blue_channel[loc] = bluesum & ~0xff ? 0xff : bluesum;
- }
- }
- }
- }
-
- void
- Lightmap::get_light(const DrawingRequest& request) const
- {
- const GetLightRequest* getlightrequest
- = (GetLightRequest*) request.request_data;
-
- int x = (int) (request.pos.x * width / SCREEN_WIDTH);
- int y = (int) (request.pos.y * height / SCREEN_HEIGHT);
- int loc = y * width + x;
- *(getlightrequest->color_ptr) = Color(((float)red_channel[loc])/255, ((float)green_channel[loc])/255, ((float)blue_channel[loc])/255);
- }
-}
+++ /dev/null
-// $Id: sdl_lightmap.hpp 4986 2007-04-16 17:48:28Z matzeb $
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#ifndef SUPERTUX_SDL_LIGHTMAP_H
-#define SUPERTUX_SDL_LIGHTMAP_H
-
-#include <SDL_video.h>
-
-#include "lightmap.hpp"
-
-class Color;
-struct DrawingRequest;
-
-namespace SDL
-{
- class Lightmap : public ::Lightmap
- {
- public:
- Lightmap();
- ~Lightmap();
-
- void start_draw(const Color &ambient_color);
- void end_draw();
- void do_draw();
- void draw_surface(const DrawingRequest& request);
- void draw_surface_part(const DrawingRequest& request);
- void draw_text(const DrawingRequest& request);
- void draw_gradient(const DrawingRequest& request);
- void draw_filled_rect(const DrawingRequest& request);
- void get_light(const DrawingRequest& request) const;
-
- private:
- SDL_Surface* screen;
- Uint8 *red_channel;
- Uint8 *blue_channel;
- Uint8 *green_channel;
- int width, height;
- int numerator, denominator;
- int LIGHTMAP_DIV;
-
- void light_blit(SDL_Surface *src, SDL_Rect *src_rect, int dstx, int dsty);
- };
-}
-
-#endif
-
+++ /dev/null
-// $Id: sdl_renderer.cpp 5063 2007-05-27 11:32:00Z matzeb $
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#include <config.h>
-
-#include <functional>
-#include <algorithm>
-#include <stdexcept>
-#include <cassert>
-#include <iostream>
-#include <SDL_image.h>
-#include <sstream>
-#include <iomanip>
-#include <physfs.h>
-
-#include "glutil.hpp"
-#include "sdl_renderer.hpp"
-#include "sdl_texture.hpp"
-#include "sdl_surface_data.hpp"
-#include "drawing_context.hpp"
-#include "drawing_request.hpp"
-#include "surface.hpp"
-#include "font.hpp"
-#include "main.hpp"
-#include "gameconfig.hpp"
-#include "log.hpp"
-#include "texture.hpp"
-#include "texture_manager.hpp"
-#include "obstack/obstackpp.hpp"
-
-namespace
-{
- SDL_Surface *apply_alpha(SDL_Surface *src, float alpha_factor)
- {
- // FIXME: This is really slow
- assert(src->format->Amask);
- int alpha = (int) (alpha_factor * 256);
- SDL_Surface *dst = SDL_CreateRGBSurface(src->flags, src->w, src->h, src->format->BitsPerPixel, src->format->Rmask, src->format->Gmask, src->format->Bmask, src->format->Amask);
- int bpp = dst->format->BytesPerPixel;
- if(SDL_MUSTLOCK(src))
- {
- SDL_LockSurface(src);
- }
- if(SDL_MUSTLOCK(dst))
- {
- SDL_LockSurface(dst);
- }
- for(int y = 0;y < dst->h;y++) {
- for(int x = 0;x < dst->w;x++) {
- Uint8 *srcpixel = (Uint8 *) src->pixels + y * src->pitch + x * bpp;
- Uint8 *dstpixel = (Uint8 *) dst->pixels + y * dst->pitch + x * bpp;
- Uint32 mapped = 0;
- switch(bpp) {
- case 1:
- mapped = *srcpixel;
- break;
- case 2:
- mapped = *(Uint16 *)srcpixel;
- break;
- case 3:
-#if SDL_BYTEORDER == SDL_BIG_ENDIAN
- mapped |= srcpixel[0] << 16;
- mapped |= srcpixel[1] << 8;
- mapped |= srcpixel[2] << 0;
-#else
- mapped |= srcpixel[0] << 0;
- mapped |= srcpixel[1] << 8;
- mapped |= srcpixel[2] << 16;
-#endif
- break;
- case 4:
- mapped = *(Uint32 *)srcpixel;
- break;
- }
- Uint8 r, g, b, a;
- SDL_GetRGBA(mapped, src->format, &r, &g, &b, &a);
- mapped = SDL_MapRGBA(dst->format, r, g, b, (a * alpha) >> 8);
- switch(bpp) {
- case 1:
- *dstpixel = mapped;
- break;
- case 2:
- *(Uint16 *)dstpixel = mapped;
- break;
- case 3:
-#if SDL_BYTEORDER == SDL_BIG_ENDIAN
- dstpixel[0] = (mapped >> 16) & 0xff;
- dstpixel[1] = (mapped >> 8) & 0xff;
- dstpixel[2] = (mapped >> 0) & 0xff;
-#else
- dstpixel[0] = (mapped >> 0) & 0xff;
- dstpixel[1] = (mapped >> 8) & 0xff;
- dstpixel[2] = (mapped >> 16) & 0xff;
-#endif
- break;
- case 4:
- *(Uint32 *)dstpixel = mapped;
- break;
- }
- }
- }
- if(SDL_MUSTLOCK(dst))
- {
- SDL_UnlockSurface(dst);
- }
- if(SDL_MUSTLOCK(src))
- {
- SDL_UnlockSurface(src);
- }
- return dst;
- }
-}
-
-namespace SDL
-{
- Renderer::Renderer()
- {
- const SDL_VideoInfo *info = SDL_GetVideoInfo();
- log_info << "Hardware surfaces are " << (info->hw_available ? "" : "not ") << "available." << std::endl;
- log_info << "Hardware to hardware blits are " << (info->blit_hw ? "" : "not ") << "accelerated." << std::endl;
- log_info << "Hardware to hardware blits with colorkey are " << (info->blit_hw_CC ? "" : "not ") << "accelerated." << std::endl;
- log_info << "Hardware to hardware blits with alpha are " << (info->blit_hw_A ? "" : "not ") << "accelerated." << std::endl;
- log_info << "Software to hardware blits are " << (info->blit_sw ? "" : "not ") << "accelerated." << std::endl;
- log_info << "Software to hardware blits with colorkey are " << (info->blit_sw_CC ? "" : "not ") << "accelerated." << std::endl;
- log_info << "Software to hardware blits with alpha are " << (info->blit_sw_A ? "" : "not ") << "accelerated." << std::endl;
- log_info << "Color fills are " << (info->blit_fill ? "" : "not ") << "accelerated." << std::endl;
-
- int flags = SDL_SWSURFACE | SDL_ANYFORMAT;
- if(config->use_fullscreen)
- flags |= SDL_FULLSCREEN;
- int width = config->screenwidth;
- int height = config->screenheight;
-
- screen = SDL_SetVideoMode(width, height, 0, flags);
- if(screen == 0) {
- std::stringstream msg;
- msg << "Couldn't set video mode (" << width << "x" << height
- << "): " << SDL_GetError();
- throw std::runtime_error(msg.str());
- }
-
- float xfactor = (float) config->screenwidth / SCREEN_WIDTH;
- float yfactor = (float) config->screenheight / SCREEN_HEIGHT;
- if(xfactor < yfactor)
- {
- numerator = config->screenwidth;
- denominator = SCREEN_WIDTH;
- }
- else
- {
- numerator = config->screenheight;
- denominator = SCREEN_HEIGHT;
- }
-
- if(texture_manager == 0)
- texture_manager = new TextureManager();
- }
-
- Renderer::~Renderer()
- {
- }
-
- void
- Renderer::draw_surface(const DrawingRequest& request)
- {
- //FIXME: support parameters request.alpha, request.angle, request.blend
- const Surface* surface = (const Surface*) request.request_data;
- SDL::Texture *sdltexture = dynamic_cast<SDL::Texture *>(surface->get_texture());
- SDL::SurfaceData *surface_data = reinterpret_cast<SDL::SurfaceData *>(surface->get_surface_data());
-
- DrawingEffect effect = request.drawing_effect;
- if (surface->get_flipx()) effect = HORIZONTAL_FLIP;
-
- SDL_Surface *transform = sdltexture->get_transform(request.color, effect);
-
- // get and check SDL_Surface
- if (transform == 0) {
- std::cerr << "Warning: Tried to draw NULL surface, skipped draw" << std::endl;
- return;
- }
-
- SDL_Rect *src_rect = surface_data->get_src_rect(effect);
- SDL_Rect dst_rect;
- dst_rect.x = (int) request.pos.x * numerator / denominator;
- dst_rect.y = (int) request.pos.y * numerator / denominator;
-
- Uint8 alpha = 0;
- if(request.alpha != 1.0)
- {
- if(!transform->format->Amask)
- {
- if(transform->flags & SDL_SRCALPHA)
- {
- alpha = transform->format->alpha;
- }
- else
- {
- alpha = 255;
- }
- SDL_SetAlpha(transform, SDL_SRCALPHA, (Uint8) (request.alpha * alpha));
- }
- /*else
- {
- transform = apply_alpha(transform, request.alpha);
- }*/
- }
-
- SDL_BlitSurface(transform, src_rect, screen, &dst_rect);
-
- if(request.alpha != 1.0)
- {
- if(!transform->format->Amask)
- {
- if(alpha == 255)
- {
- SDL_SetAlpha(transform, SDL_RLEACCEL, 0);
- }
- else
- {
- SDL_SetAlpha(transform, SDL_SRCALPHA | SDL_RLEACCEL, alpha);
- }
- }
- /*else
- {
- SDL_FreeSurface(transform);
- }*/
- }
- }
-
- void
- Renderer::draw_surface_part(const DrawingRequest& request)
- {
- const SurfacePartRequest* surfacepartrequest
- = (SurfacePartRequest*) request.request_data;
-
- const Surface* surface = surfacepartrequest->surface;
- SDL::Texture *sdltexture = dynamic_cast<SDL::Texture *>(surface->get_texture());
-
- DrawingEffect effect = request.drawing_effect;
- if (surface->get_flipx()) effect = HORIZONTAL_FLIP;
-
- SDL_Surface *transform = sdltexture->get_transform(Color(1.0, 1.0, 1.0), effect);
-
- // get and check SDL_Surface
- if (transform == 0) {
- std::cerr << "Warning: Tried to draw NULL surface, skipped draw" << std::endl;
- return;
- }
-
- int ox, oy;
- if (effect == HORIZONTAL_FLIP)
- {
- ox = sdltexture->get_texture_width() - surface->get_x() - (int) surfacepartrequest->size.x;
- }
- else
- {
- ox = surface->get_x();
- }
- if (effect == VERTICAL_FLIP)
- {
- oy = sdltexture->get_texture_height() - surface->get_y() - (int) surfacepartrequest->size.y;
- }
- else
- {
- oy = surface->get_y();
- }
-
- SDL_Rect src_rect;
- src_rect.x = (ox + (int) surfacepartrequest->source.x) * numerator / denominator;
- src_rect.y = (oy + (int) surfacepartrequest->source.y) * numerator / denominator;
- src_rect.w = (int) surfacepartrequest->size.x * numerator / denominator;
- src_rect.h = (int) surfacepartrequest->size.y * numerator / denominator;
-
- SDL_Rect dst_rect;
- dst_rect.x = (int) request.pos.x * numerator / denominator;
- dst_rect.y = (int) request.pos.y * numerator / denominator;
-
- Uint8 alpha = 0;
- if(request.alpha != 1.0)
- {
- if(!transform->format->Amask)
- {
- if(transform->flags & SDL_SRCALPHA)
- {
- alpha = transform->format->alpha;
- }
- else
- {
- alpha = 255;
- }
- SDL_SetAlpha(transform, SDL_SRCALPHA, (Uint8) (request.alpha * alpha));
- }
- /*else
- {
- transform = apply_alpha(transform, request.alpha);
- }*/
- }
-
- SDL_BlitSurface(transform, &src_rect, screen, &dst_rect);
-
- if(request.alpha != 1.0)
- {
- if(!transform->format->Amask)
- {
- if(alpha == 255)
- {
- SDL_SetAlpha(transform, SDL_RLEACCEL, 0);
- }
- else
- {
- SDL_SetAlpha(transform, SDL_SRCALPHA | SDL_RLEACCEL, alpha);
- }
- }
- /*else
- {
- SDL_FreeSurface(transform);
- }*/
- }
- }
-
- void
- Renderer::draw_gradient(const DrawingRequest& request)
- {
- const GradientRequest* gradientrequest
- = (GradientRequest*) request.request_data;
- const Color& top = gradientrequest->top;
- const Color& bottom = gradientrequest->bottom;
-
- for(int y = 0;y < screen->h;++y)
- {
- Uint8 r = (Uint8)((((float)(top.red-bottom.red)/(0-screen->h)) * y + top.red) * 255);
- Uint8 g = (Uint8)((((float)(top.green-bottom.green)/(0-screen->h)) * y + top.green) * 255);
- Uint8 b = (Uint8)((((float)(top.blue-bottom.blue)/(0-screen->h)) * y + top.blue) * 255);
- Uint8 a = (Uint8)((((float)(top.alpha-bottom.alpha)/(0-screen->h)) * y + top.alpha) * 255);
- Uint32 color = SDL_MapRGB(screen->format, r, g, b);
-
- SDL_Rect rect;
- rect.x = 0;
- rect.y = y;
- rect.w = screen->w;
- rect.h = 1;
-
- if(a == SDL_ALPHA_OPAQUE) {
- SDL_FillRect(screen, &rect, color);
- } else if(a != SDL_ALPHA_TRANSPARENT) {
- SDL_Surface *temp = SDL_CreateRGBSurface(screen->flags, rect.w, rect.h, screen->format->BitsPerPixel, screen->format->Rmask, screen->format->Gmask, screen->format->Bmask, screen->format->Amask);
-
- SDL_FillRect(temp, 0, color);
- SDL_SetAlpha(temp, SDL_SRCALPHA | SDL_RLEACCEL, a);
- SDL_BlitSurface(temp, 0, screen, &rect);
- SDL_FreeSurface(temp);
- }
- }
- }
-
- void
- Renderer::draw_filled_rect(const DrawingRequest& request)
- {
- const FillRectRequest* fillrectrequest
- = (FillRectRequest*) request.request_data;
-
- SDL_Rect rect;
- rect.x = (Sint16)request.pos.x * screen->w / SCREEN_WIDTH;
- rect.y = (Sint16)request.pos.y * screen->h / SCREEN_HEIGHT;
- rect.w = (Uint16)fillrectrequest->size.x * screen->w / SCREEN_WIDTH;
- rect.h = (Uint16)fillrectrequest->size.y * screen->h / SCREEN_HEIGHT;
- Uint8 r = static_cast<Uint8>(fillrectrequest->color.red * 255);
- Uint8 g = static_cast<Uint8>(fillrectrequest->color.green * 255);
- Uint8 b = static_cast<Uint8>(fillrectrequest->color.blue * 255);
- Uint8 a = static_cast<Uint8>(fillrectrequest->color.alpha * 255);
- Uint32 color = SDL_MapRGB(screen->format, r, g, b);
- if(a == SDL_ALPHA_OPAQUE) {
- SDL_FillRect(screen, &rect, color);
- } else if(a != SDL_ALPHA_TRANSPARENT) {
- SDL_Surface *temp = SDL_CreateRGBSurface(screen->flags, rect.w, rect.h, screen->format->BitsPerPixel, screen->format->Rmask, screen->format->Gmask, screen->format->Bmask, screen->format->Amask);
-
- SDL_FillRect(temp, 0, color);
- SDL_SetAlpha(temp, SDL_SRCALPHA | SDL_RLEACCEL, a);
- SDL_BlitSurface(temp, 0, screen, &rect);
- SDL_FreeSurface(temp);
- }
- }
-
- void
- Renderer::do_take_screenshot()
- {
- // [Christoph] TODO: Yes, this method also takes care of the actual disk I/O. Split it?
-
- SDL_Surface *screen = SDL_GetVideoSurface();
-
- // save screenshot
- static const std::string writeDir = PHYSFS_getWriteDir();
- static const std::string dirSep = PHYSFS_getDirSeparator();
- static const std::string baseName = "screenshot";
- static const std::string fileExt = ".bmp";
- std::string fullFilename;
- for (int num = 0; num < 1000; num++) {
- std::ostringstream oss;
- oss << baseName;
- oss << std::setw(3) << std::setfill('0') << num;
- oss << fileExt;
- std::string fileName = oss.str();
- fullFilename = writeDir + dirSep + fileName;
- if (!PHYSFS_exists(fileName.c_str())) {
- SDL_SaveBMP(screen, fullFilename.c_str());
- log_debug << "Wrote screenshot to \"" << fullFilename << "\"" << std::endl;
- return;
- }
- }
- log_warning << "Did not save screenshot, because all files up to \"" << fullFilename << "\" already existed" << std::endl;
- }
-
- void
- Renderer::flip()
- {
- SDL_Flip(screen);
- }
-}
+++ /dev/null
-// $Id: sdl_renderer.hpp 4986 2007-04-16 17:48:28Z matzeb $
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#ifndef SUPERTUX_SDL_RENDERER_H
-#define SUPERTUX_SDL_RENDERER_H
-
-#include <SDL_video.h>
-
-#include "renderer.hpp"
-
-namespace SDL
-{
- class Renderer : public ::Renderer
- {
- public:
- Renderer();
- ~Renderer();
-
- void draw_surface(const DrawingRequest& request);
- void draw_surface_part(const DrawingRequest& request);
- void draw_text(const DrawingRequest& request);
- void draw_gradient(const DrawingRequest& request);
- void draw_filled_rect(const DrawingRequest& request);
- void do_take_screenshot();
- void flip();
- private:
- SDL_Surface *screen;
- int numerator, denominator;
- };
-}
-
-#endif
-
+++ /dev/null
-// $Id: gl_surface_data.hpp 4063 2006-07-21 21:05:23Z anmaster $
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#ifndef __SDL_SURFACE_DATA_HPP__
-#define __SDL_SURFACE_DATA_HPP__
-
-#include <config.h>
-
-#include "surface.hpp"
-#include "texture.hpp"
-#include "main.hpp"
-#include "gameconfig.hpp"
-
-namespace SDL
-{
- class SurfaceData
- {
- private:
- const Surface &surface;
- SDL_Rect src_rects[NUM_EFFECTS];
-
- public:
- SurfaceData(const Surface &surface) :
- surface(surface)
- {
- int numerator, denominator;
- float xfactor = (float) config->screenwidth / SCREEN_WIDTH;
- float yfactor = (float) config->screenheight / SCREEN_HEIGHT;
- if(xfactor < yfactor)
- {
- numerator = config->screenwidth;
- denominator = SCREEN_WIDTH;
- }
- else
- {
- numerator = config->screenheight;
- denominator = SCREEN_HEIGHT;
- }
-
- src_rects[NO_EFFECT].x = surface.get_x() * numerator / denominator;
- src_rects[NO_EFFECT].y = surface.get_y() * numerator / denominator;
- src_rects[NO_EFFECT].w = surface.get_width() * numerator / denominator;
- src_rects[NO_EFFECT].h = surface.get_height() * numerator / denominator;
-
- int flipped_x = surface.get_texture()->get_texture_width() - surface.get_x() - surface.get_width();
- src_rects[HORIZONTAL_FLIP].x = flipped_x * numerator / denominator;
- src_rects[HORIZONTAL_FLIP].y = surface.get_y() * numerator / denominator;
- src_rects[HORIZONTAL_FLIP].w = surface.get_width() * numerator / denominator;
- src_rects[HORIZONTAL_FLIP].h = surface.get_height() * numerator / denominator;
-
- int flipped_y = surface.get_texture()->get_texture_height() - surface.get_y() - surface.get_height();
- src_rects[VERTICAL_FLIP].x = flipped_y * numerator / denominator;
- src_rects[VERTICAL_FLIP].y = surface.get_y() * numerator / denominator;
- src_rects[VERTICAL_FLIP].w = surface.get_width() * numerator / denominator;
- src_rects[VERTICAL_FLIP].h = surface.get_height() * numerator / denominator;
- }
-
- SDL_Rect *get_src_rect(DrawingEffect effect)
- {
- return src_rects + effect;
- }
- };
-}
-
-#endif
+++ /dev/null
-// $Id: sdl_texture.cpp 4063 2006-07-21 21:05:23Z anmaster $
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include "sdl_texture.hpp"
-#include "color.hpp"
-#include "gameconfig.hpp"
-#include "main.hpp"
-
-#include <assert.h>
-
-#include <SDL.h>
-
-namespace
-{
-#define BILINEAR
-
-#ifdef NAIVE
- SDL_Surface *scale(SDL_Surface *src, int numerator, int denominator)
- {
- if(numerator == denominator)
- {
- src->refcount++;
- return src;
- }
- else
- {
- SDL_Surface *dst = SDL_CreateRGBSurface(src->flags, src->w * numerator / denominator, src->h * numerator / denominator, src->format->BitsPerPixel, src->format->Rmask, src->format->Gmask, src->format->Bmask, src->format->Amask);
- int bpp = dst->format->BytesPerPixel;
- if(SDL_MUSTLOCK(src))
- {
- SDL_LockSurface(src);
- }
- if(SDL_MUSTLOCK(dst))
- {
- SDL_LockSurface(dst);
- }
- for(int y = 0;y < dst->h;y++) {
- for(int x = 0;x < dst->w;x++) {
- Uint8 *srcpixel = (Uint8 *) src->pixels + (y * denominator / numerator) * src->pitch + (x * denominator / numerator) * bpp;
- Uint8 *dstpixel = (Uint8 *) dst->pixels + y * dst->pitch + x * bpp;
- switch(bpp) {
- case 4:
- dstpixel[3] = srcpixel[3];
- case 3:
- dstpixel[2] = srcpixel[2];
- case 2:
- dstpixel[1] = srcpixel[1];
- case 1:
- dstpixel[0] = srcpixel[0];
- }
- }
- }
- if(SDL_MUSTLOCK(dst))
- {
- SDL_UnlockSurface(dst);
- }
- if(SDL_MUSTLOCK(src))
- {
- SDL_UnlockSurface(src);
- }
- if(!src->format->Amask)
- {
- if(src->flags & SDL_SRCALPHA)
- {
- SDL_SetAlpha(dst, SDL_SRCALPHA | SDL_RLEACCEL, src->format->alpha);
- }
- if(src->flags & SDL_SRCCOLORKEY)
- {
- SDL_SetColorKey(dst, SDL_SRCCOLORKEY | SDL_RLEACCEL, src->format->colorkey);
- }
- }
- return dst;
- }
- }
-#endif
-
-#ifdef BILINEAR
- void getpixel(SDL_Surface *src, int srcx, int srcy, Uint8 color[4])
- {
- int bpp = src->format->BytesPerPixel;
- if(srcx == src->w)
- {
- srcx--;
- }
- if(srcy == src->h)
- {
- srcy--;
- }
- Uint8 *srcpixel = (Uint8 *) src->pixels + srcy * src->pitch + srcx * bpp;
- Uint32 mapped = 0;
- switch(bpp) {
- case 1:
- mapped = *srcpixel;
- break;
- case 2:
- mapped = *(Uint16 *)srcpixel;
- break;
- case 3:
-#if SDL_BYTEORDER == SDL_BIG_ENDIAN
- mapped |= srcpixel[0] << 16;
- mapped |= srcpixel[1] << 8;
- mapped |= srcpixel[2] << 0;
-#else
- mapped |= srcpixel[0] << 0;
- mapped |= srcpixel[1] << 8;
- mapped |= srcpixel[2] << 16;
-#endif
- break;
- case 4:
- mapped = *(Uint32 *)srcpixel;
- break;
- }
- SDL_GetRGBA(mapped, src->format, &color[0], &color[1], &color[2], &color[3]);
- }
-
- void merge(Uint8 color[4], Uint8 color0[4], Uint8 color1[4], int rem, int total)
- {
- color[0] = (color0[0] * (total - rem) + color1[0] * rem) / total;
- color[1] = (color0[1] * (total - rem) + color1[1] * rem) / total;
- color[2] = (color0[2] * (total - rem) + color1[2] * rem) / total;
- color[3] = (color0[3] * (total - rem) + color1[3] * rem) / total;
- }
-
- SDL_Surface *scale(SDL_Surface *src, int numerator, int denominator)
- {
- if(numerator == denominator)
- {
- src->refcount++;
- return src;
- }
- else
- {
- SDL_Surface *dst = SDL_CreateRGBSurface(src->flags, src->w * numerator / denominator, src->h * numerator / denominator, src->format->BitsPerPixel, src->format->Rmask, src->format->Gmask, src->format->Bmask, src->format->Amask);
- int bpp = dst->format->BytesPerPixel;
- if(SDL_MUSTLOCK(src))
- {
- SDL_LockSurface(src);
- }
- if(SDL_MUSTLOCK(dst))
- {
- SDL_LockSurface(dst);
- }
- for(int y = 0;y < dst->h;y++) {
- for(int x = 0;x < dst->w;x++) {
- int srcx = x * denominator / numerator;
- int srcy = y * denominator / numerator;
- Uint8 color00[4], color01[4], color10[4], color11[4];
- getpixel(src, srcx, srcy, color00);
- getpixel(src, srcx + 1, srcy, color01);
- getpixel(src, srcx, srcy + 1, color10);
- getpixel(src, srcx + 1, srcy + 1, color11);
- Uint8 color0[4], color1[4], color[4];
- int remx = x * denominator % numerator;
- merge(color0, color00, color01, remx, numerator);
- merge(color1, color10, color11, remx, numerator);
- int remy = y * denominator % numerator;
- merge(color, color0, color1, remy, numerator);
- Uint8 *dstpixel = (Uint8 *) dst->pixels + y * dst->pitch + x * bpp;
- Uint32 mapped = SDL_MapRGBA(dst->format, color[0], color[1], color[2], color[3]);
- switch(bpp) {
- case 1:
- *dstpixel = mapped;
- break;
- case 2:
- *(Uint16 *)dstpixel = mapped;
- break;
- case 3:
-#if SDL_BYTEORDER == SDL_BIG_ENDIAN
- dstpixel[0] = (mapped >> 16) & 0xff;
- dstpixel[1] = (mapped >> 8) & 0xff;
- dstpixel[2] = (mapped >> 0) & 0xff;
-#else
- dstpixel[0] = (mapped >> 0) & 0xff;
- dstpixel[1] = (mapped >> 8) & 0xff;
- dstpixel[2] = (mapped >> 16) & 0xff;
-#endif
- break;
- case 4:
- *(Uint32 *)dstpixel = mapped;
- break;
- }
- }
- }
- if(SDL_MUSTLOCK(dst))
- {
- SDL_UnlockSurface(dst);
- }
- if(SDL_MUSTLOCK(src))
- {
- SDL_UnlockSurface(src);
- }
- if(!src->format->Amask)
- {
- if(src->flags & SDL_SRCALPHA)
- {
- SDL_SetAlpha(dst, SDL_SRCALPHA | SDL_RLEACCEL, src->format->alpha);
- }
- if(src->flags & SDL_SRCCOLORKEY)
- {
- SDL_SetColorKey(dst, SDL_SRCCOLORKEY | SDL_RLEACCEL, src->format->colorkey);
- }
- }
- return dst;
- }
- }
-#endif
-
- SDL_Surface *horz_flip(SDL_Surface *src)
- {
- SDL_Surface *dst = SDL_CreateRGBSurface(src->flags, src->w, src->h, src->format->BitsPerPixel, src->format->Rmask, src->format->Gmask, src->format->Bmask, src->format->Amask);
- int bpp = dst->format->BytesPerPixel;
- if(SDL_MUSTLOCK(src))
- {
- SDL_LockSurface(src);
- }
- if(SDL_MUSTLOCK(dst))
- {
- SDL_LockSurface(dst);
- }
- for(int y = 0;y < dst->h;y++) {
- for(int x = 0;x < dst->w;x++) {
- Uint8 *srcpixel = (Uint8 *) src->pixels + y * src->pitch + x * bpp;
- Uint8 *dstpixel = (Uint8 *) dst->pixels + y * dst->pitch + (dst->w - x - 1) * bpp;
- switch(bpp) {
- case 4:
- dstpixel[3] = srcpixel[3];
- case 3:
- dstpixel[2] = srcpixel[2];
- case 2:
- dstpixel[1] = srcpixel[1];
- case 1:
- dstpixel[0] = srcpixel[0];
- }
- }
- }
- if(SDL_MUSTLOCK(dst))
- {
- SDL_UnlockSurface(dst);
- }
- if(SDL_MUSTLOCK(src))
- {
- SDL_UnlockSurface(src);
- }
- if(!src->format->Amask)
- {
- if(src->flags & SDL_SRCALPHA)
- {
- SDL_SetAlpha(dst, SDL_SRCALPHA | SDL_RLEACCEL, src->format->alpha);
- }
- if(src->flags & SDL_SRCCOLORKEY)
- {
- SDL_SetColorKey(dst, SDL_SRCCOLORKEY | SDL_RLEACCEL, src->format->colorkey);
- }
- }
- return dst;
- }
-
- SDL_Surface *vert_flip(SDL_Surface *src)
- {
- SDL_Surface *dst = SDL_CreateRGBSurface(src->flags, src->w, src->h, src->format->BitsPerPixel, src->format->Rmask, src->format->Gmask, src->format->Bmask, src->format->Amask);
- int bpp = dst->format->BytesPerPixel;
- if(SDL_MUSTLOCK(src))
- {
- SDL_LockSurface(src);
- }
- if(SDL_MUSTLOCK(dst))
- {
- SDL_LockSurface(dst);
- }
- for(int y = 0;y < dst->h;y++) {
- for(int x = 0;x < dst->w;x++) {
- Uint8 *srcpixel = (Uint8 *) src->pixels + y * src->pitch + x * bpp;
- Uint8 *dstpixel = (Uint8 *) dst->pixels + (dst->h - y - 1) * dst->pitch + x * bpp;
- switch(bpp) {
- case 4:
- dstpixel[3] = srcpixel[3];
- case 3:
- dstpixel[2] = srcpixel[2];
- case 2:
- dstpixel[1] = srcpixel[1];
- case 1:
- dstpixel[0] = srcpixel[0];
- }
- }
- }
- if(SDL_MUSTLOCK(dst))
- {
- SDL_UnlockSurface(dst);
- }
- if(SDL_MUSTLOCK(src))
- {
- SDL_UnlockSurface(src);
- }
- if(!src->format->Amask)
- {
- if(src->flags & SDL_SRCALPHA)
- {
- SDL_SetAlpha(dst, SDL_SRCALPHA | SDL_RLEACCEL, src->format->alpha);
- }
- if(src->flags & SDL_SRCCOLORKEY)
- {
- SDL_SetColorKey(dst, SDL_SRCCOLORKEY | SDL_RLEACCEL, src->format->colorkey);
- }
- }
- return dst;
- }
-
- SDL_Surface *colorize(SDL_Surface *src, const Color &color)
- {
- // FIXME: This is really slow
- assert(color.red != 1.0 || color.green != 1.0 || color.blue != 1.0);
- int red = (int) (color.red * 256);
- int green = (int) (color.green * 256);
- int blue = (int) (color.blue * 256);
- SDL_Surface *dst = SDL_CreateRGBSurface(src->flags, src->w, src->h, src->format->BitsPerPixel, src->format->Rmask, src->format->Gmask, src->format->Bmask, src->format->Amask);
- int bpp = dst->format->BytesPerPixel;
- if(SDL_MUSTLOCK(src))
- {
- SDL_LockSurface(src);
- }
- if(SDL_MUSTLOCK(dst))
- {
- SDL_LockSurface(dst);
- }
- for(int y = 0;y < dst->h;y++) {
- for(int x = 0;x < dst->w;x++) {
- Uint8 *srcpixel = (Uint8 *) src->pixels + y * src->pitch + x * bpp;
- Uint8 *dstpixel = (Uint8 *) dst->pixels + y * dst->pitch + x * bpp;
- Uint32 mapped = 0;
- switch(bpp) {
- case 1:
- mapped = *srcpixel;
- break;
- case 2:
- mapped = *(Uint16 *)srcpixel;
- break;
- case 3:
-#if SDL_BYTEORDER == SDL_BIG_ENDIAN
- mapped |= srcpixel[0] << 16;
- mapped |= srcpixel[1] << 8;
- mapped |= srcpixel[2] << 0;
-#else
- mapped |= srcpixel[0] << 0;
- mapped |= srcpixel[1] << 8;
- mapped |= srcpixel[2] << 16;
-#endif
- break;
- case 4:
- mapped = *(Uint32 *)srcpixel;
- break;
- }
- if(src->format->Amask || !(src->flags & SDL_SRCCOLORKEY) || mapped != src->format->colorkey)
- {
- Uint8 r, g, b, a;
- SDL_GetRGBA(mapped, src->format, &r, &g, &b, &a);
- mapped = SDL_MapRGBA(dst->format, (r * red) >> 8, (g * green) >> 8, (b * blue) >> 8, a);
- }
- switch(bpp) {
- case 1:
- *dstpixel = mapped;
- break;
- case 2:
- *(Uint16 *)dstpixel = mapped;
- break;
- case 3:
-#if SDL_BYTEORDER == SDL_BIG_ENDIAN
- dstpixel[0] = (mapped >> 16) & 0xff;
- dstpixel[1] = (mapped >> 8) & 0xff;
- dstpixel[2] = (mapped >> 0) & 0xff;
-#else
- dstpixel[0] = (mapped >> 0) & 0xff;
- dstpixel[1] = (mapped >> 8) & 0xff;
- dstpixel[2] = (mapped >> 16) & 0xff;
-#endif
- break;
- case 4:
- *(Uint32 *)dstpixel = mapped;
- break;
- }
- }
- }
- if(SDL_MUSTLOCK(dst))
- {
- SDL_UnlockSurface(dst);
- }
- if(SDL_MUSTLOCK(src))
- {
- SDL_UnlockSurface(src);
- }
- if(!src->format->Amask)
- {
- if(src->flags & SDL_SRCALPHA)
- {
- SDL_SetAlpha(dst, SDL_SRCALPHA | SDL_RLEACCEL, src->format->alpha);
- }
- if(src->flags & SDL_SRCCOLORKEY)
- {
- SDL_SetColorKey(dst, SDL_SRCCOLORKEY | SDL_RLEACCEL, src->format->colorkey);
- }
- }
- return dst;
- }
-
- SDL_Surface *optimize(SDL_Surface *src)
- {
- if(!src->format->Amask)
- {
- return SDL_DisplayFormat(src);
- }
- else
- {
- int transparent = 0;
- int opaque = 0;
- int semitransparent = 0;
- int alphasum = 0;
- int squaredalphasum = 0;
- bool colors[(1 << 12)];
- memset(colors, 0, (1 << 12) * sizeof(bool));
-
- int bpp = src->format->BytesPerPixel;
- if(SDL_MUSTLOCK(src))
- {
- SDL_LockSurface(src);
- }
- for(int y = 0;y < src->h;y++) {
- for(int x = 0;x < src->w;x++) {
- Uint8 *pixel = (Uint8 *) src->pixels + y * src->pitch + x * bpp;
- Uint32 mapped = 0;
- switch(bpp) {
- case 1:
- mapped = *pixel;
- break;
- case 2:
- mapped = *(Uint16 *)pixel;
- break;
- case 3:
-#if SDL_BYTEORDER == SDL_BIG_ENDIAN
- mapped |= pixel[0] << 16;
- mapped |= pixel[1] << 8;
- mapped |= pixel[2] << 0;
-#else
- mapped |= pixel[0] << 0;
- mapped |= pixel[1] << 8;
- mapped |= pixel[2] << 16;
-#endif
- break;
- case 4:
- mapped = *(Uint32 *)pixel;
- break;
- }
- Uint8 red, green, blue, alpha;
- SDL_GetRGBA(mapped, src->format, &red, &green, &blue, &alpha);
- if(alpha < 16)
- {
- transparent++;
- }
- else if (alpha > 240)
- {
- opaque++;
- alphasum += alpha;
- squaredalphasum += alpha * alpha;
- }
- else
- {
- semitransparent++;
- squaredalphasum += alpha * alpha;
- }
- if(alpha != 0)
- {
- colors[((red & 0xf0) << 4) | (green & 0xf0) | ((blue & 0xf0) >> 4)] = true;
- }
- }
- }
- if(SDL_MUSTLOCK(src))
- {
- SDL_UnlockSurface(src);
- }
- int avgalpha = (opaque + semitransparent) ? alphasum / (opaque + semitransparent) : 0;
- int avgsquaredalpha = (opaque + semitransparent) ? squaredalphasum / (opaque + semitransparent) : 0;
- int alphavariance = avgsquaredalpha - avgalpha * avgalpha;
- if(semitransparent > ((transparent + opaque + semitransparent) / 8) && alphavariance > 16)
- {
- return SDL_DisplayFormatAlpha(src);
- }
- int keycolor = -1;
- for(int i = 0;i < (1 << 12);i++)
- {
- if(!colors[i])
- {
- keycolor = i;
- }
- }
- if(keycolor == -1)
- {
- return SDL_DisplayFormatAlpha(src);
- }
- SDL_Surface *dst = SDL_CreateRGBSurface(src->flags & ~(SDL_SRCALPHA), src->w, src->h, src->format->BitsPerPixel, src->format->Rmask, src->format->Gmask, src->format->Bmask, 0);
- bpp = dst->format->BytesPerPixel;
- Uint32 key = SDL_MapRGB(dst->format, (((keycolor & 0xf00) >> 4) | 0xf), ((keycolor & 0xf0) | 0xf), (((keycolor & 0xf) << 4) | 0xf));
- if(SDL_MUSTLOCK(src))
- {
- SDL_LockSurface(src);
- }
- if(SDL_MUSTLOCK(dst))
- {
- SDL_LockSurface(dst);
- }
- for(int y = 0;y < dst->h;y++) {
- for(int x = 0;x < dst->w;x++) {
- Uint8 *srcpixel = (Uint8 *) src->pixels + y * src->pitch + x * bpp;
- Uint8 *dstpixel = (Uint8 *) dst->pixels + y * dst->pitch + x * bpp;
- Uint32 mapped = 0;
- switch(bpp) {
- case 1:
- mapped = *srcpixel;
- break;
- case 2:
- mapped = *(Uint16 *)srcpixel;
- break;
- case 3:
-#if SDL_BYTEORDER == SDL_BIG_ENDIAN
- mapped |= srcpixel[0] << 16;
- mapped |= srcpixel[1] << 8;
- mapped |= srcpixel[2] << 0;
-#else
- mapped |= srcpixel[0] << 0;
- mapped |= srcpixel[1] << 8;
- mapped |= srcpixel[2] << 16;
-#endif
- break;
- case 4:
- mapped = *(Uint32 *)srcpixel;
- break;
- }
- Uint8 red, green, blue, alpha;
- SDL_GetRGBA(mapped, src->format, &red, &green, &blue, &alpha);
- if(alpha < (avgalpha / 4))
- {
- mapped = key;
- }
- else
- {
- mapped = SDL_MapRGB(dst->format, red, green, blue);
- }
- switch(bpp) {
- case 1:
- *dstpixel = mapped;
- break;
- case 2:
- *(Uint16 *)dstpixel = mapped;
- break;
- case 3:
-#if SDL_BYTEORDER == SDL_BIG_ENDIAN
- dstpixel[0] = (mapped >> 16) & 0xff;
- dstpixel[1] = (mapped >> 8) & 0xff;
- dstpixel[2] = (mapped >> 0) & 0xff;
-#else
- dstpixel[0] = (mapped >> 0) & 0xff;
- dstpixel[1] = (mapped >> 8) & 0xff;
- dstpixel[2] = (mapped >> 16) & 0xff;
-#endif
- break;
- case 4:
- *(Uint32 *)dstpixel = mapped;
- break;
- }
- }
- }
- if(SDL_MUSTLOCK(dst))
- {
- SDL_UnlockSurface(dst);
- }
- if(SDL_MUSTLOCK(src))
- {
- SDL_UnlockSurface(src);
- }
- if(avgalpha < 240)
- {
- SDL_SetAlpha(dst, SDL_SRCALPHA | SDL_RLEACCEL, avgalpha);
- }
- SDL_SetColorKey(dst, SDL_SRCCOLORKEY | SDL_RLEACCEL, key);
- SDL_Surface *convert = SDL_DisplayFormat(dst);
- SDL_FreeSurface(dst);
- return convert;
- }
- }
-}
-
-namespace SDL
-{
- Texture::Texture(SDL_Surface* image)
- {
- texture = optimize(image);
- //width = texture->w;
- //height = texture->h;
- int numerator, denominator;
- float xfactor = (float) config->screenwidth / SCREEN_WIDTH;
- float yfactor = (float) config->screenheight / SCREEN_HEIGHT;
- if(xfactor < yfactor)
- {
- numerator = config->screenwidth;
- denominator = SCREEN_WIDTH;
- }
- else
- {
- numerator = config->screenheight;
- denominator = SCREEN_HEIGHT;
- }
- cache[NO_EFFECT][Color::WHITE] = scale(texture, numerator, denominator);
- }
-
- Texture::~Texture()
- {
- SDL_FreeSurface(texture);
- }
-
- SDL_Surface *Texture::get_transform(const Color &color, DrawingEffect effect)
- {
- if(cache[NO_EFFECT][color] == 0) {
- assert(cache[NO_EFFECT][Color::WHITE]);
- cache[NO_EFFECT][color] = colorize(cache[NO_EFFECT][Color::WHITE], color);
- }
- if(cache[effect][color] == 0) {
- assert(cache[NO_EFFECT][color]);
- switch(effect) {
- case NO_EFFECT:
- break;
- case HORIZONTAL_FLIP:
- cache[HORIZONTAL_FLIP][color] = horz_flip(cache[NO_EFFECT][color]);
- break;
- case VERTICAL_FLIP:
- cache[VERTICAL_FLIP][color] = vert_flip(cache[NO_EFFECT][color]);
- break;
- default:
- return 0;
- }
- }
- return cache[effect][color];
- }
-}
+++ /dev/null
-// $Id: sdl_texture.hpp 4063 2006-07-21 21:05:23Z anmaster $
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __SDL_TEXTURE_HPP__
-#define __SDL_TEXTURE_HPP__
-
-#include <config.h>
-
-#include <SDL.h>
-
-#include "texture.hpp"
-#include "color.hpp"
-
-namespace SDL
-{
- class Texture : public ::Texture
- {
- protected:
- SDL_Surface *texture;
- //unsigned int width;
- //unsigned int height;
-
- struct ColorCache
- {
- static const int HASHED_BITS = 3;
- static const int CACHE_SIZE = 1 << (HASHED_BITS * 3);
-
- static void ref(SDL_Surface *surface)
- {
- if(surface)
- {
- surface->refcount++;
- }
- }
-
- static int hash(const Color &color)
- {
- return
- ((int) (color.red * ((1 << HASHED_BITS) - 1)) << (HASHED_BITS - 1) * 2) |
- ((int) (color.green * ((1 << HASHED_BITS) - 1)) << (HASHED_BITS - 1)) |
- ((int) (color.blue * ((1 << HASHED_BITS) - 1)) << 0);
- }
-
- SDL_Surface *data[CACHE_SIZE];
-
- ColorCache()
- {
- memset(data, 0, CACHE_SIZE * sizeof(SDL_Surface *));
- }
-
- ~ColorCache()
- {
- std::for_each(data, data + CACHE_SIZE, SDL_FreeSurface);
- }
-
- void operator = (const ColorCache &other)
- {
- std::for_each(other.data, other.data + CACHE_SIZE, ref);
- std::for_each(data, data + CACHE_SIZE, SDL_FreeSurface);
- memcpy(data, other.data, CACHE_SIZE * sizeof(SDL_Surface *));
- }
-
- SDL_Surface *&operator [] (const Color &color)
- {
- return data[hash(color)];
- }
- };
- //typedef std::map<Color, SDL_Surface *> ColorCache;
- ColorCache cache[NUM_EFFECTS];
-
- public:
- Texture(SDL_Surface* sdlsurface);
- virtual ~Texture();
-
- SDL_Surface *get_transform(const Color &color, DrawingEffect effect);
-
- SDL_Surface *get_texture() const
- {
- return texture;
- }
-
- unsigned int get_texture_width() const
- {
- return texture->w;
- }
-
- unsigned int get_texture_height() const
- {
- return texture->h;
- }
-
- unsigned int get_image_width() const
- {
- return texture->w;
- }
-
- unsigned int get_image_height() const
- {
- return texture->h;
- }
-
- /*unsigned int get_texture_width() const
- {
- return width;
- }
-
- unsigned int get_texture_height() const
- {
- return height;
- }
-
- unsigned int get_image_width() const
- {
- return width;
- }
-
- unsigned int get_image_height() const
- {
- return height;
- }*/
- };
-}
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#ifndef __SURFACE_HPP__
-#define __SURFACE_HPP__
-
-#include <config.h>
-
-#include <string>
-#include <SDL.h>
-#include "math/vector.hpp"
-#include "texture.hpp"
-#include "video_systems.hpp"
-
-/**
- * A rectangular image.
- * The class basically holds a reference to a texture with additional UV
- * coordinates that specify a rectangular area on this texture
- */
-class Surface
-{
-private:
- Texture* texture;
- void *surface_data;
- int x;
- int y;
- int w;
- int h;
- bool flipx;
-
-public:
- Surface(const std::string& file) :
- texture(texture_manager->get(file)),
- x(0), y(0), w(0), h(0),
- flipx(false)
- {
- texture->ref();
- w = texture->get_image_width();
- h = texture->get_image_height();
- surface_data = new_surface_data(*this);
- }
-
- Surface(const std::string& file, int x, int y, int w, int h) :
- texture(texture_manager->get(file)),
- x(x), y(y), w(w), h(h),
- flipx(false)
- {
- texture->ref();
- surface_data = new_surface_data(*this);
- }
-
- Surface(const Surface& other) :
- texture(other.texture),
- x(other.x), y(other.y),
- w(other.w), h(other.h),
- flipx(false)
- {
- texture->ref();
- surface_data = new_surface_data(*this);
- }
-
- ~Surface()
- {
- free_surface_data(surface_data);
- texture->unref();
- }
-
- /** flip the surface horizontally */
- void hflip()
- {
- flipx = !flipx;
- }
-
- bool get_flipx() const
- {
- return flipx;
- }
-
- const Surface& operator= (const Surface& other)
- {
- other.texture->ref();
- texture->unref();
- texture = other.texture;
- x = other.x;
- y = other.y;
- w = other.w;
- h = other.h;
- return *this;
- }
-
- Texture *get_texture() const
- {
- return texture;
- }
-
- void *get_surface_data() const
- {
- return surface_data;
- }
-
- int get_x() const
- {
- return x;
- }
-
- int get_y() const
- {
- return y;
- }
-
- int get_width() const
- {
- return w;
- }
-
- int get_height() const
- {
- return h;
- }
-
- Vector get_position() const
- { return Vector(get_x(), get_y()); }
-
- /**
- * returns a vector containing width and height
- */
- Vector get_size() const
- { return Vector(get_width(), get_height()); }
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __TEXTURE_HPP__
-#define __TEXTURE_HPP__
-
-#include <config.h>
-
-#include <assert.h>
-#include <string>
-
-#include "texture_manager.hpp"
-
-/// bitset for drawing effects
-enum DrawingEffect {
- /** Don't apply anything */
- NO_EFFECT,
- /** Draw the Surface upside down */
- VERTICAL_FLIP,
- /** Draw the Surface from left to down */
- HORIZONTAL_FLIP,
- NUM_EFFECTS
-};
-
-/**
- * This class is a wrapper around a texture handle. It stores the texture width
- * and height and provides convenience functions for uploading SDL_Surfaces
- * into the texture
- */
-class Texture
-{
-protected:
- int refcount;
- std::string filename;
-
-public:
- Texture() : refcount(0), filename() {}
- virtual ~Texture() {}
-
- virtual unsigned int get_texture_width() const = 0;
- virtual unsigned int get_texture_height() const = 0;
- virtual unsigned int get_image_width() const = 0;
- virtual unsigned int get_image_height() const = 0;
-
- std::string get_filename() const
- {
- return filename;
- }
-
- void set_filename(std::string filename)
- {
- this->filename = filename;
- }
-
- void ref()
- {
- refcount++;
- }
-
- void unref()
- {
- assert(refcount > 0);
- refcount--;
- if(refcount == 0)
- release();
- }
-
-private:
- void release()
- {
- texture_manager->release(this);
- }
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include "texture_manager.hpp"
-
-#include <assert.h>
-#include <SDL.h>
-#include <SDL_image.h>
-#include <iostream>
-#include <sstream>
-#include <stdexcept>
-#include "physfs/physfs_sdl.hpp"
-#include "video_systems.hpp"
-#include "gl_texture.hpp"
-#include "glutil.hpp"
-#include "gameconfig.hpp"
-#include "file_system.hpp"
-#include "log.hpp"
-#include "texture.hpp"
-
-TextureManager* texture_manager = NULL;
-
-TextureManager::TextureManager()
-{
-}
-
-TextureManager::~TextureManager()
-{
- for(ImageTextures::iterator i = image_textures.begin();
- i != image_textures.end(); ++i) {
- if(i->second == NULL)
- continue;
- log_warning << "Texture '" << i->first << "' not freed" << std::endl;
- delete i->second;
- }
-}
-
-Texture*
-TextureManager::get(const std::string& _filename)
-{
- std::string filename = FileSystem::normalize(_filename);
- ImageTextures::iterator i = image_textures.find(filename);
-
- Texture* texture = NULL;
- if(i != image_textures.end())
- texture = i->second;
-
- if(texture == NULL) {
- texture = create_image_texture(filename);
- image_textures[filename] = texture;
- }
-
- return texture;
-}
-
-void
-TextureManager::release(Texture* texture)
-{
- image_textures.erase(texture->get_filename());
- delete texture;
-}
-
-#ifdef HAVE_OPENGL
-void
-TextureManager::register_texture(GL::Texture* texture)
-{
- textures.insert(texture);
-}
-
-void
-TextureManager::remove_texture(GL::Texture* texture)
-{
- textures.erase(texture);
-}
-#endif
-
-Texture*
-TextureManager::create_image_texture(const std::string& filename)
-{
- SDL_Surface* image = IMG_Load_RW(get_physfs_SDLRWops(filename), 1);
- if(image == 0) {
- std::ostringstream msg;
- msg << "Couldn't load image '" << filename << "' :" << SDL_GetError();
- throw std::runtime_error(msg.str());
- }
-
- Texture* result = 0;
- try {
- result = new_texture(image);
- result->set_filename(filename);
- } catch(...) {
- delete result;
- SDL_FreeSurface(image);
- throw;
- }
-
- SDL_FreeSurface(image);
- return result;
-}
-
-#ifdef HAVE_OPENGL
-void
-TextureManager::save_textures()
-{
- glPixelStorei(GL_PACK_ROW_LENGTH, 0);
- glPixelStorei(GL_PACK_IMAGE_HEIGHT, 0);
- glPixelStorei(GL_PACK_SKIP_PIXELS, 0);
- glPixelStorei(GL_PACK_SKIP_ROWS, 0);
- glPixelStorei(GL_PACK_SKIP_IMAGES, 0);
- glPixelStorei(GL_PACK_ALIGNMENT, 1);
- for(Textures::iterator i = textures.begin(); i != textures.end(); ++i) {
- save_texture(*i);
- }
- for(ImageTextures::iterator i = image_textures.begin();
- i != image_textures.end(); ++i) {
- save_texture(dynamic_cast<GL::Texture *>(i->second));
- }
-}
-
-void
-TextureManager::save_texture(GL::Texture* texture)
-{
- SavedTexture saved_texture;
- saved_texture.texture = texture;
- glBindTexture(GL_TEXTURE_2D, texture->get_handle());
- glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH,
- &saved_texture.width);
- glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT,
- &saved_texture.height);
- glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_BORDER,
- &saved_texture.border);
- glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
- &saved_texture.min_filter);
- glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
- &saved_texture.mag_filter);
- glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,
- &saved_texture.wrap_s);
- glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,
- &saved_texture.wrap_t);
-
- size_t pixelssize = saved_texture.width * saved_texture.height * 4;
- saved_texture.pixels = new char[pixelssize];
-
- glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE,
- saved_texture.pixels);
-
- saved_textures.push_back(saved_texture);
-
- glDeleteTextures(1, &(texture->get_handle()));
- texture->set_handle(0);
-
- assert_gl("retrieving texture for save");
-}
-
-void
-TextureManager::reload_textures()
-{
- glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
- glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, 0);
- glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
- glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
- glPixelStorei(GL_UNPACK_SKIP_IMAGES, 0);
- glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
-
- for(std::vector<SavedTexture>::iterator i = saved_textures.begin();
- i != saved_textures.end(); ++i) {
- SavedTexture& saved_texture = *i;
-
- GLuint handle;
- glGenTextures(1, &handle);
- assert_gl("creating texture handle");
-
- glBindTexture(GL_TEXTURE_2D, handle);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
- saved_texture.width, saved_texture.height,
- saved_texture.border, GL_RGBA,
- GL_UNSIGNED_BYTE, saved_texture.pixels);
- delete[] saved_texture.pixels;
- assert_gl("uploading texture pixel data");
-
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
- saved_texture.min_filter);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
- saved_texture.mag_filter);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,
- saved_texture.wrap_s);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,
- saved_texture.wrap_t);
-
- assert_gl("setting texture_params");
- saved_texture.texture->set_handle(handle);
- }
-
- saved_textures.clear();
-}
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __IMAGE_TEXTURE_MANAGER_HPP__
-#define __IMAGE_TEXTURE_MANAGER_HPP__
-
-#include <config.h>
-
-#include "glutil.hpp"
-#include <string>
-#include <vector>
-#include <map>
-#include <set>
-
-class Texture;
-namespace GL { class Texture; }
-
-class TextureManager
-{
-public:
- TextureManager();
- ~TextureManager();
-
- Texture* get(const std::string& filename);
-
-#ifdef HAVE_OPENGL
- void register_texture(GL::Texture* texture);
- void remove_texture(GL::Texture* texture);
-
- void save_textures();
- void reload_textures();
-#endif
-
-private:
- friend class Texture;
- void release(Texture* texture);
-
- typedef std::map<std::string, Texture*> ImageTextures;
- ImageTextures image_textures;
-
- Texture* create_image_texture(const std::string& filename);
-
-#ifdef HAVE_OPENGL
- typedef std::set<GL::Texture*> Textures;
- Textures textures;
-
- struct SavedTexture
- {
- GL::Texture* texture;
- GLint width;
- GLint height;
- char* pixels;
- GLint border;
-
- GLint min_filter;
- GLint mag_filter;
- GLint wrap_s;
- GLint wrap_t;
- };
- std::vector<SavedTexture> saved_textures;
-
- void save_texture(GL::Texture* texture);
-#endif
-};
-
-extern TextureManager* texture_manager;
-
-#endif
+++ /dev/null
-// $Id: video_systems.cpp 5063 2007-05-27 11:32:00Z matzeb $
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#include <config.h>
-
-#include "video_systems.hpp"
-#include "gameconfig.hpp"
-#include "renderer.hpp"
-#include "gl_renderer.hpp"
-#include "sdl_renderer.hpp"
-#include "lightmap.hpp"
-#include "gl_lightmap.hpp"
-#include "sdl_lightmap.hpp"
-#include "texture.hpp"
-#include "gl_texture.hpp"
-#include "sdl_texture.hpp"
-#include "gl_surface_data.hpp"
-#include "sdl_surface_data.hpp"
-
-Renderer *new_renderer()
-{
- switch(config->video)
- {
- case AUTO_VIDEO:
-#ifdef HAVE_OPENGL
- return new GL::Renderer();
-#else
- return new SDL::Renderer();
-#endif
-#ifdef HAVE_OPENGL
- case OPENGL:
- return new GL::Renderer();
-#endif
- case PURE_SDL:
- return new SDL::Renderer();
- default:
- assert(0 && "invalid video system in config");
-#ifdef HAVE_OPENGL
- return new GL::Renderer();
-#else
- return new SDL::Renderer();
-#endif
- }
-}
-
-Lightmap *new_lightmap()
-{
- switch(config->video)
- {
- case AUTO_VIDEO:
-#ifdef HAVE_OPENGL
- return new GL::Lightmap();
-#else
- return new SDL::Lightmap();
-#endif
-#ifdef HAVE_OPENGL
- case OPENGL:
- return new GL::Lightmap();
-#endif
- case PURE_SDL:
- return new SDL::Lightmap();
- default:
- assert(0 && "invalid video system in config");
-#ifdef HAVE_OPENGL
- return new GL::Lightmap();
-#else
- return new SDL::Lightmap();
-#endif
- }
-}
-
-Texture *new_texture(SDL_Surface *image)
-{
- switch(config->video)
- {
- case AUTO_VIDEO:
-#ifdef HAVE_OPENGL
- return new GL::Texture(image);
-#else
- return new SDL::Texture(image);
-#endif
-#ifdef HAVE_OPENGL
- case OPENGL:
- return new GL::Texture(image);
-#endif
- case PURE_SDL:
- return new SDL::Texture(image);
- default:
- assert(0 && "invalid video system in config");
-#ifdef HAVE_OPENGL
- return new GL::Texture(image);
-#else
- return new SDL::Texture(image);
-#endif
- }
-}
-
-void *new_surface_data(const Surface &surface)
-{
- switch(config->video)
- {
- case AUTO_VIDEO:
-#ifdef HAVE_OPENGL
- return new GL::SurfaceData(surface);
-#else
- return new SDL::SurfaceData(surface);
-#endif
-#ifdef HAVE_OPENGL
- case OPENGL:
- return new GL::SurfaceData(surface);
-#endif
- case PURE_SDL:
- return new SDL::SurfaceData(surface);
- default:
- assert(0 && "invalid video system in config");
-#ifdef HAVE_OPENGL
- return new GL::SurfaceData(surface);
-#else
- return new SDL::SurfaceData(surface);
-#endif
- }
-}
-
-void free_surface_data(void *surface_data)
-{
- delete reinterpret_cast<char *>(surface_data);
-}
-
-VideoSystem get_video_system(const std::string &video)
-{
- if(video == "auto")
- {
- return AUTO_VIDEO;
- }
-#ifdef HAVE_OPENGL
- else if(video == "opengl")
- {
- return OPENGL;
- }
-#endif
- else if(video == "sdl")
- {
- return PURE_SDL;
- }
- else
- {
- return AUTO_VIDEO;
- }
-}
-
-std::string get_video_string(VideoSystem video)
-{
- switch(video)
- {
- case AUTO_VIDEO:
- return "auto";
- case OPENGL:
- return "opengl";
- case PURE_SDL:
- return "sdl";
- default:
- assert(0 && "invalid video system in config");
- return "auto";
- }
-}
+++ /dev/null
-// $Id: video_systems.hpp 5138 2007-08-15 01:02:22Z tuxdev $
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#ifndef __RENDER_SYTSTEMS_HPP__
-#define __RENDER_SYTSTEMS_HPP__
-
-#include <config.h>
-
-#include <string>
-#include <SDL.h>
-
-class Renderer;
-class Lightmap;
-class Texture;
-class Surface;
-
-enum VideoSystem {
- AUTO_VIDEO,
- OPENGL,
- PURE_SDL,
- NUM_SYSTEMS
-};
-
-Renderer *new_renderer();
-Lightmap *new_lightmap();
-Texture *new_texture(SDL_Surface *image);
-void *new_surface_data(const Surface &surface);
-void free_surface_data(void *surface_data);
-VideoSystem get_video_system(const std::string &video);
-std::string get_video_string(VideoSystem video);
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#include <config.h>
-
-#include <stddef.h>
-#include <physfs.h>
-#include <stdexcept>
-
-#include "world.hpp"
-#include "file_system.hpp"
-#include "lisp/parser.hpp"
-#include "lisp/lisp.hpp"
-#include "physfs/physfs_stream.hpp"
-#include "scripting/squirrel_util.hpp"
-#include "scripting/serialize.hpp"
-#include "log.hpp"
-#include "worldmap/worldmap.hpp"
-#include "mainloop.hpp"
-
-static bool has_suffix(const std::string& data, const std::string& suffix)
-{
- if (data.length() >= suffix.length())
- return data.compare(data.length() - suffix.length(), suffix.length(), suffix) == 0;
- else
- return false;
-}
-
-World* World::current_ = NULL;
-
-World::World()
-{
- is_levelset = true;
- hide_from_contribs = false;
- sq_resetobject(&world_thread);
-}
-
-World::~World()
-{
- sq_release(Scripting::global_vm, &world_thread);
- 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 << "': " <<PHYSFS_getLastError();
- throw std::runtime_error(msg.str());
- }
- }
-
- if(!PHYSFS_isDirectory(dirname.c_str())) {
- std::ostringstream msg;
- msg << "Savegame path '" << dirname << "' is not a directory";
- throw std::runtime_error(msg.str());
- }
-}
-
-void
-World::load(const std::string& filename)
-{
- basedir = FileSystem::dirname(filename);
-
- lisp::Parser parser;
- const lisp::Lisp* root = parser.parse(filename);
-
- const lisp::Lisp* info = root->get_lisp("supertux-world");
- if(info == NULL)
- info = root->get_lisp("supertux-level-subset");
- if(info == NULL)
- throw std::runtime_error("File is not a world or levelsubset file");
-
- hide_from_contribs = false;
- is_levelset = true;
-
- info->get("title", title);
- info->get("description", description);
- info->get("levelset", is_levelset);
- info->get_vector("levels", levels);
- info->get("hide-from-contribs", hide_from_contribs);
-
- // Level info file doesn't define any levels, so read the
- // directory to see what we can find
-
- std::string path = basedir;
- char** files = PHYSFS_enumerateFiles(path.c_str());
- if(!files) {
- log_warning << "Couldn't read subset dir '" << path << "'" << std::endl;
- return;
- }
-
- for(const char* const* filename = files; *filename != 0; ++filename) {
- if(has_suffix(*filename, ".stl")) {
- levels.push_back(path + *filename);
- }
- }
- PHYSFS_freeList(files);
-}
-
-void
-World::run()
-{
- using namespace Scripting;
-
- current_ = this;
-
- // create new squirrel table for persisten game state
- HSQUIRRELVM vm = Scripting::global_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";
- try {
- IFileStream in(filename);
-
- sq_release(global_vm, &world_thread);
- world_thread = create_thread(global_vm);
- compile_and_run(object_to_vm(world_thread), in, filename);
- } catch(std::exception& ) {
- // fallback: try to load worldmap worldmap.stwm
- using namespace WorldMapNS;
- main_loop->push_screen(new WorldMap(basedir + "worldmap.stwm"));
- }
-}
-
-void
-World::save_state()
-{
- using namespace Scripting;
-
- 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());
- }
-
- writer.start_list("tux");
- player_status->write(writer);
- writer.end_list("tux");
-
- writer.start_list("state");
-
- sq_pushroottable(global_vm);
- sq_pushstring(global_vm, "state", -1);
- if(SQ_SUCCEEDED(sq_get(global_vm, -2))) {
- Scripting::save_squirrel_table(global_vm, -1, writer);
- sq_pop(global_vm, 1);
- }
- sq_pop(global_vm, 1);
- writer.end_list("state");
-
- writer.end_list("supertux-savegame");
-}
-
-void
-World::load_state()
-{
- using namespace Scripting;
-
- try {
- lisp::Parser parser;
- const lisp::Lisp* 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");
-
- sq_pushroottable(global_vm);
- sq_pushstring(global_vm, "state", -1);
- if(SQ_FAILED(sq_deleteslot(global_vm, -2, SQFalse)))
- sq_pop(global_vm, 1);
-
- sq_pushstring(global_vm, "state", -1);
- sq_newtable(global_vm);
- load_squirrel_table(global_vm, -1, state);
- if(SQ_FAILED(sq_createslot(global_vm, -3)))
- throw std::runtime_error("Couldn't create state table");
- sq_pop(global_vm, 1);
- } catch(std::exception& e) {
- log_debug << "Couldn't load savegame: " << e.what() << std::endl;
- }
-}
-
-const std::string&
-World::get_level_filename(unsigned int i) const
-{
- return levels[i];
-}
-
-unsigned int
-World::get_num_levels() const
-{
- return levels.size();
-}
-
-const std::string&
-World::get_basedir() const
-{
- return basedir;
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#ifndef SUPERTUX_WORLD_H
-#define SUPERTUX_WORLD_H
-
-#include <vector>
-#include <string>
-#include <squirrel.h>
-
-class World
-{
-private:
- std::vector<std::string> levels;
- std::string basedir;
- std::string savegame_filename;
- /// squirrel table that saves persistent state (about the world)
- HSQOBJECT state_table;
- HSQOBJECT world_thread;
- static World* current_;
-
-public:
- World();
- ~World();
-
- void set_savegame_filename(const std::string& filename);
- void load(const std::string& filename);
-
- void save_state();
- void load_state();
-
- const std::string& get_level_filename(unsigned int i) const;
- unsigned int get_num_levels() const;
-
- const std::string& get_basedir() const;
-
- static World* current()
- {
- return current_;
- }
-
- void run();
-
- std::string title;
- std::string description;
- bool hide_from_contribs;
- bool is_levelset;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux - Worldmap Direction
-// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
-//
-// 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.
-#ifndef __WORLDMAP_DIRECTION_HPP__
-#define __WORLDMAP_DIRECTION_HPP__
-
-namespace WorldMapNS {
-
-enum Direction { D_NONE, D_WEST, D_EAST, D_NORTH, D_SOUTH };
-
-}
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2004 Ingo Ruhnke <grumbel@gmx.de>
-// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
-//
-// 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.
-#include <config.h>
-
-#include <stddef.h>
-#include <physfs.h>
-#include "worldmap/level.hpp"
-#include "sprite/sprite_manager.hpp"
-#include "sprite/sprite.hpp"
-#include "video/drawing_context.hpp"
-#include "log.hpp"
-#include "file_system.hpp"
-
-namespace WorldMapNS
-{
-
-LevelTile::LevelTile(const std::string& basedir, const lisp::Lisp* lisp)
- : solved(false), auto_play(false), basedir(basedir), picture_cached(false),
- picture(0)
-{
- lisp->get("name", name);
- lisp->get("x", pos.x);
- lisp->get("y", pos.y);
- lisp->get("auto-play", auto_play);
-
- std::string spritefile = "images/worldmap/common/leveldot.sprite";
- lisp->get("sprite", spritefile);
- sprite.reset(sprite_manager->create(spritefile));
-
- lisp->get("extro-script", extro_script);
-
- if (!PHYSFS_exists((basedir + name).c_str()))
- {
- log_warning << "level file '" << name
- << "' does not exist and will not be added to the worldmap" << std::endl;
- return;
- }
-}
-
-LevelTile::~LevelTile()
-{
- delete picture;
-}
-
-void
-LevelTile::draw(DrawingContext& context)
-{
- sprite->draw(context, pos*32 + Vector(16, 16), LAYER_OBJECTS - 1);
-}
-
-void
-LevelTile::update(float )
-{
-}
-
-const Surface*
-LevelTile::get_picture()
-{
- if (picture_cached) return picture;
- picture_cached = true;
- std::string fname = FileSystem::strip_extension(basedir + name)+".jpg";
- if (!PHYSFS_exists(fname.c_str())) {
- return 0;
- }
- picture = new Surface(fname);
- return picture;
-}
-
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2004 Ingo Ruhnke <grumbel@gmx.de>
-// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
-//
-// 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.
-#ifndef __LEVEL_TILE_HPP__
-#define __LEVEL_TILE_HPP__
-
-#include <memory>
-#include <string>
-#include "math/vector.hpp"
-#include "game_object.hpp"
-#include "statistics.hpp"
-#include "video/surface.hpp"
-
-class Sprite;
-
-namespace WorldMapNS
-{
-
-class LevelTile : public GameObject
-{
-public:
- LevelTile(const std::string& basedir, const lisp::Lisp* lisp);
- virtual ~LevelTile();
-
- virtual void draw(DrawingContext& context);
- virtual void update(float elapsed_time);
-
- Vector pos;
- std::string title;
- bool solved;
- bool auto_play; /**< true if Tux should automatically enter this level if it's unfinished */
-
- std::auto_ptr<Sprite> sprite;
-
- /** Statistics for level tiles */
- Statistics statistics;
-
- /** Script that is run when the level is successfully finished */
- std::string extro_script;
-
- /** return Surface of level picture or 0 if no picture is available */
- const Surface* get_picture();
-
-private:
- std::string basedir;
- bool picture_cached;
- Surface* picture;
-
-};
-
-}
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux - Worldmap Spawnpoint
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include <stdexcept>
-#include <iostream>
-#include "spawn_point.hpp"
-#include "lisp/lisp.hpp"
-#include "lisp/list_iterator.hpp"
-#include "log.hpp"
-
-namespace WorldMapNS
-{
-
-// from worldmap.cpp
-Direction string_to_direction(const std::string& directory);
-
-SpawnPoint::SpawnPoint(const lisp::Lisp* slisp) : auto_dir(D_NONE)
-{
- pos.x = -1;
- pos.y = -1;
- lisp::ListIterator iter(slisp);
- while(iter.next()) {
- const std::string& token = iter.item();
- if(token == "name") {
- iter.value()->get(name);
- } else if(token == "x") {
- iter.value()->get(pos.x);
- } else if(token == "y") {
- iter.value()->get(pos.y);
- } else if(token == "auto-dir") {
- std::string s = "";
- iter.value()->get(s);
- auto_dir = string_to_direction(s);
- } else {
- log_warning << "unknown token '" << token << "' in SpawnPoint" << std::endl;
- }
- }
-
- if(name == "")
- throw std::runtime_error("No name specified for spawnpoint");
- if(pos.x < 0 || pos.y < 0)
- throw std::runtime_error("Invalid coordinates for spawnpoint");
-}
-
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux - Worldmap Spawnpoint
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#ifndef __WORLDMAP_SPAWN_POINT_H__
-#define __WORLDMAP_SPAWN_POINT_H__
-
-#include <string>
-#include "math/vector.hpp"
-#include "lisp/lisp.hpp"
-#include "game_object.hpp"
-#include "worldmap/direction.hpp"
-
-namespace WorldMapNS
-{
-
-class SpawnPoint
-{
-public:
- SpawnPoint(const lisp::Lisp* lisp);
-
- std::string name;
- Vector pos;
- Direction auto_dir; /**< automatically start walking in this direction */
-};
-
-}
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2004 Ingo Ruhnke <grumbel@gmx.de>
-// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
-//
-// 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.
-#include <config.h>
-
-#include "worldmap/special_tile.hpp"
-#include "sprite/sprite_manager.hpp"
-#include "sprite/sprite.hpp"
-#include "video/drawing_context.hpp"
-
-namespace WorldMapNS
-{
-
-SpecialTile::SpecialTile(const lisp::Lisp* lisp)
- : passive_message(false), invisible(false),
- apply_action_north(true), apply_action_east(true),
- apply_action_south(true), apply_action_west(true)
-{
- lisp->get("x", pos.x);
- lisp->get("y", pos.y);
- lisp->get("invisible-tile", invisible);
-
- if(!invisible) {
- std::string spritefile = "";
- lisp->get("sprite", spritefile);
- sprite.reset(sprite_manager->create(spritefile));
- }
-
- lisp->get("map-message", map_message);
- lisp->get("passive-message", passive_message);
- lisp->get("script", script);
-
- std::string apply_direction;
- lisp->get("apply-to-direction", apply_direction);
- if(!apply_direction.empty()) {
- apply_action_north = false;
- apply_action_south = false;
- apply_action_east = false;
- apply_action_west = false;
- if(apply_direction.find("north") != std::string::npos)
- apply_action_north = true;
- if(apply_direction.find("south") != std::string::npos)
- apply_action_south = true;
- if(apply_direction.find("east") != std::string::npos)
- apply_action_east = true;
- if(apply_direction.find("west") != std::string::npos)
- apply_action_west = true;
- }
-}
-
-SpecialTile::~SpecialTile()
-{
-}
-
-void
-SpecialTile::draw(DrawingContext& context)
-{
- if(invisible)
- return;
-
- sprite->draw(context, pos*32 + Vector(16, 16), LAYER_OBJECTS - 1);
-}
-
-void
-SpecialTile::update(float )
-{
-}
-
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2004 Ingo Ruhnke <grumbel@gmx.de>
-// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
-//
-// 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.
-#ifndef __WORLDMAP_SPECIAL_TILE_HPP__
-#define __WORLDMAP_SPECIAL_TILE_HPP__
-
-#include <memory>
-#include <string>
-#include "game_object.hpp"
-#include "math/vector.hpp"
-#include "lisp/lisp.hpp"
-
-class Sprite;
-
-namespace WorldMapNS
-{
-
-class SpecialTile : public GameObject
-{
-public:
- SpecialTile(const lisp::Lisp* lisp);
- virtual ~SpecialTile();
-
- virtual void draw(DrawingContext& context);
- virtual void update(float elapsed_time);
-
- Vector pos;
-
- /** Sprite to render instead of guessing what image to draw */
- std::auto_ptr<Sprite> sprite;
-
- /** Message to show in the Map */
- std::string map_message;
- bool passive_message;
-
- /** Script to execute when tile is touched */
- std::string script;
-
- /** Hide special tile */
- bool invisible;
-
- /** Only applies actions (ie. passive messages) when going to that direction */
- bool apply_action_north;
- bool apply_action_east;
- bool apply_action_south;
- bool apply_action_west;
-};
-
-}
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#include <config.h>
-
-#include "sprite_change.hpp"
-#include "sprite/sprite_manager.hpp"
-#include "sprite/sprite.hpp"
-#include "video/drawing_context.hpp"
-
-namespace WorldMapNS
-{
-
-SpriteChange::SpriteChange(const lisp::Lisp* lisp)
- : change_on_touch(false), in_stay_action(false)
-{
- lisp->get("x", pos.x);
- lisp->get("y", pos.y);
- lisp->get("change-on-touch", change_on_touch);
-
- std::string spritefile = "";
- lisp->get("sprite", spritefile);
- sprite.reset(sprite_manager->create(spritefile));
-
- lisp->get("stay-action", stay_action);
- lisp->get("initial-stay-action", in_stay_action);
-
- lisp->get("stay-group", stay_group);
-
- all_sprite_changes.push_back(this);
-}
-
-SpriteChange::~SpriteChange()
-{
- all_sprite_changes.remove(this);
-}
-
-void
-SpriteChange::draw(DrawingContext& context)
-{
- if(in_stay_action && stay_action != "") {
- sprite->set_action(stay_action);
- sprite->draw(context, pos * 32, LAYER_OBJECTS-1);
- }
-}
-
-void
-SpriteChange::update(float )
-{
-}
-
-void
-SpriteChange::set_stay_action()
-{
- in_stay_action = true;
-}
-
-void
-SpriteChange::clear_stay_action()
-{
- in_stay_action = false;
-
- // if we are in a stay_group, also clear all stay actions in this group
- if (stay_group != "") {
- for (std::list<SpriteChange*>::iterator i = all_sprite_changes.begin(); i != all_sprite_changes.end(); i++) {
- SpriteChange* sc = *i;
- if (sc->stay_group != stay_group) continue;
- sc->in_stay_action = false;
- }
- }
-}
-
-std::list<SpriteChange*> SpriteChange::all_sprite_changes;
-
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#ifndef __WORLDMAP_SPRITE_CHANGE_HPP__
-#define __WORLDMAP_SPRITE_CHANGE_HPP__
-
-#include <string>
-#include <memory>
-#include <list>
-#include "game_object.hpp"
-#include "lisp/lisp.hpp"
-#include "math/vector.hpp"
-
-class Sprite;
-
-namespace WorldMapNS
-{
-
-class SpriteChange : public GameObject
-{
-public:
- SpriteChange(const lisp::Lisp* lisp);
- virtual ~SpriteChange();
-
- Vector pos;
- /**
- * should tuxs sprite change when the tile has been completely entered,
- * or already when the tile was just touched
- */
- bool change_on_touch;
- /// sprite to change tux image to
- std::auto_ptr<Sprite> sprite;
- /**
- * stay action can be used for objects like boats or cars, if it is
- * != "" then this sprite will be displayed when tux left the tile towards
- * another SpriteChange object.
- */
- std::string stay_action;
-
- /**
- * name of a group in which only one SpriteChange will ever have its stay_action displayed.
- * Leave empty if you don't care.
- */
- std::string stay_group;
-
- virtual void draw(DrawingContext& context);
- virtual void update(float elapsed_time);
-
- /**
- * Activates the SpriteChange's stay action, if applicable
- */
- void set_stay_action();
-
- /**
- * Deactivates the SpriteChange's stay action, if applicable
- */
- void clear_stay_action();
-
-private:
- /**
- * should the stayaction be displayed
- */
- bool in_stay_action;
-
- static std::list<SpriteChange*> all_sprite_changes;
-
-};
-
-}
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux - Teleporter Worldmap Tile
-// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
-//
-// 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.
-#include <config.h>
-
-#include "worldmap/teleporter.hpp"
-#include "sprite/sprite_manager.hpp"
-#include "sprite/sprite.hpp"
-#include "video/drawing_context.hpp"
-
-namespace WorldMapNS
-{
-
-Teleporter::Teleporter(const lisp::Lisp* lisp)
- : automatic(false)
-{
- lisp->get("x", pos.x);
- lisp->get("y", pos.y);
-
- std::string spritefile = "";
- if (lisp->get("sprite", spritefile)) {
- sprite.reset(sprite_manager->create(spritefile));
- }
-
- lisp->get("worldmap", worldmap);
- lisp->get("spawnpoint", spawnpoint);
- lisp->get("automatic", automatic);
- lisp->get("message", message);
-}
-
-void
-Teleporter::draw(DrawingContext& context)
-{
- if (sprite.get() != 0) sprite->draw(context, pos*32 + Vector(16, 16), LAYER_OBJECTS - 1);
-}
-
-void
-Teleporter::update(float )
-{
-}
-
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux - Teleporter Worldmap Tile
-// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
-//
-// 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.
-#ifndef __WORLDMAP_TELEPORTER_HPP__
-#define __WORLDMAP_TELEPORTER_HPP__
-
-#include <memory>
-#include <string>
-#include "game_object.hpp"
-#include "math/vector.hpp"
-#include "lisp/lisp.hpp"
-
-class Sprite;
-
-namespace WorldMapNS
-{
-
-class Teleporter : public GameObject
-{
-public:
- Teleporter(const lisp::Lisp* lisp);
-
- virtual void draw(DrawingContext& context);
- virtual void update(float elapsed_time);
-
- /** Position (in tiles, not pixels) */
- Vector pos;
-
- /** Sprite to render, or 0 for no sprite */
- std::auto_ptr<Sprite> sprite;
-
- /** Worldmap filename (relative to data root) to teleport to. Leave empty to use current word */
- std::string worldmap;
-
- /** Spawnpoint to teleport to. Leave empty to use "main" or last one */
- std::string spawnpoint;
-
- /** true if this teleporter does not need to be activated, but teleports Tux as soon as it's touched */
- bool automatic;
-
- /** optional map message to display */
- std::string message;
-
-};
-
-}
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux - A Jump'n Run
-// Copyright (C) 2004 Ingo Ruhnke <grumbel@gmx.de>
-// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
-//
-// 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.
-#include <config.h>
-
-#include "tux.hpp"
-#include "sprite/sprite.hpp"
-#include "sprite/sprite_manager.hpp"
-#include "video/drawing_context.hpp"
-#include "player_status.hpp"
-#include "worldmap.hpp"
-#include "worldmap/level.hpp"
-#include "special_tile.hpp"
-#include "sprite_change.hpp"
-#include "control/joystickkeyboardcontroller.hpp"
-#include "scripting/squirrel_util.hpp"
-#include "main.hpp"
-
-namespace WorldMapNS
-{
-
-static const float TUXSPEED = 200;
-static const float map_message_TIME = 2.8f;
-
-Tux::Tux(WorldMap* worldmap_)
- : worldmap(worldmap_)
-{
- sprite.reset(sprite_manager->create("images/worldmap/common/tux.sprite"));
-
- offset = 0;
- moving = false;
- direction = D_NONE;
- input_direction = D_NONE;
-}
-
-Tux::~Tux()
-{
-}
-
-void
-Tux::draw(DrawingContext& context)
-{
- switch (player_status->bonus) {
- case GROWUP_BONUS:
- sprite->set_action(moving ? "large-walking" : "large-stop");
- break;
- case FIRE_BONUS:
- sprite->set_action(moving ? "fire-walking" : "fire-stop");
- break;
- case NO_BONUS:
- sprite->set_action(moving ? "small-walking" : "small-stop");
- break;
- default:
- log_debug << "Bonus type not handled in worldmap." << std::endl;
- sprite->set_action("large-stop");
- break;
- }
-
- sprite->draw(context, get_pos(), LAYER_OBJECTS);
-}
-
-
-Vector
-Tux::get_pos()
-{
- float x = tile_pos.x * 32;
- float y = tile_pos.y * 32;
-
- switch(direction)
- {
- case D_WEST:
- x -= offset - 32;
- break;
- case D_EAST:
- x += offset - 32;
- break;
- case D_NORTH:
- y -= offset - 32;
- break;
- case D_SOUTH:
- y += offset - 32;
- break;
- case D_NONE:
- break;
- }
-
- return Vector(x, y);
-}
-
-void
-Tux::stop()
-{
- offset = 0;
- direction = D_NONE;
- input_direction = D_NONE;
- moving = false;
-}
-
-void
-Tux::set_direction(Direction dir)
-{
- input_direction = dir;
-}
-
-void
-Tux::tryStartWalking()
-{
- if (moving)
- return;
- if (input_direction == D_NONE)
- return;
-
- LevelTile* level = worldmap->at_level();
-
- // We got a new direction, so lets start walking when possible
- Vector next_tile;
- if ((!level || level->solved)
- && worldmap->path_ok(input_direction, tile_pos, &next_tile)) {
- tile_pos = next_tile;
- moving = true;
- direction = input_direction;
- back_direction = reverse_dir(direction);
- } else if (input_direction == back_direction) {
- moving = true;
- direction = input_direction;
- tile_pos = worldmap->get_next_tile(tile_pos, direction);
- back_direction = reverse_dir(direction);
- }
-}
-
-bool
-Tux::canWalk(int tile_data, Direction dir)
-{
- return ((tile_data & Tile::WORLDMAP_NORTH && dir == D_NORTH) ||
- (tile_data & Tile::WORLDMAP_SOUTH && dir == D_SOUTH) ||
- (tile_data & Tile::WORLDMAP_EAST && dir == D_EAST) ||
- (tile_data & Tile::WORLDMAP_WEST && dir == D_WEST));
-}
-
-void
-Tux::tryContinueWalking(float elapsed_time)
-{
- if (!moving)
- return;
-
- // Let tux walk
- offset += TUXSPEED * elapsed_time;
-
- // Do nothing if we have not yet reached the next tile
- if (offset <= 32)
- return;
-
- offset -= 32;
-
- SpriteChange* sprite_change = worldmap->at_sprite_change(tile_pos);
- if(sprite_change != NULL) {
- sprite.reset(new Sprite( *(sprite_change->sprite.get()) ));
- sprite_change->clear_stay_action();
- }
-
- // if this is a special_tile with passive_message, display it
- SpecialTile* special_tile = worldmap->at_special_tile();
- if(special_tile)
- {
- // direction and the apply_action_ are opposites, since they "see"
- // directions in a different way
- if((direction == D_NORTH && special_tile->apply_action_south) ||
- (direction == D_SOUTH && special_tile->apply_action_north) ||
- (direction == D_WEST && special_tile->apply_action_east) ||
- (direction == D_EAST && special_tile->apply_action_west))
- {
- if(special_tile->passive_message) {
- worldmap->passive_message = special_tile->map_message;
- worldmap->passive_message_timer.start(map_message_TIME);
- } else if(special_tile->script != "") {
- try {
- std::istringstream in(special_tile->script);
- worldmap->run_script(in, "specialtile");
- } catch(std::exception& e) {
- log_warning << "Couldn't execute special tile script: " << e.what()
- << std::endl;
- }
- }
- }
- }
-
- // check if we are at a Teleporter
- Teleporter* teleporter = worldmap->at_teleporter(tile_pos);
-
- // stop if we reached a level, a WORLDMAP_STOP tile, a teleporter or a special tile without a passive_message
- if ((worldmap->at_level())
- || (worldmap->tile_data_at(tile_pos) & Tile::WORLDMAP_STOP)
- || (special_tile && !special_tile->passive_message
- && special_tile->script == "")
- || (teleporter)) {
- if(special_tile && !special_tile->map_message.empty()
- && !special_tile->passive_message)
- worldmap->passive_message_timer.start(0);
- stop();
- return;
- }
-
- // if user wants to change direction, try changing, else guess the direction in which to walk next
- const int tile_data = worldmap->tile_data_at(tile_pos);
- if ((direction != input_direction) && canWalk(tile_data, input_direction)) {
- direction = input_direction;
- back_direction = reverse_dir(direction);
- } else {
- Direction dir = D_NONE;
- if (tile_data & Tile::WORLDMAP_NORTH && back_direction != D_NORTH)
- dir = D_NORTH;
- else if (tile_data & Tile::WORLDMAP_SOUTH && back_direction != D_SOUTH)
- dir = D_SOUTH;
- else if (tile_data & Tile::WORLDMAP_EAST && back_direction != D_EAST)
- dir = D_EAST;
- else if (tile_data & Tile::WORLDMAP_WEST && back_direction != D_WEST)
- dir = D_WEST;
-
- if (dir == D_NONE) {
- // Should never be reached if tiledata is good
- log_warning << "Could not determine where to walk next" << std::endl;
- stop();
- return;
- }
-
- direction = dir;
- input_direction = direction;
- back_direction = reverse_dir(direction);
- }
-
- // Walk automatically to the next tile
- if(direction == D_NONE)
- return;
-
- Vector next_tile;
- if (!worldmap->path_ok(direction, tile_pos, &next_tile)) {
- log_debug << "Tilemap data is buggy" << std::endl;
- stop();
- return;
- }
-
- SpriteChange* next_sprite = worldmap->at_sprite_change(next_tile);
- if(next_sprite != NULL && next_sprite->change_on_touch) {
- sprite.reset(new Sprite( *(next_sprite->sprite.get()) ));
- next_sprite->clear_stay_action();
- }
- SpriteChange* last_sprite = worldmap->at_sprite_change(tile_pos);
- if(last_sprite != NULL && next_sprite != NULL) {
- log_debug << "Old: " << tile_pos << " New: " << next_tile << std::endl;
- last_sprite->set_stay_action();
- }
-
- tile_pos = next_tile;
-}
-
-void
-Tux::updateInputDirection()
-{
- if(main_controller->hold(Controller::UP))
- input_direction = D_NORTH;
- else if(main_controller->hold(Controller::DOWN))
- input_direction = D_SOUTH;
- else if(main_controller->hold(Controller::LEFT))
- input_direction = D_WEST;
- else if(main_controller->hold(Controller::RIGHT))
- input_direction = D_EAST;
-}
-
-void
-Tux::update(float elapsed_time)
-{
- updateInputDirection();
- if (moving)
- tryContinueWalking(elapsed_time);
- else
- tryStartWalking();
-}
-
-void
-Tux::setup()
-{
- // check if we already touch a SpriteChange object
- SpriteChange* sprite_change = worldmap->at_sprite_change(tile_pos);
- if(sprite_change != NULL) {
- sprite.reset(new Sprite( *(sprite_change->sprite.get()) ));
- sprite_change->clear_stay_action();
- }
-}
-
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux - A Jump'n Run
-// Copyright (C) 2004 Ingo Ruhnke <grumbel@gmx.de>
-// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
-//
-// 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.
-#ifndef __WORLDMAP_TUX_HPP__
-#define __WORLDMAP_TUX_HPP__
-
-#include <memory>
-#include "game_object.hpp"
-#include "worldmap.hpp"
-
-class Sprite;
-
-namespace WorldMapNS
-{
-
-class WorldMap;
-
-class Tux : public GameObject
-{
-public:
- Direction back_direction;
-private:
- WorldMap* worldmap;
- std::auto_ptr<Sprite> sprite;
- Controller* controller;
-
- Direction input_direction;
- Direction direction;
- Vector tile_pos;
- /** Length by which tux is away from its current tile, length is in
- input_direction direction */
- float offset;
- bool moving;
-
- void stop();
-
- bool canWalk(int tile_data, Direction dir); /**< check if we can leave a tile (with given "tile_data") in direction "dir" */
- void updateInputDirection(); /**< if controller was pressed, update input_direction */
- void tryStartWalking(); /**< try starting to walk in input_direction */
- void tryContinueWalking(float elapsed_time); /**< try to continue walking in current direction */
-
-public:
- Tux(WorldMap* worldmap_);
- ~Tux();
-
- void setup(); /**< called prior to first update */
- void draw(DrawingContext& context);
- void update(float elapsed_time);
-
- void set_direction(Direction dir);
-
- bool is_moving() const { return moving; }
- Vector get_pos();
- Vector get_tile_pos() const { return tile_pos; }
- void set_tile_pos(Vector p) { tile_pos = p; }
-};
-
-}
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux - A Jump'n Run
-// Copyright (C) 2004 Ingo Ruhnke <grumbel@gmx.de>
-// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
-//
-// 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.
-#include <config.h>
-
-#include <iostream>
-#include <fstream>
-#include <vector>
-#include <cassert>
-#include <stdexcept>
-#include <sstream>
-#include <unistd.h>
-#include <physfs.h>
-
-#include "worldmap.hpp"
-
-#include "gettext.hpp"
-#include "log.hpp"
-#include "mainloop.hpp"
-#include "shrinkfade.hpp"
-#include "video/surface.hpp"
-#include "video/drawing_context.hpp"
-#include "sprite/sprite.hpp"
-#include "sprite/sprite_manager.hpp"
-#include "audio/sound_manager.hpp"
-#include "lisp/parser.hpp"
-#include "lisp/lisp.hpp"
-#include "lisp/list_iterator.hpp"
-#include "lisp/writer.hpp"
-#include "game_session.hpp"
-#include "sector.hpp"
-#include "worldmap.hpp"
-#include "resources.hpp"
-#include "log.hpp"
-#include "world.hpp"
-#include "player_status.hpp"
-#include "textscroller.hpp"
-#include "main.hpp"
-#include "spawn_point.hpp"
-#include "file_system.hpp"
-#include "gui/menu.hpp"
-#include "gui/mousecursor.hpp"
-#include "control/joystickkeyboardcontroller.hpp"
-#include "object/background.hpp"
-#include "object/tilemap.hpp"
-#include "options_menu.hpp"
-#include "scripting/squirrel_error.hpp"
-#include "scripting/squirrel_util.hpp"
-#include "worldmap/level.hpp"
-#include "worldmap/special_tile.hpp"
-#include "worldmap/tux.hpp"
-#include "worldmap/sprite_change.hpp"
-
-namespace WorldMapNS {
-
-enum WorldMapMenuIDs {
- MNID_RETURNWORLDMAP,
- MNID_QUITWORLDMAP
-};
-
-WorldMap* WorldMap::current_ = NULL;
-
-Direction reverse_dir(Direction direction)
-{
- switch(direction)
- {
- case D_WEST:
- return D_EAST;
- case D_EAST:
- return D_WEST;
- case D_NORTH:
- return D_SOUTH;
- case D_SOUTH:
- return D_NORTH;
- case D_NONE:
- return D_NONE;
- }
- return D_NONE;
-}
-
-std::string
-direction_to_string(Direction direction)
-{
- switch(direction)
- {
- case D_WEST:
- return "west";
- case D_EAST:
- return "east";
- case D_NORTH:
- return "north";
- case D_SOUTH:
- return "south";
- default:
- return "none";
- }
-}
-
-Direction
-string_to_direction(const std::string& directory)
-{
- if (directory == "west")
- return D_WEST;
- else if (directory == "east")
- return D_EAST;
- else if (directory == "north")
- return D_NORTH;
- else if (directory == "south")
- return D_SOUTH;
- else if (directory == "none")
- return D_NONE;
- else {
- log_warning << "unknown direction: \"" << directory << "\"" << std::endl;
- return D_NONE;
- }
-}
-
-//---------------------------------------------------------------------------
-
-WorldMap::WorldMap(const std::string& filename, const std::string& force_spawnpoint)
- : tux(0), ambient_light( 1.0f, 1.0f, 1.0f, 1.0f ), force_spawnpoint(force_spawnpoint), in_level(false)
-{
- tile_manager.reset(new TileManager("images/worldmap.strf"));
-
- tux = new Tux(this);
- add_object(tux);
-
- name = "<no title>";
- music = "music/salcon.ogg";
-
- total_stats.reset();
-
- worldmap_menu.reset(new Menu());
- worldmap_menu->add_label(_("Pause"));
- worldmap_menu->add_hl();
- worldmap_menu->add_entry(MNID_RETURNWORLDMAP, _("Continue"));
- worldmap_menu->add_submenu(_("Options"), get_options_menu());
- worldmap_menu->add_hl();
- worldmap_menu->add_entry(MNID_QUITWORLDMAP, _("Quit World"));
-
- // create a new squirrel table for the worldmap
- using namespace Scripting;
-
- sq_collectgarbage(global_vm);
- sq_newtable(global_vm);
- sq_pushroottable(global_vm);
- if(SQ_FAILED(sq_setdelegate(global_vm, -2)))
- throw Scripting::SquirrelError(global_vm, "Couldn't set worldmap_table delegate");
-
- sq_resetobject(&worldmap_table);
- if(SQ_FAILED(sq_getstackobj(global_vm, -1, &worldmap_table)))
- throw Scripting::SquirrelError(global_vm, "Couldn't get table from stack");
-
- sq_addref(global_vm, &worldmap_table);
- sq_pop(global_vm, 1);
-
- // load worldmap objects
- load(filename);
-}
-
-WorldMap::~WorldMap()
-{
- using namespace Scripting;
-
- for(GameObjects::iterator i = game_objects.begin();
- i != game_objects.end(); ++i) {
- GameObject* object = *i;
- try_unexpose(object);
- object->unref();
- }
-
- for(SpawnPoints::iterator i = spawn_points.begin();
- i != spawn_points.end(); ++i) {
- delete *i;
- }
-
- for(ScriptList::iterator i = scripts.begin();
- i != scripts.end(); ++i) {
- HSQOBJECT& object = *i;
- sq_release(global_vm, &object);
- }
- sq_release(global_vm, &worldmap_table);
-
- sq_collectgarbage(global_vm);
-
- if(current_ == this)
- current_ = NULL;
-}
-
-void
-WorldMap::add_object(GameObject* object)
-{
- TileMap* tilemap = dynamic_cast<TileMap*> (object);
- if(tilemap != 0 && tilemap->is_solid()) {
- solid_tilemaps.push_back(tilemap);
- }
-
- object->ref();
- try_expose(object);
- game_objects.push_back(object);
-}
-
-void
-WorldMap::try_expose(GameObject* object)
-{
- ScriptInterface* interface = dynamic_cast<ScriptInterface*> (object);
- if(interface != NULL) {
- HSQUIRRELVM vm = Scripting::global_vm;
- sq_pushobject(vm, worldmap_table);
- interface->expose(vm, -1);
- sq_pop(vm, 1);
- }
-}
-
-void
-WorldMap::try_unexpose(GameObject* object)
-{
- ScriptInterface* interface = dynamic_cast<ScriptInterface*> (object);
- if(interface != NULL) {
- HSQUIRRELVM vm = Scripting::global_vm;
- SQInteger oldtop = sq_gettop(vm);
- sq_pushobject(vm, worldmap_table);
- try {
- interface->unexpose(vm, -1);
- } catch(std::exception& e) {
- log_warning << "Couldn't unregister object: " << e.what() << std::endl;
- }
- sq_settop(vm, oldtop);
- }
-}
-
-void
-WorldMap::move_to_spawnpoint(const std::string& spawnpoint)
-{
- for(SpawnPoints::iterator i = spawn_points.begin(); i != spawn_points.end(); ++i) {
- SpawnPoint* sp = *i;
- if(sp->name == spawnpoint) {
- Vector p = sp->pos;
- tux->set_tile_pos(p);
- tux->set_direction(sp->auto_dir);
- return;
- }
- }
- log_warning << "Spawnpoint '" << spawnpoint << "' not found." << std::endl;
- if (spawnpoint != "main") {
- move_to_spawnpoint("main");
- }
-}
-
-void
-WorldMap::change(const std::string& filename, const std::string& force_spawnpoint)
-{
- main_loop->exit_screen();
- main_loop->push_screen(new WorldMap(filename, force_spawnpoint));
-}
-
-void
-WorldMap::load(const std::string& filename)
-{
- map_filename = filename;
- levels_path = FileSystem::dirname(map_filename);
-
- try {
- lisp::Parser parser;
- const lisp::Lisp* root = parser.parse(map_filename);
-
- const lisp::Lisp* lisp = root->get_lisp("supertux-level");
- if(!lisp)
- throw std::runtime_error("file isn't a supertux-level file.");
-
- lisp->get("name", name);
-
- const lisp::Lisp* sector = lisp->get_lisp("sector");
- if(!sector)
- throw std::runtime_error("No sector sepcified in worldmap file.");
-
- lisp::ListIterator iter(sector);
- while(iter.next()) {
- if(iter.item() == "tilemap") {
- add_object(new TileMap(*(iter.lisp()), tile_manager.get()));
- } else if(iter.item() == "background") {
- add_object(new Background(*(iter.lisp())));
- } else if(iter.item() == "music") {
- iter.value()->get(music);
- } else if(iter.item() == "init-script") {
- iter.value()->get(init_script);
- } else if(iter.item() == "worldmap-spawnpoint") {
- SpawnPoint* sp = new SpawnPoint(iter.lisp());
- spawn_points.push_back(sp);
- } else if(iter.item() == "level") {
- LevelTile* level = new LevelTile(levels_path, iter.lisp());
- levels.push_back(level);
- add_object(level);
- } else if(iter.item() == "special-tile") {
- SpecialTile* special_tile = new SpecialTile(iter.lisp());
- special_tiles.push_back(special_tile);
- add_object(special_tile);
- } else if(iter.item() == "sprite-change") {
- SpriteChange* sprite_change = new SpriteChange(iter.lisp());
- sprite_changes.push_back(sprite_change);
- add_object(sprite_change);
- } else if(iter.item() == "teleporter") {
- Teleporter* teleporter = new Teleporter(iter.lisp());
- teleporters.push_back(teleporter);
- add_object(teleporter);
- } else if(iter.item() == "ambient-light") {
- std::vector<float> vColor;
- sector->get_vector( "ambient-light", vColor );
- if(vColor.size() < 3) {
- log_warning << "(ambient-light) requires a color as argument" << std::endl;
- } else {
- ambient_light = Color( vColor );
- }
- } else if(iter.item() == "name") {
- // skip
- } else {
- log_warning << "Unknown token '" << iter.item() << "' in worldmap" << std::endl;
- }
- }
- if(solid_tilemaps.size() == 0)
- throw std::runtime_error("No solid tilemap specified");
-
- move_to_spawnpoint("main");
-
- } catch(std::exception& e) {
- std::stringstream msg;
- msg << "Problem when parsing worldmap '" << map_filename << "': " <<
- e.what();
- throw std::runtime_error(msg.str());
- }
-}
-
-void
-WorldMap::get_level_title(LevelTile& level)
-{
- /** get special_tile's title */
- level.title = "<no title>";
-
- try {
- lisp::Parser parser;
- const lisp::Lisp* root = parser.parse(levels_path + level.get_name());
-
- const lisp::Lisp* level_lisp = root->get_lisp("supertux-level");
- if(!level_lisp)
- return;
-
- level_lisp->get("name", level.title);
- } catch(std::exception& e) {
- log_warning << "Problem when reading leveltitle: " << e.what() << std::endl;
- return;
- }
-}
-
-void WorldMap::calculate_total_stats()
-{
- total_stats.zero();
- for(LevelTiles::iterator i = levels.begin(); i != levels.end(); ++i) {
- LevelTile* level = *i;
- if (level->solved) {
- total_stats += level->statistics;
- }
- }
-}
-
-void
-WorldMap::on_escape_press()
-{
- // Show or hide the menu
- if(!Menu::current()) {
- Menu::set_current(worldmap_menu.get());
- tux->set_direction(D_NONE); // stop tux movement when menu is called
- } else {
- Menu::set_current(NULL);
- }
-}
-
-Vector
-WorldMap::get_next_tile(Vector pos, Direction direction)
-{
- switch(direction) {
- case D_WEST:
- pos.x -= 1;
- break;
- case D_EAST:
- pos.x += 1;
- break;
- case D_NORTH:
- pos.y -= 1;
- break;
- case D_SOUTH:
- pos.y += 1;
- break;
- case D_NONE:
- break;
- }
- return pos;
-}
-
-bool
-WorldMap::path_ok(Direction direction, const Vector& old_pos, Vector* new_pos)
-{
- *new_pos = get_next_tile(old_pos, direction);
-
- if (!(new_pos->x >= 0 && new_pos->x < get_width()
- && new_pos->y >= 0 && new_pos->y < get_height()))
- { // New position is outsite the tilemap
- return false;
- }
- else
- { // Check if the tile allows us to go to new_pos
- int old_tile_data = tile_data_at(old_pos);
- int new_tile_data = tile_data_at(*new_pos);
- switch(direction)
- {
- case D_WEST:
- return (old_tile_data & Tile::WORLDMAP_WEST
- && new_tile_data & Tile::WORLDMAP_EAST);
-
- case D_EAST:
- return (old_tile_data & Tile::WORLDMAP_EAST
- && new_tile_data & Tile::WORLDMAP_WEST);
-
- case D_NORTH:
- return (old_tile_data & Tile::WORLDMAP_NORTH
- && new_tile_data & Tile::WORLDMAP_SOUTH);
-
- case D_SOUTH:
- return (old_tile_data & Tile::WORLDMAP_SOUTH
- && new_tile_data & Tile::WORLDMAP_NORTH);
-
- case D_NONE:
- assert(!"path_ok() can't walk if direction is NONE");
- }
- return false;
- }
-}
-
-void
-WorldMap::finished_level(Level* gamelevel)
-{
- // TODO use Level* parameter here?
- LevelTile* level = at_level();
-
- bool old_level_state = level->solved;
- level->solved = true;
- level->sprite->set_action("solved");
-
- // deal with statistics
- level->statistics.merge(gamelevel->stats);
- calculate_total_stats();
-
- save_state();
-
- if (old_level_state != level->solved) {
- // Try to detect the next direction to which we should walk
- // FIXME: Mostly a hack
- Direction dir = D_NONE;
-
- int dirdata = available_directions_at(tux->get_tile_pos());
- // first, test for crossroads
- if (dirdata == Tile::WORLDMAP_CNSE ||
- dirdata == Tile::WORLDMAP_CNSW ||
- dirdata == Tile::WORLDMAP_CNEW ||
- dirdata == Tile::WORLDMAP_CSEW ||
- dirdata == Tile::WORLDMAP_CNSEW)
- dir = D_NONE;
- else if (dirdata & Tile::WORLDMAP_NORTH
- && tux->back_direction != D_NORTH)
- dir = D_NORTH;
- else if (dirdata & Tile::WORLDMAP_SOUTH
- && tux->back_direction != D_SOUTH)
- dir = D_SOUTH;
- else if (dirdata & Tile::WORLDMAP_EAST
- && tux->back_direction != D_EAST)
- dir = D_EAST;
- else if (dirdata & Tile::WORLDMAP_WEST
- && tux->back_direction != D_WEST)
- dir = D_WEST;
-
- if (dir != D_NONE) {
- tux->set_direction(dir);
- }
- }
-
- if (level->extro_script != "") {
- try {
- std::istringstream in(level->extro_script);
- run_script(in, "worldmap:extro_script");
- } catch(std::exception& e) {
- log_fatal << "Couldn't run level-extro-script: " << e.what() << std::endl;
- }
- }
-}
-
-void
-WorldMap::update(float delta)
-{
- if(!in_level) {
- Menu* menu = Menu::current();
- if(menu != NULL) {
- menu->update();
-
- if(menu == worldmap_menu.get()) {
- switch (worldmap_menu->check())
- {
- case MNID_RETURNWORLDMAP: // Return to game
- Menu::set_current(0);
- break;
- case MNID_QUITWORLDMAP: // Quit Worldmap
- main_loop->exit_screen();
- break;
- }
- }
-
- return;
- }
-
- // update GameObjects
- for(size_t i = 0; i < game_objects.size(); ++i) {
- GameObject* object = game_objects[i];
- object->update(delta);
- }
-
- // remove old GameObjects
- for(GameObjects::iterator i = game_objects.begin();
- i != game_objects.end(); ) {
- GameObject* object = *i;
- if(!object->is_valid()) {
- try_unexpose(object);
- object->unref();
- i = game_objects.erase(i);
- } else {
- ++i;
- }
- }
-
- /* update solid_tilemaps list */
- //FIXME: this could be more efficient
- solid_tilemaps.clear();
- for(std::vector<GameObject*>::iterator i = game_objects.begin();
- i != game_objects.end(); ++i)
- {
- TileMap* tm = dynamic_cast<TileMap*>(*i);
- if (!tm) continue;
- if (tm->is_solid()) solid_tilemaps.push_back(tm);
- }
-
- // position "camera"
- Vector tux_pos = tux->get_pos();
- camera_offset.x = tux_pos.x - SCREEN_WIDTH/2;
- camera_offset.y = tux_pos.y - SCREEN_HEIGHT/2;
-
- if (camera_offset.x < 0)
- camera_offset.x = 0;
- if (camera_offset.y < 0)
- camera_offset.y = 0;
-
- if (camera_offset.x > (int)get_width()*32 - SCREEN_WIDTH)
- camera_offset.x = (int)get_width()*32 - SCREEN_WIDTH;
- if (camera_offset.y > (int)get_height()*32 - SCREEN_HEIGHT)
- camera_offset.y = (int)get_height()*32 - SCREEN_HEIGHT;
-
- if (int(get_width()*32) < SCREEN_WIDTH)
- camera_offset.x = get_width()*16.0 - SCREEN_WIDTH/2.0;
- if (int(get_height()*32) < SCREEN_HEIGHT)
- camera_offset.y = get_height()*16.0 - SCREEN_HEIGHT/2.0;
-
- // handle input
- bool enter_level = false;
- if(main_controller->pressed(Controller::ACTION)
- || main_controller->pressed(Controller::JUMP)
- || main_controller->pressed(Controller::MENU_SELECT)) {
- /* some people define UP and JUMP on the same key... */
- if(!main_controller->pressed(Controller::UP))
- enter_level = true;
- }
- if(main_controller->pressed(Controller::PAUSE_MENU))
- on_escape_press();
-
- // check for teleporters
- Teleporter* teleporter = at_teleporter(tux->get_tile_pos());
- if (teleporter && (teleporter->automatic || (enter_level && (!tux->is_moving())))) {
- enter_level = false;
- if (teleporter->worldmap != "") {
- change(teleporter->worldmap, teleporter->spawnpoint);
- } else {
- // TODO: an animation, camera scrolling or a fading would be a nice touch
- sound_manager->play("sounds/warp.wav");
- tux->back_direction = D_NONE;
- move_to_spawnpoint(teleporter->spawnpoint);
- }
- }
-
- // check for auto-play levels
- LevelTile* level = at_level();
- if (level && (level->auto_play) && (!level->solved) && (!tux->is_moving())) {
- enter_level = true;
- }
-
- if (enter_level && !tux->is_moving())
- {
- /* Check level action */
- LevelTile* level = at_level();
- if (!level) {
- //Respawn if player on a tile with no level and nowhere to go.
- int tile_data = tile_data_at(tux->get_tile_pos());
- if(!( tile_data & ( Tile::WORLDMAP_NORTH | Tile::WORLDMAP_SOUTH | Tile::WORLDMAP_WEST | Tile::WORLDMAP_EAST ))){
- log_warning << "Player at illegal position " << tux->get_tile_pos().x << ", " << tux->get_tile_pos().y << " respawning." << std::endl;
- move_to_spawnpoint("main");
- return;
- }
- log_warning << "No level to enter at: " << tux->get_tile_pos().x << ", " << tux->get_tile_pos().y << std::endl;
- return;
- }
-
- if (level->pos == tux->get_tile_pos()) {
- try {
- Vector shrinkpos = Vector(level->pos.x*32 + 16 - camera_offset.x,
- level->pos.y*32 + 16 - camera_offset.y);
- std::string levelfile = levels_path + level->get_name();
-
- // update state and savegame
- save_state();
-
- main_loop->push_screen(new GameSession(levelfile, &level->statistics),
- new ShrinkFade(shrinkpos, 0.5));
- in_level = true;
- } catch(std::exception& e) {
- log_fatal << "Couldn't load level: " << e.what() << std::endl;
- }
- }
- }
- else
- {
- // tux->set_direction(input_direction);
- }
- }
-}
-
-int
-WorldMap::tile_data_at(Vector p)
-{
- int dirs = 0;
-
- for(std::list<TileMap*>::const_iterator i = solid_tilemaps.begin(); i != solid_tilemaps.end(); i++) {
- TileMap* tilemap = *i;
- const Tile* tile = tilemap->get_tile((int)p.x, (int)p.y);
- int dirdata = tile->getData();
- dirs |= dirdata;
- }
-
- return dirs;
-}
-
-int
-WorldMap::available_directions_at(Vector p)
-{
- return tile_data_at(p) & Tile::WORLDMAP_DIR_MASK;
-}
-
-LevelTile*
-WorldMap::at_level()
-{
- for(LevelTiles::iterator i = levels.begin(); i != levels.end(); ++i) {
- LevelTile* level = *i;
- if (level->pos == tux->get_tile_pos())
- return level;
- }
-
- return NULL;
-}
-
-SpecialTile*
-WorldMap::at_special_tile()
-{
- for(SpecialTiles::iterator i = special_tiles.begin();
- i != special_tiles.end(); ++i) {
- SpecialTile* special_tile = *i;
- if (special_tile->pos == tux->get_tile_pos())
- return special_tile;
- }
-
- return NULL;
-}
-
-SpriteChange*
-WorldMap::at_sprite_change(const Vector& pos)
-{
- for(SpriteChanges::iterator i = sprite_changes.begin();
- i != sprite_changes.end(); ++i) {
- SpriteChange* sprite_change = *i;
- if(sprite_change->pos == pos)
- return sprite_change;
- }
-
- return NULL;
-}
-
-Teleporter*
-WorldMap::at_teleporter(const Vector& pos)
-{
- for(std::vector<Teleporter*>::iterator i = teleporters.begin(); i != teleporters.end(); ++i) {
- Teleporter* teleporter = *i;
- if(teleporter->pos == pos) return teleporter;
- }
-
- return NULL;
-}
-
-void
-WorldMap::draw(DrawingContext& context)
-{
- if (int(get_width()*32) < SCREEN_WIDTH || int(get_height()*32) < SCREEN_HEIGHT)
- context.draw_filled_rect(Vector(0, 0), Vector(SCREEN_WIDTH, SCREEN_HEIGHT),
- Color(0.0f, 0.0f, 0.0f, 1.0f), LAYER_BACKGROUND0);
-
- context.set_ambient_color( ambient_light );
- context.push_transform();
- context.set_translation(camera_offset);
-
- for(GameObjects::iterator i = game_objects.begin();
- i != game_objects.end(); ++i) {
- GameObject* object = *i;
- object->draw(context);
- }
-
-/*
- // FIXME: make this a runtime switch similar to draw_collrects/show_collrects?
- // draw visual indication of possible walk directions
- static int flipme = 0;
- if (flipme++ & 0x04)
- for (int x = 0; x < get_width(); x++) {
- for (int y = 0; y < get_height(); y++) {
- int data = tile_data_at(Vector(x,y));
- int px = x * 32;
- int py = y * 32;
- const int W = 4;
- if (data & Tile::WORLDMAP_NORTH) context.draw_filled_rect(Rect(px + 16-W, py , px + 16+W, py + 16-W), Color(0.2f, 0.2f, 0.2f, 0.7f), LAYER_FOREGROUND1 + 1000);
- if (data & Tile::WORLDMAP_SOUTH) context.draw_filled_rect(Rect(px + 16-W, py + 16+W, px + 16+W, py + 32 ), Color(0.2f, 0.2f, 0.2f, 0.7f), LAYER_FOREGROUND1 + 1000);
- if (data & Tile::WORLDMAP_EAST) context.draw_filled_rect(Rect(px + 16+W, py + 16-W, px + 32 , py + 16+W), Color(0.2f, 0.2f, 0.2f, 0.7f), LAYER_FOREGROUND1 + 1000);
- if (data & Tile::WORLDMAP_WEST) context.draw_filled_rect(Rect(px , py + 16-W, px + 16-W, py + 16+W), Color(0.2f, 0.2f, 0.2f, 0.7f), LAYER_FOREGROUND1 + 1000);
- if (data & Tile::WORLDMAP_DIR_MASK) context.draw_filled_rect(Rect(px + 16-W, py + 16-W, px + 16+W, py + 16+W), Color(0.2f, 0.2f, 0.2f, 0.7f), LAYER_FOREGROUND1 + 1000);
- if (data & Tile::WORLDMAP_STOP) context.draw_filled_rect(Rect(px + 4 , py + 4 , px + 28 , py + 28 ), Color(0.2f, 0.2f, 0.2f, 0.7f), LAYER_FOREGROUND1 + 1000);
- }
- }
-*/
-
- draw_status(context);
- context.pop_transform();
-}
-
-void
-WorldMap::draw_status(DrawingContext& context)
-{
- context.push_transform();
- context.set_translation(Vector(0, 0));
-
- player_status->draw(context);
-
- if (!tux->is_moving()) {
- for(LevelTiles::iterator i = levels.begin(); i != levels.end(); ++i) {
- LevelTile* level = *i;
-
- if (level->pos == tux->get_tile_pos()) {
- if(level->title == "")
- get_level_title(*level);
-
- context.draw_text(white_text, level->title,
- Vector(SCREEN_WIDTH/2,
- SCREEN_HEIGHT - white_text->get_height() - 30),
- ALIGN_CENTER, LAYER_FOREGROUND1);
-
- // if level is solved, draw level picture behind stats
- /*
- if (level->solved) {
- if (const Surface* picture = level->get_picture()) {
- Vector pos = Vector(SCREEN_WIDTH - picture->get_width(), SCREEN_HEIGHT - picture->get_height());
- context.push_transform();
- context.set_alpha(0.5);
- context.draw_surface(picture, pos, LAYER_FOREGROUND1-1);
- context.pop_transform();
- }
- }
- */
-
- level->statistics.draw_worldmap_info(context);
- break;
- }
- }
-
- for(SpecialTiles::iterator i = special_tiles.begin();
- i != special_tiles.end(); ++i) {
- SpecialTile* special_tile = *i;
-
- if (special_tile->pos == tux->get_tile_pos()) {
- /* Display an in-map message in the map, if any as been selected */
- if(!special_tile->map_message.empty() && !special_tile->passive_message)
- context.draw_text(gold_text, special_tile->map_message,
- Vector(SCREEN_WIDTH/2,
- SCREEN_HEIGHT - white_text->get_height() - 60),
- ALIGN_CENTER, LAYER_FOREGROUND1);
- break;
- }
- }
-
- // display teleporter messages
- Teleporter* teleporter = at_teleporter(tux->get_tile_pos());
- if (teleporter && (teleporter->message != "")) {
- Vector pos = Vector(SCREEN_WIDTH/2, SCREEN_HEIGHT - white_text->get_height() - 30);
- context.draw_text(white_text, teleporter->message, pos, ALIGN_CENTER, LAYER_FOREGROUND1);
- }
-
- }
-
- /* Display a passive message in the map, if needed */
- if(passive_message_timer.started())
- context.draw_text(gold_text, passive_message,
- Vector(SCREEN_WIDTH/2, SCREEN_HEIGHT - white_text->get_height() - 60),
- ALIGN_CENTER, LAYER_FOREGROUND1);
-
- context.pop_transform();
-}
-
-void
-WorldMap::setup()
-{
- sound_manager->play_music(music);
- Menu::set_current(NULL);
-
- current_ = this;
- load_state();
-
- // if force_spawnpoint was set, move Tux there, then clear force_spawnpoint
- if (force_spawnpoint != "") {
- move_to_spawnpoint(force_spawnpoint);
- force_spawnpoint = "";
- }
-
- tux->setup();
-
- // register worldmap_table as worldmap in scripting
- using namespace Scripting;
-
- sq_pushroottable(global_vm);
- sq_pushstring(global_vm, "worldmap", -1);
- sq_pushobject(global_vm, worldmap_table);
- if(SQ_FAILED(sq_createslot(global_vm, -3)))
- throw SquirrelError(global_vm, "Couldn't set worldmap in roottable");
- sq_pop(global_vm, 1);
-
- if(init_script != "") {
- std::istringstream in(init_script);
- run_script(in, "WorldMap::init");
- }
-}
-
-void
-WorldMap::leave()
-{
- using namespace Scripting;
-
- // save state of world and player
- save_state();
-
- // remove worldmap_table from roottable
- sq_pushroottable(global_vm);
- sq_pushstring(global_vm, "worldmap", -1);
- if(SQ_FAILED(sq_deleteslot(global_vm, -2, SQFalse)))
- throw SquirrelError(global_vm, "Couldn't unset worldmap in roottable");
- sq_pop(global_vm, 1);
-}
-
-void
-WorldMap::save_state()
-{
- using namespace Scripting;
-
- HSQUIRRELVM vm = global_vm;
- int oldtop = sq_gettop(vm);
-
- try {
- // get state table
- sq_pushroottable(vm);
- sq_pushstring(vm, "state", -1);
- if(SQ_FAILED(sq_get(vm, -2)))
- throw Scripting::SquirrelError(vm, "Couldn't get state table");
-
- // get or create worlds table
- sq_pushstring(vm, "worlds", -1);
- if(SQ_FAILED(sq_get(vm, -2))) {
- sq_pushstring(vm, "worlds", -1);
- sq_newtable(vm);
- if(SQ_FAILED(sq_createslot(vm, -3)))
- throw Scripting::SquirrelError(vm, "Couldn't create state.worlds");
-
- sq_pushstring(vm, "worlds", -1);
- if(SQ_FAILED(sq_get(vm, -2)))
- throw Scripting::SquirrelError(vm, "Couldn't create.get state.worlds");
- }
-
- sq_pushstring(vm, map_filename.c_str(), map_filename.length());
- if(SQ_FAILED(sq_deleteslot(vm, -2, SQFalse)))
- sq_pop(vm, 1);
-
- // construct new table for this worldmap
- sq_pushstring(vm, map_filename.c_str(), map_filename.length());
- sq_newtable(vm);
-
- // store tux
- sq_pushstring(vm, "tux", -1);
- sq_newtable(vm);
-
- store_float(vm, "x", tux->get_tile_pos().x);
- store_float(vm, "y", tux->get_tile_pos().y);
- store_string(vm, "back", direction_to_string(tux->back_direction));
-
- sq_createslot(vm, -3);
-
- // levels...
- sq_pushstring(vm, "levels", -1);
- sq_newtable(vm);
-
- for(LevelTiles::iterator i = levels.begin(); i != levels.end(); ++i) {
- LevelTile* level = *i;
-
- sq_pushstring(vm, level->get_name().c_str(), -1);
- sq_newtable(vm);
-
- store_bool(vm, "solved", level->solved);
- level->statistics.serialize_to_squirrel(vm);
-
- sq_createslot(vm, -3);
- }
-
- sq_createslot(vm, -3);
-
- // overall statistics...
- total_stats.serialize_to_squirrel(vm);
-
- // push world into worlds table
- sq_createslot(vm, -3);
- } catch(std::exception& ) {
- sq_settop(vm, oldtop);
- }
-
- sq_settop(vm, oldtop);
-
- if(World::current() != NULL)
- World::current()->save_state();
-}
-
-void
-WorldMap::load_state()
-{
- using namespace Scripting;
-
- HSQUIRRELVM vm = global_vm;
- int oldtop = sq_gettop(vm);
-
- try {
- // get state table
- sq_pushroottable(vm);
- sq_pushstring(vm, "state", -1);
- if(SQ_FAILED(sq_get(vm, -2)))
- throw Scripting::SquirrelError(vm, "Couldn't get state table");
-
- // get worlds table
- sq_pushstring(vm, "worlds", -1);
- if(SQ_FAILED(sq_get(vm, -2)))
- throw Scripting::SquirrelError(vm, "Couldn't get state.worlds");
-
- // get table for our world
- sq_pushstring(vm, map_filename.c_str(), map_filename.length());
- if(SQ_FAILED(sq_get(vm, -2)))
- throw Scripting::SquirrelError(vm, "Couldn't get state.worlds.mapfilename");
-
- // load tux
- sq_pushstring(vm, "tux", -1);
- if(SQ_FAILED(sq_get(vm, -2)))
- throw Scripting::SquirrelError(vm, "Couldn't get tux");
-
- Vector p;
- p.x = read_float(vm, "x");
- p.y = read_float(vm, "y");
- std::string back_str = read_string(vm, "back");
- tux->back_direction = string_to_direction(back_str);
- tux->set_tile_pos(p);
-
- sq_pop(vm, 1);
-
- // load levels
- sq_pushstring(vm, "levels", -1);
- if(SQ_FAILED(sq_get(vm, -2)))
- throw Scripting::SquirrelError(vm, "Couldn't get levels");
-
- for(LevelTiles::iterator i = levels.begin(); i != levels.end(); ++i) {
- LevelTile* level = *i;
- sq_pushstring(vm, level->get_name().c_str(), -1);
- if(SQ_SUCCEEDED(sq_get(vm, -2))) {
- level->solved = read_bool(vm, "solved");
- level->sprite->set_action(level->solved ? "solved" : "default");
- level->statistics.unserialize_from_squirrel(vm);
- sq_pop(vm, 1);
- }
- }
-
- // leave state table
- sq_pop(vm, 1);
-
- // load overall statistics
- total_stats.unserialize_from_squirrel(vm);
-
- } catch(std::exception& e) {
- log_debug << "Not loading worldmap state: " << e.what() << std::endl;
- }
- sq_settop(vm, oldtop);
-
- in_level = false;
-}
-
-size_t
-WorldMap::level_count()
-{
- return levels.size();
-}
-
-size_t
-WorldMap::solved_level_count()
-{
- size_t count = 0;
- for(LevelTiles::iterator i = levels.begin(); i != levels.end(); ++i) {
- LevelTile* level = *i;
-
- if(level->solved)
- count++;
- }
-
- return count;
-}
-
-HSQUIRRELVM
-WorldMap::run_script(std::istream& in, const std::string& sourcename)
-{
- using namespace Scripting;
-
- // garbage collect thread list
- for(ScriptList::iterator i = scripts.begin();
- i != scripts.end(); ) {
- HSQOBJECT& object = *i;
- HSQUIRRELVM vm = object_to_vm(object);
-
- if(sq_getvmstate(vm) != SQ_VMSTATE_SUSPENDED) {
- sq_release(global_vm, &object);
- i = scripts.erase(i);
- continue;
- }
-
- ++i;
- }
-
- HSQOBJECT object = create_thread(global_vm);
- scripts.push_back(object);
-
- HSQUIRRELVM vm = object_to_vm(object);
-
- // set worldmap_table as roottable for the thread
- sq_pushobject(vm, worldmap_table);
- sq_setroottable(vm);
-
- compile_and_run(vm, in, sourcename);
-
- return vm;
-}
-
-float
-WorldMap::get_width() const
-{
- float width = 0;
- for(std::list<TileMap*>::const_iterator i = solid_tilemaps.begin(); i != solid_tilemaps.end(); i++) {
- TileMap* solids = *i;
- if (solids->get_width() > width) width = solids->get_width();
- }
- return width;
-}
-
-float
-WorldMap::get_height() const
-{
- float height = 0;
- for(std::list<TileMap*>::const_iterator i = solid_tilemaps.begin(); i != solid_tilemaps.end(); i++) {
- TileMap* solids = *i;
- if (solids->get_height() > height) height = solids->get_height();
- }
- return height;
-}
-
-} // namespace WorldMapNS
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2004 Ingo Ruhnke <grumbel@gmx.de>
-// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
-//
-// 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.
-#ifndef SUPERTUX_WORLDMAP_H
-#define SUPERTUX_WORLDMAP_H
-
-#include <vector>
-#include <string>
-
-#include "math/vector.hpp"
-#include "lisp/lisp.hpp"
-#include "control/controller.hpp"
-#include "statistics.hpp"
-#include "timer.hpp"
-#include "screen.hpp"
-#include "tile_manager.hpp"
-#include "game_object.hpp"
-#include "console.hpp"
-#include "../level.hpp"
-#include "worldmap/special_tile.hpp"
-#include "worldmap/sprite_change.hpp"
-#include "worldmap/teleporter.hpp"
-#include "worldmap/spawn_point.hpp"
-#include "worldmap/direction.hpp"
-
-class Sprite;
-class Menu;
-class GameObject;
-class TileMap;
-
-namespace WorldMapNS {
-
-class Tux;
-class LevelTile;
-class SpecialTile;
-class SpriteChange;
-
-// For one way tiles
-enum {
- BOTH_WAYS,
- NORTH_SOUTH_WAY,
- SOUTH_NORTH_WAY,
- EAST_WEST_WAY,
- WEST_EAST_WAY
-};
-
-std::string direction_to_string(Direction d);
-Direction string_to_direction(const std::string& d);
-Direction reverse_dir(Direction d);
-
-/**
- * Screen that displays a worldmap
- */
-class WorldMap : public Screen
-{
-private:
- Tux* tux;
-
- static WorldMap* current_;
-
- std::auto_ptr<Menu> worldmap_menu;
-
- Vector camera_offset;
-
- std::string name;
- std::string music;
- std::string init_script;
-
- typedef std::vector<GameObject*> GameObjects;
- GameObjects game_objects;
- std::list<TileMap*> solid_tilemaps;
-
- std::auto_ptr<TileManager> tile_manager;
-
-public:
- /** Variables to deal with the passive map messages */
- Timer passive_message_timer;
- std::string passive_message;
-
-private:
- std::string map_filename;
- std::string levels_path;
-
- typedef std::vector<SpecialTile*> SpecialTiles;
- SpecialTiles special_tiles;
- typedef std::vector<LevelTile*> LevelTiles;
- LevelTiles levels;
- typedef std::vector<SpriteChange*> SpriteChanges;
- SpriteChanges sprite_changes;
- typedef std::vector<SpawnPoint*> SpawnPoints;
- SpawnPoints spawn_points;
- std::vector<Teleporter*> teleporters;
-
- Statistics total_stats;
-
- HSQOBJECT worldmap_table;
- typedef std::vector<HSQOBJECT> ScriptList;
- ScriptList scripts;
-
- Color ambient_light;
- std::string force_spawnpoint; /**< if set, spawnpoint will be forced to this value */
-
- bool in_level;
-
-public:
- WorldMap(const std::string& filename, const std::string& force_spawnpoint = "");
- ~WorldMap();
-
- void add_object(GameObject* object);
-
- void try_expose(GameObject* object);
- void try_unexpose(GameObject* object);
-
- static WorldMap* current()
- { return current_; }
-
- virtual void setup();
- virtual void leave();
-
- /** Update worldmap state */
- virtual void update(float delta);
- /** Draw worldmap */
- virtual void draw(DrawingContext& context);
-
- Vector get_next_tile(Vector pos, Direction direction);
-
- /**
- * gets a bitfield of Tile::WORLDMAP_NORTH | Tile::WORLDMAP_WEST | ... values,
- * which indicates the directions Tux can move to when at the given position.
- */
- int available_directions_at(Vector pos);
-
- /**
- * returns a bitfield representing the union of all Tile::WORLDMAP_XXX values
- * of all solid tiles at the given position
- */
- int tile_data_at(Vector pos);
-
- size_t level_count();
- size_t solved_level_count();
-
- /**
- * gets called from the GameSession when a level has been successfully
- * finished
- */
- void finished_level(Level* level);
-
- LevelTile* at_level();
- SpecialTile* at_special_tile();
- SpriteChange* at_sprite_change(const Vector& pos);
- Teleporter* at_teleporter(const Vector& pos);
-
- /** Check if it is possible to walk from \a pos into \a direction,
- if possible, write the new position to \a new_pos */
- bool path_ok(Direction direction, const Vector& pos, Vector* new_pos);
-
- /**
- * Save worldmap state to squirrel state table
- */
- void save_state();
-
- /**
- * Load worldmap state from squirrel state table
- */
- void load_state();
-
- const std::string& get_title() const
- { return name; }
-
- /**
- * runs a script in the context of the worldmap (and keeps a reference to
- * the script (so the script gets destroyed when the worldmap is destroyed)
- */
- HSQUIRRELVM run_script(std::istream& in, const std::string& sourcename);
-
- /**
- * switch to another worldmap.
- * filename is relative to data root path
- */
- void change(const std::string& filename, const std::string& force_spawnpoint="");
-
- /**
- * moves Tux to the given spawnpoint
- */
- void move_to_spawnpoint(const std::string& spawnpoint);
-
- /**
- * returns the width (in tiles) of a worldmap
- */
- float get_width() const;
-
- /**
- * returns the height (in tiles) of a worldmap
- */
- float get_height() const;
-
-private:
- void get_level_title(LevelTile& level);
- void draw_status(DrawingContext& context);
- void calculate_total_stats();
-
- void load(const std::string& filename);
- void on_escape_press();
-};
-
-} // namespace WorldMapNS
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux (Statistics module)
-// Copyright (C) 2004 Ricardo Cruz <rick2@aeiou.pt>
-// Copyright (C) 2006 Ondrej Hosek <ondra.hosek@gmail.com>
-// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
-//
-// 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.
-#include <config.h>
-
-#include <assert.h>
-#include <math.h>
-#include <sstream>
-#include <limits>
-#include "video/drawing_context.hpp"
-#include "gettext.hpp"
-#include "lisp/writer.hpp"
-#include "lisp/lisp.hpp"
-#include "resources.hpp"
-#include "main.hpp"
-#include "statistics.hpp"
-#include "log.hpp"
-#include "scripting/squirrel_util.hpp"
-
-namespace {
- const int nv_coins = std::numeric_limits<int>::min();
- const int nv_badguys = std::numeric_limits<int>::min();
- const float nv_time = std::numeric_limits<float>::max();
- const int nv_secrets = std::numeric_limits<int>::min();
-}
-
-float WMAP_INFO_LEFT_X;
-float WMAP_INFO_RIGHT_X;
-float WMAP_INFO_TOP_Y1;
-float WMAP_INFO_TOP_Y2;
-
-Statistics::Statistics() : coins(nv_coins), total_coins(nv_coins), badguys(nv_badguys), total_badguys(nv_badguys), time(nv_time), secrets(nv_secrets), total_secrets(nv_secrets), valid(true), display_stat(0)
-{
- WMAP_INFO_LEFT_X = (SCREEN_WIDTH/2 + 80) + 32;
- WMAP_INFO_RIGHT_X = SCREEN_WIDTH/2 + 368;
- WMAP_INFO_TOP_Y1 = SCREEN_HEIGHT/2 + 172 - 16;
- WMAP_INFO_TOP_Y2 = SCREEN_HEIGHT/2 + 172;
-}
-
-Statistics::~Statistics()
-{
-}
-
-/*
-void
-Statistics::parse(const lisp::Lisp& reader)
-{
- reader.get("coins-collected", coins);
- reader.get("coins-collected-total", total_coins);
- reader.get("badguys-killed", badguys);
- reader.get("badguys-killed-total", total_badguys);
- reader.get("time-needed", time);
- reader.get("secrets-found", secrets);
- reader.get("secrets-found-total", total_secrets);
-}
-
-void
-Statistics::write(lisp::Writer& writer)
-{
- writer.write_int("coins-collected", coins);
- writer.write_int("coins-collected-total", total_coins);
- writer.write_int("badguys-killed", badguys);
- writer.write_int("badguys-killed-total", total_badguys);
- writer.write_float("time-needed", time);
- writer.write_int("secrets-found", secrets);
- writer.write_int("secrets-found-total", total_secrets);
-}
-*/
-
-void
-Statistics::serialize_to_squirrel(HSQUIRRELVM vm)
-{
- // TODO: there's some bug in the unserialization routines that breaks stuff when an empty statistics table is written, so -- as a workaround -- let's make sure we will actually write something first
- if (!((coins != nv_coins) || (total_coins != nv_coins) || (badguys != nv_badguys) || (total_badguys != nv_badguys) || (time != nv_time) || (secrets != nv_secrets) || (total_secrets != nv_secrets))) return;
-
- sq_pushstring(vm, "statistics", -1);
- sq_newtable(vm);
- if (coins != nv_coins) Scripting::store_int(vm, "coins-collected", coins);
- if (total_coins != nv_coins) Scripting::store_int(vm, "coins-collected-total", total_coins);
- if (badguys != nv_badguys) Scripting::store_int(vm, "badguys-killed", badguys);
- if (total_badguys != nv_badguys) Scripting::store_int(vm, "badguys-killed-total", total_badguys);
- if (time != nv_time) Scripting::store_float(vm, "time-needed", time);
- if (secrets != nv_secrets) Scripting::store_int(vm, "secrets-found", secrets);
- if (total_secrets != nv_secrets) Scripting::store_int(vm, "secrets-found-total", total_secrets);
- sq_createslot(vm, -3);
-}
-
-void
-Statistics::unserialize_from_squirrel(HSQUIRRELVM vm)
-{
- sq_pushstring(vm, "statistics", -1);
- if(SQ_FAILED(sq_get(vm, -2))) {
- return;
- }
- Scripting::get_int(vm, "coins-collected", coins);
- Scripting::get_int(vm, "coins-collected-total", total_coins);
- Scripting::get_int(vm, "badguys-killed", badguys);
- Scripting::get_int(vm, "badguys-killed-total", total_badguys);
- Scripting::get_float(vm, "time-needed", time);
- Scripting::get_int(vm, "secrets-found", secrets);
- Scripting::get_int(vm, "secrets-found-total", total_secrets);
- sq_pop(vm, 1);
-}
-
-//define TOTAL_DISPLAY_TIME 3400
-//define FADING_TIME 600
-
-#define TOTAL_DISPLAY_TIME 5
-#define FADING_TIME 1
-
-void
-Statistics::draw_worldmap_info(DrawingContext& context)
-{
- // skip draw if level was never played
- if (coins == nv_coins) return;
-
- // skip draw if stats were declared invalid
- if (!valid) return;
-
- context.draw_text(white_small_text, std::string("- ") + _("Best Level Statistics") + " -", Vector((WMAP_INFO_LEFT_X + WMAP_INFO_RIGHT_X) / 2, WMAP_INFO_TOP_Y1), ALIGN_CENTER, LAYER_GUI);
-
- float alpha;
- if(timer.get_timegone() < FADING_TIME)
- alpha = (timer.get_timegone() * 1.0f / FADING_TIME);
- else if(timer.get_timeleft() < FADING_TIME)
- alpha = (timer.get_timeleft() * 1.0f / FADING_TIME);
- else
- alpha = 1.0f;
-
- context.push_transform();
- context.set_alpha(alpha);
-
- char caption_buf[128];
- char stat_buf[128];
- switch (display_stat)
- {
- case 0:
- snprintf(caption_buf, sizeof(caption_buf), _("Max coins collected:"));
- snprintf(stat_buf, sizeof(stat_buf), "%d/%d", coins, total_coins);
- break;
- case 1:
- snprintf(caption_buf, sizeof(caption_buf), _("Max fragging:"));
- snprintf(stat_buf, sizeof(stat_buf), "%d/%d", badguys, total_badguys);
- break;
- case 2:
- snprintf(caption_buf, sizeof(caption_buf), _("Min time needed:"));
- {
- int csecs = (int)(time * 100);
- int mins = (int)(csecs / 6000);
- int secs = (csecs % 6000) / 100;
- snprintf(stat_buf, sizeof(stat_buf), "%02d:%02d", mins,secs);
- }
- break;
- case 3:
- snprintf(caption_buf, sizeof(caption_buf), _("Max secrets found:"));
- snprintf(stat_buf, sizeof(stat_buf), "%d/%d", secrets, total_secrets);
- break;
- default:
- log_debug << "Invalid stat requested to be drawn" << std::endl;
- break;
- }
-
- if (!timer.started())
- {
- timer.start(TOTAL_DISPLAY_TIME);
- display_stat++;
- if (display_stat > 3) display_stat = 0;
- }
-
- context.draw_text(white_small_text, caption_buf, Vector(WMAP_INFO_LEFT_X, WMAP_INFO_TOP_Y2), ALIGN_LEFT, LAYER_GUI);
- context.draw_text(white_small_text, stat_buf, Vector(WMAP_INFO_RIGHT_X, WMAP_INFO_TOP_Y2), ALIGN_RIGHT, LAYER_GUI);
- context.pop_transform();
-}
-
-void
-Statistics::draw_message_info(DrawingContext& context, std::string title)
-{
- // skip draw if level was never played
- // TODO: do we need this?
- if (coins == nv_coins) return;
-
- // skip draw if stats were declared invalid
- if (!valid) return;
-
- const float width = white_small_text->get_text_width("Max coins collected: 1111 / 1111");
- const float left = (SCREEN_WIDTH - width) / 2;
- const float right = (SCREEN_WIDTH + width) / 2;
-
- context.draw_text(gold_text, title, Vector(SCREEN_WIDTH/2, 410), ALIGN_CENTER, LAYER_GUI);
-
- char stat_buf[128];
- int py = 450 + 18;
-
- snprintf(stat_buf, sizeof(stat_buf), "%d/%d", coins, total_coins);
- context.draw_text(white_small_text, _("Max coins collected:"), Vector(left, py), ALIGN_LEFT, LAYER_GUI);
- context.draw_text(white_small_text, "%d / %d", Vector(right, py), ALIGN_RIGHT, LAYER_GUI);
- py+=18;
-
- snprintf(stat_buf, sizeof(stat_buf), "%d/%d", badguys, total_badguys);
- context.draw_text(white_small_text, _("Max fragging:"), Vector(left, py), ALIGN_LEFT, LAYER_GUI);
- context.draw_text(white_small_text, "%d / %d", Vector(right, py), ALIGN_RIGHT, LAYER_GUI);
- py+=18;
-
- int csecs = (int)(time * 100);
- int mins = (int)(csecs / 6000);
- int secs = (csecs % 6000) / 100;
- snprintf(stat_buf, sizeof(stat_buf), "%02d:%02d", mins,secs);
- context.draw_text(white_small_text, _("Min time needed:"), Vector(left, py), ALIGN_LEFT, LAYER_GUI);
- context.draw_text(white_small_text, "%02d:%02d", Vector(right, py), ALIGN_RIGHT, LAYER_GUI);
- py+=18;
-
- snprintf(stat_buf, sizeof(stat_buf), "%d/%d", secrets, total_secrets);
- context.draw_text(white_small_text, _("Max secrets found:"), Vector(left, py), ALIGN_LEFT, LAYER_GUI);
- context.draw_text(white_small_text, "%d / %d", Vector(right, py), ALIGN_RIGHT, LAYER_GUI);
- py+=18;
-}
-
-void
-Statistics::draw_endseq_panel(DrawingContext& context, Statistics* best_stats, Surface* backdrop)
-{
- // skip draw if level was never played
- // TODO: do we need this?
- if (coins == nv_coins) return;
-
- // skip draw if stats were declared invalid
- if (!valid) return;
-
- // abort if we have no backdrop
- if (!backdrop) return;
-
- int box_w = 220+110+110;
- int box_h = 30+20+20+20;
- int box_x = (int)((SCREEN_WIDTH - box_w) / 2);
- int box_y = (int)(SCREEN_HEIGHT / 2) - box_h;
-
- int bd_w = (int)backdrop->get_width();
- int bd_h = (int)backdrop->get_height();
- int bd_x = (int)((SCREEN_WIDTH - bd_w) / 2);
- int bd_y = box_y + (box_h / 2) - (bd_h / 2);
-
- int col1_x = box_x;
- int col2_x = col1_x+200;
- int col3_x = col2_x+130;
-
- int row1_y = box_y;
- int row2_y = row1_y+30;
- int row3_y = row2_y+20;
- int row4_y = row3_y+20;
-
- context.push_transform();
- context.set_alpha(0.5);
- context.draw_surface(backdrop, Vector(bd_x, bd_y), LAYER_GUI);
- context.pop_transform();
-
- char buf[129];
- context.draw_text(white_text, _("You"), Vector(col2_x, row1_y), ALIGN_LEFT, LAYER_GUI);
- context.draw_text(white_text, _("Best"), Vector(col3_x, row1_y), ALIGN_LEFT, LAYER_GUI);
-
- context.draw_text(white_text, _("Coins"), Vector(col2_x-16, row2_y), ALIGN_RIGHT, LAYER_GUI);
- snprintf(buf, sizeof(buf), "%d/%d", std::min(coins, 999), std::min(total_coins, 999));
- context.draw_text(gold_text, buf, Vector(col2_x, row2_y), ALIGN_LEFT, LAYER_GUI);
- if (best_stats && (best_stats->coins > coins)) {
- snprintf(buf, sizeof(buf), "%d/%d", std::min(best_stats->coins, 999), std::min(best_stats->total_coins, 999));
- }
- context.draw_text(gold_text, buf, Vector(col3_x, row2_y), ALIGN_LEFT, LAYER_GUI);
-
- context.draw_text(white_text, _("Secrets"), Vector(col2_x-16, row4_y), ALIGN_RIGHT, LAYER_GUI);
- snprintf(buf, sizeof(buf), "%d/%d", secrets, total_secrets);
- context.draw_text(gold_text, buf, Vector(col2_x, row4_y), ALIGN_LEFT, LAYER_GUI);
- if (best_stats && (best_stats->secrets > secrets)) {
- snprintf(buf, sizeof(buf), "%d/%d", best_stats->secrets, best_stats->total_secrets);
- }
- context.draw_text(gold_text, buf, Vector(col3_x, row4_y), ALIGN_LEFT, LAYER_GUI);
-
- context.draw_text(white_text, _("Time"), Vector(col2_x-16, row3_y), ALIGN_RIGHT, LAYER_GUI);
- int csecs = (int)(time * 100);
- int mins = (int)(csecs / 6000);
- int secs = (csecs % 6000) / 100;
- snprintf(buf, sizeof(buf), "%02d:%02d", mins,secs);
- context.draw_text(gold_text, buf, Vector(col2_x, row3_y), ALIGN_LEFT, LAYER_GUI);
- if (best_stats && (best_stats->time < time)) {
- int csecs = (int)(best_stats->time * 100);
- int mins = (int)(csecs / 6000);
- int secs = (csecs % 6000) / 100;
- snprintf(buf, sizeof(buf), "%02d:%02d", mins,secs);
- }
- context.draw_text(gold_text, buf, Vector(col3_x, row3_y), ALIGN_LEFT, LAYER_GUI);
-}
-
-void
-Statistics::zero()
-{
- reset();
- total_coins = 0;
- total_badguys = 0;
- total_secrets = 0;
-}
-
-void
-Statistics::reset()
-{
- coins = 0;
- badguys = 0;
- time = 0;
- secrets = 0;
-}
-
-void
-Statistics::merge(Statistics& s2)
-{
- if (!s2.valid) return;
- coins = std::max(coins, s2.coins);
- total_coins = s2.total_coins;
- badguys = std::max(badguys, s2.badguys);
- total_badguys = s2.total_badguys;
- time = std::min(time, s2.time);
- secrets = std::max(secrets, s2.secrets);
- total_secrets = s2.total_secrets;
-}
-
-void
-Statistics::operator+=(const Statistics& s2)
-{
- if (!s2.valid) return;
- if (s2.coins != nv_coins) coins += s2.coins;
- if (s2.total_coins != nv_coins) total_coins += s2.total_coins;
- if (s2.badguys != nv_badguys) badguys += s2.badguys;
- if (s2.total_badguys != nv_badguys) total_badguys += s2.total_badguys;
- if (s2.time != nv_time) time += s2.time;
- if (s2.secrets != nv_secrets) secrets += s2.secrets;
- if (s2.total_secrets != nv_secrets) total_secrets += s2.total_secrets;
-}
-
-void
-Statistics::declare_invalid()
-{
- valid = false;
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux (Statistics module)
-// Copyright (C) 2004 Ricardo Cruz <rick2@aeiou.pt>
-// Copyright (C) 2006 Ondrej Hosek <ondra.hosek@gmail.com>
-// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
-//
-// 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.
-
-#ifndef SUPERTUX_STATISTICS_H
-#define SUPERTUX_STATISTICS_H
-
-#include <squirrel.h>
-#include "timer.hpp"
-
-namespace lisp { class Writer; }
-namespace lisp { class Lisp; }
-class Surface;
-class DrawingContext;
-
-/** This class is a layer between level and worldmap to keep
- * track of stuff like scores, and minor, but funny things, like
- * number of jumps and stuff */
-class Statistics
-{
-public:
- int coins; /**< coins collected */
- int total_coins; /**< coins in level */
- int badguys; /**< badguys actively killed */
- int total_badguys; /**< (vincible) badguys in level */
- float time; /**< seconds needed */
- int secrets; /**< secret areas found */
- int total_secrets; /**< secret areas in level */
-
-public:
- Statistics(); /**< Creates new statistics, call reset() before counting */
- ~Statistics();
-
- /// read statistics from lisp file
- //void parse(const lisp::Lisp& lisp);
- /// write statistics to lisp file
- //void write(lisp::Writer& writer);
-
- /**
- * serialize statistics object as squirrel table "statistics"
- */
- void serialize_to_squirrel(HSQUIRRELVM vm);
-
- /**
- * unserialize statistics object from squirrel table "statistics"
- */
- void unserialize_from_squirrel(HSQUIRRELVM vm);
-
- void draw_worldmap_info(DrawingContext& context); /**< draw worldmap stat HUD */
- void draw_message_info(DrawingContext& context, std::string title); /**< draw stats at level start */
- void draw_endseq_panel(DrawingContext& context, Statistics* best_stats, Surface* backdrop); /**< draw panel shown during level's end sequence */
-
- void zero(); /**< Set stats to zero */
- void reset(); /**< Set stats (but not totals) to zero */
- void merge(Statistics& stats); /**< Given another Statistics object finds the best of each one */
- void operator+=(const Statistics& o); /**< Add two Statistics objects */
-
- void declare_invalid(); /**< marks statistics as invalid for their entire lifetime (e.g. after cheating). Invalid statistics will not be merged or drawn. */
-
-private:
- bool valid; /**< stores whether this statistics can be trusted */
- Timer timer; /**< for draw_worldmap_info: time until switching to next stat */
- int display_stat; /**< for draw_worldmap_info: which stat is currently displayed */
-};
-
-#endif /*SUPERTUX_STATISTICS_H*/
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#include <config.h>
-
-#include "textscroller.hpp"
-
-#include <stdexcept>
-#include "log.hpp"
-#include "mainloop.hpp"
-#include "resources.hpp"
-#include "video/font.hpp"
-#include "video/drawing_context.hpp"
-#include "video/surface.hpp"
-#include "gui/menu.hpp"
-#include "lisp/parser.hpp"
-#include "lisp/lisp.hpp"
-#include "audio/sound_manager.hpp"
-#include "main.hpp"
-#include "fadeout.hpp"
-#include "control/joystickkeyboardcontroller.hpp"
-
-static const float DEFAULT_SPEED = 20;
-static const float LEFT_BORDER = 50;
-static const float SCROLL = 60;
-static const float ITEMS_SPACE = 4;
-
-TextScroller::TextScroller(const std::string& filename)
-{
- defaultspeed = DEFAULT_SPEED;
- speed = defaultspeed;
-
- std::string text;
- std::string background_file;
-
- lisp::Parser parser;
- try {
- const lisp::Lisp* root = parser.parse(filename);
-
- const lisp::Lisp* text_lisp = root->get_lisp("supertux-text");
- if(!text_lisp)
- throw std::runtime_error("File isn't a supertux-text file");
-
- if(!text_lisp->get("text", text))
- throw std::runtime_error("file doesn't contain a text field");
- if(!text_lisp->get("background", background_file))
- throw std::runtime_error("file doesn't contain a background file");
- text_lisp->get("speed", defaultspeed);
- text_lisp->get("music", music);
- } catch(std::exception& e) {
- std::ostringstream msg;
- msg << "Couldn't load file '" << filename << "': " << e.what() << std::endl;
- throw std::runtime_error(msg.str());
- }
-
- // Split text string lines into a vector
- lines = InfoBoxLine::split(text, SCREEN_WIDTH - 2*LEFT_BORDER);
-
- // load background image
- background.reset(new Surface("images/background/" + background_file));
-
- scroll = 0;
- fading = false;
-}
-
-TextScroller::~TextScroller()
-{
- for(std::vector<InfoBoxLine*>::iterator i = lines.begin(); i != lines.end(); i++) delete *i;
-}
-
-void
-TextScroller::setup()
-{
- sound_manager->play_music(music);
- Menu::set_current(NULL);
-}
-
-void
-TextScroller::update(float elapsed_time)
-{
- if(main_controller->hold(Controller::UP)) {
- speed = -defaultspeed*5;
- } else if(main_controller->hold(Controller::DOWN)) {
- speed = defaultspeed*5;
- } else {
- speed = defaultspeed;
- }
- if(main_controller->pressed(Controller::JUMP)
- || main_controller->pressed(Controller::ACTION)
- || main_controller->pressed(Controller::MENU_SELECT))
- scroll += SCROLL;
- if(main_controller->pressed(Controller::PAUSE_MENU)) {
- main_loop->exit_screen(new FadeOut(0.5));
- }
-
- scroll += speed * elapsed_time;
-
- if(scroll < 0)
- scroll = 0;
-}
-
-void
-TextScroller::draw(DrawingContext& context)
-{
- context.draw_filled_rect(Vector(0, 0), Vector(SCREEN_WIDTH, SCREEN_HEIGHT),
- Color(0.6f, 0.7f, 0.8f, 0.5f), 0);
- context.draw_surface(background.get(), Vector(SCREEN_WIDTH/2 - background->get_width()/2 , SCREEN_HEIGHT/2 - background->get_height()/2), 0);
-
- float y = SCREEN_HEIGHT - scroll;
- for(size_t i = 0; i < lines.size(); i++) {
- lines[i]->draw(context, Rect(LEFT_BORDER, y, SCREEN_WIDTH - 2*LEFT_BORDER, y), LAYER_GUI);
- y += lines[i]->get_height();
- }
-
- if(y < 0 && !fading ) {
- fading = true;
- main_loop->exit_screen(new FadeOut(0.5));
- }
-}
-
-InfoBox::InfoBox(const std::string& text)
- : firstline(0)
-{
- // Split text string lines into a vector
- lines = InfoBoxLine::split(text, 400);
-
- try
- {
- // get the arrow sprites
- arrow_scrollup = new Surface("images/engine/menu/scroll-up.png");
- arrow_scrolldown = new Surface("images/engine/menu/scroll-down.png");
- }
- catch (std::exception& e)
- {
- log_warning << "Could not load scrolling images: " << e.what() << std::endl;
- arrow_scrollup = 0;
- arrow_scrolldown = 0;
- }
-}
-
-InfoBox::~InfoBox()
-{
- for(std::vector<InfoBoxLine*>::iterator i = lines.begin();
- i != lines.end(); i++)
- delete *i;
- delete arrow_scrollup;
- delete arrow_scrolldown;
-}
-
-void
-InfoBox::draw(DrawingContext& context)
-{
- float x1 = SCREEN_WIDTH/2-200;
- float y1 = SCREEN_HEIGHT/2-200;
- float width = 400;
- float height = 200;
-
- context.draw_filled_rect(Vector(x1, y1), Vector(width, height),
- Color(0.6f, 0.7f, 0.8f, 0.5f), LAYER_GUI-1);
-
- float y = y1;
- bool linesLeft = false;
- for(size_t i = firstline; i < lines.size(); ++i) {
- if(y >= y1 + height) {
- linesLeft = true;
- break;
- }
-
- lines[i]->draw(context, Rect(x1, y, x1+width, y), LAYER_GUI);
- y += lines[i]->get_height();
- }
-
- {
- // draw the scrolling arrows
- if (arrow_scrollup && firstline > 0)
- context.draw_surface(arrow_scrollup,
- Vector( x1 + width - arrow_scrollup->get_width(), // top-right corner of box
- y1), LAYER_GUI);
-
- if (arrow_scrolldown && linesLeft && firstline < lines.size()-1)
- context.draw_surface(arrow_scrolldown,
- Vector( x1 + width - arrow_scrolldown->get_width(), // bottom-light corner of box
- y1 + height - arrow_scrolldown->get_height()),
- LAYER_GUI);
- }
-}
-
-void
-InfoBox::scrollup()
-{
- if(firstline > 0)
- firstline--;
-}
-
-void
-InfoBox::scrolldown()
-{
- if(firstline < lines.size()-1)
- firstline++;
-}
-
-void
-InfoBox::pageup()
-{
-}
-
-void
-InfoBox::pagedown()
-{
-}
-
-namespace {
-Font* get_font_by_format_char(char format_char) {
- switch(format_char)
- {
- case ' ':
- return white_small_text;
- break;
- case '\t':
- return white_text;
- break;
- case '-':
- return white_big_text;
- break;
- case '*':
- return blue_text;
- break;
- case '#':
- return white_text;
- break;
- case '!':
- return 0;
- break;
- default:
- return 0;
- log_warning << "Unknown format_char: '" << format_char << "'" << std::endl;
- break;
- }
-}
-
-InfoBoxLine::LineType get_linetype_by_format_char(char format_char) {
- switch(format_char)
- {
- case ' ':
- return InfoBoxLine::SMALL;
- break;
- case '\t':
- return InfoBoxLine::NORMAL;
- break;
- case '-':
- return InfoBoxLine::HEADING;
- break;
- case '*':
- return InfoBoxLine::REFERENCE;
- break;
- case '#':
- return InfoBoxLine::NORMAL_LEFT;
- break;
- case '!':
- return InfoBoxLine::IMAGE;
- break;
- default:
- return InfoBoxLine::SMALL;
- log_warning << "Unknown format_char: '" << format_char << "'" << std::endl;
- break;
- }
-}
-}
-
-InfoBoxLine::InfoBoxLine(char format_char, const std::string& text) : lineType(NORMAL), font(white_text), text(text), image(0)
-{
- font = get_font_by_format_char(format_char);
- lineType = get_linetype_by_format_char(format_char);
- if (lineType == IMAGE) image = new Surface(text);
-}
-
-InfoBoxLine::~InfoBoxLine()
-{
- delete image;
-}
-
-const std::vector<InfoBoxLine*>
-InfoBoxLine::split(const std::string& text, float width)
-{
- std::vector<InfoBoxLine*> lines;
-
- std::string::size_type i = 0;
- std::string::size_type l;
- char format_char = '#';
- while(i < text.size()) {
- // take care of empty lines - represent them as blank lines of normal text
- if (text[i] == '\n') {
- lines.push_back(new InfoBoxLine('\t', ""));
- i++;
- continue;
- }
-
- // extract the format_char
- format_char = text[i];
- i++;
- if (i >= text.size()) break;
-
- // extract one line
- l = text.find("\n", i);
- if (l == std::string::npos) l=text.size();
- std::string s = text.substr(i, l-i);
- i = l+1;
-
- // if we are dealing with an image, just store the line
- if (format_char == '!') {
- lines.push_back(new InfoBoxLine(format_char, s));
- continue;
- }
-
- // append wrapped parts of line into list
- std::string overflow;
- do {
- Font* font = get_font_by_format_char(format_char);
- std::string s2 = s;
- if (font) s2 = font->wrap_to_width(s2, width, &overflow);
- lines.push_back(new InfoBoxLine(format_char, s2));
- s = overflow;
- } while (s.length() > 0);
-
- }
-
- return lines;
-}
-
-void
-InfoBoxLine::draw(DrawingContext& context, const Rect& bbox, int layer)
-{
- Vector position = bbox.p1;
- switch (lineType) {
- case IMAGE:
- context.draw_surface(image, Vector( (bbox.p1.x + bbox.p2.x - image->get_width()) / 2, position.y), layer);
- break;
- case NORMAL_LEFT:
- context.draw_text(font, text, Vector(position.x, position.y), ALIGN_LEFT, layer);
- break;
- default:
- context.draw_text(font, text, Vector((bbox.p1.x + bbox.p2.x) / 2, position.y), ALIGN_CENTER, layer);
- break;
- }
-}
-
-float
-InfoBoxLine::get_height()
-{
- switch (lineType) {
- case IMAGE:
- return image->get_height() + ITEMS_SPACE;
- case NORMAL_LEFT:
- return font->get_height() + ITEMS_SPACE;
- default:
- return font->get_height() + ITEMS_SPACE;
- }
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __TEXTSCROLLER_H__
-#define __TEXTSCROLLER_H__
-
-#include <vector>
-#include <string>
-#include <map>
-
-#include "screen.hpp"
-#include "math/vector.hpp"
-#include "math/rect.hpp"
-
-class DrawingContext;
-class Surface;
-class Font;
-
-/**
- * Helper class for InfoBox: Represents a line of text
- */
-class InfoBoxLine
-{
-public:
- enum LineType { NORMAL, NORMAL_LEFT, SMALL, HEADING, REFERENCE, IMAGE};
-
- InfoBoxLine(char format_char, const std::string& text);
- ~InfoBoxLine();
-
- void draw(DrawingContext& context, const Rect& bbox, int layer);
- float get_height();
-
- static const std::vector<InfoBoxLine*> split(const std::string& text, float width);
-
-private:
- InfoBoxLine::LineType lineType;
- Font* font;
- std::string text;
- Surface* image;
-};
-
-/** This class is displaying a box with information text inside the game
- */
-class InfoBox
-{
-public:
- InfoBox(const std::string& text);
- ~InfoBox();
-
- void draw(DrawingContext& context);
- void scrolldown();
- void scrollup();
- void pagedown();
- void pageup();
-
-private:
- size_t firstline;
- std::vector<InfoBoxLine*> lines;
- std::map<std::string, Surface*> images;
- Surface* arrow_scrollup;
- Surface* arrow_scrolldown;
-};
-
-class TextScroller : public Screen
-{
-public:
- TextScroller(const std::string& file);
- virtual ~TextScroller();
-
- void setup();
- void draw(DrawingContext& context);
- void update(float elapsed_time);
-
-private:
- float defaultspeed;
- float speed;
- std::string music;
- std::auto_ptr<Surface> background;
- std::vector<InfoBoxLine*> lines;
- float scroll;
- bool fading;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2004 Tobias Glaesser <tobi.web@gmx.de>
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#include <config.h>
-
-#include <math.h>
-#include <assert.h>
-#include <iostream>
-#include <stdexcept>
-
-#include "lisp/lisp.hpp"
-#include "tile.hpp"
-#include "resources.hpp"
-#include "timer.hpp"
-#include "math/vector.hpp"
-#include "video/drawing_context.hpp"
-#include "log.hpp"
-
-
-Tile::Tile()
- : id(0), attributes(0), data(0), anim_fps(1)
-{
-}
-
-Tile::Tile(unsigned int id, Uint32 attributes, const ImageSpec& imagespec)
- : id(id), attributes(attributes), data(0), anim_fps(1)
-{
- imagespecs.push_back(imagespec);
-}
-
-Tile::~Tile()
-{
- for(std::vector<Surface*>::iterator i = images.begin(); i != images.end();
- ++i) {
- delete *i;
- }
-}
-
-void
-Tile::parse(const lisp::Lisp& reader)
-{
- if(!reader.get("id", id)) {
- throw std::runtime_error("Missing tile-id.");
- }
-
- bool value = false;
- if(reader.get("solid", value) && value)
- attributes |= SOLID;
- if(reader.get("unisolid", value) && value)
- attributes |= UNISOLID | SOLID;
- if(reader.get("brick", value) && value)
- attributes |= BRICK;
- if(reader.get("ice", value) && value)
- attributes |= ICE;
- if(reader.get("water", value) && value)
- attributes |= WATER;
- if(reader.get("hurts", value) && value)
- attributes |= HURTS;
- if(reader.get("fire", value) && value)
- attributes |= FIRE;
- if(reader.get("fullbox", value) && value)
- attributes |= FULLBOX;
- if(reader.get("coin", value) && value)
- attributes |= COIN;
- if(reader.get("goal", value) && value)
- attributes |= GOAL;
-
- if(reader.get("north", value) && value)
- data |= WORLDMAP_NORTH;
- if(reader.get("south", value) && value)
- data |= WORLDMAP_SOUTH;
- if(reader.get("west", value) && value)
- data |= WORLDMAP_WEST;
- if(reader.get("east", value) && value)
- data |= WORLDMAP_EAST;
- if(reader.get("stop", value) && value)
- data |= WORLDMAP_STOP;
-
- reader.get("data", data);
- reader.get("anim-fps", anim_fps);
-
- if(reader.get("slope-type", data)) {
- attributes |= SOLID | SLOPE;
- }
-
- const lisp::Lisp* images = reader.get_lisp("images");
- if(images)
- parse_images(*images);
-}
-
-void
-Tile::parse_images(const lisp::Lisp& images_lisp)
-{
- const lisp::Lisp* list = &images_lisp;
- while(list) {
- const lisp::Lisp* cur = list->get_car();
- if(cur->get_type() == lisp::Lisp::TYPE_STRING) {
- std::string file;
- cur->get(file);
- imagespecs.push_back(ImageSpec(file, Rect(0, 0, 0, 0)));
- } else if(cur->get_type() == lisp::Lisp::TYPE_CONS &&
- cur->get_car()->get_type() == lisp::Lisp::TYPE_SYMBOL &&
- cur->get_car()->get_symbol() == "region") {
- const lisp::Lisp* ptr = cur->get_cdr();
-
- std::string file;
- float x = 0, y = 0, w = 0, h = 0;
- ptr->get_car()->get(file); ptr = ptr->get_cdr();
- ptr->get_car()->get(x); ptr = ptr->get_cdr();
- ptr->get_car()->get(y); ptr = ptr->get_cdr();
- ptr->get_car()->get(w); ptr = ptr->get_cdr();
- ptr->get_car()->get(h);
- imagespecs.push_back(ImageSpec(file, Rect(x, y, x+w, y+h)));
- } else {
- log_warning << "Expected string or list in images tag" << std::endl;
- continue;
- }
-
- list = list->get_cdr();
- }
-}
-
-void
-Tile::load_images(const std::string& tilesetpath)
-{
- assert(images.size() == 0);
- for(std::vector<ImageSpec>::iterator i = imagespecs.begin(); i !=
- imagespecs.end(); ++i) {
- const ImageSpec& spec = *i;
- Surface* surface;
- std::string file = tilesetpath + spec.file;
- if(spec.rect.get_width() <= 0) {
- surface = new Surface(file);
- } else {
- surface = new Surface(file,
- (int) spec.rect.p1.x,
- (int) spec.rect.p1.y,
- (int) spec.rect.get_width(),
- (int) spec.rect.get_height());
- }
- images.push_back(surface);
- }
-}
-
-void
-Tile::draw(DrawingContext& context, const Vector& pos, int z_pos) const
-{
- if(images.size() > 1) {
- size_t frame = size_t(game_time * anim_fps) % images.size();
- context.draw_surface(images[frame], pos, z_pos);
- } else if (images.size() == 1) {
- context.draw_surface(images[0], pos, z_pos);
- }
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2004 Tobias Glaesser <tobi.web@gmx.de>
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#ifndef TILE_H
-#define TILE_H
-
-#include <vector>
-#include <SDL.h>
-#include <stdint.h>
-#include "video/surface.hpp"
-#include "math/rect.hpp"
-
-namespace lisp { class Lisp; }
-
-class DrawingContext;
-
-/**
-Tile Class
-*/
-class Tile
-{
-public:
- /// bitset for tile attributes
- enum {
- /** solid tile that is indestructable by Tux */
- SOLID = 0x0001,
- /** uni-directional solid tile */
- UNISOLID = 0x0002,
- /** a brick that can be destroyed by jumping under it */
- BRICK = 0x0004,
- /** the level should be finished when touching a goaltile.
- * if data is 0 then the endsequence should be triggered, if data is 1
- * then we can finish the level instantly.
- */
- GOAL = 0x0008,
- /** slope tile */
- SLOPE = 0x0010,
- /** Bonusbox, content is stored in \a data */
- FULLBOX = 0x0020,
- /** Tile is a coin */
- COIN = 0x0040,
-
- /* interesting flags (the following are passed to gameobjects) */
- FIRST_INTERESTING_FLAG = 0x0100,
-
- /** an ice brick that makes tux sliding more than usual */
- ICE = 0x0100,
- /** a water tile in which tux starts to swim */
- WATER = 0x0200,
- /** a tile that hurts the player if he touches it */
- HURTS = 0x0400,
- /** for lava: WATER, HURTS, FIRE */
- FIRE = 0x0800
- };
-
- /// worldmap flags
- enum {
- WORLDMAP_NORTH = 0x0001,
- WORLDMAP_SOUTH = 0x0002,
- WORLDMAP_EAST = 0x0004,
- WORLDMAP_WEST = 0x0008,
- WORLDMAP_DIR_MASK = 0x000f,
-
- WORLDMAP_STOP = 0x0010,
-
- // convenience values ("C" stands for crossroads)
- WORLDMAP_CNSE = WORLDMAP_NORTH | WORLDMAP_SOUTH | WORLDMAP_EAST,
- WORLDMAP_CNSW = WORLDMAP_NORTH | WORLDMAP_SOUTH | WORLDMAP_WEST,
- WORLDMAP_CNEW = WORLDMAP_NORTH | WORLDMAP_EAST | WORLDMAP_WEST,
- WORLDMAP_CSEW = WORLDMAP_SOUTH | WORLDMAP_EAST | WORLDMAP_WEST,
- WORLDMAP_CNSEW = WORLDMAP_NORTH | WORLDMAP_SOUTH | WORLDMAP_EAST | WORLDMAP_WEST
- };
-
- struct ImageSpec {
- ImageSpec(const std::string& newfile, const Rect& newrect)
- : file(newfile), rect(newrect)
- { }
-
- std::string file;
- Rect rect;
- };
-
-private:
- unsigned int id;
-
- std::vector<ImageSpec> imagespecs;
- std::vector<Surface*> images;
-
- /// tile attributes
- uint32_t attributes;
-
- /** General purpose data attached to a tile (content of a box, type of coin)*/
- int data;
-
- float anim_fps;
-
-public:
- ~Tile();
-
- /** Draw a tile on the screen */
- void draw(DrawingContext& context, const Vector& pos, int z_pos) const;
-
- unsigned int getID() const
- { return id; }
-
- uint32_t getAttributes() const
- { return attributes; }
-
- int getData() const
- { return data; }
-
- /// returns the width of the tile in pixels
- int getWidth() const
- {
- if(!images.size())
- return 0;
- return (int) images[0]->get_width();
- }
-
- /// returns the height of the tiles in pixels
- int getHeight() const
- {
- if(!images.size())
- return 0;
- return (int) images[0]->get_height();
- }
-
-protected:
- friend class TileManager;
- Tile();
- Tile(unsigned int id, Uint32 attributes, const ImageSpec& imagespec);
-
- void load_images(const std::string& tilesetpath);
-
- /// parses the tile and returns it's id number
- void parse(const lisp::Lisp& reader);
- void parse_images(const lisp::Lisp& cur);
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2004 Tobias Glaesser <tobi.web@gmx.de>
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#include <config.h>
-
-#include <memory>
-#include <stdexcept>
-#include <sstream>
-#include <iostream>
-#include <assert.h>
-#include <SDL.h>
-#include "video/drawing_context.hpp"
-#include "log.hpp"
-#include "lisp/lisp.hpp"
-#include "lisp/parser.hpp"
-#include "lisp/list_iterator.hpp"
-#include "tile.hpp"
-#include "tile_manager.hpp"
-#include "resources.hpp"
-
-TileManager* tile_manager = NULL;
-
-TileManager::TileManager(const std::string& filename)
-{
-#ifdef DEBUG
- Uint32 ticks = SDL_GetTicks();
-#endif
- load_tileset(filename);
-#ifdef DEBUG
- log_debug << "Tiles loaded in " << (SDL_GetTicks() - ticks) / 1000.0 << " seconds" << std::endl;
-#endif
-}
-
-TileManager::~TileManager()
-{
- for(Tiles::iterator i = tiles.begin(); i != tiles.end(); ++i)
- delete *i;
-}
-
-void TileManager::load_tileset(std::string filename)
-{
- // free old tiles
- for(Tiles::iterator i = tiles.begin(); i != tiles.end(); ++i)
- delete *i;
- tiles.clear();
-
- std::string::size_type t = filename.rfind('/');
- if(t == std::string::npos) {
- tiles_path = "";
- } else {
- tiles_path = filename.substr(0, t+1);
- }
-
- lisp::Parser parser;
- const lisp::Lisp* root = parser.parse(filename);
-
- const lisp::Lisp* tiles_lisp = root->get_lisp("supertux-tiles");
- if(!tiles_lisp)
- throw std::runtime_error("file is not a supertux tiles file.");
-
- lisp::ListIterator iter(tiles_lisp);
- while(iter.next()) {
- if(iter.item() == "tile") {
- Tile* tile = new Tile();
- tile->parse(*(iter.lisp()));
-
- if(tile->id >= tiles.size())
- tiles.resize(tile->id+1, 0);
-
- if(tiles[tile->id] != 0) {
- log_warning << "Tile with ID " << tile->id << " redefined" << std::endl;
- delete tile;
- } else {
- tiles[tile->id] = tile;
- }
- } else if(iter.item() == "tilegroup") {
- TileGroup tilegroup;
- const lisp::Lisp* tilegroup_lisp = iter.lisp();
- tilegroup_lisp->get("name", tilegroup.name);
- tilegroup_lisp->get_vector("tiles", tilegroup.tiles);
- tilegroups.insert(tilegroup);
- } else if (iter.item() == "tiles") {
- // List of ids (use 0 if the tile should be ignored)
- std::vector<unsigned int> ids;
- // List of attributes of the tile
- std::vector<unsigned int> attributes;
- std::string image;
-
- // width and height of the image in tile units, this is used for two
- // purposes:
- // a) so we don't have to load the image here to know its dimensions
- // b) so that the resulting 'tiles' entry is more robust,
- // ie. enlarging the image won't break the tile id mapping
- // FIXME: height is actually not used, since width might be enough for
- // all purposes, still feels somewhat more natural this way
- unsigned int width = 0;
- unsigned int height = 0;
-
- iter.lisp()->get_vector("ids", ids);
- iter.lisp()->get_vector("attributes", attributes);
- iter.lisp()->get("image", image);
- iter.lisp()->get("width", width);
- iter.lisp()->get("height", height);
-
- if (ids.size() != attributes.size())
- {
- std::ostringstream err;
- err << "Number of ids (" << ids.size() << ") and attributes (" << attributes.size()
- << ") missmatch for image '" << image << "', but must be equal";
- throw std::runtime_error(err.str());
- }
-
- for(std::vector<unsigned int>::size_type i = 0; i < ids.size() && i < width*height; ++i)
- {
- if (ids[i])
- {
- if(ids[i] >= tiles.size())
- tiles.resize(ids[i]+1, 0);
-
- int x = 32*(i % width);
- int y = 32*(i / width);
- Tile* tile = new Tile(ids[i], attributes[i], Tile::ImageSpec(image, Rect(x, y, x + 32, y + 32)));
- if (tiles[ids[i]] == 0) {
- tiles[ids[i]] = tile;
- } else {
- log_warning << "Tile with ID " << ids[i] << " redefined" << std::endl;
- delete tile;
- }
- }
- }
-
- } else if(iter.item() == "properties") {
- // deprecated
- } else {
- log_warning << "Unknown symbol '" << iter.item() << "' tile defintion file" << std::endl;
- }
- }
-
- if (0)
- { // enable this if you want to see a list of free tiles
- log_info << "Last Tile ID is " << tiles.size()-1 << std::endl;
- int last = -1;
- for(int i = 0; i < int(tiles.size()); ++i)
- {
- if (tiles[i] == 0 && last == -1)
- {
- last = i;
- }
- else if (tiles[i] && last != -1)
- {
- log_info << "Free Tile IDs (" << i - last << "): " << last << " - " << i-1 << std::endl;
- last = -1;
- }
- }
- }
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2004 Tobias Glaesser <tobi.web@gmx.de>
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef HEADER_TILE_MANAGER_HXX
-#define HEADER_TILE_MANAGER_HXX
-
-#include <set>
-#include <vector>
-#include <string>
-#include <map>
-#include <iostream>
-#include <stdint.h>
-#include <assert.h>
-#include "log.hpp"
-#include "tile.hpp"
-
-struct TileGroup
-{
- friend bool operator<(const TileGroup& lhs, const TileGroup& rhs)
- { return lhs.name < rhs.name; };
- friend bool operator>(const TileGroup& lhs, const TileGroup& rhs)
- { return lhs.name > rhs.name; };
-
- std::string name;
- std::vector<int> tiles;
-};
-
-class TileManager
-{
-private:
- typedef std::vector<Tile*> Tiles;
- Tiles tiles;
-
- static TileManager* instance_ ;
- std::set<TileGroup> tilegroups;
-
- std::string tiles_path;
-
- void load_tileset(std::string filename);
-
-public:
- TileManager(const std::string& filename);
- ~TileManager();
-
- const std::set<TileGroup>& get_tilegroups() const
- {
- return tilegroups;
- }
-
- const Tile* get(uint32_t id) const
- {
- //FIXME: Commenting out tiles in sprites.strf makes tiles.size() fail - it's being set to the first tile commented out.
- assert(id < tiles.size());
- Tile* tile = tiles[id];
- if(!tile) {
- log_warning << "Invalid tile: " << id << std::endl;
- return tiles[0];
- }
-
- if(tile->images.size() == 0 && tile->imagespecs.size() != 0)
- tile->load_images(tiles_path);
-
- return tile;
- }
-
- uint32_t get_max_tileid() const
- {
- return tiles.size();
- }
-
- int get_default_width() const
- {
- return 32;
- }
-
- int get_default_height() const
- {
- return 32;
- }
-};
-
-extern TileManager* tile_manager;
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#include <config.h>
-
-#include <math.h>
-#include "timer.hpp"
-
-float game_time = 0;
-float real_time = 0;
-
-Timer::Timer()
- : period(0), cycle_start(0), cyclic(false)
-{
-}
-
-Timer::~Timer()
-{
-}
-
-void
-Timer::start(float period, bool cyclic)
-{
- this->period = period;
- this->cyclic = cyclic;
- cycle_start = game_time;
-}
-
-bool
-Timer::check()
-{
- if(period == 0)
- return false;
-
- if(game_time - cycle_start >= period) {
- if(cyclic) {
- cycle_start = game_time - fmodf(game_time - cycle_start, period);
- } else {
- period = 0;
- }
- return true;
- }
-
- return false;
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#ifndef __SUPERTUX_TIMER_H__
-#define __SUPERTUX_TIMER_H__
-
-extern float game_time;
-extern float real_time;
-
-/**
- * Simple timer designed to be used in the update functions of objects
- */
-class Timer
-{
-public:
- Timer();
- ~Timer();
-
- /** start the timer with the given period (in seconds).
- * If cyclic=true then the timer willl be reset after each period.
- * Set period to zero if you want to disable the timer.
- */
- void start(float period, bool cyclic = false);
- /** returns true if a period (or more) passed since start call or last
- * successfull check
- */
- bool check();
- /** stop the timer */
- void stop()
- { start(0); }
-
- /** returns the period of the timer or 0 if it isn't started */
- float get_period() const
- { return period; }
- float get_timeleft() const
- { return period - (game_time - cycle_start); }
- float get_timegone() const
- { return game_time - cycle_start; }
- bool started() const
- { return period != 0 && get_timeleft() > 0; }
-
-private:
- float period;
- float cycle_start;
- bool cyclic;
-};
-
-#endif
+++ /dev/null
-/*
- findlocale-0.46.tar.gz from http://icculus.org/~aspirin/findlocale/
-
-Copyright (C) 2004 Adam D. Moss (the "Author"). All Rights Reserved.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is fur-
-nished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FIT-
-NESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
-IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CON-
-NECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-Except as contained in this notice, the name of the Author of the
-Software shall not be used in advertising or otherwise to promote the sale,
-use or other dealings in this Software without prior written authorization
-from the Author.
-
-*/
-#include <config.h>
-
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-
-#ifdef WIN32
-#include <windows.h>
-#include <winnt.h>
-#endif
-
-#ifdef MACOSX
-#include <CoreFoundation/CoreFoundation.h>
-#endif
-
-#include "findlocale.hpp"
-
-static int
-is_lcchar(const int c) {
- return isalnum(c);
-}
-
-static void
-lang_country_variant_from_envstring(const char *str,
- char **lang,
- char **country,
- char **variant) {
- int end = 0;
- int start;
-
- /* get lang, if any */
- start = end;
- while (is_lcchar(str[end])) {
- ++end;
- }
- if (start != end) {
- int i;
- int len = end - start;
- char *s = (char*) malloc(len + 1);
- for (i=0; i<len; ++i) {
- s[i] = tolower(str[start + i]);
- }
- s[i] = '\0';
- *lang = s;
- } else {
- *lang = NULL;
- }
-
- if (str[end] && str[end]!=':') { /* not at end of str */
- ++end;
- }
-
- /* get country, if any */
- start = end;
- while (is_lcchar(str[end])) {
- ++end;
- }
- if (start != end) {
- int i;
- int len = end - start;
- char *s = (char*) malloc(len + 1);
- for (i=0; i<len; ++i) {
- s[i] = toupper(str[start + i]);
- }
- s[i] = '\0';
- *country = s;
- } else {
- *country = NULL;
- }
-
- if (str[end] && str[end]!=':') { /* not at end of str */
- ++end;
- }
-
- /* get variant, if any */
- start = end;
- while (str[end] && str[end]!=':') {
- ++end;
- }
- if (start != end) {
- int i;
- int len = end - start;
- char *s = (char*) malloc(len + 1);
- for (i=0; i<len; ++i) {
- s[i] = str[start + i];
- }
- s[i] = '\0';
- *variant = s;
- } else {
- *variant = NULL;
- }
-}
-
-
-static int
-accumulate_locstring(const char *str, FL_Locale *l) {
- char *lang = NULL;
- char *country = NULL;
- char *variant = NULL;
- if (str) {
- lang_country_variant_from_envstring(str, &lang, &country, &variant);
- if (lang) {
- l->lang = lang;
- l->country = country;
- l->variant = variant;
- return 1;
- }
- }
- free(lang); free(country); free(variant);
- return 0;
-}
-
-
-#ifndef WIN32
-static int
-accumulate_env(const char *name, FL_Locale *l) {
- char *env;
- char *lang = NULL;
- char *country = NULL;
- char *variant = NULL;
- env = getenv(name);
- if (env) {
- return accumulate_locstring(env, l);
- }
- free(lang); free(country); free(variant);
- return 0;
-}
-#endif
-
-static void
-canonise_fl(FL_Locale *l) {
- /* this function fixes some common locale-specifying mistakes */
- /* en_UK -> en_GB */
- if (l->lang && 0 == strcmp(l->lang, "en")) {
- if (l->country && 0 == strcmp(l->country, "UK")) {
- free((void*)l->country);
- l->country = strdup("GB");
- }
- }
- /* ja_JA -> ja_JP */
- if (l->lang && 0 == strcmp(l->lang, "ja")) {
- if (l->country && 0 == strcmp(l->country, "JA")) {
- free((void*)l->country);
- l->country = strdup("JP");
- }
- }
-}
-
-
-#ifdef WIN32
-#include <stdio.h>
-#define ML(pn,sn) MAKELANGID(LANG_##pn, SUBLANG_##pn##_##sn)
-#define MLN(pn) MAKELANGID(LANG_##pn, SUBLANG_DEFAULT)
-#define RML(pn,sn) MAKELANGID(LANG_##pn, SUBLANG_##sn)
-typedef struct {
- LANGID id;
- char* code;
-} IDToCode;
-static const IDToCode both_to_code[] = {
- {ML(ENGLISH,US), "en_US.ISO_8859-1"},
- {ML(ENGLISH,CAN), "en_CA"}, /* english / canadian */
- {ML(ENGLISH,UK), "en_GB"},
- {ML(ENGLISH,EIRE), "en_IE"},
- {ML(ENGLISH,AUS), "en_AU"},
- {MLN(GERMAN), "de_DE"},
- {MLN(SPANISH), "es_ES"},
- {ML(SPANISH,MEXICAN), "es_MX"},
- {MLN(FRENCH), "fr_FR"},
- {ML(FRENCH,CANADIAN), "fr_CA"},
- {ML(FRENCH,BELGIAN), "fr_BE"}, /* ? */
- {ML(DUTCH,BELGIAN), "nl_BE"}, /* ? */
- {ML(PORTUGUESE,BRAZILIAN), "pt_BR"},
- {MLN(PORTUGUESE), "pt_PT"},
- {MLN(SWEDISH), "sv_SE"},
- {ML(CHINESE,HONGKONG), "zh_HK"},
- /* these are machine-generated and not yet verified */
- {RML(AFRIKAANS,DEFAULT), "af_ZA"},
- {RML(ALBANIAN,DEFAULT), "sq_AL"},
- {RML(ARABIC,ARABIC_ALGERIA), "ar_DZ"},
- {RML(ARABIC,ARABIC_BAHRAIN), "ar_BH"},
- {RML(ARABIC,ARABIC_EGYPT), "ar_EG"},
- {RML(ARABIC,ARABIC_IRAQ), "ar_IQ"},
- {RML(ARABIC,ARABIC_JORDAN), "ar_JO"},
- {RML(ARABIC,ARABIC_KUWAIT), "ar_KW"},
- {RML(ARABIC,ARABIC_LEBANON), "ar_LB"},
- {RML(ARABIC,ARABIC_LIBYA), "ar_LY"},
- {RML(ARABIC,ARABIC_MOROCCO), "ar_MA"},
- {RML(ARABIC,ARABIC_OMAN), "ar_OM"},
- {RML(ARABIC,ARABIC_QATAR), "ar_QA"},
- {RML(ARABIC,ARABIC_SAUDI_ARABIA), "ar_SA"},
- {RML(ARABIC,ARABIC_SYRIA), "ar_SY"},
- {RML(ARABIC,ARABIC_TUNISIA), "ar_TN"},
- {RML(ARABIC,ARABIC_UAE), "ar_AE"},
- {RML(ARABIC,ARABIC_YEMEN), "ar_YE"},
- {RML(ARMENIAN,DEFAULT), "hy_AM"},
- {RML(AZERI,AZERI_CYRILLIC), "az_AZ"},
- {RML(AZERI,AZERI_LATIN), "az_AZ"},
- {RML(BASQUE,DEFAULT), "eu_ES"},
- {RML(BELARUSIAN,DEFAULT), "be_BY"},
-/*{RML(BRETON,DEFAULT), "br_FR"},*/
- {RML(BULGARIAN,DEFAULT), "bg_BG"},
- {RML(CATALAN,DEFAULT), "ca_ES"},
- {RML(CHINESE,CHINESE_HONGKONG), "zh_HK"},
- {RML(CHINESE,CHINESE_MACAU), "zh_MO"},
- {RML(CHINESE,CHINESE_SIMPLIFIED), "zh_CN"},
- {RML(CHINESE,CHINESE_SINGAPORE), "zh_SG"},
- {RML(CHINESE,CHINESE_TRADITIONAL), "zh_TW"},
-/*{RML(CORNISH,DEFAULT), "kw_GB"},*/
- {RML(CZECH,DEFAULT), "cs_CZ"},
- {RML(DANISH,DEFAULT), "da_DK"},
- {RML(DUTCH,DUTCH), "nl_NL"},
- {RML(DUTCH,DUTCH_BELGIAN), "nl_BE"},
-/*{RML(DUTCH,DUTCH_SURINAM), "nl_SR"},*/
- {RML(ENGLISH,ENGLISH_AUS), "en_AU"},
- {RML(ENGLISH,ENGLISH_BELIZE), "en_BZ"},
- {RML(ENGLISH,ENGLISH_CAN), "en_CA"},
- {RML(ENGLISH,ENGLISH_CARIBBEAN), "en_CB"},
- {RML(ENGLISH,ENGLISH_EIRE), "en_IE"},
- {RML(ENGLISH,ENGLISH_JAMAICA), "en_JM"},
- {RML(ENGLISH,ENGLISH_NZ), "en_NZ"},
- {RML(ENGLISH,ENGLISH_PHILIPPINES), "en_PH"},
- {RML(ENGLISH,ENGLISH_SOUTH_AFRICA), "en_ZA"},
- {RML(ENGLISH,ENGLISH_TRINIDAD), "en_TT"},
- {RML(ENGLISH,ENGLISH_UK), "en_GB"},
- {RML(ENGLISH,ENGLISH_US), "en_US"},
- {RML(ENGLISH,ENGLISH_ZIMBABWE), "en_ZW"},
-/*{RML(ESPERANTO,DEFAULT), "eo_"},*/
- {RML(ESTONIAN,DEFAULT), "et_EE"},
- {RML(FAEROESE,DEFAULT), "fo_FO"},
- {RML(FARSI,DEFAULT), "fa_IR"},
- {RML(FINNISH,DEFAULT), "fi_FI"},
- {RML(FRENCH,FRENCH), "fr_FR"},
- {RML(FRENCH,FRENCH_BELGIAN), "fr_BE"},
- {RML(FRENCH,FRENCH_CANADIAN), "fr_CA"},
- {RML(FRENCH,FRENCH_LUXEMBOURG), "fr_LU"},
- {RML(FRENCH,FRENCH_MONACO), "fr_MC"},
- {RML(FRENCH,FRENCH_SWISS), "fr_CH"},
-/*{RML(GAELIC,GAELIC), "ga_IE"},*/
-/*{RML(GAELIC,GAELIC_MANX), "gv_GB"},*/
-/*{RML(GAELIC,GAELIC_SCOTTISH), "gd_GB"},*/
-/*{RML(GALICIAN,DEFAULT), "gl_ES"},*/
- {RML(GEORGIAN,DEFAULT), "ka_GE"},
- {RML(GERMAN,GERMAN), "de_DE"},
- {RML(GERMAN,GERMAN_AUSTRIAN), "de_AT"},
- {RML(GERMAN,GERMAN_LIECHTENSTEIN), "de_LI"},
- {RML(GERMAN,GERMAN_LUXEMBOURG), "de_LU"},
- {RML(GERMAN,GERMAN_SWISS), "de_CH"},
- {RML(GREEK,DEFAULT), "el_GR"},
- {RML(GUJARATI,DEFAULT), "gu_IN"},
- {RML(HEBREW,DEFAULT), "he_IL"},
- {RML(HINDI,DEFAULT), "hi_IN"},
- {RML(HUNGARIAN,DEFAULT), "hu_HU"},
- {RML(ICELANDIC,DEFAULT), "is_IS"},
- {RML(INDONESIAN,DEFAULT), "id_ID"},
- {RML(ITALIAN,ITALIAN), "it_IT"},
- {RML(ITALIAN,ITALIAN_SWISS), "it_CH"},
- {RML(JAPANESE,DEFAULT), "ja_JP"},
- {RML(KANNADA,DEFAULT), "kn_IN"},
- {RML(KAZAK,DEFAULT), "kk_KZ"},
- {RML(KONKANI,DEFAULT), "kok_IN"},
- {RML(KOREAN,KOREAN), "ko_KR"},
-/*{RML(KYRGYZ,DEFAULT), "ky_KG"},*/
- {RML(LATVIAN,DEFAULT), "lv_LV"},
- {RML(LITHUANIAN,LITHUANIAN), "lt_LT"},
- {RML(MACEDONIAN,DEFAULT), "mk_MK"},
- {RML(MALAY,MALAY_BRUNEI_DARUSSALAM), "ms_BN"},
- {RML(MALAY,MALAY_MALAYSIA), "ms_MY"},
- {RML(MARATHI,DEFAULT), "mr_IN"},
-/*{RML(MONGOLIAN,DEFAULT), "mn_MN"},*/
- {RML(NORWEGIAN,NORWEGIAN_BOKMAL), "nb_NO"},
- {RML(NORWEGIAN,NORWEGIAN_NYNORSK), "nn_NO"},
- {RML(POLISH,DEFAULT), "pl_PL"},
- {RML(PORTUGUESE,PORTUGUESE), "pt_PT"},
- {RML(PORTUGUESE,PORTUGUESE_BRAZILIAN), "pt_BR"},
- {RML(PUNJABI,DEFAULT), "pa_IN"},
- {RML(ROMANIAN,DEFAULT), "ro_RO"},
- {RML(RUSSIAN,DEFAULT), "ru_RU"},
- {RML(SANSKRIT,DEFAULT), "sa_IN"},
- {RML(SERBIAN,DEFAULT), "hr_HR"},
- {RML(SERBIAN,SERBIAN_CYRILLIC), "sr_SP"},
- {RML(SERBIAN,SERBIAN_LATIN), "sr_SP"},
- {RML(SLOVAK,DEFAULT), "sk_SK"},
- {RML(SLOVENIAN,DEFAULT), "sl_SI"},
- {RML(SPANISH,SPANISH), "es_ES"},
- {RML(SPANISH,SPANISH_ARGENTINA), "es_AR"},
- {RML(SPANISH,SPANISH_BOLIVIA), "es_BO"},
- {RML(SPANISH,SPANISH_CHILE), "es_CL"},
- {RML(SPANISH,SPANISH_COLOMBIA), "es_CO"},
- {RML(SPANISH,SPANISH_COSTA_RICA), "es_CR"},
- {RML(SPANISH,SPANISH_DOMINICAN_REPUBLIC), "es_DO"},
- {RML(SPANISH,SPANISH_ECUADOR), "es_EC"},
- {RML(SPANISH,SPANISH_EL_SALVADOR), "es_SV"},
- {RML(SPANISH,SPANISH_GUATEMALA), "es_GT"},
- {RML(SPANISH,SPANISH_HONDURAS), "es_HN"},
- {RML(SPANISH,SPANISH_MEXICAN), "es_MX"},
- {RML(SPANISH,SPANISH_MODERN), "es_ES"},
- {RML(SPANISH,SPANISH_NICARAGUA), "es_NI"},
- {RML(SPANISH,SPANISH_PANAMA), "es_PA"},
- {RML(SPANISH,SPANISH_PARAGUAY), "es_PY"},
- {RML(SPANISH,SPANISH_PERU), "es_PE"},
- {RML(SPANISH,SPANISH_PUERTO_RICO), "es_PR"},
- {RML(SPANISH,SPANISH_URUGUAY), "es_UY"},
- {RML(SPANISH,SPANISH_VENEZUELA), "es_VE"},
- {RML(SWAHILI,DEFAULT), "sw_KE"},
- {RML(SWEDISH,SWEDISH), "sv_SE"},
- {RML(SWEDISH,SWEDISH_FINLAND), "sv_FI"},
-/*{RML(SYRIAC,DEFAULT), "syr_SY"},*/
- {RML(TAMIL,DEFAULT), "ta_IN"},
- {RML(TATAR,DEFAULT), "tt_TA"},
- {RML(TELUGU,DEFAULT), "te_IN"},
- {RML(THAI,DEFAULT), "th_TH"},
- {RML(TURKISH,DEFAULT), "tr_TR"},
- {RML(UKRAINIAN,DEFAULT), "uk_UA"},
- {RML(URDU,URDU_PAKISTAN), "ur_PK"},
- {RML(UZBEK,UZBEK_CYRILLIC), "uz_UZ"},
- {RML(UZBEK,UZBEK_LATIN), "uz_UZ"},
- {RML(VIETNAMESE,DEFAULT), "vi_VN"},
-/*{RML(WALON,DEFAULT), "wa_BE"},*/
-/*{RML(WELSH,DEFAULT), "cy_GB"},*/
-};
-static const IDToCode primary_to_code[] = {
- {LANG_AFRIKAANS, "af"},
- {LANG_ARABIC, "ar"},
- {LANG_AZERI, "az"},
- {LANG_BULGARIAN, "bg"},
-/*{LANG_BRETON, "br"},*/
- {LANG_BELARUSIAN, "by"},
- {LANG_CATALAN, "ca"},
- {LANG_CZECH, "cs"},
-/*{LANG_WELSH, "cy"},*/
- {LANG_DANISH, "da"},
- {LANG_GERMAN, "de"},
- {LANG_GREEK, "el"},
- {LANG_ENGLISH, "en"},
-/*{LANG_ESPERANTO, "eo"},*/
- {LANG_SPANISH, "es"},
- {LANG_ESTONIAN, "et"},
- {LANG_BASQUE, "eu"},
- {LANG_FARSI, "fa"},
- {LANG_FINNISH, "fi"},
- {LANG_FAEROESE, "fo"},
- {LANG_FRENCH, "fr"},
-/*{LANG_GAELIC, "ga"},*/
-/*{LANG_GALICIAN, "gl"},*/
- {LANG_GUJARATI, "gu"},
- {LANG_HEBREW, "he"},
- {LANG_HINDI, "hi"},
- {LANG_SERBIAN, "hr"},
- {LANG_HUNGARIAN, "hu"},
- {LANG_ARMENIAN, "hy"},
- {LANG_INDONESIAN, "id"},
- {LANG_ITALIAN, "it"},
- {LANG_JAPANESE, "ja"},
- {LANG_GEORGIAN, "ka"},
- {LANG_KAZAK, "kk"},
- {LANG_KANNADA, "kn"},
- {LANG_KOREAN, "ko"},
-/*{LANG_KYRGYZ, "ky"},*/
- {LANG_LITHUANIAN, "lt"},
- {LANG_LATVIAN, "lv"},
- {LANG_MACEDONIAN, "mk"},
-/*{LANG_MONGOLIAN, "mn"},*/
- {LANG_MARATHI, "mr"},
- {LANG_MALAY, "ms"},
- {LANG_NORWEGIAN, "nb"},
- {LANG_DUTCH, "nl"},
- {LANG_NORWEGIAN, "nn"},
- {LANG_NORWEGIAN, "no"},/* unofficial? */
- {LANG_PUNJABI, "pa"},
- {LANG_POLISH, "pl"},
- {LANG_PORTUGUESE, "pt"},
- {LANG_ROMANIAN, "ro"},
- {LANG_RUSSIAN, "ru"},
- {LANG_SLOVAK, "sk"},
- {LANG_SLOVENIAN, "sl"},
- {LANG_ALBANIAN, "sq"},
- {LANG_SERBIAN, "sr"},
- {LANG_SWEDISH, "sv"},
- {LANG_SWAHILI, "sw"},
- {LANG_TAMIL, "ta"},
- {LANG_THAI, "th"},
- {LANG_TURKISH, "tr"},
- {LANG_TATAR, "tt"},
- {LANG_UKRAINIAN, "uk"},
- {LANG_URDU, "ur"},
- {LANG_UZBEK, "uz"},
- {LANG_VIETNAMESE, "vi"},
-/*{LANG_WALON, "wa"},*/
- {LANG_CHINESE, "zh"},
-};
-static int num_primary_to_code =
- sizeof(primary_to_code) / sizeof(*primary_to_code);
-static int num_both_to_code =
- sizeof(both_to_code) / sizeof(*both_to_code);
-
-static const int
-lcid_to_fl(LCID lcid,
- FL_Locale *rtn) {
- LANGID langid = LANGIDFROMLCID(lcid);
- LANGID primary_lang = PRIMARYLANGID(langid);
-#if 0
- LANGID sub_lang = SUBLANGID(langid);
-#endif
- int i;
- /* try to find an exact primary/sublanguage combo that we know about */
- for (i=0; i<num_both_to_code; ++i) {
- if (both_to_code[i].id == langid) {
- accumulate_locstring(both_to_code[i].code, rtn);
- return 1;
- }
- }
- /* fallback to just checking the primary language id */
- for (i=0; i<num_primary_to_code; ++i) {
- if (primary_to_code[i].id == primary_lang) {
- accumulate_locstring(primary_to_code[i].code, rtn);
- return 1;
- }
- }
- return 0;
-}
-#endif
-
-
-FL_Success
-FL_FindLocale(FL_Locale **locale, FL_Domain /*domain*/) {
- FL_Success success = FL_FAILED;
- FL_Locale *rtn = (FL_Locale*) malloc(sizeof(FL_Locale));
- rtn->lang = NULL;
- rtn->country = NULL;
- rtn->variant = NULL;
-
-#ifdef WIN32
- /* win32 >= mswindows95 */
- {
- LCID lcid = GetThreadLocale();
- if (lcid_to_fl(lcid, rtn)) {
- success = FL_CONFIDENT;
- }
- if (success == FL_FAILED) {
- /* assume US English on mswindows systems unless we know otherwise */
- if (accumulate_locstring("en_US.ISO_8859-1", rtn)) {
- success = FL_DEFAULT_GUESS;
- }
- }
- }
-#else
- /* assume unixoid */
- {
-#ifdef MACOSX
- CFIndex sz;
- CFArrayRef languages;
- CFStringRef uxstylelangs;
- char *uxsl;
-
- /* get the languages from the user's presets */
- languages = (CFArrayRef)CFPreferencesCopyValue(CFSTR("AppleLanguages"),
- kCFPreferencesAnyApplication, kCFPreferencesCurrentUser,
- kCFPreferencesAnyHost);
-
- /* join the returned string array into a string separated by colons */
- uxstylelangs = CFStringCreateByCombiningStrings(kCFAllocatorDefault,
- languages, CFSTR(":"));
-
- /* convert this string into a C string */
- sz = CFStringGetLength(uxstylelangs) + 1;
- uxsl = (char*)malloc(sz);
- CFStringGetCString(uxstylelangs, uxsl, sz, kCFStringEncodingISOLatin1);
-
- /* add it to the list */
- if (accumulate_locstring(uxsl, rtn)) {
- success = FL_CONFIDENT;
- }
- /* continue the UNIX method */
-#endif
- /* examples: */
- /* sv_SE.ISO_8859-1 */
- /* fr_FR.ISO8859-1 */
- /* no_NO_NB */
- /* no_NO_NY */
- /* no_NO */
- /* de_DE */
- /* try the various vars in decreasing order of authority */
- if (accumulate_env("LC_ALL", rtn) ||
- accumulate_env("LC_MESSAGES", rtn) ||
- accumulate_env("LANG", rtn) ||
- accumulate_env("LANGUAGE", rtn)) {
- success = FL_CONFIDENT;
- }
- if (success == FL_FAILED) {
- /* assume US English on unixoid systems unless we know otherwise */
- if (accumulate_locstring("en_US.ISO_8859-1", rtn)) {
- success = FL_DEFAULT_GUESS;
- }
- }
- }
-#endif
-
- if (success != FL_FAILED) {
- canonise_fl(rtn);
- }
-
- *locale = rtn;
- return success;
-}
-
-
-void
-FL_FreeLocale(FL_Locale **locale) {
- if (locale) {
- FL_Locale *l = *locale;
- if (l) {
- if (l->lang) {
- free((void*)l->lang);
- }
- if (l->country) {
- free((void*)l->country);
- }
- if (l->variant) {
- free((void*)l->variant);
- }
- free(l);
- *locale = NULL;
- }
- }
-}
+++ /dev/null
-/*
- findlocale-0.46.tar.gz from http://icculus.org/~aspirin/findlocale/
-
-Copyright (C) 2004 Adam D. Moss (the "Author"). All Rights Reserved.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is fur-
-nished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FIT-
-NESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
-IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CON-
-NECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-Except as contained in this notice, the name of the Author of the
-Software shall not be used in advertising or otherwise to promote the sale,
-use or other dealings in this Software without prior written authorization
-from the Author.
-
-*/
-
-#ifndef __findlocale_h_
-#define __findlocale_h_
-
-typedef const char* FL_Lang;
-typedef const char* FL_Country;
-typedef const char* FL_Variant;
-
-typedef struct {
- FL_Lang lang;
- FL_Country country;
- FL_Variant variant;
-} FL_Locale;
-
-typedef enum {
- /* for some reason we failed to even guess: this should never happen */
- FL_FAILED = 0,
- /* couldn't query locale -- returning a guess (almost always English) */
- FL_DEFAULT_GUESS = 1,
- /* the returned locale type was found by successfully asking the system */
- FL_CONFIDENT = 2
-} FL_Success;
-
-typedef enum {
- FL_MESSAGES = 0
-} FL_Domain;
-
-/* This allocates/fills in a FL_Locale structure with pointers to
- strings (which should be treated as static), or NULL for inappropriate /
- undetected fields. */
-FL_Success FL_FindLocale(FL_Locale **locale, FL_Domain domain);
-/* This should be used to free the struct written by FL_FindLocale */
-void FL_FreeLocale(FL_Locale **locale);
-
-#endif /*__findlocale_h_*/
+++ /dev/null
-// $Id$
-//
-// TinyGetText
-// Copyright (C) 2006 Ingo Ruhnke <grumbel@gmx.de>
-//
-// 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.
-
-#include <config.h>
-
-#include <sys/types.h>
-#include <fstream>
-#include <iostream>
-#include <algorithm>
-#include <ctype.h>
-#include <errno.h>
-
-#include "SDL.h"
-
-#include "tinygettext.hpp"
-#include "log.hpp"
-#include "physfs/physfs_stream.hpp"
-#include <unison/vfs/FileSystem.hpp>
-#include "log.hpp"
-#include "findlocale.hpp"
-
-//#define TRANSLATION_DEBUG
-
-namespace TinyGetText {
-
-/** Convert \a which is in \a from_charset to \a to_charset and return it */
-std::string convert(const std::string& text,
- const std::string& from_charset,
- const std::string& to_charset)
-{
- if (from_charset == to_charset)
- return text;
-
- char *in = new char[text.length() + 1];
- strcpy(in, text.c_str());
- char *out = SDL_iconv_string(to_charset.c_str(), from_charset.c_str(), in, text.length() + 1);
- delete[] in;
- if(out == 0)
- {
- log_warning << "Error: conversion from " << from_charset << " to " << to_charset << " failed" << std::endl;
- return "";
- }
- std::string ret(out);
- SDL_free(out);
- return ret;
-#if 0
- iconv_t cd = SDL_iconv_open(to_charset.c_str(), from_charset.c_str());
-
- size_t in_len = text.length();
- size_t out_len = text.length()*3; // FIXME: cross fingers that this is enough
-
- char* out_orig = new char[out_len];
- char* in_orig = new char[in_len+1];
- strcpy(in_orig, text.c_str());
-
- char* out = out_orig;
- ICONV_CONST char* in = in_orig;
- size_t out_len_temp = out_len; // iconv is counting down the bytes it has
- // written from this...
-
- size_t retval = SDL_iconv(cd, &in, &in_len, &out, &out_len_temp);
- out_len -= out_len_temp; // see above
- if (retval == (size_t) -1)
- {
- log_warning << strerror(errno) << std::endl;
- log_warning << "Error: conversion from " << from_charset << " to " << to_charset << " went wrong: " << retval << std::endl;
- return "";
- }
- SDL_iconv_close(cd);
-
- std::string ret(out_orig, out_len);
- delete[] out_orig;
- delete[] in_orig;
- return ret;
-#endif
-}
-
-bool has_suffix(const std::string& lhs, const std::string rhs)
-{
- if (lhs.length() < rhs.length())
- return false;
- else
- return lhs.compare(lhs.length() - rhs.length(), rhs.length(), rhs) == 0;
-}
-
-bool has_prefix(const std::string& lhs, const std::string rhs)
-{
- if (lhs.length() < rhs.length())
- return false;
- else
- return lhs.compare(0, rhs.length(), rhs) == 0;
-}
-
-int plural1(int ) { return 0; }
-int plural2_1(int n) { return (n != 1); }
-int plural2_2(int n) { return (n > 1); }
-int plural3_lv(int n) { return (n%10==1 && n%100!=11 ? 0 : n != 0 ? 1 : 2); }
-int plural3_ga(int n) { return n==1 ? 0 : n==2 ? 1 : 2; }
-int plural3_lt(int n) { return (n%10==1 && n%100!=11 ? 0 : n%10>=2 && (n%100<10 || n%100>=20) ? 1 : 2); }
-int plural3_1(int n) { return (n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2); }
-int plural3_sk(int n) { return (n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2; }
-int plural3_pl(int n) { return (n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2); }
-int plural3_sl(int n) { return (n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n%100==4 ? 2 : 3); }
-
-/** Language Definitions */
-//*{
-LanguageDef lang_hu("hu", "Hungarian", 1, plural1); // "nplurals=1; plural=0;"
-LanguageDef lang_ja("ja", "Japanese", 1, plural1); // "nplurals=1; plural=0;"
-LanguageDef lang_ko("ko", "Korean", 1, plural1); // "nplurals=1; plural=0;"
-LanguageDef lang_tr("tr", "Turkish", 1, plural1); // "nplurals=1; plural=0;"
-LanguageDef lang_da("da", "Danish", 2, plural2_1); // "nplurals=2; plural=(n != 1);"
-LanguageDef lang_nl("nl", "Dutch", 2, plural2_1); // "nplurals=2; plural=(n != 1);"
-LanguageDef lang_en("en", "English", 2, plural2_1); // "nplurals=2; plural=(n != 1);"
-LanguageDef lang_fo("fo", "Faroese", 2, plural2_1); // "nplurals=2; plural=(n != 1);"
-LanguageDef lang_de("de", "German", 2, plural2_1); // "nplurals=2; plural=(n != 1);"
-LanguageDef lang_nb("nb", "Norwegian Bokmal", 2, plural2_1); // "nplurals=2; plural=(n != 1);"
-LanguageDef lang_no("no", "Norwegian", 2, plural2_1); // "nplurals=2; plural=(n != 1);"
-LanguageDef lang_nn("nn", "Norwegian Nynorsk", 2, plural2_1); // "nplurals=2; plural=(n != 1);"
-LanguageDef lang_sv("sv", "Swedish", 2, plural2_1); // "nplurals=2; plural=(n != 1);"
-LanguageDef lang_et("et", "Estonian", 2, plural2_1); // "nplurals=2; plural=(n != 1);"
-LanguageDef lang_fi("fi", "Finnish", 2, plural2_1); // "nplurals=2; plural=(n != 1);"
-LanguageDef lang_el("el", "Greek", 2, plural2_1); // "nplurals=2; plural=(n != 1);"
-LanguageDef lang_he("he", "Hebrew", 2, plural2_1); // "nplurals=2; plural=(n != 1);"
-LanguageDef lang_it("it", "Italian", 2, plural2_1); // "nplurals=2; plural=(n != 1);"
-LanguageDef lang_pt("pt", "Portuguese", 2, plural2_1); // "nplurals=2; plural=(n != 1);"
-LanguageDef lang_es("es", "Spanish", 2, plural2_1); // "nplurals=2; plural=(n != 1);"
-LanguageDef lang_eo("eo", "Esperanto", 2, plural2_1); // "nplurals=2; plural=(n != 1);"
-LanguageDef lang_fr("fr", "French", 2, plural2_2); // "nplurals=2; plural=(n > 1);"
-LanguageDef lang_pt_BR("pt_BR", "Brazilian", 2, plural2_2); // "nplurals=2; plural=(n > 1);"
-LanguageDef lang_lv("lv", "Latvian", 3, plural3_lv); // "nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n != 0 ? 1 : 2);"
-LanguageDef lang_ga("ga", "Irish", 3, plural3_ga); // "nplurals=3; plural=n==1 ? 0 : n==2 ? 1 : 2;"
-LanguageDef lang_lt("lt", "Lithuanian", 3, plural3_lt); // "nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && (n%100<10 || n%100>=20) ? 1 : 2);"
-LanguageDef lang_hr("hr", "Croatian", 3, plural3_1); // "nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);"
-LanguageDef lang_cs("cs", "Czech", 3, plural3_1); // "nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);"
-LanguageDef lang_ru("ru", "Russian", 3, plural3_1); // "nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);"
-LanguageDef lang_uk("uk", "Ukrainian", 3, plural3_1); // "nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);"
-LanguageDef lang_sk("sk", "Slovak", 3, plural3_sk); // "nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;"
-LanguageDef lang_pl("pl", "Polish", 3, plural3_pl); // "nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);
-LanguageDef lang_sl("sl", "Slovenian", 3, plural3_sl); // "nplurals=4; plural=(n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n%100==4 ? 2 : 3);"
-//*}
-
-LanguageDef&
-get_language_def(const std::string& name)
-{
- if (name == "hu") return lang_hu;
- else if (name == "ja") return lang_ja;
- else if (name == "ko") return lang_ko;
- else if (name == "tr") return lang_tr;
- else if (name == "da") return lang_da;
- else if (name == "nl") return lang_nl;
- else if (name == "en") return lang_en;
- else if (name == "fo") return lang_fo;
- else if (name == "de") return lang_de;
- else if (name == "nb") return lang_nb;
- else if (name == "no") return lang_no;
- else if (name == "nn") return lang_nn;
- else if (name == "sv") return lang_sv;
- else if (name == "et") return lang_et;
- else if (name == "fi") return lang_fi;
- else if (name == "el") return lang_el;
- else if (name == "he") return lang_he;
- else if (name == "it") return lang_it;
- else if (name == "pt") return lang_pt;
- else if (name == "es") return lang_es;
- else if (name == "eo") return lang_eo;
- else if (name == "fr") return lang_fr;
- else if (name == "pt_BR") return lang_pt_BR;
- else if (name == "lv") return lang_lv;
- else if (name == "ga") return lang_ga;
- else if (name == "lt") return lang_lt;
- else if (name == "hr") return lang_hr;
- else if (name == "cs") return lang_cs;
- else if (name == "ru") return lang_ru;
- else if (name == "uk") return lang_uk;
- else if (name == "sk") return lang_sk;
- else if (name == "pl") return lang_pl;
- else if (name == "sl") return lang_sl;
- else return lang_en;
-}
-
-DictionaryManager::DictionaryManager()
- : current_dict(&empty_dict)
-{
- parseLocaleAliases();
- // Environment variable SUPERTUX_LANG overrides language settings.
- const char* lang = getenv( "SUPERTUX_LANG" );
- if( lang ){
- set_language( lang );
- return;
- }
- // use findlocale to setup language
- FL_Locale *locale;
- FL_FindLocale( &locale, FL_MESSAGES );
- if(locale->lang) {
- if (locale->country) {
- set_language( std::string(locale->lang)+"_"+std::string(locale->country) );
- } else {
- set_language( std::string(locale->lang) );
- }
- }
- FL_FreeLocale( &locale );
-}
-
-void
-DictionaryManager::parseLocaleAliases()
-{
- // try to parse language alias list
- std::ifstream in("/usr/share/locale/locale.alias");
-
- char c = ' ';
- while(in.good() && !in.eof()) {
- while(isspace(c) && !in.eof())
- in.get(c);
-
- if(c == '#') { // skip comments
- while(c != '\n' && !in.eof())
- in.get(c);
- continue;
- }
-
- std::string alias;
- while(!isspace(c) && !in.eof()) {
- alias += c;
- in.get(c);
- }
- while(isspace(c) && !in.eof())
- in.get(c);
- std::string language;
- while(!isspace(c) && !in.eof()) {
- language += c;
- in.get(c);
- }
-
- if(in.eof())
- break;
- set_language_alias(alias, language);
- }
-}
-
-Dictionary&
-DictionaryManager::get_dictionary(const std::string& spec)
-{
-
- //log_debug << "Dictionary for language \"" << spec << "\" requested" << std::endl;
-
- std::string lang = get_language_from_spec(spec);
-
- //log_debug << "...normalized as \"" << lang << "\"" << std::endl;
-
- Dictionaries::iterator i = dictionaries.find(get_language_from_spec(lang));
- if (i != dictionaries.end())
- {
- return i->second;
- }
- else // Dictionary for languages lang isn't loaded, so we load it
- {
- //log_debug << "get_dictionary: " << lang << std::endl;
- Dictionary& dict = dictionaries[lang];
-
- dict.set_language(get_language_def(lang));
- if(charset != "")
- dict.set_charset(charset);
-
- for (SearchPath::iterator p = search_path.begin(); p != search_path.end(); ++p)
- {
- std::vector<std::string> files = Unison::VFS::FileSystem::get().ls(*p);
- for(std::vector<std::string>::iterator iter = files.begin();iter != files.end();++iter)
- {
- // check if filename matches requested language
- std::string fname = *iter;
- std::string load_from_file = "";
- if(fname == lang + ".po") {
- load_from_file = fname;
- } else {
- std::string::size_type s = lang.find("_");
- if(s != std::string::npos) {
- std::string lang_short = std::string(lang, 0, s);
- if (fname == lang_short + ".po") {
- load_from_file = lang_short;
- }
- }
- }
-
- // if it matched, load dictionary
- if (load_from_file != "") {
- //log_debug << "Loading dictionary for language \"" << lang << "\" from \"" << filename << "\"" << std::endl;
- std::string pofile = *p + "/" + *iter;
- try {
- IFileStream in(pofile);
- read_po_file(dict, in);
- } catch(std::exception& e) {
- log_warning << "Error: Failure file opening: " << pofile << std::endl;
- log_warning << e.what() << "" << std::endl;
- }
- }
- }
-
-#if 0
- char** files = PHYSFS_enumerateFiles(p->c_str());
- if(!files)
- {
- log_warning << "Error: enumerateFiles() failed on " << *p << std::endl;
- }
- else
- {
- for(const char* const* filename = files;
- *filename != 0; filename++) {
-
- // check if filename matches requested language
- std::string fname = std::string(*filename);
- std::string load_from_file = "";
- if(fname == lang + ".po") {
- load_from_file = fname;
- } else {
- std::string::size_type s = lang.find("_");
- if(s != std::string::npos) {
- std::string lang_short = std::string(lang, 0, s);
- if (fname == lang_short + ".po") {
- load_from_file = lang_short;
- }
- }
- }
-
- // if it matched, load dictionary
- if (load_from_file != "") {
- //log_debug << "Loading dictionary for language \"" << lang << "\" from \"" << filename << "\"" << std::endl;
- std::string pofile = *p + "/" + *filename;
- try {
- IFileStream in(pofile);
- read_po_file(dict, in);
- } catch(std::exception& e) {
- log_warning << "Error: Failure file opening: " << pofile << std::endl;
- log_warning << e.what() << "" << std::endl;
- }
- }
-
- }
- PHYSFS_freeList(files);
- }
-#endif
- }
-
- return dict;
- }
-}
-
-std::set<std::string>
-DictionaryManager::get_languages()
-{
- std::set<std::string> languages;
-
- for (SearchPath::iterator p = search_path.begin(); p != search_path.end(); ++p)
- {
- std::vector<std::string> files = Unison::VFS::FileSystem::get().ls(*p);
- for(std::vector<std::string>::iterator iter = files.begin();iter != files.end();++iter)
- {
- if(has_suffix(*iter, ".po")) {
- std::string filename = *iter;
- languages.insert(filename.substr(0, filename.length()-3));
- }
- }
-#if 0
- char** files = PHYSFS_enumerateFiles(p->c_str());
- if (!files)
- {
- log_warning << "Error: opendir() failed on " << *p << std::endl;
- }
- else
- {
- for(const char* const* file = files; *file != 0; file++) {
- if(has_suffix(*file, ".po")) {
- std::string filename = *file;
- languages.insert(filename.substr(0, filename.length()-3));
- }
- }
- PHYSFS_freeList(files);
- }
-#endif
- }
- return languages;
-}
-
-void
-DictionaryManager::set_language(const std::string& lang)
-{
- //log_debug << "set_language \"" << lang << "\"" << std::endl;
- language = get_language_from_spec(lang);
- //log_debug << "==> \"" << language << "\"" << std::endl;
- current_dict = & (get_dictionary(language));
-}
-
-const std::string&
-DictionaryManager::get_language() const
-{
- return language;
-}
-
-void
-DictionaryManager::set_charset(const std::string& charset)
-{
- dictionaries.clear(); // changing charset invalidates cache
- this->charset = charset;
- set_language(language);
-}
-
-void
-DictionaryManager::set_language_alias(const std::string& alias,
- const std::string& language)
-{
- language_aliases.insert(std::make_pair(alias, language));
-}
-
-std::string
-DictionaryManager::get_language_from_spec(const std::string& spec)
-{
- std::string lang = spec;
- Aliases::iterator i = language_aliases.find(lang);
- if(i != language_aliases.end()) {
- lang = i->second;
- }
-
- std::string::size_type s = lang.find(".");
- if(s != std::string::npos) {
- lang = std::string(lang, 0, s);
- }
-
- s = lang.find("_");
- if(s == std::string::npos) {
- std::string lang_big = lang;
- std::transform (lang_big.begin(), lang_big.end(), lang_big.begin(), toupper);
- lang += "_" + lang_big;
- }
-
- return lang;
-
-}
-
-void
-DictionaryManager::add_directory(const std::string& pathname)
-{
- dictionaries.clear(); // adding directories invalidates cache
- search_path.push_back(pathname);
- set_language(language);
-}
-
-//---------------------------------------------------------------------------
-
-Dictionary::Dictionary(const LanguageDef& language_, const std::string& charset_)
- : language(language_), charset(charset_)
-{
-}
-
-Dictionary::Dictionary()
- : language(lang_en)
-{
-}
-
-std::string
-Dictionary::get_charset() const
-{
- return charset;
-}
-
-void
-Dictionary::set_charset(const std::string& charset_)
-{
- charset = charset_;
-}
-
-void
-Dictionary::set_language(const LanguageDef& lang)
-{
- language = lang;
-}
-
-std::string
-Dictionary::translate(const std::string& msgid, const std::string& msgid2, int num)
-{
- PluralEntries::iterator i = plural_entries.find(msgid);
- std::map<int, std::string>& msgstrs = i->second;
-
- if (i != plural_entries.end() && !msgstrs.empty())
- {
- int g = language.plural(num);
- std::map<int, std::string>::iterator j = msgstrs.find(g);
- if (j != msgstrs.end())
- {
- return j->second;
- }
- else
- {
- // Return the first translation, in case we can't translate the specific number
- return msgstrs.begin()->second;
- }
- }
- else
- {
-#ifdef TRANSLATION_DEBUG
- log_warning << "Couldn't translate: " << msgid << std::endl;
- log_warning << "Candidates: " << std::endl;
- for (PluralEntries::iterator i = plural_entries.begin(); i != plural_entries.end(); ++i)
- log_debug << "'" << i->first << "'" << std::endl;
-#endif
-
- if (plural2_1(num)) // default to english rules
- return msgid2;
- else
- return msgid;
- }
-}
-
-const char*
-Dictionary::translate(const char* msgid)
-{
- Entries::iterator i = entries.find(msgid);
- if (i != entries.end() && !i->second.empty())
- {
- return i->second.c_str();
- }
- else
- {
-#ifdef TRANSLATION_DBEUG
- log_warning << "Couldn't translate: " << msgid << std::endl;
-#endif
- return msgid;
- }
-}
-
-std::string
-Dictionary::translate(const std::string& msgid)
-{
- Entries::iterator i = entries.find(msgid);
- if (i != entries.end() && !i->second.empty())
- {
- return i->second;
- }
- else
- {
-#ifdef TRANSLATION_DBEUG
- log_warning << "Couldn't translate: " << msgid << std::endl;
-#endif
- return msgid;
- }
-}
-
-void
-Dictionary::add_translation(const std::string& msgid, const std::string& ,
- const std::map<int, std::string>& msgstrs)
-{
- // Do we need msgid2 for anything? its after all supplied to the
- // translate call, so we just throw it away
- plural_entries[msgid] = msgstrs;
-}
-
-void
-Dictionary::add_translation(const std::string& msgid, const std::string& msgstr)
-{
- entries[msgid] = msgstr;
-}
-
-class POFileReader
-{
-private:
- struct Token
- {
- std::string keyword;
- std::string content;
- };
-
- Dictionary& dict;
-
- std::string from_charset;
- std::string to_charset;
-
- std::string current_msgid;
- std::string current_msgid_plural;
- std::map<int, std::string> msgstr_plural;
-
- int line_num;
-
- enum { WANT_MSGID, WANT_MSGSTR, WANT_MSGSTR_PLURAL, WANT_MSGID_PLURAL } state;
-
-public:
- POFileReader(std::istream& in, Dictionary& dict_)
- : dict(dict_)
- {
- state = WANT_MSGID;
- line_num = 0;
- char c = in.get();
- if(c == (char) 0xef) { // skip UTF-8 intro that some texteditors produce
- in.get();
- in.get();
- } else {
- in.unget();
- }
- tokenize_po(in);
- }
-
- void parse_header(const std::string& header)
- {
- // Seperate the header in lines
- typedef std::vector<std::string> Lines;
- Lines lines;
-
- std::string::size_type start = 0;
- for(std::string::size_type i = 0; i < header.length(); ++i)
- {
- if (header[i] == '\n')
- {
- lines.push_back(header.substr(start, i - start));
- start = i+1;
- }
- }
-
- for(Lines::iterator i = lines.begin(); i != lines.end(); ++i)
- {
- if (has_prefix(*i, "Content-Type: text/plain; charset=")) {
- from_charset = i->substr(strlen("Content-Type: text/plain; charset="));
- }
- }
-
- if (from_charset.empty() || from_charset == "CHARSET")
- {
- log_warning << "Error: Charset not specified for .po, fallback to ISO-8859-1" << std::endl;
- from_charset = "ISO-8859-1";
- }
-
- to_charset = dict.get_charset();
- if (to_charset.empty())
- { // No charset requested from the dict, use utf-8
- to_charset = "utf-8";
- dict.set_charset(from_charset);
- }
- }
-
- void add_token(const Token& token)
- {
- switch(state)
- {
- case WANT_MSGID:
- if (token.keyword == "msgid")
- {
- current_msgid = token.content;
- state = WANT_MSGID_PLURAL;
- }
- else if (token.keyword.empty())
- {
- //log_warning << "Got EOF, everything looks ok." << std::endl;
- }
- else
- {
- log_warning << "tinygettext: expected 'msgid' keyword, got " << token.keyword << " at line " << line_num << std::endl;
- }
- break;
-
- case WANT_MSGID_PLURAL:
- if (token.keyword == "msgid_plural")
- {
- current_msgid_plural = token.content;
- state = WANT_MSGSTR_PLURAL;
- }
- else
- {
- state = WANT_MSGSTR;
- add_token(token);
- }
- break;
-
- case WANT_MSGSTR:
- if (token.keyword == "msgstr")
- {
- if (current_msgid == "")
- { // .po Header is hidden in the msgid with the empty string
- parse_header(token.content);
- }
- else
- {
- dict.add_translation(current_msgid, convert(token.content, from_charset, to_charset));
- }
- state = WANT_MSGID;
- }
- else
- {
- log_warning << "tinygettext: expected 'msgstr' keyword, got " << token.keyword << " at line " << line_num << std::endl;
- }
- break;
-
- case WANT_MSGSTR_PLURAL:
- if (has_prefix(token.keyword, "msgstr["))
- {
- int num;
- if (sscanf(token.keyword.c_str(), "msgstr[%d]", &num) != 1)
- {
- log_warning << "Error: Couldn't parse: " << token.keyword << std::endl;
- }
- else
- {
- msgstr_plural[num] = convert(token.content, from_charset, to_charset);
- }
- }
- else
- {
- dict.add_translation(current_msgid, current_msgid_plural, msgstr_plural);
-
- state = WANT_MSGID;
- add_token(token);
- }
- break;
- }
- }
-
- inline int getchar(std::istream& in)
- {
- int c = in.get();
- if (c == '\n')
- line_num += 1;
- return c;
- }
-
- void tokenize_po(std::istream& in)
- {
- enum State { READ_KEYWORD,
- READ_CONTENT,
- READ_CONTENT_IN_STRING,
- SKIP_COMMENT };
-
- State state = READ_KEYWORD;
- int c;
- Token token;
-
- while((c = getchar(in)) != EOF)
- {
- //log_debug << "Lexing char: " << char(c) << " " << state << std::endl;
- switch(state)
- {
- case READ_KEYWORD:
- if (c == '#')
- {
- state = SKIP_COMMENT;
- }
- else
- {
- // Read a new token
- token = Token();
-
- do { // Read keyword
- token.keyword += c;
- } while((c = getchar(in)) != EOF && !isspace(c));
- in.unget();
-
- state = READ_CONTENT;
- }
- break;
-
- case READ_CONTENT:
- while((c = getchar(in)) != EOF)
- {
- if (c == '"') {
- // Found start of content
- state = READ_CONTENT_IN_STRING;
- break;
- } else if (isspace(c)) {
- // skip
- } else { // Read something that may be a keyword
- in.unget();
- state = READ_KEYWORD;
- add_token(token);
- break;
- }
- }
- break;
-
- case READ_CONTENT_IN_STRING:
- if (c == '\\') {
- c = getchar(in);
- if (c != EOF)
- {
- if (c == 'n') token.content += '\n';
- else if (c == 't') token.content += '\t';
- else if (c == 'r') token.content += '\r';
- else if (c == '"') token.content += '"';
- else if (c == '\\') token.content += '\\';
- else
- {
- log_warning << "Unhandled escape character: " << char(c) << std::endl;
- }
- }
- else
- {
- log_warning << "Unterminated string" << std::endl;
- }
- } else if (c == '"') { // Content string is terminated
- state = READ_CONTENT;
- } else {
- token.content += c;
- }
- break;
-
- case SKIP_COMMENT:
- if (c == '\n')
- state = READ_KEYWORD;
- break;
- }
- }
- add_token(token);
- }
-};
-
-void read_po_file(Dictionary& dict_, std::istream& in)
-{
- POFileReader reader(in, dict_);
-}
-
-} // namespace TinyGetText
-
-/* EOF */
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef HEADER_TINYGETTEXT_H
-#define HEADER_TINYGETTEXT_H
-
-#include <map>
-#include <vector>
-#include <set>
-#include <string>
-
-namespace TinyGetText {
-
-typedef int (*PluralFunc)(int n);
-
-struct LanguageDef {
- const char* code;
- const char* name;
- int nplural;
- PluralFunc plural;
-
- LanguageDef(const char* code_, const char* name_, int nplural_, PluralFunc plural_)
- : code(code_), name(name_), nplural(nplural_), plural(plural_)
- {}
-};
-
-/** A simple dictionary class that mimics gettext() behaviour. Each
- Dictionary only works for a single language, for managing multiple
- languages and .po files at once use the DictionaryManager. */
-class Dictionary
-{
-private:
- typedef std::map<std::string, std::string> Entries;
- Entries entries;
-
- typedef std::map<std::string, std::map<int, std::string> > PluralEntries;
- PluralEntries plural_entries;
-
- LanguageDef language;
- std::string charset;
-public:
- /** */
- Dictionary(const LanguageDef& language_, const std::string& charset = "");
-
- Dictionary();
-
- /** Return the charset used for this dictionary */
- std::string get_charset() const;
-
- /** Set a charset for this dictionary, this will NOT convert stuff,
- it is for information only, you have to convert stuff yourself
- when you add it with \a add_translation() */
- void set_charset(const std::string& charset);
-
- /** Set the language that is used for this dictionary, this is
- mainly needed to evaluate plural forms */
- void set_language(const LanguageDef& lang);
-
- /** Translate the string \a msgid to its correct plural form, based
- on the number of items given by \a num. \a msgid2 is \a msgid in
- plural form. */
- std::string translate(const std::string& msgid, const std::string& msgid2, int num);
-
- /** Translate the string \a msgid. */
- std::string translate(const std::string& msgid);
- /** Translate the string \a msgid. */
- const char* translate(const char* msgid);
-
- /** Add a translation from \a msgid to \a msgstr to the dictionary,
- where \a msgid is the singular form of the message, msgid2 the
- plural form and msgstrs a table of translations. The right
- translation will be calculated based on the \a num argument to
- translate(). */
- void add_translation(const std::string& msgid, const std::string& msgid2,
- const std::map<int, std::string>& msgstrs);
-
- /** Add a translation from \a msgid to \a msgstr to the
- dictionary */
- void add_translation(const std::string& msgid, const std::string& msgstr);
-};
-
-/** Manager class for dictionaries, you give it a bunch of directories
- with .po files and it will then automatically load the right file
- on demand depending on which language was set. */
-class DictionaryManager
-{
-private:
- typedef std::map<std::string, Dictionary> Dictionaries;
- Dictionaries dictionaries;
- typedef std::vector<std::string> SearchPath;
- SearchPath search_path;
- typedef std::map<std::string, std::string> Aliases;
- Aliases language_aliases;
- std::string charset;
- std::string language;
- Dictionary* current_dict;
- Dictionary empty_dict;
-
-public:
- DictionaryManager();
-
- /** Return the currently active dictionary, if none is set, an empty
- dictionary is returned. */
- Dictionary& get_dictionary()
- { return *current_dict; }
-
- /** Get dictionary for lang */
- Dictionary& get_dictionary(const std::string& langspec);
-
- /** Set a language based on a four? letter country code */
- void set_language(const std::string& langspec);
-
- /** returns the (normalized) country code of the currently used language */
- const std::string& get_language() const;
-
- /** Set a charset that will be set on the returned dictionaries */
- void set_charset(const std::string& charset);
-
- /** Define an alias for a language */
- void set_language_alias(const std::string& alias, const std::string& lang);
-
- /** Add a directory to the search path for dictionaries */
- void add_directory(const std::string& pathname);
-
- /** Return a set of the available languages in their country code */
- std::set<std::string> get_languages();
-
-private:
- void parseLocaleAliases();
- /// returns the language part in a language spec (like de_DE.UTF-8 -> de)
- std::string get_language_from_spec(const std::string& spec);
-};
-
-/** Read the content of the .po file given as \a in into the
- dictionary given as \a dict */
-void read_po_file(Dictionary& dict, std::istream& in);
-LanguageDef& get_language_def(const std::string& name);
-
-} // namespace TinyGetText
-
-#endif
-
-/* EOF */
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2004 Tobias Glaesser <tobi.web@gmx.de>
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#include <config.h>
-
-#include <iostream>
-#include <sstream>
-#include <stdexcept>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <math.h>
-#include <errno.h>
-#include <unistd.h>
-#include <SDL.h>
-//#include <SDL_image.h>
-//#include <physfs.h>
-#include <unison/vfs/FileSystem.hpp>
-
-#include "title.hpp"
-#include "mainloop.hpp"
-#include "video/drawing_context.hpp"
-#include "video/surface.hpp"
-#include "audio/sound_manager.hpp"
-#include "gui/menu.hpp"
-#include "timer.hpp"
-#include "lisp/lisp.hpp"
-#include "lisp/parser.hpp"
-#include "level.hpp"
-#include "world.hpp"
-#include "game_session.hpp"
-#include "worldmap/worldmap.hpp"
-#include "player_status.hpp"
-#include "tile.hpp"
-#include "sector.hpp"
-#include "object/tilemap.hpp"
-#include "object/camera.hpp"
-#include "object/player.hpp"
-#include "resources.hpp"
-#include "gettext.hpp"
-#include "textscroller.hpp"
-#include "fadeout.hpp"
-#include "file_system.hpp"
-#include "control/joystickkeyboardcontroller.hpp"
-#include "control/codecontroller.hpp"
-#include "main.hpp"
-#include "log.hpp"
-#include "options_menu.hpp"
-#include "console.hpp"
-#include "random_generator.hpp"
-#include "addon_manager.hpp"
-
-enum MainMenuIDs {
- MNID_STARTGAME,
- MNID_LEVELS_CONTRIB,
- MNID_ADDONS,
- MNID_OPTIONMENU,
- MNID_LEVELEDITOR,
- MNID_CREDITS,
- MNID_QUITMAINMENU
-};
-
-void
-TitleScreen::update_load_game_menu()
-{
- load_game_menu.reset(new Menu());
-
- load_game_menu->add_label(_("Start Game"));
- load_game_menu->add_hl();
- for(int i = 1; i <= 5; ++i) {
- load_game_menu->add_entry(i, get_slotinfo(i));
- }
- load_game_menu->add_hl();
- load_game_menu->add_back(_("Back"));
-}
-
-void
-TitleScreen::free_contrib_menu()
-{
- for(std::vector<World*>::iterator i = contrib_worlds.begin();
- i != contrib_worlds.end(); ++i)
- delete *i;
-
- contrib_worlds.clear();
-}
-
-void
-TitleScreen::generate_contrib_menu()
-{
- /** Generating contrib levels list by making use of Level Subset */
- std::vector<std::string> level_worlds;
- std::vector<std::string> files = Unison::VFS::FileSystem::get().ls("levels/");
- for(std::vector<std::string>::iterator iter = files.begin();iter != files.end();++iter)
- {
- std::string filepath = "levels/" + *iter;
- if(Unison::VFS::FileSystem::get().is_dir(filepath))
- level_worlds.push_back(filepath);
- }
- /*char** files = PHYSFS_enumerateFiles("levels/");
- for(const char* const* filename = files; *filename != 0; ++filename) {
- std::string filepath = std::string("levels/") + *filename;
- if(PHYSFS_isDirectory(filepath.c_str()))
- level_worlds.push_back(filepath);
- }
- PHYSFS_freeList(files);*/
-
- free_contrib_menu();
- contrib_menu.reset(new Menu());
-
- contrib_menu->add_label(_("Contrib Levels"));
- contrib_menu->add_hl();
-
- int i = 0;
- for (std::vector<std::string>::iterator it = level_worlds.begin();
- it != level_worlds.end(); ++it) {
- try {
- std::auto_ptr<World> world (new World());
- world->load(*it + "/info");
- if(world->hide_from_contribs) {
- continue;
- }
- contrib_menu->add_entry(i++, world->title);
- contrib_worlds.push_back(world.release());
- } catch(std::exception& e) {
-#ifdef DEBUG
- log_warning << "Couldn't parse levelset info for '" << *it << "': " << e.what() << std::endl;
-#endif
- }
- }
-
- contrib_menu->add_hl();
- contrib_menu->add_back(_("Back"));
-}
-
-std::string
-TitleScreen::get_level_name(const std::string& filename)
-{
- try {
- lisp::Parser parser;
- const lisp::Lisp* root = parser.parse(filename);
-
- const lisp::Lisp* level = root->get_lisp("supertux-level");
- if(!level)
- return "";
-
- std::string name;
- level->get("name", name);
- return name;
- } catch(std::exception& e) {
- log_warning << "Problem getting name of '" << filename << "': "
- << e.what() << std::endl;
- return "";
- }
-}
-
-void
-TitleScreen::check_levels_contrib_menu()
-{
- int index = contrib_menu->check();
- if (index == -1)
- return;
-
- current_world = contrib_worlds[index];
-
- if(!current_world->is_levelset) {
- update_load_game_menu();
- Menu::push_current(load_game_menu.get());
- } else {
- contrib_world_menu.reset(new Menu());
-
- contrib_world_menu->add_label(current_world->title);
- contrib_world_menu->add_hl();
-
- for (unsigned int i = 0; i < current_world->get_num_levels(); ++i)
- {
- /** get level's title */
- std::string filename = current_world->get_level_filename(i);
- std::string title = get_level_name(filename);
- contrib_world_menu->add_entry(i, title);
- }
-
- contrib_world_menu->add_hl();
- contrib_world_menu->add_back(_("Back"));
-
- Menu::push_current(contrib_world_menu.get());
- }
-}
-
-void
-TitleScreen::check_contrib_world_menu()
-{
- int index = contrib_world_menu->check();
- if (index != -1) {
- if (contrib_world_menu->get_item_by_id(index).kind == MN_ACTION) {
- sound_manager->stop_music();
- GameSession* session =
- new GameSession(current_world->get_level_filename(index));
- main_loop->push_screen(session);
- }
- }
-}
-
-namespace {
- bool generate_addons_menu_sorter(const Addon& a1, const Addon& a2)
- {
- return a1.title < a2.title;
- }
-
- const int ADDON_LIST_START_ID = 10;
-}
-
-void
-TitleScreen::generate_addons_menu()
-{
- AddonManager& adm = AddonManager::get_instance();
-
- // refresh list of installed addons
- installed_addons = adm.get_installed_addons();
-
- // build new Add-on list
- addons.clear();
-
- // add installed addons to list
- addons.insert(addons.end(), installed_addons.begin(), installed_addons.end());
-
- // add available addons to list
- addons.insert(addons.end(), available_addons.begin(), available_addons.end());
-
- // sort list
- std::sort(addons.begin(), addons.end(), generate_addons_menu_sorter);
-
- // remove available addons that are already installed
- std::vector<Addon>::iterator it2 = addons.begin();
- while (it2 != addons.end()) {
- Addon addon = *it2;
- if (addon.isInstalled) {
- bool restart = false;
- for (std::vector<Addon>::iterator it = addons.begin(); it != addons.end(); ++it) {
- Addon addon2 = *it;
- if ((addon2.equals(addon)) && (!addon2.isInstalled)) {
- addons.erase(it);
- restart = true;
- break;
- }
- }
- if (restart) {
- it2 = addons.begin();
- continue;
- }
- }
- it2++;
- }
-
- // (re)generate menu
- free_addons_menu();
- addons_menu.reset(new Menu());
-
- addons_menu->add_label(_("Add-ons"));
- addons_menu->add_hl();
-
-#ifdef HAVE_LIBCURL
- addons_menu->add_entry(0, std::string(_("Check Online")));
-#else
- addons_menu->add_deactive(0, std::string(_("Check Online (disabled)")));
-#endif
-
- //addons_menu->add_hl();
-
- for (unsigned int i = 0; i < addons.size(); i++) {
- Addon addon = addons[i];
- std::string text = "";
- if (addon.kind != "") text += addon.kind + " ";
- text += std::string("\"") + addon.title + "\"";
- if (addon.author != "") text += " by \"" + addon.author + "\"";
- addons_menu->add_toggle(ADDON_LIST_START_ID + i, text, addon.isInstalled);
- }
-
- addons_menu->add_hl();
- addons_menu->add_back(_("Back"));
-}
-
-void
-TitleScreen::check_addons_menu()
-{
- int index = addons_menu->check();
- if (index == -1) return;
-
- // check if "Check Online" was chosen
- if (index == 0) {
- try {
- available_addons = AddonManager::get_instance().get_available_addons();
- generate_addons_menu();
- Menu::set_current(addons_menu.get());
- addons_menu->set_active_item(index);
- }
- catch (std::runtime_error e) {
- log_warning << "Check for available Add-ons failed: " << e.what() << std::endl;
- }
- return;
- }
-
- // if one of the Addons listed was chosen, take appropriate action
- if ((index >= ADDON_LIST_START_ID) && (index < ADDON_LIST_START_ID) + addons.size()) {
- Addon addon = addons[index - ADDON_LIST_START_ID];
- if (!addon.isInstalled) {
- try {
- addon.install();
- //generate_addons_menu();
- //Menu::set_current(addons_menu.get());
- //addons_menu->set_active_item(index);
- Menu::set_current(0);
- }
- catch (std::runtime_error e) {
- log_warning << "Installation of Add-on failed: " << e.what() << std::endl;
- }
- } else {
- try {
- addon.remove();
- //generate_addons_menu();
- //Menu::set_current(addons_menu.get());
- //addons_menu->set_active_item(index);
- Menu::set_current(0);
- }
- catch (std::runtime_error e) {
- log_warning << "Removal of Add-on failed: " << e.what() << std::endl;
- }
- }
- }
-
-}
-
-void
-TitleScreen::free_addons_menu()
-{
-}
-
-void
-TitleScreen::make_tux_jump()
-{
- static bool jumpWasReleased = true;
- Sector* sector = titlesession->get_current_sector();
- Player* tux = sector->player;
-
- controller->update();
- controller->press(Controller::RIGHT);
-
- // Check if we should press the jump button
- Rect lookahead = tux->get_bbox();
- lookahead.p2.x += 96;
- bool pathBlocked = !sector->is_free_of_statics(lookahead);
- if ((pathBlocked && jumpWasReleased) || !tux->on_ground()) {
- controller->press(Controller::JUMP);
- jumpWasReleased = false;
- } else {
- jumpWasReleased = true;
- }
-
- // Wrap around at the end of the level back to the beginnig
- if(sector->get_width() - 320 < tux->get_pos().x) {
- sector->activate("main");
- sector->camera->reset(tux->get_pos());
- }
-}
-
-TitleScreen::TitleScreen()
-{
- controller.reset(new CodeController());
- titlesession.reset(new GameSession("levels/misc/menu.stl"));
-
- Player* player = titlesession->get_current_sector()->player;
- player->set_controller(controller.get());
- player->set_speedlimit(230); //MAX_WALK_XM
-
- generate_main_menu();
-}
-
-void
-TitleScreen::generate_main_menu()
-{
- main_menu.reset(new Menu());
- main_menu->set_pos(SCREEN_WIDTH/2, SCREEN_HEIGHT/2 + 35);
- main_menu->add_entry(MNID_STARTGAME, _("Start Game"));
- main_menu->add_entry(MNID_LEVELS_CONTRIB, _("Contrib Levels"));
- main_menu->add_entry(MNID_ADDONS, _("Add-ons"));
- main_menu->add_submenu(_("Options"), get_options_menu());
- main_menu->add_entry(MNID_CREDITS, _("Credits"));
- main_menu->add_entry(MNID_QUITMAINMENU, _("Quit"));
-}
-
-TitleScreen::~TitleScreen()
-{
-}
-
-void
-TitleScreen::setup()
-{
- player_status->reset();
-
- Sector* sector = titlesession->get_current_sector();
- if(Sector::current() != sector) {
- sector->play_music(LEVEL_MUSIC);
- sector->activate(sector->player->get_pos());
- }
-
- Menu::set_current(main_menu.get());
-}
-
-void
-TitleScreen::leave()
-{
- Sector* sector = titlesession->get_current_sector();
- sector->deactivate();
- Menu::set_current(NULL);
-}
-
-void
-TitleScreen::draw(DrawingContext& context)
-{
- Sector* sector = titlesession->get_current_sector();
- sector->draw(context);
-
- context.draw_text(white_small_text, "SuperTux " PACKAGE_VERSION "\n",
- Vector(5, SCREEN_HEIGHT - 50), ALIGN_LEFT, LAYER_FOREGROUND1);
- context.draw_text(white_small_text,
- _(
-"Copyright (c) 2007 SuperTux Devel Team\n"
-"This game comes with ABSOLUTELY NO WARRANTY. This is free software, and you are welcome to\n"
-"redistribute it under certain conditions; see the file COPYING for details.\n"
-),
- Vector(5, SCREEN_HEIGHT - 50 + white_small_text->get_height() + 5),
- ALIGN_LEFT, LAYER_FOREGROUND1);
-}
-
-void
-TitleScreen::update(float elapsed_time)
-{
- main_loop->set_speed(0.6f);
- Sector* sector = titlesession->get_current_sector();
- sector->update(elapsed_time);
-
- make_tux_jump();
-
- Menu* menu = Menu::current();
- if(menu) {
- menu->update();
-
- if(menu == main_menu.get()) {
- switch (main_menu->check()) {
- case MNID_STARTGAME:
- // Start Game, ie. goto the slots menu
- if(main_world.get() == NULL) {
- main_world.reset(new World());
- main_world->load("levels/world1/info");
- }
- current_world = main_world.get();
- update_load_game_menu();
- Menu::push_current(load_game_menu.get());
- break;
- case MNID_LEVELS_CONTRIB:
- // Contrib Menu
- generate_contrib_menu();
- Menu::push_current(contrib_menu.get());
- break;
- case MNID_ADDONS:
- // Add-ons Menu
- generate_addons_menu();
- Menu::push_current(addons_menu.get());
- break;
- case MNID_CREDITS:
- main_loop->push_screen(new TextScroller("credits.txt"),
- new FadeOut(0.5));
- break;
- case MNID_QUITMAINMENU:
- main_loop->quit(new FadeOut(0.25));
- sound_manager->stop_music(0.25);
- break;
- }
- } else if(menu == load_game_menu.get()) {
- /*
- if(event.key.keysym.sym == SDLK_DELETE) {
- int slot = menu->get_active_item_id();
- std::stringstream stream;
- stream << slot;
- std::string str = _("Are you sure you want to delete slot") + stream.str() + "?";
-
- if(confirm_dialog(bkg_title, str.c_str())) {
- str = "save/slot" + stream.str() + ".stsg";
- log_debug << "Removing: " << str << std::endl;
- PHYSFS_delete(str.c_str());
- }
-
- update_load_save_game_menu(load_game_menu);
- Menu::set_current(main_menu.get());
- }*/
- process_load_game_menu();
- } else if(menu == contrib_menu.get()) {
- check_levels_contrib_menu();
- } else if(menu == addons_menu.get()) {
- check_addons_menu();
- } else if (menu == contrib_world_menu.get()) {
- check_contrib_world_menu();
- }
- }
-
- // reopen menu of user closed it (so that the app doesn't close when user
- // accidently hit ESC)
- if(Menu::current() == 0) {
- generate_main_menu();
- Menu::set_current(main_menu.get());
- }
-}
-
-std::string
-TitleScreen::get_slotinfo(int slot)
-{
- std::string tmp;
- std::string title;
-
- std::string basename = current_world->get_basedir();
- basename = basename.substr(0, basename.length()-1);
- std::string worlddirname = FileSystem::basename(basename);
- std::ostringstream stream;
- stream << "save/" << worlddirname << "_" << slot << ".stsg";
- std::string slotfile = stream.str();
-
- if(Unison::VFS::FileSystem::get().exists(slotfile))
- {
- lisp::Parser parser;
- const lisp::Lisp* root = parser.parse(slotfile);
-
- const lisp::Lisp* savegame = root->get_lisp("supertux-savegame");
- if(!savegame)
- throw std::runtime_error("file is not a supertux-savegame.");
-
- savegame->get("title", title);
- }
- else
- {
- std::ostringstream slottitle;
- slottitle << _("Slot") << " " << slot << " - " << _("Free");
- return slottitle.str();
- }
-
- std::ostringstream slottitle;
- slottitle << _("Slot") << " " << slot << " - " << title;
- return slottitle.str();
-}
-
-bool
-TitleScreen::process_load_game_menu()
-{
- int slot = load_game_menu->check();
-
- if(slot == -1)
- return false;
-
- if(load_game_menu->get_item_by_id(slot).kind != MN_ACTION)
- return false;
-
- std::string basename = current_world->get_basedir();
- basename = basename.substr(0, basename.length()-1);
- std::string worlddirname = FileSystem::basename(basename);
- std::stringstream stream;
- stream << "save/" << worlddirname << "_" << slot << ".stsg";
- std::string slotfile = stream.str();
-
- try {
- current_world->set_savegame_filename(slotfile);
- current_world->run();
- } catch(std::exception& e) {
- log_fatal << "Couldn't start world: " << e.what() << std::endl;
- }
-
- return true;
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2004 Tobias Glaesser <tobi.web@gmx.de>
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#ifndef SUPERTUX_TITLE_H
-#define SUPERTUX_TITLE_H
-
-#include <memory>
-#include <vector>
-#include "screen.hpp"
-#include "game_session.hpp"
-#include "addon.hpp"
-
-class Menu;
-class World;
-class CodeController;
-
-class TitleScreen : public Screen
-{
-public:
- TitleScreen();
- virtual ~TitleScreen();
-
- virtual void setup();
- virtual void leave();
-
- virtual void draw(DrawingContext& context);
-
- virtual void update(float elapsed_time);
-
-private:
- std::string get_slotinfo(int slot);
- std::string get_level_name(const std::string& levelfile);
- bool process_load_game_menu();
- void make_tux_jump();
- void update_load_game_menu();
- void generate_main_menu();
- void generate_contrib_menu();
- void check_levels_contrib_menu();
- void check_contrib_world_menu();
- void free_contrib_menu();
- void generate_addons_menu();
- void check_addons_menu();
- void free_addons_menu();
-
- std::auto_ptr<Menu> main_menu;
- std::auto_ptr<Menu> load_game_menu;
- std::auto_ptr<Menu> contrib_menu;
- std::auto_ptr<Menu> contrib_world_menu;
- std::auto_ptr<World> main_world;
- std::vector<World*> contrib_worlds;
- std::auto_ptr<Menu> addons_menu;
- std::vector<Addon> addons; /**< shown list of Add-ons */
- std::vector<Addon> available_addons; /**< list of downloadable Add-ons */
- std::vector<Addon> installed_addons; /**< list of currently installed Add-ons */
- World* current_world;
-
- std::auto_ptr<CodeController> controller;
- std::auto_ptr<GameSession> titlesession;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux - Climbable area
-// Copyright (C) 2007 Christoph Sommer <christoph.sommer@2007.expires.deltadevelopment.de>
-//
-// 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.
-
-#include <config.h>
-
-#include "climbable.hpp"
-#include "game_session.hpp"
-#include "lisp/lisp.hpp"
-#include "lisp/writer.hpp"
-#include "object_factory.hpp"
-#include "main.hpp"
-#include "sector.hpp"
-#include "level.hpp"
-#include "gettext.hpp"
-#include "object/tilemap.hpp"
-
-namespace {
- const float GRACE_DX = 8; // how far off may the player's bounding-box be x-wise
- const float GRACE_DY = 8; // how far off may the player's bounding-box be y-wise
- const float ACTIVATE_TRY_FOR = 1; // how long to try correcting mis-alignment of player and climbable before giving up
- const float POSITION_FIX_AX = 50; // x-wise acceleration applied to player when trying to align player and Climbable
- const float POSITION_FIX_AY = 50; // y-wise acceleration applied to player when trying to align player and Climbable
-}
-
-Climbable::Climbable(const lisp::Lisp& reader)
- : climbed_by(0)
-{
- reader.get("x", bbox.p1.x);
- reader.get("y", bbox.p1.y);
- float w = 32, h = 32;
- reader.get("width", w);
- reader.get("height", h);
- bbox.set_size(w, h);
-}
-
-Climbable::Climbable(const Rect& area)
- : climbed_by(0)
-{
- bbox = area;
-}
-
-Climbable::~Climbable()
-{
- if (climbed_by) {
- climbed_by->stop_climbing(*this);
- climbed_by = 0;
- }
-}
-
-void
-Climbable::write(lisp::Writer& writer)
-{
- writer.start_list("climbable");
-
- writer.write_float("x", bbox.p1.x);
- writer.write_float("y", bbox.p1.y);
- writer.write_float("width", bbox.get_width());
- writer.write_float("height", bbox.get_height());
-
- writer.end_list("climbable");
-}
-
-void
-Climbable::update(float /*elapsed_time*/)
-{
- if (!climbed_by) return;
-
- if (!may_climb(*climbed_by)) {
- climbed_by->stop_climbing(*this);
- climbed_by = 0;
- }
-}
-
-void
-Climbable::draw(DrawingContext& context)
-{
- if (climbed_by) {
- context.push_transform();
- context.set_translation(Vector(0, 0));
- Vector pos = Vector(0, SCREEN_HEIGHT/2 - gold_text->get_height()/2);
- context.draw_center_text(gold_text, "Up we go...", pos, LAYER_GUI);
- context.pop_transform();
- }
-}
-
-void
-Climbable::event(Player& player, EventType type)
-{
- if ((type == EVENT_ACTIVATE) || (activate_try_timer.started())) {
- if (may_climb(player)) {
- climbed_by = &player;
- player.start_climbing(*this);
- activate_try_timer.stop();
- } else {
- if (type == EVENT_ACTIVATE) activate_try_timer.start(ACTIVATE_TRY_FOR);
- if (player.get_bbox().p1.x < get_bbox().p1.x - GRACE_DX) player.add_velocity(Vector(POSITION_FIX_AX,0));
- if (player.get_bbox().p2.x > get_bbox().p2.x + GRACE_DX) player.add_velocity(Vector(-POSITION_FIX_AX,0));
- if (player.get_bbox().p1.y < get_bbox().p1.y - GRACE_DY) player.add_velocity(Vector(0,POSITION_FIX_AY));
- if (player.get_bbox().p2.y > get_bbox().p2.y + GRACE_DY) player.add_velocity(Vector(0,-POSITION_FIX_AY));
- }
- }
- if(type == EVENT_LOSETOUCH) {
- player.stop_climbing(*this);
- climbed_by = 0;
- }
-}
-
-bool
-Climbable::may_climb(Player& player)
-{
- if (player.get_bbox().p1.x < get_bbox().p1.x - GRACE_DX) return false;
- if (player.get_bbox().p2.x > get_bbox().p2.x + GRACE_DX) return false;
- if (player.get_bbox().p1.y < get_bbox().p1.y - GRACE_DY) return false;
- if (player.get_bbox().p2.y > get_bbox().p2.y + GRACE_DY) return false;
- return true;
-}
-
-IMPLEMENT_FACTORY(Climbable, "climbable");
-
+++ /dev/null
-// $Id$
-//
-// SuperTux - Climbable area
-// Copyright (C) 2007 Christoph Sommer <christoph.sommer@2007.expires.deltadevelopment.de>
-//
-// 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.
-
-#ifndef __CLIMBABLE_H__
-#define __CLIMBABLE_H__
-
-#include "trigger_base.hpp"
-#include "serializable.hpp"
-#include "resources.hpp"
-#include "video/drawing_context.hpp"
-#include "timer.hpp"
-#include "object/player.hpp"
-
-class Climbable : public TriggerBase, public Serializable
-{
-public:
- Climbable(const lisp::Lisp& reader);
- Climbable(const Rect& area);
- ~Climbable();
-
- void write(lisp::Writer& writer);
- void event(Player& player, EventType type);
- void update(float elapsed_time);
- void draw(DrawingContext& context);
-
- /**
- * returns true if the player is within bounds of the Climbable
- */
- bool may_climb(Player& player);
-
-protected:
- Player* climbed_by; /**< set to player who's currently climbing us, null if nobody is */
- Timer activate_try_timer; /**< try to correct mis-alignment while this timer runs */
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include "door.hpp"
-#include "game_session.hpp"
-#include "resources.hpp"
-#include "object_factory.hpp"
-#include "sprite/sprite.hpp"
-#include "sprite/sprite_manager.hpp"
-#include "video/drawing_context.hpp"
-#include "lisp/lisp.hpp"
-#include "lisp/writer.hpp"
-#include "audio/sound_manager.hpp"
-
-Door::Door(const lisp::Lisp& reader)
- : state(CLOSED)
-{
- reader.get("x", bbox.p1.x);
- reader.get("y", bbox.p1.y);
- reader.get("sector", target_sector);
- reader.get("spawnpoint", target_spawnpoint);
-
- sprite = sprite_manager->create("images/objects/door/door.sprite");
- sprite->set_action("closed");
- bbox.set_size(sprite->get_current_hitbox_width(), sprite->get_current_hitbox_height());
-}
-
-Door::Door(int x, int y, std::string sector, std::string spawnpoint)
- : state(CLOSED)
-{
- bbox.set_pos(Vector(x, y));
- target_sector = sector;
- target_spawnpoint = spawnpoint;
-
- sprite = sprite_manager->create("images/objects/door/door.sprite");
- sprite->set_action("closed");
- bbox.set_size(sprite->get_current_hitbox_width(), sprite->get_current_hitbox_height());
-}
-
-Door::~Door()
-{
- delete sprite;
-}
-
-void
-Door::write(lisp::Writer& writer)
-{
- writer.start_list("door");
-
- writer.write_float("x", bbox.p1.x);
- writer.write_float("y", bbox.p1.y);
- writer.write_float("width", bbox.get_width());
- writer.write_float("height", bbox.get_height());
-
- writer.write_string("sector", target_sector);
- writer.write_string("spawnpoint", target_spawnpoint);
- sound_manager->preload("sounds/door.wav");
- writer.end_list("door");
-}
-
-void
-Door::update(float )
-{
- switch (state) {
- case CLOSED:
- break;
- case OPENING:
- // if door has finished opening, start timer and keep door open
- if(sprite->animation_done()) {
- state = OPEN;
- sprite->set_action("open");
- stay_open_timer.start(1.0);
- }
- break;
- case OPEN:
- // if door was open long enough, start closing it
- if (stay_open_timer.check()) {
- state = CLOSING;
- sprite->set_action("closing", 1);
- }
- break;
- case CLOSING:
- // if door has finished closing, keep it shut
- if(sprite->animation_done()) {
- state = CLOSED;
- sprite->set_action("closed");
- }
- break;
- }
-}
-
-void
-Door::draw(DrawingContext& context)
-{
- sprite->draw(context, bbox.p1, LAYER_BACKGROUNDTILES+1);
-}
-
-void
-Door::event(Player& , EventType type)
-{
- switch (state) {
- case CLOSED:
- // if door was activated, start opening it
- if (type == EVENT_ACTIVATE) {
- state = OPENING;
- sound_manager->play("sounds/door.wav");
- sprite->set_action("opening", 1);
- }
- break;
- case OPENING:
- break;
- case OPEN:
- break;
- case CLOSING:
- break;
- }
-}
-
-HitResponse
-Door::collision(GameObject& other, const CollisionHit& hit)
-{
- switch (state) {
- case CLOSED:
- break;
- case OPENING:
- break;
- case OPEN:
- {
- // if door is open and was touched by a player, teleport the player
- Player* player = dynamic_cast<Player*> (&other);
- if (player) {
- state = CLOSING;
- sprite->set_action("closing", 1);
- GameSession::current()->respawn(target_sector, target_spawnpoint);
- }
- }
- break;
- case CLOSING:
- break;
- }
-
- return TriggerBase::collision(other, hit);
-}
-
-IMPLEMENT_FACTORY(Door, "door");
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef SUPERTUX_DOOR_H
-#define SUPERTUX_DOOR_H
-
-#include <string>
-
-#include "video/surface.hpp"
-#include "sprite/sprite.hpp"
-#include "trigger_base.hpp"
-#include "serializable.hpp"
-#include "timer.hpp"
-#include "object/player.hpp"
-
-class Door : public TriggerBase, public Serializable
-{
-public:
- Door(const lisp::Lisp& reader);
- Door(int x, int y, std::string sector, std::string spawnpoint);
- virtual ~Door();
-
- virtual void write(lisp::Writer& writer);
-
- virtual void update(float elapsed_time);
- virtual void draw(DrawingContext& context);
- virtual void event(Player& player, EventType type);
- virtual HitResponse collision(GameObject& other, const CollisionHit& hit);
-
-private:
- enum DoorState {
- CLOSED,
- OPENING,
- OPEN,
- CLOSING
- };
-
- DoorState state; /**< current state of the door */
- std::string target_sector; /**< target sector to teleport to */
- std::string target_spawnpoint; /**< target spawnpoint to teleport to */
- Sprite* sprite; /**< "door" sprite to render */
- Timer stay_open_timer; /**< time until door will close again */
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include <sstream>
-#include <stdexcept>
-#include <memory>
-
-#include "scripttrigger.hpp"
-#include "game_session.hpp"
-#include "lisp/lisp.hpp"
-#include "lisp/writer.hpp"
-#include "object_factory.hpp"
-#include "sector.hpp"
-
-ScriptTrigger::ScriptTrigger(const lisp::Lisp& reader)
-{
- bool must_activate = false;
-
- reader.get("x", bbox.p1.x);
- reader.get("y", bbox.p1.y);
- float w = 0, h = 0;
- reader.get("width", w);
- reader.get("height", h);
- bbox.set_size(w, h);
- reader.get("script", script);
- reader.get("button", must_activate);
- if(script == "") {
- throw std::runtime_error("Need to specify a script for trigger object");
- }
-
- if (must_activate)
- triggerevent = EVENT_ACTIVATE;
- else
- triggerevent = EVENT_TOUCH;
-}
-
-ScriptTrigger::ScriptTrigger(const Vector& pos, const std::string& script)
-{
- bbox.set_pos(pos);
- bbox.set_size(32, 32);
- this->script = script;
- triggerevent = EVENT_TOUCH;
-}
-
-ScriptTrigger::~ScriptTrigger()
-{
-}
-
-void
-ScriptTrigger::write(lisp::Writer& writer)
-{
- writer.start_list("scripttrigger");
-
- writer.write_float("x", bbox.p1.x);
- writer.write_float("y", bbox.p1.y);
- writer.write_float("width", bbox.get_width());
- writer.write_float("height", bbox.get_height());
- writer.write_string("script", script);
- writer.write_bool("button", triggerevent == EVENT_ACTIVATE);
-
- writer.end_list("scripttrigger");
-}
-
-void
-ScriptTrigger::event(Player& , EventType type)
-{
- if(type != triggerevent)
- return;
-
- std::istringstream stream(script);
- Sector::current()->run_script(stream, "ScriptTrigger");
-}
-
-IMPLEMENT_FACTORY(ScriptTrigger, "scripttrigger");
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __SCRIPTTRIGGER_H__
-#define __SCRIPTTRIGGER_H__
-
-#include "trigger_base.hpp"
-#include "serializable.hpp"
-
-class ScriptTrigger : public TriggerBase, public Serializable
-{
-public:
- ScriptTrigger(const lisp::Lisp& reader);
- ScriptTrigger(const Vector& pos, const std::string& script);
- ~ScriptTrigger();
-
- void write(lisp::Writer& writer);
- void event(Player& player, EventType type);
-
-private:
- EventType triggerevent;
- std::string script;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include "secretarea_trigger.hpp"
-#include "game_session.hpp"
-#include "lisp/lisp.hpp"
-#include "lisp/writer.hpp"
-#include "object_factory.hpp"
-#include "main.hpp"
-#include "sector.hpp"
-#include "level.hpp"
-#include "gettext.hpp"
-#include "object/tilemap.hpp"
-
-static const float MESSAGE_TIME=3.5;
-
-SecretAreaTrigger::SecretAreaTrigger(const lisp::Lisp& reader)
- : fade_tilemap("")
-{
- reader.get("x", bbox.p1.x);
- reader.get("y", bbox.p1.y);
- float w = 32, h = 32;
- reader.get("width", w);
- reader.get("height", h);
- bbox.set_size(w, h);
- reader.get("fade-tilemap", fade_tilemap);
-
- message_displayed = false;
-}
-
-SecretAreaTrigger::SecretAreaTrigger(const Rect& area, std::string fade_tilemap)
- : fade_tilemap(fade_tilemap)
-{
- bbox = area;
- message_displayed = false;
-}
-
-SecretAreaTrigger::~SecretAreaTrigger()
-{
-}
-
-void
-SecretAreaTrigger::write(lisp::Writer& writer)
-{
- writer.start_list("secretarea");
-
- writer.write_float("x", bbox.p1.x);
- writer.write_float("y", bbox.p1.y);
- writer.write_float("width", bbox.get_width());
- writer.write_float("height", bbox.get_height());
- writer.write_string("fade-tilemap", fade_tilemap);
-
- writer.end_list("secretarea");
-}
-
-void
-SecretAreaTrigger::draw(DrawingContext& context)
-{
- if (message_timer.started()) {
- context.push_transform();
- context.set_translation(Vector(0, 0));
- Vector pos = Vector(0, SCREEN_HEIGHT/2 - gold_text->get_height()/2);
- context.draw_center_text(gold_text, _("You found a secret area!"), pos, LAYER_GUI);
- context.pop_transform();
- }
- if (message_timer.check()) {
- remove_me();
- }
-}
-
-void
-SecretAreaTrigger::event(Player& , EventType type)
-{
- if(type == EVENT_TOUCH) {
- if (!message_displayed) {
- message_timer.start(MESSAGE_TIME);
- message_displayed = true;
- Sector::current()->get_level()->stats.secrets++;
-
- if (fade_tilemap != "") {
- // fade away tilemaps
- Sector& sector = *Sector::current();
- for(Sector::GameObjects::iterator i = sector.gameobjects.begin(); i != sector.gameobjects.end(); ++i) {
- TileMap* tm = dynamic_cast<TileMap*>(*i);
- if (!tm) continue;
- if (tm->get_name() != fade_tilemap) continue;
- tm->fade(0.0, 1.0);
- }
- }
-
- }
- }
-}
-
-IMPLEMENT_FACTORY(SecretAreaTrigger, "secretarea");
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef __SECRETAREA_TRIGGER_H__
-#define __SECRETAREA_TRIGGER_H__
-
-#include "trigger_base.hpp"
-#include "serializable.hpp"
-#include "resources.hpp"
-#include "video/drawing_context.hpp"
-#include "timer.hpp"
-
-class SecretAreaTrigger : public TriggerBase, public Serializable
-{
-public:
- SecretAreaTrigger(const lisp::Lisp& reader);
- SecretAreaTrigger(const Rect& area, std::string fade_tilemap = "");
- ~SecretAreaTrigger();
-
- void write(lisp::Writer& writer);
- void event(Player& player, EventType type);
- void draw(DrawingContext& context);
-
-private:
- Timer message_timer;
- bool message_displayed;
- std::string fade_tilemap; /**< tilemap to fade away when trigger is activated, or empty if you don't care */
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-
-#include <config.h>
-
-#include "sequence_trigger.hpp"
-#include "game_session.hpp"
-#include "lisp/lisp.hpp"
-#include "lisp/writer.hpp"
-#include "object_factory.hpp"
-
-SequenceTrigger::SequenceTrigger(const lisp::Lisp& reader)
-{
- reader.get("x", bbox.p1.x);
- reader.get("y", bbox.p1.y);
- float w = 0, h = 0;
- reader.get("width", w);
- reader.get("height", h);
- bbox.set_size(w, h);
- reader.get("sequence", sequence_name);
- triggerevent = EVENT_TOUCH;
-}
-
-SequenceTrigger::SequenceTrigger(const Vector& pos, const std::string& sequence)
-{
- bbox.set_pos(pos);
- bbox.set_size(32, 32);
- sequence_name = sequence;
- triggerevent = EVENT_TOUCH;
-}
-
-SequenceTrigger::~SequenceTrigger()
-{
-}
-
-void
-SequenceTrigger::write(lisp::Writer& writer)
-{
- writer.start_list("sequencetrigger");
-
- writer.write_float("x", bbox.p1.x);
- writer.write_float("y", bbox.p1.y);
- writer.write_float("width", bbox.get_width());
- writer.write_float("height", bbox.get_height());
- writer.write_string("sequence", sequence_name);
-
- writer.end_list("sequencetrigger");
-}
-
-void
-SequenceTrigger::event(Player& player, EventType type)
-{
- if(type == triggerevent) {
- player.trigger_sequence(sequence_name);
- }
-}
-
-IMPLEMENT_FACTORY(SequenceTrigger, "sequencetrigger")
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-
-#ifndef __SEQUENCE_TRIGGER_H__
-#define __SEQUENCE_TRIGGER_H__
-
-#include "trigger_base.hpp"
-#include "serializable.hpp"
-#include "object/player.hpp"
-
-class SequenceTrigger : public TriggerBase, public Serializable
-{
-public:
- SequenceTrigger(const lisp::Lisp& reader);
- SequenceTrigger(const Vector& pos, const std::string& sequence);
- ~SequenceTrigger();
-
- void write(lisp::Writer& writer);
- void event(Player& player, EventType type);
-
- std::string get_sequence_name() const { return sequence_name; }
-
-private:
- EventType triggerevent;
- std::string sequence_name;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux - Switch Trigger
-// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
-//
-// 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.
-
-#include <config.h>
-#include <stdexcept>
-
-#include "switch.hpp"
-#include "object_factory.hpp"
-#include "sprite/sprite.hpp"
-#include "sprite/sprite_manager.hpp"
-#include "sector.hpp"
-#include "audio/sound_manager.hpp"
-
-namespace {
- const std::string SWITCH_SOUND = "sounds/switch.ogg";
-}
-
-Switch::Switch(const lisp::Lisp& reader)
- : state(OFF)
-{
- if (!reader.get("x", bbox.p1.x)) throw std::runtime_error("no x position set");
- if (!reader.get("y", bbox.p1.y)) throw std::runtime_error("no y position set");
- if (!reader.get("sprite", sprite_name)) throw std::runtime_error("no sprite name set");
- sprite = sprite_manager->create(sprite_name);
- bbox.set_size(sprite->get_current_hitbox_width(), sprite->get_current_hitbox_height());
-
- if (!reader.get("script", script)) throw std::runtime_error("no script set");
- sound_manager->preload( SWITCH_SOUND );
-}
-
-Switch::~Switch()
-{
- delete sprite;
-}
-
-void
-Switch::write(lisp::Writer& writer)
-{
- writer.start_list("switch");
- writer.write_float("x", bbox.p1.x);
- writer.write_float("y", bbox.p1.y);
- writer.write_string("sprite", sprite_name);
- writer.write_string("script", script);
- writer.end_list("switch");
-}
-
-void
-Switch::update(float )
-{
- switch (state) {
- case OFF:
- break;
- case TURN_ON:
- if(sprite->animation_done()) {
- std::istringstream stream(script);
- Sector::current()->run_script(stream, "Switch");
-
- sprite->set_action("on", 1);
- state = ON;
- }
- break;
- case ON:
- if(sprite->animation_done()) {
- sprite->set_action("turnoff", 1);
- state = TURN_OFF;
- }
- break;
- case TURN_OFF:
- if(sprite->animation_done()) {
- sprite->set_action("off");
- state = OFF;
- }
- break;
- }
-}
-
-void
-Switch::draw(DrawingContext& context)
-{
- sprite->draw(context, bbox.p1, LAYER_TILES);
-}
-
-void
-Switch::event(Player& , EventType type)
-{
- if(type != EVENT_ACTIVATE) return;
-
- switch (state) {
- case OFF:
- sprite->set_action("turnon", 1);
- sound_manager->play( SWITCH_SOUND );
- state = TURN_ON;
- break;
- case TURN_ON:
- break;
- case ON:
- break;
- case TURN_OFF:
- break;
- }
-
-}
-
-IMPLEMENT_FACTORY(Switch, "switch");
+++ /dev/null
-// $Id$
-//
-// SuperTux - Switch Trigger
-// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
-//
-// 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.
-
-#ifndef SUPERTUX_SWITCH_H
-#define SUPERTUX_SWITCH_H
-
-#include <string>
-
-#include "trigger_base.hpp"
-#include "serializable.hpp"
-#include "lisp/lisp.hpp"
-#include "lisp/writer.hpp"
-#include "video/drawing_context.hpp"
-#include "sprite/sprite.hpp"
-
-class Switch : public TriggerBase, public Serializable
-{
-public:
- Switch(const lisp::Lisp& reader);
- virtual ~Switch();
-
- virtual void write(lisp::Writer& writer);
-
- virtual void update(float elapsed_time);
- virtual void draw(DrawingContext& context);
- virtual void event(Player& player, EventType type);
-
-private:
- enum SwitchState {
- OFF,
- TURN_ON,
- ON,
- TURN_OFF
- };
-
- std::string sprite_name;
- Sprite* sprite;
- std::string script;
-
- SwitchState state;
-
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include "trigger_base.hpp"
-#include "video/drawing_context.hpp"
-#include "object/player.hpp"
-#include "log.hpp"
-
-TriggerBase::TriggerBase()
- : sprite(0), lasthit(false), hit(false)
-{
- set_group(COLGROUP_TOUCHABLE);
-}
-
-TriggerBase::~TriggerBase()
-{
- // unregister remove_listener hooks, so nobody will try to call us after we've been destroyed
- for (std::list<Player*>::iterator i = losetouch_listeners.begin(); i != losetouch_listeners.end(); i++) {
- Player* p = *i;
- p->del_remove_listener(this);
- }
- losetouch_listeners.clear();
-}
-
-void
-TriggerBase::update(float )
-{
- if (lasthit && !hit) {
- for (std::list<Player*>::iterator i = losetouch_listeners.begin(); i != losetouch_listeners.end(); i++) {
- Player* p = *i;
- event(*p, EVENT_LOSETOUCH);
- p->del_remove_listener(this);
- }
- losetouch_listeners.clear();
- }
- lasthit = hit;
- hit = false;
-}
-
-void
-TriggerBase::draw(DrawingContext& context)
-{
- if(!sprite)
- return;
-
- sprite->draw(context, get_pos(), LAYER_TILES+1);
-}
-
-HitResponse
-TriggerBase::collision(GameObject& other, const CollisionHit& )
-{
- Player* player = dynamic_cast<Player*> (&other);
- if(player) {
- hit = true;
- if(!lasthit) {
- losetouch_listeners.push_back(player);
- player->add_remove_listener(this);
- event(*player, EVENT_TOUCH);
- }
- }
-
- return ABORT_MOVE;
-}
-
-void
-TriggerBase::object_removed(GameObject* object)
-{
- for (std::list<Player*>::iterator i = losetouch_listeners.begin(); i != losetouch_listeners.end(); i++) {
- Player* p = *i;
- if (p == object) {
- losetouch_listeners.erase(i);
- break;
- }
- }
-}
-
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#ifndef SUPERTUX_TRIGGER_BASE_H
-#define SUPERTUX_TRIGGER_BASE_H
-
-#include <list>
-#include "moving_object.hpp"
-#include "math/rect.hpp"
-#include "sprite/sprite.hpp"
-#include "object_remove_listener.hpp"
-
-class Player;
-
-/** This class is the base class for all objects you can interact with in some
- * way. There are several interaction types defined like touch and activate
- */
-class TriggerBase : public MovingObject, public ObjectRemoveListener
-{
-public:
- enum EventType {
- EVENT_TOUCH, /**< Object came into contact */
- EVENT_LOSETOUCH, /**< Lost contact with object */
- EVENT_ACTIVATE /**< Action button pressed */
- };
-
- TriggerBase();
- ~TriggerBase();
-
- void update(float elapsed_time);
- void draw(DrawingContext& context);
- HitResponse collision(GameObject& other, const CollisionHit& hit);
-
- /**
- * Receive trigger events
- */
- virtual void event(Player& player, EventType type) = 0;
-
- /**
- * Called by GameObject destructor of an object in losetouch_listeners
- */
- virtual void object_removed(GameObject* object);
-
-private:
- Sprite* sprite;
- bool lasthit;
- bool hit;
-
- std::list<Player*> losetouch_listeners; /**< Players that will be informed when we lose touch with them */
-};
-
-#endif /*SUPERTUX_INTERACTIVE_OBJECT_H*/
+++ /dev/null
-# Copyright Timothy Goya 2007.
-# Distributed under the Boost Software License, Version 1.0.
-# (See accompanying file LICENSE_1_0.txt or copy at
-# http://www.boost.org/LICENSE_1_0.txt)
-
-PROJECT(UNISON)
-
-INCLUDE_DIRECTORIES(${UNISON_SOURCE_DIR}/include/)
-
-FIND_PACKAGE(SDL REQUIRED)
-INCLUDE_DIRECTORIES(${SDL_INCLUDE_DIR})
-LINK_LIBRARIES(${SDL_LIBRARY})
-
-FIND_PACKAGE(SDL_image REQUIRED)
-INCLUDE_DIRECTORIES(${SDLIMAGE_INCLUDE_DIR})
-LINK_LIBRARIES(${SDLIMAGE_LIBRARY})
-
-FIND_PACKAGE(PhysFS)
-IF(${PHYSFS_FOUND} STREQUAL "NO")
- SET(PHYSFS_BUILD_SHARED FALSE)
- ADD_SUBDIRECTORY(physfs-1.1.1)
- SET(PHYSFS_INCLUDE_DIR physfs-1.1.1)
- SET(PHYSFS_LIBRARY ${UNISON_BINARY_DIR}/physfs-1.1.1/libphysfs.a)
-ENDIF(${PHYSFS_FOUND} STREQUAL "NO")
-INCLUDE_DIRECTORIES(${PHYSFS_INCLUDE_DIR})
-LINK_LIBRARIES(${PHYSFS_LIBRARY})
-
-IF(CMAKE_COMPILER_IS_GNUCC)
- ADD_DEFINITIONS(-g -O2 -Wall -Wextra)
-ENDIF(CMAKE_COMPILER_IS_GNUCC)
-
-IF(MSVC)
- ADD_DEFINITIONS(-D_CRG_SECURE_NO_WARNINGS=1)
-ENDIF(MSVC)
-
-CHECK_INCLUDE_FILE(assert.h HAVE_ASSERT_H)
-IF(HAVE_ASSERT_H)
- ADD_DEFINITIONS(-DHAVE_ASSERT_H=1)
-ENDIF(HAVE_ASSERT_H)
-
-FILE(GLOB_RECURSE UNISON_SOURCES RELATIVE ${UNISON_SOURCE_DIR} src/*.cpp src/*.c)
-
-ADD_LIBRARY(unison ${UNISON_SOURCES})
-
-IF(${PHYSFS_FOUND} STREQUAL "NO")
- ADD_DEPENDENCIES(unison physfs-static)
- SET(PHYSFS_FOUND "YES")
-ENDIF(${PHYSFS_FOUND} STREQUAL "NO")
-
-FIND_PACKAGE(Doxygen)
-IF(DOXYGEN_FOUND)
- ADD_CUSTOM_TARGET(docs ${DOXYGEN_EXECUTABLE} COMMENT "Building documentation")
-ELSE(DOXYGEN_FOUND)
- MESSAGE(STATUS "Doxygen not found. You won't be able to build documentation.")
-ENDIF(DOXYGEN_FOUND)
+++ /dev/null
-# Doxyfile 1.5.2
-
-# This file describes the settings to be used by the documentation system
-# doxygen (www.doxygen.org) for a project
-#
-# All text after a hash (#) is considered a comment and will be ignored
-# The format is:
-# TAG = value [value, ...]
-# For lists items can also be appended using:
-# TAG += value [value, ...]
-# Values that contain spaces should be placed between quotes (" ")
-
-#---------------------------------------------------------------------------
-# Project related configuration options
-#---------------------------------------------------------------------------
-
-# This tag specifies the encoding used for all characters in the config file that
-# follow. The default is UTF-8 which is also the encoding used for all text before
-# the first occurrence of this tag. Doxygen uses libiconv (or the iconv built into
-# libc) for the transcoding. See http://www.gnu.org/software/libiconv for the list of
-# possible encodings.
-
-DOXYFILE_ENCODING = UTF-8
-
-# The PROJECT_NAME tag is a single word (or a sequence of words surrounded
-# by quotes) that should identify the project.
-
-PROJECT_NAME = Unison
-
-# The PROJECT_NUMBER tag can be used to enter a project or revision number.
-# This could be handy for archiving the generated documentation or
-# if some version control system is used.
-
-PROJECT_NUMBER =
-
-# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
-# base path where the generated documentation will be put.
-# If a relative path is entered, it will be relative to the location
-# where doxygen was started. If left blank the current directory will be used.
-
-OUTPUT_DIRECTORY =
-
-# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create
-# 4096 sub-directories (in 2 levels) under the output directory of each output
-# format and will distribute the generated files over these directories.
-# Enabling this option can be useful when feeding doxygen a huge amount of
-# source files, where putting all generated files in the same directory would
-# otherwise cause performance problems for the file system.
-
-CREATE_SUBDIRS = NO
-
-# The OUTPUT_LANGUAGE tag is used to specify the language in which all
-# documentation generated by doxygen is written. Doxygen will use this
-# information to generate all constant output in the proper language.
-# The default language is English, other supported languages are:
-# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional,
-# Croatian, Czech, Danish, Dutch, Finnish, French, German, Greek, Hungarian,
-# Italian, Japanese, Japanese-en (Japanese with English messages), Korean,
-# Korean-en, Lithuanian, Norwegian, Polish, Portuguese, Romanian, Russian,
-# Serbian, Slovak, Slovene, Spanish, Swedish, and Ukrainian.
-
-OUTPUT_LANGUAGE = English
-
-# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will
-# include brief member descriptions after the members that are listed in
-# the file and class documentation (similar to JavaDoc).
-# Set to NO to disable this.
-
-BRIEF_MEMBER_DESC = YES
-
-# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend
-# the brief description of a member or function before the detailed description.
-# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
-# brief descriptions will be completely suppressed.
-
-REPEAT_BRIEF = YES
-
-# This tag implements a quasi-intelligent brief description abbreviator
-# that is used to form the text in various listings. Each string
-# in this list, if found as the leading text of the brief description, will be
-# stripped from the text and the result after processing the whole list, is
-# used as the annotated text. Otherwise, the brief description is used as-is.
-# If left blank, the following values are used ("$name" is automatically
-# replaced with the name of the entity): "The $name class" "The $name widget"
-# "The $name file" "is" "provides" "specifies" "contains"
-# "represents" "a" "an" "the"
-
-ABBREVIATE_BRIEF =
-
-# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
-# Doxygen will generate a detailed section even if there is only a brief
-# description.
-
-ALWAYS_DETAILED_SEC = NO
-
-# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all
-# inherited members of a class in the documentation of that class as if those
-# members were ordinary class members. Constructors, destructors and assignment
-# operators of the base classes will not be shown.
-
-INLINE_INHERITED_MEMB = NO
-
-# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full
-# path before files name in the file list and in the header files. If set
-# to NO the shortest path that makes the file name unique will be used.
-
-FULL_PATH_NAMES = YES
-
-# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag
-# can be used to strip a user-defined part of the path. Stripping is
-# only done if one of the specified strings matches the left-hand part of
-# the path. The tag can be used to show relative paths in the file list.
-# If left blank the directory from which doxygen is run is used as the
-# path to strip.
-
-STRIP_FROM_PATH =
-
-# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of
-# the path mentioned in the documentation of a class, which tells
-# the reader which header file to include in order to use a class.
-# If left blank only the name of the header file containing the class
-# definition is used. Otherwise one should specify the include paths that
-# are normally passed to the compiler using the -I flag.
-
-STRIP_FROM_INC_PATH =
-
-# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter
-# (but less readable) file names. This can be useful is your file systems
-# doesn't support long names like on DOS, Mac, or CD-ROM.
-
-SHORT_NAMES = NO
-
-# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen
-# will interpret the first line (until the first dot) of a JavaDoc-style
-# comment as the brief description. If set to NO, the JavaDoc
-# comments will behave just like the Qt-style comments (thus requiring an
-# explicit @brief command for a brief description.
-
-JAVADOC_AUTOBRIEF = NO
-
-# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen
-# treat a multi-line C++ special comment block (i.e. a block of //! or ///
-# comments) as a brief description. This used to be the default behaviour.
-# The new default is to treat a multi-line C++ comment block as a detailed
-# description. Set this tag to YES if you prefer the old behaviour instead.
-
-MULTILINE_CPP_IS_BRIEF = NO
-
-# If the DETAILS_AT_TOP tag is set to YES then Doxygen
-# will output the detailed description near the top, like JavaDoc.
-# If set to NO, the detailed description appears after the member
-# documentation.
-
-DETAILS_AT_TOP = NO
-
-# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented
-# member inherits the documentation from any documented member that it
-# re-implements.
-
-INHERIT_DOCS = YES
-
-# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce
-# a new page for each member. If set to NO, the documentation of a member will
-# be part of the file/class/namespace that contains it.
-
-SEPARATE_MEMBER_PAGES = NO
-
-# The TAB_SIZE tag can be used to set the number of spaces in a tab.
-# Doxygen uses this value to replace tabs by spaces in code fragments.
-
-TAB_SIZE = 8
-
-# This tag can be used to specify a number of aliases that acts
-# as commands in the documentation. An alias has the form "name=value".
-# For example adding "sideeffect=\par Side Effects:\n" will allow you to
-# put the command \sideeffect (or @sideeffect) in the documentation, which
-# will result in a user-defined paragraph with heading "Side Effects:".
-# You can put \n's in the value part of an alias to insert newlines.
-
-ALIASES =
-
-# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C
-# sources only. Doxygen will then generate output that is more tailored for C.
-# For instance, some of the names that are used will be different. The list
-# of all members will be omitted, etc.
-
-OPTIMIZE_OUTPUT_FOR_C = NO
-
-# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java
-# sources only. Doxygen will then generate output that is more tailored for Java.
-# For instance, namespaces will be presented as packages, qualified scopes
-# will look different, etc.
-
-OPTIMIZE_OUTPUT_JAVA = NO
-
-# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want to
-# include (a tag file for) the STL sources as input, then you should
-# set this tag to YES in order to let doxygen match functions declarations and
-# definitions whose arguments contain STL classes (e.g. func(std::string); v.s.
-# func(std::string) {}). This also make the inheritance and collaboration
-# diagrams that involve STL classes more complete and accurate.
-
-BUILTIN_STL_SUPPORT = NO
-
-# If you use Microsoft's C++/CLI language, you should set this option to YES to
-# enable parsing support.
-
-CPP_CLI_SUPPORT = NO
-
-# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
-# tag is set to YES, then doxygen will reuse the documentation of the first
-# member in the group (if any) for the other members of the group. By default
-# all members of a group must be documented explicitly.
-
-DISTRIBUTE_GROUP_DOC = NO
-
-# Set the SUBGROUPING tag to YES (the default) to allow class member groups of
-# the same type (for instance a group of public functions) to be put as a
-# subgroup of that type (e.g. under the Public Functions section). Set it to
-# NO to prevent subgrouping. Alternatively, this can be done per class using
-# the \nosubgrouping command.
-
-SUBGROUPING = YES
-
-#---------------------------------------------------------------------------
-# Build related configuration options
-#---------------------------------------------------------------------------
-
-# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in
-# documentation are documented, even if no documentation was available.
-# Private class members and static file members will be hidden unless
-# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
-
-EXTRACT_ALL = NO
-
-# If the EXTRACT_PRIVATE tag is set to YES all private members of a class
-# will be included in the documentation.
-
-EXTRACT_PRIVATE = NO
-
-# If the EXTRACT_STATIC tag is set to YES all static members of a file
-# will be included in the documentation.
-
-EXTRACT_STATIC = NO
-
-# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs)
-# defined locally in source files will be included in the documentation.
-# If set to NO only classes defined in header files are included.
-
-EXTRACT_LOCAL_CLASSES = YES
-
-# This flag is only useful for Objective-C code. When set to YES local
-# methods, which are defined in the implementation section but not in
-# the interface are included in the documentation.
-# If set to NO (the default) only methods in the interface are included.
-
-EXTRACT_LOCAL_METHODS = NO
-
-# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all
-# undocumented members of documented classes, files or namespaces.
-# If set to NO (the default) these members will be included in the
-# various overviews, but no documentation section is generated.
-# This option has no effect if EXTRACT_ALL is enabled.
-
-HIDE_UNDOC_MEMBERS = NO
-
-# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all
-# undocumented classes that are normally visible in the class hierarchy.
-# If set to NO (the default) these classes will be included in the various
-# overviews. This option has no effect if EXTRACT_ALL is enabled.
-
-HIDE_UNDOC_CLASSES = NO
-
-# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all
-# friend (class|struct|union) declarations.
-# If set to NO (the default) these declarations will be included in the
-# documentation.
-
-HIDE_FRIEND_COMPOUNDS = NO
-
-# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any
-# documentation blocks found inside the body of a function.
-# If set to NO (the default) these blocks will be appended to the
-# function's detailed documentation block.
-
-HIDE_IN_BODY_DOCS = NO
-
-# The INTERNAL_DOCS tag determines if documentation
-# that is typed after a \internal command is included. If the tag is set
-# to NO (the default) then the documentation will be excluded.
-# Set it to YES to include the internal documentation.
-
-INTERNAL_DOCS = NO
-
-# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate
-# file names in lower-case letters. If set to YES upper-case letters are also
-# allowed. This is useful if you have classes or files whose names only differ
-# in case and if your file system supports case sensitive file names. Windows
-# and Mac users are advised to set this option to NO.
-
-CASE_SENSE_NAMES = YES
-
-# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen
-# will show members with their full class and namespace scopes in the
-# documentation. If set to YES the scope will be hidden.
-
-HIDE_SCOPE_NAMES = NO
-
-# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen
-# will put a list of the files that are included by a file in the documentation
-# of that file.
-
-SHOW_INCLUDE_FILES = YES
-
-# If the INLINE_INFO tag is set to YES (the default) then a tag [inline]
-# is inserted in the documentation for inline members.
-
-INLINE_INFO = YES
-
-# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen
-# will sort the (detailed) documentation of file and class members
-# alphabetically by member name. If set to NO the members will appear in
-# declaration order.
-
-SORT_MEMBER_DOCS = YES
-
-# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the
-# brief documentation of file, namespace and class members alphabetically
-# by member name. If set to NO (the default) the members will appear in
-# declaration order.
-
-SORT_BRIEF_DOCS = NO
-
-# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be
-# sorted by fully-qualified names, including namespaces. If set to
-# NO (the default), the class list will be sorted only by class name,
-# not including the namespace part.
-# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
-# Note: This option applies only to the class list, not to the
-# alphabetical list.
-
-SORT_BY_SCOPE_NAME = NO
-
-# The GENERATE_TODOLIST tag can be used to enable (YES) or
-# disable (NO) the todo list. This list is created by putting \todo
-# commands in the documentation.
-
-GENERATE_TODOLIST = YES
-
-# The GENERATE_TESTLIST tag can be used to enable (YES) or
-# disable (NO) the test list. This list is created by putting \test
-# commands in the documentation.
-
-GENERATE_TESTLIST = YES
-
-# The GENERATE_BUGLIST tag can be used to enable (YES) or
-# disable (NO) the bug list. This list is created by putting \bug
-# commands in the documentation.
-
-GENERATE_BUGLIST = YES
-
-# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or
-# disable (NO) the deprecated list. This list is created by putting
-# \deprecated commands in the documentation.
-
-GENERATE_DEPRECATEDLIST= YES
-
-# The ENABLED_SECTIONS tag can be used to enable conditional
-# documentation sections, marked by \if sectionname ... \endif.
-
-ENABLED_SECTIONS =
-
-# The MAX_INITIALIZER_LINES tag determines the maximum number of lines
-# the initial value of a variable or define consists of for it to appear in
-# the documentation. If the initializer consists of more lines than specified
-# here it will be hidden. Use a value of 0 to hide initializers completely.
-# The appearance of the initializer of individual variables and defines in the
-# documentation can be controlled using \showinitializer or \hideinitializer
-# command in the documentation regardless of this setting.
-
-MAX_INITIALIZER_LINES = 30
-
-# Set the SHOW_USED_FILES tag to NO to disable the list of files generated
-# at the bottom of the documentation of classes and structs. If set to YES the
-# list will mention the files that were used to generate the documentation.
-
-SHOW_USED_FILES = YES
-
-# If the sources in your project are distributed over multiple directories
-# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy
-# in the documentation. The default is NO.
-
-SHOW_DIRECTORIES = NO
-
-# The FILE_VERSION_FILTER tag can be used to specify a program or script that
-# doxygen should invoke to get the current version for each file (typically from the
-# version control system). Doxygen will invoke the program by executing (via
-# popen()) the command <command> <input-file>, where <command> is the value of
-# the FILE_VERSION_FILTER tag, and <input-file> is the name of an input file
-# provided by doxygen. Whatever the program writes to standard output
-# is used as the file version. See the manual for examples.
-
-FILE_VERSION_FILTER =
-
-#---------------------------------------------------------------------------
-# configuration options related to warning and progress messages
-#---------------------------------------------------------------------------
-
-# The QUIET tag can be used to turn on/off the messages that are generated
-# by doxygen. Possible values are YES and NO. If left blank NO is used.
-
-QUIET = NO
-
-# The WARNINGS tag can be used to turn on/off the warning messages that are
-# generated by doxygen. Possible values are YES and NO. If left blank
-# NO is used.
-
-WARNINGS = YES
-
-# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings
-# for undocumented members. If EXTRACT_ALL is set to YES then this flag will
-# automatically be disabled.
-
-WARN_IF_UNDOCUMENTED = YES
-
-# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for
-# potential errors in the documentation, such as not documenting some
-# parameters in a documented function, or documenting parameters that
-# don't exist or using markup commands wrongly.
-
-WARN_IF_DOC_ERROR = YES
-
-# This WARN_NO_PARAMDOC option can be abled to get warnings for
-# functions that are documented, but have no documentation for their parameters
-# or return value. If set to NO (the default) doxygen will only warn about
-# wrong or incomplete parameter documentation, but not about the absence of
-# documentation.
-
-WARN_NO_PARAMDOC = NO
-
-# The WARN_FORMAT tag determines the format of the warning messages that
-# doxygen can produce. The string should contain the $file, $line, and $text
-# tags, which will be replaced by the file and line number from which the
-# warning originated and the warning text. Optionally the format may contain
-# $version, which will be replaced by the version of the file (if it could
-# be obtained via FILE_VERSION_FILTER)
-
-WARN_FORMAT = "$file:$line: $text"
-
-# The WARN_LOGFILE tag can be used to specify a file to which warning
-# and error messages should be written. If left blank the output is written
-# to stderr.
-
-WARN_LOGFILE =
-
-#---------------------------------------------------------------------------
-# configuration options related to the input files
-#---------------------------------------------------------------------------
-
-# The INPUT tag can be used to specify the files and/or directories that contain
-# documented source files. You may enter file names like "myfile.cpp" or
-# directories like "/usr/src/myproject". Separate the files or directories
-# with spaces.
-
-INPUT = include/unison/video include/unison/video/backend
-
-# This tag can be used to specify the character encoding of the source files that
-# doxygen parses. Internally doxygen uses the UTF-8 encoding, which is also the default
-# input encoding. Doxygen uses libiconv (or the iconv built into libc) for the transcoding.
-# See http://www.gnu.org/software/libiconv for the list of possible encodings.
-
-INPUT_ENCODING = UTF-8
-
-# If the value of the INPUT tag contains directories, you can use the
-# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
-# and *.h) to filter out the source-files in the directories. If left
-# blank the following patterns are tested:
-# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx
-# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py
-
-FILE_PATTERNS =
-
-# The RECURSIVE tag can be used to turn specify whether or not subdirectories
-# should be searched for input files as well. Possible values are YES and NO.
-# If left blank NO is used.
-
-RECURSIVE = NO
-
-# The EXCLUDE tag can be used to specify files and/or directories that should
-# excluded from the INPUT source files. This way you can easily exclude a
-# subdirectory from a directory tree whose root is specified with the INPUT tag.
-
-EXCLUDE =
-
-# The EXCLUDE_SYMLINKS tag can be used select whether or not files or
-# directories that are symbolic links (a Unix filesystem feature) are excluded
-# from the input.
-
-EXCLUDE_SYMLINKS = NO
-
-# If the value of the INPUT tag contains directories, you can use the
-# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
-# certain files from those directories. Note that the wildcards are matched
-# against the file with absolute path, so to exclude all test directories
-# for example use the pattern */test/*
-
-EXCLUDE_PATTERNS =
-
-# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
-# (namespaces, classes, functions, etc.) that should be excluded from the output.
-# The symbol name can be a fully qualified name, a word, or if the wildcard * is used,
-# a substring. Examples: ANamespace, AClass, AClass::ANamespace, ANamespace::*Test
-
-EXCLUDE_SYMBOLS =
-
-# The EXAMPLE_PATH tag can be used to specify one or more files or
-# directories that contain example code fragments that are included (see
-# the \include command).
-
-EXAMPLE_PATH =
-
-# If the value of the EXAMPLE_PATH tag contains directories, you can use the
-# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
-# and *.h) to filter out the source-files in the directories. If left
-# blank all files are included.
-
-EXAMPLE_PATTERNS =
-
-# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be
-# searched for input files to be used with the \include or \dontinclude
-# commands irrespective of the value of the RECURSIVE tag.
-# Possible values are YES and NO. If left blank NO is used.
-
-EXAMPLE_RECURSIVE = NO
-
-# The IMAGE_PATH tag can be used to specify one or more files or
-# directories that contain image that are included in the documentation (see
-# the \image command).
-
-IMAGE_PATH =
-
-# The INPUT_FILTER tag can be used to specify a program that doxygen should
-# invoke to filter for each input file. Doxygen will invoke the filter program
-# by executing (via popen()) the command <filter> <input-file>, where <filter>
-# is the value of the INPUT_FILTER tag, and <input-file> is the name of an
-# input file. Doxygen will then use the output that the filter program writes
-# to standard output. If FILTER_PATTERNS is specified, this tag will be
-# ignored.
-
-INPUT_FILTER =
-
-# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern
-# basis. Doxygen will compare the file name with each pattern and apply the
-# filter if there is a match. The filters are a list of the form:
-# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further
-# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER
-# is applied to all files.
-
-FILTER_PATTERNS =
-
-# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
-# INPUT_FILTER) will be used to filter the input files when producing source
-# files to browse (i.e. when SOURCE_BROWSER is set to YES).
-
-FILTER_SOURCE_FILES = NO
-
-#---------------------------------------------------------------------------
-# configuration options related to source browsing
-#---------------------------------------------------------------------------
-
-# If the SOURCE_BROWSER tag is set to YES then a list of source files will
-# be generated. Documented entities will be cross-referenced with these sources.
-# Note: To get rid of all source code in the generated output, make sure also
-# VERBATIM_HEADERS is set to NO.
-
-SOURCE_BROWSER = NO
-
-# Setting the INLINE_SOURCES tag to YES will include the body
-# of functions and classes directly in the documentation.
-
-INLINE_SOURCES = NO
-
-# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct
-# doxygen to hide any special comment blocks from generated source code
-# fragments. Normal C and C++ comments will always remain visible.
-
-STRIP_CODE_COMMENTS = YES
-
-# If the REFERENCED_BY_RELATION tag is set to YES (the default)
-# then for each documented function all documented
-# functions referencing it will be listed.
-
-REFERENCED_BY_RELATION = YES
-
-# If the REFERENCES_RELATION tag is set to YES (the default)
-# then for each documented function all documented entities
-# called/used by that function will be listed.
-
-REFERENCES_RELATION = YES
-
-# If the REFERENCES_LINK_SOURCE tag is set to YES (the default)
-# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from
-# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will
-# link to the source code. Otherwise they will link to the documentstion.
-
-REFERENCES_LINK_SOURCE = YES
-
-# If the USE_HTAGS tag is set to YES then the references to source code
-# will point to the HTML generated by the htags(1) tool instead of doxygen
-# built-in source browser. The htags tool is part of GNU's global source
-# tagging system (see http://www.gnu.org/software/global/global.html). You
-# will need version 4.8.6 or higher.
-
-USE_HTAGS = NO
-
-# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen
-# will generate a verbatim copy of the header file for each class for
-# which an include is specified. Set to NO to disable this.
-
-VERBATIM_HEADERS = YES
-
-#---------------------------------------------------------------------------
-# configuration options related to the alphabetical class index
-#---------------------------------------------------------------------------
-
-# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index
-# of all compounds will be generated. Enable this if the project
-# contains a lot of classes, structs, unions or interfaces.
-
-ALPHABETICAL_INDEX = NO
-
-# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then
-# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns
-# in which this list will be split (can be a number in the range [1..20])
-
-COLS_IN_ALPHA_INDEX = 5
-
-# In case all classes in a project start with a common prefix, all
-# classes will be put under the same header in the alphabetical index.
-# The IGNORE_PREFIX tag can be used to specify one or more prefixes that
-# should be ignored while generating the index headers.
-
-IGNORE_PREFIX =
-
-#---------------------------------------------------------------------------
-# configuration options related to the HTML output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_HTML tag is set to YES (the default) Doxygen will
-# generate HTML output.
-
-GENERATE_HTML = YES
-
-# The HTML_OUTPUT tag is used to specify where the HTML docs will be put.
-# If a relative path is entered the value of OUTPUT_DIRECTORY will be
-# put in front of it. If left blank `html' will be used as the default path.
-
-HTML_OUTPUT = docs
-
-# The HTML_FILE_EXTENSION tag can be used to specify the file extension for
-# each generated HTML page (for example: .htm,.php,.asp). If it is left blank
-# doxygen will generate files with .html extension.
-
-HTML_FILE_EXTENSION = .html
-
-# The HTML_HEADER tag can be used to specify a personal HTML header for
-# each generated HTML page. If it is left blank doxygen will generate a
-# standard header.
-
-HTML_HEADER =
-
-# The HTML_FOOTER tag can be used to specify a personal HTML footer for
-# each generated HTML page. If it is left blank doxygen will generate a
-# standard footer.
-
-HTML_FOOTER =
-
-# The HTML_STYLESHEET tag can be used to specify a user-defined cascading
-# style sheet that is used by each HTML page. It can be used to
-# fine-tune the look of the HTML output. If the tag is left blank doxygen
-# will generate a default style sheet. Note that doxygen will try to copy
-# the style sheet file to the HTML output directory, so don't put your own
-# stylesheet in the HTML output directory as well, or it will be erased!
-
-HTML_STYLESHEET =
-
-# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes,
-# files or namespaces will be aligned in HTML using tables. If set to
-# NO a bullet list will be used.
-
-HTML_ALIGN_MEMBERS = YES
-
-# If the GENERATE_HTMLHELP tag is set to YES, additional index files
-# will be generated that can be used as input for tools like the
-# Microsoft HTML help workshop to generate a compressed HTML help file (.chm)
-# of the generated HTML documentation.
-
-GENERATE_HTMLHELP = NO
-
-# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can
-# be used to specify the file name of the resulting .chm file. You
-# can add a path in front of the file if the result should not be
-# written to the html output directory.
-
-CHM_FILE =
-
-# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can
-# be used to specify the location (absolute path including file name) of
-# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run
-# the HTML help compiler on the generated index.hhp.
-
-HHC_LOCATION =
-
-# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag
-# controls if a separate .chi index file is generated (YES) or that
-# it should be included in the master .chm file (NO).
-
-GENERATE_CHI = NO
-
-# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag
-# controls whether a binary table of contents is generated (YES) or a
-# normal table of contents (NO) in the .chm file.
-
-BINARY_TOC = NO
-
-# The TOC_EXPAND flag can be set to YES to add extra items for group members
-# to the contents of the HTML help documentation and to the tree view.
-
-TOC_EXPAND = NO
-
-# The DISABLE_INDEX tag can be used to turn on/off the condensed index at
-# top of each HTML page. The value NO (the default) enables the index and
-# the value YES disables it.
-
-DISABLE_INDEX = NO
-
-# This tag can be used to set the number of enum values (range [1..20])
-# that doxygen will group on one line in the generated HTML documentation.
-
-ENUM_VALUES_PER_LINE = 4
-
-# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be
-# generated containing a tree-like index structure (just like the one that
-# is generated for HTML Help). For this to work a browser that supports
-# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+,
-# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are
-# probably better off using the HTML help feature.
-
-GENERATE_TREEVIEW = NO
-
-# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be
-# used to set the initial width (in pixels) of the frame in which the tree
-# is shown.
-
-TREEVIEW_WIDTH = 250
-
-#---------------------------------------------------------------------------
-# configuration options related to the LaTeX output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will
-# generate Latex output.
-
-GENERATE_LATEX = NO
-
-# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put.
-# If a relative path is entered the value of OUTPUT_DIRECTORY will be
-# put in front of it. If left blank `latex' will be used as the default path.
-
-LATEX_OUTPUT = latex
-
-# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be
-# invoked. If left blank `latex' will be used as the default command name.
-
-LATEX_CMD_NAME = latex
-
-# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to
-# generate index for LaTeX. If left blank `makeindex' will be used as the
-# default command name.
-
-MAKEINDEX_CMD_NAME = makeindex
-
-# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact
-# LaTeX documents. This may be useful for small projects and may help to
-# save some trees in general.
-
-COMPACT_LATEX = NO
-
-# The PAPER_TYPE tag can be used to set the paper type that is used
-# by the printer. Possible values are: a4, a4wide, letter, legal and
-# executive. If left blank a4wide will be used.
-
-PAPER_TYPE = a4wide
-
-# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX
-# packages that should be included in the LaTeX output.
-
-EXTRA_PACKAGES =
-
-# The LATEX_HEADER tag can be used to specify a personal LaTeX header for
-# the generated latex document. The header should contain everything until
-# the first chapter. If it is left blank doxygen will generate a
-# standard header. Notice: only use this tag if you know what you are doing!
-
-LATEX_HEADER =
-
-# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated
-# is prepared for conversion to pdf (using ps2pdf). The pdf file will
-# contain links (just like the HTML output) instead of page references
-# This makes the output suitable for online browsing using a pdf viewer.
-
-PDF_HYPERLINKS = NO
-
-# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of
-# plain latex in the generated Makefile. Set this option to YES to get a
-# higher quality PDF documentation.
-
-USE_PDFLATEX = NO
-
-# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode.
-# command to the generated LaTeX files. This will instruct LaTeX to keep
-# running if errors occur, instead of asking the user for help.
-# This option is also used when generating formulas in HTML.
-
-LATEX_BATCHMODE = NO
-
-# If LATEX_HIDE_INDICES is set to YES then doxygen will not
-# include the index chapters (such as File Index, Compound Index, etc.)
-# in the output.
-
-LATEX_HIDE_INDICES = NO
-
-#---------------------------------------------------------------------------
-# configuration options related to the RTF output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output
-# The RTF output is optimized for Word 97 and may not look very pretty with
-# other RTF readers or editors.
-
-GENERATE_RTF = NO
-
-# The RTF_OUTPUT tag is used to specify where the RTF docs will be put.
-# If a relative path is entered the value of OUTPUT_DIRECTORY will be
-# put in front of it. If left blank `rtf' will be used as the default path.
-
-RTF_OUTPUT = rtf
-
-# If the COMPACT_RTF tag is set to YES Doxygen generates more compact
-# RTF documents. This may be useful for small projects and may help to
-# save some trees in general.
-
-COMPACT_RTF = NO
-
-# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated
-# will contain hyperlink fields. The RTF file will
-# contain links (just like the HTML output) instead of page references.
-# This makes the output suitable for online browsing using WORD or other
-# programs which support those fields.
-# Note: wordpad (write) and others do not support links.
-
-RTF_HYPERLINKS = NO
-
-# Load stylesheet definitions from file. Syntax is similar to doxygen's
-# config file, i.e. a series of assignments. You only have to provide
-# replacements, missing definitions are set to their default value.
-
-RTF_STYLESHEET_FILE =
-
-# Set optional variables used in the generation of an rtf document.
-# Syntax is similar to doxygen's config file.
-
-RTF_EXTENSIONS_FILE =
-
-#---------------------------------------------------------------------------
-# configuration options related to the man page output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_MAN tag is set to YES (the default) Doxygen will
-# generate man pages
-
-GENERATE_MAN = NO
-
-# The MAN_OUTPUT tag is used to specify where the man pages will be put.
-# If a relative path is entered the value of OUTPUT_DIRECTORY will be
-# put in front of it. If left blank `man' will be used as the default path.
-
-MAN_OUTPUT = man
-
-# The MAN_EXTENSION tag determines the extension that is added to
-# the generated man pages (default is the subroutine's section .3)
-
-MAN_EXTENSION = .3
-
-# If the MAN_LINKS tag is set to YES and Doxygen generates man output,
-# then it will generate one additional man file for each entity
-# documented in the real man page(s). These additional files
-# only source the real man page, but without them the man command
-# would be unable to find the correct page. The default is NO.
-
-MAN_LINKS = NO
-
-#---------------------------------------------------------------------------
-# configuration options related to the XML output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_XML tag is set to YES Doxygen will
-# generate an XML file that captures the structure of
-# the code including all documentation.
-
-GENERATE_XML = NO
-
-# The XML_OUTPUT tag is used to specify where the XML pages will be put.
-# If a relative path is entered the value of OUTPUT_DIRECTORY will be
-# put in front of it. If left blank `xml' will be used as the default path.
-
-XML_OUTPUT = xml
-
-# The XML_SCHEMA tag can be used to specify an XML schema,
-# which can be used by a validating XML parser to check the
-# syntax of the XML files.
-
-XML_SCHEMA =
-
-# The XML_DTD tag can be used to specify an XML DTD,
-# which can be used by a validating XML parser to check the
-# syntax of the XML files.
-
-XML_DTD =
-
-# If the XML_PROGRAMLISTING tag is set to YES Doxygen will
-# dump the program listings (including syntax highlighting
-# and cross-referencing information) to the XML output. Note that
-# enabling this will significantly increase the size of the XML output.
-
-XML_PROGRAMLISTING = YES
-
-#---------------------------------------------------------------------------
-# configuration options for the AutoGen Definitions output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will
-# generate an AutoGen Definitions (see autogen.sf.net) file
-# that captures the structure of the code including all
-# documentation. Note that this feature is still experimental
-# and incomplete at the moment.
-
-GENERATE_AUTOGEN_DEF = NO
-
-#---------------------------------------------------------------------------
-# configuration options related to the Perl module output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_PERLMOD tag is set to YES Doxygen will
-# generate a Perl module file that captures the structure of
-# the code including all documentation. Note that this
-# feature is still experimental and incomplete at the
-# moment.
-
-GENERATE_PERLMOD = NO
-
-# If the PERLMOD_LATEX tag is set to YES Doxygen will generate
-# the necessary Makefile rules, Perl scripts and LaTeX code to be able
-# to generate PDF and DVI output from the Perl module output.
-
-PERLMOD_LATEX = NO
-
-# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be
-# nicely formatted so it can be parsed by a human reader. This is useful
-# if you want to understand what is going on. On the other hand, if this
-# tag is set to NO the size of the Perl module output will be much smaller
-# and Perl will parse it just the same.
-
-PERLMOD_PRETTY = YES
-
-# The names of the make variables in the generated doxyrules.make file
-# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX.
-# This is useful so different doxyrules.make files included by the same
-# Makefile don't overwrite each other's variables.
-
-PERLMOD_MAKEVAR_PREFIX =
-
-#---------------------------------------------------------------------------
-# Configuration options related to the preprocessor
-#---------------------------------------------------------------------------
-
-# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will
-# evaluate all C-preprocessor directives found in the sources and include
-# files.
-
-ENABLE_PREPROCESSING = YES
-
-# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro
-# names in the source code. If set to NO (the default) only conditional
-# compilation will be performed. Macro expansion can be done in a controlled
-# way by setting EXPAND_ONLY_PREDEF to YES.
-
-MACRO_EXPANSION = NO
-
-# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES
-# then the macro expansion is limited to the macros specified with the
-# PREDEFINED and EXPAND_AS_DEFINED tags.
-
-EXPAND_ONLY_PREDEF = NO
-
-# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files
-# in the INCLUDE_PATH (see below) will be search if a #include is found.
-
-SEARCH_INCLUDES = YES
-
-# The INCLUDE_PATH tag can be used to specify one or more directories that
-# contain include files that are not input files but should be processed by
-# the preprocessor.
-
-INCLUDE_PATH =
-
-# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
-# patterns (like *.h and *.hpp) to filter out the header-files in the
-# directories. If left blank, the patterns specified with FILE_PATTERNS will
-# be used.
-
-INCLUDE_FILE_PATTERNS =
-
-# The PREDEFINED tag can be used to specify one or more macro names that
-# are defined before the preprocessor is started (similar to the -D option of
-# gcc). The argument of the tag is a list of macros of the form: name
-# or name=definition (no spaces). If the definition and the = are
-# omitted =1 is assumed. To prevent a macro definition from being
-# undefined via #undef or recursively expanded use the := operator
-# instead of the = operator.
-
-PREDEFINED =
-
-# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then
-# this tag can be used to specify a list of macro names that should be expanded.
-# The macro definition that is found in the sources will be used.
-# Use the PREDEFINED tag if you want to use a different macro definition.
-
-EXPAND_AS_DEFINED =
-
-# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then
-# doxygen's preprocessor will remove all function-like macros that are alone
-# on a line, have an all uppercase name, and do not end with a semicolon. Such
-# function macros are typically used for boiler-plate code, and will confuse
-# the parser if not removed.
-
-SKIP_FUNCTION_MACROS = YES
-
-#---------------------------------------------------------------------------
-# Configuration::additions related to external references
-#---------------------------------------------------------------------------
-
-# The TAGFILES option can be used to specify one or more tagfiles.
-# Optionally an initial location of the external documentation
-# can be added for each tagfile. The format of a tag file without
-# this location is as follows:
-# TAGFILES = file1 file2 ...
-# Adding location for the tag files is done as follows:
-# TAGFILES = file1=loc1 "file2 = loc2" ...
-# where "loc1" and "loc2" can be relative or absolute paths or
-# URLs. If a location is present for each tag, the installdox tool
-# does not have to be run to correct the links.
-# Note that each tag file must have a unique name
-# (where the name does NOT include the path)
-# If a tag file is not located in the directory in which doxygen
-# is run, you must also specify the path to the tagfile here.
-
-TAGFILES =
-
-# When a file name is specified after GENERATE_TAGFILE, doxygen will create
-# a tag file that is based on the input files it reads.
-
-GENERATE_TAGFILE =
-
-# If the ALLEXTERNALS tag is set to YES all external classes will be listed
-# in the class index. If set to NO only the inherited external classes
-# will be listed.
-
-ALLEXTERNALS = NO
-
-# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed
-# in the modules index. If set to NO, only the current project's groups will
-# be listed.
-
-EXTERNAL_GROUPS = YES
-
-# The PERL_PATH should be the absolute path and name of the perl script
-# interpreter (i.e. the result of `which perl').
-
-PERL_PATH = /usr/bin/perl
-
-#---------------------------------------------------------------------------
-# Configuration options related to the dot tool
-#---------------------------------------------------------------------------
-
-# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will
-# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base
-# or super classes. Setting the tag to NO turns the diagrams off. Note that
-# this option is superseded by the HAVE_DOT option below. This is only a
-# fallback. It is recommended to install and use dot, since it yields more
-# powerful graphs.
-
-CLASS_DIAGRAMS = YES
-
-# You can define message sequence charts within doxygen comments using the \msc
-# command. Doxygen will then run the mscgen tool (see http://www.mcternan.me.uk/mscgen/) to
-# produce the chart and insert it in the documentation. The MSCGEN_PATH tag allows you to
-# specify the directory where the mscgen tool resides. If left empty the tool is assumed to
-# be found in the default search path.
-
-MSCGEN_PATH =
-
-# If set to YES, the inheritance and collaboration graphs will hide
-# inheritance and usage relations if the target is undocumented
-# or is not a class.
-
-HIDE_UNDOC_RELATIONS = YES
-
-# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
-# available from the path. This tool is part of Graphviz, a graph visualization
-# toolkit from AT&T and Lucent Bell Labs. The other options in this section
-# have no effect if this option is set to NO (the default)
-
-HAVE_DOT = NO
-
-# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen
-# will generate a graph for each documented class showing the direct and
-# indirect inheritance relations. Setting this tag to YES will force the
-# the CLASS_DIAGRAMS tag to NO.
-
-CLASS_GRAPH = YES
-
-# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen
-# will generate a graph for each documented class showing the direct and
-# indirect implementation dependencies (inheritance, containment, and
-# class references variables) of the class with other documented classes.
-
-COLLABORATION_GRAPH = YES
-
-# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen
-# will generate a graph for groups, showing the direct groups dependencies
-
-GROUP_GRAPHS = YES
-
-# If the UML_LOOK tag is set to YES doxygen will generate inheritance and
-# collaboration diagrams in a style similar to the OMG's Unified Modeling
-# Language.
-
-UML_LOOK = NO
-
-# If set to YES, the inheritance and collaboration graphs will show the
-# relations between templates and their instances.
-
-TEMPLATE_RELATIONS = NO
-
-# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT
-# tags are set to YES then doxygen will generate a graph for each documented
-# file showing the direct and indirect include dependencies of the file with
-# other documented files.
-
-INCLUDE_GRAPH = YES
-
-# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and
-# HAVE_DOT tags are set to YES then doxygen will generate a graph for each
-# documented header file showing the documented files that directly or
-# indirectly include this file.
-
-INCLUDED_BY_GRAPH = YES
-
-# If the CALL_GRAPH and HAVE_DOT tags are set to YES then doxygen will
-# generate a call dependency graph for every global function or class method.
-# Note that enabling this option will significantly increase the time of a run.
-# So in most cases it will be better to enable call graphs for selected
-# functions only using the \callgraph command.
-
-CALL_GRAPH = NO
-
-# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then doxygen will
-# generate a caller dependency graph for every global function or class method.
-# Note that enabling this option will significantly increase the time of a run.
-# So in most cases it will be better to enable caller graphs for selected
-# functions only using the \callergraph command.
-
-CALLER_GRAPH = NO
-
-# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen
-# will graphical hierarchy of all classes instead of a textual one.
-
-GRAPHICAL_HIERARCHY = YES
-
-# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES
-# then doxygen will show the dependencies a directory has on other directories
-# in a graphical way. The dependency relations are determined by the #include
-# relations between the files in the directories.
-
-DIRECTORY_GRAPH = YES
-
-# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images
-# generated by dot. Possible values are png, jpg, or gif
-# If left blank png will be used.
-
-DOT_IMAGE_FORMAT = png
-
-# The tag DOT_PATH can be used to specify the path where the dot tool can be
-# found. If left blank, it is assumed the dot tool can be found in the path.
-
-DOT_PATH =
-
-# The DOTFILE_DIRS tag can be used to specify one or more directories that
-# contain dot files that are included in the documentation (see the
-# \dotfile command).
-
-DOTFILE_DIRS =
-
-# The MAX_DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of
-# nodes that will be shown in the graph. If the number of nodes in a graph
-# becomes larger than this value, doxygen will truncate the graph, which is
-# visualized by representing a node as a red box. Note that doxygen will always
-# show the root nodes and its direct children regardless of this setting.
-
-DOT_GRAPH_MAX_NODES = 50
-
-# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent
-# background. This is disabled by default, which results in a white background.
-# Warning: Depending on the platform used, enabling this option may lead to
-# badly anti-aliased labels on the edges of a graph (i.e. they become hard to
-# read).
-
-DOT_TRANSPARENT = NO
-
-# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output
-# files in one run (i.e. multiple -o and -T options on the command line). This
-# makes dot run faster, but since only newer versions of dot (>1.8.10)
-# support this, this feature is disabled by default.
-
-DOT_MULTI_TARGETS = NO
-
-# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will
-# generate a legend page explaining the meaning of the various boxes and
-# arrows in the dot generated graphs.
-
-GENERATE_LEGEND = YES
-
-# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will
-# remove the intermediate dot files that are used to generate
-# the various graphs.
-
-DOT_CLEANUP = YES
-
-#---------------------------------------------------------------------------
-# Configuration::additions related to the search engine
-#---------------------------------------------------------------------------
-
-# The SEARCHENGINE tag specifies whether or not a search engine should be
-# used. If set to NO the values of all tags below this one will be ignored.
-
-SEARCHENGINE = NO
+++ /dev/null
-Boost Software License - Version 1.0 - August 17th, 2003
-
-Permission is hereby granted, free of charge, to any person or organization
-obtaining a copy of the software and accompanying documentation covered by
-this license (the "Software") to use, reproduce, display, distribute,
-execute, and transmit the Software, and to prepare derivative works of the
-Software, and to permit third-parties to whom the Software is furnished to
-do so, all subject to the following:
-
-The copyright notices in the Software and this entire statement, including
-the above license grant, this restriction and the following disclaimer,
-must be included in all copies of the Software, in whole or in part, and
-all derivative works of the Software, unless such copies or derivative
-works are solely in the form of machine-executable object code generated by
-a source language processor.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
-SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
-FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
-ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-DEALINGS IN THE SOFTWARE.
+++ /dev/null
-// Copyright Timothy Goya 2007.
-// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at
-// http://www.boost.org/LICENSE_1_0.txt)
-
-#ifndef UNISON_VFS_FILE_SYSTEM_HPP
-#define UNISON_VFS_FILE_SYSTEM_HPP
-
-#include <string>
-#include <vector>
-
-namespace Unison
-{
- namespace VFS
- {
- class FileSystem
- {
- public:
- static FileSystem &get()
- {
- static FileSystem vfs;
- return vfs;
- }
-
- void follow_sym_links(bool follow);
-
- std::string get_dir_sep();
- std::string get_base_dir();
- std::string get_user_dir();
-
- std::string get_write_dir();
- void set_write_dir(const std::string &write_dir);
-
- void mount(const std::string &path, const std::string &mount_point = "/", bool append = false);
- void umount(const std::string &path);
- std::vector<std::string> get_search_path();
- std::string get_mount_point(const std::string &path);
-
- void mkdir(const std::string &dir);
- void rm(const std::string &filename);
- std::vector<std::string> ls(const std::string &path);
- bool exists(const std::string &filename);
- bool is_dir(const std::string &filename);
-
- std::string get_real_dir(const std::string &filename);
- private:
- FileSystem();
- ~FileSystem();
- };
- }
-}
-
-#endif
+++ /dev/null
-// Copyright Timothy Goya 2007.
-// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at
-// http://www.boost.org/LICENSE_1_0.txt)
-
-#ifndef UNISON_VFS_SDL_UTILS_HPP
-#define UNISON_VFS_SDL_UTILS_HPP
-
-#include <string>
-
-#include "SDL.h"
-
-namespace Unison
-{
- namespace VFS
- {
- namespace SDL
- {
- struct Utils
- {
- static SDL_RWops *open_physfs_in(const std::string &filename);
- };
- }
- }
-}
-
-#endif
+++ /dev/null
-// Copyright Timothy Goya 2007.
-// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at
-// http://www.boost.org/LICENSE_1_0.txt)
-
-#ifndef UNISON_VFS_STREAM_HPP
-#define UNISON_VFS_STREAM_HPP
-
-#include <iostream>
-
-namespace Unison
-{
- namespace VFS
- {
- class istream : public std::istream
- {
- public:
- istream(const std::string &filename);
- ~istream();
- };
-
- class ostream : public std::ostream
- {
- public:
- ostream(const std::string &filename);
- ~ostream();
- };
- }
-}
-
-#endif
+++ /dev/null
-// Copyright Timothy Goya 2007.
-// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at
-// http://www.boost.org/LICENSE_1_0.txt)
-
-#ifndef UNISON_VIDEO_BLITTABLE_HPP
-#define UNISON_VIDEO_BLITTABLE_HPP
-
-#include <unison/video/Coord.hpp>
-#include <unison/video/Rect.hpp>
-#include <unison/video/RenderOptions.hpp>
-
-namespace Unison
-{
- namespace Video
- {
- class Surface;
- class SurfaceSection;
- class Texture;
- class TextureSection;
- class DisplayList;
- class Blittable
- {
- public:
- virtual ~Blittable();
-
- /// Does a surface blit
- /// \param[in] src The source surface
- /// \param[in] dst_pos The position to blit to
- /// \param[in] src_rect The part of the source surface to blit from
- /// \param[in] options Extra blit options
- virtual void blit(const Surface &src, const Point &dst_pos = Point(), const Rect &src_rect = Rect(), const RenderOptions &options = RenderOptions()) = 0;
-
- /// Does a texture blit
- /// \param[in] src The source texture
- /// \param[in] dst_pos The position to blit to
- /// \param[in] src_rect The part of the source texture to blit from
- /// \param[in] options Extra blit options
- virtual void blit(const Texture &src, const Point &dst_pos = Point(), const Rect &src_rect = Rect(), const RenderOptions &options = RenderOptions()) = 0;
- /// Does a surface section blit
- /// \param[in] section The section to blit
- /// \param[in] dst_pos The position to blit to
- /// \param[in] options Extra blit options
- void blit_section(const SurfaceSection §ion, const Point &dst_pos = Point(), const RenderOptions &options = RenderOptions());
-
- /// Does a texture section blit
- /// \param[in] section The section to blit
- /// \param[in] dst_pos The position to blit to
- /// \param[in] options Extra blit options
- void blit_section(const TextureSection §ion, const Point &dst_pos = Point(), const RenderOptions &options = RenderOptions());
-
- /// \param[in] color The color
- /// \param[in] rect The portion to fill
- virtual void fill(const Color &color, const Rect &rect = Rect()) = 0;
-
- /// \param[in] color The color
- /// \param[in] rect The portion to fill
- virtual void fill_blend(const Color &color, const Rect &rect = Rect()) = 0;
-
- /// Draw the requests in the display list
- /// \param[in] list The display list
- void draw(const DisplayList &list);
- };
-
- /// A section of a blittable
- class BlittableSection : public Blittable
- {
- public:
- /// The image
- Blittable ℑ
-
- /// The clip rectangle
- Rect clip_rect;
-
- /// Create a section from an image and a rectangle
- /// \param[in] image The image
- /// \param[in] rect The clip rectangle
- BlittableSection(Blittable &image, const Rect &clip_rect = Rect());
-
- /// Does a clipped blit to the image
- /// \param[in] src The source surface
- /// \param[in] dst_pos The position to blit to
- /// \param[in] src_rect The part of the blit source to blit from
- /// \param[in] options Extra blit options
- void blit(const Surface &src, const Point &dst_pos = Point(), const Rect &src_rect = Rect(), const RenderOptions &options = RenderOptions());
-
- /// Does a clipped blit to the image
- /// \param[in] src The source texture
- /// \param[in] dst_pos The position to blit to
- /// \param[in] src_rect The part of the blit source to blit from
- /// \param[in] options Extra blit options
- void blit(const Texture &src, const Point &dst_pos = Point(), const Rect &src_rect = Rect(), const RenderOptions &options = RenderOptions());
-
- /// Fills the camera viewable portion with a color
- /// \param[in] color The color
- /// \param[in] rect The portion to fill
- void fill(const Color &color, const Rect &rect = Rect());
-
- /// Fills the camera viewable portion with a color using alpha blending
- /// \param[in] color The color
- /// \param[in] rect The portion to fill
- void fill_blend(const Color &color, const Rect &rect = Rect());
- };
- }
-}
-
-#endif
+++ /dev/null
-// Copyright Timothy Goya 2007.
-// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at
-// http://www.boost.org/LICENSE_1_0.txt)
-
-#ifndef UNISON_VIDEO_BLITTERS_HPP
-#define UNISON_VIDEO_BLITTERS_HPP
-
-#include <unison/video/Coord.hpp>
-#include <unison/video/RenderOptions.hpp>
-
-namespace Unison
-{
- namespace Video
- {
- class Rect;
- class Surface;
-
- struct Blitters
- {
- static void blit_upper(const Surface &src, Rect src_rect, Surface &dst, Point dst_pos, void (*blit_lower)(const Surface &, const Rect &, Surface &, const Point &));
-
- static void blit_lower_none(const Surface &src, const Rect &src_rect, Surface &dst, const Point &dst_pos);
-
- static void blit_lower_mask(const Surface &src, const Rect &src_rect, Surface &dst, const Point &dst_pos);
-
- static void blit_lower_alpha(const Surface &src, const Rect &src_rect, Surface &dst, const Point &dst_pos);
-
- static void blit_lower_add(const Surface &src, const Rect &src_rect, Surface &dst, const Point &dst_pos);
-
- static void blit_lower_mod(const Surface &src, const Rect &src_rect, Surface &dst, const Point &dst_pos);
-
- static void blit_blend_none(const Surface &src, const Rect &src_rect, Surface &dst, const Point &dst_pos)
- {
- blit_upper(src, src_rect, dst, dst_pos, blit_lower_none);
- }
-
- static void blit_blend_mask(const Surface &src, const Rect &src_rect, Surface &dst, const Point &dst_pos)
- {
- blit_upper(src, src_rect, dst, dst_pos, blit_lower_mask);
- }
-
- static void blit_blend_alpha(const Surface &src, const Rect &src_rect, Surface &dst, const Point &dst_pos)
- {
- blit_upper(src, src_rect, dst, dst_pos, blit_lower_alpha);
- }
-
- static void blit_blend_add(const Surface &src, const Rect &src_rect, Surface &dst, const Point &dst_pos)
- {
- blit_upper(src, src_rect, dst, dst_pos, blit_lower_add);
- }
-
- static void blit_blend_mod(const Surface &src, const Rect &src_rect, Surface &dst, const Point &dst_pos)
- {
- blit_upper(src, src_rect, dst, dst_pos, blit_lower_mod);
- }
-
- static void blit_blend(const Surface &src, const Rect &src_rect, Surface &dst, const Point &dst_pos, BlendMode blend)
- {
- switch(blend)
- {
- case BLEND_NONE:
- blit_blend_none(src, src_rect, dst, dst_pos);
- break;
- case BLEND_MASK:
- blit_blend_mask(src, src_rect, dst, dst_pos);
- break;
- case BLEND_ALPHA:
- blit_blend_alpha(src, src_rect, dst, dst_pos);
- break;
- case BLEND_ADD:
- blit_blend_add(src, src_rect, dst, dst_pos);
- break;
- case BLEND_MOD:
- blit_blend_mod(src, src_rect, dst, dst_pos);
- break;
- }
- }
- };
- }
-}
-
-#endif
+++ /dev/null
-// Copyright Timothy Goya 2007.
-// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at
-// http://www.boost.org/LICENSE_1_0.txt)
-
-#ifndef UNISON_VIDEO_COLOR_HPP
-#define UNISON_VIDEO_COLOR_HPP
-
-//#include "SDL_stdinc.h"
-
-namespace Unison
-{
- namespace Video
- {
- /// A RGBA color
- class Color
- {
- public:
- /// The red component (0x00 to 0xff)
- unsigned char red;
-
- /// The green component (0x00 to 0xff)
- unsigned char green;
-
- /// The blue component (0x00 to 0xff)
- unsigned char blue;
-
- /// The alpha component (0x00 to 0xff)
- unsigned char alpha;
-
- /// Default constructor (transparent black)
- Color() :
- red(),
- green(),
- blue(),
- alpha()
- {
- }
-
- /// Create a color from the given values
- /// \param[in] red The red component (0x00 to 0xff)
- /// \param[in] green The red component (0x00 to 0xff)
- /// \param[in] blue The red component (0x00 to 0xff)
- /// \param[in] alpha The red component (0x00 to 0xff)
- Color(unsigned char red, unsigned char green, unsigned char blue, unsigned char alpha = 0xff) :
- red(red),
- green(green),
- blue(blue),
- alpha(alpha)
- {
- }
-
- /// Equality operator
- /// \param[in] rhs The color to test
- /// \return Whether the colors are equal
- bool operator == (const Color &rhs) const
- {
- return red == rhs.red && green == rhs.green && blue == rhs.blue && alpha == rhs.alpha;
- }
-
- /// Equality operator
- /// \param[in] rhs The color to test
- /// \return Whether the colors are not equal
- bool operator != (const Color &rhs) const
- {
- return !(*this == rhs);
- }
-
- /// Less than operator
- /// \param[in] rhs The color to test
- /// \return Whether the color's grayscale value is less than the tested color
- bool operator < (const Color &rhs) const
- {
- return grayscale() < rhs.grayscale();
- }
-
- /// Calculate the grayscale value of the color
- /// \return The grayscale value (30% red, 59% green, 11% blue)
- unsigned char grayscale() const
- {
- return (red * 30 + green * 59 + blue * 11) / 100;
- }
-
- /// Opaque black (red = 0x00, green = 0x00, blue = 0x00)
- static const Color BLACK;
-
- /// Opaque red (red = 0xff, green = 0x00, blue = 0x00)
- static const Color RED;
-
- /// Opaque green (red = 0x00, green = 0xff, blue = 0x00)
- static const Color GREEN;
-
- /// Opaque blue (red = 0x00, green = 0x00, blue = 0xff)
- static const Color BLUE;
-
- /// Opaque cyan (red = 0x00, green = 0xff, blue = 0xff)
- static const Color CYAN;
-
- /// Opaque magenta (red = 0xff, green = 0x00, blue = 0xff)
- static const Color MAGENTA;
-
- /// Opaque yellow (red = 0xff, green = 0xff, blue = 0x00)
- static const Color YELLOW;
-
- /// Opaque white (red = 0xff, green = 0xff, blue = 0xff)
- static const Color WHITE;
- };
- }
-}
-
-#endif
+++ /dev/null
-// Copyright Timothy Goya 2007.
-// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at
-// http://www.boost.org/LICENSE_1_0.txt)
-
-#ifndef UNISON_VIDEO_COORD_HPP
-#define UNISON_VIDEO_COORD_HPP
-
-namespace Unison
-{
- namespace Video
- {
- /// A 2 dimensional quantity in rectangular space
- template<typename T> class Coord
- {
- public:
- /// The horizontal value
- T x;
-
- /// The vertical value
- T y;
-
- /// Default constructor (0, 0)
- Coord()
- : x(),
- y()
- {
- }
-
- /// Create a coordinate from the given values
- /// \param[in] x The horizontal value
- /// \param[in] y The vertical value
- Coord(T x, T y)
- : x(x),
- y(y)
- {
- }
-
- /// Copy constructor
- /// \param[in] rhs The source coordinate
- template<typename V> Coord(const Coord<V> &rhs)
- : x(rhs.x),
- y(rhs.y)
- {
- }
-
- /// Assignment operator
- /// \param[in] rhs The source color
- template<typename V> Coord<T> &operator =(const Coord<V> &rhs)
- {
- x = rhs.x;
- y = rhs.y;
- return *this;
- }
-
- /// Equality operator
- /// \param[in] rhs The coordinate to test
- /// \return Whether the coordinates are equal
- template<typename V> bool operator ==(const Coord<V> &rhs) const
- {
- return x == rhs.x && y == rhs.y;
- }
-
- /// Equality operator
- /// \param[in] rhs The coordinate to test
- /// \return Whether the coordinates are not equal
- template<typename V> bool operator !=(const Coord<V> &rhs) const
- {
- return !(*this == rhs);
- }
-
- /// Add two coordinates and assign to the left operand
- /// \param[in] rhs The right operand
- /// \return The resultant coordinate
- template<typename V> Coord<T> &operator +=(const Coord<V> &rhs)
- {
- x += rhs.x;
- y += rhs.y;
- return *this;
- }
-
- /// Subtract two coordinates and assign to the left operand
- /// \param[in] rhs The right operand
- /// \return The resultant coordinate
- template<typename V> Coord<T> &operator -=(const Coord<V> &rhs)
- {
- x -= rhs.x;
- y -= rhs.y;
- return *this;
- }
-
- /// Multiply two coordinates and assign to the left operand
- /// \param[in] rhs The right operand
- /// \return The resultant coordinate
- template<typename V> Coord<T> &operator *=(const Coord<V> &rhs)
- {
- x *= rhs.x;
- y *= rhs.y;
- return *this;
- }
-
- /// Multiply two coordinates and assign to the left operand
- /// \param[in] rhs The right operand
- /// \return The resultant coordinate
- template<typename V> Coord<T> &operator /=(const Coord<V> &rhs)
- {
- x /= rhs.x;
- y /= rhs.y;
- return *this;
- }
-
- /// Add a coordinate with a scalar and assign to the left operand
- /// \param[in] rhs The right operand
- /// \return The resultant coordinate
- template<typename V> Coord<T> &operator +=(const V &rhs)
- {
- x += rhs;
- y += rhs;
- return *this;
- }
-
- /// Subtract a coordinate with a scalar and assign to the left operand
- /// \param[in] rhs The right operand
- /// \return The resultant coordinate
- template<typename V> Coord<T> &operator -=(const V &rhs)
- {
- x -= rhs;
- y -= rhs;
- return *this;
- }
-
- /// Multiply a coordinate with a scalar and assign to the left operand
- /// \param[in] rhs The right operand
- /// \return The resultant coordinate
- template<typename V> Coord<T> &operator *=(const V &rhs)
- {
- x *= rhs;
- y *= rhs;
- return *this;
- }
-
- /// Divide a coordinate with a scalar and assign to the left operand
- /// \param[in] rhs The right operand
- /// \return The resultant coordinate
- template<typename V> Coord<T> &operator /=(const V &rhs)
- {
- x /= rhs;
- y /= rhs;
- return *this;
- }
-
- /*T length()
- {
- double sq = x*x + y*y;
- return T(sqrt(sq) + 0.5);
- }*/
- };
-
- /// Add two coordinates
- /// \param[in] lhs The left operand
- /// \param[in] rhs The right operand
- /// \return The resultant coordinate
- template<typename T, typename V> const Coord<T> operator +(const Coord<T> &lhs, const Coord<V> &rhs)
- {
- return Coord<T>(lhs) += rhs;
- }
-
- /// Subtract two coordinates
- /// \param[in] lhs The left operand
- /// \param[in] rhs The right operand
- /// \return The resultant coordinate
- template<typename T, typename V> const Coord<T> operator -(const Coord<T> &lhs, const Coord<V> &rhs)
- {
- return Coord<T>(lhs) -= rhs;
- }
-
- /// Multiply two coordinates
- /// \param[in] lhs The left operand
- /// \param[in] rhs The right operand
- /// \return The resultant coordinate
- template<typename T, typename V> const Coord<T> operator *(const Coord<T> &lhs, const Coord<V> &rhs)
- {
- return Coord<T>(lhs) *= rhs;
- }
-
- /// Divide two coordinates
- /// \param[in] lhs The left operand
- /// \param[in] rhs The right operand
- /// \return The resultant coordinate
- template<typename T, typename V> const Coord<T> operator /(const Coord<T> &lhs, const Coord<V> &rhs)
- {
- return Coord<T>(lhs) /= rhs;
- }
-
- /// Add a coordinate with a scalar
- /// \param[in] lhs The left operand
- /// \param[in] rhs The right operand
- /// \return The resultant coordinate
- template<typename T, typename V> const Coord<T> operator +(const Coord<T> &lhs, const V &rhs)
- {
- return Coord<T>(lhs) += rhs;
- }
-
- /// Subtract a coordinate with a scalar
- /// \param[in] lhs The left operand
- /// \param[in] rhs The right operand
- /// \return The resultant coordinate
- template<typename T, typename V> const Coord<T> operator -(const Coord<T> &lhs, const V &rhs)
- {
- return Coord<T>(lhs) -= rhs;
- }
-
- /// Multiply a coordinate with a scalar
- /// \param[in] lhs The left operand
- /// \param[in] rhs The right operand
- /// \return The resultant coordinate
- template<typename T, typename V> const Coord<T> operator *(const Coord<T> &lhs, const V &rhs)
- {
- return Coord<T>(lhs) *= rhs;
- }
-
- /// Divide a coordinate with a scalar
- /// \param[in] lhs The left operand
- /// \param[in] rhs The right operand
- /// \return The resultant coordinate
- template<typename T, typename V> const Coord<T> operator /(const Coord<T> &lhs, const V &rhs)
- {
- return Coord<T>(lhs) /= rhs;
- }
-
- /// Add a coordinate with a scalar
- /// \param[in] lhs The left operand
- /// \param[in] rhs The right operand
- /// \return The resultant coordinate
- template<typename V, typename T> const Coord<T> operator +(const V &lhs, const Coord<T> &rhs)
- {
- return Coord<T>(rhs) += lhs;
- }
-
- /// Subtract a coordinate with a scalar
- /// \param[in] lhs The left operand
- /// \param[in] rhs The right operand
- /// \return The resultant coordinate
- template<typename V, typename T> const Coord<T> operator -(const V &lhs, const Coord<T> &rhs)
- {
- return Coord<T>(rhs) -= lhs;
- }
-
- /// Multiply a coordinate with a scalar
- /// \param[in] lhs The left operand
- /// \param[in] rhs The right operand
- /// \return The resultant coordinate
- template<typename V, typename T> const Coord<T> operator *(const V &lhs, const Coord<T> &rhs)
- {
- return Coord<T>(rhs) *= lhs;
- }
-
- /// Divide a coordinate with a scalar
- /// \param[in] lhs The left operand
- /// \param[in] rhs The right operand
- /// \return The resultant coordinate
- template<typename V, typename T> const Coord<T> operator /(const V &lhs, const Coord<T> &rhs)
- {
- return Coord<T>(rhs) /= lhs;
- }
-
- /// A point in 2-dimensional space
- typedef Coord<int> Point;
-
- /// A 2-dimensional area
- typedef Coord<unsigned int> Area;
- }
-}
-
-#endif
+++ /dev/null
-// Copyright Timothy Goya 2007.
-// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at
-// http://www.boost.org/LICENSE_1_0.txt)
-
-#ifndef UNISON_VIDEO_DISPLAY_LIST_HPP
-#define UNISON_VIDEO_DISPLAY_LIST_HPP
-
-#include <unison/video/Blittable.hpp>
-#include <unison/video/RenderOptions.hpp>
-#include <unison/video/Surface.hpp>
-#include <unison/video/Texture.hpp>
-
-#include <string>
-#include <vector>
-#include <map>
-
-namespace Unison
-{
- namespace Video
- {
- class DisplayList : public Blittable
- {
- public:
- DisplayList() :
- requests()
- {
- }
-
- DisplayList(const std::map<int, DisplayList> &layers) :
- requests(std::for_each(layers.begin(), layers.end(), Collator()).requests)
- {
- std::for_each(requests.begin(), requests.end(), std::mem_fun(&Unison::Video::DisplayList::Request::ref));
- }
-
- DisplayList(const DisplayList &rhs) :
- Blittable(),
- requests(rhs.requests)
- {
- std::for_each(requests.begin(), requests.end(), std::mem_fun(&Unison::Video::DisplayList::Request::ref));
- }
-
- ~DisplayList()
- {
- std::for_each(requests.begin(), requests.end(), std::mem_fun(&Unison::Video::DisplayList::Request::unref));
- }
-
- DisplayList &operator = (const DisplayList &rhs)
- {
- std::for_each(rhs.requests.begin(), rhs.requests.end(), std::mem_fun(&Unison::Video::DisplayList::Request::ref));
- std::for_each(requests.begin(), requests.end(), std::mem_fun(&Unison::Video::DisplayList::Request::unref));
- requests = rhs.requests;
- return *this;
- }
-
- /// Add a request to do a surface-to-image blit
- /// \param[in] src The source surface
- /// \param[in] dst_pos The position to blit to
- /// \param[in] src_rect The part of the source surface to blit from
- /// \param[in] options Extra blit options
- /// \param[in] layer The drawing layer to sort by
- void blit(const Surface &src, const Point &dst_pos = Point(), const Rect &src_rect = Rect(), const RenderOptions &options = RenderOptions())
- {
- add_request(new SurfaceBlitRequest(src, dst_pos, src_rect, options));
- }
-
- /// Add a request to do a texture-to-image blit
- /// \param[in] src The source texture
- /// \param[in] dst_pos The position to blit to
- /// \param[in] src_rect The part of the source texture to blit from
- /// \param[in] options Extra blit options
- /// \param[in] layer The drawing layer to sort by
- void blit(const Texture &src, const Point &dst_pos = Point(), const Rect &src_rect = Rect(), const RenderOptions &options = RenderOptions())
- {
- add_request(new TextureBlitRequest(src, dst_pos, src_rect, options));
- }
-
- /// Add a request to fill a portion of the image
- /// \param[in] color The color
- /// \param[in] rect The portion to fill
- /// \param[in] layer The drawing layer to sort by
- void fill(const Color &color, const Rect &rect = Rect())
- {
- add_request(new FillRequest(color, rect));
- }
-
- /// Add a request to blended fill a portion of the image
- /// \param[in] color The color
- /// \param[in] rect The portion to fill
- /// \param[in] layer The drawing layer to sort by
- void fill_blend(const Color &color, const Rect &rect = Rect())
- {
- add_request(new BlendedFillRequest(color, rect));
- }
-
- /// Draw requests in display list onto blittable
- /// \param[in] dst The destination blittable
- void draw(Blittable *dst) const
- {
- std::for_each(requests.begin(), requests.end(), std::bind2nd(std::mem_fun(&Request::do_request), dst));
- }
-
- void clear()
- {
- requests.clear();
- }
-
- class Request
- {
- public:
- Request() :
- refcount(1)
- {
- }
-
- virtual ~Request()
- {
- }
-
- virtual void do_request(Blittable *dst) const = 0;
-
- void ref()
- {
- refcount++;
- }
-
- void unref()
- {
- assert(refcount > 0);
- refcount--;
- if(refcount == 0)
- {
- delete this;
- }
- }
- private:
- int refcount;
- };
-
- void add_request(Request *request)
- {
- requests.push_back(request);
- }
- private:
- class Collator
- {
- public:
- void operator () (std::pair<int, DisplayList> pair)
- {
- requests.insert(requests.end(), pair.second.requests.begin(), pair.second.requests.end());
- }
- std::vector<Request *> requests;
- };
-
- class SurfaceBlitRequest : public Request
- {
- public:
- SurfaceBlitRequest(const Surface &src, const Point &dst_pos, const Rect &src_rect, const RenderOptions &options)
- : src(src),
- dst_pos(dst_pos),
- src_rect(src_rect),
- options(options)
- {
- }
-
- void do_request(Blittable *dst) const
- {
- dst->blit(src, dst_pos, src_rect, options);
- }
- private:
- Surface src;
- Point dst_pos;
- Rect src_rect;
- RenderOptions options;
- };
-
- class TextureBlitRequest : public Request
- {
- public:
- TextureBlitRequest(const Texture &src, const Point &dst_pos, const Rect &src_rect, const RenderOptions &options)
- : src(src),
- dst_pos(dst_pos),
- src_rect(src_rect),
- options(options)
- {
- }
-
- void do_request(Blittable *dst) const
- {
- dst->blit(src, dst_pos, src_rect, options);
- }
- private:
- Texture src;
- Point dst_pos;
- Rect src_rect;
- RenderOptions options;
- };
-
- class FillRequest : public Request
- {
- public:
- FillRequest(const Color &color, const Rect &rect)
- : color(color),
- rect(rect)
- {
- }
-
- void do_request(Blittable *dst) const
- {
- dst->fill(color, rect);
- }
- private:
- Color color;
- Rect rect;
- };
-
- class BlendedFillRequest : public Request
- {
- public:
- BlendedFillRequest(const Color &color, const Rect &rect)
- : color(color),
- rect(rect)
- {
- }
-
- void do_request(Blittable *dst) const
- {
- dst->fill_blend(color, rect);
- }
- private:
- Color color;
- Rect rect;
- };
-
- std::vector<Request *> requests;
- };
- }
-}
-
-#endif
+++ /dev/null
-// Copyright Timothy Goya 2007.
-// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at
-// http://www.boost.org/LICENSE_1_0.txt)
-
-#ifndef UNISON_VIDEO_RECT_HPP
-#define UNISON_VIDEO_RECT_HPP
-
-#include <algorithm>
-
-#include <unison/video/Coord.hpp>
-
-#include "SDL.h"
-
-namespace Unison
-{
- namespace Video
- {
- /// Represents a rectangular area
- class Rect
- {
- public:
- /// The position of the rectangle
- Point pos;
-
- /// The size of the rectangle
- Area size;
-
- /// Default constructor
- Rect() :
- pos(),
- size(),
- rect()
- {
- }
-
- /// Create a rectangle from the given coordinates
- /// \param[in] pos The position of the rectangle
- /// \param[in] size The size of the rectangle
- Rect(const Point &pos, const Area &size) :
- pos(pos),
- size(size),
- rect()
- {
- }
-
- /// Create a rectangle from the given values
- /// \param[in] x The x-position of the rectangle
- /// \param[in] y The y-position of the rectangle
- /// \param[in] w The width of the rectangle
- /// \param[in] h The height of the rectangle
- Rect(int x, int y, int w, int h) :
- pos(x, y),
- size(w, h),
- rect()
- {
- }
-
- /// Equality operator
- /// \param[in] rhs The rectangle to test
- /// \return Whether the rectangles are equal
- bool operator == (const Rect &rhs) const
- {
- return pos == rhs.pos && size == rhs.size;
- }
-
- /// Equality operator
- /// \param[in] rhs The rectangle to test
- /// \return Whether the rectangles are not equal
- bool operator != (const Rect &rhs) const
- {
- return !(*this == rhs);
- }
-
- /// Get the left edge of the rectnagle
- /// \return The location of the left edge
- int get_left() const
- {
- return pos.x;
- }
-
- /// Get the top edge of the rectnagle
- /// \return The location of the top edge
- int get_top() const
- {
- return pos.y;
- }
-
- /// Get the right edge of the rectnagle
- /// \return The location of the right edge
- int get_right() const
- {
- return pos.x + size.x;
- }
-
- /// Get the bottom edge of the rectnagle
- /// \return The location of the bottom edge
- int get_bottom() const
- {
- return pos.y + size.y;
- }
-
- /// Calculate the overlap between the rectangles
- /// \param[in] rhs The rectangle to check
- /// \return The part of the rectangle that is overlapping
- Rect get_overlap(const Rect &rhs)
- {
- if(*this == Rect())
- {
- return rhs;
- }
- if(rhs == Rect())
- {
- return *this;
- }
- Rect overlap;
- if(get_left() < rhs.get_right())
- {
- overlap.pos.x = std::max(get_left(), rhs.get_left());
- }
- else
- {
- return Rect();
- }
- if(rhs.get_left() < get_right())
- {
- overlap.size.x = std::min(rhs.get_right(), get_right()) - overlap.pos.x;
- }
- else
- {
- return Rect();
- }
- if(get_top() < rhs.get_bottom())
- {
- overlap.pos.y = std::max(get_top(), rhs.get_top());
- }
- else
- {
- return Rect();
- }
- if(rhs.get_top() < get_bottom())
- {
- overlap.size.y = std::min(rhs.get_bottom(), get_bottom()) - overlap.pos.y;
- }
- else
- {
- return Rect();
- }
- return overlap;
- }
-
- /// Allow rectangles to be treated like SDL_Rect
- /// \return The equavalent SDL_Rect
- operator SDL_Rect () const
- {
- rect.x = pos.x;
- rect.y = pos.y;
- rect.w = size.x;
- rect.h = size.y;
- return rect;
- }
-
- /// Allow rectangles to be treated like SDL_Rect
- /// \return The internal SDL_Rect
- SDL_Rect *operator &() const
- {
- if(*this == Rect())
- {
- return 0;
- }
- else
- {
- rect.x = pos.x;
- rect.y = pos.y;
- rect.w = size.x;
- rect.h = size.y;
- return ▭
- }
- }
- private:
- mutable SDL_Rect rect;
- };
- }
-}
-
-#endif
+++ /dev/null
-// Copyright Timothy Goya 2007.
-// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at
-// http://www.boost.org/LICENSE_1_0.txt)
-
-#ifndef UNISON_VIDEO_RENDER_OPTIONS_HPP
-#define UNISON_VIDEO_RENDER_OPTIONS_HPP
-
-#include <unison/video/Color.hpp>
-
-namespace Unison
-{
- namespace Video
- {
- /// The color blending modes
- enum BlendMode
- {
- BLEND_NONE,
- BLEND_MASK,
- BLEND_ALPHA,
- BLEND_ADD,
- BLEND_MOD
- };
-
- /// Extra rendering options
- class RenderOptions
- {
- public:
- /// The additional color value used (alpha is ignored)
- Color color;
-
- /// The additional alpha value used
- unsigned char alpha;
-
- /// The blend mode used
- BlendMode blend;
-
- /// Flip rendering horizontally
- bool h_flip;
-
- /// Flip rendering vertically
- bool v_flip;
-
- /// Default constructor
- RenderOptions() :
- color(Color::WHITE),
- alpha(0xff),
- blend(BLEND_ALPHA),
- h_flip(false),
- v_flip(false)
- {
- }
-
- /// Create a set of render options with the given data
- /// \param[in] color The color modulation (alpha ignored)
- RenderOptions(const Color &color) :
- color(color),
- alpha(0xff),
- blend(BLEND_ALPHA),
- h_flip(false),
- v_flip(false)
- {
- }
-
- /// Create a set of render options with the given data
- /// \param[in] blend The blend mode
- RenderOptions(BlendMode blend) :
- color(Color::WHITE),
- alpha(0xff),
- blend(blend),
- h_flip(false),
- v_flip(false)
- {
- }
- };
- }
-}
-
-#endif
+++ /dev/null
-// Copyright Timothy Goya 2007.
-// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at
-// http://www.boost.org/LICENSE_1_0.txt)
-
-#ifndef UNISON_VIDEO_RENDERERS_HPP
-#define UNISON_VIDEO_RENDERERS_HPP
-
-#include <string>
-#include <vector>
-
-namespace Unison
-{
- namespace Video
- {
- namespace Backend
- {
- class Renderer;
- }
- /// Manages renderers
- class Renderers
- {
- public:
- /// Initialize and retrieve singleton
- static Renderers &get();
-
- /// Set the backend renderer to use
- /// \param[in] name The name of a renderer backend (can be "auto")
- void set_renderer(const std::string &name);
-
- /// Get the current backend renderer
- /// \return The current backend renderer
- Backend::Renderer &get_renderer();
-
- /// Add a backend renderer
- /// \param[in] renderer The backend renderer to add
- void add_renderer(Backend::Renderer *renderer);
- private:
- /// The auto renderer backend
- Backend::Renderer *auto_renderer;
-
- /// The current renderer backend
- Backend::Renderer *renderer;
-
- /// The known backend renderers
- std::vector<Backend::Renderer *> renderers;
-
- /// Default constructor
- Renderers();
-
- /// Destructor
- ~Renderers();
- };
- }
-}
-
-#endif
+++ /dev/null
-// Copyright Timothy Goya 2007.
-// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at
-// http://www.boost.org/LICENSE_1_0.txt)
-
-#ifndef UNISON_VIDEO_SURFACE_HPP
-#define UNISON_VIDEO_SURFACE_HPP
-
-#include <unison/video/Blittable.hpp>
-#include <unison/video/RenderOptions.hpp>
-
-#include <string>
-#include <istream>
-#include <assert.h>
-
-namespace Unison
-{
- namespace Video
- {
- class Color;
- class Rect;
- class Texture;
- /// An image that is optimized for easy manipulation
- class Surface : public Blittable
- {
- public:
- /// Default constructor
- Surface();
-
- /// Create a Surface from an input stream
- /// \param[in] src The input stream
- Surface(std::istream &stream);
-
- /// Create a Surface from an input stream
- /// \param[in] src The input stream
- /// \param[in] colorkey The colorkey used by the file
- Surface(std::istream &stream, const Color &colorkey);
-
- /// Opens image file indicated by filename
- /// \param[in] filename The filename of the image file
- Surface(const std::string &filename);
-
- /// Opens image file indicated by filename and use the specified color key
- /// \param[in] filename The filename of the image file
- /// \param[in] colorkey The colorkey used by the file
- Surface(const std::string &filename, const Color &colorkey);
-
- /// Creates Surface of indicated dimensions
- /// \param[in] size The size of the desired surface
- Surface(const Area &size);
-
- /// Copy constructor
- /// \param[in] rhs The source surface
- Surface(const Surface &rhs);
-
- /// Destructor
- ~Surface();
-
- /// Assignment operator
- /// \param[in] rhs The source surface
- Surface &operator =(const Surface &rhs);
-
- /// Saves the surface to file
- /// \param[in] filename The destination filename
- void save(const std::string &filename) const;
-
- /// Retrieves the window's size
- /// \return The size of the surface
- Area get_size() const
- {
- return pixels ? pixels->size : Area();
- }
-
- /// Retrieves a pixel at the specified coordinates
- /// \param[in] pos The position of the pixel to retrieve
- /// \return The pixel at the specified position
- Color &get_pixel(const Point &pos)
- {
- cow();
- assert(pixels);
- return pixels->buffer[pos.y * pixels->size.x + pos.x];
- }
-
- /// Retrieves the pixel color at the specified coordinates
- /// \param[in] x The x position of the pixel to retrieve
- /// \param[in] y The y position of the pixel to retrieve
- /// \return The color of the pixel at the specified position
- Color& get_pixel(int x, int y)
- {
- cow();
- assert(pixels);
- return pixels->buffer[y * pixels->size.x + x];
- }
-
- /// Retrieves the pixel color at the specified coordinates
- /// \param[in] pos The position of the pixel to retrieve
- /// \return The color of the pixel at the specified position
- Color get_pixel(const Point &pos) const
- {
- assert(pixels);
- return pixels->buffer[pos.y * pixels->size.x + pos.x];
- }
-
- /// Retrieves the pixel color at the specified coordinates
- /// \param[in] x The x position of the pixel to retrieve
- /// \param[in] y The y position of the pixel to retrieve
- /// \return The color of the pixel at the specified position
- Color get_pixel(int x, int y) const
- {
- assert(pixels);
- return pixels->buffer[y * pixels->size.x + x];
- }
-
- /// Acquire the pixel color buffer
- /// \return the pixel color buffer
- Color *get_pixels()
- {
- cow();
- assert(pixels);
- return pixels->buffer;
- }
-
- /// Acquire the pixel color buffer
- /// \return the pixel color buffer
- const Color *get_pixels() const
- {
- assert(pixels);
- return pixels->buffer;
- }
-
- /// Does a surface-to-surface blit
- /// \param[in] src The source surface
- /// \param[in] dst_pos The position to blit to
- /// \param[in] src_rect The part of the source surface to blit from
- /// \param[in] options Extra blit options
- void blit(const Surface &src, const Point &dst_pos = Point(), const Rect &src_rect = Rect(), const RenderOptions &options = RenderOptions());
-
- /// Does a texture-to-surface blit
- /// \param[in] src The source texture
- /// \param[in] dst_pos The position to blit to
- /// \param[in] src_rect The part of the source texture to blit from
- /// \param[in] options Extra blit options
- void blit(const Texture &src, const Point &dst_pos = Point(), const Rect &src_rect = Rect(), const RenderOptions &options = RenderOptions());
-
- /// Fills a portion of the image with the given color
- /// \param[in] color The color
- /// \param[in] rect The portion to fill
- void fill(const Color &color, const Rect &rect = Rect());
-
- /// Fills and alpha blend a portion of the image with the given color
- /// \param[in] color The color
- /// \param[in] rect The portion to fill
- void fill_blend(const Color &color, const Rect &rect = Rect());
-
- /// Scale the surface by a factor of (numerator / denominator)
- /// \param[in] numerator The numerator of the scale factor
- /// \param[in] denominator The denominator of the scale factor
- /// \return The scaled surface
- Surface scale(unsigned int numerator, unsigned int denominator) const;
-
- /// Flip the surface horizontally
- /// \return The flipped surface
- Surface h_flip() const;
-
- /// Flip the surface vertically
- /// \return The flipped surface
- Surface v_flip() const;
-
- /// Modulate the image with a color
- /// \return The modulated surface
- Surface modulate(const Color &color) const;
-
- /// Modulate the image with an alpha
- /// \return The modulated surface
- Surface modulate(unsigned char alpha) const;
- private:
- /// Copy on Write
- void cow();
-
- class PixelBuffer
- {
- public:
- PixelBuffer(Area size)
- : buffer(0),
- size(size),
- refcount(1)
- {
- if(size != Area())
- {
- buffer = new Color[size.x * size.y];
- }
- }
-
- ~PixelBuffer()
- {
- delete buffer;
- }
-
- void ref()
- {
- refcount++;
- }
-
- void unref()
- {
- assert(refcount > 0);
- refcount--;
- if(refcount == 0)
- {
- delete this;
- }
- }
-
- Color *buffer;
- Area size;
- int refcount;
- };
-
- /// The pixels
- PixelBuffer *pixels;
- };
-
- /// A section of a surface
- class SurfaceSection
- {
- public:
- /// The image
- Surface image;
-
- /// The clip rectangle
- Rect clip_rect;
-
- /// Create a section from an image and a rectangle
- /// \param[in] image The image
- /// \param[in] rect The clip rectangle
- SurfaceSection(const Surface &image = Surface(), const Rect &clip_rect = Rect()) :
- image(image),
- clip_rect(clip_rect)
- {
- }
- };
- }
-}
-
-#endif
+++ /dev/null
-// Copyright Timothy Goya 2007.
-// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at
-// http://www.boost.org/LICENSE_1_0.txt)
-
-#ifndef UNISON_VIDEO_TEXTURE_HPP
-#define UNISON_VIDEO_TEXTURE_HPP
-
-#include <unison/video/Blittable.hpp>
-#include <unison/video/Surface.hpp>
-#include <unison/video/Coord.hpp>
-
-#include <string>
-#include <vector>
-#include <set>
-
-namespace Unison
-{
- namespace Video
- {
- typedef unsigned int TextureID;
- static const TextureID INVALID_TEXTURE_ID = ~0;
- /// An image that is optimized for fast drawing
- class Texture : public Blittable
- {
- public:
- /// Default constructor
- Texture();
-
- /// Opens image file indicated by filename
- /// \param[in] filename The filename of the image file
- Texture(const std::string &filename);
-
- /// Opens image file indicated by filename and use the specified colorkey
- /// \param[in] filename The filename of the image file
- /// \param[in] colorkey The colorkey used by the file
- Texture(const std::string &filename, const Color &colorkey);
-
- /// Create a texture from the given surface
- /// \param[in] surface The surface to optimize
- Texture(const Surface &surface);
-
- /// Copy constructor
- /// \param[in] rhs The source texture
- Texture(const Texture &rhs);
-
- /// Destructor
- ~Texture();
-
- /// Assignment operator
- /// \param[in] rhs The source surface
- Texture &operator =(const Texture &rhs);
-
- /// Retrieves the texture's id
- /// \return The id of the surface
- TextureID get_id() const;
-
- /// Retrieves the texture's size
- /// \return The size of the surface
- Area get_size() const;
-
- /// Does a surface-to-texture blit
- /// \param[in] src The source surface
- /// \param[in] dst_pos The position to blit to
- /// \param[in] src_rect The part of the source surface to blit from
- /// \param[in] options Extra blit options
- void blit(const Surface &src, const Point &dst_pos = Point(), const Rect &src_rect = Rect(), const RenderOptions &options = RenderOptions());
-
- /// Does a texture-to-texture blit
- /// \param[in] src The source texture
- /// \param[in] dst_pos The position to blit to
- /// \param[in] src_rect The part of the source texture to blit from
- /// \param[in] options Extra blit options
- void blit(const Texture &src, const Point &dst_pos = Point(), const Rect &src_rect = Rect(), const RenderOptions &options = RenderOptions());
-
- /// Fills a portion of the image with the given color
- /// \param[in] color The color
- /// \param[in] rect The portion to fill
- void fill(const Color &color, const Rect &rect = Rect());
-
- /// Fills and alpha blend a portion of the image with the given color
- /// \param[in] color The color
- /// \param[in] rect The portion to fill
- void fill_blend(const Color &color, const Rect &rect = Rect());
-
- static std::vector<Surface> save_textures();
- static void load_textures(const std::vector<Surface> &surfaces);
-
- /// Recover previously used but now unused texture IDs
- static void recover_texture_ids();
- private:
- /// Copy on Write
- void cow();
-
- /// The texture ID
- TextureID id;
-
- /// All the textures in existence
- static std::set<Texture *> textures;
- };
-
- /// A section of a texture
- class TextureSection
- {
- public:
- /// The image
- Texture image;
-
- /// The clip rectangle
- Rect clip_rect;
-
- /// Create a section from an image and a rectangle
- /// \param[in] image The image
- /// \param[in] rect The clip rectangle
- TextureSection(const Texture &image = Texture(), const Rect &clip_rect = Rect()) :
- image(image),
- clip_rect(clip_rect)
- {
- }
- };
- }
-}
-
-#endif
+++ /dev/null
-// Copyright Timothy Goya 2007.
-// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at
-// http://www.boost.org/LICENSE_1_0.txt)
-
-#ifndef UNISON_VIDEO_WINDOW_HPP
-#define UNISON_VIDEO_WINDOW_HPP
-
-#include <unison/video/Blittable.hpp>
-#include <unison/video/DisplayList.hpp>
-#include <unison/video/RenderOptions.hpp>
-#include <unison/video/Surface.hpp>
-#include <unison/video/Texture.hpp>
-
-#include <string>
-#include <vector>
-#include <map>
-
-namespace Unison
-{
- namespace Video
- {
- class Color;
- class Rect;
- class Texture;
- class Surface;
- namespace Backend
- {
- class Window;
- }
- /// Window management singleton
- class Window : public Blittable
- {
- public:
- /// Initialize and retrieve singleton
- static Window &get();
-
- /// Set the logical size of the window
- /// \param[in] logical_size The logical size of the window
- void set_logical_size(const Area &logical_size);
-
- /// Get the logical size of the window
- /// \return The logical size of the window
- Area get_logical_size() const;
-
- /// Open the window
- /// \param[in] size The size of the window
- /// \param[in] fullscreen Whether to open in fullscreen mode
- void open(const Area &size, bool fullscreen = false);
-
- /// Take a screenshot of the window
- /// \param[in] filename The destination filename
- void take_screenshot(const std::string &filename) const;
-
- /// Flip request buffers
- /// \note Should be called only once per frame!
- void flip();
-
- /// Redraw requests
- void redraw();
-
- /// Set window title
- void set_title(const std::string &title);
-
- /// Set window icon
- void set_icon(const Surface &icon);
-
- /// Retrieves the window's size
- /// \return The size of the window
- Area get_size() const;
-
- /// Queries whether the window is open
- /// \return Whether the window is open
- bool is_open() const;
-
- /// Queries whether the window is in fullscreen mode
- /// \return Whether the window is fullscreen
- bool is_fullscreen() const;
-
- /// Does a surface-to-window blit
- /// \param[in] src The source surface
- /// \param[in] dst_pos The position to blit to
- /// \param[in] src_rect The part of the source surface to blit from
- /// \param[in] options Extra blit options
- void blit(const Surface &src, const Point &dst_pos = Point(), const Rect &src_rect = Rect(), const RenderOptions &options = RenderOptions())
- {
- layers[0].blit(src, dst_pos, src_rect, options);
- }
-
- /// Does a texture-to-window blit
- /// \param[in] src The source texture
- /// \param[in] dst_pos The position to blit to
- /// \param[in] src_rect The part of the source texture to blit from
- /// \param[in] options Extra blit options
- void blit(const Texture &src, const Point &dst_pos = Point(), const Rect &src_rect = Rect(), const RenderOptions &options = RenderOptions())
- {
- layers[0].blit(src, dst_pos, src_rect, options);
- }
-
- /// Fills a portion of the window with the given color
- /// \param[in] color The color
- /// \param[in] rect The portion to fill
- void fill(const Color &color, const Rect &rect = Rect())
- {
- layers[0].fill(color, rect);
- }
-
- /// Fills and alpha blend a portion of the window with the given color
- /// \param[in] color The color
- /// \param[in] rect The portion to fill
- void fill_blend(const Color &color, const Rect &rect = Rect())
- {
- layers[0].fill_blend(color, rect);
- }
-
- DisplayList &operator [] (int layer)
- {
- return layers[layer];
- }
- private:
- /// The logical size of the window
- Area logical_size;
-
- /// The title of the window
- std::string title;
-
- /// The window icon
- Surface icon;
-
- /// The window
- Backend::Window *window;
-
- /// Display list currently being drawn
- DisplayList list;
-
- /// Layers of pending display lists
- std::map<int, DisplayList> layers;
-
- /// Default constructor
- Window();
-
- /// Destructor
- ~Window();
- };
- }
-}
-
-#endif
+++ /dev/null
-// Copyright Timothy Goya 2007.
-// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at
-// http://www.boost.org/LICENSE_1_0.txt)
-
-#ifndef UNISON_VIDEO_BACKEND_RENDERER_HPP
-#define UNISON_VIDEO_BACKEND_RENDERER_HPP
-
-#include <unison/video/Coord.hpp>
-
-#include <string>
-#include <istream>
-
-namespace Unison
-{
- namespace Video
- {
- class Surface;
- class Texture;
- class Window;
- class Color;
- class Rect;
- class RenderOptions;
-
- namespace Backend
- {
- class Texture;
- class Window;
- /// Backend-specific renderer interface
- class Renderer
- {
- public:
- /// Destructor
- virtual ~Renderer()
- {
- }
-
- /// Initialize the backend
- virtual void init() = 0;
-
- /// Cleanup the backend
- virtual void quit() = 0;
-
- /// Get the name of the renderer
- /// \return the name of the renderer
- virtual std::string get_name() = 0;
-
- /// Check if the backend is usable
- /// \return Whether the backend is usable
- virtual bool is_usable() = 0;
-
- virtual Surface load_surface(const std::string &filename) = 0;
- virtual Surface load_surface(const std::string &filename, const Color &colorkey) = 0;
-
- virtual void save_surface(const Surface &surface, const std::string &filename) = 0;
-
- /// Does a surface-to-surface blit
- /// \param[in] src The source surface
- /// \param[in] src_rect The part of the source surface to blit from
- /// \param[in] dst The destination surface
- /// \param[in] dst_pos The position to blit to
- /// \param[in] options Extra blit options
- virtual void blit(const Surface &src, const Rect &src_rect, Surface &dst, const Point &dst_pos, const RenderOptions &options) = 0;
-
- /// Does a texture-to-surface blit
- /// \param[in] src The source texture
- /// \param[in] src_rect The part of the source texture to blit from
- /// \param[in] dst The destination surface
- /// \param[in] dst_pos The position to blit to
- /// \param[in] options Extra blit options
- virtual void blit(Texture *src, const Rect &src_rect, Surface &dst, const Point &dst_pos, const RenderOptions &options) = 0;
-
- /// Fills a portion of a surface with the given color
- /// \param[in] dst The destination surface
- /// \param[in] color The color
- /// \param[in] rect The portion to fill
- virtual void fill(Surface &dst, const Color &color, const Rect &rect) = 0;
-
- /// Fills with alpha blend a portion of a surface with the given color
- /// \param[in] dst The destination surface
- /// \param[in] color The color
- /// \param[in] rect The portion to fill
- virtual void fill_blend(Surface &dst, const Color &color, const Rect &rect) = 0;
-
- /// Create a window
- /// \param[in] size The size of the window
- /// \param[in] logical_size The logical size of the window
- /// \param[in] fullscreen Whether to open in fullscreen mode
- /// \return The created window
- virtual Window *create_window(const Area &size, const Area &logical_size, bool fullscreen) = 0;
-
- /// Create a texture for the given surface
- /// \param[in] surface The surface to convert
- /// \param[in] name The name of the texture
- /// \return The texture for the surface
- virtual Texture *create_texture(const Surface &surface) = 0;
- };
- }
- }
-}
-
-#endif
+++ /dev/null
-// Copyright Timothy Goya 2007.
-// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at
-// http://www.boost.org/LICENSE_1_0.txt)
-
-#ifndef UNISON_VIDEO_BACKEND_TEXTURE_HPP
-#define UNISON_VIDEO_BACKEND_TEXTURE_HPP
-
-#include <unison/video/Blittable.hpp>
-#include <unison/video/Surface.hpp>
-#include <unison/video/Texture.hpp>
-
-#include <string>
-#include <vector>
-#include <map>
-
-namespace Unison
-{
- namespace Video
- {
- namespace Backend
- {
- class Renderer;
- /// Backend-specific texture interface
- class Texture : public Blittable
- {
- public:
- /// Destructor
- virtual ~Texture();
-
- /// Get the size of the texture
- /// \return The texture size
- Area get_size();
-
- /// Called when referenced
- void ref();
-
- /// Called when a reference goes away
- void unref();
-
- /// Get the number of references to the texture
- /// \return The reference count
- int get_refcount();
-
- /// Get the equavalent surface to the texture
- virtual const Surface get_surface() = 0;
-
- /// Save the texture, called when the window is about to be created or recreated
- virtual void save() = 0;
-
- /// Save all the textures
- static std::vector<Surface> save_textures();
-
- /// Load the textures
- static void load_textures(const std::vector<Surface> &surfaces);
-
- /// Recover previously used but now unused texture IDs
- /// \return A map of what IDs changed during recovery
- static std::map<TextureID, TextureID> recover_texture_ids();
-
- /// Retrieve the texture ID for the filename
- /// \param[in] filename The filename of the image file
- /// \return The texture ID of the texture
- static TextureID get_texture_id(const std::string &filename);
-
- /// Retrieve the texture ID for the filename
- /// \param[in] filename The filename of the image file
- /// \param[in] colorkey The colorkey used by the file
- /// \return The texture ID of the texture
- static TextureID get_texture_id(const std::string &filename, const Color &colorkey);
-
- /// Retrieve the texture ID for the surface
- /// \param[in] surface The surface to optimize
- /// \return The texture ID of the texture
- static TextureID get_texture_id(const Surface &surface);
-
- /// Retrieve the texture ID for the texture
- /// \param[in] texture The texture
- /// \return The texture ID of the texture
- static TextureID get_texture_id(Texture *texture);
-
- /// Retrieve the texture corresponding to the texture ID
- /// \param[in] id The texture ID
- /// \return The corresponding texture
- static Texture *get_texture(TextureID id);
-
- /// Retrieve the name associated with the texture ID
- /// \param[in] texture The texture
- /// \return The texture ID of the texture
- static std::string get_name(TextureID id);
- protected:
- /// Create a texture from the given surface with the given name
- /// \param[in] surface The surface to optimize
- Texture(const Surface &surface);
-
- /// The surface the texture is based from
- Surface surface;
-
- /// The size of the texture
- Area size;
-
- /// The number of references to the texture
- int refcount;
-
- /// All of the textures in existence
- static std::vector<Texture *> textures;
-
- /// The subset of all textures that have names
- static std::map<std::string, TextureID> named_textures;
- };
- }
- }
-}
-
-#endif
+++ /dev/null
-// Copyright Timothy Goya 2007.
-// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at
-// http://www.boost.org/LICENSE_1_0.txt)
-
-#ifndef UNISON_VIDEO_BACKEND_WINDOW_HPP
-#define UNISON_VIDEO_BACKEND_WINDOW_HPP
-
-#include <unison/video/Blittable.hpp>
-#include <unison/video/RenderOptions.hpp>
-#include <unison/video/Coord.hpp>
-#include <unison/video/Rect.hpp>
-
-#include <string>
-#include <vector>
-
-namespace Unison
-{
- namespace Video
- {
- class Color;
- class Rect;
- class Texture;
- class Surface;
- namespace Backend
- {
- /// Backend-specific window interface
- class Window : public Blittable
- {
- public:
- /// Destructor
- virtual ~Window()
- {
- }
-
- /// Take a screenshot of the window
- /// \param[in] filename The destination filename
- virtual void take_screenshot(const std::string &filename) const = 0;
-
- /// Flip request buffers
- /// \note Should be called only once per frame!
- virtual void flip() = 0;
-
- /// Set window title
- virtual void set_title(const std::string &title) = 0;
-
- /// Set window icon
- virtual void set_icon(const Surface &icon) = 0;
-
- /// Retrieves the window's size
- /// \return The size of the window
- virtual Area get_size() const = 0;
-
- /// Queries whether the window is in fullscreen mode
- /// \return Whether the window is fullscreen
- virtual bool is_fullscreen() const = 0;
- };
- }
- }
-}
-
-#endif
+++ /dev/null
-// Copyright Timothy Goya 2007.
-// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at
-// http://www.boost.org/LICENSE_1_0.txt)
-
-#ifndef UNISON_VIDEO_SDL_BLITTERS_HPP
-#define UNISON_VIDEO_SDL_BLITTERS_HPP
-
-#include <unison/video/Blitters.hpp>
-#include <unison/video/Coord.hpp>
-#include <unison/video/Surface.hpp>
-
-#include "SDL.h"
-
-namespace Unison
-{
- namespace Video
- {
- namespace SDL
- {
- struct Blitters
- {
- static SDL_Surface *create_sdl_surface_from(Surface &src)
- {
-#if SDL_BYTEORDER == SDL_LIL_ENDIAN
- SDL_Surface *surface = SDL_CreateRGBSurfaceFrom(src.get_pixels(), src.get_size().x, src.get_size().y, 32, src.get_size().x * 4, 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000);
-#else
- SDL_Surface *surface = SDL_CreateRGBSurfaceFrom(src.get_pixels().get_pixels(), src.get_size().x, src.get_size().y, 32, src.get_size().x * 4, 0xff000000, 0x00ff0000, 0x0000ff00, 0x000000ff);
-#endif
- return surface;
- }
-
- static SDL_Surface *create_sdl_surface_from(const Surface &src)
- {
-#if SDL_BYTEORDER == SDL_LIL_ENDIAN
- SDL_Surface *surface = SDL_CreateRGBSurfaceFrom(const_cast<Color *>(src.get_pixels()), src.get_size().x, src.get_size().y, 32, src.get_size().x * 4, 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000);
-#else
- SDL_Surface *surface = SDL_CreateRGBSurfaceFrom(const_cast<Color *>(src.get_pixels()).get_pixels(), src.get_size().x, src.get_size().y, 32, src.get_size().x * 4, 0xff000000, 0x00ff0000, 0x0000ff00, 0x000000ff);
-#endif
- return surface;
- }
-
- static SDL_Surface *optimize(const Surface &src);
-
- static void blit_upper(SDL_Surface *src, Rect src_rect, SDL_Surface *dst, Point dst_pos, void (*blit_lower)(SDL_Surface *, const Rect &, SDL_Surface *, const Point &));
-
- static void blit_lower_none(SDL_Surface *src, const Rect &src_rect, SDL_Surface *dst, const Point &dst_pos);
-
- static void blit_lower_mask(SDL_Surface *src, const Rect &src_rect, SDL_Surface *dst, const Point &dst_pos);
-
- static void blit_lower_alpha(SDL_Surface *src, const Rect &src_rect, SDL_Surface *dst, const Point &dst_pos);
-
- static void blit_lower_add(SDL_Surface *src, const Rect &src_rect, SDL_Surface *dst, const Point &dst_pos);
-
- static void blit_lower_mod(SDL_Surface *src, const Rect &src_rect, SDL_Surface *dst, const Point &dst_pos);
-
- static void blit_blend_none(SDL_Surface *src, const Rect &src_rect, SDL_Surface *dst, const Point &dst_pos)
- {
- blit_upper(src, src_rect, dst, dst_pos, blit_lower_none);
- }
-
- static void blit_blend_mask(SDL_Surface *src, const Rect &src_rect, SDL_Surface *dst, const Point &dst_pos)
- {
- blit_upper(src, src_rect, dst, dst_pos, blit_lower_mask);
- }
-
- static void blit_blend_alpha(SDL_Surface *src, const Rect &src_rect, SDL_Surface *dst, const Point &dst_pos)
- {
- blit_upper(src, src_rect, dst, dst_pos, blit_lower_alpha);
- }
-
- static void blit_blend_add(SDL_Surface *src, const Rect &src_rect, SDL_Surface *dst, const Point &dst_pos)
- {
- blit_upper(src, src_rect, dst, dst_pos, blit_lower_add);
- }
-
- static void blit_blend_mod(SDL_Surface *src, const Rect &src_rect, SDL_Surface *dst, const Point &dst_pos)
- {
- blit_upper(src, src_rect, dst, dst_pos, blit_lower_mod);
- }
-
- static void blit_blend(SDL_Surface *src, const Rect &src_rect, SDL_Surface *dst, const Point &dst_pos, BlendMode blend)
- {
- switch(blend)
- {
- case BLEND_NONE:
- blit_blend_none(src, src_rect, dst, dst_pos);
- break;
- case BLEND_MASK:
- blit_blend_mask(src, src_rect, dst, dst_pos);
- break;
- case BLEND_ALPHA:
- blit_blend_alpha(src, src_rect, dst, dst_pos);
- break;
- case BLEND_ADD:
- blit_blend_add(src, src_rect, dst, dst_pos);
- break;
- case BLEND_MOD:
- blit_blend_mod(src, src_rect, dst, dst_pos);
- break;
- }
- }
- };
- }
- }
-}
-
-#endif
+++ /dev/null
-/*
- * CHANGELOG.
- */
-
-04032007 - Added a "make dist" target for packing up source code releases.
- Reverted Unix recursive mutex code. There were some portability
- issues I didn't anticipate. Upped version to 1.1.1!
-04022007 - Added wxWidgets-based test program (incomplete). Filled in and
- corrected some Doxygen comments.
-04012007 - Added PHYSFS_isInit() and PHYSFS_symbolicLinksPermitted() functions.
-03312007 - Added a quick'n'dirty unpack utility to the extras directory. Moved
- DIR archiver to start of the list, so we don't have to have every
- other archiver fail to open a directory as a file before mounting
- it. Fixed typos in makeos2.cmd and the Doxygen comments. Added
- symlink support to windows.c for use on Vista-based systems.
-03282007 - Logic bug in MVL/HOG/GRP archivers: only enumerated files when
- looking in a directory other than the root, instead of enumerating
- only for the root (thanks, Chris!). Minor fix for compilers that
- don't like the BAIL_* macros with an empty argument
- (thanks, Chris!)
-03262007 - Tons of Unicode work in windows.c ... should now use UCS-2 on
- NT/XP/Vista/etc versions of the OS, and fallback to "ANSI" versions
- for 95/98/ME, tapdancing around the system codepage if it has to.
- Since the Unicode entry points are dynamically loaded, it won't
- have issues with missing symbols on Win9x, nor does it need to be
- built separately with #define UNICODE (although it will work the
- same with or without this define, as it doesn't use TCHARs or
- the non-[WA] versions of APIs. Other minor Windows cleanups and
- corrections.
-03252007 - Improved dynamic loader and initial Unicode work in windows.c ...
-03242007 - Replaced BeOS semaphores with BLockers for the mutex implementation.
- It's much simpler, it has "benaphores" built in behind the scenes
- for faster performance, and it's recursive...also, we were
- previously setting the PhysicsFS error state if BeOS mutex grabbing
- failed (a big no no!), and that's now fixed. Good wins all around.
-03222007 - Replaced some Malloc and all the alloca() calls with
- __PHYSFS_smallAlloc(), which will stack allocate small (128 or
- less bytes) blocks and Malloc the rest...naturally these now have
- to be paired with __PHYSFS_smallFree() calls, so you can't be as
- lazy as a basic alloca() would let you be. The benefit is both less
- malloc pressure for those temporary allocations and better stack
- overflow safety (so if some jerk tries to push a 78 megabyte string
- through the library as a filename, we won't try to strcpy it to
- the stack). Hopefully some internal interfaces can now get
- refactored to stop generating heap pointers and let the caller use
- smallAlloc to further reduce malloc pressure.
-03212007 - Replaced LONGLONGLITERAL with __PHYSFS_UI64/__PHYSFS_SI64 ...
-03202007 - Removed platform/skeleton.c (it was out of date), added
- platform/macosx.c (To further Macify the code and get the #ifdefs
- out of unix.c), and refactored the platform layer to try and
- make the unix/posix/macosx/beos sources try to find a split that
- works. Moved the platform allocators to physfs.c, since all but
- Mac OS X were using malloc()...there's now an interface for the
- platform to supply a custom allocator if they don't want the malloc
- version. Removed __PHYSFS_platformTimeslice(), as it's no longer
- being used. Replaced manual management of pthread mutexes with
- PTHREAD_MUTEX_RECURSIVE attribute...let's see what platforms
- throw up on that. Handled documentation comment FIXME in physfs.h.
-03192007 - Fixed two switched strings in CMakeLists.txt ... patch to compile
- with latest Windows Platform SDK. Explicitly check for NULL in
- PHYSFS_init() when we can't go on without a real string here.
- Removed ANSI-C workaround for missing lstat() nonsense in posix.c
- (POSIX != ANSI, time to give up here). Try to use /proc/self/exe
- to find the base dir on Unix, so we can do without argv[0] on
- systems with a Linux-like /proc filesystem.
-03162007 - Changed PHYSFS_file from a typedef to a #define (in case it would
- cause an aggressive compiler to think you're passing the wrong type
- to a function) and added Doxygen comments to explain it.
-03152007 - Bunch of work on Unicode...added case-folding stricmp, removed
- platform-specific stricmp implementations, changed appropriate
- calls to an ASCII-only stricmp that ignores locale. Fixed case on
- UTF-8 API entry points.
-03142007 - Dropped classic Mac OS support. It's just too hard to find a working
- Mac OS 9 install and reasonable development tools, so it's not
- worth it. If you still target OS 8 or 9, please use PhysicsFS 1.0.
-03112007 - Removed zlib_license_change.txt ... it's in Subversion and the 1.0
- branch for history's sake. Added shared and static build options
- to CMakeLists.txt, and the expected "make install" target.
- Renamed some FILENAME files to FILENAME.txt, removed physfs.rc.
- Now compiles everything whether we need it or not, removing whole
- files with #ifdefs...this will make it easier to "embed" this
- library in other projects or use a different build system: just
- push everything through the compiler with preprocessor defines for
- the parts you want/need...platform modules are determined
- automatically without the build system needing to intervene, so you
- just have to #define the archivers, etc that you want.
- Updated makeos2.cmd for newer Innotek toolchain (thanks, Dave!)
-03082007 - Fixed a comment in physfs.h. Renamed win32.c to windows.c.
- Cleaned up whitespace/formatting in pocketpc.c. Updated PocketPC
- code to expect UTF-8 strings from the higher level. Changed
- PHYSFS_SUPPORTS_LZMA to PHYSFS_SUPPORTS_7Z. Killed some #ifdefs
- in physfs.c. Moved to CMake...so long, autotools! Killed MIX
- archiver, too.
-11052006 - More 7zip archiver work (thanks, Dennis!). Initial Unicode work.
- Minor BeOS realpath tweak.
-09272006 - Reworked 7zip archiver (thanks, Dennis!).
-09232006 - Fixed typo in doxygen comment.
-04112006 - Added LZMA archiver...7zip support (thanks, Dennis!).
-03232006 - Added -fvisibility for gcc4 (http://gcc.gnu.org/wiki/Visibility)
-01012006 - Cleaned up overflow checks in platform memory allocators (thanks to
- Nicolas Lebedenco for pointing out the original issue with
- long long literals). Added physfs.rc (thanks, Dennis!). Changed my
- email address. Removed acconfig.h.
-11282005 - Corrected docs on PHYSFS_setWriteDir().
-10122005 - Fixed locateInStringList() in physfs.c (thanks, Matze!). Patched
- archivers/wad.c to compile.
-09192005 - Make unix mutexes recursive above pthread layer...fixes deadlock on
- MacOS X, for now.
-09182005 - API BREAKAGE: PHYSFS_enumerateFilesCallback() now passes the
- original directory name back to the app in the callback. This
- API was only in 1.1.0, and wasn't promised to be stable at this
- point. Please update your apps! Cleaned out a FIXME in file
- enumeration that would confuse the library under certain
- circumstances.
-09092005 - Some tweaks to PHYSFS_Allocator. Apparently configure.in doesn't
- work like I thought for version bumps, so it thinks 1.1.0 isn't
- binary compatible with 1.0...fixed, I think.
-09062005 - Happy September. Changed the allocation abstraction to use
- PHYSFS_uint64 instead of size_t, so we don't have to include
- system headers inside physfs.h. Minor MingW fixes (but it's still
- broken, I think).
-08202005 - Fixed bug in verifyPath() that was breaking PHYSFS_setSaneConfig()
- and other corner cases.
-07242005 - Patched to compile on BeOS.
-07232005 - Fixed bug in zip archiver (thanks, Jörg Walter!).
- More minor OS/2 tweaks. Updated zlib to 1.2.3, which properly
- includes the security fix. Fixed "make dist" to handle .svn dirs
- and other file changes. Removed "debian" directory. Allow a mount
- point of NULL to be "/", per the documentation. Fixed warning in
- physfs.c. Assert definition fix. Updated CWProjects.sit.
- Upped version to 1.1.0 ... first release of 1.1 dev branch!
-07212005 - Patched to compile on OS/2 again.
-07132005 - Updated zlib to 1.2.2, and patched it for this security hole:
- http://www.cve.mitre.org/cgi-bin/cvename.cgi?name=CAN-2005-2096
-06122005 - Added support for mingw to Unix build process (thanks, Matze!).
-03162005 - Added missing translation and Portuguese support (thanks, Danny!).
- MPW support and several MacOS Classic fixes (thanks, Chris!).
- Changed CWProjects from SITX to SIT format, so OS9 users can
- unpack it.
-03132005 - More mount work, added PHYSFS_getMountPoint() and more cleanups.
- Replaced all the C runtime allocations with PhysFS allocation hooks.
- Added pocketpc.c to EXTRA_DIST. Added allocation hooks to some
- platform drivers. Updated Mac Classic build.
-03122005 - Added evil GOTO_*_MACRO_* macros. Fixed unix.c to compile again on
- MacOS X. Added PHYSFS_mount() (thanks, Philip!). Cleaned up the
- INSTALL and CREDITS files a little. Split off start of
- verifySecurity() into a path sanitizer and changed entry points to
- sanitize input paths into a stack-allocated buffer before further
- processing. This removes the need for a malloc() for almost all
- file system operations, and generally cleaned things up. Added a
- "mount" command to test_physfs. Other general cleanups.
-02152005 - Minor comment fix in platform/pocketpc.c
-01052005 - Fixed HOG archiver file lookup (thanks, Chris!)
-12162004 - Fixed some documentation/header comment typos (thanks, Gaetan!)
-10302004 - Fixed a strcpy that should have been a strcat. (thanks, Tolga!)
- Build system respects external CFLAGS now. (thanks, Adam!)
- Fixed infinite loop in new enumeration code. (thanks, Adam!)
-10062004 - Removed profiling code from physfs.c.
-09292004 - Every API that can return a list of strings can now use a
- callback mechanism if the application wants to do it's own
- allocation or handling on a per-item basis. The guts of those
- APIs that create string lists now use the callbacks themselves to
- build the lists, too. The callback functionality goes all the way
- down to the archivers and platform drivers where appropriate, which
- cleans things up and simplifies some internal tasks very nicely.
- Got rid of all the annoying forward declarations in all the
- archivers and moved their PHYSFS_Archiver data to the end of the
- file, since this was annoying me and I was getting sick of updating
- function signatures in two places when the internal API changed.
- Removed the code/data for LinkedStringLists...it isn't used anymore
- now that the callback code is in place.
-09262004 - Did the same thing to FileHandles than I did to DirHandles, but
- this triggered massive tweaking in physfs.c. A lot of code got
- little cleanups, which was nice. Less malloc pressure, too, since
- opening a file used to allocate a ton of crap and mush it
- together...now it's basically down to one structure and the
- instance data in whatever archiver. Minor varname tweak in win32.c
- and pocketpc.c. Changed PHYSFS_file to PHYSFS_File to match the
- rest of the API's naming scheme (but put a typedef for source
- compatibility).
-09252004 - Cleaned up archiver interface to not deal with DirHandles anymore,
- which simplifies things, removes some responsibility and code
- duplication from the archivers, and trims some malloc pressure.
- Ripped up the allocation hook code a little. We'll try to screw
- with memory locking later, since it makes everything ugly and
- complex. Oh well.
-09232004 - Started adding allocation hooks.
-09222004 - Happy September. Added Spanish translation back in.
-04092004 - Added MIX support for legacy Westwood titles (Thanks, Sebastian!).
- Made bootstrap script MacOSX-friendly. Moved byteorder defines into
- physfs_internal.h ...
-01152003 - Added Portuguese (Brazil) translation (Thanks, Danny!)
-
-
---- This is where the 1.1 development branch starts. ---
-
-12292003 - Updated CodeWarrior projects from CW6 to CW7, and made a bunch of
- patches to get the Mac Classic target building again. Removed
- zlib114 from CVS repository. Updated OS/2 build batch file.
- Added Z_PREFIX define to Unix builds that use internal zlib.
- Patched up some (outdated?) Visual C project files for zlib121.
- Patched Doxyfile and physfs.h for newer Doxygen. Fixed OS/2
- build script. Tweaked Project Builder files to at least compile.
- Added some last minute BeOS and Cygwin build fixes. Updated
- Visual Studio projects and tweaked some Makefile.am crap. Made
- changes so Visual Studio files would pack with DOS endlines and...
- Upped version to 1.0.0 (woohoo!).
-12222003 - Fixed a search-and-replace mistake in win32.c that preventing
- compiling on Windows. (thanks, Brian!) Converted VC6 .dsp to use
- zlib121; made Z_PREFIX=1 enabled by default to avoid link clashes;
- put zlib files in separate logical folder in .dsp project; updated
- zlib121/zconf.h to address remaining symbols that were still
- causing link warnings.
-12182003 - WAD archiver now puts maps into subdirectories, making them
- accessible to the application. (Thanks, Travis!) RPM spec and
- Makefile.am* now package zlib_license_change.txt (Thanks, Edward!)
-12142003 - Added Doom WAD support (Thanks, Travis!)
-12082003 - Fixed some win32.c deficiencies that Robby Dermody pointed
- out (thanks!)
-12072003 - Upgraded internal zlib to 1.2.1 (thanks, Adam!) Other
- Unix build fixes.
-11112003 - Patches to make OS/2 support compile again.
-11092003 - Added __PHYSFS_platformStrnicmp(), and made qpak.c case-insensitive.
-09122003 - Happy September. Actually released current tree as 0.1.9.
-08262003 - Added MiNT support to build process and fixed cross-compiling
- (thanks Patrice Mandin!)
-08092003 - Some Windows build fixes (thanks, Brian Hook!)
-07232003 - Upped version to 0.1.9.
-07202003 - Switched to zlib license (see new LICENSE text in root of source
- tree, and zlib_license_switch.txt for details). Had to remove
- archivers/qpak.c, the Ruby bindings from the extras directory, and
- the Russian and Spanish translations, since those contributors
- couldn't be contacted. If they show up, we'll readd them to the
- project, otherwise we'll eventually replace their work...everyone
- else signed on for the change. Committed a patch to convert all
- tabs to spaces (Thanks, James!). Added patch to zip.c to fix
- crash (thanks, dillo!). Reimplmented qpak.c, by welding together
- bits of grp.c and zip.c. Ed contacted me, so I could readd his
- contributions post-license change...I'm going to keep the new
- qpak.c, but I've readded his Ruby bindings and Russian translations.
-06112003 - Patches to globbing.c to handle corner cases (thanks, Bradley!).
-06102003 - Added globbing.c to "extras" directory.
-05232003 - Rewrote MacOSX/Darwin CD-ROM detection code to use IOKit, which is
- much much more accurate than the previous code. Updated
- configure.in and Makefile.am.newautomake for some MacOSX stuff.
-05222003 - Fixed win32 crash if PHYSFS_init() is called with a NULL.
-05182003 - PocketPC fixes (thanks, David Hedbor!)
-05162003 - Compiler warning cleanup in HOG and MVL archivers (Thanks, Bradley!)
-04082003 - Minor changes to extras/abs-file.h (Thanks, Adam!)
-03302003 - Fixed seeking in uncompressed ZIP entries, and handle a
- misbehaviour in Java's JAR creation tools. Thanks to "Tree" for
- pointing these bugs out. Added HOG and MVL archive support for
- Descent I and II (Thanks, Bradley Bell!). Added example code to
- do case-insensitive file searches ("extras/ignorecase.*").
-03192003 - Fixed problem in PHYSFS_mkdir() when dirs to be created already
- exist. Fixed problem where PHYSFS_mkdir() incorrectly tripped an
- alarm in __PHYSFS_verifySecurity().
-03122003 - Attempt at cleaning up some type correctness for VC++6. Made QPAK
- archiver case-insensitive (since Quake2 has problems without it).
-01302003 - Added buffering API to OS/2 build's exported symbol list. Updated
- CWProjects.sit and made several fixes to get physfs building on
- MacOS Classic again.
-01282003 - Fixed seeking in buffered files opened for read.
-01072003 - .NET assembly and C# wrapper by Gregory S. Read in the extras dir.
-01042003 - Added a hack for dealing with OSX bundles and newer PBProjects
- (thanks, Eric Wing!). Added some missing files to "make dist".
- Fixed minor Doxygen typo in PHYSFS_flush() docs. Upped version to
- 0.1.8.
-12172002 - Added Apple Project Builder support files (thanks, Eric Wing!).
-12112002 - Added Ruby bindings to extras directory (thanks, Ed Sinjiashvili!).
- Patched win32.c to compile with Mingw32 (thanks, Niels Wagenaar!).
-12032002 - Adam updated his extras/abs-file.h for the new buffering API.
-12022002 - German translation added, compliments of Michael Renner.
-12012002 - Minor fix to configure.in: reported --enable-debug's default
- setting incorrectly. Added buffering to the API: you can now
- buffer a file with PHYSFS_setBuffer(), and flush the buffer to
- disk with PHYSFS_flush(). PhysicsFS file handles are unbuffered
- by default (as they were before this API addition), so this does
- not break the API. Other fixes for bugs I stumbled upon during
- this work are in CVS, too.
-11292002 - Minor fix for strange PATH strings in unix.c (thanks, Alexander!)
-11222002 - Initial PocketPC port by Corona688.
-10222002 - Fixed segfault in test_physfs.c when user hits CTRL-D (and
- readline() thus returns NULL)...now gracefully exits, as it should.
-10142002 - Added check for AMD's x86-64 ("Hammer") architecture when
- determining platform byte order.
-10112002 - Fixed "setsaneconfig" command in test_physfs.c ...
-09232002 - Happy September. Updated VC++6 project files, fixed some
- VC++ compile nags (more work to be done in zip.c).
-08302002 - Cleaned tab stops out of zip.c, and fixed a possible infinite loop
- in zip_find_entry().
-08292002 - Fixed a mistake in makeos2.cmd, and updated the INSTALL docs.
- Added physfs.spec.in to EXTRA_DIST in Makefile.am*
-08292002 - Added a physfs/stdio wrapper header to the "extras" dir,
- compliments of Adam D. Moss (file is "abs-file.h").
-08282002 - Cleanups in grp.c so that Visual C++ doesn't complain anymore.
- zip.c now works correctly when PhysicsFS is disallowing symlinks.
- A few minor optimizations in zip.c, with a few more to come later.
- Added VS.NET project files to CVS.
-08222002 - Fixed ZIP_exists() to work with directories. Now breaks out of
- __PHYSFS_verifySecurity() early if a path element is missing
- (since all the others will be, too)...this check is only done
- if symlinks are disabled, but we might as well save easy cycles
- where we can.
-08212002 - Did a couple tedious-for-small-rewards cleanups, optimizations,
- corrections and streamlinings I've been meaning to do. Touched a
- lot of code. One of the side results is that ZIP_isDirectory()
- got fixed.
-08192002 - Generalized sorting routines, moved them into physfs.c and removed
- the multiple copies from the various archivers. Adding profiling
- code (currently only for sort routines)...enable it with
- --enable-profiling in the configure script. Fixed incorrect
- behaviours in configure.in.
-08172002 - Patched configure.in to work around buggy autoconfs.
-08162002 - Fixed QPAK archiver, since I broke it (sorry!). Also fixed a
- qpak memory leak.
-08092002 - Added Quake PAK archiver (qpak.c) by Ed Sinjiashvili. Thanks!
- Made (successful?) attempt to fix pthread-to-ui64 cast problem.
- Check for OS/2 in configure.in, in case anyone gets autoconf and
- such to work right on their OS/2 box.
-08012002 - Patched win32.c to compile.
-07302002 - Minor error handling fix (thanks, Alexander!)
-07292002 - Found some memory leaks, thanks to Valgrind (which rules, btw).
- Added Russian translations (koi8-r, cp1251, cp866, and iso-8859-5)
- by Ed Sinjiashvili. Added Spanish translation by Pedro J. Pérez.
- Debian package support in CVS, thanks to Colin Bayer. French
- translation by Stéphane Peter.
-07282002 - macclassic.c now returns human readable error messages instead of
- ERR_OS_ERROR. Closing files on MacOS no longer fails if the volume
- info can't be flushed. Minor error message tweak in os2.c. All
- possible human-readable literal strings (including all those OS/2
- and MacOS error messages) have moved to constants in
- physfs_internal.h...this allows the library to be translated to
- other spoken languages fairly easily.
-07272002 - Patched the OS/2 code to be useful...works pretty well, now. Added
- makeos2.cmd for building (not an ideal solution, but oh well).
- Initialized some variables in zip.c to prevent compiler whining.
-07262002 - Fixed a typo in documentation. Archivers with matching file
- extensions are now given first shot at opening an archive, but if
- they fail, the other archivers are tried. More fixes to zip.c's
- ZIP_enumerateFiles(). Wrote an OS/2 platform driver based on API
- specs and a heavy pounding of Google Groups...as I don't have an
- OS/2 compiler at the moment, it probably doesn't even compile. :)
-07252002 - configure.in and unix.c now deal with platforms that lack a
- functional pthread library. Edward Rudd sent in a patch to the RPM
- specfile to have the build system set the correct version.
- Clean ups in grp.c, beos.cpp and macclassic.c.
-07242002 - Rewrote ZIP_enumerate(). Hopefully it sucks less this time.
- unix.c and configure.in now have the infrastructure to disable
- the CD-ROM detection code, and use a stub that successfully (and
- unconditionally) reports no detected discs. Currently this is
- used on AtheOS (which doesn't have CD-ROM support at the moment
- anyhow), but it will be useful to get the library up on odd,
- Unix-like systems that don't use either getmntinfo() or getmntent().
-07232002 - Cleaned up the cut-and-pastes in the various file enumeration
- routines and moved it into __PHYSFS_addToLinkedStringList().
- Tons more ZIP file enhancing. I'm fairly certain it's robust and
- fast in every reasonable respect, now. GRP archiver now caches
- the file table...it was generally overhauled like the ZIP driver.
- Added "ls" as an alias of "enumerate" in test_physfs.
- I lied about zip.c's robustness; disabled the enumeration code.
-07212002 - More FreeBSD build system patches. Added some new autoconf spew to
- .cvsignore. bootstrap now copies the appropriate Makefile.am
- instead of rename()ing it.
-07192002 - Cleaned up configure.in and unix.c so that we check by available
- header to determine the appropriate CD-ROM detection code...this
- should make this more future-proof (and probably get it building
- out of the box on other BSD platforms.)
-07172002 - Fixed seeking backwards in ZIP_seek(). Changed the error message
- ERR_TOO_MANY_SYMLINKS to ERR_SYMLINK_LOOP. Patches to build system
- and unix.c for FreeBSD compatibility. Added physfs.spec to
- "make dist" archives (thanks, Edward Rudd!).
-07152002 - Symlinks in ZIP archives are detected correctly now, I think.
-07142002 - Use GetVolumeInformation() instead of GetDiskFreeSpace() in
- win32.c's mediaInDrive() function. This allows Windows NT 3.x to
- correctly detect CD-ROM drives. Library now appears to be fully
- functional on WinNT 3.51...need to try NT 3.1 still. :)
- Patches to new ZIP code; cleaned up bugs in symlink reading code,
- but we incorrectly identify some entries as symlinks, which doesn't
- fly...for now, symlink code is commented out, so symlinks look
- like regular files (and reading from a symlink entry gives you
- the link as file data).
-07122002 - Rewrote the ZIP archiver to no longer use Gilles Vollant's unzip.c
- code. Losing that abstraction should make the ZIP archiver
- significantly more efficient, and halved the amount of code used.
- Plus, being a control freak, I like my coding style more than
- Gilles's. :) There are still bugs to shake out, but this is good
- progress.
-07112002 - configure.in updated to make it happier on newer autoconfs
- (thanks again, Alexander!). FIXME cleanups.
-07102002 - Added a byteorder-friendly convenience API, so you can read/write
- data and convert to the native byteorder without too much effort.
- Upped version to 0.1.7.
- Build system corrections for BeOS and Cygwin (thanks, Alexander!).
- Added RPM specfile for PhysicsFS (thanks, Edward Rudd!).
-06292002 - Fixed incorrect error message when opening a file for read without
- defining a search path. LOTS of win32 updates and fixes; lots of
- things that were broken work now, and we are slowly becoming
- more compatible with legacy win32 systems. Builds on Cygwin again.
- All platform drivers (except beos.cpp) had a buffer overflow when
- detecting mounted CD-ROM drives...it only occurs when a drive is
- detected, and it probably won't result in your box getting rooted,
- but upgrade soon anyhow. Readded the .cvsignore files from the old
- build system.
-06282002 - Reworked build system _AGAIN_.
-06222002 - Alexander Pipelka spotted a bug in the file open routines in
- posix.c; patched.
-06152002 - Autoconf build system will now generate shared libraries on BeOS,
- and (supposedly) Cygwin.
-06142002 - Rewrote autoconf build system. It now works around the MacOS X bug
- that prevented shared libraries from building.
-06112002 - Updated CodeWarrior projects and added them to CVS. _Finally_
- officially released 0.1.6.
-06102002 - Major overhauls to platform/win32.c ... should work on all Windows
- platforms, including 95/98/ME and NT/2K/XP flavors. Someone should
- see if this builds on WinCE! :) You no longer need the latest
- platform SDK to build it, either; the questionable DLL is accessed
- with LoadLibrary() at runtime now, and handled if not present. This
- now builds correctly on a freshly installed Visual Studio 6.0, and
- the DLL it builds works everywhere. Plus, a bunch of other bugs
- and incorrect behaviours were squashed. Visual Studio 6.0 project
- file added to CVS.
-06082002 - Fixes to __PHYSFS_platformEnumerateFiles() in win32.c: cleaned up
- memory leak, handles paths more robustly, and prevents possible
- skipped file entries. Removed AC_C_CONST and AC_TYPE_SIZE_T checks
- from configure.in (not needed, and they broke BeOS build). Clean
- out the docs/ directory when doing a "make dist". Fixed crashbug
- when calling PHYSFS_deinit() more than once in a row. Tried to get
- MacOS X to build a shared library, gave up; I'm doing something
- wrong in my Makefile.am, I think. On MacOS X, running ./configure
- --enable-static --disable-shared works, though. Hopefully someone
- will fix this soon. In unix.c, the Darwin version of
- __PHYSFS_platformDetectAvailableCDs() was free()ing a static
- buffer; fixed.
-06072002 - Manpages! Finally installed Doxygen and scratched together a
- Doxyfile. After some revision to physfs.h, we've got a rather
- nice API reference.
-06062002 - Fixed __PHYSFS_platformSeek() in archivers/posix.c. Implemented the
- getLastModTime method in archivers/zip.c (returns legitimate info)
- and archivers/grp.c (returns lastmodtime of GRPfile itself in the
- physical filesystem). Put a 64-bit _llseek() version of the seek()
- and tell() methods in platform/posix.c, but you need to hack (or
- rather, fix) configure.in to enable it. From Greg on win32.c: Fixed
- file enumerator function (needed a wildcard '*' specification), CD
- enumeration only reports CDs that have media, getLastModTime() has
- been implemented.
-06012002 - Added -Wall to debug builds. Removed ANSI stdio calls from
- platform/posix.c, and replaced them with actual POSIX calls (that
- is, fopen() became open(), fseek() became lseek(), etc...)
-05272002 - Added some explicit casts when calling malloc() in platform/posix.c
-05252002 - Added John Hall's file modification time patch, and added a
- getlastmodtime command to test_physfs. Corrected error reporting
- for missing files a little bit. Changed build system to only try
- building beos.cpp if on a BeOS system (since we need a C++ compiler
- available to do so). Implemented getLastModTime in macclassic.c.
-05242002 - Upped version to 0.1.6 (not officially released yet).
-05232002 - Fixed the build system to always package the complete source, not
- just what we built for a given system, when doing a "make dist".
- Updated INSTALL. Wrote BeOS platform code (platform/beos.cpp).
- Split unix.c into unix.c and posix.c. Linux and BeOS both share
- posix.c, although I don't think it's completely POSIX compliant at
- this point (not that it matters much).
-05212002 - Cleaned up some FIXMEs.
-05202002 - Added .cvsignore files.
-05162002 - Edward Rudd also caught an embarrassing screwup by me in
- unix.c: the open-for-append call was using "wb+" instead of
- "ab" when calling fopen(). Doh!
-05152002 - configure script now deals with systems that have a readline
- lib, but require it to be linked with curses. Thanks to Edward
- Rudd for the patch.
-05102002 - A trimmed-down zlib 1.1.4 is now included in the source distro, for
- use by win32, MacOS, and Unix systems that don't have it installed
- on the system. Autoconf support! Initial attempt at this. Lots of
- stuff may be very broken.
-05082002 - From Greg: More win32 work. Library is now 95% functional on win32.
- Only known win32 problem is that the CD drives are reported whether
- they contain a disc or not).
-05062002 - From Greg: Win32 boxes without the latest Platform SDK can now
- #define DISABLE_NT_SUPPORT. Other fixes.
-04242002 - Updated win32 info in INSTALL to discuss Platform SDK issues.
-04202002 - Added a (very) quick and (very) dirty http server to the
- extras directory (public domain), as another example of using
- the library.
-04192002 - Corrected some win32 info in INSTALL. Changed Makefile to
- package releases as .tar.gz instead of .tar.bz2.
-04122002 - Some win32 cleanups and fixes across several files. Upped
- version to 0.1.5.
-04082002 - Fixed problem when calling __PHYSFS_setError before PHYSFS_init.
-04062002 - Added MacOS info, etc to INSTALL. Patched unix.c and
- test_physfs.c to compile on Darwin again.
-04052002 - Added byte ordering API. Byte ordering fixes in grp.c, and some
- cleanups in unzip.c. Mac work is more or less complete.
-04042002 - Mac work continues. Almost complete, now. test_physfs now has
- tests for write, append, and filelength, and most of the
- commands can tolerate a quoted argument (although this is
- hacky, it's good enough for these purposes). Upped test_physfs
- version to 0.1.1. Added a malloc-failure check in the Unix
- CD-ROM detection code.
-04032002 - PHYSFS_init always makes sure the calling thread initializes its
- error state. Win32 codebase is updated with mutex implementation
- (thanks, Greg!).
-04022002 - Mac work continues. Found a bug where we put a double dir
- separator in if we had to resort to the fallback userdir (if
- __PHYSFS_platformGetUserDir() returned NULL to calculateUserDir().
- Made note of potential infinite recursion in platform driver docs.
-04012002 - (_NOT_ an April Fool's Joke:) Started working on MacOS Classic
- port. Added skeleton.c to platform directory. Minor patches to
- get things compiling on Mac (notably, DirInfo conflicts with
- a type exposed by MacOS's namespace-polluting API, and some
- typecasting issues). Found a call to ferror() I had missed in
- unzip.c.
-03302002 - Mutexes! PhysicsFS should be thread safe now, so long as you
- don't try to do something like close a file at the same time as
- you are reading from it in another thread. All reasonable race
- conditions should now be gone, but the new code will need some
- eyeballing before we install it on life support systems or anything.
- The mutex abstraction is implemented in unix.c, win32.c will be
- updated shortly.
-03292002 - Fixed a potential problem in ZIP_realpath() and some byte order
- issues in zip.c. Converted unzip.c to use physfs file i/o
- abstractions. Converted CHANGELOG to list latest entries first.
-03242002 - Added __PHYSFS_platformInit() and __PHYSFS_platformDeinit(). Win32
- improvements by Gregory S. Read. Added PHYSFS_[us]int(8|16|32)
- types...this breaks binary compatibility with previous PhysicsFS
- releases! Added platform specific i/o functions, so we don't have
- to rely on stdio anymore. Updated TODO with my comments on the
- physfs mailing list. 1.0, here we come! Removed race condition from
- grp.c and converted to file i/o abstraction layer calls from stdio.
- Tons of other fixes and enhancements.
-03202002 - Patched platform/win32.c to compile.
-03152002 - PHYSFS_setSaneConfig() now handles failure to set the write dir
- better. Patched makefile to link the test program. Changed all the
- "write" functions to get data from a "const" buffer. Added an
- "extras" dir, which currently contains PhysFS->SDL_RWops glue code.
-03052002 - Made unix.c's timeslice implementation more portable, and added a
- Darwin-specific means to detect CDs (thanks to Patrick Stein).
- Minor cleanup in win32.c (changed "for (; condition ;)" into
- "while (condition)" ...)
-11142001 - Removed a redundant error check in platform/win32.c
-10092001 - Syntax fixes in dir.c, a FIXME in grp.c, and a "cat" command in
- the test program. Apparently I had accidentally removed a rather
- crucial line from dir.c a few revisions ago, and no one noticed. :(
- Fixed. The win32 userdir will default to the base dir, now.
-09252001 - Changed API: PHYSFS_setSaneConfig() takes an organization name, and
- sets up less directories. Be warned. Fixes from David Hedbor:
- make setSaneConfig() set write directory correctly if it had to
- create the directory, and make sure that the writing functions
- get used in dir.c when a file is opened for writing/appending.
- Updated CREDITS.
-09142001 - David Hedbor submitted a patch to handle a case where the
- current working directory has been deleted out from under the
- process (both in platform/unix.c and physfs.c itself). Thanks,
- David! Added a CREDITS file. Changed the format of the author field
- in PHYSFS_ArchiveInfo to put the email address between "<>" instead
- of "()" chars. Updated TODO. make install now deletes previous
- revisions of the library. Changed version to 0.1.4.
-09012001 - Happy September. Moved the Visual C project files and the zlib
- source to a separate download. Look for it at
- http://icculus.org/physfs/downloads/physfs-win32-support.zip ...
- Updated the INSTALL doc for Win32 building. Rewrote win32.c's
- __PHYSFS_platformRealPath() to not rely on Visual C's runtime lib,
- which was the last Cygwin incompatibility (although the Makefile
- needs to be updated to build a DLL under Cygwin). Tinkered with the
- Makefile a little, but it needs more work. Started working on a
- MacOS version. All I have is CodeWarrior 4, which is way out of
- date, and (for what is supposed to be an ultra-user-friendly
- environment) is completely uninituitive to me. Still, managed to
- get most everything compiling, which improved the quality of the
- code somewhat). Haven't tried to compile the zipfile support, and
- I still can't link the library. Dunno what the hell I'm supposed
- to do there. Isn't Unix supposed to be hard compared to this?
-08312001 - Built PhysicsFS on Mandrake 8.0 for the PowerPC. Compiles clean,
- but there's at least one byte-ordering issue in zip.c that needs
- to be fixed.
-08292001 - win32.c calculates the base dir with GetModuleFileName() first, now,
- and falls back to SearchPath() if there were problems. Changed an
- occurence of _MAX_PATH to MAX_PATH, so both CygWin and Visual C can
- handle it.
-08282001 - win32.c now checks HOMEDRIVE, HOMEPATH, and HOME when calculating
- the userdir. Added include files that make it a little closer to
- compiling under Cygwin. Added a TODO file. Fixed unix.c's
- __PHYSFS_platformCalcBaseDir() so that it actually works. Fixed
- Makefile so that it links the test program properly.
- Changed version to 0.1.3.
-08232001 - Fixed a potential free()ing of a NULL pointer in
- __PHYSFS_platformEnumerateFiles() in platform/unix.c. Added
- platform/win32.c. Other cleanups to get this compiling with
- Visual C and CygWin. Added BAIL_MACRO for times when we were doing
- BAIL_IF_MACRO(1, ...). Abstracted mkdir() in the platform drivers.
- Added GRP setting output to showcfg in the Makefile. Updated INSTALL
- with license info and Win32 build instructions. Dependency on the
- readline library in test_physfs.c is now optional.
- Changed version to 0.1.2.
-08072001 - Changed version to 0.1.1.
-08062001 - Added CD-ROM detection code to the unix platform driver.
-08012001 - Added a safety memset in error setting, fixed URLs and email addr.
-07282001 - Initial release.
-
---ryan. (icculus@icculus.org)
-
-/* end of CHANGELOG ... */
-
+++ /dev/null
-# PhysicsFS; a portable, flexible file i/o abstraction.
-# Copyright (C) 2007 Ryan C. Gordon.
-#
-# Please see the file LICENSE.txt in the source's root directory.
-
-CMAKE_MINIMUM_REQUIRED(VERSION 2.4)
-
-PROJECT(PhysicsFS)
-SET(PHYSFS_VERSION 1.1.1)
-SET(PHYSFS_SOVERSION 1)
-
-# I hate that they define "WIN32" ... we're about to move to Win64...I hope!
-IF(WIN32 AND NOT WINDOWS)
- SET(WINDOWS TRUE)
-ENDIF(WIN32 AND NOT WINDOWS)
-
-# Bleh, let's do it for "APPLE" too.
-IF(APPLE AND NOT MACOSX)
- SET(MACOSX TRUE)
-ENDIF(APPLE AND NOT MACOSX)
-
-INCLUDE(CheckIncludeFile)
-INCLUDE(CheckLibraryExists)
-INCLUDE(CheckCSourceCompiles)
-
-INCLUDE_DIRECTORIES(.)
-#INCLUDE_DIRECTORIES(platform)
-#INCLUDE_DIRECTORIES(archivers)
-
-IF(MACOSX)
- # Fallback to older OS X on PowerPC to support wider range of systems...
- IF(CMAKE_OSX_ARCHITECTURES MATCHES ppc)
- ADD_DEFINITIONS(-DMAC_OS_X_VERSION_MIN_REQUIRED=1020)
- SET(OTHER_LDFLAGS ${OTHER_LDFLAGS} " -mmacosx-version-min=10.2")
- ENDIF(CMAKE_OSX_ARCHITECTURES MATCHES ppc)
-
- # Need these everywhere...
- ADD_DEFINITIONS(-fno-common)
- SET(OTHER_LDFLAGS ${OTHER_LDFLAGS} " -framework Carbon -framework IOKit")
-ENDIF(MACOSX)
-
-# Add some gcc-specific command lines.
-IF(CMAKE_COMPILER_IS_GNUCC)
- # Always build with debug symbols...you can strip it later.
- ADD_DEFINITIONS(-g -pipe -Werror -fsigned-char)
-
- # Stupid BeOS generates warnings in the system headers.
- IF(NOT BEOS)
- ADD_DEFINITIONS(-Wall)
- ENDIF(NOT BEOS)
-
- CHECK_C_SOURCE_COMPILES("
- #if ((defined(__GNUC__)) && (__GNUC__ >= 4))
- int main(int argc, char **argv) { int is_gcc4 = 1; return 0; }
- #else
- #error This is not gcc4.
- #endif
- " PHYSFS_IS_GCC4)
-
- IF(PHYSFS_IS_GCC4)
- ADD_DEFINITIONS(-fvisibility=hidden)
- ENDIF(PHYSFS_IS_GCC4)
-ENDIF(CMAKE_COMPILER_IS_GNUCC)
-
-IF(MSVC)
- # VS.NET 8.0 got really really anal about strcpy, etc, which even if we
- # cleaned up our code, zlib, etc still use...so disable the warning.
- ADD_DEFINITIONS(-D_CRT_SECURE_NO_WARNINGS=1)
-ENDIF(MSVC)
-
-# Basic chunks of source code ...
-
-SET(ZLIB_SRCS
- zlib123/adler32.c
- zlib123/compress.c
- zlib123/crc32.c
- zlib123/deflate.c
- zlib123/gzio.c
- zlib123/infback.c
- zlib123/inffast.c
- zlib123/inflate.c
- zlib123/inftrees.c
- zlib123/trees.c
- zlib123/uncompr.c
- zlib123/zutil.c
-)
-
-SET(LZMA_SRCS
- lzma/7zBuffer.c
- lzma/7zCrc.c
- lzma/7zDecode.c
- lzma/7zExtract.c
- lzma/7zHeader.c
- lzma/7zIn.c
- lzma/7zItem.c
- lzma/7zMethodID.c
- lzma/LzmaDecode.c
- lzma/LzmaStateDecode.c
-)
-
-IF(BEOS)
- # We add this explicitly, since we don't want CMake to think this
- # is a C++ project unless we're on BeOS.
- SET(PHYSFS_BEOS_SRCS platform/beos.cpp)
- SET(OPTIONAL_LIBRARY_LIBS ${OPTIONAL_LIBRARY_LIBS} be root)
-ENDIF(BEOS)
-
-# Almost everything is "compiled" here, but things that don't apply to the
-# build are #ifdef'd out. This is to make it easy to embed PhysicsFS into
-# another project or bring up a new build system: just compile all the source
-# code and #define the things you want.
-SET(PHYSFS_SRCS
- physfs.c
- physfs_byteorder.c
- physfs_unicode.c
- platform/os2.c
- platform/pocketpc.c
- platform/posix.c
- platform/unix.c
- platform/macosx.c
- platform/windows.c
- archivers/dir.c
- archivers/grp.c
- archivers/hog.c
- archivers/lzma.c
- archivers/mvl.c
- archivers/qpak.c
- archivers/wad.c
- archivers/zip.c
- ${PHYSFS_BEOS_SRCS}
-)
-
-
-# platform layers ...
-
-IF(UNIX)
- IF(BEOS)
- SET(PHYSFS_HAVE_CDROM_SUPPORT TRUE)
- SET(PHYSFS_HAVE_THREAD_SUPPORT TRUE)
- SET(HAVE_PTHREAD_H TRUE)
- ELSE(BEOS)
- # !!! FIXME
- # AC_DEFINE([PHYSFS_HAVE_LLSEEK], 1, [define if we have llseek])
- CHECK_INCLUDE_FILE(sys/ucred.h HAVE_UCRED_H)
- IF(HAVE_UCRED_H)
- ADD_DEFINITIONS(-DPHYSFS_HAVE_SYS_UCRED_H=1)
- SET(PHYSFS_HAVE_CDROM_SUPPORT TRUE)
- ENDIF(HAVE_UCRED_H)
-
- CHECK_INCLUDE_FILE(mntent.h HAVE_MNTENT_H)
- IF(HAVE_MNTENT_H)
- ADD_DEFINITIONS(-DPHYSFS_HAVE_MNTENT_H=1)
- SET(PHYSFS_HAVE_CDROM_SUPPORT TRUE)
- ENDIF(HAVE_MNTENT_H)
-
- CHECK_INCLUDE_FILE(pthread.h HAVE_PTHREAD_H)
- IF(HAVE_PTHREAD_H)
- SET(PHYSFS_HAVE_THREAD_SUPPORT TRUE)
- ELSE(HAVE_PTHREAD_H)
- ADD_DEFINITIONS(-DPHYSFS_NO_PTHREADS_SUPPORT=1)
- ENDIF(HAVE_PTHREAD_H)
- ENDIF(BEOS)
-ENDIF(UNIX)
-
-IF(WINDOWS)
- SET(PHYSFS_HAVE_CDROM_SUPPORT TRUE)
- SET(PHYSFS_HAVE_THREAD_SUPPORT TRUE)
-ENDIF(WINDOWS)
-
-IF(NOT PHYSFS_HAVE_CDROM_SUPPORT)
- ADD_DEFINITIONS(-DPHYSFS_NO_CDROM_SUPPORT=1)
- MESSAGE(WARNING " ***")
- MESSAGE(WARNING " *** There is no CD-ROM support in this build!")
- MESSAGE(WARNING " *** PhysicsFS will just pretend there are no discs.")
- MESSAGE(WARNING " *** This may be fine, depending on how PhysicsFS is used,")
- MESSAGE(WARNING " *** but is this what you REALLY wanted?")
- MESSAGE(WARNING " *** (Maybe fix CMakeLists.txt, or write a platform driver?)")
- MESSAGE(WARNING " ***")
-ENDIF(NOT PHYSFS_HAVE_CDROM_SUPPORT)
-
-IF(PHYSFS_HAVE_THREAD_SUPPORT)
- ADD_DEFINITIONS(-D_REENTRANT -D_THREAD_SAFE)
-ELSE(PHYSFS_HAVE_THREAD_SUPPORT)
- MESSAGE(WARNING " ***")
- MESSAGE(WARNING " *** There is no thread support in this build!")
- MESSAGE(WARNING " *** PhysicsFS will NOT be reentrant!")
- MESSAGE(WARNING " *** This may be fine, depending on how PhysicsFS is used,")
- MESSAGE(WARNING " *** but is this what you REALLY wanted?")
- MESSAGE(WARNING " *** (Maybe fix CMakeLists.txt, or write a platform driver?)")
- MESSAGE(WARNING " ***")
-ENDIF(PHYSFS_HAVE_THREAD_SUPPORT)
-
-CHECK_INCLUDE_FILE(assert.h HAVE_ASSERT_H)
-IF(HAVE_ASSERT_H)
- ADD_DEFINITIONS(-DHAVE_ASSERT_H=1)
-ENDIF(HAVE_ASSERT_H)
-
-
-
-# Archivers ...
-
-OPTION(PHYSFS_ARCHIVE_ZIP "Enable ZIP support" TRUE)
-IF(PHYSFS_ARCHIVE_ZIP)
- ADD_DEFINITIONS(-DPHYSFS_SUPPORTS_ZIP=1)
- SET(PHYSFS_NEED_ZLIB TRUE)
-ENDIF(PHYSFS_ARCHIVE_ZIP)
-
-OPTION(PHYSFS_ARCHIVE_7Z "Enable 7zip support" TRUE)
-IF(PHYSFS_ARCHIVE_7Z)
- ADD_DEFINITIONS(-DPHYSFS_SUPPORTS_7Z=1)
- # !!! FIXME: rename to 7z.c?
- SET(PHYSFS_SRCS ${PHYSFS_SRCS} ${LZMA_SRCS})
- INCLUDE_DIRECTORIES(lzma)
- ADD_DEFINITIONS(-D_LZMA_IN_CB=1)
- ADD_DEFINITIONS(-D_LZMA_PROB32=1)
- ADD_DEFINITIONS(-D_LZMA_SYSTEM_SIZE_T=1)
- ADD_DEFINITIONS(-D_SZ_ONE_DIRECTORY=1)
-ENDIF(PHYSFS_ARCHIVE_7Z)
-
-OPTION(PHYSFS_ARCHIVE_GRP "Enable Build Engine GRP support" TRUE)
-IF(PHYSFS_ARCHIVE_GRP)
- ADD_DEFINITIONS(-DPHYSFS_SUPPORTS_GRP=1)
-ENDIF(PHYSFS_ARCHIVE_GRP)
-
-OPTION(PHYSFS_ARCHIVE_WAD "Enable Doom WAD support" TRUE)
-IF(PHYSFS_ARCHIVE_WAD)
- ADD_DEFINITIONS(-DPHYSFS_SUPPORTS_WAD=1)
-ENDIF(PHYSFS_ARCHIVE_WAD)
-
-OPTION(PHYSFS_ARCHIVE_HOG "Enable Descent I/II HOG support" TRUE)
-IF(PHYSFS_ARCHIVE_HOG)
- ADD_DEFINITIONS(-DPHYSFS_SUPPORTS_HOG=1)
-ENDIF(PHYSFS_ARCHIVE_HOG)
-
-OPTION(PHYSFS_ARCHIVE_MVL "Enable Descent I/II MVL support" TRUE)
-IF(PHYSFS_ARCHIVE_MVL)
- ADD_DEFINITIONS(-DPHYSFS_SUPPORTS_MVL=1)
-ENDIF(PHYSFS_ARCHIVE_MVL)
-
-OPTION(PHYSFS_ARCHIVE_QPAK "Enable Quake I/II QPAK support" TRUE)
-IF(PHYSFS_ARCHIVE_QPAK)
- ADD_DEFINITIONS(-DPHYSFS_SUPPORTS_QPAK=1)
-ENDIF(PHYSFS_ARCHIVE_QPAK)
-
-
-# See if some archiver required zlib, and see about using system version.
-
-IF(PHYSFS_NEED_ZLIB)
- CHECK_INCLUDE_FILE(zlib.h HAVE_ZLIB_H)
- IF(HAVE_ZLIB_H)
- CHECK_LIBRARY_EXISTS("z" "inflate" "" HAVE_LIBZ)
- IF(HAVE_LIBZ)
- SET(HAVE_SYSTEM_ZLIB TRUE)
- ENDIF(HAVE_LIBZ)
- ENDIF(HAVE_ZLIB_H)
-
- IF(HAVE_SYSTEM_ZLIB)
- OPTION(PHYSFS_INTERNAL_ZLIB "Link own zlib instead of system library" FALSE)
- ELSE(HAVE_SYSTEM_ZLIB)
- SET(PHYSFS_INTERNAL_ZLIB TRUE)
- ENDIF(HAVE_SYSTEM_ZLIB)
-
- IF(PHYSFS_INTERNAL_ZLIB)
- INCLUDE_DIRECTORIES(zlib123)
- ADD_DEFINITIONS(-DZ_PREFIX=1)
- SET(PHYSFS_SRCS ${PHYSFS_SRCS} ${ZLIB_SRCS})
- ELSE(PHYSFS_INTERNAL_ZLIB)
- SET(OPTIONAL_LIBRARY_LIBS ${OPTIONAL_LIBRARY_LIBS} z)
- ENDIF(PHYSFS_INTERNAL_ZLIB)
-ENDIF(PHYSFS_NEED_ZLIB)
-
-OPTION(PHYSFS_BUILD_STATIC "Build static library" TRUE)
-IF(PHYSFS_BUILD_STATIC)
- ADD_LIBRARY(physfs-static STATIC ${PHYSFS_SRCS})
- SET_TARGET_PROPERTIES(physfs-static PROPERTIES OUTPUT_NAME "physfs")
- SET(PHYSFS_LIB_TARGET physfs-static)
- SET(PHYSFS_INSTALL_TARGETS ${PHYSFS_INSTALL_TARGETS} ";physfs-static")
-ENDIF(PHYSFS_BUILD_STATIC)
-
-OPTION(PHYSFS_BUILD_SHARED "Build shared library" TRUE)
-IF(PHYSFS_BUILD_SHARED)
- ADD_LIBRARY(physfs SHARED ${PHYSFS_SRCS})
- SET_TARGET_PROPERTIES(physfs PROPERTIES VERSION ${PHYSFS_VERSION})
- SET_TARGET_PROPERTIES(physfs PROPERTIES SOVERSION ${PHYSFS_SOVERSION})
- TARGET_LINK_LIBRARIES(physfs ${OPTIONAL_LIBRARY_LIBS} ${OTHER_LDFLAGS})
- SET(PHYSFS_LIB_TARGET physfs)
- SET(PHYSFS_INSTALL_TARGETS ${PHYSFS_INSTALL_TARGETS} ";physfs")
-ENDIF(PHYSFS_BUILD_SHARED)
-
-IF(NOT PHYSFS_BUILD_SHARED AND NOT PHYSFS_BUILD_STATIC)
- MESSAGE(FATAL "Both shared and static libraries are disabled!")
-ENDIF(NOT PHYSFS_BUILD_SHARED AND NOT PHYSFS_BUILD_STATIC)
-
-# CMake FAQ says I need this...
-IF(PHYSFS_BUILD_SHARED AND PHYSFS_BUILD_STATIC)
- SET_TARGET_PROPERTIES(physfs PROPERTIES CLEAN_DIRECT_OUTPUT 1)
- SET_TARGET_PROPERTIES(physfs-static PROPERTIES CLEAN_DIRECT_OUTPUT 1)
-ENDIF(PHYSFS_BUILD_SHARED AND PHYSFS_BUILD_STATIC)
-
-OPTION(PHYSFS_BUILD_TEST "Build stdio test program." TRUE)
-MARK_AS_ADVANCED(PHYSFS_BUILD_TEST)
-IF(PHYSFS_BUILD_TEST)
- CHECK_INCLUDE_FILE(readline/readline.h HAVE_READLINE_H)
- CHECK_INCLUDE_FILE(readline/history.h HAVE_HISTORY_H)
- IF(HAVE_READLINE_H AND HAVE_HISTORY_H)
- SET(CMAKE_REQUIRED_LIBRARIES curses)
- CHECK_LIBRARY_EXISTS("readline" "readline" "" HAVE_LIBREADLINE)
- CHECK_LIBRARY_EXISTS("readline" "history" "" HAVE_LIBHISTORY)
- IF(HAVE_LIBREADLINE AND HAVE_LIBHISTORY)
- SET(HAVE_SYSTEM_READLINE TRUE)
- SET(TEST_PHYSFS_LIBS ${TEST_PHYSFS_LIBS} " " readline curses)
- ADD_DEFINITIONS(-DPHYSFS_HAVE_READLINE=1)
- ENDIF(HAVE_LIBREADLINE AND HAVE_LIBHISTORY)
- ENDIF(HAVE_READLINE_H AND HAVE_HISTORY_H)
- ADD_EXECUTABLE(test_physfs test/test_physfs.c)
- TARGET_LINK_LIBRARIES(test_physfs ${PHYSFS_LIB_TARGET} ${TEST_PHYSFS_LIBS} ${OTHER_LDFLAGS})
- SET(PHYSFS_INSTALL_TARGETS ${PHYSFS_INSTALL_TARGETS} ";test_physfs")
-ENDIF(PHYSFS_BUILD_TEST)
-
-OPTION(PHYSFS_BUILD_WX_TEST "Build wxWidgets test program." TRUE)
-MARK_AS_ADVANCED(PHYSFS_BUILD_WX_TEST)
-IF(PHYSFS_BUILD_WX_TEST)
- SET(wxWidgets_USE_LIBS base core adv)
- SET(wxWidgets_INCLUDE_DIRS_NO_SYSTEM 1)
- FIND_PACKAGE(wxWidgets)
- IF(wxWidgets_FOUND)
- INCLUDE(${wxWidgets_USE_FILE})
- ADD_EXECUTABLE(wxtest_physfs test/wxtest_physfs.cpp)
- SET_SOURCE_FILES_PROPERTIES(test/wxtest_physfs.cpp COMPILE_FLAGS ${wxWidgets_CXX_FLAGS})
- TARGET_LINK_LIBRARIES(wxtest_physfs ${PHYSFS_LIB_TARGET} ${wxWidgets_LIBRARIES} ${OTHER_LDFLAGS})
- SET(PHYSFS_INSTALL_TARGETS ${PHYSFS_INSTALL_TARGETS} ";wxtest_physfs")
- ELSE(wxWidgets_FOUND)
- MESSAGE(STATUS "wxWidgets not found. Disabling wx test app.")
- SET(PHYSFS_BUILD_WX_TEST FALSE)
- ENDIF(wxWidgets_FOUND)
-ENDIF(PHYSFS_BUILD_WX_TEST)
-
-INSTALL(TARGETS ${PHYSFS_INSTALL_TARGETS}
- RUNTIME DESTINATION bin
- LIBRARY DESTINATION lib
- ARCHIVE DESTINATION lib)
-INSTALL(FILES physfs.h DESTINATION include)
-
-FIND_PACKAGE(Doxygen)
-IF(DOXYGEN_FOUND)
- ADD_CUSTOM_TARGET(docs ${DOXYGEN_EXECUTABLE} COMMENT "Building documentation")
-ELSE(DOXYGEN_FOUND)
- MESSAGE(STATUS "Doxygen not found. You won't be able to build documentation.")
-ENDIF(DOXYGEN_FOUND)
-
-IF(UNIX)
- ADD_CUSTOM_TARGET(dist ./extras/makedist.sh ${PHYSFS_VERSION} COMMENT "Building source tarball")
-ENDIF(UNIX)
-
-MACRO(MESSAGE_BOOL_OPTION _NAME _VALUE)
- IF(${_VALUE})
- MESSAGE(STATUS " ${_NAME}: enabled")
- ELSE(${_VALUE})
- MESSAGE(STATUS " ${_NAME}: disabled")
- ENDIF(${_VALUE})
-ENDMACRO(MESSAGE_BOOL_OPTION)
-
-MESSAGE(STATUS "PhysicsFS will build with the following options:")
-MESSAGE_BOOL_OPTION("ZIP support" PHYSFS_ARCHIVE_ZIP)
-MESSAGE_BOOL_OPTION("7zip support" PHYSFS_ARCHIVE_7Z)
-MESSAGE_BOOL_OPTION("GRP support" PHYSFS_ARCHIVE_GRP)
-MESSAGE_BOOL_OPTION("WAD support" PHYSFS_ARCHIVE_WAD)
-MESSAGE_BOOL_OPTION("HOG support" PHYSFS_ARCHIVE_HOG)
-MESSAGE_BOOL_OPTION("MVL support" PHYSFS_ARCHIVE_MVL)
-MESSAGE_BOOL_OPTION("QPAK support" PHYSFS_ARCHIVE_QPAK)
-MESSAGE_BOOL_OPTION("CD-ROM drive support" PHYSFS_HAVE_CDROM_SUPPORT)
-MESSAGE_BOOL_OPTION("Thread safety" PHYSFS_HAVE_THREAD_SUPPORT)
-MESSAGE_BOOL_OPTION("Build own zlib" PHYSFS_INTERNAL_ZLIB)
-MESSAGE_BOOL_OPTION("Build static library" PHYSFS_BUILD_STATIC)
-MESSAGE_BOOL_OPTION("Build shared library" PHYSFS_BUILD_SHARED)
-MESSAGE_BOOL_OPTION("Build wxWidgets test program" PHYSFS_BUILD_WX_TEST)
-MESSAGE_BOOL_OPTION("Build stdio test program" PHYSFS_BUILD_TEST)
-IF(PHYSFS_BUILD_TEST)
- MESSAGE_BOOL_OPTION(" Use readline in test program" HAVE_SYSTEM_READLINE)
-ENDIF(PHYSFS_BUILD_TEST)
-
-# end of CMakeLists.txt ...
-
+++ /dev/null
-Maintainer and general codemonkey:
- Ryan C. Gordon
-
-Tons of win32 help:
- Adam Gates
-
-More win32 hacking:
- Gregory S. Read
-
-Fixes for missing current working directories,
-PHYSFS_setSaneConfig() improvements,
-other bugfixes:
- David Hedbor
-
-Darwin support:
- Patrick Stein
-
-configure fixes,
-RPM specfile:
- Edward Rudd
-
-GetLastModTime API,
-other stuff:
- John R. Hall
-
-Various support, fixes and suggestions:
- Alexander Pipelka
-
-Russian translation,
-Ruby bindings,
-QPAK archiver:
- Ed Sinjiashvili
-
-French translation:
- Stéphane Peter
-
-Debian package support:
- Colin Bayer
-
-"abs-file.h" in "extras" dir:
- Adam D. Moss
-
-WinCE port and other Win32 patches:
- Corona688
-
-German translation:
- Michael Renner
-
-Apple Project Builder support,
-Mac OS X improvements:
- Eric Wing
-
-HOG archiver,
-MVL archiver:
- Bradley Bell
-
-MIX archiver:
- Sebastian Steinhauer
-
-Bug fixes:
- Tolga Dalman
-
-Initial PHYSFS_mount() work:
- Philip D. Bober
-
-Brazillian Portuguese translation:
- Danny Angelo Carminati Grein
-
-Spanish translation:
- Pedro J. Pérez
-
-MacOS Classic fixes,
-MPW support,
-bug fixes:
- Chris Taylor
-
-Mingw support,
-General bug fixes:
- Matze Braun
-
-Bug fixes:
- Jörg Walter
-
-Windows .rc file,
-7zip/lzma archiver:
- Dennis Schridde
-
-OS/2 updates:
- Dave Yeo
-
-Other stuff:
- Your name here! Patches go to icculus@icculus.org ...
-
-/* end of CREDITS.txt ... */
-
+++ /dev/null
-# Doxyfile 1.3.4
-
-# This file describes the settings to be used by the documentation system
-# doxygen (www.doxygen.org) for a project
-#
-# All text after a hash (#) is considered a comment and will be ignored
-# The format is:
-# TAG = value [value, ...]
-# For lists items can also be appended using:
-# TAG += value [value, ...]
-# Values that contain spaces should be placed between quotes (" ")
-
-#---------------------------------------------------------------------------
-# Project related configuration options
-#---------------------------------------------------------------------------
-
-# The PROJECT_NAME tag is a single word (or a sequence of words surrounded
-# by quotes) that should identify the project.
-
-PROJECT_NAME = physfs
-
-# The PROJECT_NUMBER tag can be used to enter a project or revision number.
-# This could be handy for archiving the generated documentation or
-# if some version control system is used.
-
-PROJECT_NUMBER = 1.1.0
-
-# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
-# base path where the generated documentation will be put.
-# If a relative path is entered, it will be relative to the location
-# where doxygen was started. If left blank the current directory will be used.
-
-OUTPUT_DIRECTORY = docs
-
-# The OUTPUT_LANGUAGE tag is used to specify the language in which all
-# documentation generated by doxygen is written. Doxygen will use this
-# information to generate all constant output in the proper language.
-# The default language is English, other supported languages are:
-# Brazilian, Catalan, Chinese, Chinese-Traditional, Croatian, Czech, Danish, Dutch,
-# Finnish, French, German, Greek, Hungarian, Italian, Japanese, Japanese-en
-# (Japanese with English messages), Korean, Norwegian, Polish, Portuguese,
-# Romanian, Russian, Serbian, Slovak, Slovene, Spanish, Swedish, and Ukrainian.
-
-OUTPUT_LANGUAGE = English
-
-# This tag can be used to specify the encoding used in the generated output.
-# The encoding is not always determined by the language that is chosen,
-# but also whether or not the output is meant for Windows or non-Windows users.
-# In case there is a difference, setting the USE_WINDOWS_ENCODING tag to YES
-# forces the Windows encoding (this is the default for the Windows binary),
-# whereas setting the tag to NO uses a Unix-style encoding (the default for
-# all platforms other than Windows).
-
-USE_WINDOWS_ENCODING = NO
-
-# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will
-# include brief member descriptions after the members that are listed in
-# the file and class documentation (similar to JavaDoc).
-# Set to NO to disable this.
-
-BRIEF_MEMBER_DESC = YES
-
-# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend
-# the brief description of a member or function before the detailed description.
-# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
-# brief descriptions will be completely suppressed.
-
-REPEAT_BRIEF = YES
-
-# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
-# Doxygen will generate a detailed section even if there is only a brief
-# description.
-
-ALWAYS_DETAILED_SEC = NO
-
-# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all inherited
-# members of a class in the documentation of that class as if those members were
-# ordinary class members. Constructors, destructors and assignment operators of
-# the base classes will not be shown.
-
-INLINE_INHERITED_MEMB = NO
-
-# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full
-# path before files name in the file list and in the header files. If set
-# to NO the shortest path that makes the file name unique will be used.
-
-FULL_PATH_NAMES = NO
-
-# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag
-# can be used to strip a user-defined part of the path. Stripping is
-# only done if one of the specified strings matches the left-hand part of
-# the path. It is allowed to use relative paths in the argument list.
-
-STRIP_FROM_PATH =
-
-# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter
-# (but less readable) file names. This can be useful is your file systems
-# doesn't support long names like on DOS, Mac, or CD-ROM.
-
-SHORT_NAMES = NO
-
-# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen
-# will interpret the first line (until the first dot) of a JavaDoc-style
-# comment as the brief description. If set to NO, the JavaDoc
-# comments will behave just like the Qt-style comments (thus requiring an
-# explict @brief command for a brief description.
-
-JAVADOC_AUTOBRIEF = NO
-
-# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen
-# treat a multi-line C++ special comment block (i.e. a block of //! or ///
-# comments) as a brief description. This used to be the default behaviour.
-# The new default is to treat a multi-line C++ comment block as a detailed
-# description. Set this tag to YES if you prefer the old behaviour instead.
-
-MULTILINE_CPP_IS_BRIEF = NO
-
-# If the DETAILS_AT_TOP tag is set to YES then Doxygen
-# will output the detailed description near the top, like JavaDoc.
-# If set to NO, the detailed description appears after the member
-# documentation.
-
-DETAILS_AT_TOP = NO
-
-# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented
-# member inherits the documentation from any documented member that it
-# reimplements.
-
-INHERIT_DOCS = YES
-
-# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
-# tag is set to YES, then doxygen will reuse the documentation of the first
-# member in the group (if any) for the other members of the group. By default
-# all members of a group must be documented explicitly.
-
-DISTRIBUTE_GROUP_DOC = NO
-
-# The TAB_SIZE tag can be used to set the number of spaces in a tab.
-# Doxygen uses this value to replace tabs by spaces in code fragments.
-
-TAB_SIZE = 4
-
-# This tag can be used to specify a number of aliases that acts
-# as commands in the documentation. An alias has the form "name=value".
-# For example adding "sideeffect=\par Side Effects:\n" will allow you to
-# put the command \sideeffect (or @sideeffect) in the documentation, which
-# will result in a user-defined paragraph with heading "Side Effects:".
-# You can put \n's in the value part of an alias to insert newlines.
-
-ALIASES =
-
-# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources
-# only. Doxygen will then generate output that is more tailored for C.
-# For instance, some of the names that are used will be different. The list
-# of all members will be omitted, etc.
-
-OPTIMIZE_OUTPUT_FOR_C = YES
-
-# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java sources
-# only. Doxygen will then generate output that is more tailored for Java.
-# For instance, namespaces will be presented as packages, qualified scopes
-# will look different, etc.
-
-OPTIMIZE_OUTPUT_JAVA = NO
-
-# Set the SUBGROUPING tag to YES (the default) to allow class member groups of
-# the same type (for instance a group of public functions) to be put as a
-# subgroup of that type (e.g. under the Public Functions section). Set it to
-# NO to prevent subgrouping. Alternatively, this can be done per class using
-# the \nosubgrouping command.
-
-SUBGROUPING = YES
-
-#---------------------------------------------------------------------------
-# Build related configuration options
-#---------------------------------------------------------------------------
-
-# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in
-# documentation are documented, even if no documentation was available.
-# Private class members and static file members will be hidden unless
-# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
-
-EXTRACT_ALL = NO
-
-# If the EXTRACT_PRIVATE tag is set to YES all private members of a class
-# will be included in the documentation.
-
-EXTRACT_PRIVATE = NO
-
-# If the EXTRACT_STATIC tag is set to YES all static members of a file
-# will be included in the documentation.
-
-EXTRACT_STATIC = NO
-
-# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs)
-# defined locally in source files will be included in the documentation.
-# If set to NO only classes defined in header files are included.
-
-EXTRACT_LOCAL_CLASSES = NO
-
-# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all
-# undocumented members of documented classes, files or namespaces.
-# If set to NO (the default) these members will be included in the
-# various overviews, but no documentation section is generated.
-# This option has no effect if EXTRACT_ALL is enabled.
-
-HIDE_UNDOC_MEMBERS = NO
-
-# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all
-# undocumented classes that are normally visible in the class hierarchy.
-# If set to NO (the default) these classes will be included in the various
-# overviews. This option has no effect if EXTRACT_ALL is enabled.
-
-HIDE_UNDOC_CLASSES = NO
-
-# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all
-# friend (class|struct|union) declarations.
-# If set to NO (the default) these declarations will be included in the
-# documentation.
-
-HIDE_FRIEND_COMPOUNDS = NO
-
-# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any
-# documentation blocks found inside the body of a function.
-# If set to NO (the default) these blocks will be appended to the
-# function's detailed documentation block.
-
-HIDE_IN_BODY_DOCS = NO
-
-# The INTERNAL_DOCS tag determines if documentation
-# that is typed after a \internal command is included. If the tag is set
-# to NO (the default) then the documentation will be excluded.
-# Set it to YES to include the internal documentation.
-
-INTERNAL_DOCS = NO
-
-# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate
-# file names in lower-case letters. If set to YES upper-case letters are also
-# allowed. This is useful if you have classes or files whose names only differ
-# in case and if your file system supports case sensitive file names. Windows
-# users are advised to set this option to NO.
-
-CASE_SENSE_NAMES = YES
-
-# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen
-# will show members with their full class and namespace scopes in the
-# documentation. If set to YES the scope will be hidden.
-
-HIDE_SCOPE_NAMES = NO
-
-# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen
-# will put a list of the files that are included by a file in the documentation
-# of that file.
-
-SHOW_INCLUDE_FILES = YES
-
-# If the INLINE_INFO tag is set to YES (the default) then a tag [inline]
-# is inserted in the documentation for inline members.
-
-INLINE_INFO = YES
-
-# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen
-# will sort the (detailed) documentation of file and class members
-# alphabetically by member name. If set to NO the members will appear in
-# declaration order.
-
-SORT_MEMBER_DOCS = YES
-
-# The GENERATE_TODOLIST tag can be used to enable (YES) or
-# disable (NO) the todo list. This list is created by putting \todo
-# commands in the documentation.
-
-GENERATE_TODOLIST = YES
-
-# The GENERATE_TESTLIST tag can be used to enable (YES) or
-# disable (NO) the test list. This list is created by putting \test
-# commands in the documentation.
-
-GENERATE_TESTLIST = YES
-
-# The GENERATE_BUGLIST tag can be used to enable (YES) or
-# disable (NO) the bug list. This list is created by putting \bug
-# commands in the documentation.
-
-GENERATE_BUGLIST = YES
-
-# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or
-# disable (NO) the deprecated list. This list is created by putting
-# \deprecated commands in the documentation.
-
-GENERATE_DEPRECATEDLIST= YES
-
-# The ENABLED_SECTIONS tag can be used to enable conditional
-# documentation sections, marked by \if sectionname ... \endif.
-
-ENABLED_SECTIONS =
-
-# The MAX_INITIALIZER_LINES tag determines the maximum number of lines
-# the initial value of a variable or define consists of for it to appear in
-# the documentation. If the initializer consists of more lines than specified
-# here it will be hidden. Use a value of 0 to hide initializers completely.
-# The appearance of the initializer of individual variables and defines in the
-# documentation can be controlled using \showinitializer or \hideinitializer
-# command in the documentation regardless of this setting.
-
-MAX_INITIALIZER_LINES = 30
-
-# Set the SHOW_USED_FILES tag to NO to disable the list of files generated
-# at the bottom of the documentation of classes and structs. If set to YES the
-# list will mention the files that were used to generate the documentation.
-
-SHOW_USED_FILES = YES
-
-#---------------------------------------------------------------------------
-# configuration options related to warning and progress messages
-#---------------------------------------------------------------------------
-
-# The QUIET tag can be used to turn on/off the messages that are generated
-# by doxygen. Possible values are YES and NO. If left blank NO is used.
-
-QUIET = NO
-
-# The WARNINGS tag can be used to turn on/off the warning messages that are
-# generated by doxygen. Possible values are YES and NO. If left blank
-# NO is used.
-
-WARNINGS = YES
-
-# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings
-# for undocumented members. If EXTRACT_ALL is set to YES then this flag will
-# automatically be disabled.
-
-WARN_IF_UNDOCUMENTED = YES
-
-# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for
-# potential errors in the documentation, such as not documenting some
-# parameters in a documented function, or documenting parameters that
-# don't exist or using markup commands wrongly.
-
-WARN_IF_DOC_ERROR = YES
-
-# The WARN_FORMAT tag determines the format of the warning messages that
-# doxygen can produce. The string should contain the $file, $line, and $text
-# tags, which will be replaced by the file and line number from which the
-# warning originated and the warning text.
-
-WARN_FORMAT = "$file:$line: $text"
-
-# The WARN_LOGFILE tag can be used to specify a file to which warning
-# and error messages should be written. If left blank the output is written
-# to stderr.
-
-WARN_LOGFILE =
-
-#---------------------------------------------------------------------------
-# configuration options related to the input files
-#---------------------------------------------------------------------------
-
-# The INPUT tag can be used to specify the files and/or directories that contain
-# documented source files. You may enter file names like "myfile.cpp" or
-# directories like "/usr/src/myproject". Separate the files or directories
-# with spaces.
-
-INPUT = physfs.h
-
-# If the value of the INPUT tag contains directories, you can use the
-# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
-# and *.h) to filter out the source-files in the directories. If left
-# blank the following patterns are tested:
-# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx *.hpp
-# *.h++ *.idl *.odl *.cs *.php *.php3 *.inc
-
-FILE_PATTERNS =
-
-# The RECURSIVE tag can be used to turn specify whether or not subdirectories
-# should be searched for input files as well. Possible values are YES and NO.
-# If left blank NO is used.
-
-RECURSIVE = NO
-
-# The EXCLUDE tag can be used to specify files and/or directories that should
-# excluded from the INPUT source files. This way you can easily exclude a
-# subdirectory from a directory tree whose root is specified with the INPUT tag.
-
-EXCLUDE =
-
-# The EXCLUDE_SYMLINKS tag can be used select whether or not files or directories
-# that are symbolic links (a Unix filesystem feature) are excluded from the input.
-
-EXCLUDE_SYMLINKS = NO
-
-# If the value of the INPUT tag contains directories, you can use the
-# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
-# certain files from those directories.
-
-EXCLUDE_PATTERNS =
-
-# The EXAMPLE_PATH tag can be used to specify one or more files or
-# directories that contain example code fragments that are included (see
-# the \include command).
-
-EXAMPLE_PATH =
-
-# If the value of the EXAMPLE_PATH tag contains directories, you can use the
-# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
-# and *.h) to filter out the source-files in the directories. If left
-# blank all files are included.
-
-EXAMPLE_PATTERNS =
-
-# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be
-# searched for input files to be used with the \include or \dontinclude
-# commands irrespective of the value of the RECURSIVE tag.
-# Possible values are YES and NO. If left blank NO is used.
-
-EXAMPLE_RECURSIVE = NO
-
-# The IMAGE_PATH tag can be used to specify one or more files or
-# directories that contain image that are included in the documentation (see
-# the \image command).
-
-IMAGE_PATH =
-
-# The INPUT_FILTER tag can be used to specify a program that doxygen should
-# invoke to filter for each input file. Doxygen will invoke the filter program
-# by executing (via popen()) the command <filter> <input-file>, where <filter>
-# is the value of the INPUT_FILTER tag, and <input-file> is the name of an
-# input file. Doxygen will then use the output that the filter program writes
-# to standard output.
-
-INPUT_FILTER =
-
-# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
-# INPUT_FILTER) will be used to filter the input files when producing source
-# files to browse (i.e. when SOURCE_BROWSER is set to YES).
-
-FILTER_SOURCE_FILES = NO
-
-#---------------------------------------------------------------------------
-# configuration options related to source browsing
-#---------------------------------------------------------------------------
-
-# If the SOURCE_BROWSER tag is set to YES then a list of source files will
-# be generated. Documented entities will be cross-referenced with these sources.
-
-SOURCE_BROWSER = NO
-
-# Setting the INLINE_SOURCES tag to YES will include the body
-# of functions and classes directly in the documentation.
-
-INLINE_SOURCES = NO
-
-# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct
-# doxygen to hide any special comment blocks from generated source code
-# fragments. Normal C and C++ comments will always remain visible.
-
-STRIP_CODE_COMMENTS = YES
-
-# If the REFERENCED_BY_RELATION tag is set to YES (the default)
-# then for each documented function all documented
-# functions referencing it will be listed.
-
-REFERENCED_BY_RELATION = YES
-
-# If the REFERENCES_RELATION tag is set to YES (the default)
-# then for each documented function all documented entities
-# called/used by that function will be listed.
-
-REFERENCES_RELATION = YES
-
-# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen
-# will generate a verbatim copy of the header file for each class for
-# which an include is specified. Set to NO to disable this.
-
-VERBATIM_HEADERS = YES
-
-#---------------------------------------------------------------------------
-# configuration options related to the alphabetical class index
-#---------------------------------------------------------------------------
-
-# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index
-# of all compounds will be generated. Enable this if the project
-# contains a lot of classes, structs, unions or interfaces.
-
-ALPHABETICAL_INDEX = NO
-
-# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then
-# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns
-# in which this list will be split (can be a number in the range [1..20])
-
-COLS_IN_ALPHA_INDEX = 5
-
-# In case all classes in a project start with a common prefix, all
-# classes will be put under the same header in the alphabetical index.
-# The IGNORE_PREFIX tag can be used to specify one or more prefixes that
-# should be ignored while generating the index headers.
-
-IGNORE_PREFIX =
-
-#---------------------------------------------------------------------------
-# configuration options related to the HTML output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_HTML tag is set to YES (the default) Doxygen will
-# generate HTML output.
-
-GENERATE_HTML = YES
-
-# The HTML_OUTPUT tag is used to specify where the HTML docs will be put.
-# If a relative path is entered the value of OUTPUT_DIRECTORY will be
-# put in front of it. If left blank `html' will be used as the default path.
-
-HTML_OUTPUT = html
-
-# The HTML_FILE_EXTENSION tag can be used to specify the file extension for
-# each generated HTML page (for example: .htm,.php,.asp). If it is left blank
-# doxygen will generate files with .html extension.
-
-HTML_FILE_EXTENSION = .html
-
-# The HTML_HEADER tag can be used to specify a personal HTML header for
-# each generated HTML page. If it is left blank doxygen will generate a
-# standard header.
-
-HTML_HEADER =
-
-# The HTML_FOOTER tag can be used to specify a personal HTML footer for
-# each generated HTML page. If it is left blank doxygen will generate a
-# standard footer.
-
-HTML_FOOTER =
-
-# The HTML_STYLESHEET tag can be used to specify a user-defined cascading
-# style sheet that is used by each HTML page. It can be used to
-# fine-tune the look of the HTML output. If the tag is left blank doxygen
-# will generate a default style sheet
-
-HTML_STYLESHEET =
-
-# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes,
-# files or namespaces will be aligned in HTML using tables. If set to
-# NO a bullet list will be used.
-
-HTML_ALIGN_MEMBERS = YES
-
-# If the GENERATE_HTMLHELP tag is set to YES, additional index files
-# will be generated that can be used as input for tools like the
-# Microsoft HTML help workshop to generate a compressed HTML help file (.chm)
-# of the generated HTML documentation.
-
-GENERATE_HTMLHELP = NO
-
-# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can
-# be used to specify the file name of the resulting .chm file. You
-# can add a path in front of the file if the result should not be
-# written to the html output dir.
-
-CHM_FILE =
-
-# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can
-# be used to specify the location (absolute path including file name) of
-# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run
-# the HTML help compiler on the generated index.hhp.
-
-HHC_LOCATION =
-
-# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag
-# controls if a separate .chi index file is generated (YES) or that
-# it should be included in the master .chm file (NO).
-
-GENERATE_CHI = NO
-
-# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag
-# controls whether a binary table of contents is generated (YES) or a
-# normal table of contents (NO) in the .chm file.
-
-BINARY_TOC = NO
-
-# The TOC_EXPAND flag can be set to YES to add extra items for group members
-# to the contents of the HTML help documentation and to the tree view.
-
-TOC_EXPAND = NO
-
-# The DISABLE_INDEX tag can be used to turn on/off the condensed index at
-# top of each HTML page. The value NO (the default) enables the index and
-# the value YES disables it.
-
-DISABLE_INDEX = NO
-
-# This tag can be used to set the number of enum values (range [1..20])
-# that doxygen will group on one line in the generated HTML documentation.
-
-ENUM_VALUES_PER_LINE = 4
-
-# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be
-# generated containing a tree-like index structure (just like the one that
-# is generated for HTML Help). For this to work a browser that supports
-# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+,
-# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are
-# probably better off using the HTML help feature.
-
-GENERATE_TREEVIEW = NO
-
-# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be
-# used to set the initial width (in pixels) of the frame in which the tree
-# is shown.
-
-TREEVIEW_WIDTH = 250
-
-#---------------------------------------------------------------------------
-# configuration options related to the LaTeX output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will
-# generate Latex output.
-
-GENERATE_LATEX = YES
-
-# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put.
-# If a relative path is entered the value of OUTPUT_DIRECTORY will be
-# put in front of it. If left blank `latex' will be used as the default path.
-
-LATEX_OUTPUT = latex
-
-# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be
-# invoked. If left blank `latex' will be used as the default command name.
-
-LATEX_CMD_NAME = latex
-
-# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to
-# generate index for LaTeX. If left blank `makeindex' will be used as the
-# default command name.
-
-MAKEINDEX_CMD_NAME = makeindex
-
-# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact
-# LaTeX documents. This may be useful for small projects and may help to
-# save some trees in general.
-
-COMPACT_LATEX = NO
-
-# The PAPER_TYPE tag can be used to set the paper type that is used
-# by the printer. Possible values are: a4, a4wide, letter, legal and
-# executive. If left blank a4wide will be used.
-
-PAPER_TYPE = a4wide
-
-# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX
-# packages that should be included in the LaTeX output.
-
-EXTRA_PACKAGES =
-
-# The LATEX_HEADER tag can be used to specify a personal LaTeX header for
-# the generated latex document. The header should contain everything until
-# the first chapter. If it is left blank doxygen will generate a
-# standard header. Notice: only use this tag if you know what you are doing!
-
-LATEX_HEADER =
-
-# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated
-# is prepared for conversion to pdf (using ps2pdf). The pdf file will
-# contain links (just like the HTML output) instead of page references
-# This makes the output suitable for online browsing using a pdf viewer.
-
-PDF_HYPERLINKS = NO
-
-# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of
-# plain latex in the generated Makefile. Set this option to YES to get a
-# higher quality PDF documentation.
-
-USE_PDFLATEX = NO
-
-# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode.
-# command to the generated LaTeX files. This will instruct LaTeX to keep
-# running if errors occur, instead of asking the user for help.
-# This option is also used when generating formulas in HTML.
-
-LATEX_BATCHMODE = NO
-
-# If LATEX_HIDE_INDICES is set to YES then doxygen will not
-# include the index chapters (such as File Index, Compound Index, etc.)
-# in the output.
-
-LATEX_HIDE_INDICES = NO
-
-#---------------------------------------------------------------------------
-# configuration options related to the RTF output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output
-# The RTF output is optimised for Word 97 and may not look very pretty with
-# other RTF readers or editors.
-
-GENERATE_RTF = NO
-
-# The RTF_OUTPUT tag is used to specify where the RTF docs will be put.
-# If a relative path is entered the value of OUTPUT_DIRECTORY will be
-# put in front of it. If left blank `rtf' will be used as the default path.
-
-RTF_OUTPUT = rtf
-
-# If the COMPACT_RTF tag is set to YES Doxygen generates more compact
-# RTF documents. This may be useful for small projects and may help to
-# save some trees in general.
-
-COMPACT_RTF = NO
-
-# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated
-# will contain hyperlink fields. The RTF file will
-# contain links (just like the HTML output) instead of page references.
-# This makes the output suitable for online browsing using WORD or other
-# programs which support those fields.
-# Note: wordpad (write) and others do not support links.
-
-RTF_HYPERLINKS = NO
-
-# Load stylesheet definitions from file. Syntax is similar to doxygen's
-# config file, i.e. a series of assigments. You only have to provide
-# replacements, missing definitions are set to their default value.
-
-RTF_STYLESHEET_FILE =
-
-# Set optional variables used in the generation of an rtf document.
-# Syntax is similar to doxygen's config file.
-
-RTF_EXTENSIONS_FILE =
-
-#---------------------------------------------------------------------------
-# configuration options related to the man page output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_MAN tag is set to YES (the default) Doxygen will
-# generate man pages
-
-GENERATE_MAN = YES
-
-# The MAN_OUTPUT tag is used to specify where the man pages will be put.
-# If a relative path is entered the value of OUTPUT_DIRECTORY will be
-# put in front of it. If left blank `man' will be used as the default path.
-
-MAN_OUTPUT = man
-
-# The MAN_EXTENSION tag determines the extension that is added to
-# the generated man pages (default is the subroutine's section .3)
-
-MAN_EXTENSION = .3
-
-# If the MAN_LINKS tag is set to YES and Doxygen generates man output,
-# then it will generate one additional man file for each entity
-# documented in the real man page(s). These additional files
-# only source the real man page, but without them the man command
-# would be unable to find the correct page. The default is NO.
-
-MAN_LINKS = YES
-
-#---------------------------------------------------------------------------
-# configuration options related to the XML output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_XML tag is set to YES Doxygen will
-# generate an XML file that captures the structure of
-# the code including all documentation. Note that this
-# feature is still experimental and incomplete at the
-# moment.
-
-GENERATE_XML = NO
-
-# The XML_OUTPUT tag is used to specify where the XML pages will be put.
-# If a relative path is entered the value of OUTPUT_DIRECTORY will be
-# put in front of it. If left blank `xml' will be used as the default path.
-
-XML_OUTPUT = xml
-
-# The XML_SCHEMA tag can be used to specify an XML schema,
-# which can be used by a validating XML parser to check the
-# syntax of the XML files.
-
-XML_SCHEMA =
-
-# The XML_DTD tag can be used to specify an XML DTD,
-# which can be used by a validating XML parser to check the
-# syntax of the XML files.
-
-XML_DTD =
-
-#---------------------------------------------------------------------------
-# configuration options for the AutoGen Definitions output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will
-# generate an AutoGen Definitions (see autogen.sf.net) file
-# that captures the structure of the code including all
-# documentation. Note that this feature is still experimental
-# and incomplete at the moment.
-
-GENERATE_AUTOGEN_DEF = NO
-
-#---------------------------------------------------------------------------
-# configuration options related to the Perl module output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_PERLMOD tag is set to YES Doxygen will
-# generate a Perl module file that captures the structure of
-# the code including all documentation. Note that this
-# feature is still experimental and incomplete at the
-# moment.
-
-GENERATE_PERLMOD = NO
-
-# If the PERLMOD_LATEX tag is set to YES Doxygen will generate
-# the necessary Makefile rules, Perl scripts and LaTeX code to be able
-# to generate PDF and DVI output from the Perl module output.
-
-PERLMOD_LATEX = NO
-
-# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be
-# nicely formatted so it can be parsed by a human reader. This is useful
-# if you want to understand what is going on. On the other hand, if this
-# tag is set to NO the size of the Perl module output will be much smaller
-# and Perl will parse it just the same.
-
-PERLMOD_PRETTY = YES
-
-# The names of the make variables in the generated doxyrules.make file
-# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX.
-# This is useful so different doxyrules.make files included by the same
-# Makefile don't overwrite each other's variables.
-
-PERLMOD_MAKEVAR_PREFIX =
-
-#---------------------------------------------------------------------------
-# Configuration options related to the preprocessor
-#---------------------------------------------------------------------------
-
-# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will
-# evaluate all C-preprocessor directives found in the sources and include
-# files.
-
-ENABLE_PREPROCESSING = YES
-
-# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro
-# names in the source code. If set to NO (the default) only conditional
-# compilation will be performed. Macro expansion can be done in a controlled
-# way by setting EXPAND_ONLY_PREDEF to YES.
-
-MACRO_EXPANSION = YES
-
-# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES
-# then the macro expansion is limited to the macros specified with the
-# PREDEFINED and EXPAND_AS_PREDEFINED tags.
-
-EXPAND_ONLY_PREDEF = YES
-
-# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files
-# in the INCLUDE_PATH (see below) will be search if a #include is found.
-
-SEARCH_INCLUDES = YES
-
-# The INCLUDE_PATH tag can be used to specify one or more directories that
-# contain include files that are not input files but should be processed by
-# the preprocessor.
-
-INCLUDE_PATH =
-
-# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
-# patterns (like *.h and *.hpp) to filter out the header-files in the
-# directories. If left blank, the patterns specified with FILE_PATTERNS will
-# be used.
-
-INCLUDE_FILE_PATTERNS =
-
-# The PREDEFINED tag can be used to specify one or more macro names that
-# are defined before the preprocessor is started (similar to the -D option of
-# gcc). The argument of the tag is a list of macros of the form: name
-# or name=definition (no spaces). If the definition and the = are
-# omitted =1 is assumed.
-
-PREDEFINED = DOXYGEN_SHOULD_IGNORE_THIS=1 \
- __EXPORT__=
-
-# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then
-# this tag can be used to specify a list of macro names that should be expanded.
-# The macro definition that is found in the sources will be used.
-# Use the PREDEFINED tag if you want to use a different macro definition.
-
-EXPAND_AS_DEFINED =
-
-# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then
-# doxygen's preprocessor will remove all function-like macros that are alone
-# on a line, have an all uppercase name, and do not end with a semicolon. Such
-# function macros are typically used for boiler-plate code, and will confuse the
-# parser if not removed.
-
-SKIP_FUNCTION_MACROS = YES
-
-#---------------------------------------------------------------------------
-# Configuration::addtions related to external references
-#---------------------------------------------------------------------------
-
-# The TAGFILES option can be used to specify one or more tagfiles.
-# Optionally an initial location of the external documentation
-# can be added for each tagfile. The format of a tag file without
-# this location is as follows:
-# TAGFILES = file1 file2 ...
-# Adding location for the tag files is done as follows:
-# TAGFILES = file1=loc1 "file2 = loc2" ...
-# where "loc1" and "loc2" can be relative or absolute paths or
-# URLs. If a location is present for each tag, the installdox tool
-# does not have to be run to correct the links.
-# Note that each tag file must have a unique name
-# (where the name does NOT include the path)
-# If a tag file is not located in the directory in which doxygen
-# is run, you must also specify the path to the tagfile here.
-
-TAGFILES =
-
-# When a file name is specified after GENERATE_TAGFILE, doxygen will create
-# a tag file that is based on the input files it reads.
-
-GENERATE_TAGFILE =
-
-# If the ALLEXTERNALS tag is set to YES all external classes will be listed
-# in the class index. If set to NO only the inherited external classes
-# will be listed.
-
-ALLEXTERNALS = NO
-
-# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed
-# in the modules index. If set to NO, only the current project's groups will
-# be listed.
-
-EXTERNAL_GROUPS = YES
-
-# The PERL_PATH should be the absolute path and name of the perl script
-# interpreter (i.e. the result of `which perl').
-
-PERL_PATH = /usr/bin/perl
-
-#---------------------------------------------------------------------------
-# Configuration options related to the dot tool
-#---------------------------------------------------------------------------
-
-# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will
-# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base or
-# super classes. Setting the tag to NO turns the diagrams off. Note that this
-# option is superceded by the HAVE_DOT option below. This is only a fallback. It is
-# recommended to install and use dot, since it yields more powerful graphs.
-
-CLASS_DIAGRAMS = NO
-
-# If set to YES, the inheritance and collaboration graphs will hide
-# inheritance and usage relations if the target is undocumented
-# or is not a class.
-
-HIDE_UNDOC_RELATIONS = YES
-
-# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
-# available from the path. This tool is part of Graphviz, a graph visualization
-# toolkit from AT&T and Lucent Bell Labs. The other options in this section
-# have no effect if this option is set to NO (the default)
-
-HAVE_DOT = NO
-
-# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen
-# will generate a graph for each documented class showing the direct and
-# indirect inheritance relations. Setting this tag to YES will force the
-# the CLASS_DIAGRAMS tag to NO.
-
-CLASS_GRAPH = NO
-
-# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen
-# will generate a graph for each documented class showing the direct and
-# indirect implementation dependencies (inheritance, containment, and
-# class references variables) of the class with other documented classes.
-
-COLLABORATION_GRAPH = NO
-
-# If the UML_LOOK tag is set to YES doxygen will generate inheritance and
-# collaboration diagrams in a style similiar to the OMG's Unified Modeling
-# Language.
-
-UML_LOOK = NO
-
-# If set to YES, the inheritance and collaboration graphs will show the
-# relations between templates and their instances.
-
-TEMPLATE_RELATIONS = NO
-
-# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT
-# tags are set to YES then doxygen will generate a graph for each documented
-# file showing the direct and indirect include dependencies of the file with
-# other documented files.
-
-INCLUDE_GRAPH = NO
-
-# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and
-# HAVE_DOT tags are set to YES then doxygen will generate a graph for each
-# documented header file showing the documented files that directly or
-# indirectly include this file.
-
-INCLUDED_BY_GRAPH = YES
-
-# If the CALL_GRAPH and HAVE_DOT tags are set to YES then doxygen will
-# generate a call dependency graph for every global function or class method.
-# Note that enabling this option will significantly increase the time of a run.
-# So in most cases it will be better to enable call graphs for selected
-# functions only using the \callgraph command.
-
-CALL_GRAPH = NO
-
-# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen
-# will graphical hierarchy of all classes instead of a textual one.
-
-GRAPHICAL_HIERARCHY = YES
-
-# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images
-# generated by dot. Possible values are png, jpg, or gif
-# If left blank png will be used.
-
-DOT_IMAGE_FORMAT = png
-
-# The tag DOT_PATH can be used to specify the path where the dot tool can be
-# found. If left blank, it is assumed the dot tool can be found on the path.
-
-DOT_PATH =
-
-# The DOTFILE_DIRS tag can be used to specify one or more directories that
-# contain dot files that are included in the documentation (see the
-# \dotfile command).
-
-DOTFILE_DIRS =
-
-# The MAX_DOT_GRAPH_WIDTH tag can be used to set the maximum allowed width
-# (in pixels) of the graphs generated by dot. If a graph becomes larger than
-# this value, doxygen will try to truncate the graph, so that it fits within
-# the specified constraint. Beware that most browsers cannot cope with very
-# large images.
-
-MAX_DOT_GRAPH_WIDTH = 1024
-
-# The MAX_DOT_GRAPH_HEIGHT tag can be used to set the maximum allows height
-# (in pixels) of the graphs generated by dot. If a graph becomes larger than
-# this value, doxygen will try to truncate the graph, so that it fits within
-# the specified constraint. Beware that most browsers cannot cope with very
-# large images.
-
-MAX_DOT_GRAPH_HEIGHT = 1024
-
-# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the
-# graphs generated by dot. A depth value of 3 means that only nodes reachable
-# from the root by following a path via at most 3 edges will be shown. Nodes that
-# lay further from the root node will be omitted. Note that setting this option to
-# 1 or 2 may greatly reduce the computation time needed for large code bases. Also
-# note that a graph may be further truncated if the graph's image dimensions are
-# not sufficient to fit the graph (see MAX_DOT_GRAPH_WIDTH and MAX_DOT_GRAPH_HEIGHT).
-# If 0 is used for the depth value (the default), the graph is not depth-constrained.
-
-MAX_DOT_GRAPH_DEPTH = 0
-
-# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will
-# generate a legend page explaining the meaning of the various boxes and
-# arrows in the dot generated graphs.
-
-GENERATE_LEGEND = YES
-
-# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will
-# remove the intermediate dot files that are used to generate
-# the various graphs.
-
-DOT_CLEANUP = YES
-
-#---------------------------------------------------------------------------
-# Configuration::addtions related to the search engine
-#---------------------------------------------------------------------------
-
-# The SEARCHENGINE tag specifies whether or not a search engine should be
-# used. If set to NO the values of all tags below this one will be ignored.
-
-SEARCHENGINE = NO
+++ /dev/null
-
-The latest PhysicsFS information and releases can be found at:
- http://icculus.org/physfs/
-
-Building is (ahem) very easy.
-
-
-ALL PLATFORMS:
-
-Please understand your rights and mine: read the text file LICENSE.txt in the
- root of the source tree. If you can't abide by it, delete this source tree
- now. The license is extremely liberal, even to closed-source, commercial
- applications.
-
-If you've got Doxygen (http://www.doxygen.org/) installed, you can run it
- without any command line arguments in the root of the source tree to generate
- the API reference (or build the "docs" target from your build system). This
- is optional. You can browse the API docs online here:
-
- http://icculus.org/physfs/docs/
-
-
-
-
-UNIX:
-
-You will need CMake (http://www.cmake.org/) 2.4 or later installed.
-
-Run "cmake ." in the root of the source directory to generate Makefiles.
- You can then run "ccmake ." and customize the build, but the defaults are
- probably okay. You can have CMake generate KDevelop project files if you
- prefer these.
-
-Run "make". PhysicsFS will now build.
-
-As root, run "make install".
- If you get sick of the library, run "xargs rm < install_manifest.txt" as root
- and it will remove all traces of the library from the system paths.
-
-Primary Unix development is done with GNU/Linux, but PhysicsFS is known to
- work out of the box with several flavors of Unix. It it doesn't work, patches
- to get it running can be sent to icculus@icculus.org.
-
-
-
-BeOS:
-
-Use the "Unix" instructions, above. The CMake port to BeOS is fairly new at
- the time of this writing, but it works. You can get a build of CMake from
- bebits.com or build it yourself from source from cmake.org.
-
-
-
-Windows:
-
-If building with CygWin, mingw32 or something else that uses the GNU
- toolchain, follow the Unix instructions, above.
-
-If you want to use Visual Studio, nmake, or the Platform SDK, you will need
- CMake (http://www.cmake.org/) 2.4 or later installed. Point CMake at the
- CMakeLists.txt file in the root of the source directory and hit the
- "Configure" button. After telling it what type of compiler you are targeting
- (Borland, Visual Studio, etc), CMake will process for while and then give you
- a list of options you can change (what archivers you want to support, etc).
- If you aren't sure, the defaults are probably fine. Hit the "Configure"
- button again, then "OK" once configuration has completed with options that
- match your liking. Now project files for your favorite programming
- environment will be generated for you in the directory you specified.
- Go there and use them to build PhysicsFS.
-
-PhysicsFS will only link directly against system libraries that have existed
- since Windows 95 and Windows NT 3.51. If there's a newer API we want to use,
- we try to dynamically load it at runtime and fallback to a reasonable
- behaviour when we can't find it...this is used for Unicode support and
- locating user-specific directories, etc.
-
-PhysicsFS has not been tested on 64-bit Windows, but probably works. There is
- no 16-bit Windows support at all. Reports of success and problems can go to
- Ryan at icculus@icculus.org ...
-
-If someone is willing to maintain prebuilt PhysicsFS DLLs, I'd like to hear
-from you; send an email to icculus@icculus.org ...
-
-
-
-PocketPC/WindowsCE:
-
-Code exists for PocketPC support, and there are shipping titles that used
- PhysicsFS 1.0 on PocketPC...but it isn't tested in 2.0, and is probably
- broken with the new build system. Please send patches.
-
-
-
-MAC OS 8/9:
-
-Classic Mac OS support has been dropped in PhysicsFS 2.0. Apple hasn't updated
- pre-OSX versions in almost a decade at this point, none of the hardware
- they've shipped will boot it for almost as many years, and finding
- developer tools for it is becoming almost impossible. As the switch to Intel
- hardware has removed the "Classic" emulation environment, it was time to
- remove support from PhysicsFS. That being said, the PhysicsFS 1.0 branch can
- still target back to Mac OS 8.5, so you can use that if you need support for
- this legacy OS. We still very much support Mac OS X, though: see below.
-
-
-
-MAC OS X:
-
-You will need CMake (http://www.cmake.org/) 2.4 or later installed.
-
-You can either generate a Unix makefile with CMake, or generate an Xcode
- project, whichever makes you more comfortable.
-
-PowerPC and Intel Macs should both be supported.
-
-If someone is willing to maintain prebuilt PhysicsFS Shared Libraries for
- Mac OS X, I'd like to hear from you; send an email to icculus@icculus.org.
-
-
-
-OS/2:
-
-You need Innotek GCC and libc installed (or kLIBC). I tried this on a stock
- Warp 4 install, no fixpaks. You need to install link386.exe (Selective
- Install, "link object modules" option). Once klibc and GCC are installed
- correctly, unpack the source to PhysicsFS and run the script
- file "makeos2.cmd". I know this isn't ideal, but I wanted to have this build
- without users having to hunt down a "make" program.
-
-Someone please port CMake to OS/2. Ideally I'd like to be able to target
- Innotek GCC and OpenWatcom with CMake.
-
-If someone is willing to maintain prebuilt PhysicsFS Shared Libraries for
- OS/2, I'd like to hear from you; send an email to icculus@icculus.org.
-
-
-
-OTHER PLATFORMS:
-
-Many Unix-like platforms might "just work" with CMake. Some of these platforms
- are known to have worked at one time, but have not been heavily tested, if
- tested at all. PhysicsFS is, as far as we know, 64-bit and byteorder clean,
- and is known to compile on several compilers across many platforms. To
- implement a new platform or archiver, please read the heavily-commented
- physfs_internal.h and look in the platform/ and archiver/ directories for
- examples.
-
---ryan. (icculus@icculus.org)
-
+++ /dev/null
-
- Copyright (c) 2003 Ryan C. Gordon and others.
-
- This software is provided 'as-is', without any express or implied warranty.
- In no event will the authors be held liable for any damages arising from
- the use of this software.
-
- Permission is granted to anyone to use this software for any purpose,
- including commercial applications, and to alter it and redistribute it
- freely, subject to the following restrictions:
-
- 1. The origin of this software must not be misrepresented; you must not
- claim that you wrote the original software. If you use this software in a
- product, an acknowledgment in the product documentation would be
- appreciated but is not required.
-
- 2. Altered source versions must be plainly marked as such, and must not be
- misrepresented as being the original software.
-
- 3. This notice may not be removed or altered from any source distribution.
-
- Ryan C. Gordon <icculus@icculus.org>
-
-
-(Please note that versions of PhysicsFS prior to 0.1.9 are licensed under
-the GNU Lesser General Public License, which restricts you significantly more.
-For your own safety, please make sure you've got 0.1.9 or later if you plan
-to use physfs in a commercial or closed-source project.)
-
+++ /dev/null
-Stuff that needs to be done and wishlist:
-
-These are in no particular order.
-Some might be dupes, some might be done already.
-
-UNICODE:
-- OS/2: Codepages. No full Unicode in the filesystem, but we can probably make
- a conversion effort.
-
-
-Stuff:
-- Other archivers: perhaps tar(.gz|.bz2), RPM, ARJ, etc. These are less
- important, since streaming archives aren't of much value to games (which
- is why zipfiles are king: random access), but it could have uses for, say,
- an installer/updater.
-- Reduce malloc() pressure all over the place. We fragment memory like mad.
-- profile string list interpolation.
-- We have two different ways to find dir entries in zip.c.
-- Do symlinks in zip archiver work when they point to dirs?
-- Enable more warnings?
-- Use __cdecl in physfs.h?
-- Look for FIXMEs (many marked with "!!!" in comments).
-- Find some way to relax or remove the security model for external tools.
-- OSX shouldn't use ~/.app for userdir.
-- fscanf and fprintf support in extras dir.
-- Why do we call it openArchive and dirClose?
-- Sanity check byte order at runtime.
-- Memory locking?
-- Find a better name than dvoid and fvoid.
-- Can windows.c and pocketpc.c get merged?
-- There's so much cut-and-paste between archivers...can this be reduced?
-- General code audit.
-- Multiple write dirs with mount points?
-- Deprecate PHYSFS_setSaneConfig and move it to extras?
-- Why is physfsrwops.c cut-and-pasted into the ruby bindings?
-- Replace code from SDL...
-- Should file enumeration return an error or set error state?
-- Need "getmountpoint" command in test_physfs.c ...
-- Look for calloc() calls that aren't going through the allocation hooks.
-- Write up a simple HOWTO on embedding physicsfs in another project.
-- Archivers need abstracted i/o to read from memory or files (archives in archives?)
-- Probably other stuff. Requests and recommendations are welcome.
-
-// end of TODO.txt ...
-
+++ /dev/null
-/*
- * Standard directory I/O support routines for PhysicsFS.
- *
- * Please see the file LICENSE.txt in the source's root directory.
- *
- * This file written by Ryan C. Gordon.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include "physfs.h"
-
-#define __PHYSICSFS_INTERNAL__
-#include "physfs_internal.h"
-
-static PHYSFS_sint64 DIR_read(fvoid *opaque, void *buffer,
- PHYSFS_uint32 objSize, PHYSFS_uint32 objCount)
-{
- PHYSFS_sint64 retval;
- retval = __PHYSFS_platformRead(opaque, buffer, objSize, objCount);
- return(retval);
-} /* DIR_read */
-
-
-static PHYSFS_sint64 DIR_write(fvoid *opaque, const void *buffer,
- PHYSFS_uint32 objSize, PHYSFS_uint32 objCount)
-{
- PHYSFS_sint64 retval;
- retval = __PHYSFS_platformWrite(opaque, buffer, objSize, objCount);
- return(retval);
-} /* DIR_write */
-
-
-static int DIR_eof(fvoid *opaque)
-{
- return(__PHYSFS_platformEOF(opaque));
-} /* DIR_eof */
-
-
-static PHYSFS_sint64 DIR_tell(fvoid *opaque)
-{
- return(__PHYSFS_platformTell(opaque));
-} /* DIR_tell */
-
-
-static int DIR_seek(fvoid *opaque, PHYSFS_uint64 offset)
-{
- return(__PHYSFS_platformSeek(opaque, offset));
-} /* DIR_seek */
-
-
-static PHYSFS_sint64 DIR_fileLength(fvoid *opaque)
-{
- return(__PHYSFS_platformFileLength(opaque));
-} /* DIR_fileLength */
-
-
-static int DIR_fileClose(fvoid *opaque)
-{
- /*
- * we manually flush the buffer, since that's the place a close will
- * most likely fail, but that will leave the file handle in an undefined
- * state if it fails. Flush failures we can recover from.
- */
- BAIL_IF_MACRO(!__PHYSFS_platformFlush(opaque), NULL, 0);
- BAIL_IF_MACRO(!__PHYSFS_platformClose(opaque), NULL, 0);
- return(1);
-} /* DIR_fileClose */
-
-
-static int DIR_isArchive(const char *filename, int forWriting)
-{
- /* directories ARE archives in this driver... */
- return(__PHYSFS_platformIsDirectory(filename));
-} /* DIR_isArchive */
-
-
-static void *DIR_openArchive(const char *name, int forWriting)
-{
- const char *dirsep = PHYSFS_getDirSeparator();
- char *retval = NULL;
- size_t namelen = strlen(name);
- size_t seplen = strlen(dirsep);
-
- /* !!! FIXME: when is this not called right before openArchive? */
- BAIL_IF_MACRO(!DIR_isArchive(name, forWriting),
- ERR_UNSUPPORTED_ARCHIVE, 0);
-
- retval = allocator.Malloc(namelen + seplen + 1);
- BAIL_IF_MACRO(retval == NULL, ERR_OUT_OF_MEMORY, NULL);
-
- /* make sure there's a dir separator at the end of the string */
- strcpy(retval, name);
- if (strcmp((name + namelen) - seplen, dirsep) != 0)
- strcat(retval, dirsep);
-
- return(retval);
-} /* DIR_openArchive */
-
-
-static void DIR_enumerateFiles(dvoid *opaque, const char *dname,
- int omitSymLinks, PHYSFS_EnumFilesCallback cb,
- const char *origdir, void *callbackdata)
-{
- char *d = __PHYSFS_platformCvtToDependent((char *)opaque, dname, NULL);
- if (d != NULL)
- {
- __PHYSFS_platformEnumerateFiles(d, omitSymLinks, cb,
- origdir, callbackdata);
- allocator.Free(d);
- } /* if */
-} /* DIR_enumerateFiles */
-
-
-static int DIR_exists(dvoid *opaque, const char *name)
-{
- char *f = __PHYSFS_platformCvtToDependent((char *) opaque, name, NULL);
- int retval;
-
- BAIL_IF_MACRO(f == NULL, NULL, 0);
- retval = __PHYSFS_platformExists(f);
- allocator.Free(f);
- return(retval);
-} /* DIR_exists */
-
-
-static int DIR_isDirectory(dvoid *opaque, const char *name, int *fileExists)
-{
- char *d = __PHYSFS_platformCvtToDependent((char *) opaque, name, NULL);
- int retval = 0;
-
- BAIL_IF_MACRO(d == NULL, NULL, 0);
- *fileExists = __PHYSFS_platformExists(d);
- if (*fileExists)
- retval = __PHYSFS_platformIsDirectory(d);
- allocator.Free(d);
- return(retval);
-} /* DIR_isDirectory */
-
-
-static int DIR_isSymLink(dvoid *opaque, const char *name, int *fileExists)
-{
- char *f = __PHYSFS_platformCvtToDependent((char *) opaque, name, NULL);
- int retval = 0;
-
- BAIL_IF_MACRO(f == NULL, NULL, 0);
- *fileExists = __PHYSFS_platformExists(f);
- if (*fileExists)
- retval = __PHYSFS_platformIsSymLink(f);
- allocator.Free(f);
- return(retval);
-} /* DIR_isSymLink */
-
-
-static PHYSFS_sint64 DIR_getLastModTime(dvoid *opaque,
- const char *name,
- int *fileExists)
-{
- char *d = __PHYSFS_platformCvtToDependent((char *) opaque, name, NULL);
- PHYSFS_sint64 retval = -1;
-
- BAIL_IF_MACRO(d == NULL, NULL, 0);
- *fileExists = __PHYSFS_platformExists(d);
- if (*fileExists)
- retval = __PHYSFS_platformGetLastModTime(d);
- allocator.Free(d);
- return(retval);
-} /* DIR_getLastModTime */
-
-
-static fvoid *doOpen(dvoid *opaque, const char *name,
- void *(*openFunc)(const char *filename),
- int *fileExists)
-{
- char *f = __PHYSFS_platformCvtToDependent((char *) opaque, name, NULL);
- void *rc = NULL;
-
- BAIL_IF_MACRO(f == NULL, NULL, NULL);
-
- if (fileExists != NULL)
- {
- *fileExists = __PHYSFS_platformExists(f);
- if (!(*fileExists))
- {
- allocator.Free(f);
- return(NULL);
- } /* if */
- } /* if */
-
- rc = openFunc(f);
- allocator.Free(f);
-
- return((fvoid *) rc);
-} /* doOpen */
-
-
-static fvoid *DIR_openRead(dvoid *opaque, const char *fnm, int *exist)
-{
- return(doOpen(opaque, fnm, __PHYSFS_platformOpenRead, exist));
-} /* DIR_openRead */
-
-
-static fvoid *DIR_openWrite(dvoid *opaque, const char *filename)
-{
- return(doOpen(opaque, filename, __PHYSFS_platformOpenWrite, NULL));
-} /* DIR_openWrite */
-
-
-static fvoid *DIR_openAppend(dvoid *opaque, const char *filename)
-{
- return(doOpen(opaque, filename, __PHYSFS_platformOpenAppend, NULL));
-} /* DIR_openAppend */
-
-
-static int DIR_remove(dvoid *opaque, const char *name)
-{
- char *f = __PHYSFS_platformCvtToDependent((char *) opaque, name, NULL);
- int retval;
-
- BAIL_IF_MACRO(f == NULL, NULL, 0);
- retval = __PHYSFS_platformDelete(f);
- allocator.Free(f);
- return(retval);
-} /* DIR_remove */
-
-
-static int DIR_mkdir(dvoid *opaque, const char *name)
-{
- char *f = __PHYSFS_platformCvtToDependent((char *) opaque, name, NULL);
- int retval;
-
- BAIL_IF_MACRO(f == NULL, NULL, 0);
- retval = __PHYSFS_platformMkDir(f);
- allocator.Free(f);
- return(retval);
-} /* DIR_mkdir */
-
-
-static void DIR_dirClose(dvoid *opaque)
-{
- allocator.Free(opaque);
-} /* DIR_dirClose */
-
-
-
-const PHYSFS_ArchiveInfo __PHYSFS_ArchiveInfo_DIR =
-{
- "",
- DIR_ARCHIVE_DESCRIPTION,
- "Ryan C. Gordon <icculus@icculus.org>",
- "http://icculus.org/physfs/",
-};
-
-
-
-const PHYSFS_Archiver __PHYSFS_Archiver_DIR =
-{
- &__PHYSFS_ArchiveInfo_DIR,
- DIR_isArchive, /* isArchive() method */
- DIR_openArchive, /* openArchive() method */
- DIR_enumerateFiles, /* enumerateFiles() method */
- DIR_exists, /* exists() method */
- DIR_isDirectory, /* isDirectory() method */
- DIR_isSymLink, /* isSymLink() method */
- DIR_getLastModTime, /* getLastModTime() method */
- DIR_openRead, /* openRead() method */
- DIR_openWrite, /* openWrite() method */
- DIR_openAppend, /* openAppend() method */
- DIR_remove, /* remove() method */
- DIR_mkdir, /* mkdir() method */
- DIR_dirClose, /* dirClose() method */
- DIR_read, /* read() method */
- DIR_write, /* write() method */
- DIR_eof, /* eof() method */
- DIR_tell, /* tell() method */
- DIR_seek, /* seek() method */
- DIR_fileLength, /* fileLength() method */
- DIR_fileClose /* fileClose() method */
-};
-
-/* end of dir.c ... */
-
+++ /dev/null
-/*
- * GRP support routines for PhysicsFS.
- *
- * This driver handles BUILD engine archives ("groupfiles"). This format
- * (but not this driver) was put together by Ken Silverman.
- *
- * The format is simple enough. In Ken's words:
- *
- * What's the .GRP file format?
- *
- * The ".grp" file format is just a collection of a lot of files stored
- * into 1 big one. I tried to make the format as simple as possible: The
- * first 12 bytes contains my name, "KenSilverman". The next 4 bytes is
- * the number of files that were compacted into the group file. Then for
- * each file, there is a 16 byte structure, where the first 12 bytes are
- * the filename, and the last 4 bytes are the file's size. The rest of
- * the group file is just the raw data packed one after the other in the
- * same order as the list of files.
- *
- * (That info is from http://www.advsys.net/ken/build.htm ...)
- *
- * Please see the file LICENSE.txt in the source's root directory.
- *
- * This file written by Ryan C. Gordon.
- */
-
-#if (defined PHYSFS_SUPPORTS_GRP)
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include "physfs.h"
-
-#define __PHYSICSFS_INTERNAL__
-#include "physfs_internal.h"
-
-typedef struct
-{
- char name[13];
- PHYSFS_uint32 startPos;
- PHYSFS_uint32 size;
-} GRPentry;
-
-typedef struct
-{
- char *filename;
- PHYSFS_sint64 last_mod_time;
- PHYSFS_uint32 entryCount;
- GRPentry *entries;
-} GRPinfo;
-
-typedef struct
-{
- void *handle;
- GRPentry *entry;
- PHYSFS_uint32 curPos;
-} GRPfileinfo;
-
-
-static void GRP_dirClose(dvoid *opaque)
-{
- GRPinfo *info = ((GRPinfo *) opaque);
- allocator.Free(info->filename);
- allocator.Free(info->entries);
- allocator.Free(info);
-} /* GRP_dirClose */
-
-
-static PHYSFS_sint64 GRP_read(fvoid *opaque, void *buffer,
- PHYSFS_uint32 objSize, PHYSFS_uint32 objCount)
-{
- GRPfileinfo *finfo = (GRPfileinfo *) opaque;
- GRPentry *entry = finfo->entry;
- PHYSFS_uint32 bytesLeft = entry->size - finfo->curPos;
- PHYSFS_uint32 objsLeft = (bytesLeft / objSize);
- PHYSFS_sint64 rc;
-
- if (objsLeft < objCount)
- objCount = objsLeft;
-
- rc = __PHYSFS_platformRead(finfo->handle, buffer, objSize, objCount);
- if (rc > 0)
- finfo->curPos += (PHYSFS_uint32) (rc * objSize);
-
- return(rc);
-} /* GRP_read */
-
-
-static PHYSFS_sint64 GRP_write(fvoid *opaque, const void *buffer,
- PHYSFS_uint32 objSize, PHYSFS_uint32 objCount)
-{
- BAIL_MACRO(ERR_NOT_SUPPORTED, -1);
-} /* GRP_write */
-
-
-static int GRP_eof(fvoid *opaque)
-{
- GRPfileinfo *finfo = (GRPfileinfo *) opaque;
- GRPentry *entry = finfo->entry;
- return(finfo->curPos >= entry->size);
-} /* GRP_eof */
-
-
-static PHYSFS_sint64 GRP_tell(fvoid *opaque)
-{
- return(((GRPfileinfo *) opaque)->curPos);
-} /* GRP_tell */
-
-
-static int GRP_seek(fvoid *opaque, PHYSFS_uint64 offset)
-{
- GRPfileinfo *finfo = (GRPfileinfo *) opaque;
- GRPentry *entry = finfo->entry;
- int rc;
-
- BAIL_IF_MACRO(offset < 0, ERR_INVALID_ARGUMENT, 0);
- BAIL_IF_MACRO(offset >= entry->size, ERR_PAST_EOF, 0);
- rc = __PHYSFS_platformSeek(finfo->handle, entry->startPos + offset);
- if (rc)
- finfo->curPos = (PHYSFS_uint32) offset;
-
- return(rc);
-} /* GRP_seek */
-
-
-static PHYSFS_sint64 GRP_fileLength(fvoid *opaque)
-{
- GRPfileinfo *finfo = (GRPfileinfo *) opaque;
- return((PHYSFS_sint64) finfo->entry->size);
-} /* GRP_fileLength */
-
-
-static int GRP_fileClose(fvoid *opaque)
-{
- GRPfileinfo *finfo = (GRPfileinfo *) opaque;
- BAIL_IF_MACRO(!__PHYSFS_platformClose(finfo->handle), NULL, 0);
- allocator.Free(finfo);
- return(1);
-} /* GRP_fileClose */
-
-
-static int grp_open(const char *filename, int forWriting,
- void **fh, PHYSFS_uint32 *count)
-{
- PHYSFS_uint8 buf[12];
-
- *fh = NULL;
- BAIL_IF_MACRO(forWriting, ERR_ARC_IS_READ_ONLY, 0);
-
- *fh = __PHYSFS_platformOpenRead(filename);
- BAIL_IF_MACRO(*fh == NULL, NULL, 0);
-
- if (__PHYSFS_platformRead(*fh, buf, 12, 1) != 1)
- goto openGrp_failed;
-
- if (memcmp(buf, "KenSilverman", 12) != 0)
- {
- __PHYSFS_setError(ERR_UNSUPPORTED_ARCHIVE);
- goto openGrp_failed;
- } /* if */
-
- if (__PHYSFS_platformRead(*fh, count, sizeof (PHYSFS_uint32), 1) != 1)
- goto openGrp_failed;
-
- *count = PHYSFS_swapULE32(*count);
-
- return(1);
-
-openGrp_failed:
- if (*fh != NULL)
- __PHYSFS_platformClose(*fh);
-
- *count = -1;
- *fh = NULL;
- return(0);
-} /* grp_open */
-
-
-static int GRP_isArchive(const char *filename, int forWriting)
-{
- void *fh;
- PHYSFS_uint32 fileCount;
- int retval = grp_open(filename, forWriting, &fh, &fileCount);
-
- if (fh != NULL)
- __PHYSFS_platformClose(fh);
-
- return(retval);
-} /* GRP_isArchive */
-
-
-static int grp_entry_cmp(void *_a, PHYSFS_uint32 one, PHYSFS_uint32 two)
-{
- GRPentry *a = (GRPentry *) _a;
- return(strcmp(a[one].name, a[two].name));
-} /* grp_entry_cmp */
-
-
-static void grp_entry_swap(void *_a, PHYSFS_uint32 one, PHYSFS_uint32 two)
-{
- GRPentry tmp;
- GRPentry *first = &(((GRPentry *) _a)[one]);
- GRPentry *second = &(((GRPentry *) _a)[two]);
- memcpy(&tmp, first, sizeof (GRPentry));
- memcpy(first, second, sizeof (GRPentry));
- memcpy(second, &tmp, sizeof (GRPentry));
-} /* grp_entry_swap */
-
-
-static int grp_load_entries(const char *name, int forWriting, GRPinfo *info)
-{
- void *fh = NULL;
- PHYSFS_uint32 fileCount;
- PHYSFS_uint32 location = 16; /* sizeof sig. */
- GRPentry *entry;
- char *ptr;
-
- BAIL_IF_MACRO(!grp_open(name, forWriting, &fh, &fileCount), NULL, 0);
- info->entryCount = fileCount;
- info->entries = (GRPentry *) allocator.Malloc(sizeof(GRPentry)*fileCount);
- if (info->entries == NULL)
- {
- __PHYSFS_platformClose(fh);
- BAIL_MACRO(ERR_OUT_OF_MEMORY, 0);
- } /* if */
-
- location += (16 * fileCount);
-
- for (entry = info->entries; fileCount > 0; fileCount--, entry++)
- {
- if (__PHYSFS_platformRead(fh, &entry->name, 12, 1) != 1)
- {
- __PHYSFS_platformClose(fh);
- return(0);
- } /* if */
-
- entry->name[12] = '\0'; /* name isn't null-terminated in file. */
- if ((ptr = strchr(entry->name, ' ')) != NULL)
- *ptr = '\0'; /* trim extra spaces. */
-
- if (__PHYSFS_platformRead(fh, &entry->size, 4, 1) != 1)
- {
- __PHYSFS_platformClose(fh);
- return(0);
- } /* if */
-
- entry->size = PHYSFS_swapULE32(entry->size);
- entry->startPos = location;
- location += entry->size;
- } /* for */
-
- __PHYSFS_platformClose(fh);
-
- __PHYSFS_sort(info->entries, info->entryCount,
- grp_entry_cmp, grp_entry_swap);
- return(1);
-} /* grp_load_entries */
-
-
-static void *GRP_openArchive(const char *name, int forWriting)
-{
- PHYSFS_sint64 modtime = __PHYSFS_platformGetLastModTime(name);
- GRPinfo *info = (GRPinfo *) allocator.Malloc(sizeof (GRPinfo));
-
- BAIL_IF_MACRO(info == NULL, ERR_OUT_OF_MEMORY, 0);
-
- memset(info, '\0', sizeof (GRPinfo));
- info->filename = (char *) allocator.Malloc(strlen(name) + 1);
- GOTO_IF_MACRO(!info->filename, ERR_OUT_OF_MEMORY, GRP_openArchive_failed);
-
- if (!grp_load_entries(name, forWriting, info))
- goto GRP_openArchive_failed;
-
- strcpy(info->filename, name);
- info->last_mod_time = modtime;
-
- return(info);
-
-GRP_openArchive_failed:
- if (info != NULL)
- {
- if (info->filename != NULL)
- allocator.Free(info->filename);
- if (info->entries != NULL)
- allocator.Free(info->entries);
- allocator.Free(info);
- } /* if */
-
- return(NULL);
-} /* GRP_openArchive */
-
-
-static void GRP_enumerateFiles(dvoid *opaque, const char *dname,
- int omitSymLinks, PHYSFS_EnumFilesCallback cb,
- const char *origdir, void *callbackdata)
-{
- /* no directories in GRP files. */
- if (*dname == '\0')
- {
- GRPinfo *info = (GRPinfo *) opaque;
- GRPentry *entry = info->entries;
- PHYSFS_uint32 max = info->entryCount;
- PHYSFS_uint32 i;
-
- for (i = 0; i < max; i++, entry++)
- cb(callbackdata, origdir, entry->name);
- } /* if */
-} /* GRP_enumerateFiles */
-
-
-static GRPentry *grp_find_entry(GRPinfo *info, const char *name)
-{
- char *ptr = strchr(name, '.');
- GRPentry *a = info->entries;
- PHYSFS_sint32 lo = 0;
- PHYSFS_sint32 hi = (PHYSFS_sint32) (info->entryCount - 1);
- PHYSFS_sint32 middle;
- int rc;
-
- /*
- * Rule out filenames to avoid unneeded processing...no dirs,
- * big filenames, or extensions > 3 chars.
- */
- BAIL_IF_MACRO((ptr) && (strlen(ptr) > 4), ERR_NO_SUCH_FILE, NULL);
- BAIL_IF_MACRO(strlen(name) > 12, ERR_NO_SUCH_FILE, NULL);
- BAIL_IF_MACRO(strchr(name, '/') != NULL, ERR_NO_SUCH_FILE, NULL);
-
- while (lo <= hi)
- {
- middle = lo + ((hi - lo) / 2);
- rc = strcmp(name, a[middle].name);
- if (rc == 0) /* found it! */
- return(&a[middle]);
- else if (rc > 0)
- lo = middle + 1;
- else
- hi = middle - 1;
- } /* while */
-
- BAIL_MACRO(ERR_NO_SUCH_FILE, NULL);
-} /* grp_find_entry */
-
-
-static int GRP_exists(dvoid *opaque, const char *name)
-{
- return(grp_find_entry((GRPinfo *) opaque, name) != NULL);
-} /* GRP_exists */
-
-
-static int GRP_isDirectory(dvoid *opaque, const char *name, int *fileExists)
-{
- *fileExists = GRP_exists(opaque, name);
- return(0); /* never directories in a groupfile. */
-} /* GRP_isDirectory */
-
-
-static int GRP_isSymLink(dvoid *opaque, const char *name, int *fileExists)
-{
- *fileExists = GRP_exists(opaque, name);
- return(0); /* never symlinks in a groupfile. */
-} /* GRP_isSymLink */
-
-
-static PHYSFS_sint64 GRP_getLastModTime(dvoid *opaque,
- const char *name,
- int *fileExists)
-{
- GRPinfo *info = (GRPinfo *) opaque;
- PHYSFS_sint64 retval = -1;
-
- *fileExists = (grp_find_entry(info, name) != NULL);
- if (*fileExists) /* use time of GRP itself in the physical filesystem. */
- retval = info->last_mod_time;
-
- return(retval);
-} /* GRP_getLastModTime */
-
-
-static fvoid *GRP_openRead(dvoid *opaque, const char *fnm, int *fileExists)
-{
- GRPinfo *info = (GRPinfo *) opaque;
- GRPfileinfo *finfo;
- GRPentry *entry;
-
- entry = grp_find_entry(info, fnm);
- *fileExists = (entry != NULL);
- BAIL_IF_MACRO(entry == NULL, NULL, NULL);
-
- finfo = (GRPfileinfo *) allocator.Malloc(sizeof (GRPfileinfo));
- BAIL_IF_MACRO(finfo == NULL, ERR_OUT_OF_MEMORY, NULL);
-
- finfo->handle = __PHYSFS_platformOpenRead(info->filename);
- if ( (finfo->handle == NULL) ||
- (!__PHYSFS_platformSeek(finfo->handle, entry->startPos)) )
- {
- allocator.Free(finfo);
- return(NULL);
- } /* if */
-
- finfo->curPos = 0;
- finfo->entry = entry;
- return(finfo);
-} /* GRP_openRead */
-
-
-static fvoid *GRP_openWrite(dvoid *opaque, const char *name)
-{
- BAIL_MACRO(ERR_NOT_SUPPORTED, NULL);
-} /* GRP_openWrite */
-
-
-static fvoid *GRP_openAppend(dvoid *opaque, const char *name)
-{
- BAIL_MACRO(ERR_NOT_SUPPORTED, NULL);
-} /* GRP_openAppend */
-
-
-static int GRP_remove(dvoid *opaque, const char *name)
-{
- BAIL_MACRO(ERR_NOT_SUPPORTED, 0);
-} /* GRP_remove */
-
-
-static int GRP_mkdir(dvoid *opaque, const char *name)
-{
- BAIL_MACRO(ERR_NOT_SUPPORTED, 0);
-} /* GRP_mkdir */
-
-
-const PHYSFS_ArchiveInfo __PHYSFS_ArchiveInfo_GRP =
-{
- "GRP",
- GRP_ARCHIVE_DESCRIPTION,
- "Ryan C. Gordon <icculus@icculus.org>",
- "http://icculus.org/physfs/",
-};
-
-
-const PHYSFS_Archiver __PHYSFS_Archiver_GRP =
-{
- &__PHYSFS_ArchiveInfo_GRP,
- GRP_isArchive, /* isArchive() method */
- GRP_openArchive, /* openArchive() method */
- GRP_enumerateFiles, /* enumerateFiles() method */
- GRP_exists, /* exists() method */
- GRP_isDirectory, /* isDirectory() method */
- GRP_isSymLink, /* isSymLink() method */
- GRP_getLastModTime, /* getLastModTime() method */
- GRP_openRead, /* openRead() method */
- GRP_openWrite, /* openWrite() method */
- GRP_openAppend, /* openAppend() method */
- GRP_remove, /* remove() method */
- GRP_mkdir, /* mkdir() method */
- GRP_dirClose, /* dirClose() method */
- GRP_read, /* read() method */
- GRP_write, /* write() method */
- GRP_eof, /* eof() method */
- GRP_tell, /* tell() method */
- GRP_seek, /* seek() method */
- GRP_fileLength, /* fileLength() method */
- GRP_fileClose /* fileClose() method */
-};
-
-#endif /* defined PHYSFS_SUPPORTS_GRP */
-
-/* end of grp.c ... */
-
+++ /dev/null
-/*
- * HOG support routines for PhysicsFS.
- *
- * This driver handles Descent I/II HOG archives.
- *
- * The format is very simple:
- *
- * The file always starts with the 3-byte signature "DHF" (Descent
- * HOG file). After that the files of a HOG are just attached after
- * another, divided by a 17 bytes header, which specifies the name
- * and length (in bytes) of the forthcoming file! So you just read
- * the header with its information of how big the following file is,
- * and then skip exact that number of bytes to get to the next file
- * in that HOG.
- *
- * char sig[3] = {'D', 'H', 'F'}; // "DHF"=Descent HOG File
- *
- * struct {
- * char file_name[13]; // Filename, padded to 13 bytes with 0s
- * int file_size; // filesize in bytes
- * char data[file_size]; // The file data
- * } FILE_STRUCT; // Repeated until the end of the file.
- *
- * (That info is from http://www.descent2.com/ddn/specs/hog/)
- *
- * Please see the file LICENSE.txt in the source's root directory.
- *
- * This file written by Bradley Bell.
- * Based on grp.c by Ryan C. Gordon.
- */
-
-#if (defined PHYSFS_SUPPORTS_HOG)
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include "physfs.h"
-
-#define __PHYSICSFS_INTERNAL__
-#include "physfs_internal.h"
-
-/*
- * One HOGentry is kept for each file in an open HOG archive.
- */
-typedef struct
-{
- char name[13];
- PHYSFS_uint32 startPos;
- PHYSFS_uint32 size;
-} HOGentry;
-
-/*
- * One HOGinfo is kept for each open HOG archive.
- */
-typedef struct
-{
- char *filename;
- PHYSFS_sint64 last_mod_time;
- PHYSFS_uint32 entryCount;
- HOGentry *entries;
-} HOGinfo;
-
-/*
- * One HOGfileinfo is kept for each open file in a HOG archive.
- */
-typedef struct
-{
- void *handle;
- HOGentry *entry;
- PHYSFS_uint32 curPos;
-} HOGfileinfo;
-
-
-static void HOG_dirClose(dvoid *opaque)
-{
- HOGinfo *info = ((HOGinfo *) opaque);
- allocator.Free(info->filename);
- allocator.Free(info->entries);
- allocator.Free(info);
-} /* HOG_dirClose */
-
-
-static PHYSFS_sint64 HOG_read(fvoid *opaque, void *buffer,
- PHYSFS_uint32 objSize, PHYSFS_uint32 objCount)
-{
- HOGfileinfo *finfo = (HOGfileinfo *) opaque;
- HOGentry *entry = finfo->entry;
- PHYSFS_uint32 bytesLeft = entry->size - finfo->curPos;
- PHYSFS_uint32 objsLeft = (bytesLeft / objSize);
- PHYSFS_sint64 rc;
-
- if (objsLeft < objCount)
- objCount = objsLeft;
-
- rc = __PHYSFS_platformRead(finfo->handle, buffer, objSize, objCount);
- if (rc > 0)
- finfo->curPos += (PHYSFS_uint32) (rc * objSize);
-
- return(rc);
-} /* HOG_read */
-
-
-static PHYSFS_sint64 HOG_write(fvoid *opaque, const void *buffer,
- PHYSFS_uint32 objSize, PHYSFS_uint32 objCount)
-{
- BAIL_MACRO(ERR_NOT_SUPPORTED, -1);
-} /* HOG_write */
-
-
-static int HOG_eof(fvoid *opaque)
-{
- HOGfileinfo *finfo = (HOGfileinfo *) opaque;
- HOGentry *entry = finfo->entry;
- return(finfo->curPos >= entry->size);
-} /* HOG_eof */
-
-
-static PHYSFS_sint64 HOG_tell(fvoid *opaque)
-{
- return(((HOGfileinfo *) opaque)->curPos);
-} /* HOG_tell */
-
-
-static int HOG_seek(fvoid *opaque, PHYSFS_uint64 offset)
-{
- HOGfileinfo *finfo = (HOGfileinfo *) opaque;
- HOGentry *entry = finfo->entry;
- int rc;
-
- BAIL_IF_MACRO(offset < 0, ERR_INVALID_ARGUMENT, 0);
- BAIL_IF_MACRO(offset >= entry->size, ERR_PAST_EOF, 0);
- rc = __PHYSFS_platformSeek(finfo->handle, entry->startPos + offset);
- if (rc)
- finfo->curPos = (PHYSFS_uint32) offset;
-
- return(rc);
-} /* HOG_seek */
-
-
-static PHYSFS_sint64 HOG_fileLength(fvoid *opaque)
-{
- HOGfileinfo *finfo = (HOGfileinfo *) opaque;
- return((PHYSFS_sint64) finfo->entry->size);
-} /* HOG_fileLength */
-
-
-static int HOG_fileClose(fvoid *opaque)
-{
- HOGfileinfo *finfo = (HOGfileinfo *) opaque;
- BAIL_IF_MACRO(!__PHYSFS_platformClose(finfo->handle), NULL, 0);
- allocator.Free(finfo);
- return(1);
-} /* HOG_fileClose */
-
-
-static int hog_open(const char *filename, int forWriting,
- void **fh, PHYSFS_uint32 *count)
-{
- PHYSFS_uint8 buf[13];
- PHYSFS_uint32 size;
- PHYSFS_sint64 pos;
-
- *count = 0;
-
- *fh = NULL;
- BAIL_IF_MACRO(forWriting, ERR_ARC_IS_READ_ONLY, 0);
-
- *fh = __PHYSFS_platformOpenRead(filename);
- BAIL_IF_MACRO(*fh == NULL, NULL, 0);
-
- if (__PHYSFS_platformRead(*fh, buf, 3, 1) != 1)
- goto openHog_failed;
-
- if (memcmp(buf, "DHF", 3) != 0)
- {
- __PHYSFS_setError(ERR_UNSUPPORTED_ARCHIVE);
- goto openHog_failed;
- } /* if */
-
- while (1)
- {
- if (__PHYSFS_platformRead(*fh, buf, 13, 1) != 1)
- break; /* eof here is ok */
-
- if (__PHYSFS_platformRead(*fh, &size, 4, 1) != 1)
- goto openHog_failed;
-
- size = PHYSFS_swapULE32(size);
-
- (*count)++;
-
- /* Skip over entry... */
- pos = __PHYSFS_platformTell(*fh);
- if (pos == -1)
- goto openHog_failed;
- if (!__PHYSFS_platformSeek(*fh, pos + size))
- goto openHog_failed;
- } /* while */
-
- /* Rewind to start of entries... */
- if (!__PHYSFS_platformSeek(*fh, 3))
- goto openHog_failed;
-
- return(1);
-
-openHog_failed:
- if (*fh != NULL)
- __PHYSFS_platformClose(*fh);
-
- *count = -1;
- *fh = NULL;
- return(0);
-} /* hog_open */
-
-
-static int HOG_isArchive(const char *filename, int forWriting)
-{
- void *fh;
- PHYSFS_uint32 fileCount;
- int retval = hog_open(filename, forWriting, &fh, &fileCount);
-
- if (fh != NULL)
- __PHYSFS_platformClose(fh);
-
- return(retval);
-} /* HOG_isArchive */
-
-
-static int hog_entry_cmp(void *_a, PHYSFS_uint32 one, PHYSFS_uint32 two)
-{
- HOGentry *a = (HOGentry *) _a;
- return(__PHYSFS_stricmpASCII(a[one].name, a[two].name));
-} /* hog_entry_cmp */
-
-
-static void hog_entry_swap(void *_a, PHYSFS_uint32 one, PHYSFS_uint32 two)
-{
- HOGentry tmp;
- HOGentry *first = &(((HOGentry *) _a)[one]);
- HOGentry *second = &(((HOGentry *) _a)[two]);
- memcpy(&tmp, first, sizeof (HOGentry));
- memcpy(first, second, sizeof (HOGentry));
- memcpy(second, &tmp, sizeof (HOGentry));
-} /* hog_entry_swap */
-
-
-static int hog_load_entries(const char *name, int forWriting, HOGinfo *info)
-{
- void *fh = NULL;
- PHYSFS_uint32 fileCount;
- HOGentry *entry;
-
- BAIL_IF_MACRO(!hog_open(name, forWriting, &fh, &fileCount), NULL, 0);
- info->entryCount = fileCount;
- info->entries = (HOGentry *) allocator.Malloc(sizeof(HOGentry)*fileCount);
- if (info->entries == NULL)
- {
- __PHYSFS_platformClose(fh);
- BAIL_MACRO(ERR_OUT_OF_MEMORY, 0);
- } /* if */
-
- for (entry = info->entries; fileCount > 0; fileCount--, entry++)
- {
- if (__PHYSFS_platformRead(fh, &entry->name, 13, 1) != 1)
- {
- __PHYSFS_platformClose(fh);
- return(0);
- } /* if */
-
- if (__PHYSFS_platformRead(fh, &entry->size, 4, 1) != 1)
- {
- __PHYSFS_platformClose(fh);
- return(0);
- } /* if */
-
- entry->size = PHYSFS_swapULE32(entry->size);
- entry->startPos = (unsigned int) __PHYSFS_platformTell(fh);
- if (entry->startPos == -1)
- {
- __PHYSFS_platformClose(fh);
- return(0);
- }
-
- /* Skip over entry */
- if (!__PHYSFS_platformSeek(fh, entry->startPos + entry->size))
- {
- __PHYSFS_platformClose(fh);
- return(0);
- }
- } /* for */
-
- __PHYSFS_platformClose(fh);
-
- __PHYSFS_sort(info->entries, info->entryCount,
- hog_entry_cmp, hog_entry_swap);
- return(1);
-} /* hog_load_entries */
-
-
-static void *HOG_openArchive(const char *name, int forWriting)
-{
- PHYSFS_sint64 modtime = __PHYSFS_platformGetLastModTime(name);
- HOGinfo *info = (HOGinfo *) allocator.Malloc(sizeof (HOGinfo));
-
- BAIL_IF_MACRO(info == NULL, ERR_OUT_OF_MEMORY, 0);
- memset(info, '\0', sizeof (HOGinfo));
- info->filename = (char *) allocator.Malloc(strlen(name) + 1);
- GOTO_IF_MACRO(!info->filename, ERR_OUT_OF_MEMORY, HOG_openArchive_failed);
-
- if (!hog_load_entries(name, forWriting, info))
- goto HOG_openArchive_failed;
-
- strcpy(info->filename, name);
- info->last_mod_time = modtime;
-
- return(info);
-
-HOG_openArchive_failed:
- if (info != NULL)
- {
- if (info->filename != NULL)
- allocator.Free(info->filename);
- if (info->entries != NULL)
- allocator.Free(info->entries);
- allocator.Free(info);
- } /* if */
-
- return(NULL);
-} /* HOG_openArchive */
-
-
-static void HOG_enumerateFiles(dvoid *opaque, const char *dname,
- int omitSymLinks, PHYSFS_EnumFilesCallback cb,
- const char *origdir, void *callbackdata)
-{
- /* no directories in HOG files. */
- if (*dname == '\0')
- {
- HOGinfo *info = (HOGinfo *) opaque;
- HOGentry *entry = info->entries;
- PHYSFS_uint32 max = info->entryCount;
- PHYSFS_uint32 i;
-
- for (i = 0; i < max; i++, entry++)
- cb(callbackdata, origdir, entry->name);
- } /* if */
-} /* HOG_enumerateFiles */
-
-
-static HOGentry *hog_find_entry(HOGinfo *info, const char *name)
-{
- char *ptr = strchr(name, '.');
- HOGentry *a = info->entries;
- PHYSFS_sint32 lo = 0;
- PHYSFS_sint32 hi = (PHYSFS_sint32) (info->entryCount - 1);
- PHYSFS_sint32 middle;
- int rc;
-
- /*
- * Rule out filenames to avoid unneeded processing...no dirs,
- * big filenames, or extensions > 3 chars.
- */
- BAIL_IF_MACRO((ptr) && (strlen(ptr) > 4), ERR_NO_SUCH_FILE, NULL);
- BAIL_IF_MACRO(strlen(name) > 12, ERR_NO_SUCH_FILE, NULL);
- BAIL_IF_MACRO(strchr(name, '/') != NULL, ERR_NO_SUCH_FILE, NULL);
-
- while (lo <= hi)
- {
- middle = lo + ((hi - lo) / 2);
- rc = __PHYSFS_stricmpASCII(name, a[middle].name);
- if (rc == 0) /* found it! */
- return(&a[middle]);
- else if (rc > 0)
- lo = middle + 1;
- else
- hi = middle - 1;
- } /* while */
-
- BAIL_MACRO(ERR_NO_SUCH_FILE, NULL);
-} /* hog_find_entry */
-
-
-static int HOG_exists(dvoid *opaque, const char *name)
-{
- return(hog_find_entry(((HOGinfo *) opaque), name) != NULL);
-} /* HOG_exists */
-
-
-static int HOG_isDirectory(dvoid *opaque, const char *name, int *fileExists)
-{
- *fileExists = HOG_exists(opaque, name);
- return(0); /* never directories in a groupfile. */
-} /* HOG_isDirectory */
-
-
-static int HOG_isSymLink(dvoid *opaque, const char *name, int *fileExists)
-{
- *fileExists = HOG_exists(opaque, name);
- return(0); /* never symlinks in a groupfile. */
-} /* HOG_isSymLink */
-
-
-static PHYSFS_sint64 HOG_getLastModTime(dvoid *opaque,
- const char *name,
- int *fileExists)
-{
- HOGinfo *info = ((HOGinfo *) opaque);
- PHYSFS_sint64 retval = -1;
-
- *fileExists = (hog_find_entry(info, name) != NULL);
- if (*fileExists) /* use time of HOG itself in the physical filesystem. */
- retval = info->last_mod_time;
-
- return(retval);
-} /* HOG_getLastModTime */
-
-
-static fvoid *HOG_openRead(dvoid *opaque, const char *fnm, int *fileExists)
-{
- HOGinfo *info = ((HOGinfo *) opaque);
- HOGfileinfo *finfo;
- HOGentry *entry;
-
- entry = hog_find_entry(info, fnm);
- *fileExists = (entry != NULL);
- BAIL_IF_MACRO(entry == NULL, NULL, NULL);
-
- finfo = (HOGfileinfo *) allocator.Malloc(sizeof (HOGfileinfo));
- BAIL_IF_MACRO(finfo == NULL, ERR_OUT_OF_MEMORY, NULL);
-
- finfo->handle = __PHYSFS_platformOpenRead(info->filename);
- if ( (finfo->handle == NULL) ||
- (!__PHYSFS_platformSeek(finfo->handle, entry->startPos)) )
- {
- allocator.Free(finfo);
- return(NULL);
- } /* if */
-
- finfo->curPos = 0;
- finfo->entry = entry;
- return(finfo);
-} /* HOG_openRead */
-
-
-static fvoid *HOG_openWrite(dvoid *opaque, const char *name)
-{
- BAIL_MACRO(ERR_NOT_SUPPORTED, NULL);
-} /* HOG_openWrite */
-
-
-static fvoid *HOG_openAppend(dvoid *opaque, const char *name)
-{
- BAIL_MACRO(ERR_NOT_SUPPORTED, NULL);
-} /* HOG_openAppend */
-
-
-static int HOG_remove(dvoid *opaque, const char *name)
-{
- BAIL_MACRO(ERR_NOT_SUPPORTED, 0);
-} /* HOG_remove */
-
-
-static int HOG_mkdir(dvoid *opaque, const char *name)
-{
- BAIL_MACRO(ERR_NOT_SUPPORTED, 0);
-} /* HOG_mkdir */
-
-
-const PHYSFS_ArchiveInfo __PHYSFS_ArchiveInfo_HOG =
-{
- "HOG",
- HOG_ARCHIVE_DESCRIPTION,
- "Bradley Bell <btb@icculus.org>",
- "http://icculus.org/physfs/",
-};
-
-
-const PHYSFS_Archiver __PHYSFS_Archiver_HOG =
-{
- &__PHYSFS_ArchiveInfo_HOG,
- HOG_isArchive, /* isArchive() method */
- HOG_openArchive, /* openArchive() method */
- HOG_enumerateFiles, /* enumerateFiles() method */
- HOG_exists, /* exists() method */
- HOG_isDirectory, /* isDirectory() method */
- HOG_isSymLink, /* isSymLink() method */
- HOG_getLastModTime, /* getLastModTime() method */
- HOG_openRead, /* openRead() method */
- HOG_openWrite, /* openWrite() method */
- HOG_openAppend, /* openAppend() method */
- HOG_remove, /* remove() method */
- HOG_mkdir, /* mkdir() method */
- HOG_dirClose, /* dirClose() method */
- HOG_read, /* read() method */
- HOG_write, /* write() method */
- HOG_eof, /* eof() method */
- HOG_tell, /* tell() method */
- HOG_seek, /* seek() method */
- HOG_fileLength, /* fileLength() method */
- HOG_fileClose /* fileClose() method */
-};
-
-#endif /* defined PHYSFS_SUPPORTS_HOG */
-
-/* end of hog.c ... */
-
+++ /dev/null
-/*
- * LZMA support routines for PhysicsFS.
- *
- * Please see the file LICENSE.txt in the source's root directory.
- *
- * This file is written by Dennis Schridde, with some peeking at "7zMain.c"
- * by Igor Pavlov.
- */
-
-#if (defined PHYSFS_SUPPORTS_7Z)
-
-#include <stdlib.h>
-#include <string.h>
-
-#include "physfs.h"
-
-#define __PHYSICSFS_INTERNAL__
-#include "physfs_internal.h"
-
-#ifndef _LZMA_IN_CB
-#define _LZMA_IN_CB
-/* Use callback for input data */
-#endif
-
-/* #define _LZMA_OUT_READ */
-/* Use read function for output data */
-
-#ifndef _LZMA_PROB32
-#define _LZMA_PROB32
-/* It can increase speed on some 32-bit CPUs,
- but memory usage will be doubled in that case */
-#endif
-
-#ifndef _LZMA_SYSTEM_SIZE_T
-#define _LZMA_SYSTEM_SIZE_T
-/* Use system's size_t. You can use it to enable 64-bit sizes supporting */
-#endif
-
-#include "7zIn.h"
-#include "7zCrc.h"
-#include "7zExtract.h"
-
-
-/* 7z internal from 7zIn.c */
-int TestSignatureCandidate(Byte *testBytes);
-
-
-typedef struct _CFileInStream
-{
- ISzInStream InStream;
- void *File;
-} CFileInStream;
-
-/*
- * In LZMA the archive is splited in blocks, those are called folders
- * Set by LZMA_read()
-*/
-typedef struct _LZMAfolder
-{
- PHYSFS_uint8 *cache; /* Cached folder */
- PHYSFS_uint32 size; /* Size of folder */
- PHYSFS_uint32 index; /* Index of folder in archive */
- PHYSFS_uint32 references; /* Number of files using this block */
-} LZMAfolder;
-
-/*
- * Set by LZMA_openArchive(), except folder which gets it's values
- * in LZMA_read()
- */
-typedef struct _LZMAarchive
-{
- struct _LZMAentry *firstEntry; /* Used for cleanup on shutdown */
- struct _LZMAentry *lastEntry;
- LZMAfolder *folder; /* Array of folders */
- CArchiveDatabaseEx db; /* For 7z: Database */
- CFileInStream stream; /* For 7z: Input file incl. read and seek callbacks */
-} LZMAarchive;
-
-/* Set by LZMA_openRead(), except offset which is set by LZMA_read() */
-typedef struct _LZMAentry
-{
- struct _LZMAentry *next; /* Used for cleanup on shutdown */
- struct _LZMAentry *previous;
- LZMAarchive *archive; /* Link to corresponding archive */
- CFileItem *file; /* For 7z: File info, eg. name, size */
- PHYSFS_uint32 fileIndex; /* Index of file in archive */
- PHYSFS_uint32 folderIndex; /* Index of folder in archive */
- size_t offset; /* Offset in folder */
- PHYSFS_uint64 position; /* Current "virtual" position in file */
-} LZMAentry;
-
-
-/* Memory management implementations to be passed to 7z */
-
-static void *SzAllocPhysicsFS(size_t size)
-{
- return ((size == 0) ? NULL : allocator.Malloc(size));
-} /* SzAllocPhysicsFS */
-
-
-static void SzFreePhysicsFS(void *address)
-{
- if (address != NULL)
- allocator.Free(address);
-} /* SzFreePhysicsFS */
-
-
-/* Filesystem implementations to be passed to 7z */
-
-#ifdef _LZMA_IN_CB
-
-#define kBufferSize (1 << 12)
-static Byte g_Buffer[kBufferSize]; /* !!! FIXME: not thread safe! */
-
-SZ_RESULT SzFileReadImp(void *object, void **buffer, size_t maxReqSize,
- size_t *processedSize)
-{
- CFileInStream *s = (CFileInStream *)object;
- PHYSFS_sint64 processedSizeLoc;
- if (maxReqSize > kBufferSize)
- maxReqSize = kBufferSize;
- processedSizeLoc = __PHYSFS_platformRead(s->File, g_Buffer, 1, maxReqSize);
- *buffer = g_Buffer;
- if (processedSize != NULL)
- *processedSize = (size_t) processedSizeLoc;
- return SZ_OK;
-} /* SzFileReadImp */
-
-#else
-
-SZ_RESULT SzFileReadImp(void *object, void *buffer, size_t size,
- size_t *processedSize)
-{
- CFileInStream *s = (CFileInStream *)object;
- size_t processedSizeLoc = __PHYSFS_platformRead(s->File, buffer, 1, size);
- if (processedSize != 0)
- *processedSize = processedSizeLoc;
- return SZ_OK;
-} /* SzFileReadImp */
-
-#endif
-
-SZ_RESULT SzFileSeekImp(void *object, CFileSize pos)
-{
- CFileInStream *s = (CFileInStream *) object;
- if (__PHYSFS_platformSeek(s->File, (PHYSFS_uint64) pos))
- return SZ_OK;
- return SZE_FAIL;
-} /* SzFileSeekImp */
-
-
-/*
- * Find entry 'name' in 'archive' and report the 'index' back
- */
-static int lzma_find_entry(LZMAarchive *archive, const char *name,
- PHYSFS_uint32 *index)
-{
- for (*index = 0; *index < archive->db.Database.NumFiles; (*index)++)
- {
- if (strcmp(archive->db.Database.Files[*index].Name, name) == 0)
- return 1;
- } /* for */
-
- BAIL_MACRO(ERR_NO_SUCH_FILE, 0);
-} /* lzma_find_entry */
-
-
-/*
- * Report the first file index of a directory
- */
-static PHYSFS_sint32 lzma_find_start_of_dir(LZMAarchive *archive,
- const char *path,
- int stop_on_first_find)
-{
- PHYSFS_sint32 lo = 0;
- PHYSFS_sint32 hi = (PHYSFS_sint32) (archive->db.Database.NumFiles - 1);
- PHYSFS_sint32 middle;
- PHYSFS_uint32 dlen = strlen(path);
- PHYSFS_sint32 retval = -1;
- const char *name;
- int rc;
-
- if (*path == '\0') /* root dir? */
- return(0);
-
- if ((dlen > 0) && (path[dlen - 1] == '/')) /* ignore trailing slash. */
- dlen--;
-
- while (lo <= hi)
- {
- middle = lo + ((hi - lo) / 2);
- name = archive->db.Database.Files[middle].Name;
- rc = strncmp(path, name, dlen);
- if (rc == 0)
- {
- char ch = name[dlen];
- if ('/' < ch) /* make sure this isn't just a substr match. */
- rc = -1;
- else if ('/' > ch)
- rc = 1;
- else
- {
- if (stop_on_first_find) /* Just checking dir's existance? */
- return(middle);
-
- if (name[dlen + 1] == '\0') /* Skip initial dir entry. */
- return(middle + 1);
-
- /* there might be more entries earlier in the list. */
- retval = middle;
- hi = middle - 1;
- } /* else */
- } /* if */
-
- if (rc > 0)
- lo = middle + 1;
- else
- hi = middle - 1;
- } /* while */
-
- return(retval);
-} /* lzma_find_start_of_dir */
-
-
-/*
- * Wrap all 7z calls in this, so the physfs error state is set appropriately.
- */
-static int lzma_err(SZ_RESULT rc)
-{
- switch (rc)
- {
- case SZ_OK: /* Same as LZMA_RESULT_OK */
- break;
- case SZE_DATA_ERROR: /* Same as LZMA_RESULT_DATA_ERROR */
- __PHYSFS_setError(ERR_DATA_ERROR);
- break;
- case SZE_OUTOFMEMORY:
- __PHYSFS_setError(ERR_OUT_OF_MEMORY);
- break;
- case SZE_CRC_ERROR:
- __PHYSFS_setError(ERR_CORRUPTED);
- break;
- case SZE_NOTIMPL:
- __PHYSFS_setError(ERR_NOT_IMPLEMENTED);
- break;
- case SZE_FAIL:
- __PHYSFS_setError(ERR_UNKNOWN_ERROR); /* !!! FIXME: right? */
- break;
- case SZE_ARCHIVE_ERROR:
- __PHYSFS_setError(ERR_CORRUPTED); /* !!! FIXME: right? */
- break;
- default:
- __PHYSFS_setError(ERR_UNKNOWN_ERROR);
- } /* switch */
-
- return(rc);
-} /* lzma_err */
-
-
-static PHYSFS_sint64 LZMA_read(fvoid *opaque, void *outBuffer,
- PHYSFS_uint32 objSize, PHYSFS_uint32 objCount)
-{
- LZMAentry *entry = (LZMAentry *) opaque;
-
- PHYSFS_sint64 wantedSize = objSize*objCount;
- PHYSFS_sint64 remainingSize = entry->file->Size - entry->position;
-
- size_t fileSize;
- ISzAlloc allocImp;
- ISzAlloc allocTempImp;
-
- BAIL_IF_MACRO(wantedSize == 0, NULL, 0); /* quick rejection. */
- BAIL_IF_MACRO(remainingSize == 0, ERR_PAST_EOF, 0);
-
- if (remainingSize < wantedSize)
- {
- wantedSize = remainingSize - (remainingSize % objSize);
- objCount = (PHYSFS_uint32) (remainingSize / objSize);
- BAIL_IF_MACRO(objCount == 0, ERR_PAST_EOF, 0); /* quick rejection. */
- __PHYSFS_setError(ERR_PAST_EOF); /* this is always true here. */
- } /* if */
-
- /* Prepare callbacks for 7z */
- allocImp.Alloc = SzAllocPhysicsFS;
- allocImp.Free = SzFreePhysicsFS;
-
- allocTempImp.Alloc = SzAllocPhysicsFS;
- allocTempImp.Free = SzFreePhysicsFS;
-
- /* Only decompress the folder if it is not allready cached */
- if (entry->archive->folder[entry->folderIndex].cache == NULL)
- {
- size_t tmpsize = entry->archive->folder[entry->folderIndex].size;
- int rc = lzma_err(SzExtract(
- &entry->archive->stream.InStream, /* compressed data */
- &entry->archive->db,
- entry->fileIndex,
- /* Index of cached folder, will be changed by SzExtract */
- &entry->archive->folder[entry->folderIndex].index,
- /* Cache for decompressed folder, allocated/freed by SzExtract */
- &entry->archive->folder[entry->folderIndex].cache,
- /* Size of cache, will be changed by SzExtract */
- &tmpsize,
- /* Offset of this file inside the cache, set by SzExtract */
- &entry->offset,
- &fileSize, /* Size of this file */
- &allocImp,
- &allocTempImp));
-
- entry->archive->folder[entry->folderIndex].size = tmpsize;
- if (rc != SZ_OK)
- return -1;
- } /* if */
-
- /* Copy wanted bytes over from cache to outBuffer */
-/* !!! FIXME: strncpy for non-string data? */
- strncpy(outBuffer,
- (void*) (entry->archive->folder[entry->folderIndex].cache +
- entry->offset + entry->position),
- (size_t) wantedSize);
- entry->position += wantedSize;
- return objCount;
-} /* LZMA_read */
-
-
-static PHYSFS_sint64 LZMA_write(fvoid *opaque, const void *buf,
- PHYSFS_uint32 objSize, PHYSFS_uint32 objCount)
-{
- BAIL_MACRO(ERR_NOT_SUPPORTED, -1);
-} /* LZMA_write */
-
-
-static int LZMA_eof(fvoid *opaque)
-{
- LZMAentry *entry = (LZMAentry *) opaque;
- return (entry->position >= entry->file->Size);
-} /* LZMA_eof */
-
-
-static PHYSFS_sint64 LZMA_tell(fvoid *opaque)
-{
- LZMAentry *entry = (LZMAentry *) opaque;
- return (entry->position);
-} /* LZMA_tell */
-
-
-static int LZMA_seek(fvoid *opaque, PHYSFS_uint64 offset)
-{
- LZMAentry *entry = (LZMAentry *) opaque;
-
- BAIL_IF_MACRO(offset < 0, ERR_SEEK_OUT_OF_RANGE, 0);
- BAIL_IF_MACRO(offset > entry->file->Size, ERR_PAST_EOF, 0);
-
- entry->position = offset;
- return 1;
-} /* LZMA_seek */
-
-
-static PHYSFS_sint64 LZMA_fileLength(fvoid *opaque)
-{
- LZMAentry *entry = (LZMAentry *) opaque;
- return (entry->file->Size);
-} /* LZMA_fileLength */
-
-
-static int LZMA_fileClose(fvoid *opaque)
-{
- LZMAentry *entry = (LZMAentry *) opaque;
-
- /* Fix archive */
- if (entry == entry->archive->firstEntry)
- entry->archive->firstEntry = entry->next;
- if (entry == entry->archive->lastEntry)
- entry->archive->lastEntry = entry->previous;
-
- /* Fix neighbours */
- if (entry->previous != NULL)
- entry->previous->next = entry->next;
- if (entry->next != NULL)
- entry->next->previous = entry->previous;
-
- entry->archive->folder[entry->folderIndex].references--;
- if (entry->archive->folder[entry->folderIndex].references == 0)
- {
- allocator.Free(entry->archive->folder[entry->folderIndex].cache);
- entry->archive->folder[entry->folderIndex].cache = NULL;
- }
-
- allocator.Free(entry);
- entry = NULL;
-
- return(1);
-} /* LZMA_fileClose */
-
-
-static int LZMA_isArchive(const char *filename, int forWriting)
-{
- PHYSFS_uint8 sig[k7zSignatureSize];
- PHYSFS_uint8 res;
- void *in;
-
- BAIL_IF_MACRO(forWriting, ERR_ARC_IS_READ_ONLY, 0);
-
- in = __PHYSFS_platformOpenRead(filename);
- BAIL_IF_MACRO(in == NULL, NULL, 0);
-
- if (__PHYSFS_platformRead(in, sig, k7zSignatureSize, 1) != 1)
- BAIL_MACRO(NULL, 0);
-
- /* Test whether sig is the 7z signature */
- res = TestSignatureCandidate(sig);
-
- __PHYSFS_platformClose(in);
-
- return res;
-} /* LZMA_isArchive */
-
-
-static void *LZMA_openArchive(const char *name, int forWriting)
-{
- PHYSFS_uint64 len;
- LZMAarchive *archive = NULL;
- ISzAlloc allocImp;
- ISzAlloc allocTempImp;
-
- BAIL_IF_MACRO(forWriting, ERR_ARC_IS_READ_ONLY, NULL);
- BAIL_IF_MACRO(!LZMA_isArchive(name,forWriting), ERR_UNSUPPORTED_ARCHIVE, 0);
-
- archive = (LZMAarchive *) allocator.Malloc(sizeof (LZMAarchive));
- BAIL_IF_MACRO(archive == NULL, ERR_OUT_OF_MEMORY, NULL);
-
- archive->firstEntry = NULL;
- archive->lastEntry = NULL;
-
- if ((archive->stream.File = __PHYSFS_platformOpenRead(name)) == NULL)
- {
- allocator.Free(archive);
- return NULL;
- } /* if */
-
- /* Prepare structs for 7z */
- archive->stream.InStream.Read = SzFileReadImp;
- archive->stream.InStream.Seek = SzFileSeekImp;
-
- allocImp.Alloc = SzAllocPhysicsFS;
- allocImp.Free = SzFreePhysicsFS;
-
- allocTempImp.Alloc = SzAllocPhysicsFS;
- allocTempImp.Free = SzFreePhysicsFS;
-
- InitCrcTable();
- SzArDbExInit(&archive->db);
- if (lzma_err(SzArchiveOpen(&archive->stream.InStream, &archive->db,
- &allocImp, &allocTempImp)) != SZ_OK)
- {
- __PHYSFS_platformClose(archive->stream.File);
- allocator.Free(archive);
- return NULL;
- } /* if */
-
- len = archive->db.Database.NumFolders * sizeof (LZMAfolder);
- archive->folder = (LZMAfolder *) allocator.Malloc(len);
- BAIL_IF_MACRO(archive->folder == NULL, ERR_OUT_OF_MEMORY, NULL);
-
- /*
- * Init with 0 so we know when a folder is already cached
- * Values will be set by LZMA_read()
- */
- memset(archive->folder, 0, (size_t) len);
-
- return(archive);
-} /* LZMA_openArchive */
-
-
-/*
- * Moved to seperate function so we can use alloca then immediately throw
- * away the allocated stack space...
- */
-static void doEnumCallback(PHYSFS_EnumFilesCallback cb, void *callbackdata,
- const char *odir, const char *str, PHYSFS_sint32 ln)
-{
- char *newstr = __PHYSFS_smallAlloc(ln + 1);
- if (newstr == NULL)
- return;
-
- memcpy(newstr, str, ln);
- newstr[ln] = '\0';
- cb(callbackdata, odir, newstr);
- __PHYSFS_smallFree(newstr);
-} /* doEnumCallback */
-
-
-static void LZMA_enumerateFiles(dvoid *opaque, const char *dname,
- int omitSymLinks, PHYSFS_EnumFilesCallback cb,
- const char *origdir, void *callbackdata)
-{
- LZMAarchive *archive = (LZMAarchive *) opaque;
- PHYSFS_sint32 dlen;
- PHYSFS_sint32 dlen_inc;
- PHYSFS_sint32 max;
- PHYSFS_sint32 i;
-
- i = lzma_find_start_of_dir(archive, dname, 0);
- if (i == -1) /* no such directory. */
- return;
-
- dlen = strlen(dname);
- if ((dlen > 0) && (dname[dlen - 1] == '/')) /* ignore trailing slash. */
- dlen--;
-
- dlen_inc = ((dlen > 0) ? 1 : 0) + dlen;
- max = (PHYSFS_sint32) archive->db.Database.NumFiles;
- while (i < max)
- {
- char *add;
- char *ptr;
- PHYSFS_sint32 ln;
- char *e = archive->db.Database.Files[i].Name;
- if ((dlen) && ((strncmp(e, dname, dlen)) || (e[dlen] != '/')))
- break; /* past end of this dir; we're done. */
-
- add = e + dlen_inc;
- ptr = strchr(add, '/');
- ln = (PHYSFS_sint32) ((ptr) ? ptr-add : strlen(add));
- doEnumCallback(cb, callbackdata, origdir, add, ln);
- ln += dlen_inc; /* point past entry to children... */
-
- /* increment counter and skip children of subdirs... */
- while ((++i < max) && (ptr != NULL))
- {
- char *e_new = archive->db.Database.Files[i].Name;
- if ((strncmp(e, e_new, ln) != 0) || (e_new[ln] != '/'))
- break;
- } /* while */
- } /* while */
-} /* LZMA_enumerateFiles */
-
-
-static int LZMA_exists(dvoid *opaque, const char *name)
-{
- LZMAarchive *archive = (LZMAarchive *) opaque;
- PHYSFS_uint32 index = 0;
- return(lzma_find_entry(archive, name, &index));
-} /* LZMA_exists */
-
-
-static PHYSFS_sint64 LZMA_getLastModTime(dvoid *opaque,
- const char *name,
- int *fileExists)
-{
- /* !!! FIXME: Lacking support in the LZMA C SDK. */
- BAIL_MACRO(ERR_NOT_IMPLEMENTED, -1);
-} /* LZMA_getLastModTime */
-
-
-static int LZMA_isDirectory(dvoid *opaque, const char *name, int *fileExists)
-{
- LZMAarchive *archive = (LZMAarchive *) opaque;
- PHYSFS_uint32 index = 0;
-
- *fileExists = lzma_find_entry(archive, name, &index);
-
- return(archive->db.Database.Files[index].IsDirectory);
-} /* LZMA_isDirectory */
-
-
-static int LZMA_isSymLink(dvoid *opaque, const char *name, int *fileExists)
-{
- BAIL_MACRO(ERR_NOT_SUPPORTED, 0);
-} /* LZMA_isSymLink */
-
-
-static fvoid *LZMA_openRead(dvoid *opaque, const char *name, int *fileExists)
-{
- LZMAarchive *archive = (LZMAarchive *) opaque;
- LZMAentry *entry = NULL;
- PHYSFS_uint32 fileIndex = 0;
- PHYSFS_uint32 folderIndex = 0;
-
- *fileExists = lzma_find_entry(archive, name, &fileIndex);
- BAIL_IF_MACRO(!*fileExists, ERR_NO_SUCH_FILE, NULL);
-
- folderIndex = archive->db.FileIndexToFolderIndexMap[fileIndex];
- BAIL_IF_MACRO(folderIndex == (PHYSFS_uint32)-1, ERR_UNKNOWN_ERROR, NULL);
-
- entry = (LZMAentry *) allocator.Malloc(sizeof (LZMAentry));
- BAIL_IF_MACRO(entry == NULL, ERR_OUT_OF_MEMORY, NULL);
-
- entry->fileIndex = fileIndex;
- entry->folderIndex = folderIndex;
- entry->archive = archive;
- entry->file = archive->db.Database.Files + entry->fileIndex;
- entry->offset = 0; /* Offset will be set by LZMA_read() */
- entry->position = 0;
-
- archive->folder[folderIndex].references++;
-
- entry->next = NULL;
- entry->previous = entry->archive->lastEntry;
- if (entry->previous != NULL)
- entry->previous->next = entry;
- entry->archive->lastEntry = entry;
- if (entry->archive->firstEntry == NULL)
- entry->archive->firstEntry = entry;
-
- return(entry);
-} /* LZMA_openRead */
-
-
-static fvoid *LZMA_openWrite(dvoid *opaque, const char *filename)
-{
- BAIL_MACRO(ERR_NOT_SUPPORTED, NULL);
-} /* LZMA_openWrite */
-
-
-static fvoid *LZMA_openAppend(dvoid *opaque, const char *filename)
-{
- BAIL_MACRO(ERR_NOT_SUPPORTED, NULL);
-} /* LZMA_openAppend */
-
-
-static void LZMA_dirClose(dvoid *opaque)
-{
- LZMAarchive *archive = (LZMAarchive *) opaque;
- LZMAentry *entry = archive->firstEntry;
- LZMAentry *tmpEntry = entry;
-
- while (entry != NULL)
- {
- tmpEntry = entry->next;
- LZMA_fileClose(entry);
- entry = tmpEntry;
- } /* while */
-
- SzArDbExFree(&archive->db, SzFreePhysicsFS);
- __PHYSFS_platformClose(archive->stream.File);
-
- /* Free the cache which might have been allocated by LZMA_read() */
- allocator.Free(archive->folder);
- allocator.Free(archive);
-} /* LZMA_dirClose */
-
-
-static int LZMA_remove(dvoid *opaque, const char *name)
-{
- BAIL_MACRO(ERR_NOT_SUPPORTED, 0);
-} /* LZMA_remove */
-
-
-static int LZMA_mkdir(dvoid *opaque, const char *name)
-{
- BAIL_MACRO(ERR_NOT_SUPPORTED, 0);
-} /* LZMA_mkdir */
-
-
-const PHYSFS_ArchiveInfo __PHYSFS_ArchiveInfo_LZMA =
-{
- "7Z",
- LZMA_ARCHIVE_DESCRIPTION,
- "Dennis Schridde <devurandom@gmx.net>",
- "http://icculus.org/physfs/",
-};
-
-
-const PHYSFS_Archiver __PHYSFS_Archiver_LZMA =
-{
- &__PHYSFS_ArchiveInfo_LZMA,
- LZMA_isArchive, /* isArchive() method */
- LZMA_openArchive, /* openArchive() method */
- LZMA_enumerateFiles, /* enumerateFiles() method */
- LZMA_exists, /* exists() method */
- LZMA_isDirectory, /* isDirectory() method */
- LZMA_isSymLink, /* isSymLink() method */
- LZMA_getLastModTime, /* getLastModTime() method */
- LZMA_openRead, /* openRead() method */
- LZMA_openWrite, /* openWrite() method */
- LZMA_openAppend, /* openAppend() method */
- LZMA_remove, /* remove() method */
- LZMA_mkdir, /* mkdir() method */
- LZMA_dirClose, /* dirClose() method */
- LZMA_read, /* read() method */
- LZMA_write, /* write() method */
- LZMA_eof, /* eof() method */
- LZMA_tell, /* tell() method */
- LZMA_seek, /* seek() method */
- LZMA_fileLength, /* fileLength() method */
- LZMA_fileClose /* fileClose() method */
-};
-
-#endif /* defined PHYSFS_SUPPORTS_7Z */
-
-/* end of lzma.c ... */
-
+++ /dev/null
-/*
- * MVL support routines for PhysicsFS.
- *
- * This driver handles Descent II Movielib archives.
- *
- * The file format of MVL is quite easy...
- *
- * //MVL File format - Written by Heiko Herrmann
- * char sig[4] = {'D','M', 'V', 'L'}; // "DMVL"=Descent MoVie Library
- *
- * int num_files; // the number of files in this MVL
- *
- * struct {
- * char file_name[13]; // Filename, padded to 13 bytes with 0s
- * int file_size; // filesize in bytes
- * }DIR_STRUCT[num_files];
- *
- * struct {
- * char data[file_size]; // The file data
- * }FILE_STRUCT[num_files];
- *
- * (That info is from http://www.descent2.com/ddn/specs/mvl/)
- *
- * Please see the file LICENSE.txt in the source's root directory.
- *
- * This file written by Bradley Bell.
- * Based on grp.c by Ryan C. Gordon.
- */
-
-#if (defined PHYSFS_SUPPORTS_MVL)
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include "physfs.h"
-
-#define __PHYSICSFS_INTERNAL__
-#include "physfs_internal.h"
-
-typedef struct
-{
- char name[13];
- PHYSFS_uint32 startPos;
- PHYSFS_uint32 size;
-} MVLentry;
-
-typedef struct
-{
- char *filename;
- PHYSFS_sint64 last_mod_time;
- PHYSFS_uint32 entryCount;
- MVLentry *entries;
-} MVLinfo;
-
-typedef struct
-{
- void *handle;
- MVLentry *entry;
- PHYSFS_uint32 curPos;
-} MVLfileinfo;
-
-
-static void MVL_dirClose(dvoid *opaque)
-{
- MVLinfo *info = ((MVLinfo *) opaque);
- allocator.Free(info->filename);
- allocator.Free(info->entries);
- allocator.Free(info);
-} /* MVL_dirClose */
-
-
-static PHYSFS_sint64 MVL_read(fvoid *opaque, void *buffer,
- PHYSFS_uint32 objSize, PHYSFS_uint32 objCount)
-{
- MVLfileinfo *finfo = (MVLfileinfo *) opaque;
- MVLentry *entry = finfo->entry;
- PHYSFS_uint32 bytesLeft = entry->size - finfo->curPos;
- PHYSFS_uint32 objsLeft = (bytesLeft / objSize);
- PHYSFS_sint64 rc;
-
- if (objsLeft < objCount)
- objCount = objsLeft;
-
- rc = __PHYSFS_platformRead(finfo->handle, buffer, objSize, objCount);
- if (rc > 0)
- finfo->curPos += (PHYSFS_uint32) (rc * objSize);
-
- return(rc);
-} /* MVL_read */
-
-
-static PHYSFS_sint64 MVL_write(fvoid *opaque, const void *buffer,
- PHYSFS_uint32 objSize, PHYSFS_uint32 objCount)
-{
- BAIL_MACRO(ERR_NOT_SUPPORTED, -1);
-} /* MVL_write */
-
-
-static int MVL_eof(fvoid *opaque)
-{
- MVLfileinfo *finfo = (MVLfileinfo *) opaque;
- MVLentry *entry = finfo->entry;
- return(finfo->curPos >= entry->size);
-} /* MVL_eof */
-
-
-static PHYSFS_sint64 MVL_tell(fvoid *opaque)
-{
- return(((MVLfileinfo *) opaque)->curPos);
-} /* MVL_tell */
-
-
-static int MVL_seek(fvoid *opaque, PHYSFS_uint64 offset)
-{
- MVLfileinfo *finfo = (MVLfileinfo *) opaque;
- MVLentry *entry = finfo->entry;
- int rc;
-
- BAIL_IF_MACRO(offset < 0, ERR_INVALID_ARGUMENT, 0);
- BAIL_IF_MACRO(offset >= entry->size, ERR_PAST_EOF, 0);
- rc = __PHYSFS_platformSeek(finfo->handle, entry->startPos + offset);
- if (rc)
- finfo->curPos = (PHYSFS_uint32) offset;
-
- return(rc);
-} /* MVL_seek */
-
-
-static PHYSFS_sint64 MVL_fileLength(fvoid *opaque)
-{
- MVLfileinfo *finfo = (MVLfileinfo *) opaque;
- return((PHYSFS_sint64) finfo->entry->size);
-} /* MVL_fileLength */
-
-
-static int MVL_fileClose(fvoid *opaque)
-{
- MVLfileinfo *finfo = (MVLfileinfo *) opaque;
- BAIL_IF_MACRO(!__PHYSFS_platformClose(finfo->handle), NULL, 0);
- allocator.Free(finfo);
- return(1);
-} /* MVL_fileClose */
-
-
-static int mvl_open(const char *filename, int forWriting,
- void **fh, PHYSFS_uint32 *count)
-{
- PHYSFS_uint8 buf[4];
-
- *fh = NULL;
- BAIL_IF_MACRO(forWriting, ERR_ARC_IS_READ_ONLY, 0);
-
- *fh = __PHYSFS_platformOpenRead(filename);
- BAIL_IF_MACRO(*fh == NULL, NULL, 0);
-
- if (__PHYSFS_platformRead(*fh, buf, 4, 1) != 1)
- goto openMvl_failed;
-
- if (memcmp(buf, "DMVL", 4) != 0)
- {
- __PHYSFS_setError(ERR_UNSUPPORTED_ARCHIVE);
- goto openMvl_failed;
- } /* if */
-
- if (__PHYSFS_platformRead(*fh, count, sizeof (PHYSFS_uint32), 1) != 1)
- goto openMvl_failed;
-
- *count = PHYSFS_swapULE32(*count);
-
- return(1);
-
-openMvl_failed:
- if (*fh != NULL)
- __PHYSFS_platformClose(*fh);
-
- *count = -1;
- *fh = NULL;
- return(0);
-} /* mvl_open */
-
-
-static int MVL_isArchive(const char *filename, int forWriting)
-{
- void *fh;
- PHYSFS_uint32 fileCount;
- int retval = mvl_open(filename, forWriting, &fh, &fileCount);
-
- if (fh != NULL)
- __PHYSFS_platformClose(fh);
-
- return(retval);
-} /* MVL_isArchive */
-
-
-static int mvl_entry_cmp(void *_a, PHYSFS_uint32 one, PHYSFS_uint32 two)
-{
- MVLentry *a = (MVLentry *) _a;
- return(strcmp(a[one].name, a[two].name));
-} /* mvl_entry_cmp */
-
-
-static void mvl_entry_swap(void *_a, PHYSFS_uint32 one, PHYSFS_uint32 two)
-{
- MVLentry tmp;
- MVLentry *first = &(((MVLentry *) _a)[one]);
- MVLentry *second = &(((MVLentry *) _a)[two]);
- memcpy(&tmp, first, sizeof (MVLentry));
- memcpy(first, second, sizeof (MVLentry));
- memcpy(second, &tmp, sizeof (MVLentry));
-} /* mvl_entry_swap */
-
-
-static int mvl_load_entries(const char *name, int forWriting, MVLinfo *info)
-{
- void *fh = NULL;
- PHYSFS_uint32 fileCount;
- PHYSFS_uint32 location = 8; /* sizeof sig. */
- MVLentry *entry;
-
- BAIL_IF_MACRO(!mvl_open(name, forWriting, &fh, &fileCount), NULL, 0);
- info->entryCount = fileCount;
- info->entries = (MVLentry *) allocator.Malloc(sizeof(MVLentry)*fileCount);
- if (info->entries == NULL)
- {
- __PHYSFS_platformClose(fh);
- BAIL_MACRO(ERR_OUT_OF_MEMORY, 0);
- } /* if */
-
- location += (17 * fileCount);
-
- for (entry = info->entries; fileCount > 0; fileCount--, entry++)
- {
- if (__PHYSFS_platformRead(fh, &entry->name, 13, 1) != 1)
- {
- __PHYSFS_platformClose(fh);
- return(0);
- } /* if */
-
- if (__PHYSFS_platformRead(fh, &entry->size, 4, 1) != 1)
- {
- __PHYSFS_platformClose(fh);
- return(0);
- } /* if */
-
- entry->size = PHYSFS_swapULE32(entry->size);
- entry->startPos = location;
- location += entry->size;
- } /* for */
-
- __PHYSFS_platformClose(fh);
-
- __PHYSFS_sort(info->entries, info->entryCount,
- mvl_entry_cmp, mvl_entry_swap);
- return(1);
-} /* mvl_load_entries */
-
-
-static void *MVL_openArchive(const char *name, int forWriting)
-{
- PHYSFS_sint64 modtime = __PHYSFS_platformGetLastModTime(name);
- MVLinfo *info = (MVLinfo *) allocator.Malloc(sizeof (MVLinfo));
-
- BAIL_IF_MACRO(info == NULL, ERR_OUT_OF_MEMORY, NULL);
- memset(info, '\0', sizeof (MVLinfo));
-
- info->filename = (char *) allocator.Malloc(strlen(name) + 1);
- GOTO_IF_MACRO(!info->filename, ERR_OUT_OF_MEMORY, MVL_openArchive_failed);
- if (!mvl_load_entries(name, forWriting, info))
- goto MVL_openArchive_failed;
-
- strcpy(info->filename, name);
- info->last_mod_time = modtime;
- return(info);
-
-MVL_openArchive_failed:
- if (info != NULL)
- {
- if (info->filename != NULL)
- allocator.Free(info->filename);
- if (info->entries != NULL)
- allocator.Free(info->entries);
- allocator.Free(info);
- } /* if */
-
- return(NULL);
-} /* MVL_openArchive */
-
-
-static void MVL_enumerateFiles(dvoid *opaque, const char *dname,
- int omitSymLinks, PHYSFS_EnumFilesCallback cb,
- const char *origdir, void *callbackdata)
-{
- /* no directories in MVL files. */
- if (*dname == '\0')
- {
- MVLinfo *info = ((MVLinfo *) opaque);
- MVLentry *entry = info->entries;
- PHYSFS_uint32 max = info->entryCount;
- PHYSFS_uint32 i;
-
- for (i = 0; i < max; i++, entry++)
- cb(callbackdata, origdir, entry->name);
- } /* if */
-} /* MVL_enumerateFiles */
-
-
-static MVLentry *mvl_find_entry(MVLinfo *info, const char *name)
-{
- char *ptr = strchr(name, '.');
- MVLentry *a = info->entries;
- PHYSFS_sint32 lo = 0;
- PHYSFS_sint32 hi = (PHYSFS_sint32) (info->entryCount - 1);
- PHYSFS_sint32 middle;
- int rc;
-
- /*
- * Rule out filenames to avoid unneeded processing...no dirs,
- * big filenames, or extensions > 3 chars.
- */
- BAIL_IF_MACRO((ptr) && (strlen(ptr) > 4), ERR_NO_SUCH_FILE, NULL);
- BAIL_IF_MACRO(strlen(name) > 12, ERR_NO_SUCH_FILE, NULL);
- BAIL_IF_MACRO(strchr(name, '/') != NULL, ERR_NO_SUCH_FILE, NULL);
-
- while (lo <= hi)
- {
- middle = lo + ((hi - lo) / 2);
- rc = __PHYSFS_stricmpASCII(name, a[middle].name);
- if (rc == 0) /* found it! */
- return(&a[middle]);
- else if (rc > 0)
- lo = middle + 1;
- else
- hi = middle - 1;
- } /* while */
-
- BAIL_MACRO(ERR_NO_SUCH_FILE, NULL);
-} /* mvl_find_entry */
-
-
-static int MVL_exists(dvoid *opaque, const char *name)
-{
- return(mvl_find_entry(((MVLinfo *) opaque), name) != NULL);
-} /* MVL_exists */
-
-
-static int MVL_isDirectory(dvoid *opaque, const char *name, int *fileExists)
-{
- *fileExists = MVL_exists(opaque, name);
- return(0); /* never directories in a groupfile. */
-} /* MVL_isDirectory */
-
-
-static int MVL_isSymLink(dvoid *opaque, const char *name, int *fileExists)
-{
- *fileExists = MVL_exists(opaque, name);
- return(0); /* never symlinks in a groupfile. */
-} /* MVL_isSymLink */
-
-
-static PHYSFS_sint64 MVL_getLastModTime(dvoid *opaque,
- const char *name,
- int *fileExists)
-{
- MVLinfo *info = ((MVLinfo *) opaque);
- PHYSFS_sint64 retval = -1;
-
- *fileExists = (mvl_find_entry(info, name) != NULL);
- if (*fileExists) /* use time of MVL itself in the physical filesystem. */
- retval = info->last_mod_time;
-
- return(retval);
-} /* MVL_getLastModTime */
-
-
-static fvoid *MVL_openRead(dvoid *opaque, const char *fnm, int *fileExists)
-{
- MVLinfo *info = ((MVLinfo *) opaque);
- MVLfileinfo *finfo;
- MVLentry *entry;
-
- entry = mvl_find_entry(info, fnm);
- *fileExists = (entry != NULL);
- BAIL_IF_MACRO(entry == NULL, NULL, NULL);
-
- finfo = (MVLfileinfo *) allocator.Malloc(sizeof (MVLfileinfo));
- BAIL_IF_MACRO(finfo == NULL, ERR_OUT_OF_MEMORY, NULL);
-
- finfo->handle = __PHYSFS_platformOpenRead(info->filename);
- if ( (finfo->handle == NULL) ||
- (!__PHYSFS_platformSeek(finfo->handle, entry->startPos)) )
- {
- allocator.Free(finfo);
- return(NULL);
- } /* if */
-
- finfo->curPos = 0;
- finfo->entry = entry;
- return(finfo);
-} /* MVL_openRead */
-
-
-static fvoid *MVL_openWrite(dvoid *opaque, const char *name)
-{
- BAIL_MACRO(ERR_NOT_SUPPORTED, NULL);
-} /* MVL_openWrite */
-
-
-static fvoid *MVL_openAppend(dvoid *opaque, const char *name)
-{
- BAIL_MACRO(ERR_NOT_SUPPORTED, NULL);
-} /* MVL_openAppend */
-
-
-static int MVL_remove(dvoid *opaque, const char *name)
-{
- BAIL_MACRO(ERR_NOT_SUPPORTED, 0);
-} /* MVL_remove */
-
-
-static int MVL_mkdir(dvoid *opaque, const char *name)
-{
- BAIL_MACRO(ERR_NOT_SUPPORTED, 0);
-} /* MVL_mkdir */
-
-
-const PHYSFS_ArchiveInfo __PHYSFS_ArchiveInfo_MVL =
-{
- "MVL",
- MVL_ARCHIVE_DESCRIPTION,
- "Bradley Bell <btb@icculus.org>",
- "http://icculus.org/physfs/",
-};
-
-
-const PHYSFS_Archiver __PHYSFS_Archiver_MVL =
-{
- &__PHYSFS_ArchiveInfo_MVL,
- MVL_isArchive, /* isArchive() method */
- MVL_openArchive, /* openArchive() method */
- MVL_enumerateFiles, /* enumerateFiles() method */
- MVL_exists, /* exists() method */
- MVL_isDirectory, /* isDirectory() method */
- MVL_isSymLink, /* isSymLink() method */
- MVL_getLastModTime, /* getLastModTime() method */
- MVL_openRead, /* openRead() method */
- MVL_openWrite, /* openWrite() method */
- MVL_openAppend, /* openAppend() method */
- MVL_remove, /* remove() method */
- MVL_mkdir, /* mkdir() method */
- MVL_dirClose, /* dirClose() method */
- MVL_read, /* read() method */
- MVL_write, /* write() method */
- MVL_eof, /* eof() method */
- MVL_tell, /* tell() method */
- MVL_seek, /* seek() method */
- MVL_fileLength, /* fileLength() method */
- MVL_fileClose /* fileClose() method */
-};
-
-#endif /* defined PHYSFS_SUPPORTS_MVL */
-
-/* end of mvl.c ... */
-
+++ /dev/null
-/*
- * QPAK support routines for PhysicsFS.
- *
- * This archiver handles the archive format utilized by Quake 1 and 2.
- * Quake3-based games use the PkZip/Info-Zip format (which our zip.c
- * archiver handles).
- *
- * ========================================================================
- *
- * This format info (in more detail) comes from:
- * http://debian.fmi.uni-sofia.bg/~sergei/cgsr/docs/pak.txt
- *
- * Quake PAK Format
- *
- * Header
- * (4 bytes) signature = 'PACK'
- * (4 bytes) directory offset
- * (4 bytes) directory length
- *
- * Directory
- * (56 bytes) file name
- * (4 bytes) file position
- * (4 bytes) file length
- *
- * ========================================================================
- *
- * Please see the file LICENSE.txt in the source's root directory.
- *
- * This file written by Ryan C. Gordon.
- */
-
-#if (defined PHYSFS_SUPPORTS_QPAK)
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include "physfs.h"
-
-#define __PHYSICSFS_INTERNAL__
-#include "physfs_internal.h"
-
-#if 1 /* Make this case insensitive? */
-#define QPAK_strcmp(x, y) __PHYSFS_stricmpASCII(x, y)
-#define QPAK_strncmp(x, y, z) __PHYSFS_strnicmpASCII(x, y, z)
-#else
-#define QPAK_strcmp(x, y) strcmp(x, y)
-#define QPAK_strncmp(x, y, z) strncmp(x, y, z)
-#endif
-
-
-typedef struct
-{
- char name[56];
- PHYSFS_uint32 startPos;
- PHYSFS_uint32 size;
-} QPAKentry;
-
-typedef struct
-{
- char *filename;
- PHYSFS_sint64 last_mod_time;
- PHYSFS_uint32 entryCount;
- QPAKentry *entries;
-} QPAKinfo;
-
-typedef struct
-{
- void *handle;
- QPAKentry *entry;
- PHYSFS_uint32 curPos;
-} QPAKfileinfo;
-
-/* Magic numbers... */
-#define QPAK_SIG 0x4b434150 /* "PACK" in ASCII. */
-
-
-static void QPAK_dirClose(dvoid *opaque)
-{
- QPAKinfo *info = ((QPAKinfo *) opaque);
- allocator.Free(info->filename);
- allocator.Free(info->entries);
- allocator.Free(info);
-} /* QPAK_dirClose */
-
-
-static PHYSFS_sint64 QPAK_read(fvoid *opaque, void *buffer,
- PHYSFS_uint32 objSize, PHYSFS_uint32 objCount)
-{
- QPAKfileinfo *finfo = (QPAKfileinfo *) opaque;
- QPAKentry *entry = finfo->entry;
- PHYSFS_uint32 bytesLeft = entry->size - finfo->curPos;
- PHYSFS_uint32 objsLeft = (bytesLeft / objSize);
- PHYSFS_sint64 rc;
-
- if (objsLeft < objCount)
- objCount = objsLeft;
-
- rc = __PHYSFS_platformRead(finfo->handle, buffer, objSize, objCount);
- if (rc > 0)
- finfo->curPos += (PHYSFS_uint32) (rc * objSize);
-
- return(rc);
-} /* QPAK_read */
-
-
-static PHYSFS_sint64 QPAK_write(fvoid *opaque, const void *buffer,
- PHYSFS_uint32 objSize, PHYSFS_uint32 objCount)
-{
- BAIL_MACRO(ERR_NOT_SUPPORTED, -1);
-} /* QPAK_write */
-
-
-static int QPAK_eof(fvoid *opaque)
-{
- QPAKfileinfo *finfo = (QPAKfileinfo *) opaque;
- QPAKentry *entry = finfo->entry;
- return(finfo->curPos >= entry->size);
-} /* QPAK_eof */
-
-
-static PHYSFS_sint64 QPAK_tell(fvoid *opaque)
-{
- return(((QPAKfileinfo *) opaque)->curPos);
-} /* QPAK_tell */
-
-
-static int QPAK_seek(fvoid *opaque, PHYSFS_uint64 offset)
-{
- QPAKfileinfo *finfo = (QPAKfileinfo *) opaque;
- QPAKentry *entry = finfo->entry;
- int rc;
-
- BAIL_IF_MACRO(offset < 0, ERR_INVALID_ARGUMENT, 0);
- BAIL_IF_MACRO(offset >= entry->size, ERR_PAST_EOF, 0);
- rc = __PHYSFS_platformSeek(finfo->handle, entry->startPos + offset);
- if (rc)
- finfo->curPos = (PHYSFS_uint32) offset;
-
- return(rc);
-} /* QPAK_seek */
-
-
-static PHYSFS_sint64 QPAK_fileLength(fvoid *opaque)
-{
- QPAKfileinfo *finfo = (QPAKfileinfo *) opaque;
- return((PHYSFS_sint64) finfo->entry->size);
-} /* QPAK_fileLength */
-
-
-static int QPAK_fileClose(fvoid *opaque)
-{
- QPAKfileinfo *finfo = (QPAKfileinfo *) opaque;
- BAIL_IF_MACRO(!__PHYSFS_platformClose(finfo->handle), NULL, 0);
- allocator.Free(finfo);
- return(1);
-} /* QPAK_fileClose */
-
-
-static int qpak_open(const char *filename, int forWriting,
- void **fh, PHYSFS_uint32 *count)
-{
- PHYSFS_uint32 buf;
-
- *fh = NULL;
- BAIL_IF_MACRO(forWriting, ERR_ARC_IS_READ_ONLY, 0);
-
- *fh = __PHYSFS_platformOpenRead(filename);
- BAIL_IF_MACRO(*fh == NULL, NULL, 0);
-
- if (__PHYSFS_platformRead(*fh, &buf, sizeof (PHYSFS_uint32), 1) != 1)
- goto openQpak_failed;
-
- buf = PHYSFS_swapULE32(buf);
- GOTO_IF_MACRO(buf != QPAK_SIG, ERR_UNSUPPORTED_ARCHIVE, openQpak_failed);
-
- if (__PHYSFS_platformRead(*fh, &buf, sizeof (PHYSFS_uint32), 1) != 1)
- goto openQpak_failed;
-
- buf = PHYSFS_swapULE32(buf); /* directory table offset. */
-
- if (__PHYSFS_platformRead(*fh, count, sizeof (PHYSFS_uint32), 1) != 1)
- goto openQpak_failed;
-
- *count = PHYSFS_swapULE32(*count);
-
- /* corrupted archive? */
- GOTO_IF_MACRO((*count % 64) != 0, ERR_CORRUPTED, openQpak_failed);
-
- if (!__PHYSFS_platformSeek(*fh, buf))
- goto openQpak_failed;
-
- *count /= 64;
- return(1);
-
-openQpak_failed:
- if (*fh != NULL)
- __PHYSFS_platformClose(*fh);
-
- *count = -1;
- *fh = NULL;
- return(0);
-} /* qpak_open */
-
-
-static int QPAK_isArchive(const char *filename, int forWriting)
-{
- void *fh;
- PHYSFS_uint32 fileCount;
- int retval = qpak_open(filename, forWriting, &fh, &fileCount);
-
- if (fh != NULL)
- __PHYSFS_platformClose(fh);
-
- return(retval);
-} /* QPAK_isArchive */
-
-
-static int qpak_entry_cmp(void *_a, PHYSFS_uint32 one, PHYSFS_uint32 two)
-{
- QPAKentry *a = (QPAKentry *) _a;
- return(QPAK_strcmp(a[one].name, a[two].name));
-} /* qpak_entry_cmp */
-
-
-static void qpak_entry_swap(void *_a, PHYSFS_uint32 one, PHYSFS_uint32 two)
-{
- QPAKentry tmp;
- QPAKentry *first = &(((QPAKentry *) _a)[one]);
- QPAKentry *second = &(((QPAKentry *) _a)[two]);
- memcpy(&tmp, first, sizeof (QPAKentry));
- memcpy(first, second, sizeof (QPAKentry));
- memcpy(second, &tmp, sizeof (QPAKentry));
-} /* qpak_entry_swap */
-
-
-static int qpak_load_entries(const char *name, int forWriting, QPAKinfo *info)
-{
- void *fh = NULL;
- PHYSFS_uint32 fileCount;
- QPAKentry *entry;
-
- BAIL_IF_MACRO(!qpak_open(name, forWriting, &fh, &fileCount), NULL, 0);
- info->entryCount = fileCount;
- info->entries = (QPAKentry*) allocator.Malloc(sizeof(QPAKentry)*fileCount);
- if (info->entries == NULL)
- {
- __PHYSFS_platformClose(fh);
- BAIL_MACRO(ERR_OUT_OF_MEMORY, 0);
- } /* if */
-
- for (entry = info->entries; fileCount > 0; fileCount--, entry++)
- {
- PHYSFS_uint32 loc;
-
- if (__PHYSFS_platformRead(fh,&entry->name,sizeof(entry->name),1) != 1)
- {
- __PHYSFS_platformClose(fh);
- return(0);
- } /* if */
-
- if (__PHYSFS_platformRead(fh,&loc,sizeof(loc),1) != 1)
- {
- __PHYSFS_platformClose(fh);
- return(0);
- } /* if */
-
- if (__PHYSFS_platformRead(fh,&entry->size,sizeof(entry->size),1) != 1)
- {
- __PHYSFS_platformClose(fh);
- return(0);
- } /* if */
-
- entry->size = PHYSFS_swapULE32(entry->size);
- entry->startPos = PHYSFS_swapULE32(loc);
- } /* for */
-
- __PHYSFS_platformClose(fh);
-
- __PHYSFS_sort(info->entries, info->entryCount,
- qpak_entry_cmp, qpak_entry_swap);
- return(1);
-} /* qpak_load_entries */
-
-
-static void *QPAK_openArchive(const char *name, int forWriting)
-{
- QPAKinfo *info = (QPAKinfo *) allocator.Malloc(sizeof (QPAKinfo));
- PHYSFS_sint64 modtime = __PHYSFS_platformGetLastModTime(name);
-
- BAIL_IF_MACRO(info == NULL, ERR_OUT_OF_MEMORY, NULL);
- memset(info, '\0', sizeof (QPAKinfo));
-
- info->filename = (char *) allocator.Malloc(strlen(name) + 1);
- if (info->filename == NULL)
- {
- __PHYSFS_setError(ERR_OUT_OF_MEMORY);
- goto QPAK_openArchive_failed;
- } /* if */
-
- if (!qpak_load_entries(name, forWriting, info))
- goto QPAK_openArchive_failed;
-
- strcpy(info->filename, name);
- info->last_mod_time = modtime;
- return(info);
-
-QPAK_openArchive_failed:
- if (info != NULL)
- {
- if (info->filename != NULL)
- allocator.Free(info->filename);
- if (info->entries != NULL)
- allocator.Free(info->entries);
- allocator.Free(info);
- } /* if */
-
- return(NULL);
-} /* QPAK_openArchive */
-
-
-static PHYSFS_sint32 qpak_find_start_of_dir(QPAKinfo *info, const char *path,
- int stop_on_first_find)
-{
- PHYSFS_sint32 lo = 0;
- PHYSFS_sint32 hi = (PHYSFS_sint32) (info->entryCount - 1);
- PHYSFS_sint32 middle;
- PHYSFS_uint32 dlen = strlen(path);
- PHYSFS_sint32 retval = -1;
- const char *name;
- int rc;
-
- if (*path == '\0') /* root dir? */
- return(0);
-
- if ((dlen > 0) && (path[dlen - 1] == '/')) /* ignore trailing slash. */
- dlen--;
-
- while (lo <= hi)
- {
- middle = lo + ((hi - lo) / 2);
- name = info->entries[middle].name;
- rc = QPAK_strncmp(path, name, dlen);
- if (rc == 0)
- {
- char ch = name[dlen];
- if (ch < '/') /* make sure this isn't just a substr match. */
- rc = -1;
- else if (ch > '/')
- rc = 1;
- else
- {
- if (stop_on_first_find) /* Just checking dir's existance? */
- return(middle);
-
- if (name[dlen + 1] == '\0') /* Skip initial dir entry. */
- return(middle + 1);
-
- /* there might be more entries earlier in the list. */
- retval = middle;
- hi = middle - 1;
- } /* else */
- } /* if */
-
- if (rc > 0)
- lo = middle + 1;
- else
- hi = middle - 1;
- } /* while */
-
- return(retval);
-} /* qpak_find_start_of_dir */
-
-
-/*
- * Moved to seperate function so we can use alloca then immediately throw
- * away the allocated stack space...
- */
-static void doEnumCallback(PHYSFS_EnumFilesCallback cb, void *callbackdata,
- const char *odir, const char *str, PHYSFS_sint32 ln)
-{
- char *newstr = __PHYSFS_smallAlloc(ln + 1);
- if (newstr == NULL)
- return;
-
- memcpy(newstr, str, ln);
- newstr[ln] = '\0';
- cb(callbackdata, odir, newstr);
- __PHYSFS_smallFree(newstr);
-} /* doEnumCallback */
-
-
-static void QPAK_enumerateFiles(dvoid *opaque, const char *dname,
- int omitSymLinks, PHYSFS_EnumFilesCallback cb,
- const char *origdir, void *callbackdata)
-{
- QPAKinfo *info = ((QPAKinfo *) opaque);
- PHYSFS_sint32 dlen, dlen_inc, max, i;
-
- i = qpak_find_start_of_dir(info, dname, 0);
- if (i == -1) /* no such directory. */
- return;
-
- dlen = strlen(dname);
- if ((dlen > 0) && (dname[dlen - 1] == '/')) /* ignore trailing slash. */
- dlen--;
-
- dlen_inc = ((dlen > 0) ? 1 : 0) + dlen;
- max = (PHYSFS_sint32) info->entryCount;
- while (i < max)
- {
- char *add;
- char *ptr;
- PHYSFS_sint32 ln;
- char *e = info->entries[i].name;
- if ((dlen) && ((QPAK_strncmp(e, dname, dlen)) || (e[dlen] != '/')))
- break; /* past end of this dir; we're done. */
-
- add = e + dlen_inc;
- ptr = strchr(add, '/');
- ln = (PHYSFS_sint32) ((ptr) ? ptr-add : strlen(add));
- doEnumCallback(cb, callbackdata, origdir, add, ln);
- ln += dlen_inc; /* point past entry to children... */
-
- /* increment counter and skip children of subdirs... */
- while ((++i < max) && (ptr != NULL))
- {
- char *e_new = info->entries[i].name;
- if ((QPAK_strncmp(e, e_new, ln) != 0) || (e_new[ln] != '/'))
- break;
- } /* while */
- } /* while */
-} /* QPAK_enumerateFiles */
-
-
-/*
- * This will find the QPAKentry associated with a path in platform-independent
- * notation. Directories don't have QPAKentries associated with them, but
- * (*isDir) will be set to non-zero if a dir was hit.
- */
-static QPAKentry *qpak_find_entry(QPAKinfo *info, const char *path, int *isDir)
-{
- QPAKentry *a = info->entries;
- PHYSFS_sint32 pathlen = strlen(path);
- PHYSFS_sint32 lo = 0;
- PHYSFS_sint32 hi = (PHYSFS_sint32) (info->entryCount - 1);
- PHYSFS_sint32 middle;
- const char *thispath = NULL;
- int rc;
-
- while (lo <= hi)
- {
- middle = lo + ((hi - lo) / 2);
- thispath = a[middle].name;
- rc = QPAK_strncmp(path, thispath, pathlen);
-
- if (rc > 0)
- lo = middle + 1;
-
- else if (rc < 0)
- hi = middle - 1;
-
- else /* substring match...might be dir or entry or nothing. */
- {
- if (isDir != NULL)
- {
- *isDir = (thispath[pathlen] == '/');
- if (*isDir)
- return(NULL);
- } /* if */
-
- if (thispath[pathlen] == '\0') /* found entry? */
- return(&a[middle]);
- else
- hi = middle - 1; /* adjust search params, try again. */
- } /* if */
- } /* while */
-
- if (isDir != NULL)
- *isDir = 0;
-
- BAIL_MACRO(ERR_NO_SUCH_FILE, NULL);
-} /* qpak_find_entry */
-
-
-static int QPAK_exists(dvoid *opaque, const char *name)
-{
- int isDir;
- QPAKinfo *info = (QPAKinfo *) opaque;
- QPAKentry *entry = qpak_find_entry(info, name, &isDir);
- return((entry != NULL) || (isDir));
-} /* QPAK_exists */
-
-
-static int QPAK_isDirectory(dvoid *opaque, const char *name, int *fileExists)
-{
- QPAKinfo *info = (QPAKinfo *) opaque;
- int isDir;
- QPAKentry *entry = qpak_find_entry(info, name, &isDir);
-
- *fileExists = ((isDir) || (entry != NULL));
- if (isDir)
- return(1); /* definitely a dir. */
-
- BAIL_MACRO(ERR_NO_SUCH_FILE, 0);
-} /* QPAK_isDirectory */
-
-
-static int QPAK_isSymLink(dvoid *opaque, const char *name, int *fileExists)
-{
- *fileExists = QPAK_exists(opaque, name);
- return(0); /* never symlinks in a quake pak. */
-} /* QPAK_isSymLink */
-
-
-static PHYSFS_sint64 QPAK_getLastModTime(dvoid *opaque,
- const char *name,
- int *fileExists)
-{
- int isDir;
- QPAKinfo *info = ((QPAKinfo *) opaque);
- PHYSFS_sint64 retval = -1;
- QPAKentry *entry = qpak_find_entry(info, name, &isDir);
-
- *fileExists = ((isDir) || (entry != NULL));
- if (*fileExists) /* use time of QPAK itself in the physical filesystem. */
- retval = info->last_mod_time;
-
- return(retval);
-} /* QPAK_getLastModTime */
-
-
-static fvoid *QPAK_openRead(dvoid *opaque, const char *fnm, int *fileExists)
-{
- QPAKinfo *info = ((QPAKinfo *) opaque);
- QPAKfileinfo *finfo;
- QPAKentry *entry;
- int isDir;
-
- entry = qpak_find_entry(info, fnm, &isDir);
- *fileExists = ((entry != NULL) || (isDir));
- BAIL_IF_MACRO(isDir, ERR_NOT_A_FILE, NULL);
- BAIL_IF_MACRO(entry == NULL, ERR_NO_SUCH_FILE, NULL);
-
- finfo = (QPAKfileinfo *) allocator.Malloc(sizeof (QPAKfileinfo));
- BAIL_IF_MACRO(finfo == NULL, ERR_OUT_OF_MEMORY, NULL);
-
- finfo->handle = __PHYSFS_platformOpenRead(info->filename);
- if ( (finfo->handle == NULL) ||
- (!__PHYSFS_platformSeek(finfo->handle, entry->startPos)) )
- {
- allocator.Free(finfo);
- return(NULL);
- } /* if */
-
- finfo->curPos = 0;
- finfo->entry = entry;
- return(finfo);
-} /* QPAK_openRead */
-
-
-static fvoid *QPAK_openWrite(dvoid *opaque, const char *name)
-{
- BAIL_MACRO(ERR_NOT_SUPPORTED, NULL);
-} /* QPAK_openWrite */
-
-
-static fvoid *QPAK_openAppend(dvoid *opaque, const char *name)
-{
- BAIL_MACRO(ERR_NOT_SUPPORTED, NULL);
-} /* QPAK_openAppend */
-
-
-static int QPAK_remove(dvoid *opaque, const char *name)
-{
- BAIL_MACRO(ERR_NOT_SUPPORTED, 0);
-} /* QPAK_remove */
-
-
-static int QPAK_mkdir(dvoid *opaque, const char *name)
-{
- BAIL_MACRO(ERR_NOT_SUPPORTED, 0);
-} /* QPAK_mkdir */
-
-
-const PHYSFS_ArchiveInfo __PHYSFS_ArchiveInfo_QPAK =
-{
- "PAK",
- QPAK_ARCHIVE_DESCRIPTION,
- "Ryan C. Gordon <icculus@icculus.org>",
- "http://icculus.org/physfs/",
-};
-
-
-const PHYSFS_Archiver __PHYSFS_Archiver_QPAK =
-{
- &__PHYSFS_ArchiveInfo_QPAK,
- QPAK_isArchive, /* isArchive() method */
- QPAK_openArchive, /* openArchive() method */
- QPAK_enumerateFiles, /* enumerateFiles() method */
- QPAK_exists, /* exists() method */
- QPAK_isDirectory, /* isDirectory() method */
- QPAK_isSymLink, /* isSymLink() method */
- QPAK_getLastModTime, /* getLastModTime() method */
- QPAK_openRead, /* openRead() method */
- QPAK_openWrite, /* openWrite() method */
- QPAK_openAppend, /* openAppend() method */
- QPAK_remove, /* remove() method */
- QPAK_mkdir, /* mkdir() method */
- QPAK_dirClose, /* dirClose() method */
- QPAK_read, /* read() method */
- QPAK_write, /* write() method */
- QPAK_eof, /* eof() method */
- QPAK_tell, /* tell() method */
- QPAK_seek, /* seek() method */
- QPAK_fileLength, /* fileLength() method */
- QPAK_fileClose /* fileClose() method */
-};
-
-#endif /* defined PHYSFS_SUPPORTS_QPAK */
-
-/* end of qpak.c ... */
-
+++ /dev/null
-/*
- * WAD support routines for PhysicsFS.
- *
- * This driver handles DOOM engine archives ("wads").
- * This format (but not this driver) was designed by id Software for use
- * with the DOOM engine.
- * The specs of the format are from the unofficial doom specs v1.666
- * found here: http://www.gamers.org/dhs/helpdocs/dmsp1666.html
- * The format of the archive: (from the specs)
- *
- * A WAD file has three parts:
- * (1) a twelve-byte header
- * (2) one or more "lumps"
- * (3) a directory or "info table" that contains the names, offsets, and
- * sizes of all the lumps in the WAD
- *
- * The header consists of three four-byte parts:
- * (a) an ASCII string which must be either "IWAD" or "PWAD"
- * (b) a 4-byte (long) integer which is the number of lumps in the wad
- * (c) a long integer which is the file offset to the start of
- * the directory
- *
- * The directory has one 16-byte entry for every lump. Each entry consists
- * of three parts:
- *
- * (a) a long integer, the file offset to the start of the lump
- * (b) a long integer, the size of the lump in bytes
- * (c) an 8-byte ASCII string, the name of the lump, padded with zeros.
- * For example, the "DEMO1" entry in hexadecimal would be
- * (44 45 4D 4F 31 00 00 00)
- *
- * Note that there is no way to tell if an opened WAD archive is a
- * IWAD or PWAD with this archiver.
- * I couldn't think of a way to provide that information, without being too
- * hacky.
- * I don't think it's really that important though.
- *
- *
- * Please see the file LICENSE.txt in the source's root directory.
- *
- * This file written by Travis Wells, based on the GRP archiver by
- * Ryan C. Gordon.
- */
-
-#if (defined PHYSFS_SUPPORTS_WAD)
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include "physfs.h"
-
-#define __PHYSICSFS_INTERNAL__
-#include "physfs_internal.h"
-
-typedef struct
-{
- char name[18];
- PHYSFS_uint32 startPos;
- PHYSFS_uint32 size;
-} WADentry;
-
-typedef struct
-{
- char *filename;
- PHYSFS_sint64 last_mod_time;
- PHYSFS_uint32 entryCount;
- PHYSFS_uint32 entryOffset;
- WADentry *entries;
-} WADinfo;
-
-typedef struct
-{
- void *handle;
- WADentry *entry;
- PHYSFS_uint32 curPos;
-} WADfileinfo;
-
-
-static void WAD_dirClose(dvoid *opaque)
-{
- WADinfo *info = ((WADinfo *) opaque);
- allocator.Free(info->filename);
- allocator.Free(info->entries);
- allocator.Free(info);
-} /* WAD_dirClose */
-
-
-static PHYSFS_sint64 WAD_read(fvoid *opaque, void *buffer,
- PHYSFS_uint32 objSize, PHYSFS_uint32 objCount)
-{
- WADfileinfo *finfo = (WADfileinfo *) opaque;
- WADentry *entry = finfo->entry;
- PHYSFS_uint32 bytesLeft = entry->size - finfo->curPos;
- PHYSFS_uint32 objsLeft = (bytesLeft / objSize);
- PHYSFS_sint64 rc;
-
- if (objsLeft < objCount)
- objCount = objsLeft;
-
- rc = __PHYSFS_platformRead(finfo->handle, buffer, objSize, objCount);
- if (rc > 0)
- finfo->curPos += (PHYSFS_uint32) (rc * objSize);
-
- return(rc);
-} /* WAD_read */
-
-
-static PHYSFS_sint64 WAD_write(fvoid *opaque, const void *buffer,
- PHYSFS_uint32 objSize, PHYSFS_uint32 objCount)
-{
- BAIL_MACRO(ERR_NOT_SUPPORTED, -1);
-} /* WAD_write */
-
-
-static int WAD_eof(fvoid *opaque)
-{
- WADfileinfo *finfo = (WADfileinfo *) opaque;
- WADentry *entry = finfo->entry;
- return(finfo->curPos >= entry->size);
-} /* WAD_eof */
-
-
-static PHYSFS_sint64 WAD_tell(fvoid *opaque)
-{
- return(((WADfileinfo *) opaque)->curPos);
-} /* WAD_tell */
-
-
-static int WAD_seek(fvoid *opaque, PHYSFS_uint64 offset)
-{
- WADfileinfo *finfo = (WADfileinfo *) opaque;
- WADentry *entry = finfo->entry;
- int rc;
-
- BAIL_IF_MACRO(offset < 0, ERR_INVALID_ARGUMENT, 0);
- BAIL_IF_MACRO(offset >= entry->size, ERR_PAST_EOF, 0);
- rc = __PHYSFS_platformSeek(finfo->handle, entry->startPos + offset);
- if (rc)
- finfo->curPos = (PHYSFS_uint32) offset;
-
- return(rc);
-} /* WAD_seek */
-
-
-static PHYSFS_sint64 WAD_fileLength(fvoid *opaque)
-{
- WADfileinfo *finfo = (WADfileinfo *) opaque;
- return((PHYSFS_sint64) finfo->entry->size);
-} /* WAD_fileLength */
-
-
-static int WAD_fileClose(fvoid *opaque)
-{
- WADfileinfo *finfo = (WADfileinfo *) opaque;
- BAIL_IF_MACRO(!__PHYSFS_platformClose(finfo->handle), NULL, 0);
- allocator.Free(finfo);
- return(1);
-} /* WAD_fileClose */
-
-
-static int wad_open(const char *filename, int forWriting,
- void **fh, PHYSFS_uint32 *count,PHYSFS_uint32 *offset)
-{
- PHYSFS_uint8 buf[4];
-
- *fh = NULL;
- BAIL_IF_MACRO(forWriting, ERR_ARC_IS_READ_ONLY, 0);
-
- *fh = __PHYSFS_platformOpenRead(filename);
- BAIL_IF_MACRO(*fh == NULL, NULL, 0);
-
- if (__PHYSFS_platformRead(*fh, buf, 4, 1) != 1)
- goto openWad_failed;
-
- if (memcmp(buf, "IWAD", 4) != 0 && memcmp(buf, "PWAD", 4) != 0)
- {
- __PHYSFS_setError(ERR_UNSUPPORTED_ARCHIVE);
- goto openWad_failed;
- } /* if */
-
- if (__PHYSFS_platformRead(*fh, count, sizeof (PHYSFS_uint32), 1) != 1)
- goto openWad_failed;
-
- *count = PHYSFS_swapULE32(*count);
-
- if (__PHYSFS_platformRead(*fh, offset, sizeof (PHYSFS_uint32), 1) != 1)
- goto openWad_failed;
-
- *offset = PHYSFS_swapULE32(*offset);
-
- return(1);
-
-openWad_failed:
- if (*fh != NULL)
- __PHYSFS_platformClose(*fh);
-
- *count = -1;
- *fh = NULL;
- return(0);
-} /* wad_open */
-
-
-static int WAD_isArchive(const char *filename, int forWriting)
-{
- void *fh;
- PHYSFS_uint32 fileCount,offset;
- int retval = wad_open(filename, forWriting, &fh, &fileCount,&offset);
-
- if (fh != NULL)
- __PHYSFS_platformClose(fh);
-
- return(retval);
-} /* WAD_isArchive */
-
-
-static int wad_entry_cmp(void *_a, PHYSFS_uint32 one, PHYSFS_uint32 two)
-{
- WADentry *a = (WADentry *) _a;
- return(strcmp(a[one].name, a[two].name));
-} /* wad_entry_cmp */
-
-
-static void wad_entry_swap(void *_a, PHYSFS_uint32 one, PHYSFS_uint32 two)
-{
- WADentry tmp;
- WADentry *first = &(((WADentry *) _a)[one]);
- WADentry *second = &(((WADentry *) _a)[two]);
- memcpy(&tmp, first, sizeof (WADentry));
- memcpy(first, second, sizeof (WADentry));
- memcpy(second, &tmp, sizeof (WADentry));
-} /* wad_entry_swap */
-
-
-static int wad_load_entries(const char *name, int forWriting, WADinfo *info)
-{
- void *fh = NULL;
- PHYSFS_uint32 fileCount;
- PHYSFS_uint32 directoryOffset;
- WADentry *entry;
- char lastDirectory[9];
-
- lastDirectory[8] = 0; /* Make sure lastDirectory stays null-terminated. */
-
- BAIL_IF_MACRO(!wad_open(name, forWriting, &fh, &fileCount,&directoryOffset), NULL, 0);
- info->entryCount = fileCount;
- info->entries = (WADentry *) allocator.Malloc(sizeof(WADentry)*fileCount);
- if (info->entries == NULL)
- {
- __PHYSFS_platformClose(fh);
- BAIL_MACRO(ERR_OUT_OF_MEMORY, 0);
- } /* if */
-
- __PHYSFS_platformSeek(fh,directoryOffset);
-
- for (entry = info->entries; fileCount > 0; fileCount--, entry++)
- {
- if (__PHYSFS_platformRead(fh, &entry->startPos, 4, 1) != 1)
- {
- __PHYSFS_platformClose(fh);
- return(0);
- } /* if */
-
- if (__PHYSFS_platformRead(fh, &entry->size, 4, 1) != 1)
- {
- __PHYSFS_platformClose(fh);
- return(0);
- } /* if */
-
- if (__PHYSFS_platformRead(fh, &entry->name, 8, 1) != 1)
- {
- __PHYSFS_platformClose(fh);
- return(0);
- } /* if */
-
- entry->name[8] = '\0'; /* name might not be null-terminated in file. */
- entry->size = PHYSFS_swapULE32(entry->size);
- entry->startPos = PHYSFS_swapULE32(entry->startPos);
- } /* for */
-
- __PHYSFS_platformClose(fh);
-
- __PHYSFS_sort(info->entries, info->entryCount,
- wad_entry_cmp, wad_entry_swap);
- return(1);
-} /* wad_load_entries */
-
-
-static void *WAD_openArchive(const char *name, int forWriting)
-{
- PHYSFS_sint64 modtime = __PHYSFS_platformGetLastModTime(name);
- WADinfo *info = (WADinfo *) allocator.Malloc(sizeof (WADinfo));
-
- BAIL_IF_MACRO(info == NULL, ERR_OUT_OF_MEMORY, NULL);
- memset(info, '\0', sizeof (WADinfo));
-
- info->filename = (char *) allocator.Malloc(strlen(name) + 1);
- GOTO_IF_MACRO(!info->filename, ERR_OUT_OF_MEMORY, WAD_openArchive_failed);
-
- if (!wad_load_entries(name, forWriting, info))
- goto WAD_openArchive_failed;
-
- strcpy(info->filename, name);
- info->last_mod_time = modtime;
- return(info);
-
-WAD_openArchive_failed:
- if (info != NULL)
- {
- if (info->filename != NULL)
- allocator.Free(info->filename);
- if (info->entries != NULL)
- allocator.Free(info->entries);
- allocator.Free(info);
- } /* if */
-
- return(NULL);
-} /* WAD_openArchive */
-
-
-static void WAD_enumerateFiles(dvoid *opaque, const char *dname,
- int omitSymLinks, PHYSFS_EnumFilesCallback cb,
- const char *origdir, void *callbackdata)
-{
- WADinfo *info = ((WADinfo *) opaque);
- WADentry *entry = info->entries;
- PHYSFS_uint32 max = info->entryCount;
- PHYSFS_uint32 i;
- const char *name;
- char *sep;
-
- if (*dname == '\0') /* root directory enumeration? */
- {
- for (i = 0; i < max; i++, entry++)
- {
- name = entry->name;
- if (strchr(name, '/') == NULL)
- cb(callbackdata, origdir, name);
- } /* for */
- } /* if */
- else
- {
- for (i = 0; i < max; i++, entry++)
- {
- name = entry->name;
- sep = strchr(name, '/');
- if (sep != NULL)
- {
- if (strncmp(dname, name, (sep - name)) == 0)
- cb(callbackdata, origdir, sep + 1);
- } /* if */
- } /* for */
- } /* else */
-} /* WAD_enumerateFiles */
-
-
-static WADentry *wad_find_entry(WADinfo *info, const char *name)
-{
- WADentry *a = info->entries;
- PHYSFS_sint32 lo = 0;
- PHYSFS_sint32 hi = (PHYSFS_sint32) (info->entryCount - 1);
- PHYSFS_sint32 middle;
- int rc;
-
- while (lo <= hi)
- {
- middle = lo + ((hi - lo) / 2);
- rc = strcmp(name, a[middle].name);
- if (rc == 0) /* found it! */
- return(&a[middle]);
- else if (rc > 0)
- lo = middle + 1;
- else
- hi = middle - 1;
- } /* while */
-
- BAIL_MACRO(ERR_NO_SUCH_FILE, NULL);
-} /* wad_find_entry */
-
-
-static int WAD_exists(dvoid *opaque, const char *name)
-{
- return(wad_find_entry(((WADinfo *) opaque), name) != NULL);
-} /* WAD_exists */
-
-
-static int WAD_isDirectory(dvoid *opaque, const char *name, int *fileExists)
-{
- WADentry *entry = wad_find_entry(((WADinfo *) opaque), name);
- if (entry != NULL)
- {
- char *n;
-
- *fileExists = 1;
-
- /* Can't be a directory if it's a subdirectory. */
- if (strchr(entry->name, '/') != NULL)
- return(0);
-
- /* Check if it matches "MAP??" or "E?M?" ... */
- n = entry->name;
- if ((n[0] == 'E' && n[2] == 'M') ||
- (n[0] == 'M' && n[1] == 'A' && n[2] == 'P' && n[6] == 0))
- {
- return(1);
- } /* if */
- return(0);
- } /* if */
- else
- {
- *fileExists = 0;
- return(0);
- } /* else */
-} /* WAD_isDirectory */
-
-
-static int WAD_isSymLink(dvoid *opaque, const char *name, int *fileExists)
-{
- *fileExists = WAD_exists(opaque, name);
- return(0); /* never symlinks in a wad. */
-} /* WAD_isSymLink */
-
-
-static PHYSFS_sint64 WAD_getLastModTime(dvoid *opaque,
- const char *name,
- int *fileExists)
-{
- WADinfo *info = ((WADinfo *) opaque);
- PHYSFS_sint64 retval = -1;
-
- *fileExists = (wad_find_entry(info, name) != NULL);
- if (*fileExists) /* use time of WAD itself in the physical filesystem. */
- retval = info->last_mod_time;
-
- return(retval);
-} /* WAD_getLastModTime */
-
-
-static fvoid *WAD_openRead(dvoid *opaque, const char *fnm, int *fileExists)
-{
- WADinfo *info = ((WADinfo *) opaque);
- WADfileinfo *finfo;
- WADentry *entry;
-
- entry = wad_find_entry(info, fnm);
- *fileExists = (entry != NULL);
- BAIL_IF_MACRO(entry == NULL, NULL, NULL);
-
- finfo = (WADfileinfo *) allocator.Malloc(sizeof (WADfileinfo));
- BAIL_IF_MACRO(finfo == NULL, ERR_OUT_OF_MEMORY, NULL);
-
- finfo->handle = __PHYSFS_platformOpenRead(info->filename);
- if ( (finfo->handle == NULL) ||
- (!__PHYSFS_platformSeek(finfo->handle, entry->startPos)) )
- {
- allocator.Free(finfo);
- return(NULL);
- } /* if */
-
- finfo->curPos = 0;
- finfo->entry = entry;
- return(finfo);
-} /* WAD_openRead */
-
-
-static fvoid *WAD_openWrite(dvoid *opaque, const char *name)
-{
- BAIL_MACRO(ERR_NOT_SUPPORTED, NULL);
-} /* WAD_openWrite */
-
-
-static fvoid *WAD_openAppend(dvoid *opaque, const char *name)
-{
- BAIL_MACRO(ERR_NOT_SUPPORTED, NULL);
-} /* WAD_openAppend */
-
-
-static int WAD_remove(dvoid *opaque, const char *name)
-{
- BAIL_MACRO(ERR_NOT_SUPPORTED, 0);
-} /* WAD_remove */
-
-
-static int WAD_mkdir(dvoid *opaque, const char *name)
-{
- BAIL_MACRO(ERR_NOT_SUPPORTED, 0);
-} /* WAD_mkdir */
-
-
-const PHYSFS_ArchiveInfo __PHYSFS_ArchiveInfo_WAD =
-{
- "WAD",
- WAD_ARCHIVE_DESCRIPTION,
- "Travis Wells <traviswells@mchsi.com>",
- "http://www.3dmm2.com/doom/",
-};
-
-
-const PHYSFS_Archiver __PHYSFS_Archiver_WAD =
-{
- &__PHYSFS_ArchiveInfo_WAD,
- WAD_isArchive, /* isArchive() method */
- WAD_openArchive, /* openArchive() method */
- WAD_enumerateFiles, /* enumerateFiles() method */
- WAD_exists, /* exists() method */
- WAD_isDirectory, /* isDirectory() method */
- WAD_isSymLink, /* isSymLink() method */
- WAD_getLastModTime, /* getLastModTime() method */
- WAD_openRead, /* openRead() method */
- WAD_openWrite, /* openWrite() method */
- WAD_openAppend, /* openAppend() method */
- WAD_remove, /* remove() method */
- WAD_mkdir, /* mkdir() method */
- WAD_dirClose, /* dirClose() method */
- WAD_read, /* read() method */
- WAD_write, /* write() method */
- WAD_eof, /* eof() method */
- WAD_tell, /* tell() method */
- WAD_seek, /* seek() method */
- WAD_fileLength, /* fileLength() method */
- WAD_fileClose /* fileClose() method */
-};
-
-#endif /* defined PHYSFS_SUPPORTS_WAD */
-
-/* end of wad.c ... */
-
+++ /dev/null
-/*
- * ZIP support routines for PhysicsFS.
- *
- * Please see the file LICENSE.txt in the source's root directory.
- *
- * This file written by Ryan C. Gordon, with some peeking at "unzip.c"
- * by Gilles Vollant.
- */
-
-#if (defined PHYSFS_SUPPORTS_ZIP)
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#ifndef _WIN32_WCE
-#include <errno.h>
-#include <time.h>
-#endif
-#include "physfs.h"
-#include "zlib.h"
-
-#define __PHYSICSFS_INTERNAL__
-#include "physfs_internal.h"
-
-/*
- * A buffer of ZIP_READBUFSIZE is allocated for each compressed file opened,
- * and is freed when you close the file; compressed data is read into
- * this buffer, and then is decompressed into the buffer passed to
- * PHYSFS_read().
- *
- * Uncompressed entries in a zipfile do not allocate this buffer; they just
- * read data directly into the buffer passed to PHYSFS_read().
- *
- * Depending on your speed and memory requirements, you should tweak this
- * value.
- */
-#define ZIP_READBUFSIZE (16 * 1024)
-
-
-/*
- * Entries are "unresolved" until they are first opened. At that time,
- * local file headers parsed/validated, data offsets will be updated to look
- * at the actual file data instead of the header, and symlinks will be
- * followed and optimized. This means that we don't seek and read around the
- * archive until forced to do so, and after the first time, we had to do
- * less reading and parsing, which is very CD-ROM friendly.
- */
-typedef enum
-{
- ZIP_UNRESOLVED_FILE,
- ZIP_UNRESOLVED_SYMLINK,
- ZIP_RESOLVING,
- ZIP_RESOLVED,
- ZIP_BROKEN_FILE,
- ZIP_BROKEN_SYMLINK
-} ZipResolveType;
-
-
-/*
- * One ZIPentry is kept for each file in an open ZIP archive.
- */
-typedef struct _ZIPentry
-{
- char *name; /* Name of file in archive */
- struct _ZIPentry *symlink; /* NULL or file we symlink to */
- ZipResolveType resolved; /* Have we resolved file/symlink? */
- PHYSFS_uint32 offset; /* offset of data in archive */
- PHYSFS_uint16 version; /* version made by */
- PHYSFS_uint16 version_needed; /* version needed to extract */
- PHYSFS_uint16 compression_method; /* compression method */
- PHYSFS_uint32 crc; /* crc-32 */
- PHYSFS_uint32 compressed_size; /* compressed size */
- PHYSFS_uint32 uncompressed_size; /* uncompressed size */
- PHYSFS_sint64 last_mod_time; /* last file mod time */
-} ZIPentry;
-
-/*
- * One ZIPinfo is kept for each open ZIP archive.
- */
-typedef struct
-{
- char *archiveName; /* path to ZIP in platform-dependent notation. */
- PHYSFS_uint16 entryCount; /* Number of files in ZIP. */
- ZIPentry *entries; /* info on all files in ZIP. */
-} ZIPinfo;
-
-/*
- * One ZIPfileinfo is kept for each open file in a ZIP archive.
- */
-typedef struct
-{
- ZIPentry *entry; /* Info on file. */
- void *handle; /* physical file handle. */
- PHYSFS_uint32 compressed_position; /* offset in compressed data. */
- PHYSFS_uint32 uncompressed_position; /* tell() position. */
- PHYSFS_uint8 *buffer; /* decompression buffer. */
- z_stream stream; /* zlib stream state. */
-} ZIPfileinfo;
-
-
-/* Magic numbers... */
-#define ZIP_LOCAL_FILE_SIG 0x04034b50
-#define ZIP_CENTRAL_DIR_SIG 0x02014b50
-#define ZIP_END_OF_CENTRAL_DIR_SIG 0x06054b50
-
-/* compression methods... */
-#define COMPMETH_NONE 0
-/* ...and others... */
-
-
-#define UNIX_FILETYPE_MASK 0170000
-#define UNIX_FILETYPE_SYMLINK 0120000
-
-
-/*
- * Bridge physfs allocation functions to zlib's format...
- */
-static voidpf zlibPhysfsAlloc(voidpf opaque, uInt items, uInt size)
-{
- return(((PHYSFS_Allocator *) opaque)->Malloc(items * size));
-} /* zlibPhysfsAlloc */
-
-/*
- * Bridge physfs allocation functions to zlib's format...
- */
-static void zlibPhysfsFree(voidpf opaque, voidpf address)
-{
- ((PHYSFS_Allocator *) opaque)->Free(address);
-} /* zlibPhysfsFree */
-
-
-/*
- * Construct a new z_stream to a sane state.
- */
-static void initializeZStream(z_stream *pstr)
-{
- memset(pstr, '\0', sizeof (z_stream));
- pstr->zalloc = zlibPhysfsAlloc;
- pstr->zfree = zlibPhysfsFree;
- pstr->opaque = &allocator;
-} /* initializeZStream */
-
-
-static const char *zlib_error_string(int rc)
-{
- switch (rc)
- {
- case Z_OK: return(NULL); /* not an error. */
- case Z_STREAM_END: return(NULL); /* not an error. */
-#ifndef _WIN32_WCE
- case Z_ERRNO: return(strerror(errno));
-#endif
- case Z_NEED_DICT: return(ERR_NEED_DICT);
- case Z_DATA_ERROR: return(ERR_DATA_ERROR);
- case Z_MEM_ERROR: return(ERR_MEMORY_ERROR);
- case Z_BUF_ERROR: return(ERR_BUFFER_ERROR);
- case Z_VERSION_ERROR: return(ERR_VERSION_ERROR);
- default: return(ERR_UNKNOWN_ERROR);
- } /* switch */
-
- return(NULL);
-} /* zlib_error_string */
-
-
-/*
- * Wrap all zlib calls in this, so the physfs error state is set appropriately.
- */
-static int zlib_err(int rc)
-{
- const char *str = zlib_error_string(rc);
- if (str != NULL)
- __PHYSFS_setError(str);
- return(rc);
-} /* zlib_err */
-
-
-/*
- * Read an unsigned 32-bit int and swap to native byte order.
- */
-static int readui32(void *in, PHYSFS_uint32 *val)
-{
- PHYSFS_uint32 v;
- BAIL_IF_MACRO(__PHYSFS_platformRead(in, &v, sizeof (v), 1) != 1, NULL, 0);
- *val = PHYSFS_swapULE32(v);
- return(1);
-} /* readui32 */
-
-
-/*
- * Read an unsigned 16-bit int and swap to native byte order.
- */
-static int readui16(void *in, PHYSFS_uint16 *val)
-{
- PHYSFS_uint16 v;
- BAIL_IF_MACRO(__PHYSFS_platformRead(in, &v, sizeof (v), 1) != 1, NULL, 0);
- *val = PHYSFS_swapULE16(v);
- return(1);
-} /* readui16 */
-
-
-static PHYSFS_sint64 ZIP_read(fvoid *opaque, void *buf,
- PHYSFS_uint32 objSize, PHYSFS_uint32 objCount)
-{
- ZIPfileinfo *finfo = (ZIPfileinfo *) opaque;
- ZIPentry *entry = finfo->entry;
- PHYSFS_sint64 retval = 0;
- PHYSFS_sint64 maxread = ((PHYSFS_sint64) objSize) * objCount;
- PHYSFS_sint64 avail = entry->uncompressed_size -
- finfo->uncompressed_position;
-
- BAIL_IF_MACRO(maxread == 0, NULL, 0); /* quick rejection. */
-
- if (avail < maxread)
- {
- maxread = avail - (avail % objSize);
- objCount = (PHYSFS_uint32) (maxread / objSize);
- BAIL_IF_MACRO(objCount == 0, ERR_PAST_EOF, 0); /* quick rejection. */
- __PHYSFS_setError(ERR_PAST_EOF); /* this is always true here. */
- } /* if */
-
- if (entry->compression_method == COMPMETH_NONE)
- {
- retval = __PHYSFS_platformRead(finfo->handle, buf, objSize, objCount);
- } /* if */
-
- else
- {
- finfo->stream.next_out = buf;
- finfo->stream.avail_out = objSize * objCount;
-
- while (retval < maxread)
- {
- PHYSFS_uint32 before = finfo->stream.total_out;
- int rc;
-
- if (finfo->stream.avail_in == 0)
- {
- PHYSFS_sint64 br;
-
- br = entry->compressed_size - finfo->compressed_position;
- if (br > 0)
- {
- if (br > ZIP_READBUFSIZE)
- br = ZIP_READBUFSIZE;
-
- br = __PHYSFS_platformRead(finfo->handle,
- finfo->buffer,
- 1, (PHYSFS_uint32) br);
- if (br <= 0)
- break;
-
- finfo->compressed_position += (PHYSFS_uint32) br;
- finfo->stream.next_in = finfo->buffer;
- finfo->stream.avail_in = (PHYSFS_uint32) br;
- } /* if */
- } /* if */
-
- rc = zlib_err(inflate(&finfo->stream, Z_SYNC_FLUSH));
- retval += (finfo->stream.total_out - before);
-
- if (rc != Z_OK)
- break;
- } /* while */
-
- retval /= objSize;
- } /* else */
-
- if (retval > 0)
- finfo->uncompressed_position += (PHYSFS_uint32) (retval * objSize);
-
- return(retval);
-} /* ZIP_read */
-
-
-static PHYSFS_sint64 ZIP_write(fvoid *opaque, const void *buf,
- PHYSFS_uint32 objSize, PHYSFS_uint32 objCount)
-{
- BAIL_MACRO(ERR_NOT_SUPPORTED, -1);
-} /* ZIP_write */
-
-
-static int ZIP_eof(fvoid *opaque)
-{
- ZIPfileinfo *finfo = (ZIPfileinfo *) opaque;
- return(finfo->uncompressed_position >= finfo->entry->uncompressed_size);
-} /* ZIP_eof */
-
-
-static PHYSFS_sint64 ZIP_tell(fvoid *opaque)
-{
- return(((ZIPfileinfo *) opaque)->uncompressed_position);
-} /* ZIP_tell */
-
-
-static int ZIP_seek(fvoid *opaque, PHYSFS_uint64 offset)
-{
- ZIPfileinfo *finfo = (ZIPfileinfo *) opaque;
- ZIPentry *entry = finfo->entry;
- void *in = finfo->handle;
-
- BAIL_IF_MACRO(offset > entry->uncompressed_size, ERR_PAST_EOF, 0);
-
- if (entry->compression_method == COMPMETH_NONE)
- {
- PHYSFS_sint64 newpos = offset + entry->offset;
- BAIL_IF_MACRO(!__PHYSFS_platformSeek(in, newpos), NULL, 0);
- finfo->uncompressed_position = (PHYSFS_uint32) offset;
- } /* if */
-
- else
- {
- /*
- * If seeking backwards, we need to redecode the file
- * from the start and throw away the compressed bits until we hit
- * the offset we need. If seeking forward, we still need to
- * decode, but we don't rewind first.
- */
- if (offset < finfo->uncompressed_position)
- {
- /* we do a copy so state is sane if inflateInit2() fails. */
- z_stream str;
- initializeZStream(&str);
- if (zlib_err(inflateInit2(&str, -MAX_WBITS)) != Z_OK)
- return(0);
-
- if (!__PHYSFS_platformSeek(in, entry->offset))
- return(0);
-
- inflateEnd(&finfo->stream);
- memcpy(&finfo->stream, &str, sizeof (z_stream));
- finfo->uncompressed_position = finfo->compressed_position = 0;
- } /* if */
-
- while (finfo->uncompressed_position != offset)
- {
- PHYSFS_uint8 buf[512];
- PHYSFS_uint32 maxread;
-
- maxread = (PHYSFS_uint32) (offset - finfo->uncompressed_position);
- if (maxread > sizeof (buf))
- maxread = sizeof (buf);
-
- if (ZIP_read(finfo, buf, maxread, 1) != 1)
- return(0);
- } /* while */
- } /* else */
-
- return(1);
-} /* ZIP_seek */
-
-
-static PHYSFS_sint64 ZIP_fileLength(fvoid *opaque)
-{
- ZIPfileinfo *finfo = (ZIPfileinfo *) opaque;
- return(finfo->entry->uncompressed_size);
-} /* ZIP_fileLength */
-
-
-static int ZIP_fileClose(fvoid *opaque)
-{
- ZIPfileinfo *finfo = (ZIPfileinfo *) opaque;
- BAIL_IF_MACRO(!__PHYSFS_platformClose(finfo->handle), NULL, 0);
-
- if (finfo->entry->compression_method != COMPMETH_NONE)
- inflateEnd(&finfo->stream);
-
- if (finfo->buffer != NULL)
- allocator.Free(finfo->buffer);
-
- allocator.Free(finfo);
- return(1);
-} /* ZIP_fileClose */
-
-
-static PHYSFS_sint64 zip_find_end_of_central_dir(void *in, PHYSFS_sint64 *len)
-{
- PHYSFS_uint8 buf[256];
- PHYSFS_sint32 i = 0;
- PHYSFS_sint64 filelen;
- PHYSFS_sint64 filepos;
- PHYSFS_sint32 maxread;
- PHYSFS_sint32 totalread = 0;
- int found = 0;
- PHYSFS_uint32 extra = 0;
-
- filelen = __PHYSFS_platformFileLength(in);
- BAIL_IF_MACRO(filelen == -1, NULL, 0); /* !!! FIXME: unlocalized string */
- BAIL_IF_MACRO(filelen > 0xFFFFFFFF, "ZIP bigger than 2 gigs?!", 0);
-
- /*
- * Jump to the end of the file and start reading backwards.
- * The last thing in the file is the zipfile comment, which is variable
- * length, and the field that specifies its size is before it in the
- * file (argh!)...this means that we need to scan backwards until we
- * hit the end-of-central-dir signature. We can then sanity check that
- * the comment was as big as it should be to make sure we're in the
- * right place. The comment length field is 16 bits, so we can stop
- * searching for that signature after a little more than 64k at most,
- * and call it a corrupted zipfile.
- */
-
- if (sizeof (buf) < filelen)
- {
- filepos = filelen - sizeof (buf);
- maxread = sizeof (buf);
- } /* if */
- else
- {
- filepos = 0;
- maxread = (PHYSFS_uint32) filelen;
- } /* else */
-
- while ((totalread < filelen) && (totalread < 65557))
- {
- BAIL_IF_MACRO(!__PHYSFS_platformSeek(in, filepos), NULL, -1);
-
- /* make sure we catch a signature between buffers. */
- if (totalread != 0)
- {
- if (__PHYSFS_platformRead(in, buf, maxread - 4, 1) != 1)
- return(-1);
- *((PHYSFS_uint32 *) (&buf[maxread - 4])) = extra;
- totalread += maxread - 4;
- } /* if */
- else
- {
- if (__PHYSFS_platformRead(in, buf, maxread, 1) != 1)
- return(-1);
- totalread += maxread;
- } /* else */
-
- extra = *((PHYSFS_uint32 *) (&buf[0]));
-
- for (i = maxread - 4; i > 0; i--)
- {
- if ((buf[i + 0] == 0x50) &&
- (buf[i + 1] == 0x4B) &&
- (buf[i + 2] == 0x05) &&
- (buf[i + 3] == 0x06) )
- {
- found = 1; /* that's the signature! */
- break;
- } /* if */
- } /* for */
-
- if (found)
- break;
-
- filepos -= (maxread - 4);
- } /* while */
-
- BAIL_IF_MACRO(!found, ERR_NOT_AN_ARCHIVE, -1);
-
- if (len != NULL)
- *len = filelen;
-
- return(filepos + i);
-} /* zip_find_end_of_central_dir */
-
-
-static int ZIP_isArchive(const char *filename, int forWriting)
-{
- PHYSFS_uint32 sig;
- int retval = 0;
- void *in;
-
- in = __PHYSFS_platformOpenRead(filename);
- BAIL_IF_MACRO(in == NULL, NULL, 0);
-
- /*
- * The first thing in a zip file might be the signature of the
- * first local file record, so it makes for a quick determination.
- */
- if (readui32(in, &sig))
- {
- retval = (sig == ZIP_LOCAL_FILE_SIG);
- if (!retval)
- {
- /*
- * No sig...might be a ZIP with data at the start
- * (a self-extracting executable, etc), so we'll have to do
- * it the hard way...
- */
- retval = (zip_find_end_of_central_dir(in, NULL) != -1);
- } /* if */
- } /* if */
-
- __PHYSFS_platformClose(in);
- return(retval);
-} /* ZIP_isArchive */
-
-
-static void zip_free_entries(ZIPentry *entries, PHYSFS_uint32 max)
-{
- PHYSFS_uint32 i;
- for (i = 0; i < max; i++)
- {
- ZIPentry *entry = &entries[i];
- if (entry->name != NULL)
- allocator.Free(entry->name);
- } /* for */
-
- allocator.Free(entries);
-} /* zip_free_entries */
-
-
-/*
- * This will find the ZIPentry associated with a path in platform-independent
- * notation. Directories don't have ZIPentries associated with them, but
- * (*isDir) will be set to non-zero if a dir was hit.
- */
-static ZIPentry *zip_find_entry(ZIPinfo *info, const char *path, int *isDir)
-{
- ZIPentry *a = info->entries;
- PHYSFS_sint32 pathlen = strlen(path);
- PHYSFS_sint32 lo = 0;
- PHYSFS_sint32 hi = (PHYSFS_sint32) (info->entryCount - 1);
- PHYSFS_sint32 middle;
- const char *thispath = NULL;
- int rc;
-
- while (lo <= hi)
- {
- middle = lo + ((hi - lo) / 2);
- thispath = a[middle].name;
- rc = strncmp(path, thispath, pathlen);
-
- if (rc > 0)
- lo = middle + 1;
-
- else if (rc < 0)
- hi = middle - 1;
-
- else /* substring match...might be dir or entry or nothing. */
- {
- if (isDir != NULL)
- {
- *isDir = (thispath[pathlen] == '/');
- if (*isDir)
- return(NULL);
- } /* if */
-
- if (thispath[pathlen] == '\0') /* found entry? */
- return(&a[middle]);
- else
- hi = middle - 1; /* adjust search params, try again. */
- } /* if */
- } /* while */
-
- if (isDir != NULL)
- *isDir = 0;
-
- BAIL_MACRO(ERR_NO_SUCH_FILE, NULL);
-} /* zip_find_entry */
-
-
-/* Convert paths from old, buggy DOS zippers... */
-static void zip_convert_dos_path(ZIPentry *entry, char *path)
-{
- PHYSFS_uint8 hosttype = (PHYSFS_uint8) ((entry->version >> 8) & 0xFF);
- if (hosttype == 0) /* FS_FAT_ */
- {
- while (*path)
- {
- if (*path == '\\')
- *path = '/';
- path++;
- } /* while */
- } /* if */
-} /* zip_convert_dos_path */
-
-
-static void zip_expand_symlink_path(char *path)
-{
- char *ptr = path;
- char *prevptr = path;
-
- while (1)
- {
- ptr = strchr(ptr, '/');
- if (ptr == NULL)
- break;
-
- if (*(ptr + 1) == '.')
- {
- if (*(ptr + 2) == '/')
- {
- /* current dir in middle of string: ditch it. */
- memmove(ptr, ptr + 2, strlen(ptr + 2) + 1);
- } /* else if */
-
- else if (*(ptr + 2) == '\0')
- {
- /* current dir at end of string: ditch it. */
- *ptr = '\0';
- } /* else if */
-
- else if (*(ptr + 2) == '.')
- {
- if (*(ptr + 3) == '/')
- {
- /* parent dir in middle: move back one, if possible. */
- memmove(prevptr, ptr + 4, strlen(ptr + 4) + 1);
- ptr = prevptr;
- while (prevptr != path)
- {
- prevptr--;
- if (*prevptr == '/')
- {
- prevptr++;
- break;
- } /* if */
- } /* while */
- } /* if */
-
- if (*(ptr + 3) == '\0')
- {
- /* parent dir at end: move back one, if possible. */
- *prevptr = '\0';
- } /* if */
- } /* if */
- } /* if */
- else
- {
- prevptr = ptr;
- } /* else */
- } /* while */
-} /* zip_expand_symlink_path */
-
-/* (forward reference: zip_follow_symlink and zip_resolve call each other.) */
-static int zip_resolve(void *in, ZIPinfo *info, ZIPentry *entry);
-
-/*
- * Look for the entry named by (path). If it exists, resolve it, and return
- * a pointer to that entry. If it's another symlink, keep resolving until you
- * hit a real file and then return a pointer to the final non-symlink entry.
- * If there's a problem, return NULL. (path) is always free()'d by this
- * function.
- */
-static ZIPentry *zip_follow_symlink(void *in, ZIPinfo *info, char *path)
-{
- ZIPentry *entry;
-
- zip_expand_symlink_path(path);
- entry = zip_find_entry(info, path, NULL);
- if (entry != NULL)
- {
- if (!zip_resolve(in, info, entry)) /* recursive! */
- entry = NULL;
- else
- {
- if (entry->symlink != NULL)
- entry = entry->symlink;
- } /* else */
- } /* if */
-
- allocator.Free(path);
- return(entry);
-} /* zip_follow_symlink */
-
-
-static int zip_resolve_symlink(void *in, ZIPinfo *info, ZIPentry *entry)
-{
- char *path;
- PHYSFS_uint32 size = entry->uncompressed_size;
- int rc = 0;
-
- /*
- * We've already parsed the local file header of the symlink at this
- * point. Now we need to read the actual link from the file data and
- * follow it.
- */
-
- BAIL_IF_MACRO(!__PHYSFS_platformSeek(in, entry->offset), NULL, 0);
-
- path = (char *) allocator.Malloc(size + 1);
- BAIL_IF_MACRO(path == NULL, ERR_OUT_OF_MEMORY, 0);
-
- if (entry->compression_method == COMPMETH_NONE)
- rc = (__PHYSFS_platformRead(in, path, size, 1) == 1);
-
- else /* symlink target path is compressed... */
- {
- z_stream stream;
- PHYSFS_uint32 complen = entry->compressed_size;
- PHYSFS_uint8 *compressed = (PHYSFS_uint8*) __PHYSFS_smallAlloc(complen);
- if (compressed != NULL)
- {
- if (__PHYSFS_platformRead(in, compressed, complen, 1) == 1)
- {
- initializeZStream(&stream);
- stream.next_in = compressed;
- stream.avail_in = complen;
- stream.next_out = (unsigned char *) path;
- stream.avail_out = size;
- if (zlib_err(inflateInit2(&stream, -MAX_WBITS)) == Z_OK)
- {
- rc = zlib_err(inflate(&stream, Z_FINISH));
- inflateEnd(&stream);
-
- /* both are acceptable outcomes... */
- rc = ((rc == Z_OK) || (rc == Z_STREAM_END));
- } /* if */
- } /* if */
- __PHYSFS_smallFree(compressed);
- } /* if */
- } /* else */
-
- if (!rc)
- allocator.Free(path);
- else
- {
- path[entry->uncompressed_size] = '\0'; /* null-terminate it. */
- zip_convert_dos_path(entry, path);
- entry->symlink = zip_follow_symlink(in, info, path);
- } /* else */
-
- return(entry->symlink != NULL);
-} /* zip_resolve_symlink */
-
-
-/*
- * Parse the local file header of an entry, and update entry->offset.
- */
-static int zip_parse_local(void *in, ZIPentry *entry)
-{
- PHYSFS_uint32 ui32;
- PHYSFS_uint16 ui16;
- PHYSFS_uint16 fnamelen;
- PHYSFS_uint16 extralen;
-
- /*
- * crc and (un)compressed_size are always zero if this is a "JAR"
- * archive created with Sun's Java tools, apparently. We only
- * consider this archive corrupted if those entries don't match and
- * aren't zero. That seems to work well.
- */
-
- BAIL_IF_MACRO(!__PHYSFS_platformSeek(in, entry->offset), NULL, 0);
- BAIL_IF_MACRO(!readui32(in, &ui32), NULL, 0);
- BAIL_IF_MACRO(ui32 != ZIP_LOCAL_FILE_SIG, ERR_CORRUPTED, 0);
- BAIL_IF_MACRO(!readui16(in, &ui16), NULL, 0);
- BAIL_IF_MACRO(ui16 != entry->version_needed, ERR_CORRUPTED, 0);
- BAIL_IF_MACRO(!readui16(in, &ui16), NULL, 0); /* general bits. */
- BAIL_IF_MACRO(!readui16(in, &ui16), NULL, 0);
- BAIL_IF_MACRO(ui16 != entry->compression_method, ERR_CORRUPTED, 0);
- BAIL_IF_MACRO(!readui32(in, &ui32), NULL, 0); /* date/time */
- BAIL_IF_MACRO(!readui32(in, &ui32), NULL, 0);
- BAIL_IF_MACRO(ui32 && (ui32 != entry->crc), ERR_CORRUPTED, 0);
- BAIL_IF_MACRO(!readui32(in, &ui32), NULL, 0);
- BAIL_IF_MACRO(ui32 && (ui32 != entry->compressed_size), ERR_CORRUPTED, 0);
- BAIL_IF_MACRO(!readui32(in, &ui32), NULL, 0);
- BAIL_IF_MACRO(ui32 && (ui32 != entry->uncompressed_size),ERR_CORRUPTED,0);
- BAIL_IF_MACRO(!readui16(in, &fnamelen), NULL, 0);
- BAIL_IF_MACRO(!readui16(in, &extralen), NULL, 0);
-
- entry->offset += fnamelen + extralen + 30;
- return(1);
-} /* zip_parse_local */
-
-
-static int zip_resolve(void *in, ZIPinfo *info, ZIPentry *entry)
-{
- int retval = 1;
- ZipResolveType resolve_type = entry->resolved;
-
- /* Don't bother if we've failed to resolve this entry before. */
- BAIL_IF_MACRO(resolve_type == ZIP_BROKEN_FILE, ERR_CORRUPTED, 0);
- BAIL_IF_MACRO(resolve_type == ZIP_BROKEN_SYMLINK, ERR_CORRUPTED, 0);
-
- /* uhoh...infinite symlink loop! */
- BAIL_IF_MACRO(resolve_type == ZIP_RESOLVING, ERR_SYMLINK_LOOP, 0);
-
- /*
- * We fix up the offset to point to the actual data on the
- * first open, since we don't want to seek across the whole file on
- * archive open (can be SLOW on large, CD-stored files), but we
- * need to check the local file header...not just for corruption,
- * but since it stores offset info the central directory does not.
- */
- if (resolve_type != ZIP_RESOLVED)
- {
- entry->resolved = ZIP_RESOLVING;
-
- retval = zip_parse_local(in, entry);
- if (retval)
- {
- /*
- * If it's a symlink, find the original file. This will cause
- * resolution of other entries (other symlinks and, eventually,
- * the real file) if all goes well.
- */
- if (resolve_type == ZIP_UNRESOLVED_SYMLINK)
- retval = zip_resolve_symlink(in, info, entry);
- } /* if */
-
- if (resolve_type == ZIP_UNRESOLVED_SYMLINK)
- entry->resolved = ((retval) ? ZIP_RESOLVED : ZIP_BROKEN_SYMLINK);
- else if (resolve_type == ZIP_UNRESOLVED_FILE)
- entry->resolved = ((retval) ? ZIP_RESOLVED : ZIP_BROKEN_FILE);
- } /* if */
-
- return(retval);
-} /* zip_resolve */
-
-
-static int zip_version_does_symlinks(PHYSFS_uint32 version)
-{
- int retval = 0;
- PHYSFS_uint8 hosttype = (PHYSFS_uint8) ((version >> 8) & 0xFF);
-
- switch (hosttype)
- {
- /*
- * These are the platforms that can NOT build an archive with
- * symlinks, according to the Info-ZIP project.
- */
- case 0: /* FS_FAT_ */
- case 1: /* AMIGA_ */
- case 2: /* VMS_ */
- case 4: /* VM_CSM_ */
- case 6: /* FS_HPFS_ */
- case 11: /* FS_NTFS_ */
- case 14: /* FS_VFAT_ */
- case 13: /* ACORN_ */
- case 15: /* MVS_ */
- case 18: /* THEOS_ */
- break; /* do nothing. */
-
- default: /* assume the rest to be unix-like. */
- retval = 1;
- break;
- } /* switch */
-
- return(retval);
-} /* zip_version_does_symlinks */
-
-
-static int zip_entry_is_symlink(ZIPentry *entry)
-{
- return((entry->resolved == ZIP_UNRESOLVED_SYMLINK) ||
- (entry->resolved == ZIP_BROKEN_SYMLINK) ||
- (entry->symlink));
-} /* zip_entry_is_symlink */
-
-
-static int zip_has_symlink_attr(ZIPentry *entry, PHYSFS_uint32 extern_attr)
-{
- PHYSFS_uint16 xattr = ((extern_attr >> 16) & 0xFFFF);
-
- return (
- (zip_version_does_symlinks(entry->version)) &&
- (entry->uncompressed_size > 0) &&
- ((xattr & UNIX_FILETYPE_MASK) == UNIX_FILETYPE_SYMLINK)
- );
-} /* zip_has_symlink_attr */
-
-
-static PHYSFS_sint64 zip_dos_time_to_physfs_time(PHYSFS_uint32 dostime)
-{
-#ifdef _WIN32_WCE
- /* We have no struct tm and no mktime right now.
- FIXME: This should probably be fixed at some point.
- */
- return -1;
-#else
- PHYSFS_uint32 dosdate;
- struct tm unixtime;
- memset(&unixtime, '\0', sizeof (unixtime));
-
- dosdate = (PHYSFS_uint32) ((dostime >> 16) & 0xFFFF);
- dostime &= 0xFFFF;
-
- /* dissect date */
- unixtime.tm_year = ((dosdate >> 9) & 0x7F) + 80;
- unixtime.tm_mon = ((dosdate >> 5) & 0x0F) - 1;
- unixtime.tm_mday = ((dosdate ) & 0x1F);
-
- /* dissect time */
- unixtime.tm_hour = ((dostime >> 11) & 0x1F);
- unixtime.tm_min = ((dostime >> 5) & 0x3F);
- unixtime.tm_sec = ((dostime << 1) & 0x3E);
-
- /* let mktime calculate daylight savings time. */
- unixtime.tm_isdst = -1;
-
- return((PHYSFS_sint64) mktime(&unixtime));
-#endif
-} /* zip_dos_time_to_physfs_time */
-
-
-static int zip_load_entry(void *in, ZIPentry *entry, PHYSFS_uint32 ofs_fixup)
-{
- PHYSFS_uint16 fnamelen, extralen, commentlen;
- PHYSFS_uint32 external_attr;
- PHYSFS_uint16 ui16;
- PHYSFS_uint32 ui32;
- PHYSFS_sint64 si64;
-
- /* sanity check with central directory signature... */
- BAIL_IF_MACRO(!readui32(in, &ui32), NULL, 0);
- BAIL_IF_MACRO(ui32 != ZIP_CENTRAL_DIR_SIG, ERR_CORRUPTED, 0);
-
- /* Get the pertinent parts of the record... */
- BAIL_IF_MACRO(!readui16(in, &entry->version), NULL, 0);
- BAIL_IF_MACRO(!readui16(in, &entry->version_needed), NULL, 0);
- BAIL_IF_MACRO(!readui16(in, &ui16), NULL, 0); /* general bits */
- BAIL_IF_MACRO(!readui16(in, &entry->compression_method), NULL, 0);
- BAIL_IF_MACRO(!readui32(in, &ui32), NULL, 0);
- entry->last_mod_time = zip_dos_time_to_physfs_time(ui32);
- BAIL_IF_MACRO(!readui32(in, &entry->crc), NULL, 0);
- BAIL_IF_MACRO(!readui32(in, &entry->compressed_size), NULL, 0);
- BAIL_IF_MACRO(!readui32(in, &entry->uncompressed_size), NULL, 0);
- BAIL_IF_MACRO(!readui16(in, &fnamelen), NULL, 0);
- BAIL_IF_MACRO(!readui16(in, &extralen), NULL, 0);
- BAIL_IF_MACRO(!readui16(in, &commentlen), NULL, 0);
- BAIL_IF_MACRO(!readui16(in, &ui16), NULL, 0); /* disk number start */
- BAIL_IF_MACRO(!readui16(in, &ui16), NULL, 0); /* internal file attribs */
- BAIL_IF_MACRO(!readui32(in, &external_attr), NULL, 0);
- BAIL_IF_MACRO(!readui32(in, &entry->offset), NULL, 0);
- entry->offset += ofs_fixup;
-
- entry->symlink = NULL; /* will be resolved later, if necessary. */
- entry->resolved = (zip_has_symlink_attr(entry, external_attr)) ?
- ZIP_UNRESOLVED_SYMLINK : ZIP_UNRESOLVED_FILE;
-
- entry->name = (char *) allocator.Malloc(fnamelen + 1);
- BAIL_IF_MACRO(entry->name == NULL, ERR_OUT_OF_MEMORY, 0);
- if (__PHYSFS_platformRead(in, entry->name, fnamelen, 1) != 1)
- goto zip_load_entry_puked;
-
- entry->name[fnamelen] = '\0'; /* null-terminate the filename. */
- zip_convert_dos_path(entry, entry->name);
-
- si64 = __PHYSFS_platformTell(in);
- if (si64 == -1)
- goto zip_load_entry_puked;
-
- /* seek to the start of the next entry in the central directory... */
- if (!__PHYSFS_platformSeek(in, si64 + extralen + commentlen))
- goto zip_load_entry_puked;
-
- return(1); /* success. */
-
-zip_load_entry_puked:
- allocator.Free(entry->name);
- return(0); /* failure. */
-} /* zip_load_entry */
-
-
-static int zip_entry_cmp(void *_a, PHYSFS_uint32 one, PHYSFS_uint32 two)
-{
- ZIPentry *a = (ZIPentry *) _a;
- return(strcmp(a[one].name, a[two].name));
-} /* zip_entry_cmp */
-
-
-static void zip_entry_swap(void *_a, PHYSFS_uint32 one, PHYSFS_uint32 two)
-{
- ZIPentry tmp;
- ZIPentry *first = &(((ZIPentry *) _a)[one]);
- ZIPentry *second = &(((ZIPentry *) _a)[two]);
- memcpy(&tmp, first, sizeof (ZIPentry));
- memcpy(first, second, sizeof (ZIPentry));
- memcpy(second, &tmp, sizeof (ZIPentry));
-} /* zip_entry_swap */
-
-
-static int zip_load_entries(void *in, ZIPinfo *info,
- PHYSFS_uint32 data_ofs, PHYSFS_uint32 central_ofs)
-{
- PHYSFS_uint32 max = info->entryCount;
- PHYSFS_uint32 i;
-
- BAIL_IF_MACRO(!__PHYSFS_platformSeek(in, central_ofs), NULL, 0);
-
- info->entries = (ZIPentry *) allocator.Malloc(sizeof (ZIPentry) * max);
- BAIL_IF_MACRO(info->entries == NULL, ERR_OUT_OF_MEMORY, 0);
-
- for (i = 0; i < max; i++)
- {
- if (!zip_load_entry(in, &info->entries[i], data_ofs))
- {
- zip_free_entries(info->entries, i);
- return(0);
- } /* if */
- } /* for */
-
- __PHYSFS_sort(info->entries, max, zip_entry_cmp, zip_entry_swap);
- return(1);
-} /* zip_load_entries */
-
-
-static int zip_parse_end_of_central_dir(void *in, ZIPinfo *info,
- PHYSFS_uint32 *data_start,
- PHYSFS_uint32 *central_dir_ofs)
-{
- PHYSFS_uint32 ui32;
- PHYSFS_uint16 ui16;
- PHYSFS_sint64 len;
- PHYSFS_sint64 pos;
-
- /* find the end-of-central-dir record, and seek to it. */
- pos = zip_find_end_of_central_dir(in, &len);
- BAIL_IF_MACRO(pos == -1, NULL, 0);
- BAIL_IF_MACRO(!__PHYSFS_platformSeek(in, pos), NULL, 0);
-
- /* check signature again, just in case. */
- BAIL_IF_MACRO(!readui32(in, &ui32), NULL, 0);
- BAIL_IF_MACRO(ui32 != ZIP_END_OF_CENTRAL_DIR_SIG, ERR_NOT_AN_ARCHIVE, 0);
-
- /* number of this disk */
- BAIL_IF_MACRO(!readui16(in, &ui16), NULL, 0);
- BAIL_IF_MACRO(ui16 != 0, ERR_UNSUPPORTED_ARCHIVE, 0);
-
- /* number of the disk with the start of the central directory */
- BAIL_IF_MACRO(!readui16(in, &ui16), NULL, 0);
- BAIL_IF_MACRO(ui16 != 0, ERR_UNSUPPORTED_ARCHIVE, 0);
-
- /* total number of entries in the central dir on this disk */
- BAIL_IF_MACRO(!readui16(in, &ui16), NULL, 0);
-
- /* total number of entries in the central dir */
- BAIL_IF_MACRO(!readui16(in, &info->entryCount), NULL, 0);
- BAIL_IF_MACRO(ui16 != info->entryCount, ERR_UNSUPPORTED_ARCHIVE, 0);
-
- /* size of the central directory */
- BAIL_IF_MACRO(!readui32(in, &ui32), NULL, 0);
-
- /* offset of central directory */
- BAIL_IF_MACRO(!readui32(in, central_dir_ofs), NULL, 0);
- BAIL_IF_MACRO(pos < *central_dir_ofs + ui32, ERR_UNSUPPORTED_ARCHIVE, 0);
-
- /*
- * For self-extracting archives, etc, there's crapola in the file
- * before the zipfile records; we calculate how much data there is
- * prepended by determining how far the central directory offset is
- * from where it is supposed to be (start of end-of-central-dir minus
- * sizeof central dir)...the difference in bytes is how much arbitrary
- * data is at the start of the physical file.
- */
- *data_start = (PHYSFS_uint32) (pos - (*central_dir_ofs + ui32));
-
- /* Now that we know the difference, fix up the central dir offset... */
- *central_dir_ofs += *data_start;
-
- /* zipfile comment length */
- BAIL_IF_MACRO(!readui16(in, &ui16), NULL, 0);
-
- /*
- * Make sure that the comment length matches to the end of file...
- * If it doesn't, we're either in the wrong part of the file, or the
- * file is corrupted, but we give up either way.
- */
- BAIL_IF_MACRO((pos + 22 + ui16) != len, ERR_UNSUPPORTED_ARCHIVE, 0);
-
- return(1); /* made it. */
-} /* zip_parse_end_of_central_dir */
-
-
-static ZIPinfo *zip_create_zipinfo(const char *name)
-{
- char *ptr;
- ZIPinfo *info = (ZIPinfo *) allocator.Malloc(sizeof (ZIPinfo));
- BAIL_IF_MACRO(info == NULL, ERR_OUT_OF_MEMORY, 0);
- memset(info, '\0', sizeof (ZIPinfo));
-
- ptr = (char *) allocator.Malloc(strlen(name) + 1);
- if (ptr == NULL)
- {
- allocator.Free(info);
- BAIL_MACRO(ERR_OUT_OF_MEMORY, NULL);
- } /* if */
-
- info->archiveName = ptr;
- strcpy(info->archiveName, name);
- return(info);
-} /* zip_create_zipinfo */
-
-
-static void *ZIP_openArchive(const char *name, int forWriting)
-{
- void *in = NULL;
- ZIPinfo *info = NULL;
- PHYSFS_uint32 data_start;
- PHYSFS_uint32 cent_dir_ofs;
-
- BAIL_IF_MACRO(forWriting, ERR_ARC_IS_READ_ONLY, NULL);
-
- if ((in = __PHYSFS_platformOpenRead(name)) == NULL)
- goto zip_openarchive_failed;
-
- if ((info = zip_create_zipinfo(name)) == NULL)
- goto zip_openarchive_failed;
-
- if (!zip_parse_end_of_central_dir(in, info, &data_start, ¢_dir_ofs))
- goto zip_openarchive_failed;
-
- if (!zip_load_entries(in, info, data_start, cent_dir_ofs))
- goto zip_openarchive_failed;
-
- __PHYSFS_platformClose(in);
- return(info);
-
-zip_openarchive_failed:
- if (info != NULL)
- {
- if (info->archiveName != NULL)
- allocator.Free(info->archiveName);
- allocator.Free(info);
- } /* if */
-
- if (in != NULL)
- __PHYSFS_platformClose(in);
-
- return(NULL);
-} /* ZIP_openArchive */
-
-
-static PHYSFS_sint32 zip_find_start_of_dir(ZIPinfo *info, const char *path,
- int stop_on_first_find)
-{
- PHYSFS_sint32 lo = 0;
- PHYSFS_sint32 hi = (PHYSFS_sint32) (info->entryCount - 1);
- PHYSFS_sint32 middle;
- PHYSFS_uint32 dlen = strlen(path);
- PHYSFS_sint32 retval = -1;
- const char *name;
- int rc;
-
- if (*path == '\0') /* root dir? */
- return(0);
-
- if ((dlen > 0) && (path[dlen - 1] == '/')) /* ignore trailing slash. */
- dlen--;
-
- while (lo <= hi)
- {
- middle = lo + ((hi - lo) / 2);
- name = info->entries[middle].name;
- rc = strncmp(path, name, dlen);
- if (rc == 0)
- {
- char ch = name[dlen];
- if ('/' < ch) /* make sure this isn't just a substr match. */
- rc = -1;
- else if ('/' > ch)
- rc = 1;
- else
- {
- if (stop_on_first_find) /* Just checking dir's existance? */
- return(middle);
-
- if (name[dlen + 1] == '\0') /* Skip initial dir entry. */
- return(middle + 1);
-
- /* there might be more entries earlier in the list. */
- retval = middle;
- hi = middle - 1;
- } /* else */
- } /* if */
-
- if (rc > 0)
- lo = middle + 1;
- else
- hi = middle - 1;
- } /* while */
-
- return(retval);
-} /* zip_find_start_of_dir */
-
-
-/*
- * Moved to seperate function so we can use alloca then immediately throw
- * away the allocated stack space...
- */
-static void doEnumCallback(PHYSFS_EnumFilesCallback cb, void *callbackdata,
- const char *odir, const char *str, PHYSFS_sint32 ln)
-{
- char *newstr = __PHYSFS_smallAlloc(ln + 1);
- if (newstr == NULL)
- return;
-
- memcpy(newstr, str, ln);
- newstr[ln] = '\0';
- cb(callbackdata, odir, newstr);
- __PHYSFS_smallFree(newstr);
-} /* doEnumCallback */
-
-
-static void ZIP_enumerateFiles(dvoid *opaque, const char *dname,
- int omitSymLinks, PHYSFS_EnumFilesCallback cb,
- const char *origdir, void *callbackdata)
-{
- ZIPinfo *info = ((ZIPinfo *) opaque);
- PHYSFS_sint32 dlen, dlen_inc, max, i;
-
- i = zip_find_start_of_dir(info, dname, 0);
- if (i == -1) /* no such directory. */
- return;
-
- dlen = strlen(dname);
- if ((dlen > 0) && (dname[dlen - 1] == '/')) /* ignore trailing slash. */
- dlen--;
-
- dlen_inc = ((dlen > 0) ? 1 : 0) + dlen;
- max = (PHYSFS_sint32) info->entryCount;
- while (i < max)
- {
- char *e = info->entries[i].name;
- if ((dlen) && ((strncmp(e, dname, dlen) != 0) || (e[dlen] != '/')))
- break; /* past end of this dir; we're done. */
-
- if ((omitSymLinks) && (zip_entry_is_symlink(&info->entries[i])))
- i++;
- else
- {
- char *add = e + dlen_inc;
- char *ptr = strchr(add, '/');
- PHYSFS_sint32 ln = (PHYSFS_sint32) ((ptr) ? ptr-add : strlen(add));
- doEnumCallback(cb, callbackdata, origdir, add, ln);
- ln += dlen_inc; /* point past entry to children... */
-
- /* increment counter and skip children of subdirs... */
- while ((++i < max) && (ptr != NULL))
- {
- char *e_new = info->entries[i].name;
- if ((strncmp(e, e_new, ln) != 0) || (e_new[ln] != '/'))
- break;
- } /* while */
- } /* else */
- } /* while */
-} /* ZIP_enumerateFiles */
-
-
-static int ZIP_exists(dvoid *opaque, const char *name)
-{
- int isDir;
- ZIPinfo *info = (ZIPinfo *) opaque;
- ZIPentry *entry = zip_find_entry(info, name, &isDir);
- return((entry != NULL) || (isDir));
-} /* ZIP_exists */
-
-
-static PHYSFS_sint64 ZIP_getLastModTime(dvoid *opaque,
- const char *name,
- int *fileExists)
-{
- int isDir;
- ZIPinfo *info = (ZIPinfo *) opaque;
- ZIPentry *entry = zip_find_entry(info, name, &isDir);
-
- *fileExists = ((isDir) || (entry != NULL));
- if (isDir)
- return(1); /* Best I can do for a dir... */
-
- BAIL_IF_MACRO(entry == NULL, NULL, -1);
- return(entry->last_mod_time);
-} /* ZIP_getLastModTime */
-
-
-static int ZIP_isDirectory(dvoid *opaque, const char *name, int *fileExists)
-{
- ZIPinfo *info = (ZIPinfo *) opaque;
- int isDir;
- ZIPentry *entry = zip_find_entry(info, name, &isDir);
-
- *fileExists = ((isDir) || (entry != NULL));
- if (isDir)
- return(1); /* definitely a dir. */
-
- /* Follow symlinks. This means we might need to resolve entries. */
- BAIL_IF_MACRO(entry == NULL, ERR_NO_SUCH_FILE, 0);
-
- if (entry->resolved == ZIP_UNRESOLVED_SYMLINK) /* gotta resolve it. */
- {
- int rc;
- void *in = __PHYSFS_platformOpenRead(info->archiveName);
- BAIL_IF_MACRO(in == NULL, NULL, 0);
- rc = zip_resolve(in, info, entry);
- __PHYSFS_platformClose(in);
- if (!rc)
- return(0);
- } /* if */
-
- BAIL_IF_MACRO(entry->resolved == ZIP_BROKEN_SYMLINK, NULL, 0);
- BAIL_IF_MACRO(entry->symlink == NULL, ERR_NOT_A_DIR, 0);
-
- return(zip_find_start_of_dir(info, entry->symlink->name, 1) >= 0);
-} /* ZIP_isDirectory */
-
-
-static int ZIP_isSymLink(dvoid *opaque, const char *name, int *fileExists)
-{
- int isDir;
- ZIPentry *entry = zip_find_entry((ZIPinfo *) opaque, name, &isDir);
- *fileExists = ((isDir) || (entry != NULL));
- BAIL_IF_MACRO(entry == NULL, NULL, 0);
- return(zip_entry_is_symlink(entry));
-} /* ZIP_isSymLink */
-
-
-static void *zip_get_file_handle(const char *fn, ZIPinfo *inf, ZIPentry *entry)
-{
- int success;
- void *retval = __PHYSFS_platformOpenRead(fn);
- BAIL_IF_MACRO(retval == NULL, NULL, NULL);
-
- success = zip_resolve(retval, inf, entry);
- if (success)
- {
- PHYSFS_sint64 offset;
- offset = ((entry->symlink) ? entry->symlink->offset : entry->offset);
- success = __PHYSFS_platformSeek(retval, offset);
- } /* if */
-
- if (!success)
- {
- __PHYSFS_platformClose(retval);
- retval = NULL;
- } /* if */
-
- return(retval);
-} /* zip_get_file_handle */
-
-
-static fvoid *ZIP_openRead(dvoid *opaque, const char *fnm, int *fileExists)
-{
- ZIPinfo *info = (ZIPinfo *) opaque;
- ZIPentry *entry = zip_find_entry(info, fnm, NULL);
- ZIPfileinfo *finfo = NULL;
- void *in;
-
- *fileExists = (entry != NULL);
- BAIL_IF_MACRO(entry == NULL, NULL, NULL);
-
- in = zip_get_file_handle(info->archiveName, info, entry);
- BAIL_IF_MACRO(in == NULL, NULL, NULL);
-
- finfo = (ZIPfileinfo *) allocator.Malloc(sizeof (ZIPfileinfo));
- if (finfo == NULL)
- {
- __PHYSFS_platformClose(in);
- BAIL_MACRO(ERR_OUT_OF_MEMORY, NULL);
- } /* if */
-
- memset(finfo, '\0', sizeof (ZIPfileinfo));
- finfo->handle = in;
- finfo->entry = ((entry->symlink != NULL) ? entry->symlink : entry);
- initializeZStream(&finfo->stream);
- if (finfo->entry->compression_method != COMPMETH_NONE)
- {
- if (zlib_err(inflateInit2(&finfo->stream, -MAX_WBITS)) != Z_OK)
- {
- ZIP_fileClose(finfo);
- return(NULL);
- } /* if */
-
- finfo->buffer = (PHYSFS_uint8 *) allocator.Malloc(ZIP_READBUFSIZE);
- if (finfo->buffer == NULL)
- {
- ZIP_fileClose(finfo);
- BAIL_MACRO(ERR_OUT_OF_MEMORY, NULL);
- } /* if */
- } /* if */
-
- return(finfo);
-} /* ZIP_openRead */
-
-
-static fvoid *ZIP_openWrite(dvoid *opaque, const char *filename)
-{
- BAIL_MACRO(ERR_NOT_SUPPORTED, NULL);
-} /* ZIP_openWrite */
-
-
-static fvoid *ZIP_openAppend(dvoid *opaque, const char *filename)
-{
- BAIL_MACRO(ERR_NOT_SUPPORTED, NULL);
-} /* ZIP_openAppend */
-
-
-static void ZIP_dirClose(dvoid *opaque)
-{
- ZIPinfo *zi = (ZIPinfo *) (opaque);
- zip_free_entries(zi->entries, zi->entryCount);
- allocator.Free(zi->archiveName);
- allocator.Free(zi);
-} /* ZIP_dirClose */
-
-
-static int ZIP_remove(dvoid *opaque, const char *name)
-{
- BAIL_MACRO(ERR_NOT_SUPPORTED, 0);
-} /* ZIP_remove */
-
-
-static int ZIP_mkdir(dvoid *opaque, const char *name)
-{
- BAIL_MACRO(ERR_NOT_SUPPORTED, 0);
-} /* ZIP_mkdir */
-
-
-const PHYSFS_ArchiveInfo __PHYSFS_ArchiveInfo_ZIP =
-{
- "ZIP",
- ZIP_ARCHIVE_DESCRIPTION,
- "Ryan C. Gordon <icculus@icculus.org>",
- "http://icculus.org/physfs/",
-};
-
-
-const PHYSFS_Archiver __PHYSFS_Archiver_ZIP =
-{
- &__PHYSFS_ArchiveInfo_ZIP,
- ZIP_isArchive, /* isArchive() method */
- ZIP_openArchive, /* openArchive() method */
- ZIP_enumerateFiles, /* enumerateFiles() method */
- ZIP_exists, /* exists() method */
- ZIP_isDirectory, /* isDirectory() method */
- ZIP_isSymLink, /* isSymLink() method */
- ZIP_getLastModTime, /* getLastModTime() method */
- ZIP_openRead, /* openRead() method */
- ZIP_openWrite, /* openWrite() method */
- ZIP_openAppend, /* openAppend() method */
- ZIP_remove, /* remove() method */
- ZIP_mkdir, /* mkdir() method */
- ZIP_dirClose, /* dirClose() method */
- ZIP_read, /* read() method */
- ZIP_write, /* write() method */
- ZIP_eof, /* eof() method */
- ZIP_tell, /* tell() method */
- ZIP_seek, /* seek() method */
- ZIP_fileLength, /* fileLength() method */
- ZIP_fileClose /* fileClose() method */
-};
-
-#endif /* defined PHYSFS_SUPPORTS_ZIP */
-
-/* end of zip.c ... */
-
+++ /dev/null
-using System.Reflection;
-using System.Runtime.CompilerServices;
-
-//
-// General Information about an assembly is controlled through the following
-// set of attributes. Change these attribute values to modify the information
-// associated with an assembly.
-//
-[assembly: AssemblyTitle("PhysFS.NET")]
-[assembly: AssemblyDescription("PhysFS Bindings for .NET")]
-[assembly: AssemblyConfiguration("")]
-[assembly: AssemblyCompany("")]
-[assembly: AssemblyProduct("PhysFS.NET")]
-[assembly: AssemblyCopyright("(c)2003 Gregory S. Read")]
-[assembly: AssemblyTrademark("")]
-[assembly: AssemblyCulture("")]
-
-//
-// Version information for an assembly consists of the following four values:
-//
-// Major Version
-// Minor Version
-// Build Number
-// Revision
-//
-// You can specify all the values or you can default the Revision and Build Numbers
-// by using the '*' as shown below:
-
-[assembly: AssemblyVersion("1.0.*")]
-
-//
-// In order to sign your assembly you must specify a key to use. Refer to the
-// Microsoft .NET Framework documentation for more information on assembly signing.
-//
-// Use the attributes below to control which key is used for signing.
-//
-// Notes:
-// (*) If no key is specified, the assembly is not signed.
-// (*) KeyName refers to a key that has been installed in the Crypto Service
-// Provider (CSP) on your machine. KeyFile refers to a file which contains
-// a key.
-// (*) If the KeyFile and the KeyName values are both specified, the
-// following processing occurs:
-// (1) If the KeyName can be found in the CSP, that key is used.
-// (2) If the KeyName does not exist and the KeyFile does exist, the key
-// in the KeyFile is installed into the CSP and used.
-// (*) In order to create a KeyFile, you can use the sn.exe (Strong Name) utility.
-// When specifying the KeyFile, the location of the KeyFile should be
-// relative to the project output directory which is
-// %Project Directory%\obj\<configuration>. For example, if your KeyFile is
-// located in the project directory, you would specify the AssemblyKeyFile
-// attribute as [assembly: AssemblyKeyFile("..\\..\\mykey.snk")]
-// (*) Delay Signing is an advanced option - see the Microsoft .NET Framework
-// documentation for more information on this.
-//
-[assembly: AssemblyDelaySign(false)]
-[assembly: AssemblyKeyFile("")]
-[assembly: AssemblyKeyName("")]
+++ /dev/null
-<VisualStudioProject>
- <CSHARP
- ProjectType = "Local"
- ProductVersion = "7.0.9466"
- SchemaVersion = "1.0"
- ProjectGuid = "{C6205A43-3D4D-41E6-872C-96CD7BE55230}"
- >
- <Build>
- <Settings
- ApplicationIcon = ""
- AssemblyKeyContainerName = ""
- AssemblyName = "PhysFS.NET"
- AssemblyOriginatorKeyFile = ""
- DefaultClientScript = "JScript"
- DefaultHTMLPageLayout = "Grid"
- DefaultTargetSchema = "IE50"
- DelaySign = "false"
- OutputType = "Library"
- RootNamespace = "PhysFS.NET"
- StartupObject = ""
- >
- <Config
- Name = "Debug"
- AllowUnsafeBlocks = "true"
- BaseAddress = "285212672"
- CheckForOverflowUnderflow = "false"
- ConfigurationOverrideFile = ""
- DefineConstants = "DEBUG;TRACE"
- DocumentationFile = ""
- DebugSymbols = "true"
- FileAlignment = "4096"
- IncrementalBuild = "true"
- Optimize = "false"
- OutputPath = "bin\Debug\"
- RegisterForComInterop = "false"
- RemoveIntegerChecks = "false"
- TreatWarningsAsErrors = "false"
- WarningLevel = "4"
- />
- <Config
- Name = "Release"
- AllowUnsafeBlocks = "true"
- BaseAddress = "285212672"
- CheckForOverflowUnderflow = "false"
- ConfigurationOverrideFile = ""
- DefineConstants = "TRACE"
- DocumentationFile = ""
- DebugSymbols = "false"
- FileAlignment = "4096"
- IncrementalBuild = "false"
- Optimize = "true"
- OutputPath = "bin\Release\"
- RegisterForComInterop = "false"
- RemoveIntegerChecks = "false"
- TreatWarningsAsErrors = "false"
- WarningLevel = "4"
- />
- </Settings>
- <References>
- <Reference
- Name = "System"
- AssemblyName = "System"
- HintPath = "C:\WINDOWS\Microsoft.NET\Framework\v1.0.3705\System.dll"
- />
- <Reference
- Name = "System.Data"
- AssemblyName = "System.Data"
- HintPath = "C:\WINDOWS\Microsoft.NET\Framework\v1.0.3705\System.Data.dll"
- />
- <Reference
- Name = "System.XML"
- AssemblyName = "System.Xml"
- HintPath = "C:\WINDOWS\Microsoft.NET\Framework\v1.0.3705\System.XML.dll"
- />
- <Reference
- Name = "System.Drawing"
- AssemblyName = "System.Drawing"
- HintPath = "C:\WINDOWS\Microsoft.NET\Framework\v1.0.3705\System.Drawing.dll"
- />
- <Reference
- Name = "System.Windows.Forms"
- AssemblyName = "System.Windows.Forms"
- HintPath = "C:\WINDOWS\Microsoft.NET\Framework\v1.0.3705\System.Windows.Forms.dll"
- />
- </References>
- </Build>
- <Files>
- <Include>
- <File
- RelPath = "AssemblyInfo.cs"
- SubType = "Code"
- BuildAction = "Compile"
- />
- <File
- RelPath = "PhysFS.cs"
- SubType = "Code"
- BuildAction = "Compile"
- />
- <File
- RelPath = "PhysFS_DLL.cs"
- SubType = "Code"
- BuildAction = "Compile"
- />
- <File
- RelPath = "PhysFSFileStream.cs"
- SubType = "Code"
- BuildAction = "Compile"
- />
- </Include>
- </Files>
- </CSHARP>
-</VisualStudioProject>
-
+++ /dev/null
-Microsoft Visual Studio Solution File, Format Version 7.00
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PhysFS.NET", "PhysFS.NET.csproj", "{C6205A43-3D4D-41E6-872C-96CD7BE55230}"
-EndProject
-Global
- GlobalSection(SolutionConfiguration) = preSolution
- ConfigName.0 = Debug
- ConfigName.1 = Release
- EndGlobalSection
- GlobalSection(ProjectDependencies) = postSolution
- EndGlobalSection
- GlobalSection(ProjectConfiguration) = postSolution
- {C6205A43-3D4D-41E6-872C-96CD7BE55230}.Debug.ActiveCfg = Debug|.NET
- {C6205A43-3D4D-41E6-872C-96CD7BE55230}.Debug.Build.0 = Debug|.NET
- {C6205A43-3D4D-41E6-872C-96CD7BE55230}.Release.ActiveCfg = Release|.NET
- {C6205A43-3D4D-41E6-872C-96CD7BE55230}.Release.Build.0 = Release|.NET
- EndGlobalSection
- GlobalSection(ExtensibilityGlobals) = postSolution
- EndGlobalSection
- GlobalSection(ExtensibilityAddIns) = postSolution
- EndGlobalSection
-EndGlobal
+++ /dev/null
-/* PhysFS.cs - (c)2003 Gregory S. Read
- * Provides access to PhysFS API calls not specific to file handle access.
- */
-using System;
-
-namespace PhysFS_NET
-{
- public class PhysFS
- {
- /* Initialize
- * Inits the PhysFS API. This normally does not need to be called unless
- * the API has been manually deinitialized since the PhysFS_DLL class
- * initializes just before the first call is made into the DLL.
- * Parameters
- * none
- * Returns
- * none
- * Exceptions
- * PhysFSException - An error occured in the PhysFS API
- */
- public static void Initialize()
- {
- // Initialize the physfs library, raise an exception if error
- if(PhysFS_DLL.PHYSFS_init("") == 0)
- throw new PhysFSException();
- }
-
- /* Deinitialize
- * Deinits the PhysFS API. It is recommended that this method be called
- * by the application before exiting in order to gracefully deallocate
- * resources and close all filehandles, etc.
- * Parameters
- * none
- * Returns
- * none
- * Exceptions
- * PhysFSException - An error occured in the PhysFS API
- */
- public static void Deinitialize()
- {
- // Deinit, raise an exception if an error occured
- if(PhysFS_DLL.PHYSFS_deinit() == 0)
- throw new PhysFSException();
- }
-
- /* BaseDir
- * Gets the base directory configured for PhysFS. See the PhysFS API
- * documentation for more information.
- * Parameters
- * none
- * Returns
- * A string value representing the Base Directory
- * Exceptions
- * none
- */
- public static string BaseDir
- {
- get
- {
- // Return the current base directory
- return PhysFS_DLL.PHYSFS_getBaseDir();
- }
- }
-
- /* WriteDir
- * Gets or sets the write directory configured for PhysFS. See the PhysFS API
- * documentation for more information.
- * Parameters
- * set - Path to set the WriteDir property to
- * Returns
- * A string value representing the Write Directory
- * Exceptions
- * PhysFSException - An error occured in the PhysFS API when
- * settings the write directory.
- */
- public static string WriteDir
- {
- get
- {
- // Return the current write directory
- return PhysFS_DLL.PHYSFS_getWriteDir();
- }
- set
- {
- // Set the write directory and raise an exception if an error occured
- if(PhysFS_DLL.PHYSFS_setWriteDir(value) == 0)
- throw new PhysFSException();
- }
- }
-
- /* UserDir
- * Gets or sets the write directory configured for PhysFS. See the PhysFS API
- * documentation for more information.
- * Parameters
- * set - Path to set the WriteDir property to
- * Returns
- * A string value representing the Write Directory
- * Exceptions
- * PhysFSException - An error occured in the PhysFS API when
- * settings the write directory.
- */
- public static string UserDir
- {
- get
- {
- // Return the current user directory
- return PhysFS_DLL.PHYSFS_getUserDir();
- }
- }
- public static void AddToSearchPath(string NewDir, bool Append)
- {
- if(PhysFS_DLL.PHYSFS_addToSearchPath(NewDir, Append?1:0) == 0)
- throw new PhysFSException();
- }
- public static void RemoveFromSearchPath(string OldDir)
- {
- if(PhysFS_DLL.PHYSFS_removeFromSearchPath(OldDir) == 0)
- throw new PhysFSException();
- }
- public unsafe static string[] GetSearchPath()
- {
- byte** p; // Searchpath list from PhysFS dll
- string[] pathlist; // List converted to an array
-
- // Get the CDROM drive listing
- p = PhysFS_DLL.PHYSFS_getSearchPath();
- // Convert the C-style array to a .NET style array
- pathlist = PhysFS_DLL.BytePPToArray(p);
- // Free the original list since we're done with it
- PhysFS_DLL.PHYSFS_freeList(p);
-
- return pathlist;
- }
- public unsafe static string[] GetCDROMDrives()
- {
- byte** p; // CDROM list from PhysFS dll
- string[] cdromlist; // List converted to an array
-
- // Get the CDROM drive listing
- p = PhysFS_DLL.PHYSFS_getCdRomDirs();
- // Convert the C-style array to a .NET style array
- cdromlist = PhysFS_DLL.BytePPToArray(p);
- // Free the original list since we're done with it
- PhysFS_DLL.PHYSFS_freeList(p);
-
- return cdromlist;
- }
- public static void MkDir(string Dirname)
- {
- if(PhysFS_DLL.PHYSFS_mkdir(Dirname) == 0)
- throw new PhysFSException();
- }
- public static void Delete(string Filename)
- {
- if(PhysFS_DLL.PHYSFS_delete(Filename) == 0)
- throw new PhysFSException();
- }
- public static string GetRealDir(string Filename)
- {
- string RetValue;
-
- RetValue = PhysFS_DLL.PHYSFS_getRealDir(Filename);
- if(RetValue == null)
- throw new PhysFSException("File not found in search path.");
-
- // Return the real file path of the specified filename
- return RetValue;
- }
- public unsafe static string[] EnumerateFiles(string Dirname)
- {
- byte** p; // File list from PhysFS dll
- string[] filelist; // List converted to an array
-
- // Get the CDROM drive listing
- p = PhysFS_DLL.PHYSFS_enumerateFiles(Dirname);
- // Convert the C-style array to a .NET style array
- filelist = PhysFS_DLL.BytePPToArray(p);
- // Free the original list since we're done with it
- PhysFS_DLL.PHYSFS_freeList(p);
-
- return filelist;
- }
- public static bool IsDirectory(string Filename)
- {
- // Return true if non-zero, otherwise return false
- return (PhysFS_DLL.PHYSFS_isDirectory(Filename) == 0)?false:true;
- }
- }
-}
+++ /dev/null
-/* PhysFSFileStream.cs - (c)2003 Gregory S. Read */
-using System;
-using System.Collections;
-using System.IO;
-
-namespace PhysFS_NET
-{
- public enum PhysFSFileMode {Read, Write, Append};
-
- // Our exception class we'll use for throwing all PhysFS API related exception
- public class PhysFSException : IOException
- {
- public PhysFSException(string Message) : base(Message) {}
- public PhysFSException() : base(PhysFS_DLL.PHYSFS_getLastError()) {}
- }
-
- public unsafe class PhysFSFileStream : Stream
- {
- // ***Public properties***
- public override bool CanRead
- {
- get
- {
- // Reading is supported
- return true;
- }
- }
-
- public override bool CanSeek
- {
- get
- {
- // Seek is supported
- return true;
- }
- }
-
- public override bool CanWrite
- {
- get
- {
- // Writing is supported
- return true;
- }
- }
-
- public override long Length
- {
- get
- {
- long TempLength;
- TempLength = PhysFS_DLL.PHYSFS_fileLength(pHandle);
-
- // If call returned an error, throw an exception
- if(TempLength == -1)
- throw new PhysFSException();
-
- return TempLength;
- }
- }
-
- public override long Position
- {
- get
- {
- long TempPosition;
- TempPosition = PhysFS_DLL.PHYSFS_tell(pHandle);
-
- // If call returned an error, throw an exception
- if(TempPosition == -1)
- throw new PhysFSException();
-
- return TempPosition;
- }
- set
- {
- // Seek from beginning of file using the position value
- Seek(value, SeekOrigin.Begin);
- }
- }
-
- // ***Public methods***
- public PhysFSFileStream(string FileName, PhysFSFileMode FileMode, ulong BufferSize)
- {
- // Open the specified file with the appropriate file access
- switch(FileMode)
- {
- case PhysFSFileMode.Read:
- pHandle = PhysFS_DLL.PHYSFS_openRead(FileName);
- break;
- case PhysFSFileMode.Write:
- pHandle = PhysFS_DLL.PHYSFS_openWrite(FileName);
- break;
- case PhysFSFileMode.Append:
- pHandle = PhysFS_DLL.PHYSFS_openAppend(FileName);
- break;
- default:
- throw new PhysFSException("Invalid FileMode specified");
- }
-
- // If handle is null, an error occured, so raise an exception
- //!!! Does object get created if exception is thrown?
- if(pHandle == null)
- throw new PhysFSException();
-
- // Set buffer size, raise an exception if an error occured
- if(PhysFS_DLL.PHYSFS_setBuffer(pHandle, BufferSize) == 0)
- throw new PhysFSException();
- }
-
- // This constructor sets the buffer size to 0 if not specified
- public PhysFSFileStream(string FileName, PhysFSFileMode FileMode) : this(FileName, FileMode, 0) {}
-
- ~PhysFSFileStream()
- {
- // Don't close the handle if they've specifically closed it already
- if(!Closed)
- Close();
- }
-
- public override void Flush()
- {
- if(PhysFS_DLL.PHYSFS_flush(pHandle) == 0)
- throw new PhysFSException();
- }
-
- public override int Read(byte[] buffer, int offset, int count)
- {
- long RetValue;
-
- fixed(byte *pbytes = &buffer[offset])
- {
- // Read into our allocated pointer
- RetValue = PhysFS_DLL.PHYSFS_read(pHandle, pbytes, sizeof(byte), (uint)count);
- }
-
- if(RetValue == -1)
- throw new PhysFSException();
-
- // Return number of bytes read
- // Note: This cast should be safe since we are only reading 'count' items, which
- // is of type 'int'.
- return (int)RetValue;
- }
-
- public override void Write(byte[] buffer, int offset, int count)
- {
- long RetValue;
-
- fixed(byte* pbytes = &buffer[offset])
- {
- // Write buffer
- RetValue = PhysFS_DLL.PHYSFS_write(pHandle, pbytes, sizeof(byte), (uint)count);
- }
-
- if(RetValue == -1)
- throw new PhysFSException();
- }
-
- public override long Seek(long offset, SeekOrigin origin)
- {
- // Only seeking from beginning is supported by PhysFS API
- if(origin != SeekOrigin.Begin)
- throw new PhysFSException("Only seek origin of \"Begin\" is supported");
-
- // Seek to specified offset, raise an exception if error occured
- if(PhysFS_DLL.PHYSFS_seek(pHandle, (ulong)offset) == 0)
- throw new PhysFSException();
-
- // Since we always seek from beginning, the offset is always
- // the absolute position.
- return offset;
- }
-
- public override void SetLength(long value)
- {
- throw new NotSupportedException("SetLength method not supported in PhysFSFileStream objects.");
- }
-
- public override void Close()
- {
- // Close the handle
- if(PhysFS_DLL.PHYSFS_close(pHandle) == 0)
- throw new PhysFSException();
-
- // File has been closed. Rock.
- Closed = true;
- }
-
- // ***Private variables***
- private void *pHandle;
- private bool Closed = false;
- }
-}
\ No newline at end of file
+++ /dev/null
-/* PhysFS_DLL - (c)2003 Gregory S. Read
- * Internal class that provides direct access to the PhysFS DLL. It is
- * not accessible outside of the PhysFS.NET assembly.
- */
-using System.Collections;
-using System.Runtime.InteropServices;
-
-namespace PhysFS_NET
-{
- internal class PhysFS_DLL
- {
- /* Static constructor
- * Initializes the PhysFS API before any method is called in this class. This
- * relieves the user from having to explicitly initialize the API.
- * Parameters
- * none
- * Returns
- * none
- * Exceptions
- * PhysFSException - An error occured in the PhysFS API
- */
- static PhysFS_DLL()
- {
- if(PHYSFS_init("") == 0)
- throw new PhysFSException();
- }
-
- /* BytePPToArray
- * Converts a C-style string array into a .NET managed string array
- * Parameters
- * C-style string array pointer returned from PhysFS
- * Returns
- * .NET managed string array
- * Exceptions
- * none
- */
- public unsafe static string[] BytePPToArray(byte **bytearray)
- {
- byte** ptr;
- byte* c;
- string tempstr;
- ArrayList MyArrayList = new ArrayList();
- string[] RetArray;
-
- for(ptr = bytearray; *ptr != null; ptr++)
- {
- tempstr = "";
- for(c = *ptr; *c != 0; c++)
- {
- tempstr += (char)*c;
- }
-
- // Add string to our list
- MyArrayList.Add(tempstr);
- }
-
- // Return a normal array of the list
- RetArray = new string[MyArrayList.Count];
- MyArrayList.CopyTo(RetArray, 0);
- return RetArray;
- }
-
- // Name of DLL to import
- private const string PHYSFS_DLLNAME = "physfs.dll";
-
- // DLL import declarations
- [DllImport(PHYSFS_DLLNAME)] public static extern int PHYSFS_init(string argv0);
- [DllImport(PHYSFS_DLLNAME)] public static extern int PHYSFS_deinit();
- [DllImport(PHYSFS_DLLNAME)] public static extern unsafe void PHYSFS_freeList(void *listVar);
- [DllImport(PHYSFS_DLLNAME)] public static extern string PHYSFS_getLastError();
- [DllImport(PHYSFS_DLLNAME)] public static extern string PHYSFS_getDirSeparator();
- [DllImport(PHYSFS_DLLNAME)] public static extern void PHYSFS_permitSymbolicLinks(int allow);
- [DllImport(PHYSFS_DLLNAME)] public static extern unsafe byte** PHYSFS_getCdRomDirs();
- [DllImport(PHYSFS_DLLNAME)] public static extern string PHYSFS_getBaseDir();
- [DllImport(PHYSFS_DLLNAME)] public static extern string PHYSFS_getUserDir();
- [DllImport(PHYSFS_DLLNAME)] public static extern string PHYSFS_getWriteDir();
- [DllImport(PHYSFS_DLLNAME)] public static extern int PHYSFS_setWriteDir(string newDir);
- [DllImport(PHYSFS_DLLNAME)] public static extern int PHYSFS_addToSearchPath(string newDir, int appendToPath);
- [DllImport(PHYSFS_DLLNAME)] public static extern int PHYSFS_removeFromSearchPath(string oldDir);
- [DllImport(PHYSFS_DLLNAME)] public static extern unsafe byte** PHYSFS_getSearchPath();
- [DllImport(PHYSFS_DLLNAME)] public static extern int PHYSFS_setSaneConfig(string organization,
- string appName,
- string archiveExt,
- int includeCdRoms,
- int archivesFirst);
- [DllImport(PHYSFS_DLLNAME)] public static extern int PHYSFS_mkdir(string dirName);
- [DllImport(PHYSFS_DLLNAME)] public static extern int PHYSFS_delete(string filename);
- [DllImport(PHYSFS_DLLNAME)] public static extern string PHYSFS_getRealDir(string filename);
- [DllImport(PHYSFS_DLLNAME)] public static extern unsafe byte** PHYSFS_enumerateFiles(string dir);
- [DllImport(PHYSFS_DLLNAME)] public static extern int PHYSFS_exists(string fname);
- [DllImport(PHYSFS_DLLNAME)] public static extern int PHYSFS_isDirectory(string fname);
- [DllImport(PHYSFS_DLLNAME)] public static extern int PHYSFS_isSymbolicLink(string fname);
- [DllImport(PHYSFS_DLLNAME)] public static extern unsafe void* PHYSFS_openWrite(string filename);
- [DllImport(PHYSFS_DLLNAME)] public static extern unsafe void* PHYSFS_openAppend(string filename);
- [DllImport(PHYSFS_DLLNAME)] public static extern unsafe void* PHYSFS_openRead(string filename);
- [DllImport(PHYSFS_DLLNAME)] public static extern unsafe int PHYSFS_close(void* handle);
- [DllImport(PHYSFS_DLLNAME)] public static extern unsafe long PHYSFS_getLastModTime(string filename);
- [DllImport(PHYSFS_DLLNAME)] public static extern unsafe long PHYSFS_read(void* handle,
- void *buffer,
- uint objSize,
- uint objCount);
- [DllImport(PHYSFS_DLLNAME)] public static extern unsafe long PHYSFS_write(void* handle,
- void *buffer,
- uint objSize,
- uint objCount);
- [DllImport(PHYSFS_DLLNAME)] public static extern unsafe int PHYSFS_eof(void* handle);
- [DllImport(PHYSFS_DLLNAME)] public static extern unsafe long PHYSFS_tell(void* handle);
- [DllImport(PHYSFS_DLLNAME)] public static extern unsafe int PHYSFS_seek(void* handle, ulong pos);
- [DllImport(PHYSFS_DLLNAME)] public static extern unsafe long PHYSFS_fileLength(void* handle);
- [DllImport(PHYSFS_DLLNAME)] public static extern unsafe int PHYSFS_setBuffer(void* handle, ulong bufsize);
- [DllImport(PHYSFS_DLLNAME)] public static extern unsafe int PHYSFS_flush(void* handle);
- }
-}
+++ /dev/null
-PhysFS.NET is a library that encapsulates the PhysFS API into a .NET assembly.
-
-There are two class objects that are exposed in the assembly:
- PhysFS.cs
- This class exposes any non-filehandle specific functionality contained in
- the PhysFS library.
- PhysFSFileStream.cs
- A System.IO.Stream derived class which provides file access via the
- PhysFS API. Usage of this object is identical to a standard stream
- object.
\ No newline at end of file
+++ /dev/null
-using System.Reflection;
-using System.Runtime.CompilerServices;
-
-//
-// General Information about an assembly is controlled through the following
-// set of attributes. Change these attribute values to modify the information
-// associated with an assembly.
-//
-[assembly: AssemblyTitle("")]
-[assembly: AssemblyDescription("")]
-[assembly: AssemblyConfiguration("")]
-[assembly: AssemblyCompany("")]
-[assembly: AssemblyProduct("")]
-[assembly: AssemblyCopyright("")]
-[assembly: AssemblyTrademark("")]
-[assembly: AssemblyCulture("")]
-
-//
-// Version information for an assembly consists of the following four values:
-//
-// Major Version
-// Minor Version
-// Build Number
-// Revision
-//
-// You can specify all the values or you can default the Revision and Build Numbers
-// by using the '*' as shown below:
-
-[assembly: AssemblyVersion("1.0.*")]
-
-//
-// In order to sign your assembly you must specify a key to use. Refer to the
-// Microsoft .NET Framework documentation for more information on assembly signing.
-//
-// Use the attributes below to control which key is used for signing.
-//
-// Notes:
-// (*) If no key is specified, the assembly is not signed.
-// (*) KeyName refers to a key that has been installed in the Crypto Service
-// Provider (CSP) on your machine. KeyFile refers to a file which contains
-// a key.
-// (*) If the KeyFile and the KeyName values are both specified, the
-// following processing occurs:
-// (1) If the KeyName can be found in the CSP, that key is used.
-// (2) If the KeyName does not exist and the KeyFile does exist, the key
-// in the KeyFile is installed into the CSP and used.
-// (*) In order to create a KeyFile, you can use the sn.exe (Strong Name) utility.
-// When specifying the KeyFile, the location of the KeyFile should be
-// relative to the project output directory which is
-// %Project Directory%\obj\<configuration>. For example, if your KeyFile is
-// located in the project directory, you would specify the AssemblyKeyFile
-// attribute as [assembly: AssemblyKeyFile("..\\..\\mykey.snk")]
-// (*) Delay Signing is an advanced option - see the Microsoft .NET Framework
-// documentation for more information on this.
-//
-[assembly: AssemblyDelaySign(false)]
-[assembly: AssemblyKeyFile("")]
-[assembly: AssemblyKeyName("")]
+++ /dev/null
-<VisualStudioProject>
- <CSHARP
- ProjectType = "Local"
- ProductVersion = "7.0.9466"
- SchemaVersion = "1.0"
- ProjectGuid = "{9C1ECC6B-16C7-42B3-BF7C-8BA8D81BA980}"
- >
- <Build>
- <Settings
- ApplicationIcon = "App.ico"
- AssemblyKeyContainerName = ""
- AssemblyName = "TestApp"
- AssemblyOriginatorKeyFile = ""
- DefaultClientScript = "JScript"
- DefaultHTMLPageLayout = "Grid"
- DefaultTargetSchema = "IE50"
- DelaySign = "false"
- OutputType = "WinExe"
- RootNamespace = "TestApp"
- StartupObject = ""
- >
- <Config
- Name = "Debug"
- AllowUnsafeBlocks = "false"
- BaseAddress = "285212672"
- CheckForOverflowUnderflow = "false"
- ConfigurationOverrideFile = ""
- DefineConstants = "DEBUG;TRACE"
- DocumentationFile = ""
- DebugSymbols = "true"
- FileAlignment = "4096"
- IncrementalBuild = "true"
- Optimize = "false"
- OutputPath = "bin\Debug\"
- RegisterForComInterop = "false"
- RemoveIntegerChecks = "false"
- TreatWarningsAsErrors = "false"
- WarningLevel = "4"
- />
- <Config
- Name = "Release"
- AllowUnsafeBlocks = "false"
- BaseAddress = "285212672"
- CheckForOverflowUnderflow = "false"
- ConfigurationOverrideFile = ""
- DefineConstants = "TRACE"
- DocumentationFile = ""
- DebugSymbols = "false"
- FileAlignment = "4096"
- IncrementalBuild = "false"
- Optimize = "true"
- OutputPath = "bin\Release\"
- RegisterForComInterop = "false"
- RemoveIntegerChecks = "false"
- TreatWarningsAsErrors = "false"
- WarningLevel = "4"
- />
- </Settings>
- <References>
- <Reference
- Name = "System"
- AssemblyName = "System"
- HintPath = "C:\WINDOWS\Microsoft.NET\Framework\v1.0.3705\System.dll"
- />
- <Reference
- Name = "System.Data"
- AssemblyName = "System.Data"
- HintPath = "C:\WINDOWS\Microsoft.NET\Framework\v1.0.3705\System.Data.dll"
- />
- <Reference
- Name = "System.Drawing"
- AssemblyName = "System.Drawing"
- HintPath = "C:\WINDOWS\Microsoft.NET\Framework\v1.0.3705\System.Drawing.dll"
- />
- <Reference
- Name = "System.Windows.Forms"
- AssemblyName = "System.Windows.Forms"
- HintPath = "C:\WINDOWS\Microsoft.NET\Framework\v1.0.3705\System.Windows.Forms.dll"
- />
- <Reference
- Name = "System.XML"
- AssemblyName = "System.Xml"
- HintPath = "C:\WINDOWS\Microsoft.NET\Framework\v1.0.3705\System.XML.dll"
- />
- <Reference
- Name = "PhysFS.NET"
- Project = "{C6205A43-3D4D-41E6-872C-96CD7BE55230}"
- Package = "{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}"
- />
- </References>
- </Build>
- <Files>
- <Include>
- <File
- RelPath = "App.ico"
- BuildAction = "Content"
- />
- <File
- RelPath = "AssemblyInfo.cs"
- BuildAction = "Compile"
- />
- <File
- RelPath = "TestAppForm.cs"
- SubType = "Form"
- BuildAction = "Compile"
- />
- <File
- RelPath = "TestAppForm.resx"
- DependentUpon = "TestAppForm.cs"
- BuildAction = "EmbeddedResource"
- />
- </Include>
- </Files>
- </CSHARP>
-</VisualStudioProject>
-
+++ /dev/null
-Microsoft Visual Studio Solution File, Format Version 7.00
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestApp", "TestApp.csproj", "{9C1ECC6B-16C7-42B3-BF7C-8BA8D81BA980}"
-EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PhysFS.NET", "..\PhysFS.NET.csproj", "{C6205A43-3D4D-41E6-872C-96CD7BE55230}"
-EndProject
-Global
- GlobalSection(SolutionConfiguration) = preSolution
- ConfigName.0 = Debug
- ConfigName.1 = Release
- EndGlobalSection
- GlobalSection(ProjectDependencies) = postSolution
- EndGlobalSection
- GlobalSection(ProjectConfiguration) = postSolution
- {9C1ECC6B-16C7-42B3-BF7C-8BA8D81BA980}.Debug.ActiveCfg = Debug|.NET
- {9C1ECC6B-16C7-42B3-BF7C-8BA8D81BA980}.Debug.Build.0 = Debug|.NET
- {9C1ECC6B-16C7-42B3-BF7C-8BA8D81BA980}.Release.ActiveCfg = Release|.NET
- {9C1ECC6B-16C7-42B3-BF7C-8BA8D81BA980}.Release.Build.0 = Release|.NET
- {C6205A43-3D4D-41E6-872C-96CD7BE55230}.Debug.ActiveCfg = Debug|.NET
- {C6205A43-3D4D-41E6-872C-96CD7BE55230}.Debug.Build.0 = Debug|.NET
- {C6205A43-3D4D-41E6-872C-96CD7BE55230}.Release.ActiveCfg = Release|.NET
- {C6205A43-3D4D-41E6-872C-96CD7BE55230}.Release.Build.0 = Release|.NET
- EndGlobalSection
- GlobalSection(ExtensibilityGlobals) = postSolution
- EndGlobalSection
- GlobalSection(ExtensibilityAddIns) = postSolution
- EndGlobalSection
-EndGlobal
+++ /dev/null
-using System;
-using System.Drawing;
-using System.Collections;
-using System.ComponentModel;
-using System.Windows.Forms;
-using System.Data;
-using System.IO;
-using PhysFS_NET;
-
-namespace TestApp
-{
- /// <summary>
- /// Summary description for Form1.
- /// </summary>
- public class TestAppForm : System.Windows.Forms.Form
- {
- private System.Windows.Forms.Label label2;
- private System.Windows.Forms.Button RefreshCDsButton;
- private System.Windows.Forms.ListBox CDDrivesList;
- private System.Windows.Forms.ListBox SearchPathList;
- private System.Windows.Forms.Label label1;
- private System.Windows.Forms.TextBox EnumFilesPath;
- private System.Windows.Forms.ListBox EnumList;
- private System.Windows.Forms.Label label3;
- private System.Windows.Forms.TextBox NewSearchPathText;
- private System.Windows.Forms.Button AddSearchPathButton;
- private System.Windows.Forms.Button RemovePathButton;
- private System.Windows.Forms.Button RefreshEnumList;
- private System.Windows.Forms.Button RefreshSearchPathButton;
- /// <summary>
- /// Required designer variable.
- /// </summary>
- private System.ComponentModel.Container components = null;
-
- public TestAppForm()
- {
- //
- // Required for Windows Form Designer support
- //
- InitializeComponent();
-
- //
- // TODO: Add any constructor code after InitializeComponent call
- //
- }
-
- /// <summary>
- /// Clean up any resources being used.
- /// </summary>
- protected override void Dispose( bool disposing )
- {
- if( disposing )
- {
- if (components != null)
- {
- components.Dispose();
- }
- }
- base.Dispose( disposing );
- }
-
- #region Windows Form Designer generated code
- /// <summary>
- /// Required method for Designer support - do not modify
- /// the contents of this method with the code editor.
- /// </summary>
- private void InitializeComponent()
- {
- this.label2 = new System.Windows.Forms.Label();
- this.RefreshCDsButton = new System.Windows.Forms.Button();
- this.CDDrivesList = new System.Windows.Forms.ListBox();
- this.SearchPathList = new System.Windows.Forms.ListBox();
- this.label1 = new System.Windows.Forms.Label();
- this.EnumFilesPath = new System.Windows.Forms.TextBox();
- this.EnumList = new System.Windows.Forms.ListBox();
- this.label3 = new System.Windows.Forms.Label();
- this.RefreshEnumList = new System.Windows.Forms.Button();
- this.NewSearchPathText = new System.Windows.Forms.TextBox();
- this.AddSearchPathButton = new System.Windows.Forms.Button();
- this.RemovePathButton = new System.Windows.Forms.Button();
- this.RefreshSearchPathButton = new System.Windows.Forms.Button();
- this.SuspendLayout();
- //
- // label2
- //
- this.label2.Location = new System.Drawing.Point(8, 8);
- this.label2.Name = "label2";
- this.label2.Size = new System.Drawing.Size(136, 16);
- this.label2.TabIndex = 2;
- this.label2.Text = "Available CD-ROM Drives";
- //
- // RefreshCDsButton
- //
- this.RefreshCDsButton.Location = new System.Drawing.Point(8, 152);
- this.RefreshCDsButton.Name = "RefreshCDsButton";
- this.RefreshCDsButton.Size = new System.Drawing.Size(72, 24);
- this.RefreshCDsButton.TabIndex = 4;
- this.RefreshCDsButton.Text = "Refresh";
- this.RefreshCDsButton.Click += new System.EventHandler(this.RefreshCDsButton_Click);
- //
- // CDDrivesList
- //
- this.CDDrivesList.Location = new System.Drawing.Point(8, 24);
- this.CDDrivesList.Name = "CDDrivesList";
- this.CDDrivesList.Size = new System.Drawing.Size(136, 121);
- this.CDDrivesList.TabIndex = 7;
- //
- // SearchPathList
- //
- this.SearchPathList.Location = new System.Drawing.Point(152, 24);
- this.SearchPathList.Name = "SearchPathList";
- this.SearchPathList.Size = new System.Drawing.Size(248, 95);
- this.SearchPathList.TabIndex = 8;
- //
- // label1
- //
- this.label1.Location = new System.Drawing.Point(152, 8);
- this.label1.Name = "label1";
- this.label1.Size = new System.Drawing.Size(136, 16);
- this.label1.TabIndex = 10;
- this.label1.Text = "Search Path";
- //
- // EnumFilesPath
- //
- this.EnumFilesPath.Location = new System.Drawing.Point(408, 128);
- this.EnumFilesPath.Name = "EnumFilesPath";
- this.EnumFilesPath.Size = new System.Drawing.Size(208, 20);
- this.EnumFilesPath.TabIndex = 11;
- this.EnumFilesPath.Text = "";
- //
- // EnumList
- //
- this.EnumList.Location = new System.Drawing.Point(408, 24);
- this.EnumList.Name = "EnumList";
- this.EnumList.Size = new System.Drawing.Size(208, 95);
- this.EnumList.TabIndex = 12;
- //
- // label3
- //
- this.label3.Location = new System.Drawing.Point(408, 8);
- this.label3.Name = "label3";
- this.label3.Size = new System.Drawing.Size(136, 16);
- this.label3.TabIndex = 13;
- this.label3.Text = "Enumerate Files";
- //
- // RefreshEnumList
- //
- this.RefreshEnumList.Location = new System.Drawing.Point(544, 152);
- this.RefreshEnumList.Name = "RefreshEnumList";
- this.RefreshEnumList.Size = new System.Drawing.Size(72, 24);
- this.RefreshEnumList.TabIndex = 14;
- this.RefreshEnumList.Text = "Refresh";
- this.RefreshEnumList.Click += new System.EventHandler(this.RefreshEnumList_Click);
- //
- // NewSearchPathText
- //
- this.NewSearchPathText.Location = new System.Drawing.Point(152, 128);
- this.NewSearchPathText.Name = "NewSearchPathText";
- this.NewSearchPathText.Size = new System.Drawing.Size(248, 20);
- this.NewSearchPathText.TabIndex = 15;
- this.NewSearchPathText.Text = "";
- //
- // AddSearchPathButton
- //
- this.AddSearchPathButton.Location = new System.Drawing.Point(152, 152);
- this.AddSearchPathButton.Name = "AddSearchPathButton";
- this.AddSearchPathButton.Size = new System.Drawing.Size(72, 24);
- this.AddSearchPathButton.TabIndex = 9;
- this.AddSearchPathButton.Text = "Add Path";
- this.AddSearchPathButton.Click += new System.EventHandler(this.AddSearchPathButton_Click);
- //
- // RemovePathButton
- //
- this.RemovePathButton.Location = new System.Drawing.Point(232, 152);
- this.RemovePathButton.Name = "RemovePathButton";
- this.RemovePathButton.Size = new System.Drawing.Size(88, 24);
- this.RemovePathButton.TabIndex = 16;
- this.RemovePathButton.Text = "Remove Path";
- this.RemovePathButton.Click += new System.EventHandler(this.RemovePathButton_Click);
- //
- // RefreshSearchPathButton
- //
- this.RefreshSearchPathButton.Location = new System.Drawing.Point(328, 152);
- this.RefreshSearchPathButton.Name = "RefreshSearchPathButton";
- this.RefreshSearchPathButton.Size = new System.Drawing.Size(72, 24);
- this.RefreshSearchPathButton.TabIndex = 17;
- this.RefreshSearchPathButton.Text = "Refresh";
- this.RefreshSearchPathButton.Click += new System.EventHandler(this.RefreshSearchPathButton_Click);
- //
- // TestAppForm
- //
- this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
- this.ClientSize = new System.Drawing.Size(624, 309);
- this.Controls.AddRange(new System.Windows.Forms.Control[] {
- this.RefreshSearchPathButton,
- this.RemovePathButton,
- this.NewSearchPathText,
- this.RefreshEnumList,
- this.label3,
- this.EnumList,
- this.EnumFilesPath,
- this.label1,
- this.SearchPathList,
- this.CDDrivesList,
- this.RefreshCDsButton,
- this.label2,
- this.AddSearchPathButton});
- this.Name = "TestAppForm";
- this.Text = "PhysFS Test Application";
- this.Load += new System.EventHandler(this.TestAppForm_Load);
- this.ResumeLayout(false);
-
- }
- #endregion
-
- /// <summary>
- /// The main entry point for the application.
- /// </summary>
- [STAThread]
- static void Main()
- {
- Application.Run(new TestAppForm());
- }
-
- private void TestAppForm_Load(object sender, System.EventArgs e)
- {
-
- }
-
- private void RefreshCDsButton_Click(object sender, System.EventArgs e)
- {
- // Clear ths listbox if it contains any items
- CDDrivesList.Items.Clear();
- // Add the items to the list
- CDDrivesList.Items.AddRange(PhysFS.GetCDROMDrives());
- }
-
- private void RefreshSearchPathButton_Click(object sender, System.EventArgs e)
- {
- // Clear ths listbox if it contains any items
- SearchPathList.Items.Clear();
- // Add the items to the list
- SearchPathList.Items.AddRange(PhysFS.GetSearchPath());
- }
-
- private void AddSearchPathButton_Click(object sender, System.EventArgs e)
- {
- // Add search path
- PhysFS.AddToSearchPath(NewSearchPathText.Text, false);
- // Clear ths listbox if it contains any items
- SearchPathList.Items.Clear();
- // Add the items to the list
- SearchPathList.Items.AddRange(PhysFS.GetSearchPath());
- }
-
- private void RemovePathButton_Click(object sender, System.EventArgs e)
- {
- if(SearchPathList.SelectedItem != null)
- {
- PhysFS.RemoveFromSearchPath(SearchPathList.SelectedItem.ToString());
- // Clear ths listbox if it contains any items
- SearchPathList.Items.Clear();
- // Add the items to the list
- SearchPathList.Items.AddRange(PhysFS.GetSearchPath());
- }
- }
-
- private void RefreshEnumList_Click(object sender, System.EventArgs e)
- {
- EnumList.Items.Clear();
- EnumList.Items.AddRange(PhysFS.EnumerateFiles(EnumFilesPath.Text));
- }
- }
-}
+++ /dev/null
-<?xml version="1.0" encoding="utf-8"?>
-<root>
- <!--
- Microsoft ResX Schema
-
- Version 1.3
-
- The primary goals of this format is to allow a simple XML format
- that is mostly human readable. The generation and parsing of the
- various data types are done through the TypeConverter classes
- associated with the data types.
-
- Example:
-
- ... ado.net/XML headers & schema ...
- <resheader name="resmimetype">text/microsoft-resx</resheader>
- <resheader name="version">1.3</resheader>
- <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
- <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
- <data name="Name1">this is my long string</data>
- <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
- <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
- [base64 mime encoded serialized .NET Framework object]
- </data>
- <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
- [base64 mime encoded string representing a byte array form of the .NET Framework object]
- </data>
-
- There are any number of "resheader" rows that contain simple
- name/value pairs.
-
- Each data row contains a name, and value. The row also contains a
- type or mimetype. Type corresponds to a .NET class that support
- text/value conversion through the TypeConverter architecture.
- Classes that don't support this are serialized and stored with the
- mimetype set.
-
- The mimetype is used for serialized objects, and tells the
- ResXResourceReader how to depersist the object. This is currently not
- extensible. For a given mimetype the value must be set accordingly:
-
- Note - application/x-microsoft.net.object.binary.base64 is the format
- that the ResXResourceWriter will generate, however the reader can
- read any of the formats listed below.
-
- mimetype: application/x-microsoft.net.object.binary.base64
- value : The object must be serialized with
- : System.Serialization.Formatters.Binary.BinaryFormatter
- : and then encoded with base64 encoding.
-
- mimetype: application/x-microsoft.net.object.soap.base64
- value : The object must be serialized with
- : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
- : and then encoded with base64 encoding.
- mimetype: application/x-microsoft.net.object.bytearray.base64
- value : The object must be serialized into a byte array
- : using a System.ComponentModel.TypeConverter
- : and then encoded with base64 encoding.
- -->
- <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
- <xsd:element name="root" msdata:IsDataSet="true">
- <xsd:complexType>
- <xsd:choice maxOccurs="unbounded">
- <xsd:element name="data">
- <xsd:complexType>
- <xsd:sequence>
- <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
- <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
- </xsd:sequence>
- <xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
- <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
- <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
- </xsd:complexType>
- </xsd:element>
- <xsd:element name="resheader">
- <xsd:complexType>
- <xsd:sequence>
- <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
- </xsd:sequence>
- <xsd:attribute name="name" type="xsd:string" use="required" />
- </xsd:complexType>
- </xsd:element>
- </xsd:choice>
- </xsd:complexType>
- </xsd:element>
- </xsd:schema>
- <resheader name="resmimetype">
- <value>text/microsoft-resx</value>
- </resheader>
- <resheader name="version">
- <value>1.3</value>
- </resheader>
- <resheader name="reader">
- <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
- </resheader>
- <resheader name="writer">
- <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
- </resheader>
- <data name="$this.Name">
- <value>TestAppForm</value>
- </data>
-</root>
\ No newline at end of file
+++ /dev/null
-/*
- * stdio/physfs abstraction layer 2003-04-02
- *
- * Adam D. Moss <adam@gimp.org> <aspirin@icculus.org>
- *
- * These wrapper macros and functions are designed to allow a program
- * to perform file I/O with identical semantics and syntax regardless
- * of whether PhysicsFS is being used or not.
- */
-#ifndef _ABS_FILE_H
-#define _ABS_FILE_H
-/*
-PLEASE NOTE: This license applies to abs-file.h ONLY (to make it clear that
-you may embed this wrapper code within commercial software); PhysicsFS itself
-is (at the time of writing) released under a different license with
-additional restrictions.
-
-Copyright (C) 2002-2003 Adam D. Moss (the "Author"). All Rights Reserved.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is fur-
-nished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FIT-
-NESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
-IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CON-
-NECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-Except as contained in this notice, the name of the Author of the
-Software shall not be used in advertising or otherwise to promote the sale,
-use or other dealings in this Software without prior written authorization
-from the Author.
-*/
-
-#include <stdlib.h>
-#include <stdio.h>
-
-/*
- * API:
- *
- * Macro/function use like stdio equivalent...
- * -------------- ----------------------------
- * MY_FILETYPE FILE
- * MY_OPEN_FOR_READ fopen(..., "rb")
- * MY_READ fread(...)
- * MY_CLOSE fclose(...)
- * MY_GETC fgetc(...)
- * MY_GETS fgets(...)
- * MY_ATEOF feof(...)
- * MY_TELL ftell(...)
- * MY_SEEK fseek(..., SEEK_SET)
- * MY_REWIND rewind(...)
- * MY_SETBUFFER (not a standard for stdio, does nothing there)
- */
-
-/*
- * Important DEFINEs:
- * It is important to define these consistantly across the various
- * compilation modules of your program if you wish to exchange file
- * handles between them.
- *
- * USE_PHYSFS: Define USE_PHYSFS if PhysicsFS is being used; note that if
- * you do intend to use PhysicsFS then you will still need to initialize
- * PhysicsFS yourself and set up its search-paths.
- *
- * Optional DEFINEs:
- *
- * PHYSFS_DEFAULT_READ_BUFFER <bytes>: If set then abs-file.h sets the
- * PhysicsFS buffer size to this value whenever you open a file. You
- * may over-ride this on a per-filehandle basis by using the
- * MY_SETBUFFER() macro (which simply does nothing when not using
- * PhysicsFS). If you have not defined this value explicitly then
- * abs-file.h will default to the same default buffer size as used by
- * stdio if it can be determined, or 8192 bytes otherwise.
- */
-#ifndef PHYSFS_DEFAULT_READ_BUFFER
-#ifdef BUFSIZ
-#define PHYSFS_DEFAULT_READ_BUFFER BUFSIZ
-#else
-#define PHYSFS_DEFAULT_READ_BUFFER 8192
-#endif
-#endif
-
-#ifdef USE_PHYSFS
-
-#include <physfs.h>
-#define MY_FILETYPE PHYSFS_File
-#define MY_SETBUFFER(fp,size) PHYSFS_setBuffer(fp,size)
-#define MY_READ(p,s,n,fp) PHYSFS_read(fp,p,s,n)
-#if PHYSFS_DEFAULT_READ_BUFFER
-static MY_FILETYPE* MY_OPEN_FOR_READ(const char *const filename)
-{
- MY_FILETYPE *const file = PHYSFS_openRead(filename);
- if (file) {
- MY_SETBUFFER(file, PHYSFS_DEFAULT_READ_BUFFER);
- }
- return file;
-}
-#else
-#define MY_OPEN_FOR_READ(fn) PHYSFS_openRead(fn)
-#endif
-static int MY_GETC(MY_FILETYPE *const fp) {
- unsigned char c;
- /*if (PHYSFS_eof(fp)) {
- return EOF;
- }
- MY_READ(&c, 1, 1, fp);*/
- if (MY_READ(&c, 1, 1, fp) != 1) {
- return EOF;
- }
- return c;
-}
-static char * MY_GETS(char * const str, const int size,
- MY_FILETYPE *const fp) {
- int i = 0;
- int c;
- do {
- if (i == size-1) {
- break;
- }
- c = MY_GETC(fp);
- if (c == EOF) {
- break;
- }
- str[i++] = c;
- } while (c != '\0' &&
- c != -1 &&
- c != '\n');
- str[i] = '\0';
- if (i == 0) {
- return NULL;
- }
- return str;
-}
-#define MY_CLOSE(fp) PHYSFS_close(fp)
-#define MY_ATEOF(fp) PHYSFS_eof(fp)
-#define MY_TELL(fp) PHYSFS_tell(fp)
-#define MY_SEEK(fp,o) PHYSFS_seek(fp,o)
-#define MY_REWIND(fp) MY_SEEK(fp,0)
-
-#else
-
-#define MY_FILETYPE FILE
-#define MY_READ(p,s,n,fp) fread(p,s,n,fp)
-#define MY_OPEN_FOR_READ(n) fopen(n, "rb")
-#define MY_GETC(fp) fgetc(fp)
-#define MY_GETS(str,size,fp) fgets(str,size,fp)
-#define MY_CLOSE(fp) fclose(fp)
-#define MY_ATEOF(fp) feof(fp)
-#define MY_TELL(fp) ftell(fp)
-#define MY_SEEK(fp,o) fseek(fp,o, SEEK_SET)
-#define MY_REWIND(fp) rewind(fp)
-/*static void MY_SETBUFFER(const MY_FILETYPE *const file, const int num) { }*/
-#define MY_SETBUFFER(fp,size)
-#endif
-
-#endif
+++ /dev/null
-# CaseFolding-4.1.0.txt
-# Date: 2005-03-26, 00:24:43 GMT [MD]
-#
-# Unicode Character Database
-# Copyright (c) 1991-2005 Unicode, Inc.
-# For terms of use, see http://www.unicode.org/terms_of_use.html
-# For documentation, see UCD.html
-#
-# Case Folding Properties
-#
-# This file is a supplement to the UnicodeData file.
-# It provides a case folding mapping generated from the Unicode Character Database.
-# If all characters are mapped according to the full mapping below, then
-# case differences (according to UnicodeData.txt and SpecialCasing.txt)
-# are eliminated.
-#
-# The data supports both implementations that require simple case foldings
-# (where string lengths don't change), and implementations that allow full case folding
-# (where string lengths may grow). Note that where they can be supported, the
-# full case foldings are superior: for example, they allow "MASSE" and "Maße" to match.
-#
-# All code points not listed in this file map to themselves.
-#
-# NOTE: case folding does not preserve normalization formats!
-#
-# For information on case folding, see
-# UTR #21 Case Mappings, at http://www.unicode.org/unicode/reports/tr21/
-#
-# ================================================================================
-# Format
-# ================================================================================
-# The entries in this file are in the following machine-readable format:
-#
-# <code>; <status>; <mapping>; # <name>
-#
-# The status field is:
-# C: common case folding, common mappings shared by both simple and full mappings.
-# F: full case folding, mappings that cause strings to grow in length. Multiple characters are separated by spaces.
-# S: simple case folding, mappings to single characters where different from F.
-# T: special case for uppercase I and dotted uppercase I
-# - For non-Turkic languages, this mapping is normally not used.
-# - For Turkic languages (tr, az), this mapping can be used instead of the normal mapping for these characters.
-# Note that the Turkic mappings do not maintain canonical equivalence without additional processing.
-# See the discussions of case mapping in the Unicode Standard for more information.
-#
-# Usage:
-# A. To do a simple case folding, use the mappings with status C + S.
-# B. To do a full case folding, use the mappings with status C + F.
-#
-# The mappings with status T can be used or omitted depending on the desired case-folding
-# behavior. (The default option is to exclude them.)
-#
-# =================================================================
-
-0041; C; 0061; # LATIN CAPITAL LETTER A
-0042; C; 0062; # LATIN CAPITAL LETTER B
-0043; C; 0063; # LATIN CAPITAL LETTER C
-0044; C; 0064; # LATIN CAPITAL LETTER D
-0045; C; 0065; # LATIN CAPITAL LETTER E
-0046; C; 0066; # LATIN CAPITAL LETTER F
-0047; C; 0067; # LATIN CAPITAL LETTER G
-0048; C; 0068; # LATIN CAPITAL LETTER H
-0049; C; 0069; # LATIN CAPITAL LETTER I
-0049; T; 0131; # LATIN CAPITAL LETTER I
-004A; C; 006A; # LATIN CAPITAL LETTER J
-004B; C; 006B; # LATIN CAPITAL LETTER K
-004C; C; 006C; # LATIN CAPITAL LETTER L
-004D; C; 006D; # LATIN CAPITAL LETTER M
-004E; C; 006E; # LATIN CAPITAL LETTER N
-004F; C; 006F; # LATIN CAPITAL LETTER O
-0050; C; 0070; # LATIN CAPITAL LETTER P
-0051; C; 0071; # LATIN CAPITAL LETTER Q
-0052; C; 0072; # LATIN CAPITAL LETTER R
-0053; C; 0073; # LATIN CAPITAL LETTER S
-0054; C; 0074; # LATIN CAPITAL LETTER T
-0055; C; 0075; # LATIN CAPITAL LETTER U
-0056; C; 0076; # LATIN CAPITAL LETTER V
-0057; C; 0077; # LATIN CAPITAL LETTER W
-0058; C; 0078; # LATIN CAPITAL LETTER X
-0059; C; 0079; # LATIN CAPITAL LETTER Y
-005A; C; 007A; # LATIN CAPITAL LETTER Z
-00B5; C; 03BC; # MICRO SIGN
-00C0; C; 00E0; # LATIN CAPITAL LETTER A WITH GRAVE
-00C1; C; 00E1; # LATIN CAPITAL LETTER A WITH ACUTE
-00C2; C; 00E2; # LATIN CAPITAL LETTER A WITH CIRCUMFLEX
-00C3; C; 00E3; # LATIN CAPITAL LETTER A WITH TILDE
-00C4; C; 00E4; # LATIN CAPITAL LETTER A WITH DIAERESIS
-00C5; C; 00E5; # LATIN CAPITAL LETTER A WITH RING ABOVE
-00C6; C; 00E6; # LATIN CAPITAL LETTER AE
-00C7; C; 00E7; # LATIN CAPITAL LETTER C WITH CEDILLA
-00C8; C; 00E8; # LATIN CAPITAL LETTER E WITH GRAVE
-00C9; C; 00E9; # LATIN CAPITAL LETTER E WITH ACUTE
-00CA; C; 00EA; # LATIN CAPITAL LETTER E WITH CIRCUMFLEX
-00CB; C; 00EB; # LATIN CAPITAL LETTER E WITH DIAERESIS
-00CC; C; 00EC; # LATIN CAPITAL LETTER I WITH GRAVE
-00CD; C; 00ED; # LATIN CAPITAL LETTER I WITH ACUTE
-00CE; C; 00EE; # LATIN CAPITAL LETTER I WITH CIRCUMFLEX
-00CF; C; 00EF; # LATIN CAPITAL LETTER I WITH DIAERESIS
-00D0; C; 00F0; # LATIN CAPITAL LETTER ETH
-00D1; C; 00F1; # LATIN CAPITAL LETTER N WITH TILDE
-00D2; C; 00F2; # LATIN CAPITAL LETTER O WITH GRAVE
-00D3; C; 00F3; # LATIN CAPITAL LETTER O WITH ACUTE
-00D4; C; 00F4; # LATIN CAPITAL LETTER O WITH CIRCUMFLEX
-00D5; C; 00F5; # LATIN CAPITAL LETTER O WITH TILDE
-00D6; C; 00F6; # LATIN CAPITAL LETTER O WITH DIAERESIS
-00D8; C; 00F8; # LATIN CAPITAL LETTER O WITH STROKE
-00D9; C; 00F9; # LATIN CAPITAL LETTER U WITH GRAVE
-00DA; C; 00FA; # LATIN CAPITAL LETTER U WITH ACUTE
-00DB; C; 00FB; # LATIN CAPITAL LETTER U WITH CIRCUMFLEX
-00DC; C; 00FC; # LATIN CAPITAL LETTER U WITH DIAERESIS
-00DD; C; 00FD; # LATIN CAPITAL LETTER Y WITH ACUTE
-00DE; C; 00FE; # LATIN CAPITAL LETTER THORN
-00DF; F; 0073 0073; # LATIN SMALL LETTER SHARP S
-0100; C; 0101; # LATIN CAPITAL LETTER A WITH MACRON
-0102; C; 0103; # LATIN CAPITAL LETTER A WITH BREVE
-0104; C; 0105; # LATIN CAPITAL LETTER A WITH OGONEK
-0106; C; 0107; # LATIN CAPITAL LETTER C WITH ACUTE
-0108; C; 0109; # LATIN CAPITAL LETTER C WITH CIRCUMFLEX
-010A; C; 010B; # LATIN CAPITAL LETTER C WITH DOT ABOVE
-010C; C; 010D; # LATIN CAPITAL LETTER C WITH CARON
-010E; C; 010F; # LATIN CAPITAL LETTER D WITH CARON
-0110; C; 0111; # LATIN CAPITAL LETTER D WITH STROKE
-0112; C; 0113; # LATIN CAPITAL LETTER E WITH MACRON
-0114; C; 0115; # LATIN CAPITAL LETTER E WITH BREVE
-0116; C; 0117; # LATIN CAPITAL LETTER E WITH DOT ABOVE
-0118; C; 0119; # LATIN CAPITAL LETTER E WITH OGONEK
-011A; C; 011B; # LATIN CAPITAL LETTER E WITH CARON
-011C; C; 011D; # LATIN CAPITAL LETTER G WITH CIRCUMFLEX
-011E; C; 011F; # LATIN CAPITAL LETTER G WITH BREVE
-0120; C; 0121; # LATIN CAPITAL LETTER G WITH DOT ABOVE
-0122; C; 0123; # LATIN CAPITAL LETTER G WITH CEDILLA
-0124; C; 0125; # LATIN CAPITAL LETTER H WITH CIRCUMFLEX
-0126; C; 0127; # LATIN CAPITAL LETTER H WITH STROKE
-0128; C; 0129; # LATIN CAPITAL LETTER I WITH TILDE
-012A; C; 012B; # LATIN CAPITAL LETTER I WITH MACRON
-012C; C; 012D; # LATIN CAPITAL LETTER I WITH BREVE
-012E; C; 012F; # LATIN CAPITAL LETTER I WITH OGONEK
-0130; F; 0069 0307; # LATIN CAPITAL LETTER I WITH DOT ABOVE
-0130; T; 0069; # LATIN CAPITAL LETTER I WITH DOT ABOVE
-0132; C; 0133; # LATIN CAPITAL LIGATURE IJ
-0134; C; 0135; # LATIN CAPITAL LETTER J WITH CIRCUMFLEX
-0136; C; 0137; # LATIN CAPITAL LETTER K WITH CEDILLA
-0139; C; 013A; # LATIN CAPITAL LETTER L WITH ACUTE
-013B; C; 013C; # LATIN CAPITAL LETTER L WITH CEDILLA
-013D; C; 013E; # LATIN CAPITAL LETTER L WITH CARON
-013F; C; 0140; # LATIN CAPITAL LETTER L WITH MIDDLE DOT
-0141; C; 0142; # LATIN CAPITAL LETTER L WITH STROKE
-0143; C; 0144; # LATIN CAPITAL LETTER N WITH ACUTE
-0145; C; 0146; # LATIN CAPITAL LETTER N WITH CEDILLA
-0147; C; 0148; # LATIN CAPITAL LETTER N WITH CARON
-0149; F; 02BC 006E; # LATIN SMALL LETTER N PRECEDED BY APOSTROPHE
-014A; C; 014B; # LATIN CAPITAL LETTER ENG
-014C; C; 014D; # LATIN CAPITAL LETTER O WITH MACRON
-014E; C; 014F; # LATIN CAPITAL LETTER O WITH BREVE
-0150; C; 0151; # LATIN CAPITAL LETTER O WITH DOUBLE ACUTE
-0152; C; 0153; # LATIN CAPITAL LIGATURE OE
-0154; C; 0155; # LATIN CAPITAL LETTER R WITH ACUTE
-0156; C; 0157; # LATIN CAPITAL LETTER R WITH CEDILLA
-0158; C; 0159; # LATIN CAPITAL LETTER R WITH CARON
-015A; C; 015B; # LATIN CAPITAL LETTER S WITH ACUTE
-015C; C; 015D; # LATIN CAPITAL LETTER S WITH CIRCUMFLEX
-015E; C; 015F; # LATIN CAPITAL LETTER S WITH CEDILLA
-0160; C; 0161; # LATIN CAPITAL LETTER S WITH CARON
-0162; C; 0163; # LATIN CAPITAL LETTER T WITH CEDILLA
-0164; C; 0165; # LATIN CAPITAL LETTER T WITH CARON
-0166; C; 0167; # LATIN CAPITAL LETTER T WITH STROKE
-0168; C; 0169; # LATIN CAPITAL LETTER U WITH TILDE
-016A; C; 016B; # LATIN CAPITAL LETTER U WITH MACRON
-016C; C; 016D; # LATIN CAPITAL LETTER U WITH BREVE
-016E; C; 016F; # LATIN CAPITAL LETTER U WITH RING ABOVE
-0170; C; 0171; # LATIN CAPITAL LETTER U WITH DOUBLE ACUTE
-0172; C; 0173; # LATIN CAPITAL LETTER U WITH OGONEK
-0174; C; 0175; # LATIN CAPITAL LETTER W WITH CIRCUMFLEX
-0176; C; 0177; # LATIN CAPITAL LETTER Y WITH CIRCUMFLEX
-0178; C; 00FF; # LATIN CAPITAL LETTER Y WITH DIAERESIS
-0179; C; 017A; # LATIN CAPITAL LETTER Z WITH ACUTE
-017B; C; 017C; # LATIN CAPITAL LETTER Z WITH DOT ABOVE
-017D; C; 017E; # LATIN CAPITAL LETTER Z WITH CARON
-017F; C; 0073; # LATIN SMALL LETTER LONG S
-0181; C; 0253; # LATIN CAPITAL LETTER B WITH HOOK
-0182; C; 0183; # LATIN CAPITAL LETTER B WITH TOPBAR
-0184; C; 0185; # LATIN CAPITAL LETTER TONE SIX
-0186; C; 0254; # LATIN CAPITAL LETTER OPEN O
-0187; C; 0188; # LATIN CAPITAL LETTER C WITH HOOK
-0189; C; 0256; # LATIN CAPITAL LETTER AFRICAN D
-018A; C; 0257; # LATIN CAPITAL LETTER D WITH HOOK
-018B; C; 018C; # LATIN CAPITAL LETTER D WITH TOPBAR
-018E; C; 01DD; # LATIN CAPITAL LETTER REVERSED E
-018F; C; 0259; # LATIN CAPITAL LETTER SCHWA
-0190; C; 025B; # LATIN CAPITAL LETTER OPEN E
-0191; C; 0192; # LATIN CAPITAL LETTER F WITH HOOK
-0193; C; 0260; # LATIN CAPITAL LETTER G WITH HOOK
-0194; C; 0263; # LATIN CAPITAL LETTER GAMMA
-0196; C; 0269; # LATIN CAPITAL LETTER IOTA
-0197; C; 0268; # LATIN CAPITAL LETTER I WITH STROKE
-0198; C; 0199; # LATIN CAPITAL LETTER K WITH HOOK
-019C; C; 026F; # LATIN CAPITAL LETTER TURNED M
-019D; C; 0272; # LATIN CAPITAL LETTER N WITH LEFT HOOK
-019F; C; 0275; # LATIN CAPITAL LETTER O WITH MIDDLE TILDE
-01A0; C; 01A1; # LATIN CAPITAL LETTER O WITH HORN
-01A2; C; 01A3; # LATIN CAPITAL LETTER OI
-01A4; C; 01A5; # LATIN CAPITAL LETTER P WITH HOOK
-01A6; C; 0280; # LATIN LETTER YR
-01A7; C; 01A8; # LATIN CAPITAL LETTER TONE TWO
-01A9; C; 0283; # LATIN CAPITAL LETTER ESH
-01AC; C; 01AD; # LATIN CAPITAL LETTER T WITH HOOK
-01AE; C; 0288; # LATIN CAPITAL LETTER T WITH RETROFLEX HOOK
-01AF; C; 01B0; # LATIN CAPITAL LETTER U WITH HORN
-01B1; C; 028A; # LATIN CAPITAL LETTER UPSILON
-01B2; C; 028B; # LATIN CAPITAL LETTER V WITH HOOK
-01B3; C; 01B4; # LATIN CAPITAL LETTER Y WITH HOOK
-01B5; C; 01B6; # LATIN CAPITAL LETTER Z WITH STROKE
-01B7; C; 0292; # LATIN CAPITAL LETTER EZH
-01B8; C; 01B9; # LATIN CAPITAL LETTER EZH REVERSED
-01BC; C; 01BD; # LATIN CAPITAL LETTER TONE FIVE
-01C4; C; 01C6; # LATIN CAPITAL LETTER DZ WITH CARON
-01C5; C; 01C6; # LATIN CAPITAL LETTER D WITH SMALL LETTER Z WITH CARON
-01C7; C; 01C9; # LATIN CAPITAL LETTER LJ
-01C8; C; 01C9; # LATIN CAPITAL LETTER L WITH SMALL LETTER J
-01CA; C; 01CC; # LATIN CAPITAL LETTER NJ
-01CB; C; 01CC; # LATIN CAPITAL LETTER N WITH SMALL LETTER J
-01CD; C; 01CE; # LATIN CAPITAL LETTER A WITH CARON
-01CF; C; 01D0; # LATIN CAPITAL LETTER I WITH CARON
-01D1; C; 01D2; # LATIN CAPITAL LETTER O WITH CARON
-01D3; C; 01D4; # LATIN CAPITAL LETTER U WITH CARON
-01D5; C; 01D6; # LATIN CAPITAL LETTER U WITH DIAERESIS AND MACRON
-01D7; C; 01D8; # LATIN CAPITAL LETTER U WITH DIAERESIS AND ACUTE
-01D9; C; 01DA; # LATIN CAPITAL LETTER U WITH DIAERESIS AND CARON
-01DB; C; 01DC; # LATIN CAPITAL LETTER U WITH DIAERESIS AND GRAVE
-01DE; C; 01DF; # LATIN CAPITAL LETTER A WITH DIAERESIS AND MACRON
-01E0; C; 01E1; # LATIN CAPITAL LETTER A WITH DOT ABOVE AND MACRON
-01E2; C; 01E3; # LATIN CAPITAL LETTER AE WITH MACRON
-01E4; C; 01E5; # LATIN CAPITAL LETTER G WITH STROKE
-01E6; C; 01E7; # LATIN CAPITAL LETTER G WITH CARON
-01E8; C; 01E9; # LATIN CAPITAL LETTER K WITH CARON
-01EA; C; 01EB; # LATIN CAPITAL LETTER O WITH OGONEK
-01EC; C; 01ED; # LATIN CAPITAL LETTER O WITH OGONEK AND MACRON
-01EE; C; 01EF; # LATIN CAPITAL LETTER EZH WITH CARON
-01F0; F; 006A 030C; # LATIN SMALL LETTER J WITH CARON
-01F1; C; 01F3; # LATIN CAPITAL LETTER DZ
-01F2; C; 01F3; # LATIN CAPITAL LETTER D WITH SMALL LETTER Z
-01F4; C; 01F5; # LATIN CAPITAL LETTER G WITH ACUTE
-01F6; C; 0195; # LATIN CAPITAL LETTER HWAIR
-01F7; C; 01BF; # LATIN CAPITAL LETTER WYNN
-01F8; C; 01F9; # LATIN CAPITAL LETTER N WITH GRAVE
-01FA; C; 01FB; # LATIN CAPITAL LETTER A WITH RING ABOVE AND ACUTE
-01FC; C; 01FD; # LATIN CAPITAL LETTER AE WITH ACUTE
-01FE; C; 01FF; # LATIN CAPITAL LETTER O WITH STROKE AND ACUTE
-0200; C; 0201; # LATIN CAPITAL LETTER A WITH DOUBLE GRAVE
-0202; C; 0203; # LATIN CAPITAL LETTER A WITH INVERTED BREVE
-0204; C; 0205; # LATIN CAPITAL LETTER E WITH DOUBLE GRAVE
-0206; C; 0207; # LATIN CAPITAL LETTER E WITH INVERTED BREVE
-0208; C; 0209; # LATIN CAPITAL LETTER I WITH DOUBLE GRAVE
-020A; C; 020B; # LATIN CAPITAL LETTER I WITH INVERTED BREVE
-020C; C; 020D; # LATIN CAPITAL LETTER O WITH DOUBLE GRAVE
-020E; C; 020F; # LATIN CAPITAL LETTER O WITH INVERTED BREVE
-0210; C; 0211; # LATIN CAPITAL LETTER R WITH DOUBLE GRAVE
-0212; C; 0213; # LATIN CAPITAL LETTER R WITH INVERTED BREVE
-0214; C; 0215; # LATIN CAPITAL LETTER U WITH DOUBLE GRAVE
-0216; C; 0217; # LATIN CAPITAL LETTER U WITH INVERTED BREVE
-0218; C; 0219; # LATIN CAPITAL LETTER S WITH COMMA BELOW
-021A; C; 021B; # LATIN CAPITAL LETTER T WITH COMMA BELOW
-021C; C; 021D; # LATIN CAPITAL LETTER YOGH
-021E; C; 021F; # LATIN CAPITAL LETTER H WITH CARON
-0220; C; 019E; # LATIN CAPITAL LETTER N WITH LONG RIGHT LEG
-0222; C; 0223; # LATIN CAPITAL LETTER OU
-0224; C; 0225; # LATIN CAPITAL LETTER Z WITH HOOK
-0226; C; 0227; # LATIN CAPITAL LETTER A WITH DOT ABOVE
-0228; C; 0229; # LATIN CAPITAL LETTER E WITH CEDILLA
-022A; C; 022B; # LATIN CAPITAL LETTER O WITH DIAERESIS AND MACRON
-022C; C; 022D; # LATIN CAPITAL LETTER O WITH TILDE AND MACRON
-022E; C; 022F; # LATIN CAPITAL LETTER O WITH DOT ABOVE
-0230; C; 0231; # LATIN CAPITAL LETTER O WITH DOT ABOVE AND MACRON
-0232; C; 0233; # LATIN CAPITAL LETTER Y WITH MACRON
-023B; C; 023C; # LATIN CAPITAL LETTER C WITH STROKE
-023D; C; 019A; # LATIN CAPITAL LETTER L WITH BAR
-0241; C; 0294; # LATIN CAPITAL LETTER GLOTTAL STOP
-0345; C; 03B9; # COMBINING GREEK YPOGEGRAMMENI
-0386; C; 03AC; # GREEK CAPITAL LETTER ALPHA WITH TONOS
-0388; C; 03AD; # GREEK CAPITAL LETTER EPSILON WITH TONOS
-0389; C; 03AE; # GREEK CAPITAL LETTER ETA WITH TONOS
-038A; C; 03AF; # GREEK CAPITAL LETTER IOTA WITH TONOS
-038C; C; 03CC; # GREEK CAPITAL LETTER OMICRON WITH TONOS
-038E; C; 03CD; # GREEK CAPITAL LETTER UPSILON WITH TONOS
-038F; C; 03CE; # GREEK CAPITAL LETTER OMEGA WITH TONOS
-0390; F; 03B9 0308 0301; # GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS
-0391; C; 03B1; # GREEK CAPITAL LETTER ALPHA
-0392; C; 03B2; # GREEK CAPITAL LETTER BETA
-0393; C; 03B3; # GREEK CAPITAL LETTER GAMMA
-0394; C; 03B4; # GREEK CAPITAL LETTER DELTA
-0395; C; 03B5; # GREEK CAPITAL LETTER EPSILON
-0396; C; 03B6; # GREEK CAPITAL LETTER ZETA
-0397; C; 03B7; # GREEK CAPITAL LETTER ETA
-0398; C; 03B8; # GREEK CAPITAL LETTER THETA
-0399; C; 03B9; # GREEK CAPITAL LETTER IOTA
-039A; C; 03BA; # GREEK CAPITAL LETTER KAPPA
-039B; C; 03BB; # GREEK CAPITAL LETTER LAMDA
-039C; C; 03BC; # GREEK CAPITAL LETTER MU
-039D; C; 03BD; # GREEK CAPITAL LETTER NU
-039E; C; 03BE; # GREEK CAPITAL LETTER XI
-039F; C; 03BF; # GREEK CAPITAL LETTER OMICRON
-03A0; C; 03C0; # GREEK CAPITAL LETTER PI
-03A1; C; 03C1; # GREEK CAPITAL LETTER RHO
-03A3; C; 03C3; # GREEK CAPITAL LETTER SIGMA
-03A4; C; 03C4; # GREEK CAPITAL LETTER TAU
-03A5; C; 03C5; # GREEK CAPITAL LETTER UPSILON
-03A6; C; 03C6; # GREEK CAPITAL LETTER PHI
-03A7; C; 03C7; # GREEK CAPITAL LETTER CHI
-03A8; C; 03C8; # GREEK CAPITAL LETTER PSI
-03A9; C; 03C9; # GREEK CAPITAL LETTER OMEGA
-03AA; C; 03CA; # GREEK CAPITAL LETTER IOTA WITH DIALYTIKA
-03AB; C; 03CB; # GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA
-03B0; F; 03C5 0308 0301; # GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS
-03C2; C; 03C3; # GREEK SMALL LETTER FINAL SIGMA
-03D0; C; 03B2; # GREEK BETA SYMBOL
-03D1; C; 03B8; # GREEK THETA SYMBOL
-03D5; C; 03C6; # GREEK PHI SYMBOL
-03D6; C; 03C0; # GREEK PI SYMBOL
-03D8; C; 03D9; # GREEK LETTER ARCHAIC KOPPA
-03DA; C; 03DB; # GREEK LETTER STIGMA
-03DC; C; 03DD; # GREEK LETTER DIGAMMA
-03DE; C; 03DF; # GREEK LETTER KOPPA
-03E0; C; 03E1; # GREEK LETTER SAMPI
-03E2; C; 03E3; # COPTIC CAPITAL LETTER SHEI
-03E4; C; 03E5; # COPTIC CAPITAL LETTER FEI
-03E6; C; 03E7; # COPTIC CAPITAL LETTER KHEI
-03E8; C; 03E9; # COPTIC CAPITAL LETTER HORI
-03EA; C; 03EB; # COPTIC CAPITAL LETTER GANGIA
-03EC; C; 03ED; # COPTIC CAPITAL LETTER SHIMA
-03EE; C; 03EF; # COPTIC CAPITAL LETTER DEI
-03F0; C; 03BA; # GREEK KAPPA SYMBOL
-03F1; C; 03C1; # GREEK RHO SYMBOL
-03F4; C; 03B8; # GREEK CAPITAL THETA SYMBOL
-03F5; C; 03B5; # GREEK LUNATE EPSILON SYMBOL
-03F7; C; 03F8; # GREEK CAPITAL LETTER SHO
-03F9; C; 03F2; # GREEK CAPITAL LUNATE SIGMA SYMBOL
-03FA; C; 03FB; # GREEK CAPITAL LETTER SAN
-0400; C; 0450; # CYRILLIC CAPITAL LETTER IE WITH GRAVE
-0401; C; 0451; # CYRILLIC CAPITAL LETTER IO
-0402; C; 0452; # CYRILLIC CAPITAL LETTER DJE
-0403; C; 0453; # CYRILLIC CAPITAL LETTER GJE
-0404; C; 0454; # CYRILLIC CAPITAL LETTER UKRAINIAN IE
-0405; C; 0455; # CYRILLIC CAPITAL LETTER DZE
-0406; C; 0456; # CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I
-0407; C; 0457; # CYRILLIC CAPITAL LETTER YI
-0408; C; 0458; # CYRILLIC CAPITAL LETTER JE
-0409; C; 0459; # CYRILLIC CAPITAL LETTER LJE
-040A; C; 045A; # CYRILLIC CAPITAL LETTER NJE
-040B; C; 045B; # CYRILLIC CAPITAL LETTER TSHE
-040C; C; 045C; # CYRILLIC CAPITAL LETTER KJE
-040D; C; 045D; # CYRILLIC CAPITAL LETTER I WITH GRAVE
-040E; C; 045E; # CYRILLIC CAPITAL LETTER SHORT U
-040F; C; 045F; # CYRILLIC CAPITAL LETTER DZHE
-0410; C; 0430; # CYRILLIC CAPITAL LETTER A
-0411; C; 0431; # CYRILLIC CAPITAL LETTER BE
-0412; C; 0432; # CYRILLIC CAPITAL LETTER VE
-0413; C; 0433; # CYRILLIC CAPITAL LETTER GHE
-0414; C; 0434; # CYRILLIC CAPITAL LETTER DE
-0415; C; 0435; # CYRILLIC CAPITAL LETTER IE
-0416; C; 0436; # CYRILLIC CAPITAL LETTER ZHE
-0417; C; 0437; # CYRILLIC CAPITAL LETTER ZE
-0418; C; 0438; # CYRILLIC CAPITAL LETTER I
-0419; C; 0439; # CYRILLIC CAPITAL LETTER SHORT I
-041A; C; 043A; # CYRILLIC CAPITAL LETTER KA
-041B; C; 043B; # CYRILLIC CAPITAL LETTER EL
-041C; C; 043C; # CYRILLIC CAPITAL LETTER EM
-041D; C; 043D; # CYRILLIC CAPITAL LETTER EN
-041E; C; 043E; # CYRILLIC CAPITAL LETTER O
-041F; C; 043F; # CYRILLIC CAPITAL LETTER PE
-0420; C; 0440; # CYRILLIC CAPITAL LETTER ER
-0421; C; 0441; # CYRILLIC CAPITAL LETTER ES
-0422; C; 0442; # CYRILLIC CAPITAL LETTER TE
-0423; C; 0443; # CYRILLIC CAPITAL LETTER U
-0424; C; 0444; # CYRILLIC CAPITAL LETTER EF
-0425; C; 0445; # CYRILLIC CAPITAL LETTER HA
-0426; C; 0446; # CYRILLIC CAPITAL LETTER TSE
-0427; C; 0447; # CYRILLIC CAPITAL LETTER CHE
-0428; C; 0448; # CYRILLIC CAPITAL LETTER SHA
-0429; C; 0449; # CYRILLIC CAPITAL LETTER SHCHA
-042A; C; 044A; # CYRILLIC CAPITAL LETTER HARD SIGN
-042B; C; 044B; # CYRILLIC CAPITAL LETTER YERU
-042C; C; 044C; # CYRILLIC CAPITAL LETTER SOFT SIGN
-042D; C; 044D; # CYRILLIC CAPITAL LETTER E
-042E; C; 044E; # CYRILLIC CAPITAL LETTER YU
-042F; C; 044F; # CYRILLIC CAPITAL LETTER YA
-0460; C; 0461; # CYRILLIC CAPITAL LETTER OMEGA
-0462; C; 0463; # CYRILLIC CAPITAL LETTER YAT
-0464; C; 0465; # CYRILLIC CAPITAL LETTER IOTIFIED E
-0466; C; 0467; # CYRILLIC CAPITAL LETTER LITTLE YUS
-0468; C; 0469; # CYRILLIC CAPITAL LETTER IOTIFIED LITTLE YUS
-046A; C; 046B; # CYRILLIC CAPITAL LETTER BIG YUS
-046C; C; 046D; # CYRILLIC CAPITAL LETTER IOTIFIED BIG YUS
-046E; C; 046F; # CYRILLIC CAPITAL LETTER KSI
-0470; C; 0471; # CYRILLIC CAPITAL LETTER PSI
-0472; C; 0473; # CYRILLIC CAPITAL LETTER FITA
-0474; C; 0475; # CYRILLIC CAPITAL LETTER IZHITSA
-0476; C; 0477; # CYRILLIC CAPITAL LETTER IZHITSA WITH DOUBLE GRAVE ACCENT
-0478; C; 0479; # CYRILLIC CAPITAL LETTER UK
-047A; C; 047B; # CYRILLIC CAPITAL LETTER ROUND OMEGA
-047C; C; 047D; # CYRILLIC CAPITAL LETTER OMEGA WITH TITLO
-047E; C; 047F; # CYRILLIC CAPITAL LETTER OT
-0480; C; 0481; # CYRILLIC CAPITAL LETTER KOPPA
-048A; C; 048B; # CYRILLIC CAPITAL LETTER SHORT I WITH TAIL
-048C; C; 048D; # CYRILLIC CAPITAL LETTER SEMISOFT SIGN
-048E; C; 048F; # CYRILLIC CAPITAL LETTER ER WITH TICK
-0490; C; 0491; # CYRILLIC CAPITAL LETTER GHE WITH UPTURN
-0492; C; 0493; # CYRILLIC CAPITAL LETTER GHE WITH STROKE
-0494; C; 0495; # CYRILLIC CAPITAL LETTER GHE WITH MIDDLE HOOK
-0496; C; 0497; # CYRILLIC CAPITAL LETTER ZHE WITH DESCENDER
-0498; C; 0499; # CYRILLIC CAPITAL LETTER ZE WITH DESCENDER
-049A; C; 049B; # CYRILLIC CAPITAL LETTER KA WITH DESCENDER
-049C; C; 049D; # CYRILLIC CAPITAL LETTER KA WITH VERTICAL STROKE
-049E; C; 049F; # CYRILLIC CAPITAL LETTER KA WITH STROKE
-04A0; C; 04A1; # CYRILLIC CAPITAL LETTER BASHKIR KA
-04A2; C; 04A3; # CYRILLIC CAPITAL LETTER EN WITH DESCENDER
-04A4; C; 04A5; # CYRILLIC CAPITAL LIGATURE EN GHE
-04A6; C; 04A7; # CYRILLIC CAPITAL LETTER PE WITH MIDDLE HOOK
-04A8; C; 04A9; # CYRILLIC CAPITAL LETTER ABKHASIAN HA
-04AA; C; 04AB; # CYRILLIC CAPITAL LETTER ES WITH DESCENDER
-04AC; C; 04AD; # CYRILLIC CAPITAL LETTER TE WITH DESCENDER
-04AE; C; 04AF; # CYRILLIC CAPITAL LETTER STRAIGHT U
-04B0; C; 04B1; # CYRILLIC CAPITAL LETTER STRAIGHT U WITH STROKE
-04B2; C; 04B3; # CYRILLIC CAPITAL LETTER HA WITH DESCENDER
-04B4; C; 04B5; # CYRILLIC CAPITAL LIGATURE TE TSE
-04B6; C; 04B7; # CYRILLIC CAPITAL LETTER CHE WITH DESCENDER
-04B8; C; 04B9; # CYRILLIC CAPITAL LETTER CHE WITH VERTICAL STROKE
-04BA; C; 04BB; # CYRILLIC CAPITAL LETTER SHHA
-04BC; C; 04BD; # CYRILLIC CAPITAL LETTER ABKHASIAN CHE
-04BE; C; 04BF; # CYRILLIC CAPITAL LETTER ABKHASIAN CHE WITH DESCENDER
-04C1; C; 04C2; # CYRILLIC CAPITAL LETTER ZHE WITH BREVE
-04C3; C; 04C4; # CYRILLIC CAPITAL LETTER KA WITH HOOK
-04C5; C; 04C6; # CYRILLIC CAPITAL LETTER EL WITH TAIL
-04C7; C; 04C8; # CYRILLIC CAPITAL LETTER EN WITH HOOK
-04C9; C; 04CA; # CYRILLIC CAPITAL LETTER EN WITH TAIL
-04CB; C; 04CC; # CYRILLIC CAPITAL LETTER KHAKASSIAN CHE
-04CD; C; 04CE; # CYRILLIC CAPITAL LETTER EM WITH TAIL
-04D0; C; 04D1; # CYRILLIC CAPITAL LETTER A WITH BREVE
-04D2; C; 04D3; # CYRILLIC CAPITAL LETTER A WITH DIAERESIS
-04D4; C; 04D5; # CYRILLIC CAPITAL LIGATURE A IE
-04D6; C; 04D7; # CYRILLIC CAPITAL LETTER IE WITH BREVE
-04D8; C; 04D9; # CYRILLIC CAPITAL LETTER SCHWA
-04DA; C; 04DB; # CYRILLIC CAPITAL LETTER SCHWA WITH DIAERESIS
-04DC; C; 04DD; # CYRILLIC CAPITAL LETTER ZHE WITH DIAERESIS
-04DE; C; 04DF; # CYRILLIC CAPITAL LETTER ZE WITH DIAERESIS
-04E0; C; 04E1; # CYRILLIC CAPITAL LETTER ABKHASIAN DZE
-04E2; C; 04E3; # CYRILLIC CAPITAL LETTER I WITH MACRON
-04E4; C; 04E5; # CYRILLIC CAPITAL LETTER I WITH DIAERESIS
-04E6; C; 04E7; # CYRILLIC CAPITAL LETTER O WITH DIAERESIS
-04E8; C; 04E9; # CYRILLIC CAPITAL LETTER BARRED O
-04EA; C; 04EB; # CYRILLIC CAPITAL LETTER BARRED O WITH DIAERESIS
-04EC; C; 04ED; # CYRILLIC CAPITAL LETTER E WITH DIAERESIS
-04EE; C; 04EF; # CYRILLIC CAPITAL LETTER U WITH MACRON
-04F0; C; 04F1; # CYRILLIC CAPITAL LETTER U WITH DIAERESIS
-04F2; C; 04F3; # CYRILLIC CAPITAL LETTER U WITH DOUBLE ACUTE
-04F4; C; 04F5; # CYRILLIC CAPITAL LETTER CHE WITH DIAERESIS
-04F6; C; 04F7; # CYRILLIC CAPITAL LETTER GHE WITH DESCENDER
-04F8; C; 04F9; # CYRILLIC CAPITAL LETTER YERU WITH DIAERESIS
-0500; C; 0501; # CYRILLIC CAPITAL LETTER KOMI DE
-0502; C; 0503; # CYRILLIC CAPITAL LETTER KOMI DJE
-0504; C; 0505; # CYRILLIC CAPITAL LETTER KOMI ZJE
-0506; C; 0507; # CYRILLIC CAPITAL LETTER KOMI DZJE
-0508; C; 0509; # CYRILLIC CAPITAL LETTER KOMI LJE
-050A; C; 050B; # CYRILLIC CAPITAL LETTER KOMI NJE
-050C; C; 050D; # CYRILLIC CAPITAL LETTER KOMI SJE
-050E; C; 050F; # CYRILLIC CAPITAL LETTER KOMI TJE
-0531; C; 0561; # ARMENIAN CAPITAL LETTER AYB
-0532; C; 0562; # ARMENIAN CAPITAL LETTER BEN
-0533; C; 0563; # ARMENIAN CAPITAL LETTER GIM
-0534; C; 0564; # ARMENIAN CAPITAL LETTER DA
-0535; C; 0565; # ARMENIAN CAPITAL LETTER ECH
-0536; C; 0566; # ARMENIAN CAPITAL LETTER ZA
-0537; C; 0567; # ARMENIAN CAPITAL LETTER EH
-0538; C; 0568; # ARMENIAN CAPITAL LETTER ET
-0539; C; 0569; # ARMENIAN CAPITAL LETTER TO
-053A; C; 056A; # ARMENIAN CAPITAL LETTER ZHE
-053B; C; 056B; # ARMENIAN CAPITAL LETTER INI
-053C; C; 056C; # ARMENIAN CAPITAL LETTER LIWN
-053D; C; 056D; # ARMENIAN CAPITAL LETTER XEH
-053E; C; 056E; # ARMENIAN CAPITAL LETTER CA
-053F; C; 056F; # ARMENIAN CAPITAL LETTER KEN
-0540; C; 0570; # ARMENIAN CAPITAL LETTER HO
-0541; C; 0571; # ARMENIAN CAPITAL LETTER JA
-0542; C; 0572; # ARMENIAN CAPITAL LETTER GHAD
-0543; C; 0573; # ARMENIAN CAPITAL LETTER CHEH
-0544; C; 0574; # ARMENIAN CAPITAL LETTER MEN
-0545; C; 0575; # ARMENIAN CAPITAL LETTER YI
-0546; C; 0576; # ARMENIAN CAPITAL LETTER NOW
-0547; C; 0577; # ARMENIAN CAPITAL LETTER SHA
-0548; C; 0578; # ARMENIAN CAPITAL LETTER VO
-0549; C; 0579; # ARMENIAN CAPITAL LETTER CHA
-054A; C; 057A; # ARMENIAN CAPITAL LETTER PEH
-054B; C; 057B; # ARMENIAN CAPITAL LETTER JHEH
-054C; C; 057C; # ARMENIAN CAPITAL LETTER RA
-054D; C; 057D; # ARMENIAN CAPITAL LETTER SEH
-054E; C; 057E; # ARMENIAN CAPITAL LETTER VEW
-054F; C; 057F; # ARMENIAN CAPITAL LETTER TIWN
-0550; C; 0580; # ARMENIAN CAPITAL LETTER REH
-0551; C; 0581; # ARMENIAN CAPITAL LETTER CO
-0552; C; 0582; # ARMENIAN CAPITAL LETTER YIWN
-0553; C; 0583; # ARMENIAN CAPITAL LETTER PIWR
-0554; C; 0584; # ARMENIAN CAPITAL LETTER KEH
-0555; C; 0585; # ARMENIAN CAPITAL LETTER OH
-0556; C; 0586; # ARMENIAN CAPITAL LETTER FEH
-0587; F; 0565 0582; # ARMENIAN SMALL LIGATURE ECH YIWN
-10A0; C; 2D00; # GEORGIAN CAPITAL LETTER AN
-10A1; C; 2D01; # GEORGIAN CAPITAL LETTER BAN
-10A2; C; 2D02; # GEORGIAN CAPITAL LETTER GAN
-10A3; C; 2D03; # GEORGIAN CAPITAL LETTER DON
-10A4; C; 2D04; # GEORGIAN CAPITAL LETTER EN
-10A5; C; 2D05; # GEORGIAN CAPITAL LETTER VIN
-10A6; C; 2D06; # GEORGIAN CAPITAL LETTER ZEN
-10A7; C; 2D07; # GEORGIAN CAPITAL LETTER TAN
-10A8; C; 2D08; # GEORGIAN CAPITAL LETTER IN
-10A9; C; 2D09; # GEORGIAN CAPITAL LETTER KAN
-10AA; C; 2D0A; # GEORGIAN CAPITAL LETTER LAS
-10AB; C; 2D0B; # GEORGIAN CAPITAL LETTER MAN
-10AC; C; 2D0C; # GEORGIAN CAPITAL LETTER NAR
-10AD; C; 2D0D; # GEORGIAN CAPITAL LETTER ON
-10AE; C; 2D0E; # GEORGIAN CAPITAL LETTER PAR
-10AF; C; 2D0F; # GEORGIAN CAPITAL LETTER ZHAR
-10B0; C; 2D10; # GEORGIAN CAPITAL LETTER RAE
-10B1; C; 2D11; # GEORGIAN CAPITAL LETTER SAN
-10B2; C; 2D12; # GEORGIAN CAPITAL LETTER TAR
-10B3; C; 2D13; # GEORGIAN CAPITAL LETTER UN
-10B4; C; 2D14; # GEORGIAN CAPITAL LETTER PHAR
-10B5; C; 2D15; # GEORGIAN CAPITAL LETTER KHAR
-10B6; C; 2D16; # GEORGIAN CAPITAL LETTER GHAN
-10B7; C; 2D17; # GEORGIAN CAPITAL LETTER QAR
-10B8; C; 2D18; # GEORGIAN CAPITAL LETTER SHIN
-10B9; C; 2D19; # GEORGIAN CAPITAL LETTER CHIN
-10BA; C; 2D1A; # GEORGIAN CAPITAL LETTER CAN
-10BB; C; 2D1B; # GEORGIAN CAPITAL LETTER JIL
-10BC; C; 2D1C; # GEORGIAN CAPITAL LETTER CIL
-10BD; C; 2D1D; # GEORGIAN CAPITAL LETTER CHAR
-10BE; C; 2D1E; # GEORGIAN CAPITAL LETTER XAN
-10BF; C; 2D1F; # GEORGIAN CAPITAL LETTER JHAN
-10C0; C; 2D20; # GEORGIAN CAPITAL LETTER HAE
-10C1; C; 2D21; # GEORGIAN CAPITAL LETTER HE
-10C2; C; 2D22; # GEORGIAN CAPITAL LETTER HIE
-10C3; C; 2D23; # GEORGIAN CAPITAL LETTER WE
-10C4; C; 2D24; # GEORGIAN CAPITAL LETTER HAR
-10C5; C; 2D25; # GEORGIAN CAPITAL LETTER HOE
-1E00; C; 1E01; # LATIN CAPITAL LETTER A WITH RING BELOW
-1E02; C; 1E03; # LATIN CAPITAL LETTER B WITH DOT ABOVE
-1E04; C; 1E05; # LATIN CAPITAL LETTER B WITH DOT BELOW
-1E06; C; 1E07; # LATIN CAPITAL LETTER B WITH LINE BELOW
-1E08; C; 1E09; # LATIN CAPITAL LETTER C WITH CEDILLA AND ACUTE
-1E0A; C; 1E0B; # LATIN CAPITAL LETTER D WITH DOT ABOVE
-1E0C; C; 1E0D; # LATIN CAPITAL LETTER D WITH DOT BELOW
-1E0E; C; 1E0F; # LATIN CAPITAL LETTER D WITH LINE BELOW
-1E10; C; 1E11; # LATIN CAPITAL LETTER D WITH CEDILLA
-1E12; C; 1E13; # LATIN CAPITAL LETTER D WITH CIRCUMFLEX BELOW
-1E14; C; 1E15; # LATIN CAPITAL LETTER E WITH MACRON AND GRAVE
-1E16; C; 1E17; # LATIN CAPITAL LETTER E WITH MACRON AND ACUTE
-1E18; C; 1E19; # LATIN CAPITAL LETTER E WITH CIRCUMFLEX BELOW
-1E1A; C; 1E1B; # LATIN CAPITAL LETTER E WITH TILDE BELOW
-1E1C; C; 1E1D; # LATIN CAPITAL LETTER E WITH CEDILLA AND BREVE
-1E1E; C; 1E1F; # LATIN CAPITAL LETTER F WITH DOT ABOVE
-1E20; C; 1E21; # LATIN CAPITAL LETTER G WITH MACRON
-1E22; C; 1E23; # LATIN CAPITAL LETTER H WITH DOT ABOVE
-1E24; C; 1E25; # LATIN CAPITAL LETTER H WITH DOT BELOW
-1E26; C; 1E27; # LATIN CAPITAL LETTER H WITH DIAERESIS
-1E28; C; 1E29; # LATIN CAPITAL LETTER H WITH CEDILLA
-1E2A; C; 1E2B; # LATIN CAPITAL LETTER H WITH BREVE BELOW
-1E2C; C; 1E2D; # LATIN CAPITAL LETTER I WITH TILDE BELOW
-1E2E; C; 1E2F; # LATIN CAPITAL LETTER I WITH DIAERESIS AND ACUTE
-1E30; C; 1E31; # LATIN CAPITAL LETTER K WITH ACUTE
-1E32; C; 1E33; # LATIN CAPITAL LETTER K WITH DOT BELOW
-1E34; C; 1E35; # LATIN CAPITAL LETTER K WITH LINE BELOW
-1E36; C; 1E37; # LATIN CAPITAL LETTER L WITH DOT BELOW
-1E38; C; 1E39; # LATIN CAPITAL LETTER L WITH DOT BELOW AND MACRON
-1E3A; C; 1E3B; # LATIN CAPITAL LETTER L WITH LINE BELOW
-1E3C; C; 1E3D; # LATIN CAPITAL LETTER L WITH CIRCUMFLEX BELOW
-1E3E; C; 1E3F; # LATIN CAPITAL LETTER M WITH ACUTE
-1E40; C; 1E41; # LATIN CAPITAL LETTER M WITH DOT ABOVE
-1E42; C; 1E43; # LATIN CAPITAL LETTER M WITH DOT BELOW
-1E44; C; 1E45; # LATIN CAPITAL LETTER N WITH DOT ABOVE
-1E46; C; 1E47; # LATIN CAPITAL LETTER N WITH DOT BELOW
-1E48; C; 1E49; # LATIN CAPITAL LETTER N WITH LINE BELOW
-1E4A; C; 1E4B; # LATIN CAPITAL LETTER N WITH CIRCUMFLEX BELOW
-1E4C; C; 1E4D; # LATIN CAPITAL LETTER O WITH TILDE AND ACUTE
-1E4E; C; 1E4F; # LATIN CAPITAL LETTER O WITH TILDE AND DIAERESIS
-1E50; C; 1E51; # LATIN CAPITAL LETTER O WITH MACRON AND GRAVE
-1E52; C; 1E53; # LATIN CAPITAL LETTER O WITH MACRON AND ACUTE
-1E54; C; 1E55; # LATIN CAPITAL LETTER P WITH ACUTE
-1E56; C; 1E57; # LATIN CAPITAL LETTER P WITH DOT ABOVE
-1E58; C; 1E59; # LATIN CAPITAL LETTER R WITH DOT ABOVE
-1E5A; C; 1E5B; # LATIN CAPITAL LETTER R WITH DOT BELOW
-1E5C; C; 1E5D; # LATIN CAPITAL LETTER R WITH DOT BELOW AND MACRON
-1E5E; C; 1E5F; # LATIN CAPITAL LETTER R WITH LINE BELOW
-1E60; C; 1E61; # LATIN CAPITAL LETTER S WITH DOT ABOVE
-1E62; C; 1E63; # LATIN CAPITAL LETTER S WITH DOT BELOW
-1E64; C; 1E65; # LATIN CAPITAL LETTER S WITH ACUTE AND DOT ABOVE
-1E66; C; 1E67; # LATIN CAPITAL LETTER S WITH CARON AND DOT ABOVE
-1E68; C; 1E69; # LATIN CAPITAL LETTER S WITH DOT BELOW AND DOT ABOVE
-1E6A; C; 1E6B; # LATIN CAPITAL LETTER T WITH DOT ABOVE
-1E6C; C; 1E6D; # LATIN CAPITAL LETTER T WITH DOT BELOW
-1E6E; C; 1E6F; # LATIN CAPITAL LETTER T WITH LINE BELOW
-1E70; C; 1E71; # LATIN CAPITAL LETTER T WITH CIRCUMFLEX BELOW
-1E72; C; 1E73; # LATIN CAPITAL LETTER U WITH DIAERESIS BELOW
-1E74; C; 1E75; # LATIN CAPITAL LETTER U WITH TILDE BELOW
-1E76; C; 1E77; # LATIN CAPITAL LETTER U WITH CIRCUMFLEX BELOW
-1E78; C; 1E79; # LATIN CAPITAL LETTER U WITH TILDE AND ACUTE
-1E7A; C; 1E7B; # LATIN CAPITAL LETTER U WITH MACRON AND DIAERESIS
-1E7C; C; 1E7D; # LATIN CAPITAL LETTER V WITH TILDE
-1E7E; C; 1E7F; # LATIN CAPITAL LETTER V WITH DOT BELOW
-1E80; C; 1E81; # LATIN CAPITAL LETTER W WITH GRAVE
-1E82; C; 1E83; # LATIN CAPITAL LETTER W WITH ACUTE
-1E84; C; 1E85; # LATIN CAPITAL LETTER W WITH DIAERESIS
-1E86; C; 1E87; # LATIN CAPITAL LETTER W WITH DOT ABOVE
-1E88; C; 1E89; # LATIN CAPITAL LETTER W WITH DOT BELOW
-1E8A; C; 1E8B; # LATIN CAPITAL LETTER X WITH DOT ABOVE
-1E8C; C; 1E8D; # LATIN CAPITAL LETTER X WITH DIAERESIS
-1E8E; C; 1E8F; # LATIN CAPITAL LETTER Y WITH DOT ABOVE
-1E90; C; 1E91; # LATIN CAPITAL LETTER Z WITH CIRCUMFLEX
-1E92; C; 1E93; # LATIN CAPITAL LETTER Z WITH DOT BELOW
-1E94; C; 1E95; # LATIN CAPITAL LETTER Z WITH LINE BELOW
-1E96; F; 0068 0331; # LATIN SMALL LETTER H WITH LINE BELOW
-1E97; F; 0074 0308; # LATIN SMALL LETTER T WITH DIAERESIS
-1E98; F; 0077 030A; # LATIN SMALL LETTER W WITH RING ABOVE
-1E99; F; 0079 030A; # LATIN SMALL LETTER Y WITH RING ABOVE
-1E9A; F; 0061 02BE; # LATIN SMALL LETTER A WITH RIGHT HALF RING
-1E9B; C; 1E61; # LATIN SMALL LETTER LONG S WITH DOT ABOVE
-1EA0; C; 1EA1; # LATIN CAPITAL LETTER A WITH DOT BELOW
-1EA2; C; 1EA3; # LATIN CAPITAL LETTER A WITH HOOK ABOVE
-1EA4; C; 1EA5; # LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND ACUTE
-1EA6; C; 1EA7; # LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND GRAVE
-1EA8; C; 1EA9; # LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND HOOK ABOVE
-1EAA; C; 1EAB; # LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND TILDE
-1EAC; C; 1EAD; # LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND DOT BELOW
-1EAE; C; 1EAF; # LATIN CAPITAL LETTER A WITH BREVE AND ACUTE
-1EB0; C; 1EB1; # LATIN CAPITAL LETTER A WITH BREVE AND GRAVE
-1EB2; C; 1EB3; # LATIN CAPITAL LETTER A WITH BREVE AND HOOK ABOVE
-1EB4; C; 1EB5; # LATIN CAPITAL LETTER A WITH BREVE AND TILDE
-1EB6; C; 1EB7; # LATIN CAPITAL LETTER A WITH BREVE AND DOT BELOW
-1EB8; C; 1EB9; # LATIN CAPITAL LETTER E WITH DOT BELOW
-1EBA; C; 1EBB; # LATIN CAPITAL LETTER E WITH HOOK ABOVE
-1EBC; C; 1EBD; # LATIN CAPITAL LETTER E WITH TILDE
-1EBE; C; 1EBF; # LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND ACUTE
-1EC0; C; 1EC1; # LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND GRAVE
-1EC2; C; 1EC3; # LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND HOOK ABOVE
-1EC4; C; 1EC5; # LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND TILDE
-1EC6; C; 1EC7; # LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND DOT BELOW
-1EC8; C; 1EC9; # LATIN CAPITAL LETTER I WITH HOOK ABOVE
-1ECA; C; 1ECB; # LATIN CAPITAL LETTER I WITH DOT BELOW
-1ECC; C; 1ECD; # LATIN CAPITAL LETTER O WITH DOT BELOW
-1ECE; C; 1ECF; # LATIN CAPITAL LETTER O WITH HOOK ABOVE
-1ED0; C; 1ED1; # LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND ACUTE
-1ED2; C; 1ED3; # LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND GRAVE
-1ED4; C; 1ED5; # LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND HOOK ABOVE
-1ED6; C; 1ED7; # LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND TILDE
-1ED8; C; 1ED9; # LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND DOT BELOW
-1EDA; C; 1EDB; # LATIN CAPITAL LETTER O WITH HORN AND ACUTE
-1EDC; C; 1EDD; # LATIN CAPITAL LETTER O WITH HORN AND GRAVE
-1EDE; C; 1EDF; # LATIN CAPITAL LETTER O WITH HORN AND HOOK ABOVE
-1EE0; C; 1EE1; # LATIN CAPITAL LETTER O WITH HORN AND TILDE
-1EE2; C; 1EE3; # LATIN CAPITAL LETTER O WITH HORN AND DOT BELOW
-1EE4; C; 1EE5; # LATIN CAPITAL LETTER U WITH DOT BELOW
-1EE6; C; 1EE7; # LATIN CAPITAL LETTER U WITH HOOK ABOVE
-1EE8; C; 1EE9; # LATIN CAPITAL LETTER U WITH HORN AND ACUTE
-1EEA; C; 1EEB; # LATIN CAPITAL LETTER U WITH HORN AND GRAVE
-1EEC; C; 1EED; # LATIN CAPITAL LETTER U WITH HORN AND HOOK ABOVE
-1EEE; C; 1EEF; # LATIN CAPITAL LETTER U WITH HORN AND TILDE
-1EF0; C; 1EF1; # LATIN CAPITAL LETTER U WITH HORN AND DOT BELOW
-1EF2; C; 1EF3; # LATIN CAPITAL LETTER Y WITH GRAVE
-1EF4; C; 1EF5; # LATIN CAPITAL LETTER Y WITH DOT BELOW
-1EF6; C; 1EF7; # LATIN CAPITAL LETTER Y WITH HOOK ABOVE
-1EF8; C; 1EF9; # LATIN CAPITAL LETTER Y WITH TILDE
-1F08; C; 1F00; # GREEK CAPITAL LETTER ALPHA WITH PSILI
-1F09; C; 1F01; # GREEK CAPITAL LETTER ALPHA WITH DASIA
-1F0A; C; 1F02; # GREEK CAPITAL LETTER ALPHA WITH PSILI AND VARIA
-1F0B; C; 1F03; # GREEK CAPITAL LETTER ALPHA WITH DASIA AND VARIA
-1F0C; C; 1F04; # GREEK CAPITAL LETTER ALPHA WITH PSILI AND OXIA
-1F0D; C; 1F05; # GREEK CAPITAL LETTER ALPHA WITH DASIA AND OXIA
-1F0E; C; 1F06; # GREEK CAPITAL LETTER ALPHA WITH PSILI AND PERISPOMENI
-1F0F; C; 1F07; # GREEK CAPITAL LETTER ALPHA WITH DASIA AND PERISPOMENI
-1F18; C; 1F10; # GREEK CAPITAL LETTER EPSILON WITH PSILI
-1F19; C; 1F11; # GREEK CAPITAL LETTER EPSILON WITH DASIA
-1F1A; C; 1F12; # GREEK CAPITAL LETTER EPSILON WITH PSILI AND VARIA
-1F1B; C; 1F13; # GREEK CAPITAL LETTER EPSILON WITH DASIA AND VARIA
-1F1C; C; 1F14; # GREEK CAPITAL LETTER EPSILON WITH PSILI AND OXIA
-1F1D; C; 1F15; # GREEK CAPITAL LETTER EPSILON WITH DASIA AND OXIA
-1F28; C; 1F20; # GREEK CAPITAL LETTER ETA WITH PSILI
-1F29; C; 1F21; # GREEK CAPITAL LETTER ETA WITH DASIA
-1F2A; C; 1F22; # GREEK CAPITAL LETTER ETA WITH PSILI AND VARIA
-1F2B; C; 1F23; # GREEK CAPITAL LETTER ETA WITH DASIA AND VARIA
-1F2C; C; 1F24; # GREEK CAPITAL LETTER ETA WITH PSILI AND OXIA
-1F2D; C; 1F25; # GREEK CAPITAL LETTER ETA WITH DASIA AND OXIA
-1F2E; C; 1F26; # GREEK CAPITAL LETTER ETA WITH PSILI AND PERISPOMENI
-1F2F; C; 1F27; # GREEK CAPITAL LETTER ETA WITH DASIA AND PERISPOMENI
-1F38; C; 1F30; # GREEK CAPITAL LETTER IOTA WITH PSILI
-1F39; C; 1F31; # GREEK CAPITAL LETTER IOTA WITH DASIA
-1F3A; C; 1F32; # GREEK CAPITAL LETTER IOTA WITH PSILI AND VARIA
-1F3B; C; 1F33; # GREEK CAPITAL LETTER IOTA WITH DASIA AND VARIA
-1F3C; C; 1F34; # GREEK CAPITAL LETTER IOTA WITH PSILI AND OXIA
-1F3D; C; 1F35; # GREEK CAPITAL LETTER IOTA WITH DASIA AND OXIA
-1F3E; C; 1F36; # GREEK CAPITAL LETTER IOTA WITH PSILI AND PERISPOMENI
-1F3F; C; 1F37; # GREEK CAPITAL LETTER IOTA WITH DASIA AND PERISPOMENI
-1F48; C; 1F40; # GREEK CAPITAL LETTER OMICRON WITH PSILI
-1F49; C; 1F41; # GREEK CAPITAL LETTER OMICRON WITH DASIA
-1F4A; C; 1F42; # GREEK CAPITAL LETTER OMICRON WITH PSILI AND VARIA
-1F4B; C; 1F43; # GREEK CAPITAL LETTER OMICRON WITH DASIA AND VARIA
-1F4C; C; 1F44; # GREEK CAPITAL LETTER OMICRON WITH PSILI AND OXIA
-1F4D; C; 1F45; # GREEK CAPITAL LETTER OMICRON WITH DASIA AND OXIA
-1F50; F; 03C5 0313; # GREEK SMALL LETTER UPSILON WITH PSILI
-1F52; F; 03C5 0313 0300; # GREEK SMALL LETTER UPSILON WITH PSILI AND VARIA
-1F54; F; 03C5 0313 0301; # GREEK SMALL LETTER UPSILON WITH PSILI AND OXIA
-1F56; F; 03C5 0313 0342; # GREEK SMALL LETTER UPSILON WITH PSILI AND PERISPOMENI
-1F59; C; 1F51; # GREEK CAPITAL LETTER UPSILON WITH DASIA
-1F5B; C; 1F53; # GREEK CAPITAL LETTER UPSILON WITH DASIA AND VARIA
-1F5D; C; 1F55; # GREEK CAPITAL LETTER UPSILON WITH DASIA AND OXIA
-1F5F; C; 1F57; # GREEK CAPITAL LETTER UPSILON WITH DASIA AND PERISPOMENI
-1F68; C; 1F60; # GREEK CAPITAL LETTER OMEGA WITH PSILI
-1F69; C; 1F61; # GREEK CAPITAL LETTER OMEGA WITH DASIA
-1F6A; C; 1F62; # GREEK CAPITAL LETTER OMEGA WITH PSILI AND VARIA
-1F6B; C; 1F63; # GREEK CAPITAL LETTER OMEGA WITH DASIA AND VARIA
-1F6C; C; 1F64; # GREEK CAPITAL LETTER OMEGA WITH PSILI AND OXIA
-1F6D; C; 1F65; # GREEK CAPITAL LETTER OMEGA WITH DASIA AND OXIA
-1F6E; C; 1F66; # GREEK CAPITAL LETTER OMEGA WITH PSILI AND PERISPOMENI
-1F6F; C; 1F67; # GREEK CAPITAL LETTER OMEGA WITH DASIA AND PERISPOMENI
-1F80; F; 1F00 03B9; # GREEK SMALL LETTER ALPHA WITH PSILI AND YPOGEGRAMMENI
-1F81; F; 1F01 03B9; # GREEK SMALL LETTER ALPHA WITH DASIA AND YPOGEGRAMMENI
-1F82; F; 1F02 03B9; # GREEK SMALL LETTER ALPHA WITH PSILI AND VARIA AND YPOGEGRAMMENI
-1F83; F; 1F03 03B9; # GREEK SMALL LETTER ALPHA WITH DASIA AND VARIA AND YPOGEGRAMMENI
-1F84; F; 1F04 03B9; # GREEK SMALL LETTER ALPHA WITH PSILI AND OXIA AND YPOGEGRAMMENI
-1F85; F; 1F05 03B9; # GREEK SMALL LETTER ALPHA WITH DASIA AND OXIA AND YPOGEGRAMMENI
-1F86; F; 1F06 03B9; # GREEK SMALL LETTER ALPHA WITH PSILI AND PERISPOMENI AND YPOGEGRAMMENI
-1F87; F; 1F07 03B9; # GREEK SMALL LETTER ALPHA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI
-1F88; F; 1F00 03B9; # GREEK CAPITAL LETTER ALPHA WITH PSILI AND PROSGEGRAMMENI
-1F88; S; 1F80; # GREEK CAPITAL LETTER ALPHA WITH PSILI AND PROSGEGRAMMENI
-1F89; F; 1F01 03B9; # GREEK CAPITAL LETTER ALPHA WITH DASIA AND PROSGEGRAMMENI
-1F89; S; 1F81; # GREEK CAPITAL LETTER ALPHA WITH DASIA AND PROSGEGRAMMENI
-1F8A; F; 1F02 03B9; # GREEK CAPITAL LETTER ALPHA WITH PSILI AND VARIA AND PROSGEGRAMMENI
-1F8A; S; 1F82; # GREEK CAPITAL LETTER ALPHA WITH PSILI AND VARIA AND PROSGEGRAMMENI
-1F8B; F; 1F03 03B9; # GREEK CAPITAL LETTER ALPHA WITH DASIA AND VARIA AND PROSGEGRAMMENI
-1F8B; S; 1F83; # GREEK CAPITAL LETTER ALPHA WITH DASIA AND VARIA AND PROSGEGRAMMENI
-1F8C; F; 1F04 03B9; # GREEK CAPITAL LETTER ALPHA WITH PSILI AND OXIA AND PROSGEGRAMMENI
-1F8C; S; 1F84; # GREEK CAPITAL LETTER ALPHA WITH PSILI AND OXIA AND PROSGEGRAMMENI
-1F8D; F; 1F05 03B9; # GREEK CAPITAL LETTER ALPHA WITH DASIA AND OXIA AND PROSGEGRAMMENI
-1F8D; S; 1F85; # GREEK CAPITAL LETTER ALPHA WITH DASIA AND OXIA AND PROSGEGRAMMENI
-1F8E; F; 1F06 03B9; # GREEK CAPITAL LETTER ALPHA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI
-1F8E; S; 1F86; # GREEK CAPITAL LETTER ALPHA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI
-1F8F; F; 1F07 03B9; # GREEK CAPITAL LETTER ALPHA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI
-1F8F; S; 1F87; # GREEK CAPITAL LETTER ALPHA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI
-1F90; F; 1F20 03B9; # GREEK SMALL LETTER ETA WITH PSILI AND YPOGEGRAMMENI
-1F91; F; 1F21 03B9; # GREEK SMALL LETTER ETA WITH DASIA AND YPOGEGRAMMENI
-1F92; F; 1F22 03B9; # GREEK SMALL LETTER ETA WITH PSILI AND VARIA AND YPOGEGRAMMENI
-1F93; F; 1F23 03B9; # GREEK SMALL LETTER ETA WITH DASIA AND VARIA AND YPOGEGRAMMENI
-1F94; F; 1F24 03B9; # GREEK SMALL LETTER ETA WITH PSILI AND OXIA AND YPOGEGRAMMENI
-1F95; F; 1F25 03B9; # GREEK SMALL LETTER ETA WITH DASIA AND OXIA AND YPOGEGRAMMENI
-1F96; F; 1F26 03B9; # GREEK SMALL LETTER ETA WITH PSILI AND PERISPOMENI AND YPOGEGRAMMENI
-1F97; F; 1F27 03B9; # GREEK SMALL LETTER ETA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI
-1F98; F; 1F20 03B9; # GREEK CAPITAL LETTER ETA WITH PSILI AND PROSGEGRAMMENI
-1F98; S; 1F90; # GREEK CAPITAL LETTER ETA WITH PSILI AND PROSGEGRAMMENI
-1F99; F; 1F21 03B9; # GREEK CAPITAL LETTER ETA WITH DASIA AND PROSGEGRAMMENI
-1F99; S; 1F91; # GREEK CAPITAL LETTER ETA WITH DASIA AND PROSGEGRAMMENI
-1F9A; F; 1F22 03B9; # GREEK CAPITAL LETTER ETA WITH PSILI AND VARIA AND PROSGEGRAMMENI
-1F9A; S; 1F92; # GREEK CAPITAL LETTER ETA WITH PSILI AND VARIA AND PROSGEGRAMMENI
-1F9B; F; 1F23 03B9; # GREEK CAPITAL LETTER ETA WITH DASIA AND VARIA AND PROSGEGRAMMENI
-1F9B; S; 1F93; # GREEK CAPITAL LETTER ETA WITH DASIA AND VARIA AND PROSGEGRAMMENI
-1F9C; F; 1F24 03B9; # GREEK CAPITAL LETTER ETA WITH PSILI AND OXIA AND PROSGEGRAMMENI
-1F9C; S; 1F94; # GREEK CAPITAL LETTER ETA WITH PSILI AND OXIA AND PROSGEGRAMMENI
-1F9D; F; 1F25 03B9; # GREEK CAPITAL LETTER ETA WITH DASIA AND OXIA AND PROSGEGRAMMENI
-1F9D; S; 1F95; # GREEK CAPITAL LETTER ETA WITH DASIA AND OXIA AND PROSGEGRAMMENI
-1F9E; F; 1F26 03B9; # GREEK CAPITAL LETTER ETA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI
-1F9E; S; 1F96; # GREEK CAPITAL LETTER ETA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI
-1F9F; F; 1F27 03B9; # GREEK CAPITAL LETTER ETA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI
-1F9F; S; 1F97; # GREEK CAPITAL LETTER ETA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI
-1FA0; F; 1F60 03B9; # GREEK SMALL LETTER OMEGA WITH PSILI AND YPOGEGRAMMENI
-1FA1; F; 1F61 03B9; # GREEK SMALL LETTER OMEGA WITH DASIA AND YPOGEGRAMMENI
-1FA2; F; 1F62 03B9; # GREEK SMALL LETTER OMEGA WITH PSILI AND VARIA AND YPOGEGRAMMENI
-1FA3; F; 1F63 03B9; # GREEK SMALL LETTER OMEGA WITH DASIA AND VARIA AND YPOGEGRAMMENI
-1FA4; F; 1F64 03B9; # GREEK SMALL LETTER OMEGA WITH PSILI AND OXIA AND YPOGEGRAMMENI
-1FA5; F; 1F65 03B9; # GREEK SMALL LETTER OMEGA WITH DASIA AND OXIA AND YPOGEGRAMMENI
-1FA6; F; 1F66 03B9; # GREEK SMALL LETTER OMEGA WITH PSILI AND PERISPOMENI AND YPOGEGRAMMENI
-1FA7; F; 1F67 03B9; # GREEK SMALL LETTER OMEGA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI
-1FA8; F; 1F60 03B9; # GREEK CAPITAL LETTER OMEGA WITH PSILI AND PROSGEGRAMMENI
-1FA8; S; 1FA0; # GREEK CAPITAL LETTER OMEGA WITH PSILI AND PROSGEGRAMMENI
-1FA9; F; 1F61 03B9; # GREEK CAPITAL LETTER OMEGA WITH DASIA AND PROSGEGRAMMENI
-1FA9; S; 1FA1; # GREEK CAPITAL LETTER OMEGA WITH DASIA AND PROSGEGRAMMENI
-1FAA; F; 1F62 03B9; # GREEK CAPITAL LETTER OMEGA WITH PSILI AND VARIA AND PROSGEGRAMMENI
-1FAA; S; 1FA2; # GREEK CAPITAL LETTER OMEGA WITH PSILI AND VARIA AND PROSGEGRAMMENI
-1FAB; F; 1F63 03B9; # GREEK CAPITAL LETTER OMEGA WITH DASIA AND VARIA AND PROSGEGRAMMENI
-1FAB; S; 1FA3; # GREEK CAPITAL LETTER OMEGA WITH DASIA AND VARIA AND PROSGEGRAMMENI
-1FAC; F; 1F64 03B9; # GREEK CAPITAL LETTER OMEGA WITH PSILI AND OXIA AND PROSGEGRAMMENI
-1FAC; S; 1FA4; # GREEK CAPITAL LETTER OMEGA WITH PSILI AND OXIA AND PROSGEGRAMMENI
-1FAD; F; 1F65 03B9; # GREEK CAPITAL LETTER OMEGA WITH DASIA AND OXIA AND PROSGEGRAMMENI
-1FAD; S; 1FA5; # GREEK CAPITAL LETTER OMEGA WITH DASIA AND OXIA AND PROSGEGRAMMENI
-1FAE; F; 1F66 03B9; # GREEK CAPITAL LETTER OMEGA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI
-1FAE; S; 1FA6; # GREEK CAPITAL LETTER OMEGA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI
-1FAF; F; 1F67 03B9; # GREEK CAPITAL LETTER OMEGA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI
-1FAF; S; 1FA7; # GREEK CAPITAL LETTER OMEGA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI
-1FB2; F; 1F70 03B9; # GREEK SMALL LETTER ALPHA WITH VARIA AND YPOGEGRAMMENI
-1FB3; F; 03B1 03B9; # GREEK SMALL LETTER ALPHA WITH YPOGEGRAMMENI
-1FB4; F; 03AC 03B9; # GREEK SMALL LETTER ALPHA WITH OXIA AND YPOGEGRAMMENI
-1FB6; F; 03B1 0342; # GREEK SMALL LETTER ALPHA WITH PERISPOMENI
-1FB7; F; 03B1 0342 03B9; # GREEK SMALL LETTER ALPHA WITH PERISPOMENI AND YPOGEGRAMMENI
-1FB8; C; 1FB0; # GREEK CAPITAL LETTER ALPHA WITH VRACHY
-1FB9; C; 1FB1; # GREEK CAPITAL LETTER ALPHA WITH MACRON
-1FBA; C; 1F70; # GREEK CAPITAL LETTER ALPHA WITH VARIA
-1FBB; C; 1F71; # GREEK CAPITAL LETTER ALPHA WITH OXIA
-1FBC; F; 03B1 03B9; # GREEK CAPITAL LETTER ALPHA WITH PROSGEGRAMMENI
-1FBC; S; 1FB3; # GREEK CAPITAL LETTER ALPHA WITH PROSGEGRAMMENI
-1FBE; C; 03B9; # GREEK PROSGEGRAMMENI
-1FC2; F; 1F74 03B9; # GREEK SMALL LETTER ETA WITH VARIA AND YPOGEGRAMMENI
-1FC3; F; 03B7 03B9; # GREEK SMALL LETTER ETA WITH YPOGEGRAMMENI
-1FC4; F; 03AE 03B9; # GREEK SMALL LETTER ETA WITH OXIA AND YPOGEGRAMMENI
-1FC6; F; 03B7 0342; # GREEK SMALL LETTER ETA WITH PERISPOMENI
-1FC7; F; 03B7 0342 03B9; # GREEK SMALL LETTER ETA WITH PERISPOMENI AND YPOGEGRAMMENI
-1FC8; C; 1F72; # GREEK CAPITAL LETTER EPSILON WITH VARIA
-1FC9; C; 1F73; # GREEK CAPITAL LETTER EPSILON WITH OXIA
-1FCA; C; 1F74; # GREEK CAPITAL LETTER ETA WITH VARIA
-1FCB; C; 1F75; # GREEK CAPITAL LETTER ETA WITH OXIA
-1FCC; F; 03B7 03B9; # GREEK CAPITAL LETTER ETA WITH PROSGEGRAMMENI
-1FCC; S; 1FC3; # GREEK CAPITAL LETTER ETA WITH PROSGEGRAMMENI
-1FD2; F; 03B9 0308 0300; # GREEK SMALL LETTER IOTA WITH DIALYTIKA AND VARIA
-1FD3; F; 03B9 0308 0301; # GREEK SMALL LETTER IOTA WITH DIALYTIKA AND OXIA
-1FD6; F; 03B9 0342; # GREEK SMALL LETTER IOTA WITH PERISPOMENI
-1FD7; F; 03B9 0308 0342; # GREEK SMALL LETTER IOTA WITH DIALYTIKA AND PERISPOMENI
-1FD8; C; 1FD0; # GREEK CAPITAL LETTER IOTA WITH VRACHY
-1FD9; C; 1FD1; # GREEK CAPITAL LETTER IOTA WITH MACRON
-1FDA; C; 1F76; # GREEK CAPITAL LETTER IOTA WITH VARIA
-1FDB; C; 1F77; # GREEK CAPITAL LETTER IOTA WITH OXIA
-1FE2; F; 03C5 0308 0300; # GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND VARIA
-1FE3; F; 03C5 0308 0301; # GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND OXIA
-1FE4; F; 03C1 0313; # GREEK SMALL LETTER RHO WITH PSILI
-1FE6; F; 03C5 0342; # GREEK SMALL LETTER UPSILON WITH PERISPOMENI
-1FE7; F; 03C5 0308 0342; # GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND PERISPOMENI
-1FE8; C; 1FE0; # GREEK CAPITAL LETTER UPSILON WITH VRACHY
-1FE9; C; 1FE1; # GREEK CAPITAL LETTER UPSILON WITH MACRON
-1FEA; C; 1F7A; # GREEK CAPITAL LETTER UPSILON WITH VARIA
-1FEB; C; 1F7B; # GREEK CAPITAL LETTER UPSILON WITH OXIA
-1FEC; C; 1FE5; # GREEK CAPITAL LETTER RHO WITH DASIA
-1FF2; F; 1F7C 03B9; # GREEK SMALL LETTER OMEGA WITH VARIA AND YPOGEGRAMMENI
-1FF3; F; 03C9 03B9; # GREEK SMALL LETTER OMEGA WITH YPOGEGRAMMENI
-1FF4; F; 03CE 03B9; # GREEK SMALL LETTER OMEGA WITH OXIA AND YPOGEGRAMMENI
-1FF6; F; 03C9 0342; # GREEK SMALL LETTER OMEGA WITH PERISPOMENI
-1FF7; F; 03C9 0342 03B9; # GREEK SMALL LETTER OMEGA WITH PERISPOMENI AND YPOGEGRAMMENI
-1FF8; C; 1F78; # GREEK CAPITAL LETTER OMICRON WITH VARIA
-1FF9; C; 1F79; # GREEK CAPITAL LETTER OMICRON WITH OXIA
-1FFA; C; 1F7C; # GREEK CAPITAL LETTER OMEGA WITH VARIA
-1FFB; C; 1F7D; # GREEK CAPITAL LETTER OMEGA WITH OXIA
-1FFC; F; 03C9 03B9; # GREEK CAPITAL LETTER OMEGA WITH PROSGEGRAMMENI
-1FFC; S; 1FF3; # GREEK CAPITAL LETTER OMEGA WITH PROSGEGRAMMENI
-2126; C; 03C9; # OHM SIGN
-212A; C; 006B; # KELVIN SIGN
-212B; C; 00E5; # ANGSTROM SIGN
-2160; C; 2170; # ROMAN NUMERAL ONE
-2161; C; 2171; # ROMAN NUMERAL TWO
-2162; C; 2172; # ROMAN NUMERAL THREE
-2163; C; 2173; # ROMAN NUMERAL FOUR
-2164; C; 2174; # ROMAN NUMERAL FIVE
-2165; C; 2175; # ROMAN NUMERAL SIX
-2166; C; 2176; # ROMAN NUMERAL SEVEN
-2167; C; 2177; # ROMAN NUMERAL EIGHT
-2168; C; 2178; # ROMAN NUMERAL NINE
-2169; C; 2179; # ROMAN NUMERAL TEN
-216A; C; 217A; # ROMAN NUMERAL ELEVEN
-216B; C; 217B; # ROMAN NUMERAL TWELVE
-216C; C; 217C; # ROMAN NUMERAL FIFTY
-216D; C; 217D; # ROMAN NUMERAL ONE HUNDRED
-216E; C; 217E; # ROMAN NUMERAL FIVE HUNDRED
-216F; C; 217F; # ROMAN NUMERAL ONE THOUSAND
-24B6; C; 24D0; # CIRCLED LATIN CAPITAL LETTER A
-24B7; C; 24D1; # CIRCLED LATIN CAPITAL LETTER B
-24B8; C; 24D2; # CIRCLED LATIN CAPITAL LETTER C
-24B9; C; 24D3; # CIRCLED LATIN CAPITAL LETTER D
-24BA; C; 24D4; # CIRCLED LATIN CAPITAL LETTER E
-24BB; C; 24D5; # CIRCLED LATIN CAPITAL LETTER F
-24BC; C; 24D6; # CIRCLED LATIN CAPITAL LETTER G
-24BD; C; 24D7; # CIRCLED LATIN CAPITAL LETTER H
-24BE; C; 24D8; # CIRCLED LATIN CAPITAL LETTER I
-24BF; C; 24D9; # CIRCLED LATIN CAPITAL LETTER J
-24C0; C; 24DA; # CIRCLED LATIN CAPITAL LETTER K
-24C1; C; 24DB; # CIRCLED LATIN CAPITAL LETTER L
-24C2; C; 24DC; # CIRCLED LATIN CAPITAL LETTER M
-24C3; C; 24DD; # CIRCLED LATIN CAPITAL LETTER N
-24C4; C; 24DE; # CIRCLED LATIN CAPITAL LETTER O
-24C5; C; 24DF; # CIRCLED LATIN CAPITAL LETTER P
-24C6; C; 24E0; # CIRCLED LATIN CAPITAL LETTER Q
-24C7; C; 24E1; # CIRCLED LATIN CAPITAL LETTER R
-24C8; C; 24E2; # CIRCLED LATIN CAPITAL LETTER S
-24C9; C; 24E3; # CIRCLED LATIN CAPITAL LETTER T
-24CA; C; 24E4; # CIRCLED LATIN CAPITAL LETTER U
-24CB; C; 24E5; # CIRCLED LATIN CAPITAL LETTER V
-24CC; C; 24E6; # CIRCLED LATIN CAPITAL LETTER W
-24CD; C; 24E7; # CIRCLED LATIN CAPITAL LETTER X
-24CE; C; 24E8; # CIRCLED LATIN CAPITAL LETTER Y
-24CF; C; 24E9; # CIRCLED LATIN CAPITAL LETTER Z
-2C00; C; 2C30; # GLAGOLITIC CAPITAL LETTER AZU
-2C01; C; 2C31; # GLAGOLITIC CAPITAL LETTER BUKY
-2C02; C; 2C32; # GLAGOLITIC CAPITAL LETTER VEDE
-2C03; C; 2C33; # GLAGOLITIC CAPITAL LETTER GLAGOLI
-2C04; C; 2C34; # GLAGOLITIC CAPITAL LETTER DOBRO
-2C05; C; 2C35; # GLAGOLITIC CAPITAL LETTER YESTU
-2C06; C; 2C36; # GLAGOLITIC CAPITAL LETTER ZHIVETE
-2C07; C; 2C37; # GLAGOLITIC CAPITAL LETTER DZELO
-2C08; C; 2C38; # GLAGOLITIC CAPITAL LETTER ZEMLJA
-2C09; C; 2C39; # GLAGOLITIC CAPITAL LETTER IZHE
-2C0A; C; 2C3A; # GLAGOLITIC CAPITAL LETTER INITIAL IZHE
-2C0B; C; 2C3B; # GLAGOLITIC CAPITAL LETTER I
-2C0C; C; 2C3C; # GLAGOLITIC CAPITAL LETTER DJERVI
-2C0D; C; 2C3D; # GLAGOLITIC CAPITAL LETTER KAKO
-2C0E; C; 2C3E; # GLAGOLITIC CAPITAL LETTER LJUDIJE
-2C0F; C; 2C3F; # GLAGOLITIC CAPITAL LETTER MYSLITE
-2C10; C; 2C40; # GLAGOLITIC CAPITAL LETTER NASHI
-2C11; C; 2C41; # GLAGOLITIC CAPITAL LETTER ONU
-2C12; C; 2C42; # GLAGOLITIC CAPITAL LETTER POKOJI
-2C13; C; 2C43; # GLAGOLITIC CAPITAL LETTER RITSI
-2C14; C; 2C44; # GLAGOLITIC CAPITAL LETTER SLOVO
-2C15; C; 2C45; # GLAGOLITIC CAPITAL LETTER TVRIDO
-2C16; C; 2C46; # GLAGOLITIC CAPITAL LETTER UKU
-2C17; C; 2C47; # GLAGOLITIC CAPITAL LETTER FRITU
-2C18; C; 2C48; # GLAGOLITIC CAPITAL LETTER HERU
-2C19; C; 2C49; # GLAGOLITIC CAPITAL LETTER OTU
-2C1A; C; 2C4A; # GLAGOLITIC CAPITAL LETTER PE
-2C1B; C; 2C4B; # GLAGOLITIC CAPITAL LETTER SHTA
-2C1C; C; 2C4C; # GLAGOLITIC CAPITAL LETTER TSI
-2C1D; C; 2C4D; # GLAGOLITIC CAPITAL LETTER CHRIVI
-2C1E; C; 2C4E; # GLAGOLITIC CAPITAL LETTER SHA
-2C1F; C; 2C4F; # GLAGOLITIC CAPITAL LETTER YERU
-2C20; C; 2C50; # GLAGOLITIC CAPITAL LETTER YERI
-2C21; C; 2C51; # GLAGOLITIC CAPITAL LETTER YATI
-2C22; C; 2C52; # GLAGOLITIC CAPITAL LETTER SPIDERY HA
-2C23; C; 2C53; # GLAGOLITIC CAPITAL LETTER YU
-2C24; C; 2C54; # GLAGOLITIC CAPITAL LETTER SMALL YUS
-2C25; C; 2C55; # GLAGOLITIC CAPITAL LETTER SMALL YUS WITH TAIL
-2C26; C; 2C56; # GLAGOLITIC CAPITAL LETTER YO
-2C27; C; 2C57; # GLAGOLITIC CAPITAL LETTER IOTATED SMALL YUS
-2C28; C; 2C58; # GLAGOLITIC CAPITAL LETTER BIG YUS
-2C29; C; 2C59; # GLAGOLITIC CAPITAL LETTER IOTATED BIG YUS
-2C2A; C; 2C5A; # GLAGOLITIC CAPITAL LETTER FITA
-2C2B; C; 2C5B; # GLAGOLITIC CAPITAL LETTER IZHITSA
-2C2C; C; 2C5C; # GLAGOLITIC CAPITAL LETTER SHTAPIC
-2C2D; C; 2C5D; # GLAGOLITIC CAPITAL LETTER TROKUTASTI A
-2C2E; C; 2C5E; # GLAGOLITIC CAPITAL LETTER LATINATE MYSLITE
-2C80; C; 2C81; # COPTIC CAPITAL LETTER ALFA
-2C82; C; 2C83; # COPTIC CAPITAL LETTER VIDA
-2C84; C; 2C85; # COPTIC CAPITAL LETTER GAMMA
-2C86; C; 2C87; # COPTIC CAPITAL LETTER DALDA
-2C88; C; 2C89; # COPTIC CAPITAL LETTER EIE
-2C8A; C; 2C8B; # COPTIC CAPITAL LETTER SOU
-2C8C; C; 2C8D; # COPTIC CAPITAL LETTER ZATA
-2C8E; C; 2C8F; # COPTIC CAPITAL LETTER HATE
-2C90; C; 2C91; # COPTIC CAPITAL LETTER THETHE
-2C92; C; 2C93; # COPTIC CAPITAL LETTER IAUDA
-2C94; C; 2C95; # COPTIC CAPITAL LETTER KAPA
-2C96; C; 2C97; # COPTIC CAPITAL LETTER LAULA
-2C98; C; 2C99; # COPTIC CAPITAL LETTER MI
-2C9A; C; 2C9B; # COPTIC CAPITAL LETTER NI
-2C9C; C; 2C9D; # COPTIC CAPITAL LETTER KSI
-2C9E; C; 2C9F; # COPTIC CAPITAL LETTER O
-2CA0; C; 2CA1; # COPTIC CAPITAL LETTER PI
-2CA2; C; 2CA3; # COPTIC CAPITAL LETTER RO
-2CA4; C; 2CA5; # COPTIC CAPITAL LETTER SIMA
-2CA6; C; 2CA7; # COPTIC CAPITAL LETTER TAU
-2CA8; C; 2CA9; # COPTIC CAPITAL LETTER UA
-2CAA; C; 2CAB; # COPTIC CAPITAL LETTER FI
-2CAC; C; 2CAD; # COPTIC CAPITAL LETTER KHI
-2CAE; C; 2CAF; # COPTIC CAPITAL LETTER PSI
-2CB0; C; 2CB1; # COPTIC CAPITAL LETTER OOU
-2CB2; C; 2CB3; # COPTIC CAPITAL LETTER DIALECT-P ALEF
-2CB4; C; 2CB5; # COPTIC CAPITAL LETTER OLD COPTIC AIN
-2CB6; C; 2CB7; # COPTIC CAPITAL LETTER CRYPTOGRAMMIC EIE
-2CB8; C; 2CB9; # COPTIC CAPITAL LETTER DIALECT-P KAPA
-2CBA; C; 2CBB; # COPTIC CAPITAL LETTER DIALECT-P NI
-2CBC; C; 2CBD; # COPTIC CAPITAL LETTER CRYPTOGRAMMIC NI
-2CBE; C; 2CBF; # COPTIC CAPITAL LETTER OLD COPTIC OOU
-2CC0; C; 2CC1; # COPTIC CAPITAL LETTER SAMPI
-2CC2; C; 2CC3; # COPTIC CAPITAL LETTER CROSSED SHEI
-2CC4; C; 2CC5; # COPTIC CAPITAL LETTER OLD COPTIC SHEI
-2CC6; C; 2CC7; # COPTIC CAPITAL LETTER OLD COPTIC ESH
-2CC8; C; 2CC9; # COPTIC CAPITAL LETTER AKHMIMIC KHEI
-2CCA; C; 2CCB; # COPTIC CAPITAL LETTER DIALECT-P HORI
-2CCC; C; 2CCD; # COPTIC CAPITAL LETTER OLD COPTIC HORI
-2CCE; C; 2CCF; # COPTIC CAPITAL LETTER OLD COPTIC HA
-2CD0; C; 2CD1; # COPTIC CAPITAL LETTER L-SHAPED HA
-2CD2; C; 2CD3; # COPTIC CAPITAL LETTER OLD COPTIC HEI
-2CD4; C; 2CD5; # COPTIC CAPITAL LETTER OLD COPTIC HAT
-2CD6; C; 2CD7; # COPTIC CAPITAL LETTER OLD COPTIC GANGIA
-2CD8; C; 2CD9; # COPTIC CAPITAL LETTER OLD COPTIC DJA
-2CDA; C; 2CDB; # COPTIC CAPITAL LETTER OLD COPTIC SHIMA
-2CDC; C; 2CDD; # COPTIC CAPITAL LETTER OLD NUBIAN SHIMA
-2CDE; C; 2CDF; # COPTIC CAPITAL LETTER OLD NUBIAN NGI
-2CE0; C; 2CE1; # COPTIC CAPITAL LETTER OLD NUBIAN NYI
-2CE2; C; 2CE3; # COPTIC CAPITAL LETTER OLD NUBIAN WAU
-FB00; F; 0066 0066; # LATIN SMALL LIGATURE FF
-FB01; F; 0066 0069; # LATIN SMALL LIGATURE FI
-FB02; F; 0066 006C; # LATIN SMALL LIGATURE FL
-FB03; F; 0066 0066 0069; # LATIN SMALL LIGATURE FFI
-FB04; F; 0066 0066 006C; # LATIN SMALL LIGATURE FFL
-FB05; F; 0073 0074; # LATIN SMALL LIGATURE LONG S T
-FB06; F; 0073 0074; # LATIN SMALL LIGATURE ST
-FB13; F; 0574 0576; # ARMENIAN SMALL LIGATURE MEN NOW
-FB14; F; 0574 0565; # ARMENIAN SMALL LIGATURE MEN ECH
-FB15; F; 0574 056B; # ARMENIAN SMALL LIGATURE MEN INI
-FB16; F; 057E 0576; # ARMENIAN SMALL LIGATURE VEW NOW
-FB17; F; 0574 056D; # ARMENIAN SMALL LIGATURE MEN XEH
-FF21; C; FF41; # FULLWIDTH LATIN CAPITAL LETTER A
-FF22; C; FF42; # FULLWIDTH LATIN CAPITAL LETTER B
-FF23; C; FF43; # FULLWIDTH LATIN CAPITAL LETTER C
-FF24; C; FF44; # FULLWIDTH LATIN CAPITAL LETTER D
-FF25; C; FF45; # FULLWIDTH LATIN CAPITAL LETTER E
-FF26; C; FF46; # FULLWIDTH LATIN CAPITAL LETTER F
-FF27; C; FF47; # FULLWIDTH LATIN CAPITAL LETTER G
-FF28; C; FF48; # FULLWIDTH LATIN CAPITAL LETTER H
-FF29; C; FF49; # FULLWIDTH LATIN CAPITAL LETTER I
-FF2A; C; FF4A; # FULLWIDTH LATIN CAPITAL LETTER J
-FF2B; C; FF4B; # FULLWIDTH LATIN CAPITAL LETTER K
-FF2C; C; FF4C; # FULLWIDTH LATIN CAPITAL LETTER L
-FF2D; C; FF4D; # FULLWIDTH LATIN CAPITAL LETTER M
-FF2E; C; FF4E; # FULLWIDTH LATIN CAPITAL LETTER N
-FF2F; C; FF4F; # FULLWIDTH LATIN CAPITAL LETTER O
-FF30; C; FF50; # FULLWIDTH LATIN CAPITAL LETTER P
-FF31; C; FF51; # FULLWIDTH LATIN CAPITAL LETTER Q
-FF32; C; FF52; # FULLWIDTH LATIN CAPITAL LETTER R
-FF33; C; FF53; # FULLWIDTH LATIN CAPITAL LETTER S
-FF34; C; FF54; # FULLWIDTH LATIN CAPITAL LETTER T
-FF35; C; FF55; # FULLWIDTH LATIN CAPITAL LETTER U
-FF36; C; FF56; # FULLWIDTH LATIN CAPITAL LETTER V
-FF37; C; FF57; # FULLWIDTH LATIN CAPITAL LETTER W
-FF38; C; FF58; # FULLWIDTH LATIN CAPITAL LETTER X
-FF39; C; FF59; # FULLWIDTH LATIN CAPITAL LETTER Y
-FF3A; C; FF5A; # FULLWIDTH LATIN CAPITAL LETTER Z
-10400; C; 10428; # DESERET CAPITAL LETTER LONG I
-10401; C; 10429; # DESERET CAPITAL LETTER LONG E
-10402; C; 1042A; # DESERET CAPITAL LETTER LONG A
-10403; C; 1042B; # DESERET CAPITAL LETTER LONG AH
-10404; C; 1042C; # DESERET CAPITAL LETTER LONG O
-10405; C; 1042D; # DESERET CAPITAL LETTER LONG OO
-10406; C; 1042E; # DESERET CAPITAL LETTER SHORT I
-10407; C; 1042F; # DESERET CAPITAL LETTER SHORT E
-10408; C; 10430; # DESERET CAPITAL LETTER SHORT A
-10409; C; 10431; # DESERET CAPITAL LETTER SHORT AH
-1040A; C; 10432; # DESERET CAPITAL LETTER SHORT O
-1040B; C; 10433; # DESERET CAPITAL LETTER SHORT OO
-1040C; C; 10434; # DESERET CAPITAL LETTER AY
-1040D; C; 10435; # DESERET CAPITAL LETTER OW
-1040E; C; 10436; # DESERET CAPITAL LETTER WU
-1040F; C; 10437; # DESERET CAPITAL LETTER YEE
-10410; C; 10438; # DESERET CAPITAL LETTER H
-10411; C; 10439; # DESERET CAPITAL LETTER PEE
-10412; C; 1043A; # DESERET CAPITAL LETTER BEE
-10413; C; 1043B; # DESERET CAPITAL LETTER TEE
-10414; C; 1043C; # DESERET CAPITAL LETTER DEE
-10415; C; 1043D; # DESERET CAPITAL LETTER CHEE
-10416; C; 1043E; # DESERET CAPITAL LETTER JEE
-10417; C; 1043F; # DESERET CAPITAL LETTER KAY
-10418; C; 10440; # DESERET CAPITAL LETTER GAY
-10419; C; 10441; # DESERET CAPITAL LETTER EF
-1041A; C; 10442; # DESERET CAPITAL LETTER VEE
-1041B; C; 10443; # DESERET CAPITAL LETTER ETH
-1041C; C; 10444; # DESERET CAPITAL LETTER THEE
-1041D; C; 10445; # DESERET CAPITAL LETTER ES
-1041E; C; 10446; # DESERET CAPITAL LETTER ZEE
-1041F; C; 10447; # DESERET CAPITAL LETTER ESH
-10420; C; 10448; # DESERET CAPITAL LETTER ZHEE
-10421; C; 10449; # DESERET CAPITAL LETTER ER
-10422; C; 1044A; # DESERET CAPITAL LETTER EL
-10423; C; 1044B; # DESERET CAPITAL LETTER EM
-10424; C; 1044C; # DESERET CAPITAL LETTER EN
-10425; C; 1044D; # DESERET CAPITAL LETTER ENG
-10426; C; 1044E; # DESERET CAPITAL LETTER OI
-10427; C; 1044F; # DESERET CAPITAL LETTER EW
+++ /dev/null
-/** \file globbing.c */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-
-#include "physfs.h"
-#include "globbing.h"
-
-/**
- * Please see globbing.h for details.
- *
- * License: this code is public domain. I make no warranty that it is useful,
- * correct, harmless, or environmentally safe.
- *
- * This particular file may be used however you like, including copying it
- * verbatim into a closed-source project, exploiting it commercially, and
- * removing any trace of my name from the source (although I hope you won't
- * do that). I welcome enhancements and corrections to this file, but I do
- * not require you to send me patches if you make changes. This code has
- * NO WARRANTY.
- *
- * Unless otherwise stated, the rest of PhysicsFS falls under the zlib license.
- * Please see LICENSE.txt in the root of the source tree.
- *
- * \author Ryan C. Gordon.
- */
-
-
-static int matchesPattern(const char *fname, const char *wildcard,
- int caseSensitive)
-{
- char x, y;
- const char *fnameptr = fname;
- const char *wildptr = wildcard;
-
- while ((*wildptr) && (*fnameptr))
- {
- y = *wildptr;
- if (y == '*')
- {
- do
- {
- wildptr++; /* skip multiple '*' in a row... */
- } while (*wildptr == '*');
-
- y = (caseSensitive) ? *wildptr : (char) tolower(*wildptr);
-
- while (1)
- {
- x = (caseSensitive) ? *fnameptr : (char) tolower(*fnameptr);
- if ((!x) || (x == y))
- break;
- else
- fnameptr++;
- } /* while */
- } /* if */
-
- else if (y == '?')
- {
- wildptr++;
- fnameptr++;
- } /* else if */
-
- else
- {
- if (caseSensitive)
- x = *fnameptr;
- else
- {
- x = tolower(*fnameptr);
- y = tolower(y);
- } /* if */
-
- wildptr++;
- fnameptr++;
-
- if (x != y)
- return(0);
- } /* else */
- } /* while */
-
- while (*wildptr == '*')
- wildptr++;
-
- return(*fnameptr == *wildptr);
-} /* matchesPattern */
-
-
-char **PHYSFSEXT_enumerateFilesWildcard(const char *dir, const char *wildcard,
- int caseSensitive)
-{
- char **rc = PHYSFS_enumerateFiles(dir);
- char **i = rc;
- char **j;
-
- while (*i != NULL)
- {
- if (matchesPattern(*i, wildcard, caseSensitive))
- i++;
- else
- {
- /* FIXME: This counts on physfs's allocation method not changing! */
- free(*i);
- for (j = i; *j != NULL; j++)
- j[0] = j[1];
- } /* else */
- } /* for */
-
- return(rc);
-} /* PHYSFSEXT_enumerateFilesWildcard */
-
-
-#ifdef TEST_PHYSFSEXT_ENUMERATEFILESWILDCARD
-int main(int argc, char **argv)
-{
- int rc;
- char **flist;
- char **i;
-
- if (argc != 3)
- {
- printf("USAGE: %s <pattern> <caseSen>\n"
- " where <caseSen> is 1 or 0.\n", argv[0]);
- return(1);
- } /* if */
-
- if (!PHYSFS_init(argv[0]))
- {
- fprintf(stderr, "PHYSFS_init(): %s\n", PHYSFS_getLastError());
- return(1);
- } /* if */
-
- if (!PHYSFS_addToSearchPath(".", 1))
- {
- fprintf(stderr, "PHYSFS_addToSearchPath(): %s\n", PHYSFS_getLastError());
- PHYSFS_deinit();
- return(1);
- } /* if */
-
- flist = PHYSFSEXT_enumerateFilesWildcard("/", argv[1], atoi(argv[2]));
- rc = 0;
- for (i = flist; *i; i++)
- {
- printf("%s\n", *i);
- rc++;
- } /* for */
- printf("\n total %d files.\n\n", rc);
-
- PHYSFS_freeList(flist);
- PHYSFS_deinit();
-
- return(0);
-} /* main */
-#endif
-
-/* end of globbing.c ... */
-
+++ /dev/null
-/** \file globbing.h */
-
-/**
- * \mainpage PhysicsFS globbing
- *
- * This is an extension to PhysicsFS to let you search for files with basic
- * wildcard matching, regardless of what sort of filesystem or archive they
- * reside in. It does this by enumerating directories as needed and manually
- * locating matching entries.
- *
- * Usage: Set up PhysicsFS as you normally would, then use
- * PHYSFSEXT_enumerateFilesPattern() when enumerating files. This is just
- * like PHYSFS_enumerateFiles(), but it returns a subset that matches your
- * wildcard pattern. You must call PHYSFS_freeList() on the results, just
- * like you would with PHYSFS_enumerateFiles().
- *
- * License: this code is public domain. I make no warranty that it is useful,
- * correct, harmless, or environmentally safe.
- *
- * This particular file may be used however you like, including copying it
- * verbatim into a closed-source project, exploiting it commercially, and
- * removing any trace of my name from the source (although I hope you won't
- * do that). I welcome enhancements and corrections to this file, but I do
- * not require you to send me patches if you make changes. This code has
- * NO WARRANTY.
- *
- * Unless otherwise stated, the rest of PhysicsFS falls under the zlib license.
- * Please see LICENSE.txt in the root of the source tree.
- *
- * \author Ryan C. Gordon.
- */
-
-
-/**
- * \fn char **PHYSFS_enumerateFilesWildcard(const char *dir, const char *wildcard, int caseSensitive)
- * \brief Get a file listing of a search path's directory.
- *
- * Matching directories are interpolated. That is, if "C:\mydir" is in the
- * search path and contains a directory "savegames" that contains "x.sav",
- * "y.Sav", and "z.txt", and there is also a "C:\userdir" in the search path
- * that has a "savegames" subdirectory with "w.sav", then the following code:
- *
- * \code
- * char **rc = PHYSFS_enumerateFilesWildcard("savegames", "*.sav", 0);
- * char **i;
- *
- * for (i = rc; *i != NULL; i++)
- * printf(" * We've got [%s].\n", *i);
- *
- * PHYSFS_freeList(rc);
- * \endcode
- *
- * ...will print:
- *
- * \verbatim
- * We've got [x.sav].
- * We've got [y.Sav].
- * We've got [w.sav].\endverbatim
- *
- * Feel free to sort the list however you like. We only promise there will
- * be no duplicates, but not what order the final list will come back in.
- *
- * Wildcard strings can use the '*' and '?' characters, currently.
- * Matches can be case-insensitive if you pass a zero for argument 3.
- *
- * Don't forget to call PHYSFS_freeList() with the return value from this
- * function when you are done with it.
- *
- * \param dir directory in platform-independent notation to enumerate.
- * \return Null-terminated array of null-terminated strings.
- */
-__EXPORT__ char **PHYSFSEXT_enumerateFilesWildcard(const char *dir,
- const char *wildcard,
- int caseSensitive);
-
-/* end of globbing.h ... */
-
+++ /dev/null
-/** \file ignorecase.c */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-
-#include "physfs.h"
-#include "ignorecase.h"
-
-/**
- * Please see ignorecase.h for details.
- *
- * License: this code is public domain. I make no warranty that it is useful,
- * correct, harmless, or environmentally safe.
- *
- * This particular file may be used however you like, including copying it
- * verbatim into a closed-source project, exploiting it commercially, and
- * removing any trace of my name from the source (although I hope you won't
- * do that). I welcome enhancements and corrections to this file, but I do
- * not require you to send me patches if you make changes. This code has
- * NO WARRANTY.
- *
- * Unless otherwise stated, the rest of PhysicsFS falls under the zlib license.
- * Please see LICENSE.txt in the root of the source tree.
- *
- * \author Ryan C. Gordon.
- */
-
-/* I'm not screwing around with stricmp vs. strcasecmp... */
-/* !!! FIXME: this will NOT work with UTF-8 strings in physfs2.0 */
-static int caseInsensitiveStringCompare(const char *x, const char *y)
-{
- int ux, uy;
- do
- {
- ux = toupper((int) *x);
- uy = toupper((int) *y);
- if (ux != uy)
- return((ux > uy) ? 1 : -1);
- x++;
- y++;
- } while ((ux) && (uy));
-
- return(0);
-} /* caseInsensitiveStringCompare */
-
-
-static int locateOneElement(char *buf)
-{
- char *ptr;
- char **rc;
- char **i;
-
- if (PHYSFS_exists(buf))
- return(1); /* quick rejection: exists in current case. */
-
- ptr = strrchr(buf, '/'); /* find entry at end of path. */
- if (ptr == NULL)
- {
- rc = PHYSFS_enumerateFiles("/");
- ptr = buf;
- } /* if */
- else
- {
- *ptr = '\0';
- rc = PHYSFS_enumerateFiles(buf);
- *ptr = '/';
- ptr++; /* point past dirsep to entry itself. */
- } /* else */
-
- for (i = rc; *i != NULL; i++)
- {
- if (caseInsensitiveStringCompare(*i, ptr) == 0)
- {
- strcpy(ptr, *i); /* found a match. Overwrite with this case. */
- PHYSFS_freeList(rc);
- return(1);
- } /* if */
- } /* for */
-
- /* no match at all... */
- PHYSFS_freeList(rc);
- return(0);
-} /* locateOneElement */
-
-
-int PHYSFSEXT_locateCorrectCase(char *buf)
-{
- int rc;
- char *ptr;
- char *prevptr;
-
- while (*buf == '/') /* skip any '/' at start of string... */
- buf++;
-
- ptr = prevptr = buf;
- if (*ptr == '\0')
- return(0); /* Uh...I guess that's success. */
-
- while (ptr = strchr(ptr + 1, '/'))
- {
- *ptr = '\0'; /* block this path section off */
- rc = locateOneElement(buf);
- *ptr = '/'; /* restore path separator */
- if (!rc)
- return(-2); /* missing element in path. */
- } /* while */
-
- /* check final element... */
- return(locateOneElement(buf) ? 0 : -1);
-} /* PHYSFSEXT_locateCorrectCase */
-
-
-#ifdef TEST_PHYSFSEXT_LOCATECORRECTCASE
-int main(int argc, char **argv)
-{
- int rc;
- char buf[128];
- PHYSFS_File *f;
-
- if (!PHYSFS_init(argv[0]))
- {
- fprintf(stderr, "PHYSFS_init(): %s\n", PHYSFS_getLastError());
- return(1);
- } /* if */
-
- if (!PHYSFS_addToSearchPath(".", 1))
- {
- fprintf(stderr, "PHYSFS_addToSearchPath(): %s\n", PHYSFS_getLastError());
- PHYSFS_deinit();
- return(1);
- } /* if */
-
- if (!PHYSFS_setWriteDir("."))
- {
- fprintf(stderr, "PHYSFS_setWriteDir(): %s\n", PHYSFS_getLastError());
- PHYSFS_deinit();
- return(1);
- } /* if */
-
- if (!PHYSFS_mkdir("/a/b/c"))
- {
- fprintf(stderr, "PHYSFS_mkdir(): %s\n", PHYSFS_getLastError());
- PHYSFS_deinit();
- return(1);
- } /* if */
-
- if (!PHYSFS_mkdir("/a/b/C"))
- {
- fprintf(stderr, "PHYSFS_mkdir(): %s\n", PHYSFS_getLastError());
- PHYSFS_deinit();
- return(1);
- } /* if */
-
- f = PHYSFS_openWrite("/a/b/c/x.txt");
- PHYSFS_close(f);
- if (f == NULL)
- {
- fprintf(stderr, "PHYSFS_openWrite(): %s\n", PHYSFS_getLastError());
- PHYSFS_deinit();
- return(1);
- } /* if */
-
- f = PHYSFS_openWrite("/a/b/C/X.txt");
- PHYSFS_close(f);
- if (f == NULL)
- {
- fprintf(stderr, "PHYSFS_openWrite(): %s\n", PHYSFS_getLastError());
- PHYSFS_deinit();
- return(1);
- } /* if */
-
- strcpy(buf, "/a/b/c/x.txt");
- rc = PHYSFSEXT_locateCorrectCase(buf);
- if ((rc != 0) || (strcmp(buf, "/a/b/c/x.txt") != 0))
- printf("test 1 failed\n");
-
- strcpy(buf, "/a/B/c/x.txt");
- rc = PHYSFSEXT_locateCorrectCase(buf);
- if ((rc != 0) || (strcmp(buf, "/a/b/c/x.txt") != 0))
- printf("test 2 failed\n");
-
- strcpy(buf, "/a/b/C/x.txt");
- rc = PHYSFSEXT_locateCorrectCase(buf);
- if ((rc != 0) || (strcmp(buf, "/a/b/C/X.txt") != 0))
- printf("test 3 failed\n");
-
- strcpy(buf, "/a/b/c/X.txt");
- rc = PHYSFSEXT_locateCorrectCase(buf);
- if ((rc != 0) || (strcmp(buf, "/a/b/c/x.txt") != 0))
- printf("test 4 failed\n");
-
- strcpy(buf, "/a/b/c/z.txt");
- rc = PHYSFSEXT_locateCorrectCase(buf);
- if ((rc != -1) || (strcmp(buf, "/a/b/c/z.txt") != 0))
- printf("test 5 failed\n");
-
- strcpy(buf, "/A/B/Z/z.txt");
- rc = PHYSFSEXT_locateCorrectCase(buf);
- if ((rc != -2) || (strcmp(buf, "/a/b/Z/z.txt") != 0))
- printf("test 6 failed\n");
-
- printf("Testing completed.\n");
- printf(" If no errors were reported, you're good to go.\n");
-
- PHYSFS_delete("/a/b/c/x.txt");
- PHYSFS_delete("/a/b/C/X.txt");
- PHYSFS_delete("/a/b/c");
- PHYSFS_delete("/a/b/C");
- PHYSFS_delete("/a/b");
- PHYSFS_delete("/a");
- PHYSFS_deinit();
- return(0);
-} /* main */
-#endif
-
-/* end of ignorecase.c ... */
-
+++ /dev/null
-/** \file ignorecase.h */
-
-/**
- * \mainpage PhysicsFS ignorecase
- *
- * This is an extension to PhysicsFS to let you handle files in a
- * case-insensitive manner, regardless of what sort of filesystem or
- * archive they reside in. It does this by enumerating directories as
- * needed and manually locating matching entries.
- *
- * Please note that this brings with it some caveats:
- * - On filesystems that are case-insensitive to start with, such as those
- * used on Windows or MacOS, you are adding extra overhead.
- * - On filesystems that are case-sensitive, you might select the wrong dir
- * or file (which brings security considerations and potential bugs). This
- * code favours exact case matches, but you will lose access to otherwise
- * duplicate filenames, or you might go down a wrong directory tree, etc.
- * In practive, this is rarely a problem, but you need to be aware of it.
- * - This doesn't do _anything_ with the write directory; you're on your
- * own for opening the right files for writing. You can sort of get around
- * this by adding your write directory to the search path, but then the
- * interpolated directory tree can screw you up even more.
- *
- * This code should be considered an aid for legacy code. New development
- * shouldn't do dumbass things that require this aid in the first place. :)
- *
- * Usage: Set up PhysicsFS as you normally would, then use
- * PHYSFSEXT_locateCorrectCase() to get a "correct" pathname to pass to
- * functions like PHYSFS_openRead(), etc.
- *
- * License: this code is public domain. I make no warranty that it is useful,
- * correct, harmless, or environmentally safe.
- *
- * This particular file may be used however you like, including copying it
- * verbatim into a closed-source project, exploiting it commercially, and
- * removing any trace of my name from the source (although I hope you won't
- * do that). I welcome enhancements and corrections to this file, but I do
- * not require you to send me patches if you make changes. This code has
- * NO WARRANTY.
- *
- * Unless otherwise stated, the rest of PhysicsFS falls under the zlib license.
- * Please see LICENSE.txt in the root of the source tree.
- *
- * \author Ryan C. Gordon.
- */
-
-
-/**
- * \fn int PHYSFSEXT_locateCorrectCase(char *buf)
- * \brief Find an existing filename with matching case.
- *
- * This function will look for a path/filename that matches the passed in
- * buffer. Each element of the buffer's path is checked for a
- * case-insensitive match. The buffer must specify a null-terminated string
- * in platform-independent notation.
- *
- * Please note results may be skewed differently depending on whether symlinks
- * are enabled or not.
- *
- * Each element of the buffer is overwritten with the actual case of an
- * existing match. If there is no match, the search aborts and reports an
- * error. Exact matches are favored over case-insensitive matches.
- *
- * THIS IS RISKY. Please do not use this function for anything but crappy
- * legacy code.
- *
- * \param buf Buffer with null-terminated string of path/file to locate.
- * This buffer will be modified by this function.
- * \return zero if match was found, -1 if the final element (the file itself)
- * is missing, -2 if one of the parent directories is missing.
- */
-int PHYSFSEXT_locateCorrectCase(char *buf);
-
-/* end of ignorecase.h ... */
-
+++ /dev/null
-#!/usr/bin/perl -w
-
-use warnings;
-use strict;
-
-print <<__EOF__;
-/*
- * This file is part of PhysicsFS (http://icculus.org/physfs/)
- *
- * This data generated by physfs/extras/makecasefoldhashtable.pl ...
- * Do not manually edit this file!
- *
- * Please see the file LICENSE.txt in the source's root directory.
- */
-
-#ifndef __PHYSICSFS_INTERNAL__
-#error Do not include this header from your applications.
-#endif
-
-__EOF__
-
-
-my @foldPairs;
-
-for (my $i = 0; $i < 256; $i++) {
- $foldPairs[$i] = '';
-}
-
-open(FH,'<','casefolding.txt') or die("failed to open casefolding.txt: $!\n");
-while (<FH>) {
- chomp;
- # strip comments from textfile...
- s/\#.*\Z//;
-
- # strip whitespace...
- s/\A\s+//;
- s/\s+\Z//;
-
- next if not /\A([a-fA-F0-9]+)\;\s*(.)\;\s*(.+)\;/;
- my ($code, $status, $mapping) = ($1, $2, $3);
- my $hexxed = hex($code);
- my $hashed = (($hexxed ^ ($hexxed >> 8)) & 0xFF);
- #print("// code '$code' status '$status' mapping '$mapping'\n");
- #print("// hexxed '$hexxed' hashed '$hashed'\n");
-
- if (($status eq 'C') or ($status eq 'F')) {
- my ($map1, $map2, $map3) = ('0000', '0000', '0000');
- $map1 = $1 if $mapping =~ s/\A([a-fA-F0-9]+)(\s*|\Z)//;
- $map2 = $1 if $mapping =~ s/\A([a-fA-F0-9]+)(\s*|\Z)//;
- $map3 = $1 if $mapping =~ s/\A([a-fA-F0-9]+)(\s*|\Z)//;
- die("mapping space too small for '$code'\n") if ($mapping ne '');
- $foldPairs[$hashed] .= " { 0x$code, 0x$map1, 0x$map2, 0x$map3 },\n";
- }
-}
-close(FH);
-
-for (my $i = 0; $i < 256; $i++) {
- $foldPairs[$i] =~ s/,\n\Z//;
- my $str = $foldPairs[$i];
- next if $str eq '';
- my $num = '000' . $i;
- $num =~ s/\A.*?(\d\d\d)\Z/$1/;
- my $sym = "case_fold_${num}";
- print("static const CaseFoldMapping ${sym}[] = {\n$str\n};\n\n");
-}
-
-print("\nstatic const CaseFoldHashBucket case_fold_hash[256] = {\n");
-
-for (my $i = 0; $i < 256; $i++) {
- my $str = $foldPairs[$i];
- if ($str eq '') {
- print(" { 0, NULL },\n");
- } else {
- my $num = '000' . $i;
- $num =~ s/\A.*?(\d\d\d)\Z/$1/;
- my $sym = "case_fold_${num}";
- print(" { __PHYSFS_ARRAYLEN($sym), $sym },\n");
- }
-}
-print("};\n\n");
-
-exit 0;
-
-# end of makecashfoldhashtable.pl ...
-
+++ /dev/null
-#!/bin/sh
-
-# This shell script is roughly equivalent to what "make dist" did in the
-# autotools build system and is called from a custom CMake target.
-
-# !!! FIXME: This code sort of sucks. Consider using CPack instead...
-
-if [ ! -f ./CMakeLists.txt ]; then
- echo "you are in the wrong place."
- exit 1
-fi
-
-if [ -z "$1" ]; then
- echo "Wrong arguments."
- exit 2
-fi
-
-set -e
-
-VERSION="$1"
-BASENAME="physfs-$VERSION"
-TARBALL="$BASENAME.tar.gz"
-TMPCPDIR="../9sdkujy75jv932-physfstmp-$VERSION"
-CPDIR="$TMPCPDIR/$BASENAME"
-
-echo "Packing PhysicsFS $VERSION source tarball..."
-echo " + Setting up scratch dir..."
-rm -rf $TMPCPDIR
-mkdir $TMPCPDIR
-mkdir $CPDIR
-
-echo " + Making copy of source tree in scratch dir..."
-cp -R . $CPDIR/
-echo " + Deleting cruft..."
-pushd $CPDIR >/dev/null
-rm -rf `svn propget svn:ignore .`
-rm -rf `svn status |grep '?' |sed -s 's/\?//'`
-popd >/dev/null
-rm -rf `find $CPDIR -type d -name '.svn'`
-echo " + Deleting Subversion metadata..."
-rm -rf `find $CPDIR -type d -name '.svn'`
-echo " + Fixing up permissions..."
-chmod -R a+rw $CPDIR
-chmod a+x `find $CPDIR -type d`
-echo " + Building final tarball..."
-rm -f $TARBALL
-tar -czf $TARBALL -C $TMPCPDIR $BASENAME
-echo " + Cleaning up..."
-rm -rf $TMPCPDIR
-echo " + All done! Packed to '$TARBALL' ..."
-set +e
-
-exit 0
-
+++ /dev/null
-# $Id: installer.rb 585 2003-07-21 03:46:50Z icculus $
-
-require 'rbconfig'
-require 'find'
-require 'ftools'
-
-include Config
-
-module Slimb
- class Installer
- def initialize target_dir = "", &user_skip
- @user_skip = user_skip or proc {|f| false}
-
- @version = CONFIG["MAJOR"] + "." + CONFIG["MINOR"]
- @libdir = File.join(CONFIG["libdir"], "ruby", @version)
- @sitedir = CONFIG["sitedir"] || File.join(@libdir, "site_ruby")
- @dest = File.join @sitedir, target_dir
-
- File::makedirs @dest
- File::chmod 0755, @dest, true
- end
-
- def skip? file
- @user_skip[file] or
- file[0] == ?. or file[-1] == ?~ or file[-1] == ?#
- end
-
- def install_dir dir
- File::makedirs(File.join(@dest, dir))
- File::chmod(0755, File.join(@dest, dir), true)
- Dir.foreach(dir) {|file|
- next if skip? file
-
- if File.ftype(File.join(dir, file)) == "directory"
- install_dir File.join(dir, file)
- else
- install_file File.join(dir, file)
- end
- }
- end
-
- def install_file file
- if file =~ /\.so$/
- install_so file
- else
- File::install file, File.join(@dest, file), 0644, true
- end
- end
-
- def install_so file
- File::install file, File.join(CONFIG["sitearchdir"], file), 0644, true
- end
-
- def uninstall_so file
- file = File.join(CONFIG["sitearchdir"], file)
- File::safe_unlink file
- end
-
- def install something
- case something
- when Array
- something.each {|x|
- install x if x.is_a? String
- }
- when String
- if File.ftype(something) == "directory"
- install_dir something
- else
- install_file something
- end
- end
- end
-
- def uninstall what = "*"
- case what
- when Array
- files = what.map {|x| File.join(@dest, x)}
- when String
- files = Dir[File.join(@dest, what)]
- end
-
- files.each {|x|
- # FIXME: recursive uninstall is a must
- next if FileTest.directory? x
- File::safe_unlink x
- }
- end
-
- def run files, argv
- if !argv.grep(/--uninstall/).empty?
- uninstall files
- else
- install files
- end
- end
- end
-end
-
-# self-installation
-if $0 == __FILE__
- $stderr.puts "Installing slimb installer..."
- Slimb::Installer.new("slimb").install File.basename(__FILE__)
-end
+++ /dev/null
-require 'mkmf'
-
-$CFLAGS += `sdl-config --cflags`.chomp
-$LDFLAGS += `sdl-config --libs`.chomp
-
-have_library "physfs", "PHYSFS_init"
-have_library "SDL", "SDL_AllocRW"
-
-create_makefile "physfs_so"
+++ /dev/null
-#!/usr/local/bin/ruby
-
-if __FILE__ == $0
- require 'slimb/installer'
- files = ["physfs.rb", "physfs_so.so"]
- installer = Slimb::Installer.new.run files, ARGV
-end
+++ /dev/null
-#!/bin/sh
-ruby extconf.rb
-make
-cd ..
-ruby installer.rb
-cd physfs
-ruby install.rb
-cd test
-ruby test_physfs.rb
\ No newline at end of file
+++ /dev/null
-#
-# PhysicsFS - ruby interface
-#
-# Author: Ed Sinjiashvili (slimb@vlinkmail.com)
-# License: LGPL
-#
-
-require 'physfs_so'
-
-module PhysicsFS
-
- class Version
- def initialize major, minor, patch
- @major = major
- @minor = minor
- @patch = patch
- end
-
- attr_reader :major, :minor, :patch
-
- def to_s
- "#@major.#@minor.#@patch"
- end
- end
-
- class ArchiveInfo
- def initialize ext, desc, author, url
- @extension = ext
- @description = desc
- @author = author
- @url = url
- end
-
- attr_reader :extension, :description
- attr_reader :author, :url
-
- def to_s
- " * #@extension: #@description\n Written by #@author.\n #@url\n"
- end
- end
-
- #
- # convenience methods
- #
- class << self
-
- def init argv0 = $0
- init_internal argv0
- end
-
- def append_search_path str
- add_to_search_path str, 1
- self
- end
-
- def prepend_search_path str
- add_to_search_path str, 0
- self
- end
-
- alias_method :<<, :append_search_path
- alias_method :push, :append_search_path
- alias_method :unshift, :prepend_search_path
-
- def ls path = ""
- enumerate path
- end
- end
-
- #
- # File - PhysicsFS abstract file - can be drawn from various sources
- #
- class File
- def write_str str
- write str, 1, str.length
- end
-
- def cat
- prev_pos = tell
- seek 0
- r = read length, 1
- seek prev_pos
- r
- end
-
- alias_method :size, :length
- end
-
- #
- # RWops - general stdio like operations on file-like creatures
- #
- class RWops
- SEEK_SET = 0
- SEEK_CUR = 1
- SEEK_END = 2
-
- # tell current position of RWopted entity
- def tell
- seek 0, SEEK_CUR
- end
-
- # length of RWops abstracted entity
- def length
- cur = tell
- r = seek 0, SEEK_END
- seek cur, SEEK_SET
- r
- end
-
- alias_method :size, :length
-
- #
- # create rwops from PhysicsFS file object
- #
- def self.from_physfs file
- file.to_rwops
- end
- end
-end
-
-# physfs.rb ends here #
+++ /dev/null
-/*
- * This code provides a glue layer between PhysicsFS and Simple Directmedia
- * Layer's (SDL) RWops i/o abstraction.
- *
- * License: this code is public domain. I make no warranty that it is useful,
- * correct, harmless, or environmentally safe.
- *
- * This particular file may be used however you like, including copying it
- * verbatim into a closed-source project, exploiting it commercially, and
- * removing any trace of my name from the source (although I hope you won't
- * do that). I welcome enhancements and corrections to this file, but I do
- * not require you to send me patches if you make changes.
- *
- * Unless otherwise stated, the rest of PhysicsFS falls under the GNU Lesser
- * General Public License: http://www.gnu.org/licenses/lgpl.txt
- *
- * SDL falls under the LGPL, too. You can get SDL at http://www.libsdl.org/
- *
- * This file was written by Ryan C. Gordon. (icculus@icculus.org).
- */
-
-#include <stdio.h> /* used for SEEK_SET, SEEK_CUR, SEEK_END ... */
-#include "physfsrwops.h"
-
-static int physfsrwops_seek(SDL_RWops *rw, int offset, int whence)
-{
- PHYSFS_File *handle = (PHYSFS_File *) rw->hidden.unknown.data1;
- int pos = 0;
-
- if (whence == SEEK_SET)
- {
- pos = offset;
- } /* if */
-
- else if (whence == SEEK_CUR)
- {
- PHYSFS_sint64 current = PHYSFS_tell(handle);
- if (current == -1)
- {
- SDL_SetError("Can't find position in file: %s",
- PHYSFS_getLastError());
- return(-1);
- } /* if */
-
- pos = (int) current;
- if ( ((PHYSFS_sint64) pos) != current )
- {
- SDL_SetError("Can't fit current file position in an int!");
- return(-1);
- } /* if */
-
- if (offset == 0) /* this is a "tell" call. We're done. */
- return(pos);
-
- pos += offset;
- } /* else if */
-
- else if (whence == SEEK_END)
- {
- PHYSFS_sint64 len = PHYSFS_fileLength(handle);
- if (len == -1)
- {
- SDL_SetError("Can't find end of file: %s", PHYSFS_getLastError());
- return(-1);
- } /* if */
-
- pos = (int) len;
- if ( ((PHYSFS_sint64) pos) != len )
- {
- SDL_SetError("Can't fit end-of-file position in an int!");
- return(-1);
- } /* if */
-
- pos += offset;
- } /* else if */
-
- else
- {
- SDL_SetError("Invalid 'whence' parameter.");
- return(-1);
- } /* else */
-
- if ( pos < 0 )
- {
- SDL_SetError("Attempt to seek past start of file.");
- return(-1);
- } /* if */
-
- if (!PHYSFS_seek(handle, (PHYSFS_uint64) pos))
- {
- SDL_SetError("PhysicsFS error: %s", PHYSFS_getLastError());
- return(-1);
- } /* if */
-
- return(pos);
-} /* physfsrwops_seek */
-
-
-static int physfsrwops_read(SDL_RWops *rw, void *ptr, int size, int maxnum)
-{
- PHYSFS_File *handle = (PHYSFS_File *) rw->hidden.unknown.data1;
- PHYSFS_sint64 rc = PHYSFS_read(handle, ptr, size, maxnum);
- if (rc != maxnum)
- {
- if (!PHYSFS_eof(handle)) /* not EOF? Must be an error. */
- SDL_SetError("PhysicsFS error: %s", PHYSFS_getLastError());
- } /* if */
-
- return((int) rc);
-} /* physfsrwops_read */
-
-
-static int physfsrwops_write(SDL_RWops *rw, const void *ptr, int size, int num)
-{
- PHYSFS_File *handle = (PHYSFS_File *) rw->hidden.unknown.data1;
- PHYSFS_sint64 rc = PHYSFS_write(handle, ptr, size, num);
- if (rc != num)
- SDL_SetError("PhysicsFS error: %s", PHYSFS_getLastError());
-
- return((int) rc);
-} /* physfsrwops_write */
-
-
-static int physfsrwops_close(SDL_RWops *rw)
-{
- PHYSFS_File *handle = (PHYSFS_File *) rw->hidden.unknown.data1;
- if (!PHYSFS_close(handle))
- {
- SDL_SetError("PhysicsFS error: %s", PHYSFS_getLastError());
- return(-1);
- } /* if */
-
- SDL_FreeRW(rw);
- return(0);
-} /* physfsrwops_close */
-
-
-static SDL_RWops *create_rwops(PHYSFS_File *handle)
-{
- SDL_RWops *retval = NULL;
-
- if (handle == NULL)
- SDL_SetError("PhysicsFS error: %s", PHYSFS_getLastError());
- else
- {
- retval = SDL_AllocRW();
- if (retval != NULL)
- {
- retval->seek = physfsrwops_seek;
- retval->read = physfsrwops_read;
- retval->write = physfsrwops_write;
- retval->close = physfsrwops_close;
- retval->hidden.unknown.data1 = handle;
- } /* if */
- } /* else */
-
- return(retval);
-} /* create_rwops */
-
-
-SDL_RWops *PHYSFSRWOPS_makeRWops(PHYSFS_File *handle)
-{
- SDL_RWops *retval = NULL;
- if (handle == NULL)
- SDL_SetError("NULL pointer passed to PHYSFSRWOPS_makeRWops().");
- else
- retval = create_rwops(handle);
-
- return(retval);
-} /* PHYSFSRWOPS_makeRWops */
-
-
-SDL_RWops *PHYSFSRWOPS_openRead(const char *fname)
-{
- return(create_rwops(PHYSFS_openRead(fname)));
-} /* PHYSFSRWOPS_openRead */
-
-
-SDL_RWops *PHYSFSRWOPS_openWrite(const char *fname)
-{
- return(create_rwops(PHYSFS_openWrite(fname)));
-} /* PHYSFSRWOPS_openWrite */
-
-
-SDL_RWops *PHYSFSRWOPS_openAppend(const char *fname)
-{
- return(create_rwops(PHYSFS_openAppend(fname)));
-} /* PHYSFSRWOPS_openAppend */
-
-
-/* end of physfsrwops.c ... */
-
+++ /dev/null
-/*
- * This code provides a glue layer between PhysicsFS and Simple Directmedia
- * Layer's (SDL) RWops i/o abstraction.
- *
- * License: this code is public domain. I make no warranty that it is useful,
- * correct, harmless, or environmentally safe.
- *
- * This particular file may be used however you like, including copying it
- * verbatim into a closed-source project, exploiting it commercially, and
- * removing any trace of my name from the source (although I hope you won't
- * do that). I welcome enhancements and corrections to this file, but I do
- * not require you to send me patches if you make changes.
- *
- * Unless otherwise stated, the rest of PhysicsFS falls under the GNU Lesser
- * General Public License: http://www.gnu.org/licenses/lgpl.txt
- *
- * SDL falls under the LGPL, too. You can get SDL at http://www.libsdl.org/
- *
- * This file was written by Ryan C. Gordon. (icculus@icculus.org).
- */
-
-#ifndef _INCLUDE_PHYSFSRWOPS_H_
-#define _INCLUDE_PHYSFSRWOPS_H_
-
-#include "physfs.h"
-#include "SDL.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/**
- * Open a platform-independent filename for reading, and make it accessible
- * via an SDL_RWops structure. The file will be closed in PhysicsFS when the
- * RWops is closed. PhysicsFS should be configured to your liking before
- * opening files through this method.
- *
- * @param filename File to open in platform-independent notation.
- * @return A valid SDL_RWops structure on success, NULL on error. Specifics
- * of the error can be gleaned from PHYSFS_getLastError().
- */
-__EXPORT__ SDL_RWops *PHYSFSRWOPS_openRead(const char *fname);
-
-/**
- * Open a platform-independent filename for writing, and make it accessible
- * via an SDL_RWops structure. The file will be closed in PhysicsFS when the
- * RWops is closed. PhysicsFS should be configured to your liking before
- * opening files through this method.
- *
- * @param filename File to open in platform-independent notation.
- * @return A valid SDL_RWops structure on success, NULL on error. Specifics
- * of the error can be gleaned from PHYSFS_getLastError().
- */
-__EXPORT__ SDL_RWops *PHYSFSRWOPS_openWrite(const char *fname);
-
-/**
- * Open a platform-independent filename for appending, and make it accessible
- * via an SDL_RWops structure. The file will be closed in PhysicsFS when the
- * RWops is closed. PhysicsFS should be configured to your liking before
- * opening files through this method.
- *
- * @param filename File to open in platform-independent notation.
- * @return A valid SDL_RWops structure on success, NULL on error. Specifics
- * of the error can be gleaned from PHYSFS_getLastError().
- */
-__EXPORT__ SDL_RWops *PHYSFSRWOPS_openAppend(const char *fname);
-
-/**
- * Make a SDL_RWops from an existing PhysicsFS file handle. You should
- * dispose of any references to the handle after successful creation of
- * the RWops. The actual PhysicsFS handle will be destroyed when the
- * RWops is closed.
- *
- * @param handle a valid PhysicsFS file handle.
- * @return A valid SDL_RWops structure on success, NULL on error. Specifics
- * of the error can be gleaned from PHYSFS_getLastError().
- */
-__EXPORT__ SDL_RWops *PHYSFSRWOPS_makeRWops(PHYSFS_file *handle);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* include-once blocker */
-
-/* end of physfsrwops.h ... */
-
+++ /dev/null
-/*
- * PhysicsFS - ruby interface
- *
- * Author:: Ed Sinjiashvili (slimb@vlinkmail.com)
- * License:: LGPL
- */
-
-#include "physfs.h"
-#include "ruby.h"
-
-#include "rb_physfs.h"
-#include "rb_physfs_file.h"
-
-VALUE modulePhysfs;
-
-/*
- * PhysicsFS::init str
- *
- * initialize PhysicsFS
- */
-VALUE physfs_init (VALUE self, VALUE str)
-{
- int result = PHYSFS_init (STR2CSTR(str));
-
- if (result)
- return Qtrue;
-
- return Qfalse;
-}
-
-/*
- * PhysicsFS::deinit
- */
-VALUE physfs_deinit (VALUE self)
-{
- if (PHYSFS_deinit ())
- return Qtrue;
-
- return Qfalse;
-}
-
-/*
- * PhysicsFS::version
- *
- * return PhysicsFS::Version object
- */
-VALUE physfs_version (VALUE self)
-{
- char evalStr[200];
- PHYSFS_Version ver;
-
- PHYSFS_getLinkedVersion (&ver);
-
- sprintf (evalStr, "PhysicsFS::Version.new %d, %d, %d",
- ver.major, ver.minor, ver.patch);
- return rb_eval_string (evalStr);
-}
-
-/*
- * PhysicsFS::supported_archives
- *
- * return Array of PhysicsFS::ArchiveInfo objects
- */
-VALUE physfs_supported_archives (VALUE self)
-{
- const PHYSFS_ArchiveInfo **info = PHYSFS_supportedArchiveTypes();
- VALUE klass = rb_const_get (modulePhysfs, rb_intern ("ArchiveInfo"));
- VALUE ary = rb_ary_new ();
- VALUE params[4];
-
- while ( *info != 0 )
- {
- params[0] = rb_str_new2 ((*info)->extension);
- params[1] = rb_str_new2 ((*info)->description);
- params[2] = rb_str_new2 ((*info)->author);
- params[3] = rb_str_new2 ((*info)->url);
-
- rb_ary_push (ary, rb_class_new_instance (4, params, klass));
- info++;
- }
-
- return ary;
-}
-
-/*
- * PhysicsFS::last_error
- *
- * return string representation of last PhysicsFS error
- */
-VALUE physfs_last_error (VALUE self)
-{
- const char *last_error = PHYSFS_getLastError ();
-
- if (last_error == 0)
- last_error = "";
-
- return rb_str_new2 (last_error);
-}
-
-/*
- * PhysicsFS::dir_separator
- *
- * return platform directory separator
- */
-VALUE physfs_dir_separator (VALUE self)
-{
- return rb_str_new2 (PHYSFS_getDirSeparator ());
-}
-
-/*
- * PhysicsFS::permit_symlinks boolValue
- *
- * turn symlinks support on/off
- */
-VALUE physfs_permit_symlinks (VALUE self, VALUE allow)
-{
- int p = 1;
-
- if (allow == Qfalse || allow == Qnil)
- p = 0;
-
- PHYSFS_permitSymbolicLinks (p);
- return Qtrue;
-}
-
-/*
- * PhysicsFS::cdrom_dirs
- *
- * return Array of strings containing available CDs
- */
-VALUE physfs_cdrom_dirs (VALUE self)
-{
- char **cds = PHYSFS_getCdRomDirs();
- char **i;
- VALUE ary = rb_ary_new ();
-
- for (i = cds; *i != 0; i++)
- rb_ary_push (ary, rb_str_new2 (*i));
-
- PHYSFS_freeList (cds);
- return ary;
-}
-
-/*
- * PhysicsFS::base_dir
- *
- * return base directory
- */
-VALUE physfs_base_dir (VALUE self)
-{
- const char *base_dir = PHYSFS_getBaseDir ();
- if (base_dir == 0)
- base_dir = "";
-
- return rb_str_new2 (base_dir);
-}
-
-/*
- * PhysicsFS::user_dir
- *
- * return user directory
- */
-VALUE physfs_user_dir (VALUE self)
-{
- const char *user_dir = PHYSFS_getBaseDir ();
- if (user_dir == 0)
- user_dir = "";
-
- return rb_str_new2 (user_dir);
-}
-
-/*
- * PhysicsFS::write_dir
- *
- * return write directory
- */
-VALUE physfs_write_dir (VALUE self)
-{
- const char *write_dir = PHYSFS_getWriteDir ();
- if (write_dir == 0)
- return Qnil;
-
- return rb_str_new2 (write_dir);
-}
-
-/*
- * PhysicsFS::write_dir= str
- *
- * set write directory to *str*
- */
-VALUE physfs_set_write_dir (VALUE self, VALUE str)
-{
- int result = PHYSFS_setWriteDir (STR2CSTR(str));
-
- if (result)
- return Qtrue;
- return Qfalse;
-}
-
-/*
- * PhysicsFS::add_to_search_path str, append
- *
- * if append > 0 - append str to search path, otherwise prepend it
- */
-VALUE physfs_add_search_path (VALUE self, VALUE str, VALUE append)
-{
- int result = PHYSFS_addToSearchPath (STR2CSTR(str), FIX2INT(append));
- if (result)
- return Qtrue;
- return Qfalse;
-}
-
-/*
- * PhysicsFS::remove_from_search_path str
- *
- * removes str from search path
- */
-VALUE physfs_remove_search_path (VALUE self, VALUE str)
-{
- int result = PHYSFS_removeFromSearchPath (STR2CSTR(str));
- if (result)
- return Qtrue;
- return Qfalse;
-}
-
-/*
- * PhysicsFS::search_path
- *
- * return current search_path - as array of strings
- */
-VALUE physfs_search_path (VALUE self)
-{
- char **path = PHYSFS_getSearchPath ();
- char **i;
- VALUE ary = rb_ary_new ();
-
- for (i = path ; *i != 0; i++)
- rb_ary_push (ary, rb_str_new2 (*i));
-
- PHYSFS_freeList (path);
- return ary;
-}
-
-//
-VALUE physfs_setSaneConfig(VALUE self, VALUE org, VALUE app, VALUE ext,
- VALUE includeCdroms, VALUE archivesFirst)
-{
- int res = PHYSFS_setSaneConfig (STR2CSTR(org), STR2CSTR(app), STR2CSTR(ext),
- RTEST(includeCdroms), RTEST(archivesFirst));
- if (res)
- return Qtrue;
-
- return Qfalse;
-}
-
-/*
- * PhysicsFS::mkdir newdir
- *
- * create new directory
- */
-VALUE physfs_mkdir (VALUE self, VALUE newdir)
-{
- int result = PHYSFS_mkdir (STR2CSTR(newdir));
- if (result)
- return Qtrue;
- return Qfalse;
-}
-
-/*
- * PhysicsFS::delete name
- *
- * delete file with name
- */
-VALUE physfs_delete (VALUE self, VALUE name)
-{
- int result = PHYSFS_delete (STR2CSTR(name));
- if (result)
- return Qtrue;
- return Qfalse;
-}
-
-/*
- * PhysicsFS::real_dir name
- *
- * return real directory (in search path) of a name
- */
-VALUE physfs_real_dir (VALUE self, VALUE name)
-{
- const char *path = PHYSFS_getRealDir (STR2CSTR(name));
- if (path == 0)
- return Qnil;
-
- return rb_str_new2 (path);
-}
-
-/*
- * PhysicsFS::enumerate dir
- *
- * list a dir from a search path
- */
-VALUE physfs_enumerate (VALUE self, VALUE dir)
-{
- char **files = PHYSFS_enumerateFiles (STR2CSTR(dir));
- char **i;
- VALUE ary = rb_ary_new ();
-
- for (i = files; *i != 0; i++)
- rb_ary_push (ary, rb_str_new2 (*i));
-
- PHYSFS_freeList (files);
- return ary;
-}
-
-/*
- * PhysicsFS::exists? name
- *
- * does a file with name exist?
- */
-VALUE physfs_exists (VALUE self, VALUE name)
-{
- int result = PHYSFS_exists (STR2CSTR(name));
- if (result)
- return Qtrue;
- return Qfalse;
-}
-
-/*
- * PhysicsFS::is_directory? name
- *
- * return true if name is directory
- */
-VALUE physfs_is_directory (VALUE self, VALUE name)
-{
- int result = PHYSFS_isDirectory (STR2CSTR(name));
- if (result)
- return Qtrue;
- return Qfalse;
-}
-
-/*
- * PhysicsFS::is_symlink? name
- *
- * return true if name is symlink
- */
-VALUE physfs_is_symlink (VALUE self, VALUE name)
-{
- int result = PHYSFS_isSymbolicLink (STR2CSTR(name));
- if (result)
- return Qtrue;
- return Qfalse;
-}
-
-/*
- * PhysicsFS::last_mod_time name
- *
- * return last modification time of a file
- */
-VALUE physfs_last_mod_time (VALUE self, VALUE name)
-{
- int result = PHYSFS_getLastModTime (STR2CSTR(name));
-
- return INT2FIX(result);
-}
-
-/*
- * PhysicsFS::open_read name
- *
- * return +PhysicsFS::File+ ready for reading
- */
-VALUE physfs_open_read (VALUE self, VALUE name)
-{
- PHYSFS_File *file = PHYSFS_openRead (STR2CSTR(name));
- return physfs_file_new (file);
-}
-
-/*
- * PhysicsFS::open_write name
- *
- * return PhysicsFS::File ready for writing
- */
-VALUE physfs_open_write (VALUE self, VALUE name)
-{
- PHYSFS_File *file = PHYSFS_openWrite (STR2CSTR(name));
- return physfs_file_new (file);
-}
-
-/*
- * PhysicsFS::open_append name
- *
- * return PhysicsFS::File ready for appending
- */
-VALUE physfs_open_append (VALUE self, VALUE name)
-{
- PHYSFS_File *file = PHYSFS_openAppend (STR2CSTR(name));
- return physfs_file_new (file);
-}
-
-void Init_physfs_so (void)
-{
- modulePhysfs = rb_define_module ("PhysicsFS");
-
- rb_define_singleton_method (modulePhysfs, "init_internal", physfs_init, 1);
- rb_define_singleton_method (modulePhysfs, "deinit", physfs_deinit, 0);
- rb_define_singleton_method (modulePhysfs, "version", physfs_version, 0);
- rb_define_singleton_method (modulePhysfs, "supported_archives",
- physfs_supported_archives, 0);
- rb_define_singleton_method (modulePhysfs, "last_error",
- physfs_last_error, 0);
- rb_define_singleton_method (modulePhysfs, "dir_separator",
- physfs_dir_separator, 0);
- rb_define_singleton_method (modulePhysfs, "permit_symlinks",
- physfs_permit_symlinks, 1);
- rb_define_singleton_method (modulePhysfs, "cdrom_dirs",
- physfs_cdrom_dirs, 0);
- rb_define_singleton_method (modulePhysfs, "base_dir", physfs_base_dir, 0);
- rb_define_singleton_method (modulePhysfs, "user_dir", physfs_user_dir, 0);
-
- rb_define_singleton_method (modulePhysfs, "write_dir", physfs_write_dir, 0);
- rb_define_singleton_method (modulePhysfs, "write_dir=",
- physfs_set_write_dir, 1);
-
- rb_define_singleton_method (modulePhysfs, "add_to_search_path",
- physfs_add_search_path, 2);
- rb_define_singleton_method (modulePhysfs, "remove_from_search_path",
- physfs_remove_search_path, 1);
- rb_define_singleton_method (modulePhysfs, "search_path",
- physfs_search_path, 0);
-
- rb_define_singleton_method (modulePhysfs, "set_sane_config",
- physfs_setSaneConfig, 5);
-
- rb_define_singleton_method (modulePhysfs, "mkdir", physfs_mkdir, 1);
- rb_define_singleton_method (modulePhysfs, "delete", physfs_delete, 1);
- rb_define_singleton_method (modulePhysfs, "real_dir",
- physfs_real_dir, 1);
- rb_define_singleton_method (modulePhysfs, "enumerate", physfs_enumerate, 1);
- rb_define_singleton_method (modulePhysfs, "exists?", physfs_exists, 1);
- rb_define_singleton_method (modulePhysfs, "is_directory?",
- physfs_is_directory, 1);
- rb_define_singleton_method (modulePhysfs, "is_symlink?",
- physfs_is_symlink, 1);
- rb_define_singleton_method (modulePhysfs, "last_mod_time",
- physfs_last_mod_time, 1);
-
- rb_define_singleton_method (modulePhysfs, "open_read",
- physfs_open_read, 1);
- rb_define_singleton_method (modulePhysfs, "open_write",
- physfs_open_write, 1);
- rb_define_singleton_method (modulePhysfs, "open_append",
- physfs_open_append, 1);
-
- init_physfs_file ();
- init_sdl_rwops ();
-}
-
-/*
-// Local Variables:
-// mode: C
-// c-indentation-style: "stroustrup"
-// indent-tabs-mode: nil
-// End:
-*/
+++ /dev/null
-/*
- * PhysicsFS - ruby interface
- *
- * Author:: Ed Sinjiashvili (slimb@vlinkmail.com)
- * License:: LGPL
- */
-
-#ifndef __RB__PHYSFS__H__
-#define __RB__PHYSFS__H__
-
-extern VALUE modulePhysfs;
-
-#endif
+++ /dev/null
-/*
- * PhysicsFS File abstraction - ruby interface
- *
- * Author:: Ed Sinjiashvili (slimb@vlinkmail.com)
- * License:: LGPL
- */
-
-#include "physfs.h"
-#include "ruby.h"
-
-#include "rb_physfs.h"
-#include "rb_physfs_file.h"
-#include "physfsrwops.h"
-
-VALUE classPhysfsFile;
-
-/*
- * construct new PhysicsFS::File object
- */
-VALUE physfs_file_new (PHYSFS_File *file)
-{
- if (file == 0)
- return Qnil;
-
- return Data_Wrap_Struct (classPhysfsFile, 0, 0, file);
-}
-
-/*
- * PhysicsFS::File#close
- *
- * Close the file. It's illegal to use the object after its closure.
- */
-VALUE physfs_file_close (VALUE self)
-{
- int result;
- PHYSFS_File *file;
- Data_Get_Struct (self, PHYSFS_File, file);
-
- if (file == 0)
- return Qfalse;
-
- result = PHYSFS_close (file);
- DATA_PTR(self) = 0;
-
- if (result)
- return Qtrue;
- return Qfalse;
-}
-
-/*
- * PhysicsFS::File#read obj_size, num_objects
- *
- * Read *objCount* objects which are *objSize* each.
- * return String instance containing raw data or nil if failure.
- * #length of string will reflect real number of objects read.
- */
-VALUE physfs_file_read (VALUE self, VALUE objSize, VALUE objCount)
-{
- int objRead;
- void *buffer;
- VALUE result;
- PHYSFS_File *file;
-
- Data_Get_Struct (self, PHYSFS_File, file);
- if (file == 0)
- return Qnil; //wasted file - no read possible
-
- buffer = malloc (FIX2UINT(objSize) * FIX2UINT(objCount));
- if (buffer == 0)
- return Qnil;
-
- objRead = PHYSFS_read (file, buffer, FIX2UINT(objSize), FIX2UINT(objCount));
- if (objRead == -1)
- {
- free (buffer);
- return Qnil;
- }
-
- result = rb_str_new (buffer, objRead * FIX2UINT(objSize));
- free (buffer);
- return result;
-}
-
-/*
- * PhysicsFS::File#write buffer, obj_size, num_objects
- *
- * return nil on failure or number of objects written.
- */
-VALUE physfs_file_write (VALUE self, VALUE buf, VALUE objSize, VALUE objCount)
-{
- int result;
- PHYSFS_File *file;
-
- Data_Get_Struct (self, PHYSFS_File, file);
- if (file == 0)
- return Qnil;
-
- result = PHYSFS_write (file, STR2CSTR(buf),
- FIX2UINT(objSize), FIX2UINT(objCount));
- if (result == -1)
- return Qnil;
-
- return INT2FIX(result);
-}
-
-/*
- * PhysicsFS::File#eof?
- */
-VALUE physfs_file_eof (VALUE self)
-{
- int result;
- PHYSFS_File *file;
-
- Data_Get_Struct (self, PHYSFS_File, file);
- if (file == 0)
- return Qnil;
-
- result = PHYSFS_eof (file);
-
- if (result)
- return Qtrue;
-
- return Qfalse;
-}
-
-/*
- * PhysicsFS::File#tell
- *
- * tells current position in file
- */
-VALUE physfs_file_tell (VALUE self)
-{
- int result;
- PHYSFS_File *file;
-
- Data_Get_Struct (self, PHYSFS_File, file);
- if (file == 0)
- return Qnil;
-
- result = PHYSFS_tell (file);
-
- if (result == -1)
- return Qnil;
-
- return INT2FIX(result);
-}
-
-/*
- * PhysicsFS::File#seek pos
- *
- * seek to pos in file
- */
-VALUE physfs_file_seek (VALUE self, VALUE pos)
-{
- int result;
- PHYSFS_File *file;
-
- Data_Get_Struct (self, PHYSFS_File, file);
- if (file == 0)
- return Qnil;
-
- result = PHYSFS_seek (file, FIX2LONG(pos));
-
- if (result)
- return Qtrue;
-
- return Qfalse;
-}
-
-/*
- * PhysicsFS::File#length
- */
-VALUE physfs_file_length (VALUE self)
-{
- int result;
- PHYSFS_File *file;
-
- Data_Get_Struct (self, PHYSFS_File, file);
- if (file == 0)
- return Qnil;
-
- result = PHYSFS_fileLength (file);
-
- if (result == -1)
- return Qnil;
-
- return INT2FIX(result);
-}
-
-/*
- * PhysicsFS::File#to_rwops
- *
- * File object is converted to RWops object.
- * File object becomes unusable after that - every operation
- * should be done through new-born RWops object.
- */
-VALUE physfs_file_to_rwops (VALUE self)
-{
- PHYSFS_File *file;
- SDL_RWops *rwops;
-
- Data_Get_Struct (self, PHYSFS_File, file);
- if (file == 0)
- return Qnil;
-
- rwops = PHYSFSRWOPS_makeRWops (file);
- if (rwops == 0)
- return Qnil;
-
- DATA_PTR(self) = 0; // oh, gosh, we've sacrificed ourselves!
- return sdl_rwops_new (rwops);
-}
-
-void init_physfs_file (void)
-{
- classPhysfsFile = rb_define_class_under (modulePhysfs, "File", rb_cObject);
-
- rb_define_method (classPhysfsFile, "close", physfs_file_close, 0);
- rb_define_method (classPhysfsFile, "eof?", physfs_file_eof, 0);
- rb_define_method (classPhysfsFile, "tell", physfs_file_tell, 0);
- rb_define_method (classPhysfsFile, "seek", physfs_file_seek, 1);
- rb_define_method (classPhysfsFile, "length", physfs_file_length, 0);
- rb_define_method (classPhysfsFile, "read", physfs_file_read, 2);
- rb_define_method (classPhysfsFile, "write", physfs_file_write, 3);
- rb_define_method (classPhysfsFile, "to_rwops", physfs_file_to_rwops, 0);
-}
+++ /dev/null
-/*
- * PhysicsFS File abstraction - ruby interface
- *
- * Author:: Ed Sinjiashvili (slimb@vlinkmail.com)
- * License:: LGPL
- */
-
-#ifndef __RB__PHYSFS__FILE__H__
-#define __RB__PHYSFS__FILE__H__
-
-extern VALUE classPhysfsFile;
-
-VALUE physfs_file_new (PHYSFS_file *file);
-VALUE physfs_file_close (VALUE self);
-VALUE physfs_file_read (VALUE self, VALUE objSize, VALUE objCount);
-VALUE physfs_file_write (VALUE self, VALUE buf, VALUE objSize, VALUE objCount);
-VALUE physfs_file_eof (VALUE self);
-VALUE physfs_file_tell (VALUE self);
-VALUE physfs_file_seek (VALUE self, VALUE pos);
-VALUE physfs_file_length (VALUE self);
-
-void init_physfs_file (void);
-
-#endif
+++ /dev/null
-/*
- * SDL_RWops - ruby interface
- *
- * Author:: Ed Sinjiashvili (slimb@vlinkmail.com)
- * License:: LGPL
- */
-
-#include "SDL_rwops.h"
-#include "ruby.h"
-
-#include "rb_physfs.h"
-#include "rb_sdl_rwops.h"
-
-VALUE classRWops;
-
-/*
- * RWops constructor
- */
-VALUE sdl_rwops_new (SDL_RWops *ops)
-{
- VALUE result;
-
- if (ops == 0)
- return Qnil;
-
- result = Data_Wrap_Struct (classRWops, 0, SDL_FreeRW, ops);
- return result;
-}
-
-/*
- * PhysicsFS::RWops::from_file name, mode
- *
- * create RWops object from file
- */
-VALUE sdl_rwops_from_file (VALUE self, VALUE name, VALUE mode)
-{
- SDL_RWops *ops = SDL_RWFromFile(STR2CSTR(name), STR2CSTR(mode));
- return sdl_rwops_new (ops);
-}
-
-/*
- * PhysicsFS::RWops::from_memory string
- *
- * create RWops object from memory
- */
-VALUE sdl_rwops_from_mem (VALUE self, VALUE str)
-{
- int len = RSTRING(str)->len;
- void *mem = STR2CSTR(str);
- SDL_RWops *ops = SDL_RWFromMem(mem, len);
-
- return sdl_rwops_new (ops);
-}
-
-/*
- * PhysicsFS::RWops#seek offset, whence
- *
- * position RWops object
- */
-VALUE sdl_rwops_seek (VALUE self, VALUE offset, VALUE whence)
-{
- int result;
- SDL_RWops *ops;
-
- Data_Get_Struct (self, SDL_RWops, ops);
- if (ops == 0)
- return Qnil;
-
- result = SDL_RWseek(ops, FIX2INT(offset), FIX2INT(whence));
- return INT2FIX(result);
-}
-
-/*
- * PhysicsFS::RWops#close
- *
- * close RWops. No use of the object is possible after that.
- */
-VALUE sdl_rwops_close (VALUE self)
-{
- int result;
- SDL_RWops *ops;
-
- Data_Get_Struct (self, SDL_RWops, ops);
- if (ops == 0)
- return Qnil;
-
- result = SDL_RWclose (ops);
- DATA_PTR(self) = 0;
-
- return INT2FIX(result);
-}
-
-/*
- * PhysicsFS::RWops#read
- *
- * read from RWops object objCount objSize'd entities.
- * return string containing raw data or nil
- */
-VALUE sdl_rwops_read (VALUE self, VALUE objSize, VALUE objCount)
-{
- int objRead;
- void *buffer;
- VALUE result;
- SDL_RWops *ops;
-
- Data_Get_Struct (self, SDL_RWops, ops);
- if (ops == 0)
- return Qnil;
-
- buffer = malloc (FIX2UINT(objSize) * FIX2UINT(objCount));
- if (buffer == 0)
- return Qnil;
-
- objRead = SDL_RWread (ops, buffer, FIX2UINT(objSize), FIX2UINT(objCount));
- if (objRead == -1)
- {
- free (buffer);
- return Qnil;
- }
-
- result = rb_str_new (buffer, objRead * FIX2UINT(objSize));
- free (buffer);
- return result;
-}
-
-/*
- * PhysicsFS::RWops#write buffer, size, n
- *
- * write raw string containing n objects size length each.
- * return number of objects written or nil
- */
-VALUE sdl_rwops_write (VALUE self, VALUE buffer, VALUE size, VALUE n)
-{
- int result;
- SDL_RWops *ops;
-
- Data_Get_Struct (self, SDL_RWops, ops);
- if (ops == 0)
- return Qnil;
-
- result = SDL_RWwrite (ops, STR2CSTR(buffer), FIX2INT(size), FIX2INT(n));
-
- if (result == -1)
- return Qnil;
-
- return INT2FIX(result);
-}
-
-void init_sdl_rwops (void)
-{
- classRWops = rb_define_class_under (modulePhysfs, "RWops", rb_cObject);
-
- rb_define_method (classRWops, "seek", sdl_rwops_seek, 2);
- rb_define_method (classRWops, "read", sdl_rwops_read, 2);
- rb_define_method (classRWops, "write", sdl_rwops_write, 3);
- rb_define_method (classRWops, "close", sdl_rwops_close, 0);
-
- rb_define_singleton_method (classRWops, "from_file",
- sdl_rwops_from_file, 2);
- rb_define_singleton_method (classRWops, "from_memory",
- sdl_rwops_from_mem, 1);
-}
+++ /dev/null
-/*
- * SDL_RWops - ruby interface
- *
- * Author:: Ed Sinjiashvili (slimb@vlinkmail.com)
- * License:: LGPL
- */
-
-#ifndef __RB__SDL__RWOPS__H__
-#define __RB__SDL__RWOPS__H__
-
-extern VALUE classRWops;
-
-VALUE sdl_rwops_new (SDL_RWops *ops);
-void init_sdl_rwops (void);
-
-#endif
+++ /dev/null
-#
-# PhysicsFS test program - mimics real physfs_test
-#
-require 'readline'
-require 'physfs'
-
-def die msg
- puts "#{msg} - reason: #{PhysicsFS.last_error}"
-end
-
-#
-# parse line to command and args
-#
-def parse line
- return false if line.nil?
-
- if line.strip =~ /^(.*?) (?: (?:\s+(.*)) | $)/x
- run $1, $2
- else
- false
- end
-end
-
-#
-# parse command args
-#
-def parse_args args
- args.strip!
-
- dquoted = /^ " (.*?) "/x
- squoted = /^ ' (.*?) '/x
- unquoted = /^([^\s\'\"]+)/
-
- regexps = [dquoted, squoted, unquoted]
-
- result = []
- while args != ""
- regexps.each do |r|
- if args =~ r
- result << $1
- args.sub! r, ""
- args.sub!(/\s+/, "")
- break
- end
- end
- end
- result
-end
-
-def usage cmd, prefix = "usage: "
- print prefix
- args = Commands::HELP[cmd]
- if args
- print cmd
- args.scan(/\w+/).each {|x|
- print " <#{x}>"
- }
- puts
- else
- puts %|#{cmd} (no arguments)|
- end
-end
-
-# commands go below
-module Commands
- HELP = {
- "init" => "argv0",
- "addarchive" => "archiveLocation append",
- "removearchive" => "archiveLocation",
- "enumerate" => "dirToEnumerate",
- "ls" => "dirToEnumerate",
- "setwritedir" => "newWriteDir",
- "permitsymlinks" => "1or0",
- "setsaneconfig" => "org appName arcExt includeCdRoms archivesFirst",
- "mkdir" => "dirToMk",
- "delete" => "dirToDelete",
- "getrealdir" => "fileToFind",
- "exists" => "fileToCheck",
- "isdir" => "fileToCheck",
- "issymlink" => "fileToCheck",
- "cat" => "fileToCat",
- "filelength" => "fileToCheck",
- "append" => "fileToAppend",
- "write" => "fileToCreateOrTrash",
- "getlastmodtime" => "fileToExamine"
- }
-
- def quit_cmd
- exit
- end
-
- alias q_cmd quit_cmd
-
- def help_cmd
- commands = ::Commands.instance_methods.grep(/_cmd$/).sort
- puts "Commands:"
- commands.each do |c|
- usage c.sub("_cmd", ""), " - "
- end
-
- true
- end
-
- def e val
- if val
- puts "Successful."
- else
- puts "Failure. reason: #{PhysicsFS.last_error}"
- end
- true
- end
-
- def init_cmd arg
- e PhysicsFS.init(arg)
- end
-
- def deinit_cmd
- e PhysicsFS.deinit
- end
-
- def addarchive_cmd archive, append
- e PhysicsFS.add_to_search_path(archive, append)
- end
-
- def removearchive_cmd archive
- e PhysicsFS.remove_from_search_path archive
- end
-
- def enumerate_cmd path
- entries = PhysicsFS.enumerate(path)
- entries.each {|x|
- puts x
- }
- true
- end
-
- alias ls_cmd enumerate_cmd
-
- def getlasterror_cmd
- puts "Last error is [#{PhysicsFS.last_error}]"
- true
- end
-
- def getdirsep_cmd
- puts "Directory separator is [#{PhysicsFS.dir_separator}]"
- true
- end
-
- def getcdromdirs_cmd
- dirs = PhysicsFS.cdrom_dirs
- dirs.each {|x|
- puts x
- }
- puts " total [#{dirs.length}] drives."
- true
- end
-
- def getsearchpath_cmd
- spath = PhysicsFS.search_path
- spath.each {|x|
- puts x
- }
- puts "total [#{spath.length}] directories."
- true
- end
-
- def getbasedir_cmd
- dir = PhysicsFS.base_dir
- puts dir if dir
- true
- end
-
- def getuserdir_cmd
- puts PhysicsFS.user_dir
- true
- end
-
- def getwritedir_cmd
- dir = PhysicsFS.write_dir
- if dir
- puts "Write directory is [#{dir}]."
- else
- puts "No write directory defined."
- end
- true
- end
-
- def setwritedir_cmd dir
- e(PhysicsFS.write_dir = dir)
- end
-
- def permitsymlinks_cmd val
- if val.to_i == 1
- PhysicsFS.permit_symlinks true
- puts "Symlinks are now permitted"
- else
- PhysicsFS.permit_symlinks false
- puts "Symlinks are now forbidden"
- end
- true
- end
-
- def setsaneconfig_cmd org, appname, ext, includeCdroms, archivesFirst
- includeCdroms = includeCdroms.to_i == 1
- archiveFirst = archivesFirst == 1
- e PhysicsFS.set_sane_config(org, appname, ext, includeCdroms, archivesFirst)
- end
-
- def mkdir_cmd dir
- e PhysicsFS.mkdir(dir)
- end
-
- def delete_cmd dir
- e PhysicsFS.delete(dir)
- end
-
- def getrealdir_cmd file
- dir = PhysicsFS.real_dir file
- if dir
- puts "Found at [#{dir}]"
- else
- puts "Not found."
- end
- true
- end
-
- def exists_cmd file
- if PhysicsFS.exists? file
- puts "File exists"
- else
- puts "File does not exist"
- end
- true
- end
-
- def isdir_cmd file
- if PhysicsFS.is_directory? file
- puts "File is a directory"
- else
- puts "File is NOT a directory"
- end
- true
- end
-
- def issymlink_cmd file
- if PhysicsFS.is_symlink? file
- puts "File is a symlink"
- else
- puts "File is NOT a symlink"
- end
- true
- end
-
- def cat_cmd filename
- file = PhysicsFS.open_read filename
- if file.nil?
- puts "failed to open. reason: #{PhysicsFS.last_error}"
- return true
- end
-
- puts file.cat
- true
- end
-
- def filelength_cmd filename
- file = PhysicsFS.open_read filename
- if file.nil?
- puts "failed to open. reason: #{PhysicsFS.last_error}"
- return true
- end
-
- puts file.length
- file.close
- true
- end
-
- WRITE_STR = "Rubyfied PhysicsFS works just fine.\n\n"
-
- def append_cmd filename
- file = PhysicsFS.open_append filename
- if file.nil?
- puts "failed to open. reason: #{PhysicsFS.last_error}"
- return true
- end
-
- file.write WRITE_STR, 1, WRITE_STR.length
- file.close
- true
- end
-
- def write_cmd filename
- file = PhysicsFS.open_write filename
- if file.nil?
- puts "failed to open. reason: #{PhysicsFS.last_error}"
- return true
- end
-
- file.write_str WRITE_STR
- file.close
- true
- end
-
- def getlastmodtime_cmd filename
- t = PhysicsFS.last_mod_time filename
- if t == -1
- puts "failed to determin. reason: #{PhysicsFS.last_error}"
- else
- puts "Last modified: #{Time.at(t)}"
- end
- true
- end
-end
-
-include Commands
-
-def run command, args
- if args
- args = parse_args args
- else
- args = []
- end
-
- begin
- cmd = method "#{command}_cmd"
- if args.length == cmd.arity
- return cmd.call *args
- else
- usage command
- true
- end
- rescue NameError
- puts 'Unknown command. Enter "help" for instructions.'
- true
- end
-end
-
-if __FILE__ == $0
-
- PhysicsFS.init($0) or die "PhysicsFS init failed"
-
- puts "PhysicsFS version: #{PhysicsFS.version}"
- puts
-
- puts "Supported archives: "
- puts PhysicsFS.supported_archives
- puts
-
- puts 'Enter commands. Enter "help" for instructions.'
-
- loop {
- line = Readline::readline "physfs_rb> ", true
- break unless parse line
- }
-end
-
-
-
-
+++ /dev/null
-/*
- * This is a quick and dirty HTTP server that uses PhysicsFS to retrieve
- * files. It is not robust at all, probably buggy, and definitely poorly
- * designed. It's just meant to show that it can be done.
- *
- * Basically, you compile this code, and run it:
- * ./physfshttpd archive1.zip archive2.zip /path/to/a/real/dir etc...
- *
- * The files are appended in order to the PhysicsFS search path, and when
- * a client request comes it, it looks for the file in said search path.
- *
- * My goal was to make this work in less than 300 lines of C, so again, it's
- * not to be used for any serious purpose. Patches to make this application
- * suck less will be readily and gratefully accepted.
- *
- * Command line I used to build this on Linux:
- * gcc -Wall -Werror -g -o bin/physfshttpd extras/physfshttpd.c -lphysfs
- *
- * License: this code is public domain. I make no warranty that it is useful,
- * correct, harmless, or environmentally safe.
- *
- * This particular file may be used however you like, including copying it
- * verbatim into a closed-source project, exploiting it commercially, and
- * removing any trace of my name from the source (although I hope you won't
- * do that). I welcome enhancements and corrections to this file, but I do
- * not require you to send me patches if you make changes. This code has
- * NO WARRANTY.
- *
- * Unless otherwise stated, the rest of PhysicsFS falls under the zlib license.
- * Please see LICENSE.txt in the root of the source tree.
- *
- * This file was written by Ryan C. Gordon. (icculus@icculus.org).
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <errno.h>
-#include <ctype.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-
-#ifndef LACKING_SIGNALS
-#include <signal.h>
-#endif
-
-#ifndef LACKING_PROTOENT
-#include <netdb.h>
-#endif
-
-#include "physfs.h"
-
-
-#define DEFAULT_PORTNUM 6667
-
-typedef struct
-{
- int sock;
- struct sockaddr *addr;
- socklen_t addrlen;
-} http_args;
-
-
-static char *txt404 =
-"HTTP/1.0 404 Not Found\n"
-"Connection: close\n"
-"Content-type: text/html\n"
-"\n"
-"<html><head><title>404 Not Found</title></head>\n"
-"<body>Can't find that.</body></html>\n\n";
-
-
-static void feed_file_http(const char *ipstr, int sock, const char *fname)
-{
- PHYSFS_File *in = PHYSFS_openRead(fname);
- char buffer[1024];
- printf("%s: requested [%s].\n", ipstr, fname);
- if (in == NULL)
- {
- printf("%s: Can't open [%s]: %s.\n",
- ipstr, fname, PHYSFS_getLastError());
- write(sock, txt404, strlen(txt404)); /* !!! FIXME: Check retval */
- } /* if */
- else
- {
- do
- {
- PHYSFS_sint64 br = PHYSFS_read(in, buffer, 1, sizeof (buffer));
- if (br == -1)
- {
- printf("%s: Read error: %s.\n", ipstr, PHYSFS_getLastError());
- break;
- } /* if */
-
- write(sock, buffer, (int) br); /* !!! FIXME: CHECK THIS RETVAL! */
- } while (!PHYSFS_eof(in));
-
- PHYSFS_close(in);
- } /* else */
-} /* feed_file_http */
-
-
-static void *do_http(void *_args)
-{
- http_args *args = (http_args *) _args;
- char ipstr[128];
- char buffer[512];
- char *ptr;
- strncpy(ipstr, inet_ntoa(((struct sockaddr_in *) args->addr)->sin_addr),
- sizeof (ipstr));
- ipstr[sizeof (ipstr) - 1] = '\0';
-
- printf("%s: connected.\n", ipstr);
- read(args->sock, buffer, sizeof (buffer));
- buffer[sizeof (buffer) - 1] = '\0';
- ptr = strchr(buffer, '\n');
- if (!ptr)
- printf("%s: potentially bogus request.\n", ipstr);
- else
- {
- *ptr = '\0';
- ptr = strchr(buffer, '\r');
- if (ptr != NULL)
- *ptr = '\0';
-
- if ((toupper(buffer[0]) == 'G') &&
- (toupper(buffer[1]) == 'E') &&
- (toupper(buffer[2]) == 'T') &&
- (toupper(buffer[3]) == ' ') &&
- (toupper(buffer[4]) == '/'))
- {
- ptr = strchr(buffer + 5, ' ');
- if (ptr != NULL)
- *ptr = '\0';
- feed_file_http(ipstr, args->sock, buffer + 4);
- } /* if */
- } /* else */
-
- /* !!! FIXME: Time the transfer. */
- printf("%s: closing connection.\n", ipstr);
- close(args->sock);
- free(args->addr);
- free(args);
- return(NULL);
-} /* do_http */
-
-
-static void serve_http_request(int sock, struct sockaddr *addr,
- socklen_t addrlen)
-{
- http_args *args = (http_args *) malloc(sizeof (http_args));
- if (args == NULL)
- {
- printf("out of memory.\n");
- return;
- } // if
- args->addr = (struct sockaddr *) malloc(addrlen);
- if (args->addr == NULL)
- {
- free(args);
- printf("out of memory.\n");
- return;
- } // if
-
- args->sock = sock;
- args->addrlen = addrlen;
- memcpy(args->addr, addr, addrlen);
-
- /* !!! FIXME: optionally spin a thread... */
- do_http((void *) args);
-} /* server_http_request */
-
-
-static int create_listen_socket(short portnum)
-{
- int retval = -1;
- int protocol = 0; /* pray this is right. */
-
-#ifndef LACKING_PROTOENT
- struct protoent *prot;
- setprotoent(0);
- prot = getprotobyname("tcp");
- if (prot != NULL)
- protocol = prot->p_proto;
-#endif
-
- retval = socket(PF_INET, SOCK_STREAM, protocol);
- if (retval >= 0)
- {
- struct sockaddr_in addr;
- addr.sin_family = AF_INET;
- addr.sin_port = htons(portnum);
- addr.sin_addr.s_addr = INADDR_ANY;
- if ((bind(retval, &addr, (socklen_t) sizeof (addr)) == -1) ||
- (listen(retval, 5) == -1))
- {
- close(retval);
- retval = -1;
- } /* if */
- } /* if */
-
- return(retval);
-} /* create_listen_socket */
-
-
-static int listensocket = -1;
-
-void at_exit_cleanup(void)
-{
- /*
- * !!! FIXME: If thread support, signal threads to terminate and
- * !!! FIXME: wait for them to clean up.
- */
-
- if (listensocket >= 0)
- close(listensocket);
-
- if (!PHYSFS_deinit())
- printf("PHYSFS_deinit() failed: %s\n", PHYSFS_getLastError());
-} /* at_exit_cleanup */
-
-
-int main(int argc, char **argv)
-{
- int i;
- int portnum = DEFAULT_PORTNUM;
-
- setbuf(stdout, NULL);
- setbuf(stderr, NULL);
-
-#ifndef LACKING_SIGNALS
- /* I'm not sure if this qualifies as a cheap trick... */
- signal(SIGTERM, exit);
- signal(SIGINT, exit);
- signal(SIGFPE, exit);
- signal(SIGSEGV, exit);
- signal(SIGPIPE, exit);
- signal(SIGILL, exit);
-#endif
-
- if (argc == 1)
- {
- printf("USAGE: %s <archive1> [archive2 [... archiveN]]\n", argv[0]);
- return(42);
- } /* if */
-
- if (!PHYSFS_init(argv[0]))
- {
- printf("PHYSFS_init() failed: %s\n", PHYSFS_getLastError());
- return(42);
- } /* if */
-
- /* normally, this is bad practice, but oh well. */
- atexit(at_exit_cleanup);
-
- for (i = 1; i < argc; i++)
- {
- if (!PHYSFS_addToSearchPath(argv[i], 1))
- printf(" WARNING: failed to add [%s] to search path.\n", argv[i]);
- } /* else */
-
- listensocket = create_listen_socket(portnum);
- if (listensocket < 0)
- {
- printf("listen socket failed to create.\n");
- return(42);
- } /* if */
-
- while (1) /* infinite loop for now. */
- {
- struct sockaddr addr;
- socklen_t len;
- int s = accept(listensocket, &addr, &len);
- if (s < 0)
- {
- printf("accept() failed: %s\n", strerror(errno));
- close(listensocket);
- return(42);
- } /* if */
-
- serve_http_request(s, &addr, len);
- } /* while */
-
- return(0);
-} /* main */
-
-/* end of physfshttpd.c ... */
-
+++ /dev/null
-/*
- * This code provides a glue layer between PhysicsFS and Simple Directmedia
- * Layer's (SDL) RWops i/o abstraction.
- *
- * License: this code is public domain. I make no warranty that it is useful,
- * correct, harmless, or environmentally safe.
- *
- * This particular file may be used however you like, including copying it
- * verbatim into a closed-source project, exploiting it commercially, and
- * removing any trace of my name from the source (although I hope you won't
- * do that). I welcome enhancements and corrections to this file, but I do
- * not require you to send me patches if you make changes. This code has
- * NO WARRANTY.
- *
- * Unless otherwise stated, the rest of PhysicsFS falls under the zlib license.
- * Please see LICENSE.txt in the root of the source tree.
- *
- * SDL falls under the LGPL license. You can get SDL at http://www.libsdl.org/
- *
- * This file was written by Ryan C. Gordon. (icculus@icculus.org).
- */
-
-#include <stdio.h> /* used for SEEK_SET, SEEK_CUR, SEEK_END ... */
-#include "physfsrwops.h"
-
-static int physfsrwops_seek(SDL_RWops *rw, int offset, int whence)
-{
- PHYSFS_File *handle = (PHYSFS_File *) rw->hidden.unknown.data1;
- int pos = 0;
-
- if (whence == SEEK_SET)
- {
- pos = offset;
- } /* if */
-
- else if (whence == SEEK_CUR)
- {
- PHYSFS_sint64 current = PHYSFS_tell(handle);
- if (current == -1)
- {
- SDL_SetError("Can't find position in file: %s",
- PHYSFS_getLastError());
- return(-1);
- } /* if */
-
- pos = (int) current;
- if ( ((PHYSFS_sint64) pos) != current )
- {
- SDL_SetError("Can't fit current file position in an int!");
- return(-1);
- } /* if */
-
- if (offset == 0) /* this is a "tell" call. We're done. */
- return(pos);
-
- pos += offset;
- } /* else if */
-
- else if (whence == SEEK_END)
- {
- PHYSFS_sint64 len = PHYSFS_fileLength(handle);
- if (len == -1)
- {
- SDL_SetError("Can't find end of file: %s", PHYSFS_getLastError());
- return(-1);
- } /* if */
-
- pos = (int) len;
- if ( ((PHYSFS_sint64) pos) != len )
- {
- SDL_SetError("Can't fit end-of-file position in an int!");
- return(-1);
- } /* if */
-
- pos += offset;
- } /* else if */
-
- else
- {
- SDL_SetError("Invalid 'whence' parameter.");
- return(-1);
- } /* else */
-
- if ( pos < 0 )
- {
- SDL_SetError("Attempt to seek past start of file.");
- return(-1);
- } /* if */
-
- if (!PHYSFS_seek(handle, (PHYSFS_uint64) pos))
- {
- SDL_SetError("PhysicsFS error: %s", PHYSFS_getLastError());
- return(-1);
- } /* if */
-
- return(pos);
-} /* physfsrwops_seek */
-
-
-static int physfsrwops_read(SDL_RWops *rw, void *ptr, int size, int maxnum)
-{
- PHYSFS_File *handle = (PHYSFS_File *) rw->hidden.unknown.data1;
- PHYSFS_sint64 rc = PHYSFS_read(handle, ptr, size, maxnum);
- if (rc != maxnum)
- {
- if (!PHYSFS_eof(handle)) /* not EOF? Must be an error. */
- SDL_SetError("PhysicsFS error: %s", PHYSFS_getLastError());
- } /* if */
-
- return((int) rc);
-} /* physfsrwops_read */
-
-
-static int physfsrwops_write(SDL_RWops *rw, const void *ptr, int size, int num)
-{
- PHYSFS_File *handle = (PHYSFS_File *) rw->hidden.unknown.data1;
- PHYSFS_sint64 rc = PHYSFS_write(handle, ptr, size, num);
- if (rc != num)
- SDL_SetError("PhysicsFS error: %s", PHYSFS_getLastError());
-
- return((int) rc);
-} /* physfsrwops_write */
-
-
-static int physfsrwops_close(SDL_RWops *rw)
-{
- PHYSFS_File *handle = (PHYSFS_File *) rw->hidden.unknown.data1;
- if (!PHYSFS_close(handle))
- {
- SDL_SetError("PhysicsFS error: %s", PHYSFS_getLastError());
- return(-1);
- } /* if */
-
- SDL_FreeRW(rw);
- return(0);
-} /* physfsrwops_close */
-
-
-static SDL_RWops *create_rwops(PHYSFS_File *handle)
-{
- SDL_RWops *retval = NULL;
-
- if (handle == NULL)
- SDL_SetError("PhysicsFS error: %s", PHYSFS_getLastError());
- else
- {
- retval = SDL_AllocRW();
- if (retval != NULL)
- {
- retval->seek = physfsrwops_seek;
- retval->read = physfsrwops_read;
- retval->write = physfsrwops_write;
- retval->close = physfsrwops_close;
- retval->hidden.unknown.data1 = handle;
- } /* if */
- } /* else */
-
- return(retval);
-} /* create_rwops */
-
-
-SDL_RWops *PHYSFSRWOPS_makeRWops(PHYSFS_File *handle)
-{
- SDL_RWops *retval = NULL;
- if (handle == NULL)
- SDL_SetError("NULL pointer passed to PHYSFSRWOPS_makeRWops().");
- else
- retval = create_rwops(handle);
-
- return(retval);
-} /* PHYSFSRWOPS_makeRWops */
-
-
-SDL_RWops *PHYSFSRWOPS_openRead(const char *fname)
-{
- return(create_rwops(PHYSFS_openRead(fname)));
-} /* PHYSFSRWOPS_openRead */
-
-
-SDL_RWops *PHYSFSRWOPS_openWrite(const char *fname)
-{
- return(create_rwops(PHYSFS_openWrite(fname)));
-} /* PHYSFSRWOPS_openWrite */
-
-
-SDL_RWops *PHYSFSRWOPS_openAppend(const char *fname)
-{
- return(create_rwops(PHYSFS_openAppend(fname)));
-} /* PHYSFSRWOPS_openAppend */
-
-
-/* end of physfsrwops.c ... */
-
+++ /dev/null
-/*
- * This code provides a glue layer between PhysicsFS and Simple Directmedia
- * Layer's (SDL) RWops i/o abstraction.
- *
- * License: this code is public domain. I make no warranty that it is useful,
- * correct, harmless, or environmentally safe.
- *
- * This particular file may be used however you like, including copying it
- * verbatim into a closed-source project, exploiting it commercially, and
- * removing any trace of my name from the source (although I hope you won't
- * do that). I welcome enhancements and corrections to this file, but I do
- * not require you to send me patches if you make changes. This code has
- * NO WARRANTY.
- *
- * Unless otherwise stated, the rest of PhysicsFS falls under the zlib license.
- * Please see LICENSE.txt in the root of the source tree.
- *
- * SDL falls under the LGPL license. You can get SDL at http://www.libsdl.org/
- *
- * This file was written by Ryan C. Gordon. (icculus@icculus.org).
- */
-
-#ifndef _INCLUDE_PHYSFSRWOPS_H_
-#define _INCLUDE_PHYSFSRWOPS_H_
-
-#include "physfs.h"
-#include "SDL.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/**
- * Open a platform-independent filename for reading, and make it accessible
- * via an SDL_RWops structure. The file will be closed in PhysicsFS when the
- * RWops is closed. PhysicsFS should be configured to your liking before
- * opening files through this method.
- *
- * @param filename File to open in platform-independent notation.
- * @return A valid SDL_RWops structure on success, NULL on error. Specifics
- * of the error can be gleaned from PHYSFS_getLastError().
- */
-__EXPORT__ SDL_RWops *PHYSFSRWOPS_openRead(const char *fname);
-
-/**
- * Open a platform-independent filename for writing, and make it accessible
- * via an SDL_RWops structure. The file will be closed in PhysicsFS when the
- * RWops is closed. PhysicsFS should be configured to your liking before
- * opening files through this method.
- *
- * @param filename File to open in platform-independent notation.
- * @return A valid SDL_RWops structure on success, NULL on error. Specifics
- * of the error can be gleaned from PHYSFS_getLastError().
- */
-__EXPORT__ SDL_RWops *PHYSFSRWOPS_openWrite(const char *fname);
-
-/**
- * Open a platform-independent filename for appending, and make it accessible
- * via an SDL_RWops structure. The file will be closed in PhysicsFS when the
- * RWops is closed. PhysicsFS should be configured to your liking before
- * opening files through this method.
- *
- * @param filename File to open in platform-independent notation.
- * @return A valid SDL_RWops structure on success, NULL on error. Specifics
- * of the error can be gleaned from PHYSFS_getLastError().
- */
-__EXPORT__ SDL_RWops *PHYSFSRWOPS_openAppend(const char *fname);
-
-/**
- * Make a SDL_RWops from an existing PhysicsFS file handle. You should
- * dispose of any references to the handle after successful creation of
- * the RWops. The actual PhysicsFS handle will be destroyed when the
- * RWops is closed.
- *
- * @param handle a valid PhysicsFS file handle.
- * @return A valid SDL_RWops structure on success, NULL on error. Specifics
- * of the error can be gleaned from PHYSFS_getLastError().
- */
-__EXPORT__ SDL_RWops *PHYSFSRWOPS_makeRWops(PHYSFS_File *handle);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* include-once blocker */
-
-/* end of physfsrwops.h ... */
-
+++ /dev/null
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-
-#include "physfs.h"
-
-
-static int failure = 0;
-
-static void modTimeToStr(PHYSFS_sint64 modtime, char *modstr, size_t strsize)
-{
- const char *str = "unknown modtime";
- if (modtime != -1)
- {
- time_t t = (time_t) modtime;
- str = ctime(&t);
- } /* if */
-
- strncpy(modstr, str, strsize);
- modstr[strsize-1] = '\0';
- strsize = strlen(modstr);
- while ((modstr[strsize-1] == '\n') || (modstr[strsize-1] == '\r'))
- modstr[--strsize] = '\0';
-} /* modTimeToStr */
-
-
-static void fail(const char *what, const char *why)
-{
- if (why == NULL)
- why = PHYSFS_getLastError();
- fprintf(stderr, "%s failed: %s\n", what, why);
- failure = 1;
-} /* fail */
-
-
-static void dumpFile(const char *fname)
-{
- const int origfailure = failure;
- PHYSFS_File *out = NULL;
- PHYSFS_File *in = NULL;
-
- failure = 0;
-
- if ((in = PHYSFS_openRead(fname)) == NULL)
- fail("\nPHYSFS_openRead", NULL);
- else if ((out = PHYSFS_openWrite(fname)) == NULL)
- fail("\nPHYSFS_openWrite", NULL);
- else
- {
- char modstr[64];
- PHYSFS_sint64 size = PHYSFS_fileLength(in);
-
- printf("(");
- if (size == -1)
- printf("?");
- else
- printf("%lld", (long long) size);
- printf(" bytes");
-
- modTimeToStr(PHYSFS_getLastModTime(fname), modstr, sizeof (modstr));
- printf(", %s)\n", modstr);
-
- while ( (!failure) && (!PHYSFS_eof(in)) )
- {
- static char buf[64 * 1024];
- PHYSFS_sint64 br = PHYSFS_read(in, buf, 1, sizeof (buf));
- if (br == -1)
- fail("PHYSFS_read", NULL);
- else
- {
- PHYSFS_sint64 bw = PHYSFS_write(out, buf, 1, br);
- if (bw != br)
- fail("PHYSFS_write", NULL);
- else
- size -= bw;
- } /* else */
- } /* while */
-
- if ((!failure) && (size != 0))
- fail("PHYSFS_eof", "BUG! eof != PHYSFS_fileLength bytes!");
- } /* else */
-
- if (in != NULL)
- PHYSFS_close(in);
-
- if (out != NULL)
- {
- if (!PHYSFS_close(out))
- fail("PHYSFS_close", NULL);
- } /* if */
-
- if (failure)
- PHYSFS_delete(fname);
- else
- failure = origfailure;
-} /* dumpFile */
-
-
-static void unpackCallback(void *_depth, const char *origdir, const char *str)
-{
- int depth = *((int *) _depth);
- const int len = strlen(origdir) + strlen(str) + 2;
- char *fname = (char *) malloc(len);
- if (fname == NULL)
- fail("malloc", "Out of memory!");
- else
- {
- if (strcmp(origdir, "/") == 0)
- origdir = "";
-
- snprintf(fname, len, "%s/%s", origdir, str);
-
- printf("%s ", fname);
- if (PHYSFS_isDirectory(fname))
- {
- depth++;
- printf("(directory)\n");
- if (!PHYSFS_mkdir(fname))
- fail("PHYSFS_mkdir", NULL);
- else
- PHYSFS_enumerateFilesCallback(fname, unpackCallback, &depth);
- } /* if */
-
- else if (PHYSFS_isSymbolicLink(fname))
- {
- printf("(symlink)\n");
- /* !!! FIXME: ? if (!symlink(fname, */
- } /* else if */
-
- else /* ...file. */
- {
- dumpFile(fname);
- } /* else */
-
- free(fname);
- } /* else */
-} /* unpackCallback */
-
-
-int main(int argc, char **argv)
-{
- int zero = 0;
-
- if (argc != 3)
- {
- fprintf(stderr, "USAGE: %s <archive> <unpackDirectory>\n", argv[0]);
- return 1;
- } /* if */
-
- if (!PHYSFS_init(argv[0]))
- {
- fprintf(stderr, "PHYSFS_init() failed: %s\n", PHYSFS_getLastError());
- return 2;
- } /* if */
-
- if (!PHYSFS_setWriteDir(argv[2]))
- {
- fprintf(stderr, "PHYSFS_setWriteDir('%s') failed: %s\n",
- argv[2], PHYSFS_getLastError());
- return 3;
- } /* if */
-
- if (!PHYSFS_mount(argv[1], NULL, 1))
- {
- fprintf(stderr, "PHYSFS_mount('%s') failed: %s\n",
- argv[1], PHYSFS_getLastError());
- return 4;
- } /* if */
-
- PHYSFS_permitSymbolicLinks(1);
- PHYSFS_enumerateFilesCallback("/", unpackCallback, &zero);
- PHYSFS_deinit();
- if (failure)
- return 5;
-
- return 0;
-} /* main */
-
-/* end of physfsunpack.c ... */
-
+++ /dev/null
-/*
- * This code shows how to read a zipfile included in an app's binary.
- *
- * License: this code is public domain. I make no warranty that it is useful,
- * correct, harmless, or environmentally safe.
- *
- * This particular file may be used however you like, including copying it
- * verbatim into a closed-source project, exploiting it commercially, and
- * removing any trace of my name from the source (although I hope you won't
- * do that). I welcome enhancements and corrections to this file, but I do
- * not require you to send me patches if you make changes. This code has
- * NO WARRANTY.
- *
- * Unless otherwise stated, the rest of PhysicsFS falls under the zlib license.
- * Please see LICENSE.txt in the root of the source tree.
- *
- * This file was written by Ryan C. Gordon. (icculus@icculus.org).
- */
-
-/*
- * Compile this program and then attach a .zip file to the end of the
- * compiled binary.
- *
- * On Linux, something like this will build the final binary:
- * gcc -o selfextract.tmp selfextract.c -lphysfs && \
- * cat selfextract.tmp myzipfile.zip >> selfextract && \
- * chmod a+x selfextract && \
- * rm -f selfextract.tmp
- *
- * This may not work on all platforms, and it probably only works with
- * .zip files, since they are designed to be appended to another file.
- */
-
-#include <stdio.h>
-#include "physfs.h"
-
-int main(int argc, char **argv)
-{
- int rc = 0;
-
- if (!PHYSFS_init(argv[0]))
- {
- printf("PHYSFS_init() failed: %s\n", PHYSFS_getLastError());
- return(42);
- } /* if */
-
- rc = PHYSFS_addToSearchPath(argv[0], 0);
- if (!rc)
- {
- printf("Couldn't find self-extract data: %s\n", PHYSFS_getLastError());
- printf("This might mean you didn't append a zipfile to the binary.\n");
- return(42);
- } /* if */
-
- char **files = PHYSFS_enumerateFiles("/");
- char **i;
- for (i = files; *i != NULL; i++)
- {
- const char *dirorfile = PHYSFS_isDirectory(*i) ? "Directory" : "File";
- printf(" * %s '%s' is in root of attached data.\n", dirorfile, *i);
- } /* for */
- PHYSFS_freeList(files);
-
- return(0);
-} /* main */
-
+++ /dev/null
-/* 7zAlloc.h */
-
-#ifndef __7Z_ALLOC_H
-#define __7Z_ALLOC_H
-
-#include <stddef.h>
-
-typedef struct _ISzAlloc
-{
- void *(*Alloc)(size_t size);
- void (*Free)(void *address); /* address can be 0 */
-} ISzAlloc;
-
-void *SzAlloc(size_t size);
-void SzFree(void *address);
-
-void *SzAllocTemp(size_t size);
-void SzFreeTemp(void *address);
-
-#endif
+++ /dev/null
-/* 7zBuffer.c */
-
-#include "7zBuffer.h"
-#include "7zAlloc.h"
-
-void SzByteBufferInit(CSzByteBuffer *buffer)
-{
- buffer->Capacity = 0;
- buffer->Items = 0;
-}
-
-int SzByteBufferCreate(CSzByteBuffer *buffer, size_t newCapacity, void * (*allocFunc)(size_t size))
-{
- buffer->Capacity = newCapacity;
- if (newCapacity == 0)
- {
- buffer->Items = 0;
- return 1;
- }
- buffer->Items = (Byte *)allocFunc(newCapacity);
- return (buffer->Items != 0);
-}
-
-void SzByteBufferFree(CSzByteBuffer *buffer, void (*freeFunc)(void *))
-{
- freeFunc(buffer->Items);
- buffer->Items = 0;
- buffer->Capacity = 0;
-}
+++ /dev/null
-/* 7zBuffer.h */
-
-#ifndef __7Z_BUFFER_H
-#define __7Z_BUFFER_H
-
-#include <stddef.h>
-#include "7zTypes.h"
-
-typedef struct _CSzByteBuffer
-{
- size_t Capacity;
- Byte *Items;
-}CSzByteBuffer;
-
-void SzByteBufferInit(CSzByteBuffer *buffer);
-int SzByteBufferCreate(CSzByteBuffer *buffer, size_t newCapacity, void * (*allocFunc)(size_t size));
-void SzByteBufferFree(CSzByteBuffer *buffer, void (*freeFunc)(void *));
-
-#endif
+++ /dev/null
-/* 7zCrc.c */
-
-#include "7zCrc.h"
-
-#define kCrcPoly 0xEDB88320
-
-UInt32 g_CrcTable[256];
-
-void InitCrcTable()
-{
- UInt32 i;
- for (i = 0; i < 256; i++)
- {
- UInt32 r = i;
- int j;
- for (j = 0; j < 8; j++)
- if (r & 1)
- r = (r >> 1) ^ kCrcPoly;
- else
- r >>= 1;
- g_CrcTable[i] = r;
- }
-}
-
-void CrcInit(UInt32 *crc) { *crc = 0xFFFFFFFF; }
-UInt32 CrcGetDigest(UInt32 *crc) { return *crc ^ 0xFFFFFFFF; }
-
-void CrcUpdateByte(UInt32 *crc, Byte b)
-{
- *crc = g_CrcTable[((Byte)(*crc)) ^ b] ^ (*crc >> 8);
-}
-
-void CrcUpdateUInt16(UInt32 *crc, UInt16 v)
-{
- CrcUpdateByte(crc, (Byte)v);
- CrcUpdateByte(crc, (Byte)(v >> 8));
-}
-
-void CrcUpdateUInt32(UInt32 *crc, UInt32 v)
-{
- int i;
- for (i = 0; i < 4; i++)
- CrcUpdateByte(crc, (Byte)(v >> (8 * i)));
-}
-
-void CrcUpdateUInt64(UInt32 *crc, UInt64 v)
-{
- int i;
- for (i = 0; i < 8; i++)
- {
- CrcUpdateByte(crc, (Byte)(v));
- v >>= 8;
- }
-}
-
-void CrcUpdate(UInt32 *crc, const void *data, size_t size)
-{
- UInt32 v = *crc;
- const Byte *p = (const Byte *)data;
- for (; size > 0 ; size--, p++)
- v = g_CrcTable[((Byte)(v)) ^ *p] ^ (v >> 8);
- *crc = v;
-}
-
-UInt32 CrcCalculateDigest(const void *data, size_t size)
-{
- UInt32 crc;
- CrcInit(&crc);
- CrcUpdate(&crc, data, size);
- return CrcGetDigest(&crc);
-}
-
-int CrcVerifyDigest(UInt32 digest, const void *data, size_t size)
-{
- return (CrcCalculateDigest(data, size) == digest);
-}
+++ /dev/null
-/* 7zCrc.h */
-
-#ifndef __7Z_CRC_H
-#define __7Z_CRC_H
-
-#include <stddef.h>
-
-#include "7zTypes.h"
-
-extern UInt32 g_CrcTable[256];
-void InitCrcTable();
-
-void CrcInit(UInt32 *crc);
-UInt32 CrcGetDigest(UInt32 *crc);
-void CrcUpdateByte(UInt32 *crc, Byte v);
-void CrcUpdateUInt16(UInt32 *crc, UInt16 v);
-void CrcUpdateUInt32(UInt32 *crc, UInt32 v);
-void CrcUpdateUInt64(UInt32 *crc, UInt64 v);
-void CrcUpdate(UInt32 *crc, const void *data, size_t size);
-
-UInt32 CrcCalculateDigest(const void *data, size_t size);
-int CrcVerifyDigest(UInt32 digest, const void *data, size_t size);
-
-#endif
+++ /dev/null
-/* 7zDecode.c */
-
-#include "7zDecode.h"
-#ifdef _SZ_ONE_DIRECTORY
-#include "LzmaDecode.h"
-#else
-#include "../../Compress/LZMA_C/LzmaDecode.h"
-#endif
-
-CMethodID k_Copy = { { 0x0 }, 1 };
-CMethodID k_LZMA = { { 0x3, 0x1, 0x1 }, 3 };
-
-#ifdef _LZMA_IN_CB
-
-typedef struct _CLzmaInCallbackImp
-{
- ILzmaInCallback InCallback;
- ISzInStream *InStream;
- size_t Size;
-} CLzmaInCallbackImp;
-
-int LzmaReadImp(void *object, const unsigned char **buffer, SizeT *size)
-{
- CLzmaInCallbackImp *cb = (CLzmaInCallbackImp *)object;
- size_t processedSize;
- SZ_RESULT res;
- *size = 0;
- res = cb->InStream->Read((void *)cb->InStream, (void **)buffer, cb->Size, &processedSize);
- *size = (SizeT)processedSize;
- if (processedSize > cb->Size)
- return (int)SZE_FAIL;
- cb->Size -= processedSize;
- if (res == SZ_OK)
- return 0;
- return (int)res;
-}
-
-#endif
-
-SZ_RESULT SzDecode(const CFileSize *packSizes, const CFolder *folder,
- #ifdef _LZMA_IN_CB
- ISzInStream *inStream,
- #else
- const Byte *inBuffer,
- #endif
- Byte *outBuffer, size_t outSize,
- size_t *outSizeProcessed, ISzAlloc *allocMain)
-{
- UInt32 si;
- size_t inSize = 0;
- CCoderInfo *coder;
- if (folder->NumPackStreams != 1)
- return SZE_NOTIMPL;
- if (folder->NumCoders != 1)
- return SZE_NOTIMPL;
- coder = folder->Coders;
- *outSizeProcessed = 0;
-
- for (si = 0; si < folder->NumPackStreams; si++)
- inSize += (size_t)packSizes[si];
-
- if (AreMethodsEqual(&coder->MethodID, &k_Copy))
- {
- size_t i;
- if (inSize != outSize)
- return SZE_DATA_ERROR;
- #ifdef _LZMA_IN_CB
- for (i = 0; i < inSize;)
- {
- size_t j;
- void *inBuffer;
- size_t bufferSize;
- RINOK(inStream->Read((void *)inStream, (void **)&inBuffer, inSize - i, &bufferSize));
- if (bufferSize == 0)
- return SZE_DATA_ERROR;
- if (bufferSize > inSize - i)
- return SZE_FAIL;
- *outSizeProcessed += bufferSize;
- for (j = 0; j < bufferSize && i < inSize; j++, i++)
- outBuffer[i] = ((Byte*)inBuffer)[j];
- }
- #else
- for (i = 0; i < inSize; i++)
- outBuffer[i] = inBuffer[i];
- *outSizeProcessed = inSize;
- #endif
- return SZ_OK;
- }
-
- if (AreMethodsEqual(&coder->MethodID, &k_LZMA))
- {
- #ifdef _LZMA_IN_CB
- CLzmaInCallbackImp lzmaCallback;
- #else
- SizeT inProcessed;
- #endif
-
- CLzmaDecoderState state; /* it's about 24-80 bytes structure, if int is 32-bit */
- int result;
- SizeT outSizeProcessedLoc;
-
- #ifdef _LZMA_IN_CB
- lzmaCallback.Size = inSize;
- lzmaCallback.InStream = inStream;
- lzmaCallback.InCallback.Read = LzmaReadImp;
- #endif
-
- if (LzmaDecodeProperties(&state.Properties, coder->Properties.Items,
- coder->Properties.Capacity) != LZMA_RESULT_OK)
- return SZE_FAIL;
-
- state.Probs = (CProb *)allocMain->Alloc(LzmaGetNumProbs(&state.Properties) * sizeof(CProb));
- if (state.Probs == 0)
- return SZE_OUTOFMEMORY;
-
- #ifdef _LZMA_OUT_READ
- if (state.Properties.DictionarySize == 0)
- state.Dictionary = 0;
- else
- {
- state.Dictionary = (unsigned char *)allocMain->Alloc(state.Properties.DictionarySize);
- if (state.Dictionary == 0)
- {
- allocMain->Free(state.Probs);
- return SZE_OUTOFMEMORY;
- }
- }
- LzmaDecoderInit(&state);
- #endif
-
- result = LzmaDecode(&state,
- #ifdef _LZMA_IN_CB
- &lzmaCallback.InCallback,
- #else
- inBuffer, (SizeT)inSize, &inProcessed,
- #endif
- outBuffer, (SizeT)outSize, &outSizeProcessedLoc);
- *outSizeProcessed = (size_t)outSizeProcessedLoc;
- allocMain->Free(state.Probs);
- #ifdef _LZMA_OUT_READ
- allocMain->Free(state.Dictionary);
- #endif
- if (result == LZMA_RESULT_DATA_ERROR)
- return SZE_DATA_ERROR;
- if (result != LZMA_RESULT_OK)
- return SZE_FAIL;
- return SZ_OK;
- }
- return SZE_NOTIMPL;
-}
+++ /dev/null
-/* 7zDecode.h */
-
-#ifndef __7Z_DECODE_H
-#define __7Z_DECODE_H
-
-#include "7zItem.h"
-#include "7zAlloc.h"
-#ifdef _LZMA_IN_CB
-#include "7zIn.h"
-#endif
-
-SZ_RESULT SzDecode(const CFileSize *packSizes, const CFolder *folder,
- #ifdef _LZMA_IN_CB
- ISzInStream *stream,
- #else
- const Byte *inBuffer,
- #endif
- Byte *outBuffer, size_t outSize,
- size_t *outSizeProcessed, ISzAlloc *allocMain);
-
-#endif
+++ /dev/null
-/* 7zExtract.c */
-
-#include "7zExtract.h"
-#include "7zDecode.h"
-#include "7zCrc.h"
-
-SZ_RESULT SzExtract(
- ISzInStream *inStream,
- CArchiveDatabaseEx *db,
- UInt32 fileIndex,
- UInt32 *blockIndex,
- Byte **outBuffer,
- size_t *outBufferSize,
- size_t *offset,
- size_t *outSizeProcessed,
- ISzAlloc *allocMain,
- ISzAlloc *allocTemp)
-{
- UInt32 folderIndex = db->FileIndexToFolderIndexMap[fileIndex];
- SZ_RESULT res = SZ_OK;
- *offset = 0;
- *outSizeProcessed = 0;
- if (folderIndex == (UInt32)-1)
- {
- allocMain->Free(*outBuffer);
- *blockIndex = folderIndex;
- *outBuffer = 0;
- *outBufferSize = 0;
- return SZ_OK;
- }
-
- if (*outBuffer == 0 || *blockIndex != folderIndex)
- {
- CFolder *folder = db->Database.Folders + folderIndex;
- CFileSize unPackSize = SzFolderGetUnPackSize(folder);
- #ifndef _LZMA_IN_CB
- CFileSize packSize = SzArDbGetFolderFullPackSize(db, folderIndex);
- Byte *inBuffer = 0;
- size_t processedSize;
- #endif
- *blockIndex = folderIndex;
- allocMain->Free(*outBuffer);
- *outBuffer = 0;
-
- RINOK(inStream->Seek(inStream, SzArDbGetFolderStreamPos(db, folderIndex, 0)));
-
- #ifndef _LZMA_IN_CB
- if (packSize != 0)
- {
- inBuffer = (Byte *)allocTemp->Alloc((size_t)packSize);
- if (inBuffer == 0)
- return SZE_OUTOFMEMORY;
- }
- res = inStream->Read(inStream, inBuffer, (size_t)packSize, &processedSize);
- if (res == SZ_OK && processedSize != (size_t)packSize)
- res = SZE_FAIL;
- #endif
- if (res == SZ_OK)
- {
- *outBufferSize = (size_t)unPackSize;
- if (unPackSize != 0)
- {
- *outBuffer = (Byte *)allocMain->Alloc((size_t)unPackSize);
- if (*outBuffer == 0)
- res = SZE_OUTOFMEMORY;
- }
- if (res == SZ_OK)
- {
- size_t outRealSize;
- res = SzDecode(db->Database.PackSizes +
- db->FolderStartPackStreamIndex[folderIndex], folder,
- #ifdef _LZMA_IN_CB
- inStream,
- #else
- inBuffer,
- #endif
- *outBuffer, (size_t)unPackSize, &outRealSize, allocTemp);
- if (res == SZ_OK)
- {
- if (outRealSize == (size_t)unPackSize)
- {
- if (folder->UnPackCRCDefined)
- {
- if (!CrcVerifyDigest(folder->UnPackCRC, *outBuffer, (size_t)unPackSize))
- res = SZE_FAIL;
- }
- }
- else
- res = SZE_FAIL;
- }
- }
- }
- #ifndef _LZMA_IN_CB
- allocTemp->Free(inBuffer);
- #endif
- }
- if (res == SZ_OK)
- {
- UInt32 i;
- CFileItem *fileItem = db->Database.Files + fileIndex;
- *offset = 0;
- for(i = db->FolderStartFileIndex[folderIndex]; i < fileIndex; i++)
- *offset += (UInt32)db->Database.Files[i].Size;
- *outSizeProcessed = (size_t)fileItem->Size;
- if (*offset + *outSizeProcessed > *outBufferSize)
- return SZE_FAIL;
- {
- if (fileItem->IsFileCRCDefined)
- {
- if (!CrcVerifyDigest(fileItem->FileCRC, *outBuffer + *offset, *outSizeProcessed))
- res = SZE_FAIL;
- }
- }
- }
- return res;
-}
+++ /dev/null
-/* 7zExtract.h */
-
-#ifndef __7Z_EXTRACT_H
-#define __7Z_EXTRACT_H
-
-#include "7zIn.h"
-
-/*
- SzExtract extracts file from archive
-
- *outBuffer must be 0 before first call for each new archive.
-
- Extracting cache:
- If you need to decompress more than one file, you can send
- these values from previous call:
- *blockIndex,
- *outBuffer,
- *outBufferSize
- You can consider "*outBuffer" as cache of solid block. If your archive is solid,
- it will increase decompression speed.
-
- If you use external function, you can declare these 3 cache variables
- (blockIndex, outBuffer, outBufferSize) as static in that external function.
-
- Free *outBuffer and set *outBuffer to 0, if you want to flush cache.
-*/
-
-SZ_RESULT SzExtract(
- ISzInStream *inStream,
- CArchiveDatabaseEx *db,
- UInt32 fileIndex, /* index of file */
- UInt32 *blockIndex, /* index of solid block */
- Byte **outBuffer, /* pointer to pointer to output buffer (allocated with allocMain) */
- size_t *outBufferSize, /* buffer size for output buffer */
- size_t *offset, /* offset of stream for required file in *outBuffer */
- size_t *outSizeProcessed, /* size of file in *outBuffer */
- ISzAlloc *allocMain,
- ISzAlloc *allocTemp);
-
-#endif
+++ /dev/null
-/* 7zHeader.c */
-
-#include "7zHeader.h"
-
-Byte k7zSignature[k7zSignatureSize] = {'7', 'z', 0xBC, 0xAF, 0x27, 0x1C};
+++ /dev/null
-/* 7zHeader.h */
-
-#ifndef __7Z_HEADER_H
-#define __7Z_HEADER_H
-
-#include "7zTypes.h"
-
-#define k7zSignatureSize 6
-extern Byte k7zSignature[k7zSignatureSize];
-
-#define k7zMajorVersion 0
-
-#define k7zStartHeaderSize 0x20
-
-enum EIdEnum
-{
- k7zIdEnd,
-
- k7zIdHeader,
-
- k7zIdArchiveProperties,
-
- k7zIdAdditionalStreamsInfo,
- k7zIdMainStreamsInfo,
- k7zIdFilesInfo,
-
- k7zIdPackInfo,
- k7zIdUnPackInfo,
- k7zIdSubStreamsInfo,
-
- k7zIdSize,
- k7zIdCRC,
-
- k7zIdFolder,
-
- k7zIdCodersUnPackSize,
- k7zIdNumUnPackStream,
-
- k7zIdEmptyStream,
- k7zIdEmptyFile,
- k7zIdAnti,
-
- k7zIdName,
- k7zIdCreationTime,
- k7zIdLastAccessTime,
- k7zIdLastWriteTime,
- k7zIdWinAttributes,
- k7zIdComment,
-
- k7zIdEncodedHeader,
-
- k7zIdStartPos
-};
-
-#endif
+++ /dev/null
-/* 7zIn.c */
-
-#include "7zIn.h"
-#include "7zCrc.h"
-#include "7zDecode.h"
-
-#define RINOM(x) { if((x) == 0) return SZE_OUTOFMEMORY; }
-
-void SzArDbExInit(CArchiveDatabaseEx *db)
-{
- SzArchiveDatabaseInit(&db->Database);
- db->FolderStartPackStreamIndex = 0;
- db->PackStreamStartPositions = 0;
- db->FolderStartFileIndex = 0;
- db->FileIndexToFolderIndexMap = 0;
-}
-
-void SzArDbExFree(CArchiveDatabaseEx *db, void (*freeFunc)(void *))
-{
- freeFunc(db->FolderStartPackStreamIndex);
- freeFunc(db->PackStreamStartPositions);
- freeFunc(db->FolderStartFileIndex);
- freeFunc(db->FileIndexToFolderIndexMap);
- SzArchiveDatabaseFree(&db->Database, freeFunc);
- SzArDbExInit(db);
-}
-
-/*
-CFileSize GetFolderPackStreamSize(int folderIndex, int streamIndex) const
-{
- return PackSizes[FolderStartPackStreamIndex[folderIndex] + streamIndex];
-}
-
-CFileSize GetFilePackSize(int fileIndex) const
-{
- int folderIndex = FileIndexToFolderIndexMap[fileIndex];
- if (folderIndex >= 0)
- {
- const CFolder &folderInfo = Folders[folderIndex];
- if (FolderStartFileIndex[folderIndex] == fileIndex)
- return GetFolderFullPackSize(folderIndex);
- }
- return 0;
-}
-*/
-
-#define MY_ALLOC(T, p, size, allocFunc) { if ((size) == 0) p = 0; else \
- if ((p = (T *)allocFunc((size) * sizeof(T))) == 0) return SZE_OUTOFMEMORY; }
-
-SZ_RESULT SzArDbExFill(CArchiveDatabaseEx *db, void * (*allocFunc)(size_t size))
-{
- UInt32 startPos = 0;
- CFileSize startPosSize = 0;
- UInt32 i;
- UInt32 folderIndex = 0;
- UInt32 indexInFolder = 0;
- MY_ALLOC(UInt32, db->FolderStartPackStreamIndex, db->Database.NumFolders, allocFunc);
- for(i = 0; i < db->Database.NumFolders; i++)
- {
- db->FolderStartPackStreamIndex[i] = startPos;
- startPos += db->Database.Folders[i].NumPackStreams;
- }
-
- MY_ALLOC(CFileSize, db->PackStreamStartPositions, db->Database.NumPackStreams, allocFunc);
-
- for(i = 0; i < db->Database.NumPackStreams; i++)
- {
- db->PackStreamStartPositions[i] = startPosSize;
- startPosSize += db->Database.PackSizes[i];
- }
-
- MY_ALLOC(UInt32, db->FolderStartFileIndex, db->Database.NumFolders, allocFunc);
- MY_ALLOC(UInt32, db->FileIndexToFolderIndexMap, db->Database.NumFiles, allocFunc);
-
- for (i = 0; i < db->Database.NumFiles; i++)
- {
- CFileItem *file = db->Database.Files + i;
- int emptyStream = !file->HasStream;
- if (emptyStream && indexInFolder == 0)
- {
- db->FileIndexToFolderIndexMap[i] = (UInt32)-1;
- continue;
- }
- if (indexInFolder == 0)
- {
- /*
- v3.13 incorrectly worked with empty folders
- v4.07: Loop for skipping empty folders
- */
- while(1)
- {
- if (folderIndex >= db->Database.NumFolders)
- return SZE_ARCHIVE_ERROR;
- db->FolderStartFileIndex[folderIndex] = i;
- if (db->Database.Folders[folderIndex].NumUnPackStreams != 0)
- break;
- folderIndex++;
- }
- }
- db->FileIndexToFolderIndexMap[i] = folderIndex;
- if (emptyStream)
- continue;
- indexInFolder++;
- if (indexInFolder >= db->Database.Folders[folderIndex].NumUnPackStreams)
- {
- folderIndex++;
- indexInFolder = 0;
- }
- }
- return SZ_OK;
-}
-
-
-CFileSize SzArDbGetFolderStreamPos(CArchiveDatabaseEx *db, UInt32 folderIndex, UInt32 indexInFolder)
-{
- return db->ArchiveInfo.DataStartPosition +
- db->PackStreamStartPositions[db->FolderStartPackStreamIndex[folderIndex] + indexInFolder];
-}
-
-CFileSize SzArDbGetFolderFullPackSize(CArchiveDatabaseEx *db, UInt32 folderIndex)
-{
- UInt32 packStreamIndex = db->FolderStartPackStreamIndex[folderIndex];
- CFolder *folder = db->Database.Folders + folderIndex;
- CFileSize size = 0;
- UInt32 i;
- for (i = 0; i < folder->NumPackStreams; i++)
- size += db->Database.PackSizes[packStreamIndex + i];
- return size;
-}
-
-
-/*
-SZ_RESULT SzReadTime(const CObjectVector<CSzByteBuffer> &dataVector,
- CObjectVector<CFileItem> &files, UInt64 type)
-{
- CBoolVector boolVector;
- RINOK(ReadBoolVector2(files.Size(), boolVector))
-
- CStreamSwitch streamSwitch;
- RINOK(streamSwitch.Set(this, &dataVector));
-
- for(int i = 0; i < files.Size(); i++)
- {
- CFileItem &file = files[i];
- CArchiveFileTime fileTime;
- bool defined = boolVector[i];
- if (defined)
- {
- UInt32 low, high;
- RINOK(SzReadUInt32(low));
- RINOK(SzReadUInt32(high));
- fileTime.dwLowDateTime = low;
- fileTime.dwHighDateTime = high;
- }
- switch(type)
- {
- case k7zIdCreationTime:
- file.IsCreationTimeDefined = defined;
- if (defined)
- file.CreationTime = fileTime;
- break;
- case k7zIdLastWriteTime:
- file.IsLastWriteTimeDefined = defined;
- if (defined)
- file.LastWriteTime = fileTime;
- break;
- case k7zIdLastAccessTime:
- file.IsLastAccessTimeDefined = defined;
- if (defined)
- file.LastAccessTime = fileTime;
- break;
- }
- }
- return SZ_OK;
-}
-*/
-
-SZ_RESULT SafeReadDirect(ISzInStream *inStream, Byte *data, size_t size)
-{
- #ifdef _LZMA_IN_CB
- while (size > 0)
- {
- void *inBuffer; // Dennis Schridde: Make this compile with -Wall -Werror. Was Byte* before.
- size_t processedSize;
- RINOK(inStream->Read(inStream, (void **)&inBuffer, size, &processedSize));
- if (processedSize == 0 || processedSize > size)
- return SZE_FAIL;
- size -= processedSize;
- do
- {
- *(data++) = *((Byte*)inBuffer);
- inBuffer = ((Byte*) inBuffer) + 1;
- }
- while (--processedSize != 0);
- }
- #else
- size_t processedSize;
- RINOK(inStream->Read(inStream, data, size, &processedSize));
- if (processedSize != size)
- return SZE_FAIL;
- #endif
- return SZ_OK;
-}
-
-SZ_RESULT SafeReadDirectByte(ISzInStream *inStream, Byte *data)
-{
- return SafeReadDirect(inStream, data, 1);
-}
-
-SZ_RESULT SafeReadDirectUInt32(ISzInStream *inStream, UInt32 *value)
-{
- int i;
- *value = 0;
- for (i = 0; i < 4; i++)
- {
- Byte b;
- RINOK(SafeReadDirectByte(inStream, &b));
- *value |= ((UInt32)b << (8 * i));
- }
- return SZ_OK;
-}
-
-SZ_RESULT SafeReadDirectUInt64(ISzInStream *inStream, UInt64 *value)
-{
- int i;
- *value = 0;
- for (i = 0; i < 8; i++)
- {
- Byte b;
- RINOK(SafeReadDirectByte(inStream, &b));
- *value |= ((UInt32)b << (8 * i));
- }
- return SZ_OK;
-}
-
-int TestSignatureCandidate(Byte *testBytes)
-{
- size_t i;
- for (i = 0; i < k7zSignatureSize; i++)
- if (testBytes[i] != k7zSignature[i])
- return 0;
- return 1;
-}
-
-typedef struct _CSzState
-{
- Byte *Data;
- size_t Size;
-}CSzData;
-
-SZ_RESULT SzReadByte(CSzData *sd, Byte *b)
-{
- if (sd->Size == 0)
- return SZE_ARCHIVE_ERROR;
- sd->Size--;
- *b = *sd->Data++;
- return SZ_OK;
-}
-
-SZ_RESULT SzReadBytes(CSzData *sd, Byte *data, size_t size)
-{
- size_t i;
- for (i = 0; i < size; i++)
- {
- RINOK(SzReadByte(sd, data + i));
- }
- return SZ_OK;
-}
-
-SZ_RESULT SzReadUInt32(CSzData *sd, UInt32 *value)
-{
- int i;
- *value = 0;
- for (i = 0; i < 4; i++)
- {
- Byte b;
- RINOK(SzReadByte(sd, &b));
- *value |= ((UInt32)(b) << (8 * i));
- }
- return SZ_OK;
-}
-
-SZ_RESULT SzReadNumber(CSzData *sd, UInt64 *value)
-{
- Byte firstByte;
- Byte mask = 0x80;
- int i;
- RINOK(SzReadByte(sd, &firstByte));
- *value = 0;
- for (i = 0; i < 8; i++)
- {
- Byte b;
- if ((firstByte & mask) == 0)
- {
- UInt64 highPart = firstByte & (mask - 1);
- *value += (highPart << (8 * i));
- return SZ_OK;
- }
- RINOK(SzReadByte(sd, &b));
- *value |= ((UInt64)b << (8 * i));
- mask >>= 1;
- }
- return SZ_OK;
-}
-
-SZ_RESULT SzReadSize(CSzData *sd, CFileSize *value)
-{
- UInt64 value64;
- RINOK(SzReadNumber(sd, &value64));
- *value = (CFileSize)value64;
- return SZ_OK;
-}
-
-SZ_RESULT SzReadNumber32(CSzData *sd, UInt32 *value)
-{
- UInt64 value64;
- RINOK(SzReadNumber(sd, &value64));
- if (value64 >= 0x80000000)
- return SZE_NOTIMPL;
- if (value64 >= ((UInt64)(1) << ((sizeof(size_t) - 1) * 8 + 2)))
- return SZE_NOTIMPL;
- *value = (UInt32)value64;
- return SZ_OK;
-}
-
-SZ_RESULT SzReadID(CSzData *sd, UInt64 *value)
-{
- return SzReadNumber(sd, value);
-}
-
-SZ_RESULT SzSkeepDataSize(CSzData *sd, UInt64 size)
-{
- if (size > sd->Size)
- return SZE_ARCHIVE_ERROR;
- sd->Size -= (size_t)size;
- sd->Data += (size_t)size;
- return SZ_OK;
-}
-
-SZ_RESULT SzSkeepData(CSzData *sd)
-{
- UInt64 size;
- RINOK(SzReadNumber(sd, &size));
- return SzSkeepDataSize(sd, size);
-}
-
-SZ_RESULT SzReadArchiveProperties(CSzData *sd)
-{
- while(1)
- {
- UInt64 type;
- RINOK(SzReadID(sd, &type));
- if (type == k7zIdEnd)
- break;
- SzSkeepData(sd);
- }
- return SZ_OK;
-}
-
-SZ_RESULT SzWaitAttribute(CSzData *sd, UInt64 attribute)
-{
- while(1)
- {
- UInt64 type;
- RINOK(SzReadID(sd, &type));
- if (type == attribute)
- return SZ_OK;
- if (type == k7zIdEnd)
- return SZE_ARCHIVE_ERROR;
- RINOK(SzSkeepData(sd));
- }
-}
-
-SZ_RESULT SzReadBoolVector(CSzData *sd, size_t numItems, Byte **v, void * (*allocFunc)(size_t size))
-{
- Byte b = 0;
- Byte mask = 0;
- size_t i;
- MY_ALLOC(Byte, *v, numItems, allocFunc);
- for(i = 0; i < numItems; i++)
- {
- if (mask == 0)
- {
- RINOK(SzReadByte(sd, &b));
- mask = 0x80;
- }
- (*v)[i] = (Byte)(((b & mask) != 0) ? 1 : 0);
- mask >>= 1;
- }
- return SZ_OK;
-}
-
-SZ_RESULT SzReadBoolVector2(CSzData *sd, size_t numItems, Byte **v, void * (*allocFunc)(size_t size))
-{
- Byte allAreDefined;
- size_t i;
- RINOK(SzReadByte(sd, &allAreDefined));
- if (allAreDefined == 0)
- return SzReadBoolVector(sd, numItems, v, allocFunc);
- MY_ALLOC(Byte, *v, numItems, allocFunc);
- for(i = 0; i < numItems; i++)
- (*v)[i] = 1;
- return SZ_OK;
-}
-
-SZ_RESULT SzReadHashDigests(
- CSzData *sd,
- size_t numItems,
- Byte **digestsDefined,
- UInt32 **digests,
- void * (*allocFunc)(size_t size))
-{
- size_t i;
- RINOK(SzReadBoolVector2(sd, numItems, digestsDefined, allocFunc));
- MY_ALLOC(UInt32, *digests, numItems, allocFunc);
- for(i = 0; i < numItems; i++)
- if ((*digestsDefined)[i])
- {
- RINOK(SzReadUInt32(sd, (*digests) + i));
- }
- return SZ_OK;
-}
-
-SZ_RESULT SzReadPackInfo(
- CSzData *sd,
- CFileSize *dataOffset,
- UInt32 *numPackStreams,
- CFileSize **packSizes,
- Byte **packCRCsDefined,
- UInt32 **packCRCs,
- void * (*allocFunc)(size_t size))
-{
- UInt32 i;
- RINOK(SzReadSize(sd, dataOffset));
- RINOK(SzReadNumber32(sd, numPackStreams));
-
- RINOK(SzWaitAttribute(sd, k7zIdSize));
-
- MY_ALLOC(CFileSize, *packSizes, (size_t)*numPackStreams, allocFunc);
-
- for(i = 0; i < *numPackStreams; i++)
- {
- RINOK(SzReadSize(sd, (*packSizes) + i));
- }
-
- while(1)
- {
- UInt64 type;
- RINOK(SzReadID(sd, &type));
- if (type == k7zIdEnd)
- break;
- if (type == k7zIdCRC)
- {
- RINOK(SzReadHashDigests(sd, (size_t)*numPackStreams, packCRCsDefined, packCRCs, allocFunc));
- continue;
- }
- RINOK(SzSkeepData(sd));
- }
- if (*packCRCsDefined == 0)
- {
- MY_ALLOC(Byte, *packCRCsDefined, (size_t)*numPackStreams, allocFunc);
- MY_ALLOC(UInt32, *packCRCs, (size_t)*numPackStreams, allocFunc);
- for(i = 0; i < *numPackStreams; i++)
- {
- (*packCRCsDefined)[i] = 0;
- (*packCRCs)[i] = 0;
- }
- }
- return SZ_OK;
-}
-
-SZ_RESULT SzReadSwitch(CSzData *sd)
-{
- Byte external;
- RINOK(SzReadByte(sd, &external));
- return (external == 0) ? SZ_OK: SZE_ARCHIVE_ERROR;
-}
-
-SZ_RESULT SzGetNextFolderItem(CSzData *sd, CFolder *folder, void * (*allocFunc)(size_t size))
-{
- UInt32 numCoders;
- UInt32 numBindPairs;
- UInt32 numPackedStreams;
- UInt32 i;
- UInt32 numInStreams = 0;
- UInt32 numOutStreams = 0;
- RINOK(SzReadNumber32(sd, &numCoders));
- folder->NumCoders = numCoders;
-
- MY_ALLOC(CCoderInfo, folder->Coders, (size_t)numCoders, allocFunc);
-
- for (i = 0; i < numCoders; i++)
- SzCoderInfoInit(folder->Coders + i);
-
- for (i = 0; i < numCoders; i++)
- {
- Byte mainByte;
- CCoderInfo *coder = folder->Coders + i;
- {
- RINOK(SzReadByte(sd, &mainByte));
- coder->MethodID.IDSize = (Byte)(mainByte & 0xF);
- RINOK(SzReadBytes(sd, coder->MethodID.ID, coder->MethodID.IDSize));
- if ((mainByte & 0x10) != 0)
- {
- RINOK(SzReadNumber32(sd, &coder->NumInStreams));
- RINOK(SzReadNumber32(sd, &coder->NumOutStreams));
- }
- else
- {
- coder->NumInStreams = 1;
- coder->NumOutStreams = 1;
- }
- if ((mainByte & 0x20) != 0)
- {
- UInt64 propertiesSize = 0;
- RINOK(SzReadNumber(sd, &propertiesSize));
- if (!SzByteBufferCreate(&coder->Properties, (size_t)propertiesSize, allocFunc))
- return SZE_OUTOFMEMORY;
- RINOK(SzReadBytes(sd, coder->Properties.Items, (size_t)propertiesSize));
- }
- }
- while ((mainByte & 0x80) != 0)
- {
- RINOK(SzReadByte(sd, &mainByte));
- RINOK(SzSkeepDataSize(sd, (mainByte & 0xF)));
- if ((mainByte & 0x10) != 0)
- {
- UInt32 n;
- RINOK(SzReadNumber32(sd, &n));
- RINOK(SzReadNumber32(sd, &n));
- }
- if ((mainByte & 0x20) != 0)
- {
- UInt64 propertiesSize = 0;
- RINOK(SzReadNumber(sd, &propertiesSize));
- RINOK(SzSkeepDataSize(sd, propertiesSize));
- }
- }
- numInStreams += (UInt32)coder->NumInStreams;
- numOutStreams += (UInt32)coder->NumOutStreams;
- }
-
- numBindPairs = numOutStreams - 1;
- folder->NumBindPairs = numBindPairs;
-
-
- MY_ALLOC(CBindPair, folder->BindPairs, (size_t)numBindPairs, allocFunc);
-
- for (i = 0; i < numBindPairs; i++)
- {
- CBindPair *bindPair = folder->BindPairs + i;;
- RINOK(SzReadNumber32(sd, &bindPair->InIndex));
- RINOK(SzReadNumber32(sd, &bindPair->OutIndex));
- }
-
- numPackedStreams = numInStreams - (UInt32)numBindPairs;
-
- folder->NumPackStreams = numPackedStreams;
- MY_ALLOC(UInt32, folder->PackStreams, (size_t)numPackedStreams, allocFunc);
-
- if (numPackedStreams == 1)
- {
- UInt32 j;
- UInt32 pi = 0;
- for (j = 0; j < numInStreams; j++)
- if (SzFolderFindBindPairForInStream(folder, j) < 0)
- {
- folder->PackStreams[pi++] = j;
- break;
- }
- }
- else
- for(i = 0; i < numPackedStreams; i++)
- {
- RINOK(SzReadNumber32(sd, folder->PackStreams + i));
- }
- return SZ_OK;
-}
-
-SZ_RESULT SzReadUnPackInfo(
- CSzData *sd,
- UInt32 *numFolders,
- CFolder **folders, /* for allocFunc */
- void * (*allocFunc)(size_t size),
- ISzAlloc *allocTemp)
-{
- UInt32 i;
- RINOK(SzWaitAttribute(sd, k7zIdFolder));
- RINOK(SzReadNumber32(sd, numFolders));
- {
- RINOK(SzReadSwitch(sd));
-
- MY_ALLOC(CFolder, *folders, (size_t)*numFolders, allocFunc);
-
- for(i = 0; i < *numFolders; i++)
- SzFolderInit((*folders) + i);
-
- for(i = 0; i < *numFolders; i++)
- {
- RINOK(SzGetNextFolderItem(sd, (*folders) + i, allocFunc));
- }
- }
-
- RINOK(SzWaitAttribute(sd, k7zIdCodersUnPackSize));
-
- for(i = 0; i < *numFolders; i++)
- {
- UInt32 j;
- CFolder *folder = (*folders) + i;
- UInt32 numOutStreams = SzFolderGetNumOutStreams(folder);
-
- MY_ALLOC(CFileSize, folder->UnPackSizes, (size_t)numOutStreams, allocFunc);
-
- for(j = 0; j < numOutStreams; j++)
- {
- RINOK(SzReadSize(sd, folder->UnPackSizes + j));
- }
- }
-
- while(1)
- {
- UInt64 type;
- RINOK(SzReadID(sd, &type));
- if (type == k7zIdEnd)
- return SZ_OK;
- if (type == k7zIdCRC)
- {
- SZ_RESULT res;
- Byte *crcsDefined = 0;
- UInt32 *crcs = 0;
- res = SzReadHashDigests(sd, *numFolders, &crcsDefined, &crcs, allocTemp->Alloc);
- if (res == SZ_OK)
- {
- for(i = 0; i < *numFolders; i++)
- {
- CFolder *folder = (*folders) + i;
- folder->UnPackCRCDefined = crcsDefined[i];
- folder->UnPackCRC = crcs[i];
- }
- }
- allocTemp->Free(crcs);
- allocTemp->Free(crcsDefined);
- RINOK(res);
- continue;
- }
- RINOK(SzSkeepData(sd));
- }
-}
-
-SZ_RESULT SzReadSubStreamsInfo(
- CSzData *sd,
- UInt32 numFolders,
- CFolder *folders,
- UInt32 *numUnPackStreams,
- CFileSize **unPackSizes,
- Byte **digestsDefined,
- UInt32 **digests,
- ISzAlloc *allocTemp)
-{
- UInt64 type = 0;
- UInt32 i;
- UInt32 si = 0;
- UInt32 numDigests = 0;
-
- for(i = 0; i < numFolders; i++)
- folders[i].NumUnPackStreams = 1;
- *numUnPackStreams = numFolders;
-
- while(1)
- {
- RINOK(SzReadID(sd, &type));
- if (type == k7zIdNumUnPackStream)
- {
- *numUnPackStreams = 0;
- for(i = 0; i < numFolders; i++)
- {
- UInt32 numStreams;
- RINOK(SzReadNumber32(sd, &numStreams));
- folders[i].NumUnPackStreams = numStreams;
- *numUnPackStreams += numStreams;
- }
- continue;
- }
- if (type == k7zIdCRC || type == k7zIdSize)
- break;
- if (type == k7zIdEnd)
- break;
- RINOK(SzSkeepData(sd));
- }
-
- if (*numUnPackStreams == 0)
- {
- *unPackSizes = 0;
- *digestsDefined = 0;
- *digests = 0;
- }
- else
- {
- *unPackSizes = (CFileSize *)allocTemp->Alloc((size_t)*numUnPackStreams * sizeof(CFileSize));
- RINOM(*unPackSizes);
- *digestsDefined = (Byte *)allocTemp->Alloc((size_t)*numUnPackStreams * sizeof(Byte));
- RINOM(*digestsDefined);
- *digests = (UInt32 *)allocTemp->Alloc((size_t)*numUnPackStreams * sizeof(UInt32));
- RINOM(*digests);
- }
-
- for(i = 0; i < numFolders; i++)
- {
- /*
- v3.13 incorrectly worked with empty folders
- v4.07: we check that folder is empty
- */
- CFileSize sum = 0;
- UInt32 j;
- UInt32 numSubstreams = folders[i].NumUnPackStreams;
- if (numSubstreams == 0)
- continue;
- if (type == k7zIdSize)
- for (j = 1; j < numSubstreams; j++)
- {
- CFileSize size;
- RINOK(SzReadSize(sd, &size));
- (*unPackSizes)[si++] = size;
- sum += size;
- }
- (*unPackSizes)[si++] = SzFolderGetUnPackSize(folders + i) - sum;
- }
- if (type == k7zIdSize)
- {
- RINOK(SzReadID(sd, &type));
- }
-
- for(i = 0; i < *numUnPackStreams; i++)
- {
- (*digestsDefined)[i] = 0;
- (*digests)[i] = 0;
- }
-
-
- for(i = 0; i < numFolders; i++)
- {
- UInt32 numSubstreams = folders[i].NumUnPackStreams;
- if (numSubstreams != 1 || !folders[i].UnPackCRCDefined)
- numDigests += numSubstreams;
- }
-
-
- si = 0;
- while(1)
- {
- if (type == k7zIdCRC)
- {
- int digestIndex = 0;
- Byte *digestsDefined2 = 0;
- UInt32 *digests2 = 0;
- SZ_RESULT res = SzReadHashDigests(sd, numDigests, &digestsDefined2, &digests2, allocTemp->Alloc);
- if (res == SZ_OK)
- {
- for (i = 0; i < numFolders; i++)
- {
- CFolder *folder = folders + i;
- UInt32 numSubstreams = folder->NumUnPackStreams;
- if (numSubstreams == 1 && folder->UnPackCRCDefined)
- {
- (*digestsDefined)[si] = 1;
- (*digests)[si] = folder->UnPackCRC;
- si++;
- }
- else
- {
- UInt32 j;
- for (j = 0; j < numSubstreams; j++, digestIndex++)
- {
- (*digestsDefined)[si] = digestsDefined2[digestIndex];
- (*digests)[si] = digests2[digestIndex];
- si++;
- }
- }
- }
- }
- allocTemp->Free(digestsDefined2);
- allocTemp->Free(digests2);
- RINOK(res);
- }
- else if (type == k7zIdEnd)
- return SZ_OK;
- else
- {
- RINOK(SzSkeepData(sd));
- }
- RINOK(SzReadID(sd, &type));
- }
-}
-
-
-SZ_RESULT SzReadStreamsInfo(
- CSzData *sd,
- CFileSize *dataOffset,
- CArchiveDatabase *db,
- UInt32 *numUnPackStreams,
- CFileSize **unPackSizes, /* allocTemp */
- Byte **digestsDefined, /* allocTemp */
- UInt32 **digests, /* allocTemp */
- void * (*allocFunc)(size_t size),
- ISzAlloc *allocTemp)
-{
- while(1)
- {
- UInt64 type;
- RINOK(SzReadID(sd, &type));
- if ((UInt64)(int)type != type)
- return SZE_FAIL;
- switch((int)type)
- {
- case k7zIdEnd:
- return SZ_OK;
- case k7zIdPackInfo:
- {
- RINOK(SzReadPackInfo(sd, dataOffset, &db->NumPackStreams,
- &db->PackSizes, &db->PackCRCsDefined, &db->PackCRCs, allocFunc));
- break;
- }
- case k7zIdUnPackInfo:
- {
- RINOK(SzReadUnPackInfo(sd, &db->NumFolders, &db->Folders, allocFunc, allocTemp));
- break;
- }
- case k7zIdSubStreamsInfo:
- {
- RINOK(SzReadSubStreamsInfo(sd, db->NumFolders, db->Folders,
- numUnPackStreams, unPackSizes, digestsDefined, digests, allocTemp));
- break;
- }
- default:
- return SZE_FAIL;
- }
- }
-}
-
-Byte kUtf8Limits[5] = { 0xC0, 0xE0, 0xF0, 0xF8, 0xFC };
-
-SZ_RESULT SzReadFileNames(CSzData *sd, UInt32 numFiles, CFileItem *files,
- void * (*allocFunc)(size_t size))
-{
- UInt32 i;
- for(i = 0; i < numFiles; i++)
- {
- UInt32 len = 0;
- UInt32 pos = 0;
- CFileItem *file = files + i;
- while(pos + 2 <= sd->Size)
- {
- int numAdds;
- UInt32 value = (UInt32)(sd->Data[pos] | (((UInt32)sd->Data[pos + 1]) << 8));
- pos += 2;
- len++;
- if (value == 0)
- break;
- if (value < 0x80)
- continue;
- if (value >= 0xD800 && value < 0xE000)
- {
- UInt32 c2;
- if (value >= 0xDC00)
- return SZE_ARCHIVE_ERROR;
- if (pos + 2 > sd->Size)
- return SZE_ARCHIVE_ERROR;
- c2 = (UInt32)(sd->Data[pos] | (((UInt32)sd->Data[pos + 1]) << 8));
- pos += 2;
- if (c2 < 0xDC00 || c2 >= 0xE000)
- return SZE_ARCHIVE_ERROR;
- value = ((value - 0xD800) << 10) | (c2 - 0xDC00);
- }
- for (numAdds = 1; numAdds < 5; numAdds++)
- if (value < (((UInt32)1) << (numAdds * 5 + 6)))
- break;
- len += numAdds;
- }
-
- MY_ALLOC(char, file->Name, (size_t)len, allocFunc);
-
- len = 0;
- while(2 <= sd->Size)
- {
- int numAdds;
- UInt32 value = (UInt32)(sd->Data[0] | (((UInt32)sd->Data[1]) << 8));
- SzSkeepDataSize(sd, 2);
- if (value < 0x80)
- {
- file->Name[len++] = (char)value;
- if (value == 0)
- break;
- continue;
- }
- if (value >= 0xD800 && value < 0xE000)
- {
- UInt32 c2 = (UInt32)(sd->Data[0] | (((UInt32)sd->Data[1]) << 8));
- SzSkeepDataSize(sd, 2);
- value = ((value - 0xD800) << 10) | (c2 - 0xDC00);
- }
- for (numAdds = 1; numAdds < 5; numAdds++)
- if (value < (((UInt32)1) << (numAdds * 5 + 6)))
- break;
- file->Name[len++] = (char)(kUtf8Limits[numAdds - 1] + (value >> (6 * numAdds)));
- do
- {
- numAdds--;
- file->Name[len++] = (char)(0x80 + ((value >> (6 * numAdds)) & 0x3F));
- }
- while(numAdds > 0);
-
- len += numAdds;
- }
- }
- return SZ_OK;
-}
-
-SZ_RESULT SzReadHeader2(
- CSzData *sd,
- CArchiveDatabaseEx *db, /* allocMain */
- CFileSize **unPackSizes, /* allocTemp */
- Byte **digestsDefined, /* allocTemp */
- UInt32 **digests, /* allocTemp */
- Byte **emptyStreamVector, /* allocTemp */
- Byte **emptyFileVector, /* allocTemp */
- ISzAlloc *allocMain,
- ISzAlloc *allocTemp)
-{
- UInt64 type;
- UInt32 numUnPackStreams = 0;
- UInt32 numFiles = 0;
- CFileItem *files = 0;
- UInt32 numEmptyStreams = 0;
- UInt32 i;
-
- RINOK(SzReadID(sd, &type));
-
- if (type == k7zIdArchiveProperties)
- {
- RINOK(SzReadArchiveProperties(sd));
- RINOK(SzReadID(sd, &type));
- }
-
-
- if (type == k7zIdMainStreamsInfo)
- {
- RINOK(SzReadStreamsInfo(sd,
- &db->ArchiveInfo.DataStartPosition,
- &db->Database,
- &numUnPackStreams,
- unPackSizes,
- digestsDefined,
- digests, allocMain->Alloc, allocTemp));
- db->ArchiveInfo.DataStartPosition += db->ArchiveInfo.StartPositionAfterHeader;
- RINOK(SzReadID(sd, &type));
- }
-
- if (type == k7zIdEnd)
- return SZ_OK;
- if (type != k7zIdFilesInfo)
- return SZE_ARCHIVE_ERROR;
-
- RINOK(SzReadNumber32(sd, &numFiles));
- db->Database.NumFiles = numFiles;
-
- MY_ALLOC(CFileItem, files, (size_t)numFiles, allocMain->Alloc);
-
- db->Database.Files = files;
- for(i = 0; i < numFiles; i++)
- SzFileInit(files + i);
-
- while(1)
- {
- UInt64 type;
- UInt64 size;
- RINOK(SzReadID(sd, &type));
- if (type == k7zIdEnd)
- break;
- RINOK(SzReadNumber(sd, &size));
-
- if ((UInt64)(int)type != type)
- {
- RINOK(SzSkeepDataSize(sd, size));
- }
- else
- switch((int)type)
- {
- case k7zIdName:
- {
- RINOK(SzReadSwitch(sd));
- RINOK(SzReadFileNames(sd, numFiles, files, allocMain->Alloc))
- break;
- }
- case k7zIdEmptyStream:
- {
- RINOK(SzReadBoolVector(sd, numFiles, emptyStreamVector, allocTemp->Alloc));
- numEmptyStreams = 0;
- for (i = 0; i < numFiles; i++)
- if ((*emptyStreamVector)[i])
- numEmptyStreams++;
- break;
- }
- case k7zIdEmptyFile:
- {
- RINOK(SzReadBoolVector(sd, numEmptyStreams, emptyFileVector, allocTemp->Alloc));
- break;
- }
- default:
- {
- RINOK(SzSkeepDataSize(sd, size));
- }
- }
- }
-
- {
- UInt32 emptyFileIndex = 0;
- UInt32 sizeIndex = 0;
- for(i = 0; i < numFiles; i++)
- {
- CFileItem *file = files + i;
- file->IsAnti = 0;
- if (*emptyStreamVector == 0)
- file->HasStream = 1;
- else
- file->HasStream = (Byte)((*emptyStreamVector)[i] ? 0 : 1);
- if(file->HasStream)
- {
- file->IsDirectory = 0;
- file->Size = (*unPackSizes)[sizeIndex];
- file->FileCRC = (*digests)[sizeIndex];
- file->IsFileCRCDefined = (Byte)(*digestsDefined)[sizeIndex];
- sizeIndex++;
- }
- else
- {
- if (*emptyFileVector == 0)
- file->IsDirectory = 1;
- else
- file->IsDirectory = (Byte)((*emptyFileVector)[emptyFileIndex] ? 0 : 1);
- emptyFileIndex++;
- file->Size = 0;
- file->IsFileCRCDefined = 0;
- }
- }
- }
- return SzArDbExFill(db, allocMain->Alloc);
-}
-
-SZ_RESULT SzReadHeader(
- CSzData *sd,
- CArchiveDatabaseEx *db,
- ISzAlloc *allocMain,
- ISzAlloc *allocTemp)
-{
- CFileSize *unPackSizes = 0;
- Byte *digestsDefined = 0;
- UInt32 *digests = 0;
- Byte *emptyStreamVector = 0;
- Byte *emptyFileVector = 0;
- SZ_RESULT res = SzReadHeader2(sd, db,
- &unPackSizes, &digestsDefined, &digests,
- &emptyStreamVector, &emptyFileVector,
- allocMain, allocTemp);
- allocTemp->Free(unPackSizes);
- allocTemp->Free(digestsDefined);
- allocTemp->Free(digests);
- allocTemp->Free(emptyStreamVector);
- allocTemp->Free(emptyFileVector);
- return res;
-}
-
-SZ_RESULT SzReadAndDecodePackedStreams2(
- ISzInStream *inStream,
- CSzData *sd,
- CSzByteBuffer *outBuffer,
- CFileSize baseOffset,
- CArchiveDatabase *db,
- CFileSize **unPackSizes,
- Byte **digestsDefined,
- UInt32 **digests,
- #ifndef _LZMA_IN_CB
- Byte **inBuffer,
- #endif
- ISzAlloc *allocTemp)
-{
-
- UInt32 numUnPackStreams = 0;
- CFileSize dataStartPos;
- CFolder *folder;
- #ifndef _LZMA_IN_CB
- CFileSize packSize = 0;
- UInt32 i = 0;
- #endif
- CFileSize unPackSize;
- size_t outRealSize;
- SZ_RESULT res;
-
- RINOK(SzReadStreamsInfo(sd, &dataStartPos, db,
- &numUnPackStreams, unPackSizes, digestsDefined, digests,
- allocTemp->Alloc, allocTemp));
-
- dataStartPos += baseOffset;
- if (db->NumFolders != 1)
- return SZE_ARCHIVE_ERROR;
-
- folder = db->Folders;
- unPackSize = SzFolderGetUnPackSize(folder);
-
- RINOK(inStream->Seek(inStream, dataStartPos));
-
- #ifndef _LZMA_IN_CB
- for (i = 0; i < db->NumPackStreams; i++)
- packSize += db->PackSizes[i];
-
- MY_ALLOC(Byte, *inBuffer, (size_t)packSize, allocTemp->Alloc);
-
- RINOK(SafeReadDirect(inStream, *inBuffer, (size_t)packSize));
- #endif
-
- if (!SzByteBufferCreate(outBuffer, (size_t)unPackSize, allocTemp->Alloc))
- return SZE_OUTOFMEMORY;
-
- res = SzDecode(db->PackSizes, folder,
- #ifdef _LZMA_IN_CB
- inStream,
- #else
- *inBuffer,
- #endif
- outBuffer->Items, (size_t)unPackSize,
- &outRealSize, allocTemp);
- RINOK(res)
- if (outRealSize != (UInt32)unPackSize)
- return SZE_FAIL;
- if (folder->UnPackCRCDefined)
- if (!CrcVerifyDigest(folder->UnPackCRC, outBuffer->Items, (size_t)unPackSize))
- return SZE_FAIL;
- return SZ_OK;
-}
-
-SZ_RESULT SzReadAndDecodePackedStreams(
- ISzInStream *inStream,
- CSzData *sd,
- CSzByteBuffer *outBuffer,
- CFileSize baseOffset,
- ISzAlloc *allocTemp)
-{
- CArchiveDatabase db;
- CFileSize *unPackSizes = 0;
- Byte *digestsDefined = 0;
- UInt32 *digests = 0;
- #ifndef _LZMA_IN_CB
- Byte *inBuffer = 0;
- #endif
- SZ_RESULT res;
- SzArchiveDatabaseInit(&db);
- res = SzReadAndDecodePackedStreams2(inStream, sd, outBuffer, baseOffset,
- &db, &unPackSizes, &digestsDefined, &digests,
- #ifndef _LZMA_IN_CB
- &inBuffer,
- #endif
- allocTemp);
- SzArchiveDatabaseFree(&db, allocTemp->Free);
- allocTemp->Free(unPackSizes);
- allocTemp->Free(digestsDefined);
- allocTemp->Free(digests);
- #ifndef _LZMA_IN_CB
- allocTemp->Free(inBuffer);
- #endif
- return res;
-}
-
-SZ_RESULT SzArchiveOpen2(
- ISzInStream *inStream,
- CArchiveDatabaseEx *db,
- ISzAlloc *allocMain,
- ISzAlloc *allocTemp)
-{
- Byte signature[k7zSignatureSize];
- Byte version;
- UInt32 crcFromArchive;
- UInt64 nextHeaderOffset;
- UInt64 nextHeaderSize;
- UInt32 nextHeaderCRC;
- UInt32 crc;
- CFileSize pos = 0;
- CSzByteBuffer buffer;
- CSzData sd;
- SZ_RESULT res;
-
- RINOK(SafeReadDirect(inStream, signature, k7zSignatureSize));
-
- if (!TestSignatureCandidate(signature))
- return SZE_ARCHIVE_ERROR;
-
- /*
- db.Clear();
- db.ArchiveInfo.StartPosition = _arhiveBeginStreamPosition;
- */
- RINOK(SafeReadDirectByte(inStream, &version));
- if (version != k7zMajorVersion)
- return SZE_ARCHIVE_ERROR;
- RINOK(SafeReadDirectByte(inStream, &version));
-
- RINOK(SafeReadDirectUInt32(inStream, &crcFromArchive));
-
- CrcInit(&crc);
- RINOK(SafeReadDirectUInt64(inStream, &nextHeaderOffset));
- CrcUpdateUInt64(&crc, nextHeaderOffset);
- RINOK(SafeReadDirectUInt64(inStream, &nextHeaderSize));
- CrcUpdateUInt64(&crc, nextHeaderSize);
- RINOK(SafeReadDirectUInt32(inStream, &nextHeaderCRC));
- CrcUpdateUInt32(&crc, nextHeaderCRC);
-
- pos = k7zStartHeaderSize;
- db->ArchiveInfo.StartPositionAfterHeader = pos;
-
- if (CrcGetDigest(&crc) != crcFromArchive)
- return SZE_ARCHIVE_ERROR;
-
- if (nextHeaderSize == 0)
- return SZ_OK;
-
- RINOK(inStream->Seek(inStream, (CFileSize)(pos + nextHeaderOffset)));
-
- if (!SzByteBufferCreate(&buffer, (size_t)nextHeaderSize, allocTemp->Alloc))
- return SZE_OUTOFMEMORY;
-
- res = SafeReadDirect(inStream, buffer.Items, (size_t)nextHeaderSize);
- if (res == SZ_OK)
- {
- if (CrcVerifyDigest(nextHeaderCRC, buffer.Items, (UInt32)nextHeaderSize))
- {
- while (1)
- {
- UInt64 type;
- sd.Data = buffer.Items;
- sd.Size = buffer.Capacity;
- res = SzReadID(&sd, &type);
- if (res != SZ_OK)
- break;
- if (type == k7zIdHeader)
- {
- res = SzReadHeader(&sd, db, allocMain, allocTemp);
- break;
- }
- if (type != k7zIdEncodedHeader)
- {
- res = SZE_ARCHIVE_ERROR;
- break;
- }
- {
- CSzByteBuffer outBuffer;
- res = SzReadAndDecodePackedStreams(inStream, &sd, &outBuffer,
- db->ArchiveInfo.StartPositionAfterHeader,
- allocTemp);
- if (res != SZ_OK)
- {
- SzByteBufferFree(&outBuffer, allocTemp->Free);
- break;
- }
- SzByteBufferFree(&buffer, allocTemp->Free);
- buffer.Items = outBuffer.Items;
- buffer.Capacity = outBuffer.Capacity;
- }
- }
- }
- }
- SzByteBufferFree(&buffer, allocTemp->Free);
- return res;
-}
-
-SZ_RESULT SzArchiveOpen(
- ISzInStream *inStream,
- CArchiveDatabaseEx *db,
- ISzAlloc *allocMain,
- ISzAlloc *allocTemp)
-{
- SZ_RESULT res = SzArchiveOpen2(inStream, db, allocMain, allocTemp);
- if (res != SZ_OK)
- SzArDbExFree(db, allocMain->Free);
- return res;
-}
+++ /dev/null
-/* 7zIn.h */
-
-#ifndef __7Z_IN_H
-#define __7Z_IN_H
-
-#include "7zHeader.h"
-#include "7zItem.h"
-#include "7zAlloc.h"
-
-typedef struct _CInArchiveInfo
-{
- CFileSize StartPositionAfterHeader;
- CFileSize DataStartPosition;
-}CInArchiveInfo;
-
-typedef struct _CArchiveDatabaseEx
-{
- CArchiveDatabase Database;
- CInArchiveInfo ArchiveInfo;
- UInt32 *FolderStartPackStreamIndex;
- CFileSize *PackStreamStartPositions;
- UInt32 *FolderStartFileIndex;
- UInt32 *FileIndexToFolderIndexMap;
-}CArchiveDatabaseEx;
-
-void SzArDbExInit(CArchiveDatabaseEx *db);
-void SzArDbExFree(CArchiveDatabaseEx *db, void (*freeFunc)(void *));
-CFileSize SzArDbGetFolderStreamPos(CArchiveDatabaseEx *db, UInt32 folderIndex, UInt32 indexInFolder);
-CFileSize SzArDbGetFolderFullPackSize(CArchiveDatabaseEx *db, UInt32 folderIndex);
-
-typedef struct _ISzInStream
-{
- #ifdef _LZMA_IN_CB
- SZ_RESULT (*Read)(
- void *object, /* pointer to ISzInStream itself */
- void **buffer, /* out: pointer to buffer with data */
- size_t maxRequiredSize, /* max required size to read */
- size_t *processedSize); /* real processed size.
- processedSize can be less than maxRequiredSize.
- If processedSize == 0, then there are no more
- bytes in stream. */
- #else
- SZ_RESULT (*Read)(void *object, void *buffer, size_t size, size_t *processedSize);
- #endif
- SZ_RESULT (*Seek)(void *object, CFileSize pos);
-} ISzInStream;
-
-
-int SzArchiveOpen(
- ISzInStream *inStream,
- CArchiveDatabaseEx *db,
- ISzAlloc *allocMain,
- ISzAlloc *allocTemp);
-
-#endif
+++ /dev/null
-/* 7zItem.c */
-
-#include "7zItem.h"
-#include "7zAlloc.h"
-
-void SzCoderInfoInit(CCoderInfo *coder)
-{
- SzByteBufferInit(&coder->Properties);
-}
-
-void SzCoderInfoFree(CCoderInfo *coder, void (*freeFunc)(void *p))
-{
- SzByteBufferFree(&coder->Properties, freeFunc);
- SzCoderInfoInit(coder);
-}
-
-void SzFolderInit(CFolder *folder)
-{
- folder->NumCoders = 0;
- folder->Coders = 0;
- folder->NumBindPairs = 0;
- folder->BindPairs = 0;
- folder->NumPackStreams = 0;
- folder->PackStreams = 0;
- folder->UnPackSizes = 0;
- folder->UnPackCRCDefined = 0;
- folder->UnPackCRC = 0;
- folder->NumUnPackStreams = 0;
-}
-
-void SzFolderFree(CFolder *folder, void (*freeFunc)(void *p))
-{
- UInt32 i;
- for (i = 0; i < folder->NumCoders; i++)
- SzCoderInfoFree(&folder->Coders[i], freeFunc);
- freeFunc(folder->Coders);
- freeFunc(folder->BindPairs);
- freeFunc(folder->PackStreams);
- freeFunc(folder->UnPackSizes);
- SzFolderInit(folder);
-}
-
-UInt32 SzFolderGetNumOutStreams(CFolder *folder)
-{
- UInt32 result = 0;
- UInt32 i;
- for (i = 0; i < folder->NumCoders; i++)
- result += folder->Coders[i].NumOutStreams;
- return result;
-}
-
-int SzFolderFindBindPairForInStream(CFolder *folder, UInt32 inStreamIndex)
-{
- UInt32 i;
- for(i = 0; i < folder->NumBindPairs; i++)
- if (folder->BindPairs[i].InIndex == inStreamIndex)
- return i;
- return -1;
-}
-
-
-int SzFolderFindBindPairForOutStream(CFolder *folder, UInt32 outStreamIndex)
-{
- UInt32 i;
- for(i = 0; i < folder->NumBindPairs; i++)
- if (folder->BindPairs[i].OutIndex == outStreamIndex)
- return i;
- return -1;
-}
-
-CFileSize SzFolderGetUnPackSize(CFolder *folder)
-{
- int i = (int)SzFolderGetNumOutStreams(folder);
- if (i == 0)
- return 0;
- for (i--; i >= 0; i--)
- if (SzFolderFindBindPairForOutStream(folder, i) < 0)
- return folder->UnPackSizes[i];
- /* throw 1; */
- return 0;
-}
-
-/*
-int FindPackStreamArrayIndex(int inStreamIndex) const
-{
- for(int i = 0; i < PackStreams.Size(); i++)
- if (PackStreams[i] == inStreamIndex)
- return i;
- return -1;
-}
-*/
-
-void SzFileInit(CFileItem *fileItem)
-{
- fileItem->IsFileCRCDefined = 0;
- fileItem->HasStream = 1;
- fileItem->IsDirectory = 0;
- fileItem->IsAnti = 0;
- fileItem->Name = 0;
-}
-
-void SzFileFree(CFileItem *fileItem, void (*freeFunc)(void *p))
-{
- freeFunc(fileItem->Name);
- SzFileInit(fileItem);
-}
-
-void SzArchiveDatabaseInit(CArchiveDatabase *db)
-{
- db->NumPackStreams = 0;
- db->PackSizes = 0;
- db->PackCRCsDefined = 0;
- db->PackCRCs = 0;
- db->NumFolders = 0;
- db->Folders = 0;
- db->NumFiles = 0;
- db->Files = 0;
-}
-
-void SzArchiveDatabaseFree(CArchiveDatabase *db, void (*freeFunc)(void *))
-{
- UInt32 i;
- for (i = 0; i < db->NumFolders; i++)
- SzFolderFree(&db->Folders[i], freeFunc);
- for (i = 0; i < db->NumFiles; i++)
- SzFileFree(&db->Files[i], freeFunc);
- freeFunc(db->PackSizes);
- freeFunc(db->PackCRCsDefined);
- freeFunc(db->PackCRCs);
- freeFunc(db->Folders);
- freeFunc(db->Files);
- SzArchiveDatabaseInit(db);
-}
+++ /dev/null
-/* 7zItem.h */
-
-#ifndef __7Z_ITEM_H
-#define __7Z_ITEM_H
-
-#include "7zMethodID.h"
-#include "7zHeader.h"
-#include "7zBuffer.h"
-
-typedef struct _CCoderInfo
-{
- UInt32 NumInStreams;
- UInt32 NumOutStreams;
- CMethodID MethodID;
- CSzByteBuffer Properties;
-}CCoderInfo;
-
-void SzCoderInfoInit(CCoderInfo *coder);
-void SzCoderInfoFree(CCoderInfo *coder, void (*freeFunc)(void *p));
-
-typedef struct _CBindPair
-{
- UInt32 InIndex;
- UInt32 OutIndex;
-}CBindPair;
-
-typedef struct _CFolder
-{
- UInt32 NumCoders;
- CCoderInfo *Coders;
- UInt32 NumBindPairs;
- CBindPair *BindPairs;
- UInt32 NumPackStreams;
- UInt32 *PackStreams;
- CFileSize *UnPackSizes;
- int UnPackCRCDefined;
- UInt32 UnPackCRC;
-
- UInt32 NumUnPackStreams;
-}CFolder;
-
-void SzFolderInit(CFolder *folder);
-CFileSize SzFolderGetUnPackSize(CFolder *folder);
-int SzFolderFindBindPairForInStream(CFolder *folder, UInt32 inStreamIndex);
-UInt32 SzFolderGetNumOutStreams(CFolder *folder);
-CFileSize SzFolderGetUnPackSize(CFolder *folder);
-
-/* #define CArchiveFileTime UInt64 */
-
-typedef struct _CFileItem
-{
- /*
- CArchiveFileTime LastWriteTime;
- CFileSize StartPos;
- UInt32 Attributes;
- */
- CFileSize Size;
- UInt32 FileCRC;
- char *Name;
-
- Byte IsFileCRCDefined;
- Byte HasStream;
- Byte IsDirectory;
- Byte IsAnti;
- /*
- int AreAttributesDefined;
- int IsLastWriteTimeDefined;
- int IsStartPosDefined;
- */
-}CFileItem;
-
-void SzFileInit(CFileItem *fileItem);
-
-typedef struct _CArchiveDatabase
-{
- UInt32 NumPackStreams;
- CFileSize *PackSizes;
- Byte *PackCRCsDefined;
- UInt32 *PackCRCs;
- UInt32 NumFolders;
- CFolder *Folders;
- UInt32 NumFiles;
- CFileItem *Files;
-}CArchiveDatabase;
-
-void SzArchiveDatabaseInit(CArchiveDatabase *db);
-void SzArchiveDatabaseFree(CArchiveDatabase *db, void (*freeFunc)(void *));
-
-
-#endif
+++ /dev/null
-/* 7zMethodID.c */
-
-#include "7zMethodID.h"
-
-int AreMethodsEqual(CMethodID *a1, CMethodID *a2)
-{
- int i;
- if (a1->IDSize != a2->IDSize)
- return 0;
- for (i = 0; i < a1->IDSize; i++)
- if (a1->ID[i] != a2->ID[i])
- return 0;
- return 1;
-}
+++ /dev/null
-/* 7zMethodID.h */
-
-#ifndef __7Z_METHOD_ID_H
-#define __7Z_METHOD_ID_H
-
-#include "7zTypes.h"
-
-#define kMethodIDSize 15
-
-typedef struct _CMethodID
-{
- Byte ID[kMethodIDSize];
- Byte IDSize;
-} CMethodID;
-
-int AreMethodsEqual(CMethodID *a1, CMethodID *a2);
-
-#endif
+++ /dev/null
-/* 7zTypes.h */
-
-#ifndef __COMMON_TYPES_H
-#define __COMMON_TYPES_H
-
-#ifndef _7ZIP_BYTE_DEFINED
-#define _7ZIP_BYTE_DEFINED
-typedef unsigned char Byte;
-#endif
-
-#ifndef _7ZIP_UINT16_DEFINED
-#define _7ZIP_UINT16_DEFINED
-typedef unsigned short UInt16;
-#endif
-
-#ifndef _7ZIP_UINT32_DEFINED
-#define _7ZIP_UINT32_DEFINED
-#ifdef _LZMA_UINT32_IS_ULONG
-typedef unsigned long UInt32;
-#else
-typedef unsigned int UInt32;
-#endif
-#endif
-
-/* #define _SZ_NO_INT_64 */
-/* define it your compiler doesn't support long long int */
-
-#ifndef _7ZIP_UINT64_DEFINED
-#define _7ZIP_UINT64_DEFINED
-#ifdef _SZ_NO_INT_64
-typedef unsigned long UInt64;
-#else
-#ifdef _MSC_VER
-typedef unsigned __int64 UInt64;
-#else
-typedef unsigned long long int UInt64;
-#endif
-#endif
-#endif
-
-
-/* #define _SZ_FILE_SIZE_64 */
-/* Use _SZ_FILE_SIZE_64 if you need support for files larger than 4 GB*/
-
-#ifndef CFileSize
-#ifdef _SZ_FILE_SIZE_64
-typedef UInt64 CFileSize;
-#else
-typedef UInt32 CFileSize;
-#endif
-#endif
-
-#define SZ_RESULT int
-
-#define SZ_OK (0)
-#define SZE_DATA_ERROR (1)
-#define SZE_OUTOFMEMORY (2)
-#define SZE_CRC_ERROR (3)
-
-#define SZE_NOTIMPL (4)
-#define SZE_FAIL (5)
-
-#define SZE_ARCHIVE_ERROR (6)
-
-#define RINOK(x) { int __result_ = (x); if(__result_ != 0) return __result_; }
-
-#endif
+++ /dev/null
-(These are the licensing details for this directory, taken from lzma.txt in
- the original source distribution. The basic gist is you can do what you want
- with this code, including sell it in a closed-source app...changes to LZMA
- itself must be released as source code, which in the case of PhysicsFS, you
- can just point people to our source code repository unless you make further
- changes yourself. --ryan.)
-
-
-LZMA SDK 4.43
--------------
-
-LZMA SDK Copyright (C) 1999-2006 Igor Pavlov
-
-LZMA SDK provides the documentation, samples, header files, libraries,
-and tools you need to develop applications that use LZMA compression.
-
-LZMA is default and general compression method of 7z format
-in 7-Zip compression program (www.7-zip.org). LZMA provides high
-compression ratio and very fast decompression.
-
-LZMA is an improved version of famous LZ77 compression algorithm.
-It was improved in way of maximum increasing of compression ratio,
-keeping high decompression speed and low memory requirements for
-decompressing.
-
-
-
-LICENSE
--------
-
-LZMA SDK is available under any of the following licenses:
-
-1) GNU Lesser General Public License (GNU LGPL)
-2) Common Public License (CPL)
-3) Simplified license for unmodified code (read SPECIAL EXCEPTION)
-4) Proprietary license
-
-It means that you can select one of these four options and follow rules of that license.
-
-
-1,2) GNU LGPL and CPL licenses are pretty similar and both these
-licenses are classified as
- - "Free software licenses" at http://www.gnu.org/
- - "OSI-approved" at http://www.opensource.org/
-
-
-3) SPECIAL EXCEPTION
-
-Igor Pavlov, as the author of this code, expressly permits you
-to statically or dynamically link your code (or bind by name)
-to the files from LZMA SDK without subjecting your linked
-code to the terms of the CPL or GNU LGPL.
-Any modifications or additions to files from LZMA SDK, however,
-are subject to the GNU LGPL or CPL terms.
-
-SPECIAL EXCEPTION allows you to use LZMA SDK in applications with closed code,
-while you keep LZMA SDK code unmodified.
-
-
-SPECIAL EXCEPTION #2: Igor Pavlov, as the author of this code, expressly permits
-you to use this code under the same terms and conditions contained in the License
-Agreement you have for any previous version of LZMA SDK developed by Igor Pavlov.
-
-SPECIAL EXCEPTION #2 allows owners of proprietary licenses to use latest version
-of LZMA SDK as update for previous versions.
-
-
-SPECIAL EXCEPTION #3: Igor Pavlov, as the author of this code, expressly permits
-you to use code of the following files:
-BranchTypes.h, LzmaTypes.h, LzmaTest.c, LzmaStateTest.c, LzmaAlone.cpp,
-LzmaAlone.cs, LzmaAlone.java
-as public domain code.
-
-
-4) Proprietary license
-
-LZMA SDK also can be available under a proprietary license which
-can include:
-
-1) Right to modify code without subjecting modified code to the
-terms of the CPL or GNU LGPL
-2) Technical support for code
-
-To request such proprietary license or any additional consultations,
-send email message from that page:
-http://www.7-zip.org/support.html
-
-
-You should have received a copy of the GNU Lesser General Public
-License along with this library; if not, write to the Free Software
-Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-You should have received a copy of the Common Public License
-along with this library.
+++ /dev/null
-/*
- LzmaDecode.c
- LZMA Decoder (optimized for Speed version)
-
- LZMA SDK 4.40 Copyright (c) 1999-2006 Igor Pavlov (2006-05-01)
- http://www.7-zip.org/
-
- LZMA SDK is licensed under two licenses:
- 1) GNU Lesser General Public License (GNU LGPL)
- 2) Common Public License (CPL)
- It means that you can select one of these two licenses and
- follow rules of that license.
-
- SPECIAL EXCEPTION:
- Igor Pavlov, as the author of this Code, expressly permits you to
- statically or dynamically link your Code (or bind by name) to the
- interfaces of this file without subjecting your linked Code to the
- terms of the CPL or GNU LGPL. Any modifications or additions
- to this file, however, are subject to the LGPL or CPL terms.
-*/
-
-#include "LzmaDecode.h"
-
-#define kNumTopBits 24
-#define kTopValue ((UInt32)1 << kNumTopBits)
-
-#define kNumBitModelTotalBits 11
-#define kBitModelTotal (1 << kNumBitModelTotalBits)
-#define kNumMoveBits 5
-
-#define RC_READ_BYTE (*Buffer++)
-
-#define RC_INIT2 Code = 0; Range = 0xFFFFFFFF; \
- { int i; for(i = 0; i < 5; i++) { RC_TEST; Code = (Code << 8) | RC_READ_BYTE; }}
-
-#ifdef _LZMA_IN_CB
-
-#define RC_TEST { if (Buffer == BufferLim) \
- { SizeT size; int result = InCallback->Read(InCallback, &Buffer, &size); if (result != LZMA_RESULT_OK) return result; \
- BufferLim = Buffer + size; if (size == 0) return LZMA_RESULT_DATA_ERROR; }}
-
-#define RC_INIT Buffer = BufferLim = 0; RC_INIT2
-
-#else
-
-#define RC_TEST { if (Buffer == BufferLim) return LZMA_RESULT_DATA_ERROR; }
-
-#define RC_INIT(buffer, bufferSize) Buffer = buffer; BufferLim = buffer + bufferSize; RC_INIT2
-
-#endif
-
-#define RC_NORMALIZE if (Range < kTopValue) { RC_TEST; Range <<= 8; Code = (Code << 8) | RC_READ_BYTE; }
-
-#define IfBit0(p) RC_NORMALIZE; bound = (Range >> kNumBitModelTotalBits) * *(p); if (Code < bound)
-#define UpdateBit0(p) Range = bound; *(p) += (kBitModelTotal - *(p)) >> kNumMoveBits;
-#define UpdateBit1(p) Range -= bound; Code -= bound; *(p) -= (*(p)) >> kNumMoveBits;
-
-#define RC_GET_BIT2(p, mi, A0, A1) IfBit0(p) \
- { UpdateBit0(p); mi <<= 1; A0; } else \
- { UpdateBit1(p); mi = (mi + mi) + 1; A1; }
-
-#define RC_GET_BIT(p, mi) RC_GET_BIT2(p, mi, ; , ;)
-
-#define RangeDecoderBitTreeDecode(probs, numLevels, res) \
- { int i = numLevels; res = 1; \
- do { CProb *p = probs + res; RC_GET_BIT(p, res) } while(--i != 0); \
- res -= (1 << numLevels); }
-
-
-#define kNumPosBitsMax 4
-#define kNumPosStatesMax (1 << kNumPosBitsMax)
-
-#define kLenNumLowBits 3
-#define kLenNumLowSymbols (1 << kLenNumLowBits)
-#define kLenNumMidBits 3
-#define kLenNumMidSymbols (1 << kLenNumMidBits)
-#define kLenNumHighBits 8
-#define kLenNumHighSymbols (1 << kLenNumHighBits)
-
-#define LenChoice 0
-#define LenChoice2 (LenChoice + 1)
-#define LenLow (LenChoice2 + 1)
-#define LenMid (LenLow + (kNumPosStatesMax << kLenNumLowBits))
-#define LenHigh (LenMid + (kNumPosStatesMax << kLenNumMidBits))
-#define kNumLenProbs (LenHigh + kLenNumHighSymbols)
-
-
-#define kNumStates 12
-#define kNumLitStates 7
-
-#define kStartPosModelIndex 4
-#define kEndPosModelIndex 14
-#define kNumFullDistances (1 << (kEndPosModelIndex >> 1))
-
-#define kNumPosSlotBits 6
-#define kNumLenToPosStates 4
-
-#define kNumAlignBits 4
-#define kAlignTableSize (1 << kNumAlignBits)
-
-#define kMatchMinLen 2
-
-#define IsMatch 0
-#define IsRep (IsMatch + (kNumStates << kNumPosBitsMax))
-#define IsRepG0 (IsRep + kNumStates)
-#define IsRepG1 (IsRepG0 + kNumStates)
-#define IsRepG2 (IsRepG1 + kNumStates)
-#define IsRep0Long (IsRepG2 + kNumStates)
-#define PosSlot (IsRep0Long + (kNumStates << kNumPosBitsMax))
-#define SpecPos (PosSlot + (kNumLenToPosStates << kNumPosSlotBits))
-#define Align (SpecPos + kNumFullDistances - kEndPosModelIndex)
-#define LenCoder (Align + kAlignTableSize)
-#define RepLenCoder (LenCoder + kNumLenProbs)
-#define Literal (RepLenCoder + kNumLenProbs)
-
-#if Literal != LZMA_BASE_SIZE
-StopCompilingDueBUG
-#endif
-
-int LzmaDecodeProperties(CLzmaProperties *propsRes, const unsigned char *propsData, int size)
-{
- unsigned char prop0;
- if (size < LZMA_PROPERTIES_SIZE)
- return LZMA_RESULT_DATA_ERROR;
- prop0 = propsData[0];
- if (prop0 >= (9 * 5 * 5))
- return LZMA_RESULT_DATA_ERROR;
- {
- for (propsRes->pb = 0; prop0 >= (9 * 5); propsRes->pb++, prop0 -= (9 * 5));
- for (propsRes->lp = 0; prop0 >= 9; propsRes->lp++, prop0 -= 9);
- propsRes->lc = prop0;
- /*
- unsigned char remainder = (unsigned char)(prop0 / 9);
- propsRes->lc = prop0 % 9;
- propsRes->pb = remainder / 5;
- propsRes->lp = remainder % 5;
- */
- }
-
- #ifdef _LZMA_OUT_READ
- {
- int i;
- propsRes->DictionarySize = 0;
- for (i = 0; i < 4; i++)
- propsRes->DictionarySize += (UInt32)(propsData[1 + i]) << (i * 8);
- if (propsRes->DictionarySize == 0)
- propsRes->DictionarySize = 1;
- }
- #endif
- return LZMA_RESULT_OK;
-}
-
-#define kLzmaStreamWasFinishedId (-1)
-
-int LzmaDecode(CLzmaDecoderState *vs,
- #ifdef _LZMA_IN_CB
- ILzmaInCallback *InCallback,
- #else
- const unsigned char *inStream, SizeT inSize, SizeT *inSizeProcessed,
- #endif
- unsigned char *outStream, SizeT outSize, SizeT *outSizeProcessed)
-{
- CProb *p = vs->Probs;
- SizeT nowPos = 0;
- Byte previousByte = 0;
- UInt32 posStateMask = (1 << (vs->Properties.pb)) - 1;
- UInt32 literalPosMask = (1 << (vs->Properties.lp)) - 1;
- int lc = vs->Properties.lc;
-
- #ifdef _LZMA_OUT_READ
-
- UInt32 Range = vs->Range;
- UInt32 Code = vs->Code;
- #ifdef _LZMA_IN_CB
- const Byte *Buffer = vs->Buffer;
- const Byte *BufferLim = vs->BufferLim;
- #else
- const Byte *Buffer = inStream;
- const Byte *BufferLim = inStream + inSize;
- #endif
- int state = vs->State;
- UInt32 rep0 = vs->Reps[0], rep1 = vs->Reps[1], rep2 = vs->Reps[2], rep3 = vs->Reps[3];
- int len = vs->RemainLen;
- UInt32 globalPos = vs->GlobalPos;
- UInt32 distanceLimit = vs->DistanceLimit;
-
- Byte *dictionary = vs->Dictionary;
- UInt32 dictionarySize = vs->Properties.DictionarySize;
- UInt32 dictionaryPos = vs->DictionaryPos;
-
- Byte tempDictionary[4];
-
- #ifndef _LZMA_IN_CB
- *inSizeProcessed = 0;
- #endif
- *outSizeProcessed = 0;
- if (len == kLzmaStreamWasFinishedId)
- return LZMA_RESULT_OK;
-
- if (dictionarySize == 0)
- {
- dictionary = tempDictionary;
- dictionarySize = 1;
- tempDictionary[0] = vs->TempDictionary[0];
- }
-
- if (len == kLzmaNeedInitId)
- {
- {
- UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (lc + vs->Properties.lp));
- UInt32 i;
- for (i = 0; i < numProbs; i++)
- p[i] = kBitModelTotal >> 1;
- rep0 = rep1 = rep2 = rep3 = 1;
- state = 0;
- globalPos = 0;
- distanceLimit = 0;
- dictionaryPos = 0;
- dictionary[dictionarySize - 1] = 0;
- #ifdef _LZMA_IN_CB
- RC_INIT;
- #else
- RC_INIT(inStream, inSize);
- #endif
- }
- len = 0;
- }
- while(len != 0 && nowPos < outSize)
- {
- UInt32 pos = dictionaryPos - rep0;
- if (pos >= dictionarySize)
- pos += dictionarySize;
- outStream[nowPos++] = dictionary[dictionaryPos] = dictionary[pos];
- if (++dictionaryPos == dictionarySize)
- dictionaryPos = 0;
- len--;
- }
- if (dictionaryPos == 0)
- previousByte = dictionary[dictionarySize - 1];
- else
- previousByte = dictionary[dictionaryPos - 1];
-
- #else /* if !_LZMA_OUT_READ */
-
- int state = 0;
- UInt32 rep0 = 1, rep1 = 1, rep2 = 1, rep3 = 1;
- int len = 0;
- const Byte *Buffer;
- const Byte *BufferLim;
- UInt32 Range;
- UInt32 Code;
-
- #ifndef _LZMA_IN_CB
- *inSizeProcessed = 0;
- #endif
- *outSizeProcessed = 0;
-
- {
- UInt32 i;
- UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (lc + vs->Properties.lp));
- for (i = 0; i < numProbs; i++)
- p[i] = kBitModelTotal >> 1;
- }
-
- #ifdef _LZMA_IN_CB
- RC_INIT;
- #else
- RC_INIT(inStream, inSize);
- #endif
-
- #endif /* _LZMA_OUT_READ */
-
- while(nowPos < outSize)
- {
- CProb *prob;
- UInt32 bound;
- int posState = (int)(
- (nowPos
- #ifdef _LZMA_OUT_READ
- + globalPos
- #endif
- )
- & posStateMask);
-
- prob = p + IsMatch + (state << kNumPosBitsMax) + posState;
- IfBit0(prob)
- {
- int symbol = 1;
- UpdateBit0(prob)
- prob = p + Literal + (LZMA_LIT_SIZE *
- (((
- (nowPos
- #ifdef _LZMA_OUT_READ
- + globalPos
- #endif
- )
- & literalPosMask) << lc) + (previousByte >> (8 - lc))));
-
- if (state >= kNumLitStates)
- {
- int matchByte;
- #ifdef _LZMA_OUT_READ
- UInt32 pos = dictionaryPos - rep0;
- if (pos >= dictionarySize)
- pos += dictionarySize;
- matchByte = dictionary[pos];
- #else
- matchByte = outStream[nowPos - rep0];
- #endif
- do
- {
- int bit;
- CProb *probLit;
- matchByte <<= 1;
- bit = (matchByte & 0x100);
- probLit = prob + 0x100 + bit + symbol;
- RC_GET_BIT2(probLit, symbol, if (bit != 0) break, if (bit == 0) break)
- }
- while (symbol < 0x100);
- }
- while (symbol < 0x100)
- {
- CProb *probLit = prob + symbol;
- RC_GET_BIT(probLit, symbol)
- }
- previousByte = (Byte)symbol;
-
- outStream[nowPos++] = previousByte;
- #ifdef _LZMA_OUT_READ
- if (distanceLimit < dictionarySize)
- distanceLimit++;
-
- dictionary[dictionaryPos] = previousByte;
- if (++dictionaryPos == dictionarySize)
- dictionaryPos = 0;
- #endif
- if (state < 4) state = 0;
- else if (state < 10) state -= 3;
- else state -= 6;
- }
- else
- {
- UpdateBit1(prob);
- prob = p + IsRep + state;
- IfBit0(prob)
- {
- UpdateBit0(prob);
- rep3 = rep2;
- rep2 = rep1;
- rep1 = rep0;
- state = state < kNumLitStates ? 0 : 3;
- prob = p + LenCoder;
- }
- else
- {
- UpdateBit1(prob);
- prob = p + IsRepG0 + state;
- IfBit0(prob)
- {
- UpdateBit0(prob);
- prob = p + IsRep0Long + (state << kNumPosBitsMax) + posState;
- IfBit0(prob)
- {
- #ifdef _LZMA_OUT_READ
- UInt32 pos;
- #endif
- UpdateBit0(prob);
-
- #ifdef _LZMA_OUT_READ
- if (distanceLimit == 0)
- #else
- if (nowPos == 0)
- #endif
- return LZMA_RESULT_DATA_ERROR;
-
- state = state < kNumLitStates ? 9 : 11;
- #ifdef _LZMA_OUT_READ
- pos = dictionaryPos - rep0;
- if (pos >= dictionarySize)
- pos += dictionarySize;
- previousByte = dictionary[pos];
- dictionary[dictionaryPos] = previousByte;
- if (++dictionaryPos == dictionarySize)
- dictionaryPos = 0;
- #else
- previousByte = outStream[nowPos - rep0];
- #endif
- outStream[nowPos++] = previousByte;
- #ifdef _LZMA_OUT_READ
- if (distanceLimit < dictionarySize)
- distanceLimit++;
- #endif
-
- continue;
- }
- else
- {
- UpdateBit1(prob);
- }
- }
- else
- {
- UInt32 distance;
- UpdateBit1(prob);
- prob = p + IsRepG1 + state;
- IfBit0(prob)
- {
- UpdateBit0(prob);
- distance = rep1;
- }
- else
- {
- UpdateBit1(prob);
- prob = p + IsRepG2 + state;
- IfBit0(prob)
- {
- UpdateBit0(prob);
- distance = rep2;
- }
- else
- {
- UpdateBit1(prob);
- distance = rep3;
- rep3 = rep2;
- }
- rep2 = rep1;
- }
- rep1 = rep0;
- rep0 = distance;
- }
- state = state < kNumLitStates ? 8 : 11;
- prob = p + RepLenCoder;
- }
- {
- int numBits, offset;
- CProb *probLen = prob + LenChoice;
- IfBit0(probLen)
- {
- UpdateBit0(probLen);
- probLen = prob + LenLow + (posState << kLenNumLowBits);
- offset = 0;
- numBits = kLenNumLowBits;
- }
- else
- {
- UpdateBit1(probLen);
- probLen = prob + LenChoice2;
- IfBit0(probLen)
- {
- UpdateBit0(probLen);
- probLen = prob + LenMid + (posState << kLenNumMidBits);
- offset = kLenNumLowSymbols;
- numBits = kLenNumMidBits;
- }
- else
- {
- UpdateBit1(probLen);
- probLen = prob + LenHigh;
- offset = kLenNumLowSymbols + kLenNumMidSymbols;
- numBits = kLenNumHighBits;
- }
- }
- RangeDecoderBitTreeDecode(probLen, numBits, len);
- len += offset;
- }
-
- if (state < 4)
- {
- int posSlot;
- state += kNumLitStates;
- prob = p + PosSlot +
- ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) <<
- kNumPosSlotBits);
- RangeDecoderBitTreeDecode(prob, kNumPosSlotBits, posSlot);
- if (posSlot >= kStartPosModelIndex)
- {
- int numDirectBits = ((posSlot >> 1) - 1);
- rep0 = (2 | ((UInt32)posSlot & 1));
- if (posSlot < kEndPosModelIndex)
- {
- rep0 <<= numDirectBits;
- prob = p + SpecPos + rep0 - posSlot - 1;
- }
- else
- {
- numDirectBits -= kNumAlignBits;
- do
- {
- RC_NORMALIZE
- Range >>= 1;
- rep0 <<= 1;
- if (Code >= Range)
- {
- Code -= Range;
- rep0 |= 1;
- }
- }
- while (--numDirectBits != 0);
- prob = p + Align;
- rep0 <<= kNumAlignBits;
- numDirectBits = kNumAlignBits;
- }
- {
- int i = 1;
- int mi = 1;
- do
- {
- CProb *prob3 = prob + mi;
- RC_GET_BIT2(prob3, mi, ; , rep0 |= i);
- i <<= 1;
- }
- while(--numDirectBits != 0);
- }
- }
- else
- rep0 = posSlot;
- if (++rep0 == (UInt32)(0))
- {
- /* it's for stream version */
- len = kLzmaStreamWasFinishedId;
- break;
- }
- }
-
- len += kMatchMinLen;
- #ifdef _LZMA_OUT_READ
- if (rep0 > distanceLimit)
- #else
- if (rep0 > nowPos)
- #endif
- return LZMA_RESULT_DATA_ERROR;
-
- #ifdef _LZMA_OUT_READ
- if (dictionarySize - distanceLimit > (UInt32)len)
- distanceLimit += len;
- else
- distanceLimit = dictionarySize;
- #endif
-
- do
- {
- #ifdef _LZMA_OUT_READ
- UInt32 pos = dictionaryPos - rep0;
- if (pos >= dictionarySize)
- pos += dictionarySize;
- previousByte = dictionary[pos];
- dictionary[dictionaryPos] = previousByte;
- if (++dictionaryPos == dictionarySize)
- dictionaryPos = 0;
- #else
- previousByte = outStream[nowPos - rep0];
- #endif
- len--;
- outStream[nowPos++] = previousByte;
- }
- while(len != 0 && nowPos < outSize);
- }
- }
- RC_NORMALIZE;
-
- #ifdef _LZMA_OUT_READ
- vs->Range = Range;
- vs->Code = Code;
- vs->DictionaryPos = dictionaryPos;
- vs->GlobalPos = globalPos + (UInt32)nowPos;
- vs->DistanceLimit = distanceLimit;
- vs->Reps[0] = rep0;
- vs->Reps[1] = rep1;
- vs->Reps[2] = rep2;
- vs->Reps[3] = rep3;
- vs->State = state;
- vs->RemainLen = len;
- vs->TempDictionary[0] = tempDictionary[0];
- #endif
-
- #ifdef _LZMA_IN_CB
- vs->Buffer = Buffer;
- vs->BufferLim = BufferLim;
- #else
- *inSizeProcessed = (SizeT)(Buffer - inStream);
- #endif
- *outSizeProcessed = nowPos;
- return LZMA_RESULT_OK;
-}
+++ /dev/null
-/*
- LzmaDecode.h
- LZMA Decoder interface
-
- LZMA SDK 4.40 Copyright (c) 1999-2006 Igor Pavlov (2006-05-01)
- http://www.7-zip.org/
-
- LZMA SDK is licensed under two licenses:
- 1) GNU Lesser General Public License (GNU LGPL)
- 2) Common Public License (CPL)
- It means that you can select one of these two licenses and
- follow rules of that license.
-
- SPECIAL EXCEPTION:
- Igor Pavlov, as the author of this code, expressly permits you to
- statically or dynamically link your code (or bind by name) to the
- interfaces of this file without subjecting your linked code to the
- terms of the CPL or GNU LGPL. Any modifications or additions
- to this file, however, are subject to the LGPL or CPL terms.
-*/
-
-#ifndef __LZMADECODE_H
-#define __LZMADECODE_H
-
-#include "LzmaTypes.h"
-
-/* #define _LZMA_IN_CB */
-/* Use callback for input data */
-
-/* #define _LZMA_OUT_READ */
-/* Use read function for output data */
-
-/* #define _LZMA_PROB32 */
-/* It can increase speed on some 32-bit CPUs,
- but memory usage will be doubled in that case */
-
-/* #define _LZMA_LOC_OPT */
-/* Enable local speed optimizations inside code */
-
-#ifdef _LZMA_PROB32
-#define CProb UInt32
-#else
-#define CProb UInt16
-#endif
-
-#define LZMA_RESULT_OK 0
-#define LZMA_RESULT_DATA_ERROR 1
-
-#ifdef _LZMA_IN_CB
-typedef struct _ILzmaInCallback
-{
- int (*Read)(void *object, const unsigned char **buffer, SizeT *bufferSize);
-} ILzmaInCallback;
-#endif
-
-#define LZMA_BASE_SIZE 1846
-#define LZMA_LIT_SIZE 768
-
-#define LZMA_PROPERTIES_SIZE 5
-
-typedef struct _CLzmaProperties
-{
- int lc;
- int lp;
- int pb;
- #ifdef _LZMA_OUT_READ
- UInt32 DictionarySize;
- #endif
-}CLzmaProperties;
-
-int LzmaDecodeProperties(CLzmaProperties *propsRes, const unsigned char *propsData, int size);
-
-#define LzmaGetNumProbs(Properties) (LZMA_BASE_SIZE + (LZMA_LIT_SIZE << ((Properties)->lc + (Properties)->lp)))
-
-#define kLzmaNeedInitId (-2)
-
-typedef struct _CLzmaDecoderState
-{
- CLzmaProperties Properties;
- CProb *Probs;
-
- #ifdef _LZMA_IN_CB
- const unsigned char *Buffer;
- const unsigned char *BufferLim;
- #endif
-
- #ifdef _LZMA_OUT_READ
- unsigned char *Dictionary;
- UInt32 Range;
- UInt32 Code;
- UInt32 DictionaryPos;
- UInt32 GlobalPos;
- UInt32 DistanceLimit;
- UInt32 Reps[4];
- int State;
- int RemainLen;
- unsigned char TempDictionary[4];
- #endif
-} CLzmaDecoderState;
-
-#ifdef _LZMA_OUT_READ
-#define LzmaDecoderInit(vs) { (vs)->RemainLen = kLzmaNeedInitId; }
-#endif
-
-int LzmaDecode(CLzmaDecoderState *vs,
- #ifdef _LZMA_IN_CB
- ILzmaInCallback *inCallback,
- #else
- const unsigned char *inStream, SizeT inSize, SizeT *inSizeProcessed,
- #endif
- unsigned char *outStream, SizeT outSize, SizeT *outSizeProcessed);
-
-#endif
+++ /dev/null
-/*
-LzmaTypes.h
-
-Types for LZMA Decoder
-
-This file written and distributed to public domain by Igor Pavlov.
-This file is part of LZMA SDK 4.40 (2006-05-01)
-*/
-
-#ifndef __LZMATYPES_H
-#define __LZMATYPES_H
-
-#ifndef _7ZIP_BYTE_DEFINED
-#define _7ZIP_BYTE_DEFINED
-typedef unsigned char Byte;
-#endif
-
-#ifndef _7ZIP_UINT16_DEFINED
-#define _7ZIP_UINT16_DEFINED
-typedef unsigned short UInt16;
-#endif
-
-#ifndef _7ZIP_UINT32_DEFINED
-#define _7ZIP_UINT32_DEFINED
-#ifdef _LZMA_UINT32_IS_ULONG
-typedef unsigned long UInt32;
-#else
-typedef unsigned int UInt32;
-#endif
-#endif
-
-/* #define _LZMA_SYSTEM_SIZE_T */
-/* Use system's size_t. You can use it to enable 64-bit sizes supporting */
-
-#ifndef _7ZIP_SIZET_DEFINED
-#define _7ZIP_SIZET_DEFINED
-#ifdef _LZMA_SYSTEM_SIZE_T
-#include <stddef.h>
-typedef size_t SizeT;
-#else
-typedef UInt32 SizeT;
-#endif
-#endif
-
-#endif
+++ /dev/null
-@echo off
-rem this is a simple batch file to build PhysicsFS on OS/2. You need to have
-rem the Innotek libc and GCC (or "kLIBC") installed for this to work:
-rem
-rem http://svn.netlabs.org/libc
-rem
-rem This script (and, indeed, our OS/2 support) could use some tweaking.
-rem Patches go to icculus@icculus.org ...
-
-set PHYSFSLANG=PHYSFS_LANG_ENGLISH
-set DEBUGFLAGS=-D_NDEBUG -O2 -s
-rem set CFLAGS=%DEBUGFLAGS% -Wall -Werror -Zomf -Zmt -Zmtd -I. -Izlib123 -c -D__ST_MT_ERRNO__ -DOS2 -DZ_PREFIX -DPHYSFS_SUPPORTS_ZIP -DPHYSFS_SUPPORTS_7Z -DPHYSFS_SUPPORTS_GRP -DPHYSFS_SUPPORTS_WAD -DPHYSFS_SUPPORTS_QPAK -DPHYSFS_SUPPORTS_HOG -DPHYSFS_SUPPORTS_MVL -DPHYSFS_LANG=%PHYSFSLANG% -DHAVE_ASSERT_H
-set CFLAGS=%DEBUGFLAGS% -Wall -Werror -Zomf -I. -Iz -c -D__ST_MT_ERRNO__ -DOS2 -DZ_PREFIX -DPHYSFS_SUPPORTS_ZIP -DPHYSFS_SUPPORTS_7Z -DPHYSFS_SUPPORTS_GRP -DPHYSFS_SUPPORTS_WAD -DPHYSFS_SUPPORTS_QPAK -DPHYSFS_SUPPORTS_HOG -DPHYSFS_SUPPORTS_MVL -DHAVE_ASSERT_H
-
-rem goto :dolinking
-
-@echo cleaning up any previous build...
-@mkdir bin 2>NUL
-@erase /N bin\*.* 2>NUL
-
-@echo Building export definitions...
-@echo ;don't edit this directly! It is rewritten by makeos2.cmd! > bin\test_physfs.def
-@echo NAME TESTPHYSFS WINDOWCOMPAT >> bin\test_physfs.def
-@echo DESCRIPTION 'PhysicsFS: http://icculus.org/physfs/' >> bin\test_physfs.def
-@echo STACKSIZE 0x10000 >> bin\test_physfs.def
-@echo BASE=0x10000 >> bin\test_physfs.def
-@echo PROTMODE >> bin\test_physfs.def
-
-@echo ;don't edit this directly! It is rewritten by makeos2.cmd! > bin\physfs.def
-@echo LIBRARY 'physfs' INITINSTANCE TERMINSTANCE >> bin\physfs.def
-@echo STACKSIZE 0x10000 >> bin\physfs.def
-@echo CODE LOADONCALL >> bin\physfs.def
-@echo DATA LOADONCALL NONSHARED MULTIPLE >> bin\physfs.def
-@echo DESCRIPTION 'PhysicsFS: http://icculus.org/physfs/' >> bin\physfs.def
-@echo EXPORTS >> bin\physfs.def
-@echo "_PHYSFS_getLinkedVersion" >> bin\physfs.def
-@echo "_PHYSFS_init" >> bin\physfs.def
-@echo "_PHYSFS_deinit" >> bin\physfs.def
-@echo "_PHYSFS_isInit" >> bin\physfs.def
-@echo "_PHYSFS_supportedArchiveTypes" >> bin\physfs.def
-@echo "_PHYSFS_freeList" >> bin\physfs.def
-@echo "_PHYSFS_getLastError" >> bin\physfs.def
-@echo "_PHYSFS_getDirSeparator" >> bin\physfs.def
-@echo "_PHYSFS_permitSymbolicLinks" >> bin\physfs.def
-@echo "_PHYSFS_symbolicLinksPermitted" >> bin\physfs.def
-@echo "_PHYSFS_getCdRomDirs" >> bin\physfs.def
-@echo "_PHYSFS_getBaseDir" >> bin\physfs.def
-@echo "_PHYSFS_getUserDir" >> bin\physfs.def
-@echo "_PHYSFS_getWriteDir" >> bin\physfs.def
-@echo "_PHYSFS_setWriteDir" >> bin\physfs.def
-@echo "_PHYSFS_addToSearchPath" >> bin\physfs.def
-@echo "_PHYSFS_removeFromSearchPath" >> bin\physfs.def
-@echo "_PHYSFS_getSearchPath" >> bin\physfs.def
-@echo "_PHYSFS_setSaneConfig" >> bin\physfs.def
-@echo "_PHYSFS_mkdir" >> bin\physfs.def
-@echo "_PHYSFS_delete" >> bin\physfs.def
-@echo "_PHYSFS_getRealDir" >> bin\physfs.def
-@echo "_PHYSFS_enumerateFiles" >> bin\physfs.def
-@echo "_PHYSFS_exists" >> bin\physfs.def
-@echo "_PHYSFS_isDirectory" >> bin\physfs.def
-@echo "_PHYSFS_isSymbolicLink" >> bin\physfs.def
-@echo "_PHYSFS_openWrite" >> bin\physfs.def
-@echo "_PHYSFS_openAppend" >> bin\physfs.def
-@echo "_PHYSFS_openRead" >> bin\physfs.def
-@echo "_PHYSFS_close" >> bin\physfs.def
-@echo "_PHYSFS_read" >> bin\physfs.def
-@echo "_PHYSFS_write" >> bin\physfs.def
-@echo "_PHYSFS_eof" >> bin\physfs.def
-@echo "_PHYSFS_tell" >> bin\physfs.def
-@echo "_PHYSFS_seek" >> bin\physfs.def
-@echo "_PHYSFS_fileLength" >> bin\physfs.def
-@echo "_PHYSFS_swapSLE16" >> bin\physfs.def
-@echo "_PHYSFS_swapULE16" >> bin\physfs.def
-@echo "_PHYSFS_swapSLE32" >> bin\physfs.def
-@echo "_PHYSFS_swapULE32" >> bin\physfs.def
-@echo "_PHYSFS_swapSLE64" >> bin\physfs.def
-@echo "_PHYSFS_swapULE64" >> bin\physfs.def
-@echo "_PHYSFS_swapSBE16" >> bin\physfs.def
-@echo "_PHYSFS_swapUBE16" >> bin\physfs.def
-@echo "_PHYSFS_swapSBE32" >> bin\physfs.def
-@echo "_PHYSFS_swapUBE32" >> bin\physfs.def
-@echo "_PHYSFS_swapSBE64" >> bin\physfs.def
-@echo "_PHYSFS_swapUBE64" >> bin\physfs.def
-@echo "_PHYSFS_getLastModTime" >> bin\physfs.def
-@echo "_PHYSFS_readSLE16" >> bin\physfs.def
-@echo "_PHYSFS_readULE16" >> bin\physfs.def
-@echo "_PHYSFS_readSLE32" >> bin\physfs.def
-@echo "_PHYSFS_readULE32" >> bin\physfs.def
-@echo "_PHYSFS_readSLE64" >> bin\physfs.def
-@echo "_PHYSFS_readULE64" >> bin\physfs.def
-@echo "_PHYSFS_readSBE16" >> bin\physfs.def
-@echo "_PHYSFS_readUBE16" >> bin\physfs.def
-@echo "_PHYSFS_readSBE32" >> bin\physfs.def
-@echo "_PHYSFS_readUBE32" >> bin\physfs.def
-@echo "_PHYSFS_readSBE64" >> bin\physfs.def
-@echo "_PHYSFS_readUBE64" >> bin\physfs.def
-@echo "_PHYSFS_writeSLE16" >> bin\physfs.def
-@echo "_PHYSFS_writeULE16" >> bin\physfs.def
-@echo "_PHYSFS_writeSLE32" >> bin\physfs.def
-@echo "_PHYSFS_writeULE32" >> bin\physfs.def
-@echo "_PHYSFS_writeSLE64" >> bin\physfs.def
-@echo "_PHYSFS_writeULE64" >> bin\physfs.def
-@echo "_PHYSFS_writeSBE16" >> bin\physfs.def
-@echo "_PHYSFS_writeUBE16" >> bin\physfs.def
-@echo "_PHYSFS_writeSBE32" >> bin\physfs.def
-@echo "_PHYSFS_writeUBE32" >> bin\physfs.def
-@echo "_PHYSFS_writeSBE64" >> bin\physfs.def
-@echo "_PHYSFS_writeUBE64" >> bin\physfs.def
-@echo "_PHYSFS_setBuffer" >> bin\physfs.def
-@echo "_PHYSFS_flush" >> bin\physfs.def
-@echo "_PHYSFS_mount" >> bin\physfs.def
-@echo "_PHYSFS_getMountPoint" >> bin\physfs.def
-@echo "_PHYSFS_setAllocator" >> bin\physfs.def
-@echo "_PHYSFS_getCdRomDirsCallback" >> bin\physfs.def
-@echo "_PHYSFS_getSearchPathCallback" >> bin\physfs.def
-@echo "_PHYSFS_enumerateFilesCallback" >> bin\physfs.def
-@echo "_PHYSFS_utf8ToUcs2" >> bin\physfs.def
-@echo "_PHYSFS_utf8FromUcs2" >> bin\physfs.def
-@echo "_PHYSFS_utf8ToUcs4" >> bin\physfs.def
-@echo "_PHYSFS_utf8FromUcs4" >> bin\physfs.def
-@echo "_PHYSFS_utf8FromLatin1" >> bin\physfs.def
-
-@echo Building export library...
-emximp -o bin/physfs.lib bin/physfs.def
-emximp -o bin/physfs.a bin/physfs.def
-
-@echo Compiling PhysicsFS library...
-@echo on
-gcc %CFLAGS% -o bin/physfs.obj physfs.c
-gcc %CFLAGS% -o bin/physfs_byteorder.obj physfs_byteorder.c
-gcc %CFLAGS% -o bin/physfs_unicode.obj physfs_unicode.c
-gcc %CFLAGS% -o bin/os2.obj platform/os2.c
-gcc %CFLAGS% -o bin/dir.obj archivers/dir.c
-gcc %CFLAGS% -o bin/grp.obj archivers/grp.c
-gcc %CFLAGS% -o bin/wad.obj archivers/wad.c
-gcc %CFLAGS% -o bin/lzma.obj archivers/lzma.c
-gcc %CFLAGS% -o bin/zip.obj archivers/zip.c
-gcc %CFLAGS% -o bin/qpak.obj archivers/qpak.c
-gcc %CFLAGS% -o bin/hog.obj archivers/hog.c
-gcc %CFLAGS% -o bin/mvl.obj archivers/mvl.c
-gcc %CFLAGS% -o bin/adler32.obj zlib123/adler32.c
-gcc %CFLAGS% -o bin/compress.obj zlib123/compress.c
-gcc %CFLAGS% -o bin/crc32.obj zlib123/crc32.c
-gcc %CFLAGS% -o bin/deflate.obj zlib123/deflate.c
-gcc %CFLAGS% -o bin/gzio.obj zlib123/gzio.c
-gcc %CFLAGS% -o bin/infback.obj zlib123/infback.c
-gcc %CFLAGS% -o bin/inffast.obj zlib123/inffast.c
-gcc %CFLAGS% -o bin/inflate.obj zlib123/inflate.c
-gcc %CFLAGS% -o bin/inftrees.obj zlib123/inftrees.c
-gcc %CFLAGS% -o bin/trees.obj zlib123/trees.c
-gcc %CFLAGS% -o bin/uncompr.obj zlib123/uncompr.c
-gcc %CFLAGS% -o bin/zutil.obj zlib123/zutil.c
-gcc %CFLAGS% -o bin/7zBuffer.obj lzma/7zBuffer.c
-gcc %CFLAGS% -o bin/7zCrc.obj lzma/7zCrc.c
-gcc %CFLAGS% -o bin/7zDecode.obj lzma/7zDecode.c
-gcc %CFLAGS% -o bin/7zExtract.obj lzma/7zExtract.c
-gcc %CFLAGS% -o bin/7zHeader.obj lzma/7zHeader.c
-gcc %CFLAGS% -o bin/7zIn.obj lzma/7zIn.c
-gcc %CFLAGS% -o bin/7zItem.obj lzma/7zItem.c
-gcc %CFLAGS% -o bin/7zMethodID.obj lzma/7zMethodID.c
-gcc %CFLAGS% -o bin/LzmaDecode.obj lzma/LzmaDecode.c
-gcc %CFLAGS% -o bin/LzmaStateDecode.obj lzma/LzmaStateDecode.c
-@echo off
-
-:dolinking
-@echo Linking PhysicsFS library...
-gcc %DEBUGFLAGS% -Zdll -Zcrtdll -Zomf -o bin/physfs.dll bin/*.obj bin/physfs.def
-
-rem goto :builddone
-
-@echo Compiling test program...
-gcc %CFLAGS% -o bin/test_physfs.obj test/test_physfs.c
-@echo Linking test program...
-gcc %DEBUGFLAGS% -Zomf -Zcrtdll -o bin/test_physfs.exe bin/test_physfs.obj bin/physfs.lib bin/test_physfs.def
-
-:builddone
-
-@echo "All done!"
-
-rem end of makeos2.cmd ...
-
+++ /dev/null
-Performing C SOURCE FILE Test PHYSFS_IS_GCC4 failed with the following output:
-
-Source file was:
-
- #if ((defined(__GNUC__)) && (__GNUC__ >= 4))
- int main(int argc, char **argv) { int is_gcc4 = 1; return 0; }
- #else
- #error This is not gcc4.
- #endif
-
-Determining if the include file sys/ucred.h exists failed with the following output:
-
-
-Determining if the include file mntent.h exists failed with the following output:
-
-
-Determining if the include file pthread.h exists failed with the following output:
-
-
-Determining if the include file assert.h exists failed with the following output:
-
-
-Determining if the include file zlib.h exists failed with the following output:
-
-
-Determining if the include file readline/readline.h exists failed with the following output:
-
-
-Determining if the include file readline/history.h exists failed with the following output:
-
-
+++ /dev/null
-
- #if ((defined(__GNUC__)) && (__GNUC__ >= 4))
- int main(int argc, char **argv) { int is_gcc4 = 1; return 0; }
- #else
- #error This is not gcc4.
- #endif
-
+++ /dev/null
-/**
- * PhysicsFS; a portable, flexible file i/o abstraction.
- *
- * Documentation is in physfs.h. It's verbose, honest. :)
- *
- * Please see the file LICENSE.txt in the source's root directory.
- *
- * This file written by Ryan C. Gordon.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include "physfs.h"
-
-#define __PHYSICSFS_INTERNAL__
-#include "physfs_internal.h"
-
-
-typedef struct __PHYSFS_DIRHANDLE__
-{
- void *opaque; /* Instance data unique to the archiver. */
- char *dirName; /* Path to archive in platform-dependent notation. */
- char *mountPoint; /* Mountpoint in virtual file tree. */
- const PHYSFS_Archiver *funcs; /* Ptr to archiver info for this handle. */
- struct __PHYSFS_DIRHANDLE__ *next; /* linked list stuff. */
-} DirHandle;
-
-
-typedef struct __PHYSFS_FILEHANDLE__
-{
- void *opaque; /* Instance data unique to the archiver for this file. */
- PHYSFS_uint8 forReading; /* Non-zero if reading, zero if write/append */
- const DirHandle *dirHandle; /* Archiver instance that created this */
- const PHYSFS_Archiver *funcs; /* Ptr to archiver info for this handle. */
- PHYSFS_uint8 *buffer; /* Buffer, if set (NULL otherwise). Don't touch! */
- PHYSFS_uint32 bufsize; /* Bufsize, if set (0 otherwise). Don't touch! */
- PHYSFS_uint32 buffill; /* Buffer fill size. Don't touch! */
- PHYSFS_uint32 bufpos; /* Buffer position. Don't touch! */
- struct __PHYSFS_FILEHANDLE__ *next; /* linked list stuff. */
-} FileHandle;
-
-
-typedef struct __PHYSFS_ERRMSGTYPE__
-{
- PHYSFS_uint64 tid;
- int errorAvailable;
- char errorString[80];
- struct __PHYSFS_ERRMSGTYPE__ *next;
-} ErrMsg;
-
-
-/* The various i/o drivers...some of these may not be compiled in. */
-extern const PHYSFS_ArchiveInfo __PHYSFS_ArchiveInfo_ZIP;
-extern const PHYSFS_Archiver __PHYSFS_Archiver_ZIP;
-extern const PHYSFS_ArchiveInfo __PHYSFS_ArchiveInfo_LZMA;
-extern const PHYSFS_Archiver __PHYSFS_Archiver_LZMA;
-extern const PHYSFS_ArchiveInfo __PHYSFS_ArchiveInfo_GRP;
-extern const PHYSFS_Archiver __PHYSFS_Archiver_GRP;
-extern const PHYSFS_ArchiveInfo __PHYSFS_ArchiveInfo_QPAK;
-extern const PHYSFS_Archiver __PHYSFS_Archiver_QPAK;
-extern const PHYSFS_ArchiveInfo __PHYSFS_ArchiveInfo_HOG;
-extern const PHYSFS_Archiver __PHYSFS_Archiver_HOG;
-extern const PHYSFS_ArchiveInfo __PHYSFS_ArchiveInfo_MVL;
-extern const PHYSFS_Archiver __PHYSFS_Archiver_MVL;
-extern const PHYSFS_ArchiveInfo __PHYSFS_ArchiveInfo_WAD;
-extern const PHYSFS_Archiver __PHYSFS_Archiver_WAD;
-extern const PHYSFS_Archiver __PHYSFS_Archiver_DIR;
-
-
-static const PHYSFS_ArchiveInfo *supported_types[] =
-{
-#if (defined PHYSFS_SUPPORTS_ZIP)
- &__PHYSFS_ArchiveInfo_ZIP,
-#endif
-#if (defined PHYSFS_SUPPORTS_7Z)
- &__PHYSFS_ArchiveInfo_LZMA,
-#endif
-#if (defined PHYSFS_SUPPORTS_GRP)
- &__PHYSFS_ArchiveInfo_GRP,
-#endif
-#if (defined PHYSFS_SUPPORTS_QPAK)
- &__PHYSFS_ArchiveInfo_QPAK,
-#endif
-#if (defined PHYSFS_SUPPORTS_HOG)
- &__PHYSFS_ArchiveInfo_HOG,
-#endif
-#if (defined PHYSFS_SUPPORTS_MVL)
- &__PHYSFS_ArchiveInfo_MVL,
-#endif
-#if (defined PHYSFS_SUPPORTS_WAD)
- &__PHYSFS_ArchiveInfo_WAD,
-#endif
- NULL
-};
-
-static const PHYSFS_Archiver *archivers[] =
-{
- &__PHYSFS_Archiver_DIR,
-#if (defined PHYSFS_SUPPORTS_ZIP)
- &__PHYSFS_Archiver_ZIP,
-#endif
-#if (defined PHYSFS_SUPPORTS_7Z)
- &__PHYSFS_Archiver_LZMA,
-#endif
-#if (defined PHYSFS_SUPPORTS_GRP)
- &__PHYSFS_Archiver_GRP,
-#endif
-#if (defined PHYSFS_SUPPORTS_QPAK)
- &__PHYSFS_Archiver_QPAK,
-#endif
-#if (defined PHYSFS_SUPPORTS_HOG)
- &__PHYSFS_Archiver_HOG,
-#endif
-#if (defined PHYSFS_SUPPORTS_MVL)
- &__PHYSFS_Archiver_MVL,
-#endif
-#if (defined PHYSFS_SUPPORTS_WAD)
- &__PHYSFS_Archiver_WAD,
-#endif
- NULL
-};
-
-
-
-/* General PhysicsFS state ... */
-static int initialized = 0;
-static ErrMsg *errorMessages = NULL;
-static DirHandle *searchPath = NULL;
-static DirHandle *writeDir = NULL;
-static FileHandle *openWriteList = NULL;
-static FileHandle *openReadList = NULL;
-static char *baseDir = NULL;
-static char *userDir = NULL;
-static int allowSymLinks = 0;
-
-/* mutexes ... */
-static void *errorLock = NULL; /* protects error message list. */
-static void *stateLock = NULL; /* protects other PhysFS static state. */
-
-/* allocator ... */
-static int externalAllocator = 0;
-PHYSFS_Allocator allocator;
-
-
-/* functions ... */
-
-typedef struct
-{
- char **list;
- PHYSFS_uint32 size;
- const char *errorstr;
-} EnumStringListCallbackData;
-
-static void enumStringListCallback(void *data, const char *str)
-{
- void *ptr;
- char *newstr;
- EnumStringListCallbackData *pecd = (EnumStringListCallbackData *) data;
-
- if (pecd->errorstr)
- return;
-
- ptr = allocator.Realloc(pecd->list, (pecd->size + 2) * sizeof (char *));
- newstr = (char *) allocator.Malloc(strlen(str) + 1);
- if (ptr != NULL)
- pecd->list = (char **) ptr;
-
- if ((ptr == NULL) || (newstr == NULL))
- {
- pecd->errorstr = ERR_OUT_OF_MEMORY;
- pecd->list[pecd->size] = NULL;
- PHYSFS_freeList(pecd->list);
- return;
- } /* if */
-
- strcpy(newstr, str);
- pecd->list[pecd->size] = newstr;
- pecd->size++;
-} /* enumStringListCallback */
-
-
-static char **doEnumStringList(void (*func)(PHYSFS_StringCallback, void *))
-{
- EnumStringListCallbackData ecd;
- memset(&ecd, '\0', sizeof (ecd));
- ecd.list = (char **) allocator.Malloc(sizeof (char *));
- BAIL_IF_MACRO(ecd.list == NULL, ERR_OUT_OF_MEMORY, NULL);
- func(enumStringListCallback, &ecd);
- BAIL_IF_MACRO(ecd.errorstr != NULL, ecd.errorstr, NULL);
- ecd.list[ecd.size] = NULL;
- return(ecd.list);
-} /* doEnumStringList */
-
-
-static void __PHYSFS_bubble_sort(void *a, PHYSFS_uint32 lo, PHYSFS_uint32 hi,
- int (*cmpfn)(void *, PHYSFS_uint32, PHYSFS_uint32),
- void (*swapfn)(void *, PHYSFS_uint32, PHYSFS_uint32))
-{
- PHYSFS_uint32 i;
- int sorted;
-
- do
- {
- sorted = 1;
- for (i = lo; i < hi; i++)
- {
- if (cmpfn(a, i, i + 1) > 0)
- {
- swapfn(a, i, i + 1);
- sorted = 0;
- } /* if */
- } /* for */
- } while (!sorted);
-} /* __PHYSFS_bubble_sort */
-
-
-static void __PHYSFS_quick_sort(void *a, PHYSFS_uint32 lo, PHYSFS_uint32 hi,
- int (*cmpfn)(void *, PHYSFS_uint32, PHYSFS_uint32),
- void (*swapfn)(void *, PHYSFS_uint32, PHYSFS_uint32))
-{
- PHYSFS_uint32 i;
- PHYSFS_uint32 j;
- PHYSFS_uint32 v;
-
- if ((hi - lo) <= PHYSFS_QUICKSORT_THRESHOLD)
- __PHYSFS_bubble_sort(a, lo, hi, cmpfn, swapfn);
- else
- {
- i = (hi + lo) / 2;
-
- if (cmpfn(a, lo, i) > 0) swapfn(a, lo, i);
- if (cmpfn(a, lo, hi) > 0) swapfn(a, lo, hi);
- if (cmpfn(a, i, hi) > 0) swapfn(a, i, hi);
-
- j = hi - 1;
- swapfn(a, i, j);
- i = lo;
- v = j;
- while (1)
- {
- while(cmpfn(a, ++i, v) < 0) { /* do nothing */ }
- while(cmpfn(a, --j, v) > 0) { /* do nothing */ }
- if (j < i)
- break;
- swapfn(a, i, j);
- } /* while */
- swapfn(a, i, hi-1);
- __PHYSFS_quick_sort(a, lo, j, cmpfn, swapfn);
- __PHYSFS_quick_sort(a, i+1, hi, cmpfn, swapfn);
- } /* else */
-} /* __PHYSFS_quick_sort */
-
-
-void __PHYSFS_sort(void *entries, PHYSFS_uint32 max,
- int (*cmpfn)(void *, PHYSFS_uint32, PHYSFS_uint32),
- void (*swapfn)(void *, PHYSFS_uint32, PHYSFS_uint32))
-{
- /*
- * Quicksort w/ Bubblesort fallback algorithm inspired by code from here:
- * http://www.cs.ubc.ca/spider/harrison/Java/sorting-demo.html
- */
- __PHYSFS_quick_sort(entries, 0, max - 1, cmpfn, swapfn);
-} /* __PHYSFS_sort */
-
-
-static ErrMsg *findErrorForCurrentThread(void)
-{
- ErrMsg *i;
- PHYSFS_uint64 tid;
-
- if (errorLock != NULL)
- __PHYSFS_platformGrabMutex(errorLock);
-
- if (errorMessages != NULL)
- {
- tid = __PHYSFS_platformGetThreadID();
-
- for (i = errorMessages; i != NULL; i = i->next)
- {
- if (i->tid == tid)
- {
- if (errorLock != NULL)
- __PHYSFS_platformReleaseMutex(errorLock);
- return(i);
- } /* if */
- } /* for */
- } /* if */
-
- if (errorLock != NULL)
- __PHYSFS_platformReleaseMutex(errorLock);
-
- return(NULL); /* no error available. */
-} /* findErrorForCurrentThread */
-
-
-void __PHYSFS_setError(const char *str)
-{
- ErrMsg *err;
-
- if (str == NULL)
- return;
-
- err = findErrorForCurrentThread();
-
- if (err == NULL)
- {
- err = (ErrMsg *) allocator.Malloc(sizeof (ErrMsg));
- if (err == NULL)
- return; /* uhh...? */
-
- memset((void *) err, '\0', sizeof (ErrMsg));
- err->tid = __PHYSFS_platformGetThreadID();
-
- if (errorLock != NULL)
- __PHYSFS_platformGrabMutex(errorLock);
-
- err->next = errorMessages;
- errorMessages = err;
-
- if (errorLock != NULL)
- __PHYSFS_platformReleaseMutex(errorLock);
- } /* if */
-
- err->errorAvailable = 1;
- strncpy(err->errorString, str, sizeof (err->errorString));
- err->errorString[sizeof (err->errorString) - 1] = '\0';
-} /* __PHYSFS_setError */
-
-
-const char *PHYSFS_getLastError(void)
-{
- ErrMsg *err = findErrorForCurrentThread();
-
- if ((err == NULL) || (!err->errorAvailable))
- return(NULL);
-
- err->errorAvailable = 0;
- return(err->errorString);
-} /* PHYSFS_getLastError */
-
-
-/* MAKE SURE that errorLock is held before calling this! */
-static void freeErrorMessages(void)
-{
- ErrMsg *i;
- ErrMsg *next;
-
- for (i = errorMessages; i != NULL; i = next)
- {
- next = i->next;
- allocator.Free(i);
- } /* for */
-
- errorMessages = NULL;
-} /* freeErrorMessages */
-
-
-void PHYSFS_getLinkedVersion(PHYSFS_Version *ver)
-{
- if (ver != NULL)
- {
- ver->major = PHYSFS_VER_MAJOR;
- ver->minor = PHYSFS_VER_MINOR;
- ver->patch = PHYSFS_VER_PATCH;
- } /* if */
-} /* PHYSFS_getLinkedVersion */
-
-
-static const char *find_filename_extension(const char *fname)
-{
- const char *retval = strchr(fname, '.');
- const char *p = retval;
-
- while (p != NULL)
- {
- p = strchr(p + 1, '.');
- if (p != NULL)
- retval = p;
- } /* while */
-
- if (retval != NULL)
- retval++; /* skip '.' */
-
- return(retval);
-} /* find_filename_extension */
-
-
-static DirHandle *tryOpenDir(const PHYSFS_Archiver *funcs,
- const char *d, int forWriting)
-{
- DirHandle *retval = NULL;
- if (funcs->isArchive(d, forWriting))
- {
- void *opaque = funcs->openArchive(d, forWriting);
- if (opaque != NULL)
- {
- retval = (DirHandle *) allocator.Malloc(sizeof (DirHandle));
- if (retval == NULL)
- funcs->dirClose(opaque);
- else
- {
- memset(retval, '\0', sizeof (DirHandle));
- retval->mountPoint = NULL;
- retval->funcs = funcs;
- retval->opaque = opaque;
- } /* else */
- } /* if */
- } /* if */
-
- return(retval);
-} /* tryOpenDir */
-
-
-static DirHandle *openDirectory(const char *d, int forWriting)
-{
- DirHandle *retval = NULL;
- const PHYSFS_Archiver **i;
- const char *ext;
-
- BAIL_IF_MACRO(!__PHYSFS_platformExists(d), ERR_NO_SUCH_FILE, NULL);
-
- ext = find_filename_extension(d);
- if (ext != NULL)
- {
- /* Look for archivers with matching file extensions first... */
- for (i = archivers; (*i != NULL) && (retval == NULL); i++)
- {
- if (__PHYSFS_stricmpASCII(ext, (*i)->info->extension) == 0)
- retval = tryOpenDir(*i, d, forWriting);
- } /* for */
-
- /* failing an exact file extension match, try all the others... */
- for (i = archivers; (*i != NULL) && (retval == NULL); i++)
- {
- if (__PHYSFS_stricmpASCII(ext, (*i)->info->extension) != 0)
- retval = tryOpenDir(*i, d, forWriting);
- } /* for */
- } /* if */
-
- else /* no extension? Try them all. */
- {
- for (i = archivers; (*i != NULL) && (retval == NULL); i++)
- retval = tryOpenDir(*i, d, forWriting);
- } /* else */
-
- BAIL_IF_MACRO(retval == NULL, ERR_UNSUPPORTED_ARCHIVE, NULL);
- return(retval);
-} /* openDirectory */
-
-
-/*
- * Make a platform-independent path string sane. Doesn't actually check the
- * file hierarchy, it just cleans up the string.
- * (dst) must be a buffer at least as big as (src), as this is where the
- * cleaned up string is deposited.
- * If there are illegal bits in the path (".." entries, etc) then we
- * return zero and (dst) is undefined. Non-zero if the path was sanitized.
- */
-static int sanitizePlatformIndependentPath(const char *src, char *dst)
-{
- char *prev;
- char ch;
-
- while (*src == '/') /* skip initial '/' chars... */
- src++;
-
- prev = dst;
- do
- {
- ch = *(src++);
-
- if ((ch == ':') || (ch == '\\')) /* illegal chars in a physfs path. */
- BAIL_MACRO(ERR_INSECURE_FNAME, 0);
-
- if (ch == '/') /* path separator. */
- {
- *dst = '\0'; /* "." and ".." are illegal pathnames. */
- if ((strcmp(prev, ".") == 0) || (strcmp(prev, "..") == 0))
- BAIL_MACRO(ERR_INSECURE_FNAME, 0);
-
- while (*src == '/') /* chop out doubles... */
- src++;
-
- if (*src == '\0') /* ends with a pathsep? */
- break; /* we're done, don't add final pathsep to dst. */
-
- prev = dst + 1;
- } /* if */
-
- *(dst++) = ch;
- } while (ch != '\0');
-
- return(1);
-} /* sanitizePlatformIndependentPath */
-
-
-/*
- * Figure out if (fname) is part of (h)'s mountpoint. (fname) must be an
- * output from sanitizePlatformIndependentPath(), so that it is in a known
- * state.
- *
- * This only finds legitimate segments of a mountpoint. If the mountpoint is
- * "/a/b/c" and (fname) is "/a/b/c", "/", or "/a/b/c/d", then the results are
- * all zero. "/a/b" will succeed, though.
- */
-static int partOfMountPoint(DirHandle *h, char *fname)
-{
- /* !!! FIXME: This code feels gross. */
- int rc;
- size_t len, mntpntlen;
-
- if (h->mountPoint == NULL)
- return(0);
- else if (*fname == '\0')
- return(1);
-
- len = strlen(fname);
- mntpntlen = strlen(h->mountPoint);
- if (len > mntpntlen) /* can't be a subset of mountpoint. */
- return(0);
-
- /* if true, must be not a match or a complete match, but not a subset. */
- if ((len + 1) == mntpntlen)
- return(0);
-
- rc = strncmp(fname, h->mountPoint, len); /* !!! FIXME: case insensitive? */
- if (rc != 0)
- return(0); /* not a match. */
-
- /* make sure /a/b matches /a/b/ and not /a/bc ... */
- return(h->mountPoint[len] == '/');
-} /* partOfMountPoint */
-
-
-static DirHandle *createDirHandle(const char *newDir,
- const char *mountPoint,
- int forWriting)
-{
- DirHandle *dirHandle = NULL;
- char *tmpmntpnt = NULL;
-
- GOTO_IF_MACRO(!newDir, ERR_INVALID_ARGUMENT, badDirHandle);
- if (mountPoint != NULL)
- {
- const size_t len = strlen(mountPoint) + 1;
- tmpmntpnt = (char *) __PHYSFS_smallAlloc(len);
- GOTO_IF_MACRO(!tmpmntpnt, ERR_OUT_OF_MEMORY, badDirHandle);
- if (!sanitizePlatformIndependentPath(mountPoint, tmpmntpnt))
- goto badDirHandle;
- mountPoint = tmpmntpnt; /* sanitized version. */
- } /* if */
-
- dirHandle = openDirectory(newDir, forWriting);
- GOTO_IF_MACRO(!dirHandle, NULL, badDirHandle);
-
- dirHandle->dirName = (char *) allocator.Malloc(strlen(newDir) + 1);
- GOTO_IF_MACRO(!dirHandle->dirName, ERR_OUT_OF_MEMORY, badDirHandle);
- strcpy(dirHandle->dirName, newDir);
-
- if ((mountPoint != NULL) && (*mountPoint != '\0'))
- {
- dirHandle->mountPoint = (char *)allocator.Malloc(strlen(mountPoint)+2);
- GOTO_IF_MACRO(!dirHandle->mountPoint, ERR_OUT_OF_MEMORY, badDirHandle);
- strcpy(dirHandle->mountPoint, mountPoint);
- strcat(dirHandle->mountPoint, "/");
- } /* if */
-
- __PHYSFS_smallFree(tmpmntpnt);
- return(dirHandle);
-
-badDirHandle:
- if (dirHandle != NULL)
- {
- dirHandle->funcs->dirClose(dirHandle->opaque);
- allocator.Free(dirHandle->dirName);
- allocator.Free(dirHandle->mountPoint);
- allocator.Free(dirHandle);
- } /* if */
-
- __PHYSFS_smallFree(tmpmntpnt);
- return(NULL);
-} /* createDirHandle */
-
-
-/* MAKE SURE you've got the stateLock held before calling this! */
-static int freeDirHandle(DirHandle *dh, FileHandle *openList)
-{
- FileHandle *i;
-
- if (dh == NULL)
- return(1);
-
- for (i = openList; i != NULL; i = i->next)
- BAIL_IF_MACRO(i->dirHandle == dh, ERR_FILES_STILL_OPEN, 0);
-
- dh->funcs->dirClose(dh->opaque);
- allocator.Free(dh->dirName);
- allocator.Free(dh->mountPoint);
- allocator.Free(dh);
- return(1);
-} /* freeDirHandle */
-
-
-static char *calculateUserDir(void)
-{
- char *retval = NULL;
- const char *str = NULL;
-
- str = __PHYSFS_platformGetUserDir();
- if (str != NULL)
- retval = (char *) str;
- else
- {
- const char *dirsep = PHYSFS_getDirSeparator();
- const char *uname = __PHYSFS_platformGetUserName();
-
- str = (uname != NULL) ? uname : "default";
- retval = (char *) allocator.Malloc(strlen(baseDir) + strlen(str) +
- strlen(dirsep) + 6);
-
- if (retval == NULL)
- __PHYSFS_setError(ERR_OUT_OF_MEMORY);
- else
- sprintf(retval, "%susers%s%s", baseDir, dirsep, str);
-
- allocator.Free((void *) uname);
- } /* else */
-
- return(retval);
-} /* calculateUserDir */
-
-
-static int appendDirSep(char **dir)
-{
- const char *dirsep = PHYSFS_getDirSeparator();
- char *ptr;
-
- if (strcmp((*dir + strlen(*dir)) - strlen(dirsep), dirsep) == 0)
- return(1);
-
- ptr = (char *) allocator.Realloc(*dir, strlen(*dir) + strlen(dirsep) + 1);
- if (!ptr)
- {
- allocator.Free(*dir);
- return(0);
- } /* if */
-
- strcat(ptr, dirsep);
- *dir = ptr;
- return(1);
-} /* appendDirSep */
-
-
-static char *calculateBaseDir(const char *argv0)
-{
- char *retval = NULL;
- const char *dirsep = NULL;
- char *ptr = NULL;
-
- /* Give the platform layer first shot at this. */
- retval = __PHYSFS_platformCalcBaseDir(argv0);
- if (retval != NULL)
- return(retval);
-
- /* We need argv0 to go on. */
- BAIL_IF_MACRO(argv0 == NULL, ERR_ARGV0_IS_NULL, NULL);
-
- dirsep = PHYSFS_getDirSeparator();
- if (strlen(dirsep) == 1) /* fast path. */
- ptr = strrchr(argv0, *dirsep);
- else
- {
- ptr = strstr(argv0, dirsep);
- if (ptr != NULL)
- {
- char *p = ptr;
- while (p != NULL)
- {
- ptr = p;
- p = strstr(p + 1, dirsep);
- } /* while */
- } /* if */
- } /* else */
-
- if (ptr != NULL)
- {
- size_t size = (size_t) (ptr - argv0);
- retval = (char *) allocator.Malloc(size + 1);
- BAIL_IF_MACRO(retval == NULL, ERR_OUT_OF_MEMORY, NULL);
- memcpy(retval, argv0, size);
- retval[size] = '\0';
- return(retval);
- } /* if */
-
- /* argv0 wasn't helpful. */
- BAIL_MACRO(ERR_INVALID_ARGUMENT, NULL);
- return(NULL);
-} /* calculateBaseDir */
-
-
-static int initializeMutexes(void)
-{
- errorLock = __PHYSFS_platformCreateMutex();
- if (errorLock == NULL)
- goto initializeMutexes_failed;
-
- stateLock = __PHYSFS_platformCreateMutex();
- if (stateLock == NULL)
- goto initializeMutexes_failed;
-
- return(1); /* success. */
-
-initializeMutexes_failed:
- if (errorLock != NULL)
- __PHYSFS_platformDestroyMutex(errorLock);
-
- if (stateLock != NULL)
- __PHYSFS_platformDestroyMutex(stateLock);
-
- errorLock = stateLock = NULL;
- return(0); /* failed. */
-} /* initializeMutexes */
-
-
-static void setDefaultAllocator(void);
-
-int PHYSFS_init(const char *argv0)
-{
- char *ptr;
-
- BAIL_IF_MACRO(initialized, ERR_IS_INITIALIZED, 0);
-
- if (!externalAllocator)
- setDefaultAllocator();
-
- if (allocator.Init != NULL)
- BAIL_IF_MACRO(!allocator.Init(), NULL, 0);
-
- BAIL_IF_MACRO(!__PHYSFS_platformInit(), NULL, 0);
-
- BAIL_IF_MACRO(!initializeMutexes(), NULL, 0);
-
- baseDir = calculateBaseDir(argv0);
- BAIL_IF_MACRO(baseDir == NULL, NULL, 0);
-
- /* !!! FIXME: only call this if we got this from argv0 (unreliable). */
- ptr = __PHYSFS_platformRealPath(baseDir);
- allocator.Free(baseDir);
- BAIL_IF_MACRO(ptr == NULL, NULL, 0);
- baseDir = ptr;
-
- BAIL_IF_MACRO(!appendDirSep(&baseDir), NULL, 0);
-
- userDir = calculateUserDir();
- if (userDir != NULL)
- {
- ptr = __PHYSFS_platformRealPath(userDir);
- allocator.Free(userDir);
- userDir = ptr;
- } /* if */
-
- if ((userDir == NULL) || (!appendDirSep(&userDir)))
- {
- allocator.Free(baseDir);
- baseDir = NULL;
- return(0);
- } /* if */
-
- initialized = 1;
-
- /* This makes sure that the error subsystem is initialized. */
- __PHYSFS_setError(PHYSFS_getLastError());
-
- return(1);
-} /* PHYSFS_init */
-
-
-/* MAKE SURE you hold stateLock before calling this! */
-static int closeFileHandleList(FileHandle **list)
-{
- FileHandle *i;
- FileHandle *next = NULL;
-
- for (i = *list; i != NULL; i = next)
- {
- next = i->next;
- if (!i->funcs->fileClose(i->opaque))
- {
- *list = i;
- return(0);
- } /* if */
-
- allocator.Free(i);
- } /* for */
-
- *list = NULL;
- return(1);
-} /* closeFileHandleList */
-
-
-/* MAKE SURE you hold the stateLock before calling this! */
-static void freeSearchPath(void)
-{
- DirHandle *i;
- DirHandle *next = NULL;
-
- closeFileHandleList(&openReadList);
-
- if (searchPath != NULL)
- {
- for (i = searchPath; i != NULL; i = next)
- {
- next = i->next;
- freeDirHandle(i, openReadList);
- } /* for */
- searchPath = NULL;
- } /* if */
-} /* freeSearchPath */
-
-
-int PHYSFS_deinit(void)
-{
- BAIL_IF_MACRO(!initialized, ERR_NOT_INITIALIZED, 0);
- BAIL_IF_MACRO(!__PHYSFS_platformDeinit(), NULL, 0);
-
- closeFileHandleList(&openWriteList);
- BAIL_IF_MACRO(!PHYSFS_setWriteDir(NULL), ERR_FILES_STILL_OPEN, 0);
-
- freeSearchPath();
- freeErrorMessages();
-
- if (baseDir != NULL)
- {
- allocator.Free(baseDir);
- baseDir = NULL;
- } /* if */
-
- if (userDir != NULL)
- {
- allocator.Free(userDir);
- userDir = NULL;
- } /* if */
-
- allowSymLinks = 0;
- initialized = 0;
-
- __PHYSFS_platformDestroyMutex(errorLock);
- __PHYSFS_platformDestroyMutex(stateLock);
-
- if (allocator.Deinit != NULL)
- allocator.Deinit();
-
- errorLock = stateLock = NULL;
- return(1);
-} /* PHYSFS_deinit */
-
-
-int PHYSFS_isInit(void)
-{
- return(initialized);
-} /* PHYSFS_isInit */
-
-
-const PHYSFS_ArchiveInfo **PHYSFS_supportedArchiveTypes(void)
-{
- return(supported_types);
-} /* PHYSFS_supportedArchiveTypes */
-
-
-void PHYSFS_freeList(void *list)
-{
- void **i;
- for (i = (void **) list; *i != NULL; i++)
- allocator.Free(*i);
-
- allocator.Free(list);
-} /* PHYSFS_freeList */
-
-
-const char *PHYSFS_getDirSeparator(void)
-{
- return(__PHYSFS_platformDirSeparator);
-} /* PHYSFS_getDirSeparator */
-
-
-char **PHYSFS_getCdRomDirs(void)
-{
- return(doEnumStringList(__PHYSFS_platformDetectAvailableCDs));
-} /* PHYSFS_getCdRomDirs */
-
-
-void PHYSFS_getCdRomDirsCallback(PHYSFS_StringCallback callback, void *data)
-{
- __PHYSFS_platformDetectAvailableCDs(callback, data);
-} /* PHYSFS_getCdRomDirsCallback */
-
-
-const char *PHYSFS_getBaseDir(void)
-{
- return(baseDir); /* this is calculated in PHYSFS_init()... */
-} /* PHYSFS_getBaseDir */
-
-
-const char *PHYSFS_getUserDir(void)
-{
- return(userDir); /* this is calculated in PHYSFS_init()... */
-} /* PHYSFS_getUserDir */
-
-
-const char *PHYSFS_getWriteDir(void)
-{
- const char *retval = NULL;
-
- __PHYSFS_platformGrabMutex(stateLock);
- if (writeDir != NULL)
- retval = writeDir->dirName;
- __PHYSFS_platformReleaseMutex(stateLock);
-
- return(retval);
-} /* PHYSFS_getWriteDir */
-
-
-int PHYSFS_setWriteDir(const char *newDir)
-{
- int retval = 1;
-
- __PHYSFS_platformGrabMutex(stateLock);
-
- if (writeDir != NULL)
- {
- BAIL_IF_MACRO_MUTEX(!freeDirHandle(writeDir, openWriteList), NULL,
- stateLock, 0);
- writeDir = NULL;
- } /* if */
-
- if (newDir != NULL)
- {
- writeDir = createDirHandle(newDir, NULL, 1);
- retval = (writeDir != NULL);
- } /* if */
-
- __PHYSFS_platformReleaseMutex(stateLock);
-
- return(retval);
-} /* PHYSFS_setWriteDir */
-
-
-int PHYSFS_mount(const char *newDir, const char *mountPoint, int appendToPath)
-{
- DirHandle *dh;
- DirHandle *prev = NULL;
- DirHandle *i;
-
- BAIL_IF_MACRO(newDir == NULL, ERR_INVALID_ARGUMENT, 0);
-
- if (mountPoint == NULL)
- mountPoint = "/";
-
- __PHYSFS_platformGrabMutex(stateLock);
-
- for (i = searchPath; i != NULL; i = i->next)
- {
- /* already in search path? */
- BAIL_IF_MACRO_MUTEX(strcmp(newDir, i->dirName)==0, NULL, stateLock, 1);
- prev = i;
- } /* for */
-
- dh = createDirHandle(newDir, mountPoint, 0);
- BAIL_IF_MACRO_MUTEX(dh == NULL, NULL, stateLock, 0);
-
- if (appendToPath)
- {
- if (prev == NULL)
- searchPath = dh;
- else
- prev->next = dh;
- } /* if */
- else
- {
- dh->next = searchPath;
- searchPath = dh;
- } /* else */
-
- __PHYSFS_platformReleaseMutex(stateLock);
- return(1);
-} /* PHYSFS_mount */
-
-
-int PHYSFS_addToSearchPath(const char *newDir, int appendToPath)
-{
- return(PHYSFS_mount(newDir, NULL, appendToPath));
-} /* PHYSFS_addToSearchPath */
-
-
-int PHYSFS_removeFromSearchPath(const char *oldDir)
-{
- DirHandle *i;
- DirHandle *prev = NULL;
- DirHandle *next = NULL;
-
- BAIL_IF_MACRO(oldDir == NULL, ERR_INVALID_ARGUMENT, 0);
-
- __PHYSFS_platformGrabMutex(stateLock);
- for (i = searchPath; i != NULL; i = i->next)
- {
- if (strcmp(i->dirName, oldDir) == 0)
- {
- next = i->next;
- BAIL_IF_MACRO_MUTEX(!freeDirHandle(i, openReadList), NULL,
- stateLock, 0);
-
- if (prev == NULL)
- searchPath = next;
- else
- prev->next = next;
-
- BAIL_MACRO_MUTEX(NULL, stateLock, 1);
- } /* if */
- prev = i;
- } /* for */
-
- BAIL_MACRO_MUTEX(ERR_NOT_IN_SEARCH_PATH, stateLock, 0);
-} /* PHYSFS_removeFromSearchPath */
-
-
-char **PHYSFS_getSearchPath(void)
-{
- return(doEnumStringList(PHYSFS_getSearchPathCallback));
-} /* PHYSFS_getSearchPath */
-
-
-const char *PHYSFS_getMountPoint(const char *dir)
-{
- DirHandle *i;
- __PHYSFS_platformGrabMutex(stateLock);
- for (i = searchPath; i != NULL; i = i->next)
- {
- if (strcmp(i->dirName, dir) == 0)
- {
- const char *retval = ((i->mountPoint) ? i->mountPoint : "/");
- __PHYSFS_platformReleaseMutex(stateLock);
- return(retval);
- } /* if */
- } /* for */
- __PHYSFS_platformReleaseMutex(stateLock);
-
- BAIL_MACRO(ERR_NOT_IN_SEARCH_PATH, NULL);
-} /* PHYSFS_getMountPoint */
-
-
-void PHYSFS_getSearchPathCallback(PHYSFS_StringCallback callback, void *data)
-{
- DirHandle *i;
-
- __PHYSFS_platformGrabMutex(stateLock);
-
- for (i = searchPath; i != NULL; i = i->next)
- callback(data, i->dirName);
-
- __PHYSFS_platformReleaseMutex(stateLock);
-} /* PHYSFS_getSearchPathCallback */
-
-
-/* Split out to avoid stack allocation in a loop. */
-static void setSaneCfgAddPath(const char *i, const size_t l, const char *dirsep,
- int archivesFirst)
-{
- const char *d = PHYSFS_getRealDir(i);
- const size_t allocsize = strlen(d) + strlen(dirsep) + l + 1;
- char *str = (char *) __PHYSFS_smallAlloc(allocsize);
- if (str != NULL)
- {
- sprintf(str, "%s%s%s", d, dirsep, i);
- PHYSFS_addToSearchPath(str, archivesFirst == 0);
- __PHYSFS_smallFree(str);
- } /* if */
-} /* setSaneCfgAddPath */
-
-
-int PHYSFS_setSaneConfig(const char *organization, const char *appName,
- const char *archiveExt, int includeCdRoms,
- int archivesFirst)
-{
- const char *basedir = PHYSFS_getBaseDir();
- const char *userdir = PHYSFS_getUserDir();
- const char *dirsep = PHYSFS_getDirSeparator();
- PHYSFS_uint64 len = 0;
- char *str = NULL;
-
- BAIL_IF_MACRO(!initialized, ERR_NOT_INITIALIZED, 0);
-
- /* set write dir... */
- len = (strlen(userdir) + (strlen(organization) * 2) +
- (strlen(appName) * 2) + (strlen(dirsep) * 3) + 2);
-
- str = (char *) __PHYSFS_smallAlloc(len);
-
- BAIL_IF_MACRO(str == NULL, ERR_OUT_OF_MEMORY, 0);
- sprintf(str, "%s.%s%s%s", userdir, organization, dirsep, appName);
-
- if (!PHYSFS_setWriteDir(str))
- {
- int no_write = 0;
- sprintf(str, ".%s/%s", organization, appName);
- if ( (PHYSFS_setWriteDir(userdir)) &&
- (PHYSFS_mkdir(str)) )
- {
- sprintf(str, "%s.%s%s%s", userdir, organization, dirsep, appName);
- if (!PHYSFS_setWriteDir(str))
- no_write = 1;
- } /* if */
- else
- {
- no_write = 1;
- } /* else */
-
- if (no_write)
- {
- PHYSFS_setWriteDir(NULL); /* just in case. */
- __PHYSFS_smallFree(str);
- BAIL_MACRO(ERR_CANT_SET_WRITE_DIR, 0);
- } /* if */
- } /* if */
-
- /* Put write dir first in search path... */
- PHYSFS_addToSearchPath(str, 0);
- __PHYSFS_smallFree(str);
-
- /* Put base path on search path... */
- PHYSFS_addToSearchPath(basedir, 1);
-
- /* handle CD-ROMs... */
- if (includeCdRoms)
- {
- char **cds = PHYSFS_getCdRomDirs();
- char **i;
- for (i = cds; *i != NULL; i++)
- PHYSFS_addToSearchPath(*i, 1);
-
- PHYSFS_freeList(cds);
- } /* if */
-
- /* Root out archives, and add them to search path... */
- if (archiveExt != NULL)
- {
- char **rc = PHYSFS_enumerateFiles("/");
- char **i;
- size_t extlen = strlen(archiveExt);
- char *ext;
-
- for (i = rc; *i != NULL; i++)
- {
- size_t l = strlen(*i);
- if ((l > extlen) && ((*i)[l - extlen - 1] == '.'))
- {
- ext = (*i) + (l - extlen);
- if (__PHYSFS_stricmpASCII(ext, archiveExt) == 0)
- setSaneCfgAddPath(*i, l, dirsep, archivesFirst);
- } /* if */
- } /* for */
-
- PHYSFS_freeList(rc);
- } /* if */
-
- return(1);
-} /* PHYSFS_setSaneConfig */
-
-
-void PHYSFS_permitSymbolicLinks(int allow)
-{
- allowSymLinks = allow;
-} /* PHYSFS_permitSymbolicLinks */
-
-
-int PHYSFS_symbolicLinksPermitted(void)
-{
- return(allowSymLinks);
-} /* PHYSFS_symbolicLinksPermitted */
-
-
-/* string manipulation in C makes my ass itch. */
-char *__PHYSFS_convertToDependent(const char *prepend,
- const char *dirName,
- const char *append)
-{
- const char *dirsep = __PHYSFS_platformDirSeparator;
- size_t sepsize = strlen(dirsep);
- char *str;
- char *i1;
- char *i2;
- size_t allocSize;
-
- while (*dirName == '/') /* !!! FIXME: pass through sanitize function. */
- dirName++;
-
- allocSize = strlen(dirName) + 1;
- if (prepend != NULL)
- allocSize += strlen(prepend) + sepsize;
- if (append != NULL)
- allocSize += strlen(append) + sepsize;
-
- /* make sure there's enough space if the dir separator is bigger. */
- if (sepsize > 1)
- {
- str = (char *) dirName;
- do
- {
- str = strchr(str, '/');
- if (str != NULL)
- {
- allocSize += (sepsize - 1);
- str++;
- } /* if */
- } while (str != NULL);
- } /* if */
-
- str = (char *) allocator.Malloc(allocSize);
- BAIL_IF_MACRO(str == NULL, ERR_OUT_OF_MEMORY, NULL);
-
- if (prepend == NULL)
- *str = '\0';
- else
- {
- strcpy(str, prepend);
- strcat(str, dirsep);
- } /* else */
-
- for (i1 = (char *) dirName, i2 = str + strlen(str); *i1; i1++, i2++)
- {
- if (*i1 == '/')
- {
- strcpy(i2, dirsep);
- i2 += sepsize;
- } /* if */
- else
- {
- *i2 = *i1;
- } /* else */
- } /* for */
- *i2 = '\0';
-
- if (append)
- {
- strcat(str, dirsep);
- strcat(str, append);
- } /* if */
-
- return(str);
-} /* __PHYSFS_convertToDependent */
-
-
-/*
- * Verify that (fname) (in platform-independent notation), in relation
- * to (h) is secure. That means that each element of fname is checked
- * for symlinks (if they aren't permitted). This also allows for quick
- * rejection of files that exist outside an archive's mountpoint.
- *
- * With some exceptions (like PHYSFS_mkdir(), which builds multiple subdirs
- * at a time), you should always pass zero for "allowMissing" for efficiency.
- *
- * (fname) must point to an output from sanitizePlatformIndependentPath(),
- * since it will make sure that path names are in the right format for
- * passing certain checks. It will also do checks for "insecure" pathnames
- * like ".." which should be done once instead of once per archive. This also
- * gives us license to treat (fname) as scratch space in this function.
- *
- * Returns non-zero if string is safe, zero if there's a security issue.
- * PHYSFS_getLastError() will specify what was wrong. (*fname) will be
- * updated to point past any mount point elements so it is prepared to
- * be used with the archiver directly.
- */
-static int verifyPath(DirHandle *h, char **_fname, int allowMissing)
-{
- char *fname = *_fname;
- int retval = 1;
- char *start;
- char *end;
-
- if (*fname == '\0') /* quick rejection. */
- return(1);
-
- /* !!! FIXME: This codeblock sucks. */
- if (h->mountPoint != NULL) /* NULL mountpoint means "/". */
- {
- size_t mntpntlen = strlen(h->mountPoint);
- size_t len = strlen(fname);
- assert(mntpntlen > 1); /* root mount points should be NULL. */
- /* not under the mountpoint, so skip this archive. */
- BAIL_IF_MACRO(len < mntpntlen-1, ERR_NO_SUCH_PATH, 0);
- /* !!! FIXME: Case insensitive? */
- retval = strncmp(h->mountPoint, fname, mntpntlen-1);
- BAIL_IF_MACRO(retval != 0, ERR_NO_SUCH_PATH, 0);
- if (len > mntpntlen-1) /* corner case... */
- BAIL_IF_MACRO(fname[mntpntlen-1] != '/', ERR_NO_SUCH_PATH, 0);
- fname += mntpntlen-1; /* move to start of actual archive path. */
- if (*fname == '/')
- fname++;
- *_fname = fname; /* skip mountpoint for later use. */
- retval = 1; /* may be reset, below. */
- } /* if */
-
- start = fname;
- if (!allowSymLinks)
- {
- while (1)
- {
- int rc = 0;
- end = strchr(start, '/');
-
- if (end != NULL) *end = '\0';
- rc = h->funcs->isSymLink(h->opaque, fname, &retval);
- if (end != NULL) *end = '/';
-
- BAIL_IF_MACRO(rc, ERR_SYMLINK_DISALLOWED, 0); /* insecure. */
-
- /* break out early if path element is missing. */
- if (!retval)
- {
- /*
- * We need to clear it if it's the last element of the path,
- * since this might be a non-existant file we're opening
- * for writing...
- */
- if ((end == NULL) || (allowMissing))
- retval = 1;
- break;
- } /* if */
-
- if (end == NULL)
- break;
-
- start = end + 1;
- } /* while */
- } /* if */
-
- return(retval);
-} /* verifyPath */
-
-
-static int doMkdir(const char *_dname, char *dname)
-{
- DirHandle *h;
- char *start;
- char *end;
- int retval = 0;
- int exists = 1; /* force existance check on first path element. */
-
- BAIL_IF_MACRO(!sanitizePlatformIndependentPath(_dname, dname), NULL, 0);
-
- __PHYSFS_platformGrabMutex(stateLock);
- BAIL_IF_MACRO_MUTEX(writeDir == NULL, ERR_NO_WRITE_DIR, stateLock, 0);
- h = writeDir;
- BAIL_IF_MACRO_MUTEX(!verifyPath(h, &dname, 1), NULL, stateLock, 0);
-
- start = dname;
- while (1)
- {
- end = strchr(start, '/');
- if (end != NULL)
- *end = '\0';
-
- /* only check for existance if all parent dirs existed, too... */
- if (exists)
- retval = h->funcs->isDirectory(h->opaque, dname, &exists);
-
- if (!exists)
- retval = h->funcs->mkdir(h->opaque, dname);
-
- if (!retval)
- break;
-
- if (end == NULL)
- break;
-
- *end = '/';
- start = end + 1;
- } /* while */
-
- __PHYSFS_platformReleaseMutex(stateLock);
- return(retval);
-} /* doMkdir */
-
-
-int PHYSFS_mkdir(const char *_dname)
-{
- int retval = 0;
- char *dname;
- size_t len;
-
- BAIL_IF_MACRO(_dname == NULL, ERR_INVALID_ARGUMENT, 0);
- len = strlen(_dname) + 1;
- dname = (char *) __PHYSFS_smallAlloc(len);
- BAIL_IF_MACRO(dname == NULL, ERR_OUT_OF_MEMORY, 0);
- retval = doMkdir(_dname, dname);
- __PHYSFS_smallFree(dname);
- return(retval);
-} /* PHYSFS_mkdir */
-
-
-static int doDelete(const char *_fname, char *fname)
-{
- int retval;
- DirHandle *h;
- BAIL_IF_MACRO(!sanitizePlatformIndependentPath(_fname, fname), NULL, 0);
-
- __PHYSFS_platformGrabMutex(stateLock);
-
- BAIL_IF_MACRO_MUTEX(writeDir == NULL, ERR_NO_WRITE_DIR, stateLock, 0);
- h = writeDir;
- BAIL_IF_MACRO_MUTEX(!verifyPath(h, &fname, 0), NULL, stateLock, 0);
- retval = h->funcs->remove(h->opaque, fname);
-
- __PHYSFS_platformReleaseMutex(stateLock);
- return(retval);
-} /* doDelete */
-
-
-int PHYSFS_delete(const char *_fname)
-{
- int retval;
- char *fname;
- size_t len;
-
- BAIL_IF_MACRO(_fname == NULL, ERR_INVALID_ARGUMENT, 0);
- len = strlen(_fname) + 1;
- fname = (char *) __PHYSFS_smallAlloc(len);
- BAIL_IF_MACRO(fname == NULL, ERR_OUT_OF_MEMORY, 0);
- retval = doDelete(_fname, fname);
- __PHYSFS_smallFree(fname);
- return(retval);
-} /* PHYSFS_delete */
-
-
-const char *PHYSFS_getRealDir(const char *_fname)
-{
- const char *retval = NULL;
- char *fname = NULL;
- size_t len;
-
- BAIL_IF_MACRO(_fname == NULL, ERR_INVALID_ARGUMENT, NULL);
- len = strlen(_fname) + 1;
- fname = __PHYSFS_smallAlloc(len);
- BAIL_IF_MACRO(fname == NULL, ERR_OUT_OF_MEMORY, NULL);
- if (sanitizePlatformIndependentPath(_fname, fname))
- {
- DirHandle *i;
- __PHYSFS_platformGrabMutex(stateLock);
- for (i = searchPath; ((i != NULL) && (retval == NULL)); i = i->next)
- {
- char *arcfname = fname;
- if (partOfMountPoint(i, arcfname))
- retval = i->dirName;
- else if (verifyPath(i, &arcfname, 0))
- {
- if (i->funcs->exists(i->opaque, arcfname))
- retval = i->dirName;
- } /* if */
- } /* for */
- __PHYSFS_platformReleaseMutex(stateLock);
- } /* if */
-
- __PHYSFS_smallFree(fname);
- return(retval);
-} /* PHYSFS_getRealDir */
-
-
-static int locateInStringList(const char *str,
- char **list,
- PHYSFS_uint32 *pos)
-{
- PHYSFS_uint32 len = *pos;
- PHYSFS_uint32 half_len;
- PHYSFS_uint32 lo = 0;
- PHYSFS_uint32 middle;
- int cmp;
-
- while (len > 0)
- {
- half_len = len >> 1;
- middle = lo + half_len;
- cmp = strcmp(list[middle], str);
-
- if (cmp == 0) /* it's in the list already. */
- return(1);
- else if (cmp > 0)
- len = half_len;
- else
- {
- lo = middle + 1;
- len -= half_len + 1;
- } /* else */
- } /* while */
-
- *pos = lo;
- return(0);
-} /* locateInStringList */
-
-
-static void enumFilesCallback(void *data, const char *origdir, const char *str)
-{
- PHYSFS_uint32 pos;
- void *ptr;
- char *newstr;
- EnumStringListCallbackData *pecd = (EnumStringListCallbackData *) data;
-
- /*
- * See if file is in the list already, and if not, insert it in there
- * alphabetically...
- */
- pos = pecd->size;
- if (locateInStringList(str, pecd->list, &pos))
- return; /* already in the list. */
-
- ptr = allocator.Realloc(pecd->list, (pecd->size + 2) * sizeof (char *));
- newstr = (char *) allocator.Malloc(strlen(str) + 1);
- if (ptr != NULL)
- pecd->list = (char **) ptr;
-
- if ((ptr == NULL) || (newstr == NULL))
- return; /* better luck next time. */
-
- strcpy(newstr, str);
-
- if (pos != pecd->size)
- {
- memmove(&pecd->list[pos+1], &pecd->list[pos],
- sizeof (char *) * ((pecd->size) - pos));
- } /* if */
-
- pecd->list[pos] = newstr;
- pecd->size++;
-} /* enumFilesCallback */
-
-
-char **PHYSFS_enumerateFiles(const char *path)
-{
- EnumStringListCallbackData ecd;
- memset(&ecd, '\0', sizeof (ecd));
- ecd.list = (char **) allocator.Malloc(sizeof (char *));
- BAIL_IF_MACRO(ecd.list == NULL, ERR_OUT_OF_MEMORY, NULL);
- PHYSFS_enumerateFilesCallback(path, enumFilesCallback, &ecd);
- ecd.list[ecd.size] = NULL;
- return(ecd.list);
-} /* PHYSFS_enumerateFiles */
-
-
-/*
- * Broke out to seperate function so we can use stack allocation gratuitously.
- */
-static void enumerateFromMountPoint(DirHandle *i, const char *arcfname,
- PHYSFS_EnumFilesCallback callback,
- const char *_fname, void *data)
-{
- const size_t len = strlen(arcfname);
- char *ptr = NULL;
- char *end = NULL;
- const size_t slen = strlen(i->mountPoint) + 1;
- char *mountPoint = (char *) __PHYSFS_smallAlloc(slen);
-
- if (mountPoint == NULL)
- return; /* oh well. */
-
- strcpy(mountPoint, i->mountPoint);
- ptr = mountPoint + ((len) ? len + 1 : 0);
- end = strchr(ptr, '/');
- assert(end); /* should always find a terminating '/'. */
- *end = '\0';
- callback(data, _fname, ptr);
- __PHYSFS_smallFree(mountPoint);
-} /* enumerateFromMountPoint */
-
-
-/* !!! FIXME: this should report error conditions. */
-void PHYSFS_enumerateFilesCallback(const char *_fname,
- PHYSFS_EnumFilesCallback callback,
- void *data)
-{
- size_t len;
- char *fname;
-
- BAIL_IF_MACRO(_fname == NULL, ERR_INVALID_ARGUMENT, ) /*0*/;
- BAIL_IF_MACRO(callback == NULL, ERR_INVALID_ARGUMENT, ) /*0*/;
-
- len = strlen(_fname) + 1;
- fname = (char *) __PHYSFS_smallAlloc(len);
- BAIL_IF_MACRO(fname == NULL, ERR_OUT_OF_MEMORY, ) /*0*/;
-
- if (sanitizePlatformIndependentPath(_fname, fname))
- {
- DirHandle *i;
- int noSyms;
-
- __PHYSFS_platformGrabMutex(stateLock);
- noSyms = !allowSymLinks;
- for (i = searchPath; i != NULL; i = i->next)
- {
- char *arcfname = fname;
- if (partOfMountPoint(i, arcfname))
- enumerateFromMountPoint(i, arcfname, callback, _fname, data);
-
- else if (verifyPath(i, &arcfname, 0))
- {
- i->funcs->enumerateFiles(i->opaque, arcfname, noSyms,
- callback, _fname, data);
- } /* else if */
- } /* for */
- __PHYSFS_platformReleaseMutex(stateLock);
- } /* if */
-
- __PHYSFS_smallFree(fname);
-} /* PHYSFS_enumerateFilesCallback */
-
-
-int PHYSFS_exists(const char *fname)
-{
- return(PHYSFS_getRealDir(fname) != NULL);
-} /* PHYSFS_exists */
-
-
-PHYSFS_sint64 PHYSFS_getLastModTime(const char *_fname)
-{
- PHYSFS_sint64 retval = -1;
- char *fname;
- size_t len;
-
- BAIL_IF_MACRO(_fname == NULL, ERR_INVALID_ARGUMENT, -1);
- len = strlen(_fname) + 1;
- fname = (char *) __PHYSFS_smallAlloc(len);
- BAIL_IF_MACRO(fname == NULL, ERR_OUT_OF_MEMORY, -1);
-
- if (sanitizePlatformIndependentPath(_fname, fname))
- {
- if (*fname == '\0') /* eh...punt if it's the root dir. */
- retval = 1; /* !!! FIXME: Maybe this should be an error? */
- else
- {
- DirHandle *i;
- int exists = 0;
- __PHYSFS_platformGrabMutex(stateLock);
- for (i = searchPath; ((i != NULL) && (!exists)); i = i->next)
- {
- char *arcfname = fname;
- exists = partOfMountPoint(i, arcfname);
- if (exists)
- retval = 1; /* !!! FIXME: What's the right value? */
- else if (verifyPath(i, &arcfname, 0))
- {
- retval = i->funcs->getLastModTime(i->opaque, arcfname,
- &exists);
- } /* else if */
- } /* for */
- __PHYSFS_platformReleaseMutex(stateLock);
- } /* else */
- } /* if */
-
- __PHYSFS_smallFree(fname);
- return(retval);
-} /* PHYSFS_getLastModTime */
-
-
-int PHYSFS_isDirectory(const char *_fname)
-{
- int retval = 0;
- size_t len;
- char *fname;
-
- BAIL_IF_MACRO(_fname == NULL, ERR_INVALID_ARGUMENT, 0);
- len = strlen(_fname) + 1;
- fname = (char *) __PHYSFS_smallAlloc(len);
- BAIL_IF_MACRO(fname == NULL, ERR_OUT_OF_MEMORY, 0);
-
- if (!sanitizePlatformIndependentPath(_fname, fname))
- retval = 0;
-
- else if (*fname == '\0')
- retval = 1; /* Root is always a dir. :) */
-
- else
- {
- DirHandle *i;
- int exists = 0;
-
- __PHYSFS_platformGrabMutex(stateLock);
- for (i = searchPath; ((i != NULL) && (!exists)); i = i->next)
- {
- char *arcfname = fname;
- if ((exists = partOfMountPoint(i, arcfname)) != 0)
- retval = 1;
- else if (verifyPath(i, &arcfname, 0))
- retval = i->funcs->isDirectory(i->opaque, arcfname, &exists);
- } /* for */
- __PHYSFS_platformReleaseMutex(stateLock);
- } /* else */
-
- __PHYSFS_smallFree(fname);
- return(retval);
-} /* PHYSFS_isDirectory */
-
-
-int PHYSFS_isSymbolicLink(const char *_fname)
-{
- int retval = 0;
- size_t len;
- char *fname;
-
- BAIL_IF_MACRO(!allowSymLinks, ERR_SYMLINK_DISALLOWED, 0);
-
- BAIL_IF_MACRO(_fname == NULL, ERR_INVALID_ARGUMENT, 0);
- len = strlen(_fname) + 1;
- fname = (char *) __PHYSFS_smallAlloc(len);
- BAIL_IF_MACRO(fname == NULL, ERR_OUT_OF_MEMORY, 0);
-
- if (!sanitizePlatformIndependentPath(_fname, fname))
- retval = 0;
-
- else if (*fname == '\0')
- retval = 1; /* Root is never a symlink. */
-
- else
- {
- DirHandle *i;
- int fileExists = 0;
-
- __PHYSFS_platformGrabMutex(stateLock);
- for (i = searchPath; ((i != NULL) && (!fileExists)); i = i->next)
- {
- char *arcfname = fname;
- if ((fileExists = partOfMountPoint(i, arcfname)) != 0)
- retval = 0; /* virtual dir...not a symlink. */
- else if (verifyPath(i, &arcfname, 0))
- retval = i->funcs->isSymLink(i->opaque, arcfname, &fileExists);
- } /* for */
- __PHYSFS_platformReleaseMutex(stateLock);
- } /* else */
-
- __PHYSFS_smallFree(fname);
- return(retval);
-} /* PHYSFS_isSymbolicLink */
-
-
-static PHYSFS_File *doOpenWrite(const char *_fname, int appending)
-{
- FileHandle *fh = NULL;
- size_t len;
- char *fname;
-
- BAIL_IF_MACRO(_fname == NULL, ERR_INVALID_ARGUMENT, 0);
- len = strlen(_fname) + 1;
- fname = (char *) __PHYSFS_smallAlloc(len);
- BAIL_IF_MACRO(fname == NULL, ERR_OUT_OF_MEMORY, 0);
-
- if (sanitizePlatformIndependentPath(_fname, fname))
- {
- void *opaque = NULL;
- DirHandle *h = NULL;
- const PHYSFS_Archiver *f;
-
- __PHYSFS_platformGrabMutex(stateLock);
-
- GOTO_IF_MACRO(!writeDir, ERR_NO_WRITE_DIR, doOpenWriteEnd);
-
- h = writeDir;
- GOTO_IF_MACRO(!verifyPath(h, &fname, 0), NULL, doOpenWriteEnd);
-
- f = h->funcs;
- if (appending)
- opaque = f->openAppend(h->opaque, fname);
- else
- opaque = f->openWrite(h->opaque, fname);
-
- GOTO_IF_MACRO(opaque == NULL, NULL, doOpenWriteEnd);
-
- fh = (FileHandle *) allocator.Malloc(sizeof (FileHandle));
- if (fh == NULL)
- {
- f->fileClose(opaque);
- GOTO_MACRO(ERR_OUT_OF_MEMORY, doOpenWriteEnd);
- } /* if */
- else
- {
- memset(fh, '\0', sizeof (FileHandle));
- fh->opaque = opaque;
- fh->dirHandle = h;
- fh->funcs = h->funcs;
- fh->next = openWriteList;
- openWriteList = fh;
- } /* else */
-
- doOpenWriteEnd:
- __PHYSFS_platformReleaseMutex(stateLock);
- } /* if */
-
- __PHYSFS_smallFree(fname);
- return((PHYSFS_File *) fh);
-} /* doOpenWrite */
-
-
-PHYSFS_File *PHYSFS_openWrite(const char *filename)
-{
- return(doOpenWrite(filename, 0));
-} /* PHYSFS_openWrite */
-
-
-PHYSFS_File *PHYSFS_openAppend(const char *filename)
-{
- return(doOpenWrite(filename, 1));
-} /* PHYSFS_openAppend */
-
-
-PHYSFS_File *PHYSFS_openRead(const char *_fname)
-{
- FileHandle *fh = NULL;
- char *fname;
- size_t len;
-
- BAIL_IF_MACRO(_fname == NULL, ERR_INVALID_ARGUMENT, 0);
- len = strlen(_fname) + 1;
- fname = (char *) __PHYSFS_smallAlloc(len);
- BAIL_IF_MACRO(fname == NULL, ERR_OUT_OF_MEMORY, 0);
-
- if (sanitizePlatformIndependentPath(_fname, fname))
- {
- int fileExists = 0;
- DirHandle *i = NULL;
- fvoid *opaque = NULL;
-
- __PHYSFS_platformGrabMutex(stateLock);
-
- GOTO_IF_MACRO(!searchPath, ERR_NO_SUCH_PATH, openReadEnd);
-
- /* !!! FIXME: Why aren't we using a for loop here? */
- i = searchPath;
-
- do
- {
- char *arcfname = fname;
- if (verifyPath(i, &arcfname, 0))
- {
- opaque = i->funcs->openRead(i->opaque, arcfname, &fileExists);
- if (opaque)
- break;
- } /* if */
- i = i->next;
- } while ((i != NULL) && (!fileExists));
-
- /* !!! FIXME: may not set an error if openRead didn't fail. */
- GOTO_IF_MACRO(opaque == NULL, NULL, openReadEnd);
-
- fh = (FileHandle *) allocator.Malloc(sizeof (FileHandle));
- if (fh == NULL)
- {
- i->funcs->fileClose(opaque);
- GOTO_MACRO(ERR_OUT_OF_MEMORY, openReadEnd);
- } /* if */
-
- memset(fh, '\0', sizeof (FileHandle));
- fh->opaque = opaque;
- fh->forReading = 1;
- fh->dirHandle = i;
- fh->funcs = i->funcs;
- fh->next = openReadList;
- openReadList = fh;
-
- openReadEnd:
- __PHYSFS_platformReleaseMutex(stateLock);
- } /* if */
-
- __PHYSFS_smallFree(fname);
- return((PHYSFS_File *) fh);
-} /* PHYSFS_openRead */
-
-
-static int closeHandleInOpenList(FileHandle **list, FileHandle *handle)
-{
- FileHandle *prev = NULL;
- FileHandle *i;
- int rc = 1;
-
- for (i = *list; i != NULL; i = i->next)
- {
- if (i == handle) /* handle is in this list? */
- {
- PHYSFS_uint8 *tmp = handle->buffer;
- rc = PHYSFS_flush((PHYSFS_File *) handle);
- if (rc)
- rc = handle->funcs->fileClose(handle->opaque);
- if (!rc)
- return(-1);
-
- if (tmp != NULL) /* free any associated buffer. */
- allocator.Free(tmp);
-
- if (prev == NULL)
- *list = handle->next;
- else
- prev->next = handle->next;
-
- allocator.Free(handle);
- return(1);
- } /* if */
- prev = i;
- } /* for */
-
- return(0);
-} /* closeHandleInOpenList */
-
-
-int PHYSFS_close(PHYSFS_File *_handle)
-{
- FileHandle *handle = (FileHandle *) _handle;
- int rc;
-
- __PHYSFS_platformGrabMutex(stateLock);
-
- /* -1 == close failure. 0 == not found. 1 == success. */
- rc = closeHandleInOpenList(&openReadList, handle);
- BAIL_IF_MACRO_MUTEX(rc == -1, NULL, stateLock, 0);
- if (!rc)
- {
- rc = closeHandleInOpenList(&openWriteList, handle);
- BAIL_IF_MACRO_MUTEX(rc == -1, NULL, stateLock, 0);
- } /* if */
-
- __PHYSFS_platformReleaseMutex(stateLock);
- BAIL_IF_MACRO(!rc, ERR_NOT_A_HANDLE, 0);
- return(1);
-} /* PHYSFS_close */
-
-
-static PHYSFS_sint64 doBufferedRead(FileHandle *fh, void *buffer,
- PHYSFS_uint32 objSize,
- PHYSFS_uint32 objCount)
-{
- PHYSFS_sint64 retval = 0;
- PHYSFS_uint32 remainder = 0;
-
- while (objCount > 0)
- {
- PHYSFS_uint32 buffered = fh->buffill - fh->bufpos;
- PHYSFS_uint64 mustread = (objSize * objCount) - remainder;
- PHYSFS_uint32 copied;
-
- if (buffered == 0) /* need to refill buffer? */
- {
- PHYSFS_sint64 rc = fh->funcs->read(fh->opaque, fh->buffer,
- 1, fh->bufsize);
- if (rc <= 0)
- {
- fh->bufpos -= remainder;
- return(((rc == -1) && (retval == 0)) ? -1 : retval);
- } /* if */
-
- buffered = fh->buffill = (PHYSFS_uint32) rc;
- fh->bufpos = 0;
- } /* if */
-
- if (buffered > mustread)
- buffered = (PHYSFS_uint32) mustread;
-
- memcpy(buffer, fh->buffer + fh->bufpos, (size_t) buffered);
- buffer = ((PHYSFS_uint8 *) buffer) + buffered;
- fh->bufpos += buffered;
- buffered += remainder; /* take remainder into account. */
- copied = (buffered / objSize);
- remainder = (buffered % objSize);
- retval += copied;
- objCount -= copied;
- } /* while */
-
- return(retval);
-} /* doBufferedRead */
-
-
-PHYSFS_sint64 PHYSFS_read(PHYSFS_File *handle, void *buffer,
- PHYSFS_uint32 objSize, PHYSFS_uint32 objCount)
-{
- FileHandle *fh = (FileHandle *) handle;
-
- BAIL_IF_MACRO(!fh->forReading, ERR_FILE_ALREADY_OPEN_W, -1);
- if (fh->buffer != NULL)
- return(doBufferedRead(fh, buffer, objSize, objCount));
-
- return(fh->funcs->read(fh->opaque, buffer, objSize, objCount));
-} /* PHYSFS_read */
-
-
-static PHYSFS_sint64 doBufferedWrite(PHYSFS_File *handle, const void *buffer,
- PHYSFS_uint32 objSize,
- PHYSFS_uint32 objCount)
-{
- FileHandle *fh = (FileHandle *) handle;
-
- /* whole thing fits in the buffer? */
- if (fh->buffill + (objSize * objCount) < fh->bufsize)
- {
- memcpy(fh->buffer + fh->buffill, buffer, objSize * objCount);
- fh->buffill += (objSize * objCount);
- return(objCount);
- } /* if */
-
- /* would overflow buffer. Flush and then write the new objects, too. */
- BAIL_IF_MACRO(!PHYSFS_flush(handle), NULL, -1);
- return(fh->funcs->write(fh->opaque, buffer, objSize, objCount));
-} /* doBufferedWrite */
-
-
-PHYSFS_sint64 PHYSFS_write(PHYSFS_File *handle, const void *buffer,
- PHYSFS_uint32 objSize, PHYSFS_uint32 objCount)
-{
- FileHandle *fh = (FileHandle *) handle;
-
- BAIL_IF_MACRO(fh->forReading, ERR_FILE_ALREADY_OPEN_R, -1);
- if (fh->buffer != NULL)
- return(doBufferedWrite(handle, buffer, objSize, objCount));
-
- return(fh->funcs->write(fh->opaque, buffer, objSize, objCount));
-} /* PHYSFS_write */
-
-
-int PHYSFS_eof(PHYSFS_File *handle)
-{
- FileHandle *fh = (FileHandle *) handle;
-
- if (!fh->forReading) /* never EOF on files opened for write/append. */
- return(0);
-
- /* eof if buffer is empty and archiver says so. */
- return((fh->bufpos == fh->buffill) && (fh->funcs->eof(fh->opaque)));
-} /* PHYSFS_eof */
-
-
-PHYSFS_sint64 PHYSFS_tell(PHYSFS_File *handle)
-{
- FileHandle *fh = (FileHandle *) handle;
- PHYSFS_sint64 pos = fh->funcs->tell(fh->opaque);
- PHYSFS_sint64 retval = fh->forReading ?
- (pos - fh->buffill) + fh->bufpos :
- (pos + fh->buffill);
- return(retval);
-} /* PHYSFS_tell */
-
-
-int PHYSFS_seek(PHYSFS_File *handle, PHYSFS_uint64 pos)
-{
- FileHandle *fh = (FileHandle *) handle;
- BAIL_IF_MACRO(!PHYSFS_flush(handle), NULL, 0);
-
- if (fh->buffer && fh->forReading)
- {
- /* avoid throwing away our precious buffer if seeking within it. */
- PHYSFS_sint64 offset = pos - PHYSFS_tell(handle);
- if ( /* seeking within the already-buffered range? */
- ((offset >= 0) && (offset <= fh->buffill - fh->bufpos)) /* fwd */
- || ((offset < 0) && (-offset <= fh->bufpos)) /* backward */ )
- {
- fh->bufpos += (PHYSFS_uint32) offset;
- return(1); /* successful seek */
- } /* if */
- } /* if */
-
- /* we have to fall back to a 'raw' seek. */
- fh->buffill = fh->bufpos = 0;
- return(fh->funcs->seek(fh->opaque, pos));
-} /* PHYSFS_seek */
-
-
-PHYSFS_sint64 PHYSFS_fileLength(PHYSFS_File *handle)
-{
- FileHandle *fh = (FileHandle *) handle;
- return(fh->funcs->fileLength(fh->opaque));
-} /* PHYSFS_filelength */
-
-
-int PHYSFS_setBuffer(PHYSFS_File *handle, PHYSFS_uint64 _bufsize)
-{
- FileHandle *fh = (FileHandle *) handle;
- PHYSFS_uint32 bufsize;
-
- /* !!! FIXME: Unlocalized string. */
- BAIL_IF_MACRO(_bufsize > 0xFFFFFFFF, "buffer must fit in 32-bits", 0);
- bufsize = (PHYSFS_uint32) _bufsize;
-
- BAIL_IF_MACRO(!PHYSFS_flush(handle), NULL, 0);
-
- /*
- * For reads, we need to move the file pointer to where it would be
- * if we weren't buffering, so that the next read will get the
- * right chunk of stuff from the file. PHYSFS_flush() handles writes.
- */
- if ((fh->forReading) && (fh->buffill != fh->bufpos))
- {
- PHYSFS_uint64 pos;
- PHYSFS_sint64 curpos = fh->funcs->tell(fh->opaque);
- BAIL_IF_MACRO(curpos == -1, NULL, 0);
- pos = ((curpos - fh->buffill) + fh->bufpos);
- BAIL_IF_MACRO(!fh->funcs->seek(fh->opaque, pos), NULL, 0);
- } /* if */
-
- if (bufsize == 0) /* delete existing buffer. */
- {
- if (fh->buffer != NULL)
- {
- allocator.Free(fh->buffer);
- fh->buffer = NULL;
- } /* if */
- } /* if */
-
- else
- {
- PHYSFS_uint8 *newbuf;
- newbuf = (PHYSFS_uint8 *) allocator.Realloc(fh->buffer, bufsize);
- BAIL_IF_MACRO(newbuf == NULL, ERR_OUT_OF_MEMORY, 0);
- fh->buffer = newbuf;
- } /* else */
-
- fh->bufsize = bufsize;
- fh->buffill = fh->bufpos = 0;
- return(1);
-} /* PHYSFS_setBuffer */
-
-
-int PHYSFS_flush(PHYSFS_File *handle)
-{
- FileHandle *fh = (FileHandle *) handle;
- PHYSFS_sint64 rc;
-
- if ((fh->forReading) || (fh->bufpos == fh->buffill))
- return(1); /* open for read or buffer empty are successful no-ops. */
-
- /* dump buffer to disk. */
- rc = fh->funcs->write(fh->opaque, fh->buffer + fh->bufpos,
- fh->buffill - fh->bufpos, 1);
- BAIL_IF_MACRO(rc <= 0, NULL, 0);
- fh->bufpos = fh->buffill = 0;
- return(1);
-} /* PHYSFS_flush */
-
-
-int PHYSFS_setAllocator(const PHYSFS_Allocator *a)
-{
- BAIL_IF_MACRO(initialized, ERR_IS_INITIALIZED, 0);
- externalAllocator = (a != NULL);
- if (externalAllocator)
- memcpy(&allocator, a, sizeof (PHYSFS_Allocator));
-
- return(1);
-} /* PHYSFS_setAllocator */
-
-
-static void *mallocAllocatorMalloc(PHYSFS_uint64 s)
-{
- BAIL_IF_MACRO(__PHYSFS_ui64FitsAddressSpace(s), ERR_OUT_OF_MEMORY, NULL);
- #undef malloc
- return(malloc((size_t) s));
-} /* mallocAllocatorMalloc */
-
-
-static void *mallocAllocatorRealloc(void *ptr, PHYSFS_uint64 s)
-{
- BAIL_IF_MACRO(__PHYSFS_ui64FitsAddressSpace(s), ERR_OUT_OF_MEMORY, NULL);
- #undef realloc
- return(realloc(ptr, (size_t) s));
-} /* mallocAllocatorRealloc */
-
-
-static void mallocAllocatorFree(void *ptr)
-{
- #undef free
- free(ptr);
-} /* mallocAllocatorFree */
-
-
-static void setDefaultAllocator(void)
-{
- assert(!externalAllocator);
- if (!__PHYSFS_platformSetDefaultAllocator(&allocator))
- {
- allocator.Init = NULL;
- allocator.Deinit = NULL;
- allocator.Malloc = mallocAllocatorMalloc;
- allocator.Realloc = mallocAllocatorRealloc;
- allocator.Free = mallocAllocatorFree;
- } /* if */
-} /* setDefaultAllocator */
-
-
-void *__PHYSFS_initSmallAlloc(void *ptr, PHYSFS_uint64 len)
-{
- const char useHeap = ((ptr == NULL) ? 1 : 0);
- if (useHeap) /* too large for stack allocation or alloca() failed. */
- ptr = allocator.Malloc(len+1);
-
- if (ptr != NULL)
- {
- char *retval = (char *) ptr;
- /*printf("%s alloc'd (%d) bytes at (%p).\n",
- useHeap ? "heap" : "stack", (int) len, ptr);*/
- *retval = useHeap;
- return(retval+1);
- } /* if */
-
- return(NULL); /* allocation failed. */
-} /* __PHYSFS_initSmallAlloc */
-
-
-void __PHYSFS_smallFree(void *ptr)
-{
- if (ptr != NULL)
- {
- char *block = ((char *) ptr) - 1;
- const char useHeap = *block;
- if (useHeap)
- allocator.Free(block);
- /*printf("%s free'd (%p).\n", useHeap ? "heap" : "stack", block);*/
- } /* if */
-} /* __PHYSFS_smallFree */
-
-/* end of physfs.c ... */
-
+++ /dev/null
-/** \file physfs.h */
-
-/**
- * \mainpage PhysicsFS
- *
- * The latest version of PhysicsFS can be found at:
- * http://icculus.org/physfs/
- *
- * PhysicsFS; a portable, flexible file i/o abstraction.
- *
- * This API gives you access to a system file system in ways superior to the
- * stdio or system i/o calls. The brief benefits:
- *
- * - It's portable.
- * - It's safe. No file access is permitted outside the specified dirs.
- * - It's flexible. Archives (.ZIP files) can be used transparently as
- * directory structures.
- *
- * This system is largely inspired by Quake 3's PK3 files and the related
- * fs_* cvars. If you've ever tinkered with these, then this API will be
- * familiar to you.
- *
- * With PhysicsFS, you have a single writing directory and multiple
- * directories (the "search path") for reading. You can think of this as a
- * filesystem within a filesystem. If (on Windows) you were to set the
- * writing directory to "C:\MyGame\MyWritingDirectory", then no PHYSFS calls
- * could touch anything above this directory, including the "C:\MyGame" and
- * "C:\" directories. This prevents an application's internal scripting
- * language from piddling over c:\\config.sys, for example. If you'd rather
- * give PHYSFS full access to the system's REAL file system, set the writing
- * dir to "C:\", but that's generally A Bad Thing for several reasons.
- *
- * Drive letters are hidden in PhysicsFS once you set up your initial paths.
- * The search path creates a single, hierarchical directory structure.
- * Not only does this lend itself well to general abstraction with archives,
- * it also gives better support to operating systems like MacOS and Unix.
- * Generally speaking, you shouldn't ever hardcode a drive letter; not only
- * does this hurt portability to non-Microsoft OSes, but it limits your win32
- * users to a single drive, too. Use the PhysicsFS abstraction functions and
- * allow user-defined configuration options, too. When opening a file, you
- * specify it like it was on a Unix filesystem: if you want to write to
- * "C:\MyGame\MyConfigFiles\game.cfg", then you might set the write dir to
- * "C:\MyGame" and then open "MyConfigFiles/game.cfg". This gives an
- * abstraction across all platforms. Specifying a file in this way is termed
- * "platform-independent notation" in this documentation. Specifying a
- * a filename in a form such as "C:\mydir\myfile" or
- * "MacOS hard drive:My Directory:My File" is termed "platform-dependent
- * notation". The only time you use platform-dependent notation is when
- * setting up your write directory and search path; after that, all file
- * access into those directories are done with platform-independent notation.
- *
- * All files opened for writing are opened in relation to the write directory,
- * which is the root of the writable filesystem. When opening a file for
- * reading, PhysicsFS goes through the search path. This is NOT the
- * same thing as the PATH environment variable. An application using
- * PhysicsFS specifies directories to be searched which may be actual
- * directories, or archive files that contain files and subdirectories of
- * their own. See the end of these docs for currently supported archive
- * formats.
- *
- * Once the search path is defined, you may open files for reading. If you've
- * got the following search path defined (to use a win32 example again):
- *
- * - C:\\mygame
- * - C:\\mygame\\myuserfiles
- * - D:\\mygamescdromdatafiles
- * - C:\\mygame\\installeddatafiles.zip
- *
- * Then a call to PHYSFS_openRead("textfiles/myfile.txt") (note the directory
- * separator, lack of drive letter, and lack of dir separator at the start of
- * the string; this is platform-independent notation) will check for
- * C:\\mygame\\textfiles\\myfile.txt, then
- * C:\\mygame\\myuserfiles\\textfiles\\myfile.txt, then
- * D:\\mygamescdromdatafiles\\textfiles\\myfile.txt, then, finally, for
- * textfiles\\myfile.txt inside of C:\\mygame\\installeddatafiles.zip.
- * Remember that most archive types and platform filesystems store their
- * filenames in a case-sensitive manner, so you should be careful to specify
- * it correctly.
- *
- * Files opened through PhysicsFS may NOT contain "." or ".." or ":" as dir
- * elements. Not only are these meaningless on MacOS Classic and/or Unix,
- * they are a security hole. Also, symbolic links (which can be found in
- * some archive types and directly in the filesystem on Unix platforms) are
- * NOT followed until you call PHYSFS_permitSymbolicLinks(). That's left to
- * your own discretion, as following a symlink can allow for access outside
- * the write dir and search paths. For portability, there is no mechanism for
- * creating new symlinks in PhysicsFS.
- *
- * The write dir is not included in the search path unless you specifically
- * add it. While you CAN change the write dir as many times as you like,
- * you should probably set it once and stick to it. Remember that your
- * program will not have permission to write in every directory on Unix and
- * NT systems.
- *
- * All files are opened in binary mode; there is no endline conversion for
- * textfiles. Other than that, PhysicsFS has some convenience functions for
- * platform-independence. There is a function to tell you the current
- * platform's dir separator ("\\" on windows, "/" on Unix, ":" on MacOS),
- * which is needed only to set up your search/write paths. There is a
- * function to tell you what CD-ROM drives contain accessible discs, and a
- * function to recommend a good search path, etc.
- *
- * A recommended order for the search path is the write dir, then the base dir,
- * then the cdrom dir, then any archives discovered. Quake 3 does something
- * like this, but moves the archives to the start of the search path. Build
- * Engine games, like Duke Nukem 3D and Blood, place the archives last, and
- * use the base dir for both searching and writing. There is a helper
- * function (PHYSFS_setSaneConfig()) that puts together a basic configuration
- * for you, based on a few parameters. Also see the comments on
- * PHYSFS_getBaseDir(), and PHYSFS_getUserDir() for info on what those
- * are and how they can help you determine an optimal search path.
- *
- * PhysicsFS 2.0 adds the concept of "mounting" archives to arbitrary points
- * in the search path. If a zipfile contains "maps/level.map" and you mount
- * that archive at "mods/mymod", then you would have to open
- * "mods/mymod/maps/level.map" to access the file, even though "mods/mymod"
- * isn't actually specified in the .zip file. Unlike the Unix mentality of
- * mounting a filesystem, "mods/mymod" doesn't actually have to exist when
- * mounting the zipfile. It's a "virtual" directory. The mounting mechanism
- * allows the developer to seperate archives in the tree and avoid trampling
- * over files when added new archives, such as including mod support in a
- * game...keeping external content on a tight leash in this manner can be of
- * utmost importance to some applications.
- *
- * PhysicsFS is mostly thread safe. The error messages returned by
- * PHYSFS_getLastError are unique by thread, and library-state-setting
- * functions are mutex'd. For efficiency, individual file accesses are
- * not locked, so you can not safely read/write/seek/close/etc the same
- * file from two threads at the same time. Other race conditions are bugs
- * that should be reported/patched.
- *
- * While you CAN use stdio/syscall file access in a program that has PHYSFS_*
- * calls, doing so is not recommended, and you can not use system
- * filehandles with PhysicsFS and vice versa.
- *
- * Note that archives need not be named as such: if you have a ZIP file and
- * rename it with a .PKG extension, the file will still be recognized as a
- * ZIP archive by PhysicsFS; the file's contents are used to determine its
- * type where possible.
- *
- * Currently supported archive types:
- * - .ZIP (pkZip/WinZip/Info-ZIP compatible)
- * - .GRP (Build Engine groupfile archives)
- * - .PAK (Quake I/II archive format)
- * - .HOG (Descent I/II HOG file archives)
- * - .MVL (Descent II movielib archives)
- * - .WAD (DOOM engine archives)
- *
- *
- * String policy for PhysicsFS 2.0 and later:
- *
- * PhysicsFS 1.0 could only deal with null-terminated ASCII strings. All high
- * ASCII chars resulted in undefined behaviour, and there was no Unicode
- * support at all. PhysicsFS 2.0 supports Unicode without breaking binary
- * compatibility with the 1.0 API by using UTF-8 encoding of all strings
- * passed in and out of the library.
- *
- * All strings passed through PhysicsFS are in null-terminated UTF-8 format.
- * This means that if all you care about is English (ASCII characters <= 127)
- * then you just use regular C strings. If you care about Unicode (and you
- * should!) then you need to figure out what your platform wants, needs, and
- * offers. If you are on Windows and build with Unicode support, your TCHAR
- * strings are two bytes per character (this is called "UCS-2 encoding"). You
- * should convert them to UTF-8 before handing them to PhysicsFS with
- * PHYSFS_utf8FromUcs2(). If you're using Unix or Mac OS X, your wchar_t
- * strings are four bytes per character ("UCS-4 encoding"). Use
- * PHYSFS_utf8FromUcs4(). Mac OS X can give you UTF-8 directly from a
- * CFString, and many Unixes generally give you C strings in UTF-8 format
- * everywhere. If you have a single-byte high ASCII charset, like so-many
- * European "codepages" you may be out of luck. We'll convert from "Latin1"
- * to UTF-8 only, and never back to Latin1. If you're above ASCII 127, all
- * bets are off: move to Unicode or use your platform's facilities. Passing a
- * C string with high-ASCII data that isn't UTF-8 encoded will NOT do what
- * you expect!
- *
- * Naturally, there's also PHYSFS_utf8ToUcs2() and PHYSFS_utf8ToUcs4() to get
- * data back into a format you like. Behind the scenes, PhysicsFS will use
- * Unicode where possible: the UTF-8 strings on Windows will be converted
- * and used with the multibyte Windows APIs, for example.
- *
- * PhysicsFS offers basic encoding conversion support, but not a whole string
- * library. Get your stuff into whatever format you can work with.
- *
- * Some platforms and archivers don't offer full Unicode support behind the
- * scenes. For example, OS/2 only offers "codepages" and the filesystem
- * itself doesn't support multibyte encodings. We make an earnest effort to
- * convert to/from the current locale here, but all bets are off if
- * you want to hand an arbitrary Japanese character through to these systems.
- * Modern OSes (Mac OS X, Linux, Windows, PocketPC, etc) should all be fine.
- * Many game-specific archivers are seriously unprepared for Unicode (the
- * Descent HOG/MVL and Build Engine GRP archivers, for example, only offer a
- * DOS 8.3 filename, for example). Nothing can be done for these, but they
- * tend to be legacy formats for existing content that was all ASCII (and
- * thus, valid UTF-8) anyhow. Other formats, like .ZIP, don't explicitly
- * offer Unicode support, but unofficially expect filenames to be UTF-8
- * encoded, and thus Just Work. Most everything does the right thing without
- * bothering you, but it's good to be aware of these nuances in case they
- * don't.
- *
- *
- * Other stuff:
- *
- * Please see the file LICENSE.txt in the source's root directory for licensing
- * and redistribution rights.
- *
- * Please see the file CREDITS.txt in the source's root directory for a more or
- * less complete list of who's responsible for this.
- *
- * \author Ryan C. Gordon.
- */
-
-#ifndef _INCLUDE_PHYSFS_H_
-#define _INCLUDE_PHYSFS_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#ifndef DOXYGEN_SHOULD_IGNORE_THIS
-#if (defined _MSC_VER)
-#define __EXPORT__ __declspec(dllexport)
-#elif (__GNUC__ >= 3)
-#define __EXPORT__ __attribute__((visibility("default")))
-#else
-#define __EXPORT__
-#endif
-#endif /* DOXYGEN_SHOULD_IGNORE_THIS */
-
-/**
- * \typedef PHYSFS_uint8
- * \brief An unsigned, 8-bit integer type.
- */
-typedef unsigned char PHYSFS_uint8;
-
-/**
- * \typedef PHYSFS_sint8
- * \brief A signed, 8-bit integer type.
- */
-typedef signed char PHYSFS_sint8;
-
-/**
- * \typedef PHYSFS_uint16
- * \brief An unsigned, 16-bit integer type.
- */
-typedef unsigned short PHYSFS_uint16;
-
-/**
- * \typedef PHYSFS_sint16
- * \brief A signed, 16-bit integer type.
- */
-typedef signed short PHYSFS_sint16;
-
-/**
- * \typedef PHYSFS_uint32
- * \brief An unsigned, 32-bit integer type.
- */
-typedef unsigned int PHYSFS_uint32;
-
-/**
- * \typedef PHYSFS_sint32
- * \brief A signed, 32-bit integer type.
- */
-typedef signed int PHYSFS_sint32;
-
-/**
- * \typedef PHYSFS_uint64
- * \brief An unsigned, 64-bit integer type.
- * \warning on platforms without any sort of 64-bit datatype, this is
- * equivalent to PHYSFS_uint32!
- */
-
-/**
- * \typedef PHYSFS_sint64
- * \brief A signed, 64-bit integer type.
- * \warning on platforms without any sort of 64-bit datatype, this is
- * equivalent to PHYSFS_sint32!
- */
-
-
-#if (defined PHYSFS_NO_64BIT_SUPPORT) /* oh well. */
-typedef PHYSFS_uint32 PHYSFS_uint64;
-typedef PHYSFS_sint32 PHYSFS_sint64;
-#elif (defined _MSC_VER)
-typedef signed __int64 PHYSFS_sint64;
-typedef unsigned __int64 PHYSFS_uint64;
-#else
-typedef unsigned long long PHYSFS_uint64;
-typedef signed long long PHYSFS_sint64;
-#endif
-
-
-#ifndef DOXYGEN_SHOULD_IGNORE_THIS
-/* Make sure the types really have the right sizes */
-#define PHYSFS_COMPILE_TIME_ASSERT(name, x) \
- typedef int PHYSFS_dummy_ ## name[(x) * 2 - 1]
-
-PHYSFS_COMPILE_TIME_ASSERT(uint8, sizeof(PHYSFS_uint8) == 1);
-PHYSFS_COMPILE_TIME_ASSERT(sint8, sizeof(PHYSFS_sint8) == 1);
-PHYSFS_COMPILE_TIME_ASSERT(uint16, sizeof(PHYSFS_uint16) == 2);
-PHYSFS_COMPILE_TIME_ASSERT(sint16, sizeof(PHYSFS_sint16) == 2);
-PHYSFS_COMPILE_TIME_ASSERT(uint32, sizeof(PHYSFS_uint32) == 4);
-PHYSFS_COMPILE_TIME_ASSERT(sint32, sizeof(PHYSFS_sint32) == 4);
-
-#ifndef PHYSFS_NO_64BIT_SUPPORT
-PHYSFS_COMPILE_TIME_ASSERT(uint64, sizeof(PHYSFS_uint64) == 8);
-PHYSFS_COMPILE_TIME_ASSERT(sint64, sizeof(PHYSFS_sint64) == 8);
-#endif
-
-#undef PHYSFS_COMPILE_TIME_ASSERT
-
-#endif /* DOXYGEN_SHOULD_IGNORE_THIS */
-
-
-/**
- * \struct PHYSFS_File
- * \brief A PhysicsFS file handle.
- *
- * You get a pointer to one of these when you open a file for reading,
- * writing, or appending via PhysicsFS.
- *
- * As you can see from the lack of meaningful fields, you should treat this
- * as opaque data. Don't try to manipulate the file handle, just pass the
- * pointer you got, unmolested, to various PhysicsFS APIs.
- *
- * \sa PHYSFS_openRead
- * \sa PHYSFS_openWrite
- * \sa PHYSFS_openAppend
- * \sa PHYSFS_close
- * \sa PHYSFS_read
- * \sa PHYSFS_write
- * \sa PHYSFS_seek
- * \sa PHYSFS_tell
- * \sa PHYSFS_eof
- * \sa PHYSFS_setBuffer
- * \sa PHYSFS_flush
- */
-typedef struct
-{
- void *opaque; /**< That's all you get. Don't touch. */
-} PHYSFS_File;
-
-
-/**
- * \def PHYSFS_file
- * \brief 1.0 API compatibility define.
- *
- * PHYSFS_file is identical to PHYSFS_File. This #define is here for backwards
- * compatibility with the 1.0 API, which had an inconsistent capitalization
- * convention in this case. New code should use PHYSFS_File, as this #define
- * may go away someday.
- *
- * \sa PHYSFS_File
- */
-#define PHYSFS_file PHYSFS_File
-
-
-/**
- * \struct PHYSFS_ArchiveInfo
- * \brief Information on various PhysicsFS-supported archives.
- *
- * This structure gives you details on what sort of archives are supported
- * by this implementation of PhysicsFS. Archives tend to be things like
- * ZIP files and such.
- *
- * \warning Not all binaries are created equal! PhysicsFS can be built with
- * or without support for various archives. You can check with
- * PHYSFS_supportedArchiveTypes() to see if your archive type is
- * supported.
- *
- * \sa PHYSFS_supportedArchiveTypes
- */
-typedef struct
-{
- const char *extension; /**< Archive file extension: "ZIP", for example. */
- const char *description; /**< Human-readable archive description. */
- const char *author; /**< Person who did support for this archive. */
- const char *url; /**< URL related to this archive */
-} PHYSFS_ArchiveInfo;
-
-
-/**
- * \struct PHYSFS_Version
- * \brief Information the version of PhysicsFS in use.
- *
- * Represents the library's version as three levels: major revision
- * (increments with massive changes, additions, and enhancements),
- * minor revision (increments with backwards-compatible changes to the
- * major revision), and patchlevel (increments with fixes to the minor
- * revision).
- *
- * \sa PHYSFS_VERSION
- * \sa PHYSFS_getLinkedVersion
- */
-typedef struct
-{
- PHYSFS_uint8 major; /**< major revision */
- PHYSFS_uint8 minor; /**< minor revision */
- PHYSFS_uint8 patch; /**< patchlevel */
-} PHYSFS_Version;
-
-#ifndef DOXYGEN_SHOULD_IGNORE_THIS
-#define PHYSFS_VER_MAJOR 1
-#define PHYSFS_VER_MINOR 1
-#define PHYSFS_VER_PATCH 1
-#endif /* DOXYGEN_SHOULD_IGNORE_THIS */
-
-
-/* PhysicsFS state stuff ... */
-
-/**
- * \def PHYSFS_VERSION(x)
- * \brief Macro to determine PhysicsFS version program was compiled against.
- *
- * This macro fills in a PHYSFS_Version structure with the version of the
- * library you compiled against. This is determined by what header the
- * compiler uses. Note that if you dynamically linked the library, you might
- * have a slightly newer or older version at runtime. That version can be
- * determined with PHYSFS_getLinkedVersion(), which, unlike PHYSFS_VERSION,
- * is not a macro.
- *
- * \param x A pointer to a PHYSFS_Version struct to initialize.
- *
- * \sa PHYSFS_Version
- * \sa PHYSFS_getLinkedVersion
- */
-#define PHYSFS_VERSION(x) \
-{ \
- (x)->major = PHYSFS_VER_MAJOR; \
- (x)->minor = PHYSFS_VER_MINOR; \
- (x)->patch = PHYSFS_VER_PATCH; \
-}
-
-
-/**
- * \fn void PHYSFS_getLinkedVersion(PHYSFS_Version *ver)
- * \brief Get the version of PhysicsFS that is linked against your program.
- *
- * If you are using a shared library (DLL) version of PhysFS, then it is
- * possible that it will be different than the version you compiled against.
- *
- * This is a real function; the macro PHYSFS_VERSION tells you what version
- * of PhysFS you compiled against:
- *
- * \code
- * PHYSFS_Version compiled;
- * PHYSFS_Version linked;
- *
- * PHYSFS_VERSION(&compiled);
- * PHYSFS_getLinkedVersion(&linked);
- * printf("We compiled against PhysFS version %d.%d.%d ...\n",
- * compiled.major, compiled.minor, compiled.patch);
- * printf("But we linked against PhysFS version %d.%d.%d.\n",
- * linked.major, linked.minor, linked.patch);
- * \endcode
- *
- * This function may be called safely at any time, even before PHYSFS_init().
- *
- * \sa PHYSFS_VERSION
- */
-__EXPORT__ void PHYSFS_getLinkedVersion(PHYSFS_Version *ver);
-
-
-/**
- * \fn int PHYSFS_init(const char *argv0)
- * \brief Initialize the PhysicsFS library.
- *
- * This must be called before any other PhysicsFS function.
- *
- * This should be called prior to any attempts to change your process's
- * current working directory.
- *
- * \param argv0 the argv[0] string passed to your program's mainline.
- * This may be NULL on most platforms (such as ones without a
- * standard main() function), but you should always try to pass
- * something in here. Unix-like systems such as Linux _need_ to
- * pass argv[0] from main() in here.
- * \return nonzero on success, zero on error. Specifics of the error can be
- * gleaned from PHYSFS_getLastError().
- *
- * \sa PHYSFS_deinit
- * \sa PHYSFS_isInit
- */
-__EXPORT__ int PHYSFS_init(const char *argv0);
-
-
-/**
- * \fn int PHYSFS_deinit(void)
- * \brief Deinitialize the PhysicsFS library.
- *
- * This closes any files opened via PhysicsFS, blanks the search/write paths,
- * frees memory, and invalidates all of your file handles.
- *
- * Note that this call can FAIL if there's a file open for writing that
- * refuses to close (for example, the underlying operating system was
- * buffering writes to network filesystem, and the fileserver has crashed,
- * or a hard drive has failed, etc). It is usually best to close all write
- * handles yourself before calling this function, so that you can gracefully
- * handle a specific failure.
- *
- * Once successfully deinitialized, PHYSFS_init() can be called again to
- * restart the subsystem. All defaults API states are restored at this
- * point.
- *
- * \return nonzero on success, zero on error. Specifics of the error can be
- * gleaned from PHYSFS_getLastError(). If failure, state of PhysFS is
- * undefined, and probably badly screwed up.
- *
- * \sa PHYSFS_init
- * \sa PHYSFS_isInit
- */
-__EXPORT__ int PHYSFS_deinit(void);
-
-
-/**
- * \fn const PHYSFS_ArchiveInfo **PHYSFS_supportedArchiveTypes(void)
- * \brief Get a list of supported archive types.
- *
- * Get a list of archive types supported by this implementation of PhysicFS.
- * These are the file formats usable for search path entries. This is for
- * informational purposes only. Note that the extension listed is merely
- * convention: if we list "ZIP", you can open a PkZip-compatible archive
- * with an extension of "XYZ", if you like.
- *
- * The returned value is an array of pointers to PHYSFS_ArchiveInfo structures,
- * with a NULL entry to signify the end of the list:
- *
- * \code
- * PHYSFS_ArchiveInfo **i;
- *
- * for (i = PHYSFS_supportedArchiveTypes(); *i != NULL; i++)
- * {
- * printf("Supported archive: [%s], which is [%s].\n",
- * i->extension, i->description);
- * }
- * \endcode
- *
- * The return values are pointers to static internal memory, and should
- * be considered READ ONLY, and never freed.
- *
- * \return READ ONLY Null-terminated array of READ ONLY structures.
- */
-__EXPORT__ const PHYSFS_ArchiveInfo **PHYSFS_supportedArchiveTypes(void);
-
-
-/**
- * \fn void PHYSFS_freeList(void *listVar)
- * \brief Deallocate resources of lists returned by PhysicsFS.
- *
- * Certain PhysicsFS functions return lists of information that are
- * dynamically allocated. Use this function to free those resources.
- *
- * \param listVar List of information specified as freeable by this function.
- *
- * \sa PHYSFS_getCdRomDirs
- * \sa PHYSFS_enumerateFiles
- * \sa PHYSFS_getSearchPath
- */
-__EXPORT__ void PHYSFS_freeList(void *listVar);
-
-
-/**
- * \fn const char *PHYSFS_getLastError(void)
- * \brief Get human-readable error information.
- *
- * Get the last PhysicsFS error message as a human-readable, null-terminated
- * string. This will be NULL if there's been no error since the last call to
- * this function. The pointer returned by this call points to an internal
- * buffer. Each thread has a unique error state associated with it, but each
- * time a new error message is set, it will overwrite the previous one
- * associated with that thread. It is safe to call this function at anytime,
- * even before PHYSFS_init().
- *
- * It is not wise to expect a specific string of characters here, since the
- * error message may be localized into an unfamiliar language. These strings
- * are meant to be passed on directly to the user.
- *
- * \return READ ONLY string of last error message.
- */
-__EXPORT__ const char *PHYSFS_getLastError(void);
-
-
-/**
- * \fn const char *PHYSFS_getDirSeparator(void)
- * \brief Get platform-dependent dir separator string.
- *
- * This returns "\\" on win32, "/" on Unix, and ":" on MacOS. It may be more
- * than one character, depending on the platform, and your code should take
- * that into account. Note that this is only useful for setting up the
- * search/write paths, since access into those dirs always use '/'
- * (platform-independent notation) to separate directories. This is also
- * handy for getting platform-independent access when using stdio calls.
- *
- * \return READ ONLY null-terminated string of platform's dir separator.
- */
-__EXPORT__ const char *PHYSFS_getDirSeparator(void);
-
-
-/**
- * \fn void PHYSFS_permitSymbolicLinks(int allow)
- * \brief Enable or disable following of symbolic links.
- *
- * Some physical filesystems and archives contain files that are just pointers
- * to other files. On the physical filesystem, opening such a link will
- * (transparently) open the file that is pointed to.
- *
- * By default, PhysicsFS will check if a file is really a symlink during open
- * calls and fail if it is. Otherwise, the link could take you outside the
- * write and search paths, and compromise security.
- *
- * If you want to take that risk, call this function with a non-zero parameter.
- * Note that this is more for sandboxing a program's scripting language, in
- * case untrusted scripts try to compromise the system. Generally speaking,
- * a user could very well have a legitimate reason to set up a symlink, so
- * unless you feel there's a specific danger in allowing them, you should
- * permit them.
- *
- * Symlinks are only explicitly checked when dealing with filenames
- * in platform-independent notation. That is, when setting up your
- * search and write paths, etc, symlinks are never checked for.
- *
- * Symbolic link permission can be enabled or disabled at any time after
- * you've called PHYSFS_init(), and is disabled by default.
- *
- * \param allow nonzero to permit symlinks, zero to deny linking.
- *
- * \sa PHYSFS_symbolicLinksPermitted
- */
-__EXPORT__ void PHYSFS_permitSymbolicLinks(int allow);
-
-
-/* !!! FIXME: const this? */
-/**
- * \fn char **PHYSFS_getCdRomDirs(void)
- * \brief Get an array of paths to available CD-ROM drives.
- *
- * The dirs returned are platform-dependent ("D:\" on Win32, "/cdrom" or
- * whatnot on Unix). Dirs are only returned if there is a disc ready and
- * accessible in the drive. So if you've got two drives (D: and E:), and only
- * E: has a disc in it, then that's all you get. If the user inserts a disc
- * in D: and you call this function again, you get both drives. If, on a
- * Unix box, the user unmounts a disc and remounts it elsewhere, the next
- * call to this function will reflect that change.
- *
- * This function refers to "CD-ROM" media, but it really means "inserted disc
- * media," such as DVD-ROM, HD-DVD, CDRW, and Blu-Ray discs. It looks for
- * filesystems, and as such won't report an audio CD, unless there's a
- * mounted filesystem track on it.
- *
- * The returned value is an array of strings, with a NULL entry to signify the
- * end of the list:
- *
- * \code
- * char **cds = PHYSFS_getCdRomDirs();
- * char **i;
- *
- * for (i = cds; *i != NULL; i++)
- * printf("cdrom dir [%s] is available.\n", *i);
- *
- * PHYSFS_freeList(cds);
- * \endcode
- *
- * This call may block while drives spin up. Be forewarned.
- *
- * When you are done with the returned information, you may dispose of the
- * resources by calling PHYSFS_freeList() with the returned pointer.
- *
- * \return Null-terminated array of null-terminated strings.
- *
- * \sa PHYSFS_getCdRomDirsCallback
- */
-__EXPORT__ char **PHYSFS_getCdRomDirs(void);
-
-
-/**
- * \fn const char *PHYSFS_getBaseDir(void)
- * \brief Get the path where the application resides.
- *
- * Helper function.
- *
- * Get the "base dir". This is the directory where the application was run
- * from, which is probably the installation directory, and may or may not
- * be the process's current working directory.
- *
- * You should probably use the base dir in your search path.
- *
- * \return READ ONLY string of base dir in platform-dependent notation.
- *
- * \sa PHYSFS_getUserDir
- */
-__EXPORT__ const char *PHYSFS_getBaseDir(void);
-
-
-/**
- * \fn const char *PHYSFS_getUserDir(void)
- * \brief Get the path where user's home directory resides.
- *
- * Helper function.
- *
- * Get the "user dir". This is meant to be a suggestion of where a specific
- * user of the system can store files. On Unix, this is her home directory.
- * On systems with no concept of multiple home directories (MacOS, win95),
- * this will default to something like "C:\mybasedir\users\username"
- * where "username" will either be the login name, or "default" if the
- * platform doesn't support multiple users, either.
- *
- * You should probably use the user dir as the basis for your write dir, and
- * also put it near the beginning of your search path.
- *
- * \return READ ONLY string of user dir in platform-dependent notation.
- *
- * \sa PHYSFS_getBaseDir
- */
-__EXPORT__ const char *PHYSFS_getUserDir(void);
-
-
-/**
- * \fn const char *PHYSFS_getWriteDir(void)
- * \brief Get path where PhysicsFS will allow file writing.
- *
- * Get the current write dir. The default write dir is NULL.
- *
- * \return READ ONLY string of write dir in platform-dependent notation,
- * OR NULL IF NO WRITE PATH IS CURRENTLY SET.
- *
- * \sa PHYSFS_setWriteDir
- */
-__EXPORT__ const char *PHYSFS_getWriteDir(void);
-
-
-/**
- * \fn int PHYSFS_setWriteDir(const char *newDir)
- * \brief Tell PhysicsFS where it may write files.
- *
- * Set a new write dir. This will override the previous setting.
- *
- * This call will fail (and fail to change the write dir) if the current
- * write dir still has files open in it.
- *
- * \param newDir The new directory to be the root of the write dir,
- * specified in platform-dependent notation. Setting to NULL
- * disables the write dir, so no files can be opened for
- * writing via PhysicsFS.
- * \return non-zero on success, zero on failure. All attempts to open a file
- * for writing via PhysicsFS will fail until this call succeeds.
- * Specifics of the error can be gleaned from PHYSFS_getLastError().
- *
- * \sa PHYSFS_getWriteDir
- */
-__EXPORT__ int PHYSFS_setWriteDir(const char *newDir);
-
-
-/**
- * \fn int PHYSFS_addToSearchPath(const char *newDir, int appendToPath)
- * \brief Add an archive or directory to the search path.
- *
- * This is a legacy call in PhysicsFS 2.0, equivalent to:
- * PHYSFS_mount(newDir, NULL, appendToPath);
- *
- * You must use this and not PHYSFS_mount if binary compatibility with
- * PhysicsFS 1.0 is important (which it may not be for many people).
- *
- * \sa PHYSFS_mount
- * \sa PHYSFS_removeFromSearchPath
- * \sa PHYSFS_getSearchPath
- */
-__EXPORT__ int PHYSFS_addToSearchPath(const char *newDir, int appendToPath);
-
-
-/**
- * \fn int PHYSFS_removeFromSearchPath(const char *oldDir)
- * \brief Remove a directory or archive from the search path.
- *
- * This must be a (case-sensitive) match to a dir or archive already in the
- * search path, specified in platform-dependent notation.
- *
- * This call will fail (and fail to remove from the path) if the element still
- * has files open in it.
- *
- * \param oldDir dir/archive to remove.
- * \return nonzero on success, zero on failure.
- * Specifics of the error can be gleaned from PHYSFS_getLastError().
- *
- * \sa PHYSFS_addToSearchPath
- * \sa PHYSFS_getSearchPath
- */
-__EXPORT__ int PHYSFS_removeFromSearchPath(const char *oldDir);
-
-
-/**
- * \fn char **PHYSFS_getSearchPath(void)
- * \brief Get the current search path.
- *
- * The default search path is an empty list.
- *
- * The returned value is an array of strings, with a NULL entry to signify the
- * end of the list:
- *
- * \code
- * char **i;
- *
- * for (i = PHYSFS_getSearchPath(); *i != NULL; i++)
- * printf("[%s] is in the search path.\n", *i);
- * \endcode
- *
- * When you are done with the returned information, you may dispose of the
- * resources by calling PHYSFS_freeList() with the returned pointer.
- *
- * \return Null-terminated array of null-terminated strings. NULL if there
- * was a problem (read: OUT OF MEMORY).
- *
- * \sa PHYSFS_getSearchPathCallback
- * \sa PHYSFS_addToSearchPath
- * \sa PHYSFS_removeFromSearchPath
- */
-__EXPORT__ char **PHYSFS_getSearchPath(void);
-
-
-/**
- * \fn int PHYSFS_setSaneConfig(const char *organization, const char *appName, const char *archiveExt, int includeCdRoms, int archivesFirst)
- * \brief Set up sane, default paths.
- *
- * Helper function.
- *
- * The write dir will be set to "userdir/.organization/appName", which is
- * created if it doesn't exist.
- *
- * The above is sufficient to make sure your program's configuration directory
- * is separated from other clutter, and platform-independent. The period
- * before "mygame" even hides the directory on Unix systems.
- *
- * The search path will be:
- *
- * - The Write Dir (created if it doesn't exist)
- * - The Base Dir (PHYSFS_getBaseDir())
- * - All found CD-ROM dirs (optionally)
- *
- * These directories are then searched for files ending with the extension
- * (archiveExt), which, if they are valid and supported archives, will also
- * be added to the search path. If you specified "PKG" for (archiveExt), and
- * there's a file named data.PKG in the base dir, it'll be checked. Archives
- * can either be appended or prepended to the search path in alphabetical
- * order, regardless of which directories they were found in.
- *
- * All of this can be accomplished from the application, but this just does it
- * all for you. Feel free to add more to the search path manually, too.
- *
- * \param organization Name of your company/group/etc to be used as a
- * dirname, so keep it small, and no-frills.
- *
- * \param appName Program-specific name of your program, to separate it
- * from other programs using PhysicsFS.
- *
- * \param archiveExt File extension used by your program to specify an
- * archive. For example, Quake 3 uses "pk3", even though
- * they are just zipfiles. Specify NULL to not dig out
- * archives automatically. Do not specify the '.' char;
- * If you want to look for ZIP files, specify "ZIP" and
- * not ".ZIP" ... the archive search is case-insensitive.
- *
- * \param includeCdRoms Non-zero to include CD-ROMs in the search path, and
- * (if (archiveExt) != NULL) search them for archives.
- * This may cause a significant amount of blocking
- * while discs are accessed, and if there are no discs
- * in the drive (or even not mounted on Unix systems),
- * then they may not be made available anyhow. You may
- * want to specify zero and handle the disc setup
- * yourself.
- *
- * \param archivesFirst Non-zero to prepend the archives to the search path.
- * Zero to append them. Ignored if !(archiveExt).
- *
- * \return nonzero on success, zero on error. Specifics of the error can be
- * gleaned from PHYSFS_getLastError().
- */
-__EXPORT__ int PHYSFS_setSaneConfig(const char *organization,
- const char *appName,
- const char *archiveExt,
- int includeCdRoms,
- int archivesFirst);
-
-
-/* Directory management stuff ... */
-
-/**
- * \fn int PHYSFS_mkdir(const char *dirName)
- * \brief Create a directory.
- *
- * This is specified in platform-independent notation in relation to the
- * write dir. All missing parent directories are also created if they
- * don't exist.
- *
- * So if you've got the write dir set to "C:\mygame\writedir" and call
- * PHYSFS_mkdir("downloads/maps") then the directories
- * "C:\mygame\writedir\downloads" and "C:\mygame\writedir\downloads\maps"
- * will be created if possible. If the creation of "maps" fails after we
- * have successfully created "downloads", then the function leaves the
- * created directory behind and reports failure.
- *
- * \param dirName New dir to create.
- * \return nonzero on success, zero on error. Specifics of the error can be
- * gleaned from PHYSFS_getLastError().
- *
- * \sa PHYSFS_delete
- */
-__EXPORT__ int PHYSFS_mkdir(const char *dirName);
-
-
-/**
- * \fn int PHYSFS_delete(const char *filename)
- * \brief Delete a file or directory.
- *
- * (filename) is specified in platform-independent notation in relation to the
- * write dir.
- *
- * A directory must be empty before this call can delete it.
- *
- * Deleting a symlink will remove the link, not what it points to, regardless
- * of whether you "permitSymLinks" or not.
- *
- * So if you've got the write dir set to "C:\mygame\writedir" and call
- * PHYSFS_delete("downloads/maps/level1.map") then the file
- * "C:\mygame\writedir\downloads\maps\level1.map" is removed from the
- * physical filesystem, if it exists and the operating system permits the
- * deletion.
- *
- * Note that on Unix systems, deleting a file may be successful, but the
- * actual file won't be removed until all processes that have an open
- * filehandle to it (including your program) close their handles.
- *
- * Chances are, the bits that make up the file still exist, they are just
- * made available to be written over at a later point. Don't consider this
- * a security method or anything. :)
- *
- * \param filename Filename to delete.
- * \return nonzero on success, zero on error. Specifics of the error can be
- * gleaned from PHYSFS_getLastError().
- */
-__EXPORT__ int PHYSFS_delete(const char *filename);
-
-
-/**
- * \fn const char *PHYSFS_getRealDir(const char *filename)
- * \brief Figure out where in the search path a file resides.
- *
- * The file is specified in platform-independent notation. The returned
- * filename will be the element of the search path where the file was found,
- * which may be a directory, or an archive. Even if there are multiple
- * matches in different parts of the search path, only the first one found
- * is used, just like when opening a file.
- *
- * So, if you look for "maps/level1.map", and C:\\mygame is in your search
- * path and C:\\mygame\\maps\\level1.map exists, then "C:\mygame" is returned.
- *
- * If a any part of a match is a symbolic link, and you've not explicitly
- * permitted symlinks, then it will be ignored, and the search for a match
- * will continue.
- *
- * If you specify a fake directory that only exists as a mount point, it'll
- * be associated with the first archive mounted there, even though that
- * directory isn't necessarily contained in a real archive.
- *
- * \param filename file to look for.
- * \return READ ONLY string of element of search path containing the
- * the file in question. NULL if not found.
- */
-__EXPORT__ const char *PHYSFS_getRealDir(const char *filename);
-
-
-/**
- * \fn char **PHYSFS_enumerateFiles(const char *dir)
- * \brief Get a file listing of a search path's directory.
- *
- * Matching directories are interpolated. That is, if "C:\mydir" is in the
- * search path and contains a directory "savegames" that contains "x.sav",
- * "y.sav", and "z.sav", and there is also a "C:\userdir" in the search path
- * that has a "savegames" subdirectory with "w.sav", then the following code:
- *
- * \code
- * char **rc = PHYSFS_enumerateFiles("savegames");
- * char **i;
- *
- * for (i = rc; *i != NULL; i++)
- * printf(" * We've got [%s].\n", *i);
- *
- * PHYSFS_freeList(rc);
- * \endcode
- *
- * ...will print:
- *
- * \verbatim
- * We've got [x.sav].
- * We've got [y.sav].
- * We've got [z.sav].
- * We've got [w.sav].\endverbatim
- *
- * Feel free to sort the list however you like. We only promise there will
- * be no duplicates, but not what order the final list will come back in.
- *
- * Don't forget to call PHYSFS_freeList() with the return value from this
- * function when you are done with it.
- *
- * \param dir directory in platform-independent notation to enumerate.
- * \return Null-terminated array of null-terminated strings.
- *
- * \sa PHYSFS_enumerateFilesCallback
- */
-__EXPORT__ char **PHYSFS_enumerateFiles(const char *dir);
-
-
-/**
- * \fn int PHYSFS_exists(const char *fname)
- * \brief Determine if a file exists in the search path.
- *
- * Reports true if there is an entry anywhere in the search path by the
- * name of (fname).
- *
- * Note that entries that are symlinks are ignored if
- * PHYSFS_permitSymbolicLinks(1) hasn't been called, so you
- * might end up further down in the search path than expected.
- *
- * \param fname filename in platform-independent notation.
- * \return non-zero if filename exists. zero otherwise.
- *
- * \sa PHYSFS_isDirectory
- * \sa PHYSFS_isSymbolicLink
- */
-__EXPORT__ int PHYSFS_exists(const char *fname);
-
-
-/**
- * \fn int PHYSFS_isDirectory(const char *fname)
- * \brief Determine if a file in the search path is really a directory.
- *
- * Determine if the first occurence of (fname) in the search path is
- * really a directory entry.
- *
- * Note that entries that are symlinks are ignored if
- * PHYSFS_permitSymbolicLinks(1) hasn't been called, so you
- * might end up further down in the search path than expected.
- *
- * \param fname filename in platform-independent notation.
- * \return non-zero if filename exists and is a directory. zero otherwise.
- *
- * \sa PHYSFS_exists
- * \sa PHYSFS_isSymbolicLink
- */
-__EXPORT__ int PHYSFS_isDirectory(const char *fname);
-
-
-/**
- * \fn int PHYSFS_isSymbolicLink(const char *fname)
- * \brief Determine if a file in the search path is really a symbolic link.
- *
- * Determine if the first occurence of (fname) in the search path is
- * really a symbolic link.
- *
- * Note that entries that are symlinks are ignored if
- * PHYSFS_permitSymbolicLinks(1) hasn't been called, and as such,
- * this function will always return 0 in that case.
- *
- * \param fname filename in platform-independent notation.
- * \return non-zero if filename exists and is a symlink. zero otherwise.
- *
- * \sa PHYSFS_exists
- * \sa PHYSFS_isDirectory
- */
-__EXPORT__ int PHYSFS_isSymbolicLink(const char *fname);
-
-
-/**
- * \fn PHYSFS_sint64 PHYSFS_getLastModTime(const char *filename)
- * \brief Get the last modification time of a file.
- *
- * The modtime is returned as a number of seconds since the epoch
- * (Jan 1, 1970). The exact derivation and accuracy of this time depends on
- * the particular archiver. If there is no reasonable way to obtain this
- * information for a particular archiver, or there was some sort of error,
- * this function returns (-1).
- *
- * \param filename filename to check, in platform-independent notation.
- * \return last modified time of the file. -1 if it can't be determined.
- */
-__EXPORT__ PHYSFS_sint64 PHYSFS_getLastModTime(const char *filename);
-
-
-/* i/o stuff... */
-
-/**
- * \fn PHYSFS_File *PHYSFS_openWrite(const char *filename)
- * \brief Open a file for writing.
- *
- * Open a file for writing, in platform-independent notation and in relation
- * to the write dir as the root of the writable filesystem. The specified
- * file is created if it doesn't exist. If it does exist, it is truncated to
- * zero bytes, and the writing offset is set to the start.
- *
- * Note that entries that are symlinks are ignored if
- * PHYSFS_permitSymbolicLinks(1) hasn't been called, and opening a
- * symlink with this function will fail in such a case.
- *
- * \param filename File to open.
- * \return A valid PhysicsFS filehandle on success, NULL on error. Specifics
- * of the error can be gleaned from PHYSFS_getLastError().
- *
- * \sa PHYSFS_openRead
- * \sa PHYSFS_openAppend
- * \sa PHYSFS_write
- * \sa PHYSFS_close
- */
-__EXPORT__ PHYSFS_File *PHYSFS_openWrite(const char *filename);
-
-
-/**
- * \fn PHYSFS_File *PHYSFS_openAppend(const char *filename)
- * \brief Open a file for appending.
- *
- * Open a file for writing, in platform-independent notation and in relation
- * to the write dir as the root of the writable filesystem. The specified
- * file is created if it doesn't exist. If it does exist, the writing offset
- * is set to the end of the file, so the first write will be the byte after
- * the end.
- *
- * Note that entries that are symlinks are ignored if
- * PHYSFS_permitSymbolicLinks(1) hasn't been called, and opening a
- * symlink with this function will fail in such a case.
- *
- * \param filename File to open.
- * \return A valid PhysicsFS filehandle on success, NULL on error. Specifics
- * of the error can be gleaned from PHYSFS_getLastError().
- *
- * \sa PHYSFS_openRead
- * \sa PHYSFS_openWrite
- * \sa PHYSFS_write
- * \sa PHYSFS_close
- */
-__EXPORT__ PHYSFS_File *PHYSFS_openAppend(const char *filename);
-
-
-/**
- * \fn PHYSFS_File *PHYSFS_openRead(const char *filename)
- * \brief Open a file for reading.
- *
- * Open a file for reading, in platform-independent notation. The search path
- * is checked one at a time until a matching file is found, in which case an
- * abstract filehandle is associated with it, and reading may be done.
- * The reading offset is set to the first byte of the file.
- *
- * Note that entries that are symlinks are ignored if
- * PHYSFS_permitSymbolicLinks(1) hasn't been called, and opening a
- * symlink with this function will fail in such a case.
- *
- * \param filename File to open.
- * \return A valid PhysicsFS filehandle on success, NULL on error. Specifics
- * of the error can be gleaned from PHYSFS_getLastError().
- *
- * \sa PHYSFS_openWrite
- * \sa PHYSFS_openAppend
- * \sa PHYSFS_read
- * \sa PHYSFS_close
- */
-__EXPORT__ PHYSFS_File *PHYSFS_openRead(const char *filename);
-
-
-/**
- * \fn int PHYSFS_close(PHYSFS_File *handle)
- * \brief Close a PhysicsFS filehandle.
- *
- * This call is capable of failing if the operating system was buffering
- * writes to the physical media, and, now forced to write those changes to
- * physical media, can not store the data for some reason. In such a case,
- * the filehandle stays open. A well-written program should ALWAYS check the
- * return value from the close call in addition to every writing call!
- *
- * \param handle handle returned from PHYSFS_open*().
- * \return nonzero on success, zero on error. Specifics of the error can be
- * gleaned from PHYSFS_getLastError().
- *
- * \sa PHYSFS_openRead
- * \sa PHYSFS_openWrite
- * \sa PHYSFS_openAppend
- */
-__EXPORT__ int PHYSFS_close(PHYSFS_File *handle);
-
-
-/**
- * \fn PHYSFS_sint64 PHYSFS_read(PHYSFS_File *handle, void *buffer, PHYSFS_uint32 objSize, PHYSFS_uint32 objCount)
- * \brief Read data from a PhysicsFS filehandle
- *
- * The file must be opened for reading.
- *
- * \param handle handle returned from PHYSFS_openRead().
- * \param buffer buffer to store read data into.
- * \param objSize size in bytes of objects being read from (handle).
- * \param objCount number of (objSize) objects to read from (handle).
- * \return number of objects read. PHYSFS_getLastError() can shed light on
- * the reason this might be < (objCount), as can PHYSFS_eof().
- * -1 if complete failure.
- *
- * \sa PHYSFS_eof
- */
-__EXPORT__ PHYSFS_sint64 PHYSFS_read(PHYSFS_File *handle,
- void *buffer,
- PHYSFS_uint32 objSize,
- PHYSFS_uint32 objCount);
-
-/**
- * \fn PHYSFS_sint64 PHYSFS_write(PHYSFS_File *handle, const void *buffer, PHYSFS_uint32 objSize, PHYSFS_uint32 objCount)
- * \brief Write data to a PhysicsFS filehandle
- *
- * The file must be opened for writing.
- *
- * \param handle retval from PHYSFS_openWrite() or PHYSFS_openAppend().
- * \param buffer buffer to store read data into.
- * \param objSize size in bytes of objects being read from (handle).
- * \param objCount number of (objSize) objects to read from (handle).
- * \return number of objects written. PHYSFS_getLastError() can shed light on
- * the reason this might be < (objCount). -1 if complete failure.
- */
-__EXPORT__ PHYSFS_sint64 PHYSFS_write(PHYSFS_File *handle,
- const void *buffer,
- PHYSFS_uint32 objSize,
- PHYSFS_uint32 objCount);
-
-
-/* File position stuff... */
-
-/**
- * \fn int PHYSFS_eof(PHYSFS_File *handle)
- * \brief Check for end-of-file state on a PhysicsFS filehandle.
- *
- * Determine if the end of file has been reached in a PhysicsFS filehandle.
- *
- * \param handle handle returned from PHYSFS_openRead().
- * \return nonzero if EOF, zero if not.
- *
- * \sa PHYSFS_read
- * \sa PHYSFS_tell
- */
-__EXPORT__ int PHYSFS_eof(PHYSFS_File *handle);
-
-
-/**
- * \fn PHYSFS_sint64 PHYSFS_tell(PHYSFS_File *handle)
- * \brief Determine current position within a PhysicsFS filehandle.
- *
- * \param handle handle returned from PHYSFS_open*().
- * \return offset in bytes from start of file. -1 if error occurred.
- * Specifics of the error can be gleaned from PHYSFS_getLastError().
- *
- * \sa PHYSFS_seek
- */
-__EXPORT__ PHYSFS_sint64 PHYSFS_tell(PHYSFS_File *handle);
-
-
-/**
- * \fn int PHYSFS_seek(PHYSFS_File *handle, PHYSFS_uint64 pos)
- * \brief Seek to a new position within a PhysicsFS filehandle.
- *
- * The next read or write will occur at that place. Seeking past the
- * beginning or end of the file is not allowed, and causes an error.
- *
- * \param handle handle returned from PHYSFS_open*().
- * \param pos number of bytes from start of file to seek to.
- * \return nonzero on success, zero on error. Specifics of the error can be
- * gleaned from PHYSFS_getLastError().
- *
- * \sa PHYSFS_tell
- */
-__EXPORT__ int PHYSFS_seek(PHYSFS_File *handle, PHYSFS_uint64 pos);
-
-
-/**
- * \fn PHYSFS_sint64 PHYSFS_fileLength(PHYSFS_File *handle)
- * \brief Get total length of a file in bytes.
- *
- * Note that if the file size can't be determined (since the archive is
- * "streamed" or whatnot) than this will report (-1). Also note that if
- * another process/thread is writing to this file at the same time, then
- * the information this function supplies could be incorrect before you
- * get it. Use with caution, or better yet, don't use at all.
- *
- * \param handle handle returned from PHYSFS_open*().
- * \return size in bytes of the file. -1 if can't be determined.
- *
- * \sa PHYSFS_tell
- * \sa PHYSFS_seek
- */
-__EXPORT__ PHYSFS_sint64 PHYSFS_fileLength(PHYSFS_File *handle);
-
-
-/* Buffering stuff... */
-
-/**
- * \fn int PHYSFS_setBuffer(PHYSFS_File *handle, PHYSFS_uint64 bufsize)
- * \brief Set up buffering for a PhysicsFS file handle.
- *
- * Define an i/o buffer for a file handle. A memory block of (bufsize) bytes
- * will be allocated and associated with (handle).
- *
- * For files opened for reading, up to (bufsize) bytes are read from (handle)
- * and stored in the internal buffer. Calls to PHYSFS_read() will pull
- * from this buffer until it is empty, and then refill it for more reading.
- * Note that compressed files, like ZIP archives, will decompress while
- * buffering, so this can be handy for offsetting CPU-intensive operations.
- * The buffer isn't filled until you do your next read.
- *
- * For files opened for writing, data will be buffered to memory until the
- * buffer is full or the buffer is flushed. Closing a handle implicitly
- * causes a flush...check your return values!
- *
- * Seeking, etc transparently accounts for buffering.
- *
- * You can resize an existing buffer by calling this function more than once
- * on the same file. Setting the buffer size to zero will free an existing
- * buffer.
- *
- * PhysicsFS file handles are unbuffered by default.
- *
- * Please check the return value of this function! Failures can include
- * not being able to seek backwards in a read-only file when removing the
- * buffer, not being able to allocate the buffer, and not being able to
- * flush the buffer to disk, among other unexpected problems.
- *
- * \param handle handle returned from PHYSFS_open*().
- * \param bufsize size, in bytes, of buffer to allocate.
- * \return nonzero if successful, zero on error.
- *
- * \sa PHYSFS_flush
- * \sa PHYSFS_read
- * \sa PHYSFS_write
- * \sa PHYSFS_close
- */
-__EXPORT__ int PHYSFS_setBuffer(PHYSFS_File *handle, PHYSFS_uint64 bufsize);
-
-
-/**
- * \fn int PHYSFS_flush(PHYSFS_File *handle)
- * \brief Flush a buffered PhysicsFS file handle.
- *
- * For buffered files opened for writing, this will put the current contents
- * of the buffer to disk and flag the buffer as empty if possible.
- *
- * For buffered files opened for reading or unbuffered files, this is a safe
- * no-op, and will report success.
- *
- * \param handle handle returned from PHYSFS_open*().
- * \return nonzero if successful, zero on error.
- *
- * \sa PHYSFS_setBuffer
- * \sa PHYSFS_close
- */
-__EXPORT__ int PHYSFS_flush(PHYSFS_File *handle);
-
-
-/* Byteorder stuff... */
-
-/**
- * \fn PHYSFS_sint16 PHYSFS_swapSLE16(PHYSFS_sint16 val)
- * \brief Swap littleendian signed 16 to platform's native byte order.
- *
- * Take a 16-bit signed value in littleendian format and convert it to
- * the platform's native byte order.
- *
- * \param val value to convert
- * \return converted value.
- */
-__EXPORT__ PHYSFS_sint16 PHYSFS_swapSLE16(PHYSFS_sint16 val);
-
-
-/**
- * \fn PHYSFS_uint16 PHYSFS_swapULE16(PHYSFS_uint16 val)
- * \brief Swap littleendian unsigned 16 to platform's native byte order.
- *
- * Take a 16-bit unsigned value in littleendian format and convert it to
- * the platform's native byte order.
- *
- * \param val value to convert
- * \return converted value.
- */
-__EXPORT__ PHYSFS_uint16 PHYSFS_swapULE16(PHYSFS_uint16 val);
-
-/**
- * \fn PHYSFS_sint32 PHYSFS_swapSLE32(PHYSFS_sint32 val)
- * \brief Swap littleendian signed 32 to platform's native byte order.
- *
- * Take a 32-bit signed value in littleendian format and convert it to
- * the platform's native byte order.
- *
- * \param val value to convert
- * \return converted value.
- */
-__EXPORT__ PHYSFS_sint32 PHYSFS_swapSLE32(PHYSFS_sint32 val);
-
-
-/**
- * \fn PHYSFS_uint32 PHYSFS_swapULE32(PHYSFS_uint32 val)
- * \brief Swap littleendian unsigned 32 to platform's native byte order.
- *
- * Take a 32-bit unsigned value in littleendian format and convert it to
- * the platform's native byte order.
- *
- * \param val value to convert
- * \return converted value.
- */
-__EXPORT__ PHYSFS_uint32 PHYSFS_swapULE32(PHYSFS_uint32 val);
-
-/**
- * \fn PHYSFS_sint64 PHYSFS_swapSLE64(PHYSFS_sint64 val)
- * \brief Swap littleendian signed 64 to platform's native byte order.
- *
- * Take a 64-bit signed value in littleendian format and convert it to
- * the platform's native byte order.
- *
- * \param val value to convert
- * \return converted value.
- *
- * \warning Remember, PHYSFS_uint64 is only 32 bits on platforms without
- * any sort of 64-bit support.
- */
-__EXPORT__ PHYSFS_sint64 PHYSFS_swapSLE64(PHYSFS_sint64 val);
-
-
-/**
- * \fn PHYSFS_uint64 PHYSFS_swapULE64(PHYSFS_uint64 val)
- * \brief Swap littleendian unsigned 64 to platform's native byte order.
- *
- * Take a 64-bit unsigned value in littleendian format and convert it to
- * the platform's native byte order.
- *
- * \param val value to convert
- * \return converted value.
- *
- * \warning Remember, PHYSFS_uint64 is only 32 bits on platforms without
- * any sort of 64-bit support.
- */
-__EXPORT__ PHYSFS_uint64 PHYSFS_swapULE64(PHYSFS_uint64 val);
-
-
-/**
- * \fn PHYSFS_sint16 PHYSFS_swapSBE16(PHYSFS_sint16 val)
- * \brief Swap bigendian signed 16 to platform's native byte order.
- *
- * Take a 16-bit signed value in bigendian format and convert it to
- * the platform's native byte order.
- *
- * \param val value to convert
- * \return converted value.
- */
-__EXPORT__ PHYSFS_sint16 PHYSFS_swapSBE16(PHYSFS_sint16 val);
-
-
-/**
- * \fn PHYSFS_uint16 PHYSFS_swapUBE16(PHYSFS_uint16 val)
- * \brief Swap bigendian unsigned 16 to platform's native byte order.
- *
- * Take a 16-bit unsigned value in bigendian format and convert it to
- * the platform's native byte order.
- *
- * \param val value to convert
- * \return converted value.
- */
-__EXPORT__ PHYSFS_uint16 PHYSFS_swapUBE16(PHYSFS_uint16 val);
-
-/**
- * \fn PHYSFS_sint32 PHYSFS_swapSBE32(PHYSFS_sint32 val)
- * \brief Swap bigendian signed 32 to platform's native byte order.
- *
- * Take a 32-bit signed value in bigendian format and convert it to
- * the platform's native byte order.
- *
- * \param val value to convert
- * \return converted value.
- */
-__EXPORT__ PHYSFS_sint32 PHYSFS_swapSBE32(PHYSFS_sint32 val);
-
-
-/**
- * \fn PHYSFS_uint32 PHYSFS_swapUBE32(PHYSFS_uint32 val)
- * \brief Swap bigendian unsigned 32 to platform's native byte order.
- *
- * Take a 32-bit unsigned value in bigendian format and convert it to
- * the platform's native byte order.
- *
- * \param val value to convert
- * \return converted value.
- */
-__EXPORT__ PHYSFS_uint32 PHYSFS_swapUBE32(PHYSFS_uint32 val);
-
-
-/**
- * \fn PHYSFS_sint64 PHYSFS_swapSBE64(PHYSFS_sint64 val)
- * \brief Swap bigendian signed 64 to platform's native byte order.
- *
- * Take a 64-bit signed value in bigendian format and convert it to
- * the platform's native byte order.
- *
- * \param val value to convert
- * \return converted value.
- *
- * \warning Remember, PHYSFS_uint64 is only 32 bits on platforms without
- * any sort of 64-bit support.
- */
-__EXPORT__ PHYSFS_sint64 PHYSFS_swapSBE64(PHYSFS_sint64 val);
-
-
-/**
- * \fn PHYSFS_uint64 PHYSFS_swapUBE64(PHYSFS_uint64 val)
- * \brief Swap bigendian unsigned 64 to platform's native byte order.
- *
- * Take a 64-bit unsigned value in bigendian format and convert it to
- * the platform's native byte order.
- *
- * \param val value to convert
- * \return converted value.
- *
- * \warning Remember, PHYSFS_uint64 is only 32 bits on platforms without
- * any sort of 64-bit support.
- */
-__EXPORT__ PHYSFS_uint64 PHYSFS_swapUBE64(PHYSFS_uint64 val);
-
-
-/**
- * \fn int PHYSFS_readSLE16(PHYSFS_File *file, PHYSFS_sint16 *val)
- * \brief Read and convert a signed 16-bit littleendian value.
- *
- * Convenience function. Read a signed 16-bit littleendian value from a
- * file and convert it to the platform's native byte order.
- *
- * \param file PhysicsFS file handle from which to read.
- * \param val pointer to where value should be stored.
- * \return zero on failure, non-zero on success. If successful, (*val) will
- * store the result. On failure, you can find out what went wrong
- * from PHYSFS_getLastError().
- */
-__EXPORT__ int PHYSFS_readSLE16(PHYSFS_File *file, PHYSFS_sint16 *val);
-
-
-/**
- * \fn int PHYSFS_readULE16(PHYSFS_File *file, PHYSFS_uint16 *val)
- * \brief Read and convert an unsigned 16-bit littleendian value.
- *
- * Convenience function. Read an unsigned 16-bit littleendian value from a
- * file and convert it to the platform's native byte order.
- *
- * \param file PhysicsFS file handle from which to read.
- * \param val pointer to where value should be stored.
- * \return zero on failure, non-zero on success. If successful, (*val) will
- * store the result. On failure, you can find out what went wrong
- * from PHYSFS_getLastError().
- *
- */
-__EXPORT__ int PHYSFS_readULE16(PHYSFS_File *file, PHYSFS_uint16 *val);
-
-
-/**
- * \fn int PHYSFS_readSBE16(PHYSFS_File *file, PHYSFS_sint16 *val)
- * \brief Read and convert a signed 16-bit bigendian value.
- *
- * Convenience function. Read a signed 16-bit bigendian value from a
- * file and convert it to the platform's native byte order.
- *
- * \param file PhysicsFS file handle from which to read.
- * \param val pointer to where value should be stored.
- * \return zero on failure, non-zero on success. If successful, (*val) will
- * store the result. On failure, you can find out what went wrong
- * from PHYSFS_getLastError().
- */
-__EXPORT__ int PHYSFS_readSBE16(PHYSFS_File *file, PHYSFS_sint16 *val);
-
-
-/**
- * \fn int PHYSFS_readUBE16(PHYSFS_File *file, PHYSFS_uint16 *val)
- * \brief Read and convert an unsigned 16-bit bigendian value.
- *
- * Convenience function. Read an unsigned 16-bit bigendian value from a
- * file and convert it to the platform's native byte order.
- *
- * \param file PhysicsFS file handle from which to read.
- * \param val pointer to where value should be stored.
- * \return zero on failure, non-zero on success. If successful, (*val) will
- * store the result. On failure, you can find out what went wrong
- * from PHYSFS_getLastError().
- *
- */
-__EXPORT__ int PHYSFS_readUBE16(PHYSFS_File *file, PHYSFS_uint16 *val);
-
-
-/**
- * \fn int PHYSFS_readSLE32(PHYSFS_File *file, PHYSFS_sint32 *val)
- * \brief Read and convert a signed 32-bit littleendian value.
- *
- * Convenience function. Read a signed 32-bit littleendian value from a
- * file and convert it to the platform's native byte order.
- *
- * \param file PhysicsFS file handle from which to read.
- * \param val pointer to where value should be stored.
- * \return zero on failure, non-zero on success. If successful, (*val) will
- * store the result. On failure, you can find out what went wrong
- * from PHYSFS_getLastError().
- */
-__EXPORT__ int PHYSFS_readSLE32(PHYSFS_File *file, PHYSFS_sint32 *val);
-
-
-/**
- * \fn int PHYSFS_readULE32(PHYSFS_File *file, PHYSFS_uint32 *val)
- * \brief Read and convert an unsigned 32-bit littleendian value.
- *
- * Convenience function. Read an unsigned 32-bit littleendian value from a
- * file and convert it to the platform's native byte order.
- *
- * \param file PhysicsFS file handle from which to read.
- * \param val pointer to where value should be stored.
- * \return zero on failure, non-zero on success. If successful, (*val) will
- * store the result. On failure, you can find out what went wrong
- * from PHYSFS_getLastError().
- *
- */
-__EXPORT__ int PHYSFS_readULE32(PHYSFS_File *file, PHYSFS_uint32 *val);
-
-
-/**
- * \fn int PHYSFS_readSBE32(PHYSFS_File *file, PHYSFS_sint32 *val)
- * \brief Read and convert a signed 32-bit bigendian value.
- *
- * Convenience function. Read a signed 32-bit bigendian value from a
- * file and convert it to the platform's native byte order.
- *
- * \param file PhysicsFS file handle from which to read.
- * \param val pointer to where value should be stored.
- * \return zero on failure, non-zero on success. If successful, (*val) will
- * store the result. On failure, you can find out what went wrong
- * from PHYSFS_getLastError().
- */
-__EXPORT__ int PHYSFS_readSBE32(PHYSFS_File *file, PHYSFS_sint32 *val);
-
-
-/**
- * \fn int PHYSFS_readUBE32(PHYSFS_File *file, PHYSFS_uint32 *val)
- * \brief Read and convert an unsigned 32-bit bigendian value.
- *
- * Convenience function. Read an unsigned 32-bit bigendian value from a
- * file and convert it to the platform's native byte order.
- *
- * \param file PhysicsFS file handle from which to read.
- * \param val pointer to where value should be stored.
- * \return zero on failure, non-zero on success. If successful, (*val) will
- * store the result. On failure, you can find out what went wrong
- * from PHYSFS_getLastError().
- *
- */
-__EXPORT__ int PHYSFS_readUBE32(PHYSFS_File *file, PHYSFS_uint32 *val);
-
-
-/**
- * \fn int PHYSFS_readSLE64(PHYSFS_File *file, PHYSFS_sint64 *val)
- * \brief Read and convert a signed 64-bit littleendian value.
- *
- * Convenience function. Read a signed 64-bit littleendian value from a
- * file and convert it to the platform's native byte order.
- *
- * \param file PhysicsFS file handle from which to read.
- * \param val pointer to where value should be stored.
- * \return zero on failure, non-zero on success. If successful, (*val) will
- * store the result. On failure, you can find out what went wrong
- * from PHYSFS_getLastError().
- *
- * \warning Remember, PHYSFS_sint64 is only 32 bits on platforms without
- * any sort of 64-bit support.
- */
-__EXPORT__ int PHYSFS_readSLE64(PHYSFS_File *file, PHYSFS_sint64 *val);
-
-
-/**
- * \fn int PHYSFS_readULE64(PHYSFS_File *file, PHYSFS_uint64 *val)
- * \brief Read and convert an unsigned 64-bit littleendian value.
- *
- * Convenience function. Read an unsigned 64-bit littleendian value from a
- * file and convert it to the platform's native byte order.
- *
- * \param file PhysicsFS file handle from which to read.
- * \param val pointer to where value should be stored.
- * \return zero on failure, non-zero on success. If successful, (*val) will
- * store the result. On failure, you can find out what went wrong
- * from PHYSFS_getLastError().
- *
- * \warning Remember, PHYSFS_uint64 is only 32 bits on platforms without
- * any sort of 64-bit support.
- */
-__EXPORT__ int PHYSFS_readULE64(PHYSFS_File *file, PHYSFS_uint64 *val);
-
-
-/**
- * \fn int PHYSFS_readSBE64(PHYSFS_File *file, PHYSFS_sint64 *val)
- * \brief Read and convert a signed 64-bit bigendian value.
- *
- * Convenience function. Read a signed 64-bit bigendian value from a
- * file and convert it to the platform's native byte order.
- *
- * \param file PhysicsFS file handle from which to read.
- * \param val pointer to where value should be stored.
- * \return zero on failure, non-zero on success. If successful, (*val) will
- * store the result. On failure, you can find out what went wrong
- * from PHYSFS_getLastError().
- *
- * \warning Remember, PHYSFS_sint64 is only 32 bits on platforms without
- * any sort of 64-bit support.
- */
-__EXPORT__ int PHYSFS_readSBE64(PHYSFS_File *file, PHYSFS_sint64 *val);
-
-
-/**
- * \fn int PHYSFS_readUBE64(PHYSFS_File *file, PHYSFS_uint64 *val)
- * \brief Read and convert an unsigned 64-bit bigendian value.
- *
- * Convenience function. Read an unsigned 64-bit bigendian value from a
- * file and convert it to the platform's native byte order.
- *
- * \param file PhysicsFS file handle from which to read.
- * \param val pointer to where value should be stored.
- * \return zero on failure, non-zero on success. If successful, (*val) will
- * store the result. On failure, you can find out what went wrong
- * from PHYSFS_getLastError().
- *
- * \warning Remember, PHYSFS_uint64 is only 32 bits on platforms without
- * any sort of 64-bit support.
- */
-__EXPORT__ int PHYSFS_readUBE64(PHYSFS_File *file, PHYSFS_uint64 *val);
-
-
-/**
- * \fn int PHYSFS_writeSLE16(PHYSFS_File *file, PHYSFS_sint16 val)
- * \brief Convert and write a signed 16-bit littleendian value.
- *
- * Convenience function. Convert a signed 16-bit value from the platform's
- * native byte order to littleendian and write it to a file.
- *
- * \param file PhysicsFS file handle to which to write.
- * \param val Value to convert and write.
- * \return zero on failure, non-zero on success. On failure, you can
- * find out what went wrong from PHYSFS_getLastError().
- */
-__EXPORT__ int PHYSFS_writeSLE16(PHYSFS_File *file, PHYSFS_sint16 val);
-
-
-/**
- * \fn int PHYSFS_writeULE16(PHYSFS_File *file, PHYSFS_uint16 val)
- * \brief Convert and write an unsigned 16-bit littleendian value.
- *
- * Convenience function. Convert an unsigned 16-bit value from the platform's
- * native byte order to littleendian and write it to a file.
- *
- * \param file PhysicsFS file handle to which to write.
- * \param val Value to convert and write.
- * \return zero on failure, non-zero on success. On failure, you can
- * find out what went wrong from PHYSFS_getLastError().
- */
-__EXPORT__ int PHYSFS_writeULE16(PHYSFS_File *file, PHYSFS_uint16 val);
-
-
-/**
- * \fn int PHYSFS_writeSBE16(PHYSFS_File *file, PHYSFS_sint16 val)
- * \brief Convert and write a signed 16-bit bigendian value.
- *
- * Convenience function. Convert a signed 16-bit value from the platform's
- * native byte order to bigendian and write it to a file.
- *
- * \param file PhysicsFS file handle to which to write.
- * \param val Value to convert and write.
- * \return zero on failure, non-zero on success. On failure, you can
- * find out what went wrong from PHYSFS_getLastError().
- */
-__EXPORT__ int PHYSFS_writeSBE16(PHYSFS_File *file, PHYSFS_sint16 val);
-
-
-/**
- * \fn int PHYSFS_writeUBE16(PHYSFS_File *file, PHYSFS_uint16 val)
- * \brief Convert and write an unsigned 16-bit bigendian value.
- *
- * Convenience function. Convert an unsigned 16-bit value from the platform's
- * native byte order to bigendian and write it to a file.
- *
- * \param file PhysicsFS file handle to which to write.
- * \param val Value to convert and write.
- * \return zero on failure, non-zero on success. On failure, you can
- * find out what went wrong from PHYSFS_getLastError().
- */
-__EXPORT__ int PHYSFS_writeUBE16(PHYSFS_File *file, PHYSFS_uint16 val);
-
-
-/**
- * \fn int PHYSFS_writeSLE32(PHYSFS_File *file, PHYSFS_sint32 val)
- * \brief Convert and write a signed 32-bit littleendian value.
- *
- * Convenience function. Convert a signed 32-bit value from the platform's
- * native byte order to littleendian and write it to a file.
- *
- * \param file PhysicsFS file handle to which to write.
- * \param val Value to convert and write.
- * \return zero on failure, non-zero on success. On failure, you can
- * find out what went wrong from PHYSFS_getLastError().
- */
-__EXPORT__ int PHYSFS_writeSLE32(PHYSFS_File *file, PHYSFS_sint32 val);
-
-
-/**
- * \fn int PHYSFS_writeULE32(PHYSFS_File *file, PHYSFS_uint32 val)
- * \brief Convert and write an unsigned 32-bit littleendian value.
- *
- * Convenience function. Convert an unsigned 32-bit value from the platform's
- * native byte order to littleendian and write it to a file.
- *
- * \param file PhysicsFS file handle to which to write.
- * \param val Value to convert and write.
- * \return zero on failure, non-zero on success. On failure, you can
- * find out what went wrong from PHYSFS_getLastError().
- */
-__EXPORT__ int PHYSFS_writeULE32(PHYSFS_File *file, PHYSFS_uint32 val);
-
-
-/**
- * \fn int PHYSFS_writeSBE32(PHYSFS_File *file, PHYSFS_sint32 val)
- * \brief Convert and write a signed 32-bit bigendian value.
- *
- * Convenience function. Convert a signed 32-bit value from the platform's
- * native byte order to bigendian and write it to a file.
- *
- * \param file PhysicsFS file handle to which to write.
- * \param val Value to convert and write.
- * \return zero on failure, non-zero on success. On failure, you can
- * find out what went wrong from PHYSFS_getLastError().
- */
-__EXPORT__ int PHYSFS_writeSBE32(PHYSFS_File *file, PHYSFS_sint32 val);
-
-
-/**
- * \fn int PHYSFS_writeUBE32(PHYSFS_File *file, PHYSFS_uint32 val)
- * \brief Convert and write an unsigned 32-bit bigendian value.
- *
- * Convenience function. Convert an unsigned 32-bit value from the platform's
- * native byte order to bigendian and write it to a file.
- *
- * \param file PhysicsFS file handle to which to write.
- * \param val Value to convert and write.
- * \return zero on failure, non-zero on success. On failure, you can
- * find out what went wrong from PHYSFS_getLastError().
- */
-__EXPORT__ int PHYSFS_writeUBE32(PHYSFS_File *file, PHYSFS_uint32 val);
-
-
-/**
- * \fn int PHYSFS_writeSLE64(PHYSFS_File *file, PHYSFS_sint64 val)
- * \brief Convert and write a signed 64-bit littleendian value.
- *
- * Convenience function. Convert a signed 64-bit value from the platform's
- * native byte order to littleendian and write it to a file.
- *
- * \param file PhysicsFS file handle to which to write.
- * \param val Value to convert and write.
- * \return zero on failure, non-zero on success. On failure, you can
- * find out what went wrong from PHYSFS_getLastError().
- *
- * \warning Remember, PHYSFS_uint64 is only 32 bits on platforms without
- * any sort of 64-bit support.
- */
-__EXPORT__ int PHYSFS_writeSLE64(PHYSFS_File *file, PHYSFS_sint64 val);
-
-
-/**
- * \fn int PHYSFS_writeULE64(PHYSFS_File *file, PHYSFS_uint64 val)
- * \brief Convert and write an unsigned 64-bit littleendian value.
- *
- * Convenience function. Convert an unsigned 64-bit value from the platform's
- * native byte order to littleendian and write it to a file.
- *
- * \param file PhysicsFS file handle to which to write.
- * \param val Value to convert and write.
- * \return zero on failure, non-zero on success. On failure, you can
- * find out what went wrong from PHYSFS_getLastError().
- *
- * \warning Remember, PHYSFS_uint64 is only 32 bits on platforms without
- * any sort of 64-bit support.
- */
-__EXPORT__ int PHYSFS_writeULE64(PHYSFS_File *file, PHYSFS_uint64 val);
-
-
-/**
- * \fn int PHYSFS_writeSBE64(PHYSFS_File *file, PHYSFS_sint64 val)
- * \brief Convert and write a signed 64-bit bigending value.
- *
- * Convenience function. Convert a signed 64-bit value from the platform's
- * native byte order to bigendian and write it to a file.
- *
- * \param file PhysicsFS file handle to which to write.
- * \param val Value to convert and write.
- * \return zero on failure, non-zero on success. On failure, you can
- * find out what went wrong from PHYSFS_getLastError().
- *
- * \warning Remember, PHYSFS_uint64 is only 32 bits on platforms without
- * any sort of 64-bit support.
- */
-__EXPORT__ int PHYSFS_writeSBE64(PHYSFS_File *file, PHYSFS_sint64 val);
-
-
-/**
- * \fn int PHYSFS_writeUBE64(PHYSFS_File *file, PHYSFS_uint64 val)
- * \brief Convert and write an unsigned 64-bit bigendian value.
- *
- * Convenience function. Convert an unsigned 64-bit value from the platform's
- * native byte order to bigendian and write it to a file.
- *
- * \param file PhysicsFS file handle to which to write.
- * \param val Value to convert and write.
- * \return zero on failure, non-zero on success. On failure, you can
- * find out what went wrong from PHYSFS_getLastError().
- *
- * \warning Remember, PHYSFS_uint64 is only 32 bits on platforms without
- * any sort of 64-bit support.
- */
-__EXPORT__ int PHYSFS_writeUBE64(PHYSFS_File *file, PHYSFS_uint64 val);
-
-
-/* Everything above this line is part of the PhysicsFS 1.0 API. */
-
-/**
- * \fn int PHYSFS_isInit(void)
- * \brief Determine if the PhysicsFS library is initialized.
- *
- * Once PHYSFS_init() returns successfully, this will return non-zero.
- * Before a successful PHYSFS_init() and after PHYSFS_deinit() returns
- * successfully, this will return zero. This function is safe to call at
- * any time.
- *
- * \return non-zero if library is initialized, zero if library is not.
- *
- * \sa PHYSFS_init
- * \sa PHYSFS_deinit
- */
-__EXPORT__ int PHYSFS_isInit(void);
-
-
-/**
- * \fn int PHYSFS_symbolicLinksPermitted(void)
- * \brief Determine if the symbolic links are permitted.
- *
- * This reports the setting from the last call to PHYSFS_permitSymbolicLinks().
- * If PHYSFS_permitSymbolicLinks() hasn't been called since the library was
- * last initialized, symbolic links are implicitly disabled.
- *
- * \return non-zero if symlinks are permitted, zero if not.
- *
- * \sa PHYSFS_permitSymbolicLinks
- */
-__EXPORT__ int PHYSFS_symbolicLinksPermitted(void);
-
-
-/**
- * \struct PHYSFS_Allocator
- * \brief PhysicsFS allocation function pointers.
- *
- * (This is for limited, hardcore use. If you don't immediately see a need
- * for it, you can probably ignore this forever.)
- *
- * You create one of these structures for use with PHYSFS_setAllocator.
- * Allocators are assumed to be reentrant by the caller; please mutex
- * accordingly.
- *
- * Allocations are always discussed in 64-bits, for future expansion...we're
- * on the cusp of a 64-bit transition, and we'll probably be allocating 6
- * gigabytes like it's nothing sooner or later, and I don't want to change
- * this again at that point. If you're on a 32-bit platform and have to
- * downcast, it's okay to return NULL if the allocation is greater than
- * 4 gigabytes, since you'd have to do so anyhow.
- *
- * \sa PHYSFS_setAllocator
- */
-typedef struct
-{
- int (*Init)(void); /**< Initialize. Can be NULL. Zero on failure. */
- void (*Deinit)(void); /**< Deinitialize your allocator. Can be NULL. */
- void *(*Malloc)(PHYSFS_uint64); /**< Allocate like malloc(). */
- void *(*Realloc)(void *, PHYSFS_uint64); /**< Reallocate like realloc(). */
- void (*Free)(void *); /**< Free memory from Malloc or Realloc. */
-} PHYSFS_Allocator;
-
-
-/**
- * \fn int PHYSFS_setAllocator(const PHYSFS_Allocator *allocator)
- * \brief Hook your own allocation routines into PhysicsFS.
- *
- * (This is for limited, hardcore use. If you don't immediately see a need
- * for it, you can probably ignore this forever.)
- *
- * By default, PhysicsFS will use whatever is reasonable for a platform
- * to manage dynamic memory (usually ANSI C malloc/realloc/calloc/free, but
- * some platforms might use something else), but in some uncommon cases, the
- * app might want more control over the library's memory management. This
- * lets you redirect PhysicsFS to use your own allocation routines instead.
- * You can only call this function before PHYSFS_init(); if the library is
- * initialized, it'll reject your efforts to change the allocator mid-stream.
- * You may call this function after PHYSFS_deinit() if you are willing to
- * shut down the library and restart it with a new allocator; this is a safe
- * and supported operation. The allocator remains intact between deinit/init
- * calls. If you want to return to the platform's default allocator, pass a
- * NULL in here.
- *
- * If you aren't immediately sure what to do with this function, you can
- * safely ignore it altogether.
- *
- * \param allocator Structure containing your allocator's entry points.
- * \return zero on failure, non-zero on success. This call only fails
- * when used between PHYSFS_init() and PHYSFS_deinit() calls.
- */
-__EXPORT__ int PHYSFS_setAllocator(const PHYSFS_Allocator *allocator);
-
-
-/**
- * \fn int PHYSFS_mount(const char *newDir, const char *mountPoint, int appendToPath)
- * \brief Add an archive or directory to the search path.
- *
- * If this is a duplicate, the entry is not added again, even though the
- * function succeeds. You may not add the same archive to two different
- * mountpoints: duplicate checking is done against the archive and not the
- * mountpoint.
- *
- * When you mount an archive, it is added to a virtual file system...all files
- * in all of the archives are interpolated into a single hierachical file
- * tree. Two archives mounted at the same place (or an archive with files
- * overlapping another mountpoint) may have overlapping files: in such a case,
- * the file earliest in the search path is selected, and the other files are
- * inaccessible to the application. This allows archives to be used to
- * override previous revisions; you can use the mounting mechanism to place
- * archives at a specific point in the file tree and prevent overlap; this
- * is useful for downloadable mods that might trample over application data
- * or each other, for example.
- *
- * The mountpoint does not need to exist prior to mounting, which is different
- * than those familiar with the Unix concept of "mounting" may not expect.
- * As well, more than one archive can be mounted to the same mountpoint, or
- * mountpoints and archive contents can overlap...the interpolation mechanism
- * still functions as usual.
- *
- * \param newDir directory or archive to add to the path, in
- * platform-dependent notation.
- * \param mountPoint Location in the interpolated tree that this archive
- * will be "mounted", in platform-independent notation.
- * NULL or "" is equivalent to "/".
- * \param appendToPath nonzero to append to search path, zero to prepend.
- * \return nonzero if added to path, zero on failure (bogus archive, dir
- * missing, etc). Specifics of the error can be
- * gleaned from PHYSFS_getLastError().
- *
- * \sa PHYSFS_removeFromSearchPath
- * \sa PHYSFS_getSearchPath
- * \sa PHYSFS_getMountPoint
- */
-__EXPORT__ int PHYSFS_mount(const char *newDir, const char *mountPoint, int appendToPath);
-
-/**
- * \fn int PHYSFS_getMountPoint(const char *dir)
- * \brief Determine a mounted archive's mountpoint.
- *
- * You give this function the name of an archive or dir you successfully
- * added to the search path, and it reports the location in the interpolated
- * tree where it is mounted. Files mounted with a NULL mountpoint or through
- * PHYSFS_addToSearchPath() will report "/". The return value is READ ONLY
- * and valid until the archive is removed from the search path.
- *
- * \param dir directory or archive previously added to the path, in
- * platform-dependent notation. This must match the string
- * used when adding, even if your string would also reference
- * the same file with a different string of characters.
- * \return READ-ONLY string of mount point if added to path, NULL on failure
- * (bogus archive, etc) Specifics of the error can be gleaned from
- * PHYSFS_getLastError().
- *
- * \sa PHYSFS_removeFromSearchPath
- * \sa PHYSFS_getSearchPath
- * \sa PHYSFS_getMountPoint
- */
-__EXPORT__ const char *PHYSFS_getMountPoint(const char *dir);
-
-
-/**
- * \typedef PHYSFS_StringCallback
- * \brief Function signature for callbacks that report strings.
- *
- * These are used to report a list of strings to an original caller, one
- * string per callback. All strings are UTF-8 encoded. Functions should not
- * try to modify or free the string's memory.
- *
- * These callbacks are used, starting in PhysicsFS 1.1, as an alternative to
- * functions that would return lists that need to be cleaned up with
- * PHYSFS_freeList(). The callback means that the library doesn't need to
- * allocate an entire list and all the strings up front.
- *
- * Be aware that promises data ordering in the list versions are not
- * necessarily so in the callback versions. Check the documentation on
- * specific APIs, but strings may not be sorted as you expect.
- *
- * \param data User-defined data pointer, passed through from the API
- * that eventually called the callback.
- * \param str The string data about which the callback is meant to inform.
- *
- * \sa PHYSFS_getCdRomDirsCallback
- * \sa PHYSFS_getSearchPathCallback
- */
-typedef void (*PHYSFS_StringCallback)(void *data, const char *str);
-
-
-/**
- * \typedef PHYSFS_EnumFilesCallback
- * \brief Function signature for callbacks that enumerate files.
- *
- * These are used to report a list of directory entries to an original caller,
- * one file/dir/symlink per callback. All strings are UTF-8 encoded.
- * Functions should not try to modify or free any string's memory.
- *
- * These callbacks are used, starting in PhysicsFS 1.1, as an alternative to
- * functions that would return lists that need to be cleaned up with
- * PHYSFS_freeList(). The callback means that the library doesn't need to
- * allocate an entire list and all the strings up front.
- *
- * Be aware that promises data ordering in the list versions are not
- * necessarily so in the callback versions. Check the documentation on
- * specific APIs, but strings may not be sorted as you expect.
- *
- * \param data User-defined data pointer, passed through from the API
- * that eventually called the callback.
- * \param origdir A string containing the full path, in platform-independent
- * notation, of the directory containing this file. In most
- * cases, this is the directory on which you requested
- * enumeration, passed in the callback for your convenience.
- * \param fname The filename that is being enumerated. It may not be in
- * alphabetical order compared to other callbacks that have
- * fired, and it will not contain the full path. You can
- * recreate the fullpath with $origdir/$fname ... The file
- * can be a subdirectory, a file, a symlink, etc.
- *
- * \sa PHYSFS_enumerateFilesCallback
- */
-typedef void (*PHYSFS_EnumFilesCallback)(void *data, const char *origdir,
- const char *fname);
-
-
-/**
- * \fn void PHYSFS_getCdRomDirsCallback(PHYSFS_StringCallback c, void *d)
- * \brief Enumerate CD-ROM directories, using an application-defined callback.
- *
- * Internally, PHYSFS_getCdRomDirs() just calls this function and then builds
- * a list before returning to the application, so functionality is identical
- * except for how the information is represented to the application.
- *
- * Unlike PHYSFS_getCdRomDirs(), this function does not return an array.
- * Rather, it calls a function specified by the application once per
- * detected disc:
- *
- * \code
- *
- * static void foundDisc(void *data, const char *cddir)
- * {
- * printf("cdrom dir [%s] is available.\n", cddir);
- * }
- *
- * // ...
- * PHYSFS_getCdRomDirsCallback(foundDisc, NULL);
- * \endcode
- *
- * This call may block while drives spin up. Be forewarned.
- *
- * \param c Callback function to notify about detected drives.
- * \param d Application-defined data passed to callback. Can be NULL.
- *
- * \sa PHYSFS_StringCallback
- * \sa PHYSFS_getCdRomDirs
- */
-__EXPORT__ void PHYSFS_getCdRomDirsCallback(PHYSFS_StringCallback c, void *d);
-
-
-/**
- * \fn void PHYSFS_getSearchPathCallback(PHYSFS_StringCallback c, void *d)
- * \brief Enumerate the search path, using an application-defined callback.
- *
- * Internally, PHYSFS_getSearchPath() just calls this function and then builds
- * a list before returning to the application, so functionality is identical
- * except for how the information is represented to the application.
- *
- * Unlike PHYSFS_getSearchPath(), this function does not return an array.
- * Rather, it calls a function specified by the application once per
- * element of the search path:
- *
- * \code
- *
- * static void printSearchPath(void *data, const char *pathItem)
- * {
- * printf("[%s] is in the search path.\n", pathItem);
- * }
- *
- * // ...
- * PHYSFS_getSearchPathCallback(printSearchPath, NULL);
- * \endcode
- *
- * Elements of the search path are reported in order search priority, so the
- * first archive/dir that would be examined when looking for a file is the
- * first element passed through the callback.
- *
- * \param c Callback function to notify about search path elements.
- * \param d Application-defined data passed to callback. Can be NULL.
- *
- * \sa PHYSFS_StringCallback
- * \sa PHYSFS_getSearchPath
- */
-__EXPORT__ void PHYSFS_getSearchPathCallback(PHYSFS_StringCallback c, void *d);
-
-
-/**
- * \fn void PHYSFS_enumerateFilesCallback(const char *dir, PHYSFS_EnumFilesCallback c, void *d)
- * \brief Get a file listing of a search path's directory, using an application-defined callback.
- *
- * Internally, PHYSFS_enumerateFiles() just calls this function and then builds
- * a list before returning to the application, so functionality is identical
- * except for how the information is represented to the application.
- *
- * Unlike PHYSFS_enumerateFiles(), this function does not return an array.
- * Rather, it calls a function specified by the application once per
- * element of the search path:
- *
- * \code
- *
- * static void printDir(void *data, const char *origdir, const char *fname)
- * {
- * printf(" * We've got [%s] in [%s].\n", fname, origdir);
- * }
- *
- * // ...
- * PHYSFS_enumerateFilesCallback("/some/path", printDir, NULL);
- * \endcode
- *
- * Items sent to the callback are not guaranteed to be in any order whatsoever.
- * There is no sorting done at this level, and if you need that, you should
- * probably use PHYSFS_enumerateFiles() instead, which guarantees
- * alphabetical sorting. This form reports whatever is discovered in each
- * archive before moving on to the next. Even within one archive, we can't
- * guarantee what order it will discover data. <em>Any sorting you find in
- * these callbacks is just pure luck. Do not rely on it.</em>
- *
- * \param dir Directory, in platform-independent notation, to enumerate.
- * \param c Callback function to notify about search path elements.
- * \param d Application-defined data passed to callback. Can be NULL.
- *
- * \sa PHYSFS_EnumFilesCallback
- * \sa PHYSFS_enumerateFiles
- */
-__EXPORT__ void PHYSFS_enumerateFilesCallback(const char *dir,
- PHYSFS_EnumFilesCallback c,
- void *d);
-
-/**
- * \fn void PHYSFS_utf8FromUcs4(const PHYSFS_uint32 *src, char *dst, PHYSFS_uint64 len)
- * \brief Convert a UCS-4 string to a UTF-8 string.
- *
- * UCS-4 strings are 32-bits per character: \c wchar_t on Unix.
- *
- * To ensure that the destination buffer is large enough for the conversion,
- * please allocate a buffer that is the same size as the source buffer. UTF-8
- * never uses more than 32-bits per character, so while it may shrink a UCS-4
- * string, it will never expand it.
- *
- * Strings that don't fit in the destination buffer will be truncated, but
- * will always be null-terminated and never have an incomplete UTF-8
- * sequence at the end.
- *
- * \param src Null-terminated source string in UCS-4 format.
- * \param dst Buffer to store converted UTF-8 string.
- * \param len Size, in bytes, of destination buffer.
- */
-__EXPORT__ void PHYSFS_utf8FromUcs4(const PHYSFS_uint32 *src, char *dst,
- PHYSFS_uint64 len);
-
-/**
- * \fn void PHYSFS_utf8ToUcs4(const char *src, PHYSFS_uint32 *dst, PHYSFS_uint64 len)
- * \brief Convert a UTF-8 string to a UCS-4 string.
- *
- * UCS-4 strings are 32-bits per character: \c wchar_t on Unix.
- *
- * To ensure that the destination buffer is large enough for the conversion,
- * please allocate a buffer that is four times the size of the source buffer.
- * UTF-8 uses from one to four bytes per character, but UCS-4 always uses
- * four, so an entirely low-ASCII string will quadruple in size!
- *
- * Strings that don't fit in the destination buffer will be truncated, but
- * will always be null-terminated and never have an incomplete UCS-4
- * sequence at the end.
- *
- * \param src Null-terminated source string in UTF-8 format.
- * \param dst Buffer to store converted UCS-4 string.
- * \param len Size, in bytes, of destination buffer.
- */
-__EXPORT__ void PHYSFS_utf8ToUcs4(const char *src, PHYSFS_uint32 *dst,
- PHYSFS_uint64 len);
-
-/**
- * \fn void PHYSFS_utf8FromUcs2(const PHYSFS_uint16 *src, char *dst, PHYSFS_uint64 len)
- * \brief Convert a UCS-2 string to a UTF-8 string.
- *
- * UCS-2 strings are 16-bits per character: \c TCHAR on Windows, when building
- * with Unicode support.
- *
- * To ensure that the destination buffer is large enough for the conversion,
- * please allocate a buffer that is double the size of the source buffer.
- * UTF-8 never uses more than 32-bits per character, so while it may shrink
- * a UCS-2 string, it may also expand it.
- *
- * Strings that don't fit in the destination buffer will be truncated, but
- * will always be null-terminated and never have an incomplete UTF-8
- * sequence at the end.
- *
- * Please note that UCS-2 is not UTF-16; we do not support the "surrogate"
- * values at this time.
- *
- * \param src Null-terminated source string in UCS-2 format.
- * \param dst Buffer to store converted UTF-8 string.
- * \param len Size, in bytes, of destination buffer.
- */
-__EXPORT__ void PHYSFS_utf8FromUcs2(const PHYSFS_uint16 *src, char *dst,
- PHYSFS_uint64 len);
-
-/**
- * \fn PHYSFS_utf8ToUcs2(const char *src, PHYSFS_uint16 *dst, PHYSFS_uint64 len)
- * \brief Convert a UTF-8 string to a UCS-2 string.
- *
- * UCS-2 strings are 16-bits per character: \c TCHAR on Windows, when building
- * with Unicode support.
- *
- * To ensure that the destination buffer is large enough for the conversion,
- * please allocate a buffer that is double the size of the source buffer.
- * UTF-8 uses from one to four bytes per character, but UCS-2 always uses
- * two, so an entirely low-ASCII string will double in size!
- *
- * Strings that don't fit in the destination buffer will be truncated, but
- * will always be null-terminated and never have an incomplete UCS-2
- * sequence at the end.
- *
- * Please note that UCS-2 is not UTF-16; we do not support the "surrogate"
- * values at this time.
- *
- * \param src Null-terminated source string in UTF-8 format.
- * \param dst Buffer to store converted UCS-2 string.
- * \param len Size, in bytes, of destination buffer.
- */
-__EXPORT__ void PHYSFS_utf8ToUcs2(const char *src, PHYSFS_uint16 *dst,
- PHYSFS_uint64 len);
-
-/**
- * \fn void PHYSFS_utf8FromLatin1(const char *src, char *dst, PHYSFS_uint64 len)
- * \brief Convert a UTF-8 string to a Latin1 string.
- *
- * Latin1 strings are 8-bits per character: a popular "high ASCII"
- * encoding.
- *
- * To ensure that the destination buffer is large enough for the conversion,
- * please allocate a buffer that is double the size of the source buffer.
- * UTF-8 expands latin1 codepoints over 127 from 1 to 2 bytes, so the string
- * may grow in some cases.
- *
- * Strings that don't fit in the destination buffer will be truncated, but
- * will always be null-terminated and never have an incomplete UTF-8
- * sequence at the end.
- *
- * Please note that we do not supply a UTF-8 to Latin1 converter, since Latin1
- * can't express most Unicode codepoints. It's a legacy encoding; you should
- * be converting away from it at all times.
- *
- * \param src Null-terminated source string in Latin1 format.
- * \param dst Buffer to store converted UTF-8 string.
- * \param len Size, in bytes, of destination buffer.
- */
-__EXPORT__ void PHYSFS_utf8FromLatin1(const char *src, char *dst,
- PHYSFS_uint64 len);
-
-/* Everything above this line is part of the PhysicsFS 2.0 API. */
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* !defined _INCLUDE_PHYSFS_H_ */
-
-/* end of physfs.h ... */
-
+++ /dev/null
-%define version @VERSION@
-%define release 1
-%define name physfs
-%define prefix /usr
-
-Summary: PhysicsFS file abstraction layer for games
-Name: %{name}
-Version: %{version}
-Release: %{release}
-Prefix: %{prefix}
-Copyright: zlib license
-Group: System Environment/Libraries
-URL: http://www.icculus/physfs/
-Source: physfs-%{version}.tar.gz
-BuildRoot: %{_tmppath}/%{name}-%{version}
-BuildRequires: doxygen, readline-devel, ncurses-devel
-Requires: readline, ncurses, zlib
-
-%description
-PhysicsFS is a library to provide abstract access to various archives.
-It is intended for use in video games, and the design was somewhat inspired
-by Quake 3's file subsystem. The programmer defines a "write directory" on
-the physical filesystem. No file writing done through the PhysicsFS API can
-leave that write directory, for security. For example, an embedded scripting
-language cannot write outside of this path if it uses PhysFS for all of its
-I/O, which means that untrusted scripts can run more safely. Symbolic links
-can be disabled as well, for added safety. For file reading, the programmer
-lists directories and archives that form a "search path". Once the search
-path is defined, it becomes a single, transparent hierarchical filesystem.
-This makes for easy access to ZIP files in the same way as you access a file
-directly on the disk, and it makes it easy to ship a new archive that will
-override a previous archive on a per-file basis. Finally, PhysicsFS gives
-you platform-abstracted means to determine if CD-ROMs are available, the
-user's home directory, where in the real filesystem your program is running,
-etc.
-
-%package devel
-Summary: Development headers, libraries, and documentation for PhysicsFS
-Group: Development/Libraries
-Requires: %{name} = %{version}
-
-%description devel
-PhysicsFS is a library to provide abstract access to various archives.
-This package contains the development headers, libraries, and documentaion to
-build programs using PhysicsFS.
-
-%prep
-%setup
-export CFLAGS="${RPM_OPT_FLAGS}" CXXFLAGS="${RPM_OPT_FLAGS}";
-./configure --prefix=/usr
-
-%build
-export CFLAGS="${RPM_OPT_FLAGS}" CXXFLAGS="${RPM_OPT_FLAGS}";
-make
-# Make doxygen docs
-doxygen
-
-%install
-[ -d ${RPM_BUILD_ROOT} ] && rm -rf ${RPM_BUILD_ROOT}
-make DESTDIR=${RPM_BUILD_ROOT} install
-
-%clean
-[ -d ${RPM_BUILD_ROOT} ] && rm -rf ${RPM_BUILD_ROOT}
-
-%post -p /sbin/ldconfig
-%postun -p /sbin/ldconfig
-
-%files
-%defattr(-,root,root)
-%doc CHANGELOG.txt CREDITS.txt INSTALL.txt LICENSE.txt TODO.txt
-%{_bindir}/test_physfs
-%{_libdir}/*so.*
-
-%files devel
-%defattr(-,root,root)
-%doc docs/*
-%{_libdir}/*.so
-%{_includedir}/physfs.h
-
-%changelog
-* Sun Mar 11 2007 Ryan C. Gordon <icculus@icculus.org>
-- Updated filenames in documents.
-
-* Thu Dec 18 2002 Edward Rudd <eddie@omegaware.com>
-- added zlib_license_change.txt to documents
-
-* Wed Jul 10 2002 Edward Rudd <eddie@omegaware.com>
-- added doxygen to build requirements
-
-* Wed Jul 10 2002 Edward Rudd <eddie@omegaware.com>
-- updated to release 0.17
-
-* Tue May 15 2002 Edward Rudd <eddie@omegaware.com>
-- updated to latest CVS and modified spec file to use
- the autoconf/automake support in the latest CVS
-
-* Tue Apr 30 2002 Edward Rudd <eddie@omegaware.com>
-- Initial spec file
-
+++ /dev/null
-/**
- * PhysicsFS; a portable, flexible file i/o abstraction.
- *
- * Documentation is in physfs.h. It's verbose, honest. :)
- *
- * Please see the file LICENSE.txt in the source's root directory.
- *
- * This file written by Ryan C. Gordon.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-
-#define __PHYSICSFS_INTERNAL__
-#include "physfs_internal.h"
-
-/* The macros used to swap values */
-/* Try to use superfast macros on systems that support them */
-#ifdef linux
-#include <asm/byteorder.h>
-#ifdef __arch__swab16
-#define PHYSFS_Swap16 __arch__swab16
-#endif
-#ifdef __arch__swab32
-#define PHYSFS_Swap32 __arch__swab32
-#endif
-#endif /* linux */
-
-#if (defined macintosh) && !(defined __MWERKS__)
-#define __inline__
-#endif
-
-#if (defined _MSC_VER)
-#define __inline__ __inline
-#endif
-
-#ifndef PHYSFS_Swap16
-static __inline__ PHYSFS_uint16 PHYSFS_Swap16(PHYSFS_uint16 D)
-{
- return((D<<8)|(D>>8));
-}
-#endif
-#ifndef PHYSFS_Swap32
-static __inline__ PHYSFS_uint32 PHYSFS_Swap32(PHYSFS_uint32 D)
-{
- return((D<<24)|((D<<8)&0x00FF0000)|((D>>8)&0x0000FF00)|(D>>24));
-}
-#endif
-#ifndef PHYSFS_NO_64BIT_SUPPORT
-#ifndef PHYSFS_Swap64
-static __inline__ PHYSFS_uint64 PHYSFS_Swap64(PHYSFS_uint64 val) {
- PHYSFS_uint32 hi, lo;
-
- /* Separate into high and low 32-bit values and swap them */
- lo = (PHYSFS_uint32)(val&0xFFFFFFFF);
- val >>= 32;
- hi = (PHYSFS_uint32)(val&0xFFFFFFFF);
- val = PHYSFS_Swap32(lo);
- val <<= 32;
- val |= PHYSFS_Swap32(hi);
- return(val);
-}
-#endif
-#else
-#ifndef PHYSFS_Swap64
-/* This is mainly to keep compilers from complaining in PHYSFS code.
- If there is no real 64-bit datatype, then compilers will complain about
- the fake 64-bit datatype that PHYSFS provides when it compiles user code.
-*/
-#define PHYSFS_Swap64(X) (X)
-#endif
-#endif /* PHYSFS_NO_64BIT_SUPPORT */
-
-
-/* Byteswap item from the specified endianness to the native endianness */
-#if PHYSFS_BYTEORDER == PHYSFS_LIL_ENDIAN
-PHYSFS_uint16 PHYSFS_swapULE16(PHYSFS_uint16 x) { return(x); }
-PHYSFS_sint16 PHYSFS_swapSLE16(PHYSFS_sint16 x) { return(x); }
-PHYSFS_uint32 PHYSFS_swapULE32(PHYSFS_uint32 x) { return(x); }
-PHYSFS_sint32 PHYSFS_swapSLE32(PHYSFS_sint32 x) { return(x); }
-PHYSFS_uint64 PHYSFS_swapULE64(PHYSFS_uint64 x) { return(x); }
-PHYSFS_sint64 PHYSFS_swapSLE64(PHYSFS_sint64 x) { return(x); }
-
-PHYSFS_uint16 PHYSFS_swapUBE16(PHYSFS_uint16 x) { return(PHYSFS_Swap16(x)); }
-PHYSFS_sint16 PHYSFS_swapSBE16(PHYSFS_sint16 x) { return(PHYSFS_Swap16(x)); }
-PHYSFS_uint32 PHYSFS_swapUBE32(PHYSFS_uint32 x) { return(PHYSFS_Swap32(x)); }
-PHYSFS_sint32 PHYSFS_swapSBE32(PHYSFS_sint32 x) { return(PHYSFS_Swap32(x)); }
-PHYSFS_uint64 PHYSFS_swapUBE64(PHYSFS_uint64 x) { return(PHYSFS_Swap64(x)); }
-PHYSFS_sint64 PHYSFS_swapSBE64(PHYSFS_sint64 x) { return(PHYSFS_Swap64(x)); }
-#else
-PHYSFS_uint16 PHYSFS_swapULE16(PHYSFS_uint16 x) { return(PHYSFS_Swap16(x)); }
-PHYSFS_sint16 PHYSFS_swapSLE16(PHYSFS_sint16 x) { return(PHYSFS_Swap16(x)); }
-PHYSFS_uint32 PHYSFS_swapULE32(PHYSFS_uint32 x) { return(PHYSFS_Swap32(x)); }
-PHYSFS_sint32 PHYSFS_swapSLE32(PHYSFS_sint32 x) { return(PHYSFS_Swap32(x)); }
-PHYSFS_uint64 PHYSFS_swapULE64(PHYSFS_uint64 x) { return(PHYSFS_Swap64(x)); }
-PHYSFS_sint64 PHYSFS_swapSLE64(PHYSFS_sint64 x) { return(PHYSFS_Swap64(x)); }
-
-PHYSFS_uint16 PHYSFS_swapUBE16(PHYSFS_uint16 x) { return(x); }
-PHYSFS_sint16 PHYSFS_swapSBE16(PHYSFS_sint16 x) { return(x); }
-PHYSFS_uint32 PHYSFS_swapUBE32(PHYSFS_uint32 x) { return(x); }
-PHYSFS_sint32 PHYSFS_swapSBE32(PHYSFS_sint32 x) { return(x); }
-PHYSFS_uint64 PHYSFS_swapUBE64(PHYSFS_uint64 x) { return(x); }
-PHYSFS_sint64 PHYSFS_swapSBE64(PHYSFS_sint64 x) { return(x); }
-#endif
-
-
-int PHYSFS_readSLE16(PHYSFS_File *file, PHYSFS_sint16 *val)
-{
- PHYSFS_sint16 in;
- BAIL_IF_MACRO(val == NULL, ERR_INVALID_ARGUMENT, 0);
- BAIL_IF_MACRO(PHYSFS_read(file, &in, sizeof (in), 1) != 1, NULL, 0);
- *val = PHYSFS_swapSLE16(in);
- return(1);
-} /* PHYSFS_readSLE16 */
-
-
-int PHYSFS_readULE16(PHYSFS_File *file, PHYSFS_uint16 *val)
-{
- PHYSFS_uint16 in;
- BAIL_IF_MACRO(val == NULL, ERR_INVALID_ARGUMENT, 0);
- BAIL_IF_MACRO(PHYSFS_read(file, &in, sizeof (in), 1) != 1, NULL, 0);
- *val = PHYSFS_swapULE16(in);
- return(1);
-} /* PHYSFS_readULE16 */
-
-
-int PHYSFS_readSBE16(PHYSFS_File *file, PHYSFS_sint16 *val)
-{
- PHYSFS_sint16 in;
- BAIL_IF_MACRO(val == NULL, ERR_INVALID_ARGUMENT, 0);
- BAIL_IF_MACRO(PHYSFS_read(file, &in, sizeof (in), 1) != 1, NULL, 0);
- *val = PHYSFS_swapSBE16(in);
- return(1);
-} /* PHYSFS_readSBE16 */
-
-
-int PHYSFS_readUBE16(PHYSFS_File *file, PHYSFS_uint16 *val)
-{
- PHYSFS_uint16 in;
- BAIL_IF_MACRO(val == NULL, ERR_INVALID_ARGUMENT, 0);
- BAIL_IF_MACRO(PHYSFS_read(file, &in, sizeof (in), 1) != 1, NULL, 0);
- *val = PHYSFS_swapUBE16(in);
- return(1);
-} /* PHYSFS_readUBE16 */
-
-
-int PHYSFS_readSLE32(PHYSFS_File *file, PHYSFS_sint32 *val)
-{
- PHYSFS_sint32 in;
- BAIL_IF_MACRO(val == NULL, ERR_INVALID_ARGUMENT, 0);
- BAIL_IF_MACRO(PHYSFS_read(file, &in, sizeof (in), 1) != 1, NULL, 0);
- *val = PHYSFS_swapSLE32(in);
- return(1);
-} /* PHYSFS_readSLE32 */
-
-
-int PHYSFS_readULE32(PHYSFS_File *file, PHYSFS_uint32 *val)
-{
- PHYSFS_uint32 in;
- BAIL_IF_MACRO(val == NULL, ERR_INVALID_ARGUMENT, 0);
- BAIL_IF_MACRO(PHYSFS_read(file, &in, sizeof (in), 1) != 1, NULL, 0);
- *val = PHYSFS_swapULE32(in);
- return(1);
-} /* PHYSFS_readULE32 */
-
-
-int PHYSFS_readSBE32(PHYSFS_File *file, PHYSFS_sint32 *val)
-{
- PHYSFS_sint32 in;
- BAIL_IF_MACRO(val == NULL, ERR_INVALID_ARGUMENT, 0);
- BAIL_IF_MACRO(PHYSFS_read(file, &in, sizeof (in), 1) != 1, NULL, 0);
- *val = PHYSFS_swapSBE32(in);
- return(1);
-} /* PHYSFS_readSBE32 */
-
-
-int PHYSFS_readUBE32(PHYSFS_File *file, PHYSFS_uint32 *val)
-{
- PHYSFS_uint32 in;
- BAIL_IF_MACRO(val == NULL, ERR_INVALID_ARGUMENT, 0);
- BAIL_IF_MACRO(PHYSFS_read(file, &in, sizeof (in), 1) != 1, NULL, 0);
- *val = PHYSFS_swapUBE32(in);
- return(1);
-} /* PHYSFS_readUBE32 */
-
-
-int PHYSFS_readSLE64(PHYSFS_File *file, PHYSFS_sint64 *val)
-{
- PHYSFS_sint64 in;
- BAIL_IF_MACRO(val == NULL, ERR_INVALID_ARGUMENT, 0);
- BAIL_IF_MACRO(PHYSFS_read(file, &in, sizeof (in), 1) != 1, NULL, 0);
- *val = PHYSFS_swapSLE64(in);
- return(1);
-} /* PHYSFS_readSLE64 */
-
-
-int PHYSFS_readULE64(PHYSFS_File *file, PHYSFS_uint64 *val)
-{
- PHYSFS_uint64 in;
- BAIL_IF_MACRO(val == NULL, ERR_INVALID_ARGUMENT, 0);
- BAIL_IF_MACRO(PHYSFS_read(file, &in, sizeof (in), 1) != 1, NULL, 0);
- *val = PHYSFS_swapULE64(in);
- return(1);
-} /* PHYSFS_readULE64 */
-
-
-int PHYSFS_readSBE64(PHYSFS_File *file, PHYSFS_sint64 *val)
-{
- PHYSFS_sint64 in;
- BAIL_IF_MACRO(val == NULL, ERR_INVALID_ARGUMENT, 0);
- BAIL_IF_MACRO(PHYSFS_read(file, &in, sizeof (in), 1) != 1, NULL, 0);
- *val = PHYSFS_swapSBE64(in);
- return(1);
-} /* PHYSFS_readSBE64 */
-
-
-int PHYSFS_readUBE64(PHYSFS_File *file, PHYSFS_uint64 *val)
-{
- PHYSFS_uint64 in;
- BAIL_IF_MACRO(val == NULL, ERR_INVALID_ARGUMENT, 0);
- BAIL_IF_MACRO(PHYSFS_read(file, &in, sizeof (in), 1) != 1, NULL, 0);
- *val = PHYSFS_swapUBE64(in);
- return(1);
-} /* PHYSFS_readUBE64 */
-
-
-
-int PHYSFS_writeSLE16(PHYSFS_File *file, PHYSFS_sint16 val)
-{
- PHYSFS_sint16 out = PHYSFS_swapSLE16(val);
- BAIL_IF_MACRO(PHYSFS_write(file, &out, sizeof (out), 1) != 1, NULL, 0);
- return(1);
-} /* PHYSFS_writeSLE16 */
-
-
-int PHYSFS_writeULE16(PHYSFS_File *file, PHYSFS_uint16 val)
-{
- PHYSFS_uint16 out = PHYSFS_swapULE16(val);
- BAIL_IF_MACRO(PHYSFS_write(file, &out, sizeof (out), 1) != 1, NULL, 0);
- return(1);
-} /* PHYSFS_writeULE16 */
-
-
-int PHYSFS_writeSBE16(PHYSFS_File *file, PHYSFS_sint16 val)
-{
- PHYSFS_sint16 out = PHYSFS_swapSBE16(val);
- BAIL_IF_MACRO(PHYSFS_write(file, &out, sizeof (out), 1) != 1, NULL, 0);
- return(1);
-} /* PHYSFS_writeSBE16 */
-
-
-int PHYSFS_writeUBE16(PHYSFS_File *file, PHYSFS_uint16 val)
-{
- PHYSFS_uint16 out = PHYSFS_swapUBE16(val);
- BAIL_IF_MACRO(PHYSFS_write(file, &out, sizeof (out), 1) != 1, NULL, 0);
- return(1);
-} /* PHYSFS_writeUBE16 */
-
-
-int PHYSFS_writeSLE32(PHYSFS_File *file, PHYSFS_sint32 val)
-{
- PHYSFS_sint32 out = PHYSFS_swapSLE32(val);
- BAIL_IF_MACRO(PHYSFS_write(file, &out, sizeof (out), 1) != 1, NULL, 0);
- return(1);
-} /* PHYSFS_writeSLE32 */
-
-
-int PHYSFS_writeULE32(PHYSFS_File *file, PHYSFS_uint32 val)
-{
- PHYSFS_uint32 out = PHYSFS_swapULE32(val);
- BAIL_IF_MACRO(PHYSFS_write(file, &out, sizeof (out), 1) != 1, NULL, 0);
- return(1);
-} /* PHYSFS_writeULE32 */
-
-
-int PHYSFS_writeSBE32(PHYSFS_File *file, PHYSFS_sint32 val)
-{
- PHYSFS_sint32 out = PHYSFS_swapSBE32(val);
- BAIL_IF_MACRO(PHYSFS_write(file, &out, sizeof (out), 1) != 1, NULL, 0);
- return(1);
-} /* PHYSFS_writeSBE32 */
-
-
-int PHYSFS_writeUBE32(PHYSFS_File *file, PHYSFS_uint32 val)
-{
- PHYSFS_uint32 out = PHYSFS_swapUBE32(val);
- BAIL_IF_MACRO(PHYSFS_write(file, &out, sizeof (out), 1) != 1, NULL, 0);
- return(1);
-} /* PHYSFS_writeUBE32 */
-
-
-int PHYSFS_writeSLE64(PHYSFS_File *file, PHYSFS_sint64 val)
-{
- PHYSFS_sint64 out = PHYSFS_swapSLE64(val);
- BAIL_IF_MACRO(PHYSFS_write(file, &out, sizeof (out), 1) != 1, NULL, 0);
- return(1);
-} /* PHYSFS_writeSLE64 */
-
-
-int PHYSFS_writeULE64(PHYSFS_File *file, PHYSFS_uint64 val)
-{
- PHYSFS_uint64 out = PHYSFS_swapULE64(val);
- BAIL_IF_MACRO(PHYSFS_write(file, &out, sizeof (out), 1) != 1, NULL, 0);
- return(1);
-} /* PHYSFS_writeULE64 */
-
-
-int PHYSFS_writeSBE64(PHYSFS_File *file, PHYSFS_sint64 val)
-{
- PHYSFS_sint64 out = PHYSFS_swapSBE64(val);
- BAIL_IF_MACRO(PHYSFS_write(file, &out, sizeof (out), 1) != 1, NULL, 0);
- return(1);
-} /* PHYSFS_writeSBE64 */
-
-
-int PHYSFS_writeUBE64(PHYSFS_File *file, PHYSFS_uint64 val)
-{
- PHYSFS_uint64 out = PHYSFS_swapUBE64(val);
- BAIL_IF_MACRO(PHYSFS_write(file, &out, sizeof (out), 1) != 1, NULL, 0);
- return(1);
-} /* PHYSFS_writeUBE64 */
-
-/* end of physfs_byteorder.c ... */
-
+++ /dev/null
-/*
- * This file is part of PhysicsFS (http://icculus.org/physfs/)
- *
- * This data generated by physfs/extras/makecasefoldhashtable.pl ...
- * Do not manually edit this file!
- *
- * Please see the file LICENSE.txt in the source's root directory.
- */
-
-#ifndef __PHYSICSFS_INTERNAL__
-#error Do not include this header from your applications.
-#endif
-
-static const CaseFoldMapping case_fold_000[] = {
- { 0x0202, 0x0203, 0x0000, 0x0000 },
- { 0x0404, 0x0454, 0x0000, 0x0000 },
- { 0x1E1E, 0x1E1F, 0x0000, 0x0000 },
- { 0x2C2C, 0x2C5C, 0x0000, 0x0000 },
- { 0x10404, 0x1042C, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_001[] = {
- { 0x0100, 0x0101, 0x0000, 0x0000 },
- { 0x0405, 0x0455, 0x0000, 0x0000 },
- { 0x0504, 0x0505, 0x0000, 0x0000 },
- { 0x2C2D, 0x2C5D, 0x0000, 0x0000 },
- { 0x10405, 0x1042D, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_002[] = {
- { 0x0200, 0x0201, 0x0000, 0x0000 },
- { 0x0406, 0x0456, 0x0000, 0x0000 },
- { 0x1E1C, 0x1E1D, 0x0000, 0x0000 },
- { 0x1F1D, 0x1F15, 0x0000, 0x0000 },
- { 0x2C2E, 0x2C5E, 0x0000, 0x0000 },
- { 0x10406, 0x1042E, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_003[] = {
- { 0x0102, 0x0103, 0x0000, 0x0000 },
- { 0x0407, 0x0457, 0x0000, 0x0000 },
- { 0x0506, 0x0507, 0x0000, 0x0000 },
- { 0x1F1C, 0x1F14, 0x0000, 0x0000 },
- { 0x10407, 0x1042F, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_004[] = {
- { 0x0206, 0x0207, 0x0000, 0x0000 },
- { 0x0400, 0x0450, 0x0000, 0x0000 },
- { 0x1E1A, 0x1E1B, 0x0000, 0x0000 },
- { 0x1F1B, 0x1F13, 0x0000, 0x0000 },
- { 0x2C28, 0x2C58, 0x0000, 0x0000 },
- { 0x10400, 0x10428, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_005[] = {
- { 0x0104, 0x0105, 0x0000, 0x0000 },
- { 0x0401, 0x0451, 0x0000, 0x0000 },
- { 0x0500, 0x0501, 0x0000, 0x0000 },
- { 0x1F1A, 0x1F12, 0x0000, 0x0000 },
- { 0x2C29, 0x2C59, 0x0000, 0x0000 },
- { 0x10401, 0x10429, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_006[] = {
- { 0x0204, 0x0205, 0x0000, 0x0000 },
- { 0x0402, 0x0452, 0x0000, 0x0000 },
- { 0x1E18, 0x1E19, 0x0000, 0x0000 },
- { 0x1F19, 0x1F11, 0x0000, 0x0000 },
- { 0x2C2A, 0x2C5A, 0x0000, 0x0000 },
- { 0x10402, 0x1042A, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_007[] = {
- { 0x0106, 0x0107, 0x0000, 0x0000 },
- { 0x0403, 0x0453, 0x0000, 0x0000 },
- { 0x0502, 0x0503, 0x0000, 0x0000 },
- { 0x1F18, 0x1F10, 0x0000, 0x0000 },
- { 0x2126, 0x03C9, 0x0000, 0x0000 },
- { 0x2C2B, 0x2C5B, 0x0000, 0x0000 },
- { 0x10403, 0x1042B, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_008[] = {
- { 0x020A, 0x020B, 0x0000, 0x0000 },
- { 0x040C, 0x045C, 0x0000, 0x0000 },
- { 0x1E16, 0x1E17, 0x0000, 0x0000 },
- { 0x2C24, 0x2C54, 0x0000, 0x0000 },
- { 0x1040C, 0x10434, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_009[] = {
- { 0x0108, 0x0109, 0x0000, 0x0000 },
- { 0x040D, 0x045D, 0x0000, 0x0000 },
- { 0x050C, 0x050D, 0x0000, 0x0000 },
- { 0x2C25, 0x2C55, 0x0000, 0x0000 },
- { 0x1040D, 0x10435, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_010[] = {
- { 0x0208, 0x0209, 0x0000, 0x0000 },
- { 0x040E, 0x045E, 0x0000, 0x0000 },
- { 0x1E14, 0x1E15, 0x0000, 0x0000 },
- { 0x212B, 0x00E5, 0x0000, 0x0000 },
- { 0x2C26, 0x2C56, 0x0000, 0x0000 },
- { 0x1040E, 0x10436, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_011[] = {
- { 0x010A, 0x010B, 0x0000, 0x0000 },
- { 0x040F, 0x045F, 0x0000, 0x0000 },
- { 0x050E, 0x050F, 0x0000, 0x0000 },
- { 0x212A, 0x006B, 0x0000, 0x0000 },
- { 0x2C27, 0x2C57, 0x0000, 0x0000 },
- { 0x1040F, 0x10437, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_012[] = {
- { 0x020E, 0x020F, 0x0000, 0x0000 },
- { 0x0408, 0x0458, 0x0000, 0x0000 },
- { 0x1E12, 0x1E13, 0x0000, 0x0000 },
- { 0x2C20, 0x2C50, 0x0000, 0x0000 },
- { 0x10408, 0x10430, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_013[] = {
- { 0x010C, 0x010D, 0x0000, 0x0000 },
- { 0x0409, 0x0459, 0x0000, 0x0000 },
- { 0x0508, 0x0509, 0x0000, 0x0000 },
- { 0x2C21, 0x2C51, 0x0000, 0x0000 },
- { 0x10409, 0x10431, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_014[] = {
- { 0x020C, 0x020D, 0x0000, 0x0000 },
- { 0x040A, 0x045A, 0x0000, 0x0000 },
- { 0x1E10, 0x1E11, 0x0000, 0x0000 },
- { 0x2C22, 0x2C52, 0x0000, 0x0000 },
- { 0x1040A, 0x10432, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_015[] = {
- { 0x010E, 0x010F, 0x0000, 0x0000 },
- { 0x040B, 0x045B, 0x0000, 0x0000 },
- { 0x050A, 0x050B, 0x0000, 0x0000 },
- { 0x2C23, 0x2C53, 0x0000, 0x0000 },
- { 0x1040B, 0x10433, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_016[] = {
- { 0x0212, 0x0213, 0x0000, 0x0000 },
- { 0x0414, 0x0434, 0x0000, 0x0000 },
- { 0x1E0E, 0x1E0F, 0x0000, 0x0000 },
- { 0x1F0F, 0x1F07, 0x0000, 0x0000 },
- { 0x10414, 0x1043C, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_017[] = {
- { 0x0110, 0x0111, 0x0000, 0x0000 },
- { 0x0415, 0x0435, 0x0000, 0x0000 },
- { 0x1F0E, 0x1F06, 0x0000, 0x0000 },
- { 0x10415, 0x1043D, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_018[] = {
- { 0x0210, 0x0211, 0x0000, 0x0000 },
- { 0x0416, 0x0436, 0x0000, 0x0000 },
- { 0x1E0C, 0x1E0D, 0x0000, 0x0000 },
- { 0x1F0D, 0x1F05, 0x0000, 0x0000 },
- { 0x10416, 0x1043E, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_019[] = {
- { 0x0112, 0x0113, 0x0000, 0x0000 },
- { 0x0417, 0x0437, 0x0000, 0x0000 },
- { 0x1F0C, 0x1F04, 0x0000, 0x0000 },
- { 0x10417, 0x1043F, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_020[] = {
- { 0x0216, 0x0217, 0x0000, 0x0000 },
- { 0x0410, 0x0430, 0x0000, 0x0000 },
- { 0x1E0A, 0x1E0B, 0x0000, 0x0000 },
- { 0x1F0B, 0x1F03, 0x0000, 0x0000 },
- { 0x10410, 0x10438, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_021[] = {
- { 0x0114, 0x0115, 0x0000, 0x0000 },
- { 0x0411, 0x0431, 0x0000, 0x0000 },
- { 0x1F0A, 0x1F02, 0x0000, 0x0000 },
- { 0x10411, 0x10439, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_022[] = {
- { 0x0214, 0x0215, 0x0000, 0x0000 },
- { 0x0412, 0x0432, 0x0000, 0x0000 },
- { 0x1E08, 0x1E09, 0x0000, 0x0000 },
- { 0x1F09, 0x1F01, 0x0000, 0x0000 },
- { 0x10412, 0x1043A, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_023[] = {
- { 0x0116, 0x0117, 0x0000, 0x0000 },
- { 0x0413, 0x0433, 0x0000, 0x0000 },
- { 0x1F08, 0x1F00, 0x0000, 0x0000 },
- { 0x10413, 0x1043B, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_024[] = {
- { 0x021A, 0x021B, 0x0000, 0x0000 },
- { 0x041C, 0x043C, 0x0000, 0x0000 },
- { 0x1E06, 0x1E07, 0x0000, 0x0000 },
- { 0x1041C, 0x10444, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_025[] = {
- { 0x0118, 0x0119, 0x0000, 0x0000 },
- { 0x041D, 0x043D, 0x0000, 0x0000 },
- { 0x1041D, 0x10445, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_026[] = {
- { 0x0218, 0x0219, 0x0000, 0x0000 },
- { 0x041E, 0x043E, 0x0000, 0x0000 },
- { 0x1E04, 0x1E05, 0x0000, 0x0000 },
- { 0x1041E, 0x10446, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_027[] = {
- { 0x011A, 0x011B, 0x0000, 0x0000 },
- { 0x041F, 0x043F, 0x0000, 0x0000 },
- { 0x1041F, 0x10447, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_028[] = {
- { 0x021E, 0x021F, 0x0000, 0x0000 },
- { 0x0418, 0x0438, 0x0000, 0x0000 },
- { 0x1E02, 0x1E03, 0x0000, 0x0000 },
- { 0x10418, 0x10440, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_029[] = {
- { 0x011C, 0x011D, 0x0000, 0x0000 },
- { 0x0419, 0x0439, 0x0000, 0x0000 },
- { 0x10419, 0x10441, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_030[] = {
- { 0x021C, 0x021D, 0x0000, 0x0000 },
- { 0x041A, 0x043A, 0x0000, 0x0000 },
- { 0x1E00, 0x1E01, 0x0000, 0x0000 },
- { 0x1041A, 0x10442, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_031[] = {
- { 0x011E, 0x011F, 0x0000, 0x0000 },
- { 0x041B, 0x043B, 0x0000, 0x0000 },
- { 0x1041B, 0x10443, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_032[] = {
- { 0x0222, 0x0223, 0x0000, 0x0000 },
- { 0x0424, 0x0444, 0x0000, 0x0000 },
- { 0x1E3E, 0x1E3F, 0x0000, 0x0000 },
- { 0x1F3F, 0x1F37, 0x0000, 0x0000 },
- { 0x2C0C, 0x2C3C, 0x0000, 0x0000 },
- { 0x10424, 0x1044C, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_033[] = {
- { 0x0120, 0x0121, 0x0000, 0x0000 },
- { 0x0425, 0x0445, 0x0000, 0x0000 },
- { 0x1F3E, 0x1F36, 0x0000, 0x0000 },
- { 0x2C0D, 0x2C3D, 0x0000, 0x0000 },
- { 0x10425, 0x1044D, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_034[] = {
- { 0x0220, 0x019E, 0x0000, 0x0000 },
- { 0x0426, 0x0446, 0x0000, 0x0000 },
- { 0x1E3C, 0x1E3D, 0x0000, 0x0000 },
- { 0x1F3D, 0x1F35, 0x0000, 0x0000 },
- { 0x2C0E, 0x2C3E, 0x0000, 0x0000 },
- { 0x10426, 0x1044E, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_035[] = {
- { 0x0122, 0x0123, 0x0000, 0x0000 },
- { 0x0427, 0x0447, 0x0000, 0x0000 },
- { 0x1F3C, 0x1F34, 0x0000, 0x0000 },
- { 0x2C0F, 0x2C3F, 0x0000, 0x0000 },
- { 0x10427, 0x1044F, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_036[] = {
- { 0x0226, 0x0227, 0x0000, 0x0000 },
- { 0x0420, 0x0440, 0x0000, 0x0000 },
- { 0x1E3A, 0x1E3B, 0x0000, 0x0000 },
- { 0x1F3B, 0x1F33, 0x0000, 0x0000 },
- { 0x2C08, 0x2C38, 0x0000, 0x0000 },
- { 0x10420, 0x10448, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_037[] = {
- { 0x0124, 0x0125, 0x0000, 0x0000 },
- { 0x0421, 0x0441, 0x0000, 0x0000 },
- { 0x1F3A, 0x1F32, 0x0000, 0x0000 },
- { 0x2C09, 0x2C39, 0x0000, 0x0000 },
- { 0x10421, 0x10449, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_038[] = {
- { 0x0224, 0x0225, 0x0000, 0x0000 },
- { 0x0422, 0x0442, 0x0000, 0x0000 },
- { 0x1E38, 0x1E39, 0x0000, 0x0000 },
- { 0x1F39, 0x1F31, 0x0000, 0x0000 },
- { 0x2C0A, 0x2C3A, 0x0000, 0x0000 },
- { 0x10422, 0x1044A, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_039[] = {
- { 0x0126, 0x0127, 0x0000, 0x0000 },
- { 0x0423, 0x0443, 0x0000, 0x0000 },
- { 0x1F38, 0x1F30, 0x0000, 0x0000 },
- { 0x2C0B, 0x2C3B, 0x0000, 0x0000 },
- { 0x10423, 0x1044B, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_040[] = {
- { 0x022A, 0x022B, 0x0000, 0x0000 },
- { 0x042C, 0x044C, 0x0000, 0x0000 },
- { 0x1E36, 0x1E37, 0x0000, 0x0000 },
- { 0x2C04, 0x2C34, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_041[] = {
- { 0x0128, 0x0129, 0x0000, 0x0000 },
- { 0x042D, 0x044D, 0x0000, 0x0000 },
- { 0x2C05, 0x2C35, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_042[] = {
- { 0x0228, 0x0229, 0x0000, 0x0000 },
- { 0x042E, 0x044E, 0x0000, 0x0000 },
- { 0x1E34, 0x1E35, 0x0000, 0x0000 },
- { 0x2C06, 0x2C36, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_043[] = {
- { 0x012A, 0x012B, 0x0000, 0x0000 },
- { 0x042F, 0x044F, 0x0000, 0x0000 },
- { 0x2C07, 0x2C37, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_044[] = {
- { 0x022E, 0x022F, 0x0000, 0x0000 },
- { 0x0428, 0x0448, 0x0000, 0x0000 },
- { 0x1E32, 0x1E33, 0x0000, 0x0000 },
- { 0x2C00, 0x2C30, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_045[] = {
- { 0x012C, 0x012D, 0x0000, 0x0000 },
- { 0x0429, 0x0449, 0x0000, 0x0000 },
- { 0x2C01, 0x2C31, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_046[] = {
- { 0x022C, 0x022D, 0x0000, 0x0000 },
- { 0x042A, 0x044A, 0x0000, 0x0000 },
- { 0x1E30, 0x1E31, 0x0000, 0x0000 },
- { 0x2C02, 0x2C32, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_047[] = {
- { 0x012E, 0x012F, 0x0000, 0x0000 },
- { 0x042B, 0x044B, 0x0000, 0x0000 },
- { 0x2C03, 0x2C33, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_048[] = {
- { 0x0232, 0x0233, 0x0000, 0x0000 },
- { 0x0535, 0x0565, 0x0000, 0x0000 },
- { 0x1E2E, 0x1E2F, 0x0000, 0x0000 },
- { 0x1F2F, 0x1F27, 0x0000, 0x0000 },
- { 0x2C1C, 0x2C4C, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_049[] = {
- { 0x0130, 0x0069, 0x0307, 0x0000 },
- { 0x0534, 0x0564, 0x0000, 0x0000 },
- { 0x1F2E, 0x1F26, 0x0000, 0x0000 },
- { 0x2C1D, 0x2C4D, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_050[] = {
- { 0x0230, 0x0231, 0x0000, 0x0000 },
- { 0x0537, 0x0567, 0x0000, 0x0000 },
- { 0x1E2C, 0x1E2D, 0x0000, 0x0000 },
- { 0x1F2D, 0x1F25, 0x0000, 0x0000 },
- { 0x2C1E, 0x2C4E, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_051[] = {
- { 0x0132, 0x0133, 0x0000, 0x0000 },
- { 0x0536, 0x0566, 0x0000, 0x0000 },
- { 0x1F2C, 0x1F24, 0x0000, 0x0000 },
- { 0x2C1F, 0x2C4F, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_052[] = {
- { 0x0531, 0x0561, 0x0000, 0x0000 },
- { 0x1E2A, 0x1E2B, 0x0000, 0x0000 },
- { 0x1F2B, 0x1F23, 0x0000, 0x0000 },
- { 0x2C18, 0x2C48, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_053[] = {
- { 0x0134, 0x0135, 0x0000, 0x0000 },
- { 0x1F2A, 0x1F22, 0x0000, 0x0000 },
- { 0x2C19, 0x2C49, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_054[] = {
- { 0x0533, 0x0563, 0x0000, 0x0000 },
- { 0x1E28, 0x1E29, 0x0000, 0x0000 },
- { 0x1F29, 0x1F21, 0x0000, 0x0000 },
- { 0x2C1A, 0x2C4A, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_055[] = {
- { 0x0136, 0x0137, 0x0000, 0x0000 },
- { 0x0532, 0x0562, 0x0000, 0x0000 },
- { 0x1F28, 0x1F20, 0x0000, 0x0000 },
- { 0x2C1B, 0x2C4B, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_056[] = {
- { 0x0139, 0x013A, 0x0000, 0x0000 },
- { 0x053D, 0x056D, 0x0000, 0x0000 },
- { 0x1E26, 0x1E27, 0x0000, 0x0000 },
- { 0x2C14, 0x2C44, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_057[] = {
- { 0x023B, 0x023C, 0x0000, 0x0000 },
- { 0x053C, 0x056C, 0x0000, 0x0000 },
- { 0x2C15, 0x2C45, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_058[] = {
- { 0x013B, 0x013C, 0x0000, 0x0000 },
- { 0x053F, 0x056F, 0x0000, 0x0000 },
- { 0x1E24, 0x1E25, 0x0000, 0x0000 },
- { 0x2C16, 0x2C46, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_059[] = {
- { 0x053E, 0x056E, 0x0000, 0x0000 },
- { 0x2C17, 0x2C47, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_060[] = {
- { 0x013D, 0x013E, 0x0000, 0x0000 },
- { 0x0539, 0x0569, 0x0000, 0x0000 },
- { 0x1E22, 0x1E23, 0x0000, 0x0000 },
- { 0x2C10, 0x2C40, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_061[] = {
- { 0x0538, 0x0568, 0x0000, 0x0000 },
- { 0x2C11, 0x2C41, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_062[] = {
- { 0x013F, 0x0140, 0x0000, 0x0000 },
- { 0x053B, 0x056B, 0x0000, 0x0000 },
- { 0x1E20, 0x1E21, 0x0000, 0x0000 },
- { 0x2C12, 0x2C42, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_063[] = {
- { 0x023D, 0x019A, 0x0000, 0x0000 },
- { 0x053A, 0x056A, 0x0000, 0x0000 },
- { 0x2C13, 0x2C43, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_064[] = {
- { 0x0141, 0x0142, 0x0000, 0x0000 },
- { 0x0545, 0x0575, 0x0000, 0x0000 },
- { 0x1E5E, 0x1E5F, 0x0000, 0x0000 },
- { 0x1F5F, 0x1F57, 0x0000, 0x0000 },
- { 0x2161, 0x2171, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_065[] = {
- { 0x0041, 0x0061, 0x0000, 0x0000 },
- { 0x0544, 0x0574, 0x0000, 0x0000 },
- { 0x2160, 0x2170, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_066[] = {
- { 0x0042, 0x0062, 0x0000, 0x0000 },
- { 0x0143, 0x0144, 0x0000, 0x0000 },
- { 0x0547, 0x0577, 0x0000, 0x0000 },
- { 0x1E5C, 0x1E5D, 0x0000, 0x0000 },
- { 0x1F5D, 0x1F55, 0x0000, 0x0000 },
- { 0x2163, 0x2173, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_067[] = {
- { 0x0043, 0x0063, 0x0000, 0x0000 },
- { 0x0241, 0x0294, 0x0000, 0x0000 },
- { 0x0546, 0x0576, 0x0000, 0x0000 },
- { 0x2162, 0x2172, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_068[] = {
- { 0x0044, 0x0064, 0x0000, 0x0000 },
- { 0x0145, 0x0146, 0x0000, 0x0000 },
- { 0x0541, 0x0571, 0x0000, 0x0000 },
- { 0x1E5A, 0x1E5B, 0x0000, 0x0000 },
- { 0x1F5B, 0x1F53, 0x0000, 0x0000 },
- { 0x2165, 0x2175, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_069[] = {
- { 0x0045, 0x0065, 0x0000, 0x0000 },
- { 0x0540, 0x0570, 0x0000, 0x0000 },
- { 0x2164, 0x2174, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_070[] = {
- { 0x0046, 0x0066, 0x0000, 0x0000 },
- { 0x0147, 0x0148, 0x0000, 0x0000 },
- { 0x0345, 0x03B9, 0x0000, 0x0000 },
- { 0x0543, 0x0573, 0x0000, 0x0000 },
- { 0x1E58, 0x1E59, 0x0000, 0x0000 },
- { 0x1F59, 0x1F51, 0x0000, 0x0000 },
- { 0x2167, 0x2177, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_071[] = {
- { 0x0047, 0x0067, 0x0000, 0x0000 },
- { 0x0542, 0x0572, 0x0000, 0x0000 },
- { 0x2166, 0x2176, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_072[] = {
- { 0x0048, 0x0068, 0x0000, 0x0000 },
- { 0x0149, 0x02BC, 0x006E, 0x0000 },
- { 0x054D, 0x057D, 0x0000, 0x0000 },
- { 0x1E56, 0x1E57, 0x0000, 0x0000 },
- { 0x2169, 0x2179, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_073[] = {
- { 0x0049, 0x0069, 0x0000, 0x0000 },
- { 0x054C, 0x057C, 0x0000, 0x0000 },
- { 0x1F56, 0x03C5, 0x0313, 0x0342 },
- { 0x2168, 0x2178, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_074[] = {
- { 0x004A, 0x006A, 0x0000, 0x0000 },
- { 0x054F, 0x057F, 0x0000, 0x0000 },
- { 0x1E54, 0x1E55, 0x0000, 0x0000 },
- { 0x216B, 0x217B, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_075[] = {
- { 0x004B, 0x006B, 0x0000, 0x0000 },
- { 0x014A, 0x014B, 0x0000, 0x0000 },
- { 0x054E, 0x057E, 0x0000, 0x0000 },
- { 0x1F54, 0x03C5, 0x0313, 0x0301 },
- { 0x216A, 0x217A, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_076[] = {
- { 0x004C, 0x006C, 0x0000, 0x0000 },
- { 0x0549, 0x0579, 0x0000, 0x0000 },
- { 0x1E52, 0x1E53, 0x0000, 0x0000 },
- { 0x216D, 0x217D, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_077[] = {
- { 0x004D, 0x006D, 0x0000, 0x0000 },
- { 0x014C, 0x014D, 0x0000, 0x0000 },
- { 0x0548, 0x0578, 0x0000, 0x0000 },
- { 0x1F52, 0x03C5, 0x0313, 0x0300 },
- { 0x216C, 0x217C, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_078[] = {
- { 0x004E, 0x006E, 0x0000, 0x0000 },
- { 0x054B, 0x057B, 0x0000, 0x0000 },
- { 0x1E50, 0x1E51, 0x0000, 0x0000 },
- { 0x216F, 0x217F, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_079[] = {
- { 0x004F, 0x006F, 0x0000, 0x0000 },
- { 0x014E, 0x014F, 0x0000, 0x0000 },
- { 0x054A, 0x057A, 0x0000, 0x0000 },
- { 0x1F50, 0x03C5, 0x0313, 0x0000 },
- { 0x216E, 0x217E, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_080[] = {
- { 0x0050, 0x0070, 0x0000, 0x0000 },
- { 0x0555, 0x0585, 0x0000, 0x0000 },
- { 0x1E4E, 0x1E4F, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_081[] = {
- { 0x0051, 0x0071, 0x0000, 0x0000 },
- { 0x0150, 0x0151, 0x0000, 0x0000 },
- { 0x0554, 0x0584, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_082[] = {
- { 0x0052, 0x0072, 0x0000, 0x0000 },
- { 0x1E4C, 0x1E4D, 0x0000, 0x0000 },
- { 0x1F4D, 0x1F45, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_083[] = {
- { 0x0053, 0x0073, 0x0000, 0x0000 },
- { 0x0152, 0x0153, 0x0000, 0x0000 },
- { 0x0556, 0x0586, 0x0000, 0x0000 },
- { 0x1F4C, 0x1F44, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_084[] = {
- { 0x0054, 0x0074, 0x0000, 0x0000 },
- { 0x0551, 0x0581, 0x0000, 0x0000 },
- { 0x1E4A, 0x1E4B, 0x0000, 0x0000 },
- { 0x1F4B, 0x1F43, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_085[] = {
- { 0x0055, 0x0075, 0x0000, 0x0000 },
- { 0x0154, 0x0155, 0x0000, 0x0000 },
- { 0x0550, 0x0580, 0x0000, 0x0000 },
- { 0x1F4A, 0x1F42, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_086[] = {
- { 0x0056, 0x0076, 0x0000, 0x0000 },
- { 0x0553, 0x0583, 0x0000, 0x0000 },
- { 0x1E48, 0x1E49, 0x0000, 0x0000 },
- { 0x1F49, 0x1F41, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_087[] = {
- { 0x0057, 0x0077, 0x0000, 0x0000 },
- { 0x0156, 0x0157, 0x0000, 0x0000 },
- { 0x0552, 0x0582, 0x0000, 0x0000 },
- { 0x1F48, 0x1F40, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_088[] = {
- { 0x0058, 0x0078, 0x0000, 0x0000 },
- { 0x1E46, 0x1E47, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_089[] = {
- { 0x0059, 0x0079, 0x0000, 0x0000 },
- { 0x0158, 0x0159, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_090[] = {
- { 0x005A, 0x007A, 0x0000, 0x0000 },
- { 0x1E44, 0x1E45, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_091[] = {
- { 0x015A, 0x015B, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_092[] = {
- { 0x1E42, 0x1E43, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_093[] = {
- { 0x015C, 0x015D, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_094[] = {
- { 0x1E40, 0x1E41, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_095[] = {
- { 0x015E, 0x015F, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_096[] = {
- { 0x0464, 0x0465, 0x0000, 0x0000 },
- { 0x1E7E, 0x1E7F, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_097[] = {
- { 0x0160, 0x0161, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_098[] = {
- { 0x0466, 0x0467, 0x0000, 0x0000 },
- { 0x1E7C, 0x1E7D, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_099[] = {
- { 0x0162, 0x0163, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_100[] = {
- { 0x0460, 0x0461, 0x0000, 0x0000 },
- { 0x1E7A, 0x1E7B, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_101[] = {
- { 0x0164, 0x0165, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_102[] = {
- { 0x0462, 0x0463, 0x0000, 0x0000 },
- { 0x1E78, 0x1E79, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_103[] = {
- { 0x0166, 0x0167, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_104[] = {
- { 0x046C, 0x046D, 0x0000, 0x0000 },
- { 0x1E76, 0x1E77, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_105[] = {
- { 0x0168, 0x0169, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_106[] = {
- { 0x046E, 0x046F, 0x0000, 0x0000 },
- { 0x1E74, 0x1E75, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_107[] = {
- { 0x016A, 0x016B, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_108[] = {
- { 0x0468, 0x0469, 0x0000, 0x0000 },
- { 0x1E72, 0x1E73, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_109[] = {
- { 0x016C, 0x016D, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_110[] = {
- { 0x046A, 0x046B, 0x0000, 0x0000 },
- { 0x1E70, 0x1E71, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_111[] = {
- { 0x016E, 0x016F, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_112[] = {
- { 0x0474, 0x0475, 0x0000, 0x0000 },
- { 0x1E6E, 0x1E6F, 0x0000, 0x0000 },
- { 0x1F6F, 0x1F67, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_113[] = {
- { 0x0170, 0x0171, 0x0000, 0x0000 },
- { 0x1F6E, 0x1F66, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_114[] = {
- { 0x0476, 0x0477, 0x0000, 0x0000 },
- { 0x1E6C, 0x1E6D, 0x0000, 0x0000 },
- { 0x1F6D, 0x1F65, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_115[] = {
- { 0x0172, 0x0173, 0x0000, 0x0000 },
- { 0x1F6C, 0x1F64, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_116[] = {
- { 0x0470, 0x0471, 0x0000, 0x0000 },
- { 0x1E6A, 0x1E6B, 0x0000, 0x0000 },
- { 0x1F6B, 0x1F63, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_117[] = {
- { 0x0174, 0x0175, 0x0000, 0x0000 },
- { 0x1F6A, 0x1F62, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_118[] = {
- { 0x0472, 0x0473, 0x0000, 0x0000 },
- { 0x1E68, 0x1E69, 0x0000, 0x0000 },
- { 0x1F69, 0x1F61, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_119[] = {
- { 0x0176, 0x0177, 0x0000, 0x0000 },
- { 0x1F68, 0x1F60, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_120[] = {
- { 0x0179, 0x017A, 0x0000, 0x0000 },
- { 0x047C, 0x047D, 0x0000, 0x0000 },
- { 0x1E66, 0x1E67, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_121[] = {
- { 0x0178, 0x00FF, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_122[] = {
- { 0x017B, 0x017C, 0x0000, 0x0000 },
- { 0x047E, 0x047F, 0x0000, 0x0000 },
- { 0x1E64, 0x1E65, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_124[] = {
- { 0x017D, 0x017E, 0x0000, 0x0000 },
- { 0x0478, 0x0479, 0x0000, 0x0000 },
- { 0x1E62, 0x1E63, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_126[] = {
- { 0x017F, 0x0073, 0x0000, 0x0000 },
- { 0x047A, 0x047B, 0x0000, 0x0000 },
- { 0x1E60, 0x1E61, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_128[] = {
- { 0x0181, 0x0253, 0x0000, 0x0000 },
- { 0x1F9F, 0x1F27, 0x03B9, 0x0000 },
- { 0x2CAC, 0x2CAD, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_129[] = {
- { 0x1F9E, 0x1F26, 0x03B9, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_130[] = {
- { 0x0587, 0x0565, 0x0582, 0x0000 },
- { 0x1F9D, 0x1F25, 0x03B9, 0x0000 },
- { 0x2CAE, 0x2CAF, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_131[] = {
- { 0x0182, 0x0183, 0x0000, 0x0000 },
- { 0x1F9C, 0x1F24, 0x03B9, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_132[] = {
- { 0x0480, 0x0481, 0x0000, 0x0000 },
- { 0x1E9A, 0x0061, 0x02BE, 0x0000 },
- { 0x1F9B, 0x1F23, 0x03B9, 0x0000 },
- { 0x2CA8, 0x2CA9, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_133[] = {
- { 0x0184, 0x0185, 0x0000, 0x0000 },
- { 0x0386, 0x03AC, 0x0000, 0x0000 },
- { 0x1E9B, 0x1E61, 0x0000, 0x0000 },
- { 0x1F9A, 0x1F22, 0x03B9, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_134[] = {
- { 0x0187, 0x0188, 0x0000, 0x0000 },
- { 0x1E98, 0x0077, 0x030A, 0x0000 },
- { 0x1F99, 0x1F21, 0x03B9, 0x0000 },
- { 0x2CAA, 0x2CAB, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_135[] = {
- { 0x0186, 0x0254, 0x0000, 0x0000 },
- { 0x1E99, 0x0079, 0x030A, 0x0000 },
- { 0x1F98, 0x1F20, 0x03B9, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_136[] = {
- { 0x0189, 0x0256, 0x0000, 0x0000 },
- { 0x048C, 0x048D, 0x0000, 0x0000 },
- { 0x1E96, 0x0068, 0x0331, 0x0000 },
- { 0x1F97, 0x1F27, 0x03B9, 0x0000 },
- { 0x2CA4, 0x2CA5, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_137[] = {
- { 0x038A, 0x03AF, 0x0000, 0x0000 },
- { 0x1E97, 0x0074, 0x0308, 0x0000 },
- { 0x1F96, 0x1F26, 0x03B9, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_138[] = {
- { 0x018B, 0x018C, 0x0000, 0x0000 },
- { 0x0389, 0x03AE, 0x0000, 0x0000 },
- { 0x048E, 0x048F, 0x0000, 0x0000 },
- { 0x1E94, 0x1E95, 0x0000, 0x0000 },
- { 0x1F95, 0x1F25, 0x03B9, 0x0000 },
- { 0x2CA6, 0x2CA7, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_139[] = {
- { 0x018A, 0x0257, 0x0000, 0x0000 },
- { 0x0388, 0x03AD, 0x0000, 0x0000 },
- { 0x1F94, 0x1F24, 0x03B9, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_140[] = {
- { 0x038F, 0x03CE, 0x0000, 0x0000 },
- { 0x1E92, 0x1E93, 0x0000, 0x0000 },
- { 0x1F93, 0x1F23, 0x03B9, 0x0000 },
- { 0x2CA0, 0x2CA1, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_141[] = {
- { 0x038E, 0x03CD, 0x0000, 0x0000 },
- { 0x1F92, 0x1F22, 0x03B9, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_142[] = {
- { 0x018F, 0x0259, 0x0000, 0x0000 },
- { 0x048A, 0x048B, 0x0000, 0x0000 },
- { 0x1E90, 0x1E91, 0x0000, 0x0000 },
- { 0x1F91, 0x1F21, 0x03B9, 0x0000 },
- { 0x2CA2, 0x2CA3, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_143[] = {
- { 0x018E, 0x01DD, 0x0000, 0x0000 },
- { 0x038C, 0x03CC, 0x0000, 0x0000 },
- { 0x1F90, 0x1F20, 0x03B9, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_144[] = {
- { 0x0191, 0x0192, 0x0000, 0x0000 },
- { 0x0393, 0x03B3, 0x0000, 0x0000 },
- { 0x0494, 0x0495, 0x0000, 0x0000 },
- { 0x1E8E, 0x1E8F, 0x0000, 0x0000 },
- { 0x1F8F, 0x1F07, 0x03B9, 0x0000 },
- { 0x2CBC, 0x2CBD, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_145[] = {
- { 0x0190, 0x025B, 0x0000, 0x0000 },
- { 0x0392, 0x03B2, 0x0000, 0x0000 },
- { 0x1F8E, 0x1F06, 0x03B9, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_146[] = {
- { 0x0193, 0x0260, 0x0000, 0x0000 },
- { 0x0391, 0x03B1, 0x0000, 0x0000 },
- { 0x0496, 0x0497, 0x0000, 0x0000 },
- { 0x1E8C, 0x1E8D, 0x0000, 0x0000 },
- { 0x1F8D, 0x1F05, 0x03B9, 0x0000 },
- { 0x24B6, 0x24D0, 0x0000, 0x0000 },
- { 0x2CBE, 0x2CBF, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_147[] = {
- { 0x0390, 0x03B9, 0x0308, 0x0301 },
- { 0x1F8C, 0x1F04, 0x03B9, 0x0000 },
- { 0x24B7, 0x24D1, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_148[] = {
- { 0x0397, 0x03B7, 0x0000, 0x0000 },
- { 0x0490, 0x0491, 0x0000, 0x0000 },
- { 0x1E8A, 0x1E8B, 0x0000, 0x0000 },
- { 0x1F8B, 0x1F03, 0x03B9, 0x0000 },
- { 0x2CB8, 0x2CB9, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_149[] = {
- { 0x0194, 0x0263, 0x0000, 0x0000 },
- { 0x0396, 0x03B6, 0x0000, 0x0000 },
- { 0x1F8A, 0x1F02, 0x03B9, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_150[] = {
- { 0x0197, 0x0268, 0x0000, 0x0000 },
- { 0x0395, 0x03B5, 0x0000, 0x0000 },
- { 0x0492, 0x0493, 0x0000, 0x0000 },
- { 0x1E88, 0x1E89, 0x0000, 0x0000 },
- { 0x1F89, 0x1F01, 0x03B9, 0x0000 },
- { 0x2CBA, 0x2CBB, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_151[] = {
- { 0x0196, 0x0269, 0x0000, 0x0000 },
- { 0x0394, 0x03B4, 0x0000, 0x0000 },
- { 0x1F88, 0x1F00, 0x03B9, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_152[] = {
- { 0x039B, 0x03BB, 0x0000, 0x0000 },
- { 0x049C, 0x049D, 0x0000, 0x0000 },
- { 0x1E86, 0x1E87, 0x0000, 0x0000 },
- { 0x1F87, 0x1F07, 0x03B9, 0x0000 },
- { 0x24BC, 0x24D6, 0x0000, 0x0000 },
- { 0x2CB4, 0x2CB5, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_153[] = {
- { 0x0198, 0x0199, 0x0000, 0x0000 },
- { 0x039A, 0x03BA, 0x0000, 0x0000 },
- { 0x1F86, 0x1F06, 0x03B9, 0x0000 },
- { 0x24BD, 0x24D7, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_154[] = {
- { 0x0399, 0x03B9, 0x0000, 0x0000 },
- { 0x049E, 0x049F, 0x0000, 0x0000 },
- { 0x1E84, 0x1E85, 0x0000, 0x0000 },
- { 0x1F85, 0x1F05, 0x03B9, 0x0000 },
- { 0x24BE, 0x24D8, 0x0000, 0x0000 },
- { 0x2CB6, 0x2CB7, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_155[] = {
- { 0x0398, 0x03B8, 0x0000, 0x0000 },
- { 0x1F84, 0x1F04, 0x03B9, 0x0000 },
- { 0x24BF, 0x24D9, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_156[] = {
- { 0x019D, 0x0272, 0x0000, 0x0000 },
- { 0x039F, 0x03BF, 0x0000, 0x0000 },
- { 0x0498, 0x0499, 0x0000, 0x0000 },
- { 0x1E82, 0x1E83, 0x0000, 0x0000 },
- { 0x1F83, 0x1F03, 0x03B9, 0x0000 },
- { 0x24B8, 0x24D2, 0x0000, 0x0000 },
- { 0x2CB0, 0x2CB1, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_157[] = {
- { 0x019C, 0x026F, 0x0000, 0x0000 },
- { 0x039E, 0x03BE, 0x0000, 0x0000 },
- { 0x1F82, 0x1F02, 0x03B9, 0x0000 },
- { 0x24B9, 0x24D3, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_158[] = {
- { 0x019F, 0x0275, 0x0000, 0x0000 },
- { 0x039D, 0x03BD, 0x0000, 0x0000 },
- { 0x049A, 0x049B, 0x0000, 0x0000 },
- { 0x1E80, 0x1E81, 0x0000, 0x0000 },
- { 0x1F81, 0x1F01, 0x03B9, 0x0000 },
- { 0x24BA, 0x24D4, 0x0000, 0x0000 },
- { 0x2CB2, 0x2CB3, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_159[] = {
- { 0x039C, 0x03BC, 0x0000, 0x0000 },
- { 0x1F80, 0x1F00, 0x03B9, 0x0000 },
- { 0x24BB, 0x24D5, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_160[] = {
- { 0x03A3, 0x03C3, 0x0000, 0x0000 },
- { 0x04A4, 0x04A5, 0x0000, 0x0000 },
- { 0x10B0, 0x2D10, 0x0000, 0x0000 },
- { 0x1EBE, 0x1EBF, 0x0000, 0x0000 },
- { 0x2C8C, 0x2C8D, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_161[] = {
- { 0x01A0, 0x01A1, 0x0000, 0x0000 },
- { 0x10B1, 0x2D11, 0x0000, 0x0000 },
- { 0x1FBE, 0x03B9, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_162[] = {
- { 0x03A1, 0x03C1, 0x0000, 0x0000 },
- { 0x04A6, 0x04A7, 0x0000, 0x0000 },
- { 0x10B2, 0x2D12, 0x0000, 0x0000 },
- { 0x1EBC, 0x1EBD, 0x0000, 0x0000 },
- { 0x2C8E, 0x2C8F, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_163[] = {
- { 0x01A2, 0x01A3, 0x0000, 0x0000 },
- { 0x03A0, 0x03C0, 0x0000, 0x0000 },
- { 0x10B3, 0x2D13, 0x0000, 0x0000 },
- { 0x1FBC, 0x03B1, 0x03B9, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_164[] = {
- { 0x03A7, 0x03C7, 0x0000, 0x0000 },
- { 0x04A0, 0x04A1, 0x0000, 0x0000 },
- { 0x10B4, 0x2D14, 0x0000, 0x0000 },
- { 0x1EBA, 0x1EBB, 0x0000, 0x0000 },
- { 0x1FBB, 0x1F71, 0x0000, 0x0000 },
- { 0x2C88, 0x2C89, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_165[] = {
- { 0x01A4, 0x01A5, 0x0000, 0x0000 },
- { 0x03A6, 0x03C6, 0x0000, 0x0000 },
- { 0x10B5, 0x2D15, 0x0000, 0x0000 },
- { 0x1FBA, 0x1F70, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_166[] = {
- { 0x01A7, 0x01A8, 0x0000, 0x0000 },
- { 0x03A5, 0x03C5, 0x0000, 0x0000 },
- { 0x04A2, 0x04A3, 0x0000, 0x0000 },
- { 0x10B6, 0x2D16, 0x0000, 0x0000 },
- { 0x1EB8, 0x1EB9, 0x0000, 0x0000 },
- { 0x1FB9, 0x1FB1, 0x0000, 0x0000 },
- { 0x2C8A, 0x2C8B, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_167[] = {
- { 0x01A6, 0x0280, 0x0000, 0x0000 },
- { 0x03A4, 0x03C4, 0x0000, 0x0000 },
- { 0x10B7, 0x2D17, 0x0000, 0x0000 },
- { 0x1FB8, 0x1FB0, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_168[] = {
- { 0x01A9, 0x0283, 0x0000, 0x0000 },
- { 0x03AB, 0x03CB, 0x0000, 0x0000 },
- { 0x04AC, 0x04AD, 0x0000, 0x0000 },
- { 0x10B8, 0x2D18, 0x0000, 0x0000 },
- { 0x1EB6, 0x1EB7, 0x0000, 0x0000 },
- { 0x1FB7, 0x03B1, 0x0342, 0x03B9 },
- { 0x2C84, 0x2C85, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_169[] = {
- { 0x03AA, 0x03CA, 0x0000, 0x0000 },
- { 0x10B9, 0x2D19, 0x0000, 0x0000 },
- { 0x1FB6, 0x03B1, 0x0342, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_170[] = {
- { 0x03A9, 0x03C9, 0x0000, 0x0000 },
- { 0x04AE, 0x04AF, 0x0000, 0x0000 },
- { 0x10BA, 0x2D1A, 0x0000, 0x0000 },
- { 0x1EB4, 0x1EB5, 0x0000, 0x0000 },
- { 0x2C86, 0x2C87, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_171[] = {
- { 0x03A8, 0x03C8, 0x0000, 0x0000 },
- { 0x10BB, 0x2D1B, 0x0000, 0x0000 },
- { 0x1FB4, 0x03AC, 0x03B9, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_172[] = {
- { 0x04A8, 0x04A9, 0x0000, 0x0000 },
- { 0x10BC, 0x2D1C, 0x0000, 0x0000 },
- { 0x1EB2, 0x1EB3, 0x0000, 0x0000 },
- { 0x1FB3, 0x03B1, 0x03B9, 0x0000 },
- { 0x2C80, 0x2C81, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_173[] = {
- { 0x01AC, 0x01AD, 0x0000, 0x0000 },
- { 0x10BD, 0x2D1D, 0x0000, 0x0000 },
- { 0x1FB2, 0x1F70, 0x03B9, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_174[] = {
- { 0x01AF, 0x01B0, 0x0000, 0x0000 },
- { 0x04AA, 0x04AB, 0x0000, 0x0000 },
- { 0x10BE, 0x2D1E, 0x0000, 0x0000 },
- { 0x1EB0, 0x1EB1, 0x0000, 0x0000 },
- { 0x2C82, 0x2C83, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_175[] = {
- { 0x01AE, 0x0288, 0x0000, 0x0000 },
- { 0x10BF, 0x2D1F, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_176[] = {
- { 0x01B1, 0x028A, 0x0000, 0x0000 },
- { 0x04B4, 0x04B5, 0x0000, 0x0000 },
- { 0x10A0, 0x2D00, 0x0000, 0x0000 },
- { 0x1EAE, 0x1EAF, 0x0000, 0x0000 },
- { 0x1FAF, 0x1F67, 0x03B9, 0x0000 },
- { 0x2C9C, 0x2C9D, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_177[] = {
- { 0x10A1, 0x2D01, 0x0000, 0x0000 },
- { 0x1FAE, 0x1F66, 0x03B9, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_178[] = {
- { 0x01B3, 0x01B4, 0x0000, 0x0000 },
- { 0x04B6, 0x04B7, 0x0000, 0x0000 },
- { 0x10A2, 0x2D02, 0x0000, 0x0000 },
- { 0x1EAC, 0x1EAD, 0x0000, 0x0000 },
- { 0x1FAD, 0x1F65, 0x03B9, 0x0000 },
- { 0x2C9E, 0x2C9F, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_179[] = {
- { 0x01B2, 0x028B, 0x0000, 0x0000 },
- { 0x03B0, 0x03C5, 0x0308, 0x0301 },
- { 0x10A3, 0x2D03, 0x0000, 0x0000 },
- { 0x1FAC, 0x1F64, 0x03B9, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_180[] = {
- { 0x01B5, 0x01B6, 0x0000, 0x0000 },
- { 0x04B0, 0x04B1, 0x0000, 0x0000 },
- { 0x10A4, 0x2D04, 0x0000, 0x0000 },
- { 0x1EAA, 0x1EAB, 0x0000, 0x0000 },
- { 0x1FAB, 0x1F63, 0x03B9, 0x0000 },
- { 0x2C98, 0x2C99, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_181[] = {
- { 0x00B5, 0x03BC, 0x0000, 0x0000 },
- { 0x10A5, 0x2D05, 0x0000, 0x0000 },
- { 0x1FAA, 0x1F62, 0x03B9, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_182[] = {
- { 0x01B7, 0x0292, 0x0000, 0x0000 },
- { 0x04B2, 0x04B3, 0x0000, 0x0000 },
- { 0x10A6, 0x2D06, 0x0000, 0x0000 },
- { 0x1EA8, 0x1EA9, 0x0000, 0x0000 },
- { 0x1FA9, 0x1F61, 0x03B9, 0x0000 },
- { 0x2C9A, 0x2C9B, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_183[] = {
- { 0x10A7, 0x2D07, 0x0000, 0x0000 },
- { 0x1FA8, 0x1F60, 0x03B9, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_184[] = {
- { 0x04BC, 0x04BD, 0x0000, 0x0000 },
- { 0x10A8, 0x2D08, 0x0000, 0x0000 },
- { 0x1EA6, 0x1EA7, 0x0000, 0x0000 },
- { 0x1FA7, 0x1F67, 0x03B9, 0x0000 },
- { 0x2C94, 0x2C95, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_185[] = {
- { 0x01B8, 0x01B9, 0x0000, 0x0000 },
- { 0x10A9, 0x2D09, 0x0000, 0x0000 },
- { 0x1FA6, 0x1F66, 0x03B9, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_186[] = {
- { 0x04BE, 0x04BF, 0x0000, 0x0000 },
- { 0x10AA, 0x2D0A, 0x0000, 0x0000 },
- { 0x1EA4, 0x1EA5, 0x0000, 0x0000 },
- { 0x1FA5, 0x1F65, 0x03B9, 0x0000 },
- { 0x2C96, 0x2C97, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_187[] = {
- { 0x10AB, 0x2D0B, 0x0000, 0x0000 },
- { 0x1FA4, 0x1F64, 0x03B9, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_188[] = {
- { 0x04B8, 0x04B9, 0x0000, 0x0000 },
- { 0x10AC, 0x2D0C, 0x0000, 0x0000 },
- { 0x1EA2, 0x1EA3, 0x0000, 0x0000 },
- { 0x1FA3, 0x1F63, 0x03B9, 0x0000 },
- { 0x2C90, 0x2C91, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_189[] = {
- { 0x01BC, 0x01BD, 0x0000, 0x0000 },
- { 0x10AD, 0x2D0D, 0x0000, 0x0000 },
- { 0x1FA2, 0x1F62, 0x03B9, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_190[] = {
- { 0x04BA, 0x04BB, 0x0000, 0x0000 },
- { 0x10AE, 0x2D0E, 0x0000, 0x0000 },
- { 0x1EA0, 0x1EA1, 0x0000, 0x0000 },
- { 0x1FA1, 0x1F61, 0x03B9, 0x0000 },
- { 0x2C92, 0x2C93, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_191[] = {
- { 0x10AF, 0x2D0F, 0x0000, 0x0000 },
- { 0x1FA0, 0x1F60, 0x03B9, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_192[] = {
- { 0x00C0, 0x00E0, 0x0000, 0x0000 },
- { 0x1EDE, 0x1EDF, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_193[] = {
- { 0x00C1, 0x00E1, 0x0000, 0x0000 },
- { 0x03C2, 0x03C3, 0x0000, 0x0000 },
- { 0x04C5, 0x04C6, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_194[] = {
- { 0x00C2, 0x00E2, 0x0000, 0x0000 },
- { 0x1EDC, 0x1EDD, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_195[] = {
- { 0x00C3, 0x00E3, 0x0000, 0x0000 },
- { 0x04C7, 0x04C8, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_196[] = {
- { 0x00C4, 0x00E4, 0x0000, 0x0000 },
- { 0x01C5, 0x01C6, 0x0000, 0x0000 },
- { 0x1EDA, 0x1EDB, 0x0000, 0x0000 },
- { 0x1FDB, 0x1F77, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_197[] = {
- { 0x00C5, 0x00E5, 0x0000, 0x0000 },
- { 0x01C4, 0x01C6, 0x0000, 0x0000 },
- { 0x04C1, 0x04C2, 0x0000, 0x0000 },
- { 0x1FDA, 0x1F76, 0x0000, 0x0000 },
- { 0xFF3A, 0xFF5A, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_198[] = {
- { 0x00C6, 0x00E6, 0x0000, 0x0000 },
- { 0x01C7, 0x01C9, 0x0000, 0x0000 },
- { 0x1ED8, 0x1ED9, 0x0000, 0x0000 },
- { 0x1FD9, 0x1FD1, 0x0000, 0x0000 },
- { 0xFF39, 0xFF59, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_199[] = {
- { 0x00C7, 0x00E7, 0x0000, 0x0000 },
- { 0x04C3, 0x04C4, 0x0000, 0x0000 },
- { 0x1FD8, 0x1FD0, 0x0000, 0x0000 },
- { 0xFF38, 0xFF58, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_200[] = {
- { 0x00C8, 0x00E8, 0x0000, 0x0000 },
- { 0x1ED6, 0x1ED7, 0x0000, 0x0000 },
- { 0x1FD7, 0x03B9, 0x0308, 0x0342 },
- { 0xFF37, 0xFF57, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_201[] = {
- { 0x00C9, 0x00E9, 0x0000, 0x0000 },
- { 0x01C8, 0x01C9, 0x0000, 0x0000 },
- { 0x04CD, 0x04CE, 0x0000, 0x0000 },
- { 0x1FD6, 0x03B9, 0x0342, 0x0000 },
- { 0xFF36, 0xFF56, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_202[] = {
- { 0x00CA, 0x00EA, 0x0000, 0x0000 },
- { 0x01CB, 0x01CC, 0x0000, 0x0000 },
- { 0x1ED4, 0x1ED5, 0x0000, 0x0000 },
- { 0xFF35, 0xFF55, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_203[] = {
- { 0x00CB, 0x00EB, 0x0000, 0x0000 },
- { 0x01CA, 0x01CC, 0x0000, 0x0000 },
- { 0xFF34, 0xFF54, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_204[] = {
- { 0x00CC, 0x00EC, 0x0000, 0x0000 },
- { 0x01CD, 0x01CE, 0x0000, 0x0000 },
- { 0x1ED2, 0x1ED3, 0x0000, 0x0000 },
- { 0x1FD3, 0x03B9, 0x0308, 0x0301 },
- { 0x2CE0, 0x2CE1, 0x0000, 0x0000 },
- { 0xFF33, 0xFF53, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_205[] = {
- { 0x00CD, 0x00ED, 0x0000, 0x0000 },
- { 0x04C9, 0x04CA, 0x0000, 0x0000 },
- { 0x1FD2, 0x03B9, 0x0308, 0x0300 },
- { 0xFF32, 0xFF52, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_206[] = {
- { 0x00CE, 0x00EE, 0x0000, 0x0000 },
- { 0x01CF, 0x01D0, 0x0000, 0x0000 },
- { 0x1ED0, 0x1ED1, 0x0000, 0x0000 },
- { 0x2CE2, 0x2CE3, 0x0000, 0x0000 },
- { 0xFF31, 0xFF51, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_207[] = {
- { 0x00CF, 0x00EF, 0x0000, 0x0000 },
- { 0x04CB, 0x04CC, 0x0000, 0x0000 },
- { 0xFF30, 0xFF50, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_208[] = {
- { 0x00D0, 0x00F0, 0x0000, 0x0000 },
- { 0x01D1, 0x01D2, 0x0000, 0x0000 },
- { 0x04D4, 0x04D5, 0x0000, 0x0000 },
- { 0x10C0, 0x2D20, 0x0000, 0x0000 },
- { 0x1ECE, 0x1ECF, 0x0000, 0x0000 },
- { 0xFF2F, 0xFF4F, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_209[] = {
- { 0x00D1, 0x00F1, 0x0000, 0x0000 },
- { 0x10C1, 0x2D21, 0x0000, 0x0000 },
- { 0xFF2E, 0xFF4E, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_210[] = {
- { 0x00D2, 0x00F2, 0x0000, 0x0000 },
- { 0x01D3, 0x01D4, 0x0000, 0x0000 },
- { 0x03D1, 0x03B8, 0x0000, 0x0000 },
- { 0x04D6, 0x04D7, 0x0000, 0x0000 },
- { 0x10C2, 0x2D22, 0x0000, 0x0000 },
- { 0x1ECC, 0x1ECD, 0x0000, 0x0000 },
- { 0xFF2D, 0xFF4D, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_211[] = {
- { 0x00D3, 0x00F3, 0x0000, 0x0000 },
- { 0x03D0, 0x03B2, 0x0000, 0x0000 },
- { 0x10C3, 0x2D23, 0x0000, 0x0000 },
- { 0x1FCC, 0x03B7, 0x03B9, 0x0000 },
- { 0xFF2C, 0xFF4C, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_212[] = {
- { 0x00D4, 0x00F4, 0x0000, 0x0000 },
- { 0x01D5, 0x01D6, 0x0000, 0x0000 },
- { 0x04D0, 0x04D1, 0x0000, 0x0000 },
- { 0x10C4, 0x2D24, 0x0000, 0x0000 },
- { 0x1ECA, 0x1ECB, 0x0000, 0x0000 },
- { 0x1FCB, 0x1F75, 0x0000, 0x0000 },
- { 0xFF2B, 0xFF4B, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_213[] = {
- { 0x00D5, 0x00F5, 0x0000, 0x0000 },
- { 0x03D6, 0x03C0, 0x0000, 0x0000 },
- { 0x10C5, 0x2D25, 0x0000, 0x0000 },
- { 0x1FCA, 0x1F74, 0x0000, 0x0000 },
- { 0xFF2A, 0xFF4A, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_214[] = {
- { 0x00D6, 0x00F6, 0x0000, 0x0000 },
- { 0x01D7, 0x01D8, 0x0000, 0x0000 },
- { 0x03D5, 0x03C6, 0x0000, 0x0000 },
- { 0x04D2, 0x04D3, 0x0000, 0x0000 },
- { 0x1EC8, 0x1EC9, 0x0000, 0x0000 },
- { 0x1FC9, 0x1F73, 0x0000, 0x0000 },
- { 0xFF29, 0xFF49, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_215[] = {
- { 0x1FC8, 0x1F72, 0x0000, 0x0000 },
- { 0xFF28, 0xFF48, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_216[] = {
- { 0x00D8, 0x00F8, 0x0000, 0x0000 },
- { 0x01D9, 0x01DA, 0x0000, 0x0000 },
- { 0x04DC, 0x04DD, 0x0000, 0x0000 },
- { 0x1EC6, 0x1EC7, 0x0000, 0x0000 },
- { 0x1FC7, 0x03B7, 0x0342, 0x03B9 },
- { 0xFF27, 0xFF47, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_217[] = {
- { 0x00D9, 0x00F9, 0x0000, 0x0000 },
- { 0x03DA, 0x03DB, 0x0000, 0x0000 },
- { 0x1FC6, 0x03B7, 0x0342, 0x0000 },
- { 0xFF26, 0xFF46, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_218[] = {
- { 0x00DA, 0x00FA, 0x0000, 0x0000 },
- { 0x01DB, 0x01DC, 0x0000, 0x0000 },
- { 0x04DE, 0x04DF, 0x0000, 0x0000 },
- { 0x1EC4, 0x1EC5, 0x0000, 0x0000 },
- { 0xFF25, 0xFF45, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_219[] = {
- { 0x00DB, 0x00FB, 0x0000, 0x0000 },
- { 0x03D8, 0x03D9, 0x0000, 0x0000 },
- { 0x1FC4, 0x03AE, 0x03B9, 0x0000 },
- { 0xFF24, 0xFF44, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_220[] = {
- { 0x00DC, 0x00FC, 0x0000, 0x0000 },
- { 0x04D8, 0x04D9, 0x0000, 0x0000 },
- { 0x1EC2, 0x1EC3, 0x0000, 0x0000 },
- { 0x1FC3, 0x03B7, 0x03B9, 0x0000 },
- { 0xFF23, 0xFF43, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_221[] = {
- { 0x00DD, 0x00FD, 0x0000, 0x0000 },
- { 0x03DE, 0x03DF, 0x0000, 0x0000 },
- { 0x1FC2, 0x1F74, 0x03B9, 0x0000 },
- { 0xFF22, 0xFF42, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_222[] = {
- { 0x00DE, 0x00FE, 0x0000, 0x0000 },
- { 0x04DA, 0x04DB, 0x0000, 0x0000 },
- { 0x1EC0, 0x1EC1, 0x0000, 0x0000 },
- { 0xFF21, 0xFF41, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_223[] = {
- { 0x00DF, 0x0073, 0x0073, 0x0000 },
- { 0x01DE, 0x01DF, 0x0000, 0x0000 },
- { 0x03DC, 0x03DD, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_224[] = {
- { 0x04E4, 0x04E5, 0x0000, 0x0000 },
- { 0x24C4, 0x24DE, 0x0000, 0x0000 },
- { 0x2CCC, 0x2CCD, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_225[] = {
- { 0x01E0, 0x01E1, 0x0000, 0x0000 },
- { 0x03E2, 0x03E3, 0x0000, 0x0000 },
- { 0x24C5, 0x24DF, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_226[] = {
- { 0x04E6, 0x04E7, 0x0000, 0x0000 },
- { 0x24C6, 0x24E0, 0x0000, 0x0000 },
- { 0x2CCE, 0x2CCF, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_227[] = {
- { 0x01E2, 0x01E3, 0x0000, 0x0000 },
- { 0x03E0, 0x03E1, 0x0000, 0x0000 },
- { 0x1FFC, 0x03C9, 0x03B9, 0x0000 },
- { 0x24C7, 0x24E1, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_228[] = {
- { 0x04E0, 0x04E1, 0x0000, 0x0000 },
- { 0x1FFB, 0x1F7D, 0x0000, 0x0000 },
- { 0x24C0, 0x24DA, 0x0000, 0x0000 },
- { 0x2CC8, 0x2CC9, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_229[] = {
- { 0x01E4, 0x01E5, 0x0000, 0x0000 },
- { 0x03E6, 0x03E7, 0x0000, 0x0000 },
- { 0x1FFA, 0x1F7C, 0x0000, 0x0000 },
- { 0x24C1, 0x24DB, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_230[] = {
- { 0x04E2, 0x04E3, 0x0000, 0x0000 },
- { 0x1EF8, 0x1EF9, 0x0000, 0x0000 },
- { 0x1FF9, 0x1F79, 0x0000, 0x0000 },
- { 0x24C2, 0x24DC, 0x0000, 0x0000 },
- { 0x2CCA, 0x2CCB, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_231[] = {
- { 0x01E6, 0x01E7, 0x0000, 0x0000 },
- { 0x03E4, 0x03E5, 0x0000, 0x0000 },
- { 0x1FF8, 0x1F78, 0x0000, 0x0000 },
- { 0x24C3, 0x24DD, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_232[] = {
- { 0x04EC, 0x04ED, 0x0000, 0x0000 },
- { 0x1EF6, 0x1EF7, 0x0000, 0x0000 },
- { 0x1FF7, 0x03C9, 0x0342, 0x03B9 },
- { 0x24CC, 0x24E6, 0x0000, 0x0000 },
- { 0x2CC4, 0x2CC5, 0x0000, 0x0000 },
- { 0xFB13, 0x0574, 0x0576, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_233[] = {
- { 0x01E8, 0x01E9, 0x0000, 0x0000 },
- { 0x03EA, 0x03EB, 0x0000, 0x0000 },
- { 0x1FF6, 0x03C9, 0x0342, 0x0000 },
- { 0x24CD, 0x24E7, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_234[] = {
- { 0x04EE, 0x04EF, 0x0000, 0x0000 },
- { 0x1EF4, 0x1EF5, 0x0000, 0x0000 },
- { 0x24CE, 0x24E8, 0x0000, 0x0000 },
- { 0x2CC6, 0x2CC7, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_235[] = {
- { 0x01EA, 0x01EB, 0x0000, 0x0000 },
- { 0x03E8, 0x03E9, 0x0000, 0x0000 },
- { 0x1FF4, 0x03CE, 0x03B9, 0x0000 },
- { 0x24CF, 0x24E9, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_236[] = {
- { 0x04E8, 0x04E9, 0x0000, 0x0000 },
- { 0x1EF2, 0x1EF3, 0x0000, 0x0000 },
- { 0x1FF3, 0x03C9, 0x03B9, 0x0000 },
- { 0x24C8, 0x24E2, 0x0000, 0x0000 },
- { 0x2CC0, 0x2CC1, 0x0000, 0x0000 },
- { 0xFB17, 0x0574, 0x056D, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_237[] = {
- { 0x01EC, 0x01ED, 0x0000, 0x0000 },
- { 0x03EE, 0x03EF, 0x0000, 0x0000 },
- { 0x1FF2, 0x1F7C, 0x03B9, 0x0000 },
- { 0x24C9, 0x24E3, 0x0000, 0x0000 },
- { 0xFB16, 0x057E, 0x0576, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_238[] = {
- { 0x04EA, 0x04EB, 0x0000, 0x0000 },
- { 0x1EF0, 0x1EF1, 0x0000, 0x0000 },
- { 0x24CA, 0x24E4, 0x0000, 0x0000 },
- { 0x2CC2, 0x2CC3, 0x0000, 0x0000 },
- { 0xFB15, 0x0574, 0x056B, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_239[] = {
- { 0x01EE, 0x01EF, 0x0000, 0x0000 },
- { 0x03EC, 0x03ED, 0x0000, 0x0000 },
- { 0x24CB, 0x24E5, 0x0000, 0x0000 },
- { 0xFB14, 0x0574, 0x0565, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_240[] = {
- { 0x01F1, 0x01F3, 0x0000, 0x0000 },
- { 0x04F4, 0x04F5, 0x0000, 0x0000 },
- { 0x1EEE, 0x1EEF, 0x0000, 0x0000 },
- { 0x2CDC, 0x2CDD, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_241[] = {
- { 0x01F0, 0x006A, 0x030C, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_242[] = {
- { 0x03F1, 0x03C1, 0x0000, 0x0000 },
- { 0x04F6, 0x04F7, 0x0000, 0x0000 },
- { 0x1EEC, 0x1EED, 0x0000, 0x0000 },
- { 0x2CDE, 0x2CDF, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_243[] = {
- { 0x01F2, 0x01F3, 0x0000, 0x0000 },
- { 0x03F0, 0x03BA, 0x0000, 0x0000 },
- { 0x1FEC, 0x1FE5, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_244[] = {
- { 0x03F7, 0x03F8, 0x0000, 0x0000 },
- { 0x04F0, 0x04F1, 0x0000, 0x0000 },
- { 0x1EEA, 0x1EEB, 0x0000, 0x0000 },
- { 0x1FEB, 0x1F7B, 0x0000, 0x0000 },
- { 0x2CD8, 0x2CD9, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_245[] = {
- { 0x01F4, 0x01F5, 0x0000, 0x0000 },
- { 0x1FEA, 0x1F7A, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_246[] = {
- { 0x01F7, 0x01BF, 0x0000, 0x0000 },
- { 0x03F5, 0x03B5, 0x0000, 0x0000 },
- { 0x04F2, 0x04F3, 0x0000, 0x0000 },
- { 0x1EE8, 0x1EE9, 0x0000, 0x0000 },
- { 0x1FE9, 0x1FE1, 0x0000, 0x0000 },
- { 0x2CDA, 0x2CDB, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_247[] = {
- { 0x01F6, 0x0195, 0x0000, 0x0000 },
- { 0x03F4, 0x03B8, 0x0000, 0x0000 },
- { 0x1FE8, 0x1FE0, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_248[] = {
- { 0x1EE6, 0x1EE7, 0x0000, 0x0000 },
- { 0x1FE7, 0x03C5, 0x0308, 0x0342 },
- { 0x2CD4, 0x2CD5, 0x0000, 0x0000 },
- { 0xFB03, 0x0066, 0x0066, 0x0069 }
-};
-
-static const CaseFoldMapping case_fold_249[] = {
- { 0x01F8, 0x01F9, 0x0000, 0x0000 },
- { 0x03FA, 0x03FB, 0x0000, 0x0000 },
- { 0x1FE6, 0x03C5, 0x0342, 0x0000 },
- { 0xFB02, 0x0066, 0x006C, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_250[] = {
- { 0x03F9, 0x03F2, 0x0000, 0x0000 },
- { 0x1EE4, 0x1EE5, 0x0000, 0x0000 },
- { 0x2CD6, 0x2CD7, 0x0000, 0x0000 },
- { 0xFB01, 0x0066, 0x0069, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_251[] = {
- { 0x01FA, 0x01FB, 0x0000, 0x0000 },
- { 0x1FE4, 0x03C1, 0x0313, 0x0000 },
- { 0xFB00, 0x0066, 0x0066, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_252[] = {
- { 0x04F8, 0x04F9, 0x0000, 0x0000 },
- { 0x1EE2, 0x1EE3, 0x0000, 0x0000 },
- { 0x1FE3, 0x03C5, 0x0308, 0x0301 },
- { 0x2CD0, 0x2CD1, 0x0000, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_253[] = {
- { 0x01FC, 0x01FD, 0x0000, 0x0000 },
- { 0x1FE2, 0x03C5, 0x0308, 0x0300 },
- { 0xFB06, 0x0073, 0x0074, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_254[] = {
- { 0x1EE0, 0x1EE1, 0x0000, 0x0000 },
- { 0x2CD2, 0x2CD3, 0x0000, 0x0000 },
- { 0xFB05, 0x0073, 0x0074, 0x0000 }
-};
-
-static const CaseFoldMapping case_fold_255[] = {
- { 0x01FE, 0x01FF, 0x0000, 0x0000 },
- { 0xFB04, 0x0066, 0x0066, 0x006C }
-};
-
-
-static const CaseFoldHashBucket case_fold_hash[256] = {
- { __PHYSFS_ARRAYLEN(case_fold_000), case_fold_000 },
- { __PHYSFS_ARRAYLEN(case_fold_001), case_fold_001 },
- { __PHYSFS_ARRAYLEN(case_fold_002), case_fold_002 },
- { __PHYSFS_ARRAYLEN(case_fold_003), case_fold_003 },
- { __PHYSFS_ARRAYLEN(case_fold_004), case_fold_004 },
- { __PHYSFS_ARRAYLEN(case_fold_005), case_fold_005 },
- { __PHYSFS_ARRAYLEN(case_fold_006), case_fold_006 },
- { __PHYSFS_ARRAYLEN(case_fold_007), case_fold_007 },
- { __PHYSFS_ARRAYLEN(case_fold_008), case_fold_008 },
- { __PHYSFS_ARRAYLEN(case_fold_009), case_fold_009 },
- { __PHYSFS_ARRAYLEN(case_fold_010), case_fold_010 },
- { __PHYSFS_ARRAYLEN(case_fold_011), case_fold_011 },
- { __PHYSFS_ARRAYLEN(case_fold_012), case_fold_012 },
- { __PHYSFS_ARRAYLEN(case_fold_013), case_fold_013 },
- { __PHYSFS_ARRAYLEN(case_fold_014), case_fold_014 },
- { __PHYSFS_ARRAYLEN(case_fold_015), case_fold_015 },
- { __PHYSFS_ARRAYLEN(case_fold_016), case_fold_016 },
- { __PHYSFS_ARRAYLEN(case_fold_017), case_fold_017 },
- { __PHYSFS_ARRAYLEN(case_fold_018), case_fold_018 },
- { __PHYSFS_ARRAYLEN(case_fold_019), case_fold_019 },
- { __PHYSFS_ARRAYLEN(case_fold_020), case_fold_020 },
- { __PHYSFS_ARRAYLEN(case_fold_021), case_fold_021 },
- { __PHYSFS_ARRAYLEN(case_fold_022), case_fold_022 },
- { __PHYSFS_ARRAYLEN(case_fold_023), case_fold_023 },
- { __PHYSFS_ARRAYLEN(case_fold_024), case_fold_024 },
- { __PHYSFS_ARRAYLEN(case_fold_025), case_fold_025 },
- { __PHYSFS_ARRAYLEN(case_fold_026), case_fold_026 },
- { __PHYSFS_ARRAYLEN(case_fold_027), case_fold_027 },
- { __PHYSFS_ARRAYLEN(case_fold_028), case_fold_028 },
- { __PHYSFS_ARRAYLEN(case_fold_029), case_fold_029 },
- { __PHYSFS_ARRAYLEN(case_fold_030), case_fold_030 },
- { __PHYSFS_ARRAYLEN(case_fold_031), case_fold_031 },
- { __PHYSFS_ARRAYLEN(case_fold_032), case_fold_032 },
- { __PHYSFS_ARRAYLEN(case_fold_033), case_fold_033 },
- { __PHYSFS_ARRAYLEN(case_fold_034), case_fold_034 },
- { __PHYSFS_ARRAYLEN(case_fold_035), case_fold_035 },
- { __PHYSFS_ARRAYLEN(case_fold_036), case_fold_036 },
- { __PHYSFS_ARRAYLEN(case_fold_037), case_fold_037 },
- { __PHYSFS_ARRAYLEN(case_fold_038), case_fold_038 },
- { __PHYSFS_ARRAYLEN(case_fold_039), case_fold_039 },
- { __PHYSFS_ARRAYLEN(case_fold_040), case_fold_040 },
- { __PHYSFS_ARRAYLEN(case_fold_041), case_fold_041 },
- { __PHYSFS_ARRAYLEN(case_fold_042), case_fold_042 },
- { __PHYSFS_ARRAYLEN(case_fold_043), case_fold_043 },
- { __PHYSFS_ARRAYLEN(case_fold_044), case_fold_044 },
- { __PHYSFS_ARRAYLEN(case_fold_045), case_fold_045 },
- { __PHYSFS_ARRAYLEN(case_fold_046), case_fold_046 },
- { __PHYSFS_ARRAYLEN(case_fold_047), case_fold_047 },
- { __PHYSFS_ARRAYLEN(case_fold_048), case_fold_048 },
- { __PHYSFS_ARRAYLEN(case_fold_049), case_fold_049 },
- { __PHYSFS_ARRAYLEN(case_fold_050), case_fold_050 },
- { __PHYSFS_ARRAYLEN(case_fold_051), case_fold_051 },
- { __PHYSFS_ARRAYLEN(case_fold_052), case_fold_052 },
- { __PHYSFS_ARRAYLEN(case_fold_053), case_fold_053 },
- { __PHYSFS_ARRAYLEN(case_fold_054), case_fold_054 },
- { __PHYSFS_ARRAYLEN(case_fold_055), case_fold_055 },
- { __PHYSFS_ARRAYLEN(case_fold_056), case_fold_056 },
- { __PHYSFS_ARRAYLEN(case_fold_057), case_fold_057 },
- { __PHYSFS_ARRAYLEN(case_fold_058), case_fold_058 },
- { __PHYSFS_ARRAYLEN(case_fold_059), case_fold_059 },
- { __PHYSFS_ARRAYLEN(case_fold_060), case_fold_060 },
- { __PHYSFS_ARRAYLEN(case_fold_061), case_fold_061 },
- { __PHYSFS_ARRAYLEN(case_fold_062), case_fold_062 },
- { __PHYSFS_ARRAYLEN(case_fold_063), case_fold_063 },
- { __PHYSFS_ARRAYLEN(case_fold_064), case_fold_064 },
- { __PHYSFS_ARRAYLEN(case_fold_065), case_fold_065 },
- { __PHYSFS_ARRAYLEN(case_fold_066), case_fold_066 },
- { __PHYSFS_ARRAYLEN(case_fold_067), case_fold_067 },
- { __PHYSFS_ARRAYLEN(case_fold_068), case_fold_068 },
- { __PHYSFS_ARRAYLEN(case_fold_069), case_fold_069 },
- { __PHYSFS_ARRAYLEN(case_fold_070), case_fold_070 },
- { __PHYSFS_ARRAYLEN(case_fold_071), case_fold_071 },
- { __PHYSFS_ARRAYLEN(case_fold_072), case_fold_072 },
- { __PHYSFS_ARRAYLEN(case_fold_073), case_fold_073 },
- { __PHYSFS_ARRAYLEN(case_fold_074), case_fold_074 },
- { __PHYSFS_ARRAYLEN(case_fold_075), case_fold_075 },
- { __PHYSFS_ARRAYLEN(case_fold_076), case_fold_076 },
- { __PHYSFS_ARRAYLEN(case_fold_077), case_fold_077 },
- { __PHYSFS_ARRAYLEN(case_fold_078), case_fold_078 },
- { __PHYSFS_ARRAYLEN(case_fold_079), case_fold_079 },
- { __PHYSFS_ARRAYLEN(case_fold_080), case_fold_080 },
- { __PHYSFS_ARRAYLEN(case_fold_081), case_fold_081 },
- { __PHYSFS_ARRAYLEN(case_fold_082), case_fold_082 },
- { __PHYSFS_ARRAYLEN(case_fold_083), case_fold_083 },
- { __PHYSFS_ARRAYLEN(case_fold_084), case_fold_084 },
- { __PHYSFS_ARRAYLEN(case_fold_085), case_fold_085 },
- { __PHYSFS_ARRAYLEN(case_fold_086), case_fold_086 },
- { __PHYSFS_ARRAYLEN(case_fold_087), case_fold_087 },
- { __PHYSFS_ARRAYLEN(case_fold_088), case_fold_088 },
- { __PHYSFS_ARRAYLEN(case_fold_089), case_fold_089 },
- { __PHYSFS_ARRAYLEN(case_fold_090), case_fold_090 },
- { __PHYSFS_ARRAYLEN(case_fold_091), case_fold_091 },
- { __PHYSFS_ARRAYLEN(case_fold_092), case_fold_092 },
- { __PHYSFS_ARRAYLEN(case_fold_093), case_fold_093 },
- { __PHYSFS_ARRAYLEN(case_fold_094), case_fold_094 },
- { __PHYSFS_ARRAYLEN(case_fold_095), case_fold_095 },
- { __PHYSFS_ARRAYLEN(case_fold_096), case_fold_096 },
- { __PHYSFS_ARRAYLEN(case_fold_097), case_fold_097 },
- { __PHYSFS_ARRAYLEN(case_fold_098), case_fold_098 },
- { __PHYSFS_ARRAYLEN(case_fold_099), case_fold_099 },
- { __PHYSFS_ARRAYLEN(case_fold_100), case_fold_100 },
- { __PHYSFS_ARRAYLEN(case_fold_101), case_fold_101 },
- { __PHYSFS_ARRAYLEN(case_fold_102), case_fold_102 },
- { __PHYSFS_ARRAYLEN(case_fold_103), case_fold_103 },
- { __PHYSFS_ARRAYLEN(case_fold_104), case_fold_104 },
- { __PHYSFS_ARRAYLEN(case_fold_105), case_fold_105 },
- { __PHYSFS_ARRAYLEN(case_fold_106), case_fold_106 },
- { __PHYSFS_ARRAYLEN(case_fold_107), case_fold_107 },
- { __PHYSFS_ARRAYLEN(case_fold_108), case_fold_108 },
- { __PHYSFS_ARRAYLEN(case_fold_109), case_fold_109 },
- { __PHYSFS_ARRAYLEN(case_fold_110), case_fold_110 },
- { __PHYSFS_ARRAYLEN(case_fold_111), case_fold_111 },
- { __PHYSFS_ARRAYLEN(case_fold_112), case_fold_112 },
- { __PHYSFS_ARRAYLEN(case_fold_113), case_fold_113 },
- { __PHYSFS_ARRAYLEN(case_fold_114), case_fold_114 },
- { __PHYSFS_ARRAYLEN(case_fold_115), case_fold_115 },
- { __PHYSFS_ARRAYLEN(case_fold_116), case_fold_116 },
- { __PHYSFS_ARRAYLEN(case_fold_117), case_fold_117 },
- { __PHYSFS_ARRAYLEN(case_fold_118), case_fold_118 },
- { __PHYSFS_ARRAYLEN(case_fold_119), case_fold_119 },
- { __PHYSFS_ARRAYLEN(case_fold_120), case_fold_120 },
- { __PHYSFS_ARRAYLEN(case_fold_121), case_fold_121 },
- { __PHYSFS_ARRAYLEN(case_fold_122), case_fold_122 },
- { 0, NULL },
- { __PHYSFS_ARRAYLEN(case_fold_124), case_fold_124 },
- { 0, NULL },
- { __PHYSFS_ARRAYLEN(case_fold_126), case_fold_126 },
- { 0, NULL },
- { __PHYSFS_ARRAYLEN(case_fold_128), case_fold_128 },
- { __PHYSFS_ARRAYLEN(case_fold_129), case_fold_129 },
- { __PHYSFS_ARRAYLEN(case_fold_130), case_fold_130 },
- { __PHYSFS_ARRAYLEN(case_fold_131), case_fold_131 },
- { __PHYSFS_ARRAYLEN(case_fold_132), case_fold_132 },
- { __PHYSFS_ARRAYLEN(case_fold_133), case_fold_133 },
- { __PHYSFS_ARRAYLEN(case_fold_134), case_fold_134 },
- { __PHYSFS_ARRAYLEN(case_fold_135), case_fold_135 },
- { __PHYSFS_ARRAYLEN(case_fold_136), case_fold_136 },
- { __PHYSFS_ARRAYLEN(case_fold_137), case_fold_137 },
- { __PHYSFS_ARRAYLEN(case_fold_138), case_fold_138 },
- { __PHYSFS_ARRAYLEN(case_fold_139), case_fold_139 },
- { __PHYSFS_ARRAYLEN(case_fold_140), case_fold_140 },
- { __PHYSFS_ARRAYLEN(case_fold_141), case_fold_141 },
- { __PHYSFS_ARRAYLEN(case_fold_142), case_fold_142 },
- { __PHYSFS_ARRAYLEN(case_fold_143), case_fold_143 },
- { __PHYSFS_ARRAYLEN(case_fold_144), case_fold_144 },
- { __PHYSFS_ARRAYLEN(case_fold_145), case_fold_145 },
- { __PHYSFS_ARRAYLEN(case_fold_146), case_fold_146 },
- { __PHYSFS_ARRAYLEN(case_fold_147), case_fold_147 },
- { __PHYSFS_ARRAYLEN(case_fold_148), case_fold_148 },
- { __PHYSFS_ARRAYLEN(case_fold_149), case_fold_149 },
- { __PHYSFS_ARRAYLEN(case_fold_150), case_fold_150 },
- { __PHYSFS_ARRAYLEN(case_fold_151), case_fold_151 },
- { __PHYSFS_ARRAYLEN(case_fold_152), case_fold_152 },
- { __PHYSFS_ARRAYLEN(case_fold_153), case_fold_153 },
- { __PHYSFS_ARRAYLEN(case_fold_154), case_fold_154 },
- { __PHYSFS_ARRAYLEN(case_fold_155), case_fold_155 },
- { __PHYSFS_ARRAYLEN(case_fold_156), case_fold_156 },
- { __PHYSFS_ARRAYLEN(case_fold_157), case_fold_157 },
- { __PHYSFS_ARRAYLEN(case_fold_158), case_fold_158 },
- { __PHYSFS_ARRAYLEN(case_fold_159), case_fold_159 },
- { __PHYSFS_ARRAYLEN(case_fold_160), case_fold_160 },
- { __PHYSFS_ARRAYLEN(case_fold_161), case_fold_161 },
- { __PHYSFS_ARRAYLEN(case_fold_162), case_fold_162 },
- { __PHYSFS_ARRAYLEN(case_fold_163), case_fold_163 },
- { __PHYSFS_ARRAYLEN(case_fold_164), case_fold_164 },
- { __PHYSFS_ARRAYLEN(case_fold_165), case_fold_165 },
- { __PHYSFS_ARRAYLEN(case_fold_166), case_fold_166 },
- { __PHYSFS_ARRAYLEN(case_fold_167), case_fold_167 },
- { __PHYSFS_ARRAYLEN(case_fold_168), case_fold_168 },
- { __PHYSFS_ARRAYLEN(case_fold_169), case_fold_169 },
- { __PHYSFS_ARRAYLEN(case_fold_170), case_fold_170 },
- { __PHYSFS_ARRAYLEN(case_fold_171), case_fold_171 },
- { __PHYSFS_ARRAYLEN(case_fold_172), case_fold_172 },
- { __PHYSFS_ARRAYLEN(case_fold_173), case_fold_173 },
- { __PHYSFS_ARRAYLEN(case_fold_174), case_fold_174 },
- { __PHYSFS_ARRAYLEN(case_fold_175), case_fold_175 },
- { __PHYSFS_ARRAYLEN(case_fold_176), case_fold_176 },
- { __PHYSFS_ARRAYLEN(case_fold_177), case_fold_177 },
- { __PHYSFS_ARRAYLEN(case_fold_178), case_fold_178 },
- { __PHYSFS_ARRAYLEN(case_fold_179), case_fold_179 },
- { __PHYSFS_ARRAYLEN(case_fold_180), case_fold_180 },
- { __PHYSFS_ARRAYLEN(case_fold_181), case_fold_181 },
- { __PHYSFS_ARRAYLEN(case_fold_182), case_fold_182 },
- { __PHYSFS_ARRAYLEN(case_fold_183), case_fold_183 },
- { __PHYSFS_ARRAYLEN(case_fold_184), case_fold_184 },
- { __PHYSFS_ARRAYLEN(case_fold_185), case_fold_185 },
- { __PHYSFS_ARRAYLEN(case_fold_186), case_fold_186 },
- { __PHYSFS_ARRAYLEN(case_fold_187), case_fold_187 },
- { __PHYSFS_ARRAYLEN(case_fold_188), case_fold_188 },
- { __PHYSFS_ARRAYLEN(case_fold_189), case_fold_189 },
- { __PHYSFS_ARRAYLEN(case_fold_190), case_fold_190 },
- { __PHYSFS_ARRAYLEN(case_fold_191), case_fold_191 },
- { __PHYSFS_ARRAYLEN(case_fold_192), case_fold_192 },
- { __PHYSFS_ARRAYLEN(case_fold_193), case_fold_193 },
- { __PHYSFS_ARRAYLEN(case_fold_194), case_fold_194 },
- { __PHYSFS_ARRAYLEN(case_fold_195), case_fold_195 },
- { __PHYSFS_ARRAYLEN(case_fold_196), case_fold_196 },
- { __PHYSFS_ARRAYLEN(case_fold_197), case_fold_197 },
- { __PHYSFS_ARRAYLEN(case_fold_198), case_fold_198 },
- { __PHYSFS_ARRAYLEN(case_fold_199), case_fold_199 },
- { __PHYSFS_ARRAYLEN(case_fold_200), case_fold_200 },
- { __PHYSFS_ARRAYLEN(case_fold_201), case_fold_201 },
- { __PHYSFS_ARRAYLEN(case_fold_202), case_fold_202 },
- { __PHYSFS_ARRAYLEN(case_fold_203), case_fold_203 },
- { __PHYSFS_ARRAYLEN(case_fold_204), case_fold_204 },
- { __PHYSFS_ARRAYLEN(case_fold_205), case_fold_205 },
- { __PHYSFS_ARRAYLEN(case_fold_206), case_fold_206 },
- { __PHYSFS_ARRAYLEN(case_fold_207), case_fold_207 },
- { __PHYSFS_ARRAYLEN(case_fold_208), case_fold_208 },
- { __PHYSFS_ARRAYLEN(case_fold_209), case_fold_209 },
- { __PHYSFS_ARRAYLEN(case_fold_210), case_fold_210 },
- { __PHYSFS_ARRAYLEN(case_fold_211), case_fold_211 },
- { __PHYSFS_ARRAYLEN(case_fold_212), case_fold_212 },
- { __PHYSFS_ARRAYLEN(case_fold_213), case_fold_213 },
- { __PHYSFS_ARRAYLEN(case_fold_214), case_fold_214 },
- { __PHYSFS_ARRAYLEN(case_fold_215), case_fold_215 },
- { __PHYSFS_ARRAYLEN(case_fold_216), case_fold_216 },
- { __PHYSFS_ARRAYLEN(case_fold_217), case_fold_217 },
- { __PHYSFS_ARRAYLEN(case_fold_218), case_fold_218 },
- { __PHYSFS_ARRAYLEN(case_fold_219), case_fold_219 },
- { __PHYSFS_ARRAYLEN(case_fold_220), case_fold_220 },
- { __PHYSFS_ARRAYLEN(case_fold_221), case_fold_221 },
- { __PHYSFS_ARRAYLEN(case_fold_222), case_fold_222 },
- { __PHYSFS_ARRAYLEN(case_fold_223), case_fold_223 },
- { __PHYSFS_ARRAYLEN(case_fold_224), case_fold_224 },
- { __PHYSFS_ARRAYLEN(case_fold_225), case_fold_225 },
- { __PHYSFS_ARRAYLEN(case_fold_226), case_fold_226 },
- { __PHYSFS_ARRAYLEN(case_fold_227), case_fold_227 },
- { __PHYSFS_ARRAYLEN(case_fold_228), case_fold_228 },
- { __PHYSFS_ARRAYLEN(case_fold_229), case_fold_229 },
- { __PHYSFS_ARRAYLEN(case_fold_230), case_fold_230 },
- { __PHYSFS_ARRAYLEN(case_fold_231), case_fold_231 },
- { __PHYSFS_ARRAYLEN(case_fold_232), case_fold_232 },
- { __PHYSFS_ARRAYLEN(case_fold_233), case_fold_233 },
- { __PHYSFS_ARRAYLEN(case_fold_234), case_fold_234 },
- { __PHYSFS_ARRAYLEN(case_fold_235), case_fold_235 },
- { __PHYSFS_ARRAYLEN(case_fold_236), case_fold_236 },
- { __PHYSFS_ARRAYLEN(case_fold_237), case_fold_237 },
- { __PHYSFS_ARRAYLEN(case_fold_238), case_fold_238 },
- { __PHYSFS_ARRAYLEN(case_fold_239), case_fold_239 },
- { __PHYSFS_ARRAYLEN(case_fold_240), case_fold_240 },
- { __PHYSFS_ARRAYLEN(case_fold_241), case_fold_241 },
- { __PHYSFS_ARRAYLEN(case_fold_242), case_fold_242 },
- { __PHYSFS_ARRAYLEN(case_fold_243), case_fold_243 },
- { __PHYSFS_ARRAYLEN(case_fold_244), case_fold_244 },
- { __PHYSFS_ARRAYLEN(case_fold_245), case_fold_245 },
- { __PHYSFS_ARRAYLEN(case_fold_246), case_fold_246 },
- { __PHYSFS_ARRAYLEN(case_fold_247), case_fold_247 },
- { __PHYSFS_ARRAYLEN(case_fold_248), case_fold_248 },
- { __PHYSFS_ARRAYLEN(case_fold_249), case_fold_249 },
- { __PHYSFS_ARRAYLEN(case_fold_250), case_fold_250 },
- { __PHYSFS_ARRAYLEN(case_fold_251), case_fold_251 },
- { __PHYSFS_ARRAYLEN(case_fold_252), case_fold_252 },
- { __PHYSFS_ARRAYLEN(case_fold_253), case_fold_253 },
- { __PHYSFS_ARRAYLEN(case_fold_254), case_fold_254 },
- { __PHYSFS_ARRAYLEN(case_fold_255), case_fold_255 },
-};
-
+++ /dev/null
-/*
- * Internal function/structure declaration. Do NOT include in your
- * application.
- *
- * Please see the file LICENSE.txt in the source's root directory.
- *
- * This file written by Ryan C. Gordon.
- */
-
-#ifndef _INCLUDE_PHYSFS_INTERNAL_H_
-#define _INCLUDE_PHYSFS_INTERNAL_H_
-
-#ifndef __PHYSICSFS_INTERNAL__
-#error Do not include this header from your applications.
-#endif
-
-#include "physfs.h"
-
-#include <stdlib.h> /* make sure NULL is defined... */
-
-#ifdef HAVE_ASSERT_H
-#include <assert.h>
-#elif (!defined assert)
-#define assert(x)
-#endif
-
-/* !!! FIXME: remove this when revamping stack allocation code... */
-#ifdef _MSC_VER
-#include <malloc.h>
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- * Interface for small allocations. If you need a little scratch space for
- * a throwaway buffer or string, use this. It will make small allocations
- * on the stack if possible, and use allocator.Malloc() if they are too
- * large. This helps reduce malloc pressure.
- * There are some rules, though:
- * NEVER return a pointer from this, as stack-allocated buffers go away
- * when your function returns.
- * NEVER allocate in a loop, as stack-allocated pointers will pile up. Call
- * a function that uses smallAlloc from your loop, so the allocation can
- * free each time.
- * NEVER call smallAlloc with any complex expression (it's a macro that WILL
- * have side effects...it references the argument multiple times). Use a
- * variable or a literal.
- * NEVER free a pointer from this with anything but smallFree. It will not
- * be a valid pointer to the allocator, regardless of where the memory came
- * from.
- * NEVER realloc a pointer from this.
- * NEVER forget to use smallFree: it may not be a pointer from the stack.
- * NEVER forget to check for NULL...allocation can fail here, of course!
- */
-#define __PHYSFS_SMALLALLOCTHRESHOLD 128
-void *__PHYSFS_initSmallAlloc(void *ptr, PHYSFS_uint64 len);
-
-#define __PHYSFS_smallAlloc(bytes) ( \
- __PHYSFS_initSmallAlloc((((bytes) < __PHYSFS_SMALLALLOCTHRESHOLD) ? \
- alloca((size_t)((bytes)+1)) : NULL), (bytes)) \
-)
-
-void __PHYSFS_smallFree(void *ptr);
-
-
-/* Use the allocation hooks. */
-#define malloc(x) Do not use malloc() directly.
-#define realloc(x, y) Do not use realloc() directly.
-#define free(x) Do not use free() directly.
-/* !!! FIXME: add alloca check here. */
-
-/* The LANG section. */
-/* please send questions/translations to Ryan: icculus@icculus.org. */
-
-#if (!defined PHYSFS_LANG)
-# define PHYSFS_LANG PHYSFS_LANG_ENGLISH
-#endif
-
-#define PHYSFS_LANG_ENGLISH 1 /* English by Ryan C. Gordon */
-#define PHYSFS_LANG_RUSSIAN_KOI8_R 2 /* Russian by Ed Sinjiashvili */
-#define PHYSFS_LANG_RUSSIAN_CP1251 3 /* Russian by Ed Sinjiashvili */
-#define PHYSFS_LANG_RUSSIAN_CP866 4 /* Russian by Ed Sinjiashvili */
-#define PHYSFS_LANG_RUSSIAN_ISO_8859_5 5 /* Russian by Ed Sinjiashvili */
-#define PHYSFS_LANG_SPANISH 6 /* Spanish by Pedro J. Pérez */
-#define PHYSFS_LANG_FRENCH 7 /* French by Stéphane Peter */
-#define PHYSFS_LANG_GERMAN 8 /* German by Michael Renner */
-#define PHYSFS_LANG_PORTUGUESE_BR 9 /* pt-br by Danny Angelo Carminati Grein */
-
-#if (PHYSFS_LANG == PHYSFS_LANG_ENGLISH)
- #define DIR_ARCHIVE_DESCRIPTION "Non-archive, direct filesystem I/O"
- #define GRP_ARCHIVE_DESCRIPTION "Build engine Groupfile format"
- #define HOG_ARCHIVE_DESCRIPTION "Descent I/II HOG file format"
- #define MVL_ARCHIVE_DESCRIPTION "Descent II Movielib format"
- #define QPAK_ARCHIVE_DESCRIPTION "Quake I/II format"
- #define ZIP_ARCHIVE_DESCRIPTION "PkZip/WinZip/Info-Zip compatible"
- #define WAD_ARCHIVE_DESCRIPTION "DOOM engine format"
- #define LZMA_ARCHIVE_DESCRIPTION "LZMA (7zip) format"
-
- #define ERR_IS_INITIALIZED "Already initialized"
- #define ERR_NOT_INITIALIZED "Not initialized"
- #define ERR_INVALID_ARGUMENT "Invalid argument"
- #define ERR_FILES_STILL_OPEN "Files still open"
- #define ERR_NO_DIR_CREATE "Failed to create directories"
- #define ERR_OUT_OF_MEMORY "Out of memory"
- #define ERR_NOT_IN_SEARCH_PATH "No such entry in search path"
- #define ERR_NOT_SUPPORTED "Operation not supported"
- #define ERR_UNSUPPORTED_ARCHIVE "Archive type unsupported"
- #define ERR_NOT_A_HANDLE "Not a file handle"
- #define ERR_INSECURE_FNAME "Insecure filename"
- #define ERR_SYMLINK_DISALLOWED "Symbolic links are disabled"
- #define ERR_NO_WRITE_DIR "Write directory is not set"
- #define ERR_NO_SUCH_FILE "File not found"
- #define ERR_NO_SUCH_PATH "Path not found"
- #define ERR_NO_SUCH_VOLUME "Volume not found"
- #define ERR_PAST_EOF "Past end of file"
- #define ERR_ARC_IS_READ_ONLY "Archive is read-only"
- #define ERR_IO_ERROR "I/O error"
- #define ERR_CANT_SET_WRITE_DIR "Can't set write directory"
- #define ERR_SYMLINK_LOOP "Infinite symbolic link loop"
- #define ERR_COMPRESSION "(De)compression error"
- #define ERR_NOT_IMPLEMENTED "Not implemented"
- #define ERR_OS_ERROR "Operating system reported error"
- #define ERR_FILE_EXISTS "File already exists"
- #define ERR_NOT_A_FILE "Not a file"
- #define ERR_NOT_A_DIR "Not a directory"
- #define ERR_NOT_AN_ARCHIVE "Not an archive"
- #define ERR_CORRUPTED "Corrupted archive"
- #define ERR_SEEK_OUT_OF_RANGE "Seek out of range"
- #define ERR_BAD_FILENAME "Bad filename"
- #define ERR_PHYSFS_BAD_OS_CALL "(BUG) PhysicsFS made a bad system call"
- #define ERR_ARGV0_IS_NULL "argv0 is NULL"
- #define ERR_NEED_DICT "need dictionary"
- #define ERR_DATA_ERROR "data error"
- #define ERR_MEMORY_ERROR "memory error"
- #define ERR_BUFFER_ERROR "buffer error"
- #define ERR_VERSION_ERROR "version error"
- #define ERR_UNKNOWN_ERROR "unknown error"
- #define ERR_SEARCHPATH_TRUNC "Search path was truncated"
- #define ERR_GETMODFN_TRUNC "GetModuleFileName() was truncated"
- #define ERR_GETMODFN_NO_DIR "GetModuleFileName() had no dir"
- #define ERR_DISK_FULL "Disk is full"
- #define ERR_DIRECTORY_FULL "Directory full"
- #define ERR_MACOS_GENERIC "MacOS reported error (%d)"
- #define ERR_OS2_GENERIC "OS/2 reported error (%d)"
- #define ERR_VOL_LOCKED_HW "Volume is locked through hardware"
- #define ERR_VOL_LOCKED_SW "Volume is locked through software"
- #define ERR_FILE_LOCKED "File is locked"
- #define ERR_FILE_OR_DIR_BUSY "File/directory is busy"
- #define ERR_FILE_ALREADY_OPEN_W "File already open for writing"
- #define ERR_FILE_ALREADY_OPEN_R "File already open for reading"
- #define ERR_INVALID_REFNUM "Invalid reference number"
- #define ERR_GETTING_FILE_POS "Error getting file position"
- #define ERR_VOLUME_OFFLINE "Volume is offline"
- #define ERR_PERMISSION_DENIED "Permission denied"
- #define ERR_VOL_ALREADY_ONLINE "Volume already online"
- #define ERR_NO_SUCH_DRIVE "No such drive"
- #define ERR_NOT_MAC_DISK "Not a Macintosh disk"
- #define ERR_VOL_EXTERNAL_FS "Volume belongs to an external filesystem"
- #define ERR_PROBLEM_RENAME "Problem during rename"
- #define ERR_BAD_MASTER_BLOCK "Bad master directory block"
- #define ERR_CANT_MOVE_FORBIDDEN "Attempt to move forbidden"
- #define ERR_WRONG_VOL_TYPE "Wrong volume type"
- #define ERR_SERVER_VOL_LOST "Server volume has been disconnected"
- #define ERR_FILE_ID_NOT_FOUND "File ID not found"
- #define ERR_FILE_ID_EXISTS "File ID already exists"
- #define ERR_SERVER_NO_RESPOND "Server not responding"
- #define ERR_USER_AUTH_FAILED "User authentication failed"
- #define ERR_PWORD_EXPIRED "Password has expired on server"
- #define ERR_ACCESS_DENIED "Access denied"
- #define ERR_NOT_A_DOS_DISK "Not a DOS disk"
- #define ERR_SHARING_VIOLATION "Sharing violation"
- #define ERR_CANNOT_MAKE "Cannot make"
- #define ERR_DEV_IN_USE "Device already in use"
- #define ERR_OPEN_FAILED "Open failed"
- #define ERR_PIPE_BUSY "Pipe is busy"
- #define ERR_SHARING_BUF_EXCEEDED "Sharing buffer exceeded"
- #define ERR_TOO_MANY_HANDLES "Too many open handles"
- #define ERR_SEEK_ERROR "Seek error"
- #define ERR_DEL_CWD "Trying to delete current working directory"
- #define ERR_WRITE_PROTECT_ERROR "Write protect error"
- #define ERR_WRITE_FAULT "Write fault"
- #define ERR_LOCK_VIOLATION "Lock violation"
- #define ERR_GEN_FAILURE "General failure"
- #define ERR_UNCERTAIN_MEDIA "Uncertain media"
- #define ERR_PROT_VIOLATION "Protection violation"
- #define ERR_BROKEN_PIPE "Broken pipe"
-
-#elif (PHYSFS_LANG == PHYSFS_LANG_GERMAN)
- #define DIR_ARCHIVE_DESCRIPTION "Kein Archiv, direkte Ein/Ausgabe in das Dateisystem"
- #define GRP_ARCHIVE_DESCRIPTION "Build engine Groupfile format"
- #define HOG_ARCHIVE_DESCRIPTION "Descent I/II HOG file format"
- #define MVL_ARCHIVE_DESCRIPTION "Descent II Movielib format"
- #define QPAK_ARCHIVE_DESCRIPTION "Quake I/II format"
- #define ZIP_ARCHIVE_DESCRIPTION "PkZip/WinZip/Info-Zip kompatibel"
- #define WAD_ARCHIVE_DESCRIPTION "DOOM engine format" /* !!! FIXME: translate this line if needed */
- #define LZMA_ARCHIVE_DESCRIPTION "LZMA (7zip) format" /* !!! FIXME: translate this line if needed */
-
- #define ERR_IS_INITIALIZED "Bereits initialisiert"
- #define ERR_NOT_INITIALIZED "Nicht initialisiert"
- #define ERR_INVALID_ARGUMENT "Ungültiges Argument"
- #define ERR_FILES_STILL_OPEN "Dateien noch immer geöffnet"
- #define ERR_NO_DIR_CREATE "Fehler beim Erzeugen der Verzeichnisse"
- #define ERR_OUT_OF_MEMORY "Kein Speicher mehr frei"
- #define ERR_NOT_IN_SEARCH_PATH "Eintrag nicht im Suchpfad enthalten"
- #define ERR_NOT_SUPPORTED "Befehl nicht unterstützt"
- #define ERR_UNSUPPORTED_ARCHIVE "Archiv-Typ nicht unterstützt"
- #define ERR_NOT_A_HANDLE "Ist kein Dateideskriptor"
- #define ERR_INSECURE_FNAME "Unsicherer Dateiname"
- #define ERR_SYMLINK_DISALLOWED "Symbolische Verweise deaktiviert"
- #define ERR_NO_WRITE_DIR "Schreibverzeichnis ist nicht gesetzt"
- #define ERR_NO_SUCH_FILE "Datei nicht gefunden"
- #define ERR_NO_SUCH_PATH "Pfad nicht gefunden"
- #define ERR_NO_SUCH_VOLUME "Datencontainer nicht gefunden"
- #define ERR_PAST_EOF "Hinter dem Ende der Datei"
- #define ERR_ARC_IS_READ_ONLY "Archiv ist schreibgeschützt"
- #define ERR_IO_ERROR "Ein/Ausgabe Fehler"
- #define ERR_CANT_SET_WRITE_DIR "Kann Schreibverzeichnis nicht setzen"
- #define ERR_SYMLINK_LOOP "Endlosschleife durch symbolische Verweise"
- #define ERR_COMPRESSION "(De)Kompressionsfehler"
- #define ERR_NOT_IMPLEMENTED "Nicht implementiert"
- #define ERR_OS_ERROR "Betriebssystem meldete Fehler"
- #define ERR_FILE_EXISTS "Datei existiert bereits"
- #define ERR_NOT_A_FILE "Ist keine Datei"
- #define ERR_NOT_A_DIR "Ist kein Verzeichnis"
- #define ERR_NOT_AN_ARCHIVE "Ist kein Archiv"
- #define ERR_CORRUPTED "Beschädigtes Archiv"
- #define ERR_SEEK_OUT_OF_RANGE "Suche war ausserhalb der Reichweite"
- #define ERR_BAD_FILENAME "Unzulässiger Dateiname"
- #define ERR_PHYSFS_BAD_OS_CALL "(BUG) PhysicsFS verursachte einen ungültigen Systemaufruf"
- #define ERR_ARGV0_IS_NULL "argv0 ist NULL"
- #define ERR_NEED_DICT "brauche Wörterbuch"
- #define ERR_DATA_ERROR "Datenfehler"
- #define ERR_MEMORY_ERROR "Speicherfehler"
- #define ERR_BUFFER_ERROR "Bufferfehler"
- #define ERR_VERSION_ERROR "Versionskonflikt"
- #define ERR_UNKNOWN_ERROR "Unbekannter Fehler"
- #define ERR_SEARCHPATH_TRUNC "Suchpfad war abgeschnitten"
- #define ERR_GETMODFN_TRUNC "GetModuleFileName() war abgeschnitten"
- #define ERR_GETMODFN_NO_DIR "GetModuleFileName() bekam kein Verzeichnis"
- #define ERR_DISK_FULL "Laufwerk ist voll"
- #define ERR_DIRECTORY_FULL "Verzeichnis ist voll"
- #define ERR_MACOS_GENERIC "MacOS meldete Fehler (%d)"
- #define ERR_OS2_GENERIC "OS/2 meldete Fehler (%d)"
- #define ERR_VOL_LOCKED_HW "Datencontainer ist durch Hardware gesperrt"
- #define ERR_VOL_LOCKED_SW "Datencontainer ist durch Software gesperrt"
- #define ERR_FILE_LOCKED "Datei ist gesperrt"
- #define ERR_FILE_OR_DIR_BUSY "Datei/Verzeichnis ist beschäftigt"
- #define ERR_FILE_ALREADY_OPEN_W "Datei schon im Schreibmodus geöffnet"
- #define ERR_FILE_ALREADY_OPEN_R "Datei schon im Lesemodus geöffnet"
- #define ERR_INVALID_REFNUM "Ungültige Referenznummer"
- #define ERR_GETTING_FILE_POS "Fehler beim Finden der Dateiposition"
- #define ERR_VOLUME_OFFLINE "Datencontainer ist offline"
- #define ERR_PERMISSION_DENIED "Zugriff verweigert"
- #define ERR_VOL_ALREADY_ONLINE "Datencontainer ist bereits online"
- #define ERR_NO_SUCH_DRIVE "Laufwerk nicht vorhanden"
- #define ERR_NOT_MAC_DISK "Ist kein Macintosh Laufwerk"
- #define ERR_VOL_EXTERNAL_FS "Datencontainer liegt auf einem externen Dateisystem"
- #define ERR_PROBLEM_RENAME "Fehler beim Umbenennen"
- #define ERR_BAD_MASTER_BLOCK "Beschädigter Hauptverzeichnisblock"
- #define ERR_CANT_MOVE_FORBIDDEN "Verschieben nicht erlaubt"
- #define ERR_WRONG_VOL_TYPE "Falscher Datencontainer-Typ"
- #define ERR_SERVER_VOL_LOST "Datencontainer am Server wurde getrennt"
- #define ERR_FILE_ID_NOT_FOUND "Dateikennung nicht gefunden"
- #define ERR_FILE_ID_EXISTS "Dateikennung existiert bereits"
- #define ERR_SERVER_NO_RESPOND "Server antwortet nicht"
- #define ERR_USER_AUTH_FAILED "Benutzerauthentifizierung fehlgeschlagen"
- #define ERR_PWORD_EXPIRED "Passwort am Server ist abgelaufen"
- #define ERR_ACCESS_DENIED "Zugriff verweigert"
- #define ERR_NOT_A_DOS_DISK "Ist kein DOS-Laufwerk"
- #define ERR_SHARING_VIOLATION "Zugriffsverletzung"
- #define ERR_CANNOT_MAKE "Kann nicht erzeugen"
- #define ERR_DEV_IN_USE "Gerät wird bereits benutzt"
- #define ERR_OPEN_FAILED "Öffnen fehlgeschlagen"
- #define ERR_PIPE_BUSY "Pipeverbindung ist belegt"
- #define ERR_SHARING_BUF_EXCEEDED "Zugriffsbuffer überschritten"
- #define ERR_TOO_MANY_HANDLES "Zu viele offene Dateien"
- #define ERR_SEEK_ERROR "Fehler beim Suchen"
- #define ERR_DEL_CWD "Aktuelles Arbeitsverzeichnis darf nicht gelöscht werden"
- #define ERR_WRITE_PROTECT_ERROR "Schreibschutzfehler"
- #define ERR_WRITE_FAULT "Schreibfehler"
- #define ERR_LOCK_VIOLATION "Sperrverletzung"
- #define ERR_GEN_FAILURE "Allgemeiner Fehler"
- #define ERR_UNCERTAIN_MEDIA "Unsicheres Medium"
- #define ERR_PROT_VIOLATION "Schutzverletzung"
- #define ERR_BROKEN_PIPE "Pipeverbindung unterbrochen"
-
-#elif (PHYSFS_LANG == PHYSFS_LANG_RUSSIAN_KOI8_R)
- #define DIR_ARCHIVE_DESCRIPTION "îÅ ÁÒÈÉ×, ÎÅÐÏÓÒÅÄÓÔ×ÅÎÎÙÊ ××ÏÄ/×Ù×ÏÄ ÆÁÊÌÏ×ÏÊ ÓÉÓÔÅÍÙ"
- #define GRP_ARCHIVE_DESCRIPTION "æÏÒÍÁÔ ÇÒÕÐÐÏ×ÏÇÏ ÆÁÊÌÁ Build engine"
- #define HOG_ARCHIVE_DESCRIPTION "Descent I/II HOG file format"
- #define MVL_ARCHIVE_DESCRIPTION "Descent II Movielib format"
- #define ZIP_ARCHIVE_DESCRIPTION "PkZip/WinZip/Info-Zip ÓÏ×ÍÅÓÔÉÍÙÊ"
- #define WAD_ARCHIVE_DESCRIPTION "DOOM engine format" /* !!! FIXME: translate this line if needed */
- #define LZMA_ARCHIVE_DESCRIPTION "LZMA (7zip) format" /* !!! FIXME: translate this line if needed */
-
- #define ERR_IS_INITIALIZED "õÖÅ ÉÎÉÃÉÁÌÉÚÉÒÏ×ÁÎ"
- #define ERR_NOT_INITIALIZED "îÅ ÉÎÉÃÉÁÌÉÚÉÒÏ×ÁÎ"
- #define ERR_INVALID_ARGUMENT "îÅ×ÅÒÎÙÊ ÁÒÇÕÍÅÎÔ"
- #define ERR_FILES_STILL_OPEN "æÁÊÌÙ ÅÝÅ ÏÔËÒÙÔÙ"
- #define ERR_NO_DIR_CREATE "îÅ ÍÏÇÕ ÓÏÚÄÁÔØ ËÁÔÁÌÏÇÉ"
- #define ERR_OUT_OF_MEMORY "ëÏÎÞÉÌÁÓØ ÐÁÍÑÔØ"
- #define ERR_NOT_IN_SEARCH_PATH "îÅÔ ÔÁËÏÇÏ ÜÌÅÍÅÎÔÁ × ÐÕÔÉ ÐÏÉÓËÁ"
- #define ERR_NOT_SUPPORTED "ïÐÅÒÁÃÉÑ ÎÅ ÐÏÄÄÅÒÖÉ×ÁÅÔÓÑ"
- #define ERR_UNSUPPORTED_ARCHIVE "áÒÈÉ×Ù ÔÁËÏÇÏ ÔÉÐÁ ÎÅ ÐÏÄÄÅÒÖÉ×ÁÀÔÓÑ"
- #define ERR_NOT_A_HANDLE "îÅ ÆÁÊÌÏ×ÙÊ ÄÅÓËÒÉÐÔÏÒ"
- #define ERR_INSECURE_FNAME "îÅÂÅÚÏÐÁÓÎÏÅ ÉÍÑ ÆÁÊÌÁ"
- #define ERR_SYMLINK_DISALLOWED "óÉÍ×ÏÌØÎÙÅ ÓÓÙÌËÉ ÏÔËÌÀÞÅÎÙ"
- #define ERR_NO_WRITE_DIR "ëÁÔÁÌÏÇ ÄÌÑ ÚÁÐÉÓÉ ÎÅ ÕÓÔÁÎÏ×ÌÅÎ"
- #define ERR_NO_SUCH_FILE "æÁÊÌ ÎÅ ÎÁÊÄÅÎ"
- #define ERR_NO_SUCH_PATH "ðÕÔØ ÎÅ ÎÁÊÄÅÎ"
- #define ERR_NO_SUCH_VOLUME "ôÏÍ ÎÅ ÎÁÊÄÅÎ"
- #define ERR_PAST_EOF "úÁ ËÏÎÃÏÍ ÆÁÊÌÁ"
- #define ERR_ARC_IS_READ_ONLY "áÒÈÉ× ÔÏÌØËÏ ÄÌÑ ÞÔÅÎÉÑ"
- #define ERR_IO_ERROR "ïÛÉÂËÁ ××ÏÄÁ/×Ù×ÏÄÁ"
- #define ERR_CANT_SET_WRITE_DIR "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ËÁÔÁÌÏÇ ÄÌÑ ÚÁÐÉÓÉ"
- #define ERR_SYMLINK_LOOP "âÅÓËÏÎÅÞÎÙÊ ÃÉËÌ ÓÉÍ×ÏÌØÎÏÊ ÓÓÙÌËÉ"
- #define ERR_COMPRESSION "ïÛÉÂËÁ (òÁÓ)ÐÁËÏ×ËÉ"
- #define ERR_NOT_IMPLEMENTED "îÅ ÒÅÁÌÉÚÏ×ÁÎÏ"
- #define ERR_OS_ERROR "ïÐÅÒÁÃÉÏÎÎÁÑ ÓÉÓÔÅÍÁ ÓÏÏÂÝÉÌÁ ÏÛÉÂËÕ"
- #define ERR_FILE_EXISTS "æÁÊÌ ÕÖÅ ÓÕÝÅÓÔ×ÕÅÔ"
- #define ERR_NOT_A_FILE "îÅ ÆÁÊÌ"
- #define ERR_NOT_A_DIR "îÅ ËÁÔÁÌÏÇ"
- #define ERR_NOT_AN_ARCHIVE "îÅ ÁÒÈÉ×"
- #define ERR_CORRUPTED "ðÏ×ÒÅÖÄÅÎÎÙÊ ÁÒÈÉ×"
- #define ERR_SEEK_OUT_OF_RANGE "ðÏÚÉÃÉÏÎÉÒÏ×ÁÎÉÅ ÚÁ ÐÒÅÄÅÌÙ"
- #define ERR_BAD_FILENAME "îÅ×ÅÒÎÏÅ ÉÍÑ ÆÁÊÌÁ"
- #define ERR_PHYSFS_BAD_OS_CALL "(BUG) PhysicsFS ×ÙÐÏÌÎÉÌÁ ÎÅ×ÅÒÎÙÊ ÓÉÓÔÅÍÎÙÊ ×ÙÚÏ×"
- #define ERR_ARGV0_IS_NULL "argv0 is NULL"
- #define ERR_NEED_DICT "ÎÕÖÅÎ ÓÌÏ×ÁÒØ"
- #define ERR_DATA_ERROR "ÏÛÉÂËÁ ÄÁÎÎÙÈ"
- #define ERR_MEMORY_ERROR "ÏÛÉÂËÁ ÐÁÍÑÔÉ"
- #define ERR_BUFFER_ERROR "ÏÛÉÂËÁ ÂÕÆÅÒÁ"
- #define ERR_VERSION_ERROR "ÏÛÉÂËÁ ×ÅÒÓÉÉ"
- #define ERR_UNKNOWN_ERROR "ÎÅÉÚ×ÅÓÔÎÁÑ ÏÛÉÂËÁ"
- #define ERR_SEARCHPATH_TRUNC "ðÕÔØ ÐÏÉÓËÁ ÏÂÒÅÚÁÎ"
- #define ERR_GETMODFN_TRUNC "GetModuleFileName() ÏÂÒÅÚÁÎ"
- #define ERR_GETMODFN_NO_DIR "GetModuleFileName() ÎÅ ÐÏÌÕÞÉÌ ËÁÔÁÌÏÇ"
- #define ERR_DISK_FULL "äÉÓË ÐÏÌÏÎ"
- #define ERR_DIRECTORY_FULL "ëÁÔÁÌÏÇ ÐÏÌÏÎ"
- #define ERR_MACOS_GENERIC "MacOS ÓÏÏÂÝÉÌÁ ÏÛÉÂËÕ (%d)"
- #define ERR_OS2_GENERIC "OS/2 ÓÏÏÂÝÉÌÁ ÏÛÉÂËÕ (%d)"
- #define ERR_VOL_LOCKED_HW "ôÏÍ ÂÌÏËÉÒÏ×ÁÎ ÁÐÐÁÒÁÔÎÏ"
- #define ERR_VOL_LOCKED_SW "ôÏÍ ÂÌÏËÉÒÏ×ÁÎ ÐÒÏÇÒÁÍÍÎÏ"
- #define ERR_FILE_LOCKED "æÁÊÌ ÚÁÂÌÏËÉÒÏ×ÁÎ"
- #define ERR_FILE_OR_DIR_BUSY "æÁÊÌ/ËÁÔÁÌÏÇ ÚÁÎÑÔ"
- #define ERR_FILE_ALREADY_OPEN_W "æÁÊÌ ÕÖÅ ÏÔËÒÙÔ ÎÁ ÚÁÐÉÓØ"
- #define ERR_FILE_ALREADY_OPEN_R "æÁÊÌ ÕÖÅ ÏÔËÒÙÔ ÎÁ ÞÔÅÎÉÅ"
- #define ERR_INVALID_REFNUM "îÅ×ÅÒÎÏÅ ËÏÌÉÞÅÓÔ×Ï ÓÓÙÌÏË"
- #define ERR_GETTING_FILE_POS "ïÛÉÂËÁ ÐÒÉ ÐÏÌÕÞÅÎÉÉ ÐÏÚÉÃÉÉ ÆÁÊÌÁ"
- #define ERR_VOLUME_OFFLINE "ôÏÍ ÏÔÓÏÅÄÉÎÅÎ"
- #define ERR_PERMISSION_DENIED "ïÔËÁÚÁÎÏ × ÒÁÚÒÅÛÅÎÉÉ"
- #define ERR_VOL_ALREADY_ONLINE "ôÏÍ ÕÖÅ ÐÏÄÓÏÅÄÉÎÅÎ"
- #define ERR_NO_SUCH_DRIVE "îÅÔ ÔÁËÏÇÏ ÄÉÓËÁ"
- #define ERR_NOT_MAC_DISK "îÅ ÄÉÓË Macintosh"
- #define ERR_VOL_EXTERNAL_FS "ôÏÍ ÐÒÉÎÁÄÌÅÖÉÔ ×ÎÅÛÎÅÊ ÆÁÊÌÏ×ÏÊ ÓÉÓÔÅÍÅ"
- #define ERR_PROBLEM_RENAME "ðÒÏÂÌÅÍÁ ÐÒÉ ÐÅÒÅÉÍÅÎÏ×ÁÎÉÉ"
- #define ERR_BAD_MASTER_BLOCK "ðÌÏÈÏÊ ÇÌÁ×ÎÙÊ ÂÌÏË ËÁÔÁÌÏÇÁ"
- #define ERR_CANT_MOVE_FORBIDDEN "ðÏÐÙÔËÁ ÐÅÒÅÍÅÓÔÉÔØ ÚÁÐÒÅÝÅÎÁ"
- #define ERR_WRONG_VOL_TYPE "îÅ×ÅÒÎÙÊ ÔÉÐ ÔÏÍÁ"
- #define ERR_SERVER_VOL_LOST "óÅÒ×ÅÒÎÙÊ ÔÏÍ ÂÙÌ ÏÔÓÏÅÄÉÎÅÎ"
- #define ERR_FILE_ID_NOT_FOUND "éÄÅÎÔÉÆÉËÁÔÏÒ ÆÁÊÌÁ ÎÅ ÎÁÊÄÅÎ"
- #define ERR_FILE_ID_EXISTS "éÄÅÎÔÉÆÉËÁÔÏÒ ÆÁÊÌÁ ÕÖÅ ÓÕÝÅÓÔ×ÕÅÔ"
- #define ERR_SERVER_NO_RESPOND "óÅÒ×ÅÒ ÎÅ ÏÔ×ÅÞÁÅÔ"
- #define ERR_USER_AUTH_FAILED "éÄÅÎÔÉÆÉËÁÃÉÑ ÐÏÌØÚÏ×ÁÔÅÌÑ ÎÅ ÕÄÁÌÁÓØ"
- #define ERR_PWORD_EXPIRED "ðÁÒÏÌØ ÎÁ ÓÅÒ×ÅÒÅ ÕÓÔÁÒÅÌ"
- #define ERR_ACCESS_DENIED "ïÔËÁÚÁÎÏ × ÄÏÓÔÕÐÅ"
- #define ERR_NOT_A_DOS_DISK "îÅ ÄÉÓË DOS"
- #define ERR_SHARING_VIOLATION "îÁÒÕÛÅÎÉÅ ÓÏ×ÍÅÓÔÎÏÇÏ ÄÏÓÔÕÐÁ"
- #define ERR_CANNOT_MAKE "îÅ ÍÏÇÕ ÓÏÂÒÁÔØ"
- #define ERR_DEV_IN_USE "õÓÔÒÏÊÓÔ×Ï ÕÖÅ ÉÓÐÏÌØÚÕÅÔÓÑ"
- #define ERR_OPEN_FAILED "ïÔËÒÙÔÉÅ ÎÅ ÕÄÁÌÏÓØ"
- #define ERR_PIPE_BUSY "ëÏÎ×ÅÊÅÒ ÚÁÎÑÔ"
- #define ERR_SHARING_BUF_EXCEEDED "òÁÚÄÅÌÑÅÍÙÊ ÂÕÆÅÒ ÐÅÒÅÐÏÌÎÅÎ"
- #define ERR_TOO_MANY_HANDLES "óÌÉÛËÏÍ ÍÎÏÇÏ ÏÔËÒÙÔÙÈ ÄÅÓËÒÉÐÔÏÒÏ×"
- #define ERR_SEEK_ERROR "ïÛÉÂËÁ ÐÏÚÉÃÉÏÎÉÒÏ×ÁÎÉÑ"
- #define ERR_DEL_CWD "ðÏÐÙÔËÁ ÕÄÁÌÉÔØ ÔÅËÕÝÉÊ ÒÁÂÏÞÉÊ ËÁÔÁÌÏÇ"
- #define ERR_WRITE_PROTECT_ERROR "ïÛÉÂËÁ ÚÁÝÉÔÙ ÚÁÐÉÓÉ"
- #define ERR_WRITE_FAULT "ïÛÉÂËÁ ÚÁÐÉÓÉ"
- #define ERR_LOCK_VIOLATION "îÁÒÕÛÅÎÉÅ ÂÌÏËÉÒÏ×ËÉ"
- #define ERR_GEN_FAILURE "ïÂÝÉÊ ÓÂÏÊ"
- #define ERR_UNCERTAIN_MEDIA "îÅÏÐÒÅÄÅÌÅÎÎÙÊ ÎÏÓÉÔÅÌØ"
- #define ERR_PROT_VIOLATION "îÁÒÕÛÅÎÉÅ ÚÁÝÉÔÙ"
- #define ERR_BROKEN_PIPE "óÌÏÍÁÎÎÙÊ ËÏÎ×ÅÊÅÒ"
-
-#elif (PHYSFS_LANG == PHYSFS_LANG_RUSSIAN_CP1251)
- #define DIR_ARCHIVE_DESCRIPTION "Íå àðõèâ, íåïîñðåäñòâåííûé ââîä/âûâîä ôàéëîâîé ñèñòåìû"
- #define GRP_ARCHIVE_DESCRIPTION "Ôîðìàò ãðóïïîâîãî ôàéëà Build engine"
- #define HOG_ARCHIVE_DESCRIPTION "Descent I/II HOG file format"
- #define MVL_ARCHIVE_DESCRIPTION "Descent II Movielib format"
- #define ZIP_ARCHIVE_DESCRIPTION "PkZip/WinZip/Info-Zip ñîâìåñòèìûé"
- #define WAD_ARCHIVE_DESCRIPTION "DOOM engine format" /* !!! FIXME: translate this line if needed */
- #define LZMA_ARCHIVE_DESCRIPTION "LZMA (7zip) format" /* !!! FIXME: translate this line if needed */
-
- #define ERR_IS_INITIALIZED "Óæå èíèöèàëèçèðîâàí"
- #define ERR_NOT_INITIALIZED "Íå èíèöèàëèçèðîâàí"
- #define ERR_INVALID_ARGUMENT "Íåâåðíûé àðãóìåíò"
- #define ERR_FILES_STILL_OPEN "Ôàéëû åùå îòêðûòû"
- #define ERR_NO_DIR_CREATE "Íå ìîãó ñîçäàòü êàòàëîãè"
- #define ERR_OUT_OF_MEMORY "Êîí÷èëàñü ïàìÿòü"
- #define ERR_NOT_IN_SEARCH_PATH "Íåò òàêîãî ýëåìåíòà â ïóòè ïîèñêà"
- #define ERR_NOT_SUPPORTED "Îïåðàöèÿ íå ïîääåðæèâàåòñÿ"
- #define ERR_UNSUPPORTED_ARCHIVE "Àðõèâû òàêîãî òèïà íå ïîääåðæèâàþòñÿ"
- #define ERR_NOT_A_HANDLE "Íå ôàéëîâûé äåñêðèïòîð"
- #define ERR_INSECURE_FNAME "Íåáåçîïàñíîå èìÿ ôàéëà"
- #define ERR_SYMLINK_DISALLOWED "Ñèìâîëüíûå ññûëêè îòêëþ÷åíû"
- #define ERR_NO_WRITE_DIR "Êàòàëîã äëÿ çàïèñè íå óñòàíîâëåí"
- #define ERR_NO_SUCH_FILE "Ôàéë íå íàéäåí"
- #define ERR_NO_SUCH_PATH "Ïóòü íå íàéäåí"
- #define ERR_NO_SUCH_VOLUME "Òîì íå íàéäåí"
- #define ERR_PAST_EOF "Çà êîíöîì ôàéëà"
- #define ERR_ARC_IS_READ_ONLY "Àðõèâ òîëüêî äëÿ ÷òåíèÿ"
- #define ERR_IO_ERROR "Îøèáêà ââîäà/âûâîäà"
- #define ERR_CANT_SET_WRITE_DIR "Íå ìîãó óñòàíîâèòü êàòàëîã äëÿ çàïèñè"
- #define ERR_SYMLINK_LOOP "Áåñêîíå÷íûé öèêë ñèìâîëüíîé ññûëêè"
- #define ERR_COMPRESSION "Îøèáêà (Ðàñ)ïàêîâêè"
- #define ERR_NOT_IMPLEMENTED "Íå ðåàëèçîâàíî"
- #define ERR_OS_ERROR "Îïåðàöèîííàÿ ñèñòåìà ñîîáùèëà îøèáêó"
- #define ERR_FILE_EXISTS "Ôàéë óæå ñóùåñòâóåò"
- #define ERR_NOT_A_FILE "Íå ôàéë"
- #define ERR_NOT_A_DIR "Íå êàòàëîã"
- #define ERR_NOT_AN_ARCHIVE "Íå àðõèâ"
- #define ERR_CORRUPTED "Ïîâðåæäåííûé àðõèâ"
- #define ERR_SEEK_OUT_OF_RANGE "Ïîçèöèîíèðîâàíèå çà ïðåäåëû"
- #define ERR_BAD_FILENAME "Íåâåðíîå èìÿ ôàéëà"
- #define ERR_PHYSFS_BAD_OS_CALL "(BUG) PhysicsFS âûïîëíèëà íåâåðíûé ñèñòåìíûé âûçîâ"
- #define ERR_ARGV0_IS_NULL "argv0 is NULL"
- #define ERR_NEED_DICT "íóæåí ñëîâàðü"
- #define ERR_DATA_ERROR "îøèáêà äàííûõ"
- #define ERR_MEMORY_ERROR "îøèáêà ïàìÿòè"
- #define ERR_BUFFER_ERROR "îøèáêà áóôåðà"
- #define ERR_VERSION_ERROR "îøèáêà âåðñèè"
- #define ERR_UNKNOWN_ERROR "íåèçâåñòíàÿ îøèáêà"
- #define ERR_SEARCHPATH_TRUNC "Ïóòü ïîèñêà îáðåçàí"
- #define ERR_GETMODFN_TRUNC "GetModuleFileName() îáðåçàí"
- #define ERR_GETMODFN_NO_DIR "GetModuleFileName() íå ïîëó÷èë êàòàëîã"
- #define ERR_DISK_FULL "Äèñê ïîëîí"
- #define ERR_DIRECTORY_FULL "Êàòàëîã ïîëîí"
- #define ERR_MACOS_GENERIC "MacOS ñîîáùèëà îøèáêó (%d)"
- #define ERR_OS2_GENERIC "OS/2 ñîîáùèëà îøèáêó (%d)"
- #define ERR_VOL_LOCKED_HW "Òîì áëîêèðîâàí àïïàðàòíî"
- #define ERR_VOL_LOCKED_SW "Òîì áëîêèðîâàí ïðîãðàììíî"
- #define ERR_FILE_LOCKED "Ôàéë çàáëîêèðîâàí"
- #define ERR_FILE_OR_DIR_BUSY "Ôàéë/êàòàëîã çàíÿò"
- #define ERR_FILE_ALREADY_OPEN_W "Ôàéë óæå îòêðûò íà çàïèñü"
- #define ERR_FILE_ALREADY_OPEN_R "Ôàéë óæå îòêðûò íà ÷òåíèå"
- #define ERR_INVALID_REFNUM "Íåâåðíîå êîëè÷åñòâî ññûëîê"
- #define ERR_GETTING_FILE_POS "Îøèáêà ïðè ïîëó÷åíèè ïîçèöèè ôàéëà"
- #define ERR_VOLUME_OFFLINE "Òîì îòñîåäèíåí"
- #define ERR_PERMISSION_DENIED "Îòêàçàíî â ðàçðåøåíèè"
- #define ERR_VOL_ALREADY_ONLINE "Òîì óæå ïîäñîåäèíåí"
- #define ERR_NO_SUCH_DRIVE "Íåò òàêîãî äèñêà"
- #define ERR_NOT_MAC_DISK "Íå äèñê Macintosh"
- #define ERR_VOL_EXTERNAL_FS "Òîì ïðèíàäëåæèò âíåøíåé ôàéëîâîé ñèñòåìå"
- #define ERR_PROBLEM_RENAME "Ïðîáëåìà ïðè ïåðåèìåíîâàíèè"
- #define ERR_BAD_MASTER_BLOCK "Ïëîõîé ãëàâíûé áëîê êàòàëîãà"
- #define ERR_CANT_MOVE_FORBIDDEN "Ïîïûòêà ïåðåìåñòèòü çàïðåùåíà"
- #define ERR_WRONG_VOL_TYPE "Íåâåðíûé òèï òîìà"
- #define ERR_SERVER_VOL_LOST "Ñåðâåðíûé òîì áûë îòñîåäèíåí"
- #define ERR_FILE_ID_NOT_FOUND "Èäåíòèôèêàòîð ôàéëà íå íàéäåí"
- #define ERR_FILE_ID_EXISTS "Èäåíòèôèêàòîð ôàéëà óæå ñóùåñòâóåò"
- #define ERR_SERVER_NO_RESPOND "Ñåðâåð íå îòâå÷àåò"
- #define ERR_USER_AUTH_FAILED "Èäåíòèôèêàöèÿ ïîëüçîâàòåëÿ íå óäàëàñü"
- #define ERR_PWORD_EXPIRED "Ïàðîëü íà ñåðâåðå óñòàðåë"
- #define ERR_ACCESS_DENIED "Îòêàçàíî â äîñòóïå"
- #define ERR_NOT_A_DOS_DISK "Íå äèñê DOS"
- #define ERR_SHARING_VIOLATION "Íàðóøåíèå ñîâìåñòíîãî äîñòóïà"
- #define ERR_CANNOT_MAKE "Íå ìîãó ñîáðàòü"
- #define ERR_DEV_IN_USE "Óñòðîéñòâî óæå èñïîëüçóåòñÿ"
- #define ERR_OPEN_FAILED "Îòêðûòèå íå óäàëîñü"
- #define ERR_PIPE_BUSY "Êîíâåéåð çàíÿò"
- #define ERR_SHARING_BUF_EXCEEDED "Ðàçäåëÿåìûé áóôåð ïåðåïîëíåí"
- #define ERR_TOO_MANY_HANDLES "Ñëèøêîì ìíîãî îòêðûòûõ äåñêðèïòîðîâ"
- #define ERR_SEEK_ERROR "Îøèáêà ïîçèöèîíèðîâàíèÿ"
- #define ERR_DEL_CWD "Ïîïûòêà óäàëèòü òåêóùèé ðàáî÷èé êàòàëîã"
- #define ERR_WRITE_PROTECT_ERROR "Îøèáêà çàùèòû çàïèñè"
- #define ERR_WRITE_FAULT "Îøèáêà çàïèñè"
- #define ERR_LOCK_VIOLATION "Íàðóøåíèå áëîêèðîâêè"
- #define ERR_GEN_FAILURE "Îáùèé ñáîé"
- #define ERR_UNCERTAIN_MEDIA "Íåîïðåäåëåííûé íîñèòåëü"
- #define ERR_PROT_VIOLATION "Íàðóøåíèå çàùèòû"
- #define ERR_BROKEN_PIPE "Ñëîìàííûé êîíâåéåð"
-
-#elif (PHYSFS_LANG == PHYSFS_LANG_RUSSIAN_CP866)
- #define DIR_ARCHIVE_DESCRIPTION "\8d¥ à娢, ¥¯®á।áâ¢¥ë© ¢¢®¤/¢ë¢®¤ ä ©«®¢®© á¨á⥬ë"
- #define GRP_ARCHIVE_DESCRIPTION "\94®à¬ â £à㯯®¢®£® ä ©« Build engine"
- #define HOG_ARCHIVE_DESCRIPTION "Descent I/II HOG file format"
- #define MVL_ARCHIVE_DESCRIPTION "Descent II Movielib format"
- #define ZIP_ARCHIVE_DESCRIPTION "PkZip/WinZip/Info-Zip ᮢ¬¥á⨬ë©"
- #define WAD_ARCHIVE_DESCRIPTION "DOOM engine format" /* !!! FIXME: translate this line if needed */
- #define LZMA_ARCHIVE_DESCRIPTION "LZMA (7zip) format" /* !!! FIXME: translate this line if needed */
-
- #define ERR_IS_INITIALIZED "\93¦¥ ¨¨æ¨ «¨§¨à®¢ "
- #define ERR_NOT_INITIALIZED "\8d¥ ¨¨æ¨ «¨§¨à®¢ "
- #define ERR_INVALID_ARGUMENT "\8d¥¢¥àë© à£ã¬¥â"
- #define ERR_FILES_STILL_OPEN "\94 ©«ë ¥é¥ ®âªàëâë"
- #define ERR_NO_DIR_CREATE "\8d¥ ¬®£ã á®§¤ âì ª â «®£¨"
- #define ERR_OUT_OF_MEMORY "\8a®ç¨« áì ¯ ¬ïâì"
- #define ERR_NOT_IN_SEARCH_PATH "\8d¥â â ª®£® í«¥¬¥â ¢ ¯ã⨠¯®¨áª "
- #define ERR_NOT_SUPPORTED "\8e¯¥à æ¨ï ¥ ¯®¤¤¥à¦¨¢ ¥âáï"
- #define ERR_UNSUPPORTED_ARCHIVE "\80à娢ë â ª®£® ⨯ ¥ ¯®¤¤¥à¦¨¢ îâáï"
- #define ERR_NOT_A_HANDLE "\8d¥ ä ©«®¢ë© ¤¥áªà¨¯â®à"
- #define ERR_INSECURE_FNAME "\8d¥¡¥§®¯ ᮥ ¨¬ï ä ©« "
- #define ERR_SYMLINK_DISALLOWED "\91¨¬¢®«ìë¥ áá뫪¨ ®âª«îç¥ë"
- #define ERR_NO_WRITE_DIR "\8a â «®£ ¤«ï § ¯¨á¨ ¥ ãáâ ®¢«¥"
- #define ERR_NO_SUCH_FILE "\94 ©« ¥ ©¤¥"
- #define ERR_NO_SUCH_PATH "\8fãâì ¥ ©¤¥"
- #define ERR_NO_SUCH_VOLUME "\92®¬ ¥ ©¤¥"
- #define ERR_PAST_EOF "\87 ª®æ®¬ ä ©« "
- #define ERR_ARC_IS_READ_ONLY "\80à娢 ⮫쪮 ¤«ï ç⥨ï"
- #define ERR_IO_ERROR "\8e訡ª ¢¢®¤ /¢ë¢®¤ "
- #define ERR_CANT_SET_WRITE_DIR "\8d¥ ¬®£ã ãáâ ®¢¨âì ª â «®£ ¤«ï § ¯¨á¨"
- #define ERR_SYMLINK_LOOP "\81¥áª®¥çë© æ¨ª« ᨬ¢®«ì®© áá뫪¨"
- #define ERR_COMPRESSION "\8e訡ª (\90 á)¯ ª®¢ª¨"
- #define ERR_NOT_IMPLEMENTED "\8d¥ ॠ«¨§®¢ ®"
- #define ERR_OS_ERROR "\8e¯¥à 樮 ï á¨á⥬ á®®¡é¨« ®è¨¡ªã"
- #define ERR_FILE_EXISTS "\94 ©« 㦥 áãé¥áâ¢ã¥â"
- #define ERR_NOT_A_FILE "\8d¥ ä ©«"
- #define ERR_NOT_A_DIR "\8d¥ ª â «®£"
- #define ERR_NOT_AN_ARCHIVE "\8d¥ à娢"
- #define ERR_CORRUPTED "\8f®¢à¥¦¤¥ë© à娢"
- #define ERR_SEEK_OUT_OF_RANGE "\8f®§¨æ¨®¨à®¢ ¨¥ § ¯à¥¤¥«ë"
- #define ERR_BAD_FILENAME "\8d¥¢¥à®¥ ¨¬ï ä ©« "
- #define ERR_PHYSFS_BAD_OS_CALL "(BUG) PhysicsFS ¢ë¯®«¨« ¥¢¥àë© á¨áâ¥¬ë© ¢ë§®¢"
- #define ERR_ARGV0_IS_NULL "argv0 is NULL"
- #define ERR_NEED_DICT "㦥 á«®¢ àì"
- #define ERR_DATA_ERROR "®è¨¡ª ¤ ëå"
- #define ERR_MEMORY_ERROR "®è¨¡ª ¯ ¬ïâ¨"
- #define ERR_BUFFER_ERROR "®è¨¡ª ¡ãä¥à "
- #define ERR_VERSION_ERROR "®è¨¡ª ¢¥àᨨ"
- #define ERR_UNKNOWN_ERROR "¥¨§¢¥áâ ï ®è¨¡ª "
- #define ERR_SEARCHPATH_TRUNC "\8fãâì ¯®¨áª ®¡à¥§ "
- #define ERR_GETMODFN_TRUNC "GetModuleFileName() ®¡à¥§ "
- #define ERR_GETMODFN_NO_DIR "GetModuleFileName() ¥ ¯®«ã稫 ª â «®£"
- #define ERR_DISK_FULL "\84¨áª ¯®«®"
- #define ERR_DIRECTORY_FULL "\8a â «®£ ¯®«®"
- #define ERR_MACOS_GENERIC "MacOS á®®¡é¨« ®è¨¡ªã (%d)"
- #define ERR_OS2_GENERIC "OS/2 á®®¡é¨« ®è¨¡ªã (%d)"
- #define ERR_VOL_LOCKED_HW "\92®¬ ¡«®ª¨à®¢ ¯¯ à â®"
- #define ERR_VOL_LOCKED_SW "\92®¬ ¡«®ª¨à®¢ ¯à®£à ¬¬®"
- #define ERR_FILE_LOCKED "\94 ©« § ¡«®ª¨à®¢ "
- #define ERR_FILE_OR_DIR_BUSY "\94 ©«/ª â «®£ § ïâ"
- #define ERR_FILE_ALREADY_OPEN_W "\94 ©« 㦥 ®âªàëâ § ¯¨áì"
- #define ERR_FILE_ALREADY_OPEN_R "\94 ©« 㦥 ®âªàëâ ç⥨¥"
- #define ERR_INVALID_REFNUM "\8d¥¢¥à®¥ ª®«¨ç¥á⢮ ááë«®ª"
- #define ERR_GETTING_FILE_POS "\8e訡ª ¯à¨ ¯®«ã票¨ ¯®§¨æ¨¨ ä ©« "
- #define ERR_VOLUME_OFFLINE "\92®¬ ®âᮥ¤¨¥"
- #define ERR_PERMISSION_DENIED "\8e⪠§ ® ¢ à §à¥è¥¨¨"
- #define ERR_VOL_ALREADY_ONLINE "\92®¬ 㦥 ¯®¤á®¥¤¨¥"
- #define ERR_NO_SUCH_DRIVE "\8d¥â â ª®£® ¤¨áª "
- #define ERR_NOT_MAC_DISK "\8d¥ ¤¨áª Macintosh"
- #define ERR_VOL_EXTERNAL_FS "\92®¬ ¯à¨ ¤«¥¦¨â ¢¥è¥© ä ©«®¢®© á¨á⥬¥"
- #define ERR_PROBLEM_RENAME "\8f஡«¥¬ ¯à¨ ¯¥à¥¨¬¥®¢ ¨¨"
- #define ERR_BAD_MASTER_BLOCK "\8f«®å®© £« ¢ë© ¡«®ª ª â «®£ "
- #define ERR_CANT_MOVE_FORBIDDEN "\8f®¯ë⪠¯¥à¥¬¥áâ¨âì § ¯à¥é¥ "
- #define ERR_WRONG_VOL_TYPE "\8d¥¢¥àë© â¨¯ ⮬ "
- #define ERR_SERVER_VOL_LOST "\91¥à¢¥àë© â®¬ ¡ë« ®âᮥ¤¨¥"
- #define ERR_FILE_ID_NOT_FOUND "\88¤¥â¨ä¨ª â®à ä ©« ¥ ©¤¥"
- #define ERR_FILE_ID_EXISTS "\88¤¥â¨ä¨ª â®à ä ©« 㦥 áãé¥áâ¢ã¥â"
- #define ERR_SERVER_NO_RESPOND "\91¥à¢¥à ¥ ®â¢¥ç ¥â"
- #define ERR_USER_AUTH_FAILED "\88¤¥â¨ä¨ª æ¨ï ¯®«ì§®¢ â¥«ï ¥ 㤠« áì"
- #define ERR_PWORD_EXPIRED "\8f ஫ì á¥à¢¥à¥ ãáâ ५"
- #define ERR_ACCESS_DENIED "\8e⪠§ ® ¢ ¤®áâ㯥"
- #define ERR_NOT_A_DOS_DISK "\8d¥ ¤¨áª DOS"
- #define ERR_SHARING_VIOLATION "\8d àã襨¥ ᮢ¬¥á⮣® ¤®áâ㯠"
- #define ERR_CANNOT_MAKE "\8d¥ ¬®£ã ᮡà âì"
- #define ERR_DEV_IN_USE "\93áâனá⢮ 㦥 ¨á¯®«ì§ã¥âáï"
- #define ERR_OPEN_FAILED "\8eâªàë⨥ ¥ 㤠«®áì"
- #define ERR_PIPE_BUSY "\8a®¢¥©¥à § ïâ"
- #define ERR_SHARING_BUF_EXCEEDED "\90 §¤¥«ï¥¬ë© ¡ãä¥à ¯¥à¥¯®«¥"
- #define ERR_TOO_MANY_HANDLES "\91«¨èª®¬ ¬®£® ®âªàëâëå ¤¥áªà¨¯â®à®¢"
- #define ERR_SEEK_ERROR "\8e訡ª ¯®§¨æ¨®¨à®¢ ¨ï"
- #define ERR_DEL_CWD "\8f®¯ë⪠㤠«¨âì ⥪ã騩 à ¡®ç¨© ª â «®£"
- #define ERR_WRITE_PROTECT_ERROR "\8e訡ª § é¨âë § ¯¨á¨"
- #define ERR_WRITE_FAULT "\8e訡ª § ¯¨á¨"
- #define ERR_LOCK_VIOLATION "\8d àã襨¥ ¡«®ª¨à®¢ª¨"
- #define ERR_GEN_FAILURE "\8e¡é¨© á¡®©"
- #define ERR_UNCERTAIN_MEDIA "\8d¥®¯à¥¤¥«¥ë© ®á¨â¥«ì"
- #define ERR_PROT_VIOLATION "\8d àã襨¥ § é¨âë"
- #define ERR_BROKEN_PIPE "\91«®¬ ë© ª®¢¥©¥à"
-
-#elif (PHYSFS_LANG == PHYSFS_LANG_RUSSIAN_ISO_8859_5)
- #define DIR_ARCHIVE_DESCRIPTION "½Õ ÐàåØÒ, ÝÕßÞáàÕÔáâÒÕÝÝëÙ ÒÒÞÔ/ÒëÒÞÔ äÐÙÛÞÒÞÙ áØáâÕÜë"
- #define GRP_ARCHIVE_DESCRIPTION "ÄÞàÜÐâ ÓàãßßÞÒÞÓÞ äÐÙÛÐ Build engine"
- #define HOG_ARCHIVE_DESCRIPTION "Descent I/II HOG file format"
- #define MVL_ARCHIVE_DESCRIPTION "Descent II Movielib format"
- #define ZIP_ARCHIVE_DESCRIPTION "PkZip/WinZip/Info-Zip áÞÒÜÕáâØÜëÙ"
- #define WAD_ARCHIVE_DESCRIPTION "DOOM engine format" /* !!! FIXME: translate this line if needed */
- #define LZMA_ARCHIVE_DESCRIPTION "LZMA (7zip) format" /* !!! FIXME: translate this line if needed */
-
- #define ERR_IS_INITIALIZED "ÃÖÕ ØÝØæØÐÛØ×ØàÞÒÐÝ"
- #define ERR_NOT_INITIALIZED "½Õ ØÝØæØÐÛØ×ØàÞÒÐÝ"
- #define ERR_INVALID_ARGUMENT "½ÕÒÕàÝëÙ ÐàÓãÜÕÝâ"
- #define ERR_FILES_STILL_OPEN "ÄÐÙÛë ÕéÕ ÞâÚàëâë"
- #define ERR_NO_DIR_CREATE "½Õ ÜÞÓã áÞ×ÔÐâì ÚÐâÐÛÞÓØ"
- #define ERR_OUT_OF_MEMORY "ºÞÝçØÛÐáì ßÐÜïâì"
- #define ERR_NOT_IN_SEARCH_PATH "½Õâ âÐÚÞÓÞ íÛÕÜÕÝâÐ Ò ßãâØ ßÞØáÚÐ"
- #define ERR_NOT_SUPPORTED "¾ßÕàÐæØï ÝÕ ßÞÔÔÕàÖØÒÐÕâáï"
- #define ERR_UNSUPPORTED_ARCHIVE "°àåØÒë âÐÚÞÓÞ âØßÐ ÝÕ ßÞÔÔÕàÖØÒÐîâáï"
- #define ERR_NOT_A_HANDLE "½Õ äÐÙÛÞÒëÙ ÔÕáÚàØßâÞà"
- #define ERR_INSECURE_FNAME "½ÕÑÕ×ÞßÐáÝÞÕ ØÜï äÐÙÛÐ"
- #define ERR_SYMLINK_DISALLOWED "ÁØÜÒÞÛìÝëÕ ááëÛÚØ ÞâÚÛîçÕÝë"
- #define ERR_NO_WRITE_DIR "ºÐâÐÛÞÓ ÔÛï ×ÐßØáØ ÝÕ ãáâÐÝÞÒÛÕÝ"
- #define ERR_NO_SUCH_FILE "ÄÐÙÛ ÝÕ ÝÐÙÔÕÝ"
- #define ERR_NO_SUCH_PATH "¿ãâì ÝÕ ÝÐÙÔÕÝ"
- #define ERR_NO_SUCH_VOLUME "ÂÞÜ ÝÕ ÝÐÙÔÕÝ"
- #define ERR_PAST_EOF "·Ð ÚÞÝæÞÜ äÐÙÛÐ"
- #define ERR_ARC_IS_READ_ONLY "°àåØÒ âÞÛìÚÞ ÔÛï çâÕÝØï"
- #define ERR_IO_ERROR "¾èØÑÚÐ ÒÒÞÔÐ/ÒëÒÞÔÐ"
- #define ERR_CANT_SET_WRITE_DIR "½Õ ÜÞÓã ãáâÐÝÞÒØâì ÚÐâÐÛÞÓ ÔÛï ×ÐߨáØ"
- #define ERR_SYMLINK_LOOP "±ÕáÚÞÝÕçÝëÙ æØÚÛ áØÜÒÞÛìÝÞÙ ááëÛÚØ"
- #define ERR_COMPRESSION "¾èØÑÚÐ (ÀÐá)ßÐÚÞÒÚØ"
- #define ERR_NOT_IMPLEMENTED "½Õ àÕÐÛØ×ÞÒÐÝÞ"
- #define ERR_OS_ERROR "¾ßÕàÐæØÞÝÝÐï áØáâÕÜÐ áÞÞÑéØÛÐ ÞèØÑÚã"
- #define ERR_FILE_EXISTS "ÄÐÙÛ ãÖÕ áãéÕáâÒãÕâ"
- #define ERR_NOT_A_FILE "½Õ äÐÙÛ"
- #define ERR_NOT_A_DIR "½Õ ÚÐâÐÛÞÓ"
- #define ERR_NOT_AN_ARCHIVE "½Õ ÐàåØÒ"
- #define ERR_CORRUPTED "¿ÞÒàÕÖÔÕÝÝëÙ ÐàåØÒ"
- #define ERR_SEEK_OUT_OF_RANGE "¿ÞרæØÞÝØàÞÒÐÝØÕ ×Ð ßàÕÔÕÛë"
- #define ERR_BAD_FILENAME "½ÕÒÕàÝÞÕ ØÜï äÐÙÛÐ"
- #define ERR_PHYSFS_BAD_OS_CALL "(BUG) PhysicsFS ÒëßÞÛÝØÛÐ ÝÕÒÕàÝëÙ áØáâÕÜÝëÙ Òë×ÞÒ"
- #define ERR_ARGV0_IS_NULL "argv0 is NULL"
- #define ERR_NEED_DICT "ÝãÖÕÝ áÛÞÒÐàì"
- #define ERR_DATA_ERROR "ÞèØÑÚÐ ÔÐÝÝëå"
- #define ERR_MEMORY_ERROR "ÞèØÑÚÐ ßÐÜïâØ"
- #define ERR_BUFFER_ERROR "ÞèØÑÚÐ ÑãäÕàÐ"
- #define ERR_VERSION_ERROR "ÞèØÑÚÐ ÒÕàáØØ"
- #define ERR_UNKNOWN_ERROR "ÝÕØ×ÒÕáâÝÐï ÞèØÑÚÐ"
- #define ERR_SEARCHPATH_TRUNC "¿ãâì ßÞØáÚÐ ÞÑàÕ×ÐÝ"
- #define ERR_GETMODFN_TRUNC "GetModuleFileName() ÞÑàÕ×ÐÝ"
- #define ERR_GETMODFN_NO_DIR "GetModuleFileName() ÝÕ ßÞÛãçØÛ ÚÐâÐÛÞÓ"
- #define ERR_DISK_FULL "´ØáÚ ßÞÛÞÝ"
- #define ERR_DIRECTORY_FULL "ºÐâÐÛÞÓ ßÞÛÞÝ"
- #define ERR_MACOS_GENERIC "MacOS áÞÞÑéØÛÐ ÞèØÑÚã (%d)"
- #define ERR_OS2_GENERIC "OS/2 áÞÞÑéØÛÐ ÞèØÑÚã (%d)"
- #define ERR_VOL_LOCKED_HW "ÂÞÜ ÑÛÞÚØàÞÒÐÝ ÐßßÐàÐâÝÞ"
- #define ERR_VOL_LOCKED_SW "ÂÞÜ ÑÛÞÚØàÞÒÐÝ ßàÞÓàÐÜÜÝÞ"
- #define ERR_FILE_LOCKED "ÄÐÙÛ ×ÐÑÛÞÚØàÞÒÐÝ"
- #define ERR_FILE_OR_DIR_BUSY "ÄÐÙÛ/ÚÐâÐÛÞÓ ×ÐÝïâ"
- #define ERR_FILE_ALREADY_OPEN_W "ÄÐÙÛ ãÖÕ ÞâÚàëâ ÝÐ ×Ðߨáì"
- #define ERR_FILE_ALREADY_OPEN_R "ÄÐÙÛ ãÖÕ ÞâÚàëâ ÝÐ çâÕÝØÕ"
- #define ERR_INVALID_REFNUM "½ÕÒÕàÝÞÕ ÚÞÛØçÕáâÒÞ ááëÛÞÚ"
- #define ERR_GETTING_FILE_POS "¾èØÑÚÐ ßàØ ßÞÛãçÕÝØØ ßÞ×ØæØØ äÐÙÛÐ"
- #define ERR_VOLUME_OFFLINE "ÂÞÜ ÞâáÞÕÔØÝÕÝ"
- #define ERR_PERMISSION_DENIED "¾âÚÐ×ÐÝÞ Ò àÐ×àÕèÕÝØØ"
- #define ERR_VOL_ALREADY_ONLINE "ÂÞÜ ãÖÕ ßÞÔáÞÕÔØÝÕÝ"
- #define ERR_NO_SUCH_DRIVE "½Õâ âÐÚÞÓÞ ÔØáÚÐ"
- #define ERR_NOT_MAC_DISK "½Õ ÔØáÚ Macintosh"
- #define ERR_VOL_EXTERNAL_FS "ÂÞÜ ßàØÝÐÔÛÕÖØâ ÒÝÕèÝÕÙ äÐÙÛÞÒÞÙ áØáâÕÜÕ"
- #define ERR_PROBLEM_RENAME "¿àÞÑÛÕÜÐ ßàØ ßÕàÕØÜÕÝÞÒÐÝØØ"
- #define ERR_BAD_MASTER_BLOCK "¿ÛÞåÞÙ ÓÛÐÒÝëÙ ÑÛÞÚ ÚÐâÐÛÞÓÐ"
- #define ERR_CANT_MOVE_FORBIDDEN "¿ÞßëâÚÐ ßÕàÕÜÕáâØâì ×ÐßàÕéÕÝÐ"
- #define ERR_WRONG_VOL_TYPE "½ÕÒÕàÝëÙ âØß âÞÜÐ"
- #define ERR_SERVER_VOL_LOST "ÁÕàÒÕàÝëÙ âÞÜ ÑëÛ ÞâáÞÕÔØÝÕÝ"
- #define ERR_FILE_ID_NOT_FOUND "¸ÔÕÝâØäØÚÐâÞà äÐÙÛÐ ÝÕ ÝÐÙÔÕÝ"
- #define ERR_FILE_ID_EXISTS "¸ÔÕÝâØäØÚÐâÞà äÐÙÛÐ ãÖÕ áãéÕáâÒãÕâ"
- #define ERR_SERVER_NO_RESPOND "ÁÕàÒÕà ÝÕ ÞâÒÕçÐÕâ"
- #define ERR_USER_AUTH_FAILED "¸ÔÕÝâØäØÚÐæØï ßÞÛì×ÞÒÐâÕÛï ÝÕ ãÔÐÛÐáì"
- #define ERR_PWORD_EXPIRED "¿ÐàÞÛì ÝÐ áÕàÒÕàÕ ãáâÐàÕÛ"
- #define ERR_ACCESS_DENIED "¾âÚÐ×ÐÝÞ Ò ÔÞáâãßÕ"
- #define ERR_NOT_A_DOS_DISK "½Õ ÔØáÚ DOS"
- #define ERR_SHARING_VIOLATION "½ÐàãèÕÝØÕ áÞÒÜÕáâÝÞÓÞ ÔÞáâãßÐ"
- #define ERR_CANNOT_MAKE "½Õ ÜÞÓã áÞÑàÐâì"
- #define ERR_DEV_IN_USE "ÃáâàÞÙáâÒÞ ãÖÕ ØáßÞÛì×ãÕâáï"
- #define ERR_OPEN_FAILED "¾âÚàëâØÕ ÝÕ ãÔÐÛÞáì"
- #define ERR_PIPE_BUSY "ºÞÝÒÕÙÕà ×ÐÝïâ"
- #define ERR_SHARING_BUF_EXCEEDED "ÀÐ×ÔÕÛïÕÜëÙ ÑãäÕà ßÕàÕßÞÛÝÕÝ"
- #define ERR_TOO_MANY_HANDLES "ÁÛØèÚÞÜ ÜÝÞÓÞ ÞâÚàëâëå ÔÕáÚàØßâÞàÞÒ"
- #define ERR_SEEK_ERROR "¾èØÑÚÐ ßÞרæØÞÝØàÞÒÐÝØï"
- #define ERR_DEL_CWD "¿ÞßëâÚÐ ãÔÐÛØâì âÕÚãéØÙ àÐÑÞçØÙ ÚÐâÐÛÞÓ"
- #define ERR_WRITE_PROTECT_ERROR "¾èØÑÚÐ ×ÐéØâë ×ÐߨáØ"
- #define ERR_WRITE_FAULT "¾èØÑÚÐ ×ÐߨáØ"
- #define ERR_LOCK_VIOLATION "½ÐàãèÕÝØÕ ÑÛÞÚØàÞÒÚØ"
- #define ERR_GEN_FAILURE "¾ÑéØÙ áÑÞÙ"
- #define ERR_UNCERTAIN_MEDIA "½ÕÞßàÕÔÕÛÕÝÝëÙ ÝÞáØâÕÛì"
- #define ERR_PROT_VIOLATION "½ÐàãèÕÝØÕ ×ÐéØâë"
- #define ERR_BROKEN_PIPE "ÁÛÞÜÐÝÝëÙ ÚÞÝÒÕÙÕà"
-
-
-#elif (PHYSFS_LANG == PHYSFS_LANG_FRENCH)
- #define DIR_ARCHIVE_DESCRIPTION "Pas d'archive, E/S directes sur système de fichiers"
- #define GRP_ARCHIVE_DESCRIPTION "Format Groupfile du moteur Build"
- #define HOG_ARCHIVE_DESCRIPTION "Descent I/II HOG file format"
- #define MVL_ARCHIVE_DESCRIPTION "Descent II Movielib format"
- #define QPAK_ARCHIVE_DESCRIPTION "Quake I/II format"
- #define ZIP_ARCHIVE_DESCRIPTION "Compatible PkZip/WinZip/Info-Zip"
- #define WAD_ARCHIVE_DESCRIPTION "Format WAD du moteur DOOM"
- #define LZMA_ARCHIVE_DESCRIPTION "LZMA (7zip) format" /* !!! FIXME: translate this line if needed */
-
- #define ERR_IS_INITIALIZED "Déjà initialisé"
- #define ERR_NOT_INITIALIZED "Non initialisé"
- #define ERR_INVALID_ARGUMENT "Argument invalide"
- #define ERR_FILES_STILL_OPEN "Fichiers encore ouverts"
- #define ERR_NO_DIR_CREATE "Echec de la création de répertoires"
- #define ERR_OUT_OF_MEMORY "A court de mémoire"
- #define ERR_NOT_IN_SEARCH_PATH "Aucune entrée dans le chemin de recherche"
- #define ERR_NOT_SUPPORTED "Opération non supportée"
- #define ERR_UNSUPPORTED_ARCHIVE "Type d'archive non supportée"
- #define ERR_NOT_A_HANDLE "Pas un descripteur de fichier"
- #define ERR_INSECURE_FNAME "Nom de fichier dangereux"
- #define ERR_SYMLINK_DISALLOWED "Les liens symboliques sont désactivés"
- #define ERR_NO_WRITE_DIR "Le répertoire d'écriture n'est pas spécifié"
- #define ERR_NO_SUCH_FILE "Fichier non trouvé"
- #define ERR_NO_SUCH_PATH "Chemin non trouvé"
- #define ERR_NO_SUCH_VOLUME "Volume non trouvé"
- #define ERR_PAST_EOF "Au-delà de la fin du fichier"
- #define ERR_ARC_IS_READ_ONLY "L'archive est en lecture seule"
- #define ERR_IO_ERROR "Erreur E/S"
- #define ERR_CANT_SET_WRITE_DIR "Ne peut utiliser le répertoire d'écriture"
- #define ERR_SYMLINK_LOOP "Boucle infinie dans les liens symboliques"
- #define ERR_COMPRESSION "Erreur de (dé)compression"
- #define ERR_NOT_IMPLEMENTED "Non implémenté"
- #define ERR_OS_ERROR "Erreur rapportée par le système d'exploitation"
- #define ERR_FILE_EXISTS "Le fichier existe déjà"
- #define ERR_NOT_A_FILE "Pas un fichier"
- #define ERR_NOT_A_DIR "Pas un répertoire"
- #define ERR_NOT_AN_ARCHIVE "Pas une archive"
- #define ERR_CORRUPTED "Archive corrompue"
- #define ERR_SEEK_OUT_OF_RANGE "Pointeur de fichier hors de portée"
- #define ERR_BAD_FILENAME "Mauvais nom de fichier"
- #define ERR_PHYSFS_BAD_OS_CALL "(BOGUE) PhysicsFS a fait un mauvais appel système, le salaud"
- #define ERR_ARGV0_IS_NULL "argv0 est NULL"
- #define ERR_NEED_DICT "a besoin du dico"
- #define ERR_DATA_ERROR "erreur de données"
- #define ERR_MEMORY_ERROR "erreur mémoire"
- #define ERR_BUFFER_ERROR "erreur tampon"
- #define ERR_VERSION_ERROR "erreur de version"
- #define ERR_UNKNOWN_ERROR "erreur inconnue"
- #define ERR_SEARCHPATH_TRUNC "Le chemin de recherche a été tronqué"
- #define ERR_GETMODFN_TRUNC "GetModuleFileName() a été tronqué"
- #define ERR_GETMODFN_NO_DIR "GetModuleFileName() n'a pas de répertoire"
- #define ERR_DISK_FULL "Disque plein"
- #define ERR_DIRECTORY_FULL "Répertoire plein"
- #define ERR_MACOS_GENERIC "Erreur rapportée par MacOS (%d)"
- #define ERR_OS2_GENERIC "Erreur rapportée par OS/2 (%d)"
- #define ERR_VOL_LOCKED_HW "Le volume est verrouillé matériellement"
- #define ERR_VOL_LOCKED_SW "Le volume est verrouillé par logiciel"
- #define ERR_FILE_LOCKED "Fichier verrouillé"
- #define ERR_FILE_OR_DIR_BUSY "Fichier/répertoire occupé"
- #define ERR_FILE_ALREADY_OPEN_W "Fichier déjà ouvert en écriture"
- #define ERR_FILE_ALREADY_OPEN_R "Fichier déjà ouvert en lecture"
- #define ERR_INVALID_REFNUM "Numéro de référence invalide"
- #define ERR_GETTING_FILE_POS "Erreur lors de l'obtention de la position du pointeur de fichier"
- #define ERR_VOLUME_OFFLINE "Le volume n'est pas en ligne"
- #define ERR_PERMISSION_DENIED "Permission refusée"
- #define ERR_VOL_ALREADY_ONLINE "Volumé déjà en ligne"
- #define ERR_NO_SUCH_DRIVE "Lecteur inexistant"
- #define ERR_NOT_MAC_DISK "Pas un disque Macintosh"
- #define ERR_VOL_EXTERNAL_FS "Le volume appartient à un système de fichiers externe"
- #define ERR_PROBLEM_RENAME "Problème lors du renommage"
- #define ERR_BAD_MASTER_BLOCK "Mauvais block maitre de répertoire"
- #define ERR_CANT_MOVE_FORBIDDEN "Essai de déplacement interdit"
- #define ERR_WRONG_VOL_TYPE "Mauvais type de volume"
- #define ERR_SERVER_VOL_LOST "Le volume serveur a été déconnecté"
- #define ERR_FILE_ID_NOT_FOUND "Identificateur de fichier non trouvé"
- #define ERR_FILE_ID_EXISTS "Identificateur de fichier existe déjà"
- #define ERR_SERVER_NO_RESPOND "Le serveur ne répond pas"
- #define ERR_USER_AUTH_FAILED "Authentification de l'utilisateur échouée"
- #define ERR_PWORD_EXPIRED "Le mot de passe a expiré sur le serveur"
- #define ERR_ACCESS_DENIED "Accès refusé"
- #define ERR_NOT_A_DOS_DISK "Pas un disque DOS"
- #define ERR_SHARING_VIOLATION "Violation de partage"
- #define ERR_CANNOT_MAKE "Ne peut faire"
- #define ERR_DEV_IN_USE "Périphérique déjà en utilisation"
- #define ERR_OPEN_FAILED "Ouverture échouée"
- #define ERR_PIPE_BUSY "Le tube est occupé"
- #define ERR_SHARING_BUF_EXCEEDED "Tampon de partage dépassé"
- #define ERR_TOO_MANY_HANDLES "Trop de descripteurs ouverts"
- #define ERR_SEEK_ERROR "Erreur de positionement"
- #define ERR_DEL_CWD "Essai de supprimer le répertoire courant"
- #define ERR_WRITE_PROTECT_ERROR "Erreur de protection en écriture"
- #define ERR_WRITE_FAULT "Erreur d'écriture"
- #define ERR_LOCK_VIOLATION "Violation de verrou"
- #define ERR_GEN_FAILURE "Echec général"
- #define ERR_UNCERTAIN_MEDIA "Média incertain"
- #define ERR_PROT_VIOLATION "Violation de protection"
- #define ERR_BROKEN_PIPE "Tube cassé"
-
-#elif (PHYSFS_LANG == PHYSFS_LANG_PORTUGUESE_BR)
- #define DIR_ARCHIVE_DESCRIPTION "Não arquivo, E/S sistema de arquivos direto"
- #define GRP_ARCHIVE_DESCRIPTION "Formato Groupfile do engine Build"
- #define HOG_ARCHIVE_DESCRIPTION "Formato Descent I/II HOG file"
- #define MVL_ARCHIVE_DESCRIPTION "Formato Descent II Movielib"
- #define QPAK_ARCHIVE_DESCRIPTION "Formato Quake I/II"
- #define ZIP_ARCHIVE_DESCRIPTION "Formato compatível PkZip/WinZip/Info-Zip"
- #define WAD_ARCHIVE_DESCRIPTION "Formato WAD do engine DOOM"
- #define WAD_ARCHIVE_DESCRIPTION "DOOM engine format" /* !!! FIXME: translate this line if needed */
- #define LZMA_ARCHIVE_DESCRIPTION "LZMA (7zip) format" /* !!! FIXME: translate this line if needed */
-
- #define ERR_IS_INITIALIZED "Já inicializado"
- #define ERR_NOT_INITIALIZED "Não inicializado"
- #define ERR_INVALID_ARGUMENT "Argumento inválido"
- #define ERR_FILES_STILL_OPEN "Arquivos ainda abertos"
- #define ERR_NO_DIR_CREATE "Falha na criação de diretórios"
- #define ERR_OUT_OF_MEMORY "Memória insuficiente"
- #define ERR_NOT_IN_SEARCH_PATH "Entrada não encontrada no caminho de busca"
- #define ERR_NOT_SUPPORTED "Operação não suportada"
- #define ERR_UNSUPPORTED_ARCHIVE "Tipo de arquivo não suportado"
- #define ERR_NOT_A_HANDLE "Não é um handler de arquivo"
- #define ERR_INSECURE_FNAME "Nome de arquivo inseguro"
- #define ERR_SYMLINK_DISALLOWED "Links simbólicos desabilitados"
- #define ERR_NO_WRITE_DIR "Diretório de escrita não definido"
- #define ERR_NO_SUCH_FILE "Arquivo não encontrado"
- #define ERR_NO_SUCH_PATH "Caminho não encontrado"
- #define ERR_NO_SUCH_VOLUME "Volume não encontrado"
- #define ERR_PAST_EOF "Passou o fim do arquivo"
- #define ERR_ARC_IS_READ_ONLY "Arquivo é somente de leitura"
- #define ERR_IO_ERROR "Erro de E/S"
- #define ERR_CANT_SET_WRITE_DIR "Não foi possível definir diretório de escrita"
- #define ERR_SYMLINK_LOOP "Loop infinito de link simbólico"
- #define ERR_COMPRESSION "Erro de (Des)compressão"
- #define ERR_NOT_IMPLEMENTED "Não implementado"
- #define ERR_OS_ERROR "Erro reportado pelo Sistema Operacional"
- #define ERR_FILE_EXISTS "Arquivo já existente"
- #define ERR_NOT_A_FILE "Não é um arquivo"
- #define ERR_NOT_A_DIR "Não é um diretório"
- #define ERR_NOT_AN_ARCHIVE "Não é um pacote"
- #define ERR_CORRUPTED "Pacote corrompido"
- #define ERR_SEEK_OUT_OF_RANGE "Posicionamento além do tamanho"
- #define ERR_BAD_FILENAME "Nome de arquivo inválido"
- #define ERR_PHYSFS_BAD_OS_CALL "(BUG) PhysicsFS realizou uma chamada de sistema inválida"
- #define ERR_ARGV0_IS_NULL "argv0 é NULL"
- #define ERR_NEED_DICT "precisa de diretório"
- #define ERR_DATA_ERROR "erro nos dados"
- #define ERR_MEMORY_ERROR "erro de memória"
- #define ERR_BUFFER_ERROR "erro de buffer"
- #define ERR_VERSION_ERROR "erro na version"
- #define ERR_UNKNOWN_ERROR "erro desconhecido"
- #define ERR_SEARCHPATH_TRUNC "Caminho de procura quebrado"
- #define ERR_GETMODFN_TRUNC "GetModuleFileName() foi quebrado"
- #define ERR_GETMODFN_NO_DIR "GetModuleFileName() nao teve diretório"
- #define ERR_DISK_FULL "Disco cheio"
- #define ERR_DIRECTORY_FULL "Diretório cheio"
- #define ERR_MACOS_GENERIC "MacOS reportou um erro (%d)"
- #define ERR_OS2_GENERIC "OS/2 reportou um erro (%d)"
- #define ERR_VOL_LOCKED_HW "Volume travado por hardware"
- #define ERR_VOL_LOCKED_SW "Volume travado por software"
- #define ERR_FILE_LOCKED "Arquivo travado"
- #define ERR_FILE_OR_DIR_BUSY "Arquivo/Diretório está em uso"
- #define ERR_FILE_ALREADY_OPEN_W "Arquivo já aberto para escrita"
- #define ERR_FILE_ALREADY_OPEN_R "Arquivo já aberto para leitura"
- #define ERR_INVALID_REFNUM "Número de referência"
- #define ERR_GETTING_FILE_POS "Erro ao tentar obter posição do arquivo"
- #define ERR_VOLUME_OFFLINE "Volume está indisponível"
- #define ERR_PERMISSION_DENIED "Permissão negada"
- #define ERR_VOL_ALREADY_ONLINE "Volume disponível"
- #define ERR_NO_SUCH_DRIVE "Drive inexistente"
- #define ERR_NOT_MAC_DISK "Não é um disco Macintosh"
- #define ERR_VOL_EXTERNAL_FS "Volume pertence a um sistema de arquivos externo"
- #define ERR_PROBLEM_RENAME "Problema durante renomeação"
- #define ERR_BAD_MASTER_BLOCK "Bloco master do diretório inválido"
- #define ERR_CANT_MOVE_FORBIDDEN "Tentativa de mover proibida"
- #define ERR_WRONG_VOL_TYPE "Tipo inválido de volume"
- #define ERR_SERVER_VOL_LOST "Volume servidor desconectado"
- #define ERR_FILE_ID_NOT_FOUND "ID de Arquivo não encontrado"
- #define ERR_FILE_ID_EXISTS "ID de Arquivo já existente"
- #define ERR_SERVER_NO_RESPOND "Servidor não respondendo"
- #define ERR_USER_AUTH_FAILED "Autenticação de usuário falhada"
- #define ERR_PWORD_EXPIRED "Password foi expirada no servidor"
- #define ERR_ACCESS_DENIED "Accesso negado"
- #define ERR_NOT_A_DOS_DISK "Não é um disco DOS"
- #define ERR_SHARING_VIOLATION "Violação de compartilhamento"
- #define ERR_CANNOT_MAKE "Não pode ser feito"
- #define ERR_DEV_IN_USE "Device já em uso"
- #define ERR_OPEN_FAILED "Falaha na abertura"
- #define ERR_PIPE_BUSY "Fila ocupada"
- #define ERR_SHARING_BUF_EXCEEDED "Buffer de compartilhamento excedeu"
- #define ERR_TOO_MANY_HANDLES "Muitos handles abertos"
- #define ERR_SEEK_ERROR "Erro de posicionamento"
- #define ERR_DEL_CWD "Tentando remover diretório de trabalho atual"
- #define ERR_WRITE_PROTECT_ERROR "Erro de proteção de escrita"
- #define ERR_WRITE_FAULT "Erro de escrita"
- #define ERR_LOCK_VIOLATION "Violação de trava"
- #define ERR_GEN_FAILURE "Falha geral"
- #define ERR_UNCERTAIN_MEDIA "Media incerta"
- #define ERR_PROT_VIOLATION "Violação de proteção"
- #define ERR_BROKEN_PIPE "Fila quebrada"
-
-#elif (PHYSFS_LANG == PHYSFS_LANG_SPANISH)
- #define DIR_ARCHIVE_DESCRIPTION "No es un archivo, E/S directa al sistema de ficheros"
- #define GRP_ARCHIVE_DESCRIPTION "Formato Build engine Groupfile"
- #define HOG_ARCHIVE_DESCRIPTION "Formato Descent I/II HOG file"
- #define MVL_ARCHIVE_DESCRIPTION "Formato Descent II Movielib"
- #define QPAK_ARCHIVE_DESCRIPTION "Formato Quake I/II"
- #define ZIP_ARCHIVE_DESCRIPTION "Compatible con PkZip/WinZip/Info-Zip"
- #define WAD_ARCHIVE_DESCRIPTION "DOOM engine format" /* !!! FIXME: translate this line if needed */
- #define LZMA_ARCHIVE_DESCRIPTION "LZMA (7zip) format" /* !!! FIXME: translate this line if needed */
-
- #define ERR_IS_INITIALIZED "Ya estaba inicializado"
- #define ERR_NOT_INITIALIZED "No está inicializado"
- #define ERR_INVALID_ARGUMENT "Argumento inválido"
- #define ERR_FILES_STILL_OPEN "Archivos aún abiertos"
- #define ERR_NO_DIR_CREATE "Fallo al crear los directorios"
- #define ERR_OUT_OF_MEMORY "Memoria agotada"
- #define ERR_NOT_IN_SEARCH_PATH "No existe tal entrada en la ruta de búsqueda"
- #define ERR_NOT_SUPPORTED "Operación no soportada"
- #define ERR_UNSUPPORTED_ARCHIVE "Tipo de archivo no soportado"
- #define ERR_NOT_A_HANDLE "No es un manejador de ficheo (file handle)"
- #define ERR_INSECURE_FNAME "Nombre de archivo inseguro"
- #define ERR_SYMLINK_DISALLOWED "Los enlaces simbólicos están desactivados"
- #define ERR_NO_WRITE_DIR "No has configurado un directorio de escritura"
- #define ERR_NO_SUCH_FILE "Archivo no encontrado"
- #define ERR_NO_SUCH_PATH "Ruta no encontrada"
- #define ERR_NO_SUCH_VOLUME "Volumen no encontrado"
- #define ERR_PAST_EOF "Te pasaste del final del archivo"
- #define ERR_ARC_IS_READ_ONLY "El archivo es de sólo lectura"
- #define ERR_IO_ERROR "Error E/S"
- #define ERR_CANT_SET_WRITE_DIR "No puedo configurar el directorio de escritura"
- #define ERR_SYMLINK_LOOP "Bucle infnito de enlaces simbólicos"
- #define ERR_COMPRESSION "Error de (des)compresión"
- #define ERR_NOT_IMPLEMENTED "No implementado"
- #define ERR_OS_ERROR "El sistema operativo ha devuelto un error"
- #define ERR_FILE_EXISTS "El archivo ya existe"
- #define ERR_NOT_A_FILE "No es un archivo"
- #define ERR_NOT_A_DIR "No es un directorio"
- #define ERR_NOT_AN_ARCHIVE "No es un archivo"
- #define ERR_CORRUPTED "Archivo corrupto"
- #define ERR_SEEK_OUT_OF_RANGE "Búsqueda fuera de rango"
- #define ERR_BAD_FILENAME "Nombre de archivo incorrecto"
- #define ERR_PHYSFS_BAD_OS_CALL "(BUG) PhysicsFS ha hecho una llamada incorrecta al sistema"
- #define ERR_ARGV0_IS_NULL "argv0 es NULL"
- #define ERR_NEED_DICT "necesito diccionario"
- #define ERR_DATA_ERROR "error de datos"
- #define ERR_MEMORY_ERROR "error de memoria"
- #define ERR_BUFFER_ERROR "error de buffer"
- #define ERR_VERSION_ERROR "error de versión"
- #define ERR_UNKNOWN_ERROR "error desconocido"
- #define ERR_SEARCHPATH_TRUNC "La ruta de búsqueda ha sido truncada"
- #define ERR_GETMODFN_TRUNC "GetModuleFileName() ha sido truncado"
- #define ERR_GETMODFN_NO_DIR "GetModuleFileName() no tenia directorio"
- #define ERR_DISK_FULL "El disco está lleno"
- #define ERR_DIRECTORY_FULL "El directorio está lleno"
- #define ERR_MACOS_GENERIC "MacOS ha devuelto un error (%d)"
- #define ERR_OS2_GENERIC "OS/2 ha devuelto un error (%d)"
- #define ERR_VOL_LOCKED_HW "El volumen está bloqueado por el hardware"
- #define ERR_VOL_LOCKED_SW "El volumen está bloqueado por el software"
- #define ERR_FILE_LOCKED "El archivo está bloqueado"
- #define ERR_FILE_OR_DIR_BUSY "Fichero o directorio ocupados"
- #define ERR_FILE_ALREADY_OPEN_W "Fichero ya abierto para escritura"
- #define ERR_FILE_ALREADY_OPEN_R "Fichero ya abierto para lectura"
- #define ERR_INVALID_REFNUM "El número de referencia no es válido"
- #define ERR_GETTING_FILE_POS "Error al tomar la posición del fichero"
- #define ERR_VOLUME_OFFLINE "El volumen está desconectado"
- #define ERR_PERMISSION_DENIED "Permiso denegado"
- #define ERR_VOL_ALREADY_ONLINE "El volumen ya estaba conectado"
- #define ERR_NO_SUCH_DRIVE "No existe tal unidad"
- #define ERR_NOT_MAC_DISK "No es un disco Macintosh"
- #define ERR_VOL_EXTERNAL_FS "El volumen pertence a un sistema de ficheros externo"
- #define ERR_PROBLEM_RENAME "Problemas al renombrar"
- #define ERR_BAD_MASTER_BLOCK "Bloque maestro de directorios incorrecto"
- #define ERR_CANT_MOVE_FORBIDDEN "Intento de mover forbidden"
- #define ERR_WRONG_VOL_TYPE "Tipo de volumen incorrecto"
- #define ERR_SERVER_VOL_LOST "El servidor de volúmenes ha sido desconectado"
- #define ERR_FILE_ID_NOT_FOUND "Identificador de archivo no encontrado"
- #define ERR_FILE_ID_EXISTS "El identificador de archivo ya existe"
- #define ERR_SERVER_NO_RESPOND "El servidor no responde"
- #define ERR_USER_AUTH_FAILED "Fallo al autentificar el usuario"
- #define ERR_PWORD_EXPIRED "La Password en el servidor ha caducado"
- #define ERR_ACCESS_DENIED "Acceso denegado"
- #define ERR_NOT_A_DOS_DISK "No es un disco de DOS"
- #define ERR_SHARING_VIOLATION "Violación al compartir"
- #define ERR_CANNOT_MAKE "No puedo hacer make"
- #define ERR_DEV_IN_USE "El dispositivo ya estaba en uso"
- #define ERR_OPEN_FAILED "Fallo al abrir"
- #define ERR_PIPE_BUSY "Tubería ocupada"
- #define ERR_SHARING_BUF_EXCEEDED "Buffer de compartición sobrepasado"
- #define ERR_TOO_MANY_HANDLES "Demasiados manejadores (handles)"
- #define ERR_SEEK_ERROR "Error de búsqueda"
- #define ERR_DEL_CWD "Intentando borrar el directorio de trabajo actual"
- #define ERR_WRITE_PROTECT_ERROR "Error de protección contra escritura"
- #define ERR_WRITE_FAULT "Fallo al escribir"
- #define ERR_LOCK_VIOLATION "Violación del bloqueo"
- #define ERR_GEN_FAILURE "Fallo general"
- #define ERR_UNCERTAIN_MEDIA "Medio incierto"
- #define ERR_PROT_VIOLATION "Violación de la protección"
- #define ERR_BROKEN_PIPE "Tubería rota"
-
-#else
- #error Please define PHYSFS_LANG.
-#endif
-
-/* end LANG section. */
-
-struct __PHYSFS_DIRHANDLE__;
-struct __PHYSFS_FILEFUNCTIONS__;
-
-
-/* !!! FIXME: find something better than "dvoid" and "fvoid" ... */
-/* Opaque data for file and dir handlers... */
-typedef void dvoid;
-typedef void fvoid;
-
-
-typedef struct
-{
- /*
- * Basic info about this archiver...
- */
- const PHYSFS_ArchiveInfo *info;
-
-
- /*
- * DIRECTORY ROUTINES:
- * These functions are for dir handles. Generate a handle with the
- * openArchive() method, then pass it as the "opaque" dvoid to the
- * others.
- *
- * Symlinks should always be followed; PhysicsFS will use the
- * isSymLink() method and make a judgement on whether to
- * continue to call other methods based on that.
- */
-
-
- /*
- * Returns non-zero if (filename) is a valid archive that this
- * driver can handle. This filename is in platform-dependent
- * notation. forWriting is non-zero if this is to be used for
- * the write directory, and zero if this is to be used for an
- * element of the search path.
- */
- int (*isArchive)(const char *filename, int forWriting);
-
- /*
- * Open a dirhandle for dir/archive (name).
- * This filename is in platform-dependent notation.
- * forWriting is non-zero if this is to be used for
- * the write directory, and zero if this is to be used for an
- * element of the search path.
- * Returns NULL on failure, and calls __PHYSFS_setError().
- * Returns non-NULL on success. The pointer returned will be
- * passed as the "opaque" parameter for later calls.
- */
- void *(*openArchive)(const char *name, int forWriting);
-
- /*
- * List all files in (dirname). Each file is passed to (callback),
- * where a copy is made if appropriate, so you should dispose of
- * it properly upon return from the callback.
- * You should omit symlinks if (omitSymLinks) is non-zero.
- * If you have a failure, report as much as you can.
- * (dirname) is in platform-independent notation.
- */
- void (*enumerateFiles)(dvoid *opaque,
- const char *dirname,
- int omitSymLinks,
- PHYSFS_EnumFilesCallback callback,
- const char *origdir,
- void *callbackdata);
-
- /*
- * Returns non-zero if filename can be opened for reading.
- * This filename is in platform-independent notation.
- * You should not follow symlinks.
- */
- int (*exists)(dvoid *opaque, const char *name);
-
- /*
- * Returns non-zero if filename is really a directory.
- * This filename is in platform-independent notation.
- * Symlinks should be followed; if what the symlink points
- * to is missing, or isn't a directory, then the retval is zero.
- *
- * Regardless of success or failure, please set *fileExists to
- * non-zero if the file existed (even if it's a broken symlink!),
- * zero if it did not.
- */
- int (*isDirectory)(dvoid *opaque, const char *name, int *fileExists);
-
- /*
- * Returns non-zero if filename is really a symlink.
- * This filename is in platform-independent notation.
- *
- * Regardless of success or failure, please set *fileExists to
- * non-zero if the file existed (even if it's a broken symlink!),
- * zero if it did not.
- */
- int (*isSymLink)(dvoid *opaque, const char *name, int *fileExists);
-
- /*
- * Retrieve the last modification time (mtime) of a file.
- * Returns -1 on failure, or the file's mtime in seconds since
- * the epoch (Jan 1, 1970) on success.
- * This filename is in platform-independent notation.
- *
- * Regardless of success or failure, please set *exists to
- * non-zero if the file existed (even if it's a broken symlink!),
- * zero if it did not.
- */
- PHYSFS_sint64 (*getLastModTime)(dvoid *opaque, const char *fnm, int *exist);
-
- /*
- * Open file for reading.
- * This filename is in platform-independent notation.
- * If you can't handle multiple opens of the same file,
- * you can opt to fail for the second call.
- * Fail if the file does not exist.
- * Returns NULL on failure, and calls __PHYSFS_setError().
- * Returns non-NULL on success. The pointer returned will be
- * passed as the "opaque" parameter for later file calls.
- *
- * Regardless of success or failure, please set *fileExists to
- * non-zero if the file existed (even if it's a broken symlink!),
- * zero if it did not.
- */
- fvoid *(*openRead)(dvoid *opaque, const char *fname, int *fileExists);
-
- /*
- * Open file for writing.
- * If the file does not exist, it should be created. If it exists,
- * it should be truncated to zero bytes. The writing
- * offset should be the start of the file.
- * This filename is in platform-independent notation.
- * If you can't handle multiple opens of the same file,
- * you can opt to fail for the second call.
- * Returns NULL on failure, and calls __PHYSFS_setError().
- * Returns non-NULL on success. The pointer returned will be
- * passed as the "opaque" parameter for later file calls.
- */
- fvoid *(*openWrite)(dvoid *opaque, const char *filename);
-
- /*
- * Open file for appending.
- * If the file does not exist, it should be created. The writing
- * offset should be the end of the file.
- * This filename is in platform-independent notation.
- * If you can't handle multiple opens of the same file,
- * you can opt to fail for the second call.
- * Returns NULL on failure, and calls __PHYSFS_setError().
- * Returns non-NULL on success. The pointer returned will be
- * passed as the "opaque" parameter for later file calls.
- */
- fvoid *(*openAppend)(dvoid *opaque, const char *filename);
-
- /*
- * Delete a file in the archive/directory.
- * Return non-zero on success, zero on failure.
- * This filename is in platform-independent notation.
- * This method may be NULL.
- * On failure, call __PHYSFS_setError().
- */
- int (*remove)(dvoid *opaque, const char *filename);
-
- /*
- * Create a directory in the archive/directory.
- * If the application is trying to make multiple dirs, PhysicsFS
- * will split them up into multiple calls before passing them to
- * your driver.
- * Return non-zero on success, zero on failure.
- * This filename is in platform-independent notation.
- * This method may be NULL.
- * On failure, call __PHYSFS_setError().
- */
- int (*mkdir)(dvoid *opaque, const char *filename);
-
- /*
- * Close directories/archives, and free any associated memory,
- * including (opaque) itself if applicable. Implementation can assume
- * that it won't be called if there are still files open from
- * this archive.
- */
- void (*dirClose)(dvoid *opaque);
-
-
-
- /*
- * FILE ROUTINES:
- * These functions are for file handles generated by the open*() methods.
- * They are distinguished by taking a "fvoid" instead of a "dvoid" for
- * the opaque handle.
- */
-
- /*
- * Read more from the file.
- * Returns number of objects of (objSize) bytes read from file, -1
- * if complete failure.
- * On failure, call __PHYSFS_setError().
- */
- PHYSFS_sint64 (*read)(fvoid *opaque, void *buffer,
- PHYSFS_uint32 objSize, PHYSFS_uint32 objCount);
-
- /*
- * Write more to the file. Archives don't have to implement this.
- * (Set it to NULL if not implemented).
- * Returns number of objects of (objSize) bytes written to file, -1
- * if complete failure.
- * On failure, call __PHYSFS_setError().
- */
- PHYSFS_sint64 (*write)(fvoid *opaque, const void *buffer,
- PHYSFS_uint32 objSize, PHYSFS_uint32 objCount);
-
- /*
- * Returns non-zero if at end of file.
- */
- int (*eof)(fvoid *opaque);
-
- /*
- * Returns byte offset from start of file.
- */
- PHYSFS_sint64 (*tell)(fvoid *opaque);
-
- /*
- * Move read/write pointer to byte offset from start of file.
- * Returns non-zero on success, zero on error.
- * On failure, call __PHYSFS_setError().
- */
- int (*seek)(fvoid *opaque, PHYSFS_uint64 offset);
-
- /*
- * Return number of bytes available in the file, or -1 if you
- * aren't able to determine.
- * On failure, call __PHYSFS_setError().
- */
- PHYSFS_sint64 (*fileLength)(fvoid *opaque);
-
- /*
- * Close the file, and free associated resources, including (opaque)
- * if applicable. Returns non-zero on success, zero if can't close
- * file. On failure, call __PHYSFS_setError().
- */
- int (*fileClose)(fvoid *opaque);
-} PHYSFS_Archiver;
-
-
-/*
- * Call this to set the message returned by PHYSFS_getLastError().
- * Please only use the ERR_* constants above, or add new constants to the
- * above group, but I want these all in one place.
- *
- * Calling this with a NULL argument is a safe no-op.
- */
-void __PHYSFS_setError(const char *err);
-
-
-/*
- * Convert (dirName) to platform-dependent notation, then prepend (prepend)
- * and append (append) to the converted string.
- *
- * So, on Win32, calling:
- * __PHYSFS_convertToDependent("C:\", "my/files", NULL);
- * ...will return the string "C:\my\files".
- *
- * This is a convenience function; you might want to hack something out that
- * is less generic (and therefore more efficient).
- *
- * Be sure to free() the return value when done with it.
- */
-char *__PHYSFS_convertToDependent(const char *prepend,
- const char *dirName,
- const char *append);
-
-
-/* This byteorder stuff was lifted from SDL. http://www.libsdl.org/ */
-#define PHYSFS_LIL_ENDIAN 1234
-#define PHYSFS_BIG_ENDIAN 4321
-
-#if defined(__i386__) || defined(__ia64__) || defined(WIN32) || \
- (defined(__alpha__) || defined(__alpha)) || \
- defined(__arm__) || defined(ARM) || \
- (defined(__mips__) && defined(__MIPSEL__)) || \
- defined(__SYMBIAN32__) || \
- defined(__x86_64__) || \
- defined(__LITTLE_ENDIAN__)
-#define PHYSFS_BYTEORDER PHYSFS_LIL_ENDIAN
-#else
-#define PHYSFS_BYTEORDER PHYSFS_BIG_ENDIAN
-#endif
-
-
-/*
- * When sorting the entries in an archive, we use a modified QuickSort.
- * When there are less then PHYSFS_QUICKSORT_THRESHOLD entries left to sort,
- * we switch over to a BubbleSort for the remainder. Tweak to taste.
- *
- * You can override this setting by defining PHYSFS_QUICKSORT_THRESHOLD
- * before #including "physfs_internal.h".
- */
-#ifndef PHYSFS_QUICKSORT_THRESHOLD
-#define PHYSFS_QUICKSORT_THRESHOLD 4
-#endif
-
-/*
- * Sort an array (or whatever) of (max) elements. This uses a mixture of
- * a QuickSort and BubbleSort internally.
- * (cmpfn) is used to determine ordering, and (swapfn) does the actual
- * swapping of elements in the list.
- *
- * See zip.c for an example.
- */
-void __PHYSFS_sort(void *entries, PHYSFS_uint32 max,
- int (*cmpfn)(void *, PHYSFS_uint32, PHYSFS_uint32),
- void (*swapfn)(void *, PHYSFS_uint32, PHYSFS_uint32));
-
-
-/* These get used all over for lessening code clutter. */
-#define BAIL_MACRO(e, r) { __PHYSFS_setError(e); return r; }
-#define BAIL_IF_MACRO(c, e, r) if (c) { __PHYSFS_setError(e); return r; }
-#define BAIL_MACRO_MUTEX(e, m, r) { __PHYSFS_setError(e); __PHYSFS_platformReleaseMutex(m); return r; }
-#define BAIL_IF_MACRO_MUTEX(c, e, m, r) if (c) { __PHYSFS_setError(e); __PHYSFS_platformReleaseMutex(m); return r; }
-#define GOTO_MACRO(e, g) { __PHYSFS_setError(e); goto g; }
-#define GOTO_IF_MACRO(c, e, g) if (c) { __PHYSFS_setError(e); goto g; }
-#define GOTO_MACRO_MUTEX(e, m, g) { __PHYSFS_setError(e); __PHYSFS_platformReleaseMutex(m); goto g; }
-#define GOTO_IF_MACRO_MUTEX(c, e, m, g) if (c) { __PHYSFS_setError(e); __PHYSFS_platformReleaseMutex(m); goto g; }
-
-#define __PHYSFS_ARRAYLEN(x) ( (sizeof (x)) / (sizeof (x[0])) )
-
-#if (defined __GNUC__)
-#define __PHYSFS_SI64(x) x##LL
-#define __PHYSFS_UI64(x) x##ULL
-#elif (defined _MSC_VER)
-#define __PHYSFS_SI64(x) x##i64
-#define __PHYSFS_UI64(x) x##ui64
-#else
-#define __PHYSFS_SI64(x) x
-#define __PHYSFS_UI64(x) x
-#endif
-
-/*
- * Check if a ui64 will fit in the platform's address space.
- * The initial sizeof check will optimize this macro out entirely on
- * 64-bit (and larger?!) platforms, and the other condition will
- * return zero or non-zero if the variable will fit in the platform's
- * size_t, suitable to pass to malloc. This is kinda messy, but effective.
- */
-#define __PHYSFS_ui64FitsAddressSpace(s) ( \
- (sizeof (PHYSFS_uint64) > sizeof (size_t)) && \
- ((s) > (__PHYSFS_UI64(0xFFFFFFFFFFFFFFFF) >> (64-(sizeof(size_t)*8)))) \
-)
-
-/*
- * This is a strcasecmp() or stricmp() replacement that expects both strings
- * to be in UTF-8 encoding. It will do "case folding" to decide if the
- * Unicode codepoints in the strings match.
- *
- * It will report which string is "greater than" the other, but be aware that
- * this doesn't necessarily mean anything: 'a' may be "less than" 'b', but
- * a random Kanji codepoint has no meaningful alphabetically relationship to
- * a Greek Lambda, but being able to assign a reliable "value" makes sorting
- * algorithms possible, if not entirely sane. Most cases should treat the
- * return value as "equal" or "not equal".
- */
-int __PHYSFS_utf8strcasecmp(const char *s1, const char *s2);
-
-/*
- * This works like __PHYSFS_utf8strcasecmp(), but takes a character (NOT BYTE
- * COUNT) argument, like strcasencmp().
- */
-int __PHYSFS_utf8strnicmp(const char *s1, const char *s2, PHYSFS_uint32 l);
-
-/*
- * stricmp() that guarantees to only work with low ASCII. The C runtime
- * stricmp() might try to apply a locale/codepage/etc, which we don't want.
- */
-int __PHYSFS_stricmpASCII(const char *s1, const char *s2);
-
-/*
- * strnicmp() that guarantees to only work with low ASCII. The C runtime
- * strnicmp() might try to apply a locale/codepage/etc, which we don't want.
- */
-int __PHYSFS_strnicmpASCII(const char *s1, const char *s2, PHYSFS_uint32 l);
-
-
-/*
- * The current allocator. Not valid before PHYSFS_init is called!
- */
-extern PHYSFS_Allocator __PHYSFS_AllocatorHooks;
-
-/* convenience macro to make this less cumbersome internally... */
-#define allocator __PHYSFS_AllocatorHooks
-
-/*--------------------------------------------------------------------------*/
-/*--------------------------------------------------------------------------*/
-/*------------ ----------------*/
-/*------------ You MUST implement the following functions ----------------*/
-/*------------ if porting to a new platform. ----------------*/
-/*------------ (see platform/unix.c for an example) ----------------*/
-/*------------ ----------------*/
-/*--------------------------------------------------------------------------*/
-/*--------------------------------------------------------------------------*/
-
-
-/*
- * The dir separator; "/" on unix, "\\" on win32, ":" on MacOS, etc...
- * Obviously, this isn't a function, but it IS a null-terminated string.
- */
-extern const char *__PHYSFS_platformDirSeparator;
-
-
-/*
- * Initialize the platform. This is called when PHYSFS_init() is called from
- * the application. You can use this to (for example) determine what version
- * of Windows you're running.
- *
- * Return zero if there was a catastrophic failure (which prevents you from
- * functioning at all), and non-zero otherwise.
- */
-int __PHYSFS_platformInit(void);
-
-
-/*
- * Deinitialize the platform. This is called when PHYSFS_deinit() is called
- * from the application. You can use this to clean up anything you've
- * allocated in your platform driver.
- *
- * Return zero if there was a catastrophic failure (which prevents you from
- * functioning at all), and non-zero otherwise.
- */
-int __PHYSFS_platformDeinit(void);
-
-
-/*
- * Open a file for reading. (filename) is in platform-dependent notation. The
- * file pointer should be positioned on the first byte of the file.
- *
- * The return value will be some platform-specific datatype that is opaque to
- * the caller; it could be a (FILE *) under Unix, or a (HANDLE *) under win32.
- *
- * The same file can be opened for read multiple times, and each should have
- * a unique file handle; this is frequently employed to prevent race
- * conditions in the archivers.
- *
- * Call __PHYSFS_setError() and return (NULL) if the file can't be opened.
- */
-void *__PHYSFS_platformOpenRead(const char *filename);
-
-
-/*
- * Open a file for writing. (filename) is in platform-dependent notation. If
- * the file exists, it should be truncated to zero bytes, and if it doesn't
- * exist, it should be created as a zero-byte file. The file pointer should
- * be positioned on the first byte of the file.
- *
- * The return value will be some platform-specific datatype that is opaque to
- * the caller; it could be a (FILE *) under Unix, or a (HANDLE *) under win32,
- * etc.
- *
- * Opening a file for write multiple times has undefined results.
- *
- * Call __PHYSFS_setError() and return (NULL) if the file can't be opened.
- */
-void *__PHYSFS_platformOpenWrite(const char *filename);
-
-
-/*
- * Open a file for appending. (filename) is in platform-dependent notation. If
- * the file exists, the file pointer should be place just past the end of the
- * file, so that the first write will be one byte after the current end of
- * the file. If the file doesn't exist, it should be created as a zero-byte
- * file. The file pointer should be positioned on the first byte of the file.
- *
- * The return value will be some platform-specific datatype that is opaque to
- * the caller; it could be a (FILE *) under Unix, or a (HANDLE *) under win32,
- * etc.
- *
- * Opening a file for append multiple times has undefined results.
- *
- * Call __PHYSFS_setError() and return (NULL) if the file can't be opened.
- */
-void *__PHYSFS_platformOpenAppend(const char *filename);
-
-
-/*
- * Read more data from a platform-specific file handle. (opaque) should be
- * cast to whatever data type your platform uses. Read a maximum of (count)
- * objects of (size) 8-bit bytes to the area pointed to by (buffer). If there
- * isn't enough data available, return the number of full objects read, and
- * position the file pointer at the start of the first incomplete object.
- * On success, return (count) and position the file pointer one byte past
- * the end of the last read object. Return (-1) if there is a catastrophic
- * error, and call __PHYSFS_setError() to describe the problem; the file
- * pointer should not move in such a case.
- */
-PHYSFS_sint64 __PHYSFS_platformRead(void *opaque, void *buffer,
- PHYSFS_uint32 size, PHYSFS_uint32 count);
-
-/*
- * Write more data to a platform-specific file handle. (opaque) should be
- * cast to whatever data type your platform uses. Write a maximum of (count)
- * objects of (size) 8-bit bytes from the area pointed to by (buffer). If
- * there isn't enough data available, return the number of full objects
- * written, and position the file pointer at the start of the first
- * incomplete object. Return (-1) if there is a catastrophic error, and call
- * __PHYSFS_setError() to describe the problem; the file pointer should not
- * move in such a case.
- */
-PHYSFS_sint64 __PHYSFS_platformWrite(void *opaque, const void *buffer,
- PHYSFS_uint32 size, PHYSFS_uint32 count);
-
-/*
- * Set the file pointer to a new position. (opaque) should be cast to
- * whatever data type your platform uses. (pos) specifies the number
- * of 8-bit bytes to seek to from the start of the file. Seeking past the
- * end of the file is an error condition, and you should check for it.
- *
- * Not all file types can seek; this is to be expected by the caller.
- *
- * On error, call __PHYSFS_setError() and return zero. On success, return
- * a non-zero value.
- */
-int __PHYSFS_platformSeek(void *opaque, PHYSFS_uint64 pos);
-
-
-/*
- * Get the file pointer's position, in an 8-bit byte offset from the start of
- * the file. (opaque) should be cast to whatever data type your platform
- * uses.
- *
- * Not all file types can "tell"; this is to be expected by the caller.
- *
- * On error, call __PHYSFS_setError() and return zero. On success, return
- * a non-zero value.
- */
-PHYSFS_sint64 __PHYSFS_platformTell(void *opaque);
-
-
-/*
- * Determine the current size of a file, in 8-bit bytes, from an open file.
- *
- * The caller expects that this information may not be available for all
- * file types on all platforms.
- *
- * Return -1 if you can't do it, and call __PHYSFS_setError(). Otherwise,
- * return the file length in 8-bit bytes.
- */
-PHYSFS_sint64 __PHYSFS_platformFileLength(void *handle);
-
-/*
- * Determine if a file is at EOF. (opaque) should be cast to whatever data
- * type your platform uses.
- *
- * The caller expects that there was a short read before calling this.
- *
- * Return non-zero if EOF, zero if it is _not_ EOF.
- */
-int __PHYSFS_platformEOF(void *opaque);
-
-/*
- * Flush any pending writes to disk. (opaque) should be cast to whatever data
- * type your platform uses. Be sure to check for errors; the caller expects
- * that this function can fail if there was a flushing error, etc.
- *
- * Return zero on failure, non-zero on success.
- */
-int __PHYSFS_platformFlush(void *opaque);
-
-/*
- * Flush and close a file. (opaque) should be cast to whatever data type
- * your platform uses. Be sure to check for errors when closing; the
- * caller expects that this function can fail if there was a flushing
- * error, etc.
- *
- * You should clean up all resources associated with (opaque).
- *
- * Return zero on failure, non-zero on success.
- */
-int __PHYSFS_platformClose(void *opaque);
-
-/*
- * Platform implementation of PHYSFS_getCdRomDirsCallback()...
- * CD directories are discovered and reported to the callback one at a time.
- * Pointers passed to the callback are assumed to be invalid to the
- * application after the callback returns, so you can free them or whatever.
- * Callback does not assume results will be sorted in any meaningful way.
- */
-void __PHYSFS_platformDetectAvailableCDs(PHYSFS_StringCallback cb, void *data);
-
-/*
- * Calculate the base dir, if your platform needs special consideration.
- * Just return NULL if the standard routines will suffice. (see
- * calculateBaseDir() in physfs.c ...)
- * Caller will free() the retval if it's not NULL.
- */
-char *__PHYSFS_platformCalcBaseDir(const char *argv0);
-
-/*
- * Get the platform-specific user name.
- * Caller will free() the retval if it's not NULL. If it's NULL, the username
- * will default to "default".
- */
-char *__PHYSFS_platformGetUserName(void);
-
-/*
- * Get the platform-specific user dir.
- * Caller will free() the retval if it's not NULL. If it's NULL, the userdir
- * will default to basedir/username.
- */
-char *__PHYSFS_platformGetUserDir(void);
-
-/*
- * Return a number that uniquely identifies the current thread.
- * On a platform without threading, (1) will suffice. These numbers are
- * arbitrary; the only requirement is that no two threads have the same
- * number.
- */
-PHYSFS_uint64 __PHYSFS_platformGetThreadID(void);
-
-/*
- * Return non-zero if filename (in platform-dependent notation) exists.
- * Symlinks should NOT be followed; at this stage, we do not care what the
- * symlink points to. Please call __PHYSFS_SetError() with the details of
- * why the file does not exist, if it doesn't; you are in a better position
- * to know (path not found, bogus filename, file itself is missing, etc).
- */
-int __PHYSFS_platformExists(const char *fname);
-
-/*
- * Return the last modified time (in seconds since the epoch) of a file.
- * Returns -1 on failure. (fname) is in platform-dependent notation.
- * Symlinks should be followed; if what the symlink points to is missing,
- * then the retval is -1.
- */
-PHYSFS_sint64 __PHYSFS_platformGetLastModTime(const char *fname);
-
-/*
- * Return non-zero if filename (in platform-dependent notation) is a symlink.
- */
-int __PHYSFS_platformIsSymLink(const char *fname);
-
-
-/*
- * Return non-zero if filename (in platform-dependent notation) is a symlink.
- * Symlinks should be followed; if what the symlink points to is missing,
- * or isn't a directory, then the retval is false.
- */
-int __PHYSFS_platformIsDirectory(const char *fname);
-
-
-/*
- * Convert (dirName) to platform-dependent notation, then prepend (prepend)
- * and append (append) to the converted string.
- *
- * So, on Win32, calling:
- * __PHYSFS_platformCvtToDependent("C:\", "my/files", NULL);
- * ...will return the string "C:\my\files".
- *
- * This can be implemented in a platform-specific manner, so you can get
- * get a speed boost that the default implementation can't, since
- * you can make assumptions about the size of strings, etc..
- *
- * Platforms that choose not to implement this may just call
- * __PHYSFS_convertToDependent() as a passthrough, which may fit the bill
- * already.
- *
- * Be sure to free() the return value when done with it.
- */
-char *__PHYSFS_platformCvtToDependent(const char *prepend,
- const char *dirName,
- const char *append);
-
-
-/*
- * Enumerate a directory of files. This follows the rules for the
- * PHYSFS_Archiver->enumerateFiles() method (see above), except that the
- * (dirName) that is passed to this function is converted to
- * platform-DEPENDENT notation by the caller. The PHYSFS_Archiver version
- * uses platform-independent notation. Note that ".", "..", and other
- * metaentries should always be ignored.
- */
-void __PHYSFS_platformEnumerateFiles(const char *dirname,
- int omitSymLinks,
- PHYSFS_EnumFilesCallback callback,
- const char *origdir,
- void *callbackdata);
-
-
-/*
- * Get the current working directory. The return value should be an
- * absolute path in platform-dependent notation. The caller will deallocate
- * the return value with the standard C runtime free() function when it
- * is done with it.
- * On error, return NULL and set the error message.
- */
-char *__PHYSFS_platformCurrentDir(void);
-
-
-/*
- * Get the real physical path to a file. (path) is specified in
- * platform-dependent notation, as should your return value be.
- * All relative paths should be removed, leaving you with an absolute
- * path. Symlinks should be resolved, too, so that the returned value is
- * the most direct path to a file.
- * The return value will be deallocated with the standard C runtime free()
- * function when the caller is done with it.
- * On error, return NULL and set the error message.
- */
-char *__PHYSFS_platformRealPath(const char *path);
-
-
-/*
- * Make a directory in the actual filesystem. (path) is specified in
- * platform-dependent notation. On error, return zero and set the error
- * message. Return non-zero on success.
- */
-int __PHYSFS_platformMkDir(const char *path);
-
-
-/*
- * Remove a file or directory entry in the actual filesystem. (path) is
- * specified in platform-dependent notation. Note that this deletes files
- * _and_ directories, so you might need to do some determination.
- * Non-empty directories should report an error and not delete themselves
- * or their contents.
- *
- * Deleting a symlink should remove the link, not what it points to.
- *
- * On error, return zero and set the error message. Return non-zero on success.
- */
-int __PHYSFS_platformDelete(const char *path);
-
-
-/*
- * Create a platform-specific mutex. This can be whatever datatype your
- * platform uses for mutexes, but it is cast to a (void *) for abstractness.
- *
- * Return (NULL) if you couldn't create one. Systems without threads can
- * return any arbitrary non-NULL value.
- */
-void *__PHYSFS_platformCreateMutex(void);
-
-/*
- * Destroy a platform-specific mutex, and clean up any resources associated
- * with it. (mutex) is a value previously returned by
- * __PHYSFS_platformCreateMutex(). This can be a no-op on single-threaded
- * platforms.
- */
-void __PHYSFS_platformDestroyMutex(void *mutex);
-
-/*
- * Grab possession of a platform-specific mutex. Mutexes should be recursive;
- * that is, the same thread should be able to call this function multiple
- * times in a row without causing a deadlock. This function should block
- * until a thread can gain possession of the mutex.
- *
- * Return non-zero if the mutex was grabbed, zero if there was an
- * unrecoverable problem grabbing it (this should not be a matter of
- * timing out! We're talking major system errors; block until the mutex
- * is available otherwise.)
- *
- * _DO NOT_ call __PHYSFS_setError() in here! Since setError calls this
- * function, you'll cause an infinite recursion. This means you can't
- * use the BAIL_*MACRO* macros, either.
- */
-int __PHYSFS_platformGrabMutex(void *mutex);
-
-/*
- * Relinquish possession of the mutex when this method has been called
- * once for each time that platformGrabMutex was called. Once possession has
- * been released, the next thread in line to grab the mutex (if any) may
- * proceed.
- *
- * _DO NOT_ call __PHYSFS_setError() in here! Since setError calls this
- * function, you'll cause an infinite recursion. This means you can't
- * use the BAIL_*MACRO* macros, either.
- */
-void __PHYSFS_platformReleaseMutex(void *mutex);
-
-/*
- * Called at the start of PHYSFS_init() to prepare the allocator, if the user
- * hasn't selected their own allocator via PHYSFS_setAllocator().
- * If the platform has a custom allocator, it should fill in the fields of
- * (a) with the proper function pointers and return non-zero.
- * If the platform just wants to use malloc()/free()/etc, return zero
- * immediately and the higher level will handle it. The Init and Deinit
- * fields of (a) are optional...set them to NULL if you don't need them.
- * Everything else must be implemented. All rules follow those for
- * PHYSFS_setAllocator(). If Init isn't NULL, it will be called shortly
- * after this function returns non-zero.
- */
-int __PHYSFS_platformSetDefaultAllocator(PHYSFS_Allocator *a);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
-
-/* end of physfs_internal.h ... */
-
+++ /dev/null
-#ifndef _INCL_PHYSFS_PLATFORMS
-#define _INCL_PHYSFS_PLATFORMS
-
-#ifndef __PHYSICSFS_INTERNAL__
-#error Do not include this header from your applications.
-#endif
-
-/*
- * These only define the platforms to determine which files in the platforms
- * directory should be compiled. For example, technically BeOS can be called
- * a "unix" system, but since it doesn't use unix.c, we don't define
- * PHYSFS_PLATFORM_UNIX on that system.
- */
-
-#if ((defined __BEOS__) || (defined __beos__))
-# define PHYSFS_PLATFORM_BEOS
-# define PHYSFS_PLATFORM_POSIX
-#elif (defined _WIN32_WCE) || (defined _WIN64_WCE)
-# define PHYSFS_PLATFORM_POCKETPC
-#elif (((defined _WIN32) || (defined _WIN64)) && (!defined __CYGWIN__))
-# define PHYSFS_PLATFORM_WINDOWS
-#elif (defined OS2)
-# define PHYSFS_PLATFORM_OS2
-#elif ((defined __MACH__) && (defined __APPLE__))
-# define PHYSFS_PLATFORM_MACOSX
-# define PHYSFS_PLATFORM_POSIX
-#elif defined(macintosh)
-# error Classic Mac OS support was dropped from PhysicsFS 2.0. Move to OS X.
-#elif defined(unix)
-# define PHYSFS_PLATFORM_UNIX
-# define PHYSFS_PLATFORM_POSIX
-#else
-# error Unknown platform.
-#endif
-
-#endif /* include-once blocker. */
-
+++ /dev/null
-#include "physfs.h"
-
-#define __PHYSICSFS_INTERNAL__
-#include "physfs_internal.h"
-
-
-/*
- * From rfc3629, the UTF-8 spec:
- * http://www.ietf.org/rfc/rfc3629.txt
- *
- * Char. number range | UTF-8 octet sequence
- * (hexadecimal) | (binary)
- * --------------------+---------------------------------------------
- * 0000 0000-0000 007F | 0xxxxxxx
- * 0000 0080-0000 07FF | 110xxxxx 10xxxxxx
- * 0000 0800-0000 FFFF | 1110xxxx 10xxxxxx 10xxxxxx
- * 0001 0000-0010 FFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
- */
-
-
-/*
- * This may not be the best value, but it's one that isn't represented
- * in Unicode (0x10FFFF is the largest codepoint value). We return this
- * value from utf8codepoint() if there's bogus bits in the
- * stream. utf8codepoint() will turn this value into something
- * reasonable (like a question mark), for text that wants to try to recover,
- * whereas utf8valid() will use the value to determine if a string has bad
- * bits.
- */
-#define UNICODE_BOGUS_CHAR_VALUE 0xFFFFFFFF
-
-/*
- * This is the codepoint we currently return when there was bogus bits in a
- * UTF-8 string. May not fly in Asian locales?
- */
-#define UNICODE_BOGUS_CHAR_CODEPOINT '?'
-
-static PHYSFS_uint32 utf8codepoint(const char **_str)
-{
- const char *str = *_str;
- PHYSFS_uint32 retval = 0;
- PHYSFS_uint32 octet = (PHYSFS_uint32) ((PHYSFS_uint8) *str);
- PHYSFS_uint32 octet2, octet3, octet4;
-
- if (octet == 0) /* null terminator, end of string. */
- return 0;
-
- else if (octet < 128) /* one octet char: 0 to 127 */
- {
- (*_str)++; /* skip to next possible start of codepoint. */
- return(octet);
- } /* else if */
-
- else if ((octet > 127) && (octet < 192)) /* bad (starts with 10xxxxxx). */
- {
- /*
- * Apparently each of these is supposed to be flagged as a bogus
- * char, instead of just resyncing to the next valid codepoint.
- */
- (*_str)++; /* skip to next possible start of codepoint. */
- return UNICODE_BOGUS_CHAR_VALUE;
- } /* else if */
-
- else if (octet < 224) /* two octets */
- {
- octet -= (128+64);
- octet2 = (PHYSFS_uint32) ((PHYSFS_uint8) *(++str));
- if ((octet2 & (128+64)) != 128) /* Format isn't 10xxxxxx? */
- return UNICODE_BOGUS_CHAR_VALUE;
-
- *_str += 2; /* skip to next possible start of codepoint. */
- retval = ((octet << 6) | (octet2 - 128));
- if ((retval >= 0x80) && (retval <= 0x7FF))
- return retval;
- } /* else if */
-
- else if (octet < 240) /* three octets */
- {
- octet -= (128+64+32);
- octet2 = (PHYSFS_uint32) ((PHYSFS_uint8) *(++str));
- if ((octet2 & (128+64)) != 128) /* Format isn't 10xxxxxx? */
- return UNICODE_BOGUS_CHAR_VALUE;
-
- octet3 = (PHYSFS_uint32) ((PHYSFS_uint8) *(++str));
- if ((octet3 & (128+64)) != 128) /* Format isn't 10xxxxxx? */
- return UNICODE_BOGUS_CHAR_VALUE;
-
- *_str += 3; /* skip to next possible start of codepoint. */
- retval = ( ((octet << 12)) | ((octet2-128) << 6) | ((octet3-128)) );
-
- /* There are seven "UTF-16 surrogates" that are illegal in UTF-8. */
- switch (retval)
- {
- case 0xD800:
- case 0xDB7F:
- case 0xDB80:
- case 0xDBFF:
- case 0xDC00:
- case 0xDF80:
- case 0xDFFF:
- return UNICODE_BOGUS_CHAR_VALUE;
- } /* switch */
-
- /* 0xFFFE and 0xFFFF are illegal, too, so we check them at the edge. */
- if ((retval >= 0x800) && (retval <= 0xFFFD))
- return retval;
- } /* else if */
-
- else if (octet < 248) /* four octets */
- {
- octet -= (128+64+32+16);
- octet2 = (PHYSFS_uint32) ((PHYSFS_uint8) *(++str));
- if ((octet2 & (128+64)) != 128) /* Format isn't 10xxxxxx? */
- return UNICODE_BOGUS_CHAR_VALUE;
-
- octet3 = (PHYSFS_uint32) ((PHYSFS_uint8) *(++str));
- if ((octet3 & (128+64)) != 128) /* Format isn't 10xxxxxx? */
- return UNICODE_BOGUS_CHAR_VALUE;
-
- octet4 = (PHYSFS_uint32) ((PHYSFS_uint8) *(++str));
- if ((octet4 & (128+64)) != 128) /* Format isn't 10xxxxxx? */
- return UNICODE_BOGUS_CHAR_VALUE;
-
- *_str += 4; /* skip to next possible start of codepoint. */
- retval = ( ((octet << 18)) | ((octet2 - 128) << 12) |
- ((octet3 - 128) << 6) | ((octet4 - 128)) );
- if ((retval >= 0x10000) && (retval <= 0x10FFFF))
- return retval;
- } /* else if */
-
- /*
- * Five and six octet sequences became illegal in rfc3629.
- * We throw the codepoint away, but parse them to make sure we move
- * ahead the right number of bytes and don't overflow the buffer.
- */
-
- else if (octet < 252) /* five octets */
- {
- octet = (PHYSFS_uint32) ((PHYSFS_uint8) *(++str));
- if ((octet & (128+64)) != 128) /* Format isn't 10xxxxxx? */
- return UNICODE_BOGUS_CHAR_VALUE;
-
- octet = (PHYSFS_uint32) ((PHYSFS_uint8) *(++str));
- if ((octet & (128+64)) != 128) /* Format isn't 10xxxxxx? */
- return UNICODE_BOGUS_CHAR_VALUE;
-
- octet = (PHYSFS_uint32) ((PHYSFS_uint8) *(++str));
- if ((octet & (128+64)) != 128) /* Format isn't 10xxxxxx? */
- return UNICODE_BOGUS_CHAR_VALUE;
-
- octet = (PHYSFS_uint32) ((PHYSFS_uint8) *(++str));
- if ((octet & (128+64)) != 128) /* Format isn't 10xxxxxx? */
- return UNICODE_BOGUS_CHAR_VALUE;
-
- *_str += 5; /* skip to next possible start of codepoint. */
- return UNICODE_BOGUS_CHAR_VALUE;
- } /* else if */
-
- else /* six octets */
- {
- octet = (PHYSFS_uint32) ((PHYSFS_uint8) *(++str));
- if ((octet & (128+64)) != 128) /* Format isn't 10xxxxxx? */
- return UNICODE_BOGUS_CHAR_VALUE;
-
- octet = (PHYSFS_uint32) ((PHYSFS_uint8) *(++str));
- if ((octet & (128+64)) != 128) /* Format isn't 10xxxxxx? */
- return UNICODE_BOGUS_CHAR_VALUE;
-
- octet = (PHYSFS_uint32) ((PHYSFS_uint8) *(++str));
- if ((octet & (128+64)) != 128) /* Format isn't 10xxxxxx? */
- return UNICODE_BOGUS_CHAR_VALUE;
-
- octet = (PHYSFS_uint32) ((PHYSFS_uint8) *(++str));
- if ((octet & (128+64)) != 128) /* Format isn't 10xxxxxx? */
- return UNICODE_BOGUS_CHAR_VALUE;
-
- octet = (PHYSFS_uint32) ((PHYSFS_uint8) *(++str));
- if ((octet & (128+64)) != 128) /* Format isn't 10xxxxxx? */
- return UNICODE_BOGUS_CHAR_VALUE;
-
- *_str += 6; /* skip to next possible start of codepoint. */
- return UNICODE_BOGUS_CHAR_VALUE;
- } /* else if */
-
- return UNICODE_BOGUS_CHAR_VALUE;
-} /* utf8codepoint */
-
-
-void PHYSFS_utf8ToUcs4(const char *src, PHYSFS_uint32 *dst, PHYSFS_uint64 len)
-{
- len -= sizeof (PHYSFS_uint32); /* save room for null char. */
- while (len >= sizeof (PHYSFS_uint32))
- {
- PHYSFS_uint32 cp = utf8codepoint(&src);
- if (cp == 0)
- break;
- else if (cp == UNICODE_BOGUS_CHAR_VALUE)
- cp = UNICODE_BOGUS_CHAR_CODEPOINT;
- *(dst++) = cp;
- len -= sizeof (PHYSFS_uint32);
- } /* while */
-
- *dst = 0;
-} /* PHYSFS_utf8ToUcs4 */
-
-
-void PHYSFS_utf8ToUcs2(const char *src, PHYSFS_uint16 *dst, PHYSFS_uint64 len)
-{
- len -= sizeof (PHYSFS_uint16); /* save room for null char. */
- while (len >= sizeof (PHYSFS_uint16))
- {
- PHYSFS_uint32 cp = utf8codepoint(&src);
- if (cp == 0)
- break;
- else if (cp == UNICODE_BOGUS_CHAR_VALUE)
- cp = UNICODE_BOGUS_CHAR_CODEPOINT;
-
- /* !!! BLUESKY: UTF-16 surrogates? */
- if (cp > 0xFFFF)
- cp = UNICODE_BOGUS_CHAR_CODEPOINT;
-
- *(dst++) = cp;
- len -= sizeof (PHYSFS_uint16);
- } /* while */
-
- *dst = 0;
-} /* PHYSFS_utf8ToUcs2 */
-
-static void utf8fromcodepoint(PHYSFS_uint32 cp, char **_dst, PHYSFS_uint64 *_len)
-{
- char *dst = *_dst;
- PHYSFS_uint64 len = *_len;
-
- if (len == 0)
- return;
-
- if (cp > 0x10FFFF)
- cp = UNICODE_BOGUS_CHAR_CODEPOINT;
- else if ((cp == 0xFFFE) || (cp == 0xFFFF)) /* illegal values. */
- cp = UNICODE_BOGUS_CHAR_CODEPOINT;
- else
- {
- /* There are seven "UTF-16 surrogates" that are illegal in UTF-8. */
- switch (cp)
- {
- case 0xD800:
- case 0xDB7F:
- case 0xDB80:
- case 0xDBFF:
- case 0xDC00:
- case 0xDF80:
- case 0xDFFF:
- cp = UNICODE_BOGUS_CHAR_CODEPOINT;
- } /* switch */
- } /* else */
-
- /* Do the encoding... */
- if (cp < 0x80)
- {
- *(dst++) = (char) cp;
- len--;
- } /* if */
-
- else if (cp < 0x800)
- {
- if (len < 2)
- len = 0;
- else
- {
- *(dst++) = (char) ((cp >> 6) | 128 | 64);
- *(dst++) = (char) (cp & 0x3F) | 128;
- len -= 2;
- } /* else */
- } /* else if */
-
- else if (cp < 0x10000)
- {
- if (len < 3)
- len = 0;
- else
- {
- *(dst++) = (char) ((cp >> 12) | 128 | 64 | 32);
- *(dst++) = (char) ((cp >> 6) & 0x3F) | 128;
- *(dst++) = (char) (cp & 0x3F) | 128;
- len -= 3;
- } /* else */
- } /* else if */
-
- else
- {
- if (len < 4)
- len = 0;
- else
- {
- *(dst++) = (char) ((cp >> 18) | 128 | 64 | 32 | 16);
- *(dst++) = (char) ((cp >> 12) & 0x3F) | 128;
- *(dst++) = (char) ((cp >> 6) & 0x3F) | 128;
- *(dst++) = (char) (cp & 0x3F) | 128;
- len -= 4;
- } /* else if */
- } /* else */
-
- *_dst = dst;
- *_len = len;
-} /* utf8fromcodepoint */
-
-#define UTF8FROMTYPE(typ, src, dst, len) \
- len--; \
- while (len) \
- { \
- const PHYSFS_uint32 cp = (PHYSFS_uint32) *(src++); \
- if (cp == 0) break; \
- utf8fromcodepoint(cp, &dst, &len); \
- } \
- *dst = '\0'; \
-
-void PHYSFS_utf8FromUcs4(const PHYSFS_uint32 *src, char *dst, PHYSFS_uint64 len)
-{
- UTF8FROMTYPE(PHYSFS_uint32, src, dst, len);
-} /* PHYSFS_utf8FromUcs4 */
-
-void PHYSFS_utf8FromUcs2(const PHYSFS_uint16 *src, char *dst, PHYSFS_uint64 len)
-{
- UTF8FROMTYPE(PHYSFS_uint64, src, dst, len);
-} /* PHYSFS_utf8FromUcs4 */
-
-/* latin1 maps to unicode codepoints directly, we just utf-8 encode it. */
-void PHYSFS_utf8FromLatin1(const char *src, char *dst, PHYSFS_uint64 len)
-{
- UTF8FROMTYPE(PHYSFS_uint8, src, dst, len);
-} /* PHYSFS_utf8FromLatin1 */
-
-#undef UTF8FROMTYPE
-
-
-typedef struct CaseFoldMapping
-{
- PHYSFS_uint32 from;
- PHYSFS_uint32 to0;
- PHYSFS_uint32 to1;
- PHYSFS_uint32 to2;
-} CaseFoldMapping;
-
-typedef struct CaseFoldHashBucket
-{
- const PHYSFS_uint8 count;
- const CaseFoldMapping *list;
-} CaseFoldHashBucket;
-
-#include "physfs_casefolding.h"
-
-static void locate_case_fold_mapping(const PHYSFS_uint32 from,
- PHYSFS_uint32 *to)
-{
- PHYSFS_uint32 i;
- const PHYSFS_uint8 hashed = ((from ^ (from >> 8)) & 0xFF);
- const CaseFoldHashBucket *bucket = &case_fold_hash[hashed];
- const CaseFoldMapping *mapping = bucket->list;
-
- for (i = 0; i < bucket->count; i++, mapping++)
- {
- if (mapping->from == from)
- {
- to[0] = mapping->to0;
- to[1] = mapping->to1;
- to[2] = mapping->to2;
- return;
- } /* if */
- } /* for */
-
- /* Not found...there's no remapping for this codepoint. */
- to[0] = from;
- to[1] = 0;
- to[2] = 0;
-} /* locate_case_fold_mapping */
-
-
-static int utf8codepointcmp(const PHYSFS_uint32 cp1, const PHYSFS_uint32 cp2)
-{
- PHYSFS_uint32 folded1[3], folded2[3];
- locate_case_fold_mapping(cp1, folded1);
- locate_case_fold_mapping(cp2, folded2);
- return ( (folded1[0] == folded2[0]) &&
- (folded1[1] == folded2[1]) &&
- (folded1[2] == folded2[2]) );
-} /* utf8codepointcmp */
-
-
-int __PHYSFS_utf8strcasecmp(const char *str1, const char *str2)
-{
- while (1)
- {
- const PHYSFS_uint32 cp1 = utf8codepoint(&str1);
- const PHYSFS_uint32 cp2 = utf8codepoint(&str2);
- if (!utf8codepointcmp(cp1, cp2)) return 0;
- if (cp1 == 0) return 1;
- } /* while */
-
- return 0; /* shouldn't hit this. */
-} /* __PHYSFS_utf8strcasecmp */
-
-
-int __PHYSFS_utf8strnicmp(const char *str1, const char *str2, PHYSFS_uint32 n)
-{
- while (n > 0)
- {
- const PHYSFS_uint32 cp1 = utf8codepoint(&str1);
- const PHYSFS_uint32 cp2 = utf8codepoint(&str2);
- if (!utf8codepointcmp(cp1, cp2)) return 0;
- if (cp1 == 0) return 1;
- n--;
- } /* while */
-
- return 1; /* matched to n chars. */
-} /* __PHYSFS_utf8strnicmp */
-
-
-int __PHYSFS_stricmpASCII(const char *str1, const char *str2)
-{
- while (1)
- {
- const char ch1 = *(str1++);
- const char ch2 = *(str2++);
- const char cp1 = ((ch1 >= 'A') && (ch1 <= 'Z')) ? (ch1+32) : ch1;
- const char cp2 = ((ch2 >= 'A') && (ch2 <= 'Z')) ? (ch2+32) : ch2;
- if (cp1 < cp2)
- return -1;
- else if (cp1 > cp2)
- return 1;
- else if (cp1 == 0) /* they're both null chars? */
- return 0;
- } /* while */
-
- return 0; /* shouldn't hit this. */
-} /* __PHYSFS_stricmpASCII */
-
-
-int __PHYSFS_strnicmpASCII(const char *str1, const char *str2, PHYSFS_uint32 n)
-{
- while (n-- > 0)
- {
- const char ch1 = *(str1++);
- const char ch2 = *(str2++);
- const char cp1 = ((ch1 >= 'A') && (ch1 <= 'Z')) ? (ch1+32) : ch1;
- const char cp2 = ((ch2 >= 'A') && (ch2 <= 'Z')) ? (ch2+32) : ch2;
- if (cp1 < cp2)
- return -1;
- else if (cp1 > cp2)
- return 1;
- else if (cp1 == 0) /* they're both null chars? */
- return 0;
- } /* while */
-
- return 0;
-} /* __PHYSFS_stricmpASCII */
-
-
-/* end of physfs_unicode.c ... */
-
+++ /dev/null
-/*
- * BeOS platform-dependent support routines for PhysicsFS.
- *
- * Please see the file LICENSE.txt in the source's root directory.
- *
- * This file written by Ryan C. Gordon.
- */
-
-#define __PHYSICSFS_INTERNAL__
-#include "physfs_platforms.h"
-
-#ifdef PHYSFS_PLATFORM_BEOS
-
-#include <be/kernel/OS.h>
-#include <be/app/Roster.h>
-#include <be/storage/Volume.h>
-#include <be/storage/VolumeRoster.h>
-#include <be/storage/Directory.h>
-#include <be/storage/Entry.h>
-#include <be/storage/Path.h>
-#include <be/kernel/fs_info.h>
-#include <be/device/scsi.h>
-#include <be/support/Locker.h>
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <unistd.h>
-
-#include "physfs_internal.h"
-
-
-int __PHYSFS_platformInit(void)
-{
- return(1); /* always succeed. */
-} /* __PHYSFS_platformInit */
-
-
-int __PHYSFS_platformDeinit(void)
-{
- return(1); /* always succeed. */
-} /* __PHYSFS_platformDeinit */
-
-
-static char *getMountPoint(const char *devname)
-{
- BVolumeRoster mounts;
- BVolume vol;
-
- mounts.Rewind();
- while (mounts.GetNextVolume(&vol) == B_NO_ERROR)
- {
- fs_info fsinfo;
- fs_stat_dev(vol.Device(), &fsinfo);
- if (strcmp(devname, fsinfo.device_name) == 0)
- {
- //char buf[B_FILE_NAME_LENGTH];
- BDirectory directory;
- BEntry entry;
- BPath path;
- status_t rc;
- rc = vol.GetRootDirectory(&directory);
- BAIL_IF_MACRO(rc < B_OK, strerror(rc), NULL);
- rc = directory.GetEntry(&entry);
- BAIL_IF_MACRO(rc < B_OK, strerror(rc), NULL);
- rc = entry.GetPath(&path);
- BAIL_IF_MACRO(rc < B_OK, strerror(rc), NULL);
- const char *str = path.Path();
- BAIL_IF_MACRO(str == NULL, ERR_OS_ERROR, NULL); /* ?! */
- char *retval = (char *) allocator.Malloc(strlen(str) + 1);
- BAIL_IF_MACRO(retval == NULL, ERR_OUT_OF_MEMORY, NULL);
- strcpy(retval, str);
- return(retval);
- } /* if */
- } /* while */
-
- return(NULL);
-} /* getMountPoint */
-
-
- /*
- * This function is lifted from Simple Directmedia Layer (SDL):
- * http://www.libsdl.org/
- */
-static void tryDir(const char *d, PHYSFS_StringCallback callback, void *data)
-{
- BDirectory dir;
- dir.SetTo(d);
- if (dir.InitCheck() != B_NO_ERROR)
- return;
-
- dir.Rewind();
- BEntry entry;
- while (dir.GetNextEntry(&entry) >= 0)
- {
- BPath path;
- const char *name;
- entry_ref e;
-
- if (entry.GetPath(&path) != B_NO_ERROR)
- continue;
-
- name = path.Path();
-
- if (entry.GetRef(&e) != B_NO_ERROR)
- continue;
-
- if (entry.IsDirectory())
- {
- if (strcmp(e.name, "floppy") != 0)
- tryDir(name, callback, data);
- } /* if */
-
- else
- {
- bool add_it = false;
- int devfd;
- device_geometry g;
-
- if (strcmp(e.name, "raw") == 0) /* ignore partitions. */
- {
- int devfd = open(name, O_RDONLY);
- if (devfd >= 0)
- {
- if (ioctl(devfd, B_GET_GEOMETRY, &g, sizeof(g)) >= 0)
- {
- if (g.device_type == B_CD)
- {
- char *mntpnt = getMountPoint(name);
- if (mntpnt != NULL)
- {
- callback(data, mntpnt);
- allocator.Free(mntpnt); /* !!! FIXME: lose this malloc! */
- } /* if */
- } /* if */
- } /* if */
- } /* if */
- } /* if */
-
- close(devfd);
- } /* else */
- } /* while */
-} /* tryDir */
-
-
-void __PHYSFS_platformDetectAvailableCDs(PHYSFS_StringCallback cb, void *data)
-{
- tryDir("/dev/disk", cb, data);
-} /* __PHYSFS_platformDetectAvailableCDs */
-
-
-static team_id getTeamID(void)
-{
- thread_info info;
- thread_id tid = find_thread(NULL);
- get_thread_info(tid, &info);
- return(info.team);
-} /* getTeamID */
-
-
-char *__PHYSFS_platformCalcBaseDir(const char *argv0)
-{
- /* in case there isn't a BApplication yet, we'll construct a roster. */
- BRoster roster;
- app_info info;
- status_t rc = roster.GetRunningAppInfo(getTeamID(), &info);
- BAIL_IF_MACRO(rc < B_OK, strerror(rc), NULL);
- BEntry entry(&(info.ref), true);
- BPath path;
- rc = entry.GetPath(&path); /* (path) now has binary's path. */
- assert(rc == B_OK);
- rc = path.GetParent(&path); /* chop filename, keep directory. */
- assert(rc == B_OK);
- const char *str = path.Path();
- assert(str != NULL);
- char *retval = (char *) allocator.Malloc(strlen(str) + 1);
- BAIL_IF_MACRO(retval == NULL, ERR_OUT_OF_MEMORY, NULL);
- strcpy(retval, str);
- return(retval);
-} /* __PHYSFS_platformCalcBaseDir */
-
-
-PHYSFS_uint64 __PHYSFS_platformGetThreadID(void)
-{
- return((PHYSFS_uint64) find_thread(NULL));
-} /* __PHYSFS_platformGetThreadID */
-
-
-char *__PHYSFS_platformRealPath(const char *path)
-{
- BPath normalized(path, NULL, true); /* force normalization of path. */
- const char *resolved_path = normalized.Path();
- BAIL_IF_MACRO(resolved_path == NULL, ERR_NO_SUCH_FILE, NULL);
- char *retval = (char *) allocator.Malloc(strlen(resolved_path) + 1);
- BAIL_IF_MACRO(retval == NULL, ERR_OUT_OF_MEMORY, NULL);
- strcpy(retval, resolved_path);
- return(retval);
-} /* __PHYSFS_platformRealPath */
-
-
-char *__PHYSFS_platformCurrentDir(void)
-{
- return(__PHYSFS_platformRealPath(".")); /* let BPath sort it out. */
-} /* __PHYSFS_platformCurrentDir */
-
-
-void *__PHYSFS_platformCreateMutex(void)
-{
- return(new BLocker("PhysicsFS lock", true));
-} /* __PHYSFS_platformCreateMutex */
-
-
-void __PHYSFS_platformDestroyMutex(void *mutex)
-{
- delete ((BLocker *) mutex);
-} /* __PHYSFS_platformDestroyMutex */
-
-
-int __PHYSFS_platformGrabMutex(void *mutex)
-{
- return ((BLocker *) mutex)->Lock() ? 1 : 0;
-} /* __PHYSFS_platformGrabMutex */
-
-
-void __PHYSFS_platformReleaseMutex(void *mutex)
-{
- ((BLocker *) mutex)->Unlock();
-} /* __PHYSFS_platformReleaseMutex */
-
-
-int __PHYSFS_platformSetDefaultAllocator(PHYSFS_Allocator *a)
-{
- return(0); /* just use malloc() and friends. */
-} /* __PHYSFS_platformSetDefaultAllocator */
-
-#endif /* PHYSFS_PLATFORM_BEOS */
-
-/* end of beos.cpp ... */
-
+++ /dev/null
-/*
- * Mac OS X support routines for PhysicsFS.
- *
- * Please see the file LICENSE.txt in the source's root directory.
- *
- * This file written by Ryan C. Gordon.
- */
-
-#define __PHYSICSFS_INTERNAL__
-#include "physfs_platforms.h"
-
-#ifdef PHYSFS_PLATFORM_MACOSX
-
-#include <Carbon/Carbon.h>
-#include <IOKit/storage/IOMedia.h>
-#include <IOKit/storage/IOCDMedia.h>
-#include <IOKit/storage/IODVDMedia.h>
-#include <sys/mount.h>
-
-/* Seems to get defined in some system header... */
-#ifdef Free
-#undef Free
-#endif
-
-#include "physfs_internal.h"
-
-
-/* Wrap PHYSFS_Allocator in a CFAllocator... */
-static CFAllocatorRef cfallocator = NULL;
-
-CFStringRef cfallocDesc(const void *info)
-{
- return(CFStringCreateWithCString(cfallocator, "PhysicsFS",
- kCFStringEncodingASCII));
-} /* cfallocDesc */
-
-
-static void *cfallocMalloc(CFIndex allocSize, CFOptionFlags hint, void *info)
-{
- return allocator.Malloc(allocSize);
-} /* cfallocMalloc */
-
-
-static void cfallocFree(void *ptr, void *info)
-{
- allocator.Free(ptr);
-} /* cfallocFree */
-
-
-static void *cfallocRealloc(void *ptr, CFIndex newsize,
- CFOptionFlags hint, void *info)
-{
- if ((ptr == NULL) || (newsize <= 0))
- return NULL; /* ADC docs say you should always return NULL here. */
- return allocator.Realloc(ptr, newsize);
-} /* cfallocRealloc */
-
-
-int __PHYSFS_platformInit(void)
-{
- /* set up a CFAllocator, so Carbon can use the physfs allocator, too. */
- CFAllocatorContext ctx;
- memset(&ctx, '\0', sizeof (ctx));
- ctx.copyDescription = cfallocDesc;
- ctx.allocate = cfallocMalloc;
- ctx.reallocate = cfallocRealloc;
- ctx.deallocate = cfallocFree;
- cfallocator = CFAllocatorCreate(kCFAllocatorUseContext, &ctx);
- BAIL_IF_MACRO(cfallocator == NULL, ERR_OUT_OF_MEMORY, 0);
- return(1); /* success. */
-} /* __PHYSFS_platformInit */
-
-
-int __PHYSFS_platformDeinit(void)
-{
- CFRelease(cfallocator);
- cfallocator = NULL;
- return(1); /* always succeed. */
-} /* __PHYSFS_platformDeinit */
-
-
-/* CD-ROM detection code... */
-
-/*
- * Code based on sample from Apple Developer Connection:
- * http://developer.apple.com/samplecode/Sample_Code/Devices_and_Hardware/Disks/VolumeToBSDNode/VolumeToBSDNode.c.htm
- */
-
-static int darwinIsWholeMedia(io_service_t service)
-{
- int retval = 0;
- CFTypeRef wholeMedia;
-
- if (!IOObjectConformsTo(service, kIOMediaClass))
- return(0);
-
- wholeMedia = IORegistryEntryCreateCFProperty(service,
- CFSTR(kIOMediaWholeKey),
- cfallocator, 0);
- if (wholeMedia == NULL)
- return(0);
-
- retval = CFBooleanGetValue(wholeMedia);
- CFRelease(wholeMedia);
-
- return retval;
-} /* darwinIsWholeMedia */
-
-
-static int darwinIsMountedDisc(char *bsdName, mach_port_t masterPort)
-{
- int retval = 0;
- CFMutableDictionaryRef matchingDict;
- kern_return_t rc;
- io_iterator_t iter;
- io_service_t service;
-
- if ((matchingDict = IOBSDNameMatching(masterPort, 0, bsdName)) == NULL)
- return(0);
-
- rc = IOServiceGetMatchingServices(masterPort, matchingDict, &iter);
- if ((rc != KERN_SUCCESS) || (!iter))
- return(0);
-
- service = IOIteratorNext(iter);
- IOObjectRelease(iter);
- if (!service)
- return(0);
-
- rc = IORegistryEntryCreateIterator(service, kIOServicePlane,
- kIORegistryIterateRecursively | kIORegistryIterateParents, &iter);
-
- if (!iter)
- return(0);
-
- if (rc != KERN_SUCCESS)
- {
- IOObjectRelease(iter);
- return(0);
- } /* if */
-
- IOObjectRetain(service); /* add an extra object reference... */
-
- do
- {
- if (darwinIsWholeMedia(service))
- {
- if ( (IOObjectConformsTo(service, kIOCDMediaClass)) ||
- (IOObjectConformsTo(service, kIODVDMediaClass)) )
- {
- retval = 1;
- } /* if */
- } /* if */
- IOObjectRelease(service);
- } while ((service = IOIteratorNext(iter)) && (!retval));
-
- IOObjectRelease(iter);
- IOObjectRelease(service);
-
- return(retval);
-} /* darwinIsMountedDisc */
-
-
-void __PHYSFS_platformDetectAvailableCDs(PHYSFS_StringCallback cb, void *data)
-{
- const char *devPrefix = "/dev/";
- const int prefixLen = strlen(devPrefix);
- mach_port_t masterPort = 0;
- struct statfs *mntbufp;
- int i, mounts;
-
- if (IOMasterPort(MACH_PORT_NULL, &masterPort) != KERN_SUCCESS)
- BAIL_MACRO(ERR_OS_ERROR, ) /*return void*/;
-
- mounts = getmntinfo(&mntbufp, MNT_WAIT); /* NOT THREAD SAFE! */
- for (i = 0; i < mounts; i++)
- {
- char *dev = mntbufp[i].f_mntfromname;
- char *mnt = mntbufp[i].f_mntonname;
- if (strncmp(dev, devPrefix, prefixLen) != 0) /* a virtual device? */
- continue;
-
- dev += prefixLen;
- if (darwinIsMountedDisc(dev, masterPort))
- cb(data, mnt);
- } /* for */
-} /* __PHYSFS_platformDetectAvailableCDs */
-
-
-static char *convertCFString(CFStringRef cfstr)
-{
- CFIndex len = CFStringGetMaximumSizeForEncoding(CFStringGetLength(cfstr),
- kCFStringEncodingUTF8) + 1;
- char *retval = (char *) allocator.Malloc(len);
- BAIL_IF_MACRO(retval == NULL, ERR_OUT_OF_MEMORY, NULL);
-
- if (CFStringGetCString(cfstr, retval, len, kCFStringEncodingUTF8))
- {
- /* shrink overallocated buffer if possible... */
- CFIndex newlen = strlen(retval) + 1;
- if (newlen < len)
- {
- void *ptr = allocator.Realloc(retval, newlen);
- if (ptr != NULL)
- retval = (char *) ptr;
- } /* if */
- } /* if */
-
- else /* probably shouldn't fail, but just in case... */
- {
- allocator.Free(retval);
- BAIL_MACRO(ERR_OUT_OF_MEMORY, NULL);
- } /* else */
-
- return(retval);
-} /* convertCFString */
-
-
-char *__PHYSFS_platformCalcBaseDir(const char *argv0)
-{
- ProcessSerialNumber psn = { 0, kCurrentProcess };
- FSRef fsref;
- CFRange cfrange;
- CFURLRef cfurl = NULL;
- CFStringRef cfstr = NULL;
- CFMutableStringRef cfmutstr = NULL;
- char *retval = NULL;
-
- BAIL_IF_MACRO(GetProcessBundleLocation(&psn, &fsref) != noErr, NULL, NULL);
- cfurl = CFURLCreateFromFSRef(cfallocator, &fsref);
- BAIL_IF_MACRO(cfurl == NULL, NULL, NULL);
- cfstr = CFURLCopyFileSystemPath(cfurl, kCFURLPOSIXPathStyle);
- CFRelease(cfurl);
- BAIL_IF_MACRO(cfstr == NULL, NULL, NULL);
- cfmutstr = CFStringCreateMutableCopy(cfallocator, 0, cfstr);
- CFRelease(cfstr);
- BAIL_IF_MACRO(cfmutstr == NULL, NULL, NULL);
-
- /* Find last dirsep so we can chop the binary's filename from the path. */
- cfrange = CFStringFind(cfmutstr, CFSTR("/"), kCFCompareBackwards);
- if (cfrange.location == kCFNotFound)
- {
- assert(0); /* shouldn't ever hit this... */
- CFRelease(cfmutstr);
- return(NULL);
- } /* if */
-
- /* chop the "/exename" from the end of the path string... */
- cfrange.length = CFStringGetLength(cfmutstr) - cfrange.location;
- CFStringDelete(cfmutstr, cfrange);
-
- /* If we're an Application Bundle, chop everything but the base. */
- cfrange = CFStringFind(cfmutstr, CFSTR("/Contents/MacOS"),
- kCFCompareCaseInsensitive |
- kCFCompareBackwards |
- kCFCompareAnchored);
-
- if (cfrange.location != kCFNotFound)
- CFStringDelete(cfmutstr, cfrange); /* chop that, too. */
-
- retval = convertCFString(cfmutstr);
- CFRelease(cfmutstr);
-
- return(retval); /* whew. */
-} /* __PHYSFS_platformCalcBaseDir */
-
-
-/* !!! FIXME */
-#define osxerr(x) x
-
-char *__PHYSFS_platformRealPath(const char *path)
-{
- /* The symlink and relative path resolving happens in FSPathMakeRef() */
- FSRef fsref;
- CFURLRef cfurl = NULL;
- CFStringRef cfstr = NULL;
- char *retval = NULL;
- OSStatus rc = osxerr(FSPathMakeRef((UInt8 *) path, &fsref, NULL));
- BAIL_IF_MACRO(rc != noErr, NULL, NULL);
-
- /* Now get it to spit out a full path. */
- cfurl = CFURLCreateFromFSRef(cfallocator, &fsref);
- BAIL_IF_MACRO(cfurl == NULL, ERR_OUT_OF_MEMORY, NULL);
- cfstr = CFURLCopyFileSystemPath(cfurl, kCFURLPOSIXPathStyle);
- CFRelease(cfurl);
- BAIL_IF_MACRO(cfstr == NULL, ERR_OUT_OF_MEMORY, NULL);
- retval = convertCFString(cfstr);
- CFRelease(cfstr);
-
- return(retval);
-} /* __PHYSFS_platformRealPath */
-
-
-char *__PHYSFS_platformCurrentDir(void)
-{
- return(__PHYSFS_platformRealPath(".")); /* let CFURL sort it out. */
-} /* __PHYSFS_platformCurrentDir */
-
-
-/* Platform allocator uses default CFAllocator at PHYSFS_init() time. */
-
-static CFAllocatorRef cfallocdef = NULL;
-
-static int macosxAllocatorInit(void)
-{
- int retval = 0;
- cfallocdef = CFAllocatorGetDefault();
- retval = (cfallocdef != NULL);
- if (retval)
- CFRetain(cfallocdef);
- return(retval);
-} /* macosxAllocatorInit */
-
-
-static void macosxAllocatorDeinit(void)
-{
- if (cfallocdef != NULL)
- {
- CFRelease(cfallocdef);
- cfallocdef = NULL;
- } /* if */
-} /* macosxAllocatorDeinit */
-
-
-static void *macosxAllocatorMalloc(PHYSFS_uint64 s)
-{
- BAIL_IF_MACRO(__PHYSFS_ui64FitsAddressSpace(s), ERR_OUT_OF_MEMORY, NULL);
- return(CFAllocatorAllocate(cfallocdef, (CFIndex) s, 0));
-} /* macosxAllocatorMalloc */
-
-
-static void *macosxAllocatorRealloc(void *ptr, PHYSFS_uint64 s)
-{
- BAIL_IF_MACRO(__PHYSFS_ui64FitsAddressSpace(s), ERR_OUT_OF_MEMORY, NULL);
- return(CFAllocatorReallocate(cfallocdef, ptr, (CFIndex) s, 0));
-} /* macosxAllocatorRealloc */
-
-
-static void macosxAllocatorFree(void *ptr)
-{
- CFAllocatorDeallocate(cfallocdef, ptr);
-} /* macosxAllocatorFree */
-
-
-int __PHYSFS_platformSetDefaultAllocator(PHYSFS_Allocator *a)
-{
- allocator.Init = macosxAllocatorInit;
- allocator.Deinit = macosxAllocatorDeinit;
- allocator.Malloc = macosxAllocatorMalloc;
- allocator.Realloc = macosxAllocatorRealloc;
- allocator.Free = macosxAllocatorFree;
- return(1); /* return non-zero: we're supplying custom allocator. */
-} /* __PHYSFS_platformSetDefaultAllocator */
-
-
-PHYSFS_uint64 __PHYSFS_platformGetThreadID(void)
-{
- return( (PHYSFS_uint64) ((size_t) MPCurrentTaskID()) );
-} /* __PHYSFS_platformGetThreadID */
-
-
-void *__PHYSFS_platformCreateMutex(void)
-{
- MPCriticalRegionID m = NULL;
- if (osxerr(MPCreateCriticalRegion(&m)) != noErr)
- return NULL;
- return m;
-} /* __PHYSFS_platformCreateMutex */
-
-
-void __PHYSFS_platformDestroyMutex(void *mutex)
-{
- MPCriticalRegionID m = (MPCriticalRegionID) mutex;
- MPDeleteCriticalRegion(m);
-} /* __PHYSFS_platformDestroyMutex */
-
-
-int __PHYSFS_platformGrabMutex(void *mutex)
-{
- MPCriticalRegionID m = (MPCriticalRegionID) mutex;
- if (MPEnterCriticalRegion(m, kDurationForever) != noErr)
- return(0);
- return(1);
-} /* __PHYSFS_platformGrabMutex */
-
-
-void __PHYSFS_platformReleaseMutex(void *mutex)
-{
- MPCriticalRegionID m = (MPCriticalRegionID) mutex;
- MPExitCriticalRegion(m);
-} /* __PHYSFS_platformReleaseMutex */
-
-#endif /* PHYSFS_PLATFORM_MACOSX */
-
-/* end of macosx.c ... */
-
+++ /dev/null
-/*
- * OS/2 support routines for PhysicsFS.
- *
- * Please see the file LICENSE.txt in the source's root directory.
- *
- * This file written by Ryan C. Gordon.
- */
-
-#define __PHYSICSFS_INTERNAL__
-#include "physfs_platforms.h"
-
-#ifdef PHYSFS_PLATFORM_OS2
-
-#define INCL_DOSSEMAPHORES
-#define INCL_DOSDATETIME
-#define INCL_DOSFILEMGR
-#define INCL_DOSMODULEMGR
-#define INCL_DOSERRORS
-#define INCL_DOSPROCESS
-#define INCL_DOSDEVICES
-#define INCL_DOSDEVIOCTL
-#define INCL_DOSMISC
-#include <os2.h>
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <string.h>
-#include <time.h>
-#include <ctype.h>
-
-#include "physfs_internal.h"
-
-const char *__PHYSFS_platformDirSeparator = "\\";
-
-
-static const char *get_os2_error_string(APIRET rc)
-{
- switch (rc)
- {
- case NO_ERROR: return(NULL); /* not an error. */
- case ERROR_INTERRUPT: return(NULL); /* not an error. */
- case ERROR_TIMEOUT: return(NULL); /* not an error. */
- case ERROR_NOT_ENOUGH_MEMORY: return(ERR_OUT_OF_MEMORY);
- case ERROR_FILE_NOT_FOUND: return(ERR_NO_SUCH_FILE);
- case ERROR_PATH_NOT_FOUND: return(ERR_NO_SUCH_PATH);
- case ERROR_ACCESS_DENIED: return(ERR_ACCESS_DENIED);
- case ERROR_NOT_DOS_DISK: return(ERR_NOT_A_DOS_DISK);
- case ERROR_SHARING_VIOLATION: return(ERR_SHARING_VIOLATION);
- case ERROR_CANNOT_MAKE: return(ERR_CANNOT_MAKE);
- case ERROR_DEVICE_IN_USE: return(ERR_DEV_IN_USE);
- case ERROR_OPEN_FAILED: return(ERR_OPEN_FAILED);
- case ERROR_DISK_FULL: return(ERR_DISK_FULL);
- case ERROR_PIPE_BUSY: return(ERR_PIPE_BUSY);
- case ERROR_SHARING_BUFFER_EXCEEDED: return(ERR_SHARING_BUF_EXCEEDED);
- case ERROR_FILENAME_EXCED_RANGE: return(ERR_BAD_FILENAME);
- case ERROR_META_EXPANSION_TOO_LONG: return(ERR_BAD_FILENAME);
- case ERROR_TOO_MANY_HANDLES: return(ERR_TOO_MANY_HANDLES);
- case ERROR_TOO_MANY_OPEN_FILES: return(ERR_TOO_MANY_HANDLES);
- case ERROR_NO_MORE_SEARCH_HANDLES: return(ERR_TOO_MANY_HANDLES);
- case ERROR_SEEK_ON_DEVICE: return(ERR_SEEK_ERROR);
- case ERROR_NEGATIVE_SEEK: return(ERR_SEEK_OUT_OF_RANGE);
- /*!!! FIXME: Where did this go? case ERROR_DEL_CURRENT_DIRECTORY: return(ERR_DEL_CWD);*/
- case ERROR_WRITE_PROTECT: return(ERR_WRITE_PROTECT_ERROR);
- case ERROR_WRITE_FAULT: return(ERR_WRITE_FAULT);
- case ERROR_LOCK_VIOLATION: return(ERR_LOCK_VIOLATION);
- case ERROR_GEN_FAILURE: return(ERR_GEN_FAILURE);
- case ERROR_UNCERTAIN_MEDIA: return(ERR_UNCERTAIN_MEDIA);
- case ERROR_PROTECTION_VIOLATION: return(ERR_PROT_VIOLATION);
- case ERROR_BROKEN_PIPE: return(ERR_BROKEN_PIPE);
-
- case ERROR_INVALID_PARAMETER:
- case ERROR_INVALID_NAME:
- case ERROR_INVALID_DRIVE:
- case ERROR_INVALID_HANDLE:
- case ERROR_INVALID_FUNCTION:
- case ERROR_INVALID_LEVEL:
- case ERROR_INVALID_CATEGORY:
- case ERROR_DUPLICATE_NAME:
- case ERROR_BUFFER_OVERFLOW:
- case ERROR_BAD_LENGTH:
- case ERROR_BAD_DRIVER_LEVEL:
- case ERROR_DIRECT_ACCESS_HANDLE:
- case ERROR_NOT_OWNER:
- return(ERR_PHYSFS_BAD_OS_CALL);
-
- default: return(ERR_OS2_GENERIC);
- } /* switch */
-
- return(NULL);
-} /* get_os2_error_string */
-
-
-static APIRET os2err(APIRET retval)
-{
- char buf[128];
- const char *err = get_os2_error_string(retval);
- if (err == ERR_OS2_GENERIC)
- {
- snprintf(buf, sizeof (buf), ERR_OS2_GENERIC, (int) retval);
- err = buf;
- } /* if */
-
- if (err != NULL)
- __PHYSFS_setError(err);
-
- return(retval);
-} /* os2err */
-
-
-/* (be gentle, this function isn't very robust.) */
-static void cvt_path_to_correct_case(char *buf)
-{
- char *fname = buf + 3; /* point to first element. */
- char *ptr = strchr(fname, '\\'); /* find end of first element. */
-
- buf[0] = toupper(buf[0]); /* capitalize drive letter. */
-
- /*
- * Go through each path element, and enumerate its parent dir until
- * a case-insensitive match is found. If one is (and it SHOULD be)
- * then overwrite the original element with the correct case.
- * If there's an error, or the path has vanished for some reason, it
- * won't hurt to have the original case, so we just keep going.
- */
- while (fname != NULL)
- {
- char spec[CCHMAXPATH];
- FILEFINDBUF3 fb;
- HDIR hdir = HDIR_CREATE;
- ULONG count = 1;
- APIRET rc;
-
- *(fname - 1) = '\0'; /* isolate parent dir string. */
-
- strcpy(spec, buf); /* copy isolated parent dir... */
- strcat(spec, "\\*.*"); /* ...and add wildcard search spec. */
-
- if (ptr != NULL) /* isolate element to find (fname is the start). */
- *ptr = '\0';
-
- rc = DosFindFirst(spec, &hdir, FILE_DIRECTORY,
- &fb, sizeof (fb), &count, FIL_STANDARD);
- if (rc == NO_ERROR)
- {
- while (count == 1) /* while still entries to enumerate... */
- {
- if (__PHYSFS_stricmpASCII(fb.achName, fname) == 0)
- {
- strcpy(fname, fb.achName);
- break; /* there it is. Overwrite and stop searching. */
- } /* if */
-
- DosFindNext(hdir, &fb, sizeof (fb), &count);
- } /* while */
- DosFindClose(hdir);
- } /* if */
-
- *(fname - 1) = '\\'; /* unisolate parent dir. */
- fname = ptr; /* point to next element. */
- if (ptr != NULL)
- {
- *ptr = '\\'; /* unisolate element. */
- ptr = strchr(++fname, '\\'); /* find next element. */
- } /* if */
- } /* while */
-} /* cvt_file_to_correct_case */
-
-
-static char *baseDir = NULL;
-
-int __PHYSFS_platformInit(void)
-{
- char buf[CCHMAXPATH];
- APIRET rc;
- PTIB ptib;
- PPIB ppib;
- PHYSFS_sint32 len;
-
- assert(baseDir == NULL);
- BAIL_IF_MACRO(os2err(DosGetInfoBlocks(&ptib, &ppib)) != NO_ERROR, NULL, 0);
- rc = DosQueryModuleName(ppib->pib_hmte, sizeof (buf), (PCHAR) buf);
- BAIL_IF_MACRO(os2err(rc) != NO_ERROR, NULL, 0);
-
- /* chop off filename, leave path. */
- for (len = strlen(buf) - 1; len >= 0; len--)
- {
- if (buf[len] == '\\')
- {
- buf[len] = '\0';
- break;
- } /* if */
- } /* for */
-
- assert(len > 0); /* should have been a "x:\\" on the front on string. */
-
- /* The string is capitalized! Figure out the REAL case... */
- cvt_path_to_correct_case(buf);
-
- baseDir = (char *) allocator.Malloc(len + 1);
- BAIL_IF_MACRO(baseDir == NULL, ERR_OUT_OF_MEMORY, 0);
- strcpy(baseDir, buf);
- return(1); /* success. */
-} /* __PHYSFS_platformInit */
-
-
-int __PHYSFS_platformDeinit(void)
-{
- assert(baseDir != NULL);
- allocator.Free(baseDir);
- baseDir = NULL;
- return(1); /* success. */
-} /* __PHYSFS_platformDeinit */
-
-
-static int disc_is_inserted(ULONG drive)
-{
- int rc;
- char buf[20];
- DosError(FERR_DISABLEHARDERR | FERR_DISABLEEXCEPTION);
- rc = DosQueryFSInfo(drive + 1, FSIL_VOLSER, buf, sizeof (buf));
- DosError(FERR_ENABLEHARDERR | FERR_ENABLEEXCEPTION);
- return(rc == NO_ERROR);
-} /* is_cdrom_inserted */
-
-
-/* looks like "CD01" in ASCII (littleendian)...used for an ioctl. */
-#define CD01 0x31304443
-
-static int is_cdrom_drive(ULONG drive)
-{
- PHYSFS_uint32 param, data;
- ULONG ul1, ul2;
- APIRET rc;
- HFILE hfile = NULLHANDLE;
- char drivename[3] = { 'A' + drive, ':', '\0' };
-
- rc = DosOpen(drivename, &hfile, &ul1, 0, 0,
- OPEN_ACTION_OPEN_IF_EXISTS | OPEN_ACTION_FAIL_IF_NEW,
- OPEN_FLAGS_DASD | OPEN_FLAGS_FAIL_ON_ERROR |
- OPEN_FLAGS_NOINHERIT | OPEN_SHARE_DENYNONE, NULL);
- BAIL_IF_MACRO(rc != NO_ERROR, NULL, 0);
-
- data = 0;
- param = PHYSFS_swapULE32(CD01);
- ul1 = ul2 = sizeof (PHYSFS_uint32);
- rc = DosDevIOCtl(hfile, IOCTL_CDROMDISK, CDROMDISK_GETDRIVER,
- ¶m, sizeof (param), &ul1, &data, sizeof (data), &ul2);
-
- DosClose(hfile);
- return((rc == NO_ERROR) && (PHYSFS_swapULE32(data) == CD01));
-} /* is_cdrom_drive */
-
-
-void __PHYSFS_platformDetectAvailableCDs(PHYSFS_StringCallback cb, void *data)
-{
- ULONG dummy = 0;
- ULONG drivemap = 0;
- ULONG i, bit;
- APIRET rc = DosQueryCurrentDisk(&dummy, &drivemap);
- if (os2err(rc) != NO_ERROR)
- return;
-
- for (i = 0, bit = 1; i < 26; i++, bit <<= 1)
- {
- if (drivemap & bit) /* this logical drive exists. */
- {
- if ((is_cdrom_drive(i)) && (disc_is_inserted(i)))
- {
- char drive[4] = "x:\\";
- drive[0] = ('A' + i);
- cb(data, drive);
- } /* if */
- } /* if */
- } /* for */
-} /* __PHYSFS_platformDetectAvailableCDs */
-
-
-char *__PHYSFS_platformCalcBaseDir(const char *argv0)
-{
- char *retval = (char *) allocator.Malloc(strlen(baseDir) + 1);
- BAIL_IF_MACRO(retval == NULL, ERR_OUT_OF_MEMORY, NULL);
- strcpy(retval, baseDir); /* calculated at init time. */
- return(retval);
-} /* __PHYSFS_platformCalcBaseDir */
-
-
-char *__PHYSFS_platformGetUserName(void)
-{
- return(NULL); /* (*shrug*) */
-} /* __PHYSFS_platformGetUserName */
-
-
-char *__PHYSFS_platformGetUserDir(void)
-{
- return(__PHYSFS_platformCalcBaseDir(NULL));
-} /* __PHYSFS_platformGetUserDir */
-
-
-int __PHYSFS_platformExists(const char *fname)
-{
- FILESTATUS3 fs;
- APIRET rc = DosQueryPathInfo(fname, FIL_STANDARD, &fs, sizeof (fs));
- return(os2err(rc) == NO_ERROR);
-} /* __PHYSFS_platformExists */
-
-
-int __PHYSFS_platformIsSymLink(const char *fname)
-{
- return(0); /* no symlinks in OS/2. */
-} /* __PHYSFS_platformIsSymlink */
-
-
-int __PHYSFS_platformIsDirectory(const char *fname)
-{
- FILESTATUS3 fs;
- APIRET rc = DosQueryPathInfo(fname, FIL_STANDARD, &fs, sizeof (fs));
- BAIL_IF_MACRO(os2err(rc) != NO_ERROR, NULL, 0)
- return((fs.attrFile & FILE_DIRECTORY) != 0);
-} /* __PHYSFS_platformIsDirectory */
-
-
-/* !!! FIXME: can we lose the malloc here? */
-char *__PHYSFS_platformCvtToDependent(const char *prepend,
- const char *dirName,
- const char *append)
-{
- int len = ((prepend) ? strlen(prepend) : 0) +
- ((append) ? strlen(append) : 0) +
- strlen(dirName) + 1;
- char *retval = allocator.Malloc(len);
- char *p;
-
- BAIL_IF_MACRO(retval == NULL, ERR_OUT_OF_MEMORY, NULL);
-
- if (prepend)
- strcpy(retval, prepend);
- else
- retval[0] = '\0';
-
- strcat(retval, dirName);
-
- if (append)
- strcat(retval, append);
-
- for (p = strchr(retval, '/'); p != NULL; p = strchr(p + 1, '/'))
- *p = '\\';
-
- return(retval);
-} /* __PHYSFS_platformCvtToDependent */
-
-
-void __PHYSFS_platformEnumerateFiles(const char *dirname,
- int omitSymLinks,
- PHYSFS_EnumFilesCallback callback,
- const char *origdir,
- void *callbackdata)
-{
- char spec[CCHMAXPATH];
- FILEFINDBUF3 fb;
- HDIR hdir = HDIR_CREATE;
- ULONG count = 1;
- APIRET rc;
-
- if (strlen(dirname) > sizeof (spec) - 5)
- {
- __PHYSFS_setError(ERR_BAD_FILENAME);
- return;
- } /* if */
-
- strcpy(spec, dirname);
- strcat(spec, (spec[strlen(spec) - 1] != '\\') ? "\\*.*" : "*.*");
-
- rc = DosFindFirst(spec, &hdir,
- FILE_DIRECTORY | FILE_ARCHIVED |
- FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM,
- &fb, sizeof (fb), &count, FIL_STANDARD);
-
- if (os2err(rc) != NO_ERROR)
- return;
-
- while (count == 1)
- {
- if ((strcmp(fb.achName, ".") != 0) && (strcmp(fb.achName, "..") != 0))
- callback(callbackdata, origdir, fb.achName);
-
- DosFindNext(hdir, &fb, sizeof (fb), &count);
- } /* while */
-
- DosFindClose(hdir);
-} /* __PHYSFS_platformEnumerateFiles */
-
-
-char *__PHYSFS_platformCurrentDir(void)
-{
- char *retval;
- ULONG currentDisk;
- ULONG dummy;
- ULONG pathSize = 0;
- APIRET rc;
- BYTE byte;
-
- rc = DosQueryCurrentDisk(¤tDisk, &dummy);
- BAIL_IF_MACRO(os2err(rc) != NO_ERROR, NULL, NULL);
-
- /* The first call just tells us how much space we need for the string. */
- rc = DosQueryCurrentDir(currentDisk, &byte, &pathSize);
- pathSize++; /* Add space for null terminator. */
- retval = (char *) allocator.Malloc(pathSize + 3); /* plus "x:\\" */
- BAIL_IF_MACRO(retval == NULL, ERR_OUT_OF_MEMORY, NULL);
-
- /* Actually get the string this time. */
- rc = DosQueryCurrentDir(currentDisk, (PBYTE) (retval + 3), &pathSize);
- if (os2err(rc) != NO_ERROR)
- {
- allocator.Free(retval);
- return(NULL);
- } /* if */
-
- retval[0] = ('A' + (currentDisk - 1));
- retval[1] = ':';
- retval[2] = '\\';
- return(retval);
-} /* __PHYSFS_platformCurrentDir */
-
-
-char *__PHYSFS_platformRealPath(const char *path)
-{
- char buf[CCHMAXPATH];
- char *retval;
- APIRET rc = DosQueryPathInfo(path, FIL_QUERYFULLNAME, buf, sizeof (buf));
- BAIL_IF_MACRO(os2err(rc) != NO_ERROR, NULL, NULL);
- retval = (char *) allocator.Malloc(strlen(buf) + 1);
- BAIL_IF_MACRO(retval == NULL, ERR_OUT_OF_MEMORY, NULL);
- strcpy(retval, buf);
- return(retval);
-} /* __PHYSFS_platformRealPath */
-
-
-int __PHYSFS_platformMkDir(const char *path)
-{
- return(os2err(DosCreateDir(path, NULL)) == NO_ERROR);
-} /* __PHYSFS_platformMkDir */
-
-
-void *__PHYSFS_platformOpenRead(const char *filename)
-{
- ULONG actionTaken = 0;
- HFILE hfile = NULLHANDLE;
-
- /*
- * File must be opened SHARE_DENYWRITE and ACCESS_READONLY, otherwise
- * DosQueryFileInfo() will fail if we try to get a file length, etc.
- */
- os2err(DosOpen(filename, &hfile, &actionTaken, 0, FILE_NORMAL,
- OPEN_ACTION_OPEN_IF_EXISTS | OPEN_ACTION_FAIL_IF_NEW,
- OPEN_FLAGS_FAIL_ON_ERROR | OPEN_FLAGS_NO_LOCALITY |
- OPEN_FLAGS_NOINHERIT | OPEN_SHARE_DENYWRITE |
- OPEN_ACCESS_READONLY, NULL));
-
- return((void *) hfile);
-} /* __PHYSFS_platformOpenRead */
-
-
-void *__PHYSFS_platformOpenWrite(const char *filename)
-{
- ULONG actionTaken = 0;
- HFILE hfile = NULLHANDLE;
-
- /*
- * File must be opened SHARE_DENYWRITE and ACCESS_READWRITE, otherwise
- * DosQueryFileInfo() will fail if we try to get a file length, etc.
- */
- os2err(DosOpen(filename, &hfile, &actionTaken, 0, FILE_NORMAL,
- OPEN_ACTION_REPLACE_IF_EXISTS | OPEN_ACTION_CREATE_IF_NEW,
- OPEN_FLAGS_FAIL_ON_ERROR | OPEN_FLAGS_NO_LOCALITY |
- OPEN_FLAGS_NOINHERIT | OPEN_SHARE_DENYWRITE |
- OPEN_ACCESS_READWRITE, NULL));
-
- return((void *) hfile);
-} /* __PHYSFS_platformOpenWrite */
-
-
-void *__PHYSFS_platformOpenAppend(const char *filename)
-{
- ULONG dummy = 0;
- HFILE hfile = NULLHANDLE;
- APIRET rc;
-
- /*
- * File must be opened SHARE_DENYWRITE and ACCESS_READWRITE, otherwise
- * DosQueryFileInfo() will fail if we try to get a file length, etc.
- */
- rc = os2err(DosOpen(filename, &hfile, &dummy, 0, FILE_NORMAL,
- OPEN_ACTION_OPEN_IF_EXISTS | OPEN_ACTION_CREATE_IF_NEW,
- OPEN_FLAGS_FAIL_ON_ERROR | OPEN_FLAGS_NO_LOCALITY |
- OPEN_FLAGS_NOINHERIT | OPEN_SHARE_DENYWRITE |
- OPEN_ACCESS_READWRITE, NULL));
-
- if (rc == NO_ERROR)
- {
- if (os2err(DosSetFilePtr(hfile, 0, FILE_END, &dummy)) != NO_ERROR)
- {
- DosClose(hfile);
- hfile = NULLHANDLE;
- } /* if */
- } /* if */
-
- return((void *) hfile);
-} /* __PHYSFS_platformOpenAppend */
-
-
-PHYSFS_sint64 __PHYSFS_platformRead(void *opaque, void *buffer,
- PHYSFS_uint32 size, PHYSFS_uint32 count)
-{
- HFILE hfile = (HFILE) opaque;
- PHYSFS_sint64 retval;
- ULONG br;
-
- for (retval = 0; retval < count; retval++)
- {
- os2err(DosRead(hfile, buffer, size, &br));
- if (br < size)
- {
- DosSetFilePtr(hfile, -br, FILE_CURRENT, &br); /* try to cleanup. */
- return(retval);
- } /* if */
-
- buffer = (void *) ( ((char *) buffer) + size );
- } /* for */
-
- return(retval);
-} /* __PHYSFS_platformRead */
-
-
-PHYSFS_sint64 __PHYSFS_platformWrite(void *opaque, const void *buffer,
- PHYSFS_uint32 size, PHYSFS_uint32 count)
-{
- HFILE hfile = (HFILE) opaque;
- PHYSFS_sint64 retval;
- ULONG bw;
-
- for (retval = 0; retval < count; retval++)
- {
- os2err(DosWrite(hfile, buffer, size, &bw));
- if (bw < size)
- {
- DosSetFilePtr(hfile, -bw, FILE_CURRENT, &bw); /* try to cleanup. */
- return(retval);
- } /* if */
-
- buffer = (void *) ( ((char *) buffer) + size );
- } /* for */
-
- return(retval);
-} /* __PHYSFS_platformWrite */
-
-
-int __PHYSFS_platformSeek(void *opaque, PHYSFS_uint64 pos)
-{
- ULONG dummy;
- HFILE hfile = (HFILE) opaque;
- LONG dist = (LONG) pos;
-
- /* hooray for 32-bit filesystem limits! :) */
- BAIL_IF_MACRO((PHYSFS_uint64) dist != pos, ERR_SEEK_OUT_OF_RANGE, 0);
-
- return(os2err(DosSetFilePtr(hfile, dist, FILE_BEGIN, &dummy)) == NO_ERROR);
-} /* __PHYSFS_platformSeek */
-
-
-PHYSFS_sint64 __PHYSFS_platformTell(void *opaque)
-{
- ULONG pos;
- HFILE hfile = (HFILE) opaque;
- APIRET rc = os2err(DosSetFilePtr(hfile, 0, FILE_CURRENT, &pos));
- BAIL_IF_MACRO(rc != NO_ERROR, NULL, -1);
- return((PHYSFS_sint64) pos);
-} /* __PHYSFS_platformTell */
-
-
-PHYSFS_sint64 __PHYSFS_platformFileLength(void *opaque)
-{
- FILESTATUS3 fs;
- HFILE hfile = (HFILE) opaque;
- APIRET rc = DosQueryFileInfo(hfile, FIL_STANDARD, &fs, sizeof (fs));
- BAIL_IF_MACRO(os2err(rc) != NO_ERROR, NULL, -1);
- return((PHYSFS_sint64) fs.cbFile);
-} /* __PHYSFS_platformFileLength */
-
-
-int __PHYSFS_platformEOF(void *opaque)
-{
- PHYSFS_sint64 len, pos;
-
- len = __PHYSFS_platformFileLength(opaque);
- BAIL_IF_MACRO(len == -1, NULL, 1); /* (*shrug*) */
- pos = __PHYSFS_platformTell(opaque);
- BAIL_IF_MACRO(pos == -1, NULL, 1); /* (*shrug*) */
-
- return(pos >= len);
-} /* __PHYSFS_platformEOF */
-
-
-int __PHYSFS_platformFlush(void *opaque)
-{
- return(os2err(DosResetBuffer((HFILE) opaque) == NO_ERROR));
-} /* __PHYSFS_platformFlush */
-
-
-int __PHYSFS_platformClose(void *opaque)
-{
- return(os2err(DosClose((HFILE) opaque) == NO_ERROR));
-} /* __PHYSFS_platformClose */
-
-
-int __PHYSFS_platformDelete(const char *path)
-{
- if (__PHYSFS_platformIsDirectory(path))
- return(os2err(DosDeleteDir(path)) == NO_ERROR);
-
- return(os2err(DosDelete(path) == NO_ERROR));
-} /* __PHYSFS_platformDelete */
-
-
-PHYSFS_sint64 __PHYSFS_platformGetLastModTime(const char *fname)
-{
- PHYSFS_sint64 retval;
- struct tm tm;
- FILESTATUS3 fs;
- APIRET rc = DosQueryPathInfo(fname, FIL_STANDARD, &fs, sizeof (fs));
- BAIL_IF_MACRO(os2err(rc) != NO_ERROR, NULL, -1);
-
- /* Convert to a format that mktime() can grok... */
- tm.tm_sec = ((PHYSFS_uint32) fs.ftimeLastWrite.twosecs) * 2;
- tm.tm_min = fs.ftimeLastWrite.minutes;
- tm.tm_hour = fs.ftimeLastWrite.hours;
- tm.tm_mday = fs.fdateLastWrite.day;
- tm.tm_mon = fs.fdateLastWrite.month;
- tm.tm_year = ((PHYSFS_uint32) fs.fdateLastWrite.year) + 80;
- tm.tm_wday = -1 /*st_localtz.wDayOfWeek*/;
- tm.tm_yday = -1;
- tm.tm_isdst = -1;
-
- /* Convert to a format PhysicsFS can grok... */
- retval = (PHYSFS_sint64) mktime(&tm);
- BAIL_IF_MACRO(retval == -1, strerror(errno), -1);
- return(retval);
-} /* __PHYSFS_platformGetLastModTime */
-
-
-PHYSFS_uint64 __PHYSFS_platformGetThreadID(void)
-{
- PTIB ptib;
- PPIB ppib;
-
- /*
- * Allegedly, this API never fails, but we'll punt and return a
- * default value (zero might as well do) if it does.
- */
- BAIL_IF_MACRO(os2err(DosGetInfoBlocks(&ptib, &ppib)) != NO_ERROR, 0, 0);
- return((PHYSFS_uint64) ptib->tib_ordinal);
-} /* __PHYSFS_platformGetThreadID */
-
-
-void *__PHYSFS_platformCreateMutex(void)
-{
- HMTX hmtx = NULLHANDLE;
- os2err(DosCreateMutexSem(NULL, &hmtx, 0, 0));
- return((void *) hmtx);
-} /* __PHYSFS_platformCreateMutex */
-
-
-void __PHYSFS_platformDestroyMutex(void *mutex)
-{
- DosCloseMutexSem((HMTX) mutex);
-} /* __PHYSFS_platformDestroyMutex */
-
-
-int __PHYSFS_platformGrabMutex(void *mutex)
-{
- /* Do _NOT_ call os2err() (which sets the physfs error msg) in here! */
- return(DosRequestMutexSem((HMTX) mutex, SEM_INDEFINITE_WAIT) == NO_ERROR);
-} /* __PHYSFS_platformGrabMutex */
-
-
-void __PHYSFS_platformReleaseMutex(void *mutex)
-{
- DosReleaseMutexSem((HMTX) mutex);
-} /* __PHYSFS_platformReleaseMutex */
-
-
-/* !!! FIXME: Don't use C runtime for allocators? */
-int __PHYSFS_platformSetDefaultAllocator(PHYSFS_Allocator *a)
-{
- return(0); /* just use malloc() and friends. */
-} /* __PHYSFS_platformSetDefaultAllocator */
-
-#endif /* PHYSFS_PLATFORM_OS2 */
-
-/* end of os2.c ... */
-
+++ /dev/null
-/*
- * PocketPC support routines for PhysicsFS.
- *
- * Please see the file LICENSE.txt in the source's root directory.
- *
- * This file written by Ryan C. Gordon.
- */
-
-#define __PHYSICSFS_INTERNAL__
-#include "physfs_platforms.h"
-
-#ifdef PHYSFS_PLATFORM_POCKETPC
-
-#include <stdio.h>
-#include <windows.h>
-
-#include "physfs_internal.h"
-
-#define INVALID_FILE_ATTRIBUTES 0xFFFFFFFF
-#define INVALID_SET_FILE_POINTER 0xFFFFFFFF
-typedef struct
-{
- HANDLE handle;
- int readonly;
-} winCEfile;
-
-
-const char *__PHYSFS_platformDirSeparator = "\\";
-static char *userDir = NULL;
-
-/*
- * Figure out what the last failing Win32 API call was, and
- * generate a human-readable string for the error message.
- *
- * The return value is a static buffer that is overwritten with
- * each call to this function.
- */
-static const char *win32strerror(void)
-{
- static TCHAR msgbuf[255];
- TCHAR *ptr = msgbuf;
-
- FormatMessage(
- FORMAT_MESSAGE_FROM_SYSTEM |
- FORMAT_MESSAGE_IGNORE_INSERTS,
- NULL,
- GetLastError(),
- MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), /* Default language */
- msgbuf,
- sizeof (msgbuf) / sizeof (TCHAR),
- NULL
- );
-
- /* chop off newlines. */
- for (ptr = msgbuf; *ptr; ptr++)
- {
- if ((*ptr == '\n') || (*ptr == '\r'))
- {
- *ptr = ' ';
- break;
- } /* if */
- } /* for */
-
- return((const char *) msgbuf);
-} /* win32strerror */
-
-
-/* !!! FIXME: need to check all of these for NULLs. */
-#define UTF8_TO_UNICODE_STACK_MACRO(w_assignto, str) { \
- if (str == NULL) \
- w_assignto = NULL; \
- else { \
- const PHYSFS_uint64 len = (PHYSFS_uint64) ((strlen(str) * 4) + 1); \
- w_assignto = (char *) __PHYSFS_smallAlloc(len); \
- PHYSFS_uc2fromutf8(str, (PHYSFS_uint16 *) w_assignto, len); \
- } \
-} \
-
-
-static char *getExePath()
-{
- DWORD buflen;
- int success = 0;
- TCHAR *ptr = NULL;
- TCHAR *retval = (TCHAR*) allocator.Malloc(sizeof (TCHAR) * (MAX_PATH + 1));
- char *charretval;
- BAIL_IF_MACRO(retval == NULL, ERR_OUT_OF_MEMORY, NULL);
-
- retval[0] = _T('\0');
- /* !!! FIXME: don't preallocate here? */
- /* !!! FIXME: use smallAlloc? */
- buflen = GetModuleFileName(NULL, retval, MAX_PATH + 1);
- if (buflen <= 0)
- __PHYSFS_setError(win32strerror());
- else
- {
- retval[buflen] = '\0'; /* does API always null-terminate this? */
- ptr = retval+buflen;
- while( ptr != retval )
- {
- if( *ptr != _T('\\') )
- *ptr-- = _T('\0');
- else
- break;
- } /* while */
- success = 1;
- } /* else */
-
- if (!success)
- {
- allocator.Free(retval);
- return(NULL); /* physfs error message will be set, above. */
- } /* if */
-
- buflen = (buflen * 4) + 1;
- charretval = (char *) allocator.Malloc(buflen);
- if (charretval != NULL)
- PHYSFS_utf8fromucs2((const PHYSFS_uint16 *) retval, charretval, buflen);
- allocator.Free(retval);
- return(charretval); /* w00t. */
-} /* getExePath */
-
-
-int __PHYSFS_platformInit(void)
-{
- userDir = getExePath();
- BAIL_IF_MACRO(userDir == NULL, NULL, 0); /* failed? */
- return(1); /* always succeed. */
-} /* __PHYSFS_platformInit */
-
-
-int __PHYSFS_platformDeinit(void)
-{
- allocator.Free(userDir);
- return(1); /* always succeed. */
-} /* __PHYSFS_platformDeinit */
-
-
-void __PHYSFS_platformDetectAvailableCDs(PHYSFS_StringCallback cb, void *data)
-{
- /* no-op on this platform. */
-} /* __PHYSFS_platformDetectAvailableCDs */
-
-
-char *__PHYSFS_platformCalcBaseDir(const char *argv0)
-{
- return(getExePath());
-} /* __PHYSFS_platformCalcBaseDir */
-
-
-char *__PHYSFS_platformGetUserName(void)
-{
- BAIL_MACRO(ERR_NOT_IMPLEMENTED, NULL);
-} /* __PHYSFS_platformGetUserName */
-
-
-char *__PHYSFS_platformGetUserDir(void)
-{
- return userDir;
- BAIL_MACRO(ERR_NOT_IMPLEMENTED, NULL);
-} /* __PHYSFS_platformGetUserDir */
-
-
-PHYSFS_uint64 __PHYSFS_platformGetThreadID(void)
-{
- return(1); /* single threaded. */
-} /* __PHYSFS_platformGetThreadID */
-
-
-int __PHYSFS_platformExists(const char *fname)
-{
- int retval = 0;
- wchar_t *w_fname = NULL;
-
- UTF8_TO_UNICODE_STACK_MACRO(w_fname, fname);
- if (w_fname != NULL)
- retval = (GetFileAttributes(w_fname) != INVALID_FILE_ATTRIBUTES);
- __PHYSFS_smallFree(w_fname);
-
- return(retval);
-} /* __PHYSFS_platformExists */
-
-
-int __PHYSFS_platformIsSymLink(const char *fname)
-{
- BAIL_MACRO(ERR_NOT_IMPLEMENTED, 0);
-} /* __PHYSFS_platformIsSymlink */
-
-
-int __PHYSFS_platformIsDirectory(const char *fname)
-{
- int retval = 0;
- wchar_t *w_fname = NULL;
-
- UTF8_TO_UNICODE_STACK_MACRO(w_fname, fname);
- if (w_fname != NULL)
- retval = ((GetFileAttributes(w_fname) & FILE_ATTRIBUTE_DIRECTORY) != 0);
- __PHYSFS_smallFree(w_fname);
-
- return(retval);
-} /* __PHYSFS_platformIsDirectory */
-
-
-char *__PHYSFS_platformCvtToDependent(const char *prepend,
- const char *dirName,
- const char *append)
-{
- int len = ((prepend) ? strlen(prepend) : 0) +
- ((append) ? strlen(append) : 0) +
- strlen(dirName) + 1;
- char *retval = (char *) allocator.Malloc(len);
- char *p;
-
- BAIL_IF_MACRO(retval == NULL, ERR_OUT_OF_MEMORY, NULL);
-
- if (prepend)
- strcpy(retval, prepend);
- else
- retval[0] = '\0';
-
- strcat(retval, dirName);
-
- if (append)
- strcat(retval, append);
-
- for (p = strchr(retval, '/'); p != NULL; p = strchr(p + 1, '/'))
- *p = '\\';
-
- return(retval);
-} /* __PHYSFS_platformCvtToDependent */
-
-
-static int doEnumCallback(const wchar_t *w_fname)
-{
- const PHYSFS_uint64 len = (PHYSFS_uint64) ((wcslen(w_fname) * 4) + 1);
- char *str = (char *) __PHYSFS_smallAlloc(len);
- PHYSFS_utf8fromucs2((const PHYSFS_uint16 *) w_fname, str, len);
- callback(callbackdata, origdir, str);
- __PHYSFS_smallFree(str);
- return 1;
-} /* doEnumCallback */
-
-
-void __PHYSFS_platformEnumerateFiles(const char *dirname,
- int omitSymLinks,
- PHYSFS_EnumFilesCallback callback,
- const char *origdir,
- void *callbackdata)
-{
- HANDLE dir;
- WIN32_FIND_DATA ent;
- char *SearchPath;
- wchar_t *w_SearchPath;
- size_t len = strlen(dirname);
-
- /* Allocate a new string for path, maybe '\\', "*", and NULL terminator */
- SearchPath = (char *) __PHYSFS_smallAlloc(len + 3);
- BAIL_IF_MACRO(SearchPath == NULL, ERR_OUT_OF_MEMORY, NULL);
-
- /* Copy current dirname */
- strcpy(SearchPath, dirname);
-
- /* if there's no '\\' at the end of the path, stick one in there. */
- if (SearchPath[len - 1] != '\\')
- {
- SearchPath[len++] = '\\';
- SearchPath[len] = '\0';
- } /* if */
-
- /* Append the "*" to the end of the string */
- strcat(SearchPath, "*");
-
- UTF8_TO_UNICODE_STACK_MACRO(w_SearchPath, SearchPath);
- __PHYSFS_smallFree(SearchPath);
- dir = FindFirstFile(w_SearchPath, &ent);
- __PHYSFS_smallFree(w_SearchPath);
-
- if (dir == INVALID_HANDLE_VALUE)
- return;
-
- do
- {
- const char *str = NULL;
-
- if (wcscmp(ent.cFileName, L".") == 0)
- continue;
-
- if (wcscmp(ent.cFileName, L"..") == 0)
- continue;
-
- if (!doEnumCallback(ent.cFileName))
- break;
- } while (FindNextFile(dir, &ent) != 0);
-
- FindClose(dir);
-} /* __PHYSFS_platformEnumerateFiles */
-
-
-char *__PHYSFS_platformCurrentDir(void)
-{
- return("\\");
-} /* __PHYSFS_platformCurrentDir */
-
-
-char *__PHYSFS_platformRealPath(const char *path)
-{
- char *retval = (char *) allocator.Malloc(strlen(path) + 1);
- strcpy(retval,path);
- return(retval);
-} /* __PHYSFS_platformRealPath */
-
-
-int __PHYSFS_platformMkDir(const char *path)
-{
- int retval = 0;
- wchar_t *w_path = NULL;
- UTF8_TO_UNICODE_STACK_MACRO(w_path, path);
- if (w_path != NULL)
- {
- retval = CreateDirectory(w_path, NULL);
- __PHYSFS_smallFree(w_fname);
- } /* if */
- return(retval);
-} /* __PHYSFS_platformMkDir */
-
-
-static void *doOpen(const char *fname, DWORD mode, DWORD creation, int rdonly)
-{
- HANDLE fileHandle;
- winCEfile *retval;
- wchar_t *w_fname = NULL;
-
- UTF8_TO_UNICODE_STACK_MACRO(w_fname, fname);
- fileHandle = CreateFile(w_fname, mode, FILE_SHARE_READ, NULL,
- creation, FILE_ATTRIBUTE_NORMAL, NULL);
- __PHYSFS_smallFree(w_fname);
-
- BAIL_IF_MACRO(fileHandle == INVALID_HANDLE_VALUE, win32strerror(), NULL);
-
- retval = (winCEfile *) allocator.Malloc(sizeof (winCEfile));
- if (retval == NULL)
- {
- CloseHandle(fileHandle);
- BAIL_MACRO(ERR_OUT_OF_MEMORY, NULL);
- } /* if */
-
- retval->readonly = rdonly;
- retval->handle = fileHandle;
- return(retval);
-} /* doOpen */
-
-
-void *__PHYSFS_platformOpenRead(const char *filename)
-{
- return(doOpen(filename, GENERIC_READ, OPEN_EXISTING, 1));
-} /* __PHYSFS_platformOpenRead */
-
-
-void *__PHYSFS_platformOpenWrite(const char *filename)
-{
- return(doOpen(filename, GENERIC_WRITE, CREATE_ALWAYS, 0));
-} /* __PHYSFS_platformOpenWrite */
-
-
-void *__PHYSFS_platformOpenAppend(const char *filename)
-{
- void *retval = doOpen(filename, GENERIC_WRITE, OPEN_ALWAYS, 0);
- if (retval != NULL)
- {
- HANDLE h = ((winCEfile *) retval)->handle;
- if (SetFilePointer(h, 0, NULL, FILE_END) == INVALID_SET_FILE_POINTER)
- {
- const char *err = win32strerror();
- CloseHandle(h);
- allocator.Free(retval);
- BAIL_MACRO(err, NULL);
- } /* if */
- } /* if */
-
- return(retval);
-
-} /* __PHYSFS_platformOpenAppend */
-
-
-PHYSFS_sint64 __PHYSFS_platformRead(void *opaque, void *buffer,
- PHYSFS_uint32 size, PHYSFS_uint32 count)
-{
- HANDLE Handle = ((winCEfile *) opaque)->handle;
- DWORD CountOfBytesRead;
- PHYSFS_sint64 retval;
-
- /* Read data from the file */
- /*!!! - uint32 might be a greater # than DWORD */
- if (!ReadFile(Handle, buffer, count * size, &CountOfBytesRead, NULL))
- {
- retval = -1;
- } /* if */
- else
- {
- /* Return the number of "objects" read. */
- /* !!! - What if not the right amount of bytes was read to make an object? */
- retval = CountOfBytesRead / size;
- } /* else */
-
- return(retval);
-
-} /* __PHYSFS_platformRead */
-
-
-PHYSFS_sint64 __PHYSFS_platformWrite(void *opaque, const void *buffer,
- PHYSFS_uint32 size, PHYSFS_uint32 count)
-{
- HANDLE Handle = ((winCEfile *) opaque)->handle;
- DWORD CountOfBytesWritten;
- PHYSFS_sint64 retval;
-
- /* Read data from the file */
- /*!!! - uint32 might be a greater # than DWORD */
- if (!WriteFile(Handle, buffer, count * size, &CountOfBytesWritten, NULL))
- {
- retval = -1;
- } /* if */
- else
- {
- /* Return the number of "objects" read. */
- /*!!! - What if not the right number of bytes was written? */
- retval = CountOfBytesWritten / size;
- } /* else */
-
- return(retval);
-
-} /* __PHYSFS_platformWrite */
-
-
-int __PHYSFS_platformSeek(void *opaque, PHYSFS_uint64 pos)
-{
- HANDLE Handle = ((winCEfile *) opaque)->handle;
- DWORD HighOrderPos;
- DWORD rc;
-
- /* Get the high order 32-bits of the position */
- //HighOrderPos = HIGHORDER_UINT64(pos);
- HighOrderPos = (unsigned long)(pos>>32);
-
- /*!!! SetFilePointer needs a signed 64-bit value. */
- /* Move pointer "pos" count from start of file */
- rc = SetFilePointer(Handle, (unsigned long)(pos&0x00000000ffffffff),
- &HighOrderPos, FILE_BEGIN);
-
- if ((rc == INVALID_SET_FILE_POINTER) && (GetLastError() != NO_ERROR))
- {
- BAIL_MACRO(win32strerror(), 0);
- }
-
- return(1); /* No error occured */
-} /* __PHYSFS_platformSeek */
-
-
-PHYSFS_sint64 __PHYSFS_platformTell(void *opaque)
-{
- HANDLE Handle = ((winCEfile *) opaque)->handle;
- DWORD HighPos = 0;
- DWORD LowPos;
- PHYSFS_sint64 retval;
-
- /* Get current position */
- LowPos = SetFilePointer(Handle, 0, &HighPos, FILE_CURRENT);
- if ((LowPos == INVALID_SET_FILE_POINTER) && (GetLastError() != NO_ERROR))
- {
- BAIL_MACRO(win32strerror(), 0);
- } /* if */
- else
- {
- /* Combine the high/low order to create the 64-bit position value */
- retval = (((PHYSFS_uint64) HighPos) << 32) | LowPos;
- //assert(retval >= 0);
- } /* else */
-
- return(retval);
-} /* __PHYSFS_platformTell */
-
-
-PHYSFS_sint64 __PHYSFS_platformFileLength(void *opaque)
-{
- HANDLE Handle = ((winCEfile *) opaque)->handle;
- DWORD SizeHigh;
- DWORD SizeLow;
- PHYSFS_sint64 retval;
-
- SizeLow = GetFileSize(Handle, &SizeHigh);
- if ((SizeLow == INVALID_SET_FILE_POINTER) && (GetLastError() != NO_ERROR))
- {
- BAIL_MACRO(win32strerror(), -1);
- } /* if */
- else
- {
- /* Combine the high/low order to create the 64-bit position value */
- retval = (((PHYSFS_uint64) SizeHigh) << 32) | SizeLow;
- //assert(retval >= 0);
- } /* else */
-
- return(retval);
-} /* __PHYSFS_platformFileLength */
-
-
-int __PHYSFS_platformEOF(void *opaque)
-{
- PHYSFS_sint64 FilePosition;
- int retval = 0;
-
- /* Get the current position in the file */
- if ((FilePosition = __PHYSFS_platformTell(opaque)) != 0)
- {
- /* Non-zero if EOF is equal to the file length */
- retval = FilePosition == __PHYSFS_platformFileLength(opaque);
- } /* if */
-
- return(retval);
-} /* __PHYSFS_platformEOF */
-
-
-int __PHYSFS_platformFlush(void *opaque)
-{
- winCEfile *fh = ((winCEfile *) opaque);
- if (!fh->readonly)
- BAIL_IF_MACRO(!FlushFileBuffers(fh->handle), win32strerror(), 0);
-
- return(1);
-} /* __PHYSFS_platformFlush */
-
-
-int __PHYSFS_platformClose(void *opaque)
-{
- HANDLE Handle = ((winCEfile *) opaque)->handle;
- BAIL_IF_MACRO(!CloseHandle(Handle), win32strerror(), 0);
- allocator.Free(opaque);
- return(1);
-} /* __PHYSFS_platformClose */
-
-
-int __PHYSFS_platformDelete(const char *path)
-{
- wchar_t *w_path = NULL;
- UTF8_TO_UNICODE_STACK_MACRO(w_path, path);
-
- /* If filename is a folder */
- if (GetFileAttributes(w_path) == FILE_ATTRIBUTE_DIRECTORY)
- {
- int retval = !RemoveDirectory(w_path);
- __PHYSFS_smallFree(w_path);
- BAIL_IF_MACRO(retval, win32strerror(), 0);
- } /* if */
- else
- {
- int retval = !DeleteFile(w_path);
- __PHYSFS_smallFree(w_path);
- BAIL_IF_MACRO(retval, win32strerror(), 0);
- } /* else */
-
- return(1); /* if you got here, it worked. */
-} /* __PHYSFS_platformDelete */
-
-
-/*
- * !!! FIXME: why aren't we using Critical Sections instead of Mutexes?
- * !!! FIXME: mutexes on Windows are for cross-process sync. CritSects are
- * !!! FIXME: mutexes for threads in a single process and are faster.
- */
-void *__PHYSFS_platformCreateMutex(void)
-{
- return((void *) CreateMutex(NULL, FALSE, NULL));
-} /* __PHYSFS_platformCreateMutex */
-
-
-void __PHYSFS_platformDestroyMutex(void *mutex)
-{
- CloseHandle((HANDLE) mutex);
-} /* __PHYSFS_platformDestroyMutex */
-
-
-int __PHYSFS_platformGrabMutex(void *mutex)
-{
- return(WaitForSingleObject((HANDLE) mutex, INFINITE) != WAIT_FAILED);
-} /* __PHYSFS_platformGrabMutex */
-
-
-void __PHYSFS_platformReleaseMutex(void *mutex)
-{
- ReleaseMutex((HANDLE) mutex);
-} /* __PHYSFS_platformReleaseMutex */
-
-
-PHYSFS_sint64 __PHYSFS_platformGetLastModTime(const char *fname)
-{
- BAIL_MACRO(ERR_NOT_IMPLEMENTED, -1);
-} /* __PHYSFS_platformGetLastModTime */
-
-
-/* !!! FIXME: Don't use C runtime for allocators? */
-int __PHYSFS_platformSetDefaultAllocator(PHYSFS_Allocator *a)
-{
- return(0); /* just use malloc() and friends. */
-} /* __PHYSFS_platformSetDefaultAllocator */
-
-#endif /* PHYSFS_PLATFORM_POCKETPC */
-
-/* end of pocketpc.c ... */
-
+++ /dev/null
-/*
- * Posix-esque support routines for PhysicsFS.
- *
- * Please see the file LICENSE.txt in the source's root directory.
- *
- * This file written by Ryan C. Gordon.
- */
-
-#define __PHYSICSFS_INTERNAL__
-#include "physfs_platforms.h"
-
-#ifdef PHYSFS_PLATFORM_POSIX
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <ctype.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <pwd.h>
-#include <dirent.h>
-#include <errno.h>
-#include <fcntl.h>
-
-#ifdef PHYSFS_HAVE_LLSEEK
-#include <linux/unistd.h>
-#endif
-
-#include "physfs_internal.h"
-
-
-const char *__PHYSFS_platformDirSeparator = "/";
-
-
-char *__PHYSFS_platformCopyEnvironmentVariable(const char *varname)
-{
- const char *envr = getenv(varname);
- char *retval = NULL;
-
- if (envr != NULL)
- {
- retval = (char *) allocator.Malloc(strlen(envr) + 1);
- if (retval != NULL)
- strcpy(retval, envr);
- } /* if */
-
- return(retval);
-} /* __PHYSFS_platformCopyEnvironmentVariable */
-
-
-static char *getUserNameByUID(void)
-{
- uid_t uid = getuid();
- struct passwd *pw;
- char *retval = NULL;
-
- pw = getpwuid(uid);
- if ((pw != NULL) && (pw->pw_name != NULL))
- {
- retval = (char *) allocator.Malloc(strlen(pw->pw_name) + 1);
- if (retval != NULL)
- strcpy(retval, pw->pw_name);
- } /* if */
-
- return(retval);
-} /* getUserNameByUID */
-
-
-static char *getUserDirByUID(void)
-{
- uid_t uid = getuid();
- struct passwd *pw;
- char *retval = NULL;
-
- pw = getpwuid(uid);
- if ((pw != NULL) && (pw->pw_dir != NULL))
- {
- retval = (char *) allocator.Malloc(strlen(pw->pw_dir) + 1);
- if (retval != NULL)
- strcpy(retval, pw->pw_dir);
- } /* if */
-
- return(retval);
-} /* getUserDirByUID */
-
-
-char *__PHYSFS_platformGetUserName(void)
-{
- char *retval = getUserNameByUID();
- if (retval == NULL)
- retval = __PHYSFS_platformCopyEnvironmentVariable("USER");
- return(retval);
-} /* __PHYSFS_platformGetUserName */
-
-
-char *__PHYSFS_platformGetUserDir(void)
-{
- char *retval = __PHYSFS_platformCopyEnvironmentVariable("HOME");
- if (retval == NULL)
- retval = getUserDirByUID();
- return(retval);
-} /* __PHYSFS_platformGetUserDir */
-
-
-int __PHYSFS_platformExists(const char *fname)
-{
- struct stat statbuf;
- BAIL_IF_MACRO(lstat(fname, &statbuf) == -1, strerror(errno), 0);
- return(1);
-} /* __PHYSFS_platformExists */
-
-
-int __PHYSFS_platformIsSymLink(const char *fname)
-{
- struct stat statbuf;
- BAIL_IF_MACRO(lstat(fname, &statbuf) == -1, strerror(errno), 0);
- return( (S_ISLNK(statbuf.st_mode)) ? 1 : 0 );
-} /* __PHYSFS_platformIsSymlink */
-
-
-int __PHYSFS_platformIsDirectory(const char *fname)
-{
- struct stat statbuf;
- BAIL_IF_MACRO(stat(fname, &statbuf) == -1, strerror(errno), 0);
- return( (S_ISDIR(statbuf.st_mode)) ? 1 : 0 );
-} /* __PHYSFS_platformIsDirectory */
-
-
-char *__PHYSFS_platformCvtToDependent(const char *prepend,
- const char *dirName,
- const char *append)
-{
- int len = ((prepend) ? strlen(prepend) : 0) +
- ((append) ? strlen(append) : 0) +
- strlen(dirName) + 1;
- char *retval = (char *) allocator.Malloc(len);
-
- BAIL_IF_MACRO(retval == NULL, ERR_OUT_OF_MEMORY, NULL);
-
- /* platform-independent notation is Unix-style already. :) */
-
- if (prepend)
- strcpy(retval, prepend);
- else
- retval[0] = '\0';
-
- strcat(retval, dirName);
-
- if (append)
- strcat(retval, append);
-
- return(retval);
-} /* __PHYSFS_platformCvtToDependent */
-
-
-
-void __PHYSFS_platformEnumerateFiles(const char *dirname,
- int omitSymLinks,
- PHYSFS_EnumFilesCallback callback,
- const char *origdir,
- void *callbackdata)
-{
- DIR *dir;
- struct dirent *ent;
- int bufsize = 0;
- char *buf = NULL;
- int dlen = 0;
-
- if (omitSymLinks) /* !!! FIXME: this malloc sucks. */
- {
- dlen = strlen(dirname);
- bufsize = dlen + 256;
- buf = (char *) allocator.Malloc(bufsize);
- if (buf == NULL)
- return;
- strcpy(buf, dirname);
- if (buf[dlen - 1] != '/')
- {
- buf[dlen++] = '/';
- buf[dlen] = '\0';
- } /* if */
- } /* if */
-
- errno = 0;
- dir = opendir(dirname);
- if (dir == NULL)
- {
- allocator.Free(buf);
- return;
- } /* if */
-
- while ((ent = readdir(dir)) != NULL)
- {
- if (strcmp(ent->d_name, ".") == 0)
- continue;
-
- if (strcmp(ent->d_name, "..") == 0)
- continue;
-
- if (omitSymLinks)
- {
- char *p;
- int len = strlen(ent->d_name) + dlen + 1;
- if (len > bufsize)
- {
- p = (char *) allocator.Realloc(buf, len);
- if (p == NULL)
- continue;
- buf = p;
- bufsize = len;
- } /* if */
-
- strcpy(buf + dlen, ent->d_name);
- if (__PHYSFS_platformIsSymLink(buf))
- continue;
- } /* if */
-
- callback(callbackdata, origdir, ent->d_name);
- } /* while */
-
- allocator.Free(buf);
- closedir(dir);
-} /* __PHYSFS_platformEnumerateFiles */
-
-
-int __PHYSFS_platformMkDir(const char *path)
-{
- int rc;
- errno = 0;
- rc = mkdir(path, S_IRWXU);
- BAIL_IF_MACRO(rc == -1, strerror(errno), 0);
- return(1);
-} /* __PHYSFS_platformMkDir */
-
-
-static void *doOpen(const char *filename, int mode)
-{
- int fd;
- int *retval;
- errno = 0;
-
- fd = open(filename, mode, S_IRUSR | S_IWUSR);
- BAIL_IF_MACRO(fd < 0, strerror(errno), NULL);
-
- retval = (int *) allocator.Malloc(sizeof (int));
- if (retval == NULL)
- {
- close(fd);
- BAIL_MACRO(ERR_OUT_OF_MEMORY, NULL);
- } /* if */
-
- *retval = fd;
- return((void *) retval);
-} /* doOpen */
-
-
-void *__PHYSFS_platformOpenRead(const char *filename)
-{
- return(doOpen(filename, O_RDONLY));
-} /* __PHYSFS_platformOpenRead */
-
-
-void *__PHYSFS_platformOpenWrite(const char *filename)
-{
- return(doOpen(filename, O_WRONLY | O_CREAT | O_TRUNC));
-} /* __PHYSFS_platformOpenWrite */
-
-
-void *__PHYSFS_platformOpenAppend(const char *filename)
-{
- return(doOpen(filename, O_WRONLY | O_CREAT | O_APPEND));
-} /* __PHYSFS_platformOpenAppend */
-
-
-PHYSFS_sint64 __PHYSFS_platformRead(void *opaque, void *buffer,
- PHYSFS_uint32 size, PHYSFS_uint32 count)
-{
- int fd = *((int *) opaque);
- int max = size * count;
- int rc = read(fd, buffer, max);
-
- BAIL_IF_MACRO(rc == -1, strerror(errno), rc);
- assert(rc <= max);
-
- if ((rc < max) && (size > 1))
- lseek(fd, -(rc % size), SEEK_CUR); /* rollback to object boundary. */
-
- return(rc / size);
-} /* __PHYSFS_platformRead */
-
-
-PHYSFS_sint64 __PHYSFS_platformWrite(void *opaque, const void *buffer,
- PHYSFS_uint32 size, PHYSFS_uint32 count)
-{
- int fd = *((int *) opaque);
- int max = size * count;
- int rc = write(fd, (void *) buffer, max);
-
- BAIL_IF_MACRO(rc == -1, strerror(errno), rc);
- assert(rc <= max);
-
- if ((rc < max) && (size > 1))
- lseek(fd, -(rc % size), SEEK_CUR); /* rollback to object boundary. */
-
- return(rc / size);
-} /* __PHYSFS_platformWrite */
-
-
-int __PHYSFS_platformSeek(void *opaque, PHYSFS_uint64 pos)
-{
- int fd = *((int *) opaque);
-
- #ifdef PHYSFS_HAVE_LLSEEK
- unsigned long offset_high = ((pos >> 32) & 0xFFFFFFFF);
- unsigned long offset_low = (pos & 0xFFFFFFFF);
- loff_t retoffset;
- int rc = llseek(fd, offset_high, offset_low, &retoffset, SEEK_SET);
- BAIL_IF_MACRO(rc == -1, strerror(errno), 0);
- #else
- BAIL_IF_MACRO(lseek(fd, (int) pos, SEEK_SET) == -1, strerror(errno), 0);
- #endif
-
- return(1);
-} /* __PHYSFS_platformSeek */
-
-
-PHYSFS_sint64 __PHYSFS_platformTell(void *opaque)
-{
- int fd = *((int *) opaque);
- PHYSFS_sint64 retval;
-
- #ifdef PHYSFS_HAVE_LLSEEK
- loff_t retoffset;
- int rc = llseek(fd, 0, &retoffset, SEEK_CUR);
- BAIL_IF_MACRO(rc == -1, strerror(errno), -1);
- retval = (PHYSFS_sint64) retoffset;
- #else
- retval = (PHYSFS_sint64) lseek(fd, 0, SEEK_CUR);
- BAIL_IF_MACRO(retval == -1, strerror(errno), -1);
- #endif
-
- return(retval);
-} /* __PHYSFS_platformTell */
-
-
-PHYSFS_sint64 __PHYSFS_platformFileLength(void *opaque)
-{
- int fd = *((int *) opaque);
- struct stat statbuf;
- BAIL_IF_MACRO(fstat(fd, &statbuf) == -1, strerror(errno), -1);
- return((PHYSFS_sint64) statbuf.st_size);
-} /* __PHYSFS_platformFileLength */
-
-
-int __PHYSFS_platformEOF(void *opaque)
-{
- PHYSFS_sint64 pos = __PHYSFS_platformTell(opaque);
- PHYSFS_sint64 len = __PHYSFS_platformFileLength(opaque);
- return(pos >= len);
-} /* __PHYSFS_platformEOF */
-
-
-int __PHYSFS_platformFlush(void *opaque)
-{
- int fd = *((int *) opaque);
- BAIL_IF_MACRO(fsync(fd) == -1, strerror(errno), 0);
- return(1);
-} /* __PHYSFS_platformFlush */
-
-
-int __PHYSFS_platformClose(void *opaque)
-{
- int fd = *((int *) opaque);
- BAIL_IF_MACRO(close(fd) == -1, strerror(errno), 0);
- allocator.Free(opaque);
- return(1);
-} /* __PHYSFS_platformClose */
-
-
-int __PHYSFS_platformDelete(const char *path)
-{
- BAIL_IF_MACRO(remove(path) == -1, strerror(errno), 0);
- return(1);
-} /* __PHYSFS_platformDelete */
-
-
-PHYSFS_sint64 __PHYSFS_platformGetLastModTime(const char *fname)
-{
- struct stat statbuf;
- BAIL_IF_MACRO(stat(fname, &statbuf) < 0, strerror(errno), -1);
- return statbuf.st_mtime;
-} /* __PHYSFS_platformGetLastModTime */
-
-#endif /* PHYSFS_PLATFORM_POSIX */
-
-/* end of posix.c ... */
-
+++ /dev/null
-/*
- * Unix support routines for PhysicsFS.
- *
- * Please see the file LICENSE.txt in the source's root directory.
- *
- * This file written by Ryan C. Gordon.
- */
-
-#define __PHYSICSFS_INTERNAL__
-#include "physfs_platforms.h"
-
-#ifdef PHYSFS_PLATFORM_UNIX
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <pwd.h>
-#include <sys/stat.h>
-#include <sys/param.h>
-#include <dirent.h>
-#include <time.h>
-#include <errno.h>
-#include <sys/mount.h>
-
-#if (!defined PHYSFS_NO_PTHREADS_SUPPORT)
-#include <pthread.h>
-#endif
-
-#ifdef PHYSFS_HAVE_SYS_UCRED_H
-# ifdef PHYSFS_HAVE_MNTENT_H
-# undef PHYSFS_HAVE_MNTENT_H /* don't do both... */
-# endif
-# include <sys/ucred.h>
-#endif
-
-#ifdef PHYSFS_HAVE_MNTENT_H
-#include <mntent.h>
-#endif
-
-#include "physfs_internal.h"
-
-
-int __PHYSFS_platformInit(void)
-{
- return(1); /* always succeed. */
-} /* __PHYSFS_platformInit */
-
-
-int __PHYSFS_platformDeinit(void)
-{
- return(1); /* always succeed. */
-} /* __PHYSFS_platformDeinit */
-
-
-#ifdef PHYSFS_NO_CDROM_SUPPORT
-
-/* Stub version for platforms without CD-ROM support. */
-void __PHYSFS_platformDetectAvailableCDs(PHYSFS_StringCallback cb, void *data)
-{
-} /* __PHYSFS_platformDetectAvailableCDs */
-
-#elif (defined PHYSFS_HAVE_SYS_UCRED_H)
-
-void __PHYSFS_platformDetectAvailableCDs(PHYSFS_StringCallback cb, void *data)
-{
- int i;
- struct statfs *mntbufp = NULL;
- int mounts = getmntinfo(&mntbufp, MNT_WAIT);
-
- for (i = 0; i < mounts; i++)
- {
- int add_it = 0;
-
- if (strcmp(mntbufp[i].f_fstypename, "iso9660") == 0)
- add_it = 1;
- else if (strcmp( mntbufp[i].f_fstypename, "cd9660") == 0)
- add_it = 1;
-
- /* add other mount types here */
-
- if (add_it)
- cb(data, mntbufp[i].f_mntonname);
- } /* for */
-} /* __PHYSFS_platformDetectAvailableCDs */
-
-#elif (defined PHYSFS_HAVE_MNTENT_H)
-
-void __PHYSFS_platformDetectAvailableCDs(PHYSFS_StringCallback cb, void *data)
-{
- FILE *mounts = NULL;
- struct mntent *ent = NULL;
-
- mounts = setmntent("/etc/mtab", "r");
- BAIL_IF_MACRO(mounts == NULL, ERR_IO_ERROR, /*return void*/);
-
- while ( (ent = getmntent(mounts)) != NULL )
- {
- int add_it = 0;
- if (strcmp(ent->mnt_type, "iso9660") == 0)
- add_it = 1;
-
- /* add other mount types here */
-
- if (add_it)
- cb(data, ent->mnt_dir);
- } /* while */
-
- endmntent(mounts);
-
-} /* __PHYSFS_platformDetectAvailableCDs */
-
-#endif
-
-
-/* this is in posix.c ... */
-extern char *__PHYSFS_platformCopyEnvironmentVariable(const char *varname);
-
-
-/*
- * See where program (bin) resides in the $PATH specified by (envr).
- * returns a copy of the first element in envr that contains it, or NULL
- * if it doesn't exist or there were other problems. PHYSFS_SetError() is
- * called if we have a problem.
- *
- * (envr) will be scribbled over, and you are expected to allocator.Free() the
- * return value when you're done with it.
- */
-static char *findBinaryInPath(const char *bin, char *envr)
-{
- size_t alloc_size = 0;
- char *exe = NULL;
- char *start = envr;
- char *ptr;
-
- BAIL_IF_MACRO(bin == NULL, ERR_INVALID_ARGUMENT, NULL);
- BAIL_IF_MACRO(envr == NULL, ERR_INVALID_ARGUMENT, NULL);
-
- do
- {
- size_t size;
- ptr = strchr(start, ':'); /* find next $PATH separator. */
- if (ptr)
- *ptr = '\0';
-
- size = strlen(start) + strlen(bin) + 2;
- if (size > alloc_size)
- {
- char *x = (char *) allocator.Realloc(exe, size);
- if (x == NULL)
- {
- if (exe != NULL)
- allocator.Free(exe);
- BAIL_MACRO(ERR_OUT_OF_MEMORY, NULL);
- } /* if */
-
- alloc_size = size;
- exe = x;
- } /* if */
-
- /* build full binary path... */
- strcpy(exe, start);
- if ((exe[0] == '\0') || (exe[strlen(exe) - 1] != '/'))
- strcat(exe, "/");
- strcat(exe, bin);
-
- if (access(exe, X_OK) == 0) /* Exists as executable? We're done. */
- {
- strcpy(exe, start); /* i'm lazy. piss off. */
- return(exe);
- } /* if */
-
- start = ptr + 1; /* start points to beginning of next element. */
- } while (ptr != NULL);
-
- if (exe != NULL)
- allocator.Free(exe);
-
- return(NULL); /* doesn't exist in path. */
-} /* findBinaryInPath */
-
-
-char *__PHYSFS_platformCalcBaseDir(const char *argv0)
-{
- const char *PROC_SELF_EXE = "/proc/self/exe";
- char *retval = NULL;
- char *envr = NULL;
- struct stat stbuf;
-
- /* fast path: default behaviour can handle this. */
- if ( (argv0 != NULL) && (strchr(argv0, '/') != NULL) )
- return(NULL); /* higher level will parse out real path from argv0. */
-
- /*
- * Try to avoid using argv0 unless forced to. If there's a Linux-like
- * /proc filesystem, you can get the full path to the current process from
- * the /proc/self/exe symlink.
- */
- if ((lstat(PROC_SELF_EXE, &stbuf) != -1) && (S_ISLNK(stbuf.st_mode)))
- {
- const size_t len = stbuf.st_size;
- char *buf = (char *) allocator.Malloc(len+1);
- if (buf != NULL) /* if NULL, maybe you'll get lucky later. */
- {
- if (readlink(PROC_SELF_EXE, buf, len) != len)
- allocator.Free(buf);
- else
- {
- buf[len] = '\0'; /* readlink doesn't null-terminate. */
- retval = buf; /* we're good to go. */
- } /* else */
- } /* if */
- } /* if */
-
- if ((retval == NULL) && (argv0 != NULL))
- {
- /* If there's no dirsep on argv0, then look through $PATH for it. */
- envr = __PHYSFS_platformCopyEnvironmentVariable("PATH");
- BAIL_IF_MACRO(!envr, NULL, NULL);
- retval = findBinaryInPath(argv0, envr);
- allocator.Free(envr);
- } /* if */
-
- return(retval);
-} /* __PHYSFS_platformCalcBaseDir */
-
-
-char *__PHYSFS_platformRealPath(const char *path)
-{
- char resolved_path[MAXPATHLEN];
- char *retval = NULL;
-
- errno = 0;
- BAIL_IF_MACRO(!realpath(path, resolved_path), strerror(errno), NULL);
- retval = (char *) allocator.Malloc(strlen(resolved_path) + 1);
- BAIL_IF_MACRO(retval == NULL, ERR_OUT_OF_MEMORY, NULL);
- strcpy(retval, resolved_path);
-
- return(retval);
-} /* __PHYSFS_platformRealPath */
-
-
-char *__PHYSFS_platformCurrentDir(void)
-{
- /*
- * This can't just do platformRealPath("."), since that would eventually
- * just end up calling back into here.
- */
-
- int allocSize = 0;
- char *retval = NULL;
- char *ptr;
-
- do
- {
- allocSize += 100;
- ptr = (char *) allocator.Realloc(retval, allocSize);
- if (ptr == NULL)
- {
- if (retval != NULL)
- allocator.Free(retval);
- BAIL_MACRO(ERR_OUT_OF_MEMORY, NULL);
- } /* if */
-
- retval = ptr;
- ptr = getcwd(retval, allocSize);
- } while (ptr == NULL && errno == ERANGE);
-
- if (ptr == NULL && errno)
- {
- /*
- * getcwd() failed for some reason, for example current
- * directory not existing.
- */
- if (retval != NULL)
- allocator.Free(retval);
- BAIL_MACRO(ERR_NO_SUCH_FILE, NULL);
- } /* if */
-
- return(retval);
-} /* __PHYSFS_platformCurrentDir */
-
-
-int __PHYSFS_platformSetDefaultAllocator(PHYSFS_Allocator *a)
-{
- return(0); /* just use malloc() and friends. */
-} /* __PHYSFS_platformSetDefaultAllocator */
-
-
-#if (defined PHYSFS_NO_PTHREADS_SUPPORT)
-
-PHYSFS_uint64 __PHYSFS_platformGetThreadID(void) { return(0x0001); }
-void *__PHYSFS_platformCreateMutex(void) { return((void *) 0x0001); }
-void __PHYSFS_platformDestroyMutex(void *mutex) {}
-int __PHYSFS_platformGrabMutex(void *mutex) { return(1); }
-void __PHYSFS_platformReleaseMutex(void *mutex) {}
-
-#else
-
-typedef struct
-{
- pthread_mutex_t mutex;
- pthread_t owner;
- PHYSFS_uint32 count;
-} PthreadMutex;
-
-/* Just in case; this is a panic value. */
-#if ((!defined SIZEOF_INT) || (SIZEOF_INT <= 0))
-# define SIZEOF_INT 4
-#endif
-
-#if (SIZEOF_INT == 4)
-# define PHTREAD_TO_UI64(thr) ( (PHYSFS_uint64) ((PHYSFS_uint32) (thr)) )
-#elif (SIZEOF_INT == 2)
-# define PHTREAD_TO_UI64(thr) ( (PHYSFS_uint64) ((PHYSFS_uint16) (thr)) )
-#elif (SIZEOF_INT == 1)
-# define PHTREAD_TO_UI64(thr) ( (PHYSFS_uint64) ((PHYSFS_uint8) (thr)) )
-#else
-# define PHTREAD_TO_UI64(thr) ((PHYSFS_uint64) (thr))
-#endif
-
-PHYSFS_uint64 __PHYSFS_platformGetThreadID(void)
-{
- return(PHTREAD_TO_UI64(pthread_self()));
-} /* __PHYSFS_platformGetThreadID */
-
-
-void *__PHYSFS_platformCreateMutex(void)
-{
- int rc;
- PthreadMutex *m = (PthreadMutex *) allocator.Malloc(sizeof (PthreadMutex));
- BAIL_IF_MACRO(m == NULL, ERR_OUT_OF_MEMORY, NULL);
- rc = pthread_mutex_init(&m->mutex, NULL);
- if (rc != 0)
- {
- allocator.Free(m);
- BAIL_MACRO(strerror(rc), NULL);
- } /* if */
-
- m->count = 0;
- m->owner = (pthread_t) 0xDEADBEEF;
- return((void *) m);
-} /* __PHYSFS_platformCreateMutex */
-
-
-void __PHYSFS_platformDestroyMutex(void *mutex)
-{
- PthreadMutex *m = (PthreadMutex *) mutex;
-
- /* Destroying a locked mutex is a bug, but we'll try to be helpful. */
- if ((m->owner == pthread_self()) && (m->count > 0))
- pthread_mutex_unlock(&m->mutex);
-
- pthread_mutex_destroy(&m->mutex);
- allocator.Free(m);
-} /* __PHYSFS_platformDestroyMutex */
-
-
-int __PHYSFS_platformGrabMutex(void *mutex)
-{
- PthreadMutex *m = (PthreadMutex *) mutex;
- pthread_t tid = pthread_self();
- if (m->owner != tid)
- {
- if (pthread_mutex_lock(&m->mutex) != 0)
- return(0);
- m->owner = tid;
- } /* if */
-
- m->count++;
- return(1);
-} /* __PHYSFS_platformGrabMutex */
-
-
-void __PHYSFS_platformReleaseMutex(void *mutex)
-{
- PthreadMutex *m = (PthreadMutex *) mutex;
- if (m->owner == pthread_self())
- {
- if (--m->count == 0)
- {
- m->owner = (pthread_t) 0xDEADBEEF;
- pthread_mutex_unlock(&m->mutex);
- } /* if */
- } /* if */
-} /* __PHYSFS_platformReleaseMutex */
-
-#endif /* !PHYSFS_NO_PTHREADS_SUPPORT */
-
-#endif /* PHYSFS_PLATFORM_UNIX */
-
-/* end of unix.c ... */
-
+++ /dev/null
-/*
- * Windows support routines for PhysicsFS.
- *
- * Please see the file LICENSE.txt in the source's root directory.
- *
- * This file written by Ryan C. Gordon, and made sane by Gregory S. Read.
- */
-
-#define __PHYSICSFS_INTERNAL__
-#include "physfs_platforms.h"
-
-#ifdef PHYSFS_PLATFORM_WINDOWS
-
-/* Forcibly disable UNICODE, since we manage this ourselves. */
-#ifdef UNICODE
-#undef UNICODE
-#endif
-
-#include <windows.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <ctype.h>
-#include <time.h>
-
-#include "physfs_internal.h"
-
-#define LOWORDER_UINT64(pos) (PHYSFS_uint32) \
- (pos & 0x00000000FFFFFFFF)
-#define HIGHORDER_UINT64(pos) (PHYSFS_uint32) \
- (((pos & 0xFFFFFFFF00000000) >> 32) & 0x00000000FFFFFFFF)
-
-/*
- * Users without the platform SDK don't have this defined. The original docs
- * for SetFilePointer() just said to compare with 0xFFFFFFFF, so this should
- * work as desired.
- */
-#define PHYSFS_INVALID_SET_FILE_POINTER 0xFFFFFFFF
-
-/* just in case... */
-#define PHYSFS_INVALID_FILE_ATTRIBUTES 0xFFFFFFFF
-
-/* Not defined before the Vista SDK. */
-#define PHYSFS_IO_REPARSE_TAG_SYMLINK 0xA000000C
-
-
-#define UTF8_TO_UNICODE_STACK_MACRO(w_assignto, str) { \
- if (str == NULL) \
- w_assignto = NULL; \
- else { \
- const PHYSFS_uint64 len = (PHYSFS_uint64) ((strlen(str) * 4) + 1); \
- w_assignto = (WCHAR *) __PHYSFS_smallAlloc(len); \
- if (w_assignto != NULL) \
- PHYSFS_utf8ToUcs2(str, (PHYSFS_uint16 *) w_assignto, len); \
- } \
-} \
-
-static PHYSFS_uint64 wStrLen(const WCHAR *wstr)
-{
- PHYSFS_uint64 len = 0;
- while (*(wstr++))
- len++;
- return(len);
-} /* wStrLen */
-
-static char *unicodeToUtf8Heap(const WCHAR *w_str)
-{
- char *retval = NULL;
- if (w_str != NULL)
- {
- void *ptr = NULL;
- const PHYSFS_uint64 len = (wStrLen(w_str) * 4) + 1;
- retval = allocator.Malloc(len);
- BAIL_IF_MACRO(retval == NULL, ERR_OUT_OF_MEMORY, NULL);
- PHYSFS_utf8FromUcs2((const PHYSFS_uint16 *) w_str, retval, len);
- ptr = allocator.Realloc(retval, strlen(retval) + 1); /* shrink. */
- if (ptr != NULL)
- retval = (char *) ptr;
- } /* if */
- return(retval);
-} /* unicodeToUtf8Heap */
-
-
-static char *codepageToUtf8Heap(const char *cpstr)
-{
- char *retval = NULL;
- if (cpstr != NULL)
- {
- const int len = (int) (strlen(cpstr) + 1);
- WCHAR *wbuf = (WCHAR *) __PHYSFS_smallAlloc(len * sizeof (WCHAR));
- BAIL_IF_MACRO(wbuf == NULL, ERR_OUT_OF_MEMORY, NULL);
- MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, cpstr, len, wbuf, len);
- retval = (char *) allocator.Malloc(len * 4);
- if (retval == NULL)
- __PHYSFS_setError(ERR_OUT_OF_MEMORY);
- else
- PHYSFS_utf8FromUcs2(wbuf, retval, len * 4);
- __PHYSFS_smallFree(wbuf);
- } /* if */
- return(retval);
-} /* codepageToUtf8Heap */
-
-
-typedef struct
-{
- HANDLE handle;
- int readonly;
-} WinApiFile;
-
-
-static char *userDir = NULL;
-static int osHasUnicode = 0;
-
-
-/* pointers for APIs that may not exist on some Windows versions... */
-static HANDLE libKernel32 = NULL;
-static HANDLE libUserEnv = NULL;
-static HANDLE libAdvApi32 = NULL;
-static DWORD (WINAPI *pGetModuleFileNameW)(HMODULE, LPWCH, DWORD);
-static BOOL (WINAPI *pGetUserProfileDirectoryW)(HANDLE, LPWSTR, LPDWORD);
-static BOOL (WINAPI *pGetUserNameW)(LPWSTR, LPDWORD);
-static DWORD (WINAPI *pGetFileAttributesW)(LPCWSTR);
-static HANDLE (WINAPI *pFindFirstFileW)(LPCWSTR, LPWIN32_FIND_DATAW);
-static BOOL (WINAPI *pFindNextFileW)(HANDLE, LPWIN32_FIND_DATAW);
-static DWORD (WINAPI *pGetCurrentDirectoryW)(DWORD, LPWSTR);
-static BOOL (WINAPI *pDeleteFileW)(LPCWSTR);
-static BOOL (WINAPI *pRemoveDirectoryW)(LPCWSTR);
-static BOOL (WINAPI *pCreateDirectoryW)(LPCWSTR, LPSECURITY_ATTRIBUTES);
-static BOOL (WINAPI *pGetFileAttributesExA)
- (LPCSTR, GET_FILEEX_INFO_LEVELS, LPVOID);
-static BOOL (WINAPI *pGetFileAttributesExW)
- (LPCWSTR, GET_FILEEX_INFO_LEVELS, LPVOID);
-static DWORD (WINAPI *pFormatMessageW)
- (DWORD, LPCVOID, DWORD, DWORD, LPWSTR, DWORD, va_list *);
-static HANDLE (WINAPI *pCreateFileW)
- (LPCWSTR, DWORD, DWORD, LPSECURITY_ATTRIBUTES, DWORD, DWORD, HANDLE);
-
-
-/*
- * Fallbacks for missing Unicode functions on Win95/98/ME. These are filled
- * into the function pointers if looking up the real Unicode entry points
- * in the system DLLs fails, so they're never used on WinNT/XP/Vista/etc.
- * They make an earnest effort to convert to/from UTF-8 and UCS-2 to
- * the user's current codepage.
- */
-
-static BOOL WINAPI fallbackGetUserNameW(LPWSTR buf, LPDWORD len)
-{
- const DWORD cplen = *len;
- char *cpstr = __PHYSFS_smallAlloc(cplen);
- BOOL retval = GetUserNameA(cpstr, len);
- if (buf != NULL)
- MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, cpstr, cplen, buf, *len);
- __PHYSFS_smallFree(cpstr);
- return(retval);
-} /* fallbackGetUserNameW */
-
-static DWORD WINAPI fallbackFormatMessageW(DWORD dwFlags, LPCVOID lpSource,
- DWORD dwMessageId, DWORD dwLangId,
- LPWSTR lpBuf, DWORD nSize,
- va_list *Arguments)
-{
- char *cpbuf = (char *) __PHYSFS_smallAlloc(nSize);
- DWORD retval = FormatMessageA(dwFlags, lpSource, dwMessageId, dwLangId,
- cpbuf, nSize, Arguments);
- if (retval > 0)
- MultiByteToWideChar(CP_ACP,MB_PRECOMPOSED,cpbuf,retval,lpBuf,nSize);
- __PHYSFS_smallFree(cpbuf);
- return(retval);
-} /* fallbackFormatMessageW */
-
-static DWORD WINAPI fallbackGetModuleFileNameW(HMODULE hMod, LPWCH lpBuf,
- DWORD nSize)
-{
- char *cpbuf = (char *) __PHYSFS_smallAlloc(nSize);
- DWORD retval = GetModuleFileNameA(hMod, cpbuf, nSize);
- if (retval > 0)
- MultiByteToWideChar(CP_ACP,MB_PRECOMPOSED,cpbuf,retval,lpBuf,nSize);
- __PHYSFS_smallFree(cpbuf);
- return(retval);
-} /* fallbackGetModuleFileNameW */
-
-static DWORD WINAPI fallbackGetFileAttributesW(LPCWSTR fname)
-{
- DWORD retval = 0;
- const int buflen = (int) (wStrLen(fname) + 1);
- char *cpstr = (char *) __PHYSFS_smallAlloc(buflen);
- WideCharToMultiByte(CP_ACP, 0, fname, buflen, cpstr, buflen, NULL, NULL);
- retval = GetFileAttributesA(cpstr);
- __PHYSFS_smallFree(cpstr);
- return(retval);
-} /* fallbackGetFileAttributesW */
-
-static DWORD WINAPI fallbackGetCurrentDirectoryW(DWORD buflen, LPWSTR buf)
-{
- DWORD retval = 0;
- char *cpbuf = NULL;
- if (buf != NULL)
- cpbuf = (char *) __PHYSFS_smallAlloc(buflen);
- retval = GetCurrentDirectoryA(buflen, cpbuf);
- if (cpbuf != NULL)
- {
- MultiByteToWideChar(CP_ACP,MB_PRECOMPOSED,cpbuf,retval,buf,buflen);
- __PHYSFS_smallFree(cpbuf);
- } /* if */
- return(retval);
-} /* fallbackGetCurrentDirectoryW */
-
-static BOOL WINAPI fallbackRemoveDirectoryW(LPCWSTR dname)
-{
- BOOL retval = 0;
- const int buflen = (int) (wStrLen(dname) + 1);
- char *cpstr = (char *) __PHYSFS_smallAlloc(buflen);
- WideCharToMultiByte(CP_ACP, 0, dname, buflen, cpstr, buflen, NULL, NULL);
- retval = RemoveDirectoryA(cpstr);
- __PHYSFS_smallFree(cpstr);
- return(retval);
-} /* fallbackRemoveDirectoryW */
-
-static BOOL WINAPI fallbackCreateDirectoryW(LPCWSTR dname,
- LPSECURITY_ATTRIBUTES attr)
-{
- BOOL retval = 0;
- const int buflen = (int) (wStrLen(dname) + 1);
- char *cpstr = (char *) __PHYSFS_smallAlloc(buflen);
- WideCharToMultiByte(CP_ACP, 0, dname, buflen, cpstr, buflen, NULL, NULL);
- retval = CreateDirectoryA(cpstr, attr);
- __PHYSFS_smallFree(cpstr);
- return(retval);
-} /* fallbackCreateDirectoryW */
-
-static BOOL WINAPI fallbackDeleteFileW(LPCWSTR fname)
-{
- BOOL retval = 0;
- const int buflen = (int) (wStrLen(fname) + 1);
- char *cpstr = (char *) __PHYSFS_smallAlloc(buflen);
- WideCharToMultiByte(CP_ACP, 0, fname, buflen, cpstr, buflen, NULL, NULL);
- retval = DeleteFileA(cpstr);
- __PHYSFS_smallFree(cpstr);
- return(retval);
-} /* fallbackDeleteFileW */
-
-static HANDLE WINAPI fallbackCreateFileW(LPCWSTR fname,
- DWORD dwDesiredAccess, DWORD dwShareMode,
- LPSECURITY_ATTRIBUTES lpSecurityAttrs,
- DWORD dwCreationDisposition,
- DWORD dwFlagsAndAttrs, HANDLE hTemplFile)
-{
- HANDLE retval;
- const int buflen = (int) (wStrLen(fname) + 1);
- char *cpstr = (char *) __PHYSFS_smallAlloc(buflen);
- WideCharToMultiByte(CP_ACP, 0, fname, buflen, cpstr, buflen, NULL, NULL);
- retval = CreateFileA(cpstr, dwDesiredAccess, dwShareMode, lpSecurityAttrs,
- dwCreationDisposition, dwFlagsAndAttrs, hTemplFile);
- __PHYSFS_smallFree(cpstr);
- return(retval);
-} /* fallbackCreateFileW */
-
-
-/* A blatant abuse of pointer casting... */
-static int symLookup(HMODULE dll, void **addr, const char *sym)
-{
- return( (*addr = GetProcAddress(dll, sym)) != NULL );
-} /* symLookup */
-
-
-static int findApiSymbols(void)
-{
- HMODULE dll = NULL;
-
- #define LOOKUP_NOFALLBACK(x, reallyLook) { \
- if (reallyLook) \
- symLookup(dll, (void **) &p##x, #x); \
- else \
- p##x = NULL; \
- }
-
- #define LOOKUP(x, reallyLook) { \
- if ((!reallyLook) || (!symLookup(dll, (void **) &p##x, #x))) \
- p##x = fallback##x; \
- }
-
- /* Apparently Win9x HAS the Unicode entry points, they just don't WORK. */
- /* ...so don't look them up unless we're on NT+. (see osHasUnicode.) */
-
- dll = libUserEnv = LoadLibraryA("userenv.dll");
- if (dll != NULL)
- LOOKUP_NOFALLBACK(GetUserProfileDirectoryW, osHasUnicode);
-
- /* !!! FIXME: what do they call advapi32.dll on Win64? */
- dll = libAdvApi32 = LoadLibraryA("advapi32.dll");
- if (dll != NULL)
- LOOKUP(GetUserNameW, osHasUnicode);
-
- /* !!! FIXME: what do they call kernel32.dll on Win64? */
- dll = libKernel32 = LoadLibraryA("kernel32.dll");
- if (dll != NULL)
- {
- LOOKUP_NOFALLBACK(GetFileAttributesExA, 1);
- LOOKUP_NOFALLBACK(GetFileAttributesExW, osHasUnicode);
- LOOKUP_NOFALLBACK(FindFirstFileW, osHasUnicode);
- LOOKUP_NOFALLBACK(FindNextFileW, osHasUnicode);
- LOOKUP(GetModuleFileNameW, osHasUnicode);
- LOOKUP(FormatMessageW, osHasUnicode);
- LOOKUP(GetFileAttributesW, osHasUnicode);
- LOOKUP(GetCurrentDirectoryW, osHasUnicode);
- LOOKUP(CreateDirectoryW, osHasUnicode);
- LOOKUP(RemoveDirectoryW, osHasUnicode);
- LOOKUP(CreateFileW, osHasUnicode);
- LOOKUP(DeleteFileW, osHasUnicode);
- } /* if */
-
- #undef LOOKUP_NOFALLBACK
- #undef LOOKUP
-
- return(1);
-} /* findApiSymbols */
-
-
-const char *__PHYSFS_platformDirSeparator = "\\";
-
-
-/*
- * Figure out what the last failing Windows API call was, and
- * generate a human-readable string for the error message.
- *
- * The return value is a static buffer that is overwritten with
- * each call to this function.
- */
-static const char *winApiStrError(void)
-{
- static char utf8buf[255];
- WCHAR msgbuf[255];
- WCHAR *ptr;
- DWORD rc = pFormatMessageW(
- FORMAT_MESSAGE_FROM_SYSTEM |
- FORMAT_MESSAGE_IGNORE_INSERTS,
- NULL, GetLastError(),
- MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
- msgbuf, __PHYSFS_ARRAYLEN(msgbuf),
- NULL);
-
- /* chop off newlines. */
- for (ptr = msgbuf; *ptr; ptr++)
- {
- if ((*ptr == '\n') || (*ptr == '\r'))
- {
- *ptr = '\0';
- break;
- } /* if */
- } /* for */
-
- /* may truncate, but oh well. */
- PHYSFS_utf8FromUcs2((PHYSFS_uint16 *) msgbuf, utf8buf, sizeof (utf8buf));
- return((const char *) utf8buf);
-} /* winApiStrError */
-
-
-static char *getExePath(void)
-{
- DWORD buflen = 64;
- int success = 0;
- LPWSTR modpath = NULL;
- char *retval = NULL;
-
- while (1)
- {
- DWORD rc;
- void *ptr;
-
- if ( !(ptr = allocator.Realloc(modpath, buflen*sizeof(WCHAR))) )
- {
- allocator.Free(modpath);
- BAIL_MACRO(ERR_OUT_OF_MEMORY, NULL);
- } /* if */
- modpath = (LPWSTR) ptr;
-
- rc = pGetModuleFileNameW(NULL, modpath, buflen);
- if (rc == 0)
- {
- allocator.Free(modpath);
- BAIL_MACRO(winApiStrError(), NULL);
- } /* if */
-
- if (rc < buflen)
- {
- buflen = rc;
- break;
- } /* if */
-
- buflen *= 2;
- } /* while */
-
- if (buflen > 0) /* just in case... */
- {
- WCHAR *ptr = (modpath + buflen) - 1;
- while (ptr != modpath)
- {
- if (*ptr == '\\')
- break;
- ptr--;
- } /* while */
-
- if ((ptr == modpath) && (*ptr != '\\'))
- __PHYSFS_setError(ERR_GETMODFN_NO_DIR);
- else
- {
- *(ptr + 1) = '\0'; /* chop off filename. */
- retval = unicodeToUtf8Heap(modpath);
- } /* else */
- } /* else */
- allocator.Free(modpath);
-
- return(retval); /* w00t. */
-} /* getExePath */
-
-
-/*
- * Try to make use of GetUserProfileDirectoryW(), which isn't available on
- * some common variants of Win32. If we can't use this, we just punt and
- * use the physfs base dir for the user dir, too.
- *
- * On success, module-scope variable (userDir) will have a pointer to
- * a malloc()'d string of the user's profile dir, and a non-zero value is
- * returned. If we can't determine the profile dir, (userDir) will
- * be NULL, and zero is returned.
- */
-static int determineUserDir(void)
-{
- if (userDir != NULL)
- return(1); /* already good to go. */
-
- /*
- * GetUserProfileDirectoryW() is only available on NT 4.0 and later.
- * This means Win95/98/ME (and CE?) users have to do without, so for
- * them, we'll default to the base directory when we can't get the
- * function pointer. Since this is originally an NT API, we don't
- * offer a non-Unicode fallback.
- */
- if (pGetUserProfileDirectoryW != NULL)
- {
- HANDLE accessToken = NULL; /* Security handle to process */
- HANDLE processHandle = GetCurrentProcess();
- if (OpenProcessToken(processHandle, TOKEN_QUERY, &accessToken))
- {
- DWORD psize = 0;
- WCHAR dummy = 0;
- LPWSTR wstr = NULL;
- BOOL rc = 0;
-
- /*
- * Should fail. Will write the size of the profile path in
- * psize. Also note that the second parameter can't be
- * NULL or the function fails.
- */
- rc = pGetUserProfileDirectoryW(accessToken, &dummy, &psize);
- assert(!rc); /* !!! FIXME: handle this gracefully. */
-
- /* Allocate memory for the profile directory */
- wstr = (LPWSTR) __PHYSFS_smallAlloc(psize * sizeof (WCHAR));
- if (wstr != NULL)
- {
- if (pGetUserProfileDirectoryW(accessToken, wstr, &psize))
- userDir = unicodeToUtf8Heap(wstr);
- __PHYSFS_smallFree(wstr);
- } /* else */
- } /* if */
-
- CloseHandle(accessToken);
- } /* if */
-
- if (userDir == NULL) /* couldn't get profile for some reason. */
- {
- /* Might just be a non-NT system; resort to the basedir. */
- userDir = getExePath();
- BAIL_IF_MACRO(userDir == NULL, NULL, 0); /* STILL failed?! */
- } /* if */
-
- return(1); /* We made it: hit the showers. */
-} /* determineUserDir */
-
-
-static BOOL mediaInDrive(const char *drive)
-{
- UINT oldErrorMode;
- DWORD tmp;
- BOOL retval;
-
- /* Prevent windows warning message appearing when checking media size */
- oldErrorMode = SetErrorMode(SEM_FAILCRITICALERRORS);
-
- /* If this function succeeds, there's media in the drive */
- retval = GetVolumeInformationA(drive, NULL, 0, NULL, NULL, &tmp, NULL, 0);
-
- /* Revert back to old windows error handler */
- SetErrorMode(oldErrorMode);
-
- return(retval);
-} /* mediaInDrive */
-
-
-void __PHYSFS_platformDetectAvailableCDs(PHYSFS_StringCallback cb, void *data)
-{
- /* !!! FIXME: Can CD drives be non-drive letter paths? */
- /* !!! FIXME: (so can they be Unicode paths?) */
- char drive_str[4] = "x:\\";
- char ch;
- for (ch = 'A'; ch <= 'Z'; ch++)
- {
- drive_str[0] = ch;
- if (GetDriveType(drive_str) == DRIVE_CDROM && mediaInDrive(drive_str))
- cb(data, drive_str);
- } /* for */
-} /* __PHYSFS_platformDetectAvailableCDs */
-
-
-char *__PHYSFS_platformCalcBaseDir(const char *argv0)
-{
- if ((argv0 != NULL) && (strchr(argv0, '\\') != NULL))
- return(NULL); /* default behaviour can handle this. */
-
- return(getExePath());
-} /* __PHYSFS_platformCalcBaseDir */
-
-
-char *__PHYSFS_platformGetUserName(void)
-{
- DWORD bufsize = 0;
- char *retval = NULL;
-
- if (pGetUserNameW(NULL, &bufsize) == 0) /* This SHOULD fail. */
- {
- LPWSTR wbuf = (LPWSTR) __PHYSFS_smallAlloc(bufsize * sizeof (WCHAR));
- BAIL_IF_MACRO(wbuf == NULL, ERR_OUT_OF_MEMORY, NULL);
- if (pGetUserNameW(wbuf, &bufsize) == 0) /* ?! */
- __PHYSFS_setError(winApiStrError());
- else
- retval = unicodeToUtf8Heap(wbuf);
- __PHYSFS_smallFree(wbuf);
- } /* if */
-
- return(retval);
-} /* __PHYSFS_platformGetUserName */
-
-
-char *__PHYSFS_platformGetUserDir(void)
-{
- char *retval = (char *) allocator.Malloc(strlen(userDir) + 1);
- BAIL_IF_MACRO(retval == NULL, ERR_OUT_OF_MEMORY, NULL);
- strcpy(retval, userDir); /* calculated at init time. */
- return(retval);
-} /* __PHYSFS_platformGetUserDir */
-
-
-PHYSFS_uint64 __PHYSFS_platformGetThreadID(void)
-{
- return((PHYSFS_uint64) GetCurrentThreadId());
-} /* __PHYSFS_platformGetThreadID */
-
-
-static int doPlatformExists(LPWSTR wpath)
-{
- BAIL_IF_MACRO
- (
- pGetFileAttributesW(wpath) == PHYSFS_INVALID_FILE_ATTRIBUTES,
- winApiStrError(), 0
- );
- return(1);
-} /* doPlatformExists */
-
-
-int __PHYSFS_platformExists(const char *fname)
-{
- int retval = 0;
- LPWSTR wpath;
- UTF8_TO_UNICODE_STACK_MACRO(wpath, fname);
- BAIL_IF_MACRO(wpath == NULL, ERR_OUT_OF_MEMORY, 0);
- retval = doPlatformExists(wpath);
- __PHYSFS_smallFree(wpath);
- return(retval);
-} /* __PHYSFS_platformExists */
-
-
-static int isSymlinkAttrs(const DWORD attr, const DWORD tag)
-{
- return ( (attr & FILE_ATTRIBUTE_REPARSE_POINT) &&
- (tag == PHYSFS_IO_REPARSE_TAG_SYMLINK) );
-} /* isSymlinkAttrs */
-
-
-int __PHYSFS_platformIsSymLink(const char *fname)
-{
- /* !!! FIXME:
- * Windows Vista can have NTFS symlinks. Can older Windows releases have
- * them when talking to a network file server? What happens when you
- * mount a NTFS partition on XP that was plugged into a Vista install
- * that made a symlink?
- */
-
- int retval = 0;
- LPWSTR wpath;
- HANDLE dir;
- WIN32_FIND_DATAW entw;
-
- /* no unicode entry points? Probably no symlinks. */
- BAIL_IF_MACRO(pFindFirstFileW == NULL, NULL, 0);
-
- UTF8_TO_UNICODE_STACK_MACRO(wpath, fname);
- BAIL_IF_MACRO(wpath == NULL, ERR_OUT_OF_MEMORY, 0);
-
- /* !!! FIXME: filter wildcard chars? */
- dir = pFindFirstFileW(wpath, &entw);
- if (dir != INVALID_HANDLE_VALUE)
- {
- retval = isSymlinkAttrs(entw.dwFileAttributes, entw.dwReserved0);
- FindClose(dir);
- } /* if */
-
- __PHYSFS_smallFree(wpath);
- return(retval);
-} /* __PHYSFS_platformIsSymlink */
-
-
-int __PHYSFS_platformIsDirectory(const char *fname)
-{
- int retval = 0;
- LPWSTR wpath;
- UTF8_TO_UNICODE_STACK_MACRO(wpath, fname);
- BAIL_IF_MACRO(wpath == NULL, ERR_OUT_OF_MEMORY, 0);
- retval = ((pGetFileAttributesW(wpath) & FILE_ATTRIBUTE_DIRECTORY) != 0);
- __PHYSFS_smallFree(wpath);
- return(retval);
-} /* __PHYSFS_platformIsDirectory */
-
-
-char *__PHYSFS_platformCvtToDependent(const char *prepend,
- const char *dirName,
- const char *append)
-{
- int len = ((prepend) ? strlen(prepend) : 0) +
- ((append) ? strlen(append) : 0) +
- strlen(dirName) + 1;
- char *retval = (char *) allocator.Malloc(len);
- char *p;
-
- BAIL_IF_MACRO(retval == NULL, ERR_OUT_OF_MEMORY, NULL);
-
- if (prepend)
- strcpy(retval, prepend);
- else
- retval[0] = '\0';
-
- strcat(retval, dirName);
-
- if (append)
- strcat(retval, append);
-
- for (p = strchr(retval, '/'); p != NULL; p = strchr(p + 1, '/'))
- *p = '\\';
-
- return(retval);
-} /* __PHYSFS_platformCvtToDependent */
-
-
-void __PHYSFS_platformEnumerateFiles(const char *dirname,
- int omitSymLinks,
- PHYSFS_EnumFilesCallback callback,
- const char *origdir,
- void *callbackdata)
-{
- const int unicode = (pFindFirstFileW != NULL) && (pFindNextFileW != NULL);
- HANDLE dir = INVALID_HANDLE_VALUE;
- WIN32_FIND_DATA ent;
- WIN32_FIND_DATAW entw;
- size_t len = strlen(dirname);
- char *searchPath = NULL;
- WCHAR *wSearchPath = NULL;
- char *utf8 = NULL;
-
- /* Allocate a new string for path, maybe '\\', "*", and NULL terminator */
- searchPath = (char *) __PHYSFS_smallAlloc(len + 3);
- if (searchPath == NULL)
- return;
-
- /* Copy current dirname */
- strcpy(searchPath, dirname);
-
- /* if there's no '\\' at the end of the path, stick one in there. */
- if (searchPath[len - 1] != '\\')
- {
- searchPath[len++] = '\\';
- searchPath[len] = '\0';
- } /* if */
-
- /* Append the "*" to the end of the string */
- strcat(searchPath, "*");
-
- UTF8_TO_UNICODE_STACK_MACRO(wSearchPath, searchPath);
- if (wSearchPath == NULL)
- return; /* oh well. */
-
- if (unicode)
- dir = pFindFirstFileW(wSearchPath, &entw);
- else
- {
- const int len = (int) (wStrLen(wSearchPath) + 1);
- char *cp = (char *) __PHYSFS_smallAlloc(len);
- if (cp != NULL)
- {
- WideCharToMultiByte(CP_ACP, 0, wSearchPath, len, cp, len, 0, 0);
- dir = FindFirstFileA(cp, &ent);
- __PHYSFS_smallFree(cp);
- } /* if */
- } /* else */
-
- __PHYSFS_smallFree(wSearchPath);
- __PHYSFS_smallFree(searchPath);
- if (dir == INVALID_HANDLE_VALUE)
- return;
-
- if (unicode)
- {
- do
- {
- const DWORD attr = entw.dwFileAttributes;
- const DWORD tag = entw.dwReserved0;
- const WCHAR *fn = entw.cFileName;
- if ((fn[0] == '.') && (fn[1] == '\0'))
- continue;
- if ((fn[0] == '.') && (fn[1] == '.') && (fn[2] == '\0'))
- continue;
- if ((omitSymLinks) && (isSymlinkAttrs(attr, tag)))
- continue;
-
- utf8 = unicodeToUtf8Heap(fn);
- if (utf8 != NULL)
- {
- callback(callbackdata, origdir, utf8);
- allocator.Free(utf8);
- } /* if */
- } while (pFindNextFileW(dir, &entw) != 0);
- } /* if */
-
- else /* ANSI fallback. */
- {
- do
- {
- const DWORD attr = ent.dwFileAttributes;
- const DWORD tag = ent.dwReserved0;
- const char *fn = ent.cFileName;
- if ((fn[0] == '.') && (fn[1] == '\0'))
- continue;
- if ((fn[0] == '.') && (fn[1] == '.') && (fn[2] == '\0'))
- continue;
- if ((omitSymLinks) && (isSymlinkAttrs(attr, tag)))
- continue;
-
- utf8 = codepageToUtf8Heap(fn);
- if (utf8 != NULL)
- {
- callback(callbackdata, origdir, utf8);
- allocator.Free(utf8);
- } /* if */
- } while (FindNextFileA(dir, &ent) != 0);
- } /* else */
-
- FindClose(dir);
-} /* __PHYSFS_platformEnumerateFiles */
-
-
-char *__PHYSFS_platformCurrentDir(void)
-{
- char *retval = NULL;
- WCHAR *wbuf = NULL;
- DWORD buflen = 0;
-
- buflen = pGetCurrentDirectoryW(buflen, NULL);
- wbuf = (WCHAR *) __PHYSFS_smallAlloc((buflen + 2) * sizeof (WCHAR));
- BAIL_IF_MACRO(wbuf == NULL, ERR_OUT_OF_MEMORY, NULL);
- pGetCurrentDirectoryW(buflen, wbuf);
-
- if (wbuf[buflen - 2] == '\\')
- wbuf[buflen-1] = '\0'; /* just in case... */
- else
- {
- wbuf[buflen - 1] = '\\';
- wbuf[buflen] = '\0';
- } /* else */
-
- retval = unicodeToUtf8Heap(wbuf);
- __PHYSFS_smallFree(wbuf);
- return(retval);
-} /* __PHYSFS_platformCurrentDir */
-
-
-/* this could probably use a cleanup. */
-char *__PHYSFS_platformRealPath(const char *path)
-{
- /* !!! FIXME: try GetFullPathName() instead? */
- /* this function should be UTF-8 clean. */
- char *retval = NULL;
- char *p = NULL;
-
- BAIL_IF_MACRO(path == NULL, ERR_INVALID_ARGUMENT, NULL);
- BAIL_IF_MACRO(*path == '\0', ERR_INVALID_ARGUMENT, NULL);
-
- retval = (char *) allocator.Malloc(MAX_PATH);
- BAIL_IF_MACRO(retval == NULL, ERR_OUT_OF_MEMORY, NULL);
-
- /*
- * If in \\server\path format, it's already an absolute path.
- * We'll need to check for "." and ".." dirs, though, just in case.
- */
- if ((path[0] == '\\') && (path[1] == '\\'))
- strcpy(retval, path);
-
- else
- {
- char *currentDir = __PHYSFS_platformCurrentDir();
- if (currentDir == NULL)
- {
- allocator.Free(retval);
- BAIL_MACRO(ERR_OUT_OF_MEMORY, NULL);
- } /* if */
-
- if (path[1] == ':') /* drive letter specified? */
- {
- /*
- * Apparently, "D:mypath" is the same as "D:\\mypath" if
- * D: is not the current drive. However, if D: is the
- * current drive, then "D:mypath" is a relative path. Ugh.
- */
- if (path[2] == '\\') /* maybe an absolute path? */
- strcpy(retval, path);
- else /* definitely an absolute path. */
- {
- if (path[0] == currentDir[0]) /* current drive; relative. */
- {
- strcpy(retval, currentDir);
- strcat(retval, path + 2);
- } /* if */
-
- else /* not current drive; absolute. */
- {
- retval[0] = path[0];
- retval[1] = ':';
- retval[2] = '\\';
- strcpy(retval + 3, path + 2);
- } /* else */
- } /* else */
- } /* if */
-
- else /* no drive letter specified. */
- {
- if (path[0] == '\\') /* absolute path. */
- {
- retval[0] = currentDir[0];
- retval[1] = ':';
- strcpy(retval + 2, path);
- } /* if */
- else
- {
- strcpy(retval, currentDir);
- strcat(retval, path);
- } /* else */
- } /* else */
-
- allocator.Free(currentDir);
- } /* else */
-
- /* (whew.) Ok, now take out "." and ".." path entries... */
-
- p = retval;
- while ( (p = strstr(p, "\\.")) != NULL)
- {
- /* it's a "." entry that doesn't end the string. */
- if (p[2] == '\\')
- memmove(p + 1, p + 3, strlen(p + 3) + 1);
-
- /* it's a "." entry that ends the string. */
- else if (p[2] == '\0')
- p[0] = '\0';
-
- /* it's a ".." entry. */
- else if (p[2] == '.')
- {
- char *prevEntry = p - 1;
- while ((prevEntry != retval) && (*prevEntry != '\\'))
- prevEntry--;
-
- if (prevEntry == retval) /* make it look like a "." entry. */
- memmove(p + 1, p + 2, strlen(p + 2) + 1);
- else
- {
- if (p[3] != '\0') /* doesn't end string. */
- *prevEntry = '\0';
- else /* ends string. */
- memmove(prevEntry + 1, p + 4, strlen(p + 4) + 1);
-
- p = prevEntry;
- } /* else */
- } /* else if */
-
- else
- {
- p++; /* look past current char. */
- } /* else */
- } /* while */
-
- /* shrink the retval's memory block if possible... */
- p = (char *) allocator.Realloc(retval, strlen(retval) + 1);
- if (p != NULL)
- retval = p;
-
- return(retval);
-} /* __PHYSFS_platformRealPath */
-
-
-int __PHYSFS_platformMkDir(const char *path)
-{
- WCHAR *wpath;
- DWORD rc;
- UTF8_TO_UNICODE_STACK_MACRO(wpath, path);
- rc = pCreateDirectoryW(wpath, NULL);
- __PHYSFS_smallFree(wpath);
- BAIL_IF_MACRO(rc == 0, winApiStrError(), 0);
- return(1);
-} /* __PHYSFS_platformMkDir */
-
-
- /*
- * Get OS info and save the important parts.
- *
- * Returns non-zero if successful, otherwise it returns zero on failure.
- */
- static int getOSInfo(void)
- {
- OSVERSIONINFO osVerInfo; /* Information about the OS */
- osVerInfo.dwOSVersionInfoSize = sizeof(osVerInfo);
- BAIL_IF_MACRO(!GetVersionEx(&osVerInfo), winApiStrError(), 0);
- osHasUnicode = (osVerInfo.dwPlatformId != VER_PLATFORM_WIN32_WINDOWS);
- return(1);
- } /* getOSInfo */
-
-
-int __PHYSFS_platformInit(void)
-{
- BAIL_IF_MACRO(!getOSInfo(), NULL, 0);
- BAIL_IF_MACRO(!findApiSymbols(), NULL, 0);
- BAIL_IF_MACRO(!determineUserDir(), NULL, 0);
- return(1); /* It's all good */
-} /* __PHYSFS_platformInit */
-
-
-int __PHYSFS_platformDeinit(void)
-{
- HANDLE *libs[] = { &libKernel32, &libUserEnv, &libAdvApi32, NULL };
- int i;
-
- allocator.Free(userDir);
- userDir = NULL;
-
- for (i = 0; libs[i] != NULL; i++)
- {
- const HANDLE lib = *(libs[i]);
- if (lib)
- FreeLibrary(lib);
- *(libs[i]) = NULL;
- } /* for */
-
- return(1); /* It's all good */
-} /* __PHYSFS_platformDeinit */
-
-
-static void *doOpen(const char *fname, DWORD mode, DWORD creation, int rdonly)
-{
- HANDLE fileHandle;
- WinApiFile *retval;
- WCHAR *wfname;
-
- UTF8_TO_UNICODE_STACK_MACRO(wfname, fname);
- BAIL_IF_MACRO(wfname == NULL, ERR_OUT_OF_MEMORY, NULL);
- fileHandle = pCreateFileW(wfname, mode, FILE_SHARE_READ, NULL,
- creation, FILE_ATTRIBUTE_NORMAL, NULL);
- __PHYSFS_smallFree(wfname);
-
- BAIL_IF_MACRO
- (
- fileHandle == INVALID_HANDLE_VALUE,
- winApiStrError(), NULL
- );
-
- retval = (WinApiFile *) allocator.Malloc(sizeof (WinApiFile));
- if (retval == NULL)
- {
- CloseHandle(fileHandle);
- BAIL_MACRO(ERR_OUT_OF_MEMORY, NULL);
- } /* if */
-
- retval->readonly = rdonly;
- retval->handle = fileHandle;
- return(retval);
-} /* doOpen */
-
-
-void *__PHYSFS_platformOpenRead(const char *filename)
-{
- return(doOpen(filename, GENERIC_READ, OPEN_EXISTING, 1));
-} /* __PHYSFS_platformOpenRead */
-
-
-void *__PHYSFS_platformOpenWrite(const char *filename)
-{
- return(doOpen(filename, GENERIC_WRITE, CREATE_ALWAYS, 0));
-} /* __PHYSFS_platformOpenWrite */
-
-
-void *__PHYSFS_platformOpenAppend(const char *filename)
-{
- void *retval = doOpen(filename, GENERIC_WRITE, OPEN_ALWAYS, 0);
- if (retval != NULL)
- {
- HANDLE h = ((WinApiFile *) retval)->handle;
- DWORD rc = SetFilePointer(h, 0, NULL, FILE_END);
- if (rc == PHYSFS_INVALID_SET_FILE_POINTER)
- {
- const char *err = winApiStrError();
- CloseHandle(h);
- allocator.Free(retval);
- BAIL_MACRO(err, NULL);
- } /* if */
- } /* if */
-
- return(retval);
-} /* __PHYSFS_platformOpenAppend */
-
-
-PHYSFS_sint64 __PHYSFS_platformRead(void *opaque, void *buffer,
- PHYSFS_uint32 size, PHYSFS_uint32 count)
-{
- HANDLE Handle = ((WinApiFile *) opaque)->handle;
- DWORD CountOfBytesRead;
- PHYSFS_sint64 retval;
-
- /* Read data from the file */
- /* !!! FIXME: uint32 might be a greater # than DWORD */
- if(!ReadFile(Handle, buffer, count * size, &CountOfBytesRead, NULL))
- {
- BAIL_MACRO(winApiStrError(), -1);
- } /* if */
- else
- {
- /* Return the number of "objects" read. */
- /* !!! FIXME: What if not the right amount of bytes was read to make an object? */
- retval = CountOfBytesRead / size;
- } /* else */
-
- return(retval);
-} /* __PHYSFS_platformRead */
-
-
-PHYSFS_sint64 __PHYSFS_platformWrite(void *opaque, const void *buffer,
- PHYSFS_uint32 size, PHYSFS_uint32 count)
-{
- HANDLE Handle = ((WinApiFile *) opaque)->handle;
- DWORD CountOfBytesWritten;
- PHYSFS_sint64 retval;
-
- /* Read data from the file */
- /* !!! FIXME: uint32 might be a greater # than DWORD */
- if(!WriteFile(Handle, buffer, count * size, &CountOfBytesWritten, NULL))
- {
- BAIL_MACRO(winApiStrError(), -1);
- } /* if */
- else
- {
- /* Return the number of "objects" read. */
- /* !!! FIXME: What if not the right number of bytes was written? */
- retval = CountOfBytesWritten / size;
- } /* else */
-
- return(retval);
-} /* __PHYSFS_platformWrite */
-
-
-int __PHYSFS_platformSeek(void *opaque, PHYSFS_uint64 pos)
-{
- HANDLE Handle = ((WinApiFile *) opaque)->handle;
- DWORD HighOrderPos;
- DWORD *pHighOrderPos;
- DWORD rc;
-
- /* Get the high order 32-bits of the position */
- HighOrderPos = HIGHORDER_UINT64(pos);
-
- /*
- * MSDN: "If you do not need the high-order 32 bits, this
- * pointer must be set to NULL."
- */
- pHighOrderPos = (HighOrderPos) ? &HighOrderPos : NULL;
-
- /*
- * !!! FIXME: MSDN: "Windows Me/98/95: If the pointer
- * !!! FIXME: lpDistanceToMoveHigh is not NULL, then it must
- * !!! FIXME: point to either 0, INVALID_SET_FILE_POINTER, or
- * !!! FIXME: the sign extension of the value of lDistanceToMove.
- * !!! FIXME: Any other value will be rejected."
- */
-
- /* Move pointer "pos" count from start of file */
- rc = SetFilePointer(Handle, LOWORDER_UINT64(pos),
- pHighOrderPos, FILE_BEGIN);
-
- if ( (rc == PHYSFS_INVALID_SET_FILE_POINTER) &&
- (GetLastError() != NO_ERROR) )
- {
- BAIL_MACRO(winApiStrError(), 0);
- } /* if */
-
- return(1); /* No error occured */
-} /* __PHYSFS_platformSeek */
-
-
-PHYSFS_sint64 __PHYSFS_platformTell(void *opaque)
-{
- HANDLE Handle = ((WinApiFile *) opaque)->handle;
- DWORD HighPos = 0;
- DWORD LowPos;
- PHYSFS_sint64 retval;
-
- /* Get current position */
- LowPos = SetFilePointer(Handle, 0, &HighPos, FILE_CURRENT);
- if ( (LowPos == PHYSFS_INVALID_SET_FILE_POINTER) &&
- (GetLastError() != NO_ERROR) )
- {
- BAIL_MACRO(winApiStrError(), 0);
- } /* if */
- else
- {
- /* Combine the high/low order to create the 64-bit position value */
- retval = (((PHYSFS_uint64) HighPos) << 32) | LowPos;
- assert(retval >= 0);
- } /* else */
-
- return(retval);
-} /* __PHYSFS_platformTell */
-
-
-PHYSFS_sint64 __PHYSFS_platformFileLength(void *opaque)
-{
- HANDLE Handle = ((WinApiFile *) opaque)->handle;
- DWORD SizeHigh;
- DWORD SizeLow;
- PHYSFS_sint64 retval;
-
- SizeLow = GetFileSize(Handle, &SizeHigh);
- if ( (SizeLow == PHYSFS_INVALID_SET_FILE_POINTER) &&
- (GetLastError() != NO_ERROR) )
- {
- BAIL_MACRO(winApiStrError(), -1);
- } /* if */
- else
- {
- /* Combine the high/low order to create the 64-bit position value */
- retval = (((PHYSFS_uint64) SizeHigh) << 32) | SizeLow;
- assert(retval >= 0);
- } /* else */
-
- return(retval);
-} /* __PHYSFS_platformFileLength */
-
-
-int __PHYSFS_platformEOF(void *opaque)
-{
- PHYSFS_sint64 FilePosition;
- int retval = 0;
-
- /* Get the current position in the file */
- if ((FilePosition = __PHYSFS_platformTell(opaque)) != 0)
- {
- /* Non-zero if EOF is equal to the file length */
- retval = FilePosition == __PHYSFS_platformFileLength(opaque);
- } /* if */
-
- return(retval);
-} /* __PHYSFS_platformEOF */
-
-
-int __PHYSFS_platformFlush(void *opaque)
-{
- WinApiFile *fh = ((WinApiFile *) opaque);
- if (!fh->readonly)
- BAIL_IF_MACRO(!FlushFileBuffers(fh->handle), winApiStrError(), 0);
-
- return(1);
-} /* __PHYSFS_platformFlush */
-
-
-int __PHYSFS_platformClose(void *opaque)
-{
- HANDLE Handle = ((WinApiFile *) opaque)->handle;
- BAIL_IF_MACRO(!CloseHandle(Handle), winApiStrError(), 0);
- allocator.Free(opaque);
- return(1);
-} /* __PHYSFS_platformClose */
-
-
-static int doPlatformDelete(LPWSTR wpath)
-{
- /* If filename is a folder */
- if (pGetFileAttributesW(wpath) == FILE_ATTRIBUTE_DIRECTORY)
- {
- BAIL_IF_MACRO(!pRemoveDirectoryW(wpath), winApiStrError(), 0);
- } /* if */
- else
- {
- BAIL_IF_MACRO(!pDeleteFileW(wpath), winApiStrError(), 0);
- } /* else */
-
- return(1); /* if you made it here, it worked. */
-} /* doPlatformDelete */
-
-
-int __PHYSFS_platformDelete(const char *path)
-{
- int retval = 0;
- LPWSTR wpath;
- UTF8_TO_UNICODE_STACK_MACRO(wpath, path);
- BAIL_IF_MACRO(wpath == NULL, ERR_OUT_OF_MEMORY, 0);
- retval = doPlatformDelete(wpath);
- __PHYSFS_smallFree(wpath);
- return(retval);
-} /* __PHYSFS_platformDelete */
-
-
-/*
- * !!! FIXME: why aren't we using Critical Sections instead of Mutexes?
- * !!! FIXME: mutexes on Windows are for cross-process sync. CritSects are
- * !!! FIXME: mutexes for threads in a single process and are faster.
- */
-void *__PHYSFS_platformCreateMutex(void)
-{
- return((void *) CreateMutex(NULL, FALSE, NULL));
-} /* __PHYSFS_platformCreateMutex */
-
-
-void __PHYSFS_platformDestroyMutex(void *mutex)
-{
- CloseHandle((HANDLE) mutex);
-} /* __PHYSFS_platformDestroyMutex */
-
-
-int __PHYSFS_platformGrabMutex(void *mutex)
-{
- return(WaitForSingleObject((HANDLE) mutex, INFINITE) != WAIT_FAILED);
-} /* __PHYSFS_platformGrabMutex */
-
-
-void __PHYSFS_platformReleaseMutex(void *mutex)
-{
- ReleaseMutex((HANDLE) mutex);
-} /* __PHYSFS_platformReleaseMutex */
-
-
-static PHYSFS_sint64 FileTimeToPhysfsTime(const FILETIME *ft)
-{
- SYSTEMTIME st_utc;
- SYSTEMTIME st_localtz;
- TIME_ZONE_INFORMATION tzi;
- DWORD tzid;
- PHYSFS_sint64 retval;
- struct tm tm;
-
- BAIL_IF_MACRO(!FileTimeToSystemTime(ft, &st_utc), winApiStrError(), -1);
- tzid = GetTimeZoneInformation(&tzi);
- BAIL_IF_MACRO(tzid == TIME_ZONE_ID_INVALID, winApiStrError(), -1);
-
- /* (This API is unsupported and fails on non-NT systems. */
- if (!SystemTimeToTzSpecificLocalTime(&tzi, &st_utc, &st_localtz))
- {
- /* do it by hand. Grumble... */
- ULARGE_INTEGER ui64;
- FILETIME new_ft;
- ui64.LowPart = ft->dwLowDateTime;
- ui64.HighPart = ft->dwHighDateTime;
-
- if (tzid == TIME_ZONE_ID_STANDARD)
- tzi.Bias += tzi.StandardBias;
- else if (tzid == TIME_ZONE_ID_DAYLIGHT)
- tzi.Bias += tzi.DaylightBias;
-
- /* convert from minutes to 100-nanosecond increments... */
- ui64.QuadPart -= (((LONGLONG) tzi.Bias) * (600000000));
-
- /* Move it back into a FILETIME structure... */
- new_ft.dwLowDateTime = ui64.LowPart;
- new_ft.dwHighDateTime = ui64.HighPart;
-
- /* Convert to something human-readable... */
- if (!FileTimeToSystemTime(&new_ft, &st_localtz))
- BAIL_MACRO(winApiStrError(), -1);
- } /* if */
-
- /* Convert to a format that mktime() can grok... */
- tm.tm_sec = st_localtz.wSecond;
- tm.tm_min = st_localtz.wMinute;
- tm.tm_hour = st_localtz.wHour;
- tm.tm_mday = st_localtz.wDay;
- tm.tm_mon = st_localtz.wMonth - 1;
- tm.tm_year = st_localtz.wYear - 1900;
- tm.tm_wday = -1 /*st_localtz.wDayOfWeek*/;
- tm.tm_yday = -1;
- tm.tm_isdst = -1;
-
- /* Convert to a format PhysicsFS can grok... */
- retval = (PHYSFS_sint64) mktime(&tm);
- BAIL_IF_MACRO(retval == -1, strerror(errno), -1);
- return(retval);
-} /* FileTimeToPhysfsTime */
-
-
-PHYSFS_sint64 __PHYSFS_platformGetLastModTime(const char *fname)
-{
- PHYSFS_sint64 retval = -1;
- WIN32_FILE_ATTRIBUTE_DATA attr;
- int rc = 0;
-
- memset(&attr, '\0', sizeof (attr));
-
- /* GetFileAttributesEx didn't show up until Win98 and NT4. */
- if ((pGetFileAttributesExW != NULL) || (pGetFileAttributesExA != NULL))
- {
- WCHAR *wstr;
- UTF8_TO_UNICODE_STACK_MACRO(wstr, fname);
- if (wstr != NULL) /* if NULL, maybe the fallback will work. */
- {
- if (pGetFileAttributesExW != NULL) /* NT/XP/Vista/etc system. */
- rc = pGetFileAttributesExW(wstr, GetFileExInfoStandard, &attr);
- else /* Win98/ME system */
- {
- const int len = (int) (wStrLen(wstr) + 1);
- char *cp = (char *) __PHYSFS_smallAlloc(len);
- if (cp != NULL)
- {
- WideCharToMultiByte(CP_ACP, 0, wstr, len, cp, len, 0, 0);
- rc = pGetFileAttributesExA(cp, GetFileExInfoStandard, &attr);
- __PHYSFS_smallFree(cp);
- } /* if */
- } /* else */
- __PHYSFS_smallFree(wstr);
- } /* if */
- } /* if */
-
- if (rc) /* had API entry point and it worked. */
- {
- /* 0 return value indicates an error or not supported */
- if ( (attr.ftLastWriteTime.dwHighDateTime != 0) ||
- (attr.ftLastWriteTime.dwLowDateTime != 0) )
- {
- retval = FileTimeToPhysfsTime(&attr.ftLastWriteTime);
- } /* if */
- } /* if */
-
- /* GetFileTime() has been in the Win32 API since the start. */
- if (retval == -1) /* try a fallback... */
- {
- FILETIME ft;
- BOOL rc;
- const char *err;
- WinApiFile *f = (WinApiFile *) __PHYSFS_platformOpenRead(fname);
- BAIL_IF_MACRO(f == NULL, NULL, -1)
- rc = GetFileTime(f->handle, NULL, NULL, &ft);
- err = winApiStrError();
- CloseHandle(f->handle);
- allocator.Free(f);
- BAIL_IF_MACRO(!rc, err, -1);
- retval = FileTimeToPhysfsTime(&ft);
- } /* if */
-
- return(retval);
-} /* __PHYSFS_platformGetLastModTime */
-
-
-/* !!! FIXME: Don't use C runtime for allocators? */
-int __PHYSFS_platformSetDefaultAllocator(PHYSFS_Allocator *a)
-{
- return(0); /* just use malloc() and friends. */
-} /* __PHYSFS_platformSetDefaultAllocator */
-
-#endif /* PHYSFS_PLATFORM_WINDOWS */
-
-/* end of windows.c ... */
-
-
+++ /dev/null
-/**
- * Test program for PhysicsFS. May only work on Unix.
- *
- * Please see the file LICENSE.txt in the source's root directory.
- *
- * This file written by Ryan C. Gordon.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <string.h>
-
-#if (defined __MWERKS__)
-#include <SIOUX.h>
-#endif
-
-#if (defined PHYSFS_HAVE_READLINE)
-#include <unistd.h>
-#include <readline/readline.h>
-#include <readline/history.h>
-#endif
-
-#include <time.h>
-
-#include "physfs.h"
-
-#define TEST_VERSION_MAJOR 1
-#define TEST_VERSION_MINOR 1
-#define TEST_VERSION_PATCH 1
-
-static FILE *history_file = NULL;
-static PHYSFS_uint32 do_buffer_size = 0;
-
-static void output_versions(void)
-{
- PHYSFS_Version compiled;
- PHYSFS_Version linked;
-
- PHYSFS_VERSION(&compiled);
- PHYSFS_getLinkedVersion(&linked);
-
- printf("test_physfs version %d.%d.%d.\n"
- " Compiled against PhysicsFS version %d.%d.%d,\n"
- " and linked against %d.%d.%d.\n\n",
- TEST_VERSION_MAJOR, TEST_VERSION_MINOR, TEST_VERSION_PATCH,
- (int) compiled.major, (int) compiled.minor, (int) compiled.patch,
- (int) linked.major, (int) linked.minor, (int) linked.patch);
-} /* output_versions */
-
-
-static void output_archivers(void)
-{
- const PHYSFS_ArchiveInfo **rc = PHYSFS_supportedArchiveTypes();
- const PHYSFS_ArchiveInfo **i;
-
- printf("Supported archive types:\n");
- if (*rc == NULL)
- printf(" * Apparently, NONE!\n");
- else
- {
- for (i = rc; *i != NULL; i++)
- {
- printf(" * %s: %s\n Written by %s.\n %s\n",
- (*i)->extension, (*i)->description,
- (*i)->author, (*i)->url);
- } /* for */
- } /* else */
-
- printf("\n");
-} /* output_archivers */
-
-
-static int cmd_quit(char *args)
-{
- return(0);
-} /* cmd_quit */
-
-
-static int cmd_init(char *args)
-{
- if (*args == '\"')
- {
- args++;
- args[strlen(args) - 1] = '\0';
- } /* if */
-
- if (PHYSFS_init(args))
- printf("Successful.\n");
- else
- printf("Failure. reason: %s.\n", PHYSFS_getLastError());
-
- return(1);
-} /* cmd_init */
-
-
-static int cmd_deinit(char *args)
-{
- if (PHYSFS_deinit())
- printf("Successful.\n");
- else
- printf("Failure. reason: %s.\n", PHYSFS_getLastError());
-
- return(1);
-} /* cmd_deinit */
-
-
-static int cmd_addarchive(char *args)
-{
- char *ptr = strrchr(args, ' ');
- int appending = atoi(ptr + 1);
- *ptr = '\0';
-
- if (*args == '\"')
- {
- args++;
- *(ptr - 1) = '\0';
- } /* if */
-
- /*printf("[%s], [%d]\n", args, appending);*/
-
- if (PHYSFS_addToSearchPath(args, appending))
- printf("Successful.\n");
- else
- printf("Failure. reason: %s.\n", PHYSFS_getLastError());
-
- return(1);
-} /* cmd_addarchive */
-
-
-static int cmd_mount(char *args)
-{
- char *ptr;
- char *mntpoint = NULL;
- int appending = 0;
-
- if (*args == '\"')
- {
- args++;
- ptr = strchr(args, '\"');
- if (ptr == NULL)
- {
- printf("missing string terminator in argument.\n");
- return(1);
- } /* if */
- *(ptr) = '\0';
- } /* if */
- else
- {
- ptr = strchr(args, ' ');
- *ptr = '\0';
- } /* else */
-
- mntpoint = ptr + 1;
- if (*mntpoint == '\"')
- {
- mntpoint++;
- ptr = strchr(mntpoint, '\"');
- if (ptr == NULL)
- {
- printf("missing string terminator in argument.\n");
- return(1);
- } /* if */
- *(ptr) = '\0';
- } /* if */
- else
- {
- ptr = strchr(mntpoint, ' ');
- *(ptr) = '\0';
- } /* else */
- appending = atoi(ptr + 1);
-
- /*printf("[%s], [%s], [%d]\n", args, mntpoint, appending);*/
-
- if (PHYSFS_mount(args, mntpoint, appending))
- printf("Successful.\n");
- else
- printf("Failure. reason: %s.\n", PHYSFS_getLastError());
-
- return(1);
-} /* cmd_mount */
-
-
-static int cmd_removearchive(char *args)
-{
- if (*args == '\"')
- {
- args++;
- args[strlen(args) - 1] = '\0';
- } /* if */
-
- if (PHYSFS_removeFromSearchPath(args))
- printf("Successful.\n");
- else
- printf("Failure. reason: %s.\n", PHYSFS_getLastError());
-
- return(1);
-} /* cmd_removearchive */
-
-
-static int cmd_enumerate(char *args)
-{
- char **rc;
-
- if (*args == '\"')
- {
- args++;
- args[strlen(args) - 1] = '\0';
- } /* if */
-
- rc = PHYSFS_enumerateFiles(args);
-
- if (rc == NULL)
- printf("Failure. reason: %s.\n", PHYSFS_getLastError());
- else
- {
- int file_count;
- char **i;
- for (i = rc, file_count = 0; *i != NULL; i++, file_count++)
- printf("%s\n", *i);
-
- printf("\n total (%d) files.\n", file_count);
- PHYSFS_freeList(rc);
- } /* else */
-
- return(1);
-} /* cmd_enumerate */
-
-
-static int cmd_getdirsep(char *args)
-{
- printf("Directory separator is [%s].\n", PHYSFS_getDirSeparator());
- return(1);
-} /* cmd_getdirsep */
-
-
-static int cmd_getlasterror(char *args)
-{
- printf("last error is [%s].\n", PHYSFS_getLastError());
- return(1);
-} /* cmd_getlasterror */
-
-
-static int cmd_getcdromdirs(char *args)
-{
- char **rc = PHYSFS_getCdRomDirs();
-
- if (rc == NULL)
- printf("Failure. Reason: [%s].\n", PHYSFS_getLastError());
- else
- {
- int dir_count;
- char **i;
- for (i = rc, dir_count = 0; *i != NULL; i++, dir_count++)
- printf("%s\n", *i);
-
- printf("\n total (%d) drives.\n", dir_count);
- PHYSFS_freeList(rc);
- } /* else */
-
- return(1);
-} /* cmd_getcdromdirs */
-
-
-static int cmd_getsearchpath(char *args)
-{
- char **rc = PHYSFS_getSearchPath();
-
- if (rc == NULL)
- printf("Failure. reason: %s.\n", PHYSFS_getLastError());
- else
- {
- int dir_count;
- char **i;
- for (i = rc, dir_count = 0; *i != NULL; i++, dir_count++)
- printf("%s\n", *i);
-
- printf("\n total (%d) directories.\n", dir_count);
- PHYSFS_freeList(rc);
- } /* else */
-
- return(1);
-} /* cmd_getcdromdirs */
-
-
-static int cmd_getbasedir(char *args)
-{
- printf("Base dir is [%s].\n", PHYSFS_getBaseDir());
- return(1);
-} /* cmd_getbasedir */
-
-
-static int cmd_getuserdir(char *args)
-{
- printf("User dir is [%s].\n", PHYSFS_getUserDir());
- return(1);
-} /* cmd_getuserdir */
-
-
-static int cmd_getwritedir(char *args)
-{
- printf("Write dir is [%s].\n", PHYSFS_getWriteDir());
- return(1);
-} /* cmd_getwritedir */
-
-
-static int cmd_setwritedir(char *args)
-{
- if (*args == '\"')
- {
- args++;
- args[strlen(args) - 1] = '\0';
- } /* if */
-
- if (PHYSFS_setWriteDir(args))
- printf("Successful.\n");
- else
- printf("Failure. reason: %s.\n", PHYSFS_getLastError());
-
- return(1);
-} /* cmd_setwritedir */
-
-
-static int cmd_permitsyms(char *args)
-{
- int num;
-
- if (*args == '\"')
- {
- args++;
- args[strlen(args) - 1] = '\0';
- } /* if */
-
- num = atoi(args);
- PHYSFS_permitSymbolicLinks(num);
- printf("Symlinks are now %s.\n", num ? "permitted" : "forbidden");
- return(1);
-} /* cmd_permitsyms */
-
-
-static int cmd_setbuffer(char *args)
-{
- if (*args == '\"')
- {
- args++;
- args[strlen(args) - 1] = '\0';
- } /* if */
-
- do_buffer_size = (unsigned int) atoi(args);
- if (do_buffer_size)
- {
- printf("Further tests will set a (%lu) size buffer.\n",
- (unsigned long) do_buffer_size);
- } /* if */
-
- else
- {
- printf("Further tests will NOT use a buffer.\n");
- } /* else */
-
- return(1);
-} /* cmd_setbuffer */
-
-
-static int cmd_stressbuffer(char *args)
-{
- int num;
-
- if (*args == '\"')
- {
- args++;
- args[strlen(args) - 1] = '\0';
- } /* if */
-
- num = atoi(args);
- if (num < 0)
- printf("buffer must be greater than or equal to zero.\n");
- else
- {
- PHYSFS_File *f;
- int rndnum;
-
- printf("Stress testing with (%d) byte buffer...\n", num);
- f = PHYSFS_openWrite("test.txt");
- if (f == NULL)
- printf("Couldn't open test.txt for writing: %s.\n", PHYSFS_getLastError());
- else
- {
- int i, j;
- char buf[37];
- char buf2[37];
-
- if (!PHYSFS_setBuffer(f, num))
- {
- printf("PHYSFS_setBuffer() failed: %s.\n", PHYSFS_getLastError());
- PHYSFS_close(f);
- PHYSFS_delete("test.txt");
- return(1);
- } /* if */
-
- strcpy(buf, "abcdefghijklmnopqrstuvwxyz0123456789");
- srand((unsigned int) time(NULL));
-
- for (i = 0; i < 10; i++)
- {
- for (j = 0; j < 10000; j++)
- {
- PHYSFS_uint32 right = 1 + (PHYSFS_uint32) (35.0 * rand() / (RAND_MAX + 1.0));
- PHYSFS_uint32 left = 36 - right;
- if (PHYSFS_write(f, buf, left, 1) != 1)
- {
- printf("PHYSFS_write() failed: %s.\n", PHYSFS_getLastError());
- PHYSFS_close(f);
- return(1);
- } /* if */
-
- rndnum = 1 + (int) (1000.0 * rand() / (RAND_MAX + 1.0));
- if (rndnum == 42)
- {
- if (!PHYSFS_flush(f))
- {
- printf("PHYSFS_flush() failed: %s.\n", PHYSFS_getLastError());
- PHYSFS_close(f);
- return(1);
- } /* if */
- } /* if */
-
- if (PHYSFS_write(f, buf + left, 1, right) != right)
- {
- printf("PHYSFS_write() failed: %s.\n", PHYSFS_getLastError());
- PHYSFS_close(f);
- return(1);
- } /* if */
-
- rndnum = 1 + (int) (1000.0 * rand() / (RAND_MAX + 1.0));
- if (rndnum == 42)
- {
- if (!PHYSFS_flush(f))
- {
- printf("PHYSFS_flush() failed: %s.\n", PHYSFS_getLastError());
- PHYSFS_close(f);
- return(1);
- } /* if */
- } /* if */
- } /* for */
-
- if (!PHYSFS_flush(f))
- {
- printf("PHYSFS_flush() failed: %s.\n", PHYSFS_getLastError());
- PHYSFS_close(f);
- return(1);
- } /* if */
-
- } /* for */
-
- if (!PHYSFS_close(f))
- {
- printf("PHYSFS_close() failed: %s.\n", PHYSFS_getLastError());
- return(1); /* oh well. */
- } /* if */
-
- printf(" ... test file written ...\n");
- f = PHYSFS_openRead("test.txt");
- if (f == NULL)
- {
- printf("Failed to reopen stress file for reading: %s.\n", PHYSFS_getLastError());
- return(1);
- } /* if */
-
- if (!PHYSFS_setBuffer(f, num))
- {
- printf("PHYSFS_setBuffer() failed: %s.\n", PHYSFS_getLastError());
- PHYSFS_close(f);
- return(1);
- } /* if */
-
- for (i = 0; i < 10; i++)
- {
- for (j = 0; j < 10000; j++)
- {
- PHYSFS_uint32 right = 1 + (PHYSFS_uint32) (35.0 * rand() / (RAND_MAX + 1.0));
- PHYSFS_uint32 left = 36 - right;
- if (PHYSFS_read(f, buf2, left, 1) != 1)
- {
- printf("PHYSFS_read() failed: %s.\n", PHYSFS_getLastError());
- PHYSFS_close(f);
- return(1);
- } /* if */
-
- rndnum = 1 + (int) (1000.0 * rand() / (RAND_MAX + 1.0));
- if (rndnum == 42)
- {
- if (!PHYSFS_flush(f))
- {
- printf("PHYSFS_flush() failed: %s.\n", PHYSFS_getLastError());
- PHYSFS_close(f);
- return(1);
- } /* if */
- } /* if */
-
- if (PHYSFS_read(f, buf2 + left, 1, right) != right)
- {
- printf("PHYSFS_read() failed: %s.\n", PHYSFS_getLastError());
- PHYSFS_close(f);
- return(1);
- } /* if */
-
- rndnum = 1 + (int) (1000.0 * rand() / (RAND_MAX + 1.0));
- if (rndnum == 42)
- {
- if (!PHYSFS_flush(f))
- {
- printf("PHYSFS_flush() failed: %s.\n", PHYSFS_getLastError());
- PHYSFS_close(f);
- return(1);
- } /* if */
- } /* if */
-
- if (memcmp(buf, buf2, 36) != 0)
- {
- printf("readback is mismatched on iterations (%d, %d).\n", i, j);
- printf("wanted: [");
- for (i = 0; i < 36; i++)
- printf("%c", buf[i]);
- printf("]\n");
-
- printf(" got: [");
- for (i = 0; i < 36; i++)
- printf("%c", buf2[i]);
- printf("]\n");
- PHYSFS_close(f);
- return(1);
- } /* if */
- } /* for */
-
- if (!PHYSFS_flush(f))
- {
- printf("PHYSFS_flush() failed: %s.\n", PHYSFS_getLastError());
- PHYSFS_close(f);
- return(1);
- } /* if */
-
- } /* for */
-
- printf(" ... test file read ...\n");
-
- if (!PHYSFS_eof(f))
- printf("PHYSFS_eof() returned true! That's wrong.\n");
-
- if (!PHYSFS_close(f))
- {
- printf("PHYSFS_close() failed: %s.\n", PHYSFS_getLastError());
- return(1); /* oh well. */
- } /* if */
-
- PHYSFS_delete("test.txt");
- printf("stress test completed successfully.\n");
- } /* else */
- } /* else */
-
- return(1);
-} /* cmd_stressbuffer */
-
-
-static int cmd_setsaneconfig(char *args)
-{
- char *org;
- char *appName;
- char *arcExt;
- int inclCD;
- int arcsFirst;
- char *ptr = args;
-
- /* ugly. */
- org = ptr;
- ptr = strchr(ptr, ' '); *ptr = '\0'; ptr++; appName = ptr;
- ptr = strchr(ptr, ' '); *ptr = '\0'; ptr++; arcExt = ptr;
- ptr = strchr(ptr, ' '); *ptr = '\0'; ptr++; inclCD = atoi(arcExt);
- arcsFirst = atoi(ptr);
-
- if (strcmp(arcExt, "!") == 0)
- arcExt = NULL;
-
- if (PHYSFS_setSaneConfig(org, appName, arcExt, inclCD, arcsFirst))
- printf("Successful.\n");
- else
- printf("Failure. reason: %s.\n", PHYSFS_getLastError());
-
- return(1);
-} /* cmd_setsaneconfig */
-
-
-static int cmd_mkdir(char *args)
-{
- if (*args == '\"')
- {
- args++;
- args[strlen(args) - 1] = '\0';
- } /* if */
-
- if (PHYSFS_mkdir(args))
- printf("Successful.\n");
- else
- printf("Failure. reason: %s.\n", PHYSFS_getLastError());
-
- return(1);
-} /* cmd_mkdir */
-
-
-static int cmd_delete(char *args)
-{
- if (*args == '\"')
- {
- args++;
- args[strlen(args) - 1] = '\0';
- } /* if */
-
- if (PHYSFS_delete(args))
- printf("Successful.\n");
- else
- printf("Failure. reason: %s.\n", PHYSFS_getLastError());
-
- return(1);
-} /* cmd_delete */
-
-
-static int cmd_getrealdir(char *args)
-{
- const char *rc;
-
- if (*args == '\"')
- {
- args++;
- args[strlen(args) - 1] = '\0';
- } /* if */
-
- rc = PHYSFS_getRealDir(args);
- if (rc)
- printf("Found at [%s].\n", rc);
- else
- printf("Not found.\n");
-
- return(1);
-} /* cmd_getrealdir */
-
-
-static int cmd_exists(char *args)
-{
- int rc;
-
- if (*args == '\"')
- {
- args++;
- args[strlen(args) - 1] = '\0';
- } /* if */
-
- rc = PHYSFS_exists(args);
- printf("File %sexists.\n", rc ? "" : "does not ");
- return(1);
-} /* cmd_exists */
-
-
-static int cmd_isdir(char *args)
-{
- int rc;
-
- if (*args == '\"')
- {
- args++;
- args[strlen(args) - 1] = '\0';
- } /* if */
-
- rc = PHYSFS_isDirectory(args);
- printf("File %s a directory.\n", rc ? "is" : "is NOT");
- return(1);
-} /* cmd_isdir */
-
-
-static int cmd_issymlink(char *args)
-{
- int rc;
-
- if (*args == '\"')
- {
- args++;
- args[strlen(args) - 1] = '\0';
- } /* if */
-
- rc = PHYSFS_isSymbolicLink(args);
- printf("File %s a symlink.\n", rc ? "is" : "is NOT");
- return(1);
-} /* cmd_issymlink */
-
-
-static int cmd_cat(char *args)
-{
- PHYSFS_File *f;
-
- if (*args == '\"')
- {
- args++;
- args[strlen(args) - 1] = '\0';
- } /* if */
-
- f = PHYSFS_openRead(args);
- if (f == NULL)
- printf("failed to open. Reason: [%s].\n", PHYSFS_getLastError());
- else
- {
- if (do_buffer_size)
- {
- if (!PHYSFS_setBuffer(f, do_buffer_size))
- {
- printf("failed to set file buffer. Reason: [%s].\n",
- PHYSFS_getLastError());
- PHYSFS_close(f);
- return(1);
- } /* if */
- } /* if */
-
- while (1)
- {
- char buffer[128];
- PHYSFS_sint64 rc;
- PHYSFS_sint64 i;
- rc = PHYSFS_read(f, buffer, 1, sizeof (buffer));
-
- for (i = 0; i < rc; i++)
- fputc((int) buffer[i], stdout);
-
- if (rc < sizeof (buffer))
- {
- printf("\n\n");
- if (!PHYSFS_eof(f))
- {
- printf("\n (Error condition in reading. Reason: [%s])\n\n",
- PHYSFS_getLastError());
- } /* if */
- PHYSFS_close(f);
- return(1);
- } /* if */
- } /* while */
- } /* else */
-
- return(1);
-} /* cmd_cat */
-
-
-static int cmd_filelength(char *args)
-{
- PHYSFS_File *f;
-
- if (*args == '\"')
- {
- args++;
- args[strlen(args) - 1] = '\0';
- } /* if */
-
- f = PHYSFS_openRead(args);
- if (f == NULL)
- printf("failed to open. Reason: [%s].\n", PHYSFS_getLastError());
- else
- {
- PHYSFS_sint64 len = PHYSFS_fileLength(f);
- if (len == -1)
- printf("failed to determine length. Reason: [%s].\n", PHYSFS_getLastError());
- else
- printf(" (cast to int) %d bytes.\n", (int) len);
-
- PHYSFS_close(f);
- } /* else */
-
- return(1);
-} /* cmd_filelength */
-
-
-#define WRITESTR "The cat sat on the mat.\n\n"
-
-static int cmd_append(char *args)
-{
- PHYSFS_File *f;
-
- if (*args == '\"')
- {
- args++;
- args[strlen(args) - 1] = '\0';
- } /* if */
-
- f = PHYSFS_openAppend(args);
- if (f == NULL)
- printf("failed to open. Reason: [%s].\n", PHYSFS_getLastError());
- else
- {
- size_t bw;
- PHYSFS_sint64 rc;
-
- if (do_buffer_size)
- {
- if (!PHYSFS_setBuffer(f, do_buffer_size))
- {
- printf("failed to set file buffer. Reason: [%s].\n",
- PHYSFS_getLastError());
- PHYSFS_close(f);
- return(1);
- } /* if */
- } /* if */
-
- bw = strlen(WRITESTR);
- rc = PHYSFS_write(f, WRITESTR, 1, bw);
- if (rc != bw)
- {
- printf("Wrote (%d) of (%d) bytes. Reason: [%s].\n",
- (int) rc, (int) bw, PHYSFS_getLastError());
- } /* if */
- else
- {
- printf("Successful.\n");
- } /* else */
-
- PHYSFS_close(f);
- } /* else */
-
- return(1);
-} /* cmd_append */
-
-
-static int cmd_write(char *args)
-{
- PHYSFS_File *f;
-
- if (*args == '\"')
- {
- args++;
- args[strlen(args) - 1] = '\0';
- } /* if */
-
- f = PHYSFS_openWrite(args);
- if (f == NULL)
- printf("failed to open. Reason: [%s].\n", PHYSFS_getLastError());
- else
- {
- size_t bw;
- PHYSFS_sint64 rc;
-
- if (do_buffer_size)
- {
- if (!PHYSFS_setBuffer(f, do_buffer_size))
- {
- printf("failed to set file buffer. Reason: [%s].\n",
- PHYSFS_getLastError());
- PHYSFS_close(f);
- return(1);
- } /* if */
- } /* if */
-
- bw = strlen(WRITESTR);
- rc = PHYSFS_write(f, WRITESTR, 1, bw);
- if (rc != bw)
- {
- printf("Wrote (%d) of (%d) bytes. Reason: [%s].\n",
- (int) rc, (int) bw, PHYSFS_getLastError());
- } /* if */
- else
- {
- printf("Successful.\n");
- } /* else */
-
- PHYSFS_close(f);
- } /* else */
-
- return(1);
-} /* cmd_write */
-
-
-static void modTimeToStr(PHYSFS_sint64 modtime, char *modstr, size_t strsize)
-{
- time_t t = (time_t) modtime;
- char *str = ctime(&t);
- strncpy(modstr, str, strsize);
- modstr[strsize-1] = '\0';
-} /* modTimeToStr */
-
-
-static int cmd_getlastmodtime(char *args)
-{
- PHYSFS_sint64 rc = PHYSFS_getLastModTime(args);
- if (rc == -1)
- printf("Failed to determine. Reason: [%s].\n", PHYSFS_getLastError());
- else
- {
- char modstr[64];
- modTimeToStr(rc, modstr, sizeof (modstr));
- printf("Last modified: %s (%ld).\n", modstr, (long) rc);
- } /* else */
-
- return(1);
-} /* cmd_getLastModTime */
-
-
-/* must have spaces trimmed prior to this call. */
-static int count_args(const char *str)
-{
- int retval = 0;
- int in_quotes = 0;
-
- if (str != NULL)
- {
- for (; *str != '\0'; str++)
- {
- if (*str == '\"')
- in_quotes = !in_quotes;
- else if ((*str == ' ') && (!in_quotes))
- retval++;
- } /* for */
- retval++;
- } /* if */
-
- return(retval);
-} /* count_args */
-
-
-static int cmd_help(char *args);
-
-typedef struct
-{
- const char *cmd;
- int (*func)(char *args);
- int argcount;
- const char *usage;
-} command_info;
-
-static const command_info commands[] =
-{
- { "quit", cmd_quit, 0, NULL },
- { "q", cmd_quit, 0, NULL },
- { "help", cmd_help, 0, NULL },
- { "init", cmd_init, 1, "<argv0>" },
- { "deinit", cmd_deinit, 0, NULL },
- { "addarchive", cmd_addarchive, 2, "<archiveLocation> <append>" },
- { "mount", cmd_mount, 3, "<archiveLocation> <mntpoint> <append>" },
- { "removearchive", cmd_removearchive, 1, "<archiveLocation>" },
- { "enumerate", cmd_enumerate, 1, "<dirToEnumerate>" },
- { "ls", cmd_enumerate, 1, "<dirToEnumerate>" },
- { "getlasterror", cmd_getlasterror, 0, NULL },
- { "getdirsep", cmd_getdirsep, 0, NULL },
- { "getcdromdirs", cmd_getcdromdirs, 0, NULL },
- { "getsearchpath", cmd_getsearchpath, 0, NULL },
- { "getbasedir", cmd_getbasedir, 0, NULL },
- { "getuserdir", cmd_getuserdir, 0, NULL },
- { "getwritedir", cmd_getwritedir, 0, NULL },
- { "setwritedir", cmd_setwritedir, 1, "<newWriteDir>" },
- { "permitsymlinks", cmd_permitsyms, 1, "<1or0>" },
- { "setsaneconfig", cmd_setsaneconfig, 5, "<org> <appName> <arcExt> <includeCdRoms> <archivesFirst>" },
- { "mkdir", cmd_mkdir, 1, "<dirToMk>" },
- { "delete", cmd_delete, 1, "<dirToDelete>" },
- { "getrealdir", cmd_getrealdir, 1, "<fileToFind>" },
- { "exists", cmd_exists, 1, "<fileToCheck>" },
- { "isdir", cmd_isdir, 1, "<fileToCheck>" },
- { "issymlink", cmd_issymlink, 1, "<fileToCheck>" },
- { "cat", cmd_cat, 1, "<fileToCat>" },
- { "filelength", cmd_filelength, 1, "<fileToCheck>" },
- { "append", cmd_append, 1, "<fileToAppend>" },
- { "write", cmd_write, 1, "<fileToCreateOrTrash>" },
- { "getlastmodtime", cmd_getlastmodtime, 1, "<fileToExamine>" },
- { "setbuffer", cmd_setbuffer, 1, "<bufferSize>" },
- { "stressbuffer", cmd_stressbuffer, 1, "<bufferSize>" },
- { NULL, NULL, -1, NULL }
-};
-
-
-static void output_usage(const char *intro, const command_info *cmdinfo)
-{
- if (cmdinfo->argcount == 0)
- printf("%s \"%s\" (no arguments)\n", intro, cmdinfo->cmd);
- else
- printf("%s \"%s %s\"\n", intro, cmdinfo->cmd, cmdinfo->usage);
-} /* output_usage */
-
-
-static int cmd_help(char *args)
-{
- const command_info *i;
-
- printf("Commands:\n");
- for (i = commands; i->cmd != NULL; i++)
- output_usage(" -", i);
-
- return(1);
-} /* output_cmd_help */
-
-
-static void trim_command(const char *orig, char *copy)
-{
- const char *i;
- char *writeptr = copy;
- int spacecount = 0;
- int have_first = 0;
-
- for (i = orig; *i != '\0'; i++)
- {
- if (*i == ' ')
- {
- if ((*(i + 1) != ' ') && (*(i + 1) != '\0'))
- {
- if ((have_first) && (!spacecount))
- {
- spacecount++;
- *writeptr = ' ';
- writeptr++;
- } /* if */
- } /* if */
- } /* if */
- else
- {
- have_first = 1;
- spacecount = 0;
- *writeptr = *i;
- writeptr++;
- } /* else */
- } /* for */
-
- *writeptr = '\0';
-
- /*
- printf("\n command is [%s].\n", copy);
- */
-} /* trim_command */
-
-
-static int process_command(char *complete_cmd)
-{
- const command_info *i;
- char *cmd_copy;
- char *args;
- int rc = 1;
-
- if (complete_cmd == NULL) /* can happen if user hits CTRL-D, etc. */
- {
- printf("\n");
- return(0);
- } /* if */
-
- cmd_copy = (char *) malloc(strlen(complete_cmd) + 1);
- if (cmd_copy == NULL)
- {
- printf("\n\n\nOUT OF MEMORY!\n\n\n");
- return(0);
- } /* if */
-
- trim_command(complete_cmd, cmd_copy);
- args = strchr(cmd_copy, ' ');
- if (args != NULL)
- {
- *args = '\0';
- args++;
- } /* else */
-
- if (cmd_copy[0] != '\0')
- {
- for (i = commands; i->cmd != NULL; i++)
- {
- if (strcmp(i->cmd, cmd_copy) == 0)
- {
- if ((i->argcount >= 0) && (count_args(args) != i->argcount))
- output_usage("usage:", i);
- else
- rc = i->func(args);
- break;
- } /* if */
- } /* for */
-
- if (i->cmd == NULL)
- printf("Unknown command. Enter \"help\" for instructions.\n");
-
-#if (defined PHYSFS_HAVE_READLINE)
- add_history(complete_cmd);
- if (history_file)
- {
- fprintf(history_file, "%s\n", complete_cmd);
- fflush(history_file);
- } /* if */
-#endif
-
- } /* if */
-
- free(cmd_copy);
- return(rc);
-} /* process_command */
-
-
-static void open_history_file(void)
-{
-#if (defined PHYSFS_HAVE_READLINE)
-#if 0
- const char *envr = getenv("TESTPHYSFS_HISTORY");
- if (!envr)
- return;
-#else
- char envr[256];
- strcpy(envr, PHYSFS_getUserDir());
- strcat(envr, ".testphys_history");
-#endif
-
- if (access(envr, F_OK) == 0)
- {
- char buf[512];
- FILE *f = fopen(envr, "r");
- if (!f)
- {
- printf("\n\n"
- "Could not open history file [%s] for reading!\n"
- " Will not have past history available.\n\n",
- envr);
- return;
- } /* if */
-
- do
- {
- fgets(buf, sizeof (buf), f);
- if (buf[strlen(buf) - 1] == '\n')
- buf[strlen(buf) - 1] = '\0';
- add_history(buf);
- } while (!feof(f));
-
- fclose(f);
- } /* if */
-
- history_file = fopen(envr, "ab");
- if (!history_file)
- {
- printf("\n\n"
- "Could not open history file [%s] for appending!\n"
- " Will not be able to record this session's history.\n\n",
- envr);
- } /* if */
-#endif
-} /* open_history_file */
-
-
-int main(int argc, char **argv)
-{
- char *buf = NULL;
- int rc = 0;
-
-#if (defined __MWERKS__)
- extern tSIOUXSettings SIOUXSettings;
- SIOUXSettings.asktosaveonclose = 0;
- SIOUXSettings.autocloseonquit = 1;
- SIOUXSettings.rows = 40;
- SIOUXSettings.columns = 120;
-#endif
-
- printf("\n");
-
- if (!PHYSFS_init(argv[0]))
- {
- printf("PHYSFS_init() failed!\n reason: %s.\n", PHYSFS_getLastError());
- return(1);
- } /* if */
-
- output_versions();
- output_archivers();
-
- open_history_file();
-
- printf("Enter commands. Enter \"help\" for instructions.\n");
-
- do
- {
-#if (defined PHYSFS_HAVE_READLINE)
- buf = readline("> ");
-#else
- int i;
- buf = (char *) malloc(512);
- memset(buf, '\0', 512);
- printf("> ");
- for (i = 0; i < 511; i++)
- {
- int ch = fgetc(stdin);
- if (ch == EOF)
- {
- strcpy(buf, "quit");
- break;
- } /* if */
- else if ((ch == '\n') || (ch == '\r'))
- {
- buf[i] = '\0';
- break;
- } /* else if */
- else if (ch == '\b')
- {
- if (i > 0)
- i--;
- } /* else if */
- else
- {
- buf[i] = (char) ch;
- } /* else */
- } /* for */
-#endif
-
- rc = process_command(buf);
- if (buf != NULL)
- free(buf);
- } while (rc);
-
- if (!PHYSFS_deinit())
- printf("PHYSFS_deinit() failed!\n reason: %s.\n", PHYSFS_getLastError());
-
- if (history_file)
- fclose(history_file);
-
-/*
- printf("\n\ntest_physfs written by ryan c. gordon.\n");
- printf(" it makes you shoot teh railgun bettar.\n");
-*/
-
- return(0);
-} /* main */
-
-/* end of test_physfs.c ... */
-
+++ /dev/null
-/**
- * Test program for PhysicsFS, using wxWidgets. May only work on Unix.
- *
- * Please see the file LICENSE.txt in the source's root directory.
- *
- * This file written by Ryan C. Gordon.
- */
-
-#if ( (defined(__MACH__)) && (defined(__APPLE__)) )
-#define PLATFORM_MACOSX 1
-#include <Carbon/Carbon.h>
-#endif
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-#include <errno.h>
-
-#include <wx/wx.h>
-#include <wx/treectrl.h>
-
-#include "physfs.h"
-
-#define TEST_VER_MAJOR 1
-#define TEST_VER_MINOR 1
-#define TEST_VER_PATCH 1
-
-//static PHYSFS_uint32 do_buffer_size = 0;
-
-enum WxTestPhysfsMenuCommands
-{
- // start with standard menu items, since using the wxIDs will map them
- // to sane things in the platform's UI (gnome icons in GTK+, moves the
- // about and quit items to the Apple menu on Mac OS X, etc).
- MENUCMD_About = wxID_ABOUT,
- MENUCMD_Quit = wxID_EXIT,
-
- // non-standard menu items go here.
- MENUCMD_Init = wxID_HIGHEST,
- MENUCMD_Deinit,
- MENUCMD_AddArchive,
- MENUCMD_Mount,
- MENUCMD_Remove,
- MENUCMD_GetCDs,
- MENUCMD_SetWriteDir,
- MENUCMD_PermitSymLinks,
- MENUCMD_SetSaneConfig,
- MENUCMD_MkDir,
- MENUCMD_Delete,
- MENUCMD_Cat,
- MENUCMD_SetBuffer,
- MENUCMD_StressBuffer,
- MENUCMD_Append,
- MENUCMD_Write,
- MENUCMD_GetLastError,
-
-/*
- { "getdirsep", cmd_getdirsep, 0, NULL },
- { "getsearchpath", cmd_getsearchpath, 0, NULL },
- { "getbasedir", cmd_getbasedir, 0, NULL },
- { "getuserdir", cmd_getuserdir, 0, NULL },
- { "getwritedir", cmd_getwritedir, 0, NULL },
- { "getrealdir", cmd_getrealdir, 1, "<fileToFind>" },
- { "exists", cmd_exists, 1, "<fileToCheck>" },
- { "isdir", cmd_isdir, 1, "<fileToCheck>" },
- { "issymlink", cmd_issymlink, 1, "<fileToCheck>" },
- { "filelength", cmd_filelength, 1, "<fileToCheck>" },
- { "getlastmodtime", cmd_getlastmodtime, 1, "<fileToExamine>" },
-*/
-};
-
-
-class WxTestPhysfsFrame : public wxFrame
-{
-public:
- WxTestPhysfsFrame(const wxChar *argv0);
-
- void rebuildTree();
-
- void onMenuInit(wxCommandEvent &evt);
- void onMenuDeinit(wxCommandEvent &evt);
- void onMenuAddArchive(wxCommandEvent &evt);
- void onMenuGetCDs(wxCommandEvent &evt);
- void onMenuPermitSymLinks(wxCommandEvent &evt);
-
-private:
- wxTreeCtrl *fileTree;
- wxTreeItemId stateItem;
- wxTreeItemId fsItem;
-
- int err(int success);
- void fillFileSystemTree(const char *path, const wxTreeItemId &item);
- void doInit(const char *argv0);
- void doDeinit();
-
- DECLARE_EVENT_TABLE()
-};
-
-BEGIN_EVENT_TABLE(WxTestPhysfsFrame, wxFrame)
- EVT_MENU(MENUCMD_Init, WxTestPhysfsFrame::onMenuInit)
- EVT_MENU(MENUCMD_Deinit, WxTestPhysfsFrame::onMenuDeinit)
- EVT_MENU(MENUCMD_AddArchive, WxTestPhysfsFrame::onMenuAddArchive)
- EVT_MENU(MENUCMD_GetCDs, WxTestPhysfsFrame::onMenuGetCDs)
- EVT_MENU(MENUCMD_PermitSymLinks, WxTestPhysfsFrame::onMenuPermitSymLinks)
-END_EVENT_TABLE()
-
-
-
-// This is the the Application itself.
-class WxTestPhysfsApp : public wxApp
-{
-public:
- WxTestPhysfsApp() : mainWindow(NULL) { /* no-op. */ }
- virtual bool OnInit();
-
-private:
- WxTestPhysfsFrame *mainWindow;
-};
-
-DECLARE_APP(WxTestPhysfsApp)
-
-
-static inline char *newstr(const char *str)
-{
- char *retval = NULL;
- if (str != NULL)
- {
- retval = new char[strlen(str) + 1];
- strcpy(retval, str);
- } // if
- return retval;
-} // newstr
-
-static char *newutf8(const wxString &wxstr)
-{
- #if wxUSE_UNICODE
- size_t len = wxstr.Len() + 1;
- char *utf8text = new char[len * 6];
- wxConvUTF8.WC2MB(utf8text, wxstr, len);
- return utf8text;
- #else
- return newstr(wxstr);
- #endif
-} // newutf8
-
-
-WxTestPhysfsFrame::WxTestPhysfsFrame(const wxChar *argv0)
- : wxFrame(NULL, -1, wxT("WxTestPhysfs"))
-{
- this->CreateStatusBar();
-
- wxMenuBar *menuBar = new wxMenuBar;
-
- wxMenu *stuffMenu = new wxMenu;
- stuffMenu->Append(MENUCMD_Init, wxT("&Init"));
- stuffMenu->Append(MENUCMD_Deinit, wxT("&Deinit"));
- stuffMenu->Append(MENUCMD_AddArchive, wxT("&Add Archive"));
- stuffMenu->Append(MENUCMD_Mount, wxT("&Mount Archive"));
- stuffMenu->Append(MENUCMD_Remove, wxT("&Remove Archive"));
- stuffMenu->Append(MENUCMD_GetCDs, wxT("&Get CD-ROM drives"));
- stuffMenu->Append(MENUCMD_SetWriteDir, wxT("&Set Write Dir"));
- stuffMenu->Append(MENUCMD_SetSaneConfig, wxT("Set Sane &Config"));
- stuffMenu->Append(MENUCMD_MkDir, wxT("M&kDir"));
- stuffMenu->Append(MENUCMD_Delete, wxT("D&elete"));
- stuffMenu->Append(MENUCMD_Cat, wxT("&Cat"));
- stuffMenu->Append(MENUCMD_SetBuffer, wxT("Set &Buffer"));
- stuffMenu->Append(MENUCMD_StressBuffer, wxT("Stress &Test Buffer"));
- stuffMenu->Append(MENUCMD_Append, wxT("&Append"));
- stuffMenu->Append(MENUCMD_Write, wxT("&Write"));
- stuffMenu->Append(MENUCMD_Write, wxT("&Update getLastError"));
- stuffMenu->AppendCheckItem(MENUCMD_PermitSymLinks, wxT("&Permit symlinks"));
- menuBar->Append(stuffMenu, wxT("&Stuff"));
-
- //wxMenu *helpMenu = new wxMenu;
- //helpMenu->Append(MENUCMD_About, wxT("&About\tF1"));
- //menuBar->Append(helpMenu, wxT("&Help"));
-
- this->SetMenuBar(menuBar);
-
- this->fileTree = new wxTreeCtrl(this, -1);
-
- // The sizer just makes sure that fileTree owns whole client area.
- wxBoxSizer *sizer = new wxBoxSizer(wxVERTICAL);
- sizer->Add(this->fileTree, 1, wxALL | wxEXPAND | wxALIGN_CENTRE);
- sizer->SetItemMinSize(this->fileTree, 1, 1);
- this->SetSizer(sizer);
-
- char *utf8argv0 = newutf8(wxString(argv0));
- this->doInit(utf8argv0);
- delete[] utf8argv0;
-} // WxTestPhysfsFrame::WxTestPhysfsFrame
-
-
-int WxTestPhysfsFrame::err(int success)
-{
- if (success)
- this->SetStatusText(wxT(""));
- else
- this->SetStatusText(wxString(PHYSFS_getLastError(), wxConvUTF8));
- return success;
-} // WxTestPhysfsFrame::err
-
-
-void WxTestPhysfsFrame::fillFileSystemTree(const char *path,
- const wxTreeItemId &item)
-{
- char **rc = PHYSFS_enumerateFiles(path);
- char **i;
- wxTreeItemId id;
-
- if (rc == NULL)
- {
- const wxString quote(wxT("'"));
- wxString str(wxT("Enumeration error: "));
- str << quote << wxString(PHYSFS_getLastError(), wxConvUTF8) << quote;
- id = this->fileTree->AppendItem(item, str);
- this->fileTree->SetItemTextColour(id, wxColour(255, 0, 0));
- } // if
- else
- {
- for (i = rc; *i != NULL; i++)
- {
- id = this->fileTree->AppendItem(item, wxString(*i, wxConvUTF8));
- const int len = strlen(path) + strlen(*i) + 2;
- char *fname = new char[len];
- const char *origdir = path;
- if (strcmp(origdir, "/") == 0)
- origdir = "";
- snprintf(fname, len, "%s/%s", origdir, *i);
-
- if (PHYSFS_isDirectory(fname))
- {
- this->fileTree->SetItemTextColour(id, wxColour(0, 0, 255));
- this->fillFileSystemTree(fname, id);
- } // if
-
- else if (PHYSFS_isSymbolicLink(fname))
- {
- this->fileTree->SetItemTextColour(id, wxColour(0, 255, 0));
- } // else if
-
- else // ...file.
- {
- } // else
-
- delete[] fname;
- } // for
-
- PHYSFS_freeList(rc);
- } // else
-} // fillFileSystemTree
-
-
-void WxTestPhysfsFrame::rebuildTree()
-{
- const wxString dot(wxT("."));
- const wxString quote(wxT("'"));
- wxTreeItemId item;
- wxString str;
- const char *cstr = NULL;
- const bool wasInit = PHYSFS_isInit() ? true : false;
-
- this->fileTree->DeleteAllItems();
- wxTreeItemId root = this->fileTree->AddRoot(wxT("PhysicsFS"));
- this->stateItem = this->fileTree->AppendItem(root, wxT("Library state"));
-
- str = wxT("Initialized: ");
- str << ((wasInit) ? wxT("true") : wxT("false"));
- this->fileTree->AppendItem(this->stateItem, str);
-
- this->fileTree->Expand(this->stateItem);
- this->fileTree->Expand(root);
-
- // Fill in version information...
-
- PHYSFS_Version ver;
- item = this->stateItem;
- str = wxT("wxtest_physfs version: ");
- str << TEST_VER_MAJOR << dot << TEST_VER_MINOR << dot << TEST_VER_PATCH;
- this->fileTree->AppendItem(item, str);
- PHYSFS_VERSION(&ver);
- str = wxT("Compiled against PhysicsFS version: ");
- str << (int) ver.major << dot << (int) ver.minor << dot << ver.patch;
- this->fileTree->AppendItem(item, str);
- PHYSFS_getLinkedVersion(&ver);
- str = wxT("Linked against PhysicsFS version: ");
- str << (int) ver.major << dot << (int) ver.minor << dot << ver.patch;
- this->fileTree->AppendItem(item, str);
-
- if (!wasInit)
- return; // nothing else to do before initialization...
-
- str = wxT("Symbolic links permitted: ");
- str << ((PHYSFS_symbolicLinksPermitted()) ? wxT("true") : wxT("false"));
- this->fileTree->AppendItem(this->stateItem, str);
-
- str = wxT("Native directory separator: ");
- str << quote << wxString(PHYSFS_getDirSeparator(), wxConvUTF8) << quote;
- this->fileTree->AppendItem(this->stateItem, str);
-
- // Fill in supported archives...
-
- item = this->fileTree->AppendItem(this->stateItem, wxT("Archivers"));
- const PHYSFS_ArchiveInfo **arcs = PHYSFS_supportedArchiveTypes();
- if (*arcs == NULL)
- this->fileTree->AppendItem(item, wxT("(none)"));
- else
- {
- const PHYSFS_ArchiveInfo **i;
- for (i = arcs; *i != NULL; i++)
- {
- const wxString ext((*i)->extension, wxConvUTF8);
- const wxString desc((*i)->description, wxConvUTF8);
- const wxString auth((*i)->author, wxConvUTF8);
- const wxString url((*i)->url, wxConvUTF8);
- wxTreeItemId arcitem = this->fileTree->AppendItem(item, ext);
- this->fileTree->AppendItem(arcitem, desc);
- this->fileTree->AppendItem(arcitem, auth);
- this->fileTree->AppendItem(arcitem, url);
- } // for
- } // else
-
-
- // Fill in the standard paths...
-
- item = this->fileTree->AppendItem(this->stateItem, wxT("Paths"));
- str = wxT("Base directory: ");
- str << quote << wxString(PHYSFS_getBaseDir(), wxConvUTF8) << quote;
- this->fileTree->AppendItem(item, str);
- str = wxT("User directory: ");
- str << quote << wxString(PHYSFS_getUserDir(), wxConvUTF8) << quote;
- this->fileTree->AppendItem(item, str);
- str = wxT("Write directory: ");
- if ((cstr = PHYSFS_getWriteDir()) == NULL)
- str << wxT("(NULL)");
- else
- str << quote << wxString(cstr ? cstr : "(NULL)", wxConvUTF8) << quote;
- this->fileTree->AppendItem(item, str);
- //str = wxT("Preference directory: ");
- //str << wxString(PHYSFS_getUserDir(), wxConvUTF8);
- //this->fileTree->AppendItem(item, str);
-
- // Fill in the CD-ROMs...
-
- item = this->fileTree->AppendItem(this->stateItem, wxT("CD-ROMs"));
- char **cds = PHYSFS_getCdRomDirs();
- if (cds == NULL)
- {
- str = wxT("Error: ");
- str << quote << wxString(PHYSFS_getLastError(), wxConvUTF8) << quote;
- wxTreeItemId id = this->fileTree->AppendItem(item, str);
- this->fileTree->SetItemTextColour(id, wxColour(255, 0, 0));
- } // if
- else
- {
- if (*cds == NULL)
- this->fileTree->AppendItem(item, wxT("(none)"));
- else
- {
- char **i;
- for (i = cds; *i != NULL; i++)
- this->fileTree->AppendItem(item, wxString(*i, wxConvUTF8));
- } // else
- PHYSFS_freeList(cds);
- } // else
-
- // Fill in search path...
-
- item = this->fileTree->AppendItem(this->stateItem, wxT("Search path"));
- char **sp = PHYSFS_getSearchPath();
- if (sp == NULL)
- {
- str = wxT("Error: ");
- str << quote << wxString(PHYSFS_getLastError(), wxConvUTF8) << quote;
- wxTreeItemId id = this->fileTree->AppendItem(item, str);
- this->fileTree->SetItemTextColour(id, wxColour(255, 0, 0));
- } // if
- else
- {
- if (*sp == NULL)
- this->fileTree->AppendItem(item, wxT("(none)"));
- else
- {
- char **i;
- for (i = sp; *i != NULL; i++)
- this->fileTree->AppendItem(item, wxString(*i, wxConvUTF8));
- } // else
- PHYSFS_freeList(sp);
- } // else
-
- // Now fill in the filesystem...
-
- this->fsItem = this->fileTree->AppendItem(root, wxT("Filesystem"));
- this->fillFileSystemTree("/", this->fsItem);
- this->fileTree->Expand(this->fsItem);
-} // WxTestPhysfsFrame::rebuildTree
-
-
-void WxTestPhysfsFrame::doInit(const char *argv0)
-{
- if (!this->err(PHYSFS_init(argv0)))
- ::wxMessageBox(wxT("PHYSFS_init() failed!"), wxT("wxTestPhysfs"));
- this->rebuildTree();
-} // WxTestPhysfsFrame::doInit
-
-
-void WxTestPhysfsFrame::doDeinit()
-{
- if (!this->err(PHYSFS_deinit()))
- ::wxMessageBox(wxT("PHYSFS_deinit() failed!"), wxT("wxTestPhysfs"));
- this->rebuildTree();
-} // WxTestPhysfsFrame::doDeinit
-
-
-void WxTestPhysfsFrame::onMenuInit(wxCommandEvent &evt)
-{
- wxString argv0(wxGetApp().argv[0] == NULL ? wxT("") : wxGetApp().argv[0]);
- wxString str(wxGetTextFromUser(wxT("PHYSFS_init"),
- wxT("argv[0]? (cancel for NULL)"), argv0));
- char *cstr = str.IsEmpty() ? NULL : newutf8(str);
- this->doInit(cstr);
- delete[] cstr;
-} // WxTestPhysfsFrame::onMenuInit
-
-
-void WxTestPhysfsFrame::onMenuDeinit(wxCommandEvent &evt)
-{
- this->doDeinit();
-} // WxTestPhysfsFrame::onMenuDeinit
-
-
-void WxTestPhysfsFrame::onMenuAddArchive(wxCommandEvent &evt)
-{
- wxString arc = wxFileSelector(wxT("Choose archive to add"));
- if (!arc.IsEmpty())
- {
- char *cstr = newutf8(arc);
- // !!! FIXME: add to start/end?
- if (!this->err(PHYSFS_addToSearchPath(cstr, 1)))
- ::wxMessageBox(wxT("PHYSFS_addToSearchPath() failed!"), wxT("wxTestPhysfs"));
- delete[] cstr;
- this->rebuildTree();
- } // if
-} // WxTestPhysfsFrame::onMenuAddArchive
-
-
-void WxTestPhysfsFrame::onMenuGetCDs(wxCommandEvent &evt)
-{
- this->rebuildTree(); // This will call PHYSFS_getCdRomDirs()...
-} // WxTestPhysfsFrame::onMenuGetCDs
-
-
-void WxTestPhysfsFrame::onMenuPermitSymLinks(wxCommandEvent &evt)
-{
- PHYSFS_permitSymbolicLinks(evt.IsChecked() ? 1 : 0);
- this->rebuildTree();
-} // WxTestPhysfsFrame::onMenuPermitSymLinks
-
-
-
-IMPLEMENT_APP(WxTestPhysfsApp)
-
-bool WxTestPhysfsApp::OnInit()
-{
- #if PLATFORM_MACOSX
- // This lets a stdio app become a GUI app. Otherwise, you won't get
- // GUI events from the system and other things will fail to work.
- // Putting the app in an application bundle does the same thing.
- // TransformProcessType() is a 10.3+ API. SetFrontProcess() is 10.0+.
- if (TransformProcessType != NULL) // check it as a weak symbol.
- {
- ProcessSerialNumber psn = { 0, kCurrentProcess };
- TransformProcessType(&psn, kProcessTransformToForegroundApplication);
- SetFrontProcess(&psn);
- } // if
- #endif
-
- this->mainWindow = new WxTestPhysfsFrame(this->argv[0]);
- this->mainWindow->Show(true);
- SetTopWindow(this->mainWindow);
- return true;
-} // WxTestPhysfsApp::OnInit
-
-// end of wxtest_physfs.cpp ...
-
+++ /dev/null
-/* adler32.c -- compute the Adler-32 checksum of a data stream
- * Copyright (C) 1995-2004 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* @(#) $Id$ */
-
-#define ZLIB_INTERNAL
-#include "zlib.h"
-
-#define BASE 65521UL /* largest prime smaller than 65536 */
-#define NMAX 5552
-/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
-
-#define DO1(buf,i) {adler += (buf)[i]; sum2 += adler;}
-#define DO2(buf,i) DO1(buf,i); DO1(buf,i+1);
-#define DO4(buf,i) DO2(buf,i); DO2(buf,i+2);
-#define DO8(buf,i) DO4(buf,i); DO4(buf,i+4);
-#define DO16(buf) DO8(buf,0); DO8(buf,8);
-
-/* use NO_DIVIDE if your processor does not do division in hardware */
-#ifdef NO_DIVIDE
-# define MOD(a) \
- do { \
- if (a >= (BASE << 16)) a -= (BASE << 16); \
- if (a >= (BASE << 15)) a -= (BASE << 15); \
- if (a >= (BASE << 14)) a -= (BASE << 14); \
- if (a >= (BASE << 13)) a -= (BASE << 13); \
- if (a >= (BASE << 12)) a -= (BASE << 12); \
- if (a >= (BASE << 11)) a -= (BASE << 11); \
- if (a >= (BASE << 10)) a -= (BASE << 10); \
- if (a >= (BASE << 9)) a -= (BASE << 9); \
- if (a >= (BASE << 8)) a -= (BASE << 8); \
- if (a >= (BASE << 7)) a -= (BASE << 7); \
- if (a >= (BASE << 6)) a -= (BASE << 6); \
- if (a >= (BASE << 5)) a -= (BASE << 5); \
- if (a >= (BASE << 4)) a -= (BASE << 4); \
- if (a >= (BASE << 3)) a -= (BASE << 3); \
- if (a >= (BASE << 2)) a -= (BASE << 2); \
- if (a >= (BASE << 1)) a -= (BASE << 1); \
- if (a >= BASE) a -= BASE; \
- } while (0)
-# define MOD4(a) \
- do { \
- if (a >= (BASE << 4)) a -= (BASE << 4); \
- if (a >= (BASE << 3)) a -= (BASE << 3); \
- if (a >= (BASE << 2)) a -= (BASE << 2); \
- if (a >= (BASE << 1)) a -= (BASE << 1); \
- if (a >= BASE) a -= BASE; \
- } while (0)
-#else
-# define MOD(a) a %= BASE
-# define MOD4(a) a %= BASE
-#endif
-
-/* ========================================================================= */
-uLong ZEXPORT adler32(adler, buf, len)
- uLong adler;
- const Bytef *buf;
- uInt len;
-{
- unsigned long sum2;
- unsigned n;
-
- /* split Adler-32 into component sums */
- sum2 = (adler >> 16) & 0xffff;
- adler &= 0xffff;
-
- /* in case user likes doing a byte at a time, keep it fast */
- if (len == 1) {
- adler += buf[0];
- if (adler >= BASE)
- adler -= BASE;
- sum2 += adler;
- if (sum2 >= BASE)
- sum2 -= BASE;
- return adler | (sum2 << 16);
- }
-
- /* initial Adler-32 value (deferred check for len == 1 speed) */
- if (buf == Z_NULL)
- return 1L;
-
- /* in case short lengths are provided, keep it somewhat fast */
- if (len < 16) {
- while (len--) {
- adler += *buf++;
- sum2 += adler;
- }
- if (adler >= BASE)
- adler -= BASE;
- MOD4(sum2); /* only added so many BASE's */
- return adler | (sum2 << 16);
- }
-
- /* do length NMAX blocks -- requires just one modulo operation */
- while (len >= NMAX) {
- len -= NMAX;
- n = NMAX / 16; /* NMAX is divisible by 16 */
- do {
- DO16(buf); /* 16 sums unrolled */
- buf += 16;
- } while (--n);
- MOD(adler);
- MOD(sum2);
- }
-
- /* do remaining bytes (less than NMAX, still just one modulo) */
- if (len) { /* avoid modulos if none remaining */
- while (len >= 16) {
- len -= 16;
- DO16(buf);
- buf += 16;
- }
- while (len--) {
- adler += *buf++;
- sum2 += adler;
- }
- MOD(adler);
- MOD(sum2);
- }
-
- /* return recombined sums */
- return adler | (sum2 << 16);
-}
-
-/* ========================================================================= */
-uLong ZEXPORT adler32_combine(adler1, adler2, len2)
- uLong adler1;
- uLong adler2;
- z_off_t len2;
-{
- unsigned long sum1;
- unsigned long sum2;
- unsigned rem;
-
- /* the derivation of this formula is left as an exercise for the reader */
- rem = (unsigned)(len2 % BASE);
- sum1 = adler1 & 0xffff;
- sum2 = rem * sum1;
- MOD(sum2);
- sum1 += (adler2 & 0xffff) + BASE - 1;
- sum2 += ((adler1 >> 16) & 0xffff) + ((adler2 >> 16) & 0xffff) + BASE - rem;
- if (sum1 > BASE) sum1 -= BASE;
- if (sum1 > BASE) sum1 -= BASE;
- if (sum2 > (BASE << 1)) sum2 -= (BASE << 1);
- if (sum2 > BASE) sum2 -= BASE;
- return sum1 | (sum2 << 16);
-}
+++ /dev/null
-/* compress.c -- compress a memory buffer
- * Copyright (C) 1995-2003 Jean-loup Gailly.
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* @(#) $Id$ */
-
-#define ZLIB_INTERNAL
-#include "zlib.h"
-
-/* ===========================================================================
- Compresses the source buffer into the destination buffer. The level
- parameter has the same meaning as in deflateInit. sourceLen is the byte
- length of the source buffer. Upon entry, destLen is the total size of the
- destination buffer, which must be at least 0.1% larger than sourceLen plus
- 12 bytes. Upon exit, destLen is the actual size of the compressed buffer.
-
- compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
- memory, Z_BUF_ERROR if there was not enough room in the output buffer,
- Z_STREAM_ERROR if the level parameter is invalid.
-*/
-int ZEXPORT compress2 (dest, destLen, source, sourceLen, level)
- Bytef *dest;
- uLongf *destLen;
- const Bytef *source;
- uLong sourceLen;
- int level;
-{
- z_stream stream;
- int err;
-
- stream.next_in = (Bytef*)source;
- stream.avail_in = (uInt)sourceLen;
-#ifdef MAXSEG_64K
- /* Check for source > 64K on 16-bit machine: */
- if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR;
-#endif
- stream.next_out = dest;
- stream.avail_out = (uInt)*destLen;
- if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR;
-
- stream.zalloc = (alloc_func)0;
- stream.zfree = (free_func)0;
- stream.opaque = (voidpf)0;
-
- err = deflateInit(&stream, level);
- if (err != Z_OK) return err;
-
- err = deflate(&stream, Z_FINISH);
- if (err != Z_STREAM_END) {
- deflateEnd(&stream);
- return err == Z_OK ? Z_BUF_ERROR : err;
- }
- *destLen = stream.total_out;
-
- err = deflateEnd(&stream);
- return err;
-}
-
-/* ===========================================================================
- */
-int ZEXPORT compress (dest, destLen, source, sourceLen)
- Bytef *dest;
- uLongf *destLen;
- const Bytef *source;
- uLong sourceLen;
-{
- return compress2(dest, destLen, source, sourceLen, Z_DEFAULT_COMPRESSION);
-}
-
-/* ===========================================================================
- If the default memLevel or windowBits for deflateInit() is changed, then
- this function needs to be updated.
- */
-uLong ZEXPORT compressBound (sourceLen)
- uLong sourceLen;
-{
- return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) + 11;
-}
+++ /dev/null
-/* crc32.c -- compute the CRC-32 of a data stream
- * Copyright (C) 1995-2005 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- *
- * Thanks to Rodney Brown <rbrown64@csc.com.au> for his contribution of faster
- * CRC methods: exclusive-oring 32 bits of data at a time, and pre-computing
- * tables for updating the shift register in one step with three exclusive-ors
- * instead of four steps with four exclusive-ors. This results in about a
- * factor of two increase in speed on a Power PC G4 (PPC7455) using gcc -O3.
- */
-
-/* @(#) $Id$ */
-
-/*
- Note on the use of DYNAMIC_CRC_TABLE: there is no mutex or semaphore
- protection on the static variables used to control the first-use generation
- of the crc tables. Therefore, if you #define DYNAMIC_CRC_TABLE, you should
- first call get_crc_table() to initialize the tables before allowing more than
- one thread to use crc32().
- */
-
-#ifdef MAKECRCH
-# include <stdio.h>
-# ifndef DYNAMIC_CRC_TABLE
-# define DYNAMIC_CRC_TABLE
-# endif /* !DYNAMIC_CRC_TABLE */
-#endif /* MAKECRCH */
-
-#include "zutil.h" /* for STDC and FAR definitions */
-
-#define local static
-
-/* Find a four-byte integer type for crc32_little() and crc32_big(). */
-#ifndef NOBYFOUR
-# ifdef STDC /* need ANSI C limits.h to determine sizes */
-# include <limits.h>
-# define BYFOUR
-# if (UINT_MAX == 0xffffffffUL)
- typedef unsigned int u4;
-# else
-# if (ULONG_MAX == 0xffffffffUL)
- typedef unsigned long u4;
-# else
-# if (USHRT_MAX == 0xffffffffUL)
- typedef unsigned short u4;
-# else
-# undef BYFOUR /* can't find a four-byte integer type! */
-# endif
-# endif
-# endif
-# endif /* STDC */
-#endif /* !NOBYFOUR */
-
-/* Definitions for doing the crc four data bytes at a time. */
-#ifdef BYFOUR
-# define REV(w) (((w)>>24)+(((w)>>8)&0xff00)+ \
- (((w)&0xff00)<<8)+(((w)&0xff)<<24))
- local unsigned long crc32_little OF((unsigned long,
- const unsigned char FAR *, unsigned));
- local unsigned long crc32_big OF((unsigned long,
- const unsigned char FAR *, unsigned));
-# define TBLS 8
-#else
-# define TBLS 1
-#endif /* BYFOUR */
-
-/* Local functions for crc concatenation */
-local unsigned long gf2_matrix_times OF((unsigned long *mat,
- unsigned long vec));
-local void gf2_matrix_square OF((unsigned long *square, unsigned long *mat));
-
-#ifdef DYNAMIC_CRC_TABLE
-
-local volatile int crc_table_empty = 1;
-local unsigned long FAR crc_table[TBLS][256];
-local void make_crc_table OF((void));
-#ifdef MAKECRCH
- local void write_table OF((FILE *, const unsigned long FAR *));
-#endif /* MAKECRCH */
-/*
- Generate tables for a byte-wise 32-bit CRC calculation on the polynomial:
- x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1.
-
- Polynomials over GF(2) are represented in binary, one bit per coefficient,
- with the lowest powers in the most significant bit. Then adding polynomials
- is just exclusive-or, and multiplying a polynomial by x is a right shift by
- one. If we call the above polynomial p, and represent a byte as the
- polynomial q, also with the lowest power in the most significant bit (so the
- byte 0xb1 is the polynomial x^7+x^3+x+1), then the CRC is (q*x^32) mod p,
- where a mod b means the remainder after dividing a by b.
-
- This calculation is done using the shift-register method of multiplying and
- taking the remainder. The register is initialized to zero, and for each
- incoming bit, x^32 is added mod p to the register if the bit is a one (where
- x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by
- x (which is shifting right by one and adding x^32 mod p if the bit shifted
- out is a one). We start with the highest power (least significant bit) of
- q and repeat for all eight bits of q.
-
- The first table is simply the CRC of all possible eight bit values. This is
- all the information needed to generate CRCs on data a byte at a time for all
- combinations of CRC register values and incoming bytes. The remaining tables
- allow for word-at-a-time CRC calculation for both big-endian and little-
- endian machines, where a word is four bytes.
-*/
-local void make_crc_table()
-{
- unsigned long c;
- int n, k;
- unsigned long poly; /* polynomial exclusive-or pattern */
- /* terms of polynomial defining this crc (except x^32): */
- static volatile int first = 1; /* flag to limit concurrent making */
- static const unsigned char p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26};
-
- /* See if another task is already doing this (not thread-safe, but better
- than nothing -- significantly reduces duration of vulnerability in
- case the advice about DYNAMIC_CRC_TABLE is ignored) */
- if (first) {
- first = 0;
-
- /* make exclusive-or pattern from polynomial (0xedb88320UL) */
- poly = 0UL;
- for (n = 0; n < sizeof(p)/sizeof(unsigned char); n++)
- poly |= 1UL << (31 - p[n]);
-
- /* generate a crc for every 8-bit value */
- for (n = 0; n < 256; n++) {
- c = (unsigned long)n;
- for (k = 0; k < 8; k++)
- c = c & 1 ? poly ^ (c >> 1) : c >> 1;
- crc_table[0][n] = c;
- }
-
-#ifdef BYFOUR
- /* generate crc for each value followed by one, two, and three zeros,
- and then the byte reversal of those as well as the first table */
- for (n = 0; n < 256; n++) {
- c = crc_table[0][n];
- crc_table[4][n] = REV(c);
- for (k = 1; k < 4; k++) {
- c = crc_table[0][c & 0xff] ^ (c >> 8);
- crc_table[k][n] = c;
- crc_table[k + 4][n] = REV(c);
- }
- }
-#endif /* BYFOUR */
-
- crc_table_empty = 0;
- }
- else { /* not first */
- /* wait for the other guy to finish (not efficient, but rare) */
- while (crc_table_empty)
- ;
- }
-
-#ifdef MAKECRCH
- /* write out CRC tables to crc32.h */
- {
- FILE *out;
-
- out = fopen("crc32.h", "w");
- if (out == NULL) return;
- fprintf(out, "/* crc32.h -- tables for rapid CRC calculation\n");
- fprintf(out, " * Generated automatically by crc32.c\n */\n\n");
- fprintf(out, "local const unsigned long FAR ");
- fprintf(out, "crc_table[TBLS][256] =\n{\n {\n");
- write_table(out, crc_table[0]);
-# ifdef BYFOUR
- fprintf(out, "#ifdef BYFOUR\n");
- for (k = 1; k < 8; k++) {
- fprintf(out, " },\n {\n");
- write_table(out, crc_table[k]);
- }
- fprintf(out, "#endif\n");
-# endif /* BYFOUR */
- fprintf(out, " }\n};\n");
- fclose(out);
- }
-#endif /* MAKECRCH */
-}
-
-#ifdef MAKECRCH
-local void write_table(out, table)
- FILE *out;
- const unsigned long FAR *table;
-{
- int n;
-
- for (n = 0; n < 256; n++)
- fprintf(out, "%s0x%08lxUL%s", n % 5 ? "" : " ", table[n],
- n == 255 ? "\n" : (n % 5 == 4 ? ",\n" : ", "));
-}
-#endif /* MAKECRCH */
-
-#else /* !DYNAMIC_CRC_TABLE */
-/* ========================================================================
- * Tables of CRC-32s of all single-byte values, made by make_crc_table().
- */
-#include "crc32.h"
-#endif /* DYNAMIC_CRC_TABLE */
-
-/* =========================================================================
- * This function can be used by asm versions of crc32()
- */
-const unsigned long FAR * ZEXPORT get_crc_table()
-{
-#ifdef DYNAMIC_CRC_TABLE
- if (crc_table_empty)
- make_crc_table();
-#endif /* DYNAMIC_CRC_TABLE */
- return (const unsigned long FAR *)crc_table;
-}
-
-/* ========================================================================= */
-#define DO1 crc = crc_table[0][((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8)
-#define DO8 DO1; DO1; DO1; DO1; DO1; DO1; DO1; DO1
-
-/* ========================================================================= */
-unsigned long ZEXPORT crc32(crc, buf, len)
- unsigned long crc;
- const unsigned char FAR *buf;
- unsigned len;
-{
- if (buf == Z_NULL) return 0UL;
-
-#ifdef DYNAMIC_CRC_TABLE
- if (crc_table_empty)
- make_crc_table();
-#endif /* DYNAMIC_CRC_TABLE */
-
-#ifdef BYFOUR
- if (sizeof(void *) == sizeof(ptrdiff_t)) {
- u4 endian;
-
- endian = 1;
- if (*((unsigned char *)(&endian)))
- return crc32_little(crc, buf, len);
- else
- return crc32_big(crc, buf, len);
- }
-#endif /* BYFOUR */
- crc = crc ^ 0xffffffffUL;
- while (len >= 8) {
- DO8;
- len -= 8;
- }
- if (len) do {
- DO1;
- } while (--len);
- return crc ^ 0xffffffffUL;
-}
-
-#ifdef BYFOUR
-
-/* ========================================================================= */
-#define DOLIT4 c ^= *buf4++; \
- c = crc_table[3][c & 0xff] ^ crc_table[2][(c >> 8) & 0xff] ^ \
- crc_table[1][(c >> 16) & 0xff] ^ crc_table[0][c >> 24]
-#define DOLIT32 DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4
-
-/* ========================================================================= */
-local unsigned long crc32_little(crc, buf, len)
- unsigned long crc;
- const unsigned char FAR *buf;
- unsigned len;
-{
- register u4 c;
- register const u4 FAR *buf4;
-
- c = (u4)crc;
- c = ~c;
- while (len && ((ptrdiff_t)buf & 3)) {
- c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8);
- len--;
- }
-
- buf4 = (const u4 FAR *)(const void FAR *)buf;
- while (len >= 32) {
- DOLIT32;
- len -= 32;
- }
- while (len >= 4) {
- DOLIT4;
- len -= 4;
- }
- buf = (const unsigned char FAR *)buf4;
-
- if (len) do {
- c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8);
- } while (--len);
- c = ~c;
- return (unsigned long)c;
-}
-
-/* ========================================================================= */
-#define DOBIG4 c ^= *++buf4; \
- c = crc_table[4][c & 0xff] ^ crc_table[5][(c >> 8) & 0xff] ^ \
- crc_table[6][(c >> 16) & 0xff] ^ crc_table[7][c >> 24]
-#define DOBIG32 DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4
-
-/* ========================================================================= */
-local unsigned long crc32_big(crc, buf, len)
- unsigned long crc;
- const unsigned char FAR *buf;
- unsigned len;
-{
- register u4 c;
- register const u4 FAR *buf4;
-
- c = REV((u4)crc);
- c = ~c;
- while (len && ((ptrdiff_t)buf & 3)) {
- c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8);
- len--;
- }
-
- buf4 = (const u4 FAR *)(const void FAR *)buf;
- buf4--;
- while (len >= 32) {
- DOBIG32;
- len -= 32;
- }
- while (len >= 4) {
- DOBIG4;
- len -= 4;
- }
- buf4++;
- buf = (const unsigned char FAR *)buf4;
-
- if (len) do {
- c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8);
- } while (--len);
- c = ~c;
- return (unsigned long)(REV(c));
-}
-
-#endif /* BYFOUR */
-
-#define GF2_DIM 32 /* dimension of GF(2) vectors (length of CRC) */
-
-/* ========================================================================= */
-local unsigned long gf2_matrix_times(mat, vec)
- unsigned long *mat;
- unsigned long vec;
-{
- unsigned long sum;
-
- sum = 0;
- while (vec) {
- if (vec & 1)
- sum ^= *mat;
- vec >>= 1;
- mat++;
- }
- return sum;
-}
-
-/* ========================================================================= */
-local void gf2_matrix_square(square, mat)
- unsigned long *square;
- unsigned long *mat;
-{
- int n;
-
- for (n = 0; n < GF2_DIM; n++)
- square[n] = gf2_matrix_times(mat, mat[n]);
-}
-
-/* ========================================================================= */
-uLong ZEXPORT crc32_combine(crc1, crc2, len2)
- uLong crc1;
- uLong crc2;
- z_off_t len2;
-{
- int n;
- unsigned long row;
- unsigned long even[GF2_DIM]; /* even-power-of-two zeros operator */
- unsigned long odd[GF2_DIM]; /* odd-power-of-two zeros operator */
-
- /* degenerate case */
- if (len2 == 0)
- return crc1;
-
- /* put operator for one zero bit in odd */
- odd[0] = 0xedb88320L; /* CRC-32 polynomial */
- row = 1;
- for (n = 1; n < GF2_DIM; n++) {
- odd[n] = row;
- row <<= 1;
- }
-
- /* put operator for two zero bits in even */
- gf2_matrix_square(even, odd);
-
- /* put operator for four zero bits in odd */
- gf2_matrix_square(odd, even);
-
- /* apply len2 zeros to crc1 (first square will put the operator for one
- zero byte, eight zero bits, in even) */
- do {
- /* apply zeros operator for this bit of len2 */
- gf2_matrix_square(even, odd);
- if (len2 & 1)
- crc1 = gf2_matrix_times(even, crc1);
- len2 >>= 1;
-
- /* if no more bits set, then done */
- if (len2 == 0)
- break;
-
- /* another iteration of the loop with odd and even swapped */
- gf2_matrix_square(odd, even);
- if (len2 & 1)
- crc1 = gf2_matrix_times(odd, crc1);
- len2 >>= 1;
-
- /* if no more bits set, then done */
- } while (len2 != 0);
-
- /* return combined crc */
- crc1 ^= crc2;
- return crc1;
-}
+++ /dev/null
-/* crc32.h -- tables for rapid CRC calculation
- * Generated automatically by crc32.c
- */
-
-local const unsigned long FAR crc_table[TBLS][256] =
-{
- {
- 0x00000000UL, 0x77073096UL, 0xee0e612cUL, 0x990951baUL, 0x076dc419UL,
- 0x706af48fUL, 0xe963a535UL, 0x9e6495a3UL, 0x0edb8832UL, 0x79dcb8a4UL,
- 0xe0d5e91eUL, 0x97d2d988UL, 0x09b64c2bUL, 0x7eb17cbdUL, 0xe7b82d07UL,
- 0x90bf1d91UL, 0x1db71064UL, 0x6ab020f2UL, 0xf3b97148UL, 0x84be41deUL,
- 0x1adad47dUL, 0x6ddde4ebUL, 0xf4d4b551UL, 0x83d385c7UL, 0x136c9856UL,
- 0x646ba8c0UL, 0xfd62f97aUL, 0x8a65c9ecUL, 0x14015c4fUL, 0x63066cd9UL,
- 0xfa0f3d63UL, 0x8d080df5UL, 0x3b6e20c8UL, 0x4c69105eUL, 0xd56041e4UL,
- 0xa2677172UL, 0x3c03e4d1UL, 0x4b04d447UL, 0xd20d85fdUL, 0xa50ab56bUL,
- 0x35b5a8faUL, 0x42b2986cUL, 0xdbbbc9d6UL, 0xacbcf940UL, 0x32d86ce3UL,
- 0x45df5c75UL, 0xdcd60dcfUL, 0xabd13d59UL, 0x26d930acUL, 0x51de003aUL,
- 0xc8d75180UL, 0xbfd06116UL, 0x21b4f4b5UL, 0x56b3c423UL, 0xcfba9599UL,
- 0xb8bda50fUL, 0x2802b89eUL, 0x5f058808UL, 0xc60cd9b2UL, 0xb10be924UL,
- 0x2f6f7c87UL, 0x58684c11UL, 0xc1611dabUL, 0xb6662d3dUL, 0x76dc4190UL,
- 0x01db7106UL, 0x98d220bcUL, 0xefd5102aUL, 0x71b18589UL, 0x06b6b51fUL,
- 0x9fbfe4a5UL, 0xe8b8d433UL, 0x7807c9a2UL, 0x0f00f934UL, 0x9609a88eUL,
- 0xe10e9818UL, 0x7f6a0dbbUL, 0x086d3d2dUL, 0x91646c97UL, 0xe6635c01UL,
- 0x6b6b51f4UL, 0x1c6c6162UL, 0x856530d8UL, 0xf262004eUL, 0x6c0695edUL,
- 0x1b01a57bUL, 0x8208f4c1UL, 0xf50fc457UL, 0x65b0d9c6UL, 0x12b7e950UL,
- 0x8bbeb8eaUL, 0xfcb9887cUL, 0x62dd1ddfUL, 0x15da2d49UL, 0x8cd37cf3UL,
- 0xfbd44c65UL, 0x4db26158UL, 0x3ab551ceUL, 0xa3bc0074UL, 0xd4bb30e2UL,
- 0x4adfa541UL, 0x3dd895d7UL, 0xa4d1c46dUL, 0xd3d6f4fbUL, 0x4369e96aUL,
- 0x346ed9fcUL, 0xad678846UL, 0xda60b8d0UL, 0x44042d73UL, 0x33031de5UL,
- 0xaa0a4c5fUL, 0xdd0d7cc9UL, 0x5005713cUL, 0x270241aaUL, 0xbe0b1010UL,
- 0xc90c2086UL, 0x5768b525UL, 0x206f85b3UL, 0xb966d409UL, 0xce61e49fUL,
- 0x5edef90eUL, 0x29d9c998UL, 0xb0d09822UL, 0xc7d7a8b4UL, 0x59b33d17UL,
- 0x2eb40d81UL, 0xb7bd5c3bUL, 0xc0ba6cadUL, 0xedb88320UL, 0x9abfb3b6UL,
- 0x03b6e20cUL, 0x74b1d29aUL, 0xead54739UL, 0x9dd277afUL, 0x04db2615UL,
- 0x73dc1683UL, 0xe3630b12UL, 0x94643b84UL, 0x0d6d6a3eUL, 0x7a6a5aa8UL,
- 0xe40ecf0bUL, 0x9309ff9dUL, 0x0a00ae27UL, 0x7d079eb1UL, 0xf00f9344UL,
- 0x8708a3d2UL, 0x1e01f268UL, 0x6906c2feUL, 0xf762575dUL, 0x806567cbUL,
- 0x196c3671UL, 0x6e6b06e7UL, 0xfed41b76UL, 0x89d32be0UL, 0x10da7a5aUL,
- 0x67dd4accUL, 0xf9b9df6fUL, 0x8ebeeff9UL, 0x17b7be43UL, 0x60b08ed5UL,
- 0xd6d6a3e8UL, 0xa1d1937eUL, 0x38d8c2c4UL, 0x4fdff252UL, 0xd1bb67f1UL,
- 0xa6bc5767UL, 0x3fb506ddUL, 0x48b2364bUL, 0xd80d2bdaUL, 0xaf0a1b4cUL,
- 0x36034af6UL, 0x41047a60UL, 0xdf60efc3UL, 0xa867df55UL, 0x316e8eefUL,
- 0x4669be79UL, 0xcb61b38cUL, 0xbc66831aUL, 0x256fd2a0UL, 0x5268e236UL,
- 0xcc0c7795UL, 0xbb0b4703UL, 0x220216b9UL, 0x5505262fUL, 0xc5ba3bbeUL,
- 0xb2bd0b28UL, 0x2bb45a92UL, 0x5cb36a04UL, 0xc2d7ffa7UL, 0xb5d0cf31UL,
- 0x2cd99e8bUL, 0x5bdeae1dUL, 0x9b64c2b0UL, 0xec63f226UL, 0x756aa39cUL,
- 0x026d930aUL, 0x9c0906a9UL, 0xeb0e363fUL, 0x72076785UL, 0x05005713UL,
- 0x95bf4a82UL, 0xe2b87a14UL, 0x7bb12baeUL, 0x0cb61b38UL, 0x92d28e9bUL,
- 0xe5d5be0dUL, 0x7cdcefb7UL, 0x0bdbdf21UL, 0x86d3d2d4UL, 0xf1d4e242UL,
- 0x68ddb3f8UL, 0x1fda836eUL, 0x81be16cdUL, 0xf6b9265bUL, 0x6fb077e1UL,
- 0x18b74777UL, 0x88085ae6UL, 0xff0f6a70UL, 0x66063bcaUL, 0x11010b5cUL,
- 0x8f659effUL, 0xf862ae69UL, 0x616bffd3UL, 0x166ccf45UL, 0xa00ae278UL,
- 0xd70dd2eeUL, 0x4e048354UL, 0x3903b3c2UL, 0xa7672661UL, 0xd06016f7UL,
- 0x4969474dUL, 0x3e6e77dbUL, 0xaed16a4aUL, 0xd9d65adcUL, 0x40df0b66UL,
- 0x37d83bf0UL, 0xa9bcae53UL, 0xdebb9ec5UL, 0x47b2cf7fUL, 0x30b5ffe9UL,
- 0xbdbdf21cUL, 0xcabac28aUL, 0x53b39330UL, 0x24b4a3a6UL, 0xbad03605UL,
- 0xcdd70693UL, 0x54de5729UL, 0x23d967bfUL, 0xb3667a2eUL, 0xc4614ab8UL,
- 0x5d681b02UL, 0x2a6f2b94UL, 0xb40bbe37UL, 0xc30c8ea1UL, 0x5a05df1bUL,
- 0x2d02ef8dUL
-#ifdef BYFOUR
- },
- {
- 0x00000000UL, 0x191b3141UL, 0x32366282UL, 0x2b2d53c3UL, 0x646cc504UL,
- 0x7d77f445UL, 0x565aa786UL, 0x4f4196c7UL, 0xc8d98a08UL, 0xd1c2bb49UL,
- 0xfaefe88aUL, 0xe3f4d9cbUL, 0xacb54f0cUL, 0xb5ae7e4dUL, 0x9e832d8eUL,
- 0x87981ccfUL, 0x4ac21251UL, 0x53d92310UL, 0x78f470d3UL, 0x61ef4192UL,
- 0x2eaed755UL, 0x37b5e614UL, 0x1c98b5d7UL, 0x05838496UL, 0x821b9859UL,
- 0x9b00a918UL, 0xb02dfadbUL, 0xa936cb9aUL, 0xe6775d5dUL, 0xff6c6c1cUL,
- 0xd4413fdfUL, 0xcd5a0e9eUL, 0x958424a2UL, 0x8c9f15e3UL, 0xa7b24620UL,
- 0xbea97761UL, 0xf1e8e1a6UL, 0xe8f3d0e7UL, 0xc3de8324UL, 0xdac5b265UL,
- 0x5d5daeaaUL, 0x44469febUL, 0x6f6bcc28UL, 0x7670fd69UL, 0x39316baeUL,
- 0x202a5aefUL, 0x0b07092cUL, 0x121c386dUL, 0xdf4636f3UL, 0xc65d07b2UL,
- 0xed705471UL, 0xf46b6530UL, 0xbb2af3f7UL, 0xa231c2b6UL, 0x891c9175UL,
- 0x9007a034UL, 0x179fbcfbUL, 0x0e848dbaUL, 0x25a9de79UL, 0x3cb2ef38UL,
- 0x73f379ffUL, 0x6ae848beUL, 0x41c51b7dUL, 0x58de2a3cUL, 0xf0794f05UL,
- 0xe9627e44UL, 0xc24f2d87UL, 0xdb541cc6UL, 0x94158a01UL, 0x8d0ebb40UL,
- 0xa623e883UL, 0xbf38d9c2UL, 0x38a0c50dUL, 0x21bbf44cUL, 0x0a96a78fUL,
- 0x138d96ceUL, 0x5ccc0009UL, 0x45d73148UL, 0x6efa628bUL, 0x77e153caUL,
- 0xbabb5d54UL, 0xa3a06c15UL, 0x888d3fd6UL, 0x91960e97UL, 0xded79850UL,
- 0xc7cca911UL, 0xece1fad2UL, 0xf5facb93UL, 0x7262d75cUL, 0x6b79e61dUL,
- 0x4054b5deUL, 0x594f849fUL, 0x160e1258UL, 0x0f152319UL, 0x243870daUL,
- 0x3d23419bUL, 0x65fd6ba7UL, 0x7ce65ae6UL, 0x57cb0925UL, 0x4ed03864UL,
- 0x0191aea3UL, 0x188a9fe2UL, 0x33a7cc21UL, 0x2abcfd60UL, 0xad24e1afUL,
- 0xb43fd0eeUL, 0x9f12832dUL, 0x8609b26cUL, 0xc94824abUL, 0xd05315eaUL,
- 0xfb7e4629UL, 0xe2657768UL, 0x2f3f79f6UL, 0x362448b7UL, 0x1d091b74UL,
- 0x04122a35UL, 0x4b53bcf2UL, 0x52488db3UL, 0x7965de70UL, 0x607eef31UL,
- 0xe7e6f3feUL, 0xfefdc2bfUL, 0xd5d0917cUL, 0xcccba03dUL, 0x838a36faUL,
- 0x9a9107bbUL, 0xb1bc5478UL, 0xa8a76539UL, 0x3b83984bUL, 0x2298a90aUL,
- 0x09b5fac9UL, 0x10aecb88UL, 0x5fef5d4fUL, 0x46f46c0eUL, 0x6dd93fcdUL,
- 0x74c20e8cUL, 0xf35a1243UL, 0xea412302UL, 0xc16c70c1UL, 0xd8774180UL,
- 0x9736d747UL, 0x8e2de606UL, 0xa500b5c5UL, 0xbc1b8484UL, 0x71418a1aUL,
- 0x685abb5bUL, 0x4377e898UL, 0x5a6cd9d9UL, 0x152d4f1eUL, 0x0c367e5fUL,
- 0x271b2d9cUL, 0x3e001cddUL, 0xb9980012UL, 0xa0833153UL, 0x8bae6290UL,
- 0x92b553d1UL, 0xddf4c516UL, 0xc4eff457UL, 0xefc2a794UL, 0xf6d996d5UL,
- 0xae07bce9UL, 0xb71c8da8UL, 0x9c31de6bUL, 0x852aef2aUL, 0xca6b79edUL,
- 0xd37048acUL, 0xf85d1b6fUL, 0xe1462a2eUL, 0x66de36e1UL, 0x7fc507a0UL,
- 0x54e85463UL, 0x4df36522UL, 0x02b2f3e5UL, 0x1ba9c2a4UL, 0x30849167UL,
- 0x299fa026UL, 0xe4c5aeb8UL, 0xfdde9ff9UL, 0xd6f3cc3aUL, 0xcfe8fd7bUL,
- 0x80a96bbcUL, 0x99b25afdUL, 0xb29f093eUL, 0xab84387fUL, 0x2c1c24b0UL,
- 0x350715f1UL, 0x1e2a4632UL, 0x07317773UL, 0x4870e1b4UL, 0x516bd0f5UL,
- 0x7a468336UL, 0x635db277UL, 0xcbfad74eUL, 0xd2e1e60fUL, 0xf9ccb5ccUL,
- 0xe0d7848dUL, 0xaf96124aUL, 0xb68d230bUL, 0x9da070c8UL, 0x84bb4189UL,
- 0x03235d46UL, 0x1a386c07UL, 0x31153fc4UL, 0x280e0e85UL, 0x674f9842UL,
- 0x7e54a903UL, 0x5579fac0UL, 0x4c62cb81UL, 0x8138c51fUL, 0x9823f45eUL,
- 0xb30ea79dUL, 0xaa1596dcUL, 0xe554001bUL, 0xfc4f315aUL, 0xd7626299UL,
- 0xce7953d8UL, 0x49e14f17UL, 0x50fa7e56UL, 0x7bd72d95UL, 0x62cc1cd4UL,
- 0x2d8d8a13UL, 0x3496bb52UL, 0x1fbbe891UL, 0x06a0d9d0UL, 0x5e7ef3ecUL,
- 0x4765c2adUL, 0x6c48916eUL, 0x7553a02fUL, 0x3a1236e8UL, 0x230907a9UL,
- 0x0824546aUL, 0x113f652bUL, 0x96a779e4UL, 0x8fbc48a5UL, 0xa4911b66UL,
- 0xbd8a2a27UL, 0xf2cbbce0UL, 0xebd08da1UL, 0xc0fdde62UL, 0xd9e6ef23UL,
- 0x14bce1bdUL, 0x0da7d0fcUL, 0x268a833fUL, 0x3f91b27eUL, 0x70d024b9UL,
- 0x69cb15f8UL, 0x42e6463bUL, 0x5bfd777aUL, 0xdc656bb5UL, 0xc57e5af4UL,
- 0xee530937UL, 0xf7483876UL, 0xb809aeb1UL, 0xa1129ff0UL, 0x8a3fcc33UL,
- 0x9324fd72UL
- },
- {
- 0x00000000UL, 0x01c26a37UL, 0x0384d46eUL, 0x0246be59UL, 0x0709a8dcUL,
- 0x06cbc2ebUL, 0x048d7cb2UL, 0x054f1685UL, 0x0e1351b8UL, 0x0fd13b8fUL,
- 0x0d9785d6UL, 0x0c55efe1UL, 0x091af964UL, 0x08d89353UL, 0x0a9e2d0aUL,
- 0x0b5c473dUL, 0x1c26a370UL, 0x1de4c947UL, 0x1fa2771eUL, 0x1e601d29UL,
- 0x1b2f0bacUL, 0x1aed619bUL, 0x18abdfc2UL, 0x1969b5f5UL, 0x1235f2c8UL,
- 0x13f798ffUL, 0x11b126a6UL, 0x10734c91UL, 0x153c5a14UL, 0x14fe3023UL,
- 0x16b88e7aUL, 0x177ae44dUL, 0x384d46e0UL, 0x398f2cd7UL, 0x3bc9928eUL,
- 0x3a0bf8b9UL, 0x3f44ee3cUL, 0x3e86840bUL, 0x3cc03a52UL, 0x3d025065UL,
- 0x365e1758UL, 0x379c7d6fUL, 0x35dac336UL, 0x3418a901UL, 0x3157bf84UL,
- 0x3095d5b3UL, 0x32d36beaUL, 0x331101ddUL, 0x246be590UL, 0x25a98fa7UL,
- 0x27ef31feUL, 0x262d5bc9UL, 0x23624d4cUL, 0x22a0277bUL, 0x20e69922UL,
- 0x2124f315UL, 0x2a78b428UL, 0x2bbade1fUL, 0x29fc6046UL, 0x283e0a71UL,
- 0x2d711cf4UL, 0x2cb376c3UL, 0x2ef5c89aUL, 0x2f37a2adUL, 0x709a8dc0UL,
- 0x7158e7f7UL, 0x731e59aeUL, 0x72dc3399UL, 0x7793251cUL, 0x76514f2bUL,
- 0x7417f172UL, 0x75d59b45UL, 0x7e89dc78UL, 0x7f4bb64fUL, 0x7d0d0816UL,
- 0x7ccf6221UL, 0x798074a4UL, 0x78421e93UL, 0x7a04a0caUL, 0x7bc6cafdUL,
- 0x6cbc2eb0UL, 0x6d7e4487UL, 0x6f38fadeUL, 0x6efa90e9UL, 0x6bb5866cUL,
- 0x6a77ec5bUL, 0x68315202UL, 0x69f33835UL, 0x62af7f08UL, 0x636d153fUL,
- 0x612bab66UL, 0x60e9c151UL, 0x65a6d7d4UL, 0x6464bde3UL, 0x662203baUL,
- 0x67e0698dUL, 0x48d7cb20UL, 0x4915a117UL, 0x4b531f4eUL, 0x4a917579UL,
- 0x4fde63fcUL, 0x4e1c09cbUL, 0x4c5ab792UL, 0x4d98dda5UL, 0x46c49a98UL,
- 0x4706f0afUL, 0x45404ef6UL, 0x448224c1UL, 0x41cd3244UL, 0x400f5873UL,
- 0x4249e62aUL, 0x438b8c1dUL, 0x54f16850UL, 0x55330267UL, 0x5775bc3eUL,
- 0x56b7d609UL, 0x53f8c08cUL, 0x523aaabbUL, 0x507c14e2UL, 0x51be7ed5UL,
- 0x5ae239e8UL, 0x5b2053dfUL, 0x5966ed86UL, 0x58a487b1UL, 0x5deb9134UL,
- 0x5c29fb03UL, 0x5e6f455aUL, 0x5fad2f6dUL, 0xe1351b80UL, 0xe0f771b7UL,
- 0xe2b1cfeeUL, 0xe373a5d9UL, 0xe63cb35cUL, 0xe7fed96bUL, 0xe5b86732UL,
- 0xe47a0d05UL, 0xef264a38UL, 0xeee4200fUL, 0xeca29e56UL, 0xed60f461UL,
- 0xe82fe2e4UL, 0xe9ed88d3UL, 0xebab368aUL, 0xea695cbdUL, 0xfd13b8f0UL,
- 0xfcd1d2c7UL, 0xfe976c9eUL, 0xff5506a9UL, 0xfa1a102cUL, 0xfbd87a1bUL,
- 0xf99ec442UL, 0xf85cae75UL, 0xf300e948UL, 0xf2c2837fUL, 0xf0843d26UL,
- 0xf1465711UL, 0xf4094194UL, 0xf5cb2ba3UL, 0xf78d95faUL, 0xf64fffcdUL,
- 0xd9785d60UL, 0xd8ba3757UL, 0xdafc890eUL, 0xdb3ee339UL, 0xde71f5bcUL,
- 0xdfb39f8bUL, 0xddf521d2UL, 0xdc374be5UL, 0xd76b0cd8UL, 0xd6a966efUL,
- 0xd4efd8b6UL, 0xd52db281UL, 0xd062a404UL, 0xd1a0ce33UL, 0xd3e6706aUL,
- 0xd2241a5dUL, 0xc55efe10UL, 0xc49c9427UL, 0xc6da2a7eUL, 0xc7184049UL,
- 0xc25756ccUL, 0xc3953cfbUL, 0xc1d382a2UL, 0xc011e895UL, 0xcb4dafa8UL,
- 0xca8fc59fUL, 0xc8c97bc6UL, 0xc90b11f1UL, 0xcc440774UL, 0xcd866d43UL,
- 0xcfc0d31aUL, 0xce02b92dUL, 0x91af9640UL, 0x906dfc77UL, 0x922b422eUL,
- 0x93e92819UL, 0x96a63e9cUL, 0x976454abUL, 0x9522eaf2UL, 0x94e080c5UL,
- 0x9fbcc7f8UL, 0x9e7eadcfUL, 0x9c381396UL, 0x9dfa79a1UL, 0x98b56f24UL,
- 0x99770513UL, 0x9b31bb4aUL, 0x9af3d17dUL, 0x8d893530UL, 0x8c4b5f07UL,
- 0x8e0de15eUL, 0x8fcf8b69UL, 0x8a809decUL, 0x8b42f7dbUL, 0x89044982UL,
- 0x88c623b5UL, 0x839a6488UL, 0x82580ebfUL, 0x801eb0e6UL, 0x81dcdad1UL,
- 0x8493cc54UL, 0x8551a663UL, 0x8717183aUL, 0x86d5720dUL, 0xa9e2d0a0UL,
- 0xa820ba97UL, 0xaa6604ceUL, 0xaba46ef9UL, 0xaeeb787cUL, 0xaf29124bUL,
- 0xad6fac12UL, 0xacadc625UL, 0xa7f18118UL, 0xa633eb2fUL, 0xa4755576UL,
- 0xa5b73f41UL, 0xa0f829c4UL, 0xa13a43f3UL, 0xa37cfdaaUL, 0xa2be979dUL,
- 0xb5c473d0UL, 0xb40619e7UL, 0xb640a7beUL, 0xb782cd89UL, 0xb2cddb0cUL,
- 0xb30fb13bUL, 0xb1490f62UL, 0xb08b6555UL, 0xbbd72268UL, 0xba15485fUL,
- 0xb853f606UL, 0xb9919c31UL, 0xbcde8ab4UL, 0xbd1ce083UL, 0xbf5a5edaUL,
- 0xbe9834edUL
- },
- {
- 0x00000000UL, 0xb8bc6765UL, 0xaa09c88bUL, 0x12b5afeeUL, 0x8f629757UL,
- 0x37def032UL, 0x256b5fdcUL, 0x9dd738b9UL, 0xc5b428efUL, 0x7d084f8aUL,
- 0x6fbde064UL, 0xd7018701UL, 0x4ad6bfb8UL, 0xf26ad8ddUL, 0xe0df7733UL,
- 0x58631056UL, 0x5019579fUL, 0xe8a530faUL, 0xfa109f14UL, 0x42acf871UL,
- 0xdf7bc0c8UL, 0x67c7a7adUL, 0x75720843UL, 0xcdce6f26UL, 0x95ad7f70UL,
- 0x2d111815UL, 0x3fa4b7fbUL, 0x8718d09eUL, 0x1acfe827UL, 0xa2738f42UL,
- 0xb0c620acUL, 0x087a47c9UL, 0xa032af3eUL, 0x188ec85bUL, 0x0a3b67b5UL,
- 0xb28700d0UL, 0x2f503869UL, 0x97ec5f0cUL, 0x8559f0e2UL, 0x3de59787UL,
- 0x658687d1UL, 0xdd3ae0b4UL, 0xcf8f4f5aUL, 0x7733283fUL, 0xeae41086UL,
- 0x525877e3UL, 0x40edd80dUL, 0xf851bf68UL, 0xf02bf8a1UL, 0x48979fc4UL,
- 0x5a22302aUL, 0xe29e574fUL, 0x7f496ff6UL, 0xc7f50893UL, 0xd540a77dUL,
- 0x6dfcc018UL, 0x359fd04eUL, 0x8d23b72bUL, 0x9f9618c5UL, 0x272a7fa0UL,
- 0xbafd4719UL, 0x0241207cUL, 0x10f48f92UL, 0xa848e8f7UL, 0x9b14583dUL,
- 0x23a83f58UL, 0x311d90b6UL, 0x89a1f7d3UL, 0x1476cf6aUL, 0xaccaa80fUL,
- 0xbe7f07e1UL, 0x06c36084UL, 0x5ea070d2UL, 0xe61c17b7UL, 0xf4a9b859UL,
- 0x4c15df3cUL, 0xd1c2e785UL, 0x697e80e0UL, 0x7bcb2f0eUL, 0xc377486bUL,
- 0xcb0d0fa2UL, 0x73b168c7UL, 0x6104c729UL, 0xd9b8a04cUL, 0x446f98f5UL,
- 0xfcd3ff90UL, 0xee66507eUL, 0x56da371bUL, 0x0eb9274dUL, 0xb6054028UL,
- 0xa4b0efc6UL, 0x1c0c88a3UL, 0x81dbb01aUL, 0x3967d77fUL, 0x2bd27891UL,
- 0x936e1ff4UL, 0x3b26f703UL, 0x839a9066UL, 0x912f3f88UL, 0x299358edUL,
- 0xb4446054UL, 0x0cf80731UL, 0x1e4da8dfUL, 0xa6f1cfbaUL, 0xfe92dfecUL,
- 0x462eb889UL, 0x549b1767UL, 0xec277002UL, 0x71f048bbUL, 0xc94c2fdeUL,
- 0xdbf98030UL, 0x6345e755UL, 0x6b3fa09cUL, 0xd383c7f9UL, 0xc1366817UL,
- 0x798a0f72UL, 0xe45d37cbUL, 0x5ce150aeUL, 0x4e54ff40UL, 0xf6e89825UL,
- 0xae8b8873UL, 0x1637ef16UL, 0x048240f8UL, 0xbc3e279dUL, 0x21e91f24UL,
- 0x99557841UL, 0x8be0d7afUL, 0x335cb0caUL, 0xed59b63bUL, 0x55e5d15eUL,
- 0x47507eb0UL, 0xffec19d5UL, 0x623b216cUL, 0xda874609UL, 0xc832e9e7UL,
- 0x708e8e82UL, 0x28ed9ed4UL, 0x9051f9b1UL, 0x82e4565fUL, 0x3a58313aUL,
- 0xa78f0983UL, 0x1f336ee6UL, 0x0d86c108UL, 0xb53aa66dUL, 0xbd40e1a4UL,
- 0x05fc86c1UL, 0x1749292fUL, 0xaff54e4aUL, 0x322276f3UL, 0x8a9e1196UL,
- 0x982bbe78UL, 0x2097d91dUL, 0x78f4c94bUL, 0xc048ae2eUL, 0xd2fd01c0UL,
- 0x6a4166a5UL, 0xf7965e1cUL, 0x4f2a3979UL, 0x5d9f9697UL, 0xe523f1f2UL,
- 0x4d6b1905UL, 0xf5d77e60UL, 0xe762d18eUL, 0x5fdeb6ebUL, 0xc2098e52UL,
- 0x7ab5e937UL, 0x680046d9UL, 0xd0bc21bcUL, 0x88df31eaUL, 0x3063568fUL,
- 0x22d6f961UL, 0x9a6a9e04UL, 0x07bda6bdUL, 0xbf01c1d8UL, 0xadb46e36UL,
- 0x15080953UL, 0x1d724e9aUL, 0xa5ce29ffUL, 0xb77b8611UL, 0x0fc7e174UL,
- 0x9210d9cdUL, 0x2aacbea8UL, 0x38191146UL, 0x80a57623UL, 0xd8c66675UL,
- 0x607a0110UL, 0x72cfaefeUL, 0xca73c99bUL, 0x57a4f122UL, 0xef189647UL,
- 0xfdad39a9UL, 0x45115eccUL, 0x764dee06UL, 0xcef18963UL, 0xdc44268dUL,
- 0x64f841e8UL, 0xf92f7951UL, 0x41931e34UL, 0x5326b1daUL, 0xeb9ad6bfUL,
- 0xb3f9c6e9UL, 0x0b45a18cUL, 0x19f00e62UL, 0xa14c6907UL, 0x3c9b51beUL,
- 0x842736dbUL, 0x96929935UL, 0x2e2efe50UL, 0x2654b999UL, 0x9ee8defcUL,
- 0x8c5d7112UL, 0x34e11677UL, 0xa9362eceUL, 0x118a49abUL, 0x033fe645UL,
- 0xbb838120UL, 0xe3e09176UL, 0x5b5cf613UL, 0x49e959fdUL, 0xf1553e98UL,
- 0x6c820621UL, 0xd43e6144UL, 0xc68bceaaUL, 0x7e37a9cfUL, 0xd67f4138UL,
- 0x6ec3265dUL, 0x7c7689b3UL, 0xc4caeed6UL, 0x591dd66fUL, 0xe1a1b10aUL,
- 0xf3141ee4UL, 0x4ba87981UL, 0x13cb69d7UL, 0xab770eb2UL, 0xb9c2a15cUL,
- 0x017ec639UL, 0x9ca9fe80UL, 0x241599e5UL, 0x36a0360bUL, 0x8e1c516eUL,
- 0x866616a7UL, 0x3eda71c2UL, 0x2c6fde2cUL, 0x94d3b949UL, 0x090481f0UL,
- 0xb1b8e695UL, 0xa30d497bUL, 0x1bb12e1eUL, 0x43d23e48UL, 0xfb6e592dUL,
- 0xe9dbf6c3UL, 0x516791a6UL, 0xccb0a91fUL, 0x740cce7aUL, 0x66b96194UL,
- 0xde0506f1UL
- },
- {
- 0x00000000UL, 0x96300777UL, 0x2c610eeeUL, 0xba510999UL, 0x19c46d07UL,
- 0x8ff46a70UL, 0x35a563e9UL, 0xa395649eUL, 0x3288db0eUL, 0xa4b8dc79UL,
- 0x1ee9d5e0UL, 0x88d9d297UL, 0x2b4cb609UL, 0xbd7cb17eUL, 0x072db8e7UL,
- 0x911dbf90UL, 0x6410b71dUL, 0xf220b06aUL, 0x4871b9f3UL, 0xde41be84UL,
- 0x7dd4da1aUL, 0xebe4dd6dUL, 0x51b5d4f4UL, 0xc785d383UL, 0x56986c13UL,
- 0xc0a86b64UL, 0x7af962fdUL, 0xecc9658aUL, 0x4f5c0114UL, 0xd96c0663UL,
- 0x633d0ffaUL, 0xf50d088dUL, 0xc8206e3bUL, 0x5e10694cUL, 0xe44160d5UL,
- 0x727167a2UL, 0xd1e4033cUL, 0x47d4044bUL, 0xfd850dd2UL, 0x6bb50aa5UL,
- 0xfaa8b535UL, 0x6c98b242UL, 0xd6c9bbdbUL, 0x40f9bcacUL, 0xe36cd832UL,
- 0x755cdf45UL, 0xcf0dd6dcUL, 0x593dd1abUL, 0xac30d926UL, 0x3a00de51UL,
- 0x8051d7c8UL, 0x1661d0bfUL, 0xb5f4b421UL, 0x23c4b356UL, 0x9995bacfUL,
- 0x0fa5bdb8UL, 0x9eb80228UL, 0x0888055fUL, 0xb2d90cc6UL, 0x24e90bb1UL,
- 0x877c6f2fUL, 0x114c6858UL, 0xab1d61c1UL, 0x3d2d66b6UL, 0x9041dc76UL,
- 0x0671db01UL, 0xbc20d298UL, 0x2a10d5efUL, 0x8985b171UL, 0x1fb5b606UL,
- 0xa5e4bf9fUL, 0x33d4b8e8UL, 0xa2c90778UL, 0x34f9000fUL, 0x8ea80996UL,
- 0x18980ee1UL, 0xbb0d6a7fUL, 0x2d3d6d08UL, 0x976c6491UL, 0x015c63e6UL,
- 0xf4516b6bUL, 0x62616c1cUL, 0xd8306585UL, 0x4e0062f2UL, 0xed95066cUL,
- 0x7ba5011bUL, 0xc1f40882UL, 0x57c40ff5UL, 0xc6d9b065UL, 0x50e9b712UL,
- 0xeab8be8bUL, 0x7c88b9fcUL, 0xdf1ddd62UL, 0x492dda15UL, 0xf37cd38cUL,
- 0x654cd4fbUL, 0x5861b24dUL, 0xce51b53aUL, 0x7400bca3UL, 0xe230bbd4UL,
- 0x41a5df4aUL, 0xd795d83dUL, 0x6dc4d1a4UL, 0xfbf4d6d3UL, 0x6ae96943UL,
- 0xfcd96e34UL, 0x468867adUL, 0xd0b860daUL, 0x732d0444UL, 0xe51d0333UL,
- 0x5f4c0aaaUL, 0xc97c0dddUL, 0x3c710550UL, 0xaa410227UL, 0x10100bbeUL,
- 0x86200cc9UL, 0x25b56857UL, 0xb3856f20UL, 0x09d466b9UL, 0x9fe461ceUL,
- 0x0ef9de5eUL, 0x98c9d929UL, 0x2298d0b0UL, 0xb4a8d7c7UL, 0x173db359UL,
- 0x810db42eUL, 0x3b5cbdb7UL, 0xad6cbac0UL, 0x2083b8edUL, 0xb6b3bf9aUL,
- 0x0ce2b603UL, 0x9ad2b174UL, 0x3947d5eaUL, 0xaf77d29dUL, 0x1526db04UL,
- 0x8316dc73UL, 0x120b63e3UL, 0x843b6494UL, 0x3e6a6d0dUL, 0xa85a6a7aUL,
- 0x0bcf0ee4UL, 0x9dff0993UL, 0x27ae000aUL, 0xb19e077dUL, 0x44930ff0UL,
- 0xd2a30887UL, 0x68f2011eUL, 0xfec20669UL, 0x5d5762f7UL, 0xcb676580UL,
- 0x71366c19UL, 0xe7066b6eUL, 0x761bd4feUL, 0xe02bd389UL, 0x5a7ada10UL,
- 0xcc4add67UL, 0x6fdfb9f9UL, 0xf9efbe8eUL, 0x43beb717UL, 0xd58eb060UL,
- 0xe8a3d6d6UL, 0x7e93d1a1UL, 0xc4c2d838UL, 0x52f2df4fUL, 0xf167bbd1UL,
- 0x6757bca6UL, 0xdd06b53fUL, 0x4b36b248UL, 0xda2b0dd8UL, 0x4c1b0aafUL,
- 0xf64a0336UL, 0x607a0441UL, 0xc3ef60dfUL, 0x55df67a8UL, 0xef8e6e31UL,
- 0x79be6946UL, 0x8cb361cbUL, 0x1a8366bcUL, 0xa0d26f25UL, 0x36e26852UL,
- 0x95770cccUL, 0x03470bbbUL, 0xb9160222UL, 0x2f260555UL, 0xbe3bbac5UL,
- 0x280bbdb2UL, 0x925ab42bUL, 0x046ab35cUL, 0xa7ffd7c2UL, 0x31cfd0b5UL,
- 0x8b9ed92cUL, 0x1daede5bUL, 0xb0c2649bUL, 0x26f263ecUL, 0x9ca36a75UL,
- 0x0a936d02UL, 0xa906099cUL, 0x3f360eebUL, 0x85670772UL, 0x13570005UL,
- 0x824abf95UL, 0x147ab8e2UL, 0xae2bb17bUL, 0x381bb60cUL, 0x9b8ed292UL,
- 0x0dbed5e5UL, 0xb7efdc7cUL, 0x21dfdb0bUL, 0xd4d2d386UL, 0x42e2d4f1UL,
- 0xf8b3dd68UL, 0x6e83da1fUL, 0xcd16be81UL, 0x5b26b9f6UL, 0xe177b06fUL,
- 0x7747b718UL, 0xe65a0888UL, 0x706a0fffUL, 0xca3b0666UL, 0x5c0b0111UL,
- 0xff9e658fUL, 0x69ae62f8UL, 0xd3ff6b61UL, 0x45cf6c16UL, 0x78e20aa0UL,
- 0xeed20dd7UL, 0x5483044eUL, 0xc2b30339UL, 0x612667a7UL, 0xf71660d0UL,
- 0x4d476949UL, 0xdb776e3eUL, 0x4a6ad1aeUL, 0xdc5ad6d9UL, 0x660bdf40UL,
- 0xf03bd837UL, 0x53aebca9UL, 0xc59ebbdeUL, 0x7fcfb247UL, 0xe9ffb530UL,
- 0x1cf2bdbdUL, 0x8ac2bacaUL, 0x3093b353UL, 0xa6a3b424UL, 0x0536d0baUL,
- 0x9306d7cdUL, 0x2957de54UL, 0xbf67d923UL, 0x2e7a66b3UL, 0xb84a61c4UL,
- 0x021b685dUL, 0x942b6f2aUL, 0x37be0bb4UL, 0xa18e0cc3UL, 0x1bdf055aUL,
- 0x8def022dUL
- },
- {
- 0x00000000UL, 0x41311b19UL, 0x82623632UL, 0xc3532d2bUL, 0x04c56c64UL,
- 0x45f4777dUL, 0x86a75a56UL, 0xc796414fUL, 0x088ad9c8UL, 0x49bbc2d1UL,
- 0x8ae8effaUL, 0xcbd9f4e3UL, 0x0c4fb5acUL, 0x4d7eaeb5UL, 0x8e2d839eUL,
- 0xcf1c9887UL, 0x5112c24aUL, 0x1023d953UL, 0xd370f478UL, 0x9241ef61UL,
- 0x55d7ae2eUL, 0x14e6b537UL, 0xd7b5981cUL, 0x96848305UL, 0x59981b82UL,
- 0x18a9009bUL, 0xdbfa2db0UL, 0x9acb36a9UL, 0x5d5d77e6UL, 0x1c6c6cffUL,
- 0xdf3f41d4UL, 0x9e0e5acdUL, 0xa2248495UL, 0xe3159f8cUL, 0x2046b2a7UL,
- 0x6177a9beUL, 0xa6e1e8f1UL, 0xe7d0f3e8UL, 0x2483dec3UL, 0x65b2c5daUL,
- 0xaaae5d5dUL, 0xeb9f4644UL, 0x28cc6b6fUL, 0x69fd7076UL, 0xae6b3139UL,
- 0xef5a2a20UL, 0x2c09070bUL, 0x6d381c12UL, 0xf33646dfUL, 0xb2075dc6UL,
- 0x715470edUL, 0x30656bf4UL, 0xf7f32abbUL, 0xb6c231a2UL, 0x75911c89UL,
- 0x34a00790UL, 0xfbbc9f17UL, 0xba8d840eUL, 0x79dea925UL, 0x38efb23cUL,
- 0xff79f373UL, 0xbe48e86aUL, 0x7d1bc541UL, 0x3c2ade58UL, 0x054f79f0UL,
- 0x447e62e9UL, 0x872d4fc2UL, 0xc61c54dbUL, 0x018a1594UL, 0x40bb0e8dUL,
- 0x83e823a6UL, 0xc2d938bfUL, 0x0dc5a038UL, 0x4cf4bb21UL, 0x8fa7960aUL,
- 0xce968d13UL, 0x0900cc5cUL, 0x4831d745UL, 0x8b62fa6eUL, 0xca53e177UL,
- 0x545dbbbaUL, 0x156ca0a3UL, 0xd63f8d88UL, 0x970e9691UL, 0x5098d7deUL,
- 0x11a9ccc7UL, 0xd2fae1ecUL, 0x93cbfaf5UL, 0x5cd76272UL, 0x1de6796bUL,
- 0xdeb55440UL, 0x9f844f59UL, 0x58120e16UL, 0x1923150fUL, 0xda703824UL,
- 0x9b41233dUL, 0xa76bfd65UL, 0xe65ae67cUL, 0x2509cb57UL, 0x6438d04eUL,
- 0xa3ae9101UL, 0xe29f8a18UL, 0x21cca733UL, 0x60fdbc2aUL, 0xafe124adUL,
- 0xeed03fb4UL, 0x2d83129fUL, 0x6cb20986UL, 0xab2448c9UL, 0xea1553d0UL,
- 0x29467efbUL, 0x687765e2UL, 0xf6793f2fUL, 0xb7482436UL, 0x741b091dUL,
- 0x352a1204UL, 0xf2bc534bUL, 0xb38d4852UL, 0x70de6579UL, 0x31ef7e60UL,
- 0xfef3e6e7UL, 0xbfc2fdfeUL, 0x7c91d0d5UL, 0x3da0cbccUL, 0xfa368a83UL,
- 0xbb07919aUL, 0x7854bcb1UL, 0x3965a7a8UL, 0x4b98833bUL, 0x0aa99822UL,
- 0xc9fab509UL, 0x88cbae10UL, 0x4f5def5fUL, 0x0e6cf446UL, 0xcd3fd96dUL,
- 0x8c0ec274UL, 0x43125af3UL, 0x022341eaUL, 0xc1706cc1UL, 0x804177d8UL,
- 0x47d73697UL, 0x06e62d8eUL, 0xc5b500a5UL, 0x84841bbcUL, 0x1a8a4171UL,
- 0x5bbb5a68UL, 0x98e87743UL, 0xd9d96c5aUL, 0x1e4f2d15UL, 0x5f7e360cUL,
- 0x9c2d1b27UL, 0xdd1c003eUL, 0x120098b9UL, 0x533183a0UL, 0x9062ae8bUL,
- 0xd153b592UL, 0x16c5f4ddUL, 0x57f4efc4UL, 0x94a7c2efUL, 0xd596d9f6UL,
- 0xe9bc07aeUL, 0xa88d1cb7UL, 0x6bde319cUL, 0x2aef2a85UL, 0xed796bcaUL,
- 0xac4870d3UL, 0x6f1b5df8UL, 0x2e2a46e1UL, 0xe136de66UL, 0xa007c57fUL,
- 0x6354e854UL, 0x2265f34dUL, 0xe5f3b202UL, 0xa4c2a91bUL, 0x67918430UL,
- 0x26a09f29UL, 0xb8aec5e4UL, 0xf99fdefdUL, 0x3accf3d6UL, 0x7bfde8cfUL,
- 0xbc6ba980UL, 0xfd5ab299UL, 0x3e099fb2UL, 0x7f3884abUL, 0xb0241c2cUL,
- 0xf1150735UL, 0x32462a1eUL, 0x73773107UL, 0xb4e17048UL, 0xf5d06b51UL,
- 0x3683467aUL, 0x77b25d63UL, 0x4ed7facbUL, 0x0fe6e1d2UL, 0xccb5ccf9UL,
- 0x8d84d7e0UL, 0x4a1296afUL, 0x0b238db6UL, 0xc870a09dUL, 0x8941bb84UL,
- 0x465d2303UL, 0x076c381aUL, 0xc43f1531UL, 0x850e0e28UL, 0x42984f67UL,
- 0x03a9547eUL, 0xc0fa7955UL, 0x81cb624cUL, 0x1fc53881UL, 0x5ef42398UL,
- 0x9da70eb3UL, 0xdc9615aaUL, 0x1b0054e5UL, 0x5a314ffcUL, 0x996262d7UL,
- 0xd85379ceUL, 0x174fe149UL, 0x567efa50UL, 0x952dd77bUL, 0xd41ccc62UL,
- 0x138a8d2dUL, 0x52bb9634UL, 0x91e8bb1fUL, 0xd0d9a006UL, 0xecf37e5eUL,
- 0xadc26547UL, 0x6e91486cUL, 0x2fa05375UL, 0xe836123aUL, 0xa9070923UL,
- 0x6a542408UL, 0x2b653f11UL, 0xe479a796UL, 0xa548bc8fUL, 0x661b91a4UL,
- 0x272a8abdUL, 0xe0bccbf2UL, 0xa18dd0ebUL, 0x62defdc0UL, 0x23efe6d9UL,
- 0xbde1bc14UL, 0xfcd0a70dUL, 0x3f838a26UL, 0x7eb2913fUL, 0xb924d070UL,
- 0xf815cb69UL, 0x3b46e642UL, 0x7a77fd5bUL, 0xb56b65dcUL, 0xf45a7ec5UL,
- 0x370953eeUL, 0x763848f7UL, 0xb1ae09b8UL, 0xf09f12a1UL, 0x33cc3f8aUL,
- 0x72fd2493UL
- },
- {
- 0x00000000UL, 0x376ac201UL, 0x6ed48403UL, 0x59be4602UL, 0xdca80907UL,
- 0xebc2cb06UL, 0xb27c8d04UL, 0x85164f05UL, 0xb851130eUL, 0x8f3bd10fUL,
- 0xd685970dUL, 0xe1ef550cUL, 0x64f91a09UL, 0x5393d808UL, 0x0a2d9e0aUL,
- 0x3d475c0bUL, 0x70a3261cUL, 0x47c9e41dUL, 0x1e77a21fUL, 0x291d601eUL,
- 0xac0b2f1bUL, 0x9b61ed1aUL, 0xc2dfab18UL, 0xf5b56919UL, 0xc8f23512UL,
- 0xff98f713UL, 0xa626b111UL, 0x914c7310UL, 0x145a3c15UL, 0x2330fe14UL,
- 0x7a8eb816UL, 0x4de47a17UL, 0xe0464d38UL, 0xd72c8f39UL, 0x8e92c93bUL,
- 0xb9f80b3aUL, 0x3cee443fUL, 0x0b84863eUL, 0x523ac03cUL, 0x6550023dUL,
- 0x58175e36UL, 0x6f7d9c37UL, 0x36c3da35UL, 0x01a91834UL, 0x84bf5731UL,
- 0xb3d59530UL, 0xea6bd332UL, 0xdd011133UL, 0x90e56b24UL, 0xa78fa925UL,
- 0xfe31ef27UL, 0xc95b2d26UL, 0x4c4d6223UL, 0x7b27a022UL, 0x2299e620UL,
- 0x15f32421UL, 0x28b4782aUL, 0x1fdeba2bUL, 0x4660fc29UL, 0x710a3e28UL,
- 0xf41c712dUL, 0xc376b32cUL, 0x9ac8f52eUL, 0xada2372fUL, 0xc08d9a70UL,
- 0xf7e75871UL, 0xae591e73UL, 0x9933dc72UL, 0x1c259377UL, 0x2b4f5176UL,
- 0x72f11774UL, 0x459bd575UL, 0x78dc897eUL, 0x4fb64b7fUL, 0x16080d7dUL,
- 0x2162cf7cUL, 0xa4748079UL, 0x931e4278UL, 0xcaa0047aUL, 0xfdcac67bUL,
- 0xb02ebc6cUL, 0x87447e6dUL, 0xdefa386fUL, 0xe990fa6eUL, 0x6c86b56bUL,
- 0x5bec776aUL, 0x02523168UL, 0x3538f369UL, 0x087faf62UL, 0x3f156d63UL,
- 0x66ab2b61UL, 0x51c1e960UL, 0xd4d7a665UL, 0xe3bd6464UL, 0xba032266UL,
- 0x8d69e067UL, 0x20cbd748UL, 0x17a11549UL, 0x4e1f534bUL, 0x7975914aUL,
- 0xfc63de4fUL, 0xcb091c4eUL, 0x92b75a4cUL, 0xa5dd984dUL, 0x989ac446UL,
- 0xaff00647UL, 0xf64e4045UL, 0xc1248244UL, 0x4432cd41UL, 0x73580f40UL,
- 0x2ae64942UL, 0x1d8c8b43UL, 0x5068f154UL, 0x67023355UL, 0x3ebc7557UL,
- 0x09d6b756UL, 0x8cc0f853UL, 0xbbaa3a52UL, 0xe2147c50UL, 0xd57ebe51UL,
- 0xe839e25aUL, 0xdf53205bUL, 0x86ed6659UL, 0xb187a458UL, 0x3491eb5dUL,
- 0x03fb295cUL, 0x5a456f5eUL, 0x6d2fad5fUL, 0x801b35e1UL, 0xb771f7e0UL,
- 0xeecfb1e2UL, 0xd9a573e3UL, 0x5cb33ce6UL, 0x6bd9fee7UL, 0x3267b8e5UL,
- 0x050d7ae4UL, 0x384a26efUL, 0x0f20e4eeUL, 0x569ea2ecUL, 0x61f460edUL,
- 0xe4e22fe8UL, 0xd388ede9UL, 0x8a36abebUL, 0xbd5c69eaUL, 0xf0b813fdUL,
- 0xc7d2d1fcUL, 0x9e6c97feUL, 0xa90655ffUL, 0x2c101afaUL, 0x1b7ad8fbUL,
- 0x42c49ef9UL, 0x75ae5cf8UL, 0x48e900f3UL, 0x7f83c2f2UL, 0x263d84f0UL,
- 0x115746f1UL, 0x944109f4UL, 0xa32bcbf5UL, 0xfa958df7UL, 0xcdff4ff6UL,
- 0x605d78d9UL, 0x5737bad8UL, 0x0e89fcdaUL, 0x39e33edbUL, 0xbcf571deUL,
- 0x8b9fb3dfUL, 0xd221f5ddUL, 0xe54b37dcUL, 0xd80c6bd7UL, 0xef66a9d6UL,
- 0xb6d8efd4UL, 0x81b22dd5UL, 0x04a462d0UL, 0x33cea0d1UL, 0x6a70e6d3UL,
- 0x5d1a24d2UL, 0x10fe5ec5UL, 0x27949cc4UL, 0x7e2adac6UL, 0x494018c7UL,
- 0xcc5657c2UL, 0xfb3c95c3UL, 0xa282d3c1UL, 0x95e811c0UL, 0xa8af4dcbUL,
- 0x9fc58fcaUL, 0xc67bc9c8UL, 0xf1110bc9UL, 0x740744ccUL, 0x436d86cdUL,
- 0x1ad3c0cfUL, 0x2db902ceUL, 0x4096af91UL, 0x77fc6d90UL, 0x2e422b92UL,
- 0x1928e993UL, 0x9c3ea696UL, 0xab546497UL, 0xf2ea2295UL, 0xc580e094UL,
- 0xf8c7bc9fUL, 0xcfad7e9eUL, 0x9613389cUL, 0xa179fa9dUL, 0x246fb598UL,
- 0x13057799UL, 0x4abb319bUL, 0x7dd1f39aUL, 0x3035898dUL, 0x075f4b8cUL,
- 0x5ee10d8eUL, 0x698bcf8fUL, 0xec9d808aUL, 0xdbf7428bUL, 0x82490489UL,
- 0xb523c688UL, 0x88649a83UL, 0xbf0e5882UL, 0xe6b01e80UL, 0xd1dadc81UL,
- 0x54cc9384UL, 0x63a65185UL, 0x3a181787UL, 0x0d72d586UL, 0xa0d0e2a9UL,
- 0x97ba20a8UL, 0xce0466aaUL, 0xf96ea4abUL, 0x7c78ebaeUL, 0x4b1229afUL,
- 0x12ac6fadUL, 0x25c6adacUL, 0x1881f1a7UL, 0x2feb33a6UL, 0x765575a4UL,
- 0x413fb7a5UL, 0xc429f8a0UL, 0xf3433aa1UL, 0xaafd7ca3UL, 0x9d97bea2UL,
- 0xd073c4b5UL, 0xe71906b4UL, 0xbea740b6UL, 0x89cd82b7UL, 0x0cdbcdb2UL,
- 0x3bb10fb3UL, 0x620f49b1UL, 0x55658bb0UL, 0x6822d7bbUL, 0x5f4815baUL,
- 0x06f653b8UL, 0x319c91b9UL, 0xb48adebcUL, 0x83e01cbdUL, 0xda5e5abfUL,
- 0xed3498beUL
- },
- {
- 0x00000000UL, 0x6567bcb8UL, 0x8bc809aaUL, 0xeeafb512UL, 0x5797628fUL,
- 0x32f0de37UL, 0xdc5f6b25UL, 0xb938d79dUL, 0xef28b4c5UL, 0x8a4f087dUL,
- 0x64e0bd6fUL, 0x018701d7UL, 0xb8bfd64aUL, 0xddd86af2UL, 0x3377dfe0UL,
- 0x56106358UL, 0x9f571950UL, 0xfa30a5e8UL, 0x149f10faUL, 0x71f8ac42UL,
- 0xc8c07bdfUL, 0xada7c767UL, 0x43087275UL, 0x266fcecdUL, 0x707fad95UL,
- 0x1518112dUL, 0xfbb7a43fUL, 0x9ed01887UL, 0x27e8cf1aUL, 0x428f73a2UL,
- 0xac20c6b0UL, 0xc9477a08UL, 0x3eaf32a0UL, 0x5bc88e18UL, 0xb5673b0aUL,
- 0xd00087b2UL, 0x6938502fUL, 0x0c5fec97UL, 0xe2f05985UL, 0x8797e53dUL,
- 0xd1878665UL, 0xb4e03addUL, 0x5a4f8fcfUL, 0x3f283377UL, 0x8610e4eaUL,
- 0xe3775852UL, 0x0dd8ed40UL, 0x68bf51f8UL, 0xa1f82bf0UL, 0xc49f9748UL,
- 0x2a30225aUL, 0x4f579ee2UL, 0xf66f497fUL, 0x9308f5c7UL, 0x7da740d5UL,
- 0x18c0fc6dUL, 0x4ed09f35UL, 0x2bb7238dUL, 0xc518969fUL, 0xa07f2a27UL,
- 0x1947fdbaUL, 0x7c204102UL, 0x928ff410UL, 0xf7e848a8UL, 0x3d58149bUL,
- 0x583fa823UL, 0xb6901d31UL, 0xd3f7a189UL, 0x6acf7614UL, 0x0fa8caacUL,
- 0xe1077fbeUL, 0x8460c306UL, 0xd270a05eUL, 0xb7171ce6UL, 0x59b8a9f4UL,
- 0x3cdf154cUL, 0x85e7c2d1UL, 0xe0807e69UL, 0x0e2fcb7bUL, 0x6b4877c3UL,
- 0xa20f0dcbUL, 0xc768b173UL, 0x29c70461UL, 0x4ca0b8d9UL, 0xf5986f44UL,
- 0x90ffd3fcUL, 0x7e5066eeUL, 0x1b37da56UL, 0x4d27b90eUL, 0x284005b6UL,
- 0xc6efb0a4UL, 0xa3880c1cUL, 0x1ab0db81UL, 0x7fd76739UL, 0x9178d22bUL,
- 0xf41f6e93UL, 0x03f7263bUL, 0x66909a83UL, 0x883f2f91UL, 0xed589329UL,
- 0x546044b4UL, 0x3107f80cUL, 0xdfa84d1eUL, 0xbacff1a6UL, 0xecdf92feUL,
- 0x89b82e46UL, 0x67179b54UL, 0x027027ecUL, 0xbb48f071UL, 0xde2f4cc9UL,
- 0x3080f9dbUL, 0x55e74563UL, 0x9ca03f6bUL, 0xf9c783d3UL, 0x176836c1UL,
- 0x720f8a79UL, 0xcb375de4UL, 0xae50e15cUL, 0x40ff544eUL, 0x2598e8f6UL,
- 0x73888baeUL, 0x16ef3716UL, 0xf8408204UL, 0x9d273ebcUL, 0x241fe921UL,
- 0x41785599UL, 0xafd7e08bUL, 0xcab05c33UL, 0x3bb659edUL, 0x5ed1e555UL,
- 0xb07e5047UL, 0xd519ecffUL, 0x6c213b62UL, 0x094687daUL, 0xe7e932c8UL,
- 0x828e8e70UL, 0xd49eed28UL, 0xb1f95190UL, 0x5f56e482UL, 0x3a31583aUL,
- 0x83098fa7UL, 0xe66e331fUL, 0x08c1860dUL, 0x6da63ab5UL, 0xa4e140bdUL,
- 0xc186fc05UL, 0x2f294917UL, 0x4a4ef5afUL, 0xf3762232UL, 0x96119e8aUL,
- 0x78be2b98UL, 0x1dd99720UL, 0x4bc9f478UL, 0x2eae48c0UL, 0xc001fdd2UL,
- 0xa566416aUL, 0x1c5e96f7UL, 0x79392a4fUL, 0x97969f5dUL, 0xf2f123e5UL,
- 0x05196b4dUL, 0x607ed7f5UL, 0x8ed162e7UL, 0xebb6de5fUL, 0x528e09c2UL,
- 0x37e9b57aUL, 0xd9460068UL, 0xbc21bcd0UL, 0xea31df88UL, 0x8f566330UL,
- 0x61f9d622UL, 0x049e6a9aUL, 0xbda6bd07UL, 0xd8c101bfUL, 0x366eb4adUL,
- 0x53090815UL, 0x9a4e721dUL, 0xff29cea5UL, 0x11867bb7UL, 0x74e1c70fUL,
- 0xcdd91092UL, 0xa8beac2aUL, 0x46111938UL, 0x2376a580UL, 0x7566c6d8UL,
- 0x10017a60UL, 0xfeaecf72UL, 0x9bc973caUL, 0x22f1a457UL, 0x479618efUL,
- 0xa939adfdUL, 0xcc5e1145UL, 0x06ee4d76UL, 0x6389f1ceUL, 0x8d2644dcUL,
- 0xe841f864UL, 0x51792ff9UL, 0x341e9341UL, 0xdab12653UL, 0xbfd69aebUL,
- 0xe9c6f9b3UL, 0x8ca1450bUL, 0x620ef019UL, 0x07694ca1UL, 0xbe519b3cUL,
- 0xdb362784UL, 0x35999296UL, 0x50fe2e2eUL, 0x99b95426UL, 0xfcdee89eUL,
- 0x12715d8cUL, 0x7716e134UL, 0xce2e36a9UL, 0xab498a11UL, 0x45e63f03UL,
- 0x208183bbUL, 0x7691e0e3UL, 0x13f65c5bUL, 0xfd59e949UL, 0x983e55f1UL,
- 0x2106826cUL, 0x44613ed4UL, 0xaace8bc6UL, 0xcfa9377eUL, 0x38417fd6UL,
- 0x5d26c36eUL, 0xb389767cUL, 0xd6eecac4UL, 0x6fd61d59UL, 0x0ab1a1e1UL,
- 0xe41e14f3UL, 0x8179a84bUL, 0xd769cb13UL, 0xb20e77abUL, 0x5ca1c2b9UL,
- 0x39c67e01UL, 0x80fea99cUL, 0xe5991524UL, 0x0b36a036UL, 0x6e511c8eUL,
- 0xa7166686UL, 0xc271da3eUL, 0x2cde6f2cUL, 0x49b9d394UL, 0xf0810409UL,
- 0x95e6b8b1UL, 0x7b490da3UL, 0x1e2eb11bUL, 0x483ed243UL, 0x2d596efbUL,
- 0xc3f6dbe9UL, 0xa6916751UL, 0x1fa9b0ccUL, 0x7ace0c74UL, 0x9461b966UL,
- 0xf10605deUL
-#endif
- }
-};
+++ /dev/null
-/* deflate.c -- compress data using the deflation algorithm
- * Copyright (C) 1995-2005 Jean-loup Gailly.
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/*
- * ALGORITHM
- *
- * The "deflation" process depends on being able to identify portions
- * of the input text which are identical to earlier input (within a
- * sliding window trailing behind the input currently being processed).
- *
- * The most straightforward technique turns out to be the fastest for
- * most input files: try all possible matches and select the longest.
- * The key feature of this algorithm is that insertions into the string
- * dictionary are very simple and thus fast, and deletions are avoided
- * completely. Insertions are performed at each input character, whereas
- * string matches are performed only when the previous match ends. So it
- * is preferable to spend more time in matches to allow very fast string
- * insertions and avoid deletions. The matching algorithm for small
- * strings is inspired from that of Rabin & Karp. A brute force approach
- * is used to find longer strings when a small match has been found.
- * A similar algorithm is used in comic (by Jan-Mark Wams) and freeze
- * (by Leonid Broukhis).
- * A previous version of this file used a more sophisticated algorithm
- * (by Fiala and Greene) which is guaranteed to run in linear amortized
- * time, but has a larger average cost, uses more memory and is patented.
- * However the F&G algorithm may be faster for some highly redundant
- * files if the parameter max_chain_length (described below) is too large.
- *
- * ACKNOWLEDGEMENTS
- *
- * The idea of lazy evaluation of matches is due to Jan-Mark Wams, and
- * I found it in 'freeze' written by Leonid Broukhis.
- * Thanks to many people for bug reports and testing.
- *
- * REFERENCES
- *
- * Deutsch, L.P.,"DEFLATE Compressed Data Format Specification".
- * Available in http://www.ietf.org/rfc/rfc1951.txt
- *
- * A description of the Rabin and Karp algorithm is given in the book
- * "Algorithms" by R. Sedgewick, Addison-Wesley, p252.
- *
- * Fiala,E.R., and Greene,D.H.
- * Data Compression with Finite Windows, Comm.ACM, 32,4 (1989) 490-595
- *
- */
-
-/* @(#) $Id$ */
-
-#include "deflate.h"
-
-const char deflate_copyright[] =
- " deflate 1.2.3 Copyright 1995-2005 Jean-loup Gailly ";
-/*
- If you use the zlib library in a product, an acknowledgment is welcome
- in the documentation of your product. If for some reason you cannot
- include such an acknowledgment, I would appreciate that you keep this
- copyright string in the executable of your product.
- */
-
-/* ===========================================================================
- * Function prototypes.
- */
-typedef enum {
- need_more, /* block not completed, need more input or more output */
- block_done, /* block flush performed */
- finish_started, /* finish started, need only more output at next deflate */
- finish_done /* finish done, accept no more input or output */
-} block_state;
-
-typedef block_state (*compress_func) OF((deflate_state *s, int flush));
-/* Compression function. Returns the block state after the call. */
-
-local void fill_window OF((deflate_state *s));
-local block_state deflate_stored OF((deflate_state *s, int flush));
-local block_state deflate_fast OF((deflate_state *s, int flush));
-#ifndef FASTEST
-local block_state deflate_slow OF((deflate_state *s, int flush));
-#endif
-local void lm_init OF((deflate_state *s));
-local void putShortMSB OF((deflate_state *s, uInt b));
-local void flush_pending OF((z_streamp strm));
-local int read_buf OF((z_streamp strm, Bytef *buf, unsigned size));
-#ifndef FASTEST
-#ifdef ASMV
- void match_init OF((void)); /* asm code initialization */
- uInt longest_match OF((deflate_state *s, IPos cur_match));
-#else
-local uInt longest_match OF((deflate_state *s, IPos cur_match));
-#endif
-#endif
-local uInt longest_match_fast OF((deflate_state *s, IPos cur_match));
-
-#ifdef DEBUG
-local void check_match OF((deflate_state *s, IPos start, IPos match,
- int length));
-#endif
-
-/* ===========================================================================
- * Local data
- */
-
-#define NIL 0
-/* Tail of hash chains */
-
-#ifndef TOO_FAR
-# define TOO_FAR 4096
-#endif
-/* Matches of length 3 are discarded if their distance exceeds TOO_FAR */
-
-#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1)
-/* Minimum amount of lookahead, except at the end of the input file.
- * See deflate.c for comments about the MIN_MATCH+1.
- */
-
-/* Values for max_lazy_match, good_match and max_chain_length, depending on
- * the desired pack level (0..9). The values given below have been tuned to
- * exclude worst case performance for pathological files. Better values may be
- * found for specific files.
- */
-typedef struct config_s {
- ush good_length; /* reduce lazy search above this match length */
- ush max_lazy; /* do not perform lazy search above this match length */
- ush nice_length; /* quit search above this match length */
- ush max_chain;
- compress_func func;
-} config;
-
-#ifdef FASTEST
-local const config configuration_table[2] = {
-/* good lazy nice chain */
-/* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */
-/* 1 */ {4, 4, 8, 4, deflate_fast}}; /* max speed, no lazy matches */
-#else
-local const config configuration_table[10] = {
-/* good lazy nice chain */
-/* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */
-/* 1 */ {4, 4, 8, 4, deflate_fast}, /* max speed, no lazy matches */
-/* 2 */ {4, 5, 16, 8, deflate_fast},
-/* 3 */ {4, 6, 32, 32, deflate_fast},
-
-/* 4 */ {4, 4, 16, 16, deflate_slow}, /* lazy matches */
-/* 5 */ {8, 16, 32, 32, deflate_slow},
-/* 6 */ {8, 16, 128, 128, deflate_slow},
-/* 7 */ {8, 32, 128, 256, deflate_slow},
-/* 8 */ {32, 128, 258, 1024, deflate_slow},
-/* 9 */ {32, 258, 258, 4096, deflate_slow}}; /* max compression */
-#endif
-
-/* Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4
- * For deflate_fast() (levels <= 3) good is ignored and lazy has a different
- * meaning.
- */
-
-#define EQUAL 0
-/* result of memcmp for equal strings */
-
-#ifndef NO_DUMMY_DECL
-struct static_tree_desc_s {int dummy;}; /* for buggy compilers */
-#endif
-
-/* ===========================================================================
- * Update a hash value with the given input byte
- * IN assertion: all calls to to UPDATE_HASH are made with consecutive
- * input characters, so that a running hash key can be computed from the
- * previous key instead of complete recalculation each time.
- */
-#define UPDATE_HASH(s,h,c) (h = (((h)<<s->hash_shift) ^ (c)) & s->hash_mask)
-
-
-/* ===========================================================================
- * Insert string str in the dictionary and set match_head to the previous head
- * of the hash chain (the most recent string with same hash key). Return
- * the previous length of the hash chain.
- * If this file is compiled with -DFASTEST, the compression level is forced
- * to 1, and no hash chains are maintained.
- * IN assertion: all calls to to INSERT_STRING are made with consecutive
- * input characters and the first MIN_MATCH bytes of str are valid
- * (except for the last MIN_MATCH-1 bytes of the input file).
- */
-#ifdef FASTEST
-#define INSERT_STRING(s, str, match_head) \
- (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \
- match_head = s->head[s->ins_h], \
- s->head[s->ins_h] = (Pos)(str))
-#else
-#define INSERT_STRING(s, str, match_head) \
- (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \
- match_head = s->prev[(str) & s->w_mask] = s->head[s->ins_h], \
- s->head[s->ins_h] = (Pos)(str))
-#endif
-
-/* ===========================================================================
- * Initialize the hash table (avoiding 64K overflow for 16 bit systems).
- * prev[] will be initialized on the fly.
- */
-#define CLEAR_HASH(s) \
- s->head[s->hash_size-1] = NIL; \
- zmemzero((Bytef *)s->head, (unsigned)(s->hash_size-1)*sizeof(*s->head));
-
-/* ========================================================================= */
-int ZEXPORT deflateInit_(strm, level, version, stream_size)
- z_streamp strm;
- int level;
- const char *version;
- int stream_size;
-{
- return deflateInit2_(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL,
- Z_DEFAULT_STRATEGY, version, stream_size);
- /* To do: ignore strm->next_in if we use it as window */
-}
-
-/* ========================================================================= */
-int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy,
- version, stream_size)
- z_streamp strm;
- int level;
- int method;
- int windowBits;
- int memLevel;
- int strategy;
- const char *version;
- int stream_size;
-{
- deflate_state *s;
- int wrap = 1;
- static const char my_version[] = ZLIB_VERSION;
-
- ushf *overlay;
- /* We overlay pending_buf and d_buf+l_buf. This works since the average
- * output size for (length,distance) codes is <= 24 bits.
- */
-
- if (version == Z_NULL || version[0] != my_version[0] ||
- stream_size != sizeof(z_stream)) {
- return Z_VERSION_ERROR;
- }
- if (strm == Z_NULL) return Z_STREAM_ERROR;
-
- strm->msg = Z_NULL;
- if (strm->zalloc == (alloc_func)0) {
- strm->zalloc = zcalloc;
- strm->opaque = (voidpf)0;
- }
- if (strm->zfree == (free_func)0) strm->zfree = zcfree;
-
-#ifdef FASTEST
- if (level != 0) level = 1;
-#else
- if (level == Z_DEFAULT_COMPRESSION) level = 6;
-#endif
-
- if (windowBits < 0) { /* suppress zlib wrapper */
- wrap = 0;
- windowBits = -windowBits;
- }
-#ifdef GZIP
- else if (windowBits > 15) {
- wrap = 2; /* write gzip wrapper instead */
- windowBits -= 16;
- }
-#endif
- if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED ||
- windowBits < 8 || windowBits > 15 || level < 0 || level > 9 ||
- strategy < 0 || strategy > Z_FIXED) {
- return Z_STREAM_ERROR;
- }
- if (windowBits == 8) windowBits = 9; /* until 256-byte window bug fixed */
- s = (deflate_state *) ZALLOC(strm, 1, sizeof(deflate_state));
- if (s == Z_NULL) return Z_MEM_ERROR;
- strm->state = (struct internal_state FAR *)s;
- s->strm = strm;
-
- s->wrap = wrap;
- s->gzhead = Z_NULL;
- s->w_bits = windowBits;
- s->w_size = 1 << s->w_bits;
- s->w_mask = s->w_size - 1;
-
- s->hash_bits = memLevel + 7;
- s->hash_size = 1 << s->hash_bits;
- s->hash_mask = s->hash_size - 1;
- s->hash_shift = ((s->hash_bits+MIN_MATCH-1)/MIN_MATCH);
-
- s->window = (Bytef *) ZALLOC(strm, s->w_size, 2*sizeof(Byte));
- s->prev = (Posf *) ZALLOC(strm, s->w_size, sizeof(Pos));
- s->head = (Posf *) ZALLOC(strm, s->hash_size, sizeof(Pos));
-
- s->lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */
-
- overlay = (ushf *) ZALLOC(strm, s->lit_bufsize, sizeof(ush)+2);
- s->pending_buf = (uchf *) overlay;
- s->pending_buf_size = (ulg)s->lit_bufsize * (sizeof(ush)+2L);
-
- if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL ||
- s->pending_buf == Z_NULL) {
- s->status = FINISH_STATE;
- strm->msg = (char*)ERR_MSG(Z_MEM_ERROR);
- deflateEnd (strm);
- return Z_MEM_ERROR;
- }
- s->d_buf = overlay + s->lit_bufsize/sizeof(ush);
- s->l_buf = s->pending_buf + (1+sizeof(ush))*s->lit_bufsize;
-
- s->level = level;
- s->strategy = strategy;
- s->method = (Byte)method;
-
- return deflateReset(strm);
-}
-
-/* ========================================================================= */
-int ZEXPORT deflateSetDictionary (strm, dictionary, dictLength)
- z_streamp strm;
- const Bytef *dictionary;
- uInt dictLength;
-{
- deflate_state *s;
- uInt length = dictLength;
- uInt n;
- IPos hash_head = 0;
-
- if (strm == Z_NULL || strm->state == Z_NULL || dictionary == Z_NULL ||
- strm->state->wrap == 2 ||
- (strm->state->wrap == 1 && strm->state->status != INIT_STATE))
- return Z_STREAM_ERROR;
-
- s = strm->state;
- if (s->wrap)
- strm->adler = adler32(strm->adler, dictionary, dictLength);
-
- if (length < MIN_MATCH) return Z_OK;
- if (length > MAX_DIST(s)) {
- length = MAX_DIST(s);
- dictionary += dictLength - length; /* use the tail of the dictionary */
- }
- zmemcpy(s->window, dictionary, length);
- s->strstart = length;
- s->block_start = (long)length;
-
- /* Insert all strings in the hash table (except for the last two bytes).
- * s->lookahead stays null, so s->ins_h will be recomputed at the next
- * call of fill_window.
- */
- s->ins_h = s->window[0];
- UPDATE_HASH(s, s->ins_h, s->window[1]);
- for (n = 0; n <= length - MIN_MATCH; n++) {
- INSERT_STRING(s, n, hash_head);
- }
- if (hash_head) hash_head = 0; /* to make compiler happy */
- return Z_OK;
-}
-
-/* ========================================================================= */
-int ZEXPORT deflateReset (strm)
- z_streamp strm;
-{
- deflate_state *s;
-
- if (strm == Z_NULL || strm->state == Z_NULL ||
- strm->zalloc == (alloc_func)0 || strm->zfree == (free_func)0) {
- return Z_STREAM_ERROR;
- }
-
- strm->total_in = strm->total_out = 0;
- strm->msg = Z_NULL; /* use zfree if we ever allocate msg dynamically */
- strm->data_type = Z_UNKNOWN;
-
- s = (deflate_state *)strm->state;
- s->pending = 0;
- s->pending_out = s->pending_buf;
-
- if (s->wrap < 0) {
- s->wrap = -s->wrap; /* was made negative by deflate(..., Z_FINISH); */
- }
- s->status = s->wrap ? INIT_STATE : BUSY_STATE;
- strm->adler =
-#ifdef GZIP
- s->wrap == 2 ? crc32(0L, Z_NULL, 0) :
-#endif
- adler32(0L, Z_NULL, 0);
- s->last_flush = Z_NO_FLUSH;
-
- _tr_init(s);
- lm_init(s);
-
- return Z_OK;
-}
-
-/* ========================================================================= */
-int ZEXPORT deflateSetHeader (strm, head)
- z_streamp strm;
- gz_headerp head;
-{
- if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
- if (strm->state->wrap != 2) return Z_STREAM_ERROR;
- strm->state->gzhead = head;
- return Z_OK;
-}
-
-/* ========================================================================= */
-int ZEXPORT deflatePrime (strm, bits, value)
- z_streamp strm;
- int bits;
- int value;
-{
- if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
- strm->state->bi_valid = bits;
- strm->state->bi_buf = (ush)(value & ((1 << bits) - 1));
- return Z_OK;
-}
-
-/* ========================================================================= */
-int ZEXPORT deflateParams(strm, level, strategy)
- z_streamp strm;
- int level;
- int strategy;
-{
- deflate_state *s;
- compress_func func;
- int err = Z_OK;
-
- if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
- s = strm->state;
-
-#ifdef FASTEST
- if (level != 0) level = 1;
-#else
- if (level == Z_DEFAULT_COMPRESSION) level = 6;
-#endif
- if (level < 0 || level > 9 || strategy < 0 || strategy > Z_FIXED) {
- return Z_STREAM_ERROR;
- }
- func = configuration_table[s->level].func;
-
- if (func != configuration_table[level].func && strm->total_in != 0) {
- /* Flush the last buffer: */
- err = deflate(strm, Z_PARTIAL_FLUSH);
- }
- if (s->level != level) {
- s->level = level;
- s->max_lazy_match = configuration_table[level].max_lazy;
- s->good_match = configuration_table[level].good_length;
- s->nice_match = configuration_table[level].nice_length;
- s->max_chain_length = configuration_table[level].max_chain;
- }
- s->strategy = strategy;
- return err;
-}
-
-/* ========================================================================= */
-int ZEXPORT deflateTune(strm, good_length, max_lazy, nice_length, max_chain)
- z_streamp strm;
- int good_length;
- int max_lazy;
- int nice_length;
- int max_chain;
-{
- deflate_state *s;
-
- if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
- s = strm->state;
- s->good_match = good_length;
- s->max_lazy_match = max_lazy;
- s->nice_match = nice_length;
- s->max_chain_length = max_chain;
- return Z_OK;
-}
-
-/* =========================================================================
- * For the default windowBits of 15 and memLevel of 8, this function returns
- * a close to exact, as well as small, upper bound on the compressed size.
- * They are coded as constants here for a reason--if the #define's are
- * changed, then this function needs to be changed as well. The return
- * value for 15 and 8 only works for those exact settings.
- *
- * For any setting other than those defaults for windowBits and memLevel,
- * the value returned is a conservative worst case for the maximum expansion
- * resulting from using fixed blocks instead of stored blocks, which deflate
- * can emit on compressed data for some combinations of the parameters.
- *
- * This function could be more sophisticated to provide closer upper bounds
- * for every combination of windowBits and memLevel, as well as wrap.
- * But even the conservative upper bound of about 14% expansion does not
- * seem onerous for output buffer allocation.
- */
-uLong ZEXPORT deflateBound(strm, sourceLen)
- z_streamp strm;
- uLong sourceLen;
-{
- deflate_state *s;
- uLong destLen;
-
- /* conservative upper bound */
- destLen = sourceLen +
- ((sourceLen + 7) >> 3) + ((sourceLen + 63) >> 6) + 11;
-
- /* if can't get parameters, return conservative bound */
- if (strm == Z_NULL || strm->state == Z_NULL)
- return destLen;
-
- /* if not default parameters, return conservative bound */
- s = strm->state;
- if (s->w_bits != 15 || s->hash_bits != 8 + 7)
- return destLen;
-
- /* default settings: return tight bound for that case */
- return compressBound(sourceLen);
-}
-
-/* =========================================================================
- * Put a short in the pending buffer. The 16-bit value is put in MSB order.
- * IN assertion: the stream state is correct and there is enough room in
- * pending_buf.
- */
-local void putShortMSB (s, b)
- deflate_state *s;
- uInt b;
-{
- put_byte(s, (Byte)(b >> 8));
- put_byte(s, (Byte)(b & 0xff));
-}
-
-/* =========================================================================
- * Flush as much pending output as possible. All deflate() output goes
- * through this function so some applications may wish to modify it
- * to avoid allocating a large strm->next_out buffer and copying into it.
- * (See also read_buf()).
- */
-local void flush_pending(strm)
- z_streamp strm;
-{
- unsigned len = strm->state->pending;
-
- if (len > strm->avail_out) len = strm->avail_out;
- if (len == 0) return;
-
- zmemcpy(strm->next_out, strm->state->pending_out, len);
- strm->next_out += len;
- strm->state->pending_out += len;
- strm->total_out += len;
- strm->avail_out -= len;
- strm->state->pending -= len;
- if (strm->state->pending == 0) {
- strm->state->pending_out = strm->state->pending_buf;
- }
-}
-
-/* ========================================================================= */
-int ZEXPORT deflate (strm, flush)
- z_streamp strm;
- int flush;
-{
- int old_flush; /* value of flush param for previous deflate call */
- deflate_state *s;
-
- if (strm == Z_NULL || strm->state == Z_NULL ||
- flush > Z_FINISH || flush < 0) {
- return Z_STREAM_ERROR;
- }
- s = strm->state;
-
- if (strm->next_out == Z_NULL ||
- (strm->next_in == Z_NULL && strm->avail_in != 0) ||
- (s->status == FINISH_STATE && flush != Z_FINISH)) {
- ERR_RETURN(strm, Z_STREAM_ERROR);
- }
- if (strm->avail_out == 0) ERR_RETURN(strm, Z_BUF_ERROR);
-
- s->strm = strm; /* just in case */
- old_flush = s->last_flush;
- s->last_flush = flush;
-
- /* Write the header */
- if (s->status == INIT_STATE) {
-#ifdef GZIP
- if (s->wrap == 2) {
- strm->adler = crc32(0L, Z_NULL, 0);
- put_byte(s, 31);
- put_byte(s, 139);
- put_byte(s, 8);
- if (s->gzhead == NULL) {
- put_byte(s, 0);
- put_byte(s, 0);
- put_byte(s, 0);
- put_byte(s, 0);
- put_byte(s, 0);
- put_byte(s, s->level == 9 ? 2 :
- (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ?
- 4 : 0));
- put_byte(s, OS_CODE);
- s->status = BUSY_STATE;
- }
- else {
- put_byte(s, (s->gzhead->text ? 1 : 0) +
- (s->gzhead->hcrc ? 2 : 0) +
- (s->gzhead->extra == Z_NULL ? 0 : 4) +
- (s->gzhead->name == Z_NULL ? 0 : 8) +
- (s->gzhead->comment == Z_NULL ? 0 : 16)
- );
- put_byte(s, (Byte)(s->gzhead->time & 0xff));
- put_byte(s, (Byte)((s->gzhead->time >> 8) & 0xff));
- put_byte(s, (Byte)((s->gzhead->time >> 16) & 0xff));
- put_byte(s, (Byte)((s->gzhead->time >> 24) & 0xff));
- put_byte(s, s->level == 9 ? 2 :
- (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ?
- 4 : 0));
- put_byte(s, s->gzhead->os & 0xff);
- if (s->gzhead->extra != NULL) {
- put_byte(s, s->gzhead->extra_len & 0xff);
- put_byte(s, (s->gzhead->extra_len >> 8) & 0xff);
- }
- if (s->gzhead->hcrc)
- strm->adler = crc32(strm->adler, s->pending_buf,
- s->pending);
- s->gzindex = 0;
- s->status = EXTRA_STATE;
- }
- }
- else
-#endif
- {
- uInt header = (Z_DEFLATED + ((s->w_bits-8)<<4)) << 8;
- uInt level_flags;
-
- if (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2)
- level_flags = 0;
- else if (s->level < 6)
- level_flags = 1;
- else if (s->level == 6)
- level_flags = 2;
- else
- level_flags = 3;
- header |= (level_flags << 6);
- if (s->strstart != 0) header |= PRESET_DICT;
- header += 31 - (header % 31);
-
- s->status = BUSY_STATE;
- putShortMSB(s, header);
-
- /* Save the adler32 of the preset dictionary: */
- if (s->strstart != 0) {
- putShortMSB(s, (uInt)(strm->adler >> 16));
- putShortMSB(s, (uInt)(strm->adler & 0xffff));
- }
- strm->adler = adler32(0L, Z_NULL, 0);
- }
- }
-#ifdef GZIP
- if (s->status == EXTRA_STATE) {
- if (s->gzhead->extra != NULL) {
- uInt beg = s->pending; /* start of bytes to update crc */
-
- while (s->gzindex < (s->gzhead->extra_len & 0xffff)) {
- if (s->pending == s->pending_buf_size) {
- if (s->gzhead->hcrc && s->pending > beg)
- strm->adler = crc32(strm->adler, s->pending_buf + beg,
- s->pending - beg);
- flush_pending(strm);
- beg = s->pending;
- if (s->pending == s->pending_buf_size)
- break;
- }
- put_byte(s, s->gzhead->extra[s->gzindex]);
- s->gzindex++;
- }
- if (s->gzhead->hcrc && s->pending > beg)
- strm->adler = crc32(strm->adler, s->pending_buf + beg,
- s->pending - beg);
- if (s->gzindex == s->gzhead->extra_len) {
- s->gzindex = 0;
- s->status = NAME_STATE;
- }
- }
- else
- s->status = NAME_STATE;
- }
- if (s->status == NAME_STATE) {
- if (s->gzhead->name != NULL) {
- uInt beg = s->pending; /* start of bytes to update crc */
- int val;
-
- do {
- if (s->pending == s->pending_buf_size) {
- if (s->gzhead->hcrc && s->pending > beg)
- strm->adler = crc32(strm->adler, s->pending_buf + beg,
- s->pending - beg);
- flush_pending(strm);
- beg = s->pending;
- if (s->pending == s->pending_buf_size) {
- val = 1;
- break;
- }
- }
- val = s->gzhead->name[s->gzindex++];
- put_byte(s, val);
- } while (val != 0);
- if (s->gzhead->hcrc && s->pending > beg)
- strm->adler = crc32(strm->adler, s->pending_buf + beg,
- s->pending - beg);
- if (val == 0) {
- s->gzindex = 0;
- s->status = COMMENT_STATE;
- }
- }
- else
- s->status = COMMENT_STATE;
- }
- if (s->status == COMMENT_STATE) {
- if (s->gzhead->comment != NULL) {
- uInt beg = s->pending; /* start of bytes to update crc */
- int val;
-
- do {
- if (s->pending == s->pending_buf_size) {
- if (s->gzhead->hcrc && s->pending > beg)
- strm->adler = crc32(strm->adler, s->pending_buf + beg,
- s->pending - beg);
- flush_pending(strm);
- beg = s->pending;
- if (s->pending == s->pending_buf_size) {
- val = 1;
- break;
- }
- }
- val = s->gzhead->comment[s->gzindex++];
- put_byte(s, val);
- } while (val != 0);
- if (s->gzhead->hcrc && s->pending > beg)
- strm->adler = crc32(strm->adler, s->pending_buf + beg,
- s->pending - beg);
- if (val == 0)
- s->status = HCRC_STATE;
- }
- else
- s->status = HCRC_STATE;
- }
- if (s->status == HCRC_STATE) {
- if (s->gzhead->hcrc) {
- if (s->pending + 2 > s->pending_buf_size)
- flush_pending(strm);
- if (s->pending + 2 <= s->pending_buf_size) {
- put_byte(s, (Byte)(strm->adler & 0xff));
- put_byte(s, (Byte)((strm->adler >> 8) & 0xff));
- strm->adler = crc32(0L, Z_NULL, 0);
- s->status = BUSY_STATE;
- }
- }
- else
- s->status = BUSY_STATE;
- }
-#endif
-
- /* Flush as much pending output as possible */
- if (s->pending != 0) {
- flush_pending(strm);
- if (strm->avail_out == 0) {
- /* Since avail_out is 0, deflate will be called again with
- * more output space, but possibly with both pending and
- * avail_in equal to zero. There won't be anything to do,
- * but this is not an error situation so make sure we
- * return OK instead of BUF_ERROR at next call of deflate:
- */
- s->last_flush = -1;
- return Z_OK;
- }
-
- /* Make sure there is something to do and avoid duplicate consecutive
- * flushes. For repeated and useless calls with Z_FINISH, we keep
- * returning Z_STREAM_END instead of Z_BUF_ERROR.
- */
- } else if (strm->avail_in == 0 && flush <= old_flush &&
- flush != Z_FINISH) {
- ERR_RETURN(strm, Z_BUF_ERROR);
- }
-
- /* User must not provide more input after the first FINISH: */
- if (s->status == FINISH_STATE && strm->avail_in != 0) {
- ERR_RETURN(strm, Z_BUF_ERROR);
- }
-
- /* Start a new block or continue the current one.
- */
- if (strm->avail_in != 0 || s->lookahead != 0 ||
- (flush != Z_NO_FLUSH && s->status != FINISH_STATE)) {
- block_state bstate;
-
- bstate = (*(configuration_table[s->level].func))(s, flush);
-
- if (bstate == finish_started || bstate == finish_done) {
- s->status = FINISH_STATE;
- }
- if (bstate == need_more || bstate == finish_started) {
- if (strm->avail_out == 0) {
- s->last_flush = -1; /* avoid BUF_ERROR next call, see above */
- }
- return Z_OK;
- /* If flush != Z_NO_FLUSH && avail_out == 0, the next call
- * of deflate should use the same flush parameter to make sure
- * that the flush is complete. So we don't have to output an
- * empty block here, this will be done at next call. This also
- * ensures that for a very small output buffer, we emit at most
- * one empty block.
- */
- }
- if (bstate == block_done) {
- if (flush == Z_PARTIAL_FLUSH) {
- _tr_align(s);
- } else { /* FULL_FLUSH or SYNC_FLUSH */
- _tr_stored_block(s, (char*)0, 0L, 0);
- /* For a full flush, this empty block will be recognized
- * as a special marker by inflate_sync().
- */
- if (flush == Z_FULL_FLUSH) {
- CLEAR_HASH(s); /* forget history */
- }
- }
- flush_pending(strm);
- if (strm->avail_out == 0) {
- s->last_flush = -1; /* avoid BUF_ERROR at next call, see above */
- return Z_OK;
- }
- }
- }
- Assert(strm->avail_out > 0, "bug2");
-
- if (flush != Z_FINISH) return Z_OK;
- if (s->wrap <= 0) return Z_STREAM_END;
-
- /* Write the trailer */
-#ifdef GZIP
- if (s->wrap == 2) {
- put_byte(s, (Byte)(strm->adler & 0xff));
- put_byte(s, (Byte)((strm->adler >> 8) & 0xff));
- put_byte(s, (Byte)((strm->adler >> 16) & 0xff));
- put_byte(s, (Byte)((strm->adler >> 24) & 0xff));
- put_byte(s, (Byte)(strm->total_in & 0xff));
- put_byte(s, (Byte)((strm->total_in >> 8) & 0xff));
- put_byte(s, (Byte)((strm->total_in >> 16) & 0xff));
- put_byte(s, (Byte)((strm->total_in >> 24) & 0xff));
- }
- else
-#endif
- {
- putShortMSB(s, (uInt)(strm->adler >> 16));
- putShortMSB(s, (uInt)(strm->adler & 0xffff));
- }
- flush_pending(strm);
- /* If avail_out is zero, the application will call deflate again
- * to flush the rest.
- */
- if (s->wrap > 0) s->wrap = -s->wrap; /* write the trailer only once! */
- return s->pending != 0 ? Z_OK : Z_STREAM_END;
-}
-
-/* ========================================================================= */
-int ZEXPORT deflateEnd (strm)
- z_streamp strm;
-{
- int status;
-
- if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
-
- status = strm->state->status;
- if (status != INIT_STATE &&
- status != EXTRA_STATE &&
- status != NAME_STATE &&
- status != COMMENT_STATE &&
- status != HCRC_STATE &&
- status != BUSY_STATE &&
- status != FINISH_STATE) {
- return Z_STREAM_ERROR;
- }
-
- /* Deallocate in reverse order of allocations: */
- TRY_FREE(strm, strm->state->pending_buf);
- TRY_FREE(strm, strm->state->head);
- TRY_FREE(strm, strm->state->prev);
- TRY_FREE(strm, strm->state->window);
-
- ZFREE(strm, strm->state);
- strm->state = Z_NULL;
-
- return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK;
-}
-
-/* =========================================================================
- * Copy the source state to the destination state.
- * To simplify the source, this is not supported for 16-bit MSDOS (which
- * doesn't have enough memory anyway to duplicate compression states).
- */
-int ZEXPORT deflateCopy (dest, source)
- z_streamp dest;
- z_streamp source;
-{
-#ifdef MAXSEG_64K
- return Z_STREAM_ERROR;
-#else
- deflate_state *ds;
- deflate_state *ss;
- ushf *overlay;
-
-
- if (source == Z_NULL || dest == Z_NULL || source->state == Z_NULL) {
- return Z_STREAM_ERROR;
- }
-
- ss = source->state;
-
- zmemcpy(dest, source, sizeof(z_stream));
-
- ds = (deflate_state *) ZALLOC(dest, 1, sizeof(deflate_state));
- if (ds == Z_NULL) return Z_MEM_ERROR;
- dest->state = (struct internal_state FAR *) ds;
- zmemcpy(ds, ss, sizeof(deflate_state));
- ds->strm = dest;
-
- ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte));
- ds->prev = (Posf *) ZALLOC(dest, ds->w_size, sizeof(Pos));
- ds->head = (Posf *) ZALLOC(dest, ds->hash_size, sizeof(Pos));
- overlay = (ushf *) ZALLOC(dest, ds->lit_bufsize, sizeof(ush)+2);
- ds->pending_buf = (uchf *) overlay;
-
- if (ds->window == Z_NULL || ds->prev == Z_NULL || ds->head == Z_NULL ||
- ds->pending_buf == Z_NULL) {
- deflateEnd (dest);
- return Z_MEM_ERROR;
- }
- /* following zmemcpy do not work for 16-bit MSDOS */
- zmemcpy(ds->window, ss->window, ds->w_size * 2 * sizeof(Byte));
- zmemcpy(ds->prev, ss->prev, ds->w_size * sizeof(Pos));
- zmemcpy(ds->head, ss->head, ds->hash_size * sizeof(Pos));
- zmemcpy(ds->pending_buf, ss->pending_buf, (uInt)ds->pending_buf_size);
-
- ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf);
- ds->d_buf = overlay + ds->lit_bufsize/sizeof(ush);
- ds->l_buf = ds->pending_buf + (1+sizeof(ush))*ds->lit_bufsize;
-
- ds->l_desc.dyn_tree = ds->dyn_ltree;
- ds->d_desc.dyn_tree = ds->dyn_dtree;
- ds->bl_desc.dyn_tree = ds->bl_tree;
-
- return Z_OK;
-#endif /* MAXSEG_64K */
-}
-
-/* ===========================================================================
- * Read a new buffer from the current input stream, update the adler32
- * and total number of bytes read. All deflate() input goes through
- * this function so some applications may wish to modify it to avoid
- * allocating a large strm->next_in buffer and copying from it.
- * (See also flush_pending()).
- */
-local int read_buf(strm, buf, size)
- z_streamp strm;
- Bytef *buf;
- unsigned size;
-{
- unsigned len = strm->avail_in;
-
- if (len > size) len = size;
- if (len == 0) return 0;
-
- strm->avail_in -= len;
-
- if (strm->state->wrap == 1) {
- strm->adler = adler32(strm->adler, strm->next_in, len);
- }
-#ifdef GZIP
- else if (strm->state->wrap == 2) {
- strm->adler = crc32(strm->adler, strm->next_in, len);
- }
-#endif
- zmemcpy(buf, strm->next_in, len);
- strm->next_in += len;
- strm->total_in += len;
-
- return (int)len;
-}
-
-/* ===========================================================================
- * Initialize the "longest match" routines for a new zlib stream
- */
-local void lm_init (s)
- deflate_state *s;
-{
- s->window_size = (ulg)2L*s->w_size;
-
- CLEAR_HASH(s);
-
- /* Set the default configuration parameters:
- */
- s->max_lazy_match = configuration_table[s->level].max_lazy;
- s->good_match = configuration_table[s->level].good_length;
- s->nice_match = configuration_table[s->level].nice_length;
- s->max_chain_length = configuration_table[s->level].max_chain;
-
- s->strstart = 0;
- s->block_start = 0L;
- s->lookahead = 0;
- s->match_length = s->prev_length = MIN_MATCH-1;
- s->match_available = 0;
- s->ins_h = 0;
-#ifndef FASTEST
-#ifdef ASMV
- match_init(); /* initialize the asm code */
-#endif
-#endif
-}
-
-#ifndef FASTEST
-/* ===========================================================================
- * Set match_start to the longest match starting at the given string and
- * return its length. Matches shorter or equal to prev_length are discarded,
- * in which case the result is equal to prev_length and match_start is
- * garbage.
- * IN assertions: cur_match is the head of the hash chain for the current
- * string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1
- * OUT assertion: the match length is not greater than s->lookahead.
- */
-#ifndef ASMV
-/* For 80x86 and 680x0, an optimized version will be provided in match.asm or
- * match.S. The code will be functionally equivalent.
- */
-local uInt longest_match(s, cur_match)
- deflate_state *s;
- IPos cur_match; /* current match */
-{
- unsigned chain_length = s->max_chain_length;/* max hash chain length */
- register Bytef *scan = s->window + s->strstart; /* current string */
- register Bytef *match; /* matched string */
- register int len; /* length of current match */
- int best_len = s->prev_length; /* best match length so far */
- int nice_match = s->nice_match; /* stop if match long enough */
- IPos limit = s->strstart > (IPos)MAX_DIST(s) ?
- s->strstart - (IPos)MAX_DIST(s) : NIL;
- /* Stop when cur_match becomes <= limit. To simplify the code,
- * we prevent matches with the string of window index 0.
- */
- Posf *prev = s->prev;
- uInt wmask = s->w_mask;
-
-#ifdef UNALIGNED_OK
- /* Compare two bytes at a time. Note: this is not always beneficial.
- * Try with and without -DUNALIGNED_OK to check.
- */
- register Bytef *strend = s->window + s->strstart + MAX_MATCH - 1;
- register ush scan_start = *(ushf*)scan;
- register ush scan_end = *(ushf*)(scan+best_len-1);
-#else
- register Bytef *strend = s->window + s->strstart + MAX_MATCH;
- register Byte scan_end1 = scan[best_len-1];
- register Byte scan_end = scan[best_len];
-#endif
-
- /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.
- * It is easy to get rid of this optimization if necessary.
- */
- Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever");
-
- /* Do not waste too much time if we already have a good match: */
- if (s->prev_length >= s->good_match) {
- chain_length >>= 2;
- }
- /* Do not look for matches beyond the end of the input. This is necessary
- * to make deflate deterministic.
- */
- if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead;
-
- Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead");
-
- do {
- Assert(cur_match < s->strstart, "no future");
- match = s->window + cur_match;
-
- /* Skip to next match if the match length cannot increase
- * or if the match length is less than 2. Note that the checks below
- * for insufficient lookahead only occur occasionally for performance
- * reasons. Therefore uninitialized memory will be accessed, and
- * conditional jumps will be made that depend on those values.
- * However the length of the match is limited to the lookahead, so
- * the output of deflate is not affected by the uninitialized values.
- */
-#if (defined(UNALIGNED_OK) && MAX_MATCH == 258)
- /* This code assumes sizeof(unsigned short) == 2. Do not use
- * UNALIGNED_OK if your compiler uses a different size.
- */
- if (*(ushf*)(match+best_len-1) != scan_end ||
- *(ushf*)match != scan_start) continue;
-
- /* It is not necessary to compare scan[2] and match[2] since they are
- * always equal when the other bytes match, given that the hash keys
- * are equal and that HASH_BITS >= 8. Compare 2 bytes at a time at
- * strstart+3, +5, ... up to strstart+257. We check for insufficient
- * lookahead only every 4th comparison; the 128th check will be made
- * at strstart+257. If MAX_MATCH-2 is not a multiple of 8, it is
- * necessary to put more guard bytes at the end of the window, or
- * to check more often for insufficient lookahead.
- */
- Assert(scan[2] == match[2], "scan[2]?");
- scan++, match++;
- do {
- } while (*(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
- *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
- *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
- *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
- scan < strend);
- /* The funny "do {}" generates better code on most compilers */
-
- /* Here, scan <= window+strstart+257 */
- Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
- if (*scan == *match) scan++;
-
- len = (MAX_MATCH - 1) - (int)(strend-scan);
- scan = strend - (MAX_MATCH-1);
-
-#else /* UNALIGNED_OK */
-
- if (match[best_len] != scan_end ||
- match[best_len-1] != scan_end1 ||
- *match != *scan ||
- *++match != scan[1]) continue;
-
- /* The check at best_len-1 can be removed because it will be made
- * again later. (This heuristic is not always a win.)
- * It is not necessary to compare scan[2] and match[2] since they
- * are always equal when the other bytes match, given that
- * the hash keys are equal and that HASH_BITS >= 8.
- */
- scan += 2, match++;
- Assert(*scan == *match, "match[2]?");
-
- /* We check for insufficient lookahead only every 8th comparison;
- * the 256th check will be made at strstart+258.
- */
- do {
- } while (*++scan == *++match && *++scan == *++match &&
- *++scan == *++match && *++scan == *++match &&
- *++scan == *++match && *++scan == *++match &&
- *++scan == *++match && *++scan == *++match &&
- scan < strend);
-
- Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
-
- len = MAX_MATCH - (int)(strend - scan);
- scan = strend - MAX_MATCH;
-
-#endif /* UNALIGNED_OK */
-
- if (len > best_len) {
- s->match_start = cur_match;
- best_len = len;
- if (len >= nice_match) break;
-#ifdef UNALIGNED_OK
- scan_end = *(ushf*)(scan+best_len-1);
-#else
- scan_end1 = scan[best_len-1];
- scan_end = scan[best_len];
-#endif
- }
- } while ((cur_match = prev[cur_match & wmask]) > limit
- && --chain_length != 0);
-
- if ((uInt)best_len <= s->lookahead) return (uInt)best_len;
- return s->lookahead;
-}
-#endif /* ASMV */
-#endif /* FASTEST */
-
-/* ---------------------------------------------------------------------------
- * Optimized version for level == 1 or strategy == Z_RLE only
- */
-local uInt longest_match_fast(s, cur_match)
- deflate_state *s;
- IPos cur_match; /* current match */
-{
- register Bytef *scan = s->window + s->strstart; /* current string */
- register Bytef *match; /* matched string */
- register int len; /* length of current match */
- register Bytef *strend = s->window + s->strstart + MAX_MATCH;
-
- /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.
- * It is easy to get rid of this optimization if necessary.
- */
- Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever");
-
- Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead");
-
- Assert(cur_match < s->strstart, "no future");
-
- match = s->window + cur_match;
-
- /* Return failure if the match length is less than 2:
- */
- if (match[0] != scan[0] || match[1] != scan[1]) return MIN_MATCH-1;
-
- /* The check at best_len-1 can be removed because it will be made
- * again later. (This heuristic is not always a win.)
- * It is not necessary to compare scan[2] and match[2] since they
- * are always equal when the other bytes match, given that
- * the hash keys are equal and that HASH_BITS >= 8.
- */
- scan += 2, match += 2;
- Assert(*scan == *match, "match[2]?");
-
- /* We check for insufficient lookahead only every 8th comparison;
- * the 256th check will be made at strstart+258.
- */
- do {
- } while (*++scan == *++match && *++scan == *++match &&
- *++scan == *++match && *++scan == *++match &&
- *++scan == *++match && *++scan == *++match &&
- *++scan == *++match && *++scan == *++match &&
- scan < strend);
-
- Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
-
- len = MAX_MATCH - (int)(strend - scan);
-
- if (len < MIN_MATCH) return MIN_MATCH - 1;
-
- s->match_start = cur_match;
- return (uInt)len <= s->lookahead ? (uInt)len : s->lookahead;
-}
-
-#ifdef DEBUG
-/* ===========================================================================
- * Check that the match at match_start is indeed a match.
- */
-local void check_match(s, start, match, length)
- deflate_state *s;
- IPos start, match;
- int length;
-{
- /* check that the match is indeed a match */
- if (zmemcmp(s->window + match,
- s->window + start, length) != EQUAL) {
- fprintf(stderr, " start %u, match %u, length %d\n",
- start, match, length);
- do {
- fprintf(stderr, "%c%c", s->window[match++], s->window[start++]);
- } while (--length != 0);
- z_error("invalid match");
- }
- if (z_verbose > 1) {
- fprintf(stderr,"\\[%d,%d]", start-match, length);
- do { putc(s->window[start++], stderr); } while (--length != 0);
- }
-}
-#else
-# define check_match(s, start, match, length)
-#endif /* DEBUG */
-
-/* ===========================================================================
- * Fill the window when the lookahead becomes insufficient.
- * Updates strstart and lookahead.
- *
- * IN assertion: lookahead < MIN_LOOKAHEAD
- * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD
- * At least one byte has been read, or avail_in == 0; reads are
- * performed for at least two bytes (required for the zip translate_eol
- * option -- not supported here).
- */
-local void fill_window(s)
- deflate_state *s;
-{
- register unsigned n, m;
- register Posf *p;
- unsigned more; /* Amount of free space at the end of the window. */
- uInt wsize = s->w_size;
-
- do {
- more = (unsigned)(s->window_size -(ulg)s->lookahead -(ulg)s->strstart);
-
- /* Deal with !@#$% 64K limit: */
- if (sizeof(int) <= 2) {
- if (more == 0 && s->strstart == 0 && s->lookahead == 0) {
- more = wsize;
-
- } else if (more == (unsigned)(-1)) {
- /* Very unlikely, but possible on 16 bit machine if
- * strstart == 0 && lookahead == 1 (input done a byte at time)
- */
- more--;
- }
- }
-
- /* If the window is almost full and there is insufficient lookahead,
- * move the upper half to the lower one to make room in the upper half.
- */
- if (s->strstart >= wsize+MAX_DIST(s)) {
-
- zmemcpy(s->window, s->window+wsize, (unsigned)wsize);
- s->match_start -= wsize;
- s->strstart -= wsize; /* we now have strstart >= MAX_DIST */
- s->block_start -= (long) wsize;
-
- /* Slide the hash table (could be avoided with 32 bit values
- at the expense of memory usage). We slide even when level == 0
- to keep the hash table consistent if we switch back to level > 0
- later. (Using level 0 permanently is not an optimal usage of
- zlib, so we don't care about this pathological case.)
- */
- /* %%% avoid this when Z_RLE */
- n = s->hash_size;
- p = &s->head[n];
- do {
- m = *--p;
- *p = (Pos)(m >= wsize ? m-wsize : NIL);
- } while (--n);
-
- n = wsize;
-#ifndef FASTEST
- p = &s->prev[n];
- do {
- m = *--p;
- *p = (Pos)(m >= wsize ? m-wsize : NIL);
- /* If n is not on any hash chain, prev[n] is garbage but
- * its value will never be used.
- */
- } while (--n);
-#endif
- more += wsize;
- }
- if (s->strm->avail_in == 0) return;
-
- /* If there was no sliding:
- * strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 &&
- * more == window_size - lookahead - strstart
- * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1)
- * => more >= window_size - 2*WSIZE + 2
- * In the BIG_MEM or MMAP case (not yet supported),
- * window_size == input_size + MIN_LOOKAHEAD &&
- * strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD.
- * Otherwise, window_size == 2*WSIZE so more >= 2.
- * If there was sliding, more >= WSIZE. So in all cases, more >= 2.
- */
- Assert(more >= 2, "more < 2");
-
- n = read_buf(s->strm, s->window + s->strstart + s->lookahead, more);
- s->lookahead += n;
-
- /* Initialize the hash value now that we have some input: */
- if (s->lookahead >= MIN_MATCH) {
- s->ins_h = s->window[s->strstart];
- UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]);
-#if MIN_MATCH != 3
- Call UPDATE_HASH() MIN_MATCH-3 more times
-#endif
- }
- /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage,
- * but this is not important since only literal bytes will be emitted.
- */
-
- } while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0);
-}
-
-/* ===========================================================================
- * Flush the current block, with given end-of-file flag.
- * IN assertion: strstart is set to the end of the current match.
- */
-#define FLUSH_BLOCK_ONLY(s, eof) { \
- _tr_flush_block(s, (s->block_start >= 0L ? \
- (charf *)&s->window[(unsigned)s->block_start] : \
- (charf *)Z_NULL), \
- (ulg)((long)s->strstart - s->block_start), \
- (eof)); \
- s->block_start = s->strstart; \
- flush_pending(s->strm); \
- Tracev((stderr,"[FLUSH]")); \
-}
-
-/* Same but force premature exit if necessary. */
-#define FLUSH_BLOCK(s, eof) { \
- FLUSH_BLOCK_ONLY(s, eof); \
- if (s->strm->avail_out == 0) return (eof) ? finish_started : need_more; \
-}
-
-/* ===========================================================================
- * Copy without compression as much as possible from the input stream, return
- * the current block state.
- * This function does not insert new strings in the dictionary since
- * uncompressible data is probably not useful. This function is used
- * only for the level=0 compression option.
- * NOTE: this function should be optimized to avoid extra copying from
- * window to pending_buf.
- */
-local block_state deflate_stored(s, flush)
- deflate_state *s;
- int flush;
-{
- /* Stored blocks are limited to 0xffff bytes, pending_buf is limited
- * to pending_buf_size, and each stored block has a 5 byte header:
- */
- ulg max_block_size = 0xffff;
- ulg max_start;
-
- if (max_block_size > s->pending_buf_size - 5) {
- max_block_size = s->pending_buf_size - 5;
- }
-
- /* Copy as much as possible from input to output: */
- for (;;) {
- /* Fill the window as much as possible: */
- if (s->lookahead <= 1) {
-
- Assert(s->strstart < s->w_size+MAX_DIST(s) ||
- s->block_start >= (long)s->w_size, "slide too late");
-
- fill_window(s);
- if (s->lookahead == 0 && flush == Z_NO_FLUSH) return need_more;
-
- if (s->lookahead == 0) break; /* flush the current block */
- }
- Assert(s->block_start >= 0L, "block gone");
-
- s->strstart += s->lookahead;
- s->lookahead = 0;
-
- /* Emit a stored block if pending_buf will be full: */
- max_start = s->block_start + max_block_size;
- if (s->strstart == 0 || (ulg)s->strstart >= max_start) {
- /* strstart == 0 is possible when wraparound on 16-bit machine */
- s->lookahead = (uInt)(s->strstart - max_start);
- s->strstart = (uInt)max_start;
- FLUSH_BLOCK(s, 0);
- }
- /* Flush if we may have to slide, otherwise block_start may become
- * negative and the data will be gone:
- */
- if (s->strstart - (uInt)s->block_start >= MAX_DIST(s)) {
- FLUSH_BLOCK(s, 0);
- }
- }
- FLUSH_BLOCK(s, flush == Z_FINISH);
- return flush == Z_FINISH ? finish_done : block_done;
-}
-
-/* ===========================================================================
- * Compress as much as possible from the input stream, return the current
- * block state.
- * This function does not perform lazy evaluation of matches and inserts
- * new strings in the dictionary only for unmatched strings or for short
- * matches. It is used only for the fast compression options.
- */
-local block_state deflate_fast(s, flush)
- deflate_state *s;
- int flush;
-{
- IPos hash_head = NIL; /* head of the hash chain */
- int bflush; /* set if current block must be flushed */
-
- for (;;) {
- /* Make sure that we always have enough lookahead, except
- * at the end of the input file. We need MAX_MATCH bytes
- * for the next match, plus MIN_MATCH bytes to insert the
- * string following the next match.
- */
- if (s->lookahead < MIN_LOOKAHEAD) {
- fill_window(s);
- if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) {
- return need_more;
- }
- if (s->lookahead == 0) break; /* flush the current block */
- }
-
- /* Insert the string window[strstart .. strstart+2] in the
- * dictionary, and set hash_head to the head of the hash chain:
- */
- if (s->lookahead >= MIN_MATCH) {
- INSERT_STRING(s, s->strstart, hash_head);
- }
-
- /* Find the longest match, discarding those <= prev_length.
- * At this point we have always match_length < MIN_MATCH
- */
- if (hash_head != NIL && s->strstart - hash_head <= MAX_DIST(s)) {
- /* To simplify the code, we prevent matches with the string
- * of window index 0 (in particular we have to avoid a match
- * of the string with itself at the start of the input file).
- */
-#ifdef FASTEST
- if ((s->strategy != Z_HUFFMAN_ONLY && s->strategy != Z_RLE) ||
- (s->strategy == Z_RLE && s->strstart - hash_head == 1)) {
- s->match_length = longest_match_fast (s, hash_head);
- }
-#else
- if (s->strategy != Z_HUFFMAN_ONLY && s->strategy != Z_RLE) {
- s->match_length = longest_match (s, hash_head);
- } else if (s->strategy == Z_RLE && s->strstart - hash_head == 1) {
- s->match_length = longest_match_fast (s, hash_head);
- }
-#endif
- /* longest_match() or longest_match_fast() sets match_start */
- }
- if (s->match_length >= MIN_MATCH) {
- check_match(s, s->strstart, s->match_start, s->match_length);
-
- _tr_tally_dist(s, s->strstart - s->match_start,
- s->match_length - MIN_MATCH, bflush);
-
- s->lookahead -= s->match_length;
-
- /* Insert new strings in the hash table only if the match length
- * is not too large. This saves time but degrades compression.
- */
-#ifndef FASTEST
- if (s->match_length <= s->max_insert_length &&
- s->lookahead >= MIN_MATCH) {
- s->match_length--; /* string at strstart already in table */
- do {
- s->strstart++;
- INSERT_STRING(s, s->strstart, hash_head);
- /* strstart never exceeds WSIZE-MAX_MATCH, so there are
- * always MIN_MATCH bytes ahead.
- */
- } while (--s->match_length != 0);
- s->strstart++;
- } else
-#endif
- {
- s->strstart += s->match_length;
- s->match_length = 0;
- s->ins_h = s->window[s->strstart];
- UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]);
-#if MIN_MATCH != 3
- Call UPDATE_HASH() MIN_MATCH-3 more times
-#endif
- /* If lookahead < MIN_MATCH, ins_h is garbage, but it does not
- * matter since it will be recomputed at next deflate call.
- */
- }
- } else {
- /* No match, output a literal byte */
- Tracevv((stderr,"%c", s->window[s->strstart]));
- _tr_tally_lit (s, s->window[s->strstart], bflush);
- s->lookahead--;
- s->strstart++;
- }
- if (bflush) FLUSH_BLOCK(s, 0);
- }
- FLUSH_BLOCK(s, flush == Z_FINISH);
- return flush == Z_FINISH ? finish_done : block_done;
-}
-
-#ifndef FASTEST
-/* ===========================================================================
- * Same as above, but achieves better compression. We use a lazy
- * evaluation for matches: a match is finally adopted only if there is
- * no better match at the next window position.
- */
-local block_state deflate_slow(s, flush)
- deflate_state *s;
- int flush;
-{
- IPos hash_head = NIL; /* head of hash chain */
- int bflush; /* set if current block must be flushed */
-
- /* Process the input block. */
- for (;;) {
- /* Make sure that we always have enough lookahead, except
- * at the end of the input file. We need MAX_MATCH bytes
- * for the next match, plus MIN_MATCH bytes to insert the
- * string following the next match.
- */
- if (s->lookahead < MIN_LOOKAHEAD) {
- fill_window(s);
- if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) {
- return need_more;
- }
- if (s->lookahead == 0) break; /* flush the current block */
- }
-
- /* Insert the string window[strstart .. strstart+2] in the
- * dictionary, and set hash_head to the head of the hash chain:
- */
- if (s->lookahead >= MIN_MATCH) {
- INSERT_STRING(s, s->strstart, hash_head);
- }
-
- /* Find the longest match, discarding those <= prev_length.
- */
- s->prev_length = s->match_length, s->prev_match = s->match_start;
- s->match_length = MIN_MATCH-1;
-
- if (hash_head != NIL && s->prev_length < s->max_lazy_match &&
- s->strstart - hash_head <= MAX_DIST(s)) {
- /* To simplify the code, we prevent matches with the string
- * of window index 0 (in particular we have to avoid a match
- * of the string with itself at the start of the input file).
- */
- if (s->strategy != Z_HUFFMAN_ONLY && s->strategy != Z_RLE) {
- s->match_length = longest_match (s, hash_head);
- } else if (s->strategy == Z_RLE && s->strstart - hash_head == 1) {
- s->match_length = longest_match_fast (s, hash_head);
- }
- /* longest_match() or longest_match_fast() sets match_start */
-
- if (s->match_length <= 5 && (s->strategy == Z_FILTERED
-#if TOO_FAR <= 32767
- || (s->match_length == MIN_MATCH &&
- s->strstart - s->match_start > TOO_FAR)
-#endif
- )) {
-
- /* If prev_match is also MIN_MATCH, match_start is garbage
- * but we will ignore the current match anyway.
- */
- s->match_length = MIN_MATCH-1;
- }
- }
- /* If there was a match at the previous step and the current
- * match is not better, output the previous match:
- */
- if (s->prev_length >= MIN_MATCH && s->match_length <= s->prev_length) {
- uInt max_insert = s->strstart + s->lookahead - MIN_MATCH;
- /* Do not insert strings in hash table beyond this. */
-
- check_match(s, s->strstart-1, s->prev_match, s->prev_length);
-
- _tr_tally_dist(s, s->strstart -1 - s->prev_match,
- s->prev_length - MIN_MATCH, bflush);
-
- /* Insert in hash table all strings up to the end of the match.
- * strstart-1 and strstart are already inserted. If there is not
- * enough lookahead, the last two strings are not inserted in
- * the hash table.
- */
- s->lookahead -= s->prev_length-1;
- s->prev_length -= 2;
- do {
- if (++s->strstart <= max_insert) {
- INSERT_STRING(s, s->strstart, hash_head);
- }
- } while (--s->prev_length != 0);
- s->match_available = 0;
- s->match_length = MIN_MATCH-1;
- s->strstart++;
-
- if (bflush) FLUSH_BLOCK(s, 0);
-
- } else if (s->match_available) {
- /* If there was no match at the previous position, output a
- * single literal. If there was a match but the current match
- * is longer, truncate the previous match to a single literal.
- */
- Tracevv((stderr,"%c", s->window[s->strstart-1]));
- _tr_tally_lit(s, s->window[s->strstart-1], bflush);
- if (bflush) {
- FLUSH_BLOCK_ONLY(s, 0);
- }
- s->strstart++;
- s->lookahead--;
- if (s->strm->avail_out == 0) return need_more;
- } else {
- /* There is no previous match to compare with, wait for
- * the next step to decide.
- */
- s->match_available = 1;
- s->strstart++;
- s->lookahead--;
- }
- }
- Assert (flush != Z_NO_FLUSH, "no flush?");
- if (s->match_available) {
- Tracevv((stderr,"%c", s->window[s->strstart-1]));
- _tr_tally_lit(s, s->window[s->strstart-1], bflush);
- s->match_available = 0;
- }
- FLUSH_BLOCK(s, flush == Z_FINISH);
- return flush == Z_FINISH ? finish_done : block_done;
-}
-#endif /* FASTEST */
-
-#if 0
-/* ===========================================================================
- * For Z_RLE, simply look for runs of bytes, generate matches only of distance
- * one. Do not maintain a hash table. (It will be regenerated if this run of
- * deflate switches away from Z_RLE.)
- */
-local block_state deflate_rle(s, flush)
- deflate_state *s;
- int flush;
-{
- int bflush; /* set if current block must be flushed */
- uInt run; /* length of run */
- uInt max; /* maximum length of run */
- uInt prev; /* byte at distance one to match */
- Bytef *scan; /* scan for end of run */
-
- for (;;) {
- /* Make sure that we always have enough lookahead, except
- * at the end of the input file. We need MAX_MATCH bytes
- * for the longest encodable run.
- */
- if (s->lookahead < MAX_MATCH) {
- fill_window(s);
- if (s->lookahead < MAX_MATCH && flush == Z_NO_FLUSH) {
- return need_more;
- }
- if (s->lookahead == 0) break; /* flush the current block */
- }
-
- /* See how many times the previous byte repeats */
- run = 0;
- if (s->strstart > 0) { /* if there is a previous byte, that is */
- max = s->lookahead < MAX_MATCH ? s->lookahead : MAX_MATCH;
- scan = s->window + s->strstart - 1;
- prev = *scan++;
- do {
- if (*scan++ != prev)
- break;
- } while (++run < max);
- }
-
- /* Emit match if have run of MIN_MATCH or longer, else emit literal */
- if (run >= MIN_MATCH) {
- check_match(s, s->strstart, s->strstart - 1, run);
- _tr_tally_dist(s, 1, run - MIN_MATCH, bflush);
- s->lookahead -= run;
- s->strstart += run;
- } else {
- /* No match, output a literal byte */
- Tracevv((stderr,"%c", s->window[s->strstart]));
- _tr_tally_lit (s, s->window[s->strstart], bflush);
- s->lookahead--;
- s->strstart++;
- }
- if (bflush) FLUSH_BLOCK(s, 0);
- }
- FLUSH_BLOCK(s, flush == Z_FINISH);
- return flush == Z_FINISH ? finish_done : block_done;
-}
-#endif
+++ /dev/null
-/* deflate.h -- internal compression state
- * Copyright (C) 1995-2004 Jean-loup Gailly
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* WARNING: this file should *not* be used by applications. It is
- part of the implementation of the compression library and is
- subject to change. Applications should only use zlib.h.
- */
-
-/* @(#) $Id$ */
-
-#ifndef DEFLATE_H
-#define DEFLATE_H
-
-#include "zutil.h"
-
-/* define NO_GZIP when compiling if you want to disable gzip header and
- trailer creation by deflate(). NO_GZIP would be used to avoid linking in
- the crc code when it is not needed. For shared libraries, gzip encoding
- should be left enabled. */
-#ifndef NO_GZIP
-# define GZIP
-#endif
-
-/* ===========================================================================
- * Internal compression state.
- */
-
-#define LENGTH_CODES 29
-/* number of length codes, not counting the special END_BLOCK code */
-
-#define LITERALS 256
-/* number of literal bytes 0..255 */
-
-#define L_CODES (LITERALS+1+LENGTH_CODES)
-/* number of Literal or Length codes, including the END_BLOCK code */
-
-#define D_CODES 30
-/* number of distance codes */
-
-#define BL_CODES 19
-/* number of codes used to transfer the bit lengths */
-
-#define HEAP_SIZE (2*L_CODES+1)
-/* maximum heap size */
-
-#define MAX_BITS 15
-/* All codes must not exceed MAX_BITS bits */
-
-#define INIT_STATE 42
-#define EXTRA_STATE 69
-#define NAME_STATE 73
-#define COMMENT_STATE 91
-#define HCRC_STATE 103
-#define BUSY_STATE 113
-#define FINISH_STATE 666
-/* Stream status */
-
-
-/* Data structure describing a single value and its code string. */
-typedef struct ct_data_s {
- union {
- ush freq; /* frequency count */
- ush code; /* bit string */
- } fc;
- union {
- ush dad; /* father node in Huffman tree */
- ush len; /* length of bit string */
- } dl;
-} FAR ct_data;
-
-#define Freq fc.freq
-#define Code fc.code
-#define Dad dl.dad
-#define Len dl.len
-
-typedef struct static_tree_desc_s static_tree_desc;
-
-typedef struct tree_desc_s {
- ct_data *dyn_tree; /* the dynamic tree */
- int max_code; /* largest code with non zero frequency */
- static_tree_desc *stat_desc; /* the corresponding static tree */
-} FAR tree_desc;
-
-typedef ush Pos;
-typedef Pos FAR Posf;
-typedef unsigned IPos;
-
-/* A Pos is an index in the character window. We use short instead of int to
- * save space in the various tables. IPos is used only for parameter passing.
- */
-
-typedef struct internal_state {
- z_streamp strm; /* pointer back to this zlib stream */
- int status; /* as the name implies */
- Bytef *pending_buf; /* output still pending */
- ulg pending_buf_size; /* size of pending_buf */
- Bytef *pending_out; /* next pending byte to output to the stream */
- uInt pending; /* nb of bytes in the pending buffer */
- int wrap; /* bit 0 true for zlib, bit 1 true for gzip */
- gz_headerp gzhead; /* gzip header information to write */
- uInt gzindex; /* where in extra, name, or comment */
- Byte method; /* STORED (for zip only) or DEFLATED */
- int last_flush; /* value of flush param for previous deflate call */
-
- /* used by deflate.c: */
-
- uInt w_size; /* LZ77 window size (32K by default) */
- uInt w_bits; /* log2(w_size) (8..16) */
- uInt w_mask; /* w_size - 1 */
-
- Bytef *window;
- /* Sliding window. Input bytes are read into the second half of the window,
- * and move to the first half later to keep a dictionary of at least wSize
- * bytes. With this organization, matches are limited to a distance of
- * wSize-MAX_MATCH bytes, but this ensures that IO is always
- * performed with a length multiple of the block size. Also, it limits
- * the window size to 64K, which is quite useful on MSDOS.
- * To do: use the user input buffer as sliding window.
- */
-
- ulg window_size;
- /* Actual size of window: 2*wSize, except when the user input buffer
- * is directly used as sliding window.
- */
-
- Posf *prev;
- /* Link to older string with same hash index. To limit the size of this
- * array to 64K, this link is maintained only for the last 32K strings.
- * An index in this array is thus a window index modulo 32K.
- */
-
- Posf *head; /* Heads of the hash chains or NIL. */
-
- uInt ins_h; /* hash index of string to be inserted */
- uInt hash_size; /* number of elements in hash table */
- uInt hash_bits; /* log2(hash_size) */
- uInt hash_mask; /* hash_size-1 */
-
- uInt hash_shift;
- /* Number of bits by which ins_h must be shifted at each input
- * step. It must be such that after MIN_MATCH steps, the oldest
- * byte no longer takes part in the hash key, that is:
- * hash_shift * MIN_MATCH >= hash_bits
- */
-
- long block_start;
- /* Window position at the beginning of the current output block. Gets
- * negative when the window is moved backwards.
- */
-
- uInt match_length; /* length of best match */
- IPos prev_match; /* previous match */
- int match_available; /* set if previous match exists */
- uInt strstart; /* start of string to insert */
- uInt match_start; /* start of matching string */
- uInt lookahead; /* number of valid bytes ahead in window */
-
- uInt prev_length;
- /* Length of the best match at previous step. Matches not greater than this
- * are discarded. This is used in the lazy match evaluation.
- */
-
- uInt max_chain_length;
- /* To speed up deflation, hash chains are never searched beyond this
- * length. A higher limit improves compression ratio but degrades the
- * speed.
- */
-
- uInt max_lazy_match;
- /* Attempt to find a better match only when the current match is strictly
- * smaller than this value. This mechanism is used only for compression
- * levels >= 4.
- */
-# define max_insert_length max_lazy_match
- /* Insert new strings in the hash table only if the match length is not
- * greater than this length. This saves time but degrades compression.
- * max_insert_length is used only for compression levels <= 3.
- */
-
- int level; /* compression level (1..9) */
- int strategy; /* favor or force Huffman coding*/
-
- uInt good_match;
- /* Use a faster search when the previous match is longer than this */
-
- int nice_match; /* Stop searching when current match exceeds this */
-
- /* used by trees.c: */
- /* Didn't use ct_data typedef below to supress compiler warning */
- struct ct_data_s dyn_ltree[HEAP_SIZE]; /* literal and length tree */
- struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */
- struct ct_data_s bl_tree[2*BL_CODES+1]; /* Huffman tree for bit lengths */
-
- struct tree_desc_s l_desc; /* desc. for literal tree */
- struct tree_desc_s d_desc; /* desc. for distance tree */
- struct tree_desc_s bl_desc; /* desc. for bit length tree */
-
- ush bl_count[MAX_BITS+1];
- /* number of codes at each bit length for an optimal tree */
-
- int heap[2*L_CODES+1]; /* heap used to build the Huffman trees */
- int heap_len; /* number of elements in the heap */
- int heap_max; /* element of largest frequency */
- /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used.
- * The same heap array is used to build all trees.
- */
-
- uch depth[2*L_CODES+1];
- /* Depth of each subtree used as tie breaker for trees of equal frequency
- */
-
- uchf *l_buf; /* buffer for literals or lengths */
-
- uInt lit_bufsize;
- /* Size of match buffer for literals/lengths. There are 4 reasons for
- * limiting lit_bufsize to 64K:
- * - frequencies can be kept in 16 bit counters
- * - if compression is not successful for the first block, all input
- * data is still in the window so we can still emit a stored block even
- * when input comes from standard input. (This can also be done for
- * all blocks if lit_bufsize is not greater than 32K.)
- * - if compression is not successful for a file smaller than 64K, we can
- * even emit a stored file instead of a stored block (saving 5 bytes).
- * This is applicable only for zip (not gzip or zlib).
- * - creating new Huffman trees less frequently may not provide fast
- * adaptation to changes in the input data statistics. (Take for
- * example a binary file with poorly compressible code followed by
- * a highly compressible string table.) Smaller buffer sizes give
- * fast adaptation but have of course the overhead of transmitting
- * trees more frequently.
- * - I can't count above 4
- */
-
- uInt last_lit; /* running index in l_buf */
-
- ushf *d_buf;
- /* Buffer for distances. To simplify the code, d_buf and l_buf have
- * the same number of elements. To use different lengths, an extra flag
- * array would be necessary.
- */
-
- ulg opt_len; /* bit length of current block with optimal trees */
- ulg static_len; /* bit length of current block with static trees */
- uInt matches; /* number of string matches in current block */
- int last_eob_len; /* bit length of EOB code for last block */
-
-#ifdef DEBUG
- ulg compressed_len; /* total bit length of compressed file mod 2^32 */
- ulg bits_sent; /* bit length of compressed data sent mod 2^32 */
-#endif
-
- ush bi_buf;
- /* Output buffer. bits are inserted starting at the bottom (least
- * significant bits).
- */
- int bi_valid;
- /* Number of valid bits in bi_buf. All bits above the last valid bit
- * are always zero.
- */
-
-} FAR deflate_state;
-
-/* Output a byte on the stream.
- * IN assertion: there is enough room in pending_buf.
- */
-#define put_byte(s, c) {s->pending_buf[s->pending++] = (c);}
-
-
-#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1)
-/* Minimum amount of lookahead, except at the end of the input file.
- * See deflate.c for comments about the MIN_MATCH+1.
- */
-
-#define MAX_DIST(s) ((s)->w_size-MIN_LOOKAHEAD)
-/* In order to simplify the code, particularly on 16 bit machines, match
- * distances are limited to MAX_DIST instead of WSIZE.
- */
-
- /* in trees.c */
-void _tr_init OF((deflate_state *s));
-int _tr_tally OF((deflate_state *s, unsigned dist, unsigned lc));
-void _tr_flush_block OF((deflate_state *s, charf *buf, ulg stored_len,
- int eof));
-void _tr_align OF((deflate_state *s));
-void _tr_stored_block OF((deflate_state *s, charf *buf, ulg stored_len,
- int eof));
-
-#define d_code(dist) \
- ((dist) < 256 ? _dist_code[dist] : _dist_code[256+((dist)>>7)])
-/* Mapping from a distance to a distance code. dist is the distance - 1 and
- * must not have side effects. _dist_code[256] and _dist_code[257] are never
- * used.
- */
-
-#ifndef DEBUG
-/* Inline versions of _tr_tally for speed: */
-
-#if defined(GEN_TREES_H) || !defined(STDC)
- extern uch _length_code[];
- extern uch _dist_code[];
-#else
- extern const uch _length_code[];
- extern const uch _dist_code[];
-#endif
-
-# define _tr_tally_lit(s, c, flush) \
- { uch cc = (c); \
- s->d_buf[s->last_lit] = 0; \
- s->l_buf[s->last_lit++] = cc; \
- s->dyn_ltree[cc].Freq++; \
- flush = (s->last_lit == s->lit_bufsize-1); \
- }
-# define _tr_tally_dist(s, distance, length, flush) \
- { uch len = (length); \
- ush dist = (distance); \
- s->d_buf[s->last_lit] = dist; \
- s->l_buf[s->last_lit++] = len; \
- dist--; \
- s->dyn_ltree[_length_code[len]+LITERALS+1].Freq++; \
- s->dyn_dtree[d_code(dist)].Freq++; \
- flush = (s->last_lit == s->lit_bufsize-1); \
- }
-#else
-# define _tr_tally_lit(s, c, flush) flush = _tr_tally(s, 0, c)
-# define _tr_tally_dist(s, distance, length, flush) \
- flush = _tr_tally(s, distance, length)
-#endif
-
-#endif /* DEFLATE_H */
+++ /dev/null
-/* gzio.c -- IO on .gz files
- * Copyright (C) 1995-2005 Jean-loup Gailly.
- * For conditions of distribution and use, see copyright notice in zlib.h
- *
- * Compile this file with -DNO_GZCOMPRESS to avoid the compression code.
- */
-
-/* @(#) $Id$ */
-
-#include <stdio.h>
-
-#include "zutil.h"
-
-#ifdef NO_DEFLATE /* for compatibility with old definition */
-# define NO_GZCOMPRESS
-#endif
-
-#ifndef NO_DUMMY_DECL
-struct internal_state {int dummy;}; /* for buggy compilers */
-#endif
-
-#ifndef Z_BUFSIZE
-# ifdef MAXSEG_64K
-# define Z_BUFSIZE 4096 /* minimize memory usage for 16-bit DOS */
-# else
-# define Z_BUFSIZE 16384
-# endif
-#endif
-#ifndef Z_PRINTF_BUFSIZE
-# define Z_PRINTF_BUFSIZE 4096
-#endif
-
-#ifdef __MVS__
-# pragma map (fdopen , "\174\174FDOPEN")
- FILE *fdopen(int, const char *);
-#endif
-
-#ifndef STDC
-extern voidp malloc OF((uInt size));
-extern void free OF((voidpf ptr));
-#endif
-
-#define ALLOC(size) malloc(size)
-#define TRYFREE(p) {if (p) free(p);}
-
-static int const gz_magic[2] = {0x1f, 0x8b}; /* gzip magic header */
-
-/* gzip flag byte */
-#define ASCII_FLAG 0x01 /* bit 0 set: file probably ascii text */
-#define HEAD_CRC 0x02 /* bit 1 set: header CRC present */
-#define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */
-#define ORIG_NAME 0x08 /* bit 3 set: original file name present */
-#define COMMENT 0x10 /* bit 4 set: file comment present */
-#define RESERVED 0xE0 /* bits 5..7: reserved */
-
-typedef struct gz_stream {
- z_stream stream;
- int z_err; /* error code for last stream operation */
- int z_eof; /* set if end of input file */
- FILE *file; /* .gz file */
- Byte *inbuf; /* input buffer */
- Byte *outbuf; /* output buffer */
- uLong crc; /* crc32 of uncompressed data */
- char *msg; /* error message */
- char *path; /* path name for debugging only */
- int transparent; /* 1 if input file is not a .gz file */
- char mode; /* 'w' or 'r' */
- z_off_t start; /* start of compressed data in file (header skipped) */
- z_off_t in; /* bytes into deflate or inflate */
- z_off_t out; /* bytes out of deflate or inflate */
- int back; /* one character push-back */
- int last; /* true if push-back is last character */
-} gz_stream;
-
-
-local gzFile gz_open OF((const char *path, const char *mode, int fd));
-local int do_flush OF((gzFile file, int flush));
-local int get_byte OF((gz_stream *s));
-local void check_header OF((gz_stream *s));
-local int destroy OF((gz_stream *s));
-local void putLong OF((FILE *file, uLong x));
-local uLong getLong OF((gz_stream *s));
-
-/* ===========================================================================
- Opens a gzip (.gz) file for reading or writing. The mode parameter
- is as in fopen ("rb" or "wb"). The file is given either by file descriptor
- or path name (if fd == -1).
- gz_open returns NULL if the file could not be opened or if there was
- insufficient memory to allocate the (de)compression state; errno
- can be checked to distinguish the two cases (if errno is zero, the
- zlib error is Z_MEM_ERROR).
-*/
-local gzFile gz_open (path, mode, fd)
- const char *path;
- const char *mode;
- int fd;
-{
- int err;
- int level = Z_DEFAULT_COMPRESSION; /* compression level */
- int strategy = Z_DEFAULT_STRATEGY; /* compression strategy */
- char *p = (char*)mode;
- gz_stream *s;
- char fmode[80]; /* copy of mode, without the compression level */
- char *m = fmode;
-
- if (!path || !mode) return Z_NULL;
-
- s = (gz_stream *)ALLOC(sizeof(gz_stream));
- if (!s) return Z_NULL;
-
- s->stream.zalloc = (alloc_func)0;
- s->stream.zfree = (free_func)0;
- s->stream.opaque = (voidpf)0;
- s->stream.next_in = s->inbuf = Z_NULL;
- s->stream.next_out = s->outbuf = Z_NULL;
- s->stream.avail_in = s->stream.avail_out = 0;
- s->file = NULL;
- s->z_err = Z_OK;
- s->z_eof = 0;
- s->in = 0;
- s->out = 0;
- s->back = EOF;
- s->crc = crc32(0L, Z_NULL, 0);
- s->msg = NULL;
- s->transparent = 0;
-
- s->path = (char*)ALLOC(strlen(path)+1);
- if (s->path == NULL) {
- return destroy(s), (gzFile)Z_NULL;
- }
- strcpy(s->path, path); /* do this early for debugging */
-
- s->mode = '\0';
- do {
- if (*p == 'r') s->mode = 'r';
- if (*p == 'w' || *p == 'a') s->mode = 'w';
- if (*p >= '0' && *p <= '9') {
- level = *p - '0';
- } else if (*p == 'f') {
- strategy = Z_FILTERED;
- } else if (*p == 'h') {
- strategy = Z_HUFFMAN_ONLY;
- } else if (*p == 'R') {
- strategy = Z_RLE;
- } else {
- *m++ = *p; /* copy the mode */
- }
- } while (*p++ && m != fmode + sizeof(fmode));
- if (s->mode == '\0') return destroy(s), (gzFile)Z_NULL;
-
- if (s->mode == 'w') {
-#ifdef NO_GZCOMPRESS
- err = Z_STREAM_ERROR;
-#else
- err = deflateInit2(&(s->stream), level,
- Z_DEFLATED, -MAX_WBITS, DEF_MEM_LEVEL, strategy);
- /* windowBits is passed < 0 to suppress zlib header */
-
- s->stream.next_out = s->outbuf = (Byte*)ALLOC(Z_BUFSIZE);
-#endif
- if (err != Z_OK || s->outbuf == Z_NULL) {
- return destroy(s), (gzFile)Z_NULL;
- }
- } else {
- s->stream.next_in = s->inbuf = (Byte*)ALLOC(Z_BUFSIZE);
-
- err = inflateInit2(&(s->stream), -MAX_WBITS);
- /* windowBits is passed < 0 to tell that there is no zlib header.
- * Note that in this case inflate *requires* an extra "dummy" byte
- * after the compressed stream in order to complete decompression and
- * return Z_STREAM_END. Here the gzip CRC32 ensures that 4 bytes are
- * present after the compressed stream.
- */
- if (err != Z_OK || s->inbuf == Z_NULL) {
- return destroy(s), (gzFile)Z_NULL;
- }
- }
- s->stream.avail_out = Z_BUFSIZE;
-
- errno = 0;
- s->file = fd < 0 ? F_OPEN(path, fmode) : (FILE*)fdopen(fd, fmode);
-
- if (s->file == NULL) {
- return destroy(s), (gzFile)Z_NULL;
- }
- if (s->mode == 'w') {
- /* Write a very simple .gz header:
- */
- fprintf(s->file, "%c%c%c%c%c%c%c%c%c%c", gz_magic[0], gz_magic[1],
- Z_DEFLATED, 0 /*flags*/, 0,0,0,0 /*time*/, 0 /*xflags*/, OS_CODE);
- s->start = 10L;
- /* We use 10L instead of ftell(s->file) to because ftell causes an
- * fflush on some systems. This version of the library doesn't use
- * start anyway in write mode, so this initialization is not
- * necessary.
- */
- } else {
- check_header(s); /* skip the .gz header */
- s->start = ftell(s->file) - s->stream.avail_in;
- }
-
- return (gzFile)s;
-}
-
-/* ===========================================================================
- Opens a gzip (.gz) file for reading or writing.
-*/
-gzFile ZEXPORT gzopen (path, mode)
- const char *path;
- const char *mode;
-{
- return gz_open (path, mode, -1);
-}
-
-/* ===========================================================================
- Associate a gzFile with the file descriptor fd. fd is not dup'ed here
- to mimic the behavio(u)r of fdopen.
-*/
-gzFile ZEXPORT gzdopen (fd, mode)
- int fd;
- const char *mode;
-{
- char name[46]; /* allow for up to 128-bit integers */
-
- if (fd < 0) return (gzFile)Z_NULL;
- sprintf(name, "<fd:%d>", fd); /* for debugging */
-
- return gz_open (name, mode, fd);
-}
-
-/* ===========================================================================
- * Update the compression level and strategy
- */
-int ZEXPORT gzsetparams (file, level, strategy)
- gzFile file;
- int level;
- int strategy;
-{
- gz_stream *s = (gz_stream*)file;
-
- if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR;
-
- /* Make room to allow flushing */
- if (s->stream.avail_out == 0) {
-
- s->stream.next_out = s->outbuf;
- if (fwrite(s->outbuf, 1, Z_BUFSIZE, s->file) != Z_BUFSIZE) {
- s->z_err = Z_ERRNO;
- }
- s->stream.avail_out = Z_BUFSIZE;
- }
-
- return deflateParams (&(s->stream), level, strategy);
-}
-
-/* ===========================================================================
- Read a byte from a gz_stream; update next_in and avail_in. Return EOF
- for end of file.
- IN assertion: the stream s has been sucessfully opened for reading.
-*/
-local int get_byte(s)
- gz_stream *s;
-{
- if (s->z_eof) return EOF;
- if (s->stream.avail_in == 0) {
- errno = 0;
- s->stream.avail_in = (uInt)fread(s->inbuf, 1, Z_BUFSIZE, s->file);
- if (s->stream.avail_in == 0) {
- s->z_eof = 1;
- if (ferror(s->file)) s->z_err = Z_ERRNO;
- return EOF;
- }
- s->stream.next_in = s->inbuf;
- }
- s->stream.avail_in--;
- return *(s->stream.next_in)++;
-}
-
-/* ===========================================================================
- Check the gzip header of a gz_stream opened for reading. Set the stream
- mode to transparent if the gzip magic header is not present; set s->err
- to Z_DATA_ERROR if the magic header is present but the rest of the header
- is incorrect.
- IN assertion: the stream s has already been created sucessfully;
- s->stream.avail_in is zero for the first time, but may be non-zero
- for concatenated .gz files.
-*/
-local void check_header(s)
- gz_stream *s;
-{
- int method; /* method byte */
- int flags; /* flags byte */
- uInt len;
- int c;
-
- /* Assure two bytes in the buffer so we can peek ahead -- handle case
- where first byte of header is at the end of the buffer after the last
- gzip segment */
- len = s->stream.avail_in;
- if (len < 2) {
- if (len) s->inbuf[0] = s->stream.next_in[0];
- errno = 0;
- len = (uInt)fread(s->inbuf + len, 1, Z_BUFSIZE >> len, s->file);
- if (len == 0 && ferror(s->file)) s->z_err = Z_ERRNO;
- s->stream.avail_in += len;
- s->stream.next_in = s->inbuf;
- if (s->stream.avail_in < 2) {
- s->transparent = s->stream.avail_in;
- return;
- }
- }
-
- /* Peek ahead to check the gzip magic header */
- if (s->stream.next_in[0] != gz_magic[0] ||
- s->stream.next_in[1] != gz_magic[1]) {
- s->transparent = 1;
- return;
- }
- s->stream.avail_in -= 2;
- s->stream.next_in += 2;
-
- /* Check the rest of the gzip header */
- method = get_byte(s);
- flags = get_byte(s);
- if (method != Z_DEFLATED || (flags & RESERVED) != 0) {
- s->z_err = Z_DATA_ERROR;
- return;
- }
-
- /* Discard time, xflags and OS code: */
- for (len = 0; len < 6; len++) (void)get_byte(s);
-
- if ((flags & EXTRA_FIELD) != 0) { /* skip the extra field */
- len = (uInt)get_byte(s);
- len += ((uInt)get_byte(s))<<8;
- /* len is garbage if EOF but the loop below will quit anyway */
- while (len-- != 0 && get_byte(s) != EOF) ;
- }
- if ((flags & ORIG_NAME) != 0) { /* skip the original file name */
- while ((c = get_byte(s)) != 0 && c != EOF) ;
- }
- if ((flags & COMMENT) != 0) { /* skip the .gz file comment */
- while ((c = get_byte(s)) != 0 && c != EOF) ;
- }
- if ((flags & HEAD_CRC) != 0) { /* skip the header crc */
- for (len = 0; len < 2; len++) (void)get_byte(s);
- }
- s->z_err = s->z_eof ? Z_DATA_ERROR : Z_OK;
-}
-
- /* ===========================================================================
- * Cleanup then free the given gz_stream. Return a zlib error code.
- Try freeing in the reverse order of allocations.
- */
-local int destroy (s)
- gz_stream *s;
-{
- int err = Z_OK;
-
- if (!s) return Z_STREAM_ERROR;
-
- TRYFREE(s->msg);
-
- if (s->stream.state != NULL) {
- if (s->mode == 'w') {
-#ifdef NO_GZCOMPRESS
- err = Z_STREAM_ERROR;
-#else
- err = deflateEnd(&(s->stream));
-#endif
- } else if (s->mode == 'r') {
- err = inflateEnd(&(s->stream));
- }
- }
- if (s->file != NULL && fclose(s->file)) {
-#ifdef ESPIPE
- if (errno != ESPIPE) /* fclose is broken for pipes in HP/UX */
-#endif
- err = Z_ERRNO;
- }
- if (s->z_err < 0) err = s->z_err;
-
- TRYFREE(s->inbuf);
- TRYFREE(s->outbuf);
- TRYFREE(s->path);
- TRYFREE(s);
- return err;
-}
-
-/* ===========================================================================
- Reads the given number of uncompressed bytes from the compressed file.
- gzread returns the number of bytes actually read (0 for end of file).
-*/
-int ZEXPORT gzread (file, buf, len)
- gzFile file;
- voidp buf;
- unsigned len;
-{
- gz_stream *s = (gz_stream*)file;
- Bytef *start = (Bytef*)buf; /* starting point for crc computation */
- Byte *next_out; /* == stream.next_out but not forced far (for MSDOS) */
-
- if (s == NULL || s->mode != 'r') return Z_STREAM_ERROR;
-
- if (s->z_err == Z_DATA_ERROR || s->z_err == Z_ERRNO) return -1;
- if (s->z_err == Z_STREAM_END) return 0; /* EOF */
-
- next_out = (Byte*)buf;
- s->stream.next_out = (Bytef*)buf;
- s->stream.avail_out = len;
-
- if (s->stream.avail_out && s->back != EOF) {
- *next_out++ = s->back;
- s->stream.next_out++;
- s->stream.avail_out--;
- s->back = EOF;
- s->out++;
- start++;
- if (s->last) {
- s->z_err = Z_STREAM_END;
- return 1;
- }
- }
-
- while (s->stream.avail_out != 0) {
-
- if (s->transparent) {
- /* Copy first the lookahead bytes: */
- uInt n = s->stream.avail_in;
- if (n > s->stream.avail_out) n = s->stream.avail_out;
- if (n > 0) {
- zmemcpy(s->stream.next_out, s->stream.next_in, n);
- next_out += n;
- s->stream.next_out = next_out;
- s->stream.next_in += n;
- s->stream.avail_out -= n;
- s->stream.avail_in -= n;
- }
- if (s->stream.avail_out > 0) {
- s->stream.avail_out -=
- (uInt)fread(next_out, 1, s->stream.avail_out, s->file);
- }
- len -= s->stream.avail_out;
- s->in += len;
- s->out += len;
- if (len == 0) s->z_eof = 1;
- return (int)len;
- }
- if (s->stream.avail_in == 0 && !s->z_eof) {
-
- errno = 0;
- s->stream.avail_in = (uInt)fread(s->inbuf, 1, Z_BUFSIZE, s->file);
- if (s->stream.avail_in == 0) {
- s->z_eof = 1;
- if (ferror(s->file)) {
- s->z_err = Z_ERRNO;
- break;
- }
- }
- s->stream.next_in = s->inbuf;
- }
- s->in += s->stream.avail_in;
- s->out += s->stream.avail_out;
- s->z_err = inflate(&(s->stream), Z_NO_FLUSH);
- s->in -= s->stream.avail_in;
- s->out -= s->stream.avail_out;
-
- if (s->z_err == Z_STREAM_END) {
- /* Check CRC and original size */
- s->crc = crc32(s->crc, start, (uInt)(s->stream.next_out - start));
- start = s->stream.next_out;
-
- if (getLong(s) != s->crc) {
- s->z_err = Z_DATA_ERROR;
- } else {
- (void)getLong(s);
- /* The uncompressed length returned by above getlong() may be
- * different from s->out in case of concatenated .gz files.
- * Check for such files:
- */
- check_header(s);
- if (s->z_err == Z_OK) {
- inflateReset(&(s->stream));
- s->crc = crc32(0L, Z_NULL, 0);
- }
- }
- }
- if (s->z_err != Z_OK || s->z_eof) break;
- }
- s->crc = crc32(s->crc, start, (uInt)(s->stream.next_out - start));
-
- if (len == s->stream.avail_out &&
- (s->z_err == Z_DATA_ERROR || s->z_err == Z_ERRNO))
- return -1;
- return (int)(len - s->stream.avail_out);
-}
-
-
-/* ===========================================================================
- Reads one byte from the compressed file. gzgetc returns this byte
- or -1 in case of end of file or error.
-*/
-int ZEXPORT gzgetc(file)
- gzFile file;
-{
- unsigned char c;
-
- return gzread(file, &c, 1) == 1 ? c : -1;
-}
-
-
-/* ===========================================================================
- Push one byte back onto the stream.
-*/
-int ZEXPORT gzungetc(c, file)
- int c;
- gzFile file;
-{
- gz_stream *s = (gz_stream*)file;
-
- if (s == NULL || s->mode != 'r' || c == EOF || s->back != EOF) return EOF;
- s->back = c;
- s->out--;
- s->last = (s->z_err == Z_STREAM_END);
- if (s->last) s->z_err = Z_OK;
- s->z_eof = 0;
- return c;
-}
-
-
-/* ===========================================================================
- Reads bytes from the compressed file until len-1 characters are
- read, or a newline character is read and transferred to buf, or an
- end-of-file condition is encountered. The string is then terminated
- with a null character.
- gzgets returns buf, or Z_NULL in case of error.
-
- The current implementation is not optimized at all.
-*/
-char * ZEXPORT gzgets(file, buf, len)
- gzFile file;
- char *buf;
- int len;
-{
- char *b = buf;
- if (buf == Z_NULL || len <= 0) return Z_NULL;
-
- while (--len > 0 && gzread(file, buf, 1) == 1 && *buf++ != '\n') ;
- *buf = '\0';
- return b == buf && len > 0 ? Z_NULL : b;
-}
-
-
-#ifndef NO_GZCOMPRESS
-/* ===========================================================================
- Writes the given number of uncompressed bytes into the compressed file.
- gzwrite returns the number of bytes actually written (0 in case of error).
-*/
-int ZEXPORT gzwrite (file, buf, len)
- gzFile file;
- voidpc buf;
- unsigned len;
-{
- gz_stream *s = (gz_stream*)file;
-
- if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR;
-
- s->stream.next_in = (Bytef*)buf;
- s->stream.avail_in = len;
-
- while (s->stream.avail_in != 0) {
-
- if (s->stream.avail_out == 0) {
-
- s->stream.next_out = s->outbuf;
- if (fwrite(s->outbuf, 1, Z_BUFSIZE, s->file) != Z_BUFSIZE) {
- s->z_err = Z_ERRNO;
- break;
- }
- s->stream.avail_out = Z_BUFSIZE;
- }
- s->in += s->stream.avail_in;
- s->out += s->stream.avail_out;
- s->z_err = deflate(&(s->stream), Z_NO_FLUSH);
- s->in -= s->stream.avail_in;
- s->out -= s->stream.avail_out;
- if (s->z_err != Z_OK) break;
- }
- s->crc = crc32(s->crc, (const Bytef *)buf, len);
-
- return (int)(len - s->stream.avail_in);
-}
-
-
-/* ===========================================================================
- Converts, formats, and writes the args to the compressed file under
- control of the format string, as in fprintf. gzprintf returns the number of
- uncompressed bytes actually written (0 in case of error).
-*/
-#ifdef STDC
-#include <stdarg.h>
-
-int ZEXPORTVA gzprintf (gzFile file, const char *format, /* args */ ...)
-{
- char buf[Z_PRINTF_BUFSIZE];
- va_list va;
- int len;
-
- buf[sizeof(buf) - 1] = 0;
- va_start(va, format);
-#ifdef NO_vsnprintf
-# ifdef HAS_vsprintf_void
- (void)vsprintf(buf, format, va);
- va_end(va);
- for (len = 0; len < sizeof(buf); len++)
- if (buf[len] == 0) break;
-# else
- len = vsprintf(buf, format, va);
- va_end(va);
-# endif
-#else
-# ifdef HAS_vsnprintf_void
- (void)vsnprintf(buf, sizeof(buf), format, va);
- va_end(va);
- len = strlen(buf);
-# else
- len = vsnprintf(buf, sizeof(buf), format, va);
- va_end(va);
-# endif
-#endif
- if (len <= 0 || len >= (int)sizeof(buf) || buf[sizeof(buf) - 1] != 0)
- return 0;
- return gzwrite(file, buf, (unsigned)len);
-}
-#else /* not ANSI C */
-
-int ZEXPORTVA gzprintf (file, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
- a11, a12, a13, a14, a15, a16, a17, a18, a19, a20)
- gzFile file;
- const char *format;
- int a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
- a11, a12, a13, a14, a15, a16, a17, a18, a19, a20;
-{
- char buf[Z_PRINTF_BUFSIZE];
- int len;
-
- buf[sizeof(buf) - 1] = 0;
-#ifdef NO_snprintf
-# ifdef HAS_sprintf_void
- sprintf(buf, format, a1, a2, a3, a4, a5, a6, a7, a8,
- a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
- for (len = 0; len < sizeof(buf); len++)
- if (buf[len] == 0) break;
-# else
- len = sprintf(buf, format, a1, a2, a3, a4, a5, a6, a7, a8,
- a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
-# endif
-#else
-# ifdef HAS_snprintf_void
- snprintf(buf, sizeof(buf), format, a1, a2, a3, a4, a5, a6, a7, a8,
- a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
- len = strlen(buf);
-# else
- len = snprintf(buf, sizeof(buf), format, a1, a2, a3, a4, a5, a6, a7, a8,
- a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
-# endif
-#endif
- if (len <= 0 || len >= sizeof(buf) || buf[sizeof(buf) - 1] != 0)
- return 0;
- return gzwrite(file, buf, len);
-}
-#endif
-
-/* ===========================================================================
- Writes c, converted to an unsigned char, into the compressed file.
- gzputc returns the value that was written, or -1 in case of error.
-*/
-int ZEXPORT gzputc(file, c)
- gzFile file;
- int c;
-{
- unsigned char cc = (unsigned char) c; /* required for big endian systems */
-
- return gzwrite(file, &cc, 1) == 1 ? (int)cc : -1;
-}
-
-
-/* ===========================================================================
- Writes the given null-terminated string to the compressed file, excluding
- the terminating null character.
- gzputs returns the number of characters written, or -1 in case of error.
-*/
-int ZEXPORT gzputs(file, s)
- gzFile file;
- const char *s;
-{
- return gzwrite(file, (char*)s, (unsigned)strlen(s));
-}
-
-
-/* ===========================================================================
- Flushes all pending output into the compressed file. The parameter
- flush is as in the deflate() function.
-*/
-local int do_flush (file, flush)
- gzFile file;
- int flush;
-{
- uInt len;
- int done = 0;
- gz_stream *s = (gz_stream*)file;
-
- if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR;
-
- s->stream.avail_in = 0; /* should be zero already anyway */
-
- for (;;) {
- len = Z_BUFSIZE - s->stream.avail_out;
-
- if (len != 0) {
- if ((uInt)fwrite(s->outbuf, 1, len, s->file) != len) {
- s->z_err = Z_ERRNO;
- return Z_ERRNO;
- }
- s->stream.next_out = s->outbuf;
- s->stream.avail_out = Z_BUFSIZE;
- }
- if (done) break;
- s->out += s->stream.avail_out;
- s->z_err = deflate(&(s->stream), flush);
- s->out -= s->stream.avail_out;
-
- /* Ignore the second of two consecutive flushes: */
- if (len == 0 && s->z_err == Z_BUF_ERROR) s->z_err = Z_OK;
-
- /* deflate has finished flushing only when it hasn't used up
- * all the available space in the output buffer:
- */
- done = (s->stream.avail_out != 0 || s->z_err == Z_STREAM_END);
-
- if (s->z_err != Z_OK && s->z_err != Z_STREAM_END) break;
- }
- return s->z_err == Z_STREAM_END ? Z_OK : s->z_err;
-}
-
-int ZEXPORT gzflush (file, flush)
- gzFile file;
- int flush;
-{
- gz_stream *s = (gz_stream*)file;
- int err = do_flush (file, flush);
-
- if (err) return err;
- fflush(s->file);
- return s->z_err == Z_STREAM_END ? Z_OK : s->z_err;
-}
-#endif /* NO_GZCOMPRESS */
-
-/* ===========================================================================
- Sets the starting position for the next gzread or gzwrite on the given
- compressed file. The offset represents a number of bytes in the
- gzseek returns the resulting offset location as measured in bytes from
- the beginning of the uncompressed stream, or -1 in case of error.
- SEEK_END is not implemented, returns error.
- In this version of the library, gzseek can be extremely slow.
-*/
-z_off_t ZEXPORT gzseek (file, offset, whence)
- gzFile file;
- z_off_t offset;
- int whence;
-{
- gz_stream *s = (gz_stream*)file;
-
- if (s == NULL || whence == SEEK_END ||
- s->z_err == Z_ERRNO || s->z_err == Z_DATA_ERROR) {
- return -1L;
- }
-
- if (s->mode == 'w') {
-#ifdef NO_GZCOMPRESS
- return -1L;
-#else
- if (whence == SEEK_SET) {
- offset -= s->in;
- }
- if (offset < 0) return -1L;
-
- /* At this point, offset is the number of zero bytes to write. */
- if (s->inbuf == Z_NULL) {
- s->inbuf = (Byte*)ALLOC(Z_BUFSIZE); /* for seeking */
- if (s->inbuf == Z_NULL) return -1L;
- zmemzero(s->inbuf, Z_BUFSIZE);
- }
- while (offset > 0) {
- uInt size = Z_BUFSIZE;
- if (offset < Z_BUFSIZE) size = (uInt)offset;
-
- size = gzwrite(file, s->inbuf, size);
- if (size == 0) return -1L;
-
- offset -= size;
- }
- return s->in;
-#endif
- }
- /* Rest of function is for reading only */
-
- /* compute absolute position */
- if (whence == SEEK_CUR) {
- offset += s->out;
- }
- if (offset < 0) return -1L;
-
- if (s->transparent) {
- /* map to fseek */
- s->back = EOF;
- s->stream.avail_in = 0;
- s->stream.next_in = s->inbuf;
- if (fseek(s->file, offset, SEEK_SET) < 0) return -1L;
-
- s->in = s->out = offset;
- return offset;
- }
-
- /* For a negative seek, rewind and use positive seek */
- if (offset >= s->out) {
- offset -= s->out;
- } else if (gzrewind(file) < 0) {
- return -1L;
- }
- /* offset is now the number of bytes to skip. */
-
- if (offset != 0 && s->outbuf == Z_NULL) {
- s->outbuf = (Byte*)ALLOC(Z_BUFSIZE);
- if (s->outbuf == Z_NULL) return -1L;
- }
- if (offset && s->back != EOF) {
- s->back = EOF;
- s->out++;
- offset--;
- if (s->last) s->z_err = Z_STREAM_END;
- }
- while (offset > 0) {
- int size = Z_BUFSIZE;
- if (offset < Z_BUFSIZE) size = (int)offset;
-
- size = gzread(file, s->outbuf, (uInt)size);
- if (size <= 0) return -1L;
- offset -= size;
- }
- return s->out;
-}
-
-/* ===========================================================================
- Rewinds input file.
-*/
-int ZEXPORT gzrewind (file)
- gzFile file;
-{
- gz_stream *s = (gz_stream*)file;
-
- if (s == NULL || s->mode != 'r') return -1;
-
- s->z_err = Z_OK;
- s->z_eof = 0;
- s->back = EOF;
- s->stream.avail_in = 0;
- s->stream.next_in = s->inbuf;
- s->crc = crc32(0L, Z_NULL, 0);
- if (!s->transparent) (void)inflateReset(&s->stream);
- s->in = 0;
- s->out = 0;
- return fseek(s->file, s->start, SEEK_SET);
-}
-
-/* ===========================================================================
- Returns the starting position for the next gzread or gzwrite on the
- given compressed file. This position represents a number of bytes in the
- uncompressed data stream.
-*/
-z_off_t ZEXPORT gztell (file)
- gzFile file;
-{
- return gzseek(file, 0L, SEEK_CUR);
-}
-
-/* ===========================================================================
- Returns 1 when EOF has previously been detected reading the given
- input stream, otherwise zero.
-*/
-int ZEXPORT gzeof (file)
- gzFile file;
-{
- gz_stream *s = (gz_stream*)file;
-
- /* With concatenated compressed files that can have embedded
- * crc trailers, z_eof is no longer the only/best indicator of EOF
- * on a gz_stream. Handle end-of-stream error explicitly here.
- */
- if (s == NULL || s->mode != 'r') return 0;
- if (s->z_eof) return 1;
- return s->z_err == Z_STREAM_END;
-}
-
-/* ===========================================================================
- Returns 1 if reading and doing so transparently, otherwise zero.
-*/
-int ZEXPORT gzdirect (file)
- gzFile file;
-{
- gz_stream *s = (gz_stream*)file;
-
- if (s == NULL || s->mode != 'r') return 0;
- return s->transparent;
-}
-
-/* ===========================================================================
- Outputs a long in LSB order to the given file
-*/
-local void putLong (file, x)
- FILE *file;
- uLong x;
-{
- int n;
- for (n = 0; n < 4; n++) {
- fputc((int)(x & 0xff), file);
- x >>= 8;
- }
-}
-
-/* ===========================================================================
- Reads a long in LSB order from the given gz_stream. Sets z_err in case
- of error.
-*/
-local uLong getLong (s)
- gz_stream *s;
-{
- uLong x = (uLong)get_byte(s);
- int c;
-
- x += ((uLong)get_byte(s))<<8;
- x += ((uLong)get_byte(s))<<16;
- c = get_byte(s);
- if (c == EOF) s->z_err = Z_DATA_ERROR;
- x += ((uLong)c)<<24;
- return x;
-}
-
-/* ===========================================================================
- Flushes all pending output if necessary, closes the compressed file
- and deallocates all the (de)compression state.
-*/
-int ZEXPORT gzclose (file)
- gzFile file;
-{
- gz_stream *s = (gz_stream*)file;
-
- if (s == NULL) return Z_STREAM_ERROR;
-
- if (s->mode == 'w') {
-#ifdef NO_GZCOMPRESS
- return Z_STREAM_ERROR;
-#else
- if (do_flush (file, Z_FINISH) != Z_OK)
- return destroy((gz_stream*)file);
-
- putLong (s->file, s->crc);
- putLong (s->file, (uLong)(s->in & 0xffffffff));
-#endif
- }
- return destroy((gz_stream*)file);
-}
-
-#ifdef STDC
-# define zstrerror(errnum) strerror(errnum)
-#else
-# define zstrerror(errnum) ""
-#endif
-
-/* ===========================================================================
- Returns the error message for the last error which occurred on the
- given compressed file. errnum is set to zlib error number. If an
- error occurred in the file system and not in the compression library,
- errnum is set to Z_ERRNO and the application may consult errno
- to get the exact error code.
-*/
-const char * ZEXPORT gzerror (file, errnum)
- gzFile file;
- int *errnum;
-{
- char *m;
- gz_stream *s = (gz_stream*)file;
-
- if (s == NULL) {
- *errnum = Z_STREAM_ERROR;
- return (const char*)ERR_MSG(Z_STREAM_ERROR);
- }
- *errnum = s->z_err;
- if (*errnum == Z_OK) return (const char*)"";
-
- m = (char*)(*errnum == Z_ERRNO ? zstrerror(errno) : s->stream.msg);
-
- if (m == NULL || *m == '\0') m = (char*)ERR_MSG(s->z_err);
-
- TRYFREE(s->msg);
- s->msg = (char*)ALLOC(strlen(s->path) + strlen(m) + 3);
- if (s->msg == Z_NULL) return (const char*)ERR_MSG(Z_MEM_ERROR);
- strcpy(s->msg, s->path);
- strcat(s->msg, ": ");
- strcat(s->msg, m);
- return (const char*)s->msg;
-}
-
-/* ===========================================================================
- Clear the error and end-of-file flags, and do the same for the real file.
-*/
-void ZEXPORT gzclearerr (file)
- gzFile file;
-{
- gz_stream *s = (gz_stream*)file;
-
- if (s == NULL) return;
- if (s->z_err != Z_STREAM_END) s->z_err = Z_OK;
- s->z_eof = 0;
- clearerr(s->file);
-}
+++ /dev/null
-/* infback.c -- inflate using a call-back interface
- * Copyright (C) 1995-2005 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/*
- This code is largely copied from inflate.c. Normally either infback.o or
- inflate.o would be linked into an application--not both. The interface
- with inffast.c is retained so that optimized assembler-coded versions of
- inflate_fast() can be used with either inflate.c or infback.c.
- */
-
-#include "zutil.h"
-#include "inftrees.h"
-#include "inflate.h"
-#include "inffast.h"
-
-/* function prototypes */
-local void fixedtables OF((struct inflate_state FAR *state));
-
-/*
- strm provides memory allocation functions in zalloc and zfree, or
- Z_NULL to use the library memory allocation functions.
-
- windowBits is in the range 8..15, and window is a user-supplied
- window and output buffer that is 2**windowBits bytes.
- */
-int ZEXPORT inflateBackInit_(strm, windowBits, window, version, stream_size)
-z_streamp strm;
-int windowBits;
-unsigned char FAR *window;
-const char *version;
-int stream_size;
-{
- struct inflate_state FAR *state;
-
- if (version == Z_NULL || version[0] != ZLIB_VERSION[0] ||
- stream_size != (int)(sizeof(z_stream)))
- return Z_VERSION_ERROR;
- if (strm == Z_NULL || window == Z_NULL ||
- windowBits < 8 || windowBits > 15)
- return Z_STREAM_ERROR;
- strm->msg = Z_NULL; /* in case we return an error */
- if (strm->zalloc == (alloc_func)0) {
- strm->zalloc = zcalloc;
- strm->opaque = (voidpf)0;
- }
- if (strm->zfree == (free_func)0) strm->zfree = zcfree;
- state = (struct inflate_state FAR *)ZALLOC(strm, 1,
- sizeof(struct inflate_state));
- if (state == Z_NULL) return Z_MEM_ERROR;
- Tracev((stderr, "inflate: allocated\n"));
- strm->state = (struct internal_state FAR *)state;
- state->dmax = 32768U;
- state->wbits = windowBits;
- state->wsize = 1U << windowBits;
- state->window = window;
- state->write = 0;
- state->whave = 0;
- return Z_OK;
-}
-
-/*
- Return state with length and distance decoding tables and index sizes set to
- fixed code decoding. Normally this returns fixed tables from inffixed.h.
- If BUILDFIXED is defined, then instead this routine builds the tables the
- first time it's called, and returns those tables the first time and
- thereafter. This reduces the size of the code by about 2K bytes, in
- exchange for a little execution time. However, BUILDFIXED should not be
- used for threaded applications, since the rewriting of the tables and virgin
- may not be thread-safe.
- */
-local void fixedtables(state)
-struct inflate_state FAR *state;
-{
-#ifdef BUILDFIXED
- static int virgin = 1;
- static code *lenfix, *distfix;
- static code fixed[544];
-
- /* build fixed huffman tables if first call (may not be thread safe) */
- if (virgin) {
- unsigned sym, bits;
- static code *next;
-
- /* literal/length table */
- sym = 0;
- while (sym < 144) state->lens[sym++] = 8;
- while (sym < 256) state->lens[sym++] = 9;
- while (sym < 280) state->lens[sym++] = 7;
- while (sym < 288) state->lens[sym++] = 8;
- next = fixed;
- lenfix = next;
- bits = 9;
- inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work);
-
- /* distance table */
- sym = 0;
- while (sym < 32) state->lens[sym++] = 5;
- distfix = next;
- bits = 5;
- inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work);
-
- /* do this just once */
- virgin = 0;
- }
-#else /* !BUILDFIXED */
-# include "inffixed.h"
-#endif /* BUILDFIXED */
- state->lencode = lenfix;
- state->lenbits = 9;
- state->distcode = distfix;
- state->distbits = 5;
-}
-
-/* Macros for inflateBack(): */
-
-/* Load returned state from inflate_fast() */
-#define LOAD() \
- do { \
- put = strm->next_out; \
- left = strm->avail_out; \
- next = strm->next_in; \
- have = strm->avail_in; \
- hold = state->hold; \
- bits = state->bits; \
- } while (0)
-
-/* Set state from registers for inflate_fast() */
-#define RESTORE() \
- do { \
- strm->next_out = put; \
- strm->avail_out = left; \
- strm->next_in = next; \
- strm->avail_in = have; \
- state->hold = hold; \
- state->bits = bits; \
- } while (0)
-
-/* Clear the input bit accumulator */
-#define INITBITS() \
- do { \
- hold = 0; \
- bits = 0; \
- } while (0)
-
-/* Assure that some input is available. If input is requested, but denied,
- then return a Z_BUF_ERROR from inflateBack(). */
-#define PULL() \
- do { \
- if (have == 0) { \
- have = in(in_desc, &next); \
- if (have == 0) { \
- next = Z_NULL; \
- ret = Z_BUF_ERROR; \
- goto inf_leave; \
- } \
- } \
- } while (0)
-
-/* Get a byte of input into the bit accumulator, or return from inflateBack()
- with an error if there is no input available. */
-#define PULLBYTE() \
- do { \
- PULL(); \
- have--; \
- hold += (unsigned long)(*next++) << bits; \
- bits += 8; \
- } while (0)
-
-/* Assure that there are at least n bits in the bit accumulator. If there is
- not enough available input to do that, then return from inflateBack() with
- an error. */
-#define NEEDBITS(n) \
- do { \
- while (bits < (unsigned)(n)) \
- PULLBYTE(); \
- } while (0)
-
-/* Return the low n bits of the bit accumulator (n < 16) */
-#define BITS(n) \
- ((unsigned)hold & ((1U << (n)) - 1))
-
-/* Remove n bits from the bit accumulator */
-#define DROPBITS(n) \
- do { \
- hold >>= (n); \
- bits -= (unsigned)(n); \
- } while (0)
-
-/* Remove zero to seven bits as needed to go to a byte boundary */
-#define BYTEBITS() \
- do { \
- hold >>= bits & 7; \
- bits -= bits & 7; \
- } while (0)
-
-/* Assure that some output space is available, by writing out the window
- if it's full. If the write fails, return from inflateBack() with a
- Z_BUF_ERROR. */
-#define ROOM() \
- do { \
- if (left == 0) { \
- put = state->window; \
- left = state->wsize; \
- state->whave = left; \
- if (out(out_desc, put, left)) { \
- ret = Z_BUF_ERROR; \
- goto inf_leave; \
- } \
- } \
- } while (0)
-
-/*
- strm provides the memory allocation functions and window buffer on input,
- and provides information on the unused input on return. For Z_DATA_ERROR
- returns, strm will also provide an error message.
-
- in() and out() are the call-back input and output functions. When
- inflateBack() needs more input, it calls in(). When inflateBack() has
- filled the window with output, or when it completes with data in the
- window, it calls out() to write out the data. The application must not
- change the provided input until in() is called again or inflateBack()
- returns. The application must not change the window/output buffer until
- inflateBack() returns.
-
- in() and out() are called with a descriptor parameter provided in the
- inflateBack() call. This parameter can be a structure that provides the
- information required to do the read or write, as well as accumulated
- information on the input and output such as totals and check values.
-
- in() should return zero on failure. out() should return non-zero on
- failure. If either in() or out() fails, than inflateBack() returns a
- Z_BUF_ERROR. strm->next_in can be checked for Z_NULL to see whether it
- was in() or out() that caused in the error. Otherwise, inflateBack()
- returns Z_STREAM_END on success, Z_DATA_ERROR for an deflate format
- error, or Z_MEM_ERROR if it could not allocate memory for the state.
- inflateBack() can also return Z_STREAM_ERROR if the input parameters
- are not correct, i.e. strm is Z_NULL or the state was not initialized.
- */
-int ZEXPORT inflateBack(strm, in, in_desc, out, out_desc)
-z_streamp strm;
-in_func in;
-void FAR *in_desc;
-out_func out;
-void FAR *out_desc;
-{
- struct inflate_state FAR *state;
- unsigned char FAR *next; /* next input */
- unsigned char FAR *put; /* next output */
- unsigned have, left; /* available input and output */
- unsigned long hold; /* bit buffer */
- unsigned bits; /* bits in bit buffer */
- unsigned copy; /* number of stored or match bytes to copy */
- unsigned char FAR *from; /* where to copy match bytes from */
- code this; /* current decoding table entry */
- code last; /* parent table entry */
- unsigned len; /* length to copy for repeats, bits to drop */
- int ret; /* return code */
- static const unsigned short order[19] = /* permutation of code lengths */
- {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
-
- /* Check that the strm exists and that the state was initialized */
- if (strm == Z_NULL || strm->state == Z_NULL)
- return Z_STREAM_ERROR;
- state = (struct inflate_state FAR *)strm->state;
-
- /* Reset the state */
- strm->msg = Z_NULL;
- state->mode = TYPE;
- state->last = 0;
- state->whave = 0;
- next = strm->next_in;
- have = next != Z_NULL ? strm->avail_in : 0;
- hold = 0;
- bits = 0;
- put = state->window;
- left = state->wsize;
-
- /* Inflate until end of block marked as last */
- for (;;)
- switch (state->mode) {
- case TYPE:
- /* determine and dispatch block type */
- if (state->last) {
- BYTEBITS();
- state->mode = DONE;
- break;
- }
- NEEDBITS(3);
- state->last = BITS(1);
- DROPBITS(1);
- switch (BITS(2)) {
- case 0: /* stored block */
- Tracev((stderr, "inflate: stored block%s\n",
- state->last ? " (last)" : ""));
- state->mode = STORED;
- break;
- case 1: /* fixed block */
- fixedtables(state);
- Tracev((stderr, "inflate: fixed codes block%s\n",
- state->last ? " (last)" : ""));
- state->mode = LEN; /* decode codes */
- break;
- case 2: /* dynamic block */
- Tracev((stderr, "inflate: dynamic codes block%s\n",
- state->last ? " (last)" : ""));
- state->mode = TABLE;
- break;
- case 3:
- strm->msg = (char *)"invalid block type";
- state->mode = BAD;
- }
- DROPBITS(2);
- break;
-
- case STORED:
- /* get and verify stored block length */
- BYTEBITS(); /* go to byte boundary */
- NEEDBITS(32);
- if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) {
- strm->msg = (char *)"invalid stored block lengths";
- state->mode = BAD;
- break;
- }
- state->length = (unsigned)hold & 0xffff;
- Tracev((stderr, "inflate: stored length %u\n",
- state->length));
- INITBITS();
-
- /* copy stored block from input to output */
- while (state->length != 0) {
- copy = state->length;
- PULL();
- ROOM();
- if (copy > have) copy = have;
- if (copy > left) copy = left;
- zmemcpy(put, next, copy);
- have -= copy;
- next += copy;
- left -= copy;
- put += copy;
- state->length -= copy;
- }
- Tracev((stderr, "inflate: stored end\n"));
- state->mode = TYPE;
- break;
-
- case TABLE:
- /* get dynamic table entries descriptor */
- NEEDBITS(14);
- state->nlen = BITS(5) + 257;
- DROPBITS(5);
- state->ndist = BITS(5) + 1;
- DROPBITS(5);
- state->ncode = BITS(4) + 4;
- DROPBITS(4);
-#ifndef PKZIP_BUG_WORKAROUND
- if (state->nlen > 286 || state->ndist > 30) {
- strm->msg = (char *)"too many length or distance symbols";
- state->mode = BAD;
- break;
- }
-#endif
- Tracev((stderr, "inflate: table sizes ok\n"));
-
- /* get code length code lengths (not a typo) */
- state->have = 0;
- while (state->have < state->ncode) {
- NEEDBITS(3);
- state->lens[order[state->have++]] = (unsigned short)BITS(3);
- DROPBITS(3);
- }
- while (state->have < 19)
- state->lens[order[state->have++]] = 0;
- state->next = state->codes;
- state->lencode = (code const FAR *)(state->next);
- state->lenbits = 7;
- ret = inflate_table(CODES, state->lens, 19, &(state->next),
- &(state->lenbits), state->work);
- if (ret) {
- strm->msg = (char *)"invalid code lengths set";
- state->mode = BAD;
- break;
- }
- Tracev((stderr, "inflate: code lengths ok\n"));
-
- /* get length and distance code code lengths */
- state->have = 0;
- while (state->have < state->nlen + state->ndist) {
- for (;;) {
- this = state->lencode[BITS(state->lenbits)];
- if ((unsigned)(this.bits) <= bits) break;
- PULLBYTE();
- }
- if (this.val < 16) {
- NEEDBITS(this.bits);
- DROPBITS(this.bits);
- state->lens[state->have++] = this.val;
- }
- else {
- if (this.val == 16) {
- NEEDBITS(this.bits + 2);
- DROPBITS(this.bits);
- if (state->have == 0) {
- strm->msg = (char *)"invalid bit length repeat";
- state->mode = BAD;
- break;
- }
- len = (unsigned)(state->lens[state->have - 1]);
- copy = 3 + BITS(2);
- DROPBITS(2);
- }
- else if (this.val == 17) {
- NEEDBITS(this.bits + 3);
- DROPBITS(this.bits);
- len = 0;
- copy = 3 + BITS(3);
- DROPBITS(3);
- }
- else {
- NEEDBITS(this.bits + 7);
- DROPBITS(this.bits);
- len = 0;
- copy = 11 + BITS(7);
- DROPBITS(7);
- }
- if (state->have + copy > state->nlen + state->ndist) {
- strm->msg = (char *)"invalid bit length repeat";
- state->mode = BAD;
- break;
- }
- while (copy--)
- state->lens[state->have++] = (unsigned short)len;
- }
- }
-
- /* handle error breaks in while */
- if (state->mode == BAD) break;
-
- /* build code tables */
- state->next = state->codes;
- state->lencode = (code const FAR *)(state->next);
- state->lenbits = 9;
- ret = inflate_table(LENS, state->lens, state->nlen, &(state->next),
- &(state->lenbits), state->work);
- if (ret) {
- strm->msg = (char *)"invalid literal/lengths set";
- state->mode = BAD;
- break;
- }
- state->distcode = (code const FAR *)(state->next);
- state->distbits = 6;
- ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist,
- &(state->next), &(state->distbits), state->work);
- if (ret) {
- strm->msg = (char *)"invalid distances set";
- state->mode = BAD;
- break;
- }
- Tracev((stderr, "inflate: codes ok\n"));
- state->mode = LEN;
-
- case LEN:
- /* use inflate_fast() if we have enough input and output */
- if (have >= 6 && left >= 258) {
- RESTORE();
- if (state->whave < state->wsize)
- state->whave = state->wsize - left;
- inflate_fast(strm, state->wsize);
- LOAD();
- break;
- }
-
- /* get a literal, length, or end-of-block code */
- for (;;) {
- this = state->lencode[BITS(state->lenbits)];
- if ((unsigned)(this.bits) <= bits) break;
- PULLBYTE();
- }
- if (this.op && (this.op & 0xf0) == 0) {
- last = this;
- for (;;) {
- this = state->lencode[last.val +
- (BITS(last.bits + last.op) >> last.bits)];
- if ((unsigned)(last.bits + this.bits) <= bits) break;
- PULLBYTE();
- }
- DROPBITS(last.bits);
- }
- DROPBITS(this.bits);
- state->length = (unsigned)this.val;
-
- /* process literal */
- if (this.op == 0) {
- Tracevv((stderr, this.val >= 0x20 && this.val < 0x7f ?
- "inflate: literal '%c'\n" :
- "inflate: literal 0x%02x\n", this.val));
- ROOM();
- *put++ = (unsigned char)(state->length);
- left--;
- state->mode = LEN;
- break;
- }
-
- /* process end of block */
- if (this.op & 32) {
- Tracevv((stderr, "inflate: end of block\n"));
- state->mode = TYPE;
- break;
- }
-
- /* invalid code */
- if (this.op & 64) {
- strm->msg = (char *)"invalid literal/length code";
- state->mode = BAD;
- break;
- }
-
- /* length code -- get extra bits, if any */
- state->extra = (unsigned)(this.op) & 15;
- if (state->extra != 0) {
- NEEDBITS(state->extra);
- state->length += BITS(state->extra);
- DROPBITS(state->extra);
- }
- Tracevv((stderr, "inflate: length %u\n", state->length));
-
- /* get distance code */
- for (;;) {
- this = state->distcode[BITS(state->distbits)];
- if ((unsigned)(this.bits) <= bits) break;
- PULLBYTE();
- }
- if ((this.op & 0xf0) == 0) {
- last = this;
- for (;;) {
- this = state->distcode[last.val +
- (BITS(last.bits + last.op) >> last.bits)];
- if ((unsigned)(last.bits + this.bits) <= bits) break;
- PULLBYTE();
- }
- DROPBITS(last.bits);
- }
- DROPBITS(this.bits);
- if (this.op & 64) {
- strm->msg = (char *)"invalid distance code";
- state->mode = BAD;
- break;
- }
- state->offset = (unsigned)this.val;
-
- /* get distance extra bits, if any */
- state->extra = (unsigned)(this.op) & 15;
- if (state->extra != 0) {
- NEEDBITS(state->extra);
- state->offset += BITS(state->extra);
- DROPBITS(state->extra);
- }
- if (state->offset > state->wsize - (state->whave < state->wsize ?
- left : 0)) {
- strm->msg = (char *)"invalid distance too far back";
- state->mode = BAD;
- break;
- }
- Tracevv((stderr, "inflate: distance %u\n", state->offset));
-
- /* copy match from window to output */
- do {
- ROOM();
- copy = state->wsize - state->offset;
- if (copy < left) {
- from = put + copy;
- copy = left - copy;
- }
- else {
- from = put - state->offset;
- copy = left;
- }
- if (copy > state->length) copy = state->length;
- state->length -= copy;
- left -= copy;
- do {
- *put++ = *from++;
- } while (--copy);
- } while (state->length != 0);
- break;
-
- case DONE:
- /* inflate stream terminated properly -- write leftover output */
- ret = Z_STREAM_END;
- if (left < state->wsize) {
- if (out(out_desc, state->window, state->wsize - left))
- ret = Z_BUF_ERROR;
- }
- goto inf_leave;
-
- case BAD:
- ret = Z_DATA_ERROR;
- goto inf_leave;
-
- default: /* can't happen, but makes compilers happy */
- ret = Z_STREAM_ERROR;
- goto inf_leave;
- }
-
- /* Return unused input */
- inf_leave:
- strm->next_in = next;
- strm->avail_in = have;
- return ret;
-}
-
-int ZEXPORT inflateBackEnd(strm)
-z_streamp strm;
-{
- if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0)
- return Z_STREAM_ERROR;
- ZFREE(strm, strm->state);
- strm->state = Z_NULL;
- Tracev((stderr, "inflate: end\n"));
- return Z_OK;
-}
+++ /dev/null
-/* inffast.c -- fast decoding
- * Copyright (C) 1995-2004 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-#include "zutil.h"
-#include "inftrees.h"
-#include "inflate.h"
-#include "inffast.h"
-
-#ifndef ASMINF
-
-/* Allow machine dependent optimization for post-increment or pre-increment.
- Based on testing to date,
- Pre-increment preferred for:
- - PowerPC G3 (Adler)
- - MIPS R5000 (Randers-Pehrson)
- Post-increment preferred for:
- - none
- No measurable difference:
- - Pentium III (Anderson)
- - M68060 (Nikl)
- */
-#ifdef POSTINC
-# define OFF 0
-# define PUP(a) *(a)++
-#else
-# define OFF 1
-# define PUP(a) *++(a)
-#endif
-
-/*
- Decode literal, length, and distance codes and write out the resulting
- literal and match bytes until either not enough input or output is
- available, an end-of-block is encountered, or a data error is encountered.
- When large enough input and output buffers are supplied to inflate(), for
- example, a 16K input buffer and a 64K output buffer, more than 95% of the
- inflate execution time is spent in this routine.
-
- Entry assumptions:
-
- state->mode == LEN
- strm->avail_in >= 6
- strm->avail_out >= 258
- start >= strm->avail_out
- state->bits < 8
-
- On return, state->mode is one of:
-
- LEN -- ran out of enough output space or enough available input
- TYPE -- reached end of block code, inflate() to interpret next block
- BAD -- error in block data
-
- Notes:
-
- - The maximum input bits used by a length/distance pair is 15 bits for the
- length code, 5 bits for the length extra, 15 bits for the distance code,
- and 13 bits for the distance extra. This totals 48 bits, or six bytes.
- Therefore if strm->avail_in >= 6, then there is enough input to avoid
- checking for available input while decoding.
-
- - The maximum bytes that a single length/distance pair can output is 258
- bytes, which is the maximum length that can be coded. inflate_fast()
- requires strm->avail_out >= 258 for each loop to avoid checking for
- output space.
- */
-void inflate_fast(strm, start)
-z_streamp strm;
-unsigned start; /* inflate()'s starting value for strm->avail_out */
-{
- struct inflate_state FAR *state;
- unsigned char FAR *in; /* local strm->next_in */
- unsigned char FAR *last; /* while in < last, enough input available */
- unsigned char FAR *out; /* local strm->next_out */
- unsigned char FAR *beg; /* inflate()'s initial strm->next_out */
- unsigned char FAR *end; /* while out < end, enough space available */
-#ifdef INFLATE_STRICT
- unsigned dmax; /* maximum distance from zlib header */
-#endif
- unsigned wsize; /* window size or zero if not using window */
- unsigned whave; /* valid bytes in the window */
- unsigned write; /* window write index */
- unsigned char FAR *window; /* allocated sliding window, if wsize != 0 */
- unsigned long hold; /* local strm->hold */
- unsigned bits; /* local strm->bits */
- code const FAR *lcode; /* local strm->lencode */
- code const FAR *dcode; /* local strm->distcode */
- unsigned lmask; /* mask for first level of length codes */
- unsigned dmask; /* mask for first level of distance codes */
- code this; /* retrieved table entry */
- unsigned op; /* code bits, operation, extra bits, or */
- /* window position, window bytes to copy */
- unsigned len; /* match length, unused bytes */
- unsigned dist; /* match distance */
- unsigned char FAR *from; /* where to copy match from */
-
- /* copy state to local variables */
- state = (struct inflate_state FAR *)strm->state;
- in = strm->next_in - OFF;
- last = in + (strm->avail_in - 5);
- out = strm->next_out - OFF;
- beg = out - (start - strm->avail_out);
- end = out + (strm->avail_out - 257);
-#ifdef INFLATE_STRICT
- dmax = state->dmax;
-#endif
- wsize = state->wsize;
- whave = state->whave;
- write = state->write;
- window = state->window;
- hold = state->hold;
- bits = state->bits;
- lcode = state->lencode;
- dcode = state->distcode;
- lmask = (1U << state->lenbits) - 1;
- dmask = (1U << state->distbits) - 1;
-
- /* decode literals and length/distances until end-of-block or not enough
- input data or output space */
- do {
- if (bits < 15) {
- hold += (unsigned long)(PUP(in)) << bits;
- bits += 8;
- hold += (unsigned long)(PUP(in)) << bits;
- bits += 8;
- }
- this = lcode[hold & lmask];
- dolen:
- op = (unsigned)(this.bits);
- hold >>= op;
- bits -= op;
- op = (unsigned)(this.op);
- if (op == 0) { /* literal */
- Tracevv((stderr, this.val >= 0x20 && this.val < 0x7f ?
- "inflate: literal '%c'\n" :
- "inflate: literal 0x%02x\n", this.val));
- PUP(out) = (unsigned char)(this.val);
- }
- else if (op & 16) { /* length base */
- len = (unsigned)(this.val);
- op &= 15; /* number of extra bits */
- if (op) {
- if (bits < op) {
- hold += (unsigned long)(PUP(in)) << bits;
- bits += 8;
- }
- len += (unsigned)hold & ((1U << op) - 1);
- hold >>= op;
- bits -= op;
- }
- Tracevv((stderr, "inflate: length %u\n", len));
- if (bits < 15) {
- hold += (unsigned long)(PUP(in)) << bits;
- bits += 8;
- hold += (unsigned long)(PUP(in)) << bits;
- bits += 8;
- }
- this = dcode[hold & dmask];
- dodist:
- op = (unsigned)(this.bits);
- hold >>= op;
- bits -= op;
- op = (unsigned)(this.op);
- if (op & 16) { /* distance base */
- dist = (unsigned)(this.val);
- op &= 15; /* number of extra bits */
- if (bits < op) {
- hold += (unsigned long)(PUP(in)) << bits;
- bits += 8;
- if (bits < op) {
- hold += (unsigned long)(PUP(in)) << bits;
- bits += 8;
- }
- }
- dist += (unsigned)hold & ((1U << op) - 1);
-#ifdef INFLATE_STRICT
- if (dist > dmax) {
- strm->msg = (char *)"invalid distance too far back";
- state->mode = BAD;
- break;
- }
-#endif
- hold >>= op;
- bits -= op;
- Tracevv((stderr, "inflate: distance %u\n", dist));
- op = (unsigned)(out - beg); /* max distance in output */
- if (dist > op) { /* see if copy from window */
- op = dist - op; /* distance back in window */
- if (op > whave) {
- strm->msg = (char *)"invalid distance too far back";
- state->mode = BAD;
- break;
- }
- from = window - OFF;
- if (write == 0) { /* very common case */
- from += wsize - op;
- if (op < len) { /* some from window */
- len -= op;
- do {
- PUP(out) = PUP(from);
- } while (--op);
- from = out - dist; /* rest from output */
- }
- }
- else if (write < op) { /* wrap around window */
- from += wsize + write - op;
- op -= write;
- if (op < len) { /* some from end of window */
- len -= op;
- do {
- PUP(out) = PUP(from);
- } while (--op);
- from = window - OFF;
- if (write < len) { /* some from start of window */
- op = write;
- len -= op;
- do {
- PUP(out) = PUP(from);
- } while (--op);
- from = out - dist; /* rest from output */
- }
- }
- }
- else { /* contiguous in window */
- from += write - op;
- if (op < len) { /* some from window */
- len -= op;
- do {
- PUP(out) = PUP(from);
- } while (--op);
- from = out - dist; /* rest from output */
- }
- }
- while (len > 2) {
- PUP(out) = PUP(from);
- PUP(out) = PUP(from);
- PUP(out) = PUP(from);
- len -= 3;
- }
- if (len) {
- PUP(out) = PUP(from);
- if (len > 1)
- PUP(out) = PUP(from);
- }
- }
- else {
- from = out - dist; /* copy direct from output */
- do { /* minimum length is three */
- PUP(out) = PUP(from);
- PUP(out) = PUP(from);
- PUP(out) = PUP(from);
- len -= 3;
- } while (len > 2);
- if (len) {
- PUP(out) = PUP(from);
- if (len > 1)
- PUP(out) = PUP(from);
- }
- }
- }
- else if ((op & 64) == 0) { /* 2nd level distance code */
- this = dcode[this.val + (hold & ((1U << op) - 1))];
- goto dodist;
- }
- else {
- strm->msg = (char *)"invalid distance code";
- state->mode = BAD;
- break;
- }
- }
- else if ((op & 64) == 0) { /* 2nd level length code */
- this = lcode[this.val + (hold & ((1U << op) - 1))];
- goto dolen;
- }
- else if (op & 32) { /* end-of-block */
- Tracevv((stderr, "inflate: end of block\n"));
- state->mode = TYPE;
- break;
- }
- else {
- strm->msg = (char *)"invalid literal/length code";
- state->mode = BAD;
- break;
- }
- } while (in < last && out < end);
-
- /* return unused bytes (on entry, bits < 8, so in won't go too far back) */
- len = bits >> 3;
- in -= len;
- bits -= len << 3;
- hold &= (1U << bits) - 1;
-
- /* update state and return */
- strm->next_in = in + OFF;
- strm->next_out = out + OFF;
- strm->avail_in = (unsigned)(in < last ? 5 + (last - in) : 5 - (in - last));
- strm->avail_out = (unsigned)(out < end ?
- 257 + (end - out) : 257 - (out - end));
- state->hold = hold;
- state->bits = bits;
- return;
-}
-
-/*
- inflate_fast() speedups that turned out slower (on a PowerPC G3 750CXe):
- - Using bit fields for code structure
- - Different op definition to avoid & for extra bits (do & for table bits)
- - Three separate decoding do-loops for direct, window, and write == 0
- - Special case for distance > 1 copies to do overlapped load and store copy
- - Explicit branch predictions (based on measured branch probabilities)
- - Deferring match copy and interspersed it with decoding subsequent codes
- - Swapping literal/length else
- - Swapping window/direct else
- - Larger unrolled copy loops (three is about right)
- - Moving len -= 3 statement into middle of loop
- */
-
-#endif /* !ASMINF */
+++ /dev/null
-/* inffast.h -- header to use inffast.c
- * Copyright (C) 1995-2003 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* WARNING: this file should *not* be used by applications. It is
- part of the implementation of the compression library and is
- subject to change. Applications should only use zlib.h.
- */
-
-void inflate_fast OF((z_streamp strm, unsigned start));
+++ /dev/null
- /* inffixed.h -- table for decoding fixed codes
- * Generated automatically by makefixed().
- */
-
- /* WARNING: this file should *not* be used by applications. It
- is part of the implementation of the compression library and
- is subject to change. Applications should only use zlib.h.
- */
-
- static const code lenfix[512] = {
- {96,7,0},{0,8,80},{0,8,16},{20,8,115},{18,7,31},{0,8,112},{0,8,48},
- {0,9,192},{16,7,10},{0,8,96},{0,8,32},{0,9,160},{0,8,0},{0,8,128},
- {0,8,64},{0,9,224},{16,7,6},{0,8,88},{0,8,24},{0,9,144},{19,7,59},
- {0,8,120},{0,8,56},{0,9,208},{17,7,17},{0,8,104},{0,8,40},{0,9,176},
- {0,8,8},{0,8,136},{0,8,72},{0,9,240},{16,7,4},{0,8,84},{0,8,20},
- {21,8,227},{19,7,43},{0,8,116},{0,8,52},{0,9,200},{17,7,13},{0,8,100},
- {0,8,36},{0,9,168},{0,8,4},{0,8,132},{0,8,68},{0,9,232},{16,7,8},
- {0,8,92},{0,8,28},{0,9,152},{20,7,83},{0,8,124},{0,8,60},{0,9,216},
- {18,7,23},{0,8,108},{0,8,44},{0,9,184},{0,8,12},{0,8,140},{0,8,76},
- {0,9,248},{16,7,3},{0,8,82},{0,8,18},{21,8,163},{19,7,35},{0,8,114},
- {0,8,50},{0,9,196},{17,7,11},{0,8,98},{0,8,34},{0,9,164},{0,8,2},
- {0,8,130},{0,8,66},{0,9,228},{16,7,7},{0,8,90},{0,8,26},{0,9,148},
- {20,7,67},{0,8,122},{0,8,58},{0,9,212},{18,7,19},{0,8,106},{0,8,42},
- {0,9,180},{0,8,10},{0,8,138},{0,8,74},{0,9,244},{16,7,5},{0,8,86},
- {0,8,22},{64,8,0},{19,7,51},{0,8,118},{0,8,54},{0,9,204},{17,7,15},
- {0,8,102},{0,8,38},{0,9,172},{0,8,6},{0,8,134},{0,8,70},{0,9,236},
- {16,7,9},{0,8,94},{0,8,30},{0,9,156},{20,7,99},{0,8,126},{0,8,62},
- {0,9,220},{18,7,27},{0,8,110},{0,8,46},{0,9,188},{0,8,14},{0,8,142},
- {0,8,78},{0,9,252},{96,7,0},{0,8,81},{0,8,17},{21,8,131},{18,7,31},
- {0,8,113},{0,8,49},{0,9,194},{16,7,10},{0,8,97},{0,8,33},{0,9,162},
- {0,8,1},{0,8,129},{0,8,65},{0,9,226},{16,7,6},{0,8,89},{0,8,25},
- {0,9,146},{19,7,59},{0,8,121},{0,8,57},{0,9,210},{17,7,17},{0,8,105},
- {0,8,41},{0,9,178},{0,8,9},{0,8,137},{0,8,73},{0,9,242},{16,7,4},
- {0,8,85},{0,8,21},{16,8,258},{19,7,43},{0,8,117},{0,8,53},{0,9,202},
- {17,7,13},{0,8,101},{0,8,37},{0,9,170},{0,8,5},{0,8,133},{0,8,69},
- {0,9,234},{16,7,8},{0,8,93},{0,8,29},{0,9,154},{20,7,83},{0,8,125},
- {0,8,61},{0,9,218},{18,7,23},{0,8,109},{0,8,45},{0,9,186},{0,8,13},
- {0,8,141},{0,8,77},{0,9,250},{16,7,3},{0,8,83},{0,8,19},{21,8,195},
- {19,7,35},{0,8,115},{0,8,51},{0,9,198},{17,7,11},{0,8,99},{0,8,35},
- {0,9,166},{0,8,3},{0,8,131},{0,8,67},{0,9,230},{16,7,7},{0,8,91},
- {0,8,27},{0,9,150},{20,7,67},{0,8,123},{0,8,59},{0,9,214},{18,7,19},
- {0,8,107},{0,8,43},{0,9,182},{0,8,11},{0,8,139},{0,8,75},{0,9,246},
- {16,7,5},{0,8,87},{0,8,23},{64,8,0},{19,7,51},{0,8,119},{0,8,55},
- {0,9,206},{17,7,15},{0,8,103},{0,8,39},{0,9,174},{0,8,7},{0,8,135},
- {0,8,71},{0,9,238},{16,7,9},{0,8,95},{0,8,31},{0,9,158},{20,7,99},
- {0,8,127},{0,8,63},{0,9,222},{18,7,27},{0,8,111},{0,8,47},{0,9,190},
- {0,8,15},{0,8,143},{0,8,79},{0,9,254},{96,7,0},{0,8,80},{0,8,16},
- {20,8,115},{18,7,31},{0,8,112},{0,8,48},{0,9,193},{16,7,10},{0,8,96},
- {0,8,32},{0,9,161},{0,8,0},{0,8,128},{0,8,64},{0,9,225},{16,7,6},
- {0,8,88},{0,8,24},{0,9,145},{19,7,59},{0,8,120},{0,8,56},{0,9,209},
- {17,7,17},{0,8,104},{0,8,40},{0,9,177},{0,8,8},{0,8,136},{0,8,72},
- {0,9,241},{16,7,4},{0,8,84},{0,8,20},{21,8,227},{19,7,43},{0,8,116},
- {0,8,52},{0,9,201},{17,7,13},{0,8,100},{0,8,36},{0,9,169},{0,8,4},
- {0,8,132},{0,8,68},{0,9,233},{16,7,8},{0,8,92},{0,8,28},{0,9,153},
- {20,7,83},{0,8,124},{0,8,60},{0,9,217},{18,7,23},{0,8,108},{0,8,44},
- {0,9,185},{0,8,12},{0,8,140},{0,8,76},{0,9,249},{16,7,3},{0,8,82},
- {0,8,18},{21,8,163},{19,7,35},{0,8,114},{0,8,50},{0,9,197},{17,7,11},
- {0,8,98},{0,8,34},{0,9,165},{0,8,2},{0,8,130},{0,8,66},{0,9,229},
- {16,7,7},{0,8,90},{0,8,26},{0,9,149},{20,7,67},{0,8,122},{0,8,58},
- {0,9,213},{18,7,19},{0,8,106},{0,8,42},{0,9,181},{0,8,10},{0,8,138},
- {0,8,74},{0,9,245},{16,7,5},{0,8,86},{0,8,22},{64,8,0},{19,7,51},
- {0,8,118},{0,8,54},{0,9,205},{17,7,15},{0,8,102},{0,8,38},{0,9,173},
- {0,8,6},{0,8,134},{0,8,70},{0,9,237},{16,7,9},{0,8,94},{0,8,30},
- {0,9,157},{20,7,99},{0,8,126},{0,8,62},{0,9,221},{18,7,27},{0,8,110},
- {0,8,46},{0,9,189},{0,8,14},{0,8,142},{0,8,78},{0,9,253},{96,7,0},
- {0,8,81},{0,8,17},{21,8,131},{18,7,31},{0,8,113},{0,8,49},{0,9,195},
- {16,7,10},{0,8,97},{0,8,33},{0,9,163},{0,8,1},{0,8,129},{0,8,65},
- {0,9,227},{16,7,6},{0,8,89},{0,8,25},{0,9,147},{19,7,59},{0,8,121},
- {0,8,57},{0,9,211},{17,7,17},{0,8,105},{0,8,41},{0,9,179},{0,8,9},
- {0,8,137},{0,8,73},{0,9,243},{16,7,4},{0,8,85},{0,8,21},{16,8,258},
- {19,7,43},{0,8,117},{0,8,53},{0,9,203},{17,7,13},{0,8,101},{0,8,37},
- {0,9,171},{0,8,5},{0,8,133},{0,8,69},{0,9,235},{16,7,8},{0,8,93},
- {0,8,29},{0,9,155},{20,7,83},{0,8,125},{0,8,61},{0,9,219},{18,7,23},
- {0,8,109},{0,8,45},{0,9,187},{0,8,13},{0,8,141},{0,8,77},{0,9,251},
- {16,7,3},{0,8,83},{0,8,19},{21,8,195},{19,7,35},{0,8,115},{0,8,51},
- {0,9,199},{17,7,11},{0,8,99},{0,8,35},{0,9,167},{0,8,3},{0,8,131},
- {0,8,67},{0,9,231},{16,7,7},{0,8,91},{0,8,27},{0,9,151},{20,7,67},
- {0,8,123},{0,8,59},{0,9,215},{18,7,19},{0,8,107},{0,8,43},{0,9,183},
- {0,8,11},{0,8,139},{0,8,75},{0,9,247},{16,7,5},{0,8,87},{0,8,23},
- {64,8,0},{19,7,51},{0,8,119},{0,8,55},{0,9,207},{17,7,15},{0,8,103},
- {0,8,39},{0,9,175},{0,8,7},{0,8,135},{0,8,71},{0,9,239},{16,7,9},
- {0,8,95},{0,8,31},{0,9,159},{20,7,99},{0,8,127},{0,8,63},{0,9,223},
- {18,7,27},{0,8,111},{0,8,47},{0,9,191},{0,8,15},{0,8,143},{0,8,79},
- {0,9,255}
- };
-
- static const code distfix[32] = {
- {16,5,1},{23,5,257},{19,5,17},{27,5,4097},{17,5,5},{25,5,1025},
- {21,5,65},{29,5,16385},{16,5,3},{24,5,513},{20,5,33},{28,5,8193},
- {18,5,9},{26,5,2049},{22,5,129},{64,5,0},{16,5,2},{23,5,385},
- {19,5,25},{27,5,6145},{17,5,7},{25,5,1537},{21,5,97},{29,5,24577},
- {16,5,4},{24,5,769},{20,5,49},{28,5,12289},{18,5,13},{26,5,3073},
- {22,5,193},{64,5,0}
- };
+++ /dev/null
-/* inflate.c -- zlib decompression
- * Copyright (C) 1995-2005 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/*
- * Change history:
- *
- * 1.2.beta0 24 Nov 2002
- * - First version -- complete rewrite of inflate to simplify code, avoid
- * creation of window when not needed, minimize use of window when it is
- * needed, make inffast.c even faster, implement gzip decoding, and to
- * improve code readability and style over the previous zlib inflate code
- *
- * 1.2.beta1 25 Nov 2002
- * - Use pointers for available input and output checking in inffast.c
- * - Remove input and output counters in inffast.c
- * - Change inffast.c entry and loop from avail_in >= 7 to >= 6
- * - Remove unnecessary second byte pull from length extra in inffast.c
- * - Unroll direct copy to three copies per loop in inffast.c
- *
- * 1.2.beta2 4 Dec 2002
- * - Change external routine names to reduce potential conflicts
- * - Correct filename to inffixed.h for fixed tables in inflate.c
- * - Make hbuf[] unsigned char to match parameter type in inflate.c
- * - Change strm->next_out[-state->offset] to *(strm->next_out - state->offset)
- * to avoid negation problem on Alphas (64 bit) in inflate.c
- *
- * 1.2.beta3 22 Dec 2002
- * - Add comments on state->bits assertion in inffast.c
- * - Add comments on op field in inftrees.h
- * - Fix bug in reuse of allocated window after inflateReset()
- * - Remove bit fields--back to byte structure for speed
- * - Remove distance extra == 0 check in inflate_fast()--only helps for lengths
- * - Change post-increments to pre-increments in inflate_fast(), PPC biased?
- * - Add compile time option, POSTINC, to use post-increments instead (Intel?)
- * - Make MATCH copy in inflate() much faster for when inflate_fast() not used
- * - Use local copies of stream next and avail values, as well as local bit
- * buffer and bit count in inflate()--for speed when inflate_fast() not used
- *
- * 1.2.beta4 1 Jan 2003
- * - Split ptr - 257 statements in inflate_table() to avoid compiler warnings
- * - Move a comment on output buffer sizes from inffast.c to inflate.c
- * - Add comments in inffast.c to introduce the inflate_fast() routine
- * - Rearrange window copies in inflate_fast() for speed and simplification
- * - Unroll last copy for window match in inflate_fast()
- * - Use local copies of window variables in inflate_fast() for speed
- * - Pull out common write == 0 case for speed in inflate_fast()
- * - Make op and len in inflate_fast() unsigned for consistency
- * - Add FAR to lcode and dcode declarations in inflate_fast()
- * - Simplified bad distance check in inflate_fast()
- * - Added inflateBackInit(), inflateBack(), and inflateBackEnd() in new
- * source file infback.c to provide a call-back interface to inflate for
- * programs like gzip and unzip -- uses window as output buffer to avoid
- * window copying
- *
- * 1.2.beta5 1 Jan 2003
- * - Improved inflateBack() interface to allow the caller to provide initial
- * input in strm.
- * - Fixed stored blocks bug in inflateBack()
- *
- * 1.2.beta6 4 Jan 2003
- * - Added comments in inffast.c on effectiveness of POSTINC
- * - Typecasting all around to reduce compiler warnings
- * - Changed loops from while (1) or do {} while (1) to for (;;), again to
- * make compilers happy
- * - Changed type of window in inflateBackInit() to unsigned char *
- *
- * 1.2.beta7 27 Jan 2003
- * - Changed many types to unsigned or unsigned short to avoid warnings
- * - Added inflateCopy() function
- *
- * 1.2.0 9 Mar 2003
- * - Changed inflateBack() interface to provide separate opaque descriptors
- * for the in() and out() functions
- * - Changed inflateBack() argument and in_func typedef to swap the length
- * and buffer address return values for the input function
- * - Check next_in and next_out for Z_NULL on entry to inflate()
- *
- * The history for versions after 1.2.0 are in ChangeLog in zlib distribution.
- */
-
-#include "zutil.h"
-#include "inftrees.h"
-#include "inflate.h"
-#include "inffast.h"
-
-#ifdef MAKEFIXED
-# ifndef BUILDFIXED
-# define BUILDFIXED
-# endif
-#endif
-
-/* function prototypes */
-local void fixedtables OF((struct inflate_state FAR *state));
-local int updatewindow OF((z_streamp strm, unsigned out));
-#ifdef BUILDFIXED
- void makefixed OF((void));
-#endif
-local unsigned syncsearch OF((unsigned FAR *have, unsigned char FAR *buf,
- unsigned len));
-
-int ZEXPORT inflateReset(strm)
-z_streamp strm;
-{
- struct inflate_state FAR *state;
-
- if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
- state = (struct inflate_state FAR *)strm->state;
- strm->total_in = strm->total_out = state->total = 0;
- strm->msg = Z_NULL;
- strm->adler = 1; /* to support ill-conceived Java test suite */
- state->mode = HEAD;
- state->last = 0;
- state->havedict = 0;
- state->dmax = 32768U;
- state->head = Z_NULL;
- state->wsize = 0;
- state->whave = 0;
- state->write = 0;
- state->hold = 0;
- state->bits = 0;
- state->lencode = state->distcode = state->next = state->codes;
- Tracev((stderr, "inflate: reset\n"));
- return Z_OK;
-}
-
-int ZEXPORT inflatePrime(strm, bits, value)
-z_streamp strm;
-int bits;
-int value;
-{
- struct inflate_state FAR *state;
-
- if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
- state = (struct inflate_state FAR *)strm->state;
- if (bits > 16 || state->bits + bits > 32) return Z_STREAM_ERROR;
- value &= (1L << bits) - 1;
- state->hold += value << state->bits;
- state->bits += bits;
- return Z_OK;
-}
-
-int ZEXPORT inflateInit2_(strm, windowBits, version, stream_size)
-z_streamp strm;
-int windowBits;
-const char *version;
-int stream_size;
-{
- struct inflate_state FAR *state;
-
- if (version == Z_NULL || version[0] != ZLIB_VERSION[0] ||
- stream_size != (int)(sizeof(z_stream)))
- return Z_VERSION_ERROR;
- if (strm == Z_NULL) return Z_STREAM_ERROR;
- strm->msg = Z_NULL; /* in case we return an error */
- if (strm->zalloc == (alloc_func)0) {
- strm->zalloc = zcalloc;
- strm->opaque = (voidpf)0;
- }
- if (strm->zfree == (free_func)0) strm->zfree = zcfree;
- state = (struct inflate_state FAR *)
- ZALLOC(strm, 1, sizeof(struct inflate_state));
- if (state == Z_NULL) return Z_MEM_ERROR;
- Tracev((stderr, "inflate: allocated\n"));
- strm->state = (struct internal_state FAR *)state;
- if (windowBits < 0) {
- state->wrap = 0;
- windowBits = -windowBits;
- }
- else {
- state->wrap = (windowBits >> 4) + 1;
-#ifdef GUNZIP
- if (windowBits < 48) windowBits &= 15;
-#endif
- }
- if (windowBits < 8 || windowBits > 15) {
- ZFREE(strm, state);
- strm->state = Z_NULL;
- return Z_STREAM_ERROR;
- }
- state->wbits = (unsigned)windowBits;
- state->window = Z_NULL;
- return inflateReset(strm);
-}
-
-int ZEXPORT inflateInit_(strm, version, stream_size)
-z_streamp strm;
-const char *version;
-int stream_size;
-{
- return inflateInit2_(strm, DEF_WBITS, version, stream_size);
-}
-
-/*
- Return state with length and distance decoding tables and index sizes set to
- fixed code decoding. Normally this returns fixed tables from inffixed.h.
- If BUILDFIXED is defined, then instead this routine builds the tables the
- first time it's called, and returns those tables the first time and
- thereafter. This reduces the size of the code by about 2K bytes, in
- exchange for a little execution time. However, BUILDFIXED should not be
- used for threaded applications, since the rewriting of the tables and virgin
- may not be thread-safe.
- */
-local void fixedtables(state)
-struct inflate_state FAR *state;
-{
-#ifdef BUILDFIXED
- static int virgin = 1;
- static code *lenfix, *distfix;
- static code fixed[544];
-
- /* build fixed huffman tables if first call (may not be thread safe) */
- if (virgin) {
- unsigned sym, bits;
- static code *next;
-
- /* literal/length table */
- sym = 0;
- while (sym < 144) state->lens[sym++] = 8;
- while (sym < 256) state->lens[sym++] = 9;
- while (sym < 280) state->lens[sym++] = 7;
- while (sym < 288) state->lens[sym++] = 8;
- next = fixed;
- lenfix = next;
- bits = 9;
- inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work);
-
- /* distance table */
- sym = 0;
- while (sym < 32) state->lens[sym++] = 5;
- distfix = next;
- bits = 5;
- inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work);
-
- /* do this just once */
- virgin = 0;
- }
-#else /* !BUILDFIXED */
-# include "inffixed.h"
-#endif /* BUILDFIXED */
- state->lencode = lenfix;
- state->lenbits = 9;
- state->distcode = distfix;
- state->distbits = 5;
-}
-
-#ifdef MAKEFIXED
-#include <stdio.h>
-
-/*
- Write out the inffixed.h that is #include'd above. Defining MAKEFIXED also
- defines BUILDFIXED, so the tables are built on the fly. makefixed() writes
- those tables to stdout, which would be piped to inffixed.h. A small program
- can simply call makefixed to do this:
-
- void makefixed(void);
-
- int main(void)
- {
- makefixed();
- return 0;
- }
-
- Then that can be linked with zlib built with MAKEFIXED defined and run:
-
- a.out > inffixed.h
- */
-void makefixed()
-{
- unsigned low, size;
- struct inflate_state state;
-
- fixedtables(&state);
- puts(" /* inffixed.h -- table for decoding fixed codes");
- puts(" * Generated automatically by makefixed().");
- puts(" */");
- puts("");
- puts(" /* WARNING: this file should *not* be used by applications.");
- puts(" It is part of the implementation of this library and is");
- puts(" subject to change. Applications should only use zlib.h.");
- puts(" */");
- puts("");
- size = 1U << 9;
- printf(" static const code lenfix[%u] = {", size);
- low = 0;
- for (;;) {
- if ((low % 7) == 0) printf("\n ");
- printf("{%u,%u,%d}", state.lencode[low].op, state.lencode[low].bits,
- state.lencode[low].val);
- if (++low == size) break;
- putchar(',');
- }
- puts("\n };");
- size = 1U << 5;
- printf("\n static const code distfix[%u] = {", size);
- low = 0;
- for (;;) {
- if ((low % 6) == 0) printf("\n ");
- printf("{%u,%u,%d}", state.distcode[low].op, state.distcode[low].bits,
- state.distcode[low].val);
- if (++low == size) break;
- putchar(',');
- }
- puts("\n };");
-}
-#endif /* MAKEFIXED */
-
-/*
- Update the window with the last wsize (normally 32K) bytes written before
- returning. If window does not exist yet, create it. This is only called
- when a window is already in use, or when output has been written during this
- inflate call, but the end of the deflate stream has not been reached yet.
- It is also called to create a window for dictionary data when a dictionary
- is loaded.
-
- Providing output buffers larger than 32K to inflate() should provide a speed
- advantage, since only the last 32K of output is copied to the sliding window
- upon return from inflate(), and since all distances after the first 32K of
- output will fall in the output data, making match copies simpler and faster.
- The advantage may be dependent on the size of the processor's data caches.
- */
-local int updatewindow(strm, out)
-z_streamp strm;
-unsigned out;
-{
- struct inflate_state FAR *state;
- unsigned copy, dist;
-
- state = (struct inflate_state FAR *)strm->state;
-
- /* if it hasn't been done already, allocate space for the window */
- if (state->window == Z_NULL) {
- state->window = (unsigned char FAR *)
- ZALLOC(strm, 1U << state->wbits,
- sizeof(unsigned char));
- if (state->window == Z_NULL) return 1;
- }
-
- /* if window not in use yet, initialize */
- if (state->wsize == 0) {
- state->wsize = 1U << state->wbits;
- state->write = 0;
- state->whave = 0;
- }
-
- /* copy state->wsize or less output bytes into the circular window */
- copy = out - strm->avail_out;
- if (copy >= state->wsize) {
- zmemcpy(state->window, strm->next_out - state->wsize, state->wsize);
- state->write = 0;
- state->whave = state->wsize;
- }
- else {
- dist = state->wsize - state->write;
- if (dist > copy) dist = copy;
- zmemcpy(state->window + state->write, strm->next_out - copy, dist);
- copy -= dist;
- if (copy) {
- zmemcpy(state->window, strm->next_out - copy, copy);
- state->write = copy;
- state->whave = state->wsize;
- }
- else {
- state->write += dist;
- if (state->write == state->wsize) state->write = 0;
- if (state->whave < state->wsize) state->whave += dist;
- }
- }
- return 0;
-}
-
-/* Macros for inflate(): */
-
-/* check function to use adler32() for zlib or crc32() for gzip */
-#ifdef GUNZIP
-# define UPDATE(check, buf, len) \
- (state->flags ? crc32(check, buf, len) : adler32(check, buf, len))
-#else
-# define UPDATE(check, buf, len) adler32(check, buf, len)
-#endif
-
-/* check macros for header crc */
-#ifdef GUNZIP
-# define CRC2(check, word) \
- do { \
- hbuf[0] = (unsigned char)(word); \
- hbuf[1] = (unsigned char)((word) >> 8); \
- check = crc32(check, hbuf, 2); \
- } while (0)
-
-# define CRC4(check, word) \
- do { \
- hbuf[0] = (unsigned char)(word); \
- hbuf[1] = (unsigned char)((word) >> 8); \
- hbuf[2] = (unsigned char)((word) >> 16); \
- hbuf[3] = (unsigned char)((word) >> 24); \
- check = crc32(check, hbuf, 4); \
- } while (0)
-#endif
-
-/* Load registers with state in inflate() for speed */
-#define LOAD() \
- do { \
- put = strm->next_out; \
- left = strm->avail_out; \
- next = strm->next_in; \
- have = strm->avail_in; \
- hold = state->hold; \
- bits = state->bits; \
- } while (0)
-
-/* Restore state from registers in inflate() */
-#define RESTORE() \
- do { \
- strm->next_out = put; \
- strm->avail_out = left; \
- strm->next_in = next; \
- strm->avail_in = have; \
- state->hold = hold; \
- state->bits = bits; \
- } while (0)
-
-/* Clear the input bit accumulator */
-#define INITBITS() \
- do { \
- hold = 0; \
- bits = 0; \
- } while (0)
-
-/* Get a byte of input into the bit accumulator, or return from inflate()
- if there is no input available. */
-#define PULLBYTE() \
- do { \
- if (have == 0) goto inf_leave; \
- have--; \
- hold += (unsigned long)(*next++) << bits; \
- bits += 8; \
- } while (0)
-
-/* Assure that there are at least n bits in the bit accumulator. If there is
- not enough available input to do that, then return from inflate(). */
-#define NEEDBITS(n) \
- do { \
- while (bits < (unsigned)(n)) \
- PULLBYTE(); \
- } while (0)
-
-/* Return the low n bits of the bit accumulator (n < 16) */
-#define BITS(n) \
- ((unsigned)hold & ((1U << (n)) - 1))
-
-/* Remove n bits from the bit accumulator */
-#define DROPBITS(n) \
- do { \
- hold >>= (n); \
- bits -= (unsigned)(n); \
- } while (0)
-
-/* Remove zero to seven bits as needed to go to a byte boundary */
-#define BYTEBITS() \
- do { \
- hold >>= bits & 7; \
- bits -= bits & 7; \
- } while (0)
-
-/* Reverse the bytes in a 32-bit value */
-#define REVERSE(q) \
- ((((q) >> 24) & 0xff) + (((q) >> 8) & 0xff00) + \
- (((q) & 0xff00) << 8) + (((q) & 0xff) << 24))
-
-/*
- inflate() uses a state machine to process as much input data and generate as
- much output data as possible before returning. The state machine is
- structured roughly as follows:
-
- for (;;) switch (state) {
- ...
- case STATEn:
- if (not enough input data or output space to make progress)
- return;
- ... make progress ...
- state = STATEm;
- break;
- ...
- }
-
- so when inflate() is called again, the same case is attempted again, and
- if the appropriate resources are provided, the machine proceeds to the
- next state. The NEEDBITS() macro is usually the way the state evaluates
- whether it can proceed or should return. NEEDBITS() does the return if
- the requested bits are not available. The typical use of the BITS macros
- is:
-
- NEEDBITS(n);
- ... do something with BITS(n) ...
- DROPBITS(n);
-
- where NEEDBITS(n) either returns from inflate() if there isn't enough
- input left to load n bits into the accumulator, or it continues. BITS(n)
- gives the low n bits in the accumulator. When done, DROPBITS(n) drops
- the low n bits off the accumulator. INITBITS() clears the accumulator
- and sets the number of available bits to zero. BYTEBITS() discards just
- enough bits to put the accumulator on a byte boundary. After BYTEBITS()
- and a NEEDBITS(8), then BITS(8) would return the next byte in the stream.
-
- NEEDBITS(n) uses PULLBYTE() to get an available byte of input, or to return
- if there is no input available. The decoding of variable length codes uses
- PULLBYTE() directly in order to pull just enough bytes to decode the next
- code, and no more.
-
- Some states loop until they get enough input, making sure that enough
- state information is maintained to continue the loop where it left off
- if NEEDBITS() returns in the loop. For example, want, need, and keep
- would all have to actually be part of the saved state in case NEEDBITS()
- returns:
-
- case STATEw:
- while (want < need) {
- NEEDBITS(n);
- keep[want++] = BITS(n);
- DROPBITS(n);
- }
- state = STATEx;
- case STATEx:
-
- As shown above, if the next state is also the next case, then the break
- is omitted.
-
- A state may also return if there is not enough output space available to
- complete that state. Those states are copying stored data, writing a
- literal byte, and copying a matching string.
-
- When returning, a "goto inf_leave" is used to update the total counters,
- update the check value, and determine whether any progress has been made
- during that inflate() call in order to return the proper return code.
- Progress is defined as a change in either strm->avail_in or strm->avail_out.
- When there is a window, goto inf_leave will update the window with the last
- output written. If a goto inf_leave occurs in the middle of decompression
- and there is no window currently, goto inf_leave will create one and copy
- output to the window for the next call of inflate().
-
- In this implementation, the flush parameter of inflate() only affects the
- return code (per zlib.h). inflate() always writes as much as possible to
- strm->next_out, given the space available and the provided input--the effect
- documented in zlib.h of Z_SYNC_FLUSH. Furthermore, inflate() always defers
- the allocation of and copying into a sliding window until necessary, which
- provides the effect documented in zlib.h for Z_FINISH when the entire input
- stream available. So the only thing the flush parameter actually does is:
- when flush is set to Z_FINISH, inflate() cannot return Z_OK. Instead it
- will return Z_BUF_ERROR if it has not reached the end of the stream.
- */
-
-int ZEXPORT inflate(strm, flush)
-z_streamp strm;
-int flush;
-{
- struct inflate_state FAR *state;
- unsigned char FAR *next; /* next input */
- unsigned char FAR *put; /* next output */
- unsigned have, left; /* available input and output */
- unsigned long hold; /* bit buffer */
- unsigned bits; /* bits in bit buffer */
- unsigned in, out; /* save starting available input and output */
- unsigned copy; /* number of stored or match bytes to copy */
- unsigned char FAR *from; /* where to copy match bytes from */
- code this; /* current decoding table entry */
- code last; /* parent table entry */
- unsigned len; /* length to copy for repeats, bits to drop */
- int ret; /* return code */
-#ifdef GUNZIP
- unsigned char hbuf[4]; /* buffer for gzip header crc calculation */
-#endif
- static const unsigned short order[19] = /* permutation of code lengths */
- {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
-
- if (strm == Z_NULL || strm->state == Z_NULL || strm->next_out == Z_NULL ||
- (strm->next_in == Z_NULL && strm->avail_in != 0))
- return Z_STREAM_ERROR;
-
- state = (struct inflate_state FAR *)strm->state;
- if (state->mode == TYPE) state->mode = TYPEDO; /* skip check */
- LOAD();
- in = have;
- out = left;
- ret = Z_OK;
- for (;;)
- switch (state->mode) {
- case HEAD:
- if (state->wrap == 0) {
- state->mode = TYPEDO;
- break;
- }
- NEEDBITS(16);
-#ifdef GUNZIP
- if ((state->wrap & 2) && hold == 0x8b1f) { /* gzip header */
- state->check = crc32(0L, Z_NULL, 0);
- CRC2(state->check, hold);
- INITBITS();
- state->mode = FLAGS;
- break;
- }
- state->flags = 0; /* expect zlib header */
- if (state->head != Z_NULL)
- state->head->done = -1;
- if (!(state->wrap & 1) || /* check if zlib header allowed */
-#else
- if (
-#endif
- ((BITS(8) << 8) + (hold >> 8)) % 31) {
- strm->msg = (char *)"incorrect header check";
- state->mode = BAD;
- break;
- }
- if (BITS(4) != Z_DEFLATED) {
- strm->msg = (char *)"unknown compression method";
- state->mode = BAD;
- break;
- }
- DROPBITS(4);
- len = BITS(4) + 8;
- if (len > state->wbits) {
- strm->msg = (char *)"invalid window size";
- state->mode = BAD;
- break;
- }
- state->dmax = 1U << len;
- Tracev((stderr, "inflate: zlib header ok\n"));
- strm->adler = state->check = adler32(0L, Z_NULL, 0);
- state->mode = hold & 0x200 ? DICTID : TYPE;
- INITBITS();
- break;
-#ifdef GUNZIP
- case FLAGS:
- NEEDBITS(16);
- state->flags = (int)(hold);
- if ((state->flags & 0xff) != Z_DEFLATED) {
- strm->msg = (char *)"unknown compression method";
- state->mode = BAD;
- break;
- }
- if (state->flags & 0xe000) {
- strm->msg = (char *)"unknown header flags set";
- state->mode = BAD;
- break;
- }
- if (state->head != Z_NULL)
- state->head->text = (int)((hold >> 8) & 1);
- if (state->flags & 0x0200) CRC2(state->check, hold);
- INITBITS();
- state->mode = TIME;
- case TIME:
- NEEDBITS(32);
- if (state->head != Z_NULL)
- state->head->time = hold;
- if (state->flags & 0x0200) CRC4(state->check, hold);
- INITBITS();
- state->mode = OS;
- case OS:
- NEEDBITS(16);
- if (state->head != Z_NULL) {
- state->head->xflags = (int)(hold & 0xff);
- state->head->os = (int)(hold >> 8);
- }
- if (state->flags & 0x0200) CRC2(state->check, hold);
- INITBITS();
- state->mode = EXLEN;
- case EXLEN:
- if (state->flags & 0x0400) {
- NEEDBITS(16);
- state->length = (unsigned)(hold);
- if (state->head != Z_NULL)
- state->head->extra_len = (unsigned)hold;
- if (state->flags & 0x0200) CRC2(state->check, hold);
- INITBITS();
- }
- else if (state->head != Z_NULL)
- state->head->extra = Z_NULL;
- state->mode = EXTRA;
- case EXTRA:
- if (state->flags & 0x0400) {
- copy = state->length;
- if (copy > have) copy = have;
- if (copy) {
- if (state->head != Z_NULL &&
- state->head->extra != Z_NULL) {
- len = state->head->extra_len - state->length;
- zmemcpy(state->head->extra + len, next,
- len + copy > state->head->extra_max ?
- state->head->extra_max - len : copy);
- }
- if (state->flags & 0x0200)
- state->check = crc32(state->check, next, copy);
- have -= copy;
- next += copy;
- state->length -= copy;
- }
- if (state->length) goto inf_leave;
- }
- state->length = 0;
- state->mode = NAME;
- case NAME:
- if (state->flags & 0x0800) {
- if (have == 0) goto inf_leave;
- copy = 0;
- do {
- len = (unsigned)(next[copy++]);
- if (state->head != Z_NULL &&
- state->head->name != Z_NULL &&
- state->length < state->head->name_max)
- state->head->name[state->length++] = len;
- } while (len && copy < have);
- if (state->flags & 0x0200)
- state->check = crc32(state->check, next, copy);
- have -= copy;
- next += copy;
- if (len) goto inf_leave;
- }
- else if (state->head != Z_NULL)
- state->head->name = Z_NULL;
- state->length = 0;
- state->mode = COMMENT;
- case COMMENT:
- if (state->flags & 0x1000) {
- if (have == 0) goto inf_leave;
- copy = 0;
- do {
- len = (unsigned)(next[copy++]);
- if (state->head != Z_NULL &&
- state->head->comment != Z_NULL &&
- state->length < state->head->comm_max)
- state->head->comment[state->length++] = len;
- } while (len && copy < have);
- if (state->flags & 0x0200)
- state->check = crc32(state->check, next, copy);
- have -= copy;
- next += copy;
- if (len) goto inf_leave;
- }
- else if (state->head != Z_NULL)
- state->head->comment = Z_NULL;
- state->mode = HCRC;
- case HCRC:
- if (state->flags & 0x0200) {
- NEEDBITS(16);
- if (hold != (state->check & 0xffff)) {
- strm->msg = (char *)"header crc mismatch";
- state->mode = BAD;
- break;
- }
- INITBITS();
- }
- if (state->head != Z_NULL) {
- state->head->hcrc = (int)((state->flags >> 9) & 1);
- state->head->done = 1;
- }
- strm->adler = state->check = crc32(0L, Z_NULL, 0);
- state->mode = TYPE;
- break;
-#endif
- case DICTID:
- NEEDBITS(32);
- strm->adler = state->check = REVERSE(hold);
- INITBITS();
- state->mode = DICT;
- case DICT:
- if (state->havedict == 0) {
- RESTORE();
- return Z_NEED_DICT;
- }
- strm->adler = state->check = adler32(0L, Z_NULL, 0);
- state->mode = TYPE;
- case TYPE:
- if (flush == Z_BLOCK) goto inf_leave;
- case TYPEDO:
- if (state->last) {
- BYTEBITS();
- state->mode = CHECK;
- break;
- }
- NEEDBITS(3);
- state->last = BITS(1);
- DROPBITS(1);
- switch (BITS(2)) {
- case 0: /* stored block */
- Tracev((stderr, "inflate: stored block%s\n",
- state->last ? " (last)" : ""));
- state->mode = STORED;
- break;
- case 1: /* fixed block */
- fixedtables(state);
- Tracev((stderr, "inflate: fixed codes block%s\n",
- state->last ? " (last)" : ""));
- state->mode = LEN; /* decode codes */
- break;
- case 2: /* dynamic block */
- Tracev((stderr, "inflate: dynamic codes block%s\n",
- state->last ? " (last)" : ""));
- state->mode = TABLE;
- break;
- case 3:
- strm->msg = (char *)"invalid block type";
- state->mode = BAD;
- }
- DROPBITS(2);
- break;
- case STORED:
- BYTEBITS(); /* go to byte boundary */
- NEEDBITS(32);
- if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) {
- strm->msg = (char *)"invalid stored block lengths";
- state->mode = BAD;
- break;
- }
- state->length = (unsigned)hold & 0xffff;
- Tracev((stderr, "inflate: stored length %u\n",
- state->length));
- INITBITS();
- state->mode = COPY;
- case COPY:
- copy = state->length;
- if (copy) {
- if (copy > have) copy = have;
- if (copy > left) copy = left;
- if (copy == 0) goto inf_leave;
- zmemcpy(put, next, copy);
- have -= copy;
- next += copy;
- left -= copy;
- put += copy;
- state->length -= copy;
- break;
- }
- Tracev((stderr, "inflate: stored end\n"));
- state->mode = TYPE;
- break;
- case TABLE:
- NEEDBITS(14);
- state->nlen = BITS(5) + 257;
- DROPBITS(5);
- state->ndist = BITS(5) + 1;
- DROPBITS(5);
- state->ncode = BITS(4) + 4;
- DROPBITS(4);
-#ifndef PKZIP_BUG_WORKAROUND
- if (state->nlen > 286 || state->ndist > 30) {
- strm->msg = (char *)"too many length or distance symbols";
- state->mode = BAD;
- break;
- }
-#endif
- Tracev((stderr, "inflate: table sizes ok\n"));
- state->have = 0;
- state->mode = LENLENS;
- case LENLENS:
- while (state->have < state->ncode) {
- NEEDBITS(3);
- state->lens[order[state->have++]] = (unsigned short)BITS(3);
- DROPBITS(3);
- }
- while (state->have < 19)
- state->lens[order[state->have++]] = 0;
- state->next = state->codes;
- state->lencode = (code const FAR *)(state->next);
- state->lenbits = 7;
- ret = inflate_table(CODES, state->lens, 19, &(state->next),
- &(state->lenbits), state->work);
- if (ret) {
- strm->msg = (char *)"invalid code lengths set";
- state->mode = BAD;
- break;
- }
- Tracev((stderr, "inflate: code lengths ok\n"));
- state->have = 0;
- state->mode = CODELENS;
- case CODELENS:
- while (state->have < state->nlen + state->ndist) {
- for (;;) {
- this = state->lencode[BITS(state->lenbits)];
- if ((unsigned)(this.bits) <= bits) break;
- PULLBYTE();
- }
- if (this.val < 16) {
- NEEDBITS(this.bits);
- DROPBITS(this.bits);
- state->lens[state->have++] = this.val;
- }
- else {
- if (this.val == 16) {
- NEEDBITS(this.bits + 2);
- DROPBITS(this.bits);
- if (state->have == 0) {
- strm->msg = (char *)"invalid bit length repeat";
- state->mode = BAD;
- break;
- }
- len = state->lens[state->have - 1];
- copy = 3 + BITS(2);
- DROPBITS(2);
- }
- else if (this.val == 17) {
- NEEDBITS(this.bits + 3);
- DROPBITS(this.bits);
- len = 0;
- copy = 3 + BITS(3);
- DROPBITS(3);
- }
- else {
- NEEDBITS(this.bits + 7);
- DROPBITS(this.bits);
- len = 0;
- copy = 11 + BITS(7);
- DROPBITS(7);
- }
- if (state->have + copy > state->nlen + state->ndist) {
- strm->msg = (char *)"invalid bit length repeat";
- state->mode = BAD;
- break;
- }
- while (copy--)
- state->lens[state->have++] = (unsigned short)len;
- }
- }
-
- /* handle error breaks in while */
- if (state->mode == BAD) break;
-
- /* build code tables */
- state->next = state->codes;
- state->lencode = (code const FAR *)(state->next);
- state->lenbits = 9;
- ret = inflate_table(LENS, state->lens, state->nlen, &(state->next),
- &(state->lenbits), state->work);
- if (ret) {
- strm->msg = (char *)"invalid literal/lengths set";
- state->mode = BAD;
- break;
- }
- state->distcode = (code const FAR *)(state->next);
- state->distbits = 6;
- ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist,
- &(state->next), &(state->distbits), state->work);
- if (ret) {
- strm->msg = (char *)"invalid distances set";
- state->mode = BAD;
- break;
- }
- Tracev((stderr, "inflate: codes ok\n"));
- state->mode = LEN;
- case LEN:
- if (have >= 6 && left >= 258) {
- RESTORE();
- inflate_fast(strm, out);
- LOAD();
- break;
- }
- for (;;) {
- this = state->lencode[BITS(state->lenbits)];
- if ((unsigned)(this.bits) <= bits) break;
- PULLBYTE();
- }
- if (this.op && (this.op & 0xf0) == 0) {
- last = this;
- for (;;) {
- this = state->lencode[last.val +
- (BITS(last.bits + last.op) >> last.bits)];
- if ((unsigned)(last.bits + this.bits) <= bits) break;
- PULLBYTE();
- }
- DROPBITS(last.bits);
- }
- DROPBITS(this.bits);
- state->length = (unsigned)this.val;
- if ((int)(this.op) == 0) {
- Tracevv((stderr, this.val >= 0x20 && this.val < 0x7f ?
- "inflate: literal '%c'\n" :
- "inflate: literal 0x%02x\n", this.val));
- state->mode = LIT;
- break;
- }
- if (this.op & 32) {
- Tracevv((stderr, "inflate: end of block\n"));
- state->mode = TYPE;
- break;
- }
- if (this.op & 64) {
- strm->msg = (char *)"invalid literal/length code";
- state->mode = BAD;
- break;
- }
- state->extra = (unsigned)(this.op) & 15;
- state->mode = LENEXT;
- case LENEXT:
- if (state->extra) {
- NEEDBITS(state->extra);
- state->length += BITS(state->extra);
- DROPBITS(state->extra);
- }
- Tracevv((stderr, "inflate: length %u\n", state->length));
- state->mode = DIST;
- case DIST:
- for (;;) {
- this = state->distcode[BITS(state->distbits)];
- if ((unsigned)(this.bits) <= bits) break;
- PULLBYTE();
- }
- if ((this.op & 0xf0) == 0) {
- last = this;
- for (;;) {
- this = state->distcode[last.val +
- (BITS(last.bits + last.op) >> last.bits)];
- if ((unsigned)(last.bits + this.bits) <= bits) break;
- PULLBYTE();
- }
- DROPBITS(last.bits);
- }
- DROPBITS(this.bits);
- if (this.op & 64) {
- strm->msg = (char *)"invalid distance code";
- state->mode = BAD;
- break;
- }
- state->offset = (unsigned)this.val;
- state->extra = (unsigned)(this.op) & 15;
- state->mode = DISTEXT;
- case DISTEXT:
- if (state->extra) {
- NEEDBITS(state->extra);
- state->offset += BITS(state->extra);
- DROPBITS(state->extra);
- }
-#ifdef INFLATE_STRICT
- if (state->offset > state->dmax) {
- strm->msg = (char *)"invalid distance too far back";
- state->mode = BAD;
- break;
- }
-#endif
- if (state->offset > state->whave + out - left) {
- strm->msg = (char *)"invalid distance too far back";
- state->mode = BAD;
- break;
- }
- Tracevv((stderr, "inflate: distance %u\n", state->offset));
- state->mode = MATCH;
- case MATCH:
- if (left == 0) goto inf_leave;
- copy = out - left;
- if (state->offset > copy) { /* copy from window */
- copy = state->offset - copy;
- if (copy > state->write) {
- copy -= state->write;
- from = state->window + (state->wsize - copy);
- }
- else
- from = state->window + (state->write - copy);
- if (copy > state->length) copy = state->length;
- }
- else { /* copy from output */
- from = put - state->offset;
- copy = state->length;
- }
- if (copy > left) copy = left;
- left -= copy;
- state->length -= copy;
- do {
- *put++ = *from++;
- } while (--copy);
- if (state->length == 0) state->mode = LEN;
- break;
- case LIT:
- if (left == 0) goto inf_leave;
- *put++ = (unsigned char)(state->length);
- left--;
- state->mode = LEN;
- break;
- case CHECK:
- if (state->wrap) {
- NEEDBITS(32);
- out -= left;
- strm->total_out += out;
- state->total += out;
- if (out)
- strm->adler = state->check =
- UPDATE(state->check, put - out, out);
- out = left;
- if ((
-#ifdef GUNZIP
- state->flags ? hold :
-#endif
- REVERSE(hold)) != state->check) {
- strm->msg = (char *)"incorrect data check";
- state->mode = BAD;
- break;
- }
- INITBITS();
- Tracev((stderr, "inflate: check matches trailer\n"));
- }
-#ifdef GUNZIP
- state->mode = LENGTH;
- case LENGTH:
- if (state->wrap && state->flags) {
- NEEDBITS(32);
- if (hold != (state->total & 0xffffffffUL)) {
- strm->msg = (char *)"incorrect length check";
- state->mode = BAD;
- break;
- }
- INITBITS();
- Tracev((stderr, "inflate: length matches trailer\n"));
- }
-#endif
- state->mode = DONE;
- case DONE:
- ret = Z_STREAM_END;
- goto inf_leave;
- case BAD:
- ret = Z_DATA_ERROR;
- goto inf_leave;
- case MEM:
- return Z_MEM_ERROR;
- case SYNC:
- default:
- return Z_STREAM_ERROR;
- }
-
- /*
- Return from inflate(), updating the total counts and the check value.
- If there was no progress during the inflate() call, return a buffer
- error. Call updatewindow() to create and/or update the window state.
- Note: a memory error from inflate() is non-recoverable.
- */
- inf_leave:
- RESTORE();
- if (state->wsize || (state->mode < CHECK && out != strm->avail_out))
- if (updatewindow(strm, out)) {
- state->mode = MEM;
- return Z_MEM_ERROR;
- }
- in -= strm->avail_in;
- out -= strm->avail_out;
- strm->total_in += in;
- strm->total_out += out;
- state->total += out;
- if (state->wrap && out)
- strm->adler = state->check =
- UPDATE(state->check, strm->next_out - out, out);
- strm->data_type = state->bits + (state->last ? 64 : 0) +
- (state->mode == TYPE ? 128 : 0);
- if (((in == 0 && out == 0) || flush == Z_FINISH) && ret == Z_OK)
- ret = Z_BUF_ERROR;
- return ret;
-}
-
-int ZEXPORT inflateEnd(strm)
-z_streamp strm;
-{
- struct inflate_state FAR *state;
- if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0)
- return Z_STREAM_ERROR;
- state = (struct inflate_state FAR *)strm->state;
- if (state->window != Z_NULL) ZFREE(strm, state->window);
- ZFREE(strm, strm->state);
- strm->state = Z_NULL;
- Tracev((stderr, "inflate: end\n"));
- return Z_OK;
-}
-
-int ZEXPORT inflateSetDictionary(strm, dictionary, dictLength)
-z_streamp strm;
-const Bytef *dictionary;
-uInt dictLength;
-{
- struct inflate_state FAR *state;
- unsigned long id;
-
- /* check state */
- if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
- state = (struct inflate_state FAR *)strm->state;
- if (state->wrap != 0 && state->mode != DICT)
- return Z_STREAM_ERROR;
-
- /* check for correct dictionary id */
- if (state->mode == DICT) {
- id = adler32(0L, Z_NULL, 0);
- id = adler32(id, dictionary, dictLength);
- if (id != state->check)
- return Z_DATA_ERROR;
- }
-
- /* copy dictionary to window */
- if (updatewindow(strm, strm->avail_out)) {
- state->mode = MEM;
- return Z_MEM_ERROR;
- }
- if (dictLength > state->wsize) {
- zmemcpy(state->window, dictionary + dictLength - state->wsize,
- state->wsize);
- state->whave = state->wsize;
- }
- else {
- zmemcpy(state->window + state->wsize - dictLength, dictionary,
- dictLength);
- state->whave = dictLength;
- }
- state->havedict = 1;
- Tracev((stderr, "inflate: dictionary set\n"));
- return Z_OK;
-}
-
-int ZEXPORT inflateGetHeader(strm, head)
-z_streamp strm;
-gz_headerp head;
-{
- struct inflate_state FAR *state;
-
- /* check state */
- if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
- state = (struct inflate_state FAR *)strm->state;
- if ((state->wrap & 2) == 0) return Z_STREAM_ERROR;
-
- /* save header structure */
- state->head = head;
- head->done = 0;
- return Z_OK;
-}
-
-/*
- Search buf[0..len-1] for the pattern: 0, 0, 0xff, 0xff. Return when found
- or when out of input. When called, *have is the number of pattern bytes
- found in order so far, in 0..3. On return *have is updated to the new
- state. If on return *have equals four, then the pattern was found and the
- return value is how many bytes were read including the last byte of the
- pattern. If *have is less than four, then the pattern has not been found
- yet and the return value is len. In the latter case, syncsearch() can be
- called again with more data and the *have state. *have is initialized to
- zero for the first call.
- */
-local unsigned syncsearch(have, buf, len)
-unsigned FAR *have;
-unsigned char FAR *buf;
-unsigned len;
-{
- unsigned got;
- unsigned next;
-
- got = *have;
- next = 0;
- while (next < len && got < 4) {
- if ((int)(buf[next]) == (got < 2 ? 0 : 0xff))
- got++;
- else if (buf[next])
- got = 0;
- else
- got = 4 - got;
- next++;
- }
- *have = got;
- return next;
-}
-
-int ZEXPORT inflateSync(strm)
-z_streamp strm;
-{
- unsigned len; /* number of bytes to look at or looked at */
- unsigned long in, out; /* temporary to save total_in and total_out */
- unsigned char buf[4]; /* to restore bit buffer to byte string */
- struct inflate_state FAR *state;
-
- /* check parameters */
- if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
- state = (struct inflate_state FAR *)strm->state;
- if (strm->avail_in == 0 && state->bits < 8) return Z_BUF_ERROR;
-
- /* if first time, start search in bit buffer */
- if (state->mode != SYNC) {
- state->mode = SYNC;
- state->hold <<= state->bits & 7;
- state->bits -= state->bits & 7;
- len = 0;
- while (state->bits >= 8) {
- buf[len++] = (unsigned char)(state->hold);
- state->hold >>= 8;
- state->bits -= 8;
- }
- state->have = 0;
- syncsearch(&(state->have), buf, len);
- }
-
- /* search available input */
- len = syncsearch(&(state->have), strm->next_in, strm->avail_in);
- strm->avail_in -= len;
- strm->next_in += len;
- strm->total_in += len;
-
- /* return no joy or set up to restart inflate() on a new block */
- if (state->have != 4) return Z_DATA_ERROR;
- in = strm->total_in; out = strm->total_out;
- inflateReset(strm);
- strm->total_in = in; strm->total_out = out;
- state->mode = TYPE;
- return Z_OK;
-}
-
-/*
- Returns true if inflate is currently at the end of a block generated by
- Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP
- implementation to provide an additional safety check. PPP uses
- Z_SYNC_FLUSH but removes the length bytes of the resulting empty stored
- block. When decompressing, PPP checks that at the end of input packet,
- inflate is waiting for these length bytes.
- */
-int ZEXPORT inflateSyncPoint(strm)
-z_streamp strm;
-{
- struct inflate_state FAR *state;
-
- if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
- state = (struct inflate_state FAR *)strm->state;
- return state->mode == STORED && state->bits == 0;
-}
-
-int ZEXPORT inflateCopy(dest, source)
-z_streamp dest;
-z_streamp source;
-{
- struct inflate_state FAR *state;
- struct inflate_state FAR *copy;
- unsigned char FAR *window;
- unsigned wsize;
-
- /* check input */
- if (dest == Z_NULL || source == Z_NULL || source->state == Z_NULL ||
- source->zalloc == (alloc_func)0 || source->zfree == (free_func)0)
- return Z_STREAM_ERROR;
- state = (struct inflate_state FAR *)source->state;
-
- /* allocate space */
- copy = (struct inflate_state FAR *)
- ZALLOC(source, 1, sizeof(struct inflate_state));
- if (copy == Z_NULL) return Z_MEM_ERROR;
- window = Z_NULL;
- if (state->window != Z_NULL) {
- window = (unsigned char FAR *)
- ZALLOC(source, 1U << state->wbits, sizeof(unsigned char));
- if (window == Z_NULL) {
- ZFREE(source, copy);
- return Z_MEM_ERROR;
- }
- }
-
- /* copy state */
- zmemcpy(dest, source, sizeof(z_stream));
- zmemcpy(copy, state, sizeof(struct inflate_state));
- if (state->lencode >= state->codes &&
- state->lencode <= state->codes + ENOUGH - 1) {
- copy->lencode = copy->codes + (state->lencode - state->codes);
- copy->distcode = copy->codes + (state->distcode - state->codes);
- }
- copy->next = copy->codes + (state->next - state->codes);
- if (window != Z_NULL) {
- wsize = 1U << state->wbits;
- zmemcpy(window, state->window, wsize);
- }
- copy->window = window;
- dest->state = (struct internal_state FAR *)copy;
- return Z_OK;
-}
+++ /dev/null
-/* inflate.h -- internal inflate state definition
- * Copyright (C) 1995-2004 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* WARNING: this file should *not* be used by applications. It is
- part of the implementation of the compression library and is
- subject to change. Applications should only use zlib.h.
- */
-
-/* define NO_GZIP when compiling if you want to disable gzip header and
- trailer decoding by inflate(). NO_GZIP would be used to avoid linking in
- the crc code when it is not needed. For shared libraries, gzip decoding
- should be left enabled. */
-#ifndef NO_GZIP
-# define GUNZIP
-#endif
-
-/* Possible inflate modes between inflate() calls */
-typedef enum {
- HEAD, /* i: waiting for magic header */
- FLAGS, /* i: waiting for method and flags (gzip) */
- TIME, /* i: waiting for modification time (gzip) */
- OS, /* i: waiting for extra flags and operating system (gzip) */
- EXLEN, /* i: waiting for extra length (gzip) */
- EXTRA, /* i: waiting for extra bytes (gzip) */
- NAME, /* i: waiting for end of file name (gzip) */
- COMMENT, /* i: waiting for end of comment (gzip) */
- HCRC, /* i: waiting for header crc (gzip) */
- DICTID, /* i: waiting for dictionary check value */
- DICT, /* waiting for inflateSetDictionary() call */
- TYPE, /* i: waiting for type bits, including last-flag bit */
- TYPEDO, /* i: same, but skip check to exit inflate on new block */
- STORED, /* i: waiting for stored size (length and complement) */
- COPY, /* i/o: waiting for input or output to copy stored block */
- TABLE, /* i: waiting for dynamic block table lengths */
- LENLENS, /* i: waiting for code length code lengths */
- CODELENS, /* i: waiting for length/lit and distance code lengths */
- LEN, /* i: waiting for length/lit code */
- LENEXT, /* i: waiting for length extra bits */
- DIST, /* i: waiting for distance code */
- DISTEXT, /* i: waiting for distance extra bits */
- MATCH, /* o: waiting for output space to copy string */
- LIT, /* o: waiting for output space to write literal */
- CHECK, /* i: waiting for 32-bit check value */
- LENGTH, /* i: waiting for 32-bit length (gzip) */
- DONE, /* finished check, done -- remain here until reset */
- BAD, /* got a data error -- remain here until reset */
- MEM, /* got an inflate() memory error -- remain here until reset */
- SYNC /* looking for synchronization bytes to restart inflate() */
-} inflate_mode;
-
-/*
- State transitions between above modes -
-
- (most modes can go to the BAD or MEM mode -- not shown for clarity)
-
- Process header:
- HEAD -> (gzip) or (zlib)
- (gzip) -> FLAGS -> TIME -> OS -> EXLEN -> EXTRA -> NAME
- NAME -> COMMENT -> HCRC -> TYPE
- (zlib) -> DICTID or TYPE
- DICTID -> DICT -> TYPE
- Read deflate blocks:
- TYPE -> STORED or TABLE or LEN or CHECK
- STORED -> COPY -> TYPE
- TABLE -> LENLENS -> CODELENS -> LEN
- Read deflate codes:
- LEN -> LENEXT or LIT or TYPE
- LENEXT -> DIST -> DISTEXT -> MATCH -> LEN
- LIT -> LEN
- Process trailer:
- CHECK -> LENGTH -> DONE
- */
-
-/* state maintained between inflate() calls. Approximately 7K bytes. */
-struct inflate_state {
- inflate_mode mode; /* current inflate mode */
- int last; /* true if processing last block */
- int wrap; /* bit 0 true for zlib, bit 1 true for gzip */
- int havedict; /* true if dictionary provided */
- int flags; /* gzip header method and flags (0 if zlib) */
- unsigned dmax; /* zlib header max distance (INFLATE_STRICT) */
- unsigned long check; /* protected copy of check value */
- unsigned long total; /* protected copy of output count */
- gz_headerp head; /* where to save gzip header information */
- /* sliding window */
- unsigned wbits; /* log base 2 of requested window size */
- unsigned wsize; /* window size or zero if not using window */
- unsigned whave; /* valid bytes in the window */
- unsigned write; /* window write index */
- unsigned char FAR *window; /* allocated sliding window, if needed */
- /* bit accumulator */
- unsigned long hold; /* input bit accumulator */
- unsigned bits; /* number of bits in "in" */
- /* for string and stored block copying */
- unsigned length; /* literal or length of data to copy */
- unsigned offset; /* distance back to copy string from */
- /* for table and code decoding */
- unsigned extra; /* extra bits needed */
- /* fixed and dynamic code tables */
- code const FAR *lencode; /* starting table for length/literal codes */
- code const FAR *distcode; /* starting table for distance codes */
- unsigned lenbits; /* index bits for lencode */
- unsigned distbits; /* index bits for distcode */
- /* dynamic table building */
- unsigned ncode; /* number of code length code lengths */
- unsigned nlen; /* number of length code lengths */
- unsigned ndist; /* number of distance code lengths */
- unsigned have; /* number of code lengths in lens[] */
- code FAR *next; /* next available space in codes[] */
- unsigned short lens[320]; /* temporary storage for code lengths */
- unsigned short work[288]; /* work area for code table building */
- code codes[ENOUGH]; /* space for code tables */
-};
+++ /dev/null
-/* inftrees.c -- generate Huffman trees for efficient decoding
- * Copyright (C) 1995-2005 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-#include "zutil.h"
-#include "inftrees.h"
-
-#define MAXBITS 15
-
-const char inflate_copyright[] =
- " inflate 1.2.3 Copyright 1995-2005 Mark Adler ";
-/*
- If you use the zlib library in a product, an acknowledgment is welcome
- in the documentation of your product. If for some reason you cannot
- include such an acknowledgment, I would appreciate that you keep this
- copyright string in the executable of your product.
- */
-
-/*
- Build a set of tables to decode the provided canonical Huffman code.
- The code lengths are lens[0..codes-1]. The result starts at *table,
- whose indices are 0..2^bits-1. work is a writable array of at least
- lens shorts, which is used as a work area. type is the type of code
- to be generated, CODES, LENS, or DISTS. On return, zero is success,
- -1 is an invalid code, and +1 means that ENOUGH isn't enough. table
- on return points to the next available entry's address. bits is the
- requested root table index bits, and on return it is the actual root
- table index bits. It will differ if the request is greater than the
- longest code or if it is less than the shortest code.
- */
-int inflate_table(type, lens, codes, table, bits, work)
-codetype type;
-unsigned short FAR *lens;
-unsigned codes;
-code FAR * FAR *table;
-unsigned FAR *bits;
-unsigned short FAR *work;
-{
- unsigned len; /* a code's length in bits */
- unsigned sym; /* index of code symbols */
- unsigned min, max; /* minimum and maximum code lengths */
- unsigned root; /* number of index bits for root table */
- unsigned curr; /* number of index bits for current table */
- unsigned drop; /* code bits to drop for sub-table */
- int left; /* number of prefix codes available */
- unsigned used; /* code entries in table used */
- unsigned huff; /* Huffman code */
- unsigned incr; /* for incrementing code, index */
- unsigned fill; /* index for replicating entries */
- unsigned low; /* low bits for current root entry */
- unsigned mask; /* mask for low root bits */
- code this; /* table entry for duplication */
- code FAR *next; /* next available space in table */
- const unsigned short FAR *base; /* base value table to use */
- const unsigned short FAR *extra; /* extra bits table to use */
- int end; /* use base and extra for symbol > end */
- unsigned short count[MAXBITS+1]; /* number of codes of each length */
- unsigned short offs[MAXBITS+1]; /* offsets in table for each length */
- static const unsigned short lbase[31] = { /* Length codes 257..285 base */
- 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
- 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0};
- static const unsigned short lext[31] = { /* Length codes 257..285 extra */
- 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18,
- 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 201, 196};
- static const unsigned short dbase[32] = { /* Distance codes 0..29 base */
- 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
- 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
- 8193, 12289, 16385, 24577, 0, 0};
- static const unsigned short dext[32] = { /* Distance codes 0..29 extra */
- 16, 16, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22,
- 23, 23, 24, 24, 25, 25, 26, 26, 27, 27,
- 28, 28, 29, 29, 64, 64};
-
- /*
- Process a set of code lengths to create a canonical Huffman code. The
- code lengths are lens[0..codes-1]. Each length corresponds to the
- symbols 0..codes-1. The Huffman code is generated by first sorting the
- symbols by length from short to long, and retaining the symbol order
- for codes with equal lengths. Then the code starts with all zero bits
- for the first code of the shortest length, and the codes are integer
- increments for the same length, and zeros are appended as the length
- increases. For the deflate format, these bits are stored backwards
- from their more natural integer increment ordering, and so when the
- decoding tables are built in the large loop below, the integer codes
- are incremented backwards.
-
- This routine assumes, but does not check, that all of the entries in
- lens[] are in the range 0..MAXBITS. The caller must assure this.
- 1..MAXBITS is interpreted as that code length. zero means that that
- symbol does not occur in this code.
-
- The codes are sorted by computing a count of codes for each length,
- creating from that a table of starting indices for each length in the
- sorted table, and then entering the symbols in order in the sorted
- table. The sorted table is work[], with that space being provided by
- the caller.
-
- The length counts are used for other purposes as well, i.e. finding
- the minimum and maximum length codes, determining if there are any
- codes at all, checking for a valid set of lengths, and looking ahead
- at length counts to determine sub-table sizes when building the
- decoding tables.
- */
-
- /* accumulate lengths for codes (assumes lens[] all in 0..MAXBITS) */
- for (len = 0; len <= MAXBITS; len++)
- count[len] = 0;
- for (sym = 0; sym < codes; sym++)
- count[lens[sym]]++;
-
- /* bound code lengths, force root to be within code lengths */
- root = *bits;
- for (max = MAXBITS; max >= 1; max--)
- if (count[max] != 0) break;
- if (root > max) root = max;
- if (max == 0) { /* no symbols to code at all */
- this.op = (unsigned char)64; /* invalid code marker */
- this.bits = (unsigned char)1;
- this.val = (unsigned short)0;
- *(*table)++ = this; /* make a table to force an error */
- *(*table)++ = this;
- *bits = 1;
- return 0; /* no symbols, but wait for decoding to report error */
- }
- for (min = 1; min <= MAXBITS; min++)
- if (count[min] != 0) break;
- if (root < min) root = min;
-
- /* check for an over-subscribed or incomplete set of lengths */
- left = 1;
- for (len = 1; len <= MAXBITS; len++) {
- left <<= 1;
- left -= count[len];
- if (left < 0) return -1; /* over-subscribed */
- }
- if (left > 0 && (type == CODES || max != 1))
- return -1; /* incomplete set */
-
- /* generate offsets into symbol table for each length for sorting */
- offs[1] = 0;
- for (len = 1; len < MAXBITS; len++)
- offs[len + 1] = offs[len] + count[len];
-
- /* sort symbols by length, by symbol order within each length */
- for (sym = 0; sym < codes; sym++)
- if (lens[sym] != 0) work[offs[lens[sym]]++] = (unsigned short)sym;
-
- /*
- Create and fill in decoding tables. In this loop, the table being
- filled is at next and has curr index bits. The code being used is huff
- with length len. That code is converted to an index by dropping drop
- bits off of the bottom. For codes where len is less than drop + curr,
- those top drop + curr - len bits are incremented through all values to
- fill the table with replicated entries.
-
- root is the number of index bits for the root table. When len exceeds
- root, sub-tables are created pointed to by the root entry with an index
- of the low root bits of huff. This is saved in low to check for when a
- new sub-table should be started. drop is zero when the root table is
- being filled, and drop is root when sub-tables are being filled.
-
- When a new sub-table is needed, it is necessary to look ahead in the
- code lengths to determine what size sub-table is needed. The length
- counts are used for this, and so count[] is decremented as codes are
- entered in the tables.
-
- used keeps track of how many table entries have been allocated from the
- provided *table space. It is checked when a LENS table is being made
- against the space in *table, ENOUGH, minus the maximum space needed by
- the worst case distance code, MAXD. This should never happen, but the
- sufficiency of ENOUGH has not been proven exhaustively, hence the check.
- This assumes that when type == LENS, bits == 9.
-
- sym increments through all symbols, and the loop terminates when
- all codes of length max, i.e. all codes, have been processed. This
- routine permits incomplete codes, so another loop after this one fills
- in the rest of the decoding tables with invalid code markers.
- */
-
- /* set up for code type */
- switch (type) {
- case CODES:
- base = extra = work; /* dummy value--not used */
- end = 19;
- break;
- case LENS:
- base = lbase;
- base -= 257;
- extra = lext;
- extra -= 257;
- end = 256;
- break;
- default: /* DISTS */
- base = dbase;
- extra = dext;
- end = -1;
- }
-
- /* initialize state for loop */
- huff = 0; /* starting code */
- sym = 0; /* starting code symbol */
- len = min; /* starting code length */
- next = *table; /* current table to fill in */
- curr = root; /* current table index bits */
- drop = 0; /* current bits to drop from code for index */
- low = (unsigned)(-1); /* trigger new sub-table when len > root */
- used = 1U << root; /* use root table entries */
- mask = used - 1; /* mask for comparing low */
-
- /* check available table space */
- if (type == LENS && used >= ENOUGH - MAXD)
- return 1;
-
- /* process all codes and make table entries */
- for (;;) {
- /* create table entry */
- this.bits = (unsigned char)(len - drop);
- if ((int)(work[sym]) < end) {
- this.op = (unsigned char)0;
- this.val = work[sym];
- }
- else if ((int)(work[sym]) > end) {
- this.op = (unsigned char)(extra[work[sym]]);
- this.val = base[work[sym]];
- }
- else {
- this.op = (unsigned char)(32 + 64); /* end of block */
- this.val = 0;
- }
-
- /* replicate for those indices with low len bits equal to huff */
- incr = 1U << (len - drop);
- fill = 1U << curr;
- min = fill; /* save offset to next table */
- do {
- fill -= incr;
- next[(huff >> drop) + fill] = this;
- } while (fill != 0);
-
- /* backwards increment the len-bit code huff */
- incr = 1U << (len - 1);
- while (huff & incr)
- incr >>= 1;
- if (incr != 0) {
- huff &= incr - 1;
- huff += incr;
- }
- else
- huff = 0;
-
- /* go to next symbol, update count, len */
- sym++;
- if (--(count[len]) == 0) {
- if (len == max) break;
- len = lens[work[sym]];
- }
-
- /* create new sub-table if needed */
- if (len > root && (huff & mask) != low) {
- /* if first time, transition to sub-tables */
- if (drop == 0)
- drop = root;
-
- /* increment past last table */
- next += min; /* here min is 1 << curr */
-
- /* determine length of next table */
- curr = len - drop;
- left = (int)(1 << curr);
- while (curr + drop < max) {
- left -= count[curr + drop];
- if (left <= 0) break;
- curr++;
- left <<= 1;
- }
-
- /* check for enough space */
- used += 1U << curr;
- if (type == LENS && used >= ENOUGH - MAXD)
- return 1;
-
- /* point entry in root table to sub-table */
- low = huff & mask;
- (*table)[low].op = (unsigned char)curr;
- (*table)[low].bits = (unsigned char)root;
- (*table)[low].val = (unsigned short)(next - *table);
- }
- }
-
- /*
- Fill in rest of table for incomplete codes. This loop is similar to the
- loop above in incrementing huff for table indices. It is assumed that
- len is equal to curr + drop, so there is no loop needed to increment
- through high index bits. When the current sub-table is filled, the loop
- drops back to the root table to fill in any remaining entries there.
- */
- this.op = (unsigned char)64; /* invalid code marker */
- this.bits = (unsigned char)(len - drop);
- this.val = (unsigned short)0;
- while (huff != 0) {
- /* when done with sub-table, drop back to root table */
- if (drop != 0 && (huff & mask) != low) {
- drop = 0;
- len = root;
- next = *table;
- this.bits = (unsigned char)len;
- }
-
- /* put invalid code marker in table */
- next[huff >> drop] = this;
-
- /* backwards increment the len-bit code huff */
- incr = 1U << (len - 1);
- while (huff & incr)
- incr >>= 1;
- if (incr != 0) {
- huff &= incr - 1;
- huff += incr;
- }
- else
- huff = 0;
- }
-
- /* set return parameters */
- *table += used;
- *bits = root;
- return 0;
-}
+++ /dev/null
-/* inftrees.h -- header to use inftrees.c
- * Copyright (C) 1995-2005 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* WARNING: this file should *not* be used by applications. It is
- part of the implementation of the compression library and is
- subject to change. Applications should only use zlib.h.
- */
-
-/* Structure for decoding tables. Each entry provides either the
- information needed to do the operation requested by the code that
- indexed that table entry, or it provides a pointer to another
- table that indexes more bits of the code. op indicates whether
- the entry is a pointer to another table, a literal, a length or
- distance, an end-of-block, or an invalid code. For a table
- pointer, the low four bits of op is the number of index bits of
- that table. For a length or distance, the low four bits of op
- is the number of extra bits to get after the code. bits is
- the number of bits in this code or part of the code to drop off
- of the bit buffer. val is the actual byte to output in the case
- of a literal, the base length or distance, or the offset from
- the current table to the next table. Each entry is four bytes. */
-typedef struct {
- unsigned char op; /* operation, extra bits, table bits */
- unsigned char bits; /* bits in this part of the code */
- unsigned short val; /* offset in table or code value */
-} code;
-
-/* op values as set by inflate_table():
- 00000000 - literal
- 0000tttt - table link, tttt != 0 is the number of table index bits
- 0001eeee - length or distance, eeee is the number of extra bits
- 01100000 - end of block
- 01000000 - invalid code
- */
-
-/* Maximum size of dynamic tree. The maximum found in a long but non-
- exhaustive search was 1444 code structures (852 for length/literals
- and 592 for distances, the latter actually the result of an
- exhaustive search). The true maximum is not known, but the value
- below is more than safe. */
-#define ENOUGH 2048
-#define MAXD 592
-
-/* Type of code to build for inftable() */
-typedef enum {
- CODES,
- LENS,
- DISTS
-} codetype;
-
-extern int inflate_table OF((codetype type, unsigned short FAR *lens,
- unsigned codes, code FAR * FAR *table,
- unsigned FAR *bits, unsigned short FAR *work));
+++ /dev/null
-/* trees.c -- output deflated data using Huffman coding
- * Copyright (C) 1995-2005 Jean-loup Gailly
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/*
- * ALGORITHM
- *
- * The "deflation" process uses several Huffman trees. The more
- * common source values are represented by shorter bit sequences.
- *
- * Each code tree is stored in a compressed form which is itself
- * a Huffman encoding of the lengths of all the code strings (in
- * ascending order by source values). The actual code strings are
- * reconstructed from the lengths in the inflate process, as described
- * in the deflate specification.
- *
- * REFERENCES
- *
- * Deutsch, L.P.,"'Deflate' Compressed Data Format Specification".
- * Available in ftp.uu.net:/pub/archiving/zip/doc/deflate-1.1.doc
- *
- * Storer, James A.
- * Data Compression: Methods and Theory, pp. 49-50.
- * Computer Science Press, 1988. ISBN 0-7167-8156-5.
- *
- * Sedgewick, R.
- * Algorithms, p290.
- * Addison-Wesley, 1983. ISBN 0-201-06672-6.
- */
-
-/* @(#) $Id$ */
-
-/* #define GEN_TREES_H */
-
-#include "deflate.h"
-
-#ifdef DEBUG
-# include <ctype.h>
-#endif
-
-/* ===========================================================================
- * Constants
- */
-
-#define MAX_BL_BITS 7
-/* Bit length codes must not exceed MAX_BL_BITS bits */
-
-#define END_BLOCK 256
-/* end of block literal code */
-
-#define REP_3_6 16
-/* repeat previous bit length 3-6 times (2 bits of repeat count) */
-
-#define REPZ_3_10 17
-/* repeat a zero length 3-10 times (3 bits of repeat count) */
-
-#define REPZ_11_138 18
-/* repeat a zero length 11-138 times (7 bits of repeat count) */
-
-local const int extra_lbits[LENGTH_CODES] /* extra bits for each length code */
- = {0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0};
-
-local const int extra_dbits[D_CODES] /* extra bits for each distance code */
- = {0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13};
-
-local const int extra_blbits[BL_CODES]/* extra bits for each bit length code */
- = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7};
-
-local const uch bl_order[BL_CODES]
- = {16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15};
-/* The lengths of the bit length codes are sent in order of decreasing
- * probability, to avoid transmitting the lengths for unused bit length codes.
- */
-
-#define Buf_size (8 * 2*sizeof(char))
-/* Number of bits used within bi_buf. (bi_buf might be implemented on
- * more than 16 bits on some systems.)
- */
-
-/* ===========================================================================
- * Local data. These are initialized only once.
- */
-
-#define DIST_CODE_LEN 512 /* see definition of array dist_code below */
-
-#if defined(GEN_TREES_H) || !defined(STDC)
-/* non ANSI compilers may not accept trees.h */
-
-local ct_data static_ltree[L_CODES+2];
-/* The static literal tree. Since the bit lengths are imposed, there is no
- * need for the L_CODES extra codes used during heap construction. However
- * The codes 286 and 287 are needed to build a canonical tree (see _tr_init
- * below).
- */
-
-local ct_data static_dtree[D_CODES];
-/* The static distance tree. (Actually a trivial tree since all codes use
- * 5 bits.)
- */
-
-uch _dist_code[DIST_CODE_LEN];
-/* Distance codes. The first 256 values correspond to the distances
- * 3 .. 258, the last 256 values correspond to the top 8 bits of
- * the 15 bit distances.
- */
-
-uch _length_code[MAX_MATCH-MIN_MATCH+1];
-/* length code for each normalized match length (0 == MIN_MATCH) */
-
-local int base_length[LENGTH_CODES];
-/* First normalized length for each code (0 = MIN_MATCH) */
-
-local int base_dist[D_CODES];
-/* First normalized distance for each code (0 = distance of 1) */
-
-#else
-# include "trees.h"
-#endif /* GEN_TREES_H */
-
-struct static_tree_desc_s {
- const ct_data *static_tree; /* static tree or NULL */
- const intf *extra_bits; /* extra bits for each code or NULL */
- int extra_base; /* base index for extra_bits */
- int elems; /* max number of elements in the tree */
- int max_length; /* max bit length for the codes */
-};
-
-local static_tree_desc static_l_desc =
-{static_ltree, extra_lbits, LITERALS+1, L_CODES, MAX_BITS};
-
-local static_tree_desc static_d_desc =
-{static_dtree, extra_dbits, 0, D_CODES, MAX_BITS};
-
-local static_tree_desc static_bl_desc =
-{(const ct_data *)0, extra_blbits, 0, BL_CODES, MAX_BL_BITS};
-
-/* ===========================================================================
- * Local (static) routines in this file.
- */
-
-local void tr_static_init OF((void));
-local void init_block OF((deflate_state *s));
-local void pqdownheap OF((deflate_state *s, ct_data *tree, int k));
-local void gen_bitlen OF((deflate_state *s, tree_desc *desc));
-local void gen_codes OF((ct_data *tree, int max_code, ushf *bl_count));
-local void build_tree OF((deflate_state *s, tree_desc *desc));
-local void scan_tree OF((deflate_state *s, ct_data *tree, int max_code));
-local void send_tree OF((deflate_state *s, ct_data *tree, int max_code));
-local int build_bl_tree OF((deflate_state *s));
-local void send_all_trees OF((deflate_state *s, int lcodes, int dcodes,
- int blcodes));
-local void compress_block OF((deflate_state *s, ct_data *ltree,
- ct_data *dtree));
-local void set_data_type OF((deflate_state *s));
-local unsigned bi_reverse OF((unsigned value, int length));
-local void bi_windup OF((deflate_state *s));
-local void bi_flush OF((deflate_state *s));
-local void copy_block OF((deflate_state *s, charf *buf, unsigned len,
- int header));
-
-#ifdef GEN_TREES_H
-local void gen_trees_header OF((void));
-#endif
-
-#ifndef DEBUG
-# define send_code(s, c, tree) send_bits(s, tree[c].Code, tree[c].Len)
- /* Send a code of the given tree. c and tree must not have side effects */
-
-#else /* DEBUG */
-# define send_code(s, c, tree) \
- { if (z_verbose>2) fprintf(stderr,"\ncd %3d ",(c)); \
- send_bits(s, tree[c].Code, tree[c].Len); }
-#endif
-
-/* ===========================================================================
- * Output a short LSB first on the stream.
- * IN assertion: there is enough room in pendingBuf.
- */
-#define put_short(s, w) { \
- put_byte(s, (uch)((w) & 0xff)); \
- put_byte(s, (uch)((ush)(w) >> 8)); \
-}
-
-/* ===========================================================================
- * Send a value on a given number of bits.
- * IN assertion: length <= 16 and value fits in length bits.
- */
-#ifdef DEBUG
-local void send_bits OF((deflate_state *s, int value, int length));
-
-local void send_bits(s, value, length)
- deflate_state *s;
- int value; /* value to send */
- int length; /* number of bits */
-{
- Tracevv((stderr," l %2d v %4x ", length, value));
- Assert(length > 0 && length <= 15, "invalid length");
- s->bits_sent += (ulg)length;
-
- /* If not enough room in bi_buf, use (valid) bits from bi_buf and
- * (16 - bi_valid) bits from value, leaving (width - (16-bi_valid))
- * unused bits in value.
- */
- if (s->bi_valid > (int)Buf_size - length) {
- s->bi_buf |= (value << s->bi_valid);
- put_short(s, s->bi_buf);
- s->bi_buf = (ush)value >> (Buf_size - s->bi_valid);
- s->bi_valid += length - Buf_size;
- } else {
- s->bi_buf |= value << s->bi_valid;
- s->bi_valid += length;
- }
-}
-#else /* !DEBUG */
-
-#define send_bits(s, value, length) \
-{ int len = length;\
- if (s->bi_valid > (int)Buf_size - len) {\
- int val = value;\
- s->bi_buf |= (val << s->bi_valid);\
- put_short(s, s->bi_buf);\
- s->bi_buf = (ush)val >> (Buf_size - s->bi_valid);\
- s->bi_valid += len - Buf_size;\
- } else {\
- s->bi_buf |= (value) << s->bi_valid;\
- s->bi_valid += len;\
- }\
-}
-#endif /* DEBUG */
-
-
-/* the arguments must not have side effects */
-
-/* ===========================================================================
- * Initialize the various 'constant' tables.
- */
-local void tr_static_init()
-{
-#if defined(GEN_TREES_H) || !defined(STDC)
- static int static_init_done = 0;
- int n; /* iterates over tree elements */
- int bits; /* bit counter */
- int length; /* length value */
- int code; /* code value */
- int dist; /* distance index */
- ush bl_count[MAX_BITS+1];
- /* number of codes at each bit length for an optimal tree */
-
- if (static_init_done) return;
-
- /* For some embedded targets, global variables are not initialized: */
- static_l_desc.static_tree = static_ltree;
- static_l_desc.extra_bits = extra_lbits;
- static_d_desc.static_tree = static_dtree;
- static_d_desc.extra_bits = extra_dbits;
- static_bl_desc.extra_bits = extra_blbits;
-
- /* Initialize the mapping length (0..255) -> length code (0..28) */
- length = 0;
- for (code = 0; code < LENGTH_CODES-1; code++) {
- base_length[code] = length;
- for (n = 0; n < (1<<extra_lbits[code]); n++) {
- _length_code[length++] = (uch)code;
- }
- }
- Assert (length == 256, "tr_static_init: length != 256");
- /* Note that the length 255 (match length 258) can be represented
- * in two different ways: code 284 + 5 bits or code 285, so we
- * overwrite length_code[255] to use the best encoding:
- */
- _length_code[length-1] = (uch)code;
-
- /* Initialize the mapping dist (0..32K) -> dist code (0..29) */
- dist = 0;
- for (code = 0 ; code < 16; code++) {
- base_dist[code] = dist;
- for (n = 0; n < (1<<extra_dbits[code]); n++) {
- _dist_code[dist++] = (uch)code;
- }
- }
- Assert (dist == 256, "tr_static_init: dist != 256");
- dist >>= 7; /* from now on, all distances are divided by 128 */
- for ( ; code < D_CODES; code++) {
- base_dist[code] = dist << 7;
- for (n = 0; n < (1<<(extra_dbits[code]-7)); n++) {
- _dist_code[256 + dist++] = (uch)code;
- }
- }
- Assert (dist == 256, "tr_static_init: 256+dist != 512");
-
- /* Construct the codes of the static literal tree */
- for (bits = 0; bits <= MAX_BITS; bits++) bl_count[bits] = 0;
- n = 0;
- while (n <= 143) static_ltree[n++].Len = 8, bl_count[8]++;
- while (n <= 255) static_ltree[n++].Len = 9, bl_count[9]++;
- while (n <= 279) static_ltree[n++].Len = 7, bl_count[7]++;
- while (n <= 287) static_ltree[n++].Len = 8, bl_count[8]++;
- /* Codes 286 and 287 do not exist, but we must include them in the
- * tree construction to get a canonical Huffman tree (longest code
- * all ones)
- */
- gen_codes((ct_data *)static_ltree, L_CODES+1, bl_count);
-
- /* The static distance tree is trivial: */
- for (n = 0; n < D_CODES; n++) {
- static_dtree[n].Len = 5;
- static_dtree[n].Code = bi_reverse((unsigned)n, 5);
- }
- static_init_done = 1;
-
-# ifdef GEN_TREES_H
- gen_trees_header();
-# endif
-#endif /* defined(GEN_TREES_H) || !defined(STDC) */
-}
-
-/* ===========================================================================
- * Genererate the file trees.h describing the static trees.
- */
-#ifdef GEN_TREES_H
-# ifndef DEBUG
-# include <stdio.h>
-# endif
-
-# define SEPARATOR(i, last, width) \
- ((i) == (last)? "\n};\n\n" : \
- ((i) % (width) == (width)-1 ? ",\n" : ", "))
-
-void gen_trees_header()
-{
- FILE *header = fopen("trees.h", "w");
- int i;
-
- Assert (header != NULL, "Can't open trees.h");
- fprintf(header,
- "/* header created automatically with -DGEN_TREES_H */\n\n");
-
- fprintf(header, "local const ct_data static_ltree[L_CODES+2] = {\n");
- for (i = 0; i < L_CODES+2; i++) {
- fprintf(header, "{{%3u},{%3u}}%s", static_ltree[i].Code,
- static_ltree[i].Len, SEPARATOR(i, L_CODES+1, 5));
- }
-
- fprintf(header, "local const ct_data static_dtree[D_CODES] = {\n");
- for (i = 0; i < D_CODES; i++) {
- fprintf(header, "{{%2u},{%2u}}%s", static_dtree[i].Code,
- static_dtree[i].Len, SEPARATOR(i, D_CODES-1, 5));
- }
-
- fprintf(header, "const uch _dist_code[DIST_CODE_LEN] = {\n");
- for (i = 0; i < DIST_CODE_LEN; i++) {
- fprintf(header, "%2u%s", _dist_code[i],
- SEPARATOR(i, DIST_CODE_LEN-1, 20));
- }
-
- fprintf(header, "const uch _length_code[MAX_MATCH-MIN_MATCH+1]= {\n");
- for (i = 0; i < MAX_MATCH-MIN_MATCH+1; i++) {
- fprintf(header, "%2u%s", _length_code[i],
- SEPARATOR(i, MAX_MATCH-MIN_MATCH, 20));
- }
-
- fprintf(header, "local const int base_length[LENGTH_CODES] = {\n");
- for (i = 0; i < LENGTH_CODES; i++) {
- fprintf(header, "%1u%s", base_length[i],
- SEPARATOR(i, LENGTH_CODES-1, 20));
- }
-
- fprintf(header, "local const int base_dist[D_CODES] = {\n");
- for (i = 0; i < D_CODES; i++) {
- fprintf(header, "%5u%s", base_dist[i],
- SEPARATOR(i, D_CODES-1, 10));
- }
-
- fclose(header);
-}
-#endif /* GEN_TREES_H */
-
-/* ===========================================================================
- * Initialize the tree data structures for a new zlib stream.
- */
-void _tr_init(s)
- deflate_state *s;
-{
- tr_static_init();
-
- s->l_desc.dyn_tree = s->dyn_ltree;
- s->l_desc.stat_desc = &static_l_desc;
-
- s->d_desc.dyn_tree = s->dyn_dtree;
- s->d_desc.stat_desc = &static_d_desc;
-
- s->bl_desc.dyn_tree = s->bl_tree;
- s->bl_desc.stat_desc = &static_bl_desc;
-
- s->bi_buf = 0;
- s->bi_valid = 0;
- s->last_eob_len = 8; /* enough lookahead for inflate */
-#ifdef DEBUG
- s->compressed_len = 0L;
- s->bits_sent = 0L;
-#endif
-
- /* Initialize the first block of the first file: */
- init_block(s);
-}
-
-/* ===========================================================================
- * Initialize a new block.
- */
-local void init_block(s)
- deflate_state *s;
-{
- int n; /* iterates over tree elements */
-
- /* Initialize the trees. */
- for (n = 0; n < L_CODES; n++) s->dyn_ltree[n].Freq = 0;
- for (n = 0; n < D_CODES; n++) s->dyn_dtree[n].Freq = 0;
- for (n = 0; n < BL_CODES; n++) s->bl_tree[n].Freq = 0;
-
- s->dyn_ltree[END_BLOCK].Freq = 1;
- s->opt_len = s->static_len = 0L;
- s->last_lit = s->matches = 0;
-}
-
-#define SMALLEST 1
-/* Index within the heap array of least frequent node in the Huffman tree */
-
-
-/* ===========================================================================
- * Remove the smallest element from the heap and recreate the heap with
- * one less element. Updates heap and heap_len.
- */
-#define pqremove(s, tree, top) \
-{\
- top = s->heap[SMALLEST]; \
- s->heap[SMALLEST] = s->heap[s->heap_len--]; \
- pqdownheap(s, tree, SMALLEST); \
-}
-
-/* ===========================================================================
- * Compares to subtrees, using the tree depth as tie breaker when
- * the subtrees have equal frequency. This minimizes the worst case length.
- */
-#define smaller(tree, n, m, depth) \
- (tree[n].Freq < tree[m].Freq || \
- (tree[n].Freq == tree[m].Freq && depth[n] <= depth[m]))
-
-/* ===========================================================================
- * Restore the heap property by moving down the tree starting at node k,
- * exchanging a node with the smallest of its two sons if necessary, stopping
- * when the heap property is re-established (each father smaller than its
- * two sons).
- */
-local void pqdownheap(s, tree, k)
- deflate_state *s;
- ct_data *tree; /* the tree to restore */
- int k; /* node to move down */
-{
- int v = s->heap[k];
- int j = k << 1; /* left son of k */
- while (j <= s->heap_len) {
- /* Set j to the smallest of the two sons: */
- if (j < s->heap_len &&
- smaller(tree, s->heap[j+1], s->heap[j], s->depth)) {
- j++;
- }
- /* Exit if v is smaller than both sons */
- if (smaller(tree, v, s->heap[j], s->depth)) break;
-
- /* Exchange v with the smallest son */
- s->heap[k] = s->heap[j]; k = j;
-
- /* And continue down the tree, setting j to the left son of k */
- j <<= 1;
- }
- s->heap[k] = v;
-}
-
-/* ===========================================================================
- * Compute the optimal bit lengths for a tree and update the total bit length
- * for the current block.
- * IN assertion: the fields freq and dad are set, heap[heap_max] and
- * above are the tree nodes sorted by increasing frequency.
- * OUT assertions: the field len is set to the optimal bit length, the
- * array bl_count contains the frequencies for each bit length.
- * The length opt_len is updated; static_len is also updated if stree is
- * not null.
- */
-local void gen_bitlen(s, desc)
- deflate_state *s;
- tree_desc *desc; /* the tree descriptor */
-{
- ct_data *tree = desc->dyn_tree;
- int max_code = desc->max_code;
- const ct_data *stree = desc->stat_desc->static_tree;
- const intf *extra = desc->stat_desc->extra_bits;
- int base = desc->stat_desc->extra_base;
- int max_length = desc->stat_desc->max_length;
- int h; /* heap index */
- int n, m; /* iterate over the tree elements */
- int bits; /* bit length */
- int xbits; /* extra bits */
- ush f; /* frequency */
- int overflow = 0; /* number of elements with bit length too large */
-
- for (bits = 0; bits <= MAX_BITS; bits++) s->bl_count[bits] = 0;
-
- /* In a first pass, compute the optimal bit lengths (which may
- * overflow in the case of the bit length tree).
- */
- tree[s->heap[s->heap_max]].Len = 0; /* root of the heap */
-
- for (h = s->heap_max+1; h < HEAP_SIZE; h++) {
- n = s->heap[h];
- bits = tree[tree[n].Dad].Len + 1;
- if (bits > max_length) bits = max_length, overflow++;
- tree[n].Len = (ush)bits;
- /* We overwrite tree[n].Dad which is no longer needed */
-
- if (n > max_code) continue; /* not a leaf node */
-
- s->bl_count[bits]++;
- xbits = 0;
- if (n >= base) xbits = extra[n-base];
- f = tree[n].Freq;
- s->opt_len += (ulg)f * (bits + xbits);
- if (stree) s->static_len += (ulg)f * (stree[n].Len + xbits);
- }
- if (overflow == 0) return;
-
- Trace((stderr,"\nbit length overflow\n"));
- /* This happens for example on obj2 and pic of the Calgary corpus */
-
- /* Find the first bit length which could increase: */
- do {
- bits = max_length-1;
- while (s->bl_count[bits] == 0) bits--;
- s->bl_count[bits]--; /* move one leaf down the tree */
- s->bl_count[bits+1] += 2; /* move one overflow item as its brother */
- s->bl_count[max_length]--;
- /* The brother of the overflow item also moves one step up,
- * but this does not affect bl_count[max_length]
- */
- overflow -= 2;
- } while (overflow > 0);
-
- /* Now recompute all bit lengths, scanning in increasing frequency.
- * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all
- * lengths instead of fixing only the wrong ones. This idea is taken
- * from 'ar' written by Haruhiko Okumura.)
- */
- for (bits = max_length; bits != 0; bits--) {
- n = s->bl_count[bits];
- while (n != 0) {
- m = s->heap[--h];
- if (m > max_code) continue;
- if ((unsigned) tree[m].Len != (unsigned) bits) {
- Trace((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits));
- s->opt_len += ((long)bits - (long)tree[m].Len)
- *(long)tree[m].Freq;
- tree[m].Len = (ush)bits;
- }
- n--;
- }
- }
-}
-
-/* ===========================================================================
- * Generate the codes for a given tree and bit counts (which need not be
- * optimal).
- * IN assertion: the array bl_count contains the bit length statistics for
- * the given tree and the field len is set for all tree elements.
- * OUT assertion: the field code is set for all tree elements of non
- * zero code length.
- */
-local void gen_codes (tree, max_code, bl_count)
- ct_data *tree; /* the tree to decorate */
- int max_code; /* largest code with non zero frequency */
- ushf *bl_count; /* number of codes at each bit length */
-{
- ush next_code[MAX_BITS+1]; /* next code value for each bit length */
- ush code = 0; /* running code value */
- int bits; /* bit index */
- int n; /* code index */
-
- /* The distribution counts are first used to generate the code values
- * without bit reversal.
- */
- for (bits = 1; bits <= MAX_BITS; bits++) {
- next_code[bits] = code = (code + bl_count[bits-1]) << 1;
- }
- /* Check that the bit counts in bl_count are consistent. The last code
- * must be all ones.
- */
- Assert (code + bl_count[MAX_BITS]-1 == (1<<MAX_BITS)-1,
- "inconsistent bit counts");
- Tracev((stderr,"\ngen_codes: max_code %d ", max_code));
-
- for (n = 0; n <= max_code; n++) {
- int len = tree[n].Len;
- if (len == 0) continue;
- /* Now reverse the bits */
- tree[n].Code = bi_reverse(next_code[len]++, len);
-
- Tracecv(tree != static_ltree, (stderr,"\nn %3d %c l %2d c %4x (%x) ",
- n, (isgraph(n) ? n : ' '), len, tree[n].Code, next_code[len]-1));
- }
-}
-
-/* ===========================================================================
- * Construct one Huffman tree and assigns the code bit strings and lengths.
- * Update the total bit length for the current block.
- * IN assertion: the field freq is set for all tree elements.
- * OUT assertions: the fields len and code are set to the optimal bit length
- * and corresponding code. The length opt_len is updated; static_len is
- * also updated if stree is not null. The field max_code is set.
- */
-local void build_tree(s, desc)
- deflate_state *s;
- tree_desc *desc; /* the tree descriptor */
-{
- ct_data *tree = desc->dyn_tree;
- const ct_data *stree = desc->stat_desc->static_tree;
- int elems = desc->stat_desc->elems;
- int n, m; /* iterate over heap elements */
- int max_code = -1; /* largest code with non zero frequency */
- int node; /* new node being created */
-
- /* Construct the initial heap, with least frequent element in
- * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1].
- * heap[0] is not used.
- */
- s->heap_len = 0, s->heap_max = HEAP_SIZE;
-
- for (n = 0; n < elems; n++) {
- if (tree[n].Freq != 0) {
- s->heap[++(s->heap_len)] = max_code = n;
- s->depth[n] = 0;
- } else {
- tree[n].Len = 0;
- }
- }
-
- /* The pkzip format requires that at least one distance code exists,
- * and that at least one bit should be sent even if there is only one
- * possible code. So to avoid special checks later on we force at least
- * two codes of non zero frequency.
- */
- while (s->heap_len < 2) {
- node = s->heap[++(s->heap_len)] = (max_code < 2 ? ++max_code : 0);
- tree[node].Freq = 1;
- s->depth[node] = 0;
- s->opt_len--; if (stree) s->static_len -= stree[node].Len;
- /* node is 0 or 1 so it does not have extra bits */
- }
- desc->max_code = max_code;
-
- /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree,
- * establish sub-heaps of increasing lengths:
- */
- for (n = s->heap_len/2; n >= 1; n--) pqdownheap(s, tree, n);
-
- /* Construct the Huffman tree by repeatedly combining the least two
- * frequent nodes.
- */
- node = elems; /* next internal node of the tree */
- do {
- pqremove(s, tree, n); /* n = node of least frequency */
- m = s->heap[SMALLEST]; /* m = node of next least frequency */
-
- s->heap[--(s->heap_max)] = n; /* keep the nodes sorted by frequency */
- s->heap[--(s->heap_max)] = m;
-
- /* Create a new node father of n and m */
- tree[node].Freq = tree[n].Freq + tree[m].Freq;
- s->depth[node] = (uch)((s->depth[n] >= s->depth[m] ?
- s->depth[n] : s->depth[m]) + 1);
- tree[n].Dad = tree[m].Dad = (ush)node;
-#ifdef DUMP_BL_TREE
- if (tree == s->bl_tree) {
- fprintf(stderr,"\nnode %d(%d), sons %d(%d) %d(%d)",
- node, tree[node].Freq, n, tree[n].Freq, m, tree[m].Freq);
- }
-#endif
- /* and insert the new node in the heap */
- s->heap[SMALLEST] = node++;
- pqdownheap(s, tree, SMALLEST);
-
- } while (s->heap_len >= 2);
-
- s->heap[--(s->heap_max)] = s->heap[SMALLEST];
-
- /* At this point, the fields freq and dad are set. We can now
- * generate the bit lengths.
- */
- gen_bitlen(s, (tree_desc *)desc);
-
- /* The field len is now set, we can generate the bit codes */
- gen_codes ((ct_data *)tree, max_code, s->bl_count);
-}
-
-/* ===========================================================================
- * Scan a literal or distance tree to determine the frequencies of the codes
- * in the bit length tree.
- */
-local void scan_tree (s, tree, max_code)
- deflate_state *s;
- ct_data *tree; /* the tree to be scanned */
- int max_code; /* and its largest code of non zero frequency */
-{
- int n; /* iterates over all tree elements */
- int prevlen = -1; /* last emitted length */
- int curlen; /* length of current code */
- int nextlen = tree[0].Len; /* length of next code */
- int count = 0; /* repeat count of the current code */
- int max_count = 7; /* max repeat count */
- int min_count = 4; /* min repeat count */
-
- if (nextlen == 0) max_count = 138, min_count = 3;
- tree[max_code+1].Len = (ush)0xffff; /* guard */
-
- for (n = 0; n <= max_code; n++) {
- curlen = nextlen; nextlen = tree[n+1].Len;
- if (++count < max_count && curlen == nextlen) {
- continue;
- } else if (count < min_count) {
- s->bl_tree[curlen].Freq += count;
- } else if (curlen != 0) {
- if (curlen != prevlen) s->bl_tree[curlen].Freq++;
- s->bl_tree[REP_3_6].Freq++;
- } else if (count <= 10) {
- s->bl_tree[REPZ_3_10].Freq++;
- } else {
- s->bl_tree[REPZ_11_138].Freq++;
- }
- count = 0; prevlen = curlen;
- if (nextlen == 0) {
- max_count = 138, min_count = 3;
- } else if (curlen == nextlen) {
- max_count = 6, min_count = 3;
- } else {
- max_count = 7, min_count = 4;
- }
- }
-}
-
-/* ===========================================================================
- * Send a literal or distance tree in compressed form, using the codes in
- * bl_tree.
- */
-local void send_tree (s, tree, max_code)
- deflate_state *s;
- ct_data *tree; /* the tree to be scanned */
- int max_code; /* and its largest code of non zero frequency */
-{
- int n; /* iterates over all tree elements */
- int prevlen = -1; /* last emitted length */
- int curlen; /* length of current code */
- int nextlen = tree[0].Len; /* length of next code */
- int count = 0; /* repeat count of the current code */
- int max_count = 7; /* max repeat count */
- int min_count = 4; /* min repeat count */
-
- /* tree[max_code+1].Len = -1; */ /* guard already set */
- if (nextlen == 0) max_count = 138, min_count = 3;
-
- for (n = 0; n <= max_code; n++) {
- curlen = nextlen; nextlen = tree[n+1].Len;
- if (++count < max_count && curlen == nextlen) {
- continue;
- } else if (count < min_count) {
- do { send_code(s, curlen, s->bl_tree); } while (--count != 0);
-
- } else if (curlen != 0) {
- if (curlen != prevlen) {
- send_code(s, curlen, s->bl_tree); count--;
- }
- Assert(count >= 3 && count <= 6, " 3_6?");
- send_code(s, REP_3_6, s->bl_tree); send_bits(s, count-3, 2);
-
- } else if (count <= 10) {
- send_code(s, REPZ_3_10, s->bl_tree); send_bits(s, count-3, 3);
-
- } else {
- send_code(s, REPZ_11_138, s->bl_tree); send_bits(s, count-11, 7);
- }
- count = 0; prevlen = curlen;
- if (nextlen == 0) {
- max_count = 138, min_count = 3;
- } else if (curlen == nextlen) {
- max_count = 6, min_count = 3;
- } else {
- max_count = 7, min_count = 4;
- }
- }
-}
-
-/* ===========================================================================
- * Construct the Huffman tree for the bit lengths and return the index in
- * bl_order of the last bit length code to send.
- */
-local int build_bl_tree(s)
- deflate_state *s;
-{
- int max_blindex; /* index of last bit length code of non zero freq */
-
- /* Determine the bit length frequencies for literal and distance trees */
- scan_tree(s, (ct_data *)s->dyn_ltree, s->l_desc.max_code);
- scan_tree(s, (ct_data *)s->dyn_dtree, s->d_desc.max_code);
-
- /* Build the bit length tree: */
- build_tree(s, (tree_desc *)(&(s->bl_desc)));
- /* opt_len now includes the length of the tree representations, except
- * the lengths of the bit lengths codes and the 5+5+4 bits for the counts.
- */
-
- /* Determine the number of bit length codes to send. The pkzip format
- * requires that at least 4 bit length codes be sent. (appnote.txt says
- * 3 but the actual value used is 4.)
- */
- for (max_blindex = BL_CODES-1; max_blindex >= 3; max_blindex--) {
- if (s->bl_tree[bl_order[max_blindex]].Len != 0) break;
- }
- /* Update opt_len to include the bit length tree and counts */
- s->opt_len += 3*(max_blindex+1) + 5+5+4;
- Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld",
- s->opt_len, s->static_len));
-
- return max_blindex;
-}
-
-/* ===========================================================================
- * Send the header for a block using dynamic Huffman trees: the counts, the
- * lengths of the bit length codes, the literal tree and the distance tree.
- * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4.
- */
-local void send_all_trees(s, lcodes, dcodes, blcodes)
- deflate_state *s;
- int lcodes, dcodes, blcodes; /* number of codes for each tree */
-{
- int rank; /* index in bl_order */
-
- Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes");
- Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES,
- "too many codes");
- Tracev((stderr, "\nbl counts: "));
- send_bits(s, lcodes-257, 5); /* not +255 as stated in appnote.txt */
- send_bits(s, dcodes-1, 5);
- send_bits(s, blcodes-4, 4); /* not -3 as stated in appnote.txt */
- for (rank = 0; rank < blcodes; rank++) {
- Tracev((stderr, "\nbl code %2d ", bl_order[rank]));
- send_bits(s, s->bl_tree[bl_order[rank]].Len, 3);
- }
- Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent));
-
- send_tree(s, (ct_data *)s->dyn_ltree, lcodes-1); /* literal tree */
- Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent));
-
- send_tree(s, (ct_data *)s->dyn_dtree, dcodes-1); /* distance tree */
- Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent));
-}
-
-/* ===========================================================================
- * Send a stored block
- */
-void _tr_stored_block(s, buf, stored_len, eof)
- deflate_state *s;
- charf *buf; /* input block */
- ulg stored_len; /* length of input block */
- int eof; /* true if this is the last block for a file */
-{
- send_bits(s, (STORED_BLOCK<<1)+eof, 3); /* send block type */
-#ifdef DEBUG
- s->compressed_len = (s->compressed_len + 3 + 7) & (ulg)~7L;
- s->compressed_len += (stored_len + 4) << 3;
-#endif
- copy_block(s, buf, (unsigned)stored_len, 1); /* with header */
-}
-
-/* ===========================================================================
- * Send one empty static block to give enough lookahead for inflate.
- * This takes 10 bits, of which 7 may remain in the bit buffer.
- * The current inflate code requires 9 bits of lookahead. If the
- * last two codes for the previous block (real code plus EOB) were coded
- * on 5 bits or less, inflate may have only 5+3 bits of lookahead to decode
- * the last real code. In this case we send two empty static blocks instead
- * of one. (There are no problems if the previous block is stored or fixed.)
- * To simplify the code, we assume the worst case of last real code encoded
- * on one bit only.
- */
-void _tr_align(s)
- deflate_state *s;
-{
- send_bits(s, STATIC_TREES<<1, 3);
- send_code(s, END_BLOCK, static_ltree);
-#ifdef DEBUG
- s->compressed_len += 10L; /* 3 for block type, 7 for EOB */
-#endif
- bi_flush(s);
- /* Of the 10 bits for the empty block, we have already sent
- * (10 - bi_valid) bits. The lookahead for the last real code (before
- * the EOB of the previous block) was thus at least one plus the length
- * of the EOB plus what we have just sent of the empty static block.
- */
- if (1 + s->last_eob_len + 10 - s->bi_valid < 9) {
- send_bits(s, STATIC_TREES<<1, 3);
- send_code(s, END_BLOCK, static_ltree);
-#ifdef DEBUG
- s->compressed_len += 10L;
-#endif
- bi_flush(s);
- }
- s->last_eob_len = 7;
-}
-
-/* ===========================================================================
- * Determine the best encoding for the current block: dynamic trees, static
- * trees or store, and output the encoded block to the zip file.
- */
-void _tr_flush_block(s, buf, stored_len, eof)
- deflate_state *s;
- charf *buf; /* input block, or NULL if too old */
- ulg stored_len; /* length of input block */
- int eof; /* true if this is the last block for a file */
-{
- ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */
- int max_blindex = 0; /* index of last bit length code of non zero freq */
-
- /* Build the Huffman trees unless a stored block is forced */
- if (s->level > 0) {
-
- /* Check if the file is binary or text */
- if (stored_len > 0 && s->strm->data_type == Z_UNKNOWN)
- set_data_type(s);
-
- /* Construct the literal and distance trees */
- build_tree(s, (tree_desc *)(&(s->l_desc)));
- Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len,
- s->static_len));
-
- build_tree(s, (tree_desc *)(&(s->d_desc)));
- Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len,
- s->static_len));
- /* At this point, opt_len and static_len are the total bit lengths of
- * the compressed block data, excluding the tree representations.
- */
-
- /* Build the bit length tree for the above two trees, and get the index
- * in bl_order of the last bit length code to send.
- */
- max_blindex = build_bl_tree(s);
-
- /* Determine the best encoding. Compute the block lengths in bytes. */
- opt_lenb = (s->opt_len+3+7)>>3;
- static_lenb = (s->static_len+3+7)>>3;
-
- Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ",
- opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len,
- s->last_lit));
-
- if (static_lenb <= opt_lenb) opt_lenb = static_lenb;
-
- } else {
- Assert(buf != (char*)0, "lost buf");
- opt_lenb = static_lenb = stored_len + 5; /* force a stored block */
- }
-
-#ifdef FORCE_STORED
- if (buf != (char*)0) { /* force stored block */
-#else
- if (stored_len+4 <= opt_lenb && buf != (char*)0) {
- /* 4: two words for the lengths */
-#endif
- /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE.
- * Otherwise we can't have processed more than WSIZE input bytes since
- * the last block flush, because compression would have been
- * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to
- * transform a block into a stored block.
- */
- _tr_stored_block(s, buf, stored_len, eof);
-
-#ifdef FORCE_STATIC
- } else if (static_lenb >= 0) { /* force static trees */
-#else
- } else if (s->strategy == Z_FIXED || static_lenb == opt_lenb) {
-#endif
- send_bits(s, (STATIC_TREES<<1)+eof, 3);
- compress_block(s, (ct_data *)static_ltree, (ct_data *)static_dtree);
-#ifdef DEBUG
- s->compressed_len += 3 + s->static_len;
-#endif
- } else {
- send_bits(s, (DYN_TREES<<1)+eof, 3);
- send_all_trees(s, s->l_desc.max_code+1, s->d_desc.max_code+1,
- max_blindex+1);
- compress_block(s, (ct_data *)s->dyn_ltree, (ct_data *)s->dyn_dtree);
-#ifdef DEBUG
- s->compressed_len += 3 + s->opt_len;
-#endif
- }
- Assert (s->compressed_len == s->bits_sent, "bad compressed size");
- /* The above check is made mod 2^32, for files larger than 512 MB
- * and uLong implemented on 32 bits.
- */
- init_block(s);
-
- if (eof) {
- bi_windup(s);
-#ifdef DEBUG
- s->compressed_len += 7; /* align on byte boundary */
-#endif
- }
- Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len>>3,
- s->compressed_len-7*eof));
-}
-
-/* ===========================================================================
- * Save the match info and tally the frequency counts. Return true if
- * the current block must be flushed.
- */
-int _tr_tally (s, dist, lc)
- deflate_state *s;
- unsigned dist; /* distance of matched string */
- unsigned lc; /* match length-MIN_MATCH or unmatched char (if dist==0) */
-{
- s->d_buf[s->last_lit] = (ush)dist;
- s->l_buf[s->last_lit++] = (uch)lc;
- if (dist == 0) {
- /* lc is the unmatched char */
- s->dyn_ltree[lc].Freq++;
- } else {
- s->matches++;
- /* Here, lc is the match length - MIN_MATCH */
- dist--; /* dist = match distance - 1 */
- Assert((ush)dist < (ush)MAX_DIST(s) &&
- (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) &&
- (ush)d_code(dist) < (ush)D_CODES, "_tr_tally: bad match");
-
- s->dyn_ltree[_length_code[lc]+LITERALS+1].Freq++;
- s->dyn_dtree[d_code(dist)].Freq++;
- }
-
-#ifdef TRUNCATE_BLOCK
- /* Try to guess if it is profitable to stop the current block here */
- if ((s->last_lit & 0x1fff) == 0 && s->level > 2) {
- /* Compute an upper bound for the compressed length */
- ulg out_length = (ulg)s->last_lit*8L;
- ulg in_length = (ulg)((long)s->strstart - s->block_start);
- int dcode;
- for (dcode = 0; dcode < D_CODES; dcode++) {
- out_length += (ulg)s->dyn_dtree[dcode].Freq *
- (5L+extra_dbits[dcode]);
- }
- out_length >>= 3;
- Tracev((stderr,"\nlast_lit %u, in %ld, out ~%ld(%ld%%) ",
- s->last_lit, in_length, out_length,
- 100L - out_length*100L/in_length));
- if (s->matches < s->last_lit/2 && out_length < in_length/2) return 1;
- }
-#endif
- return (s->last_lit == s->lit_bufsize-1);
- /* We avoid equality with lit_bufsize because of wraparound at 64K
- * on 16 bit machines and because stored blocks are restricted to
- * 64K-1 bytes.
- */
-}
-
-/* ===========================================================================
- * Send the block data compressed using the given Huffman trees
- */
-local void compress_block(s, ltree, dtree)
- deflate_state *s;
- ct_data *ltree; /* literal tree */
- ct_data *dtree; /* distance tree */
-{
- unsigned dist; /* distance of matched string */
- int lc; /* match length or unmatched char (if dist == 0) */
- unsigned lx = 0; /* running index in l_buf */
- unsigned code; /* the code to send */
- int extra; /* number of extra bits to send */
-
- if (s->last_lit != 0) do {
- dist = s->d_buf[lx];
- lc = s->l_buf[lx++];
- if (dist == 0) {
- send_code(s, lc, ltree); /* send a literal byte */
- Tracecv(isgraph(lc), (stderr," '%c' ", lc));
- } else {
- /* Here, lc is the match length - MIN_MATCH */
- code = _length_code[lc];
- send_code(s, code+LITERALS+1, ltree); /* send the length code */
- extra = extra_lbits[code];
- if (extra != 0) {
- lc -= base_length[code];
- send_bits(s, lc, extra); /* send the extra length bits */
- }
- dist--; /* dist is now the match distance - 1 */
- code = d_code(dist);
- Assert (code < D_CODES, "bad d_code");
-
- send_code(s, code, dtree); /* send the distance code */
- extra = extra_dbits[code];
- if (extra != 0) {
- dist -= base_dist[code];
- send_bits(s, dist, extra); /* send the extra distance bits */
- }
- } /* literal or match pair ? */
-
- /* Check that the overlay between pending_buf and d_buf+l_buf is ok: */
- Assert((uInt)(s->pending) < s->lit_bufsize + 2*lx,
- "pendingBuf overflow");
-
- } while (lx < s->last_lit);
-
- send_code(s, END_BLOCK, ltree);
- s->last_eob_len = ltree[END_BLOCK].Len;
-}
-
-/* ===========================================================================
- * Set the data type to BINARY or TEXT, using a crude approximation:
- * set it to Z_TEXT if all symbols are either printable characters (33 to 255)
- * or white spaces (9 to 13, or 32); or set it to Z_BINARY otherwise.
- * IN assertion: the fields Freq of dyn_ltree are set.
- */
-local void set_data_type(s)
- deflate_state *s;
-{
- int n;
-
- for (n = 0; n < 9; n++)
- if (s->dyn_ltree[n].Freq != 0)
- break;
- if (n == 9)
- for (n = 14; n < 32; n++)
- if (s->dyn_ltree[n].Freq != 0)
- break;
- s->strm->data_type = (n == 32) ? Z_TEXT : Z_BINARY;
-}
-
-/* ===========================================================================
- * Reverse the first len bits of a code, using straightforward code (a faster
- * method would use a table)
- * IN assertion: 1 <= len <= 15
- */
-local unsigned bi_reverse(code, len)
- unsigned code; /* the value to invert */
- int len; /* its bit length */
-{
- register unsigned res = 0;
- do {
- res |= code & 1;
- code >>= 1, res <<= 1;
- } while (--len > 0);
- return res >> 1;
-}
-
-/* ===========================================================================
- * Flush the bit buffer, keeping at most 7 bits in it.
- */
-local void bi_flush(s)
- deflate_state *s;
-{
- if (s->bi_valid == 16) {
- put_short(s, s->bi_buf);
- s->bi_buf = 0;
- s->bi_valid = 0;
- } else if (s->bi_valid >= 8) {
- put_byte(s, (Byte)s->bi_buf);
- s->bi_buf >>= 8;
- s->bi_valid -= 8;
- }
-}
-
-/* ===========================================================================
- * Flush the bit buffer and align the output on a byte boundary
- */
-local void bi_windup(s)
- deflate_state *s;
-{
- if (s->bi_valid > 8) {
- put_short(s, s->bi_buf);
- } else if (s->bi_valid > 0) {
- put_byte(s, (Byte)s->bi_buf);
- }
- s->bi_buf = 0;
- s->bi_valid = 0;
-#ifdef DEBUG
- s->bits_sent = (s->bits_sent+7) & ~7;
-#endif
-}
-
-/* ===========================================================================
- * Copy a stored block, storing first the length and its
- * one's complement if requested.
- */
-local void copy_block(s, buf, len, header)
- deflate_state *s;
- charf *buf; /* the input data */
- unsigned len; /* its length */
- int header; /* true if block header must be written */
-{
- bi_windup(s); /* align on byte boundary */
- s->last_eob_len = 8; /* enough lookahead for inflate */
-
- if (header) {
- put_short(s, (ush)len);
- put_short(s, (ush)~len);
-#ifdef DEBUG
- s->bits_sent += 2*16;
-#endif
- }
-#ifdef DEBUG
- s->bits_sent += (ulg)len<<3;
-#endif
- while (len--) {
- put_byte(s, *buf++);
- }
-}
+++ /dev/null
-/* header created automatically with -DGEN_TREES_H */
-
-local const ct_data static_ltree[L_CODES+2] = {
-{{ 12},{ 8}}, {{140},{ 8}}, {{ 76},{ 8}}, {{204},{ 8}}, {{ 44},{ 8}},
-{{172},{ 8}}, {{108},{ 8}}, {{236},{ 8}}, {{ 28},{ 8}}, {{156},{ 8}},
-{{ 92},{ 8}}, {{220},{ 8}}, {{ 60},{ 8}}, {{188},{ 8}}, {{124},{ 8}},
-{{252},{ 8}}, {{ 2},{ 8}}, {{130},{ 8}}, {{ 66},{ 8}}, {{194},{ 8}},
-{{ 34},{ 8}}, {{162},{ 8}}, {{ 98},{ 8}}, {{226},{ 8}}, {{ 18},{ 8}},
-{{146},{ 8}}, {{ 82},{ 8}}, {{210},{ 8}}, {{ 50},{ 8}}, {{178},{ 8}},
-{{114},{ 8}}, {{242},{ 8}}, {{ 10},{ 8}}, {{138},{ 8}}, {{ 74},{ 8}},
-{{202},{ 8}}, {{ 42},{ 8}}, {{170},{ 8}}, {{106},{ 8}}, {{234},{ 8}},
-{{ 26},{ 8}}, {{154},{ 8}}, {{ 90},{ 8}}, {{218},{ 8}}, {{ 58},{ 8}},
-{{186},{ 8}}, {{122},{ 8}}, {{250},{ 8}}, {{ 6},{ 8}}, {{134},{ 8}},
-{{ 70},{ 8}}, {{198},{ 8}}, {{ 38},{ 8}}, {{166},{ 8}}, {{102},{ 8}},
-{{230},{ 8}}, {{ 22},{ 8}}, {{150},{ 8}}, {{ 86},{ 8}}, {{214},{ 8}},
-{{ 54},{ 8}}, {{182},{ 8}}, {{118},{ 8}}, {{246},{ 8}}, {{ 14},{ 8}},
-{{142},{ 8}}, {{ 78},{ 8}}, {{206},{ 8}}, {{ 46},{ 8}}, {{174},{ 8}},
-{{110},{ 8}}, {{238},{ 8}}, {{ 30},{ 8}}, {{158},{ 8}}, {{ 94},{ 8}},
-{{222},{ 8}}, {{ 62},{ 8}}, {{190},{ 8}}, {{126},{ 8}}, {{254},{ 8}},
-{{ 1},{ 8}}, {{129},{ 8}}, {{ 65},{ 8}}, {{193},{ 8}}, {{ 33},{ 8}},
-{{161},{ 8}}, {{ 97},{ 8}}, {{225},{ 8}}, {{ 17},{ 8}}, {{145},{ 8}},
-{{ 81},{ 8}}, {{209},{ 8}}, {{ 49},{ 8}}, {{177},{ 8}}, {{113},{ 8}},
-{{241},{ 8}}, {{ 9},{ 8}}, {{137},{ 8}}, {{ 73},{ 8}}, {{201},{ 8}},
-{{ 41},{ 8}}, {{169},{ 8}}, {{105},{ 8}}, {{233},{ 8}}, {{ 25},{ 8}},
-{{153},{ 8}}, {{ 89},{ 8}}, {{217},{ 8}}, {{ 57},{ 8}}, {{185},{ 8}},
-{{121},{ 8}}, {{249},{ 8}}, {{ 5},{ 8}}, {{133},{ 8}}, {{ 69},{ 8}},
-{{197},{ 8}}, {{ 37},{ 8}}, {{165},{ 8}}, {{101},{ 8}}, {{229},{ 8}},
-{{ 21},{ 8}}, {{149},{ 8}}, {{ 85},{ 8}}, {{213},{ 8}}, {{ 53},{ 8}},
-{{181},{ 8}}, {{117},{ 8}}, {{245},{ 8}}, {{ 13},{ 8}}, {{141},{ 8}},
-{{ 77},{ 8}}, {{205},{ 8}}, {{ 45},{ 8}}, {{173},{ 8}}, {{109},{ 8}},
-{{237},{ 8}}, {{ 29},{ 8}}, {{157},{ 8}}, {{ 93},{ 8}}, {{221},{ 8}},
-{{ 61},{ 8}}, {{189},{ 8}}, {{125},{ 8}}, {{253},{ 8}}, {{ 19},{ 9}},
-{{275},{ 9}}, {{147},{ 9}}, {{403},{ 9}}, {{ 83},{ 9}}, {{339},{ 9}},
-{{211},{ 9}}, {{467},{ 9}}, {{ 51},{ 9}}, {{307},{ 9}}, {{179},{ 9}},
-{{435},{ 9}}, {{115},{ 9}}, {{371},{ 9}}, {{243},{ 9}}, {{499},{ 9}},
-{{ 11},{ 9}}, {{267},{ 9}}, {{139},{ 9}}, {{395},{ 9}}, {{ 75},{ 9}},
-{{331},{ 9}}, {{203},{ 9}}, {{459},{ 9}}, {{ 43},{ 9}}, {{299},{ 9}},
-{{171},{ 9}}, {{427},{ 9}}, {{107},{ 9}}, {{363},{ 9}}, {{235},{ 9}},
-{{491},{ 9}}, {{ 27},{ 9}}, {{283},{ 9}}, {{155},{ 9}}, {{411},{ 9}},
-{{ 91},{ 9}}, {{347},{ 9}}, {{219},{ 9}}, {{475},{ 9}}, {{ 59},{ 9}},
-{{315},{ 9}}, {{187},{ 9}}, {{443},{ 9}}, {{123},{ 9}}, {{379},{ 9}},
-{{251},{ 9}}, {{507},{ 9}}, {{ 7},{ 9}}, {{263},{ 9}}, {{135},{ 9}},
-{{391},{ 9}}, {{ 71},{ 9}}, {{327},{ 9}}, {{199},{ 9}}, {{455},{ 9}},
-{{ 39},{ 9}}, {{295},{ 9}}, {{167},{ 9}}, {{423},{ 9}}, {{103},{ 9}},
-{{359},{ 9}}, {{231},{ 9}}, {{487},{ 9}}, {{ 23},{ 9}}, {{279},{ 9}},
-{{151},{ 9}}, {{407},{ 9}}, {{ 87},{ 9}}, {{343},{ 9}}, {{215},{ 9}},
-{{471},{ 9}}, {{ 55},{ 9}}, {{311},{ 9}}, {{183},{ 9}}, {{439},{ 9}},
-{{119},{ 9}}, {{375},{ 9}}, {{247},{ 9}}, {{503},{ 9}}, {{ 15},{ 9}},
-{{271},{ 9}}, {{143},{ 9}}, {{399},{ 9}}, {{ 79},{ 9}}, {{335},{ 9}},
-{{207},{ 9}}, {{463},{ 9}}, {{ 47},{ 9}}, {{303},{ 9}}, {{175},{ 9}},
-{{431},{ 9}}, {{111},{ 9}}, {{367},{ 9}}, {{239},{ 9}}, {{495},{ 9}},
-{{ 31},{ 9}}, {{287},{ 9}}, {{159},{ 9}}, {{415},{ 9}}, {{ 95},{ 9}},
-{{351},{ 9}}, {{223},{ 9}}, {{479},{ 9}}, {{ 63},{ 9}}, {{319},{ 9}},
-{{191},{ 9}}, {{447},{ 9}}, {{127},{ 9}}, {{383},{ 9}}, {{255},{ 9}},
-{{511},{ 9}}, {{ 0},{ 7}}, {{ 64},{ 7}}, {{ 32},{ 7}}, {{ 96},{ 7}},
-{{ 16},{ 7}}, {{ 80},{ 7}}, {{ 48},{ 7}}, {{112},{ 7}}, {{ 8},{ 7}},
-{{ 72},{ 7}}, {{ 40},{ 7}}, {{104},{ 7}}, {{ 24},{ 7}}, {{ 88},{ 7}},
-{{ 56},{ 7}}, {{120},{ 7}}, {{ 4},{ 7}}, {{ 68},{ 7}}, {{ 36},{ 7}},
-{{100},{ 7}}, {{ 20},{ 7}}, {{ 84},{ 7}}, {{ 52},{ 7}}, {{116},{ 7}},
-{{ 3},{ 8}}, {{131},{ 8}}, {{ 67},{ 8}}, {{195},{ 8}}, {{ 35},{ 8}},
-{{163},{ 8}}, {{ 99},{ 8}}, {{227},{ 8}}
-};
-
-local const ct_data static_dtree[D_CODES] = {
-{{ 0},{ 5}}, {{16},{ 5}}, {{ 8},{ 5}}, {{24},{ 5}}, {{ 4},{ 5}},
-{{20},{ 5}}, {{12},{ 5}}, {{28},{ 5}}, {{ 2},{ 5}}, {{18},{ 5}},
-{{10},{ 5}}, {{26},{ 5}}, {{ 6},{ 5}}, {{22},{ 5}}, {{14},{ 5}},
-{{30},{ 5}}, {{ 1},{ 5}}, {{17},{ 5}}, {{ 9},{ 5}}, {{25},{ 5}},
-{{ 5},{ 5}}, {{21},{ 5}}, {{13},{ 5}}, {{29},{ 5}}, {{ 3},{ 5}},
-{{19},{ 5}}, {{11},{ 5}}, {{27},{ 5}}, {{ 7},{ 5}}, {{23},{ 5}}
-};
-
-const uch _dist_code[DIST_CODE_LEN] = {
- 0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8,
- 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10,
-10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
-11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
-12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13,
-13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15,
-15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 16, 17,
-18, 18, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22,
-23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
-24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
-26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
-26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27,
-27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
-27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
-28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
-28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
-28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
-29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
-29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
-29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29
-};
-
-const uch _length_code[MAX_MATCH-MIN_MATCH+1]= {
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12,
-13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16,
-17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19,
-19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
-21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22,
-22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23,
-23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
-24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
-25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
-25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26,
-26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
-26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
-27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28
-};
-
-local const int base_length[LENGTH_CODES] = {
-0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56,
-64, 80, 96, 112, 128, 160, 192, 224, 0
-};
-
-local const int base_dist[D_CODES] = {
- 0, 1, 2, 3, 4, 6, 8, 12, 16, 24,
- 32, 48, 64, 96, 128, 192, 256, 384, 512, 768,
- 1024, 1536, 2048, 3072, 4096, 6144, 8192, 12288, 16384, 24576
-};
-
+++ /dev/null
-/* uncompr.c -- decompress a memory buffer
- * Copyright (C) 1995-2003 Jean-loup Gailly.
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* @(#) $Id$ */
-
-#define ZLIB_INTERNAL
-#include "zlib.h"
-
-/* ===========================================================================
- Decompresses the source buffer into the destination buffer. sourceLen is
- the byte length of the source buffer. Upon entry, destLen is the total
- size of the destination buffer, which must be large enough to hold the
- entire uncompressed data. (The size of the uncompressed data must have
- been saved previously by the compressor and transmitted to the decompressor
- by some mechanism outside the scope of this compression library.)
- Upon exit, destLen is the actual size of the compressed buffer.
- This function can be used to decompress a whole file at once if the
- input file is mmap'ed.
-
- uncompress returns Z_OK if success, Z_MEM_ERROR if there was not
- enough memory, Z_BUF_ERROR if there was not enough room in the output
- buffer, or Z_DATA_ERROR if the input data was corrupted.
-*/
-int ZEXPORT uncompress (dest, destLen, source, sourceLen)
- Bytef *dest;
- uLongf *destLen;
- const Bytef *source;
- uLong sourceLen;
-{
- z_stream stream;
- int err;
-
- stream.next_in = (Bytef*)source;
- stream.avail_in = (uInt)sourceLen;
- /* Check for source > 64K on 16-bit machine: */
- if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR;
-
- stream.next_out = dest;
- stream.avail_out = (uInt)*destLen;
- if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR;
-
- stream.zalloc = (alloc_func)0;
- stream.zfree = (free_func)0;
-
- err = inflateInit(&stream);
- if (err != Z_OK) return err;
-
- err = inflate(&stream, Z_FINISH);
- if (err != Z_STREAM_END) {
- inflateEnd(&stream);
- if (err == Z_NEED_DICT || (err == Z_BUF_ERROR && stream.avail_in == 0))
- return Z_DATA_ERROR;
- return err;
- }
- *destLen = stream.total_out;
-
- err = inflateEnd(&stream);
- return err;
-}
+++ /dev/null
-/* zconf.h -- configuration of the zlib compression library
- * Copyright (C) 1995-2005 Jean-loup Gailly.
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* @(#) $Id$ */
-
-#ifndef ZCONF_H
-#define ZCONF_H
-
-/*
- * If you *really* need a unique prefix for all types and library functions,
- * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it.
- */
-#ifdef Z_PREFIX
-# define deflateInit_ z_deflateInit_
-# define deflate z_deflate
-# define deflateEnd z_deflateEnd
-# define inflateInit_ z_inflateInit_
-# define inflate z_inflate
-# define inflateEnd z_inflateEnd
-# define deflateInit2_ z_deflateInit2_
-# define deflateSetDictionary z_deflateSetDictionary
-# define deflateCopy z_deflateCopy
-# define deflateReset z_deflateReset
-# define deflateParams z_deflateParams
-# define deflateBound z_deflateBound
-# define deflatePrime z_deflatePrime
-# define inflateInit2_ z_inflateInit2_
-# define inflateSetDictionary z_inflateSetDictionary
-# define inflateSync z_inflateSync
-# define inflateSyncPoint z_inflateSyncPoint
-# define inflateCopy z_inflateCopy
-# define inflateReset z_inflateReset
-# define inflateBack z_inflateBack
-# define inflateBackEnd z_inflateBackEnd
-# define compress z_compress
-# define compress2 z_compress2
-# define compressBound z_compressBound
-# define uncompress z_uncompress
-# define adler32 z_adler32
-# define crc32 z_crc32
-# define get_crc_table z_get_crc_table
-# define zError z_zError
-
-# define alloc_func z_alloc_func
-# define free_func z_free_func
-# define in_func z_in_func
-# define out_func z_out_func
-# define Byte z_Byte
-# define uInt z_uInt
-# define uLong z_uLong
-# define Bytef z_Bytef
-# define charf z_charf
-# define intf z_intf
-# define uIntf z_uIntf
-# define uLongf z_uLongf
-# define voidpf z_voidpf
-# define voidp z_voidp
-#endif
-
-#if defined(__MSDOS__) && !defined(MSDOS)
-# define MSDOS
-#endif
-#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2)
-# define OS2
-#endif
-#if defined(_WINDOWS) && !defined(WINDOWS)
-# define WINDOWS
-#endif
-#if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__)
-# ifndef WIN32
-# define WIN32
-# endif
-#endif
-#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32)
-# if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__)
-# ifndef SYS16BIT
-# define SYS16BIT
-# endif
-# endif
-#endif
-
-/*
- * Compile with -DMAXSEG_64K if the alloc function cannot allocate more
- * than 64k bytes at a time (needed on systems with 16-bit int).
- */
-#ifdef SYS16BIT
-# define MAXSEG_64K
-#endif
-#ifdef MSDOS
-# define UNALIGNED_OK
-#endif
-
-#ifdef __STDC_VERSION__
-# ifndef STDC
-# define STDC
-# endif
-# if __STDC_VERSION__ >= 199901L
-# ifndef STDC99
-# define STDC99
-# endif
-# endif
-#endif
-#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus))
-# define STDC
-#endif
-#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__))
-# define STDC
-#endif
-#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32))
-# define STDC
-#endif
-#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__))
-# define STDC
-#endif
-
-#if defined(__OS400__) && !defined(STDC) /* iSeries (formerly AS/400). */
-# define STDC
-#endif
-
-#ifndef STDC
-# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */
-# define const /* note: need a more gentle solution here */
-# endif
-#endif
-
-/* Some Mac compilers merge all .h files incorrectly: */
-#if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__)
-# define NO_DUMMY_DECL
-#endif
-
-/* Maximum value for memLevel in deflateInit2 */
-#ifndef MAX_MEM_LEVEL
-# ifdef MAXSEG_64K
-# define MAX_MEM_LEVEL 8
-# else
-# define MAX_MEM_LEVEL 9
-# endif
-#endif
-
-/* Maximum value for windowBits in deflateInit2 and inflateInit2.
- * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files
- * created by gzip. (Files created by minigzip can still be extracted by
- * gzip.)
- */
-#ifndef MAX_WBITS
-# define MAX_WBITS 15 /* 32K LZ77 window */
-#endif
-
-/* The memory requirements for deflate are (in bytes):
- (1 << (windowBits+2)) + (1 << (memLevel+9))
- that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values)
- plus a few kilobytes for small objects. For example, if you want to reduce
- the default memory requirements from 256K to 128K, compile with
- make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7"
- Of course this will generally degrade compression (there's no free lunch).
-
- The memory requirements for inflate are (in bytes) 1 << windowBits
- that is, 32K for windowBits=15 (default value) plus a few kilobytes
- for small objects.
-*/
-
- /* Type declarations */
-
-#ifndef OF /* function prototypes */
-# ifdef STDC
-# define OF(args) args
-# else
-# define OF(args) ()
-# endif
-#endif
-
-/* The following definitions for FAR are needed only for MSDOS mixed
- * model programming (small or medium model with some far allocations).
- * This was tested only with MSC; for other MSDOS compilers you may have
- * to define NO_MEMCPY in zutil.h. If you don't need the mixed model,
- * just define FAR to be empty.
- */
-#ifdef SYS16BIT
-# if defined(M_I86SM) || defined(M_I86MM)
- /* MSC small or medium model */
-# define SMALL_MEDIUM
-# ifdef _MSC_VER
-# define FAR _far
-# else
-# define FAR far
-# endif
-# endif
-# if (defined(__SMALL__) || defined(__MEDIUM__))
- /* Turbo C small or medium model */
-# define SMALL_MEDIUM
-# ifdef __BORLANDC__
-# define FAR _far
-# else
-# define FAR far
-# endif
-# endif
-#endif
-
-#if defined(WINDOWS) || defined(WIN32)
- /* If building or using zlib as a DLL, define ZLIB_DLL.
- * This is not mandatory, but it offers a little performance increase.
- */
-# ifdef ZLIB_DLL
-# if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500))
-# ifdef ZLIB_INTERNAL
-# define ZEXTERN extern __declspec(dllexport)
-# else
-# define ZEXTERN extern __declspec(dllimport)
-# endif
-# endif
-# endif /* ZLIB_DLL */
- /* If building or using zlib with the WINAPI/WINAPIV calling convention,
- * define ZLIB_WINAPI.
- * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI.
- */
-# ifdef ZLIB_WINAPI
-# ifdef FAR
-# undef FAR
-# endif
-# include <windows.h>
- /* No need for _export, use ZLIB.DEF instead. */
- /* For complete Windows compatibility, use WINAPI, not __stdcall. */
-# define ZEXPORT WINAPI
-# ifdef WIN32
-# define ZEXPORTVA WINAPIV
-# else
-# define ZEXPORTVA FAR CDECL
-# endif
-# endif
-#endif
-
-#if defined (__BEOS__)
-# ifdef ZLIB_DLL
-# ifdef ZLIB_INTERNAL
-# define ZEXPORT __declspec(dllexport)
-# define ZEXPORTVA __declspec(dllexport)
-# else
-# define ZEXPORT __declspec(dllimport)
-# define ZEXPORTVA __declspec(dllimport)
-# endif
-# endif
-#endif
-
-#ifndef ZEXTERN
-# define ZEXTERN extern
-#endif
-#ifndef ZEXPORT
-# define ZEXPORT
-#endif
-#ifndef ZEXPORTVA
-# define ZEXPORTVA
-#endif
-
-#ifndef FAR
-# define FAR
-#endif
-
-#if !defined(__MACTYPES__)
-typedef unsigned char Byte; /* 8 bits */
-#endif
-typedef unsigned int uInt; /* 16 bits or more */
-typedef unsigned long uLong; /* 32 bits or more */
-
-#ifdef SMALL_MEDIUM
- /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */
-# define Bytef Byte FAR
-#else
- typedef Byte FAR Bytef;
-#endif
-typedef char FAR charf;
-typedef int FAR intf;
-typedef uInt FAR uIntf;
-typedef uLong FAR uLongf;
-
-#ifdef STDC
- typedef void const *voidpc;
- typedef void FAR *voidpf;
- typedef void *voidp;
-#else
- typedef Byte const *voidpc;
- typedef Byte FAR *voidpf;
- typedef Byte *voidp;
-#endif
-
-#if 0 /* HAVE_UNISTD_H -- this line is updated by ./configure */
-# include <sys/types.h> /* for off_t */
-# include <unistd.h> /* for SEEK_* and off_t */
-# ifdef VMS
-# include <unixio.h> /* for off_t */
-# endif
-# define z_off_t off_t
-#endif
-#ifndef SEEK_SET
-# define SEEK_SET 0 /* Seek from beginning of file. */
-# define SEEK_CUR 1 /* Seek from current position. */
-# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */
-#endif
-#ifndef z_off_t
-# define z_off_t long
-#endif
-
-#if defined(__OS400__)
-# define NO_vsnprintf
-#endif
-
-#if defined(__MVS__)
-# define NO_vsnprintf
-# ifdef FAR
-# undef FAR
-# endif
-#endif
-
-/* MVS linker does not support external names larger than 8 bytes */
-#if defined(__MVS__)
-# pragma map(deflateInit_,"DEIN")
-# pragma map(deflateInit2_,"DEIN2")
-# pragma map(deflateEnd,"DEEND")
-# pragma map(deflateBound,"DEBND")
-# pragma map(inflateInit_,"ININ")
-# pragma map(inflateInit2_,"ININ2")
-# pragma map(inflateEnd,"INEND")
-# pragma map(inflateSync,"INSY")
-# pragma map(inflateSetDictionary,"INSEDI")
-# pragma map(compressBound,"CMBND")
-# pragma map(inflate_table,"INTABL")
-# pragma map(inflate_fast,"INFA")
-# pragma map(inflate_copyright,"INCOPY")
-#endif
-
-#endif /* ZCONF_H */
+++ /dev/null
-/* zlib.h -- interface of the 'zlib' general purpose compression library
- version 1.2.3, July 18th, 2005
-
- Copyright (C) 1995-2005 Jean-loup Gailly and Mark Adler
-
- This software is provided 'as-is', without any express or implied
- warranty. In no event will the authors be held liable for any damages
- arising from the use of this software.
-
- Permission is granted to anyone to use this software for any purpose,
- including commercial applications, and to alter it and redistribute it
- freely, subject to the following restrictions:
-
- 1. The origin of this software must not be misrepresented; you must not
- claim that you wrote the original software. If you use this software
- in a product, an acknowledgment in the product documentation would be
- appreciated but is not required.
- 2. Altered source versions must be plainly marked as such, and must not be
- misrepresented as being the original software.
- 3. This notice may not be removed or altered from any source distribution.
-
- Jean-loup Gailly Mark Adler
- jloup@gzip.org madler@alumni.caltech.edu
-
-
- The data format used by the zlib library is described by RFCs (Request for
- Comments) 1950 to 1952 in the files http://www.ietf.org/rfc/rfc1950.txt
- (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format).
-*/
-
-#ifndef ZLIB_H
-#define ZLIB_H
-
-#include "zconf.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define ZLIB_VERSION "1.2.3"
-#define ZLIB_VERNUM 0x1230
-
-/*
- The 'zlib' compression library provides in-memory compression and
- decompression functions, including integrity checks of the uncompressed
- data. This version of the library supports only one compression method
- (deflation) but other algorithms will be added later and will have the same
- stream interface.
-
- Compression can be done in a single step if the buffers are large
- enough (for example if an input file is mmap'ed), or can be done by
- repeated calls of the compression function. In the latter case, the
- application must provide more input and/or consume the output
- (providing more output space) before each call.
-
- The compressed data format used by default by the in-memory functions is
- the zlib format, which is a zlib wrapper documented in RFC 1950, wrapped
- around a deflate stream, which is itself documented in RFC 1951.
-
- The library also supports reading and writing files in gzip (.gz) format
- with an interface similar to that of stdio using the functions that start
- with "gz". The gzip format is different from the zlib format. gzip is a
- gzip wrapper, documented in RFC 1952, wrapped around a deflate stream.
-
- This library can optionally read and write gzip streams in memory as well.
-
- The zlib format was designed to be compact and fast for use in memory
- and on communications channels. The gzip format was designed for single-
- file compression on file systems, has a larger header than zlib to maintain
- directory information, and uses a different, slower check method than zlib.
-
- The library does not install any signal handler. The decoder checks
- the consistency of the compressed data, so the library should never
- crash even in case of corrupted input.
-*/
-
-typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size));
-typedef void (*free_func) OF((voidpf opaque, voidpf address));
-
-struct internal_state;
-
-typedef struct z_stream_s {
- Bytef *next_in; /* next input byte */
- uInt avail_in; /* number of bytes available at next_in */
- uLong total_in; /* total nb of input bytes read so far */
-
- Bytef *next_out; /* next output byte should be put there */
- uInt avail_out; /* remaining free space at next_out */
- uLong total_out; /* total nb of bytes output so far */
-
- char *msg; /* last error message, NULL if no error */
- struct internal_state FAR *state; /* not visible by applications */
-
- alloc_func zalloc; /* used to allocate the internal state */
- free_func zfree; /* used to free the internal state */
- voidpf opaque; /* private data object passed to zalloc and zfree */
-
- int data_type; /* best guess about the data type: binary or text */
- uLong adler; /* adler32 value of the uncompressed data */
- uLong reserved; /* reserved for future use */
-} z_stream;
-
-typedef z_stream FAR *z_streamp;
-
-/*
- gzip header information passed to and from zlib routines. See RFC 1952
- for more details on the meanings of these fields.
-*/
-typedef struct gz_header_s {
- int text; /* true if compressed data believed to be text */
- uLong time; /* modification time */
- int xflags; /* extra flags (not used when writing a gzip file) */
- int os; /* operating system */
- Bytef *extra; /* pointer to extra field or Z_NULL if none */
- uInt extra_len; /* extra field length (valid if extra != Z_NULL) */
- uInt extra_max; /* space at extra (only when reading header) */
- Bytef *name; /* pointer to zero-terminated file name or Z_NULL */
- uInt name_max; /* space at name (only when reading header) */
- Bytef *comment; /* pointer to zero-terminated comment or Z_NULL */
- uInt comm_max; /* space at comment (only when reading header) */
- int hcrc; /* true if there was or will be a header crc */
- int done; /* true when done reading gzip header (not used
- when writing a gzip file) */
-} gz_header;
-
-typedef gz_header FAR *gz_headerp;
-
-/*
- The application must update next_in and avail_in when avail_in has
- dropped to zero. It must update next_out and avail_out when avail_out
- has dropped to zero. The application must initialize zalloc, zfree and
- opaque before calling the init function. All other fields are set by the
- compression library and must not be updated by the application.
-
- The opaque value provided by the application will be passed as the first
- parameter for calls of zalloc and zfree. This can be useful for custom
- memory management. The compression library attaches no meaning to the
- opaque value.
-
- zalloc must return Z_NULL if there is not enough memory for the object.
- If zlib is used in a multi-threaded application, zalloc and zfree must be
- thread safe.
-
- On 16-bit systems, the functions zalloc and zfree must be able to allocate
- exactly 65536 bytes, but will not be required to allocate more than this
- if the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS,
- pointers returned by zalloc for objects of exactly 65536 bytes *must*
- have their offset normalized to zero. The default allocation function
- provided by this library ensures this (see zutil.c). To reduce memory
- requirements and avoid any allocation of 64K objects, at the expense of
- compression ratio, compile the library with -DMAX_WBITS=14 (see zconf.h).
-
- The fields total_in and total_out can be used for statistics or
- progress reports. After compression, total_in holds the total size of
- the uncompressed data and may be saved for use in the decompressor
- (particularly if the decompressor wants to decompress everything in
- a single step).
-*/
-
- /* constants */
-
-#define Z_NO_FLUSH 0
-#define Z_PARTIAL_FLUSH 1 /* will be removed, use Z_SYNC_FLUSH instead */
-#define Z_SYNC_FLUSH 2
-#define Z_FULL_FLUSH 3
-#define Z_FINISH 4
-#define Z_BLOCK 5
-/* Allowed flush values; see deflate() and inflate() below for details */
-
-#define Z_OK 0
-#define Z_STREAM_END 1
-#define Z_NEED_DICT 2
-#define Z_ERRNO (-1)
-#define Z_STREAM_ERROR (-2)
-#define Z_DATA_ERROR (-3)
-#define Z_MEM_ERROR (-4)
-#define Z_BUF_ERROR (-5)
-#define Z_VERSION_ERROR (-6)
-/* Return codes for the compression/decompression functions. Negative
- * values are errors, positive values are used for special but normal events.
- */
-
-#define Z_NO_COMPRESSION 0
-#define Z_BEST_SPEED 1
-#define Z_BEST_COMPRESSION 9
-#define Z_DEFAULT_COMPRESSION (-1)
-/* compression levels */
-
-#define Z_FILTERED 1
-#define Z_HUFFMAN_ONLY 2
-#define Z_RLE 3
-#define Z_FIXED 4
-#define Z_DEFAULT_STRATEGY 0
-/* compression strategy; see deflateInit2() below for details */
-
-#define Z_BINARY 0
-#define Z_TEXT 1
-#define Z_ASCII Z_TEXT /* for compatibility with 1.2.2 and earlier */
-#define Z_UNKNOWN 2
-/* Possible values of the data_type field (though see inflate()) */
-
-#define Z_DEFLATED 8
-/* The deflate compression method (the only one supported in this version) */
-
-#define Z_NULL 0 /* for initializing zalloc, zfree, opaque */
-
-#define zlib_version zlibVersion()
-/* for compatibility with versions < 1.0.2 */
-
- /* basic functions */
-
-ZEXTERN const char * ZEXPORT zlibVersion OF((void));
-/* The application can compare zlibVersion and ZLIB_VERSION for consistency.
- If the first character differs, the library code actually used is
- not compatible with the zlib.h header file used by the application.
- This check is automatically made by deflateInit and inflateInit.
- */
-
-/*
-ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level));
-
- Initializes the internal stream state for compression. The fields
- zalloc, zfree and opaque must be initialized before by the caller.
- If zalloc and zfree are set to Z_NULL, deflateInit updates them to
- use default allocation functions.
-
- The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9:
- 1 gives best speed, 9 gives best compression, 0 gives no compression at
- all (the input data is simply copied a block at a time).
- Z_DEFAULT_COMPRESSION requests a default compromise between speed and
- compression (currently equivalent to level 6).
-
- deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not
- enough memory, Z_STREAM_ERROR if level is not a valid compression level,
- Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible
- with the version assumed by the caller (ZLIB_VERSION).
- msg is set to null if there is no error message. deflateInit does not
- perform any compression: this will be done by deflate().
-*/
-
-
-ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush));
-/*
- deflate compresses as much data as possible, and stops when the input
- buffer becomes empty or the output buffer becomes full. It may introduce some
- output latency (reading input without producing any output) except when
- forced to flush.
-
- The detailed semantics are as follows. deflate performs one or both of the
- following actions:
-
- - Compress more input starting at next_in and update next_in and avail_in
- accordingly. If not all input can be processed (because there is not
- enough room in the output buffer), next_in and avail_in are updated and
- processing will resume at this point for the next call of deflate().
-
- - Provide more output starting at next_out and update next_out and avail_out
- accordingly. This action is forced if the parameter flush is non zero.
- Forcing flush frequently degrades the compression ratio, so this parameter
- should be set only when necessary (in interactive applications).
- Some output may be provided even if flush is not set.
-
- Before the call of deflate(), the application should ensure that at least
- one of the actions is possible, by providing more input and/or consuming
- more output, and updating avail_in or avail_out accordingly; avail_out
- should never be zero before the call. The application can consume the
- compressed output when it wants, for example when the output buffer is full
- (avail_out == 0), or after each call of deflate(). If deflate returns Z_OK
- and with zero avail_out, it must be called again after making room in the
- output buffer because there might be more output pending.
-
- Normally the parameter flush is set to Z_NO_FLUSH, which allows deflate to
- decide how much data to accumualte before producing output, in order to
- maximize compression.
-
- If the parameter flush is set to Z_SYNC_FLUSH, all pending output is
- flushed to the output buffer and the output is aligned on a byte boundary, so
- that the decompressor can get all input data available so far. (In particular
- avail_in is zero after the call if enough output space has been provided
- before the call.) Flushing may degrade compression for some compression
- algorithms and so it should be used only when necessary.
-
- If flush is set to Z_FULL_FLUSH, all output is flushed as with
- Z_SYNC_FLUSH, and the compression state is reset so that decompression can
- restart from this point if previous compressed data has been damaged or if
- random access is desired. Using Z_FULL_FLUSH too often can seriously degrade
- compression.
-
- If deflate returns with avail_out == 0, this function must be called again
- with the same value of the flush parameter and more output space (updated
- avail_out), until the flush is complete (deflate returns with non-zero
- avail_out). In the case of a Z_FULL_FLUSH or Z_SYNC_FLUSH, make sure that
- avail_out is greater than six to avoid repeated flush markers due to
- avail_out == 0 on return.
-
- If the parameter flush is set to Z_FINISH, pending input is processed,
- pending output is flushed and deflate returns with Z_STREAM_END if there
- was enough output space; if deflate returns with Z_OK, this function must be
- called again with Z_FINISH and more output space (updated avail_out) but no
- more input data, until it returns with Z_STREAM_END or an error. After
- deflate has returned Z_STREAM_END, the only possible operations on the
- stream are deflateReset or deflateEnd.
-
- Z_FINISH can be used immediately after deflateInit if all the compression
- is to be done in a single step. In this case, avail_out must be at least
- the value returned by deflateBound (see below). If deflate does not return
- Z_STREAM_END, then it must be called again as described above.
-
- deflate() sets strm->adler to the adler32 checksum of all input read
- so far (that is, total_in bytes).
-
- deflate() may update strm->data_type if it can make a good guess about
- the input data type (Z_BINARY or Z_TEXT). In doubt, the data is considered
- binary. This field is only for information purposes and does not affect
- the compression algorithm in any manner.
-
- deflate() returns Z_OK if some progress has been made (more input
- processed or more output produced), Z_STREAM_END if all input has been
- consumed and all output has been produced (only when flush is set to
- Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example
- if next_in or next_out was NULL), Z_BUF_ERROR if no progress is possible
- (for example avail_in or avail_out was zero). Note that Z_BUF_ERROR is not
- fatal, and deflate() can be called again with more input and more output
- space to continue compressing.
-*/
-
-
-ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm));
-/*
- All dynamically allocated data structures for this stream are freed.
- This function discards any unprocessed input and does not flush any
- pending output.
-
- deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the
- stream state was inconsistent, Z_DATA_ERROR if the stream was freed
- prematurely (some input or output was discarded). In the error case,
- msg may be set but then points to a static string (which must not be
- deallocated).
-*/
-
-
-/*
-ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm));
-
- Initializes the internal stream state for decompression. The fields
- next_in, avail_in, zalloc, zfree and opaque must be initialized before by
- the caller. If next_in is not Z_NULL and avail_in is large enough (the exact
- value depends on the compression method), inflateInit determines the
- compression method from the zlib header and allocates all data structures
- accordingly; otherwise the allocation will be deferred to the first call of
- inflate. If zalloc and zfree are set to Z_NULL, inflateInit updates them to
- use default allocation functions.
-
- inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough
- memory, Z_VERSION_ERROR if the zlib library version is incompatible with the
- version assumed by the caller. msg is set to null if there is no error
- message. inflateInit does not perform any decompression apart from reading
- the zlib header if present: this will be done by inflate(). (So next_in and
- avail_in may be modified, but next_out and avail_out are unchanged.)
-*/
-
-
-ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush));
-/*
- inflate decompresses as much data as possible, and stops when the input
- buffer becomes empty or the output buffer becomes full. It may introduce
- some output latency (reading input without producing any output) except when
- forced to flush.
-
- The detailed semantics are as follows. inflate performs one or both of the
- following actions:
-
- - Decompress more input starting at next_in and update next_in and avail_in
- accordingly. If not all input can be processed (because there is not
- enough room in the output buffer), next_in is updated and processing
- will resume at this point for the next call of inflate().
-
- - Provide more output starting at next_out and update next_out and avail_out
- accordingly. inflate() provides as much output as possible, until there
- is no more input data or no more space in the output buffer (see below
- about the flush parameter).
-
- Before the call of inflate(), the application should ensure that at least
- one of the actions is possible, by providing more input and/or consuming
- more output, and updating the next_* and avail_* values accordingly.
- The application can consume the uncompressed output when it wants, for
- example when the output buffer is full (avail_out == 0), or after each
- call of inflate(). If inflate returns Z_OK and with zero avail_out, it
- must be called again after making room in the output buffer because there
- might be more output pending.
-
- The flush parameter of inflate() can be Z_NO_FLUSH, Z_SYNC_FLUSH,
- Z_FINISH, or Z_BLOCK. Z_SYNC_FLUSH requests that inflate() flush as much
- output as possible to the output buffer. Z_BLOCK requests that inflate() stop
- if and when it gets to the next deflate block boundary. When decoding the
- zlib or gzip format, this will cause inflate() to return immediately after
- the header and before the first block. When doing a raw inflate, inflate()
- will go ahead and process the first block, and will return when it gets to
- the end of that block, or when it runs out of data.
-
- The Z_BLOCK option assists in appending to or combining deflate streams.
- Also to assist in this, on return inflate() will set strm->data_type to the
- number of unused bits in the last byte taken from strm->next_in, plus 64
- if inflate() is currently decoding the last block in the deflate stream,
- plus 128 if inflate() returned immediately after decoding an end-of-block
- code or decoding the complete header up to just before the first byte of the
- deflate stream. The end-of-block will not be indicated until all of the
- uncompressed data from that block has been written to strm->next_out. The
- number of unused bits may in general be greater than seven, except when
- bit 7 of data_type is set, in which case the number of unused bits will be
- less than eight.
-
- inflate() should normally be called until it returns Z_STREAM_END or an
- error. However if all decompression is to be performed in a single step
- (a single call of inflate), the parameter flush should be set to
- Z_FINISH. In this case all pending input is processed and all pending
- output is flushed; avail_out must be large enough to hold all the
- uncompressed data. (The size of the uncompressed data may have been saved
- by the compressor for this purpose.) The next operation on this stream must
- be inflateEnd to deallocate the decompression state. The use of Z_FINISH
- is never required, but can be used to inform inflate that a faster approach
- may be used for the single inflate() call.
-
- In this implementation, inflate() always flushes as much output as
- possible to the output buffer, and always uses the faster approach on the
- first call. So the only effect of the flush parameter in this implementation
- is on the return value of inflate(), as noted below, or when it returns early
- because Z_BLOCK is used.
-
- If a preset dictionary is needed after this call (see inflateSetDictionary
- below), inflate sets strm->adler to the adler32 checksum of the dictionary
- chosen by the compressor and returns Z_NEED_DICT; otherwise it sets
- strm->adler to the adler32 checksum of all output produced so far (that is,
- total_out bytes) and returns Z_OK, Z_STREAM_END or an error code as described
- below. At the end of the stream, inflate() checks that its computed adler32
- checksum is equal to that saved by the compressor and returns Z_STREAM_END
- only if the checksum is correct.
-
- inflate() will decompress and check either zlib-wrapped or gzip-wrapped
- deflate data. The header type is detected automatically. Any information
- contained in the gzip header is not retained, so applications that need that
- information should instead use raw inflate, see inflateInit2() below, or
- inflateBack() and perform their own processing of the gzip header and
- trailer.
-
- inflate() returns Z_OK if some progress has been made (more input processed
- or more output produced), Z_STREAM_END if the end of the compressed data has
- been reached and all uncompressed output has been produced, Z_NEED_DICT if a
- preset dictionary is needed at this point, Z_DATA_ERROR if the input data was
- corrupted (input stream not conforming to the zlib format or incorrect check
- value), Z_STREAM_ERROR if the stream structure was inconsistent (for example
- if next_in or next_out was NULL), Z_MEM_ERROR if there was not enough memory,
- Z_BUF_ERROR if no progress is possible or if there was not enough room in the
- output buffer when Z_FINISH is used. Note that Z_BUF_ERROR is not fatal, and
- inflate() can be called again with more input and more output space to
- continue decompressing. If Z_DATA_ERROR is returned, the application may then
- call inflateSync() to look for a good compression block if a partial recovery
- of the data is desired.
-*/
-
-
-ZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm));
-/*
- All dynamically allocated data structures for this stream are freed.
- This function discards any unprocessed input and does not flush any
- pending output.
-
- inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state
- was inconsistent. In the error case, msg may be set but then points to a
- static string (which must not be deallocated).
-*/
-
- /* Advanced functions */
-
-/*
- The following functions are needed only in some special applications.
-*/
-
-/*
-ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm,
- int level,
- int method,
- int windowBits,
- int memLevel,
- int strategy));
-
- This is another version of deflateInit with more compression options. The
- fields next_in, zalloc, zfree and opaque must be initialized before by
- the caller.
-
- The method parameter is the compression method. It must be Z_DEFLATED in
- this version of the library.
-
- The windowBits parameter is the base two logarithm of the window size
- (the size of the history buffer). It should be in the range 8..15 for this
- version of the library. Larger values of this parameter result in better
- compression at the expense of memory usage. The default value is 15 if
- deflateInit is used instead.
-
- windowBits can also be -8..-15 for raw deflate. In this case, -windowBits
- determines the window size. deflate() will then generate raw deflate data
- with no zlib header or trailer, and will not compute an adler32 check value.
-
- windowBits can also be greater than 15 for optional gzip encoding. Add
- 16 to windowBits to write a simple gzip header and trailer around the
- compressed data instead of a zlib wrapper. The gzip header will have no
- file name, no extra data, no comment, no modification time (set to zero),
- no header crc, and the operating system will be set to 255 (unknown). If a
- gzip stream is being written, strm->adler is a crc32 instead of an adler32.
-
- The memLevel parameter specifies how much memory should be allocated
- for the internal compression state. memLevel=1 uses minimum memory but
- is slow and reduces compression ratio; memLevel=9 uses maximum memory
- for optimal speed. The default value is 8. See zconf.h for total memory
- usage as a function of windowBits and memLevel.
-
- The strategy parameter is used to tune the compression algorithm. Use the
- value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a
- filter (or predictor), Z_HUFFMAN_ONLY to force Huffman encoding only (no
- string match), or Z_RLE to limit match distances to one (run-length
- encoding). Filtered data consists mostly of small values with a somewhat
- random distribution. In this case, the compression algorithm is tuned to
- compress them better. The effect of Z_FILTERED is to force more Huffman
- coding and less string matching; it is somewhat intermediate between
- Z_DEFAULT and Z_HUFFMAN_ONLY. Z_RLE is designed to be almost as fast as
- Z_HUFFMAN_ONLY, but give better compression for PNG image data. The strategy
- parameter only affects the compression ratio but not the correctness of the
- compressed output even if it is not set appropriately. Z_FIXED prevents the
- use of dynamic Huffman codes, allowing for a simpler decoder for special
- applications.
-
- deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
- memory, Z_STREAM_ERROR if a parameter is invalid (such as an invalid
- method). msg is set to null if there is no error message. deflateInit2 does
- not perform any compression: this will be done by deflate().
-*/
-
-ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm,
- const Bytef *dictionary,
- uInt dictLength));
-/*
- Initializes the compression dictionary from the given byte sequence
- without producing any compressed output. This function must be called
- immediately after deflateInit, deflateInit2 or deflateReset, before any
- call of deflate. The compressor and decompressor must use exactly the same
- dictionary (see inflateSetDictionary).
-
- The dictionary should consist of strings (byte sequences) that are likely
- to be encountered later in the data to be compressed, with the most commonly
- used strings preferably put towards the end of the dictionary. Using a
- dictionary is most useful when the data to be compressed is short and can be
- predicted with good accuracy; the data can then be compressed better than
- with the default empty dictionary.
-
- Depending on the size of the compression data structures selected by
- deflateInit or deflateInit2, a part of the dictionary may in effect be
- discarded, for example if the dictionary is larger than the window size in
- deflate or deflate2. Thus the strings most likely to be useful should be
- put at the end of the dictionary, not at the front. In addition, the
- current implementation of deflate will use at most the window size minus
- 262 bytes of the provided dictionary.
-
- Upon return of this function, strm->adler is set to the adler32 value
- of the dictionary; the decompressor may later use this value to determine
- which dictionary has been used by the compressor. (The adler32 value
- applies to the whole dictionary even if only a subset of the dictionary is
- actually used by the compressor.) If a raw deflate was requested, then the
- adler32 value is not computed and strm->adler is not set.
-
- deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a
- parameter is invalid (such as NULL dictionary) or the stream state is
- inconsistent (for example if deflate has already been called for this stream
- or if the compression method is bsort). deflateSetDictionary does not
- perform any compression: this will be done by deflate().
-*/
-
-ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest,
- z_streamp source));
-/*
- Sets the destination stream as a complete copy of the source stream.
-
- This function can be useful when several compression strategies will be
- tried, for example when there are several ways of pre-processing the input
- data with a filter. The streams that will be discarded should then be freed
- by calling deflateEnd. Note that deflateCopy duplicates the internal
- compression state which can be quite large, so this strategy is slow and
- can consume lots of memory.
-
- deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not
- enough memory, Z_STREAM_ERROR if the source stream state was inconsistent
- (such as zalloc being NULL). msg is left unchanged in both source and
- destination.
-*/
-
-ZEXTERN int ZEXPORT deflateReset OF((z_streamp strm));
-/*
- This function is equivalent to deflateEnd followed by deflateInit,
- but does not free and reallocate all the internal compression state.
- The stream will keep the same compression level and any other attributes
- that may have been set by deflateInit2.
-
- deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
- stream state was inconsistent (such as zalloc or state being NULL).
-*/
-
-ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm,
- int level,
- int strategy));
-/*
- Dynamically update the compression level and compression strategy. The
- interpretation of level and strategy is as in deflateInit2. This can be
- used to switch between compression and straight copy of the input data, or
- to switch to a different kind of input data requiring a different
- strategy. If the compression level is changed, the input available so far
- is compressed with the old level (and may be flushed); the new level will
- take effect only at the next call of deflate().
-
- Before the call of deflateParams, the stream state must be set as for
- a call of deflate(), since the currently available input may have to
- be compressed and flushed. In particular, strm->avail_out must be non-zero.
-
- deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source
- stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR
- if strm->avail_out was zero.
-*/
-
-ZEXTERN int ZEXPORT deflateTune OF((z_streamp strm,
- int good_length,
- int max_lazy,
- int nice_length,
- int max_chain));
-/*
- Fine tune deflate's internal compression parameters. This should only be
- used by someone who understands the algorithm used by zlib's deflate for
- searching for the best matching string, and even then only by the most
- fanatic optimizer trying to squeeze out the last compressed bit for their
- specific input data. Read the deflate.c source code for the meaning of the
- max_lazy, good_length, nice_length, and max_chain parameters.
-
- deflateTune() can be called after deflateInit() or deflateInit2(), and
- returns Z_OK on success, or Z_STREAM_ERROR for an invalid deflate stream.
- */
-
-ZEXTERN uLong ZEXPORT deflateBound OF((z_streamp strm,
- uLong sourceLen));
-/*
- deflateBound() returns an upper bound on the compressed size after
- deflation of sourceLen bytes. It must be called after deflateInit()
- or deflateInit2(). This would be used to allocate an output buffer
- for deflation in a single pass, and so would be called before deflate().
-*/
-
-ZEXTERN int ZEXPORT deflatePrime OF((z_streamp strm,
- int bits,
- int value));
-/*
- deflatePrime() inserts bits in the deflate output stream. The intent
- is that this function is used to start off the deflate output with the
- bits leftover from a previous deflate stream when appending to it. As such,
- this function can only be used for raw deflate, and must be used before the
- first deflate() call after a deflateInit2() or deflateReset(). bits must be
- less than or equal to 16, and that many of the least significant bits of
- value will be inserted in the output.
-
- deflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source
- stream state was inconsistent.
-*/
-
-ZEXTERN int ZEXPORT deflateSetHeader OF((z_streamp strm,
- gz_headerp head));
-/*
- deflateSetHeader() provides gzip header information for when a gzip
- stream is requested by deflateInit2(). deflateSetHeader() may be called
- after deflateInit2() or deflateReset() and before the first call of
- deflate(). The text, time, os, extra field, name, and comment information
- in the provided gz_header structure are written to the gzip header (xflag is
- ignored -- the extra flags are set according to the compression level). The
- caller must assure that, if not Z_NULL, name and comment are terminated with
- a zero byte, and that if extra is not Z_NULL, that extra_len bytes are
- available there. If hcrc is true, a gzip header crc is included. Note that
- the current versions of the command-line version of gzip (up through version
- 1.3.x) do not support header crc's, and will report that it is a "multi-part
- gzip file" and give up.
-
- If deflateSetHeader is not used, the default gzip header has text false,
- the time set to zero, and os set to 255, with no extra, name, or comment
- fields. The gzip header is returned to the default state by deflateReset().
-
- deflateSetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source
- stream state was inconsistent.
-*/
-
-/*
-ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm,
- int windowBits));
-
- This is another version of inflateInit with an extra parameter. The
- fields next_in, avail_in, zalloc, zfree and opaque must be initialized
- before by the caller.
-
- The windowBits parameter is the base two logarithm of the maximum window
- size (the size of the history buffer). It should be in the range 8..15 for
- this version of the library. The default value is 15 if inflateInit is used
- instead. windowBits must be greater than or equal to the windowBits value
- provided to deflateInit2() while compressing, or it must be equal to 15 if
- deflateInit2() was not used. If a compressed stream with a larger window
- size is given as input, inflate() will return with the error code
- Z_DATA_ERROR instead of trying to allocate a larger window.
-
- windowBits can also be -8..-15 for raw inflate. In this case, -windowBits
- determines the window size. inflate() will then process raw deflate data,
- not looking for a zlib or gzip header, not generating a check value, and not
- looking for any check values for comparison at the end of the stream. This
- is for use with other formats that use the deflate compressed data format
- such as zip. Those formats provide their own check values. If a custom
- format is developed using the raw deflate format for compressed data, it is
- recommended that a check value such as an adler32 or a crc32 be applied to
- the uncompressed data as is done in the zlib, gzip, and zip formats. For
- most applications, the zlib format should be used as is. Note that comments
- above on the use in deflateInit2() applies to the magnitude of windowBits.
-
- windowBits can also be greater than 15 for optional gzip decoding. Add
- 32 to windowBits to enable zlib and gzip decoding with automatic header
- detection, or add 16 to decode only the gzip format (the zlib format will
- return a Z_DATA_ERROR). If a gzip stream is being decoded, strm->adler is
- a crc32 instead of an adler32.
-
- inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
- memory, Z_STREAM_ERROR if a parameter is invalid (such as a null strm). msg
- is set to null if there is no error message. inflateInit2 does not perform
- any decompression apart from reading the zlib header if present: this will
- be done by inflate(). (So next_in and avail_in may be modified, but next_out
- and avail_out are unchanged.)
-*/
-
-ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm,
- const Bytef *dictionary,
- uInt dictLength));
-/*
- Initializes the decompression dictionary from the given uncompressed byte
- sequence. This function must be called immediately after a call of inflate,
- if that call returned Z_NEED_DICT. The dictionary chosen by the compressor
- can be determined from the adler32 value returned by that call of inflate.
- The compressor and decompressor must use exactly the same dictionary (see
- deflateSetDictionary). For raw inflate, this function can be called
- immediately after inflateInit2() or inflateReset() and before any call of
- inflate() to set the dictionary. The application must insure that the
- dictionary that was used for compression is provided.
-
- inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a
- parameter is invalid (such as NULL dictionary) or the stream state is
- inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the
- expected one (incorrect adler32 value). inflateSetDictionary does not
- perform any decompression: this will be done by subsequent calls of
- inflate().
-*/
-
-ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm));
-/*
- Skips invalid compressed data until a full flush point (see above the
- description of deflate with Z_FULL_FLUSH) can be found, or until all
- available input is skipped. No output is provided.
-
- inflateSync returns Z_OK if a full flush point has been found, Z_BUF_ERROR
- if no more input was provided, Z_DATA_ERROR if no flush point has been found,
- or Z_STREAM_ERROR if the stream structure was inconsistent. In the success
- case, the application may save the current current value of total_in which
- indicates where valid compressed data was found. In the error case, the
- application may repeatedly call inflateSync, providing more input each time,
- until success or end of the input data.
-*/
-
-ZEXTERN int ZEXPORT inflateCopy OF((z_streamp dest,
- z_streamp source));
-/*
- Sets the destination stream as a complete copy of the source stream.
-
- This function can be useful when randomly accessing a large stream. The
- first pass through the stream can periodically record the inflate state,
- allowing restarting inflate at those points when randomly accessing the
- stream.
-
- inflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not
- enough memory, Z_STREAM_ERROR if the source stream state was inconsistent
- (such as zalloc being NULL). msg is left unchanged in both source and
- destination.
-*/
-
-ZEXTERN int ZEXPORT inflateReset OF((z_streamp strm));
-/*
- This function is equivalent to inflateEnd followed by inflateInit,
- but does not free and reallocate all the internal decompression state.
- The stream will keep attributes that may have been set by inflateInit2.
-
- inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
- stream state was inconsistent (such as zalloc or state being NULL).
-*/
-
-ZEXTERN int ZEXPORT inflatePrime OF((z_streamp strm,
- int bits,
- int value));
-/*
- This function inserts bits in the inflate input stream. The intent is
- that this function is used to start inflating at a bit position in the
- middle of a byte. The provided bits will be used before any bytes are used
- from next_in. This function should only be used with raw inflate, and
- should be used before the first inflate() call after inflateInit2() or
- inflateReset(). bits must be less than or equal to 16, and that many of the
- least significant bits of value will be inserted in the input.
-
- inflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source
- stream state was inconsistent.
-*/
-
-ZEXTERN int ZEXPORT inflateGetHeader OF((z_streamp strm,
- gz_headerp head));
-/*
- inflateGetHeader() requests that gzip header information be stored in the
- provided gz_header structure. inflateGetHeader() may be called after
- inflateInit2() or inflateReset(), and before the first call of inflate().
- As inflate() processes the gzip stream, head->done is zero until the header
- is completed, at which time head->done is set to one. If a zlib stream is
- being decoded, then head->done is set to -1 to indicate that there will be
- no gzip header information forthcoming. Note that Z_BLOCK can be used to
- force inflate() to return immediately after header processing is complete
- and before any actual data is decompressed.
-
- The text, time, xflags, and os fields are filled in with the gzip header
- contents. hcrc is set to true if there is a header CRC. (The header CRC
- was valid if done is set to one.) If extra is not Z_NULL, then extra_max
- contains the maximum number of bytes to write to extra. Once done is true,
- extra_len contains the actual extra field length, and extra contains the
- extra field, or that field truncated if extra_max is less than extra_len.
- If name is not Z_NULL, then up to name_max characters are written there,
- terminated with a zero unless the length is greater than name_max. If
- comment is not Z_NULL, then up to comm_max characters are written there,
- terminated with a zero unless the length is greater than comm_max. When
- any of extra, name, or comment are not Z_NULL and the respective field is
- not present in the header, then that field is set to Z_NULL to signal its
- absence. This allows the use of deflateSetHeader() with the returned
- structure to duplicate the header. However if those fields are set to
- allocated memory, then the application will need to save those pointers
- elsewhere so that they can be eventually freed.
-
- If inflateGetHeader is not used, then the header information is simply
- discarded. The header is always checked for validity, including the header
- CRC if present. inflateReset() will reset the process to discard the header
- information. The application would need to call inflateGetHeader() again to
- retrieve the header from the next gzip stream.
-
- inflateGetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source
- stream state was inconsistent.
-*/
-
-/*
-ZEXTERN int ZEXPORT inflateBackInit OF((z_streamp strm, int windowBits,
- unsigned char FAR *window));
-
- Initialize the internal stream state for decompression using inflateBack()
- calls. The fields zalloc, zfree and opaque in strm must be initialized
- before the call. If zalloc and zfree are Z_NULL, then the default library-
- derived memory allocation routines are used. windowBits is the base two
- logarithm of the window size, in the range 8..15. window is a caller
- supplied buffer of that size. Except for special applications where it is
- assured that deflate was used with small window sizes, windowBits must be 15
- and a 32K byte window must be supplied to be able to decompress general
- deflate streams.
-
- See inflateBack() for the usage of these routines.
-
- inflateBackInit will return Z_OK on success, Z_STREAM_ERROR if any of
- the paramaters are invalid, Z_MEM_ERROR if the internal state could not
- be allocated, or Z_VERSION_ERROR if the version of the library does not
- match the version of the header file.
-*/
-
-typedef unsigned (*in_func) OF((void FAR *, unsigned char FAR * FAR *));
-typedef int (*out_func) OF((void FAR *, unsigned char FAR *, unsigned));
-
-ZEXTERN int ZEXPORT inflateBack OF((z_streamp strm,
- in_func in, void FAR *in_desc,
- out_func out, void FAR *out_desc));
-/*
- inflateBack() does a raw inflate with a single call using a call-back
- interface for input and output. This is more efficient than inflate() for
- file i/o applications in that it avoids copying between the output and the
- sliding window by simply making the window itself the output buffer. This
- function trusts the application to not change the output buffer passed by
- the output function, at least until inflateBack() returns.
-
- inflateBackInit() must be called first to allocate the internal state
- and to initialize the state with the user-provided window buffer.
- inflateBack() may then be used multiple times to inflate a complete, raw
- deflate stream with each call. inflateBackEnd() is then called to free
- the allocated state.
-
- A raw deflate stream is one with no zlib or gzip header or trailer.
- This routine would normally be used in a utility that reads zip or gzip
- files and writes out uncompressed files. The utility would decode the
- header and process the trailer on its own, hence this routine expects
- only the raw deflate stream to decompress. This is different from the
- normal behavior of inflate(), which expects either a zlib or gzip header and
- trailer around the deflate stream.
-
- inflateBack() uses two subroutines supplied by the caller that are then
- called by inflateBack() for input and output. inflateBack() calls those
- routines until it reads a complete deflate stream and writes out all of the
- uncompressed data, or until it encounters an error. The function's
- parameters and return types are defined above in the in_func and out_func
- typedefs. inflateBack() will call in(in_desc, &buf) which should return the
- number of bytes of provided input, and a pointer to that input in buf. If
- there is no input available, in() must return zero--buf is ignored in that
- case--and inflateBack() will return a buffer error. inflateBack() will call
- out(out_desc, buf, len) to write the uncompressed data buf[0..len-1]. out()
- should return zero on success, or non-zero on failure. If out() returns
- non-zero, inflateBack() will return with an error. Neither in() nor out()
- are permitted to change the contents of the window provided to
- inflateBackInit(), which is also the buffer that out() uses to write from.
- The length written by out() will be at most the window size. Any non-zero
- amount of input may be provided by in().
-
- For convenience, inflateBack() can be provided input on the first call by
- setting strm->next_in and strm->avail_in. If that input is exhausted, then
- in() will be called. Therefore strm->next_in must be initialized before
- calling inflateBack(). If strm->next_in is Z_NULL, then in() will be called
- immediately for input. If strm->next_in is not Z_NULL, then strm->avail_in
- must also be initialized, and then if strm->avail_in is not zero, input will
- initially be taken from strm->next_in[0 .. strm->avail_in - 1].
-
- The in_desc and out_desc parameters of inflateBack() is passed as the
- first parameter of in() and out() respectively when they are called. These
- descriptors can be optionally used to pass any information that the caller-
- supplied in() and out() functions need to do their job.
-
- On return, inflateBack() will set strm->next_in and strm->avail_in to
- pass back any unused input that was provided by the last in() call. The
- return values of inflateBack() can be Z_STREAM_END on success, Z_BUF_ERROR
- if in() or out() returned an error, Z_DATA_ERROR if there was a format
- error in the deflate stream (in which case strm->msg is set to indicate the
- nature of the error), or Z_STREAM_ERROR if the stream was not properly
- initialized. In the case of Z_BUF_ERROR, an input or output error can be
- distinguished using strm->next_in which will be Z_NULL only if in() returned
- an error. If strm->next is not Z_NULL, then the Z_BUF_ERROR was due to
- out() returning non-zero. (in() will always be called before out(), so
- strm->next_in is assured to be defined if out() returns non-zero.) Note
- that inflateBack() cannot return Z_OK.
-*/
-
-ZEXTERN int ZEXPORT inflateBackEnd OF((z_streamp strm));
-/*
- All memory allocated by inflateBackInit() is freed.
-
- inflateBackEnd() returns Z_OK on success, or Z_STREAM_ERROR if the stream
- state was inconsistent.
-*/
-
-ZEXTERN uLong ZEXPORT zlibCompileFlags OF((void));
-/* Return flags indicating compile-time options.
-
- Type sizes, two bits each, 00 = 16 bits, 01 = 32, 10 = 64, 11 = other:
- 1.0: size of uInt
- 3.2: size of uLong
- 5.4: size of voidpf (pointer)
- 7.6: size of z_off_t
-
- Compiler, assembler, and debug options:
- 8: DEBUG
- 9: ASMV or ASMINF -- use ASM code
- 10: ZLIB_WINAPI -- exported functions use the WINAPI calling convention
- 11: 0 (reserved)
-
- One-time table building (smaller code, but not thread-safe if true):
- 12: BUILDFIXED -- build static block decoding tables when needed
- 13: DYNAMIC_CRC_TABLE -- build CRC calculation tables when needed
- 14,15: 0 (reserved)
-
- Library content (indicates missing functionality):
- 16: NO_GZCOMPRESS -- gz* functions cannot compress (to avoid linking
- deflate code when not needed)
- 17: NO_GZIP -- deflate can't write gzip streams, and inflate can't detect
- and decode gzip streams (to avoid linking crc code)
- 18-19: 0 (reserved)
-
- Operation variations (changes in library functionality):
- 20: PKZIP_BUG_WORKAROUND -- slightly more permissive inflate
- 21: FASTEST -- deflate algorithm with only one, lowest compression level
- 22,23: 0 (reserved)
-
- The sprintf variant used by gzprintf (zero is best):
- 24: 0 = vs*, 1 = s* -- 1 means limited to 20 arguments after the format
- 25: 0 = *nprintf, 1 = *printf -- 1 means gzprintf() not secure!
- 26: 0 = returns value, 1 = void -- 1 means inferred string length returned
-
- Remainder:
- 27-31: 0 (reserved)
- */
-
-
- /* utility functions */
-
-/*
- The following utility functions are implemented on top of the
- basic stream-oriented functions. To simplify the interface, some
- default options are assumed (compression level and memory usage,
- standard memory allocation functions). The source code of these
- utility functions can easily be modified if you need special options.
-*/
-
-ZEXTERN int ZEXPORT compress OF((Bytef *dest, uLongf *destLen,
- const Bytef *source, uLong sourceLen));
-/*
- Compresses the source buffer into the destination buffer. sourceLen is
- the byte length of the source buffer. Upon entry, destLen is the total
- size of the destination buffer, which must be at least the value returned
- by compressBound(sourceLen). Upon exit, destLen is the actual size of the
- compressed buffer.
- This function can be used to compress a whole file at once if the
- input file is mmap'ed.
- compress returns Z_OK if success, Z_MEM_ERROR if there was not
- enough memory, Z_BUF_ERROR if there was not enough room in the output
- buffer.
-*/
-
-ZEXTERN int ZEXPORT compress2 OF((Bytef *dest, uLongf *destLen,
- const Bytef *source, uLong sourceLen,
- int level));
-/*
- Compresses the source buffer into the destination buffer. The level
- parameter has the same meaning as in deflateInit. sourceLen is the byte
- length of the source buffer. Upon entry, destLen is the total size of the
- destination buffer, which must be at least the value returned by
- compressBound(sourceLen). Upon exit, destLen is the actual size of the
- compressed buffer.
-
- compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
- memory, Z_BUF_ERROR if there was not enough room in the output buffer,
- Z_STREAM_ERROR if the level parameter is invalid.
-*/
-
-ZEXTERN uLong ZEXPORT compressBound OF((uLong sourceLen));
-/*
- compressBound() returns an upper bound on the compressed size after
- compress() or compress2() on sourceLen bytes. It would be used before
- a compress() or compress2() call to allocate the destination buffer.
-*/
-
-ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen,
- const Bytef *source, uLong sourceLen));
-/*
- Decompresses the source buffer into the destination buffer. sourceLen is
- the byte length of the source buffer. Upon entry, destLen is the total
- size of the destination buffer, which must be large enough to hold the
- entire uncompressed data. (The size of the uncompressed data must have
- been saved previously by the compressor and transmitted to the decompressor
- by some mechanism outside the scope of this compression library.)
- Upon exit, destLen is the actual size of the compressed buffer.
- This function can be used to decompress a whole file at once if the
- input file is mmap'ed.
-
- uncompress returns Z_OK if success, Z_MEM_ERROR if there was not
- enough memory, Z_BUF_ERROR if there was not enough room in the output
- buffer, or Z_DATA_ERROR if the input data was corrupted or incomplete.
-*/
-
-
-typedef voidp gzFile;
-
-ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode));
-/*
- Opens a gzip (.gz) file for reading or writing. The mode parameter
- is as in fopen ("rb" or "wb") but can also include a compression level
- ("wb9") or a strategy: 'f' for filtered data as in "wb6f", 'h' for
- Huffman only compression as in "wb1h", or 'R' for run-length encoding
- as in "wb1R". (See the description of deflateInit2 for more information
- about the strategy parameter.)
-
- gzopen can be used to read a file which is not in gzip format; in this
- case gzread will directly read from the file without decompression.
-
- gzopen returns NULL if the file could not be opened or if there was
- insufficient memory to allocate the (de)compression state; errno
- can be checked to distinguish the two cases (if errno is zero, the
- zlib error is Z_MEM_ERROR). */
-
-ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode));
-/*
- gzdopen() associates a gzFile with the file descriptor fd. File
- descriptors are obtained from calls like open, dup, creat, pipe or
- fileno (in the file has been previously opened with fopen).
- The mode parameter is as in gzopen.
- The next call of gzclose on the returned gzFile will also close the
- file descriptor fd, just like fclose(fdopen(fd), mode) closes the file
- descriptor fd. If you want to keep fd open, use gzdopen(dup(fd), mode).
- gzdopen returns NULL if there was insufficient memory to allocate
- the (de)compression state.
-*/
-
-ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy));
-/*
- Dynamically update the compression level or strategy. See the description
- of deflateInit2 for the meaning of these parameters.
- gzsetparams returns Z_OK if success, or Z_STREAM_ERROR if the file was not
- opened for writing.
-*/
-
-ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len));
-/*
- Reads the given number of uncompressed bytes from the compressed file.
- If the input file was not in gzip format, gzread copies the given number
- of bytes into the buffer.
- gzread returns the number of uncompressed bytes actually read (0 for
- end of file, -1 for error). */
-
-ZEXTERN int ZEXPORT gzwrite OF((gzFile file,
- voidpc buf, unsigned len));
-/*
- Writes the given number of uncompressed bytes into the compressed file.
- gzwrite returns the number of uncompressed bytes actually written
- (0 in case of error).
-*/
-
-ZEXTERN int ZEXPORTVA gzprintf OF((gzFile file, const char *format, ...));
-/*
- Converts, formats, and writes the args to the compressed file under
- control of the format string, as in fprintf. gzprintf returns the number of
- uncompressed bytes actually written (0 in case of error). The number of
- uncompressed bytes written is limited to 4095. The caller should assure that
- this limit is not exceeded. If it is exceeded, then gzprintf() will return
- return an error (0) with nothing written. In this case, there may also be a
- buffer overflow with unpredictable consequences, which is possible only if
- zlib was compiled with the insecure functions sprintf() or vsprintf()
- because the secure snprintf() or vsnprintf() functions were not available.
-*/
-
-ZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s));
-/*
- Writes the given null-terminated string to the compressed file, excluding
- the terminating null character.
- gzputs returns the number of characters written, or -1 in case of error.
-*/
-
-ZEXTERN char * ZEXPORT gzgets OF((gzFile file, char *buf, int len));
-/*
- Reads bytes from the compressed file until len-1 characters are read, or
- a newline character is read and transferred to buf, or an end-of-file
- condition is encountered. The string is then terminated with a null
- character.
- gzgets returns buf, or Z_NULL in case of error.
-*/
-
-ZEXTERN int ZEXPORT gzputc OF((gzFile file, int c));
-/*
- Writes c, converted to an unsigned char, into the compressed file.
- gzputc returns the value that was written, or -1 in case of error.
-*/
-
-ZEXTERN int ZEXPORT gzgetc OF((gzFile file));
-/*
- Reads one byte from the compressed file. gzgetc returns this byte
- or -1 in case of end of file or error.
-*/
-
-ZEXTERN int ZEXPORT gzungetc OF((int c, gzFile file));
-/*
- Push one character back onto the stream to be read again later.
- Only one character of push-back is allowed. gzungetc() returns the
- character pushed, or -1 on failure. gzungetc() will fail if a
- character has been pushed but not read yet, or if c is -1. The pushed
- character will be discarded if the stream is repositioned with gzseek()
- or gzrewind().
-*/
-
-ZEXTERN int ZEXPORT gzflush OF((gzFile file, int flush));
-/*
- Flushes all pending output into the compressed file. The parameter
- flush is as in the deflate() function. The return value is the zlib
- error number (see function gzerror below). gzflush returns Z_OK if
- the flush parameter is Z_FINISH and all output could be flushed.
- gzflush should be called only when strictly necessary because it can
- degrade compression.
-*/
-
-ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile file,
- z_off_t offset, int whence));
-/*
- Sets the starting position for the next gzread or gzwrite on the
- given compressed file. The offset represents a number of bytes in the
- uncompressed data stream. The whence parameter is defined as in lseek(2);
- the value SEEK_END is not supported.
- If the file is opened for reading, this function is emulated but can be
- extremely slow. If the file is opened for writing, only forward seeks are
- supported; gzseek then compresses a sequence of zeroes up to the new
- starting position.
-
- gzseek returns the resulting offset location as measured in bytes from
- the beginning of the uncompressed stream, or -1 in case of error, in
- particular if the file is opened for writing and the new starting position
- would be before the current position.
-*/
-
-ZEXTERN int ZEXPORT gzrewind OF((gzFile file));
-/*
- Rewinds the given file. This function is supported only for reading.
-
- gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET)
-*/
-
-ZEXTERN z_off_t ZEXPORT gztell OF((gzFile file));
-/*
- Returns the starting position for the next gzread or gzwrite on the
- given compressed file. This position represents a number of bytes in the
- uncompressed data stream.
-
- gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR)
-*/
-
-ZEXTERN int ZEXPORT gzeof OF((gzFile file));
-/*
- Returns 1 when EOF has previously been detected reading the given
- input stream, otherwise zero.
-*/
-
-ZEXTERN int ZEXPORT gzdirect OF((gzFile file));
-/*
- Returns 1 if file is being read directly without decompression, otherwise
- zero.
-*/
-
-ZEXTERN int ZEXPORT gzclose OF((gzFile file));
-/*
- Flushes all pending output if necessary, closes the compressed file
- and deallocates all the (de)compression state. The return value is the zlib
- error number (see function gzerror below).
-*/
-
-ZEXTERN const char * ZEXPORT gzerror OF((gzFile file, int *errnum));
-/*
- Returns the error message for the last error which occurred on the
- given compressed file. errnum is set to zlib error number. If an
- error occurred in the file system and not in the compression library,
- errnum is set to Z_ERRNO and the application may consult errno
- to get the exact error code.
-*/
-
-ZEXTERN void ZEXPORT gzclearerr OF((gzFile file));
-/*
- Clears the error and end-of-file flags for file. This is analogous to the
- clearerr() function in stdio. This is useful for continuing to read a gzip
- file that is being written concurrently.
-*/
-
- /* checksum functions */
-
-/*
- These functions are not related to compression but are exported
- anyway because they might be useful in applications using the
- compression library.
-*/
-
-ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len));
-/*
- Update a running Adler-32 checksum with the bytes buf[0..len-1] and
- return the updated checksum. If buf is NULL, this function returns
- the required initial value for the checksum.
- An Adler-32 checksum is almost as reliable as a CRC32 but can be computed
- much faster. Usage example:
-
- uLong adler = adler32(0L, Z_NULL, 0);
-
- while (read_buffer(buffer, length) != EOF) {
- adler = adler32(adler, buffer, length);
- }
- if (adler != original_adler) error();
-*/
-
-ZEXTERN uLong ZEXPORT adler32_combine OF((uLong adler1, uLong adler2,
- z_off_t len2));
-/*
- Combine two Adler-32 checksums into one. For two sequences of bytes, seq1
- and seq2 with lengths len1 and len2, Adler-32 checksums were calculated for
- each, adler1 and adler2. adler32_combine() returns the Adler-32 checksum of
- seq1 and seq2 concatenated, requiring only adler1, adler2, and len2.
-*/
-
-ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len));
-/*
- Update a running CRC-32 with the bytes buf[0..len-1] and return the
- updated CRC-32. If buf is NULL, this function returns the required initial
- value for the for the crc. Pre- and post-conditioning (one's complement) is
- performed within this function so it shouldn't be done by the application.
- Usage example:
-
- uLong crc = crc32(0L, Z_NULL, 0);
-
- while (read_buffer(buffer, length) != EOF) {
- crc = crc32(crc, buffer, length);
- }
- if (crc != original_crc) error();
-*/
-
-ZEXTERN uLong ZEXPORT crc32_combine OF((uLong crc1, uLong crc2, z_off_t len2));
-
-/*
- Combine two CRC-32 check values into one. For two sequences of bytes,
- seq1 and seq2 with lengths len1 and len2, CRC-32 check values were
- calculated for each, crc1 and crc2. crc32_combine() returns the CRC-32
- check value of seq1 and seq2 concatenated, requiring only crc1, crc2, and
- len2.
-*/
-
-
- /* various hacks, don't look :) */
-
-/* deflateInit and inflateInit are macros to allow checking the zlib version
- * and the compiler's view of z_stream:
- */
-ZEXTERN int ZEXPORT deflateInit_ OF((z_streamp strm, int level,
- const char *version, int stream_size));
-ZEXTERN int ZEXPORT inflateInit_ OF((z_streamp strm,
- const char *version, int stream_size));
-ZEXTERN int ZEXPORT deflateInit2_ OF((z_streamp strm, int level, int method,
- int windowBits, int memLevel,
- int strategy, const char *version,
- int stream_size));
-ZEXTERN int ZEXPORT inflateInit2_ OF((z_streamp strm, int windowBits,
- const char *version, int stream_size));
-ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits,
- unsigned char FAR *window,
- const char *version,
- int stream_size));
-#define deflateInit(strm, level) \
- deflateInit_((strm), (level), ZLIB_VERSION, sizeof(z_stream))
-#define inflateInit(strm) \
- inflateInit_((strm), ZLIB_VERSION, sizeof(z_stream))
-#define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \
- deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\
- (strategy), ZLIB_VERSION, sizeof(z_stream))
-#define inflateInit2(strm, windowBits) \
- inflateInit2_((strm), (windowBits), ZLIB_VERSION, sizeof(z_stream))
-#define inflateBackInit(strm, windowBits, window) \
- inflateBackInit_((strm), (windowBits), (window), \
- ZLIB_VERSION, sizeof(z_stream))
-
-
-#if !defined(ZUTIL_H) && !defined(NO_DUMMY_DECL)
- struct internal_state {int dummy;}; /* hack for buggy compilers */
-#endif
-
-ZEXTERN const char * ZEXPORT zError OF((int));
-ZEXTERN int ZEXPORT inflateSyncPoint OF((z_streamp z));
-ZEXTERN const uLongf * ZEXPORT get_crc_table OF((void));
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* ZLIB_H */
+++ /dev/null
-/* zutil.c -- target dependent utility functions for the compression library
- * Copyright (C) 1995-2005 Jean-loup Gailly.
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* @(#) $Id$ */
-
-#include "zutil.h"
-
-#ifndef NO_DUMMY_DECL
-struct internal_state {int dummy;}; /* for buggy compilers */
-#endif
-
-const char * const z_errmsg[10] = {
-"need dictionary", /* Z_NEED_DICT 2 */
-"stream end", /* Z_STREAM_END 1 */
-"", /* Z_OK 0 */
-"file error", /* Z_ERRNO (-1) */
-"stream error", /* Z_STREAM_ERROR (-2) */
-"data error", /* Z_DATA_ERROR (-3) */
-"insufficient memory", /* Z_MEM_ERROR (-4) */
-"buffer error", /* Z_BUF_ERROR (-5) */
-"incompatible version",/* Z_VERSION_ERROR (-6) */
-""};
-
-
-const char * ZEXPORT zlibVersion()
-{
- return ZLIB_VERSION;
-}
-
-uLong ZEXPORT zlibCompileFlags()
-{
- uLong flags;
-
- flags = 0;
- switch (sizeof(uInt)) {
- case 2: break;
- case 4: flags += 1; break;
- case 8: flags += 2; break;
- default: flags += 3;
- }
- switch (sizeof(uLong)) {
- case 2: break;
- case 4: flags += 1 << 2; break;
- case 8: flags += 2 << 2; break;
- default: flags += 3 << 2;
- }
- switch (sizeof(voidpf)) {
- case 2: break;
- case 4: flags += 1 << 4; break;
- case 8: flags += 2 << 4; break;
- default: flags += 3 << 4;
- }
- switch (sizeof(z_off_t)) {
- case 2: break;
- case 4: flags += 1 << 6; break;
- case 8: flags += 2 << 6; break;
- default: flags += 3 << 6;
- }
-#ifdef DEBUG
- flags += 1 << 8;
-#endif
-#if defined(ASMV) || defined(ASMINF)
- flags += 1 << 9;
-#endif
-#ifdef ZLIB_WINAPI
- flags += 1 << 10;
-#endif
-#ifdef BUILDFIXED
- flags += 1 << 12;
-#endif
-#ifdef DYNAMIC_CRC_TABLE
- flags += 1 << 13;
-#endif
-#ifdef NO_GZCOMPRESS
- flags += 1L << 16;
-#endif
-#ifdef NO_GZIP
- flags += 1L << 17;
-#endif
-#ifdef PKZIP_BUG_WORKAROUND
- flags += 1L << 20;
-#endif
-#ifdef FASTEST
- flags += 1L << 21;
-#endif
-#ifdef STDC
-# ifdef NO_vsnprintf
- flags += 1L << 25;
-# ifdef HAS_vsprintf_void
- flags += 1L << 26;
-# endif
-# else
-# ifdef HAS_vsnprintf_void
- flags += 1L << 26;
-# endif
-# endif
-#else
- flags += 1L << 24;
-# ifdef NO_snprintf
- flags += 1L << 25;
-# ifdef HAS_sprintf_void
- flags += 1L << 26;
-# endif
-# else
-# ifdef HAS_snprintf_void
- flags += 1L << 26;
-# endif
-# endif
-#endif
- return flags;
-}
-
-#ifdef DEBUG
-
-# ifndef verbose
-# define verbose 0
-# endif
-int z_verbose = verbose;
-
-void z_error (m)
- char *m;
-{
- fprintf(stderr, "%s\n", m);
- exit(1);
-}
-#endif
-
-/* exported to allow conversion of error code to string for compress() and
- * uncompress()
- */
-const char * ZEXPORT zError(err)
- int err;
-{
- return ERR_MSG(err);
-}
-
-#if defined(_WIN32_WCE)
- /* The Microsoft C Run-Time Library for Windows CE doesn't have
- * errno. We define it as a global variable to simplify porting.
- * Its value is always 0 and should not be used.
- */
- int errno = 0;
-#endif
-
-#ifndef HAVE_MEMCPY
-
-void zmemcpy(dest, source, len)
- Bytef* dest;
- const Bytef* source;
- uInt len;
-{
- if (len == 0) return;
- do {
- *dest++ = *source++; /* ??? to be unrolled */
- } while (--len != 0);
-}
-
-int zmemcmp(s1, s2, len)
- const Bytef* s1;
- const Bytef* s2;
- uInt len;
-{
- uInt j;
-
- for (j = 0; j < len; j++) {
- if (s1[j] != s2[j]) return 2*(s1[j] > s2[j])-1;
- }
- return 0;
-}
-
-void zmemzero(dest, len)
- Bytef* dest;
- uInt len;
-{
- if (len == 0) return;
- do {
- *dest++ = 0; /* ??? to be unrolled */
- } while (--len != 0);
-}
-#endif
-
-
-#ifdef SYS16BIT
-
-#ifdef __TURBOC__
-/* Turbo C in 16-bit mode */
-
-# define MY_ZCALLOC
-
-/* Turbo C malloc() does not allow dynamic allocation of 64K bytes
- * and farmalloc(64K) returns a pointer with an offset of 8, so we
- * must fix the pointer. Warning: the pointer must be put back to its
- * original form in order to free it, use zcfree().
- */
-
-#define MAX_PTR 10
-/* 10*64K = 640K */
-
-local int next_ptr = 0;
-
-typedef struct ptr_table_s {
- voidpf org_ptr;
- voidpf new_ptr;
-} ptr_table;
-
-local ptr_table table[MAX_PTR];
-/* This table is used to remember the original form of pointers
- * to large buffers (64K). Such pointers are normalized with a zero offset.
- * Since MSDOS is not a preemptive multitasking OS, this table is not
- * protected from concurrent access. This hack doesn't work anyway on
- * a protected system like OS/2. Use Microsoft C instead.
- */
-
-voidpf zcalloc (voidpf opaque, unsigned items, unsigned size)
-{
- voidpf buf = opaque; /* just to make some compilers happy */
- ulg bsize = (ulg)items*size;
-
- /* If we allocate less than 65520 bytes, we assume that farmalloc
- * will return a usable pointer which doesn't have to be normalized.
- */
- if (bsize < 65520L) {
- buf = farmalloc(bsize);
- if (*(ush*)&buf != 0) return buf;
- } else {
- buf = farmalloc(bsize + 16L);
- }
- if (buf == NULL || next_ptr >= MAX_PTR) return NULL;
- table[next_ptr].org_ptr = buf;
-
- /* Normalize the pointer to seg:0 */
- *((ush*)&buf+1) += ((ush)((uch*)buf-0) + 15) >> 4;
- *(ush*)&buf = 0;
- table[next_ptr++].new_ptr = buf;
- return buf;
-}
-
-void zcfree (voidpf opaque, voidpf ptr)
-{
- int n;
- if (*(ush*)&ptr != 0) { /* object < 64K */
- farfree(ptr);
- return;
- }
- /* Find the original pointer */
- for (n = 0; n < next_ptr; n++) {
- if (ptr != table[n].new_ptr) continue;
-
- farfree(table[n].org_ptr);
- while (++n < next_ptr) {
- table[n-1] = table[n];
- }
- next_ptr--;
- return;
- }
- ptr = opaque; /* just to make some compilers happy */
- Assert(0, "zcfree: ptr not found");
-}
-
-#endif /* __TURBOC__ */
-
-
-#ifdef M_I86
-/* Microsoft C in 16-bit mode */
-
-# define MY_ZCALLOC
-
-#if (!defined(_MSC_VER) || (_MSC_VER <= 600))
-# define _halloc halloc
-# define _hfree hfree
-#endif
-
-voidpf zcalloc (voidpf opaque, unsigned items, unsigned size)
-{
- if (opaque) opaque = 0; /* to make compiler happy */
- return _halloc((long)items, size);
-}
-
-void zcfree (voidpf opaque, voidpf ptr)
-{
- if (opaque) opaque = 0; /* to make compiler happy */
- _hfree(ptr);
-}
-
-#endif /* M_I86 */
-
-#endif /* SYS16BIT */
-
-
-#ifndef MY_ZCALLOC /* Any system without a special alloc function */
-
-#ifndef STDC
-extern voidp malloc OF((uInt size));
-extern voidp calloc OF((uInt items, uInt size));
-extern void free OF((voidpf ptr));
-#endif
-
-voidpf zcalloc (opaque, items, size)
- voidpf opaque;
- unsigned items;
- unsigned size;
-{
- if (opaque) items += size - size; /* make compiler happy */
- return sizeof(uInt) > 2 ? (voidpf)malloc(items * size) :
- (voidpf)calloc(items, size);
-}
-
-void zcfree (opaque, ptr)
- voidpf opaque;
- voidpf ptr;
-{
- free(ptr);
- if (opaque) return; /* make compiler happy */
-}
-
-#endif /* MY_ZCALLOC */
+++ /dev/null
-/* zutil.h -- internal interface and configuration of the compression library
- * Copyright (C) 1995-2005 Jean-loup Gailly.
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* WARNING: this file should *not* be used by applications. It is
- part of the implementation of the compression library and is
- subject to change. Applications should only use zlib.h.
- */
-
-/* @(#) $Id$ */
-
-#ifndef ZUTIL_H
-#define ZUTIL_H
-
-#define ZLIB_INTERNAL
-#include "zlib.h"
-
-#ifdef STDC
-# ifndef _WIN32_WCE
-# include <stddef.h>
-# endif
-# include <string.h>
-# include <stdlib.h>
-#endif
-#ifdef NO_ERRNO_H
-# ifdef _WIN32_WCE
- /* The Microsoft C Run-Time Library for Windows CE doesn't have
- * errno. We define it as a global variable to simplify porting.
- * Its value is always 0 and should not be used. We rename it to
- * avoid conflict with other libraries that use the same workaround.
- */
-# define errno z_errno
-# endif
- extern int errno;
-#else
-# ifndef _WIN32_WCE
-# include <errno.h>
-# endif
-#endif
-
-#ifndef local
-# define local static
-#endif
-/* compile with -Dlocal if your debugger can't find static symbols */
-
-typedef unsigned char uch;
-typedef uch FAR uchf;
-typedef unsigned short ush;
-typedef ush FAR ushf;
-typedef unsigned long ulg;
-
-extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */
-/* (size given to avoid silly warnings with Visual C++) */
-
-#define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)]
-
-#define ERR_RETURN(strm,err) \
- return (strm->msg = (char*)ERR_MSG(err), (err))
-/* To be used only when the state is known to be valid */
-
- /* common constants */
-
-#ifndef DEF_WBITS
-# define DEF_WBITS MAX_WBITS
-#endif
-/* default windowBits for decompression. MAX_WBITS is for compression only */
-
-#if MAX_MEM_LEVEL >= 8
-# define DEF_MEM_LEVEL 8
-#else
-# define DEF_MEM_LEVEL MAX_MEM_LEVEL
-#endif
-/* default memLevel */
-
-#define STORED_BLOCK 0
-#define STATIC_TREES 1
-#define DYN_TREES 2
-/* The three kinds of block type */
-
-#define MIN_MATCH 3
-#define MAX_MATCH 258
-/* The minimum and maximum match lengths */
-
-#define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */
-
- /* target dependencies */
-
-#if defined(MSDOS) || (defined(WINDOWS) && !defined(WIN32))
-# define OS_CODE 0x00
-# if defined(__TURBOC__) || defined(__BORLANDC__)
-# if(__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__))
- /* Allow compilation with ANSI keywords only enabled */
- void _Cdecl farfree( void *block );
- void *_Cdecl farmalloc( unsigned long nbytes );
-# else
-# include <alloc.h>
-# endif
-# else /* MSC or DJGPP */
-# include <malloc.h>
-# endif
-#endif
-
-#ifdef AMIGA
-# define OS_CODE 0x01
-#endif
-
-#if defined(VAXC) || defined(VMS)
-# define OS_CODE 0x02
-# define F_OPEN(name, mode) \
- fopen((name), (mode), "mbc=60", "ctx=stm", "rfm=fix", "mrs=512")
-#endif
-
-#if defined(ATARI) || defined(atarist)
-# define OS_CODE 0x05
-#endif
-
-#ifdef OS2
-# define OS_CODE 0x06
-# ifdef M_I86
- #include <malloc.h>
-# endif
-#endif
-
-#if defined(MACOS) || defined(TARGET_OS_MAC)
-# define OS_CODE 0x07
-# if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os
-# include <unix.h> /* for fdopen */
-# else
-# ifndef fdopen
-# define fdopen(fd,mode) NULL /* No fdopen() */
-# endif
-# endif
-#endif
-
-#ifdef TOPS20
-# define OS_CODE 0x0a
-#endif
-
-#ifdef WIN32
-# ifndef __CYGWIN__ /* Cygwin is Unix, not Win32 */
-# define OS_CODE 0x0b
-# endif
-#endif
-
-#ifdef __50SERIES /* Prime/PRIMOS */
-# define OS_CODE 0x0f
-#endif
-
-#if defined(_BEOS_) || defined(RISCOS)
-# define fdopen(fd,mode) NULL /* No fdopen() */
-#endif
-
-#if (defined(_MSC_VER) && (_MSC_VER > 600))
-# if defined(_WIN32_WCE)
-# define fdopen(fd,mode) NULL /* No fdopen() */
-# ifndef _PTRDIFF_T_DEFINED
- typedef int ptrdiff_t;
-# define _PTRDIFF_T_DEFINED
-# endif
-# else
-# define fdopen(fd,type) _fdopen(fd,type)
-# endif
-#endif
-
- /* common defaults */
-
-#ifndef OS_CODE
-# define OS_CODE 0x03 /* assume Unix */
-#endif
-
-#ifndef F_OPEN
-# define F_OPEN(name, mode) fopen((name), (mode))
-#endif
-
- /* functions */
-
-#if defined(STDC99) || (defined(__TURBOC__) && __TURBOC__ >= 0x550)
-# ifndef HAVE_VSNPRINTF
-# define HAVE_VSNPRINTF
-# endif
-#endif
-#if defined(__CYGWIN__)
-# ifndef HAVE_VSNPRINTF
-# define HAVE_VSNPRINTF
-# endif
-#endif
-#ifndef HAVE_VSNPRINTF
-# ifdef MSDOS
- /* vsnprintf may exist on some MS-DOS compilers (DJGPP?),
- but for now we just assume it doesn't. */
-# define NO_vsnprintf
-# endif
-# ifdef __TURBOC__
-# define NO_vsnprintf
-# endif
-# ifdef WIN32
- /* In Win32, vsnprintf is available as the "non-ANSI" _vsnprintf. */
-# if !defined(vsnprintf) && !defined(NO_vsnprintf)
-# define vsnprintf _vsnprintf
-# endif
-# endif
-# ifdef __SASC
-# define NO_vsnprintf
-# endif
-#endif
-#ifdef VMS
-# define NO_vsnprintf
-#endif
-
-#if defined(pyr)
-# define NO_MEMCPY
-#endif
-#if defined(SMALL_MEDIUM) && !defined(_MSC_VER) && !defined(__SC__)
- /* Use our own functions for small and medium model with MSC <= 5.0.
- * You may have to use the same strategy for Borland C (untested).
- * The __SC__ check is for Symantec.
- */
-# define NO_MEMCPY
-#endif
-#if defined(STDC) && !defined(HAVE_MEMCPY) && !defined(NO_MEMCPY)
-# define HAVE_MEMCPY
-#endif
-#ifdef HAVE_MEMCPY
-# ifdef SMALL_MEDIUM /* MSDOS small or medium model */
-# define zmemcpy _fmemcpy
-# define zmemcmp _fmemcmp
-# define zmemzero(dest, len) _fmemset(dest, 0, len)
-# else
-# define zmemcpy memcpy
-# define zmemcmp memcmp
-# define zmemzero(dest, len) memset(dest, 0, len)
-# endif
-#else
- extern void zmemcpy OF((Bytef* dest, const Bytef* source, uInt len));
- extern int zmemcmp OF((const Bytef* s1, const Bytef* s2, uInt len));
- extern void zmemzero OF((Bytef* dest, uInt len));
-#endif
-
-/* Diagnostic functions */
-#ifdef DEBUG
-# include <stdio.h>
- extern int z_verbose;
- extern void z_error OF((char *m));
-# define Assert(cond,msg) {if(!(cond)) z_error(msg);}
-# define Trace(x) {if (z_verbose>=0) fprintf x ;}
-# define Tracev(x) {if (z_verbose>0) fprintf x ;}
-# define Tracevv(x) {if (z_verbose>1) fprintf x ;}
-# define Tracec(c,x) {if (z_verbose>0 && (c)) fprintf x ;}
-# define Tracecv(c,x) {if (z_verbose>1 && (c)) fprintf x ;}
-#else
-# define Assert(cond,msg)
-# define Trace(x)
-# define Tracev(x)
-# define Tracevv(x)
-# define Tracec(c,x)
-# define Tracecv(c,x)
-#endif
-
-
-voidpf zcalloc OF((voidpf opaque, unsigned items, unsigned size));
-void zcfree OF((voidpf opaque, voidpf ptr));
-
-#define ZALLOC(strm, items, size) \
- (*((strm)->zalloc))((strm)->opaque, (items), (size))
-#define ZFREE(strm, addr) (*((strm)->zfree))((strm)->opaque, (voidpf)(addr))
-#define TRY_FREE(s, p) {if (p) ZFREE(s, p);}
-
-#endif /* ZUTIL_H */
+++ /dev/null
-// Copyright Timothy Goya 2007.
-// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at
-// http://www.boost.org/LICENSE_1_0.txt)
-
-#include <unison/vfs/FileSystem.hpp>
-
-#include <fstream>
-
-#include <physfs.h>
-
-namespace Unison
-{
- namespace VFS
- {
- FileSystem::FileSystem()
- {
-#if __USE_POSIX
- std::ifstream cmdline("/proc/self/cmdline");
- std::string argv0;
- std::getline(cmdline, argv0, '\0');
- PHYSFS_init(argv0.c_str());
-#else
- PHYSFS_init(0);
-#endif
- }
-
- FileSystem::~FileSystem()
- {
- PHYSFS_deinit();
- }
-
- void FileSystem::follow_sym_links(bool follow)
- {
- PHYSFS_permitSymbolicLinks(follow);
- }
-
- std::string FileSystem::get_dir_sep()
- {
- return PHYSFS_getDirSeparator();
- }
-
- std::string FileSystem::get_base_dir()
- {
- return PHYSFS_getBaseDir();
- }
-
- std::string FileSystem::get_user_dir()
- {
- return PHYSFS_getUserDir();
- }
-
- std::string FileSystem::get_write_dir()
- {
- return PHYSFS_getWriteDir();
- }
-
- void FileSystem::set_write_dir(const std::string &write_dir)
- {
- PHYSFS_setWriteDir(write_dir.c_str());
- }
-
- void FileSystem::mount(const std::string &path, const std::string &mount_point, bool append)
- {
- PHYSFS_mount(path.c_str(), mount_point.c_str(), append);
- }
-
- void FileSystem::umount(const std::string &path)
- {
- PHYSFS_removeFromSearchPath(path.c_str());
- }
-
- std::vector<std::string> FileSystem::get_search_path()
- {
- std::vector<std::string> paths;
- char **search_path = PHYSFS_getSearchPath();
- for(char **iter = search_path;*iter;++iter)
- {
- paths.push_back(*iter);
- }
- PHYSFS_freeList(search_path);
- return paths;
- }
-
- std::string FileSystem::get_mount_point(const std::string &path)
- {
- return PHYSFS_getMountPoint(path.c_str());
- }
-
- void FileSystem::mkdir(const std::string &dir)
- {
- PHYSFS_mkdir(dir.c_str());
- }
-
- void FileSystem::rm(const std::string &filename)
- {
- PHYSFS_delete(filename.c_str());
- }
-
- std::vector<std::string> FileSystem::ls(const std::string &path)
- {
- std::vector<std::string> files;
- char **physfs_files = PHYSFS_enumerateFiles(path.c_str());
- for(char **iter = physfs_files;*iter;++iter)
- {
- files.push_back(*iter);
- }
- PHYSFS_freeList(physfs_files);
- return files;
- }
-
- bool FileSystem::exists(const std::string &filename)
- {
- return PHYSFS_exists(filename.c_str());
- }
-
- bool FileSystem::is_dir(const std::string &filename)
- {
- return PHYSFS_isDirectory(filename.c_str());
- }
-
- std::string FileSystem::get_real_dir(const std::string &filename)
- {
- return PHYSFS_getRealDir(filename.c_str());
- }
- }
-}
+++ /dev/null
-// Copyright Timothy Goya 2007.
-// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at
-// http://www.boost.org/LICENSE_1_0.txt)
-
-#include <unison/vfs/sdl/Utils.hpp>
-
-#include <fstream>
-#include <assert.h>
-
-#include <physfs.h>
-#include "SDL.h"
-
-namespace
-{
- int rwops_seek(SDL_RWops *context, int offset, int whence)
- {
- PHYSFS_File *file = reinterpret_cast<PHYSFS_File *>(context->hidden.unknown.data1);
- int res = 0;
- switch(whence) {
- case SEEK_SET:
- res = PHYSFS_seek(file, offset);
- break;
- case SEEK_CUR:
- res = PHYSFS_seek(file, PHYSFS_tell(file) + offset);
- break;
- case SEEK_END:
- res = PHYSFS_seek(file, PHYSFS_fileLength(file) + offset);
- break;
- default:
- assert(0);
- break;
- }
-
- return (int) PHYSFS_tell(file);
- }
-
- int rwops_read(SDL_RWops *context, void *ptr, int size, int maxnum)
- {
- PHYSFS_File *file = reinterpret_cast<PHYSFS_File *>(context->hidden.unknown.data1);
-
- int res = PHYSFS_read(file, ptr, size, maxnum);
- return res;
- }
-
- int rwops_close(SDL_RWops *context)
- {
- PHYSFS_File *file = reinterpret_cast<PHYSFS_File *>(context->hidden.unknown.data1);
-
- PHYSFS_close(file);
- delete context;
-
- return 0;
- }
-}
-
-
-namespace Unison
-{
- namespace VFS
- {
- namespace SDL
- {
- SDL_RWops *Utils::open_physfs_in(const std::string &filename)
- {
- PHYSFS_File *file = PHYSFS_openRead(filename.c_str());
- assert(file);
- SDL_RWops* ops = new SDL_RWops;
- ops->type = 0;
- ops->hidden.unknown.data1 = file;
- ops->seek = rwops_seek;
- ops->read = rwops_read;
- ops->write = 0;
- ops->close = rwops_close;
- return ops;
- }
- }
- }
-}
+++ /dev/null
-// Copyright Timothy Goya 2007.
-// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at
-// http://www.boost.org/LICENSE_1_0.txt)
-
-#include <unison/vfs/stream.hpp>
-
-#include <streambuf>
-#include <assert.h>
-#include <physfs.h>
-
-// FIXME: make streambufs more complete
-namespace
-{
- class iphysfsfilebuf : public std::streambuf
- {
- public:
- iphysfsfilebuf(const std::string &filename)
- {
- file = PHYSFS_openRead(filename.c_str());
- assert(file);
- }
-
- ~iphysfsfilebuf()
- {
- PHYSFS_close(file);
- }
- protected:
- int underflow()
- {
- if(PHYSFS_eof(file))
- {
- return traits_type::eof();
- }
- PHYSFS_sint64 bytes = PHYSFS_read(file, buffer, 1, sizeof(buffer));
- if(bytes <= 0)
- {
- return traits_type::eof();
- }
- setg(buffer, buffer, buffer + bytes);
- return buffer[0];
- }
-
- pos_type seekoff(off_type off, std::ios_base::seekdir way, std::ios_base::openmode which)
- {
- off_type nsp = off;
- PHYSFS_sint64 pos = PHYSFS_tell(file);
- switch(way)
- {
- case std::ios_base::beg:
- break;
- case std::ios_base::cur:
- if(off == 0)
- {
- return pos - (egptr() - gptr());
- }
- nsp += pos - (egptr() - gptr());
- break;
- case std::ios_base::end:
- nsp += PHYSFS_fileLength(file);
- break;
- default:
- assert(0);
- break;
- }
- return seekpos(nsp, which);
- }
-
- pos_type seekpos(pos_type sp, std::ios_base::openmode /*which*/)
- {
- if(PHYSFS_seek(file, sp) == 0)
- {
- return -1;
- }
- setg(buffer, buffer, buffer);
- return sp;
- }
- private:
- PHYSFS_File *file;
- char buffer[1024];
- };
-
- class ophysfsfilebuf : public std::streambuf
- {
- public:
- ophysfsfilebuf(const std::string &filename)
- {
- file = PHYSFS_openWrite(filename.c_str());
- assert(file);
- setp(buffer, buffer + sizeof(buffer));
- }
-
- ~ophysfsfilebuf()
- {
- sync();
- PHYSFS_close(file);
- }
- protected:
- int sync()
- {
- return overflow(traits_type::eof());
- }
-
- int overflow(int c)
- {
- char ch = static_cast<char>(c);
- size_t size = pptr() - pbase();
- if(size == 0)
- {
- return 0;
- }
- PHYSFS_sint64 bytes = PHYSFS_write(file, pbase(), 1, size);
- if(bytes <= 0)
- {
- return traits_type::eof();
- }
- if(c != traits_type::eof())
- {
- PHYSFS_sint64 bytes = PHYSFS_write(file, &ch, 1, 1);
- if(bytes <= 0)
- {
- return traits_type::eof();
- }
- }
- setp(buffer, buffer + bytes);
- return 0;
- }
- private:
- PHYSFS_File *file;
- char buffer[1024];
- };
-}
-
-namespace Unison
-{
- namespace VFS
- {
- istream::istream(const std::string &filename) :
- std::istream(new iphysfsfilebuf(filename))
- {
- }
-
- istream::~istream()
- {
- delete rdbuf();
- }
-
- ostream::ostream(const std::string &filename) :
- std::ostream(new ophysfsfilebuf(filename))
- {
- }
-
- ostream::~ostream()
- {
- delete rdbuf();
- }
- }
-}
+++ /dev/null
-// Copyright Timothy Goya 2007.
-// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at
-// http://www.boost.org/LICENSE_1_0.txt)
-
-#include <unison/video/Blittable.hpp>
-#include <unison/video/DisplayList.hpp>
-
-namespace Unison
-{
- namespace Video
- {
- Blittable::~Blittable()
- {
- }
-
- void Blittable::blit_section(const SurfaceSection §ion, const Point &dst_pos, const RenderOptions &options)
- {
- blit(section.image, dst_pos, section.clip_rect, options);
- }
-
- void Blittable::blit_section(const TextureSection §ion, const Point &dst_pos, const RenderOptions &options)
- {
- blit(section.image, dst_pos, section.clip_rect, options);
- }
-
- void Blittable::draw(const DisplayList &list)
- {
- list.draw(this);
- }
-
- BlittableSection::BlittableSection(Blittable &image, const Rect &clip_rect) :
- image(image),
- clip_rect(clip_rect)
- {
- }
-
- void BlittableSection::blit(const Surface &src, const Point &dst_pos, const Rect &src_rect, const RenderOptions &options)
- {
- Rect overlap = clip_rect.get_overlap(Rect(dst_pos, src_rect.size));
- if(overlap == Rect())
- {
- return;
- }
- Rect clipped_src_rect(src_rect.pos, overlap.size);
- clipped_src_rect.pos += overlap.pos;
- clipped_src_rect.pos -= dst_pos;
- image.blit(src, overlap.pos - clip_rect.pos, clipped_src_rect, options);
- }
-
- void BlittableSection::blit(const Texture &src, const Point &dst_pos, const Rect &src_rect, const RenderOptions &options)
- {
- Rect overlap = clip_rect.get_overlap(Rect(dst_pos, src_rect.size));
- if(overlap == Rect())
- {
- return;
- }
- Rect clipped_src_rect(src_rect.pos, overlap.size);
- clipped_src_rect.pos += overlap.pos;
- clipped_src_rect.pos -= dst_pos;
- image.blit(src, overlap.pos - clip_rect.pos, clipped_src_rect, options);
- }
-
- void BlittableSection::fill(const Color &color, const Rect &rect)
- {
- Rect overlap = clip_rect.get_overlap(rect);
- overlap.pos -= clip_rect.pos;
- image.fill(color, overlap);
- }
-
- void BlittableSection::fill_blend(const Color &color, const Rect &rect)
- {
- Rect overlap = clip_rect.get_overlap(rect);
- overlap.pos -= clip_rect.pos;
- image.fill_blend(color, overlap);
- }
- }
-}
+++ /dev/null
-// Copyright Timothy Goya 2007.
-// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at
-// http://www.boost.org/LICENSE_1_0.txt)
-
-#include <unison/video/Blitters.hpp>
-#include <unison/video/Surface.hpp>
-
-#include <assert.h>
-
-namespace Unison
-{
- namespace Video
- {
- void Blitters::blit_upper(const Surface &src, Rect src_rect, Surface &dst, Point dst_pos, void (*blit_lower)(const Surface &, const Rect &, Surface &, const Point &))
- {
- assert(src.get_pixels());
- assert(dst.get_pixels());
- assert(blit_lower);
- if(src_rect == Rect())
- {
- src_rect.size.x = src.get_size().x;
- src_rect.size.y = src.get_size().y;
- }
- if(dst_pos.x < 0)
- {
- if(src_rect.size.x < (unsigned int) -dst_pos.x)
- {
- return;
- }
- src_rect.pos.x += -dst_pos.x;
- src_rect.size.x += dst_pos.x;
- dst_pos.x = 0;
- }
- if(dst_pos.y < 0)
- {
- if(src_rect.size.y < (unsigned int) -dst_pos.y)
- {
- return;
- }
- src_rect.pos.y += -dst_pos.y;
- src_rect.size.y += dst_pos.y;
- dst_pos.y = 0;
- }
- if(src_rect.pos.x < 0)
- {
- if(src_rect.size.x < (unsigned int) -src_rect.pos.x)
- {
- return;
- }
- src_rect.size.x += src_rect.pos.x;
- src_rect.pos.x = 0;
- }
- if(src_rect.pos.y < 0)
- {
- if(src_rect.size.y < (unsigned int) -src_rect.pos.y)
- {
- return;
- }
- src_rect.size.y += src_rect.pos.y;
- src_rect.pos.y = 0;
- }
- if(src_rect.get_right() > (int) src.get_size().x)
- {
- src_rect.size.x = src.get_size().x - src_rect.pos.x;
- }
- if(src_rect.get_bottom() > (int) src.get_size().y)
- {
- src_rect.size.y = src.get_size().y - src_rect.pos.y;
- }
- if(dst_pos.x + src_rect.size.x > dst.get_size().x)
- {
- src_rect.size.x = dst.get_size().x - dst_pos.x;
- }
- if(dst_pos.y + src_rect.size.y > dst.get_size().y)
- {
- src_rect.size.y = dst.get_size().y - dst_pos.y;
- }
- blit_lower(src, src_rect, dst, dst_pos);
- }
-
- void Blitters::blit_lower_none(const Surface &src, const Rect &src_rect, Surface &dst, const Point &dst_pos)
- {
- if(src_rect.pos == Point() && dst_pos == Point() && src.get_size().x == dst.get_size().x && src_rect.size.x == dst.get_size().x)
- {
- memcpy(dst.get_pixels(), src.get_pixels(), src_rect.size.x * src_rect.size.y * sizeof(Color));
- }
- else
- {
- const Color *src_line = src.get_pixels() + src_rect.pos.y * src.get_size().x + src_rect.pos.x;
- Color *dst_line = dst.get_pixels() + dst_pos.y * dst.get_size().x + dst_pos.x;
- for(unsigned int y = 0;y < src_rect.size.y;y++)
- {
- memcpy(dst_line, src_line, src_rect.size.x * sizeof(Color));
- src_line += src.get_size().x;
- dst_line += dst.get_size().x;
- }
- }
- }
-
- void Blitters::blit_lower_mask(const Surface &src, const Rect &src_rect, Surface &dst, const Point &dst_pos)
- {
- const Color *src_pixel = src.get_pixels() + src_rect.pos.y * src.get_size().x + src_rect.pos.x;
- Color *dst_pixel = dst.get_pixels() + dst_pos.y * dst.get_size().x + dst_pos.x;
- for(unsigned int y = 0;y < src_rect.size.y;y++)
- {
- for(unsigned int x = 0;x < src_rect.size.x;x++)
- {
- if(src_pixel->alpha)
- {
- *dst_pixel = *src_pixel;
- }
- src_pixel++;
- dst_pixel++;
- }
- src_pixel += src.get_size().x - src_rect.size.x;
- dst_pixel += dst.get_size().x - src_rect.size.x;
- }
- }
-
- void Blitters::blit_lower_alpha(const Surface &src, const Rect &src_rect, Surface &dst, const Point &dst_pos)
- {
- const Color *src_pixel = src.get_pixels() + src_rect.pos.y * src.get_size().x + src_rect.pos.x;
- Color *dst_pixel = dst.get_pixels() + dst_pos.y * dst.get_size().x + dst_pos.x;
- for(unsigned int y = 0;y < src_rect.size.y;y++)
- {
- for(unsigned int x = 0;x < src_rect.size.x;x++)
- {
- dst_pixel->red += src_pixel->red * src_pixel->alpha - dst_pixel->red * src_pixel->alpha;
- dst_pixel->green += src_pixel->green * src_pixel->alpha - dst_pixel->green * src_pixel->alpha;
- dst_pixel->blue += src_pixel->blue * src_pixel->alpha - dst_pixel->green * src_pixel->blue;
- src_pixel++;
- dst_pixel++;
- }
- src_pixel += src.get_size().x - src_rect.size.x;
- dst_pixel += dst.get_size().x - src_rect.size.x;
- }
- }
-
- void Blitters::blit_lower_add(const Surface &src, const Rect &src_rect, Surface &dst, const Point &dst_pos)
- {
- const Color *src_pixel = src.get_pixels() + src_rect.pos.y * src.get_size().x + src_rect.pos.x;
- Color *dst_pixel = dst.get_pixels() + dst_pos.y * dst.get_size().x + dst_pos.x;
- for(unsigned int y = 0;y < src_rect.size.y;y++)
- {
- for(unsigned int x = 0;x < src_rect.size.x;x++)
- {
- if(src_pixel->red != 0 && dst_pixel->red != 0xff)
- {
- int redsum = dst_pixel->red + src_pixel->red * src_pixel->alpha / 0xff;
- dst_pixel->red = redsum & ~0xff ? 0xff : redsum;
- }
- if(src_pixel->green != 0 && dst_pixel->green != 0xff)
- {
- int greensum = dst_pixel->green + src_pixel->green * src_pixel->alpha / 0xff;
- dst_pixel->green = greensum & ~0xff ? 0xff : greensum;
- }
- if(src_pixel->blue != 0 && dst_pixel->blue != 0xff)
- {
- int bluesum = dst_pixel->blue + src_pixel->blue * src_pixel->alpha / 0xff;
- dst_pixel->blue = bluesum & ~0xff ? 0xff : bluesum;
- }
- src_pixel++;
- dst_pixel++;
- }
- src_pixel += src.get_size().x - src_rect.size.x;
- dst_pixel += dst.get_size().x - src_rect.size.x;
- }
- }
-
- void Blitters::blit_lower_mod(const Surface &src, const Rect &src_rect, Surface &dst, const Point &dst_pos)
- {
- const Color *src_pixel = src.get_pixels() + src_rect.pos.y * src.get_size().x + src_rect.pos.x;
- Color *dst_pixel = dst.get_pixels() + dst_pos.y * dst.get_size().x + dst_pos.x;
- for(unsigned int y = 0;y < src_rect.size.y;y++)
- {
- for(unsigned int x = 0;x < src_rect.size.x;x++)
- {
- dst_pixel->red = dst_pixel->red * src_pixel->red / 0xff;
- dst_pixel->green = dst_pixel->green * src_pixel->green / 0xff;
- dst_pixel->blue = dst_pixel->blue * src_pixel->blue / 0xff;
- dst_pixel->alpha = dst_pixel->alpha * src_pixel->alpha / 0xff;
- src_pixel++;
- dst_pixel++;
- }
- src_pixel += src.get_size().x - src_rect.size.x;
- dst_pixel += dst.get_size().x - src_rect.size.x;
- }
- }
- }
-}
+++ /dev/null
-// Copyright Timothy Goya 2007.
-// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at
-// http://www.boost.org/LICENSE_1_0.txt)
-
-#include <unison/video/Color.hpp>
-
-namespace Unison
-{
- namespace Video
- {
- const Color Color::BLACK(0, 0, 0);
- const Color Color::RED(0xff, 0, 0);
- const Color Color::GREEN(0, 0xff, 0);
- const Color Color::BLUE(0, 0, 0xff);
- const Color Color::CYAN(0, 0xff, 0xff);
- const Color Color::MAGENTA(0xff, 0, 0xff);
- const Color Color::YELLOW(0xff, 0xff, 0);
- const Color Color::WHITE(0xff, 0xff, 0xff);
- }
-}
+++ /dev/null
-// Copyright Timothy Goya 2007.
-// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at
-// http://www.boost.org/LICENSE_1_0.txt)
-
-#include <unison/video/Renderers.hpp>
-#include <unison/video/Window.hpp>
-#include <unison/video/Texture.hpp>
-#include "auto/Renderer.hpp"
-#include "sdl/Renderer.hpp"
-#include "opengl/Renderer.hpp"
-
-#include <assert.h>
-
-namespace Unison
-{
- namespace Video
- {
- Renderers::Renderers() :
- auto_renderer(0),
- renderer(0),
- renderers()
- {
- auto_renderer = new Auto::Renderer(renderers);
- renderer = auto_renderer;
- add_renderer(new SDL::Renderer());
- add_renderer(new OpenGL::Renderer());
- renderer->init();
- }
-
- Renderers::~Renderers()
- {
- assert(renderer);
- renderer->quit();
- std::for_each(renderers.begin(), renderers.end(), std::ptr_fun(operator delete));
- delete auto_renderer;
- }
-
- Renderers &Renderers::get()
- {
- static Renderers renderers;
- return renderers;
- }
-
- namespace
- {
- bool match_name(Backend::Renderer *renderer, std::string name)
- {
- return renderer && renderer->get_name() == name;
- }
- }
-
- void Renderers::set_renderer(const std::string &name)
- {
- Area window_size;
- bool fullscreen = false;
- if(Window::get().is_open())
- {
- window_size = Window::get().get_size();
- fullscreen = Window::get().is_fullscreen();
- }
- std::vector<Surface> surfaces = Texture::save_textures();
- renderer->quit();
- if(name == "auto")
- {
- renderer = auto_renderer;
- }
- else
- {
- std::vector<Backend::Renderer *>::iterator found = std::find_if(renderers.begin(), renderers.end(), std::bind2nd(std::ptr_fun(match_name), name));
- if(found == renderers.end())
- {
- fprintf(stderr, "Renderer '%s' not found.\n", name.c_str());
- return;
- }
- renderer = *found;
- }
- renderer->init();
- Texture::load_textures(surfaces);
- if(window_size != Area())
- {
- Window::get().open(window_size, fullscreen);
- }
- }
-
-
- Backend::Renderer &Renderers::get_renderer()
- {
- assert(renderer);
- return *renderer;
- }
-
- void Renderers::add_renderer(Backend::Renderer *renderer)
- {
- renderers.push_back(renderer);
- }
- }
-}
+++ /dev/null
-// Copyright Timothy Goya 2007.
-// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at
-// http://www.boost.org/LICENSE_1_0.txt)
-
-#include <unison/video/Texture.hpp>
-#include <unison/video/Window.hpp>
-#include <unison/video/Renderers.hpp>
-#include <unison/video/Color.hpp>
-#include <unison/video/sdl/Blitters.hpp>
-#include <unison/video/backend/Renderer.hpp>
-#include <unison/video/backend/Texture.hpp>
-#include <unison/vfs/stream.hpp>
-
-#include <assert.h>
-
-namespace Unison
-{
- namespace Video
- {
- Surface::Surface() :
- pixels(0)
- {
- }
-
- Surface::Surface(const std::string &filename) :
- pixels(0)
- {
- *this = Renderers::get().get_renderer().load_surface(filename);
- }
-
- Surface::Surface(const std::string &filename, const Color &colorkey) :
- pixels(0)
- {
- *this = Renderers::get().get_renderer().load_surface(filename, colorkey);
- }
-
- Surface::Surface(const Area &size) :
- pixels(new PixelBuffer(size))
- {
- //fill(Color::WHITE);
- }
-
- Surface::Surface(const Surface &rhs) :
- Blittable(),
- pixels(rhs.pixels)
- {
- if(pixels)
- {
- pixels->ref();
- }
- }
-
- Surface::~Surface()
- {
- if(pixels)
- {
- pixels->unref();
- }
- }
-
- Surface &Surface::operator =(const Surface &rhs)
- {
- if(rhs.pixels)
- {
- rhs.pixels->ref();
- }
- if(pixels)
- {
- pixels->unref();
- }
- pixels = rhs.pixels;
- return *this;
- }
-
- void Surface::save(const std::string &filename) const
- {
- Renderers::get().get_renderer().save_surface(*this, filename);
- }
-
- void Surface::blit(const Surface &src, const Point &dst_pos, const Rect &src_rect, const RenderOptions &options)
- {
- cow();
- assert(pixels);
- Renderers::get().get_renderer().blit(src, src_rect, *this, dst_pos, options);
- }
-
- void Surface::blit(const Texture &src, const Point &dst_pos, const Rect &src_rect, const RenderOptions &options)
- {
- cow();
- assert(pixels);
- Renderers::get().get_renderer().blit(Backend::Texture::get_texture(src.get_id()), src_rect, *this, dst_pos, options);
- }
-
- void Surface::fill(const Color &color, const Rect &rect)
- {
- cow();
- assert(pixels);
- Renderers::get().get_renderer().fill(*this, color, rect);
- }
-
- void Surface::fill_blend(const Color &color, const Rect &rect)
- {
- cow();
- assert(pixels);
- Renderers::get().get_renderer().fill_blend(*this, color, rect);
- }
-
- namespace
- {
- Color merge(const Color &color0, const Color &color1, int rem, int total)
- {
- return Color((color0.red * (total - rem) + color1.red * rem) / total,
- (color0.green * (total - rem) + color1.green * rem) / total,
- (color0.blue * (total - rem) + color1.blue * rem) / total,
- (color0.alpha * (total - rem) + color1.alpha * rem) / total);
- }
- }
-
- Surface Surface::scale(unsigned int numerator, unsigned int denominator) const
- {
- assert(pixels);
- if(numerator == denominator)
- {
- return *this;
- }
- else
- {
- Surface scaled(get_size() * numerator / denominator);
- for(unsigned int y = 0;y < scaled.get_size().y;y++)
- {
- for(unsigned int x = 0;x < scaled.get_size().x;x++)
- {
- unsigned int srcx = x * denominator / numerator;
- unsigned int srcy = y * denominator / numerator;
- //scaled.set_pixel(Point(x, y), get_pixel(Point(srcx, srcy)));
- int incx = (srcx + 1 == get_size().x ? 0 : 1);
- int incy = (srcy + 1 == get_size().y ? 0 : 1);
- Color color00 = get_pixel(srcx, srcy);
- Color color01 = get_pixel(srcx + incx, srcy);
- Color color10 = get_pixel(srcx, srcy + incy);
- Color color11 = get_pixel(srcx + incx, srcy + incy);
- int remx = x * denominator % numerator;
- Color color0 = merge(color00, color01, remx, numerator);
- Color color1 = merge(color10, color11, remx, numerator);
- int remy = y * denominator % numerator;
- Color color = merge(color0, color1, remy, numerator);
- scaled.get_pixel(x, y) = color;
- }
- }
- return scaled;
- }
- }
-
- Surface Surface::h_flip() const
- {
- assert(pixels);
- Surface flipped(get_size());
- for(unsigned int y = 0;y < get_size().y;y++)
- {
- for(unsigned int x = 0;x < get_size().x;x++)
- {
- flipped.get_pixel(x, y) = get_pixel(get_size().x - x - 1, y);
- }
- }
- return flipped;
- }
-
- Surface Surface::v_flip() const
- {
- assert(pixels);
- Surface flipped(get_size());
- for(unsigned int y = 0;y < get_size().y;y++)
- {
- for(unsigned int x = 0;x < get_size().x;x++)
- {
- flipped.get_pixel(x, y) = get_pixel(x, get_size().y - y - 1);
- }
- }
- return flipped;
- }
-
- Surface Surface::modulate(const Color &color) const
- {
- assert(pixels);
- if(color == Color::WHITE)
- {
- return *this;
- }
- else
- {
- Surface modulated(get_size());
- for(unsigned int y = 0;y < get_size().y;y++)
- {
- for(unsigned int x = 0;x < get_size().x;x++)
- {
- Color pixel = get_pixel(x, y);
- pixel.red = pixel.red * color.red / 0xff;
- pixel.green = pixel.green * color.green / 0xff;
- pixel.blue = pixel.blue * color.blue / 0xff;
- pixel.alpha = pixel.alpha * color.alpha / 0xff;
- modulated.get_pixel(x, y) = pixel;
- }
- }
- return modulated;
- }
- }
-
- Surface Surface::modulate(unsigned char alpha) const
- {
- assert(pixels);
- if(alpha == 0xff)
- {
- return *this;
- }
- else
- {
- Surface modulated(get_size());
- for(unsigned int y = 0;y < get_size().y;y++)
- {
- for(unsigned int x = 0;x < get_size().x;x++)
- {
- Color pixel = get_pixel(x, y);
- pixel.alpha = pixel.alpha * alpha / 0xff;
- modulated.get_pixel(x, y) = pixel;
- }
- }
- return modulated;
- }
- }
-
- void Surface::cow()
- {
- if(pixels && pixels->refcount > 1)
- {
- PixelBuffer *original = pixels;
- pixels = new PixelBuffer(pixels->size);
- memcpy(pixels->buffer, original->buffer, pixels->size.x * pixels->size.y * sizeof(Color));
- }
- }
- }
-}
+++ /dev/null
-// Copyright Timothy Goya 2007.
-// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at
-// http://www.boost.org/LICENSE_1_0.txt)
-
-#include <unison/video/Texture.hpp>
-#include <unison/video/backend/Texture.hpp>
-
-#include <assert.h>
-
-namespace Unison
-{
- namespace Video
- {
- std::set<Texture *> Texture::textures = std::set<Texture*>();
-
- Texture::Texture() :
- id(INVALID_TEXTURE_ID)
- {
- }
-
- Texture::Texture(const std::string &filename) :
- id(Backend::Texture::get_texture_id(filename))
- {
- assert(id != INVALID_TEXTURE_ID);
- Backend::Texture::get_texture(id)->ref();
- textures.insert(this);
- }
-
- Texture::Texture(const std::string &filename, const Color &colorkey) :
- id(Backend::Texture::get_texture_id(filename, colorkey))
- {
- assert(id != INVALID_TEXTURE_ID);
- Backend::Texture::get_texture(id)->ref();
- textures.insert(this);
- }
-
- Texture::Texture(const Surface &surface) :
- id(Backend::Texture::get_texture_id(surface))
- {
- assert(id != INVALID_TEXTURE_ID);
- Backend::Texture::get_texture(id)->ref();
- textures.insert(this);
- }
-
- Texture::Texture(const Texture &rhs) :
- Blittable(),
- id(rhs.id)
- {
- if(id != INVALID_TEXTURE_ID)
- {
- Backend::Texture::get_texture(id)->ref();
- }
- textures.insert(this);
- }
-
- Texture::~Texture()
- {
- textures.erase(this);
- if(id != INVALID_TEXTURE_ID)
- {
- Backend::Texture::get_texture(id)->unref();
- }
- }
-
- Texture &Texture::operator =(const Texture &rhs)
- {
- if(rhs.id != INVALID_TEXTURE_ID)
- {
- Backend::Texture::get_texture(rhs.id)->ref();
- }
- if(id != INVALID_TEXTURE_ID)
- {
- Backend::Texture::get_texture(id)->unref();
- }
- id = rhs.id;
- return *this;
- }
-
- TextureID Texture::get_id() const
- {
- return id;
- }
-
- Area Texture::get_size() const
- {
- assert(id != INVALID_TEXTURE_ID);
- return Backend::Texture::get_texture(id)->get_size();
- }
-
- void Texture::blit(const Surface &src, const Point &dst_pos, const Rect &src_rect, const RenderOptions &options)
- {
- assert(id != INVALID_TEXTURE_ID);
- cow();
- Backend::Texture::get_texture(id)->blit(src, dst_pos, src_rect, options);
- }
-
- void Texture::blit(const Texture &src, const Point &dst_pos, const Rect &src_rect, const RenderOptions &options)
- {
- assert(id != INVALID_TEXTURE_ID);
- cow();
- Backend::Texture::get_texture(id)->blit(src, dst_pos, src_rect, options);
- }
-
- void Texture::fill(const Color &color, const Rect &rect)
- {
- assert(id != INVALID_TEXTURE_ID);
- cow();
- Backend::Texture::get_texture(id)->fill(color, rect);
- }
-
- void Texture::fill_blend(const Color &color, const Rect &rect)
- {
- assert(id != INVALID_TEXTURE_ID);
- cow();
- Backend::Texture::get_texture(id)->fill_blend(color, rect);
- }
-
- std::vector<Surface> Texture::save_textures()
- {
- recover_texture_ids();
- return Backend::Texture::save_textures();
- }
-
- namespace
- {
- void ref(Texture *texture)
- {
- assert(texture);
- TextureID id = texture->get_id();
- if(id != INVALID_TEXTURE_ID)
- {
- Backend::Texture::get_texture(id)->ref();
- }
- }
- }
-
- void Texture::load_textures(const std::vector<Surface> &surfaces)
- {
- Backend::Texture::load_textures(surfaces);
- std::for_each(textures.begin(), textures.end(), ref);
- }
-
- void Texture::recover_texture_ids()
- {
- std::map<TextureID, TextureID> change_map = Backend::Texture::recover_texture_ids();
- if(!change_map.empty())
- {
- for(std::set<Texture *>::iterator iter = textures.begin(), end = textures.end();iter != end;++iter)
- {
- if(change_map.find((*iter)->id) != change_map.end())
- {
- (*iter)->id = change_map[(*iter)->id];
- }
- }
- }
- }
-
- void Texture::cow()
- {
- assert(id != INVALID_TEXTURE_ID);
- if(Backend::Texture::get_texture(id)->get_refcount() > 1)
- {
- TextureID old = id;
- id = Backend::Texture::get_texture_id(Backend::Texture::get_texture(id)->get_surface());
- assert(id != INVALID_TEXTURE_ID);
- Backend::Texture::get_texture(id)->ref();
- Backend::Texture::get_texture(old)->unref();
- }
- }
- }
-}
+++ /dev/null
-// Copyright Timothy Goya 2007.
-// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at
-// http://www.boost.org/LICENSE_1_0.txt)
-
-#include <unison/video/Window.hpp>
-#include <unison/video/Surface.hpp>
-#include <unison/video/Texture.hpp>
-#include <unison/video/Renderers.hpp>
-#include <unison/video/backend/Renderer.hpp>
-#include <unison/video/backend/Window.hpp>
-
-#include <assert.h>
-
-namespace Unison
-{
- namespace Video
- {
- Window::Window() :
- logical_size(),
- title(),
- icon(Surface(Area(1, 1))),
- window(0),
- list(),
- layers()
- {
- }
-
- Window::~Window()
- {
- }
-
- Window &Window::get()
- {
- // FIXME: fix init order more naturally
- Renderers::get();
- static Window window;
- return window;
- }
-
- void Window::set_logical_size(const Area &logical_size)
- {
- this->logical_size = logical_size;
- if(window)
- {
- std::vector<Surface> surfaces = Texture::save_textures();
- open(get_size(), is_fullscreen());
- Texture::load_textures(surfaces);
- }
- }
-
- Area Window::get_logical_size() const
- {
- return logical_size;
- }
-
- void Window::open(const Area &size, bool fullscreen)
- {
- std::vector<Surface> surfaces = Texture::save_textures();
- if(logical_size.x == 0 || logical_size.y == 0)
- {
- logical_size = size;
- }
- delete window;
- window = Renderers::get().get_renderer().create_window(size, logical_size, fullscreen);
- assert(window);
- Texture::load_textures(surfaces);
- window->set_title(title);
- window->set_icon(icon);
- redraw();
- }
-
- void Window::take_screenshot(const std::string &filename) const
- {
- assert(window);
- window->take_screenshot(filename);
- }
-
- void Window::flip()
- {
- list = layers;
- layers.clear();
- redraw();
- }
-
- void Window::redraw()
- {
- assert(window);
- fill(Color::BLACK);
- window->draw(list);
- window->flip();
- }
-
- void Window::set_title(const std::string &title)
- {
- this->title = title;
- if(window)
- {
- window->set_title(title);
- }
- }
-
- void Window::set_icon(const Surface &icon)
- {
- this->icon = icon.get_size() == Area() ? Surface(Area(1, 1)) : icon;
- if(window)
- {
- window->set_icon(icon);
- }
- }
-
- Area Window::get_size() const
- {
- assert(window);
- return window->get_size();
- }
-
- bool Window::is_fullscreen() const
- {
- assert(window);
- return window->is_fullscreen();
- }
-
- bool Window::is_open() const
- {
- return window;
- }
- }
-}
+++ /dev/null
-// Copyright Timothy Goya 2007.
-// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at
-// http://www.boost.org/LICENSE_1_0.txt)
-
-#include "Renderer.hpp"
-#include <unison/video/Surface.hpp>
-#include <unison/video/Window.hpp>
-
-#include <assert.h>
-
-namespace Unison
-{
- namespace Video
- {
- namespace Auto
- {
- Renderer::Renderer(const std::vector<Backend::Renderer *> &renderers) :
- renderer(0),
- renderers(renderers)
- {
- }
-
- Renderer::~Renderer()
- {
- }
-
- void Renderer::init()
- {
- assert(!renderer);
- std::vector<Backend::Renderer *>::const_reverse_iterator found = std::find_if(renderers.rbegin(), renderers.rend(), std::mem_fun(&Unison::Video::Backend::Renderer::is_usable));
- if(found == renderers.rend())
- {
- fputs("No usable renderers found\n", stderr);
- return;
- }
- renderer = *found;
- renderer->init();
- }
-
- void Renderer::quit()
- {
- assert(renderer);
- renderer->quit();
- renderer = 0;
- }
-
- std::string Renderer::get_name()
- {
- return "auto";
- }
-
- bool Renderer::is_usable()
- {
- return std::find_if(renderers.begin(), renderers.end(), std::mem_fun(&Unison::Video::Backend::Renderer::is_usable)) != renderers.end();
- }
-
- Surface Renderer::load_surface(const std::string &filename)
- {
- assert(renderer);
- return renderer->load_surface(filename);
- }
-
- Surface Renderer::load_surface(const std::string &filename, const Color &colorkey)
- {
- assert(renderer);
- return renderer->load_surface(filename, colorkey);
- }
-
- void Renderer::save_surface(const Surface &surface, const std::string &filename)
- {
- assert(renderer);
- return renderer->save_surface(surface, filename);
- }
-
- void Renderer::blit(const Surface &src, const Rect &src_rect, Surface &dst, const Point &dst_pos, const RenderOptions &options)
- {
- assert(renderer);
- renderer->blit(src, src_rect, dst, dst_pos, options);
- }
-
- void Renderer::blit(Backend::Texture *src, const Rect &src_rect, Surface &dst, const Point &dst_pos, const RenderOptions &options)
- {
- assert(renderer);
- renderer->blit(src, src_rect, dst, dst_pos, options);
- }
-
- void Renderer::fill(Surface &dst, const Color &color, const Rect &rect)
- {
- assert(renderer);
- renderer->fill(dst, color, rect);
- }
-
- void Renderer::fill_blend(Surface &dst, const Color &color, const Rect &rect)
- {
- assert(renderer);
- renderer->fill_blend(dst, color, rect);
- }
-
- Backend::Window *Renderer::create_window(const Area &size, const Area &logical_size, bool fullscreen)
- {
- assert(renderer);
- return renderer->create_window(size, logical_size, fullscreen);
- }
-
- Backend::Texture *Renderer::create_texture(const Surface &surface)
- {
- assert(renderer);
- return renderer->create_texture(surface);
- }
- }
- }
-}
+++ /dev/null
-// Copyright Timothy Goya 2007.
-// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at
-// http://www.boost.org/LICENSE_1_0.txt)
-
-#ifndef UNISON_VIDEO_AUTO_RENDERER_HPP
-#define UNISON_VIDEO_AUTO_RENDERER_HPP
-
-#include <unison/video/backend/Renderer.hpp>
-
-#include <string>
-#include <vector>
-
-namespace Unison
-{
- namespace Video
- {
- namespace Backend
- {
- class Texture;
- class Window;
- }
- namespace Auto
- {
- /// Does rendering tasks like blits and color fills using SDL
- class Renderer : public Backend::Renderer
- {
- public:
- Renderer(const std::vector<Backend::Renderer *> &renderers);
- ~Renderer();
-
- void init();
- void quit();
-
- std::string get_name();
- bool is_usable();
-
- Surface load_surface(const std::string &filename);
- Surface load_surface(const std::string &filename, const Color &colorkey);
- void save_surface(const Surface &surface, const std::string &filename);
-
- void blit(const Surface &src, const Rect &src_rect, Surface &dst, const Point &dst_pos, const RenderOptions &options);
- void blit(Backend::Texture *src, const Rect &src_rect, Surface &dst, const Point &dst_pos, const RenderOptions &options);
- void fill(Surface &dst, const Color &color, const Rect &rect);
- void fill_blend(Surface &dst, const Color &color, const Rect &rect);
-
- Backend::Window *create_window(const Area &size, const Area &logical_size, bool fullscreen);
- Backend::Texture *create_texture(const Surface &surface);
- private:
- Backend::Renderer *renderer;
- const std::vector<Backend::Renderer *> &renderers;
- };
- }
- }
-}
-
-#endif
+++ /dev/null
-// Copyright Timothy Goya 2007.
-// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at
-// http://www.boost.org/LICENSE_1_0.txt)
-
-#include <unison/video/backend/Texture.hpp>
-#include <unison/video/Renderers.hpp>
-#include <unison/video/backend/Renderer.hpp>
-
-#include <assert.h>
-#include <algorithm>
-
-namespace Unison
-{
- namespace Video
- {
- namespace Backend
- {
- std::vector<Texture *> Texture::textures = std::vector<Texture *>();
- std::map<std::string, TextureID> Texture::named_textures = std::map<std::string, TextureID>();
-
- Texture::Texture(const Surface &surface) :
- surface(surface),
- size(surface.get_size()),
- refcount(0)
- {
- assert(surface.get_size() != Area());
- }
-
- Texture::~Texture()
- {
- }
-
- Area Texture::get_size()
- {
- return size;
- }
-
- void Texture::ref()
- {
- refcount++;
- }
-
- void Texture::unref()
- {
- assert(refcount > 0);
- refcount--;
- if(refcount == 0)
- {
- std::string name = get_name(get_texture_id(this));
- *std::find(textures.begin(), textures.end(), this) = 0;
- if(!name.empty())
- {
- named_textures.erase(name);
- }
- delete this;
- }
- }
-
- int Texture::get_refcount()
- {
- return refcount;
- }
-
- namespace
- {
- class TextureSaver
- {
- public:
- void operator () (Texture *texture)
- {
- if(texture)
- {
- texture->save();
- surfaces.push_back(texture->get_surface());
- }
- else
- {
- surfaces.push_back(Surface());
- }
- delete texture;
- }
- std::vector<Surface> surfaces;
- };
-
- class TextureLoader
- {
- public:
- void operator () (Surface surface)
- {
- if(surface.get_size() != Area())
- {
- textures.push_back(Renderers::get().get_renderer().create_texture(surface));
- }
- else
- {
- textures.push_back(0);
- }
- }
- std::vector<Texture *> textures;
- };
- }
-
- std::vector<Surface> Texture::save_textures()
- {
- std::vector<Surface> surfaces = std::for_each(textures.begin(), textures.end(), TextureSaver()).surfaces;
- textures.clear();
- return surfaces;
- }
-
- void Texture::load_textures(const std::vector<Surface> &surfaces)
- {
- assert(textures.empty());
- textures = std::for_each(surfaces.begin(), surfaces.end(), TextureLoader()).textures;
- }
-
- std::map<TextureID, TextureID> Texture::recover_texture_ids()
- {
- std::map<TextureID, TextureID> change_map;
- std::vector<Texture *> new_textures;
- bool null_texture_found = false;
- for(std::vector<Texture *>::iterator iter = textures.begin(), end = textures.end();iter != end;++iter)
- {
- if(*iter)
- {
- new_textures.push_back(*iter);
- if(null_texture_found)
- {
- change_map[iter - textures.begin()] = new_textures.size() -1;
- }
- }
- else
- {
- null_texture_found = true;
- }
- }
- textures = new_textures;
- return change_map;
- }
-
- TextureID Texture::get_texture_id(const std::string &filename)
- {
- if(named_textures.find(filename) != named_textures.end())
- {
- return named_textures[filename];
- }
- textures.push_back(Renderers::get().get_renderer().create_texture(Surface(filename)));
- named_textures[filename] = textures.size() - 1;
- return textures.size() - 1;
- }
-
- TextureID Texture::get_texture_id(const std::string &filename, const Color&colorkey)
- {
- if(named_textures.find(filename) != named_textures.end())
- {
- return named_textures[filename];
- }
- textures.push_back(Renderers::get().get_renderer().create_texture(Surface(filename, colorkey)));
- named_textures[filename] = textures.size() - 1;
- return textures.size() - 1;
- }
-
- TextureID Texture::get_texture_id(const Surface &surface)
- {
- textures.push_back(Renderers::get().get_renderer().create_texture(surface));
- return textures.size() - 1;
- }
-
- TextureID Texture::get_texture_id(Texture *texture)
- {
- std::vector<Texture *>::iterator found = std::find(textures.begin(), textures.end(), texture);
- if(found != textures.end())
- {
- return found - textures.begin();
- }
- return INVALID_TEXTURE_ID;
- }
-
- Texture *Texture::get_texture(TextureID id)
- {
- assert(id < textures.size());
- assert(textures[id]);
- return textures[id];
- }
-
- namespace
- {
- bool match_id(std::pair<std::string, TextureID> pair, TextureID id)
- {
- return pair.second == id;
- }
- }
-
- std::string Texture::get_name(TextureID id)
- {
- if(id == INVALID_TEXTURE_ID)
- {
- return std::string();
- }
- std::map<std::string, TextureID>::iterator found = std::find_if(named_textures.begin(), named_textures.end(), std::bind2nd(std::ptr_fun(match_id), id));
- if(found == named_textures.end())
- {
- return std::string();
- }
- return found->first;
- }
- }
- }
-}
+++ /dev/null
-// Copyright Timothy Goya 2007.
-// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at
-// http://www.boost.org/LICENSE_1_0.txt)
-
-#include "Renderer.hpp"
-#include "Texture.hpp"
-#include "Window.hpp"
-#include <unison/video/Surface.hpp>
-#include <unison/video/Window.hpp>
-#include <unison/video/sdl/Blitters.hpp>
-#include <unison/video/backend/Texture.hpp>
-#include <unison/vfs/sdl/Utils.hpp>
-
-#include <assert.h>
-
-#include "SDL.h"
-#include "SDL_image.h"
-
-namespace Unison
-{
- namespace Video
- {
- namespace OpenGL
- {
- Renderer::Renderer()
- {
- }
-
- Renderer::~Renderer()
- {
- }
-
- void Renderer::init()
- {
- SDL_InitSubSystem(SDL_INIT_VIDEO);
-
- glLoad(0);
- }
-
- void Renderer::quit()
- {
- SDL_QuitSubSystem(SDL_INIT_VIDEO);
- }
-
- std::string Renderer::get_name()
- {
- return "opengl";
- }
-
- bool Renderer::is_usable()
- {
- SDL_InitSubSystem(SDL_INIT_VIDEO);
-
- if(SDL_GL_LoadLibrary(0))
- {
- SDL_QuitSubSystem(SDL_INIT_VIDEO);
- return false;
- }
-
- if(!SDL_ListModes(0, SDL_OPENGL))
- {
- SDL_QuitSubSystem(SDL_INIT_VIDEO);
- return false;
- }
-
- /*const SDL_VideoInfo *info = SDL_GetVideoInfo();
- if(SDL_VideoModeOK(info->current_w, info->current_h, 0, SDL_OPENGL | SDL_FULLSCREEN))
- {
- SDL_QuitSubSystem(SDL_INIT_VIDEO);
- return false;
- }*/
-
- SDL_QuitSubSystem(SDL_INIT_VIDEO);
-
- return true;
- }
-
- Surface Renderer::load_surface(const std::string &filename)
- {
- SDL_Surface *image = IMG_Load_RW(VFS::SDL::Utils::open_physfs_in(filename), 1);
- assert(image);
- Surface surface = Surface(Area(image->w, image->h));
- SDL_Surface *sdl_surface = SDL::Blitters::create_sdl_surface_from(surface);
- assert(sdl_surface);
- SDL::Blitters::blit_blend_none(image, Rect(), sdl_surface, Point());
- SDL_FreeSurface(sdl_surface);
- return surface;
- }
-
- Surface Renderer::load_surface(const std::string &filename, const Color &colorkey)
- {
- SDL_Surface *image = IMG_Load_RW(VFS::SDL::Utils::open_physfs_in(filename), 1);
- assert(image);
- Surface surface = Surface(Area(image->w, image->h));
- SDL_Surface *sdl_surface = SDL::Blitters::create_sdl_surface_from(surface);
- assert(sdl_surface);
- SDL_SetColorKey(image, SDL_SRCCOLORKEY, SDL_MapRGB(image->format, colorkey.red, colorkey.blue, colorkey.alpha));
- SDL::Blitters::blit_blend_none(image, Rect(), sdl_surface, Point());
- SDL_FreeSurface(sdl_surface);
- return surface;
- }
-
- void Renderer::save_surface(const Surface &surface, const std::string &filename)
- {
- SDL_Surface *sdl_surface = SDL::Blitters::create_sdl_surface_from(surface);
- assert(sdl_surface);
- SDL_SaveBMP(sdl_surface, filename.c_str());
- SDL_FreeSurface(sdl_surface);
- }
-
- void Renderer::blit(const Surface &src, const Rect &src_rect, Surface &dst, const Point &dst_pos, const RenderOptions &options)
- {
- Surface fragment;
- if(src_rect.pos == Point() && (src_rect.size == Area() || src_rect.size == src.get_size()))
- {
- fragment = src;
- }
- else
- {
- fragment = Surface(src_rect.size);
- Blitters::blit_blend_none(src, src_rect, fragment, Point());
- }
- if(options.h_flip)
- {
- fragment = fragment.h_flip();
- }
- if(options.v_flip)
- {
- fragment = fragment.v_flip();
- }
- SDL_Surface *src_surface = SDL::Blitters::create_sdl_surface_from(fragment.modulate(options.color).modulate(options.alpha));
- assert(src_surface);
-
- SDL_Surface *dst_surface = SDL::Blitters::create_sdl_surface_from(dst);
- assert(dst_surface);
-
-
- SDL::Blitters::blit_blend(src_surface, Rect(Point(), fragment.get_size()), dst_surface, dst_pos, options.blend);
-
- SDL_FreeSurface(dst_surface);
- SDL_FreeSurface(src_surface);
- }
-
- void Renderer::blit(Backend::Texture *src, const Rect &src_rect, Surface &dst, const Point &dst_pos, const RenderOptions &options)
- {
- assert(src);
- assert(dst.get_size() != Area());
-
- blit(src->get_surface(), src_rect, dst, dst_pos, options);
- }
-
- void Renderer::fill(Surface &dst, const Color &color, const Rect &rect)
- {
- SDL_Surface *dst_surface = SDL::Blitters::create_sdl_surface_from(dst);
- assert(dst_surface);
-
- Uint32 mapped = SDL_MapRGBA(dst_surface->format, color.red, color.green, color.blue, color.alpha);
- SDL_FillRect(dst_surface, &rect, mapped);
- }
-
- void Renderer::fill_blend(Surface &dst, const Color &color, const Rect &rect)
- {
- SDL_Surface *dst_surface = SDL::Blitters::create_sdl_surface_from(dst);
- assert(dst_surface);
-
- Uint32 mapped = SDL_MapRGBA(dst_surface->format, color.red, color.green, color.blue, color.alpha);
- if(color.alpha == 0xff)
- {
- SDL_FillRect(dst_surface, &rect, mapped);
- }
- else if(color.alpha != 0x00)
- {
- SDL_Surface *temp = SDL_CreateRGBSurface(dst_surface->flags, rect.size.x, rect.size.y, dst_surface->format->BitsPerPixel, dst_surface->format->Rmask, dst_surface->format->Gmask, dst_surface->format->Bmask, dst_surface->format->Amask);
-
- SDL_FillRect(temp, 0, mapped);
- SDL_SetAlpha(temp, SDL_SRCALPHA | SDL_RLEACCEL, color.alpha);
- SDL_BlitSurface(temp, 0, dst_surface, &rect);
- SDL_FreeSurface(temp);
- }
- }
-
- Backend::Window *Renderer::create_window(const Area &size, const Area &logical_size, bool fullscreen)
- {
- return new Window(size, logical_size, fullscreen);
- }
-
- Backend::Texture *Renderer::create_texture(const Surface &surface)
- {
- return new Texture(surface);
- }
- }
- }
-}
+++ /dev/null
-// Copyright Timothy Goya 2007.
-// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at
-// http://www.boost.org/LICENSE_1_0.txt)
-
-#ifndef UNISON_VIDEO_OPENGL_RENDERER_HPP
-#define UNISON_VIDEO_OPENGL_RENDERER_HPP
-
-#include <unison/video/backend/Renderer.hpp>
-
-#include <string>
-
-#include "SDL.h"
-
-namespace Unison
-{
- namespace Video
- {
- namespace Backend
- {
- class Texture;
- class Window;
- }
- namespace OpenGL
- {
- /// Does rendering tasks like blits and color fills using OpenGL
- class Renderer : public Backend::Renderer
- {
- public:
- /// Default constructor
- Renderer();
-
- /// Destructor
- ~Renderer();
-
- /// Initialize the backend
- void init();
-
- /// Cleanup the backend
- void quit();
-
- /// Get the name of the renderer
- /// \return the name of the renderer
- std::string get_name();
-
- /// Check if the backend is usable
- /// \return Whether the backend is usable
- bool is_usable();
-
- Surface load_surface(const std::string &filename);
- Surface load_surface(const std::string &filename, const Color &colorkey);
- void save_surface(const Surface &surface, const std::string &filename);
-
- /// Does a surface-to-surface blit
- /// \param[in] src The source surface
- /// \param[in] src_rect The part of the source surface to blit from
- /// \param[in] dst The destination surface
- /// \param[in] dst_pos The position to blit to
- /// \param[in] options Extra blit options
- void blit(const Surface &src, const Rect &src_rect, Surface &dst, const Point &dst_pos, const RenderOptions &options);
-
- /// Does a texture-to-surface blit
- /// \param[in] src The source texture
- /// \param[in] src_rect The part of the source texture to blit from
- /// \param[in] dst The destination surface
- /// \param[in] dst_pos The position to blit to
- /// \param[in] options Extra blit options
- void blit(Backend::Texture *src, const Rect &src_rect, Surface &dst, const Point &dst_pos, const RenderOptions &options);
-
- /// Fills a portion of a surface with the given color
- /// \param[in] dst The destination surface
- /// \param[in] color The color
- /// \param[in] rect The portion to fill
- void fill(Surface &dst, const Color &color, const Rect &rect);
-
- /// Fills with alpha blend a portion of a surface with the given color
- /// \param[in] dst The destination surface
- /// \param[in] color The color
- /// \param[in] rect The portion to fill
- void fill_blend(Surface &dst, const Color &color, const Rect &rect);
-
- /// Create a window
- /// \param[in] size The size of the window
- /// \param[in] logical_size The logical size of the window
- /// \param[in] fullscreen Whether to open in fullscreen mode
- /// \return The created window
- Backend::Window *create_window(const Area &size, const Area &logical_size, bool fullscreen);
-
- /// Create a texture for the given surface
- /// \param[in] surface The surface to convert
- /// \return The texture for the surface
- Backend::Texture *create_texture(const Surface &surface);
- };
- }
- }
-}
-
-#endif
+++ /dev/null
-// Copyright Timothy Goya 2007.
-// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at
-// http://www.boost.org/LICENSE_1_0.txt)
-
-#include "SDL.h"
-#include "SDL_gl.h"
-
-#define GL_PROC(ret, func, params) ret (*func) params;
-#include "SDL_glfuncs.h"
-#undef GL_PROC
-
-int glLoad(const char *path)
-{
- int ret = SDL_GL_LoadLibrary(path);
- if(ret)
- {
- return ret;
- }
-#define GL_PROC(ret, func, params) func = SDL_GL_GetProcAddress(#func);
-#include "SDL_glfuncs.h"
-#undef GL_PROC
- return 0;
-}
+++ /dev/null
-// Copyright Timothy Goya 2007.
-// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at
-// http://www.boost.org/LICENSE_1_0.txt)
-
-#ifndef _SDL_GL_H
-#define _SDL_GL_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef unsigned int GLenum;
-typedef unsigned char GLboolean;
-typedef unsigned int GLbitfield;
-typedef void GLvoid;
-typedef signed char GLbyte;
-typedef short GLshort;
-typedef int GLint;
-typedef unsigned char GLubyte;
-typedef unsigned short GLushort;
-typedef unsigned int GLuint;
-typedef int GLsizei;
-typedef float GLfloat;
-typedef float GLclampf;
-typedef double GLdouble;
-typedef double GLclampd;
-
-#define GL_UNSIGNED_BYTE 0x1401
-#define GL_QUADS 0x0007
-#define GL_MODELVIEW 0x1700
-#define GL_PROJECTION 0x1701
-#define GL_FRONT 0x0404
-#define GL_BACK 0x0405
-#define GL_DEPTH_TEST 0x0B71
-#define GL_CULL_FACE 0x0B44
-#define GL_BLEND 0x0BE2
-#define GL_ZERO 0x0
-#define GL_ONE 0x1
-#define GL_SRC_COLOR 0x0300
-#define GL_SRC_ALPHA 0x0302
-#define GL_ONE_MINUS_SRC_ALPHA 0x0303
-#define GL_DST_COLOR 0x0306
-#define GL_RGB 0x1907
-#define GL_RGBA 0x1908
-#define GL_MAX_TEXTURE_SIZE 0x0D33
-#define GL_UNPACK_ALIGNMENT 0x0CF5
-#define GL_TEXTURE_2D 0x0DE1
-#define GL_TEXTURE_WRAP_S 0x2802
-#define GL_TEXTURE_WRAP_T 0x2803
-#define GL_TEXTURE_MAG_FILTER 0x2800
-#define GL_TEXTURE_MIN_FILTER 0x2801
-#define GL_CLAMP 0x2900
-#define GL_LINEAR 0x2601
-#define GL_COLOR_BUFFER_BIT 0x00004000
-
-#define GL_PROC(ret, func, params) extern ret (*func) params;
-#include "SDL_glfuncs.h"
-#undef GL_PROC
-
-int glLoad(const char *path);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
+++ /dev/null
-// Copyright Timothy Goya 2007.
-// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at
-// http://www.boost.org/LICENSE_1_0.txt)
-
-GL_PROC(void, glClearColor, (GLclampf, GLclampf, GLclampf, GLclampf))
-GL_PROC(void, glClear, (GLbitfield))
-GL_PROC(void, glBlendFunc, (GLenum, GLenum))
-GL_PROC(void, glDrawBuffer, (GLenum))
-GL_PROC(void, glReadBuffer, (GLenum))
-GL_PROC(void, glEnable, (GLenum))
-GL_PROC(void, glDisable, (GLenum))
-GL_PROC(void, glGetIntegerv, (GLenum, GLint *))
-GL_PROC(GLenum, glGetError, (void))
-GL_PROC(const GLubyte *, glGetString, (GLenum))
-GL_PROC(void, glMatrixMode, (GLenum))
-GL_PROC(void, glOrtho, (GLdouble, GLdouble, GLdouble, GLdouble, GLdouble, GLdouble))
-GL_PROC(void, glViewport, (GLint, GLint, GLsizei, GLsizei))
-GL_PROC(void, glPushMatrix, (void))
-GL_PROC(void, glPopMatrix, (void))
-GL_PROC(void, glLoadIdentity, (void))
-GL_PROC(void, glRotatef, (GLfloat, GLfloat, GLfloat))
-GL_PROC(void, glScalef, (GLfloat, GLfloat, GLfloat))
-GL_PROC(void, glTranslatef, (GLfloat, GLfloat, GLfloat))
-GL_PROC(void, glBegin, (GLenum))
-GL_PROC(void, glEnd, (void))
-GL_PROC(void, glVertex2i, (GLint, GLint))
-GL_PROC(void, glColor4ub, (GLubyte, GLubyte, GLubyte, GLubyte))
-GL_PROC(void, glReadPixels, (GLint, GLint, GLsizei, GLsizei, GLenum, GLenum, GLvoid *))
-GL_PROC(void, glTexCoord2f, (GLfloat, GLfloat))
-GL_PROC(void, glPixelStorei, (GLenum, GLint))
-GL_PROC(void, glTexParameteri, (GLenum, GLenum, GLint))
-GL_PROC(void, glTexImage2D, (GLenum, GLint, GLint, GLsizei, GLsizei, GLint, GLenum, GLenum, const GLvoid *))
-GL_PROC(void, glTexSubImage2D, (GLenum, GLint, GLint, GLint, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *))
-GL_PROC(void, glGetTexImage, (GLenum, GLint, GLenum, GLenum, GLvoid *))
-GL_PROC(void, glGenTextures, (GLsizei, GLuint *))
-GL_PROC(void, glDeleteTextures, (GLsizei, GLuint *))
-GL_PROC(void, glBindTexture, (GLsizei, GLuint))
+++ /dev/null
-// Copyright Timothy Goya 2007.
-// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at
-// http://www.boost.org/LICENSE_1_0.txt)
-
-#include "Texture.hpp"
-#include <unison/video/Surface.hpp>
-#include <unison/video/Window.hpp>
-#include <unison/video/Renderers.hpp>
-#include <unison/video/backend/Renderer.hpp>
-
-#include <assert.h>
-#include <algorithm>
-
-namespace
-{
- int next_power_of_two(int val)
- {
- int result = 1;
- while(result < val)
- result *= 2;
- return result;
- }
-}
-
-namespace Unison
-{
- namespace Video
- {
- namespace OpenGL
- {
- Texture::Texture(const Surface &surface) :
- Backend::Texture(surface),
- handles()
- {
- }
-
- /*Texture::Texture(const Surface &surface, const std::string &name) :
- Backend::Texture(surface, name),
- handles()
- {
- }
-
- Texture::Texture(Backend::Texture *texture) :
- Backend::Texture(texture),
- handles()
- {
- }*/
-
- Texture::~Texture()
- {
- for(std::vector<Handle>::iterator iter = handles.begin(), end = handles.end();iter != end;++iter)
- {
- glDeleteTextures(1, &iter->texture);
- }
- }
-
- const Surface Texture::get_surface()
- {
- if(surface.get_size() == Area())
- {
- assert(!handles.empty());
- surface = Surface(size);
- for(std::vector<Handle>::iterator iter = handles.begin(), end = handles.end();iter != end;++iter)
- {
- Surface section(iter->rect.size);
- glBindTexture(GL_TEXTURE_2D, iter->texture);
- glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, section.get_pixels());
- surface.blit(section, iter->rect.pos, Rect(), BLEND_NONE);
- }
- assert(!glGetError());
- }
- return surface;
- }
-
- void Texture::save()
- {
- get_surface();
- for(std::vector<Handle>::iterator iter = handles.begin(), end = handles.end();iter != end;++iter)
- {
- glDeleteTextures(1, &iter->texture);
- }
- handles.clear();
- }
-
- void Texture::blit(const Surface &src, const Point &dst_pos, const Rect &src_rect, const RenderOptions &options)
- {
- save();
- Renderers::get().get_renderer().blit(src, src_rect, surface, dst_pos, options);
- }
-
- void Texture::blit(const Video::Texture &src, const Point &dst_pos, const Rect &src_rect, const RenderOptions &options)
- {
- save();
- Texture *texture = dynamic_cast<Texture *>(Backend::Texture::get_texture(src.get_id()));
- Renderers::get().get_renderer().blit(texture, src_rect, surface, dst_pos, options);
- }
-
- void Texture::fill(const Color &color, const Rect &rect)
- {
- save();
- Renderers::get().get_renderer().fill(surface, color, rect);
- }
-
- void Texture::fill_blend(const Color &color, const Rect &rect)
- {
- save();
- Renderers::get().get_renderer().fill_blend(surface, color, rect);
- }
-
- void Texture::blit_draw_buffer(const Rect &src_rect, const Point &dst_pos, const RenderOptions &options)
- {
- if(handles.empty())
- {
- assert(surface.get_size() != Area());
- GLint max_size;
- glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max_size);
- for(unsigned int y = 0;y < surface.get_size().y;y += max_size)
- {
- for(unsigned int x = 0;x < surface.get_size().x;x += max_size)
- {
- Rect rect;
- rect.pos.x = x;
- rect.pos.y = y;
- rect.size.x = std::min(surface.get_size().x - x, (unsigned int)max_size);
- rect.size.y = std::min(surface.get_size().y - y, (unsigned int)max_size);
- handles.push_back(create_handle(surface, rect));
- }
- }
- surface = Surface();
- }
-
- glColor4ub(options.color.red, options.color.green, options.color.blue, options.alpha);
- switch(options.blend)
- {
- case BLEND_NONE:
- glDisable(GL_BLEND);
- //glBlendFunc(GL_ONE, GL_ZERO);
- break;
- case BLEND_MASK:
- assert(0 && "Mask blending not implemented");
- return;
- case BLEND_ALPHA:
- glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- break;
- case BLEND_ADD:
- glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE);
- break;
- case BLEND_MOD:
- glEnable(GL_BLEND);
- glBlendFunc(GL_ZERO, GL_SRC_COLOR);
- break;
- default:
- assert(0 && "Unrecognized blend mode");
- return;
- }
-
- glPushMatrix();
-
- glTranslatef(dst_pos.x - src_rect.pos.x, dst_pos.y - src_rect.pos.y, 0);
-
- for(std::vector<Handle>::iterator iter = handles.begin(), end = handles.end();iter != end;++iter)
- {
- Rect overlap = iter->rect.get_overlap(src_rect);
- if(overlap != Rect())
- {
- GLfloat uv_left = GLfloat(overlap.get_left()) / iter->rect.size.x;
- GLfloat uv_top = GLfloat(overlap.get_top()) / iter->rect.size.y;
- GLfloat uv_right = GLfloat(overlap.get_right()) / iter->rect.size.x;
- GLfloat uv_bottom = GLfloat(overlap.get_bottom()) / iter->rect.size.y;
-
- if(options.h_flip)
- {
- std::swap(uv_left, uv_right);
- }
-
- if(options.v_flip)
- {
- std::swap(uv_top, uv_bottom);
- }
-
- glPushMatrix();
-
- glTranslatef(overlap.pos.x, overlap.pos.y, 0);
-
- glBindTexture(GL_TEXTURE_2D, iter->texture);
- glBegin(GL_QUADS);
- glTexCoord2f(uv_left, uv_top);
- glVertex2i(0, 0);
-
- glTexCoord2f(uv_right, uv_top);
- glVertex2i(overlap.size.x, 0);
-
- glTexCoord2f(uv_right, uv_bottom);
- glVertex2i(overlap.size.x, overlap.size.y);
-
- glTexCoord2f(uv_left, uv_bottom);
- glVertex2i(0, overlap.size.y);
- glEnd();
-
- glPopMatrix();
- }
- }
-
- glPopMatrix();
-
- //glColor4ub(0xff, 0xff, 0xff, 0xff);
- //glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- }
-
- Texture::Handle Texture::create_handle(const Surface &surface, const Rect &rect)
- {
- Texture::Handle handle;
- handle.rect = rect;
- handle.rect.size.x = next_power_of_two(rect.size.x);
- handle.rect.size.y = next_power_of_two(rect.size.y);
- Surface convert(handle.rect.size);
- convert.blit(surface, Point(), rect, BLEND_NONE);
-
-
- glGenTextures(1, &handle.texture);
- assert(!glGetError());
- try
- {
- glBindTexture(GL_TEXTURE_2D, handle.texture);
- //glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
-
- //surface.lock();
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
- handle.rect.size.x, handle.rect.size.y,
- 0, GL_RGBA, GL_UNSIGNED_BYTE, convert.get_pixels());
- //surface.unlock();
-
- assert(!glGetError());
-
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
- }
- catch(...)
- {
- glDeleteTextures(1, &handle.texture);
- throw;
- }
- return handle;
- }
- }
- }
-}
+++ /dev/null
-// Copyright Timothy Goya 2007.
-// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at
-// http://www.boost.org/LICENSE_1_0.txt)
-
-#ifndef UNISON_VIDEO_OPENGL_TEXTURE_HPP
-#define UNISON_VIDEO_OPENGL_TEXTURE_HPP
-
-#include <unison/video/backend/Texture.hpp>
-#include <unison/video/Surface.hpp>
-
-#include <string>
-#include <vector>
-
-#include "SDL.h"
-#include "SDL_gl.h"
-
-namespace Unison
-{
- namespace Video
- {
- namespace OpenGL
- {
- class Texture : public Backend::Texture
- {
- public:
- Texture(const Surface &surface);
- //Texture(const Surface &surface, const std::string &name);
- //Texture(Backend::Texture *texture);
- Texture();
- ~Texture();
-
- const Surface get_surface();
- void save();
- void blit(const Surface &src, const Point &dst_pos, const Rect &src_rect, const RenderOptions &options);
- void blit(const Video::Texture &src, const Point &dst_pos, const Rect &src_rect, const RenderOptions &options);
- void fill(const Color &color, const Rect &rect);
- void fill_blend(const Color &color, const Rect &rect);
-
- void blit_draw_buffer(const Rect &src_rect, const Point &dst_pos, const RenderOptions &options);
- private:
- struct Handle
- {
- GLuint texture;
- Rect rect;
- };
- std::vector<Handle> handles;
-
- static Handle create_handle(const Surface &surface, const Rect &rect);
- };
- }
- }
-}
-
-#endif
+++ /dev/null
-// Copyright Timothy Goya 2007.
-// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at
-// http://www.boost.org/LICENSE_1_0.txt)
-
-#include "Window.hpp"
-#include "Texture.hpp"
-#include <unison/video/Window.hpp>
-#include <unison/video/Surface.hpp>
-#include <unison/video/Texture.hpp>
-#include <unison/video/Renderers.hpp>
-#include <unison/video/sdl/Blitters.hpp>
-#include <unison/video/backend/Renderer.hpp>
-#include <unison/video/backend/Texture.hpp>
-
-#include <assert.h>
-
-#include "SDL.h"
-
-namespace Unison
-{
- namespace Video
- {
- namespace OpenGL
- {
- Window::Window(const Area &size, const Area &logical_size, bool fullscreen) :
- logical_size(logical_size),
- window(0)
- {
- assert(size.x);
- assert(size.y);
-
- SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
- //SDL_GL_SetAttribute(SDL_GL_ACCELERATED_VISUAL, 1);
- SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL, 1);
- SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 5);
- SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 5);
- SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 5);
-
- window = SDL_SetVideoMode(size.x, size.y, 0, SDL_OPENGL | (fullscreen ? SDL_FULLSCREEN : 0));
- assert(window);
-
- glDisable(GL_DEPTH_TEST);
- glDisable(GL_CULL_FACE);
- glEnable(GL_TEXTURE_2D);
- //glEnable(GL_BLEND);
-
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- glOrtho(0, logical_size.x, logical_size.y, 0, -1.0, 1.0);
- glMatrixMode(GL_MODELVIEW);
- glViewport(0, 0, size.x, size.y);
- glLoadIdentity();
- //glTranslatef(0, 0, 0);
- //glScalef(GLfloat(size.x) / logical_size.x, GLfloat(size.y) / logical_size.y, 1);
- //glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glClearColor(0, 0, 0, 1);
- glClear(GL_COLOR_BUFFER_BIT);
- assert(!glGetError());
- }
-
- Window::~Window()
- {
- }
-
- void Window::take_screenshot(const std::string &filename) const
- {
- //Surface surface(logical_size);
- Surface surface(get_size());
- glReadBuffer(GL_FRONT);
- glReadPixels(0, 0, get_size().x, get_size().y, GL_RGBA, GL_UNSIGNED_BYTE, surface.get_pixels());
- //glReadPixels(0, 0, logical_size.x, logical_size.y, GL_RGBA, GL_UNSIGNED_BYTE, surface->pixels);
- surface.v_flip().save(filename);
- }
-
- void Window::flip()
- {
- SDL_GL_SwapBuffers();
- }
-
- void Window::set_title(const std::string &title)
- {
- SDL_WM_SetCaption(title.c_str(), title.c_str());
- }
-
- void Window::set_icon(const Surface &icon)
- {
- SDL_Surface *icon_surface = SDL::Blitters::create_sdl_surface_from(icon);
- assert(icon_surface);
- SDL_WM_SetIcon(icon_surface, 0);
- SDL_FreeSurface(icon_surface);
- }
-
- Area Window::get_size() const
- {
- return Area(window->w, window->h);
- }
-
- bool Window::is_fullscreen() const
- {
- return window->flags & SDL_FULLSCREEN;
- }
-
- void Window::blit(const Surface &src, const Point &dst_pos, const Rect &src_rect, const RenderOptions &options)
- {
- Video::Texture texture(src);
- blit(src, dst_pos, src_rect, options);
- }
-
- void Window::blit(const Video::Texture &src, const Point &dst_pos, const Rect &src_rect, const RenderOptions &options)
- {
- Texture *texture = dynamic_cast<Texture *>(Backend::Texture::get_texture(src.get_id()));
- assert(texture);
- assert(window);
-
- texture->blit_draw_buffer(src_rect, dst_pos, options);
- }
-
- void Window::fill(const Color &color, const Rect &rect)
- {
- assert(window);
-
- glDisable(GL_BLEND);
- glDisable(GL_TEXTURE_2D);
- glColor4ub(color.red, color.green, color.blue, color.alpha);
- if(rect == Rect())
- {
- glBegin(GL_QUADS);
- glVertex2i(0, 0);
- glVertex2i(get_size().x, 0);
- glVertex2i(get_size().x, get_size().y);
- glVertex2i(0, get_size().y);
- glEnd();
- }
- else
- {
- glPushMatrix();
-
- glTranslatef(rect.pos.x, rect.pos.y, 0);
-
- glBegin(GL_QUADS);
- glVertex2i(0, 0);
- glVertex2i(rect.size.x, 0);
- glVertex2i(rect.size.x, rect.size.y);
- glVertex2i(0, rect.size.y);
- glEnd();
-
- glPopMatrix();
- }
- glEnable(GL_TEXTURE_2D);
- //glColor4ub(0xff, 0xff, 0xff, 0xff);
- }
-
- void Window::fill_blend(const Color &color, const Rect &rect)
- {
- assert(window);
-
- glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glDisable(GL_TEXTURE_2D);
- glColor4ub(color.red, color.green, color.blue, color.alpha);
- if(rect == Rect())
- {
- glBegin(GL_QUADS);
- glVertex2i(0, 0);
- glVertex2i(get_size().x, 0);
- glVertex2i(get_size().x, get_size().y);
- glVertex2i(0, get_size().y);
- glEnd();
- }
- else
- {
- glPushMatrix();
-
- glTranslatef(rect.pos.x, rect.pos.y, 0);
-
- glBegin(GL_QUADS);
- glVertex2i(0, 0);
- glVertex2i(rect.size.x, 0);
- glVertex2i(rect.size.x, rect.size.y);
- glVertex2i(0, rect.size.y);
- glEnd();
-
- glPopMatrix();
- }
- glEnable(GL_TEXTURE_2D);
- //glColor4ub(0xff, 0xff, 0xff, 0xff);
- }
- }
- }
-}
+++ /dev/null
-// Copyright Timothy Goya 2007.
-// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at
-// http://www.boost.org/LICENSE_1_0.txt)
-
-#ifndef UNISON_VIDEO_OPENGL_WINDOW_HPP
-#define UNISON_VIDEO_OPENGL_WINDOW_HPP
-
-#include <unison/video/backend/Window.hpp>
-#include <unison/video/RenderOptions.hpp>
-
-#include <string>
-
-#include "SDL.h"
-
-namespace Unison
-{
- namespace Video
- {
- namespace Backend
- {
- class Texture;
- }
- namespace OpenGL
- {
- class Window : public Backend::Window
- {
- public:
- Window(const Area &size, const Area &logical_size, bool fullscreen = false);
-
- ~Window();
- void take_screenshot(const std::string &filename) const;
- void flip();
- void set_title(const std::string &title);
- void set_icon(const Surface &icon);
- Area get_size() const;
- bool is_fullscreen() const;
- void blit(const Surface &src, const Point &dst_pos, const Rect &src_rect, const RenderOptions &options);
- void blit(const Video::Texture &src, const Point &dst_pos, const Rect &src_rect, const RenderOptions &options);
- void fill(const Color &color, const Rect &rect);
- void fill_blend(const Color &color, const Rect &rect);
- private:
- /// The logical size of the window;
- Area logical_size;
-
- /// The window
- SDL_Surface *window;
- };
- }
- }
-}
-
-#endif
+++ /dev/null
-// Copyright Timothy Goya 2007.
-// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at
-// http://www.boost.org/LICENSE_1_0.txt)
-
-#include <unison/video/sdl/Blitters.hpp>
-#include <unison/video/Surface.hpp>
-
-#include <assert.h>
-
-#include "SDL.h"
-
-namespace
-{
- unsigned char add_saturate(unsigned char lhs, int rhs)
- {
- if(lhs + rhs < 0x00)
- {
- return 0x00;
- }
- if(lhs + rhs > 0xff)
- {
- return 0xff;
- }
- return lhs + rhs;
- }
-}
-
-
-namespace Unison
-{
- namespace Video
- {
- namespace SDL
- {
- /*SDL_Surface *Blitters::optimize(const Surface &src)
- {
- bool colors[(1 << 12)];
- memset(colors, 0, (1 << 12) * sizeof(bool));
-
- Surface dst(src);
- Color *iter = dst.get_pixels();
- for(unsigned int y = 0;y < dst.get_size().y;y++)
- {
- for(unsigned int x = 0;x < dst.get_size().x;x++, iter++)
- {
- unsigned char oldalpha = iter->alpha;
- unsigned char newalpha = oldalpha & 0x80 ? 0xff : 0x00;
- iter->alpha = newalpha;
- int error = oldalpha - newalpha;
- if(x != dst.get_size().x - 1)
- {
- (iter + 1)->alpha = add_saturate((iter + 1)->alpha, error * 7 / 16);
- }
- if(y != dst.get_size().y - 1)
- {
- if(x != 0)
- {
- (iter + dst.get_size().x - 1)->alpha = add_saturate((iter + dst.get_size().x - 1)->alpha, error * 3 / 16);
- }
- (iter + dst.get_size().x)->alpha = add_saturate((iter + dst.get_size().x)->alpha, error * 5 / 16);
- if(x != dst.get_size().x - 1)
- {
- (iter + dst.get_size().x + 1)->alpha = add_saturate((iter + dst.get_size().x + 1)->alpha, error * 1 / 16);
- }
- }
- if(newalpha != 0)
- {
- colors[((iter->red & 0xf0) << 4) | (iter->green & 0xf0) | ((iter->blue & 0xf0) >> 4)] = true;
- }
- }
- }
-
- int keycolor = -1;
- for(int i = 0;i < (1 << 12);i++)
- {
- if(!colors[i])
- {
- keycolor = i;
- break;
- }
- }
- if(keycolor == -1)
- {
- SDL_Surface *converted = create_sdl_surface_from(src);
- SDL_Surface *optimized = SDL_DisplayFormatAlpha(converted);
- SDL_FreeSurface(converted);
- return optimized;
- }
-
- Color key(((keycolor & 0xf00) >> 4) | 0xf, (keycolor & 0x0f0) | 0xf, ((keycolor & 0x00f) << 4) | 0xf);
-
- Color *end = dst.get_pixels() + dst.get_size().x * dst.get_size().y;
- for(iter = dst.get_pixels();iter != end;++iter)
- {
- if(iter->alpha == 0x00)
- {
- *iter = key;
- }
- }
-
- SDL_Surface *converted = create_sdl_surface_from(dst);
- SDL_SetColorKey(converted, SDL_SRCCOLORKEY | SDL_RLEACCEL, SDL_MapRGB(converted->format, key.red, key.green, key.blue));
- SDL_Surface *optimized = SDL_DisplayFormat(converted);
- SDL_FreeSurface(converted);
- return optimized;
- }*/
- SDL_Surface *Blitters::optimize(const Surface &src)
- {
- unsigned int transparent = 0;
- unsigned int opaque = 0;
- unsigned int semitransparent = 0;
- unsigned int alphasum = 0;
- unsigned int squaredalphasum = 0;
- bool colors[(1 << 12)];
- memset(colors, 0, (1 << 12) * sizeof(bool));
-
- const Color *src_end = src.get_pixels() + src.get_size().x * src.get_size().y;
- for(const Color *iter = src.get_pixels();iter != src_end;++iter)
- {
- if(iter->alpha < 16)
- {
- transparent++;
- }
- else if(iter->alpha > 240)
- {
- opaque++;
- alphasum += iter->alpha;
- squaredalphasum += iter->alpha * iter->alpha;
- }
- else
- {
- semitransparent++;
- squaredalphasum += iter->alpha * iter->alpha;
- }
- if(iter->alpha != 0)
- {
- colors[((iter->red & 0xf0) << 4) | (iter->green & 0xf0) | ((iter->blue & 0xf0) >> 4)] = true;
- }
- }
-
- unsigned int avgalpha = (opaque + semitransparent) ? alphasum / (opaque + semitransparent) : 0;
- unsigned int avgsquaredalpha = (opaque + semitransparent) ? squaredalphasum / (opaque + semitransparent) : 0;
- unsigned int alphavariance = avgsquaredalpha - avgalpha * avgalpha;
- if(semitransparent > ((transparent + opaque + semitransparent) / 8) && alphavariance > 16)
- {
- SDL_Surface *converted = create_sdl_surface_from(src);
- SDL_Surface *optimized = SDL_DisplayFormatAlpha(converted);
- SDL_FreeSurface(converted);
- return optimized;
- }
-
- int keycolor = -1;
- for(int i = 0;i < (1 << 12);i++)
- {
- if(!colors[i])
- {
- keycolor = i;
- break;
- }
- }
- if(keycolor == -1)
- {
- SDL_Surface *converted = create_sdl_surface_from(src);
- SDL_Surface *optimized = SDL_DisplayFormatAlpha(converted);
- SDL_FreeSurface(converted);
- return optimized;
- }
-
- Color key(((keycolor & 0xf00) >> 4) | 0xf, (keycolor & 0x0f0) | 0xf, ((keycolor & 0x00f) << 4) | 0xf);
- Surface dst(src.get_size());
- Color *dst_end = dst.get_pixels() + dst.get_size().x * dst.get_size().y;
- const Color *src_iter = src.get_pixels();
- Color *dst_iter = dst.get_pixels();
- for(;dst_iter != dst_end;++dst_iter, ++src_iter)
- {
- *dst_iter = (src_iter->alpha < avgalpha / 4) ? key : *src_iter;
- }
-
- SDL_Surface *converted = create_sdl_surface_from(dst);
- if(avgalpha < 240)
- {
- SDL_SetAlpha(converted, SDL_SRCALPHA | SDL_RLEACCEL, avgalpha);
- }
- SDL_SetColorKey(converted, SDL_SRCCOLORKEY | SDL_RLEACCEL, SDL_MapRGB(converted->format, key.red, key.green, key.blue));
- SDL_Surface *optimized = SDL_DisplayFormat(converted);
- SDL_FreeSurface(converted);
- return optimized;
- }
-
- void Blitters::blit_upper(SDL_Surface *src, Rect src_rect, SDL_Surface *dst, Point dst_pos, void (*blit_lower)(SDL_Surface *, const Rect &, SDL_Surface *, const Point &))
- {
- assert(src);
- assert(dst);
- assert(blit_lower);
- if(src_rect == Rect())
- {
- src_rect.size.x = src->w;
- src_rect.size.y = src->h;
- }
- if(dst_pos.x < 0)
- {
- if(src_rect.size.x < (unsigned int) -dst_pos.x)
- {
- return;
- }
- src_rect.pos.x += -dst_pos.x;
- src_rect.size.x += dst_pos.x;
- dst_pos.x = 0;
- }
- if(dst_pos.y < 0)
- {
- if(src_rect.size.y < (unsigned int) -dst_pos.y)
- {
- return;
- }
- src_rect.pos.y += -dst_pos.y;
- src_rect.size.y += dst_pos.y;
- dst_pos.y = 0;
- }
- if(src_rect.pos.x < 0)
- {
- if(src_rect.size.x < (unsigned int) -src_rect.pos.x)
- {
- return;
- }
- src_rect.size.x += src_rect.pos.x;
- src_rect.pos.x = 0;
- }
- if(src_rect.pos.y < 0)
- {
- if(src_rect.size.y < (unsigned int) -src_rect.pos.y)
- {
- return;
- }
- src_rect.size.y += src_rect.pos.y;
- src_rect.pos.y = 0;
- }
- if(src_rect.get_right() > src->w)
- {
- src_rect.size.x = src->w - src_rect.pos.x;
- }
- if(src_rect.get_bottom() > src->h)
- {
- src_rect.size.y = src->h - src_rect.pos.y;
- }
- if(int(dst_pos.x + src_rect.size.x) > dst->w)
- {
- src_rect.size.x = dst->w - dst_pos.x;
- }
- if(int(dst_pos.y + src_rect.size.y) > dst->h)
- {
- src_rect.size.y = dst->h - dst_pos.y;
- }
- blit_lower(src, src_rect, dst, dst_pos);
- }
-
- void Blitters::blit_lower_none(SDL_Surface *src, const Rect &src_rect, SDL_Surface *dst, const Point &dst_pos)
- {
- SDL_Rect sdl_src_rect = {src_rect.pos.x, src_rect.pos.y, src_rect.size.x, src_rect.size.y};
- SDL_Rect sdl_dst_rect = {dst_pos.x, dst_pos.y, 0, 0};
-
- Uint8 alpha = src->format->alpha;
- SDL_SetAlpha(src, 0, 0);
- SDL_BlitSurface(src, &sdl_src_rect, dst, &sdl_dst_rect);
- SDL_SetAlpha(src, SDL_SRCALPHA | SDL_RLEACCEL, alpha);
- }
-
- void Blitters::blit_lower_mask(SDL_Surface *src, const Rect &src_rect, SDL_Surface *dst, const Point &dst_pos)
- {
- if(SDL_MUSTLOCK(src))
- {
- SDL_LockSurface(src);
- }
- if(SDL_MUSTLOCK(dst))
- {
- SDL_LockSurface(dst);
- }
- int src_bpp = src->format->BytesPerPixel;
- int dst_bpp = dst->format->BytesPerPixel;
- Uint8 *src_pixel = (Uint8 *)src->pixels + src_rect.pos.y * src->pitch + src_rect.pos.x * src_bpp;
- Uint8 *dst_pixel = (Uint8 *)dst->pixels + dst_pos.y * dst->pitch + dst_pos.x * dst_bpp;
- for(unsigned int y = 0;y < src_rect.size.y;y++)
- {
- for(unsigned int x = 0;x < src_rect.size.x;x++)
- {
- Uint32 src_mapped = 0;
- switch(src_bpp) {
- case 1:
- src_mapped = *src_pixel;
- break;
- case 2:
- src_mapped = *(Uint16 *)src_pixel;
- break;
- case 3:
-#if SDL_BYTEORDER == SDL_BIG_ENDIAN
- src_mapped |= src_pixel[0] << 16;
- src_mapped |= src_pixel[1] << 8;
- src_mapped |= src_pixel[2] << 0;
-#else
- src_mapped |= src_pixel[0] << 0;
- src_mapped |= src_pixel[1] << 8;
- src_mapped |= src_pixel[2] << 16;
-#endif
- break;
- case 4:
- src_mapped = *(Uint32 *)src_pixel;
- break;
- }
- Uint8 src_red, src_green, src_blue, src_alpha;
- SDL_GetRGBA(src_mapped, src->format, &src_red, &src_green, &src_blue, &src_alpha);
- if(src_alpha)
- {
- Uint32 blend_mapped = SDL_MapRGBA(dst->format, src_red, src_green, src_blue, src_alpha);
- switch(dst_bpp) {
- case 1:
- *dst_pixel = blend_mapped;
- break;
- case 2:
- *(Uint16 *)dst_pixel = blend_mapped;
- break;
- case 3:
-#if SDL_BYTEORDER == SDL_BIG_ENDIAN
- dst_pixel[0] = (blend_mapped >> 16) & 0xff;
- dst_pixel[1] = (blend_mapped >> 8) & 0xff;
- dst_pixel[2] = (blend_mapped >> 0) & 0xff;
-#else
- dst_pixel[0] = (blend_mapped >> 0) & 0xff;
- dst_pixel[1] = (blend_mapped >> 8) & 0xff;
- dst_pixel[2] = (blend_mapped >> 16) & 0xff;
-#endif
- break;
- case 4:
- *(Uint32 *)dst_pixel = blend_mapped;
- break;
- }
- }
- src_pixel += src_bpp;
- dst_pixel += dst_bpp;
- }
- src_pixel += src->pitch - src_rect.size.x * src_bpp;
- dst_pixel += dst->pitch - src_rect.size.x * dst_bpp;
- }
- if(SDL_MUSTLOCK(dst))
- {
- SDL_UnlockSurface(dst);
- }
- if(SDL_MUSTLOCK(src))
- {
- SDL_UnlockSurface(src);
- }
- }
-
- void Blitters::blit_lower_alpha(SDL_Surface *src, const Rect &src_rect, SDL_Surface *dst, const Point &dst_pos)
- {
- SDL_Rect sdl_src_rect = {src_rect.pos.x, src_rect.pos.y, src_rect.size.x, src_rect.size.y};
- SDL_Rect sdl_dst_rect = {dst_pos.x, dst_pos.y, 0, 0};
-
- SDL_BlitSurface(src, &sdl_src_rect, dst, &sdl_dst_rect);
- }
-
- void Blitters::blit_lower_add(SDL_Surface *src, const Rect &src_rect, SDL_Surface *dst, const Point &dst_pos)
- {
- if(SDL_MUSTLOCK(src))
- {
- SDL_LockSurface(src);
- }
- if(SDL_MUSTLOCK(dst))
- {
- SDL_LockSurface(dst);
- }
- int src_bpp = src->format->BytesPerPixel;
- int dst_bpp = dst->format->BytesPerPixel;
- Uint8 *src_pixel = (Uint8 *)src->pixels + src_rect.pos.y * src->pitch + src_rect.pos.x * src_bpp;
- Uint8 *dst_pixel = (Uint8 *)dst->pixels + dst_pos.y * dst->pitch + dst_pos.x * dst_bpp;
- for(unsigned int y = 0;y < src_rect.size.y;y++)
- {
- for(unsigned int x = 0;x < src_rect.size.x;x++)
- {
- Uint32 src_mapped = 0;
- switch(src_bpp) {
- case 1:
- src_mapped = *src_pixel;
- break;
- case 2:
- src_mapped = *(Uint16 *)src_pixel;
- break;
- case 3:
-#if SDL_BYTEORDER == SDL_BIG_ENDIAN
- src_mapped |= src_pixel[0] << 16;
- src_mapped |= src_pixel[1] << 8;
- src_mapped |= src_pixel[2] << 0;
-#else
- src_mapped |= src_pixel[0] << 0;
- src_mapped |= src_pixel[1] << 8;
- src_mapped |= src_pixel[2] << 16;
-#endif
- break;
- case 4:
- src_mapped = *(Uint32 *)src_pixel;
- break;
- }
- Uint8 src_red, src_green, src_blue, src_alpha;
- SDL_GetRGBA(src_mapped, src->format, &src_red, &src_green, &src_blue, &src_alpha);
- Uint32 dst_mapped = 0;
- switch(dst_bpp) {
- case 1:
- dst_mapped = *dst_pixel;
- break;
- case 2:
- dst_mapped = *(Uint16 *)dst_pixel;
- break;
- case 3:
-#if SDL_BYTEORDER == SDL_BIG_ENDIAN
- dst_mapped |= dst_pixel[0] << 16;
- dst_mapped |= dst_pixel[1] << 8;
- dst_mapped |= dst_pixel[2] << 0;
-#else
- dst_mapped |= dst_pixel[0] << 0;
- dst_mapped |= dst_pixel[1] << 8;
- dst_mapped |= dst_pixel[2] << 16;
-#endif
- break;
- case 4:
- dst_mapped = *(Uint32 *)dst_pixel;
- break;
- }
- Uint8 dst_red, dst_green, dst_blue, dst_alpha;
- SDL_GetRGBA(dst_mapped, dst->format, &dst_red, &dst_green, &dst_blue, &dst_alpha);
- Uint8 blend_red = src_red, blend_green = src_green, blend_blue = src_blue, blend_alpha = src_alpha;
- if(src_red != 0 && dst_red != 0xff)
- {
- int redsum = dst_red + src_red * src_alpha / 0xff;
- blend_red = redsum & ~0xff ? 0xff : redsum;
- }
- else
- {
- }
- if(src_green != 0 && dst_green != 0xff)
- {
- int greensum = dst_green + src_green * src_alpha / 0xff;
- blend_green = greensum & ~0xff ? 0xff : greensum;
- }
- if(src_blue != 0 && dst_blue != 0xff)
- {
- int bluesum = dst_blue + src_blue * src_alpha / 0xff;
- blend_blue = bluesum & ~0xff ? 0xff : bluesum;
- }
- if(src_red != blend_red || src_green != blend_green || src_blue != blend_blue || src_alpha != blend_alpha)
- {
- Uint32 blend_mapped = SDL_MapRGBA(dst->format, blend_red, blend_green, blend_blue, blend_alpha);
- switch(dst_bpp) {
- case 1:
- *dst_pixel = blend_mapped;
- break;
- case 2:
- *(Uint16 *)dst_pixel = blend_mapped;
- break;
- case 3:
-#if SDL_BYTEORDER == SDL_BIG_ENDIAN
- dst_pixel[0] = (blend_mapped >> 16) & 0xff;
- dst_pixel[1] = (blend_mapped >> 8) & 0xff;
- dst_pixel[2] = (blend_mapped >> 0) & 0xff;
-#else
- dst_pixel[0] = (blend_mapped >> 0) & 0xff;
- dst_pixel[1] = (blend_mapped >> 8) & 0xff;
- dst_pixel[2] = (blend_mapped >> 16) & 0xff;
-#endif
- break;
- case 4:
- *(Uint32 *)dst_pixel = blend_mapped;
- break;
- }
- }
- src_pixel += src_bpp;
- dst_pixel += dst_bpp;
- }
- src_pixel += src->pitch - src_rect.size.x * src_bpp;
- dst_pixel += dst->pitch - src_rect.size.x * dst_bpp;
- }
- if(SDL_MUSTLOCK(dst))
- {
- SDL_UnlockSurface(dst);
- }
- if(SDL_MUSTLOCK(src))
- {
- SDL_UnlockSurface(src);
- }
- }
-
- void Blitters::blit_lower_mod(SDL_Surface *src, const Rect &src_rect, SDL_Surface *dst, const Point &dst_pos)
- {
- if(SDL_MUSTLOCK(src))
- {
- SDL_LockSurface(src);
- }
- if(SDL_MUSTLOCK(dst))
- {
- SDL_LockSurface(dst);
- }
- int src_bpp = src->format->BytesPerPixel;
- int dst_bpp = dst->format->BytesPerPixel;
- Uint8 *src_pixel = (Uint8 *)src->pixels + src_rect.pos.y * src->pitch + src_rect.pos.x * src_bpp;
- Uint8 *dst_pixel = (Uint8 *)dst->pixels + dst_pos.y * dst->pitch + dst_pos.x * dst_bpp;
- for(unsigned int y = 0;y < src_rect.size.y;y++)
- {
- for(unsigned int x = 0;x < src_rect.size.x;x++)
- {
- Uint32 src_mapped = 0;
- switch(src_bpp) {
- case 1:
- src_mapped = *src_pixel;
- break;
- case 2:
- src_mapped = *(Uint16 *)src_pixel;
- break;
- case 3:
-#if SDL_BYTEORDER == SDL_BIG_ENDIAN
- src_mapped |= src_pixel[0] << 16;
- src_mapped |= src_pixel[1] << 8;
- src_mapped |= src_pixel[2] << 0;
-#else
- src_mapped |= src_pixel[0] << 0;
- src_mapped |= src_pixel[1] << 8;
- src_mapped |= src_pixel[2] << 16;
-#endif
- break;
- case 4:
- src_mapped = *(Uint32 *)src_pixel;
- break;
- }
- Uint8 src_red, src_green, src_blue, src_alpha;
- SDL_GetRGBA(src_mapped, src->format, &src_red, &src_green, &src_blue, &src_alpha);
- Uint32 dst_mapped = 0;
- switch(dst_bpp) {
- case 1:
- dst_mapped = *dst_pixel;
- break;
- case 2:
- dst_mapped = *(Uint16 *)dst_pixel;
- break;
- case 3:
-#if SDL_BYTEORDER == SDL_BIG_ENDIAN
- dst_mapped |= dst_pixel[0] << 16;
- dst_mapped |= dst_pixel[1] << 8;
- dst_mapped |= dst_pixel[2] << 0;
-#else
- dst_mapped |= dst_pixel[0] << 0;
- dst_mapped |= dst_pixel[1] << 8;
- dst_mapped |= dst_pixel[2] << 16;
-#endif
- break;
- case 4:
- dst_mapped = *(Uint32 *)dst_pixel;
- break;
- }
- Uint8 dst_red, dst_green, dst_blue, dst_alpha;
- SDL_GetRGBA(dst_mapped, dst->format, &dst_red, &dst_green, &dst_blue, &dst_alpha);
- Uint8 blend_red, blend_green, blend_blue, blend_alpha;
- blend_red = dst_red * src_red / 0xff;
- blend_green = dst_green * src_green / 0xff;
- blend_blue = dst_blue * src_blue / 0xff;
- blend_alpha = dst_alpha * src_alpha / 0xff;
- if(src_red != blend_red || src_green != blend_green || src_blue != blend_blue || src_alpha != blend_alpha)
- {
- Uint32 blend_mapped = SDL_MapRGBA(dst->format, blend_red, blend_green, blend_blue, blend_alpha);
- switch(dst_bpp) {
- case 1:
- *dst_pixel = blend_mapped;
- break;
- case 2:
- *(Uint16 *)dst_pixel = blend_mapped;
- break;
- case 3:
-#if SDL_BYTEORDER == SDL_BIG_ENDIAN
- dst_pixel[0] = (blend_mapped >> 16) & 0xff;
- dst_pixel[1] = (blend_mapped >> 8) & 0xff;
- dst_pixel[2] = (blend_mapped >> 0) & 0xff;
-#else
- dst_pixel[0] = (blend_mapped >> 0) & 0xff;
- dst_pixel[1] = (blend_mapped >> 8) & 0xff;
- dst_pixel[2] = (blend_mapped >> 16) & 0xff;
-#endif
- break;
- case 4:
- *(Uint32 *)dst_pixel = blend_mapped;
- break;
- }
- }
- src_pixel += src_bpp;
- dst_pixel += dst_bpp;
- }
- src_pixel += src->pitch - src_rect.size.x * src_bpp;
- dst_pixel += dst->pitch - src_rect.size.x * dst_bpp;
- }
- if(SDL_MUSTLOCK(dst))
- {
- SDL_UnlockSurface(dst);
- }
- if(SDL_MUSTLOCK(src))
- {
- SDL_UnlockSurface(src);
- }
- }
- }
- }
-}
+++ /dev/null
-// Copyright Timothy Goya 2007.
-// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at
-// http://www.boost.org/LICENSE_1_0.txt)
-
-#include "Renderer.hpp"
-#include "Texture.hpp"
-#include "Window.hpp"
-#include <unison/video/Surface.hpp>
-#include <unison/video/Window.hpp>
-#include <unison/video/sdl/Blitters.hpp>
-#include <unison/video/backend/Texture.hpp>
-#include <unison/vfs/sdl/Utils.hpp>
-
-#include <assert.h>
-
-#include "SDL.h"
-#include "SDL_image.h"
-
-namespace Unison
-{
- namespace Video
- {
- namespace SDL
- {
- Renderer::Renderer()
- {
- }
-
- Renderer::~Renderer()
- {
- }
-
- void Renderer::init()
- {
- SDL_InitSubSystem(SDL_INIT_VIDEO);
- }
-
- void Renderer::quit()
- {
- SDL_QuitSubSystem(SDL_INIT_VIDEO);
- }
-
- std::string Renderer::get_name()
- {
- return "sdl";
- }
-
- bool Renderer::is_usable()
- {
- SDL_InitSubSystem(SDL_INIT_VIDEO);
-
- if(!SDL_ListModes(0, SDL_SWSURFACE))
- {
- SDL_QuitSubSystem(SDL_INIT_VIDEO);
- return false;
- }
-
- /*const SDL_VideoInfo *info = SDL_GetVideoInfo();
- if(SDL_VideoModeOK(info->current_w, info->current_h, 0, SDL_SWSURFACE | SDL_FULLSCREEN))
- {
- SDL_QuitSubSystem(SDL_INIT_VIDEO);
- return false;
- }*/
-
- SDL_QuitSubSystem(SDL_INIT_VIDEO);
-
- return true;
- }
-
- Surface Renderer::load_surface(const std::string &filename)
- {
- SDL_Surface *image = IMG_Load_RW(VFS::SDL::Utils::open_physfs_in(filename), 1);
- assert(image);
- Surface surface = Surface(Area(image->w, image->h));
- SDL_Surface *sdl_surface = SDL::Blitters::create_sdl_surface_from(surface);
- assert(sdl_surface);
- SDL::Blitters::blit_blend_none(image, Rect(), sdl_surface, Point());
- SDL_FreeSurface(sdl_surface);
- return surface;
- }
-
- Surface Renderer::load_surface(const std::string &filename, const Color &colorkey)
- {
- SDL_Surface *image = IMG_Load_RW(VFS::SDL::Utils::open_physfs_in(filename), 1);
- assert(image);
- Surface surface = Surface(Area(image->w, image->h));
- SDL_Surface *sdl_surface = SDL::Blitters::create_sdl_surface_from(surface);
- assert(sdl_surface);
- SDL_SetColorKey(image, SDL_SRCCOLORKEY, SDL_MapRGB(image->format, colorkey.red, colorkey.blue, colorkey.alpha));
- SDL::Blitters::blit_blend_none(image, Rect(), sdl_surface, Point());
- SDL_FreeSurface(sdl_surface);
- return surface;
- }
-
- void Renderer::save_surface(const Surface &surface, const std::string &filename)
- {
- SDL_Surface *sdl_surface = SDL::Blitters::create_sdl_surface_from(surface);
- assert(sdl_surface);
- SDL_SaveBMP(sdl_surface, filename.c_str());
- SDL_FreeSurface(sdl_surface);
- }
-
- void Renderer::blit(const Surface &src, const Rect &src_rect, Surface &dst, const Point &dst_pos, const RenderOptions &options)
- {
- Surface fragment;
- if(src_rect.pos == Point() && (src_rect.size == Area() || src_rect.size == src.get_size()))
- {
- fragment = src;
- }
- else
- {
- fragment = Surface(src_rect.size);
- Video::Blitters::blit_blend_none(src, src_rect, fragment, Point());
- }
- if(options.h_flip)
- {
- fragment = fragment.h_flip();
- }
- if(options.v_flip)
- {
- fragment = fragment.v_flip();
- }
- SDL_Surface *src_surface = Blitters::create_sdl_surface_from(fragment.modulate(options.color).modulate(options.alpha));
- assert(src_surface);
-
- SDL_Surface *dst_surface = Blitters::create_sdl_surface_from(dst);
- assert(dst_surface);
-
-
- Blitters::blit_blend(src_surface, Rect(Point(), fragment.get_size()), dst_surface, dst_pos, options.blend);
-
- SDL_FreeSurface(dst_surface);
- SDL_FreeSurface(src_surface);
- }
-
- void Renderer::blit(Backend::Texture *src, const Rect &src_rect, Surface &dst, const Point &dst_pos, const RenderOptions &options)
- {
- blit(src->get_surface(), src_rect, dst, dst_pos, options);
- }
-
- void Renderer::fill(Surface &dst, const Color &color, const Rect &rect)
- {
- SDL_Surface *dst_surface = Blitters::create_sdl_surface_from(dst);
- assert(dst_surface);
-
- Uint32 mapped = SDL_MapRGBA(dst_surface->format, color.red, color.green, color.blue, color.alpha);
- SDL_FillRect(dst_surface, &rect, mapped);
- }
-
- void Renderer::fill_blend(Surface &dst, const Color &color, const Rect &rect)
- {
- SDL_Surface *dst_surface = Blitters::create_sdl_surface_from(dst);
- assert(dst_surface);
-
- Uint32 mapped = SDL_MapRGBA(dst_surface->format, color.red, color.green, color.blue, color.alpha);
- if(color.alpha == 0xff)
- {
- SDL_FillRect(dst_surface, &rect, mapped);
- }
- else if(color.alpha != 0x00)
- {
- SDL_Surface *temp = SDL_CreateRGBSurface(dst_surface->flags, rect.size.x, rect.size.y, dst_surface->format->BitsPerPixel, dst_surface->format->Rmask, dst_surface->format->Gmask, dst_surface->format->Bmask, dst_surface->format->Amask);
-
- SDL_FillRect(temp, 0, mapped);
- SDL_SetAlpha(temp, SDL_SRCALPHA | SDL_RLEACCEL, color.alpha);
- SDL_BlitSurface(temp, 0, dst_surface, &rect);
- SDL_FreeSurface(temp);
- }
- }
-
- Backend::Window *Renderer::create_window(const Area &size, const Area &logical_size, bool fullscreen)
- {
- return new Window(size, logical_size, fullscreen);
- }
-
- Backend::Texture *Renderer::create_texture(const Surface &surface)
- {
- return new Texture(surface);
- }
- }
- }
-}
+++ /dev/null
-// Copyright Timothy Goya 2007.
-// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at
-// http://www.boost.org/LICENSE_1_0.txt)
-
-#ifndef UNISON_VIDEO_SDL_RENDERER_HPP
-#define UNISON_VIDEO_SDL_RENDERER_HPP
-
-#include <unison/video/backend/Renderer.hpp>
-
-#include <string>
-#include "SDL.h"
-
-namespace Unison
-{
- namespace Video
- {
- namespace Backend
- {
- class Texture;
- class Window;
- }
- namespace SDL
- {
- /// Does rendering tasks like blits and color fills using SDL
- class Renderer : public Backend::Renderer
- {
- public:
- /// Default constructor
- Renderer();
-
- /// Destructor
- ~Renderer();
-
- /// Initialize the backend
- void init();
-
- /// Cleanup the backend
- void quit();
-
- /// Get the name of the renderer
- /// \return the name of the renderer
- std::string get_name();
-
- /// Check if the backend is usable
- /// \return Whether the backend is usable
- bool is_usable();
-
- Surface load_surface(const std::string &filename);
- Surface load_surface(const std::string &filename, const Color &colorkey);
- void save_surface(const Surface &surface, const std::string &filename);
-
- /// Does a surface-to-surface blit
- /// \param[in] src The source surface
- /// \param[in] src_rect The part of the source surface to blit from
- /// \param[in] dst The destination surface
- /// \param[in] dst_pos The position to blit to
- /// \param[in] options Extra blit options
- void blit(const Surface &src, const Rect &src_rect, Surface &dst, const Point &dst_pos, const RenderOptions &options);
-
- /// Does a texture-to-surface blit
- /// \param[in] src The source texture
- /// \param[in] src_rect The part of the source texture to blit from
- /// \param[in] dst The destination surface
- /// \param[in] dst_pos The position to blit to
- /// \param[in] options Extra blit options
- void blit(Backend::Texture *src, const Rect &src_rect, Surface &dst, const Point &dst_pos, const RenderOptions &options);
-
- /// Fills a portion of a surface with the given color
- /// \param[in] dst The destination surface
- /// \param[in] color The color
- /// \param[in] rect The portion to fill
- void fill(Surface &dst, const Color &color, const Rect &rect);
-
- /// Fills with alpha blend a portion of a surface with the given color
- /// \param[in] dst The destination surface
- /// \param[in] color The color
- /// \param[in] rect The portion to fill
- void fill_blend(Surface &dst, const Color &color, const Rect &rect);
-
- /// Create a window
- /// \param[in] size The size of the window
- /// \param[in] logical_size The logical size of the window
- /// \param[in] fullscreen Whether to open in fullscreen mode
- /// \return The created window
- Backend::Window *create_window(const Area &size, const Area &logical_size, bool fullscreen);
-
- /// Create a texture data for the given surface
- /// \param[in] surface The surface to convert
- /// \return The texture data for the surface
- Backend::Texture *create_texture(const Surface &surface);
- };
- }
- }
-}
-
-#endif
+++ /dev/null
-// Copyright Timothy Goya 2007.
-// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at
-// http://www.boost.org/LICENSE_1_0.txt)
-
-#include "Texture.hpp"
-#include <unison/video/Surface.hpp>
-#include <unison/video/Window.hpp>
-#include <unison/video/Renderers.hpp>
-#include <unison/video/sdl/Blitters.hpp>
-#include <unison/video/backend/Renderer.hpp>
-
-#include <assert.h>
-
-namespace Unison
-{
- namespace Video
- {
- namespace SDL
- {
- Texture::Texture(const Surface &surface) :
- Backend::Texture(surface),
- scaled(),
- n_cache(),
- h_cache(),
- v_cache(),
- d_cache()
- {
- }
- /*Texture::Texture(const Surface &surface, const std::string &name) :
- Backend::Texture(surface, name),
- scaled(),
- n_cache(),
- h_cache(),
- v_cache(),
- d_cache()
- {
- }
-
- Texture::Texture(Backend::Texture *texture) :
- Backend::Texture(texture),
- scaled(),
- n_cache(),
- h_cache(),
- v_cache(),
- d_cache()
- {
- }*/
-
- Texture::~Texture()
- {
- }
-
- const Surface Texture::get_surface()
- {
- return surface;
- }
-
- void Texture::save()
- {
- scaled = Surface();
- n_cache.clear();
- h_cache.clear();
- v_cache.clear();
- d_cache.clear();
- }
-
- void Texture::blit(const Surface &src, const Point &dst_pos, const Rect &src_rect, const RenderOptions &options)
- {
- save();
- Renderers::get().get_renderer().blit(src, src_rect, surface, dst_pos, options);
- }
-
- void Texture::blit(const Video::Texture &src, const Point &dst_pos, const Rect &src_rect, const RenderOptions &options)
- {
- save();
- Texture *texture = dynamic_cast<Texture *>(Backend::Texture::get_texture(src.get_id()));
- Renderers::get().get_renderer().blit(texture, src_rect, surface, dst_pos, options);
- }
-
- void Texture::fill(const Color &color, const Rect &rect)
- {
- save();
- Renderers::get().get_renderer().fill(surface, color, rect);
- }
-
- void Texture::fill_blend(const Color &color, const Rect &rect)
- {
- save();
- Renderers::get().get_renderer().fill_blend(surface, color, rect);
- }
-
- SDL_Surface *Texture::get_transform(const RenderOptions &options, unsigned int numerator, unsigned int denominator)
- {
- if(scaled.get_size() == Area())
- {
- scaled = surface.scale(numerator, denominator);
- }
- assert(scaled.get_size() == surface.get_size() * numerator / denominator);
- std::map<Color, AlphaMap> &cache = options.h_flip ? (options.v_flip ? d_cache : h_cache) : (options.v_flip ? v_cache : n_cache);
- if(!cache[options.color][options.alpha])
- {
- Surface transformed = scaled.modulate(options.color).modulate(options.alpha);
- if(options.h_flip)
- {
- transformed = transformed.h_flip();
- }
- if(options.v_flip)
- {
- transformed = transformed.v_flip();
- }
- cache[options.color][options.alpha] = Blitters::optimize(transformed);
- }
- return cache[options.color][options.alpha];
- }
- }
- }
-}
+++ /dev/null
-// Copyright Timothy Goya 2007.
-// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at
-// http://www.boost.org/LICENSE_1_0.txt)
-
-#ifndef UNISON_VIDEO_SDL_TEXTURE_HPP
-#define UNISON_VIDEO_SDL_TEXTURE_HPP
-
-#include <unison/video/backend/Texture.hpp>
-#include <unison/video/Surface.hpp>
-
-#include <string>
-#include <map>
-
-#include "SDL.h"
-
-namespace Unison
-{
- namespace Video
- {
- namespace SDL
- {
- class Texture : public Backend::Texture
- {
- public:
- Texture(const Surface &surface);
- //Texture(const Surface &surface, const std::string &name);
- //Texture(Backend::Texture *texture);
- ~Texture();
-
- const Surface get_surface();
- void save();
- void blit(const Surface &src, const Point &dst_pos, const Rect &src_rect, const RenderOptions &options);
- void blit(const Video::Texture &src, const Point &dst_pos, const Rect &src_rect, const RenderOptions &options);
- void fill(const Color &color, const Rect &rect);
- void fill_blend(const Color &color, const Rect &rect);
-
- SDL_Surface *get_transform(const RenderOptions &options, unsigned int numerator, unsigned int denominator);
- private:
- Surface scaled;
- struct AlphaMap
- {
- static void ref(SDL_Surface *surface)
- {
- if(surface)
- {
- surface->refcount++;
- }
- }
-
- SDL_Surface *data[256];
-
- AlphaMap()
- {
- memset(data, 0, 256 * sizeof(SDL_Surface *));
- }
-
- ~AlphaMap()
- {
- std::for_each(data, data + 256, SDL_FreeSurface);
- }
-
- void operator = (const AlphaMap &other)
- {
- std::for_each(other.data, other.data + 256, ref);
- std::for_each(data, data + 256, SDL_FreeSurface);
- memcpy(data, other.data, 256 * sizeof(SDL_Surface *));
- }
-
- SDL_Surface *&operator [] (Uint8 alpha)
- {
- return data[alpha];
- }
- };
- //std::map<Color, AlphaMap> cache;
- std::map<Color, AlphaMap> n_cache;
- std::map<Color, AlphaMap> h_cache;
- std::map<Color, AlphaMap> v_cache;
- std::map<Color, AlphaMap> d_cache;
- };
- }
- }
-}
-
-#endif
+++ /dev/null
-// Copyright Timothy Goya 2007.
-// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at
-// http://www.boost.org/LICENSE_1_0.txt)
-
-#include "Window.hpp"
-#include "Texture.hpp"
-#include <unison/video/Window.hpp>
-#include <unison/video/Surface.hpp>
-#include <unison/video/Texture.hpp>
-#include <unison/video/Renderers.hpp>
-#include <unison/video/sdl/Blitters.hpp>
-#include <unison/video/backend/Renderer.hpp>
-#include <unison/video/backend/Texture.hpp>
-
-#include <functional>
-#include <assert.h>
-
-#include "SDL.h"
-
-namespace Unison
-{
- namespace Video
- {
- namespace SDL
- {
- Window::Window(const Area &size, const Area &logical_size, bool fullscreen) :
- scale_numerator(1),
- scale_denominator(1),
- offset(),
- window(0)
- {
- assert(size.x);
- assert(size.y);
- unsigned int xratio = size.x * logical_size.y;
- unsigned int yratio = size.y * logical_size.x;
- if(xratio < yratio)
- {
- scale_numerator = size.x;
- scale_denominator = logical_size.x;
- }
- else
- {
- scale_numerator = size.y;
- scale_denominator = logical_size.y;
- }
- offset = (size - logical_size * scale_numerator / scale_denominator) / 2;
- window = SDL_SetVideoMode(size.x, size.y, 0, SDL_ANYFORMAT | SDL_SWSURFACE | (fullscreen ? SDL_FULLSCREEN : 0));
- assert(window);
- Uint32 black = SDL_MapRGB(window->format, 0, 0, 0);
- SDL_FillRect(window, 0, black);
- }
-
- Window::~Window()
- {
- }
-
- void Window::take_screenshot(const std::string &filename) const
- {
- assert(window);
- SDL_SaveBMP(window, filename.c_str());
- }
-
- void Window::flip()
- {
- assert(window);
- SDL_Flip(window);
- }
-
- void Window::set_title(const std::string &title)
- {
- SDL_WM_SetCaption(title.c_str(), title.c_str());
- }
-
- void Window::set_icon(const Surface &icon)
- {
- SDL_Surface *icon_surface = Blitters::create_sdl_surface_from(icon);
- assert(icon_surface);
- SDL_WM_SetIcon(icon_surface, 0);
- SDL_FreeSurface(icon_surface);
- }
-
- Area Window::get_size() const
- {
- return Area(window->w, window->h);
- }
-
- bool Window::is_fullscreen() const
- {
- return window->flags & SDL_FULLSCREEN;
- }
-
- void Window::blit(const Surface &src, const Point &dst_pos, const Rect &src_rect, const RenderOptions &options)
- {
- assert(src.get_pixels());
- assert(window);
-
- Surface fragment;
- if(src_rect.pos == Point() && (src_rect.size == Area() || src_rect.size == src.get_size()))
- {
- fragment = src;
- }
- else
- {
- fragment = Surface(src_rect.size);
- Video::Blitters::blit_blend_none(src, src_rect, fragment, Point());
- }
- fragment = fragment.scale(scale_numerator, scale_denominator);
- if(options.h_flip)
- {
- fragment = fragment.h_flip();
- }
- if(options.v_flip)
- {
- fragment = fragment.v_flip();
- }
- SDL_Surface *src_surface = Blitters::create_sdl_surface_from(fragment.modulate(options.color).modulate(options.alpha));
- assert(src_surface);
-
- Point scaled_dst_pos(dst_pos);
- scaled_dst_pos *= scale_numerator;
- scaled_dst_pos /= scale_denominator;
- scaled_dst_pos += offset;
-
- Blitters::blit_blend(src_surface, Rect(Point(), fragment.get_size()), window, scaled_dst_pos, options.blend);
-
- SDL_FreeSurface(src_surface);
- }
-
- void Window::blit(const Video::Texture &src, const Point &dst_pos, const Rect &src_rect, const RenderOptions &options)
- {
- Texture *texture = dynamic_cast<Texture *>(Backend::Texture::get_texture(src.get_id()));
- assert(texture);
- assert(window);
-
- Rect scaled_src_rect(src_rect);
- /*if(options.h_flip)
- {
- scaled_src_rect.pos.x = src.get_size().x - src_rect.pos.x - src_rect.size.x;
- }
- if(options.v_flip)
- {
- scaled_src_rect.pos.y = src.get_size().y - src_rect.pos.y - src_rect.size.y;
- }*/
- if(dst_pos.x < 0)
- {
- if(scaled_src_rect.size.x < (unsigned int) -dst_pos.x)
- {
- return;
- }
- scaled_src_rect.pos.x += -dst_pos.x;
- scaled_src_rect.size.x += dst_pos.x;
- }
- if(dst_pos.y < 0)
- {
- if(scaled_src_rect.size.y < (unsigned int) -dst_pos.y)
- {
- return;
- }
- scaled_src_rect.pos.y += -dst_pos.y;
- scaled_src_rect.size.y += dst_pos.y;
- }
- scaled_src_rect.pos *= scale_numerator;
- scaled_src_rect.pos /= scale_denominator;
- scaled_src_rect.size *= scale_numerator;
- scaled_src_rect.size /= scale_denominator;
-
- Point scaled_dst_pos(dst_pos);
- if(dst_pos.x < 0)
- {
- scaled_dst_pos.x = 0;
- }
- if(dst_pos.y < 0)
- {
- scaled_dst_pos.y = 0;
- }
- scaled_dst_pos *= scale_numerator;
- scaled_dst_pos /= scale_denominator;
- scaled_dst_pos += offset;
-
- Blitters::blit_blend(texture->get_transform(options, scale_numerator, scale_denominator), scaled_src_rect, window, scaled_dst_pos, options.blend);
- }
-
- void Window::fill(const Color &color, const Rect &rect)
- {
- assert(window);
-
- Uint32 mapped = SDL_MapRGBA(window->format, color.red, color.green, color.blue, color.alpha);
-
- Rect scaled_rect(rect);
- scaled_rect.pos *= scale_numerator;
- scaled_rect.pos /= scale_denominator;
- scaled_rect.size *= scale_numerator;
- scaled_rect.size /= scale_denominator;
- scaled_rect.pos += offset;
-
- SDL_FillRect(window, &scaled_rect, mapped);
- }
-
- void Window::fill_blend(const Color &color, const Rect &rect)
- {
- assert(window);
-
- Uint32 mapped = SDL_MapRGB(window->format, color.red, color.green, color.blue);
-
- Rect scaled_rect(rect);
- scaled_rect.pos *= scale_numerator;
- scaled_rect.pos /= scale_denominator;
- scaled_rect.size *= scale_numerator;
- scaled_rect.size /= scale_denominator;
- scaled_rect.pos += offset;
-
- if(color.alpha == 0xff)
- {
- SDL_FillRect(window, &scaled_rect, mapped);
- }
- else if(color.alpha != 0x00)
- {
- SDL_Surface *temp = SDL_CreateRGBSurface(window->flags, scaled_rect.size.x, scaled_rect.size.y, window->format->BitsPerPixel, window->format->Rmask, window->format->Gmask, window->format->Bmask, window->format->Amask);
-
- SDL_FillRect(temp, 0, mapped);
- SDL_SetAlpha(temp, SDL_SRCALPHA | SDL_RLEACCEL, color.alpha);
- SDL_BlitSurface(temp, 0, window, &scaled_rect);
- SDL_FreeSurface(temp);
- }
- }
- }
- }
-}
+++ /dev/null
-// Copyright Timothy Goya 2007.
-// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at
-// http://www.boost.org/LICENSE_1_0.txt)
-
-#ifndef UNISON_VIDEO_SDL_WINDOW_HPP
-#define UNISON_VIDEO_SDL_WINDOW_HPP
-
-#include <unison/video/backend/Window.hpp>
-#include <unison/video/RenderOptions.hpp>
-#include <string>
-
-#include "SDL.h"
-
-namespace Unison
-{
- namespace Video
- {
- class Texture;
- namespace SDL
- {
- class Window : public Backend::Window
- {
- public:
- Window(const Area &size, const Area &logical_size, bool fullscreen = false);
-
- ~Window();
- void take_screenshot(const std::string &filename) const;
- void flip();
- void set_title(const std::string &title);
- void set_icon(const Surface &icon);
- Area get_size() const;
- bool is_fullscreen() const;
- void blit(const Surface &src, const Point &dst_pos, const Rect &src_rect, const RenderOptions &options);
- void blit(const Video::Texture &src, const Point &dst_pos, const Rect &src_rect, const RenderOptions &options);
- void fill(const Color &color, const Rect &rect);
- void fill_blend(const Color &color, const Rect &rect);
- private:
- /// The numerator of the scaling ratio
- unsigned int scale_numerator;
-
- /// The denominator of the scaling ratio
- unsigned int scale_denominator;
-
- /// The offset used to center the drawing area
- Point offset;
-
- /// The window
- SDL_Surface *window;
- };
- }
- }
-}
-
-#endif
+++ /dev/null
-// $Id: color.cpp 5063 2007-05-27 11:32:00Z matzeb $
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#include <config.h>
-
-#include "color.hpp"
-
-const Color Color::BLACK(0.0, 0.0, 0.0);
-const Color Color::RED(1.0, 0.0, 0.0);
-const Color Color::GREEN(0.0, 1.0, 0.0);
-const Color Color::BLUE(0.0, 0.0, 1.0);
-const Color Color::CYAN(0.0, 1.0, 1.0);
-const Color Color::MAGENTA(1.0, 0.0, 1.0);
-const Color Color::YELLOW(1.0, 1.0, 0.0);
-const Color Color::WHITE(1.0, 1.0, 1.0);
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de> //
-// 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.
-
-#ifndef __COLOR_HPP__
-#define __COLOR_HPP__
-
-#include <vector>
-#include <assert.h>
-#include "log.hpp"
-
-#include <unison/video/Color.hpp>
-
-class Color
-{
-public:
- Color()
- : red(0), green(0), blue(0), alpha(1.0)
- { }
- Color(float red, float green, float blue, float alpha = 1.0)
- : red(red), green(green), blue(blue), alpha(alpha)
- {
-#ifdef DEBUG
- check_color_ranges();
-#endif
- }
- Color(const std::vector<float>& vals)
- {
- assert(vals.size() >= 3);
- red = vals[0];
- green = vals[1];
- blue = vals[2];
- if(vals.size() > 3)
- alpha = vals[3];
- else
- alpha = 1.0;
-#ifdef DEBUG
- check_color_ranges();
-#endif
- }
-
- bool operator==(const Color& other) const
- {
- return red == other.red && green == other.green && blue == other.blue
- && alpha == other.alpha;
- }
-
- void check_color_ranges()
- {
- if(red < 0 || red > 1.0 || green < 0 || green > 1.0
- || blue < 0 || blue > 1.0
- || alpha < 0 || alpha > 1.0)
- log_warning << "color value out of range: " << red << ", " << green << ", " << blue << ", " << alpha << std::endl;
- }
-
- float greyscale() const
- {
- return red * 0.30 + green * 0.59 + blue * 0.11;
- }
-
- bool operator < (const Color& other) const
- {
- return greyscale() < other.greyscale();
- }
-
- Unison::Video::Color to_unison_color() const
- {
- Unison::Video::Color color;
- color.red = (unsigned char) (red * 0xff);
- color.green = (unsigned char) (green * 0xff);
- color.blue =(unsigned char) (blue * 0xff);
- color.alpha = (unsigned char) (alpha * 0xff);
- return color;
- }
-
- float red, green, blue, alpha;
-
- static const Color BLACK;
- static const Color RED;
- static const Color GREEN;
- static const Color BLUE;
- static const Color CYAN;
- static const Color MAGENTA;
- static const Color YELLOW;
- static const Color WHITE;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#include <config.h>
-
-#include <functional>
-#include <algorithm>
-#include <cassert>
-#include <iostream>
-//#include <SDL_image.h>
-#include <sstream>
-#include <iomanip>
-#include <physfs.h>
-
-#include "drawing_context.hpp"
-//#include "drawing_request.hpp"
-//#include "video_systems.hpp"
-//#include "renderer.hpp"
-//#include "lightmap.hpp"
-#include "surface.hpp"
-#include "main.hpp"
-#include "gameconfig.hpp"
-//#include "texture.hpp"
-//#include "texture_manager.hpp"
-//#include "obstack/obstackpp.hpp"
-
-#include "math/vector.hpp"
-#include "math/rect.hpp"
-
-#include <unison/video/Renderers.hpp>
-
-/*static inline int next_po2(int val)
-{
- int result = 1;
- while(result < val)
- result *= 2;
-
- return result;
-}*/
-
-DrawingContext::DrawingContext()
- /*renderer(0), lightmap(0), ambient_color(1.0f, 1.0f, 1.0f, 1.0f), target(NORMAL), screenshot_requested(false)*/
-{
- ambient_color = Color(1.0f, 1.0f, 1.0f, 1.0f);
- target = NORMAL;
- screenshot_requested = false;
- draw_target = &normal_list;
- /*requests = &drawing_requests;
- obstack_init(&obst);*/
-}
-
-DrawingContext::~DrawingContext()
-{
- /*delete renderer;
- delete lightmap;
-
- obstack_free(&obst, NULL);*/
-}
-
-void
-DrawingContext::init_renderer()
-{
- Unison::Video::Renderers::get().set_renderer(config->video);
- Unison::Video::Window::get().set_logical_size(Unison::Video::Area(SCREEN_WIDTH, SCREEN_HEIGHT));
- Unison::Video::Window::get().open(Unison::Video::Area(config->screenwidth, config->screenheight), config->use_fullscreen);
- lightmap = Unison::Video::Surface(Unison::Video::Area(SCREEN_WIDTH, SCREEN_HEIGHT));
- /*delete renderer;
- delete lightmap;
-
- renderer = new_renderer();
- lightmap = new_lightmap();*/
-}
-
-void
-DrawingContext::draw_surface(const Surface* surface, const Vector& position,
- float angle, const Color& color, const Blend& blend,
- int layer)
-{
- assert(surface != 0);
-
- Unison::Video::RenderOptions options;
- options.color = color.to_unison_color();
- options.alpha = (unsigned char) transform.alpha * 0xff;
- options.blend = blend.to_unison_blend();
- options.h_flip = surface->get_flipx() != (transform.drawing_effect == HORIZONTAL_FLIP);
- options.v_flip = (transform.drawing_effect == VERTICAL_FLIP);
-
- Vector transformed = transform.apply(position);
- Unison::Video::Point dst_pos((int) transformed.x, (int) transformed.y);
-
- (*draw_target)[layer].blit_section(surface->get_texture(), dst_pos, options);
-
- /*DrawingRequest* request = new(obst) DrawingRequest();
-
- request->target = target;
- request->type = SURFACE;
- request->pos = transform.apply(position);
-
- if(request->pos.x >= SCREEN_WIDTH || request->pos.y >= SCREEN_HEIGHT
- || request->pos.x + surface->get_width() < 0
- || request->pos.y + surface->get_height() < 0)
- return;
-
- request->layer = layer;
- request->drawing_effect = transform.drawing_effect;
- request->alpha = transform.alpha;
- request->angle = angle;
- request->color = color;
- request->blend = blend;
-
- request->request_data = const_cast<Surface*> (surface);
-
- requests->push_back(request);*/
-}
-
-void
-DrawingContext::draw_surface(const Surface* surface, const Vector& position,
- int layer)
-{
- draw_surface(surface, position, 0.0f, Color(1.0f, 1.0f, 1.0f), Blend(), layer);
-}
-
-void
-DrawingContext::draw_surface_part(const Surface* surface, const Vector& source,
- const Vector& size, const Vector& dest, int layer)
-{
- assert(surface != 0);
-
- Unison::Video::TextureSection texture = surface->get_texture();
- texture.clip_rect.pos.x += (int) source.x;
- texture.clip_rect.pos.y += (int) source.y;
- texture.clip_rect.size.x += (unsigned int) size.x;
- texture.clip_rect.size.y += (unsigned int) size.y;
-
- Unison::Video::RenderOptions options;
- options.alpha = (unsigned char) transform.alpha * 0xff;
- options.h_flip = surface->get_flipx() != (transform.drawing_effect == HORIZONTAL_FLIP);
- options.v_flip = (transform.drawing_effect == VERTICAL_FLIP);
-
- Vector transformed = transform.apply(dest);
- Unison::Video::Point dst_pos((int) transformed.x, (int) transformed.y);
-
- (*draw_target)[layer].blit_section(texture, dst_pos, options);
-
- /*DrawingRequest* request = new(obst) DrawingRequest();
-
- request->target = target;
- request->type = SURFACE_PART;
- request->pos = transform.apply(dest);
- request->layer = layer;
- request->drawing_effect = transform.drawing_effect;
- request->alpha = transform.alpha;
-
- SurfacePartRequest* surfacepartrequest = new(obst) SurfacePartRequest();
- surfacepartrequest->size = size;
- surfacepartrequest->source = source;
- surfacepartrequest->surface = surface;
-
- // clip on screen borders
- if(request->pos.x < 0) {
- surfacepartrequest->size.x += request->pos.x;
- if(surfacepartrequest->size.x <= 0)
- return;
- surfacepartrequest->source.x -= request->pos.x;
- request->pos.x = 0;
- }
- if(request->pos.y < 0) {
- surfacepartrequest->size.y += request->pos.y;
- if(surfacepartrequest->size.y <= 0)
- return;
- surfacepartrequest->source.y -= request->pos.y;
- request->pos.y = 0;
- }
- request->request_data = surfacepartrequest;
-
- requests->push_back(request);*/
-}
-
-void
-DrawingContext::draw_text(const Font* font, const std::string& text,
- const Vector& position, FontAlignment alignment, int layer)
-{
- font->draw((*draw_target)[layer], text, transform.apply(position),
- alignment, transform.drawing_effect, transform.alpha);
-
- /*DrawingRequest* request = new(obst) DrawingRequest();
-
- request->target = target;
- request->type = TEXT;
- request->pos = transform.apply(position);
- request->layer = layer;
- request->drawing_effect = transform.drawing_effect;
- request->alpha = transform.alpha;
-
- TextRequest* textrequest = new(obst) TextRequest();
- textrequest->font = font;
- textrequest->text = text;
- textrequest->alignment = alignment;
- request->request_data = textrequest;
-
- requests->push_back(request);*/
-}
-
-void
-DrawingContext::draw_center_text(const Font* font, const std::string& text,
- const Vector& position, int layer)
-{
- draw_text(font, text, Vector(position.x + SCREEN_WIDTH/2, position.y),
- ALIGN_CENTER, layer);
-}
-
-namespace
-{
- class GradientRequest : public Unison::Video::DisplayList::Request
- {
- public:
- GradientRequest(const Color &top, const Color &bottom) :
- top(top),
- bottom(bottom)
- {
- }
-
- void do_request(Unison::Video::Blittable *dst) const
- {
- for(int y = 0;y < SCREEN_HEIGHT;++y)
- {
- Unison::Video::Color color;
- color.red = (Uint8)((((float)(top.red-bottom.red)/(0-SCREEN_HEIGHT)) * y + top.red) * 255);
- color.green = (Uint8)((((float)(top.green-bottom.green)/(0-SCREEN_HEIGHT)) * y + top.green) * 255);
- color.green = (Uint8)((((float)(top.blue-bottom.blue)/(0-SCREEN_HEIGHT)) * y + top.blue) * 255);
- color.alpha = (Uint8)((((float)(top.alpha-bottom.alpha)/(0-SCREEN_HEIGHT)) * y + top.alpha) * 255);
- dst->fill(color, Unison::Video::Rect(0, y, SCREEN_WIDTH, 1));
- }
- }
- private:
- Color top;
- Color bottom;
- };
-}
-
-void
-DrawingContext::draw_gradient(const Color& top, const Color& bottom, int layer)
-{
- (*draw_target)[layer].add_request(new GradientRequest(top, bottom));
-
- /*DrawingRequest* request = new(obst) DrawingRequest();
-
- request->target = target;
- request->type = GRADIENT;
- request->pos = Vector(0,0);
- request->layer = layer;
-
- request->drawing_effect = transform.drawing_effect;
- request->alpha = transform.alpha;
-
- GradientRequest* gradientrequest = new(obst) GradientRequest();
- gradientrequest->top = top;
- gradientrequest->bottom = bottom;
- request->request_data = gradientrequest;
-
- requests->push_back(request);*/
-}
-
-void
-DrawingContext::draw_filled_rect(const Vector& topleft, const Vector& size,
- const Color& color, int layer)
-{
- Vector transformed = transform.apply(topleft);
-
- Unison::Video::Rect rect;
- rect.pos = Unison::Video::Point((int) transformed.x, (int) transformed.y);
- rect.size.x = (unsigned int) size.x;
- rect.size.y = (unsigned int) size.y;
-
- (*draw_target)[layer].fill_blend(color.to_unison_color(), rect);
-
- /*DrawingRequest* request = new(obst) DrawingRequest();
-
- request->target = target;
- request->type = FILLRECT;
- request->pos = transform.apply(topleft);
- request->layer = layer;
-
- request->drawing_effect = transform.drawing_effect;
- request->alpha = transform.alpha;
-
- FillRectRequest* fillrectrequest = new(obst) FillRectRequest();
- fillrectrequest->size = size;
- fillrectrequest->color = color;
- fillrectrequest->color.alpha = color.alpha * transform.alpha;
- request->request_data = fillrectrequest;
-
- requests->push_back(request);*/
-}
-
-void
-DrawingContext::draw_filled_rect(const Rect& rect, const Color& color,
- int layer)
-{
- Vector transformed = transform.apply(rect.p1);
-
- Unison::Video::Rect unison_rect;
- unison_rect.pos.x = (int) transformed.x;
- unison_rect.pos.y = (int) transformed.y;
- unison_rect.size.x = (unsigned int) rect.get_width();
- unison_rect.size.y = (unsigned int) rect.get_height();
-
- (*draw_target)[layer].fill_blend(color.to_unison_color(), unison_rect);
-
- /*DrawingRequest* request = new(obst) DrawingRequest();
-
- request->target = target;
- request->type = FILLRECT;
- request->pos = transform.apply(rect.p1);
- request->layer = layer;
-
- request->drawing_effect = transform.drawing_effect;
- request->alpha = transform.alpha;
-
- FillRectRequest* fillrectrequest = new(obst) FillRectRequest;
- fillrectrequest->size = Vector(rect.get_width(), rect.get_height());
- fillrectrequest->color = color;
- fillrectrequest->color.alpha = color.alpha * transform.alpha;
- request->request_data = fillrectrequest;
-
- requests->push_back(request);*/
-}
-
-void
-DrawingContext::get_light(const Vector& position, Color* color)
-{
- if( ambient_color.red == 1.0f && ambient_color.green == 1.0f
- && ambient_color.blue == 1.0f ) {
- *color = Color( 1.0f, 1.0f, 1.0f);
- return;
- }
-
- /*DrawingRequest* request = new(obst) DrawingRequest();
- request->target = target;
- request->type = GETLIGHT;
- request->pos = transform.apply(position);*/
-
- //There is no light offscreen.
- if(position.x >= SCREEN_WIDTH || position.y >= SCREEN_HEIGHT
- || position.x < 0 || position.y < 0){
- *color = Color( 0, 0, 0);
- return;
- }
-
- Vector transformed = transform.apply(position);
- Unison::Video::Point pos((int) transformed.x, (int) transformed.y);
- get_light_requests.push_back(std::make_pair(pos, color));
-
- /*request->layer = LAYER_GUI; //make sure all get_light requests are handled last.
- GetLightRequest* getlightrequest = new(obst) GetLightRequest();
- getlightrequest->color_ptr = color;
- request->request_data = getlightrequest;
- lightmap_requests.push_back(request);*/
-}
-
-void
-DrawingContext::do_drawing()
-{
-#ifdef DEBUG
- assert(transformstack.empty());
- assert(target_stack.empty());
-#endif
- transformstack.clear();
- target_stack.clear();
-
- //Use Lightmap if ambient color is not white.
- bool use_lightmap = ( ambient_color.red != 1.0f || ambient_color.green != 1.0f ||
- ambient_color.blue != 1.0f );
-
- // PART1: create lightmap
- if(use_lightmap) {
- lightmap.fill(ambient_color.to_unison_color());
- lightmap.draw(lightmap_list);
- //lightmap->start_draw(ambient_color);
- //handle_drawing_requests(lightmap_requests);
- //lightmap->end_draw();
- }
-
- Unison::Video::Window::get().draw(normal_list);
-
- //handle_drawing_requests(drawing_requests);
- if(use_lightmap) {
- Unison::Video::Window::get().blit(lightmap, Unison::Video::Point(), Unison::Video::Rect(), Unison::Video::BLEND_MOD);
- //lightmap->do_draw();
- }
- //obstack_free(&obst, NULL);
- //obstack_init(&obst);
-
- // if a screenshot was requested, take one
- if (screenshot_requested) {
- // FIXME renderer->do_take_screenshot();
- screenshot_requested = false;
- }
-
- //renderer->flip();
- Unison::Video::Window::get().flip();
-
- normal_list.clear();
- lightmap_list.clear();
-}
-
-/*class RequestPtrCompare
- : public std::binary_function<const DrawingRequest*,
- std::vector<std::pair<Unison::Video::Point, Color *> > get_light_requests;
- const DrawingRequest*,
- bool>
-{
-public:
- bool operator()(const DrawingRequest* r1, const DrawingRequest* r2) const
- {
- return *r1 < *r2;
- }
-};
-
-void
-DrawingContext::handle_drawing_requests(DrawingRequests& requests)
-{
- std::stable_sort(requests.begin(), requests.end(), RequestPtrCompare());
-
- DrawingRequests::const_iterator i;
- for(i = requests.begin(); i != requests.end(); ++i) {
- const DrawingRequest& request = **i;
-
- switch(request.target) {
- case NORMAL:
- switch(request.type) {
- case SURFACE:
- renderer->draw_surface(request);
- break;
- case SURFACE_PART:
- renderer->draw_surface_part(request);
- break;
- case GRADIENT:
- renderer->draw_gradient(request);
- break;
- case TEXT:
- {
- const TextRequest* textrequest = (TextRequest*) request.request_data;
- textrequest->font->draw(renderer, textrequest->text, request.pos,
- textrequest->alignment, request.drawing_effect, request.alpha);
- }
- break;
- case FILLRECT:
- renderer->draw_filled_rect(request);
- break;
- case GETLIGHT:
- lightmap->get_light(request);
- break;
- }
- break;
- case LIGHTMAP:
- switch(request.type) {
- case SURFACE:
- lightmap->draw_surface(request);
- break;
- case SURFACE_PART:
- lightmap->draw_surface_part(request);
- break;
- case GRADIENT:
- lightmap->draw_gradient(request);
- break;
- case TEXT:
- {
- const TextRequest* textrequest = (TextRequest*) request.request_data;
- textrequest->font->draw(renderer, textrequest->text, request.pos,
- textrequest->alignment, request.drawing_effect, request.alpha);
- }
- break;
- case FILLRECT:
- lightmap->draw_filled_rect(request);
- break;
- case GETLIGHT:
- lightmap->get_light(request);
- break;
- }
- break;
- }
- }
- requests.clear();
-}*/
-
-void
-DrawingContext::push_transform()
-{
- transformstack.push_back(transform);
-}
-
-void
-DrawingContext::pop_transform()
-{
- assert(!transformstack.empty());
-
- transform = transformstack.back();
- transformstack.pop_back();
-}
-
-void
-DrawingContext::set_drawing_effect(DrawingEffect effect)
-{
- transform.drawing_effect = effect;
-}
-
-DrawingEffect
-DrawingContext::get_drawing_effect() const
-{
- return transform.drawing_effect;
-}
-
-void
-DrawingContext::set_alpha(float alpha)
-{
- transform.alpha = alpha;
-}
-
-float
-DrawingContext::get_alpha() const
-{
- return transform.alpha;
-}
-
-void
-DrawingContext::push_target()
-{
- target_stack.push_back(target);
-}
-
-void
-DrawingContext::pop_target()
-{
- set_target(target_stack.back());
- target_stack.pop_back();
-}
-
-void
-DrawingContext::set_target(Target target)
-{
- this->target = target;
- if(target == LIGHTMAP) {
- draw_target = &lightmap_list;
- } else {
- assert(target == NORMAL);
- draw_target = &normal_list;
- }
-}
-
-void
-DrawingContext::set_ambient_color( Color new_color )
-{
- ambient_color = new_color;
-}
-
-void
-DrawingContext::take_screenshot()
-{
- screenshot_requested = true;
-}
-
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#ifndef SUPERTUX_DRAWINGCONTEXT_H
-#define SUPERTUX_DRAWINGCONTEXT_H
-
-#include <vector>
-#include <string>
-#include <memory>
-
-//#include <stdint.h>
-
-//#include "obstack/obstack.h"
-//#include "math/vector.hpp"
-//#include "math/rect.hpp"
-#include "drawing_request.hpp"
-#include "font.hpp"
-#include "color.hpp"
-
-#include <unison/video/Texture.hpp>
-#include <unison/video/Window.hpp>
-#include <unison/video/DisplayList.hpp>
-
-class Vector;
-class Rect;
-
-class Surface;
-/*class Texture;
-struct DrawingRequest;
-class Renderer;
-class Lightmap;*/
-
-/**
- * This class provides functions for drawing things on screen. It also
- * maintains a stack of transforms that are applied to graphics.
- */
-class DrawingContext
-{
-public:
- DrawingContext();
- ~DrawingContext();
-
- void init_renderer();
-
- /// Adds a drawing request for a surface into the request list.
- void draw_surface(const Surface* surface, const Vector& position,
- int layer);
- /// Adds a drawing request for a surface into the request list.
- void draw_surface(const Surface* surface, const Vector& position,
- float angle, const Color& color, const Blend& blend,
- int layer);
- /// Adds a drawing request for part of a surface.
- void draw_surface_part(const Surface* surface, const Vector& source,
- const Vector& size, const Vector& dest, int layer);
- /// Draws a text.
- void draw_text(const Font* font, const std::string& text,
- const Vector& position, FontAlignment alignment, int layer);
-
- /// Draws text on screen center (feed Vector.x with a 0).
- /// This is the same as draw_text() with a SCREEN_WIDTH/2 position and
- /// alignment set to LEFT_ALLIGN
- void draw_center_text(const Font* font, const std::string& text,
- const Vector& position, int layer);
- /// Draws a color gradient onto the whole screen */
- void draw_gradient(const Color& from, const Color& to, int layer);
- /// Fills a rectangle.
- void draw_filled_rect(const Vector& topleft, const Vector& size,
- const Color& color, int layer);
- void draw_filled_rect(const Rect& rect, const Color& color, int layer);
-
- /// Processes all pending drawing requests and flushes the list.
- void do_drawing();
-
- const Vector& get_translation() const
- { return transform.translation; }
-
- void set_translation(const Vector& newtranslation)
- { transform.translation = newtranslation; }
-
- void push_transform();
- void pop_transform();
-
- /// Apply that effect in the next draws (effects are listed on surface.h).
- void set_drawing_effect(DrawingEffect effect);
- /// return currently applied drawing effect
- DrawingEffect get_drawing_effect() const;
- /// apply that alpha in the next draws (1.0 means fully opaque) */
- void set_alpha(float alpha);
- /// return currently set alpha
- float get_alpha() const;
-
- /// on next update, set color to lightmap's color at position
- void get_light(const Vector& position, Color* color );
-
- typedef ::Target Target;
- static const Target NORMAL = ::NORMAL;
- static const Target LIGHTMAP = ::LIGHTMAP;
- void push_target();
- void pop_target();
- void set_target(Target target);
-
- void set_ambient_color( Color new_color );
-
- /**
- * requests that a screenshot be taken after the next frame has been rendered
- */
- void take_screenshot();
-
-private:
- class Transform
- {
- public:
- Vector translation;
- DrawingEffect drawing_effect;
- float alpha;
-
- Transform()
- : drawing_effect(NO_EFFECT), alpha(1.0f)
- { }
-
- Vector apply(const Vector& v) const
- {
- return v - translation;
- }
- };
-
- Unison::Video::Surface lightmap;
- std::vector<std::pair<Unison::Video::Point, Color *> > get_light_requests;
-
- std::map<int, Unison::Video::DisplayList> normal_list;
- std::map<int, Unison::Video::DisplayList> lightmap_list;
- std::map<int, Unison::Video::DisplayList> *draw_target;
-
- //Renderer *renderer;
- //Lightmap *lightmap;
-
- /// the transform stack
- std::vector<Transform> transformstack;
- /// the currently active transform
- Transform transform;
-
- std::vector<Blend> blend_stack;
- Blend blend_mode;
-
- /*typedef std::vector<DrawingRequest*> DrawingRequests;
-
- void handle_drawing_requests(DrawingRequests& requests);
-
- DrawingRequests drawing_requests;
- DrawingRequests lightmap_requests;
-
- DrawingRequests* requests;*/
- Color ambient_color;
-
- Target target;
- std::vector<Target> target_stack;
-
- /* obstack holding the memory of the drawing requests */
- //struct obstack obst;
-
- bool screenshot_requested; /**< true if a screenshot should be taken after the next frame has been rendered */
-};
-
-#endif
-
+++ /dev/null
-// $Id: drawing_request.hpp 4986 2007-04-16 17:48:28Z matzeb $
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#ifndef SUPERTUX_DRAWINGREQUEST_H
-#define SUPERTUX_DRAWINGREQUEST_H
-
-#include <vector>
-#include <string>
-#include <memory>
-
-#include <assert.h>
-
-//#include <stdint.h>
-
-//#include <SDL_video.h>
-
-#include "glutil.hpp"
-//#include "math/vector.hpp"
-//#include "color.hpp"
-//#include "font.hpp"
-#include <unison/video/RenderOptions.hpp>
-
-class Surface;
-
-// some constants for predefined layer values
-enum {
- LAYER_BACKGROUND0 = -300,
- LAYER_BACKGROUND1 = -200,
- LAYER_BACKGROUNDTILES = -100,
- LAYER_TILES = 0,
- LAYER_OBJECTS = 50,
- LAYER_FLOATINGOBJECTS = 150,
- LAYER_FOREGROUNDTILES = 200,
- LAYER_FOREGROUND0 = 300,
- LAYER_FOREGROUND1 = 400,
- LAYER_HUD = 500,
- LAYER_GUI = 600
-};
-
-class Blend
-{
-public:
- GLenum sfactor;
- GLenum dfactor;
-
- Blend()
- : sfactor(GL_SRC_ALPHA), dfactor(GL_ONE_MINUS_SRC_ALPHA)
- {}
-
- Blend(GLenum s, GLenum d)
- : sfactor(s), dfactor(d)
- {}
-
- Unison::Video::BlendMode to_unison_blend() const
- {
- if(sfactor == GL_ONE && dfactor == GL_ZERO)
- {
- return Unison::Video::BLEND_NONE;
- }
- else if(sfactor == GL_SRC_ALPHA && dfactor == GL_ONE_MINUS_SRC_ALPHA)
- {
- return Unison::Video::BLEND_ALPHA;
- }
- else if(sfactor == GL_SRC_ALPHA && dfactor == GL_ONE)
- {
- return Unison::Video::BLEND_ADD;
- }
- else if(sfactor == GL_ZERO && dfactor == GL_SRC_COLOR)
- {
- return Unison::Video::BLEND_MOD;
- }
- else
- {
- assert(0 && "Unsupported blend factors");
- }
- }
-};
-
-enum Target {
- NORMAL, LIGHTMAP
-};
-
-/*enum RequestType
-{
- SURFACE, SURFACE_PART, TEXT, GRADIENT, FILLRECT, GETLIGHT
-};
-
-struct SurfacePartRequest
-{
- const Surface* surface;
- Vector source, size;
-};
-
-struct TextRequest
-{
- const Font* font;
- std::string text;
- FontAlignment alignment;
-};
-
-struct GradientRequest
-{
- Color top, bottom;
- Vector size;
-};
-
-struct FillRectRequest
-{
- Color color;
- Vector size;
-};
-
-struct DrawingRequest
-{
- Target target;
- RequestType type;
- Vector pos;
-
- int layer;
- DrawingEffect drawing_effect;
- float alpha;
- Blend blend;
- float angle;
- Color color;
-
- void* request_data;
-
- DrawingRequest()
- : angle(0.0f),
- color(1.0f, 1.0f, 1.0f, 1.0f)
- {}
-
- bool operator<(const DrawingRequest& other) const
- {
- return layer < other.layer;
- }
-};
-
-struct GetLightRequest
-{
- Color* color_ptr;
-};*/
-
-#endif
-
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-// Ingo Ruhnke <grumbel@gmx.de>
-//
-// 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.
-
-#include <config.h>
-
-#include <cstdlib>
-#include <cstring>
-#include <stdexcept>
-
-#include <SDL_image.h>
-#include "physfs/physfs_sdl.hpp"
-
-#include "lisp/parser.hpp"
-#include "lisp/lisp.hpp"
-#include "screen.hpp"
-#include "font.hpp"
-//#include "renderer.hpp"
-#include <unison/video/Blittable.hpp>
-#include "drawing_context.hpp"
-#include "log.hpp"
-
-namespace {
-bool has_multibyte_mark(unsigned char c);
-uint32_t decode_utf8(const std::string& text, size_t& p);
-
-struct UTF8Iterator
-{
- const std::string& text;
- std::string::size_type pos;
- uint32_t chr;
-
- UTF8Iterator(const std::string& text_)
- : text(text_),
- pos(0)
- {
- chr = decode_utf8(text, pos);
- }
-
- bool done() const
- {
- return pos > text.size();
- }
-
- UTF8Iterator& operator++() {
- try {
- chr = decode_utf8(text, pos);
- } catch (std::runtime_error) {
- log_debug << "Malformed utf-8 sequence beginning with " << *((uint32_t*)(text.c_str() + pos)) << " found " << std::endl;
- chr = 0;
- ++pos;
- }
-
- return *this;
- }
-
- uint32_t operator*() const {
- return chr;
- }
-};
-
-bool vline_empty(SDL_Surface* surface, int x, int start_y, int end_y, Uint8 threshold)
-{
- Uint8* pixels = (Uint8*)surface->pixels;
-
- for(int y = start_y; y < end_y; ++y)
- {
- const Uint8& p = pixels[surface->pitch*y + x*surface->format->BytesPerPixel + 3];
- if (p > threshold)
- {
- return false;
- }
- }
- return true;
-}
-} // namespace
-
-Font::Font(GlyphWidth glyph_width_,
- const std::string& filename,
- const std::string& shadowfile,
- int char_width, int char_height_,
- int shadowsize_)
- : glyph_width(glyph_width_),
- glyph_surface(0), shadow_glyph_surface(0),
- char_height(char_height_),
- shadowsize(shadowsize_)
-{
- glyph_surface = new Surface(filename);
- shadow_glyph_surface = new Surface(shadowfile);
-
- first_char = 32;
- char_count = ((int) glyph_surface->get_height() / char_height) * 16;
-
- if (glyph_width == FIXED)
- {
- for(uint32_t i = 0; i < char_count; ++i)
- {
- float x = (i % 16) * char_width;
- float y = (i / 16) * char_height;
-
- Glyph glyph;
- glyph.advance = char_width;
- glyph.offset = Vector(0, 0);
- glyph.rect = Rect(x, y, x + char_width, y + char_height);
-
- glyphs.push_back(glyph);
- shadow_glyphs.push_back(glyph);
- }
- }
- else // glyph_width == VARIABLE
- {
- // Load the surface into RAM and scan the pixel data for characters
- SDL_Surface* surface = IMG_Load_RW(get_physfs_SDLRWops(filename), 1);
- if(surface == NULL) {
- std::ostringstream msg;
- msg << "Couldn't load image '" << filename << "' :" << SDL_GetError();
- throw std::runtime_error(msg.str());
- }
-
- SDL_LockSurface(surface);
-
- for(uint32_t i = 0; i < char_count; ++i)
- {
- int x = (i % 16) * char_width;
- int y = (i / 16) * char_height;
-
- int left = x;
- while (left < x + char_width &&
- vline_empty(surface, left, y, y + char_height, 64))
- left += 1;
-
- int right = x + char_width - 1;
- while (right > left &&
- vline_empty(surface, right, y, y + char_height, 64))
- right -= 1;
-
- Glyph glyph;
- glyph.offset = Vector(0, 0);
-
- if (left <= right)
- glyph.rect = Rect(left, y, right+1, y + char_height);
- else // glyph is completly transparent
- glyph.rect = Rect(x, y, x + char_width, y + char_height);
-
- glyph.advance = glyph.rect.get_width() + 1; // FIXME: might be usefull to make spacing configurable
-
- glyphs.push_back(glyph);
- shadow_glyphs.push_back(glyph);
- }
-
- SDL_UnlockSurface(surface);
-
- SDL_FreeSurface(surface);
- }
-}
-
-Font::~Font()
-{
- delete glyph_surface;
- delete shadow_glyph_surface;
-}
-
-float
-Font::get_text_width(const std::string& text) const
-{
- float curr_width = 0;
- float last_width = 0;
-
- for(UTF8Iterator it(text); !it.done(); ++it)
- {
- if (*it == '\n')
- {
- last_width = std::max(last_width, curr_width);
- curr_width = 0;
- }
- else
- {
- int idx = chr2glyph(*it);
- curr_width += glyphs[idx].advance;
- }
- }
-
- return std::max(curr_width, last_width);
-}
-
-float
-Font::get_text_height(const std::string& text) const
-{
- std::string::size_type text_height = char_height;
-
- for(std::string::const_iterator it = text.begin(); it != text.end(); ++it)
- { // since UTF8 multibyte characters are decoded with values
- // outside the ASCII range there is no risk of overlapping and
- // thus we don't need to decode the utf-8 string
- if (*it == '\n')
- text_height += char_height + 2;
- }
-
- return text_height;
-}
-
-float
-Font::get_height() const
-{
- return char_height;
-}
-
-std::string
-Font::wrap_to_chars(const std::string& s, int line_length, std::string* overflow)
-{
- // if text is already smaller, return full text
- if ((int)s.length() <= line_length) {
- if (overflow) *overflow = "";
- return s;
- }
-
- // if we can find a whitespace character to break at, return text up to this character
- int i = line_length;
- while ((i > 0) && (s[i] != ' ')) i--;
- if (i > 0) {
- if (overflow) *overflow = s.substr(i+1);
- return s.substr(0, i);
- }
-
- // FIXME: wrap at line_length, taking care of multibyte characters
- if (overflow) *overflow = "";
- return s;
-}
-
-std::string
-Font::wrap_to_width(const std::string& s, float width, std::string* overflow)
-{
- // if text is already smaller, return full text
- if (get_text_width(s) <= width) {
- if (overflow) *overflow = "";
- return s;
- }
-
- // if we can find a whitespace character to break at, return text up to this character
- for (int i = s.length()-1; i >= 0; i--) {
- std::string s2 = s.substr(0,i);
- if (s[i] != ' ') continue;
- if (get_text_width(s2) <= width) {
- if (overflow) *overflow = s.substr(i+1);
- return s.substr(0, i);
- }
- }
-
- // FIXME: hard-wrap at width, taking care of multibyte characters
- if (overflow) *overflow = "";
- return s;
-}
-
-void
-Font::draw(Unison::Video::Blittable &dst, const std::string& text, const Vector& pos_,
- FontAlignment alignment, DrawingEffect drawing_effect,
- float alpha) const
-{
- float x = pos_.x;
- float y = pos_.y;
-
- std::string::size_type last = 0;
- for(std::string::size_type i = 0;; ++i)
- {
- if (text[i] == '\n' || i == text.size())
- {
- std::string temp = text.substr(last, i - last);
-
- // calculate X positions based on the alignment type
- Vector pos = Vector(x, y);
-
- if(alignment == ALIGN_CENTER)
- pos.x -= get_text_width(temp) / 2;
- else if(alignment == ALIGN_RIGHT)
- pos.x -= get_text_width(temp);
-
- // Cast font position to integer to get a clean drawing result and
- // no bluring as we would get with subpixel positions
- pos.x = static_cast<int>(pos.x);
-
- draw_text(dst, temp, pos, drawing_effect, alpha);
-
- if (i == text.size())
- break;
-
- y += char_height + 2;
- last = i + 1;
- }
- }
-}
-
-void
-Font::draw_text(Unison::Video::Blittable &dst, const std::string& text, const Vector& pos,
- DrawingEffect drawing_effect, float alpha) const
-{
- if(shadowsize > 0)
- {
- // FIXME: shadow_glyph_surface and glyph_surface do currently
- // share the same glyph array, this is incorrect and should be
- // fixed, it is however hardly noticable
- draw_chars(dst, shadow_glyph_surface, text,
- pos + Vector(shadowsize, shadowsize), drawing_effect, alpha);
- }
-
- draw_chars(dst, glyph_surface, text, pos, drawing_effect, alpha);
-}
-
-int
-Font::chr2glyph(uint32_t chr) const
-{
- int glyph_index = chr - first_char;
-
- // we don't have the control chars 0x80-0xa0 in the font
- if (chr >= 0x80) { // non-ascii character
- glyph_index -= 32;
- if(chr <= 0xa0) {
- log_debug << "Unsupported utf-8 character '" << chr << "' found" << std::endl;
- glyph_index = 0;
- }
- }
-
- if(glyph_index < 0 || glyph_index >= (int) char_count) {
- log_debug << "Unsupported utf-8 character found" << std::endl;
- glyph_index = 0;
- }
-
- return glyph_index;
-}
-
-void
-Font::draw_chars(Unison::Video::Blittable &dst, Surface* pchars, const std::string& text,
- const Vector& pos, DrawingEffect drawing_effect,
- float alpha) const
-{
- Vector p = pos;
-
- for(UTF8Iterator it(text); !it.done(); ++it)
- {
- int font_index = chr2glyph(*it);
-
- if(*it == '\n')
- {
- p.x = pos.x;
- p.y += char_height + 2;
- }
- else if(*it == ' ')
- {
- p.x += glyphs[font_index].advance;
- }
- else
- {
- const Glyph& glyph = glyphs[font_index];
-
- assert(pchars != 0);
-
- Unison::Video::TextureSection texture = pchars->get_texture();
- texture.clip_rect.pos.x += (int) glyph.rect.p1.x;
- texture.clip_rect.pos.y += (int) glyph.rect.p1.y;
- texture.clip_rect.size.x += (unsigned int) glyph.rect.get_width();
- texture.clip_rect.size.y += (unsigned int) glyph.rect.get_height();
-
- Unison::Video::RenderOptions options;
- options.alpha = (unsigned char) alpha * 0xff;
- options.h_flip = (drawing_effect == HORIZONTAL_FLIP);
- options.v_flip = (drawing_effect == VERTICAL_FLIP);
-
- Vector transformed = p + glyph.offset;
- Unison::Video::Point dst_pos((int) transformed.x, (int) transformed.y);
-
- dst.blit_section(texture, dst_pos, options);
-
- /*DrawingRequest request;
-
- request.pos = p + glyph.offset;
- request.drawing_effect = drawing_effect;
- request.alpha = alpha;
-
- SurfacePartRequest surfacepartrequest;
- surfacepartrequest.size = glyph.rect.p2 - glyph.rect.p1;
- surfacepartrequest.source = glyph.rect.p1;
- surfacepartrequest.surface = pchars;
-
- request.request_data = &surfacepartrequest;
- renderer->draw_surface_part(request);
-
- p.x += glyphs[font_index].advance;*/
- }
- }
-}
-
-
-namespace {
-
-/**
- * returns true if this byte matches a bitmask of 10xx.xxxx, i.e. it is the 2nd, 3rd or 4th byte of a multibyte utf8 string
- */
-bool has_multibyte_mark(unsigned char c) {
- return ((c & 0300) == 0200);
-}
-
-/**
- * gets unicode character at byte position @a p of UTF-8 encoded @a
- * text, then advances @a p to the next character.
- *
- * @throws std::runtime_error if decoding fails.
- * See unicode standard section 3.10 table 3-5 and 3-6 for details.
- */
-uint32_t decode_utf8(const std::string& text, size_t& p)
-{
- uint32_t c1 = (unsigned char) text[p+0];
-
- if (has_multibyte_mark(c1)) std::runtime_error("Malformed utf-8 sequence");
-
- if ((c1 & 0200) == 0000) {
- // 0xxx.xxxx: 1 byte sequence
- p+=1;
- return c1;
- }
- else if ((c1 & 0340) == 0300) {
- // 110x.xxxx: 2 byte sequence
- if(p+1 >= text.size()) throw std::range_error("Malformed utf-8 sequence");
- uint32_t c2 = (unsigned char) text[p+1];
- if (!has_multibyte_mark(c2)) throw std::runtime_error("Malformed utf-8 sequence");
- p+=2;
- return (c1 & 0037) << 6 | (c2 & 0077);
- }
- else if ((c1 & 0360) == 0340) {
- // 1110.xxxx: 3 byte sequence
- if(p+2 >= text.size()) throw std::range_error("Malformed utf-8 sequence");
- uint32_t c2 = (unsigned char) text[p+1];
- uint32_t c3 = (unsigned char) text[p+2];
- if (!has_multibyte_mark(c2)) throw std::runtime_error("Malformed utf-8 sequence");
- if (!has_multibyte_mark(c3)) throw std::runtime_error("Malformed utf-8 sequence");
- p+=3;
- return (c1 & 0017) << 12 | (c2 & 0077) << 6 | (c3 & 0077);
- }
- else if ((c1 & 0370) == 0360) {
- // 1111.0xxx: 4 byte sequence
- if(p+3 >= text.size()) throw std::range_error("Malformed utf-8 sequence");
- uint32_t c2 = (unsigned char) text[p+1];
- uint32_t c3 = (unsigned char) text[p+2];
- uint32_t c4 = (unsigned char) text[p+4];
- if (!has_multibyte_mark(c2)) throw std::runtime_error("Malformed utf-8 sequence");
- if (!has_multibyte_mark(c3)) throw std::runtime_error("Malformed utf-8 sequence");
- if (!has_multibyte_mark(c4)) throw std::runtime_error("Malformed utf-8 sequence");
- p+=4;
- return (c1 & 0007) << 18 | (c2 & 0077) << 12 | (c3 & 0077) << 6 | (c4 & 0077);
- }
- throw std::runtime_error("Malformed utf-8 sequence");
-}
-
-} // namespace
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>,
-// Ingo Ruhnke <grumbel@gmx.de>
-//
-// 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.
-
-#ifndef SUPERTUX_FONT_H
-#define SUPERTUX_FONT_H
-
-#include <string>
-#include <stdint.h>
-
-#include "video/surface.hpp"
-#include "math/vector.hpp"
-#include "math/rect.hpp"
-
-class Unison::Video::Blittable;
-
-enum FontAlignment {
- ALIGN_LEFT,
- ALIGN_CENTER,
- ALIGN_RIGHT
-};
-
-class Font
-{
-public:
- enum GlyphWidth {
- FIXED,
- VARIABLE
- };
-
- /** Construct a fixed-width font
- *
- * @param glyph_width VARIABLE for proportional fonts, VARIABLE for monospace ones
- * @param filename image file containing the characters
- * @param shadowfile image file containing the characters shadows
- * @param char_width width of a character
- * @param char_height height of a character
- */
- Font(GlyphWidth glyph_width,
- const std::string& filename, const std::string& shadowfile,
- int char_width, int char_height, int shadowsize = 2);
- ~Font();
-
- /** returns the width of a given text. (Note that I won't add a normal
- * get_width function here, as we might switch to variable width fonts in the
- * future.)
- * Supports breaklines.
- */
- float get_text_width(const std::string& text) const;
-
- /** returns the height of a given text. This function supports breaklines.
- * In case, you are positive that your text doesn't use break lines, you can
- * just use get_height().
- */
- float get_text_height(const std::string& text) const;
-
- /**
- * returns the height of the font.
- */
- float get_height() const;
-
- /**
- * returns the given string, truncated (preferrably at whitespace) to be at most max_chars characters long
- */
- static std::string wrap_to_chars(const std::string& text, int max_chars, std::string* overflow);
-
- /**
- * returns the given string, truncated (preferrably at whitespace) to be at most "width" pixels wide
- */
- std::string wrap_to_width(const std::string& text, float width, std::string* overflow);
-
- /** Draws the given text to the screen. Also needs the position.
- * Type of alignment, drawing effect and alpha are optional. */
- void draw(Unison::Video::Blittable &dst, const std::string& text, const Vector& pos,
- FontAlignment allignment = ALIGN_LEFT,
- DrawingEffect drawing_effect = NO_EFFECT,
- float alpha = 1.0f) const;
-
-private:
- friend class DrawingContext;
-
- void draw_text(Unison::Video::Blittable &dst, const std::string& text, const Vector& pos,
- DrawingEffect drawing_effect = NO_EFFECT,
- float alpha = 1.0f) const;
-
- void draw_chars(Unison::Video::Blittable &dst, Surface* pchars, const std::string& text,
- const Vector& position, DrawingEffect drawing_effect,
- float alpha) const;
-
- /** Convert a Unicode character code to the index of its glyph */
- int chr2glyph(uint32_t chr) const;
-
- GlyphWidth glyph_width;
- Surface* glyph_surface;
- Surface* shadow_glyph_surface;
- int char_height;
- int shadowsize;
-
- /// the number of the first character that is represented in the font
- uint32_t first_char;
- /// the number of the last character that is represented in the font
- uint32_t char_count;
-
- struct Glyph {
- /** How many pixels should the cursor advance after printing the
- glyph */
- float advance;
-
- /** Offset that is used when drawing the glyph */
- Vector offset;
-
- /** Position of the glyph inside the surface */
- Rect rect;
- };
-
- /** Location of the characters inside the surface */
- std::vector<Glyph> glyphs;
- std::vector<Glyph> shadow_glyphs;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#ifndef __GLUTIL_HPP__
-#define __GLUTIL_HPP__
-
-typedef unsigned int GLenum;
-typedef int GLint;
-
-#define GL_ZERO 0x0
-#define GL_ONE 0x1
-#define GL_SRC_COLOR 0x0300
-#define GL_SRC_ALPHA 0x0302
-#define GL_ONE_MINUS_SRC_ALPHA 0x0303
-#define GL_DST_COLOR 0x0306
-
-//#include <config.h>
-
-#if 0
-#ifdef HAVE_OPENGL
-
-#include <sstream>
-#include <stdexcept>
-
-#ifndef MACOSX
-#include <GL/gl.h>
-#include <GL/glext.h>
-#else
-#include <OpenGL/gl.h>
-#include <OpenGL/glext.h>
-#endif
-
-static inline void check_gl_error(const char* message)
-{
-#ifdef DEBUG
- GLenum error = glGetError();
- if(error != GL_NO_ERROR) {
- std::ostringstream msg;
- msg << "OpenGLError while '" << message << "': ";
- switch(error) {
- case GL_INVALID_ENUM:
- msg << "INVALID_ENUM: An unacceptable value is specified for an "
- "enumerated argument.";
- break;
- case GL_INVALID_VALUE:
- msg << "INVALID_VALUE: A numeric argument is out of range.";
- break;
- case GL_INVALID_OPERATION:
- msg << "INVALID_OPERATION: The specified operation is not allowed "
- "in the current state.";
- break;
- case GL_STACK_OVERFLOW:
- msg << "STACK_OVERFLOW: This command would cause a stack overflow.";
- break;
- case GL_STACK_UNDERFLOW:
- msg << "STACK_UNDERFLOW: This command would cause a stack underflow.";
- break;
- case GL_OUT_OF_MEMORY:
- msg << "OUT_OF_MEMORY: There is not enough memory left to execute the "
- "command.";
- break;
-#ifdef GL_TABLE_TOO_LARGE
- case GL_TABLE_TOO_LARGE:
- msg << "TABLE_TOO_LARGE: table is too large";
- break;
-#endif
- default:
- msg << "Unknown error (code " << error << ")";
- }
-
- throw std::runtime_error(msg.str());
- }
-#else
- (void) message;
-#endif
-}
-
-static inline void assert_gl(const char* message)
-{
-#ifdef DEBUG
- check_gl_error(message);
-#else
- (void) message;
-#endif
-}
-
-#else
-
-#define GLenum int
-#define GLint int
-#define GL_SRC_ALPHA 0
-#define GL_ONE_MINUS_SRC_ALPHA 1
-#define GL_RGBA 2
-#define GL_ONE 3
-
-#endif
-#endif
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#ifndef __SURFACE_HPP__
-#define __SURFACE_HPP__
-
-#include <config.h>
-
-#include <string>
-#include <SDL.h>
-#include "math/vector.hpp"
-#include "file_system.hpp"
-#include <unison/video/Texture.hpp>
-
-/// bitset for drawing effects
-enum DrawingEffect {
- /** Don't apply anything */
- NO_EFFECT,
- /** Draw the Surface upside down */
- VERTICAL_FLIP,
- /** Draw the Surface from left to down */
- HORIZONTAL_FLIP,
- NUM_EFFECTS
-};
-
-/**
- * A rectangular image.
- * The class basically holds a reference to a texture with additional UV
- * coordinates that specify a rectangular area on this texture
- */
-class Surface
-{
-private:
- Unison::Video::TextureSection texture;
- bool flipx;
-
-public:
- Surface(const std::string& file) :
- texture(FileSystem::normalize(file)),
- flipx(false)
- {
- }
-
- Surface(const std::string& file, int x, int y, int w, int h) :
- texture(FileSystem::normalize(file), Unison::Video::Rect(x, y, w, h)),
- flipx(false)
- {
- }
-
- Surface(const Surface& other) :
- texture(other.texture),
- flipx(false)
- {
- }
-
- ~Surface()
- {
- }
-
- /** flip the surface horizontally */
- void hflip()
- {
- flipx = !flipx;
- }
-
- bool get_flipx() const
- {
- return flipx;
- }
-
- const Surface& operator= (const Surface& other)
- {
- texture = other.texture;
- return *this;
- }
-
- Unison::Video::TextureSection get_texture() const
- {
- return texture;
- }
-
- int get_x() const
- {
- return texture.clip_rect.pos.x;
- }
-
- int get_y() const
- {
- return texture.clip_rect.pos.y;
- }
-
- int get_width() const
- {
- return texture.clip_rect.size.x ? texture.clip_rect.size.x : texture.image.get_size().x;
- }
-
- int get_height() const
- {
- return texture.clip_rect.size.y ? texture.clip_rect.size.y : texture.image.get_size().y;
- }
-
- Vector get_position() const
- { return Vector(get_x(), get_y()); }
-
- /**
- * returns a vector containing width and height
- */
- Vector get_size() const
- { return Vector(get_width(), get_height()); }
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#include <config.h>
-
-#include <stddef.h>
-//#include <physfs.h>
-#include <unison/vfs/FileSystem.hpp>
-#include <stdexcept>
-
-#include "world.hpp"
-#include "file_system.hpp"
-#include "lisp/parser.hpp"
-#include "lisp/lisp.hpp"
-#include "physfs/physfs_stream.hpp"
-#include "scripting/squirrel_util.hpp"
-#include "scripting/serialize.hpp"
-#include "log.hpp"
-#include "worldmap/worldmap.hpp"
-#include "mainloop.hpp"
-
-static bool has_suffix(const std::string& data, const std::string& suffix)
-{
- if (data.length() >= suffix.length())
- return data.compare(data.length() - suffix.length(), suffix.length(), suffix) == 0;
- else
- return false;
-}
-
-World* World::current_ = NULL;
-
-World::World()
-{
- is_levelset = true;
- hide_from_contribs = false;
- sq_resetobject(&world_thread);
-}
-
-World::~World()
-{
- sq_release(Scripting::global_vm, &world_thread);
- if(current_ == this)
- current_ = NULL;
-}
-
-void
-World::set_savegame_filename(const std::string& filename)
-{
- Unison::VFS::FileSystem &fs = Unison::VFS::FileSystem::get();
- this->savegame_filename = filename;
- // make sure the savegame directory exists
- std::string dirname = FileSystem::dirname(filename);
- if(!fs.exists(dirname)) {
- fs.mkdir(dirname);
- /*if(PHYSFS_mkdir(dirname.c_str())) {
- std::ostringstream msg;
- msg << "Couldn't create directory for savegames '"
- << dirname << "': " <<PHYSFS_getLastError();
- throw std::runtime_error(msg.str());
- }*/
- }
-
- if(!fs.is_dir(dirname)) {
- std::ostringstream msg;
- msg << "Savegame path '" << dirname << "' is not a directory";
- throw std::runtime_error(msg.str());
- }
-}
-
-void
-World::load(const std::string& filename)
-{
- basedir = FileSystem::dirname(filename);
-
- lisp::Parser parser;
- const lisp::Lisp* root = parser.parse(filename);
-
- const lisp::Lisp* info = root->get_lisp("supertux-world");
- if(info == NULL)
- info = root->get_lisp("supertux-level-subset");
- if(info == NULL)
- throw std::runtime_error("File is not a world or levelsubset file");
-
- hide_from_contribs = false;
- is_levelset = true;
-
- info->get("title", title);
- info->get("description", description);
- info->get("levelset", is_levelset);
- info->get_vector("levels", levels);
- info->get("hide-from-contribs", hide_from_contribs);
-
- // Level info file doesn't define any levels, so read the
- // directory to see what we can find
-
- std::string path = basedir;
- std::vector<std::string> files = Unison::VFS::FileSystem::get().ls(path);
- for(std::vector<std::string>::iterator iter = files.begin();iter != files.end();++iter)
- {
- if(has_suffix(iter->c_str(), ".stl")) {
- levels.push_back(path + *iter);
- }
- }
- /*char** files = PHYSFS_enumerateFiles(path.c_str());
- if(!files) {
- log_warning << "Couldn't read subset dir '" << path << "'" << std::endl;
- return;
- }
-
- for(const char* const* filename = files; *filename != 0; ++filename) {
- if(has_suffix(*filename, ".stl")) {
- levels.push_back(path + *filename);
- }
- }
- PHYSFS_freeList(files);*/
-}
-
-void
-World::run()
-{
- using namespace Scripting;
-
- current_ = this;
-
- // create new squirrel table for persisten game state
- HSQUIRRELVM vm = Scripting::global_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";
- try {
- IFileStream in(filename);
-
- sq_release(global_vm, &world_thread);
- world_thread = create_thread(global_vm);
- compile_and_run(object_to_vm(world_thread), in, filename);
- } catch(std::exception& ) {
- // fallback: try to load worldmap worldmap.stwm
- using namespace WorldMapNS;
- main_loop->push_screen(new WorldMap(basedir + "worldmap.stwm"));
- }
-}
-
-void
-World::save_state()
-{
- using namespace Scripting;
-
- 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());
- }
-
- writer.start_list("tux");
- player_status->write(writer);
- writer.end_list("tux");
-
- writer.start_list("state");
-
- sq_pushroottable(global_vm);
- sq_pushstring(global_vm, "state", -1);
- if(SQ_SUCCEEDED(sq_get(global_vm, -2))) {
- Scripting::save_squirrel_table(global_vm, -1, writer);
- sq_pop(global_vm, 1);
- }
- sq_pop(global_vm, 1);
- writer.end_list("state");
-
- writer.end_list("supertux-savegame");
-}
-
-void
-World::load_state()
-{
- using namespace Scripting;
-
- try {
- lisp::Parser parser;
- const lisp::Lisp* 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");
-
- sq_pushroottable(global_vm);
- sq_pushstring(global_vm, "state", -1);
- if(SQ_FAILED(sq_deleteslot(global_vm, -2, SQFalse)))
- sq_pop(global_vm, 1);
-
- sq_pushstring(global_vm, "state", -1);
- sq_newtable(global_vm);
- load_squirrel_table(global_vm, -1, state);
- if(SQ_FAILED(sq_createslot(global_vm, -3)))
- throw std::runtime_error("Couldn't create state table");
- sq_pop(global_vm, 1);
- } catch(std::exception& e) {
- log_debug << "Couldn't load savegame: " << e.what() << std::endl;
- }
-}
-
-const std::string&
-World::get_level_filename(unsigned int i) const
-{
- return levels[i];
-}
-
-unsigned int
-World::get_num_levels() const
-{
- return levels.size();
-}
-
-const std::string&
-World::get_basedir() const
-{
- return basedir;
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#ifndef SUPERTUX_WORLD_H
-#define SUPERTUX_WORLD_H
-
-#include <vector>
-#include <string>
-#include <squirrel.h>
-
-class World
-{
-private:
- std::vector<std::string> levels;
- std::string basedir;
- std::string savegame_filename;
- /// squirrel table that saves persistent state (about the world)
- HSQOBJECT state_table;
- HSQOBJECT world_thread;
- static World* current_;
-
-public:
- World();
- ~World();
-
- void set_savegame_filename(const std::string& filename);
- void load(const std::string& filename);
-
- void save_state();
- void load_state();
-
- const std::string& get_level_filename(unsigned int i) const;
- unsigned int get_num_levels() const;
-
- const std::string& get_basedir() const;
-
- static World* current()
- {
- return current_;
- }
-
- void run();
-
- std::string title;
- std::string description;
- bool hide_from_contribs;
- bool is_levelset;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux - Worldmap Direction
-// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
-//
-// 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.
-#ifndef __WORLDMAP_DIRECTION_HPP__
-#define __WORLDMAP_DIRECTION_HPP__
-
-namespace WorldMapNS {
-
-enum Direction { D_NONE, D_WEST, D_EAST, D_NORTH, D_SOUTH };
-
-}
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2004 Ingo Ruhnke <grumbel@gmx.de>
-// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
-//
-// 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.
-#include <config.h>
-
-#include <stddef.h>
-//#include <physfs.h>
-#include "worldmap/level.hpp"
-#include "sprite/sprite_manager.hpp"
-#include "sprite/sprite.hpp"
-#include "video/drawing_context.hpp"
-#include "log.hpp"
-#include "file_system.hpp"
-#include <unison/vfs/FileSystem.hpp>
-
-namespace WorldMapNS
-{
-
-LevelTile::LevelTile(const std::string& basedir, const lisp::Lisp* lisp)
- : solved(false), auto_play(false), basedir(basedir), picture_cached(false),
- picture(0)
-{
- lisp->get("name", name);
- lisp->get("x", pos.x);
- lisp->get("y", pos.y);
- lisp->get("auto-play", auto_play);
-
- std::string spritefile = "images/worldmap/common/leveldot.sprite";
- lisp->get("sprite", spritefile);
- sprite.reset(sprite_manager->create(spritefile));
-
- lisp->get("extro-script", extro_script);
-
- if (!Unison::VFS::FileSystem::get().exists(basedir + name))
- {
- log_warning << "level file '" << name
- << "' does not exist and will not be added to the worldmap" << std::endl;
- return;
- }
-}
-
-LevelTile::~LevelTile()
-{
- delete picture;
-}
-
-void
-LevelTile::draw(DrawingContext& context)
-{
- sprite->draw(context, pos*32 + Vector(16, 16), LAYER_OBJECTS - 1);
-}
-
-void
-LevelTile::update(float )
-{
-}
-
-const Surface*
-LevelTile::get_picture()
-{
- if (picture_cached) return picture;
- picture_cached = true;
- std::string fname = FileSystem::strip_extension(basedir + name)+".jpg";
- if (!Unison::VFS::FileSystem::get().exists(fname)) {
- return 0;
- }
- picture = new Surface(fname);
- return picture;
-}
-
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2004 Ingo Ruhnke <grumbel@gmx.de>
-// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
-//
-// 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.
-#ifndef __LEVEL_TILE_HPP__
-#define __LEVEL_TILE_HPP__
-
-#include <memory>
-#include <string>
-#include "math/vector.hpp"
-#include "game_object.hpp"
-#include "statistics.hpp"
-#include "video/surface.hpp"
-
-class Sprite;
-
-namespace WorldMapNS
-{
-
-class LevelTile : public GameObject
-{
-public:
- LevelTile(const std::string& basedir, const lisp::Lisp* lisp);
- virtual ~LevelTile();
-
- virtual void draw(DrawingContext& context);
- virtual void update(float elapsed_time);
-
- Vector pos;
- std::string title;
- bool solved;
- bool auto_play; /**< true if Tux should automatically enter this level if it's unfinished */
-
- std::auto_ptr<Sprite> sprite;
-
- /** Statistics for level tiles */
- Statistics statistics;
-
- /** Script that is run when the level is successfully finished */
- std::string extro_script;
-
- /** return Surface of level picture or 0 if no picture is available */
- const Surface* get_picture();
-
-private:
- std::string basedir;
- bool picture_cached;
- Surface* picture;
-
-};
-
-}
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux - Worldmap Spawnpoint
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-
-#include <config.h>
-
-#include <stdexcept>
-#include <iostream>
-#include "spawn_point.hpp"
-#include "lisp/lisp.hpp"
-#include "lisp/list_iterator.hpp"
-#include "log.hpp"
-
-namespace WorldMapNS
-{
-
-// from worldmap.cpp
-Direction string_to_direction(const std::string& directory);
-
-SpawnPoint::SpawnPoint(const lisp::Lisp* slisp) : auto_dir(D_NONE)
-{
- pos.x = -1;
- pos.y = -1;
- lisp::ListIterator iter(slisp);
- while(iter.next()) {
- const std::string& token = iter.item();
- if(token == "name") {
- iter.value()->get(name);
- } else if(token == "x") {
- iter.value()->get(pos.x);
- } else if(token == "y") {
- iter.value()->get(pos.y);
- } else if(token == "auto-dir") {
- std::string s = "";
- iter.value()->get(s);
- auto_dir = string_to_direction(s);
- } else {
- log_warning << "unknown token '" << token << "' in SpawnPoint" << std::endl;
- }
- }
-
- if(name == "")
- throw std::runtime_error("No name specified for spawnpoint");
- if(pos.x < 0 || pos.y < 0)
- throw std::runtime_error("Invalid coordinates for spawnpoint");
-}
-
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux - Worldmap Spawnpoint
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#ifndef __WORLDMAP_SPAWN_POINT_H__
-#define __WORLDMAP_SPAWN_POINT_H__
-
-#include <string>
-#include "math/vector.hpp"
-#include "lisp/lisp.hpp"
-#include "game_object.hpp"
-#include "worldmap/direction.hpp"
-
-namespace WorldMapNS
-{
-
-class SpawnPoint
-{
-public:
- SpawnPoint(const lisp::Lisp* lisp);
-
- std::string name;
- Vector pos;
- Direction auto_dir; /**< automatically start walking in this direction */
-};
-
-}
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2004 Ingo Ruhnke <grumbel@gmx.de>
-// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
-//
-// 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.
-#include <config.h>
-
-#include "worldmap/special_tile.hpp"
-#include "sprite/sprite_manager.hpp"
-#include "sprite/sprite.hpp"
-#include "video/drawing_context.hpp"
-
-namespace WorldMapNS
-{
-
-SpecialTile::SpecialTile(const lisp::Lisp* lisp)
- : passive_message(false), invisible(false),
- apply_action_north(true), apply_action_east(true),
- apply_action_south(true), apply_action_west(true)
-{
- lisp->get("x", pos.x);
- lisp->get("y", pos.y);
- lisp->get("invisible-tile", invisible);
-
- if(!invisible) {
- std::string spritefile = "";
- lisp->get("sprite", spritefile);
- sprite.reset(sprite_manager->create(spritefile));
- }
-
- lisp->get("map-message", map_message);
- lisp->get("passive-message", passive_message);
- lisp->get("script", script);
-
- std::string apply_direction;
- lisp->get("apply-to-direction", apply_direction);
- if(!apply_direction.empty()) {
- apply_action_north = false;
- apply_action_south = false;
- apply_action_east = false;
- apply_action_west = false;
- if(apply_direction.find("north") != std::string::npos)
- apply_action_north = true;
- if(apply_direction.find("south") != std::string::npos)
- apply_action_south = true;
- if(apply_direction.find("east") != std::string::npos)
- apply_action_east = true;
- if(apply_direction.find("west") != std::string::npos)
- apply_action_west = true;
- }
-}
-
-SpecialTile::~SpecialTile()
-{
-}
-
-void
-SpecialTile::draw(DrawingContext& context)
-{
- if(invisible)
- return;
-
- sprite->draw(context, pos*32 + Vector(16, 16), LAYER_OBJECTS - 1);
-}
-
-void
-SpecialTile::update(float )
-{
-}
-
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2004 Ingo Ruhnke <grumbel@gmx.de>
-// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
-//
-// 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.
-#ifndef __WORLDMAP_SPECIAL_TILE_HPP__
-#define __WORLDMAP_SPECIAL_TILE_HPP__
-
-#include <memory>
-#include <string>
-#include "game_object.hpp"
-#include "math/vector.hpp"
-#include "lisp/lisp.hpp"
-
-class Sprite;
-
-namespace WorldMapNS
-{
-
-class SpecialTile : public GameObject
-{
-public:
- SpecialTile(const lisp::Lisp* lisp);
- virtual ~SpecialTile();
-
- virtual void draw(DrawingContext& context);
- virtual void update(float elapsed_time);
-
- Vector pos;
-
- /** Sprite to render instead of guessing what image to draw */
- std::auto_ptr<Sprite> sprite;
-
- /** Message to show in the Map */
- std::string map_message;
- bool passive_message;
-
- /** Script to execute when tile is touched */
- std::string script;
-
- /** Hide special tile */
- bool invisible;
-
- /** Only applies actions (ie. passive messages) when going to that direction */
- bool apply_action_north;
- bool apply_action_east;
- bool apply_action_south;
- bool apply_action_west;
-};
-
-}
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#include <config.h>
-
-#include "sprite_change.hpp"
-#include "sprite/sprite_manager.hpp"
-#include "sprite/sprite.hpp"
-#include "video/drawing_context.hpp"
-
-namespace WorldMapNS
-{
-
-SpriteChange::SpriteChange(const lisp::Lisp* lisp)
- : change_on_touch(false), in_stay_action(false)
-{
- lisp->get("x", pos.x);
- lisp->get("y", pos.y);
- lisp->get("change-on-touch", change_on_touch);
-
- std::string spritefile = "";
- lisp->get("sprite", spritefile);
- sprite.reset(sprite_manager->create(spritefile));
-
- lisp->get("stay-action", stay_action);
- lisp->get("initial-stay-action", in_stay_action);
-
- lisp->get("stay-group", stay_group);
-
- all_sprite_changes.push_back(this);
-}
-
-SpriteChange::~SpriteChange()
-{
- all_sprite_changes.remove(this);
-}
-
-void
-SpriteChange::draw(DrawingContext& context)
-{
- if(in_stay_action && stay_action != "") {
- sprite->set_action(stay_action);
- sprite->draw(context, pos * 32, LAYER_OBJECTS-1);
- }
-}
-
-void
-SpriteChange::update(float )
-{
-}
-
-void
-SpriteChange::set_stay_action()
-{
- in_stay_action = true;
-}
-
-void
-SpriteChange::clear_stay_action()
-{
- in_stay_action = false;
-
- // if we are in a stay_group, also clear all stay actions in this group
- if (stay_group != "") {
- for (std::list<SpriteChange*>::iterator i = all_sprite_changes.begin(); i != all_sprite_changes.end(); i++) {
- SpriteChange* sc = *i;
- if (sc->stay_group != stay_group) continue;
- sc->in_stay_action = false;
- }
- }
-}
-
-std::list<SpriteChange*> SpriteChange::all_sprite_changes;
-
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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.
-#ifndef __WORLDMAP_SPRITE_CHANGE_HPP__
-#define __WORLDMAP_SPRITE_CHANGE_HPP__
-
-#include <string>
-#include <memory>
-#include <list>
-#include "game_object.hpp"
-#include "lisp/lisp.hpp"
-#include "math/vector.hpp"
-
-class Sprite;
-
-namespace WorldMapNS
-{
-
-class SpriteChange : public GameObject
-{
-public:
- SpriteChange(const lisp::Lisp* lisp);
- virtual ~SpriteChange();
-
- Vector pos;
- /**
- * should tuxs sprite change when the tile has been completely entered,
- * or already when the tile was just touched
- */
- bool change_on_touch;
- /// sprite to change tux image to
- std::auto_ptr<Sprite> sprite;
- /**
- * stay action can be used for objects like boats or cars, if it is
- * != "" then this sprite will be displayed when tux left the tile towards
- * another SpriteChange object.
- */
- std::string stay_action;
-
- /**
- * name of a group in which only one SpriteChange will ever have its stay_action displayed.
- * Leave empty if you don't care.
- */
- std::string stay_group;
-
- virtual void draw(DrawingContext& context);
- virtual void update(float elapsed_time);
-
- /**
- * Activates the SpriteChange's stay action, if applicable
- */
- void set_stay_action();
-
- /**
- * Deactivates the SpriteChange's stay action, if applicable
- */
- void clear_stay_action();
-
-private:
- /**
- * should the stayaction be displayed
- */
- bool in_stay_action;
-
- static std::list<SpriteChange*> all_sprite_changes;
-
-};
-
-}
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux - Teleporter Worldmap Tile
-// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
-//
-// 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.
-#include <config.h>
-
-#include "worldmap/teleporter.hpp"
-#include "sprite/sprite_manager.hpp"
-#include "sprite/sprite.hpp"
-#include "video/drawing_context.hpp"
-
-namespace WorldMapNS
-{
-
-Teleporter::Teleporter(const lisp::Lisp* lisp)
- : automatic(false)
-{
- lisp->get("x", pos.x);
- lisp->get("y", pos.y);
-
- std::string spritefile = "";
- if (lisp->get("sprite", spritefile)) {
- sprite.reset(sprite_manager->create(spritefile));
- }
-
- lisp->get("worldmap", worldmap);
- lisp->get("spawnpoint", spawnpoint);
- lisp->get("automatic", automatic);
- lisp->get("message", message);
-}
-
-void
-Teleporter::draw(DrawingContext& context)
-{
- if (sprite.get() != 0) sprite->draw(context, pos*32 + Vector(16, 16), LAYER_OBJECTS - 1);
-}
-
-void
-Teleporter::update(float )
-{
-}
-
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux - Teleporter Worldmap Tile
-// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
-//
-// 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.
-#ifndef __WORLDMAP_TELEPORTER_HPP__
-#define __WORLDMAP_TELEPORTER_HPP__
-
-#include <memory>
-#include <string>
-#include "game_object.hpp"
-#include "math/vector.hpp"
-#include "lisp/lisp.hpp"
-
-class Sprite;
-
-namespace WorldMapNS
-{
-
-class Teleporter : public GameObject
-{
-public:
- Teleporter(const lisp::Lisp* lisp);
-
- virtual void draw(DrawingContext& context);
- virtual void update(float elapsed_time);
-
- /** Position (in tiles, not pixels) */
- Vector pos;
-
- /** Sprite to render, or 0 for no sprite */
- std::auto_ptr<Sprite> sprite;
-
- /** Worldmap filename (relative to data root) to teleport to. Leave empty to use current word */
- std::string worldmap;
-
- /** Spawnpoint to teleport to. Leave empty to use "main" or last one */
- std::string spawnpoint;
-
- /** true if this teleporter does not need to be activated, but teleports Tux as soon as it's touched */
- bool automatic;
-
- /** optional map message to display */
- std::string message;
-
-};
-
-}
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux - A Jump'n Run
-// Copyright (C) 2004 Ingo Ruhnke <grumbel@gmx.de>
-// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
-//
-// 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.
-#include <config.h>
-
-#include "tux.hpp"
-#include "sprite/sprite.hpp"
-#include "sprite/sprite_manager.hpp"
-#include "video/drawing_context.hpp"
-#include "player_status.hpp"
-#include "worldmap.hpp"
-#include "worldmap/level.hpp"
-#include "special_tile.hpp"
-#include "sprite_change.hpp"
-#include "control/joystickkeyboardcontroller.hpp"
-#include "scripting/squirrel_util.hpp"
-#include "main.hpp"
-
-namespace WorldMapNS
-{
-
-static const float TUXSPEED = 200;
-static const float map_message_TIME = 2.8f;
-
-Tux::Tux(WorldMap* worldmap_)
- : worldmap(worldmap_)
-{
- sprite.reset(sprite_manager->create("images/worldmap/common/tux.sprite"));
-
- offset = 0;
- moving = false;
- direction = D_NONE;
- input_direction = D_NONE;
-}
-
-Tux::~Tux()
-{
-}
-
-void
-Tux::draw(DrawingContext& context)
-{
- switch (player_status->bonus) {
- case GROWUP_BONUS:
- sprite->set_action(moving ? "large-walking" : "large-stop");
- break;
- case FIRE_BONUS:
- sprite->set_action(moving ? "fire-walking" : "fire-stop");
- break;
- case NO_BONUS:
- sprite->set_action(moving ? "small-walking" : "small-stop");
- break;
- default:
- log_debug << "Bonus type not handled in worldmap." << std::endl;
- sprite->set_action("large-stop");
- break;
- }
-
- sprite->draw(context, get_pos(), LAYER_OBJECTS);
-}
-
-
-Vector
-Tux::get_pos()
-{
- float x = tile_pos.x * 32;
- float y = tile_pos.y * 32;
-
- switch(direction)
- {
- case D_WEST:
- x -= offset - 32;
- break;
- case D_EAST:
- x += offset - 32;
- break;
- case D_NORTH:
- y -= offset - 32;
- break;
- case D_SOUTH:
- y += offset - 32;
- break;
- case D_NONE:
- break;
- }
-
- return Vector(x, y);
-}
-
-void
-Tux::stop()
-{
- offset = 0;
- direction = D_NONE;
- input_direction = D_NONE;
- moving = false;
-}
-
-void
-Tux::set_direction(Direction dir)
-{
- input_direction = dir;
-}
-
-void
-Tux::tryStartWalking()
-{
- if (moving)
- return;
- if (input_direction == D_NONE)
- return;
-
- LevelTile* level = worldmap->at_level();
-
- // We got a new direction, so lets start walking when possible
- Vector next_tile;
- if ((!level || level->solved)
- && worldmap->path_ok(input_direction, tile_pos, &next_tile)) {
- tile_pos = next_tile;
- moving = true;
- direction = input_direction;
- back_direction = reverse_dir(direction);
- } else if (input_direction == back_direction) {
- moving = true;
- direction = input_direction;
- tile_pos = worldmap->get_next_tile(tile_pos, direction);
- back_direction = reverse_dir(direction);
- }
-}
-
-bool
-Tux::canWalk(int tile_data, Direction dir)
-{
- return ((tile_data & Tile::WORLDMAP_NORTH && dir == D_NORTH) ||
- (tile_data & Tile::WORLDMAP_SOUTH && dir == D_SOUTH) ||
- (tile_data & Tile::WORLDMAP_EAST && dir == D_EAST) ||
- (tile_data & Tile::WORLDMAP_WEST && dir == D_WEST));
-}
-
-void
-Tux::tryContinueWalking(float elapsed_time)
-{
- if (!moving)
- return;
-
- // Let tux walk
- offset += TUXSPEED * elapsed_time;
-
- // Do nothing if we have not yet reached the next tile
- if (offset <= 32)
- return;
-
- offset -= 32;
-
- SpriteChange* sprite_change = worldmap->at_sprite_change(tile_pos);
- if(sprite_change != NULL) {
- sprite.reset(new Sprite( *(sprite_change->sprite.get()) ));
- sprite_change->clear_stay_action();
- }
-
- // if this is a special_tile with passive_message, display it
- SpecialTile* special_tile = worldmap->at_special_tile();
- if(special_tile)
- {
- // direction and the apply_action_ are opposites, since they "see"
- // directions in a different way
- if((direction == D_NORTH && special_tile->apply_action_south) ||
- (direction == D_SOUTH && special_tile->apply_action_north) ||
- (direction == D_WEST && special_tile->apply_action_east) ||
- (direction == D_EAST && special_tile->apply_action_west))
- {
- if(special_tile->passive_message) {
- worldmap->passive_message = special_tile->map_message;
- worldmap->passive_message_timer.start(map_message_TIME);
- } else if(special_tile->script != "") {
- try {
- std::istringstream in(special_tile->script);
- worldmap->run_script(in, "specialtile");
- } catch(std::exception& e) {
- log_warning << "Couldn't execute special tile script: " << e.what()
- << std::endl;
- }
- }
- }
- }
-
- // check if we are at a Teleporter
- Teleporter* teleporter = worldmap->at_teleporter(tile_pos);
-
- // stop if we reached a level, a WORLDMAP_STOP tile, a teleporter or a special tile without a passive_message
- if ((worldmap->at_level())
- || (worldmap->tile_data_at(tile_pos) & Tile::WORLDMAP_STOP)
- || (special_tile && !special_tile->passive_message
- && special_tile->script == "")
- || (teleporter)) {
- if(special_tile && !special_tile->map_message.empty()
- && !special_tile->passive_message)
- worldmap->passive_message_timer.start(0);
- stop();
- return;
- }
-
- // if user wants to change direction, try changing, else guess the direction in which to walk next
- const int tile_data = worldmap->tile_data_at(tile_pos);
- if ((direction != input_direction) && canWalk(tile_data, input_direction)) {
- direction = input_direction;
- back_direction = reverse_dir(direction);
- } else {
- Direction dir = D_NONE;
- if (tile_data & Tile::WORLDMAP_NORTH && back_direction != D_NORTH)
- dir = D_NORTH;
- else if (tile_data & Tile::WORLDMAP_SOUTH && back_direction != D_SOUTH)
- dir = D_SOUTH;
- else if (tile_data & Tile::WORLDMAP_EAST && back_direction != D_EAST)
- dir = D_EAST;
- else if (tile_data & Tile::WORLDMAP_WEST && back_direction != D_WEST)
- dir = D_WEST;
-
- if (dir == D_NONE) {
- // Should never be reached if tiledata is good
- log_warning << "Could not determine where to walk next" << std::endl;
- stop();
- return;
- }
-
- direction = dir;
- input_direction = direction;
- back_direction = reverse_dir(direction);
- }
-
- // Walk automatically to the next tile
- if(direction == D_NONE)
- return;
-
- Vector next_tile;
- if (!worldmap->path_ok(direction, tile_pos, &next_tile)) {
- log_debug << "Tilemap data is buggy" << std::endl;
- stop();
- return;
- }
-
- SpriteChange* next_sprite = worldmap->at_sprite_change(next_tile);
- if(next_sprite != NULL && next_sprite->change_on_touch) {
- sprite.reset(new Sprite( *(next_sprite->sprite.get()) ));
- next_sprite->clear_stay_action();
- }
- SpriteChange* last_sprite = worldmap->at_sprite_change(tile_pos);
- if(last_sprite != NULL && next_sprite != NULL) {
- log_debug << "Old: " << tile_pos << " New: " << next_tile << std::endl;
- last_sprite->set_stay_action();
- }
-
- tile_pos = next_tile;
-}
-
-void
-Tux::updateInputDirection()
-{
- if(main_controller->hold(Controller::UP))
- input_direction = D_NORTH;
- else if(main_controller->hold(Controller::DOWN))
- input_direction = D_SOUTH;
- else if(main_controller->hold(Controller::LEFT))
- input_direction = D_WEST;
- else if(main_controller->hold(Controller::RIGHT))
- input_direction = D_EAST;
-}
-
-void
-Tux::update(float elapsed_time)
-{
- updateInputDirection();
- if (moving)
- tryContinueWalking(elapsed_time);
- else
- tryStartWalking();
-}
-
-void
-Tux::setup()
-{
- // check if we already touch a SpriteChange object
- SpriteChange* sprite_change = worldmap->at_sprite_change(tile_pos);
- if(sprite_change != NULL) {
- sprite.reset(new Sprite( *(sprite_change->sprite.get()) ));
- sprite_change->clear_stay_action();
- }
-}
-
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux - A Jump'n Run
-// Copyright (C) 2004 Ingo Ruhnke <grumbel@gmx.de>
-// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
-//
-// 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.
-#ifndef __WORLDMAP_TUX_HPP__
-#define __WORLDMAP_TUX_HPP__
-
-#include <memory>
-#include "game_object.hpp"
-#include "worldmap.hpp"
-
-class Sprite;
-
-namespace WorldMapNS
-{
-
-class WorldMap;
-
-class Tux : public GameObject
-{
-public:
- Direction back_direction;
-private:
- WorldMap* worldmap;
- std::auto_ptr<Sprite> sprite;
- Controller* controller;
-
- Direction input_direction;
- Direction direction;
- Vector tile_pos;
- /** Length by which tux is away from its current tile, length is in
- input_direction direction */
- float offset;
- bool moving;
-
- void stop();
-
- bool canWalk(int tile_data, Direction dir); /**< check if we can leave a tile (with given "tile_data") in direction "dir" */
- void updateInputDirection(); /**< if controller was pressed, update input_direction */
- void tryStartWalking(); /**< try starting to walk in input_direction */
- void tryContinueWalking(float elapsed_time); /**< try to continue walking in current direction */
-
-public:
- Tux(WorldMap* worldmap_);
- ~Tux();
-
- void setup(); /**< called prior to first update */
- void draw(DrawingContext& context);
- void update(float elapsed_time);
-
- void set_direction(Direction dir);
-
- bool is_moving() const { return moving; }
- Vector get_pos();
- Vector get_tile_pos() const { return tile_pos; }
- void set_tile_pos(Vector p) { tile_pos = p; }
-};
-
-}
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux - A Jump'n Run
-// Copyright (C) 2004 Ingo Ruhnke <grumbel@gmx.de>
-// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
-//
-// 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.
-#include <config.h>
-
-#include <iostream>
-#include <fstream>
-#include <vector>
-#include <cassert>
-#include <stdexcept>
-#include <sstream>
-#include <unistd.h>
-//#include <physfs.h>
-
-#include "worldmap.hpp"
-
-#include "gettext.hpp"
-#include "log.hpp"
-#include "mainloop.hpp"
-#include "shrinkfade.hpp"
-#include "video/surface.hpp"
-#include "video/drawing_context.hpp"
-#include "sprite/sprite.hpp"
-#include "sprite/sprite_manager.hpp"
-#include "audio/sound_manager.hpp"
-#include "lisp/parser.hpp"
-#include "lisp/lisp.hpp"
-#include "lisp/list_iterator.hpp"
-#include "lisp/writer.hpp"
-#include "game_session.hpp"
-#include "sector.hpp"
-#include "worldmap.hpp"
-#include "resources.hpp"
-#include "log.hpp"
-#include "world.hpp"
-#include "player_status.hpp"
-#include "textscroller.hpp"
-#include "main.hpp"
-#include "spawn_point.hpp"
-#include "file_system.hpp"
-#include "gui/menu.hpp"
-#include "gui/mousecursor.hpp"
-#include "control/joystickkeyboardcontroller.hpp"
-#include "object/background.hpp"
-#include "object/tilemap.hpp"
-#include "options_menu.hpp"
-#include "scripting/squirrel_error.hpp"
-#include "scripting/squirrel_util.hpp"
-#include "worldmap/level.hpp"
-#include "worldmap/special_tile.hpp"
-#include "worldmap/tux.hpp"
-#include "worldmap/sprite_change.hpp"
-
-namespace WorldMapNS {
-
-enum WorldMapMenuIDs {
- MNID_RETURNWORLDMAP,
- MNID_QUITWORLDMAP
-};
-
-WorldMap* WorldMap::current_ = NULL;
-
-Direction reverse_dir(Direction direction)
-{
- switch(direction)
- {
- case D_WEST:
- return D_EAST;
- case D_EAST:
- return D_WEST;
- case D_NORTH:
- return D_SOUTH;
- case D_SOUTH:
- return D_NORTH;
- case D_NONE:
- return D_NONE;
- }
- return D_NONE;
-}
-
-std::string
-direction_to_string(Direction direction)
-{
- switch(direction)
- {
- case D_WEST:
- return "west";
- case D_EAST:
- return "east";
- case D_NORTH:
- return "north";
- case D_SOUTH:
- return "south";
- default:
- return "none";
- }
-}
-
-Direction
-string_to_direction(const std::string& directory)
-{
- if (directory == "west")
- return D_WEST;
- else if (directory == "east")
- return D_EAST;
- else if (directory == "north")
- return D_NORTH;
- else if (directory == "south")
- return D_SOUTH;
- else if (directory == "none")
- return D_NONE;
- else {
- log_warning << "unknown direction: \"" << directory << "\"" << std::endl;
- return D_NONE;
- }
-}
-
-//---------------------------------------------------------------------------
-
-WorldMap::WorldMap(const std::string& filename, const std::string& force_spawnpoint)
- : tux(0), ambient_light( 1.0f, 1.0f, 1.0f, 1.0f ), force_spawnpoint(force_spawnpoint), in_level(false)
-{
- tile_manager.reset(new TileManager("images/worldmap.strf"));
-
- tux = new Tux(this);
- add_object(tux);
-
- name = "<no title>";
- music = "music/salcon.ogg";
-
- total_stats.reset();
-
- worldmap_menu.reset(new Menu());
- worldmap_menu->add_label(_("Pause"));
- worldmap_menu->add_hl();
- worldmap_menu->add_entry(MNID_RETURNWORLDMAP, _("Continue"));
- worldmap_menu->add_submenu(_("Options"), get_options_menu());
- worldmap_menu->add_hl();
- worldmap_menu->add_entry(MNID_QUITWORLDMAP, _("Quit World"));
-
- // create a new squirrel table for the worldmap
- using namespace Scripting;
-
- sq_collectgarbage(global_vm);
- sq_newtable(global_vm);
- sq_pushroottable(global_vm);
- if(SQ_FAILED(sq_setdelegate(global_vm, -2)))
- throw Scripting::SquirrelError(global_vm, "Couldn't set worldmap_table delegate");
-
- sq_resetobject(&worldmap_table);
- if(SQ_FAILED(sq_getstackobj(global_vm, -1, &worldmap_table)))
- throw Scripting::SquirrelError(global_vm, "Couldn't get table from stack");
-
- sq_addref(global_vm, &worldmap_table);
- sq_pop(global_vm, 1);
-
- // load worldmap objects
- load(filename);
-}
-
-WorldMap::~WorldMap()
-{
- using namespace Scripting;
-
- for(GameObjects::iterator i = game_objects.begin();
- i != game_objects.end(); ++i) {
- GameObject* object = *i;
- try_unexpose(object);
- object->unref();
- }
-
- for(SpawnPoints::iterator i = spawn_points.begin();
- i != spawn_points.end(); ++i) {
- delete *i;
- }
-
- for(ScriptList::iterator i = scripts.begin();
- i != scripts.end(); ++i) {
- HSQOBJECT& object = *i;
- sq_release(global_vm, &object);
- }
- sq_release(global_vm, &worldmap_table);
-
- sq_collectgarbage(global_vm);
-
- if(current_ == this)
- current_ = NULL;
-}
-
-void
-WorldMap::add_object(GameObject* object)
-{
- TileMap* tilemap = dynamic_cast<TileMap*> (object);
- if(tilemap != 0 && tilemap->is_solid()) {
- solid_tilemaps.push_back(tilemap);
- }
-
- object->ref();
- try_expose(object);
- game_objects.push_back(object);
-}
-
-void
-WorldMap::try_expose(GameObject* object)
-{
- ScriptInterface* interface = dynamic_cast<ScriptInterface*> (object);
- if(interface != NULL) {
- HSQUIRRELVM vm = Scripting::global_vm;
- sq_pushobject(vm, worldmap_table);
- interface->expose(vm, -1);
- sq_pop(vm, 1);
- }
-}
-
-void
-WorldMap::try_unexpose(GameObject* object)
-{
- ScriptInterface* interface = dynamic_cast<ScriptInterface*> (object);
- if(interface != NULL) {
- HSQUIRRELVM vm = Scripting::global_vm;
- SQInteger oldtop = sq_gettop(vm);
- sq_pushobject(vm, worldmap_table);
- try {
- interface->unexpose(vm, -1);
- } catch(std::exception& e) {
- log_warning << "Couldn't unregister object: " << e.what() << std::endl;
- }
- sq_settop(vm, oldtop);
- }
-}
-
-void
-WorldMap::move_to_spawnpoint(const std::string& spawnpoint)
-{
- for(SpawnPoints::iterator i = spawn_points.begin(); i != spawn_points.end(); ++i) {
- SpawnPoint* sp = *i;
- if(sp->name == spawnpoint) {
- Vector p = sp->pos;
- tux->set_tile_pos(p);
- tux->set_direction(sp->auto_dir);
- return;
- }
- }
- log_warning << "Spawnpoint '" << spawnpoint << "' not found." << std::endl;
- if (spawnpoint != "main") {
- move_to_spawnpoint("main");
- }
-}
-
-void
-WorldMap::change(const std::string& filename, const std::string& force_spawnpoint)
-{
- main_loop->exit_screen();
- main_loop->push_screen(new WorldMap(filename, force_spawnpoint));
-}
-
-void
-WorldMap::load(const std::string& filename)
-{
- map_filename = filename;
- levels_path = FileSystem::dirname(map_filename);
-
- try {
- lisp::Parser parser;
- const lisp::Lisp* root = parser.parse(map_filename);
-
- const lisp::Lisp* lisp = root->get_lisp("supertux-level");
- if(!lisp)
- throw std::runtime_error("file isn't a supertux-level file.");
-
- lisp->get("name", name);
-
- const lisp::Lisp* sector = lisp->get_lisp("sector");
- if(!sector)
- throw std::runtime_error("No sector sepcified in worldmap file.");
-
- lisp::ListIterator iter(sector);
- while(iter.next()) {
- if(iter.item() == "tilemap") {
- add_object(new TileMap(*(iter.lisp()), tile_manager.get()));
- } else if(iter.item() == "background") {
- add_object(new Background(*(iter.lisp())));
- } else if(iter.item() == "music") {
- iter.value()->get(music);
- } else if(iter.item() == "init-script") {
- iter.value()->get(init_script);
- } else if(iter.item() == "worldmap-spawnpoint") {
- SpawnPoint* sp = new SpawnPoint(iter.lisp());
- spawn_points.push_back(sp);
- } else if(iter.item() == "level") {
- LevelTile* level = new LevelTile(levels_path, iter.lisp());
- levels.push_back(level);
- add_object(level);
- } else if(iter.item() == "special-tile") {
- SpecialTile* special_tile = new SpecialTile(iter.lisp());
- special_tiles.push_back(special_tile);
- add_object(special_tile);
- } else if(iter.item() == "sprite-change") {
- SpriteChange* sprite_change = new SpriteChange(iter.lisp());
- sprite_changes.push_back(sprite_change);
- add_object(sprite_change);
- } else if(iter.item() == "teleporter") {
- Teleporter* teleporter = new Teleporter(iter.lisp());
- teleporters.push_back(teleporter);
- add_object(teleporter);
- } else if(iter.item() == "ambient-light") {
- std::vector<float> vColor;
- sector->get_vector( "ambient-light", vColor );
- if(vColor.size() < 3) {
- log_warning << "(ambient-light) requires a color as argument" << std::endl;
- } else {
- ambient_light = Color( vColor );
- }
- } else if(iter.item() == "name") {
- // skip
- } else {
- log_warning << "Unknown token '" << iter.item() << "' in worldmap" << std::endl;
- }
- }
- if(solid_tilemaps.size() == 0)
- throw std::runtime_error("No solid tilemap specified");
-
- move_to_spawnpoint("main");
-
- } catch(std::exception& e) {
- std::stringstream msg;
- msg << "Problem when parsing worldmap '" << map_filename << "': " <<
- e.what();
- throw std::runtime_error(msg.str());
- }
-}
-
-void
-WorldMap::get_level_title(LevelTile& level)
-{
- /** get special_tile's title */
- level.title = "<no title>";
-
- try {
- lisp::Parser parser;
- const lisp::Lisp* root = parser.parse(levels_path + level.get_name());
-
- const lisp::Lisp* level_lisp = root->get_lisp("supertux-level");
- if(!level_lisp)
- return;
-
- level_lisp->get("name", level.title);
- } catch(std::exception& e) {
- log_warning << "Problem when reading leveltitle: " << e.what() << std::endl;
- return;
- }
-}
-
-void WorldMap::calculate_total_stats()
-{
- total_stats.zero();
- for(LevelTiles::iterator i = levels.begin(); i != levels.end(); ++i) {
- LevelTile* level = *i;
- if (level->solved) {
- total_stats += level->statistics;
- }
- }
-}
-
-void
-WorldMap::on_escape_press()
-{
- // Show or hide the menu
- if(!Menu::current()) {
- Menu::set_current(worldmap_menu.get());
- tux->set_direction(D_NONE); // stop tux movement when menu is called
- } else {
- Menu::set_current(NULL);
- }
-}
-
-Vector
-WorldMap::get_next_tile(Vector pos, Direction direction)
-{
- switch(direction) {
- case D_WEST:
- pos.x -= 1;
- break;
- case D_EAST:
- pos.x += 1;
- break;
- case D_NORTH:
- pos.y -= 1;
- break;
- case D_SOUTH:
- pos.y += 1;
- break;
- case D_NONE:
- break;
- }
- return pos;
-}
-
-bool
-WorldMap::path_ok(Direction direction, const Vector& old_pos, Vector* new_pos)
-{
- *new_pos = get_next_tile(old_pos, direction);
-
- if (!(new_pos->x >= 0 && new_pos->x < get_width()
- && new_pos->y >= 0 && new_pos->y < get_height()))
- { // New position is outsite the tilemap
- return false;
- }
- else
- { // Check if the tile allows us to go to new_pos
- int old_tile_data = tile_data_at(old_pos);
- int new_tile_data = tile_data_at(*new_pos);
- switch(direction)
- {
- case D_WEST:
- return (old_tile_data & Tile::WORLDMAP_WEST
- && new_tile_data & Tile::WORLDMAP_EAST);
-
- case D_EAST:
- return (old_tile_data & Tile::WORLDMAP_EAST
- && new_tile_data & Tile::WORLDMAP_WEST);
-
- case D_NORTH:
- return (old_tile_data & Tile::WORLDMAP_NORTH
- && new_tile_data & Tile::WORLDMAP_SOUTH);
-
- case D_SOUTH:
- return (old_tile_data & Tile::WORLDMAP_SOUTH
- && new_tile_data & Tile::WORLDMAP_NORTH);
-
- case D_NONE:
- assert(!"path_ok() can't walk if direction is NONE");
- }
- return false;
- }
-}
-
-void
-WorldMap::finished_level(Level* gamelevel)
-{
- // TODO use Level* parameter here?
- LevelTile* level = at_level();
-
- bool old_level_state = level->solved;
- level->solved = true;
- level->sprite->set_action("solved");
-
- // deal with statistics
- level->statistics.merge(gamelevel->stats);
- calculate_total_stats();
-
- save_state();
-
- if (old_level_state != level->solved) {
- // Try to detect the next direction to which we should walk
- // FIXME: Mostly a hack
- Direction dir = D_NONE;
-
- int dirdata = available_directions_at(tux->get_tile_pos());
- // first, test for crossroads
- if (dirdata == Tile::WORLDMAP_CNSE ||
- dirdata == Tile::WORLDMAP_CNSW ||
- dirdata == Tile::WORLDMAP_CNEW ||
- dirdata == Tile::WORLDMAP_CSEW ||
- dirdata == Tile::WORLDMAP_CNSEW)
- dir = D_NONE;
- else if (dirdata & Tile::WORLDMAP_NORTH
- && tux->back_direction != D_NORTH)
- dir = D_NORTH;
- else if (dirdata & Tile::WORLDMAP_SOUTH
- && tux->back_direction != D_SOUTH)
- dir = D_SOUTH;
- else if (dirdata & Tile::WORLDMAP_EAST
- && tux->back_direction != D_EAST)
- dir = D_EAST;
- else if (dirdata & Tile::WORLDMAP_WEST
- && tux->back_direction != D_WEST)
- dir = D_WEST;
-
- if (dir != D_NONE) {
- tux->set_direction(dir);
- }
- }
-
- if (level->extro_script != "") {
- try {
- std::istringstream in(level->extro_script);
- run_script(in, "worldmap:extro_script");
- } catch(std::exception& e) {
- log_fatal << "Couldn't run level-extro-script: " << e.what() << std::endl;
- }
- }
-}
-
-void
-WorldMap::update(float delta)
-{
- if(!in_level) {
- Menu* menu = Menu::current();
- if(menu != NULL) {
- menu->update();
-
- if(menu == worldmap_menu.get()) {
- switch (worldmap_menu->check())
- {
- case MNID_RETURNWORLDMAP: // Return to game
- Menu::set_current(0);
- break;
- case MNID_QUITWORLDMAP: // Quit Worldmap
- main_loop->exit_screen();
- break;
- }
- }
-
- return;
- }
-
- // update GameObjects
- for(size_t i = 0; i < game_objects.size(); ++i) {
- GameObject* object = game_objects[i];
- object->update(delta);
- }
-
- // remove old GameObjects
- for(GameObjects::iterator i = game_objects.begin();
- i != game_objects.end(); ) {
- GameObject* object = *i;
- if(!object->is_valid()) {
- try_unexpose(object);
- object->unref();
- i = game_objects.erase(i);
- } else {
- ++i;
- }
- }
-
- /* update solid_tilemaps list */
- //FIXME: this could be more efficient
- solid_tilemaps.clear();
- for(std::vector<GameObject*>::iterator i = game_objects.begin();
- i != game_objects.end(); ++i)
- {
- TileMap* tm = dynamic_cast<TileMap*>(*i);
- if (!tm) continue;
- if (tm->is_solid()) solid_tilemaps.push_back(tm);
- }
-
- // position "camera"
- Vector tux_pos = tux->get_pos();
- camera_offset.x = tux_pos.x - SCREEN_WIDTH/2;
- camera_offset.y = tux_pos.y - SCREEN_HEIGHT/2;
-
- if (camera_offset.x < 0)
- camera_offset.x = 0;
- if (camera_offset.y < 0)
- camera_offset.y = 0;
-
- if (camera_offset.x > (int)get_width()*32 - SCREEN_WIDTH)
- camera_offset.x = (int)get_width()*32 - SCREEN_WIDTH;
- if (camera_offset.y > (int)get_height()*32 - SCREEN_HEIGHT)
- camera_offset.y = (int)get_height()*32 - SCREEN_HEIGHT;
-
- if (int(get_width()*32) < SCREEN_WIDTH)
- camera_offset.x = get_width()*16.0 - SCREEN_WIDTH/2.0;
- if (int(get_height()*32) < SCREEN_HEIGHT)
- camera_offset.y = get_height()*16.0 - SCREEN_HEIGHT/2.0;
-
- // handle input
- bool enter_level = false;
- if(main_controller->pressed(Controller::ACTION)
- || main_controller->pressed(Controller::JUMP)
- || main_controller->pressed(Controller::MENU_SELECT)) {
- /* some people define UP and JUMP on the same key... */
- if(!main_controller->pressed(Controller::UP))
- enter_level = true;
- }
- if(main_controller->pressed(Controller::PAUSE_MENU))
- on_escape_press();
-
- // check for teleporters
- Teleporter* teleporter = at_teleporter(tux->get_tile_pos());
- if (teleporter && (teleporter->automatic || (enter_level && (!tux->is_moving())))) {
- enter_level = false;
- if (teleporter->worldmap != "") {
- change(teleporter->worldmap, teleporter->spawnpoint);
- } else {
- // TODO: an animation, camera scrolling or a fading would be a nice touch
- sound_manager->play("sounds/warp.wav");
- tux->back_direction = D_NONE;
- move_to_spawnpoint(teleporter->spawnpoint);
- }
- }
-
- // check for auto-play levels
- LevelTile* level = at_level();
- if (level && (level->auto_play) && (!level->solved) && (!tux->is_moving())) {
- enter_level = true;
- }
-
- if (enter_level && !tux->is_moving())
- {
- /* Check level action */
- LevelTile* level = at_level();
- if (!level) {
- //Respawn if player on a tile with no level and nowhere to go.
- int tile_data = tile_data_at(tux->get_tile_pos());
- if(!( tile_data & ( Tile::WORLDMAP_NORTH | Tile::WORLDMAP_SOUTH | Tile::WORLDMAP_WEST | Tile::WORLDMAP_EAST ))){
- log_warning << "Player at illegal position " << tux->get_tile_pos().x << ", " << tux->get_tile_pos().y << " respawning." << std::endl;
- move_to_spawnpoint("main");
- return;
- }
- log_warning << "No level to enter at: " << tux->get_tile_pos().x << ", " << tux->get_tile_pos().y << std::endl;
- return;
- }
-
- if (level->pos == tux->get_tile_pos()) {
- try {
- Vector shrinkpos = Vector(level->pos.x*32 + 16 - camera_offset.x,
- level->pos.y*32 + 16 - camera_offset.y);
- std::string levelfile = levels_path + level->get_name();
-
- // update state and savegame
- save_state();
-
- main_loop->push_screen(new GameSession(levelfile, &level->statistics),
- new ShrinkFade(shrinkpos, 0.5));
- in_level = true;
- } catch(std::exception& e) {
- log_fatal << "Couldn't load level: " << e.what() << std::endl;
- }
- }
- }
- else
- {
- // tux->set_direction(input_direction);
- }
- }
-}
-
-int
-WorldMap::tile_data_at(Vector p)
-{
- int dirs = 0;
-
- for(std::list<TileMap*>::const_iterator i = solid_tilemaps.begin(); i != solid_tilemaps.end(); i++) {
- TileMap* tilemap = *i;
- const Tile* tile = tilemap->get_tile((int)p.x, (int)p.y);
- int dirdata = tile->getData();
- dirs |= dirdata;
- }
-
- return dirs;
-}
-
-int
-WorldMap::available_directions_at(Vector p)
-{
- return tile_data_at(p) & Tile::WORLDMAP_DIR_MASK;
-}
-
-LevelTile*
-WorldMap::at_level()
-{
- for(LevelTiles::iterator i = levels.begin(); i != levels.end(); ++i) {
- LevelTile* level = *i;
- if (level->pos == tux->get_tile_pos())
- return level;
- }
-
- return NULL;
-}
-
-SpecialTile*
-WorldMap::at_special_tile()
-{
- for(SpecialTiles::iterator i = special_tiles.begin();
- i != special_tiles.end(); ++i) {
- SpecialTile* special_tile = *i;
- if (special_tile->pos == tux->get_tile_pos())
- return special_tile;
- }
-
- return NULL;
-}
-
-SpriteChange*
-WorldMap::at_sprite_change(const Vector& pos)
-{
- for(SpriteChanges::iterator i = sprite_changes.begin();
- i != sprite_changes.end(); ++i) {
- SpriteChange* sprite_change = *i;
- if(sprite_change->pos == pos)
- return sprite_change;
- }
-
- return NULL;
-}
-
-Teleporter*
-WorldMap::at_teleporter(const Vector& pos)
-{
- for(std::vector<Teleporter*>::iterator i = teleporters.begin(); i != teleporters.end(); ++i) {
- Teleporter* teleporter = *i;
- if(teleporter->pos == pos) return teleporter;
- }
-
- return NULL;
-}
-
-void
-WorldMap::draw(DrawingContext& context)
-{
- if (int(get_width()*32) < SCREEN_WIDTH || int(get_height()*32) < SCREEN_HEIGHT)
- context.draw_filled_rect(Vector(0, 0), Vector(SCREEN_WIDTH, SCREEN_HEIGHT),
- Color(0.0f, 0.0f, 0.0f, 1.0f), LAYER_BACKGROUND0);
-
- context.set_ambient_color( ambient_light );
- context.push_transform();
- context.set_translation(camera_offset);
-
- for(GameObjects::iterator i = game_objects.begin();
- i != game_objects.end(); ++i) {
- GameObject* object = *i;
- object->draw(context);
- }
-
-/*
- // FIXME: make this a runtime switch similar to draw_collrects/show_collrects?
- // draw visual indication of possible walk directions
- static int flipme = 0;
- if (flipme++ & 0x04)
- for (int x = 0; x < get_width(); x++) {
- for (int y = 0; y < get_height(); y++) {
- int data = tile_data_at(Vector(x,y));
- int px = x * 32;
- int py = y * 32;
- const int W = 4;
- if (data & Tile::WORLDMAP_NORTH) context.draw_filled_rect(Rect(px + 16-W, py , px + 16+W, py + 16-W), Color(0.2f, 0.2f, 0.2f, 0.7f), LAYER_FOREGROUND1 + 1000);
- if (data & Tile::WORLDMAP_SOUTH) context.draw_filled_rect(Rect(px + 16-W, py + 16+W, px + 16+W, py + 32 ), Color(0.2f, 0.2f, 0.2f, 0.7f), LAYER_FOREGROUND1 + 1000);
- if (data & Tile::WORLDMAP_EAST) context.draw_filled_rect(Rect(px + 16+W, py + 16-W, px + 32 , py + 16+W), Color(0.2f, 0.2f, 0.2f, 0.7f), LAYER_FOREGROUND1 + 1000);
- if (data & Tile::WORLDMAP_WEST) context.draw_filled_rect(Rect(px , py + 16-W, px + 16-W, py + 16+W), Color(0.2f, 0.2f, 0.2f, 0.7f), LAYER_FOREGROUND1 + 1000);
- if (data & Tile::WORLDMAP_DIR_MASK) context.draw_filled_rect(Rect(px + 16-W, py + 16-W, px + 16+W, py + 16+W), Color(0.2f, 0.2f, 0.2f, 0.7f), LAYER_FOREGROUND1 + 1000);
- if (data & Tile::WORLDMAP_STOP) context.draw_filled_rect(Rect(px + 4 , py + 4 , px + 28 , py + 28 ), Color(0.2f, 0.2f, 0.2f, 0.7f), LAYER_FOREGROUND1 + 1000);
- }
- }
-*/
-
- draw_status(context);
- context.pop_transform();
-}
-
-void
-WorldMap::draw_status(DrawingContext& context)
-{
- context.push_transform();
- context.set_translation(Vector(0, 0));
-
- player_status->draw(context);
-
- if (!tux->is_moving()) {
- for(LevelTiles::iterator i = levels.begin(); i != levels.end(); ++i) {
- LevelTile* level = *i;
-
- if (level->pos == tux->get_tile_pos()) {
- if(level->title == "")
- get_level_title(*level);
-
- context.draw_text(white_text, level->title,
- Vector(SCREEN_WIDTH/2,
- SCREEN_HEIGHT - white_text->get_height() - 30),
- ALIGN_CENTER, LAYER_FOREGROUND1);
-
- // if level is solved, draw level picture behind stats
- /*
- if (level->solved) {
- if (const Surface* picture = level->get_picture()) {
- Vector pos = Vector(SCREEN_WIDTH - picture->get_width(), SCREEN_HEIGHT - picture->get_height());
- context.push_transform();
- context.set_alpha(0.5);
- context.draw_surface(picture, pos, LAYER_FOREGROUND1-1);
- context.pop_transform();
- }
- }
- */
-
- level->statistics.draw_worldmap_info(context);
- break;
- }
- }
-
- for(SpecialTiles::iterator i = special_tiles.begin();
- i != special_tiles.end(); ++i) {
- SpecialTile* special_tile = *i;
-
- if (special_tile->pos == tux->get_tile_pos()) {
- /* Display an in-map message in the map, if any as been selected */
- if(!special_tile->map_message.empty() && !special_tile->passive_message)
- context.draw_text(gold_text, special_tile->map_message,
- Vector(SCREEN_WIDTH/2,
- SCREEN_HEIGHT - white_text->get_height() - 60),
- ALIGN_CENTER, LAYER_FOREGROUND1);
- break;
- }
- }
-
- // display teleporter messages
- Teleporter* teleporter = at_teleporter(tux->get_tile_pos());
- if (teleporter && (teleporter->message != "")) {
- Vector pos = Vector(SCREEN_WIDTH/2, SCREEN_HEIGHT - white_text->get_height() - 30);
- context.draw_text(white_text, teleporter->message, pos, ALIGN_CENTER, LAYER_FOREGROUND1);
- }
-
- }
-
- /* Display a passive message in the map, if needed */
- if(passive_message_timer.started())
- context.draw_text(gold_text, passive_message,
- Vector(SCREEN_WIDTH/2, SCREEN_HEIGHT - white_text->get_height() - 60),
- ALIGN_CENTER, LAYER_FOREGROUND1);
-
- context.pop_transform();
-}
-
-void
-WorldMap::setup()
-{
- sound_manager->play_music(music);
- Menu::set_current(NULL);
-
- current_ = this;
- load_state();
-
- // if force_spawnpoint was set, move Tux there, then clear force_spawnpoint
- if (force_spawnpoint != "") {
- move_to_spawnpoint(force_spawnpoint);
- force_spawnpoint = "";
- }
-
- tux->setup();
-
- // register worldmap_table as worldmap in scripting
- using namespace Scripting;
-
- sq_pushroottable(global_vm);
- sq_pushstring(global_vm, "worldmap", -1);
- sq_pushobject(global_vm, worldmap_table);
- if(SQ_FAILED(sq_createslot(global_vm, -3)))
- throw SquirrelError(global_vm, "Couldn't set worldmap in roottable");
- sq_pop(global_vm, 1);
-
- if(init_script != "") {
- std::istringstream in(init_script);
- run_script(in, "WorldMap::init");
- }
-}
-
-void
-WorldMap::leave()
-{
- using namespace Scripting;
-
- // save state of world and player
- save_state();
-
- // remove worldmap_table from roottable
- sq_pushroottable(global_vm);
- sq_pushstring(global_vm, "worldmap", -1);
- if(SQ_FAILED(sq_deleteslot(global_vm, -2, SQFalse)))
- throw SquirrelError(global_vm, "Couldn't unset worldmap in roottable");
- sq_pop(global_vm, 1);
-}
-
-void
-WorldMap::save_state()
-{
- using namespace Scripting;
-
- HSQUIRRELVM vm = global_vm;
- int oldtop = sq_gettop(vm);
-
- try {
- // get state table
- sq_pushroottable(vm);
- sq_pushstring(vm, "state", -1);
- if(SQ_FAILED(sq_get(vm, -2)))
- throw Scripting::SquirrelError(vm, "Couldn't get state table");
-
- // get or create worlds table
- sq_pushstring(vm, "worlds", -1);
- if(SQ_FAILED(sq_get(vm, -2))) {
- sq_pushstring(vm, "worlds", -1);
- sq_newtable(vm);
- if(SQ_FAILED(sq_createslot(vm, -3)))
- throw Scripting::SquirrelError(vm, "Couldn't create state.worlds");
-
- sq_pushstring(vm, "worlds", -1);
- if(SQ_FAILED(sq_get(vm, -2)))
- throw Scripting::SquirrelError(vm, "Couldn't create.get state.worlds");
- }
-
- sq_pushstring(vm, map_filename.c_str(), map_filename.length());
- if(SQ_FAILED(sq_deleteslot(vm, -2, SQFalse)))
- sq_pop(vm, 1);
-
- // construct new table for this worldmap
- sq_pushstring(vm, map_filename.c_str(), map_filename.length());
- sq_newtable(vm);
-
- // store tux
- sq_pushstring(vm, "tux", -1);
- sq_newtable(vm);
-
- store_float(vm, "x", tux->get_tile_pos().x);
- store_float(vm, "y", tux->get_tile_pos().y);
- store_string(vm, "back", direction_to_string(tux->back_direction));
-
- sq_createslot(vm, -3);
-
- // levels...
- sq_pushstring(vm, "levels", -1);
- sq_newtable(vm);
-
- for(LevelTiles::iterator i = levels.begin(); i != levels.end(); ++i) {
- LevelTile* level = *i;
-
- sq_pushstring(vm, level->get_name().c_str(), -1);
- sq_newtable(vm);
-
- store_bool(vm, "solved", level->solved);
- level->statistics.serialize_to_squirrel(vm);
-
- sq_createslot(vm, -3);
- }
-
- sq_createslot(vm, -3);
-
- // overall statistics...
- total_stats.serialize_to_squirrel(vm);
-
- // push world into worlds table
- sq_createslot(vm, -3);
- } catch(std::exception& ) {
- sq_settop(vm, oldtop);
- }
-
- sq_settop(vm, oldtop);
-
- if(World::current() != NULL)
- World::current()->save_state();
-}
-
-void
-WorldMap::load_state()
-{
- using namespace Scripting;
-
- HSQUIRRELVM vm = global_vm;
- int oldtop = sq_gettop(vm);
-
- try {
- // get state table
- sq_pushroottable(vm);
- sq_pushstring(vm, "state", -1);
- if(SQ_FAILED(sq_get(vm, -2)))
- throw Scripting::SquirrelError(vm, "Couldn't get state table");
-
- // get worlds table
- sq_pushstring(vm, "worlds", -1);
- if(SQ_FAILED(sq_get(vm, -2)))
- throw Scripting::SquirrelError(vm, "Couldn't get state.worlds");
-
- // get table for our world
- sq_pushstring(vm, map_filename.c_str(), map_filename.length());
- if(SQ_FAILED(sq_get(vm, -2)))
- throw Scripting::SquirrelError(vm, "Couldn't get state.worlds.mapfilename");
-
- // load tux
- sq_pushstring(vm, "tux", -1);
- if(SQ_FAILED(sq_get(vm, -2)))
- throw Scripting::SquirrelError(vm, "Couldn't get tux");
-
- Vector p;
- p.x = read_float(vm, "x");
- p.y = read_float(vm, "y");
- std::string back_str = read_string(vm, "back");
- tux->back_direction = string_to_direction(back_str);
- tux->set_tile_pos(p);
-
- sq_pop(vm, 1);
-
- // load levels
- sq_pushstring(vm, "levels", -1);
- if(SQ_FAILED(sq_get(vm, -2)))
- throw Scripting::SquirrelError(vm, "Couldn't get levels");
-
- for(LevelTiles::iterator i = levels.begin(); i != levels.end(); ++i) {
- LevelTile* level = *i;
- sq_pushstring(vm, level->get_name().c_str(), -1);
- if(SQ_SUCCEEDED(sq_get(vm, -2))) {
- level->solved = read_bool(vm, "solved");
- level->sprite->set_action(level->solved ? "solved" : "default");
- level->statistics.unserialize_from_squirrel(vm);
- sq_pop(vm, 1);
- }
- }
-
- // leave state table
- sq_pop(vm, 1);
-
- // load overall statistics
- total_stats.unserialize_from_squirrel(vm);
-
- } catch(std::exception& e) {
- log_debug << "Not loading worldmap state: " << e.what() << std::endl;
- }
- sq_settop(vm, oldtop);
-
- in_level = false;
-}
-
-size_t
-WorldMap::level_count()
-{
- return levels.size();
-}
-
-size_t
-WorldMap::solved_level_count()
-{
- size_t count = 0;
- for(LevelTiles::iterator i = levels.begin(); i != levels.end(); ++i) {
- LevelTile* level = *i;
-
- if(level->solved)
- count++;
- }
-
- return count;
-}
-
-HSQUIRRELVM
-WorldMap::run_script(std::istream& in, const std::string& sourcename)
-{
- using namespace Scripting;
-
- // garbage collect thread list
- for(ScriptList::iterator i = scripts.begin();
- i != scripts.end(); ) {
- HSQOBJECT& object = *i;
- HSQUIRRELVM vm = object_to_vm(object);
-
- if(sq_getvmstate(vm) != SQ_VMSTATE_SUSPENDED) {
- sq_release(global_vm, &object);
- i = scripts.erase(i);
- continue;
- }
-
- ++i;
- }
-
- HSQOBJECT object = create_thread(global_vm);
- scripts.push_back(object);
-
- HSQUIRRELVM vm = object_to_vm(object);
-
- // set worldmap_table as roottable for the thread
- sq_pushobject(vm, worldmap_table);
- sq_setroottable(vm);
-
- compile_and_run(vm, in, sourcename);
-
- return vm;
-}
-
-float
-WorldMap::get_width() const
-{
- float width = 0;
- for(std::list<TileMap*>::const_iterator i = solid_tilemaps.begin(); i != solid_tilemaps.end(); i++) {
- TileMap* solids = *i;
- if (solids->get_width() > width) width = solids->get_width();
- }
- return width;
-}
-
-float
-WorldMap::get_height() const
-{
- float height = 0;
- for(std::list<TileMap*>::const_iterator i = solid_tilemaps.begin(); i != solid_tilemaps.end(); i++) {
- TileMap* solids = *i;
- if (solids->get_height() > height) height = solids->get_height();
- }
- return height;
-}
-
-} // namespace WorldMapNS
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2004 Ingo Ruhnke <grumbel@gmx.de>
-// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
-//
-// 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.
-#ifndef SUPERTUX_WORLDMAP_H
-#define SUPERTUX_WORLDMAP_H
-
-#include <vector>
-#include <string>
-
-#include "math/vector.hpp"
-#include "lisp/lisp.hpp"
-#include "control/controller.hpp"
-#include "statistics.hpp"
-#include "timer.hpp"
-#include "screen.hpp"
-#include "tile_manager.hpp"
-#include "game_object.hpp"
-#include "console.hpp"
-#include "../level.hpp"
-#include "worldmap/special_tile.hpp"
-#include "worldmap/sprite_change.hpp"
-#include "worldmap/teleporter.hpp"
-#include "worldmap/spawn_point.hpp"
-#include "worldmap/direction.hpp"
-
-class Sprite;
-class Menu;
-class GameObject;
-class TileMap;
-
-namespace WorldMapNS {
-
-class Tux;
-class LevelTile;
-class SpecialTile;
-class SpriteChange;
-
-// For one way tiles
-enum {
- BOTH_WAYS,
- NORTH_SOUTH_WAY,
- SOUTH_NORTH_WAY,
- EAST_WEST_WAY,
- WEST_EAST_WAY
-};
-
-std::string direction_to_string(Direction d);
-Direction string_to_direction(const std::string& d);
-Direction reverse_dir(Direction d);
-
-/**
- * Screen that displays a worldmap
- */
-class WorldMap : public Screen
-{
-private:
- Tux* tux;
-
- static WorldMap* current_;
-
- std::auto_ptr<Menu> worldmap_menu;
-
- Vector camera_offset;
-
- std::string name;
- std::string music;
- std::string init_script;
-
- typedef std::vector<GameObject*> GameObjects;
- GameObjects game_objects;
- std::list<TileMap*> solid_tilemaps;
-
- std::auto_ptr<TileManager> tile_manager;
-
-public:
- /** Variables to deal with the passive map messages */
- Timer passive_message_timer;
- std::string passive_message;
-
-private:
- std::string map_filename;
- std::string levels_path;
-
- typedef std::vector<SpecialTile*> SpecialTiles;
- SpecialTiles special_tiles;
- typedef std::vector<LevelTile*> LevelTiles;
- LevelTiles levels;
- typedef std::vector<SpriteChange*> SpriteChanges;
- SpriteChanges sprite_changes;
- typedef std::vector<SpawnPoint*> SpawnPoints;
- SpawnPoints spawn_points;
- std::vector<Teleporter*> teleporters;
-
- Statistics total_stats;
-
- HSQOBJECT worldmap_table;
- typedef std::vector<HSQOBJECT> ScriptList;
- ScriptList scripts;
-
- Color ambient_light;
- std::string force_spawnpoint; /**< if set, spawnpoint will be forced to this value */
-
- bool in_level;
-
-public:
- WorldMap(const std::string& filename, const std::string& force_spawnpoint = "");
- ~WorldMap();
-
- void add_object(GameObject* object);
-
- void try_expose(GameObject* object);
- void try_unexpose(GameObject* object);
-
- static WorldMap* current()
- { return current_; }
-
- virtual void setup();
- virtual void leave();
-
- /** Update worldmap state */
- virtual void update(float delta);
- /** Draw worldmap */
- virtual void draw(DrawingContext& context);
-
- Vector get_next_tile(Vector pos, Direction direction);
-
- /**
- * gets a bitfield of Tile::WORLDMAP_NORTH | Tile::WORLDMAP_WEST | ... values,
- * which indicates the directions Tux can move to when at the given position.
- */
- int available_directions_at(Vector pos);
-
- /**
- * returns a bitfield representing the union of all Tile::WORLDMAP_XXX values
- * of all solid tiles at the given position
- */
- int tile_data_at(Vector pos);
-
- size_t level_count();
- size_t solved_level_count();
-
- /**
- * gets called from the GameSession when a level has been successfully
- * finished
- */
- void finished_level(Level* level);
-
- LevelTile* at_level();
- SpecialTile* at_special_tile();
- SpriteChange* at_sprite_change(const Vector& pos);
- Teleporter* at_teleporter(const Vector& pos);
-
- /** Check if it is possible to walk from \a pos into \a direction,
- if possible, write the new position to \a new_pos */
- bool path_ok(Direction direction, const Vector& pos, Vector* new_pos);
-
- /**
- * Save worldmap state to squirrel state table
- */
- void save_state();
-
- /**
- * Load worldmap state from squirrel state table
- */
- void load_state();
-
- const std::string& get_title() const
- { return name; }
-
- /**
- * runs a script in the context of the worldmap (and keeps a reference to
- * the script (so the script gets destroyed when the worldmap is destroyed)
- */
- HSQUIRRELVM run_script(std::istream& in, const std::string& sourcename);
-
- /**
- * switch to another worldmap.
- * filename is relative to data root path
- */
- void change(const std::string& filename, const std::string& force_spawnpoint="");
-
- /**
- * moves Tux to the given spawnpoint
- */
- void move_to_spawnpoint(const std::string& spawnpoint);
-
- /**
- * returns the width (in tiles) of a worldmap
- */
- float get_width() const;
-
- /**
- * returns the height (in tiles) of a worldmap
- */
- float get_height() const;
-
-private:
- void get_level_title(LevelTile& level);
- void draw_status(DrawingContext& context);
- void calculate_total_stats();
-
- void load(const std::string& filename);
- void on_escape_press();
-};
-
-} // namespace WorldMapNS
-
-#endif