]> git.xonotic.org Git - xonotic/netradiant.git/blobdiff - radiant/mainframe.cpp
slow down non-fast operation but make it more accurate by not using falloff tolerance...
[xonotic/netradiant.git] / radiant / mainframe.cpp
index 31f4635cd6f9315c7ec42f3b7d75df6af0f031ba..546ba9d7a772d8df5965d4a74d37b3628d3beeb6 100644 (file)
@@ -186,44 +186,86 @@ void VFS_Destroy()
 
 #ifdef WIN32
 #include <shlobj.h>
+#include <objbase.h>
+const GUID qFOLDERID_SavedGames = {0x4C5C32FF, 0xBB9D, 0x43b0, {0xB5, 0xB4, 0x2D, 0x72, 0xE5, 0x4E, 0xAA, 0xA4}};
+#define qREFKNOWNFOLDERID GUID
+#define qKF_FLAG_CREATE 0x8000
+#define qKF_FLAG_NO_ALIAS 0x1000
+typedef HRESULT (WINAPI qSHGetKnownFolderPath_t) (qREFKNOWNFOLDERID rfid, DWORD dwFlags, HANDLE hToken, PWSTR *ppszPath);
+static qSHGetKnownFolderPath_t *qSHGetKnownFolderPath;
 #endif
 void HomePaths_Realise()
 {
-#if defined(POSIX)
-  const char* prefix = g_pGameDescription->getKeyValue("prefix");
-  if(!string_empty(prefix))
-  {
-    StringOutputStream path(256);
-    path << DirectoryCleaned(g_get_home_dir()) << prefix << "/";
-    g_qeglobals.m_userEnginePath = path.c_str();
-    Q_mkdir(g_qeglobals.m_userEnginePath.c_str());
-  }
-  else
-#elif defined(WIN32)
-  const char* prefix = g_pGameDescription->getKeyValue("prefix");
-  if(!string_empty(prefix))
+  do
   {
-    StringOutputStream path(256);
-    TCHAR mydocsdir[MAX_PATH + 1];
-    if(SHGetFolderPath(NULL, CSIDL_PERSONAL, NULL, 0, mydocsdir))
+    const char* prefix = g_pGameDescription->getKeyValue("prefix");
+    if(!string_empty(prefix))
     {
-      path << DirectoryCleaned(mydocsdir) << "My Games/" << prefix << "/";
-      // win32: only add it if it already exists
+      StringOutputStream path(256);
+
+#if defined(__APPLE__)
+      path.clear();
+      path << DirectoryCleaned(g_get_home_dir()) << "Library/Application Support" << (prefix+1) << "/";
       if(file_is_directory(path.c_str()))
+      {
         g_qeglobals.m_userEnginePath = path.c_str();
+        break;
+      }
+#endif
+
+#if defined(WIN32)
+      TCHAR mydocsdir[MAX_PATH + 1];
+      wchar_t *mydocsdirw;
+      HMODULE shfolder = LoadLibrary("shfolder.dll");
+      if(shfolder)
+        qSHGetKnownFolderPath = (qSHGetKnownFolderPath_t *) GetProcAddress(shfolder, "SHGetKnownFolderPath");
       else
-        g_qeglobals.m_userEnginePath = EnginePath_get();
-    }
-    else
-    {
-      g_qeglobals.m_userEnginePath = EnginePath_get();
-    }
-  }
-  else
+        qSHGetKnownFolderPath = NULL;
+      CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
+      if(qSHGetKnownFolderPath && qSHGetKnownFolderPath(qFOLDERID_SavedGames, qKF_FLAG_CREATE | qKF_FLAG_NO_ALIAS, NULL, &mydocsdirw) == S_OK)
+      {
+        memset(mydocsdir, 0, sizeof(mydocsdir));
+        wcstombs(mydocsdir, mydocsdirw, sizeof(mydocsdir)-1);
+        CoTaskMemFree(mydocsdirw);
+        path.clear();
+        path << DirectoryCleaned(mydocsdir) << (prefix+1) << "/";
+        if(file_is_directory(path.c_str()))
+        {
+          g_qeglobals.m_userEnginePath = path.c_str();
+          CoUninitialize();
+          FreeLibrary(shfolder);
+          break;
+        }
+      }
+      CoUninitialize();
+      if(shfolder)
+        FreeLibrary(shfolder);
+      if(SHGetFolderPath(NULL, CSIDL_PERSONAL, NULL, 0, mydocsdir))
+      {
+        path.clear();
+        path << DirectoryCleaned(mydocsdir) << "My Games/" << (prefix+1) << "/";
+        // win32: only add it if it already exists
+        if(file_is_directory(path.c_str()))
+        {
+          g_qeglobals.m_userEnginePath = path.c_str();
+          break;
+        }
+      }
 #endif
-  {
+
+#if defined(POSIX)
+      path.clear();
+      path << DirectoryCleaned(g_get_home_dir()) << prefix << "/";
+      g_qeglobals.m_userEnginePath = path.c_str();
+      break;
+#endif
+    }
+
     g_qeglobals.m_userEnginePath = EnginePath_get();
   }
+  while(0);
+
+  Q_mkdir(g_qeglobals.m_userEnginePath.c_str());
 
   {
     StringOutputStream path(256);