foxygit / doom Log in
commit afccf65a4e492befad0a0e6ba311fc1aa7659cc2
Author:     Thomas A. Birkel <capnclever@gmail.com>
AuthorDate: Fri Oct 14 20:45:27 2016 -0400
Commit:     Thomas A. Birkel <capnclever@gmail.com>
CommitDate: Fri Oct 14 20:45:27 2016 -0400

    g_game.c: Add -maxdemo parameter to Heretic/Hexen

    Works the same as in Doom: demo file is limited to the number of KBs
    specified by the argument used in conjunction with the parameter.
    Included a check on demo size to avoid memory corruption.

    Partial implementation of #432
---
 src/heretic/g_game.c | 30 ++++++++++++++++++++++++++++--
 src/hexen/g_game.c   | 31 +++++++++++++++++++++++++++++--
 2 files changed, 57 insertions(+), 4 deletions(-)

diff --git a/src/heretic/g_game.c b/src/heretic/g_game.c
index cc18e49d..1b6a951a 100644
--- a/src/heretic/g_game.c
+++ b/src/heretic/g_game.c
@@ -24,6 +24,7 @@
 #include "deh_str.h"
 #include "i_timer.h"
 #include "i_system.h"
+#include "m_argv.h"
 #include "m_controls.h"
 #include "m_misc.h"
 #include "m_random.h"
@@ -110,7 +111,7 @@ int mouseSensitivity;
 char demoname[32];
 boolean demorecording;
 boolean demoplayback;
-byte *demobuffer, *demo_p;
+byte *demobuffer, *demo_p, *demoend;
 boolean singledemo;             // quit after playing a demo from cmdline

 boolean precache = true;        // if true, load all graphics at start
@@ -1646,6 +1647,14 @@ void G_WriteDemoTiccmd(ticcmd_t * cmd)
     *demo_p++ = cmd->lookfly;
     *demo_p++ = cmd->arti;
     demo_p -= 6;
+
+    if (demo_p > demoend - 16)
+    {
+        // no more space
+        G_CheckDemoStatus();
+        return;
+    }
+
     G_ReadDemoTiccmd(cmd);      // make SURE it is exactly the same
 }

@@ -1663,12 +1672,29 @@ void G_RecordDemo(skill_t skill, int numplayers, int episode, int map,
                   char *name)
 {
     int i;
+    int maxsize;

     G_InitNew(skill, episode, map);
     usergame = false;
     M_StringCopy(demoname, name, sizeof(demoname));
     M_StringConcat(demoname, ".lmp", sizeof(demoname));
-    demobuffer = demo_p = Z_Malloc(0x20000, PU_STATIC, NULL);
+    maxsize = 0x20000;
+
+    //!
+    // @arg <size>
+    // @category demo
+    // @vanilla
+    //
+    // Specify the demo buffer size (KiB)
+    //
+
+    i = M_CheckParmWithArgs("-maxdemo", 1);
+    if (i)
+        maxsize = atoi(myargv[i + 1]) * 1024;
+    demobuffer = Z_Malloc(maxsize, PU_STATIC, NULL);
+    demoend = demobuffer + maxsize;
+
+    demo_p = demobuffer;
     *demo_p++ = skill;
     *demo_p++ = episode;
     *demo_p++ = map;
diff --git a/src/hexen/g_game.c b/src/hexen/g_game.c
index 60c616fd..bda707d1 100644
--- a/src/hexen/g_game.c
+++ b/src/hexen/g_game.c
@@ -23,6 +23,7 @@
 #include "i_video.h"
 #include "i_system.h"
 #include "i_timer.h"
+#include "m_argv.h"
 #include "m_controls.h"
 #include "m_misc.h"
 #include "p_local.h"
@@ -93,7 +94,7 @@ int levelstarttic;              // gametic at level start
 char demoname[32];
 boolean demorecording;
 boolean demoplayback;
-byte *demobuffer, *demo_p;
+byte *demobuffer, *demo_p, *demoend;
 boolean singledemo;             // quit after playing a demo from cmdline

 boolean precache = true;        // if true, load all graphics at start
@@ -1798,6 +1799,14 @@ void G_WriteDemoTiccmd(ticcmd_t * cmd)
     *demo_p++ = cmd->lookfly;
     *demo_p++ = cmd->arti;
     demo_p -= 6;
+
+    if (demo_p > demoend - 16)
+    {
+        // no more space
+        G_CheckDemoStatus();
+        return;
+    }
+
     G_ReadDemoTiccmd(cmd);      // make SURE it is exactly the same
 }

@@ -1815,12 +1824,29 @@ void G_RecordDemo(skill_t skill, int numplayers, int episode, int map,
                   char *name)
 {
     int i;
+    int maxsize;

     G_InitNew(skill, episode, map);
     usergame = false;
     M_StringCopy(demoname, name, sizeof(demoname));
     M_StringConcat(demoname, ".lmp", sizeof(demoname));
-    demobuffer = demo_p = Z_Malloc(0x20000, PU_STATIC, NULL);
+    maxsize = 0x20000;
+
+    //!
+    // @arg <size>
+    // @category demo
+    // @vanilla
+    //
+    // Specify the demo buffer size (KiB)
+    //
+
+    i = M_CheckParmWithArgs("-maxdemo", 1);
+    if (i)
+        maxsize = atoi(myargv[i + 1]) * 1024;
+    demobuffer = Z_Malloc(maxsize, PU_STATIC, NULL);
+    demoend = demobuffer + maxsize;
+
+    demo_p = demobuffer;
     *demo_p++ = skill;
     *demo_p++ = episode;
     *demo_p++ = map;
@@ -1830,6 +1856,7 @@ void G_RecordDemo(skill_t skill, int numplayers, int episode, int map,
         *demo_p++ = playeringame[i];
         *demo_p++ = PlayerClass[i];
     }
+
     demorecording = true;
 }