Don't force loading files for replays

This commit is contained in:
fickleheart 2019-02-17 10:04:48 -06:00
parent ed7afc4267
commit d1d270c09d
5 changed files with 152 additions and 8 deletions

View file

@ -2003,7 +2003,7 @@ static void Command_Playdemo_f(void)
{
char name[256];
if (COM_Argc() != 2)
if (COM_Argc() < 2)
{
CONS_Printf(M_GetText("playdemo <demoname>: playback a demo\n"));
return;
@ -2027,6 +2027,9 @@ static void Command_Playdemo_f(void)
CONS_Printf(M_GetText("Playing back demo '%s'.\n"), name);
demo_loadfiles = strcmp(COM_Argv(2), "-addfiles") == 0;
demo_ignorefiles = strcmp(COM_Argv(2), "-force") == 0;
// Internal if no extension, external if one exists
// If external, convert the file name to a path in SRB2's home directory
if (FIL_CheckExtension(name))

View file

@ -1080,6 +1080,8 @@ void F_TitleScreenTicker(boolean run)
}*/
titledemo = fromtitledemo = true;
demo_ignorefiles = true;
demo_loadfiles = false;
G_DoPlayDemo(dname);
}
}

View file

@ -287,8 +287,10 @@ UINT32 timesBeaten;
UINT32 timesBeatenWithEmeralds;
//UINT32 timesBeatenUltimate;
//@TODO put these all in a struct for namespacing purposes?
static char demoname[64];
boolean demorecording, demosaved, demodefersave, demoplayback;
boolean demo_loadfiles, demo_ignorefiles; // Demo file loading options
tic_t demosavebutton;
boolean titledemo; // Title Screen demo can be cancelled by any key
boolean fromtitledemo; // SRB2Kart: Don't stop the music
@ -6053,11 +6055,10 @@ void G_BeginRecording(void)
totalfiles = 0;
for (i = mainwads; ++i < numwadfiles; )
if (!W_VerifyNMUSlumps(wadfiles[i]->filename))
if (!wadfiles[i]->important)
{
nameonly(( filename = va("%s", wadfiles[i]->filename) ));
/* FIXME: maximum size? */
WRITESTRING(demo_p, filename);
WRITESTRINGN(demo_p, filename, 64);
WRITEMEM(demo_p, wadfiles[i]->md5sum, 16);
totalfiles++;
@ -6316,6 +6317,87 @@ static void G_SkipDemoExtraFiles(UINT8 **pp)
}
}
// G_CheckDemoExtraFiles: checks if our loaded WAD list matches the demo's.
#define DFILE_ERROR_NOTLOADED 0x01 // Files are not loaded, but can be without a restart.
#define DFILE_ERROR_OUTOFORDER 0x02 // Files are loaded, but out of order.
#define DFILE_ERROR_INCOMPLETEOUTOFORDER 0x03 // Some files are loaded out of order, but others are not.
#define DFILE_ERROR_CANNOTLOAD 0x04 // Files are missing and cannot be loaded.
#define DFILE_ERROR_EXTRAFILES 0x05 // Extra files outside of the replay's file list are loaded.
static UINT8 G_CheckDemoExtraFiles(UINT8 **pp)
{
UINT8 totalfiles, filesloaded, nmusfilecount;
char filename[MAX_WADPATH];
UINT8 md5sum[16];
boolean toomany = false;
boolean alreadyloaded;
UINT8 i, j;
UINT8 error = 0;
totalfiles = READUINT8((*pp));
filesloaded = 0;
for (i = 0; i < totalfiles; ++i)
{
if (toomany)
SKIPSTRING((*pp));
else
{
strlcpy(filename, (char *)(*pp), sizeof filename);
SKIPSTRING((*pp));
}
READMEM((*pp), md5sum, 16);
if (!toomany)
{
alreadyloaded = false;
nmusfilecount = 0;
for (j = 0; j < numwadfiles; ++j)
{
if (wadfiles[j]->important && j > mainwads)
nmusfilecount++;
else
continue;
if (memcmp(md5sum, wadfiles[j]->md5sum, 16) == 0)
{
alreadyloaded = true;
if (i != nmusfilecount-1 && error < DFILE_ERROR_OUTOFORDER)
error |= DFILE_ERROR_OUTOFORDER;
break;
}
}
if (alreadyloaded)
{
filesloaded++;
continue;
}
if (numwadfiles >= MAX_WADFILES)
error = DFILE_ERROR_CANNOTLOAD;
else if (findfile(filename, md5sum, false) != FS_FOUND)
error = DFILE_ERROR_CANNOTLOAD;
else if (error < DFILE_ERROR_INCOMPLETEOUTOFORDER)
error |= DFILE_ERROR_NOTLOADED;
} else
error = DFILE_ERROR_CANNOTLOAD;
}
// Get final file count
nmusfilecount = 0;
for (j = 0; j < numwadfiles; ++j)
if (wadfiles[j]->important && j > mainwads)
nmusfilecount++;
if (!error && filesloaded < nmusfilecount)
error = DFILE_ERROR_EXTRAFILES;
return error;
}
// Returns bitfield:
// 1 == new demo has lower time
// 2 == new demo has higher score
@ -6455,7 +6537,7 @@ void G_DeferedPlayDemo(const char *name)
{
COM_BufAddText("playdemo \"");
COM_BufAddText(name);
COM_BufAddText("\"\n");
COM_BufAddText("\" -addfiles\n");
}
//
@ -6569,7 +6651,61 @@ void G_DoPlayDemo(char *defdemoname)
demoflags = READUINT8(demo_p);
if (demoflags & DF_FILELIST)
{
G_LoadDemoExtraFiles(&demo_p);
if (titledemo) // Titledemos should always play and ought to always be compatible with whatever wadlist is running.
G_SkipDemoExtraFiles(&demo_p);
if (demo_loadfiles)
G_LoadDemoExtraFiles(&demo_p);
else if (demo_ignorefiles)
G_SkipDemoExtraFiles(&demo_p);
else
{
UINT8 error = G_CheckDemoExtraFiles(&demo_p);
if (error)
{
switch (error)
{
case DFILE_ERROR_NOTLOADED:
snprintf(msg, 1024,
M_GetText("Required files for this demo are not loaded.\n\nUse\n\"playdemo %s -addfiles\"\nto load them and play the demo.\n"),
pdemoname);
break;
case DFILE_ERROR_OUTOFORDER:
snprintf(msg, 1024,
M_GetText("Required files for this demo are loaded out of order.\n\nUse\n\"playdemo %s -force\"\nto play the demo anyway.\n"),
pdemoname);
break;
case DFILE_ERROR_INCOMPLETEOUTOFORDER:
snprintf(msg, 1024,
M_GetText("Required files for this demo are not loaded, and some are out of order.\n\nUse\n\"playdemo %s -addfiles\"\nto load needed files and play the demo.\n"),
pdemoname);
break;
case DFILE_ERROR_CANNOTLOAD:
snprintf(msg, 1024,
M_GetText("Required files for this demo cannot be loaded.\n\nUse\n\"playdemo %s -force\"\nto play the demo anyway.\n"),
pdemoname);
break;
case DFILE_ERROR_EXTRAFILES:
snprintf(msg, 1024,
M_GetText("You have additional files loaded beyond the demo's file list.\n\nUse\n\"playdemo %s -force\"\nto play the demo anyway.\n"),
pdemoname);
break;
}
CONS_Alert(CONS_ERROR, "%s", msg);
if (!CON_Ready()) // In the console they'll just see the notice there! No point pulling them out.
M_StartMessage(msg, NULL, MM_NOTHING);
Z_Free(pdemoname);
Z_Free(demobuffer);
demoplayback = false;
titledemo = false;
return;
}
}
}
modeattacking = (demoflags & DF_ATTACKMASK)>>DF_ATTACKSHIFT;
@ -6879,7 +7015,7 @@ void G_AddGhost(char *defdemoname)
flags = READUINT8(p);
if (flags & DF_FILELIST)
{
G_LoadDemoExtraFiles(&p);
G_SkipDemoExtraFiles(&p); // Don't wanna modify the file list for ghosts.
}
if (!(flags & DF_GHOST))
{
@ -6959,6 +7095,7 @@ void G_AddGhost(char *defdemoname)
if (i == numskins)
{
//@TODO nah this should fallback
CONS_Alert(CONS_NOTICE, M_GetText("Failed to add ghost %s: Invalid character.\n"), pdemoname);
Z_Free(pdemoname);
Z_Free(buffer);

View file

@ -36,7 +36,7 @@ extern boolean playeringame[MAXPLAYERS];
// ======================================
// demoplaying back and demo recording
extern boolean demoplayback, titledemo, fromtitledemo, demorecording, timingdemo, demosaved, demodefersave;
extern boolean demoplayback, titledemo, fromtitledemo, demorecording, timingdemo, demosaved, demodefersave, demo_loadfiles, demo_ignorefiles;
extern tic_t demosavebutton;
extern consvar_t cv_recordmultiplayerdemos;

View file

@ -6897,6 +6897,7 @@ static void M_HandleStaffReplay(INT32 choice)
break;
M_ClearMenus(true);
modeattacking = ATTACKING_RECORD;
demo_loadfiles = false; demo_ignorefiles = true; // Just assume that record attack replays have the files needed
G_DoPlayDemo(va("%sS%02u",G_BuildMapName(cv_nextmap.value),cv_dummystaff.value));
break;
default:
@ -6917,6 +6918,7 @@ static void M_ReplayTimeAttack(INT32 choice)
const char *which;
M_ClearMenus(true);
modeattacking = ATTACKING_RECORD; // set modeattacking before G_DoPlayDemo so the map loader knows
demo_loadfiles = false; demo_ignorefiles = true; // Just assume that record attack replays have the files needed
if (currentMenu == &SP_ReplayDef)
{