| /* |
| Copyright (C) 1996-1997 Id Software, Inc. |
| |
| This program is free software; you can redistribute it and/or |
| modify it under the terms of the GNU General Public License |
| as published by the Free Software Foundation; either version 2 |
| of the License, or (at your option) any later version. |
| |
| This program is distributed in the hope that it will be useful, |
| but WITHOUT ANY WARRANTY; without even the implied warranty of |
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
| |
| See the GNU General Public License for more details. |
| |
| You should have received a copy of the GNU General Public License |
| along with this program; if not, write to the Free Software |
| Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
| |
| */ |
| // screen.c -- master for refresh, status bar, console, chat, notify, etc |
| |
| #include "quakedef.h" |
| #include "r_local.h" |
| |
| // only the refresh window will be updated unless these variables are flagged |
| int scr_copytop; |
| int scr_copyeverything; |
| |
| float scr_con_current; |
| float scr_conlines; // lines of console to display |
| |
| float oldscreensize, oldfov; |
| cvar_t scr_viewsize = {"viewsize","100", true}; |
| cvar_t scr_fov = {"fov","90"}; // 10 - 170 |
| cvar_t scr_conspeed = {"scr_conspeed","300"}; |
| cvar_t scr_centertime = {"scr_centertime","2"}; |
| cvar_t scr_showram = {"showram","1"}; |
| cvar_t scr_showturtle = {"showturtle","0"}; |
| cvar_t scr_showpause = {"showpause","1"}; |
| cvar_t scr_printspeed = {"scr_printspeed","8"}; |
| |
| qboolean scr_initialized; // ready to draw |
| |
| qpic_t *scr_ram; |
| qpic_t *scr_net; |
| qpic_t *scr_turtle; |
| |
| int scr_fullupdate; |
| |
| int clearconsole; |
| int clearnotify; |
| |
| viddef_t vid; // global video state |
| |
| vrect_t *pconupdate; |
| vrect_t scr_vrect; |
| |
| qboolean scr_disabled_for_loading; |
| qboolean scr_drawloading; |
| float scr_disabled_time; |
| qboolean scr_skipupdate; |
| |
| qboolean block_drawing; |
| |
| void SCR_ScreenShot_f (void); |
| |
| /* |
| =============================================================================== |
| |
| CENTER PRINTING |
| |
| =============================================================================== |
| */ |
| |
| char scr_centerstring[1024]; |
| float scr_centertime_start; // for slow victory printing |
| float scr_centertime_off; |
| int scr_center_lines; |
| int scr_erase_lines; |
| int scr_erase_center; |
| |
| /* |
| ============== |
| SCR_CenterPrint |
| |
| Called for important messages that should stay in the center of the screen |
| for a few moments |
| ============== |
| */ |
| void SCR_CenterPrint (char *str) |
| { |
| strncpy (scr_centerstring, str, sizeof(scr_centerstring)-1); |
| scr_centertime_off = scr_centertime.value; |
| scr_centertime_start = cl.time; |
| |
| // count the number of lines for centering |
| scr_center_lines = 1; |
| while (*str) |
| { |
| if (*str == '\n') |
| scr_center_lines++; |
| str++; |
| } |
| } |
| |
| void SCR_EraseCenterString (void) |
| { |
| int y; |
| |
| if (scr_erase_center++ > vid.numpages) |
| { |
| scr_erase_lines = 0; |
| return; |
| } |
| |
| if (scr_center_lines <= 4) |
| y = vid.height*0.35; |
| else |
| y = 48; |
| |
| scr_copytop = 1; |
| Draw_TileClear (0, y,vid.width, 8*scr_erase_lines); |
| } |
| |
| void SCR_DrawCenterString (void) |
| { |
| char *start; |
| int l; |
| int j; |
| int x, y; |
| int remaining; |
| |
| // the finale prints the characters one at a time |
| if (cl.intermission) |
| remaining = scr_printspeed.value * (cl.time - scr_centertime_start); |
| else |
| remaining = 9999; |
| |
| scr_erase_center = 0; |
| start = scr_centerstring; |
| |
| if (scr_center_lines <= 4) |
| y = vid.height*0.35; |
| else |
| y = 48; |
| |
| do |
| { |
| // scan the width of the line |
| for (l=0 ; l<40 ; l++) |
| if (start[l] == '\n' || !start[l]) |
| break; |
| x = (vid.width - l*8)/2; |
| for (j=0 ; j<l ; j++, x+=8) |
| { |
| Draw_Character (x, y, start[j]); |
| if (!remaining--) |
| return; |
| } |
| |
| y += 8; |
| |
| while (*start && *start != '\n') |
| start++; |
| |
| if (!*start) |
| break; |
| start++; // skip the \n |
| } while (1); |
| } |
| |
| void SCR_CheckDrawCenterString (void) |
| { |
| scr_copytop = 1; |
| if (scr_center_lines > scr_erase_lines) |
| scr_erase_lines = scr_center_lines; |
| |
| scr_centertime_off -= host_frametime; |
| |
| if (scr_centertime_off <= 0 && !cl.intermission) |
| return; |
| if (key_dest != key_game) |
| return; |
| |
| SCR_DrawCenterString (); |
| } |
| |
| //============================================================================= |
| |
| /* |
| ==================== |
| CalcFov |
| ==================== |
| */ |
| float CalcFov (float fov_x, float width, float height) |
| { |
| float a; |
| float x; |
| |
| if (fov_x < 1 || fov_x > 179) |
| Sys_Error ("Bad fov: %f", fov_x); |
| |
| x = width/tan(fov_x/360*M_PI); |
| |
| a = atan (height/x); |
| |
| a = a*360/M_PI; |
| |
| return a; |
| } |
| |
| /* |
| ================= |
| SCR_CalcRefdef |
| |
| Must be called whenever vid changes |
| Internal use only |
| ================= |
| */ |
| static void SCR_CalcRefdef (void) |
| { |
| vrect_t vrect; |
| float size; |
| |
| scr_fullupdate = 0; // force a background redraw |
| vid.recalc_refdef = 0; |
| |
| // force the status bar to redraw |
| Sbar_Changed (); |
| |
| //======================================== |
| |
| // bound viewsize |
| if (scr_viewsize.value < 30) |
| Cvar_Set ("viewsize","30"); |
| if (scr_viewsize.value > 120) |
| Cvar_Set ("viewsize","120"); |
| |
| // bound field of view |
| if (scr_fov.value < 10) |
| Cvar_Set ("fov","10"); |
| if (scr_fov.value > 170) |
| Cvar_Set ("fov","170"); |
| |
| r_refdef.fov_x = scr_fov.value; |
| r_refdef.fov_y = CalcFov (r_refdef.fov_x, r_refdef.vrect.width, r_refdef.vrect.height); |
| |
| // intermission is always full screen |
| if (cl.intermission) |
| size = 120; |
| else |
| size = scr_viewsize.value; |
| |
| if (size >= 120) |
| sb_lines = 0; // no status bar at all |
| else if (size >= 110) |
| sb_lines = 24; // no inventory |
| else |
| sb_lines = 24+16+8; |
| |
| // these calculations mirror those in R_Init() for r_refdef, but take no |
| // account of water warping |
| vrect.x = 0; |
| vrect.y = 0; |
| vrect.width = vid.width; |
| vrect.height = vid.height; |
| |
| R_SetVrect (&vrect, &scr_vrect, sb_lines); |
| |
| // guard against going from one mode to another that's less than half the |
| // vertical resolution |
| if (scr_con_current > vid.height) |
| scr_con_current = vid.height; |
| |
| // notify the refresh of the change |
| R_ViewChanged (&vrect, sb_lines, vid.aspect); |
| } |
| |
| |
| /* |
| ================= |
| SCR_SizeUp_f |
| |
| Keybinding command |
| ================= |
| */ |
| void SCR_SizeUp_f (void) |
| { |
| Cvar_SetValue ("viewsize",scr_viewsize.value+10); |
| vid.recalc_refdef = 1; |
| } |
| |
| |
| /* |
| ================= |
| SCR_SizeDown_f |
| |
| Keybinding command |
| ================= |
| */ |
| void SCR_SizeDown_f (void) |
| { |
| Cvar_SetValue ("viewsize",scr_viewsize.value-10); |
| vid.recalc_refdef = 1; |
| } |
| |
| //============================================================================ |
| |
| /* |
| ================== |
| SCR_Init |
| ================== |
| */ |
| void SCR_Init (void) |
| { |
| Cvar_RegisterVariable (&scr_fov); |
| Cvar_RegisterVariable (&scr_viewsize); |
| Cvar_RegisterVariable (&scr_conspeed); |
| Cvar_RegisterVariable (&scr_showram); |
| Cvar_RegisterVariable (&scr_showturtle); |
| Cvar_RegisterVariable (&scr_showpause); |
| Cvar_RegisterVariable (&scr_centertime); |
| Cvar_RegisterVariable (&scr_printspeed); |
| |
| // |
| // register our commands |
| // |
| Cmd_AddCommand ("screenshot",SCR_ScreenShot_f); |
| Cmd_AddCommand ("sizeup",SCR_SizeUp_f); |
| Cmd_AddCommand ("sizedown",SCR_SizeDown_f); |
| |
| scr_ram = Draw_PicFromWad ("ram"); |
| scr_net = Draw_PicFromWad ("net"); |
| scr_turtle = Draw_PicFromWad ("turtle"); |
| |
| scr_initialized = true; |
| } |
| |
| |
| |
| /* |
| ============== |
| SCR_DrawRam |
| ============== |
| */ |
| void SCR_DrawRam (void) |
| { |
| if (!scr_showram.value) |
| return; |
| |
| if (!r_cache_thrash) |
| return; |
| |
| Draw_Pic (scr_vrect.x+32, scr_vrect.y, scr_ram); |
| } |
| |
| /* |
| ============== |
| SCR_DrawTurtle |
| ============== |
| */ |
| void SCR_DrawTurtle (void) |
| { |
| static int count; |
| |
| if (!scr_showturtle.value) |
| return; |
| |
| if (host_frametime < 0.1) |
| { |
| count = 0; |
| return; |
| } |
| |
| count++; |
| if (count < 3) |
| return; |
| |
| Draw_Pic (scr_vrect.x, scr_vrect.y, scr_turtle); |
| } |
| |
| /* |
| ============== |
| SCR_DrawNet |
| ============== |
| */ |
| void SCR_DrawNet (void) |
| { |
| if (realtime - cl.last_received_message < 0.3) |
| return; |
| if (cls.demoplayback) |
| return; |
| |
| Draw_Pic (scr_vrect.x+64, scr_vrect.y, scr_net); |
| } |
| |
| /* |
| ============== |
| DrawPause |
| ============== |
| */ |
| void SCR_DrawPause (void) |
| { |
| qpic_t *pic; |
| |
| if (!scr_showpause.value) // turn off for screenshots |
| return; |
| |
| if (!cl.paused) |
| return; |
| |
| pic = Draw_CachePic ("gfx/pause.lmp"); |
| Draw_Pic ( (vid.width - pic->width)/2, |
| (vid.height - 48 - pic->height)/2, pic); |
| } |
| |
| |
| |
| /* |
| ============== |
| SCR_DrawLoading |
| ============== |
| */ |
| void SCR_DrawLoading (void) |
| { |
| qpic_t *pic; |
| |
| if (!scr_drawloading) |
| return; |
| |
| pic = Draw_CachePic ("gfx/loading.lmp"); |
| Draw_Pic ( (vid.width - pic->width)/2, |
| (vid.height - 48 - pic->height)/2, pic); |
| } |
| |
| |
| |
| //============================================================================= |
| |
| |
| /* |
| ================== |
| SCR_SetUpToDrawConsole |
| ================== |
| */ |
| void SCR_SetUpToDrawConsole (void) |
| { |
| Con_CheckResize (); |
| |
| if (scr_drawloading) |
| return; // never a console with loading plaque |
| |
| // decide on the height of the console |
| con_forcedup = !cl.worldmodel || cls.signon != SIGNONS; |
| |
| if (con_forcedup) |
| { |
| scr_conlines = vid.height; // full screen |
| scr_con_current = scr_conlines; |
| } |
| else if (key_dest == key_console) |
| scr_conlines = vid.height/2; // half screen |
| else |
| scr_conlines = 0; // none visible |
| |
| if (scr_conlines < scr_con_current) |
| { |
| scr_con_current -= scr_conspeed.value*host_frametime; |
| if (scr_conlines > scr_con_current) |
| scr_con_current = scr_conlines; |
| |
| } |
| else if (scr_conlines > scr_con_current) |
| { |
| scr_con_current += scr_conspeed.value*host_frametime; |
| if (scr_conlines < scr_con_current) |
| scr_con_current = scr_conlines; |
| } |
| |
| if (clearconsole++ < vid.numpages) |
| { |
| scr_copytop = 1; |
| Draw_TileClear (0,(int)scr_con_current,vid.width, vid.height - (int)scr_con_current); |
| Sbar_Changed (); |
| } |
| else if (clearnotify++ < vid.numpages) |
| { |
| scr_copytop = 1; |
| Draw_TileClear (0,0,vid.width, con_notifylines); |
| } |
| else |
| con_notifylines = 0; |
| } |
| |
| /* |
| ================== |
| SCR_DrawConsole |
| ================== |
| */ |
| void SCR_DrawConsole (void) |
| { |
| if (scr_con_current) |
| { |
| scr_copyeverything = 1; |
| Con_DrawConsole (scr_con_current, true); |
| clearconsole = 0; |
| } |
| else |
| { |
| if (key_dest == key_game || key_dest == key_message) |
| Con_DrawNotify (); // only draw notify in game |
| } |
| } |
| |
| |
| /* |
| ============================================================================== |
| |
| SCREEN SHOTS |
| |
| ============================================================================== |
| */ |
| |
| |
| typedef struct |
| { |
| char manufacturer; |
| char version; |
| char encoding; |
| char bits_per_pixel; |
| unsigned short xmin,ymin,xmax,ymax; |
| unsigned short hres,vres; |
| unsigned char palette[48]; |
| char reserved; |
| char color_planes; |
| unsigned short bytes_per_line; |
| unsigned short palette_type; |
| char filler[58]; |
| unsigned char data; // unbounded |
| } pcx_t; |
| |
| /* |
| ============== |
| WritePCXfile |
| ============== |
| */ |
| void WritePCXfile (char *filename, byte *data, int width, int height, |
| int rowbytes, byte *palette) |
| { |
| int i, j, length; |
| pcx_t *pcx; |
| byte *pack; |
| |
| pcx = Hunk_TempAlloc (width*height*2+1000); |
| if (pcx == NULL) |
| { |
| Con_Printf("SCR_ScreenShot_f: not enough memory\n"); |
| return; |
| } |
| |
| pcx->manufacturer = 0x0a; // PCX id |
| pcx->version = 5; // 256 color |
| pcx->encoding = 1; // uncompressed |
| pcx->bits_per_pixel = 8; // 256 color |
| pcx->xmin = 0; |
| pcx->ymin = 0; |
| pcx->xmax = LittleShort((short)(width-1)); |
| pcx->ymax = LittleShort((short)(height-1)); |
| pcx->hres = LittleShort((short)width); |
| pcx->vres = LittleShort((short)height); |
| Q_memset (pcx->palette,0,sizeof(pcx->palette)); |
| pcx->color_planes = 1; // chunky image |
| pcx->bytes_per_line = LittleShort((short)width); |
| pcx->palette_type = LittleShort(2); // not a grey scale |
| Q_memset (pcx->filler,0,sizeof(pcx->filler)); |
| |
| // pack the image |
| pack = &pcx->data; |
| |
| for (i=0 ; i<height ; i++) |
| { |
| for (j=0 ; j<width ; j++) |
| { |
| if ( (*data & 0xc0) != 0xc0) |
| *pack++ = *data++; |
| else |
| { |
| *pack++ = 0xc1; |
| *pack++ = *data++; |
| } |
| } |
| |
| data += rowbytes - width; |
| } |
| |
| // write the palette |
| *pack++ = 0x0c; // palette ID byte |
| for (i=0 ; i<768 ; i++) |
| *pack++ = *palette++; |
| |
| // write output file |
| length = pack - (byte *)pcx; |
| COM_WriteFile (filename, pcx, length); |
| } |
| |
| |
| |
| /* |
| ================== |
| SCR_ScreenShot_f |
| ================== |
| */ |
| void SCR_ScreenShot_f (void) |
| { |
| int i; |
| char pcxname[80]; |
| char checkname[MAX_OSPATH]; |
| |
| // |
| // find a file name to save it to |
| // |
| strcpy(pcxname,"quake00.pcx"); |
| |
| for (i=0 ; i<=99 ; i++) |
| { |
| pcxname[5] = i/10 + '0'; |
| pcxname[6] = i%10 + '0'; |
| sprintf (checkname, "%s/%s", com_gamedir, pcxname); |
| if (Sys_FileTime(checkname) == -1) |
| break; // file doesn't exist |
| } |
| if (i==100) |
| { |
| Con_Printf ("SCR_ScreenShot_f: Couldn't create a PCX file\n"); |
| return; |
| } |
| |
| // |
| // save the pcx file |
| // |
| D_EnableBackBufferAccess (); // enable direct drawing of console to back |
| // buffer |
| |
| WritePCXfile (pcxname, vid.buffer, vid.width, vid.height, vid.rowbytes, |
| host_basepal); |
| |
| D_DisableBackBufferAccess (); // for adapters that can't stay mapped in |
| // for linear writes all the time |
| |
| Con_Printf ("Wrote %s\n", pcxname); |
| } |
| |
| |
| //============================================================================= |
| |
| |
| /* |
| =============== |
| SCR_BeginLoadingPlaque |
| |
| ================ |
| */ |
| void SCR_BeginLoadingPlaque (void) |
| { |
| S_StopAllSounds (true); |
| |
| if (cls.state != ca_connected) |
| return; |
| if (cls.signon != SIGNONS) |
| return; |
| |
| // redraw with no console and the loading plaque |
| Con_ClearNotify (); |
| scr_centertime_off = 0; |
| scr_con_current = 0; |
| |
| scr_drawloading = true; |
| scr_fullupdate = 0; |
| Sbar_Changed (); |
| SCR_UpdateScreen (); |
| scr_drawloading = false; |
| |
| scr_disabled_for_loading = true; |
| scr_disabled_time = realtime; |
| scr_fullupdate = 0; |
| } |
| |
| /* |
| =============== |
| SCR_EndLoadingPlaque |
| |
| ================ |
| */ |
| void SCR_EndLoadingPlaque (void) |
| { |
| scr_disabled_for_loading = false; |
| scr_fullupdate = 0; |
| Con_ClearNotify (); |
| } |
| |
| //============================================================================= |
| |
| char *scr_notifystring; |
| qboolean scr_drawdialog; |
| |
| void SCR_DrawNotifyString (void) |
| { |
| char *start; |
| int l; |
| int j; |
| int x, y; |
| |
| start = scr_notifystring; |
| |
| y = vid.height*0.35; |
| |
| do |
| { |
| // scan the width of the line |
| for (l=0 ; l<40 ; l++) |
| if (start[l] == '\n' || !start[l]) |
| break; |
| x = (vid.width - l*8)/2; |
| for (j=0 ; j<l ; j++, x+=8) |
| Draw_Character (x, y, start[j]); |
| |
| y += 8; |
| |
| while (*start && *start != '\n') |
| start++; |
| |
| if (!*start) |
| break; |
| start++; // skip the \n |
| } while (1); |
| } |
| |
| /* |
| ================== |
| SCR_ModalMessage |
| |
| Displays a text string in the center of the screen and waits for a Y or N |
| keypress. |
| ================== |
| */ |
| int SCR_ModalMessage (const char *text) |
| { |
| if (cls.state == ca_dedicated) |
| return true; |
| |
| scr_notifystring = text; |
| |
| // draw a fresh screen |
| scr_fullupdate = 0; |
| scr_drawdialog = true; |
| SCR_UpdateScreen (); |
| scr_drawdialog = false; |
| |
| S_ClearBuffer (); // so dma doesn't loop current sound |
| |
| do |
| { |
| key_count = -1; // wait for a key down and up |
| Sys_SendKeyEvents (); |
| } while (key_lastpress != 'y' && key_lastpress != 'n' && key_lastpress != K_ESCAPE); |
| |
| scr_fullupdate = 0; |
| SCR_UpdateScreen (); |
| |
| return key_lastpress == 'y'; |
| } |
| |
| |
| //============================================================================= |
| |
| /* |
| =============== |
| SCR_BringDownConsole |
| |
| Brings the console down and fades the palettes back to normal |
| ================ |
| */ |
| void SCR_BringDownConsole (void) |
| { |
| int i; |
| |
| scr_centertime_off = 0; |
| |
| for (i=0 ; i<20 && scr_conlines != scr_con_current ; i++) |
| SCR_UpdateScreen (); |
| |
| cl.cshifts[0].percent = 0; // no area contents palette on next frame |
| VID_SetPalette (host_basepal); |
| } |
| |
| |
| /* |
| ================== |
| SCR_UpdateScreen |
| |
| This is called every frame, and can also be called explicitly to flush |
| text to the screen. |
| |
| WARNING: be very careful calling this from elsewhere, because the refresh |
| needs almost the entire 256k of stack space! |
| ================== |
| */ |
| void SCR_UpdateScreen (void) |
| { |
| static float oldscr_viewsize; |
| static float oldlcd_x; |
| vrect_t vrect; |
| |
| if (scr_skipupdate || block_drawing) |
| return; |
| |
| scr_copytop = 0; |
| scr_copyeverything = 0; |
| |
| if (scr_disabled_for_loading) |
| { |
| if (realtime - scr_disabled_time > 60) |
| { |
| scr_disabled_for_loading = false; |
| Con_Printf ("load failed.\n"); |
| } |
| else |
| return; |
| } |
| |
| if (cls.state == ca_dedicated) |
| return; // stdout only |
| |
| if (!scr_initialized || !con_initialized) |
| return; // not initialized yet |
| |
| if (scr_viewsize.value != oldscr_viewsize) |
| { |
| oldscr_viewsize = scr_viewsize.value; |
| vid.recalc_refdef = 1; |
| } |
| |
| // |
| // check for vid changes |
| // |
| if (oldfov != scr_fov.value) |
| { |
| oldfov = scr_fov.value; |
| vid.recalc_refdef = true; |
| } |
| |
| if (oldlcd_x != lcd_x.value) |
| { |
| oldlcd_x = lcd_x.value; |
| vid.recalc_refdef = true; |
| } |
| |
| if (oldscreensize != scr_viewsize.value) |
| { |
| oldscreensize = scr_viewsize.value; |
| vid.recalc_refdef = true; |
| } |
| |
| if (vid.recalc_refdef) |
| { |
| // something changed, so reorder the screen |
| SCR_CalcRefdef (); |
| } |
| |
| // |
| // do 3D refresh drawing, and then update the screen |
| // |
| D_EnableBackBufferAccess (); // of all overlay stuff if drawing directly |
| |
| if (scr_fullupdate++ < vid.numpages) |
| { // clear the entire screen |
| scr_copyeverything = 1; |
| Draw_TileClear (0,0,vid.width,vid.height); |
| Sbar_Changed (); |
| } |
| |
| pconupdate = NULL; |
| |
| |
| SCR_SetUpToDrawConsole (); |
| SCR_EraseCenterString (); |
| |
| D_DisableBackBufferAccess (); // for adapters that can't stay mapped in |
| // for linear writes all the time |
| |
| VID_LockBuffer (); |
| |
| V_RenderView (); |
| |
| VID_UnlockBuffer (); |
| |
| D_EnableBackBufferAccess (); // of all overlay stuff if drawing directly |
| |
| if (scr_drawdialog) |
| { |
| Sbar_Draw (); |
| Draw_FadeScreen (); |
| SCR_DrawNotifyString (); |
| scr_copyeverything = true; |
| } |
| else if (scr_drawloading) |
| { |
| SCR_DrawLoading (); |
| Sbar_Draw (); |
| } |
| else if (cl.intermission == 1 && key_dest == key_game) |
| { |
| Sbar_IntermissionOverlay (); |
| } |
| else if (cl.intermission == 2 && key_dest == key_game) |
| { |
| Sbar_FinaleOverlay (); |
| SCR_CheckDrawCenterString (); |
| } |
| else if (cl.intermission == 3 && key_dest == key_game) |
| { |
| SCR_CheckDrawCenterString (); |
| } |
| else |
| { |
| SCR_DrawRam (); |
| SCR_DrawNet (); |
| SCR_DrawTurtle (); |
| SCR_DrawPause (); |
| SCR_CheckDrawCenterString (); |
| Sbar_Draw (); |
| SCR_DrawConsole (); |
| M_Draw (); |
| } |
| |
| D_DisableBackBufferAccess (); // for adapters that can't stay mapped in |
| // for linear writes all the time |
| if (pconupdate) |
| { |
| D_UpdateRects (pconupdate); |
| } |
| |
| V_UpdatePalette (); |
| |
| // |
| // update one of three areas |
| // |
| |
| if (scr_copyeverything) |
| { |
| vrect.x = 0; |
| vrect.y = 0; |
| vrect.width = vid.width; |
| vrect.height = vid.height; |
| vrect.pnext = 0; |
| |
| VID_Update (&vrect); |
| } |
| else if (scr_copytop) |
| { |
| vrect.x = 0; |
| vrect.y = 0; |
| vrect.width = vid.width; |
| vrect.height = vid.height - sb_lines; |
| vrect.pnext = 0; |
| |
| VID_Update (&vrect); |
| } |
| else |
| { |
| vrect.x = scr_vrect.x; |
| vrect.y = scr_vrect.y; |
| vrect.width = scr_vrect.width; |
| vrect.height = scr_vrect.height; |
| vrect.pnext = 0; |
| |
| VID_Update (&vrect); |
| } |
| } |
| |
| |
| /* |
| ================== |
| SCR_UpdateWholeScreen |
| ================== |
| */ |
| void SCR_UpdateWholeScreen (void) |
| { |
| scr_fullupdate = 0; |
| SCR_UpdateScreen (); |
| } |