]> de.git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - gl_screen.c
moved ixtable definition and initialization code to mathlib (and added Mathlib_Init...
[xonotic/darkplaces.git] / gl_screen.c
index a7a03d4fc5813fff1ce416381101c33e1e2c8aba..977c4a04520841e6a638c6d7e12eb9543731d2cc 100644 (file)
@@ -58,7 +58,7 @@ Con_Printf ();
 net 
 turn off messages option
 
-the refresh is allways rendered, unless the console is full screen
+the refresh is always rendered, unless the console is full screen
 
 
 console is:
@@ -70,27 +70,24 @@ console is:
 */
 
 
-int                    glx, gly, glwidth, glheight;
+int            glx, gly, glwidth, glheight;
 
-// only the refresh window will be updated unless these variables are flagged 
-int                    scr_copytop;
-int                    scr_copyeverything;
+float  scr_con_current;
+float  scr_conlines;           // lines of console to display
 
-float          scr_con_current;
-float          scr_conlines;           // lines of console to display
-
-float          oldscreensize, oldfov;
-cvar_t         scr_viewsize = {"viewsize","100", true};
-cvar_t         scr_fov = {"fov","90"}; // 10 - 170
-cvar_t         scr_conspeed = {"scr_conspeed","300"};
-cvar_t         scr_centertime = {"scr_centertime","2"};
-cvar_t         scr_showram = {"showram","1"};
-cvar_t         scr_showturtle = {"showturtle","0"};
-cvar_t         scr_showpause = {"showpause","1"};
-cvar_t         scr_printspeed = {"scr_printspeed","8"};
-cvar_t         gl_triplebuffer = {"gl_triplebuffer", "1", true };
-
-extern cvar_t  crosshair;
+float  oldscreensize, oldfov;
+cvar_t scr_viewsize = {CVAR_SAVE, "viewsize","100"};
+cvar_t scr_fov = {CVAR_SAVE, "fov","90"};      // 10 - 170
+cvar_t scr_conspeed = {CVAR_SAVE, "scr_conspeed","900"}; // LordHavoc: quake used 300
+cvar_t scr_centertime = {0, "scr_centertime","2"};
+cvar_t scr_showram = {CVAR_SAVE, "showram","1"};
+cvar_t scr_showturtle = {CVAR_SAVE, "showturtle","0"};
+cvar_t scr_showpause = {CVAR_SAVE, "showpause","1"};
+cvar_t scr_printspeed = {0, "scr_printspeed","8"};
+cvar_t showfps = {CVAR_SAVE, "showfps", "0"};
+cvar_t r_render = {0, "r_render", "1"};
+cvar_t r_brightness = {CVAR_SAVE, "r_brightness", "1"}; // LordHavoc: a method of operating system independent color correction
+cvar_t r_contrast = {CVAR_SAVE, "r_contrast", "1"}; // LordHavoc: a method of operating system independent color correction
 
 qboolean       scr_initialized;                // ready to draw
 
@@ -98,20 +95,12 @@ qpic_t              *scr_ram;
 qpic_t         *scr_net;
 qpic_t         *scr_turtle;
 
-int                    scr_fullupdate;
-
 int                    clearconsole;
 int                    clearnotify;
 
-int                    sb_lines;
-
-viddef_t       vid;                            // global video state
-
-vrect_t                scr_vrect;
-
 qboolean       scr_disabled_for_loading;
-qboolean       scr_drawloading;
-float          scr_disabled_time;
+//qboolean     scr_drawloading;
+//float                scr_disabled_time;
 
 void SCR_ScreenShot_f (void);
 
@@ -215,12 +204,11 @@ void SCR_DrawCenterString (void)
 
 void SCR_CheckDrawCenterString (void)
 {
-       scr_copytop = 1;
        if (scr_center_lines > scr_erase_lines)
                scr_erase_lines = scr_center_lines;
 
        scr_centertime_off -= host_frametime;
-       
+
        if (scr_centertime_off <= 0 && !cl.intermission)
                return;
        if (key_dest != key_game)
@@ -268,12 +256,8 @@ static void SCR_CalcRefdef (void)
        qboolean                full = false;
 
 
-       scr_fullupdate = 0;             // force a background redraw
        vid.recalc_refdef = 0;
 
-// force the status bar to redraw
-//     Sbar_Changed ();
-
 //========================================
        
 // bound viewsize
@@ -290,33 +274,30 @@ static void SCR_CalcRefdef (void)
 
 // intermission is always full screen  
        if (cl.intermission)
-               size = 120;
-       else
-               size = scr_viewsize.value;
-
-       if (size >= 120)
-               sb_lines = 0;           // no status bar at all
-       else if (size >= 110)
-               sb_lines = 24;          // no inventory
-       else
-               sb_lines = 24+16+8;
-
-       if (scr_viewsize.value >= 100.0)
        {
                full = true;
-               size = 100.0;
+               size = 1;
+               sb_lines = 0;
        }
        else
-               size = scr_viewsize.value;
-       if (cl.intermission)
        {
-               full = true;
-               size = 100;
-               sb_lines = 0;
+               if (scr_viewsize.value >= 120)
+                       sb_lines = 0;           // no status bar at all
+               else if (scr_viewsize.value >= 110)
+                       sb_lines = 24;          // no inventory
+               else
+                       sb_lines = 24+16+8;
+
+               if (scr_viewsize.value >= 100.0)
+               {
+                       full = true;
+                       size = 1.0f;
+               }
+               else
+                       size = scr_viewsize.value * (1.0f / 100.0f);
        }
-       size /= 100.0;
 
-       // LordHavoc: always fullyscreen rendering
+       // LordHavoc: always fullscreen rendering
        h = vid.height/* - sb_lines*/;
 
        r_refdef.vrect.width = vid.width * size;
@@ -339,8 +320,6 @@ static void SCR_CalcRefdef (void)
 
        r_refdef.fov_x = scr_fov.value;
        r_refdef.fov_y = CalcFov (r_refdef.fov_x, r_refdef.vrect.width, r_refdef.vrect.height);
-
-       scr_vrect = r_refdef.vrect;
 }
 
 
@@ -373,12 +352,27 @@ void SCR_SizeDown_f (void)
 
 //============================================================================
 
+void gl_screen_start(void)
+{
+       scr_ram = Draw_PicFromWad ("ram");
+       scr_net = Draw_PicFromWad ("net");
+       scr_turtle = Draw_PicFromWad ("turtle");
+}
+
+void gl_screen_shutdown(void)
+{
+}
+
+void gl_screen_newmap(void)
+{
+}
+
 /*
 ==================
 SCR_Init
 ==================
 */
-void SCR_Init (void)
+void GL_Screen_Init (void)
 {
 
        Cvar_RegisterVariable (&scr_fov);
@@ -389,7 +383,13 @@ void SCR_Init (void)
        Cvar_RegisterVariable (&scr_showpause);
        Cvar_RegisterVariable (&scr_centertime);
        Cvar_RegisterVariable (&scr_printspeed);
-       Cvar_RegisterVariable (&gl_triplebuffer);
+       Cvar_RegisterVariable (&showfps);
+       Cvar_RegisterVariable (&r_render);
+       Cvar_RegisterVariable (&r_brightness);
+       Cvar_RegisterVariable (&r_contrast);
+#ifdef NORENDER
+       r_render.value = 0;
+#endif
 
 //
 // register our commands
@@ -398,11 +398,9 @@ void SCR_Init (void)
        Cmd_AddCommand ("sizeup",SCR_SizeUp_f);
        Cmd_AddCommand ("sizedown",SCR_SizeDown_f);
 
-       scr_ram = Draw_PicFromWad ("ram");
-       scr_net = Draw_PicFromWad ("net");
-       scr_turtle = Draw_PicFromWad ("turtle");
-
        scr_initialized = true;
+
+       R_RegisterModule("GL_Screen", gl_screen_start, gl_screen_shutdown, gl_screen_newmap);
 }
 
 
@@ -420,7 +418,7 @@ void SCR_DrawRam (void)
        if (!r_cache_thrash)
                return;
 
-       Draw_Pic (scr_vrect.x+32, scr_vrect.y, scr_ram);
+       Draw_Pic (32, 0, scr_ram);
 }
 
 /*
@@ -435,7 +433,7 @@ void SCR_DrawTurtle (void)
        if (!scr_showturtle.value)
                return;
 
-       if (host_frametime < 0.1)
+       if (cl.frametime < 0.1)
        {
                count = 0;
                return;
@@ -445,7 +443,7 @@ void SCR_DrawTurtle (void)
        if (count < 3)
                return;
 
-       Draw_Pic (scr_vrect.x, scr_vrect.y, scr_turtle);
+       Draw_Pic (0, 0, scr_turtle);
 }
 
 /*
@@ -460,7 +458,7 @@ void SCR_DrawNet (void)
        if (cls.demoplayback)
                return;
 
-       Draw_Pic (scr_vrect.x+64, scr_vrect.y, scr_net);
+       Draw_Pic (64, 0, scr_net);
 }
 
 /*
@@ -490,6 +488,7 @@ void SCR_DrawPause (void)
 SCR_DrawLoading
 ==============
 */
