X-Git-Url: https://de.git.xonotic.org/?a=blobdiff_plain;f=fs.c;h=904645d6811ae2de99ffd6e7621891cae18d6b73;hb=b052bcd30dcb6147647dd344db6bb0fa5ef32255;hp=9ad570557915918b2c082aaf285735c4e92c26e5;hpb=0e936f973c3dcb7f74691912db3ad85e8805ccf1;p=xonotic%2Fdarkplaces.git diff --git a/fs.c b/fs.c index 9ad57055..904645d6 100644 --- a/fs.c +++ b/fs.c @@ -218,7 +218,6 @@ typedef struct pack_s int ignorecase; // PK3 ignores case int numfiles; packfile_t *files; - mempool_t *mempool; struct pack_s *next; } pack_t; @@ -258,7 +257,6 @@ VARIABLES */ mempool_t *fs_mempool; -mempool_t *pak_mempool; int fs_filesize; @@ -555,13 +553,12 @@ pack_t *FS_LoadPackPK3 (const char *packfile) #endif // Create a package structure in memory - pack = Mem_Alloc (pak_mempool, sizeof (pack_t)); + pack = 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->mempool = Mem_AllocPool (packfile, 0, NULL); - pack->files = Mem_Alloc (pack->mempool, eocd.nbentries * sizeof(packfile_t)); + pack->files = Mem_Alloc(fs_mempool, eocd.nbentries * sizeof(packfile_t)); pack->next = packlist; packlist = pack; @@ -749,13 +746,12 @@ pack_t *FS_LoadPackPAK (const char *packfile) if (numpackfiles > MAX_FILES_IN_PACK) Sys_Error ("%s has %i files", packfile, numpackfiles); - pack = Mem_Alloc(pak_mempool, sizeof (pack_t)); + pack = 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->mempool = Mem_AllocPool(packfile, 0, NULL); - pack->files = Mem_Alloc(pack->mempool, numpackfiles * sizeof(packfile_t)); + pack->files = Mem_Alloc(fs_mempool, numpackfiles * sizeof(packfile_t)); pack->next = packlist; packlist = pack; @@ -807,7 +803,7 @@ void FS_AddGameDirectory (const char *dir) pak = FS_LoadPackPAK (pakfile); if (pak) { - search = Mem_Alloc(pak_mempool, sizeof(searchpath_t)); + search = Mem_Alloc(fs_mempool, sizeof(searchpath_t)); search->pack = pak; search->next = fs_searchpaths; fs_searchpaths = search; @@ -826,7 +822,7 @@ void FS_AddGameDirectory (const char *dir) pak = FS_LoadPackPK3 (pakfile); if (pak) { - search = Mem_Alloc(pak_mempool, sizeof(searchpath_t)); + search = Mem_Alloc(fs_mempool, sizeof(searchpath_t)); search->pack = pak; search->next = fs_searchpaths; fs_searchpaths = search; @@ -839,7 +835,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(pak_mempool, sizeof(searchpath_t)); + search = Mem_Alloc(fs_mempool, sizeof(searchpath_t)); strlcpy (search->filename, dir, sizeof (search->filename)); search->next = fs_searchpaths; fs_searchpaths = search; @@ -853,17 +849,19 @@ FS_AddGameHierarchy */ void FS_AddGameHierarchy (const char *dir) { +#ifndef WIN32 const char *homedir; - - strlcpy (com_modname, dir, sizeof (com_modname)); +#endif // Add the common game directory FS_AddGameDirectory (va("%s/%s", fs_basedir, dir)); +#ifndef WIN32 // Add the personal game directory homedir = getenv ("HOME"); if (homedir != NULL && homedir[0] != '\0') FS_AddGameDirectory (va("%s/.%s/%s", homedir, gameuserdirname, dir)); +#endif } @@ -903,13 +901,6 @@ void FS_Init (void) searchpath_t *search; 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, "."); @@ -940,7 +931,7 @@ void FS_Init (void) if (!com_argv[i] || com_argv[i][0] == '+' || com_argv[i][0] == '-') break; - search = Mem_Alloc(pak_mempool, sizeof(searchpath_t)); + search = Mem_Alloc(fs_mempool, sizeof(searchpath_t)); if (!strcasecmp (FS_FileExtension(com_argv[i]), "pak")) { search->pack = FS_LoadPackPAK (com_argv[i]); @@ -964,7 +955,6 @@ void FS_Init (void) // add the game-specific paths // gamedirname1 (typically id1) FS_AddGameHierarchy (gamedirname1); - Cvar_SetQuick (&scr_screenshot_name, gamescreenshotname); // add the game-specific path, if any if (gamedirname2) @@ -973,6 +963,9 @@ void FS_Init (void) FS_AddGameHierarchy (gamedirname2); } + // set the com_modname (reported in server info) + strlcpy(com_modname, gamedirname1, sizeof(com_modname)); + // -game // Adds basedir/gamedir as an override game // LordHavoc: now supports multiple -game directories @@ -985,7 +978,8 @@ void FS_Init (void) i++; fs_modified = true; FS_AddGameHierarchy (com_argv[i]); - Cvar_SetQuick (&scr_screenshot_name, com_modname); + // update the com_modname + strlcpy (com_modname, com_argv[i], sizeof (com_modname)); } } @@ -994,6 +988,22 @@ void FS_Init (void) unlink (va("%s/qconsole.log", fs_gamedir)); } +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); + + // set the default screenshot name to either the mod name or the + // gamemode screenshot name + if (fs_modified) + Cvar_SetQuick (&scr_screenshot_name, com_modname); + else + Cvar_SetQuick (&scr_screenshot_name, gamescreenshotname); +} + /* ================ FS_Shutdown @@ -1001,7 +1011,6 @@ FS_Shutdown */ void FS_Shutdown (void) { - Mem_FreePool (&pak_mempool); Mem_FreePool (&fs_mempool); } @@ -1012,7 +1021,7 @@ FS_SysOpen Internal function used to create a qfile_t and open the relevant non-packed file on disk ==================== */ -static qfile_t* FS_SysOpen (const char* filepath, const char* mode) +static qfile_t* FS_SysOpen (const char* filepath, const char* mode, qboolean nonblocking) { qfile_t* file; int mod, opt; @@ -1053,6 +1062,11 @@ static qfile_t* FS_SysOpen (const char* filepath, const char* mode) } } +#ifndef WIN32 + if (nonblocking) + opt |= O_NONBLOCK; +#endif + file = Mem_Alloc (fs_mempool, sizeof (*file)); memset (file, 0, sizeof (*file)); file->ungetc = EOF; @@ -1064,12 +1078,13 @@ static qfile_t* FS_SysOpen (const char* filepath, const char* mode) return NULL; } - // For files opened in read mode, we now need to get the length - if (mod == O_RDONLY) - { - file->real_length = lseek (file->handle, 0, SEEK_END); + file->real_length = lseek (file->handle, 0, SEEK_END); + + // For files opened in append mode, we start at the end of the file + if (mod & O_APPEND) + file->position = file->real_length; + else lseek (file->handle, 0, SEEK_SET); - } return file; } @@ -1291,7 +1306,7 @@ 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) +qfile_t *FS_OpenReadFile (const char *filename, qboolean quiet, qboolean nonblocking) { searchpath_t *search; int pack_ind; @@ -1310,7 +1325,7 @@ qfile_t *FS_OpenReadFile (const char *filename, qboolean quiet) { char path [MAX_OSPATH]; dpsnprintf (path, sizeof (path), "%s/%s", search->filename, filename); - return FS_SysOpen (path, "rb"); + return FS_SysOpen (path, "rb", nonblocking); } // So, we found it in a package... @@ -1333,7 +1348,7 @@ FS_Open Open a file. The syntax is the same as fopen ==================== */ -qfile_t* FS_Open (const char* filepath, const char* mode, qboolean quiet) +qfile_t* FS_Open (const char* filepath, const char* mode, qboolean quiet, qboolean nonblocking) { qfile_t* file; @@ -1354,11 +1369,11 @@ qfile_t* FS_Open (const char* filepath, const char* mode, qboolean quiet) // Create directories up to the file FS_CreatePath (real_path); - return FS_SysOpen (real_path, mode); + 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); + file = FS_OpenReadFile (filepath, quiet, nonblocking); if (file != NULL) fs_filesize = file->real_length; @@ -1398,7 +1413,21 @@ Write "datasize" bytes into a file */ size_t FS_Write (qfile_t* file, const void* data, size_t datasize) { - ssize_t result = write (file->handle, data, datasize); + ssize_t result; + + // If necessary, seek to the exact file position we're supposed to be + if (file->buff_ind != file->buff_len) + lseek (file->handle, file->buff_ind - file->buff_len, SEEK_CUR); + + // Purge cached data + FS_Purge (file); + + // Write the buffer and update the position + result = write (file->handle, data, datasize); + file->position = lseek (file->handle, 0, SEEK_CUR); + if (file->real_length < file->position) + file->real_length = file->position; + if (result < 0) return 0; @@ -1417,12 +1446,26 @@ size_t FS_Read (qfile_t* file, void* buffer, size_t buffersize) { size_t count, done; + if (buffersize == 0) + return 0; + + // Get rid of the ungetc character + if (file->ungetc != EOF) + { + ((char*)buffer)[0] = file->ungetc; + buffersize--; + file->ungetc = EOF; + done = 1; + } + else + done = 0; + // First, we copy as many bytes as we can from "buff" if (file->buff_ind < file->buff_len) { count = file->buff_len - file->buff_ind; - done = (buffersize > count) ? count : buffersize; + done += (buffersize > count) ? count : buffersize; memcpy (buffer, &file->buff[file->buff_ind], done); file->buff_ind += done; @@ -1430,8 +1473,6 @@ size_t FS_Read (qfile_t* file, void* buffer, size_t buffersize) if (buffersize == 0) return done; } - else - done = 0; // NOTE: at this point, the read buffer is always empty @@ -1455,9 +1496,8 @@ size_t FS_Read (qfile_t* file, void* buffer, size_t buffersize) done += nb; file->position += nb; - // Invalidate the output data (for FS_Seek) - file->buff_len = 0; - file->buff_ind = 0; + // Purge cached data + FS_Purge (file); } } else @@ -1549,9 +1589,8 @@ size_t FS_Read (qfile_t* file, void* buffer, size_t buffersize) count = buffersize - ztk->zstream.avail_out; file->position += count; - // Invalidate the output data (for FS_Seek) - file->buff_len = 0; - file->buff_ind = 0; + // Purge cached data + FS_Purge (file); } done += count; @@ -1629,19 +1668,14 @@ int FS_VPrintf (qfile_t* file, const char* format, va_list ap) ==================== FS_Getc -Get stored ungetc character or the next character of a file +Get the next character of a file ==================== */ int FS_Getc (qfile_t* file) { char c; - if (file->ungetc != EOF) - { - c = file->ungetc; - file->ungetc = EOF; - } - else if (FS_Read (file, &c, 1) != 1) + if (FS_Read (file, &c, 1) != 1) return EOF; return c; @@ -1652,12 +1686,17 @@ int FS_Getc (qfile_t* file) ==================== FS_UnGetc -Put a character back into the Getc buffer (only supports one character!) +Put a character back into the read buffer (only supports one character!) ==================== */ -void FS_UnGetc (qfile_t* file, unsigned char c) +int FS_UnGetc (qfile_t* file, unsigned char c) { + // If there's already a character waiting to be read + if (file->ungetc != EOF) + return EOF; + file->ungetc = c; + return c; } @@ -1702,9 +1741,8 @@ int FS_Seek (qfile_t* file, long offset, int whence) return 0; } - // Invalidate the read buffer contents - file->buff_ind = 0; - file->buff_len = 0; + // Purge cached data + FS_Purge (file); // Unpacked or uncompressed files can seek directly if (! (file->flags & QFILE_FLAG_DEFLATED)) @@ -1771,6 +1809,21 @@ long FS_Tell (qfile_t* file) } +/* +==================== +FS_Purge + +Erases any buffered input or output data +==================== +*/ +void FS_Purge (qfile_t* file) +{ + file->buff_len = 0; + file->buff_ind = 0; + file->ungetc = EOF; +} + + /* ============ FS_LoadFile @@ -1784,7 +1837,7 @@ qbyte *FS_LoadFile (const char *path, mempool_t *pool, qboolean quiet) qfile_t *file; qbyte *buf; - file = FS_Open (path, "rb", quiet); + file = FS_Open (path, "rb", quiet, false); if (!file) return NULL; @@ -1809,7 +1862,7 @@ qboolean FS_WriteFile (const char *filename, void *data, int len) { qfile_t *file; - file = FS_Open (filename, "wb", false); + file = FS_Open (filename, "wb", false, false); if (!file) { Con_Printf("FS_WriteFile: failed on %s\n", filename);