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