22 Feb 2017

This commit is contained in:
g-cont 2017-02-22 00:00:00 +03:00 committed by Alibek Omarov
parent 8eb9c6570d
commit 32e6ad398f
60 changed files with 8318 additions and 4351 deletions

View File

@ -28,8 +28,7 @@ typedef enum
pt_blob2,
pt_vox_slowgrav,
pt_vox_grav,
pt_clientcustom, // Must have callback function specified
pt_tracer // Always have callback
pt_clientcustom // Must have callback function specified
} ptype_t;
typedef struct particle_s

View File

@ -68,8 +68,6 @@ typedef struct ref_params_s
int nextView; // the renderer calls ClientDLL_CalcRefdef() and Renderview
// so long in cycles until this value is 0 (multiple views)
int onlyClientDraw; // if !=0 nothing is drawn by the engine except clientDraw functions
// Xash3D extension
float fov_x, fov_y; // actual fov can be overrided on nextView
} ref_params_t;
// same as ref_params but for overview mode
@ -87,4 +85,21 @@ typedef struct ref_overview_s
float flZoom;
} ref_overview_t;
// ref_viewpass_t->flags
#define RF_DRAW_WORLD (1<<0) // pass should draw the world (otherwise it's player menu model)
#define RF_DRAW_CUBEMAP (1<<1) // special 6x pass to render cubemap\skybox sides
#define RF_DRAW_OVERVIEW (1<<2) // overview mode is active
#define RF_ONLY_CLIENTDRAW (1<<3) // nothing is drawn by the engine except clientDraw functions
// intermediate struct for viewpass (or just a single frame)
typedef struct ref_viewpass_s
{
int viewport[4]; // size of new viewport
vec3_t vieworigin; // view origin
vec3_t viewangles; // view angles
int viewentity; // entitynum (P2: Savior uses this)
float fov_x, fov_y; // vertical & horizontal FOV
int flags; // if !=0 nothing is drawn by the engine except clientDraw functions
} ref_viewpass_t;
#endif//REF_PARAMS_H

View File

