123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560 |
- #include "Precompiled.h"
- #include "globaldata.h"
- #include "doomdef.h"
- #include "m_bbox.h"
- #include "i_system.h"
- #include "r_main.h"
- #include "r_plane.h"
- #include "r_things.h"
- #include "doomstat.h"
- #include "r_state.h"
- void
- R_StoreWallRange
- ( int start,
- int stop );
- void R_ClearDrawSegs (void)
- {
- ::g->ds_p = ::g->drawsegs;
- }
- void
- R_ClipSolidWallSegment
- ( int first,
- int last )
- {
- cliprange_t* next;
- cliprange_t* start;
-
-
- start = ::g->solidsegs;
- while (start->last < first-1)
- start++;
- if (first < start->first)
- {
- if (last < start->first-1)
- {
-
-
- R_StoreWallRange (first, last);
- next = ::g->newend;
- ::g->newend++;
-
- while (next != start)
- {
- *next = *(next-1);
- next--;
- }
- next->first = first;
- next->last = last;
- return;
- }
-
-
- R_StoreWallRange (first, start->first - 1);
-
- start->first = first;
- }
-
- if (last <= start->last)
- return;
-
- next = start;
- while (last >= (next+1)->first-1)
- {
-
- R_StoreWallRange (next->last + 1, (next+1)->first - 1);
- next++;
-
- if (last <= next->last)
- {
-
-
- start->last = next->last;
- goto crunch;
- }
- }
-
-
- R_StoreWallRange (next->last + 1, last);
-
- start->last = last;
-
-
-
- crunch:
- if (next == start)
- {
-
- return;
- }
-
- while (next++ != ::g->newend)
- {
-
- *++start = *next;
- }
- ::g->newend = start+1;
- }
- void
- R_ClipPassWallSegment
- ( int first,
- int last )
- {
- cliprange_t* start;
-
-
- start = ::g->solidsegs;
- while (start->last < first-1)
- start++;
- if (first < start->first)
- {
- if (last < start->first-1)
- {
-
- R_StoreWallRange (first, last);
- return;
- }
-
-
- R_StoreWallRange (first, start->first - 1);
- }
-
- if (last <= start->last)
- return;
-
- while (last >= (start+1)->first-1)
- {
-
- R_StoreWallRange (start->last + 1, (start+1)->first - 1);
- start++;
-
- if (last <= start->last)
- return;
- }
-
-
- R_StoreWallRange (start->last + 1, last);
- }
- void R_ClearClipSegs (void)
- {
- ::g->solidsegs[0].first = -0x7fffffff;
- ::g->solidsegs[0].last = -1;
- ::g->solidsegs[1].first = ::g->viewwidth;
- ::g->solidsegs[1].last = 0x7fffffff;
- ::g->newend = ::g->solidsegs+2;
- }
- void R_AddLine (seg_t* line)
- {
- int x1;
- int x2;
- angle_t angle1;
- angle_t angle2;
- angle_t span;
- angle_t tspan;
-
- ::g->curline = line;
-
- angle1 = R_PointToAngle (line->v1->x, line->v1->y);
- angle2 = R_PointToAngle (line->v2->x, line->v2->y);
-
-
-
- span = angle1 - angle2;
-
-
- if (span >= ANG180)
- return;
- extern angle_t GetViewAngle();
-
- ::g->rw_angle1 = angle1;
- angle1 -= GetViewAngle();
- angle2 -= GetViewAngle();
-
- tspan = angle1 + ::g->clipangle;
- if (tspan > 2*::g->clipangle)
- {
- tspan -= 2*::g->clipangle;
-
- if (tspan >= span)
- return;
-
- angle1 = ::g->clipangle;
- }
- tspan = ::g->clipangle - angle2;
- if (tspan > 2*::g->clipangle)
- {
- tspan -= 2*::g->clipangle;
-
- if (tspan >= span)
- return;
- angle2 = -::g->clipangle;
- }
-
-
-
- angle1 = (angle1+ANG90)>>ANGLETOFINESHIFT;
- angle2 = (angle2+ANG90)>>ANGLETOFINESHIFT;
- x1 = ::g->viewangletox[angle1];
- x2 = ::g->viewangletox[angle2];
-
- if (x1 == x2)
- return;
-
- ::g->backsector = line->backsector;
-
- if (!::g->backsector)
- goto clipsolid;
-
- if (::g->backsector->ceilingheight <= ::g->frontsector->floorheight
- || ::g->backsector->floorheight >= ::g->frontsector->ceilingheight)
- goto clipsolid;
-
- if (::g->backsector->ceilingheight != ::g->frontsector->ceilingheight
- || ::g->backsector->floorheight != ::g->frontsector->floorheight)
- goto clippass;
-
-
-
-
-
-
- if (::g->backsector->ceilingpic == ::g->frontsector->ceilingpic
- && ::g->backsector->floorpic == ::g->frontsector->floorpic
- && ::g->backsector->lightlevel == ::g->frontsector->lightlevel
- && ::g->curline->sidedef->midtexture == 0)
- {
- return;
- }
-
-
- clippass:
- R_ClipPassWallSegment (x1, x2-1);
- return;
-
- clipsolid:
- R_ClipSolidWallSegment (x1, x2-1);
- }
- qboolean R_CheckBBox (fixed_t* bspcoord)
- {
- int boxx;
- int boxy;
- int boxpos;
- fixed_t x1;
- fixed_t y1;
- fixed_t x2;
- fixed_t y2;
-
- angle_t angle1;
- angle_t angle2;
- angle_t span;
- angle_t tspan;
-
- cliprange_t* start;
- int sx1;
- int sx2;
- extern fixed_t GetViewX(); extern fixed_t GetViewY();
-
-
- if (GetViewX() <= bspcoord[BOXLEFT])
- boxx = 0;
- else if (GetViewX() < bspcoord[BOXRIGHT])
- boxx = 1;
- else
- boxx = 2;
-
- if (GetViewY() >= bspcoord[BOXTOP])
- boxy = 0;
- else if (GetViewY() > bspcoord[BOXBOTTOM])
- boxy = 1;
- else
- boxy = 2;
-
- boxpos = (boxy<<2)+boxx;
- if (boxpos == 5)
- return true;
-
- x1 = bspcoord[::g->checkcoord[boxpos][0]];
- y1 = bspcoord[::g->checkcoord[boxpos][1]];
- x2 = bspcoord[::g->checkcoord[boxpos][2]];
- y2 = bspcoord[::g->checkcoord[boxpos][3]];
-
-
- extern angle_t GetViewAngle();
- angle1 = R_PointToAngle (x1, y1) - GetViewAngle();
- angle2 = R_PointToAngle (x2, y2) - GetViewAngle();
-
- span = angle1 - angle2;
-
- if (span >= ANG180)
- return true;
-
- tspan = angle1 + ::g->clipangle;
- if (tspan > 2*::g->clipangle)
- {
- tspan -= 2*::g->clipangle;
-
- if (tspan >= span)
- return false;
- angle1 = ::g->clipangle;
- }
- tspan = ::g->clipangle - angle2;
- if (tspan > 2*::g->clipangle)
- {
- tspan -= 2*::g->clipangle;
-
- if (tspan >= span)
- return false;
-
- angle2 = -::g->clipangle;
- }
-
-
-
- angle1 = (angle1+ANG90)>>ANGLETOFINESHIFT;
- angle2 = (angle2+ANG90)>>ANGLETOFINESHIFT;
- sx1 = ::g->viewangletox[angle1];
- sx2 = ::g->viewangletox[angle2];
-
- if (sx1 == sx2)
- return false;
- sx2--;
-
- start = ::g->solidsegs;
- while (start->last < sx2)
- start++;
-
- if (sx1 >= start->first
- && sx2 <= start->last)
- {
-
- return false;
- }
- return true;
- }
- void R_Subsector (int num)
- {
- int count;
- seg_t* line;
- subsector_t* sub;
-
- #ifdef RANGECHECK
- if (num>=::g->numsubsectors)
- I_Error ("R_Subsector: ss %i with numss = %i",
- num,
- ::g->numsubsectors);
- #endif
- ::g->sscount++;
- sub = &::g->subsectors[num];
- ::g->frontsector = sub->sector;
- count = sub->numlines;
- line = &::g->segs[sub->firstline];
- if (::g->frontsector->floorheight < ::g->viewz)
- {
- ::g->floorplane = R_FindPlane (::g->frontsector->floorheight,
- ::g->frontsector->floorpic,
- ::g->frontsector->lightlevel);
- }
- else
- ::g->floorplane = NULL;
-
- if (::g->frontsector->ceilingheight > ::g->viewz
- || ::g->frontsector->ceilingpic == ::g->skyflatnum)
- {
- ::g->ceilingplane = R_FindPlane (::g->frontsector->ceilingheight,
- ::g->frontsector->ceilingpic,
- ::g->frontsector->lightlevel);
- }
- else
- ::g->ceilingplane = NULL;
-
- R_AddSprites (::g->frontsector);
- while (count--)
- {
- R_AddLine (line);
- line++;
- }
- }
- void R_RenderBSPNode (int bspnum)
- {
- node_t* bsp;
- int side;
-
- if (bspnum & NF_SUBSECTOR)
- {
- if (bspnum == -1)
- R_Subsector (0);
- else
- R_Subsector (bspnum&(~NF_SUBSECTOR));
- return;
- }
-
- bsp = &::g->nodes[bspnum];
-
- extern fixed_t GetViewX(); extern fixed_t GetViewY();
-
- side = R_PointOnSide (GetViewX(), GetViewY(), bsp);
-
- R_RenderBSPNode (bsp->children[side]);
-
- if (R_CheckBBox (bsp->bbox[side^1]))
- R_RenderBSPNode (bsp->children[side^1]);
- }
|