Added --datadir/--userdir command line arguments and SUPERTUX2_DATA_DIR environment...
authorIngo Ruhnke <grumbel@gmail.com>
Mon, 18 Aug 2014 19:01:35 +0000 (21:01 +0200)
committerIngo Ruhnke <grumbel@gmail.com>
Mon, 18 Aug 2014 19:01:35 +0000 (21:01 +0200)
src/supertux/command_line_arguments.cpp
src/supertux/command_line_arguments.hpp
src/supertux/main.cpp

index 2007376..37a3810 100644 (file)
@@ -29,6 +29,8 @@
 CommandLineArguments::CommandLineArguments() :
   m_action(NO_ACTION),
   m_log_level(LOG_WARNING),
+  datadir(),
+  userdir(),
   fullscreen_size(),
   fullscreen_refresh_rate(),
   window_size(),
@@ -68,32 +70,45 @@ void
 CommandLineArguments::print_help(const char* arg0)
 {
   std::cerr << boost::format(_(
+                 "Usage: %s [OPTIONS] [LEVELFILE]\n"
                  "\n"
-                 "Usage: %s [OPTIONS] [LEVELFILE]\n\n"
-                 "CommandLineArguments:\n"
+                 "General Options:\n"
+                 "  -h, --help                   Show this help message and quit\n"
+                 "  -v, --version                Show SuperTux version and quit\n"
                  "  --verbose                    Print verbose messages\n"
                  "  --debug                      Print extra verbose messages\n"
+                "  --print-datadir              Print supertux's primary data directory.\n"
+                 "\n"
+                 "Video 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"
                  "  -d, --default                Reset video settings to default values\n"
                  "  --renderer RENDERER          Use sdl, opengl, or auto to render\n"
+                 "\n"
+                 "Audio Options:\n"
                  "  --disable-sound              Disable sound effects\n"
                  "  --disable-music              Disable music\n"
-                 "  -h, --help                   Show this help message and quit\n"
-                 "  -v, --version                Show SuperTux version and quit\n"
+                 "\n"
+                 "Game Options:\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"
+                 "  -s, --debug-scripts          Enable script debugger.\n"
+                 "\n"
+                 "Demo Recording Options:\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"
-                "  --print-datadir              Print supertux's primary data directory.\n"
+                 "\n"
+                 "Directory Options:\n"
+                 "  --datadir DIR                Set the directory for the games datafiles\n"
+                 "  --userdir DIR                Set the directory for user data (savegames, etc.)\n"
                  "\n"
                  "Environment variables:\n"
-                 "  SUPERTUX2_USER_DIR           Directory for user data (savegames, etc.);\n"
+                 "  SUPERTUX2_USER_DIR           Directory for user data (savegames, etc.)\n"
+                 "  SUPERTUX2_DATA_DIR           Directory for the games datafiles\n"
                  "\n"
                  ))
             % arg0
@@ -137,6 +152,28 @@ CommandLineArguments::parse_args(int argc, char** argv)
         m_log_level = LOG_INFO;
       }
     }
