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.
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.
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.
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.
And replaced with this ...
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).
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.
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>
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; }
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 }
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;
}
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;
}
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 }
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)); }
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.