Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

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