This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
*/
-// draw.c -- this is the only file outside the refresh that touches the
-// vid buffer
-
#include "quakedef.h"
//#define GL_COLOR_INDEX8_EXT 0x80E5
-cvar_t scr_conalpha = {"scr_conalpha", "1"};
-
-byte *draw_chars; // 8*8 graphic characters
-qpic_t *draw_disc;
+cvar_t scr_conalpha = {CVAR_SAVE, "scr_conalpha", "1"};
rtexture_t *char_texture;
typedef struct cachepic_s
{
char name[MAX_QPATH];
+ // FIXME: qpic is evil
qpic_t pic;
byte padding[32]; // for appended glpic
-} cachepic_t;
+}
+cachepic_t;
-#define MAX_CACHED_PICS 128
+#define MAX_CACHED_PICS 256
cachepic_t menu_cachepics[MAX_CACHED_PICS];
int menu_numcachepics;
byte menuplyr_pixels[4096];
-int pic_texels;
-int pic_count;
-
-qpic_t *Draw_PicFromWad (char *name)
-{
- qpic_t *p;
- glpic_t *gl;
-
- p = W_GetLumpName (name);
- gl = (glpic_t *)p->data;
-
- gl->tex = R_LoadTexture (name, p->width, p->height, p->data, TEXF_ALPHA | TEXF_PRECACHE);
- return p;
-}
+int pic_texels;
+int pic_count;
+rtexturepool_t *drawtexturepool;
/*
================
Draw_CachePic
================
*/
+// FIXME: qpic is evil
qpic_t *Draw_CachePic (char *path)
{
cachepic_t *pic;
int i;
qpic_t *dat;
glpic_t *gl;
+ rtexture_t *tex;
- for (pic=menu_cachepics, i=0 ; i<menu_numcachepics ; pic++, i++)
+ for (pic = menu_cachepics, i = 0;i < menu_numcachepics;pic++, i++)
if (!strcmp (path, pic->name))
return &pic->pic;
menu_numcachepics++;
strcpy (pic->name, path);
-//
-// load the pic from disk
-//
- dat = (qpic_t *)COM_LoadMallocFile (path, false);
- if (!dat)
- Sys_Error ("Draw_CachePic: failed to load %s", path);
- SwapPic (dat);
-
+ // FIXME: move this to menu code
// HACK HACK HACK --- we need to keep the bytes for
// the translatable player picture just for the menu
// configuration dialog
if (!strcmp (path, "gfx/menuplyr.lmp"))
- memcpy (menuplyr_pixels, dat->data, dat->width*dat->height);
-
- pic->pic.width = dat->width;
- pic->pic.height = dat->height;
-
- gl = (glpic_t *)pic->pic.data;
- gl->tex = loadtextureimage(path, 0, 0, false, false, true);
- if (!gl->tex)
- gl->tex = R_LoadTexture (path, dat->width, dat->height, dat->data, TEXF_ALPHA | TEXF_PRECACHE);
+ {
+ dat = (qpic_t *)COM_LoadFile (path, false);
+ if (!dat)
+ Sys_Error("unable to load gfx/menuplyr.lmp");
+ SwapPic (dat);
- qfree(dat);
+ memcpy (menuplyr_pixels, dat->data, dat->width*dat->height);
+ }
- return &pic->pic;
+ // load the pic from disk
+ if ((tex = loadtextureimage(drawtexturepool, path, 0, 0, false, false, true)))
+ {
+ // load the pic from an image file
+ pic->pic.width = image_width;
+ pic->pic.height = image_height;
+ gl = (glpic_t *)pic->pic.data;
+ gl->tex = tex;
+ return &pic->pic;
+ }
+ else
+ {
+ qpic_t *p;
+ // load the pic from gfx.wad
+ p = W_GetLumpName (path);
+ if (!p)
+ Sys_Error ("Draw_CachePic: failed to load %s", path);
+ pic->pic.width = p->width;
+ pic->pic.height = p->height;
+ gl = (glpic_t *)pic->pic.data;
+ gl->tex = R_LoadTexture (drawtexturepool, path, p->width, p->height, p->data, TEXTYPE_QPALETTE, TEXF_ALPHA | TEXF_PRECACHE);
+ return &pic->pic;
+ }
}
-extern void LoadSky_f(void);
-
/*
===============
Draw_Init
===============
*/
-void rmain_registercvars();
-
-void gl_draw_start()
+static void gl_draw_start(void)
{
- int i;
+ int i;
+ byte *draw_chars;
- char_texture = loadtextureimage ("conchars", 0, 0, false, false, true);
+ menu_numcachepics = 0;
+
+ drawtexturepool = R_AllocTexturePool();
+ char_texture = loadtextureimage (drawtexturepool, "conchars", 0, 0, false, false, true);
if (!char_texture)
{
draw_chars = W_GetLumpName ("conchars");
- for (i=0 ; i<128*128 ; i++)
+ // convert font to proper transparent color
+ for (i = 0;i < 128 * 128;i++)
if (draw_chars[i] == 0)
- draw_chars[i] = 255; // proper transparent color
+ draw_chars[i] = 255;
- // now turn them into textures
- char_texture = R_LoadTexture ("charset", 128, 128, draw_chars, TEXF_ALPHA | TEXF_PRECACHE);
+ // now turn into texture
+ char_texture = R_LoadTexture (drawtexturepool, "charset", 128, 128, draw_chars, TEXTYPE_QPALETTE, TEXF_ALPHA | TEXF_PRECACHE);
}
- conbacktex = loadtextureimage("gfx/conback", 0, 0, false, false, true);
-
- // get the other pics we need
- draw_disc = Draw_PicFromWad ("disc");
+ conbacktex = loadtextureimage(drawtexturepool, "gfx/conback", 0, 0, false, false, true);
}
-void gl_draw_shutdown()
+static void gl_draw_shutdown(void)
{
+ R_FreeTexturePool(&drawtexturepool);
+
+ menu_numcachepics = 0;
}
-void gl_draw_newmap()
+void SHOWLMP_clear(void);
+static void gl_draw_newmap(void)
{
+ SHOWLMP_clear();
}
-char engineversion[40];
+extern char engineversion[40];
int engineversionx, engineversiony;
-extern void R_Textures_Init();
void GL_Draw_Init (void)
{
int i;
Cvar_RegisterVariable (&scr_conalpha);
- Cmd_AddCommand ("loadsky", &LoadSky_f);
-
-#if defined(__linux__)
- sprintf (engineversion, "DarkPlaces Linux GL %.2f build %3i", (float) VERSION, buildnumber);
-#elif defined(WIN32)
- sprintf (engineversion, "DarkPlaces Windows GL %.2f build %3i", (float) VERSION, buildnumber);
-#else
- sprintf (engineversion, "DarkPlaces Unknown GL %.2f build %3i", (float) VERSION, buildnumber);
-#endif
for (i = 0;i < 40 && engineversion[i];i++)
- engineversion[i] += 0x80; // shift to orange
- engineversionx = vid.width - strlen(engineversion) * 8 - 8;
- engineversiony = vid.height - 8;
+ engineversion[i] |= 0x80; // shift to orange
+ engineversionx = vid.conwidth - strlen(engineversion) * 8 - 8;
+ engineversiony = vid.conheight - 8;
+
+ menu_numcachepics = 0;
- R_Textures_Init();
R_RegisterModule("GL_Draw", gl_draw_start, gl_draw_shutdown, gl_draw_newmap);
}
fcol = col*0.0625;
size = 0.0625;
- if (!r_render.value)
+ if (!r_render.integer)
return;
glBindTexture(GL_TEXTURE_2D, R_GetTexture(char_texture));
+ CHECKGLERROR
// LordHavoc: NEAREST mode on text if not scaling up
- if (glwidth <= (int) vid.width)
+ if (vid.realwidth <= (int) vid.conwidth)
{
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ CHECKGLERROR
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ CHECKGLERROR
}
else
{
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ CHECKGLERROR
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ CHECKGLERROR
}
if (lighthalf)
glColor3f(0.5f,0.5f,0.5f);
else
glColor3f(1.0f,1.0f,1.0f);
+ CHECKGLERROR
glBegin (GL_QUADS);
glTexCoord2f (fcol, frow);
glVertex2f (x, y);
glTexCoord2f (fcol, frow + size);
glVertex2f (x, y+8);
glEnd ();
+ CHECKGLERROR
// LordHavoc: revert to LINEAR mode
-// if (glwidth < (int) vid.width)
+// if (vid.realwidth <= (int) vid.conwidth)
// {
// glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
// glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
{
int num;
float frow, fcol;
- if (!r_render.value)
+ if (!r_render.integer)
return;
- if (y <= -8 || y >= (int) vid.height || x >= (int) vid.width || *str == 0) // completely offscreen or no text to print
+ if (y <= -8 || y >= (int) vid.conheight || x >= (int) vid.conwidth || *str == 0) // completely offscreen or no text to print
return;
if (maxlen < 1)
maxlen = strlen(str);
glBindTexture(GL_TEXTURE_2D, R_GetTexture(char_texture));
// LordHavoc: NEAREST mode on text if not scaling up
- if (glwidth <= (int) vid.width)
+ if (vid.realwidth <= (int) vid.conwidth)
{
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ CHECKGLERROR
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ CHECKGLERROR
}
else
{
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ CHECKGLERROR
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ CHECKGLERROR
}
if (lighthalf)
glColor3f(0.5f,0.5f,0.5f);
else
glColor3f(1.0f,1.0f,1.0f);
+ CHECKGLERROR
glBegin (GL_QUADS);
- while (maxlen-- && x < (int) vid.width) // stop rendering when out of characters or room
+ while (maxlen-- && x < (int) vid.conwidth) // stop rendering when out of characters or room
{
if ((num = *str++) != 32) // skip spaces
{
x += 8;
}
glEnd ();
+ CHECKGLERROR
// LordHavoc: revert to LINEAR mode
-// if (glwidth < (int) vid.width)
+// if (vid.realwidth < (int) vid.conwidth)
// {
// glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
// glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
// }
}
+void Draw_AdditiveString (int x, int y, char *str, int maxlen)
+{
+ if (!r_render.integer)
+ return;
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE);
+ CHECKGLERROR
+ Draw_String(x, y, str, maxlen);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ CHECKGLERROR
+}
+
void Draw_GenericPic (rtexture_t *tex, float red, float green, float blue, float alpha, int x, int y, int width, int height)
{
- if (!r_render.value)
+ if (!r_render.integer)
return;
if (lighthalf)
glColor4f(red * 0.5f, green * 0.5f, blue * 0.5f, alpha);
else
glColor4f(red, green, blue, alpha);
+ CHECKGLERROR
glBindTexture(GL_TEXTURE_2D, R_GetTexture(tex));
+ CHECKGLERROR
glBegin (GL_QUADS);
glTexCoord2f (0, 0);glVertex2f (x, y);
glTexCoord2f (1, 0);glVertex2f (x+width, y);
glTexCoord2f (1, 1);glVertex2f (x+width, y+height);
glTexCoord2f (0, 1);glVertex2f (x, y+height);
glEnd ();
+ CHECKGLERROR
}
/*
*/
void Draw_AlphaPic (int x, int y, qpic_t *pic, float alpha)
{
- Draw_GenericPic(((glpic_t *)pic->data)->tex, 1,1,1,alpha, x,y,pic->width, pic->height);
+ if (pic)
+ Draw_GenericPic(((glpic_t *)pic->data)->tex, 1,1,1,alpha, x,y,pic->width, pic->height);
}
*/
void Draw_Pic (int x, int y, qpic_t *pic)
{
- Draw_GenericPic(((glpic_t *)pic->data)->tex, 1,1,1,1, x,y,pic->width, pic->height);
+ if (pic)
+ Draw_GenericPic(((glpic_t *)pic->data)->tex, 1,1,1,1, x,y,pic->width, pic->height);
+}
+
+
+void Draw_AdditivePic (int x, int y, qpic_t *pic)
+{
+ if (pic)
+ {
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE);
+ CHECKGLERROR
+ Draw_GenericPic(((glpic_t *)pic->data)->tex, 1,1,1,1, x,y,pic->width, pic->height);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ CHECKGLERROR
+ }
}
byte *trans, *src, *dest;
rtexture_t *rt;
+ if (pic == NULL)
+ return;
+
c = pic->width * pic->height;
src = menuplyr_pixels;
- dest = trans = qmalloc(c);
+ dest = trans = Mem_Alloc(tempmempool, c);
for (i = 0;i < c;i++)
*dest++ = translation[*src++];
- rt = R_LoadTexture ("translatedplayerpic", pic->width, pic->height, trans, TEXF_ALPHA | TEXF_PRECACHE);
- qfree(trans);
+ rt = R_LoadTexture (drawtexturepool, "translatedplayerpic", pic->width, pic->height, trans, TEXTYPE_QPALETTE, TEXF_ALPHA | TEXF_PRECACHE);
+ Mem_Free(trans);
- if (!r_render.value)
+ if (!r_render.integer)
return;
Draw_GenericPic (rt, 1,1,1,1, x, y, pic->width, pic->height);
}
*/
void Draw_ConsoleBackground (int lines)
{
- Draw_GenericPic (conbacktex, 1,1,1,scr_conalpha.value*lines/vid.height, 0, lines - vid.height, vid.width, vid.height);
+ Draw_GenericPic (conbacktex, 1,1,1,scr_conalpha.value * lines / vid.conheight, 0, lines - vid.conheight, vid.conwidth, vid.conheight);
// LordHavoc: draw version
- Draw_String(engineversionx, lines - vid.height + engineversiony, engineversion, 9999);
+ Draw_String(engineversionx, lines - vid.conheight + engineversiony, engineversion, 9999);
}
/*
*/
void Draw_Fill (int x, int y, int w, int h, int c)
{
- if (!r_render.value)
+ if (!r_render.integer)
return;
glDisable (GL_TEXTURE_2D);
+ CHECKGLERROR
if (lighthalf)
{
byte *tempcolor = (byte *)&d_8to24table[c];
}
else
glColor4ubv ((byte *)&d_8to24table[c]);
+ CHECKGLERROR
glBegin (GL_QUADS);
glVertex2f (x, y+h);
glEnd ();
+ CHECKGLERROR
glColor3f(1,1,1);
+ CHECKGLERROR
glEnable (GL_TEXTURE_2D);
+ CHECKGLERROR
}
//=============================================================================
*/
void GL_Set2D (void)
{
- if (!r_render.value)
+ if (!r_render.integer)
return;
- glViewport (glx, gly, glwidth, glheight);
+ glViewport (vid.realx, vid.realy, vid.realwidth, vid.realheight);
+ CHECKGLERROR
glMatrixMode(GL_PROJECTION);
+ CHECKGLERROR
glLoadIdentity ();
- glOrtho (0, vid.width, vid.height, 0, -99999, 99999);
+ CHECKGLERROR
+ glOrtho (0, vid.conwidth, vid.conheight, 0, -99999, 99999);
+ CHECKGLERROR
glMatrixMode(GL_MODELVIEW);
+ CHECKGLERROR
glLoadIdentity ();
+ CHECKGLERROR
glDisable (GL_DEPTH_TEST);
+ CHECKGLERROR
glDisable (GL_CULL_FACE);
+ CHECKGLERROR
glEnable (GL_BLEND);
- glDisable (GL_ALPHA_TEST);
+ CHECKGLERROR
glEnable(GL_TEXTURE_2D);
+ CHECKGLERROR
// LordHavoc: added this
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ CHECKGLERROR
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+ CHECKGLERROR
glColor3f(1,1,1);
+ CHECKGLERROR
}
// LordHavoc: SHOWLMP stuff
showlmp_t showlmp[SHOWLMP_MAXLABELS];
-void SHOWLMP_decodehide()
+void SHOWLMP_decodehide(void)
{
int i;
byte *lmplabel;
}
}
-void SHOWLMP_decodeshow()
+void SHOWLMP_decodeshow(void)
{
int i, k;
byte lmplabel[256], picname[256];
float x, y;
strcpy(lmplabel,MSG_ReadString());
strcpy(picname, MSG_ReadString());
- if (nehahra) // LordHavoc: nasty old legacy junk
+ if (gamemode == GAME_NEHAHRA) // LordHavoc: nasty old legacy junk
{
x = MSG_ReadByte();
y = MSG_ReadByte();
showlmp[k].y = y;
}
-void SHOWLMP_drawall()
+void SHOWLMP_drawall(void)
{
int i;
for (i = 0;i < SHOWLMP_MAXLABELS;i++)
Draw_Pic(showlmp[i].x, showlmp[i].y, Draw_CachePic(showlmp[i].pic));
}
-void SHOWLMP_clear()
+void SHOWLMP_clear(void)
{
int i;
for (i = 0;i < SHOWLMP_MAXLABELS;i++)