]> de.git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - gl_screen.c
added back intermission overlays (oops)
[xonotic/darkplaces.git] / gl_screen.c
index 026861df783f77b0a203c3f973ec1252f84108fb..6eaf808f9835abfc0b5e408d389490ef8900a7c3 100644 (file)
@@ -8,7 +8,7 @@ of the License, or (at your option) any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 
 See the GNU General Public License for more details.
 
 
 See the GNU General Public License for more details.
 
@@ -55,7 +55,7 @@ SlowPrint ()
 Screen_Update ();
 Con_Printf ();
 
 Screen_Update ();
 Con_Printf ();
 
-net 
+net
 turn off messages option
 
 the refresh is always rendered, unless the console is full screen
 turn off messages option
 
 the refresh is always rendered, unless the console is full screen
@@ -65,52 +65,39 @@ console is:
        notify lines
        half
        full
        notify lines
        half
        full
-       
-
-*/
 
 
 
 
-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          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         showfps = {"showfps", "0", true};
-cvar_t         r_render = {"r_render", "1"};
+float  scr_con_current;
+float  scr_conlines;           // lines of console to display
 
 
-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 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
+cvar_t gl_dither = {CVAR_SAVE, "gl_dither", "1"}; // whether or not to use dithering
 
 qboolean       scr_initialized;                // ready to draw
 
 
 qboolean       scr_initialized;                // ready to draw
 
-qpic_t         *scr_ram;
-qpic_t         *scr_net;
-qpic_t         *scr_turtle;
-
-int                    scr_fullupdate;
-
 int                    clearconsole;
 int                    clearnotify;
 
 int                    clearconsole;
 int                    clearnotify;
 
-extern int                     sb_lines;
-
-extern viddef_t        vid;                            // global video state
+int                    lightscalebit;
+float          lightscale;
 
 qboolean       scr_disabled_for_loading;
 
 qboolean       scr_disabled_for_loading;
-qboolean       scr_drawloading;
-float          scr_disabled_time;
+//qboolean     scr_drawloading;
+//float                scr_disabled_time;
 
 void SCR_ScreenShot_f (void);
 
 
 void SCR_ScreenShot_f (void);
 
@@ -171,7 +158,7 @@ void SCR_DrawCenterString (void)
        start = scr_centerstring;
 
        if (scr_center_lines <= 4)
        start = scr_centerstring;
 
        if (scr_center_lines <= 4)
-               y = vid.height*0.35;
+               y = vid.conheight*0.35;
        else
                y = 48;
 
        else
                y = 48;
 
@@ -181,26 +168,17 @@ void SCR_DrawCenterString (void)
                for (l=0 ; l<40 ; l++)
                        if (start[l] == '\n' || !start[l])
                                break;
                for (l=0 ; l<40 ; l++)
                        if (start[l] == '\n' || !start[l])
                                break;
-               x = (vid.width - l*8)/2;
-               // LordHavoc: speedup
+               x = (vid.conwidth - l*8)/2;
                if (l > 0)
                {
                        if (remaining < l)
                                l = remaining;
                if (l > 0)
                {
                        if (remaining < l)
                                l = remaining;
-                       Draw_String(x, y, start, l);
+                       DrawQ_String(x, y, start, l, 8, 8, 1, 1, 1, 1, 0);
                        remaining -= l;
                        if (remaining <= 0)
                                return;
                }
                        remaining -= l;
                        if (remaining <= 0)
                                return;
                }
-               /*
-               for (j=0 ; j<l ; j++, x+=8)
-               {
-                       Draw_Character (x, y, start[j]);        
-                       if (!remaining--)
-                               return;
-               }
-               */
-                       
+
                y += 8;
 
                while (*start && *start != '\n')
                y += 8;
 
                while (*start && *start != '\n')
@@ -214,12 +192,11 @@ void SCR_DrawCenterString (void)
 
 void SCR_CheckDrawCenterString (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_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)
        if (scr_centertime_off <= 0 && !cl.intermission)
                return;
        if (key_dest != key_game)
@@ -237,19 +214,8 @@ CalcFov
 */
 float CalcFov (float fov_x, float width, float height)
 {
 */
 float CalcFov (float fov_x, float width, float height)
 {
-        float   a;
-        float   x;
-
-        if (fov_x < 1 || fov_x > 179)
-                Sys_Error ("Bad fov: %f", fov_x);
-
-        x = width/tan(fov_x/360*M_PI);
-
-        a = atan (height/x);
-
-        a = a*360/M_PI;
-
-        return a;
+       // calculate vision size and alter by aspect, then convert back to angle
+       return atan (height / (width / tan(fov_x/360*M_PI))) * 360 / M_PI;
 }
 
 /*
 }
 
 /*
@@ -262,16 +228,12 @@ Internal use only
 */
 static void SCR_CalcRefdef (void)
 {
 */
 static void SCR_CalcRefdef (void)
 {
-       float           size;
-       int             h;
-       qboolean                full = false;
-
+       float size;
 
 
-       scr_fullupdate = 0;             // force a background redraw
-       vid.recalc_refdef = 0;
+//     vid.recalc_refdef = 0;
 
 //========================================
 
 //========================================
-       
+
 // bound viewsize
        if (scr_viewsize.value < 30)
                Cvar_Set ("viewsize","30");
 // bound viewsize
        if (scr_viewsize.value < 30)
                Cvar_Set ("viewsize","30");
@@ -284,57 +246,45 @@ static void SCR_CalcRefdef (void)
        if (scr_fov.value > 170)
                Cvar_Set ("fov","170");
 
        if (scr_fov.value > 170)
                Cvar_Set ("fov","170");
 
-// intermission is always full screen  
+// intermission is always full screen
        if (cl.intermission)
        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
        }
        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;
+               size = scr_viewsize.value * (1.0 / 100.0);
        }
        }
