Send custom data via svc_director message instead of delta.

Minor refactoring.
This commit is contained in:
s1lent 2018-01-02 20:32:24 +07:00
parent a672305041
commit 33ce752b11
No known key found for this signature in database
GPG Key ID: 0FE401DC73916B5C
15 changed files with 321 additions and 109 deletions

View File

@ -46,6 +46,7 @@ typedef struct _UserMsg
} UserMsg; } UserMsg;
bool HookUserMsg(char *pszMsgName, pfnUserMsgHook pfn); bool HookUserMsg(char *pszMsgName, pfnUserMsgHook pfn);
bool UnHookUserMsg(char *pszMsgName);
extern UserMsg *g_pClientUserMsgs; extern UserMsg *g_pClientUserMsgs;
extern std::map<std::string, pfnUserMsgHook> g_ClientUserMsgsMap; extern std::map<std::string, pfnUserMsgHook> g_ClientUserMsgsMap;

View File

@ -188,5 +188,8 @@ typedef struct playermove_s
void (*PM_PlaySound)(int channel, const char *sample, float volume, float attenuation, int fFlags, int pitch); void (*PM_PlaySound)(int channel, const char *sample, float volume, float attenuation, int fFlags, int pitch);
const char *(*PM_TraceTexture)(int ground, float *vstart, float *vend); const char *(*PM_TraceTexture)(int ground, float *vstart, float *vend);
void (*PM_PlaybackEventFull)(int flags, int clientindex, unsigned short eventindex, float delay, float *origin, float *angles, float fparam1, float fparam2, int iparam1, int iparam2, int bparam1, int bparam2); void (*PM_PlaybackEventFull)(int flags, int clientindex, unsigned short eventindex, float delay, float *origin, float *angles, float fparam1, float fparam2, int iparam1, int iparam2, int bparam1, int bparam2);
pmtrace_t (*PM_PlayerTraceEx)(float *start, float *end, int traceFlags, int (*pfnIgnore)(physent_t *pe));
int (*PM_TestPlayerPositionEx)(float *pos, pmtrace_t *ptrace, int (*pfnIgnore)(physent_t *pe));
struct pmtrace_s *(*PM_TraceLineEx)(float *start, float *end, int flags, int usehulll, int (*pfnIgnore)(physent_t *pe));
} playermove_t; } playermove_t;

View File

@ -44,44 +44,104 @@ int Initialize(cl_enginefunc_t *pEnginefuncs, int iVersion)
void HUD_Init() void HUD_Init()
{ {
g_pClientfuncs->pHudFrame = HUD_Frame;
g_pClientfuncs->pPostRunCmd = HUD_PostRunCmd; g_pClientfuncs->pPostRunCmd = HUD_PostRunCmd;
g_pClientfuncs->pProcessPlayerState = HUD_ProcessPlayerState;
g_pClientfuncs->pStudioInterface = HUD_GetStudioModelInterface; g_pClientfuncs->pStudioInterface = HUD_GetStudioModelInterface;
g_pClientfuncs->pDirectorMessage = HUD_DirectorMessage;
gClientfuncs.pHudInitFunc(); gClientfuncs.pHudInitFunc();
gHUD.Init(); gHUD.Init();
} }
void HUD_WeaponsPostThink(local_state_t *from, local_state_t *to, usercmd_t *cmd, double time, unsigned int random_seed) void HUD_Frame(double time)
{ {
int flags = from->client.iuser3; net_status_t st;
gEngfuncs.pNetAPI->Status(&st);
g_bHoldingKnife = (from->client.m_iId == WEAPON_KNIFE); const auto delay = 0.5;
g_bHoldingShield = (flags & PLAYER_HOLDING_SHIELD) != 0; if (st.connected == 1 && st.connection_time > (delay - 0.1) && st.connection_time < delay)
{
// tell the server that i want to sync
gEngfuncs.pfnServerCmd("__request_sync");
}
gClientfuncs.pHudFrame(time);
} }
void HUD_ProcessPlayerState(entity_state_t *dst, entity_state_t *src) union split_double_t
{ {
// save current values of fields from server-side split_double_t() : d (0.0) {}
auto &sync = g_PlayerSyncInfo[src->number]; split_double_t(double f) : d(f) {}
sync.yaw = src->vuser1[0]; double d;
sync.gaityaw = src->vuser1[1]; struct {
sync.gaitframe = src->vuser1[2]; int32_t lo;
int32_t hi;
};
};
sync.gaitmovement = src->vuser2[0]; constexpr size_t DIRECTOR_UID = 0xabcdef00;
sync.gaitsequence = src->vuser2[1];
sync.pitch = src->vuser2[2];
sync.prevgaitorigin[0] = src->maxs[0]; void HUD_DirectorMessage(int iSize, void *pbuf)
sync.prevgaitorigin[1] = src->maxs[1]; {
sync.prevgaitorigin[2] = src->maxs[2]; BEGIN_READ(pbuf, iSize);
sync.time = src->mins[0]; // m_clTime auto cmd = READ_BYTE();
sync.oldtime = src->mins[1]; // m_clOldTime if (cmd != DRC_CMD_TIMESCALE)
sync.frametime = src->mins[2]; // m_clTime - m_clOldTime? {
gClientfuncs.pDirectorMessage(iSize, pbuf);
return;
}
gClientfuncs.pProcessPlayerState(dst, src); // make sure that this is our custom message
auto uid = READ_LONG();
if (uid != DIRECTOR_UID)
{
gClientfuncs.pDirectorMessage(iSize, pbuf);
return;
}
auto index = READ_BYTE();
// header packet
if (index == 0)
{
// parse time
split_double_t time, oldtime;
time.lo = READ_LONG();
time.hi = READ_LONG();
oldtime.lo = READ_LONG();
oldtime.hi = READ_LONG();
sv.time = time.d;
sv.oldtime = oldtime.d;
sv.frametime = READ_FLOAT();
}
else
{
auto &sync = g_PlayerSyncInfo[index];
// save current values of fields from server-side
sync.prevgaitorigin[0] = READ_FLOAT();
sync.prevgaitorigin[1] = READ_FLOAT();
sync.prevgaitorigin[2] = READ_FLOAT();
sync.yaw = READ_FLOAT();
sync.pitch = READ_FLOAT();
sync.gaityaw = READ_FLOAT();
sync.gaitframe = READ_FLOAT();
sync.gaitmovement = READ_FLOAT();
sync.gaitsequence = READ_LONG ();
}
}
void HUD_WeaponsPostThink(local_state_t *from, local_state_t *to, usercmd_t *cmd, double time, unsigned int random_seed)
{
g_bHoldingKnife = (from->client.m_iId == WEAPON_KNIFE);
g_bHoldingShield = (from->client.iuser3 & PLAYER_HOLDING_SHIELD) == PLAYER_HOLDING_SHIELD;
} }
void R_ForceCVars(qboolean multiplayer) void R_ForceCVars(qboolean multiplayer)

