Skip to content

Commit d2095a1

Browse files
committed
PROTOCOL: Support CSQC.
Forward port of Reki's initial implementation.
1 parent ce71730 commit d2095a1

File tree

6 files changed

+553
-1
lines changed

6 files changed

+553
-1
lines changed

src/pr2_cmds.c

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,9 @@
3939
const char *pr2_ent_data_ptr;
4040
vm_t *sv_vm = NULL;
4141
extern gameData_t gamedata;
42+
#ifdef FTE_PEXT_CSQC
43+
extern sizebuf_t *csqcmsgbuffer;
44+
#endif
4245

4346
static int PASSFLOAT(float f)
4447
{
@@ -59,6 +62,9 @@ static float GETFLOAT(int i)
5962
typedef intptr_t (*ext_syscall_t)(intptr_t *arg);
6063
static intptr_t EXT_GetSoundIndex(intptr_t *args);
6164
static intptr_t EXT_GetModelIndex(intptr_t *args);
65+
#ifdef FTE_PEXT_CSQC
66+
static intptr_t EXT_SetSendNeeded(intptr_t *args);
67+
#endif
6268
static intptr_t EXT_MapExtFieldPtr(intptr_t *args);
6369
static intptr_t EXT_SetExtFieldPtr(intptr_t *args);
6470
static intptr_t EXT_GetExtFieldPtr(intptr_t *args);
@@ -73,6 +79,9 @@ struct
7379
{"GetExtFieldPtr", EXT_GetExtFieldPtr},
7480
{"getsoundindex", EXT_GetSoundIndex},
7581
{"getmodelindex", EXT_GetModelIndex},
82+
#ifdef FTE_PEXT_CSQC
83+
{"setsendneeded", EXT_SetSendNeeded},
84+
#endif
7685
};
7786
ext_syscall_t ext_syscall_tbl[256];
7887

@@ -1177,6 +1186,9 @@ MESSAGE WRITING
11771186
#define MSG_ALL 2 // reliable to all
11781187
#define MSG_INIT 3 // write to the init string
11791188
#define MSG_MULTICAST 4 // for multicast()
1189+
#ifdef FTE_PEXT_CSQC
1190+
#define MSG_CSQC 5 // for csqc
1191+
#endif
11801192

11811193

11821194
sizebuf_t *WriteDest2(int dest)
@@ -1213,6 +1225,9 @@ sizebuf_t *WriteDest2(int dest)
12131225
case MSG_MULTICAST:
12141226
return &sv.multicast;
12151227

1228+
case MSG_CSQC:
1229+
return csqcmsgbuffer;
1230+
12161231
default:
12171232
PR2_RunError ("WriteDest: bad destination");
12181233
break;
@@ -1990,6 +2005,36 @@ intptr_t PF2_FS_GetFileList(char *path, char *ext,
19902005
return numfiles;
19912006
}
19922007

2008+
#ifdef FTE_PEXT_CSQC
2009+
intptr_t EXT_SetSendNeeded(intptr_t *args)
2010+
{
2011+
unsigned int subject = args[1];
2012+
unsigned int fl = args[2];
2013+
unsigned int to = args[3];
2014+
2015+
if (!to)
2016+
{ //broadcast
2017+
for (to = 0; to < MAX_CLIENTS; to++)
2018+
{
2019+
svs.clients[to].csqcentitysendflags[subject] |= fl;
2020+
}
2021+
}
2022+
else
2023+
{
2024+
to--;
2025+
if (to >= MAX_CLIENTS)
2026+
{
2027+
; //some kind of error.
2028+
}
2029+
else
2030+
{
2031+
svs.clients[to].csqcentitysendflags[subject] |= fl;
2032+
}
2033+
}
2034+
return 0;
2035+
}
2036+
#endif
2037+
19932038
static intptr_t EXT_GetModelIndex(intptr_t *args)
19942039
{
19952040
int model_num;
@@ -2105,6 +2150,14 @@ static intptr_t EXT_MapExtFieldPtr(intptr_t *args)
21052150
{
21062151
return offsetof(ext_entvars_t, colourmod) | GetExtFieldCookie();
21072152
}
2153+
if (!strcmp(key, "SendEntity"))
2154+
{
2155+
return offsetof(ext_entvars_t, sendentity) | GetExtFieldCookie();
2156+
}
2157+
if (!strcmp(key, "pvsflags"))
2158+
{
2159+
return offsetof(ext_entvars_t, pvsflags) | GetExtFieldCookie();
2160+
}
21082161
}
21092162

