Skip to content

Commit

Permalink
Implement fog (#225)
Browse files Browse the repository at this point in the history
  • Loading branch information
ScriptedSnark committed May 28, 2024
1 parent c0b642a commit 7538c9e
Show file tree
Hide file tree
Showing 12 changed files with 207 additions and 0 deletions.
2 changes: 2 additions & 0 deletions src/game/client/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ add_sources(
events.cpp
eventscripts.h
Exports.h
fog.cpp
fog.h
GameStudioModelRenderer.cpp
GameStudioModelRenderer.h
global_consts.h
Expand Down
45 changes: 45 additions & 0 deletions src/game/client/fog.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
#include "hud.h"
#include "fog.h"
#include "triangleapi.h"

CFog gFog;

CFog::CFog()
{
ClearFog();
}

void CFog::SetWaterLevel(int waterLevel)
{
m_iWaterLevel = waterLevel;
}

void CFog::SetFogParameters(const FogParams &params)
{
m_FogParams = params;
}

FogParams CFog::GetFogParameters() const
{
return m_FogParams;
}

void CFog::RenderFog()
{
bool bFog;

if (m_iWaterLevel <= 2) // checking if player is not underwater
bFog = (m_FogParams.density > 0.0f) ? true : false;
else
bFog = false;

gEngfuncs.pTriAPI->FogParams(m_FogParams.density, m_FogParams.fogSkybox);
gEngfuncs.pTriAPI->Fog(m_FogParams.color, FOG_START_DISTANCE, FOG_END_DISTANCE, bFog);
}

void CFog::ClearFog()
{
m_FogParams.fogSkybox = false;
m_FogParams.color[0] = m_FogParams.color[1] = m_FogParams.color[2] = 0.0f;
m_FogParams.density = 0.0f;
}
30 changes: 30 additions & 0 deletions src/game/client/fog.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#ifndef FOG_H
#define FOG_H

constexpr float FOG_START_DISTANCE = 1500.0f;
constexpr float FOG_END_DISTANCE = 2000.0f;

struct FogParams
{
bool fogSkybox = false;
float color[3] = {0.0f, 0.0f, 0.0f};
float density = 0.0f;
};

class CFog
{
public:
CFog();
void SetWaterLevel(int waterLevel);
void SetFogParameters(const FogParams &params);
FogParams GetFogParameters() const;
void RenderFog();
void ClearFog();
private:
FogParams m_FogParams;
int m_iWaterLevel;
};

extern CFog gFog;

#endif // FOG_H
4 changes: 4 additions & 0 deletions src/game/client/hud.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
#include "results.h"
#include "svc_messages.h"
#include "sdl_rt.h"
#include "fog.h"

#if USE_UPDATER
#include "updater/update_checker.h"
Expand Down Expand Up @@ -294,6 +295,7 @@ void CHud::Init(void)
HookHudMessage<&CHud::MsgFunc_SetFOV>("SetFOV");
HookHudMessage<&CHud::MsgFunc_Concuss>("Concuss");
HookHudMessage<&CHud::MsgFunc_Logo>("Logo");
HookHudMessage<&CHud::MsgFunc_Fog>("Fog");

// TFFree CommandMenu
HookCommand("+commandmenu", [] {
Expand Down Expand Up @@ -531,6 +533,8 @@ void CHud::VidInit(void)

m_iFontHeight = m_rgrcRects[m_HUD_number_0].bottom - m_rgrcRects[m_HUD_number_0].top;

gFog.ClearFog();

for (CHudElem *i : m_HudList)
i->VidInit();
}
Expand Down
1 change: 1 addition & 0 deletions src/game/client/hud.h
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,7 @@ class CHud
int MsgFunc_ViewMode(const char *pszName, int iSize, void *pbuf);
int MsgFunc_SetFOV(const char *pszName, int iSize, void *pbuf);
int MsgFunc_Concuss(const char *pszName, int iSize, void *pbuf);
int MsgFunc_Fog(const char *pszName, int iSize, void *pbuf);

float GetSensitivity();
BHopCap GetBHopCapState();
Expand Down
32 changes: 32 additions & 0 deletions src/game/client/hud_msg.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@
#include "particleman.h"
extern IParticleMan *g_pParticleMan;

#include "fog.h"

#define MAX_CLIENTS 32

#if !defined(_TFC)
Expand Down Expand Up @@ -187,3 +189,33 @@ int CHud::MsgFunc_Concuss(const char *pszName, int iSize, void *pbuf)
CHudStatusIcons::Get()->DisableIcon("dmg_concuss");
return 1;
}

int CHud::MsgFunc_Fog(const char *pszName, int iSize, void *pbuf)
{
FogParams fogParams;
float density;

// Reset fog parameters
gFog.ClearFog();

BEGIN_READ(pbuf, iSize);

fogParams.color[0] = (float)READ_BYTE(); // r
fogParams.color[1] = (float)READ_BYTE(); // g
fogParams.color[2] = (float)READ_BYTE(); // b

density = READ_FLOAT();

if (READ_OK())
{
fogParams.density = density;
fogParams.fogSkybox = true;
gFog.SetFogParameters(fogParams);
}
else
{
gFog.ClearFog();
}

return 1;
}
3 changes: 3 additions & 0 deletions src/game/client/tri.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@

#include "particleman.h"
#include "tri.h"
#include "fog.h"

CSysModule *g_hParticleManModule = NULL;
IParticleMan *g_pParticleMan = NULL;
Expand Down Expand Up @@ -101,6 +102,8 @@ void CL_DLLEXPORT HUD_DrawTransparentTriangles(void)
RunEventList();
#endif

gFog.RenderFog();

if (g_pParticleMan)
g_pParticleMan->Update();
}
3 changes: 3 additions & 0 deletions src/game/client/view.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include "hud/speedometer.h"
#include "hud/jumpspeed.h"
#include "hud/strafeguide.h"
#include "fog.h"

#ifndef M_PI
#define M_PI 3.14159265358979323846 // matches value in gcc v2 math.h
Expand Down Expand Up @@ -1679,6 +1680,8 @@ void CL_DLLEXPORT V_CalcRefdef(struct ref_params_s *pparams)
CHudSpeedometer::Get()->UpdateSpeed(pparams->simvel);
CHudJumpspeed::Get()->UpdateSpeed(pparams->simvel);
CHudStrafeGuide::Get()->Update(pparams);

gFog.SetWaterLevel(pparams->waterlevel);

// intermission / finale rendering
if (pparams->intermission)
Expand Down
12 changes: 12 additions & 0 deletions src/game/server/effects.h
Original file line number Diff line number Diff line change
Expand Up @@ -218,4 +218,16 @@ class CLaser : public CBeam
Vector m_firePosition;
};

