Skip to content

Commit

Permalink
Merge pull request #961 from qw-ctf/alphaents
Browse files Browse the repository at this point in the history
Support FTE_PEXT_TRANS and FTE_PEXT_COLOURMOD.
  • Loading branch information
tcsabina authored Nov 11, 2024
2 parents 660e7af + f670f94 commit c8c53f1
Show file tree
Hide file tree
Showing 16 changed files with 412 additions and 28 deletions.
51 changes: 47 additions & 4 deletions src/cl_ents.c
Original file line number Diff line number Diff line change
Expand Up @@ -558,6 +558,15 @@ void CL_ParseDelta (entity_state_t *from, entity_state_t *to, int bits) {
}
#endif

#ifdef FTE_PEXT_COLOURMOD
if ((morebits & U_FTE_COLOURMOD) && (cls.fteprotocolextensions & FTE_PEXT_COLOURMOD))
{
to->colourmod[0] = MSG_ReadByte();
to->colourmod[1] = MSG_ReadByte();
to->colourmod[2] = MSG_ReadByte();
}
#endif

#ifdef FTE_PEXT_ENTITYDBL
if (morebits & U_FTE_ENTITYDBL) {
to->number += 512;
Expand Down Expand Up @@ -1045,8 +1054,19 @@ void CL_LinkPacketEntities(void)
}
}
#if defined(FTE_PEXT_TRANS)
//set trans
ent.alpha = state->trans/255.0;
// set trans, 0 and 255 are both opaque, represented by alpha 0.
ent.alpha = state->trans == 255 ? 0.0f : (float)state->trans / 254.0f;
#endif
#if defined(FTE_PEXT_COLOURMOD)
// colourmod 0 is unset, 32 (1.0) incurs no color change
if ((state->colourmod[0] > 0 || state->colourmod[1] > 0 || state->colourmod[2] > 0) &&
!(state->colourmod[0] == 32 && state->colourmod[1] == 32 && state->colourmod[2] == 32))
{
ent.r_modelcolor[0] = ((float) state->colourmod[0] * 8.0f) / 256.0f;
ent.r_modelcolor[1] = ((float) state->colourmod[1] * 8.0f) / 256.0f;
ent.r_modelcolor[2] = ((float) state->colourmod[2] * 8.0f) / 256.0f;
ent.renderfx |= RF_FORCECOLOURMOD;
}
#endif

