Skip to content
This repository was archived by the owner on Dec 11, 2025. It is now read-only.

Commit 119c4e7

Browse files
committed
Merged pull request "Sync with Q2PRO: More filesystem changes": #360
2 parents b319f34 + 341c26d commit 119c4e7

4 files changed

Lines changed: 102 additions & 45 deletions

File tree

inc/common/cvar.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,13 +41,14 @@ interface from being ambiguous.
4141
#define CVAR_CUSTOM (1 << 9) // created by user
4242
#define CVAR_WEAK (1 << 10) // doesn't have value
4343
#define CVAR_GAME (1 << 11) // created by game library
44+
#define CVAR_NOARCHIVE (1 << 12) // never saved to config
4445
#define CVAR_FILES (1 << 13) // r_reload when changed
4546
#define CVAR_REFRESH (1 << 14) // vid_restart when changed
4647
#define CVAR_SOUND (1 << 15) // snd_restart when changed
4748

4849
#define CVAR_INFOMASK (CVAR_USERINFO | CVAR_SERVERINFO)
4950
#define CVAR_MODIFYMASK (CVAR_INFOMASK | CVAR_FILES | CVAR_REFRESH | CVAR_SOUND)
50-
#define CVAR_NOARCHIVEMASK (CVAR_NOSET | CVAR_CHEAT | CVAR_PRIVATE | CVAR_ROM)
51+
#define CVAR_NOARCHIVEMASK (CVAR_NOSET | CVAR_CHEAT | CVAR_PRIVATE | CVAR_ROM | CVAR_NOARCHIVE)
5152
#define CVAR_EXTENDED_MASK (~31)
5253

5354
extern cvar_t *cvar_vars;

inc/common/files.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@ typedef struct file_info_s {
107107
void FS_Init(void);
108108
void FS_Shutdown(void);
109109
void FS_Restart(bool total);
110+
void FS_AddConfigFiles(bool init);
110111

111112
#if USE_CLIENT
112113
int FS_RenameFile(const char *from, const char *to);

src/common/common.c

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -969,13 +969,7 @@ void Qcommon_Init(int argc, char **argv)
969969
logfile_name->changed = logfile_param_changed;
970970
logfile_enable_changed(logfile_enable);
971971

972-
// execute configs: default.cfg and q2rtx.cfg may come from the packfile, but config.cfg
973-
// and autoexec.cfg must be real files within the game directory
974-
Com_AddConfigFile(COM_DEFAULT_CFG, 0);
975-
Com_AddConfigFile(COM_Q2RTX_CFG, 0);
976-
Com_AddConfigFile(COM_CONFIG_CFG, FS_TYPE_REAL | FS_PATH_GAME);
977-
Com_AddConfigFile(COM_AUTOEXEC_CFG, FS_TYPE_REAL | FS_PATH_GAME);
978-
Com_AddConfigFile(COM_POSTEXEC_CFG, FS_TYPE_REAL);
972+
FS_AddConfigFiles(true);
979973

980974
Com_AddEarlyCommands(true);
981975

src/common/files.c

Lines changed: 98 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,8 @@ static int fs_count_strlwr;
206206
#define FS_COUNT_STRLWR (void)0
207207
#endif
208208

209+
static cvar_t *fs_autoexec;
210+
209211
#if USE_DEBUG
210212
static cvar_t *fs_debug;
211213
#endif
@@ -635,6 +637,8 @@ int FS_CreatePath(char *path)
635637
ofs = p + 1;
636638
}
637639
}
640+
} else if (Q_isalpha(*path) && path[1] == ':') {
641+
ofs = path + 2; // skip drive part
638642
}
639643
#endif
640644

@@ -2149,39 +2153,39 @@ static pack_t *load_pak_file(const char *packfile)
21492153

21502154
if (!fread(&header, sizeof(header), 1, fp)) {
21512155
Com_SetLastError("reading header failed");
2152-
goto fail;
2156+
goto fail1;
21532157
}
21542158

