19 Dec 2007

This commit is contained in:
g-cont 2007-12-19 00:00:00 +03:00 committed by Alibek Omarov
parent 8142611b41
commit 7d6989a167
4 changed files with 289 additions and 50 deletions

View File

@ -39,7 +39,7 @@ scroll = visible_offset
4. переписать все свапы для лумпов
5. придумать как уменьшить размер карты
научить imagelib читать якобы поврежденные вады (gfx.wad, fonts.wad, cached.wad)
научить imagelib читать якобы странные картинки creditsfont и conchars (хотя бы conchars)
typedef struct
{
@ -52,12 +52,11 @@ typedef struct
} dmapinfo_t;
1. пофиксить чтение хл-текстур (для декалей)
2. исключить добавление одинаковых вадов
//==================================================
// то, что уже готово
//==================================================
+добавлена поддержка ВСЕХ существующих типов внутри вадов
+добавлена поддержка wad-файлов
+наконец-то добавлена аппаратная гамма
+добавлена загрузка мипмапов для всех типов текстур

View File

@ -1005,7 +1005,7 @@ static bool FS_AddWad3File( const char *filename )
FS_Close( file );
return false;
}
if( header.ident != IDWAD3HEADER )
if( header.ident != IDWAD2HEADER && header.ident != IDWAD3HEADER )
{
MsgDev(D_ERROR, "FS_AddWad3File: %s have invalid ident\n", filename );
FS_Close( file );
@ -1766,10 +1766,9 @@ FS_OpenWad3File
Look for a file in the loaded wadfiles and returns buffer with image lump
===========
*/
static byte *FS_OpenWad3File( const char *name, fs_offset_t *filesizeptr )
static byte *FS_OpenWad3File( const char *name, fs_offset_t *filesizeptr, int matchtype )
{
uint i, k;
mip_t *tex;
wadfile_t *w;
char basename[MAX_QPATH];
char texname[17];
@ -1798,19 +1797,51 @@ static byte *FS_OpenWad3File( const char *name, fs_offset_t *filesizeptr )
{
if(!com_strcmp(texname, w->lumps[i].name))
{
mip_t *tex;
lmp_t *lmp;
qpic_t *pic;
qfont_t *fnt;
fs_offset_t size;
byte *buf;
if(matchtype != (int)w->lumps[i].type) break; // try next wad
if(FS_Seek(w->file, w->lumps[i].filepos, SEEK_SET))
{
MsgDev(D_ERROR, "FS_OpenWad3File: corrupt WAD3 file\n");
return NULL;
}
tex = (mip_t *)Mem_Alloc( fs_mempool, w->lumps[i].disksize );
if( FS_Read(w->file, tex, w->lumps[i].size) < w->lumps[i].disksize )
switch((int)w->lumps[i].type)
{
MsgDev(D_ERROR, "FS_OpenWad3File: corrupt WAD3 file\n");
return NULL;
}
case TYPE_QPIC:
pic = (qpic_t *)Mem_Alloc( fs_mempool, w->lumps[i].disksize );
size = FS_Read(w->file, pic, w->lumps[i].size );
buf = (byte *)((qpic_t *)pic);
break;
case TYPE_QFONT:
fnt = (qfont_t *)Mem_Alloc( fs_mempool, w->lumps[i].disksize );
size = FS_Read(w->file, fnt, w->lumps[i].disksize ); // some gfx.wad requires this
buf = (byte *)((qfont_t *)fnt);
break;
case TYPE_Q1MIP:
if(!com_stricmp( w->lumps[i].name, "conchars" ))
{
// great hack from id software
FS_Seek(w->file, w->lumps[i].filepos - w->lumps[i].size, SEEK_SET);
}
lmp = (lmp_t *)Mem_Alloc( fs_mempool, w->lumps[i].disksize );
size = FS_Read(w->file, lmp, w->lumps[i].size );
buf = (byte *)((lmp_t *)lmp);
case TYPE_HLMIP:
tex = (mip_t *)Mem_Alloc( fs_mempool, w->lumps[i].disksize );
size = FS_Read(w->file, tex, w->lumps[i].size );
buf = (byte *)((mip_t *)tex);
break;
}
if( size < w->lumps[i].disksize )
MsgDev(D_WARN, "FS_OpenWad3File: lump %s is corrupt\n", texname );
if(filesizeptr) *filesizeptr = w->lumps[i].disksize;
return (byte *)((mip_t *)tex);
return buf;
}
}
}
@ -2348,10 +2379,25 @@ byte *FS_LoadFile (const char *path, fs_offset_t *filesizeptr )
}
else if(!com_stricmp("wad3", ext ))
{
// probably it's image from wad-file
buf = FS_OpenWad3File( path, &filesize );
// probably it's half-life texture
buf = FS_OpenWad3File( path, &filesize, TYPE_HLMIP );
}
else if(!com_stricmp("lmp", ext ))
{
// probably it's quake1 texture
buf = FS_OpenWad3File( path, &filesize, TYPE_Q1MIP );
}
else if(!com_stricmp("qpic", ext ))
{
// probably it's gfx image (q1 or hl)
buf = FS_OpenWad3File( path, &filesize, TYPE_QPIC );
}
else if(!com_stricmp("qfnt", ext ))
{
// probably it's image from wad-file
buf = FS_OpenWad3File( path, &filesize, TYPE_QFONT );
}
if(filesizeptr) *filesizeptr = filesize;
return buf;
}