View File

@ -40,6 +40,7 @@ cvar_t *cl_minmodels;
cvar_t *default_fov; cvar_t *default_fov;
cvar_t *sensitivity; cvar_t *sensitivity;
server_sync_t sv;
player_sync_t g_PlayerSyncInfo [MAX_PLAYERS + 1]; player_sync_t g_PlayerSyncInfo [MAX_PLAYERS + 1];
extra_player_info_t g_PlayerExtraInfo[MAX_PLAYERS + 1]; // additional player info sent directly to the client dll extra_player_info_t g_PlayerExtraInfo[MAX_PLAYERS + 1]; // additional player info sent directly to the client dll

View File

@ -37,6 +37,13 @@ enum
MAX_TEAM_NAME = 16, MAX_TEAM_NAME = 16,
}; };
struct server_sync_t
{
double time;
double oldtime;
float frametime;
};
struct player_sync_t struct player_sync_t
{ {
float yaw; float yaw;
@ -45,9 +52,6 @@ struct player_sync_t
float gaitframe; float gaitframe;
float gaitmovement; float gaitmovement;
int gaitsequence; int gaitsequence;
float time;
float oldtime;
float frametime;
Vector prevgaitorigin; Vector prevgaitorigin;
}; };
@ -72,7 +76,8 @@ struct extra_player_info_t
}; };
// Macros to hook function calls into the HUD object // Macros to hook function calls into the HUD object
#define HOOK_MESSAGE(x) HookUserMsg(#x, __MsgFunc_##x) #define HOOK_MESSAGE(x) HookUserMsg(#x, __MsgFunc_##x)
#define UNHOOK_MESSAGE(x) UnHookUserMsg(#x)
#define DECLARE_MESSAGE(y, x)\ #define DECLARE_MESSAGE(y, x)\
int __MsgFunc_##x(const char *pszName, int iSize, void *pbuf)\ int __MsgFunc_##x(const char *pszName, int iSize, void *pbuf)\
@ -113,6 +118,7 @@ private:
extern CHud gHUD; extern CHud gHUD;
extern server_sync_t sv;
extern player_sync_t g_PlayerSyncInfo [MAX_PLAYERS + 1]; extern player_sync_t g_PlayerSyncInfo [MAX_PLAYERS + 1];
extern extra_player_info_t g_PlayerExtraInfo[MAX_PLAYERS + 1]; extern extra_player_info_t g_PlayerExtraInfo[MAX_PLAYERS + 1];

View File

