initial implementation of demo join (#679)

* initial implementation of demo join

* fix demo name when using join command

* don't save ".lmp" extension twice

* now the demo join command works in netgame

* remove redunant string copy
This commit is contained in:
Roman Fomin 2022-07-29 23:52:32 +07:00 committed by GitHub
parent 097f6915f6
commit 6ffda6c393
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 135 additions and 41 deletions

View File

@ -119,6 +119,9 @@ typedef enum
// Savegame slot numbers occupy the second byte of buttons.
BTS_SAVEMASK = (4+8+16),
BTS_SAVESHIFT = 2,
// [crispy] demo joined.
BT_JOIN = 64
} buttoncode_t;

View File

@ -2648,7 +2648,8 @@ void D_DoomMain(void)
if (autostart || netgame)
{
G_InitNew(startskill, startepisode, startmap);
if (demorecording)
// [crispy] no need to write a demo header in demo continue mode
if (demorecording && gameaction != ga_playdemo)
G_BeginRecording();
}
else

View File

@ -96,6 +96,7 @@ boolean paused;
boolean sendpause; // send a pause event next tic
boolean sendsave; // send a save event next tic
boolean sendreload; // send a reload level event next tic
boolean sendjoin;
boolean usergame; // ok to save / end game
boolean timingdemo; // if true, exit with report on completion
boolean fastdemo; // if true, run at full speed -- killough
@ -135,6 +136,9 @@ int default_complevel;
boolean strictmode, default_strictmode;
// [crispy] store last cmd to track joins
static ticcmd_t* last_cmd = NULL;
//
// controls (have defaults)
//
@ -617,6 +621,12 @@ void G_BuildTiccmd(ticcmd_t* cmd)
cmd->buttons = BT_SPECIAL | (BTS_RELOAD & BT_SPECIALMASK);
}
if (sendjoin)
{
sendjoin = false;
cmd->buttons |= BT_JOIN;
}
// low-res turning
if (lowres_turn)
@ -860,6 +870,12 @@ boolean G_Responder(event_t* ev)
return true;
}
if (M_InputActivated(input_demo_join))
{
sendjoin = true;
return true;
}
// killough 10/98:
// Don't pop up menu, if paused in middle
// of demo playback, or if automap active.
@ -967,12 +983,41 @@ boolean G_Responder(event_t* ev)
// [crispy] demo progress bar
int defdemotics = 0, deftotaldemotics;
static char *defdemoname;
#define DEMOMARKER 0x80
// Stay in the game, hand over controls to the player and continue recording the
// demo under a different name
static void G_JoinDemo(void)
{
byte *actualbuffer = demobuffer;
int actualsize = maxdemosize;
// [crispy] find a new name for the continued demo
G_RecordDemo(defdemoname);
// [crispy] discard the newly allocated demo buffer
Z_Free(demobuffer);
demobuffer = actualbuffer;
maxdemosize = actualsize;
// [crispy] continue recording
demoplayback = false;
// clear progress demo bar
ST_Start();
doomprintf("Demo recording: %s", demoname);
}
static void G_ReadDemoTiccmd(ticcmd_t *cmd)
{
if (*demo_p == DEMOMARKER)
{
last_cmd = cmd; // [crispy] remember last cmd to track joins
G_CheckDemoStatus(); // end of demo data stream
}
else
{
cmd->forwardmove = ((signed char)*demo_p++);
@ -1002,12 +1047,21 @@ static void G_ReadDemoTiccmd(ticcmd_t *cmd)
}
}
static void CheckDemoBuffer(size_t size)
{
ptrdiff_t position = demo_p - demobuffer;
if (position + size > maxdemosize)
{
maxdemosize += size + 128 * 1024; // add another 128K
demobuffer = Z_Realloc(demobuffer, maxdemosize, PU_STATIC, 0);
demo_p = position + demobuffer;
}
}
// Demo limits removed -- killough
static void G_WriteDemoTiccmd(ticcmd_t* cmd)
{
ptrdiff_t position = demo_p - demobuffer;
if (M_InputGameActive(input_demo_quit)) // press to end demo recording
G_CheckDemoStatus();
@ -1025,14 +1079,7 @@ static void G_WriteDemoTiccmd(ticcmd_t* cmd)
demo_p[4] = cmd->buttons;
}
if (position+16 > maxdemosize) // killough 8/23/98
{
// no more space
maxdemosize += 128*1024; // add another 128K -- killough
demobuffer = Z_Realloc(demobuffer,maxdemosize, PU_STATIC, 0);
demo_p = position + demobuffer; // back on track
// end of main demo limit changes -- killough
}
CheckDemoBuffer(16); // killough 8/23/98
G_ReadDemoTiccmd (cmd); // make SURE it is exactly the same
}
@ -1351,8 +1398,6 @@ static void G_DoWorldDone(void)
#define MIN_MAXPLAYERS 32
static char *defdemoname;
#define INVALID_DEMO(a, b) \
do \
{ \
@ -1375,6 +1420,13 @@ static void G_DoPlayDemo(void)
if (gameaction != ga_loadgame) // killough 12/98: support -loadgame
basetic = gametic; // killough 9/29/98
// [crispy] in demo continue mode free the obsolete demo buffer
// of size 'maxdemosize' previously allocated in G_RecordDemo()
if (demorecording)
{
Z_Free(demobuffer);
}
ExtractFileBase(defdemoname,basename); // killough
lumpnum = W_GetNumForName(basename);
@ -1583,6 +1635,8 @@ static void G_DoPlayDemo(void)
gameaction = ga_nothing;
maxdemosize = lumplength;
// [crispy] demo progress bar
{
byte *demo_ptr = demo_p;
@ -2120,10 +2174,16 @@ void G_Ticker(void)
memcpy(cmd, &netcmds[i], sizeof *cmd);
// catch BT_JOIN before G_ReadDemoTiccmd overwrites it
if (demoplayback && cmd->buttons & BT_JOIN)
G_JoinDemo();
if (demoplayback)
G_ReadDemoTiccmd(cmd);
if (demorecording)
// [crispy] do not record tics while still playing back in demo
// continue mode
if (demorecording && !demoplayback)
G_WriteDemoTiccmd(cmd);
// check for turbo cheats
@ -3130,7 +3190,11 @@ void G_RecordDemo(char *name)
for(; j <= 99999 && !M_access(demoname, F_OK); ++j)
{
M_snprintf(demoname, demoname_size, "%s-%05d.lmp", name, j);
char *str = M_StringDuplicate(name);
if (M_StringCaseEndsWith(str, ".lmp"))
str[strlen(str) - 4] = '\0';
M_snprintf(demoname, demoname_size, "%s-%05d.lmp", str, j);
free(str);
}
//!
@ -3569,7 +3633,6 @@ extern char **dehfiles;
static void G_AddDemoFooter(void)
{
ptrdiff_t position = demo_p - demobuffer;
char *tmp = NULL;
size_t len = 0;
int i;
@ -3636,12 +3699,7 @@ static void G_AddDemoFooter(void)
mem_get_buf(stream, (void **)&tmp, &len);
if (position + len > maxdemosize)
{
maxdemosize += len;
demobuffer = Z_Realloc(demobuffer, maxdemosize, PU_STATIC, 0);
demo_p = position + demobuffer;
}
CheckDemoBuffer(len);
memcpy(demo_p, tmp, len);
demo_p += len;
@ -3659,6 +3717,44 @@ static void G_AddDemoFooter(void)
boolean G_CheckDemoStatus(void)
{
// [crispy] catch the last cmd to track joins
ticcmd_t* cmd = last_cmd;
last_cmd = NULL;
if (demoplayback)
{
if (demorecording)
{
demoplayback = false;
// clear progress demo bar
ST_Start();
// [crispy] record demo join
if (cmd != NULL)
{
cmd->buttons |= BT_JOIN;
}
return true;
}
if (singledemo)
I_SafeExit(0); // killough
// [FG] ignore empty demo lumps
if (demobuffer)
{
Z_ChangeTag(demobuffer, PU_CACHE);
}
G_ReloadDefaults(); // killough 3/1/98
netgame = false; // killough 3/29/98
deathmatch = false;
D_AdvanceDemo();
return true;
}
if (demorecording)
{
demorecording = false;
@ -3691,22 +3787,6 @@ boolean G_CheckDemoStatus(void)
(unsigned) gametic * (double) TICRATE / realtics);
}
if (demoplayback)
{
if (singledemo)
I_SafeExit(0); // killough
// [FG] ignore empty demo lumps
if (demobuffer)
{
Z_ChangeTag(demobuffer, PU_CACHE);
}
G_ReloadDefaults(); // killough 3/1/98
netgame = false; // killough 3/29/98
deathmatch = false;
D_AdvanceDemo();
return true;
}
return false;
}

View File

@ -91,6 +91,7 @@ enum
input_spy,
input_demo_quit,
input_demo_fforward,
input_demo_join,
input_speed_up,
input_speed_down,
input_speed_default,

View File

@ -2893,11 +2893,12 @@ setup_menu_t keys_settings4[] = // Key Binding screen strings
{"DEMOS" ,S_SKIP|S_TITLE,m_null,KB_X,M_Y+5*M_SPC},
{"FAST-FORWARD" ,S_INPUT,m_scrn,KB_X,M_Y+6*M_SPC,{0},input_demo_fforward},
{"FINISH DEMO" ,S_INPUT,m_scrn,KB_X,M_Y+7*M_SPC,{0},input_demo_quit},
{"JOIN DEMO" ,S_INPUT,m_scrn,KB_X,M_Y+8*M_SPC,{0},input_demo_join},
// [FG] reload current level / go to next level
{"MISCELLANEOUS",S_SKIP|S_TITLE,m_null,KB_X,M_Y+9*M_SPC},
{"RELOAD LEVEL" ,S_INPUT,m_scrn,KB_X,M_Y+10*M_SPC,{0},input_menu_reloadlevel},
{"NEXT LEVEL" ,S_INPUT,m_scrn,KB_X,M_Y+11*M_SPC,{0},input_menu_nextlevel},
{"MISCELLANEOUS",S_SKIP|S_TITLE,m_null,KB_X,M_Y+10*M_SPC},
{"RELOAD LEVEL" ,S_INPUT,m_scrn,KB_X,M_Y+11*M_SPC,{0},input_menu_reloadlevel},
{"NEXT LEVEL" ,S_INPUT,m_scrn,KB_X,M_Y+12*M_SPC,{0},input_menu_nextlevel},
{"<- PREV", S_SKIP|S_PREV,m_null,M_X_PREV,M_Y_PREVNEXT, {keys_settings3}},
{"NEXT ->", S_SKIP|S_NEXT,m_null,M_X_NEXT,M_Y_PREVNEXT, {keys_settings5}},

View File

@ -903,6 +903,14 @@ default_t defaults[] = {
input_demo_quit, { {0, 0} }
},
{
"input_demo_join",
NULL, NULL,
{0}, {UL,UL}, input, ss_keys, wad_no,
"key to continue recording current demo",
input_demo_join, { {0, 0} }
},
{
"input_demo_fforward",
NULL, NULL,