#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
-//#include <physfs.h>
+#include <physfs.h>
#include <SDL.h>
-//#include <SDL_image.h>
+#include <SDL_image.h>
#ifdef MACOSX
namespace supertux_apple {
}
#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/texture_manager.hpp"
#include "video/drawing_context.hpp"
#include "video/glutil.hpp"
#include "control/joystickkeyboardcontroller.hpp"
#include "physfs/physfs_sdl.hpp"
#include "random_generator.hpp"
#include "worldmap/worldmap.hpp"
+#include "addon/addon_manager.hpp"
#include "binreloc/binreloc.h"
namespace { DrawingContext *context_pointer; }
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());
}
+ // allow symbolic links
+ PHYSFS_permitSymbolicLinks(1);
+
// 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
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";
#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)
" -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"
+ " -d, --default Reset video settings to default values\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"
+ " -h, --help Show this help message\n"
+ " -v, --version Show 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"
+ " -s, --debug-scripts Enable script debugger.\n"
"\n"));
}
for(int i = 1; i < argc; ++i) {
std::string arg = argv[i];
- if(arg == "--version") {
+ if(arg == "--version" || arg == "-v") {
std::cout << PACKAGE_NAME << " " << PACKAGE_VERSION << std::endl;
return true;
}
for(int i = 1; i < argc; ++i) {
std::string arg = argv[i];
- if(arg == "--help") {
+ if(arg == "--help" || arg == "-h") {
print_usage(argv[0]);
return true;
} else if(arg == "--fullscreen" || arg == "-f") {
config->use_fullscreen = true;
+ } else if(arg == "--default" || arg == "-d") {
+ config->use_fullscreen = false;
+
+ config->window_width = 800;
+ config->window_height = 600;
+
+ config->fullscreen_width = 800;
+ config->fullscreen_height = 600;
+
+ config->aspect_width = 0; // auto detect
+ config->aspect_height = 0;
+
} 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");
- }
+ i += 1;
+ if(i >= argc)
+ {
+ print_usage(argv[0]);
+ throw std::runtime_error("Need to specify a size (WIDTHxHEIGHT) for geometry argument");
+ }
+ else
+ {
+ int width, height;
+ if (sscanf(argv[i], "%dx%d", &width, &height) != 2)
+ {
+ print_usage(argv[0]);
+ throw std::runtime_error("Invalid geometry spec, should be WIDTHxHEIGHT");
+ }
+ else
+ {
+ config->window_width = width;
+ config->window_height = height;
+
+ config->fullscreen_width = width;
+ config->fullscreen_height = height;
+ }
+ }
} 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) {
+ i += 1;
+ if(i >= argc)
+ {
print_usage(argv[0]);
- throw std::runtime_error("Invalid aspect spec, should be WIDTH:HEIGHT");
+ throw std::runtime_error("Need to specify a ratio (WIDTH:HEIGHT) for aspect ratio");
+ }
+ else
+ {
+ int aspect_width = 0;
+ int aspect_height = 0;
+ if (strcmp(argv[i], "auto") == 0)
+ {
+ aspect_width = 0;
+ aspect_height = 0;
+ }
+ else 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 or auto");
+ }
+ else
+ {
+ float aspect_ratio = static_cast<double>(config->aspect_width) /
+ static_cast<double>(config->aspect_height);
+
+ // use aspect ratio to calculate logical resolution
+ if (aspect_ratio > 1) {
+ config->aspect_width = static_cast<int> (600 * aspect_ratio + 0.5);
+ config->aspect_height = 600;
+ } else {
+ config->aspect_width = 600;
+ config->aspect_height = static_cast<int> (600 * 1/aspect_ratio + 0.5);
+ }
+ }
}
- 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") {
throw std::runtime_error("Need to specify a demo filename");
}
config->record_demo = argv[++i];
- } else if(arg == "-d") {
+ } else if(arg == "--debug-scripts" || arg == "-s") {
config->enable_script_debugger = true;
} else if(arg[0] != '-') {
config->start_level = arg;
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);
- }
+ // FIXME: Add something here
+ SCREEN_WIDTH = 800;
+ SCREEN_HEIGHT = 600;
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);
+ 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);
+#ifdef MACOSX
+ const char* icon_fname = "images/engine/icons/supertux-256x256.png";
+#else
+ const char* icon_fname = "images/engine/icons/supertux.xpm";
+#endif
+ SDL_Surface* icon;
+ try {
+ icon = IMG_Load_RW(get_physfs_SDLRWops(icon_fname), true);
+ } catch (const std::runtime_error& err) {
+ icon = 0;
+ log_warning << "Couldn't load icon '" << icon_fname << "': " << err.what() << std::endl;
+ }
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;
+ log_warning << "Couldn't load icon '" << icon_fname << "'" << std::endl;
}
#endif
- */
SDL_ShowCursor(0);
- log_info << (config->use_fullscreen?"fullscreen ":"window ") << SCREEN_WIDTH << "x" << SCREEN_HEIGHT << " Ratio: " << aspect_ratio << "\n";
+ log_info << (config->use_fullscreen?"fullscreen ":"window ")
+ << " Window: " << config->window_width << "x" << config->window_height
+ << " Fullscreen: " << config->fullscreen_width << "x" << config->fullscreen_height
+ << " Area: " << config->aspect_width << "x" << config->aspect_height << std::endl;
}
static void init_audio()
{
int result = 0;
-#ifndef NO_CATCH
+#ifndef DEBUG
try {
#endif
timelog("controller");
main_controller = new JoystickKeyboardController();
+
timelog("config");
init_config();
+
+ timelog("addons");
+ AddonManager::get_instance().load_addons();
+
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();
// 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);
+ 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(); PAK: this call might subsume the above 3, but I'm chicken!
main_loop->run(context);
-#ifndef NO_CATCH
+#ifndef DEBUG
} catch(std::exception& e) {
log_fatal << "Unexpected exception: " << e.what() << std::endl;
result = 1;
delete Console::instance;
Console::instance = NULL;
Scripting::exit_squirrel();
- //delete texture_manager;
- //texture_manager = NULL;
+ delete texture_manager;
+ texture_manager = NULL;
SDL_Quit();
- //PHYSFS_deinit();
+ PHYSFS_deinit();
return result;
}