From 547b56497e6e2451ad189f1903a829bc989da50e Mon Sep 17 00:00:00 2001 From: g-cont Date: Tue, 22 Aug 2017 00:00:00 +0300 Subject: [PATCH] 22 Aug 2017 --- engine/client/cl_frame.c | 8 +- engine/client/cl_scrn.c | 2 +- engine/client/gl_decals.c | 233 +++++++++++++++++++++++--------------- engine/client/gl_image.c | 80 +++++++++++++ engine/client/gl_local.h | 4 +- engine/client/gl_rmain.c | 47 +++++--- engine/client/gl_rsurf.c | 25 ++-- engine/client/gl_sprite.c | 2 +- engine/client/s_main.c | 2 +- engine/client/s_utils.c | 18 --- engine/client/sound.h | 1 - engine/common/mathlib.c | 18 +++ engine/common/mathlib.h | 1 + engine/server/sv_game.c | 14 ++- engine/server/sv_phys.c | 64 ++++++----- 15 files changed, 345 insertions(+), 174 deletions(-) diff --git a/engine/client/cl_frame.c b/engine/client/cl_frame.c index 89b8d41f..a9f5698f 100644 --- a/engine/client/cl_frame.c +++ b/engine/client/cl_frame.c @@ -998,7 +998,6 @@ void CL_LinkPlayers( frame_t *frame ) VectorCopy( state->origin, ent->prevstate.origin ); VectorCopy( state->origin, ent->curstate.origin ); VectorCopy( ent->curstate.angles, ent->angles ); - local_added = true; } if( FBitSet( ent->curstate.effects, EF_NOINTERP )) @@ -1029,7 +1028,11 @@ void CL_LinkPlayers( frame_t *frame ) VectorCopy( ent->origin, ent->attachment[2] ); VectorCopy( ent->origin, ent->attachment[3] ); - CL_AddVisibleEntity( ent, ET_PLAYER ); + if( CL_AddVisibleEntity( ent, ET_PLAYER )) + { + if( i == cl.playernum ) + local_added = true; + } } // apply local player effects if entity is not added @@ -1278,6 +1281,7 @@ qboolean CL_GetEntitySpatialization( channel_t *ch ) { // entity is never has updates on the client // so we should use static origin instead + ch->staticsound = true; return valid_origin; } #if 0 diff --git a/engine/client/cl_scrn.c b/engine/client/cl_scrn.c index fe2337a5..eb6438a6 100644 --- a/engine/client/cl_scrn.c +++ b/engine/client/cl_scrn.c @@ -144,7 +144,7 @@ void SCR_NetSpeeds( void ) if( cur_clfps > max_clfps ) max_clfps = cur_clfps; } - Q_snprintf( msg, sizeof( msg ), "sv fps: ^1%4i min, ^3%4i cur, ^2%4i max\ncl fps: ^1%4i min, ^3%4i cur, ^2%4i max\nGame Time: %02d:%02d\nTotal received from server: %s\nTotal sended to server: %s\n", + Q_snprintf( msg, sizeof( msg ), "sv fps: ^1%4i min, ^3%4i cur, ^2%4i max\ncl fps: ^1%4i min, ^3%4i cur, ^2%4i max\nGame Time: %02d:%02d\nTotal received from server: %s\nTotal sent to server: %s\n", min_svfps, cur_svfps, max_svfps, min_clfps, cur_clfps, max_clfps, (int)(time / 60.0f ), (int)fmod( time, 60.0f ), Q_memprint( cls.netchan.total_received ), Q_memprint( cls.netchan.total_sended )); x = glState.width - 320; diff --git a/engine/client/gl_decals.c b/engine/client/gl_decals.c index a75b1dff..4f324894 100644 --- a/engine/client/gl_decals.c +++ b/engine/client/gl_decals.c @@ -878,11 +878,150 @@ void DrawSingleDecal( decal_t *pDecal, msurface_t *fa ) pglEnd(); } -void DrawSurfaceDecals( void ) +void DrawSurfaceDecals( msurface_t *fa, qboolean single ) +{ + decal_t *p; + cl_entity_t *e; + + if( !fa->pdecals ) return; + + e = RI.currententity; + ASSERT( e != NULL ); + + if( single ) + { + if( e->curstate.rendermode == kRenderNormal || e->curstate.rendermode == kRenderTransAlpha ) + { + pglDepthMask( GL_FALSE ); + pglEnable( GL_BLEND ); + + if( e->curstate.rendermode == kRenderTransAlpha ) + pglDisable( GL_ALPHA_TEST ); + } + + if( e->curstate.rendermode == kRenderTransColor ) + pglEnable( GL_TEXTURE_2D ); + + if( e->curstate.rendermode == kRenderTransTexture || e->curstate.rendermode == kRenderTransAdd ) + GL_Cull( GL_NONE ); + + if( gl_polyoffset->value ) + { + pglEnable( GL_POLYGON_OFFSET_FILL ); + pglPolygonOffset( -1.0f, -gl_polyoffset->value ); + } + + pglBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); + } + + if( FBitSet( fa->flags, SURF_TRANSPARENT ) && glState.stencilEnabled ) + { + mtexinfo_t *tex = fa->texinfo; + + for( p = fa->pdecals; p; p = p->pnext ) + { + if( p->texture ) + { + float *o, *v; + int i, numVerts; + o = R_DecalSetupVerts( p, fa, p->texture, &numVerts ); + + pglEnable( GL_STENCIL_TEST ); + pglStencilFunc( GL_ALWAYS, 1, 0xFFFFFFFF ); + pglColorMask( GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE ); + + pglStencilOp( GL_KEEP, GL_KEEP, GL_REPLACE ); + pglBegin( GL_POLYGON ); + + for( i = 0, v = o; i < numVerts; i++, v += VERTEXSIZE ) + { + v[5] = ( DotProduct( v, tex->vecs[0] ) + tex->vecs[0][3] ) / tex->texture->width; + v[6] = ( DotProduct( v, tex->vecs[1] ) + tex->vecs[1][3] ) / tex->texture->height; + + pglTexCoord2f( v[5], v[6] ); + pglVertex3fv( v ); + } + + pglEnd(); + pglStencilOp( GL_KEEP, GL_KEEP, GL_DECR ); + + pglEnable( GL_ALPHA_TEST ); + pglBegin( GL_POLYGON ); + + for( i = 0, v = o; i < numVerts; i++, v += VERTEXSIZE ) + { + pglTexCoord2f( v[5], v[6] ); + pglVertex3fv( v ); + } + + pglEnd(); + pglDisable( GL_ALPHA_TEST ); + + pglColorMask( GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE ); + pglStencilFunc( GL_EQUAL, 0, 0xFFFFFFFF ); + pglStencilOp( GL_KEEP, GL_KEEP, GL_KEEP ); + } + } + } + + for( p = fa->pdecals; p; p = p->pnext ) + { + if( p->texture ) + { + gltexture_t *glt = R_GetTexture( p->texture ); + + // normal HL decal with alpha-channel + if( glt->flags & TF_HAS_ALPHA ) + { + // draw transparent decals with GL_MODULATE + if( glt->fogParams[3] > DECAL_TRANSPARENT_THRESHOLD ) + pglTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ); + else pglTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE ); + pglBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); + } + else + { + // color decal like detail texture. Base color is 127 127 127 + pglTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE ); + pglBlendFunc( GL_DST_COLOR, GL_SRC_COLOR ); + } + + DrawSingleDecal( p, fa ); + } + } + + if( FBitSet( fa->flags, SURF_TRANSPARENT ) && glState.stencilEnabled ) + pglDisable( GL_STENCIL_TEST ); + + if( single ) + { + if( e->curstate.rendermode == kRenderNormal || e->curstate.rendermode == kRenderTransAlpha ) + { + pglDepthMask( GL_TRUE ); + pglDisable( GL_BLEND ); + + if( e->curstate.rendermode == kRenderTransAlpha ) + pglEnable( GL_ALPHA_TEST ); + } + + if( gl_polyoffset->value ) + pglDisable( GL_POLYGON_OFFSET_FILL ); + + if( e->curstate.rendermode == kRenderTransTexture || e->curstate.rendermode == kRenderTransAdd ) + GL_Cull( GL_FRONT ); + + if( e->curstate.rendermode == kRenderTransColor ) + pglDisable( GL_TEXTURE_2D ); + + // restore blendfunc here + if( e->curstate.rendermode == kRenderTransAdd || e->curstate.rendermode == kRenderGlow ) + pglBlendFunc( GL_SRC_ALPHA, GL_ONE ); + } +} + +void DrawDecalsBatch( void ) { cl_entity_t *e; - msurface_t *fa; - decal_t *p; int i; if( !tr.num_draw_decals ) @@ -909,93 +1048,7 @@ void DrawSurfaceDecals( void ) for( i = 0; i < tr.num_draw_decals; i++ ) { - fa = tr.draw_decals[i]; - - if( fa->flags & SURF_TRANSPARENT && glState.stencilEnabled ) - { - mtexinfo_t *tex = fa->texinfo; - texture_t *t = R_TextureAnimation( fa ); - - // sigh! we need to draw poly again here - pglEnable( GL_ALPHA_TEST ); - GL_Bind( GL_TEXTURE0, t->gl_texturenum ); - DrawGLPoly( fa->polys, 0.0f, 0.0f ); - pglDisable( GL_ALPHA_TEST ); - - for( p = fa->pdecals; p; p = p->pnext ) - { - if( p->texture ) - { - float *o, *v; - int i, numVerts; - o = R_DecalSetupVerts( p, fa, p->texture, &numVerts ); - - pglEnable( GL_STENCIL_TEST ); - pglStencilFunc( GL_ALWAYS, 1, 0xFFFFFFFF ); - pglColorMask( GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE ); - - pglStencilOp( GL_KEEP, GL_KEEP, GL_REPLACE ); - pglBegin( GL_POLYGON ); - - for( i = 0, v = o; i < numVerts; i++, v += VERTEXSIZE ) - { - v[5] = ( DotProduct( v, tex->vecs[0] ) + tex->vecs[0][3] ) / tex->texture->width; - v[6] = ( DotProduct( v, tex->vecs[1] ) + tex->vecs[1][3] ) / tex->texture->height; - - pglTexCoord2f( v[5], v[6] ); - pglVertex3fv( v ); - } - - pglEnd(); - pglStencilOp( GL_KEEP, GL_KEEP, GL_DECR ); - - pglEnable( GL_ALPHA_TEST ); - pglBegin( GL_POLYGON ); - - for( i = 0, v = o; i < numVerts; i++, v += VERTEXSIZE ) - { - pglTexCoord2f( v[5], v[6] ); - pglVertex3fv( v ); - } - - pglEnd(); - pglDisable( GL_ALPHA_TEST ); - - pglColorMask( GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE ); - pglStencilFunc( GL_EQUAL, 0, 0xFFFFFFFF ); - pglStencilOp( GL_KEEP, GL_KEEP, GL_KEEP ); - } - } - } - - for( p = fa->pdecals; p; p = p->pnext ) - { - if( p->texture ) - { - gltexture_t *glt = R_GetTexture( p->texture ); - - // normal HL decal with alpha-channel - if( glt->flags & TF_HAS_ALPHA ) - { - // draw transparent decals with GL_MODULATE - if( glt->fogParams[3] > DECAL_TRANSPARENT_THRESHOLD ) - pglTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ); - else pglTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE ); - pglBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); - } - else - { - // color decal like detail texture. Base color is 127 127 127 - pglTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE ); - pglBlendFunc( GL_DST_COLOR, GL_SRC_COLOR ); - } - - DrawSingleDecal( p, fa ); - } - } - - if( fa->flags & SURF_TRANSPARENT && glState.stencilEnabled ) - pglDisable( GL_STENCIL_TEST ); + DrawSurfaceDecals( tr.draw_decals[i], false ); } if( e->curstate.rendermode != kRenderTransTexture ) diff --git a/engine/client/gl_image.c b/engine/client/gl_image.c index 9ce478f7..385bcd98 100644 --- a/engine/client/gl_image.c +++ b/engine/client/gl_image.c @@ -780,6 +780,83 @@ byte *GL_ResampleTexture( const byte *source, int inWidth, int inHeight, int out return scaledImage; } +float GL_SimpleSpline( float value ) +{ + float valueSquared = value * value * value; + + // nice little ease-in, ease-out spline-like curve + return (4.0f * valueSquared - 3.0f * valueSquared * value); +} + +/* +================= +GL_BoxFilter3x3 + +box filter 3x3 +================= +*/ +void GL_BoxFilter3x3( byte *out, const byte *in, int w, int h, int x, int y ) +{ + int r = 0, g = 0, b = 0, a = 0; + int count = 0, acount = 0; + int i, j, u, v; + const byte *pixel; + + for( i = 0; i < 3; i++ ) + { + u = ( i - 1 ) + x; + + for( j = 0; j < 3; j++ ) + { + v = ( j - 1 ) + y; + + if( u >= 0 && u < w && v >= 0 && v < h ) + { + pixel = &in[( u + v * w ) * 4]; + + if( pixel[3] != 0 ) + { + r += pixel[0]; + g += pixel[1]; + b += pixel[2]; + a += pixel[3]; + acount++; + } + } + } + } + + if( acount == 0 ) + acount = 1; + + out[0] = r / acount; + out[1] = g / acount; + out[2] = b / acount; +// out[3] = (int)( SimpleSpline( ( a / 9.0f ) / 255.0f ) * 255 ); +} + +/* +================= +GL_ApplyFilter + +Apply box-filter to 1-bit alpha +================= +*/ +byte *GL_ApplyFilter( const byte *source, int width, int height ) +{ + byte *in = (byte *)source; + byte *out = (byte *)source; + int i; + + for( i = 0; source && i < width * height; i++, in += 4 ) + { + if( in[0] == 0 && in[1] == 0 && in[2] == 0 && in[3] == 0 ) + GL_BoxFilter3x3( in, source, width, height, i % width, i / width ); + } + + return out; +} + /* ================= GL_ApplyGamma @@ -1106,6 +1183,9 @@ static qboolean GL_UploadTexture( gltexture_t *tex, rgbdata_t *pic ) if( !ImageDXT( pic->type ) && !FBitSet( tex->flags, TF_NOMIPMAP|TF_SKYSIDE )) data = GL_ApplyGamma( data, tex->width * tex->height * tex->depth, FBitSet( tex->flags, TF_NORMALMAP )); + if( !ImageDXT( pic->type ) && FBitSet( tex->flags, TF_HAS_ALPHA )) + data = GL_ApplyFilter( data, tex->width, tex->height ); + // mips will be auto-generated if desired for( j = 0; j < mipCount; j++ ) { diff --git a/engine/client/gl_local.h b/engine/client/gl_local.h index dd52f2fe..741d5766 100644 --- a/engine/client/gl_local.h +++ b/engine/client/gl_local.h @@ -290,10 +290,11 @@ qboolean R_CullSurface( msurface_t *surf, gl_frustum_t *frustum, uint clipflags // // gl_decals.c // -void DrawSurfaceDecals( void ); +void DrawSurfaceDecals( msurface_t *fa, qboolean single ); float *R_DecalSetupVerts( decal_t *pDecal, msurface_t *surf, int texture, int *outCount ); void DrawSingleDecal( decal_t *pDecal, msurface_t *fa ); void R_EntityRemoveDecals( model_t *mod ); +void DrawDecalsBatch( void ); void R_ClearDecals( void ); // @@ -623,7 +624,6 @@ typedef struct int faceCull; - qboolean drawTrans; qboolean stencilEnabled; qboolean in2DMode; } glstate_t; diff --git a/engine/client/gl_rmain.c b/engine/client/gl_rmain.c index 3a722090..071b3daf 100644 --- a/engine/client/gl_rmain.c +++ b/engine/client/gl_rmain.c @@ -106,13 +106,13 @@ static qboolean R_OpaqueEntity( cl_entity_t *ent ) { if( ent->curstate.rendermode == kRenderNormal ) return true; - +#if 0 if( ent->model->type != mod_brush ) return false; if( ent->curstate.rendermode == kRenderTransAlpha ) return true; - +#endif return false; } @@ -127,36 +127,36 @@ static int R_TransEntityCompare( const cl_entity_t **a, const cl_entity_t **b ) { cl_entity_t *ent1, *ent2; vec3_t vecLen, org; - float len1, len2; + float dist1, dist2; ent1 = (cl_entity_t *)*a; ent2 = (cl_entity_t *)*b; - // then by distance - if( ent1->model->type == mod_brush ) + // sort by distance + if( ent1->curstate.rendermode != kRenderTransAlpha ) { VectorAverage( ent1->model->mins, ent1->model->maxs, org ); VectorAdd( ent1->origin, org, org ); VectorSubtract( RI.vieworg, org, vecLen ); + dist1 = DotProduct( vecLen, vecLen ); } - else VectorSubtract( RI.vieworg, ent1->origin, vecLen ); - len1 = VectorLength( vecLen ); + else dist1 = 1000000000; - if( ent2->model->type == mod_brush ) + if( ent2->curstate.rendermode != kRenderTransAlpha ) { VectorAverage( ent2->model->mins, ent2->model->maxs, org ); VectorAdd( ent2->origin, org, org ); VectorSubtract( RI.vieworg, org, vecLen ); + dist2 = DotProduct( vecLen, vecLen ); } - else VectorSubtract( RI.vieworg, ent2->origin, vecLen ); - len2 = VectorLength( vecLen ); + else dist2 = 1000000000; - if( len1 > len2 ) + if( dist1 > dist2 ) return -1; - if( len1 < len2 ) + if( dist1 < dist2 ) return 1; - // now sort by rendermode + // then sort by rendermode if( R_RankForRenderMode( ent1 ) > R_RankForRenderMode( ent2 )) return 1; if( R_RankForRenderMode( ent1 ) < R_RankForRenderMode( ent2 )) @@ -809,8 +809,8 @@ void R_DrawEntitiesOnList( void ) { int i; - glState.drawTrans = false; tr.blend = 1.0f; + GL_CheckForErrors(); // first draw solid entities for( i = 0; i < tr.num_solid_entities && !RI.onlyClientDraw; i++ ) @@ -837,9 +837,13 @@ void R_DrawEntitiesOnList( void ) } } + GL_CheckForErrors(); + // quake-specific feature R_DrawAlphaTextureChains(); + GL_CheckForErrors(); + // draw sprites seperately, because of alpha blending for( i = 0; i < tr.num_solid_entities && !RI.onlyClientDraw; i++ ) { @@ -857,15 +861,19 @@ void R_DrawEntitiesOnList( void ) } } + GL_CheckForErrors(); + if( !RI.onlyClientDraw ) { CL_DrawBeams( false ); } + GL_CheckForErrors(); + if( RI.drawWorld ) clgame.dllFuncs.pfnDrawNormalTriangles(); - glState.drawTrans = true; + GL_CheckForErrors(); // then draw translucent entities for( i = 0; i < tr.num_trans_entities && !RI.onlyClientDraw; i++ ) @@ -897,12 +905,16 @@ void R_DrawEntitiesOnList( void ) } } + GL_CheckForErrors(); + if( RI.drawWorld ) { pglTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ); clgame.dllFuncs.pfnDrawTransparentTriangles (); } + GL_CheckForErrors(); + if( !RI.onlyClientDraw ) { R_AllowFog( false ); @@ -912,12 +924,15 @@ void R_DrawEntitiesOnList( void ) R_AllowFog( true ); } - glState.drawTrans = false; + GL_CheckForErrors(); + pglDisable( GL_BLEND ); // Trinity Render issues if( !RI.onlyClientDraw ) R_DrawViewModel(); CL_ExtraUpdate(); + + GL_CheckForErrors(); } /* diff --git a/engine/client/gl_rsurf.c b/engine/client/gl_rsurf.c index 87df1ee9..bebba39e 100644 --- a/engine/client/gl_rsurf.c +++ b/engine/client/gl_rsurf.c @@ -1157,11 +1157,17 @@ void R_RenderBrushPoly( msurface_t *fa ) DrawGLPoly( fa->polys, 0.0f, 0.0f ); if( is_mirror ) R_EndDrawMirror(); - if( tr.num_draw_decals < MAX_DECAL_SURFS ) - tr.draw_decals[tr.num_draw_decals++] = fa; - - if( RI.currententity->curstate.rendermode == kRenderTransTexture ) - DrawSurfaceDecals(); + if( RI.currententity->curstate.rendermode == kRenderNormal ) + { + // batch decals to draw later + if( tr.num_draw_decals < MAX_DECAL_SURFS && fa->pdecals ) + tr.draw_decals[tr.num_draw_decals++] = fa; + } + else + { + // if rendermode != kRenderNormal draw decals sequentially + DrawSurfaceDecals( fa, true ); + } // NOTE: draw mirror through in mirror show dummy lightmapped texture if( fa->flags & SURF_REFLECT && RP_NORMALPASS( )) @@ -1315,6 +1321,7 @@ void R_DrawAlphaTextureChains( void ) // restore worldmodel RI.currententity = clgame.entities; RI.currentmodel = RI.currententity->model; + RI.currententity->curstate.rendermode = kRenderTransAlpha; draw_alpha_surfaces = false; for( i = 0; i < cl.worldmodel->numtextures; i++ ) @@ -1332,9 +1339,9 @@ void R_DrawAlphaTextureChains( void ) t->texturechain = NULL; } - DrawSurfaceDecals(); GL_ResetFogColor(); R_BlendLightmaps(); + RI.currententity->curstate.rendermode = kRenderNormal; // restore world rendermode pglAlphaFunc( GL_GREATER, 0.0f ); } @@ -1438,7 +1445,7 @@ void R_SetRenderMode( cl_entity_t *e ) case kRenderTransColor: pglBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); pglColor4ub( e->curstate.rendercolor.r, e->curstate.rendercolor.g, e->curstate.rendercolor.b, e->curstate.renderamt ); - pglTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_ALPHA ); + pglTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ); pglDisable( GL_TEXTURE_2D ); pglEnable( GL_BLEND ); break; @@ -1566,7 +1573,7 @@ void R_DrawBrushModel( cl_entity_t *e ) if( e->curstate.rendermode == kRenderTransColor ) pglEnable( GL_TEXTURE_2D ); - DrawSurfaceDecals(); + DrawDecalsBatch(); GL_ResetFogColor(); R_BlendLightmaps(); R_RenderFullbrights(); @@ -1987,7 +1994,7 @@ void R_DrawWorld( void ) if( !CL_IsDevOverviewMode( )) { - DrawSurfaceDecals(); + DrawDecalsBatch(); GL_ResetFogColor(); R_BlendLightmaps(); R_RenderFullbrights(); diff --git a/engine/client/gl_sprite.c b/engine/client/gl_sprite.c index bc0bad3f..330b816d 100644 --- a/engine/client/gl_sprite.c +++ b/engine/client/gl_sprite.c @@ -980,7 +980,7 @@ void R_DrawSpriteModel( cl_entity_t *e ) color2[1] = (float)lightColor.g * ( 1.0f / 255.0f ); color2[2] = (float)lightColor.b * ( 1.0f / 255.0f ); // NOTE: sprites with 'lightmap' looks ugly when alpha func is GL_GREATER 0.0 - pglAlphaFunc( GL_GEQUAL, 0.25f ); + pglAlphaFunc( GL_GREATER, 0.25f ); } if( R_SpriteAllowLerping( e, psprite )) diff --git a/engine/client/s_main.c b/engine/client/s_main.c index 225a0c53..1e8c23d3 100644 --- a/engine/client/s_main.c +++ b/engine/client/s_main.c @@ -189,7 +189,7 @@ void S_UpdateSoundFade( void ) } // spline it. - f = S_SimpleSpline( f ); + f = SimpleSpline( f ); f = bound( 0.0f, f, 1.0f ); soundfade.percent = soundfade.initial_percent * f; diff --git a/engine/client/s_utils.c b/engine/client/s_utils.c index 4344f0c3..58154a2b 100644 --- a/engine/client/s_utils.c +++ b/engine/client/s_utils.c @@ -20,24 +20,6 @@ GNU General Public License for more details. #define ZERO_X_8( b ) (( b ) < 2 && ( b ) > -2 ) #define ZERO_X_16( b ) (( b ) < 512 && ( b ) > -512 ) -/* -================= -S_SimpleSpline - -NOTE: ripped from hl2 source -hermite basis function for smooth interpolation -Similar to Gain() above, but very cheap to call -value should be between 0 & 1 inclusive -================= -*/ -float S_SimpleSpline( float value ) -{ - float valueSquared = value * value; - - // nice little ease-in, ease-out spline-like curve - return (3.0f * valueSquared - 2.0f * valueSquared * value); -} - //----------------------------------------------------------------------------- // Purpose: Search backward for a zero crossing starting at sample // Input : sample - starting point diff --git a/engine/client/sound.h b/engine/client/sound.h index 78a0f457..164e537e 100644 --- a/engine/client/sound.h +++ b/engine/client/sound.h @@ -344,7 +344,6 @@ int S_ZeroCrossingBefore( wavdata_t *pWaveData, int sample ); int S_GetOutputData( wavdata_t *pSource, void **pData, int samplePosition, int sampleCount, qboolean use_loop ); void S_SetSampleStart( channel_t *pChan, wavdata_t *pSource, int newPosition ); void S_SetSampleEnd( channel_t *pChan, wavdata_t *pSource, int newEndPosition ); -float S_SimpleSpline( float value ); // // s_vox.c diff --git a/engine/common/mathlib.c b/engine/common/mathlib.c index 00b7f139..be302645 100644 --- a/engine/common/mathlib.c +++ b/engine/common/mathlib.c @@ -51,6 +51,24 @@ float anglemod( float a ) return a; } +/* +================= +SimpleSpline + +NOTE: ripped from hl2 source +hermite basis function for smooth interpolation +Similar to Gain() above, but very cheap to call +value should be between 0 & 1 inclusive +================= +*/ +float SimpleSpline( float value ) +{ + float valueSquared = value * value; + + // nice little ease-in, ease-out spline-like curve + return (3.0f * valueSquared - 2.0f * valueSquared * value); +} + word FloatToHalf( float v ) { unsigned int i = *((unsigned int *)&v); diff --git a/engine/common/mathlib.h b/engine/common/mathlib.h index f75db1cf..4cc2a465 100644 --- a/engine/common/mathlib.h +++ b/engine/common/mathlib.h @@ -122,6 +122,7 @@ float rsqrt( float number ); float anglemod( float a ); word FloatToHalf( float v ); float HalfToFloat( word h ); +float SimpleSpline( float value ); void RoundUpHullSize( vec3_t size ); int SignbitsForPlane( const vec3_t normal ); int PlaneTypeForNormal( const vec3_t normal ); diff --git a/engine/server/sv_game.c b/engine/server/sv_game.c index 94593d72..270ff120 100644 --- a/engine/server/sv_game.c +++ b/engine/server/sv_game.c @@ -152,9 +152,10 @@ void SV_SetModel( edict_t *ent, const char *name ) case mod_brush: case mod_sprite: Mod_GetBounds( ent->v.modelindex, mins, maxs ); - SV_SetMinMaxSize( ent, mins, maxs, true ); break; } + + SV_SetMinMaxSize( ent, mins, maxs, true ); } float SV_AngleMod( float ideal, float current, float speed ) @@ -230,8 +231,7 @@ qboolean SV_CheckClientVisiblity( sv_client_t *cl, const byte *mask ) vec3_t vieworg; mleaf_t *leaf; - if( !mask || svs.maxclients <= 1 ) - return true; // GoldSrc rules + if( !mask ) return true; // GoldSrc rules clientnum = cl - svs.clients; VectorCopy( viewPoint[clientnum], vieworg ); @@ -308,7 +308,8 @@ int SV_Multicast( int dest, const vec3_t origin, const edict_t *ent, qboolean us // intentional fallthrough case MSG_PAS: if( origin == NULL ) return false; - Mod_FatPVS( origin, FATPHS_RADIUS, fatphs, world.fatbytes, false, false ); + // NOTE: GoldSource not using PHS for singleplayer + Mod_FatPVS( origin, FATPHS_RADIUS, fatphs, world.fatbytes, false, ( svs.maxclients == 1 )); mask = fatphs; // using the FatPVS like a PHS break; case MSG_PVS_R: @@ -3843,7 +3844,10 @@ void SV_PlaybackEventFull( int flags, const edict_t *pInvoker, word eventindex, // setup pvs cluster for invoker if( !FBitSet( flags, FEV_GLOBAL )) - mask = Mod_GetPVSForPoint( pvspoint ); + { + Mod_FatPVS( pvspoint, FATPHS_RADIUS, fatphs, world.fatbytes, false, ( svs.maxclients == 1 )); + mask = fatphs; // using the FatPVS like a PHS + } // process all the clients for( slot = 0, cl = svs.clients; slot < svs.maxclients; slot++, cl++ ) diff --git a/engine/server/sv_phys.c b/engine/server/sv_phys.c index e03d9d32..b39c0ace 100644 --- a/engine/server/sv_phys.c +++ b/engine/server/sv_phys.c @@ -1170,7 +1170,7 @@ void SV_Physics_Pusher( edict_t *ent ) // reset the local time to what it was before we rotated ent->v.ltime = oldtime; pBlocker = SV_PushMove( ent, movetime ); - if( oldtime2 < ent->v.ltime ) + if( ent->v.ltime < oldtime2 ) ent->v.ltime = oldtime2; } } @@ -1200,7 +1200,6 @@ void SV_Physics_Pusher( edict_t *ent ) ent->v.nextthink = 0.0f; svgame.globals->time = sv.time; svgame.dllFuncs.pfnThink( ent ); - if( ent->free ) return; } } @@ -1437,13 +1436,14 @@ void SV_Physics_Toss( edict_t *ent ) ground = ent->v.groundentity; - if( ent->v.velocity[2] > 0.0f || !SV_IsValidEdict( ground ) || ground->v.flags & (FL_MONSTER|FL_CLIENT) || svgame.globals->changelevel ) - { - ent->v.flags &= ~FL_ONGROUND; - } + if( ent->v.velocity[2] > 0 ) + ClearBits( ent->v.flags, FL_ONGROUND ); + + if( !SV_IsValidEdict( ground ) || FBitSet( ground->v.flags, FL_MONSTER|FL_CLIENT )) + ClearBits( ent->v.flags, FL_ONGROUND ); // if on ground and not moving, return. - if( ent->v.flags & FL_ONGROUND && VectorIsNull( ent->v.velocity )) + if( FBitSet( ent->v.flags, FL_ONGROUND ) && VectorIsNull( ent->v.velocity )) { VectorClear( ent->v.avelocity ); @@ -1593,37 +1593,46 @@ void SV_Physics_Step( edict_t *ent ) ent->v.velocity[2] += buoyancy; } - if( !wasonground && !( ent->v.flags & FL_FLY ) && (!( ent->v.flags & FL_SWIM ) || ent->v.waterlevel <= 0 )) + if( !wasonground ) { - if( !inwater ) - SV_AddGravity( ent ); + if( !FBitSet( ent->v.flags, FL_FLY )) + { + if( !FBitSet( ent->v.flags, FL_SWIM ) && ( ent->v.waterlevel > 0 )) + { + if( !inwater ) + SV_AddGravity( ent ); + } + } } if( !VectorIsNull( ent->v.velocity ) || !VectorIsNull( ent->v.basevelocity )) { ent->v.flags &= ~FL_ONGROUND; - if(( wasonground || wasonmover ) && ( ent->v.health > 0 || SV_CheckBottom( ent, MOVE_NORMAL ))) + if( wasonground || wasonmover ) { - float *vel = ent->v.velocity; - float control, speed, newspeed; - float friction; - - speed = sqrt(( vel[0] * vel[0] ) + ( vel[1] * vel[1] )); // DotProduct2D - - if( speed ) + if(!( ent->v.health <= 0 && !SV_CheckBottom( ent, MOVE_NORMAL ))) { - friction = sv_friction.value * ent->v.friction; // factor - ent->v.friction = 1.0f; // g-cont. ??? - if( wasonmover ) friction *= 0.5f; // add a little friction + float *vel = ent->v.velocity; + float control, speed, newspeed; + float friction; - control = (speed < sv_stopspeed.value) ? sv_stopspeed.value : speed; - newspeed = speed - (sv.frametime * control * friction); - if( newspeed < 0 ) newspeed = 0; - newspeed /= speed; + speed = sqrt(( vel[0] * vel[0] ) + ( vel[1] * vel[1] )); // DotProduct2D - vel[0] = vel[0] * newspeed; - vel[1] = vel[1] * newspeed; + if( speed ) + { + friction = sv_friction.value * ent->v.friction; // factor + ent->v.friction = 1.0f; // g-cont. ??? + if( wasonmover ) friction *= 0.5f; // add a little friction + + control = (speed < sv_stopspeed.value) ? sv_stopspeed.value : speed; + newspeed = speed - (sv.frametime * control * friction); + if( newspeed < 0 ) newspeed = 0; + newspeed /= speed; + + vel[0] = vel[0] * newspeed; + vel[1] = vel[1] * newspeed; + } } } @@ -1635,7 +1644,6 @@ void SV_Physics_Step( edict_t *ent ) SV_CheckVelocity( ent ); VectorSubtract( ent->v.velocity, ent->v.basevelocity, ent->v.velocity ); - SV_CheckVelocity( ent ); VectorAdd( ent->v.origin, ent->v.mins, mins );