]> git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - fs.c
Add support for the .dpk package format used by Unvanquished
[xonotic/darkplaces.git] / fs.c
diff --git a/fs.c b/fs.c
index 3fc3d2a353a9f0dfe4a5e40e927e610a4125b009..f8266c71a2a7e7e10b4ee3c21f1d533f6e657010 100644 (file)
--- a/fs.c
+++ b/fs.c
@@ -382,9 +382,9 @@ char fs_gamedirs[MAX_GAMEDIRS][MAX_QPATH];
 gamedir_t *fs_all_gamedirs = NULL;
 int fs_all_gamedirs_count = 0;
 
-cvar_t scr_screenshot_name = {CVAR_CLIENT | CVAR_NORESETTODEFAULTS, "scr_screenshot_name","dp", "prefix name for saved screenshots (changes based on -game commandline, as well as which game mode is running; the date is encoded using strftime escapes)"};
-cvar_t fs_empty_files_in_pack_mark_deletions = {CVAR_CLIENT | CVAR_SERVER, "fs_empty_files_in_pack_mark_deletions", "0", "if enabled, empty files in a pak/pk3 count as not existing but cancel the search in further packs, effectively allowing patch pak/pk3 files to 'delete' files"};
-cvar_t cvar_fs_gamedir = {CVAR_CLIENT | CVAR_SERVER | CVAR_READONLY | CVAR_NORESETTODEFAULTS, "fs_gamedir", "", "the list of currently selected gamedirs (use the 'gamedir' command to change this)"};
+cvar_t scr_screenshot_name = {CF_CLIENT | CF_PERSISTENT, "scr_screenshot_name","dp", "prefix name for saved screenshots (changes based on -game commandline, as well as which game mode is running; the date is encoded using strftime escapes)"};
+cvar_t fs_empty_files_in_pack_mark_deletions = {CF_CLIENT | CF_SERVER, "fs_empty_files_in_pack_mark_deletions", "0", "if enabled, empty files in a pak/pk3 count as not existing but cancel the search in further packs, effectively allowing patch pak/pk3 files to 'delete' files"};
+cvar_t cvar_fs_gamedir = {CF_CLIENT | CF_SERVER | CF_READONLY | CF_PERSISTENT, "fs_gamedir", "", "the list of currently selected gamedirs (use the 'gamedir' command to change this)"};
 
 
 /*
@@ -495,7 +495,7 @@ Unload the Zlib DLL
 static void PK3_CloseLibrary (void)
 {
 #ifndef LINK_TO_ZLIB
-       Sys_UnloadLibrary (&zlib_dll);
+       Sys_FreeLibrary (&zlib_dll);
 #endif
 }
 
@@ -535,7 +535,7 @@ static qbool PK3_OpenLibrary (void)
                return true;
 
        // Load the DLL
-       return Sys_LoadLibrary (dllnames, &zlib_dll, zlibfuncs);
+       return Sys_LoadDependency (dllnames, &zlib_dll, zlibfuncs);
 #endif
 }
 
@@ -1138,11 +1138,11 @@ static qbool FS_AddPack_Fullpath(const char *pakfile, const char *shortname, qbo
        if(already_loaded)
                *already_loaded = false;
 
-       if(!strcasecmp(ext, "pk3dir"))
+       if(!strcasecmp(ext, "pk3dir") || !strcasecmp(ext, "dpkdir"))
                pak = FS_LoadPackVirtual (pakfile);
        else if(!strcasecmp(ext, "pak"))
                pak = FS_LoadPackPAK (pakfile);
-       else if(!strcasecmp(ext, "pk3"))
+       else if(!strcasecmp(ext, "pk3") || !strcasecmp(ext, "dpk"))
                pak = FS_LoadPackPK3 (pakfile);
        else if(!strcasecmp(ext, "obb")) // android apk expansion
                pak = FS_LoadPackPK3 (pakfile);
@@ -1197,15 +1197,15 @@ static qbool FS_AddPack_Fullpath(const char *pakfile, const char *shortname, qbo
                if(pak->vpack)
                {
                        dpsnprintf(search->filename, sizeof(search->filename), "%s/", pakfile);
-                       // if shortname ends with "pk3dir", strip that suffix to make it just "pk3"
+                       // if shortname ends with "pk3dir" or "dpkdir", strip that suffix to make it just "pk3" or "dpk"
                        // same goes for the name inside the pack structure
                        l = strlen(pak->shortname);
                        if(l >= 7)
-                               if(!strcasecmp(pak->shortname + l - 7, ".pk3dir"))
+                               if(!strcasecmp(pak->shortname + l - 7, ".pk3dir") || !strcasecmp(pak->shortname + l - 7, ".dpkdir"))
                                        pak->shortname[l - 3] = 0;
                        l = strlen(pak->filename);
                        if(l >= 7)
-                               if(!strcasecmp(pak->filename + l - 7, ".pk3dir"))
+                               if(!strcasecmp(pak->filename + l - 7, ".pk3dir") || !strcasecmp(pak->filename + l - 7, ".dpkdir"))
                                        pak->filename[l - 3] = 0;
                }
                return true;
@@ -1287,7 +1287,8 @@ static 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") || !strcasecmp(FS_FileExtension(list.strings[i]), "obb") || !strcasecmp(FS_FileExtension(list.strings[i]), "pk3dir"))
+               if (!strcasecmp(FS_FileExtension(list.strings[i]), "pk3") || !strcasecmp(FS_FileExtension(list.strings[i]), "obb") || !strcasecmp(FS_FileExtension(list.strings[i]), "pk3dir")
+                       || !strcasecmp(FS_FileExtension(list.strings[i]), "dpk") || !strcasecmp(FS_FileExtension(list.strings[i]), "dpkdir"))
                {
                        FS_AddPack_Fullpath(list.strings[i], list.strings[i] + strlen(dir), NULL, false);
                }
@@ -1329,6 +1330,10 @@ const char *FS_FileExtension (const char *in)
 {
        const char *separator, *backslash, *colon, *dot;
 
+       dot = strrchr(in, '.');
+       if (dot == NULL)
+               return "";
+
        separator = strrchr(in, '/');
        backslash = strrchr(in, '\\');
        if (!separator || separator < backslash)
@@ -1337,8 +1342,7 @@ const char *FS_FileExtension (const char *in)
        if (!separator || separator < colon)
                separator = colon;
 
-       dot = strrchr(in, '.');
-       if (dot == NULL || (separator && (dot < separator)))
+       if (separator && (dot < separator))
                return "";
 
        return dot + 1;
@@ -1563,7 +1567,7 @@ qbool FS_ChangeGameDirs(int numgamedirs, char gamedirs[][MAX_QPATH], qbool compl
                }
        }
 
-       Host_SaveConfig();
+       Host_SaveConfig(CONFIGFILENAME);
 
        fs_numgamedirs = numgamedirs;
        for (i = 0;i < fs_numgamedirs;i++)
@@ -1574,15 +1578,15 @@ qbool FS_ChangeGameDirs(int numgamedirs, char gamedirs[][MAX_QPATH], qbool compl
 
        if (cls.demoplayback)
        {
-               CL_Disconnect_f(&cmd_client);
+               CL_Disconnect();
                cls.demonum = 0;
        }
 
        // unload all sounds so they will be reloaded from the new files as needed
-       S_UnloadAllSounds_f(&cmd_client);
+       S_UnloadAllSounds_f(cmd_local);
 
        // restart the video subsystem after the config is executed
-       Cbuf_InsertText(&cmd_client, "\nloadconfig\nvid_restart\n\n");
+       Cbuf_InsertText(cmd_local, "\nloadconfig\nvid_restart\n\n");
 
        return true;
 }
@@ -1823,7 +1827,7 @@ static int FS_ChooseUserDir(userdirmode_t userdirmode, char *userdir, size_t use
                break;
        case USERDIRMODE_MYGAMES:
                if (!shfolder_dll)
-                       Sys_LoadLibrary(shfolderdllnames, &shfolder_dll, shfolderfuncs);
+                       Sys_LoadDependency(shfolderdllnames, &shfolder_dll, shfolderfuncs);
                mydocsdir[0] = 0;
                if (qSHGetFolderPath && qSHGetFolderPath(NULL, CSIDL_PERSONAL, NULL, 0, mydocsdir) == S_OK)
                {
@@ -1849,9 +1853,9 @@ static int FS_ChooseUserDir(userdirmode_t userdirmode, char *userdir, size_t use
                return -1;
        case USERDIRMODE_SAVEDGAMES:
                if (!shell32_dll)
-                       Sys_LoadLibrary(shell32dllnames, &shell32_dll, shell32funcs);
+                       Sys_LoadDependency(shell32dllnames, &shell32_dll, shell32funcs);
                if (!ole32_dll)
-                       Sys_LoadLibrary(ole32dllnames, &ole32_dll, ole32funcs);
+                       Sys_LoadDependency(ole32dllnames, &ole32_dll, ole32funcs);
                if (qSHGetKnownFolderPath && qCoInitializeEx && qCoTaskMemFree && qCoUninitialize)
                {
                        savedgamesdir[0] = 0;
@@ -1967,12 +1971,12 @@ void FS_Init_Commands(void)
        Cvar_RegisterVariable (&fs_empty_files_in_pack_mark_deletions);
        Cvar_RegisterVariable (&cvar_fs_gamedir);
 
-       Cmd_AddCommand(CMD_SHARED, "gamedir", FS_GameDir_f, "changes active gamedir list (can take multiple arguments), not including base directory (example usage: gamedir ctf)");
-       Cmd_AddCommand(CMD_SHARED, "fs_rescan", FS_Rescan_f, "rescans filesystem for new pack archives and any other changes");
-       Cmd_AddCommand(CMD_SHARED, "path", FS_Path_f, "print searchpath (game directories and archives)");
-       Cmd_AddCommand(CMD_SHARED, "dir", FS_Dir_f, "list files in searchpath matching an * filename pattern, one per line");
-       Cmd_AddCommand(CMD_SHARED, "ls", FS_Ls_f, "list files in searchpath matching an * filename pattern, multiple per line");
-       Cmd_AddCommand(CMD_SHARED, "which", FS_Which_f, "accepts a file name as argument and reports where the file is taken from");
+       Cmd_AddCommand(CF_SHARED, "gamedir", FS_GameDir_f, "changes active gamedir list (can take multiple arguments), not including base directory (example usage: gamedir ctf)");
+       Cmd_AddCommand(CF_SHARED, "fs_rescan", FS_Rescan_f, "rescans filesystem for new pack archives and any other changes");
+       Cmd_AddCommand(CF_SHARED, "path", FS_Path_f, "print searchpath (game directories and archives)");
+       Cmd_AddCommand(CF_SHARED, "dir", FS_Dir_f, "list files in searchpath matching an * filename pattern, one per line");
+       Cmd_AddCommand(CF_SHARED, "ls", FS_Ls_f, "list files in searchpath matching an * filename pattern, multiple per line");
+       Cmd_AddCommand(CF_SHARED, "which", FS_Which_f, "accepts a file name as argument and reports where the file is taken from");
 }
 
 static void FS_Init_Dir (void)
@@ -2218,9 +2222,9 @@ void FS_Shutdown (void)
        PK3_CloseLibrary ();
 
 #ifdef WIN32
-       Sys_UnloadLibrary (&shfolder_dll);
-       Sys_UnloadLibrary (&shell32_dll);
-       Sys_UnloadLibrary (&ole32_dll);
+       Sys_FreeLibrary (&shfolder_dll);
+       Sys_FreeLibrary (&shell32_dll);
+       Sys_FreeLibrary (&ole32_dll);
 #endif
 
        if (fs_mutex)
@@ -2507,6 +2511,20 @@ int FS_CheckNastyPath (const char *path, qbool isgamedir)
        return false;
 }
 
+/*
+====================
+FS_SanitizePath
+
+Sanitize path (replace non-portable characters 
+with portable ones in-place, etc)
+====================
+*/
+void FS_SanitizePath(char *path)
+{
+       for (; *path; path++)
+               if (*path == '\\')
+                       *path = '/';
+}
 
 /*
 ====================