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 GetScreenInfo (*g_engfuncs.pfnGetScreenInfo)
#define SPR_Load (*g_engfuncs.pfnSPR_Load) #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 SetCrosshair (*g_engfuncs.pfnSetCrosshair)
#define SendWeaponAnim (*g_engfuncs.pEventAPI->EV_WeaponAnim) #define SendWeaponAnim (*g_engfuncs.pEventAPI->EV_WeaponAnim)

View File

@ -5,6 +5,7 @@
#include "extdll.h" #include "extdll.h"
#include "utils.h" #include "utils.h"
#include "hud.h" #include "hud.h"
#include "triangle_api.h"
void CHud :: Init( void ) 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 ) 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; return 1;
} }
@ -415,8 +419,8 @@ int CHud :: MsgFunc_ScreenFade( const char *pszName, int iSize, void *pbuf )
{ {
BEGIN_READ( pszName, iSize, pbuf ); BEGIN_READ( pszName, iSize, pbuf );
float fadeTime = fabs( READ_SHORT() / (1<<12)); float fadeTime = READ_FLOAT();
float holdTime = fabs( READ_SHORT() / (1<<12)); float holdTime = READ_FLOAT();
int fadeFlags = READ_SHORT(); int fadeFlags = READ_SHORT();
Vector m_FadeColor; 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 char *(*pfnParseToken)( const char **data_p ); // was COM_ParseFile, like it
void (*pfnFreeFile)( void *buffer ); // was COM_FreeFile, 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 triapi_s *pTriAPI;
struct efxapi_s *pEfxAPI; struct efxapi_s *pEfxAPI;
struct event_api_s *pEventAPI; 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 ); size_t api_size; // must match with sizeof( triapi_t );
HSPRITE (*LoadShader)( const char *szShaderName, int fShaderNoMip );
void (*RenderMode)( kRenderMode_t mode ); void (*RenderMode)( kRenderMode_t mode );
void (*Begin)( TRI_DRAW mode ); void (*Begin)( TRI_DRAW mode );
void (*End)( void ); void (*End)( void );

View File

@ -141,14 +141,14 @@ byte CL_GetMouthOpen( int entityIndex )
return ed->pvClientData->mouth.open; return ed->pvClientData->mouth.open;
} }
prevframe_t *CL_GetPrevFrame( int entityIndex ) studioframe_t *CL_GetStudioFrame( int entityIndex )
{ {
edict_t *pEnt = CL_GetEdictByIndex( entityIndex ); edict_t *pEnt = CL_GetEdictByIndex( entityIndex );
if( !pEnt || !pEnt->pvClientData ) if( !pEnt || !pEnt->pvClientData )
return NULL; return NULL;
return &pEnt->pvClientData->latched; return &pEnt->pvClientData->frame;
} }
/* /*
@ -906,7 +906,7 @@ void CL_InitWorld( void )
} }
// clear viewmodel prevstate // 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 ) void CL_InitEdicts( void )
@ -1984,26 +1984,6 @@ void VGui_ViewportPaintBackground( int extents[4] )
// FIXME: implement // 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 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 ); 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 ) void TriRenderMode( kRenderMode_t mode )
{ {
if( !re ) return; if( !re ) return;
@ -2353,6 +2353,7 @@ void TriFog( float flFogColor[3], float flStart, float flEnd, int bOn )
static triapi_t gTriApi = static triapi_t gTriApi =
{ {
sizeof( triapi_t ), sizeof( triapi_t ),
TriLoadShader,
TriRenderMode, TriRenderMode,
TriBegin, TriBegin,
TriEnd, TriEnd,
@ -2482,7 +2483,6 @@ static cl_enginefuncs_t gEngfuncs =
pfnLoadFile, pfnLoadFile,
pfnParseToken, pfnParseToken,
pfnFreeFile, pfnFreeFile,
pfnLoadShader,
&gTriApi, &gTriApi,
&gEfxApi, &gEfxApi,
&gEventApi &gEventApi

View File

@ -433,7 +433,7 @@ void SCR_RegisterShaders( void )
// TODO: load a font with a variable charwidths // TODO: load a font with a variable charwidths
Mem_Set( &clgame.ds, 0, sizeof( clgame.ds )); // reset a draw state 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 // vid_state has changed

View File

@ -174,7 +174,7 @@ struct cl_priv_s
entity_state_t current; entity_state_t current;
entity_state_t prev; // will always be valid, but might just be a copy of 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 // studiomodels attachments
vec3_t origin[MAXSTUDIOATTACHMENTS]; 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_GetAttachment( int entityIndex, int number, vec3_t origin, vec3_t angles );
bool CL_SetAttachment( 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 ); 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_GetEdictByIndex( int index );
edict_t *CL_GetLocalPlayer( void ); edict_t *CL_GetLocalPlayer( void );
int CL_GetMaxClients( void ); int CL_GetMaxClients( void );

View File

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

View File

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

View File

@ -284,7 +284,7 @@ void Cmd_Exec_f( void )
return; return;
} }
MsgDev( D_INFO, "execing %s\n", Cmd_Argv( 1 )); MsgDev( D_LOAD, "execing %s\n", Cmd_Argv( 1 ));
Cbuf_InsertText( f ); Cbuf_InsertText( f );
Mem_Free( 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 NearestPOW

View File

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

View File

@ -259,7 +259,7 @@ CGrenade *CGrenade::ShootContact( entvars_t *pevOwner, Vector vecStart, Vector v
// Explode on contact // Explode on contact
pGrenade->SetTouch( ExplodeTouch ); 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 )); UTIL_SetSize( pGrenade->pev, Vector( 0, 0, 0 ), Vector( 0, 0, 0 ));
pGrenade->pev->dmg = M203_DMG; pGrenade->pev->dmg = M203_DMG;

View File

@ -1601,12 +1601,12 @@ void LinkUserMessages( void )
gmsg.AmmoPickup = REG_USER_MSG( "AmmoPickup", 2 ); gmsg.AmmoPickup = REG_USER_MSG( "AmmoPickup", 2 );
gmsg.WeapPickup = REG_USER_MSG( "WeapPickup", 1 ); gmsg.WeapPickup = REG_USER_MSG( "WeapPickup", 1 );
gmsg.ItemPickup = REG_USER_MSG( "ItemPickup", -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.HideWeapon = REG_USER_MSG( "HideWeapon", 1 );
gmsg.WeaponAnim = REG_USER_MSG( "WeaponAnim", 3 ); gmsg.WeaponAnim = REG_USER_MSG( "WeaponAnim", 3 );
gmsg.ShowMenu = REG_USER_MSG( "ShowMenu", -1 ); gmsg.ShowMenu = REG_USER_MSG( "ShowMenu", -1 );
gmsg.Shake = REG_USER_MSG( "ScreenShake", 13 ); 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.AmmoX = REG_USER_MSG("AmmoX", 2);
gmsg.TeamNames = REG_USER_MSG( "TeamNames", -1 ); gmsg.TeamNames = REG_USER_MSG( "TeamNames", -1 );
gmsg.StatusText = REG_USER_MSG("StatusText", -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_FadeColor = color;
pPlayer->m_FadeAlpha = alpha; pPlayer->m_FadeAlpha = alpha;
pPlayer->m_iFadeFlags = flags; pPlayer->m_iFadeFlags = flags;
pPlayer->m_iFadeTime = fadeTime; pPlayer->m_flFadeTime = fadeTime;
pPlayer->m_iFadeHold = fadeHold; pPlayer->m_flFadeHold = fadeHold;
pPlayer->fadeNeedsUpdate = TRUE; pPlayer->fadeNeedsUpdate = TRUE;
} }
} }

View File

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

View File

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

View File

@ -19,6 +19,7 @@ typedef struct
float fDamping; float fDamping;
} dsproom_t; } dsproom_t;
static soundfade_t soundfade;
static playSound_t s_playSounds[MAX_PLAYSOUNDS]; static playSound_t s_playSounds[MAX_PLAYSOUNDS];
static playSound_t s_freePlaySounds; static playSound_t s_freePlaySounds;
static playSound_t s_pendingPlaySounds; static playSound_t s_pendingPlaySounds;
@ -118,6 +119,23 @@ bool S_CheckForErrors( void )
return true; 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 S_FadeClientVolume
@ -125,7 +143,57 @@ S_FadeClientVolume
*/ */
void S_FadeClientVolume( float fadePercent, float fadeOutSeconds, float holdTime, float fadeInSeconds ) 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; if( !ch->sfx ) continue;
S_StopChannel( ch ); S_StopChannel( ch );
} }
// clear any remaining soundfade
Mem_Set( &soundfade, 0, sizeof( soundfade ));
S_StopStreaming(); // stop streaming channel S_StopStreaming(); // stop streaming channel
S_StopBackgroundTrack(); // stop background track S_StopBackgroundTrack(); // stop background track
@ -643,7 +714,8 @@ void S_Update( ref_params_t *fd )
al_state.clientnum = fd->viewentity; al_state.clientnum = fd->viewentity;
al_state.refdef = fd; // for using everthing else 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 // set up listener
VectorSet( s_listener.position, fd->simorg[1], fd->simorg[2], -fd->simorg[0] ); 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_POSITION, s_listener.position );
palListenerfv( AL_VELOCITY, s_listener.velocity ); palListenerfv( AL_VELOCITY, s_listener.velocity );
palListenerfv( AL_ORIENTATION, s_listener.orientation ); 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 // Set state
palDistanceModel( AL_INVERSE_DISTANCE_CLAMPED ); palDistanceModel( AL_INVERSE_DISTANCE_CLAMPED );
@ -730,7 +802,7 @@ void S_Activate( bool active )
return; return;
al_state.active = active; 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 ); else palListenerf( AL_GAIN, 0.0 );
} }

