shithub: choc

Download patch

ref: 9eae89d3eb668df2ea218f3944d12996e3364000
parent: 9eaf5ccf437353a2ad61ea033fd2acb7f396cdd1
author: James Canete <SmileTheory@gmail.com>
date: Sun Oct 13 08:46:28 EDT 2019

Doom 1.2 demo support

Mostly cribbed from prboom-plus

--- a/src/doom/d_main.c
+++ b/src/doom/d_main.c
@@ -1051,6 +1051,13 @@
                     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;
--- a/src/doom/g_game.c
+++ b/src/doom/g_game.c
@@ -2053,7 +2053,7 @@
     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 @@
     {
         *demo_p++ = DOOM_191_VERSION;
     }
-    else
+    else if (gameversion != exe_doom_1_2)
     {
         *demo_p++ = G_VanillaVersionCode();
     }
@@ -2096,11 +2096,14 @@
     *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 @@
     // 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 @@
 
     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 @@
     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++; 
 
--- a/src/doom/m_menu.c
+++ b/src/doom/m_menu.c
@@ -2006,7 +2006,7 @@
     {
         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));
 	}
--- a/src/doom/p_enemy.c
+++ b/src/doom/p_enemy.c
@@ -168,6 +168,7 @@
 {
     mobj_t*	pl;
     fixed_t	dist;
+    fixed_t range;
 	
     if (!actor->target)
 	return false;
@@ -175,8 +176,14 @@
     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 @@
     // 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 @@
 	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)
--- a/src/doom/p_floor.c
+++ b/src/doom/p_floor.c
@@ -303,7 +303,8 @@
 	    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;
 
--- a/src/doom/p_inter.c
+++ b/src/doom/p_inter.c
@@ -382,7 +382,7 @@
 	
       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 @@
     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,
--- a/src/doom/p_map.c
+++ b/src/doom/p_map.c
@@ -1317,7 +1317,8 @@
     {
 	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;
 
--- 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 @@
 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 @@
     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;
--- a/src/doom/p_spec.c
+++ b/src/doom/p_spec.c
@@ -509,24 +509,37 @@
 
     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)
 	{
--- a/src/doom/s_sound.c
+++ b/src/doom/s_sound.c
@@ -445,6 +445,40 @@
         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 @@
     // 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;
     }
--- a/src/doom/st_lib.c
+++ b/src/doom/st_lib.c
@@ -50,7 +50,10 @@
 
 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 @@
     }
 
     // draw a minus sign if necessary
-    if (neg)
+    if (neg && sttminus)
 	V_DrawPatch(x - 8, n->y, sttminus);
 }
 
--- a/src/doom/st_stuff.c
+++ b/src/doom/st_stuff.c
@@ -307,6 +307,9 @@
 // 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 @@
 
 	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 @@
     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;
--- a/src/doom/wi_stuff.c
+++ b/src/doom/wi_stuff.c
@@ -675,7 +675,7 @@
     }
 
     // draw a minus sign if necessary
-    if (neg)
+    if (neg && wiminus)
 	V_DrawPatch(x-=8, y, wiminus);
 
     return x;
@@ -1613,7 +1613,10 @@
     }
 
     // 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++)
     {