]> de.git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - fs.c
changed a lot of Con_DPrint/Con_DPrintf calls to Con_Print/Con_Printf (non-technical...
[xonotic/darkplaces.git] / fs.c
diff --git a/fs.c b/fs.c
index 093d0ac9ad3a7cec37d5bd7d803d6d9efaf3e164..8298a5e9968ecfbdf88be0de80b9a02cda45f3ac 100644 (file)
--- a/fs.c
+++ b/fs.c
@@ -25,8 +25,6 @@
 
 #include "quakedef.h"
 
-#include <stdlib.h>
-#include <string.h>
 #include <limits.h>
 #include <fcntl.h>
 
 
 #include "fs.h"
 
+// use syscalls instead of f* functions
+#define FS_USESYSCALLS
+
+// Win32 requires us to add O_BINARY, but the other OSes don't have it
+#ifdef FS_USESYSCALLS
+# ifndef O_BINARY
+#  define O_BINARY 0
+# endif
+#endif
+
 
 /*
 
@@ -152,7 +160,11 @@ typedef struct
 struct qfile_s
 {
        fs_flags_t      flags;
+#ifdef FS_USESYSCALLS
+       int                     stream;
+#else
        FILE*           stream;
+#endif
        size_t          length;         // file size on disk (PACKED only)
        size_t          offset;         // offset into a package (PACKED only)
        size_t          position;       // current position in the file (PACKED only)
@@ -212,7 +224,11 @@ typedef struct
 typedef struct pack_s
 {
        char filename [MAX_OSPATH];
+#ifdef FS_USESYSCALLS
+       int handle;
+#else
        FILE *handle;
+#endif
        int ignorecase; // PK3 ignores case
        int numfiles;
        packfile_t *files;
@@ -262,7 +278,7 @@ int fs_filesize;
 
 pack_t *packlist = NULL;
 
-searchpath_t *fs_searchpaths;
+searchpath_t *fs_searchpaths = NULL;
 
 #define MAX_FILES_IN_PACK      65536
 
@@ -317,11 +333,7 @@ Unload the Zlib DLL
 */
 void PK3_CloseLibrary (void)
 {
-       if (!zlib_dll)
-               return;
-
-       Sys_UnloadLibrary (zlib_dll);
-       zlib_dll = NULL;
+       Sys_UnloadLibrary (&zlib_dll);
 }
 
 
@@ -335,7 +347,6 @@ Try to load the Zlib DLL
 qboolean PK3_OpenLibrary (void)
 {
        const char* dllname;
-       const dllfunction_t *func;
 
        // Already loaded?
        if (zlib_dll)
@@ -347,27 +358,14 @@ qboolean PK3_OpenLibrary (void)
        dllname = "libz.so";
 #endif
 
-       // Initializations
-       for (func = zlibfuncs; func && func->name != NULL; func++)
-               *func->funcvariable = NULL;
-
        // Load the DLL
-       if (! (zlib_dll = Sys_LoadLibrary (dllname)))
+       if (! Sys_LoadLibrary (dllname, &zlib_dll, zlibfuncs))
        {
-               Con_Printf("Can't find %s. Compressed files support disabled\n", dllname);
+               Con_Printf ("Compressed files support disabled\n");
                return false;
        }
 
-       // Get the function adresses
-       for (func = zlibfuncs; func && func->name != NULL; func++)
-               if (!(*func->funcvariable = (void *) Sys_GetProcAddress (zlib_dll, func->name)))
-               {
-                       Con_Printf("missing function \"%s\" - broken Zlib library!\n", func->name);
-                       PK3_CloseLibrary ();
-                       return false;
-               }
-
-       Con_Printf("%s loaded. Compressed files support enabled\n", dllname);
+       Con_Printf ("Compressed files support enabled\n");
        return true;
 }
 
@@ -379,15 +377,23 @@ PK3_GetEndOfCentralDir
 Extract the end of the central directory from a PK3 package
 ====================
 */
+#ifdef FS_USESYSCALLS
+qboolean PK3_GetEndOfCentralDir (const char *packfile, int packhandle, pk3_endOfCentralDir_t *eocd)
+#else
 qboolean PK3_GetEndOfCentralDir (const char *packfile, FILE *packhandle, pk3_endOfCentralDir_t *eocd)
+#endif
 {
        long filesize, maxsize;
        qbyte *buffer, *ptr;
        int ind;
 
        // Get the package size
+#ifdef FS_USESYSCALLS
+       filesize = lseek (packhandle, 0, SEEK_END);
+#else
        fseek (packhandle, 0, SEEK_END);
-       filesize = ftell (packhandle);
+       filesize = ftell(packhandle);
+#endif
        if (filesize < ZIP_END_CDIR_SIZE)
                return false;
 
@@ -397,8 +403,13 @@ qboolean PK3_GetEndOfCentralDir (const char *packfile, FILE *packhandle, pk3_end
        else
                maxsize = ZIP_MAX_COMMENTS_SIZE + ZIP_END_CDIR_SIZE;
        buffer = Mem_Alloc (tempmempool, maxsize);
+#ifdef FS_USESYSCALLS
+       lseek (packhandle, filesize - maxsize, SEEK_SET);
+       if (read (packhandle, buffer, maxsize) != (ssize_t) maxsize)
+#else
        fseek (packhandle, filesize - maxsize, SEEK_SET);
-       if (fread (buffer, 1, maxsize, packhandle) != (unsigned long) maxsize)
+       if (fread (buffer, 1, maxsize, packhandle) != (size_t) maxsize)
+#endif
        {
                Mem_Free (buffer);
                return false;
@@ -451,8 +462,13 @@ int PK3_BuildFileList (pack_t *pack, const pk3_endOfCentralDir_t *eocd)
 
        // Load the central directory in memory
        central_dir = Mem_Alloc (tempmempool, eocd->cdir_size);
+#ifdef FS_USESYSCALLS
+       lseek (pack->handle, eocd->cdir_offset, SEEK_SET);
+       read (pack->handle, central_dir, eocd->cdir_size);
+#else
        fseek (pack->handle, eocd->cdir_offset, SEEK_SET);
        fread (central_dir, 1, eocd->cdir_size, pack->handle);
+#endif
 
        // Extract the files properties
        // The parsing is done "by hand" because some fields have variable sizes and
@@ -541,14 +557,24 @@ Create a package entry associated with a PK3 file
 */
 pack_t *FS_LoadPackPK3 (const char *packfile)
 {
+#ifdef FS_USESYSCALLS
+       int packhandle;
+#else
        FILE *packhandle;
+#endif
        pk3_endOfCentralDir_t eocd;
        pack_t *pack;
        int real_nb_files;
 
+#ifdef FS_USESYSCALLS
+       packhandle = open (packfile, O_RDONLY | O_BINARY);
+       if (packhandle < 0)
+               return NULL;
+#else
        packhandle = fopen (packfile, "rb");
        if (!packhandle)
                return NULL;
+#endif
 
        if (! PK3_GetEndOfCentralDir (packfile, packhandle, &eocd))
                Sys_Error ("%s is not a PK3 file", packfile);
@@ -559,10 +585,10 @@ pack_t *FS_LoadPackPK3 (const char *packfile)
 
        // We only need to do this test if MAX_FILES_IN_PACK is lesser than 65535
        // since eocd.nbentries is an unsigned 16 bits integer
-       #if MAX_FILES_IN_PACK < 65535
+#if MAX_FILES_IN_PACK < 65535
        if (eocd.nbentries > MAX_FILES_IN_PACK)
                Sys_Error ("%s contains too many files (%hu)", packfile, eocd.nbentries);
-       #endif
+#endif
 
        // Create a package structure in memory
        pack = Mem_Alloc (pak_mempool, sizeof (pack_t));
@@ -570,7 +596,7 @@ pack_t *FS_LoadPackPK3 (const char *packfile)
        strlcpy (pack->filename, packfile, sizeof (pack->filename));
        pack->handle = packhandle;
        pack->numfiles = eocd.nbentries;
-       pack->mempool = Mem_AllocPool (packfile);
+       pack->mempool = Mem_AllocPool (packfile, 0, NULL);
        pack->files = Mem_Alloc (pack->mempool, eocd.nbentries * sizeof(packfile_t));
        pack->next = packlist;
        packlist = pack;
@@ -601,8 +627,13 @@ void PK3_GetTrueFileOffset (packfile_t *file, pack_t *pack)
                return;
 
        // Load the local file description
+#ifdef FS_USESYSCALLS
+       lseek (pack->handle, file->offset, SEEK_SET);
+       count = read (pack->handle, buffer, ZIP_LOCAL_CHUNK_BASE_SIZE);
+#else
        fseek (pack->handle, file->offset, SEEK_SET);
        count = fread (buffer, 1, ZIP_LOCAL_CHUNK_BASE_SIZE, pack->handle);
+#endif
        if (count != ZIP_LOCAL_CHUNK_BASE_SIZE || BuffBigLong (buffer) != ZIP_DATA_HEADER)
                Sys_Error ("Can't retrieve file %s in package %s", file->name, pack->filename);
 
@@ -634,28 +665,29 @@ static packfile_t* FS_AddFileToPack (const char* name, pack_t* pack,
                                                                         size_t realsize, file_flags_t flags)
 {
        int (*strcmp_funct) (const char* str1, const char* str2);
-       size_t left, right, middle;
-       int diff;
+       int left, right, middle;
        packfile_t *file;
 
        strcmp_funct = pack->ignorecase ? strcasecmp : strcmp;
 
        // Look for the slot we should put that file into (binary search)
        left = 0;
-       right = pack->numfiles;
-       while (left != right)
+       right = pack->numfiles - 1;
+       while (left <= right)
        {
-               middle = (left + right - 1) / 2;
+               int diff;
+
+               middle = (left + right) / 2;
                diff = strcmp_funct (pack->files[middle].name, name);
 
                // If we found the file, there's a problem
                if (!diff)
-                       Sys_Error ("Package %s contains several time the file %s\n",
+                       Sys_Error ("Package %s contains the file %s several times\n",
                                           pack->filename, name);
 
                // If we're too far in the list
                if (diff > 0)
-                       right = middle;
+                       right = middle - 1;
                else
                        left = middle + 1;
        }
@@ -737,15 +769,25 @@ pack_t *FS_LoadPackPAK (const char *packfile)
 {
        dpackheader_t header;
        int i, numpackfiles;
+#ifdef FS_USESYSCALLS
+       int packhandle;
+#else
        FILE *packhandle;
+#endif
        pack_t *pack;
        dpackfile_t *info;      // temporary alloc, allowing huge pack directories
 
+#ifdef FS_USESYSCALLS
+       packhandle = open (packfile, O_RDONLY | O_BINARY);
+       if (packhandle < 0)
+               return NULL;
+       read (packhandle, (void *)&header, sizeof(header));
+#else
        packhandle = fopen (packfile, "rb");
        if (!packhandle)
                return NULL;
-
        fread ((void *)&header, 1, sizeof(header), packhandle);
+#endif
        if (memcmp(header.id, "PACK", 4))
                Sys_Error ("%s is not a packfile", packfile);
        header.dirofs = LittleLong (header.dirofs);
@@ -764,14 +806,19 @@ pack_t *FS_LoadPackPAK (const char *packfile)
        strlcpy (pack->filename, packfile, sizeof (pack->filename));
        pack->handle = packhandle;
        pack->numfiles = 0;
-       pack->mempool = Mem_AllocPool(packfile);
+       pack->mempool = Mem_AllocPool(packfile, 0, NULL);
        pack->files = Mem_Alloc(pack->mempool, numpackfiles * sizeof(packfile_t));
        pack->next = packlist;
        packlist = pack;
 
        info = Mem_Alloc(tempmempool, sizeof(*info) * numpackfiles);
+#ifdef FS_USESYSCALLS
+       lseek (packhandle, header.dirofs, SEEK_SET);
+       read (packhandle, (void *)info, header.dirlen);
+#else
        fseek (packhandle, header.dirofs, SEEK_SET);
        fread ((void *)info, 1, header.dirlen, packhandle);
+#endif
 
        // parse the directory
        for (i = 0;i < numpackfiles;i++)
@@ -806,14 +853,6 @@ void FS_AddGameDirectory (char *dir)
 
        strlcpy (fs_gamedir, dir, sizeof (fs_gamedir));
 
-#ifndef AKVERSION
-       // add the directory to the search path
-       search = Mem_Alloc(pak_mempool, sizeof(searchpath_t));
-       strlcpy (search->filename, dir, sizeof (search->filename));
-       search->next = fs_searchpaths;
-       fs_searchpaths = search;
-#endif
-
        list = listdirectory(dir);
 
        // add any PAK package in the directory
@@ -855,14 +894,12 @@ void FS_AddGameDirectory (char *dir)
        }
        freedirectory(list);
 
-// Unpacked files have the priority over packed files if AKVERSION is defined
-#ifdef AKVERSION
-       // add the directory to the search path
+       // Add the directory to the search path
+       // (unpacked files have the priority over packed files)
        search = Mem_Alloc(pak_mempool, sizeof(searchpath_t));
        strlcpy (search->filename, dir, sizeof (search->filename));
        search->next = fs_searchpaths;
        fs_searchpaths = search;
-#endif
 }
 
 
@@ -886,7 +923,7 @@ char *FS_FileExtension (const char *in)
                separator = backslash;
        if (separator < colon)
                separator = colon;
-       if (dot < separator)
+       if (dot == NULL || dot < separator)
                return "";
        dot++;
        for (i = 0;i < 7 && dot[i];i++)
@@ -906,54 +943,39 @@ void FS_Init (void)
        int i;
        searchpath_t *search;
 
-       fs_mempool = Mem_AllocPool("file management");
-       pak_mempool = Mem_AllocPool("paks");
+       fs_mempool = Mem_AllocPool("file management", 0, NULL);
+       pak_mempool = Mem_AllocPool("paks", 0, NULL);
+
+       Cvar_RegisterVariable (&scr_screenshot_name);
 
        Cmd_AddCommand ("path", FS_Path_f);
        Cmd_AddCommand ("dir", FS_Dir_f);
        Cmd_AddCommand ("ls", FS_Ls_f);
 
        strcpy(fs_basedir, ".");
+       strcpy(fs_gamedir, ".");
 
        PK3_OpenLibrary ();
 
        // -basedir <path>
        // Overrides the system supplied base directory (under GAMENAME)
+// COMMANDLINEOPTION: Filesystem: -basedir <path> chooses what base directory the game data is in, inside this there should be a data directory for the game (for example id1)
        i = COM_CheckParm ("-basedir");
-       if (i && i < com_argc-1)
-               strlcpy (fs_basedir, com_argv[i+1], sizeof (fs_basedir));
-
-       i = strlen (fs_basedir);
-       if (i > 0 && (fs_basedir[i-1] == '\\' || fs_basedir[i-1] == '/'))
-               fs_basedir[i-1] = 0;
-
-       // start up with GAMENAME by default (id1)
-       strlcpy (com_modname, GAMENAME, sizeof (com_modname));
-       FS_AddGameDirectory (va("%s/"GAMENAME, fs_basedir));
-       if (gamedirname[0])
-       {
-               fs_modified = true;
-               strlcpy (com_modname, gamedirname, sizeof (com_modname));
-               FS_AddGameDirectory (va("%s/%s", fs_basedir, gamedirname));
-       }
-
-       // -game <gamedir>
-       // Adds basedir/gamedir as an override game
-       i = COM_CheckParm ("-game");
        if (i && i < com_argc-1)
        {
-               fs_modified = true;
-               strlcpy (com_modname, com_argv[i+1], sizeof (com_modname));
-               FS_AddGameDirectory (va("%s/%s", fs_basedir, com_argv[i+1]));
+               strlcpy (fs_basedir, com_argv[i+1], sizeof (fs_basedir));
+               i = strlen (fs_basedir);
+               if (i > 0 && (fs_basedir[i-1] == '\\' || fs_basedir[i-1] == '/'))
+                       fs_basedir[i-1] = 0;
        }
 
        // -path <dir or packfile> [<dir or packfile>] ...
        // Fully specifies the exact search path, overriding the generated one
+// COMMANDLINEOPTION: Filesystem: -path <path ..> specifies the full search path manually, overriding the generated one, example: -path c:\quake\id1 c:\quake\pak0.pak c:\quake\pak1.pak (not recommended)
        i = COM_CheckParm ("-path");
        if (i)
        {
                fs_modified = true;
-               fs_searchpaths = NULL;
                while (++i < com_argc)
                {
                        if (!com_argv[i] || com_argv[i][0] == '+' || com_argv[i][0] == '-')
@@ -977,6 +999,37 @@ void FS_Init (void)
                        search->next = fs_searchpaths;
                        fs_searchpaths = search;
                }
+               return;
+       }
+
+       // start up with GAMENAME by default (id1)
+       strlcpy (com_modname, GAMENAME, sizeof (com_modname));
+       FS_AddGameDirectory (va("%s/"GAMENAME, fs_basedir));
+       Cvar_SetQuick (&scr_screenshot_name, gamescreenshotname);
+
+       // add the game-specific path, if any
+       if (gamedirname[0])
+       {
+               fs_modified = true;
+               strlcpy (com_modname, gamedirname, sizeof (com_modname));
+               FS_AddGameDirectory (va("%s/%s", fs_basedir, gamedirname));
+       }
+
+       // -game <gamedir>
+       // Adds basedir/gamedir as an override game
+       // LordHavoc: now supports multiple -game directories
+       for (i = 1;i < com_argc;i++)
+       {
+               if (!com_argv[i])
+                       continue;
+               if (!strcmp (com_argv[i], "-game") && i < com_argc-1)
+               {
+                       i++;
+                       fs_modified = true;
+                       strlcpy (com_modname, com_argv[i], sizeof (com_modname));
+                       FS_AddGameDirectory (va("%s/%s", fs_basedir, com_argv[i]));
+                       Cvar_SetQuick (&scr_screenshot_name, com_modname);
+               }
        }
 }
 
@@ -995,12 +1048,28 @@ static qfile_t* FS_SysOpen (const char* filepath, const char* mode)
        file = Mem_Alloc (fs_mempool, sizeof (*file));
        memset (file, 0, sizeof (*file));
 
+#ifdef FS_USESYSCALLS
+       if (strchr(mode, 'r'))
+               file->stream = open (filepath, O_RDONLY | O_BINARY);
+       else if (strchr(mode, 'w'))
+               file->stream = open (filepath, O_WRONLY | O_BINARY | O_CREAT | O_TRUNC, 0666);
+       else if (strchr(mode, 'a'))
+               file->stream = open (filepath, O_RDWR | O_BINARY | O_CREAT | O_APPEND, 0666);
+       else
+               file->stream = -1;
+       if (file->stream < 0)
+       {
+               Mem_Free (file);
+               return NULL;
+       }
+#else
        file->stream = fopen (filepath, mode);
        if (!file->stream)
        {
                Mem_Free (file);
                return NULL;
        }
+#endif
 
        return file;
 }
@@ -1026,14 +1095,23 @@ qfile_t *FS_OpenRead (const char *path, int offs, int len)
        if (offs < 0 || len < 0)
        {
                // We set fs_filesize here for normal files
+#ifdef FS_USESYSCALLS
+               fs_filesize = lseek (file->stream, 0, SEEK_END);
+               lseek (file->stream, 0, SEEK_SET);
+#else
                fseek (file->stream, 0, SEEK_END);
                fs_filesize = ftell (file->stream);
                fseek (file->stream, 0, SEEK_SET);
+#endif
        }
        // Packed file
        else
        {
+#ifdef FS_USESYSCALLS
+               lseek (file->stream, offs, SEEK_SET);
+#else
                fseek (file->stream, offs, SEEK_SET);
+#endif
 
                file->flags |= FS_FLAG_PACKED;
                file->length = len;
@@ -1059,7 +1137,6 @@ static searchpath_t *FS_FindFile (const char *name, int* index, qboolean quiet)
 {
        searchpath_t *search;
        pack_t *pak;
-       int (*strcmp_funct) (const char* str1, const char* str2);
 
        // search through the path, one element at a time
        for (search = fs_searchpaths;search;search = search->next)
@@ -1067,26 +1144,27 @@ static searchpath_t *FS_FindFile (const char *name, int* index, qboolean quiet)
                // is the element a pak file?
                if (search->pack)
                {
-                       size_t left, right, middle;
+                       int (*strcmp_funct) (const char* str1, const char* str2);
+                       int left, right, middle;
 
                        pak = search->pack;
                        strcmp_funct = pak->ignorecase ? strcasecmp : strcmp;
 
                        // Look for the file (binary search)
                        left = 0;
-                       right = pak->numfiles;
-                       while (left != right)
+                       right = pak->numfiles - 1;
+                       while (left <= right)
                        {
                                int diff;
 
-                               middle = (left + right - 1) / 2;
+                               middle = (left + right) / 2;
                                diff = strcmp_funct (pak->files[middle].name, name);
 
                                // Found it
                                if (!diff)
                                {
                                        if (!quiet)
-                                               Sys_Printf("FS_FindFile: %s in %s\n",
+                                               Con_DPrintf("FS_FindFile: %s in %s\n",
                                                                        pak->files[middle].name, pak->filename);
 
                                        if (index != NULL)
@@ -1096,7 +1174,7 @@ static searchpath_t *FS_FindFile (const char *name, int* index, qboolean quiet)
 
                                // If we're too far in the list
                                if (diff > 0)
-                                       right = middle;
+                                       right = middle - 1;
                                else
                                        left = middle + 1;
                        }
@@ -1108,7 +1186,7 @@ static searchpath_t *FS_FindFile (const char *name, int* index, qboolean quiet)
                        if (FS_SysFileExists (netpath))
                        {
                                if (!quiet)
-                                       Sys_Printf("FS_FindFile: %s\n", netpath);
+                                       Con_DPrintf("FS_FindFile: %s\n", netpath);
 
                                if (index != NULL)
                                        *index = -1;
@@ -1118,7 +1196,7 @@ static searchpath_t *FS_FindFile (const char *name, int* index, qboolean quiet)
        }
 
        if (!quiet)
-               Sys_Printf("FS_FindFile: can't find %s\n", name);
+               Con_DPrintf("FS_FindFile: can't find %s\n", name);
 
        if (index != NULL)
                *index = -1;
@@ -1263,7 +1341,11 @@ Close a file
 */
 int FS_Close (qfile_t* file)
 {
+#ifdef FS_USESYSCALLS
+       if (close (file->stream))
+#else
        if (fclose (file->stream))
+#endif
                return EOF;
 
        if (file->z)
@@ -1286,7 +1368,11 @@ Write "datasize" bytes into a file
 */
 size_t FS_Write (qfile_t* file, const void* data, size_t datasize)
 {
+#ifdef FS_USESYSCALLS
+       return write (file->stream, data, datasize);
+#else
        return fwrite (data, 1, datasize, file->stream);
+#endif
 }
 
 
@@ -1304,7 +1390,11 @@ size_t FS_Read (qfile_t* file, void* buffer, size_t buffersize)
 
        // Quick path for unpacked files
        if (! (file->flags & FS_FLAG_PACKED))
+#ifdef FS_USESYSCALLS
+               return read (file->stream, buffer, buffersize);
+#else
                return fread (buffer, 1, buffersize, file->stream);
+#endif
 
        // If the file isn't compressed
        if (! (file->flags & FS_FLAG_DEFLATED))
@@ -1314,7 +1404,11 @@ size_t FS_Read (qfile_t* file, void* buffer, size_t buffersize)
                if (buffersize > count)
                        buffersize = count;
 
+#ifdef FS_USESYSCALLS
+               nb = read (file->stream, buffer, buffersize);
+#else
                nb = fread (buffer, 1, buffersize, file->stream);
+#endif
 
                file->position += nb;
                return nb;
@@ -1352,7 +1446,11 @@ size_t FS_Read (qfile_t* file, void* buffer, size_t buffersize)
 
                        remain = file->length - ztk->in_position;
                        count = (remain > sizeof (ztk->input)) ? sizeof (ztk->input) : remain;
+#ifdef FS_USESYSCALLS
+                       read (file->stream, ztk->input, count);
+#else
                        fread (ztk->input, 1, count, file->stream);
+#endif
 
                        // Update indexes and counters
                        ztk->in_ind = 0;
@@ -1427,7 +1525,11 @@ Flush the file output stream
 */
 int FS_Flush (qfile_t* file)
 {
+#ifdef FS_USESYSCALLS
+       return 0;
+#else
        return fflush (file->stream);
+#endif
 }
 
 
@@ -1456,13 +1558,45 @@ int FS_Printf(qfile_t* file, const char* format, ...)
        va_list args;
 
        va_start (args, format);
-       result = vfprintf (file->stream, format, args);
+       result = FS_VPrintf(file, format, args);
        va_end (args);
 
        return result;
 }
 
 
+/*
+====================
+FS_VPrintf
+
+Print a string into a file
+====================
+*/
+int FS_VPrintf(qfile_t* file, const char* format, va_list ap)
+{
+#ifdef FS_USESYSCALLS
+{
+       int len;
+       char tempstring[1024];
+       len = vsnprintf (tempstring, sizeof(tempstring), format, ap);
+       if (len >= sizeof(tempstring))
+       {
+               int result;
+               char *temp = Mem_Alloc(tempmempool, len + 1);
+               len = vsnprintf (temp, len + 1, format, ap);
+               result = write (file->stream, temp, len);
+               Mem_Free(temp);
+               return result;
+       }
+       else
+               return write (file->stream, tempstring, len);
+}
+#else
+       return vfprintf (file->stream, format, ap);
+#endif
+}
+
+
 /*
 ====================
 FS_Getc
@@ -1492,7 +1626,15 @@ int FS_Seek (qfile_t* file, long offset, int whence)
 {
        // Quick path for unpacked files
        if (! (file->flags & FS_FLAG_PACKED))
+#ifdef FS_USESYSCALLS
+       {
+               if (lseek (file->stream, offset, whence) == -1)
+                       return -1;
+               return 0;
+       }
+#else
                return fseek (file->stream, offset, whence);
+#endif
 
        // Seeking in compressed files is more a hack than anything else,
        // but we need to support it, so here it is.
@@ -1539,7 +1681,11 @@ int FS_Seek (qfile_t* file, long offset, int whence)
                        ztk->out_max = 0;
                        ztk->out_position = 0;
                        file->position = 0;
+#ifdef FS_USESYSCALLS
+                       lseek (file->stream, file->offset, SEEK_SET);
+#else
                        fseek (file->stream, file->offset, SEEK_SET);
+#endif
 
                        // Reset the Zlib stream
                        ztk->zstream.next_in = ztk->input;
@@ -1583,8 +1729,13 @@ int FS_Seek (qfile_t* file, long offset, int whence)
        if (offset < 0 || offset > (long) file->length)
                return -1;
 
+#ifdef FS_USESYSCALLS
+       if (lseek (file->stream, file->offset + offset, SEEK_SET) == -1)
+               return -1;
+#else
        if (fseek (file->stream, file->offset + offset, SEEK_SET) == -1)
                return -1;
+#endif
        file->position = offset;
        return 0;
 }
@@ -1602,7 +1753,11 @@ long FS_Tell (qfile_t* file)
        if (file->flags & FS_FLAG_PACKED)
                return file->position;
 
+#ifdef FS_USESYSCALLS
+       return lseek (file->stream, 0, SEEK_CUR);
+#else
        return ftell (file->stream);
+#endif
 }
 
 
@@ -1618,8 +1773,10 @@ char* FS_Gets (qfile_t* file, char* buffer, int buffersize)
        size_t ind;
 
        // Quick path for unpacked files
+#ifndef FS_USESYSCALLS
        if (! (file->flags & FS_FLAG_PACKED))
                return fgets (buffer, buffersize, file->stream);
+#endif
 
        for (ind = 0; ind < (size_t) buffersize - 1; ind++)
        {
@@ -1697,6 +1854,7 @@ FS_Eof
 Extract a line from a file
 ====================
 */
+// FIXME: remove this function?
 int FS_Eof (qfile_t* file)
 {
        if (file->flags & FS_FLAG_PACKED)
@@ -1707,7 +1865,12 @@ int FS_Eof (qfile_t* file)
                return (file->position == file->length);
        }
 
+#ifdef FS_USESYSCALLS
+       Sys_Error("FS_Eof: not implemented using syscalls\n");
+       return false;
+#else
        return feof (file->stream);
+#endif
 }
 
 
@@ -1918,7 +2081,7 @@ fssearch_t *FS_Search(const char *pattern, int caseinsensitive, int quiet)
        if (separator < colon)
                separator = colon;
        basepathlength = separator - pattern;
-       basepath = Z_Malloc(basepathlength + 1);
+       basepath = Mem_Alloc (tempmempool, basepathlength + 1);
        if (basepathlength)
                memcpy(basepath, pattern, basepathlength);
        basepath[basepathlength] = 0;
@@ -1947,7 +2110,7 @@ fssearch_t *FS_Search(const char *pattern, int caseinsensitive, int quiet)
                                                        if (liststart == NULL)
                                                                liststart = listcurrent;
                                                        if (!quiet)
-                                                               Sys_Printf("SearchPackFile: %s : %s\n", pak->filename, temp);
+                                                               Con_DPrintf("SearchPackFile: %s : %s\n", pak->filename, temp);
                                                }
                                        }
                                        // strip off one path element at a time until empty
@@ -1986,7 +2149,7 @@ fssearch_t *FS_Search(const char *pattern, int caseinsensitive, int quiet)
                                                        if (liststart == NULL)
                                                                liststart = listcurrent;
                                                        if (!quiet)
-                                                               Sys_Printf("SearchDirFile: %s\n", temp);
+                                                               Con_DPrintf("SearchDirFile: %s\n", temp);
                                                }
                                        }
                                }
@@ -2022,7 +2185,7 @@ fssearch_t *FS_Search(const char *pattern, int caseinsensitive, int quiet)
                        stringlistfree(liststart);
        }
 
-       Z_Free(basepath);
+       Mem_Free(basepath);
        return search;
 }
 
@@ -2043,7 +2206,7 @@ int FS_ListDirectory(const char *pattern, int oneperline)
        const char *name;
        char linebuf[4096];
        fssearch_t *search;
-       search = FS_Search(pattern, true, false);
+       search = FS_Search(pattern, true, true);
        if (!search)
                return 0;
        numfiles = search->numfilenames;