]> git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - cl_screen.c
fix bugs with CSQC clearscene function - it now restores the view to
[xonotic/darkplaces.git] / cl_screen.c
index bedbc92f8805294de05e79fe4dcc6e976a39156a..7485a11bbb6edd0f0ac5e6afffd72931dbcf9af2 100644 (file)
@@ -51,6 +51,7 @@ cvar_t scr_screenshot_png = {CVAR_SAVE, "scr_screenshot_png","0", "save png inst
 cvar_t scr_screenshot_gammaboost = {CVAR_SAVE, "scr_screenshot_gammaboost","1", "gamma correction on saved screenshots and videos, 1.0 saves unmodified images"};
 cvar_t scr_screenshot_hwgamma = {CVAR_SAVE, "scr_screenshot_hwgamma","1", "apply the video gamma ramp to saved screenshots and videos"};
 cvar_t scr_screenshot_alpha = {CVAR_SAVE, "scr_screenshot_alpha","0", "try to write an alpha channel to screenshots (debugging feature)"};
+cvar_t scr_screenshot_timestamp = {CVAR_SAVE, "scr_screenshot_timestamp", "1", "use a timestamp based number of the type YYYYMMDDHHMMSSsss instead of sequential numbering"};
 // scr_screenshot_name is defined in fs.c
 cvar_t cl_capturevideo = {0, "cl_capturevideo", "0", "enables saving of video to a .avi file using uncompressed I420 colorspace and PCM audio, note that scr_screenshot_gammaboost affects the brightness of the output)"};
 cvar_t cl_capturevideo_printfps = {CVAR_SAVE, "cl_capturevideo_printfps", "1", "prints the frames per second captured in capturevideo (is only written to the log file, not to the console, as that would be visible on the video)"};
@@ -613,9 +614,9 @@ static int SCR_InfobarHeight(void)
        if (cl.time > cl.oldtime)
                scr_infobartime_off -= cl.time - cl.oldtime;
        if(scr_infobartime_off > 0)
-               offset += 8;
+               offset += 1;
        if(cls.qw_downloadname[0])
-               offset += 8;
+               offset += 1;
 
        downinfo = Curl_GetDownloadInfo(&nDownloads, &addinfo);
        if(downinfo)
@@ -735,8 +736,8 @@ void R_TimeReport(const char *desc)
                return;
 
        CHECKGLERROR
-       if (r_speeds.integer == 2 && qglFinish)
-               qglFinish();
+       if (r_speeds.integer == 2)
+               GL_Finish();
        CHECKGLERROR
        r_timereport_temp = r_timereport_current;
        r_timereport_current = Sys_DoubleTime();
@@ -766,7 +767,7 @@ void R_TimeReport_BeginFrame(void)
        r_timereport_active = false;
        memset(&r_refdef.stats, 0, sizeof(r_refdef.stats));
 
-       if (r_speeds.integer >= 2 && cls.signon == SIGNONS && cls.state == ca_connected)
+       if (r_speeds.integer >= 2)
        {
                r_timereport_active = true;
                r_timereport_start = r_timereport_current = Sys_DoubleTime();
@@ -791,16 +792,16 @@ void R_TimeReport_EndFrame(void)
        mleaf_t *viewleaf;
 
        string[0] = 0;
-       if (r_speeds.integer && cls.signon == SIGNONS && cls.state == ca_connected)
+       if (r_speeds.integer)
        {
                // put the location name in the r_speeds display as it greatly helps
                // when creating loc files
                loc = CL_Locs_FindNearest(cl.movement_origin);
                viewleaf = (r_refdef.scene.worldmodel && r_refdef.scene.worldmodel->brush.PointInLeaf) ? r_refdef.scene.worldmodel->brush.PointInLeaf(r_refdef.scene.worldmodel, r_refdef.view.origin) : NULL;
                dpsnprintf(string, sizeof(string),
-"%6.0fus rendertime %3.0f%% viewscale %s%s\n"
+"%6.0fus rendertime %3.0f%% viewscale %s%s %.3f cl.time%2.4f brightness\n"
 "%3i renders org:'%+8.2f %+8.2f %+8.2f' dir:'%+2.3f %+2.3f %+2.3f'\n"
-"%5i viewleaf%5i cluster%2i area%4i brushes%4i surfaces(%7i triangles)\n"
+"%5i viewleaf%5i cluster%3i area%4i brushes%4i surfaces(%7i triangles)\n"
 "%7i surfaces%7i triangles %5i entities (%7i surfaces%7i triangles)\n"
 "%5i leafs%5i portals%6i/%6i particles%6i/%6i decals %3i%% quality\n"
 "%7i lightmap updates (%7i pixels)%8iKB/%8iKB framedata\n"
@@ -810,7 +811,7 @@ void R_TimeReport_EndFrame(void)
 "%6i draws%8i vertices%8i triangles bloompixels%8i copied%8i drawn\n"
 "updated%5i indexbuffers%8i bytes%5i vertexbuffers%8i bytes\n"
 "%s"
-, r_refdef.lastdrawscreentime * 1000000.0, r_viewscale.value * sqrt(viewscalefpsadjusted) * 100.0f, loc ? "Location: " : "", loc ? loc->name : ""
+, r_refdef.lastdrawscreentime * 1000000.0, r_viewscale.value * sqrt(viewscalefpsadjusted) * 100.0f, loc ? "Location: " : "", loc ? loc->name : "", cl.time, r_refdef.view.colorscale
 , r_refdef.stats.renders, r_refdef.view.origin[0], r_refdef.view.origin[1], r_refdef.view.origin[2], r_refdef.view.forward[0], r_refdef.view.forward[1], r_refdef.view.forward[2]
 , viewleaf ? (int)(viewleaf - r_refdef.scene.worldmodel->brush.data_leafs) : -1, viewleaf ? viewleaf->clusterindex : -1, viewleaf ? viewleaf->areaindex : -1, viewleaf ? viewleaf->numleafbrushes : 0, viewleaf ? viewleaf->numleafsurfaces : 0, viewleaf ? R_CountLeafTriangles(r_refdef.scene.worldmodel, viewleaf) : 0
 , r_refdef.stats.world_surfaces, r_refdef.stats.world_triangles, r_refdef.stats.entities, r_refdef.stats.entities_surfaces, r_refdef.stats.entities_triangles
@@ -935,6 +936,7 @@ void CL_Screen_Init(void)
        Cvar_RegisterVariable (&scr_screenshot_hwgamma);
        Cvar_RegisterVariable (&scr_screenshot_name_in_mapdir);
        Cvar_RegisterVariable (&scr_screenshot_alpha);
+       Cvar_RegisterVariable (&scr_screenshot_timestamp);
        Cvar_RegisterVariable (&cl_capturevideo);
        Cvar_RegisterVariable (&cl_capturevideo_printfps);
        Cvar_RegisterVariable (&cl_capturevideo_width);
@@ -966,6 +968,10 @@ void CL_Screen_Init(void)
        Cvar_RegisterVariable(&vid_touchscreen_outlinealpha);
        Cvar_RegisterVariable(&vid_touchscreen_overlayalpha);
 
+       // if we want no console, turn it off here too
+       if (COM_CheckParm ("-noconsole"))
+               Cvar_SetQuick(&scr_conforcewhiledisconnected, "0");
+
        Cmd_AddCommand ("sizeup",SCR_SizeUp_f, "increase view size (increases viewsize cvar)");
        Cmd_AddCommand ("sizedown",SCR_SizeDown_f, "decrease view size (decreases viewsize cvar)");
        Cmd_AddCommand ("screenshot",SCR_ScreenShot_f, "takes a screenshot of the next rendered frame");
@@ -1019,14 +1025,41 @@ void SCR_ScreenShot_f (void)
                        return;
                }
        }
+       else if (scr_screenshot_timestamp.integer)
+       {
+               int shotnumber100;
+
+               // TODO maybe make capturevideo and screenshot use similar name patterns?
+               if (scr_screenshot_name_in_mapdir.integer && cl.worldbasename[0])
+                       dpsnprintf(prefix_name, sizeof(prefix_name), "%s/%s%s", cl.worldbasename, scr_screenshot_name.string, Sys_TimeString("%Y%m%d%H%M%S"));
+               else
+                       dpsnprintf(prefix_name, sizeof(prefix_name), "%s%s", scr_screenshot_name.string, Sys_TimeString("%Y%m%d%H%M%S"));
+
+               // find a file name to save it to
+               for (shotnumber100 = 0;shotnumber100 < 100;shotnumber100++)
+                       if (!FS_SysFileExists(va("%s/screenshots/%s-%02d.tga", fs_gamedir, prefix_name, shotnumber100))
+                        && !FS_SysFileExists(va("%s/screenshots/%s-%02d.jpg", fs_gamedir, prefix_name, shotnumber100))
+                        && !FS_SysFileExists(va("%s/screenshots/%s-%02d.png", fs_gamedir, prefix_name, shotnumber100)))
+                               break;
+               if (shotnumber100 >= 100)
+               {
+                       Con_Print("Couldn't create the image file - already 100 shots taken this second!\n");
+                       return;
+               }
+
+               dpsnprintf(filename, sizeof(filename), "screenshots/%s-%02d.%s", prefix_name, shotnumber100, jpeg ? "jpg" : png ? "png" : "tga");
+       }
        else
        {
                // TODO maybe make capturevideo and screenshot use similar name patterns?
                if (scr_screenshot_name_in_mapdir.integer && cl.worldbasename[0])
-                       dpsnprintf (prefix_name, sizeof(prefix_name), "%s/%s", cl.worldbasename, Sys_TimeString(scr_screenshot_name.string));
+                       dpsnprintf(prefix_name, sizeof(prefix_name), "%s/%s", cl.worldbasename, Sys_TimeString(scr_screenshot_name.string));
                else
-                       dpsnprintf (prefix_name, sizeof(prefix_name), "%s", Sys_TimeString(scr_screenshot_name.string));
+                       dpsnprintf(prefix_name, sizeof(prefix_name), "%s", Sys_TimeString(scr_screenshot_name.string));
 
+               // if prefix changed, gamedir or map changed, reset the shotnumber so
+               // we scan again
+               // FIXME: should probably do this whenever FS_Rescan or something like that occurs?
                if (strcmp(old_prefix_name, prefix_name))
                {
                        dpsnprintf(old_prefix_name, sizeof(old_prefix_name), "%s", prefix_name );
@@ -1035,15 +1068,19 @@ void SCR_ScreenShot_f (void)
 
                // find a file name to save it to
                for (;shotnumber < 1000000;shotnumber++)
-                       if (!FS_SysFileExists(va("%s/screenshots/%s%06d.tga", fs_gamedir, prefix_name, shotnumber)) && !FS_SysFileExists(va("%s/screenshots/%s%06d.jpg", fs_gamedir, prefix_name, shotnumber)) && !FS_SysFileExists(va("%s/screenshots/%s%06d.png", fs_gamedir, prefix_name, shotnumber)))
+                       if (!FS_SysFileExists(va("%s/screenshots/%s%06d.tga", fs_gamedir, prefix_name, shotnumber))
+                        && !FS_SysFileExists(va("%s/screenshots/%s%06d.jpg", fs_gamedir, prefix_name, shotnumber))
+                        && !FS_SysFileExists(va("%s/screenshots/%s%06d.png", fs_gamedir, prefix_name, shotnumber)))
                                break;
                if (shotnumber >= 1000000)
                {
-                       Con_Print("Couldn't create the image file\n");
+                       Con_Print("Couldn't create the image file - you already have 1000000 screenshots!\n");
                        return;
                }
 
                dpsnprintf(filename, sizeof(filename), "screenshots/%s%06d.%s", prefix_name, shotnumber, jpeg ? "jpg" : png ? "png" : "tga");
+
+               shotnumber++;
        }
 
        buffer1 = (unsigned char *)Mem_Alloc(tempmempool, vid.width * vid.height * 4);
@@ -1066,8 +1103,6 @@ void SCR_ScreenShot_f (void)
 
        Mem_Free (buffer1);
        Mem_Free (buffer2);
-
-       shotnumber++;
 }
 
 void SCR_CaptureVideo_BeginVideo(void)
@@ -1418,6 +1453,8 @@ static void R_Envmap_f (void)
 
        r_refdef.view.frustum_x = 1; // tan(45 * M_PI / 180.0);
        r_refdef.view.frustum_y = 1; // tan(45 * M_PI / 180.0);
+       r_refdef.view.ortho_x = 90; // abused as angle by VM_CL_R_SetView
+       r_refdef.view.ortho_y = 90; // abused as angle by VM_CL_R_SetView
 
        buffer1 = (unsigned char *)Mem_Alloc(tempmempool, size * size * 4);
        buffer2 = (unsigned char *)Mem_Alloc(tempmempool, size * size * 3);
@@ -1608,17 +1645,16 @@ static void SCR_DrawTouchscreenOverlay(void)
        }
 }
 
