Fixed bugs regarding reading the pcx file format for player skins.

Fixed a bug in the colour-mapping code regarding player skins with sizes smaller than the player's model's skin, and optimised the uploaded image size when small skins are used.

git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@2860 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
Spoike 2008-01-16 03:19:14 +00:00
parent 01483e5e89
commit 4dcbbf5054
2 changed files with 56 additions and 12 deletions

View file

@ -206,7 +206,7 @@ qbyte *Skin_Cache8 (skin_t *skin)
qbyte *raw;
qbyte *out, *pix;
pcx_t *pcx;
int x, y;
int x, y, srcw, srch;
int dataByte;
int runLength;
int fbremap[256];
@ -291,15 +291,14 @@ qbyte *Skin_Cache8 (skin_t *skin)
pcx = (pcx_t *)raw;
raw = (qbyte *)(pcx+1);
//check format (sizes are checked later)
if (pcx->manufacturer != 0x0a
|| pcx->version != 5
|| pcx->encoding != 1
|| pcx->bits_per_pixel != 8
|| (unsigned short)LittleShort(pcx->xmax) >= 320
|| (unsigned short)LittleShort(pcx->ymax) >= 200)
|| pcx->bits_per_pixel != 8)
{
skin->failedload = true;
Con_Printf ("Bad skin %s\n", name);
Con_Printf ("Bad skin %s (unsupported format)\n", name);
return NULL;
}
@ -307,28 +306,40 @@ qbyte *Skin_Cache8 (skin_t *skin)
pcx->xmax = (unsigned short)LittleShort(pcx->xmax);
pcx->ymax = (unsigned short)LittleShort(pcx->ymax);
pcx->xmin = (unsigned short)LittleShort(pcx->xmin);
pcx->ymin = (unsigned short)LittleShort(pcx->ymin);
if (qrenderer == QR_SOFTWARE)
srcw = pcx->xmax-pcx->xmin+1;
srch = pcx->ymax-pcx->ymin+1;
if (srcw < 1 || srch < 1 || srcw > 320 || srch > 200)
{
skin->failedload = true;
Con_Printf ("Bad skin %s (unsupported size)\n", name);
return NULL;
}
if (qrenderer == QR_SOFTWARE)
{//biggest size possible, by the way
skin->width = 320;
skin->height = 200;
}
else
{
skin->width = pcx->xmax+1;
skin->height = pcx->ymax;
skin->width = srcw;
skin->height = srch;
}
out = Cache_Alloc (&skin->cache, skin->width*skin->height, skin->name);
if (!out)
Sys_Error ("Skin_Cache: couldn't allocate");
pix = out;
memset (out, 0, skin->width*skin->height);
// memset (out, 0, skin->width*skin->height);
for (y=0 ; y<pcx->ymax ; y++, pix += skin->width)
dataByte = 0; //typically black (this is in case a 0*0 file is loaded... which won't happen anyway)
for (y=0 ; y < srch ; y++, pix += skin->width)
{
for (x=0 ; x<=pcx->xmax ; )
for (x=0 ; x < srcw ; )
{
if (raw - (qbyte*)pcx > com_filesize)
{
@ -370,7 +381,14 @@ qbyte *Skin_Cache8 (skin_t *skin)
pix[x++] = dataByte;
}
//pad the end of the scan line with the trailing pixel
for ( ; x < skin->width ; )
pix[x++] = dataByte;
}
//pad the bottom of the skin with that final pixel
for ( ; y < skin->height; y++, pix += skin->width)
for (x = 0; x < skin->width; )
pix[x++] = dataByte;
if ( raw - (qbyte *)pcx > com_filesize)
{

View file

@ -1159,6 +1159,32 @@ static galiastexnum_t *GL_ChooseSkin(galiasinfo_t *inf, char *modelname, int sur
scaled_width = gl_max_size.value < 512 ? gl_max_size.value : 512;
scaled_height = gl_max_size.value < 512 ? gl_max_size.value : 512;
//handle the case of an external skin being smaller than the texture that its meant to replace
//(to support the evil hackage of the padding on the outside of common qw skins)
if (tinwidth > inwidth)
tinwidth = inwidth;
if (tinheight > inheight)
tinheight = inheight;
//don't make scaled width any larger than it needs to be
for (i = 0; i < 10; i++)
{
scaled_width = (1<<i);
if (scaled_width >= tinwidth)
break; //its covered
}
if (scaled_width > gl_max_size.value)
scaled_width = gl_max_size.value; //whoops, we made it too big
for (i = 0; i < 10; i++)
{
scaled_height = (1<<i);
if (scaled_height >= tinheight)
break; //its covered
}
if (scaled_height > gl_max_size.value)
scaled_height = gl_max_size.value; //whoops, we made it too big
for (i=0 ; i<256 ; i++)
translate[i] = i;