View File

@ -31,6 +31,7 @@ char *suf[6] = {"ft", "bk", "rt", "lf", "up", "dn"};
#define LUMP_NORMAL 0
#define LUMP_TRANSPARENT 1
#define LUMP_DECAL 2
#define LUMP_QFONT 3
uint d_8toD1table[256];
uint d_8toQ1table[256];
@ -93,6 +94,16 @@ void Image_GetPalette( byte *pal, uint *d_table )
d_table[i] = BuffBigLong( rgba );
}
break;
case LUMP_QFONT:
for (i = 1; i < 256; i++)
{
rgba[3] = pal[i*3+0];
rgba[2] = pal[i*3+1];
rgba[1] = pal[i*3+2];
rgba[0] = 0xFF;
d_table[i] = BuffBigLong( rgba );
}
break;
case LUMP_NORMAL:
for (i = 0; i < 256; i++)
{
@ -162,12 +173,19 @@ void Image_GetPaletteWAD( byte *pal, int rendermode )
{
d_rendermode = rendermode;
if(pal)
if( pal )
{
Image_GetPalette( pal, d_8to24table );
d_8to24table[255] &= LittleLong(0xffffff);
d_currentpal = d_8to24table;
}
else if(rendermode == LUMP_QFONT)
{
// quake1 base palette and font palette have some diferences
Image_GetPalette( palette_q1, d_8to24table );
d_8to24table[0] = 0;
d_currentpal = d_8to24table;
}
else Image_GetQ1Palette();
}
@ -378,32 +396,44 @@ LoadLMP
bool LoadLMP( char *name, char *buffer, int filesize )
{
lmp_t lmp;
byte *fin;
byte *fin, *pal;
int i, pixels;
int rendermode;
if (filesize < (int)sizeof(lmp))
{
MsgWarn("LoadLMP: file (%s) have invalid size\n", name );
return false;
}
fin = buffer;
Mem_Copy(&lmp, fin, sizeof(lmp));
fin += sizeof(lmp);
image_width = LittleLong(lmp.width);
image_height = LittleLong(lmp.height);
image_num_mips = 1;
// great hack from id software
if(!com_stricmp( name, "conchars" ))
{
image_width = image_height = 128;
pixels = image_width * image_height;
image_flags |= IMAGE_HAS_ALPHA;
rendermode = LUMP_QFONT;
}
else
{
Mem_Copy(&lmp, fin, sizeof(lmp));
image_width = LittleLong(lmp.width);
image_height = LittleLong(lmp.height);
fin += sizeof(lmp);
pixels = image_width * image_height;
if (filesize < (int)sizeof(lmp) + pixels)
{
MsgWarn("LoadLMP: file (%s) have invalid size %d\n", name, filesize );
return false;
}
rendermode = LUMP_NORMAL;
}
if(!Image_ValidSize( name )) return false;
image_size = image_width * image_height * 4;
pixels = image_width * image_height;
if (filesize < (int)sizeof(lmp) + pixels)
{
MsgWarn("LoadLMP: file (%s) have invalid size\n", name );
return false;
}
image_size = pixels * 4;
image_num_mips = 1;
image_rgba = (byte *)Mem_Alloc(Sys.imagepool, image_size );
image_num_layers = 1;
@ -414,10 +444,21 @@ bool LoadLMP( char *name, char *buffer, int filesize )
{
if(fin[i] != 255) continue;
image_flags |= IMAGE_HAS_ALPHA;
rendermode = LUMP_TRANSPARENT;
break; // found
}
Image_GetQ1Palette();// hardcoded
// half-life 1.0.0.1 lmp version with palette
if( filesize == (int)sizeof(lmp) + pixels + sizeof(short) + 768)
{
int numcolors;
pal = fin + pixels;
numcolors = BuffLittleShort( pal ), pal += 2;
if( numcolors != 256 ) pal = NULL; // corrupted lump ?
}
else pal = NULL;
Image_GetPaletteWAD( pal, rendermode );
Image_Copy8bitRGBA( fin, image_rgba, pixels );
return true;
@ -444,7 +485,7 @@ bool LoadMIP( char *name, char *buffer, int filesize )
image_height = LittleLong(mip.height);
for(i = 0; i < 4; i++) ofs[i] = LittleLong(mip.offsets[i]);
if(!Image_ValidSize( name )) return false;
if(!Image_ValidSize( name )) return false;
mipsize = image_width * image_height;
if (filesize < (int)sizeof(mip) + mipsize)
@ -459,6 +500,121 @@ bool LoadMIP( char *name, char *buffer, int filesize )
return FS_AddMipmapToPack( buffer + ofs[0], image_width, image_height );
}
/*
============
LoadPIC
============
*/
bool LoadPIC( char *name, char *buffer, int filesize )
{
qpic_t pic;
byte *pal, *fin;
int numcolors;
int pixels;
if(filesize < (int)sizeof(pic))
{
MsgWarn("LoadPIC: file (%s) have invalid size\n", name );
return false;
}
Mem_Copy(&pic, buffer, sizeof(pic));
image_width = LittleShort(pic.width);
image_height = LittleShort(pic.height);
if(!Image_ValidSize( name )) return false;
pixels = image_width * image_height;
fin = buffer + sizeof(pic) - 4;
image_num_layers = 1;
image_type = PF_RGBA_32;
// half-life qlmpy version with palette
if( filesize == (int)sizeof(pic) - 2 + pixels + sizeof(short) + 768)
{
pal = fin + pixels;
numcolors = BuffLittleShort(pal);
if(numcolors != 256)
{
MsgWarn("LoadPIC: file (%s) have invalid palette size %d\n", name, numcolors );
return false;
}
pal += 2; // skip colorsize
}
else pal = NULL; // quake1 pic
if(fin[0] == 255) image_flags |= IMAGE_HAS_ALPHA;
Image_GetPaletteWAD( pal, LUMP_NORMAL );
return FS_AddMipmapToPack( fin, image_width, image_height );
}
bool LoadTEST( char *name, char *buffer, int filesize )
{
return false;
}
/*
============
LoadFNT
============
*/
bool LoadFNT( char *name, char *buffer, int filesize )
{
qfont_t font;
byte *pal, *fin;
int i, pixels, fullsize;
int numcolors;
if(filesize < (int)sizeof(font))
{
MsgWarn("LoadFNT: file (%s) have invalid size\n", name );
return false;
}
Mem_Copy(&font, buffer, sizeof(font));
// swap lumps
font.width = LittleShort(font.width);
font.height = LittleShort(font.height);
font.rowcount = LittleShort(font.rowcount);
font.rowheight = LittleShort(font.rowheight);
for(i = 0; i < 256; i++)
{
font.fontinfo[i].startoffset = LittleShort( font.fontinfo[i].startoffset );
font.fontinfo[i].charwidth = LittleShort( font.fontinfo[i].charwidth );
}
// last sixty four bytes - what the hell ????
fullsize = sizeof(qfont_t)-4+(128 * font.width * QCHAR_WIDTH) + sizeof(short) + 768 + 64;
if( fullsize != filesize )
{
// probably it's "creditsfont" or "conchars"
MsgWarn("LoadFNT: (%s) it's not a qfont_t structure\n", name );
return LoadTEST( name, buffer, filesize );
}
// setup font dimensions
image_width = font.width * QCHAR_WIDTH;
image_height = font.height;
image_num_layers = 1;
image_type = PF_RGBA_32;
if(!Image_ValidSize( name )) return false;
pixels = ( image_width * image_height );
fin = buffer + sizeof(font) - 4, pal = fin + pixels;
numcolors = BuffLittleShort( pal ), pal += 2;
image_flags |= IMAGE_HAS_ALPHA; // fonts always have transparency
if(numcolors != 768)
{
MsgWarn("LoadFNT: file (%s) have invalid palette size %d\n", name, numcolors );
return false;
}
// FIXME: convert this to quake-style conchars ?
Image_GetPaletteWAD( pal, LUMP_QFONT );
return FS_AddMipmapToPack( fin, image_width, image_height );
}
/*
============
LoadWAD
@ -468,7 +624,8 @@ bool LoadWAD( char *name, char *buffer, int filesize )
{
mip_t mip;
byte *pal;
int ofs[4], i, rendermode;
int ofs[4], rendermode;
int i, numcolors;
if (filesize < (int)sizeof(mip))
{
@ -483,7 +640,13 @@ bool LoadWAD( char *name, char *buffer, int filesize )
if(!Image_ValidSize( name )) return false;
pal = buffer + mip.offsets[0] + (((image_width * image_height) * 85)>>6);
pal += 2; // get palette
numcolors = BuffLittleShort( pal ), pal += 2; // skip colorsize
if(numcolors != 256)
{
MsgWarn("LoadWAD_3: file (%s) have invalid palette size %d\n", name, numcolors );
return false;
}
image_num_layers = 1;
image_type = PF_RGBA_32; // always exctracted to 32-bit buffer
@ -491,24 +654,20 @@ bool LoadWAD( char *name, char *buffer, int filesize )
// detect rendermode
if( name[0] == '{' )
{
// note: i trying determine transparent miptex by last color in palette
// e.g. valve used in their textures blue color (0,0,255)
// other cases for red (255,0,0) ang green (0,255,0) colors,
// otherwise - it will use decal palette with ugly results. ughgrrr..
if(pal[255*3+0] == 0 && pal[255*3+1] == 0 && pal[255*3+2] == 255 && pal[255*3+3] == 0)
{
Msg("trans ");
rendermode = LUMP_TRANSPARENT;
}
else
{
Msg("decal ");
rendermode = LUMP_DECAL;
}
else if(pal[255*3+0] == 0 && pal[255*3+1] == 255 && pal[255*3+2] == 0 && pal[255*3+3] == 0)
rendermode = LUMP_TRANSPARENT;
else if(pal[255*3+0] == 255 && pal[255*3+1] == 0 && pal[255*3+2] == 0 && pal[255*3+3] == 0)
rendermode = LUMP_TRANSPARENT;
else rendermode = LUMP_DECAL;
image_flags |= IMAGE_HAS_ALPHA;
}
else
{
Msg("normal ");
rendermode = LUMP_NORMAL;
}
else rendermode = LUMP_NORMAL;
Image_GetPaletteWAD( pal, rendermode );
return FS_AddMipmapToPack( buffer + mip.offsets[0], image_width, image_height );
}
@ -1731,18 +1890,22 @@ loadformat_t load_formats[] =
{"textures/%s%s.%s", "tga", LoadTGA},
{"textures/%s%s.%s", "jpg", LoadJPG},
{"textures/%s%s.%s", "wad3",LoadWAD},
{"textures/%s%s.%s", "qpic",LoadPIC},
{"textures/%s%s.%s", "pcx", LoadPCX},
{"textures/%s%s.%s", "wal", LoadWAL},
{"textures/%s%s.%s", "lmp", LoadLMP},
{"textures/%s%s.%s", "mip", LoadMIP},
{"textures/%s%s.%s", "qfnt",LoadFNT},
{"%s%s.%s", "dds", LoadDDS},
{"%s%s.%s", "tga", LoadTGA},
{"%s%s.%s", "jpg", LoadJPG},
{"%s%s.%s", "wad3",LoadWAD},
{"%s%s.%s", "qpic",LoadPIC},
{"%s%s.%s", "pcx", LoadPCX},
{"%s%s.%s", "wal", LoadWAL},
{"%s%s.%s", "lmp", LoadLMP},
{"%s%s.%s", "mip", LoadMIP},
{"%s%s.%s", "qfnt",LoadFNT},
{NULL, NULL}
};

View File

@ -1573,9 +1573,19 @@ typedef struct mip_s
========================================================================
*/
#define IDWAD3HEADER (('3'<<24)+('D'<<16)+('A'<<8)+'W') // little-endian "WAD3"
#define IDWAD2HEADER (('2'<<24)+('D'<<16)+('A'<<8)+'W') // little-endian "WAD2" quake1 gfx.wad
#define IDWAD3HEADER (('3'<<24)+('D'<<16)+('A'<<8)+'W') // little-endian "WAD3" half-life wads
#define WAD3_NAMELEN 16
#define TYPE_QPIC 66 // quake1 and hl pic (qpic_t)
#define TYPE_HLMIP 67 // half-life textures (mip_t) TYP_SOUND for Quake1, but never used for it
#define TYPE_Q1MIP 68 // quake1 textures (mip_t)
#define TYPE_QFONT 70 // half-life font (qfont_t)
#define QCHAR_WIDTH 16
#define QFONT_WIDTH 16 // valve fonts used contant sizes
#define QFONT_HEIGHT ((128 - 32) / 16)
typedef struct
{
int ident; // should be WAD3
@ -1595,6 +1605,27 @@ typedef struct
char name[WAD3_NAMELEN]; // must be null terminated
} dlumpinfo_t;
typedef struct
{
int width, height;
byte data[4]; // variably sized
} qpic_t;
typedef struct
{
short startoffset;
short charwidth;
} charset;
typedef struct
{
int width, height;
int rowcount;
int rowheight;
charset fontinfo[256];
byte data[4]; // variable sized
} qfont_t;
/*
========================================================================