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.c341
1 files changed, 116 insertions, 225 deletions
diff --git a/source/sw_image.c b/source/sw_image.c
index 5e03868..5e6a6cf 100644
--- a/source/sw_image.c
+++ b/source/sw_image.c
@@ -19,163 +19,31 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "sw_local.h"
+#include "d_wal.h"
+image_t *r_notexture;
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_t * )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
+IMG_Unload
================
*/
-image_t *R_LoadWal( const char *name ) {
- miptex_t *mt;
- image_t *image;
- size_t size, length, ofs, endpos, 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] );
- endpos = ofs + size;
- if( endpos < ofs || endpos > 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] );
+void IMG_Unload( image_t *image ) {
+ if( image->flags & if_auto ) {
+ return;
+ }
+ Z_Free( image->pixels[0] );
+ image->pixels[0] = NULL;
}
-
/*
================
-R_LoadPic
-
+IMG_Load
================
*/
-void R_LoadImage( image_t *image, byte *pic, int width, int height, imagetype_t type, imageflags_t flags ) {
+void IMG_Load( image_t *image, byte *pic, int width, int height, imagetype_t type, imageflags_t flags ) {
int i, c, b;
image->registration_sequence = registration_sequence;
@@ -199,133 +67,156 @@ void R_LoadImage( image_t *image, byte *pic, int width, int height, imagetype_t
/*
================
-R_LoadWal
+IMG_LoadWAL
================
*/
-image_t *R_LoadWal( const char *name ) {
+image_t *IMG_LoadWAL( const char *name ) {
miptex_t *mt;
- int ofs;
image_t *image;
- int size;
+ size_t width, height, offset, endpos, filelen, size;
- fs.LoadFile( name, ( void ** )&mt );
+ filelen = FS_LoadFile( name, ( void ** )&mt );
if( !mt ) {
- //Com_Printf( "R_LoadWal: can't load %s\n", name );
- return r_notexture_mip;
+ return NULL;
+ }
+
+ image = NULL;
+
+ width = LittleLong( mt->width );
+ height = LittleLong( mt->height );
+ offset = LittleLong( mt->offsets[0] );
+
+ if( width < 1 || height < 1 || width > MAX_TEXTURE_SIZE || height > MAX_TEXTURE_SIZE ) {
+ Com_WPrintf( "LoadWAL: %s: bad dimensions\n", name );
+ goto fail;
+ }
+
+ size = width * height * ( 256 + 64 + 16 + 4 ) / 256;
+ endpos = offset + size;
+ if( endpos < offset || endpos > filelen ) {
+ Com_WPrintf( "LoadWAL: %s: bad offset\n", name );
+ goto fail;
}
- image = R_AllocImage( name );
- image->width = image->upload_width = LittleLong( mt->width );
- image->height = image->upload_height = LittleLong( mt->height );
+ image = IMG_Alloc( name );
+ image->width = image->upload_width = width;
+ image->height = image->upload_height = 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;
+ image->pixels[1] = image->pixels[0] + width * height;
+ image->pixels[2] = image->pixels[1] + width * height / 4;
+ image->pixels[3] = image->pixels[2] + width * height / 16;
- ofs = LittleLong( mt->offsets[0] );
- memcpy( image->pixels[0], ( byte * )mt + ofs, size );
+ memcpy( image->pixels[0], ( byte * )mt + offset, size );
- fs.FreeFile( ( void * )mt );
+fail:
+ FS_FreeFile( 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] == '*' ) {
- image = R_FindImage( name + 1, it_tmp );
- } else if( name[0] == '/' || name[0] == '\\' ) {
- image = R_FindImage( name + 1, it_pic );
- } else {
- Q_concat( fullname, sizeof( fullname ), "pics/", name, NULL );
- COM_DefaultExtension( fullname, ".pcx", sizeof( fullname ) );
- image = R_FindImage( fullname, it_pic );
- }
-
- return image ? ( image - r_images ) + 1 : 0;
-}
-
-/*
-================
-R_BuildGammaTable
-================
-*/
-void R_BuildGammaTable( void ) {
+static void R_BuildGammaTable( void ) {
int i, inf;
- float g;
-
- g = vid_gamma->value;
+ float 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;
+ sw_state.gammatable[i] = clamp( inf, 0, 255 );
}
}
-/*
-===============
-R_InitImages
-===============
-*/
-void R_InitImages( void ) {
- byte *data;
- size_t length;
+#define NTX 16
- registration_sequence = 1;
+static void R_CreateNotexture( void ) {
+ static byte buffer[NTX * NTX * ( 256 + 64 + 16 + 4 ) / 256];
+ int x, y, m;
+ byte *p;
+
+// create a simple checkerboard texture for the default
+ r_notexture = IMG_Alloc( "*notexture" );
+ r_notexture->type = it_wall;
+ r_notexture->flags = if_auto;
+ r_notexture->width = r_notexture->height = NTX;
+ r_notexture->upload_width = r_notexture->upload_height = NTX;
+ r_notexture->pixels[0] = buffer;
+ r_notexture->pixels[1] = r_notexture->pixels[0] + NTX * NTX;
+ r_notexture->pixels[2] = r_notexture->pixels[1] + NTX * NTX / 4;
+ r_notexture->pixels[3] = r_notexture->pixels[2] + NTX * NTX / 16;
+
+ for( m = 0; m < 4; m++ ) {
+ p = r_notexture->pixels[m];
+ for ( y = 0; y < ( 16 >> m ); y++ ) {
+ for( x = 0; x < ( 16 >> m ); x++ ) {
+ if( ( y < ( 8 >> m ) ) ^ ( x < ( 8 >> m ) ) )
+ *p++ = 0;
+ else
+ *p++ = 1;
+ }
+ }
+ }
+}
+
+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];
+}
- length = fs.LoadFile( "pics/16to8.dat", ( void ** )&data );
- if( !data ) {
+static void R_Get16to8( void ) {
+ fileHandle_t f;
+ size_t r;
+
+ FS_FOpenFile( "pics/16to8.dat", &f, FS_MODE_READ );
+ if( !f ) {
Com_Error( ERR_FATAL, "Couldn't load pics/16to8.dat" );
}
- if( length < 65536 ) {
+ r = FS_Read( d_16to8table, sizeof( d_16to8table ), f );
+ if( r != sizeof( d_16to8table ) ) {
Com_Error( ERR_FATAL, "Malformed pics/16to8.dat" );
}
- memcpy( d_16to8table, data, 65536 );
- fs.FreeFile( data );
+ FS_FCloseFile( f );
+}
- R_GetPalette( &vid.colormap );
+/*
+===============
+R_InitImages
+===============
+*/
+void R_InitImages( void ) {
+ registration_sequence = 1;
+
+ IMG_GetPalette( &vid.colormap );
vid.alphamap = vid.colormap + 64 * 256;
-#ifdef USE_ASM
+#if USE_ASM
{
/* variable needed by assembly code */
extern void *d_pcolormap;
d_pcolormap = vid.colormap;
}
#endif
+
+ R_Get16to8();
+
+ R_CreateNotexture();
+
+ R_BuildGammaTable();
}
/*
@@ -335,10 +226,10 @@ R_ShutdownImages
*/
void R_ShutdownImages( void ) {
if( vid.colormap ) {
- com.Free( vid.colormap );
+ Z_Free( vid.colormap );
vid.colormap = NULL;
}
- R_FreeAllImages();
+ IMG_FreeAll();
}