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