[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