Counter Strike : Global Offensive Source Code
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

3059 lines
88 KiB

  1. //===== Copyright (c) 1996-2005, Valve Corporation, All rights reserved. ======//
  2. //
  3. // Purpose:
  4. //
  5. // 4-23-98
  6. // JOHN: implementation of interface between client-side DLL and game engine.
  7. // The cdll shouldn't have to know anything about networking or file formats.
  8. // This file is Win32-dependant
  9. //
  10. //===========================================================================//
  11. #include "client_pch.h"
  12. #include "getintersectingsurfaces_struct.h"
  13. #include "gl_model_private.h"
  14. #include "surfinfo.h"
  15. #include "vstdlib/random.h"
  16. #include "cdll_int.h"
  17. #include "cmodel_engine.h"
  18. #include "tmessage.h"
  19. #include "console.h"
  20. #include "snd_audio_source.h"
  21. #include <vgui_controls/Controls.h>
  22. #include <vgui/IInput.h>
  23. #include "iengine.h"
  24. #include "keys.h"
  25. #include "con_nprint.h"
  26. #include "tier0/vprof.h"
  27. #include "sound.h"
  28. #include "gl_rmain.h"
  29. #include "client_class.h"
  30. #include "gl_rsurf.h"
  31. #include "server.h"
  32. #include "r_local.h"
  33. #include "lightcache.h"
  34. #include "gl_matsysiface.h"
  35. #include "inputsystem/iinputstacksystem.h"
  36. #include "materialsystem/imaterialsystemhardwareconfig.h"
  37. #include "materialsystem/materialsystem_config.h"
  38. #include "materialsystem/imaterial.h"
  39. #include "materialsystem/imaterialvar.h"
  40. #include "materialsystem/itexture.h"
  41. #include "istudiorender.h"
  42. #include "l_studio.h"
  43. #include "voice.h"
  44. #include "enginestats.h"
  45. #include "testscriptmgr.h"
  46. #include "r_areaportal.h"
  47. #include "host.h"
  48. #include "vox.h"
  49. #include "iprediction.h"
  50. #include "icliententitylist.h"
  51. #include "eiface.h"
  52. #include "engine/IClientLeafSystem.h"
  53. #include "dt_recv_eng.h"
  54. #include <vgui/IVGui.h>
  55. #include "sys_dll.h"
  56. #include "vphysics_interface.h"
  57. #include "materialsystem/imesh.h"
  58. #include "IOcclusionSystem.h"
  59. #include "filesystem_engine.h"
  60. #include "tier0/icommandline.h"
  61. #include "client_textmessage.h"
  62. #include "host_saverestore.h"
  63. #include "cl_main.h"
  64. #include "demo.h"
  65. #include "vgui_baseui_interface.h"
  66. #include "LocalNetworkBackdoor.h"
  67. #include "lightcache.h"
  68. #include "vgui/ISystem.h"
  69. #include "Steam.h"
  70. #include "ivideomode.h"
  71. #include "icolorcorrectiontools.h"
  72. #include "toolframework/itoolframework.h"
  73. #include "engine/view_sharedv1.h"
  74. #include "view.h"
  75. #include "game/client/iclientrendertargets.h"
  76. #include "tier2/tier2.h"
  77. #include "inputsystem/iinputsystem.h"
  78. #include "iachievementmgr.h"
  79. #include "profile.h"
  80. #include "singleplayersharedmemory.h"
  81. #include "cl_demo.h"
  82. #include "MapReslistGenerator.h"
  83. #include "iclientalphaproperty.h"
  84. #include "cl_steamauth.h"
  85. #include "enginebugreporter.h"
  86. #include "world.h"
  87. #include "staticpropmgr.h"
  88. #include "sv_uploadgamestats.h"
  89. #include "host_cmd.h"
  90. #include "ixboxsystem.h"
  91. #include "matchmaking/imatchframework.h"
  92. #include "appframework/ilaunchermgr.h"
  93. #include "paint.h"
  94. #include "igame.h"
  95. #include "sys_mainwind.h"
  96. #include "dbginput.h"
  97. #include "cl_broadcast.h"
  98. #if defined( _PS3 )
  99. #include "engine_helper_ps3.h"
  100. #endif
  101. // memdbgon must be the last include file in a .cpp file!!!
  102. #include "tier0/memdbgon.h"
  103. //-----------------------------------------------------------------------------
  104. // forward declarations
  105. //-----------------------------------------------------------------------------
  106. IMaterial* BrushModel_GetLightingAndMaterial( const Vector &start,
  107. const Vector &end, Vector &diffuseLightColor, Vector &baseColor );
  108. const char *Key_NameForBinding( const char *pBinding, int userId );
  109. void CL_GetBackgroundLevelName( char *pszBackgroundName, int bufSize, bool bMapName );
  110. CreateInterfaceFn g_ClientFactory = NULL;
  111. extern CGlobalVars g_ServerGlobalVariables;
  112. extern ConVar host_timescale;
  113. //-----------------------------------------------------------------------------
  114. // globals
  115. //-----------------------------------------------------------------------------
  116. CSysModule *g_ClientDLLModule = NULL; // also used by materialproxyfactory.cpp
  117. bool g_bClientGameDLLGreaterThanV13;
  118. void AddIntersectingLeafSurfaces( mleaf_t *pLeaf, GetIntersectingSurfaces_Struct *pStruct )
  119. {
  120. SurfaceHandle_t *pHandle = &host_state.worldbrush->marksurfaces[pLeaf->firstmarksurface];
  121. for ( int iSurf=0; iSurf < pLeaf->nummarksurfaces; iSurf++ )
  122. {
  123. SurfaceHandle_t surfID = pHandle[iSurf];
  124. ASSERT_SURF_VALID( surfID );
  125. if ( MSurf_Flags(surfID) & SURFDRAW_SKY )
  126. continue;
  127. // Make sure we haven't already processed this one.
  128. bool foundSurf = false;
  129. for(int iTest=0; iTest < pStruct->m_nSetInfos; iTest++)
  130. {
  131. if(pStruct->m_pInfos[iTest].m_pEngineData == (void *)surfID)
  132. {
  133. foundSurf = true;
  134. break;
  135. }
  136. }
  137. if ( foundSurf )
  138. continue;
  139. // Make sure there's output room.
  140. if(pStruct->m_nSetInfos >= pStruct->m_nMaxInfos)
  141. return;
  142. SurfInfo *pOut = &pStruct->m_pInfos[pStruct->m_nSetInfos];
  143. pOut->m_nVerts = 0;
  144. pOut->m_pEngineData = (void *)surfID;
  145. // Build vertex list and bounding box.
  146. Vector vMin( 1000000.0f, 1000000.0f, 1000000.0f);
  147. Vector vMax(-1000000.0f, -1000000.0f, -1000000.0f);
  148. for(int iVert=0; iVert < MSurf_VertCount( surfID ); iVert++)
  149. {
  150. int vertIndex = pStruct->m_pModel->brush.pShared->vertindices[MSurf_FirstVertIndex( surfID ) + iVert];
  151. pOut->m_Verts[pOut->m_nVerts] = pStruct->m_pModel->brush.pShared->vertexes[vertIndex].position;
  152. vMin = vMin.Min(pOut->m_Verts[pOut->m_nVerts]);
  153. vMax = vMax.Max(pOut->m_Verts[pOut->m_nVerts]);
  154. ++pOut->m_nVerts;
  155. if(pOut->m_nVerts >= MAX_SURFINFO_VERTS)
  156. break;
  157. }
  158. // See if the sphere intersects the box.
  159. int iDim=0;
  160. for(; iDim < 3; iDim++)
  161. {
  162. if(((*pStruct->m_pCenter)[iDim]+pStruct->m_Radius) < vMin[iDim] ||
  163. ((*pStruct->m_pCenter)[iDim]-pStruct->m_Radius) > vMax[iDim])
  164. {
  165. break;
  166. }
  167. }
  168. if(iDim == 3)
  169. {
  170. // (Couldn't reject the sphere in the loop above).
  171. pOut->m_Plane = MSurf_GetForwardFacingPlane( surfID );
  172. ++pStruct->m_nSetInfos;
  173. }
  174. }
  175. }
  176. void GetIntersectingSurfaces_R(
  177. GetIntersectingSurfaces_Struct *pStruct,
  178. mnode_t *pNode
  179. )
  180. {
  181. if(pStruct->m_nSetInfos >= pStruct->m_nMaxInfos)
  182. return;
  183. // Ok, this is a leaf. Check its surfaces.
  184. if(pNode->contents >= 0)
  185. {
  186. mleaf_t *pLeaf = (mleaf_t*)pNode;
  187. if(pStruct->m_bOnlyVisible && pStruct->m_pCenterPVS)
  188. {
  189. if(pLeaf->cluster < 0)
  190. return;
  191. if(!(pStruct->m_pCenterPVS[pLeaf->cluster>>3] & (1 << (pLeaf->cluster&7))))
  192. return;
  193. }
  194. // First, add tris from displacements.
  195. for ( int i = 0; i < pLeaf->dispCount; i++ )
  196. {
  197. IDispInfo *pDispInfo = MLeaf_Disaplcement( pLeaf, i );
  198. pDispInfo->GetIntersectingSurfaces( pStruct );
  199. }
  200. // Next, add brush tris.
  201. AddIntersectingLeafSurfaces( pLeaf, pStruct );
  202. return;
  203. }
  204. // Recurse.
  205. float dot;
  206. cplane_t *plane = pNode->plane;
  207. if ( plane->type < 3 )
  208. {
  209. dot = (*pStruct->m_pCenter)[plane->type] - plane->dist;
  210. }
  211. else
  212. {
  213. dot = pStruct->m_pCenter->Dot(plane->normal) - plane->dist;
  214. }
  215. // Recurse into child nodes.
  216. if(dot > -pStruct->m_Radius)
  217. GetIntersectingSurfaces_R(pStruct, pNode->children[SIDE_FRONT]);
  218. if(dot < pStruct->m_Radius)
  219. GetIntersectingSurfaces_R(pStruct, pNode->children[SIDE_BACK]);
  220. }
  221. //-----------------------------------------------------------------------------
  222. // slow routine to draw a physics model
  223. // NOTE: very slow code!!! just for debugging!
  224. //-----------------------------------------------------------------------------
  225. void DebugDrawPhysCollide( const CPhysCollide *pCollide, IMaterial *pMaterial, const matrix3x4_t& transform, const color32 &color, bool drawAxes )
  226. {
  227. if ( !pMaterial )
  228. {
  229. pMaterial = materials->FindMaterial("debug/debugwireframevertexcolor", TEXTURE_GROUP_OTHER);
  230. }
  231. CMatRenderContextPtr pRenderContext( materials );
  232. Vector *outVerts;
  233. int vertCount = physcollision->CreateDebugMesh( pCollide, &outVerts );
  234. if ( vertCount )
  235. {
  236. IMesh *pMesh = pRenderContext->GetDynamicMesh( true, NULL, NULL, pMaterial );
  237. CMeshBuilder meshBuilder;
  238. meshBuilder.Begin( pMesh, MATERIAL_TRIANGLES, vertCount/3 );
  239. for ( int j = 0; j < vertCount; j++ )
  240. {
  241. Vector out;
  242. VectorTransform( outVerts[j].Base(), transform, out.Base() );
  243. meshBuilder.Position3fv( out.Base() );
  244. meshBuilder.Color4ub( color.r, color.g, color.b, color.a );
  245. meshBuilder.TexCoord2f( 0, 0, 0 );
  246. meshBuilder.AdvanceVertex();
  247. }
  248. meshBuilder.End();
  249. pMesh->Draw();
  250. }
  251. physcollision->DestroyDebugMesh( vertCount, outVerts );
  252. // draw the axes
  253. if ( drawAxes )
  254. {
  255. Vector xaxis(10,0,0), yaxis(0,10,0), zaxis(0,0,10);
  256. Vector center;
  257. Vector out;
  258. MatrixGetColumn( transform, 3, center );
  259. IMesh *pMesh = pRenderContext->GetDynamicMesh( true, NULL, NULL, pMaterial );
  260. CMeshBuilder meshBuilder;
  261. meshBuilder.Begin( pMesh, MATERIAL_LINES, 3 );
  262. // X
  263. meshBuilder.Position3fv( center.Base() );
  264. meshBuilder.Color4ub( 255, 0, 0, 255 );
  265. meshBuilder.TexCoord2f( 0, 0, 0 );
  266. meshBuilder.AdvanceVertex();
  267. VectorTransform( xaxis.Base(), transform, out.Base() );
  268. meshBuilder.Position3fv( out.Base() );
  269. meshBuilder.Color4ub( 255, 0, 0, 255 );
  270. meshBuilder.TexCoord2f( 0, 0, 0 );
  271. meshBuilder.AdvanceVertex();
  272. // Y
  273. meshBuilder.Position3fv( center.Base() );
  274. meshBuilder.Color4ub( 0, 255, 0, 255 );
  275. meshBuilder.TexCoord2f( 0, 0, 0 );
  276. meshBuilder.AdvanceVertex();
  277. VectorTransform( yaxis.Base(), transform, out.Base() );
  278. meshBuilder.Position3fv( out.Base() );
  279. meshBuilder.Color4ub( 0, 255, 0, 255 );
  280. meshBuilder.TexCoord2f( 0, 0, 0 );
  281. meshBuilder.AdvanceVertex();
  282. // Z
  283. meshBuilder.Position3fv( center.Base() );
  284. meshBuilder.Color4ub( 0, 0, 255, 255 );
  285. meshBuilder.TexCoord2f( 0, 0, 0 );
  286. meshBuilder.AdvanceVertex();
  287. VectorTransform( zaxis.Base(), transform, out.Base() );
  288. meshBuilder.Position3fv( out.Base() );
  289. meshBuilder.Color4ub( 0, 0, 255, 255 );
  290. meshBuilder.TexCoord2f( 0, 0, 0 );
  291. meshBuilder.AdvanceVertex();
  292. meshBuilder.End();
  293. pMesh->Draw();
  294. }
  295. }
  296. //-----------------------------------------------------------------------------
  297. //
  298. // implementation of IVEngineHud
  299. //
  300. //-----------------------------------------------------------------------------
  301. // UNDONE: Move this to hud export code, subsume previous functions
  302. class CEngineClient : public IVEngineClient
  303. {
  304. public:
  305. CEngineClient();
  306. ~CEngineClient();
  307. int GetIntersectingSurfaces(
  308. const model_t *model,
  309. const Vector &vCenter,
  310. const float radius,
  311. const bool bOnlyVisible,
  312. SurfInfo *pInfos,
  313. const int nMaxInfos);
  314. Vector GetLightForPoint(const Vector &pos, bool bClamp);
  315. Vector GetLightForPointFast(const Vector &pos, bool bClamp);
  316. const char *ParseFile( const char *data, char *token, int maxlen );
  317. virtual bool CopyLocalFile( const char *source, const char *destination );
  318. void GetScreenSize( int& w, int &h );
  319. void ServerCmd( const char *szCmdString, bool bReliable );
  320. void ClientCmd( const char *szCmdString );
  321. void ClientCmd_Unrestricted( const char *szCmdString, bool fromConsoleOrKeybind = false );
  322. void ClientCmd_Unrestricted( const char *szCmdString, bool fromConsoleOrKeybind, int nUserSlot, bool bCheckValidSlot = true );
  323. void SetRestrictServerCommands( bool bRestrict );
  324. void SetRestrictClientCommands( bool bRestrict );
  325. bool GetPlayerInfo( int ent_num, player_info_t *pinfo );
  326. client_textmessage_t *TextMessageGet( const char *pName );
  327. bool Con_IsVisible( void );
  328. int GetLocalPlayer( void );
  329. float GetLastTimeStamp( void );
  330. virtual int GetLastAcknowledgedCommand( void );
  331. virtual int GetServerTick( void );
  332. const model_t *LoadModel( const char *pName, bool bProp );
  333. void UnloadModel( const model_t *model, bool bProp );
  334. CSentence *GetSentence( CAudioSource *pAudioSource );
  335. float GetSentenceLength( CAudioSource *pAudioSource );
  336. bool IsStreaming( CAudioSource *pAudioSource ) const;
  337. // FIXME, move entirely to client .dll
  338. void GetViewAngles( QAngle& va );
  339. void SetViewAngles( QAngle& va );
  340. int GetMaxClients( void );
  341. void Key_Event( ButtonCode_t key, int down );
  342. const char *Key_LookupBinding( const char *pBinding );
  343. const char *Key_BindingForKey( ButtonCode_t code );
  344. void Key_SetBinding( ButtonCode_t code, const char *pBinding );
  345. void StartKeyTrapMode( void );
  346. bool CheckDoneKeyTrapping( ButtonCode_t &key );
  347. bool IsInGame( void );
  348. bool IsConnected( void );
  349. bool IsDrawingLoadingImage( void );
  350. void HideLoadingPlaque( void );
  351. void Con_NPrintf( int pos, const char *fmt, ... );
  352. void Con_NXPrintf( const struct con_nprint_s *info, const char *fmt, ... );
  353. IMaterial *TraceLineMaterialAndLighting( const Vector &start, const Vector &end,
  354. Vector &diffuseLightColor, Vector &baseColor );
  355. int IsBoxVisible( const Vector& mins, const Vector& maxs );
  356. int IsBoxInViewCluster( const Vector& mins, const Vector& maxs );
  357. void Sound_ExtraUpdate( void );
  358. #if defined(_PS3)
  359. void Sound_ServerUpdateSoundsPS3( void );
  360. #endif
  361. bool CullBox ( const Vector& mins, const Vector& maxs );
  362. const char *GetGameDirectory( void );
  363. const VMatrix& WorldToScreenMatrix();
  364. const VMatrix& WorldToViewMatrix();
  365. // Loads a game lump off disk
  366. int GameLumpVersion( int lumpId ) const;
  367. int GameLumpSize( int lumpId ) const;
  368. bool LoadGameLump( int lumpId, void* pBuffer, int size );
  369. // Returns the number of leaves in the level
  370. int LevelLeafCount() const;
  371. virtual ISpatialQuery* GetBSPTreeQuery();
  372. // Convert texlight to gamma...
  373. virtual void LinearToGamma( float* linear, float* gamma );
  374. // Get the lightstyle value
  375. virtual float LightStyleValue( int style );
  376. virtual void DrawPortals();
  377. // Computes light due to dynamic lighting at a point
  378. // If the normal isn't specified, then it'll return the maximum lighting
  379. virtual void ComputeDynamicLighting( Vector const& pt, Vector const* pNormal, Vector& color );
  380. // Computes light due to dynamic lighting at a point
  381. // If the normal isn't specified, then it'll return the maximum lighting
  382. // If pBoxColors is specified (it's an array of 6), then it'll copy the light contribution at each box side.
  383. virtual void ComputeLighting( const Vector& pt, const Vector* pNormal, bool bClamp, Vector& color, Vector *pBoxColors );
  384. // Returns the color of the ambient light
  385. virtual void GetAmbientLightColor( Vector& color );
  386. // Returns the dx support level
  387. virtual int GetDXSupportLevel();
  388. virtual bool SupportsHDR();
  389. virtual void Mat_Stub( IMaterialSystem *pMatSys );
  390. // menu display
  391. virtual void GetChapterName( char *pchBuff, int iMaxLength );
  392. virtual char const *GetLevelName( void );
  393. virtual char const *GetLevelNameShort( void );
  394. virtual char const *GetMapGroupName( void );
  395. virtual bool IsLevelMainMenuBackground( void );
  396. virtual void GetMainMenuBackgroundName( char *dest, int destlen );
  397. // Occlusion system control
  398. virtual void SetOcclusionParameters( const OcclusionParams_t &params );
  399. //-----------------------------------------------------------------------------
  400. // Purpose: Takes a trackerID and returns which player slot that user is in
  401. // returns 0 if no player found with that ID
  402. //-----------------------------------------------------------------------------
  403. virtual int GetPlayerForUserID(int userID);
  404. #if !defined( NO_VOICE )
  405. virtual struct IVoiceTweak_s *GetVoiceTweakAPI( void );
  406. virtual void SetVoiceCasterID( uint32 casterID );
  407. #endif
  408. virtual void EngineStats_BeginFrame( void );
  409. virtual void EngineStats_EndFrame( void );
  410. virtual void FireEvents();
  411. virtual void ClearEvents();
  412. virtual void CheckPoint( const char *pName );
  413. virtual int GetLeavesArea( unsigned short *pLeaves, int nLeaves );
  414. virtual bool DoesBoxTouchAreaFrustum( const Vector &mins, const Vector &maxs, int iArea );
  415. virtual int GetFrustumList( Frustum_t **pList, int listMax );
  416. virtual bool ShouldUseAreaFrustum( int area );
  417. // Sets the hearing origin
  418. virtual void SetAudioState( const AudioState_t &audioState );
  419. //-----------------------------------------------------------------------------
  420. //
  421. // Sentence API
  422. //
  423. //-----------------------------------------------------------------------------
  424. virtual int SentenceGroupPick( int groupIndex, char *name, int nameLen );
  425. virtual int SentenceGroupPickSequential( int groupIndex, char *name, int nameLen, int sentenceIndex, int reset );
  426. virtual int SentenceIndexFromName( const char *pSentenceName );
  427. virtual const char *SentenceNameFromIndex( int sentenceIndex );
  428. virtual int SentenceGroupIndexFromName( const char *pGroupName );
  429. virtual const char *SentenceGroupNameFromIndex( int groupIndex );
  430. virtual float SentenceLength( int sentenceIndex );
  431. virtual void DebugDrawPhysCollide( const CPhysCollide *pCollide, IMaterial *pMaterial, const matrix3x4_t& transform, const color32 &color );
  432. // Activates/deactivates an occluder...
  433. virtual void ActivateOccluder( int nOccluderIndex, bool bActive );
  434. virtual bool IsOccluded( int occlusionViewId, const Vector &vecAbsMins, const Vector &vecAbsMaxs );
  435. virtual int GetOcclusionViewId() const;
  436. virtual void *SaveAllocMemory( size_t num, size_t size );
  437. virtual void SaveFreeMemory( void *pSaveMem );
  438. virtual INetChannelInfo *GetNetChannelInfo( void );
  439. virtual bool IsPlayingDemo( void );
  440. virtual bool IsRecordingDemo( void );
  441. virtual bool IsPlayingTimeDemo( void );
  442. virtual int GetDemoRecordingTick( void );
  443. virtual int GetDemoPlaybackTick( void );
  444. virtual int GetDemoPlaybackStartTick( void );
  445. virtual float GetDemoPlaybackTimeScale( void );
  446. virtual int GetDemoPlaybackTotalTicks( void );
  447. virtual CDemoPlaybackParameters_t const * GetDemoPlaybackParameters() OVERRIDE;
  448. virtual bool IsDemoSkipping( void ) OVERRIDE;
  449. virtual int GetConnectionDataProtocol() const OVERRIDE;
  450. virtual bool EngineGotvSyncPacket( const CEngineGotvSyncPacket *pPkt ) OVERRIDE;
  451. virtual void SetDemoImportantEventData( const KeyValues *pData ) OVERRIDE;
  452. virtual bool IsPaused( void );
  453. virtual float GetTimescale( void ) const;
  454. virtual bool IsTakingScreenshot( void );
  455. virtual void WriteScreenshot( const char *pFilename );
  456. virtual bool IsHLTV( void );
  457. virtual bool IsReplay( void );
  458. virtual void GetUILanguage( char *dest, int destlen );
  459. // Can skybox be seen from a particular point?
  460. virtual SkyboxVisibility_t IsSkyboxVisibleFromPoint( const Vector &vecPoint );
  461. virtual const char* GetMapEntitiesString();
  462. virtual bool IsInEditMode( void );
  463. virtual bool IsInCommentaryMode( void );
  464. virtual float GetScreenAspectRatio( int viewportWidth, int viewportHeight );
  465. virtual unsigned int GetEngineBuildNumber() { return GetHostVersion(); }
  466. virtual const char * GetProductVersionString() { return Sys_GetVersionString(); }
  467. virtual void GrabPreColorCorrectedFrame( int x, int y, int width, int height );
  468. virtual bool IsHammerRunning( ) const;
  469. // Stuffs the cmd into the buffer & executes it immediately (vs ClientCmd() which executes it next frame)
  470. virtual void ExecuteClientCmd( const char *szCmdString );
  471. virtual bool MapHasHDRLighting( void) ;
  472. virtual bool MapHasLightMapAlphaData(void);
  473. virtual int GetAppID();
  474. virtual void SetOverlayBindProxy( int iOverlayID, void *pBindProxy );
  475. virtual bool CopyFrameBufferToMaterial( const char *pMaterialName );
  476. // Matchmaking
  477. virtual void ReadConfiguration( const int iController, const bool readDefault );
  478. virtual void SetAchievementMgr( IAchievementMgr *pAchievementMgr );
  479. virtual IAchievementMgr *GetAchievementMgr();
  480. virtual bool MapLoadFailed( void );
  481. virtual void SetMapLoadFailed( bool bState );
  482. virtual bool IsLowViolence();
  483. virtual const char *GetMostRecentSaveGame( bool bEnsureExists );
  484. virtual void SetMostRecentSaveGame( const char *lpszFilename );
  485. virtual void StartXboxExitingProcess();
  486. virtual bool IsSaveInProgress();
  487. virtual bool IsAutoSaveDangerousInProgress();
  488. virtual bool IsAutoSaveInProgress();
  489. virtual const char * GetSaveDirName(); // get a pointer to the path where saves should go (with a trailing slash already added)
  490. virtual uint OnStorageDeviceAttached( int iController );
  491. virtual void OnStorageDeviceDetached( int iController );
  492. virtual void ResetDemoInterpolation( void );
  493. virtual bool REMOVED_SteamRefreshLogin( const char *password, bool isSecure ) { return false; }
  494. virtual bool REMOVED_SteamProcessCall( bool & finished ) { return false; }
  495. // For non-split screen games this will always be zero
  496. virtual int GetActiveSplitScreenPlayerSlot();
  497. virtual int SetActiveSplitScreenPlayerSlot( int slot );
  498. virtual bool SetLocalPlayerIsResolvable( char const *pchContext, int nLine, bool bResolvable );
  499. virtual bool IsLocalPlayerResolvable();
  500. virtual int GetSplitScreenPlayer( int nSlot );
  501. virtual bool IsSplitScreenActive();
  502. virtual bool IsValidSplitScreenSlot( int nSlot );
  503. virtual int FirstValidSplitScreenSlot(); // -1 == invalid
  504. virtual int NextValidSplitScreenSlot( int nPreviousSlot ); // -1 == invalid
  505. virtual ISPSharedMemory * GetSinglePlayerSharedMemorySpace( const char *handle, int ent_num = MAX_EDICTS );
  506. // Computes an ambient cube that includes ALL dynamic lights
  507. virtual void ComputeLightingCube( const Vector& pt, bool bClamp, Vector *pBoxColors );
  508. //All callbacks have to be registered before demo recording begins. TODO: Macro'ize a way to do it at startup
  509. virtual void RegisterDemoCustomDataCallback( string_t szCallbackSaveID, pfnDemoCustomDataCallback pCallback );
  510. virtual void RecordDemoCustomData( pfnDemoCustomDataCallback pCallback, const void *pData, size_t iDataLength );
  511. virtual void SetLeafFlag( int nLeafIndex, int nFlagBits );
  512. // you must call this once done modifying flags. Not super fast.
  513. virtual void RecalculateBSPLeafFlags( void );
  514. virtual bool DSPGetCurrentDASRoomNew(void);
  515. virtual bool DSPGetCurrentDASRoomChanged(void);
  516. virtual bool DSPGetCurrentDASRoomSkyAbove(void);
  517. virtual float DSPGetCurrentDASRoomSkyPercent(void);
  518. virtual void SetMixGroupOfCurrentMixer( const char *szgroupname, const char *szparam, float val, int setMixerType );
  519. virtual int GetMixLayerIndex( const char *szmixlayername );
  520. virtual void SetMixLayerLevel(int index, float level );
  521. virtual int GetMixGroupIndex( const char *pMixGroupName );
  522. virtual void SetMixLayerTriggerFactor( int nMixLayerIndex, int nMixGroupIndex, float flFactor );
  523. virtual void SetMixLayerTriggerFactor( const char *pMixLayerIndex, const char *pMixGroupIndex, float flFactor );
  524. virtual bool IsCreatingReslist();
  525. virtual bool IsCreatingXboxReslist();
  526. virtual void SetTimescale( float flTimescale );
  527. virtual void SetGamestatsData( CGamestatsData *pGamestatsData );
  528. virtual CGamestatsData *GetGamestatsData();
  529. virtual const char *Key_LookupBindingEx( const char *pBinding, int iUserId = -1, int iStartCount = 0, BindingLookupOption_t nFlags = BINDINGLOOKUP_ALL );
  530. virtual int Key_CodeForBinding( const char *pBinding, int iUserId = -1, int iStartCount = 0, BindingLookupOption_t nFlags = BINDINGLOOKUP_ALL );
  531. virtual void UpdateDAndELights( void );
  532. // Methods to get bug count for internal dev work stat tracking.
  533. // Will get the bug count and clear it every map transition
  534. virtual int GetBugSubmissionCount() const;
  535. virtual void ClearBugSubmissionCount();
  536. virtual bool DoesLevelContainWater() const;
  537. virtual float GetServerSimulationFrameTime() const;
  538. virtual void SolidMoved( IClientEntity *pSolidEnt, ICollideable *pSolidCollide, const Vector* pPrevAbsOrigin, bool accurateBboxTriggerChecks );
  539. virtual void TriggerMoved( IClientEntity *pTriggerEnt, bool accurateBboxTriggerChecks );
  540. virtual void ComputeLeavesConnected( const Vector &vecOrigin, int nCount, const int *pLeaves, bool *pIsConnected );
  541. virtual void SetBlurFade( float scale );
  542. virtual bool IsTransitioningToLoad();
  543. virtual void SearchPathsChangedAfterInstall();
  544. virtual void ConfigureSystemLevel( int nCPULevel, int nGPULevel );
  545. virtual void SetConnectionPassword( char const *pchCurrentPW );
  546. virtual CSteamAPIContext* GetSteamAPIContext();
  547. virtual void SubmitStatRecord( char const *szMapName, uint uiBlobVersion, uint uiBlobSize, const void *pvBlob );
  548. virtual void ServerCmdKeyValues( KeyValues *pKeyValues );
  549. virtual void SendMessageToServer( INetMessage *pMessage, bool bForceReliable, bool bVoice ) OVERRIDE;
  550. // global sound pitch scaling
  551. virtual void SetPitchScale( float flPitchScale );
  552. virtual float GetPitchScale( void );
  553. // Load/unload the SFM - used by Replay
  554. virtual bool LoadFilmmaker();
  555. virtual void UnloadFilmmaker();
  556. //paint stuff
  557. virtual bool SpherePaintSurface( const model_t *pModel, const Vector& vPosition, BYTE color, float flSphereRadius, float flPaintCoatPercent );
  558. virtual bool HasPaintmap();
  559. virtual void EnablePaintmapRender();
  560. virtual void SphereTracePaintSurface( const model_t *pModel, const Vector& vPosition, const Vector& vContactNormal, float flSphereRadius, CUtlVector<BYTE>& surfColors );
  561. virtual void RemoveAllPaint();
  562. virtual void PaintAllSurfaces( BYTE color );
  563. virtual void RemovePaint( const model_t *pModel );
  564. virtual bool IsActiveApp();
  565. // is this client running inside the same process as an active server?
  566. virtual bool IsClientLocalToActiveServer();
  567. #if defined( USE_SDL ) || defined ( OSX )
  568. virtual void GetMouseDelta( int &x, int &y, bool bIgnoreNextMouseDelta );
  569. #endif
  570. // Callback for LevelInit to tick the progress bar during time consuming operations
  571. virtual void TickProgressBar();
  572. // Returns the requested input context
  573. virtual InputContextHandle_t GetInputContext( EngineInputContextId_t id );
  574. virtual void GetStartupImage( char *pOutBuffer, int nOutBufferSize );
  575. virtual bool IsUsingLocalNetworkBackdoor();
  576. virtual bool SaveGame( const char *pSaveFilename, bool bIsXSave, char *pOutName, int nOutNameSize, char *pOutComment, int nOutCommentSize );
  577. // Request 'generic' memory stats (returns a list of N named values; caller should assume this list will change over time)
  578. virtual int GetGenericMemoryStats( GenericMemoryStat_t **ppMemoryStats );
  579. // On exit from a map, this becomes true once all map-related assets are flushed from memory:
  580. virtual bool GameHasShutdownAndFlushedMemory();
  581. virtual void FinishContainerWrites( int iController );
  582. virtual void FinishAsyncSave();
  583. const char *GetModDirectory( void );
  584. virtual void AudioLanguageChanged();
  585. virtual void StartLoadingScreenForCommand( const char* command );
  586. virtual void StartLoadingScreenForKeyValues( KeyValues* keyValues );
  587. virtual bool SOSSetOpvarFloat( const char *pOpVarName, float flValue );
  588. virtual bool SOSGetOpvarFloat( const char *pOpVarName, float &flValue );
  589. #if defined(_PS3)
  590. virtual void* GetHostStateWorldBrush( void );
  591. virtual bool PS3_IsUserRestrictedFromChat( void );
  592. virtual bool PS3_IsUserRestrictedFromOnline( void );
  593. virtual bool PS3_PendingInvitesFound( void );
  594. virtual void PS3_ShowInviteOverlay( void );
  595. virtual bool bOverrideCSMConvars( void );
  596. virtual bool bDrawWorldIntoCSM( void );
  597. virtual bool bDrawStaticPropsIntoCSM( void );
  598. virtual float GetCSMMaxDist( void );
  599. #endif
  600. virtual bool IsSubscribedMap( const char *pchMapName, bool bOnlyOnDisk );
  601. virtual bool IsFeaturedMap( const char *pchMapName, bool bOnlyOnDisk );
  602. virtual int GetClientVersion() const;
  603. virtual float GetSafeZoneXMin( void ) const;
  604. virtual bool IsVoiceRecording() const OVERRIDE;
  605. virtual void ForceVoiceRecordOn() const OVERRIDE;
  606. virtual const char* AliasToCommandString( const char* szAliasName ) OVERRIDE;
  607. };
  608. //-----------------------------------------------------------------------------
  609. // Singleton
  610. //-----------------------------------------------------------------------------
  611. static CEngineClient s_VEngineClient;
  612. IVEngineClient *engineClient = &s_VEngineClient;
  613. EXPOSE_SINGLE_INTERFACE_GLOBALVAR( CEngineClient, IVEngineClient, VENGINE_CLIENT_INTERFACE_VERSION, s_VEngineClient );
  614. //-----------------------------------------------------------------------------
  615. // Constructor
  616. //-----------------------------------------------------------------------------
  617. CEngineClient::CEngineClient()
  618. {
  619. }
  620. CEngineClient::~CEngineClient()
  621. {
  622. }
  623. int CEngineClient::GetIntersectingSurfaces(
  624. const model_t *model,
  625. const Vector &vCenter,
  626. const float radius,
  627. const bool bOnlyVisible,
  628. SurfInfo *pInfos,
  629. const int nMaxInfos)
  630. {
  631. if ( !model )
  632. return 0;
  633. byte pvs[MAX_MAP_LEAFS/8];
  634. GetIntersectingSurfaces_Struct theStruct;
  635. theStruct.m_pModel = ( model_t * )model;
  636. theStruct.m_pCenter = &vCenter;
  637. theStruct.m_pCenterPVS = CM_Vis( pvs, sizeof(pvs), CM_LeafCluster( CM_PointLeafnum( vCenter ) ), DVIS_PVS );
  638. theStruct.m_Radius = radius;
  639. theStruct.m_bOnlyVisible = bOnlyVisible;
  640. theStruct.m_pInfos = pInfos;
  641. theStruct.m_nMaxInfos = nMaxInfos;
  642. theStruct.m_nSetInfos = 0;
  643. // Go down the BSP.
  644. GetIntersectingSurfaces_R(
  645. &theStruct,
  646. &model->brush.pShared->nodes[ model->brush.firstnode ] );
  647. return theStruct.m_nSetInfos;
  648. }
  649. Vector CEngineClient::GetLightForPoint(const Vector &pos, bool bClamp)
  650. {
  651. Vector vRet;
  652. ComputeLighting( pos, NULL, bClamp, vRet, NULL );
  653. return vRet;
  654. }
  655. Vector CEngineClient::GetLightForPointFast(const Vector &pos, bool bClamp)
  656. {
  657. Vector vRet;
  658. int leafIndex = CM_PointLeafnum(pos);
  659. vRet.Init();
  660. Vector cube[6];
  661. Mod_LeafAmbientColorAtPos( cube, pos, leafIndex );
  662. for ( int i = 0; i < 6; i++ )
  663. {
  664. vRet.x = fpmax(vRet.x, cube[i].x );
  665. vRet.y = fpmax(vRet.y, cube[i].y );
  666. vRet.z = fpmax(vRet.z, cube[i].z );
  667. }
  668. if ( bClamp )
  669. {
  670. if ( vRet.x > 1.0f )
  671. vRet.x = 1.0f;
  672. if ( vRet.y > 1.0f )
  673. vRet.y = 1.0f;
  674. if ( vRet.z > 1.0f )
  675. vRet.z = 1.0f;
  676. }
  677. return vRet;
  678. }
  679. #if defined( OSX ) || defined( USE_SDL )
  680. void CEngineClient::GetMouseDelta( int &x, int &y, bool bIgnoreNextMouseDelta )
  681. {
  682. g_pLauncherMgr->GetMouseDelta( x, y, bIgnoreNextMouseDelta );
  683. }
  684. #endif
  685. const char *CEngineClient::ParseFile( const char *data, char *token, int maxlen )
  686. {
  687. return ::COM_ParseFile( data, token, maxlen );
  688. }
  689. bool CEngineClient::CopyLocalFile( const char *source, const char *destination )
  690. {
  691. return ::COM_CopyFile( source, destination );
  692. }
  693. void CEngineClient::GetScreenSize( int& w, int &h )
  694. {
  695. CMatRenderContextPtr pRenderContext( materials );
  696. pRenderContext->GetWindowSize( w, h );
  697. }
  698. void CEngineClient::ServerCmd( const char *szCmdString, bool bReliable )
  699. {
  700. // info handling
  701. char buf[255];
  702. Q_snprintf( buf, sizeof( buf ), "cmd %s", szCmdString );
  703. CCommand args;
  704. args.Tokenize( buf );
  705. Cmd_ForwardToServer( args, bReliable );
  706. }
  707. // NOTE: This code runs client commands *from the client*; it doesn't execute commands from the server.
  708. // You will want to use g_pVEngineServer->ClientCommand() for that, but that is subject to the
  709. // much more rigorous restriction of FCVAR_SERVER_CAN_EXECUTE since it is a remote command
  710. // execution path.
  711. void CEngineClient::ClientCmd( const char *szCmdString )
  712. {
  713. cmd_source_t commandSrc = kCommandSrcClientCmd;
  714. // If we aren't restricting client commands, then this is just something "from code"
  715. if ( !GetBaseLocalClient().m_bRestrictClientCommands )
  716. commandSrc = kCommandSrcCode;
  717. Cbuf_AddText( Cbuf_GetCurrentPlayer(), szCmdString, commandSrc );
  718. }
  719. extern ConVar in_forceuser;
  720. void CEngineClient::ClientCmd_Unrestricted( const char *szCmdString, bool fromConsoleOrKeybind )
  721. {
  722. int nSplitScreenPlayerSlot = 0;
  723. if ( splitscreen->IsValidSplitScreenSlot( in_forceuser.GetInt() ) )
  724. {
  725. nSplitScreenPlayerSlot = in_forceuser.GetInt();
  726. }
  727. ACTIVE_SPLITSCREEN_PLAYER_GUARD( nSplitScreenPlayerSlot );
  728. Cbuf_AddText( Cbuf_GetCurrentPlayer(), szCmdString, fromConsoleOrKeybind ? kCommandSrcUserInput : kCommandSrcCode );
  729. }
  730. void CEngineClient::ClientCmd_Unrestricted( const char *szCmdString, bool fromConsoleOrKeybind, int nUserSlot, bool bCheckValidSlot )
  731. {
  732. if ( nUserSlot < 0 || nUserSlot >= host_state.max_splitscreen_players )
  733. {
  734. return;
  735. }
  736. if ( bCheckValidSlot )
  737. {
  738. if ( !splitscreen->IsValidSplitScreenSlot( nUserSlot ) )
  739. {
  740. return;
  741. }
  742. }
  743. ACTIVE_SPLITSCREEN_PLAYER_GUARD( nUserSlot );
  744. Cbuf_AddText( Cbuf_GetCurrentPlayer(), szCmdString, fromConsoleOrKeybind ? kCommandSrcUserInput : kCommandSrcCode );
  745. }
  746. void CEngineClient::SetRestrictServerCommands( bool bRestrict )
  747. {
  748. GetBaseLocalClient().m_bRestrictServerCommands = bRestrict;
  749. }
  750. void CEngineClient::SetRestrictClientCommands( bool bRestrict )
  751. {
  752. GetBaseLocalClient().m_bRestrictClientCommands = bRestrict;
  753. }
  754. void CEngineClient::ExecuteClientCmd( const char *szCmdString )
  755. {
  756. Cbuf_AddText( Cbuf_GetCurrentPlayer(), szCmdString );
  757. Cbuf_Execute();
  758. }
  759. bool CEngineClient::GetPlayerInfo( int ent_num, player_info_t *pinfo )
  760. {
  761. ent_num--; // player list if offset by 1 from ents
  762. if ( ent_num >= GetBaseLocalClient().m_nMaxClients || ent_num < 0 )
  763. {
  764. Q_memset( pinfo, 0, sizeof( player_info_t ) );
  765. return false;
  766. }
  767. Assert( GetBaseLocalClient().m_pUserInfoTable );
  768. if ( !GetBaseLocalClient().m_pUserInfoTable )
  769. {
  770. Q_memset( pinfo, 0, sizeof( player_info_t ) );
  771. return false;
  772. }
  773. Assert( ent_num < GetBaseLocalClient().m_pUserInfoTable->GetNumStrings() );
  774. if ( ent_num >= GetBaseLocalClient().m_pUserInfoTable->GetNumStrings() )
  775. {
  776. Q_memset( pinfo, 0, sizeof( player_info_t ) );
  777. return false;
  778. }
  779. player_info_t *pi = (player_info_t*) GetBaseLocalClient().m_pUserInfoTable->GetStringUserData( ent_num, NULL );
  780. if ( !pi )
  781. {
  782. Q_memset( pinfo, 0, sizeof( player_info_t ) );
  783. return false;
  784. }
  785. // Check the version of player info coming in
  786. uint64 iVersion = BigQWord( pi->version );
  787. if ( iVersion != CDLL_PLAYER_INFO_S_VERSION_CURRENT )
  788. {
  789. // This is "old version 1"
  790. player_info_t_version_1 * pi_old_version_1 = reinterpret_cast< player_info_t_version_1 * >( pi );
  791. pinfo->version = BigQWord( CDLL_PLAYER_INFO_S_VERSION_CURRENT );
  792. Q_memcpy( &pinfo->xuid, &pi_old_version_1->xuid, sizeof( pi_old_version_1->xuid ) );
  793. Q_memcpy( pinfo->name, pi_old_version_1->name, sizeof( pi_old_version_1->name ) );
  794. Q_memcpy( &pinfo->userID, &pi_old_version_1->userID, sizeof( pi_old_version_1->userID ) );
  795. Q_memcpy( pinfo->guid, pi_old_version_1->guid, sizeof( pi_old_version_1->guid ) );
  796. Q_memcpy( &pinfo->friendsID, &pi_old_version_1->friendsID, sizeof( pi_old_version_1->friendsID ) );
  797. Q_memcpy( pinfo->friendsName, pi_old_version_1->friendsName, sizeof( pi_old_version_1->friendsName ) );
  798. Q_memcpy( &pinfo->fakeplayer, &pi_old_version_1->fakeplayer, sizeof( pi_old_version_1->fakeplayer ) );
  799. Q_memcpy( &pinfo->ishltv, &pi_old_version_1->ishltv, sizeof( pi_old_version_1->ishltv ) );
  800. Q_memcpy( pinfo->customFiles, pi_old_version_1->customFiles, sizeof( pi_old_version_1->customFiles ) );
  801. Q_memcpy( &pinfo->filesDownloaded, &pi_old_version_1->filesDownloaded, sizeof( pi_old_version_1->filesDownloaded ) );
  802. }
  803. else
  804. {
  805. Q_memcpy( pinfo, pi, sizeof( player_info_t ) );
  806. }
  807. // Fixup from network order (big endian)
  808. CByteswap byteswap;
  809. byteswap.SetTargetBigEndian( true );
  810. byteswap.SwapFieldsToTargetEndian( pinfo );
  811. return true;
  812. }
  813. client_textmessage_t *CEngineClient::TextMessageGet( const char *pName )
  814. {
  815. return ::TextMessageGet( pName );
  816. }
  817. bool CEngineClient::Con_IsVisible( void )
  818. {
  819. return ::Con_IsVisible();
  820. }
  821. int CEngineClient::GetLocalPlayer( void )
  822. {
  823. return GetLocalClient().m_nPlayerSlot + 1;
  824. }
  825. float CEngineClient::GetLastTimeStamp( void )
  826. {
  827. return GetBaseLocalClient().m_flLastServerTickTime;
  828. }
  829. int CEngineClient::GetLastAcknowledgedCommand( void )
  830. {
  831. return GetBaseLocalClient().command_ack;
  832. }
  833. int CEngineClient::GetServerTick( void )
  834. {
  835. return GetBaseLocalClient().GetServerTickCount();
  836. }
  837. bool CEngineClient::MapHasHDRLighting( void)
  838. {
  839. return modelloader->LastLoadedMapHasHDRLighting();
  840. }
  841. bool CEngineClient::MapHasLightMapAlphaData( void)
  842. {
  843. return modelloader->LastLoadedMapHasLightmapAlphaData();
  844. }
  845. const model_t *CEngineClient::LoadModel( const char *pName, bool bProp )
  846. {
  847. return modelloader->GetModelForName( pName, bProp ? IModelLoader::FMODELLOADER_DETAILPROP : IModelLoader::FMODELLOADER_CLIENTDLL );
  848. }
  849. CSentence *CEngineClient::GetSentence( CAudioSource *pAudioSource )
  850. {
  851. if (pAudioSource)
  852. {
  853. return pAudioSource->GetSentence();
  854. }
  855. return NULL;
  856. }
  857. float CEngineClient::GetSentenceLength( CAudioSource *pAudioSource )
  858. {
  859. if (pAudioSource && pAudioSource->SampleRate() > 0 )
  860. {
  861. float length = (float)pAudioSource->SampleCount() / (float)pAudioSource->SampleRate();
  862. return length;
  863. }
  864. return 0.0f;
  865. }
  866. bool CEngineClient::IsStreaming( CAudioSource *pAudioSource ) const
  867. {
  868. if ( pAudioSource )
  869. {
  870. return pAudioSource->IsStreaming();
  871. }
  872. return false;
  873. }
  874. // FIXME, move entirely to client .dll
  875. void CEngineClient::GetViewAngles( QAngle& va )
  876. {
  877. VectorCopy( GetLocalClient().viewangles, va );
  878. }
  879. void CEngineClient::SetViewAngles( QAngle& va )
  880. {
  881. if ( !va.IsValid() )
  882. {
  883. Warning( "CEngineClient::SetViewAngles: rejecting invalid value [%f %f %f]\n", VectorExpand( va ) );
  884. // Just zero it out
  885. GetLocalClient().viewangles = vec3_angle;
  886. return;
  887. }
  888. GetLocalClient().viewangles.x = AngleNormalize( va.x );
  889. GetLocalClient().viewangles.y = AngleNormalize( va.y );
  890. GetLocalClient().viewangles.z = AngleNormalize( va.z );
  891. }
  892. int CEngineClient::GetMaxClients( void )
  893. {
  894. return GetBaseLocalClient().m_nMaxClients;
  895. }
  896. void CEngineClient::SetMapLoadFailed( bool bState )
  897. {
  898. g_ServerGlobalVariables.bMapLoadFailed = bState;
  899. }
  900. bool CEngineClient::MapLoadFailed( void )
  901. {
  902. return g_ServerGlobalVariables.bMapLoadFailed;
  903. }
  904. void CEngineClient::ReadConfiguration( const int iController, const bool readDefault )
  905. {
  906. Host_ReadConfiguration( iController, readDefault );
  907. }
  908. const char *CEngineClient::Key_LookupBinding( const char *pBinding )
  909. {
  910. return ::Key_NameForBinding( pBinding );
  911. }
  912. const char *CEngineClient::Key_BindingForKey( ButtonCode_t code )
  913. {
  914. return ::Key_BindingForKey( code );
  915. }
  916. void CEngineClient::Key_SetBinding( ButtonCode_t code, const char *pBinding )
  917. {
  918. ::Key_SetBinding( code, pBinding );
  919. }
  920. void CEngineClient::StartKeyTrapMode( void )
  921. {
  922. Key_StartTrapMode();
  923. }
  924. bool CEngineClient::CheckDoneKeyTrapping( ButtonCode_t &code )
  925. {
  926. return Key_CheckDoneTrapping( code );
  927. }
  928. bool CEngineClient::IsInGame( void )
  929. {
  930. return GetBaseLocalClient().IsActive();
  931. }
  932. bool CEngineClient::IsConnected( void )
  933. {
  934. return GetBaseLocalClient().IsConnected();
  935. }
  936. bool CEngineClient::GameHasShutdownAndFlushedMemory( void )
  937. {
  938. return HostState_GameHasShutDownAndFlushedMemory();
  939. }
  940. bool CEngineClient::IsDrawingLoadingImage( void )
  941. {
  942. return scr_drawloading;
  943. }
  944. void CEngineClient::HideLoadingPlaque( void )
  945. {
  946. // Now the client DLL should let us actually shutdown the loading plaque
  947. if ( !scr_drawloading )
  948. {
  949. DevWarning( "Attempted to HideLoadingPlaque when not loading...\n" );
  950. }
  951. if ( g_ClientDLL && !g_ClientDLL->ShouldHideLoadingPlaque() )
  952. {
  953. DevWarning( "Attempted to HideLoadingPlaque when client prevents hiding loading plaque...\n" );
  954. }
  955. // Shutdown the plaque
  956. SCR_EndLoadingPlaque();
  957. }
  958. void CEngineClient::Con_NPrintf( int pos, const char *fmt, ... )
  959. {
  960. va_list argptr;
  961. char text[4096];
  962. va_start (argptr, fmt);
  963. Q_vsnprintf(text, sizeof( text ), fmt, argptr);
  964. va_end (argptr);
  965. ::Con_NPrintf( pos, "%s", text );
  966. }
  967. void CEngineClient::Con_NXPrintf( const struct con_nprint_s *info, const char *fmt, ... )
  968. {
  969. va_list argptr;
  970. char text[4096];
  971. va_start (argptr, fmt);
  972. Q_vsnprintf(text, sizeof( text ), fmt, argptr);
  973. va_end (argptr);
  974. ::Con_NXPrintf( info, "%s", text );
  975. }
  976. IMaterial *CEngineClient::TraceLineMaterialAndLighting( const Vector &start, const Vector &end,
  977. Vector &diffuseLightColor, Vector &baseColor )
  978. {
  979. return BrushModel_GetLightingAndMaterial( start, end, diffuseLightColor, baseColor );
  980. }
  981. int CEngineClient::IsBoxVisible( const Vector& mins, const Vector& maxs )
  982. {
  983. return CM_BoxVisible( mins, maxs, Map_VisCurrent(), CM_ClusterPVSSize() );
  984. }
  985. int CEngineClient::IsBoxInViewCluster( const Vector& mins, const Vector& maxs )
  986. {
  987. // See comments in Map_VisCurrentCluster for why we might get a negative number.
  988. int curCluster = Map_VisCurrentCluster();
  989. if ( curCluster < 0 )
  990. return false;
  991. byte pvs[MAX_MAP_LEAFS/8];
  992. const byte *ppvs = CM_Vis( pvs, sizeof(pvs), curCluster, DVIS_PVS );
  993. return CM_BoxVisible(mins, maxs, ppvs, sizeof(pvs) );
  994. }
  995. void CEngineClient::Sound_ExtraUpdate( void )
  996. {
  997. // On xbox, sound is mixed on another thread, this is not necessary ever
  998. if ( IsGameConsole() )
  999. return;
  1000. S_ExtraUpdate();
  1001. }
  1002. #if defined(_PS3)
  1003. extern void Host_UpdateSounds( void );
  1004. void CEngineClient::Sound_ServerUpdateSoundsPS3( void )
  1005. {
  1006. if (sv.IsActive())
  1007. {
  1008. Host_UpdateSounds();
  1009. }
  1010. }
  1011. #endif
  1012. bool CEngineClient::CullBox ( const Vector& mins, const Vector& maxs )
  1013. {
  1014. return g_Frustum.CullBox( mins, maxs );
  1015. }
  1016. const char *CEngineClient::GetGameDirectory( void )
  1017. {
  1018. return com_gamedir;
  1019. }
  1020. const char *CEngineClient::GetModDirectory( void )
  1021. {
  1022. return COM_GetModDirectory();
  1023. }
  1024. const VMatrix& CEngineClient::WorldToScreenMatrix()
  1025. {
  1026. // FIXME: this is only valid if we're currently rendering. If not, it should use the player, or it really should pass one in.
  1027. return g_EngineRenderer->WorldToScreenMatrix();
  1028. }
  1029. const VMatrix& CEngineClient::WorldToViewMatrix()
  1030. {
  1031. // FIXME: this is only valid if we're currently rendering. If not, it should use the player, or it really should pass one in.
  1032. return g_EngineRenderer->ViewMatrix();
  1033. }
  1034. // Loads a game lump off disk
  1035. int CEngineClient::GameLumpVersion( int lumpId ) const
  1036. {
  1037. return Mod_GameLumpVersion( lumpId );
  1038. }
  1039. int CEngineClient::GameLumpSize( int lumpId ) const
  1040. {
  1041. return Mod_GameLumpSize( lumpId );
  1042. }
  1043. bool CEngineClient::LoadGameLump( int lumpId, void* pBuffer, int size )
  1044. {
  1045. return Mod_LoadGameLump( lumpId, pBuffer, size );
  1046. }
  1047. // Returns the number of leaves in the level
  1048. int CEngineClient::LevelLeafCount() const
  1049. {
  1050. return host_state.worldbrush->numleafs;
  1051. }
  1052. static void SetNodeFlagBits( mnode_t *node )
  1053. {
  1054. if ( node->contents < 0 ) // has children
  1055. {
  1056. SetNodeFlagBits( node->children[0] );
  1057. SetNodeFlagBits( node->children[1] );
  1058. node->flags =
  1059. ( node->flags & ( LEAF_FLAGS_SKY | LEAF_FLAGS_SKY2D | LEAF_FLAGS_RADIAL ) ) |
  1060. node->children[0]->flags | node->children[1]->flags;
  1061. }
  1062. }
  1063. void CEngineClient::SetLeafFlag( int nLeafIndex, int nFlagBits )
  1064. {
  1065. assert( nLeafIndex < host_state.worldbrush->numleafs );
  1066. host_state.worldbrush->leafs[nLeafIndex].flags |= nFlagBits;
  1067. }
  1068. void CEngineClient::RecalculateBSPLeafFlags( void )
  1069. {
  1070. SetNodeFlagBits( host_state.worldbrush->nodes );
  1071. }
  1072. ISpatialQuery* CEngineClient::GetBSPTreeQuery()
  1073. {
  1074. return g_pToolBSPTree;
  1075. }
  1076. // Convert texlight to gamma...
  1077. void CEngineClient::LinearToGamma( float* linear, float* gamma )
  1078. {
  1079. gamma[0] = LinearToTexture( linear[0] ) / 255.0f;
  1080. gamma[1] = LinearToTexture( linear[1] ) / 255.0f;
  1081. gamma[2] = LinearToTexture( linear[2] ) / 255.0f;
  1082. }
  1083. // Get the lightstyle value
  1084. float CEngineClient::LightStyleValue( int style )
  1085. {
  1086. return ::LightStyleValue( style );
  1087. }
  1088. void CEngineClient::DrawPortals()
  1089. {
  1090. R_DrawPortals();
  1091. }
  1092. // Computes light due to dynamic lighting at a point
  1093. // If the normal isn't specified, then it'll return the maximum lighting
  1094. void CEngineClient::ComputeDynamicLighting( Vector const& pt, Vector const* pNormal, Vector& color )
  1095. {
  1096. ::ComputeDynamicLighting( pt, pNormal, color );
  1097. }
  1098. // Computes light due to dynamic lighting at a point
  1099. // If the normal isn't specified, then it'll return the maximum lighting
  1100. void CEngineClient::ComputeLighting( const Vector& pt, const Vector* pNormal, bool bClamp, Vector& color, Vector *pBoxColors )
  1101. {
  1102. ::ComputeLighting( pt, pNormal, bClamp, false, color, pBoxColors );
  1103. }
  1104. // Computes an ambient cube that includes ALL dynamic lights
  1105. void CEngineClient::ComputeLightingCube( const Vector& pt, bool bClamp, Vector *pBoxColors )
  1106. {
  1107. Vector dummy;
  1108. ::ComputeLighting( pt, NULL, bClamp, true, dummy, pBoxColors );
  1109. }
  1110. // Returns the color of the ambient light
  1111. void CEngineClient::GetAmbientLightColor( Vector& color )
  1112. {
  1113. dworldlight_t* pWorldLight = FindAmbientLight();
  1114. if (!pWorldLight)
  1115. color.Init( 0, 0, 0 );
  1116. else
  1117. VectorCopy( pWorldLight->intensity, color );
  1118. }
  1119. // Returns the dx support level
  1120. int CEngineClient::GetDXSupportLevel()
  1121. {
  1122. return g_pMaterialSystemHardwareConfig->GetDXSupportLevel();
  1123. }
  1124. bool CEngineClient::SupportsHDR()
  1125. {
  1126. // deprecated.
  1127. // Assert( 0 );
  1128. return false;
  1129. }
  1130. void CEngineClient::Mat_Stub( IMaterialSystem *pMatSys )
  1131. {
  1132. materials = pMatSys;
  1133. // Pass the call to the model renderer.
  1134. if ( g_pStudioRender )
  1135. g_pStudioRender->Mat_Stub( pMatSys );
  1136. }
  1137. void CEngineClient::GetChapterName( char *pchBuff, int iMaxLength )
  1138. {
  1139. serverGameDLL->GetSaveComment( pchBuff, iMaxLength, 0.0f, 0.0f, true );
  1140. }
  1141. char const *CEngineClient::GetLevelName( void )
  1142. {
  1143. if ( sv.IsDedicated() )
  1144. {
  1145. return "Dedicated Server";
  1146. }
  1147. else if ( !GetBaseLocalClient().IsConnected() )
  1148. {
  1149. return "";
  1150. }
  1151. return GetBaseLocalClient().m_szLevelName;
  1152. }
  1153. char const *CEngineClient::GetLevelNameShort( void )
  1154. {
  1155. if ( sv.IsDedicated() )
  1156. {
  1157. return "dedicated";
  1158. }
  1159. else if ( !GetBaseLocalClient().IsConnected() )
  1160. {
  1161. return "";
  1162. }
  1163. return GetBaseLocalClient().m_szLevelNameShort;
  1164. }
  1165. char const *CEngineClient::GetMapGroupName( void )
  1166. {
  1167. if ( !GetBaseLocalClient().IsConnected() )
  1168. {
  1169. return "";
  1170. }
  1171. return GetBaseLocalClient().m_szMapGroupName;
  1172. }
  1173. bool CEngineClient::IsLevelMainMenuBackground( void )
  1174. {
  1175. return sv.IsLevelMainMenuBackground();
  1176. }
  1177. void CEngineClient::GetMainMenuBackgroundName( char *dest, int destlen )
  1178. {
  1179. CL_GetBackgroundLevelName( dest, destlen, false );
  1180. }
  1181. void CEngineClient::GetStartupImage( char *dest, int destlen )
  1182. {
  1183. CL_GetStartupImage( dest, destlen );
  1184. }
  1185. bool CEngineClient::IsUsingLocalNetworkBackdoor()
  1186. {
  1187. return ( g_pLocalNetworkBackdoor != NULL );
  1188. }
  1189. bool CEngineClient::SaveGame( const char *pSaveFilename, bool bIsXSave, char *pOutName, int nOutNameSize, char *pOutComment, int nOutCommentSize )
  1190. {
  1191. return saverestore->SaveGame( pSaveFilename, bIsXSave, pOutName, nOutNameSize, pOutComment, nOutCommentSize );
  1192. }
  1193. // Occlusion system control
  1194. void CEngineClient::SetOcclusionParameters( const OcclusionParams_t &params )
  1195. {
  1196. OcclusionSystem()->SetOcclusionParameters( params.m_flMaxOccludeeArea, params.m_flMinOccluderArea );
  1197. }
  1198. //-----------------------------------------------------------------------------
  1199. // Purpose: Takes a trackerID and returns which player slot that user is in
  1200. // returns 0 if no player found with that ID
  1201. //-----------------------------------------------------------------------------
  1202. int CEngineClient::GetPlayerForUserID(int userID)
  1203. {
  1204. if ( !GetBaseLocalClient().m_pUserInfoTable )
  1205. return 0;
  1206. for ( int i = 0; i < GetBaseLocalClient().m_nMaxClients; i++ )
  1207. {
  1208. // [mhansen] We send the user info in big endian... so here we do what L4D did
  1209. int iEntIndex = i + 1;
  1210. player_info_t ent_info;
  1211. if ( GetPlayerInfo( iEntIndex, &ent_info ) && ent_info.userID == userID )
  1212. return iEntIndex;
  1213. }
  1214. return 0;
  1215. }
  1216. #if !defined( NO_VOICE )
  1217. struct IVoiceTweak_s *CEngineClient::GetVoiceTweakAPI( void )
  1218. {
  1219. return &g_VoiceTweakAPI;
  1220. }
  1221. void CEngineClient::SetVoiceCasterID( uint32 casterID )
  1222. {
  1223. Voice_SetCaster( casterID );
  1224. }
  1225. #endif
  1226. void CEngineClient::EngineStats_BeginFrame( void )
  1227. {
  1228. g_EngineStats.BeginFrame();
  1229. }
  1230. void CEngineClient::EngineStats_EndFrame( void )
  1231. {
  1232. g_EngineStats.EndFrame();
  1233. }
  1234. void CEngineClient::FireEvents()
  1235. {
  1236. // Run any events queued up for this frame
  1237. CL_FireEvents();
  1238. }
  1239. void CEngineClient::ClearEvents()
  1240. {
  1241. // clear any queued up events
  1242. GetBaseLocalClient().events.RemoveAll();
  1243. }
  1244. void CEngineClient::CheckPoint( const char *pName )
  1245. {
  1246. GetTestScriptMgr()->CheckPoint( pName );
  1247. }
  1248. int CEngineClient::GetLeavesArea( unsigned short *pLeaves, int nLeaves )
  1249. {
  1250. if ( nLeaves == 0 )
  1251. return -1;
  1252. int iArea = host_state.worldbrush->leafs[pLeaves[0]].area;
  1253. for ( int i=1; i < nLeaves; i++ )
  1254. {
  1255. int iTestArea = host_state.worldbrush->leafs[pLeaves[i]].area;
  1256. if ( iTestArea != iArea )
  1257. return -1;
  1258. }
  1259. return iArea;
  1260. }
  1261. bool CEngineClient::DoesBoxTouchAreaFrustum( const Vector &mins, const Vector &maxs, int iArea )
  1262. {
  1263. const Frustum_t *pFrustum = GetAreaFrustum( iArea );
  1264. return !pFrustum->CullBox( mins, maxs );
  1265. }
  1266. int CEngineClient::GetFrustumList( Frustum_t **pList, int listMax )
  1267. {
  1268. pList[0] = &g_Frustum;
  1269. int count = GetAllAreaFrustums( pList + 1, listMax-1 );
  1270. return count+1;
  1271. }
  1272. bool CEngineClient::ShouldUseAreaFrustum( int area )
  1273. {
  1274. return R_ShouldUseAreaFrustum( area );
  1275. }
  1276. //-----------------------------------------------------------------------------
  1277. // Sets the hearing origin
  1278. //-----------------------------------------------------------------------------
  1279. void CEngineClient::SetAudioState( const AudioState_t &audioState )
  1280. {
  1281. Host_SetAudioState( audioState );
  1282. }
  1283. //-----------------------------------------------------------------------------
  1284. //
  1285. // Sentence API
  1286. //
  1287. //-----------------------------------------------------------------------------
  1288. int CEngineClient::SentenceGroupPick( int groupIndex, char *name, int nameLen )
  1289. {
  1290. return VOX_GroupPick( groupIndex, name, nameLen );
  1291. }
  1292. int CEngineClient::SentenceGroupPickSequential( int groupIndex, char *name, int nameLen, int sentenceIndex, int reset )
  1293. {
  1294. return VOX_GroupPickSequential( groupIndex, name, nameLen, sentenceIndex, reset );
  1295. }
  1296. int CEngineClient::SentenceIndexFromName( const char *pSentenceName )
  1297. {
  1298. int sentenceIndex = -1;
  1299. VOX_LookupString( pSentenceName, &sentenceIndex );
  1300. return sentenceIndex;
  1301. }
  1302. const char *CEngineClient::SentenceNameFromIndex( int sentenceIndex )
  1303. {
  1304. return VOX_SentenceNameFromIndex( sentenceIndex );
  1305. }
  1306. int CEngineClient::SentenceGroupIndexFromName( const char *pGroupName )
  1307. {
  1308. return VOX_GroupIndexFromName( pGroupName );
  1309. }
  1310. const char *CEngineClient::SentenceGroupNameFromIndex( int groupIndex )
  1311. {
  1312. return VOX_GroupNameFromIndex( groupIndex );
  1313. }
  1314. float CEngineClient::SentenceLength( int sentenceIndex )
  1315. {
  1316. return VOX_SentenceLength( sentenceIndex );
  1317. }
  1318. void CEngineClient::DebugDrawPhysCollide( const CPhysCollide *pCollide, IMaterial *pMaterial, const matrix3x4_t& transform, const color32 &color )
  1319. {
  1320. ::DebugDrawPhysCollide( pCollide, pMaterial, transform, color, false );
  1321. }
  1322. // Activates/deactivates an occluder...
  1323. void CEngineClient::ActivateOccluder( int nOccluderIndex, bool bActive )
  1324. {
  1325. OcclusionSystem()->ActivateOccluder( nOccluderIndex, bActive );
  1326. }
  1327. bool CEngineClient::IsOccluded( int occlusionViewId, const Vector &vecAbsMins, const Vector &vecAbsMaxs )
  1328. {
  1329. return OcclusionSystem()->IsOccluded( occlusionViewId, vecAbsMins, vecAbsMaxs );
  1330. }
  1331. int CEngineClient::GetOcclusionViewId() const
  1332. {
  1333. return OcclusionSystem()->GetViewId();
  1334. }
  1335. void *CEngineClient::SaveAllocMemory( size_t num, size_t size )
  1336. {
  1337. return ::SaveAllocMemory( num, size );
  1338. }
  1339. void CEngineClient::SaveFreeMemory( void *pSaveMem )
  1340. {
  1341. ::SaveFreeMemory( pSaveMem );
  1342. }
  1343. INetChannelInfo *CEngineClient::GetNetChannelInfo( void )
  1344. {
  1345. return (INetChannelInfo*) GetBaseLocalClient().m_NetChannel;
  1346. }
  1347. bool CEngineClient::IsPlayingDemo( void )
  1348. {
  1349. return demoplayer->IsPlayingBack();
  1350. }
  1351. bool CEngineClient::IsRecordingDemo( void )
  1352. {
  1353. return demorecorder->IsRecording();
  1354. }
  1355. bool CEngineClient::IsPlayingTimeDemo( void )
  1356. {
  1357. return demoplayer->IsPlayingTimeDemo();
  1358. }
  1359. CDemoPlaybackParameters_t const * CEngineClient::GetDemoPlaybackParameters()
  1360. {
  1361. return demoplayer->GetDemoPlaybackParameters();
  1362. }
  1363. bool CEngineClient::IsDemoSkipping()
  1364. {
  1365. return demoplayer->IsSkipping();
  1366. }
  1367. int CEngineClient::GetConnectionDataProtocol() const
  1368. {
  1369. return GetBaseLocalClient().m_nServerInfoMsgProtocol;
  1370. }
  1371. bool CEngineClient::EngineGotvSyncPacket( const CEngineGotvSyncPacket *pPkt )
  1372. {
  1373. return s_ClientBroadcastPlayer.OnEngineGotvSyncPacket( pPkt );
  1374. }
  1375. void CEngineClient::SetDemoImportantEventData( const KeyValues *pData )
  1376. {
  1377. demoplayer->SetImportantEventData( pData );
  1378. }
  1379. bool CEngineClient::IsPaused( void )
  1380. {
  1381. return GetBaseLocalClient().IsPaused();
  1382. }
  1383. float CEngineClient::GetTimescale( void ) const
  1384. {
  1385. extern float CL_GetHltvReplayTimeScale();
  1386. return sv.GetTimescale() * host_timescale.GetFloat() * CL_GetHltvReplayTimeScale();
  1387. }
  1388. bool CEngineClient::IsTakingScreenshot( void )
  1389. {
  1390. return cl_takesnapshot;
  1391. }
  1392. extern bool cl_takesnapshot;
  1393. extern bool cl_takejpeg;
  1394. extern char cl_snapshot_fullpathname[MAX_OSPATH];
  1395. void CEngineClient::WriteScreenshot( const char *pFilename )
  1396. {
  1397. cl_takesnapshot = true;
  1398. cl_takejpeg = true;
  1399. V_strncpy( cl_snapshot_fullpathname, pFilename, MAX_OSPATH );
  1400. }
  1401. int CEngineClient::GetDemoRecordingTick( void )
  1402. {
  1403. return demorecorder->GetRecordingTick();
  1404. }
  1405. int CEngineClient::GetDemoPlaybackTick( void )
  1406. {
  1407. return demoplayer->GetPlaybackTick();
  1408. }
  1409. int CEngineClient::GetDemoPlaybackStartTick( void )
  1410. {
  1411. return demoplayer->GetPlaybackStartTick();
  1412. }
  1413. float CEngineClient::GetDemoPlaybackTimeScale( void )
  1414. {
  1415. return demoplayer->GetPlaybackTimeScale();
  1416. }
  1417. int CEngineClient::GetDemoPlaybackTotalTicks( void )
  1418. {
  1419. return demoplayer->GetDemoStream()->GetTotalTicks();
  1420. }
  1421. bool CEngineClient::IsHLTV( void )
  1422. {
  1423. return GetBaseLocalClient().ishltv || GetBaseLocalClient().GetHltvReplayDelay() > 0;
  1424. }
  1425. bool CEngineClient::IsReplay( void )
  1426. {
  1427. #if defined( REPLAY_ENABLED )
  1428. return GetBaseLocalClient().isreplay;
  1429. #else
  1430. return false;
  1431. #endif
  1432. }
  1433. void CEngineClient::GetUILanguage( char *dest, int destlen )
  1434. {
  1435. const char *pStr = cl_language.GetString();
  1436. if ( pStr )
  1437. {
  1438. V_strncpy( dest, pStr, destlen );
  1439. }
  1440. else
  1441. {
  1442. dest[0] = 0;
  1443. }
  1444. }
  1445. //-----------------------------------------------------------------------------
  1446. // Can skybox be seen from a particular point?
  1447. //-----------------------------------------------------------------------------
  1448. SkyboxVisibility_t CEngineClient::IsSkyboxVisibleFromPoint( const Vector &vecPoint )
  1449. {
  1450. // In the mat_fullbright 1 case, it's always visible
  1451. // (we may have no lighting in the level, and vrad is where LEAF_FLAGS_SKY is computed)
  1452. if ( g_pMaterialSystemConfig->nFullbright == 1 )
  1453. return SKYBOX_3DSKYBOX_VISIBLE;
  1454. int nLeaf = CM_PointLeafnum( vecPoint );
  1455. int nFlags = GetCollisionBSPData()->map_leafs[nLeaf].flags;
  1456. if ( nFlags & LEAF_FLAGS_SKY )
  1457. return SKYBOX_3DSKYBOX_VISIBLE;
  1458. return ( nFlags & LEAF_FLAGS_SKY2D ) ? SKYBOX_2DSKYBOX_VISIBLE : SKYBOX_NOT_VISIBLE;
  1459. }
  1460. const char* CEngineClient::GetMapEntitiesString()
  1461. {
  1462. return CM_EntityString();
  1463. }
  1464. bool CEngineClient::IsInEditMode( void )
  1465. {
  1466. return g_bInEditMode;
  1467. }
  1468. bool CEngineClient::IsInCommentaryMode( void )
  1469. {
  1470. return g_bInCommentaryMode;
  1471. }
  1472. float CEngineClient::GetScreenAspectRatio( int viewportWidth, int viewportHeight )
  1473. {
  1474. return GetScreenAspect( viewportWidth, viewportHeight );
  1475. }
  1476. int CEngineClient::GetAppID()
  1477. {
  1478. return GetSteamAppID();
  1479. }
  1480. void CEngineClient::SetOverlayBindProxy( int iOverlayID, void *pBindProxy )
  1481. {
  1482. OverlayMgr()->SetOverlayBindProxy( iOverlayID, pBindProxy );
  1483. }
  1484. //-----------------------------------------------------------------------------
  1485. // Returns true if copy occured
  1486. //-----------------------------------------------------------------------------
  1487. bool CEngineClient::CopyFrameBufferToMaterial( const char *pMaterialName )
  1488. {
  1489. if ( !IsX360() )
  1490. {
  1491. // not for PC
  1492. Assert( 0 );
  1493. return false;
  1494. }
  1495. IMaterial *pMaterial = materials->FindMaterial( pMaterialName, TEXTURE_GROUP_OTHER );
  1496. if ( pMaterial->IsErrorMaterial() )
  1497. {
  1498. // unknown material
  1499. return false;
  1500. }
  1501. bool bFound;
  1502. IMaterialVar *pMaterialVar = pMaterial->FindVar( "$baseTexture", &bFound, false );
  1503. if ( !bFound || pMaterialVar->GetType() != MATERIAL_VAR_TYPE_TEXTURE )
  1504. {
  1505. // lack of expected $basetexture
  1506. return false;
  1507. }
  1508. ITexture *pTexture = pMaterialVar->GetTextureValue();
  1509. if ( !pTexture || !pTexture->IsRenderTarget() )
  1510. {
  1511. // base texture is not a render target
  1512. return false;
  1513. }
  1514. CMatRenderContextPtr pRenderContext( materials );
  1515. int width, height;
  1516. pRenderContext->GetRenderTargetDimensions( width, height );
  1517. if ( width != pTexture->GetActualWidth() || height != pTexture->GetActualHeight() )
  1518. {
  1519. // better be matched, not supporting a disparate blit in this context
  1520. // disparate blit may very well use same RT we are trying to copy into
  1521. return false;
  1522. }
  1523. pRenderContext->CopyRenderTargetToTexture( pTexture );
  1524. return true;
  1525. }
  1526. //-----------------------------------------------------------------------------
  1527. // Used by the color correction UI
  1528. //-----------------------------------------------------------------------------
  1529. void CEngineClient::GrabPreColorCorrectedFrame( int x, int y, int width, int height )
  1530. {
  1531. colorcorrectiontools->GrabPreColorCorrectedFrame( x, y, width, height );
  1532. }
  1533. //-----------------------------------------------------------------------------
  1534. // Is hammer running?
  1535. //-----------------------------------------------------------------------------
  1536. bool CEngineClient::IsHammerRunning( ) const
  1537. {
  1538. return IsPC() ? InEditMode() : false;
  1539. }
  1540. extern IAchievementMgr *g_pAchievementMgr;
  1541. //-----------------------------------------------------------------------------
  1542. // Sets achievement mgr
  1543. //-----------------------------------------------------------------------------
  1544. void CEngineClient::SetAchievementMgr( IAchievementMgr *pAchievementMgr )
  1545. {
  1546. g_pAchievementMgr = pAchievementMgr;
  1547. }
  1548. //-----------------------------------------------------------------------------
  1549. // Gets achievement mgr
  1550. //-----------------------------------------------------------------------------
  1551. IAchievementMgr *CEngineClient::GetAchievementMgr()
  1552. {
  1553. return g_pAchievementMgr;
  1554. }
  1555. //-----------------------------------------------------------------------------
  1556. // Called by the client to determine violence settings for things like ragdoll
  1557. // fading.
  1558. //-----------------------------------------------------------------------------
  1559. bool CEngineClient::IsLowViolence()
  1560. {
  1561. return g_bLowViolence;
  1562. }
  1563. const char *CEngineClient::GetMostRecentSaveGame( bool bEnsureExists )
  1564. {
  1565. const char *pszResult = saverestore->GetMostRecentlyLoadedFileName();
  1566. if ( pszResult && bEnsureExists && !saverestore->SaveFileExists( pszResult ) )
  1567. pszResult = NULL;
  1568. return pszResult;
  1569. }
  1570. void CEngineClient::SetMostRecentSaveGame( const char *lpszFilename )
  1571. {
  1572. saverestore->SetMostRecentSaveGame( lpszFilename );
  1573. }
  1574. //-----------------------------------------------------------------------------
  1575. // Called by gameui to hint the engine that an exiting process has started.
  1576. // The Engine needs to stabilize to a safe quiet state. More frames are going
  1577. // to and have to run, but the true exit will occur.
  1578. //-----------------------------------------------------------------------------
  1579. void CEngineClient::StartXboxExitingProcess()
  1580. {
  1581. if ( IsPC() )
  1582. {
  1583. // not for PC
  1584. return;
  1585. }
  1586. g_pInputSystem->StopRumble();
  1587. // save out the achievements
  1588. g_pAchievementMgr->SaveGlobalStateIfDirty();
  1589. // save out profile data
  1590. if ( g_pMatchFramework )
  1591. {
  1592. g_pMatchFramework->GetEventsSubscription()->BroadcastEvent( new KeyValues( "OnProfilesWriteOpportunity", "reason", "deactivation" ) );
  1593. }
  1594. S_StopAllSounds( true );
  1595. // Shutdown QMS, need to go back to single threaded
  1596. Host_AllowQueuedMaterialSystem( false );
  1597. }
  1598. bool CEngineClient::IsSaveInProgress()
  1599. {
  1600. return saverestore->IsSaveInProgress();
  1601. }
  1602. bool CEngineClient::IsAutoSaveDangerousInProgress()
  1603. {
  1604. return saverestore->IsAutoSaveDangerousInProgress();
  1605. }
  1606. bool CEngineClient::IsAutoSaveInProgress()
  1607. {
  1608. return saverestore->IsAutoSaveInProgress();
  1609. }
  1610. const char *CEngineClient::GetSaveDirName() // get a pointer to the path where saves should go (with a trailing slash already added)
  1611. {
  1612. return saverestore->GetSaveDir();
  1613. }
  1614. extern IXboxSystem *g_pXboxSystem;
  1615. //-----------------------------------------------------------------------------
  1616. // Purpose:
  1617. //-----------------------------------------------------------------------------
  1618. uint CEngineClient::OnStorageDeviceAttached( int iController )
  1619. {
  1620. return g_pXboxSystem->OpenContainers( iController );
  1621. }
  1622. //-----------------------------------------------------------------------------
  1623. // Purpose:
  1624. //-----------------------------------------------------------------------------
  1625. void CEngineClient::OnStorageDeviceDetached( int iController )
  1626. {
  1627. XBX_SetStorageDeviceId( iController, XBX_INVALID_STORAGE_ID );
  1628. g_pXboxSystem->CloseContainers( iController );
  1629. }
  1630. void CEngineClient::FinishContainerWrites( int iController )
  1631. {
  1632. g_pXboxSystem->FinishContainerWrites( iController );
  1633. }
  1634. void CEngineClient::FinishAsyncSave()
  1635. {
  1636. saverestore->FinishAsyncSave();
  1637. }
  1638. void CEngineClient::ResetDemoInterpolation( void )
  1639. {
  1640. if( demorecorder->IsRecording() )
  1641. demorecorder->ResetDemoInterpolation();
  1642. if (demoplayer->IsPlayingBack() )
  1643. demoplayer->ResetDemoInterpolation();
  1644. }
  1645. // For non-split screen games this will always be zero
  1646. int CEngineClient::GetActiveSplitScreenPlayerSlot()
  1647. {
  1648. return GET_ACTIVE_SPLITSCREEN_SLOT();
  1649. }
  1650. int CEngineClient::SetActiveSplitScreenPlayerSlot( int slot )
  1651. {
  1652. return splitscreen->SetActiveSplitScreenPlayerSlot( slot );
  1653. }
  1654. int CEngineClient::GetSplitScreenPlayer( int nSlot )
  1655. {
  1656. return splitscreen->GetSplitScreenPlayerEntity( nSlot );
  1657. }
  1658. bool CEngineClient::SetLocalPlayerIsResolvable( char const *pchContext, int nLine, bool bResolvable )
  1659. {
  1660. return splitscreen->SetLocalPlayerIsResolvable( pchContext, nLine, bResolvable );
  1661. }
  1662. bool CEngineClient::IsLocalPlayerResolvable()
  1663. {
  1664. return splitscreen->IsLocalPlayerResolvable();
  1665. }
  1666. bool CEngineClient::IsSplitScreenActive()
  1667. {
  1668. // Need a smarter way of doing this
  1669. for ( int i = 1; i < splitscreen->GetNumSplitScreenPlayers(); i++ )
  1670. {
  1671. if ( splitscreen->IsValidSplitScreenSlot( i ) )
  1672. {
  1673. return true;
  1674. }
  1675. }
  1676. return false;
  1677. }
  1678. bool CEngineClient::IsValidSplitScreenSlot( int nSlot )
  1679. {
  1680. return splitscreen->IsValidSplitScreenSlot( nSlot );
  1681. }
  1682. int CEngineClient::FirstValidSplitScreenSlot()
  1683. {
  1684. return splitscreen->FirstValidSplitScreenSlot();
  1685. }
  1686. int CEngineClient::NextValidSplitScreenSlot( int nPreviousSlot )
  1687. {
  1688. return splitscreen->NextValidSplitScreenSlot( nPreviousSlot );
  1689. }
  1690. ISPSharedMemory *CEngineClient::GetSinglePlayerSharedMemorySpace( const char *szName, int ent_num )
  1691. {
  1692. return g_pSinglePlayerSharedMemoryManager->GetSharedMemory( szName, ent_num );
  1693. }
  1694. void CEngineClient::RegisterDemoCustomDataCallback( string_t szCallbackSaveID, pfnDemoCustomDataCallback pCallback )
  1695. {
  1696. if( demorecorder->IsRecording() )
  1697. {
  1698. Warning( "Late registration of demo custom data callback.\n" );
  1699. AssertMsg( false, "Late registration of demo custom data callback." );
  1700. }
  1701. //binary search for the callback address. Couldn't directly use UtlSortVector because of the need to pair data and sort by only the callback
  1702. int start = 0, end = g_RegisteredDemoCustomDataCallbacks.Count() - 1;
  1703. RegisteredDemoCustomDataCallbackPair_t *pEntries = g_RegisteredDemoCustomDataCallbacks.Base();
  1704. while (start <= end)
  1705. {
  1706. int mid = (start + end) >> 1;
  1707. if ( pEntries[mid].pCallback < pCallback )
  1708. {
  1709. start = mid + 1;
  1710. }
  1711. else if ( pCallback < pEntries[mid].pCallback )
  1712. {
  1713. end = mid - 1;
  1714. }
  1715. else
  1716. {
  1717. //found the entry already
  1718. Warning( "Double registration of demo custom data callback.\n" );
  1719. AssertMsg( false, "Double registration of demo custom data callback." );
  1720. return;
  1721. }
  1722. }
  1723. RegisteredDemoCustomDataCallbackPair_t addPair;
  1724. addPair.pCallback = pCallback;
  1725. addPair.szSaveID = szCallbackSaveID;
  1726. g_RegisteredDemoCustomDataCallbacks.InsertBefore( start, addPair );
  1727. }
  1728. void CEngineClient::RecordDemoCustomData( pfnDemoCustomDataCallback pCallback, const void *pData, size_t iDataLength )
  1729. {
  1730. Assert( demorecorder->IsRecording() );
  1731. if( !demorecorder->IsRecording() )
  1732. {
  1733. Warning( "IEngineClient::RecordDemoCustomData(): Not recording a demo.\n" );
  1734. AssertMsg( false, "IEngineClient::RecordDemoCustomData(): Not recording a demo." );
  1735. }
  1736. //binary search for the callback address. Couldn't directly use UtlSortVector because of the need to pair data and sort by only the callback
  1737. int start = 0, end = g_RegisteredDemoCustomDataCallbacks.Count() - 1;
  1738. RegisteredDemoCustomDataCallbackPair_t *pEntries = g_RegisteredDemoCustomDataCallbacks.Base();
  1739. while (start <= end)
  1740. {
  1741. int mid = (start + end) >> 1;
  1742. if ( pEntries[mid].pCallback < pCallback )
  1743. {
  1744. start = mid + 1;
  1745. }
  1746. else if ( pCallback < pEntries[mid].pCallback )
  1747. {
  1748. end = mid - 1;
  1749. }
  1750. else
  1751. {
  1752. //record the data
  1753. demorecorder->RecordCustomData( mid, pData, iDataLength );
  1754. return;
  1755. }
  1756. }
  1757. Warning( "Demo recording custom data for unregistered callback.\n" );
  1758. AssertMsg( false, "Demo recording custom data for unregistered callback." );
  1759. }
  1760. void CEngineClient::SetTimescale( float flTimescale )
  1761. {
  1762. sv.SetTimescale( flTimescale );
  1763. }
  1764. extern CGamestatsData *g_pGamestatsData;
  1765. void CEngineClient::SetGamestatsData( CGamestatsData *pGamestatsData )
  1766. {
  1767. g_pGamestatsData = pGamestatsData;
  1768. }
  1769. CGamestatsData *CEngineClient::GetGamestatsData()
  1770. {
  1771. return g_pGamestatsData;
  1772. }
  1773. const char *CEngineClient::Key_LookupBindingEx( const char *pBinding, int iUserId, int iStartCount, BindingLookupOption_t nFlags )
  1774. {
  1775. return ::Key_NameForBinding( pBinding, iUserId, iStartCount, nFlags );
  1776. }
  1777. int CEngineClient::Key_CodeForBinding( const char *pBinding, int iUserId, int iStartCount, BindingLookupOption_t nFlags )
  1778. {
  1779. return ::Key_CodeForBinding( pBinding, iUserId, iStartCount, nFlags );
  1780. }
  1781. // --------------------------------------------------------------------
  1782. // ADSP
  1783. // --------------------------------------------------------------------
  1784. bool CEngineClient::DSPGetCurrentDASRoomNew(void)
  1785. {
  1786. return S_DSPGetCurrentDASRoomNew();
  1787. }
  1788. bool CEngineClient::DSPGetCurrentDASRoomChanged(void)
  1789. {
  1790. return S_DSPGetCurrentDASRoomChanged();
  1791. }
  1792. bool CEngineClient::DSPGetCurrentDASRoomSkyAbove(void)
  1793. {
  1794. return S_DSPGetCurrentDASRoomSkyAbove();
  1795. }
  1796. float CEngineClient::DSPGetCurrentDASRoomSkyPercent(void)
  1797. {
  1798. return S_DSPGetCurrentDASRoomSkyPercent();
  1799. }
  1800. // --------------------------------------------------------------------
  1801. // soundmixer
  1802. // --------------------------------------------------------------------
  1803. void CEngineClient::SetMixGroupOfCurrentMixer( const char *szgroupname, const char *szparam, float val, int setMixerType )
  1804. {
  1805. S_SetMixGroupOfCurrentMixer (szgroupname, szparam, val, setMixerType );
  1806. }
  1807. int CEngineClient::GetMixGroupIndex( const char *szmixgroupname )
  1808. {
  1809. return S_GetMixGroupIndex( szmixgroupname );
  1810. }
  1811. int CEngineClient::GetMixLayerIndex( const char *szmixlayername )
  1812. {
  1813. return S_GetMixLayerIndex( szmixlayername );
  1814. }
  1815. void CEngineClient::SetMixLayerLevel( int index, float level )
  1816. {
  1817. S_SetMixLayerLevel( index, level );
  1818. }
  1819. void CEngineClient::SetMixLayerTriggerFactor( const char *pLayerName, const char *pMixGroupName, float flFactor )
  1820. {
  1821. S_SetMixLayerTriggerFactor( pLayerName, pMixGroupName, flFactor );
  1822. }
  1823. void CEngineClient::SetMixLayerTriggerFactor( int nLayerIndex, int nMixGroupIndex, float flFactor )
  1824. {
  1825. S_SetMixLayerTriggerFactor( nLayerIndex, nMixGroupIndex, flFactor );
  1826. }
  1827. bool CEngineClient::SOSSetOpvarFloat( const char *pOpVarName, float flValue )
  1828. {
  1829. return S_SOSSetOpvarFloat( pOpVarName, flValue );
  1830. }
  1831. bool CEngineClient::SOSGetOpvarFloat( const char *pOpVarName, float &flValue )
  1832. {
  1833. return S_SOSGetOpvarFloat( pOpVarName, flValue );
  1834. }
  1835. bool CEngineClient::IsSubscribedMap( const char *pchMapName, bool bOnlyOnDisk )
  1836. {
  1837. return g_ClientDLL->IsSubscribedMap( pchMapName, bOnlyOnDisk );
  1838. }
  1839. bool CEngineClient::IsFeaturedMap( const char *pchMapName, bool bOnlyOnDisk )
  1840. {
  1841. return g_ClientDLL->IsFeaturedMap( pchMapName, bOnlyOnDisk );
  1842. }
  1843. // --------------------------------------------------------------------
  1844. //
  1845. // --------------------------------------------------------------------
  1846. bool CEngineClient::IsCreatingReslist()
  1847. {
  1848. return MapReslistGenerator().IsEnabled();
  1849. }
  1850. bool CEngineClient::IsCreatingXboxReslist()
  1851. {
  1852. return MapReslistGenerator().IsCreatingForXbox();
  1853. }
  1854. void CEngineClient::UpdateDAndELights( void )
  1855. {
  1856. CL_UpdateDAndELights( false );
  1857. }
  1858. extern IEngineBugReporter *bugreporter;
  1859. int CEngineClient::GetBugSubmissionCount( void ) const
  1860. {
  1861. if ( bugreporter )
  1862. {
  1863. return bugreporter->GetBugSubmissionCount();
  1864. }
  1865. return 0;
  1866. }
  1867. void CEngineClient::ClearBugSubmissionCount( void )
  1868. {
  1869. if ( bugreporter )
  1870. {
  1871. bugreporter->ClearBugSubmissionCount();
  1872. }
  1873. }
  1874. bool CEngineClient::DoesLevelContainWater() const
  1875. {
  1876. return host_state.worldbrush->numleafwaterdata != 0;
  1877. }
  1878. float Host_GetServerSimulationFrameTime();
  1879. float CEngineClient::GetServerSimulationFrameTime() const
  1880. {
  1881. return Host_GetServerSimulationFrameTime();
  1882. }
  1883. //-----------------------------------------------------------------------------
  1884. // Adds a handle to the list of entities to update when a partition query occurs
  1885. //-----------------------------------------------------------------------------
  1886. void CEngineClient::SolidMoved( IClientEntity *pSolidEnt, ICollideable *pSolidCollide, const Vector* pPrevAbsOrigin, bool accurateBboxTriggerChecks )
  1887. {
  1888. CL_SolidMoved( pSolidEnt, pSolidCollide, pPrevAbsOrigin, accurateBboxTriggerChecks );
  1889. }
  1890. void CEngineClient::TriggerMoved( IClientEntity *pTriggerEnt, bool accurateBboxTriggerChecks )
  1891. {
  1892. CL_TriggerMoved( pTriggerEnt, accurateBboxTriggerChecks );
  1893. }
  1894. void CEngineClient::ComputeLeavesConnected( const Vector &vecOrigin, int nCount, const int *pLeaves, bool *pIsConnected )
  1895. {
  1896. CM_LeavesConnected( vecOrigin, nCount, pLeaves, pIsConnected );
  1897. }
  1898. void CEngineClient::SetBlurFade( float scale )
  1899. {
  1900. g_ClientDLL->SetBlurFade( scale );
  1901. }
  1902. bool CEngineClient::IsTransitioningToLoad( void )
  1903. {
  1904. return HostState_IsTransitioningToLoad();
  1905. }
  1906. void CEngineClient::SearchPathsChangedAfterInstall( void )
  1907. {
  1908. // close caption system needs to re-establish
  1909. g_ClientDLL->ResetHudCloseCaption();
  1910. }
  1911. void CEngineClient::ConfigureSystemLevel( int nCPULevel, int nGPULevel )
  1912. {
  1913. StaticPropMgr()->ConfigureSystemLevel( nCPULevel, nGPULevel );
  1914. OverlayMgr()->UpdateOverlayRenderLevels( nCPULevel, nGPULevel );
  1915. }
  1916. void CEngineClient::SetConnectionPassword( char const *pchCurrentPW )
  1917. {
  1918. GetBaseLocalClient().SetConnectionPassword( pchCurrentPW );
  1919. }
  1920. CSteamAPIContext* CEngineClient::GetSteamAPIContext()
  1921. {
  1922. return &Steam3Client();
  1923. }
  1924. void CEngineClient::SubmitStatRecord( char const *szMapName, uint uiBlobVersion, uint uiBlobSize, const void *pvBlob )
  1925. {
  1926. AsyncUpload_QueueData( szMapName, uiBlobVersion, uiBlobSize, pvBlob );
  1927. }
  1928. void CEngineClient::ServerCmdKeyValues( KeyValues *pKeyValues )
  1929. {
  1930. GetLocalClient().SendServerCmdKeyValues( pKeyValues );
  1931. }
  1932. void CEngineClient::SendMessageToServer( INetMessage *pMessage, bool bForceReliable, bool bVoice )
  1933. {
  1934. GetLocalClient().SendNetMsg( *pMessage, bForceReliable, bVoice );
  1935. }
  1936. void CEngineClient::SetPitchScale( float flPitchScale )
  1937. {
  1938. S_SoundSetPitchScale( flPitchScale );
  1939. }
  1940. float CEngineClient::GetPitchScale( void )
  1941. {
  1942. return S_SoundGetPitchScale();
  1943. }
  1944. bool CEngineClient::LoadFilmmaker()
  1945. {
  1946. return toolframework->LoadFilmmaker();
  1947. }
  1948. void CEngineClient::UnloadFilmmaker()
  1949. {
  1950. toolframework->UnloadFilmmaker();
  1951. }
  1952. bool CEngineClient::SpherePaintSurface( const model_t *pModel, const Vector& vPosition, BYTE colorIndex, float flSphereRadius, float flPaintCoatPercent )
  1953. {
  1954. return ShootPaintSphere( pModel, vPosition, colorIndex, flSphereRadius, flPaintCoatPercent );
  1955. }
  1956. bool CEngineClient::HasPaintmap()
  1957. {
  1958. return g_PaintManager.m_bShouldRegister;
  1959. }
  1960. void CEngineClient::PaintAllSurfaces( BYTE color )
  1961. {
  1962. g_PaintManager.PaintAllSurfaces( color );
  1963. }
  1964. void CEngineClient::EnablePaintmapRender()
  1965. {
  1966. ConVar *cv = g_pCVar->FindVar("mat_paint_enabled");
  1967. if (cv)
  1968. {
  1969. cv->SetValue("1");
  1970. }
  1971. }
  1972. void CEngineClient::SphereTracePaintSurface( const model_t *pModel, const Vector& vPosition, const Vector& vContactNormal, float flSphereRadius, CUtlVector<BYTE>& surfColors )
  1973. {
  1974. TracePaintSphere( pModel, vPosition, vContactNormal, flSphereRadius, surfColors );
  1975. }
  1976. void CEngineClient::RemoveAllPaint()
  1977. {
  1978. g_PaintManager.RemoveAllPaint();
  1979. }
  1980. void CEngineClient::RemovePaint( const model_t *pModel )
  1981. {
  1982. g_PaintManager.RemovePaint( pModel );
  1983. }
  1984. bool CEngineClient::IsClientLocalToActiveServer()
  1985. {
  1986. return sv.IsActive() || sv.IsLoading();
  1987. }
  1988. bool CEngineClient::IsActiveApp( void )
  1989. {
  1990. return game->IsActiveApp();
  1991. }
  1992. // Callback for LevelInit to tick the progress bar during time consuming operations
  1993. void CEngineClient::TickProgressBar()
  1994. {
  1995. EngineVGui()->UpdateProgressBar( PROGRESS_DEFAULT );
  1996. }
  1997. // Returns the requested input context
  1998. InputContextHandle_t CEngineClient::GetInputContext( EngineInputContextId_t id )
  1999. {
  2000. switch( id )
  2001. {
  2002. case ENGINE_INPUT_CONTEXT_GAME:
  2003. return GetGameInputContext();
  2004. case ENGINE_INPUT_CONTEXT_GAMEUI:
  2005. return EngineVGui()->GetGameUIInputContext();
  2006. }
  2007. return INPUT_CONTEXT_HANDLE_INVALID;
  2008. }
  2009. #define MAX_GENERIC_MEMORY_STATS 64
  2010. GenericMemoryStat_t g_EngineMemStats[MAX_GENERIC_MEMORY_STATS];
  2011. int g_nEngineMemStats = 0;
  2012. static inline int AddGenericMemoryStat( const char *name, int value )
  2013. {
  2014. Assert( g_nEngineMemStats < MAX_GENERIC_MEMORY_STATS );
  2015. if ( g_nEngineMemStats < MAX_GENERIC_MEMORY_STATS )
  2016. {
  2017. g_EngineMemStats[ g_nEngineMemStats ].name = name;
  2018. g_EngineMemStats[ g_nEngineMemStats ].value = value;
  2019. g_nEngineMemStats++;
  2020. }
  2021. return g_nEngineMemStats;
  2022. }
  2023. int CEngineClient::GetGenericMemoryStats( GenericMemoryStat_t **ppMemoryStats )
  2024. {
  2025. if ( !ppMemoryStats )
  2026. return 0;
  2027. g_nEngineMemStats = 0;
  2028. AddGenericMemoryStat( "Hunk", Hunk_Size() );
  2029. #ifdef _GAMECONSOLE
  2030. if ( host_state.worldbrush )
  2031. {
  2032. AddGenericMemoryStat( "BSP", host_state.worldbrush->m_nBSPFileSize );
  2033. AddGenericMemoryStat( "LM_lump", host_state.worldbrush->m_nLightingDataSize );
  2034. }
  2035. #endif // _GAMECONSOLE
  2036. *ppMemoryStats = &g_EngineMemStats[0];
  2037. return g_nEngineMemStats;
  2038. }
  2039. void CEngineClient::AudioLanguageChanged()
  2040. {
  2041. S_PurgeSoundsDueToLanguageChange();
  2042. }
  2043. void CEngineClient::StartLoadingScreenForCommand( const char* command )
  2044. {
  2045. EngineVGui()->StartLoadingScreenForCommand( command );
  2046. }
  2047. void CEngineClient::StartLoadingScreenForKeyValues( KeyValues* keyValues )
  2048. {
  2049. EngineVGui()->StartLoadingScreenForKeyValues( keyValues );
  2050. }
  2051. #if defined(_PS3)
  2052. void* CEngineClient::GetHostStateWorldBrush( void )
  2053. {
  2054. return host_state.worldbrush;
  2055. }
  2056. #endif
  2057. int CEngineClient::GetClientVersion() const
  2058. {
  2059. return ::GetClientVersion();
  2060. }
  2061. float CEngineClient::GetSafeZoneXMin( void ) const
  2062. {
  2063. float flMin = 0.85f;
  2064. int nHeight = videomode->GetModeHeight();
  2065. int nWidth = videomode->GetModeWidth();
  2066. if ( (float)nHeight / (float)nWidth < 0.26f )
  2067. flMin = 0.28f;
  2068. else if ( (float)nHeight / (float)nWidth < 0.56f )
  2069. flMin = 0.475f;
  2070. return flMin;
  2071. }
  2072. bool CEngineClient::IsVoiceRecording() const
  2073. {
  2074. return Voice_IsRecording();
  2075. }
  2076. void CEngineClient::ForceVoiceRecordOn() const
  2077. {
  2078. #if !defined( NO_VOICE )
  2079. if ( GetBaseLocalClient().IsActive() && Voice_IsRecording() == false )
  2080. {
  2081. const char *pUncompressedFile = NULL;
  2082. const char *pDecompressedFile = NULL;
  2083. const char *pInputFile = NULL;
  2084. //if (voice_recordtofile.GetInt())
  2085. //{
  2086. // pUncompressedFile = "voice_micdata.wav";
  2087. // pDecompressedFile = "voice_decompressed.wav";
  2088. //}
  2089. //if (voice_inputfromfile.GetInt())
  2090. //{
  2091. // pInputFile = "voice_input.wav";
  2092. //}
  2093. Voice_RecordStart( pUncompressedFile, pDecompressedFile, pInputFile );
  2094. }
  2095. #endif
  2096. }
  2097. const char* CEngineClient::AliasToCommandString( const char* szAliasName )
  2098. {
  2099. return Cmd_AliasToCommandString( szAliasName );
  2100. }
  2101. //-----------------------------------------------------------------------------
  2102. // The client DLL serves out this interface
  2103. //-----------------------------------------------------------------------------
  2104. IBaseClientDLL *g_ClientDLL = NULL;
  2105. IPrediction *g_pClientSidePrediction = NULL;
  2106. IClientRenderTargets *g_pClientRenderTargets = NULL;
  2107. IClientEntityList *entitylist = NULL;
  2108. IClientLeafSystemEngine *clientleafsystem = NULL;
  2109. IClientAlphaPropertyMgr *g_pClientAlphaPropertyMgr = NULL;
  2110. ClientClass *g_pClientClassHead = NULL;
  2111. ClientClass *ClientDLL_GetAllClasses( void )
  2112. {
  2113. if ( g_ClientDLL )
  2114. return g_ClientDLL->GetAllClasses();
  2115. else
  2116. return g_pClientClassHead;
  2117. }
  2118. static void ClientDLL_InitRecvTableMgr()
  2119. {
  2120. // Register all the receive tables.
  2121. RecvTable *pRecvTables[MAX_DATATABLES];
  2122. int nRecvTables = 0;
  2123. for ( ClientClass *pCur = ClientDLL_GetAllClasses(); pCur; pCur=pCur->m_pNext )
  2124. {
  2125. ErrorIfNot(
  2126. nRecvTables < ARRAYSIZE( pRecvTables ),
  2127. ("ClientDLL_InitRecvTableMgr: overflowed MAX_DATATABLES")
  2128. );
  2129. pRecvTables[nRecvTables] = pCur->m_pRecvTable;
  2130. ++nRecvTables;
  2131. }
  2132. RecvTable_Init( pRecvTables, nRecvTables );
  2133. }
  2134. static void ClientDLL_ShutdownRecvTableMgr()
  2135. {
  2136. RecvTable_Term();
  2137. }
  2138. CreateInterfaceFn ClientDLL_GetFactory( void )
  2139. {
  2140. return g_ClientFactory;
  2141. }
  2142. //-----------------------------------------------------------------------------
  2143. // Purpose: Loads the client DLL. Must return false if failed on PS3, to let the game output error screen before quitting to XMB
  2144. // Input : -
  2145. //-----------------------------------------------------------------------------
  2146. bool ClientDLL_Load()
  2147. {
  2148. Assert ( !g_ClientDLLModule );
  2149. // Check the signature on the client dll. If this fails we load it anyway but put this client
  2150. // into insecure mode so it won't connect to secure servers and get VAC banned
  2151. // #if 0 the following block and rebuild engine.dll if you want to build your own noCEG client.dll and run on Steam Public in secure mode!
  2152. #if 1
  2153. if ( !Host_AllowLoadModule( "client" DLL_EXT_STRING, "GAMEBIN", false ) )
  2154. {
  2155. // not supposed to load this but we will anyway
  2156. Host_DisallowSecureServers();
  2157. }
  2158. #endif
  2159. // loads the client.dll, but ensures that the client dll is running under Steam
  2160. // this will have to be undone when we want mods to be able to run
  2161. g_ClientDLLModule = g_pFileSystem->LoadModule( "client" DLL_EXT_STRING, "GAMEBIN", false );
  2162. if ( g_ClientDLLModule )
  2163. {
  2164. g_ClientFactory = Sys_GetFactory( g_ClientDLLModule );
  2165. if ( g_ClientFactory )
  2166. {
  2167. g_ClientDLL = (IBaseClientDLL *)g_ClientFactory( CLIENT_DLL_INTERFACE_VERSION, NULL );
  2168. // this is to ensure the old format of the string table is used for clients version 13 and older.
  2169. // when the client version gets revved, there will need to be an else that sets this bool to true
  2170. // TERROR: g_bClientGameDLLGreaterThanV13 is true, so we get better stringtables
  2171. g_bClientGameDLLGreaterThanV13 = true;
  2172. if ( !g_ClientDLL )
  2173. {
  2174. if( IsPS3() )
  2175. {
  2176. return false;
  2177. }
  2178. else
  2179. {
  2180. Sys_Error( "Could not get client.dll interface from library client" );
  2181. }
  2182. }
  2183. }
  2184. else
  2185. {
  2186. if( IsPS3() )
  2187. {
  2188. return false;
  2189. }
  2190. else
  2191. {
  2192. Sys_Error( "Could not find factory interface in library client" );
  2193. }
  2194. }
  2195. }
  2196. else
  2197. {
  2198. // library failed to load
  2199. if( IsPS3() )
  2200. {
  2201. return false;
  2202. }
  2203. else
  2204. {
  2205. Sys_Error( "Could not load library client" );
  2206. }
  2207. }
  2208. // Load the client render targets interface from the client .dll
  2209. // NOTE: Its OK if this returns NULL, as some mods won't provide the interface and will just use the default behavior of the engine
  2210. g_pClientRenderTargets = ( IClientRenderTargets * )g_ClientFactory( CLIENTRENDERTARGETS_INTERFACE_VERSION, NULL );
  2211. return g_pClientRenderTargets != NULL;
  2212. }
  2213. void ClientDLL_GameInit()
  2214. {
  2215. if ( g_ClientDLL )
  2216. {
  2217. // g_ClientDLL->GameInit();
  2218. }
  2219. }
  2220. void ClientDLL_GameShutdown()
  2221. {
  2222. if ( g_ClientDLL )
  2223. {
  2224. // g_ClientDLL->GameShutdown();
  2225. }
  2226. }
  2227. void ClientDLL_Connect( void )
  2228. {
  2229. if ( g_ClientDLL )
  2230. {
  2231. g_ClientDLL->Connect( g_AppSystemFactory, &g_ClientGlobalVariables );
  2232. }
  2233. }
  2234. void ClientDLL_Disconnect()
  2235. {
  2236. if( g_ClientDLL )
  2237. {
  2238. g_ClientDLL->Disconnect();
  2239. }
  2240. }
  2241. //-----------------------------------------------------------------------------
  2242. // Purpose: Inits the client .dll
  2243. //-----------------------------------------------------------------------------
  2244. void ClientDLL_Init( void )
  2245. {
  2246. extern void CL_SetSteamCrashComment();
  2247. // Assert ClientDLL_Load successfully created these interfaces, as we need them to init properly
  2248. Assert ( g_ClientDLL );
  2249. Assert ( g_ClientFactory );
  2250. // this will get updated after we load a map, but this gets video info if we sys_error() prior to loading a map
  2251. CL_SetSteamCrashComment();
  2252. if ( g_ClientDLL )
  2253. {
  2254. COM_TimestampedLog( "g_ClientDLL->Init" );
  2255. if ( !g_ClientDLL->Init( g_GameSystemFactory, &g_ClientGlobalVariables ) )
  2256. {
  2257. Sys_Error("Client.dll Init() in library client failed.");
  2258. }
  2259. if ( g_ClientFactory )
  2260. {
  2261. COM_TimestampedLog( "g_pClientSidePrediction->Init" );
  2262. // Load the prediction interface from the client .dll
  2263. g_pClientSidePrediction = (IPrediction *)g_ClientFactory( VCLIENT_PREDICTION_INTERFACE_VERSION, NULL );
  2264. if ( !g_pClientSidePrediction )
  2265. {
  2266. Sys_Error( "Could not get IPrediction interface from library client" );
  2267. }
  2268. g_pClientSidePrediction->Init();
  2269. entitylist = ( IClientEntityList *)g_ClientFactory( VCLIENTENTITYLIST_INTERFACE_VERSION, NULL );
  2270. if ( !entitylist )
  2271. {
  2272. Sys_Error( "Could not get client entity list interface from library client" );
  2273. }
  2274. clientleafsystem = ( IClientLeafSystemEngine *)g_ClientFactory( CLIENTLEAFSYSTEM_INTERFACE_VERSION, NULL );
  2275. if ( !clientleafsystem )
  2276. {
  2277. Sys_Error( "Could not get client leaf system interface from library client" );
  2278. }
  2279. g_pClientAlphaPropertyMgr = ( IClientAlphaPropertyMgr* )g_ClientFactory( CLIENT_ALPHA_PROPERTY_MGR_INTERFACE_VERSION, NULL );
  2280. if ( !g_pClientAlphaPropertyMgr )
  2281. {
  2282. Sys_Error( "Could not get client alpha property mgr interface from library client" );
  2283. }
  2284. toolframework->ClientInit( g_ClientFactory );
  2285. }
  2286. if ( g_pMaterialSystemHardwareConfig && !IsGameConsole( ) )
  2287. {
  2288. char pMessage[1024];
  2289. pMessage[0] = '\0';
  2290. bool bFailed = false;
  2291. // We only run on hardware that supports shader model 3.0 (dxlevel 95) or later
  2292. // @wge: HACK FIXME - Not doing this on MacOSX for now...
  2293. if ( ( g_pMaterialSystemHardwareConfig->GetDXSupportLevel() < 95 ) && IsPC() && !IsOSX() && !IsOpenGL() ) // TODO: Need to remove the IsPC() before shipping once the Mac work is complete (mac is 92 right now)
  2294. {
  2295. wchar_t wcMessage[512];
  2296. g_pVGuiLocalize->ConstructString( wcMessage, sizeof( wcMessage ), g_pVGuiLocalize->Find( "#Valve_MinShaderModel3" ), 0 );
  2297. g_pVGuiLocalize->ConvertUnicodeToANSI( wcMessage, pMessage, sizeof( pMessage ) );
  2298. bFailed = true;
  2299. }
  2300. #ifdef CSTRIKE15
  2301. // CS:GO requires CSM support for fairness. (This is primarily here in case the user is hacking/copying their moddefaults.txt or dxsupport.cfg from another product).
  2302. else if ( !g_pMaterialSystemHardwareConfig->SupportsCascadedShadowMapping() )
  2303. {
  2304. wchar_t wcMessage[512];
  2305. g_pVGuiLocalize->ConstructString( wcMessage, sizeof( wcMessage ), g_pVGuiLocalize->Find( "#Valve_CardMustSupportCSM" ), 0 );
  2306. g_pVGuiLocalize->ConvertUnicodeToANSI( wcMessage, pMessage, sizeof( pMessage ) );
  2307. bFailed = true;
  2308. }
  2309. #endif
  2310. // Allow the user to disable this check when testing internally (but not on steam public), typically when using remote desktop.
  2311. // FIXME: Don't ship this
  2312. //if ( ( GetSteamUniverse() != k_EUniversePublic ) && ( CommandLine()->CheckParm( "-nodevicechecks" ) ) )
  2313. /*
  2314. if ( CommandLine()->CheckParm( "-nodevicechecks" ) )
  2315. {
  2316. bFailed = false;
  2317. }
  2318. */
  2319. if ( bFailed )
  2320. {
  2321. #ifdef _WIN32
  2322. if ( g_pMaterialSystemConfig && materials )
  2323. {
  2324. MaterialAdapterInfo_t info;
  2325. materials->GetDisplayAdapterInfo( materials->GetCurrentAdapter(), info );
  2326. char pDeviceInfo[1024];
  2327. if ( g_pMaterialSystemHardwareConfig )
  2328. {
  2329. sprintf_s( pDeviceInfo, "\n\nDevice Info:\nMarked unsupported: %i\nSupports PCF Sampling: %i\nDriverName: \"%s\"\nVendorID: 0x%04X, DeviceID: 0x%04X\nDriverHigh: 0x%08X, DriverLow: 0x%08X\nDXLevel: %u, MinDXSupportLevel: %u, MaxDXSupportLevel: %u\n",
  2330. g_pMaterialSystemConfig->IsUnsupported() || (g_pMaterialSystemHardwareConfig->IsUnsupported()),
  2331. g_pMaterialSystemHardwareConfig->SupportsBilinearPCFSampling(),
  2332. info.m_pDriverName ? info.m_pDriverName : "?",
  2333. info.m_VendorID,
  2334. info.m_DeviceID,
  2335. info.m_nDriverVersionHigh,
  2336. info.m_nDriverVersionLow,
  2337. g_pMaterialSystemHardwareConfig->GetDXSupportLevel(),
  2338. g_pMaterialSystemHardwareConfig->GetMinDXSupportLevel(),
  2339. g_pMaterialSystemHardwareConfig->GetMaxDXSupportLevel() );
  2340. }
  2341. else
  2342. {
  2343. sprintf_s( pDeviceInfo, "\n\nDevice Info:\nMarked unsupported: %i\nDriverName: \"%s\"\nVendorID: 0x%04X, DeviceID: 0x%04X\nDriverHigh: 0x%08X, DriverLow: 0x%08X\n\n",
  2344. g_pMaterialSystemConfig->IsUnsupported(),
  2345. info.m_pDriverName ? info.m_pDriverName : "?",
  2346. info.m_VendorID,
  2347. info.m_DeviceID,
  2348. info.m_nDriverVersionHigh,
  2349. info.m_nDriverVersionLow
  2350. );
  2351. }
  2352. V_strcat( pMessage, pDeviceInfo, sizeof( pMessage ) );
  2353. }
  2354. #endif
  2355. Sys_Error( "%s", pMessage );
  2356. }
  2357. // Display a warning message (purposely not an error) if the card has been marked as unsupported in dxsupport.cfg.
  2358. // If we got this far then the card is SM3 capable and supports bilinear PCF sampling, so let them try.
  2359. if ( !CommandLine()->CheckParm( "-nounsupportedgpuchecks" ) )
  2360. {
  2361. if ( ( g_pMaterialSystemConfig && g_pMaterialSystemConfig->IsUnsupported() ) || ( g_pMaterialSystemHardwareConfig && g_pMaterialSystemHardwareConfig->IsUnsupported() ) )
  2362. {
  2363. wchar_t wcMessage[512];
  2364. g_pVGuiLocalize->ConstructString( wcMessage, sizeof( wcMessage ), g_pVGuiLocalize->Find( "#Valve_UnsupportedCard" ), 0 );
  2365. g_pVGuiLocalize->ConvertUnicodeToANSI( wcMessage, pMessage, sizeof( pMessage ) );
  2366. // Make sure the warning message is visible in full-screen mode (otherwise the game appears like it's locked up).
  2367. const bool bIsFullScreen = (videomode && !videomode->IsWindowedMode());
  2368. if ( bIsFullScreen )
  2369. videomode->ReleaseVideo();
  2370. Sys_MessageBox( pMessage, NULL, false );
  2371. if ( bIsFullScreen )
  2372. videomode->RestoreVideo();
  2373. }
  2374. }
  2375. }
  2376. }
  2377. COM_TimestampedLog( "ClientDLL_InitRecvTableMgr" );
  2378. ClientDLL_InitRecvTableMgr();
  2379. }
  2380. //-----------------------------------------------------------------------------
  2381. // Purpose: Shuts down the client .dll
  2382. //-----------------------------------------------------------------------------
  2383. void ClientDLL_Shutdown( void )
  2384. {
  2385. toolframework->ClientShutdown();
  2386. ClientDLL_ShutdownRecvTableMgr();
  2387. {
  2388. FORCE_DEFAULT_SPLITSCREEN_PLAYER_GUARD;
  2389. vgui::ivgui()->RunFrame();
  2390. materials->UncacheAllMaterials();
  2391. vgui::ivgui()->RunFrame();
  2392. }
  2393. if( g_pClientSidePrediction )
  2394. {
  2395. g_pClientSidePrediction->Shutdown();
  2396. }
  2397. entitylist = NULL;
  2398. g_pClientSidePrediction = NULL;
  2399. g_ClientFactory = NULL;
  2400. g_ClientDLL->Shutdown();
  2401. }
  2402. //-----------------------------------------------------------------------------
  2403. // Purpose: Unloads the client .dll
  2404. // Input : -
  2405. //-----------------------------------------------------------------------------
  2406. void ClientDLL_Unload()
  2407. {
  2408. // Unfortunately, appsystem framework does not disconnect client in the order opposite
  2409. // of the creation, because the client is initialized and created/connected
  2410. // in special code path. So we disconnect it here for good measure: when
  2411. // scenefilecache fails to load, the client is fully connected, but app framework
  2412. // doesn't know about it.
  2413. ClientDLL_Disconnect();
  2414. FileSystem_UnloadModule( g_ClientDLLModule );
  2415. g_ClientDLL = NULL;
  2416. g_ClientDLLModule = NULL;
  2417. g_pClientRenderTargets = NULL;
  2418. }
  2419. //-----------------------------------------------------------------------------
  2420. // Purpose: Called when the game initializes and whenever the vid_mode is changed
  2421. // so the HUD can reinitialize itself.
  2422. //-----------------------------------------------------------------------------
  2423. void ClientDLL_HudVidInit( void )
  2424. {
  2425. g_ClientDLL->HudVidInit();
  2426. }
  2427. //-----------------------------------------------------------------------------
  2428. // Purpose: Allow client .dll to modify input data
  2429. //-----------------------------------------------------------------------------
  2430. void ClientDLL_ProcessInput( void )
  2431. {
  2432. SNPROF("ClientDLL_ProcessInput");
  2433. if ( !g_ClientDLL )
  2434. return;
  2435. VPROF("ClientDLL_ProcessInput");
  2436. FOR_EACH_VALID_SPLITSCREEN_PLAYER( i )
  2437. {
  2438. ACTIVE_SPLITSCREEN_PLAYER_GUARD( i );
  2439. g_ClientDLL->HudProcessInput( GetLocalClient().IsConnected() );
  2440. }
  2441. #ifdef _PS3
  2442. if( g_pDebugInputThread && !g_pDebugInputThread->m_inputString.IsEmpty() )
  2443. {
  2444. AUTO_LOCK( g_pDebugInputThread->m_mx );
  2445. Cbuf_AddText( Cbuf_GetCurrentPlayer(), g_pDebugInputThread->m_inputString.Get(), kCommandSrcConsoleBuffer );
  2446. g_pDebugInputThread->m_inputString.Purge();
  2447. }
  2448. #endif
  2449. }
  2450. void ClientDLL_FrameStageNotify( ClientFrameStage_t frameStage )
  2451. {
  2452. if ( !g_ClientDLL )
  2453. return;
  2454. g_ClientDLL->FrameStageNotify( frameStage );
  2455. }
  2456. //-----------------------------------------------------------------------------
  2457. // Purpose: Allow client .dll to think
  2458. //-----------------------------------------------------------------------------
  2459. void ClientDLL_Update( void )
  2460. {
  2461. if ( sv.IsDedicated() )
  2462. return;
  2463. if ( g_ClientDLL )
  2464. {
  2465. g_ClientDLL->HudUpdate( true );
  2466. }
  2467. }
  2468. void ClientDLL_VoiceStatus( int entindex, int iSsSlot, bool bTalking )
  2469. {
  2470. if( g_ClientDLL )
  2471. {
  2472. g_ClientDLL->VoiceStatus( entindex, iSsSlot, bTalking );
  2473. }
  2474. }
  2475. bool ClientDLL_IsPlayerAudible( int iPlayerIndex )
  2476. {
  2477. if( g_ClientDLL )
  2478. {
  2479. return g_ClientDLL->PlayerAudible( iPlayerIndex );
  2480. }
  2481. return false;
  2482. }
  2483. void ClientDLL_OnActiveSplitscreenPlayerChanged( int slot )
  2484. {
  2485. if( g_ClientDLL )
  2486. {
  2487. g_ClientDLL->OnActiveSplitscreenPlayerChanged( slot );
  2488. }
  2489. }
  2490. void ClientDLL_OnSplitScreenStateChanged()
  2491. {
  2492. if( g_ClientDLL )
  2493. {
  2494. g_ClientDLL->OnSplitScreenStateChanged();
  2495. }
  2496. }
  2497. int ClientDLL_GetSpectatorTarget( ClientDLLObserverMode_t *pObserverMode )
  2498. {
  2499. if( g_ClientDLL )
  2500. {
  2501. return g_ClientDLL->GetSpectatorTarget( pObserverMode );
  2502. }
  2503. if ( pObserverMode )
  2504. {
  2505. *pObserverMode = CLIENT_DLL_OBSERVER_NONE;
  2506. }
  2507. return -1;
  2508. }
  2509. vgui::VPANEL ClientDLL_GetFullscreenClientDLLVPanel( void )
  2510. {
  2511. if ( g_ClientDLL )
  2512. {
  2513. return g_ClientDLL->GetFullscreenClientDLLVPanel();
  2514. }
  2515. return false;
  2516. }
  2517. #if defined ( _PS3 )
  2518. // note: We assume if we aren't connected or initialized, that the chat is NOT restricted
  2519. bool CEngineClient::PS3_IsUserRestrictedFromChat( void )
  2520. {
  2521. return EngineHelperPS3::PS3_IsUserRestrictedFromChat();
  2522. }
  2523. // NOTE: If we're not signed in yet, or not initialized, we consider this as not restricted from online
  2524. bool CEngineClient::PS3_IsUserRestrictedFromOnline( void )
  2525. {
  2526. return EngineHelperPS3::PS3_IsUserRestrictedFromOnline();
  2527. }
  2528. bool CEngineClient::PS3_PendingInvitesFound( void )
  2529. {
  2530. return EngineHelperPS3::PS3_PendingInvitesFound();
  2531. }
  2532. void CEngineClient::PS3_ShowInviteOverlay( void )
  2533. {
  2534. EngineHelperPS3::PS3_ShowInviteOverlay();
  2535. }
  2536. #endif // _PS3