Skip to content

Commit

Permalink
Add re-release fog effect support.
Browse files Browse the repository at this point in the history
Keep fog parameters in player_state_t for proper delta compression.
Height fog seems broken but that's how it is in re-release.
  • Loading branch information
skullernet committed Oct 20, 2024
1 parent 0957581 commit fbf0cd9
Show file tree
Hide file tree
Showing 24 changed files with 454 additions and 63 deletions.
6 changes: 6 additions & 0 deletions doc/client.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -687,6 +687,12 @@ gl_waterwarp::
Enable screen warping effect when underwater. Only effective when using
GLSL backend. Default value is 0 (disabled).

gl_fog::
Enable re-release fog effect. Default value is 2.
- 0 — disable fog
- 1 — enable global fog
- 2 — enable global fog and height fog

gl_flarespeed::
Specifies flare fading effect speed. Default value is 8. Set this to 0
to disable fading.
Expand Down
14 changes: 12 additions & 2 deletions inc/common/msg.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,14 @@ typedef struct {
uint8_t loop_attenuation;
} entity_packed_t;

typedef struct {
uint8_t color[3][3];
uint32_t density;
uint16_t height_density;
uint16_t height_falloff;
int32_t height_dist[2];
} player_packed_fog_t;

typedef struct {
pmove_state_new_t pmove;
int16_t viewangles[3];
Expand All @@ -59,6 +67,7 @@ typedef struct {
uint8_t gunframe;
uint8_t blend[4];
uint8_t damage_blend[4];
player_packed_fog_t fog;
uint8_t fov;
uint8_t rdflags;
int16_t stats[MAX_STATS_NEW];
Expand All @@ -73,8 +82,9 @@ typedef enum {
MSG_PS_IGNORE_PREDICTION = BIT(5), // mutually exclusive with IGNORE_VIEWANGLES
MSG_PS_EXTENSIONS = BIT(6), // enable protocol extensions
MSG_PS_EXTENSIONS_2 = BIT(7), // enable more protocol extensions
MSG_PS_FORCE = BIT(8), // send even if unchanged (MVD stream only)
MSG_PS_REMOVE = BIT(9), // player is removed (MVD stream only)
MSG_PS_MOREBITS = BIT(8), // read more playerstate bits
MSG_PS_FORCE = BIT(9), // send even if unchanged (MVD stream only)
MSG_PS_REMOVE = BIT(10), // player is removed (MVD stream only)
} msgPsFlags_t;

typedef enum {
Expand Down
38 changes: 32 additions & 6 deletions inc/common/protocol.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,11 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#define PROTOCOL_VERSION_R1Q2 35
#define PROTOCOL_VERSION_Q2PRO 36
#define PROTOCOL_VERSION_MVD 37 // not used for UDP connections
#define PROTOCOL_VERSION_EXTENDED_OLD 3434
#define PROTOCOL_VERSION_EXTENDED 3435

#define PROTOCOL_VERSION_EXTENDED_MINIMUM 3434 // r2894
#define PROTOCOL_VERSION_EXTENDED_LIMITS_2 3435 // r3300
#define PROTOCOL_VERSION_EXTENDED_PLAYERFOG 3436 // r3579
#define PROTOCOL_VERSION_EXTENDED_CURRENT 3436 // r3579

#define PROTOCOL_VERSION_R1Q2_MINIMUM 1903 // b6377
#define PROTOCOL_VERSION_R1Q2_UCMD 1904 // b7387
Expand All @@ -48,13 +51,15 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#define PROTOCOL_VERSION_Q2PRO_CINEMATICS 1023 // r2263
#define PROTOCOL_VERSION_Q2PRO_EXTENDED_LIMITS 1024 // r2894
#define PROTOCOL_VERSION_Q2PRO_EXTENDED_LIMITS_2 1025 // r3300
#define PROTOCOL_VERSION_Q2PRO_CURRENT 1025 // r3300
#define PROTOCOL_VERSION_Q2PRO_PLAYERFOG 1026 // r3579
#define PROTOCOL_VERSION_Q2PRO_CURRENT 1026 // r3579

#define PROTOCOL_VERSION_MVD_MINIMUM 2009 // r168
#define PROTOCOL_VERSION_MVD_DEFAULT 2010 // r177
#define PROTOCOL_VERSION_MVD_EXTENDED_LIMITS 2011 // r2894
#define PROTOCOL_VERSION_MVD_EXTENDED_LIMITS_2 2012 // r3300
#define PROTOCOL_VERSION_MVD_CURRENT 2012 // r3300
#define PROTOCOL_VERSION_MVD_PLAYERFOG 2013 // r3579
#define PROTOCOL_VERSION_MVD_CURRENT 2013 // r3579

#define R1Q2_SUPPORTED(x) \
((x) >= PROTOCOL_VERSION_R1Q2_MINIMUM && \
Expand All @@ -68,6 +73,10 @@ with this program; if not, write to the Free Software Foundation, Inc.,
((x) >= PROTOCOL_VERSION_MVD_MINIMUM && \
(x) <= PROTOCOL_VERSION_MVD_CURRENT)

#define EXTENDED_SUPPORTED(x) \
((x) >= PROTOCOL_VERSION_EXTENDED_MINIMUM && \
(x) <= PROTOCOL_VERSION_EXTENDED_CURRENT)

#define VALIDATE_CLIENTNUM(csr, x) \
((x) >= -1 && (x) < (csr)->max_edicts - 1)

Expand Down Expand Up @@ -213,6 +222,17 @@ typedef enum {

//==============================================

typedef enum {
FOG_BIT_COLOR = BIT(0),
FOG_BIT_DENSITY = BIT(1),
FOG_BIT_HEIGHT_DENSITY = BIT(2),
FOG_BIT_HEIGHT_FALLOFF = BIT(3),
FOG_BIT_HEIGHT_START_COLOR = BIT(4),
FOG_BIT_HEIGHT_END_COLOR = BIT(5),
FOG_BIT_HEIGHT_START_DIST = BIT(6),
FOG_BIT_HEIGHT_END_DIST = BIT(7),
} fog_bits_t;

// player_state_t communication

#define PS_M_TYPE BIT(0)
Expand All @@ -231,7 +251,9 @@ typedef enum {
#define PS_WEAPONINDEX BIT(12)
#define PS_WEAPONFRAME BIT(13)
#define PS_RDFLAGS BIT(14)
#define PS_RESERVED BIT(15)
#define PS_MOREBITS BIT(15) // read one additional byte

#define PS_FOG BIT(16)

// R1Q2 protocol specific extra flags
#define EPS_GUNOFFSET BIT(0)
Expand Down Expand Up @@ -264,7 +286,11 @@ typedef enum {
#define PPS_GUNANGLES BIT(12)
#define PPS_RDFLAGS BIT(13)
#define PPS_STATS BIT(14)
#define PPS_REMOVE BIT(15)
#define PPS_MOREBITS BIT(15) // read one additional byte
// same as PPS_REMOVE for old demos!!!

#define PPS_REMOVE BIT(16)
#define PPS_FOG BIT(17)

// this is just a small hack to store inuse flag
// in a field left otherwise unused by MVD code
Expand Down
2 changes: 2 additions & 0 deletions inc/refresh/refresh.h
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,8 @@ typedef struct {
vec3_t viewangles;
vec4_t screen_blend; // rgba 0-1 full screen blend
vec4_t damage_blend; // rgba 0-1 damage blend
player_fog_t fog;
player_heightfog_t heightfog;
float time; // time is uesed to auto animate
int rdflags; // RDF_UNDERWATER, etc
bool extended;
Expand Down
2 changes: 1 addition & 1 deletion inc/shared/game.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
//

#define GAME_API_VERSION_OLD 3 // game uses gclient_old_t
#define GAME_API_VERSION_NEW 3300 // game uses gclient_new_t
#define GAME_API_VERSION_NEW 3301 // game uses gclient_new_t

#if USE_NEW_GAME_API
#define GAME_API_VERSION GAME_API_VERSION_NEW
Expand Down
23 changes: 22 additions & 1 deletion inc/shared/shared.h
Original file line number Diff line number Diff line change
Expand Up @@ -1537,6 +1537,21 @@ typedef struct {
} player_state_old_t;

#if USE_NEW_GAME_API
typedef struct {
vec3_t color;
float density;
float sky_factor;
} player_fog_t;

typedef struct {
struct {
vec3_t color;
float dist;
} start, end;
float density;
float falloff;
} player_heightfog_t;

typedef struct {
pmove_state_new_t pmove; // for prediction

Expand All @@ -1551,15 +1566,21 @@ typedef struct {
vec3_t gunoffset;
int gunindex;
int gunframe;
int reserved_1;
int reserved_2;

vec4_t blend; // rgba full screen effect
vec4_t damage_blend;

player_fog_t fog;
player_heightfog_t heightfog;

float fov; // horizontal field of view

int rdflags; // refdef flags

int reserved[4];
int reserved_3;
int reserved_4;

int16_t stats[MAX_STATS_NEW]; // fast status bar updates
} player_state_new_t;
Expand Down
3 changes: 2 additions & 1 deletion src/client/client.h
Original file line number Diff line number Diff line change
Expand Up @@ -495,6 +495,7 @@ typedef struct {
player_packed_t ps;
entity_packed_t entities[MAX_EDICTS];
msgEsFlags_t esFlags; // for writing
msgPsFlags_t psFlags;

sizebuf_t message;
} gtv;
Expand Down Expand Up @@ -693,7 +694,7 @@ void CL_SendCmd(void);
(MSG_ES_LONGSOLID | MSG_ES_UMASK | MSG_ES_BEAMORIGIN | MSG_ES_SHORTANGLES | MSG_ES_EXTENSIONS)

#define CL_ES_EXTENDED_MASK_2 (CL_ES_EXTENDED_MASK | MSG_ES_EXTENSIONS_2)
#define CL_PS_EXTENDED_MASK_2 (MSG_PS_EXTENSIONS | MSG_PS_EXTENSIONS_2)
#define CL_PS_EXTENDED_MASK_2 (MSG_PS_EXTENSIONS | MSG_PS_EXTENSIONS_2 | MSG_PS_MOREBITS)

typedef struct {
int type;
Expand Down
4 changes: 2 additions & 2 deletions src/client/demo.c
Original file line number Diff line number Diff line change
Expand Up @@ -420,7 +420,7 @@ static void CL_Record_f(void)
// send the serverdata
MSG_WriteByte(svc_serverdata);
if (cl.csr.extended)
MSG_WriteLong(PROTOCOL_VERSION_EXTENDED);
MSG_WriteLong(PROTOCOL_VERSION_EXTENDED_CURRENT);
else
MSG_WriteLong(min(cls.serverProtocol, PROTOCOL_VERSION_DEFAULT));
MSG_WriteLong(cl.servercount);
Expand Down Expand Up @@ -1185,7 +1185,7 @@ bool CL_GetDemoInfo(const char *path, demoInfo_t *info)
goto fail;
}
c = MSG_ReadLong();
if (c == PROTOCOL_VERSION_EXTENDED || c == PROTOCOL_VERSION_EXTENDED_OLD) {
if (EXTENDED_SUPPORTED(c)) {
csr = &cs_remap_new;
} else if (c < PROTOCOL_VERSION_OLD || c > PROTOCOL_VERSION_DEFAULT) {
goto fail;
Expand Down
21 changes: 21 additions & 0 deletions src/client/entities.c
Original file line number Diff line number Diff line change
Expand Up @@ -1315,6 +1315,14 @@ static inline float lerp_client_fov(float ofov, float nfov, float lerp)
return ofov + lerp * (nfov - ofov);
}

static inline void lerp_values(const void *from, const void *to, float lerp, void *out, int count)
{
float backlerp = 1.0f - lerp;

for (int i = 0; i < count; i++)
((float *)out)[i] = ((const float *)from)[i] * backlerp + ((const float *)to)[i] * lerp;
}

/*
===============
CL_CalcViewValues
Expand Down Expand Up @@ -1389,6 +1397,19 @@ void CL_CalcViewValues(void)
Vector4Copy(ps->blend, cl.refdef.screen_blend);
Vector4Copy(ps->damage_blend, cl.refdef.damage_blend);

// interpolate fog
if (cl.psFlags & MSG_PS_MOREBITS) {
lerp_values(&ops->fog, &ps->fog, lerp,
&cl.refdef.fog, sizeof(cl.refdef.fog) / sizeof(float));
// no lerping if moved too far
if (fabsf(ps->heightfog.start.dist - ops->heightfog.start.dist) > 512 ||
fabsf(ps->heightfog.end .dist - ops->heightfog.end .dist) > 512)
cl.refdef.heightfog = ps->heightfog;
else
lerp_values(&ops->heightfog, &ps->heightfog, lerp,
&cl.refdef.heightfog, sizeof(cl.refdef.heightfog) / sizeof(float));
}

#if USE_FPS
ps = &cl.keyframe.ps;
ops = &cl.oldkeyframe.ps;
Expand Down
10 changes: 6 additions & 4 deletions src/client/gtv.c
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,10 @@ static void build_gamestate(void)

// set protocol flags
cls.gtv.esFlags = MSG_ES_UMASK | MSG_ES_BEAMORIGIN | (cl.esFlags & CL_ES_EXTENDED_MASK_2);
cls.gtv.psFlags = MSG_PS_FORCE | (cl.psFlags & CL_PS_EXTENDED_MASK_2);

if (cls.gtv.psFlags & MSG_PS_EXTENSIONS_2)
cls.gtv.psFlags |= MSG_PS_MOREBITS;
}

static void emit_gamestate(void)
Expand Down Expand Up @@ -99,8 +103,7 @@ static void emit_gamestate(void)
MSG_WriteByte(0);

// send player state
MSG_WriteDeltaPlayerstate_Packet(NULL, &cls.gtv.ps,
cl.clientNum, cl.psFlags | MSG_PS_FORCE);
MSG_WriteDeltaPlayerstate_Packet(NULL, &cls.gtv.ps, cl.clientNum, cls.gtv.psFlags);
MSG_WriteByte(CLIENTNUM_NONE);

// send entity states
Expand Down Expand Up @@ -138,8 +141,7 @@ void CL_GTV_EmitFrame(void)
// send player state
MSG_PackPlayerNew(&newps, &cl.frame.ps);

MSG_WriteDeltaPlayerstate_Packet(&cls.gtv.ps, &newps,
cl.clientNum, cl.psFlags | MSG_PS_FORCE);
MSG_WriteDeltaPlayerstate_Packet(&cls.gtv.ps, &newps, cl.clientNum, cls.gtv.psFlags);

// shuffle current state to previous
cls.gtv.ps = newps;
Expand Down
17 changes: 13 additions & 4 deletions src/client/parse.c
Original file line number Diff line number Diff line change
Expand Up @@ -320,6 +320,9 @@ static void CL_ParseFrame(int extrabits)

// parse playerstate
bits = MSG_ReadWord();
if (cl.psFlags & MSG_PS_MOREBITS && bits & PS_MOREBITS)
bits |= (uint32_t)MSG_ReadByte() << 16;

if (cls.serverProtocol > PROTOCOL_VERSION_DEFAULT) {
MSG_ParseDeltaPlayerstate_Enhanced(from, &frame.ps, bits, extraflags, cl.psFlags);
#if USE_DEBUG
Expand Down Expand Up @@ -532,7 +535,7 @@ static void CL_ParseServerData(void)
cls.serverProtocol, protocol);
}
// BIG HACK to let demos from release work with the 3.0x patch!!!
if (protocol == PROTOCOL_VERSION_EXTENDED || protocol == PROTOCOL_VERSION_EXTENDED_OLD) {
if (EXTENDED_SUPPORTED(protocol)) {
cl.csr = cs_remap_new;
cls.serverProtocol = PROTOCOL_VERSION_DEFAULT;
} else if (protocol < PROTOCOL_VERSION_OLD || protocol > PROTOCOL_VERSION_DEFAULT) {
Expand Down Expand Up @@ -649,6 +652,8 @@ static void CL_ParseServerData(void)
Com_DPrintf("Q2PRO protocol extensions v2 enabled\n");
cl.esFlags |= MSG_ES_EXTENSIONS_2;
cl.psFlags |= MSG_PS_EXTENSIONS_2;
if (cls.protocolVersion >= PROTOCOL_VERSION_Q2PRO_PLAYERFOG)
cl.psFlags |= MSG_PS_MOREBITS;
PmoveEnableExt(&cl.pmp);
}
} else {
Expand Down Expand Up @@ -684,9 +689,13 @@ static void CL_ParseServerData(void)
cl.psFlags |= MSG_PS_EXTENSIONS;

// hack for demo playback
if (protocol == PROTOCOL_VERSION_EXTENDED) {
cl.esFlags |= MSG_ES_EXTENSIONS_2;
cl.psFlags |= MSG_PS_EXTENSIONS_2;
if (EXTENDED_SUPPORTED(protocol)) {
if (protocol >= PROTOCOL_VERSION_EXTENDED_LIMITS_2) {
cl.esFlags |= MSG_ES_EXTENSIONS_2;
cl.psFlags |= MSG_PS_EXTENSIONS_2;
}
if (protocol >= PROTOCOL_VERSION_EXTENDED_PLAYERFOG)
cl.psFlags |= MSG_PS_MOREBITS;
}
}

Expand Down
Loading

0 comments on commit fbf0cd9

Please sign in to comment.