From c58a2c5893b60fbdd9b6ef5347992678c72077e7 Mon Sep 17 00:00:00 2001 From: g-cont Date: Sat, 29 Jul 2017 00:00:00 +0300 Subject: [PATCH] 29 Jul 2017 --- common/com_model.h | 1 - engine/client/gl_alias.c | 143 +++++++++++++++-------------- engine/common/common.h | 1 + engine/common/filesystem.c | 6 +- engine/common/imagelib/img_utils.c | 56 ++++++++++- engine/common/mod_local.h | 5 + 6 files changed, 133 insertions(+), 79 deletions(-) diff --git a/common/com_model.h b/common/com_model.h index 531eab4b..f9c53cfc 100644 --- a/common/com_model.h +++ b/common/com_model.h @@ -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; diff --git a/engine/client/gl_alias.c b/engine/client/gl_alias.c index b965a999..d5a9e707 100644 --- a/engine/client/gl_alias.c +++ b/engine/client/gl_alias.c @@ -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 ); } } diff --git a/engine/common/common.h b/engine/common/common.h index d98811ed..afade268 100644 --- a/engine/common/common.h +++ b/engine/common/common.h @@ -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 ); diff --git a/engine/common/filesystem.c b/engine/common/filesystem.c index f8811223..bb7adb04 100644 --- a/engine/common/filesystem.c +++ b/engine/common/filesystem.c @@ -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 ); } diff --git a/engine/common/imagelib/img_utils.c b/engine/common/imagelib/img_utils.c index 68044c27..8fe520ea 100644 --- a/engine/common/imagelib/img_utils.c +++ b/engine/common/imagelib/img_utils.c @@ -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; } diff --git a/engine/common/mod_local.h b/engine/common/mod_local.h index 41795b51..823a062c 100644 --- a/engine/common/mod_local.h +++ b/engine/common/mod_local.h @@ -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 )