summaryrefslogtreecommitdiff
path: root/source/sw_image.c
diff options
context:
space:
mode:
Diffstat (limited to 'source/sw_image.c')
-rw-r--r--source/sw_image.c343
1 files changed, 343 insertions, 0 deletions
diff --git a/source/sw_image.c b/source/sw_image.c
new file mode 100644
index 0000000..0368d2b
--- /dev/null
+++ b/source/sw_image.c
@@ -0,0 +1,343 @@
+/*
+Copyright (C) 1997-2001 Id Software, Inc.
+
+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.
+
+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.
+
+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
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+*/
+
+#include "sw_local.h"
+
+
+byte d_16to8table[65536];
+
+int R_IndexForColor( const color_t color ) {
+ unsigned int r, g, b, c;
+
+ r = ( color[0] >> 3 ) & 31;
+ g = ( color[1] >> 2 ) & 63;
+ b = ( color[2] >> 3 ) & 31;
+
+ c = r | ( g << 5 ) | ( b << 11 );
+
+ return d_16to8table[c];
+}
+
+
+image_t *R_ImageForHandle( qhandle_t hPic ) {
+ if( !hPic ) {
+ return r_notexture_mip;
+ }
+
+ if( hPic < 1 || hPic >= r_numImages + 1 ) {
+ Com_Error( ERR_DROP, "R_ImageForHandle: out of range hPic: %i\n", hPic );
+ }
+
+ return &r_images[hPic - 1];
+}
+
+#ifdef TRUECOLOR_RENDERER
+
+static void R_MipMap( byte *in, byte *out, int width, int height ) {
+ int i, j;
+
+ width <<= 2;
+ height >>= 1;
+ for( i = 0; i < height; i++, in += width ) {
+ for( j = 0; j < width; j += 8, out += 4, in += 8 ) {
+ out[0] = ( in[0] + in[4] + in[width+0] + in[width+4] ) >> 2;
+ out[1] = ( in[1] + in[5] + in[width+1] + in[width+5] ) >> 2;
+ out[2] = ( in[2] + in[6] + in[width+2] + in[width+6] ) >> 2;
+ out[3] = ( in[3] + in[7] + in[width+3] + in[width+7] ) >> 2;
+ }
+ }
+}
+
+qboolean R_ConvertTo32( const byte *data, int width, int height, byte *buffer ) {
+ byte *dest;
+ byte p;
+ int i, size;
+ qboolean transparent;
+
+ transparent = qfalse;
+ size = width * height;
+
+ dest = buffer;
+ for( i = 0; i < size; i++ ) {
+ p = data[i];
+ *( uint32 * )dest = d_8to24table[p];
+
+ if( p == 255 ) {
+ // transparent, so scan around for another color
+ // to avoid alpha fringes
+ // FIXME: do a full flood fill so mips work...
+ if (i > width && data[i-width] != 255)
+ p = data[i-width];
+ else if (i < size-width && data[i+width] != 255)
+ p = data[i+width];
+ else if (i > 0 && data[i-1] != 255)
+ p = data[i-1];
+ else if (i < size-1 && data[i+1] != 255)
+ p = data[i+1];
+ else
+ p = 0;
+ // copy rgb components
+ dest[0] = d_8to24table[p] & 255;
+ dest[1] = ( d_8to24table[p] >> 8 ) & 255;
+ dest[2] = ( d_8to24table[p] >> 16 ) & 255;
+
+ transparent = qtrue;
+ }
+
+ dest += 4;
+ }
+
+ return transparent;
+
+}
+
+/*
+================
+R_LoadWal
+================
+*/
+image_t *R_LoadWal( const char *name ) {
+ miptex_t *mt;
+ uint32 ofs;
+ image_t *image;
+ uint32 size, length;
+ uint32 w, h;
+ byte *source[4];
+
+ length = fs.LoadFile( name, ( void ** )&mt );
+ if( !mt ) {
+ Com_DPrintf( "R_LoadWal: can't load %s\n", name );
+ return r_notexture_mip;
+ }
+
+ w = LittleLong( mt->width );
+ h = LittleLong( mt->height );
+
+ size = w * h * ( 256 + 64 + 16 + 4 ) / 256;
+ ofs = LittleLong( mt->offsets[0] );
+ if( ofs + size > length ) {
+ Com_DPrintf( "R_LoadWal: %s is malformed\n", name );
+ fs.FreeFile( ( void * )mt );
+ return r_notexture_mip;
+ }
+
+ image = R_AllocImage( name );
+ image->width = image->upload_width = w;
+ image->height = image->upload_height = h;
+ image->type = it_wall;
+
+ image->pixels[0] = R_Malloc( size * 4 );
+ image->pixels[1] = image->pixels[0] + ( w * h ) * 4;
+ image->pixels[2] = image->pixels[1] + ( w * h / 4 ) * 4;
+ image->pixels[3] = image->pixels[2] + ( w * h / 16 ) * 4;
+
+ source[0] = ( byte * )mt + ofs;
+ source[1] = source[0] + w * h;
+ source[2] = source[1] + w * h / 4;
+ source[3] = source[2] + w * h / 16;
+
+ image->transparent = R_ConvertTo32( source[0], w, h, image->pixels[0] );
+ R_ConvertTo32( source[1], w >> 1, h >> 1, image->pixels[1] );
+ R_ConvertTo32( source[2], w >> 2, h >> 2, image->pixels[2] );
+ R_ConvertTo32( source[3], w >> 3, h >> 3, image->pixels[3] );
+
+ return image;
+}
+
+#endif /* TRUECOLOR_RENDERER */
+
+//=======================================================
+
+void R_FreeImage( image_t *image ) {
+ com.Free( image->pixels[0] );
+}
+
+
+/*
+================
+R_LoadPic
+
+================
+*/
+void R_LoadImage( image_t *image, byte *pic, int width, int height, imagetype_t type, imageflags_t flags ) {
+ int i, c, b;
+
+ image->registration_sequence = registration_sequence;
+
+ image->width = image->upload_width = width;
+ image->height = image->upload_height = height;
+ image->type = type;
+
+ c = width * height;
+ image->pixels[0] = pic;
+
+ for( i = 0; i < c; i++ ) {
+ b = pic[i];
+ if( b == 255 ) {
+ flags |= if_transparent;
+ }
+ }
+
+ image->flags = flags;
+}
+
+/*
+================
+R_LoadWal
+================
+*/
+image_t *R_LoadWal( const char *name ) {
+ miptex_t *mt;
+ int ofs;
+ image_t *image;
+ int size;
+
+ fs.LoadFile( name, ( void ** )&mt );
+ if( !mt ) {
+ //Com_Printf( "R_LoadWal: can't load %s\n", name );
+ return r_notexture_mip;
+ }
+
+ image = R_AllocImage( name );
+ image->width = image->upload_width = LittleLong( mt->width );
+ image->height = image->upload_height = LittleLong( mt->height );
+ image->type = it_wall;
+ image->flags = if_paletted;
+ image->registration_sequence = registration_sequence;
+
+ size = image->width * image->height * ( 256 + 64 + 16 + 4 ) / 256;
+ image->pixels[0] = R_Malloc( size );
+ image->pixels[1] = image->pixels[0] + image->width * image->height;
+ image->pixels[2] = image->pixels[1] + image->width * image->height / 4;
+ image->pixels[3] = image->pixels[2] + image->width * image->height / 16;
+
+ ofs = LittleLong( mt->offsets[0] );
+ memcpy( image->pixels[0], ( byte * )mt + ofs, size );
+
+ fs.FreeFile( ( void * )mt );
+
+ return image;
+}
+
+/*
+===============
+R_RegisterSkin
+===============
+*/
+qhandle_t R_RegisterSkin( const char *name ) {
+ image_t *image;
+
+ image = R_FindImage( name, it_skin );
+
+ return image ? ( image - r_images ) + 1 : 0;
+}
+
+/*
+================
+R_RegisterPic
+================
+*/
+qhandle_t R_RegisterPic( const char *name ) {
+ image_t *image;
+ char fullname[MAX_QPATH];
+
+ if( name[0] != '/' && name[0] != '\\' ) {
+ Com_sprintf( fullname, sizeof( fullname ), "pics/%s", name );
+ COM_DefaultExtension( fullname, ".pcx", sizeof( fullname ) );
+ image = R_FindImage( fullname, it_pic );
+ } else {
+ image = R_FindImage( name + 1, it_pic );
+ }
+
+ return image ? ( image - r_images ) + 1 : 0;
+}
+
+/*
+================
+R_BuildGammaTable
+================
+*/
+void R_BuildGammaTable( void ) {
+ int i, inf;
+ float g;
+
+ g = vid_gamma->value;
+
+ if( g == 1.0 ) {
+ for ( i = 0; i < 256; i++)
+ sw_state.gammatable[i] = i;
+ return;
+ }
+
+ for( i = 0; i < 256; i++ ) {
+ inf = 255 * pow ( ( i + 0.5 ) / 255.5 , g ) + 0.5;
+ clamp( inf, 0, 255 );
+ sw_state.gammatable[i] = inf;
+ }
+}
+
+/*
+===============
+R_InitImages
+===============
+*/
+void R_InitImages( void ) {
+ byte *data;
+ int length;
+
+ registration_sequence = 1;
+
+ length = fs.LoadFile( "pics/16to8.dat", ( void ** )&data );
+ if( !data ) {
+ Com_Error( ERR_FATAL, "Couldn't load pics/16to8.dat" );
+ }
+ if( length < 65536 ) {
+ Com_Error( ERR_FATAL, "Malformed pics/16to8.dat" );
+ }
+ memcpy( d_16to8table, data, 65536 );
+
+ fs.FreeFile( data );
+
+ R_GetPalette( &vid.colormap );
+ vid.alphamap = vid.colormap + 64 * 256;
+
+#ifdef USE_ASM
+ {
+ /* variable needed by assembly code */
+ extern void *d_pcolormap;
+ d_pcolormap = vid.colormap;
+ }
+#endif
+}
+
+/*
+===============
+R_ShutdownImages
+===============
+*/
+void R_ShutdownImages( void ) {
+ if( vid.colormap ) {
+ com.Free( vid.colormap );
+ vid.colormap = NULL;
+ }
+
+ R_FreeAllImages();
+}
+