]> de.git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - cl_screen.c
Updated Transfusion map list
[xonotic/darkplaces.git] / cl_screen.c
index a56acc4dd9718e3a8efe23a41830685511ef4390..9d5ca6289982a2c06715a2eb172683483d8c16eb 100644 (file)
@@ -1,5 +1,6 @@
 
 #include "quakedef.h"
+#include "cl_video.h"
 
 cvar_t scr_viewsize = {CVAR_SAVE, "viewsize","100"};
 cvar_t scr_fov = {CVAR_SAVE, "fov","90"};      // 10 - 170
@@ -10,6 +11,7 @@ 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 scr_2dresolution = {CVAR_SAVE, "scr_2dresolution", "1"};
+cvar_t cl_avidemo = {0, "cl_avidemo", "0"};
 
 qboolean       scr_initialized;                // ready to draw
 
@@ -19,12 +21,18 @@ float               scr_conlines;           // lines of console to display
 int                    clearconsole;
 int                    clearnotify;
 
-qboolean       scr_disabled_for_loading;
-//qboolean     scr_drawloading;
-//float                scr_disabled_time;
+qboolean       scr_drawloading = false;
 
 static qbyte menuplyr_pixels[4096];
 
+void DrawCrosshair(int num);
+void V_CalcRefdef (void);
+static void SCR_ScreenShot_f (void);
+static void R_Envmap_f (void);
+
+// backend
+void R_ClearScreen(void);
+
 /*
 ===============================================================================
 
@@ -121,6 +129,10 @@ void SCR_CheckDrawCenterString (void)
 
        scr_centertime_off -= host_frametime;
 
+       // don't draw if this is a normal stats-screen intermission,
+       // only if it is not an intermission, or a finale intermission
+       if (cl.intermission == 1)
+               return;
        if (scr_centertime_off <= 0 && !cl.intermission)
                return;
        if (key_dest != key_game)
@@ -129,18 +141,6 @@ void SCR_CheckDrawCenterString (void)
        SCR_DrawCenterString ();
 }
 
-/*
-==============
-SCR_DrawRam
-==============
-*/
-void SCR_DrawRam (void)
-{
-//     if (!scr_showram.integer)
-//             return;
-//     DrawQ_Pic (32, 0, "ram", 0, 0, 1, 1, 1, 1, 0);
-}
-
 /*
 ==============
 SCR_DrawTurtle
@@ -215,18 +215,13 @@ void SCR_DrawPause (void)
 SCR_DrawLoading
 ==============
 */
-/*
 void SCR_DrawLoading (void)
 {
        cachepic_t      *pic;
 
-       if (!scr_drawloading)
-               return;
-
        pic = Draw_CachePic ("gfx/loading.lmp");
        DrawQ_Pic ((vid.conwidth - pic->width)/2, (vid.conheight - pic->height)/2, "gfx/loading.lmp", 0, 0, 1, 1, 1, 1, 0);
 }
-*/
 
 
 
@@ -242,32 +237,37 @@ void SCR_SetUpToDrawConsole (void)
 {
        Con_CheckResize ();
 
-// decide on the height of the console
-       con_forcedup = !cl.worldmodel || cls.signon != SIGNONS;
+       if (key_dest == key_game && cls.signon != SIGNONS)
+               key_consoleactive |= KEY_CONSOLEACTIVE_FORCED;
+       else
+               key_consoleactive &= ~KEY_CONSOLEACTIVE_FORCED;
 
-       if (con_forcedup)
-       {
-               scr_conlines = vid.conheight;           // full screen
-               scr_con_current = scr_conlines;
-       }
-       else if (key_dest == key_console)
+// decide on the height of the console
+       if (key_consoleactive & KEY_CONSOLEACTIVE_FORCED)
+               scr_conlines = vid.conheight; // full screen
+       else if (key_consoleactive & KEY_CONSOLEACTIVE_USER)
                scr_conlines = vid.conheight/2; // half screen
        else
                scr_conlines = 0;                               // none visible
 
-       if (scr_conlines < scr_con_current)
+       if (scr_conspeed.value)
        {
-               scr_con_current -= scr_conspeed.value*host_realframetime;
-               if (scr_conlines > scr_con_current)
-                       scr_con_current = scr_conlines;
-
-       }
-       else if (scr_conlines > scr_con_current)
-       {
-               scr_con_current += scr_conspeed.value*host_realframetime;
                if (scr_conlines < scr_con_current)
-                       scr_con_current = scr_conlines;
+               {
+                       scr_con_current -= scr_conspeed.value*host_realframetime;
+                       if (scr_conlines > scr_con_current)
+                               scr_con_current = scr_conlines;
+
+               }
+               else if (scr_conlines > scr_con_current)
+               {
+                       scr_con_current += scr_conspeed.value*host_realframetime;
+                       if (scr_conlines < scr_con_current)
+                               scr_con_current = scr_conlines;
+               }
        }
+       else
+               scr_con_current = scr_conlines;
 }
 
 /*
@@ -295,81 +295,21 @@ SCR_BeginLoadingPlaque
 
 ================
 */