+/*
 void SCR_DrawLoading (void)
 {
        qpic_t  *pic;
@@ -501,6 +500,7 @@ void SCR_DrawLoading (void)
        Draw_Pic ( (vid.width - pic->width)/2, 
                (vid.height - 48 - pic->height)/2, pic);
 }
+*/
 
 
 
@@ -534,29 +534,17 @@ void SCR_SetUpToDrawConsole (void)
        
        if (scr_conlines < scr_con_current)
        {
-               scr_con_current -= scr_conspeed.value*host_frametime;
+               scr_con_current -= scr_conspeed.value*host_realframetime;
                if (scr_conlines > scr_con_current)
                        scr_con_current = scr_conlines;
 
        }
        else if (scr_conlines > scr_con_current)
        {
-               scr_con_current += scr_conspeed.value*host_frametime;
+               scr_con_current += scr_conspeed.value*host_realframetime;
                if (scr_conlines < scr_con_current)
                        scr_con_current = scr_conlines;
        }
-
-       /*
-       if (clearconsole++ < vid.numpages)
-       {
-               Sbar_Changed ();
-       }
-       else if (clearnotify++ < vid.numpages)
-       {
-       }
-       else
-               con_notifylines = 0;
-       */
 }
        
 /*
@@ -568,7 +556,6 @@ void SCR_DrawConsole (void)
 {
        if (scr_con_current)
        {
-               scr_copyeverything = 1;
                Con_DrawConsole (scr_con_current, true);
                clearconsole = 0;
        }
@@ -588,38 +575,29 @@ void SCR_DrawConsole (void)
 ============================================================================== 
 */ 
 
