]> de.git.xonotic.org Git - xonotic/netradiant.git/blobdiff - radiant/environment.cpp
fix some compile errors on win32
[xonotic/netradiant.git] / radiant / environment.cpp
index 8ca7eb0d41d3cda9986b01dc989d4d38317730c4..040335794d339fd627ce91c0924e804243883823 100644 (file)
@@ -26,9 +26,9 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 #include "stream/stringstream.h"
 #include "debugging/debugging.h"
 #include "os/path.h"
+#include "os/file.h"
 #include "cmdlib.h"
 
-
 int g_argc;
 char** g_argv;
 
@@ -55,6 +55,105 @@ void args_init(int argc, char* argv[])
   g_argv = argv;
 }
 
+char *gamedetect_argv_buffer[1024];
+void gamedetect_found_game(char *game, char *path)
+{
+  int argc;
+  static char buf[128];
+
+  if(g_argv == gamedetect_argv_buffer)
+    return;
+
+  globalOutputStream() << "Detected game " << game << " in " << path << "\n";
+
+  sprintf(buf, "-%s-EnginePath", game);
+  argc = 0;
+  gamedetect_argv_buffer[argc++] = "-global-gamefile";
+  gamedetect_argv_buffer[argc++] = game;
+  gamedetect_argv_buffer[argc++] = buf;
+  gamedetect_argv_buffer[argc++] = path;
+  if((size_t) (argc + g_argc) >= sizeof(gamedetect_argv_buffer) / sizeof(*gamedetect_argv_buffer) - 1)
+    g_argc = sizeof(gamedetect_argv_buffer) / sizeof(*gamedetect_argv_buffer) - g_argc - 1;
+  memcpy(gamedetect_argv_buffer + 4, g_argv, sizeof(*gamedetect_argv_buffer) * g_argc);
+  g_argc += argc;
+  g_argv = gamedetect_argv_buffer;
+}
+
+bool gamedetect_check_game(char *gamefile, const char *checkfile1, const char *checkfile2, char *buf /* must have 64 bytes free after bufpos */, int bufpos)
+{
+       buf[bufpos] = '/';
+
+       strcpy(buf + bufpos + 1, checkfile1);
+       globalOutputStream() << "Checking for a game file in " << buf << "\n";
+       if(!file_exists(buf))
+               return false;
+
+       if(checkfile2)
+       {
+               strcpy(buf + bufpos + 1, checkfile2);
+               globalOutputStream() << "Checking for a game file in " << buf << "\n";
+               if(!file_exists(buf))
+                       return false;
+       }
+
+       buf[bufpos + 1] = 0;
+       gamedetect_found_game(gamefile, buf);
+       return true;
+}
+
+void gamedetect()
+{
+  // if we're inside a Nexuiz install
+  // default to nexuiz.game (unless the user used an option to inhibit this)
+  bool nogamedetect = false;
+  int i;
+  for(i = 1; i < g_argc - 1; ++i)
+    if(g_argv[i][0] == '-')
+       {
+      if(!strcmp(g_argv[i], "-gamedetect"))
+           nogamedetect = !strcmp(g_argv[i+1], "false");
+         ++i;
+       }
+  if(!nogamedetect)
+  {
+       static char buf[1024 + 64];
+       strncpy(buf, environment_get_app_path(), sizeof(buf));
+       buf[sizeof(buf) - 1 - 64] = 0;
+       if(!strlen(buf))
+         return;
+
+       char *p = buf + strlen(buf) - 1; // point directly on the slash of get_app_path
+       while(p != buf)
+       {
+         // TODO add more games to this
+
+         // try to detect Nexuiz installs
+#if defined(WIN32)
+         if(gamedetect_check_game("nexuiz.game", "data/common-spog.pk3", "nexuiz.exe", buf, p - buf))
+#elif defined(__APPLE__)
+         if(gamedetect_check_game("nexuiz.game", "data/common-spog.pk3", "Nexuiz.app/Contents/Info.plist", buf, p - buf))
+#else
+         if(gamedetect_check_game("nexuiz.game", "data/common-spog.pk3", "nexuiz-linux-glx.sh", buf, p - buf))
+#endif
+           return;
+
+         // try to detect Q2World installs
+         if(gamedetect_check_game("q2w.game", "default/quake2world.version", NULL, buf, p - buf))
+           return;
+
+         // try to detect Warsow installs
+         if(gamedetect_check_game("warsow.game", "basewsw/dedicated_autoexec.cfg", NULL, buf, p - buf))
+           return;
+
+         // we found nothing
+         // go backwards
+         --p;
+         while(p != buf && *p != '/' && *p != '\\')
+           --p;
+       }
+  }
+}
+
 namespace
 {
   CopiedString home_path;
@@ -71,6 +170,17 @@ const char* environment_get_app_path()
   return app_path.c_str();
 }
 
+bool portable_app_setup()
+{
+       StringOutputStream confdir(256);
+       confdir << app_path.c_str() << "settings/";
+       if(file_exists(confdir.c_str()))
+       {
+               home_path = confdir.c_str();
+               return true;
+       }
+       return false;
+}
 
 #if defined(POSIX)
 
@@ -134,17 +244,20 @@ void environment_init(int argc, char* argv[])
 
   args_init(argc, argv);
 
+  {
+    char real[PATH_MAX];
+    app_path = getexename(real);
+    ASSERT_MESSAGE(!string_empty(app_path.c_str()), "failed to deduce app path");
+  }
+
+  if(!portable_app_setup())
   {
     StringOutputStream home(256);
     home << DirectoryCleaned(g_get_home_dir()) << ".netradiant/";
     Q_mkdir(home.c_str());
     home_path = home.c_str();
   }
-  {
-    char real[PATH_MAX];
-    app_path = getexename(real);
-    ASSERT_MESSAGE(!string_empty(app_path.c_str()), "failed to deduce app path");
-  }
+  gamedetect();
 }
 
 #elif defined(WIN32)
@@ -155,25 +268,6 @@ void environment_init(int argc, char* argv[])
 {
   args_init(argc, argv);
 
-  {
-    char *appdata = getenv("APPDATA");
-
-    StringOutputStream home(256);
-    if(!appdata || string_empty(appdata))
-    {
-      ERROR_MESSAGE("Application Data folder not available.\n"
-        "Please install shfolder redistributable package.\n"
-        "Radiant will use C:\\ for user preferences.\n");
-      home << "C:";
-    }
-    else
-    {
-      home << PathCleaned(appdata);
-    }
-    home << "/NetRadiantSettings/";
-    Q_mkdir(home.c_str());
-    home_path = home.c_str();
-  }
   {
     // get path to the editor
     char filename[MAX_PATH+1];
@@ -191,6 +285,26 @@ void environment_init(int argc, char* argv[])
     app << PathCleaned(filename);
     app_path = app.c_str();
   }
+
+  if(!portable_app_setup())
+  {
+    char *appdata = getenv("APPDATA");
+    StringOutputStream home(256);
+    if(!appdata || string_empty(appdata))
+    {
+      ERROR_MESSAGE("Application Data folder not available.\n"
+        "Radiant will use C:\\ for user preferences.\n");
+      home << "C:";
+    }
+    else
+    {
+      home << PathCleaned(appdata);
+    }
+    home << "/NetRadiantSettings/";
+    Q_mkdir(home.c_str());
+    home_path = home.c_str();
+  }
+  gamedetect();
 }
 
 #else