foxygit / doom Log in
commit 9eae89d3eb668df2ea218f3944d12996e3364000
Author:     James Canete <SmileTheory@gmail.com>
AuthorDate: Sun Oct 13 12:46:28 2019 -0700
Commit:     James Canete <SmileTheory@gmail.com>
CommitDate: Sun Oct 13 12:46:28 2019 -0700

    Doom 1.2 demo support

    Mostly cribbed from prboom-plus
---
 src/doom/d_main.c   |  7 +++++++
 src/doom/g_game.c   | 49 +++++++++++++++++++++++++++++++++++--------------
 src/doom/m_menu.c   |  2 +-
 src/doom/p_enemy.c  | 29 ++++++++++++++++++++++-------
 src/doom/p_floor.c  |  3 ++-
 src/doom/p_inter.c  |  4 ++--
 src/doom/p_map.c    |  3 ++-
 src/doom/p_sight.c  | 47 ++++++++++++++++++++++++++++++++++++++++++++++-
 src/doom/p_spec.c   | 45 +++++++++++++++++++++++++++++----------------
 src/doom/s_sound.c  | 37 ++++++++++++++++++++++++++++++++++++-
 src/doom/st_lib.c   |  7 +++++--
 src/doom/st_stuff.c | 18 +++++++++++++++++-
 src/doom/wi_stuff.c |  7 +++++--
 13 files changed, 209 insertions(+), 49 deletions(-)