-typedef struct _TargaHeader {
-       unsigned char   id_length, colormap_type, image_type;
-       unsigned short  colormap_index, colormap_length;
-       unsigned char   colormap_size;
-       unsigned short  x_origin, y_origin, width, height;
-       unsigned char   pixel_size, attributes;
-} TargaHeader;
-
-
-/* 
+/*
 ================== 
 SCR_ScreenShot_f
 ================== 
-*/  
+*/
 void SCR_ScreenShot_f (void) 
 {
        byte            *buffer;
-       char            pcxname[80]; 
+       char            filename[80]; 
        char            checkname[MAX_OSPATH];
-       int                     i, c, temp;
-// 
+       int                     i;
+//
 // find a file name to save it to 
 // 
-       strcpy(pcxname,"dp0000.tga");
+       strcpy(filename,"dp0000.tga");
                
        for (i=0 ; i<=9999 ; i++) 
        { 
-               pcxname[2] = (i/1000)%10 + '0'; 
-               pcxname[3] = (i/ 100)%10 + '0'; 
-               pcxname[4] = (i/  10)%10 + '0'; 
-               pcxname[5] = (i/   1)%10 + '0'; 
-               sprintf (checkname, "%s/%s", com_gamedir, pcxname);
+               filename[2] = (i/1000)%10 + '0'; 
+               filename[3] = (i/ 100)%10 + '0'; 
+               filename[4] = (i/  10)%10 + '0'; 
+               filename[5] = (i/   1)%10 + '0';
+               sprintf (checkname, "%s/%s", com_gamedir, filename);
                if (Sys_FileTime(checkname) == -1)
                        break;  // file doesn't exist
        } 
@@ -629,31 +607,13 @@ void SCR_ScreenShot_f (void)
                return;
        }
 
+       buffer = qmalloc(glwidth*glheight*3);
+       glReadPixels (glx, gly, glwidth, glheight, GL_RGB, GL_UNSIGNED_BYTE, buffer); 
+       Image_WriteTGARGB_preflipped(filename, glwidth, glheight, buffer);
 
