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 qsg_version = {"qsg_version", "1"};
29 cvar_t scr_conalpha = {"scr_conalpha", "1"};
31 byte *draw_chars; // 8*8 graphic characters
43 //=============================================================================
44 /* Support Routines */
46 typedef struct cachepic_s
50 byte padding[32]; // for appended glpic
53 #define MAX_CACHED_PICS 128
54 cachepic_t menu_cachepics[MAX_CACHED_PICS];
55 int menu_numcachepics;
57 byte menuplyr_pixels[4096];
62 qpic_t *Draw_PicFromWad (char *name)
67 p = W_GetLumpName (name);
68 gl = (glpic_t *)p->data;
70 gl->texnum = GL_LoadTexture (name, p->width, p->height, p->data, false, true, 1);
80 qpic_t *Draw_CachePic (char *path)
87 for (pic=menu_cachepics, i=0 ; i<menu_numcachepics ; pic++, i++)
88 if (!strcmp (path, pic->name))
91 if (menu_numcachepics == MAX_CACHED_PICS)
92 Sys_Error ("menu_numcachepics == MAX_CACHED_PICS");
94 strcpy (pic->name, path);
97 // load the pic from disk
99 dat = (qpic_t *)COM_LoadMallocFile (path, false);
101 Sys_Error ("Draw_CachePic: failed to load %s", path);
104 // HACK HACK HACK --- we need to keep the bytes for
105 // the translatable player picture just for the menu
106 // configuration dialog
107 if (!strcmp (path, "gfx/menuplyr.lmp"))
108 memcpy (menuplyr_pixels, dat->data, dat->width*dat->height);
110 pic->pic.width = dat->width;
111 pic->pic.height = dat->height;
113 gl = (glpic_t *)pic->pic.data;
114 gl->texnum = loadtextureimage(path, 0, 0, false, false);
116 gl->texnum = GL_LoadTexture (path, dat->width, dat->height, dat->data, false, true, 1);
123 extern void LoadSky_f(void);
130 void rmain_registercvars();
136 char_texture = loadtextureimage ("conchars", 0, 0, false, false);
139 draw_chars = W_GetLumpName ("conchars");
140 for (i=0 ; i<128*128 ; i++)
141 if (draw_chars[i] == 0)
142 draw_chars[i] = 255; // proper transparent color
144 // now turn them into textures
145 char_texture = GL_LoadTexture ("charset", 128, 128, draw_chars, false, true, 1);
148 conbacktexnum = loadtextureimage("gfx/conback", 0, 0, false, false);
150 // get the other pics we need
151 draw_disc = Draw_PicFromWad ("disc");
154 void gl_draw_shutdown()
158 char engineversion[40];
159 int engineversionx, engineversiony;
161 extern void GL_Textures_Init();
162 void GL_Draw_Init (void)
165 Cvar_RegisterVariable (&qsg_version);
166 Cvar_RegisterVariable (&scr_conalpha);
168 Cmd_AddCommand ("loadsky", &LoadSky_f);
170 #if defined(__linux__)
171 sprintf (engineversion, "DarkPlaces Linux GL %.2f build %3i", (float) VERSION, buildnumber);
173 sprintf (engineversion, "DarkPlaces Windows GL %.2f build %3i", (float) VERSION, buildnumber);
175 sprintf (engineversion, "DarkPlaces Unknown GL %.2f build %3i", (float) VERSION, buildnumber);
177 for (i = 0;i < 40 && engineversion[i];i++)
178 engineversion[i] += 0x80; // shift to orange
179 engineversionx = vid.width - strlen(engineversion) * 8 - 8;
180 engineversiony = vid.height - 8;
183 R_RegisterModule("GL_Draw", gl_draw_start, gl_draw_shutdown);
190 Draws one 8*8 graphics character with 0 being transparent.
191 It can be clipped to the top of the screen to allow the console to be
192 smoothly scrolled off.
195 void Draw_Character (int x, int y, int num)
198 float frow, fcol, size;
206 return; // totally off screen
217 glBindTexture(GL_TEXTURE_2D, char_texture);
218 // LordHavoc: NEAREST mode on text if not scaling up
219 if (glwidth < (int) vid.width)
221 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
222 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
227 glTexCoord2f (fcol, frow);
229 glTexCoord2f (fcol + size, frow);
231 glTexCoord2f (fcol + size, frow + size);
232 glVertex2f (x+8, y+8);
233 glTexCoord2f (fcol, frow + size);
237 // LordHavoc: revert to LINEAR mode
238 if (glwidth < (int) vid.width)
240 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
241 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
250 // LordHavoc: sped this up a lot, and added maxlen
251 void Draw_String (int x, int y, char *str, int maxlen)
257 if (y <= -8 || y >= (int) vid.height || x >= (int) vid.width || *str == 0) // completely offscreen or no text to print
260 maxlen = strlen(str);
261 else if (maxlen > (int) strlen(str))
262 maxlen = strlen(str);
263 glBindTexture(GL_TEXTURE_2D, char_texture);
265 // LordHavoc: NEAREST mode on text if not scaling up
266 if (glwidth < (int) vid.width)
268 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
269 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
274 while (maxlen-- && x < (int) vid.width) // stop rendering when out of characters or room
276 if ((num = *str++) != 32) // skip spaces
278 frow = (float) ((int) num >> 4)*0.0625;
279 fcol = (float) ((int) num & 15)*0.0625;
280 glTexCoord2f (fcol , frow );glVertex2f (x, y);
281 glTexCoord2f (fcol + 0.0625, frow );glVertex2f (x+8, y);
282 glTexCoord2f (fcol + 0.0625, frow + 0.0625);glVertex2f (x+8, y+8);
283 glTexCoord2f (fcol , frow + 0.0625);glVertex2f (x, y+8);
289 // LordHavoc: revert to LINEAR mode
290 if (glwidth < (int) vid.width)
292 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
293 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
297 void Draw_GenericPic (int texnum, float red, float green, float blue, float alpha, int x, int y, int width, int height)
301 glColor4f(red,green,blue,alpha);
302 glBindTexture(GL_TEXTURE_2D, texnum);
304 glTexCoord2f (0, 0);glVertex2f (x, y);
305 glTexCoord2f (1, 0);glVertex2f (x+width, y);
306 glTexCoord2f (1, 1);glVertex2f (x+width, y+height);
307 glTexCoord2f (0, 1);glVertex2f (x, y+height);
316 void Draw_AlphaPic (int x, int y, qpic_t *pic, float alpha)
318 Draw_GenericPic(((glpic_t *)pic->data)->texnum, 1,1,1,alpha, x,y,pic->width, pic->height);
327 void Draw_Pic (int x, int y, qpic_t *pic)
329 Draw_GenericPic(((glpic_t *)pic->data)->texnum, 1,1,1,1, x,y,pic->width, pic->height);
337 Only used for the player color selection menu
340 void Draw_PicTranslate (int x, int y, qpic_t *pic, byte *translation)
343 byte *trans, *src, *dest;
345 c = pic->width * pic->height;
346 src = menuplyr_pixels;
347 dest = trans = qmalloc(c);
348 for (i = 0;i < c;i++)
349 *dest++ = translation[*src++];
351 c = GL_LoadTexture ("translatedplayerpic", pic->width, pic->height, trans, false, true, 1);
356 Draw_GenericPic (c, 1,1,1,1, x, y, pic->width, pic->height);
362 Draw_ConsoleBackground
366 void Draw_ConsoleBackground (int lines)
368 Draw_GenericPic (conbacktexnum, 1,1,1,scr_conalpha.value*lines/vid.height, 0, lines - vid.height, vid.width, vid.height);
369 // LordHavoc: draw version
370 Draw_String(engineversionx, lines - vid.height + engineversiony, engineversion, 9999);
377 Fills a box of pixels with a single color
380 void Draw_Fill (int x, int y, int w, int h, int c)
384 glDisable (GL_TEXTURE_2D);
385 glColor3f (host_basepal[c*3]/255.0, host_basepal[c*3+1]/255.0, host_basepal[c*3+2]/255.0);
391 glVertex2f (x+w, y+h);
396 glEnable (GL_TEXTURE_2D);
398 //=============================================================================
400 //=============================================================================
406 Setup as if the screen was 320*200
413 glViewport (glx, gly, glwidth, glheight);
415 glMatrixMode(GL_PROJECTION);
417 glOrtho (0, vid.width, vid.height, 0, -99999, 99999);
419 glMatrixMode(GL_MODELVIEW);
422 glDisable (GL_DEPTH_TEST);
423 glDisable (GL_CULL_FACE);
425 glDisable (GL_ALPHA_TEST);
426 glEnable(GL_TEXTURE_2D);
428 // LordHavoc: added this
429 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
430 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
435 // LordHavoc: SHOWLMP stuff
436 #define SHOWLMP_MAXLABELS 256
437 typedef struct showlmp_s
446 showlmp_t showlmp[SHOWLMP_MAXLABELS];
448 void SHOWLMP_decodehide()
452 lmplabel = MSG_ReadString();
453 for (i = 0;i < SHOWLMP_MAXLABELS;i++)
454 if (showlmp[i].isactive && strcmp(showlmp[i].label, lmplabel) == 0)
456 showlmp[i].isactive = false;
461 void SHOWLMP_decodeshow()
464 byte lmplabel[256], picname[256];
466 strcpy(lmplabel,MSG_ReadString());
467 strcpy(picname, MSG_ReadString());
471 for (i = 0;i < SHOWLMP_MAXLABELS;i++)
472 if (showlmp[i].isactive)
474 if (strcmp(showlmp[i].label, lmplabel) == 0)
477 break; // drop out to replace it
480 else if (k < 0) // find first empty one to replace
483 return; // none found to replace
484 // change existing one
485 showlmp[k].isactive = true;
486 strcpy(showlmp[k].label, lmplabel);
487 strcpy(showlmp[k].pic, picname);
492 void SHOWLMP_drawall()
495 for (i = 0;i < SHOWLMP_MAXLABELS;i++)
496 if (showlmp[i].isactive)
497 Draw_Pic(showlmp[i].x, showlmp[i].y, Draw_CachePic(showlmp[i].pic));
503 for (i = 0;i < SHOWLMP_MAXLABELS;i++)
504 showlmp[i].isactive = false;