Some more messing around with aspect-ratio, window resize and stuff
[supertux.git] / src / main.cpp
index 84160c7..0b269b7 100644 (file)
 #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"
@@ -53,6 +59,7 @@
 #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; }
@@ -92,11 +99,13 @@ static void init_physfs(const char* argv0)
     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
@@ -126,27 +135,6 @@ static void init_physfs(const char* argv0)
   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";
@@ -164,9 +152,22 @@ 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");
@@ -178,6 +179,7 @@ static void init_physfs(const char* argv0)
       sourcedir = true;
     }
   }
+}
 #endif
 
 #ifdef _WIN32
@@ -198,17 +200,12 @@ static void init_physfs(const char* argv0)
 #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++)
@@ -225,6 +222,7 @@ 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"
@@ -268,35 +266,72 @@ static bool parse_commandline(int argc, char** argv)
       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  = 4;
+      config->aspect_height = 3;
+      
     } 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 parameter for geometry switch");
+        } 
+      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 parameter for aspect switch");
+        } 
+      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);
+            }
+          }
         }
-        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") {
@@ -376,26 +411,10 @@ void init_video()
     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) {
-    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();
@@ -403,21 +422,28 @@ void init_video()
   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
 
   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()
@@ -516,6 +542,8 @@ int main(int argc, char** argv)
     main_controller = new JoystickKeyboardController();
     timelog("config");
     init_config();
+    timelog("addons");
+    AddonManager::get_instance().load_addons();
     timelog("tinygettext");
     init_tinygettext();
     timelog("commandline");