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