1/*
2Copyright (C) 1996-1997 Id Software, Inc.
3
4This program is free software; you can redistribute it and/or
5modify it under the terms of the GNU General Public License
6as published by the Free Software Foundation; either version 2
7of the License, or (at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
13See the GNU General Public License for more details.
14
15You should have received a copy of the GNU General Public License
16along with this program; if not, write to the Free Software
17Foundation, 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
26int			scr_copytop;
27int			scr_copyeverything;
28
29float		scr_con_current;
30float		scr_conlines;		// lines of console to display
31
32float		oldscreensize, oldfov;
33cvar_t		scr_viewsize = {"viewsize","100", true};
34cvar_t		scr_fov = {"fov","90"};	// 10 - 170
35cvar_t		scr_conspeed = {"scr_conspeed","300"};
36cvar_t		scr_centertime = {"scr_centertime","2"};
37cvar_t		scr_showram = {"showram","1"};
38cvar_t		scr_showturtle = {"showturtle","0"};
39cvar_t		scr_showpause = {"showpause","1"};
40cvar_t		scr_printspeed = {"scr_printspeed","8"};
41
42qboolean	scr_initialized;		// ready to draw
43
44qpic_t		*scr_ram;
45qpic_t		*scr_net;
46qpic_t		*scr_turtle;
47
48int			scr_fullupdate;
49
50int			clearconsole;
51int			clearnotify;
52
53viddef_t	vid;				// global video state
54
55vrect_t		*pconupdate;
56vrect_t		scr_vrect;
57
58qboolean	scr_disabled_for_loading;
59qboolean	scr_drawloading;
60float		scr_disabled_time;
61qboolean	scr_skipupdate;
62
63qboolean	block_drawing;
64
65void SCR_ScreenShot_f (void);
66
67/*
68===============================================================================
69
70CENTER PRINTING
71
72===============================================================================
73*/
74
75char		scr_centerstring[1024];
76float		scr_centertime_start;	// for slow victory printing
77float		scr_centertime_off;
78int			scr_center_lines;
79int			scr_erase_lines;
80int			scr_erase_center;
81
82/*
83==============
84SCR_CenterPrint
85
86Called for important messages that should stay in the center of the screen
87for a few moments
88==============
89*/
90void 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
106void 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
125void 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
172void 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====================
192CalcFov
193====================
194*/
195float 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=================
214SCR_CalcRefdef
215
216Must be called whenever vid changes
217Internal use only
218=================
219*/
220static 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=================
282SCR_SizeUp_f
283
284Keybinding command
285=================
286*/
287void SCR_SizeUp_f (void)
288{
289	Cvar_SetValue ("viewsize",scr_viewsize.value+10);
290	vid.recalc_refdef = 1;
291}
292
293
294/*
295=================
296SCR_SizeDown_f
297
298Keybinding command
299=================
300*/
301void SCR_SizeDown_f (void)
302{
303	Cvar_SetValue ("viewsize",scr_viewsize.value-10);
304	vid.recalc_refdef = 1;
305}
306
307//============================================================================
308
309/*
310==================
311SCR_Init
312==================
313*/
314void 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==============
343SCR_DrawRam
344==============
345*/
346void 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==============
359SCR_DrawTurtle
360==============
361*/
362void 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==============
384SCR_DrawNet
385==============
386*/
387void 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==============
399DrawPause
400==============
401*/
402void 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==============
421SCR_DrawLoading
422==============
423*/
424void 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==================
443SCR_SetUpToDrawConsole
444==================
445*/
446void 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==================
497SCR_DrawConsole
498==================
499*/
500void 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
525typedef 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==============
544WritePCXfile
545==============
546*/
547void 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==================
610SCR_ScreenShot_f
611==================
612*/
613void 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===============
659SCR_BeginLoadingPlaque
660
661================
662*/
663void 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===============
690SCR_EndLoadingPlaque
691
692================
693*/
694void SCR_EndLoadingPlaque (void)
695{
696	scr_disabled_for_loading = false;
697	scr_fullupdate = 0;
698	Con_ClearNotify ();
699}
700
701//=============================================================================
702
703char	*scr_notifystring;
704qboolean	scr_drawdialog;
705
706void 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==================
740SCR_ModalMessage
741
742Displays a text string in the center of the screen and waits for a Y or N
743keypress.
744==================
745*/
746int SCR_ModalMessage (const 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===============
778SCR_BringDownConsole
779
780Brings the console down and fades the palettes back to normal
781================
782*/
783void 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==================
799SCR_UpdateScreen
800
801This is called every frame, and can also be called explicitly to flush
802text to the screen.
803
804WARNING: be very careful calling this from elsewhere, because the refresh
805needs almost the entire 256k of stack space!
806==================
807*/
808void 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==================
984SCR_UpdateWholeScreen
985==================
986*/
987void SCR_UpdateWholeScreen (void)
988{
989	scr_fullupdate = 0;
990	SCR_UpdateScreen ();
991}
992