|
|
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.