X-Git-Url: https://git.xonotic.org/?a=blobdiff_plain;f=fs.c;h=4288ab5dd1c20378928cd2edd9c80b6942b68a63;hb=b0938d8646e4f35a30cdb945d4107b4488f1450c;hp=d2fbb52cfc32c3e7c83f149a8dc8f01384e3988c;hpb=475a451bbac370078cf0456b23dda4be39e921cc;p=xonotic%2Fdarkplaces.git diff --git a/fs.c b/fs.c index d2fbb52c..4288ab5d 100644 --- a/fs.c +++ b/fs.c @@ -420,13 +420,13 @@ static const char* shfolderdllnames [] = static dllhandle_t shfolder_dll = NULL; const GUID qFOLDERID_SavedGames = {0x4C5C32FF, 0xBB9D, 0x43b0, {0xB5, 0xB4, 0x2D, 0x72, 0xE5, 0x4E, 0xAA, 0xA4}}; -#define qREFKNOWNFOLDERID GUID +#define qREFKNOWNFOLDERID const GUID * #define qKF_FLAG_CREATE 0x8000 #define qKF_FLAG_NO_ALIAS 0x1000 static HRESULT (WINAPI *qSHGetKnownFolderPath) (qREFKNOWNFOLDERID rfid, DWORD dwFlags, HANDLE hToken, PWSTR *ppszPath); static dllfunction_t shell32funcs[] = { - {"SHGetKnownFolderPathA", (void **) &qSHGetKnownFolderPath}, + {"SHGetKnownFolderPath", (void **) &qSHGetKnownFolderPath}, {NULL, NULL} }; static const char* shell32dllnames [] = @@ -1206,7 +1206,7 @@ void FS_AddGameDirectory (const char *dir) stringlistinit(&list); listdirectory(&list, "", dir); - stringlistsort(&list); + stringlistsort(&list, false); // add any PAK package in the directory for (i = 0;i < list.numstrings;i++) @@ -1364,11 +1364,14 @@ void FS_Rescan (void) // gamedirname1 (typically id1) FS_AddGameHierarchy (gamedirname1); // update the com_modname (used for server info) - strlcpy(com_modname, gamedirname1, sizeof(com_modname)); + if (gamedirname2 && gamedirname2[0]) + strlcpy(com_modname, gamedirname2, sizeof(com_modname)); + else + strlcpy(com_modname, gamedirname1, sizeof(com_modname)); // add the game-specific path, if any // (only used for mission packs and the like, which should set fs_modified) - if (gamedirname2) + if (gamedirname2 && gamedirname2[0]) { fs_modified = true; FS_AddGameHierarchy (gamedirname2); @@ -1644,7 +1647,7 @@ static void FS_ListGameDirs(void) stringlistinit(&list); listdirectory(&list, va("%s/", fs_basedir), ""); listdirectory(&list, va("%s/", fs_userdir), ""); - stringlistsort(&list); + stringlistsort(&list, false); stringlistinit(&list2); for(i = 0; i < list.numstrings; ++i) @@ -1680,6 +1683,13 @@ static void FS_ListGameDirs(void) } } +/* +#ifdef WIN32 +#pragma comment(lib, "shell32.lib") +#include +#endif +*/ + /* ================ FS_Init_SelfPack @@ -1797,7 +1807,14 @@ int FS_ChooseUserDir(userdirmode_t userdirmode, char *userdir, size_t userdirsiz { savedgamesdir[0] = 0; qCoInitializeEx(NULL, COINIT_APARTMENTTHREADED); - if (qSHGetKnownFolderPath(qFOLDERID_SavedGames, qKF_FLAG_CREATE | qKF_FLAG_NO_ALIAS, NULL, &savedgamesdirw) == S_OK) +/* +#ifdef __cplusplus + if (SHGetKnownFolderPath(FOLDERID_SavedGames, KF_FLAG_CREATE | KF_FLAG_NO_ALIAS, NULL, &savedgamesdirw) == S_OK) +#else + if (SHGetKnownFolderPath(&FOLDERID_SavedGames, KF_FLAG_CREATE | KF_FLAG_NO_ALIAS, NULL, &savedgamesdirw) == S_OK) +#endif +*/ + if (qSHGetKnownFolderPath(&qFOLDERID_SavedGames, qKF_FLAG_CREATE | qKF_FLAG_NO_ALIAS, NULL, &savedgamesdirw) == S_OK) { memset(savedgamesdir, 0, sizeof(savedgamesdir)); #if _MSC_VER >= 1400 @@ -1858,19 +1875,40 @@ int FS_ChooseUserDir(userdirmode_t userdirmode, char *userdir, size_t userdirsiz } #endif + +#ifdef WIN32 + // historical behavior... + if (userdirmode == USERDIRMODE_NOHOME && strcmp(gamedirname1, "id1")) + return 0; // don't bother checking if the basedir folder is writable, it's annoying... unless it is Quake on Windows where NOHOME is the default preferred and we have to check for an error case +#endif + // see if we can write to this path (note: won't create path) -#if _MSC_VER >= 1400 +#ifdef WIN32 +# if _MSC_VER >= 1400 _sopen_s(&fd, va("%s%s/config.cfg", userdir, gamedirname1), O_WRONLY | O_CREAT, _SH_DENYNO, _S_IREAD | _S_IWRITE); // note: no O_TRUNC here! -#else +# else fd = open (va("%s%s/config.cfg", userdir, gamedirname1), O_WRONLY | O_CREAT, 0666); // note: no O_TRUNC here! +# endif + if(fd >= 0) + close(fd); +#else + // on Unix, we don't need to ACTUALLY attempt to open the file + if(access(va("%s%s/", userdir, gamedirname1), W_OK | X_OK) >= 0) + fd = 1; + else + fd = 0; #endif if(fd >= 0) { - close(fd); return 1; // good choice - the path exists and is writable } else - return 0; // probably good - failed to write but maybe we need to create path + { + if (userdirmode == USERDIRMODE_NOHOME) + return -1; // path usually already exists, we lack permissions + else + return 0; // probably good - failed to write but maybe we need to create path + } } /* @@ -1904,8 +1942,7 @@ void FS_Init (void) #ifdef DP_FS_BASEDIR strlcpy(fs_basedir, DP_FS_BASEDIR, sizeof(fs_basedir)); #elif defined(MACOSX) - // FIXME: is there a better way to find the directory outside the .app? - // FIXME: check if game data is inside .app bundle + // FIXME: is there a better way to find the directory outside the .app, without using Objective-C? if (strstr(com_argv[0], ".app/")) { char *split; @@ -1913,9 +1950,23 @@ void FS_Init (void) split = strstr(fs_basedir, ".app/"); if (split) { - while (split > fs_basedir && *split != '/') - split--; - *split = 0; + struct stat statresult; + // truncate to just after the .app/ + split[5] = 0; + // see if gamedir exists in Resources + if (stat(va("%s/Contents/Resources/%s", fs_basedir, gamedirname1), &statresult) == 0) + { + // found gamedir inside Resources, use it + strlcat(fs_basedir, "Contents/Resources/", sizeof(fs_basedir)); + } + else + { + // no gamedir found in Resources, gamedir is probably + // outside the .app, remove .app part of path + while (split > fs_basedir && *split != '/') + split--; + *split = 0; + } } } #endif @@ -3476,7 +3527,7 @@ fssearch_t *FS_Search(const char *pattern, int caseinsensitive, int quiet) if (resultlist.numstrings) { - stringlistsort(&resultlist); + stringlistsort(&resultlist, true); numfiles = resultlist.numstrings; numchars = 0; for (resultlistindex = 0;resultlistindex < resultlist.numstrings;resultlistindex++) @@ -3580,7 +3631,7 @@ int FS_ListDirectory(const char *pattern, int oneperline) static void FS_ListDirectoryCmd (const char* cmdname, int oneperline) { const char *pattern; - if (Cmd_Argc() > 3) + if (Cmd_Argc() >= 3) { Con_Printf("usage:\n%s [path/pattern]\n", cmdname); return;