foxygit / doom Log in
commit 0ddec90148097c0ee1a456c56427b1a9c2715872
Author:     NY00123 <ny00@outlook.com>
AuthorDate: Tue Sep 28 23:55:30 2021 +0300
Commit:     NY00123 <ny00@outlook.com>
CommitDate: Thu Sep 29 21:17:36 2022 +0300

    hexen: Add -gameversion, accepting 1.1 and 1.1r2 as possible values.

    This is mostly based on code previously added for Doom. The main change
    is that the behaviors of two variations of Hexen v1.1 are now covered.
    They differ by the presence of a bugfix in A_SoAExplode, observed in DK
    with -nomonsters. There is also an adjustment of HEXEN_VERSIONTEXT.

    These changes are otherwise separate from support for the demo
    version's IWAD, for which no separate game version was added.
    As with Doom, the emulated version, 'Hexen 1.1' or
    'Hexen 1.1 (alt)', is now printed on startup.
---
 src/d_mode.c         |  1 +
 src/d_mode.h         |  1 +
 src/hexen/a_action.c |  4 +--
 src/hexen/h2_main.c  | 79 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/hexen/h2def.h    |  6 ++--
 5 files changed, 86 insertions(+), 5 deletions(-)

diff --git a/src/d_mode.c b/src/d_mode.c
index 26625ec4..073ab21c 100644
--- a/src/d_mode.c
+++ b/src/d_mode.c
@@ -132,6 +132,7 @@ static struct {
     { doom,     exe_chex },
     { heretic,  exe_heretic_1_3 },
     { hexen,    exe_hexen_1_1 },
+    { hexen,    exe_hexen_1_1r2 },
     { strife,   exe_strife_1_2 },
     { strife,   exe_strife_1_31 },
 };
diff --git a/src/d_mode.h b/src/d_mode.h
index a3b627ce..5f0735c7 100644
--- a/src/d_mode.h
+++ b/src/d_mode.h
@@ -71,6 +71,7 @@ typedef enum
     exe_heretic_1_3, // Heretic 1.3

     exe_hexen_1_1,   // Hexen 1.1
+    exe_hexen_1_1r2, // Hexen 1.1 (alternate exe)
     exe_strife_1_2,  // Strife v1.2
     exe_strife_1_31  // Strife v1.31
 } GameVersion_t;
diff --git a/src/hexen/a_action.c b/src/hexen/a_action.c
index bb007953..16da96da 100644
--- a/src/hexen/a_action.c
+++ b/src/hexen/a_action.c
@@ -1177,11 +1177,9 @@ void A_SoAExplode(mobj_t * actor)
     }
     if (actor->args[0])
     {                           // Spawn an item
-#if 0 // Checks are not present in version 1.1
-        if (!nomonsters
+        if ((gameversion != exe_hexen_1_1r2) || !nomonsters
             || !(mobjinfo[TranslateThingType[actor->args[0]]].
                  flags & MF_COUNTKILL))
-#endif
         {                       // Only spawn monsters if not -nomonsters
             P_SpawnMobj(actor->x, actor->y, actor->z,
                         TranslateThingType[actor->args[0]]);
diff --git a/src/hexen/h2_main.c b/src/hexen/h2_main.c
index b58a8058..6397bdc1 100644
--- a/src/hexen/h2_main.c
+++ b/src/hexen/h2_main.c
@@ -95,6 +95,7 @@ extern boolean askforquit;
 // PUBLIC DATA DEFINITIONS -------------------------------------------------

 GameMode_t gamemode;
+GameVersion_t gameversion = exe_hexen_1_1;
 static const char *gamedescription;
 char *iwadfile;
 static char demolumpname[9];    // Demo lump to start playing.
@@ -357,6 +358,81 @@ void D_SetGameDescription(void)
     }
 }

+static struct
+{
+    const char *description;
+    const char *cmdline;
+    GameVersion_t version;
+} gameversions[] = {
+    {"Hexen 1.1",            "1.1",        exe_hexen_1_1},
+    {"Hexen 1.1 (alt)",      "1.1r2",      exe_hexen_1_1r2},
+    { NULL,                  NULL,         0},
+};
+
+// Initialize the game version
+
+static void InitGameVersion(void)
+{
+    int p;
+    int i;
+
+    //!
+    // @arg <version>
+    // @category compat
+    //
+    // Emulate a specific version of Hexen.
+    // Valid values are "1.1" and "1.1r2".
+    //
+
+    p = M_CheckParmWithArgs("-gameversion", 1);
+
+    if (p)
+    {
+        for (i=0; gameversions[i].description != NULL; ++i)
+        {
+            if (!strcmp(myargv[p+1], gameversions[i].cmdline))
+            {
+                gameversion = gameversions[i].version;
+                break;
+            }
+        }
+
+        if (gameversions[i].description == NULL)
+        {
+            printf("Supported game versions:\n");
+
+            for (i=0; gameversions[i].description != NULL; ++i)
+            {
+                printf("\t%s (%s)\n", gameversions[i].cmdline,
+                        gameversions[i].description);
+            }
+
+            I_Error("Unknown game version '%s'", myargv[p+1]);
+        }
+    }
+    else
+    {
+        // Determine automatically
+
+        gameversion = exe_hexen_1_1;
+    }
+}
+
+void PrintGameVersion(void)
+{
+    int i;
+
+    for (i=0; gameversions[i].description != NULL; ++i)
+    {
+        if (gameversions[i].version == gameversion)
+        {
+            printf("Emulating the behavior of the "
+                   "'%s' executable.\n", gameversions[i].description);
+            break;
+        }
+    }
+}
+
 //==========================================================================
 //
 // H2_Main
@@ -438,6 +514,7 @@ void D_DoomMain(void)
     D_AddFile(iwadfile);
     W_CheckCorrectIWAD(hexen);
     D_IdentifyVersion();
+    InitGameVersion();
     D_SetGameDescription();
     AdjustForMacIWAD();

@@ -513,6 +590,8 @@ void D_DoomMain(void)
     ST_Message("D_CheckNetGame: Checking network game status.\n");
     D_CheckNetGame();

+    PrintGameVersion();
+
     ST_Message("SB_Init: Loading patches.\n");
     SB_Init();

diff --git a/src/hexen/h2def.h b/src/hexen/h2def.h
index 161903d3..cf3a7b95 100644
--- a/src/hexen/h2def.h
+++ b/src/hexen/h2def.h
@@ -73,8 +73,9 @@
 //#endif
 #define HEXEN_VERSIONTEXT ((gamemode == shareware) ? \
                            "DEMO 10 16 95" : \
-                           "VERSION 1.1 MAR 12 1996 (CBI)" \
-                           /*"VERSION 1.1 MAR 22 1996 (BCP)"*/)
+                           (gameversion != exe_hexen_1_1r2) ? \
+                           "VERSION 1.1 MAR 12 1996 (CBI)" : \
+                           "VERSION 1.1 MAR 22 1996 (BCP)")

 // all exterior data is defined here
 #include "xddefs.h"
@@ -589,6 +590,7 @@ void NET_SendFrags(player_t * player);
 #define TELEFOGHEIGHT (32*FRACUNIT)

 extern GameMode_t gamemode;
+extern GameVersion_t gameversion;

 extern gameaction_t gameaction;