-       size /= 100.0;
 
 
-       // LordHavoc: always fullyscreen rendering
-       h = vid.height/* - sb_lines*/;
-
-       r_refdef.vrect.width = vid.width * size;
-       if (r_refdef.vrect.width < 96)
+       if (size >= 1)
        {
        {
-               size = 96.0 / r_refdef.vrect.width;
-               r_refdef.vrect.width = 96;      // min for icons
+               r_refdef.width = vid.realwidth;
+               r_refdef.height = vid.realheight;
+               r_refdef.x = 0;
+               r_refdef.y = 0;
+       }
+       else
+       {
+               r_refdef.width = vid.realwidth * size;
+               r_refdef.height = vid.realheight * size;
+               r_refdef.x = (vid.realwidth - r_refdef.width)/2;
+               r_refdef.y = (vid.realheight - r_refdef.height)/2;
        }
        }
-
-       r_refdef.vrect.height = vid.height * size;
-       //if (r_refdef.vrect.height > vid.height - sb_lines)
-       //      r_refdef.vrect.height = vid.height - sb_lines;
-       if (r_refdef.vrect.height > (int) vid.height)
-                       r_refdef.vrect.height = vid.height;
-       r_refdef.vrect.x = (vid.width - r_refdef.vrect.width)/2;
-       if (full)
-               r_refdef.vrect.y = 0;
-       else 
-               r_refdef.vrect.y = (h - r_refdef.vrect.height)/2;
 
        r_refdef.fov_x = scr_fov.value;
 
        r_refdef.fov_x = scr_fov.value;
-       r_refdef.fov_y = CalcFov (r_refdef.fov_x, r_refdef.vrect.width, r_refdef.vrect.height);
+       r_refdef.fov_y = CalcFov (r_refdef.fov_x, r_refdef.width, r_refdef.height);
+
+       r_refdef.width = bound(0, r_refdef.width, vid.realwidth);
+       r_refdef.height = bound(0, r_refdef.height, vid.realheight);
+       r_refdef.x = bound(0, r_refdef.x, vid.realwidth) + vid.realx;
+       r_refdef.y = bound(0, r_refdef.y, vid.realheight) + vid.realy;
 }
 
 
 }
 
 
@@ -348,7 +298,6 @@ Keybinding command
 void SCR_SizeUp_f (void)
 {
        Cvar_SetValue ("viewsize",scr_viewsize.value+10);
 void SCR_SizeUp_f (void)
 {
        Cvar_SetValue ("viewsize",scr_viewsize.value+10);
-       vid.recalc_refdef = 1;
 }
 
 
 }
 
 
@@ -362,19 +311,19 @@ Keybinding command
 void SCR_SizeDown_f (void)
 {
        Cvar_SetValue ("viewsize",scr_viewsize.value-10);
 void SCR_SizeDown_f (void)
 {
        Cvar_SetValue ("viewsize",scr_viewsize.value-10);
-       vid.recalc_refdef = 1;
 }
 
 //============================================================================
 
 }
 
 //============================================================================
 
-void gl_screen_start()
+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 gl_screen_shutdown(void)
+{
+}
+
+void gl_screen_newmap(void)
 {
 }
 
 {
 }
 
@@ -383,9 +332,9 @@ void gl_screen_shutdown()
 SCR_Init
 ==================
 */
 SCR_Init
 ==================
 */
