]> git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - cl_screen.c
in X11, keypad * is KP_MULTIPLY, not '*'
[xonotic/darkplaces.git] / cl_screen.c
index 60d14e39586cb76d6613db4aafd93fd1fcbb66db..869b893f033501c99a5ec95f6d4f173b1d3d2242 100644 (file)
@@ -18,10 +18,10 @@ cvar_t scr_conforcewhiledisconnected = {0, "scr_conforcewhiledisconnected", "1",
 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"};
 cvar_t scr_showram = {CVAR_SAVE, "showram","1", "show ram icon if low on surface cache memory (not used)"};
-cvar_t scr_showturtle = {CVAR_SAVE, "showturtle","0", "show turtle icon when framerate is too low (not used)"};
+cvar_t scr_showturtle = {CVAR_SAVE, "showturtle","0", "show turtle icon when framerate is too low"};
 cvar_t scr_showpause = {CVAR_SAVE, "showpause","1", "show pause icon when game is paused"};
 cvar_t scr_showbrand = {0, "showbrand","0", "shows gfx/brand.tga in a corner of the screen (different values select different positions, including centered)"};
-cvar_t scr_printspeed = {0, "scr_printspeed","8", "speed of intermission printing (episode end texts)"};
+cvar_t scr_printspeed = {0, "scr_printspeed","0", "speed of intermission printing (episode end texts), a value of 0 disables the slow printing"};
 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"};
 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)"};
@@ -34,17 +34,19 @@ cvar_t cl_capturevideo_realtime = {0, "cl_capturevideo_realtime", "0", "causes v
 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_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)"};
+cvar_t r_stereo_separation = {0, "r_stereo_separation", "4", "separation distance of eyes in the world (negative values are only useful for cross-eyed viewing)"};
+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 (note: use a negative r_stereo_separation if you want cross-eyed viewing)"};
 cvar_t r_stereo_redblue = {0, "r_stereo_redblue", "0", "red/blue anaglyph stereo glasses (note: most of these glasses are actually red/cyan, try that one too)"};
 cvar_t r_stereo_redcyan = {0, "r_stereo_redcyan", "0", "red/cyan anaglyph stereo glasses, the kind given away at drive-in movies like Creature From The Black Lagoon In 3D"};
 cvar_t r_stereo_redgreen = {0, "r_stereo_redgreen", "0", "red/green anaglyph stereo glasses (for those who don't mind yellow)"};
+cvar_t r_stereo_angle = {0, "r_stereo_angle", "0", "separation angle of eyes (makes the views look different directions, as an example, 90 gives a 90 degree separation where the views are 45 degrees left and 45 degrees right)"};
 cvar_t scr_zoomwindow = {CVAR_SAVE, "scr_zoomwindow", "0", "displays a zoomed in overlay window"};
 cvar_t scr_zoomwindow_viewsizex = {CVAR_SAVE, "scr_zoomwindow_viewsizex", "20", "horizontal viewsize of zoom window"};
 cvar_t scr_zoomwindow_viewsizey = {CVAR_SAVE, "scr_zoomwindow_viewsizey", "20", "vertical viewsize of zoom window"};
 cvar_t scr_zoomwindow_fov = {CVAR_SAVE, "scr_zoomwindow_fov", "20", "fov of zoom window"};
 cvar_t scr_stipple = {0, "scr_stipple", "0", "interlacing-like stippling of the display"};
 cvar_t scr_refresh = {0, "scr_refresh", "1", "allows you to completely shut off rendering for benchmarking purposes"};
+cvar_t shownetgraph = {CVAR_SAVE, "shownetgraph", "0", "shows a graph of packet sizes and other information"};
 
 
 int jpeg_supported = false;
@@ -109,8 +111,8 @@ void SCR_DrawCenterString (void)
        int             remaining;
        int             color;
 
-// the finale prints the characters one at a time
-       if (cl.intermission)
+// the finale prints the characters one at a time, except if printspeed is an absurdly high value
+       if (cl.intermission && scr_printspeed.value > 0 && scr_printspeed.value < 1000000)
                remaining = (int)(scr_printspeed.value * (cl.time - scr_centertime_start));
        else
                remaining = 9999;
@@ -168,7 +170,8 @@ void SCR_CheckDrawCenterString (void)
        if (scr_center_lines > scr_erase_lines)
                scr_erase_lines = scr_center_lines;
 