-       buffer = malloc(glwidth*glheight*3 + 18);
-       memset (buffer, 0, 18);
-       buffer[2] = 2;          // uncompressed type
-       buffer[12] = glwidth&255;
-       buffer[13] = glwidth>>8;
-       buffer[14] = glheight&255;
-       buffer[15] = glheight>>8;
-       buffer[16] = 24;        // pixel size
-
-       glReadPixels (glx, gly, glwidth, glheight, GL_RGB, GL_UNSIGNED_BYTE, buffer+18 ); 
-
-       // swap rgb to bgr
-       c = 18+glwidth*glheight*3;
-       for (i=18 ; i<c ; i+=3)
-       {
-               temp = buffer[i];
-               buffer[i] = buffer[i+2];
-               buffer[i+2] = temp;
-       }
-       COM_WriteFile (pcxname, buffer, glwidth*glheight*3 + 18 );
-
-       free (buffer);
-       Con_Printf ("Wrote %s\n", pcxname);
-} 
+       qfree(buffer);
+       Con_Printf ("Wrote %s\n", filename);
+}
 
 
 //=============================================================================
@@ -665,30 +625,28 @@ SCR_BeginLoadingPlaque
 
 ================
 */
+/*
 void SCR_BeginLoadingPlaque (void)
 {
        S_StopAllSounds (true);
 
-       if (cls.state != ca_connected)
-               return;
-       if (cls.signon != SIGNONS)
-               return;
+//     if (cls.state != ca_connected)
+//             return;
+//     if (cls.signon != SIGNONS)
+//             return;
        
 // redraw with no console and the loading plaque
-       Con_ClearNotify ();
-       scr_centertime_off = 0;
-       scr_con_current = 0;
+//     Con_ClearNotify ();
+//     scr_centertime_off = 0;
+//     scr_con_current = 0;
 
        scr_drawloading = true;
-       scr_fullupdate = 0;
-//     Sbar_Changed ();
        SCR_UpdateScreen ();
-       scr_drawloading = false;
 
-       scr_disabled_for_loading = true;
-       scr_disabled_time = realtime;
-       scr_fullupdate = 0;
+//     scr_disabled_for_loading = true;
+//     scr_disabled_time = realtime;
 }
+*/
 
 /*
 ===============
@@ -696,17 +654,18 @@ SCR_EndLoadingPlaque
 
 ================
 */
+/*
 void SCR_EndLoadingPlaque (void)
 {
-       scr_disabled_for_loading = false;
-       scr_fullupdate = 0;
+//     scr_disabled_for_loading = false;
+       scr_drawloading = false;
        Con_ClearNotify ();
 }
+*/
 
 //=============================================================================
 
 char   *scr_notifystring;
-qboolean       scr_drawdialog;
 
 void SCR_DrawNotifyString (void)
 {
@@ -729,7 +688,7 @@ void SCR_DrawNotifyString (void)
 //             for (j=0 ; j<l ; j++, x+=8)
 //                     Draw_Character (x, y, start[j]);        
                Draw_String (x, y, start, l);
-                       
+
                y += 8;
 
                while (*start && *start != '\n')
@@ -741,82 +700,42 @@ void SCR_DrawNotifyString (void)
        } while (1);
 }
 
-/*
-==================
-SCR_ModalMessage
-
-Displays a text string in the center of the screen and waits for a Y or N
-keypress.  
-==================
-*/
-int SCR_ModalMessage (char *text)
-{
-       if (cls.state == ca_dedicated)
-               return true;
-
-       scr_notifystring = text;
-// draw a fresh screen
-       scr_fullupdate = 0;
-       scr_drawdialog = true;
-       SCR_UpdateScreen ();
-       scr_drawdialog = false;
-       
-       S_ClearBuffer ();               // so dma doesn't loop current sound
-
-       do
-       {
-               key_count = -1;         // wait for a key down and up
-               Sys_SendKeyEvents ();
-       } while (key_lastpress != 'y' && key_lastpress != 'n' && key_lastpress != K_ESCAPE);
-
-       scr_fullupdate = 0;
-       SCR_UpdateScreen ();
-
-       return key_lastpress == 'y';
-}
-
-
 //=============================================================================
 
-/*
-===============
-SCR_BringDownConsole
+void DrawCrosshair(int num);
+void GL_Set2D (void);
 
-Brings the console down and fades the palettes back to normal
-================
-*/
-void SCR_BringDownConsole (void)
+void GL_BrightenScreen(void)
 {
-       int             i;
-       
-       scr_centertime_off = 0;
-       
-       for (i=0 ; i<20 && scr_conlines != scr_con_current ; i++)
-               SCR_UpdateScreen ();
+       float f;
 
-       cl.cshifts[0].percent = 0;              // no area contents palette on next frame
-       VID_SetPalette (host_basepal);
-}
+       if (r_brightness.value < 0.1f)
+               Cvar_SetValue("r_brightness", 0.1f);
+       if (r_brightness.value > 5.0f)
+               Cvar_SetValue("r_brightness", 5.0f);
 
