home *** CD-ROM | disk | FTP | other *** search
/ Enigma Amiga Life 113 / EnigmaAmiga113CD.iso / software / sviluppo / quake_src / screen.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-06-17  |  19.5 KB  |  995 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. // screen.c -- master for refresh, status bar, console, chat, notify, etc
  21.  
  22. #include "quakedef.h"
  23. #include "r_local.h"
  24.  
  25.  
  26. // only the refresh window will be updated unless these variables are flagged 
  27. int     scr_copytop;
  28. int     scr_copyeverything;
  29.  
  30. float   scr_con_current;
  31. float   scr_conlines;   // lines of console to display
  32.  
  33. float   oldscreensize, oldfov;
  34. cvar_t    scr_viewsize = {"viewsize","100", true};
  35. cvar_t    scr_fov = {"fov","90"}; // 10 - 170
  36. cvar_t    scr_conspeed = {"scr_conspeed","300"};
  37. cvar_t    scr_centertime = {"scr_centertime","2"};
  38. cvar_t    scr_showram = {"showram","1"};
  39. cvar_t    scr_showturtle = {"showturtle","0"};
  40. cvar_t    scr_showpause = {"showpause","1"};
  41. cvar_t    scr_printspeed = {"scr_printspeed","8"};
  42.  
  43. qboolean  scr_initialized;    // ready to draw
  44.  
  45. qpic_t    *scr_ram;
  46. qpic_t    *scr_net;
  47. qpic_t    *scr_turtle;
  48.  
  49. int     scr_fullupdate;
  50.  
  51. int     clearconsole;
  52. int     clearnotify;
  53.  
  54. /* viddef_t  vid; @@@ defined in video driver! */ // global video state
  55.  
  56. vrect_t   *pconupdate;
  57. vrect_t   scr_vrect;
  58.  
  59. qboolean  scr_disabled_for_loading;
  60. qboolean  scr_drawloading;
  61. float   scr_disabled_time;
  62. qboolean  scr_skipupdate;
  63.  
  64. qboolean  block_drawing;
  65.  
  66. void SCR_ScreenShot_f (void);
  67.  
  68. /*
  69. ===============================================================================
  70.  
  71. CENTER PRINTING
  72.  
  73. ===============================================================================
  74. */
  75.  
  76. char    scr_centerstring[1024];
  77. float   scr_centertime_start; // for slow victory printing
  78. float   scr_centertime_off;
  79. int     scr_center_lines;
  80. int     scr_erase_lines;
  81. int     scr_erase_center;
  82.  
  83. /*
  84. ==============
  85. SCR_CenterPrint
  86.  
  87. Called for important messages that should stay in the center of the screen
  88. for a few moments
  89. ==============
  90. */
  91. void SCR_CenterPrint (char *str)
  92. {
  93.   strncpy (scr_centerstring, str, sizeof(scr_centerstring)-1);
  94.   scr_centertime_off = scr_centertime.value;
  95.   scr_centertime_start = cl.time;
  96.  
  97. // count the number of lines for centering
  98.   scr_center_lines = 1;
  99.   while (*str)
  100.   {
  101.     if (*str == '\n')
  102.       scr_center_lines++;
  103.     str++;
  104.   }
  105. }
  106.  
  107. void SCR_EraseCenterString (void)
  108. {
  109.   int   y;
  110.  
  111.   if (scr_erase_center++ > vid.numpages)
  112.   {
  113.     scr_erase_lines = 0;
  114.     return;
  115.   }
  116.  
  117.   if (scr_center_lines <= 4)
  118.     y = vid.height*0.35;
  119.   else
  120.     y = 48;
  121.  
  122.   scr_copytop = 1;
  123.   Draw_TileClear (0, y,vid.width, 8*scr_erase_lines);
  124. }
  125.  
  126. void SCR_DrawCenterString (void)
  127. {
  128.   char  *start;
  129.   int   l;
  130.   int   j;
  131.   int   x, y;
  132.   int   remaining;
  133.  
  134. // the finale prints the characters one at a time
  135.   if (cl.intermission)
  136.     remaining = scr_printspeed.value * (cl.time - scr_centertime_start);
  137.   else
  138.     remaining = 9999;
  139.  
  140.   scr_erase_center = 0;
  141.   start = scr_centerstring;
  142.  
  143.   if (scr_center_lines <= 4)
  144.     y = vid.height*0.35;
  145.   else
  146.     y = 48;
  147.  
  148.   do  
  149.   {
  150.   // scan the width of the line
  151.     for (l=0 ; l<40 ; l++)
  152.       if (start[l] == '\n' || !start[l])
  153.         break;
  154.     x = (vid.width - l*8)/2;
  155.     for (j=0 ; j<l ; j++, x+=8)
  156.     {
  157.       Draw_Character (x, y, start[j]);  
  158.       if (!remaining--)
  159.         return;
  160.     }
  161.       
  162.     y += 8;
  163.  
  164.     while (*start && *start != '\n')
  165.       start++;
  166.  
  167.     if (!*start)
  168.       break;
  169.     start++;    // skip the \n
  170.   } while (1);
  171. }
  172.  
  173. void SCR_CheckDrawCenterString (void)
  174. {
  175.   scr_copytop = 1;
  176.   if (scr_center_lines > scr_erase_lines)
  177.     scr_erase_lines = scr_center_lines;
  178.  
  179.   scr_centertime_off -= host_frametime;
  180.   
  181.   if (scr_centertime_off <= 0 && !cl.intermission)
  182.     return;
  183.   if (key_dest != key_game)
  184.     return;
  185.  
  186.   SCR_DrawCenterString ();
  187. }
  188.  
  189. //=============================================================================
  190.  
  191. /*
  192. ====================
  193. CalcFov
  194. ====================
  195. */
  196. float CalcFov (float fov_x, float width, float height)
  197. {
  198.         float   a;
  199.         float   x;
  200.  
  201.         if (fov_x < 1 || fov_x > 179)
  202.                 Sys_Error ("Bad fov: %f", fov_x);
  203.  
  204.         x = width/tan(fov_x/360*M_PI);
  205.  
  206.         a = atan (height/x);
  207.  
  208.         a = a*360/M_PI;
  209.  
  210.         return a;
  211. }
  212.  
  213. /*
  214. =================
  215. SCR_CalcRefdef
  216.  
  217. Must be called whenever vid changes
  218. Internal use only
  219. =================
  220. */
  221. static void SCR_CalcRefdef (void)
  222. {
  223.   vrect_t   vrect;
  224.   float   size;
  225.  
  226.   scr_fullupdate = 0;   // force a background redraw
  227.   vid.recalc_refdef = 0;
  228.  
  229. // force the status bar to redraw
  230.   Sbar_Changed ();
  231.  
  232. //========================================
  233.   
  234. // bound viewsize
  235.   if (scr_viewsize.value < 30)
  236.     Cvar_Set ("viewsize","30");
  237.   if (scr_viewsize.value > 120)
  238.     Cvar_Set ("viewsize","120");
  239.  
  240. // bound field of view
  241.   if (scr_fov.value < 10)
  242.     Cvar_Set ("fov","10");
  243.   if (scr_fov.value > 170)
  244.     Cvar_Set ("fov","170");
  245.  
  246.   r_refdef.fov_x = scr_fov.value;
  247.   r_refdef.fov_y = CalcFov (r_refdef.fov_x, r_refdef.vrect.width, r_refdef.vrect.height);
  248.  
  249. // intermission is always full screen 
  250.   if (cl.intermission)
  251.     size = 120;
  252.   else
  253.     size = scr_viewsize.value;
  254.  
  255.   if (size >= 120)
  256.     sb_lines = 0;   // no status bar at all
  257.   else if (size >= 110)
  258.     sb_lines = 24;    // no inventory
  259.   else
  260.     sb_lines = 24+16+8;
  261.  
  262. // these calculations mirror those in R_Init() for r_refdef, but take no
  263. // account of water warping
  264.   vrect.x = 0;
  265.   vrect.y = 0;
  266.   vrect.width = vid.width;
  267.   vrect.height = vid.height;
  268.  
  269.   R_SetVrect (&vrect, &scr_vrect, sb_lines);
  270.  
  271. // guard against going from one mode to another that's less than half the
  272. // vertical resolution
  273.   if (scr_con_current > vid.height)
  274.     scr_con_current = vid.height;
  275.  
  276. // notify the refresh of the change
  277.   R_ViewChanged (&vrect, sb_lines, vid.aspect);
  278. }
  279.  
  280.  
  281. /*
  282. =================
  283. SCR_SizeUp_f
  284.  
  285. Keybinding command
  286. =================
  287. */
  288. void SCR_SizeUp_f (void)
  289. {
  290.   Cvar_SetValue ("viewsize",scr_viewsize.value+10);
  291.   vid.recalc_refdef = 1;
  292. }
  293.  
  294.  
  295. /*
  296. =================
  297. SCR_SizeDown_f
  298.  
  299. Keybinding command
  300. =================
  301. */
  302. void SCR_SizeDown_f (void)
  303. {
  304.   Cvar_SetValue ("viewsize",scr_viewsize.value-10);
  305.   vid.recalc_refdef = 1;
  306. }
  307.  
  308. //============================================================================
  309.  
  310. /*
  311. ==================
  312. SCR_Init
  313. ==================
  314. */
  315. void SCR_Init (void)
  316. {
  317.   Cvar_RegisterVariable (&scr_fov);
  318. #ifndef AMIGA
  319.   Cvar_RegisterVariable (&scr_viewsize);
  320. #endif
  321.   Cvar_RegisterVariable (&scr_conspeed);
  322.   Cvar_RegisterVariable (&scr_showram);
  323.   Cvar_RegisterVariable (&scr_showturtle);
  324.   Cvar_RegisterVariable (&scr_showpause);
  325.   Cvar_RegisterVariable (&scr_centertime);
  326.   Cvar_RegisterVariable (&scr_printspeed);
  327.  
  328. //
  329. // register our commands
  330. //
  331.   Cmd_AddCommand ("screenshot",SCR_ScreenShot_f);
  332.   Cmd_AddCommand ("sizeup",SCR_SizeUp_f);
  333.   Cmd_AddCommand ("sizedown",SCR_SizeDown_f);
  334.  
  335.   scr_ram = Draw_PicFromWad ("ram");
  336.   scr_net = Draw_PicFromWad ("net");
  337.   scr_turtle = Draw_PicFromWad ("turtle");
  338.  
  339.   scr_initialized = true;
  340. }
  341.  
  342.  
  343.  
  344. /*
  345. ==============
  346. SCR_DrawRam
  347. ==============
  348. */
  349. void SCR_DrawRam (void)
  350. {
  351.   if (!scr_showram.value)
  352.     return;
  353.  
  354.   if (!r_cache_thrash)
  355.     return;
  356.  
  357.   Draw_Pic (scr_vrect.x+32, scr_vrect.y, scr_ram);
  358. }
  359.  
  360. /*
  361. ==============
  362. SCR_DrawTurtle
  363. ==============
  364. */
  365. void SCR_DrawTurtle (void)
  366. {
  367.   static int  count;
  368.   
  369.   if (!scr_showturtle.value)
  370.     return;
  371.  
  372.   if (host_frametime < 0.1)
  373.   {
  374.     count = 0;
  375.     return;
  376.   }
  377.  
  378.   count++;
  379.   if (count < 3)
  380.     return;
  381.  
  382.   Draw_Pic (scr_vrect.x, scr_vrect.y, scr_turtle);
  383. }
  384.  
  385. /*
  386. ==============
  387. SCR_DrawNet
  388. ==============
  389. */
  390. void SCR_DrawNet (void)
  391. {
  392.   if (realtime - cl.last_received_message < 0.3)
  393.     return;
  394.   if (cls.demoplayback)
  395.     return;
  396.  
  397.   Draw_Pic (scr_vrect.x+64, scr_vrect.y, scr_net);
  398. }
  399.  
  400. /*
  401. ==============
  402. DrawPause
  403. ==============
  404. */
  405. void SCR_DrawPause (void)
  406. {
  407.   qpic_t  *pic;
  408.  
  409.   if (!scr_showpause.value)   // turn off for screenshots
  410.     return;
  411.  
  412.   if (!cl.paused)
  413.     return;
  414.  
  415.   pic = Draw_CachePic ("gfx/pause.lmp");
  416.   Draw_Pic ( (vid.width - pic->width)/2, 
  417.     (vid.height - 48 - pic->height)/2, pic);
  418. }
  419.  
  420.  
  421.  
  422. /*
  423. ==============
  424. SCR_DrawLoading
  425. ==============
  426. */
  427. void SCR_DrawLoading (void)
  428. {
  429.   qpic_t  *pic;
  430.  
  431.   if (!scr_drawloading)
  432.     return;
  433.     
  434.   pic = Draw_CachePic ("gfx/loading.lmp");
  435.   Draw_Pic ( (vid.width - pic->width)/2, 
  436.     (vid.height - 48 - pic->height)/2, pic);
  437. }
  438.  
  439.  
  440.  
  441. //=============================================================================
  442.  
  443.  
  444. /*
  445. ==================
  446. SCR_SetUpToDrawConsole
  447. ==================
  448. */
  449. void SCR_SetUpToDrawConsole (void)
  450. {
  451.   Con_CheckResize ();
  452.   
  453.   if (scr_drawloading)
  454.     return;   // never a console with loading plaque
  455.     
  456. // decide on the height of the console
  457.   con_forcedup = !cl.worldmodel || cls.signon != SIGNONS;
  458.  
  459.   if (con_forcedup)
  460.   {
  461.     scr_conlines = vid.height;    // full screen
  462.     scr_con_current = scr_conlines;
  463.   }
  464.   else if (key_dest == key_console)
  465.     scr_conlines = vid.height/2;  // half screen
  466.   else
  467.     scr_conlines = 0;       // none visible
  468.   
  469.   if (scr_conlines < scr_con_current)
  470.   {
  471.     scr_con_current -= scr_conspeed.value*host_frametime;
  472.     if (scr_conlines > scr_con_current)
  473.       scr_con_current = scr_conlines;
  474.  
  475.   }
  476.   else if (scr_conlines > scr_con_current)
  477.   {
  478.     scr_con_current += scr_conspeed.value*host_frametime;
  479.     if (scr_conlines < scr_con_current)
  480.       scr_con_current = scr_conlines;
  481.   }
  482.  
  483.   if (clearconsole++ < vid.numpages)
  484.   {
  485.     scr_copytop = 1;
  486.     Draw_TileClear (0,(int)scr_con_current,vid.width, vid.height - (int)scr_con_current);
  487.     Sbar_Changed ();
  488.   }
  489.   else if (clearnotify++ < vid.numpages)
  490.   {
  491.     scr_copytop = 1;
  492.     Draw_TileClear (0,0,vid.width, con_notifylines);
  493.   }
  494.   else
  495.     con_notifylines = 0;
  496. }
  497.   
  498. /*
  499. ==================
  500. SCR_DrawConsole
  501. ==================
  502. */
  503. void SCR_DrawConsole (void)
  504. {
  505.   if (scr_con_current)
  506.   {
  507.     scr_copyeverything = 1;
  508.     Con_DrawConsole (scr_con_current, true);
  509.     clearconsole = 0;
  510.   }
  511.   else
  512.   {
  513.     if (key_dest == key_game || key_dest == key_message)
  514.       Con_DrawNotify ();  // only draw notify in game
  515.   }
  516. }
  517.  
  518.  
  519. /* 
  520. ============================================================================== 
  521.  
  522.             SCREEN SHOTS 
  523.  
  524. ============================================================================== 
  525. */ 
  526.  
  527.  
  528. typedef struct
  529. {
  530.     char  manufacturer;
  531.     char  version;
  532.     char  encoding;
  533.     char  bits_per_pixel;
  534.     unsigned short  xmin,ymin,xmax,ymax;
  535.     unsigned short  hres,vres;
  536.     unsigned char palette[48];
  537.     char  reserved;
  538.     char  color_planes;
  539.     unsigned short  bytes_per_line;
  540.     unsigned short  palette_type;
  541.     char  filler[58];
  542.     unsigned char data;     // unbounded
  543. } pcx_t;
  544.  
  545. /* 
  546. ============== 
  547. WritePCXfile 
  548. ============== 
  549. */ 
  550. void WritePCXfile (char *filename, byte *data, int width, int height,
  551.   int rowbytes, byte *palette) 
  552. {
  553.   int   i, j, length;
  554.   pcx_t *pcx;
  555.   byte    *pack;
  556.     
  557.   pcx = Hunk_TempAlloc (width*height*2+1000);
  558.   if (pcx == NULL)
  559.   {
  560.     Con_Printf("SCR_ScreenShot_f: not enough memory\n");
  561.     return;
  562.   } 
  563.  
  564.   pcx->manufacturer = 0x0a; // PCX id
  565.   pcx->version = 5;     // 256 color
  566.   pcx->encoding = 1;    // uncompressed
  567.   pcx->bits_per_pixel = 8;    // 256 color
  568.   pcx->xmin = 0;
  569.   pcx->ymin = 0;
  570.   pcx->xmax = LittleShort((short)(width-1));
  571.   pcx->ymax = LittleShort((short)(height-1));
  572.   pcx->hres = LittleShort((short)width);
  573.   pcx->vres = LittleShort((short)height);
  574.   Q_memset (pcx->palette,0,sizeof(pcx->palette));
  575.   pcx->color_planes = 1;    // chunky image
  576.   pcx->bytes_per_line = LittleShort((short)width);
  577.   pcx->palette_type = LittleShort(2);   // not a grey scale
  578.   Q_memset (pcx->filler,0,sizeof(pcx->filler));
  579.  
  580. // pack the image
  581.   pack = &pcx->data;
  582.   
  583.   for (i=0 ; i<height ; i++)
  584.   {
  585.     for (j=0 ; j<width ; j++)
  586.     {
  587.       if ( (*data & 0xc0) != 0xc0)
  588.         *pack++ = *data++;
  589.       else
  590.       {
  591.         *pack++ = 0xc1;
  592.         *pack++ = *data++;
  593.       }
  594.     }
  595.  
  596.     data += rowbytes - width;
  597.   }
  598.       
  599. // write the palette
  600.   *pack++ = 0x0c; // palette ID byte
  601.   for (i=0 ; i<768 ; i++)
  602.     *pack++ = *palette++;
  603.     
  604. // write output file 
  605.   length = pack - (byte *)pcx;
  606.   COM_WriteFile (filename, pcx, length);
  607.  
  608.  
  609.  
  610. /* 
  611. ================== 
  612. SCR_ScreenShot_f
  613. ================== 
  614. */  
  615. void SCR_ScreenShot_f (void) 
  616.   int     i; 
  617.   char    pcxname[80]; 
  618.   char    checkname[MAX_OSPATH];
  619.  
  620. // 
  621. // find a file name to save it to 
  622. // 
  623.   strcpy(pcxname,"quake00.pcx");
  624.     
  625.   for (i=0 ; i<=99 ; i++) 
  626.   { 
  627.     pcxname[5] = i/10 + '0'; 
  628.     pcxname[6] = i%10 + '0'; 
  629.     sprintf (checkname, "%s/%s", com_gamedir, pcxname);
  630.     if (Sys_FileTime(checkname) == -1)
  631.       break;  // file doesn't exist
  632.   } 
  633.   if (i==100) 
  634.   {
  635.     Con_Printf ("SCR_ScreenShot_f: Couldn't create a PCX file\n"); 
  636.     return;
  637.   }
  638.  
  639. // 
  640. // save the pcx file 
  641. // 
  642.   D_EnableBackBufferAccess ();  // enable direct drawing of console to back
  643.                   //  buffer
  644.  
  645.   WritePCXfile (pcxname, vid.buffer, vid.width, vid.height, vid.rowbytes,
  646.           host_basepal);
  647.  
  648.   D_DisableBackBufferAccess (); // for adapters that can't stay mapped in
  649.                   //  for linear writes all the time
  650.  
  651.   Con_Printf ("Wrote %s\n", pcxname);
  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.