if (ent.model->flags & EF_ROTATE)
Expand Down Expand Up @@ -1388,7 +1408,23 @@ void CL_ParsePlayerinfo (void)
}
else
{
flags = state->flags = MSG_ReadShort ();
#ifdef FTE_PEXT_TRANS
flags = (unsigned short) MSG_ReadShort ();
if (cls.fteprotocolextensions & FTE_PEXT_TRANS)
{
if (flags & PF_EXTRA_PFS)
flags |= MSG_ReadByte() << 16;
}
else
{
// Without PEXT_TRANS there's no PF_EXTRA_PFS, move
// PF_ONGROUND and PF_SOLID to their expected offsets.
flags = (flags & 0x3fff) | (flags & 0xc000) << 8;
}
state->flags = flags;
#else
state->flags = flags = MSG_ReadShort ();
#endif

state->messagenum = cl.parsecount;
if (cls.mvdprotocolextensions1 & MVD_PEXT1_FLOATCOORDS) {
Expand Down Expand Up @@ -1467,11 +1503,18 @@ void CL_ParsePlayerinfo (void)
state->weaponframe = 0;


state->alpha = 255;
#ifdef FTE_PEXT_TRANS
if (flags & PF_TRANS_Z && cls.fteprotocolextensions & FTE_PEXT_TRANS)
state->alpha = MSG_ReadByte();
#endif
#ifdef FTE_PEXT_COLOURMOD
if (flags & PF_COLOURMOD && cls.fteprotocolextensions & FTE_PEXT_COLOURMOD)
{
state->colourmod[0] = MSG_ReadByte();
state->colourmod[1] = MSG_ReadByte();
state->colourmod[2] = MSG_ReadByte();
}
#endif

if (cl.z_ext & Z_EXT_PM_TYPE)
{
Expand Down
11 changes: 11 additions & 0 deletions src/cl_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,10 @@ cvar_t cl_pext_floatcoords = {"cl_pext_floatcoords", "1"};
cvar_t cl_pext_alpha = {"cl_pext_alpha", "1"};
#endif

#ifdef FTE_PEXT_COLOURMOD
cvar_t cl_pext_colourmod = {"cl_pext_colourmod", "1"};
#endif

#ifdef CLIENTONLY
#define PROCESS_SERVERPACKETS_IMMEDIATELY (0)
#else
Expand Down Expand Up @@ -473,6 +477,10 @@ unsigned int CL_SupportedFTEExtensions (void)
if (cl_pext_alpha.value)
fteprotextsupported |= FTE_PEXT_TRANS;
#endif
#ifdef FTE_PEXT_COLOURMOD
if (cl_pext_colourmod.value)
fteprotextsupported |= FTE_PEXT_COLOURMOD;
#endif

if (cl_pext_limits.value) {
#ifdef FTE_PEXT_MODELDBL
Expand Down Expand Up @@ -1871,6 +1879,9 @@ static void CL_InitLocal(void)
#ifdef FTE_PEXT_TRANS
Cvar_Register(&cl_pext_alpha);
#endif
#ifdef FTE_PEXT_COLOURMOD
Cvar_Register(&cl_pext_colourmod);
#endif

Cvar_SetCurrentGroup(CVAR_GROUP_INPUT_KEYBOARD);
Cvar_Register(&allow_scripts);
Expand Down
15 changes: 15 additions & 0 deletions src/cl_parse.c
Original file line number Diff line number Diff line change
Expand Up @@ -1875,6 +1875,21 @@ void CL_ParseStatic (qbool extended)
ent->frame = es.frame;
ent->colormap = vid.colormap;
ent->skinnum = es.skinnum;
#ifdef FTE_PEXT_TRANS
// set trans, 0 and 255 are both opaque, represented by alpha 0.
ent->alpha = es.trans == 255 ? 0.0f : (float)es.trans / 254.0f;
#endif
#ifdef FTE_PEXT_COLOURMOD
// Skip colourmod if unset, or identity
if ((es.colourmod[0] > 0 || es.colourmod[1] > 0 || es.colourmod[2] > 0) &&
!(es.colourmod[0] == 32 && es.colourmod[1] == 32 && es.colourmod[2] == 32))
{
ent->r_modelcolor[0] = (float)es.colourmod[0] * 8.0f / 256.0f;
ent->r_modelcolor[1] = (float)es.colourmod[1] * 8.0f / 256.0f;
ent->r_modelcolor[2] = (float)es.colourmod[2] * 8.0f / 256.0f;
ent->renderfx |= RF_FORCECOLOURMOD;
}
#endif

VectorCopy(es.origin, ent->origin);
VectorCopy(es.angles, ent->angles);
Expand Down
5 changes: 5 additions & 0 deletions src/client.h
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,12 @@ typedef struct

int flags; // Dead, gib, etc.

#ifdef FTE_PEXT_TRANS
byte alpha;
#endif
#ifdef FTE_PEXT_COLOURMOD
byte colourmod[3];
#endif

byte vw_index;
byte pm_type;
Expand Down
3 changes: 3 additions & 0 deletions src/g_public.h
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,9 @@ typedef enum

// !!! new things comes to end of list !!!

// G_Map_Extension syscalls
#define G_EXTENSIONS_FIRST 256

//
// functions exported by the game subsystem
//
Expand Down
146 changes: 143 additions & 3 deletions src/pr2_cmds.c
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,22 @@ static float GETFLOAT(int i)
}
#endif

typedef intptr_t (*ext_syscall_t)(intptr_t *arg);
static intptr_t EXT_MapExtFieldPtr(intptr_t *args);
static intptr_t EXT_SetExtFieldPtr(intptr_t *args);
static intptr_t EXT_GetExtFieldPtr(intptr_t *args);
struct
{
char *extname;
ext_syscall_t fun;
} ext_syscalls[] =
{
{"MapExtFieldPtr", EXT_MapExtFieldPtr},
{"SetExtFieldPtr", EXT_SetExtFieldPtr},
{"GetExtFieldPtr", EXT_GetExtFieldPtr},
};
ext_syscall_t ext_syscall_tbl[256];

int NUM_FOR_GAME_EDICT(byte *e)
{
int b;
Expand Down Expand Up @@ -1405,6 +1421,17 @@ void PF2_makestatic(edict_t *ent)
s->skinnum = ent->v->skin;
VectorCopy(ent->v->origin, s->origin);
VectorCopy(ent->v->angles, s->angles);
#ifdef FTE_PEXT_TRANS
s->trans = ent->xv.alpha >= 1.0f ? 0 : bound(0, (byte)(ent->xv.alpha * 254.0), 254);
#endif
#ifdef FTE_PEXT_COLOURMOD
if (ent->xv.colourmod[0] != 1.0f && ent->xv.colourmod[1] != 1.0f && ent->xv.colourmod[2] != 1.0f)
{
s->colourmod[0] = bound(0, ent->xv.colourmod[0] * (256.0f / 8.0f), 255);
s->colourmod[1] = bound(0, ent->xv.colourmod[1] * (256.0f / 8.0f), 255);
s->colourmod[2] = bound(0, ent->xv.colourmod[2] * (256.0f / 8.0f), 255);
}
#endif
++sv.static_entity_count;

// throw the entity away now
Expand Down Expand Up @@ -1951,6 +1978,94 @@ intptr_t PF2_FS_GetFileList(char *path, char *ext,
return numfiles;
}

// To prevent mods from hardcoding field offsets which would cause engine incompatibilities.
static uint32_t GetExtFieldCookie(void)
{
static uint32_t cookie = 0;
while (cookie == 0)
{
cookie = ((uint32_t)(rand() & 0xFFFF)) << 16;
}
return cookie;
}

static qbool ValidateExtFieldToken(uint32_t token, uint32_t *offset)
{
uint32_t cookie = GetExtFieldCookie();
*offset = token & ~cookie;
return (token & cookie) == cookie;
}

static intptr_t EXT_SetExtFieldPtr(intptr_t *args)
{
uint32_t field_ref;
edict_t *e;
size_t size;

if (!ValidateExtFieldToken(args[2], &field_ref))
{
Con_Printf("SetExtFieldPtr: Corrupt field reference!\n");
return 0;
}

size = args[4];

if ((field_ref + size) > sizeof(ext_entvars_t))
{
Con_Printf("SetExtFieldPtr: Field reference out of bounds!\n");
return 0;
}

e = &sv.edicts[NUM_FOR_GAME_EDICT(VM_ArgPtr(args[1]))];
memcpy((byte*)&e->xv + field_ref, VM_ArgPtr(args[3]), size);

return 1;
}

static intptr_t EXT_GetExtFieldPtr(intptr_t *args)
{
uint32_t field_ref;
edict_t *e;
size_t size;

if (!ValidateExtFieldToken(args[2], &field_ref))
{
Con_Printf("GetExtFieldPtr: Corrupt field reference!\n");
return 0;
}

size = args[4];

if ((field_ref + size) > sizeof(ext_entvars_t))
{
Con_Printf("GetExtFieldPtr: Field reference out of bounds!\n");
return 0;
}

e = &sv.edicts[NUM_FOR_GAME_EDICT(VM_ArgPtr(args[1]))];
memcpy(VM_ArgPtr(args[3]), (byte*)&e->xv + field_ref, size);

return 1;
}

static intptr_t EXT_MapExtFieldPtr(intptr_t *args)
{
char *key = VM_ArgPtr(args[1]);
if (key)
{
if (!strcmp(key, "alpha"))
{
return offsetof(ext_entvars_t, alpha) | GetExtFieldCookie();
}
if (!strcmp(key, "colormod"))
{
return offsetof(ext_entvars_t, colourmod) | GetExtFieldCookie();
}
}

return 0;
}

/*
int trap_Map_Extension( const char* ext_name, int mapto)
return:
Expand All @@ -1960,12 +2075,30 @@ intptr_t PF2_FS_GetFileList(char *path, char *ext,
*/
intptr_t PF2_Map_Extension(char *name, int mapto)
{
if (mapto < _G__LASTAPI)
{
int i;

if ((mapto - G_EXTENSIONS_FIRST) >= ARRAY_LEN(ext_syscall_tbl))
{
return -2;
}

if (!name)
{
if (mapto < _G__LASTAPI)
{
return -2;
}
return -1;
}
for (i = 0; i < ARRAY_LEN(ext_syscalls); i++)
{
if (!strcmp(ext_syscalls[i].extname, name))
{
ext_syscall_tbl[mapto - G_EXTENSIONS_FIRST] = ext_syscalls[i].fun;
return mapto;
}
}

return -1;
}
/////////Bot Functions
Expand Down Expand Up @@ -2674,7 +2807,14 @@ intptr_t PR2_GameSystemCalls(intptr_t *args) {
PF2_VisibleTo(args[1], args[2], args[3], VMA(4));
return 0;
default:
SV_Error("Bad game system trap: %ld", (long int)args[0]);
if (args[0] >= _G__LASTAPI && ext_syscall_tbl[args[0] - G_EXTENSIONS_FIRST])
{
return ext_syscall_tbl[args[0] - G_EXTENSIONS_FIRST](args);
}
else
{
SV_Error("Bad game system trap: %ld", (long int)args[0]);
}
}
return 0;
}
Expand Down
11 changes: 11 additions & 0 deletions src/pr_cmds.c
Original file line number Diff line number Diff line change
Expand Up @@ -2228,6 +2228,17 @@ void PF_makestatic (void)
s->skinnum = ent->v->skin;
VectorCopy(ent->v->origin, s->origin);
VectorCopy(ent->v->angles, s->angles);
#ifdef FTE_PEXT_TRANS
s->trans = ent->xv.alpha >= 1.0f ? 0 : bound(0, (byte)(ent->xv.alpha * 254.0), 254);
#endif
#ifdef FTE_PEXT_COLOURMOD
if (ent->xv.colourmod[0] != 1.0f && ent->xv.colourmod[1] != 1.0f && ent->xv.colourmod[2] != 1.0f)
{
s->colourmod[0] = bound(0, ent->xv.colourmod[0] * (256.0f / 8.0f), 255);
s->colourmod[1] = bound(0, ent->xv.colourmod[1] * (256.0f / 8.0f), 255);
s->colourmod[2] = bound(0, ent->xv.colourmod[2] * (256.0f / 8.0f), 255);
}
#endif
++sv.static_entity_count;

// throw the entity away now
Expand Down
Loading

0 comments on commit c8c53f1

Please sign in to comment.