class CClientFog : public CBaseEntity
{
public:
virtual void Spawn();
virtual void KeyValue(KeyValueData *pkvd);

public:
int m_iStartDist = 0;
int m_iEndDist = 0;
float m_fDensity = 0.0f;
};

#endif //EFFECTS_H
13 changes: 13 additions & 0 deletions src/game/server/enginecallback.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,18 @@ inline void MESSAGE_BEGIN(int msg_dest, int msg_type, const float *pOrigin = NUL
#define WRITE_COORD (*g_engfuncs.pfnWriteCoord)
#define WRITE_STRING (*g_engfuncs.pfnWriteString)
#define WRITE_ENTITY (*g_engfuncs.pfnWriteEntity)

inline void WRITE_FLOAT(float val)
{
char bytes[sizeof(val)];
memcpy(bytes, &val, sizeof(bytes));

for (int i = 0; i < sizeof(bytes); i++)
{
g_engfuncs.pfnWriteByte(bytes[i]);
}
}

#define CVAR_REGISTER (*g_engfuncs.pfnCVarRegister)
#define CVAR_GET_FLOAT (*g_engfuncs.pfnCVarGetFloat)
#define CVAR_GET_STRING (*g_engfuncs.pfnCVarGetString)
Expand All @@ -91,6 +103,7 @@ inline void MESSAGE_BEGIN(int msg_dest, int msg_type, const float *pOrigin = NUL
#define ALERT (*g_engfuncs.pfnAlertMessage)
#define ENGINE_FPRINTF (*g_engfuncs.pfnEngineFprintf)
#define ALLOC_PRIVATE (*g_engfuncs.pfnPvAllocEntPrivateData)

inline void *GET_PRIVATE(edict_t *pent)
{
if (pent)
Expand Down
21 changes: 21 additions & 0 deletions src/game/server/player.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,7 @@ int gmsgAllowSpec = 0;
int gmsgViewMode = 0;
int gmsgVGUIMenu = 0;
int gmsgStatusIcon = 0;
int gmsgFog = 0;

const char *const gCustomMessages[] = {
"IconInfo",
Expand Down Expand Up @@ -263,6 +264,8 @@ void LinkUserMessages(void)
{
REG_USER_MSG(gCustomMessages[i], 0);
}

gmsgFog = REG_USER_MSG("Fog", 7);
}

LINK_ENTITY_TO_CLASS(player, CBasePlayer);
Expand Down Expand Up @@ -4092,6 +4095,24 @@ void CBasePlayer ::UpdateClientData(void)
MESSAGE_END();
}

// Send fog message
CBaseEntity *pEntity = UTIL_FindEntityByClassname(nullptr, "env_fog");
if (pEntity)
{
CClientFog *pFog = static_cast<CClientFog *>(pEntity);

int r = clamp(int(pFog->pev->rendercolor[0]), 0, 255);
int g = clamp(int(pFog->pev->rendercolor[1]), 0, 255);
int b = clamp(int(pFog->pev->rendercolor[2]), 0, 255);

MESSAGE_BEGIN(MSG_ONE, gmsgFog, nullptr, pev);
WRITE_BYTE(r);
WRITE_BYTE(g);
WRITE_BYTE(b);
WRITE_FLOAT(pFog->m_fDensity);
MESSAGE_END();
}

g_pGameRules->InitHUD(this);
m_fGameHUDInitialized = TRUE;
m_iObserverMode = OBS_ROAMING;
Expand Down
41 changes: 41 additions & 0 deletions src/game/server/triggers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include "player.h"
#include "saverestore.h"
#include "trains.h" // trigger_camera has train functionality
#include "effects.h" // fog
#include "gamerules.h"

#define SF_TRIGGER_PUSH_START_OFF 2 //spawnflag that makes trigger_push spawn turned OFF
Expand Down Expand Up @@ -2333,3 +2334,43 @@ void CTriggerCamera::Move()
float fraction = 2 * gpGlobals->frametime;
pev->velocity = ((pev->movedir * pev->speed) * fraction) + (pev->velocity * (1 - fraction));
}

LINK_ENTITY_TO_CLASS(env_fog, CClientFog)

void CClientFog::KeyValue(KeyValueData *pkvd)
{
#if 0
if (FStrEq(pkvd->szKeyName, "startdist"))
{
m_iStartDist = Q_atoi(pkvd->szValue);
pkvd->fHandled = TRUE;
}
else if (FStrEq(pkvd->szKeyName, "enddist"))
{
m_iEndDist = Q_atoi(pkvd->szValue);
pkvd->fHandled = TRUE;
}
else
#endif
if (FStrEq(pkvd->szKeyName, "density"))
{
m_fDensity = atof(pkvd->szValue);

if (m_fDensity < 0 || m_fDensity > 0.01)
m_fDensity = 0;

pkvd->fHandled = TRUE;
}
else
{
CBaseEntity::KeyValue(pkvd);
}
}

void CClientFog::Spawn()
{
pev->movetype = MOVETYPE_NOCLIP;
pev->solid = SOLID_NOT; // Remove model & collisions
pev->renderamt = 0; // The engine won't draw this model if this is set to 0 and blending is on
pev->rendermode = kRenderTransTexture;
}

0 comments on commit 7538c9e

Please sign in to comment.