DOOM-3-BFG

DOOM 3 BFG Edition
Log | Files | Refs

r_main.cpp (16713B)


      1 /*
      2 ===========================================================================
      3 
      4 Doom 3 BFG Edition GPL Source Code
      5 Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company. 
      6 
      7 This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").  
      8 
      9 Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify
     10 it under the terms of the GNU General Public License as published by
     11 the Free Software Foundation, either version 3 of the License, or
     12 (at your option) any later version.
     13 
     14 Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful,
     15 but WITHOUT ANY WARRANTY; without even the implied warranty of
     16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     17 GNU General Public License for more details.
     18 
     19 You should have received a copy of the GNU General Public License
     20 along with Doom 3 BFG Edition Source Code.  If not, see <http://www.gnu.org/licenses/>.
     21 
     22 In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code.  If not, please request a copy in writing from id Software at the address below.
     23 
     24 If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
     25 
     26 ===========================================================================
     27 */
     28 
     29 #include "Precompiled.h"
     30 #include "globaldata.h"
     31 
     32 
     33 
     34 #include <stdlib.h>
     35 #include <math.h>
     36 
     37 
     38 #include "doomdef.h"
     39 #include "d_net.h"
     40 
     41 #include "m_bbox.h"
     42 
     43 #include "r_local.h"
     44 #include "r_sky.h"
     45 #include "i_system.h"
     46 
     47 
     48 
     49 
     50 // Fineangles in the SCREENWIDTH wide window.
     51 
     52 
     53 
     54 
     55 // increment every time a check is made
     56 
     57 
     58 
     59 
     60 
     61 // just for profiling purposes
     62 
     63 
     64 
     65 
     66 
     67 
     68 // 0 = high, 1 = low
     69 
     70 //
     71 // precalculated math tables
     72 //
     73 
     74 // The ::g->viewangletox[::g->viewangle + FINEANGLES/4] lookup
     75 // maps the visible view angles to screen X coordinates,
     76 // flattening the arc to a flat ::g->projection plane.
     77 // There will be many angles mapped to the same X. 
     78 
     79 // The xtoviewangleangle[] table maps a screen pixel
     80 // to the lowest ::g->viewangle that maps back to x ranges
     81 // from ::g->clipangle to -::g->clipangle.
     82 
     83 
     84 // UNUSED.
     85 // The finetangentgent[angle+FINEANGLES/4] table
     86 // holds the fixed_t tangent values for view angles,
     87 // ranging from MININT to 0 to MAXINT.
     88 // fixed_t		finetangent[FINEANGLES/2];
     89 
     90 // fixed_t		finesine[5*FINEANGLES/4];
     91 const fixed_t*		finecosine = &finesine[FINEANGLES/4];
     92 
     93 
     94 
     95 // bumped light from gun blasts
     96 
     97 
     98 
     99 void (*colfunc) (lighttable_t * dc_colormap,
    100 				 byte * dc_source);
    101 void (*basecolfunc) (lighttable_t * dc_colormap,
    102 						byte * dc_source);
    103 void (*fuzzcolfunc) (lighttable_t * dc_colormap,
    104 						byte * dc_source);
    105 void (*transcolfunc) (lighttable_t * dc_colormap,
    106 						byte * dc_source);
    107 void (*spanfunc) (fixed_t xfrac,
    108 	fixed_t yfrac,
    109 	fixed_t ds_y,
    110 	int ds_x1,
    111 	int ds_x2,
    112 	fixed_t ds_xstep,
    113 	fixed_t ds_ystep,
    114 	lighttable_t * ds_colormap,
    115 	byte * ds_source);
    116 
    117 
    118 
    119 //
    120 // R_AddPointToBox
    121 // Expand a given bbox
    122 // so that it encloses a given point.
    123 //
    124 void
    125 R_AddPointToBox
    126 ( int		x,
    127  int		y,
    128  fixed_t*	box )
    129 {
    130 	if (x< box[BOXLEFT])
    131 		box[BOXLEFT] = x;
    132 	if (x> box[BOXRIGHT])
    133 		box[BOXRIGHT] = x;
    134 	if (y< box[BOXBOTTOM])
    135 		box[BOXBOTTOM] = y;
    136 	if (y> box[BOXTOP])
    137 		box[BOXTOP] = y;
    138 }
    139 
    140 
    141 //
    142 // R_PointOnSide
    143 // Traverse BSP (sub) tree,
    144 //  check point against partition plane.
    145 // Returns side 0 (front) or 1 (back).
    146 //
    147 int
    148 R_PointOnSide
    149 ( fixed_t	x,
    150  fixed_t	y,
    151  node_t*	node )
    152 {
    153 	fixed_t	dx;
    154 	fixed_t	dy;
    155 	fixed_t	left;
    156 	fixed_t	right;
    157 
    158 	if (!node->dx)
    159 	{
    160 		if (x <= node->x)
    161 			return node->dy > 0;
    162 
    163 		return node->dy < 0;
    164 	}
    165 	if (!node->dy)
    166 	{
    167 		if (y <= node->y)
    168 			return node->dx < 0;
    169 
    170 		return node->dx > 0;
    171 	}
    172 
    173 	dx = (x - node->x);
    174 	dy = (y - node->y);
    175 
    176 	// Try to quickly decide by looking at sign bits.
    177 	if ( (node->dy ^ node->dx ^ dx ^ dy)&0x80000000 )
    178 	{
    179 		if  ( (node->dy ^ dx) & 0x80000000 )
    180 		{
    181 			// (left is negative)
    182 			return 1;
    183 		}
    184 		return 0;
    185 	}
    186 
    187 	left = FixedMul ( node->dy>>FRACBITS , dx );
    188 	right = FixedMul ( dy , node->dx>>FRACBITS );
    189 
    190 	if (right < left)
    191 	{
    192 		// front side
    193 		return 0;
    194 	}
    195 	// back side
    196 	return 1;			
    197 }
    198 
    199 
    200 int
    201 R_PointOnSegSide
    202 ( fixed_t	x,
    203  fixed_t	y,
    204  seg_t*	line )
    205 {
    206 	fixed_t	lx;
    207 	fixed_t	ly;
    208 	fixed_t	ldx;
    209 	fixed_t	ldy;
    210 	fixed_t	dx;
    211 	fixed_t	dy;
    212 	fixed_t	left;
    213 	fixed_t	right;
    214 
    215 	lx = line->v1->x;
    216 	ly = line->v1->y;
    217 
    218 	ldx = line->v2->x - lx;
    219 	ldy = line->v2->y - ly;
    220 
    221 	if (!ldx)
    222 	{
    223 		if (x <= lx)
    224 			return ldy > 0;
    225 
    226 		return ldy < 0;
    227 	}
    228 	if (!ldy)
    229 	{
    230 		if (y <= ly)
    231 			return ldx < 0;
    232 
    233 		return ldx > 0;
    234 	}
    235 
    236 	dx = (x - lx);
    237 	dy = (y - ly);
    238 
    239 	// Try to quickly decide by looking at sign bits.
    240 	if ( (ldy ^ ldx ^ dx ^ dy)&0x80000000 )
    241 	{
    242 		if  ( (ldy ^ dx) & 0x80000000 )
    243 		{
    244 			// (left is negative)
    245 			return 1;
    246 		}
    247 		return 0;
    248 	}
    249 
    250 	left = FixedMul ( ldy>>FRACBITS , dx );
    251 	right = FixedMul ( dy , ldx>>FRACBITS );
    252 
    253 	if (right < left)
    254 	{
    255 		// front side
    256 		return 0;
    257 	}
    258 	// back side
    259 	return 1;			
    260 }
    261 
    262 
    263 //
    264 // R_PointToAngle
    265 // To get a global angle from cartesian coordinates,
    266 //  the coordinates are flipped until they are in
    267 //  the first octant of the coordinate system, then
    268 //  the y (<=x) is scaled and divided by x to get a
    269 //  tangent (slope) value which is looked up in the
    270 //  tantoangle[] table.
    271 
    272 //
    273 
    274 
    275 
    276 
    277 angle_t
    278 R_PointToAngle
    279 ( fixed_t	x,
    280  fixed_t	y )
    281 {	
    282 	extern fixed_t GetViewX(); extern fixed_t GetViewY();
    283 	x -= GetViewX();
    284 	y -= GetViewY();
    285 
    286 	if ( (!x) && (!y) )
    287 		return 0;
    288 
    289 	if (x>= 0)
    290 	{
    291 		// x >=0
    292 		if (y>= 0)
    293 		{
    294 			// y>= 0
    295 
    296 			if (x>y)
    297 			{
    298 				// octant 0
    299 				return tantoangle[ SlopeDiv(y,x)];
    300 			}
    301 			else
    302 			{
    303 				// octant 1
    304 				return ANG90-1-tantoangle[ SlopeDiv(x,y)];
    305 			}
    306 		}
    307 		else
    308 		{
    309 			// y<0
    310 			y = -y;
    311 
    312 			if (x>y)
    313 			{
    314 				// octant 8
    315 				return -tantoangle[SlopeDiv(y,x)]; // // ALANHACK UNSIGNED
    316 			}
    317 			else
    318 			{
    319 				// octant 7
    320 				return ANG270+tantoangle[ SlopeDiv(x,y)];
    321 			}
    322 		}
    323 	}
    324 	else
    325 	{
    326 		// x<0
    327 		x = -x;
    328 
    329 		if (y>= 0)
    330 		{
    331 			// y>= 0
    332 			if (x>y)
    333 			{
    334 				// octant 3
    335 				return ANG180-1-tantoangle[ SlopeDiv(y,x)];
    336 			}
    337 			else
    338 			{
    339 				// octant 2
    340 				return ANG90+ tantoangle[ SlopeDiv(x,y)];
    341 			}
    342 		}
    343 		else
    344 		{
    345 			// y<0
    346 			y = -y;
    347 
    348 			if (x>y)
    349 			{
    350 				// octant 4
    351 				return ANG180+tantoangle[ SlopeDiv(y,x)];
    352 			}
    353 			else
    354 			{
    355 				// octant 5
    356 				return ANG270-1-tantoangle[ SlopeDiv(x,y)];
    357 			}
    358 		}
    359 	}
    360 	return 0;
    361 }
    362 
    363 
    364 angle_t
    365 R_PointToAngle2
    366 ( fixed_t	x1,
    367  fixed_t	y1,
    368  fixed_t	x2,
    369  fixed_t	y2 )
    370 {	
    371 	extern void SetViewX( fixed_t ); extern void SetViewY( fixed_t );
    372 	SetViewX( x1 );
    373 	SetViewY( y1 );
    374 
    375 	return R_PointToAngle (x2, y2);
    376 }
    377 
    378 
    379 fixed_t
    380 R_PointToDist
    381 ( fixed_t	x,
    382  fixed_t	y )
    383 {
    384 	int		angle;
    385 	fixed_t	dx;
    386 	fixed_t	dy;
    387 	fixed_t	temp;
    388 	fixed_t	dist;
    389 
    390 	extern fixed_t GetViewX(); extern fixed_t GetViewY();
    391 	dx = abs(x - GetViewX());
    392 	dy = abs(y - GetViewY());
    393 
    394 	if (dy>dx)
    395 	{
    396 		temp = dx;
    397 		dx = dy;
    398 		dy = temp;
    399 	}
    400 
    401 	angle = (tantoangle[ FixedDiv(dy,dx)>>DBITS ]+ANG90) >> ANGLETOFINESHIFT;
    402 
    403 	// use as cosine
    404 	dist = FixedDiv (dx, finesine[angle] );	
    405 
    406 	return dist;
    407 }
    408 
    409 
    410 
    411 
    412 //
    413 // R_InitPointToAngle
    414 //
    415 void R_InitPointToAngle (void)
    416 {
    417 	// UNUSED - now getting from tables.c
    418 #if 0
    419 	int	i;
    420 	long	t;
    421 	float	f;
    422 	//
    423 	// slope (tangent) to angle lookup
    424 	//
    425 	for (i=0 ; i<=SLOPERANGE ; i++)
    426 	{
    427 		f = atan( (float)i/SLOPERANGE )/(3.141592657*2);
    428 		t = 0xffffffff*f;
    429 		tantoangle[i] = t;
    430 	}
    431 #endif
    432 }
    433 
    434 
    435 //
    436 // R_ScaleFromGlobalAngle
    437 // Returns the texture mapping scale
    438 //  for the current line (horizontal span)
    439 //  at the given angle.
    440 // ::g->rw_distance must be calculated first.
    441 //
    442 fixed_t R_ScaleFromGlobalAngle (angle_t visangle)
    443 {
    444 	fixed_t		scale;
    445 	//int			anglea;
    446 	//int			angleb;
    447 	angle_t		anglea;
    448 	angle_t		angleb;
    449 	int			sinea;
    450 	int			sineb;
    451 	fixed_t		num;
    452 	int			den;
    453 
    454 	// UNUSED
    455 #if 0
    456 	{
    457 		fixed_t		dist;
    458 		fixed_t		z;
    459 		fixed_t		sinv;
    460 		fixed_t		cosv;
    461 
    462 		sinv = finesine[(visangle-::g->rw_normalangle)>>ANGLETOFINESHIFT];	
    463 		dist = FixedDiv (::g->rw_distance, sinv);
    464 		cosv = finecosine[(::g->viewangle-visangle)>>ANGLETOFINESHIFT];
    465 		z = abs(FixedMul (dist, cosv));
    466 		scale = FixedDiv(::g->projection, z);
    467 		return scale;
    468 	}
    469 #endif
    470 
    471 	extern angle_t GetViewAngle();
    472 	anglea = ANG90 + (visangle-GetViewAngle());
    473 	angleb = ANG90 + (visangle-::g->rw_normalangle);
    474 
    475 	// both sines are allways positive
    476 	sinea = finesine[anglea>>ANGLETOFINESHIFT];	
    477 	sineb = finesine[angleb>>ANGLETOFINESHIFT];
    478 	num = FixedMul(::g->projection,sineb) << ::g->detailshift;
    479 	den = FixedMul(::g->rw_distance,sinea);
    480 
    481 	// DHM - Nerve :: If the den is pretty much 0, don't try the divide
    482 	if (den>>8 > 0 && den > num>>16)
    483 	{
    484 		scale = FixedDiv (num, den);
    485 
    486 		if (scale > 64*FRACUNIT)
    487 			scale = 64*FRACUNIT;
    488 		else if (scale < 256)
    489 			scale = 256;
    490 	}
    491 	else
    492 		scale = 64*FRACUNIT;
    493 
    494 	return scale;
    495 }
    496 
    497 
    498 
    499 //
    500 // R_InitTables
    501 //
    502 void R_InitTables (void)
    503 {
    504 	// UNUSED: now getting from tables.c
    505 #if 0
    506 	int		i;
    507 	float	a;
    508 	float	fv;
    509 	int		t;
    510 
    511 	// ::g->viewangle tangent table
    512 	for (i=0 ; i<FINEANGLES/2 ; i++)
    513 	{
    514 		a = (i-FINEANGLES/4+0.5)*PI*2/FINEANGLES;
    515 		fv = FRACUNIT*tan (a);
    516 		t = fv;
    517 		finetangent[i] = t;
    518 	}
    519 
    520 	// finesine table
    521 	for (i=0 ; i<5*FINEANGLES/4 ; i++)
    522 	{
    523 		// OPTIMIZE: mirror...
    524 		a = (i+0.5)*PI*2/FINEANGLES;
    525 		t = FRACUNIT*sin (a);
    526 		finesine[i] = t;
    527 	}
    528 #endif
    529 
    530 }
    531 
    532 
    533 
    534 //
    535 // R_InitTextureMapping
    536 //
    537 void R_InitTextureMapping (void)
    538 {
    539 	int			i;
    540 	int			x;
    541 	int			t;
    542 	fixed_t		focallength;
    543 
    544 	// Use tangent table to generate viewangletox:
    545 	//  ::g->viewangletox will give the next greatest x
    546 	//  after the view angle.
    547 	//
    548 	// Calc focallength
    549 	//  so FIELDOFVIEW angles covers SCREENWIDTH.
    550 	focallength = FixedDiv (::g->centerxfrac,
    551 		finetangent[FINEANGLES/4+FIELDOFVIEW/2] );
    552 
    553 	for (i=0 ; i<FINEANGLES/2 ; i++)
    554 	{
    555 		if (finetangent[i] > FRACUNIT*2)
    556 			t = -1;
    557 		else if (finetangent[i] < -FRACUNIT*2)
    558 			t = ::g->viewwidth+1;
    559 		else
    560 		{
    561 			t = FixedMul (finetangent[i], focallength);
    562 			t = (::g->centerxfrac - t+FRACUNIT-1)>>FRACBITS;
    563 
    564 			if (t < -1)
    565 				t = -1;
    566 			else if (t>::g->viewwidth+1)
    567 				t = ::g->viewwidth+1;
    568 		}
    569 		::g->viewangletox[i] = t;
    570 	}
    571 
    572 	// Scan ::g->viewangletox[] to generate ::g->xtoviewangle[]:
    573 	//  ::g->xtoviewangle will give the smallest view angle
    574 	//  that maps to x.	
    575 	for (x=0;x<=::g->viewwidth;x++)
    576 	{
    577 		i = 0;
    578 		while (::g->viewangletox[i]>x)
    579 			i++;
    580 		::g->xtoviewangle[x] = (i<<ANGLETOFINESHIFT)-ANG90;
    581 	}
    582 
    583 	// Take out the fencepost cases from ::g->viewangletox.
    584 	for (i=0 ; i<FINEANGLES/2 ; i++)
    585 	{
    586 		t = FixedMul (finetangent[i], focallength);
    587 		t = ::g->centerx - t;
    588 
    589 		if (::g->viewangletox[i] == -1)
    590 			::g->viewangletox[i] = 0;
    591 		else if (::g->viewangletox[i] == ::g->viewwidth+1)
    592 			::g->viewangletox[i]  = ::g->viewwidth;
    593 	}
    594 
    595 	::g->clipangle = ::g->xtoviewangle[0];
    596 }
    597 
    598 
    599 
    600 //
    601 // R_InitLightTables
    602 // Only inits the ::g->zlight table,
    603 //  because the ::g->scalelight table changes with view size.
    604 //
    605 
    606 void R_InitLightTables (void)
    607 {
    608 	int		i;
    609 	int		j;
    610 	int		level;
    611 	int		nocollide_startmap; 	
    612 	int		scale;
    613 
    614 	// Calculate the light levels to use
    615 	//  for each level / distance combination.
    616 	for (i=0 ; i< LIGHTLEVELS ; i++)
    617 	{
    618 		nocollide_startmap = ((LIGHTLEVELS-1-i)*2)*NUMCOLORMAPS/LIGHTLEVELS;
    619 		for (j=0 ; j<MAXLIGHTZ ; j++)
    620 		{
    621 			scale = FixedDiv ((SCREENWIDTH/2*FRACUNIT), (j+1)<<LIGHTZSHIFT);
    622 			scale >>= LIGHTSCALESHIFT;
    623 			level = nocollide_startmap - scale/DISTMAP;
    624 
    625 			if (level < 0)
    626 				level = 0;
    627 
    628 			if (level >= NUMCOLORMAPS)
    629 				level = NUMCOLORMAPS-1;
    630 
    631 			::g->zlight[i][j] = ::g->colormaps + level*256;
    632 		}
    633 	}
    634 }
    635 
    636 
    637 
    638 //
    639 // R_SetViewSize
    640 // Do not really change anything here,
    641 //  because it might be in the middle of a refresh.
    642 // The change will take effect next refresh.
    643 //
    644 
    645 
    646 void
    647 R_SetViewSize
    648 ( int		blocks,
    649  int		detail )
    650 {
    651 	::g->setsizeneeded = true;
    652 	::g->setblocks = blocks;
    653 	::g->setdetail = detail;
    654 }
    655 
    656 
    657 //
    658 // R_ExecuteSetViewSize
    659 //
    660 void R_ExecuteSetViewSize (void)
    661 {
    662 	fixed_t	cosadj;
    663 	fixed_t	dy;
    664 	int		i;
    665 	int		j;
    666 	int		level;
    667 	int		nocollide_startmap; 	
    668 
    669 	::g->setsizeneeded = false;
    670 
    671 	if (::g->setblocks == 11)
    672 	{
    673 		::g->scaledviewwidth = ORIGINAL_WIDTH;
    674 		::g->viewheight = ORIGINAL_HEIGHT;
    675 	}
    676 	else
    677 	{
    678 		::g->scaledviewwidth = ::g->setblocks*32;
    679 		::g->viewheight = (::g->setblocks*168/10)&~7;
    680 	}
    681 
    682 	// SMF - temp
    683 	::g->scaledviewwidth *= GLOBAL_IMAGE_SCALER;
    684 	::g->viewheight *= GLOBAL_IMAGE_SCALER;
    685 
    686 	::g->detailshift = ::g->setdetail;
    687 	::g->viewwidth = ::g->scaledviewwidth>>::g->detailshift;
    688 
    689 	::g->centery = ::g->viewheight/2;
    690 	::g->centerx = ::g->viewwidth/2;
    691 	::g->centerxfrac = ::g->centerx<<FRACBITS;
    692 	::g->centeryfrac = ::g->centery<<FRACBITS;
    693 	::g->projection = ::g->centerxfrac;
    694 
    695 	if (!::g->detailshift)
    696 	{
    697 		colfunc = basecolfunc = R_DrawColumn;
    698 		fuzzcolfunc = R_DrawFuzzColumn;
    699 		transcolfunc = R_DrawTranslatedColumn;
    700 		spanfunc = R_DrawSpan;
    701 	}
    702 	else
    703 	{
    704 		colfunc = basecolfunc = R_DrawColumnLow;
    705 		fuzzcolfunc = R_DrawFuzzColumn;
    706 		transcolfunc = R_DrawTranslatedColumn;
    707 		spanfunc = R_DrawSpanLow;
    708 	}
    709 
    710 	R_InitBuffer (::g->scaledviewwidth, ::g->viewheight);
    711 
    712 	R_InitTextureMapping ();
    713 
    714 	// psprite scales
    715 	::g->pspritescale = FRACUNIT*::g->viewwidth/ORIGINAL_WIDTH;
    716 	::g->pspriteiscale = FRACUNIT*ORIGINAL_WIDTH/::g->viewwidth;
    717 
    718 	// thing clipping
    719 	for (i=0 ; i < ::g->viewwidth ; i++)
    720 		::g->screenheightarray[i] = ::g->viewheight;
    721 
    722 	// planes
    723 	for (i=0 ; i < ::g->viewheight ; i++)
    724 	{
    725 		dy = ((i-::g->viewheight/2)<<FRACBITS)+FRACUNIT/2;
    726 		dy = abs(dy);
    727 		::g->yslope[i] = FixedDiv ( (::g->viewwidth << ::g->detailshift)/2*FRACUNIT, dy);
    728 	}
    729 
    730 	for (i=0 ; i < ::g->viewwidth ; i++)
    731 	{
    732 		cosadj = abs(finecosine[::g->xtoviewangle[i]>>ANGLETOFINESHIFT]);
    733 		::g->distscale[i] = FixedDiv (FRACUNIT,cosadj);
    734 	}
    735 
    736 	// Calculate the light levels to use
    737 	//  for each level / scale combination.
    738 	for (i=0 ; i< LIGHTLEVELS ; i++)
    739 	{
    740 		nocollide_startmap = ((LIGHTLEVELS-1-i)*2)*NUMCOLORMAPS/LIGHTLEVELS;
    741 		for (j=0 ; j<MAXLIGHTSCALE ; j++)
    742 		{
    743 			level = nocollide_startmap - j*SCREENWIDTH/(::g->viewwidth << ::g->detailshift)/DISTMAP;
    744 
    745 			if (level < 0)
    746 				level = 0;
    747 
    748 			if (level >= NUMCOLORMAPS)
    749 				level = NUMCOLORMAPS-1;
    750 
    751 			::g->scalelight[i][j] = ::g->colormaps + level*256;
    752 		}
    753 	}
    754 }
    755 
    756 
    757 
    758 //
    759 // R_Init
    760 //
    761 
    762 
    763 
    764 void R_Init (void)
    765 {
    766 	R_InitData ();
    767 	I_Printf ("\nR_InitData");
    768 	R_InitPointToAngle ();
    769 	I_Printf ("\nR_InitPointToAngle");
    770 	R_InitTables ();
    771 	// ::g->viewwidth / ::g->viewheight / ::g->detailLevel are set by the defaults
    772 	I_Printf ("\nR_InitTables");
    773 
    774 	R_SetViewSize (::g->screenblocks, ::g->detailLevel);
    775 	R_InitPlanes ();
    776 	I_Printf ("\nR_InitPlanes");
    777 	R_InitLightTables ();
    778 	I_Printf ("\nR_InitLightTables");
    779 	R_InitSkyMap ();
    780 	I_Printf ("\nR_InitSkyMap");
    781 	R_InitTranslationTables ();
    782 	I_Printf ("\nR_InitTranslationsTables");
    783 
    784 	::g->framecount = 0;
    785 }
    786 
    787 
    788 //
    789 // R_PointInSubsector
    790 //
    791 subsector_t*
    792 R_PointInSubsector
    793 ( fixed_t	x,
    794  fixed_t	y )
    795 {
    796 	node_t*	node;
    797 	int		side;
    798 	int		nodenum;
    799 
    800 	// single subsector is a special case
    801 	if (!::g->numnodes)				
    802 		return ::g->subsectors;
    803 
    804 	nodenum = ::g->numnodes-1;
    805 
    806 	while (! (nodenum & NF_SUBSECTOR) )
    807 	{
    808 		node = &::g->nodes[nodenum];
    809 		side = R_PointOnSide (x, y, node);
    810 		nodenum = node->children[side];
    811 	}
    812 
    813 	return &::g->subsectors[nodenum & ~NF_SUBSECTOR];
    814 }
    815 
    816 
    817 
    818 //
    819 // R_SetupFrame
    820 //
    821 void R_SetupFrame (player_t* player)
    822 {		
    823 	int		i;
    824 
    825 	::g->viewplayer = player;
    826 	extern void SetViewX( fixed_t ); extern void SetViewY( fixed_t ); extern void SetViewAngle( angle_t );
    827 	SetViewX( player->mo->x );
    828 	SetViewY( player->mo->y );
    829 	SetViewAngle( player->mo->angle + ::g->viewangleoffset );
    830 	::g->extralight = player->extralight;
    831 
    832 	::g->viewz = player->viewz;
    833 
    834 	extern angle_t GetViewAngle();
    835 
    836 	::g->viewsin = finesine[GetViewAngle()>>ANGLETOFINESHIFT];
    837 	::g->viewcos = finecosine[GetViewAngle()>>ANGLETOFINESHIFT];
    838 
    839 	::g->sscount = 0;
    840 
    841 	if (player->fixedcolormap)
    842 	{
    843 		::g->fixedcolormap =
    844 			::g->colormaps
    845 			+ player->fixedcolormap*256*sizeof(lighttable_t);
    846 
    847 		::g->walllights = ::g->scalelightfixed;
    848 
    849 		for (i=0 ; i<MAXLIGHTSCALE ; i++)
    850 			::g->scalelightfixed[i] = ::g->fixedcolormap;
    851 	}
    852 	else
    853 		::g->fixedcolormap = 0;
    854 
    855 	::g->framecount++;
    856 	::g->validcount++;
    857 }
    858 
    859 
    860 
    861 //
    862 // R_RenderView
    863 //
    864 void R_RenderPlayerView (player_t* player)
    865 {
    866 	if ( player->mo == NULL ) {
    867 		return;
    868 	}
    869 
    870 	R_SetupFrame (player);
    871 
    872 	// Clear buffers.
    873 	R_ClearClipSegs ();
    874 	R_ClearDrawSegs ();
    875 	R_ClearPlanes ();
    876 	R_ClearSprites ();
    877 
    878 	// check for new console commands.
    879 	NetUpdate ( NULL );
    880 
    881 	// The head node is the last node output.
    882 	R_RenderBSPNode (::g->numnodes-1);
    883 
    884 	// Check for new console commands.
    885 	NetUpdate ( NULL );
    886 
    887 	R_DrawPlanes ();
    888 
    889 	// Check for new console commands.
    890 	NetUpdate ( NULL );
    891 
    892 	R_DrawMasked ();
    893 
    894 	// Check for new console commands.
    895 	NetUpdate ( NULL );				
    896 }
    897