From 0a180821d9391c0138712b6c4cbc56dcfc2c9d36 Mon Sep 17 00:00:00 2001 From: Sam V Date: Thu, 18 Nov 2021 15:03:44 +0100 Subject: [PATCH 01/13] Remove unused nodes.h includes and unncessary WorldGraph forward declarations Remove references to WorldGraph global inside CGraph class #37 Resolves #48 --- cl_dll/hl/hl_weapons.cpp | 1 - dlls/airtank.cpp | 1 - dlls/apache.cpp | 1 - dlls/crossbow.cpp | 1 - dlls/crowbar.cpp | 1 - dlls/defaultai.cpp | 1 - dlls/egon.cpp | 1 - dlls/gargantua.cpp | 1 - dlls/gauss.cpp | 1 - dlls/ggrenade.cpp | 1 - dlls/handgrenade.cpp | 1 - dlls/healthkit.cpp | 1 - dlls/hornetgun.cpp | 1 - dlls/houndeye.cpp | 2 -- dlls/ichthyosaur.cpp | 2 -- dlls/monsters.cpp | 4 ---- dlls/monsterstate.cpp | 1 - dlls/mp5.cpp | 1 - dlls/nodes.cpp | 8 ++++---- dlls/osprey.cpp | 1 - dlls/player.cpp | 3 --- dlls/rpg.cpp | 1 - dlls/satchel.cpp | 1 - dlls/schedule.cpp | 2 -- dlls/shotgun.cpp | 1 - dlls/squadmonster.cpp | 1 - dlls/squeakgrenade.cpp | 1 - dlls/subs.cpp | 2 -- dlls/tripmine.cpp | 1 - dlls/weapons.cpp | 2 -- dlls/world.cpp | 1 - dlls/wpn_shared/hl_wpn_glock.cpp | 1 - 32 files changed, 4 insertions(+), 45 deletions(-) diff --git a/cl_dll/hl/hl_weapons.cpp b/cl_dll/hl/hl_weapons.cpp index 259bc019f..9f6e5c6d5 100644 --- a/cl_dll/hl/hl_weapons.cpp +++ b/cl_dll/hl/hl_weapons.cpp @@ -17,7 +17,6 @@ #include "cbase.h" #include "monsters.h" #include "weapons.h" -#include "nodes.h" #include "player.h" #include "usercmd.h" diff --git a/dlls/airtank.cpp b/dlls/airtank.cpp index 3c870b7a7..d27c56d98 100644 --- a/dlls/airtank.cpp +++ b/dlls/airtank.cpp @@ -17,7 +17,6 @@ #include "cbase.h" #include "monsters.h" #include "weapons.h" -#include "nodes.h" #include "player.h" class CAirtank : public CGrenade diff --git a/dlls/apache.cpp b/dlls/apache.cpp index 3d2810faf..c34eeee4f 100644 --- a/dlls/apache.cpp +++ b/dlls/apache.cpp @@ -18,7 +18,6 @@ #include "cbase.h" #include "monsters.h" #include "weapons.h" -#include "nodes.h" #include "effects.h" extern DLL_GLOBAL int g_iSkillLevel; diff --git a/dlls/crossbow.cpp b/dlls/crossbow.cpp index 6101abe8c..c160e922f 100644 --- a/dlls/crossbow.cpp +++ b/dlls/crossbow.cpp @@ -18,7 +18,6 @@ #include "cbase.h" #include "monsters.h" #include "weapons.h" -#include "nodes.h" #include "player.h" #include "gamerules.h" #include "UserMessages.h" diff --git a/dlls/crowbar.cpp b/dlls/crowbar.cpp index 053a94e14..569fef3f2 100644 --- a/dlls/crowbar.cpp +++ b/dlls/crowbar.cpp @@ -18,7 +18,6 @@ #include "cbase.h" #include "monsters.h" #include "weapons.h" -#include "nodes.h" #include "player.h" #include "gamerules.h" diff --git a/dlls/defaultai.cpp b/dlls/defaultai.cpp index 6f231ad19..fee2d805e 100644 --- a/dlls/defaultai.cpp +++ b/dlls/defaultai.cpp @@ -22,7 +22,6 @@ #include "schedule.h" #include "defaultai.h" #include "soundent.h" -#include "nodes.h" #include "scripted.h" //========================================================= diff --git a/dlls/egon.cpp b/dlls/egon.cpp index fd06af30c..0a0c1dd8e 100644 --- a/dlls/egon.cpp +++ b/dlls/egon.cpp @@ -19,7 +19,6 @@ #include "player.h" #include "monsters.h" #include "weapons.h" -#include "nodes.h" #include "effects.h" #include "customentity.h" #include "gamerules.h" diff --git a/dlls/gargantua.cpp b/dlls/gargantua.cpp index db94a7556..3f11183c7 100644 --- a/dlls/gargantua.cpp +++ b/dlls/gargantua.cpp @@ -19,7 +19,6 @@ #include "extdll.h" #include "util.h" #include "cbase.h" -#include "nodes.h" #include "monsters.h" #include "schedule.h" #include "customentity.h" diff --git a/dlls/gauss.cpp b/dlls/gauss.cpp index 0fbdc263f..70e329b48 100644 --- a/dlls/gauss.cpp +++ b/dlls/gauss.cpp @@ -18,7 +18,6 @@ #include "cbase.h" #include "monsters.h" #include "weapons.h" -#include "nodes.h" #include "player.h" #include "soundent.h" #include "shake.h" diff --git a/dlls/ggrenade.cpp b/dlls/ggrenade.cpp index 8f2681267..6765a7b42 100644 --- a/dlls/ggrenade.cpp +++ b/dlls/ggrenade.cpp @@ -23,7 +23,6 @@ #include "cbase.h" #include "monsters.h" #include "weapons.h" -#include "nodes.h" #include "soundent.h" #include "decals.h" diff --git a/dlls/handgrenade.cpp b/dlls/handgrenade.cpp index a1249e0c9..5e53d38a4 100644 --- a/dlls/handgrenade.cpp +++ b/dlls/handgrenade.cpp @@ -17,7 +17,6 @@ #include "cbase.h" #include "monsters.h" #include "weapons.h" -#include "nodes.h" #include "player.h" diff --git a/dlls/healthkit.cpp b/dlls/healthkit.cpp index 17fd36534..ddb3c8aa1 100644 --- a/dlls/healthkit.cpp +++ b/dlls/healthkit.cpp @@ -17,7 +17,6 @@ #include "cbase.h" #include "monsters.h" #include "weapons.h" -#include "nodes.h" #include "player.h" #include "items.h" #include "gamerules.h" diff --git a/dlls/hornetgun.cpp b/dlls/hornetgun.cpp index 97b407076..f4c56a4a0 100644 --- a/dlls/hornetgun.cpp +++ b/dlls/hornetgun.cpp @@ -18,7 +18,6 @@ #include "cbase.h" #include "monsters.h" #include "weapons.h" -#include "nodes.h" #include "player.h" #include "hornet.h" #include "gamerules.h" diff --git a/dlls/houndeye.cpp b/dlls/houndeye.cpp index 9176f60f7..46dc6d270 100644 --- a/dlls/houndeye.cpp +++ b/dlls/houndeye.cpp @@ -27,8 +27,6 @@ #include "soundent.h" #include "game.h" -extern CGraph WorldGraph; - // houndeye does 20 points of damage spread over a sphere 384 units in diameter, and each additional // squad member increases the BASE damage by 110%, per the spec. #define HOUNDEYE_MAX_SQUAD_SIZE 4 diff --git a/dlls/ichthyosaur.cpp b/dlls/ichthyosaur.cpp index ffc4808c3..8f390c19b 100644 --- a/dlls/ichthyosaur.cpp +++ b/dlls/ichthyosaur.cpp @@ -33,8 +33,6 @@ #define ICHTHYOSAUR_SPEED 150 -extern CGraph WorldGraph; - #define EYE_MAD 0 #define EYE_BASE 1 #define EYE_CLOSED 2 diff --git a/dlls/monsters.cpp b/dlls/monsters.cpp index 9379d0f64..26eebf599 100644 --- a/dlls/monsters.cpp +++ b/dlls/monsters.cpp @@ -43,10 +43,6 @@ extern DLL_GLOBAL BOOL g_fDrawLines; extern DLL_GLOBAL short g_sModelIndexLaser;// holds the index for the laser beam extern DLL_GLOBAL short g_sModelIndexLaserDot;// holds the index for the laser beam dot -extern CGraph WorldGraph;// the world node graph - - - // Global Savedata for monster // UNDONE: Save schedule data? Can this be done? We may // lose our enemy pointer or other data (goal ent, target, etc) diff --git a/dlls/monsterstate.cpp b/dlls/monsterstate.cpp index 07732f6da..b1b25e325 100644 --- a/dlls/monsterstate.cpp +++ b/dlls/monsterstate.cpp @@ -20,7 +20,6 @@ #include "extdll.h" #include "util.h" #include "cbase.h" -#include "nodes.h" #include "monsters.h" #include "animation.h" #include "saverestore.h" diff --git a/dlls/mp5.cpp b/dlls/mp5.cpp index 0390670cd..84f540b7b 100644 --- a/dlls/mp5.cpp +++ b/dlls/mp5.cpp @@ -18,7 +18,6 @@ #include "cbase.h" #include "monsters.h" #include "weapons.h" -#include "nodes.h" #include "player.h" #include "soundent.h" #include "gamerules.h" diff --git a/dlls/nodes.cpp b/dlls/nodes.cpp index 372bd3849..bed4ca928 100644 --- a/dlls/nodes.cpp +++ b/dlls/nodes.cpp @@ -119,12 +119,12 @@ void CGraph :: InitGraph() int CGraph :: AllocNodes () { // malloc all of the nodes - WorldGraph.m_pNodes = (CNode *)calloc ( sizeof ( CNode ), MAX_NODES ); + m_pNodes = (CNode *)calloc ( sizeof ( CNode ), MAX_NODES ); // could not malloc space for all the nodes! - if ( !WorldGraph.m_pNodes ) + if ( !m_pNodes ) { - ALERT ( at_aiconsole, "**ERROR**\nCouldn't malloc %d nodes!\n", WorldGraph.m_cNodes ); + ALERT ( at_aiconsole, "**ERROR**\nCouldn't malloc %d nodes!\n", m_cNodes ); return FALSE; } @@ -1310,7 +1310,7 @@ int CGraph :: LinkVisibleNodes ( CLink *pLinkPool, FILE *file, int *piBadNode ) } // record the connection info in the link pool - WorldGraph.m_pNodes [ i ].m_cNumLinks = cLinksThisNode; + m_pNodes [ i ].m_cNumLinks = cLinksThisNode; // keep track of the most initial links ANY node had, so we can figure out // if we have a large enough default link pool diff --git a/dlls/osprey.cpp b/dlls/osprey.cpp index 5865ad8eb..f9cc4e049 100644 --- a/dlls/osprey.cpp +++ b/dlls/osprey.cpp @@ -17,7 +17,6 @@ #include "cbase.h" #include "monsters.h" #include "weapons.h" -#include "nodes.h" #include "soundent.h" #include "effects.h" #include "customentity.h" diff --git a/dlls/player.cpp b/dlls/player.cpp index ab22dd51c..a3ac27902 100644 --- a/dlls/player.cpp +++ b/dlls/player.cpp @@ -55,9 +55,6 @@ BOOL gInitHUD = TRUE; extern void CopyToBodyQue(entvars_t* pev); extern edict_t *EntSelectSpawnPoint( CBaseEntity *pPlayer ); -// the world node graph -extern CGraph WorldGraph; - #define TRAIN_ACTIVE 0x80 #define TRAIN_NEW 0xc0 #define TRAIN_OFF 0x00 diff --git a/dlls/rpg.cpp b/dlls/rpg.cpp index 2dacf25a9..7cebf8785 100644 --- a/dlls/rpg.cpp +++ b/dlls/rpg.cpp @@ -18,7 +18,6 @@ #include "cbase.h" #include "monsters.h" #include "weapons.h" -#include "nodes.h" #include "player.h" #include "gamerules.h" #include "UserMessages.h" diff --git a/dlls/satchel.cpp b/dlls/satchel.cpp index 2f39d4dff..1bbac1bf1 100644 --- a/dlls/satchel.cpp +++ b/dlls/satchel.cpp @@ -18,7 +18,6 @@ #include "cbase.h" #include "monsters.h" #include "weapons.h" -#include "nodes.h" #include "player.h" #include "gamerules.h" diff --git a/dlls/schedule.cpp b/dlls/schedule.cpp index 3b8ced916..5f462974e 100644 --- a/dlls/schedule.cpp +++ b/dlls/schedule.cpp @@ -26,8 +26,6 @@ #include "defaultai.h" #include "soundent.h" -extern CGraph WorldGraph; - //========================================================= // FHaveSchedule - Returns TRUE if monster's m_pSchedule // is anything other than NULL. diff --git a/dlls/shotgun.cpp b/dlls/shotgun.cpp index 7e8da4fb2..4a7c92db1 100644 --- a/dlls/shotgun.cpp +++ b/dlls/shotgun.cpp @@ -18,7 +18,6 @@ #include "cbase.h" #include "monsters.h" #include "weapons.h" -#include "nodes.h" #include "player.h" #include "gamerules.h" #include "UserMessages.h" diff --git a/dlls/squadmonster.cpp b/dlls/squadmonster.cpp index 55b5a4442..fc621969c 100644 --- a/dlls/squadmonster.cpp +++ b/dlls/squadmonster.cpp @@ -18,7 +18,6 @@ #include "extdll.h" #include "util.h" #include "cbase.h" -#include "nodes.h" #include "monsters.h" #include "animation.h" #include "saverestore.h" diff --git a/dlls/squeakgrenade.cpp b/dlls/squeakgrenade.cpp index 0e5316000..46cbeb8bd 100644 --- a/dlls/squeakgrenade.cpp +++ b/dlls/squeakgrenade.cpp @@ -18,7 +18,6 @@ #include "cbase.h" #include "monsters.h" #include "weapons.h" -#include "nodes.h" #include "player.h" #include "soundent.h" #include "gamerules.h" diff --git a/dlls/subs.cpp b/dlls/subs.cpp index 7ecabc4ae..3ac890743 100644 --- a/dlls/subs.cpp +++ b/dlls/subs.cpp @@ -27,8 +27,6 @@ #include "nodes.h" #include "doors.h" -extern CGraph WorldGraph; - extern BOOL FEntIsVisible(entvars_t* pev, entvars_t* pevTarget); extern DLL_GLOBAL int g_iSkillLevel; diff --git a/dlls/tripmine.cpp b/dlls/tripmine.cpp index e14d1c27a..dee81c7e3 100644 --- a/dlls/tripmine.cpp +++ b/dlls/tripmine.cpp @@ -17,7 +17,6 @@ #include "cbase.h" #include "monsters.h" #include "weapons.h" -#include "nodes.h" #include "player.h" #include "effects.h" #include "gamerules.h" diff --git a/dlls/weapons.cpp b/dlls/weapons.cpp index 47dde8b42..3b4efe7da 100644 --- a/dlls/weapons.cpp +++ b/dlls/weapons.cpp @@ -26,13 +26,11 @@ #include "player.h" #include "monsters.h" #include "weapons.h" -#include "nodes.h" #include "soundent.h" #include "decals.h" #include "gamerules.h" #include "UserMessages.h" -extern CGraph WorldGraph; extern int gEvilImpulse101; diff --git a/dlls/world.cpp b/dlls/world.cpp index f8a054fb0..2b5a0c3b0 100644 --- a/dlls/world.cpp +++ b/dlls/world.cpp @@ -34,7 +34,6 @@ #include "gamerules.h" #include "teamplay_gamerules.h" -extern CGraph WorldGraph; extern CSoundEnt *pSoundEnt; extern CBaseEntity *g_pLastSpawn; diff --git a/dlls/wpn_shared/hl_wpn_glock.cpp b/dlls/wpn_shared/hl_wpn_glock.cpp index 9c5f04c8c..b2953801c 100644 --- a/dlls/wpn_shared/hl_wpn_glock.cpp +++ b/dlls/wpn_shared/hl_wpn_glock.cpp @@ -18,7 +18,6 @@ #include "cbase.h" #include "monsters.h" #include "weapons.h" -#include "nodes.h" #include "player.h" LINK_ENTITY_TO_CLASS( weapon_glock, CGlock ); From 8656016bc1df8f39b5058df663025772ae55bc40 Mon Sep 17 00:00:00 2001 From: Sam V Date: Thu, 18 Nov 2021 15:28:30 +0100 Subject: [PATCH 02/13] Disable as many Windows.h dependencies as possible Resolves #49 --- common/Platform.h | 45 +++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 43 insertions(+), 2 deletions(-) diff --git a/common/Platform.h b/common/Platform.h index 47baff44b..7a83a08ca 100644 --- a/common/Platform.h +++ b/common/Platform.h @@ -53,11 +53,52 @@ using qboolean = int; // Prevent tons of unused windows definitions #ifdef _WIN32 #define WIN32_LEAN_AND_MEAN -#define NOWINRES + +//Disable all Windows 10 and older APIs otherwise pulled in by Windows.h +#define NOGDICAPMASKS +#define NOVIRTUALKEYCODES +#define NOWINMESSAGES +#define NOWINSTYLES +#define NOSYSMETRICS +#define NOMENUS +#define NOICONS +#define NOKEYSTATES +#define NOSYSCOMMANDS +#define NORASTEROPS +#define NOSHOWWINDOW +#define OEMRESOURCE +#define NOATOM +#define NOCLIPBOARD +#define NOCOLOR +#define NOCTLMGR +#define NODRAWTEXT +#define NOGDI +#define NOKERNEL +//#define NOUSER //Need GetCursorPos in the mouse thread code +#define NONLS +#define NOMB +#define NOMEMMGR +#define NOMETAFILE +#define NOMINMAX +#define NOMSG +#define NOOPENFILE +#define NOSCROLL #define NOSERVICE +#define NOSOUND +#define NOTEXTMETRIC +#define NOWH +#define NOWINOFFSETS +#define NOCOMM +#define NOKANJI +#define NOHELP +#define NOPROFILER +#define NODEFERWINDOWPOS #define NOMCX + +//Disable additional stuff not covered by the Windows.h list +#define NOWINRES #define NOIME -#define NOMINMAX + #include "winsani_in.h" #include #include "winsani_out.h" From 322f229442fe7866e5c5a5997330748535f2cd2a Mon Sep 17 00:00:00 2001 From: Sam V Date: Thu, 18 Nov 2021 17:09:30 +0100 Subject: [PATCH 03/13] Remove benchmarking functionality Resolves #54 --- cl_dll/bench.h | 26 - cl_dll/entity.cpp | 4 - cl_dll/hud.h | 55 -- cl_dll/hud_bench.cpp | 1125 ----------------------- cl_dll/hud_benchtrace.cpp | 236 ----- cl_dll/hud_benchtrace.h | 8 - cl_dll/hud_redraw.cpp | 27 +- cl_dll/input.cpp | 5 +- cl_dll/view.cpp | 1 - projects/vs2017/hl_cdll.vcxproj | 2 - projects/vs2017/hl_cdll.vcxproj.filters | 6 - projects/vs2019/hl_cdll.vcxproj | 2 - projects/vs2019/hl_cdll.vcxproj.filters | 6 - 13 files changed, 7 insertions(+), 1496 deletions(-) delete mode 100644 cl_dll/bench.h delete mode 100644 cl_dll/hud_bench.cpp delete mode 100644 cl_dll/hud_benchtrace.cpp delete mode 100644 cl_dll/hud_benchtrace.h diff --git a/cl_dll/bench.h b/cl_dll/bench.h deleted file mode 100644 index 51ff97f6e..000000000 --- a/cl_dll/bench.h +++ /dev/null @@ -1,26 +0,0 @@ -#if !defined ( BENCHH ) -#define BENCHH -#pragma once - -#define FIRST_STAGE 1 -#define SECOND_STAGE 2 -#define THIRD_STAGE 3 -#define FOURTH_STAGE 4 -#define LAST_STAGE ( FOURTH_STAGE ) - -void Bench_CheckStart( void ); - -int Bench_InStage( int stage ); -int Bench_GetPowerPlay( void ); -int Bench_GetStage( void ); -void Bench_SetPowerPlay( int set ); -int Bench_Active( void ); - -void Bench_SetDotAdded( int dot ); -void Bench_SpotPosition( Vector dot, Vector target ); -void Bench_CheckEntity( int type, struct cl_entity_s *ent, const char *modelname ); -void Bench_AddObjects( void ); -void Bench_SetViewAngles( int recalc_wander, float *viewangles, float frametime, struct usercmd_s *cmd ); -void Bench_SetViewOrigin( float *vieworigin, float frametime ); - -#endif \ No newline at end of file diff --git a/cl_dll/entity.cpp b/cl_dll/entity.cpp index 4907bded1..cd029f7dd 100644 --- a/cl_dll/entity.cpp +++ b/cl_dll/entity.cpp @@ -12,7 +12,6 @@ #include "pm_defs.h" #include "pmtrace.h" #include "pm_shared.h" -#include "bench.h" #include "Exports.h" #include "particleman.h" @@ -37,7 +36,6 @@ int DLLEXPORT HUD_AddEntity( int type, struct cl_entity_s *ent, const char *mode switch ( type ) { case ET_NORMAL: - Bench_CheckEntity( type, ent, modelname ); break; case ET_PLAYER: case ET_BEAM: @@ -312,8 +310,6 @@ void DLLEXPORT HUD_CreateEntities() Beams(); #endif - Bench_AddObjects(); - // Add in any game specific objects Game_AddObjects(); diff --git a/cl_dll/hud.h b/cl_dll/hud.h index 58baaa844..f3e62f3db 100644 --- a/cl_dll/hud.h +++ b/cl_dll/hud.h @@ -479,60 +479,6 @@ class CHudStatusIcons: public CHudBase }; -// -//----------------------------------------------------- -// -class CHudBenchmark : public CHudBase -{ -public: - int Init() override; - int VidInit() override; - int Draw( float flTime ) override; - - void SetScore( float score ); - - void Think() override; - - void StartNextSection( int section ); - - int MsgFunc_Bench(const char *pszName, int iSize, void *pbuf); - - void CountFrame( float dt ); - - int GetObjects() { return m_nObjects; } - - void SetCompositeScore(); - - void Restart(); - - int Bench_ScoreForValue( int stage, float raw ); - -private: - float m_fDrawTime; - float m_fDrawScore; - float m_fAvgScore; - - float m_fSendTime; - float m_fReceiveTime; - - int m_nFPSCount; - float m_fAverageFT; - float m_fAvgFrameRate; - - int m_nSentFinish; - float m_fStageStarted; - - float m_StoredLatency; - float m_StoredPacketLoss; - int m_nStoredHopCount; - int m_nTraceDone; - - int m_nObjects; - - int m_nScoreComputed; - int m_nCompositeScore; -}; - // //----------------------------------------------------- // @@ -613,7 +559,6 @@ class CHud CHudAmmoSecondary m_AmmoSecondary; CHudTextMessage m_TextMessage; CHudStatusIcons m_StatusIcons; - CHudBenchmark m_Benchmark; void Init(); void VidInit(); diff --git a/cl_dll/hud_bench.cpp b/cl_dll/hud_bench.cpp deleted file mode 100644 index efba995c1..000000000 --- a/cl_dll/hud_bench.cpp +++ /dev/null @@ -1,1125 +0,0 @@ -// -//----------------------------------------------------- -// -#define BENCH_TIME 10.0 - -#include "hud.h" -#include "cl_util.h" - -#include "const.h" -#include "entity_state.h" -#include "cl_entity.h" -#include "usercmd.h" -#include "pm_defs.h" -#include "event_api.h" - -#include "bench.h" - -#include -#include -#include "parsemsg.h" - -#include "con_nprint.h" - -#include "netadr.h" -#include "hud_benchtrace.h" - -#include "net_api.h" - -#include "entity_types.h" - -#define NUM_BENCH_OBJ 12 -#define BENCH_CYCLE_TIME 10.0 -#define BENCH_INNER_CYCLE_TIME 4.0 -#define BENCH_VIEW_CYCLE_TIME 7.1 -#define BENCH_SWEEP 360.0 -#define BENCH_RADIUS 80.0 -#define BENCH_VIEW_OFFSET 250.0 -#define BLEND_IN_SPEED 150.0 -#define BENCH_BALLHEIGHT 72.0 -#define BENCH_BALL_VIEWDRIFT 60.0; -#define BENCH_RANGE 60.0 -// Scale: -// 0 - 100 -// 0 is worst -// 100 is best -// PP has 40 - 100 range -// Non-pp has 0 - 60 range -const float weights[3] = { 0.2, 0.3, 0.5 }; - -const char *g_title = "PowerPlay QoS Test"; //uality of Service Test"; -const char *pp_strings[2] = -{ - " PowerPlay Detected", - " PowerPlay Not Detected" , -}; -const char *g_stage1[2] = -{ - " Stage 1: Testing System Connectivity...", - " Stage 1: %i", -}; -const char *g_stage2[2] = -{ - " Stage 2: Testing System Performance...", - " Stage 2: %i", -}; -const char *g_stage3[2] = -{ - " Stage 3: Testing Tracking Accuracy...", - " Stage 3: %i", -}; -const char *g_stage4 = " Composite Score: %i"; - -extern Vector v_origin; - -static int g_isPowerPlay = 0; -static int g_currentstage = 0; -static int g_renderedBenchmarkDot = 0; -static float g_benchSwitchTime = 0.0; -static float g_benchSwitchTimes[ LAST_STAGE + 1 ] = { 0.0, 10.0, 12.0, 10.0, 5.0 }; - -#define SCORE_TIME_UP 1.5 - -DECLARE_MESSAGE(m_Benchmark, Bench); - -void VectorAngles( const float *forward, float *angles ); - -void Bench_SetStage( int stage ) -{ - g_currentstage = stage; -} - -int Bench_GetStage() -{ - return g_currentstage; -} - -float Bench_GetSwitchTime() -{ - return g_benchSwitchTimes[ V_min( Bench_GetStage(), LAST_STAGE ) ]; -} - -int Bench_InStage( int stage ) -{ - return ( Bench_GetStage() == stage ) ? 1 : 0; -} - -void Bench_SetPowerPlay( int set ) -{ - g_isPowerPlay = set ? 1 : 0; -} - -int Bench_GetPowerPlay() -{ - return g_isPowerPlay; -} - -int Bench_Active() -{ - return g_currentstage != 0 ? 1 : 0; -} - -void __CmdFunc_BenchMark() -{ - gHUD.m_Benchmark.Restart(); -} - - -void CHudBenchmark::Restart() -{ - Bench_SetStage( FIRST_STAGE ); - g_benchSwitchTime = gHUD.m_flTime + g_benchSwitchTimes[ FIRST_STAGE ]; - StartNextSection( FIRST_STAGE ); - - gHUD.m_Benchmark.m_iFlags |= HUD_ACTIVE; - gHUD.m_Benchmark.m_fDrawTime = gHUD.m_flTime + BENCH_TIME; -} - -int CHudBenchmark::MsgFunc_Bench(const char *pszName, int iSize, void *pbuf) -{ - int section = READ_BYTE(); - - m_fReceiveTime = gHUD.m_flTime; - m_StoredLatency = ( m_fReceiveTime - m_fSendTime ); - - m_StoredLatency = V_min( 1.0, m_StoredLatency ); - m_StoredLatency = V_max( 0.0, m_StoredLatency ); - - m_StoredPacketLoss = 0.0; - - { - char sz[ 256 ]; - netadr_t adr; - net_status_t status; - - gEngfuncs.pNetAPI->Status( &status ); - - if ( status.connected ) - { - adr = status.remote_address; - - sprintf( sz, "%i.%i.%i.%i", - adr.ip[ 0 ], adr.ip[ 1 ], adr.ip[ 2 ], adr.ip[ 3 ] ); - - if ( adr.type == NA_IP ) - { - Trace_StartTrace( &m_nStoredHopCount, &m_nTraceDone, (const char *)sz ); - } - else - { - m_nStoredHopCount = 0; - } - } - } - - return 1; -} - -void CHudBenchmark::StartNextSection( int section ) -{ - net_status_t status; - - switch ( section ) - { - case 1: - // Stage 2 requires that we tell the server to "drop" an item - m_fSendTime = gHUD.m_flTime; - m_fReceiveTime = 0.0; - m_StoredLatency = 0.0; - m_StoredPacketLoss = 0.0; - m_nStoredHopCount = 0; - m_nTraceDone = 0; - ServerCmd( "ppdemo 1 start\n" ); - break; - case 2: - if ( m_nTraceDone ) - { - gEngfuncs.pNetAPI->Status( &status ); - - gEngfuncs.Con_Printf( "Hops == %i\n", m_nStoredHopCount ); - m_StoredPacketLoss = status.packet_loss; - gEngfuncs.Con_Printf( "PL == %i\n", (int)m_StoredPacketLoss ); - - } - m_nSentFinish = 0; // added by minman - ServerCmd( "ppdemo 2\n" ); - break; - case 3: - m_nSentFinish = 0; // added by minman - ServerCmd( "ppdemo 3\n" ); - break; - default: - break; - } - - m_fStageStarted = gHUD.m_flTime; - g_benchSwitchTime = gHUD.m_flTime + Bench_GetSwitchTime(); -} - -void CHudBenchmark::CountFrame( float dt ) -{ - m_nFPSCount++; - m_fAverageFT += dt; -} - - -static int started = 0; - -void Bench_CheckStart() -{ - const char *level; - if ( !started && !Bench_Active() ) - { - level = gEngfuncs.pfnGetLevelName(); - if ( level && level[0] && !stricmp( level, "maps/ppdemo.bsp" ) ) - { - started = 1; - EngineClientCmd( "ppdemostart\n" ); - } - } -} - -void CHudBenchmark::Think() -{ - if ( !Bench_Active() ) - return; - - Trace_Think(); - - if ( started ) - { - started = 0; - - // Clear variable - m_fReceiveTime = 0.0; - m_nFPSCount = 0; - m_fAverageFT = 0.0; - m_nSentFinish = 0; - m_StoredLatency = 0.0; - m_StoredPacketLoss = 0.0; - m_nStoredHopCount = 0; - m_nTraceDone = 0; - m_nObjects = 0; - m_nScoreComputed = 0; - m_nCompositeScore = 0; - m_fAvgScore = 0; - m_fDrawScore = 0.0; - m_fAvgFrameRate = 0.0; - } - - if ( gHUD.m_flTime > g_benchSwitchTime ) - { - Bench_SetStage( Bench_GetStage() + 1 ); - StartNextSection( Bench_GetStage() ); - } - - if ( Bench_InStage( FIRST_STAGE ) ) - { - // Assume 1000 ms lag is the max and that would take all but 2 seconds of this interval to traverse - if ( m_fReceiveTime ) - { - float latency = 2.0 * m_StoredLatency; - float switch_time; - float total_time; - - latency = V_max( 0.0, latency ); - latency = V_min( 1.0, latency ); - - total_time = Bench_GetSwitchTime(); - total_time -= 2.0; - - switch_time = m_fStageStarted + latency * total_time; - switch_time += 1.0; - - if ( gHUD.m_flTime >= switch_time ) - { - if ( !m_nSentFinish ) - { - g_benchSwitchTime = gHUD.m_flTime + 1.0 + SCORE_TIME_UP; - - ServerCmd( "ppdemo 1 finish\n" ); - m_nSentFinish = 1; - } - } - else - { - g_benchSwitchTime = gHUD.m_flTime + 10.0; - } - } - } - - if ( Bench_InStage( SECOND_STAGE ) ) - { - // frametime - static float lasttime; - float elapsed; - float total; - float frac; - float switch_time; // added by minman - - if ( lasttime ) - { - float dt; - - dt = gHUD.m_flTime - lasttime; - if ( dt > 0 ) - { - CountFrame( dt ); - } - } - lasttime = gHUD.m_flTime; - - elapsed = gHUD.m_flTime - m_fStageStarted; - total = Bench_GetSwitchTime(); - if ( total ) - { - frac = elapsed / total; - - // Only takes 1/2 time to get up to maximum speed - frac *= 2.0; - frac = V_max( 0.0, frac ); - frac = V_min( 1.0, frac ); - - m_nObjects = (int)(NUM_BENCH_OBJ * frac); - } - switch_time = m_fStageStarted + total; - - /* BELOW ADDED BY minman */ - if (gHUD.m_flTime >= switch_time) - { - if ( !m_nSentFinish) - { - g_benchSwitchTime = gHUD.m_flTime + SCORE_TIME_UP; - m_nSentFinish = 1; - } - } - else - g_benchSwitchTime = gHUD.m_flTime + 10.0; - } - - /* BELOW ADDED BY minman */ - if ( Bench_InStage (THIRD_STAGE)) - { - float switch_time = m_fStageStarted + Bench_GetSwitchTime(); - - if (gHUD.m_flTime >= switch_time) - { - if ( !m_nSentFinish) - { - g_benchSwitchTime = gHUD.m_flTime + SCORE_TIME_UP; - m_nSentFinish = 1; - } - } - else - g_benchSwitchTime = gHUD.m_flTime + 10.0; - } - - if ( Bench_InStage( FOURTH_STAGE ) ) - { - if ( !m_nScoreComputed ) - { - m_nScoreComputed = 1; - gHUD.m_Benchmark.SetCompositeScore(); - } - } - - if ( Bench_GetStage() > LAST_STAGE ) - { - m_iFlags &= ~HUD_ACTIVE; - EngineClientCmd( "quit\n" ); - } -} - - -int CHudBenchmark::Init() -{ - gHUD.AddHudElem( this ); - - HOOK_COMMAND( "ppdemostart", BenchMark ); - - HOOK_MESSAGE(Bench); - - return 1; -} - -int CHudBenchmark::VidInit() -{ - return 1; -} - -int CHudBenchmark::Bench_ScoreForValue( int stage, float raw ) -{ - int score = 100.0; - int power_play = Bench_GetPowerPlay() ? 1 : 0; - - switch ( stage ) - { - case 1: // ping - score = 100.0 * ( m_StoredLatency ); - score = V_max( score, 0 ); - score = V_min( score, 100 ); - - // score is inverted - score = 100 - score; - - break; - case 2: // framerate/performance - score = (int)( 100 * m_fAvgFrameRate ) / 72; - score = V_min( score, 100 ); - score = V_max( score, 0 ); - - score *= BENCH_RANGE/100.0; - if ( power_play ) - { - score += ( 100 - BENCH_RANGE ); - } - break; - case 3: // tracking - score = (100 * m_fAvgScore) / 40; - score = V_max( score, 0 ); - score = V_min( score, 100 ); - - // score is inverted - score = 100 - score; - - score *= BENCH_RANGE/100.0; - if ( power_play ) - { - score += ( 100 - BENCH_RANGE ); - } - break; - } - - return score; -} - -void CHudBenchmark::SetCompositeScore() -{ - int tracking_score = Bench_ScoreForValue( THIRD_STAGE, m_fAvgScore ); - int ping_score = Bench_ScoreForValue( FIRST_STAGE, m_StoredLatency ); - int frame_score = Bench_ScoreForValue( SECOND_STAGE, m_fAvgFrameRate ); - - int composite = ( ping_score * weights[ 0 ] + frame_score * weights[ 1 ] + tracking_score * weights[ 2 ] ); - - composite = V_min( 100, composite ); - composite = V_max( 0, composite ); - - m_nCompositeScore = composite; -} - -int CHudBenchmark::Draw( float flTime ) -{ - char sz[ 256 ]; - int x, y; - - if ( m_fDrawTime < flTime || !Bench_Active() ) - { - m_iFlags &= ~HUD_ACTIVE; - return 1; - } - - x = 10; - y = 25; //480 - 150; - - sprintf( sz, "%s: %s", g_title , pp_strings[ Bench_GetPowerPlay() ? 0 : 1]); - - gHUD.DrawHudString( x, y, 320, sz, 251, 237, 7);// , 200, 200); //255, 255, 255 ); - - y += 20; - -// sprintf( sz, pp_strings[ Bench_GetPowerPlay() ? 0 : 1 ] ); - -// gHUD.DrawHudString( x, y, 320, sz, 31, 200, 200 ); - -// y += 20; - - - if ( Bench_InStage( FIRST_STAGE) /*|| Bench_InStage( SECOND_STAGE ) || Bench_InStage( THIRD_STAGE )*/ || Bench_InStage( FOURTH_STAGE ) ) - { - if ( m_fReceiveTime && m_nSentFinish ) - { - sprintf( sz, g_stage1[1], Bench_ScoreForValue( FIRST_STAGE, m_StoredLatency )); - } - else - { - sprintf( sz, "%s", g_stage1[0] ); - } - gHUD.DrawHudString( x, y, 320, sz, 255, 255, 255 ); - - y += 20; - - } - - - if ( Bench_InStage( SECOND_STAGE )/* || Bench_InStage( THIRD_STAGE )*/ || Bench_InStage( FOURTH_STAGE ) ) - { - float avg = 0.0; - - if ( m_nFPSCount > 0 ) - { - avg = m_fAverageFT / (float)m_nFPSCount; - m_fAvgFrameRate = 1.0 / avg; - } - - if ( m_nSentFinish /* Bench_InStage( THIRD_STAGE ) */|| Bench_InStage( FOURTH_STAGE ) ) - { - sprintf( sz, g_stage2[1], Bench_ScoreForValue( SECOND_STAGE, m_fAvgFrameRate ) ); - } - else - { - sprintf( sz, "%s", g_stage2[0] ); - } - gHUD.DrawHudString( x, y, 320, sz, 255, 255, 255 ); - y += 20; - } - - - if ( Bench_InStage( THIRD_STAGE ) || Bench_InStage( FOURTH_STAGE ) ) - { - if ( m_nSentFinish || Bench_InStage( FOURTH_STAGE ) ) - { - sprintf( sz, g_stage3[1], Bench_ScoreForValue( THIRD_STAGE, m_fAvgScore ) ); - } - else - { - sprintf( sz, "%s", g_stage3[0] ); - } - - gHUD.DrawHudString( x, y, 320, sz, 255, 255, 255 ); - - y += 20; - } - - if ( Bench_InStage( FOURTH_STAGE ) ) - { - sprintf( sz, g_stage4, m_nCompositeScore ); - gHUD.DrawHudString( x, y, 320, sz, 31, 200, 200 ); - } - - m_fDrawTime = gHUD.m_flTime + BENCH_TIME; - - return 1; -} - -#define SCORE_AVG 0.9 - -void CHudBenchmark::SetScore( float score ) -{ - // added by minman - if (m_nSentFinish) - return; - - m_fDrawScore = score; - m_fDrawTime = gHUD.m_flTime + BENCH_TIME; - - m_fAvgScore = ( SCORE_AVG ) * m_fAvgScore + ( 1.0 - SCORE_AVG ) * m_fDrawScore; -} - -void Bench_SetDotAdded( int dot ) -{ - g_renderedBenchmarkDot = dot; -} - -int Bench_GetDotAdded() -{ - return g_renderedBenchmarkDot; -} - -void Bench_SpotPosition(Vector dot, Vector target ) -{ - // Compute new score - Vector delta; - - VectorSubtract( target, dot, delta ); - - gHUD.m_Benchmark.SetScore( delta.Length() ); -} - -typedef struct model_s -{ - char name[64]; - qboolean needload; // bmodels and sprites don't cache normally - - int type; - int numframes; - int synctype; - - int flags; - -// -// volume occupied by the model -// - Vector mins, maxs; -} model_t; - -static Vector g_dotorg; -Vector g_aimorg; -float g_fZAdjust = 0.0; - -void Bench_CheckEntity( int type, struct cl_entity_s *ent, const char *modelname ) -{ - if ( Bench_InStage( THIRD_STAGE ) && !stricmp( modelname, "*3" ) ) - { - model_t *pmod; - Vector v; - pmod = (model_t *)( ent->model ); - - VectorAdd( pmod->mins, pmod->maxs, v ); - VectorScale( v, 0.5, v ); - - VectorAdd( v, ent->origin, g_aimorg ); - } - - if ( Bench_InStage( THIRD_STAGE ) && strstr( modelname, "ppdemodot" ) ) - { - Bench_SetDotAdded( 1 ); - VectorCopy( ent->origin, g_dotorg ); - - // Adjust end position - if ( Bench_Active() && Bench_InStage( THIRD_STAGE ) ) - { - static float fZAdjust = 0.0; - static float fLastTime; - float dt; - float fRate = Bench_GetPowerPlay() ? 4.0 : 8.0; - float fBounds = Bench_GetPowerPlay() ? 8.0 : 15.0; - - dt = gHUD.m_flTime - fLastTime; - if ( dt > 0.0 && dt < 1.0 ) - { - fZAdjust += gEngfuncs.pfnRandomFloat( -fRate, fRate ); - fZAdjust = V_min( fBounds, fZAdjust ); - fZAdjust = V_max( -fBounds, fZAdjust ); - - ent->origin[2] += fZAdjust; - - g_fZAdjust = fZAdjust; - } - fLastTime = gHUD.m_flTime; - } - } -} - -//TODO: since vec3_t was aliased to Vector this does nothing (vec3_t decays to pointer, Vector does not) -void NormalizeVector(Vector v ) -{ - int i; - for ( i = 0; i < 3; i++ ) - { - while ( v[i] < -180.0 ) - { - v[i] += 360.0; - } - - while ( v[i] > 180.0 ) - { - v[i] -= 360.0; - } - } -} - -float g_flStartTime; -int HUD_SetupBenchObjects( cl_entity_t *bench, int plindex, Vector origin ) -{ - int i, j; - Vector ang; - float offset; - struct model_s *mdl; - int index; - Vector forward, right, up; - Vector farpoint; - Vector centerspot; - pmtrace_t tr; - - ang = vec3_origin; - //ang[1] = 90.0; - - // Determine forward vector - AngleVectors ( ang, forward, right, up ); - - // Try to find the laserdot sprite model and retrieve the modelindex for it - mdl = gEngfuncs.CL_LoadModel( "models/spikeball.mdl", &index ); - if ( !mdl ) - return 0; - - gEngfuncs.pEventAPI->EV_SetUpPlayerPrediction( false, true ); - - // Store off the old count - gEngfuncs.pEventAPI->EV_PushPMStates(); - - // Now add in all of the players. - gEngfuncs.pEventAPI->EV_SetSolidPlayers ( plindex ); - - gEngfuncs.pEventAPI->EV_SetTraceHull( 2 ); - - centerspot = origin; - centerspot[2] -= 512; - - gEngfuncs.pEventAPI->EV_PlayerTrace( (float *)&origin, (float *)¢erspot, PM_NORMAL, -1, &tr ); - - centerspot = tr.endpos; - centerspot[2] += BENCH_BALLHEIGHT; - - // Move center out from here - centerspot = centerspot + BENCH_VIEW_OFFSET * forward; - - g_flStartTime = gHUD.m_flTime; - - for ( i = 0; i < NUM_BENCH_OBJ; i++ ) - { - offset = ( float ) i / (float) ( NUM_BENCH_OBJ - 1 ); - - ang[ 0 ] = 0; - ang[ 2 ] = 0; - ang[ 1 ] = BENCH_SWEEP * offset; - - // normalize - NormalizeVector( ang ); - - // Determine forward vector - AngleVectors ( ang, forward, right, up ); - - bench[ i ].model = mdl; - - bench[ i ].curstate.modelindex = index; - - // Set up dot info. - bench[ i ].curstate.movetype = MOVETYPE_NONE; - bench[ i ].curstate.solid = SOLID_NOT; - - // Get a far point for ray trace - farpoint = centerspot + BENCH_RADIUS * forward; - - gEngfuncs.pEventAPI->EV_PlayerTrace( (float *)¢erspot, (float *)&farpoint, PM_NORMAL, -1, &tr ); - - // Move dot to trace endpoint - bench[ i ].origin = tr.endpos; - bench[ i ].curstate.origin = bench[ i ].origin; - //bench[ i ].curstate.gravity = 0.5; - for ( j = 0; j < 2; j++ ) - { - // bench[ i ].curstate.velocity[ j ] = gEngfuncs.pfnRandomLong( -300, 300 ); - } - //bench[ i ].curstate.velocity[ 2 ] = gEngfuncs.pfnRandomLong( 0, 50 ); - bench[ i ].curstate.velocity = vec3_origin; - - bench[ i ].curstate.angles[ 2 ] = 0.0; - bench[ i ].curstate.angles[ 0 ] = 0.0; - bench[ i ].curstate.angles[ 1 ] = 0.0; // gEngfuncs.pfnRandomLong( -180, 180 ); - - for ( j = 0; j < 3; j++ ) - { - // angular velocity - bench[ i ].baseline.angles[ 0 ] = gEngfuncs.pfnRandomLong( -300, 300 ); - //bench[ i ].baseline.angles[ 0 ] = 0; - bench[ i ].baseline.angles[ 2 ] = 0; - bench[ i ].baseline.angles[ 1 ] = gEngfuncs.pfnRandomLong( -300, 300 ); - } - - bench[ i ].curstate.renderamt = 0; - - // Force no interpolation, etc., probably not necessary - bench[ i ].prevstate = bench[ i ].curstate; - } - - gEngfuncs.pEventAPI->EV_PopPMStates(); - - return 1; -} - -void HUD_CreateBenchObjects(Vector origin ) -{ - static cl_entity_t bench[ NUM_BENCH_OBJ ]; - cl_entity_t *player; - Vector forward, right, up; - Vector farpoint; - Vector centerspot; - static int first = true; - static int failed = false; - static float last_time; - float frametime; - float frac; - float frac2; - float dt; - - pmtrace_t tr; - int i = 0; - - if ( gHUD.m_flTime == last_time ) - return; - - frametime = gHUD.m_flTime - last_time; - last_time = gHUD.m_flTime; - - if ( frametime <= 0.0 ) - return; - - if ( failed ) - return; - - player = gEngfuncs.GetLocalPlayer(); - if ( !player ) - { - failed = true; - return; - } - - if ( first ) - { - first = false; - - if ( !HUD_SetupBenchObjects( bench, player->index - 1, origin ) ) - { - failed = true; - return; - } - } - - gEngfuncs.pEventAPI->EV_SetUpPlayerPrediction( false, true ); - - // Store off the old count - gEngfuncs.pEventAPI->EV_PushPMStates(); - - // Now add in all of the players. - gEngfuncs.pEventAPI->EV_SetSolidPlayers ( player->index - 1 ); - - gEngfuncs.pEventAPI->EV_SetTraceHull( 2 ); - - dt = gHUD.m_flTime - g_flStartTime; - if ( dt < 0 ) - return; - - frac = dt / BENCH_CYCLE_TIME; - if ( frac > 1.0 ) - { - frac = frac - (float)(int)frac; - } - - frac2 = dt /BENCH_INNER_CYCLE_TIME; - if ( frac2 > 1.0 ) - { - frac2 = frac2 - (float)(int)frac2; - } - - // Determine forward vector - AngleVectors ( vec3_origin, forward, right, up ); - - centerspot = origin; - centerspot[2] -= 512; - - gEngfuncs.pEventAPI->EV_PlayerTrace( (float *)&origin, (float *)¢erspot, PM_NORMAL, -1, &tr ); - - centerspot = tr.endpos; - centerspot[2] += BENCH_BALLHEIGHT; - - // Move center out from here - centerspot = centerspot + BENCH_VIEW_OFFSET * forward; - - for ( i = 0; i < NUM_BENCH_OBJ; i++ ) - { - int j; - float jitter = 0.0; - float jfrac; - float offset; - float ofs_radius = 5.0; - - Vector ang; - offset = ( float ) i / (float) ( NUM_BENCH_OBJ - 1 ); - - ang[ 0 ] = 0; - ang[ 2 ] = 0; - ang[ 1 ] = BENCH_SWEEP * offset + frac * 360.0; - // normalize - NormalizeVector( ang ); - - // Determine forward vector - AngleVectors ( ang, forward, right, up ); - - // Get a far point for ray trace - farpoint = centerspot + ( BENCH_RADIUS + ofs_radius * sin( BENCH_SWEEP * offset + frac2 * 2 * M_PI ) ) * forward; - farpoint[2] += 10 * cos( BENCH_SWEEP * offset + frac2 * 2 * M_PI ); - - gEngfuncs.pEventAPI->EV_PlayerTrace( (float *)¢erspot, (float *)&farpoint, PM_NORMAL, -1, &tr ); - - // Add angular velocity - VectorMA( bench[ i ].curstate.angles, frametime, bench[ i ].baseline.angles, bench[ i ].curstate.angles ); - - NormalizeVector( bench[ i ].curstate.angles ); - - jfrac = ( (float)gHUD.m_Benchmark.GetObjects() / (float)NUM_BENCH_OBJ ); - - // Adjust velocity - //bench[ i ].curstate.velocity[ 2 ] -= bench[ i ].curstate.gravity * frametime * 800; - - /* - // Did we hit something? - if ( tr.fraction != 1.0 && !tr.inwater ) - { - float damp; - float proj; - Vector traceNormal; - int j; - - traceNormal = tr.plane.normal; - - damp = 0.9; - - // Reflect velocity - if ( damp != 0 ) - { - proj = DotProduct( bench[ i ].curstate.velocity, traceNormal ); - VectorMA( bench[ i ].curstate.velocity, -proj*2, traceNormal, bench[ i ].curstate.velocity ); - // Reflect rotation (fake) - - for ( j = 0 ; j < 3; j++ ) - { - if ( bench[ i ].curstate.velocity[ j ] > 1000.0 ) - { - bench[ i ].curstate.velocity[ j ] = 1000.0; - } - else if ( bench[ i ].curstate.velocity[ j ] < -1000.0 ) - { - bench[ i ].curstate.velocity[ j ] = -1000.0; - } - } - - bench[ i ].baseline.angles[1] = -bench[ i ].baseline.angles[1]; - - VectorScale( bench[ i ].curstate.velocity, damp, bench[ i ].curstate.velocity ); - } - } - */ - - if ( i == ( NUM_BENCH_OBJ - 1 ) ) - { - g_aimorg = tr.endpos; - } - - if ( Bench_GetPowerPlay() ) - { - jitter = 0.5; - } - else - { - jitter = 8.0; - } - - jitter *= jfrac; - - for ( j = 0; j < 2; j++ ) - { - tr.endpos[ j ] += gEngfuncs.pfnRandomFloat( -jitter, jitter ); - } - - // Add to visedicts list for rendering - // Move dot to trace endpoint - bench[ i ].origin = tr.endpos; - bench[ i ].curstate.origin = bench[ i ].origin; - bench[ i ].angles = bench[ i ].curstate.angles; - - // Force no interpolation, etc., probably not necessary - bench[ i ].prevstate = bench[ i ].curstate; - - if ( ( NUM_BENCH_OBJ - i - 1 ) < gHUD.m_Benchmark.GetObjects() ) - { - if ( bench[ i ].curstate.renderamt == 255 ) - { - bench[i].curstate.rendermode = kRenderNormal; - } - else - { - bench[i].curstate.renderamt += BLEND_IN_SPEED * frametime; - bench[i].curstate.renderamt = V_min( 255, bench[i].curstate.renderamt ); - bench[i].curstate.rendermode = kRenderTransAlpha; - } - - gEngfuncs.CL_CreateVisibleEntity( ET_NORMAL, &bench[ i ] ); - } - } - - gEngfuncs.pEventAPI->EV_PopPMStates(); -} - -void Bench_AddObjects() -{ - if ( Bench_GetDotAdded() ) - { - Bench_SpotPosition( g_dotorg, g_aimorg ); - Bench_SetDotAdded( 0 ); - } - - if ( Bench_InStage( SECOND_STAGE ) ) - { - HUD_CreateBenchObjects( v_origin ); - } -} - - -static Vector v_stochastic; - -void Bench_SetViewAngles( int recalc_wander, float *viewangles, float frametime, struct usercmd_s *cmd ) -{ - if ( !Bench_Active() ) - return; - - int i; - Vector lookdir; - - // Clear stochastic offset between runs - if ( Bench_InStage( FIRST_STAGE ) ) - { - VectorCopy( vec3_origin, v_stochastic ); - } - - if ( Bench_InStage( SECOND_STAGE ) || Bench_InStage( THIRD_STAGE ) ) - { - VectorSubtract( g_aimorg, v_origin, lookdir ); - VectorNormalize( lookdir ); - VectorAngles( (float *)&lookdir, viewangles ); - - viewangles[0] = -viewangles[0]; - - /* - if ( recalc_wander ) - { - float fmag = 2.0; - if ( Bench_GetPowerPlay() ) - { - fmag = 10.0; - } - - for ( i = 0; i < 2; i++ ) - { - v_stochastic[ i ] += frametime * gEngfuncs.pfnRandomFloat( -fmag, fmag ); - v_stochastic[ i ] = V_max( -15.0, v_stochastic[ i ] ); - v_stochastic[ i ] = V_min( 15.0, v_stochastic[ i ] ); - } - - v_stochastic[ 2 ] = 0.0; - } - */ - - VectorAdd( viewangles, v_stochastic, viewangles ); - - for ( i = 0; i < 3; i++ ) - { - if ( viewangles[ i ] > 180 ) - viewangles[ i ] -= 360; - if ( viewangles[ i ] < -180 ) - viewangles[ i ] += 360; - } - } - else - { - VectorCopy( vec3_origin, viewangles ) - - if ( Bench_InStage( FIRST_STAGE ) ) - { - viewangles[ 1 ] = -90; - } - } - - if ( cmd ) - { - if ( Bench_InStage( THIRD_STAGE ) ) - { - cmd->buttons = IN_ATTACK; - } - else - { - cmd->buttons = 0; - } - } -} - -void Bench_SetViewOrigin( float *vieworigin, float frametime ) -{ - float dt; - float frac; - float offset_amt = BENCH_BALL_VIEWDRIFT; - float drift; - Vector ang, right; - Vector move; - - if ( !Bench_InStage( SECOND_STAGE ) ) - return; - - dt = gHUD.m_flTime - g_flStartTime; - if ( dt < 0 ) - return; - - frac = dt / BENCH_VIEW_CYCLE_TIME; - frac *= 2 * M_PI; - - drift = sin( frac ) * offset_amt; - - ang = vec3_origin; - - AngleVectors( ang, NULL, right, NULL ); - - // offset along right axis - move = right * drift; - - VectorAdd( vieworigin, move, vieworigin ); -} - diff --git a/cl_dll/hud_benchtrace.cpp b/cl_dll/hud_benchtrace.cpp deleted file mode 100644 index 1abe59e56..000000000 --- a/cl_dll/hud_benchtrace.cpp +++ /dev/null @@ -1,236 +0,0 @@ -// hud_benchtrace.cpp -// Functions for spawning a thread to get a hopcount to a particular ip address and returning the result in a specified -// variable - -#ifdef _WIN32 -#include "winsani_in.h" -#include -#include "winsani_out.h" -#else -#include "port.h" -#include -#endif - -// For tracking the trace threads -typedef struct -{ - // Inputs - char server[ 256 ]; - - // Outputs - int *p_nresults; - int *p_ndone; - - // Local variables - DWORD hThreadId; - HANDLE hThread; - HANDLE hEventDone; -} trace_params_t; - -// Static forces it to be zeroed out -static trace_params_t tp; - -// For doing the actual traceroute -struct trace_options_s -{ - unsigned char ucTTL; - unsigned char a[7]; -}; - -struct TraceReturn -{ - DWORD dwAddress; - unsigned long ulStatus, ulRoundTripTime; - unsigned char a[8]; - struct trace_options_s Options; -} traceReturn; - -/* -============== -Trace_GetHopCount - -Performs a synchronous hopcount on the specified server -============== -*/ -int Trace_GetHopCount( char *pServer, int nMaxHops ) -{ -#ifdef _WIN32 - HMODULE hICMP; // Handle to ICMP .dll - HANDLE hIP; // Handle to icmp session - DWORD *dwIPAddr; // remote IP Address as a DWORD - struct hostent *pHostEnt; // Name of remote host - struct trace_options_s traceOptions; // Input options - int c; // Hop counter - - // Prototypes - HANDLE ( WINAPI *pfnICMPCreateFile ) (); - BOOL ( WINAPI *pfnICMPCloseFile ) ( HANDLE ); - DWORD (WINAPI *pfnICMPSendEcho) ( HANDLE, DWORD, LPVOID, WORD, LPVOID, LPVOID, DWORD, DWORD ); - - hICMP = ::LoadLibrary( "ICMP.DLL" ); - - pfnICMPCreateFile = ( HANDLE ( WINAPI *)() )::GetProcAddress( hICMP,"IcmpCreateFile"); - pfnICMPCloseFile = ( BOOL ( WINAPI *) ( HANDLE ) )::GetProcAddress( hICMP,"IcmpCloseHandle"); - pfnICMPSendEcho = ( DWORD ( WINAPI * ) ( HANDLE, DWORD, LPVOID, WORD, LPVOID, LPVOID, DWORD,DWORD ) )::GetProcAddress( hICMP,"IcmpSendEcho" ); - - if ( !pfnICMPCreateFile || - !pfnICMPCloseFile || - !pfnICMPSendEcho ) - { - return -1; - } - - hIP = pfnICMPCreateFile(); - if ( !hIP ) - { - return -1; - } - - // DNS lookup on remote host - pHostEnt = gethostbyname( pServer ); - if ( !pHostEnt ) - { - return -1; - } - - // Take first IP address returned - dwIPAddr = ( DWORD * )( *pHostEnt->h_addr_list ); - - // Fixme: If not tracing, can use a "binary search" method to do the trace route - for ( c = 1; c <= nMaxHops ; c++) - { - // Set TTL correctly - traceOptions.ucTTL = (unsigned char)c; - - // Clear out return structure - memset( &traceReturn, 0, sizeof( traceReturn ) ); - - // Send echo request, 2000 milliseconds maximum waiting time - pfnICMPSendEcho ( hIP, *dwIPAddr, 0, 0, &traceOptions, &traceReturn, sizeof(traceReturn), 2000 ); - - // Found requrested remote address, c contains the correct hopcount - if ( traceReturn.dwAddress == *dwIPAddr ) - break; - } - - /* - // This is how you do a raw ping - npings = 1; - pfnICMPSendEcho( hIP, *dwIPAddr, 0, 0, NULL, &E, sizeof( E ), 2000 ); - *ping = (double)E.RoundTripTime / 1000.0; - */ - - // Clean up file and dll handles - pfnICMPCloseFile( hIP ); - - ::FreeLibrary( hICMP ); - - // Failure? - if ( c > nMaxHops ) - { - return -1; - } - - return c; -#else - return -1; -#endif -} - -/* -============== -Trace_Cleanup - -Destroys thread and event handle when trace is done, or when restarting a new trace -============== -*/ -void Trace_Cleanup() -{ -#ifdef _WIN32 - if ( tp.hThread ) - { - TerminateThread( tp.hThread, 0 ); - CloseHandle( tp.hThread ); - tp.hThread = (HANDLE)0; - } - - if ( tp.hEventDone ) - { - CloseHandle( tp.hEventDone ); - tp.hEventDone = (HANDLE)0; - } -#endif -} - -#ifdef _WIN32 - -/* -============== -Trace_ThreadFunction - -Performs a trace, sets finish event and exits -============== -*/ -DWORD WINAPI Trace_ThreadFunction( LPVOID p ) -{ - int *results; - - results = ( int * )p; - - *results = Trace_GetHopCount( tp.server, 30 ); - SetEvent( tp.hEventDone ); - - return 0; -} -#endif - -/* -============== -Trace_StartTrace - -Create finish event, sets up data, and starts thread to do a traceroute. -============== -*/ -void Trace_StartTrace( int *results, int *finished, const char *server ) -{ -#ifdef _WIN32 - tp.p_nresults = results; - strcpy( tp.server, server ); - - *results = -1; - - Trace_Cleanup(); - - tp.hEventDone = CreateEvent( NULL, TRUE, FALSE, NULL ); - if ( !tp.hEventDone ) - { - return; - } - - tp.p_ndone = finished; - *tp.p_ndone = 0; - - tp.hThread = CreateThread( NULL, 0, Trace_ThreadFunction, results, 0, &tp.hThreadId ); -#endif -} - -/* -============== -Trace_Think - -Invoked by general frame loop on client to periodically check if the traceroute thread has completed. -============== -*/ -void Trace_Think() -{ -#ifdef _WIN32 - if ( !tp.hEventDone ) - return; - - if ( WaitForSingleObject( tp.hEventDone, 0 ) == WAIT_OBJECT_0 ) - { - Trace_Cleanup(); - *tp.p_ndone = 1; - } -#endif -} \ No newline at end of file diff --git a/cl_dll/hud_benchtrace.h b/cl_dll/hud_benchtrace.h deleted file mode 100644 index 86093218d..000000000 --- a/cl_dll/hud_benchtrace.h +++ /dev/null @@ -1,8 +0,0 @@ -#if !defined( HUD_BENCHTRACEH ) -#define HUD_BENCHTRACEH -#pragma once - -void Trace_StartTrace( int *results, int *finished, const char *pszServer ); -void Trace_Think( void ); - -#endif // !HUD_BENCHTRACEH \ No newline at end of file diff --git a/cl_dll/hud_redraw.cpp b/cl_dll/hud_redraw.cpp index e6d7d4746..752f8315e 100644 --- a/cl_dll/hud_redraw.cpp +++ b/cl_dll/hud_redraw.cpp @@ -17,7 +17,6 @@ // #include "hud.h" #include "cl_util.h" -#include "bench.h" #include "vgui_TeamFortressViewport.h" @@ -87,8 +86,6 @@ void CHud::Think() { m_iFOV = gHUD.m_Spectator.GetFOV(); // default_fov->value; } - - Bench_CheckStart(); } // Redraw @@ -148,27 +145,15 @@ int CHud :: Redraw( float flTime, int intermission ) while (pList) { - if ( !Bench_Active() ) + if ( !intermission ) { - if ( !intermission ) - { - if ( (pList->p->m_iFlags & HUD_ACTIVE) && !(m_iHideHUDDisplay & HIDEHUD_ALL) ) - pList->p->Draw(flTime); - } - else - { // it's an intermission, so only draw hud elements that are set to draw during intermissions - if ( pList->p->m_iFlags & HUD_INTERMISSION ) - pList->p->Draw( flTime ); - } + if ( (pList->p->m_iFlags & HUD_ACTIVE) && !(m_iHideHUDDisplay & HIDEHUD_ALL) ) + pList->p->Draw(flTime); } else - { - if ( ( pList->p == &m_Benchmark ) && - ( pList->p->m_iFlags & HUD_ACTIVE ) && - !( m_iHideHUDDisplay & HIDEHUD_ALL ) ) - { - pList->p->Draw(flTime); - } + { // it's an intermission, so only draw hud elements that are set to draw during intermissions + if ( pList->p->m_iFlags & HUD_INTERMISSION ) + pList->p->Draw( flTime ); } pList = pList->pNext; diff --git a/cl_dll/input.cpp b/cl_dll/input.cpp index aac7e8d51..ccbdd95a4 100644 --- a/cl_dll/input.cpp +++ b/cl_dll/input.cpp @@ -17,7 +17,6 @@ extern "C" #include "camera.h" #include "in_defs.h" #include "view.h" -#include "bench.h" #include #include #include "Exports.h" @@ -665,7 +664,7 @@ void DLLEXPORT CL_CreateMove ( float frametime, struct usercmd_s *cmd, int activ Vector viewangles; static Vector oldangles; - if ( active && !Bench_Active() ) + if ( active ) { //memset( viewangles, 0, sizeof( Vector ) ); //viewangles[ 0 ] = viewangles[ 1 ] = viewangles[ 2 ] = 0.0; @@ -762,8 +761,6 @@ void DLLEXPORT CL_CreateMove ( float frametime, struct usercmd_s *cmd, int activ { VectorCopy( oldangles, cmd->viewangles ); } - - Bench_SetViewAngles( 1, (float *)&cmd->viewangles, frametime, cmd ); } /* diff --git a/cl_dll/view.cpp b/cl_dll/view.cpp index e9b4cabc1..d5ca74420 100644 --- a/cl_dll/view.cpp +++ b/cl_dll/view.cpp @@ -15,7 +15,6 @@ #include "pm_defs.h" #include "event_api.h" #include "pmtrace.h" -#include "bench.h" #include "screenfade.h" #include "shake.h" #include "hltv.h" diff --git a/projects/vs2017/hl_cdll.vcxproj b/projects/vs2017/hl_cdll.vcxproj index 51354d004..d8306521e 100644 --- a/projects/vs2017/hl_cdll.vcxproj +++ b/projects/vs2017/hl_cdll.vcxproj @@ -130,8 +130,6 @@ - - diff --git a/projects/vs2017/hl_cdll.vcxproj.filters b/projects/vs2017/hl_cdll.vcxproj.filters index 34f495fda..572ca51f0 100644 --- a/projects/vs2017/hl_cdll.vcxproj.filters +++ b/projects/vs2017/hl_cdll.vcxproj.filters @@ -165,12 +165,6 @@ Source Files\cl_dll - - Source Files\cl_dll - - - Source Files\cl_dll - Source Files\cl_dll diff --git a/projects/vs2019/hl_cdll.vcxproj b/projects/vs2019/hl_cdll.vcxproj index 855afa606..0f236761f 100644 --- a/projects/vs2019/hl_cdll.vcxproj +++ b/projects/vs2019/hl_cdll.vcxproj @@ -130,8 +130,6 @@ - - diff --git a/projects/vs2019/hl_cdll.vcxproj.filters b/projects/vs2019/hl_cdll.vcxproj.filters index 76b1d1bd1..3cfc82b66 100644 --- a/projects/vs2019/hl_cdll.vcxproj.filters +++ b/projects/vs2019/hl_cdll.vcxproj.filters @@ -168,12 +168,6 @@ Source Files\cl_dll - - Source Files\cl_dll - - - Source Files\cl_dll - Source Files\cl_dll From 4726358ee8af16c64504176c8f5efb3493861fbb Mon Sep 17 00:00:00 2001 From: Sam V Date: Thu, 18 Nov 2021 17:12:52 +0100 Subject: [PATCH 04/13] Remove game_controls.lib from client Resolves #55 --- lib/public/game_controls.lib | Bin 507268 -> 0 bytes projects/vs2017/hl_cdll.vcxproj | 3 --- projects/vs2017/hl_cdll.vcxproj.filters | 3 --- projects/vs2019/hl_cdll.vcxproj | 3 --- projects/vs2019/hl_cdll.vcxproj.filters | 3 --- 5 files changed, 12 deletions(-) delete mode 100644 lib/public/game_controls.lib diff --git a/lib/public/game_controls.lib b/lib/public/game_controls.lib deleted file mode 100644 index 02fec5c81db62669837898404e34d87c543812fa..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 507268 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%0Ab!m$1s8Wv|`-mt=UH(_n0ney!QFFIl6vm1s{ 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

