fix deltalisten bug found by shpuld, and possible entity number overflow bug.
also make csqc_ent_remove even more optional. git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4854 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
parent
afe18bec95
commit
10e91c5771
1 changed files with 33 additions and 39 deletions
|
@ -4146,7 +4146,7 @@ typedef struct
|
||||||
unsigned int maxents; //buffer size
|
unsigned int maxents; //buffer size
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
unsigned int n; //don't rely on the ent->v->entnum
|
unsigned int n; //don't rely on the ent->v->entnum, as csqc can corrupt that
|
||||||
csqcedict_t *e; //the csqc ent
|
csqcedict_t *e; //the csqc ent
|
||||||
} *e;
|
} *e;
|
||||||
} csqcdelta_pack_t;
|
} csqcdelta_pack_t;
|
||||||
|
@ -4165,8 +4165,7 @@ qboolean CSQC_DeltaPlayer(int playernum, player_state_t *state)
|
||||||
{
|
{
|
||||||
if (csqcdelta_playerents[playernum])
|
if (csqcdelta_playerents[playernum])
|
||||||
{
|
{
|
||||||
*csqcg.self = EDICT_TO_PROG(csqcprogs, (void*)csqcdelta_playerents[playernum]);
|
CSQC_EntRemove(csqcdelta_playerents[playernum]);
|
||||||
PR_ExecuteProgram(csqcprogs, csqcg.ent_remove);
|
|
||||||
csqcdelta_playerents[playernum] = NULL;
|
csqcdelta_playerents[playernum] = NULL;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@ -4198,8 +4197,7 @@ qboolean CSQC_DeltaPlayer(int playernum, player_state_t *state)
|
||||||
}
|
}
|
||||||
else if (csqcdelta_playerents[playernum])
|
else if (csqcdelta_playerents[playernum])
|
||||||
{
|
{
|
||||||
*csqcg.self = EDICT_TO_PROG(csqcprogs, (void*)csqcdelta_playerents[playernum]);
|
CSQC_EntRemove(csqcdelta_playerents[playernum]);
|
||||||
PR_ExecuteProgram(csqcprogs, csqcg.ent_remove);
|
|
||||||
csqcdelta_playerents[playernum] = NULL;
|
csqcdelta_playerents[playernum] = NULL;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@ -4219,6 +4217,20 @@ void CSQC_DeltaStart(float time)
|
||||||
csqcdelta_pack_new.readpos = 0;
|
csqcdelta_pack_new.readpos = 0;
|
||||||
csqcdelta_pack_old.readpos = 0;
|
csqcdelta_pack_old.readpos = 0;
|
||||||
}
|
}
|
||||||
|
static CSQC_EntRemove(csqcedict_t *ed)
|
||||||
|
{
|
||||||
|
if (csqcg.ent_remove)
|
||||||
|
{
|
||||||
|
*csqcg.self = EDICT_TO_PROG(csqcprogs, ed);
|
||||||
|
PR_ExecuteProgram(csqcprogs, csqcg.ent_remove);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pe->DelinkTrailstate(&ed->trailstate);
|
||||||
|
World_UnlinkEdict((wedict_t*)ed);
|
||||||
|
ED_Free (csqcprogs, (void*)ed);
|
||||||
|
}
|
||||||
|
}
|
||||||
qboolean CSQC_DeltaUpdate(entity_state_t *src)
|
qboolean CSQC_DeltaUpdate(entity_state_t *src)
|
||||||
{
|
{
|
||||||
//FTE ensures that this function is called with increasing ent numbers each time
|
//FTE ensures that this function is called with increasing ent numbers each time
|
||||||
|
@ -4229,47 +4241,31 @@ qboolean CSQC_DeltaUpdate(entity_state_t *src)
|
||||||
void *pr_globals;
|
void *pr_globals;
|
||||||
csqcedict_t *ent, *oldent;
|
csqcedict_t *ent, *oldent;
|
||||||
|
|
||||||
|
while (csqcdelta_pack_old.readpos < csqcdelta_pack_old.numents && csqcdelta_pack_old.e[csqcdelta_pack_old.readpos].n < src->number)
|
||||||
|
|
||||||
|
|
||||||
if (csqcdelta_pack_old.readpos == csqcdelta_pack_old.numents)
|
|
||||||
{ //reached the end of the old frame's ents
|
|
||||||
oldent = NULL;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
while (csqcdelta_pack_old.readpos < csqcdelta_pack_old.numents && csqcdelta_pack_old.e[csqcdelta_pack_old.readpos].n < src->number)
|
//this entity is stale, remove it.
|
||||||
{
|
CSQC_EntRemove(csqcdelta_pack_old.e[csqcdelta_pack_old.readpos].e);
|
||||||
//this entity is stale, remove it.
|
csqcdelta_pack_old.readpos++;
|
||||||
oldent = csqcdelta_pack_old.e[csqcdelta_pack_old.readpos].e;
|
}
|
||||||
*csqcg.self = EDICT_TO_PROG(csqcprogs, (void*)oldent);
|
|
||||||
PR_ExecuteProgram(csqcprogs, csqcg.ent_remove);
|
|
||||||
csqcdelta_pack_old.readpos++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (src->number < csqcdelta_pack_old.e[csqcdelta_pack_old.readpos].n)
|
if (csqcdelta_pack_old.readpos >= csqcdelta_pack_old.numents)
|
||||||
oldent = NULL;
|
oldent = NULL; //reached the end of the old frame's ents (so we must be new)
|
||||||
else
|
else if (src->number < csqcdelta_pack_old.e[csqcdelta_pack_old.readpos].n)
|
||||||
{
|
oldent = NULL; //there's a gap, this one must be new.
|
||||||
oldent = csqcdelta_pack_old.e[csqcdelta_pack_old.readpos].e;
|
else
|
||||||
csqcdelta_pack_old.readpos++;
|
{ //already known.
|
||||||
}
|
oldent = csqcdelta_pack_old.e[csqcdelta_pack_old.readpos].e;
|
||||||
|
csqcdelta_pack_old.readpos++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (src->number < maxcsqcentities && csqcent[src->number])
|
if (src->number < maxcsqcentities && csqcent[src->number])
|
||||||
{
|
{
|
||||||
//in the csqc list (don't permit in the delta list too)
|
//in the csqc list (don't permit in the delta list too)
|
||||||
if (oldent)
|
if (oldent)
|
||||||
{
|
CSQC_EntRemove(oldent);
|
||||||
*csqcg.self = EDICT_TO_PROG(csqcprogs, (void*)oldent);
|
|
||||||
PR_ExecuteProgram(csqcprogs, csqcg.ent_remove);
|
|
||||||
}
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (oldent)
|
if (oldent)
|
||||||
ent = oldent;
|
ent = oldent;
|
||||||
else
|
else
|
||||||
|
@ -4306,8 +4302,7 @@ void CSQC_DeltaEnd(void)
|
||||||
//remove any unreferenced ents stuck on the end
|
//remove any unreferenced ents stuck on the end
|
||||||
while (csqcdelta_pack_old.readpos < csqcdelta_pack_old.numents)
|
while (csqcdelta_pack_old.readpos < csqcdelta_pack_old.numents)
|
||||||
{
|
{
|
||||||
*csqcg.self = EDICT_TO_PROG(csqcprogs, (void*)csqcdelta_pack_old.e[csqcdelta_pack_old.readpos].e);
|
CSQC_EntRemove(csqcdelta_pack_old.e[csqcdelta_pack_old.readpos].e);
|
||||||
PR_ExecuteProgram(csqcprogs, csqcg.ent_remove);
|
|
||||||
csqcdelta_pack_old.readpos++;
|
csqcdelta_pack_old.readpos++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7019,8 +7014,7 @@ void CSQC_ParseEntities(void)
|
||||||
if (!ent) //hrm.
|
if (!ent) //hrm.
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
*csqcg.self = EDICT_TO_PROG(csqcprogs, (void*)ent);
|
CSQC_EntRemove(ent);
|
||||||
PR_ExecuteProgram(csqcprogs, csqcg.ent_remove);
|
|
||||||
//the csqc is expected to call the remove builtin.
|
//the csqc is expected to call the remove builtin.
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
Loading…
Reference in a new issue