21102163
return 0;

src/progs.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,10 @@ typedef struct
6767
{
6868
float alpha; // 0 = opaque, 1 = opaque, 0 < x < 1 translucent
6969
float colourmod[3]; // r,g,b [0.0 .. 1.0], > 1 overbright
70+
#ifdef FTE_PEXT_CSQC
71+
int sendentity; // Trigger GAME_CSQCSEND indirection
72+
float pvsflags; // CSQC pvsflags
73+
#endif
7074
} ext_entvars_t;
7175

7276
typedef struct edict_s

src/server.h

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,7 @@ typedef struct
130130
int static_entity_count;
131131
#ifdef FTE_PEXT_CSQC
132132
unsigned int csqcchecksum;
133+
unsigned short csqcsendstates[MAX_EDICTS];
133134
#endif
134135
} server_t;
135136

@@ -187,6 +188,24 @@ typedef struct
187188
#define MAX_WEAPONSWITCH_OPTIONS 10
188189
#endif
189190

191+
#ifdef FTE_PEXT_CSQC
192+
// code adapted from Darkplaces
193+
#define SCOPE_WANTREMOVE 1 // Set if a remove has been scheduled.
194+
#define SCOPE_WANTUPDATE 2 // Set if an update has been scheduled.
195+
#define SCOPE_WANTSEND (SCOPE_WANTREMOVE | SCOPE_WANTUPDATE)
196+
#define SCOPE_EXISTED_ONCE 4 // Set if the entity once existed. All these get resent on a full loss.
197+
#define SCOPE_ASSUMED_EXISTING 8 // Set if the entity is currently assumed existing and therefore needs removes.
198+
199+
#define NUM_CSQCENTITIES_PER_FRAME 256
200+
typedef struct csqcentityframedb_s
201+
{
202+
int framenum;
203+
int num;
204+
unsigned short entno[NUM_CSQCENTITIES_PER_FRAME];
205+
int sendflags[NUM_CSQCENTITIES_PER_FRAME];
206+
} csqcentityframedb_t;
207+
#endif
208+
190209
typedef struct client_s
191210
{
192211
sv_client_state_t state;
@@ -350,6 +369,16 @@ typedef struct client_s
350369

351370
#ifdef FTE_PEXT_CSQC
352371
qbool csqcactive;
372+
int csqc_framenum;
373+
int csqc_latestverified;
374+
int csqcnumedicts;
375+
unsigned char csqcentityscope[MAX_EDICTS];
376+
unsigned int csqcentitysendflags[MAX_EDICTS];
377+
378+
#define NUM_CSQCENTITYDB_FRAMES UPDATE_MASK//256
379+
csqcentityframedb_t csqcentityframehistory[NUM_CSQCENTITYDB_FRAMES];
380+
int csqcentityframehistory_next;
381+
int csqcentityframe_lastreset;
353382
#endif
354383

355384
//===== NETWORK ============
@@ -922,6 +951,10 @@ void SV_KickClient(client_t* client, const char* reason);
922951
//
923952
void SV_WriteEntitiesToClient (client_t *client, sizebuf_t *msg, qbool recorder);
924953
void SV_SetVisibleEntitiesForBot (client_t* client);
954+
#ifdef FTE_PEXT_CSQC
955+
int SV_EmitCSQCUpdate(client_t *client, sizebuf_t *msg, int maxsize, int entlist_size, const unsigned short *entlist);
956+
void EntityFrameCSQC_LostFrame(client_t *client, int framenum);
957+
#endif
925958

926959
//
927960
// sv_nchan.c

0 commit comments

Comments
 (0)