From b1c1256891ca6209f52cbb0bc64d0b1902c6469f Mon Sep 17 00:00:00 2001 From: Fabian Greffrath Date: Mon, 27 Mar 2023 15:19:16 +0200 Subject: [PATCH] check if drag-n-dropped .lmp files could be demo lumps (#960) and pass them to the -playdemo parameter if appropriate. --- src/d_main.c | 107 ++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 102 insertions(+), 5 deletions(-) diff --git a/src/d_main.c b/src/d_main.c index 2634d5e6..82f86231 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -1223,14 +1223,91 @@ enum FILETYPE_IWAD = 0x2, FILETYPE_PWAD = 0x4, FILETYPE_DEH = 0x8, + FILETYPE_DEMO = 0x10, }; +static boolean FileIsDemoLump(const char *filename) +{ + FILE *handle; + int count, ver; + byte buf[32], *p = buf; + + handle = M_fopen(filename, "rb"); + + if (handle == NULL) + { + return false; + } + + count = fread(buf, 1, sizeof(buf), handle); + fclose(handle); + + if (count != sizeof(buf)) + { + return false; + } + + ver = *p++; + + if (ver == 255) // skip UMAPINFO demo header + { + p += 26; + ver = *p++; + } + + if (ver >= 0 && ver <= 4) // v1.0/v1.1/v1.2 + { + p--; + } + else + { + switch (ver) + { + case 104: // v1.4 + case 105: // v1.5 + case 106: // v1.6/v1.666 + case 107: // v1.7/v1.7a + case 108: // v1.8 + case 109: // v1.9 + case 111: // v1.91 hack + break; + case 200: // Boom + case 201: + case 202: + case 203: // MBF + p += 7; // skip signature and compatibility flag + break; + case 221: // MBF21 + p += 6; // skip signature + break; + default: + return false; + break; + } + } + + if (*p++ > 5) // skill + { + return false; + } + if (*p++ > 9) // episode + { + return false; + } + if (*p++ > 99) // map + { + return false; + } + + return true; +} + static int GuessFileType(const char *name) { int ret = FILETYPE_UNKNOWN; const char *base; char *lower; - static boolean iwad_found = false; + static boolean iwad_found = false, demo_found = false; base = M_BaseName(name); lower = M_StringDuplicate(base); @@ -1244,11 +1321,24 @@ static int GuessFileType(const char *name) iwad_found = true; } else if (M_StringEndsWith(lower, ".wad") || - M_StringEndsWith(lower, ".lmp") || M_StringEndsWith(lower, ".zip")) { ret = FILETYPE_PWAD; } + else if (M_StringEndsWith(lower, ".lmp")) + { + // only ever add one argument to the -playdemo parameter + + if (demo_found == false && FileIsDemoLump(name)) + { + ret = FILETYPE_DEMO; + demo_found = true; + } + else + { + ret = FILETYPE_PWAD; + } + } else if (M_StringEndsWith(lower, ".deh") || M_StringEndsWith(lower, ".bex")) { @@ -1287,10 +1377,11 @@ static void M_AddLooseFiles(void) return; } - // allocate space for up to three additional regular parameters + // allocate space for up to four additional regular parameters + // (-iwad, -merge, -deh, -playdemo) - arguments = malloc((myargc + 3) * sizeof(*arguments)); - memset(arguments, 0, (myargc + 3) * sizeof(*arguments)); + arguments = malloc((myargc + 4) * sizeof(*arguments)); + memset(arguments, 0, (myargc + 4) * sizeof(*arguments)); // check the command line and make sure it does not already // contain any regular parameters or response files @@ -1340,6 +1431,12 @@ static void M_AddLooseFiles(void) arguments[myargc].type = FILETYPE_DEH - 1; myargc++; } + if (types & FILETYPE_DEMO) + { + arguments[myargc].str = M_StringDuplicate("-playdemo"); + arguments[myargc].type = FILETYPE_DEMO - 1; + myargc++; + } newargv = malloc(myargc * sizeof(*newargv));