+static void R_Envmap_f (void);
 void GL_Screen_Init (void)
 {
 void GL_Screen_Init (void)
 {
-
        Cvar_RegisterVariable (&scr_fov);
        Cvar_RegisterVariable (&scr_viewsize);
        Cvar_RegisterVariable (&scr_conspeed);
        Cvar_RegisterVariable (&scr_fov);
        Cvar_RegisterVariable (&scr_viewsize);
        Cvar_RegisterVariable (&scr_conspeed);
@@ -394,22 +343,25 @@ void GL_Screen_Init (void)
        Cvar_RegisterVariable (&scr_showpause);
        Cvar_RegisterVariable (&scr_centertime);
        Cvar_RegisterVariable (&scr_printspeed);
        Cvar_RegisterVariable (&scr_showpause);
        Cvar_RegisterVariable (&scr_centertime);
        Cvar_RegisterVariable (&scr_printspeed);
-       Cvar_RegisterVariable (&showfps);
        Cvar_RegisterVariable (&r_render);
        Cvar_RegisterVariable (&r_render);
+       Cvar_RegisterVariable (&r_brightness);
+       Cvar_RegisterVariable (&r_contrast);
+       Cvar_RegisterVariable (&gl_dither);
 #ifdef NORENDER
 #ifdef NORENDER
-       r_render.value = 0;
+       Cvar_SetValue("r_render", 0);
 #endif
 
 //
 // register our commands
 //
        Cmd_AddCommand ("screenshot",SCR_ScreenShot_f);
 #endif
 
 //
 // register our commands
 //
        Cmd_AddCommand ("screenshot",SCR_ScreenShot_f);
+       Cmd_AddCommand ("envmap", R_Envmap_f);
        Cmd_AddCommand ("sizeup",SCR_SizeUp_f);
        Cmd_AddCommand ("sizedown",SCR_SizeDown_f);
 
        scr_initialized = true;
 
        Cmd_AddCommand ("sizeup",SCR_SizeUp_f);
        Cmd_AddCommand ("sizedown",SCR_SizeDown_f);
 
        scr_initialized = true;
 
-       R_RegisterModule("GL_Screen", gl_screen_start, gl_screen_shutdown);
+       R_RegisterModule("GL_Screen", gl_screen_start, gl_screen_shutdown, gl_screen_newmap);
 }
 
 
 }
 
 
