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