]> de.git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - cl_screen.c
fixed an improperly filed change request
[xonotic/darkplaces.git] / cl_screen.c
index 99e29b968696dc70f7cb4c30e539974317b2f988..7c2b09bf00a499483acce2c37c77597af529eea5 100644 (file)
@@ -4,13 +4,13 @@
 #include "image.h"
 #include "jpeg.h"
 #include "cl_collision.h"
+#include "libcurl.h"
 #include "csprogs.h"
 
 cvar_t scr_viewsize = {CVAR_SAVE, "viewsize","100", "how large the view should be, 110 disables inventory bar, 120 disables status bar"};
 cvar_t scr_fov = {CVAR_SAVE, "fov","90", "field of vision, 1-170 degrees, default 90, some players use 110-130"};      // 1 - 170
-cvar_t scr_conspeed = {CVAR_SAVE, "scr_conspeed","900", "speed of console open/close"}; // LordHavoc: quake used 300
 cvar_t scr_conalpha = {CVAR_SAVE, "scr_conalpha", "1", "opacity of console background"};
-cvar_t scr_conbrightness = {CVAR_SAVE, "scr_conbrightness", "0.2", "brightness of console background (0 = black, 1 = image)"};
+cvar_t scr_conbrightness = {CVAR_SAVE, "scr_conbrightness", "1", "brightness of console background (0 = black, 1 = image)"};
 cvar_t scr_conforcewhiledisconnected = {0, "scr_conforcewhiledisconnected", "1", "forces fullscreen console while disconnected"};
 cvar_t scr_menuforcewhiledisconnected = {0, "scr_menuforcewhiledisconnected", "0", "forces menu while disconnected"};
 cvar_t scr_centertime = {0, "scr_centertime","2", "how long centerprint messages show"};
