foxygit / doom Log in
commit 5ac7ac324198351603d07f8895a53ec906653ff7
Author:     Simon Howard <fraggle@gmail.com>
AuthorDate: Fri Sep 14 22:20:08 2007 +0000
Commit:     Simon Howard <fraggle@gmail.com>
CommitDate: Fri Sep 14 22:20:08 2007 +0000

    Add P_SubstNullMobj, substitute NULL mobjs for a dummy mobj where
    mo->target is not checked for NULL.

    Subversion-branch: /trunk/chocolate-doom
    Subversion-revision: 971
---
 src/p_enemy.c | 37 ++++++++++++++++++++++++++-----------
 src/p_local.h |  1 +
 src/p_mobj.c  | 55 ++++++++++++++++++++++++++-----------------------------
 3 files changed, 53 insertions(+), 40 deletions(-)

diff --git a/src/p_enemy.c b/src/p_enemy.c
index 0ed7f60f..16d2ff06 100644
--- a/src/p_enemy.c
+++ b/src/p_enemy.c
@@ -1258,14 +1258,17 @@ void A_FireCrackle (mobj_t* actor)
 void A_Fire (mobj_t* actor)
 {
     mobj_t*	dest;
+    mobj_t*     target;
     unsigned	an;

     dest = actor->tracer;
     if (!dest)
 	return;
+
+    target = P_SubstNullMobj(actor->target);

     // don't move it if the vile lost sight
-    if (!P_CheckSight (actor->target, dest) )
+    if (!P_CheckSight (target, dest) )
 	return;

     an = dest->angle >> ANGLETOFINESHIFT;
@@ -1359,14 +1362,17 @@ void A_FatRaise (mobj_t *actor)
 void A_FatAttack1 (mobj_t* actor)
 {
     mobj_t*	mo;
+    mobj_t*     target;
     int		an;
-
+
     A_FaceTarget (actor);
+
     // Change direction  to ...
     actor->angle += FATSPREAD;
-    P_SpawnMissile (actor, actor->target, MT_FATSHOT);
+    target = P_SubstNullMobj(actor->target);
+    P_SpawnMissile (actor, target, MT_FATSHOT);

-    mo = P_SpawnMissile (actor, actor->target, MT_FATSHOT);
+    mo = P_SpawnMissile (actor, target, MT_FATSHOT);
     mo->angle += FATSPREAD;
     an = mo->angle >> ANGLETOFINESHIFT;
     mo->momx = FixedMul (mo->info->speed, finecosine[an]);
@@ -1376,14 +1382,16 @@ void A_FatAttack1 (mobj_t* actor)
 void A_FatAttack2 (mobj_t* actor)
 {
     mobj_t*	mo;
+    mobj_t*     target;
     int		an;

     A_FaceTarget (actor);
     // Now here choose opposite deviation.
     actor->angle -= FATSPREAD;
-    P_SpawnMissile (actor, actor->target, MT_FATSHOT);
+    target = P_SubstNullMobj(actor->target);
+    P_SpawnMissile (actor, target, MT_FATSHOT);

-    mo = P_SpawnMissile (actor, actor->target, MT_FATSHOT);
+    mo = P_SpawnMissile (actor, target, MT_FATSHOT);
     mo->angle -= FATSPREAD*2;
     an = mo->angle >> ANGLETOFINESHIFT;
     mo->momx = FixedMul (mo->info->speed, finecosine[an]);
@@ -1393,17 +1401,20 @@ void A_FatAttack2 (mobj_t* actor)
 void A_FatAttack3 (mobj_t*	actor)
 {
     mobj_t*	mo;
+    mobj_t*     target;
     int		an;

     A_FaceTarget (actor);
+
+    target = P_SubstNullMobj(actor->target);

-    mo = P_SpawnMissile (actor, actor->target, MT_FATSHOT);
+    mo = P_SpawnMissile (actor, target, MT_FATSHOT);
     mo->angle -= FATSPREAD/2;
     an = mo->angle >> ANGLETOFINESHIFT;
     mo->momx = FixedMul (mo->info->speed, finecosine[an]);
     mo->momy = FixedMul (mo->info->speed, finesine[an]);

-    mo = P_SpawnMissile (actor, actor->target, MT_FATSHOT);
+    mo = P_SpawnMissile (actor, target, MT_FATSHOT);
     mo->angle += FATSPREAD/2;
     an = mo->angle >> ANGLETOFINESHIFT;
     mo->momx = FixedMul (mo->info->speed, finecosine[an]);
@@ -1598,7 +1609,11 @@ void A_Fall (mobj_t *actor)
 //
 void A_Explode (mobj_t* thingy)
 {
-    P_RadiusAttack ( thingy, thingy->target, 128 );
+    mobj_t *target;
+
+    target = P_SubstNullMobj(thingy->target);
+
+    P_RadiusAttack(thingy, target, 128);
 }


@@ -1823,7 +1838,7 @@ A_CloseShotgun2

 mobj_t*		braintargets[32];
 int		numbraintargets;
-int		braintargeton;
+int		braintargeton = 0;

 void A_BrainAwake (mobj_t* mo)
 {
@@ -1959,7 +1974,7 @@ void A_SpawnFly (mobj_t* mo)
     if (--mo->reactiontime)
 	return;	// still flying

-    targ = mo->target;
+    targ = P_SubstNullMobj(mo->target);

     // First spawn teleport fog.
     fog = P_SpawnMobj (targ->x, targ->y, targ->z, MT_SPAWNFIRE);
diff --git a/src/p_local.h b/src/p_local.h
index d58a7708..2e602ad5 100644
--- a/src/p_local.h
+++ b/src/p_local.h
@@ -119,6 +119,7 @@ P_SpawnMobj
   mobjtype_t	type );

 void 	P_RemoveMobj (mobj_t* th);
+mobj_t* P_SubstNullMobj (mobj_t* th);
 boolean	P_SetMobjState (mobj_t* mobj, statenum_t state);
 void 	P_MobjThinker (mobj_t* mobj);

diff --git a/src/p_mobj.c b/src/p_mobj.c
index 29dafdec..bb72166d 100644
--- a/src/p_mobj.c
+++ b/src/p_mobj.c
@@ -922,6 +922,28 @@ void P_CheckMissileSpawn (mobj_t* th)
 	P_ExplodeMissile (th);
 }

+// Certain functions assume that a mobj_t pointer is non-NULL,
+// causing a crash in some situations where it is NULL.  Vanilla
+// Doom did not crash because of the lack of proper memory
+// protection. This function substitutes NULL pointers for
+// pointers to a dummy mobj, to avoid a crash.
+
+mobj_t *P_SubstNullMobj(mobj_t *mobj)
+{
+    if (mobj == NULL)
+    {
+        static mobj_t dummy_mobj;
+
+        dummy_mobj.x = 0;
+        dummy_mobj.y = 0;
+        dummy_mobj.z = 0;
+        dummy_mobj.flags = 0;
+
+        mobj = &dummy_mobj;
+    }
+
+    return mobj;
+}

 //
 // P_SpawnMissile
@@ -935,31 +957,6 @@ P_SpawnMissile
     mobj_t*	th;
     angle_t	an;
     int		dist;
-    fixed_t     dest_x, dest_y, dest_z, dest_flags;
-
-    // fraggle: This prevents against *crashes* when dest == NULL.
-    // For example, when loading a game saved when a mancubus was
-    // in the middle of firing, mancubus->target == NULL.  SpawnMissile
-    // then gets called with dest == NULL.
-    //
-    // However, this is not the *correct* behavior.  At the moment,
-    // the missile is aimed at 0,0,0.  In reality, monsters seem to aim
-    // somewhere else.
-
-    if (dest)
-    {
-        dest_x = dest->x;
-        dest_y = dest->y;
-        dest_z = dest->z;
-        dest_flags = dest->flags;
-    }
-    else
-    {
-        dest_x = 0;
-        dest_y = 0;
-        dest_z = 0;
-        dest_flags = 0;
-    }

     th = P_SpawnMobj (source->x,
 		      source->y,
@@ -969,10 +966,10 @@ P_SpawnMissile
 	S_StartSound (th, th->info->seesound);

     th->target = source;	// where it came from
-    an = R_PointToAngle2 (source->x, source->y, dest_x, dest_y);
+    an = R_PointToAngle2 (source->x, source->y, dest->x, dest->y);

     // fuzzy player
-    if (dest_flags & MF_SHADOW)
+    if (dest->flags & MF_SHADOW)
 	an += (P_Random()-P_Random())<<20;

     th->angle = an;
@@ -980,13 +977,13 @@ P_SpawnMissile
     th->momx = FixedMul (th->info->speed, finecosine[an]);
     th->momy = FixedMul (th->info->speed, finesine[an]);

-    dist = P_AproxDistance (dest_x - source->x, dest_y - source->y);
+    dist = P_AproxDistance (dest->x - source->x, dest->y - source->y);
     dist = dist / th->info->speed;

     if (dist < 1)
 	dist = 1;

-    th->momz = (dest_z - source->z) / dist;
+    th->momz = (dest->z - source->z) / dist;
     P_CheckMissileSpawn (th);

     return th;