Removed some old event eating code, as randomly discarding events is a bad idea with...
[supertux.git] / src / supertux / main.cpp
index 41dc622..509c60f 100644 (file)
 #include <binreloc.h>
 #include <tinygettext/log.hpp>
 #include <boost/format.hpp>
+#include <stdio.h>
+extern "C" {
+#include <findlocale.h>
+}
 
+#include "video/renderer.hpp"
+#include "video/lightmap.hpp"
 #include "supertux/main.hpp"
 
-#ifdef MACOSX
-namespace supertux_apple {
-#  include <CoreFoundation/CoreFoundation.h>
-} // namespace supertux_apple
-#endif
-
 #include "addon/addon_manager.hpp"
 #include "audio/sound_manager.hpp"
 #include "control/joystickkeyboardcontroller.hpp"
@@ -75,7 +75,7 @@ Main::init_tinygettext()
 {
   dictionary_manager = new tinygettext::DictionaryManager();
   tinygettext::Log::set_log_info_callback(0);
-  dictionary_manager->set_filesystem(std::auto_ptr<tinygettext::FileSystem>(new PhysFSFileSystem));
+  dictionary_manager->set_filesystem(std::unique_ptr<tinygettext::FileSystem>(new PhysFSFileSystem));
 
   dictionary_manager->add_directory("locale");
   dictionary_manager->set_charset("UTF-8");
@@ -84,6 +84,12 @@ Main::init_tinygettext()
   if (g_config->locale != "") 
   {
     dictionary_manager->set_language(tinygettext::Language::from_name(g_config->locale));
+  } else {
+    FL_Locale *locale;
+    FL_FindLocale(&locale);
+    tinygettext::Language language = tinygettext::Language::from_spec( locale->lang?locale->lang:"", locale->country?locale->country:"", locale->variant?locale->variant:"");
+    FL_FreeLocale(&locale);
+    dictionary_manager->set_language(language);
   }
 }
 
@@ -138,7 +144,10 @@ Main::init_physfs(const char* argv0)
   PHYSFS_addToSearchPath(writedir.c_str(), 0);
 
   // when started from source dir...
-  std::string dir = PHYSFS_getBaseDir();
+  char* base_path = SDL_GetBasePath();
+  std::string dir = base_path;
+  SDL_free(base_path);
+
   if (dir[dir.length() - 1] != '/')
     dir += "/";
   dir += "data";
@@ -155,41 +164,6 @@ Main::init_physfs(const char* argv0)
     }
   }
 
-#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) {
     std::string datadir = PHYSFS_getBaseDir();
     datadir = datadir.substr(0, datadir.rfind(INSTALL_SUBDIR_BIN));
@@ -305,6 +279,7 @@ Main::parse_commandline(int argc, char** argv)
       
       g_config->window_size     = Size(800, 600);
       g_config->fullscreen_size = Size(800, 600);
+      g_config->fullscreen_refresh_rate = 0;
       g_config->aspect_size     = Size(0, 0);  // auto detect
       
     } else if(arg == "--window" || arg == "-w") {
@@ -328,6 +303,7 @@ Main::parse_commandline(int argc, char** argv)
         {
           g_config->window_size     = Size(width, height);
           g_config->fullscreen_size = Size(width, height);
+          g_config->fullscreen_refresh_rate = 0;
         }
       }
     } else if(arg == "--aspect" || arg == "-a") {
@@ -406,7 +382,6 @@ Main::parse_commandline(int argc, char** argv)
       g_config->start_level = arg;
     } else {
       log_warning << "Unknown option '" << arg << "'. Use --help to see a list of options" << std::endl;
-      return true;
     }
   }
 
@@ -416,22 +391,13 @@ Main::parse_commandline(int argc, char** argv)
 void
 Main::init_sdl()
 {
-  if(SDL_Init(SDL_INIT_TIMER | SDL_INIT_VIDEO | SDL_INIT_JOYSTICK) < 0) {
+  if(SDL_Init(SDL_INIT_TIMER | SDL_INIT_VIDEO | SDL_INIT_JOYSTICK | SDL_INIT_GAMECONTROLLER) < 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))
-    ;
 }
 
 void