-extern void R_UpdateFogColor(void);
+extern void R_UpdateFog(void);
 void R_ClearScreen(qboolean fogcolor)
 {
        float clearcolor[4];
        // clear to black
        Vector4Clear(clearcolor);
-       if (fogcolor)
+       if (fogcolor && r_fog_clear.integer)
        {
-               R_UpdateFogColor();
-               if (r_fog_clear.integer)
-                       VectorCopy(r_refdef.fogcolor, clearcolor);
+               R_UpdateFog();
+               VectorCopy(r_refdef.fogcolor, clearcolor);
        }
        // clear depth is 1.0
        // LordHavoc: we use a stencil centered around 128 instead of 0,
@@ -1709,6 +1745,8 @@ void SCR_DrawScreen (void)
 
                r_refdef.view.frustum_x *= r_refdef.frustumscale_x;
                r_refdef.view.frustum_y *= r_refdef.frustumscale_y;
+               r_refdef.view.ortho_x = atan(r_refdef.view.frustum_x) * (360.0 / M_PI); // abused as angle by VM_CL_R_SetView
+               r_refdef.view.ortho_y = atan(r_refdef.view.frustum_y) * (360.0 / M_PI); // abused as angle by VM_CL_R_SetView
 
                if(!CL_VM_UpdateView())
                        R_RenderView();
@@ -1731,6 +1769,9 @@ void SCR_DrawScreen (void)
                        r_refdef.view.frustum_x *= r_refdef.frustumscale_x;
                        r_refdef.view.frustum_y *= r_refdef.frustumscale_y;
 
+                       r_refdef.view.ortho_x = atan(r_refdef.view.frustum_x) * (360.0 / M_PI); // abused as angle by VM_CL_R_SetView
+                       r_refdef.view.ortho_y = atan(r_refdef.view.frustum_y) * (360.0 / M_PI); // abused as angle by VM_CL_R_SetView
+
                        if(!CL_VM_UpdateView())
                                R_RenderView();
                }