21552159
if (LittleLong(header.ident) != IDPAKHEADER) {
21562160
Com_SetLastError("bad header ident");
2157-
goto fail;
2161+
goto fail1;
21582162
}
21592163

21602164
header.dirlen = LittleLong(header.dirlen);
21612165
if (header.dirlen > INT_MAX || header.dirlen % sizeof(dpackfile_t)) {
21622166
Com_SetLastError("bad directory length");
2163-
goto fail;
2167+
goto fail1;
21642168
}
21652169

21662170
num_files = header.dirlen / sizeof(dpackfile_t);
21672171
if (num_files < 1) {
21682172
Com_SetLastError("no files");
2169-
goto fail;
2173+
goto fail1;
21702174
}
21712175

21722176
header.dirofs = LittleLong(header.dirofs);
21732177
if (header.dirofs > INT_MAX) {
21742178
Com_SetLastError("bad directory offset");
2175-
goto fail;
2179+
goto fail1;
21762180
}
21772181
if (os_fseek(fp, header.dirofs, SEEK_SET)) {
21782182
Com_SetLastError("seeking to directory failed");
2179-
goto fail;
2183+
goto fail1;
21802184
}
2181-
info = FS_Malloc(header.dirlen);
2185+
info = FS_AllocTempMem(header.dirlen);
21822186
if (!fread(info, header.dirlen, 1, fp)) {
21832187
Com_SetLastError("reading directory failed");
2184-
goto fail;
2188+
goto fail2;
21852189
}
21862190

21872191
names_len = 0;
@@ -2190,7 +2194,7 @@ static pack_t *load_pak_file(const char *packfile)
21902194
dfile->filelen = LittleLong(dfile->filelen);
21912195
if (dfile->filelen > INT_MAX || dfile->filepos > INT_MAX - dfile->filelen) {
21922196
Com_SetLastError("file length or position too big");
2193-
goto fail;
2197+
goto fail2;
21942198
}
21952199
names_len += Q_strnlen(dfile->name, sizeof(dfile->name)) + 1;
21962200
}
@@ -2225,11 +2229,12 @@ static pack_t *load_pak_file(const char *packfile)
22252229
FS_DPrintf("%s: %u files, %u hash\n",
22262230
packfile, pack->num_files, pack->hash_size);
22272231

2228-
Z_Free(info);
2229-
2232+
FS_FreeTempMem(info);
22302233
return pack;
22312234

2232-
fail:
2235+
fail2:
2236+
FS_FreeTempMem(info);
2237+
fail1:
22332238
fclose(fp);
22342239
Z_Free(info);
22352240
return NULL;
@@ -3530,6 +3535,11 @@ static void setup_base_paths(void)
35303535
// the GAME bit will be removed once gamedir is set,
35313536
// and will be put back once gamedir is reset to basegame
35323537
add_game_dir(FS_PATH_BASE | FS_PATH_GAME, "%s/"BASEGAME, sys_basedir->string);
3538+
3539+
if (sys_homedir->string[0]) {
3540+
add_game_dir(FS_PATH_BASE | FS_PATH_GAME, "%s/"BASEGAME, sys_homedir->string);
3541+
}
3542+
35333543
fs_base_searchpaths = fs_searchpaths;
35343544
}
35353545

@@ -3544,7 +3554,6 @@ static void setup_game_paths(void)
35443554

35453555
// home paths override system paths
35463556
if (sys_homedir->string[0]) {
3547-
add_game_dir(FS_PATH_BASE, "%s/"BASEGAME, sys_homedir->string);
35483557
add_game_dir(FS_PATH_GAME, "%s/%s", sys_homedir->string, fs_game->string);
35493558
}
35503559

@@ -3555,13 +3564,7 @@ static void setup_game_paths(void)
35553564