@@ -421,13 +373,9 @@ SCR_DrawRam
 */
 void SCR_DrawRam (void)
 {
 */
 void SCR_DrawRam (void)
 {
-       if (!scr_showram.value)
-               return;
-
-       if (!r_cache_thrash)
-               return;
-
-       Draw_Pic (32, 0, scr_ram);
+//     if (!scr_showram.integer)
+//             return;
+//     DrawQ_Pic (32, 0, "ram", 0, 0, 1, 1, 1, 1, 0);
 }
 
 /*
 }
 
 /*
@@ -438,11 +386,14 @@ SCR_DrawTurtle
 void SCR_DrawTurtle (void)
 {
        static int      count;
 void SCR_DrawTurtle (void)
 {
        static int      count;
-       
-       if (!scr_showturtle.value)
+
+       if (cls.state != ca_connected)
                return;
 
                return;
 
-       if (cl.frametime < 0.1)
+       if (!scr_showturtle.integer)
+               return;
+
+       if (host_frametime < 0.1)
        {
                count = 0;
                return;
        {
                count = 0;
                return;
@@ -452,7 +403,7 @@ void SCR_DrawTurtle (void)
        if (count < 3)
                return;
 
        if (count < 3)
                return;
 
-       Draw_Pic (0, 0, scr_turtle);
+       DrawQ_Pic (0, 0, "turtle", 0, 0, 1, 1, 1, 1, 0);
 }
 
 /*
 }
 
 /*
@@ -462,12 +413,14 @@ SCR_DrawNet
 */
 void SCR_DrawNet (void)
 {
 */
 void SCR_DrawNet (void)
 {
+       if (cls.state != ca_connected)
+               return;
        if (realtime - cl.last_received_message < 0.3)
                return;
        if (cls.demoplayback)
                return;
 
        if (realtime - cl.last_received_message < 0.3)
                return;
        if (cls.demoplayback)
                return;
 
-       Draw_Pic (64, 0, scr_net);
+       DrawQ_Pic (64, 0, "net", 0, 0, 1, 1, 1, 1, 0);
 }
 
 /*
 }
 
 /*
@@ -477,17 +430,19 @@ DrawPause
 */
 void SCR_DrawPause (void)
 {
 */
 void SCR_DrawPause (void)
 {
-       qpic_t  *pic;
+       cachepic_t      *pic;
 
 
-       if (!scr_showpause.value)               // turn off for screenshots
+       if (cls.state != ca_connected)
+               return;
+
+       if (!scr_showpause.integer)             // turn off for screenshots
                return;
 
        if (!cl.paused)
                return;
 
        pic = Draw_CachePic ("gfx/pause.lmp");
                return;
 
        if (!cl.paused)
                return;
 
        pic = Draw_CachePic ("gfx/pause.lmp");
-       Draw_Pic ( (vid.width - pic->width)/2, 
-               (vid.height - 48 - pic->height)/2, pic);
+       DrawQ_Pic ((vid.conwidth - pic->width)/2, (vid.conheight - pic->height)/2, "gfx/pause.lmp", 0, 0, 1, 1, 1, 1, 0);
 }
 
 
 }
 
 
@@ -497,17 +452,18 @@ void SCR_DrawPause (void)
 SCR_DrawLoading
 ==============
 */
 SCR_DrawLoading
 ==============
 */
+/*
 void SCR_DrawLoading (void)
 {
 void SCR_DrawLoading (void)
 {
-       qpic_t  *pic;
+       cachepic_t      *pic;
 
        if (!scr_drawloading)
                return;
 
        if (!scr_drawloading)
                return;
-               
+
        pic = Draw_CachePic ("gfx/loading.lmp");
        pic = Draw_CachePic ("gfx/loading.lmp");
-       Draw_Pic ( (vid.width - pic->width)/2, 
-               (vid.height - 48 - pic->height)/2, pic);
+       DrawQ_Pic ((vid.conwidth - pic->width)/2, (vid.conheight - pic->height)/2, "gfx/loading.lmp", 0, 0, 1, 1, 1, 1, 0);
 }
 }
+*/
 
 
 
 
 
 
@@ -522,23 +478,20 @@ SCR_SetUpToDrawConsole
 void SCR_SetUpToDrawConsole (void)
 {
        Con_CheckResize ();
 void SCR_SetUpToDrawConsole (void)
 {
        Con_CheckResize ();
-       
-       //if (scr_drawloading)
-       //      return;         // never a console with loading plaque
 
 // decide on the height of the console
        con_forcedup = !cl.worldmodel || cls.signon != SIGNONS;
 
        if (con_forcedup)
        {
 
 // decide on the height of the console
        con_forcedup = !cl.worldmodel || cls.signon != SIGNONS;
 
        if (con_forcedup)
        {
-               scr_conlines = vid.height;              // full screen
+               scr_conlines = vid.conheight;           // full screen
                scr_con_current = scr_conlines;
        }
        else if (key_dest == key_console)
                scr_con_current = scr_conlines;
        }
        else if (key_dest == key_console)
-               scr_conlines = vid.height/2;    // half screen
+               scr_conlines = vid.conheight/2; // half screen
        else
                scr_conlines = 0;                               // none visible
        else
                scr_conlines = 0;                               // none visible
-       
+
        if (scr_conlines < scr_con_current)
        {
                scr_con_current -= scr_conspeed.value*host_realframetime;
        if (scr_conlines < scr_con_current)
        {
                scr_con_current -= scr_conspeed.value*host_realframetime;
@@ -553,7 +506,7 @@ void SCR_SetUpToDrawConsole (void)
                        scr_con_current = scr_conlines;
        }
 }
                        scr_con_current = scr_conlines;
        }
 }
-       
+
 /*
 ==================
 SCR_DrawConsole
 /*
 ==================
 SCR_DrawConsole
@@ -563,8 +516,7 @@ void SCR_DrawConsole (void)
 {
        if (scr_con_current)
        {
 {
        if (scr_con_current)
        {
-               scr_copyeverything = 1;
-               Con_DrawConsole (scr_con_current, true);
+               Con_DrawConsole (scr_con_current);
                clearconsole = 0;
        }
        else
                clearconsole = 0;
        }
        else
@@ -575,54 +527,155 @@ void SCR_DrawConsole (void)
 }
 
 
 }
 
 
-/* 
-============================================================================== 
-                                               SCREEN SHOTS 
-============================================================================== 
-*/ 
+/*
+==============================================================================
+
+                                               SCREEN SHOTS
+
+==============================================================================
+*/
 
 /*
 
 /*
-================== 
+==================
 SCR_ScreenShot_f
 SCR_ScreenShot_f
-================== 
+==================
 */
 */
-void SCR_ScreenShot_f (void) 
+void SCR_ScreenShot_f (void)
 {
 {
-       byte            *buffer;
-       char            filename[80]; 
+       byte            *buffer, gamma[256];
+       char            filename[80];
        char            checkname[MAX_OSPATH];
        int                     i;
        char            checkname[MAX_OSPATH];
        int                     i;
-// 
-// find a file name to save it to 
-// 
+//
+// find a file name to save it to
+//
        strcpy(filename,"dp0000.tga");
        strcpy(filename,"dp0000.tga");
-               
-       for (i=0 ; i<=9999 ; i++) 
-       { 
-               filename[2] = (i/1000)%10 + '0'; 
-               filename[3] = (i/ 100)%10 + '0'; 
-               filename[4] = (i/  10)%10 + '0'; 
-               filename[5] = (i/   1)%10 + '0'; 
+
+       for (i=0 ; i<=9999 ; i++)
+       {
+               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
                sprintf (checkname, "%s/%s", com_gamedir, filename);
                if (Sys_FileTime(checkname) == -1)
                        break;  // file doesn't exist
-       } 
+       }
        if (i==10000)
        {
        if (i==10000)
        {
-               Con_Printf ("SCR_ScreenShot_f: Couldn't create a TGA file\n"); 
+               Con_Printf ("SCR_ScreenShot_f: Couldn't create a TGA file\n");
                return;
        }
 
                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 = Mem_Alloc(tempmempool, vid.realwidth*vid.realheight*3);
+       glReadPixels (vid.realx, vid.realy, vid.realwidth, vid.realheight, GL_RGB, GL_UNSIGNED_BYTE, buffer);
+       CHECKGLERROR
 
 
-       qfree(buffer);
+       // apply hardware gamma to the image
+       BuildGammaTable8((lighthalf && hardwaregammasupported) ? 2.0f : 1.0f, 1, 1, 0, gamma);
+       Image_GammaRemapRGB(buffer, buffer, vid.realwidth*vid.realheight, gamma, gamma, gamma);
+
+       Image_WriteTGARGB_preflipped(filename, vid.realwidth, vid.realheight, buffer);
+
+       Mem_Free(buffer);
        Con_Printf ("Wrote %s\n", filename);
 }
 
        Con_Printf ("Wrote %s\n", filename);
 }
 
+/*
+===============
+R_Envmap_f
+
+Grab six views for environment mapping tests
+===============
+*/
+float CalcFov (float fov_x, float width, float height);
+struct
+{
+       float angles[3];
+       char *name;
+}
+envmapinfo[6] =
+{
+       {{  0,   0, 0}, "ft"},
+       {{  0,  90, 0}, "rt"},
+       {{  0, 180, 0}, "bk"},
+       {{  0, 270, 0}, "lf"},
+       {{-90,  90, 0}, "up"},
+       {{ 90,  90, 0}, "dn"}
+};
+static void R_Envmap_f (void)
+{
+       int             i, size;
+       char    filename[256];
+       char    basename[256];
+       byte    *buffer, gamma[256];
+
+       if (Cmd_Argc() != 3)
+       {
+               Con_Printf ("envmap <basename> <size>: save out 6 cubic environment map images, usable with loadsky, note that size must one of 128, 256, 512, or 1024 and can't be bigger than your current resolution\n");
+               return;
+       }
+
+       if (!r_render.integer)
+               return;
+
+       strcpy(basename, Cmd_Argv(1));
+       size = atoi(Cmd_Argv(2));
+       if (size != 128 && size != 256 && size != 512 && size != 1024)
+       {
+               Con_Printf("envmap: size must be one of 128, 256, 512, or 1024\n");
+               return;
+       }
+       if (size > vid.realwidth || size > vid.realheight)
+       {
+               Con_Printf("envmap: your resolution is not big enough to render that size\n");
+               return;
+       }
+
+       buffer = Mem_Alloc(tempmempool, size*size*3);
+       if (buffer == NULL)
+       {
+               Con_Printf("envmap: unable to allocate memory for image\n");
+               return;
+       }
+
+       BuildGammaTable8((lighthalf && hardwaregammasupported) ? 2.0f : 1.0f, 1, 1, 0, gamma);
+
+//     glDrawBuffer  (GL_FRONT);
+//     glReadBuffer  (GL_FRONT);
+       glDrawBuffer  (GL_BACK);
+       glReadBuffer  (GL_BACK);
+       envmap = true;
+
+       r_refdef.x = 0;
+       r_refdef.y = 0;
+       r_refdef.width = size;
+       r_refdef.height = size;
+
+       r_refdef.fov_x = 90;
+       r_refdef.fov_y = 90;
+
+       for (i = 0;i < 6;i++)
+       {
+               VectorCopy(envmapinfo[i].angles, r_refdef.viewangles);
+               glClearColor(0,0,0,0);
+               glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // LordHavoc: clear the screen (around the view as well)
+               R_RenderView ();
+               glReadPixels (0, 0, size, size, GL_RGB, GL_UNSIGNED_BYTE, buffer);
+               sprintf(filename, "env/%s%s.tga", basename, envmapinfo[i].name);
+               Image_GammaRemapRGB(buffer, buffer, size * size, gamma, gamma, gamma);
+               Image_WriteTGARGB_preflipped(filename, size, size, buffer);
+       }
+
+       envmap = false;
+       glDrawBuffer  (GL_BACK);
+       glReadBuffer  (GL_BACK);
+
+       Mem_Free(buffer);
+
+       // cause refdef to be fixed
+//     vid.recalc_refdef = 1;
+}
 
 //=============================================================================
 
 
 //=============================================================================
 
@@ -633,29 +686,28 @@ SCR_BeginLoadingPlaque
 
 ================
 */
 
 ================
 */
+/*
 void SCR_BeginLoadingPlaque (void)
 {
        S_StopAllSounds (true);
 
 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
 // 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_drawloading = true;
-       scr_fullupdate = 0;
        SCR_UpdateScreen ();
        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;
 }
 }
+*/
 
 /*
 ===============
 
 /*
 ===============
@@ -663,17 +715,18 @@ SCR_EndLoadingPlaque
 
 ================
 */
 
 ================
 */
+/*
 void SCR_EndLoadingPlaque (void)
 {
 void SCR_EndLoadingPlaque (void)
 {
-       scr_disabled_for_loading = false;
-       scr_fullupdate = 0;
+//     scr_disabled_for_loading = false;
+       scr_drawloading = false;
        Con_ClearNotify ();
 }
        Con_ClearNotify ();
 }
+*/
 
 //=============================================================================
 
 char   *scr_notifystring;
 
 //=============================================================================
 
 char   *scr_notifystring;
-qboolean       scr_drawdialog;
 
 void SCR_DrawNotifyString (void)
 {
 
 void SCR_DrawNotifyString (void)
 {
@@ -683,7 +736,7 @@ void SCR_DrawNotifyString (void)
 
        start = scr_notifystring;
 
 
        start = scr_notifystring;
 
-       y = vid.height*0.35;
+       y = vid.conheight*0.35;
 
        do      
        {
 
        do      
        {
@@ -691,12 +744,9 @@ void SCR_DrawNotifyString (void)
                for (l=0 ; l<40 ; l++)
                        if (start[l] == '\n' || !start[l])
                                break;
                for (l=0 ; l<40 ; l++)
                        if (start[l] == '\n' || !start[l])
                                break;
-               x = (vid.width - l*8)/2;
-               // LordHavoc: speedup
-//             for (j=0 ; j<l ; j++, x+=8)
-//                     Draw_Character (x, y, start[j]);        
-               Draw_String (x, y, start, l);
-                       
+               x = (vid.conwidth - l*8)/2;
+               DrawQ_String (x, y, start, l, 8, 8, 1, 1, 1, 1, 0);
+
                y += 8;
 
                while (*start && *start != '\n')
                y += 8;
 
                while (*start && *start != '\n')
@@ -705,116 +755,117 @@ void SCR_DrawNotifyString (void)
                if (!*start)
                        break;
                start++;                // skip the \n
                if (!*start)
                        break;
                start++;                // skip the \n
-       } while (1);
+       }
+       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);
+void DrawCrosshair(int num);
 
 
-       scr_fullupdate = 0;
-       SCR_UpdateScreen ();
+char r_speeds_string[1024];
+int speedstringcount, r_timereport_active;
+double r_timereport_temp = 0, r_timereport_current = 0, r_timereport_start = 0;
 
 
-       return key_lastpress == 'y';
-}
+void R_TimeReport(char *desc)
+{
+       char tempbuf[256];
+       int length;
+       int t;
 
 
+       if (!r_timereport_active)
+               return;
 
 
-//=============================================================================
+       r_timereport_temp = r_timereport_current;
+       r_timereport_current = Sys_DoubleTime();
+       t = (int) ((r_timereport_current - r_timereport_temp) * 1000000.0);
 
 
-/*
-===============
-SCR_BringDownConsole
+       sprintf(tempbuf, "%8i %s", t, desc);
+       length = strlen(tempbuf);
+       while (length < 20)
+               tempbuf[length++] = ' ';
+       tempbuf[length] = 0;
+       if (speedstringcount + length > (vid.conwidth / 8))
+       {
+               strcat(r_speeds_string, "\n");
+               speedstringcount = 0;
+       }
+       // skip the space at the beginning if it's the first on the line
+       if (speedstringcount == 0)
+       {
+               strcat(r_speeds_string, tempbuf + 1);
+               speedstringcount = length - 1;
+       }
+       else
+       {
+               strcat(r_speeds_string, tempbuf);
+               speedstringcount += length;
+       }
+}
 
 
-Brings the console down and fades the blends back to normal
-================
-*/
-void SCR_BringDownConsole (void)
+void R_TimeReport_Start(void)
 {
 {
-       int             i;
-       
-       scr_centertime_off = 0;
-       
-       for (i=0 ; i<20 && scr_conlines != scr_con_current ; i++)
-               SCR_UpdateScreen ();
-
-       cl.cshifts[0].percent = 0;              // no area contents blend on next frame
+       r_timereport_active = r_speeds.integer && cl.worldmodel && cls.state == ca_connected;
+       r_speeds_string[0] = 0;
+       if (r_timereport_active)
+       {
+               speedstringcount = 0;
+               AngleVectors (r_refdef.viewangles, vpn, NULL, NULL);
+               //sprintf(r_speeds_string, "org:'%c%6.2f %c%6.2f %c%6.2f' ang:'%c%3.0f %c%3.0f %c%3.0f' dir:'%c%2.3f %c%2.3f %c%2.3f'\n%6i walls %6i dlitwalls %7i modeltris %7i meshtris\nBSP: %6i faces %6i nodes %6i leafs\n%4i models %4i bmodels %4i sprites %5i particles %3i dlights\n",
+               //      r_refdef.vieworg[0] < 0 ? '-' : ' ', fabs(r_refdef.vieworg[0]), r_refdef.vieworg[1] < 0 ? '-' : ' ', fabs(r_refdef.vieworg[1]), r_refdef.vieworg[2] < 0 ? '-' : ' ', fabs(r_refdef.vieworg[2]),
+               //      r_refdef.viewangles[0] < 0 ? '-' : ' ', fabs(r_refdef.viewangles[0]), r_refdef.viewangles[1] < 0 ? '-' : ' ', fabs(r_refdef.viewangles[1]), r_refdef.viewangles[2] < 0 ? '-' : ' ', fabs(r_refdef.viewangles[2]),
+               //      vpn[0] < 0 ? '-' : ' ', fabs(vpn[0]), vpn[1] < 0 ? '-' : ' ', fabs(vpn[1]), vpn[2] < 0 ? '-' : ' ', fabs(vpn[2]),
+               sprintf(r_speeds_string, "org:'%+8.2f %+8.2f %+8.2f' ang:'%+4.0f %+4.0f %+4.0f' dir:'%+2.3f %+2.3f %+2.3f'\n%6i walls %6i dlitwalls %7i modeltris %7i meshtris\nBSP: %6i faces %6i nodes %6i leafs\n%4i models %4i bmodels %4i sprites %5i particles %3i dlights\n",
+                       r_refdef.vieworg[0], r_refdef.vieworg[1], r_refdef.vieworg[2],
+                       r_refdef.viewangles[0], r_refdef.viewangles[1], r_refdef.viewangles[2],
+                       vpn[0], vpn[1], vpn[2],
+                       c_brush_polys, c_light_polys, c_alias_polys, c_meshtris,
+                       c_faces, c_nodes, c_leafs,
+                       c_models, c_bmodels, c_sprites, c_particles, c_dlights);
+
+               c_brush_polys = 0;
+               c_alias_polys = 0;
+               c_light_polys = 0;
+               c_faces = 0;
+               c_nodes = 0;
+               c_leafs = 0;
+               c_models = 0;
+               c_bmodels = 0;
+               c_sprites = 0;
+               c_particles = 0;
+       //      c_dlights = 0;
+
+               r_timereport_start = Sys_DoubleTime();
+       }
 }
 
 }
 
-void DrawCrosshair(int num);
-void GL_Set2D (void);
-
-extern void SHOWLMP_drawall();
-extern cvar_t contrast;
-extern cvar_t brightness;
-extern cvar_t gl_lightmode;
-extern cvar_t r_speeds2;
-
-void GL_BrightenScreen()
+void R_TimeReport_End(void)
 {
 {
-       float f;
-       if (!r_render.value)
-               return;
-       glDisable(GL_TEXTURE_2D);
-       glEnable(GL_BLEND);
-       f = brightness.value = bound(1.0f, brightness.value, 5.0f);
-       if (f >= 1.01f)
+       r_timereport_current = r_timereport_start;
+       R_TimeReport("total");
+
+       if (r_timereport_active)
        {
        {
-               glBlendFunc (GL_DST_COLOR, GL_ONE);
-               glBegin (GL_TRIANGLES);
-               while (f >= 1.01f)
+               int i, j, lines, y;
+               lines = 1;
+               for (i = 0;r_speeds_string[i];i++)
+                       if (r_speeds_string[i] == '\n')
+                               lines++;
+               y = vid.conheight - sb_lines - lines * 8/* - 8*/;
+               i = j = 0;
+               DrawQ_Fill(0, y, vid.conwidth, lines * 8, 0, 0, 0, 0.5, 0);
+               while (r_speeds_string[i])
                {
                {
-                       if (f >= 2)
-                               glColor3f (1, 1, 1);
-                       else
-                               glColor3f (f-1, f-1, f-1);
-                       glVertex2f (-5000, -5000);
-                       glVertex2f (10000, -5000);
-                       glVertex2f (-5000, 10000);
-                       f *= 0.5;
+                       j = i;
+                       while (r_speeds_string[i] && r_speeds_string[i] != '\n')
+                               i++;
+                       if (i - j > 0)
+                               DrawQ_String(0, y, r_speeds_string + j, i - j, 8, 8, 1, 1, 1, 1, 0);
+                       if (r_speeds_string[i] == '\n')
+                               i++;
+                       y += 8;
                }
                }
-               glEnd ();
-       }
-       glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-       contrast.value = bound(0.2, contrast.value, 1.0);
-       if (contrast.value < 0.99f)
-       {
-               glBegin (GL_TRIANGLES);
-               glColor4f (1, 1, 1, 1-contrast.value);
-               glVertex2f (-5000, -5000);
-               glVertex2f (10000, -5000);
-               glVertex2f (-5000, 10000);
-               glEnd ();
        }
        }
-
-       glEnable (GL_CULL_FACE);
-       glEnable (GL_DEPTH_TEST);
-       glDisable(GL_BLEND);
-       glEnable(GL_TEXTURE_2D);
 }
 
 /*
 }
 
 /*
@@ -827,147 +878,90 @@ text to the screen.
 LordHavoc: due to my rewrite of R_WorldNode, it no longer takes 256k of stack space :)
 ==================
 */
 LordHavoc: due to my rewrite of R_WorldNode, it no longer takes 256k of stack space :)
 ==================
 */
-void GL_Finish();
 void SCR_UpdateScreen (void)
 {
 void SCR_UpdateScreen (void)
 {
-       double  time1 = 0, time2;
-
-       if (r_speeds.value)
-               time1 = Sys_FloatTime ();
-
-       scr_copytop = 0;
-       scr_copyeverything = 0;
+       VID_UpdateGamma(false);
 
        if (scr_disabled_for_loading)
 
        if (scr_disabled_for_loading)
-       {
-               if (realtime - scr_disabled_time > 60)
-               {
-                       scr_disabled_for_loading = false;
-                       Con_Printf ("load failed.\n");
-               }
-               else
-                       return;
-       }
+               return;
 
        if (!scr_initialized || !con_initialized)
                return;                         // not initialized yet
 
 
        if (!scr_initialized || !con_initialized)
                return;                         // not initialized yet
 
+       //Mem_CheckSentinelsGlobal();
+       //R_TimeReport("memtest");
 
 
-       GL_BeginRendering (&glx, &gly, &glwidth, &glheight);
-       
-       //
-       // determine size of refresh window
-       //
-       if (oldfov != scr_fov.value)
-       {
-               oldfov = scr_fov.value;
-               vid.recalc_refdef = true;
-       }
+       R_TimeReport("other");
 
 
-       if (oldscreensize != scr_viewsize.value)
-       {
-               oldscreensize = scr_viewsize.value;
-               vid.recalc_refdef = true;
-       }
+       glFinish ();
+       CHECKGLERROR
 
 
-       if (vid.recalc_refdef)
-               SCR_CalcRefdef ();
+       GL_EndRendering ();
 
 
-       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)
-       }
+       R_TimeReport("finish");
 
 
-//
-// do 3D refresh drawing, and then update the screen
-//
-       SCR_SetUpToDrawConsole ();
+       GL_BeginRendering (&vid.realx, &vid.realy, &vid.realwidth, &vid.realheight);
 
 
-       V_RenderView ();
+       if (gl_combine.integer && !gl_combine_extension)
+               Cvar_SetValue("gl_combine", 0);
 
 
-       GL_Set2D ();
+       lighthalf = gl_lightmode.integer;
 
 
-       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)
-       {
-               Sbar_FinaleOverlay ();
-               SCR_CheckDrawCenterString ();
-       }
-       else
-       {
-               if (crosshair.value)
-                       DrawCrosshair(crosshair.value - 1);
-               
-               SCR_DrawRam ();
-               SCR_DrawNet ();
-               SCR_DrawTurtle ();
-               SCR_DrawPause ();
-               SCR_CheckDrawCenterString ();
-               Sbar_Draw ();
-               SHOWLMP_drawall();
-               SCR_DrawConsole ();     
-               M_Draw ();
-       }
+       lightscalebit = 0;
+       if (lighthalf)
+               lightscalebit += 1;
 
 
-       if (showfps.value)
-       {
-               static double currtime;
-               double newtime;
-               char temp[32];
-               int calc;
-               newtime = Sys_FloatTime();
-               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);
-       }
+       if (gl_combine.integer && r_multitexture.integer)
+               lightscalebit += 2;
 
 
-       if (r_speeds2.value)
-       {
-               extern char r_speeds2_string1[81], r_speeds2_string2[81], r_speeds2_string3[81], r_speeds2_string4[81], r_speeds2_string5[81], r_speeds2_string6[81];
-               Draw_String(0, vid.height - sb_lines - 48, r_speeds2_string1, 80);
-               Draw_String(0, vid.height - sb_lines - 40, r_speeds2_string2, 80);
-               Draw_String(0, vid.height - sb_lines - 32, r_speeds2_string3, 80);
-               Draw_String(0, vid.height - sb_lines - 24, r_speeds2_string4, 80);
-               Draw_String(0, vid.height - sb_lines - 16, r_speeds2_string5, 80);
-               Draw_String(0, vid.height - sb_lines -  8, r_speeds2_string6, 80);
-       }
+       lightscale = 1.0f / (float) (1 << lightscalebit);
 
 
-       V_UpdateBlends ();
+       R_TimeReport("setup");
 
 
-       GL_BrightenScreen();
+       // determine size of refresh window
+       SCR_CalcRefdef();
 
 
-       GL_Finish();
+       R_TimeReport("calcrefdef");
 
 
-       if (r_speeds.value)
+       if (r_render.integer)
        {
        {
-               time2 = Sys_FloatTime ();
-               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);
+               glClearColor(0,0,0,0);
+               CHECKGLERROR
+               glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // LordHavoc: clear the screen (around the view as well)
+               CHECKGLERROR
+               if (gl_dither.integer)
+                       glEnable(GL_DITHER);
+               else
+                       glDisable(GL_DITHER);
+               CHECKGLERROR
        }
        }
-       GL_EndRendering ();
-}
 
 
-// for profiling, this is separated
-void GL_Finish()
-{
-       if (!r_render.value)
-               return;
-       glFinish ();
-}
+       SCR_SetUpToDrawConsole();
+
+       R_TimeReport("clear");
+
+       if (scr_conlines < vid.conheight)
+               R_RenderView();
+
+       SCR_DrawRam();
+       SCR_DrawNet();
+       SCR_DrawTurtle();
+       SCR_DrawPause();
+       SCR_CheckDrawCenterString();
+       Sbar_Draw();
+       SHOWLMP_drawall();
 
 
+       SCR_DrawConsole();
+       M_Draw();
+
+       ui_draw();
+
+       R_TimeReport("2d");
+
+       R_TimeReport_End();
+
+       // draw 2D stuff
+       R_DrawQueue();
+
+       R_TimeReport_Start();
+}