ref: 89fc8d89919ef71fd2d6030e9cf931630bcd4529
parent: e92f889b71eddafb30e9c64b3f17b63e73d4403d
author: Simon Howard <fraggle@soulsphere.org>
date: Tue Nov 22 19:38:01 EST 2016
heretic: Forbid vvHeretic options in WAD files. As with the Doom v1.91 format, parsing of vvHeretic extension bits is a convenience for demo playback purposes and not intended as an editing feature. If a demo with such bits set is found inside a WAD file, we ignore them as Vanilla Heretic would do. Part of #817.
--- a/src/heretic/g_game.c
+++ b/src/heretic/g_game.c
@@ -1873,23 +1873,49 @@
gameaction = ga_playdemo;
}
+// Returns true if the given lump number corresponds to data from a .lmp
+// file, as opposed to a WAD.
+static boolean IsDemoFile(int lumpnum)
+{
+ char *lower;
+ boolean result;
+
+ lower = M_StringDuplicate(lumpinfo[lumpnum]->wad_file->path);
+ M_ForceLowercase(lower);
+ result = M_StringEndsWith(lower, ".lmp");
+ free(lower);
+
+ return result;
+}
+
void G_DoPlayDemo(void)
{
skill_t skill;
- int i, episode, map;
+ int i, lumpnum, episode, map;
gameaction = ga_nothing;
- demobuffer = demo_p = W_CacheLumpName(defdemoname, PU_STATIC);
+ lumpnum = W_GetNumForName(defdemoname);
+ demobuffer = W_CacheLumpNum(lumpnum, PU_STATIC);
+ demo_p = demobuffer;
skill = *demo_p++;
episode = *demo_p++;
map = *demo_p++;
- // Read special parameter bits: see G_RecordDemo() for details.
- longtics = (*demo_p & DEMOHEADER_LONGTICS) != 0;
+ // vvHeretic allows extra options to be stored in the upper bits of
+ // the player 1 present byte. However, only recognize these bits if
+ // they are in a demo file being played manually by the user; we
+ // ignore them (as is Vanilla behavior) if they are inside a WAD file.
+ // These extra bits are a convenience feature for demo playback, not
+ // an editing extension for WAD authors.
+ if (IsDemoFile(lumpnum))
+ {
+ // Read special parameter bits: see G_RecordDemo() for details.
+ longtics = (*demo_p & DEMOHEADER_LONGTICS) != 0;
- // don't overwrite arguments from the command line
- respawnparm |= (*demo_p & DEMOHEADER_RESPAWN) != 0;
- nomonsters |= (*demo_p & DEMOHEADER_NOMONSTERS) != 0;
+ // don't overwrite arguments from the command line
+ respawnparm |= (*demo_p & DEMOHEADER_RESPAWN) != 0;
+ nomonsters |= (*demo_p & DEMOHEADER_NOMONSTERS) != 0;
+ }
for (i = 0; i < MAXPLAYERS; i++)
playeringame[i] = (*demo_p++) != 0;