yquake2remaster/src/refresh/r_draw.c

414 lines
7.4 KiB
C
Raw Normal View History

/*
2010-10-20 08:49:28 +00:00
* Copyright (C) 1997-2001 Id Software, Inc.
*
2010-10-21 07:29:20 +00:00
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or (at
* your option) any later version.
2010-10-20 08:49:28 +00:00
*
2010-10-21 07:29:20 +00:00
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
2010-10-20 08:49:28 +00:00
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
2010-10-21 07:29:20 +00:00
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
2010-10-20 08:49:28 +00:00
*
2010-10-21 07:29:20 +00:00
* =======================================================================
*
* Drawing of all images that are not textures
*
* =======================================================================
2012-04-29 13:57:33 +00:00
*/
2009-03-05 11:03:08 +00:00
#include "header/local.h"
2012-07-21 12:09:45 +00:00
image_t *draw_chars;
2010-10-20 08:49:28 +00:00
extern qboolean scrap_dirty;
2012-07-21 12:09:45 +00:00
void Scrap_Upload(void);
extern unsigned r_rawpalette[256];
2010-10-20 08:49:28 +00:00
void
2012-07-21 12:09:45 +00:00
Draw_InitLocal(void)
{
2010-10-20 08:49:28 +00:00
/* load console characters (don't bilerp characters) */
2012-07-21 12:09:45 +00:00
draw_chars = R_FindImage("pics/conchars.pcx", it_pic);
R_Bind(draw_chars->texnum);
qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
}
/*
2010-10-20 08:49:28 +00:00
* Draws one 8*8 graphics character with 0 being transparent.
* It can be clipped to the top of the screen to allow the console to be
* smoothly scrolled off.
*/
void
2012-07-21 12:09:45 +00:00
Draw_Char(int x, int y, int num)
{
2010-10-20 08:49:28 +00:00
int row, col;
float frow, fcol, size;
num &= 255;
2012-07-21 12:09:45 +00:00
if ((num & 127) == 32)
2010-10-20 08:49:28 +00:00
{
return; /* space */
}
2012-07-21 12:09:45 +00:00
if (y <= -8)
2010-10-20 08:49:28 +00:00
{
return; /* totally off screen */
}
2010-10-20 08:49:28 +00:00
row = num >> 4;
col = num & 15;
2010-10-20 08:49:28 +00:00
frow = row * 0.0625;
fcol = col * 0.0625;
size = 0.0625;
2012-07-21 12:09:45 +00:00
R_Bind(draw_chars->texnum);
qglBegin(GL_QUADS);
qglTexCoord2f(fcol, frow);
qglVertex2f(x, y);
qglTexCoord2f(fcol + size, frow);
qglVertex2f(x + 8, y);
qglTexCoord2f(fcol + size, frow + size);
qglVertex2f(x + 8, y + 8);
qglTexCoord2f(fcol, frow + size);
qglVertex2f(x, y + 8);
2010-10-20 08:49:28 +00:00
qglEnd();
}
2010-10-20 08:49:28 +00:00
image_t *
2012-07-21 12:09:45 +00:00
Draw_FindPic(char *name)
{
image_t *gl;
2012-07-21 12:09:45 +00:00
char fullname[MAX_QPATH];
2012-07-21 12:09:45 +00:00
if ((name[0] != '/') && (name[0] != '\\'))
{
2012-07-21 12:09:45 +00:00
Com_sprintf(fullname, sizeof(fullname), "pics/%s.pcx", name);
gl = R_FindImage(fullname, it_pic);
}
else
2010-10-20 08:49:28 +00:00
{
2012-07-21 12:09:45 +00:00
gl = R_FindImage(name + 1, it_pic);
2010-10-20 08:49:28 +00:00
}
2012-07-21 12:09:45 +00:00
return gl;
}
2010-10-20 08:49:28 +00:00
void
2012-07-21 12:09:45 +00:00
Draw_GetPicSize(int *w, int *h, char *pic)
{
image_t *gl;
2012-07-21 12:09:45 +00:00
gl = Draw_FindPic(pic);
2010-10-20 08:49:28 +00:00
2012-07-21 12:09:45 +00:00
if (!gl)
{
*w = *h = -1;
return;
}
2010-10-20 08:49:28 +00:00
*w = gl->width;
*h = gl->height;
}
2010-10-20 08:49:28 +00:00
void
2012-07-21 12:09:45 +00:00
Draw_StretchPic(int x, int y, int w, int h, char *pic)
{
image_t *gl;
2012-07-21 12:09:45 +00:00
gl = Draw_FindPic(pic);
2010-10-20 08:49:28 +00:00
2012-07-21 12:09:45 +00:00
if (!gl)
{
2012-07-21 12:09:45 +00:00
ri.Con_Printf(PRINT_ALL, "Can't find pic: %s\n", pic);
return;
}
2012-07-21 12:09:45 +00:00
if (scrap_dirty)
2010-10-20 08:49:28 +00:00
{
Scrap_Upload();
}
2012-07-21 12:09:45 +00:00
R_Bind(gl->texnum);
qglBegin(GL_QUADS);
qglTexCoord2f(gl->sl, gl->tl);
qglVertex2f(x, y);
qglTexCoord2f(gl->sh, gl->tl);
qglVertex2f(x + w, y);
qglTexCoord2f(gl->sh, gl->th);
qglVertex2f(x + w, y + h);
qglTexCoord2f(gl->sl, gl->th);
qglVertex2f(x, y + h);
2010-10-20 08:49:28 +00:00
qglEnd();
}
2010-10-20 08:49:28 +00:00
void
2012-07-21 12:09:45 +00:00
Draw_Pic(int x, int y, char *pic)
{
image_t *gl;
2012-07-21 12:09:45 +00:00
gl = Draw_FindPic(pic);
2010-10-20 08:49:28 +00:00
2012-07-21 12:09:45 +00:00
if (!gl)
{
2012-07-21 12:09:45 +00:00
ri.Con_Printf(PRINT_ALL, "Can't find pic: %s\n", pic);
return;
}
2010-10-20 08:49:28 +00:00
2012-07-21 12:09:45 +00:00
if (scrap_dirty)
2010-10-20 08:49:28 +00:00
{
Scrap_Upload();
}
2012-07-21 12:09:45 +00:00
R_Bind(gl->texnum);
qglBegin(GL_QUADS);
qglTexCoord2f(gl->sl, gl->tl);
qglVertex2f(x, y);
qglTexCoord2f(gl->sh, gl->tl);
qglVertex2f(x + gl->width, y);
qglTexCoord2f(gl->sh, gl->th);
qglVertex2f(x + gl->width, y + gl->height);
qglTexCoord2f(gl->sl, gl->th);
qglVertex2f(x, y + gl->height);
2010-10-20 08:49:28 +00:00
qglEnd();
}
/*
2012-04-29 13:57:33 +00:00
* This repeats a 64*64 tile graphic to fill
2010-10-20 08:49:28 +00:00
* the screen around a sized down
* refresh window.
*/
void
2012-07-21 12:09:45 +00:00
Draw_TileClear(int x, int y, int w, int h, char *pic)
{
2010-10-20 08:49:28 +00:00
image_t *image;
2012-07-21 12:09:45 +00:00
image = Draw_FindPic(pic);
2010-10-20 08:49:28 +00:00
2012-07-21 12:09:45 +00:00
if (!image)
{
2012-07-21 12:09:45 +00:00
ri.Con_Printf(PRINT_ALL, "Can't find pic: %s\n", pic);
return;
}
2012-07-21 12:09:45 +00:00
R_Bind(image->texnum);
qglBegin(GL_QUADS);
qglTexCoord2f(x / 64.0, y / 64.0);
qglVertex2f(x, y);
qglTexCoord2f((x + w) / 64.0, y / 64.0);
qglVertex2f(x + w, y);
qglTexCoord2f((x + w) / 64.0, (y + h) / 64.0);
qglVertex2f(x + w, y + h);
qglTexCoord2f(x / 64.0, (y + h) / 64.0);
qglVertex2f(x, y + h);
2010-10-20 08:49:28 +00:00
qglEnd();
}
/*
2010-10-20 08:49:28 +00:00
* Fills a box of pixels with a single color
*/
void
2012-07-21 12:09:45 +00:00
Draw_Fill(int x, int y, int w, int h, int c)
{
union
{
2010-10-20 08:49:28 +00:00
unsigned c;
2012-07-21 12:09:45 +00:00
byte v[4];
} color;
2012-07-21 12:09:45 +00:00
if ((unsigned)c > 255)
2010-10-20 08:49:28 +00:00
{
2012-07-21 12:09:45 +00:00
ri.Sys_Error(ERR_FATAL, "Draw_Fill: bad color");
2010-10-20 08:49:28 +00:00
}
2012-07-21 12:09:45 +00:00
qglDisable(GL_TEXTURE_2D);
2012-07-21 12:09:45 +00:00
color.c = d_8to24table[c];
qglColor3f(color.v[0] / 255.0, color.v[1] / 255.0,
color.v[2] / 255.0);
2012-07-21 12:09:45 +00:00
qglBegin(GL_QUADS);
2012-07-21 12:09:45 +00:00
qglVertex2f(x, y);
qglVertex2f(x + w, y);
qglVertex2f(x + w, y + h);
qglVertex2f(x, y + h);
2010-10-20 08:49:28 +00:00
qglEnd();
2012-07-21 12:09:45 +00:00
qglColor3f(1, 1, 1);
qglEnable(GL_TEXTURE_2D);
}
2010-10-20 08:49:28 +00:00
void
2012-07-21 12:09:45 +00:00
Draw_FadeScreen(void)
{
2012-07-21 12:09:45 +00:00
qglEnable(GL_BLEND);
qglDisable(GL_TEXTURE_2D);
qglColor4f(0, 0, 0, 0.8);
qglBegin(GL_QUADS);
2010-10-20 08:49:28 +00:00
2012-07-21 12:09:45 +00:00
qglVertex2f(0, 0);
qglVertex2f(vid.width, 0);
qglVertex2f(vid.width, vid.height);
qglVertex2f(0, vid.height);
2010-10-20 08:49:28 +00:00
qglEnd();
2012-07-21 12:09:45 +00:00
qglColor4f(1, 1, 1, 1);
qglEnable(GL_TEXTURE_2D);
qglDisable(GL_BLEND);
}
2010-10-20 08:49:28 +00:00
void
2012-07-21 12:09:45 +00:00
Draw_StretchRaw(int x, int y, int w, int h, int cols, int rows, byte *data)
{
2012-07-21 12:09:45 +00:00
unsigned image32[256 * 256];
unsigned char image8[256 * 256];
2010-10-20 08:49:28 +00:00
int i, j, trows;
byte *source;
int frac, fracstep;
float hscale;
int row;
float t;
2012-07-21 12:09:45 +00:00
R_Bind(0);
2010-10-20 08:49:28 +00:00
2012-07-21 12:09:45 +00:00
if (rows <= 256)
{
hscale = 1;
trows = rows;
}
else
{
2010-10-20 08:49:28 +00:00
hscale = rows / 256.0;
trows = 256;
}
2010-10-20 08:49:28 +00:00
t = rows * hscale / 256 - 1.0 / 512.0;
2012-07-21 12:09:45 +00:00
if (!qglColorTableEXT)
{
unsigned *dest;
2012-07-21 12:09:45 +00:00
for (i = 0; i < trows; i++)
{
2012-07-21 12:09:45 +00:00
row = (int)(i * hscale);
2010-10-20 08:49:28 +00:00
2012-07-21 12:09:45 +00:00
if (row > rows)
2010-10-20 08:49:28 +00:00
{
break;
2010-10-20 08:49:28 +00:00
}
source = data + cols * row;
2012-07-21 12:09:45 +00:00
dest = &image32[i * 256];
2010-10-20 08:49:28 +00:00
fracstep = cols * 0x10000 / 256;
frac = fracstep >> 1;
2010-10-20 08:49:28 +00:00
2012-07-21 12:09:45 +00:00
for (j = 0; j < 256; j++)
{
2012-07-21 12:09:45 +00:00
dest[j] = r_rawpalette[source[frac >> 16]];
frac += fracstep;
}
}
2012-07-21 12:09:45 +00:00
qglTexImage2D(GL_TEXTURE_2D, 0, gl_tex_solid_format,
256, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE,
image32);
}
else
{
unsigned char *dest;
2012-07-21 12:09:45 +00:00
for (i = 0; i < trows; i++)
{
2012-07-21 12:09:45 +00:00
row = (int)(i * hscale);
2010-10-20 08:49:28 +00:00
2012-07-21 12:09:45 +00:00
if (row > rows)
2010-10-20 08:49:28 +00:00
{
break;
2010-10-20 08:49:28 +00:00
}
source = data + cols * row;
2012-07-21 12:09:45 +00:00
dest = &image8[i * 256];
2010-10-20 08:49:28 +00:00
fracstep = cols * 0x10000 / 256;
frac = fracstep >> 1;
2010-10-20 08:49:28 +00:00
2012-07-21 12:09:45 +00:00
for (j = 0; j < 256; j++)
{
2012-07-21 12:09:45 +00:00
dest[j] = source[frac >> 16];
frac += fracstep;
}
}
2012-07-21 12:09:45 +00:00
qglTexImage2D(GL_TEXTURE_2D,
2010-10-20 08:49:28 +00:00
0,
GL_COLOR_INDEX8_EXT,
256, 256,
0,
GL_COLOR_INDEX,
GL_UNSIGNED_BYTE,
2012-07-21 12:09:45 +00:00
image8);
2010-10-20 08:49:28 +00:00
}
qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2012-07-21 12:09:45 +00:00
qglBegin(GL_QUADS);
qglTexCoord2f(1.0 / 512.0, 1.0 / 512.0);
qglVertex2f(x, y);
qglTexCoord2f(511.0 / 512.0, 1.0 / 512.0);
qglVertex2f(x + w, y);
qglTexCoord2f(511.0 / 512.0, t);
qglVertex2f(x + w, y + h);
qglTexCoord2f(1.0 / 512.0, t);
qglVertex2f(x, y + h);
2010-10-20 08:49:28 +00:00
qglEnd();
}
int
2012-07-21 12:09:45 +00:00
Draw_GetPalette(void)
{
int i;
int r, g, b;
unsigned v;
2012-07-21 12:09:45 +00:00
byte *pic, *pal;
int width, height;
/* get the palette */
2012-07-21 12:09:45 +00:00
LoadPCX("pics/colormap.pcx", &pic, &pal, &width, &height);
2012-07-21 12:09:45 +00:00
if (!pal)
{
2012-07-21 12:09:45 +00:00
ri.Sys_Error(ERR_FATAL, "Couldn't load pics/colormap.pcx");
}
2012-07-21 12:09:45 +00:00
for (i = 0; i < 256; i++)
{
2012-07-21 12:09:45 +00:00
r = pal[i * 3 + 0];
g = pal[i * 3 + 1];
b = pal[i * 3 + 2];
2012-07-21 12:09:45 +00:00
v = (255 << 24) + (r << 0) + (g << 8) + (b << 16);
d_8to24table[i] = LittleLong(v);
}
2012-07-21 12:09:45 +00:00
d_8to24table[255] &= LittleLong(0xffffff); /* 255 is transparent */
2012-07-21 12:09:45 +00:00
free(pic);
free(pal);
2012-07-21 12:09:45 +00:00
return 0;
}
2012-07-21 12:09:45 +00:00