View File

@ -91,6 +91,17 @@ typedef struct playsound_s
float pitch; float pitch;
} playSound_t; } 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 typedef struct
{ {
bool streaming; bool streaming;

View File

@ -12,6 +12,7 @@
#define MAX_PLAYSOUNDS 128 #define MAX_PLAYSOUNDS 128
dma_t dma; dma_t dma;
static soundfade_t soundfade;
channel_t channels[MAX_CHANNELS]; channel_t channels[MAX_CHANNELS];
bool sound_started = false; bool sound_started = false;
vec3_t listener_origin; 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 S_FadeClientVolume
@ -57,7 +75,57 @@ S_FadeClientVolume
*/ */
void S_FadeClientVolume( float fadePercent, float fadeOutSeconds, float holdTime, float fadeInSeconds ) 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 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 // clear all the channels
Mem_Set( channels, 0, sizeof( channels )); Mem_Set( channels, 0, sizeof( channels ));
S_ClearBuffer (); S_ClearBuffer ();
@ -661,8 +733,12 @@ void S_Update( ref_params_t *fd )
return; return;
} }
// update any client side sound fade
S_UpdateSoundFade();
// rebuild scale tables if volume is modified // 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; s_clientnum = fd->viewentity;
VectorCopy( fd->simorg, listener_origin ); VectorCopy( fd->simorg, listener_origin );

