|
|
1.1.1.4 root 1: // Emacs style mode select -*- C++ -*-
2: //-----------------------------------------------------------------------------
3: //
4: // $Id:$
5: //
6: // Copyright (C) 1993-1996 by id Software, Inc.
7: //
1.1.1.5 ! root 8: // This program is free software; you can redistribute it and/or
! 9: // modify it under the terms of the GNU General Public License
! 10: // as published by the Free Software Foundation; either version 2
! 11: // of the License, or (at your option) any later version.
1.1.1.4 root 12: //
1.1.1.5 ! root 13: // This program is distributed in the hope that it will be useful,
1.1.1.4 root 14: // but WITHOUT ANY WARRANTY; without even the implied warranty of
1.1.1.5 ! root 15: // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
! 16: // GNU General Public License for more details.
1.1.1.4 root 17: //
18: // $Log:$
19: //
20: // DESCRIPTION:
21: // Movement/collision utility functions,
22: // as used by function in p_map.c.
23: // BLOCKMAP Iterator functions,
24: // and some PIT_* functions to use for iteration.
25: //
26: //-----------------------------------------------------------------------------
1.1 root 27:
1.1.1.4 root 28: static const char
29: rcsid[] = "$Id: p_maputl.c,v 1.5 1997/02/03 22:45:11 b1 Exp $";
1.1 root 30:
31:
1.1.1.4 root 32: #include <stdlib.h>
1.1 root 33:
34:
1.1.1.4 root 35: #include "m_bbox.h"
1.1 root 36:
1.1.1.4 root 37: #include "doomdef.h"
38: #include "p_local.h"
1.1.1.3 root 39:
40:
1.1.1.4 root 41: // State.
42: #include "r_state.h"
1.1.1.3 root 43:
1.1.1.4 root 44: //
45: // P_AproxDistance
46: // Gives an estimation of distance (not exact)
47: //
1.1.1.3 root 48:
1.1.1.4 root 49: fixed_t
50: P_AproxDistance
51: ( fixed_t dx,
52: fixed_t dy )
53: {
54: dx = abs(dx);
55: dy = abs(dy);
56: if (dx < dy)
57: return dx+dy-(dx>>1);
58: return dx+dy-(dy>>1);
1.1 root 59: }
60:
61:
1.1.1.4 root 62: //
63: // P_PointOnLineSide
64: // Returns 0 or 1
65: //
66: int
67: P_PointOnLineSide
68: ( fixed_t x,
69: fixed_t y,
70: line_t* line )
1.1.1.2 root 71: {
1.1.1.4 root 72: fixed_t dx;
73: fixed_t dy;
74: fixed_t left;
75: fixed_t right;
76:
77: if (!line->dx)
78: {
79: if (x <= line->v1->x)
80: return line->dy > 0;
81:
82: return line->dy < 0;
83: }
84: if (!line->dy)
85: {
86: if (y <= line->v1->y)
87: return line->dx < 0;
88:
89: return line->dx > 0;
90: }
91:
92: dx = (x - line->v1->x);
93: dy = (y - line->v1->y);
94:
95: left = FixedMul ( line->dy>>FRACBITS , dx );
96: right = FixedMul ( dy , line->dx>>FRACBITS );
97:
98: if (right < left)
99: return 0; // front side
100: return 1; // back side
1.1.1.2 root 101: }
102:
1.1 root 103:
1.1.1.3 root 104:
1.1.1.4 root 105: //
106: // P_BoxOnLineSide
107: // Considers the line to be infinite
108: // Returns side 0 or 1, -1 if box crosses the line.
109: //
110: int
111: P_BoxOnLineSide
112: ( fixed_t* tmbox,
113: line_t* ld )
114: {
115: int p1;
116: int p2;
117:
118: switch (ld->slopetype)
119: {
120: case ST_HORIZONTAL:
121: p1 = tmbox[BOXTOP] > ld->v1->y;
122: p2 = tmbox[BOXBOTTOM] > ld->v1->y;
123: if (ld->dx < 0)
1.1 root 124: {
1.1.1.4 root 125: p1 ^= 1;
126: p2 ^= 1;
1.1 root 127: }
1.1.1.4 root 128: break;
129:
130: case ST_VERTICAL:
131: p1 = tmbox[BOXRIGHT] < ld->v1->x;
132: p2 = tmbox[BOXLEFT] < ld->v1->x;
133: if (ld->dy < 0)
1.1 root 134: {
1.1.1.4 root 135: p1 ^= 1;
136: p2 ^= 1;
1.1 root 137: }
1.1.1.4 root 138: break;
139:
140: case ST_POSITIVE:
141: p1 = P_PointOnLineSide (tmbox[BOXLEFT], tmbox[BOXTOP], ld);
142: p2 = P_PointOnLineSide (tmbox[BOXRIGHT], tmbox[BOXBOTTOM], ld);
143: break;
144:
145: case ST_NEGATIVE:
146: p1 = P_PointOnLineSide (tmbox[BOXRIGHT], tmbox[BOXTOP], ld);
147: p2 = P_PointOnLineSide (tmbox[BOXLEFT], tmbox[BOXBOTTOM], ld);
148: break;
149: }
1.1.1.3 root 150:
1.1.1.4 root 151: if (p1 == p2)
152: return p1;
153: return -1;
154: }
1.1.1.3 root 155:
156:
1.1.1.4 root 157: //
158: // P_PointOnDivlineSide
159: // Returns 0 or 1.
160: //
161: int
162: P_PointOnDivlineSide
163: ( fixed_t x,
164: fixed_t y,
165: divline_t* line )
166: {
167: fixed_t dx;
168: fixed_t dy;
169: fixed_t left;
170: fixed_t right;
171:
172: if (!line->dx)
173: {
174: if (x <= line->x)
175: return line->dy > 0;
176:
177: return line->dy < 0;
178: }
179: if (!line->dy)
180: {
181: if (y <= line->y)
182: return line->dx < 0;
1.1.1.3 root 183:
1.1.1.4 root 184: return line->dx > 0;
185: }
186:
187: dx = (x - line->x);
188: dy = (y - line->y);
189:
190: // try to quickly decide by looking at sign bits
191: if ( (line->dy ^ line->dx ^ dx ^ dy)&0x80000000 )
192: {
193: if ( (line->dy ^ dx) & 0x80000000 )
194: return 1; // (left is negative)
195: return 0;
196: }
197:
198: left = FixedMul ( line->dy>>8, dx>>8 );
199: right = FixedMul ( dy>>8 , line->dx>>8 );
200:
201: if (right < left)
202: return 0; // front side
203: return 1; // back side
1.1 root 204: }
205:
206:
207:
1.1.1.4 root 208: //
209: // P_MakeDivline
210: //
211: void
212: P_MakeDivline
213: ( line_t* li,
214: divline_t* dl )
1.1 root 215: {
1.1.1.4 root 216: dl->x = li->v1->x;
217: dl->y = li->v1->y;
218: dl->dx = li->dx;
219: dl->dy = li->dy;
1.1 root 220: }
221:
222:
1.1.1.2 root 223:
1.1.1.4 root 224: //
225: // P_InterceptVector
226: // Returns the fractional intercept point
227: // along the first divline.
228: // This is only called by the addthings
229: // and addlines traversers.
230: //
231: fixed_t
232: P_InterceptVector
233: ( divline_t* v2,
234: divline_t* v1 )
1.1.1.2 root 235: {
236: #if 1
1.1.1.4 root 237: fixed_t frac;
238: fixed_t num;
239: fixed_t den;
240:
241: den = FixedMul (v1->dy>>8,v2->dx) - FixedMul(v1->dx>>8,v2->dy);
242:
243: if (den == 0)
244: return 0;
245: // I_Error ("P_InterceptVector: parallel");
246:
247: num =
248: FixedMul ( (v1->x - v2->x)>>8 ,v1->dy )
249: +FixedMul ( (v2->y - v1->y)>>8, v1->dx );
250:
251: frac = FixedDiv (num , den);
252:
253: return frac;
254: #else // UNUSED, float debug.
255: float frac;
256: float num;
257: float den;
258: float v1x;
259: float v1y;
260: float v1dx;
261: float v1dy;
262: float v2x;
263: float v2y;
264: float v2dx;
265: float v2dy;
266:
267: v1x = (float)v1->x/FRACUNIT;
268: v1y = (float)v1->y/FRACUNIT;
269: v1dx = (float)v1->dx/FRACUNIT;
270: v1dy = (float)v1->dy/FRACUNIT;
271: v2x = (float)v2->x/FRACUNIT;
272: v2y = (float)v2->y/FRACUNIT;
273: v2dx = (float)v2->dx/FRACUNIT;
274: v2dy = (float)v2->dy/FRACUNIT;
275:
276: den = v1dy*v2dx - v1dx*v2dy;
1.1.1.3 root 277:
1.1.1.4 root 278: if (den == 0)
279: return 0; // parallel
280:
281: num = (v1x - v2x)*v1dy + (v2y - v1y)*v1dx;
282: frac = num / den;
1.1.1.2 root 283:
1.1.1.4 root 284: return frac*FRACUNIT;
1.1.1.2 root 285: #endif
286: }
287:
1.1 root 288:
1.1.1.4 root 289: //
290: // P_LineOpening
291: // Sets opentop and openbottom to the window
292: // through a two sided line.
293: // OPTIMIZE: keep this precalculated
294: //
295: fixed_t opentop;
296: fixed_t openbottom;
297: fixed_t openrange;
298: fixed_t lowfloor;
299:
1.1 root 300:
1.1.1.4 root 301: void P_LineOpening (line_t* linedef)
1.1 root 302: {
1.1.1.4 root 303: sector_t* front;
304: sector_t* back;
305:
306: if (linedef->sidenum[1] == -1)
307: {
308: // single sided line
309: openrange = 0;
310: return;
311: }
312:
313: front = linedef->frontsector;
314: back = linedef->backsector;
315:
316: if (front->ceilingheight < back->ceilingheight)
317: opentop = front->ceilingheight;
318: else
319: opentop = back->ceilingheight;
320:
321: if (front->floorheight > back->floorheight)
322: {
323: openbottom = front->floorheight;
324: lowfloor = back->floorheight;
325: }
326: else
327: {
328: openbottom = back->floorheight;
329: lowfloor = front->floorheight;
330: }
331:
332: openrange = opentop - openbottom;
333: }
1.1.1.3 root 334:
335:
1.1.1.4 root 336: //
337: // THING POSITION SETTING
338: //
339:
340:
341: //
342: // P_UnsetThingPosition
343: // Unlinks a thing from block map and sectors.
344: // On each position change, BLOCKMAP and other
345: // lookups maintaining lists ot things inside
346: // these structures need to be updated.
347: //
348: void P_UnsetThingPosition (mobj_t* thing)
349: {
350: int blockx;
351: int blocky;
352:
353: if ( ! (thing->flags & MF_NOSECTOR) )
354: {
355: // inert things don't need to be in blockmap?
356: // unlink from subsector
357: if (thing->snext)
358: thing->snext->sprev = thing->sprev;
1.1.1.3 root 359:
1.1.1.4 root 360: if (thing->sprev)
361: thing->sprev->snext = thing->snext;
1.1 root 362: else
1.1.1.4 root 363: thing->subsector->sector->thinglist = thing->snext;
364: }
365:
366: if ( ! (thing->flags & MF_NOBLOCKMAP) )
367: {
368: // inert things don't need to be in blockmap
369: // unlink from block map
370: if (thing->bnext)
371: thing->bnext->bprev = thing->bprev;
372:
373: if (thing->bprev)
374: thing->bprev->bnext = thing->bnext;
1.1 root 375: else
376: {
1.1.1.4 root 377: blockx = (thing->x - bmaporgx)>>MAPBLOCKSHIFT;
378: blocky = (thing->y - bmaporgy)>>MAPBLOCKSHIFT;
1.1.1.3 root 379:
1.1.1.4 root 380: if (blockx>=0 && blockx < bmapwidth
381: && blocky>=0 && blocky <bmapheight)
382: {
383: blocklinks[blocky*bmapwidth+blockx] = thing->bnext;
384: }
385: }
386: }
1.1 root 387: }
388:
389:
1.1.1.4 root 390: //
391: // P_SetThingPosition
392: // Links a thing into both a block and a subsector
393: // based on it's x y.
394: // Sets thing->subsector properly
395: //
396: void
397: P_SetThingPosition (mobj_t* thing)
398: {
399: subsector_t* ss;
400: sector_t* sec;
401: int blockx;
402: int blocky;
403: mobj_t** link;
404:
405:
406: // link into subsector
407: ss = R_PointInSubsector (thing->x,thing->y);
408: thing->subsector = ss;
409:
410: if ( ! (thing->flags & MF_NOSECTOR) )
411: {
412: // invisible things don't go into the sector links
413: sec = ss->sector;
414:
415: thing->sprev = NULL;
416: thing->snext = sec->thinglist;
1.1 root 417:
1.1.1.4 root 418: if (sec->thinglist)
419: sec->thinglist->sprev = thing;
1.1 root 420:
1.1.1.4 root 421: sec->thinglist = thing;
422: }
1.1 root 423:
1.1.1.4 root 424:
425: // link into blockmap
426: if ( ! (thing->flags & MF_NOBLOCKMAP) )
427: {
428: // inert things don't need to be in blockmap
429: blockx = (thing->x - bmaporgx)>>MAPBLOCKSHIFT;
430: blocky = (thing->y - bmaporgy)>>MAPBLOCKSHIFT;
431:
432: if (blockx>=0
433: && blockx < bmapwidth
434: && blocky>=0
435: && blocky < bmapheight)
436: {
437: link = &blocklinks[blocky*bmapwidth+blockx];
438: thing->bprev = NULL;
439: thing->bnext = *link;
440: if (*link)
441: (*link)->bprev = thing;
1.1 root 442:
1.1.1.4 root 443: *link = thing;
1.1 root 444: }
1.1.1.4 root 445: else
446: {
447: // thing is off the map
448: thing->bnext = thing->bprev = NULL;
1.1 root 449: }
1.1.1.4 root 450: }
1.1 root 451: }
452:
453:
1.1.1.3 root 454:
1.1.1.2 root 455: //
1.1.1.4 root 456: // BLOCK MAP ITERATORS
457: // For each line/thing in the given mapblock,
458: // call the passed PIT_* function.
459: // If the function returns false,
460: // exit with false without checking anything else.
1.1.1.2 root 461: //
1.1 root 462:
463:
1.1.1.4 root 464: //
465: // P_BlockLinesIterator
466: // The validcount flags are used to avoid checking lines
467: // that are marked in multiple mapblocks,
468: // so increment validcount before the first call
469: // to P_BlockLinesIterator, then make one or more calls
470: // to it.
471: //
472: boolean
473: P_BlockLinesIterator
474: ( int x,
475: int y,
476: boolean(*func)(line_t*) )
1.1 root 477: {
1.1.1.4 root 478: int offset;
479: short* list;
480: line_t* ld;
481:
482: if (x<0
483: || y<0
484: || x>=bmapwidth
485: || y>=bmapheight)
486: {
487: return true;
488: }
489:
490: offset = y*bmapwidth+x;
491:
492: offset = *(blockmap+offset);
1.1 root 493:
1.1.1.4 root 494: for ( list = blockmaplump+offset ; *list != -1 ; list++)
495: {
496: ld = &lines[*list];
1.1.1.3 root 497:
1.1.1.4 root 498: if (ld->validcount == validcount)
499: continue; // line has already been checked
1.1.1.3 root 500:
1.1.1.4 root 501: ld->validcount = validcount;
502:
503: if ( !func(ld) )
504: return false;
505: }
506: return true; // everything was checked
1.1 root 507: }
508:
509:
1.1.1.4 root 510: //
511: // P_BlockThingsIterator
512: //
513: boolean
514: P_BlockThingsIterator
515: ( int x,
516: int y,
517: boolean(*func)(mobj_t*) )
1.1 root 518: {
1.1.1.4 root 519: mobj_t* mobj;
520:
521: if ( x<0
522: || y<0
523: || x>=bmapwidth
524: || y>=bmapheight)
525: {
1.1 root 526: return true;
1.1.1.4 root 527: }
528:
529:
530: for (mobj = blocklinks[y*bmapwidth+x] ;
531: mobj ;
532: mobj = mobj->bnext)
533: {
534: if (!func( mobj ) )
535: return false;
536: }
537: return true;
1.1 root 538: }
539:
1.1.1.2 root 540:
541:
1.1.1.4 root 542: //
543: // INTERCEPT ROUTINES
544: //
545: intercept_t intercepts[MAXINTERCEPTS];
546: intercept_t* intercept_p;
1.1.1.2 root 547:
1.1.1.4 root 548: divline_t trace;
549: boolean earlyout;
550: int ptflags;
1.1.1.2 root 551:
552: //
1.1.1.4 root 553: // PIT_AddLineIntercepts.
554: // Looks for lines in the given block
555: // that intercept the given trace
556: // to add to the intercepts list.
1.1.1.2 root 557: //
1.1.1.4 root 558: // A line is crossed if its endpoints
559: // are on opposite sides of the trace.
560: // Returns true if earlyout and a solid line hit.
561: //
562: boolean
563: PIT_AddLineIntercepts (line_t* ld)
564: {
565: int s1;
566: int s2;
567: fixed_t frac;
568: divline_t dl;
569:
570: // avoid precision problems with two routines
571: if ( trace.dx > FRACUNIT*16
572: || trace.dy > FRACUNIT*16
573: || trace.dx < -FRACUNIT*16
574: || trace.dy < -FRACUNIT*16)
575: {
576: s1 = P_PointOnDivlineSide (ld->v1->x, ld->v1->y, &trace);
577: s2 = P_PointOnDivlineSide (ld->v2->x, ld->v2->y, &trace);
578: }
579: else
580: {
581: s1 = P_PointOnLineSide (trace.x, trace.y, ld);
582: s2 = P_PointOnLineSide (trace.x+trace.dx, trace.y+trace.dy, ld);
583: }
584:
585: if (s1 == s2)
586: return true; // line isn't crossed
587:
588: // hit the line
589: P_MakeDivline (ld, &dl);
590: frac = P_InterceptVector (&trace, &dl);
1.1.1.3 root 591:
1.1.1.4 root 592: if (frac < 0)
593: return true; // behind source
594:
595: // try to early out the check
596: if (earlyout
597: && frac < FRACUNIT
598: && !ld->backsector)
599: {
600: return false; // stop checking
601: }
602:
603:
604: intercept_p->frac = frac;
605: intercept_p->isaline = true;
606: intercept_p->d.line = ld;
607: intercept_p++;
1.1.1.2 root 608:
1.1.1.4 root 609: return true; // continue
1.1.1.2 root 610: }
611:
612:
613:
1.1.1.4 root 614: //
615: // PIT_AddThingIntercepts
616: //
617: boolean PIT_AddThingIntercepts (mobj_t* thing)
1.1.1.2 root 618: {
1.1.1.4 root 619: fixed_t x1;
620: fixed_t y1;
621: fixed_t x2;
622: fixed_t y2;
623:
624: int s1;
625: int s2;
626:
627: boolean tracepositive;
1.1.1.3 root 628:
1.1.1.4 root 629: divline_t dl;
630:
631: fixed_t frac;
632:
633: tracepositive = (trace.dx ^ trace.dy)>0;
634:
635: // check a corner to corner crossection for hit
636: if (tracepositive)
637: {
638: x1 = thing->x - thing->radius;
639: y1 = thing->y + thing->radius;
640:
641: x2 = thing->x + thing->radius;
642: y2 = thing->y - thing->radius;
643: }
644: else
645: {
646: x1 = thing->x - thing->radius;
647: y1 = thing->y - thing->radius;
648:
649: x2 = thing->x + thing->radius;
650: y2 = thing->y + thing->radius;
651: }
652:
653: s1 = P_PointOnDivlineSide (x1, y1, &trace);
654: s2 = P_PointOnDivlineSide (x2, y2, &trace);
1.1.1.2 root 655:
1.1.1.4 root 656: if (s1 == s2)
657: return true; // line isn't crossed
658:
659: dl.x = x1;
660: dl.y = y1;
661: dl.dx = x2-x1;
662: dl.dy = y2-y1;
663:
664: frac = P_InterceptVector (&trace, &dl);
665:
666: if (frac < 0)
667: return true; // behind source
668:
669: intercept_p->frac = frac;
670: intercept_p->isaline = false;
671: intercept_p->d.thing = thing;
672: intercept_p++;
673:
674: return true; // keep going
1.1.1.2 root 675: }
676:
677:
1.1.1.4 root 678: //
679: // P_TraverseIntercepts
680: // Returns true if the traverser function returns true
681: // for all lines.
682: //
683: boolean
684: P_TraverseIntercepts
685: ( traverser_t func,
686: fixed_t maxfrac )
687: {
688: int count;
689: fixed_t dist;
690: intercept_t* scan;
691: intercept_t* in;
692:
693: count = intercept_p - intercepts;
694:
695: in = 0; // shut up compiler warning
696:
697: while (count--)
698: {
699: dist = MAXINT;
700: for (scan = intercepts ; scan<intercept_p ; scan++)
701: {
702: if (scan->frac < dist)
703: {
704: dist = scan->frac;
705: in = scan;
706: }
707: }
708:
709: if (dist > maxfrac)
710: return true; // checked everything in range
1.1.1.3 root 711:
1.1.1.4 root 712: #if 0 // UNUSED
713: {
714: // don't check these yet, there may be others inserted
715: in = scan = intercepts;
716: for ( scan = intercepts ; scan<intercept_p ; scan++)
717: if (scan->frac > maxfrac)
718: *in++ = *scan;
719: intercept_p = in;
720: return false;
721: }
1.1.1.2 root 722: #endif
723:
1.1.1.4 root 724: if ( !func (in) )
725: return false; // don't bother going farther
1.1.1.3 root 726:
1.1.1.4 root 727: in->frac = MAXINT;
728: }
729:
730: return true; // everything was traversed
1.1.1.2 root 731: }
732:
733:
734:
735:
1.1.1.4 root 736: //
737: // P_PathTraverse
738: // Traces a line from x1,y1 to x2,y2,
739: // calling the traverser function for each.
740: // Returns true if the traverser function returns true
741: // for all lines.
742: //
743: boolean
744: P_PathTraverse
745: ( fixed_t x1,
746: fixed_t y1,
747: fixed_t x2,
748: fixed_t y2,
749: int flags,
750: boolean (*trav) (intercept_t *))
751: {
752: fixed_t xt1;
753: fixed_t yt1;
754: fixed_t xt2;
755: fixed_t yt2;
756:
757: fixed_t xstep;
758: fixed_t ystep;
759:
760: fixed_t partial;
761:
762: fixed_t xintercept;
763: fixed_t yintercept;
764:
765: int mapx;
766: int mapy;
767:
768: int mapxstep;
769: int mapystep;
1.1.1.2 root 770:
1.1.1.4 root 771: int count;
772:
773: earlyout = flags & PT_EARLYOUT;
774:
775: validcount++;
776: intercept_p = intercepts;
777:
778: if ( ((x1-bmaporgx)&(MAPBLOCKSIZE-1)) == 0)
779: x1 += FRACUNIT; // don't side exactly on a line
780:
781: if ( ((y1-bmaporgy)&(MAPBLOCKSIZE-1)) == 0)
782: y1 += FRACUNIT; // don't side exactly on a line
783:
784: trace.x = x1;
785: trace.y = y1;
786: trace.dx = x2 - x1;
787: trace.dy = y2 - y1;
788:
789: x1 -= bmaporgx;
790: y1 -= bmaporgy;
791: xt1 = x1>>MAPBLOCKSHIFT;
792: yt1 = y1>>MAPBLOCKSHIFT;
793:
794: x2 -= bmaporgx;
795: y2 -= bmaporgy;
796: xt2 = x2>>MAPBLOCKSHIFT;
797: yt2 = y2>>MAPBLOCKSHIFT;
798:
799: if (xt2 > xt1)
800: {
801: mapxstep = 1;
802: partial = FRACUNIT - ((x1>>MAPBTOFRAC)&(FRACUNIT-1));
803: ystep = FixedDiv (y2-y1,abs(x2-x1));
804: }
805: else if (xt2 < xt1)
806: {
807: mapxstep = -1;
808: partial = (x1>>MAPBTOFRAC)&(FRACUNIT-1);
809: ystep = FixedDiv (y2-y1,abs(x2-x1));
810: }
811: else
812: {
813: mapxstep = 0;
814: partial = FRACUNIT;
815: ystep = 256*FRACUNIT;
816: }
1.1.1.2 root 817:
1.1.1.4 root 818: yintercept = (y1>>MAPBTOFRAC) + FixedMul (partial, ystep);
1.1.1.3 root 819:
1.1.1.4 root 820:
821: if (yt2 > yt1)
822: {
823: mapystep = 1;
824: partial = FRACUNIT - ((y1>>MAPBTOFRAC)&(FRACUNIT-1));
825: xstep = FixedDiv (x2-x1,abs(y2-y1));
826: }
827: else if (yt2 < yt1)
828: {
829: mapystep = -1;
830: partial = (y1>>MAPBTOFRAC)&(FRACUNIT-1);
831: xstep = FixedDiv (x2-x1,abs(y2-y1));
832: }
833: else
834: {
835: mapystep = 0;
836: partial = FRACUNIT;
837: xstep = 256*FRACUNIT;
838: }
839: xintercept = (x1>>MAPBTOFRAC) + FixedMul (partial, xstep);
840:
841: // Step through map blocks.
842: // Count is present to prevent a round off error
843: // from skipping the break.
844: mapx = xt1;
845: mapy = yt1;
846:
847: for (count = 0 ; count < 64 ; count++)
848: {
849: if (flags & PT_ADDLINES)
1.1.1.2 root 850: {
1.1.1.4 root 851: if (!P_BlockLinesIterator (mapx, mapy,PIT_AddLineIntercepts))
852: return false; // early out
1.1.1.2 root 853: }
854:
1.1.1.4 root 855: if (flags & PT_ADDTHINGS)
1.1.1.2 root 856: {
1.1.1.4 root 857: if (!P_BlockThingsIterator (mapx, mapy,PIT_AddThingIntercepts))
858: return false; // early out
859: }
1.1.1.2 root 860:
1.1.1.4 root 861: if (mapx == xt2
862: && mapy == yt2)
863: {
864: break;
1.1.1.2 root 865: }
1.1.1.3 root 866:
1.1.1.4 root 867: if ( (yintercept >> FRACBITS) == mapy)
1.1.1.3 root 868: {
1.1.1.4 root 869: yintercept += ystep;
870: mapx += mapxstep;
1.1.1.3 root 871: }
1.1.1.4 root 872: else if ( (xintercept >> FRACBITS) == mapx)
1.1.1.3 root 873: {
1.1.1.4 root 874: xintercept += xstep;
875: mapy += mapystep;
1.1.1.3 root 876: }
1.1.1.4 root 877:
878: }
879: // go through the sorted list
880: return P_TraverseIntercepts ( trav, FRACUNIT );
1.1.1.3 root 881: }
882:
883:
884:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.