-/*
 void SCR_BeginLoadingPlaque (void)
 {
-       S_StopAllSounds (true);
-
-//     if (cls.state != ca_connected)
-//             return;
-//     if (cls.signon != SIGNONS)
-//             return;
+       if (scr_drawloading)
+               return;
 
-// redraw with no console and the loading plaque
-//     Con_ClearNotify ();
-//     scr_centertime_off = 0;
-//     scr_con_current = 0;
+       S_StopAllSounds (true);
 
        scr_drawloading = true;
-       SCR_UpdateScreen ();
-
-//     scr_disabled_for_loading = true;
-//     scr_disabled_time = realtime;
-}
-*/
-
-/*
-===============
-SCR_EndLoadingPlaque
-
-================
-*/
-/*
-void SCR_EndLoadingPlaque (void)
-{
-//     scr_disabled_for_loading = false;
-       scr_drawloading = false;
-       Con_ClearNotify ();
+       CL_UpdateScreen ();
+       scr_drawloading = true;
+       CL_UpdateScreen ();
 }
-*/
 
 //=============================================================================
 
-char   *scr_notifystring;
-
-void SCR_DrawNotifyString (void)
-{
-       char    *start;
-       int             l;
-       int             x, y;
-
-       start = scr_notifystring;
-
-       y = vid.conheight*0.35;
-
-       do
-       {
-       // scan the width of the line
-               for (l=0 ; l<40 ; l++)
-                       if (start[l] == '\n' || !start[l])
-                               break;
-               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')
-                       start++;
-
-               if (!*start)
-                       break;
-               start++;                // skip the \n
-       }
-       while (1);
-}
-
-void DrawCrosshair(int num);
-
 char r_speeds_string[1024];
 int speedstringcount, r_timereport_active;
 double r_timereport_temp = 0, r_timereport_current = 0, r_timereport_start = 0;
@@ -412,27 +352,22 @@ void R_TimeReport(char *desc)
 
 void R_TimeReport_Start(void)
 {
-       r_timereport_active = r_speeds.integer && cl.worldmodel && cls.state == ca_connected;
+       r_timereport_active = r_speeds.integer && cls.signon == SIGNONS && 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"
-                       "world:%6i faces%6i nodes%6i leafs%6i walls%6i dlitwalls\n"
+                       "world:%6i faces%6i nodes%6i leafs%6i dlitwalls\n"
                        "%5i models%5i bmodels%5i sprites%6i particles%4i dlights\n"
-                       "%6i modeltris%6i transmeshs%6i transtris%6i meshs%6i meshtris\n",
+                       "%6i modeltris%6i meshs%6i meshtris\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_faces, c_nodes, c_leafs, c_brush_polys, c_light_polys,
+                       c_faces, c_nodes, c_leafs, c_light_polys,
                        c_models, c_bmodels, c_sprites, c_particles, c_dlights,
-                       c_alias_polys, c_transmeshs, c_transtris, c_meshs, c_meshtris);
+                       c_alias_polys, c_meshs, c_meshelements / 3);
 
-               c_brush_polys = 0;
                c_alias_polys = 0;
                c_light_polys = 0;
                c_faces = 0;
@@ -442,7 +377,8 @@ void R_TimeReport_Start(void)
                c_bmodels = 0;
                c_sprites = 0;
                c_particles = 0;
-       //      c_dlights = 0;
+               c_meshs = 0;
+               c_meshelements = 0;
 
                r_timereport_start = Sys_DoubleTime();
        }
