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