26 Jun 2012

This commit is contained in:
g-cont 2012-06-26 00:00:00 +04:00 committed by Alibek Omarov
parent 1e7343b3f6
commit 0b296ece60
49 changed files with 587 additions and 299 deletions

29
cl_dll/cl_dll.dsw Normal file
View File

@ -0,0 +1,29 @@
Microsoft Developer Studio Workspace File, Format Version 6.00
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
###############################################################################
Project: "cl_dll"=.\cl_dll.dsp - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
}}}
###############################################################################
Global:
Package=<5>
{{{
}}}
Package=<3>
{{{
}}}
###############################################################################

BIN
cl_dll/cl_dll.ncb Normal file

Binary file not shown.

BIN
cl_dll/cl_dll.opt Normal file

Binary file not shown.

View File

@ -18,6 +18,9 @@ GNU General Public License for more details.
#include "bspfile.h" // we need some declarations from it
typedef vec_t vec2_t[2];
typedef vec_t vec4_t[4];
/*
==============================================================================
@ -310,8 +313,6 @@ typedef struct model_s
cache_user_t cache; // only access through Mod_Extradata
} model_t;
typedef vec_t vec4_t[4];
typedef struct alight_s
{
int ambientlight; // clip at 128

View File

@ -88,6 +88,7 @@
#define SOLID_BBOX 2 // touch on edge, block
#define SOLID_SLIDEBOX 3 // touch on edge, but not an onground
#define SOLID_BSP 4 // bsp clip, touch on edge, block
#define SOLID_CUSTOM 5 // call external callbacks for tracing
// edict->deadflag values
#define DEAD_NO 0 // alive

View File

@ -17,6 +17,7 @@
#include <math.h>
typedef float vec_t;
typedef vec_t vec2_t[2];
typedef vec_t vec3_t[3];
typedef vec_t vec4_t[4]; // x,y,z,w
typedef vec_t vec5_t[5];

View File

@ -31,6 +31,7 @@ typedef enum
#define TRI_LINES 4
#define TRI_TRIANGLE_STRIP 5
#define TRI_QUAD_STRIP 6
#define TRI_POINTS 7
typedef struct triangleapi_s
{

View File

@ -48,11 +48,22 @@ public:
static TYPEDESCRIPTION m_SaveData[];
float m_flAltitude;
float m_flCachedLength; // tongue cached length
float m_flKillVictimTime;
int m_cGibs;// barnacle loads up on gibs each time it kills something.
int m_cGibs; // barnacle loads up on gibs each time it kills something.
BOOL m_fTongueExtended;
BOOL m_fLiftingPrey;
float m_flTongueAdj;
// FIXME: need a custom barnacle model with non-generic hitgroup
// otherwise we can apply to damage to tongue instead of body
#ifdef BARNACLE_FIX_VISIBILITY
void SetObjectCollisionBox( void )
{
pev->absmin = pev->origin + Vector( -16, -16, -m_flCachedLength );
pev->absmax = pev->origin + Vector( 16, 16, 0 );
}
#endif
};
LINK_ENTITY_TO_CLASS( monster_barnacle, CBarnacle );
@ -64,6 +75,7 @@ TYPEDESCRIPTION CBarnacle::m_SaveData[] =
DEFINE_FIELD( CBarnacle, m_fTongueExtended, FIELD_BOOLEAN ),
DEFINE_FIELD( CBarnacle, m_fLiftingPrey, FIELD_BOOLEAN ),
DEFINE_FIELD( CBarnacle, m_flTongueAdj, FIELD_FLOAT ),
DEFINE_FIELD( CBarnacle, m_flCachedLength, FIELD_FLOAT ),
};
IMPLEMENT_SAVERESTORE( CBarnacle, CBaseMonster );
@ -116,7 +128,8 @@ void CBarnacle :: Spawn()
m_flFieldOfView = 0.5;// indicates the width of this monster's forward view cone ( as a dotproduct result )
m_MonsterState = MONSTERSTATE_NONE;
m_flKillVictimTime = 0;
m_cGibs = 0;
m_flCachedLength = 32; // mins.z
m_cGibs = 0;
m_fLiftingPrey = FALSE;
m_flTongueAdj = -100;
@ -148,6 +161,14 @@ void CBarnacle :: BarnacleThink ( void )
CBaseMonster *pVictim;
float flLength;
#ifdef BARNACLE_FIX_VISIBILITY
if( m_flCachedLength != ( m_flAltitude + m_flTongueAdj ) || ( pev->absmin.z != pev->origin.z + -m_flCachedLength ))
{
// recalc collision box here to avoid barnacle disappears bug
m_flCachedLength = (m_flAltitude + m_flTongueAdj);
UTIL_SetOrigin( pev, pev->origin );
}
#endif
pev->nextthink = gpGlobals->time + 0.1;
if ( m_hEnemy != NULL )

View File

@ -181,7 +181,7 @@ qboolean CL_SnapshotGetName( int lastnum, char *filename )
lastnum -= c * 10;
d = lastnum;
Q_sprintf( filename, "../%s%i%i%i%i.bmp", clgame.mapname, a, b, c, d );
Q_sprintf( filename, "../%s_%i%i%i%i.bmp", clgame.mapname, a, b, c, d );
return true;
}

View File

@ -146,7 +146,7 @@ void CL_UpdateEntityFields( cl_entity_t *ent )
{
CL_SetTraceHull( 0 ); // g-cont. player hull for better detect moving platforms
VectorSet( vecSrc, ent->origin[0], ent->origin[1], ent->origin[2] + ent->model->maxs[2] );
VectorSet( vecEnd, vecSrc[0], vecSrc[1], vecSrc[2] - ent->model->mins[2] - 32 );
VectorSet( vecEnd, vecSrc[0], vecSrc[1], vecSrc[2] - ent->model->mins[2] - 8 );
CL_PlayerTraceExt( vecSrc, vecEnd, PM_STUDIO_IGNORE, CL_PushMoveFilter, &trace );
m_pGround = CL_GetEntityByIndex( pfnIndexFromTrace( &trace ));
}
@ -428,7 +428,7 @@ void CL_UpdateStudioVars( cl_entity_t *ent, entity_state_t *newstate, qboolean n
ent->latched.prevcontroller[i] = newstate->controller[i];
// copy blends
for( i = 0; i < 4; i++ )
for( i = 0; i < 2; i++ )
ent->latched.prevblending[i] = newstate->blending[i];
return;
}
@ -441,7 +441,7 @@ void CL_UpdateStudioVars( cl_entity_t *ent, entity_state_t *newstate, qboolean n
else ent->latched.sequencetime = ent->curstate.animtime + 0.1f;
// save current blends to right lerping from last sequence
for( i = 0; i < 4; i++ )
for( i = 0; i < 2; i++ )
ent->latched.prevseqblending[i] = ent->curstate.blending[i];
ent->latched.prevsequence = ent->curstate.sequence; // save old sequence
ent->syncbase = -0.01f; // back up to get 0'th frame animations
@ -469,7 +469,7 @@ void CL_UpdateStudioVars( cl_entity_t *ent, entity_state_t *newstate, qboolean n
}
// copy blends
for( i = 0; i < 4; i++ )
for( i = 0; i < 2; i++ )
ent->latched.prevblending[i] = ent->curstate.blending[i];
if( !VectorCompare( newstate->origin, ent->curstate.origin ))

View File

@ -86,6 +86,7 @@ static dllfunc_t cdll_new_exports[] = // allowed only in SDK 2.3 and higher
{ "HUD_ChatInputPosition", (void **)&clgame.dllFuncs.pfnChatInputPosition },
{ "HUD_GetRenderInterface", (void **)&clgame.dllFuncs.pfnGetRenderInterface },
{ "HUD_GetPlayerTeam", (void **)&clgame.dllFuncs.pfnGetPlayerTeam },
{ "HUD_ClipMoveToEntity", (void **)&clgame.dllFuncs.pfnClipMoveToEntity },
{ NULL, NULL }
};
@ -1063,7 +1064,6 @@ void CL_InitEdicts( void )
cls.packet_entities = Z_Realloc( cls.packet_entities, sizeof( entity_state_t ) * cls.num_client_entities );
clgame.entities = Mem_Alloc( clgame.mempool, sizeof( cl_entity_t ) * clgame.maxEntities );
clgame.static_entities = Mem_Alloc( clgame.mempool, sizeof( cl_entity_t ) * MAX_STATIC_ENTITIES );
clgame.efrags = Mem_Alloc( clgame.mempool, sizeof( efrag_t ) * MAX_EFRAGS );
clgame.numStatics = 0;
if(( clgame.maxRemapInfos - 1 ) != clgame.maxEntities )
@ -1084,10 +1084,6 @@ void CL_FreeEdicts( void )
Mem_Free( clgame.static_entities );
clgame.static_entities = NULL;
if( clgame.efrags )
Mem_Free( clgame.efrags );
clgame.efrags = NULL;
if( cls.packet_entities )
Z_Free( cls.packet_entities );
@ -1674,7 +1670,7 @@ pfnDrawConsoleString
drawing string like a console string
=============
*/
static int pfnDrawConsoleString( int x, int y, char *string )
int pfnDrawConsoleString( int x, int y, char *string )
{
int drawLen;
@ -1696,7 +1692,7 @@ pfnDrawSetTextColor
set color for anything
=============
*/
static void pfnDrawSetTextColor( float r, float g, float b )
void pfnDrawSetTextColor( float r, float g, float b )
{
// bound color and convert to byte
clgame.ds.textColor[0] = (byte)bound( 0, r * 255, 255 );
@ -1705,7 +1701,7 @@ static void pfnDrawSetTextColor( float r, float g, float b )
clgame.ds.textColor[3] = (byte)0xFF;
}
static void pfnDrawConsoleStringLen( const char *pText, int *length, int *height )
void pfnDrawConsoleStringLen( const char *pText, int *length, int *height )
{
Con_SetFont( con_fontsize->integer );
Con_DrawStringLen( pText, length, height );
@ -2926,6 +2922,9 @@ void TriBegin( int mode )
{
switch( mode )
{
case TRI_POINTS:
mode = GL_POINTS;
break;
case TRI_TRIANGLES:
mode = GL_TRIANGLES;
break;

View File

@ -550,10 +550,14 @@ pfnDrawCharacter
quakefont draw character
=============
*/
static void pfnDrawCharacter( int x, int y, int width, int height, int ch, int ulRGBA, HIMAGE hFont )
static void pfnDrawCharacter( int ix, int iy, int iwidth, int iheight, int ch, int ulRGBA, HIMAGE hFont )
{
rgba_t color;
float row, col, size;
float s1, t1, s2, t2;
float x = ix, y = iy;
float width = iwidth;
float height = iheight;
ch &= 255;
@ -566,23 +570,32 @@ static void pfnDrawCharacter( int x, int y, int width, int height, int ch, int u
color[2] = (ulRGBA & 0xFF) >> 0;
pglColor4ubv( color );
col = (ch & 15) * 0.0625 + (0.5f / 256.0f);
row = (ch >> 4) * 0.0625 + (0.5f / 256.0f);
col = (ch & 15) * 0.0625f + (0.5f / 256.0f);
row = (ch >> 4) * 0.0625f + (0.5f / 256.0f);
size = 0.0625f - (1.0f / 256.0f);
s1 = col;
t1 = row;
s2 = s1 + size;
t2 = t1 + size;
// pass scissor test if supposed
if( menu.ds.scissor_test && !PIC_Scissor( &x, &y, &width, &height, &s1, &t1, &s2, &t2 ))
return;
GL_SetRenderMode( kRenderTransTexture );
R_DrawStretchPic( x, y, width, height, col, row, col + size, row + size, hFont );
R_DrawStretchPic( x, y, width, height, s1, t1, s2, t2, hFont );
pglColor4ub( 255, 255, 255, 255 );
}
/*
=============
pfnDrawConsoleString
UI_DrawConsoleString
drawing string like a console string
=============
*/
static int pfnDrawConsoleString( int x, int y, const char *string )
static int UI_DrawConsoleString( int x, int y, const char *string )
{
int drawLen;
@ -600,7 +613,7 @@ pfnDrawSetTextColor
set color for anything
=============
*/
static void pfnDrawSetTextColor( int r, int g, int b, int alpha )
static void UI_DrawSetTextColor( int r, int g, int b, int alpha )
{
// bound color and convert to byte
menu.ds.textColor[0] = r;
@ -889,8 +902,8 @@ static ui_enginefuncs_t gEngfuncs =
UI_GetLogoHeight,
UI_GetLogoLength,
pfnDrawCharacter,
pfnDrawConsoleString,
pfnDrawSetTextColor,
UI_DrawConsoleString,
UI_DrawSetTextColor,
Con_DrawStringLen,
Con_DefaultColor,
pfnGetPlayerModel,

View File

@ -29,6 +29,22 @@ void CL_ClearPhysEnts( void )
clgame.pmove->numphysent = 0;
}
void CL_ClipPMoveToEntity( physent_t *pe, const vec3_t start, vec3_t mins, vec3_t maxs, const vec3_t end, pmtrace_t *tr )
{
ASSERT( tr != NULL );
if( clgame.dllFuncs.pfnClipMoveToEntity != NULL )
{
// do custom sweep test
clgame.dllFuncs.pfnClipMoveToEntity( pe, start, mins, maxs, end, tr );
}
else
{
// function is missed, so we didn't hit anything
tr->allsolid = false;
}
}
qboolean CL_CopyEntityToPhysEnt( physent_t *pe, cl_entity_t *ent )
{
model_t *mod = Mod_Handle( ent->curstate.modelindex );
@ -64,6 +80,12 @@ qboolean CL_CopyEntityToPhysEnt( physent_t *pe, cl_entity_t *ent )
VectorCopy( ent->curstate.mins, pe->mins );
VectorCopy( ent->curstate.maxs, pe->maxs );
break;
case SOLID_CUSTOM:
pe->model = (mod->type == mod_brush) ? mod : NULL;
pe->studiomodel = (mod->type == mod_studio) ? mod : NULL;
VectorCopy( ent->curstate.mins, pe->mins );
VectorCopy( ent->curstate.maxs, pe->maxs );
break;
default:
pe->studiomodel = (mod->type == mod_studio) ? mod : NULL;
VectorCopy( ent->curstate.mins, pe->mins );

View File

@ -923,6 +923,9 @@ void CL_BreakModel( const vec3_t pos, const vec3_t size, const vec3_t direction,
vecSpot[1] = pos[1] + Com_RandomFloat( -0.5f, 0.5f ) * size[1];
vecSpot[2] = pos[2] + Com_RandomFloat( -0.5f, 0.5f ) * size[2];
if( CL_PointContents( vecSpot ) == CONTENTS_SOLID )
continue; // a piece stuck in the wall, ignore it
pTemp = CL_TempEntAlloc( vecSpot, Mod_Handle( modelIndex ));
if( !pTemp ) return;
@ -2693,6 +2696,8 @@ EFRAGS MANAGEMENT
==============================================================
*/
efrag_t cl_efrags[MAX_EFRAGS];
/*
==============
CL_ClearEfrags
@ -2702,10 +2707,10 @@ void CL_ClearEfrags( void )
{
int i;
Q_memset( clgame.efrags, 0, sizeof( clgame.efrags ));
Q_memset( cl_efrags, 0, sizeof( cl_efrags ));
// allocate the efrags and chain together into a free list
clgame.free_efrags = clgame.efrags;
clgame.free_efrags = cl_efrags;
for( i = 0; i < MAX_EFRAGS - 1; i++ )
clgame.free_efrags[i].entnext = &clgame.free_efrags[i+1];
clgame.free_efrags[i].entnext = NULL;

View File

@ -380,6 +380,7 @@ void V_PostRender( void )
SCR_RSpeeds();
SCR_NetSpeeds();
SCR_DrawFPS();
SV_DrawOrthoTriangles();
CL_DrawDemoRecording();
R_ShowTextures();
CL_DrawHUD( CL_CHANGELEVEL );

View File

@ -351,6 +351,7 @@ typedef struct
void (*pfnCalcRefdef)( ref_params_t *pparams );
int (*pfnGetRenderInterface)( int version, render_api_t *renderfuncs, render_interface_t *callback );
int (*pfnGetPlayerTeam)( int playerIndex );
void (*pfnClipMoveToEntity)( physent_t *pe, const vec3_t start, vec3_t mins, vec3_t maxs, const vec3_t end, pmtrace_t *tr );
} HUD_FUNCTIONS;
typedef struct
@ -403,7 +404,6 @@ typedef struct
net_request_t net_requests[MAX_REQUESTS]; // no reason to keep more
efrag_t *efrags; // efrags pool
efrag_t *free_efrags; // linked efrags
cl_entity_t viewent; // viewmodel
} clgame_static_t;

View File

@ -387,8 +387,10 @@ void R_DrawWaterSurfaces( void );
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_RebuildLightmaps( void );
void GL_BuildLightmaps( void );
void GL_ResetFogColor( void );
//
// gl_sprite.c

View File

@ -310,7 +310,7 @@ static qboolean R_RecursiveLightPoint( model_t *model, mnode_t *node, const vec3
int R_LightTraceFilter( physent_t *pe )
{
if( !pe || pe->solid != SOLID_BSP )
if( !pe || pe->solid != SOLID_BSP || pe->info == 0 )
return 1;
return 0;
@ -327,6 +327,7 @@ void R_LightForPoint( const vec3_t point, color24 *ambientLight, qboolean invLig
pmtrace_t trace;
cl_entity_t *m_pGround;
vec3_t start, end, dir;
qboolean secondpass = false;
float dist, add;
model_t *pmodel;
mnode_t *pnodes;
@ -348,6 +349,7 @@ void R_LightForPoint( const vec3_t point, color24 *ambientLight, qboolean invLig
return;
}
get_light:
// Get lighting at this point
VectorCopy( point, start );
VectorCopy( point, end );
@ -367,11 +369,12 @@ void R_LightForPoint( const vec3_t point, color24 *ambientLight, qboolean invLig
pnodes = pmodel->nodes;
m_pGround = NULL;
if( r_lighting_extended->integer )
if( r_lighting_extended->integer && !secondpass )
{
CL_SetTraceHull( 2 );
CL_PlayerTraceExt( start, end, PM_STUDIO_IGNORE, R_LightTraceFilter, &trace );
m_pGround = CL_GetEntityByIndex( pfnIndexFromTrace( &trace ));
if( trace.startsolid || trace.allsolid ) m_pGround = NULL; // trace in solid
}
if( m_pGround && m_pGround->model && m_pGround->model->type == mod_brush )
@ -424,6 +427,14 @@ void R_LightForPoint( const vec3_t point, color24 *ambientLight, qboolean invLig
ambientLight->b = 255 * ambient;
}
if( ambientLight->r == 0 && ambientLight->g == 0 && ambientLight->b == 0 && !secondpass )
{
// in some cases r_lighting_extended 1 does a wrong results
// make another pass and try to get lighting info from world
secondpass = true;
goto get_light;
}
// add dynamic lights
if( radius && r_dynamic->integer )
{

View File

@ -1040,7 +1040,8 @@ void R_DrawEntitiesOnList( void )
while( pglGetError() != GL_NO_ERROR );
// don't fogging translucent surfaces
pglDisable( GL_FOG );
if( !RI.fogCustom )
pglDisable( GL_FOG );
pglDepthMask( GL_FALSE );
glState.drawTrans = true;

View File

@ -215,6 +215,35 @@ static void SubdividePolygon_r( msurface_t *warpface, int numverts, float *verts
Q_memcpy( poly->verts[i+1], poly->verts[1], sizeof( poly->verts[0] ));
}
void GL_SetupFogColorForSurfaces( void )
{
vec3_t fogColor;
float factor, div;
if(( !RI.fogEnabled && !RI.fogCustom ) || RI.refdef.onlyClientDraw )
return;
if( RI.currententity->curstate.rendermode == kRenderTransTexture )
{
pglFogfv( GL_FOG_COLOR, RI.fogColor );
return;
}
div = (r_detailtextures->integer) ? 2.0f : 1.0f;
factor = (r_detailtextures->integer) ? 3.0f : 2.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
if(( RI.fogEnabled || RI.fogCustom ) && !RI.refdef.onlyClientDraw )
pglFogfv( GL_FOG_COLOR, RI.fogColor );
}
/*
================
GL_SubdivideSurface
@ -257,6 +286,8 @@ void GL_BuildPolygonFromSurface( model_t *mod, msurface_t *fa )
int i, lindex, lnumverts;
medge_t *pedges, *r_pedge;
int vertpage;
texture_t *tex;
gltexture_t *glt;
float *vec;
float s, t;
glpoly_t *poly;
@ -267,6 +298,20 @@ void GL_BuildPolygonFromSurface( model_t *mod, msurface_t *fa )
if( !fa->texinfo || !fa->texinfo->texture )
return; // bad polygon ?
if( fa->flags & SURF_CONVEYOR && fa->texinfo->texture->gl_texturenum != 0 )
{
glt = R_GetTexture( fa->texinfo->texture->gl_texturenum );
tex = fa->texinfo->texture;
ASSERT( glt != NULL && tex != NULL );
// DEBUG
if( glt->srcWidth != tex->width )
Msg( "Texture %s updates conveyor width from %i to %i\n", tex->name, glt->srcWidth, tex->width );
// update conveyor widths for properly scrolling speed
glt->srcWidth = tex->width;
glt->srcHeight = tex->height;
}
// reconstruct the polygon
pedges = mod->edges;
lnumverts = fa->numedges;
@ -634,6 +679,10 @@ void DrawGLPoly( glpoly_t *p, float xScale, float yScale )
cl_entity_t *e = RI.currententity;
int i, hasScale = false;
// special hack for non-lightmapped surfaces
if( p->flags & SURF_DRAWTILED )
GL_ResetFogColor();
if( p->flags & SURF_CONVEYOR )
{
gltexture_t *texture;
@ -679,6 +728,10 @@ void DrawGLPoly( glpoly_t *p, float xScale, float yScale )
}
pglEnd();
// special hack for non-lightmapped surfaces
if( p->flags & SURF_DRAWTILED )
GL_SetupFogColorForSurfaces();
}
/*
@ -727,6 +780,8 @@ void R_BlendLightmaps( void )
if( r_fullbright->integer || !cl.worldmodel->lightdata )
return;
GL_SetupFogColorForSurfaces ();
if( RI.currententity )
{
// check for rendermode
@ -868,6 +923,9 @@ void R_BlendLightmaps( void )
pglDisable( GL_ALPHA_TEST );
pglTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE );
}
// restore fog here
GL_ResetFogColor();
}
/*
@ -883,7 +941,7 @@ void R_RenderFullbrights( void )
if( !draw_fullbrights )
return;
if( !RI.fogCustom )
if( RI.fogEnabled && !RI.refdef.onlyClientDraw )
pglDisable( GL_FOG );
pglEnable( GL_BLEND );
@ -935,6 +993,8 @@ void R_RenderDetails( void )
if( !draw_details )
return;
GL_SetupFogColorForSurfaces();
pglEnable( GL_BLEND );
pglBlendFunc( GL_DST_COLOR, GL_SRC_COLOR );
pglTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL );
@ -967,6 +1027,9 @@ void R_RenderDetails( void )
pglDepthFunc( GL_LEQUAL );
draw_details = false;
// restore fog here
GL_ResetFogColor();
}
/*
@ -1026,12 +1089,35 @@ void R_RenderBrushPoly( msurface_t *fa )
draw_fullbrights = true;
}
if( r_detailtextures->integer && t->dt_texturenum )
if( r_detailtextures->integer )
{
mextrasurf_t *es = SURF_INFO( fa, RI.currentmodel );
es->detailchain = detail_surfaces[t->dt_texturenum];
detail_surfaces[t->dt_texturenum] = es;
draw_details = true;
if( RI.fogEnabled || RI.fogCustom )
{
// don't apply detail textures for windows in the fog
if( RI.currententity->curstate.rendermode != kRenderTransTexture )
{
if( t->dt_texturenum )
{
es->detailchain = detail_surfaces[t->dt_texturenum];
detail_surfaces[t->dt_texturenum] = es;
}
else
{
// draw stub detail texture for underwater surfaces
es->detailchain = detail_surfaces[tr.grayTexture];
detail_surfaces[tr.grayTexture] = es;
}
draw_details = true;
}
}
else if( t->dt_texturenum )
{
es->detailchain = detail_surfaces[t->dt_texturenum];
detail_surfaces[t->dt_texturenum] = es;
draw_details = true;
}
}
if( is_mirror ) R_BeginDrawMirror( fa );
@ -1110,6 +1196,8 @@ void R_DrawTextureChains( void )
pglColor4ub( 255, 255, 255, 255 );
R_LoadIdentity(); // set identity matrix
GL_SetupFogColorForSurfaces();
// restore worldmodel
RI.currententity = clgame.entities;
RI.currentmodel = RI.currententity->model;
@ -1141,6 +1229,8 @@ void R_DrawTextureChains( void )
}
t->texturechain = NULL;
}
GL_ResetFogColor();
}
/*
@ -1306,6 +1396,7 @@ void R_DrawBrushModel( cl_entity_t *e )
// setup the rendermode
GL_SetRenderMode( e->curstate.rendermode );
GL_SetupFogColorForSurfaces ();
// setup the color and alpha
switch( e->curstate.rendermode )
@ -1360,6 +1451,7 @@ void R_DrawBrushModel( cl_entity_t *e )
if( e->curstate.rendermode == kRenderTransColor )
pglEnable( GL_TEXTURE_2D );
GL_ResetFogColor();
R_BlendLightmaps();
R_RenderFullbrights();
R_RenderDetails();

View File

@ -959,6 +959,7 @@ void R_DrawSpriteModel( cl_entity_t *e )
break;
case kRenderGlow:
case kRenderTransAdd:
pglDisable( GL_FOG );
pglEnable( GL_BLEND );
pglBlendFunc( GL_SRC_ALPHA, GL_ONE );
break;
@ -1108,4 +1109,7 @@ void R_DrawSpriteModel( cl_entity_t *e )
pglDepthFunc( GL_LEQUAL );
pglTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE );
pglColor4ub( 255, 255, 255, 255 );
if( RI.fogCustom || ( RI.fogEnabled && !glState.drawTrans ))
pglEnable( GL_FOG );
}

View File

@ -57,6 +57,12 @@ typedef struct studiolight_s
int numelights;
} studiolight_t;
typedef struct sortedmesh_s
{
mstudiomesh_t *mesh;
int flags; // face flags
} sortedmesh_t;
convar_t *r_studio_lerping;
convar_t *r_studio_lambert;
convar_t *r_studio_lighting;
@ -71,6 +77,7 @@ static matrix3x4 g_aliastransform; // software renderer transform
static matrix3x4 g_rotationmatrix;
static vec3_t g_chrome_origin;
static vec2_t g_chrome[MAXSTUDIOVERTS]; // texture coords for surface normals
static sortedmesh_t g_sortedMeshes[MAXSTUDIOMESHES];
static matrix3x4 g_bonestransform[MAXSTUDIOBONES];
static matrix3x4 g_lighttransform[MAXSTUDIOBONES];
static matrix3x4 g_rgCachedBonesTransform[MAXSTUDIOBONES];
@ -1416,7 +1423,14 @@ void R_StudioDynamicLight( cl_entity_t *ent, alight_t *lightinfo )
plight->numdlights = 0; // clear previous dlights
if( r_studio_lighting->integer == 2 )
{
Matrix3x4_OriginFromMatrix( g_lighttransform[0], origin );
// NOTE: in some cases bone origin may be stuck in the geometry
// and produced completely black model. Run additional check for this case
if( CL_PointContents( origin ) == CONTENTS_SOLID )
Matrix3x4_OriginFromMatrix( g_rotationmatrix, origin );
}
else Matrix3x4_OriginFromMatrix( g_rotationmatrix, origin );
// setup light dir
@ -1527,7 +1541,14 @@ void R_StudioEntityLight( alight_t *lightinfo )
plight->numelights = 0; // clear previous elights
if( r_studio_lighting->integer == 2 )
{
Matrix3x4_OriginFromMatrix( g_lighttransform[0], origin );
// NOTE: in some cases bone origin may be stuck in the geometry
// and produced completely black model. Run additional check for this case
if( CL_PointContents( origin ) == CONTENTS_SOLID )
Matrix3x4_OriginFromMatrix( g_rotationmatrix, origin );
}
else Matrix3x4_OriginFromMatrix( g_rotationmatrix, origin );
for( lnum = 0, el = cl_elights; lnum < MAX_ELIGHTS; lnum++, el++ )
@ -1779,6 +1800,24 @@ mstudiotexture_t *R_StudioGetTexture( cl_entity_t *e )
return ptexture;
}
/*
===============
R_SolidEntityCompare
Sorting opaque entities by model type
===============
*/
static int R_StudioMeshCompare( const sortedmesh_t *a, const sortedmesh_t *b )
{
if( a->flags & STUDIO_NF_ADDITIVE )
return 1;
if( a->flags & STUDIO_NF_TRANSPARENT )
return -1;
return 0;
}
/*
===============
R_StudioDrawPoints
@ -1840,6 +1879,10 @@ static void R_StudioDrawPoints( void )
{
g_nFaceFlags = ptexture[pskinref[pmesh[j].skinref]].flags;
// fill in sortedmesh info
g_sortedMeshes[j].mesh = &pmesh[j];
g_sortedMeshes[j].flags = g_nFaceFlags;
for( i = 0; i < pmesh[j].numnorms; i++, lv += 3, pstudionorms++, pnormbone++ )
{
R_StudioLighting( lv, *pnormbone, g_nFaceFlags, (float *)pstudionorms );
@ -1849,18 +1892,25 @@ static void R_StudioDrawPoints( void )
}
}
// sort opaque and translucent for right results
qsort( g_sortedMeshes, m_pSubModel->nummesh, sizeof( sortedmesh_t ), R_StudioMeshCompare );
for( j = 0; j < m_pSubModel->nummesh; j++ )
{
float s, t, alpha;
short *ptricmds;
pmesh = (mstudiomesh_t *)((byte *)m_pStudioHeader + m_pSubModel->meshindex) + j;
pmesh = g_sortedMeshes[j].mesh;
ptricmds = (short *)((byte *)m_pStudioHeader + pmesh->triindex);
g_nFaceFlags = ptexture[pskinref[pmesh->skinref]].flags;
s = 1.0f / (float)ptexture[pskinref[pmesh->skinref]].width;
t = 1.0f / (float)ptexture[pskinref[pmesh->skinref]].height;
if( g_iRenderMode != kRenderTransAdd )
pglDepthMask( GL_TRUE );
else pglDepthMask( GL_FALSE );
// check bounds
if( ptexture[pskinref[pmesh->skinref]].index < 0 || ptexture[pskinref[pmesh->skinref]].index > MAX_TEXTURES )
ptexture[pskinref[pmesh->skinref]].index = tr.defaultTexture;
@ -1881,7 +1931,8 @@ static void R_StudioDrawPoints( void )
{
GL_SetRenderMode( kRenderTransAdd );
alpha = RI.currententity->curstate.renderamt * (1.0f / 255.0f);
pglBlendFunc( GL_ONE, GL_ONE );
pglBlendFunc( GL_SRC_ALPHA, GL_ONE );
pglDepthMask( GL_FALSE );
}
else
{
@ -1999,6 +2050,10 @@ static void R_StudioDrawPoints( void )
pglEnd();
}
}
// restore depthmask for next call StudioDrawPoints
if( g_iRenderMode != kRenderTransAdd )
pglDepthMask( GL_TRUE );
}
/*
@ -2449,8 +2504,9 @@ static void R_StudioRestoreRenderer( void )
pglShadeModel( GL_FLAT );
// restore depthmask state for sprites etc
if( glState.drawTrans && g_iRenderMode != kRenderTransAdd )
if( glState.drawTrans )
pglDepthMask( GL_FALSE );
else pglDepthMask( GL_TRUE );
m_fDoRemap = false;
}

View File

@ -1297,6 +1297,8 @@ void R_Free_OpenGL( void )
{
VID_RestoreGamma ();
GL_DeleteContext ();
VID_DestroyWindow ();
Sys_FreeLibrary( &opengl_dll );
@ -1355,6 +1357,9 @@ static void GL_SetDefaults( void )
pglEnable( GL_TEXTURE_2D );
pglShadeModel( GL_FLAT );
pglPointSize( 1.2f );
pglLineWidth( 1.2f );
GL_Cull( 0 );
GL_FrontFace( 0 );
@ -1453,7 +1458,7 @@ void GL_InitCommands( void )
gl_texture_lodbias = Cvar_Get( "gl_texture_lodbias", "0.0", CVAR_ARCHIVE, "LOD bias for mipmapped textures" );
gl_compress_textures = Cvar_Get( "gl_compress_textures", "0", CVAR_GLCONFIG, "compress textures to safe video memory" );
gl_luminance_textures = Cvar_Get( "gl_luminance_textures", "0", CVAR_GLCONFIG, "force all textures to luminance" );
gl_allow_static = Cvar_Get( "gl_allow_static", "1", CVAR_ARCHIVE, "force to drawing non-moveable brushes as part of world (save FPS)" );
gl_allow_static = Cvar_Get( "gl_allow_static", "0", CVAR_ARCHIVE, "force to drawing non-moveable brushes as part of world (save FPS)" );
gl_allow_mirrors = Cvar_Get( "gl_allow_mirrors", "1", CVAR_ARCHIVE, "allow to draw mirror surfaces" );
gl_showtextures = Cvar_Get( "r_showtextures", "0", CVAR_CHEAT, "show all uploaded textures (type values from 1 to 13)" );
gl_finish = Cvar_Get( "gl_finish", "0", CVAR_ARCHIVE, "use glFinish instead of glFlush" );

View File

@ -594,6 +594,9 @@ void EmitWaterPolys( glpoly_t *polys, qboolean noCull )
// set the current waveheight
waveHeight = RI.currentWaveHeight;
// reset fog color for nonlightmapped water
GL_ResetFogColor();
for( p = polys; p; p = p->next )
{
pglBegin( GL_POLYGON );
@ -625,6 +628,8 @@ void EmitWaterPolys( glpoly_t *polys, qboolean noCull )
// restore culling
if( noCull ) pglEnable( GL_CULL_FACE );
GL_SetupFogColorForSurfaces();
}
/*

View File

@ -1741,9 +1741,9 @@ qboolean S_Init( void )
s_refdist = Cvar_Get( "s_refdist", "36", 0, "soundlevel reference distance" );
s_refdb = Cvar_Get( "s_refdb", "60", 0, "soundlevel refernce dB" );
snd_gain = Cvar_Get( "snd_gain", "1", 0, "sound default gain" );
s_cull = Cvar_Get( "s_cull", "1", CVAR_ARCHIVE, "cull sounds by geometry" );
s_cull = Cvar_Get( "s_cull", "0", CVAR_ARCHIVE, "cull sounds by geometry" );
s_test = Cvar_Get( "s_test", "0", 0, "engine developer cvar for quick testing new features" );
s_phs = Cvar_Get( "s_phs", "1", CVAR_ARCHIVE, "cull sounds by PHS" );
s_phs = Cvar_Get( "s_phs", "0", CVAR_ARCHIVE, "cull sounds by PHS" );
Cmd_AddCommand( "play", S_Play_f, "playing a specified sound file" );
Cmd_AddCommand( "stopsound", S_StopSound_f, "stop all sounds" );

View File

@ -624,6 +624,9 @@ cvar_t *pfnCvar_RegisterVariable( const char *szName, const char *szValue, int f
char *COM_MemFgets( byte *pMemFile, int fileSize, int *filePos, char *pBuffer, int bufferSize );
byte* COM_LoadFileForMe( const char *filename, int *pLength );
cvar_t *pfnCVarGetPointer( const char *szVarName );
int pfnDrawConsoleString( int x, int y, char *string );
void pfnDrawSetTextColor( float r, float g, float b );
void pfnDrawConsoleStringLen( const char *pText, int *length, int *height );
int pfnAddClientCommand( const char *cmd_name, xcommand_t func );
void *Cache_Check( byte *mempool, struct cache_user_s *c );
edict_t* pfnPEntityOfEntIndex( int iEntIndex );
@ -742,6 +745,7 @@ struct cl_entity_s *CL_GetEntityByIndex( int index );
struct cl_entity_s *CL_GetLocalPlayer( void );
struct player_info_s *CL_GetPlayerInfo( int playerIndex );
void SV_DrawDebugTriangles( void );
void SV_DrawOrthoTriangles( void );
qboolean UI_CreditsActive( void );
void CL_ExtraUpdate( void );
int CL_GetMaxClients( void );
@ -749,6 +753,8 @@ qboolean CL_IsPlaybackDemo( void );
qboolean CL_LoadProgs( const char *name );
qboolean SV_GetComment( const char *savename, char *comment );
qboolean SV_NewGame( const char *mapName, qboolean loadGame );
void SV_ClipPMoveToEntity( struct physent_s *pe, const vec3_t start, vec3_t mins, vec3_t maxs, const vec3_t end, struct pmtrace_s *tr );
void CL_ClipPMoveToEntity( struct physent_s *pe, const vec3_t start, vec3_t mins, vec3_t maxs, const vec3_t end, struct pmtrace_s *tr );
void SV_SysError( const char *error_string );
void SV_InitGameProgs( void );
void SV_FreeGameProgs( void );

View File

@ -673,6 +673,13 @@ void _Q_memset( void *dest, int set, size_t count, const char *filename, int fil
memset( dest, set, count );
}
int _Q_memcmp( const void *src0, const void *src1, size_t count, const char *filename, int fileline )
{
if( src0 == NULL ) Sys_Error( "memcmp: src1 == NULL (called at %s:%i)\n", filename, fileline );
if( src1 == NULL ) Sys_Error( "memcmp: src2 == NULL (called at %s:%i)\n", filename, fileline );
return memcmp( src0, src1, count );
}
void CRT_Init( void )
{
Memory_Init();

View File

@ -175,8 +175,10 @@ char *Q_pretifymem( float value, int digitsafterdecimal );
char *va( const char *format, ... );
#define Q_memcpy( dest, src, size ) _Q_memcpy( dest, src, size, __FILE__, __LINE__ )
#define Q_memset( dest, val, size ) _Q_memset( dest, val, size, __FILE__, __LINE__ )
#define Q_memcmp( src0, src1, siz ) _Q_memcmp( src0, src1, siz, __FILE__, __LINE__ )
void _Q_memset( void *dest, int set, size_t count, const char *filename, int fileline );
void _Q_memcpy( void *dest, const void *src, size_t count, const char *filename, int fileline );
int _Q_memcmp( const void *src0, const void *src1, size_t count, const char *filename, int fileline );
//
// zone.c

View File

@ -68,8 +68,8 @@ qboolean Image_LoadBMP( const char *name, const byte *buffer, size_t filesize )
// bogus info header check
if( bhdr.fileSize != filesize )
{
MsgDev( D_ERROR, "Image_LoadBMP: incorrect file size %i should be %i\n", filesize, bhdr.fileSize );
return false;
// 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 );
}
// bogus compression? Only non-compressed supported.

View File

@ -554,6 +554,8 @@ long IN_WndProc( void *hWnd, uint uMsg, uint wParam, long lParam )
// intentional fallthrough
case WM_KEYDOWN:
Key_Event( Host_MapKey( lParam ), true );
if( Host_MapKey( lParam ) == K_ALT )
return 0; // prevent WC_SYSMENU call
break;
case WM_SYSKEYUP:
case WM_KEYUP:

View File

@ -328,9 +328,18 @@ pmtrace_t PM_PlayerTraceExt( playermove_t *pmove, vec3_t start, vec3_t end, int
if(( flags & PM_GLASS_IGNORE ) && pe->rendermode != kRenderNormal )
continue;
if(( flags & PM_CUSTOM_IGNORE ) && pe->solid == SOLID_CUSTOM )
continue;
hullcount = 1;
if( !pe->model )
if( pe->solid == SOLID_CUSTOM )
{
VectorCopy( pmove->player_mins[pmove->usehull], mins );
VectorCopy( pmove->player_maxs[pmove->usehull], maxs );
VectorClear( offset );
}
else if( !pe->model )
{
if( !pe->studiomodel )
{
@ -414,6 +423,13 @@ pmtrace_t PM_PlayerTraceExt( playermove_t *pmove, vec3_t start, vec3_t end, int
// g-cont. probably this never happens
trace_bbox.allsolid = false;
}
else if( pe->solid == SOLID_CUSTOM )
{
// run custom sweep callback
if( pmove->server )
SV_ClipPMoveToEntity( pe, start, mins, maxs, end, &trace_bbox );
else CL_ClipPMoveToEntity( pe, start, mins, maxs, end, &trace_bbox );
}
else if( hullcount == 1 )
{
PM_RecursiveHullCheck( hull, hull->firstclipnode, 0, 1, start_l, end_l, &trace_bbox );
@ -424,7 +440,7 @@ pmtrace_t PM_PlayerTraceExt( playermove_t *pmove, vec3_t start, vec3_t end, int
for( last_hitgroup = 0, j = 0; j < hullcount; j++ )
{
Q_memset(&trace_hitbox, 0, sizeof( trace_hitbox ));
Q_memset( &trace_hitbox, 0, sizeof( trace_hitbox ));
VectorCopy( end, trace_hitbox.endpos );
trace_hitbox.allsolid = true;
trace_hitbox.fraction = 1.0f;
@ -506,7 +522,13 @@ int PM_TestPlayerPosition( playermove_t *pmove, vec3_t pos, pmtrace_t *ptrace, p
hullcount = 1;
if( pe->model )
if( pe->solid == SOLID_CUSTOM )
{
VectorCopy( pmove->player_mins[pmove->usehull], mins );
VectorCopy( pmove->player_maxs[pmove->usehull], maxs );
VectorClear( offset );
}
else if( pe->model )
{
hull = PM_HullForBsp( pe, pmove, offset );
}
@ -558,7 +580,25 @@ int PM_TestPlayerPosition( playermove_t *pmove, vec3_t pos, pmtrace_t *ptrace, p
VectorSubtract( pos, offset, pos_l );
}
if( hullcount == 1 )
if( pe->solid == SOLID_CUSTOM )
{
pmtrace_t trace;
Q_memset( &trace, 0, sizeof( trace ));
VectorCopy( pos, trace.endpos );
trace.allsolid = true;
trace.fraction = 1.0f;
// run custom sweep callback
if( pmove->server )
SV_ClipPMoveToEntity( pe, pos, mins, maxs, pos, &trace );
else CL_ClipPMoveToEntity( pe, pos, mins, maxs, pos, &trace );
// if we inside the custom hull
if( trace.allsolid )
return i;
}
else if( hullcount == 1 )
{
if( PM_HullPointContents( hull, hull->firstclipnode, pos_l ) == CONTENTS_SOLID )
return i;

View File

@ -42,15 +42,20 @@ typedef struct server_physics_api_s
void ( *pfnLinkEdict) ( edict_t *ent, qboolean touch_triggers );
double ( *pfnGetServerTime )( void ); // unclamped
double ( *pfnGetFrameTime )( void ); // unclamped
void* ( *pfnGetModel)( int modelindex );
areanode_t* ( *pfnGetHeadnode)( void ); // BSP tree for all physic entities
int ( *pfnServerState)( void );
void ( *pfnHost_Error)( const char *error, ... ); // cause Host Error
void* ( *pfnGetModel )( int modelindex );
areanode_t* ( *pfnGetHeadnode )( void ); // BSP tree for all physic entities
int ( *pfnServerState )( void );
void ( *pfnHost_Error )( const char *error, ... ); // cause Host Error
// ONLY ADD NEW FUNCTIONS TO THE END OF THIS STRUCT. INTERFACE VERSION IS FROZEN AT 6
struct triangleapi_s *pTriAPI; // draw coliisions etc. Only for local system
// draw debug messages (must be called from DrawOrthoTriangles). Only for local system
int ( *pfnDrawConsoleString )( int x, int y, char *string );
void ( *pfnDrawSetTextColor )( float r, float g, float b );
void ( *pfnDrawConsoleStringLen )( const char *string, int *length, int *height );
void ( *Con_NPrintf )( int pos, char *fmt, ... );
void ( *Con_NXPrintf )( struct con_nprint_s *info, char *fmt, ... );
} server_physics_api_t;
// ONLY ADD NEW FUNCTIONS TO THE END OF THIS STRUCT. INTERFACE VERSION IS FROZEN AT 6
// physic callbacks
typedef struct physics_interface_s
@ -66,14 +71,21 @@ typedef struct physics_interface_s
void ( *SV_UpdatePlayerBaseVelocity )( edict_t *ent );
// The game .dll should return 1 if save game should be allowed
int ( *SV_AllowSaveGame )( void );
// ONLY ADD NEW FUNCTIONS TO THE END OF THIS STRUCT. INTERFACE VERSION IS FROZEN AT 6
// override trigger area checking and touching
int ( *SV_TriggerTouch )( edict_t *pent, edict_t *trigger );
// some engine features can be enabled only through this function
unsigned int ( *SV_CheckFeatures )( void );
// used for draw debug collisions for custom physic engine etc
void ( *DrawDebugTriangles)( void );
void ( *DrawDebugTriangles )( void );
// used for draw debug overlay (textured)
void ( *DrawNormalTriangles)( void );
void ( *DrawNormalTriangles )( void );
// used for draw debug messages (2d mode)
void ( *DrawOrthoTriangles )( void );
// tracing entities with SOLID_CUSTOM mode on a server (not used by pmove code)
void ( *ClipMoveToEntity)( edict_t *ent, const float *start, float *mins, float *maxs, const float *end, trace_t *trace );
// tracing entities with SOLID_CUSTOM mode on a server (only used by pmove code)
void ( *ClipPMoveToEntity)( struct physent_s *pe, const float *start, float *mins, float *maxs, const float *end, struct pmtrace_s *tr );
} physics_interface_t;
#endif//PHYSINT_H

View File

@ -411,7 +411,6 @@ extern convar_t *sv_allow_upload;
extern convar_t *sv_allow_download;
extern convar_t *sv_allow_studio_attachment_angles;
extern convar_t *sv_allow_rotate_pushables;
extern convar_t *sv_fix_pushstep;
extern convar_t *sv_clienttrace;
extern convar_t *sv_send_resources;
extern convar_t *sv_send_logos;
@ -613,6 +612,7 @@ void SV_ClearWorld( void );
void SV_UnlinkEdict( edict_t *ent );
qboolean SV_HeadnodeVisible( mnode_t *node, byte *visbits, int *lastleaf );
void SV_ClipMoveToEntity( edict_t *ent, const vec3_t start, vec3_t mins, vec3_t maxs, const vec3_t end, trace_t *trace );
void SV_CustomClipMoveToEntity( edict_t *ent, const vec3_t start, vec3_t mins, vec3_t maxs, const vec3_t end, trace_t *trace );
trace_t SV_TraceHull( edict_t *ent, int hullNum, const vec3_t start, vec3_t mins, vec3_t maxs, const vec3_t end );
trace_t SV_Move( const vec3_t start, vec3_t mins, vec3_t maxs, const vec3_t end, int type, edict_t *e );
trace_t SV_MoveNoEnts( const vec3_t start, vec3_t mins, vec3_t maxs, const vec3_t end, int type, edict_t *e );

View File

@ -245,6 +245,32 @@ gotnewcl:
svs.last_heartbeat = MAX_HEARTBEAT;
}
/*
==================
SV_DisconnectClient
Disconnect client callback
==================
*/
void SV_DisconnectClient( edict_t *pClient )
{
if( !pClient ) return;
// don't send to other clients
pClient->v.modelindex = 0;
if( pClient->pvPrivateData != NULL )
{
// NOTE: new interface can be missing
if( svgame.dllFuncs2.pfnOnFreeEntPrivateData != NULL )
svgame.dllFuncs2.pfnOnFreeEntPrivateData( pClient );
// clear any dlls data but keep engine data
Mem_Free( pClient->pvPrivateData );
pClient->pvPrivateData = NULL;
}
}
/*
==================
SV_FakeConnect
@ -380,20 +406,7 @@ void SV_DropClient( sv_client_t *drop )
}
// let the game known about client state
svgame.dllFuncs.pfnClientDisconnect( drop->edict );
// don't send to other clients
drop->edict->v.modelindex = 0;
if( drop->edict->pvPrivateData )
{
// NOTE: new interface can be missing
if( svgame.dllFuncs2.pfnOnFreeEntPrivateData )
svgame.dllFuncs2.pfnOnFreeEntPrivateData( drop->edict );
// clear any dlls data but keep engine data
Mem_Free( drop->edict->pvPrivateData );
drop->edict->pvPrivateData = NULL;
}
SV_DisconnectClient( drop->edict );
drop->fakeclient = false;
drop->hltv_proxy = false;
@ -2054,7 +2067,8 @@ static void SV_ParseClientMove( sv_client_t *cl, sizebuf_t *msg )
}
else
{
VectorCopy( cmds[0].viewangles, player->v.v_angle );
if( !player->v.fixangle )
VectorCopy( cmds[0].viewangles, player->v.v_angle );
}
player->v.button = cmds[0].buttons;

View File

@ -454,9 +454,26 @@ void SV_ChangeLevel_f( void )
}
}
// bad changelevel position invoke enables in one-way transtion
if( sv.net_framenum < 15 )
{
if( sv_validate_changelevel->integer )
{
MsgDev( D_INFO, "SV_ChangeLevel: a infinite changelevel detected.\n" );
MsgDev( D_INFO, "Changelevel will be disabled until a next save\\restore.\n" );
return; // lock with svs.spawncount here
}
}
if( sv.state != ss_active )
{
MsgDev( D_INFO, "Only the server may changelevel\n" );
return;
}
SCR_BeginLoadingPlaque( false );
if( sv.state != ss_active || sv.background )
if( sv.background )
{
// just load map
Cbuf_AddText( va( "map %s\n", mapname ));

View File

@ -1172,7 +1172,7 @@ void pfnChangeLevel( const char* s1, const char* s2 )
if( svs.changelevel_next_time > host.realtime )
return;
svs.changelevel_next_time = host.realtime + 0.5f; // rest 1 secs if failed
svs.changelevel_next_time = host.realtime + 0.5f; // rest 0.5f secs if failed
// make sure we don't issue two changelevels
if( svs.spawncount == last_spawncount )
@ -2127,7 +2127,13 @@ static void pfnTraceModel( const float *v1, const float *v2, int hullNumber, edi
mins = sv.worldmodel->hulls[hullNumber].clip_mins;
maxs = sv.worldmodel->hulls[hullNumber].clip_maxs;
if( Mod_GetType( pent->v.modelindex ) == mod_brush )
if( pent->v.solid == SOLID_CUSTOM )
{
// NOTE: always goes through custom clipping move
// even if our callbacks is not initialized
SV_CustomClipMoveToEntity( pent, v1, mins, maxs, v2, &trace );
}
else if( Mod_GetType( pent->v.modelindex ) == mod_brush )
{
int oldmovetype = pent->v.movetype;
int oldsolid = pent->v.solid;
@ -3602,7 +3608,8 @@ void SV_PlaybackEventFull( int flags, const edict_t *pInvoker, word eventindex,
if( SV_IsValidEdict( pInvoker ))
{
VectorCopy( pInvoker->v.origin, pvspoint );
// add the view_ofs to avoid problems with crossed contents line
VectorAdd( pInvoker->v.origin, pInvoker->v.view_ofs, pvspoint );
args.entindex = invokerIndex = NUM_FOR_EDICT( pInvoker );
// g-cont. allow 'ducking' param for all entities

View File

@ -625,7 +625,6 @@ void SV_InitGame( void )
svgame.globals->maxClients = sv_maxclients->integer;
SV_UPDATE_BACKUP = ( svgame.globals->maxClients == 1 ) ? SINGLEPLAYER_BACKUP : MULTIPLAYER_BACKUP;
svs.spawncount = Com_RandomLong( 0, 65535 );
svs.clients = Z_Malloc( sizeof( sv_client_t ) * sv_maxclients->integer );
svs.num_client_entities = sv_maxclients->integer * SV_UPDATE_BACKUP * 64;
svs.packet_entities = Z_Malloc( sizeof( entity_state_t ) * svs.num_client_entities );

View File

@ -64,7 +64,6 @@ convar_t *sv_send_resources;
convar_t *sv_send_logos;
convar_t *sv_sendvelocity;
convar_t *sv_airmove;
convar_t *sv_fix_pushstep;
convar_t *sv_quakehulls;
convar_t *mp_consistency;
convar_t *serverinfo;
@ -711,7 +710,6 @@ void SV_Init( void )
sv_send_logos = Cvar_Get( "sv_send_logos", "1", 0, "send custom player decals to other clients" );
sv_send_resources = Cvar_Get( "sv_send_resources", "1", 0, "send generic resources that specified in 'mapname.res'" );
sv_sendvelocity = Cvar_Get( "sv_sendvelocity", "1", CVAR_ARCHIVE, "force to send velocity for event_t structure across network" );
sv_fix_pushstep = Cvar_Get( "sv_fix_pushstep", "0", CVAR_ARCHIVE, "allow the 'func_pushable' push the clients which standing on when the entity is floating in water" );
sv_quakehulls = Cvar_Get( "sv_quakehulls", "0", CVAR_ARCHIVE, "using quake style hull select instead of half-life style hull select" );
mp_consistency = Cvar_Get( "mp_consistency", "1", CVAR_SERVERNOTIFY, "enbale consistency check in multiplayer" );
clockwindow = Cvar_Get( "clockwindow", "0.5", 0, "timewindow to execute client moves" );
@ -778,7 +776,7 @@ before Sys_Quit or Sys_Error
void SV_Shutdown( qboolean reconnect )
{
// already freed
if( !SV_Active()) return;
if( !SV_Active( )) return;
if( host.type == HOST_DEDICATED ) MsgDev( D_INFO, "SV_Shutdown: %s\n", host.finalmsg );
if( svs.clients ) SV_FinalMessage( host.finalmsg, reconnect );

View File

@ -110,7 +110,8 @@ void SV_WaterMove( edict_t *ent )
return;
}
if( ent->v.health <= 0.0f )
// no watermove for monsters but pushables
if(( ent->v.flags & FL_MONSTER ) && ent->v.health <= 0.0f )
return;
drownlevel = (ent->v.deadflag == DEAD_NO) ? 3.0 : 1.0;

View File

@ -540,7 +540,7 @@ int SV_FlyMove( edict_t *ent, float time, trace_t *steptrace )
allFraction += trace.fraction;
if( trace.allsolid )
if( trace.startsolid )
{
// entity is trapped in another solid
VectorClear( ent->v.velocity );
@ -663,7 +663,7 @@ void SV_AddGravity( edict_t *ent )
else ent_gravity = 1.0f;
// add gravity incorrectly
ent->v.velocity[2] -= (ent_gravity * sv_gravity->value * host.frametime );
ent->v.velocity[2] -= ( ent_gravity * sv_gravity->value * host.frametime );
ent->v.velocity[2] += ent->v.basevelocity[2] * host.frametime;
ent->v.basevelocity[2] = 0.0f;
@ -731,10 +731,9 @@ Does not change the entities velocity at all
*/
trace_t SV_PushEntity( edict_t *ent, const vec3_t lpush, const vec3_t apush, int *blocked )
{
trace_t trace;
sv_client_t *cl;
int type;
vec3_t end;
trace_t trace;
int type;
vec3_t end;
VectorAdd( ent->v.origin, lpush, end );
@ -750,7 +749,7 @@ trace_t SV_PushEntity( edict_t *ent, const vec3_t lpush, const vec3_t apush, int
{
VectorCopy( trace.endpos, ent->v.origin );
if( apush[YAW] && ent->v.flags & FL_CLIENT && ( cl = SV_ClientFromEdict( ent, true )) != NULL )
if( apush[YAW] && ( ent->v.flags & FL_CLIENT ))
{
ent->v.avelocity[1] += apush[1];
ent->v.fixangle = 2;
@ -803,17 +802,25 @@ allow entity to block pusher?
*/
static qboolean SV_CanBlock( edict_t *ent )
{
if( ent->v.solid == SOLID_NOT || ent->v.solid == SOLID_TRIGGER )
return false;
if( ent->v.mins[0] == ent->v.maxs[0] )
return false;
// deadbody
if( ent->v.solid == SOLID_NOT || ent->v.solid == SOLID_TRIGGER )
{
ent->v.mins[0] = ent->v.mins[1] = 0;
ent->v.maxs[0] = ent->v.maxs[1] = 0;
ent->v.maxs[2] = ent->v.mins[2];
return false;
}
#if 0 // deadbody
if( ent->v.deadflag >= DEAD_DEAD )
return false;
// point entities never block push
if( VectorCompare( ent->v.mins, ent->v.maxs ))
return false;
#endif
return true;
}
@ -1486,7 +1493,6 @@ This is also used for objects that have become still on the ground, but
will fall if the floor is pulled out from under them.
=============
*/
#if 1
void SV_Physics_Step( edict_t *ent )
{
qboolean inwater;
@ -1504,7 +1510,7 @@ void SV_Physics_Step( edict_t *ent )
if( ent->v.flags & FL_FLOAT && ent->v.waterlevel > 0 )
{
float buoyancy = SV_Submerged( ent ) * ent->v.skin * host.frametime;
float buoyancy = SV_Submerged( ent ) * ent->v.skin * host.frametime;
SV_AddGravity( ent );
ent->v.velocity[2] += buoyancy;
@ -1535,9 +1541,7 @@ void SV_Physics_Step( edict_t *ent )
control = (speed < sv_stopspeed->value) ? sv_stopspeed->value : speed;
newspeed = speed - (host.frametime * control * friction);
if( newspeed < 0 )
newspeed = 0;
if( newspeed < 0 ) newspeed = 0;
newspeed /= speed;
vel[0] = vel[0] * newspeed;
@ -1604,194 +1608,6 @@ void SV_Physics_Step( edict_t *ent )
SV_CheckWaterTransition( ent );
}
#else
void SV_Physics_Step( edict_t *ent )
{
qboolean wasonground;
qboolean wasinwater;
qboolean inwater;
qboolean isfalling = false;
trace_t trace;
SV_CheckVelocity( ent );
wasonground = (ent->v.flags & FL_ONGROUND) ? true : false;
wasinwater = (ent->v.flags & FL_INWATER) ? true : false;
// add gravity except:
// flying monsters
// swimming monsters who are in the water
// pushables
inwater = SV_CheckWater( ent );
if( ent->v.movetype == MOVETYPE_PUSHSTEP )
{
if( wasinwater && !inwater )
ent->v.velocity[2] = 0.0f;
if( inwater && ( ent->v.flags & FL_FLOAT ))
{
vec3_t lmove;
int e, block;
edict_t *check;
ent->v.flags |= FL_INWATER;
VectorClear( lmove );
// floating pushables
if( ent->v.waterlevel >= 2 )
{
VectorScale( ent->v.velocity, 1.0f - (host.frametime * 0.5f), ent->v.velocity );
ent->v.velocity[2] += (ent->v.skin * host.frametime );
}
else if( ent->v.waterlevel == 0 )
{
}
else
{
ent->v.velocity[2] -= (ent->v.skin * host.frametime);
}
if( sv_fix_pushstep->integer )
{
lmove[2] = (ent->v.skin * host.frametime);
// push the clients to avoid sticking in float items
for( e = 1; e < svgame.globals->maxClients + 1; e++ )
{
check = EDICT_NUM( e );
if( !SV_IsValidEdict( check )) continue;
if(( check->v.flags & FL_ONGROUND ) && check->v.groundentity == ent )
{
SV_PushEntity( check, lmove, vec3_origin, &block );
check->v.groundentity = NULL;
check->v.flags &= ~FL_ONGROUND;
}
}
}
}
else if( !wasonground )
{
ent->v.flags &= ~FL_INWATER;
SV_AddGravity( ent );
}
}
else
{
// monster gravity
if( !wasonground )
{
if(!( ent->v.flags & FL_FLY ))
{
if(!( ent->v.flags & FL_SWIM && ent->v.waterlevel > 0 ))
{
if( !inwater )
{
SV_AddHalfGravity( ent, host.frametime );
isfalling = true;
}
}
}
}
}
if( !VectorIsNull( ent->v.velocity ) || !VectorIsNull( ent->v.basevelocity ))
{
vec3_t mins, maxs, point;
float friction = sv_friction->value;
int x, y;
friction *= ent->v.friction;
ent->v.flags &= ~FL_ONGROUND;
// apply friction
// let dead monsters who aren't completely onground slide
if( wasonground )
{
float speed, newspeed;
float *vel, control;
vel = ent->v.velocity;
speed = sqrt( vel[0] * vel[0] + vel[1] * vel[1] );
// add ground speed
if( ent->v.groundentity )
{
if( ent->v.groundentity->v.flags & FL_CONVEYOR )
speed += ent->v.groundentity->v.speed;
}
if( speed )
{
control = speed < sv_stopspeed->value ? sv_stopspeed->value : speed;
newspeed = speed - host.frametime * control * friction;
if( newspeed < 0.0f )
newspeed = 0.0f;
newspeed /= speed;
ent->v.velocity[0] *= newspeed;
ent->v.velocity[1] *= newspeed;
}
}
VectorAdd( ent->v.velocity, ent->v.basevelocity, ent->v.velocity );
SV_FlyMove( ent, host.frametime, NULL );
VectorSubtract( ent->v.velocity, ent->v.basevelocity, ent->v.velocity );
SV_CheckVelocity( ent );
// determine if it's on solid ground at all
VectorAdd( ent->v.origin, ent->v.mins, mins );
VectorAdd( ent->v.origin, ent->v.maxs, maxs );
point[2] = mins[2] - 1;
for( x = 0; x <= 1; x++ )
{
if( ent->v.flags & FL_ONGROUND )
break;
for( y = 0; y <= 1; y++ )
{
point[0] = x ? maxs[0] : mins[0];
point[1] = y ? maxs[1] : mins[1];
trace = SV_Move( point, vec3_origin, vec3_origin, point, MOVE_NORMAL, ent );
if( trace.startsolid )
{
ent->v.flags |= FL_ONGROUND;
ent->v.groundentity = trace.ent;
ent->v.friction = 1.0f;
break;
}
}
}
SV_LinkEdict( ent, true );
}
else
{
if( svgame.globals->force_retouch != 0.0f )
{
trace = SV_Move(ent->v.origin, ent->v.mins, ent->v.maxs, ent->v.origin, MOVE_NORMAL, ent );
if(( trace.fraction < 1.0f || trace.startsolid ) && SV_IsValidEdict( trace.ent ))
SV_Impact( ent, trace.ent, &trace );
}
}
if(!( ent->v.flags & FL_ONGROUND ) && isfalling )
{
SV_AddHalfGravity( ent, host.frametime );
}
if( !SV_RunThink( ent )) return;
SV_CheckWaterTransition( ent );
}
#endif
/*
=============
@ -1983,6 +1799,7 @@ void SV_DrawDebugTriangles( void )
if( svgame.physFuncs.DrawDebugTriangles != NULL )
{
// debug draws only
pglDisable( GL_BLEND );
pglDepthMask( GL_FALSE );
pglDisable( GL_TEXTURE_2D );
@ -1991,6 +1808,26 @@ void SV_DrawDebugTriangles( void )
pglEnable( GL_TEXTURE_2D );
pglDepthMask( GL_TRUE );
pglEnable( GL_BLEND );
}
}
/*
================
SV_DrawOrthoTriangles
Called from renderer for debug purposes
================
*/
void SV_DrawOrthoTriangles( void )
{
if( host.type != HOST_NORMAL )
return;
if( svgame.physFuncs.DrawOrthoTriangles != NULL )
{
// draw solid overlay
svgame.physFuncs.DrawOrthoTriangles ();
}
}
@ -2004,6 +1841,11 @@ static server_physics_api_t gPhysicsAPI =
SV_ServerState,
Host_Error,
&gTriApi, // ouch!
pfnDrawConsoleString,
pfnDrawSetTextColor,
pfnDrawConsoleStringLen,
Con_NPrintf,
Con_NXPrintf,
};
/*

View File

@ -37,6 +37,22 @@ void SV_ConvertPMTrace( trace_t *out, pmtrace_t *in, edict_t *ent )
out->ent = ent;
}
void SV_ClipPMoveToEntity( physent_t *pe, const vec3_t start, vec3_t mins, vec3_t maxs, const vec3_t end, pmtrace_t *tr )
{
ASSERT( tr != NULL );
if( svgame.physFuncs.ClipPMoveToEntity != NULL )
{
// do custom sweep test
svgame.physFuncs.ClipPMoveToEntity( pe, start, mins, maxs, end, tr );
}
else
{
// function is missed, so we didn't hit anything
tr->allsolid = false;
}
}
qboolean SV_CopyEdictToPhysEnt( physent_t *pe, edict_t *ed )
{
model_t *mod = Mod_Handle( ed->v.modelindex );
@ -77,6 +93,12 @@ qboolean SV_CopyEdictToPhysEnt( physent_t *pe, edict_t *ed )
VectorCopy( ed->v.mins, pe->mins );
VectorCopy( ed->v.maxs, pe->maxs );
break;
case SOLID_CUSTOM:
pe->model = (mod->type == mod_brush) ? mod : NULL;
pe->studiomodel = (mod->type == mod_studio) ? mod : NULL;
VectorCopy( ed->v.mins, pe->mins );
VectorCopy( ed->v.maxs, pe->maxs );
break;
default:
pe->studiomodel = (mod->type == mod_studio) ? mod : NULL;
VectorCopy( ed->v.mins, pe->mins );
@ -192,7 +214,7 @@ void SV_AddLinksToPmove( areanode_t *node, const vec3_t pmove_mins, const vec3_t
svgame.pmove->numvisent++;
}
if( check->v.solid == SOLID_NOT && ( check->v.skin == 0 || check->v.modelindex == 0 ))
if( check->v.solid == SOLID_NOT && ( check->v.skin == CONTENTS_NONE || check->v.modelindex == 0 ))
continue;
// ignore monsterclip brushes
@ -204,13 +226,17 @@ void SV_AddLinksToPmove( areanode_t *node, const vec3_t pmove_mins, const vec3_t
if((( check->v.flags & FL_CLIENT ) && check->v.health <= 0 ) || check->v.deadflag == DEAD_DEAD )
continue; // dead body
if( VectorIsNull( check->v.size )) continue;
if( VectorIsNull( check->v.size ))
continue;
VectorCopy( check->v.absmin, mins );
VectorCopy( check->v.absmax, maxs );
if( check->v.flags & FL_CLIENT )
SV_GetTrueMinMax( svs.currentPlayer, ( NUM_FOR_EDICT( check ) - 1), mins, maxs ); // try to get interpolated values
{
// trying to get interpolated values
SV_GetTrueMinMax( svs.currentPlayer, ( NUM_FOR_EDICT( check ) - 1), mins, maxs );
}
if( !BoundsIntersect( pmove_mins, pmove_maxs, mins, maxs ))
continue;

View File

@ -2161,7 +2161,7 @@ void SV_SaveGame( const char *pName )
for( n = 0; n < 999; n++ )
{
SV_SaveGetName( n, savename );
if( !FS_FileExists( va( "save/%s.sav", savename ), false ))
if( !FS_FileExists( va( "save/%s.sav", savename ), true ))
break;
}
if( n == 1000 )
@ -2213,7 +2213,7 @@ const char *SV_GetLatestSave( void )
for( i = 0; i < f->numfilenames; i++ )
{
ft = FS_FileTime( f->filenames[i], false );
ft = FS_FileTime( f->filenames[i], true );
// found a match?
if( ft > 0 )

View File

@ -485,7 +485,7 @@ void SV_TouchLinks( edict_t *ent, areanode_t *node )
hull = SV_HullForBsp( touch, ent->v.mins, ent->v.maxs, offset );
// support for rotational triggers
if( (mod->flags & MODEL_HAS_ORIGIN) && !VectorIsNull( touch->v.angles ))
if(( mod->flags & MODEL_HAS_ORIGIN ) && !VectorIsNull( touch->v.angles ))
{
matrix4x4 matrix;
Matrix4x4_CreateFromEntity( matrix, touch->v.angles, offset, 1.0f );
@ -1071,6 +1071,33 @@ void SV_ClipMoveToEntity( edict_t *ent, const vec3_t start, vec3_t mins, vec3_t
trace->ent = ent;
}
/*
==================
SV_CustomClipMoveToEntity
A part of physics engine implementation
or custom physics implementation
==================
*/
void SV_CustomClipMoveToEntity( edict_t *ent, const vec3_t start, vec3_t mins, vec3_t maxs, const vec3_t end, trace_t *trace )
{
Q_memset( trace, 0, sizeof( trace_t ));
VectorCopy( end, trace->endpos );
trace->allsolid = true;
trace->fraction = 1.0f;
if( svgame.physFuncs.ClipMoveToEntity != NULL )
{
// do custom sweep test
svgame.physFuncs.ClipMoveToEntity( ent, start, mins, maxs, end, trace );
}
else
{
// function is missed, so we didn't hit anything
trace->allsolid = false;
}
}
/*
====================
SV_ClipToLinks
@ -1169,6 +1196,8 @@ static void SV_ClipToLinks( areanode_t *node, moveclip_t *clip )
if( touch->v.flags & FL_MONSTER )
SV_ClipMoveToEntity( touch, clip->start, clip->mins2, clip->maxs2, clip->end, &trace );
else if( touch->v.solid == SOLID_CUSTOM )
SV_CustomClipMoveToEntity( touch, clip->start, clip->mins, clip->maxs, clip->end, &trace );
else SV_ClipMoveToEntity( touch, clip->start, clip->mins, clip->maxs, clip->end, &trace );
clip->trace = World_CombineTraces( &clip->trace, &trace, touch );

View File

@ -266,6 +266,10 @@ void UI_DrawString( int x, int y, int w, int h, const char *string, const int co
ch = *l++;
ch &= 255;
// fix for letter ¸
if( ch == '¸' ) ch = 'å';
if( ch == '¨' ) ch = 'Å';
if( ch != ' ' )
{
if( shadow ) TextMessageDrawChar( xx + ofsX, yy + ofsY, charW, charH, ch, shadowModulate, uiStatic.hFont );

View File

@ -146,7 +146,8 @@ void UI_LoadBmpButtons( void )
uiStatic.buttons_height = ( pInfoHdr->biBitCount == 4 ) ? 80 : 78; // bugstompers issues
uiStatic.buttons_width = pInfoHdr->biWidth - 3; // make some offset
int cutted_img_sz = pInfoHdr->biWidth * uiStatic.buttons_height * pInfoHdr->biBitCount / 8;
int stride = (pInfoHdr->biWidth * pInfoHdr->biBitCount / 8);
int cutted_img_sz = ((stride + 3 ) & ~3) * uiStatic.buttons_height;
int CuttedBmpSize = sizeof( bmphdr_t ) + pInfoHdr->biSize + pallete_sz + cutted_img_sz;
byte *img_data = &bmp_buffer[bmp_len_holder-cutted_img_sz];

View File

@ -41,8 +41,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#define MAX_MODS 512 // engine limit
#define TYPE_LENGTH 16
#define NAME_SPACE 4
#define NAME_LENGTH 32+TYPE_LENGTH
#define VER_LENGTH 10+NAME_LENGTH
#define VER_LENGTH 6+NAME_LENGTH
#define SIZE_LENGTH 10+VER_LENGTH
typedef struct
@ -136,7 +137,14 @@ static void UI_CustomGame_GetModList( void )
if( strlen( games[i]->type ))
StringConcat( uiCustomGame.modsDescription[i], games[i]->type, TYPE_LENGTH );
StringConcat( uiCustomGame.modsDescription[i], uiEmptyString, TYPE_LENGTH );
StringConcat( uiCustomGame.modsDescription[i], games[i]->title, NAME_LENGTH );
if( ColorStrlen( games[i]->title ) > 31 ) // NAME_LENGTH
{
StringConcat( uiCustomGame.modsDescription[i], games[i]->title, ( NAME_LENGTH - NAME_SPACE ));
StringConcat( uiCustomGame.modsDescription[i], "...", NAME_LENGTH );
}
else StringConcat( uiCustomGame.modsDescription[i], games[i]->title, NAME_LENGTH );
StringConcat( uiCustomGame.modsDescription[i], uiEmptyString, NAME_LENGTH );
StringConcat( uiCustomGame.modsDescription[i], games[i]->version, VER_LENGTH );
StringConcat( uiCustomGame.modsDescription[i], uiEmptyString, VER_LENGTH );

View File

@ -734,6 +734,9 @@ void UI_ScrollList_Draw( menuScrollList_s *sl )
h = sl->generic.charHeight;
y = sl->generic.y2 + sl->generic.charHeight;
// prevent the columns out of rectangle bounds
PIC_EnableScissor( x, y, sl->generic.width - arrowWidth - uiStatic.outlineWidth, sl->generic.height );
for( i = sl->topItem; i < sl->topItem + sl->numRows; i++, y += sl->generic.charHeight )
{
if( !sl->itemNames[i] )
@ -768,6 +771,8 @@ void UI_ScrollList_Draw( menuScrollList_s *sl )
if( sl->generic.flags & QMF_FOCUSBEHIND )
UI_DrawString( x, y, w, h, sl->itemNames[i], sl->generic.color, false, sl->generic.charWidth, sl->generic.charHeight, justify, shadow );
}
PIC_DisableScissor();
}
/*
@ -2092,7 +2097,6 @@ const char *UI_PicButton_Key( menuPicButton_s *b, int key, int down )
break;
case K_ENTER:
case K_KP_ENTER:
if( !down ) return sound;
if( b->generic.flags & QMF_MOUSEONLY )
break;
sound = uiSoundLaunch;

View File

@ -25,6 +25,7 @@
#define PM_STUDIO_BOX 0x00000002 // Use boxes for non-complex studio models (even in traceline)
#define PM_GLASS_IGNORE 0x00000004 // Ignore entities with non-normal rendermode
#define PM_WORLD_ONLY 0x00000008 // Only trace against the world
#define PM_CUSTOM_IGNORE 0x00000010 // Ignore entities with SOLID_CUSTOM mode
// Values for flags parameter of PM_TraceLine
#define PM_TRACELINE_PHYSENTSONLY 0

View File

@ -1698,9 +1698,7 @@ int PM_CheckStuck (void)
PM_ResetStuckOffsets( pmove->player_index, pmove->server );
if (i >= 27)
VectorCopy ( test, pmove->origin );
VectorCopy ( test, pmove->origin );
return 0;
}