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) static void PF_cs_getstats(progfuncs_t *prinst, struct globalvars_s *pr_globals)
{ {
int stnum = G_FLOAT(OFS_PARM0); int stnum = G_FLOAT(OFS_PARM0);
char *out; char out[8];
out = PF_TempStr(prinst);
//the network protocol byteswaps //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)[3] = LittleLong(cl.stats[0][stnum+3]);
((unsigned int*)out)[4] = 0; //make sure it's null terminated ((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) 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) static void PF_ReadString(progfuncs_t *prinst, struct globalvars_s *pr_globals)
{ {
char *str = PF_TempStr(prinst);
char *read = MSG_ReadString(); char *read = MSG_ReadString();
Q_strncpyz(str, read, MAXTEMPBUFFERLEN); RETURN_TSTRING(read);
} }
static void PF_ReadAngle(progfuncs_t *prinst, struct globalvars_s *pr_globals) 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) if (*ret)
RETURN_SSTRING(ret); RETURN_TSTRING(ret);
else else
G_INT(OFS_RETURN) = 0; 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) //string(float pnum, string keyname)
static void PF_cs_getplayerkey (progfuncs_t *prinst, struct globalvars_s *pr_globals) static void PF_cs_getplayerkey (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{ {
char buffer[64];
char *ret; char *ret;
int pnum = G_FLOAT(OFS_PARM0); int pnum = G_FLOAT(OFS_PARM0);
char *keyname = PR_GetStringOfs(prinst, OFS_PARM1); 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(); CheckSendPings();
ret = PF_TempStr(prinst); ret = buffer;
sprintf(ret, "%i", cl.players[pnum].ping); sprintf(ret, "%i", cl.players[pnum].ping);
} }
else if (!strcmp(keyname, "frags")) else if (!strcmp(keyname, "frags"))
{ {
ret = PF_TempStr(prinst); ret = buffer;
sprintf(ret, "%i", cl.players[pnum].frags); sprintf(ret, "%i", cl.players[pnum].frags);
} }
else if (!strcmp(keyname, "pl")) //packet loss else if (!strcmp(keyname, "pl")) //packet loss
{ {
CheckSendPings(); CheckSendPings();
ret = PF_TempStr(prinst); ret = buffer;
sprintf(ret, "%i", cl.players[pnum].pl); sprintf(ret, "%i", cl.players[pnum].pl);
} }
else if (!strcmp(keyname, "entertime")) //packet loss else if (!strcmp(keyname, "entertime")) //packet loss
{ {
ret = PF_TempStr(prinst); ret = buffer;
sprintf(ret, "%i", (int)cl.players[pnum].entertime); sprintf(ret, "%i", (int)cl.players[pnum].entertime);
} }
else 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); ret = Info_ValueForKey(cl.players[pnum].userinfo, keyname);
} }
if (*ret) if (*ret)
RETURN_SSTRING(ret); RETURN_TSTRING(ret);
else else
G_INT(OFS_RETURN) = 0; G_INT(OFS_RETURN) = 0;
} }
@ -3770,15 +3768,11 @@ qboolean CSQC_MouseMove(float xdelta, float ydelta)
qboolean CSQC_ConsoleCommand(char *cmd) qboolean CSQC_ConsoleCommand(char *cmd)
{ {
void *pr_globals; void *pr_globals;
char *str;
if (!csqcprogs || !csqcg.console_command) if (!csqcprogs || !csqcg.console_command)
return false; return false;
str = PF_TempStr(csqcprogs);
Q_strncpyz(str, cmd, MAXTEMPBUFFERLEN);
pr_globals = PR_globals(csqcprogs, PR_CURRENT); 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); PR_ExecuteProgram (csqcprogs, csqcg.console_command);
return G_FLOAT(OFS_RETURN); return G_FLOAT(OFS_RETURN);
@ -3787,15 +3781,11 @@ qboolean CSQC_ConsoleCommand(char *cmd)
qboolean CSQC_StuffCmd(char *cmd) qboolean CSQC_StuffCmd(char *cmd)
{ {
void *pr_globals; void *pr_globals;
char *str;
if (!csqcprogs || !csqcg.parse_stuffcmd) if (!csqcprogs || !csqcg.parse_stuffcmd)
return false; return false;
str = PF_TempStr(csqcprogs);
Q_strncpyz(str, cmd, MAXTEMPBUFFERLEN);
pr_globals = PR_globals(csqcprogs, PR_CURRENT); 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); PR_ExecuteProgram (csqcprogs, csqcg.parse_stuffcmd);
return true; return true;
@ -3803,15 +3793,11 @@ qboolean CSQC_StuffCmd(char *cmd)
qboolean CSQC_CenterPrint(char *cmd) qboolean CSQC_CenterPrint(char *cmd)
{ {
void *pr_globals; void *pr_globals;
char *str;
if (!csqcprogs || !csqcg.parse_centerprint) if (!csqcprogs || !csqcg.parse_centerprint)
return false; return false;
str = PF_TempStr(csqcprogs);
Q_strncpyz(str, cmd, MAXTEMPBUFFERLEN);
pr_globals = PR_globals(csqcprogs, PR_CURRENT); 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); PR_ExecuteProgram (csqcprogs, csqcg.parse_centerprint);
return G_FLOAT(OFS_RETURN); 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) int CSQC_StartSound(int entnum, int channel, char *soundname, vec3_t pos, float vol, float attenuation)
{ {
void *pr_globals; void *pr_globals;
char *str;
csqcedict_t *ent; csqcedict_t *ent;
if (!csqcprogs || !csqcg.serversound) 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); pr_globals = PR_globals(csqcprogs, PR_CURRENT);
str = PF_TempStr(csqcprogs);
Q_strncpyz(str, soundname, MAXTEMPBUFFERLEN);
*csqcg.self = EDICT_TO_PROG(csqcprogs, (void*)ent); *csqcg.self = EDICT_TO_PROG(csqcprogs, (void*)ent);
G_FLOAT(OFS_PARM0) = channel; 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)); VectorCopy(pos, G_VECTOR(OFS_PARM2));
G_FLOAT(OFS_PARM3) = vol; G_FLOAT(OFS_PARM3) = vol;
G_FLOAT(OFS_PARM4) = attenuation; G_FLOAT(OFS_PARM4) = attenuation;
@ -3960,7 +3942,7 @@ void CSQC_ParseEntities(void)
#ifndef CLIENTONLY #ifndef CLIENTONLY
if (sv.state) 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 #endif
} }

View File

