More demo playback QOL (#692)

* implement negative -skipsec

* restart level/demo key also restarts demo playback

* rename the new demo* variables to playback_*

* disable skipping demo playback in multiplayer, add checks for connected players
This commit is contained in:
Roman Fomin 2022-08-10 13:50:15 +07:00 committed by GitHub
parent c96a0bbcac
commit a1c7b21909
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 164 additions and 87 deletions

View File

@ -109,13 +109,14 @@ static int player_class;
static int GetAdjustedTime(void)
{
if (new_sync && offsetms)
// Use the adjustments from net_client.c only if we are
// using the new sync mode.
if (new_sync && net_client_connected)
{
int time_ms;
time_ms = I_GetTimeMS();
// Use the adjustments from net_client.c only if we are
// using the new sync mode.
time_ms += (offsetms / FRACUNIT);
@ -522,6 +523,26 @@ boolean D_InitNetGame(net_connect_data_t *connect_data)
return result;
}
boolean D_CheckNetConnect(void)
{
return net_client_connected;
}
void D_CheckNetPlaybackSkip(void)
{
if (!net_client_connected)
{
return;
}
if (fastdemo || PLAYBACK_SKIP)
{
printf("Demo playback skipping is suppressed in multiplayer.\n");
fastdemo = false;
playback_warp = -1;
playback_skiptics = 0;
}
}
//
// D_QuitNetGame
@ -633,6 +654,23 @@ static boolean PlayersInGame(void)
return result;
}
int D_GetPlayersInNetGame(void)
{
int i;
int result = 0;
if (net_client_connected)
{
for (i = 0; i < NET_MAXPLAYERS; ++i)
{
if (local_playeringame[i])
++result;
}
}
return result;
}
// When using ticdup, certain values must be cleared out when running
// the duplicate ticcmds.

View File

@ -223,7 +223,7 @@ void D_Display (void)
int wipestart;
boolean done, wipe, redrawsbar;
if (demobar && DEMOSKIP)
if (demobar && PLAYBACK_SKIP)
{
if (HU_DemoProgressBar(false))
{
@ -1815,7 +1815,7 @@ static void D_EndDoom(void)
}
// [FG] fast-forward demo to the desired map
int demowarp = -1;
int playback_warp = -1;
//
// D_DoomMain
@ -2317,7 +2317,7 @@ void D_DoomMain(void)
autostart = true;
}
// [FG] fast-forward demo to the desired map
demowarp = startmap;
playback_warp = startmap;
}
//jff 1/22/98 add command line parms to disable sound and music
@ -2503,11 +2503,6 @@ void D_DoomMain(void)
I_InitJoystick();
I_InitSound();
if (fastdemo)
{
I_SetFastdemoTimer(true);
}
puts("NET_Init: Init network subsystem.");
NET_Init();
@ -2562,18 +2557,16 @@ void D_DoomMain(void)
if (sscanf(myargv[p+1], "%f:%f", &min, &sec) == 2)
{
demoskip_tics = (int) ((60 * min + sec) * TICRATE);
playback_skiptics = (int) ((60 * min + sec) * TICRATE);
}
else if (sscanf(myargv[p+1], "%f", &sec) == 1)
{
demoskip_tics = (int) (sec * TICRATE);
playback_skiptics = (int) (sec * TICRATE);
}
else
{
I_Error("Invalid parameter '%s' for -skipsec, should be min:sec", myargv[p+1]);
}
demoskip_tics = abs(demoskip_tics);
}
// start the apropriate game based on parms
@ -2660,8 +2653,13 @@ void D_DoomMain(void)
else
{
// [FG] no demo playback
demowarp = -1;
demoskip_tics = -1;
playback_warp = -1;
playback_skiptics = 0;
}
if (fastdemo)
{
I_SetFastdemoTimer(true);
}
// [FG] init graphics (WIDESCREENDELTA) before HUD widgets

View File

@ -292,26 +292,5 @@ void D_CheckNetGame (void)
printf("player %i of %i (%i nodes)\n",
consoleplayer+1, settings.num_players, settings.num_players);
// Show players here; the server might have specified a time limit
/*
if (timelimit > 0 && deathmatch)
{
// Gross hack to work like Vanilla:
if (timelimit == 20 && M_CheckParm("-avg"))
{
printf("Austin Virtual Gaming: Levels will end "
"after 20 minutes\n");
}
else
{
printf("Levels will end after %d minute", timelimit);
if (timelimit > 1)
printf("s");
printf(".\n");
}
}
*/
}

