gl_screen.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924
  1. /*
  2. Copyright (C) 1996-1997 Id Software, Inc.
  3. This program is free software; you can redistribute it and/or
  4. modify it under the terms of the GNU General Public License
  5. as published by the Free Software Foundation; either version 2
  6. of the License, or (at your option) any later version.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  10. See the GNU General Public License for more details.
  11. You should have received a copy of the GNU General Public License
  12. along with this program; if not, write to the Free Software
  13. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  14. */
  15. // screen.c -- master for refresh, status bar, console, chat, notify, etc
  16. #include "quakedef.h"
  17. /*
  18. background clear
  19. rendering
  20. turtle/net/ram icons
  21. sbar
  22. centerprint / slow centerprint
  23. notify lines
  24. intermission / finale overlay
  25. loading plaque
  26. console
  27. menu
  28. required background clears
  29. required update regions
  30. syncronous draw mode or async
  31. One off screen buffer, with updates either copied or xblited
  32. Need to double buffer?
  33. async draw will require the refresh area to be cleared, because it will be
  34. xblited, but sync draw can just ignore it.
  35. sync
  36. draw
  37. CenterPrint ()
  38. SlowPrint ()
  39. Screen_Update ();
  40. Con_Printf ();
  41. net
  42. turn off messages option
  43. the refresh is allways rendered, unless the console is full screen
  44. console is:
  45. notify lines
  46. half
  47. full
  48. */
  49. int glx, gly, glwidth, glheight;
  50. // only the refresh window will be updated unless these variables are flagged
  51. int scr_copytop;
  52. int scr_copyeverything;
  53. float scr_con_current;
  54. float scr_conlines; // lines of console to display
  55. float oldscreensize, oldfov;
  56. cvar_t scr_viewsize = {"viewsize","100", true};
  57. cvar_t scr_fov = {"fov","90"}; // 10 - 170
  58. cvar_t scr_conspeed = {"scr_conspeed","300"};
  59. cvar_t scr_centertime = {"scr_centertime","2"};
  60. cvar_t scr_showram = {"showram","1"};
  61. cvar_t scr_showturtle = {"showturtle","0"};
  62. cvar_t scr_showpause = {"showpause","1"};
  63. cvar_t scr_printspeed = {"scr_printspeed","8"};
  64. cvar_t gl_triplebuffer = {"gl_triplebuffer", "1", true };
  65. extern cvar_t crosshair;
  66. qboolean scr_initialized; // ready to draw
  67. qpic_t *scr_ram;
  68. qpic_t *scr_net;
  69. qpic_t *scr_turtle;
  70. int scr_fullupdate;
  71. int clearconsole;
  72. int clearnotify;
  73. int sb_lines;
  74. viddef_t vid; // global video state
  75. vrect_t scr_vrect;
  76. qboolean scr_disabled_for_loading;
  77. qboolean scr_drawloading;
  78. float scr_disabled_time;
  79. qboolean block_drawing;
  80. void SCR_ScreenShot_f (void);
  81. /*
  82. ===============================================================================
  83. CENTER PRINTING
  84. ===============================================================================
  85. */
  86. char scr_centerstring[1024];
  87. float scr_centertime_start; // for slow victory printing
  88. float scr_centertime_off;
  89. int scr_center_lines;
  90. int scr_erase_lines;
  91. int scr_erase_center;
  92. /*
  93. ==============
  94. SCR_CenterPrint
  95. Called for important messages that should stay in the center of the screen
  96. for a few moments
  97. ==============
  98. */
  99. void SCR_CenterPrint (char *str)
  100. {
  101. strncpy (scr_centerstring, str, sizeof(scr_centerstring)-1);
  102. scr_centertime_off = scr_centertime.value;
  103. scr_centertime_start = cl.time;
  104. // count the number of lines for centering
  105. scr_center_lines = 1;
  106. while (*str)
  107. {
  108. if (*str == '\n')
  109. scr_center_lines++;
  110. str++;
  111. }
  112. }
  113. void SCR_DrawCenterString (void)
  114. {
  115. char *start;
  116. int l;
  117. int j;
  118. int x, y;
  119. int remaining;
  120. // the finale prints the characters one at a time
  121. if (cl.intermission)
  122. remaining = scr_printspeed.value * (cl.time - scr_centertime_start);
  123. else
  124. remaining = 9999;
  125. scr_erase_center = 0;
  126. start = scr_centerstring;
  127. if (scr_center_lines <= 4)
  128. y = vid.height*0.35;
  129. else
  130. y = 48;
  131. do
  132. {
  133. // scan the width of the line
  134. for (l=0 ; l<40 ; l++)
  135. if (start[l] == '\n' || !start[l])
  136. break;
  137. x = (vid.width - l*8)/2;
  138. for (j=0 ; j<l ; j++, x+=8)
  139. {
  140. Draw_Character (x, y, start[j]);
  141. if (!remaining--)
  142. return;
  143. }
  144. y += 8;
  145. while (*start && *start != '\n')
  146. start++;
  147. if (!*start)
  148. break;
  149. start++; // skip the \n
  150. } while (1);
  151. }
  152. void SCR_CheckDrawCenterString (void)
  153. {
  154. scr_copytop = 1;
  155. if (scr_center_lines > scr_erase_lines)
  156. scr_erase_lines = scr_center_lines;
  157. scr_centertime_off -= host_frametime;
  158. if (scr_centertime_off <= 0 && !cl.intermission)
  159. return;
  160. if (key_dest != key_game)
  161. return;
  162. SCR_DrawCenterString ();
  163. }
  164. //=============================================================================
  165. /*
  166. ====================
  167. CalcFov
  168. ====================
  169. */
  170. float CalcFov (float fov_x, float width, float height)
  171. {
  172. float a;
  173. float x;
  174. if (fov_x < 1 || fov_x > 179)
  175. Sys_Error ("Bad fov: %f", fov_x);
  176. x = width/tan(fov_x/360*M_PI);
  177. a = atan (height/x);
  178. a = a*360/M_PI;
  179. return a;
  180. }
  181. /*
  182. =================
  183. SCR_CalcRefdef
  184. Must be called whenever vid changes
  185. Internal use only
  186. =================
  187. */
  188. static void SCR_CalcRefdef (void)
  189. {
  190. vrect_t vrect;
  191. float size;
  192. int h;
  193. qboolean full = false;
  194. scr_fullupdate = 0; // force a background redraw
  195. vid.recalc_refdef = 0;
  196. // force the status bar to redraw
  197. Sbar_Changed ();
  198. //========================================
  199. // bound viewsize
  200. if (scr_viewsize.value < 30)
  201. Cvar_Set ("viewsize","30");
  202. if (scr_viewsize.value > 120)
  203. Cvar_Set ("viewsize","120");
  204. // bound field of view
  205. if (scr_fov.value < 10)
  206. Cvar_Set ("fov","10");
  207. if (scr_fov.value > 170)
  208. Cvar_Set ("fov","170");
  209. // intermission is always full screen
  210. if (cl.intermission)
  211. size = 120;
  212. else
  213. size = scr_viewsize.value;
  214. if (size >= 120)
  215. sb_lines = 0; // no status bar at all
  216. else if (size >= 110)
  217. sb_lines = 24; // no inventory
  218. else
  219. sb_lines = 24+16+8;
  220. if (scr_viewsize.value >= 100.0) {
  221. full = true;
  222. size = 100.0;
  223. } else
  224. size = scr_viewsize.value;
  225. if (cl.intermission)
  226. {
  227. full = true;
  228. size = 100;
  229. sb_lines = 0;
  230. }
  231. size /= 100.0;
  232. h = vid.height - sb_lines;
  233. r_refdef.vrect.width = vid.width * size;
  234. if (r_refdef.vrect.width < 96)
  235. {
  236. size = 96.0 / r_refdef.vrect.width;
  237. r_refdef.vrect.width = 96; // min for icons
  238. }
  239. r_refdef.vrect.height = vid.height * size;
  240. if (r_refdef.vrect.height > vid.height - sb_lines)
  241. r_refdef.vrect.height = vid.height - sb_lines;
  242. if (r_refdef.vrect.height > vid.height)
  243. r_refdef.vrect.height = vid.height;
  244. r_refdef.vrect.x = (vid.width - r_refdef.vrect.width)/2;
  245. if (full)
  246. r_refdef.vrect.y = 0;
  247. else
  248. r_refdef.vrect.y = (h - r_refdef.vrect.height)/2;
  249. r_refdef.fov_x = scr_fov.value;
  250. r_refdef.fov_y = CalcFov (r_refdef.fov_x, r_refdef.vrect.width, r_refdef.vrect.height);
  251. scr_vrect = r_refdef.vrect;
  252. }
  253. /*
  254. =================
  255. SCR_SizeUp_f
  256. Keybinding command
  257. =================
  258. */
  259. void SCR_SizeUp_f (void)
  260. {
  261. Cvar_SetValue ("viewsize",scr_viewsize.value+10);
  262. vid.recalc_refdef = 1;
  263. }
  264. /*
  265. =================
  266. SCR_SizeDown_f
  267. Keybinding command
  268. =================
  269. */
  270. void SCR_SizeDown_f (void)
  271. {
  272. Cvar_SetValue ("viewsize",scr_viewsize.value-10);
  273. vid.recalc_refdef = 1;
  274. }
  275. //============================================================================
  276. /*
  277. ==================
  278. SCR_Init
  279. ==================
  280. */
  281. void SCR_Init (void)
  282. {
  283. Cvar_RegisterVariable (&scr_fov);
  284. Cvar_RegisterVariable (&scr_viewsize);
  285. Cvar_RegisterVariable (&scr_conspeed);
  286. Cvar_RegisterVariable (&scr_showram);
  287. Cvar_RegisterVariable (&scr_showturtle);
  288. Cvar_RegisterVariable (&scr_showpause);
  289. Cvar_RegisterVariable (&scr_centertime);
  290. Cvar_RegisterVariable (&scr_printspeed);
  291. Cvar_RegisterVariable (&gl_triplebuffer);
  292. //
  293. // register our commands
  294. //
  295. Cmd_AddCommand ("screenshot",SCR_ScreenShot_f);
  296. Cmd_AddCommand ("sizeup",SCR_SizeUp_f);
  297. Cmd_AddCommand ("sizedown",SCR_SizeDown_f);
  298. scr_ram = Draw_PicFromWad ("ram");
  299. scr_net = Draw_PicFromWad ("net");
  300. scr_turtle = Draw_PicFromWad ("turtle");
  301. scr_initialized = true;
  302. }
  303. /*
  304. ==============
  305. SCR_DrawRam
  306. ==============
  307. */
  308. void SCR_DrawRam (void)
  309. {
  310. if (!scr_showram.value)
  311. return;
  312. if (!r_cache_thrash)
  313. return;
  314. Draw_Pic (scr_vrect.x+32, scr_vrect.y, scr_ram);
  315. }
  316. /*
  317. ==============
  318. SCR_DrawTurtle
  319. ==============
  320. */
  321. void SCR_DrawTurtle (void)
  322. {
  323. static int count;
  324. if (!scr_showturtle.value)
  325. return;
  326. if (host_frametime < 0.1)
  327. {
  328. count = 0;
  329. return;
  330. }
  331. count++;
  332. if (count < 3)
  333. return;
  334. Draw_Pic (scr_vrect.x, scr_vrect.y, scr_turtle);
  335. }
  336. /*
  337. ==============
  338. SCR_DrawNet
  339. ==============
  340. */
  341. void SCR_DrawNet (void)
  342. {
  343. if (realtime - cl.last_received_message < 0.3)
  344. return;
  345. if (cls.demoplayback)
  346. return;
  347. Draw_Pic (scr_vrect.x+64, scr_vrect.y, scr_net);
  348. }
  349. /*
  350. ==============
  351. DrawPause
  352. ==============
  353. */
  354. void SCR_DrawPause (void)
  355. {
  356. qpic_t *pic;
  357. if (!scr_showpause.value) // turn off for screenshots
  358. return;
  359. if (!cl.paused)
  360. return;
  361. pic = Draw_CachePic ("gfx/pause.lmp");
  362. Draw_Pic ( (vid.width - pic->width)/2,
  363. (vid.height - 48 - pic->height)/2, pic);
  364. }
  365. /*
  366. ==============
  367. SCR_DrawLoading
  368. ==============
  369. */
  370. void SCR_DrawLoading (void)
  371. {
  372. qpic_t *pic;
  373. if (!scr_drawloading)
  374. return;
  375. pic = Draw_CachePic ("gfx/loading.lmp");
  376. Draw_Pic ( (vid.width - pic->width)/2,
  377. (vid.height - 48 - pic->height)/2, pic);
  378. }
  379. //=============================================================================
  380. /*
  381. ==================
  382. SCR_SetUpToDrawConsole
  383. ==================
  384. */
  385. void SCR_SetUpToDrawConsole (void)
  386. {
  387. Con_CheckResize ();
  388. if (scr_drawloading)
  389. return; // never a console with loading plaque
  390. // decide on the height of the console
  391. con_forcedup = !cl.worldmodel || cls.signon != SIGNONS;
  392. if (con_forcedup)
  393. {
  394. scr_conlines = vid.height; // full screen
  395. scr_con_current = scr_conlines;
  396. }
  397. else if (key_dest == key_console)
  398. scr_conlines = vid.height/2; // half screen
  399. else
  400. scr_conlines = 0; // none visible
  401. if (scr_conlines < scr_con_current)
  402. {
  403. scr_con_current -= scr_conspeed.value*host_frametime;
  404. if (scr_conlines > scr_con_current)
  405. scr_con_current = scr_conlines;
  406. }
  407. else if (scr_conlines > scr_con_current)
  408. {
  409. scr_con_current += scr_conspeed.value*host_frametime;
  410. if (scr_conlines < scr_con_current)
  411. scr_con_current = scr_conlines;
  412. }
  413. if (clearconsole++ < vid.numpages)
  414. {
  415. Sbar_Changed ();
  416. }
  417. else if (clearnotify++ < vid.numpages)
  418. {
  419. }
  420. else
  421. con_notifylines = 0;
  422. }
  423. /*
  424. ==================
  425. SCR_DrawConsole
  426. ==================
  427. */
  428. void SCR_DrawConsole (void)
  429. {
  430. if (scr_con_current)
  431. {
  432. scr_copyeverything = 1;
  433. Con_DrawConsole (scr_con_current, true);
  434. clearconsole = 0;
  435. }
  436. else
  437. {
  438. if (key_dest == key_game || key_dest == key_message)
  439. Con_DrawNotify (); // only draw notify in game
  440. }
  441. }
  442. /*
  443. ==============================================================================
  444. SCREEN SHOTS
  445. ==============================================================================
  446. */
  447. typedef struct _TargaHeader {
  448. unsigned char id_length, colormap_type, image_type;
  449. unsigned short colormap_index, colormap_length;
  450. unsigned char colormap_size;
  451. unsigned short x_origin, y_origin, width, height;
  452. unsigned char pixel_size, attributes;
  453. } TargaHeader;
  454. /*
  455. ==================
  456. SCR_ScreenShot_f
  457. ==================
  458. */
  459. void SCR_ScreenShot_f (void)
  460. {
  461. byte *buffer;
  462. char pcxname[80];
  463. char checkname[MAX_OSPATH];
  464. int i, c, temp;
  465. //
  466. // find a file name to save it to
  467. //
  468. strcpy(pcxname,"quake00.tga");
  469. for (i=0 ; i<=99 ; i++)
  470. {
  471. pcxname[5] = i/10 + '0';
  472. pcxname[6] = i%10 + '0';
  473. sprintf (checkname, "%s/%s", com_gamedir, pcxname);
  474. if (Sys_FileTime(checkname) == -1)
  475. break; // file doesn't exist
  476. }
  477. if (i==100)
  478. {
  479. Con_Printf ("SCR_ScreenShot_f: Couldn't create a PCX file\n");
  480. return;
  481. }
  482. buffer = malloc(glwidth*glheight*3 + 18);
  483. memset (buffer, 0, 18);
  484. buffer[2] = 2; // uncompressed type
  485. buffer[12] = glwidth&255;
  486. buffer[13] = glwidth>>8;
  487. buffer[14] = glheight&255;
  488. buffer[15] = glheight>>8;
  489. buffer[16] = 24; // pixel size
  490. glReadPixels (glx, gly, glwidth, glheight, GL_RGB, GL_UNSIGNED_BYTE, buffer+18 );
  491. // swap rgb to bgr
  492. c = 18+glwidth*glheight*3;
  493. for (i=18 ; i<c ; i+=3)
  494. {
  495. temp = buffer[i];
  496. buffer[i] = buffer[i+2];
  497. buffer[i+2] = temp;
  498. }
  499. COM_WriteFile (pcxname, buffer, glwidth*glheight*3 + 18 );
  500. free (buffer);
  501. Con_Printf ("Wrote %s\n", pcxname);
  502. }
  503. //=============================================================================
  504. /*
  505. ===============
  506. SCR_BeginLoadingPlaque
  507. ================
  508. */
  509. void SCR_BeginLoadingPlaque (void)
  510. {
  511. S_StopAllSounds (true);
  512. if (cls.state != ca_connected)
  513. return;
  514. if (cls.signon != SIGNONS)
  515. return;
  516. // redraw with no console and the loading plaque
  517. Con_ClearNotify ();
  518. scr_centertime_off = 0;
  519. scr_con_current = 0;
  520. scr_drawloading = true;
  521. scr_fullupdate = 0;
  522. Sbar_Changed ();
  523. SCR_UpdateScreen ();
  524. scr_drawloading = false;
  525. scr_disabled_for_loading = true;
  526. scr_disabled_time = realtime;
  527. scr_fullupdate = 0;
  528. }
  529. /*
  530. ===============
  531. SCR_EndLoadingPlaque
  532. ================
  533. */
  534. void SCR_EndLoadingPlaque (void)
  535. {
  536. scr_disabled_for_loading = false;
  537. scr_fullupdate = 0;
  538. Con_ClearNotify ();
  539. }
  540. //=============================================================================
  541. char *scr_notifystring;
  542. qboolean scr_drawdialog;
  543. void SCR_DrawNotifyString (void)
  544. {
  545. char *start;
  546. int l;
  547. int j;
  548. int x, y;
  549. start = scr_notifystring;
  550. y = vid.height*0.35;
  551. do
  552. {
  553. // scan the width of the line
  554. for (l=0 ; l<40 ; l++)
  555. if (start[l] == '\n' || !start[l])
  556. break;
  557. x = (vid.width - l*8)/2;
  558. for (j=0 ; j<l ; j++, x+=8)
  559. Draw_Character (x, y, start[j]);
  560. y += 8;
  561. while (*start && *start != '\n')
  562. start++;
  563. if (!*start)
  564. break;
  565. start++; // skip the \n
  566. } while (1);
  567. }
  568. /*
  569. ==================
  570. SCR_ModalMessage
  571. Displays a text string in the center of the screen and waits for a Y or N
  572. keypress.
  573. ==================
  574. */
  575. int SCR_ModalMessage (char *text)
  576. {
  577. if (cls.state == ca_dedicated)
  578. return true;
  579. scr_notifystring = text;
  580. // draw a fresh screen
  581. scr_fullupdate = 0;
  582. scr_drawdialog = true;
  583. SCR_UpdateScreen ();
  584. scr_drawdialog = false;
  585. S_ClearBuffer (); // so dma doesn't loop current sound
  586. do
  587. {
  588. key_count = -1; // wait for a key down and up
  589. Sys_SendKeyEvents ();
  590. } while (key_lastpress != 'y' && key_lastpress != 'n' && key_lastpress != K_ESCAPE);
  591. scr_fullupdate = 0;
  592. SCR_UpdateScreen ();
  593. return key_lastpress == 'y';
  594. }
  595. //=============================================================================
  596. /*
  597. ===============
  598. SCR_BringDownConsole
  599. Brings the console down and fades the palettes back to normal
  600. ================
  601. */
  602. void SCR_BringDownConsole (void)
  603. {
  604. int i;
  605. scr_centertime_off = 0;
  606. for (i=0 ; i<20 && scr_conlines != scr_con_current ; i++)
  607. SCR_UpdateScreen ();
  608. cl.cshifts[0].percent = 0; // no area contents palette on next frame
  609. VID_SetPalette (host_basepal);
  610. }
  611. void SCR_TileClear (void)
  612. {
  613. if (r_refdef.vrect.x > 0) {
  614. // left
  615. Draw_TileClear (0, 0, r_refdef.vrect.x, vid.height - sb_lines);
  616. // right
  617. Draw_TileClear (r_refdef.vrect.x + r_refdef.vrect.width, 0,
  618. vid.width - r_refdef.vrect.x + r_refdef.vrect.width,
  619. vid.height - sb_lines);
  620. }
  621. if (r_refdef.vrect.y > 0) {
  622. // top
  623. Draw_TileClear (r_refdef.vrect.x, 0,
  624. r_refdef.vrect.x + r_refdef.vrect.width,
  625. r_refdef.vrect.y);
  626. // bottom
  627. Draw_TileClear (r_refdef.vrect.x,
  628. r_refdef.vrect.y + r_refdef.vrect.height,
  629. r_refdef.vrect.width,
  630. vid.height - sb_lines -
  631. (r_refdef.vrect.height + r_refdef.vrect.y));
  632. }
  633. }
  634. /*
  635. ==================
  636. SCR_UpdateScreen
  637. This is called every frame, and can also be called explicitly to flush
  638. text to the screen.
  639. WARNING: be very careful calling this from elsewhere, because the refresh
  640. needs almost the entire 256k of stack space!
  641. ==================
  642. */
  643. void SCR_UpdateScreen (void)
  644. {
  645. static float oldscr_viewsize;
  646. vrect_t vrect;
  647. if (block_drawing)
  648. return;
  649. vid.numpages = 2 + gl_triplebuffer.value;
  650. scr_copytop = 0;
  651. scr_copyeverything = 0;
  652. if (scr_disabled_for_loading)
  653. {
  654. if (realtime - scr_disabled_time > 60)
  655. {
  656. scr_disabled_for_loading = false;
  657. Con_Printf ("load failed.\n");
  658. }
  659. else
  660. return;
  661. }
  662. if (!scr_initialized || !con_initialized)
  663. return; // not initialized yet
  664. GL_BeginRendering (&glx, &gly, &glwidth, &glheight);
  665. //
  666. // determine size of refresh window
  667. //
  668. if (oldfov != scr_fov.value)
  669. {
  670. oldfov = scr_fov.value;
  671. vid.recalc_refdef = true;
  672. }
  673. if (oldscreensize != scr_viewsize.value)
  674. {
  675. oldscreensize = scr_viewsize.value;
  676. vid.recalc_refdef = true;
  677. }
  678. if (vid.recalc_refdef)
  679. SCR_CalcRefdef ();
  680. //
  681. // do 3D refresh drawing, and then update the screen
  682. //
  683. SCR_SetUpToDrawConsole ();
  684. V_RenderView ();
  685. GL_Set2D ();
  686. //
  687. // draw any areas not covered by the refresh
  688. //
  689. SCR_TileClear ();
  690. if (scr_drawdialog)
  691. {
  692. Sbar_Draw ();
  693. Draw_FadeScreen ();
  694. SCR_DrawNotifyString ();
  695. scr_copyeverything = true;
  696. }
  697. else if (scr_drawloading)
  698. {
  699. SCR_DrawLoading ();
  700. Sbar_Draw ();
  701. }
  702. else if (cl.intermission == 1 && key_dest == key_game)
  703. {
  704. Sbar_IntermissionOverlay ();
  705. }
  706. else if (cl.intermission == 2 && key_dest == key_game)
  707. {
  708. Sbar_FinaleOverlay ();
  709. SCR_CheckDrawCenterString ();
  710. }
  711. else
  712. {
  713. if (crosshair.value)
  714. Draw_Character (scr_vrect.x + scr_vrect.width/2, scr_vrect.y + scr_vrect.height/2, '+');
  715. SCR_DrawRam ();
  716. SCR_DrawNet ();
  717. SCR_DrawTurtle ();
  718. SCR_DrawPause ();
  719. SCR_CheckDrawCenterString ();
  720. Sbar_Draw ();
  721. SCR_DrawConsole ();
  722. M_Draw ();
  723. }
  724. V_UpdatePalette ();
  725. GL_EndRendering ();
  726. }