@@ -460,7 +396,7 @@ void R_TimeReport_End(void)
                for (i = 0;r_speeds_string[i];i++)
                        if (r_speeds_string[i] == '\n')
                                lines++;
-               y = vid.conheight - sb_lines - lines * 8/* - 8*/;
+               y = vid.conheight - sb_lines - lines * 8;
                i = j = 0;
                DrawQ_Fill(0, y, vid.conwidth, lines * 8, 0, 0, 0, 0.5, 0);
                while (r_speeds_string[i])
@@ -514,10 +450,13 @@ void CL_Screen_Init(void)
        Cvar_RegisterVariable (&scr_showpause);
        Cvar_RegisterVariable (&scr_centertime);
        Cvar_RegisterVariable (&scr_printspeed);
-       Cvar_RegisterVariable(&scr_2dresolution);
+       Cvar_RegisterVariable (&scr_2dresolution);
+       Cvar_RegisterVariable (&cl_avidemo);
 
        Cmd_AddCommand ("sizeup",SCR_SizeUp_f);
        Cmd_AddCommand ("sizedown",SCR_SizeDown_f);
+       Cmd_AddCommand ("screenshot",SCR_ScreenShot_f);
+       Cmd_AddCommand ("envmap", R_Envmap_f);
 
        scr_initialized = true;
 