@ -27,7 +27,7 @@ GNU General Public License for more details.
// move misc functions at end of the interface
// added new export for clearing studio decals
#define CL_RENDER_INTERFACE_VERSION 35
#define CL_RENDER_INTERFACE_VERSION 36
#define MAX_STUDIO_DECALS 4096 // + unused space of BSP decals
#define SURF_INFO( surf, mod ) ((mextrasurf_t *)mod->cache.data + (surf - mod->surfaces))
@ -118,7 +118,7 @@ typedef enum
{
CONTEXT_TYPE_GL = 0,
CONTEXT_TYPE_GLES_1_X,
CONTEXT_TYPE_GLES_2_x
CONTEXT_TYPE_GLES_2_X
} gl_context_type_t;
typedef enum
@ -238,7 +238,7 @@ typedef struct render_interface_s
{
int version;
// passed through R_RenderFrame (0 - use engine renderer, 1 - use custom client renderer)
int (*GL_RenderFrame)( const struct ref_params_s *pparams, qboolean drawWorld );
int (*GL_RenderFrame)( const struct ref_viewpass_s *rvp );
// build all the lightmaps on new level or when gamma is changed
void (*GL_BuildLightmaps)( void );
// setup map bounds for ortho-projection when we in dev_overview mode
@ -251,8 +251,6 @@ typedef struct render_interface_s
void (*R_ClearStudioDecals)( void );
// grab r_speeds message
qboolean (*R_SpeedsMessage)( char *out, size_t size );
// replace with built-in R_DrawCubemapView for make skyshots or envshots
qboolean (*R_DrawCubemapView)( const float *origin, const float *angles, int size );
// alloc or destroy model custom data
void (*Mod_ProcessUserData)( struct model_s *mod, qboolean create, const byte *buffer );
// alloc or destroy entity custom data

View File

@ -256,6 +256,7 @@ void CTripmineGrenade :: MakeBeam( void )
m_pBeam = CBeam::BeamCreate( g_pModelNameLaser, 10 );
m_pBeam->PointEntInit( vecTmpEnd, entindex() );
// m_pBeam->HoseInit( pev->origin, vecTmpEnd );
m_pBeam->SetColor( 0, 214, 198 );
m_pBeam->SetScrollRate( 255 );
m_pBeam->SetBrightness( 64 );

View File

@ -207,7 +207,7 @@ void CL_ScreenShot_f( void )
int i;
string checkname;
if( gl_overview->value == 1 )
if( CL_IsDevOverviewMode() == 1 )
{
// special case for write overview image and script file
Q_snprintf( cls.shotname, sizeof( cls.shotname ), "overviews/%s.bmp", clgame.mapname );
@ -245,7 +245,7 @@ void CL_SnapShot_f( void )
int i;
string checkname;
if( gl_overview->value == 1 )
if( CL_IsDevOverviewMode() == 1 )
{
// special case for write overview image and script file
Q_snprintf( cls.shotname, sizeof( cls.shotname ), "overviews/%s.bmp", clgame.mapname );
@ -455,24 +455,24 @@ void SCR_TimeRefresh_f( void )
start = Sys_DoubleTime();
if( Cmd_Argc() == 2 )
// run without page flipping like GoldSrc
if( Cmd_Argc() == 1 )
{
// run without page flipping
R_BeginFrame( false );
pglDrawBuffer( GL_FRONT );
for( i = 0; i < 128; i++ )
{
RI.viewangles[1] = i / 128.0 * 360.0f;
R_RenderScene();
}
pglFinish();
R_EndFrame();
}
else
{
for( i = 0; i < 128; i++ )
{
RI.viewangles[1] = i / 128.0 * 360.0f;
R_BeginFrame( true );
RI.viewangles[1] = i / 128.0 * 360.0f;
R_RenderScene();
R_EndFrame();
}

View File

@ -567,7 +567,7 @@ void CL_ReadDemoUserCmd( qboolean discard )
// record update
a->starttime = demo.timestamp;
VectorCopy( cl.viewangles, a->viewangles );
VectorCopy( cl.cmd->viewangles, a->viewangles );
demo.lasttime = demo.timestamp;
}

View File

@ -53,7 +53,7 @@ void CL_CalcPlayerVelocity( int idx, vec3_t velocity )
if( idx == cl.playernum + 1 )
{
pcd = &cl.frames[cl.parsecountmod].client;
pcd = &cl.frames[cl.parsecountmod].clientdata;
VectorCopy( pcd->velocity, velocity );
}
else
@ -424,9 +424,11 @@ void CL_ParseEvent( sizebuf_t *msg )
if( packet_index != -1 )
{
if( packet_index < cl.frames[cl.parsecountmod].num_entities )
frame_t *frame = &cl.frames[cl.parsecountmod];
if( packet_index < frame->num_entities )
{
state = &cls.packet_entities[(cl.frame.first_entity+packet_index)%cls.num_client_entities];
state = &cls.packet_entities[(frame->first_entity+packet_index)%cls.num_client_entities];
args.entindex = state->number;
if( VectorIsNull( args.origin ))

File diff suppressed because it is too large Load Diff

View File

@ -106,15 +106,12 @@ cl_entity_t *CL_GetEntityByIndex( int index )
if( !clgame.entities ) // not in game yet
return NULL;
if( index < 0 || index >= clgame.maxEntities )
return NULL;
if( index == 0 )
return cl.world;
if( index < 0 )
return clgame.dllFuncs.pfnGetUserEntity( abs( index ));
if( index >= clgame.maxEntities )
return NULL;
return CL_EDICT_NUM( index );
}
@ -834,19 +831,13 @@ Render crosshair
*/
void CL_DrawCrosshair( void )
{
int x, y, width, height;
cl_entity_t *pPlayer;
int x, y, width, height;
if( !clgame.ds.pCrosshair || cl.crosshairangle[2] || !cl_crosshair->value )
if( !clgame.ds.pCrosshair || !cl_crosshair->value )
return;
pPlayer = CL_GetLocalPlayer();
if( cl.frame.client.deadflag != DEAD_NO || cl.frame.client.flags & FL_FROZEN )
return;
// any camera on
if( cl.viewentity != pPlayer->index )
// any camera on or client is died
if( cl.local.health <= 0 || cl.viewentity != ( cl.playernum + 1 ))
return;
// get crosshair dimension
@ -864,7 +855,7 @@ void CL_DrawCrosshair( void )
vec3_t forward;
vec3_t point, screen;
VectorAdd( cl.viewangles, cl.crosshairangle, angles );
VectorAdd( RI.viewangles, cl.crosshairangle, angles );
AngleVectors( angles, forward, NULL, NULL );
VectorAdd( RI.vieworg, forward, point );
R_WorldToScreen( point, screen );
@ -1824,7 +1815,7 @@ value that come from server
*/
static float pfnGetClientMaxspeed( void )
{
return cl.frame.client.maxspeed;
return cl.local.maxspeed;
}
/*
@ -1871,11 +1862,7 @@ pfnIsNoClipping
*/
int pfnIsNoClipping( void )
{
cl_entity_t *pl = CL_GetLocalPlayer();
if( !pl ) return false;
return pl->curstate.movetype == MOVETYPE_NOCLIP;
return ( cl.frames[cl.parsecountmod].playerstate[cl.playernum].movetype == MOVETYPE_NOCLIP );
}
/*
@ -1928,8 +1915,8 @@ void pfnCalcShake( void )
// compute random shake extents (the shake will settle down from this)
for( i = 0; i < 3; i++ )
clgame.shake.offset[i] = Com_RandomFloat( -clgame.shake.amplitude, clgame.shake.amplitude );
clgame.shake.angle = Com_RandomFloat( -clgame.shake.amplitude * 0.25f, clgame.shake.amplitude * 0.25f );
clgame.shake.offset[i] = COM_RandomFloat( -clgame.shake.amplitude, clgame.shake.amplitude );
clgame.shake.angle = COM_RandomFloat( -clgame.shake.amplitude * 0.25f, clgame.shake.amplitude * 0.25f );
}
// ramp down amplitude over duration (fraction goes from 1 to 0 linearly with slope 1/duration)
@ -2888,27 +2875,29 @@ void TriRenderMode( int mode )
switch( mode )
{
case kRenderNormal:
default: pglDisable( GL_BLEND );
pglDisable( GL_ALPHA_TEST );
pglDisable( GL_BLEND );
pglDepthMask( GL_TRUE );
break;
case kRenderTransAlpha:
pglEnable( GL_BLEND );
pglTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
pglBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
pglDepthMask( GL_FALSE );
break;
case kRenderTransColor:
case kRenderTransAlpha:
case kRenderTransTexture:
// NOTE: TriAPI doesn't have 'solid' mode
pglEnable( GL_BLEND );
pglDisable( GL_ALPHA_TEST );
pglBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
pglTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
break;
case kRenderGlow:
case kRenderTransAdd:
pglBlendFunc( GL_ONE, GL_ONE );
pglEnable( GL_BLEND );
pglDisable( GL_ALPHA_TEST );
pglBlendFunc( GL_SRC_ALPHA, GL_ONE );
pglTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
pglDepthMask( GL_FALSE );
break;
}
clgame.ds.renderMode = mode;
}
/*
@ -2961,7 +2950,6 @@ draw triangle sequence
void TriEnd( void )
{
pglEnd();
pglDisable( GL_ALPHA_TEST );
}
/*
@ -2972,11 +2960,14 @@ TriColor4f
*/
void TriColor4f( float r, float g, float b, float a )
{
clgame.ds.triColor[0] = (byte)bound( 0, (r * 255.0f), 255 );
clgame.ds.triColor[1] = (byte)bound( 0, (g * 255.0f), 255 );
clgame.ds.triColor[2] = (byte)bound( 0, (b * 255.0f), 255 );
clgame.ds.triColor[3] = (byte)bound( 0, (a * 255.0f), 255 );
pglColor4ub( clgame.ds.triColor[0], clgame.ds.triColor[1], clgame.ds.triColor[2], clgame.ds.triColor[3] );
if( clgame.ds.renderMode == kRenderTransAlpha )
pglColor4ub( r * 255.9f, g * 255.9f, b * 255.9f, a * 255.0f );
else pglColor4f( r * a, g * a, b * a, 1.0 );
clgame.ds.triRGBA[0] = r;
clgame.ds.triRGBA[1] = g;
clgame.ds.triRGBA[2] = b;
clgame.ds.triRGBA[3] = a;
}
/*
@ -2987,11 +2978,12 @@ TriColor4ub
*/
void TriColor4ub( byte r, byte g, byte b, byte a )
{
clgame.ds.triColor[0] = r;
clgame.ds.triColor[1] = g;
clgame.ds.triColor[2] = b;
clgame.ds.triColor[3] = a;
pglColor4ub( r, g, b, a );
clgame.ds.triRGBA[0] = r * (1.0f / 255.0f);
clgame.ds.triRGBA[1] = g * (1.0f / 255.0f);
clgame.ds.triRGBA[2] = b * (1.0f / 255.0f);
clgame.ds.triRGBA[3] = a * (1.0f / 255.0f);
pglColor4f( clgame.ds.triRGBA[0], clgame.ds.triRGBA[1], clgame.ds.triRGBA[2], 1.0f );
}
/*
@ -3035,14 +3027,13 @@ TriBrightness
*/
void TriBrightness( float brightness )
{
rgba_t rgba;
float r, g, b;
brightness = max( 0.0f, brightness );
rgba[0] = clgame.ds.triColor[0] * brightness;
rgba[1] = clgame.ds.triColor[1] * brightness;
rgba[2] = clgame.ds.triColor[2] * brightness;
r = clgame.ds.triRGBA[0] * clgame.ds.triRGBA[3] * brightness;
g = clgame.ds.triRGBA[1] * clgame.ds.triRGBA[3] * brightness;
b = clgame.ds.triRGBA[2] * clgame.ds.triRGBA[3] * brightness;
pglColor4ub( rgba[0], rgba[1], rgba[2], clgame.ds.triColor[3] );
pglColor4f( r, g, b, 1.0f );
}
/*
@ -3051,7 +3042,7 @@ TriCullFace
=============
*/
void TriCullFace( TRICULLSTYLE mode )
void TriCullFace( int mode )
{
switch( mode )
{
@ -3075,23 +3066,12 @@ bind current texture
int TriSpriteTexture( model_t *pSpriteModel, int frame )
{
int gl_texturenum;
msprite_t *psprite;
if(( gl_texturenum = R_GetSpriteTexture( pSpriteModel, frame )) == 0 )
return 0;
if( gl_texturenum <= 0 || gl_texturenum > MAX_TEXTURES )
{
MsgDev( D_ERROR, "TriSpriteTexture: bad index %i\n", gl_texturenum );
gl_texturenum = tr.defaultTexture;
}
psprite = pSpriteModel->cache.data;
if( psprite->texFormat == SPR_ALPHTEST )
{
pglEnable( GL_ALPHA_TEST );
pglAlphaFunc( GL_GEQUAL, 0.5f );
}
GL_Bind( GL_TEXTURE0, gl_texturenum );
@ -3195,14 +3175,12 @@ void TriLightAtPoint( float *pos, float *value )
{
color24 ambient;
if( !pos || !value )
return;
if( !pos || !value ) return;
R_LightForPoint( pos, &ambient, false, false, 0.0f );
value[0] = (float)ambient.r * 255.0f;
value[1] = (float)ambient.g * 255.0f;
value[2] = (float)ambient.b * 255.0f;
value[0] = ambient.r;
value[1] = ambient.g;
value[2] = ambient.b;
}
/*
@ -3214,8 +3192,11 @@ Heavy legacy of Quake...
*/
void TriColor4fRendermode( float r, float g, float b, float a, int rendermode )
{
if( rendermode == kRenderTransAlpha )
if( clgame.ds.renderMode == kRenderTransAlpha )
{
clgame.ds.triRGBA[3] = a / 255.0f;
pglColor4f( r, g, b, a );
}
else pglColor4f( r * a, g * a, b * a, 1.0f );
}
@ -3298,6 +3279,23 @@ void NetAPI_InitNetworking( void )
NET_Config( true ); // allow remote
}
int Net_GetPacketLoss( void )
{
int packet_loss = 0;
if( cls.state == ca_active )
{
packet_loss = bound( 0, (int)cls.packet_loss, 100 );
if ( packet_loss < 0 )
packet_loss = 0;
if ( packet_loss > 100 )
packet_loss = 100;
}
return packet_loss;
}
/*
=================
NetAPI_InitNetworking
@ -3306,15 +3304,24 @@ NetAPI_InitNetworking
*/
void NetAPI_Status( net_status_t *status )
{
qboolean connected = false;
int packet_loss = 0;
ASSERT( status != NULL );
status->connected = NET_IsLocalAddress( cls.netchan.remote_address ) ? false : true;
status->connection_time = host.realtime - cls.netchan.connect_time;
if( cls.state > ca_disconnected && cls.state != ca_cinematic )
connected = true;
if( cls.state == ca_active )
packet_loss = bound( 0, (int)cls.packet_loss, 100 );
status->connected = connected;
status->connection_time = (connected) ? (host.realtime - cls.netchan.connect_time) : 0.0;
status->latency = (connected) ? cl.frames[cl.parsecountmod].latency : 0.0;
status->remote_address = cls.netchan.remote_address;
status->packet_loss = cls.packet_loss / 100.0; // percent
status->latency = cl.frame.latency;
status->packet_loss = packet_loss;
status->local_address = net_local;
status->rate = cls.netchan.rate;
status->rate = rate->value;
}
/*
@ -3615,7 +3622,7 @@ triangleapi_t gTriApi =
static efx_api_t gEfxApi =
{
CL_AllocParticle,
R_AllocParticle,
CL_BlobExplosion,
CL_Blood,
CL_BloodSprite,
@ -3623,14 +3630,14 @@ static efx_api_t gEfxApi =
CL_BreakModel,
CL_Bubbles,
CL_BubbleTrail,
CL_BulletImpactParticles,
R_BulletImpactParticles,
CL_EntityParticles,
CL_Explosion,
CL_FizzEffect,
CL_FireField,
CL_FlickerParticles,
CL_FunnelSprite,
CL_Implosion,
R_Implosion,
CL_Large_Funnel,
CL_LavaSplash,
CL_MultiGunshot,
@ -3646,21 +3653,21 @@ static efx_api_t gEfxApi =
CL_RicochetSprite,
CL_RocketFlare,
CL_RocketTrail,
CL_RunParticleEffect,
R_RunParticleEffect,
CL_ShowLine,
CL_SparkEffect,
CL_SparkShower,
CL_SparkStreaks,
R_SparkEffect,
R_SparkShower,
R_SparkStreaks,
CL_Spray,
CL_Sprite_Explode,
CL_Sprite_Smoke,
CL_Sprite_Spray,
CL_Sprite_Trail,
CL_Sprite_WallPuff,
CL_StreakSplash,
CL_TracerEffect,
CL_UserTracerParticle,
CL_TracerParticles,
R_StreakSplash,
R_TracerEffect,
R_UserTracerParticle,
R_TracerParticles,
CL_TeleportSplash,
CL_TempSphereModel,
CL_TempModel,
@ -3671,14 +3678,14 @@ static efx_api_t gEfxApi =
CL_DecalShoot,
CL_AttachTentToPlayer,
CL_KillAttachedTents,
CL_BeamCirclePoints,
CL_BeamEntPoint,
CL_BeamEnts,
CL_BeamFollow,
CL_BeamKill,
CL_BeamLightning,
CL_BeamPoints,
CL_BeamRing,
R_BeamCirclePoints,
R_BeamEntPoint,
R_BeamEnts,
R_BeamFollow,
R_BeamKill,
R_BeamLightning,
R_BeamPoints,
R_BeamRing,
CL_AllocDlight,
CL_AllocElight,
CL_TempEntAlloc,
@ -3824,8 +3831,8 @@ static cl_enginefunc_t gEngfuncs =
pfnPrecacheEvent,
CL_PlaybackEvent,
CL_WeaponAnim,
Com_RandomFloat,
Com_RandomLong,
COM_RandomFloat,
COM_RandomLong,
pfnHookEvent,
Con_Visible,
pfnGetGameDirectory,

View File

@ -28,6 +28,13 @@ gameui_static_t gameui;
void UI_UpdateMenu( float realtime )
{
if( !gameui.hInstance ) return;
// menu time (not paused, not clamped)
gameui.globals->time = host.realtime;
gameui.globals->frametime = host.realframetime;
gameui.globals->demoplayback = cls.demoplayback;
gameui.globals->demorecording = cls.demorecording;
gameui.dllFuncs.pfnRedraw( realtime );
UI_UpdateUserinfo();
}
@ -661,17 +668,34 @@ pfnRenderScene
for drawing playermodel previews
====================
*/
static void pfnRenderScene( const ref_params_t *fd )
static void pfnRenderScene( const ref_viewpass_t *rvp )
{
// to avoid division by zero
if( !fd || fd->fov_x <= 0.0f || fd->fov_y <= 0.0f )
if( !rvp || rvp->fov_x <= 0.0f || rvp->fov_y <= 0.0f )
return;
// don't allow special modes from menu
((ref_viewpass_t *)&rvp)->flags = 0;
R_Set2DMode( false );
R_RenderFrame( fd, false, fd->fov_x );
R_RenderFrame( rvp );
R_Set2DMode( true );
}
/*
====================
pfnAddEntity
adding player model into visible list
====================
*/
static int pfnAddEntity( int entityType, cl_entity_t *ent )
{
if( !R_AddEntity( ent, entityType ))
return false;
return true;
}
/*
====================
pfnClientJoin
@ -926,7 +950,7 @@ static ui_enginefuncs_t gEngfuncs =
pfnSetPlayerModel,
R_ClearScene,
pfnRenderScene,
CL_AddEntity,
pfnAddEntity,
Host_Error,
FS_FileExists,
pfnGetGameDir,
@ -959,8 +983,8 @@ static ui_enginefuncs_t gEngfuncs =
pfnChangeInstance,
pfnStartBackgroundTrack,
pfnHostEndGame,
Com_RandomFloat,
Com_RandomLong,
COM_RandomFloat,
COM_RandomLong,
IN_SetCursor,
pfnIsMapValid,
GL_ProcessTexture,

View File

@ -26,7 +26,8 @@ GNU General Public License for more details.
#define MAX_CMD_BUFFER 8000
#define CONNECTION_PROBLEM_TIME 15.0 // 15 seconds
CVAR_DEFINE( cl_test, "cl_mycvar", "0", 0, "test variable on a new system" );
CVAR_DEFINE_AUTO( mp_decals, "300", FCVAR_ARCHIVE, "decals limit in multiplayer" );
CVAR_DEFINE_AUTO( dev_overview, "0", 0, "draw level in overview-mode" );
convar_t *rcon_client_password;
convar_t *rcon_address;
convar_t *cl_timeout;
@ -38,6 +39,7 @@ convar_t *cl_cmdbackup;
convar_t *cl_showerror;
convar_t *cl_bmodelinterp;
convar_t *cl_draw_particles;
convar_t *cl_draw_tracers;
convar_t *cl_lightstyle_lerping;
convar_t *cl_idealpitchscale;
convar_t *cl_nosmooth;
@ -127,10 +129,10 @@ char *CL_Userinfo( void )
int CL_IsDevOverviewMode( void )
{
if( gl_overview->value )
if( dev_overview.value > 0.0f )
{
if( host.developer > 0 || cls.spectator )
return 1;
return (int)dev_overview.value;
}
return 0;
@ -219,7 +221,6 @@ void CL_CheckClientState( void )
{
// first update is the final signon stage
cls.state = ca_active;
cl.force_refdef = true;
cls.changelevel = false;
cls.changedemo = false;
cl.first_frame = true;
@ -391,15 +392,11 @@ CL_UpdateFrameLerp
*/
void CL_UpdateFrameLerp( void )
{
// not in server yet, no entities to redraw
if( cls.state != ca_active ) return;
// we haven't received our first valid update from the server.
if( !cl.frame.valid || !cl.validsequence )
if( cls.state != ca_active || !cl.validsequence )
return;
// compute last interpolation amount
cl.commands[( cls.netchan.outgoing_sequence - 1 ) & CL_UPDATE_MASK].frame_lerp = cl.lerpFrac;
cl.commands[(cls.netchan.outgoing_sequence - 1) & CL_UPDATE_MASK].frame_lerp = CL_LerpPoint();
}
/*
@ -422,7 +419,7 @@ qboolean CL_ProcessShowTexturesCmds( usercmd_t *cmd )
int changed;
int pressed, released;
if( !gl_showtextures->value || gl_overview->value )
if( !gl_showtextures->value || CL_IsDevOverviewMode( ))
return false;
changed = (oldbuttons ^ cmd->buttons);
@ -453,7 +450,7 @@ qboolean CL_ProcessOverviewCmds( usercmd_t *cmd )
float step = (2.0f / size) * host.realframetime;
float step2 = step * 100.0f * (2.0f / ov->flZoom);
if( !gl_overview->value || gl_showtextures->value )
if( !CL_IsDevOverviewMode() || gl_showtextures->value )
return false;
if( ov->flZoom < 0.0f ) sign = -1;
@ -533,14 +530,11 @@ void CL_CreateCmd( void )
int input_override;
int i, ms;
// store viewangles in case it's frozen
VectorCopy( cl.viewangles, angles );
CL_UpdateClientData();
if( cls.state < ca_connected || cls.state == ca_cinematic )
return;
// store viewangles in case it's will be freeze
VectorCopy( cl.viewangles, angles );
ms = bound( 1, host.frametime * 1000, 255 );
memset( &cmd, 0, sizeof( cmd ));
input_override = 0;
@ -587,6 +581,9 @@ void CL_CreateCmd( void )
// demo always have commands so don't overwrite them
if( !cls.demoplayback ) cl.cmd = &pcmd->cmd;
// predict all unacknowledged movements
CL_PredictMovement( false );
}
void CL_WriteUsercmd( sizebuf_t *msg, int from, int to )
@ -795,12 +792,12 @@ void CL_WritePacket( void )
/*
=================
CL_SendCmd
CL_SendCommand
Called every frame to builds and sends a command packet to the server.
=================
*/
void CL_SendCmd( void )
void CL_SendCommand( void )
{
// we create commands even if a demo is playing,
CL_CreateCmd();
@ -1589,7 +1586,6 @@ void CL_PrepVideo( void )
SCR_UpdateScreen ();
cl.video_prepped = true;
cl.force_refdef = true;
}
/*
@ -1832,6 +1828,9 @@ void CL_ReadNetMessage( void )
cl.send_reply = true;
}
// build list of all solid entities per next frame (exclude clients)
CL_SetSolidEntities();
// check for fragmentation/reassembly related packets.
if( cls.state != ca_disconnected && Netchan_IncomingReady( &cls.netchan ))
{
@ -1855,12 +1854,27 @@ void CL_ReadNetMessage( void )
CL_ProcessNetRequests();
}
/*
=================
CL_ReadPackets
Updates the local time and reads/handles messages
on client net connection.
=================
*/
void CL_ReadPackets( void )
{
CL_ReadNetMessage();
// decide the simulation time
cl.oldtime = cl.time;
cl.lerpFrac = CL_LerpPoint();
cl.lerpBack = 1.0f - cl.lerpFrac;
if( !cls.demoplayback && !cl.paused )
cl.time += host.frametime;
// demo time
if( cls.demorecording && !cls.demowaiting )
cls.demotime += host.frametime;
CL_ReadNetMessage();
cl.local.thirdperson = clgame.dllFuncs.CL_IsThirdPerson();
#if 0
@ -1868,14 +1882,12 @@ void CL_ReadPackets( void )
if( cl.maxclients > 1 && cls.state == ca_active && host.developer <= 1 )
Cvar_SetCheatState();
#endif
CL_UpdateFrameLerp ();
// build list of all solid entities per next frame (exclude clients)
CL_SetSolidEntities();
// singleplayer never has connection timeout
if( NET_IsLocalAddress( cls.netchan.remote_address ))
return;
// if in the debugger last frame, don't timeout
if( host.frametime > 5.0f ) cls.netchan.last_received = Sys_DoubleTime();
// check timeout
if( cls.state >= ca_connected && !cls.demoplayback && cls.state != ca_cinematic )
@ -2109,7 +2121,8 @@ void CL_InitLocal( void )
cls.state = ca_disconnected;
cls.signon = 0;
Cvar_RegisterVariable( &cl_test );
Cvar_RegisterVariable( &mp_decals );
Cvar_RegisterVariable( &dev_overview );
// register our variables
cl_crosshair = Cvar_Get( "crosshair", "1", FCVAR_ARCHIVE, "show weapon chrosshair" );
@ -2142,8 +2155,9 @@ void CL_InitLocal( void )
cl_smoothtime = Cvar_Get( "cl_smoothtime", "0.1", FCVAR_ARCHIVE, "time to smooth up" );
cl_cmdbackup = Cvar_Get( "cl_cmdbackup", "10", FCVAR_ARCHIVE, "how many additional history commands are sent" );
cl_cmdrate = Cvar_Get( "cl_cmdrate", "30", FCVAR_ARCHIVE, "Max number of command packets sent to server per second" );
cl_draw_particles = Cvar_Get( "cl_draw_particles", "1", FCVAR_ARCHIVE, "Disable any particle effects" );
cl_draw_beams = Cvar_Get( "cl_draw_beams", "1", FCVAR_ARCHIVE, "Disable view beams" );
cl_draw_particles = Cvar_Get( "r_drawparticles", "1", FCVAR_CHEAT|FCVAR_ARCHIVE, "render particles" );
cl_draw_tracers = Cvar_Get( "r_drawtracers", "1", FCVAR_CHEAT|FCVAR_ARCHIVE, "render tracers" );
cl_draw_beams = Cvar_Get( "r_drawbeams", "1", FCVAR_CHEAT|FCVAR_ARCHIVE, "render beams" );
cl_lightstyle_lerping = Cvar_Get( "cl_lightstyle_lerping", "0", FCVAR_ARCHIVE, "enables animated light lerping (perfomance option)" );
cl_showerror = Cvar_Get( "cl_showerror", "0", FCVAR_ARCHIVE, "show prediction error" );
cl_bmodelinterp = Cvar_Get( "cl_bmodelinterp", "1", FCVAR_ARCHIVE, "enable bmodel interpolation" );
@ -2158,9 +2172,6 @@ void CL_InitLocal( void )
Cvar_Get( "direct", "1", FCVAR_ARCHIVE, "direct lighting level (legacy, unused)" );
Cvar_Get( "voice_serverdebug", "0", 0, "debug voice (legacy, unused)" );
// interpolation cvars
Cvar_Get( "ex_maxerrordistance", "0", 0, "" );
// server commands
Cmd_AddCommand ("noclip", NULL, "enable or disable no clipping mode" );
Cmd_AddCommand ("notarget", NULL, "notarget mode (monsters do not see you)" );
@ -2217,22 +2228,6 @@ void CL_InitLocal( void )
}
//============================================================================
/*
==================
CL_SendCommand
==================
*/
void CL_SendCommand( void )
{
// send intentions now
CL_SendCmd ();
// resend a connection request if necessary
CL_CheckForResend ();
}
/*
==================
CL_AdjustClock
@ -2271,66 +2266,26 @@ void CL_AdjustClock( void )
/*
==================
Host_ClientFrame
Host_ClientBegin
==================
*/
void _Host_ClientFrame( void )
void Host_ClientBegin( void )
{
#if 0
// if client is not active, do nothing
if( !cls.initialized ) return;
// evaluate console animation
Con_RunConsole ();
// finalize connection process if needs
CL_CheckClientState();
Host_InputFrame();
ClientDLL_UpdateClientData();
// tell the client.dll about client data
CL_UpdateClientData();
// if running the server locally, make intentions now
if( SV_Active( )) CL_Move ();
#endif
}
/*
==================
Host_RenderFrame
==================
*/
void Host_RenderFrame( void )
{
#if 0
// if client is not active, do nothing
if( !cls.initialized ) return;
// if running the server remotely, send intentions now after
// the incoming messages have been read
if( !SV_Active( )) CL_Move ();
ClientDLL_Frame( host_frametime );
CL_SetLastUpdate();
CL_ReadPackets();
CL_RedoPrediction();
Voice_Idle(host_frametime);
CL_EmitEntities();
CL_CheckForResend();
while (CL_RequestMissingResources());
CL_UpdateSoundFade();
Host_CheckConnectionFailure();
CL_HTTPUpdate();
Steam_ClientRunFrame();
ClientDLL_CAM_Think();
CL_MoveSpectatorCamera();
Host_UpdateScreen ();
CL_DecayLights ();
Host_UpdateSounds ();
CDAudio_Update();
CL_AdjustClock();
#endif
if( SV_Active( )) CL_SendCommand ();
}
/*
@ -2344,41 +2299,41 @@ void Host_ClientFrame( void )
// if client is not active, do nothing
if( !cls.initialized ) return;
// decide the simulation time
cl.oldtime = cl.time;
cl.time += host.frametime;
// demo time
if( cls.demorecording && !cls.demowaiting )
cls.demotime += host.frametime;
if( gameui.hInstance )
{
// menu time (not paused, not clamped)
gameui.globals->time = host.realtime;
gameui.globals->frametime = host.realframetime;
gameui.globals->demoplayback = cls.demoplayback;
gameui.globals->demorecording = cls.demorecording;
}
// if in the debugger last frame, don't timeout
if( host.frametime > 5.0f ) cls.netchan.last_received = Sys_DoubleTime();
VGui_RunFrame ();
// if running the server remotely, send intentions now after
// the incoming messages have been read
if( !SV_Active( )) CL_SendCommand ();
clgame.dllFuncs.pfnFrame( host.frametime );
// fetch results from server
CL_ReadPackets();
// remember last received framenum
CL_SetLastUpdate ();
// read updates from server
CL_ReadPackets ();
// do prediction again in case we got
// a new portion updates from server
CL_RedoPrediction ();
// Voice_Idle( host.frametime );
CL_EmitEntities ();
// in case we lost connection
CL_CheckForResend ();
// while( CL_RequestMissingResources( ));
// CL_HTTPUpdate ();
// handle spectator movement
CL_MoveSpectatorCamera();
// catch changes video settings
VID_CheckChanges();
// allow sound and video DLL change
if( cls.state == ca_active )
{
if( !cl.video_prepped ) CL_PrepVideo();
if( !cl.audio_prepped ) CL_PrepSound();
}
// process VGUI
VGui_RunFrame ();
// update the screen
SCR_UpdateScreen ();
@ -2386,25 +2341,18 @@ void Host_ClientFrame( void )
// update audio
SND_UpdateSound ();
// send a new command message to the server
CL_SendCommand();
// predict all unacknowledged movements
CL_PredictMovement( false );
// adjust client time
CL_AdjustClock();
// animate lightestyles
CL_RunLightStyles();
CL_RunLightStyles ();
// decay dynamic lights
CL_DecayLights ();
SCR_RunCinematic();
Con_RunConsole();
}
// play avi-files
SCR_RunCinematic ();
// adjust client time
CL_AdjustClock ();
}
//============================================================================

View File

@ -482,6 +482,12 @@ void SCR_DrawNetGraph( void )
int maxmsgbytes;
int w, x, y;
if( !host.developer )
return;
if( cls.state != ca_active )
return;
if( !net_graph->value )
return;

View File

@ -234,6 +234,21 @@ int CL_UserMsgStub( const char *pszName, int iSize, void *pbuf )
return 1;
}
/*
==================
CL_ParseViewEntity
==================
*/
void CL_ParseViewEntity( sizebuf_t *msg )
{
cl.viewentity = MSG_ReadWord( msg );
// check entity bounds in case we want
// to use this directly in clgame.entities[] array
cl.viewentity = bound( 0, cl.viewentity, clgame.maxEntities - 1 );
}
/*
==================
CL_ParseSoundPacket
@ -465,7 +480,7 @@ void CL_ParseParticles( sizebuf_t *msg )
{
particle_t *p;
p = CL_AllocParticle( NULL );
p = R_AllocParticle( NULL );
if( !p ) return;
p->die += life;
@ -475,7 +490,7 @@ void CL_ParseParticles( sizebuf_t *msg )
VectorCopy( org, p->org );
VectorCopy( dir, p->vel );
}
else CL_RunParticleEffect( org, dir, color, count );
else R_RunParticleEffect( org, dir, color, count );
}
/*
@ -536,21 +551,64 @@ void CL_ParseStaticEntity( sizebuf_t *msg )
ent->trivial_accept = INVALID_HANDLE;
// setup the new static entity
CL_UpdateEntityFields( ent );
if( Mod_GetType( state.modelindex ) == mod_studio )
{
CL_UpdateStudioVars( ent, &state, true );
// animate studio model
ent->curstate.animtime = cl.time;
ent->curstate.framerate = 1.0f;
ent->latched.prevframe = 0.0f;
}
VectorCopy( ent->curstate.origin, ent->origin );
VectorCopy( ent->curstate.angles, ent->angles );
ent->model = Mod_Handle( state.modelindex );
ent->curstate.framerate = 1.0f;
CL_ResetLatchedVars( ent, true );
R_AddEfrags( ent ); // add link
}
/*
==================
CL_WeaponAnim
Set new weapon animation
==================
*/
void CL_WeaponAnim( int iAnim, int body )
{
cl_entity_t *view = &clgame.viewent;
cl.local.weaponstarttime = 0;
cl.local.weaponsequence = iAnim;
// anim is changed. update latchedvars
if( iAnim != view->curstate.sequence )
{
int i;
// save current blends to right lerping from last sequence
for( i = 0; i < 2; i++ )
view->latched.prevseqblending[i] = view->curstate.blending[i];
view->latched.prevsequence = view->curstate.sequence; // save old sequence
// save animtime
view->latched.prevanimtime = view->curstate.animtime;
view->latched.sequencetime = 0.0f;
}
view->curstate.animtime = cl.time; // start immediately
view->curstate.framerate = 1.0f;
view->curstate.sequence = iAnim;
view->latched.prevframe = 0.0f;
view->curstate.scale = 1.0f;
view->curstate.frame = 0.0f;
view->curstate.body = body;
view->curstate.rendermode = kRenderNormal;
view->curstate.renderamt = 255;
#if 0 // g-cont. for GlowShell testing
view->curstate.renderfx = kRenderFxGlowShell;
view->curstate.rendercolor.r = 255;
view->curstate.rendercolor.g = 128;
view->curstate.rendercolor.b = 0;
view->curstate.renderamt = 100;
#endif
}
/*
==================
CL_ParseStaticDecal
@ -658,6 +716,14 @@ void CL_ParseServerData( sizebuf_t *msg )
if( cl.maxclients > 1 && host.developer < 1 )
host.developer++;
// multiplayer game?
if( cl.maxclients != 1 )
{
if( r_decals->value > mp_decals.value )
Cvar_SetValue( "r_decals", mp_decals.value );
}
else Cvar_Reset( "r_decals" );
// set the background state
if( cls.demoplayback && ( cls.demonum != -1 ))
{
@ -806,7 +872,7 @@ void CL_ParseClientData( sizebuf_t *msg )
ps = &frame->playerstate[cl.playernum];
wd = frame->weapondata;
pcd = &frame->client;
pcd = &frame->clientdata;
}
else
{
@ -858,7 +924,7 @@ void CL_ParseClientData( sizebuf_t *msg )
return;
}
to_cd = &frame->client;
to_cd = &frame->clientdata;
to_wd = frame->weapondata;
// clear to old value before delta parsing
@ -866,7 +932,7 @@ void CL_ParseClientData( sizebuf_t *msg )
{
int delta_sequence = MSG_ReadByte( msg );
from_cd = &cl.frames[delta_sequence & CL_UPDATE_MASK].client;
from_cd = &cl.frames[delta_sequence & CL_UPDATE_MASK].clientdata;
from_wd = cl.frames[delta_sequence & CL_UPDATE_MASK].weapondata;
}
else
@ -891,12 +957,12 @@ void CL_ParseClientData( sizebuf_t *msg )
}
// make a local copy of physinfo
Q_strncpy( cls.physinfo, frame->client.physinfo, sizeof( cls.physinfo ));
Q_strncpy( cls.physinfo, frame->clientdata.physinfo, sizeof( cls.physinfo ));
cl.local.maxspeed = frame->client.maxspeed;
cl.local.pushmsec = frame->client.pushmsec;
cl.local.weapons = frame->client.weapons; // g-cont 32-bit predictable weapon limit !!!
cl.local.health = frame->client.health;
cl.local.maxspeed = frame->clientdata.maxspeed;
cl.local.pushmsec = frame->clientdata.pushmsec;
cl.local.weapons = frame->clientdata.weapons;
cl.local.health = frame->clientdata.health;
}
/*
@ -912,7 +978,7 @@ void CL_ParseBaseline( sizebuf_t *msg )
Delta_InitClient (); // finalize client delta's
newnum = MSG_ReadWord( msg );
newnum = MSG_ReadUBitLong( msg, MAX_ENTITY_BITS );
if( newnum < 0 ) Host_Error( "CL_SpawnEdict: invalid number %i\n", newnum );
if( newnum >= clgame.maxEntities ) Host_Error( "CL_AllocEdict: no free edicts\n" );
@ -1623,7 +1689,7 @@ void CL_ParseServerMessage( sizebuf_t *msg )
cls.connect_time = MAX_HEARTBEAT; // CL_CheckForResend() will fire immediately
break;
case svc_setview:
cl.viewentity = MSG_ReadWord( msg );
CL_ParseViewEntity( msg );
break;
case svc_sound:
case svc_ambientsound:

File diff suppressed because it is too large Load Diff

View File

@ -122,25 +122,30 @@ void SCR_NetSpeeds( void )
int cur_clfps = 0;
rgba_t color;
if( !host.developer )
return;
if( !net_speeds->value || cls.demoplayback || cls.state != ca_active )
return;
if( cl_serverframetime() != 0 )
// prevent to get too big values at max
if( cl_serverframetime() > 0.0001f )
{
cur_svfps = Q_rint( 1.0f / cl_serverframetime( ));
if( cur_svfps < min_svfps ) min_svfps = cur_svfps;
if( cur_svfps > max_svfps ) max_svfps = cur_svfps;
}
if( cl_clientframetime() != 0 )
// prevent to get too big values at max
if( cl_clientframetime() > 0.0001f )
{
cur_clfps = Q_rint( 1.0f / cl_clientframetime( ));
if( cur_clfps < min_clfps ) min_clfps = cur_clfps;
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 sended to server: %s\nTotal received from 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_sended ), Q_memprint( cls.netchan.total_received ));
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",
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;
y = 384;
@ -172,6 +177,9 @@ void SCR_RSpeeds( void )
{
char msg[MAX_SYSPATH];
if( !host.developer )
return;
if( R_SpeedsMessage( msg, sizeof( msg )))
{
int x, y, height;
@ -516,9 +524,9 @@ void SCR_InstallParticlePalette( void )
{
for( i = 0; i < 256; i++ )
{
clgame.palette[i][0] = pic->palette[i*4+0];
clgame.palette[i][1] = pic->palette[i*4+1];
clgame.palette[i][2] = pic->palette[i*4+2];
clgame.palette[i].r = pic->palette[i*4+0];
clgame.palette[i].g = pic->palette[i*4+1];
clgame.palette[i].b = pic->palette[i*4+2];
}
FS_FreeImage( pic );
}
@ -526,9 +534,9 @@ void SCR_InstallParticlePalette( void )
{
for( i = 0; i < 256; i++ )
{
clgame.palette[i][0] = i;
clgame.palette[i][1] = i;
clgame.palette[i][2] = i;
clgame.palette[i].r = i;
clgame.palette[i].g = i;
clgame.palette[i].b = i;
}
MsgDev( D_WARN, "CL_InstallParticlePalette: failed. Force to grayscale\n" );
}

File diff suppressed because it is too large Load Diff

View File

@ -16,38 +16,32 @@ GNU General Public License for more details.
#ifndef CL_TENT_H
#define CL_TENT_H
#define SPARK_ELECTRIC_MINSPEED 64.0f
#define SPARK_ELECTRIC_MAXSPEED 100.0f
// EfxAPI
void CL_DrawTracer( vec3_t start, vec3_t delta, float width, rgb_t color, int alpha, float startV, float endV );
struct particle_s *CL_AllocParticle( void (*callback)( struct particle_s*, float ));
struct particle_s *R_AllocParticle( void (*callback)( struct particle_s*, float ));
void CL_Explosion( vec3_t pos, int model, float scale, float framerate, int flags );
void CL_ParticleExplosion( const vec3_t org );
void CL_ParticleExplosion2( const vec3_t org, int colorStart, int colorLength );
void CL_Implosion( const vec3_t end, float radius, int count, float life );
void R_Implosion( const vec3_t end, float radius, int count, float life );
void CL_Blood( const vec3_t org, const vec3_t dir, int pcolor, int speed );
void CL_BloodStream( const vec3_t org, const vec3_t dir, int pcolor, int speed );
void CL_BlobExplosion( const vec3_t org );
void CL_EntityParticles( cl_entity_t *ent );
void CL_FlickerParticles( const vec3_t org );
void CL_RunParticleEffect( const vec3_t org, const vec3_t dir, int color, int count );
void R_RunParticleEffect( const vec3_t org, const vec3_t dir, int color, int count );
void CL_ParticleBurst( const vec3_t org, int size, int color, float life );
void CL_LavaSplash( const vec3_t org );
void CL_TeleportSplash( const vec3_t org );
void CL_RocketTrail( vec3_t start, vec3_t end, int type );
short CL_LookupColor( byte r, byte g, byte b );
void CL_GetPackedColor( short *packed, short color );
void CL_SparkleTracer( const vec3_t pos, const vec3_t dir, float vel );
void CL_StreakTracer( const vec3_t pos, const vec3_t velocity, int colorIndex );
void CL_TracerEffect( const vec3_t start, const vec3_t end );
void CL_UserTracerParticle( float *org, float *vel, float life, int colorIndex, float length, byte deathcontext, void (*deathfunc)( struct particle_s* ));
struct particle_s *CL_TracerParticles( float *org, float *vel, float life );
void R_TracerEffect( const vec3_t start, const vec3_t end );
void R_UserTracerParticle( float *org, float *vel, float life, int colorIndex, float length, byte deathcontext, void (*deathfunc)( struct particle_s* ));
struct particle_s *R_TracerParticles( float *org, float *vel, float life );
void CL_ParticleLine( const vec3_t start, const vec3_t end, byte r, byte g, byte b, float life );
void CL_ParticleBox( const vec3_t mins, const vec3_t maxs, byte r, byte g, byte b, float life );
void CL_ShowLine( const vec3_t start, const vec3_t end );
void CL_BulletImpactParticles( const vec3_t pos );
void CL_SparkShower( const vec3_t org );
void R_BulletImpactParticles( const vec3_t pos );
void R_SparkShower( const vec3_t org );
struct tempent_s *CL_TempEntAlloc( const vec3_t org, model_t *pmodel );
struct tempent_s *CL_TempEntAllocHigh( const vec3_t org, model_t *pmodel );
struct tempent_s *CL_TempEntAllocNoModel( const vec3_t org );
@ -72,9 +66,9 @@ void CL_Sprite_Spray( const vec3_t pos, const vec3_t dir, int modelIndex, int co
void CL_Sprite_Trail( int type, const vec3_t vecStart, const vec3_t vecEnd, int modelIndex, int nCount, float flLife, float flSize, float flAmplitude, int nRenderamt, float flSpeed );
void CL_FunnelSprite( const vec3_t pos, int spriteIndex, int flags );
void CL_Large_Funnel( const vec3_t pos, int flags );
void CL_SparkEffect( const vec3_t pos, int count, int velocityMin, int velocityMax );
void CL_StreakSplash( const vec3_t pos, const vec3_t dir, int color, int count, float speed, int velMin, int velMax );
void CL_SparkStreaks( const vec3_t pos, int count, int velocityMin, int velocityMax );
void R_SparkEffect( const vec3_t pos, int count, int velocityMin, int velocityMax );
void R_StreakSplash( const vec3_t pos, const vec3_t dir, int color, int count, float speed, int velMin, int velMax );
void R_SparkStreaks( const vec3_t pos, int count, int velocityMin, int velocityMax );
void CL_Projectile( const vec3_t origin, const vec3_t velocity, int modelIndex, int life, int owner, void (*hitcallback)( struct tempent_s*, struct pmtrace_s* ));
void CL_TempSphereModel( const vec3_t pos, float speed, float life, int count, int modelIndex );
void CL_MultiGunshot( const vec3_t org, const vec3_t dir, const vec3_t noise, int count, int decalCount, int *decalIndices );
@ -86,27 +80,38 @@ void CL_RicochetSound( const vec3_t pos );
struct dlight_s *CL_AllocDlight( int key );
struct dlight_s *CL_AllocElight( int key );
void CL_UpdateFlashlight( cl_entity_t *pEnt );
void CL_AddEntityEffects( cl_entity_t *ent );
void CL_AddStudioEffects( cl_entity_t *ent );
void CL_DecalShoot( int textureIndex, int entityIndex, int modelIndex, float *pos, int flags );
void CL_DecalRemoveAll( int textureIndex );
int CL_DecalIndexFromName( const char *name );
int CL_DecalIndex( int id );
// Beams
struct beam_s *CL_BeamLightning( const vec3_t start, const vec3_t end, int modelIndex, float life, float width, float amplitude, float brightness, float speed );
struct beam_s *CL_BeamEnts( int startEnt, int endEnt, int modelIndex, float life, float width, float amplitude, float brightness, float speed, int startFrame, float framerate, float r, float g, float b );
struct beam_s *CL_BeamPoints( const vec3_t start, const vec3_t end, int modelIndex, float life, float width, float amplitude, float brightness, float speed, int startFrame, float framerate, float r, float g, float b );
struct beam_s *CL_BeamCirclePoints( int type, const vec3_t start, const vec3_t end, int modelIndex, float life, float width, float amplitude, float brightness, float speed, int startFrame, float framerate, float r, float g, float b );
struct beam_s *CL_BeamEntPoint( int startEnt, const vec3_t end, int modelIndex, float life, float width, float amplitude, float brightness, float speed, int startFrame, float framerate, float r, float g, float b );
struct beam_s *CL_BeamRing( int startEnt, int endEnt, int modelIndex, float life, float width, float amplitude, float brightness, float speed, int startFrame, float framerate, float r, float g, float b );
struct beam_s *CL_BeamFollow( int startEnt, int modelIndex, float life, float width, float r, float g, float b, float brightness );
void CL_BeamKill( int deadEntity );
struct beam_s *R_BeamLightning( vec3_t start, vec3_t end, int modelIndex, float life, float width, float amplitude, float brightness, float speed );
struct beam_s *R_BeamEnts( int startEnt, int endEnt, int modelIndex, float life, float width, float amplitude, float brightness, float speed, int startFrame, float framerate, float r, float g, float b );
struct beam_s *R_BeamPoints( vec3_t start, vec3_t end, int modelIndex, float life, float width, float amplitude, float brightness, float speed, int startFrame, float framerate, float r, float g, float b );
struct beam_s *R_BeamCirclePoints( int type, vec3_t start, vec3_t end, int modelIndex, float life, float width, float amplitude, float brightness, float speed, int startFrame, float framerate, float r, float g, float b );
struct beam_s *R_BeamEntPoint( int startEnt, vec3_t end, int modelIndex, float life, float width, float amplitude, float brightness, float speed, int startFrame, float framerate, float r, float g, float b );
struct beam_s *R_BeamRing( int startEnt, int endEnt, int modelIndex, float life, float width, float amplitude, float brightness, float speed, int startFrame, float framerate, float r, float g, float b );
struct beam_s *R_BeamFollow( int startEnt, int modelIndex, float life, float width, float r, float g, float b, float brightness );
void R_BeamKill( int deadEntity );
// TriAPI
void TriBegin( int mode );
void TriTexCoord2f( float u, float v );
void TriVertex3fv( const float *v );
void TriNormal3fv( const float *v );
void TriVertex3f( float x, float y, float z );
int TriBoxInPVS( float *mins, float *maxs );
void TriColor4f( float r, float g, float b, float a );
int TriSpriteTexture( model_t *pSpriteModel, int frame );
void TriColor4fRendermode( float r, float g, float b, float a, int rendermode );
int TriWorldToScreen( float *world, float *screen );
void TriColor4ub( byte r, byte g, byte b, byte a );
void TriBrightness( float brightness );
void TriRenderMode( int mode );
void TriCullFace( int mode );
void TriEnd( void );
#endif//CL_TENT_H

View File

@ -29,18 +29,37 @@ calc frame rectangle (Quake1 style)
*/
void V_CalcViewRect( void )
{
int size, sb_lines;
qboolean full = false;
int sb_lines;
float size;
if( scr_viewsize->value >= 120.0f )
// intermission is always full screen
if( cl.intermission ) size = 120.0f;
else size = scr_viewsize->value;
if( size >= 120.0f )
sb_lines = 0; // no status bar at all
else if( scr_viewsize->value >= 110.0f )
else if( size >= 110.0f )
sb_lines = 24; // no inventory
else sb_lines = 48;
size = Q_min( scr_viewsize->value, 100 );
if( scr_viewsize->value >= 100.0 )
{
full = true;
size = 100.0f;
}
else size = scr_viewsize->value;
clgame.viewport[2] = glState.width * size / 100;
clgame.viewport[3] = glState.height * size / 100;
if( cl.intermission )
{
size = 100.0f;
sb_lines = 0;
full = true;
}
size /= 100.0;
clgame.viewport[2] = glState.width * size;
clgame.viewport[3] = glState.height * size;
if( clgame.viewport[3] > glState.height - sb_lines )
clgame.viewport[3] = glState.height - sb_lines;
@ -48,7 +67,8 @@ void V_CalcViewRect( void )
clgame.viewport[3] = glState.height;
clgame.viewport[0] = ( glState.width - clgame.viewport[2] ) / 2;
clgame.viewport[1] = ( glState.height - sb_lines - clgame.viewport[3] ) / 2;
if( full ) clgame.viewport[1] = 0;
else clgame.viewport[1] = ( glState.height - sb_lines - clgame.viewport[3] ) / 2;
}
@ -126,16 +146,6 @@ void V_SetRefParams( ref_params_t *fd )
fd->onlyClientDraw = 0; // reset clientdraw
fd->nextView = 0; // reset nextview
// Xash3D extension. FIXME: it's needs to be removed...
// calc FOV
fd->fov_x = bound( 1.0f, cl.local.scr_fov, 179.0f ); // this is a final fov value
fd->fov_y = V_CalcFov( &fd->fov_x, clgame.viewport[2], clgame.viewport[3] );
// adjust FOV for widescreen
if( glState.wideScreen && r_adjust_fov->value )
V_AdjustFov( &fd->fov_x, &fd->fov_y, clgame.viewport[2], clgame.viewport[3], false );
}
/*
@ -145,7 +155,7 @@ V_MergeOverviewRefdef
merge refdef with overview settings
===============
*/
void V_RefParamsApplyOverview( ref_params_t *fd )
void V_RefApplyOverview( ref_viewpass_t *rvp )
{
ref_overview_t *ov = &clgame.overView;
float aspect;
@ -167,25 +177,27 @@ void V_RefParamsApplyOverview( ref_params_t *fd )
ov->xTop = -(size_y / 2);
ov->xBottom = (size_y / 2);
if( gl_overview->value == 1 )
if( CL_IsDevOverviewMode() == 1 )
{
Con_NPrintf( 0, " Overview: Zoom %.2f, Map Origin (%.2f, %.2f, %.2f), Z Min %.2f, Z Max %.2f, Rotated %i\n",
ov->flZoom, ov->origin[0], ov->origin[1], ov->origin[2], ov->zNear, ov->zFar, ov->rotated );
}
VectorCopy( ov->origin, fd->vieworg );
fd->vieworg[2] = ov->zFar + ov->zNear;
Vector2Copy( fd->vieworg, mins );
Vector2Copy( fd->vieworg, maxs );
VectorCopy( ov->origin, rvp->vieworigin );
rvp->vieworigin[2] = ov->zFar + ov->zNear;
Vector2Copy( rvp->vieworigin, mins );
Vector2Copy( rvp->vieworigin, maxs );
mins[!ov->rotated] += ov->xLeft;
maxs[!ov->rotated] += ov->xRight;
mins[ov->rotated] += ov->xTop;
maxs[ov->rotated] += ov->xBottom;
fd->viewangles[0] = 90.0f;
fd->viewangles[1] = 90.0f;
fd->viewangles[2] = (ov->rotated) ? (ov->flZoom < 0.0f) ? 180.0f : 0.0f : (ov->flZoom < 0.0f) ? -90.0f : 90.0f;
rvp->viewangles[0] = 90.0f;
rvp->viewangles[1] = 90.0f;
rvp->viewangles[2] = (ov->rotated) ? (ov->flZoom < 0.0f) ? 180.0f : 0.0f : (ov->flZoom < 0.0f) ? -90.0f : 90.0f;
SetBits( rvp->flags, RF_DRAW_OVERVIEW );
Mod_SetOrthoBounds( mins, maxs );
}
@ -195,7 +207,7 @@ void V_RefParamsApplyOverview( ref_params_t *fd )
V_GetRefParams
=============
*/
void V_GetRefParams( ref_params_t *fd )
void V_GetRefParams( ref_params_t *fd, ref_viewpass_t *rvp )
{
// part1: deniable updates
VectorCopy( fd->simvel, cl.simvel );
@ -207,6 +219,33 @@ void V_GetRefParams( ref_params_t *fd )
VectorCopy( fd->crosshairangle, cl.crosshairangle );
VectorCopy( fd->cl_viewangles, cl.viewangles );
cl.intermission = fd->intermission; // Quake Remake compatibility
// setup ref_viewpass
rvp->viewport[0] = fd->viewport[0];
rvp->viewport[1] = fd->viewport[1];
rvp->viewport[2] = fd->viewport[2];
rvp->viewport[3] = fd->viewport[3];
VectorCopy( fd->vieworg, rvp->vieworigin );
VectorCopy( fd->viewangles, rvp->viewangles );
rvp->viewentity = fd->viewentity;
// calc FOV
rvp->fov_x = bound( 10.0f, cl.local.scr_fov, 150.0f ); // this is a final fov value
// first we need to compute FOV and other things that needs for frustum properly work
rvp->fov_y = V_CalcFov( &rvp->fov_x, rvp->viewport[2], rvp->viewport[3] );
// adjust FOV for widescreen
if( glState.wideScreen && r_adjust_fov->value )
V_AdjustFov( &rvp->fov_x, &rvp->fov_y, rvp->viewport[2], rvp->viewport[3], false );
rvp->flags = 0;
if( fd->onlyClientDraw )
SetBits( rvp->flags, RF_ONLY_CLIENTDRAW );
SetBits( rvp->flags, RF_DRAW_WORLD );
}
/*
@ -254,42 +293,33 @@ V_RenderView
void V_RenderView( void )
{
ref_params_t rp;
ref_viewpass_t rvp;
int viewnum = 0;
if( !cl.video_prepped || ( UI_IsVisible() && !cl.background ))
return; // still loading
if( cl.frame.valid && ( cl.force_refdef || !cl.paused ))
{
cl.force_refdef = false;
R_ClearScene ();
CL_AddEntities ();
}
V_CalcViewRect (); // compute viewport rectangle
V_SetRefParams( &rp );
V_SetupViewModel ();
R_Set2DMode( false );
SCR_AddDirtyPoint( 0, 0 );
SCR_AddDirtyPoint( clgame.viewport[2] - 1, clgame.viewport[3] - 1 );
SCR_DirtyScreen();
GL_BackendStartFrame ();
tr.framecount++; // g-cont. keep actual frame for all viewpasses
do
{
clgame.dllFuncs.pfnCalcRefdef( &rp );
V_RefParamsApplyOverview( &rp );
V_GetRefParams( &rp );
V_GetRefParams( &rp, &rvp );
V_RefApplyOverview( &rvp );
if ( viewnum == 0 && rp.onlyClientDraw )
if( viewnum == 0 && FBitSet( rvp.flags, RF_ONLY_CLIENTDRAW ))
{
pglClearColor( 0.0f, 0.0f, 0.0f, 0.0f );
pglClear( GL_COLOR_BUFFER_BIT );
}
R_RenderFrame( &rp, true, cl.local.scr_fov );
R_RenderFrame( &rvp );
viewnum++;
} while( rp.nextView );

View File

@ -71,11 +71,11 @@ typedef struct frame_s
double time; // server timestamp
qboolean valid; // cleared if delta parsing was invalid
clientdata_t client; // local client private data
clientdata_t clientdata; // local client private data
entity_state_t playerstate[MAX_CLIENTS];
weapon_data_t weapondata[MAX_LOCAL_WEAPONS];
netbandwidthgraph_t graphdata;
byte flags[MAX_VISIBLE_PACKET_VIS_BYTES];
int num_entities;
int first_entity; // into the circular cl_packet_entities[]
} frame_t;
@ -157,7 +157,6 @@ typedef struct
qboolean video_prepped; // false if on new level or new ref dll
qboolean audio_prepped; // false if on new level or new snd dll
qboolean force_refdef; // vid has changed, so we can't use a paused refdef
qboolean paused;
int delta_sequence; // acknowledged sequence number
@ -174,8 +173,6 @@ typedef struct
uint checksum; // for catching cheater maps
frame_t frame; // received from server
frame_t frames[MULTIPLAYER_BACKUP]; // alloced on svc_serverdata
runcmd_t commands[MULTIPLAYER_BACKUP]; // each mesage will send several old cmds
local_state_t predicted_frames[MULTIPLAYER_BACKUP]; // local client state
@ -185,9 +182,6 @@ typedef struct
// a lerp point for other data
double oldtime; // previous cl.time, time-oldtime is used
// to decay light values and smooth step ups
float lerpFrac; // interpolation value
float lerpBack; // invert interpolation value
float timedelta; // floating delta between two updates
char serverinfo[MAX_SERVERINFO_STRING];
@ -307,12 +301,13 @@ typedef struct
qboolean scissor_test;
qboolean adjust_size; // allow to adjust scale for fonts
int renderMode; // override kRenderMode from TriAPI
int cullMode; // override CULL FACE from TriAPI
// holds text color
rgba_t textColor;
rgba_t spriteColor;
rgba_t triColor;
vec4_t triRGBA;
// crosshair members
const model_t *pCrosshair;
@ -443,7 +438,7 @@ typedef struct
center_print_t centerPrint; // centerprint variables
SCREENINFO scrInfo; // actual screen info
ref_overview_t overView; // overView params
rgb_t palette[256]; // palette used for particle colors
color24 palette[256]; // palette used for particle colors
client_textmessage_t *titles; // title messages, not network messages
int numTitles;
@ -594,6 +589,7 @@ extern gameui_static_t gameui;
//
// cvars
//
extern convar_t mp_decals;
extern convar_t *cl_nopred;
extern convar_t *cl_showfps;
extern convar_t *cl_envshot_size;
@ -612,6 +608,7 @@ extern convar_t *cl_idealpitchscale;
extern convar_t *cl_allow_levelshots;
extern convar_t *cl_lightstyle_lerping;
extern convar_t *cl_draw_particles;
extern convar_t *cl_draw_tracers;
extern convar_t *cl_levelshot_name;
extern convar_t *cl_draw_beams;
extern convar_t *cl_clockreset;
@ -625,13 +622,12 @@ extern convar_t *scr_viewsize;
extern convar_t *scr_download;
extern convar_t *scr_loading;
extern convar_t *scr_dark; // start from dark
extern convar_t *rate;
//=============================================================================
void CL_SetLightstyle( int style, const char* s, float f );
void CL_RunLightStyles( void );
void CL_AddEntities( void );
void CL_DecayLights( void );
//=================================================
@ -663,7 +659,7 @@ void CL_SendCommand( void );
void CL_Disconnect_f( void );
void CL_ProcessFile( qboolean successfully_received, const char *filename );
void CL_WriteUsercmd( sizebuf_t *msg, int from, int to );
void CL_GetChallengePacket( void );
void CL_UpdateFrameLerp( void );
int CL_IsDevOverviewMode( void );
void CL_PingServers_f( void );
void CL_SignonReply( void );
@ -757,6 +753,7 @@ qboolean CL_DispatchUserMessage( const char *pszName, int iSize, void *pbuf );
//
void SCR_VidInit( void );
void SCR_TileClear( void );
void SCR_DirtyScreen( void );
void SCR_AddDirtyPoint( int x, int y );
void SCR_InstallParticlePalette( void );
void SCR_EndLoadingPlaque( void );
@ -800,6 +797,7 @@ int CL_WaterEntity( const float *rgflPos );
cl_entity_t *CL_GetWaterEntity( const float *rgflPos );
void CL_SetupPMove( playermove_t *pmove, local_state_t *from, usercmd_t *ucmd, qboolean runfuncs, double time );
pmtrace_t CL_TraceLine( vec3_t start, vec3_t end, int flags );
void CL_MoveSpectatorCamera( void );
void CL_SetLastUpdate( void );
void CL_RedoPrediction( void );
void CL_ClearPhysEnts( void );
@ -817,13 +815,14 @@ void CL_InitStudioAPI( void );
//
int CL_ParsePacketEntities( sizebuf_t *msg, qboolean delta );
qboolean CL_AddVisibleEntity( cl_entity_t *ent, int entityType );
void CL_UpdateStudioVars( cl_entity_t *ent, entity_state_t *newstate, qboolean noInterp );
void CL_ResetLatchedVars( cl_entity_t *ent, qboolean full_reset );
qboolean CL_GetEntitySpatialization( struct channel_s *ch );
qboolean CL_GetMovieSpatialization( struct rawchan_s *ch );
void CL_ComputePlayerOrigin( cl_entity_t *clent );
void CL_UpdateEntityFields( cl_entity_t *ent );
qboolean CL_IsPlayerIndex( int idx );
void CL_SetIdealPitch( void );
void CL_EmitEntities( void );
//
// cl_remap.c
@ -847,14 +846,17 @@ void CL_DrawParticlesExternal( const float *vieworg, const float *fwd, const flo
void CL_FireCustomDecal( int textureIndex, int entityIndex, int modelIndex, float *pos, int flags, float scale );
void CL_DecalShoot( int textureIndex, int entityIndex, int modelIndex, float *pos, int flags );
void CL_PlayerDecal( int textureIndex, int entityIndex, float *pos );
void R_FreeDeadParticles( particle_t **ppparticles );
int CL_FxBlend( cl_entity_t *e );
void CL_InitParticles( void );
void CL_ClearParticles( void );
void CL_FreeParticles( void );
void CL_DrawParticles( void );
void CL_DrawParticles( double frametime );
void CL_DrawTracers( double frametime );
void CL_InitTempEnts( void );
void CL_ClearTempEnts( void );
void CL_FreeTempEnts( void );
void CL_AddTempEnts( void );
void CL_TempEntUpdate( void );
void CL_InitViewBeams( void );
void CL_ClearViewBeams( void );
void CL_FreeViewBeams( void );

View File

@ -525,11 +525,11 @@ qboolean VID_ScreenShot( const char *filename, int shot_type )
switch( shot_type )
{
case VID_SCREENSHOT:
if( !gl_overview->value )
if( !CL_IsDevOverviewMode( ))
VID_ImageAdjustGamma( r_shot->buffer, r_shot->width, r_shot->height ); // scrshot gamma
break;
case VID_SNAPSHOT:
if( !gl_overview->value )
if( !CL_IsDevOverviewMode( ))
VID_ImageAdjustGamma( r_shot->buffer, r_shot->width, r_shot->height ); // scrshot gamma
FS_AllowDirectPaths( true );
break;

File diff suppressed because it is too large Load Diff

2200
engine/client/gl_beams.old Normal file

File diff suppressed because it is too large Load Diff

View File

@ -48,7 +48,7 @@ extern byte *r_temppool;
#define RP_NONVIEWERREF (RP_MIRRORVIEW|RP_ENVVIEW)
#define R_StudioOpaque( rm ) ( rm == kRenderNormal || rm == kRenderTransAlpha )
#define RP_LOCALCLIENT( e ) (CL_GetLocalPlayer() && ((e)->index == CL_GetLocalPlayer()->index && e->curstate.entityType == ET_PLAYER ))
#define RP_LOCALCLIENT( e ) ((e)->index == ( cl.playernum + 1 ) && e->player )
#define RP_NORMALPASS() ((RI.params & RP_NONVIEWERREF) == 0 )
#define TF_SKY (TF_SKYSIDE|TF_UNCOMPRESSED|TF_NOMIPMAP|TF_NOPICMIP)
@ -203,16 +203,16 @@ typedef struct
// OpenGL matrix states
qboolean modelviewIdentity;
qboolean fResetVis;
int visframecount; // PVS frame
int dlightframecount; // dynamic light frame
int realframecount; // not including passes
int framecount;
int lightstylevalue[MAX_LIGHTSTYLES]; // value 0 - 65536
float lightcache[MAX_LIGHTSTYLES];
double frametime; // special frametime for multipass rendering (will set to 0 on a nextview)
// cull info
vec3_t modelorg; // relative to viewpoint
} ref_globals_t;
@ -250,7 +250,7 @@ extern dlight_t cl_elights[MAX_ELIGHTS];
extern struct beam_s *cl_active_beams;
extern struct beam_s *cl_free_beams;
extern struct particle_s *cl_free_trails;
extern struct particle_s *cl_free_particles;
//
// gl_backend.c
@ -355,7 +355,6 @@ void R_RenderScene( void );
void R_DrawCubemapView( const vec3_t origin, const vec3_t angles, int size );
void R_TranslateForEntity( cl_entity_t *e );
void R_RotateForEntity( cl_entity_t *e );
int R_ComputeFxBlend( cl_entity_t *e );
qboolean R_InitRenderAPI( void );
void R_SetupFrustum( void );
void R_FindViewLeaf( void );
@ -416,6 +415,7 @@ void R_DrawSpriteModel( cl_entity_t *e );
void R_StudioInit( void );
void Mod_LoadStudioModel( model_t *mod, const void *buffer, qboolean *loaded );
struct mstudiotex_s *R_StudioGetTexture( cl_entity_t *e );
float CL_GetStudioEstimatedFrame( cl_entity_t *ent );
void R_DrawStudioModel( cl_entity_t *e );
//
@ -455,7 +455,7 @@ qboolean VID_ScreenShot( const char *filename, int shot_type );
qboolean VID_CubemapShot( const char *base, uint size, const float *vieworg, qboolean skyshot );
void VID_RestoreGamma( void );
void R_BeginFrame( qboolean clearScene );
void R_RenderFrame( const struct ref_params_s *fd, qboolean drawWorld, float fov );
void R_RenderFrame( const struct ref_viewpass_s *vp );
void R_EndFrame( void );
void R_ClearScene( void );
void R_GetTextureParms( int *w, int *h, int texnum );
@ -643,7 +643,6 @@ extern convar_t *gl_compress_textures;
extern convar_t *gl_compensate_gamma_screenshots;
extern convar_t *gl_keeptjunctions;
extern convar_t *gl_detailscale;
extern convar_t *gl_overview; // draw map in overview mode
extern convar_t *gl_wireframe;
extern convar_t *gl_allow_static;
extern convar_t *gl_allow_mirrors;

View File

@ -336,7 +336,7 @@ void R_DrawMirrors( void )
tr.mirror_entities[i].ent = NULL;
}
tr.framecount = oldframecount; // restore real framecount
RI.viewleaf = NULL; // force markleafs next frame
tr.num_mirror_entities = 0;
tr.num_mirrors_used = 0;
}

View File

@ -196,6 +196,7 @@ static int R_TransEntityCompare( const cl_entity_t **a, const cl_entity_t **b )
R_WorldToScreen
Convert a given point from world into screen space
Returns true if we behind to screen
===============
*/
qboolean R_WorldToScreen( const vec3_t point, vec3_t screen )
@ -205,7 +206,7 @@ qboolean R_WorldToScreen( const vec3_t point, vec3_t screen )
float w;
if( !point || !screen )
return false;
return true;
Matrix4x4_Copy( worldToScreen, RI.worldviewProjectionMatrix );
screen[0] = worldToScreen[0][0] * point[0] + worldToScreen[0][1] * point[1] + worldToScreen[0][2] * point[2] + worldToScreen[0][3];
@ -215,17 +216,18 @@ qboolean R_WorldToScreen( const vec3_t point, vec3_t screen )
if( w < 0.001f )
{
behind = true;
screen[0] *= 100000;
screen[1] *= 100000;
behind = true;
}
else
{
float invw = 1.0f / w;
behind = false;
screen[0] *= invw;
screen[1] *= invw;
behind = false;
}
return behind;
}
@ -253,135 +255,6 @@ void R_ScreenToWorld( const vec3_t screen, vec3_t point )
if( w != 0.0f ) VectorScale( point, ( 1.0f / w ), point );
}
/*
===============
R_ComputeFxBlend
===============
*/
int R_ComputeFxBlend( cl_entity_t *e )
{
int blend = 0, renderAmt;
float offset, dist;
vec3_t tmp;
offset = ((int)e->index ) * 363.0f; // Use ent index to de-sync these fx
renderAmt = e->curstate.renderamt;
switch( e->curstate.renderfx )
{
case kRenderFxPulseSlowWide:
blend = renderAmt + 0x40 * sin( cl.time * 2 + offset );
break;
case kRenderFxPulseFastWide:
blend = renderAmt + 0x40 * sin( cl.time * 8 + offset );
break;
case kRenderFxPulseSlow:
blend = renderAmt + 0x10 * sin( cl.time * 2 + offset );
break;
case kRenderFxPulseFast:
blend = renderAmt + 0x10 * sin( cl.time * 8 + offset );
break;
// JAY: HACK for now -- not time based
case kRenderFxFadeSlow:
if( renderAmt > 0 )
renderAmt -= 1;
else renderAmt = 0;
blend = renderAmt;
break;
case kRenderFxFadeFast:
if( renderAmt > 3 )
renderAmt -= 4;
else renderAmt = 0;
blend = renderAmt;
break;
case kRenderFxSolidSlow:
if( renderAmt < 255 )
renderAmt += 1;
else renderAmt = 255;
blend = renderAmt;
break;
case kRenderFxSolidFast:
if( renderAmt < 252 )
renderAmt += 4;
else renderAmt = 255;
blend = renderAmt;
break;
case kRenderFxStrobeSlow:
blend = 20 * sin( cl.time * 4 + offset );
if( blend < 0 ) blend = 0;
else blend = renderAmt;
break;
case kRenderFxStrobeFast:
blend = 20 * sin( cl.time * 16 + offset );
if( blend < 0 ) blend = 0;
else blend = renderAmt;
break;
case kRenderFxStrobeFaster:
blend = 20 * sin( cl.time * 36 + offset );
if( blend < 0 ) blend = 0;
else blend = renderAmt;
break;
case kRenderFxFlickerSlow:
blend = 20 * (sin( cl.time * 2 ) + sin( cl.time * 17 + offset ));
if( blend < 0 ) blend = 0;
else blend = renderAmt;
break;
case kRenderFxFlickerFast:
blend = 20 * (sin( cl.time * 16 ) + sin( cl.time * 23 + offset ));
if( blend < 0 ) blend = 0;
else blend = renderAmt;
break;
case kRenderFxHologram:
case kRenderFxDistort:
VectorCopy( e->origin, tmp );
VectorSubtract( tmp, RI.vieworg, tmp );
dist = DotProduct( tmp, RI.vforward );
// Turn off distance fade
if( e->curstate.renderfx == kRenderFxDistort )
dist = 1;
if( dist <= 0 )
{
blend = 0;
}
else
{
renderAmt = 180;
if( dist <= 100 ) blend = renderAmt;
else blend = (int) ((1.0f - ( dist - 100 ) * ( 1.0f / 400.0f )) * renderAmt );
blend += Com_RandomLong( -32, 31 );
}
break;
case kRenderFxNone:
case kRenderFxClampMinScale:
if( e->curstate.rendermode == kRenderNormal )
blend = 255;
else blend = renderAmt;
break;
case kRenderFxGlowShell: // safe current renderamt because it's shell scale!
case kRenderFxDeadPlayer: // safe current renderamt because it's player index!
default:
blend = renderAmt;
break;
}
if( e->model && e->model->type != mod_brush )
{
// NOTE: never pass sprites with rendercolor '0 0 0' it's a stupid Valve Hammer Editor bug
if( !e->curstate.rendercolor.r && !e->curstate.rendercolor.g && !e->curstate.rendercolor.b )
e->curstate.rendercolor.r = e->curstate.rendercolor.g = e->curstate.rendercolor.b = 255;
// apply scale to studiomodels and sprites only
if( !e->curstate.scale )
e->curstate.scale = 1.0f;
}
blend = bound( 0, blend, 255 );
return blend;
}
/*
===============
R_ClearScene
@ -391,7 +264,7 @@ void R_ClearScene( void )
{
tr.num_solid_entities = tr.num_trans_entities = 0;
tr.num_static_entities = tr.num_mirror_entities = 0;
tr.num_child_entities = 0;
tr.num_child_entities = cl.num_custombeams = 0;
}
/*
@ -399,7 +272,7 @@ void R_ClearScene( void )
R_AddEntity
===============
*/
qboolean R_AddEntity( struct cl_entity_s *clent, int entityType )
qboolean R_AddEntity( struct cl_entity_s *clent, int type )
{
if( !r_drawentities->value )
return false; // not allow to drawing
@ -410,14 +283,12 @@ qboolean R_AddEntity( struct cl_entity_s *clent, int entityType )
if( clent->curstate.effects & EF_NODRAW )
return false; // done
clent->curstate.renderamt = R_ComputeFxBlend( clent );
clent->curstate.renderamt = CL_FxBlend( clent );
if( clent->curstate.rendermode != kRenderNormal && clent->curstate.renderamt <= 0.0f )
return true; // invisible
clent->curstate.entityType = entityType;
if( entityType == ET_FRAGMENTED )
if( type == ET_FRAGMENTED )
r_stats.c_client_ents++;
if( R_FollowEntity( clent ))
@ -474,7 +345,7 @@ static void R_Clear( int bitMask )
{
int bits;
if( gl_overview->value )
if( CL_IsDevOverviewMode( ))
pglClearColor( 0.0f, 1.0f, 0.0f, 1.0f ); // green background (Valve rules)
else pglClearColor( 0.5f, 0.5f, 0.5f, 1.0f );
@ -577,13 +448,6 @@ void R_SetupFrustum( void )
vec3_t farPoint;
int i;
// first we need to compute FOV and other things that needs for frustum properly work
RI.fov_y = V_CalcFov( &RI.fov_x, RI.viewport[2], RI.viewport[3] );
// adjust FOV for widescreen
if( glState.wideScreen && RI.drawWorld && r_adjust_fov->value )
V_AdjustFov( &RI.fov_x, &RI.fov_y, RI.viewport[2], RI.viewport[3], false );
// build the transformation matrix for the given view angles
AngleVectors( RI.viewangles, RI.vforward, RI.vright, RI.vup );
@ -759,7 +623,6 @@ R_FindViewLeaf
*/
void R_FindViewLeaf( void )
{
RI.oldviewleaf = RI.viewleaf;
RI.viewleaf = Mod_PointInLeaf( RI.pvsorigin, cl.worldmodel->nodes );
}
@ -1134,7 +997,8 @@ void R_DrawEntitiesOnList( void )
if( !RI.onlyClientDraw )
{
CL_DrawBeams( true );
CL_DrawParticles();
CL_DrawParticles( tr.frametime );
CL_DrawTracers( tr.frametime );
}
// NOTE: some mods with custom renderer may generate glErrors
@ -1159,9 +1023,19 @@ R_SetupRefParams must be called right before
*/
void R_RenderScene( void )
{
static int framecount = -1;
if( !cl.worldmodel && RI.drawWorld )
Host_Error( "R_RenderView: NULL worldmodel\n" );
// frametime is valid only for normal pass
if( RP_NORMALPASS( ))
{
tr.frametime = cl.time - cl.oldtime;
framecount = tr.framecount;
}
else tr.frametime = 0.0;
R_PushDlights();
R_SetupFrustum();
@ -1191,7 +1065,7 @@ void R_BeginFrame( qboolean clearScene )
{
glConfig.softwareGammaUpdate = false; // in case of possible fails
if(( gl_clear->value || gl_overview->value ) && clearScene && cls.state != ca_cinematic )
if(( gl_clear->value || CL_IsDevOverviewMode( )) && clearScene && cls.state != ca_cinematic )
{
pglClear( GL_COLOR_BUFFER_BIT );
}
@ -1236,28 +1110,34 @@ R_SetupRefParams
set initial params for renderer
===============
*/
void R_SetupRefParams( const ref_params_t *fd, qboolean drawWorld, float fov )
void R_SetupRefParams( const ref_viewpass_t *rvp )
{
RI.params = RP_NONE;
RI.drawWorld = drawWorld;
RI.thirdPerson = cl.local.thirdperson;
RI.drawOrtho = (drawWorld) ? (int)gl_overview->value : 0;
RI.drawWorld = FBitSet( rvp->flags, RF_DRAW_WORLD );
RI.onlyClientDraw = FBitSet( rvp->flags, RF_ONLY_CLIENTDRAW );
RI.clipFlags = 15; // top, bottom, left, right
RI.onlyClientDraw = fd->onlyClientDraw;
RI.farClip = 0;
if( !FBitSet( rvp->flags, RF_DRAW_CUBEMAP ))
{
RI.drawOrtho = FBitSet( rvp->flags, RF_DRAW_OVERVIEW );
RI.thirdPerson = cl.local.thirdperson;
}
else RI.thirdPerson = RI.drawOrtho = false;
// setup viewport
RI.viewport[0] = fd->viewport[0];
RI.viewport[1] = fd->viewport[1];
RI.viewport[2] = fd->viewport[2];
RI.viewport[3] = fd->viewport[3];
RI.viewport[0] = rvp->viewport[0];
RI.viewport[1] = rvp->viewport[1];
RI.viewport[2] = rvp->viewport[2];
RI.viewport[3] = rvp->viewport[3];
// calc FOV
RI.fov_x = fov; // this is a final fov value
RI.fov_x = rvp->fov_x;
RI.fov_y = rvp->fov_y;
VectorCopy( fd->vieworg, RI.vieworg );
VectorCopy( fd->viewangles, RI.viewangles );
VectorCopy( fd->vieworg, RI.pvsorigin );
VectorCopy( rvp->vieworigin, RI.vieworg );
VectorCopy( rvp->viewangles, RI.viewangles );
VectorCopy( rvp->vieworigin, RI.pvsorigin );
}
/*
@ -1265,32 +1145,27 @@ void R_SetupRefParams( const ref_params_t *fd, qboolean drawWorld, float fov )
R_RenderFrame
===============
*/
void R_RenderFrame( const ref_params_t *fd, qboolean drawWorld, float fov )
void R_RenderFrame( const ref_viewpass_t *rvp )
{
if( r_norefresh->value )
return;
tr.realframecount++;
// setup the initial render params
R_SetupRefParams( rvp );
if( RI.drawOrtho != gl_overview->value )
tr.fResetVis = true;
if( gl_finish->value && RI.drawWorld )
pglFinish();
// completely override rendering
if( clgame.drawFuncs.GL_RenderFrame != NULL )
{
if( clgame.drawFuncs.GL_RenderFrame( fd, drawWorld ))
if( clgame.drawFuncs.GL_RenderFrame( rvp ))
{
RI.drawWorld = drawWorld;
tr.fResetVis = true;
RI.viewleaf = NULL; // force markleafs next frame
return;
}
}
R_SetupRefParams( fd, drawWorld, fov );
if( gl_finish->value && drawWorld )
pglFinish();
if( gl_allow_mirrors->value )
{
// render mirrors
@ -1325,35 +1200,24 @@ R_DrawCubemapView
*/
void R_DrawCubemapView( const vec3_t origin, const vec3_t angles, int size )
{
if( clgame.drawFuncs.R_DrawCubemapView != NULL )
{
if( clgame.drawFuncs.R_DrawCubemapView( origin, angles, size ))
return;
}
ref_viewpass_t rvp;
// basic params
RI.params = RP_NONE;
RI.drawWorld = true;
RI.thirdPerson = RI.drawOrtho = false;
RI.clipFlags = 15; // top, bottom, left, right
RI.onlyClientDraw = false;
RI.farClip = 0;
rvp.flags = rvp.viewentity = 0;
SetBits( rvp.flags, RF_DRAW_WORLD );
SetBits( rvp.flags, RF_DRAW_CUBEMAP );
// setup viewport
RI.viewport[0] = RI.viewport[1] = 0;
RI.viewport[2] = RI.viewport[3] = size;
// calc FOV
RI.fov_x = 90.0f; // this is a final fov value
rvp.viewport[0] = rvp.viewport[1] = 0;
rvp.viewport[2] = rvp.viewport[3] = size;
rvp.fov_x = rvp.fov_y = 90.0f; // this is a final fov value
// setup origin & angles
VectorCopy( origin, RI.vieworg );
VectorCopy( angles, RI.viewangles );
VectorCopy( origin, RI.pvsorigin );
VectorCopy( origin, rvp.vieworigin );
VectorCopy( angles, rvp.viewangles );
R_RenderScene ();
R_RenderFrame( &rvp );
RI.oldviewleaf = RI.viewleaf = NULL; // force markleafs next frame
RI.viewleaf = NULL; // force markleafs next frame
}
static int GL_RenderGetParm( int parm, int arg )
@ -1559,7 +1423,7 @@ static void CL_GetBeamChains( BEAM ***active_beams, BEAM ***free_beams, particle
{
*active_beams = &cl_active_beams;
*free_beams = &cl_free_beams;
*free_trails = &cl_free_trails;
*free_trails = &cl_free_particles;
}
static void GL_SetWorldviewProjectionMatrix( const float *glmatrix )

View File

@ -160,7 +160,7 @@ static const char *R_DetailTextureForName( const char *name )
if( Q_stristr( name, table->texname ))
{
if(( table->lMin + table->lMax ) > 0 )
return va( table->detail, Com_RandomLong( table->lMin, table->lMax ));
return va( table->detail, COM_RandomLong( table->lMin, table->lMax ));
return table->detail;
}
}

File diff suppressed because it is too large Load Diff

1751
engine/client/gl_rpart.old Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1957,20 +1957,20 @@ Mark the leaves and nodes that are in the PVS for the current leaf
*/
void R_MarkLeaves( void )
{
qboolean novis = false;
mnode_t *node;
int i;
if( !RI.drawWorld ) return;
if( FBitSet( r_novis->flags, FCVAR_CHANGED ) || tr.fResetVis )
if( FBitSet( r_novis->flags, FCVAR_CHANGED ))
{
// force recalc viewleaf
ClearBits( r_novis->flags, FCVAR_CHANGED );
tr.fResetVis = false;
RI.viewleaf = NULL;
}
if( RI.viewleaf == RI.oldviewleaf && !r_novis->value && RI.viewleaf != NULL )
if( RI.viewleaf == RI.oldviewleaf && RI.viewleaf != NULL )
return;
// development aid to let you run around
@ -1981,16 +1981,9 @@ void R_MarkLeaves( void )
tr.visframecount++;
if( r_novis->value || RI.drawOrtho || !RI.viewleaf || !cl.worldmodel->visdata )
{
// mark everything
for( i = 0; i < cl.worldmodel->numleafs; i++ )
cl.worldmodel->leafs[i+1].visframe = tr.visframecount;
for( i = 0; i < cl.worldmodel->numnodes; i++ )
cl.worldmodel->nodes[i].visframe = tr.visframecount;
return;
}
novis = true;
Mod_FatPVS( RI.pvsorigin, REFPVS_RADIUS, RI.visbytes, world.visbytes, FBitSet( RI.params, RP_OLDVIEWLEAF ), r_novis->value );
Mod_FatPVS( RI.pvsorigin, REFPVS_RADIUS, RI.visbytes, world.visbytes, FBitSet( RI.params, RP_OLDVIEWLEAF ), novis );
for( i = 0; i < cl.worldmodel->numleafs; i++ )
{

View File

@ -554,25 +554,25 @@ float R_GetSpriteFrameInterpolant( cl_entity_t *ent, mspriteframe_t **oldframe,
// this can be happens when rendering switched between single and angled frames
// or change model on replace delta-entity
ent->latched.prevblending[0] = ent->latched.prevblending[1] = frame;
ent->latched.prevanimtime = cl.time;
ent->latched.sequencetime = cl.time;
lerpFrac = 1.0f;
}
if( ent->latched.prevanimtime < cl.time )
if( ent->latched.sequencetime < cl.time )
{
if( frame != ent->latched.prevblending[1] )
{
ent->latched.prevblending[0] = ent->latched.prevblending[1];
ent->latched.prevblending[1] = frame;
ent->latched.prevanimtime = cl.time;
ent->latched.sequencetime = cl.time;
lerpFrac = 0.0f;
}
else lerpFrac = (cl.time - ent->latched.prevanimtime) * 10;
else lerpFrac = (cl.time - ent->latched.sequencetime) * 10;
}
else
{
ent->latched.prevblending[0] = ent->latched.prevblending[1] = frame;
ent->latched.prevanimtime = cl.time;
ent->latched.sequencetime = cl.time;
lerpFrac = 0.0f;
}
}
@ -586,7 +586,7 @@ float R_GetSpriteFrameInterpolant( cl_entity_t *ent, mspriteframe_t **oldframe,
{
// reset interpolation on change model
ent->latched.prevblending[0] = ent->latched.prevblending[1] = frame;
ent->latched.prevanimtime = cl.time;
ent->latched.sequencetime = cl.time;
lerpFrac = 0.0f;
}
@ -640,25 +640,25 @@ float R_GetSpriteFrameInterpolant( cl_entity_t *ent, mspriteframe_t **oldframe,
// this can be happens when rendering switched between single and angled frames
// or change model on replace delta-entity
ent->latched.prevblending[0] = ent->latched.prevblending[1] = frame;
ent->latched.prevanimtime = cl.time;
ent->latched.sequencetime = cl.time;
lerpFrac = 1.0f;
}
if( ent->latched.prevanimtime < cl.time )
if( ent->latched.sequencetime < cl.time )
{
if( frame != ent->latched.prevblending[1] )
{
ent->latched.prevblending[0] = ent->latched.prevblending[1];
ent->latched.prevblending[1] = frame;
ent->latched.prevanimtime = cl.time;
ent->latched.sequencetime = cl.time;
lerpFrac = 0.0f;
}
else lerpFrac = (cl.time - ent->latched.prevanimtime) * ent->curstate.framerate;
else lerpFrac = (cl.time - ent->latched.sequencetime) * ent->curstate.framerate;
}
else
{
ent->latched.prevblending[0] = ent->latched.prevblending[1] = frame;
ent->latched.prevanimtime = cl.time;
ent->latched.sequencetime = cl.time;
lerpFrac = 0.0f;
}
}
@ -832,6 +832,7 @@ qboolean R_SpriteOccluded( cl_entity_t *e, vec3_t origin, int *alpha, float *psc
if( R_CullSpriteModel( e, origin ))
return true;
}
return false;
}
@ -936,6 +937,7 @@ void R_DrawSpriteModel( cl_entity_t *e )
alpha = e->curstate.renderamt;
scale = e->curstate.scale;
if( !scale ) scale = 1.0f;
if( R_SpriteOccluded( e, origin, &alpha, &scale ))
return; // sprite culled
@ -981,10 +983,19 @@ void R_DrawSpriteModel( cl_entity_t *e )
// all sprites can have color
pglTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
// add basecolor (any rendermode can colored sprite)
color[0] = (float)e->curstate.rendercolor.r * ( 1.0f / 255.0f );
color[1] = (float)e->curstate.rendercolor.g * ( 1.0f / 255.0f );
color[2] = (float)e->curstate.rendercolor.b * ( 1.0f / 255.0f );
// NOTE: never pass sprites with rendercolor '0 0 0' it's a stupid Valve Hammer Editor bug
if( e->curstate.rendercolor.r || e->curstate.rendercolor.g || e->curstate.rendercolor.b )
{
color[0] = (float)e->curstate.rendercolor.r * ( 1.0f / 255.0f );
color[1] = (float)e->curstate.rendercolor.g * ( 1.0f / 255.0f );
color[2] = (float)e->curstate.rendercolor.b * ( 1.0f / 255.0f );
}
else
{
color[0] = 1.0f;
color[1] = 1.0f;
color[2] = 1.0f;
}
if( R_SpriteHasLightmap( e, psprite->texFormat ))
{

View File

@ -77,6 +77,12 @@ typedef struct sortedmesh_s
int flags; // face flags
} sortedmesh_t;
typedef struct
{
double time;
double frametime;
} studio_draw_state_t;
convar_t *r_studio_lerping;
convar_t *r_studio_lambert;
convar_t *r_studio_lighting;
@ -106,6 +112,7 @@ static uint g_nNumArrayVerts;
static uint g_nNumArrayElems;
static vec3_t g_lightvalues[MAXSTUDIOVERTS];
static studiolight_t g_studiolight;
static studio_draw_state_t g_studio; // used for draw studiomodels
char g_nCachedBoneNames[MAXSTUDIOBONES][32];
int g_nCachedBones; // number of bones in cache
int g_nStudioCount; // for chrome update
@ -197,6 +204,29 @@ static int R_StudioBodyVariations( model_t *mod )
return count;
}
/*
================
R_StudioSetupTimings
init current time for a given model
================
*/
static void R_StudioSetupTimings( void )
{
if( RI.drawWorld )
{
// synchronize with server time
g_studio.time = cl.time;
g_studio.frametime = cl.time - cl.oldtime;
}
else
{
// menu stuff
g_studio.time = host.realtime;
g_studio.frametime = host.frametime;
}
}
/*
================
R_StudioExtractBbox
@ -321,9 +351,10 @@ pfnGetPlayerState
*/
entity_state_t *R_StudioGetPlayerState( int index )
{
if( index < 0 || index > cl.maxclients )
if( index < 0 || index >= cl.maxclients )
return NULL;
return &cl.frame.playerstate[index];
return &cl.frames[cl.parsecountmod].playerstate[index];
}
/*
@ -346,8 +377,8 @@ pfnGetEngineTimes
static void pfnGetEngineTimes( int *framecount, double *current, double *old )
{
if( framecount ) *framecount = tr.framecount;
if( current ) *current = cl.time;
if( old ) *old = cl.oldtime;
if( current ) *current = g_studio.time;
if( old ) *old = g_studio.time - g_studio.frametime;
}
/*
@ -458,7 +489,7 @@ qboolean R_CullStudioModel( cl_entity_t *e )
if( !e || !e->model || !e->model->cache.data )
return true;
if( e == &clgame.viewent && ( r_lefthand->value >= 2 || gl_overview->value ))
if( e == &clgame.viewent && ( r_lefthand->value >= 2 || CL_IsDevOverviewMode( )))
return true; // hidden
if( !R_StudioComputeBBox( e, NULL ))
@ -524,10 +555,10 @@ void R_StudioSetUpTransform( cl_entity_t *e )
// don't do it if the goalstarttime hasn't updated in a while.
// NOTE: Because we need to interpolate multiplayer characters, the interpolation time limit
// was increased to 1.0 s., which is 2x the max lag we are accounting for.
if( m_fDoInterp && ( cl.time < e->curstate.animtime + 1.0f ) && ( e->curstate.animtime != e->latched.prevanimtime ))
if( m_fDoInterp && ( g_studio.time < e->curstate.animtime + 1.0f ) && ( e->curstate.animtime != e->latched.prevanimtime ))
{
f = ( cl.time - e->curstate.animtime ) / ( e->curstate.animtime - e->latched.prevanimtime );
// Msg( "%4.2f %.2f %.2f\n", f, e->curstate.animtime, cl.time );
f = ( g_studio.time - e->curstate.animtime ) / ( e->curstate.animtime - e->latched.prevanimtime );
// Msg( "%4.2f %.2f %.2f\n", f, e->curstate.animtime, g_studio.time );
}
if( m_fDoInterp )
@ -583,11 +614,11 @@ StudioEstimateFrame
float R_StudioEstimateFrame( cl_entity_t *e, mstudioseqdesc_t *pseqdesc )
{
double dfdt, f;
if( m_fDoInterp )
{
if( cl.time < e->curstate.animtime ) dfdt = 0.0;
else dfdt = (cl.time - e->curstate.animtime) * e->curstate.framerate * pseqdesc->fps;
if( g_studio.time < e->curstate.animtime ) dfdt = 0.0;
else dfdt = (g_studio.time - e->curstate.animtime) * e->curstate.framerate * pseqdesc->fps;
}
else dfdt = 0;
@ -623,12 +654,39 @@ float R_StudioEstimateInterpolant( cl_entity_t *e )
if( m_fDoInterp && ( e->curstate.animtime >= e->latched.prevanimtime + 0.01f ))
{
dadt = ( cl.time - e->curstate.animtime ) / 0.1f;
dadt = ( g_studio.time - e->curstate.animtime ) / 0.1f;
if( dadt > 2.0f ) dadt = 2.0f;
}
return dadt;
}
/*
====================
CL_GetStudioEstimatedFrame
====================
*/
float CL_GetStudioEstimatedFrame( cl_entity_t *ent )
{
studiohdr_t *pstudiohdr;
mstudioseqdesc_t *pseqdesc;
int sequence;
if( ent->model != NULL && ent->model->type == mod_studio )
{
pstudiohdr = (studiohdr_t *)Mod_Extradata( ent->model );
if( pstudiohdr )
{
sequence = bound( 0, ent->curstate.sequence, pstudiohdr->numseq - 1 );
pseqdesc = (mstudioseqdesc_t *)((byte *)pstudiohdr + pstudiohdr->seqindex) + sequence;
return R_StudioEstimateFrame( ent, pseqdesc );
}
}
return 0;
}
/*
====================
StudioGetAnim
@ -693,28 +751,28 @@ void R_StudioFxTransform( cl_entity_t *ent, matrix3x4 transform )
{
case kRenderFxDistort:
case kRenderFxHologram:
if( !Com_RandomLong( 0, 49 ))
if( !COM_RandomLong( 0, 49 ))
{
int axis = Com_RandomLong( 0, 1 );
int axis = COM_RandomLong( 0, 1 );
if( axis == 1 ) axis = 2; // choose between x & z
VectorScale( transform[axis], Com_RandomFloat( 1.0f, 1.484f ), transform[axis] );
VectorScale( transform[axis], COM_RandomFloat( 1.0f, 1.484f ), transform[axis] );
}
else if( !Com_RandomLong( 0, 49 ))
else if( !COM_RandomLong( 0, 49 ))
{
float offset;
int axis = Com_RandomLong( 0, 1 );
int axis = COM_RandomLong( 0, 1 );
if( axis == 1 ) axis = 2; // choose between x & z
offset = Com_RandomFloat( -10.0f, 10.0f );
transform[Com_RandomLong( 0, 2 )][3] += offset;
offset = COM_RandomFloat( -10.0f, 10.0f );
transform[COM_RandomLong( 0, 2 )][3] += offset;
}
break;
case kRenderFxExplode:
{
float scale;
scale = 1.0f + ( cl.time - ent->curstate.animtime ) * 10.0f;
scale = 1.0f + ( g_studio.time - ent->curstate.animtime ) * 10.0f;
if( scale > 2.0f ) scale = 2.0f; // don't blow up more than 200%
transform[0][1] *= scale;
@ -1143,7 +1201,7 @@ void R_StudioSetupBones( cl_entity_t *e )
}
}
if( m_fDoInterp && e->latched.sequencetime && ( e->latched.sequencetime + 0.2f > cl.time) && ( e->latched.prevsequence < m_pStudioHeader->numseq ))
if( m_fDoInterp && e->latched.sequencetime && ( e->latched.sequencetime + 0.2f > g_studio.time ) && ( e->latched.prevsequence < m_pStudioHeader->numseq ))
{
// blend from last sequence
static vec3_t pos1b[MAXSTUDIOBONES];
@ -1180,7 +1238,7 @@ void R_StudioSetupBones( cl_entity_t *e )
}
}
s = 1.0f - ( cl.time - e->latched.sequencetime ) / 0.2f;
s = 1.0f - ( g_studio.time - e->latched.sequencetime ) / 0.2f;
R_StudioSlerpBones( q, pos, q1b, pos1b, s );
}
else
@ -1291,7 +1349,7 @@ void R_StudioSetupChrome( float *pchrome, int bone, vec3_t normal )
float angle, sr, cr;
int i;
angle = anglemod( cl.time * 40 ) * (M_PI2 / 360.0f);
angle = anglemod( g_studio.time * 40 ) * (M_PI2 / 360.0f);
SinCos( angle, &sr, &cr );
for( i = 0; i < 3; i++ )
@ -1488,7 +1546,7 @@ void R_StudioDynamicLight( cl_entity_t *ent, alight_t *lightinfo )
for( lnum = 0, dl = cl_dlights; lnum < MAX_DLIGHTS; lnum++, dl++ )
{
if( dl->die < cl.time || !dl->radius )
if( dl->die < g_studio.time || !dl->radius )
continue;
VectorSubtract( dl->origin, origin, direction );
@ -1574,7 +1632,7 @@ void R_StudioEntityLight( alight_t *lightinfo )
for( lnum = 0, el = cl_elights; lnum < MAX_ELIGHTS; lnum++, el++ )
{
if( el->die < cl.time || !el->radius )
if( el->die < g_studio.time || !el->radius )
continue;
VectorSubtract( el->origin, origin, direction );
@ -1832,7 +1890,7 @@ void R_StudioSetRenderamt( int iRenderamt )
if( !RI.currententity ) return;
RI.currententity->curstate.renderamt = iRenderamt;
RI.currententity->curstate.renderamt = R_ComputeFxBlend( RI.currententity );
RI.currententity->curstate.renderamt = CL_FxBlend( RI.currententity );
}
/*
@ -2478,18 +2536,41 @@ static void R_StudioClientEvents( void )
mstudioevent_t *pevent;
cl_entity_t *e = RI.currententity;
int i, sequence;
float f, start;
float end, start;
if( g_studio.frametime == 0.0 )
return; // gamepaused
if( FBitSet( e->curstate.effects, EF_MUZZLEFLASH ))
{
dlight_t *el = CL_AllocElight( 0 );
ClearBits( e->curstate.effects, EF_MUZZLEFLASH );
VectorCopy( e->attachment[0], el->origin );
el->die = cl.time + 0.05f;
el->color.r = 255;
el->color.g = 192;
el->color.b = 64;
el->decay = 320;
el->radius = 16;
}
sequence = bound( 0, e->curstate.sequence, m_pStudioHeader->numseq - 1 );
pseqdesc = (mstudioseqdesc_t *)((byte *)m_pStudioHeader + m_pStudioHeader->seqindex) + sequence;
pevent = (mstudioevent_t *)((byte *)m_pStudioHeader + pseqdesc->eventindex);
// no events for this animation or gamepaused
if( pseqdesc->numevents == 0 || cl.time == cl.oldtime )
// no events for this animation
if( pseqdesc->numevents == 0 )
return;
f = R_StudioEstimateFrame( e, pseqdesc ) + 0.01f; // get start offset
start = f - e->curstate.framerate * host.frametime * pseqdesc->fps;
end = R_StudioEstimateFrame( e, pseqdesc );
start = end - e->curstate.framerate * host.frametime * pseqdesc->fps;
pevent = (mstudioevent_t *)((byte *)m_pStudioHeader + pseqdesc->eventindex);
if( e->latched.sequencetime == e->curstate.animtime )
{
if( !FBitSet( pseqdesc->flags, STUDIO_LOOPING ))
start = -0.01f;
}
for( i = 0; i < pseqdesc->numevents; i++ )
{
@ -2497,7 +2578,7 @@ static void R_StudioClientEvents( void )
if( pevent[i].event < EVENT_CLIENT )
continue;
if( (float)pevent[i].frame > start && f >= (float)pevent[i].frame )
if( (float)pevent[i].frame > start && pevent[i].frame <= end )
clgame.dllFuncs.pfnStudioEvent( &pevent[i], e );
}
}
@ -2811,7 +2892,7 @@ void R_StudioEstimateGait( entity_state_t *pplayer )
vec3_t est_velocity;
float dt;
dt = bound( 0.0f, (cl.time - cl.oldtime), 1.0f );
dt = bound( 0.0f, g_studio.frametime, 1.0f );
if( dt == 0.0f || m_pPlayerInfo->renderframe == tr.framecount )
{
@ -2880,7 +2961,7 @@ void R_StudioProcessGait( entity_state_t *pplayer )
RI.currententity->latched.prevblending[0] = RI.currententity->curstate.blending[0];
RI.currententity->latched.prevseqblending[0] = RI.currententity->curstate.blending[0];
dt = bound( 0.0f, (cl.time - cl.oldtime), 1.0f );
dt = bound( 0.0f, g_studio.frametime, 1.0f );
R_StudioEstimateGait( pplayer );
// calc side to side turning
@ -3234,6 +3315,8 @@ void R_DrawStudioModelInternal( cl_entity_t *e, qboolean follow_entity )
prevFrame = e->latched.prevframe;
R_StudioSetupTimings();
// prevent to crash some mods like HLFX in menu Customize
if( !RI.drawWorld && !r_customdraw_playermodel->value )
{
@ -3287,7 +3370,14 @@ R_RunViewmodelEvents
*/
void R_RunViewmodelEvents( void )
{
if( cl.local.thirdperson || RI.params & RP_NONVIEWERREF )
if( RI.onlyClientDraw || r_drawviewmodel->value == 0 )
return;
// ignore in thirdperson, camera view or client is died
if( cl.local.thirdperson || cl.local.health <= 0 || cl.viewentity != ( cl.playernum + 1 ))
return;
if( RI.params & RP_NONVIEWERREF )
return;
if( !Mod_Extradata( clgame.viewent.model ))
@ -3297,7 +3387,9 @@ void R_RunViewmodelEvents( void )
RI.currentmodel = RI.currententity->model;
if( !RI.currentmodel ) return;
if( !cl.local.weaponstarttime ) cl.local.weaponstarttime = cl.time;
R_StudioSetupTimings();
if( !cl.local.weaponstarttime ) cl.local.weaponstarttime = g_studio.time;
RI.currententity->curstate.animtime = cl.local.weaponstarttime;
RI.currententity->curstate.sequence = cl.local.weaponsequence;
@ -3331,7 +3423,9 @@ void R_DrawViewModel( void )
RI.currentmodel = RI.currententity->model;
if( !RI.currentmodel ) return;
RI.currententity->curstate.renderamt = R_ComputeFxBlend( RI.currententity );
R_StudioSetupTimings();
RI.currententity->curstate.renderamt = CL_FxBlend( RI.currententity );
// hack the depth range to prevent view model from poking into walls
pglDepthRange( gldepthmin, gldepthmin + 0.3f * ( gldepthmax - gldepthmin ));
@ -3340,7 +3434,7 @@ void R_DrawViewModel( void )
if( r_lefthand->value == 1 || g_iBackFaceCull )
GL_FrontFace( !glState.frontFace );
if( !cl.local.weaponstarttime ) cl.local.weaponstarttime = cl.time;
if( !cl.local.weaponstarttime ) cl.local.weaponstarttime = g_studio.time;
RI.currententity->curstate.animtime = cl.local.weaponstarttime;
RI.currententity->curstate.sequence = cl.local.weaponsequence;

View File

@ -44,7 +44,6 @@ convar_t *gl_allow_static;
convar_t *gl_allow_mirrors;
convar_t *gl_wireframe;
convar_t *gl_round_down;
convar_t *gl_overview;
convar_t *gl_max_size;
convar_t *gl_picmip;
convar_t *gl_skymip;
@ -1786,7 +1785,6 @@ void GL_InitCommands( void )
gl_clear = Cvar_Get( "gl_clear", "0", FCVAR_ARCHIVE, "clearing screen after each frame" );
gl_test = Cvar_Get( "gl_test", "0", 0, "engine developer cvar for quick testing new features" );
gl_wireframe = Cvar_Get( "gl_wireframe", "0", FCVAR_ARCHIVE|FCVAR_SPONLY, "show wireframe overlay" );
gl_overview = Cvar_Get( "dev_overview", "0", 0, "show level overview" );
// these cvar not used by engine but some mods requires this
Cvar_Get( "gl_polyoffset", "-0.1", 0, "polygon offset for decals" );

View File

@ -385,7 +385,7 @@ void DLY_DoStereoDelay( int count )
// set up new crossfade, if not crossfading, not modulating, but going to
if( !dly->xfade && !dly->modcur && dly->mod )
{
dly->idelayoutputxf = dly->idelayoutput + ((Com_RandomLong( 0, 255 ) * dly->delaysamples ) >> 9 );
dly->idelayoutputxf = dly->idelayoutput + ((COM_RandomLong( 0, 255 ) * dly->delaysamples ) >> 9 );
dly->xfade = 128;
}
@ -611,7 +611,7 @@ int RVB_DoReverbForOneDly( dly_t *dly, const int vlr, const portable_samplepair_
// modulate delay rate
if( !dly->mod )
{
dly->idelayoutputxf = dly->idelayoutput + ((Com_RandomLong( 0, 255 ) * delay) >> 9 );
dly->idelayoutputxf = dly->idelayoutput + ((COM_RandomLong( 0, 255 ) * delay) >> 9 );
if( dly->idelayoutputxf >= dly->cdelaysamplesmax )
dly->idelayoutputxf -= dly->cdelaysamplesmax;
@ -738,13 +738,13 @@ void RVB_DoAMod( int count )
sxmod1cur = sxmod1;
if( !sxmod1 )
sxamodlt = Com_RandomLong( 32, 255 );
sxamodlt = COM_RandomLong( 32, 255 );
if( --sxmod2cur < 0 )
sxmod2cur = sxmod2;
if( !sxmod2 )
sxamodrt = Com_RandomLong( 32, 255 );
sxamodrt = COM_RandomLong( 32, 255 );
res.left = (sxamodl * res.left) >> 8;
res.right = (sxamodr * res.right) >> 8;
@ -874,8 +874,8 @@ void SX_Profiling_f( void )
for( i = 0; i < 512; i++ )
{
testbuffer[i].left = Com_RandomLong( 0, 3000 );
testbuffer[i].right = Com_RandomLong( 0, 3000 );
testbuffer[i].left = COM_RandomLong( 0, 3000 );
testbuffer[i].right = COM_RandomLong( 0, 3000 );
}
if( Cmd_Argc() > 1 )

View File

@ -972,7 +972,7 @@ void S_StartSound( const vec3_t pos, int ent, int chan, sound_t handle, float fv
if( check->sfx == sfx && !check->pMixer.sample )
{
// skip up to 0.1 seconds of audio
int skip = Com_RandomLong( 0, (long)( 0.1f * check->sfx->cache->rate ));
int skip = COM_RandomLong( 0, (long)( 0.1f * check->sfx->cache->rate ));
S_SetSampleStart( check, sfx->cache, skip );
break;

View File

@ -20,6 +20,108 @@ GNU General Public License for more details.
#include "client.h"
#include "library.h"
static long idum = 0;
#define MAX_RANDOM_RANGE 0x7FFFFFFFUL
#define IA 16807
#define IM 2147483647
#define IQ 127773
#define IR 2836
#define NTAB 32
#define EPS 1.2e-7
#define NDIV (1 + (IM - 1) / NTAB)
#define AM (1.0 / IM)
#define RNMX (1.0 - EPS)
static long lran1( void )
{
static long iy = 0;
static long iv[NTAB];
int j;
long k;
if( idum <= 0 || !iy )
{
if( -(idum) < 1 ) idum = 1;
else idum = -(idum);
for( j = NTAB + 7; j >= 0; j-- )
{
k = (idum) / IQ;
idum = IA * (idum - k * IQ) - IR * k;
if( idum < 0 ) idum += IM;
if( j < NTAB ) iv[j] = idum;
}
iy = iv[0];
}
k = (idum) / IQ;
idum = IA * (idum - k * IQ) - IR * k;
if( idum < 0 ) idum += IM;
j = iy / NDIV;
iy = iv[j];
iv[j] = idum;
return iy;
}
// fran1 -- return a random floating-point number on the interval [0,1]
static float fran1( void )
{
float temp = (float)AM * lran1();
if( temp > RNMX )
return (float)RNMX;
return temp;
}
void COM_SetRandomSeed( long lSeed )
{
if( lSeed ) idum = lSeed;
else idum = -time( NULL );
if( 1000 < idum )
idum = -idum;
else if( -1000 < idum )
idum -= 22261048;
}
float COM_RandomFloat( float flLow, float flHigh )
{
float fl;
if( idum == 0 ) COM_SetRandomSeed( 0 );
fl = fran1(); // float in [0,1]
return (fl * (flHigh - flLow)) + flLow; // float in [low, high)
}
long COM_RandomLong( long lLow, long lHigh )
{
dword maxAcceptable;
dword n, x = lHigh - lLow + 1;
if( idum == 0 ) COM_SetRandomSeed( 0 );
if( x <= 0 || MAX_RANDOM_RANGE < x - 1 )
return lLow;
// The following maps a uniform distribution on the interval [0, MAX_RANDOM_RANGE]
// to a smaller, client-specified range of [0,x-1] in a way that doesn't bias
// the uniform distribution unfavorably. Even for a worst case x, the loop is
// guaranteed to be taken no more than half the time, so for that worst case x,
// the average number of times through the loop is 2. For cases where x is
// much smaller than MAX_RANDOM_RANGE, the average number of times through the
// loop is very close to 1.
maxAcceptable = MAX_RANDOM_RANGE - ((MAX_RANDOM_RANGE + 1) % x );
do
{
n = lran1();
} while( n > maxAcceptable );
return lLow + (n % x);
}
/*
==============
COM_IsSingleChar

View File

@ -150,6 +150,7 @@ extern convar_t *cl_allow_levelshots;
extern convar_t *vid_displayfrequency;
extern convar_t *mod_allow_materials;
extern convar_t *host_limitlocal;
extern convar_t *host_framerate;
extern convar_t *host_maxfps;
/*
@ -662,8 +663,8 @@ CLIENT / SERVER SYSTEMS
*/
void CL_Init( void );
void CL_Shutdown( void );
void Host_ClientBegin( void );
void Host_ClientFrame( void );
void Host_RenderFrame( void );
qboolean CL_Active( void );
void SV_Init( void );
@ -822,7 +823,6 @@ void R_ClearAllDecals( void );
void R_ClearStaticEntities( void );
qboolean S_StreamGetCurrentState( char *currentTrack, char *loopTrack, int *position );
struct cl_entity_s *CL_GetEntityByIndex( int index );
struct cl_entity_s *CL_GetLocalPlayer( void );
struct player_info_s *CL_GetPlayerInfo( int playerIndex );
void CL_ServerCommand( qboolean reliable, char *fmt, ... );
const char *CL_MsgInfo( int cmd );
@ -880,8 +880,8 @@ qboolean Cmd_CheckMapsList( qboolean fRefresh );
qboolean Cmd_AutocompleteName( const char *source, char *buffer, size_t bufsize );
void Cmd_AutoComplete( char *complete_string );
void COM_SetRandomSeed( long lSeed );
long Com_RandomLong( long lMin, long lMax );
float Com_RandomFloat( float fMin, float fMax );
long COM_RandomLong( long lMin, long lMax );
float COM_RandomFloat( float fMin, float fMax );
void TrimSpace( const char *source, char *dest );
const byte *GL_TextureData( unsigned int texnum );
void GL_FreeImage( const char *name );

View File

@ -2040,7 +2040,7 @@ void Con_DrawVersion( void )
if( !host.force_draw_version )
{
if(( cls.key_dest != key_menu && !draw_version ) || gl_overview->value == 2 )
if(( cls.key_dest != key_menu && !draw_version ) || CL_IsDevOverviewMode() == 2 )
return;
}
@ -2076,10 +2076,10 @@ void Con_RunConsole( void )
}
else con.showlines = 0; // none visible
lines_per_frame = bound( 1, fabs( scr_conspeed->value ) * host.realframetime, glState.height );
if( cls.state == ca_connecting || cls.state == ca_connected )
lines_per_frame = 0;
host.realframetime = ( MAX_FPS / host_maxfps->value ) * MIN_FRAMETIME;
lines_per_frame = bound( 1, fabs( scr_conspeed->value ) * host.realframetime, glState.height );
if( con.showlines < con.vislines )
{

View File

@ -408,7 +408,7 @@ void Cvar_DirectSet( convar_t *var, const char *value )
// check value
if( !value )
{
if( !FBitSet( var->flags, FCVAR_EXTENDED ))
if( !FBitSet( var->flags, FCVAR_EXTENDED|FCVAR_ALLOCATED ))
{
MsgDev( D_INFO, "%s has no default value and can't be reset.\n", var->name );
return;

View File

@ -258,10 +258,10 @@ void Host_Exec_f( void )
return;
}
// don't execute listenserver.cfg in singleplayer
if( !Q_stricmp( Cvar_VariableString( "lservercfgfile" ), Cmd_Argv( 1 )))
if( !Q_stricmp( "settings.rc", Cmd_Argv( 1 )))
{
if( Cvar_VariableInteger( "maxplayers" ) == 1 )
// don't execute settings.rc in singleplayer
if( SV_GetMaxClients() == 1 )
return;
}
@ -605,6 +605,7 @@ void Host_Frame( float time )
Host_InputFrame (); // input frame
Host_GetCommands (); // dedicated in
Host_ClientBegin (); // begin client
Host_ServerFrame (); // server frame
Host_ClientFrame (); // client frame

View File

@ -412,7 +412,7 @@ char *Info_FindLargestKey( char *s )
qboolean Info_SetValueForStarKey( char *s, const char *key, const char *value, int maxsize )
{
char new[1024], *v;
int c, team, name;
int c, team;
if( Q_strstr( key, "\\" ) || Q_strstr( value, "\\" ))
{
@ -474,22 +474,12 @@ qboolean Info_SetValueForStarKey( char *s, const char *key, const char *value, i
s += Q_strlen( s );
v = new;
name = ( Q_stricmp( key, "name" ) == 0 ) ? true : false;
team = ( Q_stricmp( key, "team" ) == 0 ) ? true : false;
while( *v )
{
c = (byte)*v++;
// only clients allows highbits on name
if( !name )
{
c &= 127; // strip high bits
if( c < 32 && c > 127 )
continue;
if( team ) c = Q_tolower( c );
}
if( team ) c = Q_tolower( c );
if( c > 13 ) *s++ = c;
}
*s = 0;

View File

@ -127,6 +127,7 @@ void Mod_SetupHulls( vec3_t mins[MAX_MAP_HULLS], vec3_t maxs[MAX_MAP_HULLS] );
void Mod_GetBounds( int handle, vec3_t mins, vec3_t maxs );
void Mod_GetFrames( int handle, int *numFrames );
void Mod_LoadWorld( const char *name, uint *checksum, qboolean multiplayer );
int Mod_FrameCount( model_t *mod );
void Mod_FreeUnused( void );
void *Mod_Calloc( int number, size_t size );
void *Mod_CacheCheck( struct cache_user_s *c );

View File

@ -3229,6 +3229,29 @@ void Mod_GetFrames( int handle, int *numFrames )
if( *numFrames < 1 ) *numFrames = 1;
}
/*
===================
Mod_FrameCount
model_t as input
===================
*/
int Mod_FrameCount( model_t *mod )
{
if( !mod ) return 1;
switch( mod->type )
{
case mod_sprite:
case mod_studio:
return mod->numframes;
case mod_brush:
return 2; // regular and alternate animation
default:
return 1;
}
}
/*
===================
Mod_GetBounds

View File

@ -106,7 +106,7 @@ void Netchan_Init( void )
int port;
// pick a port value that should be nice and random
port = Com_RandomLong( 1, 65535 );
port = COM_RandomLong( 1, 65535 );
net_showpackets = Cvar_Get ("net_showpackets", "0", 0, "show network packets" );
net_chokeloopback = Cvar_Get( "net_chokeloop", "0", 0, "apply bandwidth choke to loopback packets" );

View File

@ -1668,7 +1668,7 @@ void MSG_WriteDeltaEntity( entity_state_t *from, entity_state_t *to, sizebuf_t *
if( from == NULL ) return;
// a NULL to is a delta remove message
MSG_WriteWord( msg, from->number );
MSG_WriteUBitLong( msg, from->number, MAX_ENTITY_BITS );
// fRemoveType:
// 0 - keep alive, has delta-update
@ -1686,7 +1686,7 @@ void MSG_WriteDeltaEntity( entity_state_t *from, entity_state_t *to, sizebuf_t *
if( to->number < 0 || to->number >= GI->max_edicts )
Host_Error( "MSG_WriteDeltaEntity: Bad entity number: %i\n", to->number );
MSG_WriteWord( msg, to->number );
MSG_WriteUBitLong( msg, to->number, MAX_ENTITY_BITS );
MSG_WriteUBitLong( msg, 0, 2 ); // alive
if( force || ( to->entityType != from->entityType ))
@ -1697,21 +1697,18 @@ void MSG_WriteDeltaEntity( entity_state_t *from, entity_state_t *to, sizebuf_t *
}
else MSG_WriteOneBit( msg, 0 );
if( to->entityType == ENTITY_NORMAL )
{
if( player )
{
dt = Delta_FindStruct( "entity_state_player_t" );
}
else
{
dt = Delta_FindStruct( "entity_state_t" );
}
}
else if( to->entityType == ENTITY_BEAM )
if( FBitSet( to->entityType, ENTITY_BEAM ))
{
dt = Delta_FindStruct( "custom_entity_state_t" );
}
else if( player )
{
dt = Delta_FindStruct( "entity_state_player_t" );
}
else
{
dt = Delta_FindStruct( "entity_state_t" );
}
Assert( dt && dt->bInitialized );
@ -1780,21 +1777,18 @@ qboolean MSG_ReadDeltaEntity( sizebuf_t *msg, entity_state_t *from, entity_state
if( MSG_ReadOneBit( msg ))
to->entityType = MSG_ReadUBitLong( msg, 2 );
if( to->entityType == ENTITY_NORMAL )
{
if( player )
{
dt = Delta_FindStruct( "entity_state_player_t" );
}
else
{
dt = Delta_FindStruct( "entity_state_t" );
}
}
else if( to->entityType == ENTITY_BEAM )
if( FBitSet( to->entityType, ENTITY_BEAM ))
{
dt = Delta_FindStruct( "custom_entity_state_t" );
}
else if( player )
{
dt = Delta_FindStruct( "entity_state_player_t" );
}
else
{
dt = Delta_FindStruct( "entity_state_t" );
}
Assert( dt && dt->bInitialized );

View File

@ -795,7 +795,7 @@ static qboolean NET_LagPacket( qboolean newdata, netsrc_t sock, netadr_t *from,
}
else
{
if( Com_RandomLong( 0, 100 ) <= net_fakeloss->value )
if( COM_RandomLong( 0, 100 ) <= net_fakeloss->value )
return false;
}
}

View File

@ -26,6 +26,7 @@ typedef int (*pfnIgnore)( physent_t *pe ); // custom trace filter
void Pmove_Init( void );
void PM_InitBoxHull( void );
hull_t *PM_HullForBsp( physent_t *pe, playermove_t *pmove, float *offset );
qboolean PM_RecursiveHullCheck( hull_t *hull, int num, float p1f, float p2f, vec3_t p1, vec3_t p2, pmtrace_t *trace );
pmtrace_t PM_PlayerTraceExt( playermove_t *pm, vec3_t p1, vec3_t p2, int flags, int numents, physent_t *ents, int ignore_pe, pfnIgnore pmFilter );
int PM_TestPlayerPosition( playermove_t *pmove, vec3_t pos, pmtrace_t *ptrace, pfnIgnore pmFilter );
int PM_HullPointContents( hull_t *hull, int num, const vec3_t p );

View File

@ -94,7 +94,9 @@ GNU General Public License for more details.
#define clc_requestcvarvalue2 10
#define clc_lastmsg 10 // end client messages
#define MAX_VISIBLE_PACKET 1024 // 1024 visible entities per frame (hl1 has 256)
#define MAX_VISIBLE_PACKET_BITS 10
#define MAX_VISIBLE_PACKET (1<<MAX_VISIBLE_PACKET_BITS) // 1024 visible entities per frame (hl1 has 256)
#define MAX_VISIBLE_PACKET_VIS_BYTES ((MAX_VISIBLE_PACKET + 7 ) / 8)
// additional protocol data
#define MAX_CLIENT_BITS 5

View File

@ -1,118 +0,0 @@
/*
random.c - random generator
Copyright (C) 2007 Uncle Mike
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
*/
#include "common.h"
static long idum = 0;
#define MAX_RANDOM_RANGE 0x7FFFFFFFUL
#define IA 16807
#define IM 2147483647
#define IQ 127773
#define IR 2836
#define NTAB 32
#define EPS 1.2e-7
#define NDIV (1 + (IM - 1) / NTAB)
#define AM (1.0 / IM)
#define RNMX (1.0 - EPS)
void COM_SetRandomSeed( long lSeed )
{
if( lSeed ) idum = lSeed;
else idum = -time( NULL );
if( 1000 < idum )
idum = -idum;
else if( -1000 < idum )
idum -= 22261048;
}
long lran1( void )
{
static long iy = 0;
static long iv[NTAB];
int j;
long k;
if( idum <= 0 || !iy )
{
if( -(idum) < 1 ) idum = 1;
else idum = -(idum);
for( j = NTAB + 7; j >= 0; j-- )
{
k = (idum) / IQ;
idum = IA * (idum - k * IQ) - IR * k;
if( idum < 0 ) idum += IM;
if( j < NTAB ) iv[j] = idum;
}
iy = iv[0];
}
k = (idum) / IQ;
idum = IA * (idum - k * IQ) - IR * k;
if( idum < 0 ) idum += IM;
j = iy / NDIV;
iy = iv[j];
iv[j] = idum;
return iy;
}
// fran1 -- return a random floating-point number on the interval [0,1]
float fran1( void )
{
float temp = (float)AM * lran1();
if( temp > RNMX )
return (float)RNMX;
return temp;
}
float Com_RandomFloat( float flLow, float flHigh )
{
float fl;
if( idum == 0 ) COM_SetRandomSeed( 0 );
fl = fran1(); // float in [0,1]
return (fl * (flHigh - flLow)) + flLow; // float in [low, high)
}
long Com_RandomLong( long lLow, long lHigh )
{
dword maxAcceptable;
dword n, x = lHigh - lLow + 1;
if( idum == 0 ) COM_SetRandomSeed( 0 );
if( x <= 0 || MAX_RANDOM_RANGE < x - 1 )
return lLow;
// The following maps a uniform distribution on the interval [0, MAX_RANDOM_RANGE]
// to a smaller, client-specified range of [0,x-1] in a way that doesn't bias
// the uniform distribution unfavorably. Even for a worst case x, the loop is
// guaranteed to be taken no more than half the time, so for that worst case x,
// the average number of times through the loop is 2. For cases where x is
// much smaller than MAX_RANDOM_RANGE, the average number of times through the
// loop is very close to 1.
maxAcceptable = MAX_RANDOM_RANGE - ((MAX_RANDOM_RANGE + 1) % x );
do
{
n = lran1();
} while( n > maxAcceptable );
return lLow + (n % x);
}

View File

@ -408,10 +408,6 @@ SOURCE=.\common\pm_trace.c
# End Source File
# Begin Source File
SOURCE=.\common\random.c
# End Source File
# Begin Source File
SOURCE=.\client\s_backend.c
# End Source File
# Begin Source File

View File

@ -103,7 +103,7 @@ typedef struct ui_enginefuncs_s
struct cl_entity_s* (*pfnGetPlayerModel)( void ); // for drawing playermodel previews
void (*pfnSetModel)( struct cl_entity_s *ed, const char *path );
void (*pfnClearScene)( void );
void (*pfnRenderScene)( const struct ref_params_s *fd );
void (*pfnRenderScene)( const struct ref_viewpass_s *rvp );
int (*CL_CreateVisibleEntity)( int type, struct cl_entity_s *ent );
// misc handlers

View File

@ -174,8 +174,8 @@ typedef struct server_s
model_t *worldmodel; // pointer to world
uint checksum; // for catching cheater maps
qboolean simulating;
qboolean write_bad_message; // just for debug
qboolean simulating; // physics is running
qboolean paused;
} server_t;

View File

@ -1110,7 +1110,6 @@ void SV_PutClientInServer( sv_client_t *cl )
MSG_WriteBitAngle( &cl->netchan.message, ent->v.angles[2], 16 );
ent->v.fixangle = 0;
}
SetBits( ent->v.effects, EF_NOINTERP );
// reset weaponanim
MSG_BeginServerCmd( &cl->netchan.message, svc_weaponanim );

View File

@ -22,6 +22,7 @@ typedef struct
{
int num_entities;
entity_state_t entities[MAX_VISIBLE_PACKET];
byte sended[MAX_VISIBLE_PACKET_VIS_BYTES];
} sv_ents_t;
int c_fullsend; // just a debug counter
@ -99,9 +100,8 @@ static void SV_AddEntitiesToPacket( edict_t *pViewEnt, edict_t *pClient, client_
if( !SV_IsValidEdict( ent ))
continue;
// don't double add an entity through portals (already added)
// HACHACK: use pushmsec to keep net_framenum
if( ent->v.pushmsec == sv.net_framenum )
// don't double add an entity through portals (in case this already added)
if( CHECKVISBIT( ents->sended, NUM_FOR_EDICT( ent )))
continue;
if( FBitSet( ent->v.effects, EF_REQUEST_PHS ))
@ -115,7 +115,7 @@ static void SV_AddEntitiesToPacket( edict_t *pViewEnt, edict_t *pClient, client_
if( svgame.dllFuncs.pfnAddToFullPack( state, e, ent, pClient, sv.hostflags, ( netclient != NULL ), pset ))
{
// to prevent adds it twice through portals
ent->v.pushmsec = sv.net_framenum;
SETVISBIT( ents->sended, NUM_FOR_EDICT( ent ));
if( netclient && netclient->modelindex )
{
@ -179,41 +179,41 @@ void SV_EmitPacketEntities( sv_client_t *cl, client_frame_t *to, sizebuf_t *msg
{
entity_state_t *oldent, *newent;
int oldindex, newindex;
int from_num_entities;
int oldnum, newnum;
int oldmax;
client_frame_t *from;
// this is the frame that we are going to delta update from
if( cl->delta_sequence != -1 )
{
from = &cl->frames[cl->delta_sequence & SV_UPDATE_MASK];
from_num_entities = from->num_entities;
oldmax = from->num_entities;
// the snapshot's entities may still have rolled off the buffer, though
if( from->first_entity <= ( svs.next_client_entities - svs.num_client_entities ))
{
MsgDev( D_WARN, "%s: delta request from out of date entities.\n", cl->name );
from = NULL;
from_num_entities = 0;
MSG_BeginServerCmd( msg, svc_packetentities );
MSG_WriteWord( msg, to->num_entities );
MSG_WriteUBitLong( msg, to->num_entities, MAX_VISIBLE_PACKET_BITS );
from = NULL;
oldmax = 0;
}
else
{
MSG_BeginServerCmd( msg, svc_deltapacketentities );
MSG_WriteWord( msg, to->num_entities );
MSG_WriteUBitLong( msg, to->num_entities, MAX_VISIBLE_PACKET_BITS );
MSG_WriteByte( msg, cl->delta_sequence );
}
}
else
{
from = NULL;
from_num_entities = 0;
oldmax = 0;
MSG_BeginServerCmd( msg, svc_packetentities );
MSG_WriteWord( msg, to->num_entities );
MSG_WriteUBitLong( msg, to->num_entities, MAX_VISIBLE_PACKET_BITS );
}
newent = NULL;
@ -221,7 +221,7 @@ void SV_EmitPacketEntities( sv_client_t *cl, client_frame_t *to, sizebuf_t *msg
newindex = 0;
oldindex = 0;
while( newindex < to->num_entities || oldindex < from_num_entities )
while( newindex < to->num_entities || oldindex < oldmax )
{
if( newindex >= to->num_entities )
{
@ -233,7 +233,7 @@ void SV_EmitPacketEntities( sv_client_t *cl, client_frame_t *to, sizebuf_t *msg
newnum = newent->number;
}
if( oldindex >= from_num_entities )
if( oldindex >= oldmax )
{
oldnum = MAX_ENTNUMBER;
}
@ -264,11 +264,11 @@ void SV_EmitPacketEntities( sv_client_t *cl, client_frame_t *to, sizebuf_t *msg
if( newnum > oldnum )
{
qboolean force;
qboolean force = false;
// check if entity completely removed from server
if( EDICT_NUM( oldent->number )->free )
force = true; // entity completely removed from server
else force = false; // just removed from delta-message
force = true;
// remove from message
MSG_WriteDeltaEntity( oldent, NULL, msg, force, false, sv.time );
@ -277,7 +277,7 @@ void SV_EmitPacketEntities( sv_client_t *cl, client_frame_t *to, sizebuf_t *msg
}
}
MSG_WriteWord( msg, 0 ); // end of packetentities
MSG_WriteUBitLong( msg, 0, MAX_ENTITY_BITS ); // end of packetentities
}
/*
@ -473,19 +473,17 @@ void SV_WriteClientdataToMessage( sv_client_t *cl, sizebuf_t *msg )
MSG_WriteBitAngle( msg, clent->v.angles[0], 16 );
MSG_WriteBitAngle( msg, clent->v.angles[1], 16 );
MSG_WriteBitAngle( msg, clent->v.angles[2], 16 );
clent->v.effects |= EF_NOINTERP;
break;
case 2:
MSG_BeginServerCmd( msg, svc_addangle );
MSG_WriteBitAngle( msg, clent->v.avelocity[1], 16 );
clent->v.avelocity[1] = 0.0f;
MSG_WriteBitAngle( msg, clent->v.avelocity[YAW], 16 );
clent->v.avelocity[YAW] = 0.0f;
break;
}
clent->v.fixangle = 0; // reset fixangle
memset( &frame->clientdata, 0, sizeof( frame->clientdata ));
clent->v.pushmsec = 0; // reset net framenum
// update clientdata_t
svgame.dllFuncs.pfnUpdateClientData( clent, FBitSet( cl->flags, FCL_LOCAL_WEAPONS ), &frame->clientdata );
@ -550,6 +548,7 @@ void SV_WriteEntitiesToClient( sv_client_t *cl, sizebuf_t *msg )
send_pings = SV_ShouldUpdatePing( cl );
memset( frame_ents.sended, 0, sizeof( frame_ents.sended ));
ClearBits( sv.hostflags, SVF_MERGE_VISIBILITY );
sv.net_framenum++; // now all portal-through entities are invalidate
@ -576,15 +575,15 @@ void SV_WriteEntitiesToClient( sv_client_t *cl, sizebuf_t *msg )
// it will break all connected clients, but it takes more than one week to overflow it
if(( (uint)svs.next_client_entities ) + frame_ents.num_entities >= 0x7FFFFFFE )
{
// just reset counter
svs.next_client_entities = 0;
// delta is broken now, cannot keep connected clients
SV_FinalMessage( "Server is running to long, reconnecting!", true );
// delta is broken for now, cannot keep connected clients
SV_FinalMessage( "Server will restart due delta is outdated", true );
}
// copy the entity states out
frame->num_entities = 0;
frame->first_entity = svs.next_client_entities;
frame->num_entities = 0;
for( i = 0; i < frame_ents.num_entities; i++ )
{
@ -699,7 +698,7 @@ void SV_UpdateToReliableMessages( void )
}
// 1% chanse for simulate random network bugs
if( sv.write_bad_message && Com_RandomLong( 0, 512 ) == 404 )
if( sv.write_bad_message && COM_RandomLong( 0, 512 ) == 404 )
{
// just for network debugging (send only for local client)
MSG_BeginServerCmd( &sv.reliable_datagram, svc_bad );

View File

@ -1026,7 +1026,7 @@ void SV_BaselineForEntity( edict_t *pEdict )
svgame.dllFuncs.pfnCreateBaseline( player, baseline.number, &baseline, pEdict, modelindex, mins, maxs );
// set entity type
if( pEdict->v.flags & FL_CUSTOMENTITY )
if( FBitSet( pEdict->v.flags, FL_CUSTOMENTITY ))
baseline.entityType = ENTITY_BEAM;
else baseline.entityType = ENTITY_NORMAL;
@ -3453,7 +3453,7 @@ void pfnRunPlayerMove( edict_t *pClient, const float *v_angle, float fmove, floa
cmd.impulse = impulse;
cmd.msec = msec;
seed = Com_RandomLong( 0, 0x7fffffff ); // full range
seed = COM_RandomLong( 0, 0x7fffffff ); // full range
SV_RunCmd( cl, &cmd, seed );
@ -4045,8 +4045,9 @@ int pfnCreateInstancedBaseline( int classname, struct entity_state_s *baseline )
if( !baseline ) return -1;
i = sv.instanced.count;
if( i > 62 ) return 0;
if( i > 64 ) return 0;
Msg( "Added instanced baseline: %s [%i]\n", STRING( classname ), i );
sv.instanced.classnames[i] = classname;
sv.instanced.baselines[i] = *baseline;
sv.instanced.count++;
@ -4444,8 +4445,8 @@ static enginefuncs_t gEngfuncs =
CRC32_ProcessBuffer,
CRC32_ProcessByte,
pfnCRC32_Final,
Com_RandomLong,
Com_RandomFloat,
COM_RandomLong,
COM_RandomFloat,
pfnSetView,
pfnTime,
pfnCrosshairAngle,

View File

@ -383,15 +383,8 @@ void SV_ActivateServer( void )
if( svs.maxclients > 1 )
{
// listenserver is executed on every map change in multiplayer
if( host.type != HOST_DEDICATED )
{
#if 0
// temporare disable because it's broken TFC multiplayer
char *plservercfgfile = Cvar_VariableString( "lservercfgfile" );
if( *plservercfgfile ) Cbuf_AddText( va( "exec %s\n", plservercfgfile ));
#endif
}
char *mapchangecfgfile = Cvar_VariableString( "mapchangecfgfile" );
if( *mapchangecfgfile ) Cbuf_AddText( va( "exec %s\n", mapchangecfgfile ));
if( public_server->value )
{
@ -399,12 +392,6 @@ void SV_ActivateServer( void )
Master_Add( );
}
}
// mapchangecfgfile
{
char *mapchangecfgfile = Cvar_VariableString( "mapchangecfgfile" );
if( *mapchangecfgfile ) Cbuf_AddText( va( "exec %s\n", mapchangecfgfile ));
}
}
/*

View File

@ -54,9 +54,6 @@ CVAR_DEFINE( sv_consistency, "mp_consistency", "1", FCVAR_SERVER, "enbale consis
// game-related cvars
CVAR_DEFINE_AUTO( mapcyclefile, "mapcycle.txt", 0, "name of multiplayer map cycle configuration file" );
CVAR_DEFINE_AUTO( motdfile, "motd.txt", 0, "name of 'message of the day' file" );
CVAR_DEFINE_AUTO( servercfgfile, "server.cfg", 0, "name of dedicated server configuration file" );
CVAR_DEFINE_AUTO( lservercfgfile, "listenserver.cfg", 0, "name of listen server configuration file" );
CVAR_DEFINE_AUTO( mapchangecfgfile, "", 0, "name of config file for map changing rules" );
CVAR_DEFINE_AUTO( logsdir, "logs", 0, "place to store multiplayer logs" );
CVAR_DEFINE_AUTO( bannedcfgfile, "banned.cfg", 0, "name of list of banned users" );
CVAR_DEFINE_AUTO( deathmatch, "0", 0, "deathmatch mode in multiplayer game" );
@ -324,7 +321,7 @@ void SV_ReadPackets( void )
if( Netchan_Process( &cl->netchan, &net_message ))
{
if( svs.maxclients == 1 || cl->state != cs_spawned )
if(( svs.maxclients == 1 && !host_limitlocal->value ) || ( cl->state != cs_spawned ))
SetBits( cl->flags, FCL_SEND_NET_MESSAGE ); // reply at end of frame
// this is a valid, sequenced packet, so process it
@ -714,7 +711,10 @@ void SV_Init( void )
Cvar_Get( "sv_alltalk", "1", 0, "allow to talking for all players (legacy, unused)" );
Cvar_Get( "sv_allow_PhysX", "1", FCVAR_ARCHIVE, "allow XashXT to usage PhysX engine" ); // XashXT cvar
Cvar_Get( "sv_precache_meshes", "1", FCVAR_ARCHIVE, "cache SOLID_CUSTOM meshes before level loading" ); // Paranoia 2 cvar
Cvar_Get ("mapcyclefile", "mapcycle.txt", 0, "name of config file for map changing rules" );
Cvar_Get ("servercfgfile","server.cfg", 0, "name of dedicated server configuration file" );
Cvar_Get ("lservercfgfile","listenserver.cfg", 0, "name of listen server configuration file" );
Cvar_RegisterVariable (&sv_zmax);
Cvar_RegisterVariable (&sv_wateramp);
Cvar_RegisterVariable (&sv_skycolor_r);
@ -736,9 +736,6 @@ void SV_Init( void )
Cvar_RegisterVariable (&showtriggers);
Cvar_RegisterVariable (&sv_aim);
Cvar_RegisterVariable (&mapcyclefile);
Cvar_RegisterVariable (&servercfgfile);
Cvar_RegisterVariable (&lservercfgfile);
Cvar_RegisterVariable (&motdfile);
Cvar_RegisterVariable (&deathmatch);
Cvar_RegisterVariable (&coop);
@ -788,6 +785,11 @@ void SV_Init( void )
Cvar_RegisterVariable (&sv_consistency);
sv_novis = Cvar_Get( "sv_novis", "0", 0, "force to ignore server visibility" );
Cvar_RegisterVariable (&violence_ablood);
Cvar_RegisterVariable (&violence_hblood);
Cvar_RegisterVariable (&violence_agibs);
Cvar_RegisterVariable (&violence_hgibs);
// when we in developer-mode automatically turn cheats on
if( host.developer > 1 ) Cvar_SetValue( "sv_cheats", 1.0f );

View File

@ -145,7 +145,7 @@ void SV_WaterMove( edict_t *ent )
if( flags & FL_INWATER )
{
// leave the water.
switch( Com_RandomLong( 0, 3 ))
switch( COM_RandomLong( 0, 3 ))
{
case 0:
SV_StartSound( ent, CHAN_BODY, "player/pl_wade1.wav", 1.0f, ATTN_NORM, 0, 100 );
@ -192,7 +192,7 @@ void SV_WaterMove( edict_t *ent )
if( watertype == CONTENTS_WATER )
{
// entering the water
switch( Com_RandomLong( 0, 3 ))
switch( COM_RandomLong( 0, 3 ))
{
case 0:
SV_StartSound( ent, CHAN_BODY, "player/pl_wade1.wav", 1.0f, ATTN_NORM, 0, 100 );
@ -482,7 +482,7 @@ void SV_NewChaseDir( edict_t *actor, vec3_t destination, float dist )
}
// try other directions
if( Com_RandomLong( 0, 1 ) != 0 || fabs( deltay ) > fabs( deltax ))
if( COM_RandomLong( 0, 1 ) != 0 || fabs( deltay ) > fabs( deltax ))
{
tempdir = d[1];
d[1] = d[2];
@ -500,7 +500,7 @@ void SV_NewChaseDir( edict_t *actor, vec3_t destination, float dist )
return;
// fine, just run somewhere.
if( Com_RandomLong( 0, 1 ) != 1 )
if( COM_RandomLong( 0, 1 ) != 1 )
{
for( tempdir = 0; tempdir <= 315.0f; tempdir += 45.0f )
{

View File

@ -587,8 +587,8 @@ void SV_InitClientMove( void )
svgame.pmove->PM_HullPointContents = pfnHullPointContents;
svgame.pmove->PM_PlayerTrace = pfnPlayerTrace;
svgame.pmove->PM_TraceLine = pfnTraceLine;
svgame.pmove->RandomLong = Com_RandomLong;
svgame.pmove->RandomFloat = Com_RandomFloat;
svgame.pmove->RandomLong = COM_RandomLong;
svgame.pmove->RandomFloat = COM_RandomFloat;
svgame.pmove->PM_GetModelType = pfnGetModelType;
svgame.pmove->PM_GetModelBounds = pfnGetModelBounds;
svgame.pmove->PM_HullForBsp = pfnHullForBsp;

View File

@ -188,7 +188,7 @@ hull_t *SV_HullForBsp( edict_t *ent, const vec3_t mins, const vec3_t maxs, float
#ifdef RANDOM_HULL_NULLIZATION
// author: The FiEctro
hull = &model->hulls[Com_RandomLong( 0, 0 )];
hull = &model->hulls[COM_RandomLong( 0, 0 )];
#endif
if( sv_quakehulls->value == 1 )
{
@ -995,7 +995,7 @@ void SV_ClipMoveToEntity( edict_t *ent, const vec3_t start, vec3_t mins, vec3_t
if( hullcount == 1 )
{
SV_RecursiveHullCheck( hull, hull->firstclipnode, 0.0f, 1.0f, start_l, end_l, trace );
PM_RecursiveHullCheck( hull, hull->firstclipnode, 0.0f, 1.0f, start_l, end_l, (pmtrace_t *)trace );
}
else
{
@ -1008,7 +1008,7 @@ void SV_ClipMoveToEntity( edict_t *ent, const vec3_t start, vec3_t mins, vec3_t
trace_hitbox.fraction = 1.0;
trace_hitbox.allsolid = 1;
SV_RecursiveHullCheck( &hull[i], hull[i].firstclipnode, 0.0f, 1.0f, start_l, end_l, &trace_hitbox );
PM_RecursiveHullCheck( &hull[i], hull[i].firstclipnode, 0.0f, 1.0f, start_l, end_l, (pmtrace_t *)&trace_hitbox );
if( i == 0 || trace_hitbox.allsolid || trace_hitbox.startsolid || trace_hitbox.fraction < trace->fraction )
{

View File

@ -51,7 +51,7 @@ typedef struct
int num_models;
char currentModel[CS_SIZE];
ref_params_t refdef;
ref_viewpass_t rvp;
cl_entity_t *ent;
menuFramework_s menu;
@ -83,11 +83,12 @@ UI_PlayerSetup_CalcFov
assume refdef is valid
=================
*/
static void UI_PlayerSetup_CalcFov( ref_params_t *fd )
static void UI_PlayerSetup_CalcFov( ref_viewpass_t *rvp )
{
float x = fd->viewport[2] / tan( DEG2RAD( fd->fov_x ) * 0.5f );
float half_fov_y = atan( fd->viewport[3] / x );
fd->fov_y = RAD2DEG( half_fov_y ) * 2;
rvp->fov_x = 40.0f;
float x = rvp->viewport[2] / tan( DEG2RAD( rvp->fov_x ) * 0.5f );
float half_fov_y = atan( rvp->viewport[3] / x );
rvp->fov_y = RAD2DEG( half_fov_y ) * 2;
}
/*
@ -319,14 +320,12 @@ static void UI_PlayerSetup_Ownerdraw( void *self )
{
R_ClearScene ();
// update renderer timings
uiPlayerSetup.refdef.time = gpGlobals->time;
uiPlayerSetup.refdef.frametime = gpGlobals->frametime;
uiPlayerSetup.ent->curstate.body = 0; // clearing body each frame
// clearing body for each frame
uiPlayerSetup.ent->curstate.body = 0;
// draw the player model
R_AddEntity( ET_NORMAL, uiPlayerSetup.ent );
R_RenderFrame( &uiPlayerSetup.refdef );
R_RenderFrame( &uiPlayerSetup.rvp );
}
}
@ -487,16 +486,14 @@ static void UI_PlayerSetup_Init( void )
UI_AddItem( &uiPlayerSetup.menu, (void *)&uiPlayerSetup.showModels );
UI_AddItem( &uiPlayerSetup.menu, (void *)&uiPlayerSetup.hiModels );
}
// setup render and actor
uiPlayerSetup.refdef.fov_x = 40;
// NOTE: must be called after UI_AddItem whan we sure what UI_ScaleCoords is done
uiPlayerSetup.refdef.viewport[0] = uiPlayerSetup.view.generic.x;
uiPlayerSetup.refdef.viewport[1] = uiPlayerSetup.view.generic.y;
uiPlayerSetup.refdef.viewport[2] = uiPlayerSetup.view.generic.width;
uiPlayerSetup.refdef.viewport[3] = uiPlayerSetup.view.generic.height;
uiPlayerSetup.rvp.viewport[0] = uiPlayerSetup.view.generic.x;
uiPlayerSetup.rvp.viewport[1] = uiPlayerSetup.view.generic.y;
uiPlayerSetup.rvp.viewport[2] = uiPlayerSetup.view.generic.width;
uiPlayerSetup.rvp.viewport[3] = uiPlayerSetup.view.generic.height;
UI_PlayerSetup_CalcFov( &uiPlayerSetup.refdef );
UI_PlayerSetup_CalcFov( &uiPlayerSetup.rvp );
uiPlayerSetup.ent = GET_MENU_EDICT ();
if( !uiPlayerSetup.ent )
@ -518,7 +515,7 @@ static void UI_PlayerSetup_Init( void )
uiPlayerSetup.ent->latched.prevcontroller[1] = 127;
uiPlayerSetup.ent->latched.prevcontroller[2] = 127;
uiPlayerSetup.ent->latched.prevcontroller[3] = 127;
uiPlayerSetup.ent->origin[0] = uiPlayerSetup.ent->curstate.origin[0] = 45.0f / tan( DEG2RAD( uiPlayerSetup.refdef.fov_y / 2.0f ));
uiPlayerSetup.ent->origin[0] = uiPlayerSetup.ent->curstate.origin[0] = 45.0f / tan( DEG2RAD( uiPlayerSetup.rvp.fov_y / 2.0f ));
uiPlayerSetup.ent->origin[2] = uiPlayerSetup.ent->curstate.origin[2] = 2.0f;
uiPlayerSetup.ent->angles[1] = uiPlayerSetup.ent->curstate.angles[1] = 180.0f;
uiPlayerSetup.ent->player = true; // yes, draw me as playermodel