Add the fork+sleep builtins to the menuqc and csqc VMs too.
This commit is contained in:
parent
39e921624f
commit
0650610667
9 changed files with 160 additions and 143 deletions
|
@ -6834,9 +6834,9 @@ static struct {
|
||||||
{"registertempent", PF_NoCSQC, 208},//{"RegisterTempEnt", PF_RegisterTEnt, 0, 0, 0, 208},
|
{"registertempent", PF_NoCSQC, 208},//{"RegisterTempEnt", PF_RegisterTEnt, 0, 0, 0, 208},
|
||||||
{"customtempent", PF_NoCSQC, 209},//{"CustomTempEnt", PF_CustomTEnt, 0, 0, 0, 209},
|
{"customtempent", PF_NoCSQC, 209},//{"CustomTempEnt", PF_CustomTEnt, 0, 0, 0, 209},
|
||||||
//210
|
//210
|
||||||
{"fork", PF_Fixme, 210},//{"fork", PF_Fork, 0, 0, 0, 210},
|
{"fork", PF_Fork, 210},//{"fork", PF_Fork, 0, 0, 0, 210},
|
||||||
{"abort", PF_Abort, 211}, //#211 void() abort (FTE_MULTITHREADED)
|
{"abort", PF_Abort, 211}, //#211 void() abort (FTE_MULTITHREADED)
|
||||||
{"sleep", PF_Fixme, 212},//{"sleep", PF_Sleep, 0, 0, 0, 212},
|
{"sleep", PF_Sleep, 212},//{"sleep", PF_Sleep, 0, 0, 0, 212},
|
||||||
{"forceinfokey", PF_NoCSQC, 213},//{"forceinfokey", PF_ForceInfoKey, 0, 0, 0, 213},
|
{"forceinfokey", PF_NoCSQC, 213},//{"forceinfokey", PF_ForceInfoKey, 0, 0, 0, 213},
|
||||||
{"forceinfokeyblob", PF_NoCSQC, 0},//{"forceinfokey", PF_ForceInfoKey, 0, 0, 0, 213},
|
{"forceinfokeyblob", PF_NoCSQC, 0},//{"forceinfokey", PF_ForceInfoKey, 0, 0, 0, 213},
|
||||||
{"chat", PF_NoCSQC, 214},//{"chat", PF_chat, 0, 0, 0, 214},// #214 void(string filename, float starttag, entity edict) SV_Chat (FTE_NPCCHAT)
|
{"chat", PF_NoCSQC, 214},//{"chat", PF_chat, 0, 0, 0, 214},// #214 void(string filename, float starttag, entity edict) SV_Chat (FTE_NPCCHAT)
|
||||||
|
@ -8792,6 +8792,7 @@ qboolean CSQC_DrawView(void)
|
||||||
if (csqc_isdarkplaces && *csqc_world.g.physics_mode == 1)
|
if (csqc_isdarkplaces && *csqc_world.g.physics_mode == 1)
|
||||||
{
|
{
|
||||||
csqc_world.physicstime = cl.servertime;
|
csqc_world.physicstime = cl.servertime;
|
||||||
|
PR_RunThreads(&csqc_world);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -8822,6 +8823,7 @@ qboolean CSQC_DrawView(void)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
PR_RunThreads(&csqc_world);
|
||||||
World_Physics_Frame(&csqc_world);
|
World_Physics_Frame(&csqc_world);
|
||||||
csqc_world.physicstime += host_frametime;
|
csqc_world.physicstime += host_frametime;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2551,7 +2551,9 @@ static struct {
|
||||||
//gap
|
//gap
|
||||||
{"getmodelindex", PF_m_getmodelindex, 200},
|
{"getmodelindex", PF_m_getmodelindex, 200},
|
||||||
//gap
|
//gap
|
||||||
|
{"fork", PF_Fork, 210},
|
||||||
{"abort", PF_Abort, 211},
|
{"abort", PF_Abort, 211},
|
||||||
|
{"sleep", PF_Sleep, 212},
|
||||||
//gap
|
//gap
|
||||||
{"strstrofs", PF_strstrofs, 221},
|
{"strstrofs", PF_strstrofs, 221},
|
||||||
{"str2chr", PF_str2chr, 222},
|
{"str2chr", PF_str2chr, 222},
|
||||||
|
@ -3555,6 +3557,8 @@ void MP_Draw(void)
|
||||||
*menu_world.g.frametime = host_frametime;
|
*menu_world.g.frametime = host_frametime;
|
||||||
|
|
||||||
inmenuprogs++;
|
inmenuprogs++;
|
||||||
|
PR_RunThreads(&menu_world);
|
||||||
|
|
||||||
pr_globals = PR_globals(menu_world.progs, PR_CURRENT);
|
pr_globals = PR_globals(menu_world.progs, PR_CURRENT);
|
||||||
|
|
||||||
if (scr_drawloading||scr_disabled_for_loading)
|
if (scr_drawloading||scr_disabled_for_loading)
|
||||||
|
|
|
@ -2113,15 +2113,15 @@ void QCBUILTIN PF_memcpy (pubprogfuncs_t *prinst, struct globalvars_s *pr_global
|
||||||
int srcoffset = (prinst->callargc>3)?G_INT(OFS_PARM3):0;
|
int srcoffset = (prinst->callargc>3)?G_INT(OFS_PARM3):0;
|
||||||
int dstoffset = (prinst->callargc>4)?G_INT(OFS_PARM4):0;
|
int dstoffset = (prinst->callargc>4)?G_INT(OFS_PARM4):0;
|
||||||
if (size < 0)
|
if (size < 0)
|
||||||
PR_BIError(prinst, "PF_memcpy: invalid size\n");
|
PR_BIError(prinst, "PF_memcpy: invalid size %#x\n", size);
|
||||||
else if (size)
|
else if (size)
|
||||||
{
|
{
|
||||||
void *dst = PR_PointerToNative_Resize(prinst, qcdst, dstoffset, size);
|
void *dst = PR_PointerToNative_Resize(prinst, qcdst, dstoffset, size);
|
||||||
void *src = PR_PointerToNative_MoInvalidate(prinst, qcsrc, srcoffset, size);
|
void *src = PR_PointerToNative_MoInvalidate(prinst, qcsrc, srcoffset, size);
|
||||||
if (!dst)
|
if (!dst)
|
||||||
PR_BIError(prinst, "PF_memcpy: invalid dest\n");
|
PR_BIError(prinst, "PF_memcpy: invalid dest (%#x - %#x)\n", qcdst, qcdst+size);
|
||||||
else if (!src)
|
else if (!src)
|
||||||
PR_BIError(prinst, "PF_memcpy: invalid source\n");
|
PR_BIError(prinst, "PF_memcpy: invalid source (%#x - %#x)\n", qcsrc, qcsrc+size);
|
||||||
else
|
else
|
||||||
memmove(dst, src, size);
|
memmove(dst, src, size);
|
||||||
}
|
}
|
||||||
|
@ -5056,7 +5056,6 @@ void QCBUILTIN PF_strftime (pubprogfuncs_t *prinst, struct globalvars_s *pr_glob
|
||||||
{
|
{
|
||||||
const char *in = PF_VarString(prinst, 1, pr_globals);
|
const char *in = PF_VarString(prinst, 1, pr_globals);
|
||||||
char result[8192];
|
char result[8192];
|
||||||
char uresult[8192];
|
|
||||||
|
|
||||||
time_t ctime;
|
time_t ctime;
|
||||||
struct tm *tm;
|
struct tm *tm;
|
||||||
|
@ -5075,9 +5074,8 @@ void QCBUILTIN PF_strftime (pubprogfuncs_t *prinst, struct globalvars_s *pr_glob
|
||||||
in = "%Y-%m-%d";
|
in = "%Y-%m-%d";
|
||||||
|
|
||||||
strftime(result, sizeof(result), in, tm);
|
strftime(result, sizeof(result), in, tm);
|
||||||
unicode_strtoupper(result, uresult, sizeof(uresult), VMUTF8MARKUP);
|
|
||||||
|
|
||||||
RETURN_TSTRING(uresult);
|
RETURN_TSTRING(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
//String functions
|
//String functions
|
||||||
|
@ -6870,10 +6868,133 @@ void QCBUILTIN PF_rotatevectorsbymatrix (pubprogfuncs_t *prinst, struct globalva
|
||||||
////////////////////////////////////////////////////
|
////////////////////////////////////////////////////
|
||||||
//Progs internals
|
//Progs internals
|
||||||
|
|
||||||
|
qcstate_t *PR_CreateThread(pubprogfuncs_t *prinst, float retval, float resumetime, qboolean wait)
|
||||||
|
{
|
||||||
|
world_t *world = prinst->parms->user;
|
||||||
|
qcstate_t *state;
|
||||||
|
edict_t *ed;
|
||||||
|
|
||||||
|
state = prinst->parms->memalloc(sizeof(qcstate_t));
|
||||||
|
state->next = world->qcthreads;
|
||||||
|
world->qcthreads = state;
|
||||||
|
state->resumetime = resumetime;
|
||||||
|
|
||||||
|
if (prinst->edicttable_length)
|
||||||
|
{
|
||||||
|
ed = PROG_TO_EDICT(prinst, world->g.self?*world->g.self:0);
|
||||||
|
state->self = NUM_FOR_EDICT(prinst, ed);
|
||||||
|
state->selfid = (prinst==svprogfuncs&&ed->ereftype==ER_ENTITY)?ed->xv->uniquespawnid:0;
|
||||||
|
ed = PROG_TO_EDICT(prinst, world->g.self?*world->g.self:0);
|
||||||
|
state->other = NUM_FOR_EDICT(prinst, ed);
|
||||||
|
state->otherid = (prinst==svprogfuncs&&ed->ereftype==ER_ENTITY)?ed->xv->uniquespawnid:0;
|
||||||
|
}
|
||||||
|
else //allows us to call this during init().
|
||||||
|
state->self = state->other = state->selfid = state->otherid = 0;
|
||||||
|
state->thread = prinst->Fork(prinst);
|
||||||
|
state->waiting = wait;
|
||||||
|
state->returnval = retval;
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
void PR_RunThreads(world_t *world)
|
||||||
|
{
|
||||||
|
struct globalvars_s *pr_globals;
|
||||||
|
edict_t *ed;
|
||||||
|
|
||||||
|
qcstate_t *state = world->qcthreads, *next;
|
||||||
|
world->qcthreads = NULL;
|
||||||
|
while(state)
|
||||||
|
{
|
||||||
|
pubprogfuncs_t *prinst = world->progs;
|
||||||
|
next = state->next;
|
||||||
|
|
||||||
|
if (state->resumetime > (world->g.time?*world->g.time:0) || state->waiting)
|
||||||
|
{ //not time yet, reform original list.
|
||||||
|
state->next = world->qcthreads;
|
||||||
|
world->qcthreads = state;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{ //call it and forget it ever happened. The Sleep biltin will recreate if needed.
|
||||||
|
pr_globals = PR_globals(prinst, PR_CURRENT);
|
||||||
|
|
||||||
|
if (world->g.self)
|
||||||
|
{
|
||||||
|
//restore the thread's self variable, if applicable.
|
||||||
|
ed = PROG_TO_EDICT(prinst, state->self);
|
||||||
|
if ((prinst==svprogfuncs?ed->xv->uniquespawnid:0) != state->selfid)
|
||||||
|
ed = prinst->edicttable[0];
|
||||||
|
*world->g.self = EDICT_TO_PROG(prinst, ed);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (world->g.other)
|
||||||
|
{
|
||||||
|
//restore the thread's other variable, if applicable
|
||||||
|
ed = PROG_TO_EDICT(prinst, state->other);
|
||||||
|
if ((prinst==svprogfuncs?ed->xv->uniquespawnid:0) != state->otherid)
|
||||||
|
ed = prinst->edicttable[0];
|
||||||
|
*world->g.other = EDICT_TO_PROG(prinst, ed);
|
||||||
|
}
|
||||||
|
|
||||||
|
G_FLOAT(OFS_RETURN) = state->returnval; //return value of fork or sleep
|
||||||
|
|
||||||
|
prinst->RunThread(prinst, state->thread);
|
||||||
|
prinst->parms->memfree(state->thread);
|
||||||
|
prinst->parms->memfree(state);
|
||||||
|
}
|
||||||
|
|
||||||
|
state = next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void PR_ClearThreads(pubprogfuncs_t *prinst)
|
||||||
|
{
|
||||||
|
world_t *world;
|
||||||
|
qcstate_t *state, *next;
|
||||||
|
if (!prinst)
|
||||||
|
return; //shoo!
|
||||||
|
world = prinst->parms->user;
|
||||||
|
state = world->qcthreads;
|
||||||
|
world->qcthreads = NULL;
|
||||||
|
while(state)
|
||||||
|
{
|
||||||
|
next = state->next;
|
||||||
|
|
||||||
|
//free the memory.
|
||||||
|
prinst->parms->memfree(state->thread);
|
||||||
|
prinst->parms->memfree(state);
|
||||||
|
|
||||||
|
state = next;
|
||||||
|
}
|
||||||
|
}
|
||||||
void QCBUILTIN PF_Abort(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
|
void QCBUILTIN PF_Abort(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
|
||||||
{
|
{
|
||||||
prinst->AbortStack(prinst);
|
prinst->AbortStack(prinst);
|
||||||
}
|
}
|
||||||
|
void QCBUILTIN PF_Sleep(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
|
||||||
|
{
|
||||||
|
world_t *world = prinst->parms->user;
|
||||||
|
float sleeptime;
|
||||||
|
|
||||||
|
sleeptime = G_FLOAT(OFS_PARM0);
|
||||||
|
|
||||||
|
PR_CreateThread(prinst, 1, (world->g.time?*world->g.time:0) + sleeptime, false);
|
||||||
|
|
||||||
|
prinst->AbortStack(prinst);
|
||||||
|
}
|
||||||
|
void QCBUILTIN PF_Fork(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
|
||||||
|
{
|
||||||
|
world_t *world = prinst->parms->user;
|
||||||
|
float sleeptime;
|
||||||
|
|
||||||
|
if (svprogfuncs->callargc >= 1)
|
||||||
|
sleeptime = G_FLOAT(OFS_PARM0);
|
||||||
|
else
|
||||||
|
sleeptime = 0;
|
||||||
|
|
||||||
|
PR_CreateThread(prinst, 1, (world->g.time?*world->g.time:0) + sleeptime, false);
|
||||||
|
|
||||||
|
// PRSV_RunThreads();
|
||||||
|
|
||||||
|
G_FLOAT(OFS_RETURN) = 0;
|
||||||
|
}
|
||||||
|
|
||||||
//this func calls a function in another progs
|
//this func calls a function in another progs
|
||||||
//it works in the same way as the above func, except that it calls by reference to a function, as opposed to by it's name
|
//it works in the same way as the above func, except that it calls by reference to a function, as opposed to by it's name
|
||||||
|
@ -7739,6 +7860,7 @@ void QCBUILTIN PF_pushmove (pubprogfuncs_t *prinst, struct globalvars_s *pr_glob
|
||||||
|
|
||||||
void PR_Common_Shutdown(pubprogfuncs_t *progs, qboolean errored)
|
void PR_Common_Shutdown(pubprogfuncs_t *progs, qboolean errored)
|
||||||
{
|
{
|
||||||
|
PR_ClearThreads(progs);
|
||||||
#if defined(SKELETALOBJECTS) || defined(RAGDOLLS)
|
#if defined(SKELETALOBJECTS) || defined(RAGDOLLS)
|
||||||
skel_reset(progs->parms->user);
|
skel_reset(progs->parms->user);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -391,7 +391,12 @@ void QCBUILTIN PF_findchainfloat (pubprogfuncs_t *prinst, struct globalvars_s *p
|
||||||
void QCBUILTIN PF_findchainflags (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);
|
void QCBUILTIN PF_findchainflags (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);
|
||||||
void QCBUILTIN PF_bitshift(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);
|
void QCBUILTIN PF_bitshift(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);
|
||||||
|
|
||||||
|
struct qcstate_s *PR_CreateThread(pubprogfuncs_t *prinst, float retval, float resumetime, qboolean wait);
|
||||||
|
void PR_ClearThreads(pubprogfuncs_t *prinst);
|
||||||
|
void PR_RunThreads(world_t *world);
|
||||||
void QCBUILTIN PF_Abort(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);
|
void QCBUILTIN PF_Abort(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);
|
||||||
|
void QCBUILTIN PF_Fork(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);
|
||||||
|
void QCBUILTIN PF_Sleep(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);
|
||||||
void QCBUILTIN PF_externcall (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);
|
void QCBUILTIN PF_externcall (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);
|
||||||
void QCBUILTIN PF_externrefcall (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);
|
void QCBUILTIN PF_externrefcall (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);
|
||||||
void QCBUILTIN PF_externvalue (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);
|
void QCBUILTIN PF_externvalue (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);
|
||||||
|
@ -1273,6 +1278,19 @@ typedef struct csqcedict_s
|
||||||
int skinobject;
|
int skinobject;
|
||||||
} csqcedict_t;
|
} csqcedict_t;
|
||||||
|
|
||||||
|
typedef struct qcstate_s
|
||||||
|
{
|
||||||
|
float resumetime;
|
||||||
|
qboolean waiting;
|
||||||
|
struct qcthread_s *thread;
|
||||||
|
int self;
|
||||||
|
int selfid;
|
||||||
|
int other;
|
||||||
|
int otherid;
|
||||||
|
float returnval;
|
||||||
|
|
||||||
|
struct qcstate_s *next;
|
||||||
|
} qcstate_t;
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
};
|
};
|
||||||
|
|
|
@ -263,6 +263,7 @@ struct world_s
|
||||||
pvec_t *drawfont;
|
pvec_t *drawfont;
|
||||||
pvec_t *drawfontscale;
|
pvec_t *drawfontscale;
|
||||||
} g;
|
} g;
|
||||||
|
struct qcstate_s *qcthreads;
|
||||||
|
|
||||||
#ifdef USERBE
|
#ifdef USERBE
|
||||||
qboolean rbe_hasphysicsents;
|
qboolean rbe_hasphysicsents;
|
||||||
|
|
|
@ -2069,8 +2069,8 @@ void PDECL PR_ResumeThread (pubprogfuncs_t *ppf, struct qcthread_s *thread)
|
||||||
// thread->lstackused -= f->locals; //the current function is the odd one out.
|
// thread->lstackused -= f->locals; //the current function is the odd one out.
|
||||||
|
|
||||||
//add on the locals stack
|
//add on the locals stack
|
||||||
memcpy(prinst.localstack+prinst.localstack_used, thread->lstack, sizeof(int)*thread->lstackused);
|
// memcpy(prinst.localstack+prinst.localstack_used, thread->lstack, sizeof(int)*thread->lstackused);
|
||||||
prinst.localstack_used += thread->lstackused;
|
// prinst.localstack_used += thread->lstackused;
|
||||||
|
|
||||||
//bung the locals of the current function on the stack.
|
//bung the locals of the current function on the stack.
|
||||||
// for (i=0 ; i < f->locals ; i++)
|
// for (i=0 ; i < f->locals ; i++)
|
||||||
|
|
|
@ -116,7 +116,6 @@ int pr_teamfield;
|
||||||
static unsigned int h2infoplaque[2]; /*hexen2 stat*/
|
static unsigned int h2infoplaque[2]; /*hexen2 stat*/
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void PRSV_ClearThreads(void);
|
|
||||||
void PR_fclose_progs(pubprogfuncs_t*);
|
void PR_fclose_progs(pubprogfuncs_t*);
|
||||||
void PF_InitTempStrings(pubprogfuncs_t *prinst);
|
void PF_InitTempStrings(pubprogfuncs_t *prinst);
|
||||||
static int PDECL PR_SSQC_MapNamedBuiltin(pubprogfuncs_t *progfuncs, int headercrc, const char *builtinname);
|
static int PDECL PR_SSQC_MapNamedBuiltin(pubprogfuncs_t *progfuncs, int headercrc, const char *builtinname);
|
||||||
|
@ -124,21 +123,6 @@ static void QCBUILTIN PF_Fixme (pubprogfuncs_t *prinst, struct globalvars_s *pr_
|
||||||
|
|
||||||
void PR_DumpPlatform_f(void);
|
void PR_DumpPlatform_f(void);
|
||||||
|
|
||||||
typedef struct qcstate_s
|
|
||||||
{
|
|
||||||
float resumetime;
|
|
||||||
qboolean waiting;
|
|
||||||
struct qcthread_s *thread;
|
|
||||||
int self;
|
|
||||||
int selfid;
|
|
||||||
int other;
|
|
||||||
int otherid;
|
|
||||||
float returnval;
|
|
||||||
|
|
||||||
struct qcstate_s *next;
|
|
||||||
} qcstate_t;
|
|
||||||
static qcstate_t *qcthreads;
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
//for func finding and swapping.
|
//for func finding and swapping.
|
||||||
char *name;
|
char *name;
|
||||||
|
@ -246,33 +230,6 @@ static struct
|
||||||
void PR_RegisterFields(void);
|
void PR_RegisterFields(void);
|
||||||
void PR_ResetBuiltins(progstype_t type);
|
void PR_ResetBuiltins(progstype_t type);
|
||||||
|
|
||||||
static qcstate_t *PR_CreateThread(pubprogfuncs_t *prinst, float retval, float resumetime, qboolean wait)
|
|
||||||
{
|
|
||||||
qcstate_t *state;
|
|
||||||
edict_t *ed;
|
|
||||||
|
|
||||||
state = prinst->parms->memalloc(sizeof(qcstate_t));
|
|
||||||
state->next = qcthreads;
|
|
||||||
qcthreads = state;
|
|
||||||
state->resumetime = resumetime;
|
|
||||||
|
|
||||||
if (prinst->edicttable_length)
|
|
||||||
{
|
|
||||||
ed = PROG_TO_EDICT(prinst, pr_global_struct->self);
|
|
||||||
state->self = NUM_FOR_EDICT(prinst, ed);
|
|
||||||
state->selfid = (ed->ereftype==ER_ENTITY)?ed->xv->uniquespawnid:0;
|
|
||||||
ed = PROG_TO_EDICT(prinst, pr_global_struct->other);
|
|
||||||
state->other = NUM_FOR_EDICT(prinst, ed);
|
|
||||||
state->otherid = (ed->ereftype==ER_ENTITY)?ed->xv->uniquespawnid:0;
|
|
||||||
}
|
|
||||||
else //allows us to call this during init().
|
|
||||||
state->self = state->other = state->selfid = state->otherid = 0;
|
|
||||||
state->thread = prinst->Fork(prinst);
|
|
||||||
state->waiting = wait;
|
|
||||||
state->returnval = retval;
|
|
||||||
return state;
|
|
||||||
}
|
|
||||||
|
|
||||||
void PDECL ED_Spawned (struct edict_s *ent, int loading)
|
void PDECL ED_Spawned (struct edict_s *ent, int loading)
|
||||||
{
|
{
|
||||||
#ifdef VM_Q1
|
#ifdef VM_Q1
|
||||||
|
@ -803,7 +760,7 @@ void Q_SetProgsParms(qboolean forcompiler)
|
||||||
sv.world.Event_ContentsTransition = SVPR_Event_ContentsTransition;
|
sv.world.Event_ContentsTransition = SVPR_Event_ContentsTransition;
|
||||||
sv.world.Get_CModel = SVPR_GetCModel;
|
sv.world.Get_CModel = SVPR_GetCModel;
|
||||||
sv.world.Get_FrameState = SVPR_Get_FrameState;
|
sv.world.Get_FrameState = SVPR_Get_FrameState;
|
||||||
PRSV_ClearThreads();
|
PR_ClearThreads(svprogfuncs);
|
||||||
PR_fclose_progs(svprogfuncs);
|
PR_fclose_progs(svprogfuncs);
|
||||||
|
|
||||||
// svs.numprogs = 0;
|
// svs.numprogs = 0;
|
||||||
|
@ -814,7 +771,7 @@ void PR_Deinit(void)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
PRSV_ClearThreads();
|
PR_ClearThreads(svprogfuncs);
|
||||||
#ifdef VM_Q1
|
#ifdef VM_Q1
|
||||||
Q1QVM_Shutdown(true);
|
Q1QVM_Shutdown(true);
|
||||||
#endif
|
#endif
|
||||||
|
@ -9238,91 +9195,6 @@ void QCBUILTIN PF_sv_pointparticles(pubprogfuncs_t *prinst, struct globalvars_s
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void PRSV_RunThreads(void)
|
|
||||||
{
|
|
||||||
struct globalvars_s *pr_globals;
|
|
||||||
edict_t *ed;
|
|
||||||
|
|
||||||
qcstate_t *state = qcthreads, *next;
|
|
||||||
qcthreads = NULL;
|
|
||||||
while(state)
|
|
||||||
{
|
|
||||||
next = state->next;
|
|
||||||
|
|
||||||
if (state->resumetime > sv.time || state->waiting)
|
|
||||||
{ //not time yet, reform original list.
|
|
||||||
state->next = qcthreads;
|
|
||||||
qcthreads = state;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{ //call it and forget it ever happened. The Sleep biltin will recreate if needed.
|
|
||||||
pr_globals = PR_globals(svprogfuncs, PR_CURRENT);
|
|
||||||
|
|
||||||
//restore the thread's self variable, if applicable.
|
|
||||||
ed = PROG_TO_EDICT(svprogfuncs, state->self);
|
|
||||||
if (ed->xv->uniquespawnid != state->selfid)
|
|
||||||
ed = svprogfuncs->edicttable[0];
|
|
||||||
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, ed);
|
|
||||||
|
|
||||||
//restore the thread's other variable, if applicable
|
|
||||||
ed = PROG_TO_EDICT(svprogfuncs, state->other);
|
|
||||||
if (ed->xv->uniquespawnid != state->otherid)
|
|
||||||
ed = svprogfuncs->edicttable[0];
|
|
||||||
pr_global_struct->other = EDICT_TO_PROG(svprogfuncs, ed);
|
|
||||||
|
|
||||||
G_FLOAT(OFS_RETURN) = state->returnval; //return value of fork or sleep
|
|
||||||
|
|
||||||
svprogfuncs->RunThread(svprogfuncs, state->thread);
|
|
||||||
svprogfuncs->parms->memfree(state->thread);
|
|
||||||
svprogfuncs->parms->memfree(state);
|
|
||||||
}
|
|
||||||
|
|
||||||
state = next;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void PRSV_ClearThreads(void)
|
|
||||||
{
|
|
||||||
qcstate_t *state = qcthreads, *next;
|
|
||||||
qcthreads = NULL;
|
|
||||||
while(state)
|
|
||||||
{
|
|
||||||
next = state->next;
|
|
||||||
|
|
||||||
svprogfuncs->parms->memfree(state->thread);
|
|
||||||
svprogfuncs->parms->memfree(state);
|
|
||||||
|
|
||||||
state = next;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void QCBUILTIN PF_Sleep(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
|
|
||||||
{
|
|
||||||
float sleeptime;
|
|
||||||
|
|
||||||
sleeptime = G_FLOAT(OFS_PARM0);
|
|
||||||
|
|
||||||
PR_CreateThread(prinst, 1, sv.time + sleeptime, false);
|
|
||||||
|
|
||||||
prinst->AbortStack(prinst);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void QCBUILTIN PF_Fork(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
|
|
||||||
{
|
|
||||||
float sleeptime;
|
|
||||||
|
|
||||||
if (svprogfuncs->callargc >= 1)
|
|
||||||
sleeptime = G_FLOAT(OFS_PARM0);
|
|
||||||
else
|
|
||||||
sleeptime = 0;
|
|
||||||
|
|
||||||
PR_CreateThread(prinst, 1, sv.time + sleeptime, false);
|
|
||||||
|
|
||||||
// PRSV_RunThreads();
|
|
||||||
|
|
||||||
G_FLOAT(OFS_RETURN) = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
//DP_TE_STANDARDEFFECTBUILTINS
|
//DP_TE_STANDARDEFFECTBUILTINS
|
||||||
//void(vector org) te_gunshot = #418;
|
//void(vector org) te_gunshot = #418;
|
||||||
static void QCBUILTIN PF_te_gunshot(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
|
static void QCBUILTIN PF_te_gunshot(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
|
||||||
|
|
|
@ -48,8 +48,6 @@ qboolean PR_ParseClusterEvent(const char *dest, const char *source, const char *
|
||||||
qboolean PR_UserCmd(const char *cmd);
|
qboolean PR_UserCmd(const char *cmd);
|
||||||
qboolean PR_ConsoleCmd(const char *cmd);
|
qboolean PR_ConsoleCmd(const char *cmd);
|
||||||
|
|
||||||
void PRSV_RunThreads(void);
|
|
||||||
|
|
||||||
|
|
||||||
#define PR_MAINPROGS 0 //this is a constant that should really be phased out. But seeing as QCLIB requires some sort of master progs due to extern funcs...
|
#define PR_MAINPROGS 0 //this is a constant that should really be phased out. But seeing as QCLIB requires some sort of master progs due to extern funcs...
|
||||||
//maybe go through looking for extern funcs, and remember which were not allocated. It would then be a first come gets priority. Not too bad I supppose.
|
//maybe go through looking for extern funcs, and remember which were not allocated. It would then be a first come gets priority. Not too bad I supppose.
|
||||||
|
|
|
@ -2726,7 +2726,7 @@ qboolean SV_Physics (void)
|
||||||
|
|
||||||
SV_ProgStartFrame ();
|
SV_ProgStartFrame ();
|
||||||
|
|
||||||
PRSV_RunThreads();
|
PR_RunThreads(&sv.world);
|
||||||
|
|
||||||
#ifdef USERBE
|
#ifdef USERBE
|
||||||
if (sv.world.rbe)
|
if (sv.world.rbe)
|
||||||
|
|
Loading…
Reference in a new issue