07 Dec 2009

This commit is contained in:
g-cont 2009-12-07 00:00:00 +03:00 committed by Alibek Omarov
parent 94d8705b3b
commit b3b6f79adb
30 changed files with 389 additions and 368 deletions

View File

@ -21,7 +21,7 @@
#define GetScreenInfo (*g_engfuncs.pfnGetScreenInfo)
#define SPR_Load (*g_engfuncs.pfnSPR_Load)
#define TEX_Load( x ) (*g_engfuncs.pfnLoadShader)( x, false )
#define TEX_Load( x ) (*g_engfuncs.pTriAPI->LoadShader)( x, false )
#define SetCrosshair (*g_engfuncs.pfnSetCrosshair)
#define SendWeaponAnim (*g_engfuncs.pEventAPI->EV_WeaponAnim)

View File

@ -5,6 +5,7 @@
#include "extdll.h"
#include "utils.h"
#include "hud.h"
#include "triangle_api.h"
void CHud :: Init( void )
{

View File

@ -406,7 +406,11 @@ int CHud::MsgFunc_ServerName( const char *pszName, int iSize, void *pbuf )
int CHud :: MsgFunc_RoomType( const char *pszName, int iSize, void *pbuf )
{
CVAR_SET_FLOAT( "room_type", READ_SHORT());
BEGIN_READ( pszName, iSize, pbuf );
CVAR_SET_FLOAT( "room_type", (float)READ_BYTE( ));
END_READ();
return 1;
}
@ -415,8 +419,8 @@ int CHud :: MsgFunc_ScreenFade( const char *pszName, int iSize, void *pbuf )
{
BEGIN_READ( pszName, iSize, pbuf );
float fadeTime = fabs( READ_SHORT() / (1<<12));
float holdTime = fabs( READ_SHORT() / (1<<12));
float fadeTime = READ_FLOAT();
float holdTime = READ_FLOAT();
int fadeFlags = READ_SHORT();
Vector m_FadeColor;

View File

@ -214,9 +214,6 @@ typedef struct cl_enginefuncs_s
char *(*pfnParseToken)( const char **data_p ); // was COM_ParseFile, like it
void (*pfnFreeFile)( void *buffer ); // was COM_FreeFile, like it
// FIXME: move to pTriAPI
HSPRITE (*pfnLoadShader)( const char *szShaderName, int fShaderNoMip );
struct triapi_s *pTriAPI;
struct efxapi_s *pEfxAPI;
struct event_api_s *pEventAPI;

View File

@ -32,6 +32,7 @@ typedef struct triapi_s
{
size_t api_size; // must match with sizeof( triapi_t );
HSPRITE (*LoadShader)( const char *szShaderName, int fShaderNoMip );
void (*RenderMode)( kRenderMode_t mode );
void (*Begin)( TRI_DRAW mode );
void (*End)( void );

View File

@ -141,14 +141,14 @@ byte CL_GetMouthOpen( int entityIndex )
return ed->pvClientData->mouth.open;
}
prevframe_t *CL_GetPrevFrame( int entityIndex )
studioframe_t *CL_GetStudioFrame( int entityIndex )
{
edict_t *pEnt = CL_GetEdictByIndex( entityIndex );
if( !pEnt || !pEnt->pvClientData )
return NULL;
return &pEnt->pvClientData->latched;
return &pEnt->pvClientData->frame;
}
/*
@ -906,7 +906,7 @@ void CL_InitWorld( void )
}
// clear viewmodel prevstate
Mem_Set( &clgame.viewent.pvClientData->latched, 0, sizeof( prevframe_t ));
Mem_Set( &clgame.viewent.pvClientData->frame, 0, sizeof( studioframe_t ));
}
void CL_InitEdicts( void )
@ -1984,26 +1984,6 @@ void VGui_ViewportPaintBackground( int extents[4] )
// FIXME: implement
}
/*
=============
pfnLoadShader
=============
*/
shader_t pfnLoadShader( const char *szShaderName, int fShaderNoMip )
{
if( !re ) return 0; // render not initialized
if( !szShaderName || !*szShaderName )
{
MsgDev( D_ERROR, "CL_LoadShader: invalid shadername (%s)\n", fShaderNoMip ? "nomip" : "generic" );
return -1;
}
if( fShaderNoMip )
return re->RegisterShader( szShaderName, SHADER_NOMIP );
return re->RegisterShader( szShaderName, SHADER_GENERIC );
}
/*
===============================================================================
EffectsAPI Builtin Functions
@ -2205,6 +2185,26 @@ static void Tri_SetVertex( float x, float y, float z )
Tri_CheckOverflow( clgame.pTri->numIndex - oldIndex, clgame.pTri->vertexState );
}
/*
=============
TriLoadShader
=============
*/
shader_t TriLoadShader( const char *szShaderName, int fShaderNoMip )
{
if( !re ) return 0; // render not initialized
if( !szShaderName || !*szShaderName )
{
MsgDev( D_ERROR, "CL_LoadShader: invalid shadername (%s)\n", fShaderNoMip ? "nomip" : "generic" );
return -1;
}
if( fShaderNoMip )
return re->RegisterShader( szShaderName, SHADER_NOMIP );
return re->RegisterShader( szShaderName, SHADER_GENERIC );
}
void TriRenderMode( kRenderMode_t mode )
{
if( !re ) return;
@ -2353,6 +2353,7 @@ void TriFog( float flFogColor[3], float flStart, float flEnd, int bOn )
static triapi_t gTriApi =
{
sizeof( triapi_t ),
TriLoadShader,
TriRenderMode,
TriBegin,
TriEnd,
@ -2482,7 +2483,6 @@ static cl_enginefuncs_t gEngfuncs =
pfnLoadFile,
pfnParseToken,
pfnFreeFile,
pfnLoadShader,
&gTriApi,
&gEfxApi,
&gEventApi

View File

@ -433,7 +433,7 @@ void SCR_RegisterShaders( void )
// TODO: load a font with a variable charwidths
Mem_Set( &clgame.ds, 0, sizeof( clgame.ds )); // reset a draw state
clgame.ds.hHudFont = re->RegisterShader( "sprites/font.spr", SHADER_NOMIP );
clgame.ds.hHudFont = re->RegisterShader( "gfx/creditsfont", SHADER_NOMIP );
}
// vid_state has changed

View File

@ -174,7 +174,7 @@ struct cl_priv_s
entity_state_t current;
entity_state_t prev; // will always be valid, but might just be a copy of current
prevframe_t latched; // previous frame to lerping from
studioframe_t frame; // holds the studio values for right lerping
// studiomodels attachments
vec3_t origin[MAXSTUDIOATTACHMENTS];

View File

@ -211,7 +211,7 @@ void CL_GetEntitySoundSpatialization( int ent, vec3_t origin, vec3_t velocity );
bool CL_GetAttachment( int entityIndex, int number, vec3_t origin, vec3_t angles );
bool CL_SetAttachment( int entityIndex, int number, vec3_t origin, vec3_t angles );
void CL_StudioEvent( dstudioevent_t *event, edict_t *ent );
prevframe_t *CL_GetPrevFrame( int entityIndex );
studioframe_t *CL_GetStudioFrame( int entityIndex );
edict_t *CL_GetEdictByIndex( int index );
edict_t *CL_GetLocalPlayer( void );
int CL_GetMaxClients( void );

View File

@ -159,7 +159,7 @@ bool Host_InitRender( void )
ri.GetAttachment = CL_GetAttachment;
ri.SetAttachment = CL_SetAttachment;
ri.GetClientEdict = CL_GetEdictByIndex;
ri.GetPrevFrame = CL_GetPrevFrame;
ri.GetStudioFrame = CL_GetStudioFrame;
ri.GetMouthOpen = CL_GetMouthOpen;
ri.GetLocalPlayer = CL_GetLocalPlayer;
ri.GetMaxClients = CL_GetMaxClients;

View File

@ -511,8 +511,8 @@ bool SV_RateDrop( sv_client_t *cl )
int i, total = 0;
// never drop over the loopback
// if( NET_IsLocalAddress( cl->netchan.remote_address ))
// return false;
if( NET_IsLocalAddress( cl->netchan.remote_address ))
return false;
for( i = 0; i < RATE_MESSAGES; i++ )
total += cl->message_size[i];

View File

@ -284,7 +284,7 @@ void Cmd_Exec_f( void )
return;
}
MsgDev( D_INFO, "execing %s\n", Cmd_Argv( 1 ));
MsgDev( D_LOAD, "execing %s\n", Cmd_Argv( 1 ));
Cbuf_InsertText( f );
Mem_Free( f );
}

View File

@ -675,6 +675,25 @@ _inline void PerpendicularVector( vec3_t dst, const vec3_t src )
}
}
/*
=================
SimpleSpline
NOTE: ripped from hl2 source
hermite basis function for smooth interpolation
Similar to Gain() above, but very cheap to call
value should be between 0 & 1 inclusive
=================
*/
_inline float SimpleSpline( float value )
{
float valueSquared = value * value;
// nice little ease-in, ease-out spline-like curve
return (3 * valueSquared - 2 * valueSquared * value);
}
/*
=================
NearestPOW

View File

@ -63,6 +63,7 @@ typedef struct
vec3_t normal;
} fragment_t;
// hold values that needs for right studio lerping
typedef struct
{
float frame;
@ -82,11 +83,17 @@ typedef struct
float m_flGroundSpeed; // looped sequence ground speed (movement)
float m_flLastEventCheck; // last time when event is checked
float curanimtime; // HACKHACK current animtime
float curframe; // HACKHACK current frame
int cursequence; // HACKHACK current sequence
byte curblending[16]; // HACKHACK current blending
byte curcontroller[16]; // HACKHACL current blending
byte blending[16]; // previous blending values
byte controller[16]; // previous controller values
byte seqblending[16]; // blending between sequence when it's changed
} prevframe_t;
} studioframe_t;
typedef struct
{
@ -180,7 +187,7 @@ typedef struct render_imp_s
bool (*GetAttachment)( int entityIndex, int number, vec3_t origin, vec3_t angles );
bool (*SetAttachment)( int entityIndex, int number, vec3_t origin, vec3_t angles );
edict_t *(*GetClientEdict)( int index );
prevframe_t *(*GetPrevFrame)( int entityIndex );
studioframe_t *(*GetStudioFrame)( int entityIndex );
byte (*GetMouthOpen)( int entityIndex );
edict_t *(*GetLocalPlayer)( void );
int (*GetMaxClients)( void );

View File

@ -259,7 +259,7 @@ CGrenade *CGrenade::ShootContact( entvars_t *pevOwner, Vector vecStart, Vector v
// Explode on contact
pGrenade->SetTouch( ExplodeTouch );
UTIL_SetModel( ENT( pGrenade->pev ), "models/weapons/w_grenade.mdl");
UTIL_SetModel( ENT( pGrenade->pev ), "models/props/grenade.mdl");
UTIL_SetSize( pGrenade->pev, Vector( 0, 0, 0 ), Vector( 0, 0, 0 ));
pGrenade->pev->dmg = M203_DMG;

View File

@ -1601,12 +1601,12 @@ void LinkUserMessages( void )
gmsg.AmmoPickup = REG_USER_MSG( "AmmoPickup", 2 );
gmsg.WeapPickup = REG_USER_MSG( "WeapPickup", 1 );
gmsg.ItemPickup = REG_USER_MSG( "ItemPickup", -1 );
gmsg.RoomType = REG_USER_MSG( "RoomType", 2 );
gmsg.RoomType = REG_USER_MSG( "RoomType", 1 );
gmsg.HideWeapon = REG_USER_MSG( "HideWeapon", 1 );
gmsg.WeaponAnim = REG_USER_MSG( "WeaponAnim", 3 );
gmsg.ShowMenu = REG_USER_MSG( "ShowMenu", -1 );
gmsg.Shake = REG_USER_MSG( "ScreenShake", 13 );
gmsg.Fade = REG_USER_MSG( "ScreenFade", sizeof( ScreenFade ));
gmsg.Fade = REG_USER_MSG( "ScreenFade", 14 );
gmsg.AmmoX = REG_USER_MSG("AmmoX", 2);
gmsg.TeamNames = REG_USER_MSG( "TeamNames", -1 );
gmsg.StatusText = REG_USER_MSG("StatusText", -1);

View File

@ -2123,8 +2123,8 @@ void UTIL_ScreenFade( const Vector &color, float fadeTime, float fadeHold, int a
pPlayer->m_FadeColor = color;
pPlayer->m_FadeAlpha = alpha;
pPlayer->m_iFadeFlags = flags;
pPlayer->m_iFadeTime = fadeTime;
pPlayer->m_iFadeHold = fadeHold;
pPlayer->m_flFadeTime = fadeTime;
pPlayer->m_flFadeHold = fadeHold;
pPlayer->fadeNeedsUpdate = TRUE;
}
}

View File

@ -137,7 +137,8 @@ TYPEDESCRIPTION CBasePlayer::m_playerSaveData[] =
DEFINE_FIELD( CBasePlayer, m_FadeColor, FIELD_VECTOR ),
DEFINE_FIELD( CBasePlayer, m_FadeAlpha, FIELD_INTEGER ),
DEFINE_FIELD( CBasePlayer, m_iFadeFlags, FIELD_INTEGER ),
DEFINE_FIELD( CBasePlayer, m_iFadeHold, FIELD_INTEGER ),
DEFINE_FIELD( CBasePlayer, m_flFadeHold, FIELD_FLOAT ),
DEFINE_FIELD( CBasePlayer, m_flFadeTime, FIELD_FLOAT ),
DEFINE_FIELD( CBasePlayer, m_flStartTime, FIELD_TIME ),
@ -401,12 +402,12 @@ void CBasePlayer :: TraceAttack( entvars_t *pevAttacker, float flDamage, Vector
break;
}
if( bitsDamageType & DMG_NUCLEAR )
if( bitsDamageType & DMG_NUCLEAR && !fadeNeedsUpdate )
{
m_FadeColor = Vector( 255, 255, 255 );
m_FadeAlpha = 240;
m_iFadeFlags = 0;
m_iFadeTime = 25;
m_iFadeFlags = FFADE_IN|FFADE_MODULATE;
m_flFadeTime = 25.0f;
fadeNeedsUpdate = TRUE;
}
else SpawnBlood(ptr->vecEndPos, BloodColor(), flDamage);// a little surface blood.
@ -907,14 +908,21 @@ void CBasePlayer::Killed( entvars_t *pevAttacker, int iGib )
// death fading
m_FadeColor = Vector( 128, 0, 0 );
m_FadeAlpha = 240;
m_iFadeFlags = FFADE_OUT|FFADE_MODULATE|FFADE_STAYOUT;
m_iFadeTime = 6;
m_FadeAlpha = 254;
m_iFadeFlags = FFADE_OUT|FFADE_MODULATE;
m_flFadeTime = 6.0f;
m_flFadeHold = 999999.0f;
fadeNeedsUpdate = TRUE;
// death sound fading
g_engfuncs.pfnFadeClientVolume( edict(), 99, 6.0f, 999999.0f, 0.0f );
m_iSndRoomtype = 15;
hearNeedsUpdate = 1;
if ( ( pev->health < -40 && iGib != GIB_NEVER ) || iGib == GIB_ALWAYS )
{
pev->solid = SOLID_NOT;
pev->solid = SOLID_NOT;
GibMonster(); // This clears pev->model
pev->effects |= EF_NODRAW;
return;
@ -2847,8 +2855,8 @@ void CBasePlayer :: Precache( void )
m_FadeColor = Vector( 255, 255, 255 );
m_FadeAlpha = 0;
m_iFadeFlags = 0;
m_iFadeTime = 0;
m_iFadeHold = 0;
m_flFadeTime = 0.0f;
m_flFadeHold = 0.0f;
fadeNeedsUpdate = TRUE;
}
}
@ -3735,7 +3743,7 @@ void CBasePlayer :: UpdateClientData( void )
{
// update dsp sound
MESSAGE_BEGIN( MSG_ONE, gmsg.RoomType, NULL, pev );
WRITE_SHORT( m_iSndRoomtype );
WRITE_BYTE( m_iSndRoomtype );
MESSAGE_END();
hearNeedsUpdate = 0;
}
@ -3744,8 +3752,8 @@ void CBasePlayer :: UpdateClientData( void )
{
// update screenfade
MESSAGE_BEGIN( MSG_ONE, gmsg.Fade, NULL, pev );
WRITE_SHORT( FixedUnsigned16( m_iFadeTime, 1<<12 ));
WRITE_SHORT( FixedUnsigned16( m_iFadeHold, 1<<12 ));
WRITE_FLOAT( m_flFadeTime );
WRITE_FLOAT( m_flFadeHold );
WRITE_SHORT( m_iFadeFlags ); // fade flags
WRITE_BYTE( (byte)m_FadeColor.x ); // fade red
WRITE_BYTE( (byte)m_FadeColor.y ); // fade green

View File

@ -329,8 +329,8 @@ public:
Vector m_FadeColor;
int m_FadeAlpha;
int m_iFadeFlags;
int m_iFadeTime;
int m_iFadeHold;
float m_flFadeTime;
float m_flFadeHold;
int fadeNeedsUpdate;
int m_iStartMessage;

View File

@ -19,6 +19,7 @@ typedef struct
float fDamping;
} dsproom_t;
static soundfade_t soundfade;
static playSound_t s_playSounds[MAX_PLAYSOUNDS];
static playSound_t s_freePlaySounds;
static playSound_t s_pendingPlaySounds;
@ -118,6 +119,23 @@ bool S_CheckForErrors( void )
return true;
}
/*
=================
S_GetMasterVolume
=================
*/
float S_GetMasterVolume( void )
{
float scale = 1.0f;
if( soundfade.percent != 0 )
{
scale = bound( 0.0f, soundfade.percent / 100.0f, 1.0f );
scale = 1.0f - scale;
}
return s_volume->value * scale;
}
/*
=================
S_FadeClientVolume
@ -125,7 +143,57 @@ S_FadeClientVolume
*/
void S_FadeClientVolume( float fadePercent, float fadeOutSeconds, float holdTime, float fadeInSeconds )
{
// FIXME: implement
soundfade.starttime = si.GetServerTime() * 0.001f;
soundfade.initial_percent = fadePercent;
soundfade.fadeouttime = fadeOutSeconds;
soundfade.holdtime = holdTime;
soundfade.fadeintime = fadeInSeconds;
}
/*
=================
S_UpdateSoundFade
=================
*/
void S_UpdateSoundFade( void )
{
float f, totaltime, elapsed;
// determine current fade value.
// assume no fading remains
soundfade.percent = 0;
totaltime = soundfade.fadeouttime + soundfade.fadeintime + soundfade.holdtime;
elapsed = (si.GetServerTime() * 0.001f) - soundfade.starttime;
// clock wrapped or reset (BUG) or we've gone far enough
if( elapsed < 0.0f || elapsed >= totaltime || totaltime <= 0.0f )
return;
// We are in the fade time, so determine amount of fade.
if( soundfade.fadeouttime > 0.0f && ( elapsed < soundfade.fadeouttime ))
{
// ramp up
f = elapsed / soundfade.fadeouttime;
}
else if( elapsed <= ( soundfade.fadeouttime + soundfade.holdtime )) // Inside the hold time
{
// stay
f = 1.0f;
}
else
{
// ramp down
f = ( elapsed - ( soundfade.fadeouttime + soundfade.holdtime ) ) / soundfade.fadeintime;
f = 1.0f - f; // backward interpolated...
}
// spline it.
f = SimpleSpline( f );
f = bound( 0.0f, f, 1.0f );
soundfade.percent = soundfade.initial_percent * f;
}
/*
@ -591,6 +659,9 @@ void S_StopAllSounds( void )
if( !ch->sfx ) continue;
S_StopChannel( ch );
}
// clear any remaining soundfade
Mem_Set( &soundfade, 0, sizeof( soundfade ));
S_StopStreaming(); // stop streaming channel
S_StopBackgroundTrack(); // stop background track
@ -643,7 +714,8 @@ void S_Update( ref_params_t *fd )
al_state.clientnum = fd->viewentity;
al_state.refdef = fd; // for using everthing else
// if( fd->paused ) return;
// update any client side sound fade
if( !fd->paused ) S_UpdateSoundFade();
// set up listener
VectorSet( s_listener.position, fd->simorg[1], fd->simorg[2], -fd->simorg[0] );
@ -661,7 +733,7 @@ void S_Update( ref_params_t *fd )
palListenerfv( AL_POSITION, s_listener.position );
palListenerfv( AL_VELOCITY, s_listener.velocity );
palListenerfv( AL_ORIENTATION, s_listener.orientation );
palListenerf( AL_GAIN, (al_state.active) ? s_volume->value : 0.0f );
palListenerf( AL_GAIN, (al_state.active) ? S_GetMasterVolume () : 0.0f );
// Set state
palDistanceModel( AL_INVERSE_DISTANCE_CLAMPED );
@ -730,7 +802,7 @@ void S_Activate( bool active )
return;
al_state.active = active;
if( active ) palListenerf( AL_GAIN, s_volume->value );
if( active ) palListenerf( AL_GAIN, S_GetMasterVolume() );
else palListenerf( AL_GAIN, 0.0 );
}

View File

@ -91,6 +91,17 @@ typedef struct playsound_s
float pitch;
} playSound_t;
// structure used for fading in and out client sound volume.
typedef struct
{
float initial_percent;
float percent; // how far to adjust client's volume down by.
float starttime; // GetHostTime() when we started adjusting volume
float fadeouttime; // # of seconds to get to faded out state
float holdtime; // # of seconds to hold
float fadeintime; // # of seconds to restore
} soundfade_t;
typedef struct
{
bool streaming;

View File

@ -12,6 +12,7 @@
#define MAX_PLAYSOUNDS 128
dma_t dma;
static soundfade_t soundfade;
channel_t channels[MAX_CHANNELS];
bool sound_started = false;
vec3_t listener_origin;
@ -50,6 +51,23 @@ cvar_t *s_primary;
=============================================================================
*/
/*
=================
S_GetMasterVolume
=================
*/
float S_GetMasterVolume( void )
{
float scale = 1.0f;
if( soundfade.percent != 0 )
{
scale = bound( 0.0f, soundfade.percent / 100.0f, 1.0f );
scale = 1.0f - scale;
}
return s_volume->value * scale;
}
/*
=================
S_FadeClientVolume
@ -57,7 +75,57 @@ S_FadeClientVolume
*/
void S_FadeClientVolume( float fadePercent, float fadeOutSeconds, float holdTime, float fadeInSeconds )
{
// FIXME: implement
soundfade.starttime = si.GetServerTime() * 0.001f;
soundfade.initial_percent = fadePercent;
soundfade.fadeouttime = fadeOutSeconds;
soundfade.holdtime = holdTime;
soundfade.fadeintime = fadeInSeconds;
}
/*
=================
S_UpdateSoundFade
=================
*/
void S_UpdateSoundFade( void )
{
float f, totaltime, elapsed;
// determine current fade value.
// assume no fading remains
soundfade.percent = 0;
totaltime = soundfade.fadeouttime + soundfade.fadeintime + soundfade.holdtime;
elapsed = (si.GetServerTime() * 0.001f) - soundfade.starttime;
// clock wrapped or reset (BUG) or we've gone far enough
if( elapsed < 0.0f || elapsed >= totaltime || totaltime <= 0.0f )
return;
// We are in the fade time, so determine amount of fade.
if( soundfade.fadeouttime > 0.0f && ( elapsed < soundfade.fadeouttime ))
{
// ramp up
f = elapsed / soundfade.fadeouttime;
}
else if( elapsed <= ( soundfade.fadeouttime + soundfade.holdtime )) // Inside the hold time
{
// stay
f = 1.0f;
}
else
{
// ramp down
f = ( elapsed - ( soundfade.fadeouttime + soundfade.holdtime ) ) / soundfade.fadeintime;
f = 1.0f - f; // backward interpolated...
}
// spline it.
f = SimpleSpline( f );
f = bound( 0.0f, f, 1.0f );
soundfade.percent = soundfade.initial_percent * f;
}
/*
@ -501,6 +569,10 @@ void S_StopAllSounds( void )
total_channels = MAX_CHANNELS; // no statics
// clear any remaining soundfade
Mem_Set( &soundfade, 0, sizeof( soundfade ));
s_volume->modified = true; // rebuild scaletable
// clear all the channels
Mem_Set( channels, 0, sizeof( channels ));
S_ClearBuffer ();
@ -661,8 +733,12 @@ void S_Update( ref_params_t *fd )
return;
}
// update any client side sound fade
S_UpdateSoundFade();
// rebuild scale tables if volume is modified
if( s_volume->modified ) S_InitScaletable();
if( s_volume->modified || soundfade.percent != 0 )
S_InitScaletable();
s_clientnum = fd->viewentity;
VectorCopy( fd->simorg, listener_origin );

View File

@ -269,7 +269,7 @@ void S_PaintChannels( int endtime )
playsound_t *ps;
int i, end;
snd_vol = s_volume->value * 256;
snd_vol = S_GetMasterVolume () * 256;
while( paintedtime < endtime )
{
@ -330,7 +330,7 @@ void S_InitScaletable( void )
for( i = 0; i < 32; i++ )
{
scale = i * 8 * 256 * s_volume->value;
scale = i * 8 * 256 * S_GetMasterVolume();
for( j = 0; j < 256; j++ ) snd_scaletable[i][j] = ((signed char)j) * scale;
}
s_volume->modified = false;

View File

@ -61,6 +61,17 @@ typedef struct playsound_s
uint begin; // begin on this sample
} playsound_t;
// structure used for fading in and out client sound volume.
typedef struct
{
float initial_percent;
float percent; // how far to adjust client's volume down by.
float starttime; // GetHostTime() when we started adjusting volume
float fadeouttime; // # of seconds to get to faded out state
float holdtime; // # of seconds to hold
float fadeintime; // # of seconds to restore
} soundfade_t;
typedef struct
{
int channels;
@ -170,6 +181,7 @@ void S_InitScaletable( void );
sfxcache_t *S_LoadSound( sfx_t *sfx );
void S_IssuePlaysound( playsound_t *ps );
void S_PaintChannels( int endtime );
float S_GetMasterVolume( void );
// s_load.c
bool S_TestSoundChar( const char *pch, char c );

View File

@ -162,7 +162,7 @@ Beta 13.12.09
136. re-vision uimenu
137. complete rewriting physic.dll OK
138. implement hashtable for loaded sounds OK
139. finalize client API's
139. finalize triangle API
140. net_msg is buggly!!!! OK
141. implement client predicting OK
142. finalize CL_Move and CL_LinkEdict OK
@ -188,7 +188,9 @@ Beta 13.12.09
162. rewrote auto-classify OK
163. rewrote sv_phys.c OK
164. remove vprogs.dll OK
165. fix bsplib error
165. finalize EventAPI
166. move cl_input.c into client.dll OK
167. fix all founded errors
168. release at 13/12/2009

View File

@ -1650,17 +1650,7 @@ void R_ModifyColor( const ref_stage_t *pass )
}
break;
case RGBGEN_LIGHTING_DIFFUSE:
if( r_studio_bonelighting->integer && RI.currentmodel && RI.currentmodel->type == mod_studio )
{
// Paranoia-Style bonelighting instead of diffuse lighting (Faster)
for( i = 0; i < r_backacc.numColors; i++, bArray += 4, inArray += 4 )
{
bArray[0] = inArray[0] >> bits;
bArray[1] = inArray[1] >> bits;
bArray[2] = inArray[2] >> bits;
}
}
else if( RI.currententity ) R_LightForEntity( RI.currententity, bArray );
if( RI.currententity ) R_LightForEntity( RI.currententity, bArray );
break;
case RGBGEN_LIGHTING_DIFFUSE_ONLY:
if( RI.currententity && !( RI.params & RP_SHADOWMAPVIEW ) )

View File

@ -214,17 +214,15 @@ typedef struct ref_entity_s
struct ref_model_s *model; // opaque type outside refresh
struct ref_entity_s *parent; // link to parent entity (FOLLOW or weaponmodel)
prevframe_t *prev; // previous frame values for lerping
studioframe_t *prev; // previous frame values for lerping
float framerate; // custom framerate
float animtime; // lerping animtime
float frame; // also used as RF_BEAM's diameter
float frame;
int body;
int skin;
int movetype; // entity moving type
int sequence;
float scale;
byte *mempool; // studio mempool
@ -430,9 +428,6 @@ extern cvar_t *r_outlines_scale;
extern cvar_t *r_outlines_cutoff;
extern cvar_t *r_himodels;
extern cvar_t *r_studio_bonelighting;
extern cvar_t *r_environment_color;
extern cvar_t *r_gamma;
extern cvar_t *r_texturebits;

View File

@ -2114,6 +2114,7 @@ bool R_AddGenericEntity( edict_t *pRefEntity, ref_entity_t *refent )
if( !refent->model->extradata )
return false;
refent->scale = 1.0f; // ignore scale for brush models
refent->frame = pRefEntity->v.frame; // brush properly animating
break;
case mod_studio:
case mod_sprite:
@ -2124,7 +2125,7 @@ bool R_AddGenericEntity( edict_t *pRefEntity, ref_entity_t *refent )
break;
}
refent->prev = ri.GetPrevFrame( refent->index ); // setup prevframe data
refent->prev = ri.GetStudioFrame( refent->index ); // setup prevframe data
if( refent->prev == NULL )
{
@ -2154,9 +2155,9 @@ bool R_AddGenericEntity( edict_t *pRefEntity, ref_entity_t *refent )
{
float numframes = ((msprite_t *)refent->model->extradata)->numframes;
refent->frame += (pRefEntity->v.framerate * RI.refdef.frametime);
if( refent->frame > numframes && numframes > 0 )
refent->frame = fmod( refent->frame, numframes );
refent->prev->curframe += (pRefEntity->v.framerate * RI.refdef.frametime);
if( refent->prev->curframe > numframes && numframes > 0 )
refent->prev->curframe = fmod( refent->prev->curframe, numframes );
}
break;
case mod_studio:
@ -2168,8 +2169,8 @@ bool R_AddGenericEntity( edict_t *pRefEntity, ref_entity_t *refent )
else
{
if( refent->prev )
refent->prev->frame = refent->frame; // save oldframe
refent->frame = pRefEntity->v.frame;
refent->prev->frame = refent->prev->curframe; // save oldframe
refent->prev->curframe = pRefEntity->v.frame;
}
if( refent->ent_type == ED_MOVER || refent->ent_type == ED_BSPBRUSH )

View File

@ -259,7 +259,7 @@ mspriteframe_t *R_GetSpriteFrame( ref_entity_t *ent )
float *pintervals, fullinterval, targettime, time;
psprite = ent->model->extradata;
frame = (int)ent->frame;
frame = (int)ent->prev->curframe;
if((frame >= psprite->numframes) || (frame < 0))
{
@ -317,7 +317,7 @@ float R_GetSpriteFrameInterpolant( ref_entity_t *ent, mspriteframe_t **oldframe,
int m_fDoInterp;
psprite = ent->model->extradata;
frame = (int)ent->frame;
frame = (int)ent->prev->curframe;
lerpFrac = 1.0f;
// misc info
@ -339,40 +339,40 @@ float R_GetSpriteFrameInterpolant( ref_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->prev->sequence = ent->sequence = frame;
ent->animtime = RI.refdef.time;
ent->prev->sequence = ent->prev->cursequence = frame;
ent->prev->curanimtime = RI.refdef.time;
lerpFrac = 1.0f;
}
if( ent->animtime < RI.refdef.time )
if( ent->prev->curanimtime < RI.refdef.time )
{
if( frame != ent->sequence )
if( frame != ent->prev->cursequence )
{
ent->prev->sequence = ent->sequence;
ent->sequence = frame;
ent->animtime = RI.refdef.time;
ent->prev->sequence = ent->prev->cursequence;
ent->prev->cursequence = frame;
ent->prev->curanimtime = RI.refdef.time;
lerpFrac = 0.0f;
}
else lerpFrac = (RI.refdef.time - ent->animtime) * ent->framerate;
else lerpFrac = (RI.refdef.time - ent->prev->curanimtime) * ent->framerate;
}
else
{
ent->prev->sequence = ent->sequence = frame;
ent->animtime = RI.refdef.time;
ent->prev->sequence = ent->prev->cursequence = frame;
ent->prev->curanimtime = RI.refdef.time;
lerpFrac = 0.0f;
}
}
else
{
ent->prev->sequence = ent->sequence = frame;
ent->prev->sequence = ent->prev->cursequence = frame;
lerpFrac = 1.0f;
}
if( ent->prev->sequence >= psprite->numframes )
{
// reset interpolation on change model
ent->prev->sequence = ent->sequence = frame;
ent->animtime = RI.refdef.time;
ent->prev->sequence = ent->prev->cursequence = frame;
ent->prev->curanimtime = RI.refdef.time;
lerpFrac = 0.0f;
}
@ -425,32 +425,32 @@ float R_GetSpriteFrameInterpolant( ref_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->prev->sequence = ent->sequence = frame;
ent->animtime = RI.refdef.time;
ent->prev->sequence = ent->prev->cursequence = frame;
ent->prev->curanimtime = RI.refdef.time;
lerpFrac = 1.0f;
}
if( ent->animtime < RI.refdef.time )
if( ent->prev->curanimtime < RI.refdef.time )
{
if( frame != ent->sequence )
if( frame != ent->prev->cursequence )
{
ent->prev->sequence = ent->sequence;
ent->sequence = frame;
ent->animtime = RI.refdef.time;
ent->prev->sequence = ent->prev->cursequence;
ent->prev->cursequence = frame;
ent->prev->curanimtime = RI.refdef.time;
lerpFrac = 0.0f;
}
else lerpFrac = (RI.refdef.time - ent->animtime) * ent->framerate;
else lerpFrac = (RI.refdef.time - ent->prev->curanimtime) * ent->framerate;
}
else
{
ent->prev->sequence = ent->sequence = frame;
ent->animtime = RI.refdef.time;
ent->prev->sequence = ent->prev->cursequence = frame;
ent->prev->curanimtime = RI.refdef.time;
lerpFrac = 0.0f;
}
}
else
{
ent->prev->sequence = ent->sequence = frame;
ent->prev->sequence = ent->prev->cursequence = frame;
lerpFrac = 1.0f;
}

View File

@ -44,21 +44,7 @@ vec3_t studio_mins, studio_maxs;
float studio_radius;
// studio cvars
cvar_t *r_studio_bonelighting;
cvar_t *r_studio_lerping;
cvar_t *r_studio_lambert;
typedef struct studiolight_s
{
vec3_t lightvec; // light vector
vec4_t lightcolor; // ambient light color
vec4_t lightdiffuse; // diffuse light color
vec3_t bonelightvec[MAXSTUDIOBONES]; // ambient lightvectors per bone
vec3_t dynlightcolor[MAX_DLIGHTS]; // ambient dynamic light colors
vec3_t dynlightvec[MAX_DLIGHTS][MAXSTUDIOBONES];
int numdynlights;
} studiolight_t;
typedef struct studioverts_s
{
@ -73,11 +59,9 @@ typedef struct studioverts_s
typedef struct studiovars_s
{
byte blending[MAXSTUDIOBLENDS];
byte controller[MAXSTUDIOCONTROLLERS];
prevframe_t *prev; // duplcate e->prev for consistency
studioframe_t *prev; // duplcate e->prev for consistency
// cached bones, valid only for CURRENT frame
// cached values, valid only for CURRENT frame
char bonenames[MAXSTUDIOBONES][32];// used for attached entities
studioverts_t *mesh[MAXSTUDIOMODELS];
matrix4x4 rotationmatrix;
@ -86,9 +70,6 @@ typedef struct studiovars_s
vec3_t *chromeup;
int *chromeage;
int numbones;
// StudioBoneLighting (slow but ugly)
studiolight_t *light; // FIXME: alloc match size not maximum
} studiovars_t;
/*
@ -105,8 +86,6 @@ void R_StudioInit( void )
m_pStudioHeader = NULL;
m_flGaitMovement = 1;
r_studio_bonelighting = Cvar_Get( "r_studio_bonelighting", "0", CVAR_ARCHIVE, "use bonelighting instead of vertex diffuse lighting on studio models" );
r_studio_lambert = Cvar_Get( "r_studio_lambert", "2", CVAR_ARCHIVE, "bonelighting lambert value" );
r_studio_lerping = Cvar_Get( "r_studio_lerping", "1", CVAR_ARCHIVE, "enables studio model animation lerping" );
for( i = 1; i < MAX_ENTITIES; i++ )
@ -145,34 +124,34 @@ void R_StudioAllocExtradata( edict_t *in, ref_entity_t *e )
// copy controllers
for( i = 0; i < MAXSTUDIOCONTROLLERS; i++ )
{
studio->prev->controller[i] = studio->controller[i];
studio->controller[i] = in->v.controller[i];
studio->prev->controller[i] = studio->prev->curcontroller[i];
studio->prev->curcontroller[i] = in->v.controller[i];
}
// copy blends
for( i = 0; i < MAXSTUDIOBLENDS; i++ )
{
studio->prev->blending[i] = studio->blending[i];
studio->blending[i] = in->v.blending[i];
studio->prev->blending[i] = studio->prev->curblending[i];
studio->prev->curblending[i] = in->v.blending[i];
}
// sequence has changed, hold the previous sequence info
if( in->v.sequence != e->sequence )
if( in->v.sequence != e->prev->cursequence )
{
studio->prev->sequencetime = e->prev->animtime + 0.01f;
studio->prev->sequence = e->sequence;
studio->prev->sequence = e->prev->cursequence;
// save current blendings
for( i = 0; i < MAXSTUDIOBLENDS; i++ )
studio->prev->blending[i] = studio->blending[i];
studio->prev->blending[i] = studio->prev->curblending[i];
}
if( e->flags & EF_ANIMATE )
{
if( in->v.frame == -1 )
{
in->v.frame = e->frame = 0;
e->sequence = in->v.sequence;
in->v.frame = e->prev->curframe = 0;
e->prev->cursequence = in->v.sequence;
R_StudioResetSequenceInfo( e );
}
else
@ -189,15 +168,15 @@ void R_StudioAllocExtradata( edict_t *in, ref_entity_t *e )
else
{
// copy current frame back to let user grab it on a client-side
in->v.frame = e->frame;
in->v.frame = e->prev->curframe;
}
}
}
else
{
e->sequence = in->v.sequence;
e->prev->animtime = e->animtime; // must be update each frame!
e->animtime = in->v.animtime;
e->prev->cursequence = in->v.sequence;
e->prev->animtime = e->prev->curanimtime; // must be update each frame!
e->prev->curanimtime = in->v.animtime;
}
if( studio->numbones != numbones )
@ -228,17 +207,6 @@ void R_StudioAllocExtradata( edict_t *in, ref_entity_t *e )
studio->chromeage = NULL;
}
studio->numbones = numbones;
if( r_studio_bonelighting->integer )
{
if( !studio->light )
studio->light = Mem_Alloc( e->mempool, sizeof( studiolight_t ));
}
else
{
if( studio->light ) Mem_Free( studio->light );
studio->light = NULL;
}
}
void R_StudioShutdown( void )
@ -317,7 +285,7 @@ void R_StudioModelBBox( ref_entity_t *e, vec3_t mins, vec3_t maxs )
hdr = ((mstudiomodel_t *)e->model->extradata)->phdr;
if( !hdr ) return;
R_StudioExtractBbox( hdr, e->sequence, mins, maxs );
R_StudioExtractBbox( hdr, e->prev->cursequence, mins, maxs );
}
/*
@ -564,10 +532,10 @@ float R_StudioSequenceDuration( dstudiohdr_t *hdr, ref_entity_t *ent )
{
dstudioseqdesc_t *pseqdesc;
if( !hdr || ent->sequence >= hdr->numseq )
if( !hdr || ent->prev->cursequence >= hdr->numseq )
return 0.0f;
pseqdesc = (dstudioseqdesc_t *)((byte *)hdr + hdr->seqindex) + ent->sequence;
pseqdesc = (dstudioseqdesc_t *)((byte *)hdr + hdr->seqindex) + ent->prev->cursequence;
return pseqdesc->numframes / pseqdesc->fps;
}
@ -575,10 +543,10 @@ int R_StudioGetSequenceFlags( dstudiohdr_t *hdr, ref_entity_t *ent )
{
dstudioseqdesc_t *pseqdesc;
if( !hdr || ent->sequence >= hdr->numseq )
if( !hdr || ent->prev->cursequence >= hdr->numseq )
return 0;
pseqdesc = (dstudioseqdesc_t *)((byte *)hdr + hdr->seqindex) + (int)ent->sequence;
pseqdesc = (dstudioseqdesc_t *)((byte *)hdr + hdr->seqindex) + (int)ent->prev->cursequence;
return pseqdesc->flags;
}
@ -586,14 +554,14 @@ void R_StuioGetSequenceInfo( dstudiohdr_t *hdr, ref_entity_t *ent, float *pflFra
{
dstudioseqdesc_t *pseqdesc;
if( !hdr || ent->sequence >= hdr->numseq )
if( !hdr || ent->prev->cursequence >= hdr->numseq )
{
*pflFrameRate = 0.0;
*pflGroundSpeed = 0.0;
return;
}
pseqdesc = (dstudioseqdesc_t *)((byte *)hdr + hdr->seqindex) + ent->sequence;
pseqdesc = (dstudioseqdesc_t *)((byte *)hdr + hdr->seqindex) + ent->prev->cursequence;
if( pseqdesc->numframes > 1 )
{
@ -617,23 +585,23 @@ float R_StudioFrameAdvance( ref_entity_t *ent, float flInterval )
if( flInterval == 0.0 )
{
flInterval = ( RI.refdef.time - ent->animtime );
flInterval = ( RI.refdef.time - ent->prev->curanimtime );
if( flInterval <= 0.001 )
{
ent->animtime = RI.refdef.time;
ent->prev->curanimtime = RI.refdef.time;
return 0.0;
}
}
if( !ent->animtime ) flInterval = 0.0;
if( !ent->prev->curanimtime ) flInterval = 0.0;
ent->frame += flInterval * pstudio->prev->m_flFrameRate * ent->framerate;
ent->animtime = RI.refdef.time;
ent->prev->curframe += flInterval * pstudio->prev->m_flFrameRate * ent->framerate;
ent->prev->curanimtime = RI.refdef.time;
if( ent->frame < 0.0 || ent->frame >= 256.0 )
if( ent->prev->curframe < 0.0 || ent->prev->curframe >= 256.0 )
{
if( pstudio->prev->m_fSequenceLoops )
ent->frame -= (int)(ent->frame / 256.0) * 256.0;
else ent->frame = (ent->frame < 0.0) ? 0 : 255;
ent->prev->curframe -= (int)(ent->prev->curframe / 256.0) * 256.0;
else ent->prev->curframe = (ent->prev->curframe < 0.0) ? 0 : 255;
pstudio->prev->m_fSequenceFinished = true;
}
return flInterval;
@ -652,8 +620,8 @@ void R_StudioResetSequenceInfo( ref_entity_t *ent )
R_StuioGetSequenceInfo( hdr, ent, &pstudio->prev->m_flFrameRate, &pstudio->prev->m_flGroundSpeed );
pstudio->prev->m_fSequenceLoops = ((R_StudioGetSequenceFlags( hdr, ent ) & STUDIO_LOOPING) != 0 );
ent->prev->animtime = ent->animtime;
ent->animtime = RI.refdef.time;
ent->prev->animtime = ent->prev->curanimtime;
ent->prev->curanimtime = RI.refdef.time;
pstudio->prev->m_fSequenceFinished = false;
pstudio->prev->m_flLastEventCheck = RI.refdef.time;
}
@ -664,7 +632,7 @@ int R_StudioGetEvent( ref_entity_t *e, dstudioevent_t *pcurrent, float flStart,
dstudioevent_t *pevent;
int events = 0;
pseqdesc = (dstudioseqdesc_t *)((byte *)m_pStudioHeader + m_pStudioHeader->seqindex) + e->sequence;
pseqdesc = (dstudioseqdesc_t *)((byte *)m_pStudioHeader + m_pStudioHeader->seqindex) + e->prev->cursequence;
pevent = (dstudioevent_t *)((byte *)m_pStudioHeader + pseqdesc->eventindex);
if( pseqdesc->numevents == 0 || index > pseqdesc->numevents )
@ -1087,9 +1055,9 @@ float R_StudioEstimateInterpolant( void )
{
float dadt = 1.0;
if( m_fDoInterp && ( RI.currententity->animtime >= RI.currententity->prev->animtime + 0.01 ))
if( m_fDoInterp && ( RI.currententity->prev->curanimtime >= RI.currententity->prev->animtime + 0.01 ))
{
dadt = (RI.refdef.time - RI.currententity->animtime) / 0.1;
dadt = (RI.refdef.time - RI.currententity->prev->curanimtime) / 0.1;
if( dadt > 2.0 ) dadt = 2.0;
}
return dadt;
@ -1127,7 +1095,7 @@ void R_StudioCalcRotations( float pos[][3], vec4_t *q, dstudioseqdesc_t *pseqdes
pstudio = RI.currententity->extradata;
Com_Assert( pstudio == NULL );
// Msg("%d %.4f %.4f %.4f %.4f %d\n", RI.currententity->curstate.sequence, m_clTime, RI.currententity->animtime, RI.currententity->frame, f, frame );
// Msg("%d %.4f %.4f %.4f %.4f %d\n", RI.currententity->curstate.sequence, m_clTime, RI.currententity->prev->curanimtime, RI.currententity->prev->curframe, f, frame );
// Msg( "%f %f %f\n", RI.currententity->angles[ROLL], RI.currententity->angles[PITCH], RI.currententity->angles[YAW] );
// Msg("frame %d %d\n", frame1, frame2 );
@ -1138,13 +1106,13 @@ void R_StudioCalcRotations( float pos[][3], vec4_t *q, dstudioseqdesc_t *pseqdes
pbone = (dstudiobone_t *)((byte *)m_pStudioHeader + m_pStudioHeader->boneindex);
mouthopen = ri.GetMouthOpen( RI.currententity->index );
R_StudioCalcBoneAdj( dadt, adj, pstudio->controller, pstudio->prev->controller, mouthopen );
R_StudioCalcBoneAdj( dadt, adj, pstudio->prev->curcontroller, pstudio->prev->controller, mouthopen );
for (i = 0; i < m_pStudioHeader->numbones; i++, pbone++, panim++)
{
R_StudioCalcBoneQuaterion( frame, s, pbone, panim, adj, q[i] );
R_StudioCalcBonePosition( frame, s, pbone, panim, adj, pos[i] );
// if( 0 && i == 0 ) Msg("%d %d %d %d\n", RI.currententity->sequence, frame, j, k );
// if( 0 && i == 0 ) Msg("%d %d %d %d\n", RI.currententity->prev->cursequence, frame, j, k );
}
if( pseqdesc->motiontype & STUDIO_X ) pos[pseqdesc->motionbone][0] = 0.0f;
@ -1170,13 +1138,13 @@ float R_StudioEstimateFrame( dstudioseqdesc_t *pseqdesc )
if( m_fDoInterp )
{
if( RI.refdef.time < RI.currententity->animtime ) dfdt = 0;
else dfdt = (RI.refdef.time - RI.currententity->animtime) * RI.currententity->framerate * pseqdesc->fps;
if( RI.refdef.time < RI.currententity->prev->curanimtime ) dfdt = 0;
else dfdt = (RI.refdef.time - RI.currententity->prev->curanimtime) * RI.currententity->framerate * pseqdesc->fps;
}
else dfdt = 0;
if( pseqdesc->numframes <= 1 ) f = 0;
else f = (RI.currententity->frame * (pseqdesc->numframes - 1)) / 256.0;
else f = (RI.currententity->prev->curframe * (pseqdesc->numframes - 1)) / 256.0;
f += dfdt;
@ -1226,8 +1194,8 @@ float R_StudioSetupBones( ref_entity_t *e )
return 0.0f;
cl_entity = ri.GetClientEdict( e->index );
if( e->sequence >= m_pStudioHeader->numseq ) e->sequence = 0;
pseqdesc = (dstudioseqdesc_t *)((byte *)m_pStudioHeader + m_pStudioHeader->seqindex) + e->sequence;
if( e->prev->cursequence >= m_pStudioHeader->numseq ) e->prev->cursequence = 0;
pseqdesc = (dstudioseqdesc_t *)((byte *)m_pStudioHeader + m_pStudioHeader->seqindex) + e->prev->cursequence;
f = R_StudioEstimateFrame( pseqdesc );
@ -1248,7 +1216,7 @@ float R_StudioSetupBones( ref_entity_t *e )
R_StudioCalcRotations( pos2, q2, pseqdesc, panim, f );
dadt = R_StudioEstimateInterpolant();
s = (pstudio->blending[0] * dadt + pstudio->prev->blending[0] * (1.0 - dadt)) / 255.0;
s = (pstudio->prev->curblending[0] * dadt + pstudio->prev->blending[0] * (1.0 - dadt)) / 255.0;
R_StudioSlerpBones( q, pos, q2, pos2, s );
@ -1260,10 +1228,10 @@ float R_StudioSetupBones( ref_entity_t *e )
panim += m_pStudioHeader->numbones;
R_StudioCalcRotations( pos4, q4, pseqdesc, panim, f );
s = (pstudio->blending[0] * dadt + pstudio->prev->blending[0] * (1.0 - dadt)) / 255.0;
s = (pstudio->prev->curblending[0] * dadt + pstudio->prev->blending[0] * (1.0 - dadt)) / 255.0;
R_StudioSlerpBones( q3, pos3, q4, pos4, s );
s = (pstudio->blending[1] * dadt + pstudio->prev->blending[1] * (1.0 - dadt)) / 255.0;
s = (pstudio->prev->curblending[1] * dadt + pstudio->prev->blending[1] * (1.0 - dadt)) / 255.0;
R_StudioSlerpBones( q, pos, q3, pos3, s );
}
}
@ -1376,7 +1344,7 @@ float R_StudioMergeBones( ref_entity_t *e, ref_model_t *m_pSubModel )
{
int i, j;
double f;
int sequence = e->sequence;
int sequence = e->prev->cursequence;
dstudiobone_t *pbones;
dstudioseqdesc_t *pseqdesc;
dstudioanim_t *panim;
@ -1487,7 +1455,7 @@ bool R_StudioComputeBBox( vec3_t bbox[8] )
vec3_t vectors[3];
ref_entity_t *e = RI.currententity;
vec3_t tmp, angles;
int i, seq = RI.currententity->sequence;
int i, seq = RI.currententity->prev->cursequence;
if(!R_ExtractBbox( seq, studio_mins, studio_maxs ))
return false;
@ -1540,121 +1508,6 @@ static void R_StudioSetupSubModel( int body, int bodypart )
m_pSubModel = (dstudiomodel_t *)((byte *)m_pStudioHeader + m_pBodyPart->modelindex) + index;
}
void R_StudioSetupLighting( ref_entity_t *e, ref_model_t *mod )
{
studiolight_t *plight;
int i;
if( !r_studio_bonelighting->integer ) return;
// light already cached for this frame
if( e->m_nCachedFrameCount == r_framecount2 ) return;
plight = ((studiovars_t *)e->extradata)->light;
Com_Assert( plight == NULL );
// set radius to 0 because we want handle dynamic lights manually
R_LightForOrigin( e->lightingOrigin, plight->lightvec, plight->lightcolor, plight->lightdiffuse, 0 );
for( i = 0; i < m_pStudioHeader->numbones; i++ )
Matrix4x4_VectorIRotate( m_pbonestransform[i], plight->lightvec, plight->bonelightvec[i] );
plight->numdynlights = 0;
// add dynamic lights
if( r_dynamiclight->integer && r_numDlights )
{
uint lnum;
dlight_t *dl;
float dist, radius, radius2;
vec3_t direction;
for( lnum = 0, dl = r_dlights; lnum < r_numDlights; lnum++, dl++ )
{
if( !BoundsAndSphereIntersect( dl->mins, dl->maxs, e->lightingOrigin, mod->radius ))
continue;
VectorSubtract( dl->origin, e->lightingOrigin, direction );
dist = VectorLength( direction );
if( !dist || dist > dl->intensity + mod->radius )
continue;
radius = RadiusFromBounds( dl->mins, dl->maxs );
radius2 = radius * radius; // squared radius
for( i = 0; i < m_pStudioHeader->numbones; i++ )
{
vec3_t vec, org;
float dist, atten;
Matrix4x4_OriginFromMatrix( m_pbonestransform[i], org );
VectorSubtract( org, dl->origin, vec );
dist = DotProduct( vec, vec );
atten = (dist / radius2 - 1) * -1;
if( atten < 0 ) atten = 0;
dist = com.sqrt( dist );
if( dist )
{
dist = 1.0f / dist;
VectorScale( vec, dist, vec );
}
Matrix4x4_VectorIRotate( m_pbonestransform[i], vec, plight->dynlightvec[plight->numdynlights][i] );
VectorScale( plight->dynlightvec[plight->numdynlights][i], atten, plight->dynlightvec[plight->numdynlights][i] );
}
VectorCopy( dl->color, plight->dynlightcolor[plight->numdynlights] );
plight->numdynlights++;
}
}
}
void R_StudioLighting( vec3_t lv, int bone, int flags, vec3_t normal )
{
vec3_t illum;
float lightcos;
studiolight_t *plight;
plight = ((studiovars_t *)RI.currententity->extradata)->light;
Com_Assert( plight == NULL );
VectorCopy( plight->lightcolor, illum );
if( flags & STUDIO_NF_FLATSHADE )
{
VectorMA( illum, 0.8f, plight->lightdiffuse, illum );
}
else
{
float r;
int i;
lightcos = DotProduct( normal, plight->bonelightvec[bone] ); // -1 colinear, 1 opposite
if( lightcos > 1.0f ) lightcos = 1;
VectorAdd( illum, plight->lightdiffuse, illum );
r = r_studio_lambert->value;
if( r < 1.0f ) r = 1.0f;
lightcos = (lightcos + (r - 1.0)) / r; // do modified hemispherical lighting
if( lightcos > 0.0f ) VectorMA( illum, -lightcos, plight->lightdiffuse, illum );
if( illum[0] <= 0 ) illum[0] = 0;
if( illum[1] <= 0 ) illum[1] = 0;
if( illum[2] <= 0 ) illum[2] = 0;
// buz: now add all dynamic lights
for( i = 0; i < plight->numdynlights; i++)
{
lightcos = -DotProduct( normal, plight->dynlightvec[i][bone] );
if( lightcos > 0 ) VectorMA( illum, lightcos, plight->dynlightcolor[i], illum );
}
}
ColorNormalize( illum, illum );
VectorScale( illum, 255, lv );
}
void R_StudioSetupChrome( float *pchrome, int modelnum, int bone, float *normal )
{
float n;
@ -1744,16 +1597,6 @@ void R_StudioDrawMesh( const meshbuffer_t *mb, short *ptricmds, float s, float t
if( flags & STUDIO_NF_CHROME )
Vector2Set( inCoordsArray[r_backacc.numVerts], m_pchrome[ptricmds[1]][0] * s, m_pchrome[ptricmds[1]][1] * t );
else Vector2Set( inCoordsArray[r_backacc.numVerts], ptricmds[2] * s, ptricmds[3] * t );
if( r_studio_bonelighting->integer )
{
if( shader != R_PlanarShadowShader())
{
lv = m_pxformlight[ptricmds[1]];
Vector4Set( inColorsArray[0][r_backacc.numColors], lv[0], lv[1], lv[2], 255 );
r_backacc.numColors++;
}
}
if( features & MF_NORMALS )
{
@ -2111,17 +1954,17 @@ void R_StudioProcessGait( ref_entity_t *e, edict_t *pplayer, studiovars_t *pstud
float dt, flYaw; // view direction relative to movement
int iBlend;
if( e->sequence >= m_pStudioHeader->numseq )
e->sequence = 0;
if( e->prev->cursequence >= m_pStudioHeader->numseq )
e->prev->cursequence = 0;
pseqdesc = (dstudioseqdesc_t *)((byte *)m_pStudioHeader + m_pStudioHeader->seqindex) + e->sequence;
pseqdesc = (dstudioseqdesc_t *)((byte *)m_pStudioHeader + m_pStudioHeader->seqindex) + e->prev->cursequence;
R_StudioPlayerBlend( pseqdesc, &iBlend, &e->angles[PITCH] );
pstudio->blending[0] = iBlend;
pstudio->prev->blending[0] = pstudio->blending[0];
pstudio->prev->seqblending[0] = pstudio->blending[0];
pstudio->prev->curblending[0] = iBlend;
pstudio->prev->blending[0] = pstudio->prev->curblending[0];
pstudio->prev->seqblending[0] = pstudio->prev->curblending[0];
// MsgDev( D_INFO, "%f %d\n", e->angles[PITCH], pstudio->blending[0] );
// MsgDev( D_INFO, "%f %d\n", e->angles[PITCH], pstudio->prev->curblending[0] );
dt = bound( 0.0f, RI.refdef.frametime, 1.0f );
@ -2149,14 +1992,14 @@ void R_StudioProcessGait( ref_entity_t *e, edict_t *pplayer, studiovars_t *pstud
}
// adjust torso
pstudio->controller[0] = ((flYaw / 4.0) + 30) / (60.0 / 255.0);
pstudio->controller[1] = ((flYaw / 4.0) + 30) / (60.0 / 255.0);
pstudio->controller[2] = ((flYaw / 4.0) + 30) / (60.0 / 255.0);
pstudio->controller[3] = ((flYaw / 4.0) + 30) / (60.0 / 255.0);
pstudio->prev->controller[0] = pstudio->controller[0];
pstudio->prev->controller[1] = pstudio->controller[1];
pstudio->prev->controller[2] = pstudio->controller[2];
pstudio->prev->controller[3] = pstudio->controller[3];
pstudio->prev->curcontroller[0] = ((flYaw / 4.0) + 30) / (60.0 / 255.0);
pstudio->prev->curcontroller[1] = ((flYaw / 4.0) + 30) / (60.0 / 255.0);
pstudio->prev->curcontroller[2] = ((flYaw / 4.0) + 30) / (60.0 / 255.0);
pstudio->prev->curcontroller[3] = ((flYaw / 4.0) + 30) / (60.0 / 255.0);
pstudio->prev->controller[0] = pstudio->prev->curcontroller[0];
pstudio->prev->controller[1] = pstudio->prev->curcontroller[1];
pstudio->prev->controller[2] = pstudio->prev->curcontroller[2];
pstudio->prev->controller[3] = pstudio->prev->curcontroller[3];
e->angles[YAW] = pstudio->prev->gaityaw;
if( e->angles[YAW] < -0 ) e->angles[YAW] += 360;
@ -2197,7 +2040,7 @@ static bool R_StudioSetupModel( ref_entity_t *e, ref_model_t *mod )
if( e->ent_type == ED_CLIENT || e->renderfx == kRenderFxDeadPlayer )
{
// MsgDev( D_INFO, "DrawPlayer %d\n", pstudio->blending[0] );
// MsgDev( D_INFO, "DrawPlayer %d %d (%d)\n", r_framecount2, m_pEntity->serialnumber, e->sequence );
// MsgDev( D_INFO, "DrawPlayer %d %d (%d)\n", r_framecount2, m_pEntity->serialnumber, e->prev->cursequence );
// MsgDev( D_INFO, "Player %.2f %.2f %.2f\n", m_pEntity->v.velocity[0], m_pEntity->v.velocity[1], m_pEntity->v.velocity[2] );
if( e->renderfx == kRenderFxDeadPlayer )
@ -2213,7 +2056,7 @@ static bool R_StudioSetupModel( ref_entity_t *e, ref_model_t *mod )
if( m_pEntity->v.gaitsequence <= 0 )
{
for( i = 0; i < 4; i++ ) // clear torso controllers
pstudio->prev->controller[i] = pstudio->controller[i] = 0x7F;
pstudio->prev->controller[i] = pstudio->prev->curcontroller[i] = 0x7F;
e->gaitsequence = 0; // StudioSetupBones() issuses
R_StudioSetUpTransform ( e, false );
@ -2243,20 +2086,19 @@ static bool R_StudioSetupModel( ref_entity_t *e, ref_model_t *mod )
curframe = R_StudioSetupBones( e );
R_StudioSaveBones( e );
}
R_StudioSetupLighting( e, mod );
if( m_pEntity && e->movetype != MOVETYPE_FOLLOW && !RI.refdef.paused && e->m_nCachedFrameCount != r_framecount2 )
{
float flInterval = 0.01f;
float flStart = e->frame + (pstudio->prev->m_flLastEventCheck - e->animtime) * pstudio->prev->m_flFrameRate * e->framerate;
float flEnd = e->frame + flInterval * pstudio->prev->m_flFrameRate * e->framerate;
float flStart = e->prev->curframe + (pstudio->prev->m_flLastEventCheck - e->prev->curanimtime) * pstudio->prev->m_flFrameRate * e->framerate;
float flEnd = e->prev->curframe + flInterval * pstudio->prev->m_flFrameRate * e->framerate;
int index = 0;
dstudioevent_t event;
Mem_Set( &event, 0, sizeof( event ));
R_StudioCalcAttachments( e );
pstudio->prev->m_flLastEventCheck = e->animtime + flInterval;
pstudio->prev->m_flLastEventCheck = e->prev->curanimtime + flInterval;
pstudio->prev->m_fSequenceFinished = false;
if( flEnd >= 256.0f || flEnd <= 0.0f )
pstudio->prev->m_fSequenceFinished = true;
@ -2329,20 +2171,6 @@ void R_StudioDrawPoints( const meshbuffer_t *mb, ref_entity_t *e )
// initialize vertex cache
if( !studio->mesh[modelnum] )
studio->mesh[modelnum] = Mem_Alloc( e->mempool, sizeof( studioverts_t ));
if( r_studio_bonelighting->integer )
{
if( !studio->mesh[modelnum]->light || studio->mesh[modelnum]->numnorms != m_pSubModel->numnorms )
{
studio->mesh[modelnum]->light = Mem_Realloc( e->mempool, studio->mesh[modelnum]->light, sizeof( vec3_t ) * m_pSubModel->numnorms );
}
}
else
{
if( studio->mesh[modelnum]->light )
Mem_Free( studio->mesh[modelnum]->light );
studio->mesh[modelnum]->light = NULL;
}
if( studio->mesh[modelnum]->numverts != m_pSubModel->numverts )
studio->mesh[modelnum]->verts = Mem_Realloc( e->mempool, studio->mesh[modelnum]->verts, sizeof( vec3_t ) * m_pSubModel->numverts );
@ -2376,7 +2204,7 @@ void R_StudioDrawPoints( const meshbuffer_t *mb, ref_entity_t *e )
Matrix4x4_VectorRotate( m_pbonestransform[pnormbone[i]], pstudionorms[i], m_pxformnorms[i] );
}
if( m_pStudioHeader->flags & STUDIO_HAS_CHROME || r_studio_bonelighting->integer )
if( m_pStudioHeader->flags & STUDIO_HAS_CHROME )
{
for( i = 0; i < m_pSubModel->nummesh; i++ )
{
@ -2384,9 +2212,6 @@ void R_StudioDrawPoints( const meshbuffer_t *mb, ref_entity_t *e )
for( j = 0; j < pmesh[i].numnorms; j++, lv += 3, pstudionorms++, pnormbone++ )
{
if( r_studio_bonelighting->integer )
R_StudioLighting( lv, *pnormbone, flags, (float *)pstudionorms );
if(!( texflags & STUDIO_NF_CHROME )) continue;
R_StudioSetupChrome( m_pchrome[(float (*)[3])lv - m_pxformlight], modelnum, *pnormbone, (float *)pstudionorms );
}
@ -2458,12 +2283,12 @@ bool R_CullStudioModel( ref_entity_t *e )
{
// cull child entities with parent volume
R_StudioSetupRender( e->parent, e->parent->model );
sequence = e->parent->sequence;
sequence = e->parent->prev->cursequence;
}
else
{
R_StudioSetupRender( e, e->model );
sequence = e->sequence;
sequence = e->prev->cursequence;
}
if(!R_ExtractBbox( sequence, studio_mins, studio_maxs ))
@ -2528,12 +2353,12 @@ void R_AddStudioModelToList( ref_entity_t *e )
{
// cull child entities with parent volume
R_StudioSetupRender( e->parent, e->parent->model );
sequence = e->parent->sequence;
sequence = e->parent->prev->cursequence;
}
else
{
R_StudioSetupRender( e, e->model );
sequence = e->sequence;
sequence = e->prev->cursequence;
}
if(!R_ExtractBbox( sequence, studio_mins, studio_maxs )) return; // invalid sequence