35563565
// this var is set for compatibility with server browsers, etc
35573566
Cvar_FullSet("gamedir", fs_game->string, CVAR_ROM | CVAR_SERVERINFO, FROM_CODE);
3558-
35593567
} else {
3560-
if (sys_homedir->string[0]) {
3561-
add_game_dir(FS_PATH_BASE | FS_PATH_GAME,
3562-
"%s/"BASEGAME, sys_homedir->string);
3563-
}
3564-
35653568
// add the game bit to base paths
35663569
for (path = fs_base_searchpaths; path; path = path->next) {
35673570
path->mode |= FS_PATH_GAME;
@@ -3574,6 +3577,18 @@ static void setup_game_paths(void)
35743577
Cvar_FullSet("fs_gamedir", fs_gamedir, CVAR_ROM, FROM_CODE);
35753578
}
35763579

3580+
static void setup_base_gamedir(void)
3581+
{
3582+
if (sys_homedir->string[0]) {
3583+
Q_snprintf(fs_gamedir, sizeof(fs_gamedir), "%s/"BASEGAME, sys_homedir->string);
3584+
} else {
3585+
Q_snprintf(fs_gamedir, sizeof(fs_gamedir), "%s/"BASEGAME, sys_basedir->string);
3586+
}
3587+
#ifdef _WIN32
3588+
FS_ReplaceSeparators(fs_gamedir, '/');
3589+
#endif
3590+
}
3591+
35773592
/*
35783593
================
35793594
FS_Restart
@@ -3592,10 +3607,7 @@ void FS_Restart(bool total)
35923607
} else {
35933608
// just change gamedir
35943609
free_game_paths();
3595-
Q_snprintf(fs_gamedir, sizeof(fs_gamedir), "%s/"BASEGAME, sys_basedir->string);
3596-
#ifdef _WIN32
3597-
FS_ReplaceSeparators(fs_gamedir, '/');
3598-
#endif
3610+
setup_base_gamedir();
35993611
}
36003612

36013613
setup_game_paths();
@@ -3673,6 +3685,34 @@ void FS_Shutdown(void)
36733685
Cmd_Deregister(c_fs);
36743686
}
36753687

3688+
/*
3689+
================
3690+
FS_AddConfigFiles
3691+
================
3692+
*/
3693+
void FS_AddConfigFiles(bool init)
3694+
{
3695+
int flag = init ? FS_PATH_ANY : FS_PATH_GAME;
3696+
3697+
if (!init && !fs_autoexec->integer)
3698+
return;
3699+
3700+
// default.cfg and q2rtx.cfg may come from packfile, but config.cfg and autoexec.cfg
3701+
// must be real files within the game directory.
3702+
Com_AddConfigFile(COM_DEFAULT_CFG, flag);
3703+
Com_AddConfigFile(COM_Q2RTX_CFG, FS_PATH_ANY);
3704+
Com_AddConfigFile(COM_CONFIG_CFG, FS_TYPE_REAL | flag);
3705+
3706+
// autoexec.cfg is executed twice, first from basedir and then from
3707+
// gamedir. This ensures user settings configured in baseq2/autoexec.cfg
3708+
// override those in default.cfg and config.cfg.
3709+
if (*fs_game->string)
3710+
Com_AddConfigFile(COM_AUTOEXEC_CFG, FS_TYPE_REAL | FS_PATH_BASE);
3711+
Com_AddConfigFile(COM_AUTOEXEC_CFG, FS_TYPE_REAL | FS_PATH_GAME);
3712+
3713+
Com_AddConfigFile(COM_POSTEXEC_CFG, FS_TYPE_REAL);
3714+
}
3715+
36763716
// this is called when local server starts up and gets it's latched variables,
36773717
// client receives a serverdata packet, or user changes the game by hand while
36783718
// disconnected
@@ -3683,7 +3723,7 @@ static void fs_game_changed(cvar_t *self)
36833723
// validate it
36843724
if (*s) {
36853725
if (!Q_stricmp(s, BASEGAME)) {
3686-
Cvar_Reset(self);
3726+
Cvar_SetByVar(self, "", FROM_CODE);
36873727
} else if (!COM_IsPath(s)) {
36883728
Com_Printf("'%s' should contain characters [A-Za-z0-9_-] only.\n", self->name);
36893729
Cvar_Reset(self);
@@ -3720,22 +3760,40 @@ static void fs_game_changed(cvar_t *self)
37203760
// otherwise, restart the filesystem
37213761
CL_RestartFilesystem(false);
37223762

3723-
Com_AddConfigFile(COM_DEFAULT_CFG, FS_PATH_GAME);
3724-
Com_AddConfigFile(COM_Q2RTX_CFG, 0);
3725-
Com_AddConfigFile(COM_CONFIG_CFG, FS_TYPE_REAL | FS_PATH_GAME);
3763+
FS_AddConfigFiles(false);
3764+
}
37263765

3727-
// If baseq2/autoexec.cfg exists exec it again after default.cfg and config.cfg.
3728-
// Assumes user prefers to do configuration via autoexec.cfg and hopefully
3729-
// settings and binds will be restored to their preference whenever gamedir changes after startup.
3730-
if(Q_stricmp(s, BASEGAME) && FS_FileExistsEx(COM_AUTOEXEC_CFG, FS_TYPE_REAL | FS_PATH_BASE)) {
3731-
Com_AddConfigFile(COM_AUTOEXEC_CFG, FS_TYPE_REAL | FS_PATH_BASE);
3766+
static void list_dirs(genctx_t *ctx, const char *path)
3767+
{
3768+
listfiles_t list = {
3769+
.flags = FS_SEARCH_DIRSONLY,
3770+
};
3771+
3772+
Sys_ListFiles_r(&list, path, 0);
3773+
3774+
for (int i = 0; i < list.count; i++) {
3775+
char *s = list.files[i];
3776+
3777+
if (COM_IsPath(s))
3778+
Prompt_AddMatch(ctx, s);
3779+
3780+
Z_Free(s);
37323781
}
37333782

3734-
// exec autoexec.cfg (must be a real file within the game directory)
3735-
Com_AddConfigFile(COM_AUTOEXEC_CFG, FS_TYPE_REAL | FS_PATH_GAME);
3783+
Z_Free(list.files);
3784+
}
37363785

3737-
// exec postexec.cfg (must be a real file)
3738-
Com_AddConfigFile(COM_POSTEXEC_CFG, FS_TYPE_REAL);
3786+
static void fs_game_generator(genctx_t *ctx)
3787+
{
3788+
ctx->ignoredups = true;
3789+
#ifdef _WIN32
3790+
ctx->ignorecase = true;
3791+
#endif
3792+
3793+
list_dirs(ctx, sys_basedir->string);
3794+
3795+
if (sys_homedir->string[0])
3796+
list_dirs(ctx, sys_homedir->string);
37393797
}
37403798

37413799
/*
@@ -3752,15 +3810,18 @@ void FS_Init(void)
37523810

37533811
Cmd_Register(c_fs);
37543812

3813+
fs_autoexec = Cvar_Get("fs_autoexec", "1", 0);
3814+
37553815
#if USE_DEBUG
37563816
fs_debug = Cvar_Get("fs_debug", "0", 0);
37573817
#endif
37583818

37593819
fs_shareware = Cvar_Get("fs_shareware", "0", CVAR_ROM);
37603820

37613821
// get the game cvar and start the filesystem
3762-
fs_game = Cvar_Get("game", DEFGAME, CVAR_LATCH | CVAR_SERVERINFO);
3822+
fs_game = Cvar_Get("game", DEFGAME, CVAR_LATCH | CVAR_SERVERINFO | CVAR_NOARCHIVE);
37633823
fs_game->changed = fs_game_changed;
3824+
fs_game->generator = fs_game_generator;
37643825
fs_game_changed(fs_game);
37653826

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

0 commit comments

Comments
 (0)