]> de.git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - gl_draw.c
another patch from div0 to improve ping parsing behavior in the event that multiple...
[xonotic/darkplaces.git] / gl_draw.c
index 95f9e7bd9869072fbb9d5adda8c53cfcefd85dc4..5f96691276dc60a90d527545702bd2328066406a 100644 (file)
--- a/gl_draw.c
+++ b/gl_draw.c
@@ -263,10 +263,8 @@ static rtexture_t *draw_generatecrosshair(int num)
                }
                else
                {
-                       data[i][0] = 255;
-                       data[i][1] = 255;
-                       data[i][2] = 255;
-                       data[i][3] = (unsigned char) ((int) (in[i] - '0') * 255 / 7);
+                       data[i][0] = data[i][1] = data[i][2] = (unsigned char) ((int) (in[i] - '0') * 127 / 7 + 128);
+                       data[i][3] = 255;
                }
        }
        return R_LoadTexture2D(drawtexturepool, va("crosshair%i", num), 16, 16, &data[0][0], TEXTYPE_RGBA, TEXF_ALPHA | TEXF_PRECACHE, NULL);
@@ -304,8 +302,10 @@ cachepic_t *Draw_CachePic (const char *path, qboolean persistent)
 {
        int crc, hashkey;
        cachepic_t *pic;
-       qpic_t *p;
        int flags;
+       fs_offset_t lmpsize;
+       unsigned char *lmpdata;
+       char lmpname[MAX_QPATH];
 
        if (!strncmp(CLVIDEOPREFIX, path, sizeof(CLVIDEOPREFIX) - 1))
        {
@@ -340,53 +340,91 @@ cachepic_t        *Draw_CachePic (const char *path, qboolean persistent)
        if (!strcmp(path, "gfx/colorcontrol/ditherpattern"))
                flags |= TEXF_CLAMP;
 
-       // load the pic from disk
+       // load a high quality image from disk if possible
        pic->tex = loadtextureimage(drawtexturepool, path, 0, 0, false, flags);
        if (pic->tex == NULL && !strncmp(path, "gfx/", 4))
        {
-               // compatibility with older versions
+               // compatibility with older versions which did not require gfx/ prefix
                pic->tex = loadtextureimage(drawtexturepool, path + 4, 0, 0, false, flags);
-               // failed to find gfx/whatever.tga or similar, try the wad
-               if (pic->tex == NULL && (p = (qpic_t *)W_GetLumpName (path + 4)))
+       }
+       // if a high quality image was loaded, set the pic's size to match it, just
+       // in case there's no low quality version to get the size from
+       if (pic->tex)
+       {
+               pic->width = R_TextureWidth(pic->tex);
+               pic->height = R_TextureHeight(pic->tex);
+       }
+
+       // now read the low quality version (wad or lmp file), and take the pic
+       // size from that even if we don't upload the texture, this way the pics
+       // show up the right size in the menu even if they were replaced with
+       // higher or lower resolution versions
+       dpsnprintf(lmpname, sizeof(lmpname), "%s.lmp", path);
+       if (!strncmp(path, "gfx/", 4) && (lmpdata = FS_LoadFile(lmpname, tempmempool, false, &lmpsize)))
+       {
+               if (lmpsize >= 9)
                {
-                       if (!strcmp(path, "gfx/conchars"))
-                       {
-                               // conchars is a raw image and with color 0 as transparent instead of 255
-                               pic->tex = R_LoadTexture2D(drawtexturepool, path, 128, 128, (unsigned char *)p, TEXTYPE_PALETTE, flags, palette_font);
-                       }
-                       else
-                               pic->tex = R_LoadTexture2D(drawtexturepool, path, p->width, p->height, p->data, TEXTYPE_PALETTE, flags, palette_transparent);
+                       pic->width = lmpdata[0] + lmpdata[1] * 256 + lmpdata[2] * 65536 + lmpdata[3] * 16777216;
+                       pic->height = lmpdata[4] + lmpdata[5] * 256 + lmpdata[6] * 65536 + lmpdata[7] * 16777216;
+                       // if no high quality replacement image was found, upload the original low quality texture
+                       if (!pic->tex)
+                               pic->tex = R_LoadTexture2D(drawtexturepool, path, pic->width, pic->height, lmpdata + 8, TEXTYPE_PALETTE, flags, palette_transparent);
+               }
+               Mem_Free(lmpdata);
+       }
+       else if ((lmpdata = W_GetLumpName (path + 4)))
+       {
+               if (!strcmp(path, "gfx/conchars"))
+               {
+                       // conchars is a raw image and with color 0 as transparent instead of 255
+                       pic->width = 128;
+                       pic->height = 128;
+                       // if no high quality replacement image was found, upload the original low quality texture
+                       if (!pic->tex)
+                               pic->tex = R_LoadTexture2D(drawtexturepool, path, 128, 128, lmpdata, TEXTYPE_PALETTE, flags, palette_font);
+               }
+               else
+               {
+                       pic->width = lmpdata[0] + lmpdata[1] * 256 + lmpdata[2] * 65536 + lmpdata[3] * 16777216;
+                       pic->height = lmpdata[4] + lmpdata[5] * 256 + lmpdata[6] * 65536 + lmpdata[7] * 16777216;
+                       // if no high quality replacement image was found, upload the original low quality texture
+                       if (!pic->tex)
+                               pic->tex = R_LoadTexture2D(drawtexturepool, path, pic->width, pic->height, lmpdata + 8, TEXTYPE_PALETTE, flags, palette_transparent);
                }
        }
 
-       if (pic->tex == NULL && !strcmp(path, "gfx/conchars"))
-               pic->tex = draw_generateconchars();
-       if (pic->tex == NULL && !strcmp(path, "ui/mousepointer"))
-               pic->tex = draw_generatemousepointer();
-       if (pic->tex == NULL && !strcmp(path, "gfx/prydoncursor001"))
-               pic->tex = draw_generatemousepointer();
-       if (pic->tex == NULL && !strcmp(path, "gfx/crosshair1"))
-               pic->tex = draw_generatecrosshair(0);
-       if (pic->tex == NULL && !strcmp(path, "gfx/crosshair2"))
-               pic->tex = draw_generatecrosshair(1);
-       if (pic->tex == NULL && !strcmp(path, "gfx/crosshair3"))
-               pic->tex = draw_generatecrosshair(2);
-       if (pic->tex == NULL && !strcmp(path, "gfx/crosshair4"))
-               pic->tex = draw_generatecrosshair(3);
-       if (pic->tex == NULL && !strcmp(path, "gfx/crosshair5"))
-               pic->tex = draw_generatecrosshair(4);
-       if (pic->tex == NULL && !strcmp(path, "gfx/crosshair6"))
-               pic->tex = draw_generatecrosshair(5);
-       if (pic->tex == NULL && !strcmp(path, "gfx/colorcontrol/ditherpattern"))
-               pic->tex = draw_generateditherpattern();
+       // if it's not found on disk, check if it's one of the builtin images
        if (pic->tex == NULL)
        {
-               Con_Printf("Draw_CachePic: failed to load %s\n", path);
-               pic->tex = r_texture_notexture;
+               if (pic->tex == NULL && !strcmp(path, "gfx/conchars"))
+                       pic->tex = draw_generateconchars();
+               if (pic->tex == NULL && !strcmp(path, "ui/mousepointer"))
+                       pic->tex = draw_generatemousepointer();
+               if (pic->tex == NULL && !strcmp(path, "gfx/prydoncursor001"))
+                       pic->tex = draw_generatemousepointer();
+               if (pic->tex == NULL && !strcmp(path, "gfx/crosshair1"))
+                       pic->tex = draw_generatecrosshair(0);
+               if (pic->tex == NULL && !strcmp(path, "gfx/crosshair2"))
+                       pic->tex = draw_generatecrosshair(1);
+               if (pic->tex == NULL && !strcmp(path, "gfx/crosshair3"))
+                       pic->tex = draw_generatecrosshair(2);
+               if (pic->tex == NULL && !strcmp(path, "gfx/crosshair4"))
+                       pic->tex = draw_generatecrosshair(3);
+               if (pic->tex == NULL && !strcmp(path, "gfx/crosshair5"))
+                       pic->tex = draw_generatecrosshair(4);
+               if (pic->tex == NULL && !strcmp(path, "gfx/crosshair6"))
+                       pic->tex = draw_generatecrosshair(5);
+               if (pic->tex == NULL && !strcmp(path, "gfx/colorcontrol/ditherpattern"))
+                       pic->tex = draw_generateditherpattern();
+               if (pic->tex == NULL)
+               {
+                       Con_Printf("Draw_CachePic: failed to load %s\n", path);
+                       pic->tex = r_texture_notexture;
+               }
+               pic->width = R_TextureWidth(pic->tex);
+               pic->height = R_TextureHeight(pic->tex);
        }
 
-       pic->width = R_TextureWidth(pic->tex);
-       pic->height = R_TextureHeight(pic->tex);
        return pic;
 }
 
@@ -420,7 +458,7 @@ cachepic_t *Draw_NewPic(const char *picname, int width, int height, int alpha, u
                                return cachepics; // return the first one
                        }
                        pic = cachepics + (numcachepics++);
-                       strcpy (pic->name, picname);
+                       strlcpy (pic->name, picname, sizeof(pic->name));
                        // link into list
                        pic->chain = cachepichash[hashkey];
                        cachepichash[hashkey] = pic;
@@ -491,25 +529,34 @@ void GL_Draw_Init (void)
        R_RegisterModule("GL_Draw", gl_draw_start, gl_draw_shutdown, gl_draw_newmap);
 }
 