@@ -544,10 +483,10 @@ void DrawQ_Pic(float x, float y, char *picname, float width, float height, float
 {
        int size;
        drawqueue_t *dq;
-       if (alpha < (1.0f / 255.0f))
+       if (alpha < (1.0f / 255.0f) || !picname || !picname[0])
                return;
        size = sizeof(*dq) + ((strlen(picname) + 1 + 3) & ~3);
-       if (r_refdef.drawqueuesize + size > MAX_DRAWQUEUE)
+       if (r_refdef.drawqueuesize + size > r_refdef.maxdrawqueuesize)
                return;
        red = bound(0, red, 1);
        green = bound(0, green, 1);
@@ -585,7 +524,7 @@ void DrawQ_String(float x, float y, char *string, int maxlen, float scalex, floa
        if (x >= vid.conwidth || y >= vid.conheight || x < (-scalex * maxlen) || y < (-scaley))
                return;
        size = sizeof(*dq) + ((len + 1 + 3) & ~3);
-       if (r_refdef.drawqueuesize + size > MAX_DRAWQUEUE)
+       if (r_refdef.drawqueuesize + size > r_refdef.maxdrawqueuesize)
                return;
        red = bound(0, red, 1);
        green = bound(0, green, 1);
@@ -613,7 +552,7 @@ void DrawQ_Fill (float x, float y, float w, float h, float red, float green, flo
        if (alpha < (1.0f / 255.0f))
                return;
        size = sizeof(*dq) + 4;
-       if (r_refdef.drawqueuesize + size > MAX_DRAWQUEUE)
+       if (r_refdef.drawqueuesize + size > r_refdef.maxdrawqueuesize)
                return;
        red = bound(0, red, 1);
        green = bound(0, green, 1);
@@ -633,34 +572,41 @@ void DrawQ_Fill (float x, float y, float w, float h, float red, float green, flo
        r_refdef.drawqueuesize += dq->size;
 }
 
-//only used for the player color selection menu
-void DrawQ_PicTranslate (int x, int y, char *picname, qbyte *translation)
+void DrawQ_Mesh (drawqueuemesh_t *mesh, int flags)
 {
-       int i, c;
-       unsigned int trans[4096];
-       cachepic_t *pic;
-
-       pic = Draw_CachePic(picname);
-       if (pic == NULL)
-               return;
-
-       c = pic->width * pic->height;
-       if (c > 4096)
-       {
-               Con_Printf("DrawQ_PicTranslate: image larger than 4k buffer\n");
+       int size;
+       void *p;
+       drawqueue_t *dq;
+       drawqueuemesh_t *m;
+       size = sizeof(*dq);
+       size += sizeof(drawqueuemesh_t);
+       size += sizeof(int) * mesh->numindices;
+       size += sizeof(float[4]) * mesh->numvertices;
+       size += sizeof(float[2]) * mesh->numvertices;
+       size += sizeof(float[4]) * mesh->numvertices;
+       if (r_refdef.drawqueuesize + size > r_refdef.maxdrawqueuesize)
                return;
-       }
-
-       for (i = 0;i < c;i++)
-               trans[i] = d_8to24table[translation[menuplyr_pixels[i]]];
-
-       // FIXME: this is renderer stuff?
-       R_UpdateTexture (pic->tex, (qbyte *)trans);
-
-       DrawQ_Pic(x, y, picname, 0, 0, 1, 1, 1, 1, 0);
+       dq = (void *)(r_refdef.drawqueue + r_refdef.drawqueuesize);
+       dq->size = size;
+       dq->command = DRAWQUEUE_MESH;
+       dq->flags = flags;
+       dq->color = 0;
+       dq->x = 0;
+       dq->y = 0;
+       dq->scalex = 0;
+       dq->scaley = 0;
+       p = (void *)(dq + 1);
+       m = p;(qbyte *)p += sizeof(drawqueuemesh_t);
+       m->numindices = mesh->numindices;
+       m->numvertices = mesh->numvertices;
+       m->texture = mesh->texture;
+       m->indices   = p;memcpy(m->indices  , mesh->indices  , m->numindices  * sizeof(int     ));(qbyte *)p += m->numindices  * sizeof(int     );
+       m->vertices  = p;memcpy(m->vertices , mesh->vertices , m->numvertices * sizeof(float[4]));(qbyte *)p += m->numvertices * sizeof(float[4]);
+       m->texcoords = p;memcpy(m->texcoords, mesh->texcoords, m->numvertices * sizeof(float[2]));(qbyte *)p += m->numvertices * sizeof(float[2]);
+       m->colors    = p;memcpy(m->colors   , mesh->colors   , m->numvertices * sizeof(float[4]));(qbyte *)p += m->numvertices * sizeof(float[4]);
+       r_refdef.drawqueuesize += dq->size;
 }
 
-
 /*
 ====================
 CalcFov
@@ -743,7 +689,7 @@ static void SCR_CalcRefdef (void)
        if (cl.worldmodel)
        {
                Mod_CheckLoaded(cl.worldmodel);
-               contents = Mod_PointInLeaf(r_refdef.vieworg, cl.worldmodel)->contents;
+               contents = Mod_PointContents(r_refdef.vieworg, cl.worldmodel);
                if (contents != CONTENTS_EMPTY && contents != CONTENTS_SOLID)
                {
                        r_refdef.fov_x *= (sin(cl.time * 4.7) * 0.015 + 0.985);
@@ -752,8 +698,121 @@ static void SCR_CalcRefdef (void)
        }
 }
 
+/*
+==================
+SCR_ScreenShot_f
+==================
+*/
+void SCR_ScreenShot_f (void)
+{
+       static int i = 0;
+       char filename[16];
+       char checkname[MAX_OSPATH];
+//
+// find a file name to save it to
+//
+       for (; i<=9999 ; i++)
+       {
+               sprintf (filename, "dp%04i.tga", i);
+               sprintf (checkname, "%s/%s", com_gamedir, filename);
+               if (Sys_FileTime(checkname) == -1)
+                       break;  // file doesn't exist
+       }
+       if (i==10000)
+       {
+               Con_Printf ("SCR_ScreenShot_f: Couldn't create a TGA file\n");
+               return;
+       }
+
+       if (SCR_ScreenShot(filename, vid.realx, vid.realy, vid.realwidth, vid.realheight))
+               Con_Printf ("Wrote %s\n", filename);
+       else
+               Con_Printf ("unable to write %s\n", filename);
+}
+
+static int cl_avidemo_frame = 0;
 
-void V_CalcRefdef (void);
+void SCR_CaptureAVIDemo(void)
+{
+       char filename[32];
+       sprintf(filename, "dpavi%06d.tga", cl_avidemo_frame);
+       if (SCR_ScreenShot(filename, vid.realx, vid.realy, vid.realwidth, vid.realheight))
+               cl_avidemo_frame++;
+       else
+       {
+               Cvar_SetValueQuick(&cl_avidemo, 0);
+               Con_Printf("avi saving failed on frame %i, out of disk space?  stopping avi demo catpure.\n", cl_avidemo_frame);
+               cl_avidemo_frame = 0;
+       }
+}
+
+/*
+===============
+R_Envmap_f
+
+Grab six views for environment mapping tests
+===============
+*/
+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 j, size;
+       char filename[256], basename[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;
+       }
+
+       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;
+       }
+
+       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 (j = 0;j < 6;j++)
+       {
+               sprintf(filename, "env/%s%s.tga", basename, envmapinfo[j].name);
+               VectorCopy(envmapinfo[j].angles, r_refdef.viewangles);
+               R_ClearScreen();
+               R_RenderView ();
+               SCR_ScreenShot(filename, vid.realx, vid.realy, size, size);
+       }
+
+       envmap = false;
+}
 
 //=============================================================================
 
@@ -826,10 +885,9 @@ void SHOWLMP_decodeshow(void)
 void SHOWLMP_drawall(void)
 {
        int i;
-       if (cl.worldmodel)
-               for (i = 0;i < SHOWLMP_MAXLABELS;i++)
-                       if (showlmp[i].isactive)
-                               DrawQ_Pic(showlmp[i].x, showlmp[i].y, showlmp[i].pic, 0, 0, 1, 1, 1, 1, 0);
+       for (i = 0;i < SHOWLMP_MAXLABELS;i++)
+               if (showlmp[i].isactive)
+                       DrawQ_Pic(showlmp[i].x, showlmp[i].y, showlmp[i].pic, 0, 0, 1, 1, 1, 1, 0);
 }
 
 void SHOWLMP_clear(void)
@@ -839,18 +897,10 @@ void SHOWLMP_clear(void)
                showlmp[i].isactive = false;
 }
 
-void CL_UpdateScreen(void)
+void CL_SetupScreenSize(void)
 {
        static float old2dresolution = -1;
 
-       if (scr_disabled_for_loading)
-               return;
-
-       if (!scr_initialized || !con_initialized)
-               return;                         // not initialized yet
-
-       R_TimeReport("other");
-
        VID_GetWindowSize (&vid.realx, &vid.realy, &vid.realwidth, &vid.realheight);
 
        VID_UpdateGamma(false);
@@ -881,36 +931,61 @@ void CL_UpdateScreen(void)
 
        // determine size of refresh window
        SCR_CalcRefdef();
+}
 
-       DrawQ_Clear();
-
-       V_UpdateBlends();
-       V_CalcRefdef ();
+void CL_UpdateScreen(void)
+{
+       if (!scr_initialized || !con_initialized || vid_hidden)
+               return;                         // not initialized yet
 
-       R_TimeReport("setup");
+       if (cl_avidemo.integer)
+               SCR_CaptureAVIDemo();
+       else
+               cl_avidemo_frame = 0;
 
-       SCR_DrawRam();
-       SCR_DrawNet();
-       SCR_DrawTurtle();
-       SCR_DrawPause();
-       SCR_CheckDrawCenterString();
-       Sbar_Draw();
-       SHOWLMP_drawall();
+       if (cls.signon == SIGNONS)
+               R_TimeReport("other");
 
-       SCR_DrawConsole();
+       CL_SetupScreenSize();
 
-       ui_draw();
+       DrawQ_Clear();
 
-       R_TimeReport("2d");
+       V_UpdateBlends();
+       V_CalcRefdef ();
 
-       // add r_speeds text to queue
-       R_TimeReport_End();
+       if (cls.signon == SIGNONS)
+               R_TimeReport("setup");
 
-       // start a new timing run
-       R_TimeReport_Start();
+       //FIXME: force menu if nothing else to look at?
+       //if (key_dest == key_game && cls.signon != SIGNONS && cls.state == ca_disconnected)
 
-       // make menu fade everything else on the screen
-       M_Draw();
+       if (scr_drawloading)
+       {
+               scr_drawloading = false;
+               SCR_DrawLoading();
+       }
+       else
+       {
+               if (cls.signon == SIGNONS)
+               {
+                       SCR_DrawNet ();
+                       SCR_DrawTurtle ();
+                       SCR_DrawPause ();
+                       Sbar_Draw();
+                       SHOWLMP_drawall();
+                       SCR_CheckDrawCenterString();
+               }
+               ui_draw();
+               CL_DrawVideo();
+               M_Draw();
+               if (cls.signon == SIGNONS)
+               {
+                       R_TimeReport("2d");
+                       R_TimeReport_End();
+                       R_TimeReport_Start();
+               }
+       }
+       SCR_DrawConsole();
 
        SCR_UpdateScreen();
 }
@@ -919,3 +994,4 @@ void CL_Screen_NewMap(void)
 {
        SHOWLMP_clear();
 }
+