]> git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - fs.c
changed behavior of gl_workaround_mac_texmatrix, reverting to previous
[xonotic/darkplaces.git] / fs.c
diff --git a/fs.c b/fs.c
index 52a7ab1bf2089351a762b498666bd0a7778e3b7e..e6d69f6583233981129388dd79e0527a86418d8f 100644 (file)
--- a/fs.c
+++ b/fs.c
@@ -318,6 +318,15 @@ static dllfunction_t zlibfuncs[] =
 // Handle for Zlib DLL
 static dllhandle_t zlib_dll = NULL;
 
+#ifdef WIN32
+static HRESULT (WINAPI *qSHGetFolderPath) (HWND hwndOwner, int nFolder, HANDLE hToken, DWORD dwFlags, LPTSTR pszPath);
+static dllfunction_t shfolderfuncs[] =
+{
+       {"SHGetFolderPathA", (void **) &qSHGetFolderPath},
+       {NULL, NULL}
+};
+static dllhandle_t shfolder_dll = NULL;
+#endif
 
 /*
 ====================
@@ -481,9 +490,16 @@ int PK3_BuildFileList (pack_t *pack, const pk3_endOfCentralDir_t *eocd)
                // Check encryption, compression, and attributes
                // 1st uint8  : general purpose bit flag
                //    Check bits 0 (encryption), 3 (data descriptor after the file), and 5 (compressed patched data (?))
+               //
+               // LordHavoc: bit 3 would be a problem if we were scanning the archive
+               // but is not a problem in the central directory where the values are
+               // always real.
+               //
+               // bit 3 seems to always be set by the standard Mac OSX zip maker
+               //
                // 2nd uint8 : external file attributes
                //    Check bits 3 (file is a directory) and 5 (file is a volume (?))
-               if ((ptr[8] & 0x29) == 0 && (ptr[38] & 0x18) == 0)
+               if ((ptr[8] & 0x21) == 0 && (ptr[38] & 0x18) == 0)
                {
                        // Still enough bytes for the name?
                        if (remaining < namesize || namesize >= (int)sizeof (*pack->files))
@@ -1007,9 +1023,8 @@ void FS_AddGameHierarchy (const char *dir)
        char userdir[MAX_QPATH];
 #ifdef WIN32
        TCHAR mydocsdir[MAX_PATH + 1];
-#else
-       const char *homedir;
 #endif
+       const char *homedir;
 
        // Add the common game directory
        FS_AddGameDirectory (va("%s%s/", fs_basedir, dir));
@@ -1018,15 +1033,36 @@ void FS_AddGameHierarchy (const char *dir)
 
        // Add the personal game directory
 #ifdef WIN32
-       if(SHGetFolderPath(NULL, CSIDL_PERSONAL, NULL, 0, mydocsdir) == S_OK)
+       if(qSHGetFolderPath && (qSHGetFolderPath(NULL, CSIDL_PERSONAL, NULL, 0, mydocsdir) == S_OK))
+       {
                dpsnprintf(userdir, sizeof(userdir), "%s/My Games/%s/", mydocsdir, gameuserdirname);
-       fprintf(stderr, "userdir = %s\n", userdir);
+               Con_DPrintf("Obtained personal directory %s from SHGetFolderPath\n", userdir);
+       }
+       else
+       {
+               // use the environment
+               homedir = getenv ("USERPROFILE");
+               if(homedir)
+               {
+                       dpsnprintf(userdir, sizeof(userdir), "%s/My Documents/My Games/%s/", homedir, gameuserdirname);
+                       Con_DPrintf("Obtained personal directory %s from environment\n", userdir);
+               }
+               else
+                       *userdir = 0; // just to make sure it hasn't been written to by SHGetFolderPath returning failure
+       }
+
+       if(!*userdir)
+               Con_DPrintf("Could not obtain home directory; not supporting -mygames\n");
 #else
        homedir = getenv ("HOME");
        if(homedir)
                dpsnprintf(userdir, sizeof(userdir), "%s/.%s/", homedir, gameuserdirname);
+
+       if(!*userdir)
+               Con_DPrintf("Could not obtain home directory; assuming -nohome\n");
 #endif
 
+
 #ifdef WIN32
        if(!COM_CheckParm("-mygames"))
        {
@@ -1041,7 +1077,7 @@ void FS_AddGameHierarchy (const char *dir)
 
        if(COM_CheckParm("-nohome"))
                *userdir = 0;
-       
+
        if((i = COM_CheckParm("-userdir")) && i < com_argc - 1)
                dpsnprintf(userdir, sizeof(userdir), "%s/", com_argv[i+1]);
 
@@ -1244,9 +1280,6 @@ qboolean FS_ChangeGameDirs(int numgamedirs, char gamedirs[][MAX_QPATH], qboolean
                }
        }
 
-       // halt demo playback to close the file
-       CL_Disconnect();
-
        Host_SaveConfig();
 
        fs_numgamedirs = numgamedirs;
@@ -1305,6 +1338,9 @@ void FS_GameDir_f (void)
                return;
        }
 
+       // halt demo playback to close the file
+       CL_Disconnect();
+
        FS_ChangeGameDirs(numgamedirs, gamedirs, true, true);
 }
 
@@ -1335,6 +1371,16 @@ void FS_Init (void)
 {
        int i;
 
+#ifdef WIN32
+       const char* dllnames [] =
+       {
+               "shfolder.dll",  // IE 4, or Win NT and higher
+               NULL
+       };
+       Sys_LoadLibrary(dllnames, &shfolder_dll, shfolderfuncs);
+       // don't care for the result; if it fails, %USERPROFILE% will be used instead
+#endif
+
        fs_mempool = Mem_AllocPool("file management", 0, NULL);
 
        strlcpy(fs_gamedir, "", sizeof(fs_gamedir));
@@ -1379,10 +1425,10 @@ void FS_Init (void)
                strlcat(fs_basedir, "/", sizeof(fs_basedir));
 
        if (!FS_CheckGameDir(gamedirname1))
-               Sys_Error("base gamedir %s%s/ not found!\n", fs_basedir, gamedirname1);
+               Con_Printf("WARNING: base gamedir %s%s/ not found!\n", fs_basedir, gamedirname1);
 
        if (gamedirname2 && !FS_CheckGameDir(gamedirname2))
-               Sys_Error("base gamedir %s%s/ not found!\n", fs_basedir, gamedirname2);
+               Con_Printf("WARNING: base gamedir %s%s/ not found!\n", fs_basedir, gamedirname2);
 
        // -game <gamedir>
        // Adds basedir/gamedir as an override game
@@ -1397,7 +1443,7 @@ void FS_Init (void)
                        if (FS_CheckNastyPath(com_argv[i], true))
                                Sys_Error("-game %s%s/ is a dangerous/non-portable path\n", fs_basedir, com_argv[i]);
                        if (!FS_CheckGameDir(com_argv[i]))
-                               Sys_Error("-game %s%s/ not found!\n", fs_basedir, com_argv[i]);
+                               Con_Printf("WARNING: -game %s%s/ not found!\n", fs_basedir, com_argv[i]);
                        // add the gamedir to the list of active gamedirs
                        strlcpy (fs_gamedirs[fs_numgamedirs], com_argv[i], sizeof(fs_gamedirs[fs_numgamedirs]));
                        fs_numgamedirs++;
@@ -1432,6 +1478,10 @@ void FS_Shutdown (void)
        //  by the OS anyway)
        FS_ClearSearchPath();
        Mem_FreePool (&fs_mempool);
+
+#ifdef WIN32
+       Sys_UnloadLibrary (&shfolder_dll);
+#endif
 }
 
 /*
@@ -1809,17 +1859,6 @@ Open a file. The syntax is the same as fopen
 */
 qfile_t* FS_Open (const char* filepath, const char* mode, qboolean quiet, qboolean nonblocking)
 {
-#ifdef FS_FIX_PATHS
-       char fixedFileName[MAX_QPATH];
-       char *d;
-       strlcpy( fixedFileName, filepath, MAX_QPATH );
-       // try to fix common mistakes (\ instead of /)
-       for( d = fixedFileName ; *d ; d++ )
-               if( *d == '\\' )
-                       *d = '/';
-       filepath = fixedFileName;
-#endif
-
        if (FS_CheckNastyPath(filepath, false))
        {
                Con_Printf("FS_Open(\"%s\", \"%s\", %s): nasty filename rejected\n", filepath, mode, quiet ? "true" : "false");
@@ -2629,25 +2668,25 @@ fssearch_t *FS_Search(const char *pattern, int caseinsensitive, int quiet)
                                if( !nextseparator ) {
                                        nextseparator = start + strlen( start );
                                }
-                               
+
                                // prevseparator points past the '/' right before the wildcard and nextseparator at the one following it (or at the end of the string)
                                // copy everything up except nextseperator
                                strlcpy(subpattern, pattern, min(sizeof(subpattern), (size_t) (nextseparator - pattern + 1)));
                                // find the last '/' before the wildcard
-                               prevseparator = strrchr( subpattern, '/' ) + 1;
+                               prevseparator = strrchr( subpattern, '/' );
                                if (!prevseparator)
-                               {
                                        prevseparator = subpattern;
-                               }
+                               else
+                                       prevseparator++;
                                // copy everything from start to the previous including the '/' (before the wildcard)
                                // everything up to start is already included in the path of matchedSet's entries
                                strlcpy(subpath, start, min(sizeof(subpath), (size_t) ((prevseparator - subpattern) - (start - pattern) + 1)));
-                               
+
                                // for each entry in matchedSet try to open the subdirectories specified in subpath
                                for( dirlistindex = 0 ; dirlistindex < matchedSet.numstrings ; dirlistindex++ ) {
                                        strlcpy( temp, matchedSet.strings[ dirlistindex ], sizeof(temp) );
                                        strlcat( temp, subpath, sizeof(temp) );
-                                       listdirectory( &foundSet, searchpath->filename, temp );                         
+                                       listdirectory( &foundSet, searchpath->filename, temp );
                                }
                                if( dirlistindex == 0 ) {
                                        break;
@@ -2665,7 +2704,7 @@ fssearch_t *FS_Search(const char *pattern, int caseinsensitive, int quiet)
 
                                start = nextseparator;
                        }
-                       
+
                        for (dirlistindex = 0;dirlistindex < matchedSet.numstrings;dirlistindex++)
                        {
                                const char *temp = matchedSet.strings[dirlistindex];