12 extern void R_RenderMap();
13 extern void R_DrawPlayerSprites();
22 int validcount = 1; // increment every time a check is made
24 lighttable_t *fixedcolormap;
25 extern lighttable_t **walllights;
28 fixed_t centerxfrac, centeryfrac;
31 int framecount; // just for profiling purposes
33 int sscount, linecount, loopcount;
35 fixed_t viewx, viewy, viewz;
37 fixed_t viewcos, viewsin;
41 float viewpitch; // player->lookdir, global version
44 int detailshift; // 0 = high, 1 = low
47 // precalculated math tables
51 // The viewangletox[viewangle + FINEANGLES/4] lookup maps the visible view
52 // angles to screen X coordinates, flattening the arc to a flat projection
53 // plane. There will be many angles mapped to the same X.
54 int viewangletox[FINEANGLES/2];
56 // The xtoviewangleangle[] table maps a screen pixel to the lowest viewangle
57 // that maps back to x ranges from clipangle to -clipangle
58 angle_t xtoviewangle[SCREENWIDTH+1];
60 // the finetangentgent[angle+FINEANGLES/4] table holds the fixed_t tangent
61 // values for view angles, ranging from MININT to 0 to MAXINT.
62 // fixed_t finetangent[FINEANGLES/2];
64 // fixed_t finesine[5*FINEANGLES/4];
65 fixed_t *finecosine = &finesine[FINEANGLES/4];
68 lighttable_t *scalelight[LIGHTLEVELS][MAXLIGHTSCALE];
69 lighttable_t *scalelightfixed[MAXLIGHTSCALE];
70 lighttable_t *zlight[LIGHTLEVELS][MAXLIGHTZ];
72 int extralight; // bumped light from gun blasts
74 void (*colfunc) (void);
75 void (*basecolfunc) (void);
76 void (*fuzzcolfunc) (void);
77 void (*transcolfunc) (void);
78 void (*spanfunc) (void);
88 void R_AddPointToBox (int x, int y, fixed_t *box)
94 if (y< box[BOXBOTTOM])
103 ===============================================================================
107 = Returns side 0 (front) or 1 (back)
108 ===============================================================================
111 int R_PointOnSide (fixed_t x, fixed_t y, node_t *node)
132 // try to quickly decide by looking at sign bits
133 if ( (node->dy ^ node->dx ^ dx ^ dy)&0x80000000 )
135 if ( (node->dy ^ dx) & 0x80000000 )
136 return 1; // (left is negative)
140 left = FixedMul ( node->dy>>FRACBITS , dx );
141 right = FixedMul ( dy , node->dx>>FRACBITS );
144 return 0; // front side
145 return 1; // back side
149 int R_PointOnSegSide (fixed_t x, fixed_t y, seg_t *line)
159 ldx = line->v2->x - lx;
160 ldy = line->v2->y - ly;
178 // try to quickly decide by looking at sign bits
179 if ( (ldy ^ ldx ^ dx ^ dy)&0x80000000 )
181 if ( (ldy ^ dx) & 0x80000000 )
182 return 1; // (left is negative)
186 left = FixedMul ( ldy>>FRACBITS , dx );
187 right = FixedMul ( dy , ldx>>FRACBITS );
190 return 0; // front side
191 return 1; // back side
196 ===============================================================================
200 ===============================================================================
203 // to get a global angle from cartesian coordinates, the coordinates are
204 // flipped until they are in the first octant of the coordinate system, then
205 // the y (<=x) is scaled and divided by x to get a tangent (slope) value
206 // which is looked up in the tantoangle[] table. The +1 size is to handle
207 // the case when x==y without additional checking.
208 #define SLOPERANGE 2048
210 #define DBITS (FRACBITS-SLOPEBITS)
213 extern int tantoangle[SLOPERANGE+1]; // get from tables.c
215 // int tantoangle[SLOPERANGE+1];
217 int SlopeDiv (unsigned num, unsigned den)
222 ans = (num<<3)/(den>>8);
223 return ans <= SLOPERANGE ? ans : SLOPERANGE;
226 angle_t R_PointToAngle (fixed_t x, fixed_t y)
237 return tantoangle[ SlopeDiv(y,x)]; // octant 0
239 return ANG90-1-tantoangle[ SlopeDiv(x,y)]; // octant 1
245 return -tantoangle[SlopeDiv(y,x)]; // octant 8
247 return ANG270+tantoangle[ SlopeDiv(x,y)]; // octant 7
256 return ANG180-1-tantoangle[ SlopeDiv(y,x)]; // octant 3
258 return ANG90+ tantoangle[ SlopeDiv(x,y)]; // octant 2
264 return ANG180+tantoangle[ SlopeDiv(y,x)]; // octant 4
266 return ANG270-1-tantoangle[ SlopeDiv(x,y)]; // octant 5
274 angle_t R_PointToAngle2 (fixed_t x1, fixed_t y1, fixed_t x2, fixed_t y2)
278 return R_PointToAngle (x2, y2);
282 fixed_t R_PointToDist (fixed_t x, fixed_t y)
285 fixed_t dx, dy, temp;
298 angle = (tantoangle[ FixedDiv(dy,dx)>>DBITS ]+ANG90) >> ANGLETOFINESHIFT;
300 dist = FixedDiv (dx, finesine[angle] ); // use as cosine
315 void R_InitPointToAngle (void)
317 // now getting from tables.c
323 // slope (tangent) to angle lookup
325 for (i=0 ; i<=SLOPERANGE ; i++)
327 f = atan( (float)i/SLOPERANGE )/(3.141592657*2);
334 //=============================================================================
339 = R_ScaleFromGlobalAngle
341 = Returns the texture mapping scale for the current line at the given angle
342 = rw_distance must be calculated first
346 fixed_t R_ScaleFromGlobalAngle (angle_t visangle)
358 sinv = finesine[(visangle-rw_normalangle)>>ANGLETOFINESHIFT];
359 dist = FixedDiv (rw_distance, sinv);
360 cosv = finecosine[(viewangle-visangle)>>ANGLETOFINESHIFT];
361 z = abs(FixedMul (dist, cosv));
362 scale = FixedDiv(projection, z);
367 anglea = ANG90 + (visangle-viewangle);
368 angleb = ANG90 + (visangle-rw_normalangle);
369 // bothe sines are allways positive
370 sinea = finesine[anglea>>ANGLETOFINESHIFT];
371 sineb = finesine[angleb>>ANGLETOFINESHIFT];
372 num = FixedMul(projection,sineb)<<detailshift;
373 den = FixedMul(rw_distance,sinea);
376 scale = FixedDiv (num, den);
377 if (scale > 64*FRACUNIT)
379 else if (scale < 256)
398 void R_InitTables (void)
400 // now getting from tables.c
407 // viewangle tangent table
409 for (i=0 ; i<FINEANGLES/2 ; i++)
411 a = (i-FINEANGLES/4+0.5)*PI*2/FINEANGLES;
412 fv = FRACUNIT*tan (a);
420 for (i=0 ; i<5*FINEANGLES/4 ; i++)
422 // OPTIMIZE: mirror...
423 a = (i+0.5)*PI*2/FINEANGLES;
424 t = FRACUNIT*sin (a);
435 = R_InitTextureMapping
440 void R_InitTextureMapping (void)
449 // use tangent table to generate viewangletox
450 // viewangletox will give the next greatest x after the view angle
452 // calc focallength so FIELDOFVIEW angles covers SCREENWIDTH
453 focallength = FixedDiv (centerxfrac
454 , finetangent[FINEANGLES/4+FIELDOFVIEW/2] );
456 for (i=0 ; i<FINEANGLES/2 ; i++)
458 if (finetangent[i] > FRACUNIT*2)
460 else if (finetangent[i] < -FRACUNIT*2)
464 t = FixedMul (finetangent[i], focallength);
465 t = (centerxfrac - t+FRACUNIT-1)>>FRACBITS;
468 else if (t>viewwidth+1)
475 // scan viewangletox[] to generate xtoviewangleangle[]
477 // xtoviewangle will give the smallest view angle that maps to x
478 for (x=0;x<=viewwidth;x++)
481 while (viewangletox[i]>x)
483 xtoviewangle[x] = (i<<ANGLETOFINESHIFT)-ANG90;
487 // take out the fencepost cases from viewangletox
489 for (i=0 ; i<FINEANGLES/2 ; i++)
491 t = FixedMul (finetangent[i], focallength);
493 if (viewangletox[i] == -1)
495 else if (viewangletox[i] == viewwidth+1)
496 viewangletox[i] = viewwidth;
499 clipangle = xtoviewangle[0];
502 //=============================================================================
509 = Only inits the zlight table, because the scalelight table changes
517 void R_InitLightTables (void)
519 int i,j, level, startmap;
523 // Calculate the light levels to use for each level / distance combination
525 for (i=0 ; i< LIGHTLEVELS ; i++)
527 startmap = ((LIGHTLEVELS-1-i)*2)*NUMCOLORMAPS/LIGHTLEVELS;
528 for (j=0 ; j<MAXLIGHTZ ; j++)
530 scale = FixedDiv ((SCREENWIDTH/2*FRACUNIT), (j+1)<<LIGHTZSHIFT);
531 scale >>= LIGHTSCALESHIFT;
532 level = startmap - scale/DISTMAP;
535 if (level >= NUMCOLORMAPS)
536 level = NUMCOLORMAPS-1;
537 zlight[i][j] = colormaps + level*256;
548 = Don't really change anything here, because i might be in the middle of
549 = a refresh. The change will take effect next refresh.
554 boolean setsizeneeded;
555 int setblocks, setdetail;
557 void R_SetViewSize (int blocks, int detail)
559 setsizeneeded = true;
567 = R_ExecuteSetViewSize
572 void R_ExecuteSetViewSize (void)
575 int i,j, level, startmap;
577 setsizeneeded = false;
581 scaledviewwidth = SCREENWIDTH;
582 viewheight = SCREENHEIGHT;
586 scaledviewwidth = setblocks*32;
588 viewheight = (setblocks*(200-SBARHEIGHT*sbarscale/20)/10);
590 viewheight = (setblocks*158/10);
594 detailshift = setdetail;
595 viewwidth = scaledviewwidth>>detailshift;
597 centery = viewheight/2;
598 centerx = viewwidth/2;
599 centerxfrac = centerx<<FRACBITS;
600 centeryfrac = centery<<FRACBITS;
601 projection = centerxfrac;
606 colfunc = basecolfunc = R_DrawColumn;
607 fuzzcolfunc = R_DrawFuzzColumn;
608 transcolfunc = R_DrawTranslatedColumn;
609 spanfunc = R_DrawSpan;
613 colfunc = basecolfunc = R_DrawColumnLow;
614 fuzzcolfunc = R_DrawFuzzColumn;
615 transcolfunc = R_DrawTranslatedColumn;
616 spanfunc = R_DrawSpanLow;
620 R_InitBuffer (scaledviewwidth, viewheight);
622 R_InitTextureMapping ();
627 pspritescale = FRACUNIT*viewwidth/SCREENWIDTH;
628 pspriteiscale = FRACUNIT*SCREENWIDTH/viewwidth;
633 for (i=0 ; i<viewwidth ; i++)
634 screenheightarray[i] = viewheight;
639 for (i=0 ; i<viewheight ; i++)
641 dy = ((i-viewheight/2)<<FRACBITS)+FRACUNIT/2;
643 yslope[i] = FixedDiv ( (viewwidth<<detailshift)/2*FRACUNIT, dy);
646 for (i=0 ; i<viewwidth ; i++)
648 cosadj = abs(finecosine[xtoviewangle[i]>>ANGLETOFINESHIFT]);
649 distscale[i] = FixedDiv (FRACUNIT,cosadj);
653 // Calculate the light levels to use for each level / scale combination
655 for (i=0 ; i< LIGHTLEVELS ; i++)
657 startmap = ((LIGHTLEVELS-1-i)*2)*NUMCOLORMAPS/LIGHTLEVELS;
658 for (j=0 ; j<MAXLIGHTSCALE ; j++)
660 level = startmap - j*SCREENWIDTH/(viewwidth<<detailshift)/DISTMAP;
663 if (level >= NUMCOLORMAPS)
664 level = NUMCOLORMAPS-1;
665 scalelight[i][j] = colormaps + level*256;
672 R_DrawViewBorder (); // erase old menu stuff
689 tprintf("R_InitData ",1);
692 tprintf("R_InitPointToAngle\n",0);
693 R_InitPointToAngle ();
695 tprintf("R_InitTables ",0);
697 // viewwidth / viewheight / detailLevel are set by the defaults
699 R_SetViewSize (screenblocks, detailLevel);
700 tprintf("R_InitPlanes\n",0);
703 tprintf("R_InitLightTables ",0);
704 R_InitLightTables ();
706 tprintf("R_InitSkyMap\n",0);
710 R_InitTranslationTables();
726 subsector_t *R_PointInSubsector (fixed_t x, fixed_t y)
731 if (!numnodes) // single subsector is a special case
734 nodenum = numnodes-1;
736 while (! (nodenum & NF_SUBSECTOR) )
738 node = &nodes[nodenum];
739 side = R_PointOnSide (x, y, node);
740 nodenum = node->children[side];
743 return &subsectors[nodenum & ~NF_SUBSECTOR];
747 //----------------------------------------------------------------------------
751 //----------------------------------------------------------------------------
753 void R_SetupFrame(player_t *player)
762 viewangleoffset = newViewAngleOff<<ANGLETOFINESHIFT;
764 viewangle = player->mo->angle+viewangleoffset;
766 viewpitch = player->lookdir;
768 tableAngle = viewangle>>ANGLETOFINESHIFT;
769 if(player->chickenTics && player->chickenPeck)
770 { // Set chicken attack view position
771 viewx = player->mo->x+player->chickenPeck*finecosine[tableAngle];
772 viewy = player->mo->y+player->chickenPeck*finesine[tableAngle];
775 { // Normal view position
776 viewx = player->mo->x;
777 viewy = player->mo->y;
779 extralight = player->extralight;
780 viewz = player->viewz;
783 tempCentery = viewheight/2;
785 tempCentery = viewheight/2+(player->lookdir)*screenblocks/10;
787 if(centery != tempCentery)
789 centery = tempCentery;
790 centeryfrac = centery<<FRACBITS;
791 for(i = 0; i < viewheight; i++)
793 yslope[i] = FixedDiv ((viewwidth<<detailshift)/2*FRACUNIT,
794 abs(((i-centery)<<FRACBITS)+FRACUNIT/2));
797 viewsin = finesine[tableAngle];
798 viewcos = finecosine[tableAngle];
800 if(player->fixedcolormap)
802 fixedcolormap = colormaps+player->fixedcolormap
803 *256*sizeof(lighttable_t);
804 walllights = scalelightfixed;
805 for(i = 0; i < MAXLIGHTSCALE; i++)
807 scalelightfixed[i] = fixedcolormap;
816 if(BorderNeedRefresh)
826 BorderNeedRefresh = false;
827 BorderTopRefresh = false;
828 UpdateState |= I_FULLSCRN;
836 BorderTopRefresh = false;
837 UpdateState |= I_MESSAGES;
841 RD_ClearMapWindow ();
844 destview = destscreen+(viewwindowx>>2)+viewwindowy*80;
850 memset (screen, frame, SCREENWIDTH*SCREENHEIGHT);
864 void R_RenderPlayerView (player_t *player)
866 R_SetupFrame (player);
874 NetUpdate (); // check for new console commands
877 OGL_SwitchTo3DState();
882 R_RenderBSPNode (numnodes-1); // the head node is the last node output
884 NetUpdate (); // check for new console commands
887 NetUpdate (); // check for new console commands
890 NetUpdate (); // check for new console commands
892 OGL_Restore2DState(1);
895 if( viewangleoffset <= 1024<<ANGLETOFINESHIFT || viewangleoffset >=
896 -1024<<ANGLETOFINESHIFT )
897 { // don't draw on side views
898 R_DrawPlayerSprites();
901 OGL_Restore2DState(2);