r_main.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656
  1. /* Emacs style mode select -*- C++ -*-
  2. *-----------------------------------------------------------------------------
  3. *
  4. *
  5. * PrBoom: a Doom port merged with LxDoom and LSDLDoom
  6. * based on BOOM, a modified and improved DOOM engine
  7. * Copyright (C) 1999 by
  8. * id Software, Chi Hoang, Lee Killough, Jim Flynn, Rand Phares, Ty Halderman
  9. * Copyright (C) 1999-2000 by
  10. * Jess Haas, Nicolas Kalkhof, Colin Phipps, Florian Schulze
  11. * Copyright 2005, 2006 by
  12. * Florian Schulze, Colin Phipps, Neil Stevens, Andrey Budko
  13. *
  14. * This program is free software; you can redistribute it and/or
  15. * modify it under the terms of the GNU General Public License
  16. * as published by the Free Software Foundation; either version 2
  17. * of the License, or (at your option) any later version.
  18. *
  19. * This program is distributed in the hope that it will be useful,
  20. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  21. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  22. * GNU General Public License for more details.
  23. *
  24. * You should have received a copy of the GNU General Public License
  25. * along with this program; if not, write to the Free Software
  26. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
  27. * 02111-1307, USA.
  28. *
  29. * DESCRIPTION:
  30. * Rendering main loop and setup functions,
  31. * utility functions (BSP, geometry, trigonometry).
  32. * See tables.c, too.
  33. *
  34. *-----------------------------------------------------------------------------*/
  35. #ifdef HAVE_CONFIG_H
  36. #include "config.h"
  37. #endif
  38. #ifdef USE_SDL
  39. #include "SDL.h"
  40. #endif
  41. #include "doomstat.h"
  42. #include "d_net.h"
  43. #include "w_wad.h"
  44. #include "r_main.h"
  45. #include "r_things.h"
  46. #include "r_plane.h"
  47. #include "r_bsp.h"
  48. #include "r_draw.h"
  49. #include "m_bbox.h"
  50. #include "r_sky.h"
  51. #include "v_video.h"
  52. #include "lprintf.h"
  53. #include "st_stuff.h"
  54. #include "i_main.h"
  55. #include "i_system.h"
  56. #include "g_game.h"
  57. #include "r_demo.h"
  58. #include "r_fps.h"
  59. // Fineangles in the SCREENWIDTH wide window.
  60. #define FIELDOFVIEW 2048
  61. // killough: viewangleoffset is a legacy from the pre-v1.2 days, when Doom
  62. // had Left/Mid/Right viewing. +/-ANG90 offsets were placed here on each
  63. // node, by d_net.c, to set up a L/M/R session.
  64. int viewangleoffset;
  65. int validcount = 1; // increment every time a check is made
  66. const lighttable_t *fixedcolormap;
  67. int centerx, centery;
  68. fixed_t centerxfrac, centeryfrac;
  69. fixed_t viewheightfrac; //e6y: for correct clipping of things
  70. fixed_t projection;
  71. // proff 11/06/98: Added for high-res
  72. fixed_t projectiony;
  73. fixed_t viewx, viewy, viewz;
  74. angle_t viewangle;
  75. fixed_t viewcos, viewsin;
  76. player_t *viewplayer;
  77. extern lighttable_t **walllights;
  78. static mobj_t *oviewer;
  79. //
  80. // precalculated math tables
  81. //
  82. angle_t clipangle;
  83. // The viewangletox[viewangle + FINEANGLES/4] lookup
  84. // maps the visible view angles to screen X coordinates,
  85. // flattening the arc to a flat projection plane.
  86. // There will be many angles mapped to the same X.
  87. int viewangletox[FINEANGLES/2];
  88. // The xtoviewangleangle[] table maps a screen pixel
  89. // to the lowest viewangle that maps back to x ranges
  90. // from clipangle to -clipangle.
  91. angle_t xtoviewangle[MAX_SCREENWIDTH+1]; // killough 2/8/98
  92. // killough 3/20/98: Support dynamic colormaps, e.g. deep water
  93. // killough 4/4/98: support dynamic number of them as well
  94. int numcolormaps;
  95. const lighttable_t *(*c_zlight)[LIGHTLEVELS][MAXLIGHTZ];
  96. const lighttable_t *(*zlight)[MAXLIGHTZ];
  97. const lighttable_t *fullcolormap;
  98. const lighttable_t **colormaps;
  99. // killough 3/20/98, 4/4/98: end dynamic colormaps
  100. int extralight; // bumped light from gun blasts
  101. //
  102. // R_PointOnSide
  103. // Traverse BSP (sub) tree,
  104. // check point against partition plane.
  105. // Returns side 0 (front) or 1 (back).
  106. //
  107. // killough 5/2/98: reformatted
  108. //
  109. PUREFUNC int R_PointOnSide(fixed_t x, fixed_t y, const node_t *node)
  110. {
  111. if (!node->dx)
  112. return x <= node->x ? node->dy > 0 : node->dy < 0;
  113. if (!node->dy)
  114. return y <= node->y ? node->dx < 0 : node->dx > 0;
  115. x -= node->x;
  116. y -= node->y;
  117. // Try to quickly decide by looking at sign bits.
  118. if ((node->dy ^ node->dx ^ x ^ y) < 0)
  119. return (node->dy ^ x) < 0; // (left is negative)
  120. return FixedMul(y, node->dx>>FRACBITS) >= FixedMul(node->dy>>FRACBITS, x);
  121. }
  122. // killough 5/2/98: reformatted
  123. PUREFUNC int R_PointOnSegSide(fixed_t x, fixed_t y, const seg_t *line)
  124. {
  125. fixed_t lx = line->v1->x;
  126. fixed_t ly = line->v1->y;
  127. fixed_t ldx = line->v2->x - lx;
  128. fixed_t ldy = line->v2->y - ly;
  129. if (!ldx)
  130. return x <= lx ? ldy > 0 : ldy < 0;
  131. if (!ldy)
  132. return y <= ly ? ldx < 0 : ldx > 0;
  133. x -= lx;
  134. y -= ly;
  135. // Try to quickly decide by looking at sign bits.
  136. if ((ldy ^ ldx ^ x ^ y) < 0)
  137. return (ldy ^ x) < 0; // (left is negative)
  138. return FixedMul(y, ldx>>FRACBITS) >= FixedMul(ldy>>FRACBITS, x);
  139. }
  140. //
  141. // R_PointToAngle
  142. // To get a global angle from cartesian coordinates,
  143. // the coordinates are flipped until they are in
  144. // the first octant of the coordinate system, then
  145. // the y (<=x) is scaled and divided by x to get a
  146. // tangent (slope) value which is looked up in the
  147. // tantoangle[] table. The +1 size of tantoangle[]
  148. // is to handle the case when x==y without additional
  149. // checking.
  150. //
  151. // killough 5/2/98: reformatted, cleaned up
  152. #include <math.h>
  153. angle_t R_PointToAngle(fixed_t x, fixed_t y)
  154. {
  155. #if 0
  156. // JDC: the oldresult case only hit 10%, making it a net loss.
  157. // JDC: added parenthesis to force constant evaluation
  158. return (int)(atan2(y-viewy, x-viewx) * (ANG180/M_PI) );
  159. #else
  160. static fixed_t oldx, oldy;
  161. static angle_t oldresult;
  162. x -= viewx; y -= viewy;
  163. if ( /* !render_precise && */
  164. // e6y: here is where "slime trails" can SOMETIMES occur
  165. #ifdef GL_DOOM
  166. (V_GetMode() != VID_MODEGL) &&
  167. #endif
  168. (x < INT_MAX/4 && x > -INT_MAX/4 && y < INT_MAX/4 && y > -INT_MAX/4)
  169. )
  170. {
  171. // old R_PointToAngle
  172. return (x || y) ?
  173. x >= 0 ?
  174. y >= 0 ?
  175. (x > y) ? tantoangle[SlopeDiv(y,x)] : // octant 0
  176. ANG90-1-tantoangle[SlopeDiv(x,y)] : // octant 1
  177. x > (y = -y) ? 0-tantoangle[SlopeDiv(y,x)] : // octant 8
  178. ANG270+tantoangle[SlopeDiv(x,y)] : // octant 7
  179. y >= 0 ? (x = -x) > y ? ANG180-1-tantoangle[SlopeDiv(y,x)] : // octant 3
  180. ANG90 + tantoangle[SlopeDiv(x,y)] : // octant 2
  181. (x = -x) > (y = -y) ? ANG180+tantoangle[ SlopeDiv(y,x)] : // octant 4
  182. ANG270-1-tantoangle[SlopeDiv(x,y)] : // octant 5
  183. 0;
  184. }
  185. // R_PointToAngleEx merged into R_PointToAngle
  186. // e6y: The precision of the code above is abysmal so use the CRT atan2 function instead!
  187. if (oldx != x || oldy != y)
  188. {
  189. oldx = x;
  190. oldy = y;
  191. oldresult = (int)(atan2(y, x) * ANG180/M_PI );
  192. }
  193. return oldresult;
  194. #endif
  195. }
  196. angle_t R_PointToAngle2(fixed_t viewx, fixed_t viewy, fixed_t x, fixed_t y)
  197. {
  198. return (y -= viewy, (x -= viewx) || y) ?
  199. x >= 0 ?
  200. y >= 0 ?
  201. (x > y) ? tantoangle[SlopeDiv(y,x)] : // octant 0
  202. ANG90-1-tantoangle[SlopeDiv(x,y)] : // octant 1
  203. x > (y = -y) ? 0-tantoangle[SlopeDiv(y,x)] : // octant 8
  204. ANG270+tantoangle[SlopeDiv(x,y)] : // octant 7
  205. y >= 0 ? (x = -x) > y ? ANG180-1-tantoangle[SlopeDiv(y,x)] : // octant 3
  206. ANG90 + tantoangle[SlopeDiv(x,y)] : // octant 2
  207. (x = -x) > (y = -y) ? ANG180+tantoangle[ SlopeDiv(y,x)] : // octant 4
  208. ANG270-1-tantoangle[SlopeDiv(x,y)] : // octant 5
  209. 0;
  210. }
  211. //
  212. // R_InitTextureMapping
  213. //
  214. // killough 5/2/98: reformatted
  215. static void R_InitTextureMapping (void)
  216. {
  217. register int i,x;
  218. fixed_t focallength;
  219. // Use tangent table to generate viewangletox:
  220. // viewangletox will give the next greatest x
  221. // after the view angle.
  222. //
  223. // Calc focallength
  224. // so FIELDOFVIEW angles covers SCREENWIDTH.
  225. focallength = FixedDiv(centerxfrac, finetangent[FINEANGLES/4+FIELDOFVIEW/2]);
  226. for (i=0 ; i<FINEANGLES/2 ; i++)
  227. {
  228. int t;
  229. if (finetangent[i] > FRACUNIT*2)
  230. t = -1;
  231. else
  232. if (finetangent[i] < -FRACUNIT*2)
  233. t = viewwidth+1;
  234. else
  235. {
  236. t = FixedMul(finetangent[i], focallength);
  237. t = (centerxfrac - t + FRACUNIT-1) >> FRACBITS;
  238. if (t < -1)
  239. t = -1;
  240. else
  241. if (t > viewwidth+1)
  242. t = viewwidth+1;
  243. }
  244. viewangletox[i] = t;
  245. }
  246. // Scan viewangletox[] to generate xtoviewangle[]:
  247. // xtoviewangle will give the smallest view angle
  248. // that maps to x.
  249. for (x=0; x<=viewwidth; x++)
  250. {
  251. for (i=0; viewangletox[i] > x; i++)
  252. ;
  253. xtoviewangle[x] = (i<<ANGLETOFINESHIFT)-ANG90;
  254. }
  255. // Take out the fencepost cases from viewangletox.
  256. for (i=0; i<FINEANGLES/2; i++)
  257. if (viewangletox[i] == -1)
  258. viewangletox[i] = 0;
  259. else
  260. if (viewangletox[i] == viewwidth+1)
  261. viewangletox[i] = viewwidth;
  262. clipangle = xtoviewangle[0];
  263. }
  264. //
  265. // R_InitLightTables
  266. //
  267. #define DISTMAP 2
  268. static void R_InitLightTables (void)
  269. {
  270. int i;
  271. // killough 4/4/98: dynamic colormaps
  272. c_zlight = malloc(sizeof(*c_zlight) * numcolormaps);
  273. // Calculate the light levels to use
  274. // for each level / distance combination.
  275. for (i=0; i< LIGHTLEVELS; i++)
  276. {
  277. int j, startmap = ((LIGHTLEVELS-1-i)*2)*NUMCOLORMAPS/LIGHTLEVELS;
  278. for (j=0; j<MAXLIGHTZ; j++)
  279. {
  280. // CPhipps - use 320 here instead of SCREENWIDTH, otherwise hires is
  281. // brighter than normal res
  282. int scale = FixedDiv ((320/2*FRACUNIT), (j+1)<<LIGHTZSHIFT);
  283. int t, level = startmap - (scale >>= LIGHTSCALESHIFT)/DISTMAP;
  284. if (level < 0)
  285. level = 0;
  286. else
  287. if (level >= NUMCOLORMAPS)
  288. level = NUMCOLORMAPS-1;
  289. // killough 3/20/98: Initialize multiple colormaps
  290. level *= 256;
  291. for (t=0; t<numcolormaps; t++) // killough 4/4/98
  292. c_zlight[t][i][j] = colormaps[t] + level;
  293. }
  294. }
  295. }
  296. //
  297. // R_SetViewSize
  298. // Do not really change anything here,
  299. // because it might be in the middle of a refresh.
  300. // The change will take effect next refresh.
  301. //
  302. boolean setsizeneeded;
  303. int setblocks;
  304. void R_SetViewSize(int blocks)
  305. {
  306. setsizeneeded = true;
  307. setblocks = blocks;
  308. }
  309. //
  310. // R_ExecuteSetViewSize
  311. //
  312. void R_ExecuteSetViewSize (void)
  313. {
  314. int i;
  315. setsizeneeded = false;
  316. if (setblocks == 11)
  317. {
  318. scaledviewwidth = SCREENWIDTH;
  319. viewheight = SCREENHEIGHT;
  320. }
  321. // proff 09/24/98: Added for high-res
  322. else if (setblocks == 10)
  323. {
  324. scaledviewwidth = SCREENWIDTH;
  325. viewheight = SCREENHEIGHT-ST_SCALED_HEIGHT;
  326. }
  327. else
  328. {
  329. // proff 08/17/98: Changed for high-res
  330. scaledviewwidth = setblocks*SCREENWIDTH/10;
  331. viewheight = (setblocks*(SCREENHEIGHT-ST_SCALED_HEIGHT)/10) & ~7;
  332. }
  333. viewwidth = scaledviewwidth;
  334. viewheightfrac = viewheight<<FRACBITS;//e6y
  335. centery = viewheight/2;
  336. centerx = viewwidth/2;
  337. centerxfrac = centerx<<FRACBITS;
  338. centeryfrac = centery<<FRACBITS;
  339. projection = centerxfrac;
  340. // proff 11/06/98: Added for high-res
  341. projectiony = ((SCREENHEIGHT * centerx * 320) / 200) / SCREENWIDTH * FRACUNIT;
  342. R_InitBuffer (scaledviewwidth, viewheight);
  343. R_InitTextureMapping();
  344. // psprite scales
  345. // proff 08/17/98: Changed for high-res
  346. pspritescale = FRACUNIT*viewwidth/320;
  347. pspriteiscale = FRACUNIT*320/viewwidth;
  348. // proff 11/06/98: Added for high-res
  349. pspriteyscale = (((SCREENHEIGHT*viewwidth)/SCREENWIDTH) << FRACBITS) / 200;
  350. // thing clipping
  351. for (i=0 ; i<viewwidth ; i++)
  352. screenheightarray[i] = viewheight;
  353. // planes
  354. for (i=0 ; i<viewheight ; i++)
  355. { // killough 5/2/98: reformatted
  356. fixed_t dy = D_abs(((i-viewheight/2)<<FRACBITS)+FRACUNIT/2);
  357. // proff 08/17/98: Changed for high-res
  358. yslope[i] = FixedDiv(projectiony, dy);
  359. }
  360. for (i=0 ; i<viewwidth ; i++)
  361. {
  362. fixed_t cosadj = D_abs(finecosine[xtoviewangle[i]>>ANGLETOFINESHIFT]);
  363. distscale[i] = FixedDiv(FRACUNIT,cosadj);
  364. }
  365. }
  366. //
  367. // R_Init
  368. //
  369. extern int screenblocks;
  370. void R_Init (void)
  371. {
  372. // CPhipps - R_DrawColumn isn't constant anymore, so must
  373. // initialise in code
  374. // current column draw function
  375. lprintf(LO_INFO, "\nR_LoadTrigTables: ");
  376. R_LoadTrigTables();
  377. lprintf(LO_INFO, "\nR_InitData: ");
  378. R_InitData();
  379. R_SetViewSize(screenblocks);
  380. lprintf(LO_INFO, "\nR_Init: R_InitPlanes ");
  381. R_InitPlanes();
  382. lprintf(LO_INFO, "R_InitLightTables ");
  383. R_InitLightTables();
  384. lprintf(LO_INFO, "R_InitSkyMap ");
  385. R_InitSkyMap();
  386. lprintf(LO_INFO, "R_InitTranslationsTables ");
  387. R_InitTranslationTables();
  388. lprintf(LO_INFO, "R_InitPatches ");
  389. R_InitPatches();
  390. }
  391. //
  392. // R_PointInSubsector
  393. //
  394. // killough 5/2/98: reformatted, cleaned up
  395. subsector_t *R_PointInSubsector(fixed_t x, fixed_t y)
  396. {
  397. int nodenum = numnodes-1;
  398. // special case for trivial maps (single subsector, no nodes)
  399. if (numnodes == 0)
  400. return subsectors;
  401. while (!(nodenum & NF_SUBSECTOR))
  402. nodenum = nodes[nodenum].children[R_PointOnSide(x, y, nodes+nodenum)];
  403. return &subsectors[nodenum & ~NF_SUBSECTOR];
  404. }
  405. //
  406. // R_SetupFrame
  407. //
  408. static void R_SetupFrame (player_t *player)
  409. {
  410. int cm;
  411. boolean NoInterpolate = paused || (menuactive && !demoplayback);
  412. viewplayer = player;
  413. if (player->mo != oviewer || NoInterpolate)
  414. {
  415. R_ResetViewInterpolation ();
  416. oviewer = player->mo;
  417. }
  418. tic_vars.frac = I_GetTimeFrac ();
  419. if (NoInterpolate)
  420. tic_vars.frac = FRACUNIT;
  421. R_InterpolateView (player, tic_vars.frac);
  422. extralight = player->extralight;
  423. viewsin = finesine[viewangle>>ANGLETOFINESHIFT];
  424. viewcos = finecosine[viewangle>>ANGLETOFINESHIFT];
  425. R_DoInterpolations(tic_vars.frac);
  426. // killough 3/20/98, 4/4/98: select colormap based on player status
  427. if (player->mo->subsector->sector->heightsec != -1)
  428. {
  429. const sector_t *s = player->mo->subsector->sector->heightsec + sectors;
  430. cm = viewz < s->floorheight ? s->bottommap : viewz > s->ceilingheight ?
  431. s->topmap : s->midmap;
  432. if (cm < 0 || cm > numcolormaps)
  433. cm = 0;
  434. }
  435. else
  436. cm = 0;
  437. fullcolormap = colormaps[cm];
  438. zlight = c_zlight[cm];
  439. if (player->fixedcolormap)
  440. {
  441. fixedcolormap = fullcolormap // killough 3/20/98: use fullcolormap
  442. + player->fixedcolormap*256*sizeof(lighttable_t);
  443. }
  444. else
  445. fixedcolormap = 0;
  446. validcount++;
  447. }
  448. int autodetect_hom = 0; // killough 2/7/98: HOM autodetection flag
  449. //
  450. // R_ShowStats
  451. //
  452. int rendered_visplanes, rendered_segs, rendered_vissprites;
  453. boolean rendering_stats;
  454. static void R_ShowStats(void)
  455. {
  456. //e6y
  457. #if USE_SDL
  458. static unsigned int FPS_SavedTick = 0, FPS_FrameCount = 0;
  459. unsigned int tick = SDL_GetTicks();
  460. FPS_FrameCount++;
  461. if(tick >= FPS_SavedTick + 1000)
  462. {
  463. doom_printf((V_GetMode() == VID_MODEGL)
  464. ?"Frame rate %d fps\nWalls %d, Flats %d, Sprites %d"
  465. :"Frame rate %d fps\nSegs %d, Visplanes %d, Sprites %d",
  466. 1000 * FPS_FrameCount / (tick - FPS_SavedTick), rendered_segs,
  467. rendered_visplanes, rendered_vissprites);
  468. FPS_SavedTick = tick;
  469. FPS_FrameCount = 0;
  470. }
  471. #else
  472. #define KEEPTIMES 10
  473. static int keeptime[KEEPTIMES], showtime;
  474. int now = I_GetTime();
  475. if (now - showtime > 35) {
  476. doom_printf((V_GetMode() == VID_MODEGL)
  477. ?"Frame rate %d fps\nWalls %d, Flats %d, Sprites %d"
  478. :"Frame rate %d fps\nSegs %d, Visplanes %d, Sprites %d",
  479. (35*KEEPTIMES)/(now - keeptime[0]), rendered_segs,
  480. rendered_visplanes, rendered_vissprites);
  481. showtime = now;
  482. }
  483. memmove(keeptime, keeptime+1, sizeof(keeptime[0]) * (KEEPTIMES-1));
  484. keeptime[KEEPTIMES-1] = now;
  485. #endif //e6y
  486. }
  487. //
  488. // R_RenderView
  489. //
  490. void R_RenderPlayerView (player_t* player)
  491. {
  492. R_SetupFrame (player);
  493. // Clear buffers.
  494. R_ClearClipSegs ();
  495. R_ClearDrawSegs ();
  496. R_ClearPlanes ();
  497. R_ClearSprites ();
  498. rendered_segs = rendered_visplanes = 0;
  499. if (V_GetMode() == VID_MODEGL)
  500. {
  501. #ifdef GL_DOOM
  502. // proff 11/99: clear buffers
  503. gld_InitDrawScene();
  504. // proff 11/99: switch to perspective mode
  505. gld_StartDrawScene();
  506. #endif
  507. } else {
  508. if (autodetect_hom)
  509. { // killough 2/10/98: add flashing red HOM indicators
  510. unsigned char color=(gametic % 20) < 9 ? 0xb0 : 0;
  511. V_FillRect(0, viewwindowx, viewwindowy, viewwidth, viewheight, color);
  512. R_DrawViewBorder();
  513. }
  514. }
  515. // check for new console commands.
  516. #ifdef HAVE_NET
  517. NetUpdate ();
  518. #endif
  519. // The head node is the last node output.
  520. R_RenderBSPNode (numnodes-1);
  521. R_ResetColumnBuffer();
  522. // Check for new console commands.
  523. #ifdef HAVE_NET
  524. NetUpdate ();
  525. #endif
  526. if (V_GetMode() != VID_MODEGL)
  527. R_DrawPlanes ();
  528. // Check for new console commands.
  529. #ifdef HAVE_NET
  530. NetUpdate ();
  531. #endif
  532. if (V_GetMode() != VID_MODEGL) {
  533. R_DrawMasked ();
  534. R_ResetColumnBuffer();
  535. }
  536. // Check for new console commands.
  537. #ifdef HAVE_NET
  538. NetUpdate ();
  539. #endif
  540. if (V_GetMode() == VID_MODEGL) {
  541. #ifdef GL_DOOM
  542. // proff 11/99: draw the scene
  543. gld_DrawScene(player);
  544. // proff 11/99: finishing off
  545. gld_EndDrawScene();
  546. #endif
  547. }
  548. if (rendering_stats) R_ShowStats();
  549. R_RestoreInterpolations();
  550. }