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:
parent
01483e5e89
commit
4dcbbf5054
2 changed files with 56 additions and 12 deletions
|
@ -206,7 +206,7 @@ qbyte *Skin_Cache8 (skin_t *skin)
|
||||||
qbyte *raw;
|
qbyte *raw;
|
||||||
qbyte *out, *pix;
|
qbyte *out, *pix;
|
||||||
pcx_t *pcx;
|
pcx_t *pcx;
|
||||||
int x, y;
|
int x, y, srcw, srch;
|
||||||
int dataByte;
|
int dataByte;
|
||||||
int runLength;
|
int runLength;
|
||||||
int fbremap[256];
|
int fbremap[256];
|
||||||
|
@ -291,15 +291,14 @@ qbyte *Skin_Cache8 (skin_t *skin)
|
||||||
pcx = (pcx_t *)raw;
|
pcx = (pcx_t *)raw;
|
||||||
raw = (qbyte *)(pcx+1);
|
raw = (qbyte *)(pcx+1);
|
||||||
|
|
||||||
|
//check format (sizes are checked later)
|
||||||
if (pcx->manufacturer != 0x0a
|
if (pcx->manufacturer != 0x0a
|
||||||
|| pcx->version != 5
|
|| pcx->version != 5
|
||||||
|| pcx->encoding != 1
|
|| pcx->encoding != 1
|
||||||
|| pcx->bits_per_pixel != 8
|
|| pcx->bits_per_pixel != 8)
|
||||||
|| (unsigned short)LittleShort(pcx->xmax) >= 320
|
|
||||||
|| (unsigned short)LittleShort(pcx->ymax) >= 200)
|
|
||||||
{
|
{
|
||||||
skin->failedload = true;
|
skin->failedload = true;
|
||||||
Con_Printf ("Bad skin %s\n", name);
|
Con_Printf ("Bad skin %s (unsupported format)\n", name);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -307,28 +306,40 @@ qbyte *Skin_Cache8 (skin_t *skin)
|
||||||
|
|
||||||
pcx->xmax = (unsigned short)LittleShort(pcx->xmax);
|
pcx->xmax = (unsigned short)LittleShort(pcx->xmax);
|
||||||
pcx->ymax = (unsigned short)LittleShort(pcx->ymax);
|
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->width = 320;
|
||||||
skin->height = 200;
|
skin->height = 200;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
skin->width = pcx->xmax+1;
|
skin->width = srcw;
|
||||||
skin->height = pcx->ymax;
|
skin->height = srch;
|
||||||
}
|
}
|
||||||
|
|
||||||
out = Cache_Alloc (&skin->cache, skin->width*skin->height, skin->name);
|
out = Cache_Alloc (&skin->cache, skin->width*skin->height, skin->name);
|
||||||
if (!out)
|
if (!out)
|
||||||
Sys_Error ("Skin_Cache: couldn't allocate");
|
Sys_Error ("Skin_Cache: couldn't allocate");
|
||||||
|
|
||||||
pix = out;
|
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)
|
if (raw - (qbyte*)pcx > com_filesize)
|
||||||
{
|
{
|
||||||
|
@ -370,7 +381,14 @@ qbyte *Skin_Cache8 (skin_t *skin)
|
||||||
pix[x++] = dataByte;
|
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)
|
if ( raw - (qbyte *)pcx > com_filesize)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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_width = gl_max_size.value < 512 ? gl_max_size.value : 512;
|
||||||
scaled_height = 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++)
|
for (i=0 ; i<256 ; i++)
|
||||||
translate[i] = i;
|
translate[i] = i;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue