From 3148416c04ec532fcd360145381beeb62b47fe7f Mon Sep 17 00:00:00 2001 From: Thilo Schulz Date: Fri, 4 Feb 2011 12:04:56 +0000 Subject: [PATCH] - Change runtime standalone detection: * com_standalone now read-only * add new cvars com_basegame, com_homepath * standalone now automatically detected when com_basegame is set to something different than baseq3 and no id pak pk3s are found * This fixes https://bugzilla.icculus.org/show_bug.cgi?id=4699 - Replace a few hardcoded string literals with macros - Add checks for Team Arena PK3s to FS_CheckPak0() --- README | 30 ++++- code/botlib/be_interface.c | 5 +- code/client/cl_main.c | 2 +- code/q3_ui/ui_menu.c | 4 +- code/qcommon/common.c | 14 ++- code/qcommon/files.c | 219 +++++++++++++++++++++++++++---------- code/qcommon/q_shared.h | 1 + code/qcommon/qcommon.h | 8 +- code/server/sv_ccmds.c | 2 +- code/server/sv_client.c | 6 +- code/sys/sys_unix.c | 16 ++- code/sys/sys_win32.c | 10 +- code/ui/ui_main.c | 2 +- 13 files changed, 236 insertions(+), 83 deletions(-) diff --git a/README b/README index 65b86670..28bc645b 100644 --- a/README +++ b/README @@ -141,7 +141,14 @@ New cvars com_ansiColor - enable use of ANSI escape codes in the tty com_altivec - enable use of altivec on PowerPC systems - com_standalone - Run in standalone mode + com_standalone (read only) - If set to 1, quake3 is running in + standalone mode. + com_basegame - Use a different base than baseq3. If no + original Quake3 or TeamArena pak files + are found, this will enable running in + standalone mode. + com_homepath - Specify name that is to be appended to the + home path com_maxfpsUnfocused - Maximum frames per second when unfocused com_maxfpsMinimized - Maximum frames per second when minimized com_busyWait - Will use a busy loop to wait for rendering @@ -334,11 +341,22 @@ Creating standalone games your own binaries. Instead, you can just use the pre-built binaries on the website. Just make sure the game is called with: - +set com_standalone 1 +set fs_game - - in any links/scripts you install for your users to start the game. Note that - the com_standalone setting is rendered ineffective, if the binary detects pk3 - files in the directory "baseq3", so you cannot use that one as game dir. + +set com_basegame + + in any links/scripts you install for your users to start the game. The + binary must not detect any original quake3 game pak files. If this + condition is met, the game will set com_standalone to 1 and is then running + in stand alone mode. + + If you want the engine to use a different directory in your homepath than + e.g. "Quake3" on Windows or ".q3a" on Linux, then set a new name at startup + by adding + + +set com_homepath + + to the command line. Example line: + + +set com_basegame basefoo +set com_homepath .foo If you really changed parts that would make vanilla ioquake3 incompatible with your mod, we have included another way to conveniently build a stand-alone diff --git a/code/botlib/be_interface.c b/code/botlib/be_interface.c index 3f57df54..4c982082 100644 --- a/code/botlib/be_interface.c +++ b/code/botlib/be_interface.c @@ -144,16 +144,19 @@ int Export_BotLibSetup(void) if(botDeveloper) { - char *homedir, *gamedir; + char *homedir, *gamedir, *basedir; char logfilename[MAX_OSPATH]; homedir = LibVarGetString("homedir"); gamedir = LibVarGetString("gamedir"); + basedir = LibVarGetString("com_basegame"); if (*homedir) { if(*gamedir) Com_sprintf(logfilename, sizeof(logfilename), "%s%c%s%cbotlib.log", homedir, PATH_SEP, gamedir, PATH_SEP); + else if(*basedir) + Com_sprintf(logfilename, sizeof(logfilename), "%s%c%s%cbotlib.log", homedir, PATH_SEP, basedir, PATH_SEP); else Com_sprintf(logfilename, sizeof(logfilename), "%s%c" BASEGAME "%cbotlib.log", homedir, PATH_SEP, PATH_SEP); } diff --git a/code/client/cl_main.c b/code/client/cl_main.c index 112d61de..9f2bc3f4 100644 --- a/code/client/cl_main.c +++ b/code/client/cl_main.c @@ -2106,7 +2106,7 @@ void CL_CheckForResend( void ) { case CA_CONNECTING: // requesting a challenge .. IPv6 users always get in as authorize server supports no ipv6. #ifndef STANDALONE - if (!Cvar_VariableIntegerValue("com_standalone") && clc.serverAddress.type == NA_IP && !Sys_IsLANAddress( clc.serverAddress ) ) + if (!com_standalone->integer && clc.serverAddress.type == NA_IP && !Sys_IsLANAddress( clc.serverAddress ) ) CL_RequestAuthorization(); #endif diff --git a/code/q3_ui/ui_menu.c b/code/q3_ui/ui_menu.c index 73cddd06..54a28023 100644 --- a/code/q3_ui/ui_menu.c +++ b/code/q3_ui/ui_menu.c @@ -121,7 +121,7 @@ void Main_MenuEvent (void* ptr, int event) { break; case ID_TEAMARENA: - trap_Cvar_Set( "fs_game", "missionpack"); + trap_Cvar_Set( "fs_game", BASETA); trap_Cmd_ExecuteText( EXEC_APPEND, "vid_restart;" ); break; @@ -248,7 +248,7 @@ static qboolean UI_TeamArenaExists( void ) { for( i = 0; i < numdirs; i++ ) { dirlen = strlen( dirptr ) + 1; descptr = dirptr + dirlen; - if (Q_stricmp(dirptr, "missionpack") == 0) { + if (Q_stricmp(dirptr, BASETA) == 0) { return qtrue; } dirptr += dirlen + strlen(descptr) + 1; diff --git a/code/qcommon/common.c b/code/qcommon/common.c index ca0570a5..73e82fbf 100644 --- a/code/qcommon/common.c +++ b/code/qcommon/common.c @@ -83,6 +83,8 @@ cvar_t *com_minimized; cvar_t *com_maxfpsMinimized; cvar_t *com_abnormalExit; cvar_t *com_standalone; +cvar_t *com_basegame; +cvar_t *com_homepath; cvar_t *com_busyWait; // com_speeds times @@ -2616,12 +2618,19 @@ void Com_Init( char *commandLine ) { Cmd_Init (); // get the developer cvar set as early as possible - Com_StartupVariable( "developer" ); com_developer = Cvar_Get("developer", "0", CVAR_TEMP); // done early so bind command exists CL_InitKeyCommands(); + com_standalone = Cvar_Get("com_standalone", "0", CVAR_ROM); + com_basegame = Cvar_Get("com_basegame", BASEGAME, CVAR_INIT); + com_homepath = Cvar_Get("com_homepath", "", CVAR_INIT); + + if(!com_basegame->string[0]) + Cvar_ForceReset("com_basegame"); + + // Com_StartupVariable( FS_InitFilesystem (); Com_InitJournaling(); @@ -2690,7 +2699,6 @@ void Com_Init( char *commandLine ) { com_minimized = Cvar_Get( "com_minimized", "0", CVAR_ROM ); com_maxfpsMinimized = Cvar_Get( "com_maxfpsMinimized", "0", CVAR_ARCHIVE ); com_abnormalExit = Cvar_Get( "com_abnormalExit", "0", CVAR_ROM ); - com_standalone = Cvar_Get( "com_standalone", "0", CVAR_INIT ); com_busyWait = Cvar_Get("com_busyWait", "0", CVAR_ARCHIVE); com_introPlayed = Cvar_Get( "com_introplayed", "0", CVAR_ARCHIVE); @@ -2806,7 +2814,7 @@ void Com_WriteConfiguration( void ) { #ifndef DEDICATED fs = Cvar_Get ("fs_game", "", CVAR_INIT|CVAR_SYSTEMINFO ); #ifndef STANDALONE - if(!Cvar_VariableIntegerValue("com_standalone")) + if(!com_standalone->integer) { if (UI_usesUniqueCDKey() && fs && fs->string[0] != 0) { Com_WriteCDKey( fs->string, &cl_cdkey[16] ); diff --git a/code/qcommon/files.c b/code/qcommon/files.c index 1bc6b6f7..5c5e3641 100644 --- a/code/qcommon/files.c +++ b/code/qcommon/files.c @@ -175,7 +175,7 @@ or configs will never get loaded from disk! // every time a new demo pk3 file is built, this checksum must be updated. // the easiest way to get it is to just run the game and see what it spits out #define DEMO_PAK0_CHECKSUM 2985612116u -static const unsigned pak_checksums[] = { +static const unsigned int pak_checksums[] = { 1566731103u, 298122907u, 412165236u, @@ -187,6 +187,14 @@ static const unsigned pak_checksums[] = { 977125798u }; +static const unsigned int missionpak_checksums[] = +{ + 2430342401u, + 511014160u, + 2662638993u, + 1438664554u +}; + // if this is defined, the executable positively won't work with any paks other // than the demo pak, even if productid is present. This is only used for our // last demo release to prevent the mac and linux users from using the demo @@ -2195,7 +2203,7 @@ int FS_GetModList( char *listbuf, int bufsize ) { continue; } // we drop "baseq3" "." and ".." - if (Q_stricmp(name, BASEGAME) && Q_stricmpn(name, ".", 1)) { + if (Q_stricmp(name, com_basegame->string) && Q_stricmpn(name, ".", 1)) { // now we need to find some .pk3 files to validate the mod // NOTE TTimo: (actually I'm not sure why .. what if it's a mod under developement with no .pk3?) // we didn't keep the information when we merged the directory names, as to what OS Path it was found under @@ -2546,7 +2554,8 @@ void FS_AddGameDirectory( const char *path, const char *dir ) { FS_idPak ================ */ -qboolean FS_idPak( char *pak, char *base ) { +qboolean FS_idPak(char *pak, char *base, int numPaks) +{ int i; for (i = 0; i < NUM_ID_PAKS; i++) { @@ -2554,7 +2563,7 @@ qboolean FS_idPak( char *pak, char *base ) { break; } } - if (i < NUM_ID_PAKS) { + if (i < numPaks) { return qtrue; } return qfalse; @@ -2621,8 +2630,8 @@ qboolean FS_ComparePaks( char *neededpaks, int len, qboolean dlstring ) { havepak = qfalse; // never autodownload any of the id paks - if ( FS_idPak(fs_serverReferencedPakNames[i], "baseq3") - || FS_idPak(fs_serverReferencedPakNames[i], "missionpack") ) { + if ( FS_idPak(fs_serverReferencedPakNames[i], BASEGAME, NUM_ID_PAKS) + || FS_idPak(fs_serverReferencedPakNames[i], BASETA, NUM_TA_PAKS) ) { continue; } @@ -2855,7 +2864,7 @@ static void FS_Startup( const char *gameName ) } #ifndef STANDALONE - if(!Cvar_VariableIntegerValue("com_standalone")) + if(!com_standalone->integer) { cvar_t *fs; @@ -2897,16 +2906,20 @@ static void FS_Startup( const char *gameName ) =================== FS_CheckPak0 -Checks that pak0.pk3 is present and its checksum is correct +Check whether any of the original id pak files is present, +and start up in standalone mode, if there are none and a +different com_basegame was set. Note: If you're building a game that doesn't depend on the -Q3 media pak0.pk3, you'll want to remove this function +Q3 media pak0.pk3, you'll want to remove this by defining +STANDALONE in q_shared.h =================== */ static void FS_CheckPak0( void ) { searchpath_t *path; + pack_t *curpack; qboolean founddemo = qfalse; - unsigned foundPak = 0; + unsigned int foundPak = 0, foundTA = 0; for( path = fs_searchpaths; path; path = path->next ) { @@ -2914,13 +2927,119 @@ static void FS_CheckPak0( void ) if(!path->pack) continue; + + curpack = path->pack; - if(!Q_stricmpn( path->pack->pakGamename, "demoq3", MAX_OSPATH ) + if(!Q_stricmpn( curpack->pakGamename, "demoq3", MAX_OSPATH ) && !Q_stricmpn( pakBasename, "pak0", MAX_OSPATH )) { - founddemo = qtrue; + if(curpack->checksum == DEMO_PAK0_CHECKSUM) + founddemo = qtrue; + } - if( path->pack->checksum == DEMO_PAK0_CHECKSUM ) + else if(!Q_stricmpn( curpack->pakGamename, BASEGAME, MAX_OSPATH ) + && strlen(pakBasename) == 4 && !Q_stricmpn( pakBasename, "pak", 3 ) + && pakBasename[3] >= '0' && pakBasename[3] <= '0' + NUM_ID_PAKS - 1) + { + if( curpack->checksum != pak_checksums[pakBasename[3]-'0'] ) + { + if(pakBasename[3] == '0') + { + Com_Printf("\n\n" + "**************************************************\n" + "WARNING: " BASEGAME "/pak0.pk3 is present but its checksum (%u)\n" + "is not correct. Please re-copy pak0.pk3 from your\n" + "legitimate Q3 CDROM.\n" + "**************************************************\n\n\n", + curpack->checksum ); + } + else + { + Com_Printf("\n\n" + "**************************************************\n" + "WARNING: " BASEGAME "/pak%d.pk3 is present but its checksum (%u)\n" + "is not correct. Please re-install the point release\n" + "**************************************************\n\n\n", + pakBasename[3]-'0', curpack->checksum ); + } + } + + foundPak |= 1<<(pakBasename[3]-'0'); + } + else if(!Q_stricmpn(curpack->pakGamename, BASETA, MAX_OSPATH) + && strlen(pakBasename) == 4 && !Q_stricmpn(pakBasename, "pak", 3) + && pakBasename[3] >= '0' && pakBasename[3] <= '0' + NUM_TA_PAKS - 1) + + { + if(curpack->checksum != missionpak_checksums[pakBasename[3]-'0']) + { + Com_Printf("\n\n" + "**************************************************\n" + "WARNING: " BASETA "/pak%d.pk3 is present but its checksum (%u)\n" + "is not correct. Please re-install Team Arena\n" + "**************************************************\n\n\n", + pakBasename[3]-'0', curpack->checksum ); + } + + foundTA |= 1 << (pakBasename[3]-'0'); + } + else + { + int index; + + // Finally check whether this pak's checksum is listed because the user tried + // to trick us by renaming the file, and set foundPak's highest bit to indicate this case. + + for(index = 0; index < ARRAY_LEN(pak_checksums); index++) + { + if(curpack->checksum == pak_checksums[index]) + { + Com_Printf("\n\n" + "**************************************************\n" + "WARNING: %s is renamed pak file %s%cpak%d.pk3\n" + "Running in standalone mode won't work\n" + "Please rename, or remove this file\n" + "**************************************************\n\n\n", + curpack->pakFilename, BASEGAME, PATH_SEP, index); + + + foundPak |= 0x80000000; + } + } + + for(index = 0; index < ARRAY_LEN(missionpak_checksums); index++) + { + if(curpack->checksum == missionpak_checksums[index]) + { + Com_Printf("\n\n" + "**************************************************\n" + "WARNING: %s is renamed pak file %s%cpak%d.pk3\n" + "Running in standalone mode won't work\n" + "Please rename, or remove this file\n" + "**************************************************\n\n\n", + curpack->pakFilename, BASETA, PATH_SEP, index); + + foundTA |= 0x80000000; + } + } + } + } + + if(com_basegame->string[0] && + Q_stricmp(com_basegame->string, BASEGAME) && + !foundPak && !foundTA + ) + { + Cvar_Set("com_standalone", "1"); + } + else + Cvar_Set("com_standalone", "0"); + + if(!com_standalone->integer) + { + if(!(foundPak & 0x01)) + { + if(founddemo) { Com_Printf( "\n\n" "**************************************************\n" @@ -2928,57 +3047,25 @@ static void FS_CheckPak0( void ) "from the demo. This may work fine, but it is not\n" "guaranteed or supported.\n" "**************************************************\n\n\n" ); + + foundPak |= 0x01; } } - - else if(!Q_stricmpn( path->pack->pakGamename, BASEGAME, MAX_OSPATH ) - && strlen(pakBasename) == 4 && !Q_stricmpn( pakBasename, "pak", 3 ) - && pakBasename[3] >= '0' && pakBasename[3] <= '8') - { - if( path->pack->checksum != pak_checksums[pakBasename[3]-'0'] ) - { - if(pakBasename[0] == '0') - { - Com_Printf("\n\n" - "**************************************************\n" - "WARNING: pak0.pk3 is present but its checksum (%u)\n" - "is not correct. Please re-copy pak0.pk3 from your\n" - "legitimate Q3 CDROM.\n" - "**************************************************\n\n\n", - path->pack->checksum ); - } - else - { - Com_Printf("\n\n" - "**************************************************\n" - "WARNING: pak%d.pk3 is present but its checksum (%u)\n" - "is not correct. Please re-install the point release\n" - "**************************************************\n\n\n", - pakBasename[3]-'0', path->pack->checksum ); - } - } - - foundPak |= 1<<(pakBasename[3]-'0'); - } } - if( (!Cvar_VariableIntegerValue("com_standalone") || - !fs_gamedirvar->string[0] || - !Q_stricmp(fs_gamedirvar->string, BASEGAME) || - !Q_stricmp(fs_gamedirvar->string, "missionpack") ) - && - (!founddemo && (foundPak & 0x1ff) != 0x1ff) ) + + if(!com_standalone->integer && (foundPak & 0x1ff) != 0x1ff) { char errorText[MAX_STRING_CHARS] = ""; - if((foundPak&1) != 1 ) + if((foundPak & 0x01) != 0x01) { Q_strcat(errorText, sizeof(errorText), "\"pak0.pk3\" is missing. Please copy it " "from your legitimate Q3 CDROM. "); } - if((foundPak&0x1fe) != 0x1fe ) + if((foundPak & 0x1fe) != 0x1fe) { Q_strcat(errorText, sizeof(errorText), "Point Release files are missing. Please " @@ -2993,8 +3080,26 @@ static void FS_CheckPak0( void ) Com_Error(ERR_FATAL, "%s", errorText); } - if(foundPak & 1) - Cvar_Set("com_standalone", "0"); + if(!com_standalone->integer && foundTA && (foundTA & 0x0f) != 0x0f) + { + char errorText[MAX_STRING_CHARS] = ""; + + if((foundTA & 0x01) != 0x01) + { + Com_sprintf(errorText, sizeof(errorText), + "\"" BASETA "%cpak0.pk3\" is missing. Please copy it " + "from your legitimate Quake 3 Team Arena CDROM. ", PATH_SEP); + } + + if((foundTA & 0x0e) != 0x0e) + { + Q_strcat(errorText, sizeof(errorText), + "Team Arena Point Release files are missing. Please " + "re-install the latest Team Arena point release."); + } + + Com_Error(ERR_FATAL, "%s", errorText); + } } #endif @@ -3123,7 +3228,7 @@ const char *FS_ReferencedPakChecksums( void ) { for ( search = fs_searchpaths ; search ; search = search->next ) { // is the element a pak file? if ( search->pack ) { - if (search->pack->referenced || Q_stricmpn(search->pack->pakGamename, BASEGAME, strlen(BASEGAME))) { + if (search->pack->referenced || Q_stricmpn(search->pack->pakGamename, com_basegame->string, strlen(com_basegame->string))) { Q_strcat( info, sizeof( info ), va("%i ", search->pack->checksum ) ); } } @@ -3198,7 +3303,7 @@ const char *FS_ReferencedPakNames( void ) { for ( search = fs_searchpaths ; search ; search = search->next ) { // is the element a pak file? if ( search->pack ) { - if (search->pack->referenced || Q_stricmpn(search->pack->pakGamename, BASEGAME, strlen(BASEGAME))) { + if (search->pack->referenced || Q_stricmpn(search->pack->pakGamename, com_basegame->string, strlen(com_basegame->string))) { if (*info) { Q_strcat(info, sizeof( info ), " " ); } @@ -3362,7 +3467,7 @@ void FS_InitFilesystem( void ) { Com_StartupVariable( "fs_game" ); // try to start up normally - FS_Startup( BASEGAME ); + FS_Startup(com_basegame->string); #ifndef STANDALONE FS_CheckPak0( ); @@ -3397,7 +3502,7 @@ void FS_Restart( int checksumFeed ) { FS_ClearPakReferences(0); // try to start up normally - FS_Startup( BASEGAME ); + FS_Startup(com_basegame->string); #ifndef STANDALONE FS_CheckPak0( ); diff --git a/code/qcommon/q_shared.h b/code/qcommon/q_shared.h index 1699d08b..2c261389 100644 --- a/code/qcommon/q_shared.h +++ b/code/qcommon/q_shared.h @@ -36,6 +36,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #else #define PRODUCT_NAME "ioq3" #define BASEGAME "baseq3" + #define BASETA "missionpack" #define CLIENT_WINDOW_TITLE "ioquake3" #define CLIENT_WINDOW_MIN_TITLE "ioq3" #define GAMENAME_FOR_MASTER "Quake3Arena" diff --git a/code/qcommon/qcommon.h b/code/qcommon/qcommon.h index f293b265..2ee952c0 100644 --- a/code/qcommon/qcommon.h +++ b/code/qcommon/qcommon.h @@ -573,8 +573,9 @@ issues. #define FS_UI_REF 0x02 #define FS_CGAME_REF 0x04 #define FS_QAGAME_REF 0x08 -// number of id paks that will never be autodownloaded from baseq3 +// number of id paks that will never be autodownloaded from baseq3/missionpack #define NUM_ID_PAKS 9 +#define NUM_TA_PAKS 4 #define MAX_FILE_HANDLES 64 @@ -702,7 +703,7 @@ void FS_PureServerSetLoadedPaks( const char *pakSums, const char *pakNames ); // sole exception of .cfg files. qboolean FS_CheckDirTraversal(const char *checkdir); -qboolean FS_idPak( char *pak, char *base ); +qboolean FS_idPak(char *pak, char *base, int numPaks); qboolean FS_ComparePaks( char *neededpaks, int len, qboolean dlstring ); void FS_Rename( const char *from, const char *to ); @@ -831,6 +832,9 @@ extern cvar_t *com_maxfpsUnfocused; extern cvar_t *com_minimized; extern cvar_t *com_maxfpsMinimized; extern cvar_t *com_altivec; +extern cvar_t *com_standalone; +extern cvar_t *com_basegame; +extern cvar_t *com_homepath; // both client and server must agree to pause extern cvar_t *cl_paused; diff --git a/code/server/sv_ccmds.c b/code/server/sv_ccmds.c index ba2d3b31..4f0b4cb0 100644 --- a/code/server/sv_ccmds.c +++ b/code/server/sv_ccmds.c @@ -1279,7 +1279,7 @@ void SV_AddOperatorCommands( void ) { Cmd_AddCommand ("heartbeat", SV_Heartbeat_f); Cmd_AddCommand ("kick", SV_Kick_f); #ifndef STANDALONE - if(!Cvar_VariableIntegerValue("com_standalone")) + if(!com_standalone->integer) { Cmd_AddCommand ("banUser", SV_Ban_f); Cmd_AddCommand ("banClient", SV_BanNum_f); diff --git a/code/server/sv_client.c b/code/server/sv_client.c index 1db1a3bb..af002de3 100644 --- a/code/server/sv_client.c +++ b/code/server/sv_client.c @@ -97,7 +97,7 @@ void SV_GetChallenge(netadr_t from) #ifndef STANDALONE // Drop the authorize stuff if this client is coming in via v6 as the auth server does not support ipv6. // Drop also for addresses coming in on local LAN and for stand-alone games independent from id's assets. - if(challenge->adr.type == NA_IP && !Cvar_VariableIntegerValue("com_standalone") && !Sys_IsLANAddress(from)) + if(challenge->adr.type == NA_IP && !com_standalone->integer && !Sys_IsLANAddress(from)) { // look up the authorize server's IP if (svs.authorizeAddress.type == NA_BAD) @@ -882,8 +882,8 @@ void SV_WriteDownloadToClient( client_t *cl , msg_t *msg ) // now that we know the file is referenced, // check whether it's legal to download it. - missionPack = FS_idPak(pakbuf, "missionpack"); - idPack = missionPack || FS_idPak(pakbuf, BASEGAME); + missionPack = FS_idPak(pakbuf, BASETA, NUM_TA_PAKS); + idPack = missionPack || FS_idPak(pakbuf, BASEGAME, NUM_ID_PAKS); break; } diff --git a/code/sys/sys_unix.c b/code/sys/sys_unix.c index a71b652a..c1bdcab1 100644 --- a/code/sys/sys_unix.c +++ b/code/sys/sys_unix.c @@ -55,12 +55,20 @@ char *Sys_DefaultHomePath(void) { if( ( p = getenv( "HOME" ) ) != NULL ) { - Q_strncpyz( homePath, p, sizeof( homePath ) ); + Com_sprintf(homePath, sizeof(homePath), "%s%c", p, PATH_SEP); #ifdef MACOS_X - Q_strcat( homePath, sizeof( homePath ), - "/Library/Application Support/Quake3" ); + Q_strcat(homePath, sizeof(homePath), + "Library/Application Support/"); + + if(com_homepath->string[0]) + Q_strcat(homePath, sizeof(homePath), com_homepath->string); + else + Q_strcat(homePath, sizeof(homePath), "Quake3"); #else - Q_strcat( homePath, sizeof( homePath ), "/.q3a" ); + if(com_homepath->string[0]) + Q_strcat(homePath, sizeof(homePath), com_homepath->string); + else + Q_strcat(homePath, sizeof(homePath), ".q3a"); #endif } } diff --git a/code/sys/sys_win32.c b/code/sys/sys_win32.c index 8ae6b7d4..7a19d6dc 100644 --- a/code/sys/sys_win32.c +++ b/code/sys/sys_win32.c @@ -88,8 +88,14 @@ char *Sys_DefaultHomePath( void ) FreeLibrary(shfolder); return NULL; } - Q_strncpyz( homePath, szPath, sizeof( homePath ) ); - Q_strcat( homePath, sizeof( homePath ), "\\Quake3" ); + + Com_Sprintf(homePath, sizeof(homePath), "%s%c", szPath, PATH_SEP); + + if(com_homepath->string[0]) + Q_strcat(homePath, sizeof(homePath), com_homepath->string); + else + Q_strcat(homePath, sizeof(homePath), "Quake3"); + FreeLibrary(shfolder); } diff --git a/code/ui/ui_main.c b/code/ui/ui_main.c index b8b6db4e..1972a932 100644 --- a/code/ui/ui_main.c +++ b/code/ui/ui_main.c @@ -65,7 +65,7 @@ static const int numNetSources = sizeof(netSources) / sizeof(const char*); static const serverFilter_t serverFilters[] = { {"All", "" }, {"Quake 3 Arena", "" }, - {"Team Arena", "missionpack" }, + {"Team Arena", BASETA }, {"Rocket Arena", "arena" }, {"Alliance", "alliance20" }, {"Weapons Factory Arena", "wfa" },