+    else if (arg == "--datadir")
+    {
+      if (i+1 >= argc)
+      {
+        throw std::runtime_error("Need to specify a directory for --datadir");
+      }
+      else
+      {
+        datadir = argv[++i];
+      }
+    }
+    else if (arg == "--userdir")
+    {
+      if (i+1 >= argc)
+      {
+        throw std::runtime_error("Need to specify a directory for --userdir");
+      }
+      else
+      {
+        userdir = argv[++i];
+      }
+    }
     else if (arg == "--fullscreen" || arg == "-f")
     {
       use_fullscreen = true;
index d47215c..e76ebb7 100644 (file)
@@ -42,6 +42,9 @@ private:
   LogLevel m_log_level;
 
 public:
+  boost::optional<std::string> datadir;
+  boost::optional<std::string> userdir;
+
   boost::optional<Size> fullscreen_size;
   boost::optional<int> fullscreen_refresh_rate;
   boost::optional<Size> window_size;
index 3e54020..c7efd55 100644 (file)
 #include <version.h>
 
 #include <SDL_image.h>
-#include <physfs.h>
-#include <iostream>
-#include <tinygettext/log.hpp>
 #include <boost/format.hpp>
+#include <boost/optional.hpp>
+#include <iostream>
+#include <physfs.h>
 #include <stdio.h>
+#include <tinygettext/log.hpp>
 extern "C" {
 #include <findlocale.h>
 }
@@ -113,8 +114,16 @@ Main::init_tinygettext()
 
 class PhysfsSubsystem
 {
+private:
+  boost::optional<std::string> m_forced_datadir;
+  boost::optional<std::string> m_forced_userdir;
+
 public:
-  PhysfsSubsystem(const char* argv0)
+  PhysfsSubsystem(const char* argv0,
+                  boost::optional<std::string> forced_datadir,
+                  boost::optional<std::string> forced_userdir) :
+    m_forced_datadir(forced_datadir),
+    m_forced_userdir(forced_userdir)
   {
     if (!PHYSFS_init(argv0))
     {
@@ -134,19 +143,31 @@ public:
 
   void find_datadir()
   {
-    // check if we run from source dir
-    char* basepath_c = SDL_GetBasePath();
-    std::string basepath = basepath_c;
-    SDL_free(basepath_c);
-
-    std::string datadir = FileSystem::join(basepath, "data");
-    std::string testfname = FileSystem::join(datadir, "credits.txt");
-    if (!FileSystem::exists(testfname))
+    std::string datadir;
+    if (m_forced_datadir)
+    {
+      datadir = *m_forced_datadir;
+    }
+    else if (const char* env_datadir = getenv("SUPERTUX2_DATA_DIR"))
+    {
+      datadir = env_datadir;
+    }
+    else
     {
-      // if the game is not run from the source directory, try to find
-      // the global install location
-      datadir = datadir.substr(0, datadir.rfind(INSTALL_SUBDIR_BIN));
-      datadir = FileSystem::join(datadir, INSTALL_SUBDIR_SHARE);
+      // check if we run from source dir
+      char* basepath_c = SDL_GetBasePath();
+      std::string basepath = basepath_c;
+      SDL_free(basepath_c);
+
+      datadir = FileSystem::join(basepath, "data");
+      std::string testfname = FileSystem::join(datadir, "credits.txt");
+      if (!FileSystem::exists(testfname))
+      {
+        // if the game is not run from the source directory, try to find
+        // the global install location
+        datadir = datadir.substr(0, datadir.rfind(INSTALL_SUBDIR_BIN));
+        datadir = FileSystem::join(datadir, INSTALL_SUBDIR_SHARE);
+      }
     }
 
     if (!PHYSFS_addToSearchPath(datadir.c_str(), 1))
@@ -157,48 +178,50 @@ public:
 
   void find_userdir()
   {
-#ifdef _WIN32
-# define WRITEDIR_NAME PACKAGE_NAME
-#else
-# define WRITEDIR_NAME "." PACKAGE_NAME
-#endif
-
-    std::string writedir;
-
-    const char* env_writedir = getenv("SUPERTUX2_USER_DIR");
-    if (env_writedir)
+    std::string userdir;
+    if (m_forced_userdir)
     {
-      writedir = env_writedir;
+      userdir = *m_forced_userdir;
+    }
+    else if (const char* env_userdir = getenv("SUPERTUX2_USER_DIR"))
+    {
+      userdir = env_userdir;
     }
     else
     {
-      std::string userdir = PHYSFS_getUserDir();
-      writedir = FileSystem::join(userdir, WRITEDIR_NAME);
+      std::string physfs_userdir = PHYSFS_getUserDir();
+#ifdef _WIN32
+      userdir = FileSystem::join(physfs_userdir, "." PACKAGE_NAME);
+#else
+      userdir = FileSystem::join(physfs_userdir, PACKAGE_NAME);
+#endif
     }
 
-    if (!FileSystem::is_directory(writedir))
+    if (!FileSystem::is_directory(userdir))
     {
-      FileSystem::mkdir(writedir);
-      log_info << "Created SuperTux userdir: " << writedir << std::endl;
+      FileSystem::mkdir(userdir);
+      log_info << "Created SuperTux userdir: " << userdir << std::endl;
     }
 
-    if (!PHYSFS_setWriteDir(writedir.c_str()))
+    if (!PHYSFS_setWriteDir(userdir.c_str()))
     {
       std::ostringstream msg;
-      msg << "Failed to use configuration directory '"
-          <<  writedir << "': " << PHYSFS_getLastError();
+      msg << "Failed to use userdir directory '"
+          <<  userdir << "': " << PHYSFS_getLastError();
       throw std::runtime_error(msg.str());
     }
 
-    PHYSFS_addToSearchPath(writedir.c_str(), 0);
+    PHYSFS_addToSearchPath(userdir.c_str(), 0);
   }
 
   void print_search_path()
   {
+    const char* writedir = PHYSFS_getWriteDir();
+    log_info << "PhysfsWritedDir: " << (writedir || "<null>") << std::endl;
     char** searchpath = PHYSFS_getSearchPath();
     for(char** i = searchpath; *i != NULL; ++i)
     {
-      log_info << "[" << *i << "] is in the search path" << std::endl;
+      log_info << "PhysfsSearchPath: " << *i << std::endl;
     }
     PHYSFS_freeList(searchpath);
   }
@@ -372,7 +395,7 @@ Main::run(int argc, char** argv)
       return EXIT_FAILURE;
     }
 
-    PhysfsSubsystem physfs_subsystem(argv[0]);
+    PhysfsSubsystem physfs_subsystem(argv[0], args.datadir, args.userdir);
     physfs_subsystem.print_search_path();
 
     timelog("config");