1
0
Fork 0
forked from valve/halflife-sdk

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 "StudioModelRenderer.h"
#include "GameStudioModelRenderer.h" #include "GameStudioModelRenderer.h"
#include "Exports.h"
// //
// Override the StudioModelRender virtual member functions here to implement custom bone // 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. Export this function for the engine to use the studio renderer class to render objects.
==================== ====================
*/ */
#define DLLEXPORT __declspec( dllexport ) int CL_DLLEXPORT HUD_GetStudioModelInterface( int version, struct r_studio_interface_s **ppinterface, struct engine_studio_api_s *pstudio )
extern "C" int 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 ) if ( version != STUDIO_INTERFACE_VERSION )
return 0; 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 // studio_model.cpp
// routines for setting up to draw 3DStudio models // routines for setting up to draw 3DStudio models
@ -29,6 +22,18 @@
#include "StudioModelRenderer.h" #include "StudioModelRenderer.h"
#include "GameStudioModelRenderer.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 // Global engine <-> studio model rendering code interface
engine_studio_api_t IEngineStudio; engine_studio_api_t IEngineStudio;
@ -363,7 +368,7 @@ mstudioanim_t *CStudioModelRenderer::StudioGetAnim( model_t *m_pSubModel, mstudi
if (pseqdesc->seqgroup == 0) 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; 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; 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 ); f = StudioEstimateFrame( pseqdesc );
if (m_pCurrentEntity->latched.prevframe > f) if (m_pCurrentEntity->latched.prevframe > f)
@ -842,6 +863,11 @@ void CStudioModelRenderer::StudioSetupBones ( void )
static vec4_t q1b[MAXSTUDIOBONES]; static vec4_t q1b[MAXSTUDIOBONES];
float s; 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; pseqdesc = (mstudioseqdesc_t *)((byte *)m_pStudioHeader + m_pStudioHeader->seqindex) + m_pCurrentEntity->latched.prevsequence;
panim = StudioGetAnim( m_pRenderModel, pseqdesc ); panim = StudioGetAnim( m_pRenderModel, pseqdesc );
// clip prevframe // clip prevframe
@ -882,29 +908,49 @@ void CStudioModelRenderer::StudioSetupBones ( void )
pbones = (mstudiobone_t *)((byte *)m_pStudioHeader + m_pStudioHeader->boneindex); pbones = (mstudiobone_t *)((byte *)m_pStudioHeader + m_pStudioHeader->boneindex);
// calc gait animation // bounds checking
if (m_pPlayerInfo && m_pPlayerInfo->gaitsequence != 0) 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; 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 ); panim = StudioGetAnim( m_pRenderModel, pseqdesc );
StudioCalcRotations( pos2, q2, pseqdesc, panim, m_pPlayerInfo->gaitframe ); 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) if ( !strcmp( pbones[i].name, "Bip01 Spine" ) )
break; {
memcpy( pos[i], pos2[i], sizeof( pos[i] )); copy = 0;
memcpy( q[i], q2[i], sizeof( q[i] )); }
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++) for (i = 0; i < m_pStudioHeader->numbones; i++)
{ {
QuaternionMatrix( q[i], bonematrix ); 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 StudioDrawModel
@ -1154,9 +1246,86 @@ int CStudioModelRenderer::StudioDrawModel( int flags )
IEngineStudio.StudioSetupLighting (&lighting); IEngineStudio.StudioSetupLighting (&lighting);
// get remap colors // 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; 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 ); IEngineStudio.StudioSetRemapColors( m_nTopColor, m_nBottomColor );
StudioRenderModel( ); StudioRenderModel( );
@ -1312,7 +1481,7 @@ void CStudioModelRenderer::StudioProcessGait( entity_state_t *pplayer )
m_pCurrentEntity->angles[YAW] += 360; m_pCurrentEntity->angles[YAW] += 360;
m_pCurrentEntity->latched.prevangles[YAW] = m_pCurrentEntity->angles[YAW]; m_pCurrentEntity->latched.prevangles[YAW] = m_pCurrentEntity->angles[YAW];
if (pplayer->gaitsequence >= m_pStudioHeader->numseq) if (pplayer->gaitsequence >= m_pStudioHeader->numseq)
{ {
pplayer->gaitsequence = 0; pplayer->gaitsequence = 0;
} }
@ -1335,6 +1504,149 @@ void CStudioModelRenderer::StudioProcessGait( entity_state_t *pplayer )
m_pPlayerInfo->gaitframe += pseqdesc->numframes; 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 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.GetViewInfo( m_vRenderOrigin, m_vUp, m_vRight, m_vNormal );
IEngineStudio.GetAliasScale( &m_fSoftwareXScale, &m_fSoftwareYScale ); 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; m_nPlayerIndex = pplayer->number - 1;
if (m_nPlayerIndex < 0 || m_nPlayerIndex >= gEngfuncs.GetMaxClients()) if (m_nPlayerIndex < 0 || m_nPlayerIndex >= gEngfuncs.GetMaxClients())
return 0; 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 ); m_pRenderModel = IEngineStudio.SetupPlayerModel( m_nPlayerIndex );
#endif
if (m_pRenderModel == NULL) if (m_pRenderModel == NULL)
return 0; return 0;
@ -1458,9 +1788,48 @@ int CStudioModelRenderer::StudioDrawPlayer( int flags, entity_state_t *pplayer )
m_pPlayerInfo = IEngineStudio.PlayerInfo( m_nPlayerIndex ); m_pPlayerInfo = IEngineStudio.PlayerInfo( m_nPlayerIndex );
// get remap colors #if defined _TFC
m_nTopColor = m_pPlayerInfo->topcolor;
m_nTopColor = m_pPlayerInfo->topcolor;
m_nBottomColor = m_pPlayerInfo->bottomcolor; 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) if (m_nTopColor < 0)
m_nTopColor = 0; m_nTopColor = 0;
if (m_nTopColor > 360) if (m_nTopColor > 360)
@ -1481,10 +1850,77 @@ int CStudioModelRenderer::StudioDrawPlayer( int flags, entity_state_t *pplayer )
model_t *pweaponmodel = IEngineStudio.GetModelByIndex( pplayer->weaponmodel ); 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); m_pStudioHeader = (studiohdr_t *)IEngineStudio.Mod_Extradata (pweaponmodel);
IEngineStudio.StudioSetHeader( m_pStudioHeader ); 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); IEngineStudio.StudioSetupLighting (&lighting);
@ -1675,3 +2111,4 @@ void CStudioModelRenderer::StudioRenderFinal(void)
} }
} }

View file