diff --git a/src/doom/d_main.c b/src/doom/d_main.c
index a060193a..bf42575d 100644
--- a/src/doom/d_main.c
+++ b/src/doom/d_main.c
@@ -1051,6 +1051,13 @@ static void InitGameVersion(void)
                     status = true;
                     switch (demoversion)
                     {
+                        case 0:
+                        case 1:
+                        case 2:
+                        case 3:
+                        case 4:
+                            gameversion = exe_doom_1_2;
+                            break;
                         case 106:
                             gameversion = exe_doom_1_666;
                             break;
diff --git a/src/doom/g_game.c b/src/doom/g_game.c
index 9cabfaf8..4420f655 100644
--- a/src/doom/g_game.c
+++ b/src/doom/g_game.c
@@ -2053,7 +2053,7 @@ int G_VanillaVersionCode(void)
     switch (gameversion)
     {
         case exe_doom_1_2:
-            I_Error("Doom 1.2 does not have a version code!");
+            return 102;
         case exe_doom_1_666:
             return 106;
         case exe_doom_1_7:
@@ -2088,7 +2088,7 @@ void G_BeginRecording (void)
     {
         *demo_p++ = DOOM_191_VERSION;
     }
-    else
+    else if (gameversion != exe_doom_1_2)
     {
         *demo_p++ = G_VanillaVersionCode();
     }
@@ -2096,11 +2096,14 @@ void G_BeginRecording (void)
     *demo_p++ = gameskill;
     *demo_p++ = gameepisode;
     *demo_p++ = gamemap;
-    *demo_p++ = deathmatch;
-    *demo_p++ = respawnparm;
-    *demo_p++ = fastparm;
-    *demo_p++ = nomonsters;
-    *demo_p++ = consoleplayer;
+    if (longtics || gameversion != exe_doom_1_2)
+    {
+        *demo_p++ = deathmatch;
+        *demo_p++ = respawnparm;
+        *demo_p++ = fastparm;
+        *demo_p++ = nomonsters;
+        *demo_p++ = consoleplayer;
+    }

     for (i=0 ; i<MAXPLAYERS ; i++)
 	*demo_p++ = playeringame[i];
@@ -2148,7 +2151,7 @@ static const char *DemoVersionDescription(int version)
     // Unknown version.  Perhaps this is a pre-v1.4 IWAD?  If the version
     // byte is in the range 0-4 then it can be a v1.0-v1.2 demo.

-    if (version >= 0 && version <= 4)
+    if (version == 102 || (version >= 0 && version <= 4))
     {
         return "v1.0/v1.1/v1.2";
     }
@@ -2173,6 +2176,12 @@ void G_DoPlayDemo (void)

     demoversion = *demo_p++;

+    if (demoversion < 102)
+    {
+        demoversion = 102;
+        demo_p--;
+    }
+
     longtics = false;

     // Longtics demos use the modified format that is generated by cph's
@@ -2200,12 +2209,24 @@ void G_DoPlayDemo (void)
     skill = *demo_p++;
     episode = *demo_p++;
     map = *demo_p++;
-    deathmatch = *demo_p++;
-    respawnparm = *demo_p++;
-    fastparm = *demo_p++;
-    nomonsters = *demo_p++;
-    consoleplayer = *demo_p++;
-
+    if (demoversion != 102)
+    {
+        deathmatch = *demo_p++;
+        respawnparm = *demo_p++;
+        fastparm = *demo_p++;
+        nomonsters = *demo_p++;
+        consoleplayer = *demo_p++;
+    }
+    else
+    {
+        deathmatch = 0;
+        respawnparm = 0;
+        fastparm = 0;
+        nomonsters = 0;
+        consoleplayer = 0;
+    }
+
+
     for (i=0 ; i<MAXPLAYERS ; i++)
 	playeringame[i] = *demo_p++;

diff --git a/src/doom/m_menu.c b/src/doom/m_menu.c
index 859b096a..0da4869b 100644
--- a/src/doom/m_menu.c
+++ b/src/doom/m_menu.c
@@ -2006,7 +2006,7 @@ void M_Drawer (void)
     {
         name = DEH_String(currentMenu->menuitems[i].name);

-	if (name[0])
+	if (name[0] && W_CheckNumForName(name) > 0)
 	{
 	    V_DrawPatchDirect (x, y, W_CacheLumpName(name, PU_CACHE));
 	}
diff --git a/src/doom/p_enemy.c b/src/doom/p_enemy.c
index 1f48fe90..ca395310 100644
--- a/src/doom/p_enemy.c
+++ b/src/doom/p_enemy.c
@@ -168,6 +168,7 @@ boolean P_CheckMeleeRange (mobj_t*	actor)
 {
     mobj_t*	pl;
     fixed_t	dist;
+    fixed_t range;

     if (!actor->target)
 	return false;
@@ -175,8 +176,14 @@ boolean P_CheckMeleeRange (mobj_t*	actor)
     pl = actor->target;
     dist = P_AproxDistance (pl->x-actor->x, pl->y-actor->y);

-    if (dist >= MELEERANGE-20*FRACUNIT+pl->info->radius)
-	return false;
+    if (gameversion == exe_doom_1_2)
+        range = MELEERANGE;
+    else
+        range = MELEERANGE-20*FRACUNIT+pl->info->radius;
+
+    if (dist >= range)
+        return false;
+

     if (! P_CheckSight (actor, actor->target) )
 	return false;
@@ -665,8 +672,8 @@ void A_Chase (mobj_t*	actor)
     // modify target threshold
     if  (actor->threshold)
     {
-	if (!actor->target
-	    || actor->target->health <= 0)
+        if (gameversion != exe_doom_1_2 &&
+            (!actor->target || actor->target->health <= 0))
 	{
 	    actor->threshold = 0;
 	}
@@ -925,11 +932,19 @@ void A_SargAttack (mobj_t* actor)
 	return;

     A_FaceTarget (actor);
-    if (P_CheckMeleeRange (actor))
+
+    if (gameversion != exe_doom_1_2)
     {
-	damage = ((P_Random()%10)+1)*4;
-	P_DamageMobj (actor->target, actor, actor, damage);
+        if (!P_CheckMeleeRange (actor))
+            return;
     }
+
+    damage = ((P_Random()%10)+1)*4;
+
+    if (gameversion == exe_doom_1_2)
+        P_LineAttack(actor, actor->angle, MELEERANGE, 0, damage);
+    else
+        P_DamageMobj (actor->target, actor, actor, damage);
 }

 void A_HeadAttack (mobj_t* actor)
diff --git a/src/doom/p_floor.c b/src/doom/p_floor.c
index 9468ed2a..0e539bfc 100644
--- a/src/doom/p_floor.c
+++ b/src/doom/p_floor.c
@@ -303,7 +303,8 @@ EV_DoFloor
 	    floor->speed = FLOORSPEED * 4;
 	    floor->floordestheight =
 		P_FindHighestFloorSurrounding(sec);
-	    if (floor->floordestheight != sec->floorheight)
+	    if (gameversion == exe_doom_1_2 ||
+	        floor->floordestheight != sec->floorheight)
 		floor->floordestheight += 8*FRACUNIT;
 	    break;

diff --git a/src/doom/p_inter.c b/src/doom/p_inter.c
index 633408fe..744dabbb 100644
--- a/src/doom/p_inter.c
+++ b/src/doom/p_inter.c
@@ -382,7 +382,7 @@ P_TouchSpecialThing

       case SPR_BON2:
 	player->armorpoints++;		// can go over 100%
-	if (player->armorpoints > deh_max_armor)
+	if (player->armorpoints > deh_max_armor && gameversion != exe_doom_1_2)
 	    player->armorpoints = deh_max_armor;
         // deh_green_armor_class only applies to the green armor shirt;
         // for the armor helmets, armortype 1 is always used.
@@ -907,7 +907,7 @@ P_DamageMobj
     target->reactiontime = 0;		// we're awake now...

     if ( (!target->threshold || target->type == MT_VILE)
-	 && source && source != target
+	 && source && (source != target || gameversion == exe_doom_1_2)
 	 && source->type != MT_VILE)
     {
 	// if not intent on another player,
diff --git a/src/doom/p_map.c b/src/doom/p_map.c
index 005a8155..bfb25149 100644
--- a/src/doom/p_map.c
+++ b/src/doom/p_map.c
@@ -1317,7 +1317,8 @@ boolean PIT_ChangeSector (mobj_t*	thing)
     {
 	P_SetMobjState (thing, S_GIBS);

-	thing->flags &= ~MF_SOLID;
+    if (gameversion != exe_doom_1_2)
+	    thing->flags &= ~MF_SOLID;
 	thing->height = 0;
 	thing->radius = 0;

diff --git a/src/doom/p_sight.c b/src/doom/p_sight.c
index 48ba6838..867c86a9 100644
--- a/src/doom/p_sight.c
+++ b/src/doom/p_sight.c
@@ -16,9 +16,10 @@
 //	LineOfSight/Visibility checks, uses REJECT Lookup Table.
 //

-
+#include <stdlib.h> // abs()

 #include "doomdef.h"
+#include "doomstat.h"

 #include "i_system.h"
 #include "p_local.h"
@@ -40,6 +41,44 @@ fixed_t		t2y;
 int		sightcounts[2];


+// PTR_SightTraverse() for Doom 1.2 sight calculations
+// taken from prboom-plus/src/p_sight.c:69-102
+boolean PTR_SightTraverse(intercept_t *in)
+{
+  line_t *li;
+  fixed_t slope;
+
+  li = in->d.line;
+
+  //
+  // crosses a two sided line
+  //
+  P_LineOpening(li);
+
+  if (openbottom >= opentop)  // quick test for totally closed doors
+    return false;  // stop
+
+  if (li->frontsector->floorheight != li->backsector->floorheight)
+  {
+    slope = FixedDiv(openbottom - sightzstart , in->frac);
+    if (slope > bottomslope)
+      bottomslope = slope;
+  }
+
+  if (li->frontsector->ceilingheight != li->backsector->ceilingheight)
+  {
+    slope = FixedDiv(opentop - sightzstart, in->frac);
+    if (slope < topslope)
+      topslope = slope;
+  }
+
+  if (topslope <= bottomslope)
+    return false;  // stop
+
+  return true;  // keep going
+}
+
+
 //
 // P_DivlineSide
 // Returns side 0 (front), 1 (back), or 2 (on).
@@ -336,6 +375,12 @@ P_CheckSight
     topslope = (t2->z+t2->height) - sightzstart;
     bottomslope = (t2->z) - sightzstart;

+    if (gameversion == exe_doom_1_2)
+    {
+        return P_PathTraverse(t1->x, t1->y, t2->x, t2->y,
+                              PT_EARLYOUT | PT_ADDLINES, PTR_SightTraverse);
+    }
+
     strace.x = t1->x;
     strace.y = t1->y;
     t2x = t2->x;
diff --git a/src/doom/p_spec.c b/src/doom/p_spec.c
index e56db82d..81addb7c 100644
--- a/src/doom/p_spec.c
+++ b/src/doom/p_spec.c
@@ -509,24 +509,37 @@ P_CrossSpecialLine

     line = &lines[linenum];

-    //	Triggers that other things can activate
+    if (gameversion == exe_doom_1_2)
+    {
+        if (line->special > 98 && line->special != 104)
+        {
+            return;
+        }
+    }
+    else
+    {
+        //	Triggers that other things can activate
+        if (!thing->player)
+        {
+            // Things that should NOT trigger specials...
+            switch(thing->type)
+            {
+                case MT_ROCKET:
+                case MT_PLASMA:
+                case MT_BFG:
+                case MT_TROOPSHOT:
+                case MT_HEADSHOT:
+                case MT_BRUISERSHOT:
+                    return;
+                    break;
+
+                default: break;
+            }
+        }
+    }
+
     if (!thing->player)
     {
-	// Things that should NOT trigger specials...
-	switch(thing->type)
-	{
-	  case MT_ROCKET:
-	  case MT_PLASMA:
-	  case MT_BFG:
-	  case MT_TROOPSHOT:
-	  case MT_HEADSHOT:
-	  case MT_BRUISERSHOT:
-	    return;
-	    break;
-
-	  default: break;
-	}
-
 	ok = 0;
 	switch(line->special)
 	{
diff --git a/src/doom/s_sound.c b/src/doom/s_sound.c
index 9af5e07e..2de5b0df 100644
--- a/src/doom/s_sound.c
+++ b/src/doom/s_sound.c
@@ -445,6 +445,40 @@ void S_StartSound(void *origin_p, int sfx_id)
         I_Error("Bad sfx #: %d", sfx_id);
     }

+    // substitute missing sounds in Doom 1.2
+    if (gameversion == exe_doom_1_2)
+    {
+        switch(sfx_id)
+        {
+            case sfx_bdcls:
+                sfx_id = sfx_dorcls;
+                break;
+
+            case sfx_bdopn:
+                sfx_id = sfx_doropn;
+                break;
+
+            case sfx_getpow:
+                sfx_id = sfx_itemup;
+                break;
+
+            case sfx_itmbk:
+                sfx_id = sfx_stnmov;
+                break;
+
+            case sfx_pdiehi:
+                sfx_id = sfx_pldeth;
+                break;
+
+            case sfx_tink:
+                sfx_id = sfx_swtchx;
+                break;
+
+            default:
+                break;
+        }
+    }
+
     sfx = &S_sfx[sfx_id];

     // Initialize sound parameters
@@ -661,7 +695,8 @@ void S_ChangeMusic(int musicnum, int looping)
     // and d_introa.  The latter is used for OPL playback.

     if (musicnum == mus_intro && (snd_musicdevice == SNDDEVICE_ADLIB
-                               || snd_musicdevice == SNDDEVICE_SB))
+                               || snd_musicdevice == SNDDEVICE_SB)
+        && W_CheckNumForName("D_INTROA") > 0)
     {
         musicnum = mus_introa;
     }
diff --git a/src/doom/st_lib.c b/src/doom/st_lib.c
index 64533658..28ab1b30 100644
--- a/src/doom/st_lib.c
+++ b/src/doom/st_lib.c
@@ -50,7 +50,10 @@ patch_t*		sttminus;

 void STlib_init(void)
 {
-    sttminus = (patch_t *) W_CacheLumpName(DEH_String("STTMINUS"), PU_STATIC);
+    if (W_CheckNumForName(DEH_String("STTMINUS")) > 0)
+        sttminus = (patch_t *) W_CacheLumpName(DEH_String("STTMINUS"), PU_STATIC);
+    else
+        sttminus = NULL;
 }


@@ -136,7 +139,7 @@ STlib_drawNum
     }

     // draw a minus sign if necessary
-    if (neg)
+    if (neg && sttminus)
 	V_DrawPatch(x - 8, n->y, sttminus);
 }

diff --git a/src/doom/st_stuff.c b/src/doom/st_stuff.c
index dc72f1e6..5aee4520 100644
--- a/src/doom/st_stuff.c
+++ b/src/doom/st_stuff.c
@@ -307,6 +307,9 @@ static boolean		st_fragson;
 // main bar left
 static patch_t*		sbar;

+// main bar right, for doom 1.0
+static patch_t*		sbarr;
+
 // 0-9, tall numbers
 static patch_t*		tallnum[10];

@@ -422,6 +425,10 @@ void ST_refreshBackground(void)

 	V_DrawPatch(ST_X, 0, sbar);

+	// draw right side of bar if needed (Doom 1.0)
+	if (sbarr)
+	    V_DrawPatch(ST_ARMSBGX, 0, sbarr);
+
 	if (netgame)
 	    V_DrawPatch(ST_FX, 0, faceback);

@@ -1142,7 +1149,16 @@ static void ST_loadUnloadGraphics(load_callback_t callback)
     callback(namebuf, &faceback);

     // status bar background bits
-    callback(DEH_String("STBAR"), &sbar);
+    if (W_CheckNumForName(DEH_String("STBAR")) > 0)
+    {
+        callback(DEH_String("STBAR"), &sbar);
+        sbarr = NULL;
+    }
+    else
+    {
+        callback(DEH_String("STMBARL"), &sbar);
+        callback(DEH_String("STMBARR"), &sbarr);
+    }

     // face states
     facenum = 0;
diff --git a/src/doom/wi_stuff.c b/src/doom/wi_stuff.c
index 1bfbcb2b..361ed30f 100644
--- a/src/doom/wi_stuff.c
+++ b/src/doom/wi_stuff.c
@@ -675,7 +675,7 @@ WI_drawNum
     }

     // draw a minus sign if necessary
-    if (neg)
+    if (neg && wiminus)
 	V_DrawPatch(x-=8, y, wiminus);

     return x;
@@ -1613,7 +1613,10 @@ static void WI_loadUnloadData(load_callback_t callback)
     }

     // More hacks on minus sign.
-    callback(DEH_String("WIMINUS"), &wiminus);
+    if (W_CheckNumForName(DEH_String("WIMINUS")) > 0)
+        callback(DEH_String("WIMINUS"), &wiminus);
+    else
+        wiminus = NULL;

     for (i=0;i<10;i++)
     {