diff --git a/code/qcommon/files.c b/code/qcommon/files.c index e4d22d37..1c1c593c 100644 --- a/code/qcommon/files.c +++ b/code/qcommon/files.c @@ -251,6 +251,7 @@ static cvar_t *fs_homepath; static cvar_t *fs_apppath; #endif static cvar_t *fs_steampath; +static cvar_t *fs_gogpath; static cvar_t *fs_basepath; static cvar_t *fs_basegame; @@ -750,7 +751,7 @@ long FS_SV_FOpenFileRead(const char *filename, fileHandle_t *fp) fsh[f].handleSync = qfalse; } - // Check fs_steampath too + // Check fs_steampath if (!fsh[f].handleFiles.file.o && fs_steampath->string[0]) { ospath = FS_BuildOSPath( fs_steampath->string, filename, "" ); @@ -765,6 +766,21 @@ long FS_SV_FOpenFileRead(const char *filename, fileHandle_t *fp) fsh[f].handleSync = qfalse; } + // Check fs_gogpath + if (!fsh[f].handleFiles.file.o && fs_gogpath->string[0]) + { + ospath = FS_BuildOSPath( fs_gogpath->string, filename, "" ); + ospath[strlen(ospath)-1] = '\0'; + + if ( fs_debug->integer ) + { + Com_Printf( "FS_SV_FOpenFileRead (fs_gogpath): %s\n", ospath ); + } + + fsh[f].handleFiles.file.o = Sys_FOpen( ospath, "rb" ); + fsh[f].handleSync = qfalse; + } + if ( !fsh[f].handleFiles.file.o ) { f = 0; @@ -2510,6 +2526,8 @@ int FS_GetModList( char *listbuf, int bufsize ) { char **pFiles1 = NULL; char **pFiles2 = NULL; char **pFiles3 = NULL; + char **pFiles4 = NULL; + char **pFiles5 = NULL; qboolean bDrop = qfalse; *listbuf = 0; @@ -2518,10 +2536,12 @@ int FS_GetModList( char *listbuf, int bufsize ) { pFiles0 = Sys_ListFiles( fs_homepath->string, NULL, NULL, &dummy, qtrue ); pFiles1 = Sys_ListFiles( fs_basepath->string, NULL, NULL, &dummy, qtrue ); pFiles2 = Sys_ListFiles( fs_steampath->string, NULL, NULL, &dummy, qtrue ); - // we searched for mods in the three paths + pFiles3 = Sys_ListFiles( fs_gogpath->string, NULL, NULL, &dummy, qtrue ); + // we searched for mods in the four paths // it is likely that we have duplicate names now, which we will cleanup below - pFiles3 = Sys_ConcatenateFileLists( pFiles0, pFiles1 ); - pFiles = Sys_ConcatenateFileLists( pFiles2, pFiles3 ); + pFiles4 = Sys_ConcatenateFileLists( pFiles0, pFiles1 ); + pFiles5 = Sys_ConcatenateFileLists( pFiles2, pFiles3 ); + pFiles = Sys_ConcatenateFileLists( pFiles4, pFiles5 ); nPotential = Sys_CountFileList(pFiles); @@ -2573,6 +2593,15 @@ int FS_GetModList( char *listbuf, int bufsize ) { Sys_FreeFileList( pPaks ); } + /* try on gog path */ + if ( nPaks <= 0 ) + { + path = FS_BuildOSPath( fs_gogpath->string, name, "" ); + nPaks = 0; + pPaks = Sys_ListFiles( path, ".pk3", NULL, &nPaks, qfalse ); + Sys_FreeFileList( pPaks ); + } + if (nPaks > 0) { nLen = strlen(name) + 1; // nLen is the length of the mod path @@ -3301,6 +3330,10 @@ static void FS_Startup( const char *gameName ) fs_gamedirvar = Cvar_Get ("fs_game", "", CVAR_INIT|CVAR_SYSTEMINFO ); // add search path elements in reverse priority order + fs_gogpath = Cvar_Get ("fs_gogpath", Sys_GogPath(), CVAR_INIT|CVAR_PROTECTED ); + if (fs_gogpath->string[0]) { + FS_AddGameDirectory( fs_gogpath->string, gameName ); + } fs_steampath = Cvar_Get ("fs_steampath", Sys_SteamPath(), CVAR_INIT|CVAR_PROTECTED ); if (fs_steampath->string[0]) { FS_AddGameDirectory( fs_steampath->string, gameName ); @@ -3325,6 +3358,9 @@ static void FS_Startup( const char *gameName ) // check for additional base game so mods can be based upon other mods if ( fs_basegame->string[0] && Q_stricmp( fs_basegame->string, gameName ) ) { + if (fs_gogpath->string[0]) { + FS_AddGameDirectory(fs_gogpath->string, fs_basegame->string); + } if (fs_steampath->string[0]) { FS_AddGameDirectory(fs_steampath->string, fs_basegame->string); } @@ -3338,6 +3374,9 @@ static void FS_Startup( const char *gameName ) // check for additional game folder for mods if ( fs_gamedirvar->string[0] && Q_stricmp( fs_gamedirvar->string, gameName ) ) { + if (fs_gogpath->string[0]) { + FS_AddGameDirectory(fs_gogpath->string, fs_gamedirvar->string); + } if (fs_steampath->string[0]) { FS_AddGameDirectory(fs_steampath->string, fs_gamedirvar->string); } diff --git a/code/qcommon/q_shared.h b/code/qcommon/q_shared.h index 791a5abe..9f63f928 100644 --- a/code/qcommon/q_shared.h +++ b/code/qcommon/q_shared.h @@ -50,6 +50,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #define HOMEPATH_NAME_MACOSX HOMEPATH_NAME_WIN #define STEAMPATH_NAME "Quake 3 Arena" #define STEAMPATH_APPID "2200" + #define GOGPATH_ID "1441704920" #define GAMENAME_FOR_MASTER "Quake3Arena" #define CINEMATICS_LOGO "idlogo.RoQ" #define CINEMATICS_INTRO "intro.RoQ" diff --git a/code/qcommon/qcommon.h b/code/qcommon/qcommon.h index feeca186..996c3106 100644 --- a/code/qcommon/qcommon.h +++ b/code/qcommon/qcommon.h @@ -1108,6 +1108,7 @@ char *Sys_Cwd( void ); void Sys_SetDefaultInstallPath(const char *path); char *Sys_DefaultInstallPath(void); char *Sys_SteamPath(void); +char *Sys_GogPath(void); #ifdef __APPLE__ char *Sys_DefaultAppPath(void); diff --git a/code/sys/sys_unix.c b/code/sys/sys_unix.c index 0e9f99bf..b6f33b1f 100644 --- a/code/sys/sys_unix.c +++ b/code/sys/sys_unix.c @@ -47,6 +47,9 @@ static char homePath[ MAX_OSPATH ] = { 0 }; // Used to store the Steam Quake 3 installation path static char steamPath[ MAX_OSPATH ] = { 0 }; +// Used to store the GOG Quake 3 installation path +static char gogPath[ MAX_OSPATH ] = { 0 }; + /* ================== Sys_DefaultHomePath @@ -106,6 +109,17 @@ char *Sys_SteamPath( void ) return steamPath; } +/* +================ +Sys_GogPath +================ +*/ +char *Sys_GogPath( void ) +{ + // GOG also doesn't let you install Quake 3 on Mac/Linux + return gogPath; +} + /* ================ Sys_Milliseconds diff --git a/code/sys/sys_win32.c b/code/sys/sys_win32.c index 6bf0828c..0faec19a 100644 --- a/code/sys/sys_win32.c +++ b/code/sys/sys_win32.c @@ -45,6 +45,9 @@ static char homePath[ MAX_OSPATH ] = { 0 }; // Used to store the Steam Quake 3 installation path static char steamPath[ MAX_OSPATH ] = { 0 }; +// Used to store the GOG Quake 3 installation path +static char gogPath[ MAX_OSPATH ] = { 0 }; + #ifndef DEDICATED static UINT timerResolution = 0; #endif @@ -183,6 +186,38 @@ char *Sys_SteamPath( void ) return steamPath; } +/* +================ +Sys_GogPath +================ +*/ +char *Sys_GogPath( void ) +{ +#ifdef GOGPATH_ID + HKEY gogRegKey; + DWORD pathLen = MAX_OSPATH; + + if (!gogPath[0] && !RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\GOG.com\\Games\\" GOGPATH_ID, 0, KEY_QUERY_VALUE | KEY_WOW64_32KEY, &gogRegKey)) + { + pathLen = MAX_OSPATH; + if (RegQueryValueEx(gogRegKey, "PATH", NULL, NULL, (LPBYTE)gogPath, &pathLen)) + gogPath[0] = '\0'; + + RegCloseKey(gogRegKey); + } + + if (gogPath[0]) + { + if (pathLen == MAX_OSPATH) + pathLen--; + + gogPath[pathLen] = '\0'; + } +#endif + + return gogPath; +} + /* ================ Sys_Milliseconds