Announcement

Collapse
No announcement yet.

Engine Code: Adding Any.Pak Support

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Engine Code: Adding Any.Pak Support

    Summary

    This uses JoeQuake 0.14 as an example to add the ability to add any the ability to read any *.pak in the JoeQuake folder ONLY. This should easily apply to Qrack since Qrack was based on JoeQuake 0.14 or most engines with gamedir switching capability.

    Some of this is based on something similar by "MrG" (MrGLQuake).

    Instructions

    The changes here almost exclusively take place in common.c.

    First, we need to add io.h to the header to use some findfile functions.

    #include <io.h>
    Second, I've consolidated all the pak loading into a single point because the code repeats several times. I added this above COM_AddGameDirectory. For clarity, it indicates that it must be passed the full path of the pak file.

    Code:
    qboolean COM_AddPak (char *pakfilefullpath) {
    	searchpath_t *search;
    	pack_t *pak;
    
    	pak = COM_LoadPackFile(pakfilefullpath);
    	if (!pak)
    		return false; //do not pass go, do not collect $500
    	
    	search = Q_malloc (sizeof(searchpath_t));
    	search->pack = pak;
    	search->next = com_searchpaths;
    	com_searchpaths = search;
    	return true;
    }
    Second, the entire COM_AddGameDirectory was rewritten.

    First, I feel that it should only be passed the short version of the "gamedir" path, not the full file path. The full file path should always be com_basedir anyway.

    Second, I don't have it use any.pak capability outside the JoeQuake folder. One reason is because any.pak capability is non-standard, but the main reason is that only 2 good reasons to add any.pak capability exist and the main one is to package replacement graphics into nice little tidy packages.

    And third, I have the base "pak0.pak" in the JoeQuake simply called JoeQuake.pak. It has lowest priority so it needs to be first in the search path and I assume that any engine is going to have a default custom graphics pak so we'll call that JoeQuake_Extras.pak and have it have 2nd lowest priority.

    Code:
    void COM_AddGameDirectory (char *shortdir) // Baker: dir WAS a fullpath, but now I changed to expect relative path from basedir
    {
    // Ok, I'm pretty sure this was getting the LONG dir!
    // And gamedir command was NOT using it either
    // But gamedir(short) was getting set
    // So other than that single reference
    // The rest requires LONG name (except where we added new stuff!)
    	int		i;
    	searchpath_t	*search;
    	//pack_t		*pak;
    	char		pakfile[MAX_OSPATH]; //, *p;
    
    //	if ((p = strrchr(dir, '/')) { 
    //		Q_strncpyz (com_gamedirname, ++p, sizeof(com_gamedirname));
    //	}else{
    //		Q_strncpyz (com_gamedirname, p, sizeof(com_gamedirname));
    //	}
    	
    	COM_SetPath_GameDirFull(shortdir); // Set the gamedir with Mr. Shorty Gamedir
    
    // add the directory to the search path
    	search = Q_malloc (sizeof(searchpath_t));
    	Q_strncpyz (search->filename, com_gamedirfull, sizeof(search->filename));
    	search->pack = NULL;
    	search->next = com_searchpaths;
    	com_searchpaths = search;
    
    	// Baker: if joequake folder, load any paks
    	//        else use standard scheme
    	if (Q_strcasecmp(com_gamedirshort, "joequake")!=0) {
    		// Not joequake folder, use traditional method
    
    		// add any pak files in the format pak0.pak pak1.pak, ...
    		for (i=0 ; ; i++) {
    			Q_snprintfz (pakfile, sizeof(pakfile), "%s/pak%i.pak", com_gamedirfull, i);
    			
    			//MessageBox(NULL, va("Pak files for %s is %s\n", com_gamedirfull, pakfile), "gamedir add", MB_OK);
    			if(!COM_AddPak(pakfile)) // If no match, terminate pakx.pak search sequence
    				break;
    		}
    
    	} else {		
    		// joequake folder; load any paks found
    		// Adapted from "add ANY pak file -   MrG ([email protected])
    		char	dirstring[1024];
    		int		handle;
    		struct	_finddata_t fileinfo;
    
        	// Load joequake.pak first
    		Q_snprintfz (pakfile, sizeof(pakfile), "%s/joequake.pak", com_gamedirfull);
    		//MessageBox(NULL, pakfile, "joequake", MB_OK);
    		if(!COM_AddPak(pakfile)) {
    			Sys_Error ("joequake.pak file is missing"); // Required file: throw a fit
    		}	
    		// End joequake.pak
    
    	   	// Load joequake_extras.pak next
    		
    		Q_snprintfz (pakfile, sizeof(pakfile), "%s/joequake_extras.pak", com_gamedirfull);
    		//MessageBox(NULL, pakfile, "joequake", MB_OK);
    		if(!COM_AddPak(pakfile)) {
    			// Load failed, but this isn't a required file so .. nothing
    		}	
    		// End joequake_extras.pak
    
    
    		Q_snprintfz (dirstring, sizeof(dirstring), "%s/*.pak", com_gamedirfull);
    		handle = _findfirst (dirstring, &fileinfo);
    
          	if (handle != -1) {
    			do {
    				if (fileinfo.name[0] == '.')
    					continue;
    
    				if (Q_strcasecmp(fileinfo.name, "joequake.pak")==0) {
    					continue;
    				}
    
    				if (Q_strcasecmp(fileinfo.name, "joequake_extras.pak")==0) {
    					continue;
    				}
    
    
      				Q_snprintfz(pakfile, sizeof(pakfile), "%s/%s", com_gamedirfull, fileinfo.name);
    
    				if (!COM_AddPak(pakfile))
    					break;
    
    				Con_Printf("adding joequake %s pak file\n", fileinfo.name);
            	} while (_findnext( handle, &fileinfo ) != -1);
    			_findclose (handle);
    		}
    		// End joequake folder
      	}
    
    	// initializing demodir (probably only the default demodir and this changes dynamically, for demo menu only)
    	Q_snprintfz (demodir, sizeof(demodir), "/%s/demos", com_gamedirshort); // Baker: Not sure this is "right" since we want demos in joequake/demos
    }
    If using something similar to the above it is important to ensure that all references to COM_AddDirectory send only the short gamedir like "quoth" instead of "c:/quake/quoth".

    com_gamedir has been renamed to com_gamedirfull, since that was the full path and com_gamedirname has been renamed to com_gamedirshort.

    Next ...

    I modified COM_SetGameDir to have COM_AddGameDirectory do the gamedir processing instead of it occurring in COM_SetGameDir, to make gamedir changing all go straight through a single point.

    Code in COM_SetGameDir to be removed ...

    Q_snprintfz (com_gamedir, sizeof(com_gamedir), "%s/%s", com_basedir, dir); Baker: No! No! No! Only COM_AddGameDirectory should be doing this!

    if (!strcmp(dir, "id1") || !strcmp(dir, "joequake"))
    return;
    <-- Baker: this is a good start, but more must be done

    // add the directory to the search path
    search = Q_malloc (sizeof(searchpath_t));
    Q_strncpyz (search->filename, com_gamedir, sizeof(search->filename));
    search->pack = NULL;
    search->next = com_searchpaths;
    com_searchpaths = search;

    // add any pak files in the format pak0.pak pak1.pak, ...
    for (i=0 ; ; i++)
    {
    Q_snprintfz (pakfile, sizeof(pakfile), "%s/pak%i.pak", com_gamedir, i);
    if (!(pak = COM_LoadPackFile(pakfile)))
    break;
    search = Q_malloc (sizeof(searchpath_t));
    search->pack = pak;
    search->next = com_searchpaths;
    com_searchpaths = search;
    }
    And replaced with this ...

    Code:
    	if (Q_strcasecmp(shortdir, "id1")==0 || Q_strcasecmp(shortdir, "joequake")==0) {
    		COM_SetPath_GameDirFull("joequake"); // Set the gamedir with Mr. Shorty Gamedir
    		Con_Printf("Gamedir reset to base: %s\n", com_gamedirshort);
    	} else {
    		// Gamedir isn't id1 or joequake, so add the gamedirectory
    		COM_AddGameDirectory(/*com_basedir,*/ shortdir); // was a return with the gamedir add logic afterwards
    	}
    Note that I made sure COM_SetGameDir only gets passed the short gamedir path ("quoth" or whatever) instead of the full gamedir path ("c:/quake/quoth" or whatever).

    The above is important because JoeQuake should NOT allow someone to set "id1" as the gamedir!!! Then configs and such save to the wrong place!

    Finally, I added a single point where the actual gamedir is set to have a centralized place to optionally set any other desired paths that change at gamedir switch time. (One example is altering the save game path to use id1 if joequake is the gamedir, I don't see any reason that JoeQuake games should save in the JoeQuake folder instead of id1).

    Code:
    void COM_SetPath_GameDirFull(char *shortdir) {
    	// This is where the gamedirname gets set!
    	Q_strncpyz (com_gamedirfull, va("%s/%s", com_basedir, shortdir), sizeof(com_gamedirfull));
    	Q_strncpyz (com_gamedirshort, shortdir, sizeof(com_gamedirshort));
    
    }
    Results

    In the above example, pak files can have any file name in the JoeQuake folder and joequake.pak and joequake_extras.pak will have the lowest priority, allowing pak files to be tossed in there with friendly names like yellowno5_texturepack.pak or qrp_weapon_models.pak and so forth.

    But outside the JoeQuake folder, the regular naming convention applies so someone with a 5 year old Quake folder isn't shocked to find some miscellaneous pak file being loaded that wasn't expected.
    Quakeone.com - Being exactly one-half good and one-half evil has advantages. When a portal opens to the antimatter universe, my opposite is just me with a goatee.

    So while you guys all have to fight your anti-matter counterparts, me and my evil twin will be drinking a beer laughing at you guys ...
Working...
X