-void GL_Set2D (void);
+       if (r_contrast.value < 0.2f)
+               Cvar_SetValue("r_contrast", 0.2f);
+       if (r_contrast.value > 1.0f)
+               Cvar_SetValue("r_contrast", 1.0f);
 
-extern void SHOWLMP_drawall();
-extern cvar_t contrast;
-extern cvar_t brightness;
-extern cvar_t gl_lightmode;
+       if (!(lighthalf && !hardwaregammasupported) && r_brightness.value < 1.01f && r_contrast.value > 0.99f)
+               return;
+
+       if (!r_render.value)
+               return;
 
-void GL_BrightenScreen()
-{
-       float f;
        glDisable(GL_TEXTURE_2D);
        glEnable(GL_BLEND);
-       f = brightness.value = bound(1.0f, brightness.value, 5.0f);
-       if (f > 1)
+       f = r_brightness.value;
+       // only apply lighthalf using software color correction if hardware is not available (speed reasons)
+       if (lighthalf && !hardwaregammasupported)
+               f *= 2;
+       if (f >= 1.01f)
        {
                glBlendFunc (GL_DST_COLOR, GL_ONE);
                glBegin (GL_TRIANGLES);
-               while (f > 1)
+               while (f >= 1.01f)
                {
                        if (f >= 2)
                                glColor3f (1, 1, 1);
@@ -829,17 +748,20 @@ void GL_BrightenScreen()
                }
                glEnd ();
        }
-       glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-       contrast.value = bound(0.2, contrast.value, 1.0);
-       if (contrast.value < 1.0f)
+       if (r_contrast.value <= 0.99f)
        {
+               glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+               if (lighthalf && hardwaregammasupported)
+                       glColor4f (0.5, 0.5, 0.5, 1 - r_contrast.value);
+               else
+                       glColor4f (1, 1, 1, 1 - r_contrast.value);
                glBegin (GL_TRIANGLES);
-               glColor4f (1, 1, 1, 1-contrast.value);
                glVertex2f (-5000, -5000);
                glVertex2f (10000, -5000);
                glVertex2f (-5000, 10000);
                glEnd ();
        }
+       glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
 
        glEnable (GL_CULL_FACE);
        glEnable (GL_DEPTH_TEST);
@@ -854,43 +776,30 @@ SCR_UpdateScreen
 This is called every frame, and can also be called explicitly to flush
 text to the screen.
 
-WARNING: be very careful calling this from elsewhere, because the refresh
-needs almost the entire 256k of stack space!
+LordHavoc: due to my rewrite of R_WorldNode, it no longer takes 256k of stack space :)
 ==================
 */
-extern cvar_t gl_vertexarrays;
-extern qboolean gl_arrays;
-void GL_Finish();
-int c_nodes;
+void GL_Finish(void);
+void R_Clip_DisplayBuffer(void);
 void SCR_UpdateScreen (void)
 {
-       static float    oldscr_viewsize;
-       double  time1, time2;
+       double  time1 = 0, time2;
 
        if (r_speeds.value)
-       {
-               time1 = Sys_FloatTime ();
-               c_brush_polys = 0;
-               c_alias_polys = 0;
-               c_nodes = 0;
-       }
-
-       if (!gl_arrays)
-               gl_vertexarrays.value = 0;
-
-       vid.numpages = 2 + gl_triplebuffer.value;
+               time1 = Sys_DoubleTime ();
 
-       scr_copytop = 0;
-       scr_copyeverything = 0;
+       VID_UpdateGamma(false);
 
        if (scr_disabled_for_loading)
        {
+               /*
                if (realtime - scr_disabled_time > 60)
                {
                        scr_disabled_for_loading = false;
                        Con_Printf ("load failed.\n");
                }
                else
+               */
                        return;
        }
 
@@ -899,7 +808,7 @@ void SCR_UpdateScreen (void)
 
 
        GL_BeginRendering (&glx, &gly, &glwidth, &glheight);
-       
+
        //
        // determine size of refresh window
        //
@@ -916,58 +825,86 @@ void SCR_UpdateScreen (void)
        }
 
        if (vid.recalc_refdef)
-               SCR_CalcRefdef ();
+               SCR_CalcRefdef();
 
