29 Jul 2017

This commit is contained in:
g-cont 2017-07-29 00:00:00 +03:00 committed by Alibek Omarov
parent 22b4712957
commit c58a2c5893
6 changed files with 133 additions and 79 deletions

View File

@ -461,7 +461,6 @@ typedef struct
int *commands; // gl command list with embedded s/t
unsigned short gl_texturenum[MAX_SKINS][4];
unsigned short fb_texturenum[MAX_SKINS][4];
int *texels[MAX_SKINS]; // only for player skins
maliasframedesc_t frames[1]; // variable sized
} aliashdr_t;

View File

@ -509,6 +509,75 @@ rgbdata_t *Mod_CreateSkinData( byte *data, int width, int height )
return FS_CopyImage( &skin );
}
void *Mod_LoadSignleSkin( daliasskintype_t *pskintype, int skinnum, int size )
{
string name, lumaname;
rgbdata_t *pic;
Q_snprintf( name, sizeof( name ), "%s:frame%i", loadmodel->name, skinnum );
Q_snprintf( lumaname, sizeof( lumaname ), "%s:luma%i", loadmodel->name, skinnum );
pic = Mod_CreateSkinData( (byte *)(pskintype + 1), m_pAliasHeader->skinwidth, m_pAliasHeader->skinheight );
m_pAliasHeader->gl_texturenum[skinnum][0] =
m_pAliasHeader->gl_texturenum[skinnum][1] =
m_pAliasHeader->gl_texturenum[skinnum][2] =
m_pAliasHeader->gl_texturenum[skinnum][3] = GL_LoadTextureInternal( name, pic, 0, false );
FS_FreeImage( pic );
if( R_GetTexture( m_pAliasHeader->gl_texturenum[skinnum][0] )->flags & TF_HAS_LUMA )
{
pic = Mod_CreateSkinData( (byte *)(pskintype + 1), m_pAliasHeader->skinwidth, m_pAliasHeader->skinheight );
m_pAliasHeader->fb_texturenum[skinnum][0] =
m_pAliasHeader->fb_texturenum[skinnum][1] =
m_pAliasHeader->fb_texturenum[skinnum][2] =
m_pAliasHeader->fb_texturenum[skinnum][3] = GL_LoadTextureInternal( lumaname, pic, TF_MAKELUMA, false );
FS_FreeImage( pic );
}
return ((byte *)(pskintype + 1) + size);
}
void *Mod_LoadGroupSkin( daliasskintype_t *pskintype, int skinnum, int size )
{
daliasskininterval_t *pinskinintervals;
daliasskingroup_t *pinskingroup;
string name, lumaname;
rgbdata_t *pic;
int i, j;
// animating skin group. yuck.
pskintype++;
pinskingroup = (daliasskingroup_t *)pskintype;
pinskinintervals = (daliasskininterval_t *)(pinskingroup + 1);
pskintype = (void *)(pinskinintervals + pinskingroup->numskins);
for( i = 0; i < pinskingroup->numskins; i++ )
{
Q_snprintf( name, sizeof( name ), "%s_%i_%i", loadmodel->name, skinnum, i );
pic = Mod_CreateSkinData( (byte *)(pskintype), m_pAliasHeader->skinwidth, m_pAliasHeader->skinheight );
m_pAliasHeader->gl_texturenum[skinnum][i & 3] = GL_LoadTextureInternal( name, pic, 0, false );
FS_FreeImage( pic );
if( R_GetTexture( m_pAliasHeader->gl_texturenum[skinnum][i & 3] )->flags & TF_HAS_LUMA )
{
Q_snprintf( lumaname, sizeof( lumaname ), "%s_%i_%i_luma", loadmodel->name, skinnum, i );
pic = Mod_CreateSkinData((byte *)(pskintype), m_pAliasHeader->skinwidth, m_pAliasHeader->skinheight );
m_pAliasHeader->fb_texturenum[skinnum][i & 3] = GL_LoadTextureInternal( lumaname, pic, TF_MAKELUMA, false );
FS_FreeImage( pic );
}
pskintype = (daliasskintype_t *)((byte *)(pskintype) + size);
}
for( j = i; i < 4; i++ )
{
m_pAliasHeader->gl_texturenum[skinnum][i & 3] = m_pAliasHeader->gl_texturenum[skinnum][i - j];
m_pAliasHeader->fb_texturenum[skinnum][i & 3] = m_pAliasHeader->fb_texturenum[skinnum][i - j];
}
return pskintype;
}
/*
===============
Mod_LoadAllSkins
@ -516,15 +585,7 @@ Mod_LoadAllSkins
*/
void *Mod_LoadAllSkins( int numskins, daliasskintype_t *pskintype )
{
daliasskininterval_t *pinskinintervals;
int size, groupskins;
string name, lumaname;
daliasskingroup_t *pinskingroup;
int i, j, k;
byte *skin;
rgbdata_t *pic;
skin = (byte *)(pskintype + 1);
int i, size;
if( numskins < 1 || numskins > MAX_SKINS )
Host_Error( "Mod_LoadAliasModel: Invalid # of skins: %d\n", numskins );
@ -535,71 +596,11 @@ void *Mod_LoadAllSkins( int numskins, daliasskintype_t *pskintype )
{
if( pskintype->type == ALIAS_SKIN_SINGLE )
{
// Mod_FloodFillSkin( skin, m_pAliasHeader->skinwidth, m_pAliasHeader->skinheight );
// save 8 bit texels for the player model to remap
m_pAliasHeader->texels[i] = Mem_Alloc( loadmodel->mempool, size );
memcpy( m_pAliasHeader->texels[i], (byte *)(pskintype + 1), size );
Q_snprintf( name, sizeof( name ), "%s:frame%i", loadmodel->name, i );
Q_snprintf( lumaname, sizeof( lumaname ), "%s:luma%i", loadmodel->name, i );
pic = Mod_CreateSkinData( (byte *)(pskintype + 1), m_pAliasHeader->skinwidth, m_pAliasHeader->skinheight );
m_pAliasHeader->gl_texturenum[i][0] =
m_pAliasHeader->gl_texturenum[i][1] =
m_pAliasHeader->gl_texturenum[i][2] =
m_pAliasHeader->gl_texturenum[i][3] = GL_LoadTextureInternal( name, pic, 0, false );
FS_FreeImage( pic );
if( R_GetTexture( m_pAliasHeader->gl_texturenum[i][0] )->flags & TF_HAS_LUMA )
{
pic = Mod_CreateSkinData( (byte *)(pskintype + 1), m_pAliasHeader->skinwidth, m_pAliasHeader->skinheight );
m_pAliasHeader->fb_texturenum[i][0] =
m_pAliasHeader->fb_texturenum[i][1] =
m_pAliasHeader->fb_texturenum[i][2] =
m_pAliasHeader->fb_texturenum[i][3] = GL_LoadTextureInternal( lumaname, pic, TF_MAKELUMA, false );
FS_FreeImage( pic );
}
pskintype = (daliasskintype_t *)((byte *)(pskintype + 1) + size);
pskintype = (daliasskintype_t *)Mod_LoadSignleSkin( pskintype, i, size );
}
else
{
// animating skin group. yuck.
pskintype++;
pinskingroup = (daliasskingroup_t *)pskintype;
groupskins = pinskingroup->numskins;
pinskinintervals = (daliasskininterval_t *)(pinskingroup + 1);
pskintype = (void *)(pinskinintervals + groupskins);
for( j = 0; j < groupskins; j++ )
{
// Mod_FloodFillSkin( skin, m_pAliasHeader->skinwidth, m_pAliasHeader->skinheight );
if( j == 0 )
{
m_pAliasHeader->texels[i] = Mem_Alloc( loadmodel->mempool, size );
memcpy( m_pAliasHeader->texels[i], (byte *)(pskintype), size );
}
Q_snprintf( name, sizeof( name ), "%s_%i_%i", loadmodel->name, i, j );
pic = Mod_CreateSkinData( (byte *)(pskintype), m_pAliasHeader->skinwidth, m_pAliasHeader->skinheight );
m_pAliasHeader->gl_texturenum[i][j & 3] = GL_LoadTextureInternal( name, pic, 0, false );
FS_FreeImage( pic );
if( R_GetTexture( m_pAliasHeader->gl_texturenum[i][j & 3] )->flags & TF_HAS_LUMA )
{
Q_snprintf( lumaname, sizeof( lumaname ), "%s_%i_%i_luma", loadmodel->name, i, j );
pic = Mod_CreateSkinData((byte *)(pskintype), m_pAliasHeader->skinwidth, m_pAliasHeader->skinheight );
m_pAliasHeader->fb_texturenum[i][j & 3] = GL_LoadTextureInternal( lumaname, pic, TF_MAKELUMA, false );
FS_FreeImage( pic );
}
pskintype = (daliasskintype_t *)((byte *)(pskintype) + size);
}
for( k = j; j < 4; j++ )
{
m_pAliasHeader->gl_texturenum[i][j & 3] = m_pAliasHeader->gl_texturenum[i][j - k];
m_pAliasHeader->fb_texturenum[i][j & 3] = m_pAliasHeader->fb_texturenum[i][j - k];
}
pskintype = (daliasskintype_t *)Mod_LoadGroupSkin( pskintype, i, size );
}
}

View File

@ -559,6 +559,7 @@ void FS_FreeImage( rgbdata_t *pack );
extern const bpc_desc_t PFDesc[]; // image get pixelformat
qboolean Image_Process( rgbdata_t **pix, int width, int height, uint flags, imgfilter_t *filter );
void Image_PaletteHueReplace( byte *palSrc, int newHue, int start, int end );
void Image_PaletteTranslate( byte *palSrc, int top, int bottom );
void Image_SetForceFlags( uint flags ); // set image force flags on loading
size_t Image_DXTGetLinearSize( int type, int width, int height, int depth );

View File

@ -1337,25 +1337,27 @@ static qboolean FS_ParseGameInfo( const char *gamedir, gameinfo_t *GameInfo )
{
string liblist_path, gameinfo_path;
string default_gameinfo_path;
string config_path;
gameinfo_t tmpGameInfo;
Q_snprintf( default_gameinfo_path, sizeof( default_gameinfo_path ), "%s/gameinfo.txt", fs_basedir );
Q_snprintf( gameinfo_path, sizeof( gameinfo_path ), "%s/gameinfo.txt", gamedir );
Q_snprintf( liblist_path, sizeof( liblist_path ), "%s/liblist.gam", gamedir );
Q_snprintf( config_path, sizeof( config_path ), "%s/config.cfg", gamedir );
// if user change liblist.gam update the gameinfo.txt
if( FS_FileTime( liblist_path, false ) > FS_FileTime( gameinfo_path, false ))
FS_ConvertGameInfo( gamedir, gameinfo_path, liblist_path );
// force to create gameinfo for specified game if missing
if( !Q_stricmp( fs_gamedir, gamedir ) && !FS_FileExists( gameinfo_path, false ))
if(( FS_FileExists( config_path, false ) || !Q_stricmp( fs_gamedir, gamedir )) && !FS_FileExists( gameinfo_path, false ))
{
memset( &tmpGameInfo, 0, sizeof( tmpGameInfo ));
if( FS_ReadGameInfo( default_gameinfo_path, gamedir, &tmpGameInfo ))
{
// now we have copy of game info from basedir but needs to change gamedir
MsgDev( D_INFO, "converting %s to %s\n", default_gameinfo_path, gameinfo_path );
MsgDev( D_INFO, "Convert %s to %s\n", default_gameinfo_path, gameinfo_path );
Q_strncpy( tmpGameInfo.gamedir, gamedir, sizeof( tmpGameInfo.gamedir ));
FS_WriteGameInfo( gameinfo_path, &tmpGameInfo );
}

View File

@ -281,9 +281,9 @@ int Image_ComparePalette( const byte *pal )
{
if( pal == NULL )
return PAL_INVALID;
else if( !memcmp( palette_q1, pal, 768 ))
else if( !memcmp( palette_q1, pal, 765 )) // last color was changed
return PAL_QUAKE1;
else if( !memcmp( palette_hl, pal, 768 ))
else if( !memcmp( palette_hl, pal, 765 ))
return PAL_HALFLIFE;
return PAL_CUSTOM;
}
@ -522,6 +522,45 @@ void Image_PaletteHueReplace( byte *palSrc, int newHue, int start, int end )
}
}
void Image_PaletteTranslate( byte *palSrc, int top, int bottom )
{
byte dst[256], src[256];
int i;
for( i = 0; i < 256; i++ )
src[i] = i;
memcpy( dst, src, 256 );
if( top < 128 )
{
// the artists made some backwards ranges. sigh.
memcpy( dst + SHIRT_HUE_START, src + top, 16 );
}
else
{
for( i = 0; i < 16; i++ )
dst[SHIRT_HUE_START+i] = src[top + 15 - i];
}
if( bottom < 128 )
{
memcpy( dst + PANTS_HUE_START, src + bottom, 16 );
}
else
{
for( i = 0; i < 16; i++ )
dst[PANTS_HUE_START + i] = src[bottom + 15 - i];
}
// last color isn't changed
for( i = 0; i < 255; i++ )
{
palSrc[i*3+0] = palette_q1[dst[i]*3+0];
palSrc[i*3+1] = palette_q1[dst[i]*3+1];
palSrc[i*3+2] = palette_q1[dst[i]*3+2];
}
}
void Image_CopyParms( rgbdata_t *src )
{
Image_Reset();
@ -1420,9 +1459,16 @@ qboolean Image_RemapInternal( rgbdata_t *pic, int topColor, int bottomColor )
return false;
}
// g-cont. preview images has a swapped top and bottom colors. I don't know why.
Image_PaletteHueReplace( pic->palette, topColor, SUIT_HUE_START, SUIT_HUE_END );
Image_PaletteHueReplace( pic->palette, bottomColor, PLATE_HUE_START, PLATE_HUE_END );
if( Image_ComparePalette( pic->palette ) == PAL_QUAKE1 )
{
Image_PaletteTranslate( pic->palette, topColor * 16, bottomColor * 16 );
}
else
{
// g-cont. preview images has a swapped top and bottom colors. I don't know why.
Image_PaletteHueReplace( pic->palette, topColor, SUIT_HUE_START, SUIT_HUE_END );
Image_PaletteHueReplace( pic->palette, bottomColor, PLATE_HUE_START, PLATE_HUE_END );
}
return true;
}

View File

@ -38,6 +38,11 @@ GNU General Public License for more details.
#define PLATE_HUE_START 160
#define PLATE_HUE_END 191
#define SHIRT_HUE_START 16
#define SHIRT_HUE_END 32
#define PANTS_HUE_START 96
#define PANTS_HUE_END 112
#define LM_SAMPLE_SIZE world.lm_sample_size // lightmap resoultion
#define CHECKVISBIT( vis, b ) ((b) >= 0 ? (byte)((vis)[(b) >> 3] & (1 << ((b) & 7))) : (byte)false )