21 Jul 2017
This commit is contained in:
parent
6298f8f8bc
commit
8ef70775dc
|
@ -1102,7 +1102,7 @@ void GL_DrawAliasFrame( aliashdr_t *paliashdr )
|
|||
VectorLerp( m_bytenormals[verts0->lightnormalindex], g_alias.lerpfrac, m_bytenormals[verts1->lightnormalindex], norm );
|
||||
VectorNormalize( norm );
|
||||
R_AliasLighting( &lv_tmp, norm );
|
||||
pglColor3f( g_alias.lightcolor[0] * lv_tmp, g_alias.lightcolor[1] * lv_tmp, g_alias.lightcolor[2] * lv_tmp );
|
||||
pglColor4f( g_alias.lightcolor[0] * lv_tmp, g_alias.lightcolor[1] * lv_tmp, g_alias.lightcolor[2] * lv_tmp, tr.blend );
|
||||
VectorLerp( verts0->v, g_alias.lerpfrac, verts1->v, vert );
|
||||
pglVertex3fv( vert );
|
||||
verts0++, verts1++;
|
||||
|
@ -1369,6 +1369,8 @@ void R_DrawAliasModel( cl_entity_t *e )
|
|||
m_pAliasHeader = (aliashdr_t *)Mod_AliasExtradata( RI.currententity->model );
|
||||
if( !m_pAliasHeader ) return;
|
||||
|
||||
GL_SetupFogColorForModels();
|
||||
|
||||
// init time
|
||||
R_AliasSetupTimings();
|
||||
|
||||
|
@ -1399,6 +1401,7 @@ void R_DrawAliasModel( cl_entity_t *e )
|
|||
|
||||
// model and frame independant
|
||||
R_AliasSetupLighting( &lighting );
|
||||
GL_SetRenderMode( e->curstate.rendermode );
|
||||
|
||||
pglTranslatef( m_pAliasHeader->scale_origin[0], m_pAliasHeader->scale_origin[1], m_pAliasHeader->scale_origin[2] );
|
||||
|
||||
|
@ -1421,7 +1424,6 @@ void R_DrawAliasModel( cl_entity_t *e )
|
|||
}
|
||||
|
||||
pglShadeModel( GL_SMOOTH );
|
||||
|
||||
R_SetupAliasFrame( e, m_pAliasHeader );
|
||||
|
||||
if( m_pAliasHeader->fb_texturenum[skin][anim] )
|
||||
|
@ -1459,6 +1461,8 @@ void R_DrawAliasModel( cl_entity_t *e )
|
|||
|
||||
// HACKHACK: keep the angles unchanged
|
||||
VectorCopy( angles, e->angles );
|
||||
|
||||
GL_ResetFogColor();
|
||||
}
|
||||
|
||||
//==================================================================================
|
|
@ -102,8 +102,11 @@ qboolean R_CullSurface( msurface_t *surf, gl_frustum_t *frustum, uint clipflags
|
|||
if( !surf || !surf->texinfo || !surf->texinfo->texture )
|
||||
return true;
|
||||
|
||||
if( surf->flags & SURF_WATERCSG && !( e->curstate.effects & EF_NOWATERCSG ))
|
||||
return true;
|
||||
if( !FBitSet( host.features, ENGINE_QUAKE_COMPATIBLE ))
|
||||
{
|
||||
if( surf->flags & SURF_WATERCSG && !( e->curstate.effects & EF_NOWATERCSG ))
|
||||
return true;
|
||||
}
|
||||
|
||||
// don't cull transparent surfaces because we should be draw decals on them
|
||||
if( surf->pdecals && ( e->curstate.rendermode == kRenderTransTexture || e->curstate.rendermode == kRenderTransAdd ))
|
||||
|
|
|
@ -401,6 +401,7 @@ void R_DrawBrushModel( cl_entity_t *e );
|
|||
void GL_SubdivideSurface( msurface_t *fa );
|
||||
void GL_BuildPolygonFromSurface( model_t *mod, msurface_t *fa );
|
||||
void GL_SetupFogColorForSurfaces( void );
|
||||
void GL_SetupFogColorForModels( void );
|
||||
void GL_RebuildLightmaps( void );
|
||||
void GL_InitRandomTable( void );
|
||||
void GL_BuildLightmaps( void );
|
||||
|
|
|
@ -704,6 +704,20 @@ static void R_CheckFog( void )
|
|||
gltexture_t *tex;
|
||||
int i, cnt, count;
|
||||
|
||||
// quake global fog
|
||||
if( clgame.movevars.fog_settings != 0 && FBitSet( host.features, ENGINE_QUAKE_COMPATIBLE ))
|
||||
{
|
||||
// quake-style global fog
|
||||
RI.fogColor[0] = ((clgame.movevars.fog_settings & 0xFF000000) >> 24) / 255.0f;
|
||||
RI.fogColor[1] = ((clgame.movevars.fog_settings & 0xFF0000) >> 16) / 255.0f;
|
||||
RI.fogColor[2] = ((clgame.movevars.fog_settings & 0xFF00) >> 8) / 255.0f;
|
||||
RI.fogDensity = ((clgame.movevars.fog_settings & 0xFF) / 255.0f) * 0.015625f;
|
||||
RI.fogStart = RI.fogEnd = 0.0f;
|
||||
RI.fogCustom = false;
|
||||
RI.fogEnabled = true;
|
||||
return;
|
||||
}
|
||||
|
||||
RI.fogEnabled = false;
|
||||
|
||||
if( cl.local.waterlevel < 2 || !RI.drawWorld || !RI.viewleaf )
|
||||
|
|
|
@ -242,6 +242,28 @@ void GL_SetupFogColorForSurfaces( void )
|
|||
pglFogfv( GL_FOG_COLOR, fogColor );
|
||||
}
|
||||
|
||||
void GL_SetupFogColorForModels( void )
|
||||
{
|
||||
vec3_t fogColor;
|
||||
float factor, div;
|
||||
|
||||
if(( !RI.fogEnabled && !RI.fogCustom ) || RI.onlyClientDraw || !RI.currententity )
|
||||
return;
|
||||
|
||||
if( RI.currententity->curstate.rendermode == kRenderTransTexture )
|
||||
{
|
||||
pglFogfv( GL_FOG_COLOR, RI.fogColor );
|
||||
return;
|
||||
}
|
||||
|
||||
div = 2.0f;
|
||||
factor = 1.0f;
|
||||
fogColor[0] = pow( RI.fogColor[0] / div, ( 1.0f / factor ));
|
||||
fogColor[1] = pow( RI.fogColor[1] / div, ( 1.0f / factor ));
|
||||
fogColor[2] = pow( RI.fogColor[2] / div, ( 1.0f / factor ));
|
||||
pglFogfv( GL_FOG_COLOR, fogColor );
|
||||
}
|
||||
|
||||
void GL_ResetFogColor( void )
|
||||
{
|
||||
// restore fog here
|
||||
|
@ -1395,6 +1417,7 @@ void R_DrawBrushModel( cl_entity_t *e )
|
|||
qboolean need_sort = false;
|
||||
vec3_t origin_l, oldorigin;
|
||||
vec3_t mins, maxs;
|
||||
int rendermode;
|
||||
msurface_t *psurf;
|
||||
model_t *clmodel;
|
||||
qboolean rotated;
|
||||
|
@ -1432,8 +1455,12 @@ void R_DrawBrushModel( cl_entity_t *e )
|
|||
return;
|
||||
|
||||
memset( gl_lms.lightmap_surfaces, 0, sizeof( gl_lms.lightmap_surfaces ));
|
||||
rendermode = e->curstate.rendermode;
|
||||
gl_lms.dynamic_surfaces = NULL;
|
||||
|
||||
if( FBitSet( clmodel->flags, MODEL_TRANSPARENT ) && FBitSet( host.features, ENGINE_QUAKE_COMPATIBLE ))
|
||||
rendermode = kRenderTransAlpha;
|
||||
|
||||
if( rotated ) R_RotateForEntity( e );
|
||||
else R_TranslateForEntity( e );
|
||||
|
||||
|
@ -1456,14 +1483,14 @@ void R_DrawBrushModel( cl_entity_t *e )
|
|||
}
|
||||
|
||||
// setup the rendermode
|
||||
GL_SetRenderMode( e->curstate.rendermode );
|
||||
GL_SetRenderMode( rendermode );
|
||||
GL_SetupFogColorForSurfaces ();
|
||||
|
||||
if( e->curstate.rendermode == kRenderTransTexture && r_lighting_extended->value >= 2.0f )
|
||||
if( rendermode == kRenderTransTexture && r_lighting_extended->value >= 2.0f )
|
||||
pglBlendFunc( GL_DST_COLOR, GL_ONE_MINUS_SRC_ALPHA );
|
||||
|
||||
// setup the color and alpha
|
||||
switch( e->curstate.rendermode )
|
||||
switch( rendermode )
|
||||
{
|
||||
case kRenderTransAdd:
|
||||
if( RI.fogCustom )
|
||||
|
@ -1514,7 +1541,7 @@ void R_DrawBrushModel( cl_entity_t *e )
|
|||
for( i = 0; i < num_sorted; i++ )
|
||||
R_RenderBrushPoly( world.draw_surfaces[i] );
|
||||
|
||||
if( e->curstate.rendermode == kRenderTransColor )
|
||||
if( rendermode == kRenderTransColor )
|
||||
pglEnable( GL_TEXTURE_2D );
|
||||
|
||||
GL_ResetFogColor();
|
||||
|
@ -1523,7 +1550,7 @@ void R_DrawBrushModel( cl_entity_t *e )
|
|||
R_RenderDetails();
|
||||
|
||||
// restore fog here
|
||||
if( e->curstate.rendermode == kRenderTransAdd )
|
||||
if( rendermode == kRenderTransAdd )
|
||||
{
|
||||
if( RI.fogCustom )
|
||||
pglEnable( GL_FOG );
|
||||
|
|
|
@ -30,6 +30,7 @@ convar_t *r_sprite_lerping;
|
|||
convar_t *r_sprite_lighting;
|
||||
char group_suffix[8];
|
||||
static uint r_texFlags = 0;
|
||||
static int sprite_version;
|
||||
float sprite_radius;
|
||||
|
||||
/*
|
||||
|
@ -58,14 +59,17 @@ static dframetype_t *R_SpriteLoadFrame( model_t *mod, void *pin, mspriteframe_t
|
|||
char texname[128], sprname[128];
|
||||
qboolean load_external = false;
|
||||
int gl_texturenum = 0;
|
||||
int bytes = 1;
|
||||
|
||||
pinframe = (dspriteframe_t *)pin;
|
||||
if( sprite_version == SPRITE_VERSION_32 )
|
||||
bytes = 4;
|
||||
|
||||
// build uinque frame name
|
||||
if( FBitSet( mod->flags, MODEL_CLIENT )) // it's a HUD sprite
|
||||
{
|
||||
Q_snprintf( texname, sizeof( texname ), "#HUD/%s_%s_%i%i.spr", mod->name, group_suffix, num / 10, num % 10 );
|
||||
gl_texturenum = GL_LoadTexture( texname, pin, pinframe->width * pinframe->height, r_texFlags, NULL );
|
||||
gl_texturenum = GL_LoadTexture( texname, pin, pinframe->width * pinframe->height * bytes, r_texFlags, NULL );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -87,7 +91,7 @@ static dframetype_t *R_SpriteLoadFrame( model_t *mod, void *pin, mspriteframe_t
|
|||
if( !load_external )
|
||||
{
|
||||
Q_snprintf( texname, sizeof( texname ), "#%s_%s_%i%i.spr", mod->name, group_suffix, num / 10, num % 10 );
|
||||
gl_texturenum = GL_LoadTexture( texname, pin, pinframe->width * pinframe->height, r_texFlags, NULL );
|
||||
gl_texturenum = GL_LoadTexture( texname, pin, pinframe->width * pinframe->height * bytes, r_texFlags, NULL );
|
||||
}
|
||||
else MsgDev( D_NOTE, "loading HQ: %s\n", texname );
|
||||
}
|
||||
|
@ -103,7 +107,7 @@ static dframetype_t *R_SpriteLoadFrame( model_t *mod, void *pin, mspriteframe_t
|
|||
pspriteframe->gl_texturenum = gl_texturenum;
|
||||
*ppframe = pspriteframe;
|
||||
|
||||
return (dframetype_t *)((byte *)(pinframe + 1) + pinframe->width * pinframe->height );
|
||||
return (dframetype_t *)((byte *)(pinframe + 1) + pinframe->width * pinframe->height * bytes );
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -181,15 +185,16 @@ void Mod_LoadSpriteModel( model_t *mod, const void *buffer, qboolean *loaded, ui
|
|||
return;
|
||||
}
|
||||
|
||||
if( i != SPRITE_VERSION_Q1 && i != SPRITE_VERSION_HL )
|
||||
if( i != SPRITE_VERSION_Q1 && i != SPRITE_VERSION_HL && i != SPRITE_VERSION_32 )
|
||||
{
|
||||
MsgDev( D_ERROR, "%s has wrong version number (%i should be %i or %i)\n", mod->name, i, SPRITE_VERSION_Q1, SPRITE_VERSION_HL );
|
||||
return;
|
||||
}
|
||||
|
||||
mod->mempool = Mem_AllocPool( va( "^2%s^7", mod->name ));
|
||||
sprite_version = i;
|
||||
|
||||
if( i == SPRITE_VERSION_Q1 )
|
||||
if( i == SPRITE_VERSION_Q1 || i == SPRITE_VERSION_32 )
|
||||
{
|
||||
pinq1 = (dsprite_q1_t *)buffer;
|
||||
size = sizeof( msprite_t ) + ( pinq1->numframes - 1 ) * sizeof( psprite->frames );
|
||||
|
|
|
@ -391,7 +391,7 @@ void R_DrawSkyBox( void )
|
|||
RI.isSkyVisible = true;
|
||||
|
||||
// don't fogging skybox (this fix old Half-Life bug)
|
||||
if( !RI.fogCustom )
|
||||
if( !RI.fogCustom && !FBitSet( host.features, ENGINE_QUAKE_COMPATIBLE ))
|
||||
pglDisable( GL_FOG );
|
||||
pglDisable( GL_BLEND );
|
||||
pglDisable( GL_ALPHA_TEST );
|
||||
|
|
|
@ -106,10 +106,9 @@ byte *fs_mempool;
|
|||
searchpath_t *fs_searchpaths = NULL; // chain
|
||||
searchpath_t fs_directpath; // static direct path
|
||||
char fs_rootdir[MAX_SYSPATH]; // engine root directory
|
||||
char fs_basedir[MAX_SYSPATH]; // base directory of game
|
||||
char fs_falldir[MAX_SYSPATH]; // game falling directory
|
||||
char fs_basedir[MAX_SYSPATH]; // base game directory
|
||||
char fs_gamedir[MAX_SYSPATH]; // game current directory
|
||||
char gs_basedir[MAX_SYSPATH]; // initial dir before loading gameinfo.txt (used for compilers too)
|
||||
char fs_writedir[MAX_SYSPATH]; // path that game allows to overwrite, delete and rename files (and create new of course)
|
||||
qboolean fs_ext_path = false; // attempt to read\write from ./ or ../ pathes
|
||||
static const wadtype_t wad_hints[10];
|
||||
|
||||
|
@ -634,7 +633,7 @@ static qboolean FS_AddPak_Fullpath( const char *pakfile, qboolean *already_loade
|
|||
================
|
||||
FS_AddGameDirectory
|
||||
|
||||
Sets fs_gamedir, adds the directory to the head of the path,
|
||||
Sets fs_writedir, adds the directory to the head of the path,
|
||||
then loads and adds pak1.pak pak2.pak ...
|
||||
================
|
||||
*/
|
||||
|
@ -646,7 +645,7 @@ void FS_AddGameDirectory( const char *dir, int flags )
|
|||
int i;
|
||||
|
||||
if( !FBitSet( flags, FS_NOWRITE_PATH ))
|
||||
Q_strncpy( fs_gamedir, dir, sizeof( fs_gamedir ));
|
||||
Q_strncpy( fs_writedir, dir, sizeof( fs_writedir ));
|
||||
|
||||
stringlistinit( &list );
|
||||
listdirectory( &list, dir );
|
||||
|
@ -694,7 +693,7 @@ FS_AddGameHierarchy
|
|||
void FS_AddGameHierarchy( const char *dir, int flags )
|
||||
{
|
||||
// Add the common game directory
|
||||
if( dir && *dir ) FS_AddGameDirectory( va( "%s%s/", fs_basedir, dir ), flags );
|
||||
if( dir && *dir ) FS_AddGameDirectory( va( "%s/", dir ), flags );
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -886,13 +885,10 @@ FS_WriteGameInfo
|
|||
assume GameInfo is valid
|
||||
================
|
||||
*/
|
||||
static qboolean FS_WriteGameInfo( const char *filepath, gameinfo_t *GameInfo )
|
||||
static void FS_WriteGameInfo( const char *filepath, gameinfo_t *GameInfo )
|
||||
{
|
||||
file_t *f;
|
||||
|
||||
if( !GameInfo ) return false;
|
||||
f = FS_Open( filepath, "w", false ); // we in binary-mode
|
||||
if( !f ) return false;
|
||||
file_t *f = FS_Open( filepath, "w", false ); // we in binary-mode
|
||||
if( !f ) Sys_Error( "FS_WriteGameInfo: can't write %s\n", filepath ); // may be disk-space is out?
|
||||
|
||||
FS_Print( f, "// generated by Xash3D\n\n\n" );
|
||||
|
||||
|
@ -968,8 +964,6 @@ static qboolean FS_WriteGameInfo( const char *filepath, gameinfo_t *GameInfo )
|
|||
|
||||
FS_Print( f, "\n\n\n" );
|
||||
FS_Close( f ); // all done
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -992,8 +986,8 @@ void FS_CreateDefaultGameInfo( const char *filename )
|
|||
defGI.falldir[0] = '\0';
|
||||
|
||||
Q_strncpy( defGI.title, "New Game", sizeof( defGI.title ));
|
||||
Q_strncpy( defGI.gamedir, gs_basedir, sizeof( defGI.gamedir ));
|
||||
Q_strncpy( defGI.basedir, SI.basedirName, sizeof( defGI.basedir ));
|
||||
Q_strncpy( defGI.gamedir, fs_gamedir, sizeof( defGI.gamedir ));
|
||||
Q_strncpy( defGI.basedir, fs_basedir, sizeof( defGI.basedir ));
|
||||
Q_strncpy( defGI.sp_entity, "info_player_start", sizeof( defGI.sp_entity ));
|
||||
Q_strncpy( defGI.mp_entity, "info_player_deathmatch", sizeof( defGI.mp_entity ));
|
||||
Q_strncpy( defGI.dll_path, "cl_dlls", sizeof( defGI.dll_path ));
|
||||
|
@ -1029,7 +1023,7 @@ static qboolean FS_ParseLiblistGam( const char *filename, const char *gamedir, g
|
|||
|
||||
Q_strncpy( GameInfo->title, "New Game", sizeof( GameInfo->title ));
|
||||
Q_strncpy( GameInfo->gamedir, gamedir, sizeof( GameInfo->gamedir ));
|
||||
Q_strncpy( GameInfo->basedir, SI.basedirName, sizeof( GameInfo->basedir ));
|
||||
Q_strncpy( GameInfo->basedir, fs_basedir, sizeof( GameInfo->basedir ));
|
||||
Q_strncpy( GameInfo->sp_entity, "info_player_start", sizeof( GameInfo->sp_entity ));
|
||||
Q_strncpy( GameInfo->mp_entity, "info_player_deathmatch", sizeof( GameInfo->mp_entity ));
|
||||
Q_strncpy( GameInfo->game_dll, "dlls/hl.dll", sizeof( GameInfo->game_dll ));
|
||||
|
@ -1153,34 +1147,16 @@ void FS_ConvertGameInfo( const char *gamedir, const char *gameinfo_path, const c
|
|||
|
||||
if( FS_ParseLiblistGam( liblist_path, gamedir, &GameInfo ))
|
||||
{
|
||||
if( FS_WriteGameInfo( gameinfo_path, &GameInfo ))
|
||||
MsgDev( D_INFO, "Convert %s to %s\n", liblist_path, gameinfo_path );
|
||||
MsgDev( D_INFO, "Convert %s to %s\n", liblist_path, gameinfo_path );
|
||||
FS_WriteGameInfo( gameinfo_path, &GameInfo );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
FS_ParseGameInfo
|
||||
================
|
||||
*/
|
||||
static qboolean FS_ParseGameInfo( const char *gamedir, gameinfo_t *GameInfo )
|
||||
static qboolean FS_ReadGameInfo( const char *filepath, const char *gamedir, gameinfo_t *GameInfo )
|
||||
{
|
||||
char *afile, *pfile;
|
||||
string fs_path, filepath;
|
||||
string liblist, token;
|
||||
|
||||
Q_snprintf( filepath, sizeof( filepath ), "%s/gameinfo.txt", gamedir );
|
||||
Q_snprintf( liblist, sizeof( liblist ), "%s/liblist.gam", gamedir );
|
||||
|
||||
// if user change liblist.gam update the gameinfo.txt
|
||||
if( FS_FileTime( liblist, false ) > FS_FileTime( filepath, false ))
|
||||
FS_ConvertGameInfo( gamedir, filepath, liblist );
|
||||
|
||||
// force to create gameinfo for specified game if missing
|
||||
if( !Q_stricmp( gs_basedir, gamedir ) && !FS_FileExists( filepath, false ))
|
||||
FS_CreateDefaultGameInfo( filepath );
|
||||
|
||||
if( !GameInfo ) return false; // no dest
|
||||
char token[1204];
|
||||
string fs_path;
|
||||
|
||||
afile = FS_LoadFile( filepath, NULL, false );
|
||||
if( !afile ) return false;
|
||||
|
@ -1329,7 +1305,7 @@ static qboolean FS_ParseGameInfo( const char *gamedir, gameinfo_t *GameInfo )
|
|||
|
||||
if( ambientNum < 0 || ambientNum > ( NUM_AMBIENTS - 1 ))
|
||||
{
|
||||
MsgDev( D_ERROR, "FS_ParseGameInfo: Invalid ambient number %i. Ignored.\n", ambientNum );
|
||||
MsgDev( D_ERROR, "FS_ReadGameInfo: Invalid ambient number %i. Ignored.\n", ambientNum );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1342,6 +1318,7 @@ static qboolean FS_ParseGameInfo( const char *gamedir, gameinfo_t *GameInfo )
|
|||
if( !FS_SysFolderExists( va( "%s\\%s", host.rootdir, GameInfo->gamedir )))
|
||||
Q_strncpy( GameInfo->gamedir, gamedir, sizeof( GameInfo->gamedir ));
|
||||
|
||||
// make sure what fallback_dir is really exist
|
||||
if( !FS_SysFolderExists( va( "%s\\%s", host.rootdir, GameInfo->falldir )))
|
||||
GameInfo->falldir[0] = '\0';
|
||||
|
||||
|
@ -1351,6 +1328,48 @@ static qboolean FS_ParseGameInfo( const char *gamedir, gameinfo_t *GameInfo )
|
|||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
FS_ParseGameInfo
|
||||
================
|
||||
*/
|
||||
static qboolean FS_ParseGameInfo( const char *gamedir, gameinfo_t *GameInfo )
|
||||
{
|
||||
string liblist_path, gameinfo_path;
|
||||
string default_gameinfo_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 );
|
||||
|
||||
// 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 ))
|
||||
{
|
||||
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 );
|
||||
Q_strncpy( tmpGameInfo.gamedir, gamedir, sizeof( tmpGameInfo.gamedir ));
|
||||
FS_WriteGameInfo( gameinfo_path, &tmpGameInfo );
|
||||
}
|
||||
else FS_CreateDefaultGameInfo( gameinfo_path );
|
||||
}
|
||||
|
||||
if( !GameInfo || !FS_FileExists( gameinfo_path, false ))
|
||||
return false; // no dest
|
||||
|
||||
if( FS_ReadGameInfo( gameinfo_path, gamedir, GameInfo ))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
FS_LoadGameInfo
|
||||
|
@ -1365,8 +1384,8 @@ void FS_LoadGameInfo( const char *rootfolder )
|
|||
// lock uplevel of gamedir for read\write
|
||||
fs_ext_path = false;
|
||||
|
||||
if( rootfolder ) Q_strcpy( gs_basedir, rootfolder );
|
||||
MsgDev( D_NOTE, "FS_LoadGameInfo( %s )\n", gs_basedir );
|
||||
if( rootfolder ) Q_strcpy( fs_gamedir, rootfolder );
|
||||
MsgDev( D_NOTE, "FS_LoadGameInfo( %s )\n", fs_gamedir );
|
||||
|
||||
// clear any old pathes
|
||||
FS_ClearSearchPath();
|
||||
|
@ -1374,12 +1393,12 @@ void FS_LoadGameInfo( const char *rootfolder )
|
|||
// validate gamedir
|
||||
for( i = 0; i < SI.numgames; i++ )
|
||||
{
|
||||
if( !Q_stricmp( SI.games[i]->gamefolder, gs_basedir ))
|
||||
if( !Q_stricmp( SI.games[i]->gamefolder, fs_gamedir ))
|
||||
break;
|
||||
}
|
||||
|
||||
if( i == SI.numgames )
|
||||
Sys_Error( "Couldn't find game directory '%s'\n", gs_basedir );
|
||||
Sys_Error( "Couldn't find game directory '%s'\n", fs_gamedir );
|
||||
|
||||
SI.GameInfo = SI.games[i];
|
||||
FS_Rescan(); // create new filesystem
|
||||
|
@ -1395,7 +1414,8 @@ FS_Init
|
|||
void FS_Init( void )
|
||||
{
|
||||
stringlist_t dirs;
|
||||
qboolean hasDefaultDir = false;
|
||||
qboolean hasBaseDir = false;
|
||||
qboolean hasGameDir = false;
|
||||
int i;
|
||||
|
||||
FS_InitMemory();
|
||||
|
@ -1411,30 +1431,38 @@ void FS_Init( void )
|
|||
listdirectory( &dirs, "./" );
|
||||
stringlistsort( &dirs );
|
||||
SI.numgames = 0;
|
||||
|
||||
if( !Sys_GetParmFromCmdLine( "-game", gs_basedir ))
|
||||
Q_strcpy( gs_basedir, SI.basedirName ); // default dir
|
||||
|
||||
if( FS_CheckNastyPath( gs_basedir, true ))
|
||||
Q_strncpy( fs_basedir, SI.basedirName, sizeof( fs_basedir )); // default dir
|
||||
|
||||
if( !Sys_GetParmFromCmdLine( "-game", fs_gamedir ))
|
||||
Q_strncpy( fs_gamedir, fs_basedir, sizeof( fs_gamedir )); // gamedir == basedir
|
||||
|
||||
if( FS_CheckNastyPath( fs_basedir, true ))
|
||||
{
|
||||
MsgDev( D_ERROR, "FS_Init: invalid game directory \"%s\"\n", gs_basedir );
|
||||
Q_strcpy( gs_basedir, SI.basedirName ); // default dir
|
||||
// this is completely fatal...
|
||||
Sys_Error( "FS_Init: invalid base directory \"%s\"\n", fs_basedir );
|
||||
}
|
||||
|
||||
if( FS_CheckNastyPath( fs_gamedir, true ))
|
||||
{
|
||||
MsgDev( D_ERROR, "FS_Init: invalid game directory \"%s\"\n", fs_gamedir );
|
||||
Q_strncpy( fs_gamedir, fs_basedir, sizeof( fs_gamedir )); // default dir
|
||||
}
|
||||
|
||||
// validate directories
|
||||
for( i = 0; i < dirs.numstrings; i++ )
|
||||
{
|
||||
if( !Q_stricmp( SI.basedirName, dirs.strings[i] ))
|
||||
hasDefaultDir = true;
|
||||
if( !Q_stricmp( fs_basedir, dirs.strings[i] ))
|
||||
hasBaseDir = true;
|
||||
|
||||
if( !Q_stricmp( gs_basedir, dirs.strings[i] ))
|
||||
break;
|
||||
if( !Q_stricmp( fs_gamedir, dirs.strings[i] ))
|
||||
hasGameDir = true;
|
||||
}
|
||||
|
||||
if( i == dirs.numstrings )
|
||||
if( !hasGameDir )
|
||||
{
|
||||
MsgDev( D_INFO, "FS_Init: game directory \"%s\" not exist\n", gs_basedir );
|
||||
if( hasDefaultDir ) Q_strncpy( gs_basedir, SI.basedirName, sizeof( gs_basedir )); // default dir
|
||||
MsgDev( D_ERROR, "FS_Init: game directory \"%s\" not exist\n", fs_gamedir );
|
||||
if( hasBaseDir ) Q_strncpy( fs_gamedir, fs_basedir, sizeof( fs_gamedir ));
|
||||
}
|
||||
|
||||
// build list of game directories here
|
||||
|
@ -1442,10 +1470,10 @@ void FS_Init( void )
|
|||
|
||||
for( i = 0; i < dirs.numstrings; i++ )
|
||||
{
|
||||
if( !FS_SysFolderExists( dirs.strings[i] ) || (!Q_stricmp( dirs.strings[i], ".." ) && !fs_ext_path ))
|
||||
if( !FS_SysFolderExists( dirs.strings[i] ) || ( !Q_stricmp( dirs.strings[i], ".." ) && !fs_ext_path ))
|
||||
continue;
|
||||
|
||||
if( !SI.games[SI.numgames] )
|
||||
if( SI.games[SI.numgames] == NULL )
|
||||
SI.games[SI.numgames] = (gameinfo_t *)Mem_Alloc( fs_mempool, sizeof( gameinfo_t ));
|
||||
|
||||
if( FS_ParseGameInfo( dirs.strings[i], SI.games[SI.numgames] ))
|
||||
|
@ -1853,7 +1881,7 @@ file_t *FS_Open( const char *filepath, const char *mode, qboolean gamedironly )
|
|||
char real_path[MAX_SYSPATH];
|
||||
|
||||
// open the file on disk directly
|
||||
Q_sprintf( real_path, "%s/%s", fs_gamedir, filepath );
|
||||
Q_sprintf( real_path, "%s/%s", fs_writedir, filepath );
|
||||
FS_CreatePath( real_path );// Create directories up to the file
|
||||
return FS_SysOpen( real_path, mode );
|
||||
}
|
||||
|
@ -2552,8 +2580,8 @@ qboolean FS_Rename( const char *oldname, const char *newname )
|
|||
if( !oldname || !newname || !*oldname || !*newname )
|
||||
return false;
|
||||
|
||||
Q_snprintf( oldpath, sizeof( oldpath ), "%s%s", fs_gamedir, oldname );
|
||||
Q_snprintf( newpath, sizeof( newpath ), "%s%s", fs_gamedir, newname );
|
||||
Q_snprintf( oldpath, sizeof( oldpath ), "%s%s", fs_writedir, oldname );
|
||||
Q_snprintf( newpath, sizeof( newpath ), "%s%s", fs_writedir, newname );
|
||||
|
||||
COM_FixSlashes( oldpath );
|
||||
COM_FixSlashes( newpath );
|
||||
|
@ -2578,7 +2606,7 @@ qboolean FS_Delete( const char *path )
|
|||
if( !path || !*path )
|
||||
return false;
|
||||
|
||||
Q_snprintf( real_path, sizeof( real_path ), "%s%s", fs_gamedir, path );
|
||||
Q_snprintf( real_path, sizeof( real_path ), "%s%s", fs_writedir, path );
|
||||
COM_FixSlashes( real_path );
|
||||
iRet = remove( real_path );
|
||||
|
||||
|
@ -2840,11 +2868,6 @@ search_t *FS_Search( const char *pattern, int caseinsensitive, int gamedironly )
|
|||
void FS_InitMemory( void )
|
||||
{
|
||||
fs_mempool = Mem_AllocPool( "FileSystem Pool" );
|
||||
|
||||
// add a path separator to the end of the basedir if it lacks one
|
||||
if( fs_basedir[0] && fs_basedir[Q_strlen(fs_basedir) - 1] != '/' && fs_basedir[Q_strlen(fs_basedir) - 1] != '\\' )
|
||||
Q_strncat( fs_basedir, "/", sizeof( fs_basedir ));
|
||||
|
||||
fs_searchpaths = NULL;
|
||||
}
|
||||
|
||||
|
|
|
@ -188,6 +188,7 @@ Image_LoadSPR
|
|||
qboolean Image_LoadSPR( const char *name, const byte *buffer, size_t filesize )
|
||||
{
|
||||
dspriteframe_t *pin; // identical for q1\hl sprites
|
||||
qboolean truecolor = false;
|
||||
|
||||
if( image.hint == IL_HINT_HL )
|
||||
{
|
||||
|
@ -217,9 +218,12 @@ qboolean Image_LoadSPR( const char *name, const byte *buffer, size_t filesize )
|
|||
return false;
|
||||
}
|
||||
|
||||
if( filesize == ( image.width * image.height * 4 ))
|
||||
truecolor = true;
|
||||
|
||||
// sorry, can't validate palette rendermode
|
||||
if( !Image_LumpValidSize( name )) return false;
|
||||
image.type = PF_INDEXED_32; // 32-bit palete
|
||||
image.type = (truecolor) ? PF_RGBA_32 : PF_INDEXED_32; // 32-bit palete
|
||||
image.depth = 1;
|
||||
|
||||
// detect alpha-channel by palette type
|
||||
|
@ -232,6 +236,16 @@ qboolean Image_LoadSPR( const char *name, const byte *buffer, size_t filesize )
|
|||
break;
|
||||
}
|
||||
|
||||
if( truecolor )
|
||||
{
|
||||
// spr32 support
|
||||
image.size = image.width * image.height * 4;
|
||||
image.rgba = Mem_Alloc( host.imagepool, image.size );
|
||||
memcpy( image.rgba, (byte *)(pin + 1), image.size );
|
||||
SetBits( image.flags, IMAGE_HAS_COLOR ); // Color. True Color!
|
||||
return true;
|
||||
}
|
||||
|
||||
return Image_AddIndexedImageToPack( (byte *)(pin + 1), image.width, image.height );
|
||||
}
|
||||
|
||||
|
@ -261,7 +275,7 @@ qboolean Image_LoadLMP( const char *name, const byte *buffer, size_t filesize )
|
|||
if( image.hint != IL_HINT_HL && Q_stristr( name, "conchars" ))
|
||||
{
|
||||
image.width = image.height = 128;
|
||||
rendermode = LUMP_MASKED;
|
||||
rendermode = LUMP_QUAKE1;
|
||||
filesize += sizeof( lmp );
|
||||
fin = (byte *)buffer;
|
||||
|
||||
|
@ -411,10 +425,10 @@ qboolean Image_LoadMIP( const char *name, const byte *buffer, size_t filesize )
|
|||
|
||||
hl_texture = false;
|
||||
|
||||
// check for luma pixels
|
||||
// check for luma and alpha pixels
|
||||
for( i = 0; i < image.width * image.height; i++ )
|
||||
{
|
||||
if( fin[i] > 224 )
|
||||
if( fin[i] > 224 && fin[i] != 255 )
|
||||
{
|
||||
// don't apply luma to water surfaces because
|
||||
// we use glpoly->next for store luma chain each frame
|
||||
|
@ -427,6 +441,19 @@ qboolean Image_LoadMIP( const char *name, const byte *buffer, size_t filesize )
|
|||
}
|
||||
}
|
||||
|
||||
// Arcane Dimensions has the transparent textures
|
||||
if( Q_strrchr( name, '{' ))
|
||||
{
|
||||
for( i = 0; i < image.width * image.height; i++ )
|
||||
{
|
||||
if( fin[i] == 255 )
|
||||
{
|
||||
image.flags |= IMAGE_HAS_ALPHA;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Image_GetPaletteQ1();
|
||||
}
|
||||
else
|
||||
|
|
|
@ -52,6 +52,7 @@ GNU General Public License for more details.
|
|||
#define MODEL_CONVEYOR BIT( 0 )
|
||||
#define MODEL_HAS_ORIGIN BIT( 1 )
|
||||
#define MODEL_LIQUID BIT( 2 ) // model has only point hull
|
||||
#define MODEL_TRANSPARENT BIT( 3 ) // have transparent surfaces
|
||||
|
||||
#define MODEL_CLIENT BIT( 30 ) // client sprite
|
||||
|
||||
|
|
|
@ -2318,6 +2318,9 @@ static void Mod_LoadBrushModel( model_t *mod, const void *buffer, qboolean *load
|
|||
if( surf->flags & SURF_CONVEYOR )
|
||||
mod->flags |= MODEL_CONVEYOR;
|
||||
|
||||
if( surf->flags & SURF_TRANSPARENT )
|
||||
mod->flags |= MODEL_TRANSPARENT;
|
||||
|
||||
// kill water backplanes for submodels (half-life rules)
|
||||
if( surf->flags & SURF_DRAWTURB )
|
||||
{
|
||||
|
|
|
@ -58,6 +58,7 @@ CVAR_DEFINE_AUTO( logsdir, "logs", 0, "place to store multiplayer logs" );
|
|||
CVAR_DEFINE_AUTO( bannedcfgfile, "banned.cfg", 0, "name of list of banned users" );
|
||||
CVAR_DEFINE_AUTO( deathmatch, "0", 0, "deathmatch mode in multiplayer game" );
|
||||
CVAR_DEFINE_AUTO( coop, "0", 0, "cooperative mode in multiplayer game" );
|
||||
CVAR_DEFINE_AUTO( teamplay, "0", 0, "team mode in multiplayer game" );
|
||||
CVAR_DEFINE_AUTO( skill, "1", 0, "skill level in singleplayer game" );
|
||||
|
||||
// physic-related variables
|
||||
|
@ -732,6 +733,7 @@ void SV_Init( void )
|
|||
Cvar_RegisterVariable (&motdfile);
|
||||
Cvar_RegisterVariable (&deathmatch);
|
||||
Cvar_RegisterVariable (&coop);
|
||||
Cvar_RegisterVariable (&teamplay);
|
||||
Cvar_RegisterVariable (&skill);
|
||||
|
||||
Cvar_RegisterVariable (&rcon_password);
|
||||
|
|
|
@ -29,6 +29,7 @@ SPRITE MODELS
|
|||
|
||||
#define SPRITE_VERSION_Q1 1 // Quake sprites
|
||||
#define SPRITE_VERSION_HL 2 // Half-Life sprites
|
||||
#define SPRITE_VERSION_32 32 // Captain Obvious mode on
|
||||
|
||||
// must match definition in alias.h
|
||||
#ifndef SYNCTYPE_T
|
||||
|
|
Reference in New Issue