@ -308,9 +308,6 @@ void CHudAmmo::Reset(void)
gWR.Reset(); gWR.Reset();
gHR.Reset(); gHR.Reset();
// VidInit();
} }
int CHudAmmo::VidInit(void) int CHudAmmo::VidInit(void)
@ -674,7 +671,6 @@ int CHudAmmo::MsgFunc_WeaponList(const char *pszName, int iSize, void *pbuf )
// Slot button pressed // Slot button pressed
void CHudAmmo::SlotInput( int iSlot ) void CHudAmmo::SlotInput( int iSlot )
{ {
// Let the Viewport use it first, for menus
if ( gViewPort && gViewPort->SlotInput( iSlot ) ) if ( gViewPort && gViewPort->SlotInput( iSlot ) )
return; return;
@ -740,7 +736,7 @@ void CHudAmmo::UserCmd_Close(void)
PlaySound("common/wpn_hudoff.wav", 1); PlaySound("common/wpn_hudoff.wav", 1);
} }
else 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 ) int CHudBattery:: MsgFunc_Battery(const char *pszName, int iSize, void *pbuf )
{ {
m_iFlags |= HUD_ACTIVE; m_iFlags |= HUD_ACTIVE;
BEGIN_READ( pbuf, iSize ); BEGIN_READ( pbuf, iSize );
int x = READ_SHORT(); 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_fFade = FADE_TIME;
m_iBat = x; m_iBat = x;
} }
#endif
return 1; return 1;
} }
@ -81,7 +91,17 @@ int CHudBattery::Draw(float flTime)
wrect_t rc; wrect_t rc;
rc = *m_prc2; 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 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); 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 * This product contains software technology licensed from Id
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc. * Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
@ -21,7 +21,9 @@
#include "hud.h" #include "hud.h"
#include "cl_util.h" #include "cl_util.h"
#include "netadr.h" #include "netadr.h"
#include "vgui_schememanager.h" #undef INTERFACE_H
#include "../public/interface.h"
//#include "vgui_schememanager.h"
extern "C" extern "C"
{ {
@ -33,42 +35,33 @@ extern "C"
#include "vgui_int.h" #include "vgui_int.h"
#include "interface.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; cl_enginefunc_t gEngfuncs;
CHud gHUD; CHud gHUD;
TeamFortressViewport *gViewPort = NULL; 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 InitInput (void);
void EV_HookEvents( void ); void EV_HookEvents( void );
void IN_Commands( 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 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. 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; int iret = 0;
switch ( hullnumber ) 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. 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 // Parse stuff from args
int max_buffer_size = *response_buffer_size; 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; return 0;
} }
void DLLEXPORT HUD_PlayerMoveInit( struct playermove_s *ppmove ) void CL_DLLEXPORT HUD_PlayerMoveInit( struct playermove_s *ppmove )
{ {
// RecClClientMoveInit(ppmove);
PM_Init( ppmove ); PM_Init( ppmove );
} }
char DLLEXPORT HUD_PlayerMoveTexture( char *name ) char CL_DLLEXPORT HUD_PlayerMoveTexture( char *name )
{ {
// RecClClientTextureType(name);
return PM_FindTextureType( 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 ); 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; gEngfuncs = *pEnginefuncs;
// RecClInitialize(pEnginefuncs, iVersion);
if (iVersion != CLDLL_INTERFACE_VERSION) if (iVersion != CLDLL_INTERFACE_VERSION)
return 0; return 0;
memcpy(&gEngfuncs, pEnginefuncs, sizeof(cl_enginefunc_t)); memcpy(&gEngfuncs, pEnginefuncs, sizeof(cl_enginefunc_t));
EV_HookEvents(); EV_HookEvents();
CL_LoadParticleMan();
// get tracker interface, if any
return 1; 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(); gHUD.VidInit();
VGui_Startup(); VGui_Startup();
@ -183,8 +191,9 @@ the hud variables.
========================== ==========================
*/ */
void DLLEXPORT HUD_Init( void ) void CL_DLLEXPORT HUD_Init( void )
{ {
// RecClHudInit();
InitInput(); InitInput();
gHUD.Init(); gHUD.Init();
Scheme_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 ); gHUD.Redraw( time, intermission );
return 1; 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(); IN_Commands();
return gHUD.UpdateClientData(pcldata, flTime ); 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(); 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 ); ServersThink( time );
GetClientVoiceMgr()->Frame(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); GetClientVoiceMgr()->UpdateSpeakerStatus(entindex, bTalking);
} }
/* /*
========================== ==========================
HUD_DirectorEvent HUD_DirectorMessage
Called when a director event message was received 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 # Begin Project
# PROP AllowPerConfigDependencies 0 # PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=cl.exe CPP=cl.exe
MTL=midl.exe MTL=midl.exe
RSC=rc.exe RSC=rc.exe
@ -43,7 +41,7 @@ RSC=rc.exe
# PROP Ignore_Export_Lib 0 # PROP Ignore_Export_Lib 0
# PROP Target_Dir "" # PROP Target_Dir ""
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /c # 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 BASE MTL /nologo /D "NDEBUG" /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x409 /d "NDEBUG" # ADD BASE RSC /l 0x409 /d "NDEBUG"
@ -53,7 +51,26 @@ BSC32=bscmake.exe
# ADD BSC32 /nologo # ADD BSC32 /nologo
LINK32=link.exe 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 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" !ELSEIF "$(CFG)" == "cl_dll - Win32 Debug"
@ -69,7 +86,7 @@ LINK32=link.exe
# PROP Ignore_Export_Lib 0 # PROP Ignore_Export_Lib 0
# PROP Target_Dir "" # PROP Target_Dir ""
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /c # 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 BASE MTL /nologo /D "_DEBUG" /win32
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x409 /d "_DEBUG" # ADD BASE RSC /l 0x409 /d "_DEBUG"
@ -79,7 +96,26 @@ BSC32=bscmake.exe
# ADD BSC32 /nologo # ADD BSC32 /nologo
LINK32=link.exe 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 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 !ENDIF
@ -92,7 +128,7 @@ LINK32=link.exe
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat;for;f90" # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat;for;f90"
# Begin Group "hl" # Begin Group "hl"
# PROP Default_Filter "*.CPP" # PROP Default_Filter "*.cpp"
# Begin Source File # Begin Source File
SOURCE=..\dlls\crossbow.cpp SOURCE=..\dlls\crossbow.cpp
@ -143,10 +179,6 @@ SOURCE=..\dlls\hornetgun.cpp
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\common\interface.cpp
# End Source File
# Begin Source File
SOURCE=..\dlls\mp5.cpp SOURCE=..\dlls\mp5.cpp
# End Source File # End Source File
# Begin Source File # Begin Source File
@ -173,22 +205,6 @@ SOURCE=..\dlls\squeakgrenade.cpp
SOURCE=..\dlls\tripmine.cpp SOURCE=..\dlls\tripmine.cpp
# End Source File # 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 # End Group
# Begin Source File # Begin Source File
@ -225,6 +241,15 @@ SOURCE=.\demo.cpp
# Begin Source File # Begin Source File
SOURCE=.\entity.cpp SOURCE=.\entity.cpp
!IF "$(CFG)" == "cl_dll - Win32 Release"
!ELSEIF "$(CFG)" == "cl_dll - Win32 Debug"
# ADD CPP /MT
!ENDIF
# End Source File # End Source File
# Begin Source File # Begin Source File
@ -256,6 +281,14 @@ SOURCE=.\hud.cpp
# End Source File # End Source File
# Begin 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 SOURCE=.\hud_msg.cpp
# End Source File # End Source File
# Begin Source File # Begin Source File
@ -288,6 +321,14 @@ SOURCE=.\inputw32.cpp
# End Source File # End Source File
# Begin 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 SOURCE=.\menu.cpp
# End Source File # End Source File
# Begin Source File # Begin Source File
@ -296,16 +337,7 @@ SOURCE=.\message.cpp
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\overview.cpp SOURCE=..\common\parsemsg.cpp
# PROP Exclude_From_Build 1
# End Source File
# Begin Source File
SOURCE=.\parsemsg.cpp
# End Source File
# Begin Source File
SOURCE=.\parsemsg.h
# End Source File # End Source File
# Begin Source File # Begin Source File
@ -365,10 +397,6 @@ SOURCE=.\vgui_ClassMenu.cpp
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\vgui_ConsolePanel.cpp
# End Source File
# Begin Source File
SOURCE=.\vgui_ControlConfigPanel.cpp SOURCE=.\vgui_ControlConfigPanel.cpp
# End Source File # End Source File
# Begin Source File # Begin Source File
@ -409,10 +437,18 @@ SOURCE=.\vgui_ScorePanel.cpp
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\game_shared\vgui_scrollbar2.cpp
# End Source File
# Begin Source File
SOURCE=.\vgui_ServerBrowser.cpp SOURCE=.\vgui_ServerBrowser.cpp
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\game_shared\vgui_slider2.cpp
# End Source File
# Begin Source File
SOURCE=.\vgui_SpectatorPanel.cpp SOURCE=.\vgui_SpectatorPanel.cpp
# End Source File # End Source File
# Begin Source File # Begin Source File
@ -421,12 +457,20 @@ SOURCE=.\vgui_TeamFortressViewport.cpp
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\vgui_teammenu.cpp SOURCE=.\vgui_TeamMenu.cpp
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\view.cpp SOURCE=.\view.cpp
# End Source File # 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 # End Group
# Begin Group "Header Files" # Begin Group "Header Files"
@ -449,6 +493,10 @@ SOURCE=.\cl_dll.h
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\cl_util.h
# End Source File
# Begin Source File
SOURCE=.\com_weapons.h SOURCE=.\com_weapons.h
# End Source File # End Source File
# Begin Source File # Begin Source File
@ -477,10 +525,6 @@ SOURCE=.\hud.h
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\hud_iface.h
# End Source File
# Begin Source File
SOURCE=.\hud_servers.h SOURCE=.\hud_servers.h
# End Source File # End Source File
# Begin Source File # Begin Source File
@ -497,7 +541,7 @@ SOURCE=.\in_defs.h
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\common\itrackeruser.h SOURCE=.\interpolation.h
# End Source File # End Source File
# Begin Source File # Begin Source File
@ -505,7 +549,7 @@ SOURCE=.\kbutton.h
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\overview.h SOURCE=..\common\parsemsg.h
# End Source File # End Source File
# Begin Source File # Begin Source File
@ -533,15 +577,11 @@ SOURCE=..\pm_shared\pm_shared.h
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\studio_util.h
# End Source File
# Begin Source File
SOURCE=.\StudioModelRenderer.h SOURCE=.\StudioModelRenderer.h
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\util.h SOURCE=.\tri.h
# End Source File # End Source File
# Begin Source File # Begin Source File
@ -549,10 +589,6 @@ SOURCE=.\util_vector.h
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\vgui_ConsolePanel.h
# End Source File
# Begin Source File
SOURCE=.\vgui_ControlConfigPanel.h SOURCE=.\vgui_ControlConfigPanel.h
# End Source File # End Source File
# Begin Source File # Begin Source File
@ -569,15 +605,19 @@ SOURCE=.\vgui_ScorePanel.h
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\game_shared\vgui_scrollbar2.h
# End Source File
# Begin Source File
SOURCE=.\vgui_ServerBrowser.h SOURCE=.\vgui_ServerBrowser.h
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\vgui_SpectatorPanel.h SOURCE=..\game_shared\vgui_slider2.h
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\vgui_TeamFortressViewport.h SOURCE=.\vgui_SpectatorPanel.h
# End Source File # End Source File
# Begin Source File # Begin Source File
@ -593,10 +633,6 @@ SOURCE=..\game_shared\voice_status.h
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\game_shared\voice_vgui_tweakdlg.h
# End Source File
# Begin Source File
SOURCE=.\wrect.h SOURCE=.\wrect.h
# End Source File # End Source File
# End Group # 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" # PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe"
# End Group # End Group
# Begin Source File
SOURCE=..\lib\public\game_controls.lib
# End Source File
# End Target # End Target
# End Project # End Project

View file

@ -31,7 +31,11 @@ typedef float vec_t;
typedef int (*pfnUserMsgHook)(const char *pszName, int iSize, void *pbuf); typedef int (*pfnUserMsgHook)(const char *pszName, int iSize, void *pbuf);
#include "util_vector.h" #include "util_vector.h"
#ifdef _WIN32
#define EXPORT _declspec( dllexport ) #define EXPORT _declspec( dllexport )
#else
#define EXPORT __attribute__ ((visibility("default")))
#endif
#include "../engine/cdll_int.h" #include "../engine/cdll_int.h"
#include "../dlls/cdll_dll.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 * This product contains software technology licensed from Id
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc. * Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
@ -23,19 +23,23 @@
#define FALSE 0 #define FALSE 0
#endif #endif
#include <stdio.h> // for safe_sprintf()
#include <stdarg.h> // "
#include <string.h> // for strncpy()
// Macros to hook function calls into the HUD object // Macros to hook function calls into the HUD object
#define HOOK_MESSAGE(x) gEngfuncs.pfnHookUserMsg(#x, __MsgFunc_##x ); #define HOOK_MESSAGE(x) gEngfuncs.pfnHookUserMsg(#x, __MsgFunc_##x );
#define DECLARE_MESSAGE(y, x) int __MsgFunc_##x(const char *pszName, int iSize, void *pbuf) \ #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 HOOK_COMMAND(x, y) gEngfuncs.pfnAddCommand( x, __CmdFunc_##y );
#define DECLARE_COMMAND(y, x) void __CmdFunc_##x( void ) \ #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 ); } 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 // ScreenWidth returns the width of the screen, in pixels
#define ScreenWidth (gHUD.m_scrinfo.iWidth) #define ScreenWidth (gHUD.m_scrinfo.iWidth)
// Use this to set any co-ords in 640x480 space #define BASE_XRES 640.f
#define XRES(x) ((int)(float(x) * ((float)ScreenWidth / 640.0f) + 0.5f))
#define YRES(y) ((int)(float(y) * ((float)ScreenHeight / 480.0f) + 0.5f))
// use this to project world coordinates to screen coordinates // use this to project world coordinates to screen coordinates
#define XPROJECT(x) ( (1.0f+(x))*ScreenWidth*0.5f ) #define XPROJECT(x) ( (1.0f+(x))*ScreenWidth*0.5f )
#define YPROJECT(y) ( (1.0f-(y))*ScreenHeight*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 GetScreenInfo (*gEngfuncs.pfnGetScreenInfo)
#define ServerCmd (*gEngfuncs.pfnServerCmd) #define ServerCmd (*gEngfuncs.pfnServerCmd)
#define ClientCmd (*gEngfuncs.pfnClientCmd) #define EngineClientCmd (*gEngfuncs.pfnClientCmd)
#define SetCrosshair (*gEngfuncs.pfnSetCrosshair) #define SetCrosshair (*gEngfuncs.pfnSetCrosshair)
#define AngleVectors (*gEngfuncs.pfnAngleVectors) #define AngleVectors (*gEngfuncs.pfnAngleVectors)
@ -119,8 +124,39 @@ inline void CenterPrint( const char *string )
gEngfuncs.pfnCenterPrint( 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 // sound functions
inline void PlaySound( char *szSound, float vol ) { gEngfuncs.pfnPlaySoundByName( szSound, vol ); } 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_PrecacheModel ( char* s ) { return 0; }
int stub_PrecacheSound ( char* s ) { return 0; } int stub_PrecacheSound ( char* s ) { return 0; }
unsigned short stub_PrecacheEvent ( int type, const 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 ) {} void stub_SetModel ( edict_t *e, const char *m ) {}

View file

@ -14,11 +14,7 @@
#endif #endif
#include "hud_iface.h" #include "hud_iface.h"
#include "Exports.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 );
}
void COM_Log( char *pszFile, char *fmt, ...); void COM_Log( char *pszFile, char *fmt, ...);
int CL_IsDead( void ); 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_PrecacheModel( char* s );
int stub_PrecacheSound( char* s ); int stub_PrecacheSound( char* s );
unsigned short stub_PrecacheEvent( int type, const 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 ); 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 * This product contains software technology licensed from Id
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc. * Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
@ -115,7 +115,7 @@ int CHudDeathNotice :: Draw( float flTime )
if ( gViewPort && gViewPort->AllowedToPrintText() ) if ( gViewPort && gViewPort->AllowedToPrintText() )
{ {
// Draw the death notice // 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; 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); 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 ); gViewPort->DeathMsg( killer, victim );
gHUD.m_Spectator.DeathMessage(victim); gHUD.m_Spectator.DeathMessage(victim);
int i;
for ( int i = 0; i < MAX_DEATHNOTICES; i++ ) for ( i = 0; i < MAX_DEATHNOTICES; i++ )
{ {
if ( rgDeathNoticeList[i].iId == 0 ) if ( rgDeathNoticeList[i].iId == 0 )
break; break;

View file

@ -17,8 +17,7 @@
#include "demo.h" #include "demo.h"
#include "demo_api.h" #include "demo_api.h"
#include <memory.h> #include <memory.h>
#include "Exports.h"
#define DLLEXPORT __declspec( dllexport )
int g_demosniper = 0; int g_demosniper = 0;
int g_demosniperdamage = 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. // 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 Demo_WriteBuffer
@ -60,8 +54,10 @@ Demo_ReadBuffer
Engine wants us to parse some data from the demo stream 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 type;
int i = 0; int i = 0;

View file

@ -1,10 +1,3 @@
//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================
// Client side entity management functions // Client side entity management functions
#include <memory.h> #include <memory.h>
@ -19,8 +12,11 @@
#include "pm_defs.h" #include "pm_defs.h"
#include "pmtrace.h" #include "pmtrace.h"
#include "pm_shared.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 ); void Game_AddObjects( void );
@ -28,29 +24,21 @@ extern vec3_t v_origin;
int g_iAlive = 1; 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 HUD_AddEntity
Return 0 to filter entity from visible list for rendering 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 ) switch ( type )
{ {
case ET_NORMAL: case ET_NORMAL:
Bench_CheckEntity( type, ent, modelname );
break;
case ET_PLAYER: case ET_PLAYER:
case ET_BEAM: case ET_BEAM:
case ET_TEMPENTITY: 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. 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 ); VectorCopy( client->origin, state->origin );
// Spectator // Spectator
@ -108,8 +98,10 @@ We have received entity_state_t for this player over the network. We need to co
playerstate structure 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 // Copy in network data
VectorCopy( src->origin, dst->origin ); VectorCopy( src->origin, dst->origin );
VectorCopy( src->angles, dst->angles ); 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->team = src->team;
dst->colormap = src->colormap; 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 // 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 cl_entity_t *player = gEngfuncs.GetLocalPlayer(); // Get the local player's index
if ( dst->number == player->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. 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->oldbuttons = pps->oldbuttons;
ps->flFallVelocity = pps->flFallVelocity; ps->flFallVelocity = pps->flFallVelocity;
ps->iStepLeft = pps->iStepLeft; 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->iuser1 = g_iUser1; // observer mode
pcd->iuser2 = g_iUser2; // first target pcd->iuser2 = g_iUser2; // first target
pcd->iuser3 = g_iUser3; // second target pcd->iuser3 = g_iUser3; // second target
} }
// Fire prevention // 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 ) ); 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 ) #if defined( BEAM_TEST )
// Note can't index beam[ 0 ] in Beam callback, so don't use that index // Note can't index beam[ 0 ] in Beam callback, so don't use that index
// Room for 1 beam ( 0 can't be used ) // 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 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. // RecClCreateEntities();
// 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();
*/
#if defined( BEAM_TEST ) #if defined( BEAM_TEST )
Beams(); Beams();
#endif #endif
Bench_AddObjects();
// Add in any game specific objects // Add in any game specific objects
Game_AddObjects(); Game_AddObjects();
GetClientVoiceMgr()->CreateEntities(); GetClientVoiceMgr()->CreateEntities();
} }
#if defined( _TFC )
extern int g_bACSpinning[33];
#endif
/* /*
========================= =========================
HUD_StudioEvent 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 ) 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 ) switch( event->event )
{ {
case 5001: 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; break;
case 5011: 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; break;
case 5021: 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; break;
case 5031: 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; break;
case 5002: case 5002:
gEngfuncs.pEfxAPI->R_SparkEffect( (float *)&entity->attachment[0], atoi( event->options), -100, 100 ); 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 Simulation and cleanup of temporary entities
================= =================
*/ */
void DLLEXPORT HUD_TempEntUpdate ( void CL_DLLEXPORT HUD_TempEntUpdate (
double frametime, // Simulation time double frametime, // Simulation time
double client_time, // Absolute time on client double client_time, // Absolute time on client
double cl_gravity, // True gravity on client double cl_gravity, // True gravity on client
@ -594,11 +391,20 @@ void DLLEXPORT HUD_TempEntUpdate (
int ( *Callback_AddVisibleEntity )( cl_entity_t *pEntity ), int ( *Callback_AddVisibleEntity )( cl_entity_t *pEntity ),
void ( *Callback_TempEntPlaySound )( TEMPENTITY *pTemp, float damp ) ) void ( *Callback_TempEntPlaySound )( TEMPENTITY *pTemp, float damp ) )
{ {
// RecClTempEntUpdate(frametime, client_time, cl_gravity, ppTempEntFree, ppTempEntActive, Callback_AddVisibleEntity, Callback_TempEntPlaySound);
static int gTempEntFrame = 0; static int gTempEntFrame = 0;
int i; int i;
TEMPENTITY *pTemp, *pnext, *pprev; TEMPENTITY *pTemp, *pnext, *pprev;
float freq, gravity, gravitySlow, life, fastFreq; float freq, gravity, gravitySlow, life, fastFreq;
Vector vAngles;
gEngfuncs.GetViewAngles( (float*)vAngles );
if ( g_pParticleMan )
g_pParticleMan->SetVariables( cl_gravity, vAngles );
// Nothing to simulate // Nothing to simulate
if ( !*ppTempEntActive ) if ( !*ppTempEntActive )
return; 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. 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 ) #if defined( BEAM_TEST )
// None by default, you would return a valic pointer if you create a client side // None by default, you would return a valic pointer if you create a client side
// beam and attach it to a client side entity. // beam and attach it to a client side entity.

View file

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

View file

@ -39,7 +39,10 @@ extern engine_studio_api_t IEngineStudio;
static int tracerCount[ 32 ]; 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 V_PunchAxis( int axis, float punch );
void VectorAngles( const float *forward, float *angles ); 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_15DEGREES Vector( 0.13053, 0.13053, 0.13053 )
#define VECTOR_CONE_20DEGREES Vector( 0.17365, 0.17365, 0.17365 ) #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 // 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. // 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 // returns volume of strike instrument (crowbar) to play

View file

@ -68,14 +68,10 @@ int CHudGeiger::Draw (float flTime)
int rg[3]; int rg[3];
int i; 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 // peicewise linear is better than continuous formula for this
if (m_iGeigerRange > 800) if (m_iGeigerRange > 600)
{
pct = 0; //Con_Printf ( "range > 800\n");
}
else if (m_iGeigerRange > 600)
{ {
pct = 2; pct = 2;
flvol = 0.4; //Con_Printf ( "range > 600\n"); 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 // implementation of CHudHealth class
// //
#include "STDIO.H" #include "stdio.h"
#include "STDLIB.H" #include "stdlib.h"
#include "MATH.H" #include "math.h"
#include "hud.h" #include "hud.h"
#include "cl_util.h" #include "cl_util.h"
@ -379,7 +379,8 @@ int CHudHealth::DrawDamage(float flTime)
ScaleColors(r, g, b, a); ScaleColors(r, g, b, a);
// Draw all the items // 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]) 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 CBasePlayerItem::Save( class CSave & ) { return 1; }
int CBasePlayerWeapon::Restore( class CRestore & ) { return 1; } int CBasePlayerWeapon::Restore( class CRestore & ) { return 1; }
int CBasePlayerWeapon::Save( class CSave & ) { return 1; } int CBasePlayerWeapon::Save( class CSave & ) { return 1; }
float CBasePlayerWeapon::GetNextAttackDelay( float flTime ) { return flTime; }
void CBasePlayerItem :: SetObjectCollisionBox( void ) { } void CBasePlayerItem :: SetObjectCollisionBox( void ) { }
void CBasePlayerItem :: FallInit( void ) { } void CBasePlayerItem :: FallInit( void ) { }
void CBasePlayerItem::FallThink ( 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 ); 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 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 ]; ( ( 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 // Or if we don't have a weapon model deployed
if ( ( player.pev->deadflag != ( DEAD_DISCARDBODY + 1 ) ) && if ( ( player.pev->deadflag != ( DEAD_DISCARDBODY + 1 ) ) &&
!CL_IsDead() && player.pev->viewmodel && !g_iUser1 ) !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 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; g_runfuncs = runfuncs;
#if defined( CLIENT_WEAPONS ) #if defined( CLIENT_WEAPONS )

View file

@ -29,9 +29,10 @@
#include "demo.h" #include "demo.h"
#include "demo_api.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 class CHLVoiceStatusHelper : public IVoiceStatusHelper
{ {
@ -258,13 +259,27 @@ int __MsgFunc_Spectator(const char *pszName, int iSize, void *pbuf)
return 0; 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) int __MsgFunc_AllowSpec(const char *pszName, int iSize, void *pbuf)
{ {
if (gViewPort) if (gViewPort)
return gViewPort->MsgFunc_AllowSpec( pszName, iSize, pbuf ); return gViewPort->MsgFunc_AllowSpec( pszName, iSize, pbuf );
return 0; return 0;
} }
// This is called every time the DLL is loaded // This is called every time the DLL is loaded
void CHud :: Init( void ) void CHud :: Init( void )
{ {
@ -297,6 +312,9 @@ void CHud :: Init( void )
HOOK_MESSAGE( Spectator ); HOOK_MESSAGE( Spectator );
HOOK_MESSAGE( AllowSpec ); HOOK_MESSAGE( AllowSpec );
HOOK_MESSAGE( SpecFade );
HOOK_MESSAGE( ResetFade );
// VGUI Menus // VGUI Menus
HOOK_MESSAGE( VGUIMenu ); HOOK_MESSAGE( VGUIMenu );
@ -423,7 +441,8 @@ void CHud :: VidInit( void )
// count the number of sprites of the appropriate res // count the number of sprites of the appropriate res
m_iSpriteCount = 0; m_iSpriteCount = 0;
client_sprite_t *p = m_pSpriteList; 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 ) if ( p->iRes == m_iRes )
m_iSpriteCount++; 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 * This product contains software technology licensed from Id
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc. * Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
@ -25,6 +25,10 @@
#define RGB_REDISH 0x00FF1010 //255,160,0 #define RGB_REDISH 0x00FF1010 //255,160,0
#define RGB_GREENISH 0x0000A000 //0,160,0 #define RGB_GREENISH 0x0000A000 //0,160,0
#ifndef _WIN32
#define _cdecl
#endif
#include "wrect.h" #include "wrect.h"
#include "cl_dll.h" #include "cl_dll.h"
#include "ammo.h" #include "ammo.h"
@ -40,12 +44,7 @@ typedef struct {
int x, y; int x, y;
} POSITION; } POSITION;
enum #include "global_consts.h"
{
MAX_PLAYERS = 64,
MAX_TEAMS = 64,
MAX_TEAM_NAME = 16,
};
typedef struct { typedef struct {
unsigned char r,g,b,a; 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" #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 { enum {
MAX_STATUSTEXT_LENGTH = 128, MAX_STATUSTEXT_LENGTH = 128,
MAX_STATUSBAR_VALUES = 8, 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 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]; 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 struct extra_player_info_t
{ {
short frags; short frags;
short deaths; short deaths;
short playerclass; short playerclass;
short health; // UNUSED currently, spectator UI would like this
bool dead; // UNUSED currently, spectator UI would like this
short teamnumber; short teamnumber;
char teamname[MAX_TEAM_NAME]; char teamname[MAX_TEAM_NAME];
}; };
@ -317,11 +259,7 @@ struct team_info_t
int teamnumber; int teamnumber;
}; };
extern hud_player_info_t g_PlayerInfoList[MAX_PLAYERS+1]; // player info from the engine #include "player_info.h"
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];
// //
//----------------------------------------------------- //-----------------------------------------------------
@ -398,6 +336,7 @@ private:
wrect_t *m_prc1; wrect_t *m_prc1;
wrect_t *m_prc2; wrect_t *m_prc2;
int m_iBat; int m_iBat;
int m_iBatMax;
float m_fFade; float m_fFade;
int m_iHeight; // width of the battery innards int m_iHeight; // width of the battery innards
}; };
@ -476,6 +415,7 @@ public:
int VidInit( void ); int VidInit( void );
int Draw(float flTime); int Draw(float flTime);
int MsgFunc_HudText(const char *pszName, int iSize, void *pbuf); 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); int MsgFunc_GameTitle(const char *pszName, int iSize, void *pbuf);
float FadeBlend( float fadein, float fadeout, float hold, float localTime ); 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 class CHud
@ -617,6 +610,7 @@ public:
CHudAmmoSecondary m_AmmoSecondary; CHudAmmoSecondary m_AmmoSecondary;
CHudTextMessage m_TextMessage; CHudTextMessage m_TextMessage;
CHudStatusIcons m_StatusIcons; CHudStatusIcons m_StatusIcons;
CHudBenchmark m_Benchmark;
void Init( void ); void Init( void );
void VidInit( void ); void VidInit( void );
@ -654,10 +648,7 @@ public:
}; };
class TeamFortressViewport;
extern CHud gHUD; extern CHud gHUD;
extern TeamFortressViewport *gViewPort;
extern int g_iPlayerClass; extern int g_iPlayerClass;
extern int g_iTeamNumber; 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 #define HUD_IFACEH
#pragma once #pragma once
#define EXPORT _declspec( dllexport )
#define _DLLEXPORT __declspec( dllexport )
typedef int (*pfnUserMsgHook)(const char *pszName, int iSize, void *pbuf); typedef int (*pfnUserMsgHook)(const char *pszName, int iSize, void *pbuf);
#include "wrect.h" #include "wrect.h"
#include "../engine/cdll_int.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 * This product contains software technology licensed from Id
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc. * Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
@ -21,10 +21,19 @@
#include "parsemsg.h" #include "parsemsg.h"
#include "r_efx.h" #include "r_efx.h"
#include "particleman.h"
extern IParticleMan *g_pParticleMan;
#define MAX_CLIENTS 32 #define MAX_CLIENTS 32
#if !defined( _TFC )
extern BEAM *pBeam; extern BEAM *pBeam;
extern BEAM *pBeam2; extern BEAM *pBeam2;
#endif
#if defined( _TFC )
void ClearEventList( void );
#endif
/// USER-DEFINED SERVER MESSAGE HANDLERS /// USER-DEFINED SERVER MESSAGE HANDLERS
@ -70,8 +79,20 @@ void CHud :: MsgFunc_InitHUD( const char *pszName, int iSize, void *pbuf )
pList = pList->pNext; 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. //Probably not a good place to put this.
pBeam = pBeam2 = NULL; 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 * This product contains software technology licensed from Id
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc. * Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
@ -18,6 +18,7 @@
#include <math.h> #include <math.h>
#include "hud.h" #include "hud.h"
#include "cl_util.h" #include "cl_util.h"
#include "bench.h"
#include "vgui_TeamFortressViewport.h" #include "vgui_TeamFortressViewport.h"
@ -40,6 +41,9 @@ extern cvar_t *sensitivity;
// Think // Think
void CHud::Think(void) void CHud::Think(void)
{ {
m_scrinfo.iSize = sizeof(m_scrinfo);
GetScreenInfo(&m_scrinfo);
int newfov; int newfov;
HUDLIST *pList = m_pHudList; 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 { // only let players adjust up in fov, and only if they are not overriden by something else
m_iFOV = max( default_fov->value, 90 ); m_iFOV = max( default_fov->value, 90 );
} }
if ( gEngfuncs.IsSpectateOnly() )
{
m_iFOV = gHUD.m_Spectator.GetFOV(); // default_fov->value;
}
Bench_CheckStart();
} }
// Redraw // Redraw
@ -89,7 +100,7 @@ int CHud :: Redraw( float flTime, int intermission )
m_fOldTime = m_flTime; // save time of previous redraw m_fOldTime = m_flTime; // save time of previous redraw
m_flTime = flTime; m_flTime = flTime;
m_flTimeDelta = (double)m_flTime - m_fOldTime; m_flTimeDelta = (double)m_flTime - m_fOldTime;
static m_flShotTime = 0; static float m_flShotTime = 0;
// Clock was reset, reset delta // Clock was reset, reset delta
if ( m_flTimeDelta < 0 ) if ( m_flTimeDelta < 0 )
@ -131,21 +142,34 @@ int CHud :: Redraw( float flTime, int intermission )
// if no redrawing is necessary // if no redrawing is necessary
// return 0; // return 0;
// draw all registered HUD elements
if ( m_pCvarDraw->value ) if ( m_pCvarDraw->value )
{ {
HUDLIST *pList = m_pHudList; HUDLIST *pList = m_pHudList;
while (pList) while (pList)
{ {
if ( !intermission ) if ( !Bench_Active() )
{ {
if ( (pList->p->m_iFlags & HUD_ACTIVE) && !(m_iHideHUDDisplay & HIDEHUD_ALL) ) if ( !intermission )
pList->p->Draw(flTime); {
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 else
{ // it's an intermission, so only draw hud elements that are set to draw during intermissions {
if ( pList->p->m_iFlags & HUD_INTERMISSION ) if ( ( pList->p == &m_Benchmark ) &&
pList->p->Draw( flTime ); ( pList->p->m_iFlags & HUD_ACTIVE ) &&
!( m_iHideHUDDisplay & HIDEHUD_ALL ) )
{
pList->p->Draw(flTime);
}
} }
pList = pList->pNext; 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 ) 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 return xpos + gEngfuncs.pfnDrawString( xpos, ypos, szIt, r, g, b);
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;
} }
int CHud :: DrawHudNumberString( int xpos, int ypos, int iMinX, int iNumber, int r, int g, int 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) // 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 ) int CHud :: DrawHudStringReverse( int xpos, int ypos, int iMinX, char *szString, int r, int g, int b )
{ {
// find the end of the string return xpos - gEngfuncs.pfnDrawStringReverse( xpos, ypos, szString, r, g, b);
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;
} }
int CHud :: DrawHudNumber( int x, int y, int iFlags, int iNumber, int r, int g, int 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 "hud_servers.h"
#include "net_api.h" #include "net_api.h"
#include <string.h> #include <string.h>
#ifdef _WIN32
#include "winsani_in.h"
#include <winsock.h> #include <winsock.h>
#include "winsani_out.h"
#else
#define __cdecl
#include <arpa/inet.h>
#endif
static int context_id; 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 VALVE_MASTER_ADDRESS "half-life.east.won.net"
#define PORT_MASTER 27010 #define PORT_MASTER 27010
#define PORT_SERVER 27015 #define PORT_SERVER 27015
// File where we really should look for master servers // 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 #define MAX_QUERIES 20
@ -599,7 +605,7 @@ int CompareField( CHudServers::server_t *p1, CHudServers::server_t *p2, const ch
return stricmp( sz1, sz2 ); 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 if (!p1 || !p2) // No meaningful comparison
return 0; return 0;
@ -1227,4 +1233,4 @@ void ServerPlayers( int server )
{ {
g_pServers->ServerPlayers( 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: // Purpose:
// //
@ -37,8 +37,6 @@ extern "C" float vJumpAngles[3];
extern void V_GetInEyePos(int entity, float * origin, float * angles ); extern void V_GetInEyePos(int entity, float * origin, float * angles );
extern void V_ResetChaseCam(); extern void V_ResetChaseCam();
extern void V_GetChasePos(int target, float * cl_angles, float * origin, float * angles); 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 float * GetClientColor( int clientIndex );
extern vec3_t v_origin; // last view origin 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_cl_angles; // last client/mouse angle
extern vec3_t v_sim_org; // last sim origin 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) void SpectatorMode(void)
{ {
@ -142,6 +171,7 @@ int CHudSpectator::Init()
m_flNextObserverInput = 0.0f; m_flNextObserverInput = 0.0f;
m_zoomDelta = 0.0f; m_zoomDelta = 0.0f;
m_moveDelta = 0.0f; m_moveDelta = 0.0f;
m_FOV = 90.0f;
m_chatEnabled = (gHUD.m_SayText.m_HUD_saytext->value!=0); m_chatEnabled = (gHUD.m_SayText.m_HUD_saytext->value!=0);
iJumpSpectator = 0; iJumpSpectator = 0;
@ -359,6 +389,182 @@ void CHudSpectator::SetSpectatorStartPosition()
iJumpSpectator = 1; // jump anyway 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 // Purpose: Loads new icons
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -373,9 +579,21 @@ int CHudSpectator::VidInit()
m_hsprCamera = SPR_Load("sprites/camera.spr"); m_hsprCamera = SPR_Load("sprites/camera.spr");
m_hCrosshair = SPR_Load("sprites/crosshairs.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; return 1;
} }
float CHudSpectator::GetFOV()
{
return m_FOV;
}
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Purpose: // Purpose:
// Input : flTime - // Input : flTime -
@ -462,8 +680,10 @@ int CHudSpectator::Draw(float flTime)
void CHudSpectator::DirectorMessage( int iSize, void *pbuf ) void CHudSpectator::DirectorMessage( int iSize, void *pbuf )
{ {
float value; float f1,f2;
char * string; char * string;
vec3_t v1,v2;
int i1,i2,i3;
BEGIN_READ( pbuf, iSize ); BEGIN_READ( pbuf, iSize );
@ -482,7 +702,7 @@ void CHudSpectator::DirectorMessage( int iSize, void *pbuf )
break; break;
case DRC_CMD_EVENT : case DRC_CMD_EVENT : // old director style message
m_lastPrimaryObject = READ_WORD(); m_lastPrimaryObject = READ_WORD();
m_lastSecondaryObject = READ_WORD(); m_lastSecondaryObject = READ_WORD();
m_iObserverFlags = READ_LONG(); m_iObserverFlags = READ_LONG();
@ -494,11 +714,12 @@ void CHudSpectator::DirectorMessage( int iSize, void *pbuf )
g_iUser2 = m_lastPrimaryObject; g_iUser2 = m_lastPrimaryObject;
g_iUser3 = m_lastSecondaryObject; g_iUser3 = m_lastSecondaryObject;
m_IsInterpolating = false;
m_ChaseEntity = 0;
} }
// gEngfuncs.Con_Printf("Director Camera: %i %i\n", firstObject, secondObject); // gEngfuncs.Con_Printf("Director Camera: %i %i\n", firstObject, secondObject);
break; break;
case DRC_CMD_MODE : case DRC_CMD_MODE :
if ( m_autoDirector->value ) if ( m_autoDirector->value )
{ {
@ -506,20 +727,23 @@ void CHudSpectator::DirectorMessage( int iSize, void *pbuf )
} }
break; break;
case DRC_CMD_CAMERA : 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 ) if ( m_autoDirector->value )
{ {
vJumpOrigin[0] = READ_COORD(); // position SetModes( OBS_ROAMING, -1 );
vJumpOrigin[1] = READ_COORD(); SetCameraView(v1, v2, f1);
vJumpOrigin[2] = READ_COORD(); m_ChaseEntity = i1;
vJumpAngles[0] = READ_COORD(); // view angle
vJumpAngles[1] = READ_COORD();
vJumpAngles[2] = READ_COORD();
gEngfuncs.SetViewAngles( vJumpAngles );
iJumpSpectator = 1;
} }
break; break;
@ -560,15 +784,15 @@ void CHudSpectator::DirectorMessage( int iSize, void *pbuf )
case DRC_CMD_SOUND : case DRC_CMD_SOUND :
string = READ_STRING(); string = READ_STRING();
value = READ_FLOAT(); f1 = READ_FLOAT();
// gEngfuncs.Con_Printf("DRC_CMD_FX_SOUND: %s %.2f\n", string, value ); // 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; break;
case DRC_CMD_TIMESCALE : case DRC_CMD_TIMESCALE :
value = READ_FLOAT(); f1 = READ_FLOAT(); // ignore this command (maybe show slowmo sign)
break; break;
@ -587,11 +811,69 @@ void CHudSpectator::DirectorMessage( int iSize, void *pbuf )
gViewPort->UpdateSpectatorPanel(); gViewPort->UpdateSpectatorPanel();
break; break;
case DRC_CMD_FADE: case DRC_CMD_STUFFTEXT:
EngineClientCmd( READ_STRING() );
break; break;
case DRC_CMD_STUFFTEXT: case DRC_CMD_CAMPATH:
ClientCmd( READ_STRING() ); 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; break;
default : gEngfuncs.Con_DPrintf("CHudSpectator::DirectorMessage: unknown command %i.\n", cmd ); 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->origin, vJumpOrigin );
VectorCopy ( pEnt->angles, vJumpAngles ); VectorCopy ( pEnt->angles, vJumpAngles );
} }
iJumpSpectator = 1; 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 ) void CHudSpectator::HandleButtonsDown( int ButtonPressed )
@ -678,6 +1020,7 @@ void CHudSpectator::HandleButtonsDown( int ButtonPressed )
int newInsetMode = m_pip->value; int newInsetMode = m_pip->value;
// gEngfuncs.Con_Printf(" HandleButtons:%i\n", ButtonPressed ); // gEngfuncs.Con_Printf(" HandleButtons:%i\n", ButtonPressed );
if ( !gViewPort ) if ( !gViewPort )
return; return;
@ -743,7 +1086,7 @@ void CHudSpectator::HandleButtonsDown( int ButtonPressed )
iJumpSpectator = 1; 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; m_autoDirector->value = 0.0f;
} }
} }
@ -800,17 +1143,24 @@ void CHudSpectator::SetModes(int iNewMainMode, int iNewInsetMode)
gEngfuncs.Con_Printf("Invalid spectator mode.\n"); gEngfuncs.Con_Printf("Invalid spectator mode.\n");
return; 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 ( iNewMainMode != g_iUser1 )
{ {
// if we are NOT in HLTV mode, main spectator mode is set on server // if we are NOT in HLTV mode, main spectator mode is set on server
if ( !gEngfuncs.IsSpectateOnly() ) if ( !gEngfuncs.IsSpectateOnly() )
{ {
char cmdstring[32];
// forward command to server
sprintf(cmdstring,"specmode %i",iNewMainMode );
gEngfuncs.pfnServerCmd(cmdstring);
return; 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 // choose last Director object if still available
if ( IsActivePlayer( gEngfuncs.GetEntityByIndex( m_lastPrimaryObject ) ) ) if ( IsActivePlayer( gEngfuncs.GetEntityByIndex( m_lastPrimaryObject ) ) )
@ -871,6 +1221,8 @@ void CHudSpectator::SetModes(int iNewMainMode, int iNewInsetMode)
SetCrosshair( 0, m_crosshairRect, 0, 0, 0 ); SetCrosshair( 0, m_crosshairRect, 0, 0, 0 );
} }
gViewPort->MsgFunc_ResetFade( NULL, 0, NULL );
char string[128]; char string[128];
sprintf(string, "#Spec_Mode%d", g_iUser1 ); sprintf(string, "#Spec_Mode%d", g_iUser1 );
sprintf(string, "%c%s", HUD_PRINTCENTER, CHudTextMessage::BufferedLocaliseTextString( string )); sprintf(string, "%c%s", HUD_PRINTCENTER, CHudTextMessage::BufferedLocaliseTextString( string ));
@ -928,7 +1280,7 @@ bool CHudSpectator::ParseOverviewFile( )
if (!pfile) 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; return false;
} }
@ -1076,7 +1428,7 @@ void CHudSpectator::DrawOverviewLayer()
if ( hasMapImage) if ( hasMapImage)
{ {
i = m_MapSprite->numframes / (4*3); i = m_MapSprite->numframes / (4*3);
i = sqrt(i); i = sqrt((float)i);
xTiles = i*4; xTiles = i*4;
yTiles = i*3; yTiles = i*3;
} }
@ -1591,6 +1943,12 @@ void CHudSpectator::Reset()
memset( &m_OverviewEntities, 0, sizeof(m_OverviewEntities)); memset( &m_OverviewEntities, 0, sizeof(m_OverviewEntities));
m_FOV = 90.0f;
m_IsInterpolating = false;
m_ChaseEntity = 0;
SetSpectatorStartPosition(); SetSpectatorStartPosition();
} }
@ -1613,7 +1971,7 @@ void CHudSpectator::InitHUDData()
Reset(); Reset();
SetModes( OBS_CHASE_FREE, INSET_OFF ); SetModes( OBS_CHASE_LOCKED, INSET_OFF );
g_iUser2 = 0; // fake not target until first camera command 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: // Purpose:
// //
@ -10,7 +10,7 @@
#pragma once #pragma once
#include "cl_entity.h" #include "cl_entity.h"
#include "interpolation.h"
#define INSET_OFF 0 #define INSET_OFF 0
@ -21,11 +21,12 @@
#define MAX_SPEC_HUD_MESSAGES 8 #define MAX_SPEC_HUD_MESSAGES 8
#define OVERVIEW_TILE_SIZE 128 // don't change this #define OVERVIEW_TILE_SIZE 128 // don't change this
#define OVERVIEW_MAX_LAYERS 1 #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 ) // 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; double killTime;
} overviewEntity_t; } 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_OVERVIEW_ENTITIES 128
#define MAX_CAM_WAYPOINTS 32
class CHudSpectator : public CHudBase class CHudSpectator : public CHudBase
{ {
@ -76,6 +87,7 @@ public:
void HandleButtonsDown(int ButtonPressed); void HandleButtonsDown(int ButtonPressed);
void HandleButtonsUp(int ButtonPressed); void HandleButtonsUp(int ButtonPressed);
void FindNextPlayer( bool bReverse ); void FindNextPlayer( bool bReverse );
void FindPlayer(const char *name);
void DirectorMessage( int iSize, void *pbuf ); void DirectorMessage( int iSize, void *pbuf );
void SetSpectatorStartPosition(); void SetSpectatorStartPosition();
int Init(); int Init();
@ -83,6 +95,13 @@ public:
int Draw(float flTime); 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; int m_iDrawCycle;
client_textmessage_t m_HUDMessages[MAX_SPEC_HUD_MESSAGES]; client_textmessage_t m_HUDMessages[MAX_SPEC_HUD_MESSAGES];
char m_HUDMessageText[MAX_SPEC_HUD_MESSAGES][128]; char m_HUDMessageText[MAX_SPEC_HUD_MESSAGES][128];
@ -99,13 +118,15 @@ public:
cvar_t * m_drawstatus; cvar_t * m_drawstatus;
cvar_t * m_autoDirector; cvar_t * m_autoDirector;
cvar_t * m_pip; cvar_t * m_pip;
qboolean m_chatEnabled; 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_cameraOrigin; // a help camera
vec3_t m_cameraAngles; // and it's angles vec3_t m_cameraAngles; // and it's angles
CInterpolation m_WayInterpolation;
private: private:
vec3_t m_vPlayerPos[MAX_PLAYERS]; 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 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_flNextObserverInput;
float m_FOV;
float m_zoomDelta; float m_zoomDelta;
float m_moveDelta; float m_moveDelta;
int m_lastPrimaryObject; int m_lastPrimaryObject;
int m_lastSecondaryObject; int m_lastSecondaryObject;
cameraWayPoint_t m_CamPath[MAX_CAM_WAYPOINTS];
}; };
#endif // SPECTATOR_H #endif // SPECTATOR_H

