5289 - Support for .pk3dir

This commit is contained in:
Andrew Browne 2013-02-11 17:58:24 -06:00 committed by Zack Middleton
parent c9137d9d14
commit 37a9614179
2 changed files with 87 additions and 13 deletions

6
README
View File

@ -496,6 +496,12 @@ QuakeLive mouse acceleration (patch and this text written by TTimo from id)
---------------------------------------------------- README for Developers ----- ---------------------------------------------------- README for Developers -----
pk3dir
Ioquake3 has a useful new feature for mappers. Paths in a game directory with
the extension ".pk3dir" are treated like pak files. This means you can keep
all files specific to your map in one directory tree and easily zip this
folder for distribution.
64bit mods 64bit mods
If you wish to compile external mods as shared libraries on a 64bit platform, If you wish to compile external mods as shared libraries on a 64bit platform,
and the mod source is derived from the id Q3 SDK, you will need to modify the and the mod source is derived from the id Q3 SDK, you will need to modify the

View File

@ -2829,12 +2829,20 @@ then loads the zip headers
*/ */
void FS_AddGameDirectory( const char *path, const char *dir ) { void FS_AddGameDirectory( const char *path, const char *dir ) {
searchpath_t *sp; searchpath_t *sp;
int i;
searchpath_t *search; searchpath_t *search;
pack_t *pak; pack_t *pak;
char curpath[MAX_OSPATH + 1], *pakfile; char curpath[MAX_OSPATH + 1], *pakfile;
int numfiles; int numfiles;
char **pakfiles; char **pakfiles;
int pakfilesi;
char **pakfilestmp;
int numdirs;
char **pakdirs;
int pakdirsi;
char **pakdirstmp;
int pakwhich;
int len;
// Unique // Unique
for ( sp = fs_searchpaths ; sp ; sp = sp->next ) { for ( sp = fs_searchpaths ; sp ; sp = sp->next ) {
@ -2849,14 +2857,45 @@ void FS_AddGameDirectory( const char *path, const char *dir ) {
Q_strncpyz(curpath, FS_BuildOSPath(path, dir, ""), sizeof(curpath)); Q_strncpyz(curpath, FS_BuildOSPath(path, dir, ""), sizeof(curpath));
curpath[strlen(curpath) - 1] = '\0'; // strip the trailing slash curpath[strlen(curpath) - 1] = '\0'; // strip the trailing slash
// Get .pk3 files
pakfiles = Sys_ListFiles(curpath, ".pk3", NULL, &numfiles, qfalse); pakfiles = Sys_ListFiles(curpath, ".pk3", NULL, &numfiles, qfalse);
qsort( pakfiles, numfiles, sizeof(char*), paksort ); // Get top level directories (we'll filter them later since the Sys_ListFiles filtering is terrible)
pakdirs = Sys_ListFiles(curpath, "/", NULL, &numdirs, qfalse);
for ( i = 0 ; i < numfiles ; i++ ) { qsort( pakfiles, numfiles, sizeof(char*), paksort );
pakfile = FS_BuildOSPath( path, dir, pakfiles[i] ); qsort( pakdirs, numdirs, sizeof(char *), paksort );
if ( ( pak = FS_LoadZipFile( pakfile, pakfiles[i] ) ) == 0 )
pakfilesi = 0;
pakdirsi = 0;
while((pakfilesi < numfiles) || (pakdirsi < numdirs))
{
// Check if a pakfile or pakdir comes next
if (pakfilesi >= numfiles) {
// We've used all the pakfiles, it must be a pakdir.
pakwhich = 0;
}
else if (pakdirsi >= numdirs) {
// We've used all the pakdirs, it must be a pakfile.
pakwhich = 1;
}
else {
// Could be either, compare to see which name comes first
// Need tmp variables for appropriate indirection for paksort()
pakfilestmp = &pakfiles[pakfilesi];
pakdirstmp = &pakdirs[pakdirsi];
pakwhich = (paksort(pakfilestmp, pakdirstmp) < 0);
}
if (pakwhich) {
// The next .pk3 file is before the next .pk3dir
pakfile = FS_BuildOSPath(path, dir, pakfiles[pakfilesi]);
if ((pak = FS_LoadZipFile(pakfile, pakfiles[pakfilesi])) == 0) {
// This isn't a .pk3! Next!
pakfilesi++;
continue; continue;
}
Q_strncpyz(pak->pakPathname, curpath, sizeof(pak->pakPathname)); Q_strncpyz(pak->pakPathname, curpath, sizeof(pak->pakPathname));
// store the game name for downloading // store the game name for downloading
@ -2868,10 +2907,39 @@ void FS_AddGameDirectory( const char *path, const char *dir ) {
search->pack = pak; search->pack = pak;
search->next = fs_searchpaths; search->next = fs_searchpaths;
fs_searchpaths = search; fs_searchpaths = search;
pakfilesi++;
}
else {
// The next .pk3dir is before the next .pk3 file
// But wait, this could be any directory, we're filtering to only ending with ".pk3dir" here.
len = strlen(pakdirs[pakdirsi]);
if (!FS_IsExt(pakdirs[pakdirsi], ".pk3dir", len)) {
// This isn't a .pk3dir! Next!
pakdirsi++;
continue;
}
pakfile = FS_BuildOSPath(path, dir, pakdirs[pakdirsi]);
// add the directory to the search path
search = Z_Malloc(sizeof(searchpath_t));
search->dir = Z_Malloc(sizeof(*search->dir));
Q_strncpyz(search->dir->path, curpath, sizeof(search->dir->path)); // c:\xreal\base
Q_strncpyz(search->dir->fullpath, pakfile, sizeof(search->dir->fullpath)); // c:\xreal\base\mypak.pk3dir
Q_strncpyz(search->dir->gamedir, pakdirs[pakdirsi], sizeof(search->dir->gamedir)); // mypak.pk3dir
search->next = fs_searchpaths;
fs_searchpaths = search;
pakdirsi++;
}
} }
// done // done
Sys_FreeFileList( pakfiles ); Sys_FreeFileList( pakfiles );
Sys_FreeFileList( pakdirs );
// //
// add the directory to the search path // add the directory to the search path