diff options
author | James Haley | 2011-02-05 01:23:54 +0000 |
---|---|---|
committer | James Haley | 2011-02-05 01:23:54 +0000 |
commit | e81e9d80c45f6ec0698adfbc77b10e37df8c4c26 (patch) | |
tree | 7c8f5b2f8e5b6c27544a5fd666ce32ab7b133f20 /src/strife/p_maputl.c | |
parent | 725090a6ac3b526560082681e3329effd800bd5b (diff) | |
download | chocolate-doom-e81e9d80c45f6ec0698adfbc77b10e37df8c4c26.tar.gz chocolate-doom-e81e9d80c45f6ec0698adfbc77b10e37df8c4c26.tar.bz2 chocolate-doom-e81e9d80c45f6ec0698adfbc77b10e37df8c4c26.zip |
Finished second passes through p_map and p_maputl - modules are largely
finalized. Fixes/additions include adjusted dropoff height in P_TryMove,
order-of-evaluation fix in PIT_ChangeSector, proper spechit overrun
emulation, and Rogue's fix which prevents intercepts overflows.
Subversion-branch: /branches/strife-branch
Subversion-revision: 2247
Diffstat (limited to 'src/strife/p_maputl.c')
-rw-r--r-- | src/strife/p_maputl.c | 746 |
1 files changed, 395 insertions, 351 deletions
diff --git a/src/strife/p_maputl.c b/src/strife/p_maputl.c index 681e7c26..ee8485ca 100644 --- a/src/strife/p_maputl.c +++ b/src/strife/p_maputl.c @@ -47,7 +47,8 @@ // P_AproxDistance // Gives an estimation of distance (not exact) // - +// [STRIFE] Verified unmodified +// fixed_t P_AproxDistance ( fixed_t dx, @@ -56,7 +57,7 @@ P_AproxDistance dx = abs(dx); dy = abs(dy); if (dx < dy) - return dx+dy-(dx>>1); + return dx+dy-(dx>>1); return dx+dy-(dy>>1); } @@ -65,41 +66,43 @@ P_AproxDistance // P_PointOnLineSide // Returns 0 or 1 // +// [STRIFE] Verified unmodified +// int P_PointOnLineSide ( fixed_t x, fixed_t y, line_t* line ) { - fixed_t dx; - fixed_t dy; - fixed_t left; - fixed_t right; - + fixed_t dx; + fixed_t dy; + fixed_t left; + fixed_t right; + if (!line->dx) { - if (x <= line->v1->x) - return line->dy > 0; - - return line->dy < 0; + if (x <= line->v1->x) + return line->dy > 0; + + return line->dy < 0; } if (!line->dy) { - if (y <= line->v1->y) - return line->dx < 0; - - return line->dx > 0; + if (y <= line->v1->y) + return line->dx < 0; + + return line->dx > 0; } - + dx = (x - line->v1->x); dy = (y - line->v1->y); - + left = FixedMul ( line->dy>>FRACBITS , dx ); right = FixedMul ( dy , line->dx>>FRACBITS ); - + if (right < left) - return 0; // front side - return 1; // back side + return 0; // front side + return 1; // back side } @@ -109,49 +112,51 @@ P_PointOnLineSide // Considers the line to be infinite // Returns side 0 or 1, -1 if box crosses the line. // +// [STRIFE] Verified unmodified +// int P_BoxOnLineSide -( fixed_t* tmbox, - line_t* ld ) +( fixed_t* tmbox, + line_t* ld ) { - int p1 = 0; - int p2 = 0; - + int p1 = 0; + int p2 = 0; + switch (ld->slopetype) { - case ST_HORIZONTAL: - p1 = tmbox[BOXTOP] > ld->v1->y; - p2 = tmbox[BOXBOTTOM] > ld->v1->y; - if (ld->dx < 0) - { - p1 ^= 1; - p2 ^= 1; - } - break; - - case ST_VERTICAL: - p1 = tmbox[BOXRIGHT] < ld->v1->x; - p2 = tmbox[BOXLEFT] < ld->v1->x; - if (ld->dy < 0) - { - p1 ^= 1; - p2 ^= 1; - } - break; - - case ST_POSITIVE: - p1 = P_PointOnLineSide (tmbox[BOXLEFT], tmbox[BOXTOP], ld); - p2 = P_PointOnLineSide (tmbox[BOXRIGHT], tmbox[BOXBOTTOM], ld); - break; - - case ST_NEGATIVE: - p1 = P_PointOnLineSide (tmbox[BOXRIGHT], tmbox[BOXTOP], ld); - p2 = P_PointOnLineSide (tmbox[BOXLEFT], tmbox[BOXBOTTOM], ld); - break; + case ST_HORIZONTAL: + p1 = tmbox[BOXTOP] > ld->v1->y; + p2 = tmbox[BOXBOTTOM] > ld->v1->y; + if (ld->dx < 0) + { + p1 ^= 1; + p2 ^= 1; + } + break; + + case ST_VERTICAL: + p1 = tmbox[BOXRIGHT] < ld->v1->x; + p2 = tmbox[BOXLEFT] < ld->v1->x; + if (ld->dy < 0) + { + p1 ^= 1; + p2 ^= 1; + } + break; + + case ST_POSITIVE: + p1 = P_PointOnLineSide (tmbox[BOXLEFT], tmbox[BOXTOP], ld); + p2 = P_PointOnLineSide (tmbox[BOXRIGHT], tmbox[BOXBOTTOM], ld); + break; + + case ST_NEGATIVE: + p1 = P_PointOnLineSide (tmbox[BOXRIGHT], tmbox[BOXTOP], ld); + p2 = P_PointOnLineSide (tmbox[BOXLEFT], tmbox[BOXBOTTOM], ld); + break; } if (p1 == p2) - return p1; + return p1; return -1; } @@ -160,48 +165,50 @@ P_BoxOnLineSide // P_PointOnDivlineSide // Returns 0 or 1. // +// [STRIFE] Verified unmodified +// int P_PointOnDivlineSide -( fixed_t x, - fixed_t y, - divline_t* line ) +( fixed_t x, + fixed_t y, + divline_t* line ) { - fixed_t dx; - fixed_t dy; - fixed_t left; - fixed_t right; - + fixed_t dx; + fixed_t dy; + fixed_t left; + fixed_t right; + if (!line->dx) { - if (x <= line->x) - return line->dy > 0; - - return line->dy < 0; + if (x <= line->x) + return line->dy > 0; + + return line->dy < 0; } if (!line->dy) { - if (y <= line->y) - return line->dx < 0; + if (y <= line->y) + return line->dx < 0; - return line->dx > 0; + return line->dx > 0; } - + dx = (x - line->x); dy = (y - line->y); - + // try to quickly decide by looking at sign bits if ( (line->dy ^ line->dx ^ dx ^ dy)&0x80000000 ) { - if ( (line->dy ^ dx) & 0x80000000 ) - return 1; // (left is negative) - return 0; + if ( (line->dy ^ dx) & 0x80000000 ) + return 1; // (left is negative) + return 0; } - + left = FixedMul ( line->dy>>8, dx>>8 ); right = FixedMul ( dy>>8 , line->dx>>8 ); - + if (right < left) - return 0; // front side + return 0; // front side return 1; // back side } @@ -230,25 +237,27 @@ P_MakeDivline // This is only called by the addthings // and addlines traversers. // +// [STRIFE] Verified unmodified +// fixed_t P_InterceptVector -( divline_t* v2, - divline_t* v1 ) +( divline_t* v2, + divline_t* v1 ) { #if 1 - fixed_t frac; - fixed_t num; - fixed_t den; - + fixed_t frac; + fixed_t num; + fixed_t den; + den = FixedMul (v1->dy>>8,v2->dx) - FixedMul(v1->dx>>8,v2->dy); if (den == 0) - return 0; - // I_Error ("P_InterceptVector: parallel"); - + return 0; + // I_Error ("P_InterceptVector: parallel"); + num = - FixedMul ( (v1->x - v2->x)>>8 ,v1->dy ) - +FixedMul ( (v2->y - v1->y)>>8, v1->dx ); + FixedMul ( (v1->x - v2->x)>>8 ,v1->dy ) + +FixedMul ( (v2->y - v1->y)>>8, v1->dx ); frac = FixedDiv (num , den); @@ -294,6 +303,8 @@ P_InterceptVector // through a two sided line. // OPTIMIZE: keep this precalculated // +// [STRIFE] Verified unmodified +// fixed_t opentop; fixed_t openbottom; fixed_t openrange; @@ -302,35 +313,35 @@ fixed_t lowfloor; void P_LineOpening (line_t* linedef) { - sector_t* front; - sector_t* back; - + sector_t* front; + sector_t* back; + if (linedef->sidenum[1] == -1) { - // single sided line - openrange = 0; - return; + // single sided line + openrange = 0; + return; } - + front = linedef->frontsector; back = linedef->backsector; - + if (front->ceilingheight < back->ceilingheight) - opentop = front->ceilingheight; + opentop = front->ceilingheight; else - opentop = back->ceilingheight; + opentop = back->ceilingheight; if (front->floorheight > back->floorheight) { - openbottom = front->floorheight; - lowfloor = back->floorheight; + openbottom = front->floorheight; + lowfloor = back->floorheight; } else { - openbottom = back->floorheight; - lowfloor = front->floorheight; + openbottom = back->floorheight; + lowfloor = front->floorheight; } - + openrange = opentop - openbottom; } @@ -347,44 +358,46 @@ void P_LineOpening (line_t* linedef) // lookups maintaining lists ot things inside // these structures need to be updated. // +// [STRIFE] Verified unmodified +// void P_UnsetThingPosition (mobj_t* thing) { - int blockx; - int blocky; + int blockx; + int blocky; if ( ! (thing->flags & MF_NOSECTOR) ) { - // inert things don't need to be in blockmap? - // unlink from subsector - if (thing->snext) - thing->snext->sprev = thing->sprev; - - if (thing->sprev) - thing->sprev->snext = thing->snext; - else - thing->subsector->sector->thinglist = thing->snext; + // inert things don't need to be in blockmap? + // unlink from subsector + if (thing->snext) + thing->snext->sprev = thing->sprev; + + if (thing->sprev) + thing->sprev->snext = thing->snext; + else + thing->subsector->sector->thinglist = thing->snext; } - + if ( ! (thing->flags & MF_NOBLOCKMAP) ) { - // inert things don't need to be in blockmap - // unlink from block map - if (thing->bnext) - thing->bnext->bprev = thing->bprev; - - if (thing->bprev) - thing->bprev->bnext = thing->bnext; - else - { - blockx = (thing->x - bmaporgx)>>MAPBLOCKSHIFT; - blocky = (thing->y - bmaporgy)>>MAPBLOCKSHIFT; - - if (blockx>=0 && blockx < bmapwidth - && blocky>=0 && blocky <bmapheight) - { - blocklinks[blocky*bmapwidth+blockx] = thing->bnext; - } - } + // inert things don't need to be in blockmap + // unlink from block map + if (thing->bnext) + thing->bnext->bprev = thing->bprev; + + if (thing->bprev) + thing->bprev->bnext = thing->bnext; + else + { + blockx = (thing->x - bmaporgx)>>MAPBLOCKSHIFT; + blocky = (thing->y - bmaporgy)>>MAPBLOCKSHIFT; + + if (blockx>=0 && blockx < bmapwidth + && blocky>=0 && blocky <bmapheight) + { + blocklinks[blocky*bmapwidth+blockx] = thing->bnext; + } + } } } @@ -395,60 +408,62 @@ void P_UnsetThingPosition (mobj_t* thing) // based on it's x y. // Sets thing->subsector properly // +// [STRIFE] Verified unmodified +// void P_SetThingPosition (mobj_t* thing) { - subsector_t* ss; - sector_t* sec; - int blockx; - int blocky; - mobj_t** link; + subsector_t* ss; + sector_t* sec; + int blockx; + int blocky; + mobj_t** link; + - // link into subsector ss = R_PointInSubsector (thing->x,thing->y); thing->subsector = ss; - + if ( ! (thing->flags & MF_NOSECTOR) ) { - // invisible things don't go into the sector links - sec = ss->sector; - - thing->sprev = NULL; - thing->snext = sec->thinglist; + // invisible things don't go into the sector links + sec = ss->sector; + + thing->sprev = NULL; + thing->snext = sec->thinglist; - if (sec->thinglist) - sec->thinglist->sprev = thing; + if (sec->thinglist) + sec->thinglist->sprev = thing; - sec->thinglist = thing; + sec->thinglist = thing; } - + // link into blockmap if ( ! (thing->flags & MF_NOBLOCKMAP) ) { - // inert things don't need to be in blockmap - blockx = (thing->x - bmaporgx)>>MAPBLOCKSHIFT; - blocky = (thing->y - bmaporgy)>>MAPBLOCKSHIFT; - - if (blockx>=0 - && blockx < bmapwidth - && blocky>=0 - && blocky < bmapheight) - { - link = &blocklinks[blocky*bmapwidth+blockx]; - thing->bprev = NULL; - thing->bnext = *link; - if (*link) - (*link)->bprev = thing; - - *link = thing; - } - else - { - // thing is off the map - thing->bnext = thing->bprev = NULL; - } + // inert things don't need to be in blockmap + blockx = (thing->x - bmaporgx)>>MAPBLOCKSHIFT; + blocky = (thing->y - bmaporgy)>>MAPBLOCKSHIFT; + + if (blockx>=0 + && blockx < bmapwidth + && blocky>=0 + && blocky < bmapheight) + { + link = &blocklinks[blocky*bmapwidth+blockx]; + thing->bprev = NULL; + thing->bnext = *link; + if (*link) + (*link)->bprev = thing; + + *link = thing; + } + else + { + // thing is off the map + thing->bnext = thing->bprev = NULL; + } } } @@ -485,9 +500,9 @@ P_BlockLinesIterator line_t* ld; if (x<0 - || y<0 - || x>=bmapwidth - || y>=bmapheight) + || y<0 + || x>=bmapwidth + || y>=bmapheight) { return true; } @@ -518,29 +533,31 @@ P_BlockLinesIterator // // P_BlockThingsIterator // +// [STRIFE] Verified unmodified +// boolean P_BlockThingsIterator -( int x, - int y, +( int x, + int y, boolean(*func)(mobj_t*) ) { - mobj_t* mobj; - + mobj_t* mobj; + if ( x<0 - || y<0 - || x>=bmapwidth - || y>=bmapheight) + || y<0 + || x>=bmapwidth + || y>=bmapheight) { - return true; + return true; } - + for (mobj = blocklinks[y*bmapwidth+x] ; - mobj ; - mobj = mobj->bnext) + mobj ; + mobj = mobj->bnext) { - if (!func( mobj ) ) - return false; + if (!func( mobj ) ) + return false; } return true; } @@ -569,55 +586,66 @@ static void InterceptsOverrun(int num_intercepts, intercept_t *intercept); // are on opposite sides of the trace. // Returns true if earlyout and a solid line hit. // +// haleyjd 20110204 [STRIFE]: Added Rogue's fix for intercepts overflows +// boolean PIT_AddLineIntercepts (line_t* ld) { - int s1; - int s2; - fixed_t frac; - divline_t dl; - + int s1; + int s2; + fixed_t frac; + divline_t dl; + // avoid precision problems with two routines if ( trace.dx > FRACUNIT*16 - || trace.dy > FRACUNIT*16 - || trace.dx < -FRACUNIT*16 - || trace.dy < -FRACUNIT*16) + || trace.dy > FRACUNIT*16 + || trace.dx < -FRACUNIT*16 + || trace.dy < -FRACUNIT*16) { - s1 = P_PointOnDivlineSide (ld->v1->x, ld->v1->y, &trace); - s2 = P_PointOnDivlineSide (ld->v2->x, ld->v2->y, &trace); + s1 = P_PointOnDivlineSide (ld->v1->x, ld->v1->y, &trace); + s2 = P_PointOnDivlineSide (ld->v2->x, ld->v2->y, &trace); } else { - s1 = P_PointOnLineSide (trace.x, trace.y, ld); - s2 = P_PointOnLineSide (trace.x+trace.dx, trace.y+trace.dy, ld); + s1 = P_PointOnLineSide (trace.x, trace.y, ld); + s2 = P_PointOnLineSide (trace.x+trace.dx, trace.y+trace.dy, ld); } - + if (s1 == s2) - return true; // line isn't crossed - + return true; // line isn't crossed + // hit the line P_MakeDivline (ld, &dl); frac = P_InterceptVector (&trace, &dl); if (frac < 0) - return true; // behind source - + return true; // behind source + // try to early out the check if (earlyout - && frac < FRACUNIT - && !ld->backsector) + && frac < FRACUNIT + && !ld->backsector) { - return false; // stop checking + return false; // stop checking } - - + + intercept_p->frac = frac; intercept_p->isaline = true; intercept_p->d.line = ld; - InterceptsOverrun(intercept_p - intercepts, intercept_p); intercept_p++; - return true; // continue + // haleyjd 20110204 [STRIFE] + // Evidently Rogue had trouble with intercepts overflows during + // development, as they added this check here which will stop adding + // intercepts if the array would be overflown. + if(intercept_p <= &intercepts[MAXINTERCEPTS_ORIGINAL-2]) + return true; // continue + else + return false; + + // [STRIFE] Not needed? + //InterceptsOverrun(intercept_p - intercepts, intercept_p); } @@ -627,63 +655,71 @@ PIT_AddLineIntercepts (line_t* ld) // boolean PIT_AddThingIntercepts (mobj_t* thing) { - fixed_t x1; - fixed_t y1; - fixed_t x2; - fixed_t y2; - - int s1; - int s2; - - boolean tracepositive; + fixed_t x1; + fixed_t y1; + fixed_t x2; + fixed_t y2; + + int s1; + int s2; + + boolean tracepositive; + + divline_t dl; + + fixed_t frac; - divline_t dl; - - fixed_t frac; - tracepositive = (trace.dx ^ trace.dy)>0; - + // check a corner to corner crossection for hit if (tracepositive) { - x1 = thing->x - thing->radius; - y1 = thing->y + thing->radius; - - x2 = thing->x + thing->radius; - y2 = thing->y - thing->radius; + x1 = thing->x - thing->radius; + y1 = thing->y + thing->radius; + + x2 = thing->x + thing->radius; + y2 = thing->y - thing->radius; } else { - x1 = thing->x - thing->radius; - y1 = thing->y - thing->radius; - - x2 = thing->x + thing->radius; - y2 = thing->y + thing->radius; + x1 = thing->x - thing->radius; + y1 = thing->y - thing->radius; + + x2 = thing->x + thing->radius; + y2 = thing->y + thing->radius; } - + s1 = P_PointOnDivlineSide (x1, y1, &trace); s2 = P_PointOnDivlineSide (x2, y2, &trace); if (s1 == s2) - return true; // line isn't crossed - + return true; // line isn't crossed + dl.x = x1; dl.y = y1; dl.dx = x2-x1; dl.dy = y2-y1; - + frac = P_InterceptVector (&trace, &dl); if (frac < 0) - return true; // behind source + return true; // behind source intercept_p->frac = frac; intercept_p->isaline = false; intercept_p->d.thing = thing; - InterceptsOverrun(intercept_p - intercepts, intercept_p); + intercept_p++; + + // haleyjd 20110204 [STRIFE]: As above, protection against intercepts + // overflows, courtesy of Rogue Software. + if(intercept_p <= &intercepts[MAXINTERCEPTS_ORIGINAL-2]) + return true; // keep going + else + return false; - return true; // keep going + // haleyjd [STRIFE]: Not needed? + //InterceptsOverrun(intercept_p - intercepts, intercept_p); } @@ -699,49 +735,49 @@ P_TraverseIntercepts ( traverser_t func, fixed_t maxfrac ) { - int count; - fixed_t dist; - intercept_t* scan; - intercept_t* in; - + int count; + fixed_t dist; + intercept_t* scan; + intercept_t* in; + count = intercept_p - intercepts; - - in = 0; // shut up compiler warning - + + in = 0; // shut up compiler warning + while (count--) { - dist = INT_MAX; - for (scan = intercepts ; scan<intercept_p ; scan++) - { - if (scan->frac < dist) - { - dist = scan->frac; - in = scan; - } - } - - if (dist > maxfrac) - return true; // checked everything in range + dist = INT_MAX; + for (scan = intercepts ; scan<intercept_p ; scan++) + { + if (scan->frac < dist) + { + dist = scan->frac; + in = scan; + } + } + + if (dist > maxfrac) + return true; // checked everything in range #if 0 // UNUSED - { - // don't check these yet, there may be others inserted - in = scan = intercepts; - for ( scan = intercepts ; scan<intercept_p ; scan++) - if (scan->frac > maxfrac) - *in++ = *scan; - intercept_p = in; - return false; - } + { + // don't check these yet, there may be others inserted + in = scan = intercepts; + for ( scan = intercepts ; scan<intercept_p ; scan++) + if (scan->frac > maxfrac) + *in++ = *scan; + intercept_p = in; + return false; + } #endif if ( !func (in) ) - return false; // don't bother going farther + return false; // don't bother going farther - in->frac = INT_MAX; + in->frac = INT_MAX; } - - return true; // everything was traversed + + return true; // everything was traversed } extern fixed_t bulletslope; @@ -766,6 +802,12 @@ typedef struct // playerstarts, which is effectively an array of 16-bit integers and // must be treated differently. +// haleyjd 20110204: NB: This array has *not* been updated for Strife, +// because Strife has protection against intercepts overflows. The memory +// layout of the 1.2 and 1.31 EXEs is radically different with respect +// to this area of the BSS segment, so it would have to be redone entirely +// if it were needed. + static intercepts_overrun_t intercepts_overrun[] = { {4, NULL, false}, @@ -873,46 +915,48 @@ static void InterceptsOverrun(int num_intercepts, intercept_t *intercept) // Returns true if the traverser function returns true // for all lines. // +// [STRIFE] Verified unmodified +// boolean P_PathTraverse -( fixed_t x1, - fixed_t y1, - fixed_t x2, - fixed_t y2, - int flags, +( fixed_t x1, + fixed_t y1, + fixed_t x2, + fixed_t y2, + int flags, boolean (*trav) (intercept_t *)) { - fixed_t xt1; - fixed_t yt1; - fixed_t xt2; - fixed_t yt2; + fixed_t xt1; + fixed_t yt1; + fixed_t xt2; + fixed_t yt2; - fixed_t xstep; - fixed_t ystep; + fixed_t xstep; + fixed_t ystep; - fixed_t partial; + fixed_t partial; - fixed_t xintercept; - fixed_t yintercept; + fixed_t xintercept; + fixed_t yintercept; - int mapx; - int mapy; + int mapx; + int mapy; - int mapxstep; - int mapystep; + int mapxstep; + int mapystep; + + int count; - int count; - earlyout = flags & PT_EARLYOUT; - + validcount++; intercept_p = intercepts; - + if ( ((x1-bmaporgx)&(MAPBLOCKSIZE-1)) == 0) - x1 += FRACUNIT; // don't side exactly on a line - + x1 += FRACUNIT; // don't side exactly on a line + if ( ((y1-bmaporgy)&(MAPBLOCKSIZE-1)) == 0) - y1 += FRACUNIT; // don't side exactly on a line + y1 += FRACUNIT; // don't side exactly on a line trace.x = x1; trace.y = y1; @@ -931,83 +975,83 @@ P_PathTraverse if (xt2 > xt1) { - mapxstep = 1; - partial = FRACUNIT - ((x1>>MAPBTOFRAC)&(FRACUNIT-1)); - ystep = FixedDiv (y2-y1,abs(x2-x1)); + mapxstep = 1; + partial = FRACUNIT - ((x1>>MAPBTOFRAC)&(FRACUNIT-1)); + ystep = FixedDiv (y2-y1,abs(x2-x1)); } else if (xt2 < xt1) { - mapxstep = -1; - partial = (x1>>MAPBTOFRAC)&(FRACUNIT-1); - ystep = FixedDiv (y2-y1,abs(x2-x1)); + mapxstep = -1; + partial = (x1>>MAPBTOFRAC)&(FRACUNIT-1); + ystep = FixedDiv (y2-y1,abs(x2-x1)); } else { - mapxstep = 0; - partial = FRACUNIT; - ystep = 256*FRACUNIT; + mapxstep = 0; + partial = FRACUNIT; + ystep = 256*FRACUNIT; } yintercept = (y1>>MAPBTOFRAC) + FixedMul (partial, ystep); - + if (yt2 > yt1) { - mapystep = 1; - partial = FRACUNIT - ((y1>>MAPBTOFRAC)&(FRACUNIT-1)); - xstep = FixedDiv (x2-x1,abs(y2-y1)); + mapystep = 1; + partial = FRACUNIT - ((y1>>MAPBTOFRAC)&(FRACUNIT-1)); + xstep = FixedDiv (x2-x1,abs(y2-y1)); } else if (yt2 < yt1) { - mapystep = -1; - partial = (y1>>MAPBTOFRAC)&(FRACUNIT-1); - xstep = FixedDiv (x2-x1,abs(y2-y1)); + mapystep = -1; + partial = (y1>>MAPBTOFRAC)&(FRACUNIT-1); + xstep = FixedDiv (x2-x1,abs(y2-y1)); } else { - mapystep = 0; - partial = FRACUNIT; - xstep = 256*FRACUNIT; + mapystep = 0; + partial = FRACUNIT; + xstep = 256*FRACUNIT; } xintercept = (x1>>MAPBTOFRAC) + FixedMul (partial, xstep); - + // Step through map blocks. // Count is present to prevent a round off error // from skipping the break. mapx = xt1; mapy = yt1; - + for (count = 0 ; count < 64 ; count++) { - if (flags & PT_ADDLINES) - { - if (!P_BlockLinesIterator (mapx, mapy,PIT_AddLineIntercepts)) - return false; // early out - } - - if (flags & PT_ADDTHINGS) - { - if (!P_BlockThingsIterator (mapx, mapy,PIT_AddThingIntercepts)) - return false; // early out - } - - if (mapx == xt2 - && mapy == yt2) - { - break; - } - - if ( (yintercept >> FRACBITS) == mapy) - { - yintercept += ystep; - mapx += mapxstep; - } - else if ( (xintercept >> FRACBITS) == mapx) - { - xintercept += xstep; - mapy += mapystep; - } - + if (flags & PT_ADDLINES) + { + if (!P_BlockLinesIterator (mapx, mapy,PIT_AddLineIntercepts)) + return false; // early out + } + + if (flags & PT_ADDTHINGS) + { + if (!P_BlockThingsIterator (mapx, mapy,PIT_AddThingIntercepts)) + return false; // early out + } + + if (mapx == xt2 + && mapy == yt2) + { + break; + } + + if ( (yintercept >> FRACBITS) == mapy) + { + yintercept += ystep; + mapx += mapxstep; + } + else if ( (xintercept >> FRACBITS) == mapx) + { + xintercept += xstep; + mapy += mapystep; + } + } // go through the sorted list return P_TraverseIntercepts ( trav, FRACUNIT ); |