View file

@ -14,18 +14,13 @@
#include "const.h" #include "const.h"
#include "camera.h" #include "camera.h"
#include "in_defs.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); 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; extern cl_enginefunc_t gEngfuncs;
//-------------------------------------------------- Constants //-------------------------------------------------- Constants
@ -88,6 +83,15 @@ void CAM_ToFirstPerson(void);
void CAM_StartDistance(void); void CAM_StartDistance(void);
void CAM_EndDistance(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 //-------------------------------------------------- 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); 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 origin;
vec3_t ext, pnt, camForward, camRight, camUp; vec3_t ext, pnt, camForward, camRight, camUp;
moveclip_t clip; moveclip_t clip;
@ -194,7 +200,7 @@ void DLLEXPORT CAM_Think( void )
if (cam_mousemove) if (cam_mousemove)
{ {
//get windows cursor position //get windows cursor position
GetCursorPos (&cam_mouse); SDL_GetCursorPos (&cam_mouse);
//check for X delta values and adjust accordingly //check for X delta values and adjust accordingly
//eventually adjust YAW based on amount of movement //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 //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_x=cam_mouse.x;
cam_old_mouse_y=cam_mouse.y; 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 //since we are done with the mouse
cam_old_mouse_x=cam_mouse.x*gHUD.GetSensitivity(); cam_old_mouse_x=cam_mouse.x*gHUD.GetSensitivity();
cam_old_mouse_y=cam_mouse.y*gHUD.GetSensitivity(); cam_old_mouse_y=cam_mouse.y*gHUD.GetSensitivity();
SetCursorPos (gEngfuncs.GetWindowCenterX(), gEngfuncs.GetWindowCenterY()); SDL_SetCursorPos (gEngfuncs.GetWindowCenterX(), gEngfuncs.GetWindowCenterY());
} }
#ifdef LATER #ifdef LATER
if( cam_contain->value ) if( cam_contain->value )
@ -540,7 +546,7 @@ void CAM_StartMouseMove(void)
{ {
cam_mousemove=1; cam_mousemove=1;
iMouseInUse=1; iMouseInUse=1;
GetCursorPos (&cam_mouse); SDL_GetCursorPos (&cam_mouse);
if ( ( flSensitivity = gHUD.GetSensitivity() ) != 0 ) if ( ( flSensitivity = gHUD.GetSensitivity() ) != 0 )
{ {
@ -587,7 +593,7 @@ void CAM_StartDistance(void)
cam_distancemove=1; cam_distancemove=1;
cam_mousemove=1; cam_mousemove=1;
iMouseInUse=1; iMouseInUse=1;
GetCursorPos (&cam_mouse); SDL_GetCursorPos (&cam_mouse);
cam_old_mouse_x=cam_mouse.x*gHUD.GetSensitivity(); cam_old_mouse_x=cam_mouse.x*gHUD.GetSensitivity();
cam_old_mouse_y=cam_mouse.y*gHUD.GetSensitivity(); cam_old_mouse_y=cam_mouse.y*gHUD.GetSensitivity();
} }
@ -610,12 +616,16 @@ void CAM_EndDistance(void)
iMouseInUse=0; 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) ); 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 ); VectorCopy( cam_ofs, ofs );
} }

View file

