foxygit / doom Log in
commit 7c47cdf16112ed6b15e8a918377156035a166f1e
Author:     Simon Howard <fraggle@gmail.com>
AuthorDate: Tue Jan 26 19:18:18 2010 +0000
Commit:     Simon Howard <fraggle@gmail.com>
CommitDate: Tue Jan 26 19:18:18 2010 +0000

    Fix glass hack windows where a linedef is flagged as two sided but has
    only one side. Fixes WADs such as OTTAWAU.WAD (thanks Never_Again).

    Subversion-branch: /trunk/chocolate-doom
    Subversion-revision: 1826
---
 NEWS          |  2 ++
 src/p_map.c   | 21 +++++++++++++++++++--
 src/p_setup.c | 27 +++++++++++++++++++++++----
 src/p_sight.c | 10 +++++++++-
 4 files changed, 53 insertions(+), 7 deletions(-)

diff --git a/NEWS b/NEWS
index 9c267b12..abe5aa9d 100644
--- a/NEWS
+++ b/NEWS
@@ -50,6 +50,8 @@
        instead of the red colormaps normally used when taking damage
        or using the berserk pack.  This matches Vanilla chex.exe
        behavior (thanks Fuzztooth).
+     * Impassible glass now displays and works the same as in Vanilla,
+       fixing wads such as OTTAWAU.WAD (thanks Never_Again).

     Bugs fixed:
      * Memory-mapped WAD I/O is disabled by default, as it caused
diff --git a/src/p_map.c b/src/p_map.c
index 89f8f3f8..b50fff2c 100644
--- a/src/p_map.c
+++ b/src/p_map.c
@@ -885,7 +885,17 @@ PTR_AimTraverse (intercept_t* in)

 	dist = FixedMul (attackrange, in->frac);

-	if (li->frontsector->floorheight != li->backsector->floorheight)
+        // Return false if there is no back sector.  This should never
+        // be the case if the line is two-sided; however, some WADs
+        // (eg. ottawau.wad) use this as an "impassible glass" trick
+        // and rely on Vanilla Doom's (unintentional) support for this.
+
+        if (li->backsector == NULL)
+        {
+            return false;
+        }
+
+        if (li->frontsector->floorheight != li->backsector->floorheight)
 	{
 	    slope = FixedDiv (openbottom - shootz , dist);
 	    if (slope > bottomslope)
@@ -973,7 +983,14 @@ boolean PTR_ShootTraverse (intercept_t* in)

 	dist = FixedMul (attackrange, in->frac);

-	if (li->frontsector->floorheight != li->backsector->floorheight)
+        // Check if backsector is NULL.  See comment in PTR_AimTraverse.
+
+	if (li->backsector == NULL)
+        {
+            goto hitline;
+        }
+
+        if (li->frontsector->floorheight != li->backsector->floorheight)
 	{
 	    slope = FixedDiv (openbottom - shootz , dist);
 	    if (slope > aimslope)
diff --git a/src/p_setup.c b/src/p_setup.c
index 5cf7a628..2a3a8f85 100644
--- a/src/p_setup.c
+++ b/src/p_setup.c
@@ -167,6 +167,7 @@ void P_LoadSegs (int lump)
     line_t*		ldef;
     int			linedef;
     int			side;
+    int                 sidenum;

     numsegs = W_LumpLength (lump) / sizeof(mapseg_t);
     segs = Z_Malloc (numsegs*sizeof(seg_t),PU_LEVEL,0);
@@ -179,7 +180,7 @@ void P_LoadSegs (int lump)
     {
 	li->v1 = &vertexes[SHORT(ml->v1)];
 	li->v2 = &vertexes[SHORT(ml->v2)];
-
+
 	li->angle = (SHORT(ml->angle))<<16;
 	li->offset = (SHORT(ml->offset))<<16;
 	linedef = SHORT(ml->linedef);
@@ -188,10 +189,28 @@ void P_LoadSegs (int lump)
 	side = SHORT(ml->side);
 	li->sidedef = &sides[ldef->sidenum[side]];
 	li->frontsector = sides[ldef->sidenum[side]].sector;
-	if (ldef-> flags & ML_TWOSIDED)
-	    li->backsector = sides[ldef->sidenum[side^1]].sector;
-	else
+
+        if (ldef-> flags & ML_TWOSIDED)
+        {
+            sidenum = ldef->sidenum[side ^ 1];
+
+            // If the sidenum is out of range, this may be a "glass hack"
+            // impassible window.  Point at side #0 (this may not be
+            // the correct Vanilla behavior; however, it seems to work for
+            // OTTAWAU.WAD, which is the one place I've seen this trick
+            // used).
+
+            if (sidenum < 0 || sidenum >= numsides)
+            {
+                sidenum = 0;
+            }
+
+            li->backsector = sides[sidenum].sector;
+        }
+        else
+        {
 	    li->backsector = 0;
+        }
     }

     W_ReleaseLumpNum(lump);
diff --git a/src/p_sight.c b/src/p_sight.c
index e192567b..79c1bb1d 100644
--- a/src/p_sight.c
+++ b/src/p_sight.c
@@ -173,7 +173,7 @@ boolean P_CrossSubsector (int num)
 	    continue;

 	line->validcount = validcount;
-
+
 	v1 = line->v1;
 	v2 = line->v2;
 	s1 = P_DivlineSide (v1->x,v1->y, &strace);
@@ -194,6 +194,14 @@ boolean P_CrossSubsector (int num)
 	if (s1 == s2)
 	    continue;

+        // Backsector may be NULL if this is an "impassible
+        // glass" hack line.
+
+        if (line->backsector == NULL)
+        {
+            return false;
+        }
+
 	// stop because it is not two sided anyway
 	// might do this after updating validcount?
 	if ( !(line->flags & ML_TWOSIDED) )