X-Git-Url: http://de.git.xonotic.org/?a=blobdiff_plain;f=fs.c;h=a0fdcde45b918da9c6e81c7b934d80ece2de1bca;hb=a53125498eeac71ffa52aa0160c3de455799877b;hp=b34116971f36d159af3da2d1fcdbcd629df0520f;hpb=f499e85f5a0f00c4bde11a4e2023d71d40c17055;p=xonotic%2Fdarkplaces.git diff --git a/fs.c b/fs.c index b3411697..a0fdcde4 100644 --- a/fs.c +++ b/fs.c @@ -2,7 +2,6 @@ DarkPlaces file system Copyright (C) 2003-2005 Mathieu Olivier - Copyright (C) 1999,2000 contributors of the QuakeForge project This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -44,6 +43,11 @@ # define O_BINARY 0 #endif +// In case the system doesn't support the O_NONBLOCK flag +#ifndef O_NONBLOCK +# define O_NONBLOCK 0 +#endif + /* @@ -90,7 +94,11 @@ CONSTANTS #define MAX_WBITS 15 #define Z_OK 0 #define Z_STREAM_END 1 -#define ZLIB_VERSION "1.1.4" +#define ZLIB_VERSION "1.2.3" + +// Uncomment the following line if the zlib DLL you have still uses +// the 1.1.x series calling convention on Win32 (WINAPI) +//#define ZLIB_USES_WINAPI /* @@ -106,11 +114,11 @@ TYPES // been cast to "void*" for a matter of simplicity typedef struct { - qbyte *next_in; // next input byte + unsigned char *next_in; // next input byte unsigned int avail_in; // number of bytes available at next_in unsigned long total_in; // total nb of input bytes read so far - qbyte *next_out; // next output byte should be put there + unsigned char *next_out; // next output byte should be put there unsigned int avail_out; // remaining free space at next_out unsigned long total_out; // total nb of bytes output so far @@ -127,12 +135,10 @@ typedef struct } z_stream; -typedef enum -{ - QFILE_FLAG_NONE = 0, - QFILE_FLAG_PACKED = (1 << 0), // inside a package (PAK or PK3) - QFILE_FLAG_DEFLATED = (1 << 1) // file is compressed using the deflate algorithm (PK3 only) -} qfile_flags_t; +// inside a package (PAK or PK3) +#define QFILE_FLAG_PACKED (1 << 0) +// file is compressed using the deflate algorithm (PK3 only) +#define QFILE_FLAG_DEFLATED (1 << 1) #define FILE_BUFF_SIZE 2048 typedef struct @@ -141,12 +147,12 @@ typedef struct size_t comp_length; // length of the compressed file size_t in_ind, in_len; // input buffer current index and length size_t in_position; // position in the compressed file - qbyte input [FILE_BUFF_SIZE]; + unsigned char input [FILE_BUFF_SIZE]; } ztoolkit_t; struct qfile_s { - qfile_flags_t flags; + int flags; int handle; // file descriptor fs_offset_t real_length; // uncompressed file size (for files opened in "read" mode) fs_offset_t position; // current position in the file @@ -154,8 +160,8 @@ struct qfile_s int ungetc; // single stored character from ungetc, cleared to EOF when read // Contents buffer - size_t buff_ind, buff_len; // buffer current index and length - qbyte buff [FILE_BUFF_SIZE]; + fs_offset_t buff_ind, buff_len; // buffer current index and length + unsigned char buff [FILE_BUFF_SIZE]; // For zipped files ztoolkit_t* ztk; @@ -166,7 +172,7 @@ struct qfile_s // You can get the complete ZIP format description from PKWARE website -typedef struct +typedef struct pk3_endOfCentralDir_s { unsigned int signature; unsigned short disknum; @@ -180,13 +186,13 @@ typedef struct // ------ PAK files on disk ------ // -typedef struct +typedef struct dpackfile_s { char name[56]; int filepos, filelen; } dpackfile_t; -typedef struct +typedef struct dpackheader_s { char id[4]; int dirofs; @@ -195,17 +201,15 @@ typedef struct // Packages in memory -typedef enum -{ - PACKFILE_FLAG_NONE = 0, - PACKFILE_FLAG_TRUEOFFS = (1 << 0), // the offset in packfile_t is the true contents offset - PACKFILE_FLAG_DEFLATED = (1 << 1) // file compressed using the deflate algorithm -} packfile_flags_t; +// the offset in packfile_t is the true contents offset +#define PACKFILE_FLAG_TRUEOFFS (1 << 0) +// file compressed using the deflate algorithm +#define PACKFILE_FLAG_DEFLATED (1 << 1) -typedef struct +typedef struct packfile_s { char name [MAX_QPATH]; - packfile_flags_t flags; + int flags; fs_offset_t offset; fs_offset_t packsize; // size in the package fs_offset_t realsize; // real file size (uncompressed) @@ -245,7 +249,7 @@ void FS_Ls_f(void); static packfile_t* FS_AddFileToPack (const char* name, pack_t* pack, fs_offset_t offset, fs_offset_t packsize, - fs_offset_t realsize, packfile_flags_t flags); + fs_offset_t realsize, int flags); /* @@ -258,8 +262,6 @@ VARIABLES mempool_t *fs_mempool; -fs_offset_t fs_filesize; - pack_t *packlist = NULL; searchpath_t *fs_searchpaths = NULL; @@ -271,6 +273,8 @@ char fs_basedir[MAX_OSPATH]; qboolean fs_modified; // set true if using non-id files +cvar_t scr_screenshot_name = {0, "scr_screenshot_name","dp", "prefix name for saved screenshots (changes based on -game commandline, as well as which game mode is running)"}; + /* ============================================================================= @@ -281,7 +285,7 @@ PRIVATE FUNCTIONS - PK3 HANDLING */ // Functions exported from zlib -#ifdef WIN32 +#if defined(WIN32) && defined(ZLIB_USES_WINAPI) # define ZEXPORT WINAPI #else # define ZEXPORT @@ -332,8 +336,15 @@ qboolean PK3_OpenLibrary (void) { const char* dllnames [] = { -#ifdef WIN32 +#if defined(WIN64) + "zlib64.dll", +#elif defined(WIN32) +# ifdef ZLIB_USES_WINAPI + "zlibwapi.dll", "zlib.dll", +# else + "zlib1.dll", +# endif #elif defined(MACOSX) "libz.dylib", #else @@ -368,8 +379,8 @@ Extract the end of the central directory from a PK3 package */ qboolean PK3_GetEndOfCentralDir (const char *packfile, int packhandle, pk3_endOfCentralDir_t *eocd) { - long filesize, maxsize; - qbyte *buffer, *ptr; + fs_offset_t filesize, maxsize; + unsigned char *buffer, *ptr; int ind; // Get the package size @@ -382,7 +393,7 @@ qboolean PK3_GetEndOfCentralDir (const char *packfile, int packhandle, pk3_endOf maxsize = filesize; else maxsize = ZIP_MAX_COMMENTS_SIZE + ZIP_END_CDIR_SIZE; - buffer = Mem_Alloc (tempmempool, maxsize); + buffer = (unsigned char *)Mem_Alloc (tempmempool, maxsize); lseek (packhandle, filesize - maxsize, SEEK_SET); if (read (packhandle, buffer, maxsize) != (fs_offset_t) maxsize) { @@ -431,12 +442,12 @@ Extract the file list from a PK3 file */ int PK3_BuildFileList (pack_t *pack, const pk3_endOfCentralDir_t *eocd) { - qbyte *central_dir, *ptr; + unsigned char *central_dir, *ptr; unsigned int ind; fs_offset_t remaining; // Load the central directory in memory - central_dir = Mem_Alloc (tempmempool, eocd->cdir_size); + central_dir = (unsigned char *)Mem_Alloc (tempmempool, eocd->cdir_size); lseek (pack->handle, eocd->cdir_offset, SEEK_SET); read (pack->handle, central_dir, eocd->cdir_size); @@ -486,7 +497,7 @@ int PK3_BuildFileList (pack_t *pack, const pk3_endOfCentralDir_t *eocd) { char filename [sizeof (pack->files[0].name)]; fs_offset_t offset, packsize, realsize; - packfile_flags_t flags; + int flags; // Extract the name (strip it if necessary) namesize = min(namesize, (int)sizeof (filename) - 1); @@ -539,7 +550,7 @@ pack_t *FS_LoadPackPK3 (const char *packfile) if (! PK3_GetEndOfCentralDir (packfile, packhandle, &eocd)) { - Con_Printf ("%s is not a PK3 file", packfile); + Con_Printf ("%s is not a PK3 file\n", packfile); close(packhandle); return NULL; } @@ -547,7 +558,7 @@ pack_t *FS_LoadPackPK3 (const char *packfile) // Multi-volume ZIP archives are NOT allowed if (eocd.disknum != 0 || eocd.cdir_disknum != 0) { - Con_Printf ("%s is a multi-volume ZIP archive", packfile); + Con_Printf ("%s is a multi-volume ZIP archive\n", packfile); close(packhandle); return NULL; } @@ -557,26 +568,26 @@ pack_t *FS_LoadPackPK3 (const char *packfile) #if MAX_FILES_IN_PACK < 65535 if (eocd.nbentries > MAX_FILES_IN_PACK) { - Con_Printf ("%s contains too many files (%hu)", packfile, eocd.nbentries); + Con_Printf ("%s contains too many files (%hu)\n", packfile, eocd.nbentries); close(packhandle); return NULL; } #endif // Create a package structure in memory - pack = Mem_Alloc(fs_mempool, sizeof (pack_t)); + pack = (pack_t *)Mem_Alloc(fs_mempool, sizeof (pack_t)); pack->ignorecase = true; // PK3 ignores case strlcpy (pack->filename, packfile, sizeof (pack->filename)); pack->handle = packhandle; pack->numfiles = eocd.nbentries; - pack->files = Mem_Alloc(fs_mempool, eocd.nbentries * sizeof(packfile_t)); + pack->files = (packfile_t *)Mem_Alloc(fs_mempool, eocd.nbentries * sizeof(packfile_t)); pack->next = packlist; packlist = pack; real_nb_files = PK3_BuildFileList (pack, &eocd); if (real_nb_files < 0) { - Con_Printf ("%s is not a valid PK3 file", packfile); + Con_Printf ("%s is not a valid PK3 file\n", packfile); close(pack->handle); Mem_Free(pack); return NULL; @@ -596,7 +607,7 @@ Find where the true file data offset is */ qboolean PK3_GetTrueFileOffset (packfile_t *pfile, pack_t *pack) { - qbyte buffer [ZIP_LOCAL_CHUNK_BASE_SIZE]; + unsigned char buffer [ZIP_LOCAL_CHUNK_BASE_SIZE]; fs_offset_t count; // Already found? @@ -608,7 +619,7 @@ qboolean PK3_GetTrueFileOffset (packfile_t *pfile, pack_t *pack) count = read (pack->handle, buffer, ZIP_LOCAL_CHUNK_BASE_SIZE); if (count != ZIP_LOCAL_CHUNK_BASE_SIZE || BuffBigLong (buffer) != ZIP_DATA_HEADER) { - Con_Printf ("Can't retrieve file %s in package %s", pfile->name, pack->filename); + Con_Printf ("Can't retrieve file %s in package %s\n", pfile->name, pack->filename); return false; } @@ -638,7 +649,7 @@ Add a file to the list of files contained into a package */ static packfile_t* FS_AddFileToPack (const char* name, pack_t* pack, fs_offset_t offset, fs_offset_t packsize, - fs_offset_t realsize, packfile_flags_t flags) + fs_offset_t realsize, int flags) { int (*strcmp_funct) (const char* str1, const char* str2); int left, right, middle; @@ -752,7 +763,7 @@ pack_t *FS_LoadPackPAK (const char *packfile) read (packhandle, (void *)&header, sizeof(header)); if (memcmp(header.id, "PACK", 4)) { - Con_Printf ("%s is not a packfile", packfile); + Con_Printf ("%s is not a packfile\n", packfile); close(packhandle); return NULL; } @@ -761,7 +772,7 @@ pack_t *FS_LoadPackPAK (const char *packfile) if (header.dirlen % sizeof(dpackfile_t)) { - Con_Printf ("%s has an invalid directory size", packfile); + Con_Printf ("%s has an invalid directory size\n", packfile); close(packhandle); return NULL; } @@ -770,21 +781,21 @@ pack_t *FS_LoadPackPAK (const char *packfile) if (numpackfiles > MAX_FILES_IN_PACK) { - Con_Printf ("%s has %i files", packfile, numpackfiles); + Con_Printf ("%s has %i files\n", packfile, numpackfiles); close(packhandle); return NULL; } - pack = Mem_Alloc(fs_mempool, sizeof (pack_t)); + pack = (pack_t *)Mem_Alloc(fs_mempool, sizeof (pack_t)); pack->ignorecase = false; // PAK is case sensitive strlcpy (pack->filename, packfile, sizeof (pack->filename)); pack->handle = packhandle; pack->numfiles = 0; - pack->files = Mem_Alloc(fs_mempool, numpackfiles * sizeof(packfile_t)); + pack->files = (packfile_t *)Mem_Alloc(fs_mempool, numpackfiles * sizeof(packfile_t)); pack->next = packlist; packlist = pack; - info = Mem_Alloc(tempmempool, sizeof(*info) * numpackfiles); + info = (dpackfile_t *)Mem_Alloc(tempmempool, sizeof(*info) * numpackfiles); lseek (packhandle, header.dirofs, SEEK_SET); read (packhandle, (void *)info, header.dirlen); @@ -832,7 +843,7 @@ void FS_AddGameDirectory (const char *dir) pak = FS_LoadPackPAK (pakfile); if (pak) { - search = Mem_Alloc(fs_mempool, sizeof(searchpath_t)); + search = (searchpath_t *)Mem_Alloc(fs_mempool, sizeof(searchpath_t)); search->pack = pak; search->next = fs_searchpaths; fs_searchpaths = search; @@ -851,7 +862,7 @@ void FS_AddGameDirectory (const char *dir) pak = FS_LoadPackPK3 (pakfile); if (pak) { - search = Mem_Alloc(fs_mempool, sizeof(searchpath_t)); + search = (searchpath_t *)Mem_Alloc(fs_mempool, sizeof(searchpath_t)); search->pack = pak; search->next = fs_searchpaths; fs_searchpaths = search; @@ -864,7 +875,7 @@ void FS_AddGameDirectory (const char *dir) // Add the directory to the search path // (unpacked files have the priority over packed files) - search = Mem_Alloc(fs_mempool, sizeof(searchpath_t)); + search = (searchpath_t *)Mem_Alloc(fs_mempool, sizeof(searchpath_t)); strlcpy (search->filename, dir, sizeof (search->filename)); search->next = fs_searchpaths; fs_searchpaths = search; @@ -883,7 +894,7 @@ void FS_AddGameHierarchy (const char *dir) #endif // Add the common game directory - FS_AddGameDirectory (va("%s/%s/", fs_basedir, dir)); + FS_AddGameDirectory (va("%s%s/", fs_basedir, dir)); #ifndef WIN32 // Add the personal game directory @@ -931,7 +942,7 @@ void FS_Init (void) fs_mempool = Mem_AllocPool("file management", 0, NULL); - strcpy(fs_basedir, "."); + strcpy(fs_basedir, ""); strcpy(fs_gamedir, ""); #ifdef MACOSX @@ -939,7 +950,7 @@ void FS_Init (void) if (strstr(com_argv[0], ".app/")) { char *split; - char temp[4096]; + split = strstr(com_argv[0], ".app/"); while (split > com_argv[0] && *split != '/') split--; @@ -962,6 +973,10 @@ void FS_Init (void) fs_basedir[i-1] = 0; } + // add a path separator to the end of the basedir if it lacks one + if (fs_basedir[0] && fs_basedir[strlen(fs_basedir) - 1] != '/' && fs_basedir[strlen(fs_basedir) - 1] != '\\') + strlcat(fs_basedir, "/", sizeof(fs_basedir)); + // -path [] ... // Fully specifies the exact search path, overriding the generated one // COMMANDLINEOPTION: Filesystem: -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) @@ -974,13 +989,13 @@ void FS_Init (void) if (!com_argv[i] || com_argv[i][0] == '+' || com_argv[i][0] == '-') break; - search = Mem_Alloc(fs_mempool, sizeof(searchpath_t)); + search = (searchpath_t *)Mem_Alloc(fs_mempool, sizeof(searchpath_t)); if (!strcasecmp (FS_FileExtension(com_argv[i]), "pak")) { search->pack = FS_LoadPackPAK (com_argv[i]); if (!search->pack) { - Con_Printf ("Couldn't load packfile: %s", com_argv[i]); + Con_Printf ("Couldn't load packfile: %s\n", com_argv[i]); Mem_Free(search); continue; } @@ -990,7 +1005,7 @@ void FS_Init (void) search->pack = FS_LoadPackPK3 (com_argv[i]); if (!search->pack) { - Con_Printf ("Couldn't load packfile: %s", com_argv[i]); + Con_Printf ("Couldn't load packfile: %s\n", com_argv[i]); Mem_Free(search); continue; } @@ -1043,9 +1058,9 @@ void FS_Init_Commands(void) { Cvar_RegisterVariable (&scr_screenshot_name); - Cmd_AddCommand ("path", FS_Path_f); - Cmd_AddCommand ("dir", FS_Dir_f); - Cmd_AddCommand ("ls", FS_Ls_f); + Cmd_AddCommand ("path", FS_Path_f, "print searchpath (game directories and archives)"); + Cmd_AddCommand ("dir", FS_Dir_f, "list files in searchpath matching an * filename pattern, one per line"); + Cmd_AddCommand ("ls", FS_Ls_f, "list files in searchpath matching an * filename pattern, multiple per line"); // set the default screenshot name to either the mod name or the // gamemode screenshot name @@ -1113,12 +1128,10 @@ static qfile_t* FS_SysOpen (const char* filepath, const char* mode, qboolean non } } -#ifndef WIN32 if (nonblocking) opt |= O_NONBLOCK; -#endif - file = Mem_Alloc (fs_mempool, sizeof (*file)); + file = (qfile_t *)Mem_Alloc (fs_mempool, sizeof (*file)); memset (file, 0, sizeof (*file)); file->ungetc = EOF; @@ -1156,8 +1169,6 @@ qfile_t *FS_OpenPackedFile (pack_t* pack, int pack_ind) pfile = &pack->files[pack_ind]; - fs_filesize = 0; - // If we don't have the true offset, get it now if (! (pfile->flags & PACKFILE_FLAG_TRUEOFFS)) if (!PK3_GetTrueFileOffset (pfile, pack)) @@ -1176,7 +1187,7 @@ qfile_t *FS_OpenPackedFile (pack_t* pack, int pack_ind) // the dup() call to avoid having to close the dup_handle on error here if (lseek (pack->handle, pfile->offset, SEEK_SET) == -1) { - Con_Printf ("FS_OpenPackedFile: can't lseek to %s in %s (offset: %d)", + Con_Printf ("FS_OpenPackedFile: can't lseek to %s in %s (offset: %d)\n", pfile->name, pack->filename, pfile->offset); return NULL; } @@ -1184,11 +1195,11 @@ qfile_t *FS_OpenPackedFile (pack_t* pack, int pack_ind) dup_handle = dup (pack->handle); if (dup_handle < 0) { - Con_Printf ("FS_OpenPackedFile: can't dup package's handle (pack: %s)", pack->filename); + Con_Printf ("FS_OpenPackedFile: can't dup package's handle (pack: %s)\n", pack->filename); return NULL; } - file = Mem_Alloc (fs_mempool, sizeof (*file)); + file = (qfile_t *)Mem_Alloc (fs_mempool, sizeof (*file)); memset (file, 0, sizeof (*file)); file->handle = dup_handle; file->flags = QFILE_FLAG_PACKED; @@ -1204,7 +1215,7 @@ qfile_t *FS_OpenPackedFile (pack_t* pack, int pack_ind) file->flags |= QFILE_FLAG_DEFLATED; // We need some more variables - ztk = Mem_Alloc (fs_mempool, sizeof (*ztk)); + ztk = (ztoolkit_t *)Mem_Alloc (fs_mempool, sizeof (*ztk)); ztk->comp_length = pfile->packsize; @@ -1223,7 +1234,7 @@ qfile_t *FS_OpenPackedFile (pack_t* pack, int pack_ind) */ if (qz_inflateInit2 (&ztk->zstream, -MAX_WBITS) != Z_OK) { - Con_Printf ("FS_OpenPackedFile: inflate init error (file: %s)", pfile->name); + Con_Printf ("FS_OpenPackedFile: inflate init error (file: %s)\n", pfile->name); close(dup_handle); Mem_Free(file); return NULL; @@ -1235,8 +1246,6 @@ qfile_t *FS_OpenPackedFile (pack_t* pack, int pack_ind) file->ztk = ztk; } - fs_filesize = pfile->realsize; - return file; } @@ -1368,8 +1377,6 @@ static searchpath_t *FS_FindFile (const char *name, int* index, qboolean quiet) FS_OpenReadFile Look for a file in the search paths and open it in read-only mode - -Sets fs_filesize =========== */ qfile_t *FS_OpenReadFile (const char *filename, qboolean quiet, qboolean nonblocking) @@ -1381,10 +1388,7 @@ qfile_t *FS_OpenReadFile (const char *filename, qboolean quiet, qboolean nonbloc // Not found? if (search == NULL) - { - fs_filesize = 0; return NULL; - } // Found in the filesystem? if (pack_ind < 0) @@ -1416,8 +1420,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) { - qfile_t* file; - if (FS_CheckNastyPath(filepath)) { Con_Printf("FS_Open(\"%s\", \"%s\", %s): nasty filename rejected\n", filepath, mode, quiet ? "true" : "false"); @@ -1430,20 +1432,16 @@ qfile_t* FS_Open (const char* filepath, const char* mode, qboolean quiet, qboole char real_path [MAX_OSPATH]; // Open the file on disk directly - dpsnprintf (real_path, sizeof (real_path), "%s%s", fs_gamedir, filepath); + dpsnprintf (real_path, sizeof (real_path), "%s/%s", fs_gamedir, filepath); // Create directories up to the file FS_CreatePath (real_path); return FS_SysOpen (real_path, mode, nonblocking); } - // Else, we look at the various search paths and open the file in read-only mode - file = FS_OpenReadFile (filepath, quiet, nonblocking); - if (file != NULL) - fs_filesize = file->real_length; - - return file; + else + return FS_OpenReadFile (filepath, quiet, nonblocking); } @@ -1483,7 +1481,7 @@ fs_offset_t FS_Write (qfile_t* file, const void* data, size_t datasize) // If necessary, seek to the exact file position we're supposed to be if (file->buff_ind != file->buff_len) - lseek (file->handle, (fs_offset_t)(file->buff_ind - file->buff_len), SEEK_CUR); + lseek (file->handle, file->buff_ind - file->buff_len, SEEK_CUR); // Purge cached data FS_Purge (file); @@ -1529,7 +1527,7 @@ fs_offset_t FS_Read (qfile_t* file, void* buffer, size_t buffersize) // First, we copy as many bytes as we can from "buff" if (file->buff_ind < file->buff_len) { - count = (fs_offset_t)(file->buff_len - file->buff_ind); + count = file->buff_len - file->buff_ind; done += ((fs_offset_t)buffersize > count) ? count : (fs_offset_t)buffersize; memcpy (buffer, &file->buff[file->buff_ind], done); @@ -1545,7 +1543,7 @@ fs_offset_t FS_Read (qfile_t* file, void* buffer, size_t buffersize) // If the file isn't compressed if (! (file->flags & QFILE_FLAG_DEFLATED)) { - int nb; + fs_offset_t nb; // We must take care to not read after the end of the file count = file->real_length - file->position; @@ -1556,7 +1554,7 @@ fs_offset_t FS_Read (qfile_t* file, void* buffer, size_t buffersize) if (count > (fs_offset_t)buffersize) count = (fs_offset_t)buffersize; lseek (file->handle, file->offset + file->position, SEEK_SET); - nb = read (file->handle, &((qbyte*)buffer)[done], count); + nb = read (file->handle, &((unsigned char*)buffer)[done], count); if (nb > 0) { done += nb; @@ -1578,8 +1576,8 @@ fs_offset_t FS_Read (qfile_t* file, void* buffer, size_t buffersize) file->position += nb; // Copy the requested data in "buffer" (as much as we can) - count = (fs_offset_t)((buffersize > file->buff_len) ? file->buff_len : buffersize); - memcpy (&((qbyte*)buffer)[done], file->buff, count); + count = (fs_offset_t)buffersize > file->buff_len ? file->buff_len : (fs_offset_t)buffersize; + memcpy (&((unsigned char*)buffer)[done], file->buff, count); file->buff_ind = count; done += count; } @@ -1610,7 +1608,7 @@ fs_offset_t FS_Read (qfile_t* file, void* buffer, size_t buffersize) lseek (file->handle, file->offset + (fs_offset_t)ztk->in_position, SEEK_SET); if (read (file->handle, ztk->input, count) != count) { - Con_Printf ("FS_Read: unexpected end of file"); + Con_Printf ("FS_Read: unexpected end of file\n"); break; } @@ -1633,29 +1631,29 @@ fs_offset_t FS_Read (qfile_t* file, void* buffer, size_t buffersize) error = qz_inflate (&ztk->zstream, Z_SYNC_FLUSH); if (error != Z_OK && error != Z_STREAM_END) { - Con_Printf ("FS_Read: Can't inflate file"); + Con_Printf ("FS_Read: Can't inflate file\n"); break; } ztk->in_ind = ztk->in_len - ztk->zstream.avail_in; - file->buff_len = sizeof (file->buff) - ztk->zstream.avail_out; - file->position += (fs_offset_t)file->buff_len; + file->buff_len = (fs_offset_t)sizeof (file->buff) - ztk->zstream.avail_out; + file->position += file->buff_len; // Copy the requested data in "buffer" (as much as we can) - count = (fs_offset_t)((buffersize > file->buff_len) ? file->buff_len : buffersize); - memcpy (&((qbyte*)buffer)[done], file->buff, count); + count = (fs_offset_t)buffersize > file->buff_len ? file->buff_len : (fs_offset_t)buffersize; + memcpy (&((unsigned char*)buffer)[done], file->buff, count); file->buff_ind = count; } // Else, we inflate directly in "buffer" else { - ztk->zstream.next_out = &((qbyte*)buffer)[done]; + ztk->zstream.next_out = &((unsigned char*)buffer)[done]; ztk->zstream.avail_out = (unsigned int)buffersize; error = qz_inflate (&ztk->zstream, Z_SYNC_FLUSH); if (error != Z_OK && error != Z_STREAM_END) { - Con_Printf ("FS_Read: Can't inflate file"); + Con_Printf ("FS_Read: Can't inflate file\n"); break; } ztk->in_ind = ztk->in_len - ztk->zstream.avail_in; @@ -1718,18 +1716,17 @@ Print a string into a file int FS_VPrintf (qfile_t* file, const char* format, va_list ap) { int len; - fs_offset_t buff_size; - char *tempbuff = NULL; + fs_offset_t buff_size = MAX_INPUTLINE; + char *tempbuff; - buff_size = 1024; - tempbuff = Mem_Alloc (tempmempool, buff_size); - len = dpvsnprintf (tempbuff, buff_size, format, ap); - while (len < 0) + for (;;) { + tempbuff = (char *)Mem_Alloc (tempmempool, buff_size); + len = dpvsnprintf (tempbuff, buff_size, format, ap); + if (len >= 0 && len < buff_size) + break; Mem_Free (tempbuff); buff_size *= 2; - tempbuff = Mem_Alloc (tempmempool, buff_size); - len = dpvsnprintf (tempbuff, buff_size, format, ap); } len = write (file->handle, tempbuff, len); @@ -1785,21 +1782,21 @@ Move the position index in a file int FS_Seek (qfile_t* file, fs_offset_t offset, int whence) { ztoolkit_t *ztk; - qbyte* buffer; + unsigned char* buffer; fs_offset_t buffersize; // Compute the file offset switch (whence) { case SEEK_CUR: - offset += (long)(file->position - file->buff_len + file->buff_ind); + offset += file->position - file->buff_len + file->buff_ind; break; case SEEK_SET: break; case SEEK_END: - offset += (long)file->real_length; + offset += file->real_length; break; default: @@ -1809,8 +1806,7 @@ int FS_Seek (qfile_t* file, fs_offset_t offset, int whence) return -1; // If we have the data in our read buffer, we don't need to actually seek - if (file->position - (fs_offset_t)file->buff_len <= offset - && offset <= file->position) + if (file->position - file->buff_len <= offset && offset <= file->position) { file->buff_ind = offset + file->buff_len - file->position; return 0; @@ -1849,7 +1845,7 @@ int FS_Seek (qfile_t* file, fs_offset_t offset, int whence) // We need a big buffer to force inflating into it directly buffersize = 2 * sizeof (file->buff); - buffer = Mem_Alloc (tempmempool, buffersize); + buffer = (unsigned char *)Mem_Alloc (tempmempool, buffersize); // Skip all data until we reach the requested offset while (offset > file->position) @@ -1880,7 +1876,7 @@ Give the current position in a file */ fs_offset_t FS_Tell (qfile_t* file) { - return file->position - (fs_offset_t)(file->buff_len + file->buff_ind); + return file->position - file->buff_len + file->buff_ind; } @@ -1907,21 +1903,24 @@ Filename are relative to the quake directory. Always appends a 0 byte. ============ */ -qbyte *FS_LoadFile (const char *path, mempool_t *pool, qboolean quiet) +unsigned char *FS_LoadFile (const char *path, mempool_t *pool, qboolean quiet, fs_offset_t *filesizepointer) { qfile_t *file; - qbyte *buf; + unsigned char *buf = NULL; + fs_offset_t filesize = 0; file = FS_Open (path, "rb", quiet, false); - if (!file) - return NULL; - - buf = Mem_Alloc (pool, fs_filesize + 1); - buf[fs_filesize] = '\0'; - - FS_Read (file, buf, fs_filesize); - FS_Close (file); + if (file) + { + filesize = file->real_length; + buf = (unsigned char *)Mem_Alloc (pool, filesize + 1); + buf[filesize] = '\0'; + FS_Read (file, buf, filesize); + FS_Close (file); + } + if (filesizepointer) + *filesizepointer = filesize; return buf; } @@ -2100,7 +2099,7 @@ fssearch_t *FS_Search(const char *pattern, int caseinsensitive, int quiet) separator = max(slash, backslash); separator = max(separator, colon); basepathlength = separator ? (separator + 1 - pattern) : 0; - basepath = Mem_Alloc (tempmempool, basepathlength + 1); + basepath = (char *)Mem_Alloc (tempmempool, basepathlength + 1); if (basepathlength) memcpy(basepath, pattern, basepathlength); basepath[basepathlength] = 0; @@ -2187,7 +2186,7 @@ fssearch_t *FS_Search(const char *pattern, int caseinsensitive, int quiet) numfiles++; numchars += (int)strlen(listtemp->text) + 1; } - search = Z_Malloc(sizeof(fssearch_t) + numchars + numfiles * sizeof(char *)); + search = (fssearch_t *)Z_Malloc(sizeof(fssearch_t) + numchars + numfiles * sizeof(char *)); search->filenames = (char **)((char *)search + sizeof(fssearch_t)); search->filenamesbuffer = (char *)((char *)search + sizeof(fssearch_t) + numfiles * sizeof(char *)); search->numfilenames = (int)numfiles; @@ -2223,7 +2222,7 @@ int FS_ListDirectory(const char *pattern, int oneperline) int linebufpos; int i, j, k, l; const char *name; - char linebuf[4096]; + char linebuf[MAX_INPUTLINE]; fssearch_t *search; search = FS_Search(pattern, true, true); if (!search)