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