@ -97,9 +97,15 @@ bool CEngine::Init(const char *szModuleName, const char *pszFile)
m_Software = !Q_stricmp(szModuleName, ENGINE_CLIENT_SOFT_LIB) ? true : false; m_Software = !Q_stricmp(szModuleName, ENGINE_CLIENT_SOFT_LIB) ? true : false;
if (!LoadSecureClient_Init() || !LoadInSecureClient_Init()) if (!LoadSecureClient_Init())
{ {
TraceLog("> %s: Not found ClientFuncs\n", __FUNCTION__); TraceLog("> %s: Not found LoadSecureClient\n", __FUNCTION__);
return false;
}
if (!LoadInSecureClient_Init())
{
TraceLog("> %s: Not found LoadInSecureClient\n", __FUNCTION__);
return false; return false;
} }
@ -229,12 +235,11 @@ bool CEngine::StudioLightingInit()
void R_StudioLighting(float *lv, int bone, int flags, const vec_t *normal) void R_StudioLighting(float *lv, int bone, int flags, const vec_t *normal)
{ {
if (!pfnR_StudioLighting) { *lv = 0.75f;
*lv = 0.75f;
return;
}
pfnR_StudioLighting(lv, bone, flags, normal); if (pfnR_StudioLighting) {
pfnR_StudioLighting(lv, bone, flags, normal);
}
if (g_EngineLib->IsSoftware()) { if (g_EngineLib->IsSoftware()) {
*lv = *lv / (USHRT_MAX + 1); *lv = *lv / (USHRT_MAX + 1);

View File

@ -356,8 +356,6 @@ void CGameStudioModelRenderer::StudioSetupBones()
&& m_pCurrentEntity->curstate.sequence != ANIM_SWIM_1 && m_pCurrentEntity->curstate.sequence != ANIM_SWIM_1
&& m_pCurrentEntity->curstate.sequence != ANIM_SWIM_2) && m_pCurrentEntity->curstate.sequence != ANIM_SWIM_2)
{ {
bool bCopy = true;
if (m_pPlayerInfo->gaitsequence >= m_pStudioHeader->numseq || m_pPlayerInfo->gaitsequence < 0) if (m_pPlayerInfo->gaitsequence >= m_pStudioHeader->numseq || m_pPlayerInfo->gaitsequence < 0)
m_pPlayerInfo->gaitsequence = 0; m_pPlayerInfo->gaitsequence = 0;
@ -366,6 +364,7 @@ void CGameStudioModelRenderer::StudioSetupBones()
panim = StudioGetAnim(m_pRenderModel, pseqdesc); panim = StudioGetAnim(m_pRenderModel, pseqdesc);
StudioCalcRotations(pos2, q2, pseqdesc, panim, m_pPlayerInfo->gaitframe); StudioCalcRotations(pos2, q2, pseqdesc, panim, m_pPlayerInfo->gaitframe);
bool bCopy = true;
for (int i = 0; i < m_pStudioHeader->numbones; i++) for (int i = 0; i < m_pStudioHeader->numbones; i++)
{ {
if (!Q_strcmp(pbones[i].name, "Bip01 Spine")) if (!Q_strcmp(pbones[i].name, "Bip01 Spine"))
@ -418,7 +417,7 @@ void CGameStudioModelRenderer::StudioEstimateGait(entity_state_t *pplayer)
float dt; float dt;
if (m_pPlayerSync) if (m_pPlayerSync)
{ {
dt = clamp(m_pPlayerSync->time - m_pPlayerSync->oldtime, 0.0f, 1.0f); dt = clamp(sv.time - sv.oldtime, 0.0, 1.0);
} }
else else
{ {
@ -513,7 +512,7 @@ void CGameStudioModelRenderer::StudioProcessGait(entity_state_t *pplayer)
float dt; float dt;
if (m_pPlayerSync) if (m_pPlayerSync)
{ {
dt = clamp(m_pPlayerSync->time - m_pPlayerSync->oldtime, 0.0f, 1.0f); dt = clamp(sv.time - sv.oldtime, 0.0, 1.0);
} }
else else
{ {
@ -732,7 +731,7 @@ void CGameStudioModelRenderer::SetupClientAnimation(entity_state_t *pplayer)
st->m_fSequenceLoops = ((GetSequenceFlags(pmodel, st) & STUDIO_LOOPING) != 0) ? TRUE : FALSE; st->m_fSequenceLoops = ((GetSequenceFlags(pmodel, st) & STUDIO_LOOPING) != 0) ? TRUE : FALSE;
StudioFrameAdvance(st, fr, dt); StudioFrameAdvance(st, fr, dt);
// gEngfuncs.Con_Printf("gs %i frame %f\n", st->gaitsequence, st->frame); //gEngfuncs.Con_Printf("gs %i frame %f\n", st->gaitsequence, st->frame);
ent->angles = st->realangles; ent->angles = st->realangles;
ent->curstate.angles = st->angles; ent->curstate.angles = st->angles;
@ -809,7 +808,7 @@ int CGameStudioModelRenderer::StudioDrawPlayer(int flags, entity_state_t *pplaye
// Call real draw function // Call real draw function
int iret = _StudioDrawPlayer(flags, pplayer); int iret = _StudioDrawPlayer(flags, pplayer);
if (iret && m_pCvarDrawEntities->value == 6) if (iret && (m_pCvarDrawEntities->value == 6 || m_pCvarDrawEntities->value == 7))
{ {
m_pPlayerSync = &g_PlayerSyncInfo[pplayer->number]; m_pPlayerSync = &g_PlayerSyncInfo[pplayer->number];
m_pPlayerInfo = IEngineStudio.PlayerInfo(m_nPlayerIndex); m_pPlayerInfo = IEngineStudio.PlayerInfo(m_nPlayerIndex);
@ -982,7 +981,6 @@ int CGameStudioModelRenderer::_StudioDrawPlayer(int flags, entity_state_t *pplay
if (m_pCurrentEntity->index > 0) if (m_pCurrentEntity->index > 0)
{ {
cl_entity_t *ent = gEngfuncs.GetEntityByIndex(m_pCurrentEntity->index); cl_entity_t *ent = gEngfuncs.GetEntityByIndex(m_pCurrentEntity->index);
Q_memcpy(ent->attachment, m_pCurrentEntity->attachment, sizeof(ent->attachment)); Q_memcpy(ent->attachment, m_pCurrentEntity->attachment, sizeof(ent->attachment));
} }
} }
@ -1157,9 +1155,9 @@ void CGameStudioModelRenderer::CalculatePitchBlend(entity_state_t *pplayer)
StudioPlayerBlend(pseqdesc, &iBlend, &m_pCurrentEntity->angles[PITCH]); StudioPlayerBlend(pseqdesc, &iBlend, &m_pCurrentEntity->angles[PITCH]);
m_pCurrentEntity->latched.prevangles[PITCH] = m_pCurrentEntity->angles[PITCH]; m_pCurrentEntity->latched.prevangles[PITCH] = m_pCurrentEntity->angles[PITCH];
m_pCurrentEntity->curstate.blending[1] = iBlend; m_pCurrentEntity->curstate.blending[1] = iBlend;
m_pCurrentEntity->latched.prevblending[1] = m_pCurrentEntity->curstate.blending[1]; m_pCurrentEntity->latched.prevblending[1] = m_pCurrentEntity->curstate.blending[1];
m_pCurrentEntity->latched.prevseqblending[1] = m_pCurrentEntity->curstate.blending[1]; m_pCurrentEntity->latched.prevseqblending[1] = m_pCurrentEntity->curstate.blending[1];
} }

View File

@ -46,14 +46,14 @@ int CStudioModelRenderer::m_boxpnt[6][4] =
vec3_t CStudioModelRenderer::m_hullcolor[8] = vec3_t CStudioModelRenderer::m_hullcolor[8] =
{ {
{ 1.0, 1.0, 1.0 }, { 1.0, 1.0, 1.0 }, // Shield : White
{ 1.0, 0.5, 0.5 }, { 1.0, 0.5, 0.5 }, // Head : Light red
{ 0.5, 1.0, 0.5 }, { 0.5, 1.0, 0.5 }, // Chest : Light green
{ 1.0, 1.0, 0.5 }, { 1.0, 1.0, 0.5 }, // Stomach : Light yellow
{ 0.5, 0.5, 1.0 }, { 0.5, 0.5, 1.0 }, // Leftarm : Light blue
{ 1.0, 0.5, 1.0 }, { 1.0, 0.5, 1.0 }, // Rightarm: Pink
{ 0.5, 1.0, 1.0 }, { 0.5, 1.0, 1.0 }, // Leftleg : Aqua
{ 1.0, 1.0, 1.0 }, { 1.0, 1.0, 1.0 }, // Rightleg: White
}; };
void CStudioModelRenderer::Init() void CStudioModelRenderer::Init()
@ -63,7 +63,7 @@ void CStudioModelRenderer::Init()
m_pCvarDeveloper = IEngineStudio.GetCvar("developer"); m_pCvarDeveloper = IEngineStudio.GetCvar("developer");
m_pCvarDrawEntities = IEngineStudio.GetCvar("r_drawentities"); m_pCvarDrawEntities = IEngineStudio.GetCvar("r_drawentities");
m_pChromeSprite = IEngineStudio.GetChromeSprite(); m_pChromeSprite = IEngineStudio.GetChromeSprite();
m_pWhiteSprite = IEngineStudio.Mod_ForName("sprites/white.spr", 1); m_pWhiteSprite = IEngineStudio.Mod_ForName("sprites/white.spr", TRUE);
IEngineStudio.GetModelCounters(&m_pStudioModelCount, &m_pModelsDrawn); IEngineStudio.GetModelCounters(&m_pStudioModelCount, &m_pModelsDrawn);
@ -690,7 +690,7 @@ void CStudioModelRenderer::StudioSetupBones()
} }
panim = StudioGetAnim(m_pRenderModel, pseqdesc); panim = StudioGetAnim(m_pRenderModel, pseqdesc);
StudioCalcRotations(pos, q, pseqdesc, panim, (int)f); // TODO: CHECK ME cast from float to int and to float StudioCalcRotations(pos, q, pseqdesc, panim, f);
if (pseqdesc->numblends > 1) if (pseqdesc->numblends > 1)
{ {
@ -834,9 +834,6 @@ void CStudioModelRenderer::StudioSetupBones()
if (IEngineStudio.IsHardware()) if (IEngineStudio.IsHardware())
{ {
ConcatTransforms((*m_protationmatrix), bonematrix, (*m_pbonetransform)[i]); ConcatTransforms((*m_protationmatrix), bonematrix, (*m_pbonetransform)[i]);
// MatrixCopy should be faster...
//ConcatTransforms((*m_protationmatrix), bonematrix, (*m_plighttransform)[i]);
MatrixCopy((*m_pbonetransform)[i], (*m_plighttransform)[i]); MatrixCopy((*m_pbonetransform)[i], (*m_plighttransform)[i]);
} }
else else
@ -1693,7 +1690,6 @@ void CStudioModelRenderer::StudioDrawAbsBBox()
gEngfuncs.pTriAPI->Begin(TRI_QUADS); gEngfuncs.pTriAPI->Begin(TRI_QUADS);
gEngfuncs.pTriAPI->Color4f(0.5f, 0.5f, 1.0f, 1.0f); gEngfuncs.pTriAPI->Color4f(0.5f, 0.5f, 1.0f, 1.0f);
//gEngfuncs.pTriAPI->TexCoord2f(0.0f, 0.0f);
for (j = 0; j < ARRAYSIZE(m_boxpnt); j++) for (j = 0; j < ARRAYSIZE(m_boxpnt); j++)
{ {
@ -1720,22 +1716,28 @@ void CStudioModelRenderer::StudioRenderFinal_Software()
if (m_pCvarDrawEntities->value == 2) if (m_pCvarDrawEntities->value == 2)
{ {
//IEngineStudio.StudioDrawBones(); /*IEngineStudio.*/StudioDrawBones();
StudioDrawBones(); // IEngineStudio.StudioDrawBones();
} }
else if (m_pCvarDrawEntities->value == 3) else if (m_pCvarDrawEntities->value == 3)
{ {
StudioDrawHulls(); // IEngineStudio.StudioDrawHulls(); /*IEngineStudio.*/StudioDrawHulls();
} }
else else
{ {
if (m_pPlayerSync) if (m_pPlayerSync)
{ {
if (m_pCurrentEntity->player && m_pCvarDrawEntities->value == 6) if (m_pCurrentEntity->player)
{ {
gEngfuncs.pTriAPI->RenderMode(kRenderTransAdd); if (m_pCvarDrawEntities->value == 6)
StudioDrawHulls(); {
gEngfuncs.pTriAPI->RenderMode(kRenderNormal); gEngfuncs.pTriAPI->RenderMode(kRenderTransAdd);
StudioDrawHulls();
gEngfuncs.pTriAPI->RenderMode(kRenderNormal);
}
else if (m_pCvarDrawEntities->value == 7)
{
StudioDrawHulls();
}
} }
} }
else else
@ -1752,13 +1754,13 @@ void CStudioModelRenderer::StudioRenderFinal_Software()
if (m_pCvarDrawEntities->value == 4) if (m_pCvarDrawEntities->value == 4)
{ {
gEngfuncs.pTriAPI->RenderMode(kRenderTransAdd); gEngfuncs.pTriAPI->RenderMode(kRenderTransAdd);
StudioDrawHulls(); // IEngineStudio.StudioDrawHulls(); /*IEngineStudio.*/StudioDrawHulls();
gEngfuncs.pTriAPI->RenderMode(kRenderNormal); gEngfuncs.pTriAPI->RenderMode(kRenderNormal);
} }
if (m_pCvarDrawEntities->value == 5) if (m_pCvarDrawEntities->value == 5)
{ {
StudioDrawAbsBBox(); // IEngineStudio.StudioDrawAbsBBox(); /*IEngineStudio.*/StudioDrawAbsBBox();
} }
IEngineStudio.RestoreRenderer(); IEngineStudio.RestoreRenderer();
@ -1771,21 +1773,28 @@ void CStudioModelRenderer::StudioRenderFinal_Hardware()
if (m_pCvarDrawEntities->value == 2) if (m_pCvarDrawEntities->value == 2)
{ {
StudioDrawBones(); // IEngineStudio.StudioDrawBones(); /*IEngineStudio.*/StudioDrawBones();
} }
else if (m_pCvarDrawEntities->value == 3) else if (m_pCvarDrawEntities->value == 3)
{ {
StudioDrawHulls(); // IEngineStudio.StudioDrawHulls(); /*IEngineStudio.*/StudioDrawHulls();
} }
else else
{ {
if (m_pPlayerSync) if (m_pPlayerSync)
{ {
if (m_pCurrentEntity->player && m_pCvarDrawEntities->value == 6) if (m_pCurrentEntity->player)
{ {
gEngfuncs.pTriAPI->RenderMode(kRenderTransAdd); if (m_pCvarDrawEntities->value == 6)
StudioDrawHulls(); {
gEngfuncs.pTriAPI->RenderMode(kRenderNormal); gEngfuncs.pTriAPI->RenderMode(kRenderTransAdd);
StudioDrawHulls();
gEngfuncs.pTriAPI->RenderMode(kRenderNormal);
}
else if (m_pCvarDrawEntities->value == 7)
{
StudioDrawHulls();
}
} }
} }
else else
@ -1811,13 +1820,13 @@ void CStudioModelRenderer::StudioRenderFinal_Hardware()
if (m_pCvarDrawEntities->value == 4) if (m_pCvarDrawEntities->value == 4)
{ {
gEngfuncs.pTriAPI->RenderMode(kRenderTransAdd); gEngfuncs.pTriAPI->RenderMode(kRenderTransAdd);
StudioDrawHulls(); // IEngineStudio.StudioDrawHulls(); /*IEngineStudio.*/StudioDrawHulls();
gEngfuncs.pTriAPI->RenderMode(kRenderNormal); gEngfuncs.pTriAPI->RenderMode(kRenderNormal);
} }
if (m_pCvarDrawEntities->value == 5) if (m_pCvarDrawEntities->value == 5)
{ {
StudioDrawAbsBBox(); // IEngineStudio.StudioDrawAbsBBox(); /*IEngineStudio.*/StudioDrawAbsBBox();
} }
IEngineStudio.RestoreRenderer(); IEngineStudio.RestoreRenderer();

View File

@ -157,7 +157,7 @@ void AngleQuaternion(float *angles, vec4_t quaternion)
void QuaternionSlerp(vec4_t p, vec4_t q, float t, vec4_t qt) void QuaternionSlerp(vec4_t p, vec4_t q, float t, vec4_t qt)
{ {
int i; int i;
float omega, cosom, sinom, sclp, sclq; float omega, cosom, sinom, sclp, sclq;
// decide if one of the quaternions is backwards // decide if one of the quaternions is backwards
float a = 0; float a = 0;
@ -168,6 +168,7 @@ void QuaternionSlerp(vec4_t p, vec4_t q, float t, vec4_t qt)
a += (p[i] - q[i]) * (p[i] - q[i]); a += (p[i] - q[i]) * (p[i] - q[i]);
b += (p[i] + q[i]) * (p[i] + q[i]); b += (p[i] + q[i]) * (p[i] + q[i]);
} }
if (a > b) if (a > b)
{ {
for (i = 0; i < 4; i++) for (i = 0; i < 4; i++)
@ -176,7 +177,7 @@ void QuaternionSlerp(vec4_t p, vec4_t q, float t, vec4_t qt)
} }
} }
cosom = p[0]*q[0] + p[1]*q[1] + p[2]*q[2] + p[3]*q[3]; cosom = p[0] * q[0] + p[1] * q[1] + p[2] * q[2] + p[3] * q[3];
if ((1.0 + cosom) > 0.000001) if ((1.0 + cosom) > 0.000001)
{ {
@ -184,6 +185,7 @@ void QuaternionSlerp(vec4_t p, vec4_t q, float t, vec4_t qt)
{ {
omega = acos(cosom); omega = acos(cosom);
sinom = sin(omega); sinom = sin(omega);
sclp = sin((1.0 - t) * omega) / sinom; sclp = sin((1.0 - t) * omega) / sinom;
sclq = sin(t * omega) / sinom; sclq = sin(t * omega) / sinom;
} }
@ -201,11 +203,13 @@ void QuaternionSlerp(vec4_t p, vec4_t q, float t, vec4_t qt)
else else
{ {
qt[0] = -q[1]; qt[0] = -q[1];
qt[1] = q[0]; qt[1] = q[0];
qt[2] = -q[3]; qt[2] = -q[3];
qt[3] = q[2]; qt[3] = q[2];
sclp = sin((1.0 - t) * (0.5 * M_PI)); sclp = sin((1.0 - t) * (0.5 * M_PI));
sclq = sin(t * (0.5 * M_PI)); sclq = sin(t * (0.5 * M_PI));
for (i = 0; i < 3; i++) for (i = 0; i < 3; i++)
{ {
qt[i] = sclp * p[i] + sclq * qt[i]; qt[i] = sclp * p[i] + sclq * qt[i];

View File

@ -29,7 +29,7 @@
#pragma once #pragma once
#ifndef M_PI #ifndef M_PI
#define M_PI 3.14159265358979323846 // matches value in gcc v2 math.h #define M_PI 3.14159265358979323846 // matches value in gcc v2 math.h
#endif #endif
#define PITCH 0 // up / down #define PITCH 0 // up / down

View File

@ -48,3 +48,21 @@ bool HookUserMsg(char *pszMsgName, pfnUserMsgHook pfn)
return false; return false;
} }
bool UnHookUserMsg(char *pszMsgName)
{
auto pClientUserMsgs = g_pClientUserMsgs;
while (pClientUserMsgs)
{
if (!Q_strcmp(pClientUserMsgs->szName, pszMsgName))
{
pClientUserMsgs->pfn = g_ClientUserMsgsMap[pszMsgName];
g_ClientUserMsgsMap[pszMsgName] = nullptr;
return true;
}
pClientUserMsgs = pClientUserMsgs->next;
}
return false;
}

View File

@ -1,2 +0,0 @@
#pragma once

View File

@ -18,16 +18,16 @@ DLL_FUNCTIONS g_DllFunctionTable_Post =
NULL, // pfnRestoreGlobalState NULL, // pfnRestoreGlobalState
NULL, // pfnResetGlobalState NULL, // pfnResetGlobalState
NULL, // pfnClientConnect NULL, // pfnClientConnect
NULL, // pfnClientDisconnect &ClientDisconnect_Post, // pfnClientDisconnect
NULL, // pfnClientKill NULL, // pfnClientKill
NULL, // pfnClientPutInServer NULL, // pfnClientPutInServer
NULL, // pfnClientCommand &ClientCommand_Post, // pfnClientCommand
NULL, // pfnClientUserInfoChanged NULL, // pfnClientUserInfoChanged
&ServerActivate_Post, // pfnServerActivate &ServerActivate_Post, // pfnServerActivate
NULL, // pfnServerDeactivate NULL, // pfnServerDeactivate
NULL, // pfnPlayerPreThink NULL, // pfnPlayerPreThink
NULL, // pfnPlayerPostThink &PlayerPostThink_Post, // pfnPlayerPostThink
NULL, // pfnStartFrame &StartFrame_Post, // pfnStartFrame
NULL, // pfnParmsNewLevel NULL, // pfnParmsNewLevel
NULL, // pfnParmsChangeLevel NULL, // pfnParmsChangeLevel
NULL, // pfnGetGameDescription NULL, // pfnGetGameDescription
@ -41,7 +41,7 @@ DLL_FUNCTIONS g_DllFunctionTable_Post =
NULL, // pfnPM_FindTextureType NULL, // pfnPM_FindTextureType
NULL, // pfnSetupVisibility NULL, // pfnSetupVisibility
NULL, // pfnUpdateClientData NULL, // pfnUpdateClientData
&AddToFullPack_Post, // pfnAddToFullPack NULL, // pfnAddToFullPack
NULL, // pfnCreateBaseline NULL, // pfnCreateBaseline
NULL, // pfnRegisterEncoders NULL, // pfnRegisterEncoders
NULL, // pfnGetWeaponData NULL, // pfnGetWeaponData

View File

@ -30,39 +30,145 @@
server_t *sv; server_t *sv;
int AddToFullPack_Post(entity_state_t *state, int e, edict_t *ent, edict_t *host, int hostflags, int player, unsigned char *pSet) struct player_t
{ {
if (ent->v.modelindex <= 0 || ent->v.modelindex >= MAX_MODELS) struct player_info_t
{ {
RETURN_META_VALUE(MRES_IGNORED, 0); bool read_packet : 1;
bool request_sync : 1;
};
player_info_t &operator[](size_t i) { return m_data[i - 1]; }
player_info_t &operator[](edict_t *pEdict) { return m_data[ENTINDEX(pEdict) - 1]; }
player_info_t &operator[](CBasePlayer *pPlayer) { return m_data[pPlayer->entindex() - 1]; }
player_info_t m_data[MAX_CLIENTS];
};
player_t g_Players;
constexpr size_t DIRECTOR_UID = 0xabcdef00;
void ClientCommand_Post(edict_t *pEdict)
{
const auto cmd = CMD_ARGV(0);
if (!Q_strcmp(cmd, "__request_sync"))
{
// want sync
g_Players[pEdict].request_sync = true;
} }
// we need to call every time SV_StudioSetupBones RETURN_META(MRES_IGNORED);
// to keep gaityaw and other synced on client-side }
TraceResult tr;
TRACE_LINE(ent->v.origin - Vector(1, 1, 1), host->v.origin + Vector(1, 1, 1), 0, nullptr, &tr);
CBasePlayer *plr = UTIL_PlayerByIndexSafe(e); void SendPlayerSyncInfo(CBasePlayer *pPlayer)
if (plr) {
for (int i = 1; i <= gpGlobals->maxClients; i++)
{ {
state->vuser1[0] = plr->m_flYaw; auto plr = UTIL_PlayerByIndex(i);
state->vuser1[1] = plr->m_flGaityaw; if (!plr)
state->vuser1[2] = plr->m_flGaitframe; continue;
state->vuser2[0] = plr->m_flGaitMovement; if (plr->IsDormant() || plr->has_disconnected)
state->vuser2[1] = plr->m_iGaitsequence; continue;
state->vuser2[2] = plr->m_flPitch;
state->maxs[0] = plr->m_prevgaitorigin[0]; if (!plr->IsNetClient())
state->maxs[1] = plr->m_prevgaitorigin[0]; continue;
state->maxs[2] = plr->m_prevgaitorigin[0];
state->mins[0] = sv->time; if (g_Players[plr].request_sync)
state->mins[1] = sv->oldtime; {
state->mins[2] = gpGlobals->frametime; MESSAGE_BEGIN(MSG_ONE, SVC_DIRECTOR, nullptr, plr->pev);
WRITE_BYTE(42); // number of bytes this message
WRITE_BYTE(DRC_CMD_TIMESCALE);
WRITE_LONG(DIRECTOR_UID); // unique message id
WRITE_BYTE(pPlayer->entindex());
WRITE_LONG(*(int *)&pPlayer->m_prevgaitorigin[0]);
WRITE_LONG(*(int *)&pPlayer->m_prevgaitorigin[1]);
WRITE_LONG(*(int *)&pPlayer->m_prevgaitorigin[2]);
WRITE_LONG(*(int *)&pPlayer->m_flYaw);
WRITE_LONG(*(int *)&pPlayer->m_flPitch);
WRITE_LONG(*(int *)&pPlayer->m_flGaityaw);
WRITE_LONG(*(int *)&pPlayer->m_flGaitframe);
WRITE_LONG(*(int *)&pPlayer->m_flGaitMovement);
WRITE_LONG(pPlayer->m_iGaitsequence);
MESSAGE_END();
}
}
}
void PlayerPostThink_Post(edict_t *pEdict)
{
g_Players[pEdict].read_packet = true;
RETURN_META(MRES_IGNORED);
}
void ClientDisconnect_Post(edict_t *pEdict)
{
g_Players[pEdict].read_packet = false;
g_Players[pEdict].request_sync = false;
RETURN_META(MRES_IGNORED);
}
union split_double_t
{
split_double_t() : d (0.0) {}
split_double_t(double f) : d(f) {}
double d;
struct {
int32_t lo;
int32_t hi;
};
};
void StartFrame_Post()
{
int count = 0;
CBasePlayer *plrList[MAX_CLIENTS];
for (int i = 1; i <= gpGlobals->maxClients; i++)
{
auto pPlayer = UTIL_PlayerByIndex(i);
if (!pPlayer)
continue;
if (pPlayer->IsDormant() || pPlayer->has_disconnected)
continue;
if (!pPlayer->IsAlive())
continue;
if (!g_Players[i].read_packet)
{
RETURN_META(MRES_IGNORED);
}
g_Players[i].read_packet = false;
plrList[count++] = pPlayer;
} }
RETURN_META_VALUE(MRES_IGNORED, 0); if (count > 0)
{
split_double_t time(sv->time), oldtime(sv->oldtime);
MESSAGE_BEGIN(MSG_ALL, SVC_DIRECTOR);
WRITE_BYTE(26); // number of bytes this message
WRITE_BYTE(DRC_CMD_TIMESCALE);
WRITE_LONG(DIRECTOR_UID); // unique message id
WRITE_BYTE(0);
WRITE_LONG(time.lo);
WRITE_LONG(time.hi);
WRITE_LONG(oldtime.lo);
WRITE_LONG(oldtime.hi);
WRITE_LONG(*(int *)&gpGlobals->frametime);
MESSAGE_END();
// 26 + (42 * count) the total number of payload bytes
for (int i = 0; i < count; i++) {
SendPlayerSyncInfo(plrList[i]);
}
}
RETURN_META(MRES_IGNORED);
} }
void ServerActivate_Post(edict_t *pEdictList, int edictCount, int clientMax) void ServerActivate_Post(edict_t *pEdictList, int edictCount, int clientMax)

View File

@ -28,7 +28,10 @@
#pragma once #pragma once
#include "entity_state.h" #include "hltv.h"
int AddToFullPack_Post(entity_state_t *state, int e, edict_t *ent, edict_t *host, int hostflags, int player, unsigned char *pSet); void StartFrame_Post();
void PlayerPostThink_Post(edict_t *pEdict);
void ServerActivate_Post(edict_t *pEdictList, int edictCount, int clientMax); void ServerActivate_Post(edict_t *pEdictList, int edictCount, int clientMax);
void ClientDisconnect_Post(edict_t *pEdict);
void ClientCommand_Post(edict_t *pEdict);