Support for .pk3dir (#5298) - Patch by Andrew (dersaidin@gmail.com)

This commit is contained in:
Thilo Schulz 2012-07-01 18:00:18 +00:00
parent 56f16e10d6
commit b757968839
2 changed files with 87 additions and 14 deletions

6
README
View file

@ -493,6 +493,12 @@ QuakeLive mouse acceleration (patch and this text written by TTimo from id)
---------------------------------------------------- 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
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

View file

@ -2822,12 +2822,20 @@ then loads the zip headers
*/
void FS_AddGameDirectory( const char *path, const char *dir ) {
searchpath_t *sp;
int i;
searchpath_t *search;
pack_t *pak;
char curpath[MAX_OSPATH + 1], *pakfile;
int numfiles;
char **pakfiles;
int pakfilesi;
char **pakfilestmp;
int numdirs;
char **pakdirs;
int pakdirsi;
char **pakdirstmp;
int pakwhich;
int len;
// Unique
for ( sp = fs_searchpaths ; sp ; sp = sp->next ) {
@ -2842,25 +2850,84 @@ void FS_AddGameDirectory( const char *path, const char *dir ) {
Q_strncpyz(curpath, FS_BuildOSPath(path, dir, ""), sizeof(curpath));
curpath[strlen(curpath) - 1] = '\0'; // strip the trailing slash
// Get .pk3 files
pakfiles = Sys_ListFiles(curpath, ".pk3", NULL, &numfiles, qfalse);
// Get top level directories (we'll filter them later since the Sys_ListFiles filtering is terrible)
pakdirs = Sys_ListFiles(curpath, "/", NULL, &numdirs, qfalse);
qsort( pakfiles, numfiles, sizeof(char*), paksort );
qsort(pakdirs, numdirs, sizeof(char *), paksort);
for ( i = 0 ; i < numfiles ; i++ ) {
pakfile = FS_BuildOSPath( path, dir, pakfiles[i] );
if ( ( pak = FS_LoadZipFile( pakfile, pakfiles[i] ) ) == 0 )
continue;
pakfilesi = 0;
pakdirsi = 0;
Q_strncpyz(pak->pakPathname, curpath, sizeof(pak->pakPathname));
// store the game name for downloading
Q_strncpyz(pak->pakGamename, dir, sizeof(pak->pakGamename));
fs_packFiles += pak->numfiles;
// Log may not be initialized at this point, but it will still show in the console.
search = Z_Malloc (sizeof(searchpath_t));
search->pack = pak;
search->next = fs_searchpaths;
fs_searchpaths = search;
while((pakfilesi + pakdirsi) < (numfiles + 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) {
continue;
}
Q_strncpyz(pak->pakPathname, curpath, sizeof(pak->pakPathname));
// store the game name for downloading
Q_strncpyz(pak->pakGamename, dir, sizeof(pak->pakGamename));
fs_packFiles += pak->numfiles;
search = Z_Malloc(sizeof(searchpath_t));
search->pack = pak;
search->next = fs_searchpaths;
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