Fix demo loop after changing the game through the menu.

Injecting the demo loop right after the `game` cvar was changed cannot
work: The demo loop is implemented through aliases, aliases are expended
as soon as they're added to the command buffer. However, the game isn't
changed as soon as the cvar is set, but the next time when the control
flow enters the file system. Therefor the aliases get expanded to the
wrong game and the demo loops breaks.

This closes #719.
This commit is contained in:
Yamagi 2021-07-25 09:45:51 +02:00
parent fb1a2b0ce7
commit e2e2bddfa3
2 changed files with 30 additions and 1 deletions

View file

@ -39,6 +39,9 @@ static int m_main_cursor;
/* Number of the frames of the spinning quake logo */
#define NUM_CURSOR_FRAMES 15
/* Signals the file system to start the demo loop. */
qboolean menu_startdemoloop;
static char *menu_in_sound = "misc/menu1.wav";
static char *menu_move_sound = "misc/menu2.wav";
static char *menu_out_sound = "misc/menu3.wav";
@ -2193,7 +2196,7 @@ ModsApplyActionFunc(void *unused)
Cbuf_AddText(va("game %s\n", modnames[s_mods_list.curvalue]));
// start the demo cycle in the new game directory
Cbuf_AddText("d1\n");
menu_startdemoloop = true;
M_ForceMenuOff();
}

View file

@ -1715,7 +1715,18 @@ void FS_BuildGenericSearchPath(void) {
Sys_Mkdir(path);
}
// filesystem.c is used by the client and the server,
// it includes common.h only. Not the client not the
// server header. The game reset logic messes with
// client state, so we need some forwar declarations
// here.
#ifndef DEDICATED_ONLY
// Variables
extern qboolean menu_startdemoloop;
// Functions
void CL_WriteConfiguration(void);
#endif
void
FS_BuildGameSpecificSearchPath(char *dir)
@ -1819,6 +1830,21 @@ FS_BuildGameSpecificSearchPath(char *dir)
free(mapnames);
mapnames = NULL;
}
// Start the demoloop, if requested. This is kind of hacky: Normaly the
// demo loop would be started by the menu, after changeing the 'game'
// cvar. However, the demo loop is implemented by aliases. Since the
// game isn't changed right after the cvar is set (but when the control
// flow enters this function) the aliases evaulate to the wrong game.
// Work around that by injection the demo loop into the command buffer
// here, right after the game was changed. Do it only when the game was
// changed though the menu, otherwise we might break into the demo loop
// after we've received a latched cvar from the server.
if (menu_startdemoloop)
{
Cbuf_AddText("d1\n");
menu_startdemoloop = false;
}
#endif
}