@@ -24,13 +24,13 @@ cvar_t vid_conheight = {CVAR_SAVE, "vid_conheight", "480", "virtual height of 2D
 cvar_t vid_pixelheight = {CVAR_SAVE, "vid_pixelheight", "1", "adjusts vertical field of vision to account for non-square pixels (1280x1024 on a CRT monitor for example)"};
 cvar_t scr_screenshot_jpeg = {CVAR_SAVE, "scr_screenshot_jpeg","1", "save jpeg instead of targa"};
 cvar_t scr_screenshot_jpeg_quality = {CVAR_SAVE, "scr_screenshot_jpeg_quality","0.9", "image quality of saved jpeg"};
-cvar_t scr_screenshot_gamma = {CVAR_SAVE, "scr_screenshot_gamma","2.2", "gamma correction on saved screenshots and videos, 1.0 saves unmodified images"};
+cvar_t scr_screenshot_gammaboost = {CVAR_SAVE, "scr_screenshot_gammaboost","1", "gamma correction on saved screenshots and videos, 1.0 saves unmodified images"};
 // scr_screenshot_name is defined in fs.c
-cvar_t cl_capturevideo = {0, "cl_capturevideo", "0", "enables saving of video to a file or files (default is .tga files, if scr_screenshot_jpeg is on it saves .jpg files (VERY SLOW), if any rawrgb or rawyv12 are on it saves those formats instead, note that scr_screenshot_gamma affects the brightness of the output)"};
-cvar_t cl_capturevideo_sound = {0, "cl_capturevideo_sound", "0", "enables saving of sound to a .wav file (warning: this requires exact sync, if your hard drive can't keep up it will abort, if your graphics can't keep up it will save duplicate frames to maintain sound sync)"};
+cvar_t cl_capturevideo = {0, "cl_capturevideo", "0", "enables saving of video to a file or files (default is .tga files, if scr_screenshot_jpeg is on it saves .jpg files (VERY SLOW), if any rawrgb or rawyv12 are on it saves those formats instead, note that scr_screenshot_gammaboost affects the brightness of the output)"};
 cvar_t cl_capturevideo_fps = {0, "cl_capturevideo_fps", "30", "how many frames per second to save (29.97 for NTSC, 30 for typical PC video, 15 can be useful)"};
 cvar_t cl_capturevideo_rawrgb = {0, "cl_capturevideo_rawrgb", "0", "saves a single .rgb video file containing raw RGB images (you'll need special processing tools to encode this to something more useful)"};
 cvar_t cl_capturevideo_rawyv12 = {0, "cl_capturevideo_rawyv12", "0", "saves a single .yv12 video file containing raw YV12 (luma plane, then half resolution chroma planes, first chroma blue then chroma red, this is the format used internally by many encoders, some tools can read it directly)"};
+cvar_t cl_capturevideo_number = {CVAR_SAVE, "cl_capturevideo_number", "1", "number to append to video filename, incremented each time a capture begins"};
 cvar_t r_letterbox = {0, "r_letterbox", "0", "reduces vertical height of view to simulate a letterboxed movie effect (can be used by mods for cutscenes)"};
 cvar_t r_stereo_separation = {0, "r_stereo_separation", "4", "separation of eyes in the world (try negative values too)"};
 cvar_t r_stereo_sidebyside = {0, "r_stereo_sidebyside", "0", "side by side views (for those who can't afford glasses but can afford eye strain)"};
@@ -51,7 +51,6 @@ float         scr_con_current;
 
 extern int     con_vislines;
 
-void DrawCrosshair(int num);
 static void SCR_ScreenShot_f (void);
 static void R_Envmap_f (void);
 
@@ -126,11 +125,19 @@ void SCR_DrawCenterString (void)
        color = -1;
        do
        {
-       // scan the width of the line
+               // scan the number of characters on the line, not counting color codes
+               int chars = 0;
                for (l=0 ; l<vid_conwidth.integer/8 ; l++)
+               {
                        if (start[l] == '\n' || !start[l])
                                break;
-               x = (vid_conwidth.integer - l*8)/2;
+                       // color codes add no visible characters, so don't count them
+                       if (start[l] == '^' && (start[l+1] >= '0' && start[l+1] <= '9'))
+                               l++;
+                       else
+                               chars++;
+               }
+               x = (vid_conwidth.integer - chars*8)/2;
                if (l > 0)
                {
                        if (remaining < l)
@@ -296,27 +303,88 @@ void SCR_DrawBrand (void)
 
 /*
 ==============
-SCR_DrawDownload
+SCR_DrawQWDownload
 ==============
 */
-static void SCR_DrawDownload(void)
+static int SCR_DrawQWDownload(int offset)
 {
        int len;
        float x, y;
        float size = 8;
        char temp[256];
        if (!cls.qw_downloadname[0])
-               return;
+               return 0;
        dpsnprintf(temp, sizeof(temp), "Downloading %s ...  %3i%%\n", cls.qw_downloadname, cls.qw_downloadpercent);
        len = (int)strlen(temp);
        x = (vid_conwidth.integer - len*size) / 2;
-       y = vid_conheight.integer - size;
+       y = vid_conheight.integer - size - offset;
        DrawQ_Pic(0, y, NULL, vid_conwidth.integer, size, 0, 0, 0, 0.5, 0);
        DrawQ_String(x, y, temp, len, size, size, 1, 1, 1, 1, 0);
+       return 8;
 }
 
-//=============================================================================
+/*
+==============
+SCR_DrawCurlDownload
+==============
+*/
+static int SCR_DrawCurlDownload(int offset)
+{
+       int len;
+       int nDownloads;
+       int i;
+       float x, y;
+       float size = 8;
+       Curl_downloadinfo_t *downinfo;
+       char temp[256];
+       const char *addinfo;
 
+       downinfo = Curl_GetDownloadInfo(&nDownloads, &addinfo);
+       if(!downinfo)
+               return 0;
+
+       y = vid_conheight.integer - size * nDownloads - offset;
+
+       if(addinfo)
+       {
+               len = (int)strlen(addinfo);
+               x = (vid_conwidth.integer - len*size) / 2;
+               DrawQ_Pic(0, y - size, NULL, vid_conwidth.integer, size, 1, 1, 1, 0.8, 0);
+               DrawQ_String(x, y - size, addinfo, len, size, size, 0, 0, 0, 1, 0);
+       }
+
+       for(i = 0; i != nDownloads; ++i)
+       {
+               if(downinfo[i].queued)
+                       dpsnprintf(temp, sizeof(temp), "Still in queue: %s\n", downinfo[i].filename);
+               else if(downinfo[i].progress <= 0)
+                       dpsnprintf(temp, sizeof(temp), "Downloading %s ...  ???.?%% @ %.1f KiB/s\n", downinfo[i].filename, downinfo[i].speed / 1024.0);
+               else
+                       dpsnprintf(temp, sizeof(temp), "Downloading %s ...  %5.1f%% @ %.1f KiB/s\n", downinfo[i].filename, 100.0 * downinfo[i].progress, downinfo[i].speed / 1024.0);
+               len = (int)strlen(temp);
+               x = (vid_conwidth.integer - len*size) / 2;
+               DrawQ_Pic(0, y + i * size, NULL, vid_conwidth.integer, size, 0, 0, 0, 0.8, 0);
+               DrawQ_String(x, y + i * size, temp, len, size, size, 1, 1, 1, 1, 0);
+       }
+
+       Z_Free(downinfo);
+
+       return 8 * (nDownloads + (addinfo ? 1 : 0));
+}
+
+/*
+==============
+SCR_DrawDownload
+==============
+*/
+static void SCR_DrawDownload()
+{
+       int offset = 0;
+       offset += SCR_DrawQWDownload(offset);
+       offset += SCR_DrawCurlDownload(offset);
+}
+
+//=============================================================================
 
 /*
 ==================
@@ -352,23 +420,7 @@ void SCR_SetUpToDrawConsole (void)
        else
                conlines = 0;                           // none visible
 
-       if (scr_conspeed.value)
-       {
-               if (scr_con_current > conlines)
-               {
-                       scr_con_current -= scr_conspeed.value*cl.realframetime;
-                       if (scr_con_current < conlines)
-                               scr_con_current = conlines;
-               }
-               else if (scr_con_current < conlines)
-               {
-                       scr_con_current += scr_conspeed.value*cl.realframetime;
-                       if (scr_con_current > conlines)
-                               scr_con_current = conlines;
-               }
-       }
-       else
-               scr_con_current = conlines;
+       scr_con_current = conlines;
 }
 
 /*
@@ -388,7 +440,7 @@ void SCR_DrawConsole (void)
        else
        {
                con_vislines = 0;
-               if (key_dest == key_game || key_dest == key_message)
+               if ((key_dest == key_game || key_dest == key_message) && !r_letterbox.value)
                        Con_DrawNotify ();      // only draw notify in game
        }
 }
@@ -424,7 +476,8 @@ void R_TimeReport(char *desc)
        if (r_speeds.integer < 2 || !r_timereport_active)
                return;
 
-       qglFinish();
+       CHECKGLERROR
+       qglFinish();CHECKGLERROR
        r_timereport_temp = r_timereport_current;
        r_timereport_current = Sys_DoubleTime();
        t = (int) ((r_timereport_current - r_timereport_temp) * 1000000.0 + 0.5);
@@ -480,15 +533,15 @@ void R_TimeReport_Frame(void)
                speedstringcount = 0;
                r_speeds_string[0] = 0;
                r_timereport_active = false;
-               sprintf(r_speeds_string + strlen(r_speeds_string), "org:'%+8.2f %+8.2f %+8.2f' dir:'%+2.3f %+2.3f %+2.3f'\n", r_vieworigin[0], r_vieworigin[1], r_vieworigin[2], r_viewforward[0], r_viewforward[1], r_viewforward[2]);
-               sprintf(r_speeds_string + strlen(r_speeds_string), "%5i entities%6i surfaces%6i triangles%5i leafs%5i portals%6i particles\n", renderstats.entities, renderstats.entities_surfaces, renderstats.entities_triangles, renderstats.world_leafs, renderstats.world_portals, renderstats.particles);
-               sprintf(r_speeds_string + strlen(r_speeds_string), "%4i lights%4i clears%4i scissored%7i light%7i shadow%7i dynamic\n", renderstats.lights, renderstats.lights_clears, renderstats.lights_scissored, renderstats.lights_lighttriangles, renderstats.lights_shadowtriangles, renderstats.lights_dynamicshadowtriangles);
-               if (renderstats.bloom)
-                       sprintf(r_speeds_string + strlen(r_speeds_string), "rendered%6i meshes%8i triangles bloompixels%8i copied%8i drawn\n", renderstats.meshes, renderstats.meshes_elements / 3, renderstats.bloom_copypixels, renderstats.bloom_drawpixels);
+               sprintf(r_speeds_string + strlen(r_speeds_string), "org:'%+8.2f %+8.2f %+8.2f' dir:'%+2.3f %+2.3f %+2.3f'\n", r_view.origin[0], r_view.origin[1], r_view.origin[2], r_view.forward[0], r_view.forward[1], r_view.forward[2]);
+               sprintf(r_speeds_string + strlen(r_speeds_string), "%5i entities%6i surfaces%6i triangles%5i leafs%5i portals%6i particles\n", r_refdef.stats.entities, r_refdef.stats.entities_surfaces, r_refdef.stats.entities_triangles, r_refdef.stats.world_leafs, r_refdef.stats.world_portals, r_refdef.stats.particles);
+               sprintf(r_speeds_string + strlen(r_speeds_string), "%4i lights%4i clears%4i scissored%7i light%7i shadow%7i dynamic\n", r_refdef.stats.lights, r_refdef.stats.lights_clears, r_refdef.stats.lights_scissored, r_refdef.stats.lights_lighttriangles, r_refdef.stats.lights_shadowtriangles, r_refdef.stats.lights_dynamicshadowtriangles);
+               if (r_refdef.stats.bloom)
+                       sprintf(r_speeds_string + strlen(r_speeds_string), "rendered%6i meshes%8i triangles bloompixels%8i copied%8i drawn\n", r_refdef.stats.meshes, r_refdef.stats.meshes_elements / 3, r_refdef.stats.bloom_copypixels, r_refdef.stats.bloom_drawpixels);
                else
-                       sprintf(r_speeds_string + strlen(r_speeds_string), "rendered%6i meshes%8i triangles\n", renderstats.meshes, renderstats.meshes_elements / 3);
+                       sprintf(r_speeds_string + strlen(r_speeds_string), "rendered%6i meshes%8i triangles\n", r_refdef.stats.meshes, r_refdef.stats.meshes_elements / 3);
 
-               memset(&renderstats, 0, sizeof(renderstats));
+               memset(&r_refdef.stats, 0, sizeof(r_refdef.stats));
 
                if (r_speeds.integer >= 2)
                {
@@ -527,7 +580,6 @@ void CL_Screen_Init(void)
 {
        Cvar_RegisterVariable (&scr_fov);
        Cvar_RegisterVariable (&scr_viewsize);
-       Cvar_RegisterVariable (&scr_conspeed);
        Cvar_RegisterVariable (&scr_conalpha);
        Cvar_RegisterVariable (&scr_conbrightness);
        Cvar_RegisterVariable (&scr_conforcewhiledisconnected);
@@ -543,12 +595,12 @@ void CL_Screen_Init(void)
        Cvar_RegisterVariable (&vid_pixelheight);
        Cvar_RegisterVariable (&scr_screenshot_jpeg);
        Cvar_RegisterVariable (&scr_screenshot_jpeg_quality);
-       Cvar_RegisterVariable (&scr_screenshot_gamma);
+       Cvar_RegisterVariable (&scr_screenshot_gammaboost);
        Cvar_RegisterVariable (&cl_capturevideo);
-       Cvar_RegisterVariable (&cl_capturevideo_sound);
        Cvar_RegisterVariable (&cl_capturevideo_fps);
        Cvar_RegisterVariable (&cl_capturevideo_rawrgb);
        Cvar_RegisterVariable (&cl_capturevideo_rawyv12);
+       Cvar_RegisterVariable (&cl_capturevideo_number);
        Cvar_RegisterVariable (&r_letterbox);
        Cvar_RegisterVariable(&r_stereo_separation);
        Cvar_RegisterVariable(&r_stereo_sidebyside);
@@ -634,7 +686,9 @@ void SCR_CaptureVideo_BeginVideo(void)
        cls.capturevideo_soundrate = 0;
        cls.capturevideo_frame = 0;
        cls.capturevideo_buffer = (unsigned char *)Mem_Alloc(tempmempool, vid.width * vid.height * (3+3+3) + 18);
-       gamma = 1.0/scr_screenshot_gamma.value;
+       gamma = 1.0/scr_screenshot_gammaboost.value;
+       dpsnprintf(cls.capturevideo_basename, sizeof(cls.capturevideo_basename), "video/dpvideo%03i", cl_capturevideo_number.integer);
+       Cvar_SetValueQuick(&cl_capturevideo_number, cl_capturevideo_number.integer + 1);
 
        /*
        for (i = 0;i < 256;i++)
@@ -677,12 +731,12 @@ Cr = R *  .500 + G * -.419 + B * -.0813 + 128.;
        if (cl_capturevideo_rawrgb.integer)
        {
                cls.capturevideo_format = CAPTUREVIDEOFORMAT_RAWRGB;
-               cls.capturevideo_videofile = FS_Open ("video/dpvideo.rgb", "wb", false, true);
+               cls.capturevideo_videofile = FS_Open (va("%s.rgb", cls.capturevideo_basename), "wb", false, true);
        }
        else if (cl_capturevideo_rawyv12.integer)
        {
                cls.capturevideo_format = CAPTUREVIDEOFORMAT_RAWYV12;
-               cls.capturevideo_videofile = FS_Open ("video/dpvideo.yv12", "wb", false, true);
+               cls.capturevideo_videofile = FS_Open (va("%s.yv12", cls.capturevideo_basename), "wb", false, true);
        }
        else if (scr_screenshot_jpeg.integer)
        {
@@ -695,15 +749,15 @@ Cr = R *  .500 + G * -.419 + B * -.0813 + 128.;
                cls.capturevideo_videofile = NULL;
        }
 
-       if (cl_capturevideo_sound.integer)
+       cls.capturevideo_soundfile = FS_Open (va("%s.wav", cls.capturevideo_basename), "wb", false, true);
+       if (cls.capturevideo_soundfile)
        {
-               cls.capturevideo_soundfile = FS_Open ("video/dpvideo.wav", "wb", false, true);
                // wave header will be filled out when video ends
                memset(out, 0, 44);
                FS_Write (cls.capturevideo_soundfile, out, 44);
        }
        else
-               cls.capturevideo_soundfile = NULL;
+               Con_Printf("Could not open video/dpvideo.wav for writing, sound capture disabled\n");
 }
 
 void SCR_CaptureVideo_EndVideo(void)
@@ -775,14 +829,17 @@ qboolean SCR_CaptureVideo_VideoFrame(int newframenum)
        unsigned char *b, *out;
        char filename[32];
        int outoffset = (width/2)*(height/2);
+       CHECKGLERROR
        //return SCR_ScreenShot(filename, cls.capturevideo_buffer, cls.capturevideo_buffer + vid.width * vid.height * 3, cls.capturevideo_buffer + vid.width * vid.height * 6, 0, 0, vid.width, vid.height, false, false, false, jpeg, true);
        // speed is critical here, so do saving as directly as possible
        switch (cls.capturevideo_format)
        {
        case CAPTUREVIDEOFORMAT_RAWYV12:
+               // if there's no videofile we have to just give up, and abort saving if there's no video or sound file
+               if (!cls.capturevideo_videofile)
+                       return cls.capturevideo_soundfile != NULL;
                // FIXME: width/height must be multiple of 2, enforce this?
-               qglReadPixels (x, y, width, height, GL_RGB, GL_UNSIGNED_BYTE, cls.capturevideo_buffer);
-               CHECKGLERROR
+               qglReadPixels (x, y, width, height, GL_RGB, GL_UNSIGNED_BYTE, cls.capturevideo_buffer);CHECKGLERROR
                // process one line at a time, and CbCr every other line at 2 pixel intervals
                for (y = 0;y < height;y++)
                {
@@ -823,18 +880,19 @@ qboolean SCR_CaptureVideo_VideoFrame(int newframenum)
                                return false;
                return true;
        case CAPTUREVIDEOFORMAT_RAWRGB:
-               qglReadPixels (x, y, width, height, GL_RGB, GL_UNSIGNED_BYTE, cls.capturevideo_buffer);
-               CHECKGLERROR
+               // if there's no videofile we have to just give up, and abort saving if there's no video or sound file
+               if (!cls.capturevideo_videofile)
+                       return cls.capturevideo_soundfile != NULL;
+               qglReadPixels (x, y, width, height, GL_RGB, GL_UNSIGNED_BYTE, cls.capturevideo_buffer);CHECKGLERROR
                for (;cls.capturevideo_frame < newframenum;cls.capturevideo_frame++)
                        if (!FS_Write (cls.capturevideo_videofile, cls.capturevideo_buffer, width*height*3))
                                return false;
                return true;
        case CAPTUREVIDEOFORMAT_JPEG:
-               qglReadPixels (x, y, width, height, GL_RGB, GL_UNSIGNED_BYTE, cls.capturevideo_buffer);
-               CHECKGLERROR
+               qglReadPixels (x, y, width, height, GL_RGB, GL_UNSIGNED_BYTE, cls.capturevideo_buffer);CHECKGLERROR
                for (;cls.capturevideo_frame < newframenum;cls.capturevideo_frame++)
                {
-                       sprintf(filename, "video/dp%06d.jpg", cls.capturevideo_frame);
+                       sprintf(filename, "%s_%06d.jpg", cls.capturevideo_basename, cls.capturevideo_frame);
                        if (!JPEG_SaveImage_preflipped (filename, width, height, cls.capturevideo_buffer))
                                return false;
                }
@@ -848,11 +906,10 @@ qboolean SCR_CaptureVideo_VideoFrame(int newframenum)
                cls.capturevideo_buffer[14] = (height >> 0) & 0xFF;
                cls.capturevideo_buffer[15] = (height >> 8) & 0xFF;
                cls.capturevideo_buffer[16] = 24;       // pixel size
-               qglReadPixels (x, y, width, height, GL_BGR, GL_UNSIGNED_BYTE, cls.capturevideo_buffer + 18);
-               CHECKGLERROR
+               qglReadPixels (x, y, width, height, GL_BGR, GL_UNSIGNED_BYTE, cls.capturevideo_buffer + 18);CHECKGLERROR
                for (;cls.capturevideo_frame < newframenum;cls.capturevideo_frame++)
                {
-                       sprintf(filename, "video/dp%06d.tga", cls.capturevideo_frame);
+                       sprintf(filename, "%s_%06d.tga", cls.capturevideo_basename, cls.capturevideo_frame);
                        if (!FS_WriteFile (filename, cls.capturevideo_buffer, width*height*3 + 18))
                                return false;
                }
@@ -887,12 +944,14 @@ void SCR_CaptureVideo(void)
                        Con_Printf("You can not change the video framerate while recording a video.\n");
                        Cvar_SetValueQuick(&cl_capturevideo_fps, cls.capturevideo_framerate);
                }
+#if 0
                if (cls.capturevideo_soundfile)
                {
                        // preserve sound sync by duplicating frames when running slow
                        newframenum = (int)((Sys_DoubleTime() - cls.capturevideo_starttime) * cls.capturevideo_framerate);
                }
                else
+#endif
                        newframenum = cls.capturevideo_frame + 1;
                // if falling behind more than one second, stop
                if (newframenum - cls.capturevideo_frame > (int)ceil(cls.capturevideo_framerate))
@@ -971,15 +1030,19 @@ static void R_Envmap_f (void)
                return;
        }
 
-       envmap = true;
+       r_refdef.envmap = true;
+
+       R_UpdateVariables();
 
-       r_refdef.x = 0;
-       r_refdef.y = 0;
-       r_refdef.width = size;
-       r_refdef.height = size;
+       r_view.x = 0;
+       r_view.y = 0;
+       r_view.z = 0;
+       r_view.width = size;
+       r_view.height = size;
+       r_view.depth = 1;
 
-       r_refdef.frustum_x = tan(90 * M_PI / 360.0);
-       r_refdef.frustum_y = tan(90 * M_PI / 360.0);
+       r_view.frustum_x = tan(90 * M_PI / 360.0);
+       r_view.frustum_y = tan(90 * M_PI / 360.0);
 
        buffer1 = (unsigned char *)Mem_Alloc(tempmempool, size * size * 3);
        buffer2 = (unsigned char *)Mem_Alloc(tempmempool, size * size * 3);
@@ -988,19 +1051,19 @@ static void R_Envmap_f (void)
        for (j = 0;j < 12;j++)
        {
                sprintf(filename, "env/%s%s.tga", basename, envmapinfo[j].name);
-               Matrix4x4_CreateFromQuakeEntity(&r_refdef.viewentitymatrix, r_vieworigin[0], r_vieworigin[1], r_vieworigin[2], envmapinfo[j].angles[0], envmapinfo[j].angles[1], envmapinfo[j].angles[2], 1);
+               Matrix4x4_CreateFromQuakeEntity(&r_view.matrix, r_view.origin[0], r_view.origin[1], r_view.origin[2], envmapinfo[j].angles[0], envmapinfo[j].angles[1], envmapinfo[j].angles[2], 1);
                R_ClearScreen();
                R_Mesh_Start();
                R_RenderView();
                R_Mesh_Finish();
-               SCR_ScreenShot(filename, buffer1, buffer2, buffer3, 0, vid.height - (r_refdef.y + r_refdef.height), size, size, envmapinfo[j].flipx, envmapinfo[j].flipy, envmapinfo[j].flipdiagonaly, false, false);
+               SCR_ScreenShot(filename, buffer1, buffer2, buffer3, 0, vid.height - (r_view.y + r_view.height), size, size, envmapinfo[j].flipx, envmapinfo[j].flipy, envmapinfo[j].flipdiagonaly, false, false);
        }
 
        Mem_Free (buffer1);
        Mem_Free (buffer2);
        Mem_Free (buffer3);
 
-       envmap = false;
+       r_refdef.envmap = false;
 }
 
 //=============================================================================
@@ -1102,13 +1165,13 @@ qboolean SCR_ScreenShot(char *filename, unsigned char *buffer1, unsigned char *b
        if (!r_render.integer)
                return false;
 
-       qglReadPixels (x, y, width, height, GL_RGB, GL_UNSIGNED_BYTE, buffer1);
        CHECKGLERROR
+       qglReadPixels (x, y, width, height, GL_RGB, GL_UNSIGNED_BYTE, buffer1);CHECKGLERROR
 
-       if (scr_screenshot_gamma.value != 1 && gammacorrect)
+       if (scr_screenshot_gammaboost.value != 1 && gammacorrect)
        {
                int i;
-               double igamma = 1.0 / scr_screenshot_gamma.value;
+               double igamma = 1.0 / scr_screenshot_gammaboost.value;
                unsigned char ramp[256];
                for (i = 0;i < 256;i++)
                        ramp[i] = (unsigned char) (pow(i * (1.0 / 255.0), igamma) * 255.0);
@@ -1130,33 +1193,35 @@ qboolean SCR_ScreenShot(char *filename, unsigned char *buffer1, unsigned char *b
 
 void R_ClearScreen(void)
 {
-       if (r_render.integer)
+       // clear to black
+       CHECKGLERROR
+       if (r_refdef.fogenabled)
        {
-               // clear to black
-               if (fogenabled)
-                       qglClearColor(fogcolor[0],fogcolor[1],fogcolor[2],0);
-               else
-                       qglClearColor(0,0,0,0);
-               CHECKGLERROR
-               qglClearDepth(1);CHECKGLERROR
-               if (gl_stencil)
-               {
-                       // LordHavoc: we use a stencil centered around 128 instead of 0,
-                       // to avoid clamping interfering with strange shadow volume
-                       // drawing orders
-                       qglClearStencil(128);CHECKGLERROR
-               }
-               // clear the screen
+               qglClearColor(r_refdef.fogcolor[0],r_refdef.fogcolor[1],r_refdef.fogcolor[2],0);CHECKGLERROR
+       }
+       else
+       {
+               qglClearColor(0,0,0,0);CHECKGLERROR
+       }
+       qglClearDepth(1);CHECKGLERROR
+       if (gl_stencil)
+       {
+               // LordHavoc: we use a stencil centered around 128 instead of 0,
+               // to avoid clamping interfering with strange shadow volume
+               // drawing orders
+               qglClearStencil(128);CHECKGLERROR
+       }
+       // clear the screen
+       if (r_render.integer)
                GL_Clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | (gl_stencil ? GL_STENCIL_BUFFER_BIT : 0));
-               // set dithering mode
-               if (gl_dither.integer)
-               {
-                       qglEnable(GL_DITHER);CHECKGLERROR
-               }
-               else
-               {
-                       qglDisable(GL_DITHER);CHECKGLERROR
-               }
+       // set dithering mode
+       if (gl_dither.integer)
+       {
+               qglEnable(GL_DITHER);CHECKGLERROR
+       }
+       else
+       {
+               qglDisable(GL_DITHER);CHECKGLERROR
        }
 }
 
@@ -1173,6 +1238,8 @@ void SCR_DrawScreen (void)
        if (r_timereport_active)
                R_TimeReport("setup");
 
+       R_UpdateVariables();
+
        if (cls.signon == SIGNONS)
        {
                float size;
@@ -1182,19 +1249,23 @@ void SCR_DrawScreen (void)
 
                if (r_stereo_sidebyside.integer)
                {
-                       r_refdef.width = (int)(vid.width * size / 2.5);
-                       r_refdef.height = (int)(vid.height * size / 2.5 * (1 - bound(0, r_letterbox.value, 100) / 100));
-                       r_refdef.x = (int)((vid.width - r_refdef.width * 2.5) * 0.5);
-                       r_refdef.y = (int)((vid.height - r_refdef.height)/2);
+                       r_view.width = (int)(vid.width * size / 2.5);
+                       r_view.height = (int)(vid.height * size / 2.5 * (1 - bound(0, r_letterbox.value, 100) / 100));
+                       r_view.depth = 1;
+                       r_view.x = (int)((vid.width - r_view.width * 2.5) * 0.5);
+                       r_view.y = (int)((vid.height - r_view.height)/2);
+                       r_view.z = 0;
                        if (r_stereo_side)
-                               r_refdef.x += (int)(r_refdef.width * 1.5);
+                               r_view.x += (int)(r_view.width * 1.5);
                }
                else
                {
-                       r_refdef.width = (int)(vid.width * size);
-                       r_refdef.height = (int)(vid.height * size * (1 - bound(0, r_letterbox.value, 100) / 100));
-                       r_refdef.x = (int)((vid.width - r_refdef.width)/2);
-                       r_refdef.y = (int)((vid.height - r_refdef.height)/2);
+                       r_view.width = (int)(vid.width * size);
+                       r_view.height = (int)(vid.height * size * (1 - bound(0, r_letterbox.value, 100) / 100));
+                       r_view.depth = 1;
+                       r_view.x = (int)((vid.width - r_view.width)/2);
+                       r_view.y = (int)((vid.height - r_view.height)/2);
+                       r_view.z = 0;
                }
 
                // LordHavoc: viewzoom (zoom in for sniper rifles, etc)
@@ -1203,11 +1274,11 @@ void SCR_DrawScreen (void)
                // this it simply assumes the requested fov is the vertical fov
                // for a 4x3 display, if the ratio is not 4x3 this makes the fov
                // higher/lower according to the ratio
-               r_refdef.frustum_y = tan(scr_fov.value * cl.viewzoom * M_PI / 360.0) * (3.0/4.0);
-               r_refdef.frustum_x = r_refdef.frustum_y * (float)r_refdef.width / (float)r_refdef.height / vid_pixelheight.value;
+               r_view.frustum_y = tan(scr_fov.value * cl.viewzoom * M_PI / 360.0) * (3.0/4.0);
+               r_view.frustum_x = r_view.frustum_y * (float)r_view.width / (float)r_view.height / vid_pixelheight.value;
 
-               r_refdef.frustum_x *= r_refdef.frustumscale_x;
-               r_refdef.frustum_y *= r_refdef.frustumscale_y;
+               r_view.frustum_x *= r_refdef.frustumscale_x;
+               r_view.frustum_y *= r_refdef.frustumscale_y;
 
                if(!CL_VM_UpdateView())
                        R_RenderView();
@@ -1218,16 +1289,18 @@ void SCR_DrawScreen (void)
                {
                        float sizex = bound(10, scr_zoomwindow_viewsizex.value, 100) / 100.0;
                        float sizey = bound(10, scr_zoomwindow_viewsizey.value, 100) / 100.0;
-                       r_refdef.width = (int)(vid.width * sizex);
-                       r_refdef.height = (int)(vid.height * sizey);
-                       r_refdef.x = (int)((vid.width - r_refdef.width)/2);
-                       r_refdef.y = 0;
+                       r_view.width = (int)(vid.width * sizex);
+                       r_view.height = (int)(vid.height * sizey);
+                       r_view.depth = 1;
+                       r_view.x = (int)((vid.width - r_view.width)/2);
+                       r_view.y = 0;
+                       r_view.z = 0;
 
-                       r_refdef.frustum_y = tan(scr_zoomwindow_fov.value * cl.viewzoom * M_PI / 360.0) * (3.0/4.0);
-                       r_refdef.frustum_x = r_refdef.frustum_y * vid_pixelheight.value * (float)r_refdef.width / (float)r_refdef.height;
+                       r_view.frustum_y = tan(scr_zoomwindow_fov.value * cl.viewzoom * M_PI / 360.0) * (3.0/4.0);
+                       r_view.frustum_x = r_view.frustum_y * vid_pixelheight.value * (float)r_view.width / (float)r_view.height;
 
-                       r_refdef.frustum_x *= r_refdef.frustumscale_x;
-                       r_refdef.frustum_y *= r_refdef.frustumscale_y;
+                       r_view.frustum_x *= r_refdef.frustumscale_x;
+                       r_view.frustum_y *= r_refdef.frustumscale_y;
 
                        if(!CL_VM_UpdateView())
                                R_RenderView();
@@ -1236,10 +1309,12 @@ void SCR_DrawScreen (void)
 
        if (!r_stereo_sidebyside.integer)
        {
-               r_refdef.width = vid.width;
-               r_refdef.height = vid.height;
-               r_refdef.x = 0;
-               r_refdef.y = 0;
+               r_view.width = vid.width;
+               r_view.height = vid.height;
+               r_view.depth = 1;
+               r_view.x = 0;
+               r_view.y = 0;
+               r_view.z = 0;
        }
 
        // draw 2D stuff
@@ -1294,14 +1369,15 @@ void SCR_UpdateLoadingScreen (void)
        // don't do anything if not initialized yet
        if (vid_hidden)
                return;
-       qglViewport(0, 0, vid.width, vid.height);
-       //qglDisable(GL_SCISSOR_TEST);
-       //qglDepthMask(1);
-       qglColorMask(1,1,1,1);
-       //qglClearColor(0,0,0,0);
-       //qglClear(GL_COLOR_BUFFER_BIT);
-       //qglCullFace(GL_FRONT);
-       //qglDisable(GL_CULL_FACE);
+       CHECKGLERROR
+       qglViewport(0, 0, vid.width, vid.height);CHECKGLERROR
+       //qglDisable(GL_SCISSOR_TEST);CHECKGLERROR
+       //qglDepthMask(1);CHECKGLERROR
+       qglColorMask(1,1,1,1);CHECKGLERROR
+       //qglClearColor(0,0,0,0);CHECKGLERROR
+       //qglClear(GL_COLOR_BUFFER_BIT);CHECKGLERROR
+       //qglCullFace(GL_FRONT);CHECKGLERROR
+       //qglDisable(GL_CULL_FACE);CHECKGLERROR
        //R_ClearScreen();
        R_Textures_Frame();
        GL_SetupView_Mode_Ortho(0, 0, vid_conwidth.integer, vid_conheight.integer, -10, 100);
@@ -1395,9 +1471,9 @@ void CL_UpdateScreen(void)
                        sb_lines = 24+16+8;
        }
 
-       r_refdef.colormask[0] = 1;
-       r_refdef.colormask[1] = 1;
-       r_refdef.colormask[2] = 1;
+       r_view.colormask[0] = 1;
+       r_view.colormask[1] = 1;
+       r_view.colormask[2] = 1;
 
        if (r_timereport_active)
                R_TimeReport("other");
@@ -1408,53 +1484,52 @@ void CL_UpdateScreen(void)
                R_TimeReport("start");
 
        CHECKGLERROR
-       qglViewport(0, 0, vid.width, vid.height);
-       qglDisable(GL_SCISSOR_TEST);
-       qglDepthMask(1);
-       qglColorMask(1,1,1,1);
-       qglClearColor(0,0,0,0);
-       qglClear(GL_COLOR_BUFFER_BIT);
-       CHECKGLERROR
+       qglViewport(0, 0, vid.width, vid.height);CHECKGLERROR
+       qglDisable(GL_SCISSOR_TEST);CHECKGLERROR
+       qglDepthMask(1);CHECKGLERROR
+       qglColorMask(1,1,1,1);CHECKGLERROR
+       qglClearColor(0,0,0,0);CHECKGLERROR
+       qglClear(GL_COLOR_BUFFER_BIT);CHECKGLERROR
 
        if (r_timereport_active)
                R_TimeReport("clear");
 
        if (r_stereo_redblue.integer || r_stereo_redgreen.integer || r_stereo_redcyan.integer || r_stereo_sidebyside.integer)
        {
-               matrix4x4_t originalmatrix = r_refdef.viewentitymatrix;
-               r_refdef.viewentitymatrix.m[0][3] = originalmatrix.m[0][3] + r_stereo_separation.value * -0.5f * r_refdef.viewentitymatrix.m[0][1];
-               r_refdef.viewentitymatrix.m[1][3] = originalmatrix.m[1][3] + r_stereo_separation.value * -0.5f * r_refdef.viewentitymatrix.m[1][1];
-               r_refdef.viewentitymatrix.m[2][3] = originalmatrix.m[2][3] + r_stereo_separation.value * -0.5f * r_refdef.viewentitymatrix.m[2][1];
+               matrix4x4_t originalmatrix = r_view.matrix;
+               r_view.matrix.m[0][3] = originalmatrix.m[0][3] + r_stereo_separation.value * -0.5f * r_view.matrix.m[0][1];
+               r_view.matrix.m[1][3] = originalmatrix.m[1][3] + r_stereo_separation.value * -0.5f * r_view.matrix.m[1][1];
+               r_view.matrix.m[2][3] = originalmatrix.m[2][3] + r_stereo_separation.value * -0.5f * r_view.matrix.m[2][1];
 
                if (r_stereo_sidebyside.integer)
                        r_stereo_side = 0;
 
                if (r_stereo_redblue.integer || r_stereo_redgreen.integer || r_stereo_redcyan.integer)
                {
-                       r_refdef.colormask[0] = 1;
-                       r_refdef.colormask[1] = 0;
-                       r_refdef.colormask[2] = 0;
+                       r_view.colormask[0] = 1;
+                       r_view.colormask[1] = 0;
+                       r_view.colormask[2] = 0;
                }
 
                SCR_DrawScreen();
 
-               r_refdef.viewentitymatrix.m[0][3] = originalmatrix.m[0][3] + r_stereo_separation.value * 0.5f * r_refdef.viewentitymatrix.m[0][1];
-               r_refdef.viewentitymatrix.m[1][3] = originalmatrix.m[1][3] + r_stereo_separation.value * 0.5f * r_refdef.viewentitymatrix.m[1][1];
-               r_refdef.viewentitymatrix.m[2][3] = originalmatrix.m[2][3] + r_stereo_separation.value * 0.5f * r_refdef.viewentitymatrix.m[2][1];
+               r_view.matrix.m[0][3] = originalmatrix.m[0][3] + r_stereo_separation.value * 0.5f * r_view.matrix.m[0][1];
+               r_view.matrix.m[1][3] = originalmatrix.m[1][3] + r_stereo_separation.value * 0.5f * r_view.matrix.m[1][1];
+               r_view.matrix.m[2][3] = originalmatrix.m[2][3] + r_stereo_separation.value * 0.5f * r_view.matrix.m[2][1];
 
                if (r_stereo_sidebyside.integer)
                        r_stereo_side = 1;
 
                if (r_stereo_redblue.integer || r_stereo_redgreen.integer || r_stereo_redcyan.integer)
                {
-                       r_refdef.colormask[0] = 0;
-                       r_refdef.colormask[1] = r_stereo_redcyan.integer || r_stereo_redgreen.integer;
-                       r_refdef.colormask[2] = r_stereo_redcyan.integer || r_stereo_redblue.integer;
+                       r_view.colormask[0] = 0;
+                       r_view.colormask[1] = r_stereo_redcyan.integer || r_stereo_redgreen.integer;
+                       r_view.colormask[2] = r_stereo_redcyan.integer || r_stereo_redblue.integer;
                }
 
                SCR_DrawScreen();
 
-               r_refdef.viewentitymatrix = originalmatrix;
+               r_view.matrix = originalmatrix;
        }
        else
                SCR_DrawScreen();