@@ -1791,7 +1832,6 @@ void SCR_DrawScreen (void)
                SCR_DrawPause ();
                if (!r_letterbox.value)
                        Sbar_Draw();
-               Sbar_ShowFPS();
                SHOWLMP_drawall();
                SCR_CheckDrawCenterString();
        }
@@ -1811,11 +1851,9 @@ void SCR_DrawScreen (void)
        if (r_timereport_active)
                R_TimeReport("2d");
 
-       if (cls.signon == SIGNONS)
-       {
-               R_TimeReport_EndFrame();
-               R_TimeReport_BeginFrame();
-       }
+       R_TimeReport_EndFrame();
+       R_TimeReport_BeginFrame();
+       Sbar_ShowFPS();
 
        DrawQ_Finish();
 
@@ -2009,7 +2047,7 @@ static void SCR_DrawLoadingStack(void)
                sscanf(scr_loadingscreen_barcolor.string, "%f %f %f", &colors[12], &colors[13], &colors[14]);  colors[15] = 1;
 
                R_Mesh_PrepareVertices_Generic_Arrays(4, verts, colors, NULL);
-               R_SetupShader_Generic(NULL, NULL, GL_MODULATE, 1);
+               R_SetupShader_Generic(NULL, NULL, GL_MODULATE, 1, true, true);
                R_Mesh_Draw(0, 4, 0, 2, polygonelement3i, NULL, 0, polygonelement3s, NULL, 0);
 
                // make sure everything is cleared, including the progress indicator
