]> icculus.org git repositories - theoddone33/hheretic.git/blob - base/r_main.c
More 64bit fixes
[theoddone33/hheretic.git] / base / r_main.c
1 // R_main.c
2
3 #include <stdlib.h>
4 #include <math.h>
5 #include "doomdef.h"
6 #include "r_local.h"
7 #ifdef RENDER3D
8 #include "ogl_def.h"
9 #endif
10
11 #ifdef RENDER3D
12 extern void R_RenderMap();
13 extern void R_DrawPlayerSprites();
14 #endif
15
16 int                     viewangleoffset;
17
18 #ifdef __WATCOMC__
19 int newViewAngleOff;
20 #endif
21
22 int                     validcount = 1;         // increment every time a check is made
23
24 lighttable_t    *fixedcolormap;
25 extern  lighttable_t    **walllights;
26
27 int                             centerx, centery;
28 fixed_t                 centerxfrac, centeryfrac;
29 fixed_t                 projection;
30
31 int                             framecount;             // just for profiling purposes
32
33 int             sscount, linecount, loopcount;
34
35 fixed_t         viewx, viewy, viewz;
36 angle_t         viewangle;
37 fixed_t         viewcos, viewsin;
38 player_t        *viewplayer;
39
40 #ifdef RENDER3D
41 float       viewpitch;          // player->lookdir, global version
42 #endif
43
44 int                             detailshift;            // 0 = high, 1 = low
45
46 //
47 // precalculated math tables
48 //
49 angle_t         clipangle;
50
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];
55
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];
59
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];
63
64 // fixed_t              finesine[5*FINEANGLES/4];
65 fixed_t         *finecosine = &finesine[FINEANGLES/4];
66
67
68 lighttable_t    *scalelight[LIGHTLEVELS][MAXLIGHTSCALE];
69 lighttable_t    *scalelightfixed[MAXLIGHTSCALE];
70 lighttable_t    *zlight[LIGHTLEVELS][MAXLIGHTZ];
71
72 int                     extralight;                     // bumped light from gun blasts
73
74 void            (*colfunc) (void);
75 void            (*basecolfunc) (void);
76 void            (*fuzzcolfunc) (void);
77 void            (*transcolfunc) (void);
78 void            (*spanfunc) (void);
79
80 /*
81 ===================
82 =
83 = R_AddPointToBox
84 =
85 ===================
86 */
87
88 void R_AddPointToBox (int x, int y, fixed_t *box)
89 {
90         if (x< box[BOXLEFT])
91                 box[BOXLEFT] = x;
92         if (x> box[BOXRIGHT])
93                 box[BOXRIGHT] = x;
94         if (y< box[BOXBOTTOM])
95                 box[BOXBOTTOM] = y;
96         if (y> box[BOXTOP])
97                 box[BOXTOP] = y;
98 }
99
100
101
102 /*
103 ===============================================================================
104 =
105 = R_PointOnSide
106 =
107 = Returns side 0 (front) or 1 (back)
108 ===============================================================================
109 */
110
111 int     R_PointOnSide (fixed_t x, fixed_t y, node_t *node)
112 {
113         fixed_t dx,dy;
114         fixed_t left, right;
115
116         if (!node->dx)
117         {
118                 if (x <= node->x)
119                         return node->dy > 0;
120                 return node->dy < 0;
121         }
122         if (!node->dy)
123         {
124                 if (y <= node->y)
125                         return node->dx < 0;
126                 return node->dx > 0;
127         }
128
129         dx = (x - node->x);
130         dy = (y - node->y);
131
132 // try to quickly decide by looking at sign bits
133         if ( (node->dy ^ node->dx ^ dx ^ dy)&0x80000000 )
134         {
135                 if  ( (node->dy ^ dx) & 0x80000000 )
136                         return 1;       // (left is negative)
137                 return 0;
138         }
139
140         left = FixedMul ( node->dy>>FRACBITS , dx );
141         right = FixedMul ( dy , node->dx>>FRACBITS );
142
143         if (right < left)
144                 return 0;               // front side
145         return 1;                       // back side
146 }
147
148
149 int     R_PointOnSegSide (fixed_t x, fixed_t y, seg_t *line)
150 {
151         fixed_t lx, ly;
152         fixed_t ldx, ldy;
153         fixed_t dx,dy;
154         fixed_t left, right;
155
156         lx = line->v1->x;
157         ly = line->v1->y;
158
159         ldx = line->v2->x - lx;
160         ldy = line->v2->y - ly;
161
162         if (!ldx)
163         {
164                 if (x <= lx)
165                         return ldy > 0;
166                 return ldy < 0;
167         }
168         if (!ldy)
169         {
170                 if (y <= ly)
171                         return ldx < 0;
172                 return ldx > 0;
173         }
174
175         dx = (x - lx);
176         dy = (y - ly);
177
178 // try to quickly decide by looking at sign bits
179         if ( (ldy ^ ldx ^ dx ^ dy)&0x80000000 )
180         {
181                 if  ( (ldy ^ dx) & 0x80000000 )
182                         return 1;       // (left is negative)
183                 return 0;
184         }
185
186         left = FixedMul ( ldy>>FRACBITS , dx );
187         right = FixedMul ( dy , ldx>>FRACBITS );
188
189         if (right < left)
190                 return 0;               // front side
191         return 1;                       // back side
192 }
193
194
195 /*
196 ===============================================================================
197 =
198 = R_PointToAngle
199 =
200 ===============================================================================
201 */
202
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
209 #define SLOPEBITS       11
210 #define DBITS           (FRACBITS-SLOPEBITS)
211
212
213 extern  int     tantoangle[SLOPERANGE+1];               // get from tables.c
214
215 // int  tantoangle[SLOPERANGE+1];
216
217 int SlopeDiv (unsigned num, unsigned den)
218 {
219         unsigned ans;
220         if (den < 512)
221                 return SLOPERANGE;
222         ans = (num<<3)/(den>>8);
223         return ans <= SLOPERANGE ? ans : SLOPERANGE;
224 }
225
226 angle_t R_PointToAngle (fixed_t x, fixed_t y)
227 {
228         x -= viewx;
229         y -= viewy;
230         if ( (!x) && (!y) )
231                 return 0;
232         if (x>= 0)
233         {       // x >=0
234                 if (y>= 0)
235                 {       // y>= 0
236                         if (x>y)
237                                 return tantoangle[ SlopeDiv(y,x)];     // octant 0
238                         else
239                                 return ANG90-1-tantoangle[ SlopeDiv(x,y)];  // octant 1
240                 }
241                 else
242                 {       // y<0
243                         y = -y;
244                         if (x>y)
245                                 return -tantoangle[SlopeDiv(y,x)];  // octant 8
246                         else
247                                 return ANG270+tantoangle[ SlopeDiv(x,y)];  // octant 7
248                 }
249         }
250         else
251         {       // x<0
252                 x = -x;
253                 if (y>= 0)
254                 {       // y>= 0
255                         if (x>y)
256                                 return ANG180-1-tantoangle[ SlopeDiv(y,x)]; // octant 3
257                         else
258                                 return ANG90+ tantoangle[ SlopeDiv(x,y)];  // octant 2
259                 }
260                 else
261                 {       // y<0
262                         y = -y;
263                         if (x>y)
264                                 return ANG180+tantoangle[ SlopeDiv(y,x)];  // octant 4
265                         else
266                                 return ANG270-1-tantoangle[ SlopeDiv(x,y)];  // octant 5
267                 }
268         }
269
270         return 0;
271 }
272
273
274 angle_t R_PointToAngle2 (fixed_t x1, fixed_t y1, fixed_t x2, fixed_t y2)
275 {
276         viewx = x1;
277         viewy = y1;
278         return R_PointToAngle (x2, y2);
279 }
280
281
282 fixed_t R_PointToDist (fixed_t x, fixed_t y)
283 {
284         int             angle;
285         fixed_t dx, dy, temp;
286         fixed_t dist;
287
288         dx = abs(x - viewx);
289         dy = abs(y - viewy);
290
291         if (dy>dx)
292         {
293                 temp = dx;
294                 dx = dy;
295                 dy = temp;
296         }
297
298         angle = (tantoangle[ FixedDiv(dy,dx)>>DBITS ]+ANG90) >> ANGLETOFINESHIFT;
299
300         dist = FixedDiv (dx, finesine[angle] ); // use as cosine
301
302         return dist;
303 }
304
305
306
307 /*
308 =================
309 =
310 = R_InitPointToAngle
311 =
312 =================
313 */
314
315 void R_InitPointToAngle (void)
316 {
317 // now getting from tables.c
318 #if 0
319         int     i;
320         long    t;
321         float   f;
322 //
323 // slope (tangent) to angle lookup
324 //
325         for (i=0 ; i<=SLOPERANGE ; i++)
326         {
327                 f = atan( (float)i/SLOPERANGE )/(3.141592657*2);
328                 t = 0xffffffff*f;
329                 tantoangle[i] = t;
330         }
331 #endif
332 }
333
334 //=============================================================================
335
336 /*
337 ================
338 =
339 = R_ScaleFromGlobalAngle
340 =
341 = Returns the texture mapping scale for the current line at the given angle
342 = rw_distance must be calculated first
343 ================
344 */
345
346 fixed_t R_ScaleFromGlobalAngle (angle_t visangle)
347 {
348         fixed_t         scale;
349         int                     anglea, angleb;
350         int                     sinea, sineb;
351         fixed_t         num,den;
352
353 #if 0
354 {
355         fixed_t         dist,z;
356         fixed_t         sinv, cosv;
357
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);
363         return scale;
364 }
365 #endif
366
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);
374         if (den > num>>16)
375         {
376                 scale = FixedDiv (num, den);
377                 if (scale > 64*FRACUNIT)
378                         scale = 64*FRACUNIT;
379                 else if (scale < 256)
380                         scale = 256;
381         }
382         else
383                 scale = 64*FRACUNIT;
384
385         return scale;
386 }
387
388
389
390 /*
391 =================
392 =
393 = R_InitTables
394 =
395 =================
396 */
397
398 void R_InitTables (void)
399 {
400 // now getting from tables.c
401 #if 0
402         int             i;
403         float           a, fv;
404         int                     t;
405
406 //
407 // viewangle tangent table
408 //
409         for (i=0 ; i<FINEANGLES/2 ; i++)
410         {
411                 a = (i-FINEANGLES/4+0.5)*PI*2/FINEANGLES;
412                 fv = FRACUNIT*tan (a);
413                 t = fv;
414                 finetangent[i] = t;
415         }
416
417 //
418 // finesine table
419 //
420         for (i=0 ; i<5*FINEANGLES/4 ; i++)
421         {
422 // OPTIMIZE: mirror...
423                 a = (i+0.5)*PI*2/FINEANGLES;
424                 t = FRACUNIT*sin (a);
425                 finesine[i] = t;
426         }
427 #endif
428
429 }
430
431
432 /*
433 =================
434 =
435 = R_InitTextureMapping
436 =
437 =================
438 */
439
440 void R_InitTextureMapping (void)
441 {
442         int                     i;
443         int                     x;
444         int                     t;
445         fixed_t         focallength;
446
447
448 //
449 // use tangent table to generate viewangletox
450 // viewangletox will give the next greatest x after the view angle
451 //
452         // calc focallength so FIELDOFVIEW angles covers SCREENWIDTH
453         focallength = FixedDiv (centerxfrac
454         , finetangent[FINEANGLES/4+FIELDOFVIEW/2] );
455
456         for (i=0 ; i<FINEANGLES/2 ; i++)
457         {
458                 if (finetangent[i] > FRACUNIT*2)
459                         t = -1;
460                 else if (finetangent[i] < -FRACUNIT*2)
461                         t = viewwidth+1;
462                 else
463                 {
464                         t = FixedMul (finetangent[i], focallength);
465                         t = (centerxfrac - t+FRACUNIT-1)>>FRACBITS;
466                         if (t < -1)
467                                 t = -1;
468                         else if (t>viewwidth+1)
469                                 t = viewwidth+1;
470                 }
471                 viewangletox[i] = t;
472         }
473
474 //
475 // scan viewangletox[] to generate xtoviewangleangle[]
476 //
477 // xtoviewangle will give the smallest view angle that maps to x
478         for (x=0;x<=viewwidth;x++)
479         {
480                 i = 0;
481                 while (viewangletox[i]>x)
482                         i++;
483                 xtoviewangle[x] = (i<<ANGLETOFINESHIFT)-ANG90;
484         }
485
486 //
487 // take out the fencepost cases from viewangletox
488 //
489         for (i=0 ; i<FINEANGLES/2 ; i++)
490         {
491                 t = FixedMul (finetangent[i], focallength);
492                 t = centerx - t;
493                 if (viewangletox[i] == -1)
494                         viewangletox[i] = 0;
495                 else if (viewangletox[i] == viewwidth+1)
496                         viewangletox[i]  = viewwidth;
497         }
498
499         clipangle = xtoviewangle[0];
500 }
501
502 //=============================================================================
503
504 /*
505 ====================
506 =
507 = R_InitLightTables
508 =
509 = Only inits the zlight table, because the scalelight table changes
510 = with view size
511 =
512 ====================
513 */
514
515 #define         DISTMAP 2
516
517 void R_InitLightTables (void)
518 {
519         int             i,j, level, startmap;
520         int             scale;
521
522 //
523 // Calculate the light levels to use for each level / distance combination
524 //
525         for (i=0 ; i< LIGHTLEVELS ; i++)
526         {
527                 startmap = ((LIGHTLEVELS-1-i)*2)*NUMCOLORMAPS/LIGHTLEVELS;
528                 for (j=0 ; j<MAXLIGHTZ ; j++)
529                 {
530                         scale = FixedDiv ((SCREENWIDTH/2*FRACUNIT), (j+1)<<LIGHTZSHIFT);
531                         scale >>= LIGHTSCALESHIFT;
532                         level = startmap - scale/DISTMAP;
533                         if (level < 0)
534                                 level = 0;
535                         if (level >= NUMCOLORMAPS)
536                                 level = NUMCOLORMAPS-1;
537                         zlight[i][j] = colormaps + level*256;
538                 }
539         }
540 }
541
542
543 /*
544 ==============
545 =
546 = R_SetViewSize
547 =
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.
550 =
551 ==============
552 */
553
554 boolean setsizeneeded;
555 int             setblocks, setdetail;
556
557 void R_SetViewSize (int blocks, int detail)
558 {
559         setsizeneeded = true;
560         setblocks = blocks;
561         setdetail = detail;
562 }
563
564 /*
565 ==============
566 =
567 = R_ExecuteSetViewSize
568 =
569 ==============
570 */
571
572 void R_ExecuteSetViewSize (void)
573 {
574         fixed_t cosadj, dy;
575         int             i,j, level, startmap;
576
577         setsizeneeded = false;
578
579         if (setblocks == 11)
580         {
581                 scaledviewwidth = SCREENWIDTH;
582                 viewheight = SCREENHEIGHT;
583         }
584         else
585         {
586                 scaledviewwidth = setblocks*32;
587 #ifdef RENDER3D
588         viewheight = (setblocks*(200-SBARHEIGHT*sbarscale/20)/10);
589 #else
590                 viewheight = (setblocks*158/10);
591 #endif
592         }
593
594         detailshift = setdetail;
595         viewwidth = scaledviewwidth>>detailshift;
596
597         centery = viewheight/2;
598         centerx = viewwidth/2;
599         centerxfrac = centerx<<FRACBITS;
600         centeryfrac = centery<<FRACBITS;
601         projection = centerxfrac;
602
603 #ifndef RENDER3D
604         if (!detailshift)
605         {
606                 colfunc = basecolfunc = R_DrawColumn;
607                 fuzzcolfunc = R_DrawFuzzColumn;
608                 transcolfunc = R_DrawTranslatedColumn;
609                 spanfunc = R_DrawSpan;
610         }
611         else
612         {
613                 colfunc = basecolfunc = R_DrawColumnLow;
614                 fuzzcolfunc = R_DrawFuzzColumn;
615                 transcolfunc = R_DrawTranslatedColumn;
616                 spanfunc = R_DrawSpanLow;
617         }
618 #endif
619
620         R_InitBuffer (scaledviewwidth, viewheight);
621
622         R_InitTextureMapping ();
623
624 //
625 // psprite scales
626 //
627         pspritescale = FRACUNIT*viewwidth/SCREENWIDTH;
628         pspriteiscale = FRACUNIT*SCREENWIDTH/viewwidth;
629
630 //
631 // thing clipping
632 //
633         for (i=0 ; i<viewwidth ; i++)
634                 screenheightarray[i] = viewheight;
635
636 //
637 // planes
638 //
639         for (i=0 ; i<viewheight ; i++)
640         {
641                 dy = ((i-viewheight/2)<<FRACBITS)+FRACUNIT/2;
642                 dy = abs(dy);
643                 yslope[i] = FixedDiv ( (viewwidth<<detailshift)/2*FRACUNIT, dy);
644         }
645
646         for (i=0 ; i<viewwidth ; i++)
647         {
648                 cosadj = abs(finecosine[xtoviewangle[i]>>ANGLETOFINESHIFT]);
649                 distscale[i] = FixedDiv (FRACUNIT,cosadj);
650         }
651
652 //
653 // Calculate the light levels to use for each level / scale combination
654 //
655         for (i=0 ; i< LIGHTLEVELS ; i++)
656         {
657                 startmap = ((LIGHTLEVELS-1-i)*2)*NUMCOLORMAPS/LIGHTLEVELS;
658                 for (j=0 ; j<MAXLIGHTSCALE ; j++)
659                 {
660                         level = startmap - j*SCREENWIDTH/(viewwidth<<detailshift)/DISTMAP;
661                         if (level < 0)
662                                 level = 0;
663                         if (level >= NUMCOLORMAPS)
664                                 level = NUMCOLORMAPS-1;
665                         scalelight[i][j] = colormaps + level*256;
666                 }
667         }
668
669 //
670 // draw the border
671 //
672         R_DrawViewBorder ();    // erase old menu stuff
673 }
674
675
676 /*
677 ==============
678 =
679 = R_Init
680 =
681 ==============
682 */
683
684 int     detailLevel;
685 int     screenblocks;
686
687 void R_Init (void)
688 {
689         tprintf("R_InitData ",1);
690         R_InitData ();
691 //printf (".");
692         tprintf("R_InitPointToAngle\n",0);
693         R_InitPointToAngle ();
694 //printf (".");
695         tprintf("R_InitTables ",0);
696         R_InitTables ();
697         // viewwidth / viewheight / detailLevel are set by the defaults
698 //printf (".");
699         R_SetViewSize (screenblocks, detailLevel);
700         tprintf("R_InitPlanes\n",0);
701         R_InitPlanes ();
702 //printf (".");
703         tprintf("R_InitLightTables ",0);
704         R_InitLightTables ();
705 //printf (".");
706         tprintf("R_InitSkyMap\n",0);
707         R_InitSkyMap ();
708 //printf (".");
709 #ifndef RENDER3D
710         R_InitTranslationTables();
711 #else
712     OGL_InitData();
713 #endif
714         framecount = 0;
715 }
716
717
718 /*
719 ==============
720 =
721 = R_PointInSubsector
722 =
723 ==============
724 */
725
726 subsector_t *R_PointInSubsector (fixed_t x, fixed_t y)
727 {
728         node_t  *node;
729         int             side, nodenum;
730
731         if (!numnodes)                          // single subsector is a special case
732                 return subsectors;
733
734         nodenum = numnodes-1;
735
736         while (! (nodenum & NF_SUBSECTOR) )
737         {
738                 node = &nodes[nodenum];
739                 side = R_PointOnSide (x, y, node);
740                 nodenum = node->children[side];
741         }
742
743         return &subsectors[nodenum & ~NF_SUBSECTOR];
744
745 }
746
747 //----------------------------------------------------------------------------
748 //
749 // PROC R_SetupFrame
750 //
751 //----------------------------------------------------------------------------
752
753 void R_SetupFrame(player_t *player)
754 {
755         int i;
756         int tableAngle;
757         int tempCentery;
758
759         //drawbsp = 1;
760         viewplayer = player;
761 #ifdef __WATCOMC__
762         viewangleoffset = newViewAngleOff<<ANGLETOFINESHIFT;
763 #endif
764         viewangle = player->mo->angle+viewangleoffset;
765 #ifdef RENDER3D
766     viewpitch = player->lookdir;
767 #endif
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];
773         }
774         else
775         { // Normal view position
776                 viewx = player->mo->x;
777                 viewy = player->mo->y;
778         }
779         extralight = player->extralight;
780         viewz = player->viewz;
781         
782 #ifdef RENDER3D
783         tempCentery = viewheight/2;
784 #else
785         tempCentery = viewheight/2+(player->lookdir)*screenblocks/10;
786 #endif
787         if(centery != tempCentery)
788         {
789                 centery = tempCentery;
790                 centeryfrac = centery<<FRACBITS;
791                 for(i = 0; i < viewheight; i++)
792                 {
793                         yslope[i] = FixedDiv ((viewwidth<<detailshift)/2*FRACUNIT,
794                                 abs(((i-centery)<<FRACBITS)+FRACUNIT/2));
795                 }
796         }
797         viewsin = finesine[tableAngle];
798         viewcos = finecosine[tableAngle];
799         sscount = 0;
800         if(player->fixedcolormap)
801         {
802                 fixedcolormap = colormaps+player->fixedcolormap
803                         *256*sizeof(lighttable_t);
804                 walllights = scalelightfixed;
805                 for(i = 0; i < MAXLIGHTSCALE; i++)
806                 {
807                         scalelightfixed[i] = fixedcolormap;
808                 }
809         }
810         else
811         {
812                 fixedcolormap = 0;
813         }
814         framecount++;
815         validcount++;
816         if(BorderNeedRefresh)
817         {
818 #ifdef RENDER3D
819         R_DrawViewBorder();
820 #else
821                 if(setblocks < 10)
822                 {
823                         R_DrawViewBorder();
824                 }
825 #endif
826                 BorderNeedRefresh = false;
827                 BorderTopRefresh = false;
828                 UpdateState |= I_FULLSCRN;
829         }
830         if(BorderTopRefresh)
831         {
832                 if(setblocks < 10)
833                 {
834                         R_DrawTopBorder();
835                 }
836                 BorderTopRefresh = false;
837                 UpdateState |= I_MESSAGES;
838         }
839
840 #ifdef __NeXT__
841         RD_ClearMapWindow ();
842 #endif
843 #ifdef __WATCOMC__
844         destview = destscreen+(viewwindowx>>2)+viewwindowy*80;
845 #endif
846
847 #if 0
848 {
849 static int frame;
850 memset (screen, frame, SCREENWIDTH*SCREENHEIGHT);
851 frame++;
852 }
853 #endif
854 }
855
856 /*
857 ==============
858 =
859 = R_RenderView
860 =
861 ==============
862 */
863
864 void R_RenderPlayerView (player_t *player)
865 {
866         R_SetupFrame (player);
867
868 #ifndef RENDER3D
869         R_ClearClipSegs ();
870         R_ClearDrawSegs ();
871         R_ClearPlanes ();
872 #endif
873         R_ClearSprites ();
874         NetUpdate ();                                   // check for new console commands
875
876 #ifdef RENDER3D
877     OGL_SwitchTo3DState();
878 #endif
879 #ifdef RENDER3D
880         R_RenderMap();
881 #else
882         R_RenderBSPNode (numnodes-1);   // the head node is the last node output
883 #endif
884         NetUpdate ();                                   // check for new console commands
885 #ifndef RENDER3D
886         R_DrawPlanes ();
887         NetUpdate ();                                   // check for new console commands
888 #endif
889         R_DrawMasked ();
890         NetUpdate ();                                   // check for new console commands
891 #ifdef RENDER3D
892     OGL_Restore2DState(1);
893
894     // Draw psprites.
895     if( viewangleoffset <= 1024<<ANGLETOFINESHIFT || viewangleoffset >=
896         -1024<<ANGLETOFINESHIFT )
897     {   // don't draw on side views
898         R_DrawPlayerSprites();
899     }
900
901     OGL_Restore2DState(2);
902 #endif
903 }