-void DrawQ_Begin(void)
+static void _DrawQ_Setup(void)
 {
-       GL_ColorMask(r_view.colormask[0], r_view.colormask[1], r_view.colormask[2], 1);
-
+       if (r_refdef.draw2dstage)
+               return;
+       r_refdef.draw2dstage = true;
        CHECKGLERROR
        qglViewport(r_view.x, vid.height - (r_view.y + r_view.height), r_view.width, r_view.height);CHECKGLERROR
+       GL_ColorMask(r_view.colormask[0], r_view.colormask[1], r_view.colormask[2], 1);
        GL_SetupView_Mode_Ortho(0, 0, vid_conwidth.integer, vid_conheight.integer, -10, 100);
        qglDepthFunc(GL_LEQUAL);CHECKGLERROR
+       qglDisable(GL_POLYGON_OFFSET_FILL);CHECKGLERROR
        R_Mesh_Matrix(&identitymatrix);
 
        GL_DepthMask(true);
        GL_DepthTest(false);
        GL_Color(1,1,1,1);
+       GL_AlphaTest(false);
+       GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
 
-       r_refdef.draw2dstage = true;
+       if (gl_support_fragment_shader)
+       {
+               qglUseProgramObjectARB(0);CHECKGLERROR
+       }
 }
 
 static void _DrawQ_ProcessDrawFlag(int flags)
 {
+       _DrawQ_Setup();
        CHECKGLERROR
        if(flags == DRAWFLAG_ADDITIVE)
                GL_BlendFunc(GL_SRC_ALPHA, GL_ONE);
@@ -523,11 +570,6 @@ static void _DrawQ_ProcessDrawFlag(int flags)
 
 void DrawQ_Pic(float x, float y, cachepic_t *pic, float width, float height, float red, float green, float blue, float alpha, int flags)
 {
-       if (!r_refdef.draw2dstage)
-       {
-               Con_Printf("DrawQ_Pic: not in 2d rendering stage!\n");
-               return;
-       }
        DrawQ_SuperPic(x,y,pic,width,height,0,0,red,green,blue,alpha,1,0,red,green,blue,alpha,0,1,red,green,blue,alpha,1,1,red,green,blue,alpha,flags);
 }
 
@@ -539,15 +581,6 @@ void DrawQ_String_Real(float x, float y, const char *string, int maxlen, float w
        float vertex3f[QUADELEMENTS_MAXQUADS*4*3];
        float texcoord2f[QUADELEMENTS_MAXQUADS*4*2];
 
-       if (!r_refdef.draw2dstage)
-       {
-               Con_Printf("DrawQ_String: not in 2d rendering stage!\n");
-               return;
-       }
-
-       if (!r_render.integer)
-               return;
-
        if (alpha < (1.0f / 255.0f))
                return;
 
@@ -607,12 +640,6 @@ void DrawQ_String_Real(float x, float y, const char *string, int maxlen, float w
 
 void DrawQ_String(float x, float y, const char *string, int maxlen, float scalex, float scaley, float red, float green, float blue, float alpha, int flags)
 {
-       if (!r_refdef.draw2dstage)
-       {
-               Con_Printf("DrawQ_String: not in 2d rendering stage!\n");
-               return;
-       }
-
        if (r_textshadow.integer)
                DrawQ_String_Real(x+scalex*0.25,y+scaley*0.25,string,maxlen,scalex,scaley,0,0,0,alpha*0.8,flags);
 
@@ -657,11 +684,6 @@ void DrawQ_ColoredString( float x, float y, const char *text, int maxlen, float
        int colorindex;
        const char *start, *current;
 
-       if (!r_refdef.draw2dstage)
-       {
-               Con_Printf("DrawQ_ColoredString: not in 2d rendering stage!\n");
-               return;
-       }
        if( !outcolor || *outcolor == -1 ) {
                colorindex = STRING_COLOR_DEFAULT;
        } else {
@@ -736,15 +758,6 @@ void DrawQ_SuperPic(float x, float y, cachepic_t *pic, float width, float height
 {
        float floats[36];
 
-       if (!r_refdef.draw2dstage)
-       {
-               Con_Printf("DrawQ_SuperPic: not in 2d rendering stage!\n");
-               return;
-       }
-
-       if (!r_render.integer)
-               return;
-
        _DrawQ_ProcessDrawFlag(flags);
 
        R_Mesh_VertexPointer(floats);
@@ -779,15 +792,6 @@ void DrawQ_SuperPic(float x, float y, cachepic_t *pic, float width, float height
 
 void DrawQ_Mesh (drawqueuemesh_t *mesh, int flags)
 {
-       if (!r_refdef.draw2dstage)
-       {
-               Con_Printf("DrawQ_Mesh: not in 2d rendering stage!\n");
-               return;
-       }
-
-       if (!r_render.integer)
-               return;
-
        _DrawQ_ProcessDrawFlag(flags);
 
        R_Mesh_VertexPointer(mesh->data_vertex3f);
@@ -805,15 +809,6 @@ void DrawQ_LineLoop (drawqueuemesh_t *mesh, int flags)
 {
        int num;
 
-       if (!r_refdef.draw2dstage)
-       {
-               Con_Printf("DrawQ_LineLoop: not in 2d rendering stage!\n");
-               return;
-       }
-
-       if (!r_render.integer)
-               return;
-
        _DrawQ_ProcessDrawFlag(flags);
 
        GL_Color(1,1,1,1);
@@ -829,35 +824,13 @@ void DrawQ_LineLoop (drawqueuemesh_t *mesh, int flags)
        CHECKGLERROR
 }
 
-//LordHavoc: FIXME: this is nasty!
-void DrawQ_LineWidth (float width)
-{
-       if (!r_refdef.draw2dstage)
-       {
-               Con_Printf("DrawQ_LineWidth: not in 2d rendering stage!\n");
-               return;
-       }
-       CHECKGLERROR
-       qglLineWidth(width);CHECKGLERROR
-}
-
 //[515]: this is old, delete
 void DrawQ_Line (float width, float x1, float y1, float x2, float y2, float r, float g, float b, float alpha, int flags)
 {
-       if (!r_refdef.draw2dstage)
-       {
-               Con_Printf("DrawQ_Line: not in 2d rendering stage!\n");
-               return;
-       }
-
-       if (!r_render.integer)
-               return;
+       _DrawQ_ProcessDrawFlag(flags);
 
        CHECKGLERROR
-       if(width > 0)
-               DrawQ_LineWidth(width);
-
-       _DrawQ_ProcessDrawFlag(flags);
+       qglLineWidth(width);CHECKGLERROR
 
        GL_Color(r,g,b,alpha);
        CHECKGLERROR
@@ -870,11 +843,7 @@ void DrawQ_Line (float width, float x1, float y1, float x2, float y2, float r, f
 
 void DrawQ_SetClipArea(float x, float y, float width, float height)
 {
-       if (!r_refdef.draw2dstage)
-       {
-               Con_Printf("DrawQ_SetClipArea: not in 2d rendering stage!\n");
-               return;
-       }
+       _DrawQ_Setup();
 
        // We have to convert the con coords into real coords
        // OGL uses top to bottom
@@ -885,22 +854,12 @@ void DrawQ_SetClipArea(float x, float y, float width, float height)
 
 void DrawQ_ResetClipArea(void)
 {
-       if (!r_refdef.draw2dstage)
-       {
-               Con_Printf("DrawQ_ResetClipArea: not in 2d rendering stage!\n");
-               return;
-       }
+       _DrawQ_Setup();
        GL_ScissorTest(false);
 }
 
 void DrawQ_Finish(void)
 {
-       if (!r_refdef.draw2dstage)
-       {
-               Con_Printf("R_DrawQueue: not in 2d rendering stage!\n");
-               return;
-       }
-
        r_refdef.draw2dstage = false;
 }