@ -16,6 +16,5 @@
// fall over // fall over
#define ROLL 2 #define ROLL 2
#define DLLEXPORT __declspec( dllexport )
#endif #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 // 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 //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 "camera.h"
#include "in_defs.h" #include "in_defs.h"
#include "view.h" #include "view.h"
#include "bench.h"
#include <string.h> #include <string.h>
#include <ctype.h> #include <ctype.h>
#include "Exports.h"
#include "vgui_TeamFortressViewport.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_iAlive;
extern int g_weaponselect; 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 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; kblist_t *p;
p = g_kbkeys; p = g_kbkeys;
while ( p ) while ( p )
@ -376,8 +365,10 @@ HUD_Key_Event
Return 1 to allow engine to process the key, otherwise, act on it as needed 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) if (gViewPort)
return gViewPort->KeyInput(down, keynum, pszCurrentBinding); return gViewPort->KeyInput(down, keynum, pszCurrentBinding);
@ -462,6 +453,10 @@ void IN_Attack2Down(void)
{ {
KeyDown(&in_attack2); KeyDown(&in_attack2);
#ifdef _TFC
__CmdFunc_InputPlayerSpecial();
#endif
gHUD.m_Spectator.HandleButtonsDown( IN_ATTACK2 ); 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 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; float spd;
vec3_t viewangles; vec3_t viewangles;
static vec3_t oldangles; static vec3_t oldangles;
if ( active ) if ( active && !Bench_Active() )
{ {
//memset( viewangles, 0, sizeof( vec3_t ) ); //memset( viewangles, 0, sizeof( vec3_t ) );
//viewangles[ 0 ] = viewangles[ 1 ] = viewangles[ 2 ] = 0.0; //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 ); VectorCopy( oldangles, cmd->viewangles );
} }
Bench_SetViewAngles( 1, (float *)&cmd->viewangles, frametime, cmd );
} }
/* /*
@ -1022,7 +1020,22 @@ void ShutdownInput (void)
KB_Shutdown(); 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(); ShutdownInput();
#if defined( _TFC )
ClearEventList();
#endif
CL_UnloadParticleMan();
} }

View file

@ -8,6 +8,8 @@
// in_win.c -- windows 95 mouse and joystick code // in_win.c -- windows 95 mouse and joystick code
// 02/21/97 JCB Added extended DirectInput code to support external controllers. // 02/21/97 JCB Added extended DirectInput code to support external controllers.
#include "port.h"
#include "hud.h" #include "hud.h"
#include "cl_util.h" #include "cl_util.h"
#include "camera.h" #include "camera.h"
@ -17,26 +19,19 @@
#include "const.h" #include "const.h"
#include "camera.h" #include "camera.h"
#include "in_defs.h" #include "in_defs.h"
#include "../engine/keydefs.h" #include "../public/keydefs.h"
#include "view.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 #define MOUSE_BUTTON_COUNT 5
// Set this to 1 to show mouse cursor. Experimental // Set this to 1 to show mouse cursor. Experimental
int g_iVisibleMouse = 0; 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 cl_enginefunc_t gEngfuncs;
extern int iMouseInUse; extern int iMouseInUse;
extern kbutton_t in_strafe; extern kbutton_t in_strafe;
@ -59,18 +54,39 @@ extern cvar_t *cl_forwardspeed;
extern cvar_t *cl_pitchspeed; extern cvar_t *cl_pitchspeed;
extern cvar_t *cl_movespeedkey; 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 // mouse variables
cvar_t *m_filter; cvar_t *m_filter;
cvar_t *sensitivity; 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_buttons;
int mouse_oldbuttonstate; int mouse_oldbuttonstate;
POINT current_pos; 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 restore_spi;
static int originalmouseparms[3], newmouseparms[3] = {0, 0, 1}; static int originalmouseparms[3], newmouseparms[3] = {0, 0, 1};
static int mouseactive; static int mouseactive = 0;
int mouseinitialized; int mouseinitialized;
static int mouseparmsvalid; static int mouseparmsvalid;
static int mouseshowtoggle = 1; static int mouseshowtoggle = 1;
@ -96,19 +112,17 @@ enum _ControlList
AxisTurn AxisTurn
}; };
DWORD dwAxisFlags[JOY_MAX_AXES] =
{
JOY_RETURNX,
JOY_RETURNY,
JOY_RETURNZ,
JOY_RETURNR,
JOY_RETURNU,
JOY_RETURNV
};
DWORD dwAxisMap[ JOY_MAX_AXES ]; DWORD dwAxisMap[ JOY_MAX_AXES ];
DWORD dwControlMap[ 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 // none of these cvars are saved over a session
// this means that advanced controller configuration needs to be executed // this means that advanced controller configuration needs to be executed
@ -136,13 +150,13 @@ cvar_t *joy_wwhack1;
cvar_t *joy_wwhack2; cvar_t *joy_wwhack2;
int joy_avail, joy_advancedinit, joy_haspov; int joy_avail, joy_advancedinit, joy_haspov;
DWORD joy_oldbuttonstate, joy_oldpovstate;
int joy_id; #ifdef _WIN32
DWORD joy_flags; DWORD s_hMouseThreadId = 0;
DWORD joy_numbuttons; HANDLE s_hMouseThread = 0;
HANDLE s_hMouseQuitEvent = 0;
static JOYINFOEX ji; 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 IN_ActivateMouse
=========== ===========
*/ */
void DLLEXPORT IN_ActivateMouse (void) void CL_DLLEXPORT IN_ActivateMouse (void)
{ {
if (mouseinitialized) if (mouseinitialized)
{ {
#ifdef _WIN32
if (mouseparmsvalid) if (mouseparmsvalid)
restore_spi = SystemParametersInfo (SPI_SETMOUSE, 0, newmouseparms, 0); restore_spi = SystemParametersInfo (SPI_SETMOUSE, 0, newmouseparms, 0);
#endif
mouseactive = 1; mouseactive = 1;
} }
} }
/* /*
=========== ===========
IN_DeactivateMouse IN_DeactivateMouse
=========== ===========
*/ */
void DLLEXPORT IN_DeactivateMouse (void) void CL_DLLEXPORT IN_DeactivateMouse (void)
{ {
if (mouseinitialized) if (mouseinitialized)
{ {
#ifdef _WIN32
if (restore_spi) if (restore_spi)
SystemParametersInfo (SPI_SETMOUSE, 0, originalmouseparms, 0); SystemParametersInfo (SPI_SETMOUSE, 0, originalmouseparms, 0);
#endif
mouseactive = 0; mouseactive = 0;
} }
} }
@ -203,6 +268,7 @@ void IN_StartupMouse (void)
return; return;
mouseinitialized = 1; mouseinitialized = 1;
#ifdef _WIN32
mouseparmsvalid = SystemParametersInfo (SPI_GETMOUSE, 0, originalmouseparms, 0); mouseparmsvalid = SystemParametersInfo (SPI_GETMOUSE, 0, originalmouseparms, 0);
if (mouseparmsvalid) if (mouseparmsvalid)
@ -223,7 +289,8 @@ void IN_StartupMouse (void)
newmouseparms[2] = originalmouseparms[2]; newmouseparms[2] = originalmouseparms[2];
} }
} }
#endif
mouse_buttons = MOUSE_BUTTON_COUNT; mouse_buttons = MOUSE_BUTTON_COUNT;
} }
@ -235,6 +302,34 @@ IN_Shutdown
void IN_Shutdown (void) void IN_Shutdown (void)
{ {
IN_DeactivateMouse (); 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 ) 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 IN_MouseEvent
=========== ===========
*/ */
void DLLEXPORT IN_MouseEvent (int mstate) void CL_DLLEXPORT IN_MouseEvent (int mstate)
{ {
int i; int i;
@ -292,6 +402,55 @@ void DLLEXPORT IN_MouseEvent (int mstate)
mouse_oldbuttonstate = 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 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 //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 // 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); int deltaX, deltaY;
#ifdef _WIN32
mx = current_pos.x - gEngfuncs.GetWindowCenterX() + mx_accum; if ( !m_bRawInput )
my = current_pos.y - gEngfuncs.GetWindowCenterY() + my_accum; {
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; mx_accum = 0;
my_accum = 0; my_accum = 0;
if (m_filter->value) if (m_filter && m_filter->value)
{ {
mouse_x = (mx + old_mouse_x) * 0.5; mouse_x = (mx + old_mouse_x) * 0.5;
mouse_y = (my + old_mouse_y) * 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_x = mx;
old_mouse_y = my; old_mouse_y = my;
if ( gHUD.GetSensitivity() != 0 ) // Apply custom mouse scaling/acceleration
{ IN_ScaleMouse( &mouse_x, &mouse_y );
mouse_x *= gHUD.GetSensitivity();
mouse_y *= gHUD.GetSensitivity();
}
else
{
mouse_x *= sensitivity->value;
mouse_y *= sensitivity->value;
}
// add mouse X/Y movement to cmd // add mouse X/Y movement to cmd
if ( (in_strafe.state & 1) || (lookstrafe->value && (in_mlook.state & 1) )) 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 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 //only accumulate mouse if we are not moving the camera with the mouse
if ( !iMouseInUse && !g_iVisibleMouse ) if ( !iMouseInUse && !g_iVisibleMouse)
{ {
if (mouseactive) if (mouseactive)
{ {
GetCursorPos (&current_pos); #ifdef _WIN32
if ( !m_bRawInput )
mx_accum += current_pos.x - gEngfuncs.GetWindowCenterX(); {
my_accum += current_pos.y - gEngfuncs.GetWindowCenterY(); 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 // force the mouse to the center, so there's room to move
IN_ResetMouse(); IN_ResetMouse();
} }
} }
@ -423,7 +629,7 @@ void DLLEXPORT IN_Accumulate (void)
IN_ClearStates IN_ClearStates
=================== ===================
*/ */
void DLLEXPORT IN_ClearStates (void) void CL_DLLEXPORT IN_ClearStates (void)
{ {
if ( !mouseactive ) if ( !mouseactive )
return; return;
@ -440,93 +646,66 @@ IN_StartupJoystick
*/ */
void IN_StartupJoystick (void) void IN_StartupJoystick (void)
{ {
int numdevs;
JOYCAPS jc;
MMRESULT mmr;
// assume no joystick
joy_avail = 0;
// abort startup if user requests no joystick // abort startup if user requests no joystick
if ( gEngfuncs.CheckParm ("-nojoy", NULL ) ) if ( gEngfuncs.CheckParm ("-nojoy", NULL ) )
return; return;
// verify joystick driver is present // assume no joystick
if ((numdevs = joyGetNumDevs ()) == 0) 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"); 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;
} }
/* int RawValuePointer (int axis)
===========
RawValuePointer
===========
*/
PDWORD RawValuePointer (int axis)
{ {
switch (axis) switch (axis)
{ {
case JOY_AXIS_X: default:
return &ji.dwXpos; case JOY_AXIS_X:
case JOY_AXIS_Y: return SDL_GameControllerGetAxis( s_pJoystick, SDL_CONTROLLER_AXIS_LEFTX );
return &ji.dwYpos; case JOY_AXIS_Y:
case JOY_AXIS_Z: return SDL_GameControllerGetAxis( s_pJoystick, SDL_CONTROLLER_AXIS_LEFTY );
return &ji.dwZpos; case JOY_AXIS_Z:
case JOY_AXIS_R: return SDL_GameControllerGetAxis( s_pJoystick, SDL_CONTROLLER_AXIS_RIGHTX );
return &ji.dwRpos; case JOY_AXIS_R:
case JOY_AXIS_U: return SDL_GameControllerGetAxis( s_pJoystick, SDL_CONTROLLER_AXIS_RIGHTY );
return &ji.dwUpos;
case JOY_AXIS_V:
return &ji.dwVpos;
} }
// FIX: need to do some kind of error
return &ji.dwXpos;
} }
/* /*
=========== ===========
Joy_AdvancedUpdate_f Joy_AdvancedUpdate_f
@ -586,16 +765,6 @@ void Joy_AdvancedUpdate_f (void)
dwAxisMap[JOY_AXIS_V] = dwTemp & 0x0000000f; dwAxisMap[JOY_AXIS_V] = dwTemp & 0x0000000f;
dwControlMap[JOY_AXIS_V] = dwTemp & JOY_RELATIVE_AXIS; 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) void IN_Commands (void)
{ {
int i, key_index; int i, key_index;
DWORD buttonstate, povstate;
if (!joy_avail) if (!joy_avail)
{ {
return; return;
} }
DWORD buttonstate, povstate;
// loop through the joystick buttons // loop through the joystick buttons
// key a joystick event or auxillary event for higher number buttons for each state change // 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++) for (i=0 ; i < (int)joy_numbuttons ; i++)
{ {
if ( (buttonstate & (1<<i)) && !(joy_oldbuttonstate & (1<<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 // this avoids any potential problems related to moving from one
// direction to another without going through the center position // direction to another without going through the center position
povstate = 0; 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 // determine which bits have changed and key an auxillary event for each change
for (i=0 ; i < 4 ; i++) for (i=0 ; i < 4 ; i++)
{ {
@ -676,31 +847,8 @@ IN_ReadJoystick
*/ */
int IN_ReadJoystick (void) int IN_ReadJoystick (void)
{ {
SDL_JoystickUpdate();
memset (&ji, 0, sizeof(ji)); return 1;
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;
}
} }
@ -750,9 +898,7 @@ void IN_JoyMove ( float frametime, usercmd_t *cmd )
for (i = 0; i < JOY_MAX_AXES; i++) for (i = 0; i < JOY_MAX_AXES; i++)
{ {
// get the floating point zero-centered, potentially-inverted data for the current axis // get the floating point zero-centered, potentially-inverted data for the current axis
fAxisValue = (float) *pdwRawValue[i]; fAxisValue = (float)pdwRawValue[i];
// move centerpoint to zero
fAxisValue -= 32768.0;
if (joy_wwhack2->value != 0.0) if (joy_wwhack2->value != 0.0)
{ {
@ -891,7 +1037,6 @@ void IN_JoyMove ( float frametime, usercmd_t *cmd )
viewangles[PITCH] = -cl_pitchup->value; viewangles[PITCH] = -cl_pitchup->value;
gEngfuncs.SetViewAngles( (float *)viewangles ); gEngfuncs.SetViewAngles( (float *)viewangles );
} }
/* /*
@ -939,9 +1084,31 @@ void IN_Init (void)
joy_wwhack1 = gEngfuncs.pfnRegisterVariable ( "joywwhack1", "0.0", 0 ); joy_wwhack1 = gEngfuncs.pfnRegisterVariable ( "joywwhack1", "0.0", 0 );
joy_wwhack2 = gEngfuncs.pfnRegisterVariable ( "joywwhack2", "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 ("force_centerview", Force_CenterView_f);
gEngfuncs.pfnAddCommand ("joyadvancedupdate", Joy_AdvancedUpdate_f); gEngfuncs.pfnAddCommand ("joyadvancedupdate", Joy_AdvancedUpdate_f);
IN_StartupMouse (); IN_StartupMouse ();
IN_StartupJoystick (); 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; 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 ) int CHudMenu :: Draw( float flTime )
{ {
// check for if menu is set to disappear // check for if menu is set to disappear
@ -84,7 +147,8 @@ int CHudMenu :: Draw( float flTime )
// count the number of newlines // count the number of newlines
int nlc = 0; 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' ) if ( g_szMenuString[i] == '\n' )
nlc++; nlc++;
@ -92,18 +156,50 @@ int CHudMenu :: Draw( float flTime )
// center it // center it
int y = (ScreenHeight/2) - ((nlc/2)*12) - 40; // make sure it is above the say text int y = (ScreenHeight/2) - ((nlc/2)*12) - 40; // make sure it is above the say text
int x = 20;
i = 0; menu_r = 255;
while ( i < MAX_MENU_STRING && g_szMenuString[i] != '\0' ) 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 ); if ( *sptr == '\\' )
y += 12; {
sptr = ParseEscapeToken( sptr );
while ( i < MAX_MENU_STRING && g_szMenuString[i] != '\0' && g_szMenuString[i] != '\n' ) }
i++; else if ( *sptr == '\n' )
if ( g_szMenuString[i] == '\n' ) {
i++; 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; return 1;
@ -117,7 +213,7 @@ void CHudMenu :: SelectMenuItem( int menu_item )
{ {
char szbuf[32]; char szbuf[32];
sprintf( szbuf, "menuselect %d\n", menu_item ); sprintf( szbuf, "menuselect %d\n", menu_item );
ClientCmd( szbuf ); EngineClientCmd( szbuf );
// remove the menu // remove the menu
m_fMenuDisplayed = 0; m_fMenuDisplayed = 0;

View file

@ -147,13 +147,13 @@ void CHudMessage::MessageScanNextChar( void )
srcGreen = m_parms.pMessage->g1; srcGreen = m_parms.pMessage->g1;
srcBlue = m_parms.pMessage->b1; srcBlue = m_parms.pMessage->b1;
blend = 0; // Pure source blend = 0; // Pure source
destRed = destGreen = destBlue = 0;
switch( m_parms.pMessage->effect ) switch( m_parms.pMessage->effect )
{ {
// Fade-in / Fade-out // Fade-in / Fade-out
case 0: case 0:
case 1: case 1:
destRed = destGreen = destBlue = 0;
blend = m_parms.fadeBlend; blend = m_parms.fadeBlend;
break; break;
@ -168,7 +168,6 @@ void CHudMessage::MessageScanNextChar( void )
{ {
float deltaTime = m_parms.time - m_parms.charTime; float deltaTime = m_parms.time - m_parms.charTime;
destRed = destGreen = destBlue = 0;
if ( m_parms.time > m_parms.fadeTime ) if ( m_parms.time > m_parms.fadeTime )
{ {
blend = m_parms.fadeBlend; 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 <string.h>
#include <stdio.h> #include <stdio.h>
#include <malloc.h> // _alloca
#include "vgui_TeamFortressViewport.h" #include "vgui_TeamFortressViewport.h"
@ -129,16 +130,25 @@ int CHudSayText :: Draw( float flTime )
if ( *g_szLineBuffer[i] == 2 && g_pflNameColors[i] ) if ( *g_szLineBuffer[i] == 2 && g_pflNameColors[i] )
{ {
// it's a saytext string // 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 // draw the first x characters in the player color
strncpy( buf, g_szLineBuffer[i], min(g_iNameLengths[i], MAX_PLAYER_NAME_LENGTH+32) ); 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; 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] ); gEngfuncs.pfnDrawSetTextColor( g_pflNameColors[i][0], g_pflNameColors[i][1], g_pflNameColors[i][2] );
int x = DrawConsoleString( LINE_START, y, buf ); 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] ));
// color is reset after each string draw buf[ strlen( g_szLineBuffer[i] + g_iNameLengths[i] ) - 1 ] = '\0';
DrawConsoleString( x, y, g_szLineBuffer[i] + g_iNameLengths[i] ); // color is reset after each string draw
DrawConsoleString( x, y, buf );
}
else
{
assert( "Not able to alloca chat buffer!\n");
}
} }
else else
{ {
@ -150,7 +160,6 @@ int CHudSayText :: Draw( float flTime )
y += line_height; y += line_height;
} }
return 1; return 1;
} }
@ -173,8 +182,9 @@ void CHudSayText :: SayTextPrint( const char *pszBuf, int iBufSize, int clientIn
return; return;
} }
int i;
// find an empty string slot // find an empty string slot
for ( int i = 0; i < MAX_LINES; i++ ) for ( i = 0; i < MAX_LINES; i++ )
{ {
if ( ! *g_szLineBuffer[i] ) if ( ! *g_szLineBuffer[i] )
break; 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 it's a say message, search for the players name in the string
if ( *pszBuf == 2 && clientIndex > 0 ) if ( *pszBuf == 2 && clientIndex > 0 )
{ {
GetPlayerInfo( clientIndex, &g_PlayerInfoList[clientIndex] ); gEngfuncs.pfnGetPlayerInfo( clientIndex, &g_PlayerInfoList[clientIndex] );
const char *pName = g_PlayerInfoList[clientIndex].name; const char *pName = g_PlayerInfoList[clientIndex].name;
if ( pName ) 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 // make sure the text fits in one line
EnsureTextFitsInOneLineAndWrapIfHaveTo( i ); EnsureTextFitsInOneLineAndWrapIfHaveTo( i );
@ -221,12 +231,7 @@ void CHudSayText :: SayTextPrint( const char *pszBuf, int iBufSize, int clientIn
m_iFlags |= HUD_ACTIVE; m_iFlags |= HUD_ACTIVE;
PlaySound( "misc/talk.wav", 1 ); PlaySound( "misc/talk.wav", 1 );
if ( ScreenHeight >= 480 ) Y_START = ScreenHeight - 60 - ( line_height * (MAX_LINES+2) );
Y_START = ScreenHeight - 60;
else
Y_START = ScreenHeight - 45;
Y_START -= (line_height * (MAX_LINES+1));
} }
void CHudSayText :: EnsureTextFitsInOneLineAndWrapIfHaveTo( int line ) 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 // 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 ) 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 // 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 ) ) if ( !stricmp( m_IconList[i].szSpriteName, pszIconName ) )
break; break;
@ -155,7 +156,7 @@ void CHudStatusIcons::DisableIcon( char *pszIconName )
if ( !stricmp( m_IconList[i].szSpriteName, pszIconName ) ) if ( !stricmp( m_IconList[i].szSpriteName, pszIconName ) )
{ {
// clear the item from the list // 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; 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 * This product contains software technology licensed from Id
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc. * Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
@ -29,7 +29,11 @@
DECLARE_MESSAGE( m_StatusBar, StatusText ); DECLARE_MESSAGE( m_StatusBar, StatusText );
DECLARE_MESSAGE( m_StatusBar, StatusValue ); DECLARE_MESSAGE( m_StatusBar, StatusValue );
#ifdef _TFC
#define STATUSBAR_ID_LINE 2
#else
#define STATUSBAR_ID_LINE 1 #define STATUSBAR_ID_LINE 1
#endif
float *GetClientColor( int clientIndex ); float *GetClientColor( int clientIndex );
extern float g_ColorYellow[3]; extern float g_ColorYellow[3];
@ -138,7 +142,7 @@ void CHudStatusBar :: ParseStatusString( int line_num )
switch ( valtype ) switch ( valtype )
{ {
case 'p': // player name case 'p': // player name
GetPlayerInfo( indexval, &g_PlayerInfoList[indexval] ); gEngfuncs.pfnGetPlayerInfo( indexval, &g_PlayerInfoList[indexval] );
if ( g_PlayerInfoList[indexval].name != NULL ) if ( g_PlayerInfoList[indexval].name != NULL )
{ {
strncpy( szRepString, g_PlayerInfoList[indexval].name, MAX_PLAYER_NAME_LENGTH ); strncpy( szRepString, g_PlayerInfoList[indexval].name, MAX_PLAYER_NAME_LENGTH );
@ -184,15 +188,15 @@ int CHudStatusBar :: Draw( float fTime )
m_bReparseString = FALSE; m_bReparseString = FALSE;
} }
int Y_START = ScreenHeight - YRES(32 + 4); int Y_START = ScreenHeight - 52;
// Draw the status bar lines // Draw the status bar lines
for ( int i = 0; i < MAX_STATUSBAR_LINES; i++ ) for ( int i = 0; i < MAX_STATUSBAR_LINES; i++ )
{ {
int TextHeight, TextWidth; int TextHeight, TextWidth;
GetConsoleStringSize( m_szStatusBar[i], &TextWidth, &TextHeight ); GetConsoleStringSize( m_szStatusBar[i], &TextWidth, &TextHeight );
int x = 4; int x = 8;
int y = Y_START - ( 4 + TextHeight * i ); // draw along bottom of screen int y = Y_START - ( 4 + TextHeight * i ); // draw along bottom of screen
// let user set status ID bar centering // 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(); int line = READ_BYTE();
if ( line < 0 || line >= MAX_STATUSBAR_LINES ) if ( line < 0 || line > MAX_STATUSBAR_LINES )
return 1; return 1;
strncpy( m_szStatusText[line], READ_STRING(), MAX_STATUSTEXT_LENGTH ); 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) 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;
m_iFlags &= ~HUD_ACTIVE;
else
m_iFlags |= HUD_ACTIVE; // we have status text, so turn on the status bar
m_bReparseString = TRUE; m_bReparseString = TRUE;
return 1; return 1;
@ -254,7 +254,7 @@ int CHudStatusBar :: MsgFunc_StatusValue( const char *pszName, int iSize, void *
BEGIN_READ( pbuf, iSize ); BEGIN_READ( pbuf, iSize );
int index = READ_BYTE(); int index = READ_BYTE();
if ( index < 1 || index >= MAX_STATUSBAR_VALUES ) if ( index < 1 || index > MAX_STATUSBAR_VALUES )
return 1; // index out of range return 1; // index out of range
m_iStatusValues[index] = READ_SHORT(); 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(); 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 ); 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 // keep reading strings and using C format strings for subsituting the strings into the localised text string
char *sstr1 = LookupString( READ_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 StripEndNewlineFromString( sstr1 ); // these strings are meant for subsitution into the main strings, so cull the automatic end newlines
char *sstr2 = LookupString( READ_STRING() ); char *sstr2 = LookupString( READ_STRING() );
sstr2 = strcpy( szBuf[2], sstr2 ); sstr2 = safe_strcpy( szBuf[2], sstr2 , MSG_BUF_SIZE);
StripEndNewlineFromString( sstr2 ); StripEndNewlineFromString( sstr2 );
char *sstr3 = LookupString( READ_STRING() ); char *sstr3 = LookupString( READ_STRING() );
sstr3 = strcpy( szBuf[3], sstr3 ); sstr3 = safe_strcpy( szBuf[3], sstr3 , MSG_BUF_SIZE);
StripEndNewlineFromString( sstr3 ); StripEndNewlineFromString( sstr3 );
char *sstr4 = LookupString( READ_STRING() ); char *sstr4 = LookupString( READ_STRING() );
sstr4 = strcpy( szBuf[4], sstr4 ); sstr4 = safe_strcpy( szBuf[4], sstr4 , MSG_BUF_SIZE);
StripEndNewlineFromString( sstr4 ); StripEndNewlineFromString( sstr4 );
char *psz = szBuf[5]; char *psz = szBuf[5];
@ -188,23 +189,23 @@ int CHudTextMessage::MsgFunc_TextMsg( const char *pszName, int iSize, void *pbuf
switch ( msg_dest ) switch ( msg_dest )
{ {
case HUD_PRINTCENTER: 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 ) ); CenterPrint( ConvertCRtoNL( psz ) );
break; break;
case HUD_PRINTNOTIFY: case HUD_PRINTNOTIFY:
psz[0] = 1; // mark this message to go into the notify buffer 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 ) ); ConsolePrint( ConvertCRtoNL( psz ) );
break; break;
case HUD_PRINTTALK: 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 ); gHUD.m_SayText.SayTextPrint( ConvertCRtoNL( psz ), 128 );
break; break;
case HUD_PRINTCONSOLE: 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 ) ); ConsolePrint( ConvertCRtoNL( psz ) );
break; break;
} }

View file

@ -16,80 +16,11 @@
#include "entity_state.h" #include "entity_state.h"
#include "cl_entity.h" #include "cl_entity.h"
#include "triangleapi.h" #include "triangleapi.h"
#include "Exports.h"
#define DLLEXPORT __declspec( dllexport ) #include "particleman.h"
#include "tri.h"
extern "C" extern IParticleMan *g_pParticleMan;
{
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
/* /*
================= =================
@ -98,16 +29,17 @@ HUD_DrawNormalTriangles
Non-transparent triangles-- add them here Non-transparent triangles-- add them here
================= =================
*/ */
void DLLEXPORT HUD_DrawNormalTriangles( void ) void CL_DLLEXPORT HUD_DrawNormalTriangles( void )
{ {
// RecClDrawNormalTriangles();
gHUD.m_Spectator.DrawOverview(); gHUD.m_Spectator.DrawOverview();
#if defined( TEST_IT )
// Draw_Triangles();
#endif
} }
#if defined( _TFC )
void RunEventList( void );
#endif
/* /*
================= =================
HUD_DrawTransparentTriangles HUD_DrawTransparentTriangles
@ -115,10 +47,14 @@ HUD_DrawTransparentTriangles
Render any triangles with transparent rendermode needs here Render any triangles with transparent rendermode needs here
================= =================
*/ */
void DLLEXPORT HUD_DrawTransparentTriangles( void ) void CL_DLLEXPORT HUD_DrawTransparentTriangles( void )
{ {
// RecClDrawTransparentTriangles();
#if defined( TEST_IT ) #if defined( _TFC )
// Draw_Triangles(); RunEventList();
#endif #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 // implementation of class-less helper functions
// //
#include "STDIO.H" #include "stdio.h"
#include "STDLIB.H" #include "stdlib.h"
#include "MATH.H" #include "math.h"
#include "hud.h" #include "hud.h"
#include "cl_util.h" #include "cl_util.h"

View file

@ -17,13 +17,13 @@
// //
// Misc C-runtime library headers // Misc C-runtime library headers
#include "STDIO.H" #include "stdio.h"
#include "STDLIB.H" #include "stdlib.h"
#include "MATH.H" #include "math.h"
// Header file containing definition of globalvars_t and entvars_t // Header file containing definition of globalvars_t and entvars_t
typedef int func_t; // typedef unsigned int func_t; //
typedef int string_t; // from engine's pr_comp.h; typedef unsigned int string_t; // from engine's pr_comp.h;
typedef float vec_t; // needed before including progdefs.h typedef float vec_t; // needed before including progdefs.h
//========================================================= //=========================================================
@ -61,6 +61,7 @@ public:
vec_t x, y; 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 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; } 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 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 ); } 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 #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(); m_pScrollPanel->validate();
// Create the Class buttons // Create the Class buttons
#ifdef _TFC
for (int i = 0; i <= PC_RANDOM; i++) for (int i = 0; i <= PC_RANDOM; i++)
{ {
char sz[256]; 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->setBgColor( r, g, b, a );
pNameLabel->setContentAlignment( vgui::Label::a_west ); pNameLabel->setContentAlignment( vgui::Label::a_west );
//pNameLabel->setBorder(new LineBorder()); //pNameLabel->setBorder(new LineBorder());
pNameLabel->setText(localName); pNameLabel->setText( "%s", localName);
// Create the Class Image // Create the Class Image
if ( bShowClassGraphic ) if ( bShowClassGraphic )
@ -239,7 +240,7 @@ CClassMenuPanel::CClassMenuPanel(int iTrans, int iRemoveMe, int x,int y,int wide
//m_pClassInfoPanel[i]->setBorder(new LineBorder()); //m_pClassInfoPanel[i]->setBorder(new LineBorder());
} }
#endif
// Create the Cancel button // 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 = 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 ); m_pCancelButton->setParent( this );
@ -260,6 +261,7 @@ void CClassMenuPanel::Update()
int iYPos = CLASSMENU_TOPLEFT_BUTTON_Y; int iYPos = CLASSMENU_TOPLEFT_BUTTON_Y;
// Cycle through the rest of the buttons // Cycle through the rest of the buttons
#ifdef _TFC
for (int i = 0; i <= PC_RANDOM; i++) for (int i = 0; i <= PC_RANDOM; i++)
{ {
bool bCivilian = (gViewPort->GetValidClasses(g_iTeamNumber) == -1); bool bCivilian = (gViewPort->GetValidClasses(g_iTeamNumber) == -1);
@ -318,7 +320,7 @@ void CClassMenuPanel::Update()
char sz[256]; char sz[256];
sprintf(sz, m_sPlayersOnTeamString, iTotal); sprintf(sz, m_sPlayersOnTeamString, iTotal);
m_pPlayers[i]->setText( sz ); m_pPlayers[i]->setText( "%s", sz );
// Set the text color to the teamcolor // Set the text color to the teamcolor
m_pPlayers[i]->setFgColor( iTeamColors[g_iTeamNumber % iNumberOfTeamColors][0], 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 the player already has a class, make the cancel button visible
if ( g_iPlayerClass ) if ( g_iPlayerClass )
@ -413,6 +416,7 @@ void CClassMenuPanel::Initialize( void )
void CClassMenuPanel::SetActiveInfo( int iInput ) void CClassMenuPanel::SetActiveInfo( int iInput )
{ {
// Remove all the Info panels and bring up the specified one // Remove all the Info panels and bring up the specified one
#ifdef _TFC
for (int i = 0; i <= PC_RANDOM; i++) for (int i = 0; i <= PC_RANDOM; i++)
{ {
m_pButtons[i]->setArmed( false ); m_pButtons[i]->setArmed( false );
@ -420,6 +424,7 @@ void CClassMenuPanel::SetActiveInfo( int iInput )
} }
if ( iInput > PC_RANDOM || iInput < 0 ) if ( iInput > PC_RANDOM || iInput < 0 )
#endif
iInput = 0; iInput = 0;
m_pButtons[iInput]->setArmed( true ); 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 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 // The contents may be used and/or copied only with the written permission of
@ -32,7 +32,7 @@
#include "vgui_int.h" #include "vgui_int.h"
#include "vgui_TeamFortressViewport.h" #include "vgui_TeamFortressViewport.h"
#include "vgui_ServerBrowser.h" #include "vgui_ServerBrowser.h"
#include "..\game_shared\vgui_LoadTGA.h" #include "vgui_loadtga.h"
// Arrow filenames // Arrow filenames
char *sArrowFilenames[] = char *sArrowFilenames[] =
@ -305,15 +305,21 @@ int ClassButton::IsNotValid()
} }
// Is it an illegal class? // Is it an illegal class?
#ifdef _TFC
if ((gViewPort->GetValidClasses(0) & sTFValidClassInts[ m_iPlayerClass ]) || (gViewPort->GetValidClasses(g_iTeamNumber) & sTFValidClassInts[ m_iPlayerClass ])) if ((gViewPort->GetValidClasses(0) & sTFValidClassInts[ m_iPlayerClass ]) || (gViewPort->GetValidClasses(g_iTeamNumber) & sTFValidClassInts[ m_iPlayerClass ]))
return true; return true;
#endif
// Only check current class if they've got autokill on // Only check current class if they've got autokill on
bool bAutoKill = CVAR_GET_FLOAT( "hud_classautokill" ) != 0; bool bAutoKill = CVAR_GET_FLOAT( "hud_classautokill" ) != 0;
if ( bAutoKill ) if ( bAutoKill )
{ {
// Is it the player's current class? // 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; return true;
} }
@ -529,8 +535,13 @@ void CMenuHandler_StringCommandClassSelect::actionPerformed(Panel* panel)
{ {
CMenuHandler_StringCommand::actionPerformed( 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; bool bAutoKill = CVAR_GET_FLOAT( "hud_classautokill" ) != 0;
if ( bAutoKill && g_iPlayerClass != 0 ) if ( bAutoKill && g_iPlayerClass != 0 )
gEngfuncs.pfnClientCmd("kill"); 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 ); pSchemes->getBgColor( hTitleScheme, r, g, b, a );
pLabel->setBgColor( r, g, b, a ); pLabel->setBgColor( r, g, b, a );
pLabel->setContentAlignment( vgui::Label::a_west ); pLabel->setContentAlignment( vgui::Label::a_west );
pLabel->setText(szTitle); pLabel->setText( "%s", szTitle);
// Create the Scroll panel // 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) ); 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 ); pText->setFgColor( r, g, b, a );
pSchemes->getBgColor( hMOTDText, r, g, b, a ); pSchemes->getBgColor( hMOTDText, r, g, b, a );
pText->setBgColor( 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 // Get the total size of the MOTD text and resize the text panel
int iScrollSizeX, iScrollSizeY; int iScrollSizeX, iScrollSizeY;

View file

@ -395,7 +395,19 @@ buildDefaultFont:
if(g_CV_BitmapFonts && g_CV_BitmapFonts->value) 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 ); pFontData = gEngfuncs.COM_LoadFile( fontFilename, 5, &fontFileLength );
if(!pFontData) if(!pFontData)
gEngfuncs.Con_Printf("Missing bitmap font: %s\n", fontFilename); 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 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 // The contents may be used and/or copied only with the written permission of
@ -26,12 +26,13 @@
#include "cl_entity.h" #include "cl_entity.h"
#include "vgui_TeamFortressViewport.h" #include "vgui_TeamFortressViewport.h"
#include "vgui_ScorePanel.h" #include "vgui_ScorePanel.h"
#include "..\game_shared\vgui_helpers.h" #include "vgui_helpers.h"
#include "..\game_shared\vgui_loadtga.h" #include "vgui_loadtga.h"
#include "voice_status.h"
#include "vgui_SpectatorPanel.h" #include "vgui_SpectatorPanel.h"
hud_player_info_t g_PlayerInfoList[MAX_PLAYERS+1]; // player info from the engine extern 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 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]; team_info_t g_TeamInfo[MAX_TEAMS+1];
int g_IsSpectator[MAX_PLAYERS+1]; int g_IsSpectator[MAX_PLAYERS+1];
@ -56,7 +57,7 @@ public:
SBColumnInfo g_ColumnInfo[NUM_COLUMNS] = SBColumnInfo g_ColumnInfo[NUM_COLUMNS] =
{ {
{NULL, 24, Label::a_east}, {NULL, 24, Label::a_east}, // tracker column
{NULL, 140, Label::a_east}, // name {NULL, 140, Label::a_east}, // name
{NULL, 56, Label::a_east}, // class {NULL, 56, Label::a_east}, // class
{"#SCORE", 40, Label::a_east}, {"#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_pCurrentHighlightLabel = NULL;
m_iHighlightRow = -1; m_iHighlightRow = -1;
//m_pTrackerIcon = vgui_LoadTGANoInvertAlpha("gfx/vgui/640_scoreboardtracker.tga");
// Initialize the top title. // Initialize the top title.
m_TitleLabel.setFont(tfont); m_TitleLabel.setFont(tfont);
m_TitleLabel.setText(""); 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) else if (i == 0)
{ {
// tracker icon cell
xwide -= 8; 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->setBgColor(0,0,0,255);
// pGridRow->SetSpacing(2, 0);
pGridRow->SetSpacing(0, 0); pGridRow->SetSpacing(0, 0);
pGridRow->CopyColumnWidths(&m_HeaderGrid); pGridRow->CopyColumnWidths(&m_HeaderGrid);
pGridRow->AutoSetRowHeights(); pGridRow->AutoSetRowHeights();
@ -249,7 +252,7 @@ void ScorePanel::Initialize( void )
bool HACK_GetPlayerUniqueID( int iPlayer, char playerID[16] ) 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() void ScorePanel::Update()
{ {
int i;
// Set the title // Set the title
if (gViewPort->m_szServerName) if (gViewPort->m_szServerName)
{ {
@ -269,10 +274,13 @@ void ScorePanel::Update()
gViewPort->GetAllPlayersInfo(); gViewPort->GetAllPlayersInfo();
// Clear out sorts // Clear out sorts
for (int i = 0; i < NUM_ROWS; i++) for (i = 0; i < NUM_ROWS; i++)
{ {
m_iSortedRows[i] = 0; m_iSortedRows[i] = 0;
m_iIsATeam[i] = TEAM_NO; m_iIsATeam[i] = TEAM_NO;
}
for (i = 0; i < MAX_PLAYERS; i++)
{
m_bHasBeenSorted[i] = false; m_bHasBeenSorted[i] = false;
} }
@ -303,7 +311,8 @@ void ScorePanel::Update()
void ScorePanel::SortTeams() void ScorePanel::SortTeams()
{ {
// clear out team scores // 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 ) if ( !g_TeamInfo[i].scores_overriden )
g_TeamInfo[i].frags = g_TeamInfo[i].deaths = 0; 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 continue; // skip over players who are not in a team
// find what team this player is in // 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 ) ) if ( !stricmp( g_PlayerExtraInfo[i].teamname, g_TeamInfo[j].name ) )
break; break;
@ -462,7 +472,8 @@ void ScorePanel::SortPlayers( int iTeam, char *team )
void ScorePanel::RebuildTeams() void ScorePanel::RebuildTeams()
{ {
// clear out player counts from teams // 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; g_TeamInfo[i].players = 0;
} }
@ -479,7 +490,8 @@ void ScorePanel::RebuildTeams()
continue; // skip over players who are not in a team continue; // skip over players who are not in a team
// is this player in an existing 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' ) if ( g_TeamInfo[j].name[0] == '\0' )
break; break;
@ -540,8 +552,8 @@ void ScorePanel::FillGrid()
} }
bool bNextRowIsGap = false; bool bNextRowIsGap = false;
int row;
for(int row=0; row < NUM_ROWS; row++) for(row=0; row < NUM_ROWS; row++)
{ {
CGrid *pGridRow = &m_PlayerGrids[row]; CGrid *pGridRow = &m_PlayerGrids[row];
pGridRow->SetRowUnderline(0, false, 0, 0, 0, 0, 0); pGridRow->SetRowUnderline(0, false, 0, 0, 0, 0, 0);
@ -742,15 +754,24 @@ void ScorePanel::FillGrid()
switch (col) switch (col)
{ {
case COLUMN_NAME: 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); sprintf(sz, "%s ", pl_info->name);
break; break;
case COLUMN_VOICE: case COLUMN_VOICE:
sz[0] = 0; sz[0] = 0;
// in HLTV mode allow spectator to turn on/off commentator voice GetClientVoiceMgr()->UpdateSpeakerImage(pLabel, m_iSortedRows[row]);
if (!pl_info->thisplayer || gEngfuncs.IsSpectateOnly() )
{
GetClientVoiceMgr()->UpdateSpeakerImage(pLabel, m_iSortedRows[row]);
}
break; break;
case COLUMN_CLASS: case COLUMN_CLASS:
// No class for other team's members (unless allied or spectator) // 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 // Don't show classes if this client hasnt picked a team yet
if ( g_iTeamNumber == 0 ) if ( g_iTeamNumber == 0 )
bShowClass = false; bShowClass = false;
#ifdef _TFC
// in TFC show all classes in spectator mode
if ( g_iUser1 )
bShowClass = true;
#endif
if (bShowClass) if (bShowClass)
{ {
@ -782,7 +808,36 @@ void ScorePanel::FillGrid()
break; break;
case COLUMN_TRACKER: 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; 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: case COLUMN_KILLS:
sprintf(sz, "%d", g_PlayerExtraInfo[ m_iSortedRows[row] ].frags ); sprintf(sz, "%d", g_PlayerExtraInfo[ m_iSortedRows[row] ].frags );
break; break;
@ -792,6 +847,7 @@ void ScorePanel::FillGrid()
case COLUMN_LATENCY: case COLUMN_LATENCY:
sprintf(sz, "%d", g_PlayerInfoList[ m_iSortedRows[row] ].ping ); sprintf(sz, "%d", g_PlayerInfoList[ m_iSortedRows[row] ].ping );
break; break;
#endif
default: default:
break; 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: // Purpose:
// //
@ -14,7 +14,7 @@
#include<VGUI_TextGrid.h> #include<VGUI_TextGrid.h>
#include<VGUI_Label.h> #include<VGUI_Label.h>
#include<VGUI_TextImage.h> #include<VGUI_TextImage.h>
#include "..\game_shared\vgui_listbox.h" #include "../game_shared/vgui_listbox.h"
#include <ctype.h> #include <ctype.h>
@ -222,8 +222,8 @@ private:
class ScoreTablePanel; class ScoreTablePanel;
#include "..\game_shared\vgui_grid.h" #include "../game_shared/vgui_grid.h"
#include "..\game_shared\vgui_defaultinputsignal.h" #include "../game_shared/vgui_defaultinputsignal.h"
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Purpose: Scoreboard back panel // Purpose: Scoreboard back panel
@ -304,7 +304,7 @@ public:
virtual void mousePressed(MouseCode code, Panel* panel); virtual void mousePressed(MouseCode code, Panel* panel);
virtual void cursorMoved(int x, int y, Panel *panel); virtual void cursorMoved(int x, int y, Panel *panel);
friend CLabelHeader; friend class CLabelHeader;
}; };
#endif #endif

View file

@ -115,7 +115,7 @@ public:
void DoCancel( void ) void DoCancel( void )
{ {
ClientCmd( "togglebrowser\n" ); EngineClientCmd( "togglebrowser\n" );
} }
void DoConnect( void ) void DoConnect( void )
@ -133,7 +133,7 @@ public:
sprintf( sz, "connect %s\n", address ); sprintf( sz, "connect %s\n", address );
ClientCmd( sz ); EngineClientCmd( sz );
DoCancel(); 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. // vgui_SpectatorPanel.cpp: implementation of the SpectatorPanel class.
// //
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
@ -17,17 +10,34 @@
#include "pm_shared.h" #include "pm_shared.h"
#include "vgui_TeamFortressViewport.h" #include "vgui_TeamFortressViewport.h"
#include "vgui_SpectatorPanel.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 Sets the location of the input for chat text
#define BANNER_HEIGHT 64 ==========================
*/
void CL_DLLEXPORT HUD_ChatInputPosition( int *x, int *y )
{
// RecClChatInputPosition( x, y );
#define OPTIONS_BUTTON_X 96 if ( g_iUser1 != 0 || gEngfuncs.IsSpectateOnly() )
#define CAMOPTIONS_BUTTON_X 200 {
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 // Construction/Destruction
@ -57,6 +67,9 @@ void SpectatorPanel::ActionSignal(int cmd)
case SPECTATOR_PANEL_CMD_PREVPLAYER : gHUD.m_Spectator.FindNextPlayer(false); case SPECTATOR_PANEL_CMD_PREVPLAYER : gHUD.m_Spectator.FindNextPlayer(false);
break; break;
case SPECTATOR_PANEL_CMD_PLAYERS : gViewPort->ShowCommandMenu( gViewPort->m_PlayerMenu );
break;
case SPECTATOR_PANEL_CMD_HIDEMENU : ShowMenu(false); case SPECTATOR_PANEL_CMD_HIDEMENU : ShowMenu(false);
break; break;
@ -84,15 +97,15 @@ void SpectatorPanel::Initialize()
SchemeHandle_t hSmallScheme = pSchemes->getSchemeHandle( "Team Info Text" ); 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_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); m_BottomBorder->setParent(this);
setPaintBackgroundEnabled(false); 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->setParent(m_TopBorder);
m_ExtraInfo->setFont( pSchemes->getFont(hSmallScheme) ); 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 = new CImageLabel( "banner", 0, 0, XRES(BANNER_WIDTH), YRES(BANNER_HEIGHT) );
m_TopBanner->setParent(this); 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->setParent(m_TopBorder);
m_CurrentTime->setFont( pSchemes->getFont(hSmallScheme) ); m_CurrentTime->setFont( pSchemes->getFont(hSmallScheme) );
m_CurrentTime->setPaintBackgroundEnabled(false); m_CurrentTime->setPaintBackgroundEnabled(false);
@ -122,7 +135,7 @@ void SpectatorPanel::Initialize()
for ( int j= 0; j < TEAM_NUMBER; j++ ) 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]->setParent( m_TopBorder );
m_TeamScores[j]->setFont( pSchemes->getFont(hSmallScheme) ); m_TeamScores[j]->setFont( pSchemes->getFont(hSmallScheme) );
m_TeamScores[j]->setPaintBackgroundEnabled(false); m_TeamScores[j]->setPaintBackgroundEnabled(false);
@ -133,7 +146,8 @@ void SpectatorPanel::Initialize()
// Initialize command buttons. // 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->setParent( m_BottomBorder );
m_OptionButton->setContentAlignment( vgui::Label::a_center ); m_OptionButton->setContentAlignment( vgui::Label::a_center );
m_OptionButton->setBoundKey( (char)255 ); // special no bound to avoid leading spaces in name 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->setUnArmedColor ( 143, 143, 54, 0 );
m_OptionButton->setArmedColor ( 194, 202, 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->setParent( m_BottomBorder );
m_CamButton->setContentAlignment( vgui::Label::a_center ); m_CamButton->setContentAlignment( vgui::Label::a_center );
m_CamButton->setBoundKey( (char)255 ); // special no bound to avoid leading spaces in name 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->setUnArmedColor ( 143, 143, 54, 0 );
m_CamButton->setArmedColor ( 194, 202, 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->setParent( m_BottomBorder );
m_PrevPlayerButton->setContentAlignment( vgui::Label::a_center ); m_PrevPlayerButton->setContentAlignment( vgui::Label::a_center );
m_PrevPlayerButton->setBoundKey( (char)255 ); // special no bound to avoid leading spaces in name 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->setUnArmedColor ( 143, 143, 54, 0 );
m_PrevPlayerButton->setArmedColor ( 194, 202, 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->setParent( m_BottomBorder );
m_NextPlayerButton->setContentAlignment( vgui::Label::a_center ); m_NextPlayerButton->setContentAlignment( vgui::Label::a_center );
m_NextPlayerButton->setBoundKey( (char)255 ); // special no bound to avoid leading spaces in name 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 ); 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->setParent(m_BottomBorder);
m_BottomMainLabel->setPaintBackgroundEnabled(false); m_BottomMainLabel->setPaintBackgroundEnabled(false);
m_BottomMainLabel->setFgColor( Scheme::sc_primary1 ); m_BottomMainLabel->setFgColor( Scheme::sc_primary1 );
m_BottomMainLabel->setContentAlignment( vgui::Label::a_center ); 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 = new ColorButton("", XRES(2), YRES(2), XRES(240), YRES(180), false, false );
m_InsetViewButton->setParent( this ); m_InsetViewButton->setParent( this );
m_InsetViewButton->setBoundKey( (char)255 ); m_InsetViewButton->setBoundKey( (char)255 );
@ -215,15 +251,22 @@ void SpectatorPanel::ShowMenu(bool isVisible)
m_CamButton->setVisible(isVisible); m_CamButton->setArmed( false ); m_CamButton->setVisible(isVisible); m_CamButton->setArmed( false );
m_NextPlayerButton->setVisible(isVisible); m_NextPlayerButton->setArmed( false ); m_NextPlayerButton->setVisible(isVisible); m_NextPlayerButton->setArmed( false );
m_PrevPlayerButton->setVisible(isVisible); m_PrevPlayerButton->setArmed( false ); m_PrevPlayerButton->setVisible(isVisible); m_PrevPlayerButton->setArmed( false );
if ( !isVisible ) if ( !isVisible )
{ {
int iLabelSizeX, iLabelSizeY; int iLabelSizeX, iLabelSizeY;
m_BottomMainLabel->setVisible(true);
m_BottomMainButton->setVisible(false);
m_BottomMainLabel->getSize( iLabelSizeX, iLabelSizeY ); m_BottomMainLabel->getSize( iLabelSizeX, iLabelSizeY );
m_BottomMainLabel->setPos( ( ScreenWidth / 2 ) - (iLabelSizeX/2), YRES(6) ); m_BottomMainLabel->setPos( ( ScreenWidth / 2 ) - (iLabelSizeX/2), YRES(6) );
} }
else 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 ) if ( !isVisible )
{ {
@ -288,7 +331,7 @@ void SpectatorPanel::EnableInsetView(bool isEnabled)
if ( isEnabled ) if ( isEnabled )
{ {
// short black bar to see full inset // 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() ) if ( gEngfuncs.IsSpectateOnly() )
{ {
@ -298,8 +341,8 @@ void SpectatorPanel::EnableInsetView(bool isEnabled)
else else
m_TopBanner->setVisible( false ); m_TopBanner->setVisible( false );
m_InsetViewButton->setBounds( XRES( x ), YRES( y ), m_InsetViewButton->setBounds( XRES( x -1 ), YRES( y ),
XRES( wide ), YRES( tall ) ); XRES( wide +2), YRES( tall ) );
m_InsetViewButton->setVisible(true); m_InsetViewButton->setVisible(true);
} }
else else
@ -314,7 +357,7 @@ void SpectatorPanel::EnableInsetView(bool isEnabled)
else else
m_TopBanner->setVisible( false ); 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); m_InsetViewButton->setVisible(false);
} }
@ -356,28 +399,28 @@ void SpectatorPanel::Update()
m_ExtraInfo->getTextSize( iTextWidth, iTextHeight ); m_ExtraInfo->getTextSize( iTextWidth, iTextHeight );
m_CurrentTime->getTextSize( iTimeWidth, iTimeHeight ); m_CurrentTime->getTextSize( iTimeWidth, iTimeHeight );
iTimeWidth += XRES ( 14 ); // +timer icon iTimeWidth += XRES ( SEPERATOR_WIDTH*2 + 1 ); // +timer icon
iTimeWidth += ( 4-(iTimeWidth%4) ); iTimeWidth += ( SEPERATOR_WIDTH-(iTimeWidth%SEPERATOR_WIDTH) );
if ( iTimeWidth > iTextWidth ) if ( iTimeWidth > iTextWidth )
iTextWidth = iTimeWidth; 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->setPos( ScreenWidth - ( iTextWidth + XRES ( 2*SEPERATOR_WIDTH+SEPERATOR_WIDTH/2+offset ) ) , YRES( 5 ) );
m_Separator->setSize( XRES( 4 ), YRES( PANEL_HEIGHT - 2 ) ); m_Separator->setSize( XRES( 1 ), PANEL_HEIGHT - 10 );
for ( j= 0; j < TEAM_NUMBER; j++ ) for ( j= 0; j < TEAM_NUMBER; j++ )
{ {
int iwidth, iheight; int iwidth, iheight;
m_TeamScores[j]->getTextSize( 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. // 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_HIDEMENU 4
#define SPECTATOR_PANEL_CMD_TOGGLE_INSET 5 #define SPECTATOR_PANEL_CMD_TOGGLE_INSET 5
#define SPECTATOR_PANEL_CMD_CAMERA 6 #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 #define TEAM_NUMBER 2
@ -50,20 +58,22 @@ public:
void EnableInsetView(bool isEnabled); void EnableInsetView(bool isEnabled);
void ShowMenu(bool isVisible); void ShowMenu(bool isVisible);
DropDownButton * m_OptionButton;
ColorButton * m_OptionButton;
// CommandButton * m_HideButton; // CommandButton * m_HideButton;
ColorButton * m_PrevPlayerButton; //ColorButton * m_PrevPlayerButton;
ColorButton * m_NextPlayerButton; //ColorButton * m_NextPlayerButton;
ColorButton * m_CamButton; CImageButton * m_PrevPlayerButton;
CImageButton * m_NextPlayerButton;
DropDownButton * m_CamButton;
CTransparentPanel * m_TopBorder; CTransparentPanel * m_TopBorder;
CTransparentPanel * m_BottomBorder; CTransparentPanel * m_BottomBorder;
ColorButton *m_InsetViewButton; ColorButton *m_InsetViewButton;
Label *m_BottomMainLabel; DropDownButton *m_BottomMainButton;
CImageLabel *m_TimerImage; CImageLabel *m_TimerImage;
Label *m_BottomMainLabel;
Label *m_CurrentTime; Label *m_CurrentTime;
Label *m_ExtraInfo; Label *m_ExtraInfo;
Panel *m_Separator; 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 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 // The contents may be used and/or copied only with the written permission of
@ -45,7 +45,7 @@
#include "in_defs.h" #include "in_defs.h"
#include "parsemsg.h" #include "parsemsg.h"
#include "pm_shared.h" #include "pm_shared.h"
#include "../engine/keydefs.h" #include "keydefs.h"
#include "demo.h" #include "demo.h"
#include "demo_api.h" #include "demo_api.h"
@ -55,13 +55,16 @@
#include "vgui_ScorePanel.h" #include "vgui_ScorePanel.h"
#include "vgui_SpectatorPanel.h" #include "vgui_SpectatorPanel.h"
#include "shake.h"
#include "screenfade.h"
extern int g_iVisibleMouse; extern int g_iVisibleMouse;
class CCommandMenu; class CCommandMenu;
int g_iPlayerClass; int g_iPlayerClass;
int g_iTeamNumber; int g_iTeamNumber;
int g_iUser1; int g_iUser1 = 0;
int g_iUser2; int g_iUser2 = 0;
int g_iUser3; int g_iUser3 = 0;
// Scoreboard positions // Scoreboard positions
#define SBOARD_INDENT_X XRES(104) #define SBOARD_INDENT_X XRES(104)
@ -140,10 +143,12 @@ char *sTFClassSelection[] =
"civilian", "civilian",
}; };
#ifdef _TFC
int iBuildingCosts[] = int iBuildingCosts[] =
{ {
BUILD_COST_DISPENSER, BUILD_COST_DISPENSER,
BUILD_COST_SENTRYGUN BUILD_COST_SENTRYGUN,
BUILD_COST_TELEPORTER
}; };
// This maps class numbers to the Invalid Class bit. // This maps class numbers to the Invalid Class bit.
@ -163,6 +168,7 @@ int sTFValidClassInts[] =
TF_ILL_ENGINEER, TF_ILL_ENGINEER,
TF_ILL_RANDOMPC, TF_ILL_RANDOMPC,
}; };
#endif
// Get the name of TGA file, based on GameDir // Get the name of TGA file, based on GameDir
char* GetVGUITGAName(const char *pszName) 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 // Purpose: Tries to find a button that has a key bound to the input, and
// presses the button if found // presses the button if found
@ -434,7 +461,7 @@ CCommandMenu *TeamFortressViewport::CreateSubMenu( CommandButton *pButton, CComm
iDirection = pParentMenu->GetDirection(); 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); pMenu->setParent(this);
pButton->AddSubMenu( pMenu ); pButton->AddSubMenu( pMenu );
pButton->setFont( Scheme::sf_primary3 ); pButton->setFont( Scheme::sf_primary3 );
@ -445,13 +472,13 @@ CCommandMenu *TeamFortressViewport::CreateSubMenu( CommandButton *pButton, CComm
pButton->addInputSignal(pISignal); pButton->addInputSignal(pISignal);
// Put a > to show it's a submenu // 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->setParent(pButton);
pLabel->addInputSignal(pISignal); pLabel->addInputSignal(pISignal);
// Reposition // Reposition
pLabel->getPos( iXPos, iYPos ); 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 // Create the mouse off signal for the Label too
if (!pButton->m_bNoHighlight) 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_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_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_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, YRES(32), true, XRES( 200 ), BUTTON_SIZE_Y / 2, ScreenWidth - ( XRES ( 200 ) + 15 ) ); // 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(); CreateServerBrowser();
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -636,7 +680,7 @@ void TeamFortressViewport::Initialize( void )
strcpy(m_sTeamNames[i], ""); 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; class CException;
@ -669,8 +713,10 @@ int TeamFortressViewport::CreateCommandMenu( char * menuFile, int direction, int
return newIndex; return newIndex;
} }
#ifdef _WIN32
try try
{ {
#endif
// First, read in the localisation strings // First, read in the localisation strings
// Detpack strings // Detpack strings
@ -749,6 +795,7 @@ try
else else
{ {
// See if it's a Class // See if it's a Class
#ifdef _TFC
for (int i = 1; i <= PC_ENGINEER; i++) for (int i = 1; i <= PC_ENGINEER; i++)
{ {
if ( !strcmp(token, sTFClasses[i]) ) if ( !strcmp(token, sTFClasses[i]) )
@ -761,6 +808,7 @@ try
break; break;
} }
} }
#endif
} }
// Get the button bound key // Get the button bound key
@ -875,6 +923,7 @@ try
pfile = gEngfuncs.COM_ParseFile(pfile, token); pfile = gEngfuncs.COM_ParseFile(pfile, token);
} }
#ifdef _WIN32
} }
catch( CException *e ) catch( CException *e )
{ {
@ -884,6 +933,7 @@ catch( CException *e )
m_iInitialized = false; m_iInitialized = false;
return newIndex; return newIndex;
} }
#endif
SetCurrentMenu( NULL ); SetCurrentMenu( NULL );
SetCurrentCommandMenu( NULL ); SetCurrentCommandMenu( NULL );
@ -906,6 +956,7 @@ CCommandMenu *TeamFortressViewport::CreateDisguiseSubmenu( CommandButton *pButto
m_iNumMenus++; m_iNumMenus++;
// create the class choice buttons // create the class choice buttons
#ifdef _TFC
for ( int i = PC_SCOUT; i <= PC_ENGINEER; i++ ) 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 ); 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 ); pMenu->AddButton( pDisguiseButton );
} }
#endif
return pMenu; return pMenu;
} }
@ -973,6 +1025,7 @@ CommandButton *TeamFortressViewport::CreateCustomButton( char *pButtonText, char
m_pCommandMenus[m_iNumMenus] = pMenu; m_pCommandMenus[m_iNumMenus] = pMenu;
m_iNumMenus++; m_iNumMenus++;
#ifdef _TFC
for (int i = PC_SCOUT; i <= PC_RANDOM; i++ ) for (int i = PC_SCOUT; i <= PC_RANDOM; i++ )
{ {
char sz[256]; char sz[256];
@ -985,7 +1038,9 @@ CommandButton *TeamFortressViewport::CreateCustomButton( char *pButtonText, char
pClassButton->addActionSignal(new CMenuHandler_StringCommandClassSelect(sz)); pClassButton->addActionSignal(new CMenuHandler_StringCommandClassSelect(sz));
pMenu->AddButton( pClassButton ); pMenu->AddButton( pClassButton );
} }
#endif
} }
#ifdef _TFC
// Map Briefing // Map Briefing
else if ( !strcmp( pButtonName, "!MAPBRIEFING" ) ) 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 // Create an input signal that'll popup the current menu
pButton->addInputSignal( new CMenuHandler_PopupSubMenuInput(pButton, m_pCurrentCommandMenu) ); 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 // Stop building
else if ( !strcmp( pButtonName, "!BUILDSTOP" ) ) 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 // Create an input signal that'll popup the current menu
pButton->addInputSignal( new CMenuHandler_PopupSubMenuInput(pButton, m_pCurrentCommandMenu) ); pButton->addInputSignal( new CMenuHandler_PopupSubMenuInput(pButton, m_pCurrentCommandMenu) );
} }
#endif
return pButton; return pButton;
} }
@ -1281,6 +1379,12 @@ void TeamFortressViewport::HideCommandMenu()
m_pCommandMenus[m_SpectatorCameraMenu]->ClearButtonsOfArmedState(); m_pCommandMenus[m_SpectatorCameraMenu]->ClearButtonsOfArmedState();
} }
if ( m_pCommandMenus[m_PlayerMenu] )
{
m_pCommandMenus[m_PlayerMenu]->ClearButtonsOfArmedState();
}
m_flMenuOpenTime = 0.0f; m_flMenuOpenTime = 0.0f;
SetCurrentCommandMenu( NULL ); SetCurrentCommandMenu( NULL );
UpdateCursorState(); UpdateCursorState();
@ -1341,6 +1445,7 @@ void TeamFortressViewport::InputPlayerSpecial( void )
if (!m_iInitialized) if (!m_iInitialized)
return; return;
#ifdef _TFC
if ( g_iPlayerClass == PC_ENGINEER || g_iPlayerClass == PC_SPY ) if ( g_iPlayerClass == PC_ENGINEER || g_iPlayerClass == PC_SPY )
{ {
ShowCommandMenu( gViewPort->m_StandardMenu ); ShowCommandMenu( gViewPort->m_StandardMenu );
@ -1351,9 +1456,10 @@ void TeamFortressViewport::InputPlayerSpecial( void )
} }
} }
else else
#endif
{ {
// if it's any other class, just send the command down to the server // 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) 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]->RecalculateVisibles( 0, false );
m_pCommandMenus[menuIndex]->RecalculatePositions( 0 ); 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 COM_FileBase ( const char *in, char *out);
void TeamFortressViewport::UpdateSpectatorPanel() void TeamFortressViewport::UpdateSpectatorPanel()
@ -1392,6 +1548,7 @@ void TeamFortressViewport::UpdateSpectatorPanel()
char helpString2[128]; char helpString2[128];
char tempString[128]; char tempString[128];
char * name; char * name;
char *pBottomText = NULL;
int player = 0; int player = 0;
// check if spectator combinations are still valid // check if spectator combinations are still valid
@ -1429,7 +1586,13 @@ void TeamFortressViewport::UpdateSpectatorPanel()
// create player & health string // create player & health string
if ( player && name ) 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 // in first person mode colorize player names
@ -1442,10 +1605,12 @@ void TeamFortressViewport::UpdateSpectatorPanel()
// set team color, a bit transparent // set team color, a bit transparent
m_pSpectatorPanel->m_BottomMainLabel->setFgColor(r,g,b,0); m_pSpectatorPanel->m_BottomMainLabel->setFgColor(r,g,b,0);
m_pSpectatorPanel->m_BottomMainButton->setFgColor(r,g,b,0);
} }
else else
{ // restore GUI color { // restore GUI color
m_pSpectatorPanel->m_BottomMainLabel->setFgColor( 143, 143, 54, 0 ); 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 // add sting auto if we are in auto directed mode
@ -1456,7 +1621,8 @@ void TeamFortressViewport::UpdateSpectatorPanel()
strcpy( helpString2, tempString ); 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 // 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(); m_pCurrentMenu->Open();
} }
else
{
gEngfuncs.pfnClientCmd( "closemenus;" );
}
} }
//================================================================ //================================================================
@ -1557,7 +1727,7 @@ CMenuPanel* TeamFortressViewport::CreateTextWindow( int iTextToShow )
char sz[256]; char sz[256];
char *cText; char *cText;
char *pfile = NULL; char *pfile = NULL;
static const int MAX_TITLE_LENGTH = 32; static const int MAX_TITLE_LENGTH = 64;
char cTitle[MAX_TITLE_LENGTH]; char cTitle[MAX_TITLE_LENGTH];
if ( iTextToShow == SHOW_MOTD ) if ( iTextToShow == SHOW_MOTD )
@ -1565,8 +1735,8 @@ CMenuPanel* TeamFortressViewport::CreateTextWindow( int iTextToShow )
if (!m_szServerName || !m_szServerName[0]) if (!m_szServerName || !m_szServerName[0])
strcpy( cTitle, "Half-Life" ); strcpy( cTitle, "Half-Life" );
else else
strncpy( cTitle, m_szServerName, MAX_TITLE_LENGTH ); strncpy( cTitle, m_szServerName, sizeof(cTitle) );
cTitle[MAX_TITLE_LENGTH-1] = 0; cTitle[sizeof(cTitle)-1] = 0;
cText = m_szMOTD; cText = m_szMOTD;
} }
else if ( iTextToShow == SHOW_MAPBRIEFING ) else if ( iTextToShow == SHOW_MAPBRIEFING )
@ -1615,6 +1785,7 @@ CMenuPanel* TeamFortressViewport::CreateTextWindow( int iTextToShow )
strncpy( cTitle, m_sMapName, MAX_TITLE_LENGTH ); strncpy( cTitle, m_sMapName, MAX_TITLE_LENGTH );
cTitle[MAX_TITLE_LENGTH-1] = 0; cTitle[MAX_TITLE_LENGTH-1] = 0;
} }
#ifdef _TFC
else if ( iTextToShow == SHOW_CLASSDESC ) else if ( iTextToShow == SHOW_CLASSDESC )
{ {
switch ( g_iPlayerClass ) switch ( g_iPlayerClass )
@ -1657,6 +1828,7 @@ CMenuPanel* TeamFortressViewport::CreateTextWindow( int iTextToShow )
cText = pfile; cText = pfile;
} }
} }
#endif
else if ( iTextToShow == SHOW_SPECHELP ) else if ( iTextToShow == SHOW_SPECHELP )
{ {
CHudTextMessage::LocaliseTextString( "#Spec_Help_Title", cTitle, MAX_TITLE_LENGTH ); 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() ) if ( m_pSpectatorPanel->m_menuVisible || m_pCurrentMenu || m_pTeamMenu->isVisible() || m_pServerBrowser->isVisible() || GetClientVoiceMgr()->IsInSquelchMode() )
{ {
g_iVisibleMouse = true; 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; return;
} }
else if ( m_pCurrentCommandMenu ) else if ( m_pCurrentCommandMenu )
@ -1898,7 +2070,7 @@ void TeamFortressViewport::UpdateCursorState()
if ( gHUD.m_pCvarStealMouse->value != 0.0f ) if ( gHUD.m_pCvarStealMouse->value != 0.0f )
{ {
g_iVisibleMouse = true; 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; return;
} }
} }
@ -1910,7 +2082,7 @@ void TeamFortressViewport::UpdateCursorState()
} }
g_iVisibleMouse = false; 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() void TeamFortressViewport::UpdateHighlights()
@ -1923,7 +2095,7 @@ void TeamFortressViewport::GetAllPlayersInfo( void )
{ {
for ( int i = 1; i < MAX_PLAYERS; i++ ) for ( int i = 1; i < MAX_PLAYERS; i++ )
{ {
GetPlayerInfo( i, &g_PlayerInfoList[i] ); gEngfuncs.pfnGetPlayerInfo( i, &g_PlayerInfoList[i] );
if ( g_PlayerInfoList[i].thisplayer ) if ( g_PlayerInfoList[i].thisplayer )
m_pScoreBoard->m_iPlayerNum = i; // !!!HACK: this should be initialized elsewhere... maybe gotten from the engine 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() void TeamFortressViewport::paintBackground()
{ {
int wide, tall;
getParent()->getSize( wide, tall );
setSize( wide, tall );
if (m_pScoreBoard) if (m_pScoreBoard)
{ {
int x, y; int x, y;
@ -2229,7 +2404,7 @@ int TeamFortressViewport::MsgFunc_BuildSt( const char *pszName, int iSize, void
{ {
BEGIN_READ( pbuf, iSize ); BEGIN_READ( pbuf, iSize );
m_iBuildState = READ_BYTE(); m_iBuildState = READ_SHORT();
// Force the menu to update // Force the menu to update
UpdateCommandMenu( m_StandardMenu ); UpdateCommandMenu( m_StandardMenu );
@ -2250,7 +2425,8 @@ int TeamFortressViewport::MsgFunc_ServerName( const char *pszName, int iSize, vo
{ {
BEGIN_READ( pbuf, iSize ); 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; return 1;
} }
@ -2293,7 +2469,8 @@ int TeamFortressViewport::MsgFunc_TeamScore( const char *pszName, int iSize, voi
char *TeamName = READ_STRING(); char *TeamName = READ_STRING();
// find the team matching the name // 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 ) ) if ( !stricmp( TeamName, g_TeamInfo[i].name ) )
break; break;
@ -2367,3 +2544,101 @@ int TeamFortressViewport::MsgFunc_AllowSpec( const char *pszName, int iSize, voi
return 1; 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 #ifndef TEAMFORTRESSVIEWPORT_H
#define TEAMFORTRESSVIEWPORT_H #define TEAMFORTRESSVIEWPORT_H
@ -32,8 +26,21 @@
#include "vgui_SchemeManager.h" #include "vgui_SchemeManager.h"
#define TF_DEFS_ONLY #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; using namespace vgui;
class Cursor; class Cursor;
@ -50,6 +57,7 @@ class DragNDropPanel;
class CTransparentPanel; class CTransparentPanel;
class CClassMenuPanel; class CClassMenuPanel;
class CTeamMenuPanel; class CTeamMenuPanel;
class TeamFortressViewport;
char* GetVGUITGAName(const char *pszName); char* GetVGUITGAName(const char *pszName);
BitmapTGA *LoadTGAForRes(const char* pImageName); BitmapTGA *LoadTGAForRes(const char* pImageName);
@ -59,8 +67,8 @@ extern int sTFValidClassInts[];
extern char *sLocalisedClasses[]; extern char *sLocalisedClasses[];
extern int iTeamColors[5][3]; extern int iTeamColors[5][3];
extern int iNumberOfTeamColors; extern int iNumberOfTeamColors;
extern TeamFortressViewport *gViewPort;
#define MAX_SERVERNAME_LENGTH 32
// Command Menu positions // Command Menu positions
#define MAX_MENUS 80 #define MAX_MENUS 80
@ -74,7 +82,7 @@ extern int iNumberOfTeamColors;
#define CMENU_TOP (BUTTON_SIZE_Y * 4) #define CMENU_TOP (BUTTON_SIZE_Y * 4)
#define MAX_TEAMNAME_SIZE 64 //#define MAX_TEAMNAME_SIZE 64
#define MAX_BUTTON_SIZE 32 #define MAX_BUTTON_SIZE 32
// Map Briefing Window // Map Briefing Window
@ -377,6 +385,7 @@ public:
m_iDirection = 0; m_iDirection = 0;
} }
CCommandMenu( CCommandMenu *pParentMenu, int direction, int x,int y,int wide,int tall ) : Panel(x,y,wide,tall) CCommandMenu( CCommandMenu *pParentMenu, int direction, int x,int y,int wide,int tall ) : Panel(x,y,wide,tall)
{ {
m_pParentMenu = pParentMenu; m_pParentMenu = pParentMenu;
@ -402,12 +411,81 @@ public:
void ClearButtonsOfArmedState( void ); void ClearButtonsOfArmedState( void );
void RemoveAllButtons(void);
bool KeyInput( int keyNum ); bool KeyInput( int keyNum );
virtual void paintBackground(); 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 class TeamFortressViewport : public Panel
{ {
@ -467,6 +545,10 @@ private:
char m_sDetpackStrings[3][MAX_BUTTON_SIZE]; char m_sDetpackStrings[3][MAX_BUTTON_SIZE];
char m_sMapName[64]; char m_sMapName[64];
// helper function to update the player menu entries
void UpdatePlayerMenu(int menuIndex);
public: public:
TeamFortressViewport(int x,int y,int wide,int tall); TeamFortressViewport(int x,int y,int wide,int tall);
void Initialize( void ); void Initialize( void );
@ -535,6 +617,8 @@ public:
int MsgFunc_TeamInfo( const char *pszName, int iSize, void *pbuf ); int MsgFunc_TeamInfo( const char *pszName, int iSize, void *pbuf );
int MsgFunc_Spectator( 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_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 // Input
bool SlotInput( int iSlot ); bool SlotInput( int iSlot );
@ -553,6 +637,7 @@ public:
int m_StandardMenu; // indexs in m_pCommandMenus int m_StandardMenu; // indexs in m_pCommandMenus
int m_SpectatorOptionsMenu; int m_SpectatorOptionsMenu;
int m_SpectatorCameraMenu; int m_SpectatorCameraMenu;
int m_PlayerMenu; // a list of current player
CClassMenuPanel *m_pClassMenu; CClassMenuPanel *m_pClassMenu;
ScorePanel *m_pScoreBoard; ScorePanel *m_pScoreBoard;
SpectatorPanel * m_pSpectatorPanel; SpectatorPanel * m_pSpectatorPanel;
@ -751,11 +836,37 @@ public:
else else
m_cvar->value = 1.0f; m_cvar->value = 1.0f;
// hide the menu
gViewPort->HideCommandMenu();
gViewPort->UpdateSpectatorPanel(); 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 class CDragNDropHandler : public InputSignal
{ {
private: private:
@ -922,12 +1033,13 @@ public:
virtual int IsNotValid() virtual int IsNotValid()
{ {
// Only visible for spies // Only visible for spies
#ifdef _TFC
if (g_iPlayerClass != PC_SPY) if (g_iPlayerClass != PC_SPY)
return true; return true;
#endif
if (m_iFeignState == gViewPort->GetIsFeigning()) if (m_iFeignState == gViewPort->GetIsFeigning())
return false; return false;
return true; return true;
} }
}; };
@ -967,9 +1079,11 @@ public:
virtual int IsNotValid() virtual int IsNotValid()
{ {
#ifdef _TFC
// Only visible for spies // Only visible for spies
if ( g_iPlayerClass != PC_SPY ) if ( g_iPlayerClass != PC_SPY )
return true; return true;
#endif
// if it's not tied to a specific team, then always show (for spies) // if it's not tied to a specific team, then always show (for spies)
if ( !m_iValidTeamsBits ) if ( !m_iValidTeamsBits )
@ -979,7 +1093,6 @@ public:
int iTmp = 1 << (gViewPort->GetNumberOfTeams() - 1); int iTmp = 1 << (gViewPort->GetNumberOfTeams() - 1);
if ( m_iValidTeamsBits & iTmp ) if ( m_iValidTeamsBits & iTmp )
return false; return false;
return true; return true;
} }
}; };
@ -996,9 +1109,11 @@ public:
virtual int IsNotValid() virtual int IsNotValid()
{ {
#ifdef _TFC
// Only visible for demomen // Only visible for demomen
if (g_iPlayerClass != PC_DEMOMAN) if (g_iPlayerClass != PC_DEMOMAN)
return true; return true;
#endif
if (m_iDetpackState == gViewPort->GetIsSettingDetpack()) if (m_iDetpackState == gViewPort->GetIsSettingDetpack())
return false; return false;
@ -1008,10 +1123,10 @@ public:
}; };
extern int iBuildingCosts[]; 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_BUILDING (1<<1)
#define BUILDSTATE_BASE (1<<2) #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 class BuildButton : public CommandButton
{ {
@ -1024,6 +1139,8 @@ public:
{ {
DISPENSER = 0, DISPENSER = 0,
SENTRYGUN = 1, 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) 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() virtual int IsNotValid()
{ {
#ifdef _TFC
// Only visible for engineers // Only visible for engineers
if (g_iPlayerClass != PC_ENGINEER) if (g_iPlayerClass != PC_ENGINEER)
return true; return true;
@ -1055,7 +1173,7 @@ public:
if (m_iBuildState & BUILDSTATE_BASE) if (m_iBuildState & BUILDSTATE_BASE)
{ {
// Only appear if we've got enough metal to build something, or something already built // 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 false;
return true; return true;
@ -1068,6 +1186,10 @@ public:
return true; return true;
if ( m_iBuildData == BuildButton::SENTRYGUN && !(gViewPort->GetBuildState() & BS_HAS_SENTRYGUN) ) if ( m_iBuildData == BuildButton::SENTRYGUN && !(gViewPort->GetBuildState() & BS_HAS_SENTRYGUN) )
return true; 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 // Can build something
@ -1078,10 +1200,14 @@ public:
return false; return false;
if ( m_iBuildData == BuildButton::SENTRYGUN && (gViewPort->GetBuildState() & BS_CANB_SENTRYGUN) ) if ( m_iBuildData == BuildButton::SENTRYGUN && (gViewPort->GetBuildState() & BS_CANB_SENTRYGUN) )
return false; 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; return true;
} }
#endif
return false; return false;
} }
}; };
@ -1132,29 +1258,6 @@ public:
return CommandButton::IsNotValid(); 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 ); pSchemes->getBgColor( hTitleScheme, r, g, b, a );
pLabel->setBgColor( r, g, b, a ); pLabel->setBgColor( r, g, b, a );
pLabel->setContentAlignment( vgui::Label::a_west ); 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 // Create the Info Window
m_pTeamWindow = new CTransparentPanel( 255, TEAMMENU_WINDOW_X, TEAMMENU_WINDOW_Y, TEAMMENU_WINDOW_SIZE_X, TEAMMENU_WINDOW_SIZE_Y ); 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 ); strcpy( szTitle, ch+1 );
ch = strchr( szTitle, '.' ); ch = strchr( szTitle, '.' );
*ch = '\0'; *ch = '\0';
m_pMapTitle->setText( szTitle ); m_pMapTitle->setText( "%s", szTitle );
*ch = '.'; *ch = '.';
// Update the map briefing // Update the map briefing

View file

@ -1,10 +1,3 @@
//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================
// view/refresh setup functions // view/refresh setup functions
#include "hud.h" #include "hud.h"
@ -22,51 +15,45 @@
#include "pm_defs.h" #include "pm_defs.h"
#include "event_api.h" #include "event_api.h"
#include "pmtrace.h" #include "pmtrace.h"
#include "bench.h"
#include "screenfade.h" #include "screenfade.h"
#include "shake.h" #include "shake.h"
#include "hltv.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 #ifndef M_PI
#define M_PI 3.14159265358979323846 // matches value in gcc v2 math.h #define M_PI 3.14159265358979323846 // matches value in gcc v2 math.h
#endif #endif
extern "C"
{
int CL_IsThirdPerson( void ); int CL_IsThirdPerson( void );
void CL_CameraOffset( float *ofs ); 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); void PM_ParticleLine( float *start, float *end, int pcolor, float life, float vert);
int PM_GetVisEntInfo( int ent ); 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 InterpolateAngles( float * start, float * end, float * output, float frac );
void NormalizeAngles( float * angles ); 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 AngleBetweenVectors( const float * v1, const float * v2 );
float vJumpOrigin[3]; float vJumpOrigin[3];
float vJumpAngles[3]; float vJumpAngles[3];
}
void V_DropPunchAngle ( float frametime, float *ev_punchangle ); void V_DropPunchAngle ( float frametime, float *ev_punchangle );
void VectorAngles( const float *forward, float *angles ); void VectorAngles( const float *forward, float *angles );
#include "r_studioint.h" #include "r_studioint.h"
#include "com_model.h" #include "com_model.h"
#include "kbutton.h"
extern engine_studio_api_t IEngineStudio; 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, 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 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 // don't count small mouse motion
if (pd.nodrift) if ( pd.nodrift)
{ {
if ( fabs( pparams->cmd->forwardmove ) < cl_forwardspeed->value ) if ( v_centermove->value > 0 && !(in_mlook.state & 1) )
pd.driftmove = 0; {
else // this is for lazy players. if they stopped, looked around and then continued
pd.driftmove += pparams->frametime; // to move the view will be centered automatically if they move more than
// v_centermove units.
if ( pd.driftmove > v_centermove->value)
{ if ( fabs( pparams->cmd->forwardmove ) < cl_forwardspeed->value )
V_StartPitchDrift (); 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]; delta = pparams->idealpitch - pparams->cl_viewangles[PITCH];
@ -326,7 +325,8 @@ void V_DriftPitch ( struct ref_params_s *pparams )
} }
move = pparams->frametime * pd.pitchvel; 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) 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; pparams->viewangles[YAW] += v_idlescale * sin(pparams->time*v_iyaw_cycle.value) * v_iyaw_level.value;
} }
/* /*
============== ==============
V_CalcViewRoll V_CalcViewRoll
@ -1388,6 +1388,26 @@ int V_FindViewModelByWeaponModel(int weaponindex)
{ {
static char * modelmap[][2] = { 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_crossbow.mdl", "models/v_crossbow.mdl" },
{ "models/p_crowbar.mdl", "models/v_crowbar.mdl" }, { "models/p_crowbar.mdl", "models/v_crowbar.mdl" },
{ "models/p_egon.mdl", "models/v_egon.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 ) // 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() ) if ( gEngfuncs.IsSpectateOnly() )
#endif
{ {
V_GetInEyePos( g_iUser2, pparams->simorg, pparams->cl_viewangles ); 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); case OBS_ROAMING : VectorCopy (v_cl_angles, v_angles);
VectorCopy (v_sim_org, v_origin); VectorCopy (v_sim_org, v_origin);
// override values if director is active
gHUD.m_Spectator.GetDirectorCamera(v_origin, v_angles);
break; break;
case OBS_IN_EYE : V_CalcNormalRefdef ( pparams ); 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 // intermission / finale rendering
if ( pparams->intermission ) 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 #pragma once
#endif #endif
#ifdef __cplusplus
extern "C" {
#endif
typedef struct con_nprint_s typedef struct con_nprint_s
{ {
int index; // Row # int index; // Row #
@ -27,5 +31,8 @@ typedef struct con_nprint_s
void Con_NPrintf( int idx, char *fmt, ... ); void Con_NPrintf( int idx, char *fmt, ... );
void Con_NXPrintf( struct con_nprint_s *info, char *fmt, ... ); void Con_NXPrintf( struct con_nprint_s *info, char *fmt, ... );
#ifdef __cplusplus
}
#endif
#endif #endif

View file

@ -109,6 +109,10 @@
#define EF_NOINTERP 32 // don't interpolate the next frame #define EF_NOINTERP 32 // don't interpolate the next frame
#define EF_LIGHT 64 // rocket flare glow sprite #define EF_LIGHT 64 // rocket flare glow sprite
#define EF_NODRAW 128 // don't draw entity #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 // entity flags
#define EFLAG_SLERP 1 // do studio interpolation of this entity #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_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_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_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) #define TE_PLAYERATTACHMENT 124 // attaches a TENT to a player (this is a high-priority tent)
// byte (entity index of player) // byte (entity index of player)
@ -592,7 +597,7 @@
#define CONTENTS_TRANSLUCENT -15 #define CONTENTS_TRANSLUCENT -15
*/ */
#define CONTENTS_LADDER -16 #define CONTENTS_LADDER -16
#define CONTENT_FLYFIELD -17 #define CONTENT_FLYFIELD -17
#define CONTENT_GRAVITY_FLYFIELD -18 #define CONTENT_GRAVITY_FLYFIELD -18
@ -615,6 +620,7 @@
#define CHAN_STATIC 6 // allocate channel from the static area #define CHAN_STATIC 6 // allocate channel from the static area
#define CHAN_NETWORKVOICE_BASE 7 // voice data coming across the network #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_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 // attenuation values
#define ATTN_NONE 0 #define ATTN_NONE 0
@ -706,11 +712,12 @@ enum
kRenderFxExplode, // Scale up really big! kRenderFxExplode, // Scale up really big!
kRenderFxGlowShell, // Glowing Shell kRenderFxGlowShell, // Glowing Shell
kRenderFxClampMinScale, // Keep this sprite from getting very small (SPRITES only!) 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 unsigned int func_t;
typedef int string_t; typedef unsigned int string_t;
typedef unsigned char byte; typedef unsigned char byte;
typedef unsigned short word; typedef unsigned short word;

View file

@ -19,6 +19,8 @@
#pragma once #pragma once
#endif #endif
#include "archtypes.h" // DAL
// MD5 Hash // MD5 Hash
typedef struct typedef struct
{ {
@ -28,13 +30,24 @@ typedef struct
} MD5Context_t; } 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); void CRC32_Init(CRC32_t *pulCRC);
CRC32_t CRC32_Final(CRC32_t pulCRC); CRC32_t CRC32_Final(CRC32_t pulCRC);
void CRC32_ProcessBuffer(CRC32_t *pulCRC, void *p, int len); void CRC32_ProcessBuffer(CRC32_t *pulCRC, void *p, int len);
void CRC32_ProcessByte(CRC32_t *pulCRC, unsigned char ch); void CRC32_ProcessByte(CRC32_t *pulCRC, unsigned char ch);
int CRC_File(CRC32_t *crcvalue, char *pszFileName); int CRC_File(CRC32_t *crcvalue, char *pszFileName);
#ifdef __cplusplus
}
#endif
unsigned char COM_BlockSequenceCRCByte (unsigned char *base, int length, int sequence); unsigned char COM_BlockSequenceCRCByte (unsigned char *base, int length, int sequence);
void MD5Init(MD5Context_t *context); 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_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_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_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 typedef struct cvar_s
{ {

View file

@ -187,7 +187,7 @@ typedef struct local_state_s
{ {
entity_state_t playerstate; entity_state_t playerstate;
clientdata_t client; clientdata_t client;
weapon_data_t weapondata[ 32 ]; weapon_data_t weapondata[ 64 ];
} local_state_t; } local_state_t;
#endif // !ENTITY_STATEH #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 // hltv.h
// all shared consts between server, clients and proxy // all shared consts between server, clients and proxy
@ -15,31 +8,34 @@
#define TYPE_PROXY 1 // client is another proxy #define TYPE_PROXY 1 // client is another proxy
#define TYPE_COMMENTATOR 3 // client is a commentator #define TYPE_COMMENTATOR 3 // client is a commentator
#define TYPE_DEMO 4 // client is a demo file #define TYPE_DEMO 4 // client is a demo file
// sub commands of svc_hltv: // sub commands of svc_hltv:
#define HLTV_ACTIVE 0 // tells client that he's an spectator and will get director commands #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_STATUS 1 // send status infos about proxy
#define HLTV_LISTEN 2 // tell client to listen to a multicast stream #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_NONE 0 // NULL director command
#define DRC_CMD_START 1 // start director mode #define DRC_CMD_START 1 // start director mode
#define DRC_CMD_EVENT 2 // informs about director command #define DRC_CMD_EVENT 2 // informs about director command
#define DRC_CMD_MODE 3 // switches camera modes #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_TIMESCALE 5 // sets time scale
#define DRC_CMD_MESSAGE 6 // send HUD centerprint #define DRC_CMD_MESSAGE 6 // send HUD centerprint
#define DRC_CMD_SOUND 7 // plays a particular sound #define DRC_CMD_SOUND 7 // plays a particular sound
#define DRC_CMD_STATUS 8 // status info about broadcast #define DRC_CMD_STATUS 8 // HLTV broadcast status
#define DRC_CMD_BANNER 9 // banner file name for HLTV gui #define DRC_CMD_BANNER 9 // set GUI banner
#define DRC_CMD_FADE 10 // send screen fade command #define DRC_CMD_STUFFTEXT 10 // like the normal svc_stufftext but as director command
#define DRC_CMD_SHAKE 11 // send screen shake command #define DRC_CMD_CHASE 11 // chase a certain player
#define DRC_CMD_STUFFTEXT 12 // like the normal svc_stufftext but as director command #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
// DRC_CMD_EVENT event flags
// HLTV_EVENT event flags
#define DRC_FLAG_PRIO_MASK 0x0F // priorities between 0 and 15 (15 most important) #define DRC_FLAG_PRIO_MASK 0x0F // priorities between 0 and 15 (15 most important)
#define DRC_FLAG_SIDE (1<<4) // #define DRC_FLAG_SIDE (1<<4) //
#define DRC_FLAG_DRAMATIC (1<<5) // is a dramatic scene #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 DRC_FLAG_NO_RANDOM (1<<10) // don't randomize event data
#define MAX_DIRECTOR_CMD_PARAMETERS 4 // DRC_CMD_WAYPOINT flags
#define MAX_DIRECTOR_CMD_STRING 128 #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 #endif // HLTV_H

View file

@ -15,7 +15,8 @@
typedef enum typedef enum
{ {
MicrophoneVolume=0, // values 0-1. 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; } VoiceTweakControl;
@ -29,6 +30,8 @@ typedef struct IVoiceTweak_s
// Get/set control values. // Get/set control values.
void (*SetControlFloat)(VoiceTweakControl iControl, float value); void (*SetControlFloat)(VoiceTweakControl iControl, float value);
float (*GetControlFloat)(VoiceTweakControl iControl); float (*GetControlFloat)(VoiceTweakControl iControl);
int (*GetSpeakingVolume)();
} IVoiceTweak; } IVoiceTweak;

View file

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

View file

@ -1,4 +1,4 @@
//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ //========= Copyright © 1996-2001, Valve LLC, All rights reserved. ============
// //
// Purpose: // Purpose:
// //
@ -10,6 +10,7 @@
#ifndef _WIN32 #ifndef _WIN32
#include <unistd.h> #include <unistd.h>
#include <sys/types.h>
#endif //!_WIN32 #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 // Font stuff
#define NUM_GLYPHS 256 #define NUM_GLYPHS 256
// does not exist: // #include "basetypes.h"
typedef struct typedef struct
{ {
@ -34,7 +35,7 @@ typedef struct qfont_s
int rowcount; int rowcount;
int rowheight; int rowheight;
charinfo fontinfo[ NUM_GLYPHS ]; charinfo fontinfo[ NUM_GLYPHS ];
byte data[4]; unsigned char data[4];
} qfont_t; } qfont_t;
#endif // qfont.h #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_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 ) #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 typedef struct tempent_s
{ {
int flags; int flags;
@ -99,7 +98,7 @@ typedef struct tempent_s
int hitSound; int hitSound;
void ( *hitcallback ) ( struct tempent_s *ent, struct pmtrace_s *ptr ); void ( *hitcallback ) ( struct tempent_s *ent, struct pmtrace_s *ptr );
void ( *callback ) ( struct tempent_s *ent, float frametime, float currenttime ); void ( *callback ) ( struct tempent_s *ent, float frametime, float currenttime );
TEMPENTITY *next; struct tempent_s *next;
int priority; int priority;
short clientIndex; // if attached, this is the index of the client to stick to 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 // 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 ); void ( *R_GetPackedColor ) ( short *packed, short color );
short ( *R_LookupColor ) ( unsigned char r, unsigned char g, unsigned char b ); 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_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; 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 ) #if !defined( R_STUDIOINT_H )
#define R_STUDIOINT_H #define R_STUDIOINT_H
#if defined( _WIN32 ) #if defined( _WIN32 )
@ -101,6 +94,10 @@ typedef struct engine_studio_api_s
// Only called by hardware interface // Only called by hardware interface
void ( *GL_StudioDrawShadow ) ( void ); void ( *GL_StudioDrawShadow ) ( void );
void ( *GL_SetRenderMode ) ( int mode ); 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; } engine_studio_api_t;
typedef struct server_studio_api_s typedef struct server_studio_api_s
@ -131,17 +128,17 @@ extern r_studio_interface_t *pStudioAPI;
typedef struct sv_blending_interface_s typedef struct sv_blending_interface_s
{ {
int version; int version;
void ( *SV_StudioSetupBones )( struct model_s *pModel, void ( *SV_StudioSetupBones ) ( struct model_s *pModel,
float frame, float frame,
int sequence, int sequence,
const vec3_t angles, const vec3_t angles,
const vec3_t origin, const vec3_t origin,
const byte *pcontroller, const byte *pcontroller,
const byte *pblending, const byte *pblending,
int iBone, int iBone,
const edict_t *pEdict ); const edict_t *pEdict );
} sv_blending_interface_t; } 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 ); void ( *CullFace ) ( TRICULLSTYLE style );
int ( *SpriteTexture ) ( struct model_s *pSpriteModel, int frame ); int ( *SpriteTexture ) ( struct model_s *pSpriteModel, int frame );
int ( *WorldToScreen ) ( float *world, float *screen ); // Returns 1 if it's z clipped 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 ( *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; } 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 * This product contains software technology licensed from Id
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc. * 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 * This product contains software technology licensed from Id
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc. * 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 * This product contains software technology licensed from Id
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc. * Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
@ -14,6 +14,8 @@
****/ ****/
//========================================================= //=========================================================
//========================================================= //=========================================================
#include "archtypes.h" // DAL
#include "extdll.h" #include "extdll.h"
#include "util.h" #include "util.h"
#include "cbase.h" #include "cbase.h"
@ -211,7 +213,7 @@ void CFlockingFlyerFlock :: SpawnFlock( void )
pBoid->pev->frame = 0; pBoid->pev->frame = 0;
pBoid->pev->nextthink = gpGlobals->time + 0.2; pBoid->pev->nextthink = gpGlobals->time + 0.2;
pBoid->SetThink( CFlockingFlyer :: IdleThink ); pBoid->SetThink( &CFlockingFlyer :: IdleThink );
if ( pBoid != pLeader ) if ( pBoid != pLeader )
{ {
@ -229,7 +231,7 @@ void CFlockingFlyer :: Spawn( )
pev->frame = 0; pev->frame = 0;
pev->nextthink = gpGlobals->time + 0.1; 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) ); UTIL_SetSize( pev, Vector(0,0,0), Vector(0,0,0) );
pev->movetype = MOVETYPE_TOSS; pev->movetype = MOVETYPE_TOSS;
SetThink ( FallHack ); SetThink ( &CFlockingFlyer::FallHack );
pev->nextthink = gpGlobals->time + 0.1; 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 // see if there's a client in the same pvs as the monster
if ( !FNullEnt( FIND_CLIENT_IN_PVS( edict() ) ) ) if ( !FNullEnt( FIND_CLIENT_IN_PVS( edict() ) ) )
{ {
SetThink( Start ); SetThink( &CFlockingFlyer::Start );
pev->nextthink = gpGlobals->time + 0.1; pev->nextthink = gpGlobals->time + 0.1;
} }
} }
@ -380,11 +382,11 @@ void CFlockingFlyer :: Start( void )
if ( IsLeader() ) if ( IsLeader() )
{ {
SetThink( FlockLeaderThink ); SetThink( &CFlockingFlyer::FlockLeaderThink );
} }
else 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; pev->nextthink = gpGlobals->time;
} }
@ -673,7 +675,7 @@ void CFlockingFlyer :: FlockFollowerThink( void )
if ( IsLeader() || !InSquad() ) if ( IsLeader() || !InSquad() )
{ {
// the leader has been killed and this flyer suddenly finds himself the leader. // the leader has been killed and this flyer suddenly finds himself the leader.
SetThink ( FlockLeaderThink ); SetThink ( &CFlockingFlyer::FlockLeaderThink );
return; 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 * This product contains software technology licensed from Id
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc. * 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 * This product contains software technology licensed from Id
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc. * 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_SetSize(pev, Vector( -16, -16, 0), Vector(16, 16, 36));
UTIL_SetOrigin( pev, pev->origin ); UTIL_SetOrigin( pev, pev->origin );
SetTouch( TankTouch ); SetTouch( &CAirtank::TankTouch );
SetThink( TankThink ); SetThink( &CAirtank::TankThink );
pev->flags |= FL_MONSTER; pev->flags |= FL_MONSTER;
pev->takedamage = DAMAGE_YES; 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 * This product contains software technology licensed from Id
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc. * 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 * This product contains software technology licensed from Id
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc. * 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 ) float SetController( void *pmodel, entvars_t *pev, int iController, float flValue )
{ {
studiohdr_t *pstudiohdr; studiohdr_t *pstudiohdr;
int i;
pstudiohdr = (studiohdr_t *)pmodel; pstudiohdr = (studiohdr_t *)pmodel;
if (! pstudiohdr) 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); mstudiobonecontroller_t *pbonecontroller = (mstudiobonecontroller_t *)((byte *)pstudiohdr + pstudiohdr->bonecontrollerindex);
// find first controller that matches the index // 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) if (pbonecontroller->index == iController)
break; break;
@ -524,4 +525,4 @@ int GetBodygroup( void *pmodel, entvars_t *pev, int iGroup )
int iCurrent = (pev->body / pbodypart->base) % pbodypart->nummodels; int iCurrent = (pev->body / pbodypart->base) % pbodypart->nummodels;
return iCurrent; 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 * This product contains software technology licensed from Id
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc. * 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 * This product contains software technology licensed from Id
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc. * Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
@ -139,12 +139,12 @@ void CApache :: Spawn( void )
if (pev->spawnflags & SF_WAITFORTRIGGER) if (pev->spawnflags & SF_WAITFORTRIGGER)
{ {
SetUse( StartupUse ); SetUse( &CApache::StartupUse );
} }
else else
{ {
SetThink( HuntThink ); SetThink( &CApache::HuntThink );
SetTouch( FlyTouch ); SetTouch( &CApache::FlyTouch );
pev->nextthink = gpGlobals->time + 1.0; 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 ) void CApache::StartupUse( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value )
{ {
SetThink( HuntThink ); SetThink( &CApache::HuntThink );
SetTouch( FlyTouch ); SetTouch( &CApache::FlyTouch );
pev->nextthink = gpGlobals->time + 0.1; pev->nextthink = gpGlobals->time + 0.1;
SetUse( NULL ); SetUse( NULL );
} }
@ -200,8 +200,8 @@ void CApache :: Killed( entvars_t *pevAttacker, int iGib )
STOP_SOUND( ENT(pev), CHAN_STATIC, "apache/ap_rotor2.wav" ); STOP_SOUND( ENT(pev), CHAN_STATIC, "apache/ap_rotor2.wav" );
UTIL_SetSize( pev, Vector( -32, -32, -64), Vector( 32, 32, 0) ); UTIL_SetSize( pev, Vector( -32, -32, -64), Vector( 32, 32, 0) );
SetThink( DyingThink ); SetThink( &CApache::DyingThink );
SetTouch( CrashTouch ); SetTouch( &CApache::CrashTouch );
pev->nextthink = gpGlobals->time + 0.1; pev->nextthink = gpGlobals->time + 0.1;
pev->health = 0; pev->health = 0;
pev->takedamage = DAMAGE_NO; pev->takedamage = DAMAGE_NO;
@ -402,7 +402,7 @@ void CApache :: DyingThink( void )
WRITE_BYTE( BREAK_METAL ); WRITE_BYTE( BREAK_METAL );
MESSAGE_END(); MESSAGE_END();
SetThink( SUB_Remove ); SetThink( &CApache::SUB_Remove );
pev->nextthink = gpGlobals->time + 0.1; 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_SetSize(pev, Vector( 0, 0, 0), Vector(0, 0, 0));
UTIL_SetOrigin( pev, pev->origin ); UTIL_SetOrigin( pev, pev->origin );
SetThink( IgniteThink ); SetThink( &CApacheHVR::IgniteThink );
SetTouch( ExplodeTouch ); SetTouch( &CApacheHVR::ExplodeTouch );
UTIL_MakeAimVectors( pev->angles ); UTIL_MakeAimVectors( pev->angles );
m_vecForward = gpGlobals->v_forward; 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) MESSAGE_END(); // move PHS/PVS data sending into here (SEND_ALL, SEND_PVS, SEND_PHS)
// set to accelerate // set to accelerate
SetThink( AccelerateThink ); SetThink( &CApacheHVR::AccelerateThink );
pev->nextthink = gpGlobals->time + 0.1; 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 * This product contains software technology licensed from Id
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc. * Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
@ -124,7 +124,7 @@ void CBarnacle :: Spawn()
SetActivity ( ACT_IDLE ); SetActivity ( ACT_IDLE );
SetThink ( BarnacleThink ); SetThink ( &CBarnacle::BarnacleThink );
pev->nextthink = gpGlobals->time + 0.5; pev->nextthink = gpGlobals->time + 0.5;
UTIL_SetOrigin ( pev, pev->origin ); UTIL_SetOrigin ( pev, pev->origin );
@ -349,7 +349,7 @@ void CBarnacle :: Killed( entvars_t *pevAttacker, int iGib )
StudioFrameAdvance( 0.1 ); StudioFrameAdvance( 0.1 );
pev->nextthink = gpGlobals->time + 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 * This product contains software technology licensed from Id
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc. * 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; m_afCapability = bits_CAP_HEAR | bits_CAP_TURN_HEAD | bits_CAP_DOORS_GROUP;
MonsterInit(); 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 * This product contains software technology licensed from Id
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc. * 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 * This product contains software technology licensed from Id
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc. * 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->velocity = vecVelocity;
pSpit->pev->owner = pOwner; pSpit->pev->owner = pOwner;
pSpit->pev->scale = 2.5; pSpit->pev->scale = 2.5;
pSpit->SetThink ( Animate ); pSpit->SetThink ( &CBMortar::Animate );
pSpit->pev->nextthink = gpGlobals->time + 0.1; pSpit->pev->nextthink = gpGlobals->time + 0.1;
return pSpit; return pSpit;

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