View File

@ -203,6 +203,8 @@ extern boolean respawnmonsters;
// Netgame? Only true if >1 player.
extern boolean netgame;
extern boolean D_CheckNetConnect(void);
// Flag: true only if started as net deathmatch.
// An enum might handle altdeath/cooperative better.
extern boolean deathmatch;
@ -298,13 +300,13 @@ extern boolean timingdemo;
// Run tick clock at fastest speed possible while playing demo. killough
extern boolean fastdemo;
// [FG] fast-forward demo to the desired map
extern int demowarp;
extern int playback_warp;
// fast-forward demo to the next map
extern boolean demonext;
extern boolean playback_nextlevel;
// skipping demo
extern int demoskip_tics;
extern int playback_skiptics;
#define DEMOSKIP (demowarp >= 0 || demoskip_tics > 0 || demonext)
#define PLAYBACK_SKIP (playback_warp >= 0 || playback_skiptics || playback_nextlevel)
extern boolean strictmode, default_strictmode;

View File

@ -313,26 +313,35 @@ void G_EnableWarp(boolean warp)
}
}
int demoskip_tics = -1;
static int playback_levelstarttic;
int playback_skiptics = 0;
static void G_DemoSkipTics(void)
{
static boolean warp = false;
if (demoskip_tics == -1)
if (!playback_skiptics || !playback_totaltics)
return;
if (demowarp >= 0)
if (playback_warp >= 0)
warp = true;
if (demowarp == -1)
if (playback_warp == -1)
{
if ((warp && demoskip_tics < gametic - levelstarttic) ||
(!warp && demoskip_tics < gametic))
if (playback_skiptics < 0)
{
if (warp)
playback_skiptics = playback_totaltics - playback_levelstarttic + playback_skiptics;
else
playback_skiptics = playback_totaltics + playback_skiptics;
}
if ((warp && playback_skiptics < playback_tic - playback_levelstarttic) ||
(!warp && playback_skiptics < playback_tic))
{
G_EnableWarp(false);
S_RestartMusic();
demoskip_tics = -1;
playback_skiptics = 0;
}
}
}
@ -705,6 +714,8 @@ static void G_DoLoadLevel(void)
levelstarttic = gametic; // for time calculation
playback_levelstarttic = playback_tic;
if (!demo_compatibility && demo_version < 203) // killough 9/29/98
basetic = gametic;
@ -839,7 +850,6 @@ boolean G_Responder(event_t* ev)
if (M_InputActivated(input_menu_reloadlevel) &&
(gamestate == GS_LEVEL || gamestate == GS_INTERMISSION) &&
!demoplayback &&
!deathmatch &&
!menuactive)
{
@ -872,7 +882,7 @@ boolean G_Responder(event_t* ev)
return true;
}
if (M_InputActivated(input_demo_join))
if (M_InputActivated(input_demo_join) && !PLAYBACK_SKIP && !fastdemo)
{
sendjoin = true;
return true;
@ -978,12 +988,27 @@ boolean G_Responder(event_t* ev)
return false;
}
int D_GetPlayersInNetGame(void);
static void CheckPlayersInNetGame(void)
{
int i;
int playerscount = 0;
for (i = 0; i < MAXPLAYERS; ++i)
{
if (playeringame[i])
++playerscount;
}
if (playerscount != D_GetPlayersInNetGame())
I_Error("Not enough players to continue the demo.");
}
//
// DEMO RECORDING
//
// [crispy] demo progress bar
int defdemotics = 0, deftotaldemotics;
int playback_tic = 0, playback_totaltics = 0;
static char *defdemoname;
@ -993,6 +1018,9 @@ static char *defdemoname;
// demo under a different name
static void G_JoinDemo(void)
{
if (netgame)
CheckPlayersInNetGame();
if (!orig_demoname)
{
byte *actualbuffer = demobuffer;
@ -1048,7 +1076,7 @@ static void G_ReadDemoTiccmd(ticcmd_t *cmd)
players[consoleplayer].message = "Game Saved (Suppressed)";
}
defdemotics++;
playback_tic++;
}
}
@ -1646,12 +1674,12 @@ static void G_DoPlayDemo(void)
{
byte *demo_ptr = demo_p;
deftotaldemotics = defdemotics = 0;
playback_totaltics = playback_tic = 0;
while (*demo_ptr != DEMOMARKER && (demo_ptr - demobuffer) < lumplength)
{
demo_ptr += (longtics ? 5 : 4);
deftotaldemotics++;
playback_totaltics++;
}
}
@ -2185,6 +2213,15 @@ void G_Ticker(void)
if (demoplayback && cmd->buttons & BT_JOIN)
G_JoinDemo();
// catch BTS_RELOAD for demo playback restart
if (demoplayback &&
cmd->buttons & BT_SPECIAL && cmd->buttons & BT_SPECIALMASK &&
cmd->buttons & BTS_RELOAD)
{
playback_tic = 0;
gameaction = ga_playdemo;
}
if (demoplayback)
G_ReadDemoTiccmd(cmd);
@ -3152,7 +3189,7 @@ void G_InitNew(skill_t skill, int episode, int map)
// [FG] total time for all completed levels
totalleveltimes = 0;
defdemotics = 0;
playback_tic = 0;
//jff 4/16/98 force marks on automap cleared every new level start
AM_clearMarks();
@ -3620,13 +3657,17 @@ void G_BeginRecording(void)
// G_PlayDemo
//
void D_CheckNetPlaybackSkip(void);
void G_DeferedPlayDemo(char* name)
{
defdemoname = name;
gameaction = ga_playdemo;
D_CheckNetPlaybackSkip();
// [FG] fast-forward demo to the desired map
if (demowarp >= 0 || demoskip_tics > 0)
if (playback_warp >= 0 || playback_skiptics)
{
G_EnableWarp(true);
}
@ -3729,6 +3770,9 @@ boolean G_CheckDemoStatus(void)
{
if (demorecording)
{
if (netgame)
CheckPlayersInNetGame();
demoplayback = false;
// clear progress demo bar

View File

@ -1082,10 +1082,10 @@ static void HU_DrawCrosshair(void)
// [crispy] print a bar indicating demo progress at the bottom of the screen
boolean HU_DemoProgressBar(boolean force)
{
const int progress = SCREENWIDTH * defdemotics / deftotaldemotics;
const int progress = SCREENWIDTH * playback_tic / playback_totaltics;
static int old_progress = 0;
if (progress - old_progress)
if (old_progress < progress)
{
old_progress = progress;
}

View File

@ -89,7 +89,7 @@ extern int hud_timests; // Time/STS above status bar
extern boolean message_centered; // center messages
extern boolean message_colorized; // colorize player messages
extern int defdemotics, deftotaldemotics;
extern int playback_tic, playback_totaltics;
extern int crispy_hud;

View File

@ -1009,7 +1009,7 @@ void I_BeginRead(unsigned int bytes)
static void I_DrawDiskIcon(void)
{
if (!disk_icon || !in_graphics_mode || DEMOSKIP)
if (!disk_icon || !in_graphics_mode || PLAYBACK_SKIP)
return;
if (disk_to_draw >= DISK_ICON_THRESHOLD)
@ -1032,7 +1032,7 @@ void I_EndRead(void)
static void I_RestoreDiskBackground(void)
{
if (!disk_icon || !in_graphics_mode || DEMOSKIP)
if (!disk_icon || !in_graphics_mode || PLAYBACK_SKIP)
return;
if (disk_to_restore)
@ -1383,6 +1383,7 @@ static void I_InitGraphicsMode(void)
if (firsttime)
{
int p, tmp_scalefactor;
firsttime = false;
//!
@ -1421,8 +1422,8 @@ static void I_InitGraphicsMode(void)
// Don't scale up the screen. Implies -window.
//
if (M_CheckParm("-1"))
scalefactor = 1;
if ((p = M_CheckParm("-1")))
tmp_scalefactor = 1;
//!
// @category video
@ -1430,8 +1431,8 @@ static void I_InitGraphicsMode(void)
// Double up the screen to 2x its normal size. Implies -window.
//
else if (M_CheckParm("-2"))
scalefactor = 2;
else if ((p = M_CheckParm("-2")))
tmp_scalefactor = 2;
//!
// @category video
@ -1439,12 +1440,16 @@ static void I_InitGraphicsMode(void)
// Triple up the screen to 3x its normal size. Implies -window.
//
else if (M_CheckParm("-3"))
scalefactor = 3;
else if (M_CheckParm("-4"))
scalefactor = 4;
else if (M_CheckParm("-5"))
scalefactor = 5;
else if ((p = M_CheckParm("-3")))
tmp_scalefactor = 3;
else if ((p = M_CheckParm("-4")))
tmp_scalefactor = 4;
else if ((p = M_CheckParm("-5")))
tmp_scalefactor = 5;
// -skipsec can take a negative number as a parameter
if (p && strcasecmp("-skipsec", myargv[p - 1]))
scalefactor = tmp_scalefactor;
//!
// @category video

View File

@ -178,10 +178,20 @@ void M_CheckCommandLine(void)
else if (!strcasecmp(myargv[p], "-warp"))
{
check = CheckNumArgs(p, 1);
if (!check)
I_Error("No parameter for '-warp'.");
else
if (check)
p = check;
else
I_Error("No parameter for '-warp'.");
}
// -skipsec can be negative
else if (!strcasecmp(myargv[p], "-skipsec") && p + 1 < myargc)
{
float min, sec;
if (sscanf(myargv[p + 1], "%f:%f", &min, &sec) == 2 ||
sscanf(myargv[p + 1], "%f", &sec) == 1)
p += 2;
else
I_Error("No parameter for '-skipsec'.");
}
// -turbo has default value
else if (!strcasecmp(myargv[p], "-turbo"))

View File

@ -5347,9 +5347,9 @@ boolean M_Responder (event_t* ev)
// [FG] reload current level / go to next level
if (M_InputActivated(input_menu_nextlevel))
{
if (demoplayback && singledemo && !DEMOSKIP)
if (demoplayback && singledemo && !PLAYBACK_SKIP)
{
demonext = true;
playback_nextlevel = true;
G_EnableWarp(true);
return true;
}
@ -5359,7 +5359,8 @@ boolean M_Responder (event_t* ev)
if (M_InputActivated(input_demo_fforward))
{
if (demoplayback && singledemo && !DEMOSKIP && !fastdemo)
if (demoplayback && !PLAYBACK_SKIP && !fastdemo
&& !D_CheckNetConnect())
{
static boolean fastdemo_timer = false;
fastdemo_timer = !fastdemo_timer;
@ -5368,7 +5369,7 @@ boolean M_Responder (event_t* ev)
}
}
if (M_InputActivated(input_speed_up) && (!netgame || demoplayback)
if (M_InputActivated(input_speed_up) && !D_CheckNetConnect()
&& !strictmode)
{
realtic_clock_rate += 10;
@ -5377,7 +5378,7 @@ boolean M_Responder (event_t* ev)
I_SetTimeScale(realtic_clock_rate);
}
if (M_InputActivated(input_speed_down) && (!netgame || demoplayback)
if (M_InputActivated(input_speed_down) && !D_CheckNetConnect()
&& !strictmode)
{
realtic_clock_rate -= 10;
@ -5386,7 +5387,7 @@ boolean M_Responder (event_t* ev)
I_SetTimeScale(realtic_clock_rate);
}
if (M_InputActivated(input_speed_default) && (!netgame || demoplayback)
if (M_InputActivated(input_speed_default) && !D_CheckNetConnect()
&& !strictmode)
{
realtic_clock_rate = 100;

View File

@ -1501,7 +1501,7 @@ static boolean P_LoadReject(int lumpnum, int totallines)
// killough 5/3/98: reformatted, cleaned up
// fast-forward demo to the next map
boolean demonext = false;
boolean playback_nextlevel = false;
void P_SetupLevel(int episode, int map, int playermask, skill_t skill)
{
@ -1522,13 +1522,13 @@ void P_SetupLevel(int episode, int map, int playermask, skill_t skill)
players[consoleplayer].viewz = 1;
// [FG] fast-forward demo to the desired map
if (demowarp == map || demonext)
if (playback_warp == map || playback_nextlevel)
{
if (demoskip_tics == -1)
if (!playback_skiptics)
G_EnableWarp(false);
demowarp = -1;
demonext = false;
playback_warp = -1;
playback_nextlevel = false;
}
// Make sure all sounds are stopped before Z_FreeTags.