@ -633,22 +633,16 @@ int MP_TranslateDPtoFTECodes(int code);
void PF_cl_keynumtostring (progfuncs_t *prinst, struct globalvars_s *pr_globals) void PF_cl_keynumtostring (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{ {
int code = G_FLOAT(OFS_PARM0); int code = G_FLOAT(OFS_PARM0);
char *keyname = PF_TempStr(prinst);
code = MP_TranslateDPtoFTECodes (code); code = MP_TranslateDPtoFTECodes (code);
strcpy(keyname, Key_KeynumToString(code)); RETURN_TSTRING(Key_KeynumToString(code));
RETURN_SSTRING(keyname);
} }
void PF_cl_getkeybind (progfuncs_t *prinst, struct globalvars_s *pr_globals) void PF_cl_getkeybind (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{ {
char *binding = Key_GetBinding(G_FLOAT(OFS_PARM0)); char *binding = Key_GetBinding(G_FLOAT(OFS_PARM0));
char *result = PF_TempStr(prinst); RETURN_TSTRING(binding);
if (!binding)
binding = "";
Q_strncpyz(result, binding, MAXTEMPBUFFERLEN);
RETURN_SSTRING(result);
} }
int MP_TranslateDPtoFTECodes(int code); 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); char *cmdname = PR_GetStringOfs(prinst, OFS_PARM0);
int keynums[2]; int keynums[2];
char *keyname = PF_TempStr(prinst); char keyname[512];
M_FindKeysForCommand(cmdname, keynums); M_FindKeysForCommand(cmdname, keynums);
keyname[0] = '\0'; keyname[0] = '\0';
Q_strncatz (keyname, va(" \'%i\'", MP_TranslateFTEtoDPCodes(keynums[0])), MAXTEMPBUFFERLEN); Q_strncatz (keyname, va(" \'%i\'", MP_TranslateFTEtoDPCodes(keynums[0])), sizeof(keyname));
Q_strncatz (keyname, va(" \'%i\'", MP_TranslateFTEtoDPCodes(keynums[1])), MAXTEMPBUFFERLEN); Q_strncatz (keyname, va(" \'%i\'", MP_TranslateFTEtoDPCodes(keynums[1])), sizeof(keyname));
RETURN_SSTRING(keyname); RETURN_TSTRING(keyname);
} }
//vector getmousepos(void) = #66; //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) 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 keynum = G_FLOAT(OFS_PARM0);
int svnum = G_FLOAT(OFS_PARM1); int svnum = G_FLOAT(OFS_PARM1);
serverinfo_t *sv; serverinfo_t *sv;
sv = Master_SortedServer(svnum);
sv = Master_SortedServer(svnum);
ret = Master_ReadKeyString(sv, keynum); ret = Master_ReadKeyString(sv, keynum);
Q_strncpyz(keyname, ret, MAXTEMPBUFFERLEN); RETURN_TSTRING(ret);
RETURN_SSTRING(keyname);
} }
//float gethostcacheindexforkey(string key) = #622; //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; //string altstr_prepare(string str) = #83;
void PF_altstr_prepare(progfuncs_t *prinst, struct globalvars_s *pr_globals) void PF_altstr_prepare(progfuncs_t *prinst, struct globalvars_s *pr_globals)
{ {
char *outstr, *out; char outstr[8192], *out;
char *instr, *in; char *instr, *in;
int size; int size;
@ -1018,23 +1010,26 @@ void PF_altstr_prepare(progfuncs_t *prinst, struct globalvars_s *pr_globals)
instr = PR_GetStringOfs(prinst, OFS_PARM0 ); instr = PR_GetStringOfs(prinst, OFS_PARM0 );
//VM_CheckEmptyString( instr ); //VM_CheckEmptyString( instr );
outstr = PF_TempStr(prinst);
for( out = outstr, in = instr, size = MAXTEMPBUFFERLEN - 1 ; size && *in ; size--, in++, out++ ) for( out = outstr, in = instr, size = sizeof(outstr) - 1 ; size && *in ; size--, in++, out++ )
if( *in == '\'' ) { {
if( *in == '\'' )
{
*out++ = '\\'; *out++ = '\\';
*out = '\''; *out = '\'';
size--; size--;
} else }
else
*out = *in; *out = *in;
}
*out = 0; *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; //string altstr_get(string str, float num) = #84;
void PF_altstr_get(progfuncs_t *prinst, struct globalvars_s *pr_globals) 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; int count, size;
// VM_SAFEPARMCOUNT( 2, VM_altstr_get ); // 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; count = count * 2 + 1;
for( pos = altstr ; *pos && count ; pos++ ) for( pos = altstr ; *pos && count ; pos++ )
{
if( *pos == '\\' && !*++pos ) if( *pos == '\\' && !*++pos )
break; break;
else if( *pos == '\'' ) else if( *pos == '\'' )
count--; count--;
}
if( !*pos ) { if( !*pos )
{
G_INT( OFS_RETURN ) = (int)PR_SetString( prinst, "" ); G_INT( OFS_RETURN ) = (int)PR_SetString( prinst, "" );
return; return;
} }
outstr = PF_TempStr(prinst); for( out = outstr, size = sizeof(outstr) - 1 ; size && *pos ; size--, pos++, out++ )
for( out = outstr, size = MAXTEMPBUFFERLEN - 1 ; size && *pos ; size--, pos++, out++ ) {
if( *pos == '\\' ) { if( *pos == '\\' )
{
if( !*++pos ) if( !*++pos )
break; break;
*out = *pos; *out = *pos;
size--; size--;
} else if( *pos == '\'' ) }
else if( *pos == '\'' )
break; break;
else else
*out = *pos; *out = *pos;
}
*out = 0; *out = 0;
G_INT( OFS_RETURN ) = (int)PR_SetString( prinst, outstr ); 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; int num;
char *altstr, *str; char *altstr, *str;
char *in; char *in;
char *outstr, *out; char outstr[8192], *out;
// VM_SAFEPARMCOUNT( 3, VM_altstr_set ); // 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 ); str = PR_GetStringOfs(prinst, OFS_PARM2 );
//VM_CheckEmptyString( str ); //VM_CheckEmptyString( str );
outstr = out = PF_TempStr(prinst); out = outstr;
for( num = num * 2 + 1, in = altstr; *in && num; *out++ = *in++ ) for( num = num * 2 + 1, in = altstr; *in && num; *out++ = *in++ )
{
if( *in == '\\' && !*++in ) if( *in == '\\' && !*++in )
break; break;
else if( *in == '\'' ) else if( *in == '\'' )
num--; num--;
}
if( !in ) { if( !in )
{
G_INT( OFS_RETURN ) = (int)PR_SetString( prinst, "" ); G_INT( OFS_RETURN ) = (int)PR_SetString( prinst, "" );
return; return;
} }
// copy set in // copy set in
for( ; *str; *out++ = *str++ ); for( ; *str; *out++ = *str++ )
;
// now jump over the old contents // now jump over the old contents
for( ; *in ; in++ ) for( ; *in ; in++ )
{
if( *in == '\'' || (*in == '\\' && !*++in) ) if( *in == '\'' || (*in == '\\' && !*++in) )
break; break;
}
if( !in ) { if( !in ) {
G_INT( OFS_RETURN ) = (int)PR_SetString( prinst, "" ); 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 ); 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 = 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++) for (i=0 ; i<sv.num_edicts ; i++)
{ {
ent = EDICT_NUM(svprogfuncs, 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. 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 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 RETURN_TSTRING(s) (((int *)pr_globals)[OFS_RETURN] = PR_TempString(prinst, s)) //temp (static but cycle buffers)
#define MAXTEMPBUFFERLEN ((int)pr_tempstringsize.value)
extern cvar_t pr_tempstringsize; extern cvar_t pr_tempstringsize;
extern cvar_t pr_tempstringcount; extern cvar_t pr_tempstringcount;

View File

@ -176,7 +176,7 @@ reeval:
OPC->_float = (float)(!OPA->_vector[0] && !OPA->_vector[1] && !OPA->_vector[2]); OPC->_float = (float)(!OPA->_vector[0] && !OPA->_vector[1] && !OPA->_vector[2]);
break; break;
case OP_NOT_S: case OP_NOT_S:
OPC->_float = (float)(!(OPA->string) || !*(OPA->string+progfuncs->stringtable)); OPC->_float = (float)(!(OPA->string) || !*PR_StringToNative(progfuncs, OPA->string));
break; break;
case OP_NOT_FNC: case OP_NOT_FNC:
OPC->_float = (float)(!(OPA->function & ~0xff000000)); OPC->_float = (float)(!(OPA->function & ~0xff000000));
@ -206,20 +206,20 @@ reeval:
OPC->_float = true; OPC->_float = true;
else if (!OPA->string) else if (!OPA->string)
{ {
if (!OPB->string || !*(OPB->string+progfuncs->stringtable)) if (!OPB->string || !*PR_StringToNative(progfuncs, OPB->string))
OPC->_float = true; OPC->_float = true;
else else
OPC->_float = false; OPC->_float = false;
} }
else if (!OPB->string) else if (!OPB->string)
{ {
if (!OPA->string || !*(OPA->string+progfuncs->stringtable)) if (!OPA->string || !*PR_StringToNative(progfuncs, OPA->string))
OPC->_float = true; OPC->_float = true;
else else
OPC->_float = false; OPC->_float = false;
} }
else 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; break;
case OP_EQ_E: case OP_EQ_E:
OPC->_float = (float)(OPA->_int == OPB->_int); OPC->_float = (float)(OPA->_int == OPB->_int);
@ -242,20 +242,20 @@ reeval:
OPC->_float = false; OPC->_float = false;
else if (!OPA->string) else if (!OPA->string)
{ {
if (!OPB->string || !*(OPB->string+progfuncs->stringtable)) if (!OPB->string || !*(PR_StringToNative(progfuncs, OPB->string)))
OPC->_float = false; OPC->_float = false;
else else
OPC->_float = true; OPC->_float = true;
} }
else if (!OPB->string) else if (!OPB->string)
{ {
if (!OPA->string || !*(OPA->string+progfuncs->stringtable)) if (!OPA->string || !*PR_StringToNative(progfuncs, OPA->string))
OPC->_float = false; OPC->_float = false;
else else
OPC->_float = true; OPC->_float = true;
} }
else 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; break;
case OP_NE_E: case OP_NE_E:
OPC->_float = (float)(OPA->_int != OPB->_int); OPC->_float = (float)(OPA->_int != OPB->_int);
@ -443,7 +443,7 @@ reeval:
case OP_IFNOTS: case OP_IFNOTS:
RUNAWAYCHECK(); RUNAWAYCHECK();
if (!OPA->string || !OPA->string[progfuncs->stringtable]) if (!OPA->string || !PR_StringToNative(progfuncs, OPA->string))
st += (sofs)st->b - 1; // offset the s++ st += (sofs)st->b - 1; // offset the s++
break; break;
@ -455,7 +455,7 @@ reeval:
case OP_IFS: case OP_IFS:
RUNAWAYCHECK(); RUNAWAYCHECK();
if (OPA->string && OPA->string[progfuncs->stringtable]) if (OPA->string && PR_StringToNative(progfuncs, OPA->string))
st += (sofs)st->b - 1; // offset the s++ st += (sofs)st->b - 1; // offset the s++
break; break;
@ -542,6 +542,7 @@ if (pr_typecurrent != 0)
progfuncs->lastcalledbuiltinnumber = i; progfuncs->lastcalledbuiltinnumber = i;
if (i < externs->numglobalbuiltins) if (i < externs->numglobalbuiltins)
{ {
prinst->numtempstringsstack = prinst->numtempstrings;
(*externs->globalbuiltins[i]) (progfuncs, (struct globalvars_s *)current_progstate->globals); (*externs->globalbuiltins[i]) (progfuncs, (struct globalvars_s *)current_progstate->globals);
if (prinst->continuestatement!=-1) if (prinst->continuestatement!=-1)
{ {
@ -868,9 +869,9 @@ if (pr_typecurrent != 0)
RUNAWAYCHECK(); RUNAWAYCHECK();
st += (sofs)st->b-1; // -1 to offset the s++ 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; break;
if (!strcmp(progfuncs->stringtable+swtch->string, progfuncs->stringtable+OPA->string)) if (!strcmp(PR_StringToNative(progfuncs, swtch->string), PR_StringToNative(progfuncs, OPA->string)))
{ {
RUNAWAYCHECK(); RUNAWAYCHECK();
st += (sofs)st->b-1; // -1 to offset the s++ 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]); OPC->_float = (float)(!OPA->_vector[0] && !OPA->_vector[1] && !OPA->_vector[2]);
break; break;
case OP_NOT_S: case OP_NOT_S:
OPC->_float = (float)(!(OPA->string) || !*(OPA->string+progfuncs->stringtable)); OPC->_float = (float)(!(OPA->string) || !*PR_StringToNative(progfuncs, OPA->string));
break; break;
case OP_NOT_FNC: case OP_NOT_FNC:
OPC->_float = (float)(!(OPA->function & ~0xff000000)); OPC->_float = (float)(!(OPA->function & ~0xff000000));
@ -206,20 +206,20 @@ reeval:
OPC->_float = true; OPC->_float = true;
else if (!OPA->string) else if (!OPA->string)
{ {
if (!OPB->string || !*(OPB->string+progfuncs->stringtable)) if (!OPB->string || !*PR_StringToNative(progfuncs, OPB->string))
OPC->_float = true; OPC->_float = true;
else else
OPC->_float = false; OPC->_float = false;
} }
else if (!OPB->string) else if (!OPB->string)
{ {
if (!OPA->string || !*(OPA->string+progfuncs->stringtable)) if (!OPA->string || !*PR_StringToNative(progfuncs, OPA->string))
OPC->_float = true; OPC->_float = true;
else else
OPC->_float = false; OPC->_float = false;
} }
else 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; break;
case OP_EQ_E: case OP_EQ_E:
OPC->_float = (float)(OPA->_int == OPB->_int); OPC->_float = (float)(OPA->_int == OPB->_int);
@ -242,20 +242,20 @@ reeval:
OPC->_float = false; OPC->_float = false;
else if (!OPA->string) else if (!OPA->string)
{ {
if (!OPB->string || !*(OPB->string+progfuncs->stringtable)) if (!OPB->string || !*(PR_StringToNative(progfuncs, OPB->string)))
OPC->_float = false; OPC->_float = false;
else else
OPC->_float = true; OPC->_float = true;
} }
else if (!OPB->string) else if (!OPB->string)
{ {
if (!OPA->string || !*(OPA->string+progfuncs->stringtable)) if (!OPA->string || !*PR_StringToNative(progfuncs, OPA->string))
OPC->_float = false; OPC->_float = false;
else else
OPC->_float = true; OPC->_float = true;
} }
else 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; break;
case OP_NE_E: case OP_NE_E:
OPC->_float = (float)(OPA->_int != OPB->_int); OPC->_float = (float)(OPA->_int != OPB->_int);
@ -394,11 +394,18 @@ reeval:
#ifdef PARANOID #ifdef PARANOID
NUM_FOR_EDICT(ed); // make sure it's in range NUM_FOR_EDICT(ed); // make sure it's in range
#endif #endif
if (ed->readonly) if (!ed || ed->readonly)
{ {
pr_xstatement = st-pr_statements; pr_xstatement = st-pr_statements;
PR_RunError (progfuncs, "assignment to read-only entity in %s", progfuncs->stringtable + pr_xfunction->s_name); 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)); OPC->_int = ENGINEPOINTER((((int *)edvars(ed)) + OPB->_int + progfuncs->fieldadjust));
break; break;
@ -436,7 +443,7 @@ reeval:
case OP_IFNOTS: case OP_IFNOTS:
RUNAWAYCHECK(); RUNAWAYCHECK();
if (!OPA->string || !OPA->string[progfuncs->stringtable]) if (!OPA->string || !PR_StringToNative(progfuncs, OPA->string))
st += (sofs)st->b - 1; // offset the s++ st += (sofs)st->b - 1; // offset the s++
break; break;
@ -448,7 +455,7 @@ reeval:
case OP_IFS: case OP_IFS:
RUNAWAYCHECK(); RUNAWAYCHECK();
if (OPA->string && OPA->string[progfuncs->stringtable]) if (OPA->string && PR_StringToNative(progfuncs, OPA->string))
st += (sofs)st->b - 1; // offset the s++ st += (sofs)st->b - 1; // offset the s++
break; break;
@ -535,6 +542,7 @@ if (pr_typecurrent != 0)
progfuncs->lastcalledbuiltinnumber = i; progfuncs->lastcalledbuiltinnumber = i;
if (i < externs->numglobalbuiltins) if (i < externs->numglobalbuiltins)
{ {
prinst->numtempstringsstack = prinst->numtempstrings;
(*externs->globalbuiltins[i]) (progfuncs, (struct globalvars_s *)current_progstate->globals); (*externs->globalbuiltins[i]) (progfuncs, (struct globalvars_s *)current_progstate->globals);
if (prinst->continuestatement!=-1) if (prinst->continuestatement!=-1)
{ {
@ -734,7 +742,7 @@ if (pr_typecurrent != 0)
case OP_FETCH_GBL_E: case OP_FETCH_GBL_E:
case OP_FETCH_GBL_FNC: case OP_FETCH_GBL_FNC:
i = (int)OPB->_float; 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); 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; break;
case OP_FETCH_GBL_V: case OP_FETCH_GBL_V:
i = (int)OPB->_float; 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); 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(); RUNAWAYCHECK();
st += (sofs)st->b-1; // -1 to offset the s++ 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; break;
if (!strcmp(progfuncs->stringtable+swtch->string, progfuncs->stringtable+OPA->string)) if (!strcmp(PR_StringToNative(progfuncs, swtch->string), PR_StringToNative(progfuncs, OPA->string)))
{ {
RUNAWAYCHECK(); RUNAWAYCHECK();
st += (sofs)st->b-1; // -1 to offset the s++ 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]); OPC->_float = (float)(!OPA->_vector[0] && !OPA->_vector[1] && !OPA->_vector[2]);
break; break;
case OP_NOT_S: case OP_NOT_S:
OPC->_float = (float)(!(OPA->string) || !*(OPA->string+progfuncs->stringtable)); OPC->_float = (float)(!(OPA->string) || !*PR_StringToNative(progfuncs, OPA->string));
break; break;
case OP_NOT_FNC: case OP_NOT_FNC:
OPC->_float = (float)(!(OPA->function & ~0xff000000)); OPC->_float = (float)(!(OPA->function & ~0xff000000));
@ -206,20 +206,20 @@ reeval:
OPC->_float = true; OPC->_float = true;
else if (!OPA->string) else if (!OPA->string)
{ {
if (!OPB->string || !*(OPB->string+progfuncs->stringtable)) if (!OPB->string || !*PR_StringToNative(progfuncs, OPB->string))
OPC->_float = true; OPC->_float = true;
else else
OPC->_float = false; OPC->_float = false;
} }
else if (!OPB->string) else if (!OPB->string)
{ {
if (!OPA->string || !*(OPA->string+progfuncs->stringtable)) if (!OPA->string || !*PR_StringToNative(progfuncs, OPA->string))
OPC->_float = true; OPC->_float = true;
else else
OPC->_float = false; OPC->_float = false;
} }
else 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; break;
case OP_EQ_E: case OP_EQ_E:
OPC->_float = (float)(OPA->_int == OPB->_int); OPC->_float = (float)(OPA->_int == OPB->_int);
@ -242,20 +242,20 @@ reeval:
OPC->_float = false; OPC->_float = false;
else if (!OPA->string) else if (!OPA->string)
{ {
if (!OPB->string || !*(OPB->string+progfuncs->stringtable)) if (!OPB->string || !*(PR_StringToNative(progfuncs, OPB->string)))
OPC->_float = false; OPC->_float = false;
else else
OPC->_float = true; OPC->_float = true;
} }
else if (!OPB->string) else if (!OPB->string)
{ {
if (!OPA->string || !*(OPA->string+progfuncs->stringtable)) if (!OPA->string || !*PR_StringToNative(progfuncs, OPA->string))
OPC->_float = false; OPC->_float = false;
else else
OPC->_float = true; OPC->_float = true;
} }
else 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; break;
case OP_NE_E: case OP_NE_E:
OPC->_float = (float)(OPA->_int != OPB->_int); OPC->_float = (float)(OPA->_int != OPB->_int);
@ -394,11 +394,18 @@ reeval:
#ifdef PARANOID #ifdef PARANOID
NUM_FOR_EDICT(ed); // make sure it's in range NUM_FOR_EDICT(ed); // make sure it's in range
#endif #endif
if (ed->readonly) if (!ed || ed->readonly)
{ {
pr_xstatement = st-pr_statements; pr_xstatement = st-pr_statements;
PR_RunError (progfuncs, "assignment to read-only entity in %s", progfuncs->stringtable + pr_xfunction->s_name); 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)); OPC->_int = ENGINEPOINTER((((int *)edvars(ed)) + OPB->_int + progfuncs->fieldadjust));
break; break;
@ -436,7 +443,7 @@ reeval:
case OP_IFNOTS: case OP_IFNOTS:
RUNAWAYCHECK(); RUNAWAYCHECK();
if (!OPA->string || !OPA->string[progfuncs->stringtable]) if (!OPA->string || !PR_StringToNative(progfuncs, OPA->string))
st += (sofs)st->b - 1; // offset the s++ st += (sofs)st->b - 1; // offset the s++
break; break;
@ -448,7 +455,7 @@ reeval:
case OP_IFS: case OP_IFS:
RUNAWAYCHECK(); RUNAWAYCHECK();
if (OPA->string && OPA->string[progfuncs->stringtable]) if (OPA->string && PR_StringToNative(progfuncs, OPA->string))
st += (sofs)st->b - 1; // offset the s++ st += (sofs)st->b - 1; // offset the s++
break; break;
@ -535,6 +542,7 @@ if (pr_typecurrent != 0)
progfuncs->lastcalledbuiltinnumber = i; progfuncs->lastcalledbuiltinnumber = i;
if (i < externs->numglobalbuiltins) if (i < externs->numglobalbuiltins)
{ {
prinst->numtempstringsstack = prinst->numtempstrings;
(*externs->globalbuiltins[i]) (progfuncs, (struct globalvars_s *)current_progstate->globals); (*externs->globalbuiltins[i]) (progfuncs, (struct globalvars_s *)current_progstate->globals);
if (prinst->continuestatement!=-1) if (prinst->continuestatement!=-1)
{ {
@ -734,7 +742,7 @@ if (pr_typecurrent != 0)
case OP_FETCH_GBL_E: case OP_FETCH_GBL_E:
case OP_FETCH_GBL_FNC: case OP_FETCH_GBL_FNC:
i = (int)OPB->_float; 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); 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; break;
case OP_FETCH_GBL_V: case OP_FETCH_GBL_V:
i = (int)OPB->_float; 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); 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(); RUNAWAYCHECK();
st += (sofs)st->b-1; // -1 to offset the s++ 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; break;
if (!strcmp(progfuncs->stringtable+swtch->string, progfuncs->stringtable+OPA->string)) if (!strcmp(PR_StringToNative(progfuncs, swtch->string), PR_StringToNative(progfuncs, OPA->string)))
{ {
RUNAWAYCHECK(); RUNAWAYCHECK();
st += (sofs)st->b-1; // -1 to offset the s++ 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]); OPC->_float = (float)(!OPA->_vector[0] && !OPA->_vector[1] && !OPA->_vector[2]);
break; break;
case OP_NOT_S: case OP_NOT_S:
OPC->_float = (float)(!(OPA->string) || !*(OPA->string+progfuncs->stringtable)); OPC->_float = (float)(!(OPA->string) || !*PR_StringToNative(progfuncs, OPA->string));
break; break;
case OP_NOT_FNC: case OP_NOT_FNC:
OPC->_float = (float)(!(OPA->function & ~0xff000000)); OPC->_float = (float)(!(OPA->function & ~0xff000000));
@ -206,20 +206,20 @@ reeval:
OPC->_float = true; OPC->_float = true;
else if (!OPA->string) else if (!OPA->string)
{ {
if (!OPB->string || !*(OPB->string+progfuncs->stringtable)) if (!OPB->string || !*PR_StringToNative(progfuncs, OPB->string))
OPC->_float = true; OPC->_float = true;
else else
OPC->_float = false; OPC->_float = false;
} }
else if (!OPB->string) else if (!OPB->string)
{ {
if (!OPA->string || !*(OPA->string+progfuncs->stringtable)) if (!OPA->string || !*PR_StringToNative(progfuncs, OPA->string))
OPC->_float = true; OPC->_float = true;
else else
OPC->_float = false; OPC->_float = false;
} }
else 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; break;
case OP_EQ_E: case OP_EQ_E:
OPC->_float = (float)(OPA->_int == OPB->_int); OPC->_float = (float)(OPA->_int == OPB->_int);
@ -242,20 +242,20 @@ reeval:
OPC->_float = false; OPC->_float = false;
else if (!OPA->string) else if (!OPA->string)
{ {
if (!OPB->string || !*(OPB->string+progfuncs->stringtable)) if (!OPB->string || !*(PR_StringToNative(progfuncs, OPB->string)))
OPC->_float = false; OPC->_float = false;
else else
OPC->_float = true; OPC->_float = true;
} }
else if (!OPB->string) else if (!OPB->string)
{ {
if (!OPA->string || !*(OPA->string+progfuncs->stringtable)) if (!OPA->string || !*PR_StringToNative(progfuncs, OPA->string))
OPC->_float = false; OPC->_float = false;
else else
OPC->_float = true; OPC->_float = true;
} }
else 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; break;
case OP_NE_E: case OP_NE_E:
OPC->_float = (float)(OPA->_int != OPB->_int); OPC->_float = (float)(OPA->_int != OPB->_int);
@ -394,11 +394,18 @@ reeval:
#ifdef PARANOID #ifdef PARANOID
NUM_FOR_EDICT(ed); // make sure it's in range NUM_FOR_EDICT(ed); // make sure it's in range
#endif #endif
if (ed->readonly) if (!ed || ed->readonly)
{ {
pr_xstatement = st-pr_statements; pr_xstatement = st-pr_statements;
PR_RunError (progfuncs, "assignment to read-only entity in %s", progfuncs->stringtable + pr_xfunction->s_name); 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)); OPC->_int = ENGINEPOINTER((((int *)edvars(ed)) + OPB->_int + progfuncs->fieldadjust));
break; break;
@ -436,7 +443,7 @@ reeval:
case OP_IFNOTS: case OP_IFNOTS:
RUNAWAYCHECK(); RUNAWAYCHECK();
if (!OPA->string || !OPA->string[progfuncs->stringtable]) if (!OPA->string || !PR_StringToNative(progfuncs, OPA->string))
st += (sofs)st->b - 1; // offset the s++ st += (sofs)st->b - 1; // offset the s++
break; break;
@ -448,7 +455,7 @@ reeval:
case OP_IFS: case OP_IFS:
RUNAWAYCHECK(); RUNAWAYCHECK();
if (OPA->string && OPA->string[progfuncs->stringtable]) if (OPA->string && PR_StringToNative(progfuncs, OPA->string))
st += (sofs)st->b - 1; // offset the s++ st += (sofs)st->b - 1; // offset the s++
break; break;
@ -535,6 +542,7 @@ if (pr_typecurrent != 0)
progfuncs->lastcalledbuiltinnumber = i; progfuncs->lastcalledbuiltinnumber = i;
if (i < externs->numglobalbuiltins) if (i < externs->numglobalbuiltins)
{ {
prinst->numtempstringsstack = prinst->numtempstrings;
(*externs->globalbuiltins[i]) (progfuncs, (struct globalvars_s *)current_progstate->globals); (*externs->globalbuiltins[i]) (progfuncs, (struct globalvars_s *)current_progstate->globals);
if (prinst->continuestatement!=-1) if (prinst->continuestatement!=-1)
{ {
@ -734,7 +742,7 @@ if (pr_typecurrent != 0)
case OP_FETCH_GBL_E: case OP_FETCH_GBL_E:
case OP_FETCH_GBL_FNC: case OP_FETCH_GBL_FNC:
i = (int)OPB->_float; 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); 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; break;
case OP_FETCH_GBL_V: case OP_FETCH_GBL_V:
i = (int)OPB->_float; 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); 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(); RUNAWAYCHECK();
st += (sofs)st->b-1; // -1 to offset the s++ 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; break;
if (!strcmp(progfuncs->stringtable+swtch->string, progfuncs->stringtable+OPA->string)) if (!strcmp(PR_StringToNative(progfuncs, swtch->string), PR_StringToNative(progfuncs, OPA->string)))
{ {
RUNAWAYCHECK(); RUNAWAYCHECK();
st += (sofs)st->b-1; // -1 to offset the s++ 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); 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); struct qcthread_s *PR_ForkStack (progfuncs_t *progfuncs);
void PR_ResumeThread (progfuncs_t *progfuncs, struct qcthread_s *thread); void PR_ResumeThread (progfuncs_t *progfuncs, struct qcthread_s *thread);
@ -416,7 +540,12 @@ progfuncs_t deffuncs = {
QC_RegisterFieldVar, QC_RegisterFieldVar,
0, 0,
0 0,
PR_AllocTempString,
PR_StringToProgs,
PR_StringToNative
}; };
#undef printf #undef printf

View File

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

View File

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

View File

@ -328,6 +328,16 @@ void PR_SetBuiltins(int type);
#define vars(type, name, size) type name[size] #define vars(type, name, size) type name[size]
typedef struct prinst_s { typedef struct prinst_s {
char **tempstrings;
int maxtempstrings;
int numtempstrings;
int numtempstringsstack;
char **allocedstrings;
int maxallocedstrings;
int numallocedstrings;
var(progstate_t *, pr_progstate); var(progstate_t *, pr_progstate);
#define pr_progstate prinst->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_FindGlobal32 (progfuncs_t *progfuncs, char *name);
ddef32_t *ED_GlobalAtOfs32 (progfuncs_t *progfuncs, unsigned int ofs); 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_GlobalString (progfuncs_t *progfuncs, int ofs);
char *PR_GlobalStringNoContents (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. char *tempstringbase; //for engine's use. Store your base tempstring pointer here.
int tempstringnum; //for engine's use. 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 { 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_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 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)) #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_VECTOR(o) (&((float *)pr_globals)[o])
#define G_FUNCTION(o) (*(func_t *)&((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_GetString(p,s) (s?s + p->stringtable:"")
#define PR_GetStringOfs(p,o) (G_INT(o)?G_INT(o) + 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_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 #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) if (dest == MSG_ONE)
{ {
client_t *cl = Write_GetClient(); 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 if (cl->protocol == SCP_BAD) // is a bot
return; return;
@ -571,12 +576,22 @@ void NPP_NQWriteAngle(int dest, float in) //replacement write func (nq to qw)
if (dest == MSG_ONE) if (dest == MSG_ONE)
{ {
client_t *cl = Write_GetClient(); client_t *cl = Write_GetClient();
if (cl && !ISQWCLIENT(cl)) if (!cl)
{ {
ClientReliableCheckBlock(cl, sizeof(char)); Con_Printf("msg_entity: not a client\n");
ClientReliableWrite_Angle(cl, in);
return; return;
} }
else
{
if (cl->protocol == SCP_BAD)
return;
else if (!ISQWCLIENT(cl))
{
ClientReliableCheckBlock(cl, sizeof(char));
ClientReliableWrite_Angle(cl, in);
return;
}
}
} }
else else
MSG_WriteAngle (NQWriteDest(dest), in); 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"); Con_Printf("NQWriteCoord: Messages should start with WriteByte\n");
#ifdef NQPROT #ifdef NQPROT
if (dest == MSG_ONE) { if (dest == MSG_ONE)
{
client_t *cl = Write_GetClient(); client_t *cl = Write_GetClient();
if (cl && !ISQWCLIENT(cl)) if (!cl)
{ {
ClientReliableCheckBlock(cl, sizeof(float)); Con_Printf("msg_entity: not a client\n");
ClientReliableWrite_Coord(cl, in);
return; 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); MSG_WriteCoord (NQWriteDest(dest), in);
#endif #endif
@ -627,15 +654,27 @@ void NPP_NQWriteString(int dest, char *data) //replacement write func (nq to qw)
} }
#ifdef NQPROT #ifdef NQPROT
if (dest == MSG_ONE) { if (dest == MSG_ONE)
{
client_t *cl = Write_GetClient(); client_t *cl = Write_GetClient();
if (cl && !ISQWCLIENT(cl)) if (!cl)
{ {
ClientReliableCheckBlock(cl, strlen(data)+1); Con_Printf("msg_entity: not a client\n");
ClientReliableWrite_String(cl, data);
return; 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); MSG_WriteString (NQWriteDest(dest), data);
#endif #endif
@ -668,15 +707,27 @@ void NPP_NQWriteEntity(int dest, short data) //replacement write func (nq to qw)
data = svs.clients[data-1].viewent; data = svs.clients[data-1].viewent;
#ifdef NQPROT #ifdef NQPROT
if (dest == MSG_ONE) { if (dest == MSG_ONE)
{
client_t *cl = Write_GetClient(); client_t *cl = Write_GetClient();
if (cl && !ISQWCLIENT(cl)) if (!cl)
{ {
ClientReliableCheckBlock(cl, sizeof(short)); Con_Printf("msg_entity: not a client\n");
ClientReliableWrite_Short(cl, data);
return; 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); MSG_WriteShort (NQWriteDest(dest), data);
#endif #endif
@ -961,6 +1012,7 @@ void NPP_QWCheckDest(int dest)
} }
cldest = cl; cldest = cl;
*/ */
cldest = NULL;
} }
else else
{ {
@ -985,16 +1037,21 @@ void NPP_QWWriteByte(int dest, qbyte data) //replacement write func (nq to qw)
if (dest == MSG_ONE) if (dest == MSG_ONE)
{ {
client_t *cl = Write_GetClient(); 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)); ClientReliableCheckBlock(cl, sizeof(qbyte));
ClientReliableWrite_Byte(cl, data); ClientReliableWrite_Byte(cl, data);
return; return;
} }
else if (cl->protocol == SCP_BAD) // is a bot
return;
} }
} }
else else
@ -1218,15 +1275,27 @@ void NPP_QWWriteString(int dest, char *data) //replacement write func (nq to qw)
NPP_QWCheckDest(dest); NPP_QWCheckDest(dest);
#ifdef NQPROT #ifdef NQPROT
if (dest == MSG_ONE) { if (dest == MSG_ONE)
{
client_t *cl = Write_GetClient(); client_t *cl = Write_GetClient();
if (cl && ISQWCLIENT(cl)) if (!cl)
{ {
ClientReliableCheckBlock(cl, strlen(data)+1); Con_Printf("msg_entity: not a client\n");
ClientReliableWrite_String(cl, data);
return; 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); MSG_WriteString (QWWriteDest(dest), data);
#endif #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_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_tempstringsize = SCVAR("pr_tempstringsize", "4096");
cvar_t pr_droptofloorunits = SCVAR("pr_droptofloorunits", ""); 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_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_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_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 #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 MAX_TEMPSTRS ((int)pr_tempstringcount.value)
#define MAXTEMPBUFFERLEN ((int)pr_tempstringsize.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) string_t PR_TempString(progfuncs_t *prinst, char *str)
{ {
char *tmp; char *tmp;
if (!prinst->tempstringbase)
return prinst->TempString(prinst, str);
if (!str || !*str) if (!str || !*str)
return 0; 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); Q_strncpyz(tmp, str, MAXTEMPBUFFERLEN);
return tmp - prinst->stringtable; return tmp - prinst->stringtable;
} }
void PF_InitTempStrings(progfuncs_t *prinst) void PF_InitTempStrings(progfuncs_t *prinst)
{ {
if (pr_tempstringcount.value < 2) if (pr_tempstringcount.value > 0 && pr_tempstringcount.value < 2)
pr_tempstringcount.value = 2; pr_tempstringcount.value = 2;
if (pr_tempstringsize.value < 256) if (pr_tempstringsize.value < 256)
pr_tempstringsize.value = 256; pr_tempstringsize.value = 256;
pr_tempstringcount.flags |= CVAR_NOSET; pr_tempstringcount.flags |= CVAR_NOSET;
pr_tempstringsize.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; prinst->tempstringnum = 0;
} }
void PF_ftos (progfuncs_t *prinst, struct globalvars_s *pr_globals) void PF_ftos (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{ {
float v; float v;
char *pr_string_temp = PF_TempStr(prinst); char pr_string_temp[64];
v = G_FLOAT(OFS_PARM0); v = G_FLOAT(OFS_PARM0);
if (v == (int)v) 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) 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]); 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); 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]; t = ((string_t *)ed->v)[f];
if (!t) if (!t)
continue; continue;
if (!strcmp(t+prinst->stringtable,s)) if (!strcmp(PR_GetString(prinst, t),s))
{ {
RETURN_EDICT(prinst, ed); RETURN_EDICT(prinst, ed);
return; return;
@ -5190,7 +5194,6 @@ void PF_infokey (progfuncs_t *prinst, struct globalvars_s *pr_globals)
char *value; char *value;
char *key; char *key;
char ov[256]; char ov[256];
char *dest;
e = G_EDICT(prinst, OFS_PARM0); e = G_EDICT(prinst, OFS_PARM0);
e1 = NUM_FOR_EDICT(prinst, e); e1 = NUM_FOR_EDICT(prinst, e);
@ -5236,9 +5239,7 @@ void PF_infokey (progfuncs_t *prinst, struct globalvars_s *pr_globals)
} else } else
value = ""; value = "";
dest = PF_TempStr(prinst); G_INT(OFS_RETURN) = PR_TempString(prinst, value);
strcpy(dest, value);
RETURN_CSTRING(dest);
} }
/* /*
@ -5486,7 +5487,7 @@ void PF_substring (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{ {
int i, start, length; int i, start, length;
char *s; char *s;
char *string = PF_TempStr(prinst); char string[4096];
s = PR_GetStringOfs(prinst, OFS_PARM0); s = PR_GetStringOfs(prinst, OFS_PARM0);
start = G_FLOAT(OFS_PARM1); 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] = *s;
string[i] = 0; 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; int i;
char *string = PF_TempStr(prinst); char string[16];
for (i = 0; i < *prinst->callargc; i++) for (i = 0; i < *prinst->callargc; i++)
string[i] = G_FLOAT(OFS_PARM0 + i*3); string[i] = G_FLOAT(OFS_PARM0 + i*3);
string[i] = '\0'; string[i] = '\0';
RETURN_SSTRING(string); RETURN_TSTRING(string);
} }
static int chrconv_number(int i, int base, int conv) 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); unsigned char *string = PF_VarString(prinst, 3, pr_globals);
int len = strlen(string); int len = strlen(string);
int i; int i;
unsigned char *result = PF_TempStr(prinst); unsigned char resbuf[8192];
unsigned char *resbuf = result; unsigned char *result = resbuf;
if (len >= MAXTEMPBUFFERLEN) if (len >= MAXTEMPBUFFERLEN)
len = MAXTEMPBUFFERLEN-1; 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... if (*string >= '0' && *string <= '9') //normal numbers...
*result = chrconv_number(*string, '0', redchars); *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 *info = PR_GetStringOfs(prinst, OFS_PARM0);
char *key = PR_GetStringOfs(prinst, OFS_PARM1); char *key = PR_GetStringOfs(prinst, OFS_PARM1);
char *value = PF_VarString(prinst, 2, pr_globals); char *value = PF_VarString(prinst, 2, pr_globals);
char *temp; char temp[8192];
temp = PF_TempStr(prinst);
Q_strncpyz(temp, info, MAXTEMPBUFFERLEN); Q_strncpyz(temp, info, MAXTEMPBUFFERLEN);
Info_SetValueForStarKey(temp, key, value, MAXTEMPBUFFERLEN); Info_SetValueForStarKey(temp, key, value, MAXTEMPBUFFERLEN);
RETURN_SSTRING(temp); RETURN_TSTRING(temp);
} }
//uses qw style \key\value strings //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 *info = PR_GetStringOfs(prinst, OFS_PARM0);
char *key = PR_GetStringOfs(prinst, OFS_PARM1); char *key = PR_GetStringOfs(prinst, OFS_PARM1);
char *temp;
key = Info_ValueForKey(info, key); key = Info_ValueForKey(info, key);
temp = PF_TempStr(prinst); RETURN_TSTRING(key);
strcpy(temp, key);
RETURN_SSTRING(temp);
} }
//back to frik_file support. //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; char c, *s, *o, *max;
int fnum = G_FLOAT(OFS_PARM0) - FIRST_QC_FILE_INDEX; 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'; *pr_string_temp = '\0';
RETURN_SSTRING(pr_string_temp); G_INT(OFS_RETURN) = 0; //EOF
if (fnum < 0 || fnum >= MAX_QC_FILES) if (fnum < 0 || fnum >= MAX_QC_FILES)
{ {
PR_BIError(prinst, "PF_fgets: File out of range\n"); 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) if (!pr_string_temp[0] && !*s)
G_INT(OFS_RETURN) = 0; //EOF G_INT(OFS_RETURN) = 0; //EOF
else 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) 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) if (num < 0 || num >= s->entries)
return; return;
G_INT(OFS_RETURN) = (int)(s->names[num] - prinst->stringtable); RETURN_TSTRING(s->names[num]);
return; 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; 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); int i = G_FLOAT(OFS_PARM0);
if (i < 0) if (i < 0)
{ {
@ -6586,8 +6582,7 @@ void PF_ArgV (progfuncs_t *prinst, struct globalvars_s *pr_globals) //86 /
G_INT(OFS_RETURN) = 0; G_INT(OFS_RETURN) = 0;
return; return;
} }
strcpy(dest, Cmd_Argv(i)); RETURN_TSTRING(Cmd_Argv(i));
RETURN_CSTRING(dest);
} }
/* /*
@ -6613,7 +6608,7 @@ string substr(string str, float start, float len)
void PF_substr (progfuncs_t *prinst, struct globalvars_s *pr_globals) void PF_substr (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{ {
char *dest; char dest[4096];
char *s; char *s;
int start, len, l; int start, len, l;
@ -6627,7 +6622,6 @@ void PF_substr (progfuncs_t *prinst, struct globalvars_s *pr_globals)
RETURN_TSTRING(""); RETURN_TSTRING("");
return; return;
} }
dest = PF_TempStr(prinst);
s += start; s += start;
l -= start; l -= start;
@ -6635,6 +6629,9 @@ void PF_substr (progfuncs_t *prinst, struct globalvars_s *pr_globals)
if (len > l + 1) if (len > l + 1)
len = l + 1; len = l + 1;
if (len > sizeof(dest)-1)
len = sizeof(dest)-1;
Q_strncpyz(dest, s, len + 1); Q_strncpyz(dest, s, len + 1);
RETURN_TSTRING(dest); RETURN_TSTRING(dest);
@ -6650,7 +6647,7 @@ string strcat(string str1, string str2)
void PF_strcat (progfuncs_t *prinst, struct globalvars_s *pr_globals) 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); char *src = PF_VarString(prinst, 0, pr_globals);
Q_strncpyz(dest, src, MAXTEMPBUFFERLEN); Q_strncpyz(dest, src, MAXTEMPBUFFERLEN);
RETURN_TSTRING(dest); RETURN_TSTRING(dest);
@ -6666,12 +6663,11 @@ string strcat(float pad, string str1, ...)
void PF_strpad (progfuncs_t *prinst, struct globalvars_s *pr_globals) 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); int pad = G_FLOAT(OFS_PARM0);
char *src = PF_VarString(prinst, 1, pr_globals); char *src = PF_VarString(prinst, 1, pr_globals);
RETURN_TSTRING(dest);
if (pad < 0) if (pad < 0)
{ //pad left { //pad left
pad = -pad - strlen(src); pad = -pad - strlen(src);
@ -6702,6 +6698,8 @@ void PF_strpad (progfuncs_t *prinst, struct globalvars_s *pr_globals)
*dest++ = ' '; *dest++ = ' ';
*dest = '\0'; *dest = '\0';
} }
RETURN_TSTRING(destbuf);
} }
/* /*
@ -6804,7 +6802,6 @@ void PF_calltimeofday (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{ {
date_t date; date_t date;
func_t f; func_t f;
char *ret = PF_TempStr(prinst);
f = PR_FindFunction(svprogfuncs, "timeofday", PR_ANY); f = PR_FindFunction(svprogfuncs, "timeofday", PR_ANY);
if (f) 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_PARM3) = (float)date.day;
G_FLOAT(OFS_PARM4) = (float)date.mon; G_FLOAT(OFS_PARM4) = (float)date.mon;
G_FLOAT(OFS_PARM5) = (float)date.year; G_FLOAT(OFS_PARM5) = (float)date.year;
strcpy(ret, date.str); G_INT(OFS_PARM6) = (int)PR_TempString(prinst, date.str);
G_INT(OFS_PARM6) = (int)PR_SetString(prinst, ret);
PR_ExecuteProgram(prinst, f); 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 //string(entity ent) etos = #65
void PF_etos (progfuncs_t *prinst, struct globalvars_s *pr_globals) void PF_etos (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{ {
char *s; char s[64];
s = PF_TempStr(prinst); snprintf (s, sizeof(s), "entity %i", G_EDICTNUM(prinst, OFS_PARM0));
sprintf (s, "entity %i", G_EDICTNUM(prinst, OFS_PARM0)); RETURN_TSTRING(s);
G_INT(OFS_RETURN) = (int)PR_SetString(prinst, s);
} }