shithub: choc

Download patch

ref: e92f889b71eddafb30e9c64b3f17b63e73d4403d
parent: 999f56818bcb45b48c22b0e21a74592ad7b80a14
author: Simon Howard <[email protected]>
date: Tue Nov 22 19:26:49 EST 2016

doom: Forbid longtics demos in WAD files.

As per reasoning on #817, we only allow longtics demos as a feature for
users to cleanly record vanilla gameplay without affecting the turning
resolution. When playing back demos, we detect the different header byte
(111) that indicates a longtics demo file and proceed accordingly.

However, we should only support such demos when they are played manually
on the command line by the user. Longtics demo playback support should
not be a feature that WAD authors can use to break from Vanilla
behavior. If such a demo is encountered inside a WAD, treat it as
Vanilla would treat it and exit accordingly.

--- a/src/doom/g_game.c
+++ b/src/doom/g_game.c
@@ -2127,6 +2127,8 @@
             return "v1.8";
         case 109:
             return "v1.9";
+        case 111:
+            return "v1.91 hack demo?";
         default:
             break;
     }
@@ -2146,27 +2148,45 @@
     }
 }
 
-void G_DoPlayDemo (void) 
-{ 
-    skill_t skill; 
-    int             i, episode, map; 
+// 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, lumpnum, episode, map;
     int demoversion;
-	 
-    gameaction = ga_nothing; 
-    demobuffer = demo_p = W_CacheLumpName (defdemoname, PU_STATIC); 
 
+    lumpnum = W_GetNumForName(defdemoname);
+    gameaction = ga_nothing;
+    demobuffer = W_CacheLumpNum(lumpnum, PU_STATIC);
+    demo_p = demobuffer;
+
     demoversion = *demo_p++;
 
-    if (demoversion == G_VanillaVersionCode())
+    longtics = false;
+
+    // Longtics demos use the modified format that is generated by cph's
+    // hacked "v1.91" doom exe. We support this format, but only if the
+    // demo is being played "manually" on the command line; such demos
+    // are forbidden inside WAD files.
+    if (IsDemoFile(lumpnum) && demoversion == DOOM_191_VERSION)
     {
-        longtics = false;
-    }
-    else if (demoversion == DOOM_191_VERSION)
-    {
-        // demo recorded with cph's modified "v1.91" doom exe
         longtics = true;
     }
-    else
+    else if (demoversion != G_VanillaVersionCode())
     {
         char *message = "Demo is from a different game version!\n"
                         "(read %i, should be %i)\n"
--- a/src/w_file.h
+++ b/src/w_file.h
@@ -28,35 +28,31 @@
 typedef struct
 {
     // Open a file for reading.
-
     wad_file_t *(*OpenFile)(char *path);
 
     // Close the specified file.
-
     void (*CloseFile)(wad_file_t *file);
 
     // Read data from the specified position in the file into the 
     // provided buffer.  Returns the number of bytes read.
-
     size_t (*Read)(wad_file_t *file, unsigned int offset,
                    void *buffer, size_t buffer_len);
-
 } wad_file_class_t;
 
 struct _wad_file_s
 {
     // Class of this file.
-
     wad_file_class_t *file_class;
 
     // If this is NULL, the file cannot be mapped into memory.  If this
     // is non-NULL, it is a pointer to the mapped file.
-
     byte *mapped;
 
     // Length of the file, in bytes.
-
     unsigned int length;
+
+    // File's location on disk.
+    const char *path;
 };
 
 // Open the specified file. Returns a pointer to a new wad_file_t 
--- a/src/w_file_posix.c
+++ b/src/w_file_posix.c
@@ -26,6 +26,7 @@
 #include <sys/mman.h>
 #include <string.h>
 
+#include "m_misc.h"
 #include "w_file.h"
 #include "z_zone.h"
 
@@ -90,6 +91,7 @@
     result = Z_Malloc(sizeof(posix_wad_file_t), PU_STATIC, 0);
     result->wad.file_class = &posix_wad_file;
     result->wad.length = GetFileLength(handle);
+    result->wad.path = M_StringDuplicate(path);
     result->handle = handle;
 
     // Try to map the file into memory with mmap:
--- a/src/w_file_stdc.c
+++ b/src/w_file_stdc.c
@@ -48,6 +48,7 @@
     result->wad.file_class = &stdc_wad_file;
     result->wad.mapped = NULL;
     result->wad.length = M_FileLength(fstream);
+    result->wad.path = M_StringDuplicate(path);
     result->fstream = fstream;
 
     return &result->wad;
--- a/src/w_file_win32.c
+++ b/src/w_file_win32.c
@@ -26,6 +26,7 @@
 #include <windows.h>
 
 #include "i_system.h"
+#include "m_misc.h"
 #include "w_file.h"
 #include "z_zone.h"
 
@@ -115,6 +116,7 @@
     result = Z_Malloc(sizeof(win32_wad_file_t), PU_STATIC, 0);
     result->wad.file_class = &win32_wad_file;
     result->wad.length = GetFileLength(handle);
+    result->wad.path = M_StringDuplicate(path);
     result->handle = handle;
 
     // Try to map the file into memory with mmap: