X-Git-Url: https://git.xonotic.org/?a=blobdiff_plain;f=fs.c;h=cbcf7c035a35a388302e1c385ba97e700a9133ae;hb=f9ded58b753c4144d9ac31a345b65a6b6bdf1a51;hp=6d20dea7ffb4a134af9c945774d3de38558ff6fa;hpb=f2a40f08af5c0f24b5af4251e0a265675d7b6ad3;p=xonotic%2Fdarkplaces.git diff --git a/fs.c b/fs.c index 6d20dea7..cbcf7c03 100644 --- a/fs.c +++ b/fs.c @@ -106,6 +106,19 @@ CONSTANTS #define ZIP_CDIR_CHUNK_BASE_SIZE 46 #define ZIP_LOCAL_CHUNK_BASE_SIZE 30 +#ifdef LINK_TO_ZLIB +#include + +#define qz_inflate inflate +#define qz_inflateEnd inflateEnd +#define qz_inflateInit2_ inflateInit2_ +#define qz_inflateReset inflateReset +#define qz_deflateInit2_ deflateInit2_ +#define qz_deflateEnd deflateEnd +#define qz_deflate deflate +#define Z_MEMLEVEL_DEFAULT 8 +#else + // Zlib constants (from zlib.h) #define Z_SYNC_FLUSH 2 #define MAX_WBITS 15 @@ -166,6 +179,7 @@ typedef struct unsigned long adler; ///< adler32 value of the uncompressed data unsigned long reserved; ///< reserved for future use } z_stream; +#endif /// inside a package (PAK or PK3) @@ -262,6 +276,7 @@ typedef struct pack_s int handle; int ignorecase; ///< PK3 ignores case int numfiles; + qboolean vpack; packfile_t *files; } pack_t; //@} @@ -334,6 +349,7 @@ PRIVATE FUNCTIONS - PK3 HANDLING ============================================================================= */ +#ifndef LINK_TO_ZLIB // Functions exported from zlib #if defined(WIN32) && defined(ZLIB_USES_WINAPI) # define ZEXPORT WINAPI @@ -348,12 +364,14 @@ static int (ZEXPORT *qz_inflateReset) (z_stream* strm); static int (ZEXPORT *qz_deflateInit2_) (z_stream* strm, int level, int method, int windowBits, int memLevel, int strategy, const char *version, int stream_size); static int (ZEXPORT *qz_deflateEnd) (z_stream* strm); static int (ZEXPORT *qz_deflate) (z_stream* strm, int flush); +#endif #define qz_inflateInit2(strm, windowBits) \ qz_inflateInit2_((strm), (windowBits), ZLIB_VERSION, sizeof(z_stream)) #define qz_deflateInit2(strm, level, method, windowBits, memLevel, strategy) \ qz_deflateInit2_((strm), (level), (method), (windowBits), (memLevel), (strategy), ZLIB_VERSION, sizeof(z_stream)) +#ifndef LINK_TO_ZLIB // qz_deflateInit_((strm), (level), ZLIB_VERSION, sizeof(z_stream)) static dllfunction_t zlibfuncs[] = @@ -370,6 +388,7 @@ static dllfunction_t zlibfuncs[] = /// Handle for Zlib DLL static dllhandle_t zlib_dll = NULL; +#endif #ifdef WIN32 static HRESULT (WINAPI *qSHGetFolderPath) (HWND hwndOwner, int nFolder, HANDLE hToken, DWORD dwFlags, LPTSTR pszPath); @@ -390,7 +409,9 @@ Unload the Zlib DLL */ void PK3_CloseLibrary (void) { +#ifndef LINK_TO_ZLIB Sys_UnloadLibrary (&zlib_dll); +#endif } @@ -403,11 +424,12 @@ Try to load the Zlib DLL */ qboolean PK3_OpenLibrary (void) { +#ifdef LINK_TO_ZLIB + return true; +#else const char* dllnames [] = { -#if defined(WIN64) - "zlib64.dll", -#elif defined(WIN32) +#if defined(WIN32) # ifdef ZLIB_USES_WINAPI "zlibwapi.dll", "zlib.dll", @@ -429,6 +451,7 @@ qboolean PK3_OpenLibrary (void) // Load the DLL return Sys_LoadLibrary (dllnames, &zlib_dll, zlibfuncs); +#endif } /* @@ -440,8 +463,12 @@ See if zlib is available */ qboolean FS_HasZlib(void) { +#ifdef LINK_TO_ZLIB + return true; +#else PK3_OpenLibrary(); // to be safe return (zlib_dll != 0); +#endif } /* @@ -523,7 +550,7 @@ int PK3_BuildFileList (pack_t *pack, const pk3_endOfCentralDir_t *eocd) // Load the central directory in memory central_dir = (unsigned char *)Mem_Alloc (tempmempool, eocd->cdir_size); lseek (pack->handle, eocd->cdir_offset, SEEK_SET); - if(read (pack->handle, central_dir, eocd->cdir_size) != (ssize_t) eocd->cdir_size) + if(read (pack->handle, central_dir, eocd->cdir_size) != (fs_offset_t) eocd->cdir_size) { Mem_Free (central_dir); return -1; @@ -692,7 +719,7 @@ pack_t *FS_LoadPackPK3 (const char *packfile) return NULL; } - Con_Printf("Added packfile %s (%i files)\n", packfile, real_nb_files); + Con_DPrintf("Added packfile %s (%i files)\n", packfile, real_nb_files); return pack; } @@ -831,7 +858,12 @@ void FS_Path_f (void) for (s=fs_searchpaths ; s ; s=s->next) { if (s->pack) - Con_Printf("%s (%i files)\n", s->pack->filename, s->pack->numfiles); + { + if(s->pack->vpack) + Con_Printf("%sdir (virtual pack)\n", s->pack->filename); + else + Con_Printf("%s (%i files)\n", s->pack->filename, s->pack->numfiles); + } else Con_Printf("%s\n", s->filename); } @@ -921,7 +953,28 @@ pack_t *FS_LoadPackPAK (const char *packfile) Mem_Free(info); - Con_Printf("Added packfile %s (%i files)\n", packfile, numpackfiles); + Con_DPrintf("Added packfile %s (%i files)\n", packfile, numpackfiles); + return pack; +} + +/* +==================== +FS_LoadPackVirtual + +Create a package entry associated with a directory file +==================== +*/ +pack_t *FS_LoadPackVirtual (const char *dirname) +{ + pack_t *pack; + pack = (pack_t *)Mem_Alloc(fs_mempool, sizeof (pack_t)); + pack->vpack = true; + pack->ignorecase = false; + strlcpy (pack->filename, dirname, sizeof(pack->filename)); + pack->handle = -1; + pack->numfiles = -1; + pack->files = NULL; + Con_DPrintf("Added packfile %s (virtual pack)\n", dirname); return pack; } @@ -945,6 +998,7 @@ static qboolean FS_AddPack_Fullpath(const char *pakfile, const char *shortname, searchpath_t *search; pack_t *pak = NULL; const char *ext = FS_FileExtension(pakfile); + size_t l; for(search = fs_searchpaths; search; search = search->next) { @@ -959,16 +1013,19 @@ static qboolean FS_AddPack_Fullpath(const char *pakfile, const char *shortname, if(already_loaded) *already_loaded = false; - if(!strcasecmp(ext, "pak")) + if(!strcasecmp(ext, "pk3dir")) + pak = FS_LoadPackVirtual (pakfile); + else if(!strcasecmp(ext, "pak")) pak = FS_LoadPackPAK (pakfile); else if(!strcasecmp(ext, "pk3")) pak = FS_LoadPackPK3 (pakfile); else Con_Printf("\"%s\" does not have a pack extension\n", pakfile); - if (pak) + if(pak) { strlcpy(pak->shortname, shortname, sizeof(pak->shortname)); + //Con_DPrintf(" Registered pack with short name %s\n", shortname); if(keep_plain_dirs) { @@ -992,7 +1049,6 @@ static qboolean FS_AddPack_Fullpath(const char *pakfile, const char *shortname, if(!insertion_point) { search = (searchpath_t *)Mem_Alloc(fs_mempool, sizeof(searchpath_t)); - search->pack = pak; search->next = fs_searchpaths; fs_searchpaths = search; } @@ -1000,7 +1056,6 @@ static qboolean FS_AddPack_Fullpath(const char *pakfile, const char *shortname, // otherwise we want to append directly after insertion_point. { search = (searchpath_t *)Mem_Alloc(fs_mempool, sizeof(searchpath_t)); - search->pack = pak; search->next = insertion_point->next; insertion_point->next = search; } @@ -1008,10 +1063,24 @@ static qboolean FS_AddPack_Fullpath(const char *pakfile, const char *shortname, else { search = (searchpath_t *)Mem_Alloc(fs_mempool, sizeof(searchpath_t)); - search->pack = pak; search->next = fs_searchpaths; fs_searchpaths = search; } + search->pack = pak; + if(pak->vpack) + { + dpsnprintf(search->filename, sizeof(search->filename), "%s/", pakfile); + // if shortname ends with "pk3dir", strip that suffix to make it just "pk3" + // same goes for the name inside the pack structure + l = strlen(pak->shortname); + if(l >= 7) + if(!strcasecmp(pak->shortname + l - 7, ".pk3dir")) + pak->shortname[l - 3] = 0; + l = strlen(pak->filename); + if(l >= 7) + if(!strcasecmp(pak->filename + l - 7, ".pk3dir")) + pak->filename[l - 3] = 0; + } return true; } else @@ -1091,7 +1160,7 @@ void FS_AddGameDirectory (const char *dir) // add any PK3 package in the directory for (i = 0;i < list.numstrings;i++) { - if (!strcasecmp(FS_FileExtension(list.strings[i]), "pk3")) + if (!strcasecmp(FS_FileExtension(list.strings[i]), "pk3") || !strcasecmp(FS_FileExtension(list.strings[i]), "pk3dir")) { FS_AddPack_Fullpath(list.strings[i], list.strings[i] + strlen(dir), NULL, false); } @@ -1184,11 +1253,14 @@ void FS_ClearSearchPath (void) fs_searchpaths = search->next; if (search->pack) { - // close the file - close(search->pack->handle); - // free any memory associated with it - if (search->pack->files) - Mem_Free(search->pack->files); + if(!search->pack->vpack) + { + // close the file + close(search->pack->handle); + // free any memory associated with it + if (search->pack->files) + Mem_Free(search->pack->files); + } Mem_Free(search->pack); } Mem_Free(search); @@ -1488,7 +1560,7 @@ static void FS_ListGameDirs(void) } stringlistfreecontents(&list); - fs_all_gamedirs = Mem_Alloc(fs_mempool, list2.numstrings * sizeof(*fs_all_gamedirs)); + fs_all_gamedirs = (gamedir_t *)Mem_Alloc(fs_mempool, list2.numstrings * sizeof(*fs_all_gamedirs)); for(i = 0; i < list2.numstrings; ++i) { info = FS_CheckGameDir(list2.strings[i]); @@ -1808,6 +1880,7 @@ qfile_t *FS_OpenPackedFile (pack_t* pack, int pack_ind) if (!PK3_GetTrueFileOffset (pfile, pack)) return NULL; +#ifndef LINK_TO_ZLIB // No Zlib DLL = no compressed files if (!zlib_dll && (pfile->flags & PACKFILE_FLAG_DEFLATED)) { @@ -1816,6 +1889,7 @@ qfile_t *FS_OpenPackedFile (pack_t* pack, int pack_ind) pfile->name); return NULL; } +#endif // LordHavoc: lseek affects all duplicates of a handle so we do it before // the dup() call to avoid having to close the dup_handle on error here @@ -1968,7 +2042,7 @@ static searchpath_t *FS_FindFile (const char *name, int* index, qboolean quiet) for (search = fs_searchpaths;search;search = search->next) { // is the element a pak file? - if (search->pack) + if (search->pack && !search->pack->vpack) { int (*strcmp_funct) (const char* str1, const char* str2); int left, right, middle; @@ -1992,16 +2066,16 @@ static searchpath_t *FS_FindFile (const char *name, int* index, qboolean quiet) if (fs_empty_files_in_pack_mark_deletions.integer && pak->files[middle].realsize == 0) { // yes, but the first one is empty so we treat it as not being there - if (!quiet && developer.integer >= 10) - Con_Printf("FS_FindFile: %s is marked as deleted\n", name); + if (!quiet && developer_extra.integer) + Con_DPrintf("FS_FindFile: %s is marked as deleted\n", name); if (index != NULL) *index = -1; return NULL; } - if (!quiet && developer.integer >= 10) - Con_Printf("FS_FindFile: %s in %s\n", + if (!quiet && developer_extra.integer) + Con_DPrintf("FS_FindFile: %s in %s\n", pak->files[middle].name, pak->filename); if (index != NULL) @@ -2022,8 +2096,8 @@ static searchpath_t *FS_FindFile (const char *name, int* index, qboolean quiet) dpsnprintf(netpath, sizeof(netpath), "%s%s", search->filename, name); if (FS_SysFileExists (netpath)) { - if (!quiet && developer.integer >= 10) - Con_Printf("FS_FindFile: %s\n", netpath); + if (!quiet && developer_extra.integer) + Con_DPrintf("FS_FindFile: %s\n", netpath); if (index != NULL) *index = -1; @@ -2032,8 +2106,8 @@ static searchpath_t *FS_FindFile (const char *name, int* index, qboolean quiet) } } - if (!quiet && developer.integer >= 10) - Con_Printf("FS_FindFile: can't find %s\n", name); + if (!quiet && developer_extra.integer) + Con_DPrintf("FS_FindFile: can't find %s\n", name); if (index != NULL) *index = -1; @@ -2062,6 +2136,7 @@ qfile_t *FS_OpenReadFile (const char *filename, qboolean quiet, qboolean nonbloc // Found in the filesystem? if (pack_ind < 0) { + // this works with vpacks, so we are fine char path [MAX_OSPATH]; dpsnprintf (path, sizeof (path), "%s%s", search->filename, filename); return FS_SysOpen (path, "rb", nonblocking); @@ -2172,7 +2247,7 @@ qfile_t* FS_OpenRealFile (const char* filepath, const char* mode, qboolean quiet return NULL; } - dpsnprintf (real_path, sizeof (real_path), "%s/%s", fs_gamedir, filepath); + dpsnprintf (real_path, sizeof (real_path), "%s/%s", fs_gamedir, filepath); // this is never a vpack // If the file is opened in "write", "append", or "read/write" mode, // create directories up to the file. @@ -2847,7 +2922,7 @@ int FS_FileType (const char *filename) if(!search) return FS_FILETYPE_NONE; - if(search->pack) + if(search->pack && !search->pack->vpack) return FS_FILETYPE_FILE; // TODO can't check directories in paks yet, maybe later dpsnprintf(fullpath, sizeof(fullpath), "%s%s", search->filename, filename); @@ -2898,6 +2973,9 @@ int FS_SysFileType (const char *path) if (stat (path,&buf) == -1) return FS_FILETYPE_NONE; +#ifndef S_ISDIR +#define S_ISDIR(a) (((a) & S_IFMT) == S_IFDIR) +#endif if(S_ISDIR(buf.st_mode)) return FS_FILETYPE_DIRECTORY; @@ -2965,7 +3043,7 @@ fssearch_t *FS_Search(const char *pattern, int caseinsensitive, int quiet) for (searchpath = fs_searchpaths;searchpath;searchpath = searchpath->next) { // is the element a pak file? - if (searchpath->pack) + if (searchpath->pack && !searchpath->pack->vpack) { // look through all the pak file elements pak = searchpath->pack; @@ -3241,7 +3319,12 @@ void FS_Which_f(void) return; } if (sp->pack) - Con_Printf("%s is in package %s\n", filename, sp->pack->shortname); + { + if(sp->pack->vpack) + Con_Printf("%s is in virtual package %sdir\n", filename, sp->pack->shortname); + else + Con_Printf("%s is in package %s\n", filename, sp->pack->shortname); + } else Con_Printf("%s is file %s%s\n", filename, sp->filename, filename); } @@ -3274,7 +3357,8 @@ qboolean FS_IsRegisteredQuakePack(const char *name) // search through the path, one element at a time for (search = fs_searchpaths;search;search = search->next) { - if (search->pack && !strcasecmp(FS_FileWithoutPath(search->filename), name)) + if (search->pack && !search->pack->vpack && !strcasecmp(FS_FileWithoutPath(search->filename), name)) + // TODO do we want to support vpacks in here too? { int (*strcmp_funct) (const char* str1, const char* str2); int left, right, middle; @@ -3338,8 +3422,10 @@ unsigned char *FS_Deflate(const unsigned char *data, size_t size, size_t *deflat unsigned char *tmp; *deflated_size = 0; +#ifndef LINK_TO_ZLIB if(!zlib_dll) return NULL; +#endif memset(&strm, 0, sizeof(strm)); strm.zalloc = Z_NULL; @@ -3435,8 +3521,10 @@ unsigned char *FS_Inflate(const unsigned char *data, size_t size, size_t *inflat sizebuf_t outbuf; *inflated_size = 0; +#ifndef LINK_TO_ZLIB if(!zlib_dll) return NULL; +#endif memset(&outbuf, 0, sizeof(outbuf)); outbuf.data = (unsigned char *) Mem_Alloc(tempmempool, sizeof(tmp));