@@ -2042,7 +2080,7 @@ static void SCR_DrawLoadingScreen_SharedSetup (qboolean clear)
        R_Mesh_Start();
        R_EntityMatrix(&identitymatrix);
        // draw the loading plaque
-       loadingscreenpic = Draw_CachePic (loadingscreenpic_number ? va("gfx/loading%d", loadingscreenpic_number+1) : "gfx/loading");
+       loadingscreenpic = Draw_CachePic_Flags (loadingscreenpic_number ? va("gfx/loading%d", loadingscreenpic_number+1) : "gfx/loading", loadingscreenpic_number ? CACHEPICFLAG_NOTPERSISTENT : 0);
 
        w = loadingscreenpic->width;
        h = loadingscreenpic->height;
@@ -2108,11 +2146,11 @@ static void SCR_DrawLoadingScreen (qboolean clear)
        if(loadingscreentexture)
        {
                R_Mesh_PrepareVertices_Generic_Arrays(4, loadingscreentexture_vertex3f, NULL, loadingscreentexture_texcoord2f);
-               R_SetupShader_Generic(loadingscreentexture, NULL, GL_MODULATE, 1);
+               R_SetupShader_Generic(loadingscreentexture, NULL, GL_MODULATE, 1, true, true);
                R_Mesh_Draw(0, 4, 0, 2, polygonelement3i, NULL, 0, polygonelement3s, NULL, 0);
        }
        R_Mesh_PrepareVertices_Generic_Arrays(4, loadingscreenpic_vertex3f, NULL, loadingscreenpic_texcoord2f);
