From fcdd241f968caedf68a2a8f1180665e31535b5b8 Mon Sep 17 00:00:00 2001 From: Knightmare66 Date: Mon, 27 Sep 2021 21:37:44 -0400 Subject: [PATCH] Added re-initialization of UI data (via UI_RefreshData() in ui_main.c) when changing gamedirs. Added CL_ChangeGameRefresh() in cl_main.c. Refactored execution of default.cfg and kmq2config.cfg via FS_ExecConfigs() in filesystem.c. Fixed crash due to uncleared pointers when reinitializing mapshotvalid state arrays. --- client/cl_keys.c | 8 +- client/cl_main.c | 16 ++++ client/cl_tempent.c | 6 +- qcommon/common.c | 19 +--- qcommon/cvar.c | 8 ++ qcommon/filesystem.c | 56 +++++++++--- qcommon/qcommon.h | 2 + server/sv_ccmds.c | 13 +-- ui/ui_local.h | 10 ++- ui/ui_main.c | 37 ++++++++ ui/ui_utils.c | 203 ++++++++++++++++++++++++++++++++++++++++++- 11 files changed, 338 insertions(+), 40 deletions(-) diff --git a/client/cl_keys.c b/client/cl_keys.c index 7fda104..2d031bb 100644 --- a/client/cl_keys.c +++ b/client/cl_keys.c @@ -902,10 +902,10 @@ void Key_Init (void) // // register our functions // - Cmd_AddCommand ("bind",Key_Bind_f); - Cmd_AddCommand ("unbind",Key_Unbind_f); - Cmd_AddCommand ("unbindall",Key_Unbindall_f); - Cmd_AddCommand ("bindlist",Key_Bindlist_f); + Cmd_AddCommand ("bind", Key_Bind_f); + Cmd_AddCommand ("unbind", Key_Unbind_f); + Cmd_AddCommand ("unbindall", Key_Unbindall_f); + Cmd_AddCommand ("bindlist", Key_Bindlist_f); } /* diff --git a/client/cl_main.c b/client/cl_main.c index 3e92bd2..0d862f2 100644 --- a/client/cl_main.c +++ b/client/cl_main.c @@ -3062,3 +3062,19 @@ void CL_Shutdown (void) UI_Shutdown (); // added UI shutdown Con_Shutdown (); // added Con shutdown } + + +/* +==================== +CL_ChangeGameRefresh + +Called during a gamedir change +==================== +*/ +void CL_ChangeGameRefresh (void) +{ + if (dedicated->integer) + return; // nothing running on the client + + UI_RefreshData (); // refresh UI data +} diff --git a/client/cl_tempent.c b/client/cl_tempent.c index e6b40ff..d8bda7d 100644 --- a/client/cl_tempent.c +++ b/client/cl_tempent.c @@ -328,7 +328,7 @@ void CL_Explosion_Flash (vec3_t origin, int dist, int size, qboolean plasma) if (cl_particle_scale->value > 1 || plasma) { for (i=0; ivalue) if (!dedicated->integer) Cbuf_AddText ("d1\n"); else diff --git a/qcommon/cvar.c b/qcommon/cvar.c index e567de9..ec35e31 100644 --- a/qcommon/cvar.c +++ b/qcommon/cvar.c @@ -335,6 +335,10 @@ cvar_t *Cvar_Set2 (char *var_name, char *value, qboolean force) if (!strcmp(var->name, "game")) { FS_SetGamedir (var->string); + // Knightmare added + CL_ChangeGameRefresh (); // refresh client data + FS_ExecConfigs (true); // exec configs + // end Knightmare FS_ExecAutoexec (); } } @@ -593,6 +597,10 @@ void Cvar_GetLatchedVars (void) if (!strcmp(var->name, "game")) { FS_SetGamedir (var->string); + // Knightmare added + CL_ChangeGameRefresh (); // refresh client data + FS_ExecConfigs (true); // exec configs + // end Knightmare FS_ExecAutoexec (); } } diff --git a/qcommon/filesystem.c b/qcommon/filesystem.c index 07fa5f1..b636a9a 100644 --- a/qcommon/filesystem.c +++ b/qcommon/filesystem.c @@ -2492,10 +2492,12 @@ void FS_CopyConfigsToSavegameDir (void) continue; } ++cfgName; // move to after the '/' - // don't copy default.cfg or configs written by other engines + // Don't copy default.cfg, autoexec.cfg, or configs written by other engines // TODO: keep this up to date! // config.cfg, aprconfig.cfg, bqconfig.cfg, eglcfg.cfg, maxconfig.cfg, q2config.cfg, q2b_config.cfg, q2econfig.cfg, xpconfig.cfg, yq2.cfg - if ( (strstr(cfgName, "config.cfg") && stricmp(cfgName, "kmq2config.cfg")) || !stricmp(cfgName, "default.cfg") || !stricmp(cfgName, "eglcfg.cfg") || !stricmp(cfgName, "yq2.cfg") ) { + if ( (strstr(cfgName, "config.cfg") && (stricmp(cfgName, "kmq2config.cfg") != 0)) || + !stricmp(cfgName, "default.cfg") || !stricmp(cfgName, "autoexec.cfg") || + !stricmp(cfgName, "eglcfg.cfg") || !stricmp(cfgName, "yq2.cfg") ) { continue; } Com_sprintf (dstCfgPath, sizeof(dstCfgPath), "%s/%s", FS_SaveGameDir(), cfgName); @@ -2742,7 +2744,6 @@ void FS_SetGamedir (const char *dir) // // flush all data, so it will be forced to reload // -// if (dedicated && !dedicated->value) if (dedicated && !dedicated->integer) Cbuf_AddText ("vid_restart\nsnd_restart\n"); @@ -2863,6 +2864,38 @@ void FS_Link_f (void) } +/* +================= +FS_ExecConfigs + +Executes default.cfg and kmq2config.cfg +Encapsulated to avoid redundancy +================= +*/ +void FS_ExecConfigs (qboolean unbind) +{ +// char *cfgfile; + + if (unbind) { + Cbuf_AddText ("unbindall\n"); + } + Cbuf_AddText ("exec default.cfg\n"); + Cbuf_AddText ("exec kmq2config.cfg\n"); + + // Look for kmq2config.cfg, if not there, try config.cfg + // Removed because some settings in existing config.cfgs may cause problems +/* FS_LoadFile ("kmq2config.cfg", (void **)&cfgfile); + if (cfgfile) + { + Cbuf_AddText ("exec kmq2config.cfg\n"); + FS_FreeFile (cfgfile); + } + else + Cbuf_AddText ("exec config.cfg\n"); +*/ +} + + /* ============= FS_ExecAutoexec @@ -2870,17 +2903,20 @@ FS_ExecAutoexec */ void FS_ExecAutoexec (void) { - char *dir; - char name [MAX_QPATH]; + char *dir; + char name[MAX_QPATH]; dir = Cvar_VariableString("gamedir"); - if (*dir) - Com_sprintf(name, sizeof(name), "%s/%s/autoexec.cfg", fs_basedir->string, dir); - else + if (*dir) { + Com_sprintf(name, sizeof(name), "%s/%s/autoexec.cfg", fs_basedir->string, dir); + } + else { Com_sprintf(name, sizeof(name), "%s/%s/autoexec.cfg", fs_basedir->string, BASEDIRNAME); - if (Sys_FindFirst(name, 0, SFF_SUBDIR | SFF_HIDDEN | SFF_SYSTEM)) + } + if ( Sys_FindFirst(name, 0, SFF_SUBDIR | SFF_HIDDEN | SFF_SYSTEM) ) { Cbuf_AddText ("exec autoexec.cfg\n"); - Sys_FindClose(); + } + Sys_FindClose (); } /* diff --git a/qcommon/qcommon.h b/qcommon/qcommon.h index 05e6c7f..b4c5fbe 100644 --- a/qcommon/qcommon.h +++ b/qcommon/qcommon.h @@ -902,6 +902,7 @@ void FS_InsertInList (char **list, const char *insert, int len, int start); void FS_Dir_f (void); void FS_ExecAutoexec (void); +void FS_ExecConfigs (qboolean unbind); // Knightmare added int FS_LoadFile (const char *path, void **buffer); void FS_AddPAKFile (const char *packPath, qboolean isProtected); // add pak file function @@ -1041,6 +1042,7 @@ CLIENT / SERVER SYSTEMS void CL_Init (void); void CL_Drop (void); void CL_Shutdown (void); +void CL_ChangeGameRefresh (void); // Knightmare added void CL_Frame (int msec); void Con_Print (char *text); void SCR_BeginLoadingPlaque (void); diff --git a/server/sv_ccmds.c b/server/sv_ccmds.c index 102ad6e..9ae9b56 100644 --- a/server/sv_ccmds.c +++ b/server/sv_ccmds.c @@ -1121,11 +1121,14 @@ void SV_StartMod (char *mod) // killserver, start mod, unbind keys, exec configs, and start demos Cbuf_AddText ("killserver\n"); Cbuf_AddText (va("game %s\n", mod)); - Cbuf_AddText ("unbindall\n"); - Cbuf_AddText ("exec default.cfg\n"); - Cbuf_AddText ("exec kmq2config.cfg\n"); - Cbuf_AddText ("exec autoexec.cfg\n"); - Cbuf_AddText ("d1\n"); +// Cbuf_AddText ("unbindall\n"); +// Cbuf_AddText ("exec default.cfg\n"); +// Cbuf_AddText ("exec kmq2config.cfg\n"); +// Cbuf_AddText ("exec autoexec.cfg\n"); + if (!dedicated->integer) + Cbuf_AddText ("d1\n"); + else + Cbuf_AddText ("dedicated_start\n"); } /* diff --git a/ui/ui_local.h b/ui/ui_local.h index 7f66bad..ace99ab 100644 --- a/ui/ui_local.h +++ b/ui/ui_local.h @@ -250,6 +250,9 @@ extern char **ui_video_modes; extern char **ui_aniso_names; extern char **ui_aniso_values; +//extern char **ui_mod_names; +//extern char **ui_mod_values; + extern char **ui_font_names; extern int ui_numfonts; @@ -352,10 +355,14 @@ int UI_TallyMenuSlots (menuframework_s *menu); void UIStartSPGame (void); void UI_StartServer (char *startmap, qboolean dedicated); +void UI_LoadMod (char *modName); void UI_GetVideoInfo (void); void UI_FreeVideoInfo (void); +//void UI_GetModList (void); +//void UI_FreeModList (void); + void UI_LoadFontNames (void); void UI_FreeFontNames (void); @@ -463,7 +470,7 @@ void UI_DrawMenu (menuframework_s *menu); const char *UI_DefaultMenuKey (menuframework_s *m, int key); // -// ui_subsystem.c +// ui_main.c // void UI_Draw (void); void UI_Keydown (int key); @@ -471,6 +478,7 @@ void UI_RootMenu (void); void UI_Precache (void); void UI_Init (void); void UI_Shutdown (void); +void UI_RefreshData (void); // // ui_draw.c diff --git a/ui/ui_main.c b/ui/ui_main.c index 0ab427f..0483b67 100644 --- a/ui/ui_main.c +++ b/ui/ui_main.c @@ -245,6 +245,7 @@ void UI_Init (void) Cvar_SetDescription ("ui_new_textfield", "Toggles use of new text field image. Setting this to 0 uses old font-based tiles."); UI_GetVideoInfo (); // build video mode list +// UI_GetModList (); // load mods list UI_LoadFontNames (); // load font list // UI_LoadHudNames (); // load hud list UI_LoadCrosshairs (); // load crosshairs @@ -295,6 +296,7 @@ void UI_Shutdown (void) return; UI_FreeVideoInfo (); +// UI_FreeModList (); UI_FreeFontNames (); // UI_FreeHudNames (); UI_FreeCrosshairs (); @@ -326,3 +328,38 @@ void UI_Shutdown (void) ui_initialized = false; } + + +/* +================= +UI_RefreshData +================= +*/ +void UI_RefreshData (void) +{ + // Don't refresh data if not initialized + // Fixes errors in dedicated console + if (!ui_initialized) + return; + + // Close all menus before refreshing data + UI_ForceMenuOff (); + + UI_FreeVideoInfo (); +// UI_FreeModList (); + UI_FreeFontNames (); +// UI_FreeHudNames (); + UI_FreeCrosshairs (); + UI_FreeMapList (); + UI_FreePlayerModels (); + + UI_GetVideoInfo (); // build video mode list +// UI_GetModList (); // load mods list + UI_LoadFontNames (); // load font list +// UI_LoadHudNames (); // load hud list + UI_LoadCrosshairs (); // load crosshairs + UI_InitServerList (); // init join server list + UI_LoadMapList (); // load map list + UI_LoadPlayerModels (); // load player models + UI_InitSavegameData (); // load savegame data +} diff --git a/ui/ui_utils.c b/ui/ui_utils.c index 3bd9017..cd7b0a1 100644 --- a/ui/ui_utils.c +++ b/ui/ui_utils.c @@ -373,6 +373,20 @@ void UI_StartServer (char *startmap, qboolean dedicated) // UI_ForceMenuOff (); } + +/* +=============== +UI_LoadMod +=============== +*/ +void UI_LoadMod (char *modName) +{ + if ( Q_strcasecmp(Cvar_VariableString("game"), modName) ) { + UI_ForceMenuOff (); + Cbuf_AddText (va("changegame %s\n", modName) ); + } +} + /* ======================================================================= @@ -578,6 +592,187 @@ void UI_FreeVideoInfo (void) UI_FreeAnisoValues (); } +/* +======================================================================= + + MOD LIST LOADING + +======================================================================= +*/ + +// TODO: Enable this when mod menu is ready +#if 0 +#define UI_MAX_MODS 256 + +char **ui_mod_names = NULL; +char **ui_mod_values = NULL; +qboolean ui_mod_isUnsupported[UI_MAX_MODS]; +int ui_num_mods = 0; + +/* +========================== +UI_BuildModList +========================== +*/ +void UI_BuildModList (void) +{ + char findName[1024]; + char modDesc[1024]; + char modFormatedName[1024]; + char **dirnames; + char *modDir, *modName; + FILE *f; + int count = 0, ndirs = 0, nmods = 0; + int i; + qboolean unsupportedMod; + + ui_mod_names = malloc(sizeof(char *) * (UI_MAX_MODS+1)); + ui_mod_values = malloc(sizeof(char *) * (UI_MAX_MODS+1)); + memset(ui_mod_names, 0, sizeof(char *) * (UI_MAX_MODS+1)); + memset(ui_mod_values, 0, sizeof(char *) * (UI_MAX_MODS+1)); + + // add baseq2 first + ui_mod_names[0] = strdup("Quake II (vanilla)"); + ui_mod_values[0] = strdup(BASEDIRNAME); + ui_mod_isUnsupported[0] = false; + count++; + + // get a list of directories + Com_sprintf(findName, sizeof(findName), "%s/*.*", FS_HomePath()); + dirnames = FS_ListFiles (findName, &ndirs, SFF_SUBDIR, 0); + if (!dirnames) { + ui_num_mods = count; + return; + } + + // go through the directories + nmods = ndirs; + if (nmods > UI_MAX_MODS) + nmods = UI_MAX_MODS; + if ( (count + nmods) > UI_MAX_MODS ) + nmods = UI_MAX_MODS - count; + + for (i = 0; i < nmods; i++) + { + if (dirnames[i] == 0) + continue; + + modDir = COM_SkipPath(dirnames[i]); + + // Ignore baseq2 + if ( !Q_strcasecmp(modDir, BASEDIRNAME) ) + continue; + + // Must have a pak or pk3 file, or a maps dir + if ( !Sys_FindFirst( va("%s/*.pak", dirnames[i]), 0, SFF_SUBDIR | SFF_HIDDEN | SFF_SYSTEM) ) { + Sys_FindClose(); + if ( !Sys_FindFirst( va("%s/*.pk3", dirnames[i]), 0, SFF_SUBDIR | SFF_HIDDEN | SFF_SYSTEM) ) { + Sys_FindClose(); + if ( !Sys_FindFirst( va("%s/maps", dirnames[i]), SFF_SUBDIR, 0) ) { + Sys_FindClose(); + continue; + } + } + } + Sys_FindClose(); + + // check if this mod has a gamex86.dll/gamei386.so without an equivalent KMQ2 dll/so + unsupportedMod = false; + if ( Sys_FindFirst( va("%s/"STOCK_Q2_GAME_LIBRARY_NAME, dirnames[i]), 0, SFF_SUBDIR | SFF_HIDDEN | SFF_SYSTEM) ) + { + Sys_FindClose(); + if ( !Sys_FindFirst( va("%s/"KMQ2_GAME_LIBRARY_NAME, dirnames[i]), 0, SFF_SUBDIR | SFF_HIDDEN | SFF_SYSTEM) ) { + Sys_FindClose(); + unsupportedMod = true; + // Com_Printf ("UI_BuildModList: mod %s has an unsupported game library.\n", modDir); + } + } + Sys_FindClose(); + + // try to load description.txt + f = fopen( va("%s/description.txt", dirnames[i]), "rb"); + if (f != NULL) { + fgets(modDesc, sizeof(modDesc), f); + fclose(f); + modName = modDesc; + } + else if ( !Q_strcasecmp(modDir, "ctf") ) + modName = "Quake II: Capture The Flag"; + else if ( !Q_strcasecmp(modDir, "rogue") ) + modName = "Quake II: Ground Zero"; + else if ( !Q_strcasecmp(modDir, "xatrix") ) + modName = "Quake II: The Reckoning"; + else if ( !Q_strcasecmp(modDir, "zaero") ) + modName = "Zaero Mission Pack"; + else if ( !Q_strcasecmp(modDir, "3zb2") ) + modName ="3rd Zigrock Bot II"; + else if ( !Q_strcasecmp(modDir, "gen") ) + modName = "Generations"; + else if ( !Q_strcasecmp(modDir, "ra2") ) + modName = "Rocket Arena 2"; + else if ( !Q_strcasecmp(modDir, "bots") ) + modName = "Battle of the Sexes"; + else if ( !Q_strcasecmp(modDir, "lmctf") ) + modName = "Loki's Minions CTF"; + else if ( !Q_strcasecmp(modDir, "wf") ) + modName = "Weapons Factory"; + else if ( !Q_strcasecmp(modDir, "wod") ) + modName = "Weapons of Destruction"; + else if ( !Q_strcasecmp(modDir, "rts") ) + modName = "Rob the Strogg"; + else + modName = modDir; + + if (unsupportedMod) + Com_sprintf(modFormatedName, sizeof(modFormatedName), S_COLOR_ORANGE"%s\0", modName); + else + Q_strncpyz(modFormatedName, sizeof(modFormatedName), modName); + + if (!FS_ItemInList(modDir, count, ui_mod_values)) + { + // FS_InsertInList (ui_mod_names, modName, count, 1); // start=1 so first item stays first! + FS_InsertInList (ui_mod_names, modFormatedName, count, 1); // start=1 so first item stays first! + FS_InsertInList (ui_mod_values, modDir, count, 1); // start=1 so first item stays first! + count++; + ui_mod_isUnsupported[count] = unsupportedMod; + } + } + + if (dirnames) + FS_FreeFileList (dirnames, ndirs); + + ui_num_mods = count; +} + + +/* +========================== +UI_GetModList +========================== +*/ +void UI_GetModList (void) +{ + UI_BuildModList (); +// Com_Printf ("UI_GetModList: found %i mod dirs\n", ui_num_mods); +} + + +/* +========================== +UI_FreeModList +========================== +*/ +void UI_FreeModList (void) +{ + if (ui_num_mods > 0) { + FS_FreeFileList (ui_mod_names, ui_num_mods); + FS_FreeFileList (ui_mod_values, ui_num_mods); + } + ui_mod_names = NULL; + ui_mod_values = NULL; +} +#endif + /* ======================================================================= @@ -1995,8 +2190,10 @@ void UI_BuildStartSeverLevelshotTables (void) for (i=0; i