Migrate commits from github.com/ValveSoftware/halflife (Jun 6, 2019)

This commit is contained in:
Marco Cawthorne 2023-07-20 11:11:37 -07:00
parent 030f9987fd
commit 8ebc994352
Signed by: eukara
GPG key ID: CE2032F0A2882A22
465 changed files with 62938 additions and 2958 deletions

117
cl_dll/Exports.h Normal file
View file

@ -0,0 +1,117 @@
// CL_DLLEXPORT is the client version of dllexport. It's turned off for secure clients.
#ifdef _WIN32
#define CL_DLLEXPORT __declspec(dllexport)
#else
#define CL_DLLEXPORT __attribute__ ((visibility("default")))
#endif
extern "C"
{
// From hl_weapons
void CL_DLLEXPORT HUD_PostRunCmd( struct local_state_s *from, struct local_state_s *to, struct usercmd_s *cmd, int runfuncs, double time, unsigned int random_seed );
// From cdll_int
int CL_DLLEXPORT Initialize( cl_enginefunc_t *pEnginefuncs, int iVersion );
int CL_DLLEXPORT HUD_VidInit( void );
void CL_DLLEXPORT HUD_Init( void );
int CL_DLLEXPORT HUD_Redraw( float flTime, int intermission );
int CL_DLLEXPORT HUD_UpdateClientData( client_data_t *cdata, float flTime );
void CL_DLLEXPORT HUD_Reset ( void );
void CL_DLLEXPORT HUD_PlayerMove( struct playermove_s *ppmove, int server );
void CL_DLLEXPORT HUD_PlayerMoveInit( struct playermove_s *ppmove );
char CL_DLLEXPORT HUD_PlayerMoveTexture( char *name );
int CL_DLLEXPORT HUD_ConnectionlessPacket( const struct netadr_s *net_from, const char *args, char *response_buffer, int *response_buffer_size );
int CL_DLLEXPORT HUD_GetHullBounds( int hullnumber, float *mins, float *maxs );
void CL_DLLEXPORT HUD_Frame( double time );
void CL_DLLEXPORT HUD_VoiceStatus(int entindex, qboolean bTalking);
void CL_DLLEXPORT HUD_DirectorMessage( int iSize, void *pbuf );
void CL_DLLEXPORT HUD_ChatInputPosition( int *x, int *y );
// From demo
void CL_DLLEXPORT Demo_ReadBuffer( int size, unsigned char *buffer );
// From entity
int CL_DLLEXPORT HUD_AddEntity( int type, struct cl_entity_s *ent, const char *modelname );
void CL_DLLEXPORT HUD_CreateEntities( void );
void CL_DLLEXPORT HUD_StudioEvent( const struct mstudioevent_s *event, const struct cl_entity_s *entity );
void CL_DLLEXPORT HUD_TxferLocalOverrides( struct entity_state_s *state, const struct clientdata_s *client );
void CL_DLLEXPORT HUD_ProcessPlayerState( struct entity_state_s *dst, const struct entity_state_s *src );
void CL_DLLEXPORT HUD_TxferPredictionData ( struct entity_state_s *ps, const struct entity_state_s *pps, struct clientdata_s *pcd, const struct clientdata_s *ppcd, struct weapon_data_s *wd, const struct weapon_data_s *pwd );
void CL_DLLEXPORT HUD_TempEntUpdate( double frametime, double client_time, double cl_gravity, struct tempent_s **ppTempEntFree, struct tempent_s **ppTempEntActive, int ( *Callback_AddVisibleEntity )( struct cl_entity_s *pEntity ), void ( *Callback_TempEntPlaySound )( struct tempent_s *pTemp, float damp ) );
struct cl_entity_s CL_DLLEXPORT *HUD_GetUserEntity( int index );
// From in_camera
void CL_DLLEXPORT CAM_Think( void );
int CL_DLLEXPORT CL_IsThirdPerson( void );
void CL_DLLEXPORT CL_CameraOffset( float *ofs );
// From input
struct kbutton_s CL_DLLEXPORT *KB_Find( const char *name );
void CL_DLLEXPORT CL_CreateMove ( float frametime, struct usercmd_s *cmd, int active );
void CL_DLLEXPORT HUD_Shutdown( void );
int CL_DLLEXPORT HUD_Key_Event( int eventcode, int keynum, const char *pszCurrentBinding );
// From inputw32
void CL_DLLEXPORT IN_ActivateMouse( void );
void CL_DLLEXPORT IN_DeactivateMouse( void );
void CL_DLLEXPORT IN_MouseEvent (int mstate);
void CL_DLLEXPORT IN_Accumulate (void);
void CL_DLLEXPORT IN_ClearStates (void);
// From tri
void CL_DLLEXPORT HUD_DrawNormalTriangles( void );
void CL_DLLEXPORT HUD_DrawTransparentTriangles( void );
// From view
void CL_DLLEXPORT V_CalcRefdef( struct ref_params_s *pparams );
// From GameStudioModelRenderer
int CL_DLLEXPORT HUD_GetStudioModelInterface( int version, struct r_studio_interface_s **ppinterface, struct engine_studio_api_s *pstudio );
}
/*
extern cldll_func_dst_t *g_pcldstAddrs;
// Macros for the client receiving calls from the engine
#define RecClInitialize(a, b) (g_pcldstAddrs->pInitFunc(&a, &b))
#define RecClHudInit() (g_pcldstAddrs->pHudInitFunc())
#define RecClHudVidInit() (g_pcldstAddrs->pHudVidInitFunc())
#define RecClHudRedraw(a, b) (g_pcldstAddrs->pHudRedrawFunc(&a, &b))
#define RecClHudUpdateClientData(a, b) (g_pcldstAddrs->pHudUpdateClientDataFunc(&a, &b))
#define RecClHudReset() (g_pcldstAddrs->pHudResetFunc())
#define RecClClientMove(a, b) (g_pcldstAddrs->pClientMove(&a, &b))
#define RecClClientMoveInit(a) (g_pcldstAddrs->pClientMoveInit(&a))
#define RecClClientTextureType(a) (g_pcldstAddrs->pClientTextureType(&a))
#define RecClIN_ActivateMouse() (g_pcldstAddrs->pIN_ActivateMouse())
#define RecClIN_DeactivateMouse() (g_pcldstAddrs->pIN_DeactivateMouse())
#define RecClIN_MouseEvent(a) (g_pcldstAddrs->pIN_MouseEvent(&a))
#define RecClIN_ClearStates() (g_pcldstAddrs->pIN_ClearStates())
#define RecClIN_Accumulate() (g_pcldstAddrs->pIN_Accumulate())
#define RecClCL_CreateMove(a, b, c) (g_pcldstAddrs->pCL_CreateMove(&a, &b, &c))
#define RecClCL_IsThirdPerson() (g_pcldstAddrs->pCL_IsThirdPerson())
#define RecClCL_GetCameraOffsets(a) (g_pcldstAddrs->pCL_GetCameraOffsets(&a))
#define RecClFindKey(a) (g_pcldstAddrs->pFindKey(&a))
#define RecClCamThink() (g_pcldstAddrs->pCamThink())
#define RecClCalcRefdef(a) (g_pcldstAddrs->pCalcRefdef(&a))
#define RecClAddEntity(a, b, c) (g_pcldstAddrs->pAddEntity(&a, &b, &c))
#define RecClCreateEntities() (g_pcldstAddrs->pCreateEntities())
#define RecClDrawNormalTriangles() (g_pcldstAddrs->pDrawNormalTriangles())
#define RecClDrawTransparentTriangles() (g_pcldstAddrs->pDrawTransparentTriangles())
#define RecClStudioEvent(a, b) (g_pcldstAddrs->pStudioEvent(&a, &b))
#define RecClPostRunCmd(a, b, c, d, e, f) (g_pcldstAddrs->pPostRunCmd(&a, &b, &c, &d, &e, &f))
#define RecClShutdown() (g_pcldstAddrs->pShutdown())
#define RecClTxferLocalOverrides(a, b) (g_pcldstAddrs->pTxferLocalOverrides(&a, &b))
#define RecClProcessPlayerState(a, b) (g_pcldstAddrs->pProcessPlayerState(&a, &b))
#define RecClTxferPredictionData(a, b, c, d, e, f) (g_pcldstAddrs->pTxferPredictionData(&a, &b, &c, &d, &e, &f))
#define RecClReadDemoBuffer(a, b) (g_pcldstAddrs->pReadDemoBuffer(&a, &b))
#define RecClConnectionlessPacket(a, b, c, d) (g_pcldstAddrs->pConnectionlessPacket(&a, &b, &c, &d))
#define RecClGetHullBounds(a, b, c) (g_pcldstAddrs->pGetHullBounds(&a, &b, &c))
#define RecClHudFrame(a) (g_pcldstAddrs->pHudFrame(&a))
#define RecClKeyEvent(a, b, c) (g_pcldstAddrs->pKeyEvent(&a, &b, &c))
#define RecClTempEntUpdate(a, b, c, d, e, f, g) (g_pcldstAddrs->pTempEntUpdate(&a, &b, &c, &d, &e, &f, &g))
#define RecClGetUserEntity(a) (g_pcldstAddrs->pGetUserEntity(&a))
#define RecClVoiceStatus(a, b) (g_pcldstAddrs->pVoiceStatus(&a, &b))
#define RecClDirectorMessage(a, b) (g_pcldstAddrs->pDirectorMessage(&a, &b))
#define RecClStudioInterface(a, b, c) (g_pcldstAddrs->pStudioInterface(&a, &b, &c))
#define RecClChatInputPosition(a, b) (g_pcldstAddrs->pChatInputPosition(&a, &b))
*/

View file

@ -26,6 +26,7 @@
#include "StudioModelRenderer.h"
#include "GameStudioModelRenderer.h"
#include "Exports.h"
//
// Override the StudioModelRender virtual member functions here to implement custom bone
@ -99,9 +100,10 @@ HUD_GetStudioModelInterface
Export this function for the engine to use the studio renderer class to render objects.
====================
*/
#define DLLEXPORT __declspec( dllexport )
extern "C" int DLLEXPORT HUD_GetStudioModelInterface( int version, struct r_studio_interface_s **ppinterface, struct engine_studio_api_s *pstudio )
int CL_DLLEXPORT HUD_GetStudioModelInterface( int version, struct r_studio_interface_s **ppinterface, struct engine_studio_api_s *pstudio )
{
// RecClStudioInterface(version, ppinterface, pstudio);
if ( version != STUDIO_INTERFACE_VERSION )
return 0;

155
cl_dll/MOTD.cpp Normal file
View file

@ -0,0 +1,155 @@
/***
*
* Copyright (c) 1999, Valve LLC. All rights reserved.
*
* This product contains software technology licensed from Id
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
* All Rights Reserved.
*
* Use, distribution, and modification of this source code and/or resulting
* object code is restricted to non-commercial enhancements to products from
* Valve LLC. All other use, distribution, or modification is prohibited
* without written permission from Valve LLC.
*
****/
//
// MOTD.cpp
//
// for displaying a server-sent message of the day
//
#include "hud.h"
#include "cl_util.h"
#include "parsemsg.h"
#include <string.h>
#include <stdio.h>
//DECLARE_MESSAGE( m_MOTD, MOTD );
int CHudMOTD::MOTD_DISPLAY_TIME;
int CHudMOTD :: Init( void )
{
gHUD.AddHudElem( this );
// HOOK_MESSAGE( MOTD );
CVAR_CREATE( "motd_display_time", "15", 0 );
m_iFlags &= ~HUD_ACTIVE; // start out inactive
m_szMOTD[0] = 0;
return 1;
}
int CHudMOTD :: VidInit( void )
{
// Load sprites here
return 1;
}
void CHudMOTD :: Reset( void )
{
m_iFlags &= ~HUD_ACTIVE; // start out inactive
m_szMOTD[0] = 0;
m_iLines = 0;
m_flActiveRemaining = 0;
}
#define LINE_HEIGHT 13
int CHudMOTD :: Draw( float fTime )
{
static float sfLastTime;
float fElapsed;
// Draw MOTD line-by-line
if ( m_flActiveRemaining <= 0.0 )
{
// finished with MOTD, disable it
m_szMOTD[0] = 0;
m_iLines = 0;
m_iFlags &= ~HUD_ACTIVE;
m_flActiveRemaining = 0.0;
return 1;
}
fElapsed = gHUD.m_flTime - sfLastTime;
// Don't let time go negative ( level transition? )
fElapsed = max( 0.0, fElapsed );
// Don't let time go hugely positive ( first connection to active server ? )
fElapsed = min( 1.0, fElapsed );
// Remember last timestamp
sfLastTime = gHUD.m_flTime;
// Remove a bit of time
m_flActiveRemaining -= fElapsed;
// find the top of where the MOTD should be drawn, so the whole thing is centered in the screen
int ypos = max(((ScreenHeight - (m_iLines * LINE_HEIGHT)) / 2) - 40, 30 ); // shift it up slightly
char *ch = m_szMOTD;
while ( *ch )
{
int line_length = 0; // count the length of the current line
for ( char *next_line = ch; *next_line != '\n' && *next_line != 0; next_line++ )
line_length += gHUD.m_scrinfo.charWidths[ *next_line ];
char *top = next_line;
if ( *top == '\n' )
*top = 0;
else
top = NULL;
// find where to start drawing the line
int xpos = (ScreenWidth - line_length) / 2;
gHUD.DrawHudString( xpos, ypos, ScreenWidth, ch, 255, 180, 0 );
ypos += LINE_HEIGHT;
if ( top ) // restore
*top = '\n';
ch = next_line;
if ( *ch == '\n' )
ch++;
if ( ypos > (ScreenHeight - 20) )
break; // don't let it draw too low
}
return 1;
}
int CHudMOTD :: MsgFunc_MOTD( const char *pszName, int iSize, void *pbuf )
{
if ( m_iFlags & HUD_ACTIVE )
{
Reset(); // clear the current MOTD in prep for this one
}
BEGIN_READ( pbuf, iSize );
int is_finished = READ_BYTE();
strcat( m_szMOTD, READ_STRING() );
if ( is_finished )
{
m_iFlags |= HUD_ACTIVE;
MOTD_DISPLAY_TIME = max( 10, CVAR_GET_FLOAT( "motd_display_time" ) );
m_flActiveRemaining = MOTD_DISPLAY_TIME;
for ( char *sz = m_szMOTD; *sz != 0; sz++ ) // count the number of lines in the MOTD
{
if ( *sz == '\n' )
m_iLines++;
}
}
return 1;
}

View file

@ -1,10 +1,3 @@
//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================
// studio_model.cpp
// routines for setting up to draw 3DStudio models
@ -29,6 +22,18 @@
#include "StudioModelRenderer.h"
#include "GameStudioModelRenderer.h"
extern cvar_t *tfc_newmodels;
extern extra_player_info_t g_PlayerExtraInfo[MAX_PLAYERS+1];
// team colors for old TFC models
#define TEAM1_COLOR 150
#define TEAM2_COLOR 250
#define TEAM3_COLOR 45
#define TEAM4_COLOR 100
int m_nPlayerGaitSequences[MAX_CLIENTS];
// Global engine <-> studio model rendering code interface
engine_studio_api_t IEngineStudio;
@ -363,7 +368,7 @@ mstudioanim_t *CStudioModelRenderer::StudioGetAnim( model_t *m_pSubModel, mstudi
if (pseqdesc->seqgroup == 0)
{
return (mstudioanim_t *)((byte *)m_pStudioHeader + pseqgroup->data + pseqdesc->animindex);
return (mstudioanim_t *)((byte *)m_pStudioHeader + pseqdesc->animindex);
}
paSequences = (cache_user_t *)m_pSubModel->submodels;
@ -793,6 +798,22 @@ void CStudioModelRenderer::StudioSetupBones ( void )
pseqdesc = (mstudioseqdesc_t *)((byte *)m_pStudioHeader + m_pStudioHeader->seqindex) + m_pCurrentEntity->curstate.sequence;
// always want new gait sequences to start on frame zero
/* if ( m_pPlayerInfo )
{
int playerNum = m_pCurrentEntity->index - 1;
// new jump gaitsequence? start from frame zero
if ( m_nPlayerGaitSequences[ playerNum ] != m_pPlayerInfo->gaitsequence )
{
// m_pPlayerInfo->gaitframe = 0.0;
gEngfuncs.Con_Printf( "Setting gaitframe to 0\n" );
}
m_nPlayerGaitSequences[ playerNum ] = m_pPlayerInfo->gaitsequence;
// gEngfuncs.Con_Printf( "index: %d gaitsequence: %d\n",playerNum, m_pPlayerInfo->gaitsequence);
}
*/
f = StudioEstimateFrame( pseqdesc );
if (m_pCurrentEntity->latched.prevframe > f)
@ -842,6 +863,11 @@ void CStudioModelRenderer::StudioSetupBones ( void )
static vec4_t q1b[MAXSTUDIOBONES];
float s;
if (m_pCurrentEntity->latched.prevsequence >= m_pStudioHeader->numseq)
{
m_pCurrentEntity->latched.prevsequence = 0;
}
pseqdesc = (mstudioseqdesc_t *)((byte *)m_pStudioHeader + m_pStudioHeader->seqindex) + m_pCurrentEntity->latched.prevsequence;
panim = StudioGetAnim( m_pRenderModel, pseqdesc );
// clip prevframe
@ -882,29 +908,49 @@ void CStudioModelRenderer::StudioSetupBones ( void )
pbones = (mstudiobone_t *)((byte *)m_pStudioHeader + m_pStudioHeader->boneindex);
// calc gait animation
if (m_pPlayerInfo && m_pPlayerInfo->gaitsequence != 0)
// bounds checking
if ( m_pPlayerInfo )
{
if (m_pPlayerInfo->gaitsequence >= m_pStudioHeader->numseq)
if ( m_pPlayerInfo->gaitsequence >= m_pStudioHeader->numseq )
{
m_pPlayerInfo->gaitsequence = 0;
}
}
// calc gait animation
if ( m_pPlayerInfo && m_pPlayerInfo->gaitsequence != 0 )
{
if (m_pPlayerInfo->gaitsequence >= m_pStudioHeader->numseq)
{
m_pPlayerInfo->gaitsequence = 0;
}
pseqdesc = (mstudioseqdesc_t *)((byte *)m_pStudioHeader + m_pStudioHeader->seqindex) + m_pPlayerInfo->gaitsequence;
int copy = 1;
pseqdesc = (mstudioseqdesc_t *)( (byte *)m_pStudioHeader + m_pStudioHeader->seqindex ) + m_pPlayerInfo->gaitsequence;
panim = StudioGetAnim( m_pRenderModel, pseqdesc );
StudioCalcRotations( pos2, q2, pseqdesc, panim, m_pPlayerInfo->gaitframe );
for (i = 0; i < m_pStudioHeader->numbones; i++)
for ( i = 0; i < m_pStudioHeader->numbones; i++ )
{
if (strcmp( pbones[i].name, "Bip01 Spine") == 0)
break;
memcpy( pos[i], pos2[i], sizeof( pos[i] ));
memcpy( q[i], q2[i], sizeof( q[i] ));
if ( !strcmp( pbones[i].name, "Bip01 Spine" ) )
{
copy = 0;
}
else if ( !strcmp( pbones[ pbones[i].parent ].name, "Bip01 Pelvis" ) )
{
copy = 1;
}
if ( copy )
{
memcpy( pos[i], pos2[i], sizeof( pos[i] ) );
memcpy( q[i], q2[i], sizeof( q[i] ) );
}
}
}
for (i = 0; i < m_pStudioHeader->numbones; i++)
{
QuaternionMatrix( q[i], bonematrix );
@ -1052,6 +1098,52 @@ void CStudioModelRenderer::StudioMergeBones ( model_t *m_pSubModel )
}
}
#if defined( _TFC )
#include "pm_shared.h"
const Vector& GetTeamColor( int team_no );
#define IS_FIRSTPERSON_SPEC ( g_iUser1 == OBS_IN_EYE || (g_iUser1 && (gHUD.m_Spectator.m_pip->value == INSET_IN_EYE)) )
int GetRemapColor( int iTeam, bool bTopColor )
{
int retVal = 0;
switch( iTeam )
{
default:
case 1:
if ( bTopColor )
retVal = TEAM1_COLOR;
else
retVal = TEAM1_COLOR - 10;
break;
case 2:
if ( bTopColor )
retVal = TEAM2_COLOR;
else
retVal = TEAM2_COLOR - 10;
break;
case 3:
if ( bTopColor )
retVal = TEAM3_COLOR;
else
retVal = TEAM3_COLOR - 10;
break;
case 4:
if ( bTopColor )
retVal = TEAM4_COLOR;
else
retVal = TEAM4_COLOR - 10;
break;
}
return retVal;
}
#endif
/*
====================
StudioDrawModel
@ -1154,9 +1246,86 @@ int CStudioModelRenderer::StudioDrawModel( int flags )
IEngineStudio.StudioSetupLighting (&lighting);
// get remap colors
m_nTopColor = m_pCurrentEntity->curstate.colormap & 0xFF;
#if defined( _TFC )
m_nTopColor = m_pCurrentEntity->curstate.colormap & 0xFF;
m_nBottomColor = (m_pCurrentEntity->curstate.colormap & 0xFF00) >> 8;
// use the old tfc colors for the models (view models)
// team 1
if ( ( m_nTopColor < 155 ) && ( m_nTopColor > 135 ) )
{
m_nTopColor = TEAM1_COLOR;
m_nBottomColor = TEAM1_COLOR - 10;
}
// team 2
else if ( ( m_nTopColor < 260 ) && ( ( m_nTopColor > 240 ) || ( m_nTopColor == 5 ) ) )
{
m_nTopColor = TEAM2_COLOR;
m_nBottomColor = TEAM2_COLOR - 10;
}
// team 3
else if ( ( m_nTopColor < 50 ) && ( m_nTopColor > 40 ) )
{
m_nTopColor = TEAM3_COLOR;
m_nBottomColor = TEAM3_COLOR - 10;
}
// team 4
else if ( ( m_nTopColor < 110 ) && ( m_nTopColor > 75 ) )
{
m_nTopColor = TEAM4_COLOR;
m_nBottomColor = TEAM4_COLOR - 10;
}
// is this our view model and should it be glowing? we also fix a remap colors
// problem if we're spectating in first-person mode
if ( m_pCurrentEntity == gEngfuncs.GetViewModel() )
{
cl_entity_t *pTarget = NULL;
// we're spectating someone via first-person mode
if ( IS_FIRSTPERSON_SPEC )
{
pTarget = gEngfuncs.GetEntityByIndex( g_iUser2 );
if ( pTarget )
{
// we also need to correct the m_nTopColor and m_nBottomColor for the
// view model here. this is separate from the glowshell stuff, but
// the same conditions need to be met (this is the view model and we're
// in first-person spectator mode)
m_nTopColor = GetRemapColor( g_PlayerExtraInfo[pTarget->index].teamnumber, true );
m_nBottomColor = GetRemapColor( g_PlayerExtraInfo[pTarget->index].teamnumber, false );
}
}
// we're not spectating, this is OUR view model
else
{
pTarget = gEngfuncs.GetLocalPlayer();
}
if ( pTarget && pTarget->curstate.renderfx == kRenderFxGlowShell )
{
m_pCurrentEntity->curstate.renderfx = kRenderFxGlowShell;
m_pCurrentEntity->curstate.rendercolor.r = pTarget->curstate.rendercolor.r;
m_pCurrentEntity->curstate.rendercolor.g = pTarget->curstate.rendercolor.g;
m_pCurrentEntity->curstate.rendercolor.b = pTarget->curstate.rendercolor.b;
}
else
{
m_pCurrentEntity->curstate.renderfx = kRenderFxNone;
m_pCurrentEntity->curstate.rendercolor.r = 0;
m_pCurrentEntity->curstate.rendercolor.g = 0;
m_pCurrentEntity->curstate.rendercolor.b = 0;
}
}
#else
m_nTopColor = m_pCurrentEntity->curstate.colormap & 0xFF;
m_nBottomColor = (m_pCurrentEntity->curstate.colormap & 0xFF00) >> 8;
#endif
IEngineStudio.StudioSetRemapColors( m_nTopColor, m_nBottomColor );
StudioRenderModel( );
@ -1312,7 +1481,7 @@ void CStudioModelRenderer::StudioProcessGait( entity_state_t *pplayer )
m_pCurrentEntity->angles[YAW] += 360;
m_pCurrentEntity->latched.prevangles[YAW] = m_pCurrentEntity->angles[YAW];
if (pplayer->gaitsequence >= m_pStudioHeader->numseq)
if (pplayer->gaitsequence >= m_pStudioHeader->numseq)
{
pplayer->gaitsequence = 0;
}
@ -1335,6 +1504,149 @@ void CStudioModelRenderer::StudioProcessGait( entity_state_t *pplayer )
m_pPlayerInfo->gaitframe += pseqdesc->numframes;
}
#if defined _TFC
#define PC_UNDEFINED 0
#define PC_SCOUT 1
#define PC_SNIPER 2
#define PC_SOLDIER 3
#define PC_DEMOMAN 4
#define PC_MEDIC 5
#define PC_HVYWEAP 6
#define PC_PYRO 7
#define PC_SPY 8
#define PC_ENGINEER 9
#define PC_RANDOM 10
#define PC_CIVILIAN 11
#define PC_LASTCLASS 12
#define TFC_MODELS_OLD 0
extern cvar_t *tfc_newmodels;
char *sNewClassModelFiles[] =
{
NULL,
"models/player/scout/scout.mdl",
"models/player/sniper/sniper.mdl",
"models/player/soldier/soldier.mdl",
"models/player/demo/demo.mdl",
"models/player/medic/medic.mdl",
"models/player/hvyweapon/hvyweapon.mdl",
"models/player/pyro/pyro.mdl",
"models/player/spy/spy.mdl",
"models/player/engineer/engineer.mdl",
"models/player/scout/scout.mdl", // PC_RANDOM
"models/player/civilian/civilian.mdl",
};
char *sOldClassModelFiles[] =
{
NULL,
"models/player/scout/scout2.mdl",
"models/player/sniper/sniper2.mdl",
"models/player/soldier/soldier2.mdl",
"models/player/demo/demo2.mdl",
"models/player/medic/medic2.mdl",
"models/player/hvyweapon/hvyweapon2.mdl",
"models/player/pyro/pyro2.mdl",
"models/player/spy/spy2.mdl",
"models/player/engineer/engineer2.mdl",
"models/player/scout/scout2.mdl", // PC_RANDOM
"models/player/civilian/civilian.mdl",
};
#define NUM_WEAPON_PMODELS 18
char *sNewWeaponPModels[] =
{
"models/p_9mmhandgun.mdl",
"models/p_crowbar.mdl",
"models/p_egon.mdl",
"models/p_glauncher.mdl",
"models/p_grenade.mdl",
"models/p_knife.mdl",
"models/p_medkit.mdl",
"models/p_mini.mdl",
"models/p_nailgun.mdl",
"models/p_srpg.mdl",
"models/p_shotgun.mdl",
"models/p_snailgun.mdl",
"models/p_sniper.mdl",
"models/p_spanner.mdl",
"models/p_umbrella.mdl",
"models/p_rpg.mdl",
"models/p_spygun.mdl",
"models/p_smallshotgun.mdl"
};
char *sOldWeaponPModels[] =
{
"models/p_9mmhandgun2.mdl",
"models/p_crowbar2.mdl",
"models/p_egon2.mdl",
"models/p_glauncher2.mdl",
"models/p_grenade2.mdl",
"models/p_knife2.mdl",
"models/p_medkit2.mdl",
"models/p_mini2.mdl",
"models/p_nailgun2.mdl",
"models/p_rpg2.mdl",
"models/p_shotgun2.mdl",
"models/p_snailgun2.mdl",
"models/p_sniper2.mdl",
"models/p_spanner2.mdl",
"models/p_umbrella.mdl",
"models/p_rpg2.mdl",
"models/p_9mmhandgun2.mdl",
"models/p_shotgun2.mdl"
};
int CStudioModelRenderer :: ReturnDiguisedClass ( int iPlayerIndex )
{
m_pRenderModel = IEngineStudio.SetupPlayerModel( iPlayerIndex );
if ( !m_pRenderModel )
return PC_SCOUT;
for ( int i = PC_SCOUT ; i < PC_LASTCLASS ; i++ )
{
if ( !strcmp ( m_pRenderModel->name, sNewClassModelFiles[ i ] ) )
return i;
}
return PC_SCOUT;
}
char * ReturnCorrectedModelString ( int iSwitchClass )
{
if ( tfc_newmodels->value == TFC_MODELS_OLD )
{
if ( sOldClassModelFiles[ iSwitchClass ] )
return sOldClassModelFiles[ iSwitchClass ];
else
return sOldClassModelFiles[ PC_SCOUT ];
}
else
{
if ( sNewClassModelFiles[ iSwitchClass ] )
return sNewClassModelFiles[ iSwitchClass ];
else
return sNewClassModelFiles[ PC_SCOUT ];
}
}
#endif
#ifdef _TFC
float g_flSpinUpTime[ 33 ];
float g_flSpinDownTime[ 33 ];
#endif
/*
====================
StudioDrawPlayer
@ -1351,18 +1663,36 @@ int CStudioModelRenderer::StudioDrawPlayer( int flags, entity_state_t *pplayer )
IEngineStudio.GetViewInfo( m_vRenderOrigin, m_vUp, m_vRight, m_vNormal );
IEngineStudio.GetAliasScale( &m_fSoftwareXScale, &m_fSoftwareYScale );
// Con_DPrintf("DrawPlayer %d\n", m_pCurrentEntity->blending[0] );
// Con_DPrintf("DrawPlayer %d %d (%d)\n", m_nFrameCount, pplayer->player_index, m_pCurrentEntity->curstate.sequence );
// Con_DPrintf("Player %.2f %.2f %.2f\n", pplayer->velocity[0], pplayer->velocity[1], pplayer->velocity[2] );
m_nPlayerIndex = pplayer->number - 1;
if (m_nPlayerIndex < 0 || m_nPlayerIndex >= gEngfuncs.GetMaxClients())
return 0;
#if defined( _TFC )
int modelindex;
int iSwitchClass = pplayer->playerclass;
if ( iSwitchClass == PC_SPY )
iSwitchClass = ReturnDiguisedClass( m_nPlayerIndex );
// do we have a "replacement_model" for this player?
if ( pplayer->fuser1 )
{
m_pRenderModel = IEngineStudio.SetupPlayerModel( m_nPlayerIndex );
}
else
{
// get the model pointer using a "corrected" model string based on tfc_newmodels
m_pRenderModel = gEngfuncs.CL_LoadModel( ReturnCorrectedModelString( iSwitchClass ), &modelindex );
}
#else
m_pRenderModel = IEngineStudio.SetupPlayerModel( m_nPlayerIndex );
#endif
if (m_pRenderModel == NULL)
return 0;
@ -1458,9 +1788,48 @@ int CStudioModelRenderer::StudioDrawPlayer( int flags, entity_state_t *pplayer )
m_pPlayerInfo = IEngineStudio.PlayerInfo( m_nPlayerIndex );
// get remap colors
m_nTopColor = m_pPlayerInfo->topcolor;
#if defined _TFC
m_nTopColor = m_pPlayerInfo->topcolor;
m_nBottomColor = m_pPlayerInfo->bottomcolor;
// get old remap colors
if ( tfc_newmodels->value == TFC_MODELS_OLD )
{
// team 1
if ( ( m_nTopColor < 155 ) && ( m_nTopColor > 135 ) )
{
m_nTopColor = TEAM1_COLOR;
m_nBottomColor = TEAM1_COLOR - 10;
}
// team 2
else if ( ( m_nTopColor < 260 ) && ( ( m_nTopColor > 240 ) || ( m_nTopColor == 5 ) ) )
{
m_nTopColor = TEAM2_COLOR;
m_nBottomColor = TEAM2_COLOR - 10;
}
// team 3
else if ( ( m_nTopColor < 50 ) && ( m_nTopColor > 40 ) )
{
m_nTopColor = TEAM3_COLOR;
m_nBottomColor = TEAM3_COLOR - 10;
}
// team 4
else if ( ( m_nTopColor < 110 ) && ( m_nTopColor > 75 ) )
{
m_nTopColor = TEAM4_COLOR;
m_nBottomColor = TEAM4_COLOR - 10;
}
}
#else
// get remap colors
m_nTopColor = m_pPlayerInfo->topcolor;
m_nBottomColor = m_pPlayerInfo->bottomcolor;
#endif
// bounds check
if (m_nTopColor < 0)
m_nTopColor = 0;
if (m_nTopColor > 360)
@ -1481,10 +1850,77 @@ int CStudioModelRenderer::StudioDrawPlayer( int flags, entity_state_t *pplayer )
model_t *pweaponmodel = IEngineStudio.GetModelByIndex( pplayer->weaponmodel );
#if defined _TFC
if ( pweaponmodel )
{
// if we want to see the old p_models
if ( tfc_newmodels->value == TFC_MODELS_OLD )
{
for ( int i = 0 ; i < NUM_WEAPON_PMODELS ; ++i )
{
if ( !stricmp( pweaponmodel->name, sNewWeaponPModels[i] ) )
{
gEngfuncs.CL_LoadModel( sOldWeaponPModels[i] , &modelindex );
pweaponmodel = IEngineStudio.GetModelByIndex( modelindex );
break;
}
}
}
}
#endif
m_pStudioHeader = (studiohdr_t *)IEngineStudio.Mod_Extradata (pweaponmodel);
IEngineStudio.StudioSetHeader( m_pStudioHeader );
StudioMergeBones( pweaponmodel);
#ifdef _TFC
//Do spinning stuff for the HWGuy minigun
if ( strstr ( m_pStudioHeader->name, "p_mini.mdl" ) )
{
if ( g_flSpinUpTime[ m_nPlayerIndex ] && g_flSpinUpTime[ m_nPlayerIndex ] > gEngfuncs.GetClientTime() )
{
float flmod = ( g_flSpinUpTime[ m_nPlayerIndex ] - ( gEngfuncs.GetClientTime() + 3.5 ) );
flmod *= -30;
m_pCurrentEntity->curstate.frame = flmod;
m_pCurrentEntity->curstate.sequence = 2;
}
else if ( g_flSpinUpTime[ m_nPlayerIndex ] && g_flSpinUpTime[ m_nPlayerIndex ] <= gEngfuncs.GetClientTime() )
g_flSpinUpTime[ m_nPlayerIndex ] = 0.0;
else if ( g_flSpinDownTime[ m_nPlayerIndex ] && g_flSpinDownTime[ m_nPlayerIndex ] > gEngfuncs.GetClientTime() && !g_flSpinUpTime[ m_nPlayerIndex ] )
{
float flmod = ( g_flSpinDownTime[ m_nPlayerIndex ] - ( gEngfuncs.GetClientTime() + 3.5 ) );
flmod *= -30;
m_pCurrentEntity->curstate.frame = flmod;
m_pCurrentEntity->curstate.sequence = 3;
}
else if ( g_flSpinDownTime[ m_nPlayerIndex ] && g_flSpinDownTime[ m_nPlayerIndex ] <= gEngfuncs.GetClientTime() && !g_flSpinUpTime[ m_nPlayerIndex ] )
g_flSpinDownTime[ m_nPlayerIndex ] = 0.0;
if ( m_pCurrentEntity->curstate.sequence == 70 || m_pCurrentEntity->curstate.sequence == 72 )
{
if ( g_flSpinUpTime[ m_nPlayerIndex ] )
g_flSpinUpTime[ m_nPlayerIndex ] = 0.0;
m_pCurrentEntity->curstate.sequence = 1;
}
StudioSetupBones( );
}
else
{
if ( g_flSpinUpTime[ m_nPlayerIndex ] || g_flSpinDownTime[ m_nPlayerIndex ] )
{
g_flSpinUpTime[ m_nPlayerIndex ] = 0.0;
g_flSpinDownTime[ m_nPlayerIndex ] = 0.0;
}
}
#endif
StudioMergeBones( pweaponmodel );
IEngineStudio.StudioSetupLighting (&lighting);
@ -1675,3 +2111,4 @@ void CStudioModelRenderer::StudioRenderFinal(void)
}
}

View file

@ -308,9 +308,6 @@ void CHudAmmo::Reset(void)
gWR.Reset();
gHR.Reset();
// VidInit();
}
int CHudAmmo::VidInit(void)
@ -674,7 +671,6 @@ int CHudAmmo::MsgFunc_WeaponList(const char *pszName, int iSize, void *pbuf )
// Slot button pressed
void CHudAmmo::SlotInput( int iSlot )
{
// Let the Viewport use it first, for menus
if ( gViewPort && gViewPort->SlotInput( iSlot ) )
return;
@ -740,7 +736,7 @@ void CHudAmmo::UserCmd_Close(void)
PlaySound("common/wpn_hudoff.wav", 1);
}
else
ClientCmd("escape");
EngineClientCmd("escape");
}

View file

@ -57,16 +57,26 @@ int CHudBattery::VidInit(void)
int CHudBattery:: MsgFunc_Battery(const char *pszName, int iSize, void *pbuf )
{
m_iFlags |= HUD_ACTIVE;
BEGIN_READ( pbuf, iSize );
int x = READ_SHORT();
if (x != m_iBat)
#if defined( _TFC )
int y = READ_SHORT();
if ( x != m_iBat || y != m_iBatMax )
{
m_fFade = FADE_TIME;
m_iBat = x;
m_iBatMax = y;
}
#else
if ( x != m_iBat )
{
m_fFade = FADE_TIME;
m_iBat = x;
}
#endif
return 1;
}
@ -81,7 +91,17 @@ int CHudBattery::Draw(float flTime)
wrect_t rc;
rc = *m_prc2;
#if defined( _TFC )
float fScale = 0.0;
if ( m_iBatMax > 0 )
fScale = 1.0 / (float)m_iBatMax;
rc.top += m_iHeight * ((float)(m_iBatMax-(min(m_iBatMax,m_iBat))) * fScale); // battery can go from 0 to m_iBatMax so * fScale goes from 0 to 1
#else
rc.top += m_iHeight * ((float)(100-(min(100,m_iBat))) * 0.01); // battery can go from 0 to 100 so * 0.01 goes from 0 to 1
#endif
UnpackRGB(r,g,b, RGB_YELLOWISH);

26
cl_dll/bench.h Normal file
View file

@ -0,0 +1,26 @@
#if !defined ( BENCHH )
#define BENCHH
#pragma once
#define FIRST_STAGE 1
#define SECOND_STAGE 2
#define THIRD_STAGE 3
#define FOURTH_STAGE 4
#define LAST_STAGE ( FOURTH_STAGE )
void Bench_CheckStart( void );
int Bench_InStage( int stage );
int Bench_GetPowerPlay( void );
int Bench_GetStage( void );
void Bench_SetPowerPlay( int set );
int Bench_Active( void );
void Bench_SetDotAdded( int dot );
void Bench_SpotPosition( vec3_t dot, vec3_t target );
void Bench_CheckEntity( int type, struct cl_entity_s *ent, const char *modelname );
void Bench_AddObjects( void );
void Bench_SetViewAngles( int recalc_wander, float *viewangles, float frametime, struct usercmd_s *cmd );
void Bench_SetViewOrigin( float *vieworigin, float frametime );
#endif

View file

@ -1,6 +1,6 @@
/***
*
* Copyright (c) 1996-2002, Valve LLC. All rights reserved.
* Copyright (c) 1999, Valve LLC. All rights reserved.
*
* This product contains software technology licensed from Id
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
@ -21,7 +21,9 @@
#include "hud.h"
#include "cl_util.h"
#include "netadr.h"
#include "vgui_schememanager.h"
#undef INTERFACE_H
#include "../public/interface.h"
//#include "vgui_schememanager.h"
extern "C"
{
@ -33,42 +35,33 @@ extern "C"
#include "vgui_int.h"
#include "interface.h"
#define DLLEXPORT __declspec( dllexport )
#ifdef _WIN32
#include "winsani_in.h"
#include <windows.h>
#include "winsani_out.h"
#endif
#include "Exports.h"
#
#include "tri.h"
#include "vgui_TeamFortressViewport.h"
#include "../public/interface.h"
cl_enginefunc_t gEngfuncs;
CHud gHUD;
TeamFortressViewport *gViewPort = NULL;
#include "particleman.h"
CSysModule *g_hParticleManModule = NULL;
IParticleMan *g_pParticleMan = NULL;
void CL_LoadParticleMan( void );
void CL_UnloadParticleMan( void );
void InitInput (void);
void EV_HookEvents( void );
void IN_Commands( void );
/*
==========================
Initialize
Called when the DLL is first loaded.
==========================
*/
extern "C"
{
int DLLEXPORT Initialize( cl_enginefunc_t *pEnginefuncs, int iVersion );
int DLLEXPORT HUD_VidInit( void );
void DLLEXPORT HUD_Init( void );
int DLLEXPORT HUD_Redraw( float flTime, int intermission );
int DLLEXPORT HUD_UpdateClientData( client_data_t *cdata, float flTime );
void DLLEXPORT HUD_Reset ( void );
void DLLEXPORT HUD_PlayerMove( struct playermove_s *ppmove, int server );
void DLLEXPORT HUD_PlayerMoveInit( struct playermove_s *ppmove );
char DLLEXPORT HUD_PlayerMoveTexture( char *name );
int DLLEXPORT HUD_ConnectionlessPacket( const struct netadr_s *net_from, const char *args, char *response_buffer, int *response_buffer_size );
int DLLEXPORT HUD_GetHullBounds( int hullnumber, float *mins, float *maxs );
void DLLEXPORT HUD_Frame( double time );
void DLLEXPORT HUD_VoiceStatus(int entindex, qboolean bTalking);
void DLLEXPORT HUD_DirectorMessage( int iSize, void *pbuf );
}
/*
================================
HUD_GetHullBounds
@ -76,8 +69,10 @@ HUD_GetHullBounds
Engine calls this to enumerate player collision hulls, for prediction. Return 0 if the hullnumber doesn't exist.
================================
*/
int DLLEXPORT HUD_GetHullBounds( int hullnumber, float *mins, float *maxs )
int CL_DLLEXPORT HUD_GetHullBounds( int hullnumber, float *mins, float *maxs )
{
// RecClGetHullBounds(hullnumber, mins, maxs);
int iret = 0;
switch ( hullnumber )
@ -110,8 +105,10 @@ HUD_ConnectionlessPacket
size of the response_buffer, so you must zero it out if you choose not to respond.
================================
*/
int DLLEXPORT HUD_ConnectionlessPacket( const struct netadr_s *net_from, const char *args, char *response_buffer, int *response_buffer_size )
int CL_DLLEXPORT HUD_ConnectionlessPacket( const struct netadr_s *net_from, const char *args, char *response_buffer, int *response_buffer_size )
{
// RecClConnectionlessPacket(net_from, args, response_buffer, response_buffer_size);
// Parse stuff from args
int max_buffer_size = *response_buffer_size;
@ -124,32 +121,42 @@ int DLLEXPORT HUD_ConnectionlessPacket( const struct netadr_s *net_from, const c
return 0;
}
void DLLEXPORT HUD_PlayerMoveInit( struct playermove_s *ppmove )
void CL_DLLEXPORT HUD_PlayerMoveInit( struct playermove_s *ppmove )
{
// RecClClientMoveInit(ppmove);
PM_Init( ppmove );
}
char DLLEXPORT HUD_PlayerMoveTexture( char *name )
char CL_DLLEXPORT HUD_PlayerMoveTexture( char *name )
{
// RecClClientTextureType(name);
return PM_FindTextureType( name );
}
void DLLEXPORT HUD_PlayerMove( struct playermove_s *ppmove, int server )
void CL_DLLEXPORT HUD_PlayerMove( struct playermove_s *ppmove, int server )
{
// RecClClientMove(ppmove, server);
PM_Move( ppmove, server );
}
int DLLEXPORT Initialize( cl_enginefunc_t *pEnginefuncs, int iVersion )
int CL_DLLEXPORT Initialize( cl_enginefunc_t *pEnginefuncs, int iVersion )
{
gEngfuncs = *pEnginefuncs;
// RecClInitialize(pEnginefuncs, iVersion);
if (iVersion != CLDLL_INTERFACE_VERSION)
return 0;
memcpy(&gEngfuncs, pEnginefuncs, sizeof(cl_enginefunc_t));
EV_HookEvents();
CL_LoadParticleMan();
// get tracker interface, if any
return 1;
}
@ -164,8 +171,9 @@ so the HUD can reinitialize itself.
==========================
*/
int DLLEXPORT HUD_VidInit( void )
int CL_DLLEXPORT HUD_VidInit( void )
{
// RecClHudVidInit();
gHUD.VidInit();
VGui_Startup();
@ -183,8 +191,9 @@ the hud variables.
==========================
*/
void DLLEXPORT HUD_Init( void )
void CL_DLLEXPORT HUD_Init( void )
{
// RecClHudInit();
InitInput();
gHUD.Init();
Scheme_Init();
@ -200,8 +209,10 @@ redraw the HUD.
===========================
*/
int DLLEXPORT HUD_Redraw( float time, int intermission )
int CL_DLLEXPORT HUD_Redraw( float time, int intermission )
{
// RecClHudRedraw(time, intermission);
gHUD.Redraw( time, intermission );
return 1;
@ -221,8 +232,10 @@ returns 1 if anything has been changed, 0 otherwise.
==========================
*/
int DLLEXPORT HUD_UpdateClientData(client_data_t *pcldata, float flTime )
int CL_DLLEXPORT HUD_UpdateClientData(client_data_t *pcldata, float flTime )
{
// RecClHudUpdateClientData(pcldata, flTime);
IN_Commands();
return gHUD.UpdateClientData(pcldata, flTime );
@ -236,8 +249,10 @@ Called at start and end of demos to restore to "non"HUD state.
==========================
*/
void DLLEXPORT HUD_Reset( void )
void CL_DLLEXPORT HUD_Reset( void )
{
// RecClHudReset();
gHUD.VidInit();
}
@ -249,8 +264,10 @@ Called by engine every frame that client .dll is loaded
==========================
*/
void DLLEXPORT HUD_Frame( double time )
void CL_DLLEXPORT HUD_Frame( double time )
{
// RecClHudFrame(time);
ServersThink( time );
GetClientVoiceMgr()->Frame(time);
@ -265,22 +282,166 @@ Called when a player starts or stops talking.
==========================
*/
void DLLEXPORT HUD_VoiceStatus(int entindex, qboolean bTalking)
void CL_DLLEXPORT HUD_VoiceStatus(int entindex, qboolean bTalking)
{
//// RecClVoiceStatus(entindex, bTalking);
GetClientVoiceMgr()->UpdateSpeakerStatus(entindex, bTalking);
}
/*
==========================
HUD_DirectorEvent
HUD_DirectorMessage
Called when a director event message was received
==========================
*/
void DLLEXPORT HUD_DirectorMessage( int iSize, void *pbuf )
void CL_DLLEXPORT HUD_DirectorMessage( int iSize, void *pbuf )
{
gHUD.m_Spectator.DirectorMessage( iSize, pbuf );
// RecClDirectorMessage(iSize, pbuf);
gHUD.m_Spectator.DirectorMessage( iSize, pbuf );
}
void CL_UnloadParticleMan( void )
{
Sys_UnloadModule( g_hParticleManModule );
g_pParticleMan = NULL;
g_hParticleManModule = NULL;
}
void CL_LoadParticleMan( void )
{
char szPDir[512];
if ( gEngfuncs.COM_ExpandFilename( PARTICLEMAN_DLLNAME, szPDir, sizeof( szPDir ) ) == FALSE )
{
g_pParticleMan = NULL;
g_hParticleManModule = NULL;
return;
}
g_hParticleManModule = Sys_LoadModule( szPDir );
CreateInterfaceFn particleManFactory = Sys_GetFactory( g_hParticleManModule );
if ( particleManFactory == NULL )
{
g_pParticleMan = NULL;
g_hParticleManModule = NULL;
return;
}
g_pParticleMan = (IParticleMan *)particleManFactory( PARTICLEMAN_INTERFACE, NULL);
if ( g_pParticleMan )
{
g_pParticleMan->SetUp( &gEngfuncs );
// Add custom particle classes here BEFORE calling anything else or you will die.
g_pParticleMan->AddCustomParticleClassSize ( sizeof ( CBaseParticle ) );
}
}
cldll_func_dst_t *g_pcldstAddrs;
extern "C" void CL_DLLEXPORT F(void *pv)
{
cldll_func_t *pcldll_func = (cldll_func_t *)pv;
// Hack!
g_pcldstAddrs = ((cldll_func_dst_t *)pcldll_func->pHudVidInitFunc);
cldll_func_t cldll_func =
{
Initialize,
HUD_Init,
HUD_VidInit,
HUD_Redraw,
HUD_UpdateClientData,
HUD_Reset,
HUD_PlayerMove,
HUD_PlayerMoveInit,
HUD_PlayerMoveTexture,
IN_ActivateMouse,
IN_DeactivateMouse,
IN_MouseEvent,
IN_ClearStates,
IN_Accumulate,
CL_CreateMove,
CL_IsThirdPerson,
CL_CameraOffset,
KB_Find,
CAM_Think,
V_CalcRefdef,
HUD_AddEntity,
HUD_CreateEntities,
HUD_DrawNormalTriangles,
HUD_DrawTransparentTriangles,
HUD_StudioEvent,
HUD_PostRunCmd,
HUD_Shutdown,
HUD_TxferLocalOverrides,
HUD_ProcessPlayerState,
HUD_TxferPredictionData,
Demo_ReadBuffer,
HUD_ConnectionlessPacket,
HUD_GetHullBounds,
HUD_Frame,
HUD_Key_Event,
HUD_TempEntUpdate,
HUD_GetUserEntity,
HUD_VoiceStatus,
HUD_DirectorMessage,
HUD_GetStudioModelInterface,
HUD_ChatInputPosition,
};
*pcldll_func = cldll_func;
}
#include "cl_dll/IGameClientExports.h"
//-----------------------------------------------------------------------------
// Purpose: Exports functions that are used by the gameUI for UI dialogs
//-----------------------------------------------------------------------------
class CClientExports : public IGameClientExports
{
public:
// returns the name of the server the user is connected to, if any
virtual const char *GetServerHostName()
{
/*if (gViewPortInterface)
{
return gViewPortInterface->GetServerName();
}*/
return "";
}
// ingame voice manipulation
virtual bool IsPlayerGameVoiceMuted(int playerIndex)
{
if (GetClientVoiceMgr())
return GetClientVoiceMgr()->IsPlayerBlocked(playerIndex);
return false;
}
virtual void MutePlayerGameVoice(int playerIndex)
{
if (GetClientVoiceMgr())
{
GetClientVoiceMgr()->SetPlayerBlockedState(playerIndex, true);
}
}
virtual void UnmutePlayerGameVoice(int playerIndex)
{
if (GetClientVoiceMgr())
{
GetClientVoiceMgr()->SetPlayerBlockedState(playerIndex, false);
}
}
};
EXPOSE_SINGLE_INTERFACE(CClientExports, IGameClientExports, GAMECLIENTEXPORTS_INTERFACE_VERSION);

View file

@ -23,8 +23,6 @@ CFG=cl_dll - Win32 Release
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=cl.exe
MTL=midl.exe
RSC=rc.exe
@ -43,7 +41,7 @@ RSC=rc.exe
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /c
# ADD CPP /nologo /MT /W3 /GX /Zi /O2 /I "..\utils\vgui\include" /I "..\engine" /I "..\common" /I "..\pm_shared" /I "..\dlls" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "CLIENT_DLL" /D "CLIENT_WEAPONS" /YX /FD /c
# ADD CPP /nologo /W3 /GR /GX /Zi /O2 /I "..\dlls" /I "." /I "..\tfc" /I "..\public" /I "..\common" /I "..\pm_shared" /I "..\engine" /I "..\utils\vgui\include" /I "..\game_shared" /I "..\external" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "CLIENT_DLL" /D "CLIENT_WEAPONS" /D "HL_DLL" /FR /YX /FD /c
# ADD BASE MTL /nologo /D "NDEBUG" /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x409 /d "NDEBUG"
@ -53,7 +51,26 @@ BSC32=bscmake.exe
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib winmm.lib ../utils/vgui/lib/win32_vc6/vgui.lib wsock32.lib /nologo /subsystem:windows /dll /map /machine:I386 /out:".\Release\client.dll"
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib winmm.lib ..\utils\vgui\lib\win32_vc6\vgui.lib wsock32.lib ..\lib\public\sdl2.lib /nologo /base:"0x01900000" /subsystem:windows /dll /map /debug /machine:I386 /nodefaultlib:"LIBCMTD" /nodefaultlib:"LIBCD" /out:".\Release\client.dll"
# SUBTRACT LINK32 /pdb:none
# Begin Custom Build
InputDir=.\Release
ProjDir=.
InputPath=.\Release\client.dll
InputName=client
SOURCE="$(InputPath)"
BuildCmds= \
call ..\filecopy.bat $(InputDir)\$(InputName).dll $(ProjDir)\..\..\game\mod\cl_dlls\$(InputName).dll \
call ..\filecopy.bat $(InputDir)\$(InputName).pdb $(ProjDir)\..\..\game\mod\cl_dlls\$(InputName).pdb \
"$(ProjDir)\..\..\game\mod\cl_dlls\$(InputName).dll" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
$(BuildCmds)
"$(ProjDir)\..\..\game\mod\cl_dlls\$(InputName).pdb" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
$(BuildCmds)
# End Custom Build
!ELSEIF "$(CFG)" == "cl_dll - Win32 Debug"
@ -69,7 +86,7 @@ LINK32=link.exe
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /c
# ADD CPP /nologo /G5 /MTd /W3 /Gm /GR /GX /ZI /Od /I "..\dlls" /I "..\common" /I "..\pm_shared" /I "..\engine" /I "..\utils\vgui\include" /I "..\game_shared" /D "_DEBUG" /D "_MBCS" /D "WIN32" /D "_WINDOWS" /D "CLIENT_DLL" /D "CLIENT_WEAPONS" /FR /YX /FD /c
# ADD CPP /nologo /G5 /MTd /W3 /Gm /GR /GX /ZI /Od /I "..\dlls" /I "." /I "..\tfc" /I "..\public" /I "..\common" /I "..\pm_shared" /I "..\engine" /I "..\utils\vgui\include" /I "..\game_shared" /I "..\external" /D "_DEBUG" /D "_MBCS" /D "WIN32" /D "_WINDOWS" /D "CLIENT_DLL" /D "CLIENT_WEAPONS" /D "_WINDLL" /D "HL_DLL" /FR /YX /FD /c
# ADD BASE MTL /nologo /D "_DEBUG" /win32
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x409 /d "_DEBUG"
@ -79,7 +96,26 @@ BSC32=bscmake.exe
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386
# ADD LINK32 oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib winmm.lib ../utils/vgui/lib/win32_vc6/vgui.lib wsock32.lib /nologo /subsystem:windows /dll /debug /machine:I386 /out:".\Debug\client.dll"
# ADD LINK32 oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib winmm.lib ..\utils\vgui\lib\win32_vc6\vgui.lib wsock32.lib ..\lib\public\sdl2.lib /nologo /base:"0x01900000" /subsystem:windows /dll /debug /machine:I386 /out:".\Debug\client.dll"
# SUBTRACT LINK32 /pdb:none
# Begin Custom Build
InputDir=.\Debug
ProjDir=.
InputPath=.\Debug\client.dll
InputName=client
SOURCE="$(InputPath)"
BuildCmds= \
call ..\filecopy.bat $(InputDir)\$(InputName).dll $(ProjDir)\..\..\game\mod\cl_dlls\$(InputName).dll \
call ..\filecopy.bat $(InputDir)\$(InputName).pdb $(ProjDir)\..\..\game\mod\cl_dlls\$(InputName).pdb \
"$(ProjDir)\..\..\game\mod\cl_dlls\$(InputName).dll" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
$(BuildCmds)
"$(ProjDir)\..\..\game\mod\cl_dlls\$(InputName).pdb" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
$(BuildCmds)
# End Custom Build
!ENDIF
@ -92,7 +128,7 @@ LINK32=link.exe
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat;for;f90"
# Begin Group "hl"
# PROP Default_Filter "*.CPP"
# PROP Default_Filter "*.cpp"
# Begin Source File
SOURCE=..\dlls\crossbow.cpp
@ -143,10 +179,6 @@ SOURCE=..\dlls\hornetgun.cpp
# End Source File
# Begin Source File
SOURCE=..\common\interface.cpp
# End Source File
# Begin Source File
SOURCE=..\dlls\mp5.cpp
# End Source File
# Begin Source File
@ -173,22 +205,6 @@ SOURCE=..\dlls\squeakgrenade.cpp
SOURCE=..\dlls\tripmine.cpp
# End Source File
# Begin Source File
SOURCE=..\game_shared\vgui_scrollbar2.cpp
# End Source File
# Begin Source File
SOURCE=..\game_shared\vgui_slider2.cpp
# End Source File
# Begin Source File
SOURCE=..\game_shared\voice_banmgr.cpp
# End Source File
# Begin Source File
SOURCE=..\game_shared\voice_status.cpp
# End Source File
# End Group
# Begin Source File
@ -225,6 +241,15 @@ SOURCE=.\demo.cpp
# Begin Source File
SOURCE=.\entity.cpp
!IF "$(CFG)" == "cl_dll - Win32 Release"
!ELSEIF "$(CFG)" == "cl_dll - Win32 Debug"
# ADD CPP /MT
!ENDIF
# End Source File
# Begin Source File
@ -256,6 +281,14 @@ SOURCE=.\hud.cpp
# End Source File
# Begin Source File
SOURCE=.\hud_bench.cpp
# End Source File
# Begin Source File
SOURCE=.\hud_benchtrace.cpp
# End Source File
# Begin Source File
SOURCE=.\hud_msg.cpp
# End Source File
# Begin Source File
@ -288,6 +321,14 @@ SOURCE=.\inputw32.cpp
# End Source File
# Begin Source File
SOURCE=..\public\interface.cpp
# End Source File
# Begin Source File
SOURCE=.\interpolation.cpp
# End Source File
# Begin Source File
SOURCE=.\menu.cpp
# End Source File
# Begin Source File
@ -296,16 +337,7 @@ SOURCE=.\message.cpp
# End Source File
# Begin Source File
SOURCE=.\overview.cpp
# PROP Exclude_From_Build 1
# End Source File
# Begin Source File
SOURCE=.\parsemsg.cpp
# End Source File
# Begin Source File
SOURCE=.\parsemsg.h
SOURCE=..\common\parsemsg.cpp
# End Source File
# Begin Source File
@ -365,10 +397,6 @@ SOURCE=.\vgui_ClassMenu.cpp
# End Source File
# Begin Source File
SOURCE=.\vgui_ConsolePanel.cpp
# End Source File
# Begin Source File
SOURCE=.\vgui_ControlConfigPanel.cpp
# End Source File
# Begin Source File
@ -409,10 +437,18 @@ SOURCE=.\vgui_ScorePanel.cpp
# End Source File
# Begin Source File
SOURCE=..\game_shared\vgui_scrollbar2.cpp
# End Source File
# Begin Source File
SOURCE=.\vgui_ServerBrowser.cpp
# End Source File
# Begin Source File
SOURCE=..\game_shared\vgui_slider2.cpp
# End Source File
# Begin Source File
SOURCE=.\vgui_SpectatorPanel.cpp
# End Source File
# Begin Source File
@ -421,12 +457,20 @@ SOURCE=.\vgui_TeamFortressViewport.cpp
# End Source File
# Begin Source File
SOURCE=.\vgui_teammenu.cpp
SOURCE=.\vgui_TeamMenu.cpp
# End Source File
# Begin Source File
SOURCE=.\view.cpp
# End Source File
# Begin Source File
SOURCE=..\game_shared\voice_banmgr.cpp
# End Source File
# Begin Source File
SOURCE=.\voice_status.cpp
# End Source File
# End Group
# Begin Group "Header Files"
@ -449,6 +493,10 @@ SOURCE=.\cl_dll.h
# End Source File
# Begin Source File
SOURCE=.\cl_util.h
# End Source File
# Begin Source File
SOURCE=.\com_weapons.h
# End Source File
# Begin Source File
@ -477,10 +525,6 @@ SOURCE=.\hud.h
# End Source File
# Begin Source File
SOURCE=.\hud_iface.h
# End Source File
# Begin Source File
SOURCE=.\hud_servers.h
# End Source File
# Begin Source File
@ -497,7 +541,7 @@ SOURCE=.\in_defs.h
# End Source File
# Begin Source File
SOURCE=..\common\itrackeruser.h
SOURCE=.\interpolation.h
# End Source File
# Begin Source File
@ -505,7 +549,7 @@ SOURCE=.\kbutton.h
# End Source File
# Begin Source File
SOURCE=.\overview.h
SOURCE=..\common\parsemsg.h
# End Source File
# Begin Source File
@ -533,15 +577,11 @@ SOURCE=..\pm_shared\pm_shared.h
# End Source File
# Begin Source File
SOURCE=.\studio_util.h
# End Source File
# Begin Source File
SOURCE=.\StudioModelRenderer.h
# End Source File
# Begin Source File
SOURCE=.\util.h
SOURCE=.\tri.h
# End Source File
# Begin Source File
@ -549,10 +589,6 @@ SOURCE=.\util_vector.h
# End Source File
# Begin Source File
SOURCE=.\vgui_ConsolePanel.h
# End Source File
# Begin Source File
SOURCE=.\vgui_ControlConfigPanel.h
# End Source File
# Begin Source File
@ -569,15 +605,19 @@ SOURCE=.\vgui_ScorePanel.h
# End Source File
# Begin Source File
SOURCE=..\game_shared\vgui_scrollbar2.h
# End Source File
# Begin Source File
SOURCE=.\vgui_ServerBrowser.h
# End Source File
# Begin Source File
SOURCE=.\vgui_SpectatorPanel.h
SOURCE=..\game_shared\vgui_slider2.h
# End Source File
# Begin Source File
SOURCE=.\vgui_TeamFortressViewport.h
SOURCE=.\vgui_SpectatorPanel.h
# End Source File
# Begin Source File
@ -593,10 +633,6 @@ SOURCE=..\game_shared\voice_status.h
# End Source File
# Begin Source File
SOURCE=..\game_shared\voice_vgui_tweakdlg.h
# End Source File
# Begin Source File
SOURCE=.\wrect.h
# End Source File
# End Group
@ -604,5 +640,9 @@ SOURCE=.\wrect.h
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe"
# End Group
# Begin Source File
SOURCE=..\lib\public\game_controls.lib
# End Source File
# End Target
# End Project

View file

@ -31,7 +31,11 @@ typedef float vec_t;
typedef int (*pfnUserMsgHook)(const char *pszName, int iSize, void *pbuf);
#include "util_vector.h"
#ifdef _WIN32
#define EXPORT _declspec( dllexport )
#else
#define EXPORT __attribute__ ((visibility("default")))
#endif
#include "../engine/cdll_int.h"
#include "../dlls/cdll_dll.h"

View file

@ -1,6 +1,6 @@
/***
*
* Copyright (c) 1996-2002, Valve LLC. All rights reserved.
* Copyright (c) 1999, Valve LLC. All rights reserved.
*
* This product contains software technology licensed from Id
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
@ -23,19 +23,23 @@
#define FALSE 0
#endif
#include <stdio.h> // for safe_sprintf()
#include <stdarg.h> // "
#include <string.h> // for strncpy()
// Macros to hook function calls into the HUD object
#define HOOK_MESSAGE(x) gEngfuncs.pfnHookUserMsg(#x, __MsgFunc_##x );
#define DECLARE_MESSAGE(y, x) int __MsgFunc_##x(const char *pszName, int iSize, void *pbuf) \
{ \
return gHUD.##y.MsgFunc_##x(pszName, iSize, pbuf ); \
return gHUD.y.MsgFunc_##x(pszName, iSize, pbuf ); \
}
#define HOOK_COMMAND(x, y) gEngfuncs.pfnAddCommand( x, __CmdFunc_##y );
#define DECLARE_COMMAND(y, x) void __CmdFunc_##x( void ) \
{ \
gHUD.##y.UserCmd_##x( ); \
gHUD.y.UserCmd_##x( ); \
}
inline float CVAR_GET_FLOAT( const char *x ) { return gEngfuncs.pfnGetCvarFloat( (char*)x ); }
@ -67,17 +71,18 @@ inline struct cvar_s *CVAR_CREATE( const char *cv, const char *val, const int fl
// ScreenWidth returns the width of the screen, in pixels
#define ScreenWidth (gHUD.m_scrinfo.iWidth)
// Use this to set any co-ords in 640x480 space
#define XRES(x) ((int)(float(x) * ((float)ScreenWidth / 640.0f) + 0.5f))
#define YRES(y) ((int)(float(y) * ((float)ScreenHeight / 480.0f) + 0.5f))
#define BASE_XRES 640.f
// use this to project world coordinates to screen coordinates
#define XPROJECT(x) ( (1.0f+(x))*ScreenWidth*0.5f )
#define YPROJECT(y) ( (1.0f-(y))*ScreenHeight*0.5f )
#define XRES(x) (x * ((float)ScreenWidth / 640))
#define YRES(y) (y * ((float)ScreenHeight / 480))
#define GetScreenInfo (*gEngfuncs.pfnGetScreenInfo)
#define ServerCmd (*gEngfuncs.pfnServerCmd)
#define ClientCmd (*gEngfuncs.pfnClientCmd)
#define EngineClientCmd (*gEngfuncs.pfnClientCmd)
#define SetCrosshair (*gEngfuncs.pfnSetCrosshair)
#define AngleVectors (*gEngfuncs.pfnAngleVectors)
@ -119,8 +124,39 @@ inline void CenterPrint( const char *string )
gEngfuncs.pfnCenterPrint( string );
}
// returns the players name of entity no.
#define GetPlayerInfo (*gEngfuncs.pfnGetPlayerInfo)
inline char *safe_strcpy( char *dst, const char *src, int len_dst)
{
if( len_dst <= 0 )
{
return NULL; // this is bad
}
strncpy(dst,src,len_dst);
dst[ len_dst - 1 ] = '\0';
return dst;
}
inline int safe_sprintf( char *dst, int len_dst, const char *format, ...)
{
if( len_dst <= 0 )
{
return -1; // this is bad
}
va_list v;
va_start(v, format);
_vsnprintf(dst,len_dst,format,v);
va_end(v);
dst[ len_dst - 1 ] = '\0';
return 0;
}
// sound functions
inline void PlaySound( char *szSound, float vol ) { gEngfuncs.pfnPlaySoundByName( szSound, vol ); }

View file

@ -273,5 +273,5 @@ stub functions for such things as precaching. So we don't have to modify weapon
int stub_PrecacheModel ( char* s ) { return 0; }
int stub_PrecacheSound ( char* s ) { return 0; }
unsigned short stub_PrecacheEvent ( int type, const char *s ) { return 0; }
const char *stub_NameForFunction ( unsigned long function ) { return "func"; }
const char *stub_NameForFunction ( uint32 function ) { return "func"; }
void stub_SetModel ( edict_t *e, const char *m ) {}

View file

@ -14,11 +14,7 @@
#endif
#include "hud_iface.h"
extern "C"
{
void _DLLEXPORT HUD_PostRunCmd( struct local_state_s *from, struct local_state_s *to, struct usercmd_s *cmd, int runfuncs, double time, unsigned int random_seed );
}
#include "Exports.h"
void COM_Log( char *pszFile, char *fmt, ...);
int CL_IsDead( void );
@ -34,7 +30,7 @@ void HUD_SetMaxSpeed( const struct edict_s *ed, float speed );
int stub_PrecacheModel( char* s );
int stub_PrecacheSound( char* s );
unsigned short stub_PrecacheEvent( int type, const char *s );
const char *stub_NameForFunction ( unsigned long function );
const char *stub_NameForFunction ( uint32 function );
void stub_SetModel ( struct edict_s *e, const char *m );

View file

@ -1,6 +1,6 @@
/***
*
* Copyright (c) 1996-2002, Valve LLC. All rights reserved.
* Copyright (c) 1999, Valve LLC. All rights reserved.
*
* This product contains software technology licensed from Id
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
@ -115,7 +115,7 @@ int CHudDeathNotice :: Draw( float flTime )
if ( gViewPort && gViewPort->AllowedToPrintText() )
{
// Draw the death notice
y = YRES(DEATHNOTICE_TOP) + 2 + (20 * i); //!!!
y = DEATHNOTICE_TOP + 2 + (20 * i); //!!!
int id = (rgDeathNoticeList[i].iId == -1) ? m_HUD_d_skull : rgDeathNoticeList[i].iId;
x = ScreenWidth - ConsoleStringLen(rgDeathNoticeList[i].szVictim) - (gHUD.GetSpriteRect(id).right - gHUD.GetSpriteRect(id).left);
@ -173,8 +173,8 @@ int CHudDeathNotice :: MsgFunc_DeathMsg( const char *pszName, int iSize, void *p
gViewPort->DeathMsg( killer, victim );
gHUD.m_Spectator.DeathMessage(victim);
for ( int i = 0; i < MAX_DEATHNOTICES; i++ )
int i;
for ( i = 0; i < MAX_DEATHNOTICES; i++ )
{
if ( rgDeathNoticeList[i].iId == 0 )
break;

View file

@ -17,8 +17,7 @@
#include "demo.h"
#include "demo_api.h"
#include <memory.h>
#define DLLEXPORT __declspec( dllexport )
#include "Exports.h"
int g_demosniper = 0;
int g_demosniperdamage = 0;
@ -28,11 +27,6 @@ float g_demozoom;
// FIXME: There should be buffer helper functions to avoid all of the *(int *)& crap.
extern "C"
{
void DLLEXPORT Demo_ReadBuffer( int size, unsigned char *buffer );
}
/*
=====================
Demo_WriteBuffer
@ -60,8 +54,10 @@ Demo_ReadBuffer
Engine wants us to parse some data from the demo stream
=====================
*/
void DLLEXPORT Demo_ReadBuffer( int size, unsigned char *buffer )
void CL_DLLEXPORT Demo_ReadBuffer( int size, unsigned char *buffer )
{
// RecClReadDemoBuffer(size, buffer);
int type;
int i = 0;

View file

@ -1,10 +1,3 @@
//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================
// Client side entity management functions
#include <memory.h>
@ -19,8 +12,11 @@
#include "pm_defs.h"
#include "pmtrace.h"
#include "pm_shared.h"
#include "bench.h"
#include "Exports.h"
#define DLLEXPORT __declspec( dllexport )
#include "particleman.h"
extern IParticleMan *g_pParticleMan;
void Game_AddObjects( void );
@ -28,29 +24,21 @@ extern vec3_t v_origin;
int g_iAlive = 1;
extern "C"
{
int DLLEXPORT HUD_AddEntity( int type, struct cl_entity_s *ent, const char *modelname );
void DLLEXPORT HUD_CreateEntities( void );
void DLLEXPORT HUD_StudioEvent( const struct mstudioevent_s *event, const struct cl_entity_s *entity );
void DLLEXPORT HUD_TxferLocalOverrides( struct entity_state_s *state, const struct clientdata_s *client );
void DLLEXPORT HUD_ProcessPlayerState( struct entity_state_s *dst, const struct entity_state_s *src );
void DLLEXPORT HUD_TxferPredictionData ( struct entity_state_s *ps, const struct entity_state_s *pps, struct clientdata_s *pcd, const struct clientdata_s *ppcd, struct weapon_data_s *wd, const struct weapon_data_s *pwd );
void DLLEXPORT HUD_TempEntUpdate( double frametime, double client_time, double cl_gravity, struct tempent_s **ppTempEntFree, struct tempent_s **ppTempEntActive, int ( *Callback_AddVisibleEntity )( struct cl_entity_s *pEntity ), void ( *Callback_TempEntPlaySound )( struct tempent_s *pTemp, float damp ) );
struct cl_entity_s DLLEXPORT *HUD_GetUserEntity( int index );
}
/*
========================
HUD_AddEntity
Return 0 to filter entity from visible list for rendering
========================
*/
int DLLEXPORT HUD_AddEntity( int type, struct cl_entity_s *ent, const char *modelname )
int CL_DLLEXPORT HUD_AddEntity( int type, struct cl_entity_s *ent, const char *modelname )
{
// RecClAddEntity(type, ent, modelname);
switch ( type )
{
case ET_NORMAL:
Bench_CheckEntity( type, ent, modelname );
break;
case ET_PLAYER:
case ET_BEAM:
case ET_TEMPENTITY:
@ -85,8 +73,10 @@ playerstate update in entity_state_t. In order for these overrides to eventuall
structure, we need to copy them into the state structure at this point.
=========================
*/
void DLLEXPORT HUD_TxferLocalOverrides( struct entity_state_s *state, const struct clientdata_s *client )
void CL_DLLEXPORT HUD_TxferLocalOverrides( struct entity_state_s *state, const struct clientdata_s *client )
{
// RecClTxferLocalOverrides(state, client);
VectorCopy( client->origin, state->origin );
// Spectator
@ -108,8 +98,10 @@ We have received entity_state_t for this player over the network. We need to co
playerstate structure
=========================
*/
void DLLEXPORT HUD_ProcessPlayerState( struct entity_state_s *dst, const struct entity_state_s *src )
void CL_DLLEXPORT HUD_ProcessPlayerState( struct entity_state_s *dst, const struct entity_state_s *src )
{
// RecClProcessPlayerState(dst, src);
// Copy in network data
VectorCopy( src->origin, dst->origin );
VectorCopy( src->angles, dst->angles );
@ -151,6 +143,10 @@ void DLLEXPORT HUD_ProcessPlayerState( struct entity_state_s *dst, const struct
dst->team = src->team;
dst->colormap = src->colormap;
#if defined( _TFC )
dst->fuser1 = src->fuser1;
#endif
// Save off some data so other areas of the Client DLL can get to it
cl_entity_t *player = gEngfuncs.GetLocalPlayer(); // Get the local player's index
if ( dst->number == player->index )
@ -174,8 +170,10 @@ Because we can predict an arbitrary number of frames before the server responds
update is occupying.
=========================
*/
void DLLEXPORT HUD_TxferPredictionData ( struct entity_state_s *ps, const struct entity_state_s *pps, struct clientdata_s *pcd, const struct clientdata_s *ppcd, struct weapon_data_s *wd, const struct weapon_data_s *pwd )
void CL_DLLEXPORT HUD_TxferPredictionData ( struct entity_state_s *ps, const struct entity_state_s *pps, struct clientdata_s *pcd, const struct clientdata_s *ppcd, struct weapon_data_s *wd, const struct weapon_data_s *pwd )
{
// RecClTxferPredictionData(ps, pps, pcd, ppcd, wd, pwd);
ps->oldbuttons = pps->oldbuttons;
ps->flFallVelocity = pps->flFallVelocity;
ps->iStepLeft = pps->iStepLeft;
@ -212,7 +210,6 @@ void DLLEXPORT HUD_TxferPredictionData ( struct entity_state_s *ps, const struct
pcd->iuser1 = g_iUser1; // observer mode
pcd->iuser2 = g_iUser2; // first target
pcd->iuser3 = g_iUser3; // second target
}
// Fire prevention
@ -229,210 +226,6 @@ void DLLEXPORT HUD_TxferPredictionData ( struct entity_state_s *ps, const struct
memcpy( wd, pwd, 32 * sizeof( weapon_data_t ) );
}
/*
//#define TEST_IT
#if defined( TEST_IT )
cl_entity_t mymodel[9];
void MoveModel( void )
{
cl_entity_t *player;
int i, j;
int modelindex;
struct model_s *mod;
// Load it up with some bogus data
player = gEngfuncs.GetLocalPlayer();
if ( !player )
return;
mod = gEngfuncs.CL_LoadModel( "models/sentry3.mdl", &modelindex );
for ( i = 0; i < 3; i++ )
{
for ( j = 0; j < 3; j++ )
{
// Don't draw over ourself...
if ( ( i == 1 ) && ( j == 1 ) )
continue;
mymodel[ i * 3 + j ] = *player;
mymodel[ i * 3 + j ].player = 0;
mymodel[ i * 3 + j ].model = mod;
mymodel[ i * 3 + j ].curstate.modelindex = modelindex;
// Move it out a bit
mymodel[ i * 3 + j ].origin[0] = player->origin[0] + 50 * ( 1 - i );
mymodel[ i * 3 + j ].origin[1] = player->origin[1] + 50 * ( 1 - j );
gEngfuncs.CL_CreateVisibleEntity( ET_NORMAL, &mymodel[i*3+j] );
}
}
}
#endif
//#define TRACE_TEST
#if defined( TRACE_TEST )
extern int hitent;
cl_entity_t hit;
void TraceModel( void )
{
cl_entity_t *ent;
if ( hitent <= 0 )
return;
// Load it up with some bogus data
ent = gEngfuncs.GetEntityByIndex( hitent );
if ( !ent )
return;
hit = *ent;
//hit.curstate.rendermode = kRenderTransTexture;
//hit.curstate.renderfx = kRenderFxGlowShell;
//hit.curstate.renderamt = 100;
hit.origin[2] += 40;
gEngfuncs.CL_CreateVisibleEntity( ET_NORMAL, &hit );
}
#endif
*/
/*
void ParticleCallback( struct particle_s *particle, float frametime )
{
int i;
for ( i = 0; i < 3; i++ )
{
particle->org[ i ] += particle->vel[ i ] * frametime;
}
}
cvar_t *color = NULL;
void Particles( void )
{
static float lasttime;
float curtime;
curtime = gEngfuncs.GetClientTime();
if ( ( curtime - lasttime ) < 2.0 )
return;
if ( !color )
{
color = gEngfuncs.pfnRegisterVariable ( "color","255 0 0", 0 );
}
lasttime = curtime;
// Create a few particles
particle_t *p;
int i, j;
for ( i = 0; i < 1000; i++ )
{
int r, g, b;
p = gEngfuncs.pEfxAPI->R_AllocParticle( ParticleCallback );
if ( !p )
break;
for ( j = 0; j < 3; j++ )
{
p->org[ j ] = v_origin[ j ] + gEngfuncs.pfnRandomFloat( -32.0, 32.0 );;
p->vel[ j ] = gEngfuncs.pfnRandomFloat( -100.0, 100.0 );
}
if ( color )
{
sscanf( color->string, "%i %i %i", &r, &g, &b );
}
else
{
r = 192;
g = 0;
b = 0;
}
p->color = gEngfuncs.pEfxAPI->R_LookupColor( r, g, b );
gEngfuncs.pEfxAPI->R_GetPackedColor( &p->packedColor, p->color );
// p->die is set to current time so all you have to do is add an additional time to it
p->die += 3.0;
}
}
*/
/*
void TempEntCallback ( struct tempent_s *ent, float frametime, float currenttime )
{
int i;
for ( i = 0; i < 3; i++ )
{
ent->entity.curstate.origin[ i ] += ent->entity.baseline.origin[ i ] * frametime;
}
}
void TempEnts( void )
{
static float lasttime;
float curtime;
curtime = gEngfuncs.GetClientTime();
if ( ( curtime - lasttime ) < 10.0 )
return;
lasttime = curtime;
TEMPENTITY *p;
int i, j;
struct model_s *mod;
vec3_t origin;
int index;
mod = gEngfuncs.CL_LoadModel( "sprites/laserdot.spr", &index );
for ( i = 0; i < 100; i++ )
{
for ( j = 0; j < 3; j++ )
{
origin[ j ] = v_origin[ j ];
if ( j != 2 )
{
origin[ j ] += 75;
}
}
p = gEngfuncs.pEfxAPI->CL_TentEntAllocCustom( (float *)&origin, mod, 0, TempEntCallback );
if ( !p )
break;
for ( j = 0; j < 3; j++ )
{
p->entity.curstate.origin[ j ] = origin[ j ];
// Store velocity in baseline origin
p->entity.baseline.origin[ j ] = gEngfuncs.pfnRandomFloat( -100, 100 );
}
// p->die is set to current time so all you have to do is add an additional time to it
p->die += 10.0;
}
}
*/
#if defined( BEAM_TEST )
// Note can't index beam[ 0 ] in Beam callback, so don't use that index
// Room for 1 beam ( 0 can't be used )
@ -511,37 +304,26 @@ HUD_CreateEntities
Gives us a chance to add additional entities to the render this frame
=========================
*/
void DLLEXPORT HUD_CreateEntities( void )
void CL_DLLEXPORT HUD_CreateEntities( void )
{
// e.g., create a persistent cl_entity_t somewhere.
// Load an appropriate model into it ( gEngfuncs.CL_LoadModel )
// Call gEngfuncs.CL_CreateVisibleEntity to add it to the visedicts list
/*
#if defined( TEST_IT )
MoveModel();
#endif
#if defined( TRACE_TEST )
TraceModel();
#endif
*/
/*
Particles();
*/
/*
TempEnts();
*/
// RecClCreateEntities();
#if defined( BEAM_TEST )
Beams();
#endif
Bench_AddObjects();
// Add in any game specific objects
Game_AddObjects();
GetClientVoiceMgr()->CreateEntities();
}
#if defined( _TFC )
extern int g_bACSpinning[33];
#endif
/*
=========================
HUD_StudioEvent
@ -550,21 +332,36 @@ The entity's studio model description indicated an event was
fired during this frame, handle the event by it's tag ( e.g., muzzleflash, sound )
=========================
*/
void DLLEXPORT HUD_StudioEvent( const struct mstudioevent_s *event, const struct cl_entity_s *entity )
void CL_DLLEXPORT HUD_StudioEvent( const struct mstudioevent_s *event, const struct cl_entity_s *entity )
{
// RecClStudioEvent(event, entity);
int iMuzzleFlash = 1;
#if defined( _TFC )
if ( g_bACSpinning[ entity->index - 1 ] )
iMuzzleFlash = 0;
#endif
switch( event->event )
{
case 5001:
gEngfuncs.pEfxAPI->R_MuzzleFlash( (float *)&entity->attachment[0], atoi( event->options) );
if ( iMuzzleFlash )
gEngfuncs.pEfxAPI->R_MuzzleFlash( (float *)&entity->attachment[0], atoi( event->options) );
break;
case 5011:
gEngfuncs.pEfxAPI->R_MuzzleFlash( (float *)&entity->attachment[1], atoi( event->options) );
if ( iMuzzleFlash )
gEngfuncs.pEfxAPI->R_MuzzleFlash( (float *)&entity->attachment[1], atoi( event->options) );
break;
case 5021:
gEngfuncs.pEfxAPI->R_MuzzleFlash( (float *)&entity->attachment[2], atoi( event->options) );
if ( iMuzzleFlash )
gEngfuncs.pEfxAPI->R_MuzzleFlash( (float *)&entity->attachment[2], atoi( event->options) );
break;
case 5031:
gEngfuncs.pEfxAPI->R_MuzzleFlash( (float *)&entity->attachment[3], atoi( event->options) );
if ( iMuzzleFlash )
gEngfuncs.pEfxAPI->R_MuzzleFlash( (float *)&entity->attachment[3], atoi( event->options) );
break;
case 5002:
gEngfuncs.pEfxAPI->R_SparkEffect( (float *)&entity->attachment[0], atoi( event->options), -100, 100 );
@ -585,7 +382,7 @@ CL_UpdateTEnts
Simulation and cleanup of temporary entities
=================
*/
void DLLEXPORT HUD_TempEntUpdate (
void CL_DLLEXPORT HUD_TempEntUpdate (
double frametime, // Simulation time
double client_time, // Absolute time on client
double cl_gravity, // True gravity on client
@ -594,11 +391,20 @@ void DLLEXPORT HUD_TempEntUpdate (
int ( *Callback_AddVisibleEntity )( cl_entity_t *pEntity ),
void ( *Callback_TempEntPlaySound )( TEMPENTITY *pTemp, float damp ) )
{
// RecClTempEntUpdate(frametime, client_time, cl_gravity, ppTempEntFree, ppTempEntActive, Callback_AddVisibleEntity, Callback_TempEntPlaySound);
static int gTempEntFrame = 0;
int i;
TEMPENTITY *pTemp, *pnext, *pprev;
float freq, gravity, gravitySlow, life, fastFreq;
Vector vAngles;
gEngfuncs.GetViewAngles( (float*)vAngles );
if ( g_pParticleMan )
g_pParticleMan->SetVariables( cl_gravity, vAngles );
// Nothing to simulate
if ( !*ppTempEntActive )
return;
@ -957,8 +763,10 @@ If you specify negative numbers for beam start and end point entities, then
Indices must start at 1, not zero.
=================
*/
cl_entity_t DLLEXPORT *HUD_GetUserEntity( int index )
cl_entity_t CL_DLLEXPORT *HUD_GetUserEntity( int index )
{
// RecClGetUserEntity(index);
#if defined( BEAM_TEST )
// None by default, you would return a valic pointer if you create a client side
// beam and attach it to a client side entity.

View file

@ -202,4 +202,4 @@ void EV_MuzzleFlash( void )
// Or in the muzzle flash
ent->curstate.effects |= EF_MUZZLEFLASH;
}
}

View file

@ -39,7 +39,10 @@ extern engine_studio_api_t IEngineStudio;
static int tracerCount[ 32 ];
extern "C" char PM_FindTextureType( char *name );
extern "C"
{
#include "pm_shared.h"
}
void V_PunchAxis( int axis, float punch );
void VectorAngles( const float *forward, float *angles );
@ -86,6 +89,7 @@ void EV_TrainPitchAdjust( struct event_args_s *args );
#define VECTOR_CONE_15DEGREES Vector( 0.13053, 0.13053, 0.13053 )
#define VECTOR_CONE_20DEGREES Vector( 0.17365, 0.17365, 0.17365 )
// play a strike sound based on the texture that was hit by the attack traceline. VecSrc/VecEnd are the
// original traceline endpoints used by the attacker, iBulletType is the type of bullet that hit the texture.
// returns volume of strike instrument (crowbar) to play

View file

@ -68,14 +68,10 @@ int CHudGeiger::Draw (float flTime)
int rg[3];
int i;
if (m_iGeigerRange < 1000 && m_iGeigerRange > 0)
if (m_iGeigerRange <= 800 && m_iGeigerRange > 0)
{
// peicewise linear is better than continuous formula for this
if (m_iGeigerRange > 800)
{
pct = 0; //Con_Printf ( "range > 800\n");
}
else if (m_iGeigerRange > 600)
if (m_iGeigerRange > 600)
{
pct = 2;
flvol = 0.4; //Con_Printf ( "range > 600\n");

30
cl_dll/global_consts.h Normal file
View file

@ -0,0 +1,30 @@
//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================
#ifndef GLOBALCONSTS_H
#define GLOBALCONSTS_H
#ifdef _WIN32
#pragma once
#endif
enum
{
MAX_PLAYERS = 64,
MAX_TEAMS = 64,
MAX_TEAM_NAME = 16,
};
#define MAX_SCORES 10
#define MAX_SCOREBOARD_TEAMS 5
#define NUM_ROWS (MAX_PLAYERS + (MAX_SCOREBOARD_TEAMS * 2))
#define MAX_SERVERNAME_LENGTH 64
#define MAX_TEAMNAME_SIZE 32
#endif // GLOBALCONSTS_H

View file

@ -18,9 +18,9 @@
// implementation of CHudHealth class
//
#include "STDIO.H"
#include "STDLIB.H"
#include "MATH.H"
#include "stdio.h"
#include "stdlib.h"
#include "math.h"
#include "hud.h"
#include "cl_util.h"
@ -379,7 +379,8 @@ int CHudHealth::DrawDamage(float flTime)
ScaleColors(r, g, b, a);
// Draw all the items
for (int i = 0; i < NUM_DMG_TYPES; i++)
int i;
for ( i = 0; i < NUM_DMG_TYPES; i++)
{
if (m_bitsDamage & giDmgFlags[i])
{

View file

@ -314,6 +314,7 @@ int CBasePlayerItem::Restore( class CRestore & ) { return 1; }
int CBasePlayerItem::Save( class CSave & ) { return 1; }
int CBasePlayerWeapon::Restore( class CRestore & ) { return 1; }
int CBasePlayerWeapon::Save( class CSave & ) { return 1; }
float CBasePlayerWeapon::GetNextAttackDelay( float flTime ) { return flTime; }
void CBasePlayerItem :: SetObjectCollisionBox( void ) { }
void CBasePlayerItem :: FallInit( void ) { }
void CBasePlayerItem::FallThink ( void ) { }

View file

@ -563,22 +563,6 @@ void UTIL_ParticleLine( CBasePlayer *player, float *start, float *end, float lif
gEngfuncs.pEfxAPI->R_ParticleLine( start, end, r, g, b, life );
}
/*
=====================
CBasePlayerWeapon::PrintState
For debugging, print out state variables to log file
=====================
*/
void CBasePlayerWeapon::PrintState( void )
{
COM_Log( "c:\\hl.log", "%.4f ", gpGlobals->time );
COM_Log( "c:\\hl.log", "%.4f ", m_pPlayer->m_flNextAttack );
COM_Log( "c:\\hl.log", "%.4f ", m_flNextPrimaryAttack );
COM_Log( "c:\\hl.log", "%.4f ", m_flTimeWeaponIdle - gpGlobals->time);
COM_Log( "c:\\hl.log", "%i ", m_iClip );
}
/*
=====================
HUD_InitClientWeapons
@ -867,7 +851,7 @@ void HUD_WeaponsPostThink( local_state_s *from, local_state_s *to, usercmd_t *cm
( ( CRpg * )player.m_pActiveItem)->m_cActiveRockets = (int)from->client.vuser2[ 2 ];
}
// Don't go firing anything if we have died.
// Don't go firing anything if we have died or are spectating
// Or if we don't have a weapon model deployed
if ( ( player.pev->deadflag != ( DEAD_DISCARDBODY + 1 ) ) &&
!CL_IsDead() && player.pev->viewmodel && !g_iUser1 )
@ -1067,8 +1051,10 @@ runfuncs is 1 if this is the first time we've predicted this command. If so, so
be ignored
=====================
*/
void _DLLEXPORT HUD_PostRunCmd( struct local_state_s *from, struct local_state_s *to, struct usercmd_s *cmd, int runfuncs, double time, unsigned int random_seed )
void CL_DLLEXPORT HUD_PostRunCmd( struct local_state_s *from, struct local_state_s *to, struct usercmd_s *cmd, int runfuncs, double time, unsigned int random_seed )
{
// RecClPostRunCmd(from, to, cmd, runfuncs, time, random_seed);
g_runfuncs = runfuncs;
#if defined( CLIENT_WEAPONS )

View file

@ -29,9 +29,10 @@
#include "demo.h"
#include "demo_api.h"
#include "vgui_scorepanel.h"
#include "vgui_ScorePanel.h"
hud_player_info_t g_PlayerInfoList[MAX_PLAYERS+1]; // player info from the engine
extra_player_info_t g_PlayerExtraInfo[MAX_PLAYERS+1]; // additional player info sent directly to the client dll
class CHLVoiceStatusHelper : public IVoiceStatusHelper
{
@ -258,13 +259,27 @@ int __MsgFunc_Spectator(const char *pszName, int iSize, void *pbuf)
return 0;
}
int __MsgFunc_SpecFade(const char *pszName, int iSize, void *pbuf)
{
if (gViewPort)
return gViewPort->MsgFunc_SpecFade( pszName, iSize, pbuf );
return 0;
}
int __MsgFunc_ResetFade(const char *pszName, int iSize, void *pbuf)
{
if (gViewPort)
return gViewPort->MsgFunc_ResetFade( pszName, iSize, pbuf );
return 0;
}
int __MsgFunc_AllowSpec(const char *pszName, int iSize, void *pbuf)
{
if (gViewPort)
return gViewPort->MsgFunc_AllowSpec( pszName, iSize, pbuf );
return 0;
}
// This is called every time the DLL is loaded
void CHud :: Init( void )
{
@ -297,6 +312,9 @@ void CHud :: Init( void )
HOOK_MESSAGE( Spectator );
HOOK_MESSAGE( AllowSpec );
HOOK_MESSAGE( SpecFade );
HOOK_MESSAGE( ResetFade );
// VGUI Menus
HOOK_MESSAGE( VGUIMenu );
@ -423,7 +441,8 @@ void CHud :: VidInit( void )
// count the number of sprites of the appropriate res
m_iSpriteCount = 0;
client_sprite_t *p = m_pSpriteList;
for ( int j = 0; j < m_iSpriteCountAllRes; j++ )
int j;
for ( j = 0; j < m_iSpriteCountAllRes; j++ )
{
if ( p->iRes == m_iRes )
m_iSpriteCount++;

View file

@ -1,6 +1,6 @@
/***
*
* Copyright (c) 1996-2002, Valve LLC. All rights reserved.
* Copyright (c) 1999, Valve LLC. All rights reserved.
*
* This product contains software technology licensed from Id
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
@ -25,6 +25,10 @@
#define RGB_REDISH 0x00FF1010 //255,160,0
#define RGB_GREENISH 0x0000A000 //0,160,0
#ifndef _WIN32
#define _cdecl
#endif
#include "wrect.h"
#include "cl_dll.h"
#include "ammo.h"
@ -40,12 +44,7 @@ typedef struct {
int x, y;
} POSITION;
enum
{
MAX_PLAYERS = 64,
MAX_TEAMS = 64,
MAX_TEAM_NAME = 16,
};
#include "global_consts.h"
typedef struct {
unsigned char r,g,b,a;
@ -90,7 +89,7 @@ struct HUDLIST {
//
//-----------------------------------------------------
//
#include "..\game_shared\voice_status.h"
#include "voice_status.h" // base voice handling class
#include "hud_spectator.h"
@ -203,30 +202,6 @@ private:
};
//
//-----------------------------------------------------
//
// REMOVED: Vgui has replaced this.
//
/*
class CHudMOTD : public CHudBase
{
public:
int Init( void );
int VidInit( void );
int Draw( float flTime );
void Reset( void );
int MsgFunc_MOTD( const char *pszName, int iSize, void *pbuf );
protected:
static int MOTD_DISPLAY_TIME;
char m_szMOTD[ MAX_MOTD_LENGTH ];
float m_flActiveRemaining;
int m_iLines;
};
*/
//
//-----------------------------------------------------
//
@ -246,7 +221,7 @@ protected:
enum {
MAX_STATUSTEXT_LENGTH = 128,
MAX_STATUSBAR_VALUES = 8,
MAX_STATUSBAR_LINES = 2,
MAX_STATUSBAR_LINES = 3,
};
char m_szStatusText[MAX_STATUSBAR_LINES][MAX_STATUSTEXT_LENGTH]; // a text string describing how the status bar is to be drawn
@ -259,46 +234,13 @@ protected:
float *m_pflNameColors[MAX_STATUSBAR_LINES];
};
//
//-----------------------------------------------------
//
// REMOVED: Vgui has replaced this.
//
/*
class CHudScoreboard: public CHudBase
{
public:
int Init( void );
void InitHUDData( void );
int VidInit( void );
int Draw( float flTime );
int DrawPlayers( int xoffset, float listslot, int nameoffset = 0, char *team = NULL ); // returns the ypos where it finishes drawing
void UserCmd_ShowScores( void );
void UserCmd_HideScores( void );
int MsgFunc_ScoreInfo( const char *pszName, int iSize, void *pbuf );
int MsgFunc_TeamInfo( const char *pszName, int iSize, void *pbuf );
int MsgFunc_TeamScore( const char *pszName, int iSize, void *pbuf );
void DeathMsg( int killer, int victim );
int m_iNumTeams;
int m_iLastKilledBy;
int m_fLastKillTime;
int m_iPlayerNum;
int m_iShowscoresHeld;
void GetAllPlayersInfo( void );
private:
struct cvar_s *cl_showpacketloss;
};
*/
struct extra_player_info_t
{
short frags;
short deaths;
short playerclass;
short health; // UNUSED currently, spectator UI would like this
bool dead; // UNUSED currently, spectator UI would like this
short teamnumber;
char teamname[MAX_TEAM_NAME];
};
@ -317,11 +259,7 @@ struct team_info_t
int teamnumber;
};
extern hud_player_info_t g_PlayerInfoList[MAX_PLAYERS+1]; // player info from the engine
extern extra_player_info_t g_PlayerExtraInfo[MAX_PLAYERS+1]; // additional player info sent directly to the client dll
extern team_info_t g_TeamInfo[MAX_TEAMS+1];
extern int g_IsSpectator[MAX_PLAYERS+1];
#include "player_info.h"
//
//-----------------------------------------------------
@ -398,6 +336,7 @@ private:
wrect_t *m_prc1;
wrect_t *m_prc2;
int m_iBat;
int m_iBatMax;
float m_fFade;
int m_iHeight; // width of the battery innards
};
@ -476,6 +415,7 @@ public:
int VidInit( void );
int Draw(float flTime);
int MsgFunc_HudText(const char *pszName, int iSize, void *pbuf);
int MsgFunc_HudTextPro(const char *pszName, int iSize, void *pbuf);
int MsgFunc_GameTitle(const char *pszName, int iSize, void *pbuf);
float FadeBlend( float fadein, float fadeout, float hold, float localTime );
@ -542,7 +482,60 @@ private:
//
//-----------------------------------------------------
//
class CHudBenchmark : public CHudBase
{
public:
int Init( void );
int VidInit( void );
int Draw( float flTime );
void SetScore( float score );
void Think( void );
void StartNextSection( int section );
int MsgFunc_Bench(const char *pszName, int iSize, void *pbuf);
void CountFrame( float dt );
int GetObjects( void ) { return m_nObjects; };
void SetCompositeScore( void );
void Restart( void );
int Bench_ScoreForValue( int stage, float raw );
private:
float m_fDrawTime;
float m_fDrawScore;
float m_fAvgScore;
float m_fSendTime;
float m_fReceiveTime;
int m_nFPSCount;
float m_fAverageFT;
float m_fAvgFrameRate;
int m_nSentFinish;
float m_fStageStarted;
float m_StoredLatency;
float m_StoredPacketLoss;
int m_nStoredHopCount;
int m_nTraceDone;
int m_nObjects;
int m_nScoreComputed;
int m_nCompositeScore;
};
//
//-----------------------------------------------------
//
class CHud
@ -617,6 +610,7 @@ public:
CHudAmmoSecondary m_AmmoSecondary;
CHudTextMessage m_TextMessage;
CHudStatusIcons m_StatusIcons;
CHudBenchmark m_Benchmark;
void Init( void );
void VidInit( void );
@ -654,10 +648,7 @@ public:
};
class TeamFortressViewport;
extern CHud gHUD;
extern TeamFortressViewport *gViewPort;
extern int g_iPlayerClass;
extern int g_iTeamNumber;

1129
cl_dll/hud_bench.cpp Normal file

File diff suppressed because it is too large Load diff

236
cl_dll/hud_benchtrace.cpp Normal file
View file

@ -0,0 +1,236 @@
// hud_benchtrace.cpp
// Functions for spawning a thread to get a hopcount to a particular ip address and returning the result in a specified
// variable
#ifdef _WIN32
#include "winsani_in.h"
#include <windows.h>
#include "winsani_out.h"
#else
#include "port.h"
#include <dlfcn.h>
#endif
// For tracking the trace threads
typedef struct
{
// Inputs
char server[ 256 ];
// Outputs
int *p_nresults;
int *p_ndone;
// Local variables
DWORD hThreadId;
HANDLE hThread;
HANDLE hEventDone;
} trace_params_t;
// Static forces it to be zeroed out
static trace_params_t tp;
// For doing the actual traceroute
struct trace_options_s
{
unsigned char ucTTL;
unsigned char a[7];
};
struct
{
DWORD dwAddress;
unsigned long ulStatus, ulRoundTripTime;
unsigned char a[8];
struct trace_options_s Options;
} traceReturn;
/*
==============
Trace_GetHopCount
Performs a synchronous hopcount on the specified server
==============
*/
int Trace_GetHopCount( char *pServer, int nMaxHops )
{
#ifdef _WIN32
HMODULE hICMP; // Handle to ICMP .dll
HANDLE hIP; // Handle to icmp session
DWORD *dwIPAddr; // remote IP Address as a DWORD
struct hostent *pHostEnt; // Name of remote host
struct trace_options_s traceOptions; // Input options
int c; // Hop counter
// Prototypes
HANDLE ( WINAPI *pfnICMPCreateFile ) ( VOID );
BOOL ( WINAPI *pfnICMPCloseFile ) ( HANDLE );
DWORD (WINAPI *pfnICMPSendEcho) ( HANDLE, DWORD, LPVOID, WORD, LPVOID, LPVOID, DWORD, DWORD );
hICMP = ::LoadLibrary( "ICMP.DLL" );
pfnICMPCreateFile = ( HANDLE ( WINAPI *)(VOID ) )::GetProcAddress( hICMP,"IcmpCreateFile");
pfnICMPCloseFile = ( BOOL ( WINAPI *) ( HANDLE ) )::GetProcAddress( hICMP,"IcmpCloseHandle");
pfnICMPSendEcho = ( DWORD ( WINAPI * ) ( HANDLE, DWORD, LPVOID, WORD, LPVOID, LPVOID, DWORD,DWORD ) )::GetProcAddress( hICMP,"IcmpSendEcho" );
if ( !pfnICMPCreateFile ||
!pfnICMPCloseFile ||
!pfnICMPSendEcho )
{
return -1;
}
hIP = pfnICMPCreateFile();
if ( !hIP )
{
return -1;
}
// DNS lookup on remote host
pHostEnt = gethostbyname( pServer );
if ( !pHostEnt )
{
return -1;
}
// Take first IP address returned
dwIPAddr = ( DWORD * )( *pHostEnt->h_addr_list );
// Fixme: If not tracing, can use a "binary search" method to do the trace route
for ( c = 1; c <= nMaxHops ; c++)
{
// Set TTL correctly
traceOptions.ucTTL = (unsigned char)c;
// Clear out return structure
memset( &traceReturn, 0, sizeof( traceReturn ) );
// Send echo request, 2000 milliseconds maximum waiting time
pfnICMPSendEcho ( hIP, *dwIPAddr, 0, 0, &traceOptions, &traceReturn, sizeof(traceReturn), 2000 );
// Found requrested remote address, c contains the correct hopcount
if ( traceReturn.dwAddress == *dwIPAddr )
break;
}
/*
// This is how you do a raw ping
npings = 1;
pfnICMPSendEcho( hIP, *dwIPAddr, 0, 0, NULL, &E, sizeof( E ), 2000 );
*ping = (double)E.RoundTripTime / 1000.0;
*/
// Clean up file and dll handles
pfnICMPCloseFile( hIP );
::FreeLibrary( hICMP );
// Failure?
if ( c > nMaxHops )
{
return -1;
}
return c;
#else
return -1;
#endif
}
/*
==============
Trace_Cleanup
Destroys thread and event handle when trace is done, or when restarting a new trace
==============
*/
void Trace_Cleanup( void )
{
#ifdef _WIN32
if ( tp.hThread )
{
TerminateThread( tp.hThread, 0 );
CloseHandle( tp.hThread );
tp.hThread = (HANDLE)0;
}
if ( tp.hEventDone )
{
CloseHandle( tp.hEventDone );
tp.hEventDone = (HANDLE)0;
}
#endif
}
#ifdef _WIN32
/*
==============
Trace_ThreadFunction
Performs a trace, sets finish event and exits
==============
*/
DWORD WINAPI Trace_ThreadFunction( LPVOID p )
{
int *results;
results = ( int * )p;
*results = Trace_GetHopCount( tp.server, 30 );
SetEvent( tp.hEventDone );
return 0;
}
#endif
/*
==============
Trace_StartTrace
Create finish event, sets up data, and starts thread to do a traceroute.
==============
*/
void Trace_StartTrace( int *results, int *finished, const char *server )
{
#ifdef _WIN32
tp.p_nresults = results;
strcpy( tp.server, server );
*results = -1;
Trace_Cleanup();
tp.hEventDone = CreateEvent( NULL, TRUE, FALSE, NULL );
if ( !tp.hEventDone )
{
return;
}
tp.p_ndone = finished;
*tp.p_ndone = 0;
tp.hThread = CreateThread( NULL, 0, Trace_ThreadFunction, results, 0, &tp.hThreadId );
#endif
}
/*
==============
Trace_Think
Invoked by general frame loop on client to periodically check if the traceroute thread has completed.
==============
*/
void Trace_Think( void )
{
#ifdef _WIN32
if ( !tp.hEventDone )
return;
if ( WaitForSingleObject( tp.hEventDone, 0 ) == WAIT_OBJECT_0 )
{
Trace_Cleanup();
*tp.p_ndone = 1;
}
#endif
}

8
cl_dll/hud_benchtrace.h Normal file
View file

@ -0,0 +1,8 @@
#if !defined( HUD_BENCHTRACEH )
#define HUD_BENCHTRACEH
#pragma once
void Trace_StartTrace( int *results, int *finished, const char *pszServer );
void Trace_Think( void );
#endif // !HUD_BENCHTRACEH

View file

@ -9,9 +9,6 @@
#define HUD_IFACEH
#pragma once
#define EXPORT _declspec( dllexport )
#define _DLLEXPORT __declspec( dllexport )
typedef int (*pfnUserMsgHook)(const char *pszName, int iSize, void *pbuf);
#include "wrect.h"
#include "../engine/cdll_int.h"

View file

@ -1,6 +1,6 @@
/***
*
* Copyright (c) 1996-2002, Valve LLC. All rights reserved.
* Copyright (c) 1999, Valve LLC. All rights reserved.
*
* This product contains software technology licensed from Id
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
@ -21,10 +21,19 @@
#include "parsemsg.h"
#include "r_efx.h"
#include "particleman.h"
extern IParticleMan *g_pParticleMan;
#define MAX_CLIENTS 32
#if !defined( _TFC )
extern BEAM *pBeam;
extern BEAM *pBeam2;
#endif
#if defined( _TFC )
void ClearEventList( void );
#endif
/// USER-DEFINED SERVER MESSAGE HANDLERS
@ -70,8 +79,20 @@ void CHud :: MsgFunc_InitHUD( const char *pszName, int iSize, void *pbuf )
pList = pList->pNext;
}
#if defined( _TFC )
ClearEventList();
// catch up on any building events that are going on
gEngfuncs.pfnServerCmd("sendevents");
#endif
if ( g_pParticleMan )
g_pParticleMan->ResetParticles();
#if !defined( _TFC )
//Probably not a good place to put this.
pBeam = pBeam2 = NULL;
#endif
}

View file

@ -1,6 +1,6 @@
/***
*
* Copyright (c) 1996-2002, Valve LLC. All rights reserved.
* Copyright (c) 1999, Valve LLC. All rights reserved.
*
* This product contains software technology licensed from Id
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
@ -18,6 +18,7 @@
#include <math.h>
#include "hud.h"
#include "cl_util.h"
#include "bench.h"
#include "vgui_TeamFortressViewport.h"
@ -40,6 +41,9 @@ extern cvar_t *sensitivity;
// Think
void CHud::Think(void)
{
m_scrinfo.iSize = sizeof(m_scrinfo);
GetScreenInfo(&m_scrinfo);
int newfov;
HUDLIST *pList = m_pHudList;
@ -79,6 +83,13 @@ void CHud::Think(void)
{ // only let players adjust up in fov, and only if they are not overriden by something else
m_iFOV = max( default_fov->value, 90 );
}
if ( gEngfuncs.IsSpectateOnly() )
{
m_iFOV = gHUD.m_Spectator.GetFOV(); // default_fov->value;
}
Bench_CheckStart();
}
// Redraw
@ -89,7 +100,7 @@ int CHud :: Redraw( float flTime, int intermission )
m_fOldTime = m_flTime; // save time of previous redraw
m_flTime = flTime;
m_flTimeDelta = (double)m_flTime - m_fOldTime;
static m_flShotTime = 0;
static float m_flShotTime = 0;
// Clock was reset, reset delta
if ( m_flTimeDelta < 0 )
@ -131,21 +142,34 @@ int CHud :: Redraw( float flTime, int intermission )
// if no redrawing is necessary
// return 0;
// draw all registered HUD elements
if ( m_pCvarDraw->value )
{
HUDLIST *pList = m_pHudList;
while (pList)
{
if ( !intermission )
if ( !Bench_Active() )
{
if ( (pList->p->m_iFlags & HUD_ACTIVE) && !(m_iHideHUDDisplay & HIDEHUD_ALL) )
pList->p->Draw(flTime);
if ( !intermission )
{
if ( (pList->p->m_iFlags & HUD_ACTIVE) && !(m_iHideHUDDisplay & HIDEHUD_ALL) )
pList->p->Draw(flTime);
}
else
{ // it's an intermission, so only draw hud elements that are set to draw during intermissions
if ( pList->p->m_iFlags & HUD_INTERMISSION )
pList->p->Draw( flTime );
}
}
else
{ // it's an intermission, so only draw hud elements that are set to draw during intermissions
if ( pList->p->m_iFlags & HUD_INTERMISSION )
pList->p->Draw( flTime );
{
if ( ( pList->p == &m_Benchmark ) &&
( pList->p->m_iFlags & HUD_ACTIVE ) &&
!( m_iHideHUDDisplay & HIDEHUD_ALL ) )
{
pList->p->Draw(flTime);
}
}
pList = pList->pNext;
@ -208,18 +232,7 @@ void ScaleColors( int &r, int &g, int &b, int a )
int CHud :: DrawHudString(int xpos, int ypos, int iMaxX, char *szIt, int r, int g, int b )
{
// draw the string until we hit the null character or a newline character
for ( ; *szIt != 0 && *szIt != '\n'; szIt++ )
{
int next = xpos + gHUD.m_scrinfo.charWidths[ *szIt ]; // variable-width fonts look cool
if ( next > iMaxX )
return xpos;
TextMessageDrawChar( xpos, ypos, *szIt, r, g, b );
xpos = next;
}
return xpos;
return xpos + gEngfuncs.pfnDrawString( xpos, ypos, szIt, r, g, b);
}
int CHud :: DrawHudNumberString( int xpos, int ypos, int iMinX, int iNumber, int r, int g, int b )
@ -233,23 +246,7 @@ int CHud :: DrawHudNumberString( int xpos, int ypos, int iMinX, int iNumber, int
// draws a string from right to left (right-aligned)
int CHud :: DrawHudStringReverse( int xpos, int ypos, int iMinX, char *szString, int r, int g, int b )
{
// find the end of the string
for ( char *szIt = szString; *szIt != 0; szIt++ )
{ // we should count the length?
}
// iterate throug the string in reverse
for ( szIt--; szIt != (szString-1); szIt-- )
{
int next = xpos - gHUD.m_scrinfo.charWidths[ *szIt ]; // variable-width fonts look cool
if ( next < iMinX )
return xpos;
xpos = next;
TextMessageDrawChar( xpos, ypos, *szIt, r, g, b );
}
return xpos;
return xpos - gEngfuncs.pfnDrawStringReverse( xpos, ypos, szString, r, g, b);
}
int CHud :: DrawHudNumber( int x, int y, int iFlags, int iNumber, int r, int g, int b)

View file

@ -12,17 +12,23 @@
#include "hud_servers.h"
#include "net_api.h"
#include <string.h>
#ifdef _WIN32
#include "winsani_in.h"
#include <winsock.h>
#include "winsani_out.h"
#else
#define __cdecl
#include <arpa/inet.h>
#endif
static int context_id;
// Default master server address in case we can't read any from woncomm.lst file
// Default master server address in case we can't read any from valvecomm.lst file
#define VALVE_MASTER_ADDRESS "half-life.east.won.net"
#define PORT_MASTER 27010
#define PORT_SERVER 27015
// File where we really should look for master servers
#define MASTER_PARSE_FILE "woncomm.lst"
#define MASTER_PARSE_FILE "valvecomm.lst"
#define MAX_QUERIES 20
@ -599,7 +605,7 @@ int CompareField( CHudServers::server_t *p1, CHudServers::server_t *p2, const ch
return stricmp( sz1, sz2 );
}
int CALLBACK ServerListCompareFunc( CHudServers::server_t *p1, CHudServers::server_t *p2, const char *fieldname )
int ServerListCompareFunc( CHudServers::server_t *p1, CHudServers::server_t *p2, const char *fieldname )
{
if (!p1 || !p2) // No meaningful comparison
return 0;
@ -1227,4 +1233,4 @@ void ServerPlayers( int server )
{
g_pServers->ServerPlayers( server );
}
}
}

View file

@ -1,4 +1,4 @@
//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============
//========= Copyright © 1996-2001, Valve LLC, All rights reserved. ============
//
// Purpose:
//
@ -37,8 +37,6 @@ extern "C" float vJumpAngles[3];
extern void V_GetInEyePos(int entity, float * origin, float * angles );
extern void V_ResetChaseCam();
extern void V_GetChasePos(int target, float * cl_angles, float * origin, float * angles);
extern void VectorAngles( const float *forward, float *angles );
extern "C" void NormalizeAngles( float *angles );
extern float * GetClientColor( int clientIndex );
extern vec3_t v_origin; // last view origin
@ -46,6 +44,37 @@ extern vec3_t v_angles; // last view angle
extern vec3_t v_cl_angles; // last client/mouse angle
extern vec3_t v_sim_org; // last sim origin
#if 0
const char *GetSpectatorLabel ( int iMode )
{
switch ( iMode )
{
case OBS_CHASE_LOCKED:
return "#OBS_CHASE_LOCKED";
case OBS_CHASE_FREE:
return "#OBS_CHASE_FREE";
case OBS_ROAMING:
return "#OBS_ROAMING";
case OBS_IN_EYE:
return "#OBS_IN_EYE";
case OBS_MAP_FREE:
return "#OBS_MAP_FREE";
case OBS_MAP_CHASE:
return "#OBS_MAP_CHASE";
case OBS_NONE:
default:
return "#OBS_NONE";
}
}
#endif
void SpectatorMode(void)
{
@ -142,6 +171,7 @@ int CHudSpectator::Init()
m_flNextObserverInput = 0.0f;
m_zoomDelta = 0.0f;
m_moveDelta = 0.0f;
m_FOV = 90.0f;
m_chatEnabled = (gHUD.m_SayText.m_HUD_saytext->value!=0);
iJumpSpectator = 0;
@ -359,6 +389,182 @@ void CHudSpectator::SetSpectatorStartPosition()
iJumpSpectator = 1; // jump anyway
}
void CHudSpectator::SetCameraView( vec3_t pos, vec3_t angle, float fov)
{
m_FOV = fov;
VectorCopy(pos, vJumpOrigin);
VectorCopy(angle, vJumpAngles);
gEngfuncs.SetViewAngles( vJumpAngles );
iJumpSpectator = 1; // jump anyway
}
void CHudSpectator::AddWaypoint( float time, vec3_t pos, vec3_t angle, float fov, int flags )
{
if ( !flags == 0 && time == 0.0f)
{
// switch instantly to this camera view
SetCameraView( pos, angle, fov );
return;
}
if ( m_NumWayPoints >= MAX_CAM_WAYPOINTS )
{
gEngfuncs.Con_Printf( "Too many camera waypoints!\n" );
return;
}
VectorCopy( angle, m_CamPath[ m_NumWayPoints ].angle );
VectorCopy( pos, m_CamPath[ m_NumWayPoints ].position );
m_CamPath[ m_NumWayPoints ].flags = flags;
m_CamPath[ m_NumWayPoints ].fov = fov;
m_CamPath[ m_NumWayPoints ].time = time;
gEngfuncs.Con_DPrintf("Added waypoint %i\n", m_NumWayPoints );
m_NumWayPoints++;
}
void CHudSpectator::SetWayInterpolation(cameraWayPoint_t * prev, cameraWayPoint_t * start, cameraWayPoint_t * end, cameraWayPoint_t * next)
{
m_WayInterpolation.SetViewAngles( start->angle, end->angle );
m_WayInterpolation.SetFOVs( start->fov, end->fov );
m_WayInterpolation.SetSmoothing( ( start->flags & DRC_FLAG_SLOWSTART ) != 0,
( start->flags & DRC_FLAG_SLOWEND ) != 0);
if ( prev && next )
{
m_WayInterpolation.SetWaypoints(&prev->position, start->position, end->position, &next->position);
}
else if ( prev )
{
m_WayInterpolation.SetWaypoints(&prev->position, start->position, end->position, NULL );
}
else if ( next )
{
m_WayInterpolation.SetWaypoints(NULL, start->position, end->position, &next->position );
}
else
{
m_WayInterpolation.SetWaypoints(NULL, start->position, end->position, NULL );
}
}
bool CHudSpectator::GetDirectorCamera(vec3_t &position, vec3_t &angle)
{
float now = gHUD.m_flTime;
float fov = 90.0f;
if ( m_ChaseEntity )
{
cl_entity_t * ent = gEngfuncs.GetEntityByIndex( m_ChaseEntity );
if ( ent )
{
vec3_t vt = ent->curstate.origin;
if ( m_ChaseEntity <= gEngfuncs.GetMaxClients() )
{
if ( ent->curstate.solid == SOLID_NOT )
{
vt[2]+= -8 ; // PM_DEAD_VIEWHEIGHT
}
else if (ent->curstate.usehull == 1 )
{
vt[2]+= 12; // VEC_DUCK_VIEW;
}
else
{
vt[2]+= 28; // DEFAULT_VIEWHEIGHT
}
}
vt = vt - position;
VectorAngles(vt, angle);
angle[0] = -angle[0];
return true;
}
else
{
return false;
}
}
if ( !m_IsInterpolating )
return false;
if ( m_WayPoint < 0 || m_WayPoint >= (m_NumWayPoints-1) )
return false;
cameraWayPoint_t * wp1 = &m_CamPath[m_WayPoint];
cameraWayPoint_t * wp2 = &m_CamPath[m_WayPoint+1];
if ( now < wp1->time )
return false;
while ( now > wp2->time )
{
// go to next waypoint, if possible
m_WayPoint++;
if ( m_WayPoint >= (m_NumWayPoints-1) )
{
m_IsInterpolating = false;
return false; // there is no following waypoint
}
wp1 = wp2;
wp2 = &m_CamPath[m_WayPoint+1];
if ( m_WayPoint > 0 )
{
// we have a predecessor
if ( m_WayPoint < (m_NumWayPoints-1) )
{
// we have also a successor
SetWayInterpolation( &m_CamPath[m_WayPoint-1], wp1, wp2, &m_CamPath[m_WayPoint+2] );
}
else
{
SetWayInterpolation( &m_CamPath[m_WayPoint-1], wp1, wp2, NULL );
}
}
else if ( m_WayPoint < (m_NumWayPoints-1) )
{
// we only have a successor
SetWayInterpolation( NULL, wp1, wp2, &m_CamPath[m_WayPoint+2] );
}
else
{
// we have only two waypoints
SetWayInterpolation( NULL, wp1, wp2, NULL );
}
}
if ( wp2->time <= wp1->time )
return false;
float fraction = (now - wp1->time) / (wp2->time - wp1->time);
if ( fraction < 0.0f )
fraction = 0.0f;
else if ( fraction > 1.0f )
fraction = 1.0f;
m_WayInterpolation.Interpolate( fraction, position, angle, &fov );
// gEngfuncs.Con_Printf("Interpolate time: %.2f, fraction %.2f, point : %.2f,%.2f,%.2f\n", now, fraction, position[0], position[1], position[2] );
SetCameraView( position, angle, fov );
return true;
}
//-----------------------------------------------------------------------------
// Purpose: Loads new icons
//-----------------------------------------------------------------------------
@ -373,9 +579,21 @@ int CHudSpectator::VidInit()
m_hsprCamera = SPR_Load("sprites/camera.spr");
m_hCrosshair = SPR_Load("sprites/crosshairs.spr");
m_lastPrimaryObject = m_lastSecondaryObject = 0;
m_flNextObserverInput = 0.0f;
m_lastHudMessage = 0;
m_iSpectatorNumber = 0;
iJumpSpectator = 0;
g_iUser1 = g_iUser2 = 0;
return 1;
}
float CHudSpectator::GetFOV()
{
return m_FOV;
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : flTime -
@ -462,8 +680,10 @@ int CHudSpectator::Draw(float flTime)
void CHudSpectator::DirectorMessage( int iSize, void *pbuf )
{
float value;
float f1,f2;
char * string;
vec3_t v1,v2;
int i1,i2,i3;
BEGIN_READ( pbuf, iSize );
@ -482,7 +702,7 @@ void CHudSpectator::DirectorMessage( int iSize, void *pbuf )
break;
case DRC_CMD_EVENT :
case DRC_CMD_EVENT : // old director style message
m_lastPrimaryObject = READ_WORD();
m_lastSecondaryObject = READ_WORD();
m_iObserverFlags = READ_LONG();
@ -494,11 +714,12 @@ void CHudSpectator::DirectorMessage( int iSize, void *pbuf )
g_iUser2 = m_lastPrimaryObject;
g_iUser3 = m_lastSecondaryObject;
m_IsInterpolating = false;
m_ChaseEntity = 0;
}
// gEngfuncs.Con_Printf("Director Camera: %i %i\n", firstObject, secondObject);
break;
case DRC_CMD_MODE :
if ( m_autoDirector->value )
{
@ -506,20 +727,23 @@ void CHudSpectator::DirectorMessage( int iSize, void *pbuf )
}
break;
case DRC_CMD_CAMERA :
v1[0] = READ_COORD(); // position
v1[1] = READ_COORD();
v1[2] = READ_COORD(); // vJumpOrigin
v2[0] = READ_COORD(); // view angle
v2[1] = READ_COORD(); // vJumpAngles
v2[2] = READ_COORD();
f1 = READ_BYTE(); // fov
i1 = READ_WORD(); // target
if ( m_autoDirector->value )
{
vJumpOrigin[0] = READ_COORD(); // position
vJumpOrigin[1] = READ_COORD();
vJumpOrigin[2] = READ_COORD();
vJumpAngles[0] = READ_COORD(); // view angle
vJumpAngles[1] = READ_COORD();
vJumpAngles[2] = READ_COORD();
gEngfuncs.SetViewAngles( vJumpAngles );
iJumpSpectator = 1;
SetModes( OBS_ROAMING, -1 );
SetCameraView(v1, v2, f1);
m_ChaseEntity = i1;
}
break;
@ -560,15 +784,15 @@ void CHudSpectator::DirectorMessage( int iSize, void *pbuf )
case DRC_CMD_SOUND :
string = READ_STRING();
value = READ_FLOAT();
f1 = READ_FLOAT();
// gEngfuncs.Con_Printf("DRC_CMD_FX_SOUND: %s %.2f\n", string, value );
gEngfuncs.pEventAPI->EV_PlaySound(0, v_origin, CHAN_BODY, string, value, ATTN_NORM, 0, PITCH_NORM );
gEngfuncs.pEventAPI->EV_PlaySound(0, v_origin, CHAN_BODY, string, f1, ATTN_NORM, 0, PITCH_NORM );
break;
case DRC_CMD_TIMESCALE :
value = READ_FLOAT();
f1 = READ_FLOAT(); // ignore this command (maybe show slowmo sign)
break;
@ -587,11 +811,69 @@ void CHudSpectator::DirectorMessage( int iSize, void *pbuf )
gViewPort->UpdateSpectatorPanel();
break;
case DRC_CMD_FADE:
case DRC_CMD_STUFFTEXT:
EngineClientCmd( READ_STRING() );
break;
case DRC_CMD_STUFFTEXT:
ClientCmd( READ_STRING() );
case DRC_CMD_CAMPATH:
v1[0] = READ_COORD(); // position
v1[1] = READ_COORD();
v1[2] = READ_COORD(); // vJumpOrigin
v2[0] = READ_COORD(); // view angle
v2[1] = READ_COORD(); // vJumpAngles
v2[2] = READ_COORD();
f1 = READ_BYTE(); // FOV
i1 = READ_BYTE(); // flags
if ( m_autoDirector->value )
{
SetModes( OBS_ROAMING, -1 );
SetCameraView(v1, v2, f1);
}
break;
case DRC_CMD_WAYPOINTS :
i1 = READ_BYTE();
m_NumWayPoints = 0;
m_WayPoint = 0;
for ( i2=0; i2<i1; i2++ )
{
f1 = gHUD.m_flTime + (float)(READ_SHORT())/100.0f;
v1[0] = READ_COORD(); // position
v1[1] = READ_COORD();
v1[2] = READ_COORD(); // vJumpOrigin
v2[0] = READ_COORD(); // view angle
v2[1] = READ_COORD(); // vJumpAngles
v2[2] = READ_COORD();
f2 = READ_BYTE(); // fov
i3 = READ_BYTE(); // flags
AddWaypoint( f1, v1, v2, f2, i3);
}
// gEngfuncs.Con_Printf("CHudSpectator::DirectorMessage: waypoints %i.\n", m_NumWayPoints );
if ( !m_autoDirector->value )
{
// ignore waypoints
m_NumWayPoints = 0;
break;
}
SetModes( OBS_ROAMING, -1 );
m_IsInterpolating = true;
if ( m_NumWayPoints > 2 )
{
SetWayInterpolation( NULL, &m_CamPath[0], &m_CamPath[1], &m_CamPath[2] );
}
else
{
SetWayInterpolation( NULL, &m_CamPath[0], &m_CamPath[1], NULL );
}
break;
default : gEngfuncs.Con_DPrintf("CHudSpectator::DirectorMessage: unknown command %i.\n", cmd );
@ -667,7 +949,67 @@ void CHudSpectator::FindNextPlayer(bool bReverse)
VectorCopy ( pEnt->origin, vJumpOrigin );
VectorCopy ( pEnt->angles, vJumpAngles );
}
iJumpSpectator = 1;
gViewPort->MsgFunc_ResetFade( NULL, 0, NULL );
}
void CHudSpectator::FindPlayer(const char *name)
{
// MOD AUTHORS: Modify the logic of this function if you want to restrict the observer to watching
// only a subset of the players. e.g. Make it check the target's team.
// if we are NOT in HLTV mode, spectator targets are set on server
if ( !gEngfuncs.IsSpectateOnly() )
{
char cmdstring[32];
// forward command to server
sprintf(cmdstring,"follow %s",name);
gEngfuncs.pfnServerCmd(cmdstring);
return;
}
g_iUser2 = 0;
// make sure we have player info
gViewPort->GetAllPlayersInfo();
cl_entity_t * pEnt = NULL;
for (int i = 1; i < MAX_PLAYERS; i++ )
{
pEnt = gEngfuncs.GetEntityByIndex( i );
if ( !IsActivePlayer( pEnt ) )
continue;
if(!stricmp(g_PlayerInfoList[pEnt->index].name,name))
{
g_iUser2 = i;
break;
}
}
// Did we find a target?
if ( !g_iUser2 )
{
gEngfuncs.Con_DPrintf( "No observer targets.\n" );
// take save camera position
VectorCopy(m_cameraOrigin, vJumpOrigin);
VectorCopy(m_cameraAngles, vJumpAngles);
}
else
{
// use new entity position for roaming
VectorCopy ( pEnt->origin, vJumpOrigin );
VectorCopy ( pEnt->angles, vJumpAngles );
}
iJumpSpectator = 1;
gViewPort->MsgFunc_ResetFade( NULL, 0, NULL );
}
void CHudSpectator::HandleButtonsDown( int ButtonPressed )
@ -678,6 +1020,7 @@ void CHudSpectator::HandleButtonsDown( int ButtonPressed )
int newInsetMode = m_pip->value;
// gEngfuncs.Con_Printf(" HandleButtons:%i\n", ButtonPressed );
if ( !gViewPort )
return;
@ -743,7 +1086,7 @@ void CHudSpectator::HandleButtonsDown( int ButtonPressed )
iJumpSpectator = 1;
}
// lease directed mode if player want to see another player
// release directed mode if player wants to see another player
m_autoDirector->value = 0.0f;
}
}
@ -800,17 +1143,24 @@ void CHudSpectator::SetModes(int iNewMainMode, int iNewInsetMode)
gEngfuncs.Con_Printf("Invalid spectator mode.\n");
return;
}
m_IsInterpolating = false;
m_ChaseEntity = 0;
// main modes ettings will override inset window settings
// main mode settings will override inset window settings
if ( iNewMainMode != g_iUser1 )
{
// if we are NOT in HLTV mode, main spectator mode is set on server
if ( !gEngfuncs.IsSpectateOnly() )
{
char cmdstring[32];
// forward command to server
sprintf(cmdstring,"specmode %i",iNewMainMode );
gEngfuncs.pfnServerCmd(cmdstring);
return;
}
if ( !g_iUser2 && (iNewMainMode !=OBS_ROAMING ) ) // make sure we have a target
if ( !g_iUser2 && (iNewMainMode != OBS_ROAMING ) ) // make sure we have a target
{
// choose last Director object if still available
if ( IsActivePlayer( gEngfuncs.GetEntityByIndex( m_lastPrimaryObject ) ) )
@ -871,6 +1221,8 @@ void CHudSpectator::SetModes(int iNewMainMode, int iNewInsetMode)
SetCrosshair( 0, m_crosshairRect, 0, 0, 0 );
}
gViewPort->MsgFunc_ResetFade( NULL, 0, NULL );
char string[128];
sprintf(string, "#Spec_Mode%d", g_iUser1 );
sprintf(string, "%c%s", HUD_PRINTCENTER, CHudTextMessage::BufferedLocaliseTextString( string ));
@ -928,7 +1280,7 @@ bool CHudSpectator::ParseOverviewFile( )
if (!pfile)
{
gEngfuncs.Con_Printf("Couldn't open file %s. Using default values for overiew mode.\n", filename );
gEngfuncs.Con_DPrintf("Couldn't open file %s. Using default values for overiew mode.\n", filename );
return false;
}
@ -1076,7 +1428,7 @@ void CHudSpectator::DrawOverviewLayer()
if ( hasMapImage)
{
i = m_MapSprite->numframes / (4*3);
i = sqrt(i);
i = sqrt((float)i);
xTiles = i*4;
yTiles = i*3;
}
@ -1591,6 +1943,12 @@ void CHudSpectator::Reset()
memset( &m_OverviewEntities, 0, sizeof(m_OverviewEntities));
m_FOV = 90.0f;
m_IsInterpolating = false;
m_ChaseEntity = 0;
SetSpectatorStartPosition();
}
@ -1613,7 +1971,7 @@ void CHudSpectator::InitHUDData()
Reset();
SetModes( OBS_CHASE_FREE, INSET_OFF );
SetModes( OBS_CHASE_LOCKED, INSET_OFF );
g_iUser2 = 0; // fake not target until first camera command

View file

@ -1,4 +1,4 @@
//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============
//========= Copyright <EFBFBD> 1996-2001, Valve LLC, All rights reserved. ============
//
// Purpose:
//
@ -10,7 +10,7 @@
#pragma once
#include "cl_entity.h"
#include "interpolation.h"
#define INSET_OFF 0
@ -21,11 +21,12 @@
#define MAX_SPEC_HUD_MESSAGES 8
#define OVERVIEW_TILE_SIZE 128 // don't change this
#define OVERVIEW_MAX_LAYERS 1
extern void VectorAngles( const float *forward, float *angles );
extern "C" void NormalizeAngles( float *angles );
//-----------------------------------------------------------------------------
// Purpose: Handles the drawing of the spectator stuff (camera & top-down map and all the things on it )
//-----------------------------------------------------------------------------
@ -52,7 +53,17 @@ typedef struct overviewEntity_s {
double killTime;
} overviewEntity_t;
typedef struct cameraWayPoint_s
{
float time;
vec3_t position;
vec3_t angle;
float fov;
int flags;
} cameraWayPoint_t;
#define MAX_OVERVIEW_ENTITIES 128
#define MAX_CAM_WAYPOINTS 32
class CHudSpectator : public CHudBase
{
@ -76,6 +87,7 @@ public:
void HandleButtonsDown(int ButtonPressed);
void HandleButtonsUp(int ButtonPressed);
void FindNextPlayer( bool bReverse );
void FindPlayer(const char *name);
void DirectorMessage( int iSize, void *pbuf );
void SetSpectatorStartPosition();
int Init();
@ -83,6 +95,13 @@ public:
int Draw(float flTime);
void AddWaypoint( float time, vec3_t pos, vec3_t angle, float fov, int flags );
void SetCameraView( vec3_t pos, vec3_t angle, float fov);
float GetFOV();
bool GetDirectorCamera(vec3_t &position, vec3_t &angle);
void SetWayInterpolation(cameraWayPoint_t * prev, cameraWayPoint_t * start, cameraWayPoint_t * end, cameraWayPoint_t * next);
int m_iDrawCycle;
client_textmessage_t m_HUDMessages[MAX_SPEC_HUD_MESSAGES];
char m_HUDMessageText[MAX_SPEC_HUD_MESSAGES][128];
@ -99,13 +118,15 @@ public:
cvar_t * m_drawstatus;
cvar_t * m_autoDirector;
cvar_t * m_pip;
qboolean m_chatEnabled;
qboolean m_IsInterpolating;
int m_ChaseEntity; // if != 0, follow this entity with viewangles
int m_WayPoint; // current waypoint 1
int m_NumWayPoints; // current number of waypoints
vec3_t m_cameraOrigin; // a help camera
vec3_t m_cameraAngles; // and it's angles
CInterpolation m_WayInterpolation;
private:
vec3_t m_vPlayerPos[MAX_PLAYERS];
@ -123,10 +144,13 @@ private:
struct model_s * m_MapSprite; // each layer image is saved in one sprite, where each tile is a sprite frame
float m_flNextObserverInput;
float m_FOV;
float m_zoomDelta;
float m_moveDelta;
int m_lastPrimaryObject;
int m_lastSecondaryObject;
cameraWayPoint_t m_CamPath[MAX_CAM_WAYPOINTS];
};
#endif // SPECTATOR_H

View file

@ -14,18 +14,13 @@
#include "const.h"
#include "camera.h"
#include "in_defs.h"
#include "Exports.h"
#include "windows.h"
#include "SDL2/SDL_mouse.h"
#include "port.h"
float CL_KeyState (kbutton_t *key);
extern "C"
{
void DLLEXPORT CAM_Think( void );
int DLLEXPORT CL_IsThirdPerson( void );
void DLLEXPORT CL_CameraOffset( float *ofs );
}
extern cl_enginefunc_t gEngfuncs;
//-------------------------------------------------- Constants
@ -88,6 +83,15 @@ void CAM_ToFirstPerson(void);
void CAM_StartDistance(void);
void CAM_EndDistance(void);
void SDL_GetCursorPos( POINT *p )
{
gEngfuncs.GetMousePosition( (int *)&p->x, (int *)&p->y );
// SDL_GetMouseState( (int *)&p->x, (int *)&p->y );
}
void SDL_SetCursorPos( const int x, const int y )
{
}
//-------------------------------------------------- Local Functions
@ -146,8 +150,10 @@ typedef struct
extern trace_t SV_ClipMoveToEntity (edict_t *ent, vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end);
void DLLEXPORT CAM_Think( void )
void CL_DLLEXPORT CAM_Think( void )
{
// RecClCamThink();
vec3_t origin;
vec3_t ext, pnt, camForward, camRight, camUp;
moveclip_t clip;
@ -194,7 +200,7 @@ void DLLEXPORT CAM_Think( void )
if (cam_mousemove)
{
//get windows cursor position
GetCursorPos (&cam_mouse);
SDL_GetCursorPos (&cam_mouse);
//check for X delta values and adjust accordingly
//eventually adjust YAW based on amount of movement
//don't do any movement of the cam using YAW/PITCH if we are zooming in/out the camera
@ -269,7 +275,7 @@ void DLLEXPORT CAM_Think( void )
cam_old_mouse_x=cam_mouse.x;
cam_old_mouse_y=cam_mouse.y;
}
SetCursorPos (gEngfuncs.GetWindowCenterX(), gEngfuncs.GetWindowCenterY());
SDL_SetCursorPos (gEngfuncs.GetWindowCenterX(), gEngfuncs.GetWindowCenterY());
}
}
@ -327,7 +333,7 @@ void DLLEXPORT CAM_Think( void )
//since we are done with the mouse
cam_old_mouse_x=cam_mouse.x*gHUD.GetSensitivity();
cam_old_mouse_y=cam_mouse.y*gHUD.GetSensitivity();
SetCursorPos (gEngfuncs.GetWindowCenterX(), gEngfuncs.GetWindowCenterY());
SDL_SetCursorPos (gEngfuncs.GetWindowCenterX(), gEngfuncs.GetWindowCenterY());
}
#ifdef LATER
if( cam_contain->value )
@ -540,7 +546,7 @@ void CAM_StartMouseMove(void)
{
cam_mousemove=1;
iMouseInUse=1;
GetCursorPos (&cam_mouse);
SDL_GetCursorPos (&cam_mouse);
if ( ( flSensitivity = gHUD.GetSensitivity() ) != 0 )
{
@ -587,7 +593,7 @@ void CAM_StartDistance(void)
cam_distancemove=1;
cam_mousemove=1;
iMouseInUse=1;
GetCursorPos (&cam_mouse);
SDL_GetCursorPos (&cam_mouse);
cam_old_mouse_x=cam_mouse.x*gHUD.GetSensitivity();
cam_old_mouse_y=cam_mouse.y*gHUD.GetSensitivity();
}
@ -610,12 +616,16 @@ void CAM_EndDistance(void)
iMouseInUse=0;
}
int DLLEXPORT CL_IsThirdPerson( void )
int CL_DLLEXPORT CL_IsThirdPerson( void )
{
// RecClCL_IsThirdPerson();
return (cam_thirdperson ? 1 : 0) || (g_iUser1 && (g_iUser2 == gEngfuncs.GetLocalPlayer()->index) );
}
void DLLEXPORT CL_CameraOffset( float *ofs )
void CL_DLLEXPORT CL_CameraOffset( float *ofs )
{
// RecClCL_GetCameraOffsets(ofs);
VectorCopy( cam_ofs, ofs );
}
}

View file

@ -16,6 +16,5 @@
// fall over
#define ROLL 2
#define DLLEXPORT __declspec( dllexport )
#endif

View file

@ -1,10 +1,3 @@
//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================
// cl.input.c -- builds an intended movement command to send to the server
//xxxxxx Move bob and pitch drifting code here and other stuff from view if needed
@ -24,20 +17,14 @@ extern "C"
#include "camera.h"
#include "in_defs.h"
#include "view.h"
#include "bench.h"
#include <string.h>
#include <ctype.h>
#include "Exports.h"
#include "vgui_TeamFortressViewport.h"
extern "C"
{
struct kbutton_s DLLEXPORT *KB_Find( const char *name );
void DLLEXPORT CL_CreateMove ( float frametime, struct usercmd_s *cmd, int active );
void DLLEXPORT HUD_Shutdown( void );
int DLLEXPORT HUD_Key_Event( int eventcode, int keynum, const char *pszCurrentBinding );
}
extern int g_iAlive;
extern int g_weaponselect;
@ -219,8 +206,10 @@ KB_Find
Allows the engine to get a kbutton_t directly ( so it can check +mlook state, etc ) for saving out to .cfg files
============
*/
struct kbutton_s DLLEXPORT *KB_Find( const char *name )
struct kbutton_s CL_DLLEXPORT *KB_Find( const char *name )
{
// RecClFindKey(name);
kblist_t *p;
p = g_kbkeys;
while ( p )
@ -376,8 +365,10 @@ HUD_Key_Event
Return 1 to allow engine to process the key, otherwise, act on it as needed
============
*/
int DLLEXPORT HUD_Key_Event( int down, int keynum, const char *pszCurrentBinding )
int CL_DLLEXPORT HUD_Key_Event( int down, int keynum, const char *pszCurrentBinding )
{
// RecClKeyEvent(down, keynum, pszCurrentBinding);
if (gViewPort)
return gViewPort->KeyInput(down, keynum, pszCurrentBinding);
@ -462,6 +453,10 @@ void IN_Attack2Down(void)
{
KeyDown(&in_attack2);
#ifdef _TFC
__CmdFunc_InputPlayerSpecial();
#endif
gHUD.m_Spectator.HandleButtonsDown( IN_ATTACK2 );
}
@ -662,13 +657,15 @@ if active == 1 then we are 1) not playing back demos ( where our commands are ig
2 ) we have finished signing on to server
================
*/
void DLLEXPORT CL_CreateMove ( float frametime, struct usercmd_s *cmd, int active )
void CL_DLLEXPORT CL_CreateMove ( float frametime, struct usercmd_s *cmd, int active )
{
// RecClCL_CreateMove(frametime, cmd, active);
float spd;
vec3_t viewangles;
static vec3_t oldangles;
if ( active )
if ( active && !Bench_Active() )
{
//memset( viewangles, 0, sizeof( vec3_t ) );
//viewangles[ 0 ] = viewangles[ 1 ] = viewangles[ 2 ] = 0.0;
@ -766,6 +763,7 @@ void DLLEXPORT CL_CreateMove ( float frametime, struct usercmd_s *cmd, int activ
VectorCopy( oldangles, cmd->viewangles );
}
Bench_SetViewAngles( 1, (float *)&cmd->viewangles, frametime, cmd );
}
/*
@ -1022,7 +1020,22 @@ void ShutdownInput (void)
KB_Shutdown();
}
void DLLEXPORT HUD_Shutdown( void )
#include "interface.h"
void CL_UnloadParticleMan( void );
#if defined( _TFC )
void ClearEventList( void );
#endif
void CL_DLLEXPORT HUD_Shutdown( void )
{
// RecClShutdown();
ShutdownInput();
#if defined( _TFC )
ClearEventList();
#endif
CL_UnloadParticleMan();
}

View file

@ -8,6 +8,8 @@
// in_win.c -- windows 95 mouse and joystick code
// 02/21/97 JCB Added extended DirectInput code to support external controllers.
#include "port.h"
#include "hud.h"
#include "cl_util.h"
#include "camera.h"
@ -17,26 +19,19 @@
#include "const.h"
#include "camera.h"
#include "in_defs.h"
#include "../engine/keydefs.h"
#include "../public/keydefs.h"
#include "view.h"
#include "windows.h"
#include "Exports.h"
#include <SDL2/SDL_mouse.h>
#include <SDL2/SDL_gamecontroller.h>
#define MOUSE_BUTTON_COUNT 5
// Set this to 1 to show mouse cursor. Experimental
int g_iVisibleMouse = 0;
extern "C"
{
void DLLEXPORT IN_ActivateMouse( void );
void DLLEXPORT IN_DeactivateMouse( void );
void DLLEXPORT IN_MouseEvent (int mstate);
void DLLEXPORT IN_Accumulate (void);
void DLLEXPORT IN_ClearStates (void);
}
extern cl_enginefunc_t gEngfuncs;
extern int iMouseInUse;
extern kbutton_t in_strafe;
@ -59,18 +54,39 @@ extern cvar_t *cl_forwardspeed;
extern cvar_t *cl_pitchspeed;
extern cvar_t *cl_movespeedkey;
static double s_flRawInputUpdateTime = 0.0f;
static bool m_bRawInput = false;
static bool m_bMouseThread = false;
extern globalvars_t *gpGlobals;
// mouse variables
cvar_t *m_filter;
cvar_t *sensitivity;
// Custom mouse acceleration (0 disable, 1 to enable, 2 enable with separate yaw/pitch rescale)
static cvar_t *m_customaccel;
//Formula: mousesensitivity = ( rawmousedelta^m_customaccel_exponent ) * m_customaccel_scale + sensitivity
// If mode is 2, then x and y sensitivity are scaled by m_pitch and m_yaw respectively.
// Custom mouse acceleration value.
static cvar_t *m_customaccel_scale;
//Max mouse move scale factor, 0 for no limit
static cvar_t *m_customaccel_max;
//Mouse move is raised to this power before being scaled by scale factor
static cvar_t *m_customaccel_exponent;
// if threaded mouse is enabled then the time to sleep between polls
static cvar_t *m_mousethread_sleep;
int mouse_buttons;
int mouse_oldbuttonstate;
POINT current_pos;
int mouse_x, mouse_y, old_mouse_x, old_mouse_y, mx_accum, my_accum;
int old_mouse_x, old_mouse_y, mx_accum, my_accum;
float mouse_x, mouse_y;
static int restore_spi;
static int originalmouseparms[3], newmouseparms[3] = {0, 0, 1};
static int mouseactive;
static int mouseactive = 0;
int mouseinitialized;
static int mouseparmsvalid;
static int mouseshowtoggle = 1;
@ -96,19 +112,17 @@ enum _ControlList
AxisTurn
};
DWORD dwAxisFlags[JOY_MAX_AXES] =
{
JOY_RETURNX,
JOY_RETURNY,
JOY_RETURNZ,
JOY_RETURNR,
JOY_RETURNU,
JOY_RETURNV
};
DWORD dwAxisMap[ JOY_MAX_AXES ];
DWORD dwControlMap[ JOY_MAX_AXES ];
PDWORD pdwRawValue[ JOY_MAX_AXES ];
int pdwRawValue[ JOY_MAX_AXES ];
DWORD joy_oldbuttonstate, joy_oldpovstate;
int joy_id;
DWORD joy_numbuttons;
SDL_GameController *s_pJoystick = NULL;
// none of these cvars are saved over a session
// this means that advanced controller configuration needs to be executed
@ -136,13 +150,13 @@ cvar_t *joy_wwhack1;
cvar_t *joy_wwhack2;
int joy_avail, joy_advancedinit, joy_haspov;
DWORD joy_oldbuttonstate, joy_oldpovstate;
int joy_id;
DWORD joy_flags;
DWORD joy_numbuttons;
static JOYINFOEX ji;
#ifdef _WIN32
DWORD s_hMouseThreadId = 0;
HANDLE s_hMouseThread = 0;
HANDLE s_hMouseQuitEvent = 0;
HANDLE s_hMouseDoneQuitEvent = 0;
#endif
/*
===========
@ -161,33 +175,84 @@ void Force_CenterView_f (void)
}
}
#ifdef _WIN32
long s_mouseDeltaX = 0;
long s_mouseDeltaY = 0;
POINT old_mouse_pos;
long ThreadInterlockedExchange( long *pDest, long value )
{
return InterlockedExchange( pDest, value );
}
DWORD WINAPI MousePos_ThreadFunction( LPVOID p )
{
s_hMouseDoneQuitEvent = CreateEvent( NULL, FALSE, FALSE, NULL );
while ( 1 )
{
if ( WaitForSingleObject( s_hMouseQuitEvent, (int)m_mousethread_sleep->value ) == WAIT_OBJECT_0 )
{
return 0;
}
if ( mouseactive )
{
POINT mouse_pos;
GetCursorPos(&mouse_pos);
volatile int mx = mouse_pos.x - old_mouse_pos.x + s_mouseDeltaX;
volatile int my = mouse_pos.y - old_mouse_pos.y + s_mouseDeltaY;
ThreadInterlockedExchange( &old_mouse_pos.x, mouse_pos.x );
ThreadInterlockedExchange( &old_mouse_pos.y, mouse_pos.y );
ThreadInterlockedExchange( &s_mouseDeltaX, mx );
ThreadInterlockedExchange( &s_mouseDeltaY, my );
}
}
SetEvent( s_hMouseDoneQuitEvent );
return 0;
}
#endif
/*
===========
IN_ActivateMouse
===========
*/
void DLLEXPORT IN_ActivateMouse (void)
void CL_DLLEXPORT IN_ActivateMouse (void)
{
if (mouseinitialized)
{
#ifdef _WIN32
if (mouseparmsvalid)
restore_spi = SystemParametersInfo (SPI_SETMOUSE, 0, newmouseparms, 0);
#endif
mouseactive = 1;
}
}
/*
===========
IN_DeactivateMouse
===========
*/
void DLLEXPORT IN_DeactivateMouse (void)
void CL_DLLEXPORT IN_DeactivateMouse (void)
{
if (mouseinitialized)
{
#ifdef _WIN32
if (restore_spi)
SystemParametersInfo (SPI_SETMOUSE, 0, originalmouseparms, 0);
#endif
mouseactive = 0;
}
}
@ -203,6 +268,7 @@ void IN_StartupMouse (void)
return;
mouseinitialized = 1;
#ifdef _WIN32
mouseparmsvalid = SystemParametersInfo (SPI_GETMOUSE, 0, originalmouseparms, 0);
if (mouseparmsvalid)
@ -223,7 +289,8 @@ void IN_StartupMouse (void)
newmouseparms[2] = originalmouseparms[2];
}
}
#endif
mouse_buttons = MOUSE_BUTTON_COUNT;
}
@ -235,6 +302,34 @@ IN_Shutdown
void IN_Shutdown (void)
{
IN_DeactivateMouse ();
#ifdef _WIN32
if ( s_hMouseQuitEvent )
{
SetEvent( s_hMouseQuitEvent );
WaitForSingleObject( s_hMouseDoneQuitEvent, 100 );
}
if ( s_hMouseThread )
{
TerminateThread( s_hMouseThread, 0 );
CloseHandle( s_hMouseThread );
s_hMouseThread = (HANDLE)0;
}
if ( s_hMouseQuitEvent )
{
CloseHandle( s_hMouseQuitEvent );
s_hMouseQuitEvent = (HANDLE)0;
}
if ( s_hMouseDoneQuitEvent )
{
CloseHandle( s_hMouseDoneQuitEvent );
s_hMouseDoneQuitEvent = (HANDLE)0;
}
#endif
}
/*
@ -258,7 +353,22 @@ FIXME: Call through to engine?
*/
void IN_ResetMouse( void )
{
SetCursorPos ( gEngfuncs.GetWindowCenterX(), gEngfuncs.GetWindowCenterY() );
// no work to do in SDL
#ifdef _WIN32
if ( !m_bRawInput && mouseactive && gEngfuncs.GetWindowCenterX && gEngfuncs.GetWindowCenterY )
{
SetCursorPos ( gEngfuncs.GetWindowCenterX(), gEngfuncs.GetWindowCenterY() );
ThreadInterlockedExchange( &old_mouse_pos.x, gEngfuncs.GetWindowCenterX() );
ThreadInterlockedExchange( &old_mouse_pos.y, gEngfuncs.GetWindowCenterY() );
}
if ( gpGlobals && gpGlobals->time - s_flRawInputUpdateTime > 1.0f )
{
s_flRawInputUpdateTime = gpGlobals->time;
m_bRawInput = CVAR_GET_FLOAT( "m_rawinput" ) != 0;
}
#endif
}
/*
@ -266,7 +376,7 @@ void IN_ResetMouse( void )
IN_MouseEvent
===========
*/
void DLLEXPORT IN_MouseEvent (int mstate)
void CL_DLLEXPORT IN_MouseEvent (int mstate)
{
int i;
@ -292,6 +402,55 @@ void DLLEXPORT IN_MouseEvent (int mstate)
mouse_oldbuttonstate = mstate;
}
//-----------------------------------------------------------------------------
// Purpose: Allows modulation of mouse scaling/senstivity value and application
// of custom algorithms.
// Input : *x -
// *y -
//-----------------------------------------------------------------------------
void IN_ScaleMouse( float *x, float *y )
{
float mx = *x;
float my = *y;
// This is the default sensitivity
float mouse_senstivity = ( gHUD.GetSensitivity() != 0 ) ? gHUD.GetSensitivity() : sensitivity->value;
// Using special accleration values
if ( m_customaccel->value != 0 )
{
float raw_mouse_movement_distance = sqrt( mx * mx + my * my );
float acceleration_scale = m_customaccel_scale->value;
float accelerated_sensitivity_max = m_customaccel_max->value;
float accelerated_sensitivity_exponent = m_customaccel_exponent->value;
float accelerated_sensitivity = ( (float)pow( raw_mouse_movement_distance, accelerated_sensitivity_exponent ) * acceleration_scale + mouse_senstivity );
if ( accelerated_sensitivity_max > 0.0001f &&
accelerated_sensitivity > accelerated_sensitivity_max )
{
accelerated_sensitivity = accelerated_sensitivity_max;
}
*x *= accelerated_sensitivity;
*y *= accelerated_sensitivity;
// Further re-scale by yaw and pitch magnitude if user requests alternate mode 2
// This means that they will need to up their value for m_customaccel_scale greatly (>40x) since m_pitch/yaw default
// to 0.022
if ( m_customaccel->value == 2 )
{
*x *= m_yaw->value;
*y *= m_pitch->value;
}
}
else
{
// Just apply the default
*x *= mouse_senstivity;
*y *= mouse_senstivity;
}
}
/*
===========
IN_MouseMove
@ -311,17 +470,57 @@ void IN_MouseMove ( float frametime, usercmd_t *cmd)
//jjb - this disbles normal mouse control if the user is trying to
// move the camera, or if the mouse cursor is visible or if we're in intermission
if ( !iMouseInUse && !g_iVisibleMouse && !gHUD.m_iIntermission )
if ( !iMouseInUse && !gHUD.m_iIntermission && !g_iVisibleMouse )
{
GetCursorPos (&current_pos);
mx = current_pos.x - gEngfuncs.GetWindowCenterX() + mx_accum;
my = current_pos.y - gEngfuncs.GetWindowCenterY() + my_accum;
int deltaX, deltaY;
#ifdef _WIN32
if ( !m_bRawInput )
{
if ( m_bMouseThread )
{
ThreadInterlockedExchange( &current_pos.x, s_mouseDeltaX );
ThreadInterlockedExchange( &current_pos.y, s_mouseDeltaY );
ThreadInterlockedExchange( &s_mouseDeltaX, 0 );
ThreadInterlockedExchange( &s_mouseDeltaY, 0 );
}
else
{
GetCursorPos (&current_pos);
}
}
else
#endif
{
SDL_GetRelativeMouseState( &deltaX, &deltaY );
current_pos.x = deltaX;
current_pos.y = deltaY;
}
#ifdef _WIN32
if ( !m_bRawInput )
{
if ( m_bMouseThread )
{
mx = current_pos.x;
my = current_pos.y;
}
else
{
mx = current_pos.x - gEngfuncs.GetWindowCenterX() + mx_accum;
my = current_pos.y - gEngfuncs.GetWindowCenterY() + my_accum;
}
}
else
#endif
{
mx = deltaX + mx_accum;
my = deltaY + my_accum;
}
mx_accum = 0;
my_accum = 0;
if (m_filter->value)
if (m_filter && m_filter->value)
{
mouse_x = (mx + old_mouse_x) * 0.5;
mouse_y = (my + old_mouse_y) * 0.5;
@ -335,16 +534,8 @@ void IN_MouseMove ( float frametime, usercmd_t *cmd)
old_mouse_x = mx;
old_mouse_y = my;
if ( gHUD.GetSensitivity() != 0 )
{
mouse_x *= gHUD.GetSensitivity();
mouse_y *= gHUD.GetSensitivity();
}
else
{
mouse_x *= sensitivity->value;
mouse_y *= sensitivity->value;
}
// Apply custom mouse scaling/acceleration
IN_ScaleMouse( &mouse_x, &mouse_y );
// add mouse X/Y movement to cmd
if ( (in_strafe.state & 1) || (lookstrafe->value && (in_mlook.state & 1) ))
@ -399,20 +590,35 @@ void IN_MouseMove ( float frametime, usercmd_t *cmd)
IN_Accumulate
===========
*/
void DLLEXPORT IN_Accumulate (void)
void CL_DLLEXPORT IN_Accumulate (void)
{
//only accumulate mouse if we are not moving the camera with the mouse
if ( !iMouseInUse && !g_iVisibleMouse )
if ( !iMouseInUse && !g_iVisibleMouse)
{
if (mouseactive)
{
GetCursorPos (&current_pos);
mx_accum += current_pos.x - gEngfuncs.GetWindowCenterX();
my_accum += current_pos.y - gEngfuncs.GetWindowCenterY();
#ifdef _WIN32
if ( !m_bRawInput )
{
if ( !m_bMouseThread )
{
GetCursorPos (&current_pos);
mx_accum += current_pos.x - gEngfuncs.GetWindowCenterX();
my_accum += current_pos.y - gEngfuncs.GetWindowCenterY();
}
}
else
#endif
{
int deltaX, deltaY;
SDL_GetRelativeMouseState( &deltaX, &deltaY );
mx_accum += deltaX;
my_accum += deltaY;
}
// force the mouse to the center, so there's room to move
IN_ResetMouse();
}
}
@ -423,7 +629,7 @@ void DLLEXPORT IN_Accumulate (void)
IN_ClearStates
===================
*/
void DLLEXPORT IN_ClearStates (void)
void CL_DLLEXPORT IN_ClearStates (void)
{
if ( !mouseactive )
return;
@ -440,93 +646,66 @@ IN_StartupJoystick
*/
void IN_StartupJoystick (void)
{
int numdevs;
JOYCAPS jc;
MMRESULT mmr;
// assume no joystick
joy_avail = 0;
// abort startup if user requests no joystick
if ( gEngfuncs.CheckParm ("-nojoy", NULL ) )
return;
// verify joystick driver is present
if ((numdevs = joyGetNumDevs ()) == 0)
// assume no joystick
joy_avail = 0;
int nJoysticks = SDL_NumJoysticks();
if ( nJoysticks > 0 )
{
for ( int i = 0; i < nJoysticks; i++ )
{
if ( SDL_IsGameController( i ) )
{
s_pJoystick = SDL_GameControllerOpen( i );
if ( s_pJoystick )
{
//save the joystick's number of buttons and POV status
joy_numbuttons = SDL_CONTROLLER_BUTTON_MAX;
joy_haspov = 0;
// old button and POV states default to no buttons pressed
joy_oldbuttonstate = joy_oldpovstate = 0;
// mark the joystick as available and advanced initialization not completed
// this is needed as cvars are not available during initialization
gEngfuncs.Con_Printf ("joystick found\n\n", SDL_GameControllerName(s_pJoystick));
joy_avail = 1;
joy_advancedinit = 0;
break;
}
}
}
}
else
{
gEngfuncs.Con_DPrintf ("joystick not found -- driver not present\n\n");
return;
}
// cycle through the joystick ids for the first valid one
for (joy_id=0 ; joy_id<numdevs ; joy_id++)
{
memset (&ji, 0, sizeof(ji));
ji.dwSize = sizeof(ji);
ji.dwFlags = JOY_RETURNCENTERED;
if ((mmr = joyGetPosEx (joy_id, &ji)) == JOYERR_NOERROR)
break;
}
// abort startup if we didn't find a valid joystick
if (mmr != JOYERR_NOERROR)
{
gEngfuncs.Con_DPrintf ("joystick not found -- no valid joysticks (%x)\n\n", mmr);
return;
}
// get the capabilities of the selected joystick
// abort startup if command fails
memset (&jc, 0, sizeof(jc));
if ((mmr = joyGetDevCaps (joy_id, &jc, sizeof(jc))) != JOYERR_NOERROR)
{
gEngfuncs.Con_DPrintf ("joystick not found -- invalid joystick capabilities (%x)\n\n", mmr);
return;
}
// save the joystick's number of buttons and POV status
joy_numbuttons = jc.wNumButtons;
joy_haspov = jc.wCaps & JOYCAPS_HASPOV;
// old button and POV states default to no buttons pressed
joy_oldbuttonstate = joy_oldpovstate = 0;
// mark the joystick as available and advanced initialization not completed
// this is needed as cvars are not available during initialization
gEngfuncs.Con_Printf ("joystick found\n\n", mmr);
joy_avail = 1;
joy_advancedinit = 0;
}
/*
===========
RawValuePointer
===========
*/
PDWORD RawValuePointer (int axis)
int RawValuePointer (int axis)
{
switch (axis)
{
case JOY_AXIS_X:
return &ji.dwXpos;
case JOY_AXIS_Y:
return &ji.dwYpos;
case JOY_AXIS_Z:
return &ji.dwZpos;
case JOY_AXIS_R:
return &ji.dwRpos;
case JOY_AXIS_U:
return &ji.dwUpos;
case JOY_AXIS_V:
return &ji.dwVpos;
default:
case JOY_AXIS_X:
return SDL_GameControllerGetAxis( s_pJoystick, SDL_CONTROLLER_AXIS_LEFTX );
case JOY_AXIS_Y:
return SDL_GameControllerGetAxis( s_pJoystick, SDL_CONTROLLER_AXIS_LEFTY );
case JOY_AXIS_Z:
return SDL_GameControllerGetAxis( s_pJoystick, SDL_CONTROLLER_AXIS_RIGHTX );
case JOY_AXIS_R:
return SDL_GameControllerGetAxis( s_pJoystick, SDL_CONTROLLER_AXIS_RIGHTY );
}
// FIX: need to do some kind of error
return &ji.dwXpos;
}
/*
===========
Joy_AdvancedUpdate_f
@ -586,16 +765,6 @@ void Joy_AdvancedUpdate_f (void)
dwAxisMap[JOY_AXIS_V] = dwTemp & 0x0000000f;
dwControlMap[JOY_AXIS_V] = dwTemp & JOY_RELATIVE_AXIS;
}
// compute the axes to collect from DirectInput
joy_flags = JOY_RETURNCENTERED | JOY_RETURNBUTTONS | JOY_RETURNPOV;
for (i = 0; i < JOY_MAX_AXES; i++)
{
if (dwAxisMap[i] != AxisNada)
{
joy_flags |= dwAxisFlags[i];
}
}
}
@ -607,17 +776,30 @@ IN_Commands
void IN_Commands (void)
{
int i, key_index;
DWORD buttonstate, povstate;
if (!joy_avail)
{
return;
}
DWORD buttonstate, povstate;
// loop through the joystick buttons
// key a joystick event or auxillary event for higher number buttons for each state change
buttonstate = ji.dwButtons;
buttonstate = 0;
for ( i = 0; i < SDL_CONTROLLER_BUTTON_MAX; i++ )
{
if ( SDL_GameControllerGetButton( s_pJoystick, (SDL_GameControllerButton)i ) )
{
buttonstate |= 1<<i;
}
}
for (i = 0; i < JOY_MAX_AXES; i++)
{
pdwRawValue[i] = RawValuePointer(i);
}
for (i=0 ; i < (int)joy_numbuttons ; i++)
{
if ( (buttonstate & (1<<i)) && !(joy_oldbuttonstate & (1<<i)) )
@ -640,17 +822,6 @@ void IN_Commands (void)
// this avoids any potential problems related to moving from one
// direction to another without going through the center position
povstate = 0;
if(ji.dwPOV != JOY_POVCENTERED)
{
if (ji.dwPOV == JOY_POVFORWARD)
povstate |= 0x01;
if (ji.dwPOV == JOY_POVRIGHT)
povstate |= 0x02;
if (ji.dwPOV == JOY_POVBACKWARD)
povstate |= 0x04;
if (ji.dwPOV == JOY_POVLEFT)
povstate |= 0x08;
}
// determine which bits have changed and key an auxillary event for each change
for (i=0 ; i < 4 ; i++)
{
@ -676,31 +847,8 @@ IN_ReadJoystick
*/
int IN_ReadJoystick (void)
{
memset (&ji, 0, sizeof(ji));
ji.dwSize = sizeof(ji);
ji.dwFlags = joy_flags;
if (joyGetPosEx (joy_id, &ji) == JOYERR_NOERROR)
{
// this is a hack -- there is a bug in the Logitech WingMan Warrior DirectInput Driver
// rather than having 32768 be the zero point, they have the zero point at 32668
// go figure -- anyway, now we get the full resolution out of the device
if (joy_wwhack1->value != 0.0)
{
ji.dwUpos += 100;
}
return 1;
}
else
{
// read error occurred
// turning off the joystick seems too harsh for 1 read error,\
// but what should be done?
// Con_Printf ("IN_ReadJoystick: no response\n");
// joy_avail = 0;
return 0;
}
SDL_JoystickUpdate();
return 1;
}
@ -750,9 +898,7 @@ void IN_JoyMove ( float frametime, usercmd_t *cmd )
for (i = 0; i < JOY_MAX_AXES; i++)
{
// get the floating point zero-centered, potentially-inverted data for the current axis
fAxisValue = (float) *pdwRawValue[i];
// move centerpoint to zero
fAxisValue -= 32768.0;
fAxisValue = (float)pdwRawValue[i];
if (joy_wwhack2->value != 0.0)
{
@ -891,7 +1037,6 @@ void IN_JoyMove ( float frametime, usercmd_t *cmd )
viewangles[PITCH] = -cl_pitchup->value;
gEngfuncs.SetViewAngles( (float *)viewangles );
}
/*
@ -939,9 +1084,31 @@ void IN_Init (void)
joy_wwhack1 = gEngfuncs.pfnRegisterVariable ( "joywwhack1", "0.0", 0 );
joy_wwhack2 = gEngfuncs.pfnRegisterVariable ( "joywwhack2", "0.0", 0 );
m_customaccel = gEngfuncs.pfnRegisterVariable ( "m_customaccel", "0", FCVAR_ARCHIVE );
m_customaccel_scale = gEngfuncs.pfnRegisterVariable ( "m_customaccel_scale", "0.04", FCVAR_ARCHIVE );
m_customaccel_max = gEngfuncs.pfnRegisterVariable ( "m_customaccel_max", "0", FCVAR_ARCHIVE );
m_customaccel_exponent = gEngfuncs.pfnRegisterVariable ( "m_customaccel_exponent", "1", FCVAR_ARCHIVE );
#ifdef _WIN32
m_bRawInput = CVAR_GET_FLOAT( "m_rawinput" ) > 0;
m_bMouseThread = gEngfuncs.CheckParm ("-mousethread", NULL ) != NULL;
m_mousethread_sleep = gEngfuncs.pfnRegisterVariable ( "m_mousethread_sleep", "10", FCVAR_ARCHIVE );
if ( !m_bRawInput && m_bMouseThread && m_mousethread_sleep )
{
s_mouseDeltaX = s_mouseDeltaY = 0;
s_hMouseQuitEvent = CreateEvent( NULL, FALSE, FALSE, NULL );
if ( s_hMouseQuitEvent )
{
s_hMouseThread = CreateThread( NULL, 0, MousePos_ThreadFunction, NULL, 0, &s_hMouseThreadId );
}
}
#endif
gEngfuncs.pfnAddCommand ("force_centerview", Force_CenterView_f);
gEngfuncs.pfnAddCommand ("joyadvancedupdate", Joy_AdvancedUpdate_f);
IN_StartupMouse ();
IN_StartupJoystick ();
}
}

222
cl_dll/interpolation.cpp Normal file
View file

@ -0,0 +1,222 @@
/************ (C) Copyright 2003 Valve, L.L.C. All rights reserved. ***********
**
** The copyright to the contents herein is the property of Valve, L.L.C.
** The contents may be used and/or copied only with the written permission of
** Valve, L.L.C., or in accordance with the terms and conditions stipulated in
** the agreement/contract under which the contents have been supplied.
**
*******************************************************************************
**
** Contents:
**
** interpolation.cpp: implementation of the interpolation class
**
******************************************************************************/
#include "hud.h"
#include "cl_util.h"
#include "interpolation.h"
// = determinant of matrix a,b,c
#define Determinant(a,b,c) ( (a)[2] * ( (b)[0]*(c)[1] - (b)[1]*(c)[0] ) + \
(a)[1] * ( (b)[2]*(c)[0] - (b)[0]*(c)[2] ) + \
(a)[0] * ( (b)[1]*(c)[2] - (b)[2]*(c)[1] ) )
// slove 3 vector linear system of equations v0 = x*v1 + y*v2 + z*v3 (if possible)
bool SolveLSE (vec3_t v0, vec3_t v1, vec3_t v2, vec3_t v3, float * x, float * y, float * z)
{
float d = Determinant(v1,v2,v3);
if (d==0.0f)
return false;
if ( x )
*x = Determinant(v0,v2,v3) / d;
if ( y )
*y= Determinant(v1,v0,v3) / d;
if ( z )
*z= Determinant(v1,v2,v0) / d;
return true;
}
// p = closest point between vector lines a1+x*m1 and a2+x*m2
bool GetPointBetweenLines(vec3_t &p, vec3_t a1, vec3_t m1, vec3_t a2, vec3_t m2 )
{
float x,z;
vec3_t t1 = CrossProduct(m1, m2);
vec3_t t2 = a2 - a1;
if ( !SolveLSE( t2, m1, t1, m2, &x , NULL, &z ) )
return false;
t1 = a1 + x*m1;
t2 = a2 + (-z)*m2;
p = ( t1 + t2 ) / 2.0f;
return true;
}
// Bernstein Poynom B(u) with n = 2, i = 0
#define BernsteinPolynom20(u) ((1.0f-u)*(1.0f-u))
#define BernsteinPolynom21(u) (2.0f*u*(1.0f-u))
#define BernsteinPolynom22(u) (u*u)
CInterpolation::CInterpolation()
{
}
CInterpolation::~CInterpolation()
{
m_SmoothStart = m_SmoothEnd = false;
}
void CInterpolation::SetViewAngles( vec3_t start, vec3_t end )
{
m_StartAngle = start;
m_EndAngle = end;
NormalizeAngles( m_StartAngle );
NormalizeAngles( m_EndAngle );
}
void CInterpolation::SetFOVs(float start, float end)
{
m_StartFov = start;
m_EndFov = end;
}
void CInterpolation::SetWaypoints( vec3_t * prev, vec3_t start, vec3_t end, vec3_t * next)
{
m_StartPoint = start;
m_EndPoint = end;
vec3_t a,b,c,d;
if ( !prev && !next )
{
// no direction given, straight linear interpolation
m_Center = (m_StartPoint + m_EndPoint) / 2.0f;
}
else if ( !prev )
{
a = start - end;
float dist = a.Length() / 2.0f;
a = a.Normalize();
b = *next - end;
b = b.Normalize();
c = a - b;
c = c.Normalize();
m_Center = end + c*dist;
}
else if ( !next )
{
a = *prev - start;
a = a.Normalize();
b = end - start;
float dist = b.Length() / 2.0f;
b = b.Normalize();
c = b - a;
c = c.Normalize();
m_Center = start + c*dist;
}
else
{
// we have a previous and a next point, great!
a = *prev - start;
a = a.Normalize();
b = end - start;
b = b.Normalize();
c = b - a;
a = start - end;
a = a.Normalize();
b = *next - end;
b = b.Normalize();
d = a - b;
GetPointBetweenLines( m_Center, start, c, end, d);
}
}
void CInterpolation::Interpolate( float t, vec3_t &point, vec3_t &angle, float * fov)
{
if ( m_SmoothStart && m_SmoothEnd )
{
t = (1.0f-t)*(t*t)+t*(1.0f-((t-1.0f)*(t-1.0f)));
}
else if ( m_SmoothStart )
{
t = t*t;
}
else if ( m_SmoothEnd )
{
t = t - 1.0f;
t = -(t*t)+1;
}
if ( point )
{
BezierInterpolatePoint(t, point);
}
if ( angle )
{
InterpolateAngle(t, angle);
}
if ( fov )
{
*fov = m_StartFov + (t * (m_EndFov-m_StartFov));
}
}
void CInterpolation::BezierInterpolatePoint( float t, vec3_t &point )
{
point = m_StartPoint * BernsteinPolynom20(t);
point = point + m_Center * BernsteinPolynom21(t);
point = point + m_EndPoint * BernsteinPolynom22(t);
}
void CInterpolation::SetSmoothing(bool start, bool end)
{
m_SmoothStart = start;
m_SmoothEnd = end;
}
void CInterpolation::InterpolateAngle( float t, vec3_t &angle )
{
int i;
float ang1, ang2;
float d;
for ( i = 0 ; i < 3 ; i++ )
{
ang1 = m_StartAngle[i];
ang2 = m_EndAngle[i];
d = ang2 - ang1;
if ( d > 180 )
{
d -= 360;
}
else if ( d < -180 )
{
d += 360;
}
angle[i] = ang1 + d * t;
}
NormalizeAngles( angle );
}

56
cl_dll/interpolation.h Normal file
View file

@ -0,0 +1,56 @@
/************ (C) Copyright 2003 Valve, L.L.C. All rights reserved. ***********
**
** The copyright to the contents herein is the property of Valve, L.L.C.
** The contents may be used and/or copied only with the written permission of
** Valve, L.L.C., or in accordance with the terms and conditions stipulated in
** the agreement/contract under which the contents have been supplied.
**
*******************************************************************************
**
** Contents:
**
** interpolation.h: Bezier inpolation classes
**
******************************************************************************/
#ifndef INTERPOLATION_H
#define INTERPOLATION_H
#ifdef _WIN32
#pragma once
#endif
// interpolation class
class CInterpolation
{
public:
CInterpolation();
virtual ~CInterpolation();
void SetWaypoints(vec3_t * prev, vec3_t start, vec3_t end, vec3_t * next);
void SetViewAngles( vec3_t start, vec3_t end );
void SetFOVs(float start, float end);
void SetSmoothing(bool start, bool end);
// get interpolated point 0 =< t =< 1, 0 = start, 1 = end
void Interpolate(float t, vec3_t &point, vec3_t &angle, float * fov);
protected:
void BezierInterpolatePoint( float t, vec3_t &point );
void InterpolateAngle( float t, vec3_t &angle );
vec3_t m_StartPoint;
vec3_t m_EndPoint;
vec3_t m_StartAngle;
vec3_t m_EndAngle;
vec3_t m_Center;
float m_StartFov;
float m_EndFov;
bool m_SmoothStart;
bool m_SmoothEnd;
};
#endif // INTERPOLATION_H

View file

@ -63,6 +63,69 @@ int CHudMenu :: VidInit( void )
return 1;
}
/*=================================
ParseEscapeToken
Interprets the given escape token (backslash followed by a letter). The
first character of the token must be a backslash. The second character
specifies the operation to perform:
\w : White text (this is the default)
\d : Dim (gray) text
\y : Yellow text
\r : Red text
\R : Right-align (just for the remainder of the current line)
=================================*/
static int menu_r, menu_g, menu_b, menu_x, menu_ralign;
static inline const char* ParseEscapeToken( const char* token )
{
if ( *token != '\\' )
return token;
token++;
switch ( *token )
{
case '\0':
return token;
case 'w':
menu_r = 255;
menu_g = 255;
menu_b = 255;
break;
case 'd':
menu_r = 100;
menu_g = 100;
menu_b = 100;
break;
case 'y':
menu_r = 255;
menu_g = 210;
menu_b = 64;
break;
case 'r':
menu_r = 210;
menu_g = 24;
menu_b = 0;
break;
case 'R':
menu_x = ScreenWidth/2;
menu_ralign = TRUE;
break;
}
return ++token;
}
int CHudMenu :: Draw( float flTime )
{
// check for if menu is set to disappear
@ -84,7 +147,8 @@ int CHudMenu :: Draw( float flTime )
// count the number of newlines
int nlc = 0;
for ( int i = 0; i < MAX_MENU_STRING && g_szMenuString[i] != '\0'; i++ )
int i;
for ( i = 0; i < MAX_MENU_STRING && g_szMenuString[i] != '\0'; i++ )
{
if ( g_szMenuString[i] == '\n' )
nlc++;
@ -92,18 +156,50 @@ int CHudMenu :: Draw( float flTime )
// center it
int y = (ScreenHeight/2) - ((nlc/2)*12) - 40; // make sure it is above the say text
int x = 20;
i = 0;
while ( i < MAX_MENU_STRING && g_szMenuString[i] != '\0' )
menu_r = 255;
menu_g = 255;
menu_b = 255;
menu_x = 20;
menu_ralign = FALSE;
const char* sptr = g_szMenuString;
while ( *sptr != '\0' )
{
gHUD.DrawHudString( x, y, 320, g_szMenuString + i, 255, 255, 255 );
y += 12;
while ( i < MAX_MENU_STRING && g_szMenuString[i] != '\0' && g_szMenuString[i] != '\n' )
i++;
if ( g_szMenuString[i] == '\n' )
i++;
if ( *sptr == '\\' )
{
sptr = ParseEscapeToken( sptr );
}
else if ( *sptr == '\n' )
{
menu_ralign = FALSE;
menu_x = 20;
y += (12);
sptr++;
}
else
{
char menubuf[ 80 ];
const char *ptr = sptr;
while ( *sptr != '\0' && *sptr != '\n' && *sptr != '\\')
{
sptr++;
}
strncpy( menubuf, ptr, min( ( sptr - ptr), (int)sizeof( menubuf ) ));
menubuf[ min( ( sptr - ptr), (int)(sizeof( menubuf )-1) ) ] = '\0';
if ( menu_ralign )
{
// IMPORTANT: Right-to-left rendered text does not parse escape tokens!
menu_x = gHUD.DrawHudStringReverse( menu_x, y, 0, menubuf, menu_r, menu_g, menu_b );
}
else
{
menu_x = gHUD.DrawHudString( menu_x, y, 320, menubuf, menu_r, menu_g, menu_b );
}
}
}
return 1;
@ -117,7 +213,7 @@ void CHudMenu :: SelectMenuItem( int menu_item )
{
char szbuf[32];
sprintf( szbuf, "menuselect %d\n", menu_item );
ClientCmd( szbuf );
EngineClientCmd( szbuf );
// remove the menu
m_fMenuDisplayed = 0;

View file

@ -147,13 +147,13 @@ void CHudMessage::MessageScanNextChar( void )
srcGreen = m_parms.pMessage->g1;
srcBlue = m_parms.pMessage->b1;
blend = 0; // Pure source
destRed = destGreen = destBlue = 0;
switch( m_parms.pMessage->effect )
{
// Fade-in / Fade-out
case 0:
case 1:
destRed = destGreen = destBlue = 0;
blend = m_parms.fadeBlend;
break;
@ -168,7 +168,6 @@ void CHudMessage::MessageScanNextChar( void )
{
float deltaTime = m_parms.time - m_parms.charTime;
destRed = destGreen = destBlue = 0;
if ( m_parms.time > m_parms.fadeTime )
{
blend = m_parms.fadeBlend;

20
cl_dll/player_info.h Normal file
View file

@ -0,0 +1,20 @@
/***
*
* Copyright (c) 2003', Valve LLC. All rights reserved.
*
* This product contains software technology licensed from Id
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
* All Rights Reserved.
*
* Use, distribution, and modification of this source code and/or resulting
* object code is restricted to non-commercial enhancements to products from
* Valve LLC. All other use, distribution, or modification is prohibited
* without written permission from Valve LLC.
*
****/
extern hud_player_info_t g_PlayerInfoList[MAX_PLAYERS+1]; // player info from the engine
extern extra_player_info_t g_PlayerExtraInfo[MAX_PLAYERS+1]; // additional player info sent directly to the client dll
extern team_info_t g_TeamInfo[MAX_TEAMS+1];
extern int g_IsSpectator[MAX_PLAYERS+1];

View file

@ -24,6 +24,7 @@
#include <string.h>
#include <stdio.h>
#include <malloc.h> // _alloca
#include "vgui_TeamFortressViewport.h"
@ -129,16 +130,25 @@ int CHudSayText :: Draw( float flTime )
if ( *g_szLineBuffer[i] == 2 && g_pflNameColors[i] )
{
// it's a saytext string
static char buf[MAX_PLAYER_NAME_LENGTH+32];
char *buf = static_cast<char *>( _alloca( strlen( g_szLineBuffer[i] ) ) );
if ( buf )
{
//char buf[MAX_PLAYER_NAME_LENGTH+32];
// draw the first x characters in the player color
strncpy( buf, g_szLineBuffer[i], min(g_iNameLengths[i], MAX_PLAYER_NAME_LENGTH+32) );
buf[ min(g_iNameLengths[i], MAX_PLAYER_NAME_LENGTH+31) ] = 0;
gEngfuncs.pfnDrawSetTextColor( g_pflNameColors[i][0], g_pflNameColors[i][1], g_pflNameColors[i][2] );
int x = DrawConsoleString( LINE_START, y, buf );
// color is reset after each string draw
DrawConsoleString( x, y, g_szLineBuffer[i] + g_iNameLengths[i] );
// draw the first x characters in the player color
strncpy( buf, g_szLineBuffer[i], min(g_iNameLengths[i], MAX_PLAYER_NAME_LENGTH+32) );
buf[ min(g_iNameLengths[i], MAX_PLAYER_NAME_LENGTH+31) ] = 0;
gEngfuncs.pfnDrawSetTextColor( g_pflNameColors[i][0], g_pflNameColors[i][1], g_pflNameColors[i][2] );
int x = DrawConsoleString( LINE_START, y, buf + 1 ); // don't draw the control code at the start
strncpy( buf, g_szLineBuffer[i] + g_iNameLengths[i], strlen( g_szLineBuffer[i] ));
buf[ strlen( g_szLineBuffer[i] + g_iNameLengths[i] ) - 1 ] = '\0';
// color is reset after each string draw
DrawConsoleString( x, y, buf );
}
else
{
assert( "Not able to alloca chat buffer!\n");
}
}
else
{
@ -150,7 +160,6 @@ int CHudSayText :: Draw( float flTime )
y += line_height;
}
return 1;
}
@ -173,8 +182,9 @@ void CHudSayText :: SayTextPrint( const char *pszBuf, int iBufSize, int clientIn
return;
}
int i;
// find an empty string slot
for ( int i = 0; i < MAX_LINES; i++ )
for ( i = 0; i < MAX_LINES; i++ )
{
if ( ! *g_szLineBuffer[i] )
break;
@ -192,7 +202,7 @@ void CHudSayText :: SayTextPrint( const char *pszBuf, int iBufSize, int clientIn
// if it's a say message, search for the players name in the string
if ( *pszBuf == 2 && clientIndex > 0 )
{
GetPlayerInfo( clientIndex, &g_PlayerInfoList[clientIndex] );
gEngfuncs.pfnGetPlayerInfo( clientIndex, &g_PlayerInfoList[clientIndex] );
const char *pName = g_PlayerInfoList[clientIndex].name;
if ( pName )
@ -207,7 +217,7 @@ void CHudSayText :: SayTextPrint( const char *pszBuf, int iBufSize, int clientIn
}
}
strncpy( g_szLineBuffer[i], pszBuf, max(iBufSize -1, MAX_CHARS_PER_LINE-1) );
strncpy( g_szLineBuffer[i], pszBuf, max(iBufSize , MAX_CHARS_PER_LINE) );
// make sure the text fits in one line
EnsureTextFitsInOneLineAndWrapIfHaveTo( i );
@ -221,12 +231,7 @@ void CHudSayText :: SayTextPrint( const char *pszBuf, int iBufSize, int clientIn
m_iFlags |= HUD_ACTIVE;
PlaySound( "misc/talk.wav", 1 );
if ( ScreenHeight >= 480 )
Y_START = ScreenHeight - 60;
else
Y_START = ScreenHeight - 45;
Y_START -= (line_height * (MAX_LINES+1));
Y_START = ScreenHeight - 60 - ( line_height * (MAX_LINES+2) );
}
void CHudSayText :: EnsureTextFitsInOneLineAndWrapIfHaveTo( int line )
@ -318,4 +323,4 @@ void CHudSayText :: EnsureTextFitsInOneLineAndWrapIfHaveTo( int line )
}
}
}
}
}

586
cl_dll/scoreboard.cpp Normal file
View file

@ -0,0 +1,586 @@
/***
*
* Copyright (c) 1999, Valve LLC. All rights reserved.
*
* This product contains software technology licensed from Id
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
* All Rights Reserved.
*
* Use, distribution, and modification of this source code and/or resulting
* object code is restricted to non-commercial enhancements to products from
* Valve LLC. All other use, distribution, or modification is prohibited
* without written permission from Valve LLC.
*
****/
//
// Scoreboard.cpp
//
// implementation of CHudScoreboard class
//
#include "hud.h"
#include "cl_util.h"
#include "parsemsg.h"
#include <string.h>
#include <stdio.h>
#include "vgui_TeamFortressViewport.h"
DECLARE_COMMAND( m_Scoreboard, ShowScores );
DECLARE_COMMAND( m_Scoreboard, HideScores );
DECLARE_MESSAGE( m_Scoreboard, ScoreInfo );
DECLARE_MESSAGE( m_Scoreboard, TeamInfo );
DECLARE_MESSAGE( m_Scoreboard, TeamScore );
int CHudScoreboard :: Init( void )
{
gHUD.AddHudElem( this );
// Hook messages & commands here
//HOOK_COMMAND( "+showscores", ShowScores );
//HOOK_COMMAND( "-showscores", HideScores );
HOOK_MESSAGE( ScoreInfo );
HOOK_MESSAGE( TeamScore );
HOOK_MESSAGE( TeamInfo );
InitHUDData();
cl_showpacketloss = CVAR_CREATE( "cl_showpacketloss", "0", FCVAR_ARCHIVE );
return 1;
}
int CHudScoreboard :: VidInit( void )
{
// Load sprites here
return 1;
}
void CHudScoreboard :: InitHUDData( void )
{
memset( g_PlayerExtraInfo, 0, sizeof g_PlayerExtraInfo );
m_iLastKilledBy = 0;
m_fLastKillTime = 0;
m_iPlayerNum = 0;
m_iNumTeams = 0;
memset( g_TeamInfo, 0, sizeof g_TeamInfo );
m_iFlags &= ~HUD_ACTIVE; // starts out inactive
m_iFlags |= HUD_INTERMISSION; // is always drawn during an intermission
}
/* The scoreboard
We have a minimum width of 1-320 - we could have the field widths scale with it?
*/
// X positions
// relative to the side of the scoreboard
#define NAME_RANGE_MIN 20
#define NAME_RANGE_MAX 145
#define KILLS_RANGE_MIN 130
#define KILLS_RANGE_MAX 170
#define DIVIDER_POS 180
#define DEATHS_RANGE_MIN 185
#define DEATHS_RANGE_MAX 210
#define PING_RANGE_MIN 245
#define PING_RANGE_MAX 295
#define PL_RANGE_MIN 315
#define PL_RANGE_MAX 375
int SCOREBOARD_WIDTH = 320;
// Y positions
#define ROW_GAP 13
#define ROW_RANGE_MIN 15
#define ROW_RANGE_MAX ( ScreenHeight - 50 )
int CHudScoreboard :: Draw( float fTime )
{
int can_show_packetloss = 0;
int FAR_RIGHT;
if ( !m_iShowscoresHeld && gHUD.m_Health.m_iHealth > 0 && !gHUD.m_iIntermission )
return 1;
GetAllPlayersInfo();
// Packetloss removed on Kelly 'shipping nazi' Bailey's orders
if ( cl_showpacketloss && cl_showpacketloss->value && ( ScreenWidth >= 400 ) )
{
can_show_packetloss = 1;
SCOREBOARD_WIDTH = 400;
}
else
{
SCOREBOARD_WIDTH = 320;
}
// just sort the list on the fly
// list is sorted first by frags, then by deaths
float list_slot = 0;
int xpos_rel = (ScreenWidth - SCOREBOARD_WIDTH) / 2;
// print the heading line
int ypos = ROW_RANGE_MIN + (list_slot * ROW_GAP);
int xpos = NAME_RANGE_MIN + xpos_rel;
if ( !gHUD.m_Teamplay )
gHUD.DrawHudString( xpos, ypos, NAME_RANGE_MAX + xpos_rel, "Player", 255, 140, 0 );
else
gHUD.DrawHudString( xpos, ypos, NAME_RANGE_MAX + xpos_rel, "Teams", 255, 140, 0 );
gHUD.DrawHudStringReverse( KILLS_RANGE_MAX + xpos_rel, ypos, 0, "kills", 255, 140, 0 );
gHUD.DrawHudString( DIVIDER_POS + xpos_rel, ypos, ScreenWidth, "/", 255, 140, 0 );
gHUD.DrawHudString( DEATHS_RANGE_MIN + xpos_rel + 5, ypos, ScreenWidth, "deaths", 255, 140, 0 );
gHUD.DrawHudString( PING_RANGE_MAX + xpos_rel - 35, ypos, ScreenWidth, "latency", 255, 140, 0 );
if ( can_show_packetloss )
{
gHUD.DrawHudString( PL_RANGE_MAX + xpos_rel - 35, ypos, ScreenWidth, "pkt loss", 255, 140, 0 );
}
FAR_RIGHT = can_show_packetloss ? PL_RANGE_MAX : PING_RANGE_MAX;
FAR_RIGHT += 5;
list_slot += 1.2;
ypos = ROW_RANGE_MIN + (list_slot * ROW_GAP);
xpos = NAME_RANGE_MIN + xpos_rel;
FillRGBA( xpos - 5, ypos, FAR_RIGHT, 1, 255, 140, 0, 255); // draw the seperator line
list_slot += 0.8;
if ( !gHUD.m_Teamplay )
{
// it's not teamplay, so just draw a simple player list
DrawPlayers( xpos_rel, list_slot );
return 1;
}
// clear out team scores
for ( int i = 1; i <= m_iNumTeams; i++ )
{
if ( !g_TeamInfo[i].scores_overriden )
g_TeamInfo[i].frags = g_TeamInfo[i].deaths = 0;
g_TeamInfo[i].ping = g_TeamInfo[i].packetloss = 0;
}
// recalc the team scores, then draw them
for ( i = 1; i < MAX_PLAYERS; i++ )
{
if ( g_PlayerInfoList[i].name == NULL )
continue; // empty player slot, skip
if ( g_PlayerExtraInfo[i].teamname[0] == 0 )
continue; // skip over players who are not in a team
// find what team this player is in
for ( int j = 1; j <= m_iNumTeams; j++ )
{
if ( !stricmp( g_PlayerExtraInfo[i].teamname, g_TeamInfo[j].name ) )
break;
}
if ( j > m_iNumTeams ) // player is not in a team, skip to the next guy
continue;
if ( !g_TeamInfo[j].scores_overriden )
{
g_TeamInfo[j].frags += g_PlayerExtraInfo[i].frags;
g_TeamInfo[j].deaths += g_PlayerExtraInfo[i].deaths;
}
g_TeamInfo[j].ping += g_PlayerInfoList[i].ping;
g_TeamInfo[j].packetloss += g_PlayerInfoList[i].packetloss;
if ( g_PlayerInfoList[i].thisplayer )
g_TeamInfo[j].ownteam = TRUE;
else
g_TeamInfo[j].ownteam = FALSE;
}
// find team ping/packetloss averages
for ( i = 1; i <= m_iNumTeams; i++ )
{
g_TeamInfo[i].already_drawn = FALSE;
if ( g_TeamInfo[i].players > 0 )
{
g_TeamInfo[i].ping /= g_TeamInfo[i].players; // use the average ping of all the players in the team as the teams ping
g_TeamInfo[i].packetloss /= g_TeamInfo[i].players; // use the average ping of all the players in the team as the teams ping
}
}
// Draw the teams
while ( 1 )
{
int highest_frags = -99999; int lowest_deaths = 99999;
int best_team = 0;
for ( i = 1; i <= m_iNumTeams; i++ )
{
if ( g_TeamInfo[i].players < 0 )
continue;
if ( !g_TeamInfo[i].already_drawn && g_TeamInfo[i].frags >= highest_frags )
{
if ( g_TeamInfo[i].frags > highest_frags || g_TeamInfo[i].deaths < lowest_deaths )
{
best_team = i;
lowest_deaths = g_TeamInfo[i].deaths;
highest_frags = g_TeamInfo[i].frags;
}
}
}
// draw the best team on the scoreboard
if ( !best_team )
break;
// draw out the best team
team_info_t *team_info = &g_TeamInfo[best_team];
ypos = ROW_RANGE_MIN + (list_slot * ROW_GAP);
// check we haven't drawn too far down
if ( ypos > ROW_RANGE_MAX ) // don't draw to close to the lower border
break;
xpos = NAME_RANGE_MIN + xpos_rel;
int r = 255, g = 225, b = 55; // draw the stuff kinda yellowish
if ( team_info->ownteam ) // if it is their team, draw the background different color
{
// overlay the background in blue, then draw the score text over it
FillRGBA( NAME_RANGE_MIN + xpos_rel - 5, ypos, FAR_RIGHT, ROW_GAP, 0, 0, 255, 70 );
}
// draw their name (left to right)
gHUD.DrawHudString( xpos, ypos, NAME_RANGE_MAX + xpos_rel, team_info->name, r, g, b );
// draw kills (right to left)
xpos = KILLS_RANGE_MAX + xpos_rel;
gHUD.DrawHudNumberString( xpos, ypos, KILLS_RANGE_MIN + xpos_rel, team_info->frags, r, g, b );
// draw divider
xpos = DIVIDER_POS + xpos_rel;
gHUD.DrawHudString( xpos, ypos, xpos + 20, "/", r, g, b );
// draw deaths
xpos = DEATHS_RANGE_MAX + xpos_rel;
gHUD.DrawHudNumberString( xpos, ypos, DEATHS_RANGE_MIN + xpos_rel, team_info->deaths, r, g, b );
// draw ping
// draw ping & packetloss
static char buf[64];
sprintf( buf, "%d", team_info->ping );
xpos = ((PING_RANGE_MAX - PING_RANGE_MIN) / 2) + PING_RANGE_MIN + xpos_rel + 25;
UnpackRGB( r, g, b, RGB_YELLOWISH );
gHUD.DrawHudStringReverse( xpos, ypos, xpos - 50, buf, r, g, b );
// Packetloss removed on Kelly 'shipping nazi' Bailey's orders
if ( can_show_packetloss )
{
xpos = ((PL_RANGE_MAX - PL_RANGE_MIN) / 2) + PL_RANGE_MIN + xpos_rel + 25;
sprintf( buf, " %d", team_info->packetloss );
gHUD.DrawHudString( xpos, ypos, xpos+50, buf, r, g, b );
}
team_info->already_drawn = TRUE; // set the already_drawn to be TRUE, so this team won't get drawn again
list_slot++;
// draw all the players that belong to this team, indented slightly
list_slot = DrawPlayers( xpos_rel, list_slot, 10, team_info->name );
}
// draw all the players who are not in a team
list_slot += 0.5;
DrawPlayers( xpos_rel, list_slot, 0, "" );
return 1;
}
// returns the ypos where it finishes drawing
int CHudScoreboard :: DrawPlayers( int xpos_rel, float list_slot, int nameoffset, char *team )
{
int can_show_packetloss = 0;
int FAR_RIGHT;
// Packetloss removed on Kelly 'shipping nazi' Bailey's orders
if ( cl_showpacketloss && cl_showpacketloss->value && ( ScreenWidth >= 400 ) )
{
can_show_packetloss = 1;
SCOREBOARD_WIDTH = 400;
}
else
{
SCOREBOARD_WIDTH = 320;
}
FAR_RIGHT = can_show_packetloss ? PL_RANGE_MAX : PING_RANGE_MAX;
FAR_RIGHT += 5;
// draw the players, in order, and restricted to team if set
while ( 1 )
{
// Find the top ranking player
int highest_frags = -99999; int lowest_deaths = 99999;
int best_player = 0;
for ( int i = 1; i < MAX_PLAYERS; i++ )
{
if ( g_PlayerInfoList[i].name && g_PlayerExtraInfo[i].frags >= highest_frags )
{
if ( !(team && stricmp(g_PlayerExtraInfo[i].teamname, team)) ) // make sure it is the specified team
{
extra_player_info_t *pl_info = &g_PlayerExtraInfo[i];
if ( pl_info->frags > highest_frags || pl_info->deaths < lowest_deaths )
{
best_player = i;
lowest_deaths = pl_info->deaths;
highest_frags = pl_info->frags;
}
}
}
}
if ( !best_player )
break;
// draw out the best player
hud_player_info_t *pl_info = &g_PlayerInfoList[best_player];
int ypos = ROW_RANGE_MIN + (list_slot * ROW_GAP);
// check we haven't drawn too far down
if ( ypos > ROW_RANGE_MAX ) // don't draw to close to the lower border
break;
int xpos = NAME_RANGE_MIN + xpos_rel;
int r = 255, g = 255, b = 255;
if ( best_player == m_iLastKilledBy && m_fLastKillTime && m_fLastKillTime > gHUD.m_flTime )
{
if ( pl_info->thisplayer )
{ // green is the suicide color? i wish this could do grey...
FillRGBA( NAME_RANGE_MIN + xpos_rel - 5, ypos, FAR_RIGHT, ROW_GAP, 80, 155, 0, 70 );
}
else
{ // Highlight the killers name - overlay the background in red, then draw the score text over it
FillRGBA( NAME_RANGE_MIN + xpos_rel - 5, ypos, FAR_RIGHT, ROW_GAP, 255, 0, 0, ((float)15 * (float)(m_fLastKillTime - gHUD.m_flTime)) );
}
}
else if ( pl_info->thisplayer ) // if it is their name, draw it a different color
{
// overlay the background in blue, then draw the score text over it
FillRGBA( NAME_RANGE_MIN + xpos_rel - 5, ypos, FAR_RIGHT, ROW_GAP, 0, 0, 255, 70 );
}
// draw their name (left to right)
gHUD.DrawHudString( xpos + nameoffset, ypos, NAME_RANGE_MAX + xpos_rel, pl_info->name, r, g, b );
// draw kills (right to left)
xpos = KILLS_RANGE_MAX + xpos_rel;
gHUD.DrawHudNumberString( xpos, ypos, KILLS_RANGE_MIN + xpos_rel, g_PlayerExtraInfo[best_player].frags, r, g, b );
// draw divider
xpos = DIVIDER_POS + xpos_rel;
gHUD.DrawHudString( xpos, ypos, xpos + 20, "/", r, g, b );
// draw deaths
xpos = DEATHS_RANGE_MAX + xpos_rel;
gHUD.DrawHudNumberString( xpos, ypos, DEATHS_RANGE_MIN + xpos_rel, g_PlayerExtraInfo[best_player].deaths, r, g, b );
// draw ping & packetloss
static char buf[64];
sprintf( buf, "%d", g_PlayerInfoList[best_player].ping );
xpos = ((PING_RANGE_MAX - PING_RANGE_MIN) / 2) + PING_RANGE_MIN + xpos_rel + 25;
gHUD.DrawHudStringReverse( xpos, ypos, xpos - 50, buf, r, g, b );
// Packetloss removed on Kelly 'shipping nazi' Bailey's orders
if ( can_show_packetloss )
{
if ( g_PlayerInfoList[best_player].packetloss >= 63 )
{
UnpackRGB( r, g, b, RGB_REDISH );
sprintf( buf, " !!!!" );
}
else
{
sprintf( buf, " %d", g_PlayerInfoList[best_player].packetloss );
}
xpos = ((PL_RANGE_MAX - PL_RANGE_MIN) / 2) + PL_RANGE_MIN + xpos_rel + 25;
gHUD.DrawHudString( xpos, ypos, xpos+50, buf, r, g, b );
}
pl_info->name = NULL; // set the name to be NULL, so this client won't get drawn again
list_slot++;
}
return list_slot;
}
void CHudScoreboard :: GetAllPlayersInfo( void )
{
for ( int i = 1; i < MAX_PLAYERS; i++ )
{
GetPlayerInfo( i, &g_PlayerInfoList[i] );
if ( g_PlayerInfoList[i].thisplayer )
m_iPlayerNum = i; // !!!HACK: this should be initialized elsewhere... maybe gotten from the engine
}
}
int CHudScoreboard :: MsgFunc_ScoreInfo( const char *pszName, int iSize, void *pbuf )
{
m_iFlags |= HUD_ACTIVE;
BEGIN_READ( pbuf, iSize );
short cl = READ_BYTE();
short frags = READ_SHORT();
short deaths = READ_SHORT();
short playerclass = READ_SHORT();
short teamnumber = READ_SHORT();
if ( cl > 0 && cl <= MAX_PLAYERS )
{
g_PlayerExtraInfo[cl].frags = frags;
g_PlayerExtraInfo[cl].deaths = deaths;
g_PlayerExtraInfo[cl].playerclass = playerclass;
g_PlayerExtraInfo[cl].teamnumber = teamnumber;
gViewPort->UpdateOnPlayerInfo();
}
return 1;
}
// Message handler for TeamInfo message
// accepts two values:
// byte: client number
// string: client team name
int CHudScoreboard :: MsgFunc_TeamInfo( const char *pszName, int iSize, void *pbuf )
{
BEGIN_READ( pbuf, iSize );
short cl = READ_BYTE();
if ( cl > 0 && cl <= MAX_PLAYERS )
{ // set the players team
strncpy( g_PlayerExtraInfo[cl].teamname, READ_STRING(), MAX_TEAM_NAME );
}
// rebuild the list of teams
// clear out player counts from teams
for ( int i = 1; i <= m_iNumTeams; i++ )
{
g_TeamInfo[i].players = 0;
}
// rebuild the team list
GetAllPlayersInfo();
m_iNumTeams = 0;
for ( i = 1; i < MAX_PLAYERS; i++ )
{
if ( g_PlayerInfoList[i].name == NULL )
continue;
if ( g_PlayerExtraInfo[i].teamname[0] == 0 )
continue; // skip over players who are not in a team
// is this player in an existing team?
for ( int j = 1; j <= m_iNumTeams; j++ )
{
if ( g_TeamInfo[j].name[0] == '\0' )
break;
if ( !stricmp( g_PlayerExtraInfo[i].teamname, g_TeamInfo[j].name ) )
break;
}
if ( j > m_iNumTeams )
{ // they aren't in a listed team, so make a new one
// search through for an empty team slot
for ( int j = 1; j <= m_iNumTeams; j++ )
{
if ( g_TeamInfo[j].name[0] == '\0' )
break;
}
m_iNumTeams = max( j, m_iNumTeams );
strncpy( g_TeamInfo[j].name, g_PlayerExtraInfo[i].teamname, MAX_TEAM_NAME );
g_TeamInfo[j].players = 0;
}
g_TeamInfo[j].players++;
}
// clear out any empty teams
for ( i = 1; i <= m_iNumTeams; i++ )
{
if ( g_TeamInfo[i].players < 1 )
memset( &g_TeamInfo[i], 0, sizeof(team_info_t) );
}
return 1;
}
// Message handler for TeamScore message
// accepts three values:
// string: team name
// short: teams kills
// short: teams deaths
// if this message is never received, then scores will simply be the combined totals of the players.
int CHudScoreboard :: MsgFunc_TeamScore( const char *pszName, int iSize, void *pbuf )
{
BEGIN_READ( pbuf, iSize );
char *TeamName = READ_STRING();
// find the team matching the name
for ( int i = 1; i <= m_iNumTeams; i++ )
{
if ( !stricmp( TeamName, g_TeamInfo[i].name ) )
break;
}
if ( i > m_iNumTeams )
return 1;
// use this new score data instead of combined player scores
g_TeamInfo[i].scores_overriden = TRUE;
g_TeamInfo[i].frags = READ_SHORT();
g_TeamInfo[i].deaths = READ_SHORT();
return 1;
}
void CHudScoreboard :: DeathMsg( int killer, int victim )
{
// if we were the one killed, or the world killed us, set the scoreboard to indicate suicide
if ( victim == m_iPlayerNum || killer == 0 )
{
m_iLastKilledBy = killer ? killer : m_iPlayerNum;
m_fLastKillTime = gHUD.m_flTime + 10; // display who we were killed by for 10 seconds
if ( killer == m_iPlayerNum )
m_iLastKilledBy = m_iPlayerNum;
}
}
void CHudScoreboard :: UserCmd_ShowScores( void )
{
m_iShowscoresHeld = TRUE;
}
void CHudScoreboard :: UserCmd_HideScores( void )
{
m_iShowscoresHeld = FALSE;
}

View file

@ -106,8 +106,9 @@ int CHudStatusIcons::MsgFunc_StatusIcon( const char *pszName, int iSize, void *p
// add the icon to the icon list, and set it's drawing color
void CHudStatusIcons::EnableIcon( char *pszIconName, unsigned char red, unsigned char green, unsigned char blue )
{
int i;
// check to see if the sprite is in the current list
for ( int i = 0; i < MAX_ICONSPRITES; i++ )
for ( i = 0; i < MAX_ICONSPRITES; i++ )
{
if ( !stricmp( m_IconList[i].szSpriteName, pszIconName ) )
break;
@ -155,7 +156,7 @@ void CHudStatusIcons::DisableIcon( char *pszIconName )
if ( !stricmp( m_IconList[i].szSpriteName, pszIconName ) )
{
// clear the item from the list
memset( &m_IconList[i], 0, sizeof icon_sprite_t );
memset( &m_IconList[i], 0, sizeof(icon_sprite_t) );
return;
}
}

View file

@ -1,6 +1,6 @@
/***
*
* Copyright (c) 1996-2002, Valve LLC. All rights reserved.
* Copyright (c) 1999, Valve LLC. All rights reserved.
*
* This product contains software technology licensed from Id
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
@ -29,7 +29,11 @@
DECLARE_MESSAGE( m_StatusBar, StatusText );
DECLARE_MESSAGE( m_StatusBar, StatusValue );
#ifdef _TFC
#define STATUSBAR_ID_LINE 2
#else
#define STATUSBAR_ID_LINE 1
#endif
float *GetClientColor( int clientIndex );
extern float g_ColorYellow[3];
@ -138,7 +142,7 @@ void CHudStatusBar :: ParseStatusString( int line_num )
switch ( valtype )
{
case 'p': // player name
GetPlayerInfo( indexval, &g_PlayerInfoList[indexval] );
gEngfuncs.pfnGetPlayerInfo( indexval, &g_PlayerInfoList[indexval] );
if ( g_PlayerInfoList[indexval].name != NULL )
{
strncpy( szRepString, g_PlayerInfoList[indexval].name, MAX_PLAYER_NAME_LENGTH );
@ -184,15 +188,15 @@ int CHudStatusBar :: Draw( float fTime )
m_bReparseString = FALSE;
}
int Y_START = ScreenHeight - YRES(32 + 4);
int Y_START = ScreenHeight - 52;
// Draw the status bar lines
for ( int i = 0; i < MAX_STATUSBAR_LINES; i++ )
{
int TextHeight, TextWidth;
GetConsoleStringSize( m_szStatusBar[i], &TextWidth, &TextHeight );
int x = 4;
int x = 8;
int y = Y_START - ( 4 + TextHeight * i ); // draw along bottom of screen
// let user set status ID bar centering
@ -229,17 +233,13 @@ int CHudStatusBar :: MsgFunc_StatusText( const char *pszName, int iSize, void *p
int line = READ_BYTE();
if ( line < 0 || line >= MAX_STATUSBAR_LINES )
if ( line < 0 || line > MAX_STATUSBAR_LINES )
return 1;
strncpy( m_szStatusText[line], READ_STRING(), MAX_STATUSTEXT_LENGTH );
m_szStatusText[line][MAX_STATUSTEXT_LENGTH-1] = 0; // ensure it's null terminated ( strncpy() won't null terminate if read string too long)
if ( m_szStatusText[0] == 0 )
m_iFlags &= ~HUD_ACTIVE;
else
m_iFlags |= HUD_ACTIVE; // we have status text, so turn on the status bar
m_iFlags |= HUD_ACTIVE;
m_bReparseString = TRUE;
return 1;
@ -254,7 +254,7 @@ int CHudStatusBar :: MsgFunc_StatusValue( const char *pszName, int iSize, void *
BEGIN_READ( pbuf, iSize );
int index = READ_BYTE();
if ( index < 1 || index >= MAX_STATUSBAR_VALUES )
if ( index < 1 || index > MAX_STATUSBAR_VALUES )
return 1; // index out of range
m_iStatusValues[index] = READ_SHORT();

View file

@ -163,22 +163,23 @@ int CHudTextMessage::MsgFunc_TextMsg( const char *pszName, int iSize, void *pbuf
int msg_dest = READ_BYTE();
static char szBuf[6][128];
#define MSG_BUF_SIZE 128
static char szBuf[6][MSG_BUF_SIZE];
char *msg_text = LookupString( READ_STRING(), &msg_dest );
msg_text = strcpy( szBuf[0], msg_text );
msg_text = safe_strcpy( szBuf[0], msg_text , MSG_BUF_SIZE);
// keep reading strings and using C format strings for subsituting the strings into the localised text string
char *sstr1 = LookupString( READ_STRING() );
sstr1 = strcpy( szBuf[1], sstr1 );
sstr1 = safe_strcpy( szBuf[1], sstr1 , MSG_BUF_SIZE);
StripEndNewlineFromString( sstr1 ); // these strings are meant for subsitution into the main strings, so cull the automatic end newlines
char *sstr2 = LookupString( READ_STRING() );
sstr2 = strcpy( szBuf[2], sstr2 );
sstr2 = safe_strcpy( szBuf[2], sstr2 , MSG_BUF_SIZE);
StripEndNewlineFromString( sstr2 );
char *sstr3 = LookupString( READ_STRING() );
sstr3 = strcpy( szBuf[3], sstr3 );
sstr3 = safe_strcpy( szBuf[3], sstr3 , MSG_BUF_SIZE);
StripEndNewlineFromString( sstr3 );
char *sstr4 = LookupString( READ_STRING() );
sstr4 = strcpy( szBuf[4], sstr4 );
sstr4 = safe_strcpy( szBuf[4], sstr4 , MSG_BUF_SIZE);
StripEndNewlineFromString( sstr4 );
char *psz = szBuf[5];
@ -188,23 +189,23 @@ int CHudTextMessage::MsgFunc_TextMsg( const char *pszName, int iSize, void *pbuf
switch ( msg_dest )
{
case HUD_PRINTCENTER:
sprintf( psz, msg_text, sstr1, sstr2, sstr3, sstr4 );
safe_sprintf( psz, MSG_BUF_SIZE, msg_text, sstr1, sstr2, sstr3, sstr4 );
CenterPrint( ConvertCRtoNL( psz ) );
break;
case HUD_PRINTNOTIFY:
psz[0] = 1; // mark this message to go into the notify buffer
sprintf( psz+1, msg_text, sstr1, sstr2, sstr3, sstr4 );
safe_sprintf( psz+1, MSG_BUF_SIZE, msg_text, sstr1, sstr2, sstr3, sstr4 );
ConsolePrint( ConvertCRtoNL( psz ) );
break;
case HUD_PRINTTALK:
sprintf( psz, msg_text, sstr1, sstr2, sstr3, sstr4 );
safe_sprintf( psz, MSG_BUF_SIZE, msg_text, sstr1, sstr2, sstr3, sstr4 );
gHUD.m_SayText.SayTextPrint( ConvertCRtoNL( psz ), 128 );
break;
case HUD_PRINTCONSOLE:
sprintf( psz, msg_text, sstr1, sstr2, sstr3, sstr4 );
safe_sprintf( psz, MSG_BUF_SIZE, msg_text, sstr1, sstr2, sstr3, sstr4 );
ConsolePrint( ConvertCRtoNL( psz ) );
break;
}

View file

@ -16,80 +16,11 @@
#include "entity_state.h"
#include "cl_entity.h"
#include "triangleapi.h"
#include "Exports.h"
#define DLLEXPORT __declspec( dllexport )
extern "C"
{
void DLLEXPORT HUD_DrawNormalTriangles( void );
void DLLEXPORT HUD_DrawTransparentTriangles( void );
};
//#define TEST_IT
#if defined( TEST_IT )
/*
=================
Draw_Triangles
Example routine. Draws a sprite offset from the player origin.
=================
*/
void Draw_Triangles( void )
{
cl_entity_t *player;
vec3_t org;
// Load it up with some bogus data
player = gEngfuncs.GetLocalPlayer();
if ( !player )
return;
org = player->origin;
org.x += 50;
org.y += 50;
if (gHUD.m_hsprCursor == 0)
{
char sz[256];
sprintf( sz, "sprites/cursor.spr" );
gHUD.m_hsprCursor = SPR_Load( sz );
}
if ( !gEngfuncs.pTriAPI->SpriteTexture( (struct model_s *)gEngfuncs.GetSpritePointer( gHUD.m_hsprCursor ), 0 ))
{
return;
}
// Create a triangle, sigh
gEngfuncs.pTriAPI->RenderMode( kRenderNormal );
gEngfuncs.pTriAPI->CullFace( TRI_NONE );
gEngfuncs.pTriAPI->Begin( TRI_QUADS );
// Overload p->color with index into tracer palette, p->packedColor with brightness
gEngfuncs.pTriAPI->Color4f( 1.0, 1.0, 1.0, 1.0 );
// UNDONE: This gouraud shading causes tracers to disappear on some cards (permedia2)
gEngfuncs.pTriAPI->Brightness( 1 );
gEngfuncs.pTriAPI->TexCoord2f( 0, 0 );
gEngfuncs.pTriAPI->Vertex3f( org.x, org.y, org.z );
gEngfuncs.pTriAPI->Brightness( 1 );
gEngfuncs.pTriAPI->TexCoord2f( 0, 1 );
gEngfuncs.pTriAPI->Vertex3f( org.x, org.y + 50, org.z );
gEngfuncs.pTriAPI->Brightness( 1 );
gEngfuncs.pTriAPI->TexCoord2f( 1, 1 );
gEngfuncs.pTriAPI->Vertex3f( org.x + 50, org.y + 50, org.z );
gEngfuncs.pTriAPI->Brightness( 1 );
gEngfuncs.pTriAPI->TexCoord2f( 1, 0 );
gEngfuncs.pTriAPI->Vertex3f( org.x + 50, org.y, org.z );
gEngfuncs.pTriAPI->End();
gEngfuncs.pTriAPI->RenderMode( kRenderNormal );
}
#endif
#include "particleman.h"
#include "tri.h"
extern IParticleMan *g_pParticleMan;
/*
=================
@ -98,16 +29,17 @@ HUD_DrawNormalTriangles
Non-transparent triangles-- add them here
=================
*/
void DLLEXPORT HUD_DrawNormalTriangles( void )
void CL_DLLEXPORT HUD_DrawNormalTriangles( void )
{
// RecClDrawNormalTriangles();
gHUD.m_Spectator.DrawOverview();
#if defined( TEST_IT )
// Draw_Triangles();
#endif
}
#if defined( _TFC )
void RunEventList( void );
#endif
/*
=================
HUD_DrawTransparentTriangles
@ -115,10 +47,14 @@ HUD_DrawTransparentTriangles
Render any triangles with transparent rendermode needs here
=================
*/
void DLLEXPORT HUD_DrawTransparentTriangles( void )
void CL_DLLEXPORT HUD_DrawTransparentTriangles( void )
{
// RecClDrawTransparentTriangles();
#if defined( TEST_IT )
// Draw_Triangles();
#if defined( _TFC )
RunEventList();
#endif
}
if ( g_pParticleMan )
g_pParticleMan->Update();
}

13
cl_dll/tri.h Normal file
View file

@ -0,0 +1,13 @@
#ifndef TRI_H
#define TRI_H
#include "particleman.h"
extern IParticleMan *g_pParticleMan;
#endif //TRI_H

View file

@ -18,9 +18,9 @@
// implementation of class-less helper functions
//
#include "STDIO.H"
#include "STDLIB.H"
#include "MATH.H"
#include "stdio.h"
#include "stdlib.h"
#include "math.h"
#include "hud.h"
#include "cl_util.h"

View file

@ -17,13 +17,13 @@
//
// Misc C-runtime library headers
#include "STDIO.H"
#include "STDLIB.H"
#include "MATH.H"
#include "stdio.h"
#include "stdlib.h"
#include "math.h"
// Header file containing definition of globalvars_t and entvars_t
typedef int func_t; //
typedef int string_t; // from engine's pr_comp.h;
typedef unsigned int func_t; //
typedef unsigned int string_t; // from engine's pr_comp.h;
typedef float vec_t; // needed before including progdefs.h
//=========================================================
@ -61,6 +61,7 @@ public:
vec_t x, y;
};
#undef DotProduct
inline float DotProduct(const Vector2D& a, const Vector2D& b) { return( a.x*b.x + a.y*b.y ); }
inline Vector2D operator*(float fl, const Vector2D& v) { return v * fl; }
@ -118,4 +119,7 @@ inline Vector operator*(float fl, const Vector& v) { return v * fl; }
inline float DotProduct(const Vector& a, const Vector& b) { return(a.x*b.x+a.y*b.y+a.z*b.z); }
inline Vector CrossProduct(const Vector& a, const Vector& b) { return Vector( a.y*b.z - a.z*b.y, a.z*b.x - a.x*b.z, a.x*b.y - a.y*b.x ); }
#ifndef DID_VEC3_T_DEFINE
#define DID_VEC3_T_DEFINE
#define vec3_t Vector
#endif

View file

@ -102,6 +102,7 @@ CClassMenuPanel::CClassMenuPanel(int iTrans, int iRemoveMe, int x,int y,int wide
m_pScrollPanel->validate();
// Create the Class buttons
#ifdef _TFC
for (int i = 0; i <= PC_RANDOM; i++)
{
char sz[256];
@ -153,7 +154,7 @@ CClassMenuPanel::CClassMenuPanel(int iTrans, int iRemoveMe, int x,int y,int wide
pNameLabel->setBgColor( r, g, b, a );
pNameLabel->setContentAlignment( vgui::Label::a_west );
//pNameLabel->setBorder(new LineBorder());
pNameLabel->setText(localName);
pNameLabel->setText( "%s", localName);
// Create the Class Image
if ( bShowClassGraphic )
@ -239,7 +240,7 @@ CClassMenuPanel::CClassMenuPanel(int iTrans, int iRemoveMe, int x,int y,int wide
//m_pClassInfoPanel[i]->setBorder(new LineBorder());
}
#endif
// Create the Cancel button
m_pCancelButton = new CommandButton( gHUD.m_TextMessage.BufferedLocaliseTextString( "#Menu_Cancel" ), CLASSMENU_TOPLEFT_BUTTON_X, 0, CLASSMENU_BUTTON_SIZE_X, CLASSMENU_BUTTON_SIZE_Y);
m_pCancelButton->setParent( this );
@ -260,6 +261,7 @@ void CClassMenuPanel::Update()
int iYPos = CLASSMENU_TOPLEFT_BUTTON_Y;
// Cycle through the rest of the buttons
#ifdef _TFC
for (int i = 0; i <= PC_RANDOM; i++)
{
bool bCivilian = (gViewPort->GetValidClasses(g_iTeamNumber) == -1);
@ -318,7 +320,7 @@ void CClassMenuPanel::Update()
char sz[256];
sprintf(sz, m_sPlayersOnTeamString, iTotal);
m_pPlayers[i]->setText( sz );
m_pPlayers[i]->setText( "%s", sz );
// Set the text color to the teamcolor
m_pPlayers[i]->setFgColor( iTeamColors[g_iTeamNumber % iNumberOfTeamColors][0],
@ -346,6 +348,7 @@ void CClassMenuPanel::Update()
}
}
}
#endif
// If the player already has a class, make the cancel button visible
if ( g_iPlayerClass )
@ -413,6 +416,7 @@ void CClassMenuPanel::Initialize( void )
void CClassMenuPanel::SetActiveInfo( int iInput )
{
// Remove all the Info panels and bring up the specified one
#ifdef _TFC
for (int i = 0; i <= PC_RANDOM; i++)
{
m_pButtons[i]->setArmed( false );
@ -420,6 +424,7 @@ void CClassMenuPanel::SetActiveInfo( int iInput )
}
if ( iInput > PC_RANDOM || iInput < 0 )
#endif
iInput = 0;
m_pButtons[iInput]->setArmed( true );

View file

@ -1,4 +1,4 @@
//=========== (C) Copyright 1996-2002 Valve, L.L.C. All rights reserved. ===========
//=========== (C) Copyright 1999 Valve, L.L.C. All rights reserved. ===========
//
// The copyright to the contents herein is the property of Valve, L.L.C.
// The contents may be used and/or copied only with the written permission of
@ -32,7 +32,7 @@
#include "vgui_int.h"
#include "vgui_TeamFortressViewport.h"
#include "vgui_ServerBrowser.h"
#include "..\game_shared\vgui_LoadTGA.h"
#include "vgui_loadtga.h"
// Arrow filenames
char *sArrowFilenames[] =
@ -305,15 +305,21 @@ int ClassButton::IsNotValid()
}
// Is it an illegal class?
#ifdef _TFC
if ((gViewPort->GetValidClasses(0) & sTFValidClassInts[ m_iPlayerClass ]) || (gViewPort->GetValidClasses(g_iTeamNumber) & sTFValidClassInts[ m_iPlayerClass ]))
return true;
#endif
// Only check current class if they've got autokill on
bool bAutoKill = CVAR_GET_FLOAT( "hud_classautokill" ) != 0;
if ( bAutoKill )
{
// Is it the player's current class?
if ( (gViewPort->IsRandomPC() && m_iPlayerClass == PC_RANDOM) || (!gViewPort->IsRandomPC() && (m_iPlayerClass == g_iPlayerClass)) )
if (
#ifdef _TFC
(gViewPort->IsRandomPC() && m_iPlayerClass == PC_RANDOM) ||
#endif
(!gViewPort->IsRandomPC() && (m_iPlayerClass == g_iPlayerClass)) )
return true;
}
@ -529,8 +535,13 @@ void CMenuHandler_StringCommandClassSelect::actionPerformed(Panel* panel)
{
CMenuHandler_StringCommand::actionPerformed( panel );
// THIS IS NOW BEING DONE ON THE TFC SERVER TO AVOID KILLING SOMEONE THEN
// HAVE THE SERVER SAY "SORRY...YOU CAN'T BE THAT CLASS".
#if !defined _TFC
bool bAutoKill = CVAR_GET_FLOAT( "hud_classautokill" ) != 0;
if ( bAutoKill && g_iPlayerClass != 0 )
gEngfuncs.pfnClientCmd("kill");
#endif
}

View file

@ -99,7 +99,7 @@ CMessageWindowPanel::CMessageWindowPanel( const char *szMOTD, const char *szTitl
pSchemes->getBgColor( hTitleScheme, r, g, b, a );
pLabel->setBgColor( r, g, b, a );
pLabel->setContentAlignment( vgui::Label::a_west );
pLabel->setText(szTitle);
pLabel->setText( "%s", szTitle);
// Create the Scroll panel
ScrollPanel *pScrollPanel = new CTFScrollPanel( iXPos + XRES(16), iYPos + MOTD_TITLE_Y*2 + YRES(16), iXSize - XRES(32), iYSize - (YRES(48) + BUTTON_SIZE_Y*2) );
@ -120,7 +120,7 @@ CMessageWindowPanel::CMessageWindowPanel( const char *szMOTD, const char *szTitl
pText->setFgColor( r, g, b, a );
pSchemes->getBgColor( hMOTDText, r, g, b, a );
pText->setBgColor( r, g, b, a );
pText->setText(szMOTD);
pText->setText( szMOTD);
// Get the total size of the MOTD text and resize the text panel
int iScrollSizeX, iScrollSizeY;

View file

@ -395,7 +395,19 @@ buildDefaultFont:
if(g_CV_BitmapFonts && g_CV_BitmapFonts->value)
{
sprintf(fontFilename, "gfx\\vgui\\fonts\\%d_%s.tga", m_xRes, m_pSchemeList[i].schemeName);
int fontRes = 640;
if ( m_xRes >= 1600 )
fontRes = 1600;
else if ( m_xRes >= 1280 )
fontRes = 1280;
else if ( m_xRes >= 1152 )
fontRes = 1152;
else if ( m_xRes >= 1024 )
fontRes = 1024;
else if ( m_xRes >= 800 )
fontRes = 800;
sprintf(fontFilename, "gfx\\vgui\\fonts\\%d_%s.tga", fontRes, m_pSchemeList[i].schemeName);
pFontData = gEngfuncs.COM_LoadFile( fontFilename, 5, &fontFileLength );
if(!pFontData)
gEngfuncs.Con_Printf("Missing bitmap font: %s\n", fontFilename);

View file

@ -1,4 +1,4 @@
//=========== (C) Copyright 1996-2002 Valve, L.L.C. All rights reserved. ===========
//=========== (C) Copyright 1999 Valve, L.L.C. All rights reserved. ===========
//
// The copyright to the contents herein is the property of Valve, L.L.C.
// The contents may be used and/or copied only with the written permission of
@ -26,12 +26,13 @@
#include "cl_entity.h"
#include "vgui_TeamFortressViewport.h"
#include "vgui_ScorePanel.h"
#include "..\game_shared\vgui_helpers.h"
#include "..\game_shared\vgui_loadtga.h"
#include "vgui_helpers.h"
#include "vgui_loadtga.h"
#include "voice_status.h"
#include "vgui_SpectatorPanel.h"
hud_player_info_t g_PlayerInfoList[MAX_PLAYERS+1]; // player info from the engine
extra_player_info_t g_PlayerExtraInfo[MAX_PLAYERS+1]; // additional player info sent directly to the client dll
extern hud_player_info_t g_PlayerInfoList[MAX_PLAYERS+1]; // player info from the engine
extern extra_player_info_t g_PlayerExtraInfo[MAX_PLAYERS+1]; // additional player info sent directly to the client dll
team_info_t g_TeamInfo[MAX_TEAMS+1];
int g_IsSpectator[MAX_PLAYERS+1];
@ -56,7 +57,7 @@ public:
SBColumnInfo g_ColumnInfo[NUM_COLUMNS] =
{
{NULL, 24, Label::a_east},
{NULL, 24, Label::a_east}, // tracker column
{NULL, 140, Label::a_east}, // name
{NULL, 56, Label::a_east}, // class
{"#SCORE", 40, Label::a_east},
@ -102,6 +103,8 @@ ScorePanel::ScorePanel(int x,int y,int wide,int tall) : Panel(x,y,wide,tall)
m_pCurrentHighlightLabel = NULL;
m_iHighlightRow = -1;
//m_pTrackerIcon = vgui_LoadTGANoInvertAlpha("gfx/vgui/640_scoreboardtracker.tga");
// Initialize the top title.
m_TitleLabel.setFont(tfont);
m_TitleLabel.setText("");
@ -149,6 +152,7 @@ ScorePanel::ScorePanel(int x,int y,int wide,int tall) : Panel(x,y,wide,tall)
}
else if (i == 0)
{
// tracker icon cell
xwide -= 8;
}
}
@ -202,7 +206,6 @@ ScorePanel::ScorePanel(int x,int y,int wide,int tall) : Panel(x,y,wide,tall)
}
pGridRow->setBgColor(0,0,0,255);
// pGridRow->SetSpacing(2, 0);
pGridRow->SetSpacing(0, 0);
pGridRow->CopyColumnWidths(&m_HeaderGrid);
pGridRow->AutoSetRowHeights();
@ -249,7 +252,7 @@ void ScorePanel::Initialize( void )
bool HACK_GetPlayerUniqueID( int iPlayer, char playerID[16] )
{
return !!gEngfuncs.GetPlayerUniqueID( iPlayer, playerID );
return !!gEngfuncs.GetPlayerUniqueID( iPlayer, playerID ); // TODO remove after testing
}
//-----------------------------------------------------------------------------
@ -257,6 +260,8 @@ bool HACK_GetPlayerUniqueID( int iPlayer, char playerID[16] )
//-----------------------------------------------------------------------------
void ScorePanel::Update()
{
int i;
// Set the title
if (gViewPort->m_szServerName)
{
@ -269,10 +274,13 @@ void ScorePanel::Update()
gViewPort->GetAllPlayersInfo();
// Clear out sorts
for (int i = 0; i < NUM_ROWS; i++)
for (i = 0; i < NUM_ROWS; i++)
{
m_iSortedRows[i] = 0;
m_iIsATeam[i] = TEAM_NO;
}
for (i = 0; i < MAX_PLAYERS; i++)
{
m_bHasBeenSorted[i] = false;
}
@ -303,7 +311,8 @@ void ScorePanel::Update()
void ScorePanel::SortTeams()
{
// clear out team scores
for ( int i = 1; i <= m_iNumTeams; i++ )
int i;
for ( i = 1; i <= m_iNumTeams; i++ )
{
if ( !g_TeamInfo[i].scores_overriden )
g_TeamInfo[i].frags = g_TeamInfo[i].deaths = 0;
@ -320,7 +329,8 @@ void ScorePanel::SortTeams()
continue; // skip over players who are not in a team
// find what team this player is in
for ( int j = 1; j <= m_iNumTeams; j++ )
int j;
for ( j = 1; j <= m_iNumTeams; j++ )
{
if ( !stricmp( g_PlayerExtraInfo[i].teamname, g_TeamInfo[j].name ) )
break;
@ -462,7 +472,8 @@ void ScorePanel::SortPlayers( int iTeam, char *team )
void ScorePanel::RebuildTeams()
{
// clear out player counts from teams
for ( int i = 1; i <= m_iNumTeams; i++ )
int i;
for ( i = 1; i <= m_iNumTeams; i++ )
{
g_TeamInfo[i].players = 0;
}
@ -479,7 +490,8 @@ void ScorePanel::RebuildTeams()
continue; // skip over players who are not in a team
// is this player in an existing team?
for ( int j = 1; j <= m_iNumTeams; j++ )
int j;
for ( j = 1; j <= m_iNumTeams; j++ )
{
if ( g_TeamInfo[j].name[0] == '\0' )
break;
@ -540,8 +552,8 @@ void ScorePanel::FillGrid()
}
bool bNextRowIsGap = false;
for(int row=0; row < NUM_ROWS; row++)
int row;
for(row=0; row < NUM_ROWS; row++)
{
CGrid *pGridRow = &m_PlayerGrids[row];
pGridRow->SetRowUnderline(0, false, 0, 0, 0, 0, 0);
@ -742,15 +754,24 @@ void ScorePanel::FillGrid()
switch (col)
{
case COLUMN_NAME:
/*
if (g_pTrackerUser)
{
int playerSlot = m_iSortedRows[row];
int trackerID = gEngfuncs.GetTrackerIDForPlayer(playerSlot);
const char *trackerName = g_pTrackerUser->GetUserName(trackerID);
if (trackerName && *trackerName)
{
sprintf(sz, " (%s)", trackerName);
pLabel->setText2(sz);
}
}
*/
sprintf(sz, "%s ", pl_info->name);
break;
case COLUMN_VOICE:
sz[0] = 0;
// in HLTV mode allow spectator to turn on/off commentator voice
if (!pl_info->thisplayer || gEngfuncs.IsSpectateOnly() )
{
GetClientVoiceMgr()->UpdateSpeakerImage(pLabel, m_iSortedRows[row]);
}
GetClientVoiceMgr()->UpdateSpeakerImage(pLabel, m_iSortedRows[row]);
break;
case COLUMN_CLASS:
// No class for other team's members (unless allied or spectator)
@ -759,6 +780,11 @@ void ScorePanel::FillGrid()
// Don't show classes if this client hasnt picked a team yet
if ( g_iTeamNumber == 0 )
bShowClass = false;
#ifdef _TFC
// in TFC show all classes in spectator mode
if ( g_iUser1 )
bShowClass = true;
#endif
if (bShowClass)
{
@ -782,7 +808,36 @@ void ScorePanel::FillGrid()
break;
case COLUMN_TRACKER:
/*
if (g_pTrackerUser)
{
int playerSlot = m_iSortedRows[row];
int trackerID = gEngfuncs.GetTrackerIDForPlayer(playerSlot);
if (g_pTrackerUser->IsFriend(trackerID) && trackerID != g_pTrackerUser->GetTrackerID())
{
pLabel->setImage(m_pTrackerIcon);
pLabel->setFgColorAsImageColor(false);
m_pTrackerIcon->setColor(Color(255, 255, 255, 0));
}
}
*/
break;
#ifdef _TFC
case COLUMN_KILLS:
if (g_PlayerExtraInfo[ m_iSortedRows[row] ].teamnumber)
sprintf(sz, "%d", g_PlayerExtraInfo[ m_iSortedRows[row] ].frags );
break;
case COLUMN_DEATHS:
if (g_PlayerExtraInfo[ m_iSortedRows[row] ].teamnumber)
sprintf(sz, "%d", g_PlayerExtraInfo[ m_iSortedRows[row] ].deaths );
break;
case COLUMN_LATENCY:
if (g_PlayerExtraInfo[ m_iSortedRows[row] ].teamnumber)
sprintf(sz, "%d", g_PlayerInfoList[ m_iSortedRows[row] ].ping );
break;
#else
case COLUMN_KILLS:
sprintf(sz, "%d", g_PlayerExtraInfo[ m_iSortedRows[row] ].frags );
break;
@ -792,6 +847,7 @@ void ScorePanel::FillGrid()
case COLUMN_LATENCY:
sprintf(sz, "%d", g_PlayerInfoList[ m_iSortedRows[row] ].ping );
break;
#endif
default:
break;
}

View file

@ -1,4 +1,4 @@
//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============
//========= Copyright <EFBFBD> 1996-2002, Valve LLC, All rights reserved. ============
//
// Purpose:
//
@ -14,7 +14,7 @@
#include<VGUI_TextGrid.h>
#include<VGUI_Label.h>
#include<VGUI_TextImage.h>
#include "..\game_shared\vgui_listbox.h"
#include "../game_shared/vgui_listbox.h"
#include <ctype.h>
@ -222,8 +222,8 @@ private:
class ScoreTablePanel;
#include "..\game_shared\vgui_grid.h"
#include "..\game_shared\vgui_defaultinputsignal.h"
#include "../game_shared/vgui_grid.h"
#include "../game_shared/vgui_defaultinputsignal.h"
//-----------------------------------------------------------------------------
// Purpose: Scoreboard back panel
@ -304,7 +304,7 @@ public:
virtual void mousePressed(MouseCode code, Panel* panel);
virtual void cursorMoved(int x, int y, Panel *panel);
friend CLabelHeader;
friend class CLabelHeader;
};
#endif

View file

@ -115,7 +115,7 @@ public:
void DoCancel( void )
{
ClientCmd( "togglebrowser\n" );
EngineClientCmd( "togglebrowser\n" );
}
void DoConnect( void )
@ -133,7 +133,7 @@ public:
sprintf( sz, "connect %s\n", address );
ClientCmd( sz );
EngineClientCmd( sz );
DoCancel();
}

View file

@ -1,10 +1,3 @@
//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================
// vgui_SpectatorPanel.cpp: implementation of the SpectatorPanel class.
//
//////////////////////////////////////////////////////////////////////
@ -17,17 +10,34 @@
#include "pm_shared.h"
#include "vgui_TeamFortressViewport.h"
#include "vgui_SpectatorPanel.h"
#include "vgui_scorepanel.h"
#include "vgui_ScorePanel.h"
#define PANEL_HEIGHT 32
#include "Exports.h"
/*
==========================
HUD_ChatInputPosition
#define BANNER_WIDTH 256
#define BANNER_HEIGHT 64
Sets the location of the input for chat text
==========================
*/
void CL_DLLEXPORT HUD_ChatInputPosition( int *x, int *y )
{
// RecClChatInputPosition( x, y );
#define OPTIONS_BUTTON_X 96
#define CAMOPTIONS_BUTTON_X 200
if ( g_iUser1 != 0 || gEngfuncs.IsSpectateOnly() )
{
if ( gHUD.m_Spectator.m_pip->value == INSET_OFF )
{
*y = YRES( PANEL_HEIGHT );
}
else
{
*y = YRES( gHUD.m_Spectator.m_OverviewData.insetWindowHeight + 5 );
}
}
}
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
@ -57,6 +67,9 @@ void SpectatorPanel::ActionSignal(int cmd)
case SPECTATOR_PANEL_CMD_PREVPLAYER : gHUD.m_Spectator.FindNextPlayer(false);
break;
case SPECTATOR_PANEL_CMD_PLAYERS : gViewPort->ShowCommandMenu( gViewPort->m_PlayerMenu );
break;
case SPECTATOR_PANEL_CMD_HIDEMENU : ShowMenu(false);
break;
@ -84,15 +97,15 @@ void SpectatorPanel::Initialize()
SchemeHandle_t hSmallScheme = pSchemes->getSchemeHandle( "Team Info Text" );
m_TopBorder = new CTransparentPanel(64, 0, 0, ScreenWidth, YRES(PANEL_HEIGHT));
m_TopBorder = new CTransparentPanel(64, 0, 0, ScreenWidth, PANEL_HEIGHT);
m_TopBorder->setParent(this);
m_BottomBorder = new CTransparentPanel(64, 0, ScreenHeight - YRES(32), ScreenWidth, YRES(PANEL_HEIGHT));
m_BottomBorder = new CTransparentPanel(64, 0, ScreenHeight - PANEL_HEIGHT, ScreenWidth, PANEL_HEIGHT);
m_BottomBorder->setParent(this);
setPaintBackgroundEnabled(false);
m_ExtraInfo = new Label( "Extra Info", 0, 0, wide, YRES(PANEL_HEIGHT) );
m_ExtraInfo = new Label( "Extra Info", 0, 0, wide, PANEL_HEIGHT );
m_ExtraInfo->setParent(m_TopBorder);
m_ExtraInfo->setFont( pSchemes->getFont(hSmallScheme) );
@ -108,7 +121,7 @@ void SpectatorPanel::Initialize()
m_TopBanner = new CImageLabel( "banner", 0, 0, XRES(BANNER_WIDTH), YRES(BANNER_HEIGHT) );
m_TopBanner->setParent(this);
m_CurrentTime = new Label( "00:00", 0, 0, wide, YRES(PANEL_HEIGHT) );
m_CurrentTime = new Label( "00:00", 0, 0, wide, PANEL_HEIGHT );
m_CurrentTime->setParent(m_TopBorder);
m_CurrentTime->setFont( pSchemes->getFont(hSmallScheme) );
m_CurrentTime->setPaintBackgroundEnabled(false);
@ -122,7 +135,7 @@ void SpectatorPanel::Initialize()
for ( int j= 0; j < TEAM_NUMBER; j++ )
{
m_TeamScores[j] = new Label( " ", 0, 0, wide, YRES(PANEL_HEIGHT) );
m_TeamScores[j] = new Label( " ", 0, 0, wide, PANEL_HEIGHT );
m_TeamScores[j]->setParent( m_TopBorder );
m_TeamScores[j]->setFont( pSchemes->getFont(hSmallScheme) );
m_TeamScores[j]->setPaintBackgroundEnabled(false);
@ -133,7 +146,8 @@ void SpectatorPanel::Initialize()
// Initialize command buttons.
m_OptionButton = new ColorButton( CHudTextMessage::BufferedLocaliseTextString( "#SPECT_OPTIONS" ), XRES(15), YRES(6), XRES(OPTIONS_BUTTON_X), YRES(20), false, false );
// m_OptionButton = new ColorButton( CHudTextMessage::BufferedLocaliseTextString( "#SPECT_OPTIONS" ), XRES(15), YRES(6), XRES(OPTIONS_BUTTON_X), YRES(20), false, false );
m_OptionButton = new DropDownButton( CHudTextMessage::BufferedLocaliseTextString( "#SPECT_OPTIONS" ), XRES(15), YRES(6), XRES(OPTIONS_BUTTON_X), YRES(20), false, false );
m_OptionButton->setParent( m_BottomBorder );
m_OptionButton->setContentAlignment( vgui::Label::a_center );
m_OptionButton->setBoundKey( (char)255 ); // special no bound to avoid leading spaces in name
@ -143,7 +157,7 @@ void SpectatorPanel::Initialize()
m_OptionButton->setUnArmedColor ( 143, 143, 54, 0 );
m_OptionButton->setArmedColor ( 194, 202, 54, 0 );
m_CamButton = new ColorButton( CHudTextMessage::BufferedLocaliseTextString( "#CAM_OPTIONS" ), ScreenWidth - ( XRES ( CAMOPTIONS_BUTTON_X ) + 15 ), YRES(6), XRES ( CAMOPTIONS_BUTTON_X ), YRES(20), false, false );
m_CamButton = new DropDownButton( CHudTextMessage::BufferedLocaliseTextString( "#CAM_OPTIONS" ), ScreenWidth - ( XRES ( CAMOPTIONS_BUTTON_X ) + 15 ), YRES(6), XRES ( CAMOPTIONS_BUTTON_X ), YRES(20), false, false );
m_CamButton->setParent( m_BottomBorder );
m_CamButton->setContentAlignment( vgui::Label::a_center );
m_CamButton->setBoundKey( (char)255 ); // special no bound to avoid leading spaces in name
@ -153,7 +167,8 @@ void SpectatorPanel::Initialize()
m_CamButton->setUnArmedColor ( 143, 143, 54, 0 );
m_CamButton->setArmedColor ( 194, 202, 54, 0 );
m_PrevPlayerButton= new ColorButton("<", XRES( 15 + OPTIONS_BUTTON_X + 15 ), YRES(6), XRES(24), YRES(20), false, false );
// m_PrevPlayerButton= new ColorButton("<", XRES( 15 + OPTIONS_BUTTON_X + 15 ), YRES(6), XRES(24), YRES(20), false, false );
m_PrevPlayerButton= new CImageButton("arrowleft", XRES( 15 + OPTIONS_BUTTON_X + 15 ), YRES(6), XRES(24), YRES(20), false, false );
m_PrevPlayerButton->setParent( m_BottomBorder );
m_PrevPlayerButton->setContentAlignment( vgui::Label::a_center );
m_PrevPlayerButton->setBoundKey( (char)255 ); // special no bound to avoid leading spaces in name
@ -163,7 +178,8 @@ void SpectatorPanel::Initialize()
m_PrevPlayerButton->setUnArmedColor ( 143, 143, 54, 0 );
m_PrevPlayerButton->setArmedColor ( 194, 202, 54, 0 );
m_NextPlayerButton= new ColorButton(">", (ScreenWidth - (XRES ( CAMOPTIONS_BUTTON_X ) + 15)) - XRES ( 24 + 15 ), YRES(6), XRES(24), YRES(20),false, false );
// m_NextPlayerButton= new ColorButton(">", (ScreenWidth - (XRES ( CAMOPTIONS_BUTTON_X ) + 15)) - XRES ( 24 + 15 ), YRES(6), XRES(24), YRES(20),false, false );
m_NextPlayerButton= new CImageButton("arrowright", (ScreenWidth - (XRES ( CAMOPTIONS_BUTTON_X ) + 15)) - XRES ( 24 + 15 ), YRES(6), XRES(24), YRES(20),false, false );
m_NextPlayerButton->setParent( m_BottomBorder );
m_NextPlayerButton->setContentAlignment( vgui::Label::a_center );
m_NextPlayerButton->setBoundKey( (char)255 ); // special no bound to avoid leading spaces in name
@ -177,13 +193,33 @@ void SpectatorPanel::Initialize()
float flLabelSize = ( (ScreenWidth - (XRES ( CAMOPTIONS_BUTTON_X ) + 15)) - XRES ( 24 + 15 ) ) - XRES( (15 + OPTIONS_BUTTON_X + 15) + 38 );
m_BottomMainLabel = new Label( "Spectator Bottom", XRES( ( 15 + OPTIONS_BUTTON_X + 15 ) + 31 ), YRES(6), flLabelSize, YRES(20) );
m_BottomMainButton = new DropDownButton("Spectator Bottom",
XRES( ( 15 + OPTIONS_BUTTON_X + 15 ) + 31 ), YRES(6), flLabelSize, YRES(20),
false, false );
m_BottomMainButton->setParent(m_BottomBorder);
m_BottomMainButton->setPaintBackgroundEnabled(false);
m_BottomMainButton->setFgColor( Scheme::sc_primary1 );
m_BottomMainButton->setContentAlignment( vgui::Label::a_center );
m_BottomMainButton->setBorder( new LineBorder( Color( 59, 58, 34, 48 ) ) );
m_BottomMainButton->setBoundKey( (char)255 ); // special no bound to avoid leading spaces in name
m_BottomMainButton->addActionSignal( new CSpectatorHandler_Command(this,SPECTATOR_PANEL_CMD_PLAYERS) );
m_BottomMainButton->setUnArmedBorderColor ( 59, 58, 34, 48 );
m_BottomMainButton->setArmedBorderColor ( 194, 202, 54, 0 );
m_BottomMainButton->setUnArmedColor ( 143, 143, 54, 0 );
m_BottomMainButton->setArmedColor ( 194, 202, 54, 0 );
m_BottomMainLabel = new Label("Spectator Bottom",
XRES( ( 15 + OPTIONS_BUTTON_X + 15 ) + 31 ), YRES(6), flLabelSize, YRES(20));
m_BottomMainLabel->setParent(m_BottomBorder);
m_BottomMainLabel->setPaintBackgroundEnabled(false);
m_BottomMainLabel->setFgColor( Scheme::sc_primary1 );
m_BottomMainLabel->setContentAlignment( vgui::Label::a_center );
m_BottomMainLabel->setBorder( new LineBorder( Color( 59, 58, 34, 48 ) ) );
m_BottomMainLabel->setBorder( NULL );
m_BottomMainLabel->setVisible(false);
m_InsetViewButton = new ColorButton("", XRES(2), YRES(2), XRES(240), YRES(180), false, false );
m_InsetViewButton->setParent( this );
m_InsetViewButton->setBoundKey( (char)255 );
@ -215,15 +251,22 @@ void SpectatorPanel::ShowMenu(bool isVisible)
m_CamButton->setVisible(isVisible); m_CamButton->setArmed( false );
m_NextPlayerButton->setVisible(isVisible); m_NextPlayerButton->setArmed( false );
m_PrevPlayerButton->setVisible(isVisible); m_PrevPlayerButton->setArmed( false );
if ( !isVisible )
{
int iLabelSizeX, iLabelSizeY;
m_BottomMainLabel->setVisible(true);
m_BottomMainButton->setVisible(false);
m_BottomMainLabel->getSize( iLabelSizeX, iLabelSizeY );
m_BottomMainLabel->setPos( ( ScreenWidth / 2 ) - (iLabelSizeX/2), YRES(6) );
}
else
m_BottomMainLabel->setPos( XRES( ( 15 + OPTIONS_BUTTON_X + 15 ) + 31 ), YRES(6) );
{
m_BottomMainButton->setPos( XRES( ( 15 + OPTIONS_BUTTON_X + 15 ) + 31 ), YRES(6) );
m_BottomMainLabel->setVisible(false);
m_BottomMainButton->setVisible(true);
}
if ( !isVisible )
{
@ -288,7 +331,7 @@ void SpectatorPanel::EnableInsetView(bool isEnabled)
if ( isEnabled )
{
// short black bar to see full inset
m_TopBorder->setBounds( XRES(offset), 0, XRES(640 - offset ), YRES(PANEL_HEIGHT) );
m_TopBorder->setBounds( XRES(offset), 0, XRES(640 - offset ), PANEL_HEIGHT );
if ( gEngfuncs.IsSpectateOnly() )
{
@ -298,8 +341,8 @@ void SpectatorPanel::EnableInsetView(bool isEnabled)
else
m_TopBanner->setVisible( false );
m_InsetViewButton->setBounds( XRES( x ), YRES( y ),
XRES( wide ), YRES( tall ) );
m_InsetViewButton->setBounds( XRES( x -1 ), YRES( y ),
XRES( wide +2), YRES( tall ) );
m_InsetViewButton->setVisible(true);
}
else
@ -314,7 +357,7 @@ void SpectatorPanel::EnableInsetView(bool isEnabled)
else
m_TopBanner->setVisible( false );
m_TopBorder->setBounds( 0, 0, ScreenWidth, YRES(PANEL_HEIGHT) );
m_TopBorder->setBounds( 0, 0, ScreenWidth, PANEL_HEIGHT );
m_InsetViewButton->setVisible(false);
}
@ -356,28 +399,28 @@ void SpectatorPanel::Update()
m_ExtraInfo->getTextSize( iTextWidth, iTextHeight );
m_CurrentTime->getTextSize( iTimeWidth, iTimeHeight );
iTimeWidth += XRES ( 14 ); // +timer icon
iTimeWidth += ( 4-(iTimeWidth%4) );
iTimeWidth += XRES ( SEPERATOR_WIDTH*2 + 1 ); // +timer icon
iTimeWidth += ( SEPERATOR_WIDTH-(iTimeWidth%SEPERATOR_WIDTH) );
if ( iTimeWidth > iTextWidth )
iTextWidth = iTimeWidth;
int xPos = ScreenWidth - ( iTextWidth + XRES ( 4 + offset ) );
int xPos = ScreenWidth - ( iTextWidth + XRES ( SEPERATOR_WIDTH + offset ) );
m_ExtraInfo->setBounds( xPos, YRES( 1 ), iTextWidth, iTextHeight );
m_ExtraInfo->setBounds( xPos, YRES( SEPERATOR_HEIGHT ), iTextWidth, iTextHeight );
m_TimerImage->setBounds( xPos, YRES( 2 ) + iTextHeight , XRES(14), YRES(14) );
m_TimerImage->setBounds( xPos, YRES( SEPERATOR_HEIGHT ) + iTextHeight , XRES(SEPERATOR_WIDTH*2 + 1), YRES(SEPERATOR_HEIGHT + 1) );
m_CurrentTime->setBounds( xPos + XRES ( 14 + 1 ), YRES( 2 ) + iTextHeight , iTimeWidth, iTimeHeight );
m_CurrentTime->setBounds( xPos + XRES ( SEPERATOR_WIDTH*2 + 1 ), YRES( SEPERATOR_HEIGHT ) + iTextHeight , iTimeWidth, iTimeHeight );
m_Separator->setPos( ScreenWidth - ( iTextWidth + XRES ( 4+2+4+offset ) ) , YRES( 1 ) );
m_Separator->setSize( XRES( 4 ), YRES( PANEL_HEIGHT - 2 ) );
m_Separator->setPos( ScreenWidth - ( iTextWidth + XRES ( 2*SEPERATOR_WIDTH+SEPERATOR_WIDTH/2+offset ) ) , YRES( 5 ) );
m_Separator->setSize( XRES( 1 ), PANEL_HEIGHT - 10 );
for ( j= 0; j < TEAM_NUMBER; j++ )
{
int iwidth, iheight;
m_TeamScores[j]->getTextSize( iwidth, iheight );
m_TeamScores[j]->setBounds( ScreenWidth - ( iTextWidth + XRES ( 4+2+4+2+offset ) + iwidth ), YRES( 1 ) + ( iheight * j ), iwidth, iheight );
m_TeamScores[j]->setBounds( ScreenWidth - ( iTextWidth + XRES ( 2*SEPERATOR_WIDTH+2*SEPERATOR_WIDTH/2+offset ) + iwidth ), YRES( SEPERATOR_HEIGHT ) + ( iheight * j ), iwidth, iheight );
}
}

View file

@ -1,10 +1,3 @@
//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================
// vgui_SpectatorPanel.h: interface for the SpectatorPanel class.
//
//////////////////////////////////////////////////////////////////////
@ -26,6 +19,21 @@ using namespace vgui;
#define SPECTATOR_PANEL_CMD_HIDEMENU 4
#define SPECTATOR_PANEL_CMD_TOGGLE_INSET 5
#define SPECTATOR_PANEL_CMD_CAMERA 6
#define SPECTATOR_PANEL_CMD_PLAYERS 7
// spectator panel sizes
#define PANEL_HEIGHT 64
#define BANNER_WIDTH 256
#define BANNER_HEIGHT 64
#define OPTIONS_BUTTON_X 96
#define CAMOPTIONS_BUTTON_X 200
#define SEPERATOR_WIDTH 15
#define SEPERATOR_HEIGHT 15
#define TEAM_NUMBER 2
@ -50,20 +58,22 @@ public:
void EnableInsetView(bool isEnabled);
void ShowMenu(bool isVisible);
ColorButton * m_OptionButton;
DropDownButton * m_OptionButton;
// CommandButton * m_HideButton;
ColorButton * m_PrevPlayerButton;
ColorButton * m_NextPlayerButton;
ColorButton * m_CamButton;
//ColorButton * m_PrevPlayerButton;
//ColorButton * m_NextPlayerButton;
CImageButton * m_PrevPlayerButton;
CImageButton * m_NextPlayerButton;
DropDownButton * m_CamButton;
CTransparentPanel * m_TopBorder;
CTransparentPanel * m_BottomBorder;
ColorButton *m_InsetViewButton;
Label *m_BottomMainLabel;
DropDownButton *m_BottomMainButton;
CImageLabel *m_TimerImage;
Label *m_BottomMainLabel;
Label *m_CurrentTime;
Label *m_ExtraInfo;
Panel *m_Separator;

View file

@ -1,4 +1,4 @@
//=========== (C) Copyright 1996-2002 Valve, L.L.C. All rights reserved. ===========
//=========== (C) Copyright 1999 Valve, L.L.C. All rights reserved. ===========
//
// The copyright to the contents herein is the property of Valve, L.L.C.
// The contents may be used and/or copied only with the written permission of
@ -45,7 +45,7 @@
#include "in_defs.h"
#include "parsemsg.h"
#include "pm_shared.h"
#include "../engine/keydefs.h"
#include "keydefs.h"
#include "demo.h"
#include "demo_api.h"
@ -55,13 +55,16 @@
#include "vgui_ScorePanel.h"
#include "vgui_SpectatorPanel.h"
#include "shake.h"
#include "screenfade.h"
extern int g_iVisibleMouse;
class CCommandMenu;
int g_iPlayerClass;
int g_iTeamNumber;
int g_iUser1;
int g_iUser2;
int g_iUser3;
int g_iUser1 = 0;
int g_iUser2 = 0;
int g_iUser3 = 0;
// Scoreboard positions
#define SBOARD_INDENT_X XRES(104)
@ -140,10 +143,12 @@ char *sTFClassSelection[] =
"civilian",
};
#ifdef _TFC
int iBuildingCosts[] =
{
BUILD_COST_DISPENSER,
BUILD_COST_SENTRYGUN
BUILD_COST_SENTRYGUN,
BUILD_COST_TELEPORTER
};
// This maps class numbers to the Invalid Class bit.
@ -163,6 +168,7 @@ int sTFValidClassInts[] =
TF_ILL_ENGINEER,
TF_ILL_RANDOMPC,
};
#endif
// Get the name of TGA file, based on GameDir
char* GetVGUITGAName(const char *pszName)
@ -208,6 +214,27 @@ void CCommandMenu::AddButton( CommandButton *pButton )
}
}
void CCommandMenu::RemoveAllButtons(void)
{
/*
for(int i=0;i<m_iButtons;i++)
{
CommandButton *pTemp = m_aButtons[i];
m_aButtons[i] = NULL;
pTemp
if(pTemp)
{
delete(pTemp);
}
}
*/
removeAllChildren();
m_iButtons=0;
}
//-----------------------------------------------------------------------------
// Purpose: Tries to find a button that has a key bound to the input, and
// presses the button if found
@ -434,7 +461,7 @@ CCommandMenu *TeamFortressViewport::CreateSubMenu( CommandButton *pButton, CComm
iDirection = pParentMenu->GetDirection();
}
CCommandMenu *pMenu = new CCommandMenu(pParentMenu, iDirection, iXPos, iYPos, iWide, iTall );
CCommandMenu *pMenu = new CCommandMenu(pParentMenu, iDirection, iXPos, iYPos, iWide, iTall );
pMenu->setParent(this);
pButton->AddSubMenu( pMenu );
pButton->setFont( Scheme::sf_primary3 );
@ -445,13 +472,13 @@ CCommandMenu *TeamFortressViewport::CreateSubMenu( CommandButton *pButton, CComm
pButton->addInputSignal(pISignal);
// Put a > to show it's a submenu
CImageLabel *pLabel = new CImageLabel( "arrow", CMENU_SIZE_X - SUBMENU_SIZE_X, SUBMENU_SIZE_Y );
CImageLabel *pLabel = new CImageLabel( "arrowright", XRES(CMENU_SIZE_X - SUBMENU_SIZE_X), YRES(SUBMENU_SIZE_Y) );
pLabel->setParent(pButton);
pLabel->addInputSignal(pISignal);
// Reposition
pLabel->getPos( iXPos, iYPos );
pLabel->setPos( CMENU_SIZE_X - pLabel->getImageWide(), (BUTTON_SIZE_Y - pLabel->getImageTall()) / 2 );
pLabel->setPos( pButton->getWide() - pLabel->getImageWide()-4, -4 );
// Create the mouse off signal for the Label too
if (!pButton->m_bNoHighlight)
@ -584,9 +611,26 @@ TeamFortressViewport::TeamFortressViewport(int x,int y,int wide,int tall) : Pane
m_iCurrentTeamNumber = m_iUser1 = m_iUser2 = m_iUser3 = 0;
m_StandardMenu = CreateCommandMenu("commandmenu.txt", 0, CMENU_TOP, false, CMENU_SIZE_X, BUTTON_SIZE_Y, 0 );
m_SpectatorOptionsMenu = CreateCommandMenu("spectatormenu.txt", 1, YRES(32), true, CMENU_SIZE_X, BUTTON_SIZE_Y / 2, 0 ); // above bottom bar, flat design
m_SpectatorCameraMenu = CreateCommandMenu("spectcammenu.txt", 1, YRES(32), true, XRES( 200 ), BUTTON_SIZE_Y / 2, ScreenWidth - ( XRES ( 200 ) + 15 ) ); // above bottom bar, flat design
m_SpectatorOptionsMenu = CreateCommandMenu("spectatormenu.txt", 1, PANEL_HEIGHT, true, CMENU_SIZE_X, BUTTON_SIZE_Y / 2, 0 ); // above bottom bar, flat design
m_SpectatorCameraMenu = CreateCommandMenu("spectcammenu.txt", 1, PANEL_HEIGHT, true, XRES( 200 ), BUTTON_SIZE_Y / 2, ScreenWidth - ( XRES ( 200 ) + 15 ) ); // above bottom bar, flat design
m_PlayerMenu = m_iNumMenus;
m_iNumMenus++;
float flLabelSize = ( (ScreenWidth - (XRES ( CAMOPTIONS_BUTTON_X ) + 15)) - XRES ( 24 + 15 ) ) - XRES( (15 + OPTIONS_BUTTON_X + 15) + 38 );
m_pCommandMenus[m_PlayerMenu] = new CCommandMenu(NULL, 1,
XRES( ( 15 + OPTIONS_BUTTON_X + 15 ) + 31 ),PANEL_HEIGHT, flLabelSize,300);
m_pCommandMenus[m_PlayerMenu]->setParent(this);
m_pCommandMenus[m_PlayerMenu]->setVisible(false);
m_pCommandMenus[m_PlayerMenu]->m_flButtonSizeY = BUTTON_SIZE_Y /2;
m_pCommandMenus[m_PlayerMenu]->m_iSpectCmdMenu = 1;
UpdatePlayerMenu(m_PlayerMenu);
CreateServerBrowser();
}
//-----------------------------------------------------------------------------
@ -636,7 +680,7 @@ void TeamFortressViewport::Initialize( void )
strcpy(m_sTeamNames[i], "");
}
App::getInstance()->setCursorOveride( App::getInstance()->getScheme()->getCursor(Scheme::SchemeCursor::scu_none) );
App::getInstance()->setCursorOveride( App::getInstance()->getScheme()->getCursor(Scheme::scu_none) );
}
class CException;
@ -669,8 +713,10 @@ int TeamFortressViewport::CreateCommandMenu( char * menuFile, int direction, int
return newIndex;
}
#ifdef _WIN32
try
{
#endif
// First, read in the localisation strings
// Detpack strings
@ -749,6 +795,7 @@ try
else
{
// See if it's a Class
#ifdef _TFC
for (int i = 1; i <= PC_ENGINEER; i++)
{
if ( !strcmp(token, sTFClasses[i]) )
@ -761,6 +808,7 @@ try
break;
}
}
#endif
}
// Get the button bound key
@ -875,6 +923,7 @@ try
pfile = gEngfuncs.COM_ParseFile(pfile, token);
}
#ifdef _WIN32
}
catch( CException *e )
{
@ -884,6 +933,7 @@ catch( CException *e )
m_iInitialized = false;
return newIndex;
}
#endif
SetCurrentMenu( NULL );
SetCurrentCommandMenu( NULL );
@ -906,6 +956,7 @@ CCommandMenu *TeamFortressViewport::CreateDisguiseSubmenu( CommandButton *pButto
m_iNumMenus++;
// create the class choice buttons
#ifdef _TFC
for ( int i = PC_SCOUT; i <= PC_ENGINEER; i++ )
{
CommandButton *pDisguiseButton = new CommandButton( CHudTextMessage::BufferedLocaliseTextString( sLocalisedClasses[i] ), 0, BUTTON_SIZE_Y, CMENU_SIZE_X, BUTTON_SIZE_Y );
@ -916,7 +967,8 @@ CCommandMenu *TeamFortressViewport::CreateDisguiseSubmenu( CommandButton *pButto
pMenu->AddButton( pDisguiseButton );
}
#endif
return pMenu;
}
@ -973,6 +1025,7 @@ CommandButton *TeamFortressViewport::CreateCustomButton( char *pButtonText, char
m_pCommandMenus[m_iNumMenus] = pMenu;
m_iNumMenus++;
#ifdef _TFC
for (int i = PC_SCOUT; i <= PC_RANDOM; i++ )
{
char sz[256];
@ -985,7 +1038,9 @@ CommandButton *TeamFortressViewport::CreateCustomButton( char *pButtonText, char
pClassButton->addActionSignal(new CMenuHandler_StringCommandClassSelect(sz));
pMenu->AddButton( pClassButton );
}
#endif
}
#ifdef _TFC
// Map Briefing
else if ( !strcmp( pButtonName, "!MAPBRIEFING" ) )
{
@ -1166,6 +1221,48 @@ CommandButton *TeamFortressViewport::CreateCustomButton( char *pButtonText, char
// Create an input signal that'll popup the current menu
pButton->addInputSignal( new CMenuHandler_PopupSubMenuInput(pButton, m_pCurrentCommandMenu) );
}
else if ( !strcmp( pButtonName, "!BUILDENTRYTELEPORTER" ) )
{
pButton = new BuildButton( BUILDSTATE_CANBUILD, BuildButton::ENTRY_TELEPORTER, pButtonText, 0, BUTTON_SIZE_Y * 2, CMENU_SIZE_X, BUTTON_SIZE_Y);
pButton->addActionSignal(new CMenuHandler_StringCommand("build 4"));
// Create an input signal that'll popup the current menu
pButton->addInputSignal( new CMenuHandler_PopupSubMenuInput(pButton, m_pCurrentCommandMenu) );
}
else if ( !strcmp( pButtonName, "!DISMANTLEENTRYTELEPORTER" ) )
{
pButton = new BuildButton( BUILDSTATE_HASBUILDING, BuildButton::ENTRY_TELEPORTER, pButtonText, 0, BUTTON_SIZE_Y * 2, CMENU_SIZE_X, BUTTON_SIZE_Y);
pButton->addActionSignal(new CMenuHandler_StringCommand("dismantle 4"));
// Create an input signal that'll popup the current menu
pButton->addInputSignal( new CMenuHandler_PopupSubMenuInput(pButton, m_pCurrentCommandMenu) );
}
else if ( !strcmp( pButtonName, "!DETONATEENTRYTELEPORTER" ) )
{
pButton = new BuildButton( BUILDSTATE_HASBUILDING, BuildButton::ENTRY_TELEPORTER, pButtonText, 0, BUTTON_SIZE_Y * 2, CMENU_SIZE_X, BUTTON_SIZE_Y);
pButton->addActionSignal(new CMenuHandler_StringCommand("detentryteleporter"));
// Create an input signal that'll popup the current menu
pButton->addInputSignal( new CMenuHandler_PopupSubMenuInput(pButton, m_pCurrentCommandMenu) );
}
else if ( !strcmp( pButtonName, "!BUILDEXITTELEPORTER" ) )
{
pButton = new BuildButton( BUILDSTATE_CANBUILD, BuildButton::EXIT_TELEPORTER, pButtonText, 0, BUTTON_SIZE_Y * 2, CMENU_SIZE_X, BUTTON_SIZE_Y);
pButton->addActionSignal(new CMenuHandler_StringCommand("build 5"));
// Create an input signal that'll popup the current menu
pButton->addInputSignal( new CMenuHandler_PopupSubMenuInput(pButton, m_pCurrentCommandMenu) );
}
else if ( !strcmp( pButtonName, "!DISMANTLEEXITTELEPORTER" ) )
{
pButton = new BuildButton( BUILDSTATE_HASBUILDING, BuildButton::EXIT_TELEPORTER, pButtonText, 0, BUTTON_SIZE_Y * 2, CMENU_SIZE_X, BUTTON_SIZE_Y);
pButton->addActionSignal(new CMenuHandler_StringCommand("dismantle 5"));
// Create an input signal that'll popup the current menu
pButton->addInputSignal( new CMenuHandler_PopupSubMenuInput(pButton, m_pCurrentCommandMenu) );
}
else if ( !strcmp( pButtonName, "!DETONATEEXITTELEPORTER" ) )
{
pButton = new BuildButton( BUILDSTATE_HASBUILDING, BuildButton::EXIT_TELEPORTER, pButtonText, 0, BUTTON_SIZE_Y * 2, CMENU_SIZE_X, BUTTON_SIZE_Y);
pButton->addActionSignal(new CMenuHandler_StringCommand("detexitteleporter"));
// Create an input signal that'll popup the current menu
pButton->addInputSignal( new CMenuHandler_PopupSubMenuInput(pButton, m_pCurrentCommandMenu) );
}
// Stop building
else if ( !strcmp( pButtonName, "!BUILDSTOP" ) )
{
@ -1174,6 +1271,7 @@ CommandButton *TeamFortressViewport::CreateCustomButton( char *pButtonText, char
// Create an input signal that'll popup the current menu
pButton->addInputSignal( new CMenuHandler_PopupSubMenuInput(pButton, m_pCurrentCommandMenu) );
}
#endif
return pButton;
}
@ -1281,6 +1379,12 @@ void TeamFortressViewport::HideCommandMenu()
m_pCommandMenus[m_SpectatorCameraMenu]->ClearButtonsOfArmedState();
}
if ( m_pCommandMenus[m_PlayerMenu] )
{
m_pCommandMenus[m_PlayerMenu]->ClearButtonsOfArmedState();
}
m_flMenuOpenTime = 0.0f;
SetCurrentCommandMenu( NULL );
UpdateCursorState();
@ -1341,6 +1445,7 @@ void TeamFortressViewport::InputPlayerSpecial( void )
if (!m_iInitialized)
return;
#ifdef _TFC
if ( g_iPlayerClass == PC_ENGINEER || g_iPlayerClass == PC_SPY )
{
ShowCommandMenu( gViewPort->m_StandardMenu );
@ -1351,9 +1456,10 @@ void TeamFortressViewport::InputPlayerSpecial( void )
}
}
else
#endif
{
// if it's any other class, just send the command down to the server
ClientCmd( "_special" );
EngineClientCmd( "_special" );
}
}
@ -1371,10 +1477,60 @@ void TeamFortressViewport::SetCurrentCommandMenu( CCommandMenu *pNewMenu )
void TeamFortressViewport::UpdateCommandMenu(int menuIndex)
{
// if its the player menu update the player list
if(menuIndex==m_PlayerMenu)
{
m_pCommandMenus[m_PlayerMenu]->RemoveAllButtons();
UpdatePlayerMenu(m_PlayerMenu);
}
m_pCommandMenus[menuIndex]->RecalculateVisibles( 0, false );
m_pCommandMenus[menuIndex]->RecalculatePositions( 0 );
}
void TeamFortressViewport::UpdatePlayerMenu(int menuIndex)
{
cl_entity_t * pEnt = NULL;
float flLabelSize = ( (ScreenWidth - (XRES ( CAMOPTIONS_BUTTON_X ) + 15)) - XRES ( 24 + 15 ) ) - XRES( (15 + OPTIONS_BUTTON_X + 15) + 38 );
gViewPort->GetAllPlayersInfo();
for (int i = 1; i < MAX_PLAYERS; i++ )
{
//if ( g_PlayerInfoList[i].name == NULL )
// continue; // empty player slot, skip
pEnt = gEngfuncs.GetEntityByIndex( i );
if ( !gHUD.m_Spectator.IsActivePlayer( pEnt ) )
continue;
//if ( g_PlayerExtraInfo[i].teamname[0] == 0 )
// continue; // skip over players who are not in a team
SpectButton *pButton = new SpectButton(1 , g_PlayerInfoList[pEnt->index].name ,
XRES( ( 15 + OPTIONS_BUTTON_X + 15 ) + 31 ),PANEL_HEIGHT+(i-1)*CMENU_SIZE_X, flLabelSize, BUTTON_SIZE_Y /2 );
pButton->setBoundKey( (char)255 );
pButton->setContentAlignment( vgui::Label::a_center );
m_pCommandMenus[menuIndex]->AddButton( pButton );
pButton->setParentMenu( m_pCommandMenus[menuIndex] );
// Override font in CommandMenu
pButton->setFont( Scheme::sf_primary3 );
pButton->addActionSignal(new CMenuHandler_SpectateFollow( g_PlayerInfoList[pEnt->index].name));
// Create an input signal that'll popup the current menu
pButton->addInputSignal( new CMenuHandler_PopupSubMenuInput(pButton, m_pCommandMenus[menuIndex]) );
}
}
void COM_FileBase ( const char *in, char *out);
void TeamFortressViewport::UpdateSpectatorPanel()
@ -1392,6 +1548,7 @@ void TeamFortressViewport::UpdateSpectatorPanel()
char helpString2[128];
char tempString[128];
char * name;
char *pBottomText = NULL;
int player = 0;
// check if spectator combinations are still valid
@ -1429,7 +1586,13 @@ void TeamFortressViewport::UpdateSpectatorPanel()
// create player & health string
if ( player && name )
{
strcpy( bottomText, name );
strncpy( bottomText, name, sizeof(bottomText) );
bottomText[ sizeof(bottomText) - 1 ] = 0;
pBottomText = bottomText;
}
else
{
pBottomText = CHudTextMessage::BufferedLocaliseTextString( bottomText );
}
// in first person mode colorize player names
@ -1442,10 +1605,12 @@ void TeamFortressViewport::UpdateSpectatorPanel()
// set team color, a bit transparent
m_pSpectatorPanel->m_BottomMainLabel->setFgColor(r,g,b,0);
m_pSpectatorPanel->m_BottomMainButton->setFgColor(r,g,b,0);
}
else
{ // restore GUI color
m_pSpectatorPanel->m_BottomMainLabel->setFgColor( 143, 143, 54, 0 );
m_pSpectatorPanel->m_BottomMainButton->setFgColor( 143, 143, 54, 0 );
}
// add sting auto if we are in auto directed mode
@ -1456,7 +1621,8 @@ void TeamFortressViewport::UpdateSpectatorPanel()
strcpy( helpString2, tempString );
}
m_pSpectatorPanel->m_BottomMainLabel->setText( CHudTextMessage::BufferedLocaliseTextString( bottomText ) );
m_pSpectatorPanel->m_BottomMainLabel->setText( "%s", pBottomText );
m_pSpectatorPanel->m_BottomMainButton->setText( pBottomText );
// update extra info field
@ -1504,7 +1670,7 @@ void TeamFortressViewport::UpdateSpectatorPanel()
}
}
m_flSpectatorPanelLastUpdated = gHUD.m_flTime + 1.0; // update every seconds
m_flSpectatorPanelLastUpdated = gHUD.m_flTime + 1.0; // update every second
}
//======================================================================
@ -1548,6 +1714,10 @@ void TeamFortressViewport::SetCurrentMenu( CMenuPanel *pMenu )
m_pCurrentMenu->Open();
}
else
{
gEngfuncs.pfnClientCmd( "closemenus;" );
}
}
//================================================================
@ -1557,7 +1727,7 @@ CMenuPanel* TeamFortressViewport::CreateTextWindow( int iTextToShow )
char sz[256];
char *cText;
char *pfile = NULL;
static const int MAX_TITLE_LENGTH = 32;
static const int MAX_TITLE_LENGTH = 64;
char cTitle[MAX_TITLE_LENGTH];
if ( iTextToShow == SHOW_MOTD )
@ -1565,8 +1735,8 @@ CMenuPanel* TeamFortressViewport::CreateTextWindow( int iTextToShow )
if (!m_szServerName || !m_szServerName[0])
strcpy( cTitle, "Half-Life" );
else
strncpy( cTitle, m_szServerName, MAX_TITLE_LENGTH );
cTitle[MAX_TITLE_LENGTH-1] = 0;
strncpy( cTitle, m_szServerName, sizeof(cTitle) );
cTitle[sizeof(cTitle)-1] = 0;
cText = m_szMOTD;
}
else if ( iTextToShow == SHOW_MAPBRIEFING )
@ -1615,6 +1785,7 @@ CMenuPanel* TeamFortressViewport::CreateTextWindow( int iTextToShow )
strncpy( cTitle, m_sMapName, MAX_TITLE_LENGTH );
cTitle[MAX_TITLE_LENGTH-1] = 0;
}
#ifdef _TFC
else if ( iTextToShow == SHOW_CLASSDESC )
{
switch ( g_iPlayerClass )
@ -1657,6 +1828,7 @@ CMenuPanel* TeamFortressViewport::CreateTextWindow( int iTextToShow )
cText = pfile;
}
}
#endif
else if ( iTextToShow == SHOW_SPECHELP )
{
CHudTextMessage::LocaliseTextString( "#Spec_Help_Title", cTitle, MAX_TITLE_LENGTH );
@ -1889,7 +2061,7 @@ void TeamFortressViewport::UpdateCursorState()
if ( m_pSpectatorPanel->m_menuVisible || m_pCurrentMenu || m_pTeamMenu->isVisible() || m_pServerBrowser->isVisible() || GetClientVoiceMgr()->IsInSquelchMode() )
{
g_iVisibleMouse = true;
App::getInstance()->setCursorOveride( App::getInstance()->getScheme()->getCursor(Scheme::SchemeCursor::scu_arrow) );
App::getInstance()->setCursorOveride( App::getInstance()->getScheme()->getCursor(Scheme::scu_arrow) );
return;
}
else if ( m_pCurrentCommandMenu )
@ -1898,7 +2070,7 @@ void TeamFortressViewport::UpdateCursorState()
if ( gHUD.m_pCvarStealMouse->value != 0.0f )
{
g_iVisibleMouse = true;
App::getInstance()->setCursorOveride( App::getInstance()->getScheme()->getCursor(Scheme::SchemeCursor::scu_arrow) );
App::getInstance()->setCursorOveride( App::getInstance()->getScheme()->getCursor(Scheme::scu_arrow) );
return;
}
}
@ -1910,7 +2082,7 @@ void TeamFortressViewport::UpdateCursorState()
}
g_iVisibleMouse = false;
App::getInstance()->setCursorOveride( App::getInstance()->getScheme()->getCursor(Scheme::SchemeCursor::scu_none) );
App::getInstance()->setCursorOveride( App::getInstance()->getScheme()->getCursor(Scheme::scu_none) );
}
void TeamFortressViewport::UpdateHighlights()
@ -1923,7 +2095,7 @@ void TeamFortressViewport::GetAllPlayersInfo( void )
{
for ( int i = 1; i < MAX_PLAYERS; i++ )
{
GetPlayerInfo( i, &g_PlayerInfoList[i] );
gEngfuncs.pfnGetPlayerInfo( i, &g_PlayerInfoList[i] );
if ( g_PlayerInfoList[i].thisplayer )
m_pScoreBoard->m_iPlayerNum = i; // !!!HACK: this should be initialized elsewhere... maybe gotten from the engine
@ -1932,6 +2104,9 @@ void TeamFortressViewport::GetAllPlayersInfo( void )
void TeamFortressViewport::paintBackground()
{
int wide, tall;
getParent()->getSize( wide, tall );
setSize( wide, tall );
if (m_pScoreBoard)
{
int x, y;
@ -2229,7 +2404,7 @@ int TeamFortressViewport::MsgFunc_BuildSt( const char *pszName, int iSize, void
{
BEGIN_READ( pbuf, iSize );
m_iBuildState = READ_BYTE();
m_iBuildState = READ_SHORT();
// Force the menu to update
UpdateCommandMenu( m_StandardMenu );
@ -2250,7 +2425,8 @@ int TeamFortressViewport::MsgFunc_ServerName( const char *pszName, int iSize, vo
{
BEGIN_READ( pbuf, iSize );
strncpy( m_szServerName, READ_STRING(), MAX_SERVERNAME_LENGTH );
strncpy( m_szServerName, READ_STRING(), sizeof(m_szServerName) );
m_szServerName[sizeof(m_szServerName) - 1] = 0;
return 1;
}
@ -2293,7 +2469,8 @@ int TeamFortressViewport::MsgFunc_TeamScore( const char *pszName, int iSize, voi
char *TeamName = READ_STRING();
// find the team matching the name
for ( int i = 1; i <= m_pScoreBoard->m_iNumTeams; i++ )
int i;
for ( i = 1; i <= m_pScoreBoard->m_iNumTeams; i++ )
{
if ( !stricmp( TeamName, g_TeamInfo[i].name ) )
break;
@ -2367,3 +2544,101 @@ int TeamFortressViewport::MsgFunc_AllowSpec( const char *pszName, int iSize, voi
return 1;
}
#if defined( _TFC )
const Vector& GetTeamColor( int team_no );
extern globalvars_t *gpGlobals;
#endif
// used to reset the player's screen immediately
int TeamFortressViewport::MsgFunc_ResetFade( const char *pszName, int iSize, void *pbuf )
{
#if defined( _TFC )
if ( !gpGlobals )
return 0;
screenfade_t sf;
gEngfuncs.pfnGetScreenFade( &sf );
sf.fader = 0;
sf.fadeg = 0;
sf.fadeb = 0;
sf.fadealpha = 0;
sf.fadeEnd = 0.1;
sf.fadeReset = 0.0;
sf.fadeSpeed = 0.0;
sf.fadeFlags = FFADE_IN;
sf.fadeReset += gpGlobals->time;
sf.fadeEnd += sf.fadeReset;
gEngfuncs.pfnSetScreenFade( &sf );
#endif
return 1;
}
// used to fade a player's screen out/in when they're spectating someone who is teleported
int TeamFortressViewport::MsgFunc_SpecFade( const char *pszName, int iSize, void *pbuf )
{
#if defined( _TFC )
BEGIN_READ( pbuf, iSize );
int iIndex = READ_BYTE();
// we're in first-person spectator mode (...not first-person in the PIP)
if ( g_iUser1 == OBS_IN_EYE )
{
// this is the person we're watching
if ( g_iUser2 == iIndex )
{
int iFade = READ_BYTE();
int iTeam = READ_BYTE();
float flTime = ( (float)READ_SHORT() / 100.0 );
int iAlpha = READ_BYTE();
Vector team = GetTeamColor( iTeam );
screenfade_t sf;
gEngfuncs.pfnGetScreenFade( &sf );
sf.fader = team[0];
sf.fadeg = team[1];
sf.fadeb = team[2];
sf.fadealpha = iAlpha;
sf.fadeEnd = flTime;
sf.fadeReset = 0.0;
sf.fadeSpeed = 0.0;
if ( iFade == BUILD_TELEPORTER_FADE_OUT )
{
sf.fadeFlags = FFADE_OUT;
sf.fadeReset = flTime;
if ( sf.fadeEnd )
sf.fadeSpeed = -(float)sf.fadealpha / sf.fadeEnd;
sf.fadeTotalEnd = sf.fadeEnd += gpGlobals->time;
sf.fadeReset += sf.fadeEnd;
}
else
{
sf.fadeFlags = FFADE_IN;
if ( sf.fadeEnd )
sf.fadeSpeed = (float)sf.fadealpha / sf.fadeEnd;
sf.fadeReset += gpGlobals->time;
sf.fadeEnd += sf.fadeReset;
}
gEngfuncs.pfnSetScreenFade( &sf );
}
}
#endif
return 1;
}

View file

@ -1,9 +1,3 @@
//========= Copyright Š 1996-2002, Valve LLC, All rights reserved. ============
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================
#ifndef TEAMFORTRESSVIEWPORT_H
#define TEAMFORTRESSVIEWPORT_H
@ -32,8 +26,21 @@
#include "vgui_SchemeManager.h"
#define TF_DEFS_ONLY
#include "tf_defs.h"
#ifdef _TFC
#include "../tfc/tf_defs.h"
#else
#define PC_LASTCLASS 10
#define PC_UNDEFINED 0
#define MENU_DEFAULT 1
#define MENU_TEAM 2
#define MENU_CLASS 3
#define MENU_MAPBRIEFING 4
#define MENU_INTRO 5
#define MENU_CLASSHELP 6
#define MENU_CLASSHELP2 7
#define MENU_REPEATHELP 8
#define MENU_SPECHELP 9
#endif
using namespace vgui;
class Cursor;
@ -50,6 +57,7 @@ class DragNDropPanel;
class CTransparentPanel;
class CClassMenuPanel;
class CTeamMenuPanel;
class TeamFortressViewport;
char* GetVGUITGAName(const char *pszName);
BitmapTGA *LoadTGAForRes(const char* pImageName);
@ -59,8 +67,8 @@ extern int sTFValidClassInts[];
extern char *sLocalisedClasses[];
extern int iTeamColors[5][3];
extern int iNumberOfTeamColors;
extern TeamFortressViewport *gViewPort;
#define MAX_SERVERNAME_LENGTH 32
// Command Menu positions
#define MAX_MENUS 80
@ -74,7 +82,7 @@ extern int iNumberOfTeamColors;
#define CMENU_TOP (BUTTON_SIZE_Y * 4)
#define MAX_TEAMNAME_SIZE 64
//#define MAX_TEAMNAME_SIZE 64
#define MAX_BUTTON_SIZE 32
// Map Briefing Window
@ -377,6 +385,7 @@ public:
m_iDirection = 0;
}
CCommandMenu( CCommandMenu *pParentMenu, int direction, int x,int y,int wide,int tall ) : Panel(x,y,wide,tall)
{
m_pParentMenu = pParentMenu;
@ -402,12 +411,81 @@ public:
void ClearButtonsOfArmedState( void );
void RemoveAllButtons(void);
bool KeyInput( int keyNum );
virtual void paintBackground();
};
//==============================================================================
// Command menu root button (drop down box style)
class DropDownButton : public ColorButton
{
private:
CImageLabel *m_pOpenButton;
public:
DropDownButton( const char* text,int x,int y,int wide,int tall, bool bNoHighlight, bool bFlat ) :
ColorButton( text, x, y, wide, tall, bNoHighlight, bFlat )
{
// Put a > to show it's a submenu
m_pOpenButton = new CImageLabel( "arrowup", XRES( CMENU_SIZE_X-2 ) , YRES( BUTTON_SIZE_Y-2 ) );
m_pOpenButton->setParent(this);
int textwide, texttall;
getSize( textwide, texttall);
// Reposition
m_pOpenButton->setPos( textwide-(m_pOpenButton->getImageWide()+6), -2 /*(tall - m_pOpenButton->getImageTall()*2) / 2*/ );
m_pOpenButton->setVisible(true);
}
virtual void setVisible(bool state)
{
m_pOpenButton->setVisible(state);
ColorButton::setVisible(state);
}
};
//==============================================================================
// Button with image instead of text
class CImageButton : public ColorButton
{
private:
CImageLabel *m_pOpenButton;
public:
CImageButton( const char* text,int x,int y,int wide,int tall, bool bNoHighlight, bool bFlat ) :
ColorButton( " ", x, y, wide, tall, bNoHighlight, bFlat )
{
m_pOpenButton = new CImageLabel( text,1,1,wide-2 , tall-2 );
m_pOpenButton->setParent(this);
// Reposition
// m_pOpenButton->setPos( x+1,y+1 );
// m_pOpenButton->setSize(wide-2,tall-2);
m_pOpenButton->setVisible(true);
}
virtual void setVisible(bool state)
{
m_pOpenButton->setVisible(state);
ColorButton::setVisible(state);
}
};
//==============================================================================
class TeamFortressViewport : public Panel
{
@ -467,6 +545,10 @@ private:
char m_sDetpackStrings[3][MAX_BUTTON_SIZE];
char m_sMapName[64];
// helper function to update the player menu entries
void UpdatePlayerMenu(int menuIndex);
public:
TeamFortressViewport(int x,int y,int wide,int tall);
void Initialize( void );
@ -535,6 +617,8 @@ public:
int MsgFunc_TeamInfo( const char *pszName, int iSize, void *pbuf );
int MsgFunc_Spectator( const char *pszName, int iSize, void *pbuf );
int MsgFunc_AllowSpec( const char *pszName, int iSize, void *pbuf );
int MsgFunc_SpecFade( const char *pszName, int iSize, void *pbuf );
int MsgFunc_ResetFade( const char *pszName, int iSize, void *pbuf );
// Input
bool SlotInput( int iSlot );
@ -553,6 +637,7 @@ public:
int m_StandardMenu; // indexs in m_pCommandMenus
int m_SpectatorOptionsMenu;
int m_SpectatorCameraMenu;
int m_PlayerMenu; // a list of current player
CClassMenuPanel *m_pClassMenu;
ScorePanel *m_pScoreBoard;
SpectatorPanel * m_pSpectatorPanel;
@ -751,11 +836,37 @@ public:
else
m_cvar->value = 1.0f;
// hide the menu
gViewPort->HideCommandMenu();
gViewPort->UpdateSpectatorPanel();
}
};
class CMenuHandler_SpectateFollow : public ActionSignal
{
protected:
char m_szplayer[MAX_COMMAND_SIZE];
public:
CMenuHandler_SpectateFollow( char *player )
{
strncpy( m_szplayer, player, MAX_COMMAND_SIZE);
m_szplayer[MAX_COMMAND_SIZE-1] = '\0';
}
virtual void actionPerformed(Panel* panel)
{
gHUD.m_Spectator.FindPlayer(m_szplayer);
gViewPort->HideCommandMenu();
}
};
class CDragNDropHandler : public InputSignal
{
private:
@ -922,12 +1033,13 @@ public:
virtual int IsNotValid()
{
// Only visible for spies
#ifdef _TFC
if (g_iPlayerClass != PC_SPY)
return true;
#endif
if (m_iFeignState == gViewPort->GetIsFeigning())
return false;
return true;
}
};
@ -967,9 +1079,11 @@ public:
virtual int IsNotValid()
{
#ifdef _TFC
// Only visible for spies
if ( g_iPlayerClass != PC_SPY )
return true;
#endif
// if it's not tied to a specific team, then always show (for spies)
if ( !m_iValidTeamsBits )
@ -979,7 +1093,6 @@ public:
int iTmp = 1 << (gViewPort->GetNumberOfTeams() - 1);
if ( m_iValidTeamsBits & iTmp )
return false;
return true;
}
};
@ -996,9 +1109,11 @@ public:
virtual int IsNotValid()
{
#ifdef _TFC
// Only visible for demomen
if (g_iPlayerClass != PC_DEMOMAN)
return true;
#endif
if (m_iDetpackState == gViewPort->GetIsSettingDetpack())
return false;
@ -1008,10 +1123,10 @@ public:
};
extern int iBuildingCosts[];
#define BUILDSTATE_HASBUILDING (1<<0) // Data is building ID (1 = Dispenser, 2 = Sentry)
#define BUILDSTATE_HASBUILDING (1<<0) // Data is building ID (1 = Dispenser, 2 = Sentry, 3 = Entry Teleporter, 4 = Exit Teleporter)
#define BUILDSTATE_BUILDING (1<<1)
#define BUILDSTATE_BASE (1<<2)
#define BUILDSTATE_CANBUILD (1<<3) // Data is building ID (0 = Dispenser, 1 = Sentry)
#define BUILDSTATE_CANBUILD (1<<3) // Data is building ID (1 = Dispenser, 2 = Sentry, 3 = Entry Teleporter, 4 = Exit Teleporter)
class BuildButton : public CommandButton
{
@ -1024,6 +1139,8 @@ public:
{
DISPENSER = 0,
SENTRYGUN = 1,
ENTRY_TELEPORTER = 2,
EXIT_TELEPORTER = 3
};
BuildButton( int iState, int iData, const char* text,int x,int y,int wide,int tall ) : CommandButton( text,x,y,wide,tall)
@ -1034,6 +1151,7 @@ public:
virtual int IsNotValid()
{
#ifdef _TFC
// Only visible for engineers
if (g_iPlayerClass != PC_ENGINEER)
return true;
@ -1055,7 +1173,7 @@ public:
if (m_iBuildState & BUILDSTATE_BASE)
{
// Only appear if we've got enough metal to build something, or something already built
if ( gViewPort->GetBuildState() & (BS_HAS_SENTRYGUN | BS_HAS_DISPENSER | BS_CANB_SENTRYGUN | BS_CANB_DISPENSER) )
if ( gViewPort->GetBuildState() & (BS_HAS_SENTRYGUN | BS_HAS_DISPENSER | BS_CANB_SENTRYGUN | BS_CANB_DISPENSER | BS_HAS_ENTRY_TELEPORTER | BS_HAS_EXIT_TELEPORTER | BS_CANB_ENTRY_TELEPORTER | BS_CANB_EXIT_TELEPORTER) )
return false;
return true;
@ -1068,6 +1186,10 @@ public:
return true;
if ( m_iBuildData == BuildButton::SENTRYGUN && !(gViewPort->GetBuildState() & BS_HAS_SENTRYGUN) )
return true;
if ( m_iBuildData == BuildButton::ENTRY_TELEPORTER && !(gViewPort->GetBuildState() & BS_HAS_ENTRY_TELEPORTER) )
return true;
if ( m_iBuildData == BuildButton::EXIT_TELEPORTER && !(gViewPort->GetBuildState() & BS_HAS_EXIT_TELEPORTER) )
return true;
}
// Can build something
@ -1078,10 +1200,14 @@ public:
return false;
if ( m_iBuildData == BuildButton::SENTRYGUN && (gViewPort->GetBuildState() & BS_CANB_SENTRYGUN) )
return false;
if ( m_iBuildData == BuildButton::ENTRY_TELEPORTER && (gViewPort->GetBuildState() & BS_CANB_ENTRY_TELEPORTER) )
return false;
if ( m_iBuildData == BuildButton::EXIT_TELEPORTER && (gViewPort->GetBuildState() & BS_CANB_EXIT_TELEPORTER) )
return false;
return true;
}
#endif
return false;
}
};
@ -1132,29 +1258,6 @@ public:
return CommandButton::IsNotValid();
}
virtual void paintBackground()
{
if ( isArmed() )
{
drawSetColor( 143,143, 54, 125 );
drawFilledRect( 5, 0,_size[0] - 5,_size[1]);
}
}
virtual void paint( void )
{
if ( isArmed() )
{
setFgColor( 194, 202, 54, 0 );
}
else
{
setFgColor( 143, 143, 54, 15 );
}
Button::paint();
}
};
//-----------------------------------------------------------------------------

View file

@ -69,7 +69,7 @@ CTeamMenuPanel::CTeamMenuPanel(int iTrans, int iRemoveMe, int x,int y,int wide,i
pSchemes->getBgColor( hTitleScheme, r, g, b, a );
pLabel->setBgColor( r, g, b, a );
pLabel->setContentAlignment( vgui::Label::a_west );
pLabel->setText(gHUD.m_TextMessage.BufferedLocaliseTextString("#Title_SelectYourTeam"));
pLabel->setText( "%s", gHUD.m_TextMessage.BufferedLocaliseTextString("#Title_SelectYourTeam"));
// Create the Info Window
m_pTeamWindow = new CTransparentPanel( 255, TEAMMENU_WINDOW_X, TEAMMENU_WINDOW_Y, TEAMMENU_WINDOW_SIZE_X, TEAMMENU_WINDOW_SIZE_Y );
@ -286,7 +286,7 @@ void CTeamMenuPanel::Update( void )
strcpy( szTitle, ch+1 );
ch = strchr( szTitle, '.' );
*ch = '\0';
m_pMapTitle->setText( szTitle );
m_pMapTitle->setText( "%s", szTitle );
*ch = '.';
// Update the map briefing

View file

@ -1,10 +1,3 @@
//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================
// view/refresh setup functions
#include "hud.h"
@ -22,51 +15,45 @@
#include "pm_defs.h"
#include "event_api.h"
#include "pmtrace.h"
#include "bench.h"
#include "screenfade.h"
#include "shake.h"
#include "hltv.h"
#include "Exports.h"
// Spectator Mode
extern "C"
{
float vecNewViewAngles[3];
int iHasNewViewAngles;
float vecNewViewOrigin[3];
int iHasNewViewOrigin;
int iIsSpectator;
}
#ifndef M_PI
#define M_PI 3.14159265358979323846 // matches value in gcc v2 math.h
#endif
extern "C"
{
int CL_IsThirdPerson( void );
void CL_CameraOffset( float *ofs );
void DLLEXPORT V_CalcRefdef( struct ref_params_s *pparams );
void CL_DLLEXPORT V_CalcRefdef( struct ref_params_s *pparams );
void PM_ParticleLine( float *start, float *end, int pcolor, float life, float vert);
int PM_GetVisEntInfo( int ent );
int PM_GetPhysEntInfo( int ent );
extern "C" int PM_GetPhysEntInfo( int ent );
void InterpolateAngles( float * start, float * end, float * output, float frac );
void NormalizeAngles( float * angles );
float Distance(const float * v1, const float * v2);
extern "C" float Distance(const float * v1, const float * v2);
float AngleBetweenVectors( const float * v1, const float * v2 );
float vJumpOrigin[3];
float vJumpAngles[3];
}
void V_DropPunchAngle ( float frametime, float *ev_punchangle );
void VectorAngles( const float *forward, float *angles );
#include "r_studioint.h"
#include "com_model.h"
#include "kbutton.h"
extern engine_studio_api_t IEngineStudio;
extern kbutton_t in_mlook;
/*
The view is allowed to move slightly from it's true position for bobbing,
but if it exceeds 8 pixels linear distance (spherical, not box), the list of
@ -303,18 +290,30 @@ void V_DriftPitch ( struct ref_params_s *pparams )
}
// don't count small mouse motion
if (pd.nodrift)
if ( pd.nodrift)
{
if ( fabs( pparams->cmd->forwardmove ) < cl_forwardspeed->value )
pd.driftmove = 0;
else
pd.driftmove += pparams->frametime;
if ( pd.driftmove > v_centermove->value)
{
V_StartPitchDrift ();
if ( v_centermove->value > 0 && !(in_mlook.state & 1) )
{
// this is for lazy players. if they stopped, looked around and then continued
// to move the view will be centered automatically if they move more than
// v_centermove units.
if ( fabs( pparams->cmd->forwardmove ) < cl_forwardspeed->value )
pd.driftmove = 0;
else
pd.driftmove += pparams->frametime;
if ( pd.driftmove > v_centermove->value)
{
V_StartPitchDrift ();
}
else
{
return; // player didn't move enough
}
}
return;
return; // don't drift view
}
delta = pparams->idealpitch - pparams->cl_viewangles[PITCH];
@ -326,7 +325,8 @@ void V_DriftPitch ( struct ref_params_s *pparams )
}
move = pparams->frametime * pd.pitchvel;
pd.pitchvel += pparams->frametime * v_centerspeed->value;
pd.pitchvel *= (1.0f+(pparams->frametime*0.25f)); // get faster by time
if (delta > 0)
{
@ -393,7 +393,7 @@ void V_AddIdle ( struct ref_params_s *pparams )
pparams->viewangles[YAW] += v_idlescale * sin(pparams->time*v_iyaw_cycle.value) * v_iyaw_level.value;
}
/*
==============
V_CalcViewRoll
@ -1388,6 +1388,26 @@ int V_FindViewModelByWeaponModel(int weaponindex)
{
static char * modelmap[][2] = {
# ifdef _TFC // TFC models override HL models
{ "models/p_mini.mdl", "models/v_tfac.mdl" },
{ "models/p_sniper.mdl", "models/v_tfc_sniper.mdl" },
{ "models/p_umbrella.mdl", "models/v_umbrella.mdl" },
{ "models/p_crowbar.mdl", "models/v_tfc_crowbar.mdl" },
{ "models/p_spanner.mdl", "models/v_tfc_spanner.mdl" },
{ "models/p_knife.mdl", "models/v_tfc_knife.mdl" },
{ "models/p_medkit.mdl", "models/v_tfc_medkit.mdl" },
{ "models/p_egon.mdl", "models/v_flame.mdl" },
{ "models/p_glauncher.mdl", "models/v_tfgl.mdl" },
{ "models/p_rpg.mdl", "models/v_tfc_rpg.mdl" },
{ "models/p_nailgun.mdl", "models/v_tfc_nailgun.mdl" },
{ "models/p_snailgun.mdl", "models/v_tfc_supernailgun.mdl" },
{ "models/p_9mmhandgun.mdl", "models/v_tfc_railgun.mdl" },
{ "models/p_srpg.mdl", "models/v_tfc_rpg.mdl" },
{ "models/p_smallshotgun.mdl", "models/v_tfc_12gauge.mdl" },
{ "models/p_shotgun.mdl", "models/v_tfc_shotgun.mdl" },
{ "models/p_spygun.mdl", "models/v_tfc_pistol.mdl" },
#endif
{ "models/p_crossbow.mdl", "models/v_crossbow.mdl" },
{ "models/p_crowbar.mdl", "models/v_crowbar.mdl" },
{ "models/p_egon.mdl", "models/v_egon.mdl" },
@ -1473,7 +1493,11 @@ void V_CalcSpectatorRefdef ( struct ref_params_s * pparams )
}
// predict missing client data and set weapon model ( in HLTV mode or inset in eye mode )
#ifdef _TFC
if ( gEngfuncs.IsSpectateOnly() || gHUD.m_Spectator.m_pip->value == INSET_IN_EYE )
#else
if ( gEngfuncs.IsSpectateOnly() )
#endif
{
V_GetInEyePos( g_iUser2, pparams->simorg, pparams->cl_viewangles );
@ -1536,6 +1560,9 @@ void V_CalcSpectatorRefdef ( struct ref_params_s * pparams )
case OBS_ROAMING : VectorCopy (v_cl_angles, v_angles);
VectorCopy (v_sim_org, v_origin);
// override values if director is active
gHUD.m_Spectator.GetDirectorCamera(v_origin, v_angles);
break;
case OBS_IN_EYE : V_CalcNormalRefdef ( pparams );
@ -1602,8 +1629,10 @@ void V_CalcSpectatorRefdef ( struct ref_params_s * pparams )
void DLLEXPORT V_CalcRefdef( struct ref_params_s *pparams )
void CL_DLLEXPORT V_CalcRefdef( struct ref_params_s *pparams )
{
// RecClCalcRefdef(pparams);
// intermission / finale rendering
if ( pparams->intermission )
{

885
cl_dll/voice_status.cpp Normal file
View file

@ -0,0 +1,885 @@
//========= Copyright <20> 1996-2001, Valve LLC, All rights reserved. ============
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================
// There are hud.h's coming out of the woodwork so this ensures that we get the right one.
#if defined(THREEWAVE) || defined(DMC_BUILD)
#include "../dmc/cl_dll/hud.h"
#elif defined(CSTRIKE)
#include "../cstrike/cl_dll/hud.h"
#elif defined(DOD)
#include "../dod/cl_dll/hud.h"
#else
#include "hud.h"
#endif
#include "cl_util.h"
#include <assert.h>
#include <string.h>
#include <stdio.h>
#include "parsemsg.h"
#include "hud_servers.h"
#include "demo.h"
#include "demo_api.h"
#include "voice_status.h"
#include "r_efx.h"
#include "entity_types.h"
#include "VGUI_ActionSignal.h"
#include "VGUI_Scheme.h"
#include "VGUI_TextImage.h"
#include "vgui_loadtga.h"
#include "vgui_helpers.h"
#include "VGUI_MouseCode.h"
using namespace vgui;
extern int cam_thirdperson;
#define VOICE_MODEL_INTERVAL 0.3
#define SCOREBOARD_BLINK_FREQUENCY 0.3 // How often to blink the scoreboard icons.
#define SQUELCHOSCILLATE_PER_SECOND 2.0f
extern BitmapTGA *LoadTGA( const char* pImageName );
// ---------------------------------------------------------------------- //
// The voice manager for the client.
// ---------------------------------------------------------------------- //
CVoiceStatus g_VoiceStatus;
CVoiceStatus* GetClientVoiceMgr()
{
return &g_VoiceStatus;
}
// ---------------------------------------------------------------------- //
// CVoiceStatus.
// ---------------------------------------------------------------------- //
static CVoiceStatus *g_pInternalVoiceStatus = NULL;
int __MsgFunc_VoiceMask(const char *pszName, int iSize, void *pbuf)
{
if(g_pInternalVoiceStatus)
g_pInternalVoiceStatus->HandleVoiceMaskMsg(iSize, pbuf);
return 1;
}
int __MsgFunc_ReqState(const char *pszName, int iSize, void *pbuf)
{
if(g_pInternalVoiceStatus)
g_pInternalVoiceStatus->HandleReqStateMsg(iSize, pbuf);
return 1;
}
int g_BannedPlayerPrintCount;
void ForEachBannedPlayer(char id[16])
{
char str[256];
sprintf(str, "Ban %d: %2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x\n",
g_BannedPlayerPrintCount++,
id[0], id[1], id[2], id[3],
id[4], id[5], id[6], id[7],
id[8], id[9], id[10], id[11],
id[12], id[13], id[14], id[15]
);
#ifdef _WIN32
strupr(str);
#endif
gEngfuncs.pfnConsolePrint(str);
}
void ShowBannedCallback()
{
if(g_pInternalVoiceStatus)
{
g_BannedPlayerPrintCount = 0;
gEngfuncs.pfnConsolePrint("------- BANNED PLAYERS -------\n");
g_pInternalVoiceStatus->m_BanMgr.ForEachBannedPlayer(ForEachBannedPlayer);
gEngfuncs.pfnConsolePrint("------------------------------\n");
}
}
// ---------------------------------------------------------------------- //
// CVoiceStatus.
// ---------------------------------------------------------------------- //
CVoiceStatus::CVoiceStatus()
{
m_bBanMgrInitialized = false;
m_LastUpdateServerState = 0;
m_pSpeakerLabelIcon = NULL;
m_pScoreboardNeverSpoken = NULL;
m_pScoreboardNotSpeaking = NULL;
m_pScoreboardSpeaking = NULL;
m_pScoreboardSpeaking2 = NULL;
m_pScoreboardSquelch = NULL;
m_pScoreboardBanned = NULL;
m_pLocalBitmap = NULL;
m_pAckBitmap = NULL;
m_bTalking = m_bServerAcked = false;
memset(m_pBanButtons, 0, sizeof(m_pBanButtons));
m_pParentPanel = NULL;
m_bServerModEnable = -1;
m_pchGameDir = NULL;
}
CVoiceStatus::~CVoiceStatus()
{
g_pInternalVoiceStatus = NULL;
for(int i=0; i < MAX_VOICE_SPEAKERS; i++)
{
delete m_Labels[i].m_pLabel;
m_Labels[i].m_pLabel = NULL;
delete m_Labels[i].m_pIcon;
m_Labels[i].m_pIcon = NULL;
delete m_Labels[i].m_pBackground;
m_Labels[i].m_pBackground = NULL;
}
delete m_pLocalLabel;
m_pLocalLabel = NULL;
FreeBitmaps();
if(m_pchGameDir)
{
if(m_bBanMgrInitialized)
{
m_BanMgr.SaveState(m_pchGameDir);
}
free(m_pchGameDir);
}
}
int CVoiceStatus::Init(
IVoiceStatusHelper *pHelper,
Panel **pParentPanel)
{
// Setup the voice_modenable cvar.
gEngfuncs.pfnRegisterVariable("voice_modenable", "1", FCVAR_ARCHIVE);
gEngfuncs.pfnRegisterVariable("voice_clientdebug", "0", 0);
gEngfuncs.pfnAddCommand("voice_showbanned", ShowBannedCallback);
if(gEngfuncs.pfnGetGameDirectory())
{
m_BanMgr.Init(gEngfuncs.pfnGetGameDirectory());
m_bBanMgrInitialized = true;
}
assert(!g_pInternalVoiceStatus);
g_pInternalVoiceStatus = this;
m_BlinkTimer = 0;
m_VoiceHeadModel = NULL;
memset(m_Labels, 0, sizeof(m_Labels));
for(int i=0; i < MAX_VOICE_SPEAKERS; i++)
{
CVoiceLabel *pLabel = &m_Labels[i];
pLabel->m_pBackground = new Label("");
if(pLabel->m_pLabel = new Label(""))
{
pLabel->m_pLabel->setVisible( true );
pLabel->m_pLabel->setFont( Scheme::sf_primary2 );
pLabel->m_pLabel->setTextAlignment( Label::a_east );
pLabel->m_pLabel->setContentAlignment( Label::a_east );
pLabel->m_pLabel->setParent( pLabel->m_pBackground );
}
if( pLabel->m_pIcon = new ImagePanel( NULL ) )
{
pLabel->m_pIcon->setVisible( true );
pLabel->m_pIcon->setParent( pLabel->m_pBackground );
}
pLabel->m_clientindex = -1;
}
m_pLocalLabel = new ImagePanel(NULL);
m_bInSquelchMode = false;
m_pHelper = pHelper;
m_pParentPanel = pParentPanel;
gHUD.AddHudElem(this);
m_iFlags = HUD_ACTIVE;
HOOK_MESSAGE(VoiceMask);
HOOK_MESSAGE(ReqState);
// Cache the game directory for use when we shut down
const char *pchGameDirT = gEngfuncs.pfnGetGameDirectory();
m_pchGameDir = (char *)malloc(strlen(pchGameDirT) + 1);
strcpy(m_pchGameDir, pchGameDirT);
return 1;
}
int CVoiceStatus::VidInit()
{
FreeBitmaps();
if( m_pLocalBitmap = vgui_LoadTGA("gfx/vgui/icntlk_pl.tga") )
{
m_pLocalBitmap->setColor(Color(255,255,255,135));
}
if( m_pAckBitmap = vgui_LoadTGA("gfx/vgui/icntlk_sv.tga") )
{
m_pAckBitmap->setColor(Color(255,255,255,135)); // Give just a tiny bit of translucency so software draws correctly.
}
m_pLocalLabel->setImage( m_pLocalBitmap );
m_pLocalLabel->setVisible( false );
if( m_pSpeakerLabelIcon = vgui_LoadTGANoInvertAlpha("gfx/vgui/speaker4.tga" ) )
m_pSpeakerLabelIcon->setColor( Color(255,255,255,1) ); // Give just a tiny bit of translucency so software draws correctly.
if (m_pScoreboardNeverSpoken = vgui_LoadTGANoInvertAlpha("gfx/vgui/640_speaker1.tga"))
m_pScoreboardNeverSpoken->setColor(Color(255,255,255,1)); // Give just a tiny bit of translucency so software draws correctly.
if(m_pScoreboardNotSpeaking = vgui_LoadTGANoInvertAlpha("gfx/vgui/640_speaker2.tga"))
m_pScoreboardNotSpeaking->setColor(Color(255,255,255,1)); // Give just a tiny bit of translucency so software draws correctly.
if(m_pScoreboardSpeaking = vgui_LoadTGANoInvertAlpha("gfx/vgui/640_speaker3.tga"))
m_pScoreboardSpeaking->setColor(Color(255,255,255,1)); // Give just a tiny bit of translucency so software draws correctly.
if(m_pScoreboardSpeaking2 = vgui_LoadTGANoInvertAlpha("gfx/vgui/640_speaker4.tga"))
m_pScoreboardSpeaking2->setColor(Color(255,255,255,1)); // Give just a tiny bit of translucency so software draws correctly.
if(m_pScoreboardSquelch = vgui_LoadTGA("gfx/vgui/icntlk_squelch.tga"))
m_pScoreboardSquelch->setColor(Color(255,255,255,1)); // Give just a tiny bit of translucency so software draws correctly.
if(m_pScoreboardBanned = vgui_LoadTGA("gfx/vgui/640_voiceblocked.tga"))
m_pScoreboardBanned->setColor(Color(255,255,255,1)); // Give just a tiny bit of translucency so software draws correctly.
// Figure out the voice head model height.
m_VoiceHeadModelHeight = 45;
char *pFile = (char *)gEngfuncs.COM_LoadFile("scripts/voicemodel.txt", 5, NULL);
if(pFile)
{
char token[4096];
gEngfuncs.COM_ParseFile(pFile, token);
if(token[0] >= '0' && token[0] <= '9')
{
m_VoiceHeadModelHeight = (float)atof(token);
}
gEngfuncs.COM_FreeFile(pFile);
}
m_VoiceHeadModel = gEngfuncs.pfnSPR_Load("sprites/voiceicon.spr");
return TRUE;
}
void CVoiceStatus::Frame(double frametime)
{
// check server banned players once per second
if(gEngfuncs.GetClientTime() - m_LastUpdateServerState > 1)
{
UpdateServerState(false);
}
m_BlinkTimer += frametime;
// Update speaker labels.
if( m_pHelper->CanShowSpeakerLabels() )
{
for( int i=0; i < MAX_VOICE_SPEAKERS; i++ )
m_Labels[i].m_pBackground->setVisible( m_Labels[i].m_clientindex != -1 );
}
else
{
for( int i=0; i < MAX_VOICE_SPEAKERS; i++ )
m_Labels[i].m_pBackground->setVisible( false );
}
for(int i=0; i < VOICE_MAX_PLAYERS; i++)
UpdateBanButton(i);
}
void CVoiceStatus::CreateEntities()
{
if(!m_VoiceHeadModel)
return;
cl_entity_t *localPlayer = gEngfuncs.GetLocalPlayer();
int iOutModel = 0;
for(int i=0; i < VOICE_MAX_PLAYERS; i++)
{
if(!m_VoicePlayers[i])
continue;
cl_entity_s *pClient = gEngfuncs.GetEntityByIndex(i+1);
// Don't show an icon if the player is not in our PVS.
if(!pClient || pClient->curstate.messagenum < localPlayer->curstate.messagenum)
continue;
// Don't show an icon for dead or spectating players (ie: invisible entities).
if(pClient->curstate.effects & EF_NODRAW)
continue;
// Don't show an icon for the local player unless we're in thirdperson mode.
if(pClient == localPlayer && !cam_thirdperson)
continue;
cl_entity_s *pEnt = &m_VoiceHeadModels[iOutModel];
++iOutModel;
memset(pEnt, 0, sizeof(*pEnt));
pEnt->curstate.rendermode = kRenderTransAdd;
pEnt->curstate.renderamt = 255;
pEnt->baseline.renderamt = 255;
pEnt->curstate.renderfx = kRenderFxNoDissipation;
pEnt->curstate.framerate = 1;
pEnt->curstate.frame = 0;
pEnt->model = (struct model_s*)gEngfuncs.GetSpritePointer(m_VoiceHeadModel);
pEnt->angles[0] = pEnt->angles[1] = pEnt->angles[2] = 0;
pEnt->curstate.scale = 0.5f;
pEnt->origin[0] = pEnt->origin[1] = 0;
pEnt->origin[2] = 45;
VectorAdd(pEnt->origin, pClient->origin, pEnt->origin);
// Tell the engine.
gEngfuncs.CL_CreateVisibleEntity(ET_NORMAL, pEnt);
}
}
void CVoiceStatus::UpdateSpeakerStatus( int entindex, qboolean bTalking )
{
cvar_t *pVoiceLoopback = NULL;
if ( !m_pParentPanel || !*m_pParentPanel )
{
return;
}
if ( gEngfuncs.pfnGetCvarFloat( "voice_clientdebug" ) )
{
char msg[256];
_snprintf( msg, sizeof( msg ), "CVoiceStatus::UpdateSpeakerStatus: ent %d talking = %d\n", entindex, bTalking );
gEngfuncs.pfnConsolePrint( msg );
}
int iLocalPlayerIndex = gEngfuncs.GetLocalPlayer()->index;
// Is it the local player talking?
if ( entindex == -1 )
{
m_bTalking = !!bTalking;
if( bTalking )
{
// Enable voice for them automatically if they try to talk.
gEngfuncs.pfnClientCmd( "voice_modenable 1" );
}
// now set the player index to the correct index for the local player
// this will allow us to have the local player's icon flash in the scoreboard
entindex = iLocalPlayerIndex;
pVoiceLoopback = gEngfuncs.pfnGetCvarPointer( "voice_loopback" );
}
else if ( entindex == -2 )
{
m_bServerAcked = !!bTalking;
}
if ( entindex >= 0 && entindex <= VOICE_MAX_PLAYERS )
{
int iClient = entindex - 1;
if ( iClient < 0 )
{
return;
}
CVoiceLabel *pLabel = FindVoiceLabel( iClient );
if ( bTalking )
{
m_VoicePlayers[iClient] = true;
m_VoiceEnabledPlayers[iClient] = true;
// If we don't have a label for this guy yet, then create one.
if ( !pLabel )
{
// if this isn't the local player (unless they have voice_loopback on)
if ( ( entindex != iLocalPlayerIndex ) || ( pVoiceLoopback && pVoiceLoopback->value ) )
{
if ( pLabel = GetFreeVoiceLabel() )
{
// Get the name from the engine.
hud_player_info_t info;
memset( &info, 0, sizeof( info ) );
gEngfuncs.pfnGetPlayerInfo( entindex, &info );
char paddedName[512];
_snprintf( paddedName, sizeof( paddedName ), "%s ", info.name );
int color[3];
m_pHelper->GetPlayerTextColor( entindex, color );
if ( pLabel->m_pBackground )
{
pLabel->m_pBackground->setBgColor( color[0], color[1], color[2], 135 );
pLabel->m_pBackground->setParent( *m_pParentPanel );
pLabel->m_pBackground->setVisible( m_pHelper->CanShowSpeakerLabels() );
}
if ( pLabel->m_pLabel )
{
pLabel->m_pLabel->setFgColor( 255, 255, 255, 0 );
pLabel->m_pLabel->setBgColor( 0, 0, 0, 255 );
pLabel->m_pLabel->setText( "%s", paddedName );
}
pLabel->m_clientindex = iClient;
}
}
}
}
else
{
m_VoicePlayers[iClient] = false;
// If we have a label for this guy, kill it.
if ( pLabel )
{
pLabel->m_pBackground->setVisible( false );
pLabel->m_clientindex = -1;
}
}
}
RepositionLabels();
}
void CVoiceStatus::UpdateServerState(bool bForce)
{
// Can't do anything when we're not in a level.
char const *pLevelName = gEngfuncs.pfnGetLevelName();
if( pLevelName[0] == 0 )
{
if( gEngfuncs.pfnGetCvarFloat("voice_clientdebug") )
{
gEngfuncs.pfnConsolePrint( "CVoiceStatus::UpdateServerState: pLevelName[0]==0\n" );
}
return;
}
int bCVarModEnable = !!gEngfuncs.pfnGetCvarFloat("voice_modenable");
if(bForce || m_bServerModEnable != bCVarModEnable)
{
m_bServerModEnable = bCVarModEnable;
char str[256];
_snprintf(str, sizeof(str), "VModEnable %d", m_bServerModEnable);
ServerCmd(str);
if(gEngfuncs.pfnGetCvarFloat("voice_clientdebug"))
{
char msg[256];
sprintf(msg, "CVoiceStatus::UpdateServerState: Sending '%s'\n", str);
gEngfuncs.pfnConsolePrint(msg);
}
}
char str[2048];
sprintf(str, "vban");
bool bChange = false;
for(unsigned long dw=0; dw < VOICE_MAX_PLAYERS_DW; dw++)
{
unsigned long serverBanMask = 0;
unsigned long banMask = 0;
for(unsigned long i=0; i < 32; i++)
{
char playerID[16];
if(!gEngfuncs.GetPlayerUniqueID(i+1, playerID))
continue;
if(m_BanMgr.GetPlayerBan(playerID))
banMask |= 1 << i;
if(m_ServerBannedPlayers[dw*32 + i])
serverBanMask |= 1 << i;
}
if(serverBanMask != banMask)
bChange = true;
// Ok, the server needs to be updated.
char numStr[512];
sprintf(numStr, " %x", banMask);
strcat(str, numStr);
}
if(bChange || bForce)
{
if(gEngfuncs.pfnGetCvarFloat("voice_clientdebug"))
{
char msg[256];
sprintf(msg, "CVoiceStatus::UpdateServerState: Sending '%s'\n", str);
gEngfuncs.pfnConsolePrint(msg);
}
gEngfuncs.pfnServerCmdUnreliable(str); // Tell the server..
}
else
{
if (gEngfuncs.pfnGetCvarFloat("voice_clientdebug"))
{
gEngfuncs.pfnConsolePrint( "CVoiceStatus::UpdateServerState: no change\n" );
}
}
m_LastUpdateServerState = gEngfuncs.GetClientTime();
}
void CVoiceStatus::UpdateSpeakerImage(Label *pLabel, int iPlayer)
{
m_pBanButtons[iPlayer-1] = pLabel;
UpdateBanButton(iPlayer-1);
}
void CVoiceStatus::UpdateBanButton(int iClient)
{
Label *pPanel = m_pBanButtons[iClient];
if (!pPanel)
return;
char playerID[16];
extern bool HACK_GetPlayerUniqueID( int iPlayer, char playerID[16] );
if(!HACK_GetPlayerUniqueID(iClient+1, playerID))
return;
// Figure out if it's blinking or not.
bool bBlink = fmod(m_BlinkTimer, SCOREBOARD_BLINK_FREQUENCY*2) < SCOREBOARD_BLINK_FREQUENCY;
bool bTalking = !!m_VoicePlayers[iClient];
bool bBanned = m_BanMgr.GetPlayerBan(playerID);
bool bNeverSpoken = !m_VoiceEnabledPlayers[iClient];
// Get the appropriate image to display on the panel.
if (bBanned)
{
pPanel->setImage(m_pScoreboardBanned);
}
else if (bTalking)
{
if (bBlink)
{
pPanel->setImage(m_pScoreboardSpeaking2);
}
else
{
pPanel->setImage(m_pScoreboardSpeaking);
}
pPanel->setFgColor(255, 170, 0, 1);
}
else if (bNeverSpoken)
{
pPanel->setImage(m_pScoreboardNeverSpoken);
pPanel->setFgColor(100, 100, 100, 1);
}
else
{
pPanel->setImage(m_pScoreboardNotSpeaking);
}
}
void CVoiceStatus::HandleVoiceMaskMsg(int iSize, void *pbuf)
{
BEGIN_READ( pbuf, iSize );
unsigned long dw;
for(dw=0; dw < VOICE_MAX_PLAYERS_DW; dw++)
{
m_AudiblePlayers.SetDWord(dw, (unsigned long)READ_LONG());
m_ServerBannedPlayers.SetDWord(dw, (unsigned long)READ_LONG());
if(gEngfuncs.pfnGetCvarFloat("voice_clientdebug"))
{
char str[256];
gEngfuncs.pfnConsolePrint("CVoiceStatus::HandleVoiceMaskMsg\n");
sprintf(str, " - m_AudiblePlayers[%d] = %lu\n", dw, m_AudiblePlayers.GetDWord(dw));
gEngfuncs.pfnConsolePrint(str);
sprintf(str, " - m_ServerBannedPlayers[%d] = %lu\n", dw, m_ServerBannedPlayers.GetDWord(dw));
gEngfuncs.pfnConsolePrint(str);
}
}
m_bServerModEnable = READ_BYTE();
}
void CVoiceStatus::HandleReqStateMsg(int iSize, void *pbuf)
{
if(gEngfuncs.pfnGetCvarFloat("voice_clientdebug"))
{
gEngfuncs.pfnConsolePrint("CVoiceStatus::HandleReqStateMsg\n");
}
UpdateServerState(true);
}
void CVoiceStatus::StartSquelchMode()
{
if(m_bInSquelchMode)
return;
m_bInSquelchMode = true;
m_pHelper->UpdateCursorState();
}
void CVoiceStatus::StopSquelchMode()
{
m_bInSquelchMode = false;
m_pHelper->UpdateCursorState();
}
bool CVoiceStatus::IsInSquelchMode()
{
return m_bInSquelchMode;
}
CVoiceLabel* CVoiceStatus::FindVoiceLabel(int clientindex)
{
for(int i=0; i < MAX_VOICE_SPEAKERS; i++)
{
if(m_Labels[i].m_clientindex == clientindex)
return &m_Labels[i];
}
return NULL;
}
CVoiceLabel* CVoiceStatus::GetFreeVoiceLabel()
{
return FindVoiceLabel(-1);
}
void CVoiceStatus::RepositionLabels()
{
// find starting position to draw from, along right-hand side of screen
int y = ScreenHeight / 2;
int iconWide = 8, iconTall = 8;
if( m_pSpeakerLabelIcon )
{
m_pSpeakerLabelIcon->getSize( iconWide, iconTall );
}
// Reposition active labels.
for(int i = 0; i < MAX_VOICE_SPEAKERS; i++)
{
CVoiceLabel *pLabel = &m_Labels[i];
if( pLabel->m_clientindex == -1 || !pLabel->m_pLabel )
{
if( pLabel->m_pBackground )
pLabel->m_pBackground->setVisible( false );
continue;
}
int textWide, textTall;
pLabel->m_pLabel->getContentSize( textWide, textTall );
// Don't let it stretch too far across their screen.
if( textWide > (ScreenWidth*2)/3 )
textWide = (ScreenWidth*2)/3;
// Setup the background label to fit everything in.
int border = 2;
int bgWide = textWide + iconWide + border*3;
int bgTall = max( textTall, iconTall ) + border*2;
pLabel->m_pBackground->setBounds( ScreenWidth - bgWide - 8, y, bgWide, bgTall );
// Put the text at the left.
pLabel->m_pLabel->setBounds( border, (bgTall - textTall) / 2, textWide, textTall );
// Put the icon at the right.
int iconLeft = border + textWide + border;
int iconTop = (bgTall - iconTall) / 2;
if( pLabel->m_pIcon )
{
pLabel->m_pIcon->setImage( m_pSpeakerLabelIcon );
pLabel->m_pIcon->setBounds( iconLeft, iconTop, iconWide, iconTall );
}
y += bgTall + 2;
}
if( m_pLocalBitmap && m_pAckBitmap && m_pLocalLabel && (m_bTalking || m_bServerAcked) )
{
m_pLocalLabel->setParent(*m_pParentPanel);
m_pLocalLabel->setVisible( true );
if( m_bServerAcked && !!gEngfuncs.pfnGetCvarFloat("voice_clientdebug") )
m_pLocalLabel->setImage( m_pAckBitmap );
else
m_pLocalLabel->setImage( m_pLocalBitmap );
int sizeX, sizeY;
m_pLocalBitmap->getSize(sizeX, sizeY);
int local_xPos = ScreenWidth - sizeX - 10;
int local_yPos = m_pHelper->GetAckIconHeight() - sizeY;
m_pLocalLabel->setPos( local_xPos, local_yPos );
}
else
{
m_pLocalLabel->setVisible( false );
}
}
void CVoiceStatus::FreeBitmaps()
{
// Delete all the images we have loaded.
delete m_pLocalBitmap;
m_pLocalBitmap = NULL;
delete m_pAckBitmap;
m_pAckBitmap = NULL;
delete m_pSpeakerLabelIcon;
m_pSpeakerLabelIcon = NULL;
delete m_pScoreboardNeverSpoken;
m_pScoreboardNeverSpoken = NULL;
delete m_pScoreboardNotSpeaking;
m_pScoreboardNotSpeaking = NULL;
delete m_pScoreboardSpeaking;
m_pScoreboardSpeaking = NULL;
delete m_pScoreboardSpeaking2;
m_pScoreboardSpeaking2 = NULL;
delete m_pScoreboardSquelch;
m_pScoreboardSquelch = NULL;
delete m_pScoreboardBanned;
m_pScoreboardBanned = NULL;
// Clear references to the images in panels.
for(int i=0; i < VOICE_MAX_PLAYERS; i++)
{
if (m_pBanButtons[i])
{
m_pBanButtons[i]->setImage(NULL);
}
}
if(m_pLocalLabel)
m_pLocalLabel->setImage(NULL);
}
//-----------------------------------------------------------------------------
// Purpose: returns true if the target client has been banned
// Input : playerID -
// Output : Returns true on success, false on failure.
//-----------------------------------------------------------------------------
bool CVoiceStatus::IsPlayerBlocked(int iPlayer)
{
char playerID[16];
if (!gEngfuncs.GetPlayerUniqueID(iPlayer, playerID))
return false;
return m_BanMgr.GetPlayerBan(playerID);
}
//-----------------------------------------------------------------------------
// Purpose: returns true if the player can't hear the other client due to game rules (eg. the other team)
// Input : playerID -
// Output : Returns true on success, false on failure.
//-----------------------------------------------------------------------------
bool CVoiceStatus::IsPlayerAudible(int iPlayer)
{
return !!m_AudiblePlayers[iPlayer-1];
}
//-----------------------------------------------------------------------------
// Purpose: blocks/unblocks the target client from being heard
// Input : playerID -
// Output : Returns true on success, false on failure.
//-----------------------------------------------------------------------------
void CVoiceStatus::SetPlayerBlockedState(int iPlayer, bool blocked)
{
if (gEngfuncs.pfnGetCvarFloat("voice_clientdebug"))
{
gEngfuncs.pfnConsolePrint( "CVoiceStatus::SetPlayerBlockedState part 1\n" );
}
char playerID[16];
if (!gEngfuncs.GetPlayerUniqueID(iPlayer, playerID))
return;
if (gEngfuncs.pfnGetCvarFloat("voice_clientdebug"))
{
gEngfuncs.pfnConsolePrint( "CVoiceStatus::SetPlayerBlockedState part 2\n" );
}
// Squelch or (try to) unsquelch this player.
if (gEngfuncs.pfnGetCvarFloat("voice_clientdebug"))
{
char str[256];
sprintf(str, "CVoiceStatus::SetPlayerBlockedState: setting player %d ban to %d\n", iPlayer, !m_BanMgr.GetPlayerBan(playerID));
gEngfuncs.pfnConsolePrint(str);
}
m_BanMgr.SetPlayerBan( playerID, blocked );
UpdateServerState(false);
}

228
cl_dll/voice_status.h Normal file
View file

@ -0,0 +1,228 @@
//========= Copyright © 1996-2001, Valve LLC, All rights reserved. ============
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================
#ifndef VOICE_STATUS_H
#define VOICE_STATUS_H
#pragma once
#include "VGUI_Label.h"
#include "VGUI_LineBorder.h"
#include "VGUI_ImagePanel.h"
#include "VGUI_BitmapTGA.h"
#include "VGUI_InputSignal.h"
#include "VGUI_Button.h"
#include "voice_common.h"
#include "cl_entity.h"
#include "voice_banmgr.h"
#include "vgui_checkbutton2.h"
#include "vgui_defaultinputsignal.h"
class CVoiceStatus;
class CVoiceLabel
{
public:
vgui::Label *m_pLabel;
vgui::Label *m_pBackground;
vgui::ImagePanel *m_pIcon; // Voice icon next to player name.
int m_clientindex; // Client index of the speaker. -1 if this label isn't being used.
};
// This is provided by each mod to access data that may not be the same across mods.
class IVoiceStatusHelper
{
public:
virtual ~IVoiceStatusHelper() {}
// Get RGB color for voice status text about this player.
virtual void GetPlayerTextColor(int entindex, int color[3]) = 0;
// Force it to update the cursor state.
virtual void UpdateCursorState() = 0;
// Return the height above the bottom that the voice ack icons should be drawn at.
virtual int GetAckIconHeight() = 0;
// Return true if the voice manager is allowed to show speaker labels
// (mods usually return false when the scoreboard is up).
virtual bool CanShowSpeakerLabels() = 0;
};
//-----------------------------------------------------------------------------
// Purpose: Holds a color for the shared image
//-----------------------------------------------------------------------------
class VoiceImagePanel : public vgui::ImagePanel
{
virtual void paintBackground()
{
if (_image!=null)
{
vgui::Color col;
getFgColor(col);
_image->setColor(col);
_image->doPaint(this);
}
}
};
class CVoiceStatus : public CHudBase, public vgui::CDefaultInputSignal
{
public:
CVoiceStatus();
virtual ~CVoiceStatus();
// CHudBase overrides.
public:
// Initialize the cl_dll's voice manager.
virtual int Init(
IVoiceStatusHelper *m_pHelper,
vgui::Panel **pParentPanel);
// ackPosition is the bottom position of where CVoiceStatus will draw the voice acknowledgement labels.
virtual int VidInit();
public:
// Call from HUD_Frame each frame.
void Frame(double frametime);
// Called when a player starts or stops talking.
// entindex is -1 to represent the local client talking (before the data comes back from the server).
// When the server acknowledges that the local client is talking, then entindex will be gEngfuncs.GetLocalPlayer().
// entindex is -2 to represent the local client's voice being acked by the server.
void UpdateSpeakerStatus(int entindex, qboolean bTalking);
// sets the correct image in the label for the player
void UpdateSpeakerImage(vgui::Label *pLabel, int iPlayer);
// Call from the HUD_CreateEntities function so it can add sprites above player heads.
void CreateEntities();
// Called when the server registers a change to who this client can hear.
void HandleVoiceMaskMsg(int iSize, void *pbuf);
// The server sends this message initially to tell the client to send their state.
void HandleReqStateMsg(int iSize, void *pbuf);
// Squelch mode functions.
public:
// When you enter squelch mode, pass in
void StartSquelchMode();
void StopSquelchMode();
bool IsInSquelchMode();
// returns true if the target client has been banned
// playerIndex is of range 1..maxplayers
bool IsPlayerBlocked(int iPlayerIndex);
// returns false if the player can't hear the other client due to game rules (eg. the other team)
bool IsPlayerAudible(int iPlayerIndex);
// blocks the target client from being heard
void SetPlayerBlockedState(int iPlayerIndex, bool blocked);
public:
CVoiceLabel* FindVoiceLabel(int clientindex); // Find a CVoiceLabel representing the specified speaker.
// Returns NULL if none.
// entindex can be -1 if you want a currently-unused voice label.
CVoiceLabel* GetFreeVoiceLabel(); // Get an unused voice label. Returns NULL if none.
void RepositionLabels();
void FreeBitmaps();
void UpdateServerState(bool bForce);
// Update the button artwork to reflect the client's current state.
void UpdateBanButton(int iClient);
public:
enum {MAX_VOICE_SPEAKERS=7};
float m_LastUpdateServerState; // Last time we called this function.
int m_bServerModEnable; // What we've sent to the server about our "voice_modenable" cvar.
vgui::Panel **m_pParentPanel;
CPlayerBitVec m_VoicePlayers; // Who is currently talking. Indexed by client index.
// This is the gamerules-defined list of players that you can hear. It is based on what teams people are on
// and is totally separate from the ban list. Indexed by client index.
CPlayerBitVec m_AudiblePlayers;
// Players who have spoken at least once in the game so far
CPlayerBitVec m_VoiceEnabledPlayers;
// This is who the server THINKS we have banned (it can become incorrect when a new player arrives on the server).
// It is checked periodically, and the server is told to squelch or unsquelch the appropriate players.
CPlayerBitVec m_ServerBannedPlayers;
cl_entity_s m_VoiceHeadModels[VOICE_MAX_PLAYERS]; // These aren't necessarily in the order of players. They are just
// a place for it to put data in during CreateEntities.
IVoiceStatusHelper *m_pHelper; // Each mod provides an implementation of this.
// Scoreboard icons.
double m_BlinkTimer; // Blink scoreboard icons..
vgui::BitmapTGA *m_pScoreboardNeverSpoken;
vgui::BitmapTGA *m_pScoreboardNotSpeaking;
vgui::BitmapTGA *m_pScoreboardSpeaking;
vgui::BitmapTGA *m_pScoreboardSpeaking2;
vgui::BitmapTGA *m_pScoreboardSquelch;
vgui::BitmapTGA *m_pScoreboardBanned;
vgui::Label *m_pBanButtons[VOICE_MAX_PLAYERS]; // scoreboard buttons.
// Squelch mode stuff.
bool m_bInSquelchMode;
HSPRITE m_VoiceHeadModel; // Voice head model (goes above players who are speaking).
float m_VoiceHeadModelHeight; // Height above their head to place the model.
vgui::Image *m_pSpeakerLabelIcon; // Icon next to speaker labels.
// Lower-right icons telling when the local player is talking..
vgui::BitmapTGA *m_pLocalBitmap; // Represents the local client talking.
vgui::BitmapTGA *m_pAckBitmap; // Represents the server ack'ing the client talking.
vgui::ImagePanel *m_pLocalLabel; // Represents the local client talking.
bool m_bTalking; // Set to true when the client thinks it's talking.
bool m_bServerAcked; // Set to true when the server knows the client is talking.
public:
CVoiceBanMgr m_BanMgr; // Tracks which users we have squelched and don't want to hear.
public:
bool m_bBanMgrInitialized;
// Labels telling who is speaking.
CVoiceLabel m_Labels[MAX_VOICE_SPEAKERS];
// Cache the game directory for use when we shut down
char * m_pchGameDir;
};
// Get the (global) voice manager.
CVoiceStatus* GetClientVoiceMgr();
#endif // VOICE_STATUS_H

201
common/Sequence.h Normal file
View file

@ -0,0 +1,201 @@
//---------------------------------------------------------------------------
//
// S c r i p t e d S e q u e n c e s
//
//---------------------------------------------------------------------------
#ifndef _INCLUDE_SEQUENCE_H_
#define _INCLUDE_SEQUENCE_H_
#ifndef _DEF_BYTE_
typedef unsigned char byte;
#endif
//---------------------------------------------------------------------------
// client_textmessage_t
//---------------------------------------------------------------------------
typedef struct client_textmessage_s
{
int effect;
byte r1, g1, b1, a1; // 2 colors for effects
byte r2, g2, b2, a2;
float x;
float y;
float fadein;
float fadeout;
float holdtime;
float fxtime;
const char *pName;
const char *pMessage;
} client_textmessage_t;
//--------------------------------------------------------------------------
// sequenceDefaultBits_e
//
// Enumerated list of possible modifiers for a command. This enumeration
// is used in a bitarray controlling what modifiers are specified for a command.
//---------------------------------------------------------------------------
enum sequenceModifierBits
{
SEQUENCE_MODIFIER_EFFECT_BIT = (1 << 1),
SEQUENCE_MODIFIER_POSITION_BIT = (1 << 2),
SEQUENCE_MODIFIER_COLOR_BIT = (1 << 3),
SEQUENCE_MODIFIER_COLOR2_BIT = (1 << 4),
SEQUENCE_MODIFIER_FADEIN_BIT = (1 << 5),
SEQUENCE_MODIFIER_FADEOUT_BIT = (1 << 6),
SEQUENCE_MODIFIER_HOLDTIME_BIT = (1 << 7),
SEQUENCE_MODIFIER_FXTIME_BIT = (1 << 8),
SEQUENCE_MODIFIER_SPEAKER_BIT = (1 << 9),
SEQUENCE_MODIFIER_LISTENER_BIT = (1 << 10),
SEQUENCE_MODIFIER_TEXTCHANNEL_BIT = (1 << 11),
};
typedef enum sequenceModifierBits sequenceModifierBits_e ;
//---------------------------------------------------------------------------
// sequenceCommandEnum_e
//
// Enumerated sequence command types.
//---------------------------------------------------------------------------
enum sequenceCommandEnum_
{
SEQUENCE_COMMAND_ERROR = -1,
SEQUENCE_COMMAND_PAUSE = 0,
SEQUENCE_COMMAND_FIRETARGETS,
SEQUENCE_COMMAND_KILLTARGETS,
SEQUENCE_COMMAND_TEXT,
SEQUENCE_COMMAND_SOUND,
SEQUENCE_COMMAND_GOSUB,
SEQUENCE_COMMAND_SENTENCE,
SEQUENCE_COMMAND_REPEAT,
SEQUENCE_COMMAND_SETDEFAULTS,
SEQUENCE_COMMAND_MODIFIER,
SEQUENCE_COMMAND_POSTMODIFIER,
SEQUENCE_COMMAND_NOOP,
SEQUENCE_MODIFIER_EFFECT,
SEQUENCE_MODIFIER_POSITION,
SEQUENCE_MODIFIER_COLOR,
SEQUENCE_MODIFIER_COLOR2,
SEQUENCE_MODIFIER_FADEIN,
SEQUENCE_MODIFIER_FADEOUT,
SEQUENCE_MODIFIER_HOLDTIME,
SEQUENCE_MODIFIER_FXTIME,
SEQUENCE_MODIFIER_SPEAKER,
SEQUENCE_MODIFIER_LISTENER,
SEQUENCE_MODIFIER_TEXTCHANNEL,
};
typedef enum sequenceCommandEnum_ sequenceCommandEnum_e;
//---------------------------------------------------------------------------
// sequenceCommandType_e
//
// Typeerated sequence command types.
//---------------------------------------------------------------------------
enum sequenceCommandType_
{
SEQUENCE_TYPE_COMMAND,
SEQUENCE_TYPE_MODIFIER,
};
typedef enum sequenceCommandType_ sequenceCommandType_e;
//---------------------------------------------------------------------------
// sequenceCommandMapping_s
//
// A mapping of a command enumerated-value to its name.
//---------------------------------------------------------------------------
typedef struct sequenceCommandMapping_ sequenceCommandMapping_s;
struct sequenceCommandMapping_
{
sequenceCommandEnum_e commandEnum;
const char* commandName;
sequenceCommandType_e commandType;
};
//---------------------------------------------------------------------------
// sequenceCommandLine_s
//
// Structure representing a single command (usually 1 line) from a
// .SEQ file entry.
//---------------------------------------------------------------------------
typedef struct sequenceCommandLine_ sequenceCommandLine_s;
struct sequenceCommandLine_
{
int commandType; // Specifies the type of command
client_textmessage_t clientMessage; // Text HUD message struct
char* speakerName; // Targetname of speaking entity
char* listenerName; // Targetname of entity being spoken to
char* soundFileName; // Name of sound file to play
char* sentenceName; // Name of sentences.txt to play
char* fireTargetNames; // List of targetnames to fire
char* killTargetNames; // List of targetnames to remove
float delay; // Seconds 'till next command
int repeatCount; // If nonzero, reset execution pointer to top of block (N times, -1 = infinite)
int textChannel; // Display channel on which text message is sent
int modifierBitField; // Bit field to specify what clientmessage fields are valid
sequenceCommandLine_s* nextCommandLine; // Next command (linked list)
};
//---------------------------------------------------------------------------
// sequenceEntry_s
//
// Structure representing a single command (usually 1 line) from a
// .SEQ file entry.
//---------------------------------------------------------------------------
typedef struct sequenceEntry_ sequenceEntry_s;
struct sequenceEntry_
{
char* fileName; // Name of sequence file without .SEQ extension
char* entryName; // Name of entry label in file
sequenceCommandLine_s* firstCommand; // Linked list of commands in entry
sequenceEntry_s* nextEntry; // Next loaded entry
qboolean isGlobal; // Is entry retained over level transitions?
};
//---------------------------------------------------------------------------
// sentenceEntry_s
// Structure representing a single sentence of a group from a .SEQ
// file entry. Sentences are identical to entries in sentences.txt, but
// can be unique per level and are loaded/unloaded with the level.
//---------------------------------------------------------------------------
typedef struct sentenceEntry_ sentenceEntry_s;
struct sentenceEntry_
{
char* data; // sentence data (ie "We have hostiles" )
sentenceEntry_s* nextEntry; // Next loaded entry
qboolean isGlobal; // Is entry retained over level transitions?
unsigned int index; // this entry's position in the file.
};
//--------------------------------------------------------------------------
// sentenceGroupEntry_s
// Structure representing a group of sentences found in a .SEQ file.
// A sentence group is defined by all sentences with the same name, ignoring
// the number at the end of the sentence name. Groups enable a sentence
// to be picked at random across a group.
//--------------------------------------------------------------------------
typedef struct sentenceGroupEntry_ sentenceGroupEntry_s;
struct sentenceGroupEntry_
{
char* groupName; // name of the group (ie CT_ALERT )
unsigned int numSentences; // number of sentences in group
sentenceEntry_s* firstSentence; // head of linked list of sentences in group
sentenceGroupEntry_s* nextEntry; // next loaded group
};
//---------------------------------------------------------------------------
// Function declarations
//---------------------------------------------------------------------------
sequenceEntry_s* SequenceGet( const char* fileName, const char* entryName );
void Sequence_ParseFile( const char* fileName, qboolean isGlobal );
void Sequence_OnLevelLoad( const char* mapName );
sentenceEntry_s* SequencePickSentence( const char *groupName, int pickMethod, int *picked );
#endif // _INCLUDE_SEQUENCE_H_

View file

@ -18,6 +18,10 @@
#pragma once
#endif
#ifdef __cplusplus
extern "C" {
#endif
typedef struct con_nprint_s
{
int index; // Row #
@ -27,5 +31,8 @@ typedef struct con_nprint_s
void Con_NPrintf( int idx, char *fmt, ... );
void Con_NXPrintf( struct con_nprint_s *info, char *fmt, ... );
#ifdef __cplusplus
}
#endif
#endif

View file

@ -109,6 +109,10 @@
#define EF_NOINTERP 32 // don't interpolate the next frame
#define EF_LIGHT 64 // rocket flare glow sprite
#define EF_NODRAW 128 // don't draw entity
#define EF_NIGHTVISION 256 // player nightvision
#define EF_SNIPERLASER 512 // sniper laser effect
#define EF_FIBERCAMERA 1024// fiber camera
// entity flags
#define EFLAG_SLERP 1 // do studio interpolation of this entity
@ -520,6 +524,7 @@
#define TEFIRE_FLAG_LOOP 4 // if set, sprite plays at 15 fps, otherwise plays at whatever rate stretches the animation over the sprite's duration.
#define TEFIRE_FLAG_ALPHA 8 // if set, sprite is rendered alpha blended at 50% else, opaque
#define TEFIRE_FLAG_PLANAR 16 // if set, all fire sprites have same initial Z instead of randomly filling a cube.
#define TEFIRE_FLAG_ADDITIVE 32 // if set, sprite is rendered non-opaque with additive
#define TE_PLAYERATTACHMENT 124 // attaches a TENT to a player (this is a high-priority tent)
// byte (entity index of player)
@ -592,7 +597,7 @@
#define CONTENTS_TRANSLUCENT -15
*/
#define CONTENTS_LADDER -16
#define CONTENTS_LADDER -16
#define CONTENT_FLYFIELD -17
#define CONTENT_GRAVITY_FLYFIELD -18
@ -615,6 +620,7 @@
#define CHAN_STATIC 6 // allocate channel from the static area
#define CHAN_NETWORKVOICE_BASE 7 // voice data coming across the network
#define CHAN_NETWORKVOICE_END 500 // network voice data reserves slots (CHAN_NETWORKVOICE_BASE through CHAN_NETWORKVOICE_END).
#define CHAN_BOT 501 // channel used for bot chatter.
// attenuation values
#define ATTN_NONE 0
@ -706,11 +712,12 @@ enum
kRenderFxExplode, // Scale up really big!
kRenderFxGlowShell, // Glowing Shell
kRenderFxClampMinScale, // Keep this sprite from getting very small (SPRITES only!)
kRenderFxLightMultiplier, //CTM !!!CZERO added to tell the studiorender that the value in iuser2 is a lightmultiplier
};
typedef int func_t;
typedef int string_t;
typedef unsigned int func_t;
typedef unsigned int string_t;
typedef unsigned char byte;
typedef unsigned short word;

View file

@ -19,6 +19,8 @@
#pragma once
#endif
#include "archtypes.h" // DAL
// MD5 Hash
typedef struct
{
@ -28,13 +30,24 @@ typedef struct
} MD5Context_t;
typedef unsigned long CRC32_t;
#ifdef _WIN32
typedef uint32 CRC32_t;
#else
typedef uint32 CRC32_t;
#endif
#ifdef __cplusplus
extern "C"
{
#endif
void CRC32_Init(CRC32_t *pulCRC);
CRC32_t CRC32_Final(CRC32_t pulCRC);
void CRC32_ProcessBuffer(CRC32_t *pulCRC, void *p, int len);
void CRC32_ProcessByte(CRC32_t *pulCRC, unsigned char ch);
int CRC_File(CRC32_t *crcvalue, char *pszFileName);
#ifdef __cplusplus
}
#endif
unsigned char COM_BlockSequenceCRCByte (unsigned char *base, int length, int sequence);
void MD5Init(MD5Context_t *context);

View file

@ -24,6 +24,7 @@
#define FCVAR_SPONLY (1<<6) // This cvar cannot be changed by clients connected to a multiplayer server.
#define FCVAR_PRINTABLEONLY (1<<7) // This cvar's string cannot contain unprintable characters ( e.g., used for player name etc ).
#define FCVAR_UNLOGGED (1<<8) // If this is a FCVAR_SERVER, don't log changes to the log file / console if we are creating a log
#define FCVAR_NOEXTRAWHITEPACE (1<<9) // strip trailing/leading white space from this cvar
typedef struct cvar_s
{

View file

@ -187,7 +187,7 @@ typedef struct local_state_s
{
entity_state_t playerstate;
clientdata_t client;
weapon_data_t weapondata[ 32 ];
weapon_data_t weapondata[ 64 ];
} local_state_t;
#endif // !ENTITY_STATEH

27
common/enums.h Normal file
View file

@ -0,0 +1,27 @@
/***
*
* Copyright (c) 2009, Valve LLC. All rights reserved.
*
* This product contains software technology licensed from Id
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
* All Rights Reserved.
*
* Use, distribution, and modification of this source code and/or resulting
* object code is restricted to non-commercial enhancements to products from
* Valve LLC. All other use, distribution, or modification is prohibited
* without written permission from Valve LLC.
*
****/
#ifndef ENUMS_H
#define ENUMS_H
typedef enum netsrc_s
{
NS_CLIENT,
NS_SERVER,
NS_MULTICAST // xxxMO
} netsrc_t;
#endif

View file

@ -1,10 +1,3 @@
//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================
// hltv.h
// all shared consts between server, clients and proxy
@ -15,31 +8,34 @@
#define TYPE_PROXY 1 // client is another proxy
#define TYPE_COMMENTATOR 3 // client is a commentator
#define TYPE_DEMO 4 // client is a demo file
// sub commands of svc_hltv:
#define HLTV_ACTIVE 0 // tells client that he's an spectator and will get director commands
#define HLTV_STATUS 1 // send status infos about proxy
#define HLTV_LISTEN 2 // tell client to listen to a multicast stream
// sub commands of svc_director:
// director command types:
#define DRC_CMD_NONE 0 // NULL director command
#define DRC_CMD_START 1 // start director mode
#define DRC_CMD_EVENT 2 // informs about director command
#define DRC_CMD_MODE 3 // switches camera modes
#define DRC_CMD_CAMERA 4 // sets camera registers
#define DRC_CMD_CAMERA 4 // set fixed camera
#define DRC_CMD_TIMESCALE 5 // sets time scale
#define DRC_CMD_MESSAGE 6 // send HUD centerprint
#define DRC_CMD_SOUND 7 // plays a particular sound
#define DRC_CMD_STATUS 8 // status info about broadcast
#define DRC_CMD_BANNER 9 // banner file name for HLTV gui
#define DRC_CMD_FADE 10 // send screen fade command
#define DRC_CMD_SHAKE 11 // send screen shake command
#define DRC_CMD_STUFFTEXT 12 // like the normal svc_stufftext but as director command
#define DRC_CMD_STATUS 8 // HLTV broadcast status
#define DRC_CMD_BANNER 9 // set GUI banner
#define DRC_CMD_STUFFTEXT 10 // like the normal svc_stufftext but as director command
#define DRC_CMD_CHASE 11 // chase a certain player
#define DRC_CMD_INEYE 12 // view player through own eyes
#define DRC_CMD_MAP 13 // show overview map
#define DRC_CMD_CAMPATH 14 // define camera waypoint
#define DRC_CMD_WAYPOINTS 15 // start moving camera, inetranl message
#define DRC_CMD_LAST 12
#define DRC_CMD_LAST 15
// HLTV_EVENT event flags
// DRC_CMD_EVENT event flags
#define DRC_FLAG_PRIO_MASK 0x0F // priorities between 0 and 15 (15 most important)
#define DRC_FLAG_SIDE (1<<4) //
#define DRC_FLAG_DRAMATIC (1<<5) // is a dramatic scene
@ -50,8 +46,9 @@
#define DRC_FLAG_NO_RANDOM (1<<10) // don't randomize event data
#define MAX_DIRECTOR_CMD_PARAMETERS 4
#define MAX_DIRECTOR_CMD_STRING 128
// DRC_CMD_WAYPOINT flags
#define DRC_FLAG_STARTPATH 1 // end with speed 0.0
#define DRC_FLAG_SLOWSTART 2 // start with speed 0.0
#define DRC_FLAG_SLOWEND 4 // end with speed 0.0
#endif // HLTV_H

View file

@ -15,7 +15,8 @@
typedef enum
{
MicrophoneVolume=0, // values 0-1.
OtherSpeakerScale // values 0-1. Scales how loud other players are.
OtherSpeakerScale, // values 0-1. Scales how loud other players are.
MicBoost, // 20 db gain to voice input
} VoiceTweakControl;
@ -29,6 +30,8 @@ typedef struct IVoiceTweak_s
// Get/set control values.
void (*SetControlFloat)(VoiceTweakControl iControl, float value);
float (*GetControlFloat)(VoiceTweakControl iControl);
int (*GetSpeakingVolume)();
} IVoiceTweak;

View file

@ -15,7 +15,10 @@
// mathlib.h
typedef float vec_t;
#ifndef DID_VEC3_T_DEFINE
#define DID_VEC3_T_DEFINE
typedef vec_t vec3_t[3];
#endif
typedef vec_t vec4_t[4]; // x,y,z,w
typedef vec_t vec5_t[5];
@ -27,7 +30,6 @@ typedef vec_s_t vec5s_t[5];
typedef int fixed4_t;
typedef int fixed8_t;
typedef int fixed16_t;
#ifndef M_PI
#define M_PI 3.14159265358979323846 // matches value in gcc v2 math.h
#endif

View file

@ -1,4 +1,4 @@
//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============
//========= Copyright © 1996-2001, Valve LLC, All rights reserved. ============
//
// Purpose:
//
@ -10,6 +10,7 @@
#ifndef _WIN32
#include <unistd.h>
#include <sys/types.h>
#endif //!_WIN32
#endif //INC_NOWIN_H
#endif //INC_NOWIN_H

259
common/parsemsg.cpp Normal file
View file

@ -0,0 +1,259 @@
/***
*
* Copyright (c) 1999, Valve LLC. All rights reserved.
*
* This product contains software technology licensed from Id
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
* All Rights Reserved.
*
* Use, distribution, and modification of this source code and/or resulting
* object code is restricted to non-commercial enhancements to products from
* Valve LLC. All other use, distribution, or modification is prohibited
* without written permission from Valve LLC.
*
****/
//
// parsemsg.cpp
//
//--------------------------------------------------------------------------------------------------------------
#include "parsemsg.h"
#include <port.h>
typedef unsigned char byte;
#define true 1
static byte *gpBuf;
static int giSize;
static int giRead;
static int giBadRead;
int READ_OK( void )
{
return !giBadRead;
}
void BEGIN_READ( void *buf, int size )
{
giRead = 0;
giBadRead = 0;
giSize = size;
gpBuf = (byte*)buf;
}
int READ_CHAR( void )
{
int c;
if (giRead + 1 > giSize)
{
giBadRead = true;
return -1;
}
c = (signed char)gpBuf[giRead];
giRead++;
return c;
}
int READ_BYTE( void )
{
int c;
if (giRead+1 > giSize)
{
giBadRead = true;
return -1;
}
c = (unsigned char)gpBuf[giRead];
giRead++;
return c;
}
int READ_SHORT( void )
{
int c;
if (giRead+2 > giSize)
{
giBadRead = true;
return -1;
}
c = (short)( gpBuf[giRead] + ( gpBuf[giRead+1] << 8 ) );
giRead += 2;
return c;
}
int READ_WORD( void )
{
return READ_SHORT();
}
int READ_LONG( void )
{
int c;
if (giRead+4 > giSize)
{
giBadRead = true;
return -1;
}
c = gpBuf[giRead] + (gpBuf[giRead + 1] << 8) + (gpBuf[giRead + 2] << 16) + (gpBuf[giRead + 3] << 24);
giRead += 4;
return c;
}
float READ_FLOAT( void )
{
union
{
byte b[4];
float f;
int l;
} dat;
dat.b[0] = gpBuf[giRead];
dat.b[1] = gpBuf[giRead+1];
dat.b[2] = gpBuf[giRead+2];
dat.b[3] = gpBuf[giRead+3];
giRead += 4;
// dat.l = LittleLong (dat.l);
return dat.f;
}
char* READ_STRING( void )
{
static char string[2048];
int l,c;
string[0] = 0;
l = 0;
do
{
if ( giRead+1 > giSize )
break; // no more characters
c = READ_CHAR();
if (c == -1 || c == 0)
break;
string[l] = c;
l++;
} while (l < sizeof(string)-1);
string[l] = 0;
return string;
}
float READ_COORD( void )
{
return (float)(READ_SHORT() * (1.0/8));
}
float READ_ANGLE( void )
{
return (float)(READ_CHAR() * (360.0/256));
}
float READ_HIRESANGLE( void )
{
return (float)(READ_SHORT() * (360.0/65536));
}
//--------------------------------------------------------------------------------------------------------------
BufferWriter::BufferWriter()
{
Init( NULL, 0 );
}
//--------------------------------------------------------------------------------------------------------------
BufferWriter::BufferWriter( unsigned char *buffer, int bufferLen )
{
Init( buffer, bufferLen );
}
//--------------------------------------------------------------------------------------------------------------
void BufferWriter::Init( unsigned char *buffer, int bufferLen )
{
m_overflow = false;
m_buffer = buffer;
m_remaining = bufferLen;
m_overallLength = bufferLen;
}
//--------------------------------------------------------------------------------------------------------------
void BufferWriter::WriteByte( unsigned char data )
{
if (!m_buffer || !m_remaining)
{
m_overflow = true;
return;
}
*m_buffer = data;
++m_buffer;
--m_remaining;
}
//--------------------------------------------------------------------------------------------------------------
void BufferWriter::WriteLong( int data )
{
if (!m_buffer || m_remaining < 4)
{
m_overflow = true;
return;
}
m_buffer[0] = data&0xff;
m_buffer[1] = (data>>8)&0xff;
m_buffer[2] = (data>>16)&0xff;
m_buffer[3] = data>>24;
m_buffer += 4;
m_remaining -= 4;
}
//--------------------------------------------------------------------------------------------------------------
void BufferWriter::WriteString( const char *str )
{
if (!m_buffer || !m_remaining)
{
m_overflow = true;
return;
}
if (!str)
str = "";
int len = strlen(str)+1;
if ( len > m_remaining )
{
m_overflow = true;
str = "";
len = 1;
}
strcpy((char *)m_buffer, str);
m_remaining -= len;
m_buffer += len;
}
//--------------------------------------------------------------------------------------------------------------
int BufferWriter::GetSpaceUsed()
{
return m_overallLength - m_remaining;
}
//--------------------------------------------------------------------------------------------------------------

66
common/parsemsg.h Normal file
View file

@ -0,0 +1,66 @@
/***
*
* Copyright (c) 1999, Valve LLC. All rights reserved.
*
* This product contains software technology licensed from Id
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
* All Rights Reserved.
*
* Use, distribution, and modification of this source code and/or resulting
* object code is restricted to non-commercial enhancements to products from
* Valve LLC. All other use, distribution, or modification is prohibited
* without written permission from Valve LLC.
*
****/
//
// parsemsg.h
// MDC - copying from cstrike\cl_dll so career-mode stuff can catch messages
// in this dll. (and C++ifying it)
//
#ifndef PARSEMSG_H
#define PARSEMSG_H
#define ASSERT( x )
//--------------------------------------------------------------------------------------------------------------
void BEGIN_READ( void *buf, int size );
int READ_CHAR( void );
int READ_BYTE( void );
int READ_SHORT( void );
int READ_WORD( void );
int READ_LONG( void );
float READ_FLOAT( void );
char* READ_STRING( void );
float READ_COORD( void );
float READ_ANGLE( void );
float READ_HIRESANGLE( void );
int READ_OK( void );
//--------------------------------------------------------------------------------------------------------------
class BufferWriter
{
public:
BufferWriter();
BufferWriter( unsigned char *buffer, int bufferLen );
void Init( unsigned char *buffer, int bufferLen );
void WriteByte( unsigned char data );
void WriteLong( int data );
void WriteString( const char *str );
bool HasOverflowed();
int GetSpaceUsed();
protected:
unsigned char *m_buffer;
int m_remaining;
bool m_overflow;
int m_overallLength;
};
//--------------------------------------------------------------------------------------------------------------
#endif // PARSEMSG_H

124
common/port.h Normal file
View file

@ -0,0 +1,124 @@
// port.h: portability helper
//
//////////////////////////////////////////////////////////////////////
#if !defined PORT_H
#define PORT_H
#include "archtypes.h" // DAL
#ifdef _WIN32
// Insert your headers here
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
#define WIN32_EXTRA_LEAN
#include "winsani_in.h"
#include <windows.h>
#include "winsani_out.h"
#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
#define snprintf _snprintf
#define vsnprintf _vsnprintf
#else // _WIN32
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h> // exit()
#include <string.h> // strncpy()
#include <ctype.h> // tolower()
#include <limits.h>
#include <sys/time.h>
#include <errno.h>
#include <sys/ioctl.h>
typedef unsigned char BYTE;
typedef short int WORD;
typedef unsigned int DWORD;
typedef int32 LONG;
//typedef uint32 ULONG;
#ifndef ARCHTYPES_H
typedef uint32 ULONG;
#endif
typedef void *HANDLE;
#ifndef HMODULE
typedef void *HMODULE;
#endif
typedef char * LPSTR;
#define __cdecl
//const int MAX_PATH = PATH_MAX;
#define MAX_PATH PATH_MAX
#ifdef LINUX
typedef struct POINT_s
{
int x;
int y;
} POINT;
typedef void *HINSTANCE;
typedef void *HWND;
typedef void *HDC;
typedef void *HGLRC;
typedef struct RECT_s
{
int left;
int right;
int top;
int bottom;
} RECT;
#endif
#ifdef __cplusplus
//#undef FALSE
//#undef TRUE
#ifdef OSX
//#else
//const bool FALSE = false;
//const bool TRUE = true;
#endif
#endif
#ifndef NULL
#ifdef __cplusplus
#define NULL 0
#else
#define NULL ((void *)0)
#endif
#endif
#ifdef __cplusplus
inline int ioctlsocket( int d, int cmd, uint32 *argp ) { return ioctl( d, cmd, argp ); }
inline int closesocket( int fd ) { return close( fd ); }
inline char * GetCurrentDirectory( size_t size, char * buf ) { return getcwd( buf, size ); }
inline int WSAGetLastError() { return errno; }
inline void DebugBreak( void ) { exit( 1 ); }
#endif
extern char g_szEXEName[ 4096 ];
#define _snprintf snprintf
#if defined(OSX)
#define SO_ARCH_SUFFIX ".dylib"
#else
#if defined ( __x86_64__ )
#define SO_ARCH_SUFFIX "_amd64.so"
#else
#define SO_ARCH_SUFFIX ".so"
#endif
#endif
#endif
#endif // PORT_H

View file

@ -21,6 +21,7 @@
// Font stuff
#define NUM_GLYPHS 256
// does not exist: // #include "basetypes.h"
typedef struct
{
@ -34,7 +35,7 @@ typedef struct qfont_s
int rowcount;
int rowheight;
charinfo fontinfo[ NUM_GLYPHS ];
byte data[4];
unsigned char data[4];
} qfont_t;
#endif // qfont.h

View file

@ -85,7 +85,6 @@ color24 gTracerColors[] =
#define FTENT_NOMODEL 0x00040000 // Doesn't have a model, never try to draw ( it just triggers other things )
#define FTENT_CLIENTCUSTOM 0x00080000 // Must specify callback. Callback function is responsible for killing tempent and updating fields ( unless other flags specify how to do things )
typedef struct tempent_s TEMPENTITY;
typedef struct tempent_s
{
int flags;
@ -99,7 +98,7 @@ typedef struct tempent_s
int hitSound;
void ( *hitcallback ) ( struct tempent_s *ent, struct pmtrace_s *ptr );
void ( *callback ) ( struct tempent_s *ent, float frametime, float currenttime );
TEMPENTITY *next;
struct tempent_s *next;
int priority;
short clientIndex; // if attached, this is the index of the client to stick to
// if COLLIDEALL, this is the index of the client to ignore
@ -190,6 +189,7 @@ struct efx_api_s
void ( *R_GetPackedColor ) ( short *packed, short color );
short ( *R_LookupColor ) ( unsigned char r, unsigned char g, unsigned char b );
void ( *R_DecalRemoveAll ) ( int textureIndex ); //textureIndex points to the decal index in the array, not the actual texture index.
void ( *R_FireCustomDecal ) ( int textureIndex, int entity, int modelIndex, float * position, int flags, float scale );
};
extern efx_api_t efx;

View file

@ -1,10 +1,3 @@
//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================
#if !defined( R_STUDIOINT_H )
#define R_STUDIOINT_H
#if defined( _WIN32 )
@ -101,6 +94,10 @@ typedef struct engine_studio_api_s
// Only called by hardware interface
void ( *GL_StudioDrawShadow ) ( void );
void ( *GL_SetRenderMode ) ( int mode );
void ( *StudioSetRenderamt ) (int iRenderamt); //!!!CZERO added for rendering glass on viewmodels
void ( *StudioSetCullState ) ( int iCull );
void ( *StudioRenderShadow ) ( int iSprite, float *p1, float *p2, float *p3, float *p4 );
} engine_studio_api_t;
typedef struct server_studio_api_s
@ -131,17 +128,17 @@ extern r_studio_interface_t *pStudioAPI;
typedef struct sv_blending_interface_s
{
int version;
int version;
void ( *SV_StudioSetupBones )( struct model_s *pModel,
float frame,
int sequence,
const vec3_t angles,
const vec3_t origin,
const byte *pcontroller,
const byte *pblending,
int iBone,
const edict_t *pEdict );
void ( *SV_StudioSetupBones ) ( struct model_s *pModel,
float frame,
int sequence,
const vec3_t angles,
const vec3_t origin,
const byte *pcontroller,
const byte *pblending,
int iBone,
const edict_t *pEdict );
} sv_blending_interface_t;
#endif // R_STUDIOINT_H
#endif // R_STUDIOINT_H

View file

@ -51,8 +51,13 @@ typedef struct triangleapi_s
void ( *CullFace ) ( TRICULLSTYLE style );
int ( *SpriteTexture ) ( struct model_s *pSpriteModel, int frame );
int ( *WorldToScreen ) ( float *world, float *screen ); // Returns 1 if it's z clipped
void ( *Fog ) ( float flFogColor[3], float flStart, float flEnd, int bOn ); //Works just like GL_FOG, flFogColor is r/g/b.
void ( *Fog ) ( float flFogColor[3], float flStart, float flEnd, int bOn ); // Works just like GL_FOG, flFogColor is r/g/b.
void ( *ScreenToWorld ) ( float *screen, float *world );
void ( *GetMatrix ) ( const int pname, float *matrix );
int ( *BoxInPVS ) ( float *mins, float *maxs );
void ( *LightAtPoint ) ( float *pos, float *value );
void ( *Color4fRendermode ) ( float r, float g, float b, float a, int rendermode );
void ( *FogParams ) ( float flDensity, int iFogSkybox ); // Used with Fog()...sets fog density and whether the fog should be applied to the skybox
} triangleapi_t;

7
common/winsani_in.h Normal file
View file

@ -0,0 +1,7 @@
#if _MSC_VER >= 1500 // MSVC++ 9.0 (Visual Studio 2008)
#pragma push_macro("ARRAYSIZE")
#ifdef ARRAYSIZE
#undef ARRAYSIZE
#endif
#define HSPRITE WINDOWS_HSPRITE
#endif

4
common/winsani_out.h Normal file
View file

@ -0,0 +1,4 @@
#if _MSC_VER >= 1500 // MSVC++ 9.0 (Visual Studio 2008)
#undef HSPRITE
#pragma pop_macro("ARRAYSIZE")
#endif

View file

@ -1,6 +1,6 @@
/***
*
* Copyright (c) 1996-2002, Valve LLC. All rights reserved.
* Copyright (c) 1996-2001, Valve LLC. All rights reserved.
*
* This product contains software technology licensed from Id
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.

View file

@ -1,6 +1,6 @@
/***
*
* Copyright (c) 1996-2002, Valve LLC. All rights reserved.
* Copyright (c) 1996-2001, Valve LLC. All rights reserved.
*
* This product contains software technology licensed from Id
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.

View file

@ -1,6 +1,6 @@
/***
*
* Copyright (c) 1996-2002, Valve LLC. All rights reserved.
* Copyright (c) 1996-2001, Valve LLC. All rights reserved.
*
* This product contains software technology licensed from Id
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
@ -14,6 +14,8 @@
****/
//=========================================================
//=========================================================
#include "archtypes.h" // DAL
#include "extdll.h"
#include "util.h"
#include "cbase.h"
@ -211,7 +213,7 @@ void CFlockingFlyerFlock :: SpawnFlock( void )
pBoid->pev->frame = 0;
pBoid->pev->nextthink = gpGlobals->time + 0.2;
pBoid->SetThink( CFlockingFlyer :: IdleThink );
pBoid->SetThink( &CFlockingFlyer :: IdleThink );
if ( pBoid != pLeader )
{
@ -229,7 +231,7 @@ void CFlockingFlyer :: Spawn( )
pev->frame = 0;
pev->nextthink = gpGlobals->time + 0.1;
SetThink( IdleThink );
SetThink( &CFlockingFlyer::IdleThink );
}
//=========================================================
@ -292,7 +294,7 @@ void CFlockingFlyer :: Killed( entvars_t *pevAttacker, int iGib )
UTIL_SetSize( pev, Vector(0,0,0), Vector(0,0,0) );
pev->movetype = MOVETYPE_TOSS;
SetThink ( FallHack );
SetThink ( &CFlockingFlyer::FallHack );
pev->nextthink = gpGlobals->time + 0.1;
}
@ -366,7 +368,7 @@ void CFlockingFlyer :: IdleThink( void )
// see if there's a client in the same pvs as the monster
if ( !FNullEnt( FIND_CLIENT_IN_PVS( edict() ) ) )
{
SetThink( Start );
SetThink( &CFlockingFlyer::Start );
pev->nextthink = gpGlobals->time + 0.1;
}
}
@ -380,11 +382,11 @@ void CFlockingFlyer :: Start( void )
if ( IsLeader() )
{
SetThink( FlockLeaderThink );
SetThink( &CFlockingFlyer::FlockLeaderThink );
}
else
{
SetThink( FlockFollowerThink );
SetThink( &CFlockingFlyer::FlockFollowerThink );
}
/*
@ -438,7 +440,7 @@ void CFlockingFlyer :: FormFlock( void )
}
}
SetThink( IdleThink );// now that flock is formed, go to idle and wait for a player to come along.
SetThink( &CFlockingFlyer::IdleThink );// now that flock is formed, go to idle and wait for a player to come along.
pev->nextthink = gpGlobals->time;
}
@ -673,7 +675,7 @@ void CFlockingFlyer :: FlockFollowerThink( void )
if ( IsLeader() || !InSquad() )
{
// the leader has been killed and this flyer suddenly finds himself the leader.
SetThink ( FlockLeaderThink );
SetThink ( &CFlockingFlyer::FlockLeaderThink );
return;
}

View file

@ -1,6 +1,6 @@
/***
*
* Copyright (c) 1996-2002, Valve LLC. All rights reserved.
* Copyright (c) 1996-2001, Valve LLC. All rights reserved.
*
* This product contains software technology licensed from Id
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.

View file

@ -1,6 +1,6 @@
/***
*
* Copyright (c) 1996-2002, Valve LLC. All rights reserved.
* Copyright (c) 1996-2001, Valve LLC. All rights reserved.
*
* This product contains software technology licensed from Id
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
@ -58,8 +58,8 @@ void CAirtank :: Spawn( void )
UTIL_SetSize(pev, Vector( -16, -16, 0), Vector(16, 16, 36));
UTIL_SetOrigin( pev, pev->origin );
SetTouch( TankTouch );
SetThink( TankThink );
SetTouch( &CAirtank::TankTouch );
SetThink( &CAirtank::TankThink );
pev->flags |= FL_MONSTER;
pev->takedamage = DAMAGE_YES;

View file

@ -1,6 +1,6 @@
/***
*
* Copyright (c) 1996-2002, Valve LLC. All rights reserved.
* Copyright (c) 1996-2001, Valve LLC. All rights reserved.
*
* This product contains software technology licensed from Id
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.

View file

@ -1,6 +1,6 @@
/***
*
* Copyright (c) 1996-2002, Valve LLC. All rights reserved.
* Copyright (c) 1996-2001, Valve LLC. All rights reserved.
*
* This product contains software technology licensed from Id
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
@ -321,6 +321,7 @@ int GetAnimationEvent( void *pmodel, entvars_t *pev, MonsterEvent_t *pMonsterEve
float SetController( void *pmodel, entvars_t *pev, int iController, float flValue )
{
studiohdr_t *pstudiohdr;
int i;
pstudiohdr = (studiohdr_t *)pmodel;
if (! pstudiohdr)
@ -329,7 +330,7 @@ float SetController( void *pmodel, entvars_t *pev, int iController, float flValu
mstudiobonecontroller_t *pbonecontroller = (mstudiobonecontroller_t *)((byte *)pstudiohdr + pstudiohdr->bonecontrollerindex);
// find first controller that matches the index
for (int i = 0; i < pstudiohdr->numbonecontrollers; i++, pbonecontroller++)
for ( i = 0; i < pstudiohdr->numbonecontrollers; i++, pbonecontroller++)
{
if (pbonecontroller->index == iController)
break;
@ -524,4 +525,4 @@ int GetBodygroup( void *pmodel, entvars_t *pev, int iGroup )
int iCurrent = (pev->body / pbodypart->base) % pbodypart->nummodels;
return iCurrent;
}
}

View file

@ -1,6 +1,6 @@
/***
*
* Copyright (c) 1996-2002, Valve LLC. All rights reserved.
* Copyright (c) 1996-2001, Valve LLC. All rights reserved.
*
* This product contains software technology licensed from Id
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.

View file

@ -1,6 +1,6 @@
/***
*
* Copyright (c) 1996-2002, Valve LLC. All rights reserved.
* Copyright (c) 1996-2001, Valve LLC. All rights reserved.
*
* This product contains software technology licensed from Id
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
@ -139,12 +139,12 @@ void CApache :: Spawn( void )
if (pev->spawnflags & SF_WAITFORTRIGGER)
{
SetUse( StartupUse );
SetUse( &CApache::StartupUse );
}
else
{
SetThink( HuntThink );
SetTouch( FlyTouch );
SetThink( &CApache::HuntThink );
SetTouch( &CApache::FlyTouch );
pev->nextthink = gpGlobals->time + 1.0;
}
@ -186,8 +186,8 @@ void CApache::NullThink( void )
void CApache::StartupUse( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value )
{
SetThink( HuntThink );
SetTouch( FlyTouch );
SetThink( &CApache::HuntThink );
SetTouch( &CApache::FlyTouch );
pev->nextthink = gpGlobals->time + 0.1;
SetUse( NULL );
}
@ -200,8 +200,8 @@ void CApache :: Killed( entvars_t *pevAttacker, int iGib )
STOP_SOUND( ENT(pev), CHAN_STATIC, "apache/ap_rotor2.wav" );
UTIL_SetSize( pev, Vector( -32, -32, -64), Vector( 32, 32, 0) );
SetThink( DyingThink );
SetTouch( CrashTouch );
SetThink( &CApache::DyingThink );
SetTouch( &CApache::CrashTouch );
pev->nextthink = gpGlobals->time + 0.1;
pev->health = 0;
pev->takedamage = DAMAGE_NO;
@ -402,7 +402,7 @@ void CApache :: DyingThink( void )
WRITE_BYTE( BREAK_METAL );
MESSAGE_END();
SetThink( SUB_Remove );
SetThink( &CApache::SUB_Remove );
pev->nextthink = gpGlobals->time + 0.1;
}
}
@ -972,8 +972,8 @@ void CApacheHVR :: Spawn( void )
UTIL_SetSize(pev, Vector( 0, 0, 0), Vector(0, 0, 0));
UTIL_SetOrigin( pev, pev->origin );
SetThink( IgniteThink );
SetTouch( ExplodeTouch );
SetThink( &CApacheHVR::IgniteThink );
SetTouch( &CApacheHVR::ExplodeTouch );
UTIL_MakeAimVectors( pev->angles );
m_vecForward = gpGlobals->v_forward;
@ -1019,7 +1019,7 @@ void CApacheHVR :: IgniteThink( void )
MESSAGE_END(); // move PHS/PVS data sending into here (SEND_ALL, SEND_PVS, SEND_PHS)
// set to accelerate
SetThink( AccelerateThink );
SetThink( &CApacheHVR::AccelerateThink );
pev->nextthink = gpGlobals->time + 0.1;
}
@ -1047,4 +1047,4 @@ void CApacheHVR :: AccelerateThink( void )
}
#endif
#endif

View file

@ -1,6 +1,6 @@
/***
*
* Copyright (c) 1996-2002, Valve LLC. All rights reserved.
* Copyright (c) 1996-2001, Valve LLC. All rights reserved.
*
* This product contains software technology licensed from Id
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
@ -124,7 +124,7 @@ void CBarnacle :: Spawn()
SetActivity ( ACT_IDLE );
SetThink ( BarnacleThink );
SetThink ( &CBarnacle::BarnacleThink );
pev->nextthink = gpGlobals->time + 0.5;
UTIL_SetOrigin ( pev, pev->origin );
@ -349,7 +349,7 @@ void CBarnacle :: Killed( entvars_t *pevAttacker, int iGib )
StudioFrameAdvance( 0.1 );
pev->nextthink = gpGlobals->time + 0.1;
SetThink ( WaitTillDead );
SetThink ( &CBarnacle::WaitTillDead );
}
//=========================================================

View file

@ -1,6 +1,6 @@
/***
*
* Copyright (c) 1996-2002, Valve LLC. All rights reserved.
* Copyright (c) 1996-2001, Valve LLC. All rights reserved.
*
* This product contains software technology licensed from Id
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
@ -424,7 +424,7 @@ void CBarney :: Spawn()
m_afCapability = bits_CAP_HEAR | bits_CAP_TURN_HEAD | bits_CAP_DOORS_GROUP;
MonsterInit();
SetUse( FollowerUse );
SetUse( &CBarney::FollowerUse );
}
//=========================================================

View file

@ -1,6 +1,6 @@
/***
*
* Copyright (c) 1996-2002, Valve LLC. All rights reserved.
* Copyright (c) 1996-2001, Valve LLC. All rights reserved.
*
* This product contains software technology licensed from Id
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.

View file

@ -1,6 +1,6 @@
/***
*
* Copyright (c) 1996-2002, Valve LLC. All rights reserved.
* Copyright (c) 1996-2001, Valve LLC. All rights reserved.
*
* This product contains software technology licensed from Id
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
@ -1198,7 +1198,7 @@ CBMortar *CBMortar::Shoot( edict_t *pOwner, Vector vecStart, Vector vecVelocity
pSpit->pev->velocity = vecVelocity;
pSpit->pev->owner = pOwner;
pSpit->pev->scale = 2.5;
pSpit->SetThink ( Animate );
pSpit->SetThink ( &CBMortar::Animate );
pSpit->pev->nextthink = gpGlobals->time + 0.1;
return pSpit;

Some files were not shown because too many files have changed in this diff Show more