#include <stdexcept>
#include <sstream>
-#include <time.h>
-#include <stdlib.h>
+#include <ctime>
+#include <cstdlib>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
-#include <assert.h>
#include <physfs.h>
#include <SDL.h>
#include <SDL_image.h>
-#include <GL/gl.h>
+
+#ifdef MACOSX
+namespace supertux_apple {
+#include <CoreFoundation/CoreFoundation.h>
+}
+#endif
#include "gameconfig.hpp"
#include "resources.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 "worldmap/worldmap.hpp"
#include "binreloc/binreloc.h"
-SDL_Surface* screen = 0;
+namespace { DrawingContext *context_pointer; }
+SDL_Surface *screen;
JoystickKeyboardController* main_controller = 0;
TinyGetText::DictionaryManager dictionary_manager;
{
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)
}
#ifdef MACOSX
+{
+ using namespace supertux_apple;
+
// when started from Application file on Mac OS X...
- dir = PHYSFS_getBaseDir();
- dir += "SuperTux.app/Contents/Resources/data";
+ 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");
sourcedir = true;
}
}
+}
#endif
#ifdef _WIN32
#ifdef ENABLE_BINRELOC
char* dir;
- br_init (NULL);
- dir = br_find_data_dir(APPDATADIR);
+ br_init (NULL);
+ dir = br_find_data_dir(APPDATADIR);
datadir = dir;
- datadir += "/" PACKAGE_NAME;
- free(dir);
+ free(dir);
#else
datadir = APPDATADIR;
PHYSFS_permitSymbolicLinks(1);
//show search Path
- for(char** i = PHYSFS_getSearchPath(); *i != NULL; i++)
+ 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)
" -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"
for(int i = 1; i < argc; ++i) {
std::string arg = argv[i];
- if(arg == "--help") {
- print_usage(argv[0]);
- return true;
- } else if(arg == "--version") {
+ if(arg == "--version") {
std::cout << PACKAGE_NAME << " " << PACKAGE_VERSION << std::endl;
return true;
}
for(int i = 1; i < argc; ++i) {
std::string arg = argv[i];
- if(arg == "--fullscreen" || arg == "-f") {
+ if(arg == "--help") {
+ 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->aspect_width = 800;
+ config->aspect_height = 600;
+ config->screenwidth = 800;
+ config->screenheight = 600;
} else if(arg == "--window" || arg == "-w") {
config->use_fullscreen = false;
} else if(arg == "--geometry" || arg == "-g") {
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 (sscanf(argv[i], "%dx%d:%dx%d",
+ &config->screenwidth, &config->screenheight,
+ &config->aspect_width, &config->aspect_height) != 4 &&
+ 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(sscanf(argv[++i], "%d:%d", &config->aspectwidth, &config->aspectheight)
- != 2) {
- print_usage(argv[0]);
- throw std::runtime_error("Invalid aspect spec, should be WIDTH:HEIGHT");
+ } else {
+ int aspect_width = 4;
+ int aspect_height = 3;
+ 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");
+ } 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);
+ }
+ }
}
} else if(arg == "--show-fps") {
config->show_fps = true;
static void init_rand()
{
- const char *how = config->random_seed? ", user fixed.": ", from time().";
-
config->random_seed = systemRandom.srand(config->random_seed);
- log_info << "Using random seed " << config->random_seed << how << std::endl;
+ //const char *how = config->random_seed? ", user fixed.": ", from time().";
+ //log_info << "Using random seed " << config->random_seed << how << std::endl;
}
void init_video()
{
- if(texture_manager != NULL)
- texture_manager->save_textures();
-
- 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;
-
- 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());
+ 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
+
+ SCREEN_WIDTH = config->aspect_width;
+ SCREEN_HEIGHT = config->aspect_height;
+
+ 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);
+ #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 = IMG_Load_RW(get_physfs_SDLRWops(icon_fname), 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;
+ log_warning << "Couldn't find icon '" << icon_fname << "'" << std::endl;
}
#endif
- // use aspect ratio to calculate logical resolution
- if (config->aspectwidth > config->aspectheight) {
- SCREEN_HEIGHT=600;
- SCREEN_WIDTH=600*config->aspectwidth/config->aspectheight;
- }
- else {
- SCREEN_WIDTH=600;
- SCREEN_HEIGHT=600*config->aspectheight/config->aspectwidth;
- }
+ SDL_ShowCursor(0);
- // 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 != NULL)
- texture_manager->reload_textures();
- else
- texture_manager = new TextureManager();
+ log_info << (config->use_fullscreen?"fullscreen ":"window ")
+ << " Window: " << config->screenwidth << "x" << config->screenheight
+ << " Area: " << config->aspect_width << "x" << config->aspect_height << std::endl;
}
static void init_audio()
{
int result = 0;
+#ifndef NO_CATCH
try {
+#endif
if(pre_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");
}
//init_rand(); PAK: this call might subsume the above 3, but I'm chicken!
- main_loop->run();
+ main_loop->run(context);
+#ifndef NO_CATCH
} catch(std::exception& e) {
log_fatal << "Unexpected exception: " << e.what() << std::endl;
result = 1;
log_fatal << "Unexpected exception" << std::endl;
result = 1;
}
+#endif
delete main_loop;
main_loop = NULL;
- free_options_menu();
unload_shared();
quit_audio();