Skip to content

Commit

Permalink
Filesystem: allow multiple basegames in fs_basegame cvar separated by…
Browse files Browse the repository at this point in the history
… '/'

Makefile: use additive LDFLAGS
  • Loading branch information
ec- committed Jan 30, 2024
1 parent 914fc40 commit 93cb470
Show file tree
Hide file tree
Showing 6 changed files with 97 additions and 62 deletions.
10 changes: 5 additions & 5 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -418,7 +418,7 @@ ifdef MINGW

BINEXT = .exe

LDFLAGS = -mwindows -Wl,--dynamicbase -Wl,--nxcompat
LDFLAGS += -mwindows -Wl,--dynamicbase -Wl,--nxcompat
LDFLAGS += -Wl,--gc-sections -fvisibility=hidden
LDFLAGS += -lwsock32 -lgdi32 -lwinmm -lole32 -lws2_32 -lpsapi -lcomctl32
LDFLAGS += -flto
Expand Down Expand Up @@ -479,15 +479,15 @@ ifeq ($(COMPILE_PLATFORM),darwin)

ARCHEXT = .$(ARCH)

LDFLAGS =
LDFLAGS +=

ifeq ($(ARCH),x86_64)
BASE_CFLAGS += -arch x86_64
LDFLAGS = -arch x86_64
LDFLAGS += -arch x86_64
endif
ifeq ($(ARCH),aarch64)
BASE_CFLAGS += -arch arm64
LDFLAGS = -arch arm64
LDFLAGS += -arch arm64
endif

ifeq ($(USE_LOCAL_HEADERS),1)
Expand Down Expand Up @@ -554,7 +554,7 @@ else
SHLIBCFLAGS = -fPIC -fvisibility=hidden
SHLIBLDFLAGS = -shared $(LDFLAGS)

LDFLAGS = -lm
LDFLAGS += -lm
LDFLAGS += -Wl,--gc-sections -fvisibility=hidden

ifeq ($(USE_SDL),1)
Expand Down
2 changes: 1 addition & 1 deletion code/client/cl_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -3967,7 +3967,7 @@ void CL_Init( void ) {
Cvar_CheckRange( cl_dlDirectory, "0", "1", CV_INTEGER );
s = va( "Save downloads initiated by \\dlmap and \\download commands in:\n"
" 0 - current game directory\n"
" 1 - fs_basegame (%s) directory\n", FS_GetBaseGameDir() );
" 1 - basegame (%s) directory\n", FS_GetBaseGameDir() );
Cvar_SetDescription( cl_dlDirectory, s );

