cleaned up nearly all of the externs in .c files (moved to appropriate .h files)
[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 always 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 float   scr_con_current;
76 float   scr_conlines;           // lines of console to display
77
78 float   oldscreensize, oldfov;
79 cvar_t  scr_viewsize = {"viewsize","100", true};
80 cvar_t  scr_fov = {"fov","90"}; // 10 - 170
81 cvar_t  scr_conspeed = {"scr_conspeed","300"};
82 cvar_t  scr_centertime = {"scr_centertime","2"};
83 cvar_t  scr_showram = {"showram","1"};
84 cvar_t  scr_showturtle = {"showturtle","0"};
85 cvar_t  scr_showpause = {"showpause","1"};
86 cvar_t  scr_printspeed = {"scr_printspeed","8"};
87 cvar_t  showfps = {"showfps", "0", true};
88 cvar_t  r_render = {"r_render", "1"};
89 cvar_t  r_brightness = {"r_brightness", "1", true}; // LordHavoc: a method of operating system independent color correction
90 cvar_t  r_contrast = {"r_contrast", "1", true}; // LordHavoc: a method of operating system independent color correction
91
92 qboolean        scr_initialized;                // ready to draw
93
94 qpic_t          *scr_ram;
95 qpic_t          *scr_net;
96 qpic_t          *scr_turtle;
97
98 int                     clearconsole;
99 int                     clearnotify;
100
101 qboolean        scr_disabled_for_loading;
102 //qboolean      scr_drawloading;
103 //float         scr_disabled_time;
104
105 void SCR_ScreenShot_f (void);
106
107 /*
108 ===============================================================================
109
110 CENTER PRINTING
111
112 ===============================================================================
113 */
114
115 char            scr_centerstring[1024];
116 float           scr_centertime_start;   // for slow victory printing
117 float           scr_centertime_off;
118 int                     scr_center_lines;
119 int                     scr_erase_lines;
120 int                     scr_erase_center;
121
122 /*
123 ==============
124 SCR_CenterPrint
125
126 Called for important messages that should stay in the center of the screen
127 for a few moments
128 ==============
129 */
130 void SCR_CenterPrint (char *str)
131 {
132         strncpy (scr_centerstring, str, sizeof(scr_centerstring)-1);
133         scr_centertime_off = scr_centertime.value;
134         scr_centertime_start = cl.time;
135
136 // count the number of lines for centering
137         scr_center_lines = 1;
138         while (*str)
139         {
140                 if (*str == '\n')
141                         scr_center_lines++;
142                 str++;
143         }
144 }
145
146
147 void SCR_DrawCenterString (void)
148 {
149         char    *start;
150         int             l;
151         int             x, y;
152         int             remaining;
153
154 // the finale prints the characters one at a time
155         if (cl.intermission)
156                 remaining = scr_printspeed.value * (cl.time - scr_centertime_start);
157         else
158                 remaining = 9999;
159
160         scr_erase_center = 0;
161         start = scr_centerstring;
162
163         if (scr_center_lines <= 4)
164                 y = vid.height*0.35;
165         else
166                 y = 48;
167
168         do      
169         {
170         // scan the width of the line
171                 for (l=0 ; l<40 ; l++)
172                         if (start[l] == '\n' || !start[l])
173                                 break;
174                 x = (vid.width - l*8)/2;
175                 // LordHavoc: speedup
176                 if (l > 0)
177                 {
178                         if (remaining < l)
179                                 l = remaining;
180                         Draw_String(x, y, start, l);
181                         remaining -= l;
182                         if (remaining <= 0)
183                                 return;
184                 }
185                 /*
186                 for (j=0 ; j<l ; j++, x+=8)
187                 {
188                         Draw_Character (x, y, start[j]);        
189                         if (!remaining--)
190                                 return;
191                 }
192                 */
193                         
194                 y += 8;
195
196                 while (*start && *start != '\n')
197                         start++;
198
199                 if (!*start)
200                         break;
201                 start++;                // skip the \n
202         } while (1);
203 }
204
205 void SCR_CheckDrawCenterString (void)
206 {
207         if (scr_center_lines > scr_erase_lines)
208                 scr_erase_lines = scr_center_lines;
209
210         scr_centertime_off -= host_frametime;
211         
212         if (scr_centertime_off <= 0 && !cl.intermission)
213                 return;
214         if (key_dest != key_game)
215                 return;
216
217         SCR_DrawCenterString ();
218 }
219
220 //=============================================================================
221
222 /*
223 ====================
224 CalcFov
225 ====================
226 */
227 float CalcFov (float fov_x, float width, float height)
228 {
229         float   a;
230         float   x;
231
232         if (fov_x < 1 || fov_x > 179)
233                 Sys_Error ("Bad fov: %f", fov_x);
234
235         x = width/tan(fov_x/360*M_PI);
236
237         a = atan (height/x);
238
239         a = a*360/M_PI;
240
241         return a;
242 }
243
244 /*
245 =================
246 SCR_CalcRefdef
247
248 Must be called whenever vid changes
249 Internal use only
250 =================
251 */
252 static void SCR_CalcRefdef (void)
253 {
254         float           size;
255         int             h;
256         qboolean                full = false;
257
258
259         vid.recalc_refdef = 0;
260
261 //========================================
262         
263 // bound viewsize
264         if (scr_viewsize.value < 30)
265                 Cvar_Set ("viewsize","30");
266         if (scr_viewsize.value > 120)
267                 Cvar_Set ("viewsize","120");
268
269 // bound field of view
270         if (scr_fov.value < 10)
271                 Cvar_Set ("fov","10");
272         if (scr_fov.value > 170)
273                 Cvar_Set ("fov","170");
274
275 // intermission is always full screen   
276         if (cl.intermission)
277                 size = 120;
278         else
279                 size = scr_viewsize.value;
280
281         if (size >= 120)
282                 sb_lines = 0;           // no status bar at all
283         else if (size >= 110)
284                 sb_lines = 24;          // no inventory
285         else
286                 sb_lines = 24+16+8;
287
288         if (scr_viewsize.value >= 100.0)
289         {
290                 full = true;
291                 size = 100.0;
292         }
293         else
294                 size = scr_viewsize.value;
295         if (cl.intermission)
296         {
297                 full = true;
298                 size = 100;
299                 sb_lines = 0;
300         }
301         size /= 100.0;
302
303         // LordHavoc: always fullyscreen rendering
304         h = vid.height/* - sb_lines*/;
305
306         r_refdef.vrect.width = vid.width * size;
307         if (r_refdef.vrect.width < 96)
308         {
309                 size = 96.0 / r_refdef.vrect.width;
310                 r_refdef.vrect.width = 96;      // min for icons
311         }
312
313         r_refdef.vrect.height = vid.height * size;
314         //if (r_refdef.vrect.height > vid.height - sb_lines)
315         //      r_refdef.vrect.height = vid.height - sb_lines;
316         if (r_refdef.vrect.height > (int) vid.height)
317                         r_refdef.vrect.height = vid.height;
318         r_refdef.vrect.x = (vid.width - r_refdef.vrect.width)/2;
319         if (full)
320                 r_refdef.vrect.y = 0;
321         else 
322                 r_refdef.vrect.y = (h - r_refdef.vrect.height)/2;
323
324         r_refdef.fov_x = scr_fov.value;
325         r_refdef.fov_y = CalcFov (r_refdef.fov_x, r_refdef.vrect.width, r_refdef.vrect.height);
326 }
327
328
329 /*
330 =================
331 SCR_SizeUp_f
332
333 Keybinding command
334 =================
335 */
336 void SCR_SizeUp_f (void)
337 {
338         Cvar_SetValue ("viewsize",scr_viewsize.value+10);
339         vid.recalc_refdef = 1;
340 }
341
342
343 /*
344 =================
345 SCR_SizeDown_f
346
347 Keybinding command
348 =================
349 */
350 void SCR_SizeDown_f (void)
351 {
352         Cvar_SetValue ("viewsize",scr_viewsize.value-10);
353         vid.recalc_refdef = 1;
354 }
355
356 //============================================================================
357
358 void gl_screen_start(void)
359 {
360         scr_ram = Draw_PicFromWad ("ram");
361         scr_net = Draw_PicFromWad ("net");
362         scr_turtle = Draw_PicFromWad ("turtle");
363 }
364
365 void gl_screen_shutdown(void)
366 {
367 }
368
369 void gl_screen_newmap(void)
370 {
371 }
372
373 /*
374 ==================
375 SCR_Init
376 ==================
377 */
378 void GL_Screen_Init (void)
379 {
380
381         Cvar_RegisterVariable (&scr_fov);
382         Cvar_RegisterVariable (&scr_viewsize);
383         Cvar_RegisterVariable (&scr_conspeed);
384         Cvar_RegisterVariable (&scr_showram);
385         Cvar_RegisterVariable (&scr_showturtle);
386         Cvar_RegisterVariable (&scr_showpause);
387         Cvar_RegisterVariable (&scr_centertime);
388         Cvar_RegisterVariable (&scr_printspeed);
389         Cvar_RegisterVariable (&showfps);
390         Cvar_RegisterVariable (&r_render);
391         Cvar_RegisterVariable (&r_brightness);
392         Cvar_RegisterVariable (&r_contrast);
393 #ifdef NORENDER
394         r_render.value = 0;
395 #endif
396
397 //
398 // register our commands
399 //
400         Cmd_AddCommand ("screenshot",SCR_ScreenShot_f);
401         Cmd_AddCommand ("sizeup",SCR_SizeUp_f);
402         Cmd_AddCommand ("sizedown",SCR_SizeDown_f);
403
404         scr_initialized = true;
405
406         R_RegisterModule("GL_Screen", gl_screen_start, gl_screen_shutdown, gl_screen_newmap);
407 }
408
409
410
411 /*
412 ==============
413 SCR_DrawRam
414 ==============
415 */
416 void SCR_DrawRam (void)
417 {
418         if (!scr_showram.value)
419                 return;
420
421         if (!r_cache_thrash)
422                 return;
423
424         Draw_Pic (32, 0, scr_ram);
425 }
426
427 /*
428 ==============
429 SCR_DrawTurtle
430 ==============
431 */
432 void SCR_DrawTurtle (void)
433 {
434         static int      count;
435         
436         if (!scr_showturtle.value)
437                 return;
438
439         if (cl.frametime < 0.1)
440         {
441                 count = 0;
442                 return;
443         }
444
445         count++;
446         if (count < 3)
447                 return;
448
449         Draw_Pic (0, 0, scr_turtle);
450 }
451
452 /*
453 ==============
454 SCR_DrawNet
455 ==============
456 */
457 void SCR_DrawNet (void)
458 {
459         if (realtime - cl.last_received_message < 0.3)
460                 return;
461         if (cls.demoplayback)
462                 return;
463
464         Draw_Pic (64, 0, scr_net);
465 }
466
467 /*
468 ==============
469 DrawPause
470 ==============
471 */
472 void SCR_DrawPause (void)
473 {
474         qpic_t  *pic;
475
476         if (!scr_showpause.value)               // turn off for screenshots
477                 return;
478
479         if (!cl.paused)
480                 return;
481
482         pic = Draw_CachePic ("gfx/pause.lmp");
483         Draw_Pic ( (vid.width - pic->width)/2, 
484                 (vid.height - 48 - pic->height)/2, pic);
485 }
486
487
488
489 /*
490 ==============
491 SCR_DrawLoading
492 ==============
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 ==================
515 SCR_SetUpToDrawConsole
516 ==================
517 */
518 void SCR_SetUpToDrawConsole (void)
519 {
520         Con_CheckResize ();
521         
522         //if (scr_drawloading)
523         //      return;         // never a console with loading plaque
524
525 // decide on the height of the console
526         con_forcedup = !cl.worldmodel || cls.signon != SIGNONS;
527
528         if (con_forcedup)
529         {
530                 scr_conlines = vid.height;              // full screen
531                 scr_con_current = scr_conlines;
532         }
533         else if (key_dest == key_console)
534                 scr_conlines = vid.height/2;    // half screen
535         else
536                 scr_conlines = 0;                               // none visible
537         
538         if (scr_conlines < scr_con_current)
539         {
540                 scr_con_current -= scr_conspeed.value*host_realframetime;
541                 if (scr_conlines > scr_con_current)
542                         scr_con_current = scr_conlines;
543
544         }
545         else if (scr_conlines > scr_con_current)
546         {
547                 scr_con_current += scr_conspeed.value*host_realframetime;
548                 if (scr_conlines < scr_con_current)
549                         scr_con_current = scr_conlines;
550         }
551 }
552         
553 /*
554 ==================
555 SCR_DrawConsole
556 ==================
557 */
558 void SCR_DrawConsole (void)
559 {
560         if (scr_con_current)
561         {
562                 Con_DrawConsole (scr_con_current, true);
563                 clearconsole = 0;
564         }
565         else
566         {
567                 if (key_dest == key_game || key_dest == key_message)
568                         Con_DrawNotify ();      // only draw notify in game
569         }
570 }
571
572
573 /* 
574 ============================================================================== 
575  
576                                                 SCREEN SHOTS 
577  
578 ============================================================================== 
579 */ 
580
581 /*
582 ================== 
583 SCR_ScreenShot_f
584 ================== 
585 */
586 void SCR_ScreenShot_f (void) 
587 {
588         byte            *buffer;
589         char            filename[80]; 
590         char            checkname[MAX_OSPATH];
591         int                     i;
592 // 
593 // find a file name to save it to 
594 // 
595         strcpy(filename,"dp0000.tga");
596                 
597         for (i=0 ; i<=9999 ; i++) 
598         { 
599                 filename[2] = (i/1000)%10 + '0'; 
600                 filename[3] = (i/ 100)%10 + '0'; 
601                 filename[4] = (i/  10)%10 + '0'; 
602                 filename[5] = (i/   1)%10 + '0'; 
603                 sprintf (checkname, "%s/%s", com_gamedir, filename);
604                 if (Sys_FileTime(checkname) == -1)
605                         break;  // file doesn't exist
606         } 
607         if (i==10000)
608         {
609                 Con_Printf ("SCR_ScreenShot_f: Couldn't create a TGA file\n"); 
610                 return;
611         }
612
613         buffer = qmalloc(glwidth*glheight*3);
614         glReadPixels (glx, gly, glwidth, glheight, GL_RGB, GL_UNSIGNED_BYTE, buffer); 
615         Image_WriteTGARGB_preflipped(filename, glwidth, glheight, buffer);
616
617         qfree(buffer);
618         Con_Printf ("Wrote %s\n", filename);
619 }
620
621
622 //=============================================================================
623
624
625 /*
626 ===============
627 SCR_BeginLoadingPlaque
628
629 ================
630 */
631 /*
632 void SCR_BeginLoadingPlaque (void)
633 {
634         S_StopAllSounds (true);
635
636 //      if (cls.state != ca_connected)
637 //              return;
638 //      if (cls.signon != SIGNONS)
639 //              return;
640         
641 // redraw with no console and the loading plaque
642 //      Con_ClearNotify ();
643 //      scr_centertime_off = 0;
644 //      scr_con_current = 0;
645
646         scr_drawloading = true;
647         SCR_UpdateScreen ();
648
649 //      scr_disabled_for_loading = true;
650 //      scr_disabled_time = realtime;
651 }
652 */
653
654 /*
655 ===============
656 SCR_EndLoadingPlaque
657
658 ================
659 */
660 /*
661 void SCR_EndLoadingPlaque (void)
662 {
663 //      scr_disabled_for_loading = false;
664         scr_drawloading = false;
665         Con_ClearNotify ();
666 }
667 */
668
669 //=============================================================================
670
671 char    *scr_notifystring;
672
673 void SCR_DrawNotifyString (void)
674 {
675         char    *start;
676         int             l;
677         int             x, y;
678
679         start = scr_notifystring;
680
681         y = vid.height*0.35;
682
683         do      
684         {
685         // scan the width of the line
686                 for (l=0 ; l<40 ; l++)
687                         if (start[l] == '\n' || !start[l])
688                                 break;
689                 x = (vid.width - l*8)/2;
690                 // LordHavoc: speedup
691 //              for (j=0 ; j<l ; j++, x+=8)
692 //                      Draw_Character (x, y, start[j]);        
693                 Draw_String (x, y, start, l);
694                         
695                 y += 8;
696
697                 while (*start && *start != '\n')
698                         start++;
699
700                 if (!*start)
701                         break;
702                 start++;                // skip the \n
703         } while (1);
704 }
705
706 //=============================================================================
707
708 void DrawCrosshair(int num);
709 void GL_Set2D (void);
710
711 void GL_BrightenScreen(void)
712 {
713         float f;
714
715         if (r_brightness.value < 0.1f)
716                 Cvar_SetValue("r_brightness", 0.1f);
717         if (r_brightness.value > 5.0f)
718                 Cvar_SetValue("r_brightness", 5.0f);
719
720         if (r_contrast.value < 0.2f)
721                 Cvar_SetValue("r_contrast", 0.2f);
722         if (r_contrast.value > 1.0f)
723                 Cvar_SetValue("r_contrast", 1.0f);
724
725         if (!(lighthalf && !hardwaregammasupported) && r_brightness.value < 1.01f && r_contrast.value > 0.99f)
726                 return;
727
728         if (!r_render.value)
729                 return;
730
731         glDisable(GL_TEXTURE_2D);
732         glEnable(GL_BLEND);
733         f = r_brightness.value;
734         // only apply lighthalf using software color correction if hardware is not available (speed reasons)
735         if (lighthalf && !hardwaregammasupported)
736                 f *= 2;
737         if (f >= 1.01f)
738         {
739                 glBlendFunc (GL_DST_COLOR, GL_ONE);
740                 glBegin (GL_TRIANGLES);
741                 while (f >= 1.01f)
742                 {
743                         if (f >= 2)
744                                 glColor3f (1, 1, 1);
745                         else
746                                 glColor3f (f-1, f-1, f-1);
747                         glVertex2f (-5000, -5000);
748                         glVertex2f (10000, -5000);
749                         glVertex2f (-5000, 10000);
750                         f *= 0.5;
751                 }
752                 glEnd ();
753         }
754         if (r_contrast.value <= 0.99f)
755         {
756                 glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
757                 if (lighthalf && hardwaregammasupported)
758                         glColor4f (0.5, 0.5, 0.5, 1 - r_contrast.value);
759                 else
760                         glColor4f (1, 1, 1, 1 - r_contrast.value);
761                 glBegin (GL_TRIANGLES);
762                 glVertex2f (-5000, -5000);
763                 glVertex2f (10000, -5000);
764                 glVertex2f (-5000, 10000);
765                 glEnd ();
766         }
767         glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
768
769         glEnable (GL_CULL_FACE);
770         glEnable (GL_DEPTH_TEST);
771         glDisable(GL_BLEND);
772         glEnable(GL_TEXTURE_2D);
773 }
774
775 /*
776 ==================
777 SCR_UpdateScreen
778
779 This is called every frame, and can also be called explicitly to flush
780 text to the screen.
781
782 LordHavoc: due to my rewrite of R_WorldNode, it no longer takes 256k of stack space :)
783 ==================
784 */
785 void GL_Finish(void);
786 void SCR_UpdateScreen (void)
787 {
788         double  time1 = 0, time2;
789
790         if (r_speeds.value)
791                 time1 = Sys_DoubleTime ();
792
793         VID_UpdateGamma(false);
794
795         if (scr_disabled_for_loading)
796         {
797                 /*
798                 if (realtime - scr_disabled_time > 60)
799                 {
800                         scr_disabled_for_loading = false;
801                         Con_Printf ("load failed.\n");
802                 }
803                 else
804                 */
805                         return;
806         }
807
808         if (!scr_initialized || !con_initialized)
809                 return;                         // not initialized yet
810
811
812         GL_BeginRendering (&glx, &gly, &glwidth, &glheight);
813         
814         //
815         // determine size of refresh window
816         //
817         if (oldfov != scr_fov.value)
818         {
819                 oldfov = scr_fov.value;
820                 vid.recalc_refdef = true;
821         }
822
823         if (oldscreensize != scr_viewsize.value)
824         {
825                 oldscreensize = scr_viewsize.value;
826                 vid.recalc_refdef = true;
827         }
828
829         if (vid.recalc_refdef)
830                 SCR_CalcRefdef();
831
832         if (r_render.value)
833         {
834                 glClearColor(0,0,0,0);
835                 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // LordHavoc: clear the screen (around the view as well)
836         }
837
838 //
839 // do 3D refresh drawing, and then update the screen
840 //
841         SCR_SetUpToDrawConsole();
842
843         V_RenderView();
844
845         GL_Set2D();
846
847         SCR_DrawRam();
848         SCR_DrawNet();
849         SCR_DrawTurtle();
850         SCR_DrawPause();
851         SCR_CheckDrawCenterString();
852         Sbar_Draw();
853         SHOWLMP_drawall();
854
855         if (crosshair.value)
856                 DrawCrosshair(crosshair.value - 1);
857
858         if (cl.intermission == 1)
859                 Sbar_IntermissionOverlay();
860         else if (cl.intermission == 2)
861                 Sbar_FinaleOverlay();
862
863         SCR_DrawConsole();      
864         M_Draw();
865
866 //      if (scr_drawloading)
867 //              SCR_DrawLoading();
868
869         if (showfps.value)
870         {
871                 static double currtime;
872                 double newtime;
873                 char temp[32];
874                 int calc;
875                 newtime = Sys_DoubleTime();
876                 calc = (int) ((1.0 / (newtime - currtime)) + 0.5);
877                 sprintf(temp, "%4i fps", calc);
878                 currtime = newtime;
879                 Draw_String(vid.width - (8*8), vid.height - sb_lines - 8, temp, 9999);
880         }
881
882         if (r_speeds2.value)
883         {
884                 Draw_String(0, vid.height - sb_lines - 56, r_speeds2_string1, 80);
885                 Draw_String(0, vid.height - sb_lines - 48, r_speeds2_string2, 80);
886                 Draw_String(0, vid.height - sb_lines - 40, r_speeds2_string3, 80);
887                 Draw_String(0, vid.height - sb_lines - 32, r_speeds2_string4, 80);
888                 Draw_String(0, vid.height - sb_lines - 24, r_speeds2_string5, 80);
889                 Draw_String(0, vid.height - sb_lines - 16, r_speeds2_string6, 80);
890                 Draw_String(0, vid.height - sb_lines -  8, r_speeds2_string7, 80);
891         }
892
893         V_UpdateBlends();
894
895         GL_BrightenScreen();
896
897         GL_Finish();
898
899         if (r_speeds.value)
900         {
901                 time2 = Sys_DoubleTime ();
902                 Con_Printf ("%3i ms  %4i wpoly %4i epoly %4i transpoly %4i lightpoly %4i BSPnodes %4i BSPleafs %4i BSPfaces %4i models %4i bmodels %4i sprites %4i particles %3i dlights\n", (int)((time2-time1)*1000), c_brush_polys, c_alias_polys, currenttranspoly, c_light_polys, c_nodes, c_leafs, c_faces, c_models, c_bmodels, c_sprites, c_particles, c_dlights);
903         }
904         GL_EndRendering ();
905 }
906
907 // for profiling, this is separated
908 void GL_Finish(void)
909 {
910         if (!r_render.value)
911                 return;
912         glFinish ();
913 }
914