@@ -448,41 +414,24 @@ Main::init_rand()
 void
 Main::init_video()
 {
-  // FIXME: Add something here
-  SCREEN_WIDTH  = 800;
-  SCREEN_HEIGHT = 600;
+  SDL_SetWindowTitle(Renderer::instance()->get_window(), PACKAGE_NAME " " PACKAGE_VERSION);
 
-  context_pointer->init_renderer();
-  g_screen = SDL_GetVideoSurface();
-
-  SDL_WM_SetCaption(PACKAGE_NAME " " PACKAGE_VERSION, 0);
-
-  // set icon
-#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;
+  SDL_Surface* icon = IMG_Load_RW(get_physfs_SDLRWops(icon_fname), true);
+  if (!icon)
+  {
+    log_warning << "Couldn't load icon '" << icon_fname << "': " << SDL_GetError() << std::endl;
   }
-  if(icon != 0) {
-    SDL_WM_SetIcon(icon, 0);
+  else
+  {
+    SDL_SetWindowIcon(Renderer::instance()->get_window(), icon);
     SDL_FreeSurface(icon);
   }
-  else {
-    log_warning << "Couldn't load icon '" << icon_fname << "'" << std::endl;
-  }
-
   SDL_ShowCursor(0);
 
   log_info << (g_config->use_fullscreen?"fullscreen ":"window ")
            << " Window: "     << g_config->window_size
-           << " Fullscreen: " << g_config->fullscreen_size
+           << " Fullscreen: " << g_config->fullscreen_size << "@" << g_config->fullscreen_refresh_rate
            << " Area: "       << g_config->aspect_size << std::endl;
 }
 
@@ -504,47 +453,6 @@ Main::quit_audio()
   }
 }
 
-void
-Main::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:
-          g_screen_manager->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);
-  }
-}
-
 static Uint32 last_timelog_ticks = 0;
 static const char* last_timelog_component = 0;
 
@@ -573,8 +481,8 @@ Main::run(int argc, char** argv)
     if(pre_parse_commandline(argc, argv))
       return 0;
 
-    Console::instance = new Console();
     init_sdl();
+    Console::instance = new Console();
 
     timelog("controller");
     g_jk_controller = new JoystickKeyboardController();
@@ -582,23 +490,22 @@ Main::run(int argc, char** argv)
     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;
+    std::unique_ptr<Renderer> renderer(VideoSystem::new_renderer());
+    std::unique_ptr<Lightmap> lightmap(VideoSystem::new_lightmap());
+    DrawingContext context(*renderer, *lightmap);
     context_pointer = &context;
     init_video();
+    
+    timelog("audio");
+    init_audio();
+    
+    timelog("tinygettext");
+    init_tinygettext();
 
     Console::instance->init_graphics();
 
@@ -607,10 +514,13 @@ Main::run(int argc, char** argv)
 
     timelog("resources");
     Resources::load_shared();
+    
+    timelog("addons");
+    AddonManager::get_instance().load_addons();
 
     timelog(0);
 
-    const std::auto_ptr<PlayerStatus> default_playerstatus(new PlayerStatus());
+    const std::unique_ptr<PlayerStatus> default_playerstatus(new PlayerStatus());
 
     g_screen_manager = new ScreenManager();
 
@@ -620,6 +530,11 @@ Main::run(int argc, char** argv)
       // we have a normal path specified at commandline, not a physfs path.
       // So we simply mount that path here...
       std::string dir = FileSystem::dirname(g_config->start_level);
+      std::string fileProtocol = "file://";
+      std::string::size_type position = dir.find(fileProtocol);
+      if(position != std::string::npos) {
+         dir = dir.replace(position, fileProtocol.length(), "");
+      }
       log_debug << "Adding dir: " << dir << std::endl;
       PHYSFS_addToSearchPath(dir.c_str(), true);
 
@@ -628,7 +543,7 @@ Main::run(int argc, char** argv)
         g_screen_manager->push_screen(new worldmap::WorldMap(
                                  FileSystem::basename(g_config->start_level), default_playerstatus.get()));
       } else {
-        std::auto_ptr<GameSession> session (
+        std::unique_ptr<GameSession> session (
           new GameSession(FileSystem::basename(g_config->start_level), default_playerstatus.get()));
 
         g_config->random_seed =session->get_demo_random_seed(g_config->start_demo);