View File

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

View File

@ -61,6 +61,17 @@ typedef struct playsound_s
uint begin; // begin on this sample uint begin; // begin on this sample
} playsound_t; } 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 typedef struct
{ {
int channels; int channels;
@ -170,6 +181,7 @@ void S_InitScaletable( void );
sfxcache_t *S_LoadSound( sfx_t *sfx ); sfxcache_t *S_LoadSound( sfx_t *sfx );
void S_IssuePlaysound( playsound_t *ps ); void S_IssuePlaysound( playsound_t *ps );
void S_PaintChannels( int endtime ); void S_PaintChannels( int endtime );
float S_GetMasterVolume( void );
// s_load.c // s_load.c
bool S_TestSoundChar( const char *pch, char c ); bool S_TestSoundChar( const char *pch, char c );

View File

@ -162,7 +162,7 @@ Beta 13.12.09
136. re-vision uimenu 136. re-vision uimenu
137. complete rewriting physic.dll OK 137. complete rewriting physic.dll OK
138. implement hashtable for loaded sounds OK 138. implement hashtable for loaded sounds OK
139. finalize client API's 139. finalize triangle API
140. net_msg is buggly!!!! OK 140. net_msg is buggly!!!! OK
141. implement client predicting OK 141. implement client predicting OK
142. finalize CL_Move and CL_LinkEdict OK 142. finalize CL_Move and CL_LinkEdict OK
@ -188,7 +188,9 @@ Beta 13.12.09
162. rewrote auto-classify OK 162. rewrote auto-classify OK
163. rewrote sv_phys.c OK 163. rewrote sv_phys.c OK
164. remove vprogs.dll OK 164. remove vprogs.dll OK
165. fix bsplib error 165. finalize EventAPI
166. move cl_input.c into client.dll OK 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; break;
case RGBGEN_LIGHTING_DIFFUSE: case RGBGEN_LIGHTING_DIFFUSE:
if( r_studio_bonelighting->integer && RI.currentmodel && RI.currentmodel->type == mod_studio ) if( RI.currententity ) R_LightForEntity( RI.currententity, bArray );
{
// 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 );
break; break;
case RGBGEN_LIGHTING_DIFFUSE_ONLY: case RGBGEN_LIGHTING_DIFFUSE_ONLY:
if( RI.currententity && !( RI.params & RP_SHADOWMAPVIEW ) ) 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_model_s *model; // opaque type outside refresh
struct ref_entity_s *parent; // link to parent entity (FOLLOW or weaponmodel) 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 framerate; // custom framerate
float animtime; // lerping animtime float frame;
float frame; // also used as RF_BEAM's diameter
int body; int body;
int skin; int skin;
int movetype; // entity moving type int movetype; // entity moving type
int sequence;
float scale; float scale;
byte *mempool; // studio mempool byte *mempool; // studio mempool
@ -430,9 +428,6 @@ extern cvar_t *r_outlines_scale;
extern cvar_t *r_outlines_cutoff; extern cvar_t *r_outlines_cutoff;
extern cvar_t *r_himodels; extern cvar_t *r_himodels;
extern cvar_t *r_studio_bonelighting;
extern cvar_t *r_environment_color; extern cvar_t *r_environment_color;
extern cvar_t *r_gamma; extern cvar_t *r_gamma;
extern cvar_t *r_texturebits; 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 ) if( !refent->model->extradata )
return false; return false;
refent->scale = 1.0f; // ignore scale for brush models refent->scale = 1.0f; // ignore scale for brush models
refent->frame = pRefEntity->v.frame; // brush properly animating
break; break;
case mod_studio: case mod_studio:
case mod_sprite: case mod_sprite:
@ -2124,7 +2125,7 @@ bool R_AddGenericEntity( edict_t *pRefEntity, ref_entity_t *refent )
break; break;
} }
refent->prev = ri.GetPrevFrame( refent->index ); // setup prevframe data refent->prev = ri.GetStudioFrame( refent->index ); // setup prevframe data
if( refent->prev == NULL ) 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; float numframes = ((msprite_t *)refent->model->extradata)->numframes;
refent->frame += (pRefEntity->v.framerate * RI.refdef.frametime); refent->prev->curframe += (pRefEntity->v.framerate * RI.refdef.frametime);
if( refent->frame > numframes && numframes > 0 ) if( refent->prev->curframe > numframes && numframes > 0 )
refent->frame = fmod( refent->frame, numframes ); refent->prev->curframe = fmod( refent->prev->curframe, numframes );
} }
break; break;
case mod_studio: case mod_studio:
@ -2168,8 +2169,8 @@ bool R_AddGenericEntity( edict_t *pRefEntity, ref_entity_t *refent )
else else
{ {
if( refent->prev ) if( refent->prev )
refent->prev->frame = refent->frame; // save oldframe refent->prev->frame = refent->prev->curframe; // save oldframe
refent->frame = pRefEntity->v.frame; refent->prev->curframe = pRefEntity->v.frame;
} }
if( refent->ent_type == ED_MOVER || refent->ent_type == ED_BSPBRUSH ) 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; float *pintervals, fullinterval, targettime, time;
psprite = ent->model->extradata; psprite = ent->model->extradata;
frame = (int)ent->frame; frame = (int)ent->prev->curframe;
if((frame >= psprite->numframes) || (frame < 0)) if((frame >= psprite->numframes) || (frame < 0))
{ {
@ -317,7 +317,7 @@ float R_GetSpriteFrameInterpolant( ref_entity_t *ent, mspriteframe_t **oldframe,
int m_fDoInterp; int m_fDoInterp;
psprite = ent->model->extradata; psprite = ent->model->extradata;
frame = (int)ent->frame; frame = (int)ent->prev->curframe;
lerpFrac = 1.0f; lerpFrac = 1.0f;
// misc info // 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 // this can be happens when rendering switched between single and angled frames
// or change model on replace delta-entity // or change model on replace delta-entity
ent->prev->sequence = ent->sequence = frame; ent->prev->sequence = ent->prev->cursequence = frame;
ent->animtime = RI.refdef.time; ent->prev->curanimtime = RI.refdef.time;
lerpFrac = 1.0f; 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->prev->sequence = ent->prev->cursequence;
ent->sequence = frame; ent->prev->cursequence = frame;
ent->animtime = RI.refdef.time; ent->prev->curanimtime = RI.refdef.time;
lerpFrac = 0.0f; lerpFrac = 0.0f;
} }
else lerpFrac = (RI.refdef.time - ent->animtime) * ent->framerate; else lerpFrac = (RI.refdef.time - ent->prev->curanimtime) * ent->framerate;
} }
else else
{ {
ent->prev->sequence = ent->sequence = frame; ent->prev->sequence = ent->prev->cursequence = frame;
ent->animtime = RI.refdef.time; ent->prev->curanimtime = RI.refdef.time;
lerpFrac = 0.0f; lerpFrac = 0.0f;
} }
} }
else else
{ {
ent->prev->sequence = ent->sequence = frame; ent->prev->sequence = ent->prev->cursequence = frame;
lerpFrac = 1.0f; lerpFrac = 1.0f;
} }
if( ent->prev->sequence >= psprite->numframes ) if( ent->prev->sequence >= psprite->numframes )
{ {
// reset interpolation on change model // reset interpolation on change model
ent->prev->sequence = ent->sequence = frame; ent->prev->sequence = ent->prev->cursequence = frame;
ent->animtime = RI.refdef.time; ent->prev->curanimtime = RI.refdef.time;
lerpFrac = 0.0f; 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 // this can be happens when rendering switched between single and angled frames
// or change model on replace delta-entity // or change model on replace delta-entity
ent->prev->sequence = ent->sequence = frame; ent->prev->sequence = ent->prev->cursequence = frame;
ent->animtime = RI.refdef.time; ent->prev->curanimtime = RI.refdef.time;
lerpFrac = 1.0f; 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->prev->sequence = ent->prev->cursequence;
ent->sequence = frame; ent->prev->cursequence = frame;
ent->animtime = RI.refdef.time; ent->prev->curanimtime = RI.refdef.time;
lerpFrac = 0.0f; lerpFrac = 0.0f;
} }
else lerpFrac = (RI.refdef.time - ent->animtime) * ent->framerate; else lerpFrac = (RI.refdef.time - ent->prev->curanimtime) * ent->framerate;
} }
else else
{ {
ent->prev->sequence = ent->sequence = frame; ent->prev->sequence = ent->prev->cursequence = frame;
ent->animtime = RI.refdef.time; ent->prev->curanimtime = RI.refdef.time;
lerpFrac = 0.0f; lerpFrac = 0.0f;
} }
} }
else else
{ {
ent->prev->sequence = ent->sequence = frame; ent->prev->sequence = ent->prev->cursequence = frame;
lerpFrac = 1.0f; lerpFrac = 1.0f;
} }

