2 Copyright (C) 1996-1997 Id Software, Inc.
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License
6 as published by the Free Software Foundation; either version 2
7 of the License, or (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13 See the GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21 // draw.c -- this is the only file outside the refresh that touches the
26 //#define GL_COLOR_INDEX8_EXT 0x80E5
28 cvar_t scr_conalpha = {CVAR_SAVE, "scr_conalpha", "1"};
30 byte *draw_chars; // 8*8 graphic characters
33 rtexture_t *char_texture;
40 rtexture_t *conbacktex;
42 //=============================================================================
43 /* Support Routines */
45 typedef struct cachepic_s
49 byte padding[32]; // for appended glpic
52 #define MAX_CACHED_PICS 128
53 cachepic_t menu_cachepics[MAX_CACHED_PICS];
54 int menu_numcachepics;
56 byte menuplyr_pixels[4096];
61 qpic_t *Draw_PicFromWad (char *name)
66 p = W_GetLumpName (name);
67 gl = (glpic_t *)p->data;
69 gl->tex = R_LoadTexture (name, p->width, p->height, p->data, TEXF_ALPHA | TEXF_PRECACHE);
79 qpic_t *Draw_CachePic (char *path)
86 for (pic=menu_cachepics, i=0 ; i<menu_numcachepics ; pic++, i++)
87 if (!strcmp (path, pic->name))
90 if (menu_numcachepics == MAX_CACHED_PICS)
91 Sys_Error ("menu_numcachepics == MAX_CACHED_PICS");
93 strcpy (pic->name, path);
96 // load the pic from disk
98 dat = (qpic_t *)COM_LoadMallocFile (path, false);
100 Sys_Error ("Draw_CachePic: failed to load %s", path);
103 // HACK HACK HACK --- we need to keep the bytes for
104 // the translatable player picture just for the menu
105 // configuration dialog
106 if (!strcmp (path, "gfx/menuplyr.lmp"))
107 memcpy (menuplyr_pixels, dat->data, dat->width*dat->height);
109 pic->pic.width = dat->width;
110 pic->pic.height = dat->height;
112 gl = (glpic_t *)pic->pic.data;
113 gl->tex = loadtextureimage(path, 0, 0, false, false, true);
115 gl->tex = R_LoadTexture (path, dat->width, dat->height, dat->data, TEXF_ALPHA | TEXF_PRECACHE);
127 void gl_draw_start(void)
131 char_texture = loadtextureimage ("conchars", 0, 0, false, false, true);
134 draw_chars = W_GetLumpName ("conchars");
135 for (i=0 ; i<128*128 ; i++)
136 if (draw_chars[i] == 0)
137 draw_chars[i] = 255; // proper transparent color
139 // now turn them into textures
140 char_texture = R_LoadTexture ("charset", 128, 128, draw_chars, TEXF_ALPHA | TEXF_PRECACHE);
143 conbacktex = loadtextureimage("gfx/conback", 0, 0, false, false, true);
145 // get the other pics we need
146 draw_disc = Draw_PicFromWad ("disc");
149 void gl_draw_shutdown(void)
153 void gl_draw_newmap(void)
157 extern char engineversion[40];
158 int engineversionx, engineversiony;
160 extern void R_Textures_Init();
161 void GL_Draw_Init (void)
164 Cvar_RegisterVariable (&scr_conalpha);
166 for (i = 0;i < 40 && engineversion[i];i++)
167 engineversion[i] += 0x80; // shift to orange
168 engineversionx = vid.conwidth - strlen(engineversion) * 8 - 8;
169 engineversiony = vid.conheight - 8;
172 R_RegisterModule("GL_Draw", gl_draw_start, gl_draw_shutdown, gl_draw_newmap);
179 Draws one 8*8 graphics character with 0 being transparent.
180 It can be clipped to the top of the screen to allow the console to be
181 smoothly scrolled off.
184 void Draw_Character (int x, int y, int num)
187 float frow, fcol, size;
195 return; // totally off screen
206 glBindTexture(GL_TEXTURE_2D, R_GetTexture(char_texture));
207 // LordHavoc: NEAREST mode on text if not scaling up
208 if (vid.realwidth <= (int) vid.conwidth)
210 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
211 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
215 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
216 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
220 glColor3f(0.5f,0.5f,0.5f);
222 glColor3f(1.0f,1.0f,1.0f);
224 glTexCoord2f (fcol, frow);
226 glTexCoord2f (fcol + size, frow);
228 glTexCoord2f (fcol + size, frow + size);
229 glVertex2f (x+8, y+8);
230 glTexCoord2f (fcol, frow + size);
234 // LordHavoc: revert to LINEAR mode
235 // if (vid.realwidth <= (int) vid.conwidth)
237 // glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
238 // glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
247 // LordHavoc: sped this up a lot, and added maxlen
248 void Draw_String (int x, int y, char *str, int maxlen)
254 if (y <= -8 || y >= (int) vid.conheight || x >= (int) vid.conwidth || *str == 0) // completely offscreen or no text to print
257 maxlen = strlen(str);
258 else if (maxlen > (int) strlen(str))
259 maxlen = strlen(str);
260 glBindTexture(GL_TEXTURE_2D, R_GetTexture(char_texture));
262 // LordHavoc: NEAREST mode on text if not scaling up
263 if (vid.realwidth <= (int) vid.conwidth)
265 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
266 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
270 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
271 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
275 glColor3f(0.5f,0.5f,0.5f);
277 glColor3f(1.0f,1.0f,1.0f);
279 while (maxlen-- && x < (int) vid.conwidth) // stop rendering when out of characters or room
281 if ((num = *str++) != 32) // skip spaces
283 frow = (float) ((int) num >> 4)*0.0625;
284 fcol = (float) ((int) num & 15)*0.0625;
285 glTexCoord2f (fcol , frow );glVertex2f (x, y);
286 glTexCoord2f (fcol + 0.0625, frow );glVertex2f (x+8, y);
287 glTexCoord2f (fcol + 0.0625, frow + 0.0625);glVertex2f (x+8, y+8);
288 glTexCoord2f (fcol , frow + 0.0625);glVertex2f (x, y+8);
294 // LordHavoc: revert to LINEAR mode
295 // if (vid.realwidth < (int) vid.conwidth)
297 // glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
298 // glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
302 void Draw_AdditiveString (int x, int y, char *str, int maxlen)
306 glBlendFunc(GL_SRC_ALPHA, GL_ONE);
307 Draw_String(x, y, str, maxlen);
308 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
311 void Draw_GenericPic (rtexture_t *tex, float red, float green, float blue, float alpha, int x, int y, int width, int height)
316 glColor4f(red * 0.5f, green * 0.5f, blue * 0.5f, alpha);
318 glColor4f(red, green, blue, alpha);
319 glBindTexture(GL_TEXTURE_2D, R_GetTexture(tex));
321 glTexCoord2f (0, 0);glVertex2f (x, y);
322 glTexCoord2f (1, 0);glVertex2f (x+width, y);
323 glTexCoord2f (1, 1);glVertex2f (x+width, y+height);
324 glTexCoord2f (0, 1);glVertex2f (x, y+height);
333 void Draw_AlphaPic (int x, int y, qpic_t *pic, float alpha)
336 Draw_GenericPic(((glpic_t *)pic->data)->tex, 1,1,1,alpha, x,y,pic->width, pic->height);
345 void Draw_Pic (int x, int y, qpic_t *pic)
348 Draw_GenericPic(((glpic_t *)pic->data)->tex, 1,1,1,1, x,y,pic->width, pic->height);
352 void Draw_AdditivePic (int x, int y, qpic_t *pic)
356 glBlendFunc(GL_SRC_ALPHA, GL_ONE);
357 Draw_GenericPic(((glpic_t *)pic->data)->tex, 1,1,1,1, x,y,pic->width, pic->height);
358 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
367 Only used for the player color selection menu
370 void Draw_PicTranslate (int x, int y, qpic_t *pic, byte *translation)
373 byte *trans, *src, *dest;
379 c = pic->width * pic->height;
380 src = menuplyr_pixels;
381 dest = trans = qmalloc(c);
382 for (i = 0;i < c;i++)
383 *dest++ = translation[*src++];
385 rt = R_LoadTexture ("translatedplayerpic", pic->width, pic->height, trans, TEXF_ALPHA | TEXF_PRECACHE);
390 Draw_GenericPic (rt, 1,1,1,1, x, y, pic->width, pic->height);
396 Draw_ConsoleBackground
400 void Draw_ConsoleBackground (int lines)
402 Draw_GenericPic (conbacktex, 1,1,1,scr_conalpha.value * lines / vid.conheight, 0, lines - vid.conheight, vid.conwidth, vid.conheight);
403 // LordHavoc: draw version
404 Draw_String(engineversionx, lines - vid.conheight + engineversiony, engineversion, 9999);
411 Fills a box of pixels with a single color
414 void Draw_Fill (int x, int y, int w, int h, int c)
418 glDisable (GL_TEXTURE_2D);
421 byte *tempcolor = (byte *)&d_8to24table[c];
422 glColor4ub ((byte) (tempcolor[0] >> 1), (byte) (tempcolor[1] >> 1), (byte) (tempcolor[2] >> 1), tempcolor[3]);
425 glColor4ubv ((byte *)&d_8to24table[c]);
431 glVertex2f (x+w, y+h);
436 glEnable (GL_TEXTURE_2D);
438 //=============================================================================
440 //=============================================================================
446 Setup as if the screen was 320*200
453 glViewport (vid.realx, vid.realy, vid.realwidth, vid.realheight);
455 glMatrixMode(GL_PROJECTION);
457 glOrtho (0, vid.conwidth, vid.conheight, 0, -99999, 99999);
459 glMatrixMode(GL_MODELVIEW);
462 glDisable (GL_DEPTH_TEST);
463 glDisable (GL_CULL_FACE);
465 glDisable (GL_ALPHA_TEST);
466 glEnable(GL_TEXTURE_2D);
468 // LordHavoc: added this
469 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
470 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
475 // LordHavoc: SHOWLMP stuff
476 #define SHOWLMP_MAXLABELS 256
477 typedef struct showlmp_s
486 showlmp_t showlmp[SHOWLMP_MAXLABELS];
488 void SHOWLMP_decodehide(void)
492 lmplabel = MSG_ReadString();
493 for (i = 0;i < SHOWLMP_MAXLABELS;i++)
494 if (showlmp[i].isactive && strcmp(showlmp[i].label, lmplabel) == 0)
496 showlmp[i].isactive = false;
501 void SHOWLMP_decodeshow(void)
504 byte lmplabel[256], picname[256];
506 strcpy(lmplabel,MSG_ReadString());
507 strcpy(picname, MSG_ReadString());
508 if (gamemode == GAME_NEHAHRA) // LordHavoc: nasty old legacy junk
519 for (i = 0;i < SHOWLMP_MAXLABELS;i++)
520 if (showlmp[i].isactive)
522 if (strcmp(showlmp[i].label, lmplabel) == 0)
525 break; // drop out to replace it
528 else if (k < 0) // find first empty one to replace
531 return; // none found to replace
532 // change existing one
533 showlmp[k].isactive = true;
534 strcpy(showlmp[k].label, lmplabel);
535 strcpy(showlmp[k].pic, picname);
540 void SHOWLMP_drawall(void)
543 for (i = 0;i < SHOWLMP_MAXLABELS;i++)
544 if (showlmp[i].isactive)
545 Draw_Pic(showlmp[i].x, showlmp[i].y, Draw_CachePic(showlmp[i].pic));
548 void SHOWLMP_clear(void)
551 for (i = 0;i < SHOWLMP_MAXLABELS;i++)
552 showlmp[i].isactive = false;