_}>} 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

B9zLp|lGv&&M%>q0wKo|pBDR*fLhWV!W-aUK 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 diff --git a/projects/vs2017/hl_cdll.vcxproj b/projects/vs2017/hl_cdll.vcxproj index d8306521e..35d89dbad 100644 --- a/projects/vs2017/hl_cdll.vcxproj +++ b/projects/vs2017/hl_cdll.vcxproj @@ -279,9 +279,6 @@ - - - diff --git a/projects/vs2017/hl_cdll.vcxproj.filters b/projects/vs2017/hl_cdll.vcxproj.filters index 572ca51f0..c9dc0a683 100644 --- a/projects/vs2017/hl_cdll.vcxproj.filters +++ b/projects/vs2017/hl_cdll.vcxproj.filters @@ -561,7 +561,4 @@ Header Files - - - \ No newline at end of file diff --git a/projects/vs2019/hl_cdll.vcxproj b/projects/vs2019/hl_cdll.vcxproj index 0f236761f..0e6ce28e3 100644 --- a/projects/vs2019/hl_cdll.vcxproj +++ b/projects/vs2019/hl_cdll.vcxproj @@ -279,9 +279,6 @@ - - - diff --git a/projects/vs2019/hl_cdll.vcxproj.filters b/projects/vs2019/hl_cdll.vcxproj.filters index 3cfc82b66..7786a9a67 100644 --- a/projects/vs2019/hl_cdll.vcxproj.filters +++ b/projects/vs2019/hl_cdll.vcxproj.filters @@ -564,7 +564,4 @@ Header Files\engine - - - \ No newline at end of file From acaa843433ff6cdbf0cae632d137fd5a3b7a8f95 Mon Sep 17 00:00:00 2001 From: Sam V Date: Thu, 18 Nov 2021 17:14:14 +0100 Subject: [PATCH 05/13] Remove benchmarking files from Linux makefile Resolves #54 --- linux/Makefile.hl_cdll | 2 -- 1 file changed, 2 deletions(-) diff --git a/linux/Makefile.hl_cdll b/linux/Makefile.hl_cdll index 20d3c8039..d2df1a44d 100644 --- a/linux/Makefile.hl_cdll +++ b/linux/Makefile.hl_cdll @@ -56,8 +56,6 @@ HL1_OBJS = \ $(HL1_OBJ_DIR)/GameStudioModelRenderer.o \ $(HL1_OBJ_DIR)/geiger.o \ $(HL1_OBJ_DIR)/health.o \ - $(HL1_OBJ_DIR)/hud_bench.o \ - $(HL1_OBJ_DIR)/hud_benchtrace.o \ $(HL1_OBJ_DIR)/hud_msg.o \ $(HL1_OBJ_DIR)/hud_redraw.o \ $(HL1_OBJ_DIR)/hud_update.o \ From 4b7226e44b1b8e969cfeb47941d92a0b976f94d4 Mon Sep 17 00:00:00 2001 From: Sam V Date: Thu, 18 Nov 2021 17:50:02 +0100 Subject: [PATCH 06/13] Define platform-agnostic types for common structures Resolves #56 --- cl_dll/ammo.cpp | 16 ++++++++-------- cl_dll/ammo.h | 16 ++++++++-------- cl_dll/ammohistory.cpp | 6 +++--- cl_dll/ammohistory.h | 2 +- cl_dll/battery.cpp | 2 +- cl_dll/flashlight.cpp | 2 +- cl_dll/hud.cpp | 2 +- cl_dll/hud.h | 18 +++++++++--------- cl_dll/hud_spectator.h | 2 +- cl_dll/in_camera.cpp | 8 ++++---- cl_dll/inputw32.cpp | 2 +- common/Platform.h | 1 + cl_dll/wrect.h => common/common_types.h | 24 ++++++++++++++++++------ common/port.h | 13 ------------- engine/APIProxy.h | 25 +++++++++++++------------ engine/cdll_int.h | 4 ++-- game_shared/vgui_loadtga.cpp | 1 - projects/vs2017/hl_cdll.vcxproj | 2 +- projects/vs2017/hl_cdll.vcxproj.filters | 6 +++--- projects/vs2019/hl_cdll.vcxproj | 2 +- projects/vs2019/hl_cdll.vcxproj.filters | 6 +++--- 21 files changed, 80 insertions(+), 80 deletions(-) rename cl_dll/wrect.h => common/common_types.h (54%) diff --git a/cl_dll/ammo.cpp b/cl_dll/ammo.cpp index 8e6ac0443..7fdf05373 100644 --- a/cl_dll/ammo.cpp +++ b/cl_dll/ammo.cpp @@ -84,10 +84,10 @@ void WeaponsResource :: LoadWeaponSprites( WEAPON *pWeapon ) if ( !pWeapon ) return; - memset( &pWeapon->rcActive, 0, sizeof(wrect_t) ); - memset( &pWeapon->rcInactive, 0, sizeof(wrect_t) ); - memset( &pWeapon->rcAmmo, 0, sizeof(wrect_t) ); - memset( &pWeapon->rcAmmo2, 0, sizeof(wrect_t) ); + memset( &pWeapon->rcActive, 0, sizeof(Rect) ); + memset( &pWeapon->rcInactive, 0, sizeof(Rect) ); + memset( &pWeapon->rcAmmo, 0, sizeof(Rect) ); + memset( &pWeapon->rcAmmo2, 0, sizeof(Rect) ); pWeapon->hInactive = 0; pWeapon->hActive = 0; pWeapon->hAmmo = 0; @@ -391,7 +391,7 @@ void CHudAmmo::Think() // Helper function to return a Ammo pointer from id // -HSPRITE* WeaponsResource :: GetAmmoPicFromWeapon( int iAmmoId, wrect_t& rect ) +HSPRITE* WeaponsResource :: GetAmmoPicFromWeapon( int iAmmoId, Rect& rect ) { for ( int i = 0; i < MAX_WEAPONS; i++ ) { @@ -541,7 +541,7 @@ int CHudAmmo::MsgFunc_HideWeapon( const char *pszName, int iSize, void *pbuf ) if ( gHUD.m_iHideHUDDisplay & ( HIDEHUD_WEAPONS | HIDEHUD_ALL ) ) { - static wrect_t nullrc; + static Rect nullrc; gpActiveSel = NULL; SetCrosshair( 0, nullrc, 0, 0, 0 ); } @@ -561,7 +561,7 @@ int CHudAmmo::MsgFunc_HideWeapon( const char *pszName, int iSize, void *pbuf ) // int CHudAmmo::MsgFunc_CurWeapon(const char *pszName, int iSize, void *pbuf ) { - static wrect_t nullrc; + static Rect nullrc; int fOnTarget = FALSE; BEGIN_READ( pbuf, iSize ); @@ -887,7 +887,7 @@ int CHudAmmo::Draw(float flTime) x = ScreenWidth - (8 * AmmoWidth) - iIconWidth; x = gHUD.DrawHudNumber(x, y, iFlags | DHN_3DIGITS, pw->iClip, r, g, b); - wrect_t rc; + Rect rc; rc.top = 0; rc.left = 0; rc.right = AmmoWidth; diff --git a/cl_dll/ammo.h b/cl_dll/ammo.h index 5e44065ab..465d697cc 100644 --- a/cl_dll/ammo.h +++ b/cl_dll/ammo.h @@ -39,21 +39,21 @@ struct WEAPON int iCount; // # of itesm in plist HSPRITE hActive; - wrect_t rcActive; + Rect rcActive; HSPRITE hInactive; - wrect_t rcInactive; + Rect rcInactive; HSPRITE hAmmo; - wrect_t rcAmmo; + Rect rcAmmo; HSPRITE hAmmo2; - wrect_t rcAmmo2; + Rect rcAmmo2; HSPRITE hCrosshair; - wrect_t rcCrosshair; + Rect rcCrosshair; HSPRITE hAutoaim; - wrect_t rcAutoaim; + Rect rcAutoaim; HSPRITE hZoomedCrosshair; - wrect_t rcZoomedCrosshair; + Rect rcZoomedCrosshair; HSPRITE hZoomedAutoaim; - wrect_t rcZoomedAutoaim; + Rect rcZoomedAutoaim; }; typedef int AMMO; diff --git a/cl_dll/ammohistory.cpp b/cl_dll/ammohistory.cpp index 33fd3b5d8..ef69f2a75 100644 --- a/cl_dll/ammohistory.cpp +++ b/cl_dll/ammohistory.cpp @@ -40,7 +40,7 @@ struct ITEM_INFO { char szName[MAX_ITEM_NAME]; HSPRITE spr; - wrect_t rect; + Rect rect; }; void HistoryResource :: AddToHistory( int iType, int iId, int iCount ) @@ -120,7 +120,7 @@ int HistoryResource :: DrawAmmoHistory( float flTime ) } else if ( rgAmmoHistory[i].type == HISTSLOT_AMMO ) { - wrect_t rcPic; + Rect rcPic; HSPRITE *spr = gWR.GetAmmoPicFromWeapon( rgAmmoHistory[i].iId, rcPic ); int r, g, b; @@ -168,7 +168,7 @@ int HistoryResource :: DrawAmmoHistory( float flTime ) if ( !rgAmmoHistory[i].iId ) continue; // sprite not loaded - wrect_t rect = gHUD.GetSpriteRect( rgAmmoHistory[i].iId ); + Rect rect = gHUD.GetSpriteRect( rgAmmoHistory[i].iId ); UnpackRGB(r,g,b, RGB_YELLOWISH); float scale = (rgAmmoHistory[i].DisplayTime - flTime) * 80; diff --git a/cl_dll/ammohistory.h b/cl_dll/ammohistory.h index 8aaf3c188..ec1e699a3 100644 --- a/cl_dll/ammohistory.h +++ b/cl_dll/ammohistory.h @@ -89,7 +89,7 @@ class WeaponsResource int CountAmmo( int iId ); - HSPRITE* GetAmmoPicFromWeapon( int iAmmoId, wrect_t& rect ); + HSPRITE* GetAmmoPicFromWeapon( int iAmmoId, Rect& rect ); }; extern WeaponsResource gWR; diff --git a/cl_dll/battery.cpp b/cl_dll/battery.cpp index c4a8524df..e0384afa0 100644 --- a/cl_dll/battery.cpp +++ b/cl_dll/battery.cpp @@ -88,7 +88,7 @@ int CHudBattery::Draw(float flTime) return 1; int r, g, b, x, y, a; - wrect_t rc; + Rect rc; rc = *m_prc2; diff --git a/cl_dll/flashlight.cpp b/cl_dll/flashlight.cpp index f1fa51b0c..ef87d1591 100644 --- a/cl_dll/flashlight.cpp +++ b/cl_dll/flashlight.cpp @@ -100,7 +100,7 @@ int CHudFlashlight::Draw(float flTime) return 1; int r, g, b, x, y, a; - wrect_t rc; + Rect rc; if (!(gHUD.m_iWeaponBits & (1<<(WEAPON_SUIT)) )) return 1; diff --git a/cl_dll/hud.cpp b/cl_dll/hud.cpp index 7e2b46d08..fd2ee82e7 100644 --- a/cl_dll/hud.cpp +++ b/cl_dll/hud.cpp @@ -444,7 +444,7 @@ void CHud :: VidInit() // allocated memory for sprite handle arrays m_rghSprites = new HSPRITE[m_iSpriteCount]; - m_rgrcRects = new wrect_t[m_iSpriteCount]; + m_rgrcRects = new Rect[m_iSpriteCount]; m_rgszSpriteNames = new char[m_iSpriteCount * MAX_SPRITE_NAME_LENGTH]; p = m_pSpriteList; diff --git a/cl_dll/hud.h b/cl_dll/hud.h index f3e62f3db..81ecfda29 100644 --- a/cl_dll/hud.h +++ b/cl_dll/hud.h @@ -29,7 +29,7 @@ #define _cdecl #endif -#include "wrect.h" +#include "common_types.h" #include "cl_dll.h" #include "ammo.h" @@ -333,8 +333,8 @@ class CHudBattery: public CHudBase private: HSPRITE m_hSprite1; HSPRITE m_hSprite2; - wrect_t *m_prc1; - wrect_t *m_prc2; + Rect *m_prc1; + Rect *m_prc2; int m_iBat; int m_iBatMax; float m_fFade; @@ -359,9 +359,9 @@ class CHudFlashlight: public CHudBase HSPRITE m_hSprite1; HSPRITE m_hSprite2; HSPRITE m_hBeam; - wrect_t *m_prc1; - wrect_t *m_prc2; - wrect_t *m_prcBeam; + Rect *m_prc1; + Rect *m_prc2; + Rect *m_prcBeam; float m_flBat; int m_iBat; int m_fOn; @@ -471,7 +471,7 @@ class CHudStatusIcons: public CHudBase { char szSpriteName[MAX_ICONSPRITENAME_LENGTH]; HSPRITE spr; - wrect_t rc; + Rect rc; unsigned char r, g, b; } icon_sprite_t; @@ -526,7 +526,7 @@ class CHud // the memory for these arrays are allocated in the first call to CHud::VidInit(), when the hud.txt and associated sprites are loaded. // freed in ~CHud() HSPRITE *m_rghSprites; /*[HUD_SPRITE_COUNT]*/ // the sprites loaded from hud.txt - wrect_t *m_rgrcRects; /*[HUD_SPRITE_COUNT]*/ + Rect *m_rgrcRects; /*[HUD_SPRITE_COUNT]*/ char *m_rgszSpriteNames; /*[HUD_SPRITE_COUNT][MAX_SPRITE_NAME_LENGTH]*/ struct cvar_s *default_fov; @@ -536,7 +536,7 @@ class CHud return (index < 0) ? 0 : m_rghSprites[index]; } - wrect_t& GetSpriteRect( int index ) + Rect& GetSpriteRect( int index ) { return m_rgrcRects[index]; } diff --git a/cl_dll/hud_spectator.h b/cl_dll/hud_spectator.h index ed89318ca..e06aaee9f 100644 --- a/cl_dll/hud_spectator.h +++ b/cl_dll/hud_spectator.h @@ -140,7 +140,7 @@ class CHudSpectator : public CHudBase HSPRITE m_hsprBeam; HSPRITE m_hCrosshair; - wrect_t m_crosshairRect; + Rect m_crosshairRect; struct model_s * m_MapSprite; // each layer image is saved in one sprite, where each tile is a sprite frame float m_flNextObserverInput; diff --git a/cl_dll/in_camera.cpp b/cl_dll/in_camera.cpp index ef38f6492..fe94cca03 100644 --- a/cl_dll/in_camera.cpp +++ b/cl_dll/in_camera.cpp @@ -70,7 +70,7 @@ int iMouseInUse=0; int cam_distancemove; extern int mouse_x, mouse_y; //used to determine what the current x and y values are int cam_old_mouse_x, cam_old_mouse_y; //holds the last ticks mouse movement -POINT cam_mouse; +Point cam_mouse; //-------------------------------------------------- Local Variables static kbutton_t cam_pitchup, cam_pitchdown, cam_yawleft, cam_yawright; @@ -83,10 +83,10 @@ void CAM_ToFirstPerson(); void CAM_StartDistance(); void CAM_EndDistance(); -void SDL_GetCursorPos( POINT *p ) +void SDL_GetCursorPos( Point *p ) { - gEngfuncs.GetMousePosition( (int *)&p->x, (int *)&p->y ); -// SDL_GetMouseState( (int *)&p->x, (int *)&p->y ); + gEngfuncs.GetMousePosition( &p->x, &p->y ); +// SDL_GetMouseState( &p->x, &p->y ); } void SDL_SetCursorPos( const int x, const int y ) diff --git a/cl_dll/inputw32.cpp b/cl_dll/inputw32.cpp index a009c3bca..ba4c76e96 100644 --- a/cl_dll/inputw32.cpp +++ b/cl_dll/inputw32.cpp @@ -80,7 +80,6 @@ static cvar_t *m_mousethread_sleep; int mouse_buttons; int mouse_oldbuttonstate; -POINT current_pos; int old_mouse_x, old_mouse_y, mx_accum, my_accum; float mouse_x, mouse_y; @@ -179,6 +178,7 @@ void Force_CenterView_f () #ifdef _WIN32 long s_mouseDeltaX = 0; long s_mouseDeltaY = 0; +POINT current_pos; POINT old_mouse_pos; long ThreadInterlockedExchange( long *pDest, long value ) diff --git a/common/Platform.h b/common/Platform.h index 7a83a08ca..fcce01896 100644 --- a/common/Platform.h +++ b/common/Platform.h @@ -35,6 +35,7 @@ #pragma warning(disable : 4100) // unreferenced formal parameter #include "archtypes.h" // DAL +#include "common_types.h" // Misc C-runtime library headers #include diff --git a/cl_dll/wrect.h b/common/common_types.h similarity index 54% rename from cl_dll/wrect.h rename to common/common_types.h index a3494aed3..8a1d44da2 100644 --- a/cl_dll/wrect.h +++ b/common/common_types.h @@ -5,12 +5,24 @@ // $NoKeywords: $ //============================================================================= -#if !defined( WRECTH ) -#define WRECTH +#pragma once -typedef struct rect_s +/** +* @file +* +* Common data types +*/ + +struct Point { - int left, right, top, bottom; -} wrect_t; + int x = 0; + int y = 0; +}; -#endif \ No newline at end of file +struct Rect +{ + int left = 0; + int right = 0; + int top = 0; + int bottom = 0; +}; diff --git a/common/port.h b/common/port.h index 295d697ca..1497785f2 100644 --- a/common/port.h +++ b/common/port.h @@ -47,23 +47,10 @@ typedef char * LPSTR; #define MAX_PATH PATH_MAX #ifdef LINUX -typedef struct POINT_s -{ - int x; - int y; -} POINT; typedef void *HINSTANCE; typedef void *HWND; typedef void *HDC; typedef void *HGLRC; - -typedef struct RECT_s -{ - int left; - int right; - int top; - int bottom; -} RECT; #endif diff --git a/engine/APIProxy.h b/engine/APIProxy.h index 59f17e7be..078072bdc 100644 --- a/engine/APIProxy.h +++ b/engine/APIProxy.h @@ -4,6 +4,7 @@ #include "archtypes.h" // DAL #include "netadr.h" #include "Sequence.h" +#include "common_types.h" #ifndef _WIN32 #include "enums.h" @@ -223,15 +224,15 @@ typedef int (*pfnEngSrc_pfnSPR_Frames_t ) ( HSPRITE hPic ); typedef int (*pfnEngSrc_pfnSPR_Height_t ) ( HSPRITE hPic, int frame ); typedef int (*pfnEngSrc_pfnSPR_Width_t ) ( HSPRITE hPic, int frame ); typedef void (*pfnEngSrc_pfnSPR_Set_t ) ( HSPRITE hPic, int r, int g, int b ); -typedef void (*pfnEngSrc_pfnSPR_Draw_t ) ( int frame, int x, int y, const struct rect_s *prc ); -typedef void (*pfnEngSrc_pfnSPR_DrawHoles_t ) ( int frame, int x, int y, const struct rect_s *prc ); -typedef void (*pfnEngSrc_pfnSPR_DrawAdditive_t ) ( int frame, int x, int y, const struct rect_s *prc ); +typedef void (*pfnEngSrc_pfnSPR_Draw_t ) ( int frame, int x, int y, const Rect *prc ); +typedef void (*pfnEngSrc_pfnSPR_DrawHoles_t ) ( int frame, int x, int y, const Rect *prc ); +typedef void (*pfnEngSrc_pfnSPR_DrawAdditive_t ) ( int frame, int x, int y, const Rect *prc ); typedef void (*pfnEngSrc_pfnSPR_EnableScissor_t ) ( int x, int y, int width, int height ); typedef void (*pfnEngSrc_pfnSPR_DisableScissor_t ) ( void ); typedef struct client_sprite_s * (*pfnEngSrc_pfnSPR_GetList_t ) (const char *psz, int *piCount ); typedef void (*pfnEngSrc_pfnFillRGBA_t ) ( int x, int y, int width, int height, int r, int g, int b, int a ); typedef int (*pfnEngSrc_pfnGetScreenInfo_t ) ( struct SCREENINFO_s *pscrinfo ); -typedef void (*pfnEngSrc_pfnSetCrosshair_t ) ( HSPRITE hspr, wrect_t rc, int r, int g, int b ); +typedef void (*pfnEngSrc_pfnSetCrosshair_t ) ( HSPRITE hspr, Rect rc, int r, int g, int b ); typedef struct cvar_s * (*pfnEngSrc_pfnRegisterVariable_t ) ( const char *szName, const char *szValue, int flags ); typedef float (*pfnEngSrc_pfnGetCvarFloat_t ) ( const char *szName ); typedef const char* (*pfnEngSrc_pfnGetCvarString_t ) ( const char *szName ); @@ -319,7 +320,7 @@ typedef qboolean (*pfnEngSrc_GetPlayerUniqueID_t)(int iPlayer, char playerID typedef int (*pfnEngSrc_GetTrackerIDForPlayer_t)(int playerSlot); typedef int (*pfnEngSrc_GetPlayerForTrackerID_t)(int trackerID); typedef int (*pfnEngSrc_pfnServerCmdUnreliable_t )( char *szCmdString ); -typedef void (*pfnEngSrc_GetMousePos_t )(struct tagPOINT *ppt); +typedef void (*pfnEngSrc_GetMousePos_t )(Point *ppt); typedef void (*pfnEngSrc_SetMousePos_t )(int x, int y); typedef void (*pfnEngSrc_SetMouseEnable_t)(qboolean fEnable); typedef struct cvar_s * (*pfnEngSrc_GetFirstCVarPtr_t)(); @@ -333,7 +334,7 @@ typedef void (*pfnEngSrc_pfnSetFilterMode_t )( int mode ); typedef void (*pfnEngSrc_pfnSetFilterColor_t )( float r, float g, float b ); typedef void (*pfnEngSrc_pfnSetFilterBrightness_t )( float brightness ); typedef sequenceEntry_s* (*pfnEngSrc_pfnSequenceGet_t )( const char *fileName, const char* entryName ); -typedef void (*pfnEngSrc_pfnSPR_DrawGeneric_t )( int frame, int x, int y, const struct rect_s *prc, int src, int dest, int w, int h ); +typedef void (*pfnEngSrc_pfnSPR_DrawGeneric_t )( int frame, int x, int y, const Rect *prc, int src, int dest, int w, int h ); typedef sentenceEntry_s* (*pfnEngSrc_pfnSequencePickSentence_t )( const char *sentenceName, int pickMethod, int* entryPicked ); // draw a complete string typedef int (*pfnEngSrc_pfnDrawString_t ) ( int x, int y, const char *str, int r, int g, int b ); @@ -501,15 +502,15 @@ typedef void (*pfnEngDst_pfnSPR_Frames_t ) ( HSPRITE * ); typedef void (*pfnEngDst_pfnSPR_Height_t ) ( HSPRITE *, int * ); typedef void (*pfnEngDst_pfnSPR_Width_t ) ( HSPRITE *, int * ); typedef void (*pfnEngDst_pfnSPR_Set_t ) ( HSPRITE *, int *, int *, int * ); -typedef void (*pfnEngDst_pfnSPR_Draw_t ) ( int *, int *, int *, const struct rect_s ** ); -typedef void (*pfnEngDst_pfnSPR_DrawHoles_t ) ( int *, int *, int *, const struct rect_s ** ); -typedef void (*pfnEngDst_pfnSPR_DrawAdditive_t ) ( int *, int *, int *, const struct rect_s ** ); +typedef void (*pfnEngDst_pfnSPR_Draw_t ) ( int *, int *, int *, const Rect ** ); +typedef void (*pfnEngDst_pfnSPR_DrawHoles_t ) ( int *, int *, int *, const Rect ** ); +typedef void (*pfnEngDst_pfnSPR_DrawAdditive_t ) ( int *, int *, int *, const Rect ** ); typedef void (*pfnEngDst_pfnSPR_EnableScissor_t ) ( int *, int *, int *, int * ); typedef void (*pfnEngDst_pfnSPR_DisableScissor_t ) ( void ); typedef void (*pfnEngDst_pfnSPR_GetList_t ) ( char **, int ** ); typedef void (*pfnEngDst_pfnFillRGBA_t ) ( int *, int *, int *, int *, int *, int *, int *, int * ); typedef void (*pfnEngDst_pfnGetScreenInfo_t ) ( struct SCREENINFO_s ** ); -typedef void (*pfnEngDst_pfnSetCrosshair_t ) ( HSPRITE *, struct rect_s *, int *, int *, int * ); +typedef void (*pfnEngDst_pfnSetCrosshair_t ) ( HSPRITE *, Rect *, int *, int *, int * ); typedef void (*pfnEngDst_pfnRegisterVariable_t ) ( char **, char **, int * ); typedef void (*pfnEngDst_pfnGetCvarFloat_t ) ( char ** ); typedef void (*pfnEngDst_pfnGetCvarString_t ) ( char ** ); @@ -591,14 +592,14 @@ typedef void (*pfnEngDst_GetPlayerUniqueID_t) (int *, char **); typedef void (*pfnEngDst_GetTrackerIDForPlayer_t) (int *); typedef void (*pfnEngDst_GetPlayerForTrackerID_t) (int *); typedef void (*pfnEngDst_pfnServerCmdUnreliable_t ) ( char ** ); -typedef void (*pfnEngDst_GetMousePos_t ) (struct tagPOINT **); +typedef void (*pfnEngDst_GetMousePos_t ) (Point **); typedef void (*pfnEngDst_SetMousePos_t ) (int *, int *); typedef void (*pfnEngDst_SetMouseEnable_t ) (qboolean *); typedef void (*pfnEngDst_pfnSetFilterMode_t) ( int * ); typedef void (*pfnEngDst_pfnSetFilterColor_t) ( float *, float *, float * ); typedef void (*pfnEngDst_pfnSetFilterBrightness_t) ( float * ); typedef void (*pfnEngDst_pfnSequenceGet_t ) ( const char**, const char** ); -typedef void (*pfnEngDst_pfnSPR_DrawGeneric_t ) ( int *, int *, int *, const struct rect_s **, int *, int *, int *, int * ); +typedef void (*pfnEngDst_pfnSPR_DrawGeneric_t ) ( int *, int *, int *, const Rect **, int *, int *, int *, int * ); typedef void (*pfnEngDst_pfnSequencePickSentence_t ) ( const char**, int *, int ** ); typedef void (*pfnEngDst_pfnDrawString_t ) ( int *, int *, const char *, int *, int *, int * ); typedef void (*pfnEngDst_pfnDrawStringReverse_t ) ( int *, int *, const char *, int *, int *, int * ); diff --git a/engine/cdll_int.h b/engine/cdll_int.h index 319744193..0cf6a8a92 100644 --- a/engine/cdll_int.h +++ b/engine/cdll_int.h @@ -31,7 +31,7 @@ extern "C" { #include "ref_params.h" #include "r_efx.h" #include "studio_event.h" -#include "wrect.h" +#include "common_types.h" // this file is included by both the engine and the client-dll, // so make sure engine declarations aren't done twice @@ -70,7 +70,7 @@ typedef struct client_sprite_s char szSprite[64]; int hspr; int iRes; - wrect_t rc; + Rect rc; } client_sprite_t; diff --git a/game_shared/vgui_loadtga.cpp b/game_shared/vgui_loadtga.cpp index 69081ae68..0085669b8 100644 --- a/game_shared/vgui_loadtga.cpp +++ b/game_shared/vgui_loadtga.cpp @@ -5,7 +5,6 @@ // $NoKeywords: $ //============================================================================= -#include "../cl_dll/wrect.h" #include "../cl_dll/cl_dll.h" #include "VGUI.h" #include "vgui_loadtga.h" diff --git a/projects/vs2017/hl_cdll.vcxproj b/projects/vs2017/hl_cdll.vcxproj index 35d89dbad..6cfca3220 100644 --- a/projects/vs2017/hl_cdll.vcxproj +++ b/projects/vs2017/hl_cdll.vcxproj @@ -214,9 +214,9 @@ - + diff --git a/projects/vs2017/hl_cdll.vcxproj.filters b/projects/vs2017/hl_cdll.vcxproj.filters index c9dc0a683..2d2a83286 100644 --- a/projects/vs2017/hl_cdll.vcxproj.filters +++ b/projects/vs2017/hl_cdll.vcxproj.filters @@ -395,9 +395,6 @@ Header Files\game_shared - - Header Files\cl_dll - Header Files\cl_dll @@ -560,5 +557,8 @@ Header Files + + Header Files\common + \ No newline at end of file diff --git a/projects/vs2019/hl_cdll.vcxproj b/projects/vs2019/hl_cdll.vcxproj index 0e6ce28e3..3b4013ab2 100644 --- a/projects/vs2019/hl_cdll.vcxproj +++ b/projects/vs2019/hl_cdll.vcxproj @@ -214,9 +214,9 @@ - + diff --git a/projects/vs2019/hl_cdll.vcxproj.filters b/projects/vs2019/hl_cdll.vcxproj.filters index 7786a9a67..6b9714186 100644 --- a/projects/vs2019/hl_cdll.vcxproj.filters +++ b/projects/vs2019/hl_cdll.vcxproj.filters @@ -398,9 +398,6 @@ Header Files\game_shared - - Header Files\cl_dll - Header Files\cl_dll @@ -563,5 +560,8 @@ Header Files\engine + + Header Files\common + \ No newline at end of file From 74daa12d6c5fcf627e5dc9e0cc4b802de9463c36 Mon Sep 17 00:00:00 2001 From: Sam V Date: Thu, 18 Nov 2021 17:56:44 +0100 Subject: [PATCH 07/13] Remove obsolete engine APIs related to security modules Resolves #57 --- cl_dll/cdll_int.cpp | 5 - engine/APIProxy.h | 537 -------------------------------------------- engine/cdll_int.h | 360 ----------------------------- 3 files changed, 902 deletions(-) diff --git a/cl_dll/cdll_int.cpp b/cl_dll/cdll_int.cpp index 81bf411c9..9566d142e 100644 --- a/cl_dll/cdll_int.cpp +++ b/cl_dll/cdll_int.cpp @@ -334,15 +334,10 @@ void CL_LoadParticleMan() } } -cldll_func_dst_t *g_pcldstAddrs; - extern "C" void DLLEXPORT F(void *pv) { cldll_func_t *pcldll_func = (cldll_func_t *)pv; - // Hack! - g_pcldstAddrs = ((cldll_func_dst_t *)pcldll_func->pHudVidInitFunc); - cldll_func_t cldll_func = { Initialize, diff --git a/engine/APIProxy.h b/engine/APIProxy.h index 078072bdc..e1a41ca2b 100644 --- a/engine/APIProxy.h +++ b/engine/APIProxy.h @@ -120,100 +120,6 @@ typedef struct CLIENTFACTORY pClientFactory; } cldll_func_t; -// Function type declarations for client destination functions -typedef void (*DST_INITIALIZE_FUNC) ( struct cl_enginefuncs_s**, int *); -typedef void (*DST_HUD_INIT_FUNC) ( void ); -typedef void (*DST_HUD_VIDINIT_FUNC) ( void ); -typedef void (*DST_HUD_REDRAW_FUNC) ( float*, int* ); -typedef void (*DST_HUD_UPDATECLIENTDATA_FUNC) ( struct client_data_s**, float* ); -typedef void (*DST_HUD_RESET_FUNC) ( void ); -typedef void (*DST_HUD_CLIENTMOVE_FUNC)( struct playermove_s **, qboolean * ); -typedef void (*DST_HUD_CLIENTMOVEINIT_FUNC)( struct playermove_s ** ); -typedef void (*DST_HUD_TEXTURETYPE_FUNC)( char ** ); -typedef void (*DST_HUD_IN_ACTIVATEMOUSE_FUNC) ( void ); -typedef void (*DST_HUD_IN_DEACTIVATEMOUSE_FUNC) ( void ); -typedef void (*DST_HUD_IN_MOUSEEVENT_FUNC) ( int * ); -typedef void (*DST_HUD_IN_CLEARSTATES_FUNC) ( void ); -typedef void (*DST_HUD_IN_ACCUMULATE_FUNC ) ( void ); -typedef void (*DST_HUD_CL_CREATEMOVE_FUNC) ( float *, struct usercmd_s **, int * ); -typedef void (*DST_HUD_CL_ISTHIRDPERSON_FUNC) ( void ); -typedef void (*DST_HUD_CL_GETCAMERAOFFSETS_FUNC )( float ** ); -typedef void (*DST_HUD_KB_FIND_FUNC) ( const char ** ); -typedef void (*DST_HUD_CAMTHINK_FUNC )( void ); -typedef void (*DST_HUD_CALCREF_FUNC ) ( struct ref_params_s ** ); -typedef void (*DST_HUD_ADDENTITY_FUNC ) ( int *, struct cl_entity_s **, const char ** ); -typedef void (*DST_HUD_CREATEENTITIES_FUNC ) ( void ); -typedef void (*DST_HUD_DRAWNORMALTRIS_FUNC ) ( void ); -typedef void (*DST_HUD_DRAWTRANSTRIS_FUNC ) ( void ); -typedef void (*DST_HUD_STUDIOEVENT_FUNC ) ( const struct mstudioevent_s **, const struct cl_entity_s ** ); -typedef void (*DST_HUD_POSTRUNCMD_FUNC ) ( struct local_state_s **, struct local_state_s **, struct usercmd_s **, int *, double *, unsigned int * ); -typedef void (*DST_HUD_SHUTDOWN_FUNC ) ( void ); -typedef void (*DST_HUD_TXFERLOCALOVERRIDES_FUNC )( struct entity_state_s **, const struct clientdata_s ** ); -typedef void (*DST_HUD_PROCESSPLAYERSTATE_FUNC )( struct entity_state_s **, const struct entity_state_s ** ); -typedef void (*DST_HUD_TXFERPREDICTIONDATA_FUNC ) ( struct entity_state_s **, const struct entity_state_s **, struct clientdata_s **, const struct clientdata_s **, struct weapon_data_s **, const struct weapon_data_s ** ); -typedef void (*DST_HUD_DEMOREAD_FUNC ) ( int *, unsigned char ** ); -typedef void (*DST_HUD_CONNECTIONLESS_FUNC )( const struct netadr_s **, const char **, char **, int ** ); -typedef void (*DST_HUD_GETHULLBOUNDS_FUNC ) ( int *, float **, float ** ); -typedef void (*DST_HUD_FRAME_FUNC) ( double * ); -typedef void (*DST_HUD_KEY_EVENT_FUNC ) ( int *, int *, const char ** ); -typedef void (*DST_HUD_TEMPENTUPDATE_FUNC) ( double *, double *, double *, struct tempent_s ***, struct tempent_s ***, int ( **Callback_AddVisibleEntity )( struct cl_entity_s *pEntity ), void ( **Callback_TempEntPlaySound )( struct tempent_s *pTemp, float damp ) ); -typedef void (*DST_HUD_GETUSERENTITY_FUNC ) ( int * ); -typedef void (*DST_HUD_VOICESTATUS_FUNC)(int *, qboolean *); -typedef void (*DST_HUD_DIRECTORMESSAGE_FUNC)( int *, void ** ); -typedef void (*DST_HUD_STUDIO_INTERFACE_FUNC ) ( int *, struct r_studio_interface_s ***, struct engine_studio_api_s ** ); -typedef void (*DST_HUD_CHATINPUTPOSITION_FUNC)( int **, int ** ); -typedef void (*DST_HUD_GETPLAYERTEAM)(int); - -// Pointers to the client destination functions -typedef struct -{ - DST_INITIALIZE_FUNC pInitFunc; - DST_HUD_INIT_FUNC pHudInitFunc; - DST_HUD_VIDINIT_FUNC pHudVidInitFunc; - DST_HUD_REDRAW_FUNC pHudRedrawFunc; - DST_HUD_UPDATECLIENTDATA_FUNC pHudUpdateClientDataFunc; - DST_HUD_RESET_FUNC pHudResetFunc; - DST_HUD_CLIENTMOVE_FUNC pClientMove; - DST_HUD_CLIENTMOVEINIT_FUNC pClientMoveInit; - DST_HUD_TEXTURETYPE_FUNC pClientTextureType; - DST_HUD_IN_ACTIVATEMOUSE_FUNC pIN_ActivateMouse; - DST_HUD_IN_DEACTIVATEMOUSE_FUNC pIN_DeactivateMouse; - DST_HUD_IN_MOUSEEVENT_FUNC pIN_MouseEvent; - DST_HUD_IN_CLEARSTATES_FUNC pIN_ClearStates; - DST_HUD_IN_ACCUMULATE_FUNC pIN_Accumulate; - DST_HUD_CL_CREATEMOVE_FUNC pCL_CreateMove; - DST_HUD_CL_ISTHIRDPERSON_FUNC pCL_IsThirdPerson; - DST_HUD_CL_GETCAMERAOFFSETS_FUNC pCL_GetCameraOffsets; - DST_HUD_KB_FIND_FUNC pFindKey; - DST_HUD_CAMTHINK_FUNC pCamThink; - DST_HUD_CALCREF_FUNC pCalcRefdef; - DST_HUD_ADDENTITY_FUNC pAddEntity; - DST_HUD_CREATEENTITIES_FUNC pCreateEntities; - DST_HUD_DRAWNORMALTRIS_FUNC pDrawNormalTriangles; - DST_HUD_DRAWTRANSTRIS_FUNC pDrawTransparentTriangles; - DST_HUD_STUDIOEVENT_FUNC pStudioEvent; - DST_HUD_POSTRUNCMD_FUNC pPostRunCmd; - DST_HUD_SHUTDOWN_FUNC pShutdown; - DST_HUD_TXFERLOCALOVERRIDES_FUNC pTxferLocalOverrides; - DST_HUD_PROCESSPLAYERSTATE_FUNC pProcessPlayerState; - DST_HUD_TXFERPREDICTIONDATA_FUNC pTxferPredictionData; - DST_HUD_DEMOREAD_FUNC pReadDemoBuffer; - DST_HUD_CONNECTIONLESS_FUNC pConnectionlessPacket; - DST_HUD_GETHULLBOUNDS_FUNC pGetHullBounds; - DST_HUD_FRAME_FUNC pHudFrame; - DST_HUD_KEY_EVENT_FUNC pKeyEvent; - DST_HUD_TEMPENTUPDATE_FUNC pTempEntUpdate; - DST_HUD_GETUSERENTITY_FUNC pGetUserEntity; - DST_HUD_VOICESTATUS_FUNC pVoiceStatus; // Possibly null on old client dlls. - DST_HUD_DIRECTORMESSAGE_FUNC pDirectorMessage; // Possibly null on old client dlls. - DST_HUD_STUDIO_INTERFACE_FUNC pStudioInterface; // Not used by all clients - DST_HUD_CHATINPUTPOSITION_FUNC pChatInputPosition; // Not used by all clients - DST_HUD_GETPLAYERTEAM pGetPlayerTeam; // Not used by all clients -} cldll_func_dst_t; - - - - // ******************************************************** // Functions exported by the engine // ******************************************************** @@ -496,447 +402,4 @@ typedef struct cl_enginefuncs_s pfnEngSrc_pfnFilteredClientCmd_t pfnFilteredClientCmd; } cl_enginefunc_t; -// Function type declarations for engine destination functions -typedef void (*pfnEngDst_pfnSPR_Load_t ) ( const char ** ); -typedef void (*pfnEngDst_pfnSPR_Frames_t ) ( HSPRITE * ); -typedef void (*pfnEngDst_pfnSPR_Height_t ) ( HSPRITE *, int * ); -typedef void (*pfnEngDst_pfnSPR_Width_t ) ( HSPRITE *, int * ); -typedef void (*pfnEngDst_pfnSPR_Set_t ) ( HSPRITE *, int *, int *, int * ); -typedef void (*pfnEngDst_pfnSPR_Draw_t ) ( int *, int *, int *, const Rect ** ); -typedef void (*pfnEngDst_pfnSPR_DrawHoles_t ) ( int *, int *, int *, const Rect ** ); -typedef void (*pfnEngDst_pfnSPR_DrawAdditive_t ) ( int *, int *, int *, const Rect ** ); -typedef void (*pfnEngDst_pfnSPR_EnableScissor_t ) ( int *, int *, int *, int * ); -typedef void (*pfnEngDst_pfnSPR_DisableScissor_t ) ( void ); -typedef void (*pfnEngDst_pfnSPR_GetList_t ) ( char **, int ** ); -typedef void (*pfnEngDst_pfnFillRGBA_t ) ( int *, int *, int *, int *, int *, int *, int *, int * ); -typedef void (*pfnEngDst_pfnGetScreenInfo_t ) ( struct SCREENINFO_s ** ); -typedef void (*pfnEngDst_pfnSetCrosshair_t ) ( HSPRITE *, Rect *, int *, int *, int * ); -typedef void (*pfnEngDst_pfnRegisterVariable_t ) ( char **, char **, int * ); -typedef void (*pfnEngDst_pfnGetCvarFloat_t ) ( char ** ); -typedef void (*pfnEngDst_pfnGetCvarString_t ) ( char ** ); -typedef void (*pfnEngDst_pfnAddCommand_t ) ( char **, void (**pfnEngDst_function)(void) ); -typedef void (*pfnEngDst_pfnHookUserMsg_t ) ( char **, pfnUserMsgHook * ); -typedef void (*pfnEngDst_pfnServerCmd_t ) ( char ** ); -typedef void (*pfnEngDst_pfnClientCmd_t ) ( char ** ); -typedef void (*pfnEngDst_pfnPrimeMusicStream_t ) ( char **, int *); -typedef void (*pfnEngDst_pfnGetPlayerInfo_t ) ( int *, struct hud_player_info_s ** ); -typedef void (*pfnEngDst_pfnPlaySoundByName_t ) ( char **, float * ); -typedef void (*pfnEngDst_pfnPlaySoundByNameAtPitch_t ) ( char **, float *, int * ); -typedef void (*pfnEngDst_pfnPlaySoundVoiceByName_t ) (char **, float * ); -typedef void (*pfnEngDst_pfnPlaySoundByIndex_t ) ( int *, float * ); -typedef void (*pfnEngDst_pfnAngleVectors_t ) ( const float * *, float * *, float * *, float * * ); -typedef void (*pfnEngDst_pfnTextMessageGet_t ) ( const char ** ); -typedef void (*pfnEngDst_pfnDrawCharacter_t ) ( int *, int *, int *, int *, int *, int * ); -typedef void (*pfnEngDst_pfnDrawConsoleString_t ) ( int *, int *, char ** ); -typedef void (*pfnEngDst_pfnDrawSetTextColor_t ) ( float *, float *, float * ); -typedef void (*pfnEngDst_pfnDrawConsoleStringLen_t ) ( const char **, int **, int ** ); -typedef void (*pfnEngDst_pfnConsolePrint_t ) ( const char ** ); -typedef void (*pfnEngDst_pfnCenterPrint_t ) ( const char ** ); -typedef void (*pfnEngDst_GetWindowCenterX_t ) ( void ); -typedef void (*pfnEngDst_GetWindowCenterY_t ) ( void ); -typedef void (*pfnEngDst_GetViewAngles_t ) ( float ** ); -typedef void (*pfnEngDst_SetViewAngles_t ) ( float ** ); -typedef void (*pfnEngDst_GetMaxClients_t ) ( void ); -typedef void (*pfnEngDst_Cvar_SetValue_t ) ( char **, float * ); -typedef void (*pfnEngDst_Cmd_Argc_t) (void); -typedef void (*pfnEngDst_Cmd_Argv_t ) ( int * ); -typedef void (*pfnEngDst_Con_Printf_t ) ( char **); -typedef void (*pfnEngDst_Con_DPrintf_t ) ( char **); -typedef void (*pfnEngDst_Con_NPrintf_t ) ( int *, char ** ); -typedef void (*pfnEngDst_Con_NXPrintf_t ) ( struct con_nprint_s **, char **); -typedef void (*pfnEngDst_PhysInfo_ValueForKey_t ) ( const char ** ); -typedef void (*pfnEngDst_ServerInfo_ValueForKey_t ) ( const char ** ); -typedef void (*pfnEngDst_GetClientMaxspeed_t ) ( void ); -typedef void (*pfnEngDst_CheckParm_t ) ( char **, char *** ); -typedef void (*pfnEngDst_Key_Event_t ) ( int *, int * ); -typedef void (*pfnEngDst_GetMousePosition_t ) ( int **, int ** ); -typedef void (*pfnEngDst_IsNoClipping_t ) ( void ); -typedef void (*pfnEngDst_GetLocalPlayer_t ) ( void ); -typedef void (*pfnEngDst_GetViewModel_t ) ( void ); -typedef void (*pfnEngDst_GetEntityByIndex_t ) ( int * ); -typedef void (*pfnEngDst_GetClientTime_t ) ( void ); -typedef void (*pfnEngDst_V_CalcShake_t ) ( void ); -typedef void (*pfnEngDst_V_ApplyShake_t ) ( float **, float **, float * ); -typedef void (*pfnEngDst_PM_PointContents_t ) ( float **, int ** ); -typedef void (*pfnEngDst_PM_WaterEntity_t ) ( float ** ); -typedef void (*pfnEngDst_PM_TraceLine_t ) ( float **, float **, int *, int *, int * ); -typedef void (*pfnEngDst_CL_LoadModel_t ) ( const char **, int ** ); -typedef void (*pfnEngDst_CL_CreateVisibleEntity_t ) ( int *, struct cl_entity_s ** ); -typedef void (*pfnEngDst_GetSpritePointer_t ) ( HSPRITE * ); -typedef void (*pfnEngDst_pfnPlaySoundByNameAtLocation_t ) ( char **, float *, float ** ); -typedef void (*pfnEngDst_pfnPrecacheEvent_t ) ( int *, const char* * ); -typedef void (*pfnEngDst_pfnPlaybackEvent_t ) ( int *, const struct edict_s **, unsigned short *, float *, float **, float **, float *, float *, int *, int *, int *, int * ); -typedef void (*pfnEngDst_pfnWeaponAnim_t ) ( int *, int * ); -typedef void (*pfnEngDst_pfnRandomFloat_t ) ( float *, float * ); -typedef void (*pfnEngDst_pfnRandomLong_t ) ( int32 *, int32 * ); -typedef void (*pfnEngDst_pfnHookEvent_t ) ( char **, void ( **pfnEvent )( struct event_args_s *args ) ); -typedef void (*pfnEngDst_Con_IsVisible_t) (); -typedef void (*pfnEngDst_pfnGetGameDirectory_t ) ( void ); -typedef void (*pfnEngDst_pfnGetCvarPointer_t ) ( const char ** ); -typedef void (*pfnEngDst_Key_LookupBinding_t ) ( const char ** ); -typedef void (*pfnEngDst_pfnGetLevelName_t ) ( void ); -typedef void (*pfnEngDst_pfnGetScreenFade_t ) ( struct screenfade_s ** ); -typedef void (*pfnEngDst_pfnSetScreenFade_t ) ( struct screenfade_s ** ); -typedef void (*pfnEngDst_VGui_GetPanel_t ) ( ); -typedef void (*pfnEngDst_VGui_ViewportPaintBackground_t ) (int **); -typedef void (*pfnEngDst_COM_LoadFile_t ) ( char **, int *, int ** ); -typedef void (*pfnEngDst_COM_ParseFile_t ) ( char **, char ** ); -typedef void (*pfnEngDst_COM_FreeFile_t) ( void ** ); -typedef void (*pfnEngDst_IsSpectateOnly_t ) ( void ); -typedef void (*pfnEngDst_LoadMapSprite_t ) ( const char ** ); -typedef void (*pfnEngDst_COM_AddAppDirectoryToSearchPath_t ) ( const char **, const char ** ); -typedef void (*pfnEngDst_COM_ExpandFilename_t) ( const char **, char **, int * ); -typedef void (*pfnEngDst_PlayerInfo_ValueForKey_t ) ( int *, const char ** ); -typedef void (*pfnEngDst_PlayerInfo_SetValueForKey_t )( const char **, const char ** ); -typedef void (*pfnEngDst_GetPlayerUniqueID_t) (int *, char **); -typedef void (*pfnEngDst_GetTrackerIDForPlayer_t) (int *); -typedef void (*pfnEngDst_GetPlayerForTrackerID_t) (int *); -typedef void (*pfnEngDst_pfnServerCmdUnreliable_t ) ( char ** ); -typedef void (*pfnEngDst_GetMousePos_t ) (Point **); -typedef void (*pfnEngDst_SetMousePos_t ) (int *, int *); -typedef void (*pfnEngDst_SetMouseEnable_t ) (qboolean *); -typedef void (*pfnEngDst_pfnSetFilterMode_t) ( int * ); -typedef void (*pfnEngDst_pfnSetFilterColor_t) ( float *, float *, float * ); -typedef void (*pfnEngDst_pfnSetFilterBrightness_t) ( float * ); -typedef void (*pfnEngDst_pfnSequenceGet_t ) ( const char**, const char** ); -typedef void (*pfnEngDst_pfnSPR_DrawGeneric_t ) ( int *, int *, int *, const Rect **, int *, int *, int *, int * ); -typedef void (*pfnEngDst_pfnSequencePickSentence_t ) ( const char**, int *, int ** ); -typedef void (*pfnEngDst_pfnDrawString_t ) ( int *, int *, const char *, int *, int *, int * ); -typedef void (*pfnEngDst_pfnDrawStringReverse_t ) ( int *, int *, const char *, int *, int *, int * ); -typedef void (*pfnEngDst_LocalPlayerInfo_ValueForKey_t )( const char **); -typedef void (*pfnEngDst_pfnVGUI2DrawCharacter_t ) ( int *, int *, int *, unsigned int * ); -typedef void (*pfnEngDst_pfnVGUI2DrawCharacterAdd_t ) ( int *, int *, int *, int *, int *, int *, unsigned int *); -typedef void (*pfnEngDst_pfnProcessTutorMessageDecayBuffer_t )(int **, int *); -typedef void (*pfnEngDst_pfnConstructTutorMessageDecayBuffer_t )(int **, int *); -typedef void (*pfnEngDst_pfnResetTutorMessageDecayData_t)(); -typedef void (*pfnEngDst_pfnFillRGBABlend_t ) ( int *, int *, int *, int *, int *, int *, int *, int * ); -typedef void (*pfnEngDst_pfnGetAppID_t ) ( void ); -typedef void (*pfnEngDst_pfnGetAliases_t ) ( void ); -typedef void (*pfnEngDst_pfnVguiWrap2_GetMouseDelta_t) ( int *x, int *y ); - - -// Pointers to the engine destination functions -typedef struct -{ - pfnEngDst_pfnSPR_Load_t pfnSPR_Load; - pfnEngDst_pfnSPR_Frames_t pfnSPR_Frames; - pfnEngDst_pfnSPR_Height_t pfnSPR_Height; - pfnEngDst_pfnSPR_Width_t pfnSPR_Width; - pfnEngDst_pfnSPR_Set_t pfnSPR_Set; - pfnEngDst_pfnSPR_Draw_t pfnSPR_Draw; - pfnEngDst_pfnSPR_DrawHoles_t pfnSPR_DrawHoles; - pfnEngDst_pfnSPR_DrawAdditive_t pfnSPR_DrawAdditive; - pfnEngDst_pfnSPR_EnableScissor_t pfnSPR_EnableScissor; - pfnEngDst_pfnSPR_DisableScissor_t pfnSPR_DisableScissor; - pfnEngDst_pfnSPR_GetList_t pfnSPR_GetList; - pfnEngDst_pfnFillRGBA_t pfnFillRGBA; - pfnEngDst_pfnGetScreenInfo_t pfnGetScreenInfo; - pfnEngDst_pfnSetCrosshair_t pfnSetCrosshair; - pfnEngDst_pfnRegisterVariable_t pfnRegisterVariable; - pfnEngDst_pfnGetCvarFloat_t pfnGetCvarFloat; - pfnEngDst_pfnGetCvarString_t pfnGetCvarString; - pfnEngDst_pfnAddCommand_t pfnAddCommand; - pfnEngDst_pfnHookUserMsg_t pfnHookUserMsg; - pfnEngDst_pfnServerCmd_t pfnServerCmd; - pfnEngDst_pfnClientCmd_t pfnClientCmd; - pfnEngDst_pfnGetPlayerInfo_t pfnGetPlayerInfo; - pfnEngDst_pfnPlaySoundByName_t pfnPlaySoundByName; - pfnEngDst_pfnPlaySoundByIndex_t pfnPlaySoundByIndex; - pfnEngDst_pfnAngleVectors_t pfnAngleVectors; - pfnEngDst_pfnTextMessageGet_t pfnTextMessageGet; - pfnEngDst_pfnDrawCharacter_t pfnDrawCharacter; - pfnEngDst_pfnDrawConsoleString_t pfnDrawConsoleString; - pfnEngDst_pfnDrawSetTextColor_t pfnDrawSetTextColor; - pfnEngDst_pfnDrawConsoleStringLen_t pfnDrawConsoleStringLen; - pfnEngDst_pfnConsolePrint_t pfnConsolePrint; - pfnEngDst_pfnCenterPrint_t pfnCenterPrint; - pfnEngDst_GetWindowCenterX_t GetWindowCenterX; - pfnEngDst_GetWindowCenterY_t GetWindowCenterY; - pfnEngDst_GetViewAngles_t GetViewAngles; - pfnEngDst_SetViewAngles_t SetViewAngles; - pfnEngDst_GetMaxClients_t GetMaxClients; - pfnEngDst_Cvar_SetValue_t Cvar_SetValue; - pfnEngDst_Cmd_Argc_t Cmd_Argc; - pfnEngDst_Cmd_Argv_t Cmd_Argv; - pfnEngDst_Con_Printf_t Con_Printf; - pfnEngDst_Con_DPrintf_t Con_DPrintf; - pfnEngDst_Con_NPrintf_t Con_NPrintf; - pfnEngDst_Con_NXPrintf_t Con_NXPrintf; - pfnEngDst_PhysInfo_ValueForKey_t PhysInfo_ValueForKey; - pfnEngDst_ServerInfo_ValueForKey_t ServerInfo_ValueForKey; - pfnEngDst_GetClientMaxspeed_t GetClientMaxspeed; - pfnEngDst_CheckParm_t CheckParm; - pfnEngDst_Key_Event_t Key_Event; - pfnEngDst_GetMousePosition_t GetMousePosition; - pfnEngDst_IsNoClipping_t IsNoClipping; - pfnEngDst_GetLocalPlayer_t GetLocalPlayer; - pfnEngDst_GetViewModel_t GetViewModel; - pfnEngDst_GetEntityByIndex_t GetEntityByIndex; - pfnEngDst_GetClientTime_t GetClientTime; - pfnEngDst_V_CalcShake_t V_CalcShake; - pfnEngDst_V_ApplyShake_t V_ApplyShake; - pfnEngDst_PM_PointContents_t PM_PointContents; - pfnEngDst_PM_WaterEntity_t PM_WaterEntity; - pfnEngDst_PM_TraceLine_t PM_TraceLine; - pfnEngDst_CL_LoadModel_t CL_LoadModel; - pfnEngDst_CL_CreateVisibleEntity_t CL_CreateVisibleEntity; - pfnEngDst_GetSpritePointer_t GetSpritePointer; - pfnEngDst_pfnPlaySoundByNameAtLocation_t pfnPlaySoundByNameAtLocation; - pfnEngDst_pfnPrecacheEvent_t pfnPrecacheEvent; - pfnEngDst_pfnPlaybackEvent_t pfnPlaybackEvent; - pfnEngDst_pfnWeaponAnim_t pfnWeaponAnim; - pfnEngDst_pfnRandomFloat_t pfnRandomFloat; - pfnEngDst_pfnRandomLong_t pfnRandomLong; - pfnEngDst_pfnHookEvent_t pfnHookEvent; - pfnEngDst_Con_IsVisible_t Con_IsVisible; - pfnEngDst_pfnGetGameDirectory_t pfnGetGameDirectory; - pfnEngDst_pfnGetCvarPointer_t pfnGetCvarPointer; - pfnEngDst_Key_LookupBinding_t Key_LookupBinding; - pfnEngDst_pfnGetLevelName_t pfnGetLevelName; - pfnEngDst_pfnGetScreenFade_t pfnGetScreenFade; - pfnEngDst_pfnSetScreenFade_t pfnSetScreenFade; - pfnEngDst_VGui_GetPanel_t VGui_GetPanel; - pfnEngDst_VGui_ViewportPaintBackground_t VGui_ViewportPaintBackground; - pfnEngDst_COM_LoadFile_t COM_LoadFile; - pfnEngDst_COM_ParseFile_t COM_ParseFile; - pfnEngDst_COM_FreeFile_t COM_FreeFile; - struct triangleapi_s *pTriAPI; - struct efx_api_s *pEfxAPI; - struct event_api_s *pEventAPI; - struct demo_api_s *pDemoAPI; - struct net_api_s *pNetAPI; - struct IVoiceTweak_s *pVoiceTweak; - pfnEngDst_IsSpectateOnly_t IsSpectateOnly; - pfnEngDst_LoadMapSprite_t LoadMapSprite; - pfnEngDst_COM_AddAppDirectoryToSearchPath_t COM_AddAppDirectoryToSearchPath; - pfnEngDst_COM_ExpandFilename_t COM_ExpandFilename; - pfnEngDst_PlayerInfo_ValueForKey_t PlayerInfo_ValueForKey; - pfnEngDst_PlayerInfo_SetValueForKey_t PlayerInfo_SetValueForKey; - pfnEngDst_GetPlayerUniqueID_t GetPlayerUniqueID; - pfnEngDst_GetTrackerIDForPlayer_t GetTrackerIDForPlayer; - pfnEngDst_GetPlayerForTrackerID_t GetPlayerForTrackerID; - pfnEngDst_pfnServerCmdUnreliable_t pfnServerCmdUnreliable; - pfnEngDst_GetMousePos_t pfnGetMousePos; - pfnEngDst_SetMousePos_t pfnSetMousePos; - pfnEngDst_SetMouseEnable_t pfnSetMouseEnable; - pfnEngDst_pfnSetFilterMode_t pfnSetFilterMode ; - pfnEngDst_pfnSetFilterColor_t pfnSetFilterColor ; - pfnEngDst_pfnSetFilterBrightness_t pfnSetFilterBrightness ; - pfnEngDst_pfnSequenceGet_t pfnSequenceGet; - pfnEngDst_pfnSPR_DrawGeneric_t pfnSPR_DrawGeneric; - pfnEngDst_pfnSequencePickSentence_t pfnSequencePickSentence; - pfnEngDst_pfnDrawString_t pfnDrawString; - pfnEngDst_pfnDrawString_t pfnDrawStringReverse; - pfnEngDst_LocalPlayerInfo_ValueForKey_t LocalPlayerInfo_ValueForKey; - pfnEngDst_pfnVGUI2DrawCharacter_t pfnVGUI2DrawCharacter; - pfnEngDst_pfnVGUI2DrawCharacterAdd_t pfnVGUI2DrawCharacterAdd; - pfnEngDst_pfnPlaySoundVoiceByName_t pfnPlaySoundVoiceByName; - pfnEngDst_pfnPrimeMusicStream_t pfnPrimeMusicStream; - pfnEngDst_pfnProcessTutorMessageDecayBuffer_t pfnProcessTutorMessageDecayBuffer; - pfnEngDst_pfnConstructTutorMessageDecayBuffer_t pfnConstructTutorMessageDecayBuffer; - pfnEngDst_pfnResetTutorMessageDecayData_t pfnResetTutorMessageDecayData; - pfnEngDst_pfnPlaySoundByNameAtPitch_t pfnPlaySoundByNameAtPitch; - pfnEngDst_pfnFillRGBABlend_t pfnFillRGBABlend; - pfnEngDst_pfnGetAppID_t pfnGetAppID; - pfnEngDst_pfnGetAliases_t pfnGetAliasList; - pfnEngDst_pfnVguiWrap2_GetMouseDelta_t pfnVguiWrap2_GetMouseDelta; -} cl_enginefunc_dst_t; - - -// ******************************************************** -// Functions exposed by the engine to the module -// ******************************************************** - -// Functions for ModuleS -typedef void (*PFN_KICKPLAYER)(int nPlayerSlot, int nReason); - -typedef struct modshelpers_s -{ - PFN_KICKPLAYER m_pfnKickPlayer; - - // reserved for future expansion - int m_nVoid1; - int m_nVoid2; - int m_nVoid3; - int m_nVoid4; - int m_nVoid5; - int m_nVoid6; - int m_nVoid7; - int m_nVoid8; - int m_nVoid9; -} modshelpers_t; - -// Functions for moduleC -typedef struct modchelpers_s -{ - // reserved for future expansion - int m_nVoid0; - int m_nVoid1; - int m_nVoid2; - int m_nVoid3; - int m_nVoid4; - int m_nVoid5; - int m_nVoid6; - int m_nVoid7; - int m_nVoid8; - int m_nVoid9; -} modchelpers_t; - - -// ******************************************************** -// Information about the engine -// ******************************************************** -typedef struct engdata_s -{ - cl_enginefunc_t *pcl_enginefuncs; // functions exported by the engine - cl_enginefunc_dst_t *pg_engdstAddrs; // destination handlers for engine exports - cldll_func_t *pcl_funcs; // client exports - cldll_func_dst_t *pg_cldstAddrs; // client export destination handlers - struct modfuncs_s *pg_modfuncs; // engine's pointer to module functions - struct cmd_function_s **pcmd_functions; // list of all registered commands - void *pkeybindings; // all key bindings (not really a void *, but easier this way) - void (*pfnConPrintf)(char *, ...); // dump to console - struct cvar_s **pcvar_vars; // pointer to head of cvar list - struct glwstate_t *pglwstate; // OpenGl information - void *(*pfnSZ_GetSpace)(struct sizebuf_s *, int); // pointer to SZ_GetSpace - struct modfuncs_s *pmodfuncs; // &g_modfuncs - void *pfnGetProcAddress; // &GetProcAddress - void *pfnGetModuleHandle; // &GetModuleHandle - struct server_static_s *psvs; // &svs - struct client_static_s *pcls; // &cls - void (*pfnSV_DropClient)(struct client_s *, qboolean, char *, ...); // pointer to SV_DropClient - void (*pfnNetchan_Transmit)(struct netchan_s *, int, byte *); // pointer to Netchan_Transmit - void (*pfnNET_SendPacket)(enum netsrc_s sock, int length, void *data, netadr_t to); // &NET_SendPacket - struct cvar_s *(*pfnCvarFindVar)(const char *pchName); // pointer to Cvar_FindVar - int *phinstOpenGlEarly; // &g_hinstOpenGlEarly - - // Reserved for future expansion - void *pVoid0; // reserved for future expan - void *pVoid1; // reserved for future expan - void *pVoid2; // reserved for future expan - void *pVoid3; // reserved for future expan - void *pVoid4; // reserved for future expan - void *pVoid5; // reserved for future expan - void *pVoid6; // reserved for future expan - void *pVoid7; // reserved for future expan - void *pVoid8; // reserved for future expan - void *pVoid9; // reserved for future expan -} engdata_t; - - -// ******************************************************** -// Functions exposed by the security module -// ******************************************************** -typedef void (*PFN_LOADMOD)(char *pchModule); -typedef void (*PFN_CLOSEMOD)(void); -typedef int (*PFN_NCALL)(int ijump, int cnArg, ...); - -typedef void (*PFN_GETCLDSTADDRS)(cldll_func_dst_t *pcldstAddrs); -typedef void (*PFN_GETENGDSTADDRS)(cl_enginefunc_dst_t *pengdstAddrs); -typedef void (*PFN_MODULELOADED)(void); - -typedef void (*PFN_PROCESSOUTGOINGNET)(struct netchan_s *pchan, struct sizebuf_s *psizebuf); -typedef qboolean (*PFN_PROCESSINCOMINGNET)(struct netchan_s *pchan, struct sizebuf_s *psizebuf); - -typedef void (*PFN_TEXTURELOAD)(char *pszName, int dxWidth, int dyHeight, char *pbData); -typedef void (*PFN_MODELLOAD)(struct model_s *pmodel, void *pvBuf); - -typedef void (*PFN_FRAMEBEGIN)(void); -typedef void (*PFN_FRAMERENDER1)(void); -typedef void (*PFN_FRAMERENDER2)(void); - -typedef void (*PFN_SETMODSHELPERS)(modshelpers_t *pmodshelpers); -typedef void (*PFN_SETMODCHELPERS)(modchelpers_t *pmodchelpers); -typedef void (*PFN_SETENGDATA)(engdata_t *pengdata); - -typedef void (*PFN_CONNECTCLIENT)(int iPlayer); -typedef void (*PFN_RECORDIP)(unsigned int pnIP); -typedef void (*PFN_PLAYERSTATUS)(unsigned char *pbData, int cbData); - -typedef void (*PFN_SETENGINEVERSION)(int nVersion); - -// typedef class CMachine *(*PFN_PCMACHINE)(void); -typedef int (*PFN_PCMACHINE)(void); -typedef void (*PFN_SETIP)(int ijump); -typedef void (*PFN_EXECUTE)(void); - -typedef struct modfuncs_s -{ - // Functions for the pcode interpreter - PFN_LOADMOD m_pfnLoadMod; - PFN_CLOSEMOD m_pfnCloseMod; - PFN_NCALL m_pfnNCall; - - // API destination functions - PFN_GETCLDSTADDRS m_pfnGetClDstAddrs; - PFN_GETENGDSTADDRS m_pfnGetEngDstAddrs; - - // Miscellaneous functions - PFN_MODULELOADED m_pfnModuleLoaded; // Called right after the module is loaded - - // Functions for processing network traffic - PFN_PROCESSOUTGOINGNET m_pfnProcessOutgoingNet; // Every outgoing packet gets run through this - PFN_PROCESSINCOMINGNET m_pfnProcessIncomingNet; // Every incoming packet gets run through this - - // Resource functions - PFN_TEXTURELOAD m_pfnTextureLoad; // Called as each texture is loaded - PFN_MODELLOAD m_pfnModelLoad; // Called as each model is loaded - - // Functions called every frame - PFN_FRAMEBEGIN m_pfnFrameBegin; // Called at the beginning of each frame cycle - PFN_FRAMERENDER1 m_pfnFrameRender1; // Called at the beginning of the render loop - PFN_FRAMERENDER2 m_pfnFrameRender2; // Called at the end of the render loop - - // Module helper transfer - PFN_SETMODSHELPERS m_pfnSetModSHelpers; - PFN_SETMODCHELPERS m_pfnSetModCHelpers; - PFN_SETENGDATA m_pfnSetEngData; - - // Which version of the module is this? - int m_nVersion; - - // Miscellaneous game stuff - PFN_CONNECTCLIENT m_pfnConnectClient; // Called whenever a new client connects - PFN_RECORDIP m_pfnRecordIP; // Secure master has reported a new IP for us - PFN_PLAYERSTATUS m_pfnPlayerStatus; // Called whenever we receive a PlayerStatus packet - - // Recent additions - PFN_SETENGINEVERSION m_pfnSetEngineVersion; // 1 = patched engine - - // reserved for future expansion - int m_nVoid2; - int m_nVoid3; - int m_nVoid4; - int m_nVoid5; - int m_nVoid6; - int m_nVoid7; - int m_nVoid8; - int m_nVoid9; -} modfuncs_t; - - -#define k_nEngineVersion15Base 0 -#define k_nEngineVersion15Patch 1 -#define k_nEngineVersion16Base 2 -#define k_nEngineVersion16Validated 3 // 1.6 engine with built-in validation - - -typedef struct validator_s -{ - int m_nRandomizer; // Random number to be XOR'd into all subsequent fields - int m_nSignature1; // First signature that identifies this structure - int m_nSignature2; // Second signature - int m_pbCode; // Beginning of the code block - int m_cbCode; // Size of the code block - int m_nChecksum; // Checksum of the code block - int m_nSpecial; // For engine, 1 if hw.dll, 0 if sw.dll. For client, pclfuncs checksum - int m_nCompensator; // Keeps the checksum correct -} validator_t; - - -#define k_nChecksumCompensator 0x36a8f09c // Don't change this value: it's hardcorded in cdll_int.cpp, - -#define k_nModuleVersionCur 0x43210004 - - #endif // __APIPROXY__ diff --git a/engine/cdll_int.h b/engine/cdll_int.h index 0cf6a8a92..4f4503a7c 100644 --- a/engine/cdll_int.h +++ b/engine/cdll_int.h @@ -91,375 +91,15 @@ typedef struct hud_player_info_s uint64 m_nSteamID; } hud_player_info_t; - - -typedef struct module_s -{ - unsigned char ucMD5Hash[16]; // hash over code - qboolean fLoaded; // true if successfully loaded -} module_t; - - - - - - #ifndef IN_BUTTONS_H #include "in_buttons.h" #endif #define CLDLL_INTERFACE_VERSION 7 -extern void LoadSecurityModuleFromDisk(char * pszDllName); -extern void LoadSecurityModuleFromMemory( unsigned char * pCode, int nSize ); -extern void CloseSecurityModule(); - - -extern void ClientDLL_Init( void ); // from cdll_int.c -extern void ClientDLL_Shutdown( void ); -extern void ClientDLL_HudInit( void ); -extern void ClientDLL_HudVidInit( void ); -extern void ClientDLL_UpdateClientData( void ); -extern void ClientDLL_Frame( double time ); -extern void ClientDLL_HudRedraw( int intermission ); -extern void ClientDLL_MoveClient( struct playermove_s *ppmove ); -extern void ClientDLL_ClientMoveInit( struct playermove_s *ppmove ); -extern char ClientDLL_ClientTextureType( char *name ); - -extern void ClientDLL_CreateMove( float frametime, struct usercmd_s *cmd, int active ); -extern void ClientDLL_ActivateMouse( void ); -extern void ClientDLL_DeactivateMouse( void ); -extern void ClientDLL_MouseEvent( int mstate ); -extern void ClientDLL_ClearStates( void ); -extern int ClientDLL_IsThirdPerson( void ); -extern void ClientDLL_GetCameraOffsets( float *ofs ); -extern int ClientDLL_GraphKeyDown( void ); -extern struct kbutton_s *ClientDLL_FindKey( const char *name ); -extern void ClientDLL_CAM_Think( void ); -extern void ClientDLL_IN_Accumulate( void ); -extern void ClientDLL_CalcRefdef( struct ref_params_s *pparams ); -extern int ClientDLL_AddEntity( int type, struct cl_entity_s *ent ); -extern void ClientDLL_CreateEntities( void ); - -extern void ClientDLL_DrawNormalTriangles( void ); -extern void ClientDLL_DrawTransparentTriangles( void ); -extern void ClientDLL_StudioEvent( const struct mstudioevent_s *event, const struct cl_entity_s *entity ); -extern void ClientDLL_PostRunCmd( struct local_state_s *from, struct local_state_s *to, struct usercmd_s *cmd, int runfuncs, double time, unsigned int random_seed ); -extern void ClientDLL_TxferLocalOverrides( struct entity_state_s *state, const struct clientdata_s *client ); -extern void ClientDLL_ProcessPlayerState( struct entity_state_s *dst, const struct entity_state_s *src ); -extern void ClientDLL_TxferPredictionData ( struct entity_state_s *ps, const struct entity_state_s *pps, struct clientdata_s *pcd, const struct clientdata_s *ppcd, struct weapon_data_s *wd, const struct weapon_data_s *pwd ); -extern void ClientDLL_ReadDemoBuffer( int size, unsigned char *buffer ); -extern int ClientDLL_ConnectionlessPacket( const struct netadr_s *net_from, const char *args, char *response_buffer, int *response_buffer_size ); -extern int ClientDLL_GetHullBounds( int hullnumber, float *mins, float *maxs ); - -extern void ClientDLL_VGui_ConsolePrint(const char* text); - -extern int ClientDLL_Key_Event( int down, int keynum, const char *pszCurrentBinding ); -extern void ClientDLL_TempEntUpdate( double ft, double ct, double grav, struct tempent_s **ppFreeTE, struct tempent_s **ppActiveTE, int ( *addTEntity )( struct cl_entity_s *pEntity ), void ( *playTESound )( struct tempent_s *pTemp, float damp ) ); -extern struct cl_entity_s *ClientDLL_GetUserEntity( int index ); -extern void ClientDLL_VoiceStatus(int entindex, qboolean bTalking); -extern void ClientDLL_DirectorMessage( int iSize, void *pbuf ); -extern void ClientDLL_ChatInputPosition( int *x, int *y ); - //#include "server.h" // server_static_t define for apiproxy #include "APIProxy.h" -extern cldll_func_t cl_funcs; -extern cl_enginefunc_t cl_engsrcProxies; -extern cl_enginefunc_dst_t g_engdstAddrs; - -// Module exports -extern modfuncs_t g_modfuncs; -extern module_t g_module; - -// Macros for exported engine funcs -#define RecEngSPR_Load(a) (g_engdstAddrs.pfnSPR_Load(&a)) -#define RecEngSPR_Frames(a) (g_engdstAddrs.pfnSPR_Frames(&a)) -#define RecEngSPR_Height(a, b) (g_engdstAddrs.pfnSPR_Height(&a, &b)) -#define RecEngSPR_Width(a, b) (g_engdstAddrs.pfnSPR_Width(&a, &b)) -#define RecEngSPR_Set(a, b, c, d) (g_engdstAddrs.pfnSPR_Set(&a, &b, &c, &d)) -#define RecEngSPR_Draw(a, b, c, d) (g_engdstAddrs.pfnSPR_Draw(&a, &b, &c, &d)) -#define RecEngSPR_DrawHoles(a, b, c, d) (g_engdstAddrs.pfnSPR_DrawHoles(&a, &b, &c, &d)) -#define RecEngSPR_DrawAdditive(a, b, c, d) (g_engdstAddrs.pfnSPR_DrawAdditive(&a, &b, &c, &d)) -#define RecEngSPR_EnableScissor(a, b, c, d) (g_engdstAddrs.pfnSPR_EnableScissor(&a, &b, &c, &d)) -#define RecEngSPR_DisableScissor() (g_engdstAddrs.pfnSPR_DisableScissor()) -#define RecEngSPR_GetList(a, b) (g_engdstAddrs.pfnSPR_GetList(&a, &b)) -#define RecEngDraw_FillRGBA(a, b, c, d, e, f, g, h) (g_engdstAddrs.pfnFillRGBA(&a, &b, &c, &d, &e, &f, &g, &h)) -#define RecEnghudGetScreenInfo(a) (g_engdstAddrs.pfnGetScreenInfo(&a)) -#define RecEngSetCrosshair(a, b, c, d, e) (g_engdstAddrs.pfnSetCrosshair(&a, &b, &c, &d, &e)) -#define RecEnghudRegisterVariable(a, b, c) (g_engdstAddrs.pfnRegisterVariable(&a, &b, &c)) -#define RecEnghudGetCvarFloat(a) (g_engdstAddrs.pfnGetCvarFloat(&a)) -#define RecEnghudGetCvarString(a) (g_engdstAddrs.pfnGetCvarString(&a)) -#define RecEnghudAddCommand(a, b) (g_engdstAddrs.pfnAddCommand(&a, &b)) -#define RecEnghudHookUserMsg(a, b) (g_engdstAddrs.pfnHookUserMsg(&a, &b)) -#define RecEnghudServerCmd(a) (g_engdstAddrs.pfnServerCmd(&a)) -#define RecEnghudClientCmd(a) (g_engdstAddrs.pfnClientCmd(&a)) -#define RecEngPrimeMusicStream(a, b) (g_engdstAddrs.pfnPrimeMusicStream(&a, &b)) -#define RecEnghudGetPlayerInfo(a, b) (g_engdstAddrs.pfnGetPlayerInfo(&a, &b)) -#define RecEnghudPlaySoundByName(a, b) (g_engdstAddrs.pfnPlaySoundByName(&a, &b)) -#define RecEnghudPlaySoundByNameAtPitch(a, b, c) (g_engdstAddrs.pfnPlaySoundByNameAtPitch(&a, &b, &c)) -#define RecEnghudPlaySoundVoiceByName(a, b) (g_engdstAddrs.pfnPlaySoundVoiceByName(&a, &b)) -#define RecEnghudPlaySoundByIndex(a, b) (g_engdstAddrs.pfnPlaySoundByIndex(&a, &b)) -#define RecEngAngleVectors(a, b, c, d) (g_engdstAddrs.pfnAngleVectors(&a, &b, &c, &d)) -#define RecEngTextMessageGet(a) (g_engdstAddrs.pfnTextMessageGet(&a)) -#define RecEngTextMessageDrawCharacter(a, b, c, d, e, f) (g_engdstAddrs.pfnDrawCharacter(&a, &b, &c, &d, &e, &f)) -#define RecEngDrawConsoleString(a, b, c) (g_engdstAddrs.pfnDrawConsoleString(&a, &b, &c)) -#define RecEngDrawSetTextColor(a, b, c) (g_engdstAddrs.pfnDrawSetTextColor(&a, &b, &c)) -#define RecEnghudDrawConsoleStringLen(a, b, c) (g_engdstAddrs.pfnDrawConsoleStringLen(&a, &b, &c)) -#define RecEnghudConsolePrint(a) (g_engdstAddrs.pfnConsolePrint(&a)) -#define RecEnghudCenterPrint(a) (g_engdstAddrs.pfnCenterPrint(&a)) -#define RecEnghudCenterX() (g_engdstAddrs.GetWindowCenterX()) -#define RecEnghudCenterY() (g_engdstAddrs.GetWindowCenterY()) -#define RecEnghudGetViewAngles(a) (g_engdstAddrs.GetViewAngles(&a)) -#define RecEnghudSetViewAngles(a) (g_engdstAddrs.SetViewAngles(&a)) -#define RecEnghudGetMaxClients() (g_engdstAddrs.GetMaxClients()) -#define RecEngCvar_SetValue(a, b) (g_engdstAddrs.Cvar_SetValue(&a, &b)) -#define RecEngCmd_Argc() (g_engdstAddrs.Cmd_Argc()) -#define RecEngCmd_Argv(a) (g_engdstAddrs.Cmd_Argv(&a)) -#define RecEngCon_Printf(a) (g_engdstAddrs.Con_Printf(&a)) -#define RecEngCon_DPrintf(a) (g_engdstAddrs.Con_DPrintf(&a)) -#define RecEngCon_NPrintf(a, b) (g_engdstAddrs.Con_NPrintf(&a, &b)) -#define RecEngCon_NXPrintf(a, b) (g_engdstAddrs.Con_NXPrintf(&a, &b)) -#define RecEnghudPhysInfo_ValueForKey(a) (g_engdstAddrs.PhysInfo_ValueForKey(&a)) -#define RecEnghudServerInfo_ValueForKey(a) (g_engdstAddrs.ServerInfo_ValueForKey(&a)) -#define RecEnghudGetClientMaxspeed() (g_engdstAddrs.GetClientMaxspeed()) -#define RecEnghudCheckParm(a, b) (g_engdstAddrs.CheckParm(&a, &b)) -#define RecEngKey_Event(a, b) (g_engdstAddrs.Key_Event(&a, &b)) -#define RecEnghudGetMousePosition(a, b) (g_engdstAddrs.GetMousePosition(&a, &b)) -#define RecEnghudIsNoClipping() (g_engdstAddrs.IsNoClipping()) -#define RecEnghudGetLocalPlayer() (g_engdstAddrs.GetLocalPlayer()) -#define RecEnghudGetViewModel() (g_engdstAddrs.GetViewModel()) -#define RecEnghudGetEntityByIndex(a) (g_engdstAddrs.GetEntityByIndex(&a)) -#define RecEnghudGetClientTime() (g_engdstAddrs.GetClientTime()) -#define RecEngV_CalcShake() (g_engdstAddrs.V_CalcShake()) -#define RecEngV_ApplyShake(a, b, c) (g_engdstAddrs.V_ApplyShake(&a, &b, &c)) -#define RecEngPM_PointContents(a, b) (g_engdstAddrs.PM_PointContents(&a, &b)) -#define RecEngPM_WaterEntity(a) (g_engdstAddrs.PM_WaterEntity(&a)) -#define RecEngPM_TraceLine(a, b, c, d, e) (g_engdstAddrs.PM_TraceLine(&a, &b, &c, &d, &e)) -#define RecEngCL_LoadModel(a, b) (g_engdstAddrs.CL_LoadModel(&a, &b)) -#define RecEngCL_CreateVisibleEntity(a, b) (g_engdstAddrs.CL_CreateVisibleEntity(&a, &b)) -#define RecEnghudGetSpritePointer(a) (g_engdstAddrs.GetSpritePointer(&a)) -#define RecEnghudPlaySoundByNameAtLocation(a, b, c) (g_engdstAddrs.pfnPlaySoundByNameAtLocation(&a, &b, &c)) -#define RecEnghudPrecacheEvent(a, b) (g_engdstAddrs.pfnPrecacheEvent(&a, &b)) -#define RecEnghudPlaybackEvent(a, b, c, d, e, f, g, h, i, j, k, l) (g_engdstAddrs.pfnPlaybackEvent(&a, &b, &c, &d, &e, &f, &g, &h, &i, &j, &k, &l)) -#define RecEnghudWeaponAnim(a, b) (g_engdstAddrs.pfnWeaponAnim(&a, &b)) -#define RecEngRandomFloat(a, b) (g_engdstAddrs.pfnRandomFloat(&a, &b)) -#define RecEngRandomLong(a, b) (g_engdstAddrs.pfnRandomLong(&a, &b)) -#define RecEngCL_HookEvent(a, b) (g_engdstAddrs.pfnHookEvent(&a, &b)) -#define RecEngCon_IsVisible() (g_engdstAddrs.Con_IsVisible()) -#define RecEnghudGetGameDir() (g_engdstAddrs.pfnGetGameDirectory()) -#define RecEngCvar_FindVar(a) (g_engdstAddrs.pfnGetCvarPointer(&a)) -#define RecEngKey_NameForBinding(a) (g_engdstAddrs.Key_LookupBinding(&a)) -#define RecEnghudGetLevelName() (g_engdstAddrs.pfnGetLevelName()) -#define RecEnghudGetScreenFade(a) (g_engdstAddrs.pfnGetScreenFade(&a)) -#define RecEnghudSetScreenFade(a) (g_engdstAddrs.pfnSetScreenFade(&a)) -#define RecEngVGuiWrap_GetPanel() (g_engdstAddrs.VGui_GetPanel()) -#define RecEngVGui_ViewportPaintBackground(a) (g_engdstAddrs.VGui_ViewportPaintBackground(&a)) -#define RecEngCOM_LoadFile(a, b, c) (g_engdstAddrs.COM_LoadFile(&a, &b, &c)) -#define RecEngCOM_ParseFile(a, b) (g_engdstAddrs.COM_ParseFile(&a, &b)) -#define RecEngCOM_FreeFile(a) (g_engdstAddrs.COM_FreeFile(&a)) -#define RecEngCL_IsSpectateOnly() (g_engdstAddrs.IsSpectateOnly()) -#define RecEngR_LoadMapSprite(a) (g_engdstAddrs.LoadMapSprite(&a)) -#define RecEngCOM_AddAppDirectoryToSearchPath(a, b) (g_engdstAddrs.COM_AddAppDirectoryToSearchPath(&a, &b)) -#define RecEngClientDLL_ExpandFileName(a, b, c) (g_engdstAddrs.COM_ExpandFilename(&a, &b, &c)) -#define RecEngPlayerInfo_ValueForKey(a, b) (g_engdstAddrs.PlayerInfo_ValueForKey(&a, &b)) -#define RecEngPlayerInfo_SetValueForKey(a, b) (g_engdstAddrs.PlayerInfo_SetValueForKey(&a, &b)) -#define RecEngGetPlayerUniqueID(a, b) (g_engdstAddrs.GetPlayerUniqueID(&a, &b)) -#define RecEngGetTrackerIDForPlayer(a) (g_engdstAddrs.GetTrackerIDForPlayer(&a)) -#define RecEngGetPlayerForTrackerID(a) (g_engdstAddrs.GetPlayerForTrackerID(&a)) -#define RecEnghudServerCmdUnreliable(a) (g_engdstAddrs.pfnServerCmdUnreliable(&a)) -#define RecEngGetMousePos(a) (g_engdstAddrs.pfnGetMousePos(&a)) -#define RecEngSetMousePos(a, b) (g_engdstAddrs.pfnSetMousePos(&a, &b)) -#define RecEngSetMouseEnable(a) (g_engdstAddrs.pfnSetMouseEnable(&a)) -#define RecEngSetFilterMode(a) (g_engdstAddrs.pfnSetFilterMode(&a)) -#define RecEngSetFilterColor(a,b,c) (g_engdstAddrs.pfnSetFilterColor(&a,&b,&c)) -#define RecEngSetFilterBrightness(a) (g_engdstAddrs.pfnSetFilterBrightness(&a)) -#define RecEngSequenceGet(a,b) (g_engdstAddrs.pfnSequenceGet(&a,&b)) -#define RecEngSPR_DrawGeneric(a,b,c,d,e,f,g,h) (g_engdstAddrs.pfnSPR_DrawGeneric(&a, &b, &c, &d, &e, &f, &g, &h)) -#define RecEngSequencePickSentence(a,b,c) (g_engdstAddrs.pfnSequencePickSentence(&a, &b, &c)) -#define RecEngLocalPlayerInfo_ValueForKey(a) (g_engdstAddrs.LocalPlayerInfo_ValueForKey(&a)) -#define RecEngProcessTutorMessageDecayBuffer(a, b) (g_engdstAddrs.pfnProcessTutorMessageDecayBuffer(&a, &b)) -#define RecEngConstructTutorMessageDecayBuffer(a, b) (g_engdstAddrs.pfnConstructTutorMessageDecayBuffer(&a, &b)) -#define RecEngResetTutorMessageDecayBuffer() (g_engdstAddrs.pfnResetTutorMessageDecayBuffer()) -#define RecEngDraw_FillRGBABlend(a, b, c, d, e, f, g, h) (g_engdstAddrs.pfnFillRGBABlend(&a, &b, &c, &d, &e, &f, &g, &h)) - -// Dummy destination function for use when there's no security module -extern void NullDst(void); - -// Use this to init an engdst structure to point to NullDst -#define k_engdstNull \ -{ \ - (pfnEngDst_pfnSPR_Load_t) NullDst, \ - (pfnEngDst_pfnSPR_Frames_t) NullDst, \ - (pfnEngDst_pfnSPR_Height_t) NullDst, \ - (pfnEngDst_pfnSPR_Width_t) NullDst, \ - (pfnEngDst_pfnSPR_Set_t) NullDst, \ - (pfnEngDst_pfnSPR_Draw_t) NullDst, \ - (pfnEngDst_pfnSPR_DrawHoles_t) NullDst, \ - (pfnEngDst_pfnSPR_DrawAdditive_t) NullDst, \ - (pfnEngDst_pfnSPR_EnableScissor_t) NullDst, \ - (pfnEngDst_pfnSPR_DisableScissor_t) NullDst, \ - (pfnEngDst_pfnSPR_GetList_t) NullDst, \ - (pfnEngDst_pfnFillRGBA_t) NullDst, \ - (pfnEngDst_pfnGetScreenInfo_t) NullDst, \ - (pfnEngDst_pfnSetCrosshair_t) NullDst, \ - (pfnEngDst_pfnRegisterVariable_t) NullDst, \ - (pfnEngDst_pfnGetCvarFloat_t) NullDst, \ - (pfnEngDst_pfnGetCvarString_t) NullDst, \ - (pfnEngDst_pfnAddCommand_t) NullDst, \ - (pfnEngDst_pfnHookUserMsg_t) NullDst, \ - (pfnEngDst_pfnServerCmd_t) NullDst, \ - (pfnEngDst_pfnClientCmd_t) NullDst, \ - (pfnEngDst_pfnGetPlayerInfo_t) NullDst, \ - (pfnEngDst_pfnPlaySoundByName_t) NullDst, \ - (pfnEngDst_pfnPlaySoundByIndex_t) NullDst, \ - (pfnEngDst_pfnAngleVectors_t) NullDst, \ - (pfnEngDst_pfnTextMessageGet_t) NullDst, \ - (pfnEngDst_pfnDrawCharacter_t) NullDst, \ - (pfnEngDst_pfnDrawConsoleString_t) NullDst, \ - (pfnEngDst_pfnDrawSetTextColor_t) NullDst, \ - (pfnEngDst_pfnDrawConsoleStringLen_t) NullDst, \ - (pfnEngDst_pfnConsolePrint_t) NullDst, \ - (pfnEngDst_pfnCenterPrint_t) NullDst, \ - (pfnEngDst_GetWindowCenterX_t) NullDst, \ - (pfnEngDst_GetWindowCenterY_t) NullDst, \ - (pfnEngDst_GetViewAngles_t) NullDst, \ - (pfnEngDst_SetViewAngles_t) NullDst, \ - (pfnEngDst_GetMaxClients_t) NullDst, \ - (pfnEngDst_Cvar_SetValue_t) NullDst, \ - (pfnEngDst_Cmd_Argc_t) NullDst, \ - (pfnEngDst_Cmd_Argv_t) NullDst, \ - (pfnEngDst_Con_Printf_t) NullDst, \ - (pfnEngDst_Con_DPrintf_t) NullDst, \ - (pfnEngDst_Con_NPrintf_t) NullDst, \ - (pfnEngDst_Con_NXPrintf_t) NullDst, \ - (pfnEngDst_PhysInfo_ValueForKey_t) NullDst, \ - (pfnEngDst_ServerInfo_ValueForKey_t) NullDst, \ - (pfnEngDst_GetClientMaxspeed_t) NullDst, \ - (pfnEngDst_CheckParm_t) NullDst, \ - (pfnEngDst_Key_Event_t) NullDst, \ - (pfnEngDst_GetMousePosition_t) NullDst, \ - (pfnEngDst_IsNoClipping_t) NullDst, \ - (pfnEngDst_GetLocalPlayer_t) NullDst, \ - (pfnEngDst_GetViewModel_t) NullDst, \ - (pfnEngDst_GetEntityByIndex_t) NullDst, \ - (pfnEngDst_GetClientTime_t) NullDst, \ - (pfnEngDst_V_CalcShake_t) NullDst, \ - (pfnEngDst_V_ApplyShake_t) NullDst, \ - (pfnEngDst_PM_PointContents_t) NullDst, \ - (pfnEngDst_PM_WaterEntity_t) NullDst, \ - (pfnEngDst_PM_TraceLine_t) NullDst, \ - (pfnEngDst_CL_LoadModel_t) NullDst, \ - (pfnEngDst_CL_CreateVisibleEntity_t) NullDst, \ - (pfnEngDst_GetSpritePointer_t) NullDst, \ - (pfnEngDst_pfnPlaySoundByNameAtLocation_t) NullDst, \ - (pfnEngDst_pfnPrecacheEvent_t) NullDst, \ - (pfnEngDst_pfnPlaybackEvent_t) NullDst, \ - (pfnEngDst_pfnWeaponAnim_t) NullDst, \ - (pfnEngDst_pfnRandomFloat_t) NullDst, \ - (pfnEngDst_pfnRandomLong_t) NullDst, \ - (pfnEngDst_pfnHookEvent_t) NullDst, \ - (pfnEngDst_Con_IsVisible_t) NullDst, \ - (pfnEngDst_pfnGetGameDirectory_t) NullDst, \ - (pfnEngDst_pfnGetCvarPointer_t) NullDst, \ - (pfnEngDst_Key_LookupBinding_t) NullDst, \ - (pfnEngDst_pfnGetLevelName_t) NullDst, \ - (pfnEngDst_pfnGetScreenFade_t) NullDst, \ - (pfnEngDst_pfnSetScreenFade_t) NullDst, \ - (pfnEngDst_VGui_GetPanel_t) NullDst, \ - (pfnEngDst_VGui_ViewportPaintBackground_t) NullDst, \ - (pfnEngDst_COM_LoadFile_t) NullDst, \ - (pfnEngDst_COM_ParseFile_t) NullDst, \ - (pfnEngDst_COM_FreeFile_t) NullDst, \ - NULL, \ - NULL, \ - NULL, \ - NULL, \ - NULL, \ - NULL, \ - (pfnEngDst_IsSpectateOnly_t) NullDst, \ - (pfnEngDst_LoadMapSprite_t) NullDst, \ - (pfnEngDst_COM_AddAppDirectoryToSearchPath_t) NullDst, \ - (pfnEngDst_COM_ExpandFilename_t) NullDst, \ - (pfnEngDst_PlayerInfo_ValueForKey_t) NullDst, \ - (pfnEngDst_PlayerInfo_SetValueForKey_t) NullDst, \ - (pfnEngDst_GetPlayerUniqueID_t) NullDst, \ - (pfnEngDst_GetTrackerIDForPlayer_t) NullDst, \ - (pfnEngDst_GetPlayerForTrackerID_t) NullDst, \ - (pfnEngDst_pfnServerCmdUnreliable_t) NullDst, \ - (pfnEngDst_GetMousePos_t) NullDst, \ - (pfnEngDst_SetMousePos_t) NullDst, \ - (pfnEngDst_SetMouseEnable_t) NullDst, \ - (pfnEngDst_pfnSetFilterMode_t) NullDst, \ - (pfnEngDst_pfnSetFilterColor_t) NullDst, \ - (pfnEngDst_pfnSetFilterBrightness_t) NullDst, \ - (pfnEngDst_pfnSequenceGet_t) NullDst, \ - (pfnEngDst_pfnSPR_DrawGeneric_t) NullDst, \ - (pfnEngDst_pfnSequencePickSentence_t) NullDst, \ - (pfnEngDst_pfnDrawString_t) NullDst, \ - (pfnEngDst_pfnDrawStringReverse_t) NullDst, \ - (pfnEngDst_LocalPlayerInfo_ValueForKey_t) NullDst, \ - (pfnEngDst_pfnVGUI2DrawCharacter_t) NullDst, \ - (pfnEngDst_pfnVGUI2DrawCharacterAdd_t) NullDst, \ - (pfnEngDst_pfnPlaySoundVoiceByName_t) NullDst, \ - (pfnEngDst_pfnPrimeMusicStream_t) NullDst, \ - (pfnEngDst_pfnProcessTutorMessageDecayBuffer_t) NullDst, \ - (pfnEngDst_pfnConstructTutorMessageDecayBuffer_t) NullDst, \ - (pfnEngDst_pfnResetTutorMessageDecayData_t) NullDst, \ - (pfnEngDst_pfnPlaySoundByNameAtPitch_t) NullDst, \ - (pfnEngDst_pfnFillRGBABlend_t) NullDst, \ - (pfnEngDst_pfnGetAppID_t) NullDst, \ - (pfnEngDst_pfnGetAliases_t) NullDst, \ - (pfnEngDst_pfnVguiWrap2_GetMouseDelta_t) NullDst, \ -}; - -// Use this to init a cldll_func_dst structure to point to NullDst -#define k_cldstNull \ -{ \ - (DST_INITIALIZE_FUNC) NullDst, \ - (DST_HUD_INIT_FUNC) NullDst, \ - (DST_HUD_VIDINIT_FUNC) NullDst, \ - (DST_HUD_REDRAW_FUNC) NullDst, \ - (DST_HUD_UPDATECLIENTDATA_FUNC) NullDst, \ - (DST_HUD_RESET_FUNC) NullDst, \ - (DST_HUD_CLIENTMOVE_FUNC) NullDst, \ - (DST_HUD_CLIENTMOVEINIT_FUNC) NullDst, \ - (DST_HUD_TEXTURETYPE_FUNC) NullDst, \ - (DST_HUD_IN_ACTIVATEMOUSE_FUNC) NullDst, \ - (DST_HUD_IN_DEACTIVATEMOUSE_FUNC) NullDst, \ - (DST_HUD_IN_MOUSEEVENT_FUNC) NullDst, \ - (DST_HUD_IN_CLEARSTATES_FUNC) NullDst, \ - (DST_HUD_IN_ACCUMULATE_FUNC) NullDst, \ - (DST_HUD_CL_CREATEMOVE_FUNC) NullDst, \ - (DST_HUD_CL_ISTHIRDPERSON_FUNC) NullDst, \ - (DST_HUD_CL_GETCAMERAOFFSETS_FUNC) NullDst, \ - (DST_HUD_KB_FIND_FUNC) NullDst, \ - (DST_HUD_CAMTHINK_FUNC) NullDst, \ - (DST_HUD_CALCREF_FUNC) NullDst, \ - (DST_HUD_ADDENTITY_FUNC) NullDst, \ - (DST_HUD_CREATEENTITIES_FUNC) NullDst, \ - (DST_HUD_DRAWNORMALTRIS_FUNC) NullDst, \ - (DST_HUD_DRAWTRANSTRIS_FUNC) NullDst, \ - (DST_HUD_STUDIOEVENT_FUNC) NullDst, \ - (DST_HUD_POSTRUNCMD_FUNC) NullDst, \ - (DST_HUD_SHUTDOWN_FUNC) NullDst, \ - (DST_HUD_TXFERLOCALOVERRIDES_FUNC) NullDst, \ - (DST_HUD_PROCESSPLAYERSTATE_FUNC) NullDst, \ - (DST_HUD_TXFERPREDICTIONDATA_FUNC) NullDst, \ - (DST_HUD_DEMOREAD_FUNC) NullDst, \ - (DST_HUD_CONNECTIONLESS_FUNC) NullDst, \ - (DST_HUD_GETHULLBOUNDS_FUNC) NullDst, \ - (DST_HUD_FRAME_FUNC) NullDst, \ - (DST_HUD_KEY_EVENT_FUNC) NullDst, \ - (DST_HUD_TEMPENTUPDATE_FUNC) NullDst, \ - (DST_HUD_GETUSERENTITY_FUNC) NullDst, \ - (DST_HUD_VOICESTATUS_FUNC) NullDst, \ - (DST_HUD_DIRECTORMESSAGE_FUNC) NullDst, \ - (DST_HUD_STUDIO_INTERFACE_FUNC) NullDst, \ - (DST_HUD_CHATINPUTPOSITION_FUNC) NullDst, \ - (DST_HUD_GETPLAYERTEAM) NullDst, \ -} - #ifdef __cplusplus } #endif From 191b8fe1cbb28834093358d8e2286f89f12a4755 Mon Sep 17 00:00:00 2001 From: Sam V Date: Thu, 18 Nov 2021 18:24:18 +0100 Subject: [PATCH 08/13] Remove extern C wrappers around functions Resolves #58 --- cl_dll/ev_hldm.h | 43 +++++++++++++++++++---------------------- cl_dll/hl/hl_events.cpp | 3 +-- cl_dll/input.cpp | 3 --- cl_dll/vgui_int.h | 3 --- common/con_nprint.h | 7 ------- common/crc.h | 8 +------- common/interface.h | 4 ---- common/port.h | 10 +--------- engine/cdll_int.h | 8 -------- 9 files changed, 23 insertions(+), 66 deletions(-) diff --git a/cl_dll/ev_hldm.h b/cl_dll/ev_hldm.h index 7c4e18acd..099b7005c 100644 --- a/cl_dll/ev_hldm.h +++ b/cl_dll/ev_hldm.h @@ -13,31 +13,28 @@ void EV_HLDM_DecalGunshot( pmtrace_t *pTrace, int iBulletType ); int EV_HLDM_CheckTracer( int idx, float *vecSrc, float *end, float *forward, float *right, int iBulletType, int iTracerFreq, int *tracerCount ); void EV_HLDM_FireBullets( int idx, float *forward, float *right, float *up, int cShots, float *vecSrc, float *vecDirShooting, float flDistance, int iBulletType, int iTracerFreq, int *tracerCount, float flSpreadX, float flSpreadY ); -extern "C" -{ - // HLDM - void EV_FireGlock1(event_args_t* args); - void EV_FireGlock2(event_args_t* args); - void EV_FireShotGunSingle(event_args_t* args); - void EV_FireShotGunDouble(event_args_t* args); - void EV_FireMP5(event_args_t* args); - void EV_FireMP52(event_args_t* args); - void EV_FirePython(event_args_t* args); - void EV_FireGauss(event_args_t* args); - void EV_SpinGauss(event_args_t* args); - void EV_Crowbar(event_args_t* args); - void EV_FireCrossbow(event_args_t* args); - void EV_FireCrossbow2(event_args_t* args); - void EV_FireRpg(event_args_t* args); - void EV_EgonFire(event_args_t* args); - void EV_EgonStop(event_args_t* args); - void EV_HornetGunFire(event_args_t* args); - void EV_TripmineFire(event_args_t* args); - void EV_SnarkFire(event_args_t* args); +// HLDM +void EV_FireGlock1(event_args_t* args); +void EV_FireGlock2(event_args_t* args); +void EV_FireShotGunSingle(event_args_t* args); +void EV_FireShotGunDouble(event_args_t* args); +void EV_FireMP5(event_args_t* args); +void EV_FireMP52(event_args_t* args); +void EV_FirePython(event_args_t* args); +void EV_FireGauss(event_args_t* args); +void EV_SpinGauss(event_args_t* args); +void EV_Crowbar(event_args_t* args); +void EV_FireCrossbow(event_args_t* args); +void EV_FireCrossbow2(event_args_t* args); +void EV_FireRpg(event_args_t* args); +void EV_EgonFire(event_args_t* args); +void EV_EgonStop(event_args_t* args); +void EV_HornetGunFire(event_args_t* args); +void EV_TripmineFire(event_args_t* args); +void EV_SnarkFire(event_args_t* args); - void EV_TrainPitchAdjust(event_args_t* args); -} +void EV_TrainPitchAdjust(event_args_t* args); #endif // EV_HLDMH \ No newline at end of file diff --git a/cl_dll/hl/hl_events.cpp b/cl_dll/hl/hl_events.cpp index 9891fdb17..0a7719c1f 100644 --- a/cl_dll/hl/hl_events.cpp +++ b/cl_dll/hl/hl_events.cpp @@ -22,8 +22,7 @@ ====================== Game_HookEvents -Associate script file name with callback functions. Callback's must be extern "C" so - the engine doesn't get confused about name mangling stuff. Note that the format is +Associate script file name with callback functions. Note that the format is always the same. Of course, a clever mod team could actually embed parameters, behavior into the actual .sc files and create a .sc file parser and hook their functionality through that.. i.e., a scripting system. diff --git a/cl_dll/input.cpp b/cl_dll/input.cpp index ccbdd95a4..7a2fa9e1e 100644 --- a/cl_dll/input.cpp +++ b/cl_dll/input.cpp @@ -7,10 +7,7 @@ #include "hud.h" #include "cl_util.h" #include "camera.h" -extern "C" -{ #include "kbutton.h" -} #include "cvardef.h" #include "usercmd.h" #include "const.h" diff --git a/cl_dll/vgui_int.h b/cl_dll/vgui_int.h index 6510853e9..598744226 100644 --- a/cl_dll/vgui_int.h +++ b/cl_dll/vgui_int.h @@ -8,14 +8,11 @@ #ifndef VGUI_INT_H #define VGUI_INT_H -extern "C" -{ void VGui_Startup(); void VGui_Shutdown(); //Only safe to call from inside subclass of Panel::paintBackground void VGui_ViewportPaintBackground(int extents[4]); -} #endif \ No newline at end of file diff --git a/common/con_nprint.h b/common/con_nprint.h index 64f5dacf2..6ebc6c636 100644 --- a/common/con_nprint.h +++ b/common/con_nprint.h @@ -17,10 +17,6 @@ #ifdef _WIN32 #pragma once #endif - -#ifdef __cplusplus -extern "C" { -#endif typedef struct con_nprint_s { @@ -31,8 +27,5 @@ typedef struct con_nprint_s void Con_NPrintf( int idx, char *fmt, ... ); void Con_NXPrintf( struct con_nprint_s *info, char *fmt, ... ); -#ifdef __cplusplus -} -#endif #endif diff --git a/common/crc.h b/common/crc.h index eba4ab8c9..2c00544a1 100644 --- a/common/crc.h +++ b/common/crc.h @@ -36,18 +36,12 @@ typedef uint32 CRC32_t; typedef uint32 CRC32_t; #endif -#ifdef __cplusplus -extern "C" -{ -#endif void CRC32_Init(CRC32_t *pulCRC); CRC32_t CRC32_Final(CRC32_t pulCRC); void CRC32_ProcessBuffer(CRC32_t *pulCRC, void *p, int len); void CRC32_ProcessByte(CRC32_t *pulCRC, unsigned char ch); int CRC_File(CRC32_t *crcvalue, char *pszFileName); -#ifdef __cplusplus -} -#endif + unsigned char COM_BlockSequenceCRCByte (unsigned char *base, int length, int sequence); void MD5Init(MD5Context_t *context); diff --git a/common/interface.h b/common/interface.h index b49d08743..0ff9877d4 100644 --- a/common/interface.h +++ b/common/interface.h @@ -23,8 +23,6 @@ #ifndef INTERFACE_H #define INTERFACE_H -#ifdef __cplusplus - // All interfaces derive from this. class IBaseInterface { @@ -121,8 +119,6 @@ extern void Sys_FreeModule(HINTERFACEMODULE hModule); extern CreateInterfaceFn Sys_GetFactory( HINTERFACEMODULE hModule ); extern CreateInterfaceFn Sys_GetFactoryThis( void ); -#endif // __cplusplus - #endif diff --git a/common/port.h b/common/port.h index 1497785f2..50505e8e5 100644 --- a/common/port.h +++ b/common/port.h @@ -54,7 +54,6 @@ typedef void *HGLRC; #endif -#ifdef __cplusplus //#undef FALSE //#undef TRUE @@ -64,24 +63,17 @@ typedef void *HGLRC; //const bool FALSE = false; //const bool TRUE = true; #endif -#endif #ifndef NULL - #ifdef __cplusplus - #define NULL 0 - #else - #define NULL ((void *)0) - #endif + #define NULL 0 #endif -#ifdef __cplusplus inline int ioctlsocket( int d, int cmd, uint32 *argp ) { return ioctl( d, cmd, argp ); } inline int closesocket( int fd ) { return close( fd ); } inline char * GetCurrentDirectory( size_t size, char * buf ) { return getcwd( buf, size ); } inline int WSAGetLastError() { return errno; } inline void DebugBreak( void ) { exit( 1 ); } -#endif extern char g_szEXEName[ 4096 ]; diff --git a/engine/cdll_int.h b/engine/cdll_int.h index 4f4503a7c..59b378e9e 100644 --- a/engine/cdll_int.h +++ b/engine/cdll_int.h @@ -22,10 +22,6 @@ #ifndef CDLL_INT_H #define CDLL_INT_H -#ifdef __cplusplus -extern "C" { -#endif - #include "const.h" #include "steam/steamtypes.h" #include "ref_params.h" @@ -100,9 +96,5 @@ typedef struct hud_player_info_s //#include "server.h" // server_static_t define for apiproxy #include "APIProxy.h" -#ifdef __cplusplus -} -#endif - #endif // CDLL_INT_H \ No newline at end of file From 2a82a3703d24f59085c3d79f1e5150028a24d373 Mon Sep 17 00:00:00 2001 From: Sam V Date: Thu, 18 Nov 2021 18:25:35 +0100 Subject: [PATCH 09/13] Remove commented out macros in Exports.h involving security module stuff Resolves #57 --- cl_dll/Exports.h | 47 ----------------------------------------------- 1 file changed, 47 deletions(-) diff --git a/cl_dll/Exports.h b/cl_dll/Exports.h index e47dcc784..d6313352e 100644 --- a/cl_dll/Exports.h +++ b/cl_dll/Exports.h @@ -63,50 +63,3 @@ extern "C" // From GameStudioModelRenderer int DLLEXPORT HUD_GetStudioModelInterface( int version, struct r_studio_interface_s **ppinterface, struct engine_studio_api_s *pstudio ); } - -/* -extern cldll_func_dst_t *g_pcldstAddrs; - -// Macros for the client receiving calls from the engine -#define RecClInitialize(a, b) (g_pcldstAddrs->pInitFunc(&a, &b)) -#define RecClHudInit() (g_pcldstAddrs->pHudInitFunc()) -#define RecClHudVidInit() (g_pcldstAddrs->pHudVidInitFunc()) -#define RecClHudRedraw(a, b) (g_pcldstAddrs->pHudRedrawFunc(&a, &b)) -#define RecClHudUpdateClientData(a, b) (g_pcldstAddrs->pHudUpdateClientDataFunc(&a, &b)) -#define RecClHudReset() (g_pcldstAddrs->pHudResetFunc()) -#define RecClClientMove(a, b) (g_pcldstAddrs->pClientMove(&a, &b)) -#define RecClClientMoveInit(a) (g_pcldstAddrs->pClientMoveInit(&a)) -#define RecClClientTextureType(a) (g_pcldstAddrs->pClientTextureType(&a)) -#define RecClIN_ActivateMouse() (g_pcldstAddrs->pIN_ActivateMouse()) -#define RecClIN_DeactivateMouse() (g_pcldstAddrs->pIN_DeactivateMouse()) -#define RecClIN_MouseEvent(a) (g_pcldstAddrs->pIN_MouseEvent(&a)) -#define RecClIN_ClearStates() (g_pcldstAddrs->pIN_ClearStates()) -#define RecClIN_Accumulate() (g_pcldstAddrs->pIN_Accumulate()) -#define RecClCL_CreateMove(a, b, c) (g_pcldstAddrs->pCL_CreateMove(&a, &b, &c)) -#define RecClCL_IsThirdPerson() (g_pcldstAddrs->pCL_IsThirdPerson()) -#define RecClCL_GetCameraOffsets(a) (g_pcldstAddrs->pCL_GetCameraOffsets(&a)) -#define RecClFindKey(a) (g_pcldstAddrs->pFindKey(&a)) -#define RecClCamThink() (g_pcldstAddrs->pCamThink()) -#define RecClCalcRefdef(a) (g_pcldstAddrs->pCalcRefdef(&a)) -#define RecClAddEntity(a, b, c) (g_pcldstAddrs->pAddEntity(&a, &b, &c)) -#define RecClCreateEntities() (g_pcldstAddrs->pCreateEntities()) -#define RecClDrawNormalTriangles() (g_pcldstAddrs->pDrawNormalTriangles()) -#define RecClDrawTransparentTriangles() (g_pcldstAddrs->pDrawTransparentTriangles()) -#define RecClStudioEvent(a, b) (g_pcldstAddrs->pStudioEvent(&a, &b)) -#define RecClPostRunCmd(a, b, c, d, e, f) (g_pcldstAddrs->pPostRunCmd(&a, &b, &c, &d, &e, &f)) -#define RecClShutdown() (g_pcldstAddrs->pShutdown()) -#define RecClTxferLocalOverrides(a, b) (g_pcldstAddrs->pTxferLocalOverrides(&a, &b)) -#define RecClProcessPlayerState(a, b) (g_pcldstAddrs->pProcessPlayerState(&a, &b)) -#define RecClTxferPredictionData(a, b, c, d, e, f) (g_pcldstAddrs->pTxferPredictionData(&a, &b, &c, &d, &e, &f)) -#define RecClReadDemoBuffer(a, b) (g_pcldstAddrs->pReadDemoBuffer(&a, &b)) -#define RecClConnectionlessPacket(a, b, c, d) (g_pcldstAddrs->pConnectionlessPacket(&a, &b, &c, &d)) -#define RecClGetHullBounds(a, b, c) (g_pcldstAddrs->pGetHullBounds(&a, &b, &c)) -#define RecClHudFrame(a) (g_pcldstAddrs->pHudFrame(&a)) -#define RecClKeyEvent(a, b, c) (g_pcldstAddrs->pKeyEvent(&a, &b, &c)) -#define RecClTempEntUpdate(a, b, c, d, e, f, g) (g_pcldstAddrs->pTempEntUpdate(&a, &b, &c, &d, &e, &f, &g)) -#define RecClGetUserEntity(a) (g_pcldstAddrs->pGetUserEntity(&a)) -#define RecClVoiceStatus(a, b) (g_pcldstAddrs->pVoiceStatus(&a, &b)) -#define RecClDirectorMessage(a, b) (g_pcldstAddrs->pDirectorMessage(&a, &b)) -#define RecClStudioInterface(a, b, c) (g_pcldstAddrs->pStudioInterface(&a, &b, &c)) -#define RecClChatInputPosition(a, b) (g_pcldstAddrs->pChatInputPosition(&a, &b)) -*/ \ No newline at end of file From a81e9be88faca9a28db7746f47571037745c33c4 Mon Sep 17 00:00:00 2001 From: Sam V Date: Thu, 18 Nov 2021 18:33:42 +0100 Subject: [PATCH 10/13] Only assign to mouse current_pos on Windows Resolves #56 --- cl_dll/inputw32.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/cl_dll/inputw32.cpp b/cl_dll/inputw32.cpp index ba4c76e96..99ffd1496 100644 --- a/cl_dll/inputw32.cpp +++ b/cl_dll/inputw32.cpp @@ -523,8 +523,10 @@ void IN_MouseMove ( float frametime, usercmd_t *cmd) #endif { SDL_GetRelativeMouseState( &deltaX, &deltaY ); +#ifdef _WIN32 current_pos.x = deltaX; - current_pos.y = deltaY; + current_pos.y = deltaY; +#endif } #ifdef _WIN32 From 2c911f96bca9bd61e8204b8defe61294ec9de59f Mon Sep 17 00:00:00 2001 From: Sam V Date: Thu, 18 Nov 2021 18:46:42 +0100 Subject: [PATCH 11/13] Rework uses of Windows API types in input code to use standard types #59 --- cl_dll/inputw32.cpp | 24 ++++++++++++------------ common/Platform.h | 1 + common/port.h | 1 - 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/cl_dll/inputw32.cpp b/cl_dll/inputw32.cpp index 99ffd1496..dc41892b0 100644 --- a/cl_dll/inputw32.cpp +++ b/cl_dll/inputw32.cpp @@ -113,13 +113,13 @@ enum _ControlList -DWORD dwAxisMap[ JOY_MAX_AXES ]; -DWORD dwControlMap[ JOY_MAX_AXES ]; +std::uint32_t dwAxisMap[ JOY_MAX_AXES ]; +std::uint32_t dwControlMap[ JOY_MAX_AXES ]; int pdwRawValue[ JOY_MAX_AXES ]; -DWORD joy_oldbuttonstate, joy_oldpovstate; +std::uint32_t joy_oldbuttonstate, joy_oldpovstate; int joy_id; -DWORD joy_numbuttons; +std::uint32_t joy_numbuttons; SDL_GameController *s_pJoystick = NULL; @@ -763,7 +763,7 @@ void Joy_AdvancedUpdate_f () // called once by IN_ReadJoystick and by user whenever an update is needed // cvars are now available int i; - DWORD dwTemp; + std::uint32_t dwTemp; // initialize all the maps for (i = 0; i < JOY_MAX_AXES; i++) @@ -792,22 +792,22 @@ void Joy_AdvancedUpdate_f () // advanced initialization here // data supplied by user via joy_axisn cvars - dwTemp = (DWORD) joy_advaxisx->value; + dwTemp = (std::uint32_t) joy_advaxisx->value; dwAxisMap[JOY_AXIS_X] = dwTemp & 0x0000000f; dwControlMap[JOY_AXIS_X] = dwTemp & JOY_RELATIVE_AXIS; - dwTemp = (DWORD) joy_advaxisy->value; + dwTemp = (std::uint32_t) joy_advaxisy->value; dwAxisMap[JOY_AXIS_Y] = dwTemp & 0x0000000f; dwControlMap[JOY_AXIS_Y] = dwTemp & JOY_RELATIVE_AXIS; - dwTemp = (DWORD) joy_advaxisz->value; + dwTemp = (std::uint32_t) joy_advaxisz->value; dwAxisMap[JOY_AXIS_Z] = dwTemp & 0x0000000f; dwControlMap[JOY_AXIS_Z] = dwTemp & JOY_RELATIVE_AXIS; - dwTemp = (DWORD) joy_advaxisr->value; + dwTemp = (std::uint32_t) joy_advaxisr->value; dwAxisMap[JOY_AXIS_R] = dwTemp & 0x0000000f; dwControlMap[JOY_AXIS_R] = dwTemp & JOY_RELATIVE_AXIS; - dwTemp = (DWORD) joy_advaxisu->value; + dwTemp = (std::uint32_t) joy_advaxisu->value; dwAxisMap[JOY_AXIS_U] = dwTemp & 0x0000000f; dwControlMap[JOY_AXIS_U] = dwTemp & JOY_RELATIVE_AXIS; - dwTemp = (DWORD) joy_advaxisv->value; + dwTemp = (std::uint32_t) joy_advaxisv->value; dwAxisMap[JOY_AXIS_V] = dwTemp & 0x0000000f; dwControlMap[JOY_AXIS_V] = dwTemp & JOY_RELATIVE_AXIS; } @@ -828,7 +828,7 @@ void IN_Commands () return; } - DWORD buttonstate, povstate; + std::uint32_t buttonstate, povstate; // loop through the joystick buttons // key a joystick event or auxillary event for higher number buttons for each state change diff --git a/common/Platform.h b/common/Platform.h index fcce01896..049f94a6c 100644 --- a/common/Platform.h +++ b/common/Platform.h @@ -39,6 +39,7 @@ // Misc C-runtime library headers #include +#include #include #include #include diff --git a/common/port.h b/common/port.h index 50505e8e5..f210f57cd 100644 --- a/common/port.h +++ b/common/port.h @@ -28,7 +28,6 @@ typedef unsigned char BYTE; typedef short int WORD; -typedef unsigned int DWORD; typedef int32 LONG; //typedef uint32 ULONG; #ifndef ARCHTYPES_H From 45117081f611e976fd1dfb1dfdc089275378e402 Mon Sep 17 00:00:00 2001 From: Sam V Date: Thu, 18 Nov 2021 18:50:39 +0100 Subject: [PATCH 12/13] Merge platform abstraction headers Resolves #53 --- cl_dll/in_camera.cpp | 1 - cl_dll/inputw32.cpp | 2 - common/nowin.h | 16 ----- common/parsemsg.cpp | 1 - common/port.h | 92 ------------------------- projects/vs2017/hl_cdll.vcxproj | 2 - projects/vs2017/hl_cdll.vcxproj.filters | 6 -- projects/vs2017/hldll.vcxproj | 2 - projects/vs2017/hldll.vcxproj.filters | 6 -- projects/vs2019/hl_cdll.vcxproj | 2 - projects/vs2019/hl_cdll.vcxproj.filters | 6 -- projects/vs2019/hldll.vcxproj | 2 - projects/vs2019/hldll.vcxproj.filters | 6 -- 13 files changed, 144 deletions(-) delete mode 100644 common/nowin.h delete mode 100644 common/port.h diff --git a/cl_dll/in_camera.cpp b/cl_dll/in_camera.cpp index fe94cca03..962e0ac6e 100644 --- a/cl_dll/in_camera.cpp +++ b/cl_dll/in_camera.cpp @@ -17,7 +17,6 @@ #include "Exports.h" #include "SDL2/SDL_mouse.h" -#include "port.h" float CL_KeyState (kbutton_t *key); diff --git a/cl_dll/inputw32.cpp b/cl_dll/inputw32.cpp index dc41892b0..8b96c1c2e 100644 --- a/cl_dll/inputw32.cpp +++ b/cl_dll/inputw32.cpp @@ -8,8 +8,6 @@ // in_win.c -- windows 95 mouse and joystick code // 02/21/97 JCB Added extended DirectInput code to support external controllers. -#include "port.h" - #include "hud.h" #include "cl_util.h" #include "camera.h" diff --git a/common/nowin.h b/common/nowin.h deleted file mode 100644 index cecd2c1fc..000000000 --- a/common/nowin.h +++ /dev/null @@ -1,16 +0,0 @@ -//========= Copyright © 1996-2001, Valve LLC, All rights reserved. ============ -// -// Purpose: -// -// $NoKeywords: $ -//============================================================================= - -#ifndef INC_NOWIN_H -#define INC_NOWIN_H -#ifndef _WIN32 - -#include -#include - -#endif //!_WIN32 -#endif //INC_NOWIN_H diff --git a/common/parsemsg.cpp b/common/parsemsg.cpp index 2b1931ab2..2dec798ae 100644 --- a/common/parsemsg.cpp +++ b/common/parsemsg.cpp @@ -18,7 +18,6 @@ //-------------------------------------------------------------------------------------------------------------- #include "extdll.h" #include "parsemsg.h" -#include #define true 1 diff --git a/common/port.h b/common/port.h deleted file mode 100644 index f210f57cd..000000000 --- a/common/port.h +++ /dev/null @@ -1,92 +0,0 @@ -// port.h: portability helper -// -////////////////////////////////////////////////////////////////////// - -#if !defined PORT_H -#define PORT_H - -#include "archtypes.h" // DAL - -#ifdef _WIN32 - -// Insert your headers here -#include "Platform.h" - -#include - -#else // _WIN32 - -#include -#include -#include // exit() -#include // strncpy() -#include // tolower() -#include -#include -#include -#include - -typedef unsigned char BYTE; -typedef short int WORD; -typedef int32 LONG; -//typedef uint32 ULONG; -#ifndef ARCHTYPES_H -typedef uint32 ULONG; -#endif -typedef void *HANDLE; -#ifndef HMODULE -typedef void *HMODULE; -#endif -typedef char * LPSTR; - -#define __cdecl - - -//const int MAX_PATH = PATH_MAX; -#define MAX_PATH PATH_MAX - -#ifdef LINUX -typedef void *HINSTANCE; -typedef void *HWND; -typedef void *HDC; -typedef void *HGLRC; -#endif - - - -//#undef FALSE -//#undef TRUE - -#ifdef OSX -//#else -//const bool FALSE = false; -//const bool TRUE = true; -#endif - -#ifndef NULL - #define NULL 0 -#endif - -inline int ioctlsocket( int d, int cmd, uint32 *argp ) { return ioctl( d, cmd, argp ); } -inline int closesocket( int fd ) { return close( fd ); } -inline char * GetCurrentDirectory( size_t size, char * buf ) { return getcwd( buf, size ); } -inline int WSAGetLastError() { return errno; } - -inline void DebugBreak( void ) { exit( 1 ); } - -extern char g_szEXEName[ 4096 ]; - -#define _snprintf snprintf - -#if defined(OSX) -#define SO_ARCH_SUFFIX ".dylib" -#else -#if defined ( __x86_64__ ) -#define SO_ARCH_SUFFIX "_amd64.so" -#else -#define SO_ARCH_SUFFIX ".so" -#endif -#endif -#endif - -#endif // PORT_H diff --git a/projects/vs2017/hl_cdll.vcxproj b/projects/vs2017/hl_cdll.vcxproj index 6cfca3220..618448774 100644 --- a/projects/vs2017/hl_cdll.vcxproj +++ b/projects/vs2017/hl_cdll.vcxproj @@ -239,12 +239,10 @@ - - diff --git a/projects/vs2017/hl_cdll.vcxproj.filters b/projects/vs2017/hl_cdll.vcxproj.filters index 2d2a83286..da44d7e1a 100644 --- a/projects/vs2017/hl_cdll.vcxproj.filters +++ b/projects/vs2017/hl_cdll.vcxproj.filters @@ -479,18 +479,12 @@ Header Files\common - - Header Files\common - Header Files\common Header Files\common - - Header Files\common - Header Files\common diff --git a/projects/vs2017/hldll.vcxproj b/projects/vs2017/hldll.vcxproj index 8edbe1de6..0881d18f5 100644 --- a/projects/vs2017/hldll.vcxproj +++ b/projects/vs2017/hldll.vcxproj @@ -232,10 +232,8 @@ - - diff --git a/projects/vs2017/hldll.vcxproj.filters b/projects/vs2017/hldll.vcxproj.filters index f3e4b9c7e..de07d0456 100644 --- a/projects/vs2017/hldll.vcxproj.filters +++ b/projects/vs2017/hldll.vcxproj.filters @@ -581,15 +581,9 @@ Header Files\common - - Header Files\common - Header Files\common - - Header Files\common - Header Files\common diff --git a/projects/vs2019/hl_cdll.vcxproj b/projects/vs2019/hl_cdll.vcxproj index 3b4013ab2..39d457a00 100644 --- a/projects/vs2019/hl_cdll.vcxproj +++ b/projects/vs2019/hl_cdll.vcxproj @@ -239,12 +239,10 @@ - - diff --git a/projects/vs2019/hl_cdll.vcxproj.filters b/projects/vs2019/hl_cdll.vcxproj.filters index 6b9714186..8a0a5e6c4 100644 --- a/projects/vs2019/hl_cdll.vcxproj.filters +++ b/projects/vs2019/hl_cdll.vcxproj.filters @@ -500,18 +500,12 @@ Header Files\common - - Header Files\common - Header Files\common Header Files\common - - Header Files\common - Header Files\common diff --git a/projects/vs2019/hldll.vcxproj b/projects/vs2019/hldll.vcxproj index e92b18fdf..bec0e0765 100644 --- a/projects/vs2019/hldll.vcxproj +++ b/projects/vs2019/hldll.vcxproj @@ -232,10 +232,8 @@ - - diff --git a/projects/vs2019/hldll.vcxproj.filters b/projects/vs2019/hldll.vcxproj.filters index f3e4b9c7e..de07d0456 100644 --- a/projects/vs2019/hldll.vcxproj.filters +++ b/projects/vs2019/hldll.vcxproj.filters @@ -581,15 +581,9 @@ Header Files\common - - Header Files\common - Header Files\common - - Header Files\common - Header Files\common From fddcb4cbc66b5158463aadb6661badd10aa9ab6e Mon Sep 17 00:00:00 2001 From: Sam V Date: Thu, 18 Nov 2021 18:59:23 +0100 Subject: [PATCH 13/13] Remove redundant include guards #52 --- common/const.h | 2 -- dlls/animation.cpp | 10 ---------- dlls/animation.h | 2 -- dlls/cbase.h | 3 --- dlls/scripted.cpp | 7 ------- dlls/scripted.h | 2 -- dlls/talkmonster.h | 2 -- dlls/util.h | 6 +----- engine/cdll_int.h | 2 -- 9 files changed, 1 insertion(+), 35 deletions(-) diff --git a/common/const.h b/common/const.h index 7defb9897..caa247987 100644 --- a/common/const.h +++ b/common/const.h @@ -645,9 +645,7 @@ #define SF_TRAIN_PASSABLE 8 // Train is not solid -- used to make water trains // buttons -#ifndef IN_BUTTONS_H #include "in_buttons.h" -#endif // Break Model Defines diff --git a/dlls/animation.cpp b/dlls/animation.cpp index 5f3e27232..3c3815287 100644 --- a/dlls/animation.cpp +++ b/dlls/animation.cpp @@ -17,20 +17,10 @@ #include "util.h" #include "studio.h" - -#ifndef ACTIVITY_H #include "activity.h" -#endif - #include "activitymap.h" - -#ifndef ANIMATION_H #include "animation.h" -#endif - -#ifndef SCRIPTEVENT_H #include "scriptevent.h" -#endif extern globalvars_t *gpGlobals; diff --git a/dlls/animation.h b/dlls/animation.h index ec00ca40d..28bc76dc1 100644 --- a/dlls/animation.h +++ b/dlls/animation.h @@ -17,9 +17,7 @@ #define ACTIVITY_NOT_AVAILABLE -1 -#ifndef MONSTEREVENT_H #include "monsterevent.h" -#endif extern int IsSoundEvent( int eventNumber ); diff --git a/dlls/cbase.h b/dlls/cbase.h index 2f96d9270..8ac4e49a6 100644 --- a/dlls/cbase.h +++ b/dlls/cbase.h @@ -45,10 +45,7 @@ CBaseEntity #include "archtypes.h" // DAL #include "saverestore.h" #include "schedule.h" - -#ifndef MONSTEREVENT_H #include "monsterevent.h" -#endif #include "Platform.h" diff --git a/dlls/scripted.cpp b/dlls/scripted.cpp index 75b03dbe8..d5a505d2c 100644 --- a/dlls/scripted.cpp +++ b/dlls/scripted.cpp @@ -23,15 +23,8 @@ #include "util.h" #include "cbase.h" #include "monsters.h" - -#ifndef ANIMATION_H #include "animation.h" -#endif - -#ifndef SAVERESTORE_H #include "saverestore.h" -#endif - #include "schedule.h" #include "scripted.h" #include "defaultai.h" diff --git a/dlls/scripted.h b/dlls/scripted.h index e72e1eeb0..4a715d16d 100644 --- a/dlls/scripted.h +++ b/dlls/scripted.h @@ -15,9 +15,7 @@ #ifndef SCRIPTED_H #define SCRIPTED_H -#ifndef SCRIPTEVENT_H #include "scriptevent.h" -#endif #define SF_SCRIPT_WAITTILLSEEN 1 #define SF_SCRIPT_EXITAGITATED 2 diff --git a/dlls/talkmonster.h b/dlls/talkmonster.h index 594dda20e..39031520c 100644 --- a/dlls/talkmonster.h +++ b/dlls/talkmonster.h @@ -15,9 +15,7 @@ #ifndef TALKMONSTER_H #define TALKMONSTER_H -#ifndef MONSTERS_H #include "monsters.h" -#endif //========================================================= // Talking monster base class diff --git a/dlls/util.h b/dlls/util.h index d62e76939..9adc30c64 100644 --- a/dlls/util.h +++ b/dlls/util.h @@ -17,13 +17,9 @@ // // Misc utility code // -#ifndef ACTIVITY_H #include "activity.h" -#endif - -#ifndef ENGINECALLBACK_H #include "enginecallback.h" -#endif + inline void MESSAGE_BEGIN( int msg_dest, int msg_type, const float *pOrigin, entvars_t *ent ); // implementation later in this file extern globalvars_t *gpGlobals; diff --git a/engine/cdll_int.h b/engine/cdll_int.h index 59b378e9e..14e3385e2 100644 --- a/engine/cdll_int.h +++ b/engine/cdll_int.h @@ -87,9 +87,7 @@ typedef struct hud_player_info_s uint64 m_nSteamID; } hud_player_info_t; -#ifndef IN_BUTTONS_H #include "in_buttons.h" -#endif #define CLDLL_INTERFACE_VERSION 7