foxygit / doom Log in
commit 9d51e5310899f3d0fefdd36c305dfe7a6d9ef3de
Author:     Thomas A. Birkel <capnclever@gmail.com>
AuthorDate: Sat Oct 15 02:05:31 2016 -0400
Commit:     Thomas A. Birkel <capnclever@gmail.com>
CommitDate: Sat Oct 15 02:05:31 2016 -0400

    Add -demoextend parameter to improve Heretic/Hexen demo support

    Vanilla Heretic and Hexen demo support is limited to one level (quits
    after level completion) and one life (quits after player respawn). When
    -demoextend is used, these premature quits are ignored.

    Additional work on Hexen to conditionally suppress demo-related
    variable setting whenever loading a map.

    Partial implementation of #432
---
 src/heretic/d_main.c  |  9 +++++++++
 src/heretic/doomdef.h |  1 +
 src/heretic/g_game.c  |  5 +++--
 src/hexen/g_game.c    | 15 ++++++++++-----
 src/hexen/h2_main.c   |  9 +++++++++
 src/hexen/h2def.h     |  1 +
 src/hexen/mn_menu.c   | 10 ++++++++++
 7 files changed, 43 insertions(+), 7 deletions(-)

diff --git a/src/heretic/d_main.c b/src/heretic/d_main.c
index 71dc626c..f261dc5d 100644
--- a/src/heretic/d_main.c
+++ b/src/heretic/d_main.c
@@ -1039,6 +1039,15 @@ void D_DoomMain(void)

     longtics = M_CheckParm("-longtics") != 0;