View File

@ -44,21 +44,7 @@ vec3_t studio_mins, studio_maxs;
float studio_radius; float studio_radius;
// studio cvars // studio cvars
cvar_t *r_studio_bonelighting;
cvar_t *r_studio_lerping; 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 typedef struct studioverts_s
{ {
@ -73,11 +59,9 @@ typedef struct studioverts_s
typedef struct studiovars_s typedef struct studiovars_s
{ {
byte blending[MAXSTUDIOBLENDS]; studioframe_t *prev; // duplcate e->prev for consistency
byte controller[MAXSTUDIOCONTROLLERS];
prevframe_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 char bonenames[MAXSTUDIOBONES][32];// used for attached entities
studioverts_t *mesh[MAXSTUDIOMODELS]; studioverts_t *mesh[MAXSTUDIOMODELS];
matrix4x4 rotationmatrix; matrix4x4 rotationmatrix;
@ -86,9 +70,6 @@ typedef struct studiovars_s
vec3_t *chromeup; vec3_t *chromeup;
int *chromeage; int *chromeage;
int numbones; int numbones;
// StudioBoneLighting (slow but ugly)
studiolight_t *light; // FIXME: alloc match size not maximum
} studiovars_t; } studiovars_t;
/* /*
@ -105,8 +86,6 @@ void R_StudioInit( void )
m_pStudioHeader = NULL; m_pStudioHeader = NULL;
m_flGaitMovement = 1; 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" ); r_studio_lerping = Cvar_Get( "r_studio_lerping", "1", CVAR_ARCHIVE, "enables studio model animation lerping" );
for( i = 1; i < MAX_ENTITIES; i++ ) for( i = 1; i < MAX_ENTITIES; i++ )
@ -145,34 +124,34 @@ void R_StudioAllocExtradata( edict_t *in, ref_entity_t *e )
// copy controllers // copy controllers
for( i = 0; i < MAXSTUDIOCONTROLLERS; i++ ) for( i = 0; i < MAXSTUDIOCONTROLLERS; i++ )
{ {
studio->prev->controller[i] = studio->controller[i]; studio->prev->controller[i] = studio->prev->curcontroller[i];
studio->controller[i] = in->v.controller[i]; studio->prev->curcontroller[i] = in->v.controller[i];
} }
// copy blends // copy blends
for( i = 0; i < MAXSTUDIOBLENDS; i++ ) for( i = 0; i < MAXSTUDIOBLENDS; i++ )
{ {
studio->prev->blending[i] = studio->blending[i]; studio->prev->blending[i] = studio->prev->curblending[i];
studio->blending[i] = in->v.blending[i]; studio->prev->curblending[i] = in->v.blending[i];
} }
// sequence has changed, hold the previous sequence info // 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->sequencetime = e->prev->animtime + 0.01f;
studio->prev->sequence = e->sequence; studio->prev->sequence = e->prev->cursequence;
// save current blendings // save current blendings
for( i = 0; i < MAXSTUDIOBLENDS; i++ ) 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( e->flags & EF_ANIMATE )
{ {
if( in->v.frame == -1 ) if( in->v.frame == -1 )
{ {
in->v.frame = e->frame = 0; in->v.frame = e->prev->curframe = 0;
e->sequence = in->v.sequence; e->prev->cursequence = in->v.sequence;
R_StudioResetSequenceInfo( e ); R_StudioResetSequenceInfo( e );
} }
else else
@ -189,15 +168,15 @@ void R_StudioAllocExtradata( edict_t *in, ref_entity_t *e )
else else
{ {
// copy current frame back to let user grab it on a client-side // 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 else
{ {
e->sequence = in->v.sequence; e->prev->cursequence = in->v.sequence;
e->prev->animtime = e->animtime; // must be update each frame! e->prev->animtime = e->prev->curanimtime; // must be update each frame!
e->animtime = in->v.animtime; e->prev->curanimtime = in->v.animtime;
} }
if( studio->numbones != numbones ) if( studio->numbones != numbones )
@ -228,17 +207,6 @@ void R_StudioAllocExtradata( edict_t *in, ref_entity_t *e )
studio->chromeage = NULL; studio->chromeage = NULL;
} }
studio->numbones = numbones; 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 ) 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; hdr = ((mstudiomodel_t *)e->model->extradata)->phdr;
if( !hdr ) return; 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; dstudioseqdesc_t *pseqdesc;
if( !hdr || ent->sequence >= hdr->numseq ) if( !hdr || ent->prev->cursequence >= hdr->numseq )
return 0.0f; 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; return pseqdesc->numframes / pseqdesc->fps;
} }
@ -575,10 +543,10 @@ int R_StudioGetSequenceFlags( dstudiohdr_t *hdr, ref_entity_t *ent )
{ {
dstudioseqdesc_t *pseqdesc; dstudioseqdesc_t *pseqdesc;
if( !hdr || ent->sequence >= hdr->numseq ) if( !hdr || ent->prev->cursequence >= hdr->numseq )
return 0; 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; return pseqdesc->flags;
} }
@ -586,14 +554,14 @@ void R_StuioGetSequenceInfo( dstudiohdr_t *hdr, ref_entity_t *ent, float *pflFra
{ {
dstudioseqdesc_t *pseqdesc; dstudioseqdesc_t *pseqdesc;
if( !hdr || ent->sequence >= hdr->numseq ) if( !hdr || ent->prev->cursequence >= hdr->numseq )
{ {
*pflFrameRate = 0.0; *pflFrameRate = 0.0;
*pflGroundSpeed = 0.0; *pflGroundSpeed = 0.0;
return; return;
} }
pseqdesc = (dstudioseqdesc_t *)((byte *)hdr + hdr->seqindex) + ent->sequence; pseqdesc = (dstudioseqdesc_t *)((byte *)hdr + hdr->seqindex) + ent->prev->cursequence;
if( pseqdesc->numframes > 1 ) if( pseqdesc->numframes > 1 )
{ {
@ -617,23 +585,23 @@ float R_StudioFrameAdvance( ref_entity_t *ent, float flInterval )
if( flInterval == 0.0 ) if( flInterval == 0.0 )
{ {
flInterval = ( RI.refdef.time - ent->animtime ); flInterval = ( RI.refdef.time - ent->prev->curanimtime );
if( flInterval <= 0.001 ) if( flInterval <= 0.001 )
{ {
ent->animtime = RI.refdef.time; ent->prev->curanimtime = RI.refdef.time;
return 0.0; 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->prev->curframe += flInterval * pstudio->prev->m_flFrameRate * ent->framerate;
ent->animtime = RI.refdef.time; 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 ) if( pstudio->prev->m_fSequenceLoops )
ent->frame -= (int)(ent->frame / 256.0) * 256.0; ent->prev->curframe -= (int)(ent->prev->curframe / 256.0) * 256.0;
else ent->frame = (ent->frame < 0.0) ? 0 : 255; else ent->prev->curframe = (ent->prev->curframe < 0.0) ? 0 : 255;
pstudio->prev->m_fSequenceFinished = true; pstudio->prev->m_fSequenceFinished = true;
} }
return flInterval; 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 ); R_StuioGetSequenceInfo( hdr, ent, &pstudio->prev->m_flFrameRate, &pstudio->prev->m_flGroundSpeed );
pstudio->prev->m_fSequenceLoops = ((R_StudioGetSequenceFlags( hdr, ent ) & STUDIO_LOOPING) != 0 ); pstudio->prev->m_fSequenceLoops = ((R_StudioGetSequenceFlags( hdr, ent ) & STUDIO_LOOPING) != 0 );
ent->prev->animtime = ent->animtime; ent->prev->animtime = ent->prev->curanimtime;
ent->animtime = RI.refdef.time; ent->prev->curanimtime = RI.refdef.time;
pstudio->prev->m_fSequenceFinished = false; pstudio->prev->m_fSequenceFinished = false;
pstudio->prev->m_flLastEventCheck = RI.refdef.time; 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; dstudioevent_t *pevent;
int events = 0; 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); pevent = (dstudioevent_t *)((byte *)m_pStudioHeader + pseqdesc->eventindex);
if( pseqdesc->numevents == 0 || index > pseqdesc->numevents ) if( pseqdesc->numevents == 0 || index > pseqdesc->numevents )
@ -1087,9 +1055,9 @@ float R_StudioEstimateInterpolant( void )
{ {
float dadt = 1.0; 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; if( dadt > 2.0 ) dadt = 2.0;
} }
return dadt; return dadt;
@ -1127,7 +1095,7 @@ void R_StudioCalcRotations( float pos[][3], vec4_t *q, dstudioseqdesc_t *pseqdes
pstudio = RI.currententity->extradata; pstudio = RI.currententity->extradata;
Com_Assert( pstudio == NULL ); 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( "%f %f %f\n", RI.currententity->angles[ROLL], RI.currententity->angles[PITCH], RI.currententity->angles[YAW] );
// Msg("frame %d %d\n", frame1, frame2 ); // 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); pbone = (dstudiobone_t *)((byte *)m_pStudioHeader + m_pStudioHeader->boneindex);
mouthopen = ri.GetMouthOpen( RI.currententity->index ); 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++) for (i = 0; i < m_pStudioHeader->numbones; i++, pbone++, panim++)
{ {
R_StudioCalcBoneQuaterion( frame, s, pbone, panim, adj, q[i] ); R_StudioCalcBoneQuaterion( frame, s, pbone, panim, adj, q[i] );
R_StudioCalcBonePosition( frame, s, pbone, panim, adj, pos[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; 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( m_fDoInterp )
{ {
if( RI.refdef.time < RI.currententity->animtime ) dfdt = 0; if( RI.refdef.time < RI.currententity->prev->curanimtime ) dfdt = 0;
else dfdt = (RI.refdef.time - RI.currententity->animtime) * RI.currententity->framerate * pseqdesc->fps; else dfdt = (RI.refdef.time - RI.currententity->prev->curanimtime) * RI.currententity->framerate * pseqdesc->fps;
} }
else dfdt = 0; else dfdt = 0;
if( pseqdesc->numframes <= 1 ) f = 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; f += dfdt;
@ -1226,8 +1194,8 @@ float R_StudioSetupBones( ref_entity_t *e )
return 0.0f; return 0.0f;
cl_entity = ri.GetClientEdict( e->index ); cl_entity = ri.GetClientEdict( e->index );
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;
f = R_StudioEstimateFrame( pseqdesc ); f = R_StudioEstimateFrame( pseqdesc );
@ -1248,7 +1216,7 @@ float R_StudioSetupBones( ref_entity_t *e )
R_StudioCalcRotations( pos2, q2, pseqdesc, panim, f ); R_StudioCalcRotations( pos2, q2, pseqdesc, panim, f );
dadt = R_StudioEstimateInterpolant(); 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 ); R_StudioSlerpBones( q, pos, q2, pos2, s );
@ -1260,10 +1228,10 @@ float R_StudioSetupBones( ref_entity_t *e )
panim += m_pStudioHeader->numbones; panim += m_pStudioHeader->numbones;
R_StudioCalcRotations( pos4, q4, pseqdesc, panim, f ); 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 ); 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 ); 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; int i, j;
double f; double f;
int sequence = e->sequence; int sequence = e->prev->cursequence;
dstudiobone_t *pbones; dstudiobone_t *pbones;
dstudioseqdesc_t *pseqdesc; dstudioseqdesc_t *pseqdesc;
dstudioanim_t *panim; dstudioanim_t *panim;
@ -1487,7 +1455,7 @@ bool R_StudioComputeBBox( vec3_t bbox[8] )
vec3_t vectors[3]; vec3_t vectors[3];
ref_entity_t *e = RI.currententity; ref_entity_t *e = RI.currententity;
vec3_t tmp, angles; 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 )) if(!R_ExtractBbox( seq, studio_mins, studio_maxs ))
return false; 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; 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 ) void R_StudioSetupChrome( float *pchrome, int modelnum, int bone, float *normal )
{ {
float n; float n;
@ -1744,16 +1597,6 @@ void R_StudioDrawMesh( const meshbuffer_t *mb, short *ptricmds, float s, float t
if( flags & STUDIO_NF_CHROME ) if( flags & STUDIO_NF_CHROME )
Vector2Set( inCoordsArray[r_backacc.numVerts], m_pchrome[ptricmds[1]][0] * s, m_pchrome[ptricmds[1]][1] * t ); 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 ); 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 ) 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 float dt, flYaw; // view direction relative to movement
int iBlend; int iBlend;
if( e->sequence >= m_pStudioHeader->numseq ) if( e->prev->cursequence >= m_pStudioHeader->numseq )
e->sequence = 0; 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] ); R_StudioPlayerBlend( pseqdesc, &iBlend, &e->angles[PITCH] );
pstudio->blending[0] = iBlend; pstudio->prev->curblending[0] = iBlend;
pstudio->prev->blending[0] = pstudio->blending[0]; pstudio->prev->blending[0] = pstudio->prev->curblending[0];
pstudio->prev->seqblending[0] = pstudio->blending[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 ); 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 // adjust torso
pstudio->controller[0] = ((flYaw / 4.0) + 30) / (60.0 / 255.0); pstudio->prev->curcontroller[0] = ((flYaw / 4.0) + 30) / (60.0 / 255.0);
pstudio->controller[1] = ((flYaw / 4.0) + 30) / (60.0 / 255.0); pstudio->prev->curcontroller[1] = ((flYaw / 4.0) + 30) / (60.0 / 255.0);
pstudio->controller[2] = ((flYaw / 4.0) + 30) / (60.0 / 255.0); pstudio->prev->curcontroller[2] = ((flYaw / 4.0) + 30) / (60.0 / 255.0);
pstudio->controller[3] = ((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->controller[0]; pstudio->prev->controller[0] = pstudio->prev->curcontroller[0];
pstudio->prev->controller[1] = pstudio->controller[1]; pstudio->prev->controller[1] = pstudio->prev->curcontroller[1];
pstudio->prev->controller[2] = pstudio->controller[2]; pstudio->prev->controller[2] = pstudio->prev->curcontroller[2];
pstudio->prev->controller[3] = pstudio->controller[3]; pstudio->prev->controller[3] = pstudio->prev->curcontroller[3];
e->angles[YAW] = pstudio->prev->gaityaw; e->angles[YAW] = pstudio->prev->gaityaw;
if( e->angles[YAW] < -0 ) e->angles[YAW] += 360; 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 ) if( e->ent_type == ED_CLIENT || e->renderfx == kRenderFxDeadPlayer )
{ {
// MsgDev( D_INFO, "DrawPlayer %d\n", pstudio->blending[0] ); // 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] ); // 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 ) 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 ) if( m_pEntity->v.gaitsequence <= 0 )
{ {
for( i = 0; i < 4; i++ ) // clear torso controllers 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 e->gaitsequence = 0; // StudioSetupBones() issuses
R_StudioSetUpTransform ( e, false ); R_StudioSetUpTransform ( e, false );
@ -2243,20 +2086,19 @@ static bool R_StudioSetupModel( ref_entity_t *e, ref_model_t *mod )
curframe = R_StudioSetupBones( e ); curframe = R_StudioSetupBones( e );
R_StudioSaveBones( e ); R_StudioSaveBones( e );
} }
R_StudioSetupLighting( e, mod );
if( m_pEntity && e->movetype != MOVETYPE_FOLLOW && !RI.refdef.paused && e->m_nCachedFrameCount != r_framecount2 ) if( m_pEntity && e->movetype != MOVETYPE_FOLLOW && !RI.refdef.paused && e->m_nCachedFrameCount != r_framecount2 )
{ {
float flInterval = 0.01f; float flInterval = 0.01f;
float flStart = e->frame + (pstudio->prev->m_flLastEventCheck - e->animtime) * 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->frame + flInterval * pstudio->prev->m_flFrameRate * e->framerate; float flEnd = e->prev->curframe + flInterval * pstudio->prev->m_flFrameRate * e->framerate;
int index = 0; int index = 0;
dstudioevent_t event; dstudioevent_t event;
Mem_Set( &event, 0, sizeof( event )); Mem_Set( &event, 0, sizeof( event ));
R_StudioCalcAttachments( e ); R_StudioCalcAttachments( e );
pstudio->prev->m_flLastEventCheck = e->animtime + flInterval; pstudio->prev->m_flLastEventCheck = e->prev->curanimtime + flInterval;
pstudio->prev->m_fSequenceFinished = false; pstudio->prev->m_fSequenceFinished = false;
if( flEnd >= 256.0f || flEnd <= 0.0f ) if( flEnd >= 256.0f || flEnd <= 0.0f )
pstudio->prev->m_fSequenceFinished = true; pstudio->prev->m_fSequenceFinished = true;
@ -2329,20 +2171,6 @@ void R_StudioDrawPoints( const meshbuffer_t *mb, ref_entity_t *e )
// initialize vertex cache // initialize vertex cache
if( !studio->mesh[modelnum] ) if( !studio->mesh[modelnum] )
studio->mesh[modelnum] = Mem_Alloc( e->mempool, sizeof( studioverts_t )); 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 ) 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 ); 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] ); 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++ ) 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++ ) 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; if(!( texflags & STUDIO_NF_CHROME )) continue;
R_StudioSetupChrome( m_pchrome[(float (*)[3])lv - m_pxformlight], modelnum, *pnormbone, (float *)pstudionorms ); 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 // cull child entities with parent volume
R_StudioSetupRender( e->parent, e->parent->model ); R_StudioSetupRender( e->parent, e->parent->model );
sequence = e->parent->sequence; sequence = e->parent->prev->cursequence;
} }
else else
{ {
R_StudioSetupRender( e, e->model ); R_StudioSetupRender( e, e->model );
sequence = e->sequence; sequence = e->prev->cursequence;
} }
if(!R_ExtractBbox( sequence, studio_mins, studio_maxs )) 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 // cull child entities with parent volume
R_StudioSetupRender( e->parent, e->parent->model ); R_StudioSetupRender( e->parent, e->parent->model );
sequence = e->parent->sequence; sequence = e->parent->prev->cursequence;
} }
else else
{ {
R_StudioSetupRender( e, e->model ); R_StudioSetupRender( e, e->model );
sequence = e->sequence; sequence = e->prev->cursequence;
} }
if(!R_ExtractBbox( sequence, studio_mins, studio_maxs )) return; // invalid sequence if(!R_ExtractBbox( sequence, studio_mins, studio_maxs )) return; // invalid sequence