home *** CD-ROM | disk | FTP | other *** search
/ Enigma Amiga Life 113 / EnigmaAmiga113CD.iso / software / sviluppo / glquake_src / gl_screen.c < prev    next >
C/C++ Source or Header  |  2000-03-06  |  19KB  |  946 lines

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