-       glClearColor(0,0,0,0);
-       glClear (GL_COLOR_BUFFER_BIT); // LordHavoc: clear the screen (around the view as well)
+       if (r_render.value)
+       {
+               glClearColor(0,0,0,0);
+               glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // LordHavoc: clear the screen (around the view as well)
+       }
 
 //
 // do 3D refresh drawing, and then update the screen
 //
-       SCR_SetUpToDrawConsole ();
+       SCR_SetUpToDrawConsole();
 
-       V_RenderView ();
+       V_RenderView();
 
-       GL_Set2D ();
+       GL_Set2D();
 
-       if (scr_drawdialog)
-       {
-               Sbar_Draw ();
-//             Draw_FadeScreen ();
-               SCR_DrawNotifyString ();
-               scr_copyeverything = true;
-       }
-       else if (scr_drawloading)
-       {
-               SCR_DrawLoading ();
-               Sbar_Draw ();
-       }
-       else if (cl.intermission == 1 && key_dest == key_game)
-       {
-               Sbar_IntermissionOverlay ();
-       }
-       else if (cl.intermission == 2 && key_dest == key_game)
+       R_Clip_DisplayBuffer();
+
+       SCR_DrawRam();
+       SCR_DrawNet();
+       SCR_DrawTurtle();
+       SCR_DrawPause();
+       SCR_CheckDrawCenterString();
+       Sbar_Draw();
+       SHOWLMP_drawall();
+
+       if (crosshair.value)
+               DrawCrosshair(crosshair.value - 1);
+
+       if (cl.intermission == 1)
+               Sbar_IntermissionOverlay();
+       else if (cl.intermission == 2)
+               Sbar_FinaleOverlay();
+
+       SCR_DrawConsole();
+       M_Draw();
+
+       ui_draw();
+
+//     if (scr_drawloading)
+//             SCR_DrawLoading();
+
+       if (showfps.value)
        {
-               Sbar_FinaleOverlay ();
-               SCR_CheckDrawCenterString ();
+               static double currtime;
+               double newtime;
+               char temp[32];
+               int calc;
+               newtime = Sys_DoubleTime();
+               calc = (int) ((1.0 / (newtime - currtime)) + 0.5);
+               sprintf(temp, "%4i fps", calc);
+               currtime = newtime;
+               Draw_String(vid.width - (8*8), vid.height - sb_lines - 8, temp, 9999);
        }
-       else
+
+       // LordHavoc: only print info if renderer is being used
+       if (r_speeds2.value && !con_forcedup)
        {
-               if (crosshair.value)
-                       Draw_Character (scr_vrect.x + scr_vrect.width/2, scr_vrect.y + scr_vrect.height/2, '+');
-               
-               SCR_DrawRam ();
-               SCR_DrawNet ();
-               SCR_DrawTurtle ();
-               SCR_DrawPause ();
-               SCR_CheckDrawCenterString ();
-               Sbar_Draw ();
-               SHOWLMP_drawall();
-               SCR_DrawConsole ();     
-               M_Draw ();
+               int i, j, lines, y;
+               lines = 1;
+               for (i = 0;r_speeds2_string[i];i++)
+                       if (r_speeds2_string[i] == '\n')
+                               lines++;
+               y = vid.height - sb_lines - lines * 8 - 8;
+               i = j = 0;
+               while (r_speeds2_string[i])
+               {
+                       j = i;
+                       while (r_speeds2_string[i] && r_speeds2_string[i] != '\n')
+                               i++;
+                       if (i - j > 0)
+                               Draw_String(0, y, r_speeds2_string + j, i - j);
+                       if (r_speeds2_string[i] == '\n')
+                               i++;
+                       y += 8;
+               }
        }
 
-       V_UpdatePalette ();
+       V_UpdateBlends();
 
        GL_BrightenScreen();
 
@@ -975,15 +912,17 @@ void SCR_UpdateScreen (void)
 
        if (r_speeds.value)
        {
-               time2 = Sys_FloatTime ();
-               Con_Printf ("%3i ms  %4i wpoly %4i epoly %4i BSPnodes\n", (int)((time2-time1)*1000), c_brush_polys, c_alias_polys, c_nodes); 
+               time2 = Sys_DoubleTime ();
+               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);
        }
        GL_EndRendering ();
 }
 
-// for profiling, this is seperated
-void GL_Finish()
+// for profiling, this is separated
+void GL_Finish(void)
 {
+       if (!r_render.value)
+               return;
        glFinish ();
 }