diff --git a/common/bspfile.h b/common/bspfile.h index 42b3a215..f0c4b300 100644 --- a/common/bspfile.h +++ b/common/bspfile.h @@ -16,6 +16,8 @@ GNU General Public License for more details. #ifndef BSPFILE_H #define BSPFILE_H +//#define SUPPORT_BSP2_FORMAT // allow to loading Darkplaces BSP2 maps (with broke binary compatibility) + /* ============================================================================== @@ -63,9 +65,18 @@ BRUSH MODELS #define LS_UNUSED 0xFE #define LS_NONE 0xFF +#ifdef SUPPORT_BSP2_FORMAT +#define MAX_MAP_MODELS 2048 // can be increased up to 2048 if needed +#define MAX_MAP_ENTSTRING 0x200000 // 2 Mb should be enough +#define MAX_MAP_PLANES 131072 // can be increased without problems +#define MAX_MAP_NODES 262144 // because negative shorts are leafs +#define MAX_MAP_CLIPNODES 524288 // because negative shorts are contents +#define MAX_MAP_LEAFS 131072 // CRITICAL STUFF to run ad_sepulcher!!! +#define MAX_MAP_VERTS 524288 // unsigned short limit +#define MAX_MAP_FACES 262144 // unsigned short limit +#define MAX_MAP_MARKSURFACES 524288 // unsigned short limit +#else #define MAX_MAP_MODELS 1024 // can be increased up to 2048 if needed -#define MAX_MAP_BRUSHES 32768 // unsigned short limit -#define MAX_MAP_ENTITIES 8192 // can be increased up to 32768 if needed #define MAX_MAP_ENTSTRING 0x80000 // 512 kB should be enough #define MAX_MAP_PLANES 65536 // can be increased without problems #define MAX_MAP_NODES 32767 // because negative shorts are leafs @@ -74,6 +85,10 @@ BRUSH MODELS #define MAX_MAP_VERTS 65535 // unsigned short limit #define MAX_MAP_FACES 65535 // unsigned short limit #define MAX_MAP_MARKSURFACES 65535 // unsigned short limit +#endif + +#define MAX_MAP_BRUSHES 32768 // unsigned short limit +#define MAX_MAP_ENTITIES 8192 // can be increased up to 32768 if needed #define MAX_MAP_TEXINFO MAX_MAP_FACES // in theory each face may have personal texinfo #define MAX_MAP_EDGES 0x100000 // can be increased but not needed #define MAX_MAP_SURFEDGES 0x200000 // can be increased but not needed diff --git a/common/com_model.h b/common/com_model.h index 28dc1db5..5275e679 100644 --- a/common/com_model.h +++ b/common/com_model.h @@ -31,7 +31,6 @@ typedef vec_t vec4_t[4]; #define STUDIO_EVENTS 2 #define ZISCALE ((float)0x8000) -//#define SUPPORT_BSP2_FORMAT #define MIPLEVELS 4 #define VERTEXSIZE 7 diff --git a/common/features.h b/common/features.h index 3c17382c..30d50396 100644 --- a/common/features.h +++ b/common/features.h @@ -20,7 +20,7 @@ GNU General Public License for more details. #define ENGINE_WRITE_LARGE_COORD (1<<0) // replace standard message WRITE_COORD with big message for support more than 8192 units in world #define ENGINE_QUAKE_COMPATIBLE (1<<1) // make engine compatible with quake (flags and effects) #define ENGINE_LOAD_DELUXEDATA (1<<2) // loading deluxemap for map (if present) -#define ENGINE_TRANSFORM_TRACE_AABB (1<<3) // transform trace bbox into local space of rotating bmodels +#define ENGINE_PHYSICS_PUSHER_EXT (1<<3) // enable sets of improvements for MOVETYPE_PUSH physics #define ENGINE_LARGE_LIGHTMAPS (1<<4) // change lightmap sizes from 128x128 to 1024x1024 #define ENGINE_COMPENSATE_QUAKE_BUG (1<<5) // compensate stupid quake bug (inverse pitch) for mods where this bug is fixed #define ENGINE_DISABLE_HDTEXTURES (1<<6) // disable support of HD-textures in case custom renderer have separate way to load them diff --git a/engine/client/cl_frame.c b/engine/client/cl_frame.c index bf03599f..edd115d1 100644 --- a/engine/client/cl_frame.c +++ b/engine/client/cl_frame.c @@ -1084,7 +1084,10 @@ void CL_LinkPacketEntities( frame_t *frame ) { // auto 'solid' faces if( FBitSet( ent->model->flags, MODEL_TRANSPARENT ) && FBitSet( host.features, ENGINE_QUAKE_COMPATIBLE )) + { ent->curstate.rendermode = kRenderTransAlpha; + ent->curstate.renderamt = 255; + } } parametric = ( ent->curstate.impacttime != 0.0f && ent->curstate.starttime != 0.0f ); @@ -1170,6 +1173,9 @@ void CL_LinkPacketEntities( frame_t *frame ) // NOTE: never pass sprites with rendercolor '0 0 0' it's a stupid Valve Hammer Editor bug if( !ent->curstate.rendercolor.r && !ent->curstate.rendercolor.g && !ent->curstate.rendercolor.b ) ent->curstate.rendercolor.r = ent->curstate.rendercolor.g = ent->curstate.rendercolor.b = 255; + + if( ent->model->type == mod_sprite ) + R_SetSpriteRenderamt( ent, ent->model ); } if( ent->curstate.aiment != 0 && ent->curstate.movetype != MOVETYPE_COMPOUND ) diff --git a/engine/client/cl_game.c b/engine/client/cl_game.c index f3274b42..0c55a809 100644 --- a/engine/client/cl_game.c +++ b/engine/client/cl_game.c @@ -2263,7 +2263,7 @@ int CL_FindModelIndex( const char *m ) if( cls.state == ca_active ) { // tell user about problem (but don't spam console about playermodel) - MsgDev( D_NOTE, "CL_ModelIndex: %s not precached\n", m ); + MsgDev( D_ERROR, "CL_ModelIndex: %s not precached\n", m ); } return 0; diff --git a/engine/client/cl_parse.c b/engine/client/cl_parse.c index 43c1ad45..e9e94c7f 100644 --- a/engine/client/cl_parse.c +++ b/engine/client/cl_parse.c @@ -557,6 +557,16 @@ void CL_ParseStaticEntity( sizebuf_t *msg ) ent->curstate.framerate = 1.0f; CL_ResetLatchedVars( ent, true ); + if( ent->curstate.rendermode == kRenderNormal && ent->model != NULL ) + { + // auto 'solid' faces + if( FBitSet( ent->model->flags, MODEL_TRANSPARENT ) && FBitSet( host.features, ENGINE_QUAKE_COMPATIBLE )) + { + ent->curstate.rendermode = kRenderTransAlpha; + ent->curstate.renderamt = 255; + } + } + R_AddEfrags( ent ); // add link } @@ -685,7 +695,7 @@ void CL_ParseServerData( sizebuf_t *msg ) cl.playernum = MSG_ReadByte( msg ); cl.maxclients = MSG_ReadByte( msg ); clgame.maxEntities = MSG_ReadWord( msg ); - clgame.maxEntities = bound( 600, clgame.maxEntities, 4096 ); + clgame.maxEntities = bound( 600, clgame.maxEntities, MAX_EDICTS ); Q_strncpy( clgame.mapname, MSG_ReadString( msg ), MAX_STRING ); Q_strncpy( clgame.maptitle, MSG_ReadString( msg ), MAX_STRING ); background = MSG_ReadOneBit( msg ); diff --git a/engine/client/cl_scrn.c b/engine/client/cl_scrn.c index 90ae8cfc..b641358b 100644 --- a/engine/client/cl_scrn.c +++ b/engine/client/cl_scrn.c @@ -313,6 +313,9 @@ void SCR_BeginLoadingPlaque( qboolean is_background ) if( cls.state == ca_disconnected ) return; // if at console, don't bring up the plaque if( cls.key_dest == key_console ) return; + if( CL_IsInMenu( ) && !cls.changedemo && !is_background ) + UI_SetActiveMenu( false ); + cls.draw_changelevel = is_background ? false : true; SCR_UpdateScreen(); cls.disable_screen = host.realtime; diff --git a/engine/client/cl_tent.c b/engine/client/cl_tent.c index 4516c02e..31a2bf37 100644 --- a/engine/client/cl_tent.c +++ b/engine/client/cl_tent.c @@ -257,15 +257,8 @@ void CL_PrepareTEnt( TEMPENTITY *pTemp, model_t *pmodel ) pTemp->flags = FTENT_NONE; pTemp->die = cl.time + 0.75f; - if( pmodel ) - { - modelIndex = CL_FindModelIndex( pmodel->name ); - Mod_GetFrames( modelIndex, &frameCount ); - } - else - { - pTemp->flags |= FTENT_NOMODEL; - } + if( pmodel ) frameCount = Mod_FrameCount( pmodel ); + else pTemp->flags |= FTENT_NOMODEL; pTemp->entity.curstate.modelindex = modelIndex; pTemp->entity.curstate.rendermode = kRenderNormal; @@ -861,14 +854,10 @@ Create rocket flare void R_RocketFlare( const vec3_t pos ) { TEMPENTITY *pTemp; - model_t *pmodel; - int modelIndex; - modelIndex = CL_FindModelIndex( "sprites/animglow01.spr" ); - pmodel = Mod_Handle( modelIndex ); - if( !pmodel ) return; + if( !cl_sprite_glow ) return; - pTemp = CL_TempEntAlloc( pos, pmodel ); + pTemp = CL_TempEntAlloc( pos, cl_sprite_glow ); if ( !pTemp ) return; pTemp->entity.curstate.rendermode = kRenderGlow; @@ -2615,11 +2604,12 @@ update client flashlight */ void CL_UpdateFlashlight( cl_entity_t *ent ) { - vec3_t forward, view_ofs; - vec3_t vecSrc, vecEnd; - float falloff; - pmtrace_t *trace; - dlight_t *dl; + vec3_t forward, view_ofs; + vec3_t vecSrc, vecEnd; + float falloff; + pmtrace_t *trace; + cl_entity_t *hit; + dlight_t *dl; if( ent->index == ( cl.playernum + 1 )) { @@ -2652,10 +2642,10 @@ void CL_UpdateFlashlight( cl_entity_t *ent ) // update flashlight endpos dl = CL_AllocDlight( ent->index ); -#if 0 - // g-cont. disabled until studio lighting will be finished - if( trace->ent > 0 && clgame.pmove->visents[trace->ent].studiomodel ) - VectorCopy( clgame.pmove->visents[trace->ent].origin, dl->origin ); +#if 1 + hit = CL_GetEntityByIndex( clgame.pmove->visents[trace->ent].info ); + if( hit && hit->model && ( hit->model->type == mod_alias || hit->model->type == mod_studio )) + VectorCopy( hit->origin, dl->origin ); else VectorCopy( trace->endpos, dl->origin ); #else VectorCopy( trace->endpos, dl->origin ); diff --git a/engine/client/client.h b/engine/client/client.h index 7a638cf2..03b6d8af 100644 --- a/engine/client/client.h +++ b/engine/client/client.h @@ -37,7 +37,7 @@ GNU General Public License for more details. #define MAX_MOVIES 8 #define MAX_CDTRACKS 32 #define MAX_IMAGES 256 // SpriteTextures -#define MAX_EFRAGS 4096 +#define MAX_EFRAGS 8192 #define MAX_REQUESTS 64 // screenshot types diff --git a/engine/client/gl_alias.c b/engine/client/gl_alias.c index d5a9e707..8bb121be 100644 --- a/engine/client/gl_alias.c +++ b/engine/client/gl_alias.c @@ -299,8 +299,6 @@ void BuildTris( void ) } g_commands[g_numcommands++] = 0; // end of list marker - - MsgDev( D_REPORT, "%3i tri %3i vert %3i cmd\n", m_pAliasHeader->numtris, g_numorder, g_numcommands ); } /* @@ -1391,6 +1389,7 @@ void R_DrawAliasModel( cl_entity_t *e ) R_AliasDynamicLight( e, &lighting ); r_stats.c_alias_polys += m_pAliasHeader->numtris; + r_stats.c_alias_models_drawn++; // // draw all the triangles diff --git a/engine/client/gl_backend.c b/engine/client/gl_backend.c index 6ee7f80e..4e6e0b70 100644 --- a/engine/client/gl_backend.c +++ b/engine/client/gl_backend.c @@ -74,12 +74,12 @@ void GL_BackendEndFrame( void ) r_stats.c_world_leafs, Mod_PointInLeaf( RI.pvsorigin, cl.worldmodel->nodes ) - cl.worldmodel->leafs ); break; case 3: - Q_snprintf( r_speeds_msg, sizeof( r_speeds_msg ), "%3i studio models drawn\n%3i sprites drawn", - r_stats.c_studio_models_drawn, r_stats.c_sprite_models_drawn ); + Q_snprintf( r_speeds_msg, sizeof( r_speeds_msg ), "%3i alias models drawn\n%3i studio models drawn\n%3i sprites drawn", + r_stats.c_alias_models_drawn, r_stats.c_studio_models_drawn, r_stats.c_sprite_models_drawn ); break; case 4: - Q_snprintf( r_speeds_msg, sizeof( r_speeds_msg ), "%3i static entities\n%3i normal entities", - r_numStatics, r_numEntities - r_numStatics ); + Q_snprintf( r_speeds_msg, sizeof( r_speeds_msg ), "%3i static entities\n%3i normal entities\n%3i server entities", + r_numStatics, r_numEntities - r_numStatics, pfnNumberOfEntities( )); break; case 5: Q_snprintf( r_speeds_msg, sizeof( r_speeds_msg ), "%3i tempents\n%3i viewbeams\n%3i particles", diff --git a/engine/client/gl_local.h b/engine/client/gl_local.h index 96b7b1ec..0f3f33ba 100644 --- a/engine/client/gl_local.h +++ b/engine/client/gl_local.h @@ -227,6 +227,7 @@ typedef struct uint c_view_beams_count; uint c_active_tents_count; + uint c_alias_models_drawn; uint c_studio_models_drawn; uint c_sprite_models_drawn; uint c_particle_count; @@ -402,6 +403,7 @@ void GL_SubdivideSurface( msurface_t *fa ); void GL_BuildPolygonFromSurface( model_t *mod, msurface_t *fa ); void GL_SetupFogColorForSurfaces( void ); void GL_SetupFogColorForModels( void ); +void R_DrawAlphaTextureChains( void ); void GL_RebuildLightmaps( void ); void GL_InitRandomTable( void ); void GL_BuildLightmaps( void ); @@ -413,6 +415,7 @@ void GL_ResetFogColor( void ); void R_SpriteInit( void ); void Mod_LoadSpriteModel( model_t *mod, const void *buffer, qboolean *loaded, uint texFlags ); mspriteframe_t *R_GetSpriteFrame( const model_t *pModel, int frame, float yaw ); +void R_SetSpriteRenderamt( cl_entity_t *ent, const model_t *pModel ); void R_SetSpriteRendermode( const model_t *pModel ); void R_DrawSpriteModel( cl_entity_t *e ); diff --git a/engine/client/gl_rmain.c b/engine/client/gl_rmain.c index 64739f33..a8ce9965 100644 --- a/engine/client/gl_rmain.c +++ b/engine/client/gl_rmain.c @@ -98,28 +98,6 @@ static qboolean R_OpaqueEntity( cl_entity_t *ent ) return false; } -/* -=============== -R_SolidEntityCompare - -Sorting opaque entities by model type -=============== -*/ -static int R_SolidEntityCompare( const cl_entity_t **a, const cl_entity_t **b ) -{ - cl_entity_t *ent1, *ent2; - - ent1 = (cl_entity_t *)*a; - ent2 = (cl_entity_t *)*b; - - if( ent1->model->type > ent2->model->type ) - return 1; - if( ent1->model->type < ent2->model->type ) - return -1; - - return 0; -} - /* =============== R_TransEntityCompare @@ -261,7 +239,7 @@ qboolean R_AddEntity( struct cl_entity_s *clent, int type ) if( clent->curstate.effects & EF_NODRAW ) return false; // done - if( clent->curstate.rendermode != kRenderNormal && clent->curstate.renderamt <= 0.0f ) + if( clent->curstate.rendermode != kRenderNormal && clent->curstate.renderamt <= 0 ) return true; // invisible if( type == ET_FRAGMENTED ) @@ -363,6 +341,12 @@ void R_SetupFrustum( void ) { ref_overview_t *ov = &clgame.overView; + if( RP_NORMALPASS() && ( cl.local.waterlevel >= 3 )) + { + RI.fov_x = atan( tan( DEG2RAD( RI.fov_x ) / 2 ) * ( 0.97 + sin( cl.time * 1.5 ) * 0.03 )) * 2 / (M_PI / 180.0); + RI.fov_y = atan( tan( DEG2RAD( RI.fov_y ) / 2 ) * ( 1.03 - sin( cl.time * 1.5 ) * 0.03 )) * 2 / (M_PI / 180.0); + } + // build the transformation matrix for the given view angles AngleVectors( RI.viewangles, RI.vforward, RI.vright, RI.vup ); @@ -519,9 +503,6 @@ static void R_SetupFrame( void ) // setup viewplane dist RI.viewplanedist = DotProduct( RI.vieworg, RI.vforward ); - // sort opaque entities by model type to avoid drawing model shadows under alpha-surfaces - qsort( tr.solid_entities, tr.num_solid_entities, sizeof( cl_entity_t* ), R_SolidEntityCompare ); - if( !gl_nosort->value ) { // sort translucents entities by rendermode and distance @@ -543,12 +524,6 @@ R_SetupGL */ void R_SetupGL( qboolean set_gl_state ) { - if( RP_NORMALPASS() && ( cl.local.waterlevel >= 3 )) - { - RI.fov_x = atan( tan( DEG2RAD( RI.fov_x ) / 2 ) * ( 0.97 + sin( cl.time * 1.5 ) * 0.03 )) * 2 / (M_PI / 180.0); - RI.fov_y = atan( tan( DEG2RAD( RI.fov_y ) / 2 ) * ( 1.03 - sin( cl.time * 1.5 ) * 0.03 )) * 2 / (M_PI / 180.0); - } - R_SetupModelviewMatrix( RI.worldviewMatrix ); R_SetupProjectionMatrix( RI.projectionMatrix ); @@ -814,6 +789,8 @@ void R_DrawEntitiesOnList( void ) // draw the solid submodels fog R_DrawFog (); + pglDepthMask( GL_TRUE ); + // first draw solid entities for( i = 0; i < tr.num_solid_entities && !RI.onlyClientDraw; i++ ) { @@ -842,6 +819,8 @@ void R_DrawEntitiesOnList( void ) } } + R_DrawAlphaTextureChains(); + if( !RI.onlyClientDraw ) { CL_DrawBeams( false ); diff --git a/engine/client/gl_rsurf.c b/engine/client/gl_rsurf.c index 2b5c5f69..d4e16fe9 100644 --- a/engine/client/gl_rsurf.c +++ b/engine/client/gl_rsurf.c @@ -36,6 +36,7 @@ static glpoly_t *fullbright_polys[MAX_TEXTURES]; static qboolean draw_fullbrights = false; static mextrasurf_t *detail_surfaces[MAX_TEXTURES]; static int rtable[MOD_FRAMES][MOD_FRAMES]; +static qboolean draw_alpha_surfaces = false; static qboolean draw_details = false; static msurface_t *skychain = NULL; static gllightmapstate_t gl_lms; @@ -1308,6 +1309,12 @@ void R_DrawTextureChains( void ) if(( s->flags & SURF_DRAWTURB ) && clgame.movevars.wateralpha < 1.0f ) continue; // draw translucent water later + if( FBitSet( host.features, ENGINE_QUAKE_COMPATIBLE ) && FBitSet( s->flags, SURF_TRANSPARENT )) + { + draw_alpha_surfaces = true; + continue; // draw transparent surfaces later + } + for( ; s != NULL; s = s->texturechain ) R_RenderBrushPoly( s ); t->texturechain = NULL; @@ -1316,6 +1323,57 @@ void R_DrawTextureChains( void ) GL_ResetFogColor(); } +/* +================ +R_DrawAlphaTextureChains +================ +*/ +void R_DrawAlphaTextureChains( void ) +{ + int i; + msurface_t *s; + texture_t *t; + + if( !draw_alpha_surfaces ) + return; + + memset( gl_lms.lightmap_surfaces, 0, sizeof( gl_lms.lightmap_surfaces )); + gl_lms.dynamic_surfaces = NULL; + + // make sure what color is reset + pglColor4ub( 255, 255, 255, 255 ); + R_LoadIdentity(); // set identity matrix + + pglDisable( GL_BLEND ); + pglEnable( GL_ALPHA_TEST ); + pglAlphaFunc( GL_GEQUAL, 0.5f ); + + GL_SetupFogColorForSurfaces(); + + // restore worldmodel + RI.currententity = clgame.entities; + RI.currentmodel = RI.currententity->model; + draw_alpha_surfaces = false; + + for( i = 0; i < cl.worldmodel->numtextures; i++ ) + { + t = cl.worldmodel->textures[i]; + if( !t ) continue; + + s = t->texturechain; + + if( !s || !FBitSet( s->flags, SURF_TRANSPARENT )) + continue; + + for( ; s != NULL; s = s->texturechain ) + R_RenderBrushPoly( s ); + t->texturechain = NULL; + } + + GL_ResetFogColor(); + R_BlendLightmaps(); +} + /* ================ R_DrawWaterSurfaces @@ -1553,6 +1611,7 @@ void R_DrawBrushModel( cl_entity_t *e ) pglEnable( GL_FOG ); } + pglDisable( GL_BLEND ); R_LoadIdentity(); // restore worldmatrix } @@ -2153,6 +2212,7 @@ void GL_BuildLightmaps( void ) tr.framecount = tr.visframecount = 1; // no dlight cache gl_lms.current_lightmap_texture = 0; + tr.modelviewIdentity = false; tr.num_mirror_entities = 0; tr.num_mirrors_used = 0; tr.realframecount = 1; diff --git a/engine/client/gl_sprite.c b/engine/client/gl_sprite.c index b7f44bda..44adcd95 100644 --- a/engine/client/gl_sprite.c +++ b/engine/client/gl_sprite.c @@ -483,7 +483,7 @@ void Mod_UnloadSpriteModel( model_t *mod ) /* ================ -R_GetSpriteFrame +R_SetSpriteRendermode assume pModel is valid ================ @@ -513,6 +513,25 @@ void R_SetSpriteRendermode( const model_t *pModel ) } } +/* +================ +R_SetSpriteRenderamt + +assume pModel is valid +================ +*/ +void R_SetSpriteRenderamt( cl_entity_t *ent, const model_t *pModel ) +{ + msprite_t *psprite; + + if( !pModel ) return; + psprite = (msprite_t *)pModel->cache.data; + if( !psprite ) return; + + if( psprite->texFormat == SPR_NORMAL || psprite->texFormat == SPR_ALPHTEST ) + ent->curstate.renderamt = 255; +} + /* ================ R_GetSpriteFrame diff --git a/engine/client/gl_studio.c b/engine/client/gl_studio.c index 06a84608..6b303a4b 100644 --- a/engine/client/gl_studio.c +++ b/engine/client/gl_studio.c @@ -1627,7 +1627,7 @@ void R_StudioDynamicLight( cl_entity_t *ent, alight_t *plight ) vecEnd[2] = origin[2] - mv->skyvec_z * 8192.0f; } - trace = CL_TraceLine( vecSrc, vecEnd, PM_STUDIO_IGNORE ); + trace = CL_TraceLine( vecSrc, vecEnd, PM_WORLD_ONLY ); if( trace.ent > 0 ) psurf = PM_TraceSurface( &clgame.pmove->physents[trace.ent], vecSrc, vecEnd ); else psurf = PM_TraceSurface( clgame.pmove->physents, vecSrc, vecEnd ); @@ -1699,10 +1699,10 @@ void R_StudioDynamicLight( cl_entity_t *ent, alight_t *plight ) if( dl->die < g_studio.time || !r_dynamic->value ) continue; - VectorSubtract( origin, dl->origin, dist ); + VectorSubtract( ent->origin, dl->origin, dist ); radius = VectorLength( dist ); - add = dl->radius - radius; + add = (dl->radius - radius); if( add > 0.0f ) { @@ -1714,9 +1714,9 @@ void R_StudioDynamicLight( cl_entity_t *ent, alight_t *plight ) VectorAdd( lightDir, dist, lightDir ); - finalLight[0] += LightToTexGamma( dl->color.r ) * ( add / 256.0f ); - finalLight[1] += LightToTexGamma( dl->color.g ) * ( add / 256.0f ); - finalLight[2] += LightToTexGamma( dl->color.b ) * ( add / 256.0f ); + finalLight[0] += LightToTexGamma( dl->color.r ) * ( add * 512.0f ); + finalLight[1] += LightToTexGamma( dl->color.g ) * ( add * 512.0f ); + finalLight[2] += LightToTexGamma( dl->color.b ) * ( add * 512.0f ); } } @@ -2345,7 +2345,7 @@ static void R_StudioDrawPoints( void ) if( FBitSet( g_nFaceFlags, STUDIO_NF_MASKED )) { - pglAlphaFunc( GL_NOTEQUAL, 0.0f ); + pglAlphaFunc( GL_GREATER, 0.0f ); pglDisable( GL_ALPHA_TEST ); } else if( FBitSet( g_nFaceFlags, STUDIO_NF_ADDITIVE ) && R_ModelOpaque( RI.currententity->curstate.rendermode )) @@ -2740,6 +2740,8 @@ static void R_StudioSetupRenderer( int rendermode ) // enable depthmask on studiomodels if( glState.drawTrans && g_studio.rendermode != kRenderTransAdd ) pglDepthMask( GL_TRUE ); + + pglDisable( GL_ALPHA_TEST ); pglShadeModel( GL_SMOOTH ); } @@ -2870,7 +2872,7 @@ void GL_StudioSetRenderMode( int rendermode ) case kRenderTransAdd: pglTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ); pglColor4f( tr.blend, tr.blend, tr.blend, 1.0f ); - pglBlendFunc( GL_SRC_ALPHA, GL_ONE ); + pglBlendFunc( GL_ONE, GL_ONE ); pglDepthMask( GL_FALSE ); pglEnable( GL_BLEND ); break; diff --git a/engine/client/s_main.c b/engine/client/s_main.c index 7029fc7e..64f7e46c 100644 --- a/engine/client/s_main.c +++ b/engine/client/s_main.c @@ -376,6 +376,9 @@ channel_t *SND_PickStaticChannel( int entnum, sfx_t *sfx ) { if( channels[i].sfx == NULL ) break; + + if( channels[i].entnum == entnum && channels[i].sfx == sfx ) + break; } if( i < total_channels ) diff --git a/engine/client/sound.h b/engine/client/sound.h index 60d150b8..1cd317e0 100644 --- a/engine/client/sound.h +++ b/engine/client/sound.h @@ -241,8 +241,8 @@ void SNDDMA_Submit( void ); //==================================================================== -#define MAX_DYNAMIC_CHANNELS (28 + NUM_AMBIENTS) -#define MAX_CHANNELS (400 + MAX_DYNAMIC_CHANNELS) // Scourge Of Armagon has too many static sounds on hip2m4.bsp +#define MAX_DYNAMIC_CHANNELS (60 + NUM_AMBIENTS) +#define MAX_CHANNELS (224 + MAX_DYNAMIC_CHANNELS) // Scourge Of Armagon has too many static sounds on hip2m4.bsp #define MAX_RAW_CHANNELS 16 #define MAX_RAW_SAMPLES 8192 diff --git a/engine/common/common.h b/engine/common/common.h index afade268..e4dd1d08 100644 --- a/engine/common/common.h +++ b/engine/common/common.h @@ -125,7 +125,7 @@ typedef enum #define CS_TIME 16 // size of time string #define MAX_DECALS 512 // touching TE_DECAL messages, etc -#define MAX_STATIC_ENTITIES 512 // static entities that moved on the client when level is spawn +#define MAX_STATIC_ENTITIES 3072 // static entities that moved on the client when level is spawn // filesystem flags #define FS_STATIC_PATH 1 // FS_ClearSearchPath will be ignore this path @@ -707,6 +707,7 @@ int pfnGetModelType( model_t *mod ); int pfnIsMapValid( char *filename ); void Con_DPrintf( char *fmt, ... ); void Con_Printf( char *szFmt, ... ); +int pfnNumberOfEntities( void ); int pfnIsInGame( void ); // CS:CS engfuncs (stubs) diff --git a/engine/common/con_utils.c b/engine/common/con_utils.c index 86e34b9a..07bfd967 100644 --- a/engine/common/con_utils.c +++ b/engine/common/con_utils.c @@ -16,7 +16,6 @@ GNU General Public License for more details. #include "common.h" #include "client.h" #include "const.h" -#include "bspfile.h" #include "../cl_dll/kbutton.h" extern convar_t *con_gamemaps; diff --git a/engine/common/crclib.c b/engine/common/crclib.c index 14fad2e9..b9e5be5c 100644 --- a/engine/common/crclib.c +++ b/engine/common/crclib.c @@ -14,7 +14,6 @@ GNU General Public License for more details. */ #include "common.h" -#include "bspfile.h" #include "client.h" #define NUM_BYTES 256 diff --git a/engine/common/host.c b/engine/common/host.c index 6c05fc80..0c90a64a 100644 --- a/engine/common/host.c +++ b/engine/common/host.c @@ -77,8 +77,8 @@ void Host_PrintEngineFeatures( void ) if( FBitSet( host.features, ENGINE_LOAD_DELUXEDATA )) MsgDev( D_REPORT, "^3EXT:^7 deluxemap support enabled\n" ); - if( FBitSet( host.features, ENGINE_TRANSFORM_TRACE_AABB )) - MsgDev( D_REPORT, "^3EXT:^7 Transform trace AABB enabled\n" ); + if( FBitSet( host.features, ENGINE_PHYSICS_PUSHER_EXT )) + MsgDev( D_REPORT, "^3EXT:^7 Improved MOVETYPE_PUSH is used\n" ); if( FBitSet( host.features, ENGINE_LARGE_LIGHTMAPS )) MsgDev( D_REPORT, "^3EXT:^7 Large lightmaps enabled\n" ); diff --git a/engine/common/imagelib/img_bmp.c b/engine/common/imagelib/img_bmp.c index aebce918..26f91e3f 100644 --- a/engine/common/imagelib/img_bmp.c +++ b/engine/common/imagelib/img_bmp.c @@ -71,7 +71,7 @@ qboolean Image_LoadBMP( const char *name, const byte *buffer, size_t filesize ) if( bhdr.fileSize != filesize ) { // Sweet Half-Life issues. splash.bmp have bogus filesize - MsgDev( D_WARN, "Image_LoadBMP: %s have incorrect file size %i should be %i\n", name, filesize, bhdr.fileSize ); + MsgDev( D_REPORT, "Image_LoadBMP: %s have incorrect file size %i should be %i\n", name, filesize, bhdr.fileSize ); } // bogus compression? Only non-compressed supported. diff --git a/engine/common/imagelib/img_wad.c b/engine/common/imagelib/img_wad.c index f7e53b25..f824c718 100644 --- a/engine/common/imagelib/img_wad.c +++ b/engine/common/imagelib/img_wad.c @@ -288,7 +288,7 @@ qboolean Image_LoadLMP( const char *name, const byte *buffer, size_t filesize ) memcpy( &lmp, fin, sizeof( lmp )); image.width = lmp.width; image.height = lmp.height; - rendermode = LUMP_MASKED; + rendermode = LUMP_NORMAL; fin += sizeof( lmp ); } @@ -307,6 +307,11 @@ qboolean Image_LoadLMP( const char *name, const byte *buffer, size_t filesize ) { int numcolors; + if( fin[0] == 255 ) + { + image.flags |= IMAGE_HAS_ALPHA; + rendermode = LUMP_MASKED; + } pal = fin + pixels; numcolors = *(short *)pal; if( numcolors != 256 ) pal = NULL; // corrupted lump ? @@ -314,6 +319,7 @@ qboolean Image_LoadLMP( const char *name, const byte *buffer, size_t filesize ) } else if( image.hint != IL_HINT_HL ) { + image.flags |= IMAGE_HAS_ALPHA; rendermode = LUMP_QUAKE1; pal = NULL; } @@ -324,7 +330,6 @@ qboolean Image_LoadLMP( const char *name, const byte *buffer, size_t filesize ) } Image_GetPaletteLMP( pal, rendermode ); - image.flags |= IMAGE_HAS_ALPHA; // FIXME: detect it properly image.type = PF_INDEXED_32; // 32-bit palete image.depth = 1; diff --git a/engine/common/mod_local.h b/engine/common/mod_local.h index 2006e3b1..444f66d6 100644 --- a/engine/common/mod_local.h +++ b/engine/common/mod_local.h @@ -17,7 +17,6 @@ GNU General Public License for more details. #define MOD_LOCAL_H #include "common.h" -#include "bspfile.h" #include "edict.h" #include "eiface.h" #include "com_model.h" diff --git a/engine/common/model.c b/engine/common/model.c index 3013f7d1..8b0cd235 100644 --- a/engine/common/model.c +++ b/engine/common/model.c @@ -235,7 +235,7 @@ mleaf_t *Mod_PointInLeaf( const vec3_t p, mnode_t *node ) { if( node->contents < 0 ) return (mleaf_t *)node; - node = node->children[PlaneDiff( p, node->plane ) < 0]; + node = node->children[PlaneDiff( p, node->plane ) <= 0]; } // never reached @@ -266,7 +266,7 @@ byte *Mod_GetPVSForPoint( const vec3_t p ) leaf = (mleaf_t *)node; break; // we found a leaf } - node = node->children[PlaneDiff( p, node->plane ) < 0]; + node = node->children[PlaneDiff( p, node->plane ) <= 0]; } if( leaf && leaf->cluster >= 0 ) @@ -1263,6 +1263,50 @@ static void Mod_LoadLightVecs( const dlump_t *l ) MsgDev( D_INFO, "Mod_LoadLightVecs: loaded\n" ); } +/* +================= +Mod_LoadColoredLighting +================= +*/ +static qboolean Mod_LoadColoredLighting( void ) +{ + char path[64]; + int iCompare; + size_t litdatasize; + byte *in; + + Q_snprintf( path, sizeof( path ), "maps/%s.lit", modelname ); + + // make sure what deluxemap is actual + if( !COM_CompareFileTime( path, loadmodel->name, &iCompare )) + return false; + + if( iCompare < 0 ) // this may happens if level-designer used -onlyents key for hlcsg + MsgDev( D_WARN, "Mod_LoadColoredLighting: %s probably is out of date\n", path ); + + in = FS_LoadFile( path, &litdatasize, false ); + + ASSERT( in != NULL ); + + if( *(uint *)in != IDDELUXEMAPHEADER || *((uint *)in + 1) != DELUXEMAP_VERSION ) + { + MsgDev( D_ERROR, "Mod_LoadColoredLighting: %s is not a lightmap file\n", path ); + Mem_Free( in ); + return false; + } + + // skip header bytes + litdatasize -= 8; + + MsgDev( D_INFO, "Mod_LoadColoredLighting: %s loaded\n", path ); + loadmodel->lightdata = Mem_Alloc( loadmodel->mempool, litdatasize ); + memcpy( loadmodel->lightdata, in + 8, litdatasize ); + if( world.loading ) world.litdatasize = litdatasize; + Mem_Free( in ); + + return true; +} + /* ================= Mod_LoadLighting @@ -1293,16 +1337,19 @@ static void Mod_LoadLighting( const dlump_t *l, dextrahdr_t *extrahdr ) { case Q1BSP_VERSION: case QBSP2_VERSION: - // expand the white lighting data - loadmodel->lightdata = (color24 *)Mem_Alloc( loadmodel->mempool, l->filelen * sizeof( color24 )); - out = loadmodel->lightdata; - - for( i = 0; i < l->filelen; i++, out++ ) + if( !Mod_LoadColoredLighting( )) { - d = *in++; - out->r = d; - out->g = d; - out->b = d; + // expand the white lighting data + loadmodel->lightdata = (color24 *)Mem_Alloc( loadmodel->mempool, l->filelen * sizeof( color24 )); + out = loadmodel->lightdata; + + for( i = 0; i < l->filelen; i++, out++ ) + { + d = *in++; + out->r = d; + out->g = d; + out->b = d; + } } break; case HLBSP_VERSION: diff --git a/engine/common/net_encode.c b/engine/common/net_encode.c index de2a19bc..03a762bb 100644 --- a/engine/common/net_encode.c +++ b/engine/common/net_encode.c @@ -811,7 +811,7 @@ void Delta_Init( void ) Delta_AddField( "movevars_t", "zmax", DT_FLOAT|DT_SIGNED, 18, 1.0f, 1.0f ); else Delta_AddField( "movevars_t", "zmax", DT_FLOAT|DT_SIGNED, 16, 1.0f, 1.0f ); - Delta_AddField( "movevars_t", "waveHeight", DT_FLOAT|DT_SIGNED, 16, 16.0f, 8.0f ); + Delta_AddField( "movevars_t", "waveHeight", DT_FLOAT|DT_SIGNED, 16, 16.0f, 1.0f ); Delta_AddField( "movevars_t", "skyName", DT_STRING, 1, 1.0f, 1.0f ); Delta_AddField( "movevars_t", "footsteps", DT_INTEGER, 1, 1.0f, 1.0f ); Delta_AddField( "movevars_t", "rollangle", DT_FLOAT|DT_SIGNED, 16, 32.0f, 1.0f ); diff --git a/engine/common/pm_trace.c b/engine/common/pm_trace.c index 4d8b7a79..dfd27acb 100644 --- a/engine/common/pm_trace.c +++ b/engine/common/pm_trace.c @@ -408,7 +408,7 @@ pmtrace_t PM_PlayerTraceExt( playermove_t *pmove, vec3_t start, vec3_t end, int rotated = true; else rotated = false; - if( host.features & ENGINE_TRANSFORM_TRACE_AABB ) + if( FBitSet( host.features, ENGINE_PHYSICS_PUSHER_EXT )) { if(( check_angles( pe->angles[0] ) || check_angles( pe->angles[2] )) && pmove->usehull != 2 ) transform_bbox = true; @@ -586,7 +586,7 @@ int PM_TestPlayerPosition( playermove_t *pmove, vec3_t pos, pmtrace_t *ptrace, p qboolean transform_bbox = false; matrix4x4 matrix; - if( host.features & ENGINE_TRANSFORM_TRACE_AABB ) + if( FBitSet( host.features, ENGINE_PHYSICS_PUSHER_EXT )) { if(( check_angles( pe->angles[0] ) || check_angles( pe->angles[2] )) && pmove->usehull != 2 ) transform_bbox = true; diff --git a/engine/common/protocol.h b/engine/common/protocol.h index 7e721904..c66a7d03 100644 --- a/engine/common/protocol.h +++ b/engine/common/protocol.h @@ -94,8 +94,12 @@ GNU General Public License for more details. #define clc_requestcvarvalue2 10 #define clc_lastmsg 10 // end client messages -#define MAX_VISIBLE_PACKET_BITS 10 -#define MAX_VISIBLE_PACKET (1<v.flags, FL_KILLME )) continue; // don't double add an entity through portals (in case this already added) @@ -265,9 +265,10 @@ void SV_EmitPacketEntities( sv_client_t *cl, client_frame_t *to, sizebuf_t *msg if( newnum > oldnum ) { qboolean force = false; + edict_t *ed = EDICT_NUM( oldent->number ); // check if entity completely removed from server - if( EDICT_NUM( oldent->number )->free ) + if( ed->free || FBitSet( ed->v.flags, FL_KILLME )) force = true; // remove from message diff --git a/engine/server/sv_game.c b/engine/server/sv_game.c index e9bbadd6..1aae0158 100644 --- a/engine/server/sv_game.c +++ b/engine/server/sv_game.c @@ -1527,7 +1527,7 @@ edict_t* pfnFindClientInPVS( edict_t *pEdict ) // portals & monitors // NOTE: this specific break "radiaton tick" in normal half-life. use only as feature - if( FBitSet( host.features, ENGINE_TRANSFORM_TRACE_AABB ) && mod && mod->type == mod_brush && !FBitSet( mod->flags, MODEL_HAS_ORIGIN )) + if( FBitSet( host.features, ENGINE_PHYSICS_PUSHER_EXT ) && mod && mod->type == mod_brush && !FBitSet( mod->flags, MODEL_HAS_ORIGIN )) { // handle PVS origin for bmodels VectorAverage( pEdict->v.mins, pEdict->v.maxs, view ); @@ -2742,18 +2742,18 @@ void pfnWriteString( const char *src ) { static char string[2048]; int len = Q_strlen( src ) + 1; - int rem = (255 - svgame.msg_realsize); + int rem = (254 - svgame.msg_realsize); char *dst; // user-message strings can't exceeds 255 symbols, // but system message allow up to 2048 characters - if(( svgame.msg_index > 0 ) && ( len == 1 || len >= rem )) + if( svgame.msg_index < 0 ) rem = sizeof( string ) - 1; + + if( len == 1 ) { - if( len >= rem ) - MsgDev( D_ERROR, "pfnWriteString: exceeds %i symbols\n", rem ); MSG_WriteChar( &sv.multicast, 0 ); svgame.msg_realsize += 1; - return; + return; // fast exit } // prepare string to sending @@ -2782,6 +2782,14 @@ void pfnWriteString( const char *src ) } else if(( *dst++ = *src++ ) == 0 ) break; + + if( --rem <= 0 ) + { + MsgDev( D_ERROR, "pfnWriteString: exceeds %i symbols\n", len ); + *dst = '\0'; // string end (not included in count) + len = Q_strlen( string ) + 1; + break; + } } *dst = '\0'; // string end (not included in count) diff --git a/engine/server/sv_init.c b/engine/server/sv_init.c index 336d57c3..375e79e1 100644 --- a/engine/server/sv_init.c +++ b/engine/server/sv_init.c @@ -310,7 +310,7 @@ void SV_ActivateServer( void ) // Activate the DLL server code svgame.dllFuncs.pfnServerActivate( svgame.edicts, svgame.numEntities, svgame.globals->maxClients ); - if( sv.loadgame && !svgame.globals->changelevel ) + if( sv.loadgame || svgame.globals->changelevel ) { sv.frametime = 0.001; numFrames = 1; diff --git a/engine/server/sv_main.c b/engine/server/sv_main.c index 1ffdad63..d8166c8a 100644 --- a/engine/server/sv_main.c +++ b/engine/server/sv_main.c @@ -116,7 +116,6 @@ convar_t *sv_check_errors; convar_t *public_server; // should heartbeats be sent convar_t *sv_reconnect_limit; // minimum seconds between connect messages convar_t *sv_allow_studio_attachment_angles; -convar_t *sv_allow_rotate_pushables; convar_t *sv_validate_changelevel; convar_t *sv_sendvelocity; @@ -746,7 +745,6 @@ void SV_Init( void ) zombietime = Cvar_Get( "zombietime", "2", FCVAR_SERVER, "timeout for clients-zombie (who died but not respawned)" ); sv_pausable = Cvar_Get( "pausable", "1", FCVAR_SERVER, "allow players to pause or not" ); sv_allow_studio_attachment_angles = Cvar_Get( "sv_allow_studio_attachment_angles", "0", FCVAR_ARCHIVE, "enable calc angles for attachment points (on studio models)" ); - sv_allow_rotate_pushables = Cvar_Get( "sv_allow_rotate_pushables", "0", FCVAR_ARCHIVE, "let the pushers rotate pushables with included origin-brush" ); sv_validate_changelevel = Cvar_Get( "sv_validate_changelevel", "1", FCVAR_ARCHIVE, "test change level for level-designer errors" ); Cvar_RegisterVariable (&sv_clienttrace); Cvar_RegisterVariable (&sv_bounce); diff --git a/engine/server/sv_phys.c b/engine/server/sv_phys.c index 8bb50b2a..5454fa16 100644 --- a/engine/server/sv_phys.c +++ b/engine/server/sv_phys.c @@ -765,7 +765,7 @@ qboolean SV_AllowPushRotate( edict_t *ent ) if( !mod || mod->type != mod_brush ) return true; - if( !sv_allow_rotate_pushables->value ) + if( !FBitSet( host.features, ENGINE_PHYSICS_PUSHER_EXT )) return false; return (mod->flags & MODEL_HAS_ORIGIN) ? true : false; @@ -811,7 +811,13 @@ trace_t SV_PushEntity( edict_t *ent, const vec3_t lpush, const vec3_t apush, int SV_LinkEdict( ent, true ); - if( blocked ) *blocked = !VectorCompare( ent->v.origin, end ); // can't move full distance + if( blocked ) + { + // more accuracy blocking code + if( FBitSet( host.features, ENGINE_PHYSICS_PUSHER_EXT )) + *blocked = !VectorCompare( ent->v.origin, end ); // can't move full distance + else *blocked = true; + } // so we can run impact function afterwards. if( SV_IsValidEdict( trace.ent )) diff --git a/engine/server/sv_save.c b/engine/server/sv_save.c index d24af567..a80cfc71 100644 --- a/engine/server/sv_save.c +++ b/engine/server/sv_save.c @@ -759,7 +759,7 @@ SAVERESTOREDATA *SV_SaveInit( int size ) const int nTokens = 0xfff; // Assume a maximum of 4K-1 symbol table entries(each of some length) int numents; - if( size <= 0 ) size = 0x200000; // Reserve 2Mb for now + if( size <= 0 ) size = 0x400000; // Reserve 4Mb for now numents = svgame.numEntities; pSaveData = Mem_Alloc( host.mempool, sizeof(SAVERESTOREDATA) + ( sizeof(ENTITYTABLE) * numents ) + size ); @@ -1367,7 +1367,7 @@ void SV_LoadClientState( SAVERESTOREDATA *pSaveData, const char *level, qboolean FS_Read( pFile, &soundCount, sizeof( int )); - for( i = 0; i < soundCount; i++ ) + for( i = 0; i < Q_min( soundCount, MAX_CHANNELS ); i++ ) { soundlist_t *entry; byte nameSize; diff --git a/engine/server/sv_world.c b/engine/server/sv_world.c index b3479543..14578686 100644 --- a/engine/server/sv_world.c +++ b/engine/server/sv_world.c @@ -878,7 +878,7 @@ void SV_ClipMoveToEntity( edict_t *ent, const vec3_t start, vec3_t mins, vec3_t rotated = true; else rotated = false; - if( host.features & ENGINE_TRANSFORM_TRACE_AABB ) + if( FBitSet( host.features, ENGINE_PHYSICS_PUSHER_EXT )) { // keep untransformed bbox less than 45 degress or train on subtransit.bsp will stop working if(( check_angles( ent->v.angles[0] ) || check_angles( ent->v.angles[2] )) && !VectorIsNull( mins )) diff --git a/mainui/basemenu.h b/mainui/basemenu.h index fc82c5a4..e653249c 100644 --- a/mainui/basemenu.h +++ b/mainui/basemenu.h @@ -32,6 +32,8 @@ GNU General Public License for more details. #define ColorIndex( c ) ((( c ) - '0' ) & 7 ) #define IsColorString( p ) ( p && *( p ) == '^' && *(( p ) + 1) && *(( p ) + 1) >= '0' && *(( p ) + 1 ) <= '9' ) +#define ARRAYSIZE(p) (sizeof(p)/sizeof(p[0])) + #include "netadr.h" #define ART_BACKGROUND "gfx/shell/splash"