diff options
Diffstat (limited to 'source/sw_image.c')
-rw-r--r-- | source/sw_image.c | 341 |
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(); } |