+    //!
+    // @category demo
+    //
+    // Demo records and plays back without automatically quitting
+    // after level exit.
+    //
+
+    demoextend = M_CheckParm("-demoextend");
+
     if (W_CheckNumForName(DEH_String("E2M1")) == -1)
     {
         gamemode = shareware;
diff --git a/src/heretic/doomdef.h b/src/heretic/doomdef.h
index eeb91c21..2619452e 100644
--- a/src/heretic/doomdef.h
+++ b/src/heretic/doomdef.h
@@ -531,6 +531,7 @@ extern boolean lowres_turn; // Truncate angleturn in ticcmds to nearest 256.
                             // Used when recording Vanilla demos in netgames.
 extern boolean longtics;    // specifies 16-bit angleturn resolution in demos
 extern boolean demoplayback;
+extern boolean demoextend;      // allow demos to persist through exit/respawn
 extern int skytexture;

 extern gamestate_t gamestate;
diff --git a/src/heretic/g_game.c b/src/heretic/g_game.c
index 65488b7b..146dc40c 100644
--- a/src/heretic/g_game.c
+++ b/src/heretic/g_game.c
@@ -114,6 +114,7 @@ boolean longtics;
 boolean lowres_turn;
 boolean shortticfix;        // properly calculates lowres turns like in doom
 boolean demoplayback;
+boolean demoextend;
 byte *demobuffer, *demo_p, *demoend;
 boolean singledemo;             // quit after playing a demo from cmdline

@@ -1322,7 +1323,7 @@ void G_DoReborn(int playernum)
 {
     int i;

-    if (G_CheckDemoStatus())
+    if (!demoextend && G_CheckDemoStatus()) // quit demo unless -demoextend
         return;
     if (!netgame)
         gameaction = ga_loadlevel;      // reload the level from scratch
@@ -1391,7 +1392,7 @@ void G_DoCompleted(void)
     static int afterSecret[5] = { 7, 5, 5, 5, 4 };

     gameaction = ga_nothing;
-    if (G_CheckDemoStatus())
+    if (!demoextend && G_CheckDemoStatus()) // quit demo unless -demoextend
     {
         return;
     }
diff --git a/src/hexen/g_game.c b/src/hexen/g_game.c
index 906b031e..1c5c3ad6 100644
--- a/src/hexen/g_game.c
+++ b/src/hexen/g_game.c
@@ -97,6 +97,7 @@ boolean longtics;
 boolean lowres_turn;
 boolean shortticfix;        // properly calculates lowres turns like in doom
 boolean demoplayback;
+boolean demoextend;
 byte *demobuffer, *demo_p, *demoend;
 boolean singledemo;             // quit after playing a demo from cmdline

@@ -1325,7 +1326,7 @@ void G_DoReborn(int playernum)
     boolean foundSpot;
     int bestWeapon;

-    if (G_CheckDemoStatus())
+    if (!demoextend && G_CheckDemoStatus()) // quit demo unless -demoextend
     {
         return;
     }
@@ -1520,7 +1521,7 @@ void G_DoCompleted(void)
     int i;

     gameaction = ga_nothing;
-    if (G_CheckDemoStatus())
+    if (!demoextend && G_CheckDemoStatus()) // quit demo unless -demoextend
     {
         return;
     }
@@ -1771,10 +1772,14 @@ void G_InitNew(skill_t skill, int episode, int map)
     }

     // Set up a bunch of globals
-    usergame = true;            // will be set false if a demo
+    if (!demoextend) // this prevents map-loading from stopping the demo
+    {                // demoextend is set back to false only if starting a
+                     //  new game or loading a saved one during playback
+        demorecording = false;
+        demoplayback = false;
+        usergame = true;            // will be set false if a demo
+    }
     paused = false;
-    demorecording = false;
-    demoplayback = false;
     viewactive = true;
     gameepisode = episode;
     gamemap = map;
diff --git a/src/hexen/h2_main.c b/src/hexen/h2_main.c
index 1e2c0af6..98361158 100644
--- a/src/hexen/h2_main.c
+++ b/src/hexen/h2_main.c
@@ -684,6 +684,15 @@ static void HandleArgs(void)

     longtics = M_CheckParm("-longtics") != 0;

+    //!
+    // @category demo
+    //
+    // Demo records and plays back without automatically quitting
+    // after level exit.
+    //
+
+    demoextend = M_CheckParm("-demoextend");
+
     if (M_ParmExists("-testcontrols"))
     {
         autostart = true;
diff --git a/src/hexen/h2def.h b/src/hexen/h2def.h
index aa84e430..71128f91 100644
--- a/src/hexen/h2def.h
+++ b/src/hexen/h2def.h
@@ -636,6 +636,7 @@ extern boolean lowres_turn; // Truncate angleturn in ticcmds to nearest 256.
                             // Used when recording Vanilla demos in netgames.
 extern boolean longtics;    // specifies 16-bit angleturn resolution in demos
 extern boolean demoplayback;
+extern boolean demoextend;      // allow demos to persist through exit/respawn
 extern int maxzone;             // Maximum chunk allocated for zone heap

 extern int Sky1Texture;
diff --git a/src/hexen/mn_menu.c b/src/hexen/mn_menu.c
index 15170279..c6095492 100644
--- a/src/hexen/mn_menu.c
+++ b/src/hexen/mn_menu.c
@@ -130,6 +130,7 @@ boolean MenuActive;
 int InfoType;
 int messageson = true;
 boolean mn_SuicideConsole;
+boolean demoextend; // from h2def.h

 // PRIVATE DATA DEFINITIONS ------------------------------------------------

@@ -895,6 +896,10 @@ static void SCNetCheck2(int option)

 static void SCLoadGame(int option)
 {
+    if (demoplayback)
+    {
+        demoextend = false;
+    }
     if (!SlotStatus[option])
     {                           // Don't try to load from an empty slot
         return;
@@ -1003,6 +1008,11 @@ static void SCClass(int option)

 static void SCSkill(int option)
 {
+    if (demoplayback)
+    {
+        demoextend = false;
+    }
+
     PlayerClass[consoleplayer] = MenuPClass;
     G_DeferredNewGame(option);
     SB_SetClassData();