|
|
1.1 root 1:
2: /* P_maputl.c */
3:
4: #include "doomdef.h"
5: #include "p_local.h"
6:
7:
8: /*
9: ===================
10: =
11: = P_AproxDistance
12: =
13: = Gives an estimation of distance (not exact)
14: =
15: ===================
16: */
17:
18: fixed_t P_AproxDistance (fixed_t dx, fixed_t dy)
19: {
20: dx = abs(dx);
21: dy = abs(dy);
22: if (dx < dy)
23: return dx+dy-(dx>>1);
24: return dx+dy-(dy>>1);
25: }
26:
27:
28: /*
29: ==================
30: =
31: = P_PointOnLineSide
32: =
33: = Returns 0 or 1
34: ==================
35: */
36:
37: int P_PointOnLineSide (fixed_t x, fixed_t y, line_t *line)
38: {
39: fixed_t dx,dy;
40: fixed_t left, right;
41:
42: if (!line->dx)
43: {
44: if (x <= line->v1->x)
45: return line->dy > 0;
46: return line->dy < 0;
47: }
48: if (!line->dy)
49: {
50: if (y <= line->v1->y)
51: return line->dx < 0;
52: return line->dx > 0;
53: }
54:
55: dx = (x - line->v1->x);
56: dy = (y - line->v1->y);
57:
58: left = (line->dy>>16) * (dx>>16);
59: right = (dy>>16) * (line->dx>>16);
60:
61: if (right < left)
62: return 0; /* front side */
63: return 1; /* back side */
64: }
65:
66:
67: /*
68: ==================
69: =
70: = P_PointOnDivlineSide
71: =
72: = Returns 0 or 1
73: ==================
74: */
75:
76: int P_PointOnDivlineSide (fixed_t x, fixed_t y, divline_t *line)
77: {
78: fixed_t dx,dy;
79: fixed_t left, right;
80:
81: if (!line->dx)
82: {
83: if (x <= line->x)
84: return line->dy > 0;
85: return line->dy < 0;
86: }
87: if (!line->dy)
88: {
89: if (y <= line->y)
90: return line->dx < 0;
91: return line->dx > 0;
92: }
93:
94: dx = (x - line->x);
95: dy = (y - line->y);
96:
97: /* try to quickly decide by looking at sign bits */
98: if ( (line->dy ^ line->dx ^ dx ^ dy)&0x80000000 )
99: {
100: if ( (line->dy ^ dx) & 0x80000000 )
101: return 1; /* (left is negative) */
102: return 0;
103: }
104:
105: left = FixedMul ( line->dy>>8, dx>>8 );
106: right = FixedMul ( dy>>8 , line->dx>>8 );
107:
108: if (right < left)
109: return 0; /* front side */
110: return 1; /* back side */
111: }
112:
113:
114:
115: /*
116: ==============
117: =
118: = P_MakeDivline
119: =
120: ==============
121: */
122:
123: void P_MakeDivline (line_t *li, divline_t *dl)
124: {
125: dl->x = li->v1->x;
126: dl->y = li->v1->y;
127: dl->dx = li->dx;
128: dl->dy = li->dy;
129: }
130:
131:
132: /*
133: ==================
134: =
135: = P_LineOpening
136: =
137: = Sets opentop and openbottom to the window through a two sided line
138: = OPTIMIZE: keep this precalculated
139: ==================
140: */
141:
142: fixed_t opentop, openbottom, openrange;
143: fixed_t lowfloor;
144:
145: void P_LineOpening (line_t *linedef)
146: {
147: sector_t *front, *back;
148:
149: if (linedef->sidenum[1] == -1)
150: { /* single sided line */
151: openrange = 0;
152: return;
153: }
154:
155: front = linedef->frontsector;
156: back = linedef->backsector;
157:
158: if (front->ceilingheight < back->ceilingheight)
159: opentop = front->ceilingheight;
160: else
161: opentop = back->ceilingheight;
162: if (front->floorheight > back->floorheight)
163: {
164: openbottom = front->floorheight;
165: lowfloor = back->floorheight;
166: }
167: else
168: {
169: openbottom = back->floorheight;
170: lowfloor = front->floorheight;
171: }
172:
173: openrange = opentop - openbottom;
174: }
175:
176: /*
177: ===============================================================================
178:
179: THING POSITION SETTING
180:
181: ===============================================================================
182: */
183:
184: /*
185: ===================
186: =
187: = P_UnsetThingPosition
188: =
189: = Unlinks a thing from block map and sectors
190: =
191: ===================
192: */
193:
194: void P_UnsetThingPosition (mobj_t *thing)
195: {
196: int blockx, blocky;
197:
198: if ( ! (thing->flags & MF_NOSECTOR) )
199: { /* inert things don't need to be in blockmap */
200: /* unlink from subsector */
201: if (thing->snext)
202: thing->snext->sprev = thing->sprev;
203: if (thing->sprev)
204: thing->sprev->snext = thing->snext;
205: else
206: thing->subsector->sector->thinglist = thing->snext;
207: }
208:
209: if ( ! (thing->flags & MF_NOBLOCKMAP) )
210: { /* inert things don't need to be in blockmap */
211: /* unlink from block map */
212: if (thing->bnext)
213: thing->bnext->bprev = thing->bprev;
214: if (thing->bprev)
215: thing->bprev->bnext = thing->bnext;
216: else
217: {
218: blockx = (thing->x - bmaporgx)>>MAPBLOCKSHIFT;
219: blocky = (thing->y - bmaporgy)>>MAPBLOCKSHIFT;
220: blocklinks[blocky*bmapwidth+blockx] = thing->bnext;
221: }
222: }
223: }
224:
225:
226: /*
227: ===================
228: =
229: = P_SetThingPosition
230: =
231: = Links a thing into both a block and a subsector based on it's x y
232: = Sets thing->subsector properly
233: =
234: ===================
235: */
236:
237: void P_SetThingPosition (mobj_t *thing)
238: {
239: subsector_t *ss;
240: sector_t *sec;
241: int blockx, blocky;
242: mobj_t **link;
243:
244: /* */
245: /* link into subsector */
246: /* */
247: ss = R_PointInSubsector (thing->x,thing->y);
248: thing->subsector = ss;
249: if ( ! (thing->flags & MF_NOSECTOR) )
250: { /* invisible things don't go into the sector links */
251: sec = ss->sector;
252:
253: thing->sprev = NULL;
254: thing->snext = sec->thinglist;
255: if (sec->thinglist)
256: sec->thinglist->sprev = thing;
257: sec->thinglist = thing;
258: }
259:
260: /* */
261: /* link into blockmap */
262: /* */
263: if ( ! (thing->flags & MF_NOBLOCKMAP) )
264: { /* inert things don't need to be in blockmap */
265: blockx = (thing->x - bmaporgx)>>MAPBLOCKSHIFT;
266: blocky = (thing->y - bmaporgy)>>MAPBLOCKSHIFT;
267: if (blockx>=0 && blockx < bmapwidth && blocky>=0 && blocky <bmapheight)
268: {
269: link = &blocklinks[blocky*bmapwidth+blockx];
270: thing->bprev = NULL;
271: thing->bnext = *link;
272: if (*link)
273: (*link)->bprev = thing;
274: *link = thing;
275: }
276: else
277: { /* thing is off the map */
278: thing->bnext = thing->bprev = NULL;
279: }
280: }
281: }
282:
283:
284:
285: /*
286: ===============================================================================
287:
288: BLOCK MAP ITERATORS
289:
290: For each line/thing in the given mapblock, call the passed function.
291: If the function returns false, exit with false without checking anything else.
292:
293: ===============================================================================
294: */
295:
296: /*
297: ==================
298: =
299: = P_BlockLinesIterator
300: =
301: = The validcount flags are used to avoid checking lines
302: = that are marked in multiple mapblocks, so increment validcount before
303: = the first call to P_BlockLinesIterator, then make one or more calls to it
304: ===================
305: */
306:
307: boolean P_BlockLinesIterator (int x, int y, boolean(*func)(line_t*) )
308: {
309: int offset;
310: short *list;
311: line_t *ld;
312:
313: if (x<0 || y<0 || x>=bmapwidth || y>=bmapheight)
314: return true;
315: offset = y*bmapwidth+x;
316:
317: offset = *(blockmap+offset);
318:
319: for ( list = blockmaplump+offset ; *list != -1 ; list++)
320: {
321: ld = &lines[*list];
322: if (ld->validcount == validcount)
323: continue; /* line has already been checked */
324: ld->validcount = validcount;
325:
326: if ( !func(ld) )
327: return false;
328: }
329:
330: return true; /* everything was checked */
331: }
332:
333:
334: /*
335: ==================
336: =
337: = P_BlockThingsIterator
338: =
339: ==================
340: */
341:
342: boolean P_BlockThingsIterator (int x, int y, boolean(*func)(mobj_t*) )
343: {
344: mobj_t *mobj;
345:
346: if (x<0 || y<0 || x>=bmapwidth || y>=bmapheight)
347: return true;
348:
349: for (mobj = blocklinks[y*bmapwidth+x] ; mobj ; mobj = mobj->bnext)
350: if (!func( mobj ) )
351: return false;
352:
353: return true;
354: }
355:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.