]> git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - fs.c
Support darkplaces.opt from local files too.
[xonotic/darkplaces.git] / fs.c
diff --git a/fs.c b/fs.c
index c7cc768152f629b5f336d79a051bab4c521b1548..f5df1f4aa99378b15b537af3b038a4a101a0225f 100644 (file)
--- a/fs.c
+++ b/fs.c
@@ -587,8 +587,8 @@ static qboolean PK3_GetEndOfCentralDir (const char *packfile, int packhandle, pk
        Mem_Free (buffer);
 
        if (
-                       eocd->cdir_size < 0 || eocd->cdir_size > filesize ||
-                       eocd->cdir_offset < 0 || eocd->cdir_offset >= filesize ||
+                       eocd->cdir_size > filesize ||
+                       eocd->cdir_offset >= filesize ||
                        eocd->cdir_offset + eocd->cdir_size > filesize
           )
        {
@@ -1642,7 +1642,7 @@ FS_CheckGameDir
 const char *FS_CheckGameDir(const char *gamedir)
 {
        const char *ret;
-       char buf[8192];
+       static char buf[8192];
        char vabuf[1024];
 
        if (FS_CheckNastyPath(gamedir, true))
@@ -1726,55 +1726,78 @@ static void FS_ListGameDirs(void)
 #endif
 */
 
+static void COM_InsertFlags(const char *buf) {
+       const char *p;
+       char *q;
+       const char **new_argv;
+       int i = 0;
+       int args_left = 256;
+       new_argv = (const char **)Mem_Alloc(fs_mempool, sizeof(*com_argv) * (com_argc + args_left + 2));
+       if(com_argc == 0)
+               new_argv[0] = "dummy";  // Can't really happen.
+       else
+               new_argv[0] = com_argv[0];
+       ++i;
+       p = buf;
+       while(COM_ParseToken_Console(&p))
+       {
+               size_t sz = strlen(com_token) + 1; // shut up clang
+               if(i > args_left)
+                       break;
+               q = (char *)Mem_Alloc(fs_mempool, sz);
+               strlcpy(q, com_token, sz);
+               new_argv[i] = q;
+               ++i;
+       }
+       // Now: i <= args_left + 1.
+       if (com_argc >= 1)
+       {
+               memcpy((char *)(&new_argv[i]), &com_argv[1], sizeof(*com_argv) * (com_argc - 1));
+               i += com_argc - 1;
+       }
+       // Now: i <= args_left + (com_argc || 1).
+       new_argv[i] = NULL;
+       com_argv = new_argv;
+       com_argc = i;
+}
+
 /*
 ================
 FS_Init_SelfPack
 ================
 */
+static unsigned char *FS_SysLoadFile (const char *path, mempool_t *pool, qboolean quiet, fs_offset_t *filesizepointer);
 void FS_Init_SelfPack (void)
 {
        PK3_OpenLibrary ();
        fs_mempool = Mem_AllocPool("file management", 0, NULL);
-       if(com_selffd >= 0)
+
+       // Load darkplaces.opt from the FS.
+       if (!COM_CheckParm("-noopt"))
+       {
+               char *buf = (char *) FS_SysLoadFile("darkplaces.opt", tempmempool, true, NULL);
+               if(buf)
+                       COM_InsertFlags(buf);
+               Mem_Free(buf);
+       }
+
+       // Provide the SelfPack.
+       if (!COM_CheckParm("-noselfpack"))
        {
-               fs_selfpack = FS_LoadPackPK3FromFD(com_argv[0], com_selffd, true);
-               if(fs_selfpack)
+               if (com_selffd >= 0)
                {
-                       char *buf, *q;
-                       const char *p;
-                       FS_AddSelfPack();
-                       buf = (char *) FS_LoadFile("darkplaces.opt", tempmempool, true, NULL);
-                       if(buf)
+                       fs_selfpack = FS_LoadPackPK3FromFD(com_argv[0], com_selffd, true);
+                       if(fs_selfpack)
                        {
-                               const char **new_argv;
-                               int i = 0;
-                               int args_left = 256;
-                               new_argv = (const char **)Mem_Alloc(fs_mempool, sizeof(*com_argv) * (com_argc + args_left + 2));
-                               if(com_argc == 0)
+                               FS_AddSelfPack();
+                               if (!COM_CheckParm("-noopt"))
                                {
-                                       new_argv[0] = "dummy";
-                                       com_argc = 1;
+                                       char *buf = (char *) FS_LoadFile("darkplaces.opt", tempmempool, true, NULL);
+                                       if(buf)
+                                               COM_InsertFlags(buf);
+                                       Mem_Free(buf);
                                }
-                               else
-                               {
-                                       memcpy((char *)(&new_argv[0]), &com_argv[0], sizeof(*com_argv) * com_argc);
-                               }
-                               p = buf;
-                               while(COM_ParseToken_Console(&p))
-                               {
-                                       size_t sz = strlen(com_token) + 1; // shut up clang
-                                       if(i >= args_left)
-                                               break;
-                                       q = (char *)Mem_Alloc(fs_mempool, sz);
-                                       strlcpy(q, com_token, sz);
-                                       new_argv[com_argc + i] = q;
-                                       ++i;
-                               }
-                               new_argv[i+com_argc] = NULL;
-                               com_argv = new_argv;
-                               com_argc = com_argc + i;
                        }
-                       Mem_Free(buf);
                }
        }
 }
@@ -1934,7 +1957,7 @@ static int FS_ChooseUserDir(userdirmode_t userdirmode, char *userdir, size_t use
        if(access(va(vabuf, sizeof(vabuf), "%s%s/", userdir, gamedirname1), W_OK | X_OK) >= 0)
                fd = 1;
        else
-               fd = 0;
+               fd = -1;
 #endif
        if(fd >= 0)
        {
@@ -2715,7 +2738,15 @@ int FS_Close (qfile_t* file)
        if (file->filename)
        {
                if (file->flags & QFILE_FLAG_REMOVE)
-                       remove(file->filename);
+               {
+                       if (remove(file->filename) == -1)
+                       {
+                               // No need to report this. If removing a just
+                               // written file failed, this most likely means
+                               // someone else deleted it first - which we
+                               // like.
+                       }
+               }
 
                Mem_Free((void *) file->filename);
        }
@@ -2751,7 +2782,7 @@ fs_offset_t FS_Write (qfile_t* file, const void* data, size_t datasize)
        {
                if (lseek (file->handle, file->buff_ind - file->buff_len, SEEK_CUR) == -1)
                {
-                       Con_Printf("WARNING: could not seek in %s.\n");
+                       Con_Printf("WARNING: could not seek in %s.\n", file->filename);
                }
        }
 
@@ -3220,19 +3251,17 @@ void FS_Purge (qfile_t* file)
 
 /*
 ============
-FS_LoadFile
+FS_LoadAndCloseQFile
 
-Filename are relative to the quake directory.
+Loads full content of a qfile_t and closes it.
 Always appends a 0 byte.
 ============
 */
-unsigned char *FS_LoadFile (const char *path, mempool_t *pool, qboolean quiet, fs_offset_t *filesizepointer)
+static unsigned char *FS_LoadAndCloseQFile (qfile_t *file, const char *path, mempool_t *pool, qboolean quiet, fs_offset_t *filesizepointer)
 {
-       qfile_t *file;
        unsigned char *buf = NULL;
        fs_offset_t filesize = 0;
 
-       file = FS_OpenVirtualFile(path, quiet);
        if (file)
        {
                filesize = file->real_length;
@@ -3257,6 +3286,36 @@ unsigned char *FS_LoadFile (const char *path, mempool_t *pool, qboolean quiet, f
 }
 
 
+/*
+============
+FS_LoadFile
+
+Filename are relative to the quake directory.
+Always appends a 0 byte.
+============
+*/
+unsigned char *FS_LoadFile (const char *path, mempool_t *pool, qboolean quiet, fs_offset_t *filesizepointer)
+{
+       qfile_t *file = FS_OpenVirtualFile(path, quiet);
+       return FS_LoadAndCloseQFile(file, path, pool, quiet, filesizepointer);
+}
+
+
+/*
+============
+FS_SysLoadFile
+
+Filename are OS paths.
+Always appends a 0 byte.
+============
+*/
+static unsigned char *FS_SysLoadFile (const char *path, mempool_t *pool, qboolean quiet, fs_offset_t *filesizepointer)
+{
+       qfile_t *file = FS_SysOpen(path, "rb", false);
+       return FS_LoadAndCloseQFile(file, path, pool, quiet, filesizepointer);
+}
+
+
 /*
 ============
 FS_WriteFile
@@ -3342,7 +3401,7 @@ void FS_DefaultExtension (char *path, const char *extension, size_t size_path)
 
        // if path doesn't have a .EXT, append extension
        // (extension should include the .)
-       src = path + strlen(path) - 1;
+       src = path + strlen(path);
 
        while (*src != '/' && src != path)
        {
@@ -3816,7 +3875,7 @@ qboolean FS_IsRegisteredQuakePack(const char *name)
                                int diff;
 
                                middle = (left + right) / 2;
-                               diff = !strcmp_funct (pak->files[middle].name, "gfx/pop.lmp");
+                               diff = strcmp_funct (pak->files[middle].name, "gfx/pop.lmp");
 
                                // Found it
                                if (!diff)
@@ -3927,8 +3986,7 @@ unsigned char *FS_Deflate(const unsigned char *data, size_t size, size_t *deflat
                return NULL;
        }
 
-       if(deflated_size)
-               *deflated_size = (size_t)strm.total_out;
+       *deflated_size = (size_t)strm.total_out;
 
        memcpy(out, tmp, strm.total_out);
        Mem_Free(tmp);
@@ -4042,8 +4100,7 @@ unsigned char *FS_Inflate(const unsigned char *data, size_t size, size_t *inflat
        memcpy(out, outbuf.data, outbuf.cursize);
        Mem_Free(outbuf.data);
 
-       if(inflated_size)
-               *inflated_size = (size_t)outbuf.cursize;
+       *inflated_size = (size_t)outbuf.cursize;
        
        return out;
 }