cl_reconnectArgs = Cvar_Get( "cl_reconnectArgs", "", CVAR_ARCHIVE_ND | CVAR_NOTABCOMPLETE );
Expand Down
4 changes: 2 additions & 2 deletions code/qcommon/common.c
Original file line number Diff line number Diff line change
Expand Up @@ -4074,8 +4074,8 @@ void Com_WriteConfiguration( void ) {
Com_WriteConfigToFile( Q3CONFIG_CFG );

#ifndef DEDICATED
gamedir = Cvar_VariableString( "fs_game" );
basegame = Cvar_VariableString( "fs_basegame" );
gamedir = FS_GetCurrentGameDir();
basegame = FS_GetBaseGameDir();
if ( UI_usesUniqueCDKey() && gamedir[0] && Q_stricmp( basegame, gamedir ) ) {
Com_WriteCDKey( gamedir, &cl_cdkey[16] );
} else {
Expand Down
135 changes: 88 additions & 47 deletions code/qcommon/files.c
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,11 @@ typedef struct searchpath_s {
dirPolicy_t policy;
} searchpath_t;

#define MAX_BASEGAMES 4
static char basegame_str[MAX_OSPATH], *basegames[MAX_BASEGAMES];
static int basegame_cnt;
static const char *basegame = ""; /* last value in array */

static char fs_gamedir[MAX_OSPATH]; // this will be a single file name with no separators
static cvar_t *fs_debug;
static cvar_t *fs_homepath;
Expand Down Expand Up @@ -3642,6 +3647,29 @@ static void FS_GetModDescription( const char *modDir, char *description, int des
}


/*
================
FS_IsBaseGame
================
*/
static qboolean FS_IsBaseGame( const char *game )
{
int i;

if ( game == NULL || *game == '\0' ) {
return qtrue;
}

for ( i = 0; i < basegame_cnt; i++ ) {
if ( Q_stricmp( basegames[i], game ) == 0 ) {
return qtrue;
}
}

return qfalse;
}


/*
================
FS_GetModList
Expand Down Expand Up @@ -3697,10 +3725,11 @@ static int FS_GetModList( char *listbuf, int bufsize ) {
}

// we also drop BASEGAME, "." and ".."
if ( bDrop || Q_stricmp( name, fs_basegame->string ) == 0 ) {
if ( bDrop || strcmp(name, "." ) == 0 || strcmp( name, ".." ) == 0 ) {
continue;
}
if ( strcmp( name, "." ) == 0 || strcmp( name, ".." ) == 0 ) {

if ( FS_IsBaseGame( name ) ) {
continue;
}

Expand Down Expand Up @@ -4639,7 +4668,7 @@ FS_Startup
*/
static void FS_Startup( void ) {
const char *homePath;
int start, end;
int i, start, end;

Com_Printf( "----- FS_Startup -----\n" );

Expand All @@ -4650,21 +4679,34 @@ static void FS_Startup( void ) {
fs_basepath = Cvar_Get( "fs_basepath", Sys_DefaultBasePath(), CVAR_INIT | CVAR_PROTECTED | CVAR_PRIVATE );
Cvar_SetDescription( fs_basepath, "Write-protected CVAR specifying the path to the installation folder of the game." );
fs_basegame = Cvar_Get( "fs_basegame", BASEGAME, CVAR_INIT | CVAR_PROTECTED );
Cvar_SetDescription( fs_basegame, "Write-protected CVAR specifying the path to the base game folder." );
Cvar_SetDescription( fs_basegame, "Write-protected CVAR specifying the path to the base game(s) folder(s), separated by '/'." );
fs_steampath = Cvar_Get( "fs_steampath", Sys_SteamPath(), CVAR_INIT | CVAR_PROTECTED | CVAR_PRIVATE );

/* parse fs_basegame cvar */
Q_strncpyz( basegame_str, fs_basegame->string, sizeof( basegame_str ) );
basegame_cnt = Com_Split( basegame_str, basegames, ARRAY_LEN( basegames ), '/' );
/* set up basegame on last item from the list */
basegame = basegames[0];
for (i = 1; i < basegame_cnt; i++) {
if ( basegames[i] != '\0' ) {
basegame = basegames[i];
}
}

if ( fs_basegame->string[0] == '\0' || *basegame == '\0' || basegame_cnt == 0 )
Com_Error( ERR_FATAL, "* fs_basegame is not set *" );

Com_Printf( S_COLOR_YELLOW "basegame set to '%s'\n", basegame );

#ifndef USE_HANDLE_CACHE
fs_locked = Cvar_Get( "fs_locked", "0", CVAR_INIT );
Cvar_SetDescription( fs_locked, "Set file handle policy for pk3 files:\n"
" 0 - release after use, unlimited number of pk3 files can be loaded\n"
" 1 - keep file handle locked, more consistent, total pk3 files count limited to ~1k-4k\n" );
#endif

if ( !fs_basegame->string[0] )
Com_Error( ERR_FATAL, "* fs_basegame is not set *" );

homePath = Sys_DefaultHomePath();
if ( !homePath || !homePath[0] ) {
if ( homePath == NULL || homePath[0] == '\0' ) {
homePath = fs_basepath->string;
}

Expand All @@ -4675,7 +4717,7 @@ static void FS_Startup( void ) {
Cvar_CheckRange( fs_gamedirvar, NULL, NULL, CV_FSPATH );
Cvar_SetDescription( fs_gamedirvar, "Specify an alternate mod directory and run the game with this mod." );

if ( !Q_stricmp( fs_basegame->string, fs_gamedirvar->string ) ) {
if ( FS_IsBaseGame( fs_gamedirvar->string ) ) {
Cvar_ForceReset( "fs_game" );
}

Expand All @@ -4693,36 +4735,49 @@ static void FS_Startup( void ) {
#endif

// add search path elements in reverse priority order
if ( fs_steampath->string[0] ) {
FS_AddGameDirectory( fs_steampath->string, fs_basegame->string );
if (fs_steampath->string[0]) {
// handle multiple basegames:
for (i = 0; i < basegame_cnt; i++) {
FS_AddGameDirectory( fs_steampath->string, basegames[i] );
}
}

if ( fs_basepath->string[0] ) {
FS_AddGameDirectory( fs_basepath->string, fs_basegame->string );
if (fs_basepath->string[0]) {
// handle multiple basegames:
for (i = 0; i < basegame_cnt; i++) {
FS_AddGameDirectory( fs_basepath->string, basegames[i] );
}
}

#ifdef __APPLE__
fs_apppath = Cvar_Get ("fs_apppath", Sys_DefaultAppPath(), CVAR_INIT|CVAR_PROTECTED );
fs_apppath = Cvar_Get( "fs_apppath", Sys_DefaultAppPath(), CVAR_INIT | CVAR_PROTECTED );
// Make MacOSX also include the base path included with the .app bundle
if (fs_apppath->string[0])
FS_AddGameDirectory(fs_apppath->string, fs_basegame->string);
if ( fs_apppath->string[0] ) {
// handle multiple basegames:
for ( i = 0; i < basegame_cnt; i++ ) {
FS_AddGameDirectory( fs_apppath->string, basegames[i] );
}
}
#endif

// fs_homepath is somewhat particular to *nix systems, only add if relevant
// NOTE: same filtering below for mods and basegame
if ( fs_homepath->string[0] && Q_stricmp( fs_homepath->string, fs_basepath->string ) ) {
FS_AddGameDirectory( fs_homepath->string, fs_basegame->string );
// handle multiple basegames:
for ( i = 0; i < basegame_cnt; i++ ) {
FS_AddGameDirectory( fs_homepath->string, basegames[i] );
}
}

// check for additional game folder for mods
if ( fs_gamedirvar->string[0] && Q_stricmp( fs_gamedirvar->string, fs_basegame->string ) ) {
if ( fs_steampath->string[0] ) {
if ( fs_gamedirvar->string[0] != '\0' && !FS_IsBaseGame( fs_gamedirvar->string ) ) {
if ( fs_steampath->string[0] != '\0' ) {
FS_AddGameDirectory( fs_steampath->string, fs_gamedirvar->string );
}
if ( fs_basepath->string[0] ) {
if ( fs_basepath->string[0] != '\0' ) {
FS_AddGameDirectory( fs_basepath->string, fs_gamedirvar->string );
}
if ( fs_homepath->string[0] && Q_stricmp( fs_homepath->string, fs_basepath->string ) ) {
if ( fs_homepath->string[0] != '\0' && Q_stricmp( fs_homepath->string, fs_basepath->string ) ) {
FS_AddGameDirectory( fs_homepath->string, fs_gamedirvar->string );
}
}
Expand All @@ -4739,9 +4794,8 @@ static void FS_Startup( void ) {

end = Sys_Milliseconds();

Com_ReadCDKey( fs_basegame->string );

if ( fs_gamedirvar->string[0] && Q_stricmp( fs_gamedirvar->string, fs_basegame->string ) ) {
Com_ReadCDKey( basegame );
if ( !FS_IsBaseGame( fs_gamedirvar->string ) ) {
Com_AppendCDKey( fs_gamedirvar->string );
}

Expand All @@ -4765,8 +4819,9 @@ static void FS_Startup( void ) {
fs_gamedirvar->modified = qfalse; // We just loaded, it's not modified

// check original q3a files
if ( !Q_stricmp( fs_basegame->string, BASEGAME ) || !Q_stricmp( fs_basegame->string, BASEDEMO ) )
if ( FS_IsBaseGame( BASEGAME ) || FS_IsBaseGame( BASEDEMO ) ) {
FS_CheckIdPaks();
}

#ifdef FS_MISSING
if (missingFiles == NULL) {
Expand Down Expand Up @@ -5014,7 +5069,7 @@ const char *FS_ReferencedPakChecksums( void ) {
if ( search->pack->exclude ) {
continue;
}
if ( search->pack->referenced || Q_stricmp( search->pack->pakGamename, fs_basegame->string ) ) {
if ( search->pack->referenced || !FS_IsBaseGame( search->pack->pakGamename ) ) {
Q_strcat( info, sizeof( info ), va( "%i ", search->pack->checksum ) );
}
}
Expand Down Expand Up @@ -5141,7 +5196,7 @@ const char *FS_ReferencedPakNames( void ) {
if ( search->pack->exclude ) {
continue;
}
if ( search->pack->referenced || Q_stricmp( search->pack->pakGamename, fs_basegame->string ) ) {
if ( search->pack->referenced || !FS_IsBaseGame( search->pack->pakGamename ) ) {
pakName = va( "%s/%s", search->pack->pakGamename, search->pack->pakBasename );
if ( *info != '\0' ) {
Q_strcat( info, sizeof( info ), " " );
Expand Down Expand Up @@ -5624,22 +5679,22 @@ void FS_VM_CloseFiles( handleOwner_t owner )

const char *FS_GetCurrentGameDir( void )
{
if ( fs_gamedirvar->string[0] )
if ( fs_gamedirvar->string[0] != '\0' )
return fs_gamedirvar->string;

return fs_basegame->string;
return basegame; // last basegame
}


const char *FS_GetBaseGameDir( void )
{
return fs_basegame->string;
return basegame; // last basegame
}


const char *FS_GetBasePath( void )
static const char *FS_GetBasePath( void )
{
if ( fs_basepath && fs_basepath->string[0] )
if ( fs_basepath && fs_basepath->string[0] != '\0' )
return fs_basepath->string;
else
return "";
Expand All @@ -5648,27 +5703,13 @@ const char *FS_GetBasePath( void )

const char *FS_GetHomePath( void )
{
if ( fs_homepath && fs_homepath->string[0] )
if ( fs_homepath && fs_homepath->string[0] != '\0' )
return fs_homepath->string;
else
return FS_GetBasePath();
}


const char *FS_GetGamePath( void )
{
static char buffer[ MAX_OSPATH + MAX_CVAR_VALUE_STRING + 1 ];
if ( fs_gamedirvar && fs_gamedirvar->string[0] ) {
Com_sprintf( buffer, sizeof( buffer ), "%s%c%s", FS_GetHomePath(),
PATH_SEP, fs_gamedirvar->string );
return buffer;
} else {
buffer[0] = '\0';
return buffer;
}
}


fileHandle_t FS_PipeOpenWrite( const char *cmd, const char *filename ) {
fileHandleData_t *fd;
fileHandle_t f;
Expand Down
2 changes: 0 additions & 2 deletions code/qcommon/qcommon.h
Original file line number Diff line number Diff line change
Expand Up @@ -851,9 +851,7 @@ void FS_VM_CloseFiles( handleOwner_t owner );
const char *FS_GetCurrentGameDir( void );
const char *FS_GetBaseGameDir( void );

const char *FS_GetBasePath( void );
const char *FS_GetHomePath( void );
const char *FS_GetGamePath( void );

qboolean FS_StripExt( char *filename, const char *ext );
qboolean FS_AllowedExtension( const char *fileName, qboolean allowPk3s, const char **ext );
Expand Down
6 changes: 1 addition & 5 deletions code/qcommon/vm.c
Original file line number Diff line number Diff line change
Expand Up @@ -1689,15 +1689,11 @@ TTimo: added some verbosity in debug
*/
static void * QDECL VM_LoadDll( const char *name, vmMainFunc_t *entryPoint, dllSyscall_t systemcalls ) {

const char *gamedir = Cvar_VariableString( "fs_game" );
const char *gamedir = FS_GetCurrentGameDir();
char filename[ MAX_QPATH ];
void *libHandle;
dllEntry_t dllEntry;

if ( !*gamedir ) {
gamedir = Cvar_VariableString( "fs_basegame" );
}

Com_sprintf( filename, sizeof( filename ), "%s%c%s" ARCH_STRING DLL_EXT, gamedir, PATH_SEP, name );

libHandle = FS_LoadLibrary( filename );
Expand Down

0 comments on commit 93cb470

Please sign in to comment.