umapinfo: implement demo extension (#224)

This commit is contained in:
Roman Fomin 2021-06-17 13:48:55 +07:00 committed by GitHub
parent 943918030b
commit 412eb1ea6b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 138 additions and 5 deletions

View File

@ -121,6 +121,8 @@ boolean singletics = false; // debug flag to cancel adaptiveness
boolean nosfxparm;
boolean nomusicparm;
boolean umapinfo_loaded = false;
//jff 4/18/98
extern boolean inhelpscreens;
@ -1639,7 +1641,10 @@ static void D_ProcessUMInWad(int i)
D_ProcessUMInWad(lumpinfo[i].next);
if (!strncasecmp(lumpinfo[i].name, "umapinfo", 8) &&
lumpinfo[i].namespace == ns_global)
U_ParseMapInfo((const char *)W_CacheLumpNum(i, PU_CACHE), W_LumpLength(i));
{
U_ParseMapInfo((const char *)W_CacheLumpNum(i, PU_CACHE), W_LumpLength(i));
umapinfo_loaded = true;
}
}
}

View File

@ -53,6 +53,8 @@ extern boolean pistolstart;
extern boolean nosfxparm;
extern boolean nomusicparm;
extern boolean umapinfo_loaded;
// Called by IO functions when input is detected.
void D_PostEvent(event_t* ev);

View File

@ -1253,12 +1253,78 @@ static void G_DoPlayDemo(void)
return;
}
// ano - jun2019
// so the format is
// demover byte == 255
// "PR+UM" signature (w/ ending null terminator)
// extension_version byte. for now this should always be "1"
// 2 bytes for num_extensions (little-endian)
// num_extensions *
// 1 byte string length
// and length chars (up to 65535 obviously)
// note that the format has each length by each string
// as opposed to a table of lengths
// an example extensions string is "UMAPINFO".
// then finally the "real" demover byte is present here
demover = *demo_p++;
if (demover == 255)
{
boolean using_umapinfo = false;
int extension_version = -1;
int num_extensions;
// we check for the PR+UM signature as mentioned.
// Eternity Engine also uses 255 demover, with other signatures.
if (strncmp((const char *)demo_p, "PR+UM", 5) != 0)
{
I_Error("G_DoPlayDemo: Extended demo format 255 found, but \"PR+UM\" string not found.");
}
demo_p += 6;
extension_version = *demo_p++;
if (extension_version != 1)
{
I_Error("G_DoPlayDemo: Extended demo format version %d unrecognized.", extension_version);
}
num_extensions = *demo_p++;
num_extensions |= ((unsigned int)(*demo_p++)) << 8;
for (i = 0; i < num_extensions; i++)
{
int r_len = *demo_p++;
// ano - jun2019 - when more potential extension strings get added,
// this section can become more complex
if (r_len == 8 && strncmp((const char *)demo_p, "UMAPINFO", 8) == 0)
{
using_umapinfo = true;
}
else
{
I_Error("G_DoPlayDemo: Extended demo format extension unrecognized.");
}
demo_p += r_len;
}
// skip map name
if (using_umapinfo)
{
demo_p += 8;
}
// ano - jun2019 - this is to support other demovers effectively?
// while still having the extended features
demover = *demo_p++;
}
// killough 2/22/98, 2/28/98: autodetect old demos and act accordingly.
// Old demos turn on demo_compatibility => compatibility; new demos load
// compatibility flag, and other flags as well, as a part of the demo.
demo_version = // killough 7/19/98: use the version id stored in demo
demover = *demo_p++;
demo_version = demover; // killough 7/19/98: use the version id stored in demo
// [FG] PrBoom's own demo format starts with demo version 210
if (demover >= 210 && demover != MBF21VERSION)
@ -3025,6 +3091,68 @@ void G_BeginRecording(void)
demo_p = demobuffer;
if (umapinfo_loaded)
{
int num_extensions = 1;
char mapname[9] = {0};
// demover
*demo_p++ = 0xFF;
// signature
*demo_p++ = 'P';
*demo_p++ = 'R';
*demo_p++ = '+';
*demo_p++ = 'U';
*demo_p++ = 'M';
*demo_p++ = '\0';
// extension version
*demo_p++ = 1;
//
*demo_p++ = num_extensions & 0xff;
*demo_p++ = (num_extensions >> 8) & 0xff;
// ano - note that the format has each length by each string
// as opposed to a table of lengths
*demo_p++ = 0x08;
*demo_p++ = 'U';
*demo_p++ = 'M';
*demo_p++ = 'A';
*demo_p++ = 'P';
*demo_p++ = 'I';
*demo_p++ = 'N';
*demo_p++ = 'F';
*demo_p++ = 'O';
// ano - to properly extend this to support other extension strings
// we wouldn't just plop this here, but right now we only support the 1
// in the future, we should assume that chunks in the header should
// follow the order of their appearance in the extensions table.
// [XA] get the map name from gamemapinfo if the
// starting map has a UMAPINFO definition. if not,
// fall back to the usual MAPxx/ExMy default.
if (gamemapinfo)
{
strncpy(mapname, gamemapinfo->mapname, 8);
}
else if(gamemode == commercial)
{
snprintf(mapname, 9, "MAP%02d", gamemap);
}
else
{
snprintf(mapname, 9, "E%dM%d", gameepisode, gamemap);
}
for (i = 0; i < 8; i++)
{
// FIXME - the toupper is a hacky workaround for the case insensitivity
// in the current UMAPINFO reader. lump names should probably not be
// lowercase ever (?)
*demo_p++ = toupper(mapname[i]);
}
}
// ano - done with the extension format!
if (complevel == MBFVERSION || complevel == MBF21VERSION)
{
if (complevel == MBF21VERSION)
@ -3051,8 +3179,6 @@ void G_BeginRecording(void)
*demo_p++ = compatibility; // killough 2/22/98
}
demo_version = complevel;
*demo_p++ = gameskill;
*demo_p++ = gameepisode;
*demo_p++ = gamemap;