bigfoot: Works for me(TM)

final 64bit qcvm portability issues fixed (I hope).
new qc extension: DP_QC_UNLIMITEDTEMPSTRINGS (assuming pr_tempstringcount = 0)
fixed a couple of issues with msg_entity being random.

git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@2475 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
Spoike 2007-03-11 16:51:45 +00:00
parent 3f81d677ff
commit 4a823c3601
15 changed files with 462 additions and 214 deletions

View File

@ -1176,9 +1176,7 @@ static void PF_cs_getstati(progfuncs_t *prinst, struct globalvars_s *pr_globals)
static void PF_cs_getstats(progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
int stnum = G_FLOAT(OFS_PARM0);
char *out;
out = PF_TempStr(prinst);
char out[8];
//the network protocol byteswaps
@ -1188,7 +1186,7 @@ static void PF_cs_getstats(progfuncs_t *prinst, struct globalvars_s *pr_globals)
((unsigned int*)out)[3] = LittleLong(cl.stats[0][stnum+3]);
((unsigned int*)out)[4] = 0; //make sure it's null terminated
RETURN_SSTRING(out);
RETURN_TSTRING(out);
}
static void PF_cs_SetOrigin(progfuncs_t *prinst, struct globalvars_s *pr_globals)
@ -1555,10 +1553,9 @@ static void PF_ReadFloat(progfuncs_t *prinst, struct globalvars_s *pr_globals)
static void PF_ReadString(progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
char *str = PF_TempStr(prinst);
char *read = MSG_ReadString();
Q_strncpyz(str, read, MAXTEMPBUFFERLEN);
RETURN_TSTRING(read);
}
static void PF_ReadAngle(progfuncs_t *prinst, struct globalvars_s *pr_globals)
@ -1854,7 +1851,7 @@ static void PF_cs_serverkey (progfuncs_t *prinst, struct globalvars_s *pr_global
}
if (*ret)
RETURN_SSTRING(ret);
RETURN_TSTRING(ret);
else
G_INT(OFS_RETURN) = 0;
}
@ -1862,6 +1859,7 @@ static void PF_cs_serverkey (progfuncs_t *prinst, struct globalvars_s *pr_global
//string(float pnum, string keyname)
static void PF_cs_getplayerkey (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
char buffer[64];
char *ret;
int pnum = G_FLOAT(OFS_PARM0);
char *keyname = PR_GetStringOfs(prinst, OFS_PARM1);
@ -1886,24 +1884,24 @@ static void PF_cs_getplayerkey (progfuncs_t *prinst, struct globalvars_s *pr_glo
{
CheckSendPings();
ret = PF_TempStr(prinst);
ret = buffer;
sprintf(ret, "%i", cl.players[pnum].ping);
}
else if (!strcmp(keyname, "frags"))
{
ret = PF_TempStr(prinst);
ret = buffer;
sprintf(ret, "%i", cl.players[pnum].frags);
}
else if (!strcmp(keyname, "pl")) //packet loss
{
CheckSendPings();
ret = PF_TempStr(prinst);
ret = buffer;
sprintf(ret, "%i", cl.players[pnum].pl);
}
else if (!strcmp(keyname, "entertime")) //packet loss
{
ret = PF_TempStr(prinst);
ret = buffer;
sprintf(ret, "%i", (int)cl.players[pnum].entertime);
}
else
@ -1911,7 +1909,7 @@ static void PF_cs_getplayerkey (progfuncs_t *prinst, struct globalvars_s *pr_glo
ret = Info_ValueForKey(cl.players[pnum].userinfo, keyname);
}
if (*ret)
RETURN_SSTRING(ret);
RETURN_TSTRING(ret);
else
G_INT(OFS_RETURN) = 0;
}
@ -3770,15 +3768,11 @@ qboolean CSQC_MouseMove(float xdelta, float ydelta)
qboolean CSQC_ConsoleCommand(char *cmd)
{
void *pr_globals;
char *str;
if (!csqcprogs || !csqcg.console_command)
return false;
str = PF_TempStr(csqcprogs);
Q_strncpyz(str, cmd, MAXTEMPBUFFERLEN);
pr_globals = PR_globals(csqcprogs, PR_CURRENT);
(((string_t *)pr_globals)[OFS_PARM0] = PR_SetString(csqcprogs, str));
(((string_t *)pr_globals)[OFS_PARM0] = PR_TempString(csqcprogs, cmd));
PR_ExecuteProgram (csqcprogs, csqcg.console_command);
return G_FLOAT(OFS_RETURN);
@ -3787,15 +3781,11 @@ qboolean CSQC_ConsoleCommand(char *cmd)
qboolean CSQC_StuffCmd(char *cmd)
{
void *pr_globals;
char *str;
if (!csqcprogs || !csqcg.parse_stuffcmd)
return false;
str = PF_TempStr(csqcprogs);
Q_strncpyz(str, cmd, MAXTEMPBUFFERLEN);
pr_globals = PR_globals(csqcprogs, PR_CURRENT);
(((string_t *)pr_globals)[OFS_PARM0] = PR_SetString(csqcprogs, str));
(((string_t *)pr_globals)[OFS_PARM0] = PR_TempString(csqcprogs, cmd));
PR_ExecuteProgram (csqcprogs, csqcg.parse_stuffcmd);
return true;
@ -3803,15 +3793,11 @@ qboolean CSQC_StuffCmd(char *cmd)
qboolean CSQC_CenterPrint(char *cmd)
{
void *pr_globals;
char *str;
if (!csqcprogs || !csqcg.parse_centerprint)
return false;
str = PF_TempStr(csqcprogs);
Q_strncpyz(str, cmd, MAXTEMPBUFFERLEN);
pr_globals = PR_globals(csqcprogs, PR_CURRENT);
(((string_t *)pr_globals)[OFS_PARM0] = PR_SetString(csqcprogs, str));
(((string_t *)pr_globals)[OFS_PARM0] = PR_TempString(csqcprogs, cmd));
PR_ExecuteProgram (csqcprogs, csqcg.parse_centerprint);
return G_FLOAT(OFS_RETURN);
@ -3823,7 +3809,6 @@ qboolean CSQC_CenterPrint(char *cmd)
int CSQC_StartSound(int entnum, int channel, char *soundname, vec3_t pos, float vol, float attenuation)
{
void *pr_globals;
char *str;
csqcedict_t *ent;
if (!csqcprogs || !csqcg.serversound)
@ -3840,12 +3825,9 @@ int CSQC_StartSound(int entnum, int channel, char *soundname, vec3_t pos, float
pr_globals = PR_globals(csqcprogs, PR_CURRENT);
str = PF_TempStr(csqcprogs);
Q_strncpyz(str, soundname, MAXTEMPBUFFERLEN);
*csqcg.self = EDICT_TO_PROG(csqcprogs, (void*)ent);
G_FLOAT(OFS_PARM0) = channel;
G_INT(OFS_PARM1) = PR_SetString(csqcprogs, str);
G_INT(OFS_PARM1) = PR_TempString(csqcprogs, soundname);
VectorCopy(pos, G_VECTOR(OFS_PARM2));
G_FLOAT(OFS_PARM3) = vol;
G_FLOAT(OFS_PARM4) = attenuation;
@ -3960,7 +3942,7 @@ void CSQC_ParseEntities(void)
#ifndef CLIENTONLY
if (sv.state)
{
Con_Printf("Server classname: \"%s\"\n", svprogfuncs->stringtable+EDICT_NUM(svprogfuncs, entnum)->v->classname);
Con_Printf("Server classname: \"%s\"\n", PR_GetString(svprogfuncs, EDICT_NUM(svprogfuncs, entnum)->v->classname));
}
#endif
}

View File

@ -633,22 +633,16 @@ int MP_TranslateDPtoFTECodes(int code);
void PF_cl_keynumtostring (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
int code = G_FLOAT(OFS_PARM0);
char *keyname = PF_TempStr(prinst);
code = MP_TranslateDPtoFTECodes (code);
strcpy(keyname, Key_KeynumToString(code));
RETURN_SSTRING(keyname);
RETURN_TSTRING(Key_KeynumToString(code));
}
void PF_cl_getkeybind (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
char *binding = Key_GetBinding(G_FLOAT(OFS_PARM0));
char *result = PF_TempStr(prinst);
if (!binding)
binding = "";
Q_strncpyz(result, binding, MAXTEMPBUFFERLEN);
RETURN_SSTRING(result);
RETURN_TSTRING(binding);
}
int MP_TranslateDPtoFTECodes(int code);
@ -657,16 +651,16 @@ void PF_cl_findkeysforcommand (progfuncs_t *prinst, struct globalvars_s *pr_glob
{
char *cmdname = PR_GetStringOfs(prinst, OFS_PARM0);
int keynums[2];
char *keyname = PF_TempStr(prinst);
char keyname[512];
M_FindKeysForCommand(cmdname, keynums);
keyname[0] = '\0';
Q_strncatz (keyname, va(" \'%i\'", MP_TranslateFTEtoDPCodes(keynums[0])), MAXTEMPBUFFERLEN);
Q_strncatz (keyname, va(" \'%i\'", MP_TranslateFTEtoDPCodes(keynums[1])), MAXTEMPBUFFERLEN);
Q_strncatz (keyname, va(" \'%i\'", MP_TranslateFTEtoDPCodes(keynums[0])), sizeof(keyname));
Q_strncatz (keyname, va(" \'%i\'", MP_TranslateFTEtoDPCodes(keynums[1])), sizeof(keyname));
RETURN_SSTRING(keyname);
RETURN_TSTRING(keyname);
}
//vector getmousepos(void) = #66;
@ -813,17 +807,15 @@ void PF_M_gethostcachenumber(progfuncs_t *prinst, struct globalvars_s *pr_global
}
void PF_M_gethostcachestring (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
char *keyname = PF_TempStr(prinst);
char *ret = "";
char *ret;
int keynum = G_FLOAT(OFS_PARM0);
int svnum = G_FLOAT(OFS_PARM1);
serverinfo_t *sv;
sv = Master_SortedServer(svnum);
sv = Master_SortedServer(svnum);
ret = Master_ReadKeyString(sv, keynum);
Q_strncpyz(keyname, ret, MAXTEMPBUFFERLEN);
RETURN_SSTRING(keyname);
RETURN_TSTRING(ret);
}
//float gethostcacheindexforkey(string key) = #622;
@ -1010,7 +1002,7 @@ void PF_altstr_count(progfuncs_t *prinst, struct globalvars_s *pr_globals)
//string altstr_prepare(string str) = #83;
void PF_altstr_prepare(progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
char *outstr, *out;
char outstr[8192], *out;
char *instr, *in;
int size;
@ -1018,23 +1010,26 @@ void PF_altstr_prepare(progfuncs_t *prinst, struct globalvars_s *pr_globals)
instr = PR_GetStringOfs(prinst, OFS_PARM0 );
//VM_CheckEmptyString( instr );
outstr = PF_TempStr(prinst);
for( out = outstr, in = instr, size = MAXTEMPBUFFERLEN - 1 ; size && *in ; size--, in++, out++ )
if( *in == '\'' ) {
for( out = outstr, in = instr, size = sizeof(outstr) - 1 ; size && *in ; size--, in++, out++ )
{
if( *in == '\'' )
{
*out++ = '\\';
*out = '\'';
size--;
} else
}
else
*out = *in;
}
*out = 0;
G_INT( OFS_RETURN ) = (int)PR_SetString( prinst, outstr );
G_INT( OFS_RETURN ) = (int)PR_TempString( prinst, outstr );
}
//string altstr_get(string str, float num) = #84;
void PF_altstr_get(progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
char *altstr, *pos, *outstr, *out;
char *altstr, *pos, outstr[8192], *out;
int count, size;
// VM_SAFEPARMCOUNT( 2, VM_altstr_get );
@ -1046,27 +1041,33 @@ void PF_altstr_get(progfuncs_t *prinst, struct globalvars_s *pr_globals)
count = count * 2 + 1;
for( pos = altstr ; *pos && count ; pos++ )
{
if( *pos == '\\' && !*++pos )
break;
else if( *pos == '\'' )
count--;
}
if( !*pos ) {
if( !*pos )
{
G_INT( OFS_RETURN ) = (int)PR_SetString( prinst, "" );
return;
}
outstr = PF_TempStr(prinst);
for( out = outstr, size = MAXTEMPBUFFERLEN - 1 ; size && *pos ; size--, pos++, out++ )
if( *pos == '\\' ) {
for( out = outstr, size = sizeof(outstr) - 1 ; size && *pos ; size--, pos++, out++ )
{
if( *pos == '\\' )
{
if( !*++pos )
break;
*out = *pos;
size--;
} else if( *pos == '\'' )
}
else if( *pos == '\'' )
break;
else
*out = *pos;
}
*out = 0;
G_INT( OFS_RETURN ) = (int)PR_SetString( prinst, outstr );
@ -1077,7 +1078,7 @@ void PF_altstr_set(progfuncs_t *prinst, struct globalvars_s *pr_globals)
int num;
char *altstr, *str;
char *in;
char *outstr, *out;
char outstr[8192], *out;
// VM_SAFEPARMCOUNT( 3, VM_altstr_set );
@ -1089,23 +1090,29 @@ void PF_altstr_set(progfuncs_t *prinst, struct globalvars_s *pr_globals)
str = PR_GetStringOfs(prinst, OFS_PARM2 );
//VM_CheckEmptyString( str );
outstr = out = PF_TempStr(prinst);
out = outstr;
for( num = num * 2 + 1, in = altstr; *in && num; *out++ = *in++ )
{
if( *in == '\\' && !*++in )
break;
else if( *in == '\'' )
num--;
}
if( !in ) {
if( !in )
{
G_INT( OFS_RETURN ) = (int)PR_SetString( prinst, "" );
return;
}
// copy set in
for( ; *str; *out++ = *str++ );
for( ; *str; *out++ = *str++ )
;
// now jump over the old contents
for( ; *in ; in++ )
{
if( *in == '\'' || (*in == '\\' && !*++in) )
break;
}
if( !in ) {
G_INT( OFS_RETURN ) = (int)PR_SetString( prinst, "" );
@ -1113,7 +1120,7 @@ void PF_altstr_set(progfuncs_t *prinst, struct globalvars_s *pr_globals)
}
strcpy( out, in );
G_INT( OFS_RETURN ) = (int)PR_SetString( prinst, outstr );
G_INT( OFS_RETURN ) = (int)PR_TempString( prinst, outstr );
}

View File

@ -1629,7 +1629,7 @@ TRACE(("dbg: R_ApplyRenderer: clearing world\n"));
}
ent = sv.edicts;
ent->v->model = PR_SetString(svprogfuncs, sv.worldmodel->name); //FIXME: is this a problem for normal ents?
// ent->v->model = PR_NewString(svprogfuncs, sv.worldmodel->name); //FIXME: is this a problem for normal ents?
for (i=0 ; i<sv.num_edicts ; i++)
{
ent = EDICT_NUM(svprogfuncs, i);

View File

@ -4,8 +4,7 @@ string_t PR_TempString(progfuncs_t *prinst, char *str); //returns a tempstring c
char *PF_TempStr(progfuncs_t *prinst); //returns a tempstring which can be filled in with whatever junk you want.
#define RETURN_SSTRING(s) (((int *)pr_globals)[OFS_RETURN] = PR_SetString(prinst, s)) //static - exe will not change it.
#define MAX_TEMPSTRS ((int)pr_tempstringcount.value)
#define MAXTEMPBUFFERLEN ((int)pr_tempstringsize.value)
#define RETURN_TSTRING(s) (((int *)pr_globals)[OFS_RETURN] = PR_TempString(prinst, s)) //temp (static but cycle buffers)
extern cvar_t pr_tempstringsize;
extern cvar_t pr_tempstringcount;

View File

@ -176,7 +176,7 @@ reeval:
OPC->_float = (float)(!OPA->_vector[0] && !OPA->_vector[1] && !OPA->_vector[2]);
break;
case OP_NOT_S:
OPC->_float = (float)(!(OPA->string) || !*(OPA->string+progfuncs->stringtable));
OPC->_float = (float)(!(OPA->string) || !*PR_StringToNative(progfuncs, OPA->string));
break;
case OP_NOT_FNC:
OPC->_float = (float)(!(OPA->function & ~0xff000000));
@ -206,20 +206,20 @@ reeval:
OPC->_float = true;
else if (!OPA->string)
{
if (!OPB->string || !*(OPB->string+progfuncs->stringtable))
if (!OPB->string || !*PR_StringToNative(progfuncs, OPB->string))
OPC->_float = true;
else
OPC->_float = false;
}
else if (!OPB->string)
{
if (!OPA->string || !*(OPA->string+progfuncs->stringtable))
if (!OPA->string || !*PR_StringToNative(progfuncs, OPA->string))
OPC->_float = true;
else
OPC->_float = false;
}
else
OPC->_float = (float)(!strcmp(OPA->string+progfuncs->stringtable,OPB->string+progfuncs->stringtable));
OPC->_float = (float)(!strcmp(PR_StringToNative(progfuncs, OPA->string),PR_StringToNative(progfuncs, OPB->string)));
break;
case OP_EQ_E:
OPC->_float = (float)(OPA->_int == OPB->_int);
@ -242,20 +242,20 @@ reeval:
OPC->_float = false;
else if (!OPA->string)
{
if (!OPB->string || !*(OPB->string+progfuncs->stringtable))
if (!OPB->string || !*(PR_StringToNative(progfuncs, OPB->string)))
OPC->_float = false;
else
OPC->_float = true;
}
else if (!OPB->string)
{
if (!OPA->string || !*(OPA->string+progfuncs->stringtable))
if (!OPA->string || !*PR_StringToNative(progfuncs, OPA->string))
OPC->_float = false;
else
OPC->_float = true;
}
else
OPC->_float = (float)(strcmp(OPA->string+progfuncs->stringtable,OPB->string+progfuncs->stringtable));
OPC->_float = (float)(strcmp(PR_StringToNative(progfuncs, OPA->string),PR_StringToNative(progfuncs, OPB->string)));
break;
case OP_NE_E:
OPC->_float = (float)(OPA->_int != OPB->_int);
@ -443,7 +443,7 @@ reeval:
case OP_IFNOTS:
RUNAWAYCHECK();
if (!OPA->string || !OPA->string[progfuncs->stringtable])
if (!OPA->string || !PR_StringToNative(progfuncs, OPA->string))
st += (sofs)st->b - 1; // offset the s++
break;
@ -455,7 +455,7 @@ reeval:
case OP_IFS:
RUNAWAYCHECK();
if (OPA->string && OPA->string[progfuncs->stringtable])
if (OPA->string && PR_StringToNative(progfuncs, OPA->string))
st += (sofs)st->b - 1; // offset the s++
break;
@ -542,6 +542,7 @@ if (pr_typecurrent != 0)
progfuncs->lastcalledbuiltinnumber = i;
if (i < externs->numglobalbuiltins)
{
prinst->numtempstringsstack = prinst->numtempstrings;
(*externs->globalbuiltins[i]) (progfuncs, (struct globalvars_s *)current_progstate->globals);
if (prinst->continuestatement!=-1)
{
@ -868,9 +869,9 @@ if (pr_typecurrent != 0)
RUNAWAYCHECK();
st += (sofs)st->b-1; // -1 to offset the s++
}
if ((!swtch->_int && progfuncs->stringtable[OPA->string]) || (!OPA->_int && progfuncs->stringtable[swtch->string])) //one is null (cannot be not both).
if ((!swtch->_int && PR_StringToNative(progfuncs, OPA->string)) || (!OPA->_int && PR_StringToNative(progfuncs, swtch->string))) //one is null (cannot be not both).
break;
if (!strcmp(progfuncs->stringtable+swtch->string, progfuncs->stringtable+OPA->string))
if (!strcmp(PR_StringToNative(progfuncs, swtch->string), PR_StringToNative(progfuncs, OPA->string)))
{
RUNAWAYCHECK();
st += (sofs)st->b-1; // -1 to offset the s++

View File

@ -176,7 +176,7 @@ reeval:
OPC->_float = (float)(!OPA->_vector[0] && !OPA->_vector[1] && !OPA->_vector[2]);
break;
case OP_NOT_S:
OPC->_float = (float)(!(OPA->string) || !*(OPA->string+progfuncs->stringtable));
OPC->_float = (float)(!(OPA->string) || !*PR_StringToNative(progfuncs, OPA->string));
break;
case OP_NOT_FNC:
OPC->_float = (float)(!(OPA->function & ~0xff000000));
@ -206,20 +206,20 @@ reeval:
OPC->_float = true;
else if (!OPA->string)
{
if (!OPB->string || !*(OPB->string+progfuncs->stringtable))
if (!OPB->string || !*PR_StringToNative(progfuncs, OPB->string))
OPC->_float = true;
else
OPC->_float = false;
}
else if (!OPB->string)
{
if (!OPA->string || !*(OPA->string+progfuncs->stringtable))
if (!OPA->string || !*PR_StringToNative(progfuncs, OPA->string))
OPC->_float = true;
else
OPC->_float = false;
}
else
OPC->_float = (float)(!strcmp(OPA->string+progfuncs->stringtable,OPB->string+progfuncs->stringtable));
OPC->_float = (float)(!strcmp(PR_StringToNative(progfuncs, OPA->string),PR_StringToNative(progfuncs, OPB->string)));
break;
case OP_EQ_E:
OPC->_float = (float)(OPA->_int == OPB->_int);
@ -242,20 +242,20 @@ reeval:
OPC->_float = false;
else if (!OPA->string)
{
if (!OPB->string || !*(OPB->string+progfuncs->stringtable))
if (!OPB->string || !*(PR_StringToNative(progfuncs, OPB->string)))
OPC->_float = false;
else
OPC->_float = true;
}
else if (!OPB->string)
{
if (!OPA->string || !*(OPA->string+progfuncs->stringtable))
if (!OPA->string || !*PR_StringToNative(progfuncs, OPA->string))
OPC->_float = false;
else
OPC->_float = true;
}
else
OPC->_float = (float)(strcmp(OPA->string+progfuncs->stringtable,OPB->string+progfuncs->stringtable));
OPC->_float = (float)(strcmp(PR_StringToNative(progfuncs, OPA->string),PR_StringToNative(progfuncs, OPB->string)));
break;
case OP_NE_E:
OPC->_float = (float)(OPA->_int != OPB->_int);
@ -394,11 +394,18 @@ reeval:
#ifdef PARANOID
NUM_FOR_EDICT(ed); // make sure it's in range
#endif
if (ed->readonly)
if (!ed || ed->readonly)
{
pr_xstatement = st-pr_statements;
PR_RunError (progfuncs, "assignment to read-only entity in %s", progfuncs->stringtable + pr_xfunction->s_name);
}
//Whilst the next block would technically be correct, we don't use it as it breaks too many quake mods.
// if (ed->isfree)
// {
// pr_xstatement = st-pr_statements;
// PR_RunError (progfuncs, "assignment to free entitiy in %s", progfuncs->stringtable + pr_xfunction->s_name);
// }
OPC->_int = ENGINEPOINTER((((int *)edvars(ed)) + OPB->_int + progfuncs->fieldadjust));
break;
@ -436,7 +443,7 @@ reeval:
case OP_IFNOTS:
RUNAWAYCHECK();
if (!OPA->string || !OPA->string[progfuncs->stringtable])
if (!OPA->string || !PR_StringToNative(progfuncs, OPA->string))
st += (sofs)st->b - 1; // offset the s++
break;
@ -448,7 +455,7 @@ reeval:
case OP_IFS:
RUNAWAYCHECK();
if (OPA->string && OPA->string[progfuncs->stringtable])
if (OPA->string && PR_StringToNative(progfuncs, OPA->string))
st += (sofs)st->b - 1; // offset the s++
break;
@ -535,6 +542,7 @@ if (pr_typecurrent != 0)
progfuncs->lastcalledbuiltinnumber = i;
if (i < externs->numglobalbuiltins)
{
prinst->numtempstringsstack = prinst->numtempstrings;
(*externs->globalbuiltins[i]) (progfuncs, (struct globalvars_s *)current_progstate->globals);
if (prinst->continuestatement!=-1)
{
@ -734,7 +742,7 @@ if (pr_typecurrent != 0)
case OP_FETCH_GBL_E:
case OP_FETCH_GBL_FNC:
i = (int)OPB->_float;
if(i < 0 || i > G_INT((uofs)st->a - 1))
if(i < 0 || i > ((eval_t *)&glob[st->a-1])->_int)
{
PR_RunError(progfuncs, "array index out of bounds: %s[%d]", PR_GlobalStringNoContents(progfuncs, st->a), i);
}
@ -743,7 +751,7 @@ if (pr_typecurrent != 0)
break;
case OP_FETCH_GBL_V:
i = (int)OPB->_float;
if(i < 0 || i > G_INT((uofs)st->a - 1))
if(i < 0 || i > ((eval_t *)&glob[st->a-1])->_int)
{
PR_RunError(progfuncs, "array index out of bounds: %s[%d]", PR_GlobalStringNoContents(progfuncs, st->a), i);
}
@ -861,9 +869,9 @@ if (pr_typecurrent != 0)
RUNAWAYCHECK();
st += (sofs)st->b-1; // -1 to offset the s++
}
if ((!swtch->_int && progfuncs->stringtable[OPA->string]) || (!OPA->_int && progfuncs->stringtable[swtch->string])) //one is null (cannot be not both).
if ((!swtch->_int && PR_StringToNative(progfuncs, OPA->string)) || (!OPA->_int && PR_StringToNative(progfuncs, swtch->string))) //one is null (cannot be not both).
break;
if (!strcmp(progfuncs->stringtable+swtch->string, progfuncs->stringtable+OPA->string))
if (!strcmp(PR_StringToNative(progfuncs, swtch->string), PR_StringToNative(progfuncs, OPA->string)))
{
RUNAWAYCHECK();
st += (sofs)st->b-1; // -1 to offset the s++

View File

@ -176,7 +176,7 @@ reeval:
OPC->_float = (float)(!OPA->_vector[0] && !OPA->_vector[1] && !OPA->_vector[2]);
break;
case OP_NOT_S:
OPC->_float = (float)(!(OPA->string) || !*(OPA->string+progfuncs->stringtable));
OPC->_float = (float)(!(OPA->string) || !*PR_StringToNative(progfuncs, OPA->string));
break;
case OP_NOT_FNC:
OPC->_float = (float)(!(OPA->function & ~0xff000000));
@ -206,20 +206,20 @@ reeval:
OPC->_float = true;
else if (!OPA->string)
{
if (!OPB->string || !*(OPB->string+progfuncs->stringtable))
if (!OPB->string || !*PR_StringToNative(progfuncs, OPB->string))
OPC->_float = true;
else
OPC->_float = false;
}
else if (!OPB->string)
{
if (!OPA->string || !*(OPA->string+progfuncs->stringtable))
if (!OPA->string || !*PR_StringToNative(progfuncs, OPA->string))
OPC->_float = true;
else
OPC->_float = false;
}
else
OPC->_float = (float)(!strcmp(OPA->string+progfuncs->stringtable,OPB->string+progfuncs->stringtable));
OPC->_float = (float)(!strcmp(PR_StringToNative(progfuncs, OPA->string),PR_StringToNative(progfuncs, OPB->string)));
break;
case OP_EQ_E:
OPC->_float = (float)(OPA->_int == OPB->_int);
@ -242,20 +242,20 @@ reeval:
OPC->_float = false;
else if (!OPA->string)
{
if (!OPB->string || !*(OPB->string+progfuncs->stringtable))
if (!OPB->string || !*(PR_StringToNative(progfuncs, OPB->string)))
OPC->_float = false;
else
OPC->_float = true;
}
else if (!OPB->string)
{
if (!OPA->string || !*(OPA->string+progfuncs->stringtable))
if (!OPA->string || !*PR_StringToNative(progfuncs, OPA->string))
OPC->_float = false;
else
OPC->_float = true;
}
else
OPC->_float = (float)(strcmp(OPA->string+progfuncs->stringtable,OPB->string+progfuncs->stringtable));
OPC->_float = (float)(strcmp(PR_StringToNative(progfuncs, OPA->string),PR_StringToNative(progfuncs, OPB->string)));
break;
case OP_NE_E:
OPC->_float = (float)(OPA->_int != OPB->_int);
@ -394,11 +394,18 @@ reeval:
#ifdef PARANOID
NUM_FOR_EDICT(ed); // make sure it's in range
#endif
if (ed->readonly)
if (!ed || ed->readonly)
{
pr_xstatement = st-pr_statements;
PR_RunError (progfuncs, "assignment to read-only entity in %s", progfuncs->stringtable + pr_xfunction->s_name);
}
//Whilst the next block would technically be correct, we don't use it as it breaks too many quake mods.
// if (ed->isfree)
// {
// pr_xstatement = st-pr_statements;
// PR_RunError (progfuncs, "assignment to free entitiy in %s", progfuncs->stringtable + pr_xfunction->s_name);
// }
OPC->_int = ENGINEPOINTER((((int *)edvars(ed)) + OPB->_int + progfuncs->fieldadjust));
break;
@ -436,7 +443,7 @@ reeval:
case OP_IFNOTS:
RUNAWAYCHECK();
if (!OPA->string || !OPA->string[progfuncs->stringtable])
if (!OPA->string || !PR_StringToNative(progfuncs, OPA->string))
st += (sofs)st->b - 1; // offset the s++
break;
@ -448,7 +455,7 @@ reeval:
case OP_IFS:
RUNAWAYCHECK();
if (OPA->string && OPA->string[progfuncs->stringtable])
if (OPA->string && PR_StringToNative(progfuncs, OPA->string))
st += (sofs)st->b - 1; // offset the s++
break;
@ -535,6 +542,7 @@ if (pr_typecurrent != 0)
progfuncs->lastcalledbuiltinnumber = i;
if (i < externs->numglobalbuiltins)
{
prinst->numtempstringsstack = prinst->numtempstrings;
(*externs->globalbuiltins[i]) (progfuncs, (struct globalvars_s *)current_progstate->globals);
if (prinst->continuestatement!=-1)
{
@ -734,7 +742,7 @@ if (pr_typecurrent != 0)
case OP_FETCH_GBL_E:
case OP_FETCH_GBL_FNC:
i = (int)OPB->_float;
if(i < 0 || i > G_INT((uofs)st->a - 1))
if(i < 0 || i > ((eval_t *)&glob[st->a-1])->_int)
{
PR_RunError(progfuncs, "array index out of bounds: %s[%d]", PR_GlobalStringNoContents(progfuncs, st->a), i);
}
@ -743,7 +751,7 @@ if (pr_typecurrent != 0)
break;
case OP_FETCH_GBL_V:
i = (int)OPB->_float;
if(i < 0 || i > G_INT((uofs)st->a - 1))
if(i < 0 || i > ((eval_t *)&glob[st->a-1])->_int)
{
PR_RunError(progfuncs, "array index out of bounds: %s[%d]", PR_GlobalStringNoContents(progfuncs, st->a), i);
}
@ -861,9 +869,9 @@ if (pr_typecurrent != 0)
RUNAWAYCHECK();
st += (sofs)st->b-1; // -1 to offset the s++
}
if ((!swtch->_int && progfuncs->stringtable[OPA->string]) || (!OPA->_int && progfuncs->stringtable[swtch->string])) //one is null (cannot be not both).
if ((!swtch->_int && PR_StringToNative(progfuncs, OPA->string)) || (!OPA->_int && PR_StringToNative(progfuncs, swtch->string))) //one is null (cannot be not both).
break;
if (!strcmp(progfuncs->stringtable+swtch->string, progfuncs->stringtable+OPA->string))
if (!strcmp(PR_StringToNative(progfuncs, swtch->string), PR_StringToNative(progfuncs, OPA->string)))
{
RUNAWAYCHECK();
st += (sofs)st->b-1; // -1 to offset the s++

View File

@ -176,7 +176,7 @@ reeval:
OPC->_float = (float)(!OPA->_vector[0] && !OPA->_vector[1] && !OPA->_vector[2]);
break;
case OP_NOT_S:
OPC->_float = (float)(!(OPA->string) || !*(OPA->string+progfuncs->stringtable));
OPC->_float = (float)(!(OPA->string) || !*PR_StringToNative(progfuncs, OPA->string));
break;
case OP_NOT_FNC:
OPC->_float = (float)(!(OPA->function & ~0xff000000));
@ -206,20 +206,20 @@ reeval:
OPC->_float = true;
else if (!OPA->string)
{
if (!OPB->string || !*(OPB->string+progfuncs->stringtable))
if (!OPB->string || !*PR_StringToNative(progfuncs, OPB->string))
OPC->_float = true;
else
OPC->_float = false;
}
else if (!OPB->string)
{
if (!OPA->string || !*(OPA->string+progfuncs->stringtable))
if (!OPA->string || !*PR_StringToNative(progfuncs, OPA->string))
OPC->_float = true;
else
OPC->_float = false;
}
else
OPC->_float = (float)(!strcmp(OPA->string+progfuncs->stringtable,OPB->string+progfuncs->stringtable));
OPC->_float = (float)(!strcmp(PR_StringToNative(progfuncs, OPA->string),PR_StringToNative(progfuncs, OPB->string)));
break;
case OP_EQ_E:
OPC->_float = (float)(OPA->_int == OPB->_int);
@ -242,20 +242,20 @@ reeval:
OPC->_float = false;
else if (!OPA->string)
{
if (!OPB->string || !*(OPB->string+progfuncs->stringtable))
if (!OPB->string || !*(PR_StringToNative(progfuncs, OPB->string)))
OPC->_float = false;
else
OPC->_float = true;
}
else if (!OPB->string)
{
if (!OPA->string || !*(OPA->string+progfuncs->stringtable))
if (!OPA->string || !*PR_StringToNative(progfuncs, OPA->string))
OPC->_float = false;
else
OPC->_float = true;
}
else
OPC->_float = (float)(strcmp(OPA->string+progfuncs->stringtable,OPB->string+progfuncs->stringtable));
OPC->_float = (float)(strcmp(PR_StringToNative(progfuncs, OPA->string),PR_StringToNative(progfuncs, OPB->string)));
break;
case OP_NE_E:
OPC->_float = (float)(OPA->_int != OPB->_int);
@ -394,11 +394,18 @@ reeval:
#ifdef PARANOID
NUM_FOR_EDICT(ed); // make sure it's in range
#endif
if (ed->readonly)
if (!ed || ed->readonly)
{
pr_xstatement = st-pr_statements;
PR_RunError (progfuncs, "assignment to read-only entity in %s", progfuncs->stringtable + pr_xfunction->s_name);
}
//Whilst the next block would technically be correct, we don't use it as it breaks too many quake mods.
// if (ed->isfree)
// {
// pr_xstatement = st-pr_statements;
// PR_RunError (progfuncs, "assignment to free entitiy in %s", progfuncs->stringtable + pr_xfunction->s_name);
// }
OPC->_int = ENGINEPOINTER((((int *)edvars(ed)) + OPB->_int + progfuncs->fieldadjust));
break;
@ -436,7 +443,7 @@ reeval:
case OP_IFNOTS:
RUNAWAYCHECK();
if (!OPA->string || !OPA->string[progfuncs->stringtable])
if (!OPA->string || !PR_StringToNative(progfuncs, OPA->string))
st += (sofs)st->b - 1; // offset the s++
break;
@ -448,7 +455,7 @@ reeval:
case OP_IFS:
RUNAWAYCHECK();
if (OPA->string && OPA->string[progfuncs->stringtable])
if (OPA->string && PR_StringToNative(progfuncs, OPA->string))
st += (sofs)st->b - 1; // offset the s++
break;
@ -535,6 +542,7 @@ if (pr_typecurrent != 0)
progfuncs->lastcalledbuiltinnumber = i;
if (i < externs->numglobalbuiltins)
{
prinst->numtempstringsstack = prinst->numtempstrings;
(*externs->globalbuiltins[i]) (progfuncs, (struct globalvars_s *)current_progstate->globals);
if (prinst->continuestatement!=-1)
{
@ -734,7 +742,7 @@ if (pr_typecurrent != 0)
case OP_FETCH_GBL_E:
case OP_FETCH_GBL_FNC:
i = (int)OPB->_float;
if(i < 0 || i > G_INT((uofs)st->a - 1))
if(i < 0 || i > ((eval_t *)&glob[st->a-1])->_int)
{
PR_RunError(progfuncs, "array index out of bounds: %s[%d]", PR_GlobalStringNoContents(progfuncs, st->a), i);
}
@ -743,7 +751,7 @@ if (pr_typecurrent != 0)
break;
case OP_FETCH_GBL_V:
i = (int)OPB->_float;
if(i < 0 || i > G_INT((uofs)st->a - 1))
if(i < 0 || i > ((eval_t *)&glob[st->a-1])->_int)
{
PR_RunError(progfuncs, "array index out of bounds: %s[%d]", PR_GlobalStringNoContents(progfuncs, st->a), i);
}
@ -861,9 +869,9 @@ if (pr_typecurrent != 0)
RUNAWAYCHECK();
st += (sofs)st->b-1; // -1 to offset the s++
}
if ((!swtch->_int && progfuncs->stringtable[OPA->string]) || (!OPA->_int && progfuncs->stringtable[swtch->string])) //one is null (cannot be not both).
if ((!swtch->_int && PR_StringToNative(progfuncs, OPA->string)) || (!OPA->_int && PR_StringToNative(progfuncs, swtch->string))) //one is null (cannot be not both).
break;
if (!strcmp(progfuncs->stringtable+swtch->string, progfuncs->stringtable+OPA->string))
if (!strcmp(PR_StringToNative(progfuncs, swtch->string), PR_StringToNative(progfuncs, OPA->string)))
{
RUNAWAYCHECK();
st += (sofs)st->b-1; // -1 to offset the s++

View File

@ -330,6 +330,130 @@ int EdictToProgs (progfuncs_t *progfuncs, struct edict_s *ed)
return EDICT_TO_PROG(progfuncs, ed);
}
string_t PR_StringToProgs (progfuncs_t *progfuncs, char *str)
{
char **ntable;
int i, free=-1;
if (!str)
return 0;
// if (str-progfuncs->stringtable < progfuncs->stringtablesize)
// return str - progfuncs->stringtable;
for (i = prinst->numallocedstrings-1; i >= 0; i--)
{
if (prinst->allocedstrings[i] == str)
return (string_t)((unsigned int)i | 0x80000000);
if (!prinst->allocedstrings[i])
free = i;
}
if (free != -1)
{
i = free;
prinst->allocedstrings[i] = str;
return (string_t)((unsigned int)i | 0x80000000);
}
prinst->maxallocedstrings += 1024;
ntable = memalloc(sizeof(char*) * prinst->maxallocedstrings);
memcpy(ntable, prinst->allocedstrings, sizeof(char*) * prinst->numallocedstrings);
prinst->numallocedstrings = prinst->maxallocedstrings;
if (prinst->allocedstrings)
memfree(prinst->allocedstrings);
prinst->allocedstrings = ntable;
for (i = prinst->numallocedstrings-1; i >= 0; i--)
{
if (!prinst->allocedstrings[i])
{
prinst->allocedstrings[i] = str;
return (string_t)((unsigned int)i | 0x80000000);
}
}
return 0;
}
char *PR_StringToNative (progfuncs_t *progfuncs, string_t str)
{
if ((unsigned int)str & 0xc0000000)
{
if ((unsigned int)str & 0x80000000)
{
int i = str & ~0x80000000;
if (i >= prinst->numallocedstrings)
return "";
if (prinst->allocedstrings[i])
return prinst->allocedstrings[i];
else
return ""; //urm, was freed...
}
if ((unsigned int)str & 0x40000000)
{
int i = str & ~0x40000000;
if (i >= prinst->numtempstrings)
return "";
return prinst->tempstrings[i];
}
}
if (str >= progfuncs->stringtablesize)
return "";
return progfuncs->stringtable + str;
}
string_t PR_AllocTempString (progfuncs_t *progfuncs, char *str)
{
char **ntable;
int newmax;
int i;
if (!str)
return 0;
if (prinst->numtempstrings == prinst->maxtempstrings)
{
newmax = prinst->maxtempstrings += 1024;
prinst->maxtempstrings += 1024;
ntable = memalloc(sizeof(char*) * newmax);
memcpy(ntable, prinst->tempstrings, sizeof(char*) * prinst->numtempstrings);
prinst->maxtempstrings = newmax;
if (prinst->tempstrings)
memfree(prinst->tempstrings);
prinst->tempstrings = ntable;
}
i = prinst->numtempstrings;
if (i == 0x10000000)
return 0;
prinst->numtempstrings++;
prinst->tempstrings[i] = memalloc(strlen(str)+1);
strcpy(prinst->tempstrings[i], str);
return (string_t)((unsigned int)i | 0x40000000);
}
void PR_FreeTemps (progfuncs_t *progfuncs, int depth)
{
int i;
if (depth > prinst->numtempstrings)
{
Sys_Error("QC Temp stack inverted\n");
return;
}
for (i = depth; i < prinst->numtempstrings; i++)
{
memfree(prinst->tempstrings[i]);
}
prinst->numtempstrings = depth;
}
struct qcthread_s *PR_ForkStack (progfuncs_t *progfuncs);
void PR_ResumeThread (progfuncs_t *progfuncs, struct qcthread_s *thread);
@ -416,7 +540,12 @@ progfuncs_t deffuncs = {
QC_RegisterFieldVar,
0,
0
0,
PR_AllocTempString,
PR_StringToProgs,
PR_StringToNative
};
#undef printf

View File

@ -508,7 +508,7 @@ char *PR_ValueString (progfuncs_t *progfuncs, etype_t type, eval_t *val)
sprintf (line, "union");
break;
case ev_string:
sprintf (line, "%s", val->string+progfuncs->stringtable);
sprintf (line, "%s", PR_StringToNative(progfuncs, val->string));
break;
case ev_entity:
sprintf (line, "entity %i", NUM_FOR_EDICT(progfuncs, (struct edict_s *)PROG_TO_EDICT(progfuncs, val->edict)) );
@ -609,7 +609,7 @@ char *PR_UglyValueString (progfuncs_t *progfuncs, etype_t type, eval_t *val)
if ((unsigned)val->_int > (unsigned)addressableused)
_snprintf (line, sizeof(line), "CORRUPT STRING");
else
_snprintf (line, sizeof(line), "%s", val->string+progfuncs->stringtable);
_snprintf (line, sizeof(line), "%s", PR_StringToNative(progfuncs, val->string));
break;
case ev_entity:
sprintf (line, "%i", val->_int);
@ -683,7 +683,7 @@ char *PR_UglyOldValueString (progfuncs_t *progfuncs, etype_t type, eval_t *val)
sprintf (line, "unions cannot yet be saved");
break;
case ev_string:
sprintf (line, "%s", val->string+progfuncs->stringtable);
sprintf (line, "%s", PR_StringToNative(progfuncs, val->string));
break;
case ev_entity:
sprintf (line, "%i", NUM_FOR_EDICT(progfuncs, (struct edict_s *)PROG_TO_EDICT(progfuncs, val->edict)));
@ -1051,7 +1051,7 @@ pbool ED_ParseEpair (progfuncs_t *progfuncs, void *base, ddefXX_t *key, char *s,
switch (type)
{
case ev_string:
st = ED_NewString (progfuncs, s, 0)-progfuncs->stringtable;
st = PR_StringToProgs(progfuncs, ED_NewString (progfuncs, s, 0));
*(string_t *)d = st;
break;
@ -2018,7 +2018,7 @@ int LoadEnts(progfuncs_t *progfuncs, char *file, float killonspawnflags)
CheckSpawn = PR_FindFunc(progfuncs, "CheckSpawn", -2);
var = GetEdictFieldValue (progfuncs, (struct edict_s *)ed, "classname", NULL);
if (!var || !var->string || !*(var->string+progfuncs->stringtable))
if (!var || !var->string || !*PR_StringToNative(progfuncs, var->string))
{
printf("No classname\n");
ED_Free(progfuncs, (struct edict_s *)ed);
@ -2044,7 +2044,7 @@ int LoadEnts(progfuncs_t *progfuncs, char *file, float killonspawnflags)
selfvar = (eval_t *)((int *)pr_globals + ED_FindGlobalOfs(progfuncs, "self"));
selfvar->edict = EDICT_TO_PROG(progfuncs, ed);
f = PR_FindFunc(progfuncs, var->string+progfuncs->stringtable, PR_ANYBACK);
f = PR_FindFunc(progfuncs, PR_StringToNative(progfuncs, var->string), PR_ANYBACK);
if (f)
{
if (CheckSpawn)
@ -2064,7 +2064,7 @@ int LoadEnts(progfuncs_t *progfuncs, char *file, float killonspawnflags)
}
else
{
printf("Couldn't find spawn function %s\n", var->string+progfuncs->stringtable);
printf("Couldn't find spawn function %s\n", PR_StringToNative(progfuncs, var->string));
ED_Free(progfuncs, (struct edict_s *)ed);
}
}
@ -2977,6 +2977,9 @@ retry:
if (!progfuncs->stringtable)
progfuncs->stringtable = pr_strings;
if (progfuncs->stringtablesize + progfuncs->stringtable < pr_strings + pr_progs->numstrings)
progfuncs->stringtablesize = (pr_strings + pr_progs->numstrings) - progfuncs->stringtable;
eval = PR_FindGlobal(progfuncs, "thisprogs", progstype);
if (eval)
eval->prog = progstype;

View File

@ -894,6 +894,8 @@ void PR_ExecuteProgram (progfuncs_t *progfuncs, func_t fnum)
int s;
int tempdepth;
unsigned int newprogs = (fnum & 0xff000000)>>24;
initial_progs = pr_typecurrent;
@ -953,14 +955,19 @@ void PR_ExecuteProgram (progfuncs_t *progfuncs, func_t fnum)
// make a stack frame
prinst->exitdepth = pr_depth;
s = PR_EnterFunction (progfuncs, f, initial_progs);
tempdepth = prinst->numtempstringsstack;
PR_ExecuteCode(progfuncs, s);
PR_MoveParms(progfuncs, initial_progs, pr_typecurrent);
PR_SwitchProgs(progfuncs, initial_progs);
PR_FreeTemps(progfuncs, tempdepth);
prinst->numtempstringsstack = tempdepth;
prinst->exitdepth = oldexitdepth;
}
@ -1061,6 +1068,7 @@ void PR_ResumeThread (progfuncs_t *progfuncs, struct qcthread_s *thread)
int oldexitdepth;
int s;
int tempdepth;
progsnum_t prnum = thread->xprogs;
int fnum = thread->xfunction;
@ -1133,11 +1141,14 @@ void PR_ResumeThread (progfuncs_t *progfuncs, struct qcthread_s *thread)
pr_xfunction = f;
s = thread->xstatement;
tempdepth = prinst->numtempstringsstack;
PR_ExecuteCode(progfuncs, s);
PR_MoveParms(progfuncs, initial_progs, pr_typecurrent);
PR_SwitchProgs(progfuncs, initial_progs);
PR_FreeTemps(progfuncs, tempdepth);
prinst->numtempstringsstack = tempdepth;
prinst->exitdepth = oldexitdepth;
pr_xfunction = oldf;

View File

@ -328,6 +328,16 @@ void PR_SetBuiltins(int type);
#define vars(type, name, size) type name[size]
typedef struct prinst_s {
char **tempstrings;
int maxtempstrings;
int numtempstrings;
int numtempstringsstack;
char **allocedstrings;
int maxallocedstrings;
int numallocedstrings;
var(progstate_t *, pr_progstate);
#define pr_progstate prinst->pr_progstate
@ -440,6 +450,11 @@ ddef16_t *ED_FindGlobal16 (progfuncs_t *progfuncs, char *name);
ddef32_t *ED_FindGlobal32 (progfuncs_t *progfuncs, char *name);
ddef32_t *ED_GlobalAtOfs32 (progfuncs_t *progfuncs, unsigned int ofs);
string_t PR_StringToProgs (progfuncs_t *inst, char *str);
char *PR_StringToNative (progfuncs_t *inst, string_t str);
void PR_FreeTemps (progfuncs_t *progfuncs, int depth);
char *PR_GlobalString (progfuncs_t *progfuncs, int ofs);
char *PR_GlobalStringNoContents (progfuncs_t *progfuncs, int ofs);

View File

@ -127,6 +127,12 @@ struct progfuncs_s {
char *tempstringbase; //for engine's use. Store your base tempstring pointer here.
int tempstringnum; //for engine's use.
string_t (*TempString) (progfuncs_t *prinst, char *str);
string_t (*StringToProgs) (progfuncs_t *prinst, char *str);
char *(*StringToNative) (progfuncs_t *prinst, string_t str);
int stringtablesize;
};
typedef struct progexterns_s {
@ -244,6 +250,10 @@ typedef union eval_s
#define PR_RegisterBuiltin(pf, name, func) (*pf->RegisterBuiltin) (pf, name, func)
#define PR_GetString(pf,s) (*pf->StringToNative) (pf, s)
#define PR_GetStringOfs(pf,o) (*pf->StringToNative) (pf, G_INT(o))
#define PR_SetString(pf, s) (*pf->StringToProgs) (pf, s)
#define NEXT_EDICT(pf,o) EDICT_NUM(pf, NUM_FOR_EDICT(pf, o)+1)
#define RETURN_EDICT(pf, e) (((int *)pr_globals)[OFS_RETURN] = EDICT_TO_PROG(pf, e))
@ -258,11 +268,14 @@ typedef union eval_s
#define G_VECTOR(o) (&((float *)pr_globals)[o])
#define G_FUNCTION(o) (*(func_t *)&((float *)pr_globals)[o])
/*
#define PR_GetString(p,s) (s?s + p->stringtable:"")
#define PR_GetStringOfs(p,o) (G_INT(o)?G_INT(o) + p->stringtable:"")
#define PR_SetStringOfs(p,o,s) (G_INT(o) = s - p->stringtable)
#define PR_SetString(p, s) ((s&&*s)?(s - p->stringtable):0)
#define PR_NewString(p, s, l) (PR_AddString(p, s, l) - p->stringtable)
*/
//#define PR_SetString(p, s) ((s&&*s)?(s - p->stringtable):0)
#define PR_NewString(p, s, l) PR_SetString(p, PR_AddString(p, s, l))
/**/
#define ev_prog ev_integer

View File

@ -262,7 +262,12 @@ void NPP_NQWriteByte(int dest, qbyte data) //replacement write func (nq to qw)
if (dest == MSG_ONE)
{
client_t *cl = Write_GetClient();
if (cl)
if (!cl)
{
Con_Printf("msg_entity: not a client\n");
return;
}
else
{
if (cl->protocol == SCP_BAD) // is a bot
return;
@ -571,12 +576,22 @@ void NPP_NQWriteAngle(int dest, float in) //replacement write func (nq to qw)
if (dest == MSG_ONE)
{
client_t *cl = Write_GetClient();
if (cl && !ISQWCLIENT(cl))
if (!cl)
{
ClientReliableCheckBlock(cl, sizeof(char));
ClientReliableWrite_Angle(cl, in);
Con_Printf("msg_entity: not a client\n");
return;
}
else
{
if (cl->protocol == SCP_BAD)
return;
else if (!ISQWCLIENT(cl))
{
ClientReliableCheckBlock(cl, sizeof(char));
ClientReliableWrite_Angle(cl, in);
return;
}
}
}
else
MSG_WriteAngle (NQWriteDest(dest), in);
@ -594,15 +609,27 @@ void NPP_NQWriteCoord(int dest, float in) //replacement write func (nq to qw)
Con_Printf("NQWriteCoord: Messages should start with WriteByte\n");
#ifdef NQPROT
if (dest == MSG_ONE) {
if (dest == MSG_ONE)
{
client_t *cl = Write_GetClient();
if (cl && !ISQWCLIENT(cl))
if (!cl)
{
ClientReliableCheckBlock(cl, sizeof(float));
ClientReliableWrite_Coord(cl, in);
Con_Printf("msg_entity: not a client\n");
return;
}
} else
else
{
if (cl->protocol == SCP_BAD)
return;
else if (!ISQWCLIENT(cl))
{
ClientReliableCheckBlock(cl, sizeof(float));
ClientReliableWrite_Coord(cl, in);
return;
}
}
}
else
MSG_WriteCoord (NQWriteDest(dest), in);
#endif
@ -627,15 +654,27 @@ void NPP_NQWriteString(int dest, char *data) //replacement write func (nq to qw)
}
#ifdef NQPROT
if (dest == MSG_ONE) {
if (dest == MSG_ONE)
{
client_t *cl = Write_GetClient();
if (cl && !ISQWCLIENT(cl))
if (!cl)
{
ClientReliableCheckBlock(cl, strlen(data)+1);
ClientReliableWrite_String(cl, data);
Con_Printf("msg_entity: not a client\n");
return;
}
} else
else
{
if (cl->protocol == SCP_BAD)
return;
else if (!ISQWCLIENT(cl))
{
ClientReliableCheckBlock(cl, strlen(data)+1);
ClientReliableWrite_String(cl, data);
return;
}
}
}
else
MSG_WriteString (NQWriteDest(dest), data);
#endif
@ -668,15 +707,27 @@ void NPP_NQWriteEntity(int dest, short data) //replacement write func (nq to qw)
data = svs.clients[data-1].viewent;
#ifdef NQPROT
if (dest == MSG_ONE) {
if (dest == MSG_ONE)
{
client_t *cl = Write_GetClient();
if (cl && !ISQWCLIENT(cl))
if (!cl)
{
ClientReliableCheckBlock(cl, sizeof(short));
ClientReliableWrite_Short(cl, data);
Con_Printf("msg_entity: not a client\n");
return;
}
} else
else
{
if (cl->protocol == SCP_BAD)
return;
else if (!ISQWCLIENT(cl))
{
ClientReliableCheckBlock(cl, sizeof(short));
ClientReliableWrite_Short(cl, data);
return;
}
}
}
else
MSG_WriteShort (NQWriteDest(dest), data);
#endif
@ -961,6 +1012,7 @@ void NPP_QWCheckDest(int dest)
}
cldest = cl;
*/
cldest = NULL;
}
else
{
@ -985,16 +1037,21 @@ void NPP_QWWriteByte(int dest, qbyte data) //replacement write func (nq to qw)
if (dest == MSG_ONE)
{
client_t *cl = Write_GetClient();
if (cl)
if (!cl)
{
if (ISQWCLIENT(cl))
Con_Printf("msg_entity: not a client\n");
return;
}
else
{
if (cl->protocol == SCP_BAD) // is a bot
return;
else if (ISQWCLIENT(cl))
{
ClientReliableCheckBlock(cl, sizeof(qbyte));
ClientReliableWrite_Byte(cl, data);
return;
}
else if (cl->protocol == SCP_BAD) // is a bot
return;
}
}
else
@ -1218,15 +1275,27 @@ void NPP_QWWriteString(int dest, char *data) //replacement write func (nq to qw)
NPP_QWCheckDest(dest);
#ifdef NQPROT
if (dest == MSG_ONE) {
if (dest == MSG_ONE)
{
client_t *cl = Write_GetClient();
if (cl && ISQWCLIENT(cl))
if (!cl)
{
ClientReliableCheckBlock(cl, strlen(data)+1);
ClientReliableWrite_String(cl, data);
Con_Printf("msg_entity: not a client\n");
return;
}
} else
else
{
if (cl->protocol == SCP_BAD)
return;
else if (ISQWCLIENT(cl))
{
ClientReliableCheckBlock(cl, strlen(data)+1);
ClientReliableWrite_String(cl, data);
return;
}
}
}
else
MSG_WriteString (QWWriteDest(dest), data);
#endif

View File

@ -61,7 +61,7 @@ cvar_t pr_compatabilitytest = SCVARF("pr_compatabilitytest", "0", CVAR_LATCH);
cvar_t pr_ssqc_coreonerror = SCVAR("pr_coreonerror", "1");
cvar_t pr_tempstringcount = SCVAR("pr_tempstringcount", "16");
cvar_t pr_tempstringcount = SCVAR("pr_tempstringcount", "");//"16");
cvar_t pr_tempstringsize = SCVAR("pr_tempstringsize", "4096");
cvar_t pr_droptofloorunits = SCVAR("pr_droptofloorunits", "");
@ -1611,7 +1611,7 @@ char *PF_VarString (progfuncs_t *prinst, int first, globalvars_t *pr_globals)
//#define RETURN_EDICT(pf, e) (((int *)pr_globals)[OFS_RETURN] = EDICT_TO_PROG(pf, e))
#define RETURN_SSTRING(s) (((int *)pr_globals)[OFS_RETURN] = PR_SetString(prinst, s)) //static - exe will not change it.
#define RETURN_TSTRING(s) (((int *)pr_globals)[OFS_RETURN] = PR_SetString(prinst, s)) //temp (static but cycle buffers?)
#define RETURN_TSTRING(s) (((int *)pr_globals)[OFS_RETURN] = PR_TempString(prinst, s)) //temp (static but cycle buffers)
#define RETURN_CSTRING(s) (((int *)pr_globals)[OFS_RETURN] = PR_SetString(prinst, s)) //semi-permanant. (hash tables?)
#define RETURN_PSTRING(s) (((int *)pr_globals)[OFS_RETURN] = PR_NewString(prinst, s, 0)) //permanant
@ -3510,40 +3510,43 @@ void PF_printv (progfuncs_t *prinst, struct globalvars_s *pr_globals)
#define MAX_TEMPSTRS ((int)pr_tempstringcount.value)
#define MAXTEMPBUFFERLEN ((int)pr_tempstringsize.value)
char *PF_TempStr(progfuncs_t *prinst)
{
if (prinst->tempstringnum == MAX_TEMPSTRS)
prinst->tempstringnum = 0;
return prinst->tempstringbase + (prinst->tempstringnum++)*MAXTEMPBUFFERLEN;
}
string_t PR_TempString(progfuncs_t *prinst, char *str)
{
char *tmp;
if (!prinst->tempstringbase)
return prinst->TempString(prinst, str);
if (!str || !*str)
return 0;
tmp = PF_TempStr(prinst);
if (prinst->tempstringnum == MAX_TEMPSTRS)
prinst->tempstringnum = 0;
tmp = prinst->tempstringbase + (prinst->tempstringnum++)*MAXTEMPBUFFERLEN;
Q_strncpyz(tmp, str, MAXTEMPBUFFERLEN);
return tmp - prinst->stringtable;
}
void PF_InitTempStrings(progfuncs_t *prinst)
{
if (pr_tempstringcount.value < 2)
if (pr_tempstringcount.value > 0 && pr_tempstringcount.value < 2)
pr_tempstringcount.value = 2;
if (pr_tempstringsize.value < 256)
pr_tempstringsize.value = 256;
pr_tempstringcount.flags |= CVAR_NOSET;
pr_tempstringsize.flags |= CVAR_NOSET;
prinst->tempstringbase = prinst->AddString(prinst, "", MAXTEMPBUFFERLEN*MAX_TEMPSTRS);
if (pr_tempstringcount.value >= 2)
prinst->tempstringbase = prinst->AddString(prinst, "", MAXTEMPBUFFERLEN*MAX_TEMPSTRS);
else
prinst->tempstringbase = 0;
prinst->tempstringnum = 0;
}
void PF_ftos (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
float v;
char *pr_string_temp = PF_TempStr(prinst);
char pr_string_temp[64];
v = G_FLOAT(OFS_PARM0);
if (v == (int)v)
@ -3564,8 +3567,9 @@ void PF_fabs (progfuncs_t *prinst, struct globalvars_s *pr_globals)
void PF_vtos (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
char *pr_string_temp = PF_TempStr(prinst);
char pr_string_temp[64];
sprintf (pr_string_temp, "'%5.1f %5.1f %5.1f'", G_VECTOR(OFS_PARM0)[0], G_VECTOR(OFS_PARM0)[1], G_VECTOR(OFS_PARM0)[2]);
PR_TempString(prinst, pr_string_temp);
RETURN_TSTRING(pr_string_temp);
}
@ -3630,7 +3634,7 @@ void PF_FindString (progfuncs_t *prinst, struct globalvars_s *pr_globals)
t = ((string_t *)ed->v)[f];
if (!t)
continue;
if (!strcmp(t+prinst->stringtable,s))
if (!strcmp(PR_GetString(prinst, t),s))
{
RETURN_EDICT(prinst, ed);
return;
@ -5190,7 +5194,6 @@ void PF_infokey (progfuncs_t *prinst, struct globalvars_s *pr_globals)
char *value;
char *key;
char ov[256];
char *dest;
e = G_EDICT(prinst, OFS_PARM0);
e1 = NUM_FOR_EDICT(prinst, e);
@ -5236,9 +5239,7 @@ void PF_infokey (progfuncs_t *prinst, struct globalvars_s *pr_globals)
} else
value = "";
dest = PF_TempStr(prinst);
strcpy(dest, value);
RETURN_CSTRING(dest);
G_INT(OFS_RETURN) = PR_TempString(prinst, value);
}
/*
@ -5486,7 +5487,7 @@ void PF_substring (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
int i, start, length;
char *s;
char *string = PF_TempStr(prinst);
char string[4096];
s = PR_GetStringOfs(prinst, OFS_PARM0);
start = G_FLOAT(OFS_PARM1);
@ -5513,7 +5514,7 @@ void PF_substring (progfuncs_t *prinst, struct globalvars_s *pr_globals)
string[i] = *s;
string[i] = 0;
RETURN_SSTRING(string);
RETURN_TSTRING(string);
}
@ -5592,11 +5593,11 @@ void PF_chr2str (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
int i;
char *string = PF_TempStr(prinst);
char string[16];
for (i = 0; i < *prinst->callargc; i++)
string[i] = G_FLOAT(OFS_PARM0 + i*3);
string[i] = '\0';
RETURN_SSTRING(string);
RETURN_TSTRING(string);
}
static int chrconv_number(int i, int base, int conv)
{
@ -5688,13 +5689,13 @@ void PF_strconv (progfuncs_t *prinst, struct globalvars_s *pr_globals)
unsigned char *string = PF_VarString(prinst, 3, pr_globals);
int len = strlen(string);
int i;
unsigned char *result = PF_TempStr(prinst);
unsigned char *resbuf = result;
unsigned char resbuf[8192];
unsigned char *result = resbuf;
if (len >= MAXTEMPBUFFERLEN)
len = MAXTEMPBUFFERLEN-1;
for (i = 0; i < len; i++, string++, result++) //do this backwards
for (i = 0; i < len; i++, string++, result++) //should this be done backwards?
{
if (*string >= '0' && *string <= '9') //normal numbers...
*result = chrconv_number(*string, '0', redchars);
@ -5764,14 +5765,13 @@ void PF_infoadd (progfuncs_t *prinst, struct globalvars_s *pr_globals)
char *info = PR_GetStringOfs(prinst, OFS_PARM0);
char *key = PR_GetStringOfs(prinst, OFS_PARM1);
char *value = PF_VarString(prinst, 2, pr_globals);
char *temp;
char temp[8192];
temp = PF_TempStr(prinst);
Q_strncpyz(temp, info, MAXTEMPBUFFERLEN);
Info_SetValueForStarKey(temp, key, value, MAXTEMPBUFFERLEN);
RETURN_SSTRING(temp);
RETURN_TSTRING(temp);
}
//uses qw style \key\value strings
@ -5779,13 +5779,10 @@ void PF_infoget (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
char *info = PR_GetStringOfs(prinst, OFS_PARM0);
char *key = PR_GetStringOfs(prinst, OFS_PARM1);
char *temp;
key = Info_ValueForKey(info, key);
temp = PF_TempStr(prinst);
strcpy(temp, key);
RETURN_SSTRING(temp);
RETURN_TSTRING(key);
}
//back to frik_file support.
@ -5919,10 +5916,10 @@ void PF_fgets (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
char c, *s, *o, *max;
int fnum = G_FLOAT(OFS_PARM0) - FIRST_QC_FILE_INDEX;
char *pr_string_temp = PF_TempStr(prinst);
char pr_string_temp[4096];
*pr_string_temp = '\0';
RETURN_SSTRING(pr_string_temp);
G_INT(OFS_RETURN) = 0; //EOF
if (fnum < 0 || fnum >= MAX_QC_FILES)
{
PR_BIError(prinst, "PF_fgets: File out of range\n");
@ -5964,7 +5961,7 @@ void PF_fgets (progfuncs_t *prinst, struct globalvars_s *pr_globals)
if (!pr_string_temp[0] && !*s)
G_INT(OFS_RETURN) = 0; //EOF
else
G_INT(OFS_RETURN) = pr_string_temp - prinst->stringtable;
RETURN_TSTRING(pr_string_temp);
}
void PF_fputs (progfuncs_t *prinst, struct globalvars_s *pr_globals)
@ -6194,7 +6191,7 @@ void PF_search_getfilename (progfuncs_t *prinst, struct globalvars_s *pr_globals
if (num < 0 || num >= s->entries)
return;
G_INT(OFS_RETURN) = (int)(s->names[num] - prinst->stringtable);
RETURN_TSTRING(s->names[num]);
return;
}
}
@ -6578,7 +6575,6 @@ void PF_Tokenize (progfuncs_t *prinst, struct globalvars_s *pr_globals) //84
}
void PF_ArgV (progfuncs_t *prinst, struct globalvars_s *pr_globals) //86 //string(float num) argv;
{
char *dest = PF_TempStr(prinst);
int i = G_FLOAT(OFS_PARM0);
if (i < 0)
{
@ -6586,8 +6582,7 @@ void PF_ArgV (progfuncs_t *prinst, struct globalvars_s *pr_globals) //86 /
G_INT(OFS_RETURN) = 0;
return;
}
strcpy(dest, Cmd_Argv(i));
RETURN_CSTRING(dest);
RETURN_TSTRING(Cmd_Argv(i));
}
/*
@ -6613,7 +6608,7 @@ string substr(string str, float start, float len)
void PF_substr (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
char *dest;
char dest[4096];
char *s;
int start, len, l;
@ -6627,7 +6622,6 @@ void PF_substr (progfuncs_t *prinst, struct globalvars_s *pr_globals)
RETURN_TSTRING("");
return;
}
dest = PF_TempStr(prinst);
s += start;
l -= start;
@ -6635,6 +6629,9 @@ void PF_substr (progfuncs_t *prinst, struct globalvars_s *pr_globals)
if (len > l + 1)
len = l + 1;
if (len > sizeof(dest)-1)
len = sizeof(dest)-1;
Q_strncpyz(dest, s, len + 1);
RETURN_TSTRING(dest);
@ -6650,7 +6647,7 @@ string strcat(string str1, string str2)
void PF_strcat (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
char *dest = PF_TempStr(prinst);
char dest[4096];
char *src = PF_VarString(prinst, 0, pr_globals);
Q_strncpyz(dest, src, MAXTEMPBUFFERLEN);
RETURN_TSTRING(dest);
@ -6666,12 +6663,11 @@ string strcat(float pad, string str1, ...)
void PF_strpad (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
char *dest = PF_TempStr(prinst);
char destbuf[4096];
char *dest = destbuf;
int pad = G_FLOAT(OFS_PARM0);
char *src = PF_VarString(prinst, 1, pr_globals);
RETURN_TSTRING(dest);
if (pad < 0)
{ //pad left
pad = -pad - strlen(src);
@ -6702,6 +6698,8 @@ void PF_strpad (progfuncs_t *prinst, struct globalvars_s *pr_globals)
*dest++ = ' ';
*dest = '\0';
}
RETURN_TSTRING(destbuf);
}
/*
@ -6804,7 +6802,6 @@ void PF_calltimeofday (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
date_t date;
func_t f;
char *ret = PF_TempStr(prinst);
f = PR_FindFunction(svprogfuncs, "timeofday", PR_ANY);
if (f)
@ -6817,8 +6814,7 @@ void PF_calltimeofday (progfuncs_t *prinst, struct globalvars_s *pr_globals)
G_FLOAT(OFS_PARM3) = (float)date.day;
G_FLOAT(OFS_PARM4) = (float)date.mon;
G_FLOAT(OFS_PARM5) = (float)date.year;
strcpy(ret, date.str);
G_INT(OFS_PARM6) = (int)PR_SetString(prinst, ret);
G_INT(OFS_PARM6) = (int)PR_TempString(prinst, date.str);
PR_ExecuteProgram(prinst, f);
}
@ -7033,10 +7029,9 @@ static void PF_copyentity (progfuncs_t *prinst, struct globalvars_s *pr_globals)
//string(entity ent) etos = #65
void PF_etos (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
char *s;
s = PF_TempStr(prinst);
sprintf (s, "entity %i", G_EDICTNUM(prinst, OFS_PARM0));
G_INT(OFS_RETURN) = (int)PR_SetString(prinst, s);
char s[64];
snprintf (s, sizeof(s), "entity %i", G_EDICTNUM(prinst, OFS_PARM0));
RETURN_TSTRING(s);
}