-       scr_centertime_off -= cl.realframetime;
+       if (cl.time > cl.oldtime)
+               scr_centertime_off -= cl.time - cl.oldtime;
 
        // don't draw if this is a normal stats-screen intermission,
        // only if it is not an intermission, or a finale intermission
@@ -182,6 +185,86 @@ void SCR_CheckDrawCenterString (void)
        SCR_DrawCenterString ();
 }
 
+void SCR_DrawNetGraph_DrawGraph (int graphx, int graphy, int barwidth, int barheight, int bardivide, const char *label, float textsize, int packetcounter, int numparameters, const int **parameters, const float parametercolors[][4])
+{
+       int j, k, x, y, index, offset, height;
+       // dim background
+       DrawQ_Pic (graphx, graphy, NULL, barwidth * NETGRAPH_PACKETS, barheight + textsize, 0, 0, 0, 0.5, 0);
+       // draw a label
+       DrawQ_String (graphx, graphy + barheight, label, 0, textsize, textsize, 1, 1, 1, 1, 0);
+       // draw the bar graph itself
+       for (j = 0;j < NETGRAPH_PACKETS;j++)
+       {
+               x = graphx + j * barwidth;
+               y = graphy + barheight;
+               index = (packetcounter + j) % NETGRAPH_PACKETS;
+               if (parameters[0][index] == NETGRAPH_LOSTPACKET)
+                       DrawQ_Pic(x, y - barheight, NULL, barwidth, barheight, 1, 0, 0, 1, 0);
+               else if (parameters[0][index] == NETGRAPH_CHOKEDPACKET)
+                       DrawQ_Pic(x, y - min(2, barheight), NULL, barwidth, min(2, barheight), 1, 1, 0, 1, 0);
+               else
+               {
+                       offset = 0;
+                       for (k = 0;k < numparameters;k++)
+                       {
+                               height = (parameters[k][index] + bardivide - 1) / bardivide;
+                               height = min(height, barheight - offset);
+                               offset += height;
+                               if (height)
+                                       DrawQ_Pic(x, y - offset, NULL, barwidth, height, parametercolors[k][0], parametercolors[k][1], parametercolors[k][2], parametercolors[k][3], 0);
+                       }
+               }
+       }
+}
+
+const float netgraphcolors[3][4] =
+{
+       {1  , 0.5, 0  , 1},
+       {1  , 1  , 1  , 1},
+       {0  , 1  , 0  , 1},
+};
+
+void SCR_DrawNetGraph_DrawConnection (netconn_t *conn, int graphx, int graphy, int barwidth, int barheight, int bardivide, const char *labelincoming, int separator, const char *labeloutgoing, float textsize)
+{
+       int numparameters;
+       const int *parameters[3];
+       numparameters = 3;
+       parameters[0] = conn->incoming_unreliablesize;
+       parameters[1] = conn->incoming_reliablesize;
+       parameters[2] = conn->incoming_acksize;
+       SCR_DrawNetGraph_DrawGraph(graphx, graphy, barwidth, barheight, bardivide, labelincoming, textsize, conn->incoming_packetcounter, numparameters, parameters, netgraphcolors);
+       parameters[0] = conn->outgoing_unreliablesize;
+       parameters[1] = conn->outgoing_reliablesize;
+       parameters[2] = conn->outgoing_acksize;
+       SCR_DrawNetGraph_DrawGraph(graphx + barwidth * NETGRAPH_PACKETS + separator, graphy, barwidth, barheight, bardivide, labeloutgoing, textsize, conn->outgoing_packetcounter, numparameters, parameters, netgraphcolors);
+}
+
+/*
+==============
+SCR_DrawNetGraph
+==============
+*/
+void SCR_DrawNetGraph (void)
+{
+       int separator, barwidth, barheight, bardivide, netgraph_x, netgraph_y, textsize;
+
+       if (cls.state != ca_connected)
+               return;
+       if (!cls.netcon)
+               return;
+       if (!shownetgraph.integer)
+               return;
+
+       separator = 4;
+       textsize = 8;
+       barwidth = 1;
+       barheight = 50;
+       bardivide = 20;
+       netgraph_x = 0;
+       netgraph_y = vid_conheight.integer - 48 - barheight - textsize;
+       SCR_DrawNetGraph_DrawConnection(cls.netcon, netgraph_x, netgraph_y, barwidth, barheight, bardivide, "incoming", separator, "outgoing", textsize);
+}
+
 /*
 ==============
 SCR_DrawTurtle
@@ -630,12 +713,14 @@ void CL_Screen_Init(void)
        Cvar_RegisterVariable(&r_stereo_redblue);
        Cvar_RegisterVariable(&r_stereo_redcyan);
        Cvar_RegisterVariable(&r_stereo_redgreen);
+       Cvar_RegisterVariable(&r_stereo_angle);
        Cvar_RegisterVariable(&scr_zoomwindow);
        Cvar_RegisterVariable(&scr_zoomwindow_viewsizex);
        Cvar_RegisterVariable(&scr_zoomwindow_viewsizey);
        Cvar_RegisterVariable(&scr_zoomwindow_fov);
        Cvar_RegisterVariable(&scr_stipple);
        Cvar_RegisterVariable(&scr_refresh);
+       Cvar_RegisterVariable(&shownetgraph);
 
        Cmd_AddCommand ("sizeup",SCR_SizeUp_f, "increase view size (increases viewsize cvar)");
        Cmd_AddCommand ("sizedown",SCR_SizeDown_f, "decrease view size (decreases viewsize cvar)");
@@ -853,7 +938,7 @@ void SCR_CaptureVideo_BeginVideo(void)
        memset(&cls.capturevideo, 0, sizeof(cls.capturevideo));
        // soundrate is figured out on the first SoundFrame
        cls.capturevideo.active = true;
-       cls.capturevideo.starttime = Sys_DoubleTime();
+       cls.capturevideo.starttime = realtime;
        cls.capturevideo.framerate = bound(1, cl_capturevideo_fps.value, 1000);
        cls.capturevideo.soundrate = S_GetSoundRate();
        cls.capturevideo.frame = 0;
@@ -1209,7 +1294,7 @@ void SCR_CaptureVideo(void)
                if (cls.capturevideo.realtime)
                {
                        // preserve sound sync by duplicating frames when running slow
-                       newframenum = (int)((Sys_DoubleTime() - cls.capturevideo.starttime) * cls.capturevideo.framerate);
+                       newframenum = (int)((realtime - cls.capturevideo.starttime) * cls.capturevideo.framerate);
                }
                else
                        newframenum = cls.capturevideo.frame + 1;
@@ -1535,7 +1620,7 @@ 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_view.frustum_y = tan(scr_fov.value * cl.viewzoom * M_PI / 360.0) * (3.0/4.0);
+               r_view.frustum_y = tan(scr_fov.value * M_PI / 360.0) * (3.0/4.0) * cl.viewzoom;
                r_view.frustum_x = r_view.frustum_y * (float)r_view.width / (float)r_view.height / vid_pixelheight.value;
 
                r_view.frustum_x *= r_refdef.frustumscale_x;
@@ -1555,7 +1640,7 @@ void SCR_DrawScreen (void)
                        r_view.y = 0;
                        r_view.z = 0;
 
-                       r_view.frustum_y = tan(scr_zoomwindow_fov.value * cl.viewzoom * M_PI / 360.0) * (3.0/4.0);
+                       r_view.frustum_y = tan(scr_zoomwindow_fov.value * M_PI / 360.0) * (3.0/4.0) * cl.viewzoom;
                        r_view.frustum_x = r_view.frustum_y * vid_pixelheight.value * (float)r_view.width / (float)r_view.height;
 
                        r_view.frustum_x *= r_refdef.frustumscale_x;
@@ -1588,6 +1673,7 @@ void SCR_DrawScreen (void)
                SHOWLMP_drawall();
                SCR_CheckDrawCenterString();
        }
+       SCR_DrawNetGraph ();
        MR_Draw();
        CL_DrawVideo();
        R_Shadow_EditLights_DrawSelectedLightProperties();
@@ -1646,12 +1732,13 @@ void SCR_UpdateLoadingScreen (qboolean clear)
        y = (vid_conheight.integer - pic->height)/2;
        GL_Color(1,1,1,1);
        GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+       GL_DepthRange(0, 1);
        GL_DepthTest(false);
-       R_Mesh_VertexPointer(vertex3f);
-       R_Mesh_ColorPointer(NULL);
+       R_Mesh_VertexPointer(vertex3f, 0, 0);
+       R_Mesh_ColorPointer(NULL, 0, 0);
        R_Mesh_ResetTextureState();
        R_Mesh_TexBind(0, R_GetTexture(pic->tex));
-       R_Mesh_TexCoordPointer(0, 2, texcoord2f);
+       R_Mesh_TexCoordPointer(0, 2, texcoord2f, 0, 0);
        vertex3f[2] = vertex3f[5] = vertex3f[8] = vertex3f[11] = 0;
        vertex3f[0] = vertex3f[9] = x;
        vertex3f[1] = vertex3f[4] = y;
@@ -1664,19 +1751,21 @@ void SCR_UpdateLoadingScreen (qboolean clear)
        if (vid.stereobuffer)
        {
                qglDrawBuffer(GL_FRONT_LEFT);
-               R_Mesh_Draw(0, 4, 2, polygonelements);
+               R_Mesh_Draw(0, 4, 2, polygonelements, 0, 0);
                qglDrawBuffer(GL_FRONT_RIGHT);
-               R_Mesh_Draw(0, 4, 2, polygonelements);
+               R_Mesh_Draw(0, 4, 2, polygonelements, 0, 0);
        }
        else
        {
                qglDrawBuffer(GL_FRONT);
-               R_Mesh_Draw(0, 4, 2, polygonelements);
+               R_Mesh_Draw(0, 4, 2, polygonelements, 0, 0);
        }
        R_Mesh_Finish();
        // refresh
        // not necessary when rendering to GL_FRONT buffers
        //VID_Finish(false);
+       // however this IS necessary on Windows Vista
+       qglFinish();
 }
 
 void CL_UpdateScreen(void)
@@ -1689,15 +1778,6 @@ void CL_UpdateScreen(void)
        if (!scr_initialized || !con_initialized)
                return;                         // not initialized yet
 
-       // don't allow cheats in multiplayer
-       if (!cl.islocalgame && cl.worldmodel)
-       {
-               if (r_fullbright.integer != 0)
-                       Cvar_Set ("r_fullbright", "0");
-               if (r_ambient.value != 0)
-                       Cvar_Set ("r_ambient", "0");
-       }
-
        conwidth = bound(320, vid_conwidth.value, 2048);
        conheight = bound(200, vid_conheight.value, 1536);
        if (vid_conwidth.value != conwidth)
@@ -1785,11 +1865,13 @@ void CL_UpdateScreen(void)
        if (r_timereport_active)
                R_TimeReport("clear");
 
+       qglDrawBuffer(GL_BACK);
+
        if (vid.stereobuffer || r_stereo_redblue.integer || r_stereo_redgreen.integer || r_stereo_redcyan.integer || r_stereo_sidebyside.integer)
        {
                matrix4x4_t originalmatrix = r_view.matrix;
                matrix4x4_t offsetmatrix;
-               Matrix4x4_CreateTranslate(&offsetmatrix, 0, r_stereo_separation.value * -0.5f, 0);
+               Matrix4x4_CreateFromQuakeEntity(&offsetmatrix, 0, r_stereo_separation.value * 0.5f, 0, 0, r_stereo_angle.value * 0.5f, 0, 1);
                Matrix4x4_Concat(&r_view.matrix, &originalmatrix, &offsetmatrix);
 
                if (r_stereo_sidebyside.integer)
@@ -1807,7 +1889,7 @@ void CL_UpdateScreen(void)
 
                SCR_DrawScreen();
 
-               Matrix4x4_CreateTranslate(&offsetmatrix, 0, r_stereo_separation.value * 0.5f, 0);
+               Matrix4x4_CreateFromQuakeEntity(&offsetmatrix, 0, r_stereo_separation.value * -0.5f, 0, 0, r_stereo_angle.value * -0.5f, 0, 1);
                Matrix4x4_Concat(&r_view.matrix, &originalmatrix, &offsetmatrix);
 
                if (r_stereo_sidebyside.integer)
@@ -1828,10 +1910,7 @@ void CL_UpdateScreen(void)
                r_view.matrix = originalmatrix;
        }
        else
-       {
-               qglDrawBuffer(GL_BACK);
                SCR_DrawScreen();
-       }
 
        SCR_CaptureVideo();