yquake2remaster/src/refresh/r_draw.c

413 lines
7.8 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
*
* =======================================================================
*/
2009-03-05 11:03:08 +00:00
#include "header/local.h"
2010-10-20 08:49:28 +00:00
image_t *draw_chars;
2010-10-20 08:49:28 +00:00
extern qboolean scrap_dirty;
void Scrap_Upload ( void );
extern unsigned r_rawpalette [ 256 ];
2010-10-20 08:49:28 +00:00
void
Draw_InitLocal ( void )
{
2010-10-20 08:49:28 +00:00
/* load console characters (don't bilerp characters) */
draw_chars = R_FindImage( "pics/conchars.pcx", it_pic );
R_Bind( draw_chars->texnum );
2010-10-20 08:49:28 +00:00
qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
qglTexParameterf( 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
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;
2010-10-20 08:49:28 +00:00
if ( ( num & 127 ) == 32 )
{
return; /* space */
}
if ( y <= -8 )
{
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;
R_Bind( draw_chars->texnum );
2010-10-20 08:49:28 +00:00
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 );
qglEnd();
}
2010-10-20 08:49:28 +00:00
image_t *
Draw_FindPic ( char *name )
{
image_t *gl;
2010-10-20 08:49:28 +00:00
char fullname [ MAX_QPATH ];
2010-10-20 08:49:28 +00:00
if ( ( name [ 0 ] != '/' ) && ( name [ 0 ] != '\\' ) )
{
2010-10-20 08:49:28 +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
{
gl = R_FindImage( name + 1, it_pic );
2010-10-20 08:49:28 +00:00
}
2010-10-20 08:49:28 +00:00
return ( gl );
}
2010-10-20 08:49:28 +00:00
void
Draw_GetPicSize ( int *w, int *h, char *pic )
{
image_t *gl;
2010-10-20 08:49:28 +00:00
gl = Draw_FindPic( pic );
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
Draw_StretchPic ( int x, int y, int w, int h, char *pic )
{
image_t *gl;
2010-10-20 08:49:28 +00:00
gl = Draw_FindPic( pic );
if ( !gl )
{
2010-10-20 08:49:28 +00:00
ri.Con_Printf( PRINT_ALL, "Can't find pic: %s\n", pic );
return;
}
2010-10-20 08:49:28 +00:00
if ( scrap_dirty )
{
Scrap_Upload();
}
R_Bind( gl->texnum );
2010-10-20 08:49:28 +00:00
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 );
qglEnd();
}
2010-10-20 08:49:28 +00:00
void
Draw_Pic ( int x, int y, char *pic )
{
image_t *gl;
2010-10-20 08:49:28 +00:00
gl = Draw_FindPic( pic );
if ( !gl )
{
2010-10-20 08:49:28 +00:00
ri.Con_Printf( PRINT_ALL, "Can't find pic: %s\n", pic );
return;
}
2010-10-20 08:49:28 +00:00
if ( scrap_dirty )
{
Scrap_Upload();
}
R_Bind( gl->texnum );
2010-10-20 08:49:28 +00:00
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 );
qglEnd();
}
/*
2010-10-20 08:49:28 +00:00
* This repeats a 64*64 tile graphic to fill
* the screen around a sized down
* refresh window.
*/
void
Draw_TileClear ( int x, int y, int w, int h, char *pic )
{
2010-10-20 08:49:28 +00:00
image_t *image;
2010-10-20 08:49:28 +00:00
image = Draw_FindPic( pic );
if ( !image )
{
2010-10-20 08:49:28 +00:00
ri.Con_Printf( PRINT_ALL, "Can't find pic: %s\n", pic );
return;
}
R_Bind( image->texnum );
2010-10-20 08:49:28 +00:00
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 );
qglEnd();
}
/*
2010-10-20 08:49:28 +00:00
* Fills a box of pixels with a single color
*/
void
Draw_Fill ( int x, int y, int w, int h, int c )
{
union
{
2010-10-20 08:49:28 +00:00
unsigned c;
byte v [ 4 ];
} color;
2010-10-20 08:49:28 +00:00
if ( (unsigned) c > 255 )
{
ri.Sys_Error( ERR_FATAL, "Draw_Fill: bad color" );
}
2010-10-20 08:49:28 +00:00
qglDisable( GL_TEXTURE_2D );
2010-10-20 08:49:28 +00:00
color.c = d_8to24table [ c ];
qglColor3f( color.v [ 0 ] / 255.0,
color.v [ 1 ] / 255.0,
color.v [ 2 ] / 255.0 );
2010-10-20 08:49:28 +00:00
qglBegin( GL_QUADS );
2010-10-20 08:49:28 +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();
qglColor3f( 1, 1, 1 );
qglEnable( GL_TEXTURE_2D );
}
2010-10-20 08:49:28 +00:00
void
Draw_FadeScreen ( void )
{
2010-10-20 08:49:28 +00:00
qglEnable( GL_BLEND );
qglDisable( GL_TEXTURE_2D );
qglColor4f( 0, 0, 0, 0.8 );
qglBegin( GL_QUADS );
qglVertex2f( 0, 0 );
qglVertex2f( vid.width, 0 );
qglVertex2f( vid.width, vid.height );
qglVertex2f( 0, vid.height );
qglEnd();
qglColor4f( 1, 1, 1, 1 );
qglEnable( GL_TEXTURE_2D );
qglDisable( GL_BLEND );
}
2010-10-20 08:49:28 +00:00
void
Draw_StretchRaw ( int x, int y, int w, int h, int cols, int rows, byte *data )
{
2010-10-20 08:49:28 +00:00
unsigned image32 [ 256 * 256 ];
unsigned char image8 [ 256 * 256 ];
int i, j, trows;
byte *source;
int frac, fracstep;
float hscale;
int row;
float t;
R_Bind( 0 );
2010-10-20 08:49:28 +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;
if ( !qglColorTableEXT )
{
unsigned *dest;
2010-10-20 08:49:28 +00:00
for ( i = 0; i < trows; i++ )
{
2010-10-20 08:49:28 +00:00
row = (int) ( i * hscale );
if ( row > rows )
{
break;
2010-10-20 08:49:28 +00:00
}
source = data + cols * row;
dest = &image32 [ i * 256 ];
fracstep = cols * 0x10000 / 256;
frac = fracstep >> 1;
2010-10-20 08:49:28 +00:00
for ( j = 0; j < 256; j++ )
{
2010-10-20 08:49:28 +00:00
dest [ j ] = r_rawpalette [ source [ frac >> 16 ] ];
frac += fracstep;
}
}
2010-10-20 08:49:28 +00:00
qglTexImage2D( GL_TEXTURE_2D, 0, gl_tex_solid_format, 256, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, image32 );
}
else
{
unsigned char *dest;
2010-10-20 08:49:28 +00:00
for ( i = 0; i < trows; i++ )
{
2010-10-20 08:49:28 +00:00
row = (int) ( i * hscale );
if ( row > rows )
{
break;
2010-10-20 08:49:28 +00:00
}
source = data + cols * row;
dest = &image8 [ i * 256 ];
fracstep = cols * 0x10000 / 256;
frac = fracstep >> 1;
2010-10-20 08:49:28 +00:00
for ( j = 0; j < 256; j++ )
{
2010-10-20 08:49:28 +00:00
dest [ j ] = source [ frac >> 16 ];
frac += fracstep;
}
}
2010-10-20 08:49:28 +00:00
qglTexImage2D( GL_TEXTURE_2D,
0,
GL_COLOR_INDEX8_EXT,
256, 256,
0,
GL_COLOR_INDEX,
GL_UNSIGNED_BYTE,
image8 );
}
qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
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 );
qglEnd();
}
int
Draw_GetPalette ( void )
{
int i;
int r, g, b;
unsigned v;
byte *pic, *pal;
int width, height;
/* get the palette */
LoadPCX( "pics/colormap.pcx", &pic, &pal, &width, &height );
if ( !pal )
{
ri.Sys_Error( ERR_FATAL, "Couldn't load pics/colormap.pcx" );
}
for ( i = 0; i < 256; i++ )
{
r = pal [ i * 3 + 0 ];
g = pal [ i * 3 + 1 ];
b = pal [ i * 3 + 2 ];
v = ( 255 << 24 ) + ( r << 0 ) + ( g << 8 ) + ( b << 16 );
d_8to24table [ i ] = LittleLong( v );
}
d_8to24table [ 255 ] &= LittleLong( 0xffffff ); /* 255 is transparent */
free( pic );
free( pal );
return ( 0 );
}