]> git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - cl_screen.c
added GAME_QUOTH to use the hipnotic hud and workarounds with the quoth
[xonotic/darkplaces.git] / cl_screen.c
index a9a088c5b22e163fe9b792ccb0817ba5a7bbaa7f..dfc556187ece9948d970244709d5f7f938e2275f 100644 (file)
@@ -38,9 +38,12 @@ cvar_t scr_loadingscreen_background = {0, "scr_loadingscreen_background","0", "s
 cvar_t scr_loadingscreen_scale = {0, "scr_loadingscreen_scale","1", "scale factor of the background"};
 cvar_t scr_loadingscreen_scale_base = {0, "scr_loadingscreen_scale_base","0", "0 = console pixels, 1 = video pixels"};
 cvar_t scr_loadingscreen_scale_limit = {0, "scr_loadingscreen_scale_limit","0", "0 = no limit, 1 = until first edge hits screen edge, 2 = until last edge hits screen edge, 3 = until width hits screen width, 4 = until height hits screen height"};
+cvar_t scr_loadingscreen_picture = {CVAR_SAVE, "scr_loadingscreen_picture", "gfx/loading", "picture shown during loading"};
 cvar_t scr_loadingscreen_count = {0, "scr_loadingscreen_count","1", "number of loading screen files to use randomly (named loading.tga, loading2.tga, loading3.tga, ...)"};
+cvar_t scr_loadingscreen_firstforstartup = {0, "scr_loadingscreen_firstforstartup","0", "remove loading.tga from random scr_loadingscreen_count selection and only display it on client startup, 0 = normal, 1 = firstforstartup"};
 cvar_t scr_loadingscreen_barcolor = {0, "scr_loadingscreen_barcolor", "0 0 1", "rgb color of loadingscreen progress bar"};
 cvar_t scr_loadingscreen_barheight = {0, "scr_loadingscreen_barheight", "8", "the height of the loadingscreen progress bar"};
+cvar_t scr_loadingscreen_maxfps = {0, "scr_loadingscreen_maxfps", "10", "restrict maximal FPS for loading screen so it will not update very often (this will make lesser loading times on a maps loading large number of models)"};
 cvar_t scr_infobar_height = {0, "scr_infobar_height", "8", "the height of the infobar items"};
 cvar_t vid_conwidth = {CVAR_SAVE, "vid_conwidth", "640", "virtual width of 2D graphics system"};
 cvar_t vid_conheight = {CVAR_SAVE, "vid_conheight", "480", "virtual height of 2D graphics system"};
@@ -235,9 +238,6 @@ static void SCR_DrawNetGraph_DrawGraph (int graphx, int graphy, int graphwidth,
        float *c;
        DrawQ_Fill(graphx, graphy, graphwidth, graphheight + textsize * 2, 0, 0, 0, 0.5, 0);
        // draw the bar graph itself
-       // advance the packet counter because it is the latest packet column being
-       // built up and should come last
-       packetcounter = (packetcounter + 1) % NETGRAPH_PACKETS;
        memset(g, 0, sizeof(g));
        for (j = 0;j < NETGRAPH_PACKETS;j++)
        {
@@ -709,13 +709,13 @@ SCR_BeginLoadingPlaque
 
 ================
 */
-void SCR_BeginLoadingPlaque (void)
+void SCR_BeginLoadingPlaque (qboolean startup)
 {
        // save console log up to this point to log_file if it was set by configs
        Log_Start();
 
        Host_StartVideo();
-       SCR_UpdateLoadingScreen(false);
+       SCR_UpdateLoadingScreen(false, startup);
 }
 
 //=============================================================================
@@ -915,9 +915,12 @@ void CL_Screen_Init(void)
        Cvar_RegisterVariable (&scr_loadingscreen_scale);
        Cvar_RegisterVariable (&scr_loadingscreen_scale_base);
        Cvar_RegisterVariable (&scr_loadingscreen_scale_limit);
+       Cvar_RegisterVariable (&scr_loadingscreen_picture);
        Cvar_RegisterVariable (&scr_loadingscreen_count);
+       Cvar_RegisterVariable (&scr_loadingscreen_firstforstartup);
        Cvar_RegisterVariable (&scr_loadingscreen_barcolor);
        Cvar_RegisterVariable (&scr_loadingscreen_barheight);
+       Cvar_RegisterVariable (&scr_loadingscreen_maxfps);
        Cvar_RegisterVariable (&scr_infobar_height);
        Cvar_RegisterVariable (&scr_showram);
        Cvar_RegisterVariable (&scr_showturtle);
@@ -1890,7 +1893,7 @@ static void SCR_SetLoadingScreenTexture(void)
 void SCR_UpdateLoadingScreenIfShown(void)
 {
        if(loadingscreendone)
-               SCR_UpdateLoadingScreen(loadingscreencleared);
+               SCR_UpdateLoadingScreen(loadingscreencleared, false);
 }
 
 void SCR_PushLoadingScreen (qboolean redraw, const char *msg, float len_in_parent)
@@ -2046,7 +2049,7 @@ static void SCR_DrawLoadingScreen_SharedSetup (qboolean clear)
        R_Mesh_Start();
        R_EntityMatrix(&identitymatrix);
        // draw the loading plaque
-       loadingscreenpic = Draw_CachePic_Flags (loadingscreenpic_number ? va(vabuf, sizeof(vabuf), "gfx/loading%d", loadingscreenpic_number+1) : "gfx/loading", loadingscreenpic_number ? CACHEPICFLAG_NOTPERSISTENT : 0);
+       loadingscreenpic = Draw_CachePic_Flags (loadingscreenpic_number ? va(vabuf, sizeof(vabuf), "%s%d", scr_loadingscreen_picture.string, loadingscreenpic_number+1) : scr_loadingscreen_picture.string, loadingscreenpic_number ? CACHEPICFLAG_NOTPERSISTENT : 0);
 
        w = loadingscreenpic->width;
        h = loadingscreenpic->height;
@@ -2128,7 +2131,9 @@ static void SCR_DrawLoadingScreen_SharedFinish (qboolean clear)
        VID_Finish();
 }
 
-void SCR_UpdateLoadingScreen (qboolean clear)
+static double loadingscreen_lastupdate;
+
+void SCR_UpdateLoadingScreen (qboolean clear, qboolean startup)
 {
        keydest_t       old_key_dest;
        int                     old_key_consoleactive;
@@ -2137,6 +2142,15 @@ void SCR_UpdateLoadingScreen (qboolean clear)
        if (vid_hidden || cls.state == ca_dedicated)
                return;
 
+       // limit update rate
+       if (scr_loadingscreen_maxfps.value)
+       {
+               double t = Sys_DirtyTime();
+               if ((t - loadingscreen_lastupdate) < 1.0f/scr_loadingscreen_maxfps.value)
+                       return;
+               loadingscreen_lastupdate = t;
+       }
+
        if(!scr_loadingscreen_background.integer)
                clear = true;
        
@@ -2144,7 +2158,17 @@ void SCR_UpdateLoadingScreen (qboolean clear)
                clear |= loadingscreencleared;
 
        if(!loadingscreendone)
-               loadingscreenpic_number = rand() % (scr_loadingscreen_count.integer > 1 ? scr_loadingscreen_count.integer : 1);
+       {
+               if(startup && scr_loadingscreen_firstforstartup.integer)
+                       loadingscreenpic_number = 0;
+               else if(scr_loadingscreen_firstforstartup.integer)
+                       if(scr_loadingscreen_count.integer > 1)
+                               loadingscreenpic_number = rand() % (scr_loadingscreen_count.integer - 1) + 1;
+                       else
+                               loadingscreenpic_number = 0;
+               else
+                       loadingscreenpic_number = rand() % (scr_loadingscreen_count.integer > 1 ? scr_loadingscreen_count.integer : 1);
+       }
 
        if(clear)
                SCR_ClearLoadingScreenTexture();
@@ -2208,6 +2232,7 @@ extern cvar_t cl_minfps_qualitymin;
 extern cvar_t cl_minfps_qualitymultiply;
 extern cvar_t cl_minfps_qualityhysteresis;
 extern cvar_t cl_minfps_qualitystepmax;
+extern cvar_t cl_minfps_force;
 static double cl_updatescreen_quality = 1;
 void CL_UpdateScreen(void)
 {
@@ -2220,7 +2245,7 @@ void CL_UpdateScreen(void)
        if(drawscreenstart)
        {
                drawscreendelta = Sys_DirtyTime() - drawscreenstart;
-               if (cl_minfps.value > 0 && !cls.timedemo && (!cls.capturevideo.active || cls.capturevideo.realtime) && drawscreendelta >= 0 && drawscreendelta < 60)
+               if (cl_minfps.value > 0 && (cl_minfps_force.integer || !(cls.timedemo || (cls.capturevideo.active && !cls.capturevideo.realtime))) && drawscreendelta >= 0 && drawscreendelta < 60)
                {
                        // quality adjustment according to render time
                        double actualframetime;
@@ -2228,49 +2253,54 @@ void CL_UpdateScreen(void)
                        double adjust;
                        double f;
                        double h;
+
+                       // fade lastdrawscreentime
                        r_refdef.lastdrawscreentime += (drawscreendelta - r_refdef.lastdrawscreentime) * cl_minfps_fade.value;
+
+                       // find actual and target frame times
                        actualframetime = r_refdef.lastdrawscreentime;
                        targetframetime = (1.0 / cl_minfps.value);
 
-                       // assume render time scales linearily / cl_minfps_qualitymultiply.value with quality...
-                       f = cl_updatescreen_quality / actualframetime * cl_minfps_qualitymultiply.value;
                        // we scale hysteresis by quality
                        h = cl_updatescreen_quality * cl_minfps_qualityhysteresis.value;
 
-                       targetframetime -= h / f; // this makes sure resulting fps is > minfps despite hysteresis
-
+                       // calculate adjustment assuming linearity
+                       f = cl_updatescreen_quality / actualframetime * cl_minfps_qualitymultiply.value;
                        adjust = (targetframetime - actualframetime) * f;
-                       if(adjust > h)
-                               adjust -= h;
-                       else if(adjust > -h)
-                               adjust = 0;
-                       else
-                               adjust += h;
+
+                       // one sided hysteresis
+                       if(adjust > 0)
+                               adjust = max(0, adjust - h);
 
                        // adjust > 0 if:
                        //   (targetframetime - actualframetime) * f > h
-                       //   (targetframetime - actualframetime) * (cl_updatescreen_quality / actualframetime * qualitymultiply) > h
-                       //   (1.0 / minfps - h / (quality / actualframetime * qualitymultiply) - actualframetime) * (quality / actualframetime * qualitymultiply) > h
-                       //   (1.0 / minfps - actualframetime) * (quality / actualframetime * qualitymultiply) > 2 * h
-                       //   actualframetime < quality qualitymultiply / (minfps quality qualitymultiply + 2 minfps h)
-                       //   actualframetime < 1.0 / minfps * (quality qualitymultiply) / (quality qualitymultiply + 2 h)
-                       //   actualframetime < 1.0 / minfps / (1 + 2 h / (quality qualitymultiply))
-                       //   actualframetime < 1.0 / minfps / (1 + 2 qualityhysteresis / qualitymultiply)
+                       //   ((1.0 / cl_minfps.value) - actualframetime) * (cl_updatescreen_quality / actualframetime * cl_minfps_qualitymultiply.value) > (cl_updatescreen_quality * cl_minfps_qualityhysteresis.value)
+                       //   ((1.0 / cl_minfps.value) - actualframetime) * (cl_minfps_qualitymultiply.value / actualframetime) > cl_minfps_qualityhysteresis.value
+                       //   (1.0 / cl_minfps.value) * (cl_minfps_qualitymultiply.value / actualframetime) - cl_minfps_qualitymultiply.value > cl_minfps_qualityhysteresis.value
+                       //   (1.0 / cl_minfps.value) * (cl_minfps_qualitymultiply.value / actualframetime) > cl_minfps_qualityhysteresis.value + cl_minfps_qualitymultiply.value
+                       //   (1.0 / cl_minfps.value) / actualframetime > (cl_minfps_qualityhysteresis.value + cl_minfps_qualitymultiply.value) / cl_minfps_qualitymultiply.value
+                       //   (1.0 / cl_minfps.value) / actualframetime > 1.0 + cl_minfps_qualityhysteresis.value / cl_minfps_qualitymultiply.value
+                       //   cl_minfps.value * actualframetime < 1.0 / (1.0 + cl_minfps_qualityhysteresis.value / cl_minfps_qualitymultiply.value)
+                       //   actualframetime < 1.0 / cl_minfps.value / (1.0 + cl_minfps_qualityhysteresis.value / cl_minfps_qualitymultiply.value)
+                       //   actualfps > cl_minfps.value * (1.0 + cl_minfps_qualityhysteresis.value / cl_minfps_qualitymultiply.value)
 
                        // adjust < 0 if:
-                       //   (targetframetime - actualframetime) * f < -h
-                       //   (targetframetime - actualframetime) * (cl_updatescreen_quality / actualframetime * qualitymultiply) < -h
-                       //   (1.0 / minfps - h / (quality / actualframetime * qualitymultiply) - actualframetime) * (quality / actualframetime * qualitymultiply) < -h
-                       //   (1.0 / minfps - actualframetime) * (quality / actualframetime * qualitymultiply) < 0
-                       //   actualframetime > 1.0 / minfps
+                       //   (targetframetime - actualframetime) * f < 0
+                       //   ((1.0 / cl_minfps.value) - actualframetime) * (cl_updatescreen_quality / actualframetime * cl_minfps_qualitymultiply.value) < 0
+                       //   ((1.0 / cl_minfps.value) - actualframetime) < 0
+                       //   -actualframetime) < -(1.0 / cl_minfps.value)
+                       //   actualfps < cl_minfps.value
 
                        /*
                        Con_Printf("adjust UP if fps > %f, adjust DOWN if fps < %f\n",
-                                       cl_minfps.value * (1.0 + 2.0 * cl_minfps_qualityhysteresis.value / cl_minfps_qualitymultiply.value),
+                                       cl_minfps.value * (1.0 + cl_minfps_qualityhysteresis.value / cl_minfps_qualitymultiply.value),
                                        cl_minfps.value);
                        */
 
+                       // don't adjust too much at once
                        adjust = bound(-cl_minfps_qualitystepmax.value, adjust, cl_minfps_qualitystepmax.value);
+
+                       // adjust!
                        cl_updatescreen_quality += adjust;
                        cl_updatescreen_quality = bound(max(0.01, cl_minfps_qualitymin.value), cl_updatescreen_quality, cl_minfps_qualitymax.value);
                }