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