mirror of
https://github.com/nzp-team/fteqw.git
synced 2024-11-10 14:42:13 +00:00
Fixed an issue with fteqw's pr_fixbrokenqccarrays cvar when used with mutators. Also fixed field remapping with regard to multiple fields with the same offsets.
Played around with classes a bit. Should work a bit better now. Added an extra compiler flag, to allow for fast-tracking arrays in supported engines. It uses a global to detect it, but we don't yet set that global anywhere in the loader. This will probably have issues in DP. git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@1325 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
parent
f1ec9f4952
commit
43a1890bcc
9 changed files with 138 additions and 50 deletions
|
@ -388,6 +388,8 @@ reeval:
|
|||
|
||||
//get a pointer to a field var
|
||||
case OP_ADDRESS:
|
||||
if ((unsigned)OPA->edict >= maxedicts)
|
||||
PR_RunError (progfuncs, "OP_ADDRESS references invalid entity in %s", progfuncs->stringtable + pr_xfunction->s_name);
|
||||
ed = PROG_TO_EDICT(progfuncs, OPA->edict);
|
||||
#ifdef PARANOID
|
||||
NUM_FOR_EDICT(ed); // make sure it's in range
|
||||
|
@ -407,6 +409,8 @@ reeval:
|
|||
case OP_LOAD_ENT:
|
||||
case OP_LOAD_S:
|
||||
case OP_LOAD_FNC:
|
||||
if ((unsigned)OPA->edict >= maxedicts)
|
||||
PR_RunError (progfuncs, "OP_LOAD references invalid entity in %s", progfuncs->stringtable + pr_xfunction->s_name);
|
||||
ed = PROG_TO_EDICT(progfuncs, OPA->edict);
|
||||
#ifdef PARANOID
|
||||
NUM_FOR_EDICT(ed); // make sure it's in range
|
||||
|
@ -416,6 +420,8 @@ reeval:
|
|||
break;
|
||||
|
||||
case OP_LOAD_V:
|
||||
if ((unsigned)OPA->edict >= maxedicts)
|
||||
PR_RunError (progfuncs, "OP_LOAD_V references invalid entity in %s", progfuncs->stringtable + pr_xfunction->s_name);
|
||||
ed = PROG_TO_EDICT(progfuncs, OPA->edict);
|
||||
#ifdef PARANOID
|
||||
NUM_FOR_EDICT(ed); // make sure it's in range
|
||||
|
|
|
@ -360,7 +360,7 @@ typedef struct fdef_s
|
|||
unsigned int type; // if DEF_SAVEGLOBAL bit is set
|
||||
// the variable needs to be saved in savegames
|
||||
unsigned int ofs;
|
||||
unsigned int requestedofs;
|
||||
unsigned int progsofs; //used at loading time, so maching field offsets (unions/members) are positioned at the same runtime offset.
|
||||
char * name;
|
||||
} fdef_t;
|
||||
|
||||
|
|
|
@ -1439,28 +1439,13 @@ char *SaveCallStack (progfuncs_t *progfuncs, char *s)
|
|||
sprintf(buffer, "\t\tofs%i %i // %f\n", f->parm_start+arg, *(int *)(globalbase - f->locals+arg), *(float *)(globalbase - f->locals+arg) );
|
||||
else
|
||||
{
|
||||
//__try
|
||||
//{
|
||||
if (local->type == ev_entity)
|
||||
{ //go safly.
|
||||
int n;
|
||||
sprintf(buffer, "\t\t\"%s\"\t\"entity INVALID POINTER\"\n", local->s_name+progfuncs->stringtable);
|
||||
for (n = 0; n < sv_num_edicts; n++)
|
||||
{
|
||||
if (prinst->edicttable[n] == (struct edict_s *)PROG_TO_EDICT(progfuncs, ((eval_t*)(globalbase - f->locals+arg))->edict))
|
||||
{
|
||||
sprintf(buffer, "\t\t\"%s\" \"entity %i\"\n", local->s_name+progfuncs->stringtable, n);
|
||||
break;
|
||||
}
|
||||
}
|
||||
{
|
||||
sprintf(buffer, "\t\t\"%s\" \"entity %i\"\n", local->s_name+progfuncs->stringtable, ((eval_t*)(globalbase - f->locals+arg))->edict);
|
||||
}
|
||||
else
|
||||
sprintf(buffer, "\t\t\"%s\"\t\"%s\"\n", local->s_name+progfuncs->stringtable, PR_ValueString(progfuncs, local->type, (eval_t*)(globalbase - f->locals+arg)));
|
||||
//}
|
||||
//__except(EXCEPTION_EXECUTE_HANDLER)
|
||||
//{
|
||||
// sprintf(buffer, "\t\t\"%s\" \"ILLEGAL POINTER\"\n", local->s_name+progfuncs->stringtable);
|
||||
//}
|
||||
|
||||
if (local->type == ev_vector)
|
||||
arg+=2;
|
||||
}
|
||||
|
@ -2632,6 +2617,7 @@ retry:
|
|||
if (reorg)
|
||||
reorg = (headercrc != -1);
|
||||
|
||||
QC_FlushProgsOffsets(progfuncs);
|
||||
switch(current_progstate->intsize)
|
||||
{
|
||||
case 24:
|
||||
|
@ -2662,7 +2648,7 @@ retry:
|
|||
else
|
||||
type = fld16[i].type & ~(DEF_SHARED|DEF_SAVEGLOBAL);
|
||||
|
||||
if (progfuncs->fieldadjust) //we need to make sure all fields appear in thier original place.
|
||||
if (progfuncs->fieldadjust && !pr_typecurrent) //we need to make sure all fields appear in thier original place.
|
||||
QC_RegisterFieldVar(progfuncs, type, fld16[i].s_name+pr_strings, 4*(fld16[i].ofs+progfuncs->fieldadjust), -1);
|
||||
else if (type == ev_vector) //emit vector vars early, so thier fields cannot be alocated before the vector itself. (useful against scramblers)
|
||||
{
|
||||
|
@ -2697,7 +2683,9 @@ retry:
|
|||
type = pr_types[pr_fielddefs32[i].type & ~(DEF_SHARED|DEF_SAVEGLOBAL)].type;
|
||||
else
|
||||
type = pr_fielddefs32[i].type & ~(DEF_SHARED|DEF_SAVEGLOBAL);
|
||||
if (type == ev_vector)
|
||||
if (progfuncs->fieldadjust && !pr_typecurrent) //we need to make sure all fields appear in thier original place.
|
||||
QC_RegisterFieldVar(progfuncs, type, fld16[i].s_name+pr_strings, 4*(fld16[i].ofs+progfuncs->fieldadjust), -1);
|
||||
else if (type == ev_vector)
|
||||
QC_RegisterFieldVar(progfuncs, type, pr_fielddefs32[i].s_name+pr_strings, -1, -1);
|
||||
}
|
||||
pr_fielddefs32[i].s_name += stringadjust;
|
||||
|
|
|
@ -212,7 +212,7 @@ void VARGS PR_RunError (progfuncs_t *progfuncs, char *error, ...)
|
|||
// pr_depth = 0; // dump the stack so host_error can shutdown functions
|
||||
// prinst->exitdepth = 0;
|
||||
|
||||
Abort (string);
|
||||
Abort ("%s", string);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -180,13 +180,27 @@ void QC_InitShares(progfuncs_t *progfuncs)
|
|||
progfuncs->fieldadjust = 0;
|
||||
}
|
||||
|
||||
void QC_FlushProgsOffsets(progfuncs_t *progfuncs)
|
||||
{ //sets the fields up for loading a new progs.
|
||||
//fields are matched by name to other progs
|
||||
//not by offset
|
||||
unsigned int i;
|
||||
for (i = 0; i < numfields; i++)
|
||||
field[i].progsofs = -1;
|
||||
}
|
||||
|
||||
|
||||
//called if a global is defined as a field
|
||||
//returns offset.
|
||||
|
||||
//vectors must be added before any of thier corresponding _x/y/z vars
|
||||
//in this way, even screwed up progs work.
|
||||
int QC_RegisterFieldVar(progfuncs_t *progfuncs, unsigned int type, char *name, int requestedpos, int originalofs)
|
||||
|
||||
//requestedpos is the offset the engine WILL put it at.
|
||||
//origionaloffs is used to track matching field offsets. fields with the same progs offset overlap
|
||||
|
||||
//note: we probably suffer from progs with renamed system globals.
|
||||
int QC_RegisterFieldVar(progfuncs_t *progfuncs, unsigned int type, char *name, int engineofs, int progsofs)
|
||||
{
|
||||
// progstate_t *p;
|
||||
// int pnum;
|
||||
|
@ -215,13 +229,13 @@ int QC_RegisterFieldVar(progfuncs_t *progfuncs, unsigned int type, char *name, i
|
|||
printf("Field type mismatch on %s\n", name);
|
||||
continue;
|
||||
}
|
||||
if (!progfuncs->fieldadjust && requestedpos>=0)
|
||||
if ((unsigned)requestedpos != field[i].ofs)
|
||||
if (!progfuncs->fieldadjust && engineofs>=0)
|
||||
if ((unsigned)engineofs != field[i].ofs)
|
||||
Sys_Error("Field %s at wrong offset", name);
|
||||
|
||||
if (field[i].requestedofs == -1)
|
||||
field[i].requestedofs = originalofs;
|
||||
return field[i].ofs; //got a match
|
||||
if (field[i].progsofs == -1)
|
||||
field[i].progsofs = progsofs;
|
||||
return field[i].ofs-progfuncs->fieldadjust; //got a match
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -240,29 +254,31 @@ int QC_RegisterFieldVar(progfuncs_t *progfuncs, unsigned int type, char *name, i
|
|||
fnum = numfields;
|
||||
numfields++;
|
||||
field[fnum].name = name;
|
||||
if (type == ev_vector) //resize with the following floats (this is where I think I went wrong)
|
||||
if (type == ev_vector)
|
||||
{
|
||||
char *n;
|
||||
namelen = strlen(name)+5;
|
||||
|
||||
n=PRHunkAlloc(progfuncs, namelen);
|
||||
sprintf(n, "%s_x", name);
|
||||
ofs = QC_RegisterFieldVar(progfuncs, ev_float, n, requestedpos, -1);
|
||||
ofs = QC_RegisterFieldVar(progfuncs, ev_float, n, engineofs, progsofs);
|
||||
field[fnum].ofs = ofs;
|
||||
|
||||
n=PRHunkAlloc(progfuncs, namelen);
|
||||
sprintf(n, "%s_y", name);
|
||||
QC_RegisterFieldVar(progfuncs, ev_float, n, (requestedpos==-1)?-1:(requestedpos+4), -1);
|
||||
QC_RegisterFieldVar(progfuncs, ev_float, n, (engineofs==-1)?-1:(engineofs+4), (progsofs==-1)?-1:progsofs+1);
|
||||
|
||||
n=PRHunkAlloc(progfuncs, namelen);
|
||||
sprintf(n, "%s_z", name);
|
||||
QC_RegisterFieldVar(progfuncs, ev_float, n, (requestedpos==-1)?-1:(requestedpos+8), -1);
|
||||
QC_RegisterFieldVar(progfuncs, ev_float, n, (engineofs==-1)?-1:(engineofs+8), (progsofs==-1)?-1:progsofs+2);
|
||||
}
|
||||
else if (requestedpos >= 0)
|
||||
{
|
||||
else if (engineofs >= 0)
|
||||
{ //the engine is setting up a list of required field indexes.
|
||||
|
||||
//paranoid checking of the offset.
|
||||
for (i = 0; i < numfields-1; i++)
|
||||
{
|
||||
if (field[i].ofs == (unsigned)requestedpos)
|
||||
if (field[i].ofs == ((unsigned)engineofs)*4)
|
||||
{
|
||||
if (type == ev_float && field[i].type == ev_vector) //check names
|
||||
{
|
||||
|
@ -273,12 +289,27 @@ int QC_RegisterFieldVar(progfuncs_t *progfuncs, unsigned int type, char *name, i
|
|||
Sys_Error("Duplicated offset");
|
||||
}
|
||||
}
|
||||
if (requestedpos&3)
|
||||
Sys_Error("field %s is %i&3", name, requestedpos);
|
||||
field[fnum].ofs = ofs = requestedpos/4;
|
||||
if (engineofs&3)
|
||||
Sys_Error("field %s is %i&3", name, engineofs);
|
||||
field[fnum].ofs = ofs = engineofs/4;
|
||||
}
|
||||
else
|
||||
field[fnum].ofs = ofs = fields_size/4;
|
||||
{ //we just found a new fieldname inside a progs
|
||||
field[fnum].ofs = ofs = fields_size/4; //add on the end
|
||||
|
||||
//if the progs field offset matches annother offset in the same progs, make it match up with the earlier one.
|
||||
if (progsofs>=0)
|
||||
{
|
||||
for (i = 0; i < numfields-1; i++)
|
||||
{
|
||||
if (field[i].progsofs == (unsigned)progsofs)
|
||||
{
|
||||
field[fnum].ofs = ofs = field[i].ofs;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// if (type != ev_vector)
|
||||
if (fields_size < (ofs+type_size[type])*4)
|
||||
fields_size = (ofs+type_size[type])*4;
|
||||
|
@ -287,10 +318,10 @@ int QC_RegisterFieldVar(progfuncs_t *progfuncs, unsigned int type, char *name, i
|
|||
Sys_Error("Allocated too many additional fields after ents were inited.");
|
||||
field[fnum].type = type;
|
||||
|
||||
field[fnum].requestedofs = originalofs;
|
||||
field[fnum].progsofs = progsofs;
|
||||
|
||||
//we've finished setting the structure
|
||||
return ofs;
|
||||
return ofs - progfuncs->fieldadjust;
|
||||
}
|
||||
|
||||
|
||||
|
@ -326,7 +357,10 @@ void QC_AddSharedFieldVar(progfuncs_t *progfuncs, int num, char *stringtable)
|
|||
{
|
||||
if (!strcmp(pr_fielddefs16[i].s_name+stringtable, pr_globaldefs16[num].s_name+stringtable))
|
||||
{
|
||||
*(int *)&pr_globals[pr_globaldefs16[num].ofs] = QC_RegisterFieldVar(progfuncs, pr_fielddefs16[i].type, pr_globaldefs16[num].s_name+stringtable, -1, *(int *)&pr_globals[pr_globaldefs16[num].ofs])-progfuncs->fieldadjust;
|
||||
int old = *(int *)&pr_globals[pr_globaldefs16[num].ofs];
|
||||
*(int *)&pr_globals[pr_globaldefs16[num].ofs] = QC_RegisterFieldVar(progfuncs, pr_fielddefs16[i].type, pr_globaldefs16[num].s_name+stringtable, -1, *(int *)&pr_globals[pr_globaldefs16[num].ofs]);
|
||||
|
||||
printf("Field %s %i -> %i\n", pr_globaldefs16[num].s_name+stringtable, old, *(int *)&pr_globals[pr_globaldefs16[num].ofs]);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -335,10 +369,12 @@ void QC_AddSharedFieldVar(progfuncs_t *progfuncs, int num, char *stringtable)
|
|||
|
||||
for (i = 0; i < numfields; i++)
|
||||
{
|
||||
o = field[i].requestedofs;
|
||||
o = field[i].progsofs;
|
||||
if (o == *(unsigned int *)&pr_globals[pr_globaldefs16[num].ofs])
|
||||
{
|
||||
int old = *(int *)&pr_globals[pr_globaldefs16[num].ofs];
|
||||
*(int *)&pr_globals[pr_globaldefs16[num].ofs] = field[i].ofs-progfuncs->fieldadjust;
|
||||
printf("Field %s %i -> %i\n", pr_globaldefs16[num].s_name+stringtable, old, *(int *)&pr_globals[pr_globaldefs16[num].ofs]);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -352,7 +388,7 @@ void QC_AddSharedFieldVar(progfuncs_t *progfuncs, int num, char *stringtable)
|
|||
{
|
||||
if (!strcmp(pr_fielddefs32[i].s_name+stringtable, pr_globaldefs32[num].s_name+stringtable))
|
||||
{
|
||||
*(int *)&pr_globals[pr_globaldefs32[num].ofs] = QC_RegisterFieldVar(progfuncs, pr_fielddefs32[i].type, pr_globaldefs32[num].s_name+stringtable, -1, *(int *)&pr_globals[pr_globaldefs32[num].ofs])-progfuncs->fieldadjust;
|
||||
*(int *)&pr_globals[pr_globaldefs32[num].ofs] = QC_RegisterFieldVar(progfuncs, pr_fielddefs32[i].type, pr_globaldefs32[num].s_name+stringtable, -1, *(int *)&pr_globals[pr_globaldefs32[num].ofs]);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -361,7 +397,7 @@ void QC_AddSharedFieldVar(progfuncs_t *progfuncs, int num, char *stringtable)
|
|||
|
||||
for (i = 0; i < numfields; i++)
|
||||
{
|
||||
o = field[i].requestedofs;
|
||||
o = field[i].progsofs;
|
||||
if (o == *(unsigned int *)&pr_globals[pr_globaldefs32[num].ofs])
|
||||
{
|
||||
*(int *)&pr_globals[pr_globaldefs32[num].ofs] = field[i].ofs-progfuncs->fieldadjust;
|
||||
|
|
|
@ -476,6 +476,7 @@ extern pbool flag_acc;
|
|||
extern pbool flag_caseinsensative;
|
||||
extern pbool flag_laxcasts;
|
||||
extern pbool flag_hashonly;
|
||||
extern pbool flag_fasttrackarrays;
|
||||
|
||||
extern pbool opt_overlaptemps;
|
||||
extern pbool opt_shortenifnots;
|
||||
|
|
|
@ -72,6 +72,7 @@ pbool flag_acc; //reacc like behaviour of src files (finds *.qc in start dir
|
|||
pbool flag_caseinsensative; //symbols will be matched to an insensative case if the specified case doesn't exist. This should b usable for any mod
|
||||
pbool flag_laxcasts; //Allow lax casting. This'll produce loadsa warnings of course. But allows compilation of certain dodgy code.
|
||||
pbool flag_hashonly; //Allows use of only #constant for precompiler constants, allows certain preqcc using mods to compile
|
||||
pbool flag_fasttrackarrays; //Faster arrays, dynamically detected, activated only in supporting engines.
|
||||
|
||||
pbool opt_overlaptemps; //reduce numpr_globals by reuse of temps. When they are not needed they are freed for reuse. The way this is implemented is better than frikqcc's. (This is the single most important optimisation)
|
||||
pbool opt_assignments; //STORE_F isn't used if an operation wrote to a temp.
|
||||
|
@ -3141,6 +3142,14 @@ void QCC_PR_EmitClassFromFunction(QCC_def_t *scope, char *tname)
|
|||
if (!basetype)
|
||||
QCC_PR_ParseError(ERR_INTERNAL, "Type %s was not defined...", tname);
|
||||
|
||||
|
||||
pr_scope = NULL;
|
||||
memset(basictypefield, 0, sizeof(basictypefield));
|
||||
QCC_PR_EmitFieldsForMembers(basetype);
|
||||
|
||||
|
||||
|
||||
|
||||
pr_scope = scope;
|
||||
|
||||
df = &functions[numfunctions];
|
||||
|
@ -3184,10 +3193,7 @@ void QCC_PR_EmitClassFromFunction(QCC_def_t *scope, char *tname)
|
|||
QCC_FreeTemp(QCC_PR_Statement(&pr_opcodes[OP_DONE], NULL, NULL, NULL));
|
||||
|
||||
|
||||
pr_scope = NULL;
|
||||
memset(basictypefield, 0, sizeof(basictypefield));
|
||||
QCC_PR_EmitFieldsForMembers(basetype);
|
||||
pr_scope = scope;
|
||||
|
||||
QCC_WriteAsmFunction(scope, df->first_statement, df->parm_start);
|
||||
pr.localvars = NULL;
|
||||
|
||||
|
@ -6568,6 +6574,13 @@ void QCC_PR_EmitArrayGetFunction(QCC_def_t *scope, char *arrayname)
|
|||
QCC_dstatement_t *st;
|
||||
QCC_def_t *eq;
|
||||
|
||||
QCC_def_t *fasttrackpossible;
|
||||
|
||||
if (flag_fasttrackarrays)
|
||||
fasttrackpossible = QCC_PR_GetDef(NULL, "__ext__fasttrackarrays", NULL, true, 1);
|
||||
else
|
||||
fasttrackpossible = NULL;
|
||||
|
||||
def = QCC_PR_GetDef(NULL, arrayname, NULL, false, 0);
|
||||
|
||||
if (def->arraysize >= 15 && def->type->size == 1)
|
||||
|
@ -6592,6 +6605,22 @@ void QCC_PR_EmitArrayGetFunction(QCC_def_t *scope, char *arrayname)
|
|||
|
||||
G_FUNCTION(scope->ofs) = df - functions;
|
||||
|
||||
if (fasttrackpossible)
|
||||
{
|
||||
QCC_PR_Statement(pr_opcodes+OP_IFNOT, fasttrackpossible, NULL, &st);
|
||||
//fetch_gbl takes: (float size, variant array[]), float index, variant pos
|
||||
//note that the array size is coded into the globals, one index before the array.
|
||||
def->ofs--;
|
||||
if (def->type->size >= 3)
|
||||
QCC_PR_Statement3(&pr_opcodes[OP_FETCH_GBL_V], def, index, &def_ret);
|
||||
else
|
||||
QCC_PR_Statement3(&pr_opcodes[OP_FETCH_GBL_F], def, index, &def_ret);
|
||||
def->ofs++;
|
||||
|
||||
//finish the jump
|
||||
st->b = &statements[numstatements] - st;
|
||||
}
|
||||
|
||||
if (vectortrick)
|
||||
{
|
||||
QCC_def_t *div3, *intdiv3, *ret;
|
||||
|
@ -6704,6 +6733,13 @@ void QCC_PR_EmitArraySetFunction(QCC_def_t *scope, char *arrayname)
|
|||
QCC_dfunction_t *df;
|
||||
QCC_def_t *def, *index, *value;
|
||||
|
||||
QCC_def_t *fasttrackpossible;
|
||||
|
||||
if (flag_fasttrackarrays)
|
||||
fasttrackpossible = QCC_PR_GetDef(NULL, "__ext__fasttrackarrays", NULL, true, 1);
|
||||
else
|
||||
fasttrackpossible = NULL;
|
||||
|
||||
def = QCC_PR_GetDef(NULL, arrayname, NULL, false, 0);
|
||||
pr_scope = scope;
|
||||
|
||||
|
@ -6724,6 +6760,27 @@ void QCC_PR_EmitArraySetFunction(QCC_def_t *scope, char *arrayname)
|
|||
|
||||
G_FUNCTION(scope->ofs) = df - functions;
|
||||
|
||||
if (fasttrackpossible)
|
||||
{
|
||||
QCC_dstatement_t *st;
|
||||
|
||||
QCC_PR_Statement(pr_opcodes+OP_IFNOT, fasttrackpossible, NULL, &st);
|
||||
//note that the array size is coded into the globals, one index before the array.
|
||||
|
||||
QCC_PR_Statement3(&pr_opcodes[OP_CONV_FTOI], index, NULL, index); //address stuff is integer based, but standard qc (which this accelerates in supported engines) only supports floats
|
||||
QCC_PR_SimpleStatement (OP_BOUNDCHECK, index->ofs, 0, ((int*)qcc_pr_globals)[def->ofs-1]);//annoy the programmer. :p
|
||||
if (def->type->size != 1)//shift it upwards for larger types
|
||||
QCC_PR_Statement3(&pr_opcodes[OP_MUL_I], index, QCC_MakeIntDef(def->type->size), index);
|
||||
QCC_PR_Statement3(&pr_opcodes[OP_GLOBALADDRESS], def, index, index); //comes with built in add
|
||||
if (def->type->size >= 3)
|
||||
QCC_PR_Statement3(&pr_opcodes[OP_STOREP_V], value, index, NULL); //*b = a
|
||||
else
|
||||
QCC_PR_Statement3(&pr_opcodes[OP_STOREP_F], value, index, NULL);
|
||||
|
||||
//finish the jump
|
||||
st->b = &statements[numstatements] - st;
|
||||
}
|
||||
|
||||
QCC_PR_Statement3(pr_opcodes+OP_BITAND, index, index, index);
|
||||
QCC_PR_ArraySetRecurseDivide(def, index, value, 0, def->arraysize);
|
||||
|
||||
|
|
|
@ -555,7 +555,6 @@ pbool QCC_PR_Precompiler(void)
|
|||
}
|
||||
else if (!strncmp(directive, "include", 7))
|
||||
{
|
||||
int rellen;
|
||||
char sm;
|
||||
|
||||
pr_file_p=directive+7;
|
||||
|
|
|
@ -221,6 +221,7 @@ compiler_flag_t compiler_flag[] = {
|
|||
{&flag_laxcasts, FLAG_MIDCOMPILE,"lax", "Lax type checks", "Disables many errors (generating warnings instead) when function calls or operations refer to two normally incompatable types. This is required for reacc support, and can also allow certain (evil) mods to compile that were originally written for frikqcc."}, //Allow lax casting. This'll produce loadsa warnings of course. But allows compilation of certain dodgy code.
|
||||
{&flag_hashonly, FLAG_MIDCOMPILE,"hashonly", "Hash-only constants", "Allows use of only #constant for precompiler constants, allows certain preqcc using mods to compile"},
|
||||
{&opt_logicops, FLAG_MIDCOMPILE,"lo", "Logic ops", "This changes the behaviour of your code. It generates additional if operations to early-out in if statements. With this flag, the line if (0 && somefunction()) will never call the function. It can thus be considered an optimisation. However, due to the change of behaviour, it is not considered so by fteqcc. Note that due to inprecisions with floats, this flag can cause runaway loop errors within the player walk and run functions. This code is advised:\nplayer_stand1:\n if (self.velocity_x || self.velocity_y)\nplayer_run\n if (!(self.velocity_x || self.velocity_y))"},
|
||||
{&flag_fasttrackarrays, FLAG_MIDCOMPILE,"fastarrays", "fast arrays where possible", "Generates extra instructions inside array handling functions to detect engine and use extension opcodes in supporting engines.\nAdds a global which is set by the engine if the engine supports the extra opcodes. Note that this applies to al lor none."}, //correction for if(string) no-ifstring to get the standard behaviour.
|
||||
{NULL}
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in a new issue