[quake3-commits] r2295 - in trunk: . code/qcommon
DONOTREPLY at icculus.org
DONOTREPLY at icculus.org
Sun Jul 1 14:00:18 EDT 2012
Author: thilo
Date: 2012-07-01 14:00:18 -0400 (Sun, 01 Jul 2012)
New Revision: 2295
Modified:
trunk/README
trunk/code/qcommon/files.c
Log:
Support for .pk3dir (#5298) - Patch by Andrew (dersaidin at gmail.com)
Modified: trunk/README
===================================================================
--- trunk/README 2012-07-01 17:27:52 UTC (rev 2294)
+++ trunk/README 2012-07-01 18:00:18 UTC (rev 2295)
@@ -493,6 +493,12 @@
---------------------------------------------------- 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
Modified: trunk/code/qcommon/files.c
===================================================================
--- trunk/code/qcommon/files.c 2012-07-01 17:27:52 UTC (rev 2294)
+++ trunk/code/qcommon/files.c 2012-07-01 18:00:18 UTC (rev 2295)
@@ -2822,13 +2822,21 @@
*/
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 ) {
if ( sp->dir && !Q_stricmp(sp->dir->path, path) && !Q_stricmp(sp->dir->gamedir, dir)) {
@@ -2842,25 +2850,84 @@
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
More information about the quake3-commits
mailing list