123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349 |
- #include "Precompiled.h"
- #include "globaldata.h"
- #include "doomdef.h"
- #include "i_system.h"
- #include "p_local.h"
- #include "r_state.h"
- int
- P_DivlineSide
- ( fixed_t x,
- fixed_t y,
- divline_t* node )
- {
- fixed_t dx;
- fixed_t dy;
- fixed_t left;
- fixed_t right;
- if (!node->dx)
- {
- if (x==node->x)
- return 2;
-
- if (x <= node->x)
- return node->dy > 0;
- return node->dy < 0;
- }
-
- if (!node->dy)
- {
- if (x==node->y)
- return 2;
- if (y <= node->y)
- return node->dx < 0;
- return node->dx > 0;
- }
-
- dx = (x - node->x);
- dy = (y - node->y);
- left = (node->dy>>FRACBITS) * (dx>>FRACBITS);
- right = (dy>>FRACBITS) * (node->dx>>FRACBITS);
-
- if (right < left)
- return 0;
-
- if (left == right)
- return 2;
- return 1;
- }
- fixed_t
- P_InterceptVector2
- ( divline_t* v2,
- divline_t* v1 )
- {
- 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;
-
-
- num = FixedMul ( (v1->x - v2->x)>>8 ,v1->dy) +
- FixedMul ( (v2->y - v1->y)>>8 , v1->dx);
- frac = FixedDiv (num , den);
- return frac;
- }
- qboolean P_CrossSubsector (int num)
- {
- seg_t* seg;
- line_t* line;
- int s1;
- int s2;
- int count;
- subsector_t* sub;
- sector_t* front;
- sector_t* back;
- fixed_t psight_opentop;
- fixed_t psight_openbottom;
- divline_t divl;
- vertex_t* v1;
- vertex_t* v2;
- fixed_t frac;
- fixed_t slope;
-
- #ifdef RANGECHECK
- if (num>=::g->numsubsectors)
- I_Error ("P_CrossSubsector: ss %i with numss = %i",
- num,
- ::g->numsubsectors);
- #endif
- sub = &::g->subsectors[num];
-
-
- count = sub->numlines;
- seg = &::g->segs[sub->firstline];
- for ( ; count ; seg++, count--)
- {
- line = seg->linedef;
-
- if (line->validcount == ::g->validcount)
- continue;
-
- line->validcount = ::g->validcount;
-
- v1 = line->v1;
- v2 = line->v2;
- s1 = P_DivlineSide (v1->x,v1->y, &::g->strace);
- s2 = P_DivlineSide (v2->x, v2->y, &::g->strace);
-
- if (s1 == s2)
- continue;
-
- divl.x = v1->x;
- divl.y = v1->y;
- divl.dx = v2->x - v1->x;
- divl.dy = v2->y - v1->y;
- s1 = P_DivlineSide (::g->strace.x, ::g->strace.y, &divl);
- s2 = P_DivlineSide (::g->t2x, ::g->t2y, &divl);
-
- if (s1 == s2)
- continue;
-
-
- if ( !(line->flags & ML_TWOSIDED) )
- return false;
-
-
- front = seg->frontsector;
- back = seg->backsector;
-
- if (front->floorheight == back->floorheight
- && front->ceilingheight == back->ceilingheight)
- continue;
-
-
- if (front->ceilingheight < back->ceilingheight)
- psight_opentop = front->ceilingheight;
- else
- psight_opentop = back->ceilingheight;
-
- if (front->floorheight > back->floorheight)
- psight_openbottom = front->floorheight;
- else
- psight_openbottom = back->floorheight;
-
-
- if (psight_openbottom >= psight_opentop)
- return false;
-
- frac = P_InterceptVector2 (&::g->strace, &divl);
-
- if (front->floorheight != back->floorheight)
- {
- slope = FixedDiv (psight_openbottom - ::g->sightzstart , frac);
- if (slope > ::g->bottomslope)
- ::g->bottomslope = slope;
- }
-
- if (front->ceilingheight != back->ceilingheight)
- {
- slope = FixedDiv (psight_opentop - ::g->sightzstart , frac);
- if (slope < ::g->topslope)
- ::g->topslope = slope;
- }
-
- if (::g->topslope <= ::g->bottomslope)
- return false;
- }
-
- return true;
- }
- qboolean P_CrossBSPNode (int bspnum)
- {
- node_t* bsp;
- int side;
- if (bspnum & NF_SUBSECTOR)
- {
- if (bspnum == -1)
- return P_CrossSubsector (0);
- else
- return P_CrossSubsector (bspnum&(~NF_SUBSECTOR));
- }
-
- bsp = &::g->nodes[bspnum];
-
-
- side = P_DivlineSide (::g->strace.x, ::g->strace.y, (divline_t *)bsp);
- if (side == 2)
- side = 0;
-
- if (!P_CrossBSPNode (bsp->children[side]) )
- return false;
-
-
- if (side == P_DivlineSide (::g->t2x, ::g->t2y,(divline_t *)bsp))
- {
-
- return true;
- }
-
-
- return P_CrossBSPNode (bsp->children[side^1]);
- }
- qboolean
- P_CheckSight
- ( mobj_t* t1,
- mobj_t* t2 )
- {
- int s1;
- int s2;
- int pnum;
- int bytenum;
- int bitnum;
-
-
-
- s1 = (t1->subsector->sector - ::g->sectors);
- s2 = (t2->subsector->sector - ::g->sectors);
- pnum = s1*::g->numsectors + s2;
- bytenum = pnum>>3;
- bitnum = 1 << (pnum&7);
-
- if (::g->rejectmatrix[bytenum]&bitnum)
- {
- ::g->sightcounts[0]++;
-
- return false;
- }
-
-
- ::g->sightcounts[1]++;
- ::g->validcount++;
-
- ::g->sightzstart = t1->z + t1->height - (t1->height>>2);
- ::g->topslope = (t2->z+t2->height) - ::g->sightzstart;
- ::g->bottomslope = (t2->z) - ::g->sightzstart;
-
- ::g->strace.x = t1->x;
- ::g->strace.y = t1->y;
- ::g->t2x = t2->x;
- ::g->t2y = t2->y;
- ::g->strace.dx = t2->x - t1->x;
- ::g->strace.dy = t2->y - t1->y;
-
- return P_CrossBSPNode (::g->numnodes-1);
- }
|