-       R_SetupShader_Generic(loadingscreenpic->tex, NULL, GL_MODULATE, 1);
+       R_SetupShader_Generic(Draw_GetPicTexture(loadingscreenpic), NULL, GL_MODULATE, 1, true, true);
        R_Mesh_Draw(0, 4, 0, 2, polygonelement3i, NULL, 0, polygonelement3s, NULL, 0);
        SCR_DrawLoadingStack();
 }
@@ -2154,6 +2192,10 @@ void SCR_UpdateLoadingScreen (qboolean clear)
        }
        loadingscreencleared = clear;
 
+#ifdef USE_GLES2
+       SCR_DrawLoadingScreen_SharedSetup(clear);
+       SCR_DrawLoadingScreen(clear);
+#else
        if (qglDrawBuffer)
                qglDrawBuffer(GL_BACK);
        SCR_DrawLoadingScreen_SharedSetup(clear);
@@ -2170,6 +2212,7 @@ void SCR_UpdateLoadingScreen (qboolean clear)
                        qglDrawBuffer(GL_BACK);
                SCR_DrawLoadingScreen(clear);
        }
+#endif
        SCR_DrawLoadingScreen_SharedFinish(clear);
 
        // this goes into the event loop, and should prevent unresponsive cursor on vista
@@ -2280,6 +2323,7 @@ void CL_UpdateScreen(void)
 
        SCR_SetUpToDrawConsole();
 
+#ifndef USE_GLES2
        if (qglDrawBuffer)
        {
                CHECKGLERROR
@@ -2294,6 +2338,7 @@ void CL_UpdateScreen(void)
                        qglDisable(GL_DITHER);CHECKGLERROR
                }
        }
+#endif
 
        R_Viewport_InitOrtho(&viewport, &identitymatrix, 0, 0, vid.width, vid.height, 0, 0, vid_conwidth.integer, vid_conheight.integer, -10, 100, NULL);
        R_Mesh_ResetRenderTargets();
@@ -2308,6 +2353,7 @@ void CL_UpdateScreen(void)
        f = pow((float)cl_updatescreen_quality, cl_minfps_qualitypower.value) * cl_minfps_qualityscale.value;
        r_refdef.view.quality = bound(cl_minfps_qualitymin.value, f, cl_minfps_qualitymax.value);
 
+#ifndef USE_GLES2
        if (qglPolygonStipple)
        {
                if(scr_stipple.integer)
@@ -2334,10 +2380,12 @@ void CL_UpdateScreen(void)
                        qglDisable(GL_POLYGON_STIPPLE);CHECKGLERROR
                }
        }
+#endif
 
-       if (r_viewscale_fpsscaling.integer && qglFinish)
-               qglFinish();
+       if (r_viewscale_fpsscaling.integer)
+               GL_Finish();
        drawscreenstart = Sys_DoubleTime();
+#ifndef USE_GLES2
        if (R_Stereo_Active())
        {
                r_stereo_side = 0;
@@ -2369,9 +2417,10 @@ void CL_UpdateScreen(void)
                SCR_DrawScreen();
        }
        else
+#endif
                SCR_DrawScreen();
-       if (r_viewscale_fpsscaling.integer && qglFinish)
-               qglFinish();
+       if (r_viewscale_fpsscaling.integer)
+               GL_Finish();
        r_refdef.lastdrawscreentime = Sys_DoubleTime() - drawscreenstart;
 
        SCR_CaptureVideo();