progs version 3 support in qclib, attempt fix qtest traceline

git-svn-id: https://svn.code.sf.net/p/fteqw/code/branches/wip@3745 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
TimeServ 2011-03-04 13:59:06 +00:00
parent b558134529
commit 2fba86e3a0
11 changed files with 394 additions and 225 deletions

View File

@ -232,15 +232,16 @@ func_t PR_FindFunc(progfuncs_t *progfuncs, char *funcname, progsnum_t pnum)
{
ddef16_t *var16;
ddef32_t *var32;
switch(pr_progstate[pnum].intsize)
switch(pr_progstate[pnum].structtype)
{
case 24:
case 16:
case PST_KKQWSV:
case PST_DEFAULT:
var16 = ED_FindTypeGlobalFromProgs16(progfuncs, funcname, pnum, ev_function); //we must make sure we actually have a function def - 'light' is defined as a field before it is defined as a function.
if (!var16)
return (f - pr_progstate[pnum].functions) | (pnum << 24);
return *(int *)&pr_progstate[pnum].globals[var16->ofs];
case 32:
return *(int *)&pr_progstate[pnum].globals[var16->ofs];
case PST_QTEST:
case PST_FTE32:
var32 = ED_FindTypeGlobalFromProgs32(progfuncs, funcname, pnum, ev_function); //we must make sure we actually have a function def - 'light' is defined as a field before it is defined as a function.
if (!var32)
return (f - pr_progstate[pnum].functions) | (pnum << 24);
@ -273,15 +274,16 @@ eval_t *PR_FindGlobal(progfuncs_t *progfuncs, char *globname, progsnum_t pnum)
}
if (pnum < 0 || (unsigned)pnum >= maxprogs || !pr_progstate[pnum].progs)
return NULL;
switch(pr_progstate[pnum].intsize)
switch(pr_progstate[pnum].structtype)
{
case 16:
case 24:
case PST_DEFAULT:
case PST_KKQWSV:
if (!(var16 = ED_FindGlobalFromProgs16(progfuncs, globname, pnum)))
return NULL;
return (eval_t *)&pr_progstate[pnum].globals[var16->ofs];
case 32:
case PST_QTEST:
case PST_FTE32:
if (!(var32 = ED_FindGlobalFromProgs32(progfuncs, globname, pnum)))
return NULL;

View File

@ -353,6 +353,37 @@ enum {
OP_NUMOPS
};
#define MAX_PARMS 8
// qtest structs (used for reordering and not execution)
typedef struct qtest_statement_s
{
unsigned int line; // line number in source code file
unsigned short op;
unsigned short a,b,c;
} qtest_statement_t;
typedef struct qtest_def_s
{
unsigned int type; // no DEFGLOBAL found in qtest progs
unsigned int s_name; // different order!
unsigned int ofs;
} qtest_def_t;
typedef struct qtest_function_s
{
int first_statement;
int unused1;
int locals; // assumed! (always 0 in real qtest progs)
int profile; // assumed! (always 0 in real qtest progs)
int s_name;
int s_file;
int numparms;
int parm_start; // different order
int parm_size[MAX_PARMS]; // ints instead of bytes...
} qtest_function_t;
#ifndef COMPILER
typedef struct statement16_s
@ -430,8 +461,6 @@ typedef struct QCC_ddef32_s
#define DEF_SAVEGLOBAL (1<<15)
#define DEF_SHARED (1<<14)
#define MAX_PARMS 8
#ifndef COMPILER
typedef struct
{
@ -464,7 +493,7 @@ typedef struct
} QCC_dfunction_t;
#endif
#define PROG_QTESTVERSION 3
#define PROG_VERSION 6
#define PROG_KKQWSVVERSION 7
#define PROG_EXTENDEDVERSION 7

View File

@ -305,17 +305,18 @@ unsigned int ED_FindGlobalOfs (progfuncs_t *progfuncs, char *name)
{
ddef16_t *d16;
ddef32_t *d32;
switch(current_progstate->intsize)
switch(current_progstate->structtype)
{
case 24:
case 16:
case PST_KKQWSV:
case PST_DEFAULT:
d16 = ED_FindGlobal16(progfuncs, name);
return d16?d16->ofs:0;
case 32:
case PST_QTEST:
case PST_FTE32:
d32 = ED_FindGlobal32(progfuncs, name);
return d32?d32->ofs:0;
}
Sys_Error("ED_FindGlobalOfs - bad intsize");
Sys_Error("ED_FindGlobalOfs - bad struct type");
return 0;
}
@ -398,22 +399,23 @@ unsigned int *ED_FindGlobalOfsFromProgs (progfuncs_t *progfuncs, char *name, pro
ddef16_t *def16;
ddef32_t *def32;
static unsigned int pos;
switch(pr_progstate[prnum].intsize)
switch(pr_progstate[prnum].structtype)
{
case 16:
case 24:
case PST_DEFAULT:
case PST_KKQWSV:
def16 = ED_FindTypeGlobalFromProgs16(progfuncs, name, prnum, type);
if (!def16)
return NULL;
pos = def16->ofs;
return &pos;
case 32:
case PST_QTEST:
case PST_FTE32:
def32 = ED_FindTypeGlobalFromProgs32(progfuncs, name, prnum, type);
if (!def32)
return NULL;
return &def32->ofs;
}
Sys_Error("ED_FindGlobalOfsFromProgs - bad intsize");
Sys_Error("ED_FindGlobalOfsFromProgs - bad struct type");
return 0;
}
@ -804,10 +806,10 @@ char *PR_GlobalString (progfuncs_t *progfuncs, int ofs)
void *val;
static char line[128];
switch (current_progstate->intsize)
switch (current_progstate->structtype)
{
case 16:
case 24:
case PST_DEFAULT:
case PST_KKQWSV:
val = (void *)&pr_globals[ofs];
def16 = ED_GlobalAtOfs16(progfuncs, ofs);
if (!def16)
@ -823,7 +825,8 @@ char *PR_GlobalString (progfuncs_t *progfuncs, int ofs)
strcat (line," ");
strcat (line," ");
return line;
case 32:
case PST_QTEST:
case PST_FTE32:
val = (void *)&pr_globals[ofs];
def32 = ED_GlobalAtOfs32(progfuncs, ofs);
if (!def32)
@ -840,7 +843,7 @@ char *PR_GlobalString (progfuncs_t *progfuncs, int ofs)
strcat (line," ");
return line;
}
Sys_Error("Bad offset size in PR_GlobalString");
Sys_Error("Bad struct type in PR_GlobalString");
return "";
}
@ -851,17 +854,18 @@ char *PR_GlobalStringNoContents (progfuncs_t *progfuncs, int ofs)
ddef32_t *def32;
static char line[128];
switch (current_progstate->intsize)
switch (current_progstate->structtype)
{
case 16:
case 24:
case PST_DEFAULT:
case PST_KKQWSV:
def16 = ED_GlobalAtOfs16(progfuncs, ofs);
if (!def16)
sprintf (line,"%i(?""?""?)", ofs);
else
sprintf (line,"%i(%s)", ofs, def16->s_name+progfuncs->stringtable);
break;
case 32:
case PST_QTEST:
case PST_FTE32:
def32 = ED_GlobalAtOfs32(progfuncs, ofs);
if (!def32)
sprintf (line,"%i(?""?""?)", ofs);
@ -869,7 +873,7 @@ char *PR_GlobalStringNoContents (progfuncs_t *progfuncs, int ofs)
sprintf (line,"%i(%s)", ofs, def32->s_name+progfuncs->stringtable);
break;
default:
Sys_Error("Bad offset size in PR_GlobalStringNoContents");
Sys_Error("Bad struct type in PR_GlobalStringNoContents");
}
i = strlen(line);
@ -1041,7 +1045,7 @@ Can parse either fields or globals
returns false if error
=============
*/
pbool ED_ParseEpair (progfuncs_t *progfuncs, void *base, ddefXX_t *key, char *s, int bits)
pbool ED_ParseEpair (progfuncs_t *progfuncs, void *base, ddefXX_t *key, char *s, int structtype)
{
int i;
char string[128];
@ -1053,9 +1057,9 @@ pbool ED_ParseEpair (progfuncs_t *progfuncs, void *base, ddefXX_t *key, char *s,
int type;
switch(bits)
switch(structtype)
{
case 16:
case PST_DEFAULT:
d = (void *)((int *)base + ((ddef16_t*)key)->ofs);
if (pr_types)
@ -1063,7 +1067,7 @@ pbool ED_ParseEpair (progfuncs_t *progfuncs, void *base, ddefXX_t *key, char *s,
else
type = ((ddef16_t*)key)->type & ~DEF_SAVEGLOBAL;
break;
case 32:
case PST_FTE32:
d = (void *)((int *)base + ((ddef32_t*)key)->ofs);
if (pr_types)
@ -1072,7 +1076,7 @@ pbool ED_ParseEpair (progfuncs_t *progfuncs, void *base, ddefXX_t *key, char *s,
type = ((ddef32_t*)key)->type & ~DEF_SAVEGLOBAL;
break;
default:
Sys_Error("Bad bits in ED_ParseEpair");
Sys_Error("Bad struct type in ED_ParseEpair");
d = 0;
}
@ -1248,7 +1252,7 @@ char *ED_ParseEdict (progfuncs_t *progfuncs, char *data, edictrun_t *ent)
}
cont:
if (!ED_ParseEpair (progfuncs, ent->fields, (ddefXX_t*)key, qcc_token, 32))
if (!ED_ParseEpair (progfuncs, ent->fields, (ddefXX_t*)key, qcc_token, PST_FTE32))
{
continue;
// Sys_Error ("ED_ParseEdict: parse error on entities");
@ -1290,10 +1294,10 @@ char *ED_WriteGlobals(progfuncs_t *progfuncs, char *buffer) //switch first.
int type;
int curprogs = pr_typecurrent;
int len;
switch(current_progstate->intsize)
switch(current_progstate->structtype)
{
case 16:
case 24:
case PST_DEFAULT:
case PST_KKQWSV:
for (i=0 ; i<pr_progs->numglobaldefs ; i++)
{
def16 = &pr_globaldefs16[i];
@ -1358,7 +1362,8 @@ char *ED_WriteGlobals(progfuncs_t *progfuncs, char *buffer) //switch first.
AddS (qcva("\"%s\"\n", PR_UglyValueString(progfuncs, def16->type&~DEF_SAVEGLOBAL, (eval_t *)v)));
}
break;
case 32:
case PST_QTEST:
case PST_FTE32:
for (i=0 ; i<pr_progs->numglobaldefs ; i++)
{
def32 = &pr_globaldefs32[i];
@ -1412,7 +1417,7 @@ add32:
}
break;
default:
Sys_Error("Bad number of bits in SaveEnts");
Sys_Error("Bad struct type in SaveEnts");
}
return buffer;
@ -1881,10 +1886,10 @@ int LoadEnts(progfuncs_t *progfuncs, char *file, float killonspawnflags)
else if (!qcc_token[0] || !file)
Sys_Error("EOF when parsing global values");
switch(current_progstate->intsize)
switch(current_progstate->structtype)
{
case 16:
case 24:
case PST_DEFAULT:
case PST_KKQWSV:
if (!(d16 = ED_FindGlobal16(progfuncs, qcc_token)))
{
file = QCC_COM_Parse(file);
@ -1893,10 +1898,11 @@ int LoadEnts(progfuncs_t *progfuncs, char *file, float killonspawnflags)
else
{
file = QCC_COM_Parse(file);
ED_ParseEpair(progfuncs, pr_globals, (ddefXX_t*)d16, qcc_token, 16);
ED_ParseEpair(progfuncs, pr_globals, (ddefXX_t*)d16, qcc_token, PST_DEFAULT);
}
break;
case 32:
case PST_QTEST:
case PST_FTE32:
if (!(d32 = ED_FindGlobal32(progfuncs, qcc_token)))
{
file = QCC_COM_Parse(file);
@ -1905,11 +1911,11 @@ int LoadEnts(progfuncs_t *progfuncs, char *file, float killonspawnflags)
else
{
file = QCC_COM_Parse(file);
ED_ParseEpair(progfuncs, pr_globals, (ddefXX_t*)d32, qcc_token, 32);
ED_ParseEpair(progfuncs, pr_globals, (ddefXX_t*)d32, qcc_token, PST_FTE32);
}
break;
default:
Sys_Error("Bad intsize in LoadEnts");
Sys_Error("Bad struct type in LoadEnts");
}
}
@ -1979,10 +1985,10 @@ int LoadEnts(progfuncs_t *progfuncs, char *file, float killonspawnflags)
else if (!qcc_token[0] || !file)
Sys_Error("EOF when parsing global values");
switch(current_progstate->intsize)
switch(current_progstate->structtype)
{
case 16:
case 24:
case PST_DEFAULT:
case PST_KKQWSV:
if (!(d16 = ED_FindGlobal16(progfuncs, qcc_token)))
{
file = QCC_COM_Parse(file);
@ -1991,10 +1997,11 @@ int LoadEnts(progfuncs_t *progfuncs, char *file, float killonspawnflags)
else
{
file = QCC_COM_Parse(file);
ED_ParseEpair(progfuncs, pr_globals, (ddefXX_t*)d16, qcc_token, 16);
ED_ParseEpair(progfuncs, pr_globals, (ddefXX_t*)d16, qcc_token, PST_DEFAULT);
}
break;
case 32:
case PST_QTEST:
case PST_FTE32:
if (!(d32 = ED_FindGlobal32(progfuncs, qcc_token)))
{
file = QCC_COM_Parse(file);
@ -2003,11 +2010,11 @@ int LoadEnts(progfuncs_t *progfuncs, char *file, float killonspawnflags)
else
{
file = QCC_COM_Parse(file);
ED_ParseEpair(progfuncs, pr_globals, (ddefXX_t*)d32, qcc_token, 32);
ED_ParseEpair(progfuncs, pr_globals, (ddefXX_t*)d32, qcc_token, PST_FTE32);
}
break;
default:
Sys_Error("Bad intsize in LoadEnts");
Sys_Error("Bad struct type in LoadEnts");
}
}
}
@ -2404,7 +2411,11 @@ retry:
if (pr_progs->version == PROG_VERSION)
{
// printf("Opening standard progs file \"%s\"\n", filename);
current_progstate->intsize = 16;
current_progstate->structtype = PST_DEFAULT;
}
else if (pr_progs->version == PROG_QTESTVERSION)
{
current_progstate->structtype = PST_QTEST;
}
else if (pr_progs->version == PROG_EXTENDEDVERSION)
{
@ -2415,17 +2426,17 @@ retry:
if (pr_progs->secondaryversion == PROG_SECONDARYVERSION16)
{
// printf("Opening 16bit fte progs file \"%s\"\n", filename);
current_progstate->intsize = 16;
current_progstate->structtype = PST_DEFAULT;
}
else if (pr_progs->secondaryversion == PROG_SECONDARYVERSION32)
{
// printf("Opening 32bit fte progs file \"%s\"\n", filename);
current_progstate->intsize = 32;
current_progstate->structtype = PST_FTE32;
}
else
{
// printf("Opening KK7 progs file \"%s\"\n", filename);
current_progstate->intsize = 24; //KK progs. Yuck. Disabling saving would be a VERY good idea.
current_progstate->structtype = PST_KKQWSV; //KK progs. Yuck. Disabling saving would be a VERY good idea.
pr_progs->version = PROG_VERSION; //not fte.
}
/* else
@ -2500,16 +2511,16 @@ retry:
//start decompressing stuff...
if (pr_progs->blockscompressed & 1) //statements
{
switch(current_progstate->intsize)
switch(current_progstate->structtype)
{
case 16:
case PST_DEFAULT:
len=sizeof(dstatement16_t)*pr_progs->numstatements;
break;
case 32:
case PST_FTE32:
len=sizeof(dstatement32_t)*pr_progs->numstatements;
break;
default:
Sys_Error("Bad intsize");
Sys_Error("Bad struct type");
}
s = PRHunkAlloc(progfuncs, len);
QC_decode(progfuncs, PRLittleLong(*(int *)pr_statements16), len, 2, (char *)(((int *)pr_statements16)+1), s);
@ -2518,16 +2529,16 @@ retry:
}
if (pr_progs->blockscompressed & 2) //global defs
{
switch(current_progstate->intsize)
switch(current_progstate->structtype)
{
case 16:
case PST_DEFAULT:
len=sizeof(ddef16_t)*pr_progs->numglobaldefs;
break;
case 32:
case PST_FTE32:
len=sizeof(ddef32_t)*pr_progs->numglobaldefs;
break;
default:
Sys_Error("Bad intsize");
Sys_Error("Bad struct type");
}
s = PRHunkAlloc(progfuncs, len);
QC_decode(progfuncs, PRLittleLong(*(int *)pr_globaldefs16), len, 2, (char *)(((int *)pr_globaldefs16)+1), s);
@ -2536,16 +2547,16 @@ retry:
}
if (pr_progs->blockscompressed & 4) //fields
{
switch(current_progstate->intsize)
switch(current_progstate->structtype)
{
case 16:
case PST_DEFAULT:
len=sizeof(ddef16_t)*pr_progs->numglobaldefs;
break;
case 32:
case PST_FTE32:
len=sizeof(ddef32_t)*pr_progs->numglobaldefs;
break;
default:
Sys_Error("Bad intsize");
Sys_Error("Bad struct type");
}
s = PRHunkAlloc(progfuncs, len);
QC_decode(progfuncs, PRLittleLong(*(int *)pr_fielddefs16), len, 2, (char *)(((int *)pr_fielddefs16)+1), s);
@ -2659,40 +2670,47 @@ retry:
current_progstate->edict_size = pr_progs->entityfields * 4 + externs->edictsize;
// byte swap the lumps
for (i=0 ; i<pr_progs->numfunctions; i++)
switch(current_progstate->structtype)
{
#ifndef NOENDIAN
fnc[i].first_statement = PRLittleLong (fnc[i].first_statement);
fnc[i].parm_start = PRLittleLong (fnc[i].parm_start);
fnc[i].s_name = (string_t)PRLittleLong ((long)fnc[i].s_name);
fnc[i].s_file = (string_t)PRLittleLong ((long)fnc[i].s_file);
fnc[i].numparms = PRLittleLong (fnc[i].numparms);
fnc[i].locals = PRLittleLong (fnc[i].locals);
#endif
/* if (!strncmp(fnc[i].s_name+pr_strings, "ext_", 4))
case PST_QTEST:
// qtest needs a struct remap
for (i=0 ; i<pr_progs->numfunctions; i++)
{
for (eb = extensionbuiltin; eb; eb = eb->prev)
{
if (*eb->name == '_')
{
if (!strncmp(fnc[i].s_name+pr_strings+4, eb->name+1, strlen(eb->name+1)))
{
fnc[i].first_statement = -0x7fffffff;
*(void**)&fnc[i].profile = (void*)eb->func;
break;
}
}
else if (!strcmp(fnc[i].s_name+4, eb->name))
{
fnc[i].first_statement = -0x7fffffff;
*(void**)&fnc[i].profile = (void*)eb->func;
break;
}
}
int j;
qtest_function_t qtfunc = ((qtest_function_t*)fnc)[i];
fnc[i].first_statement = PRLittleLong (qtfunc.first_statement);
fnc[i].parm_start = PRLittleLong (qtfunc.parm_start);
fnc[i].s_name = (string_t)PRLittleLong (qtfunc.s_name);
fnc[i].s_file = (string_t)PRLittleLong (qtfunc.s_file);
fnc[i].numparms = PRLittleLong (qtfunc.numparms);
fnc[i].locals = PRLittleLong (qtfunc.locals);
for (j=0; j<MAX_PARMS;j++)
fnc[i].parm_size[j] = PRLittleLong (qtfunc.parm_size[j]);
fnc[i].s_name += stringadjust;
fnc[i].s_file += stringadjust;
}
*/
fnc[i].s_name += stringadjust;
fnc[i].s_file += stringadjust;
break;
case PST_KKQWSV:
case PST_DEFAULT:
case PST_FTE32:
for (i=0 ; i<pr_progs->numfunctions; i++)
{
#ifndef NOENDIAN
fnc[i].first_statement = PRLittleLong (fnc[i].first_statement);
fnc[i].parm_start = PRLittleLong (fnc[i].parm_start);
fnc[i].s_name = (string_t)PRLittleLong ((long)fnc[i].s_name);
fnc[i].s_file = (string_t)PRLittleLong ((long)fnc[i].s_file);
fnc[i].numparms = PRLittleLong (fnc[i].numparms);
fnc[i].locals = PRLittleLong (fnc[i].locals);
#endif
fnc[i].s_name += stringadjust;
fnc[i].s_file += stringadjust;
}
default:
Sys_Error("Bad struct type");
}
//actual global values
@ -2722,10 +2740,10 @@ retry:
reorg = (headercrc != -1);
QC_FlushProgsOffsets(progfuncs);
switch(current_progstate->intsize)
switch(current_progstate->structtype)
{
case 24:
case 16:
case PST_KKQWSV:
case PST_DEFAULT:
//byteswap the globals and fix name offsets
for (i=0 ; i<pr_progs->numglobaldefs ; i++)
{
@ -2796,7 +2814,26 @@ retry:
}
break;
case 32:
case PST_QTEST:
// qtest needs a struct remap
for (i=0 ; i<pr_progs->numglobaldefs ; i++)
{
qtest_def_t qtdef = ((qtest_def_t *)pr_globaldefs32)[i];
pr_globaldefs32[i].type = qtdef.type;
pr_globaldefs32[i].s_name = qtdef.s_name;
pr_globaldefs32[i].ofs = qtdef.ofs;
}
for (i=0 ; i<pr_progs->numfielddefs ; i++)
{
qtest_def_t qtdef = ((qtest_def_t *)pr_fielddefs32)[i];
pr_fielddefs32[i].type = qtdef.type;
pr_fielddefs32[i].s_name = qtdef.s_name;
pr_fielddefs32[i].ofs = qtdef.ofs;
}
// passthrough
case PST_FTE32:
for (i=0 ; i<pr_progs->numglobaldefs ; i++)
{
#ifndef NOENDIAN
@ -2822,7 +2859,7 @@ retry:
else
type = pr_fielddefs32[i].type & ~(DEF_SHARED|DEF_SAVEGLOBAL);
if (progfuncs->fieldadjust && !pr_typecurrent) //we need to make sure all fields appear in their original place.
QC_RegisterFieldVar(progfuncs, type, fld16[i].s_name+pr_strings, 4*(fld16[i].ofs+progfuncs->fieldadjust), -1);
QC_RegisterFieldVar(progfuncs, type, pr_fielddefs32[i].s_name+pr_strings, 4*(pr_fielddefs32[i].ofs+progfuncs->fieldadjust), -1);
else if (type == ev_vector)
QC_RegisterFieldVar(progfuncs, type, pr_fielddefs32[i].s_name+pr_strings, -1, pr_fielddefs32[i].ofs);
}
@ -2840,14 +2877,27 @@ retry:
}
break;
default:
Sys_Error("Bad int size");
Sys_Error("Bad struct type");
}
//ifstring fixes arn't performed anymore.
//the following switch just fixes endian and hexen2 calling conventions (by using different opcodes).
switch(current_progstate->intsize)
switch(current_progstate->structtype)
{
case 16:
case PST_QTEST:
for (i=0 ; i<pr_progs->numstatements ; i++)
{
qtest_statement_t qtst = ((qtest_statement_t*)st16)[i];
st16[i].op = PRLittleShort(qtst.op);
st16[i].a = PRLittleShort(qtst.a);
st16[i].b = PRLittleShort(qtst.b);
st16[i].c = PRLittleShort(qtst.c);
// could use the line info as lno information maybe? is it really worth it?
// also never assuming h2 calling mechanism
}
break;
case PST_DEFAULT:
for (i=0 ; i<pr_progs->numstatements ; i++)
{
#ifndef NOENDIAN
@ -2861,9 +2911,7 @@ retry:
if (st16[i].b)
{
hexencalling = true;
#ifdef NOENDIAN
break;
#endif
}
}
}
@ -2877,7 +2925,8 @@ retry:
}
break;
case 24: //24 sucks. Guess why.
case PST_KKQWSV: //24 sucks. Guess why.
case PST_FTE32:
for (i=0 ; i<pr_progs->numstatements ; i++)
{
#ifndef NOENDIAN
@ -2889,33 +2938,10 @@ retry:
if (pr_statements32[i].op >= OP_CALL1 && pr_statements32[i].op <= OP_CALL8)
{
if (pr_statements32[i].b)
{
hexencalling = true;
}
}
if (hexencalling)
{
for (i=0 ; i<pr_progs->numstatements ; i++)
{
if (pr_statements32[i].op >= OP_CALL1 && pr_statements32[i].op <= OP_CALL8)
pr_statements32[i].op += OP_CALL1H - OP_CALL1;
}
}
break;
case 32:
for (i=0 ; i<pr_progs->numstatements ; i++)
{
#ifndef NOENDIAN
pr_statements32[i].op = PRLittleLong(pr_statements32[i].op);
pr_statements32[i].a = PRLittleLong(pr_statements32[i].a);
pr_statements32[i].b = PRLittleLong(pr_statements32[i].b);
pr_statements32[i].c = PRLittleLong(pr_statements32[i].c);
#endif
if (pr_statements32[i].op >= OP_CALL1 && pr_statements32[i].op <= OP_CALL8)
{
if (pr_statements32[i].b)
hexencalling = true;
break;
}
}
}
if (hexencalling)
@ -2933,7 +2959,7 @@ retry:
if (headercrc == -1)
{
isfriked = true;
if (current_progstate->intsize != 16)
if (current_progstate->structtype != PST_DEFAULT)
Sys_Error("Decompiling a bigprogs");
return true;
}
@ -2947,10 +2973,10 @@ retry:
isfriked = -1; //partly to avoid some bad progs.
// len = 0;
switch(current_progstate->intsize)
switch(current_progstate->structtype)
{
case 24:
case 16:
case PST_DEFAULT:
case PST_KKQWSV:
for (i=0 ; i<pr_progs->numglobaldefs ; i++)
{
if (pr_types)
@ -2996,7 +3022,8 @@ retry:
}
}
break;
case 32:
case PST_QTEST:
case PST_FTE32:
for (i=0 ; i<pr_progs->numglobaldefs ; i++)
{
if (pr_types)
@ -3049,7 +3076,7 @@ retry:
}
break;
default:
Sys_Error("Bad int size");
Sys_Error("Bad struct type");
}
if ((isfriked && pr_typecurrent)) //friked progs only allow one file.
@ -3071,9 +3098,9 @@ retry:
if (eval)
eval->prog = progstype;
switch(current_progstate->intsize)
switch(current_progstate->structtype)
{
case 16:
case PST_DEFAULT:
if (pr_progs->version == PROG_EXTENDEDVERSION && pr_progs->numbodylessfuncs)
{
s = &((char *)pr_progs)[pr_progs->ofsbodylessfuncs];
@ -3101,9 +3128,10 @@ retry:
}
}
break;
case 24:
case PST_QTEST:
case PST_KKQWSV:
break; //cannot happen anyway.
case 32:
case PST_FTE32:
if (pr_progs->version == PROG_EXTENDEDVERSION && pr_progs->numbodylessfuncs)
{
s = &((char *)pr_progs)[pr_progs->ofsbodylessfuncs];

View File

@ -346,10 +346,10 @@ ddef32_t *ED_FindLocalOrGlobal(progfuncs_t *progfuncs, char *name, eval_t **val)
ddef16_t *def16;
int i;
switch (pr_progstate[pr_typecurrent].intsize)
switch (pr_progstate[pr_typecurrent].structtype)
{
case 16:
case 24:
case PST_DEFAULT:
case PST_KKQWSV:
//this gets parms fine, but not locals
if (pr_xfunction)
for (i = 0; i < pr_xfunction->numparms; i++)
@ -377,7 +377,8 @@ ddef32_t *ED_FindLocalOrGlobal(progfuncs_t *progfuncs, char *name, eval_t **val)
def.s_name = def16->s_name;
def32 = &def;
break;
case 32:
case PST_QTEST:
case PST_FTE32:
//this gets parms fine, but not locals
if (pr_xfunction)
for (i = 0; i < pr_xfunction->numparms; i++)
@ -399,7 +400,7 @@ ddef32_t *ED_FindLocalOrGlobal(progfuncs_t *progfuncs, char *name, eval_t **val)
return NULL;
break;
default:
Sys_Error("Bad int size in ED_FindLocalOrGlobal");
Sys_Error("Bad struct type in ED_FindLocalOrGlobal");
def32 = NULL;
}
@ -589,17 +590,17 @@ void SetExecutionToLine(progfuncs_t *progfuncs, int linenum)
int snum;
dfunction_t *f = pr_xfunction;
switch(current_progstate->intsize)
switch(current_progstate->structtype)
{
case 16:
case PST_DEFAULT:
for (snum = f->first_statement; pr_progstate[pn].linenums[snum] < linenum; snum++)
{
if (pr_statements16[snum].op == OP_DONE)
return;
}
break;
case 24:
case 32:
case PST_KKQWSV:
case PST_FTE32:
for (snum = f->first_statement; pr_progstate[pn].linenums[snum] < linenum; snum++)
{
if (pr_statements32[snum].op == OP_DONE)
@ -607,7 +608,7 @@ void SetExecutionToLine(progfuncs_t *progfuncs, int linenum)
}
break;
default:
Sys_Error("Bad intsize");
Sys_Error("Bad struct type");
snum = 0;
}
debugstatement = snum;
@ -648,17 +649,18 @@ int PR_ToggleBreakpoint(progfuncs_t *progfuncs, char *filename, int linenum, int
if ((unsigned int)pr_progstate[pn].linenums[i] > fl)
break;
switch(pr_progstate[pn].intsize)
switch(pr_progstate[pn].structtype)
{
case 16:
case PST_DEFAULT:
case PST_QTEST:
op = ((dstatement16_t*)pr_progstate[pn].statements + i)->op;
break;
case 24:
case 32:
case PST_KKQWSV:
case PST_FTE32:
op = ((dstatement32_t*)pr_progstate[pn].statements + i)->op;
break;
default:
Sys_Error("Bad intsize");
Sys_Error("Bad structtype");
op = 0;
}
switch (flag)
@ -689,17 +691,18 @@ int PR_ToggleBreakpoint(progfuncs_t *progfuncs, char *filename, int linenum, int
if (op & 0x8000)
return true;
}
switch(pr_progstate[pn].intsize)
switch(pr_progstate[pn].structtype)
{
case 16:
case PST_DEFAULT:
case PST_QTEST:
((dstatement16_t*)pr_progstate[pn].statements + i)->op = op;
break;
case 24:
case 32:
case PST_KKQWSV:
case PST_FTE32:
((dstatement32_t*)pr_progstate[pn].statements + i)->op = op;
break;
default:
Sys_Error("Bad intsize");
Sys_Error("Bad structtype");
op = 0;
}
}
@ -716,17 +719,18 @@ int PR_ToggleBreakpoint(progfuncs_t *progfuncs, char *filename, int linenum, int
if (!strcmp(f->s_name+progfuncs->stringtable, filename))
{
i = f->first_statement;
switch(pr_progstate[pn].intsize)
switch(pr_progstate[pn].structtype)
{
case 16:
case PST_DEFAULT:
case PST_QTEST:
op = ((dstatement16_t*)pr_progstate[pn].statements + i)->op;
break;
case 24:
case 32:
case PST_KKQWSV:
case PST_FTE32:
op = ((dstatement32_t*)pr_progstate[pn].statements + i)->op;
break;
default:
Sys_Error("Bad intsize");
Sys_Error("Bad structtype");
}
switch (flag)
{
@ -756,17 +760,18 @@ int PR_ToggleBreakpoint(progfuncs_t *progfuncs, char *filename, int linenum, int
if (op & 0x8000)
return true;
}
switch(pr_progstate[pn].intsize)
switch(pr_progstate[pn].structtype)
{
case 16:
case PST_DEFAULT:
case PST_QTEST:
((dstatement16_t*)pr_progstate[pn].statements + i)->op = op;
break;
case 24:
case 32:
case PST_KKQWSV:
case PST_FTE32:
((dstatement32_t*)pr_progstate[pn].statements + i)->op = op;
break;
default:
Sys_Error("Bad intsize");
Sys_Error("Bad structtype");
}
break;
}
@ -882,9 +887,10 @@ void PR_ExecuteCode (progfuncs_t *progfuncs, int s)
restart: //jumped to when the progs might have changed.
glob = pr_globals;
switch (current_progstate->intsize)
switch (current_progstate->structtype)
{
case 16:
case PST_DEFAULT:
case PST_QTEST:
#define INTSIZE 16
st16 = &pr_statements16[s];
while (pr_trace)
@ -905,8 +911,8 @@ restart: //jumped to when the progs might have changed.
#undef INTSIZE
Sys_Error("PR_ExecuteProgram - should be unreachable");
break;
case 24:
case 32:
case PST_KKQWSV:
case PST_FTE32:
#define INTSIZE 32
st32 = &pr_statements32[s];
while (pr_trace)
@ -932,7 +938,7 @@ restart: //jumped to when the progs might have changed.
Sys_Error("PR_ExecuteProgram - should be unreachable");
break;
default:
Sys_Error("PR_ExecuteProgram - bad intsize");
Sys_Error("PR_ExecuteProgram - bad structtype");
}
}

View File

@ -358,10 +358,10 @@ void QC_AddSharedFieldVar(progfuncs_t *progfuncs, int num, char *stringtable)
}
*/
switch(current_progstate->intsize)
switch(current_progstate->structtype)
{
case 24:
case 16:
case PST_KKQWSV:
case PST_DEFAULT:
for (i=1 ; i<pr_progs->numfielddefs; i++)
{
if (!strcmp(pr_fielddefs16[i].s_name+stringtable, pr_globaldefs16[num].s_name+stringtable))
@ -392,7 +392,8 @@ void QC_AddSharedFieldVar(progfuncs_t *progfuncs, int num, char *stringtable)
// if (*(int *)&pr_globals[pr_globaldefs16[num].ofs])
// Sys_Error("QCLIB: Global field var with no matching field \"%s\", from offset %i", pr_globaldefs16[num].s_name+stringtable, *(int *)&pr_globals[pr_globaldefs16[num].ofs]);
return;
case 32:
case PST_FTE32:
case PST_QTEST:
for (i=1 ; i<pr_progs->numfielddefs; i++)
{
if (!strcmp(pr_fielddefs32[i].s_name+stringtable, pr_globaldefs32[num].s_name+stringtable))

View File

@ -160,6 +160,14 @@ void PR_StackTrace (progfuncs_t *progfuncs);
extern int noextensions;
typedef enum
{
PST_DEFAULT, //16
PST_FTE32, //32
PST_KKQWSV, //24
PST_QTEST,
} progstructtype_t;
#ifndef COMPILER
typedef struct progstate_s
{
@ -191,7 +199,7 @@ typedef struct progstate_s
int *linenums; //debug versions only
int intsize; //16 for standard (more limiting) versions
progstructtype_t structtype;
} progstate_t;
typedef struct extensionbuiltin_s {

View File

@ -63,7 +63,7 @@ extern int MAX_CONSTANTS;
#define MAXCONSTANTPARAMLENGTH 32
#define MAXCONSTANTPARAMS 32
typedef enum {QCF_STANDARD, QCF_HEXEN2, QCF_DARKPLACES, QCF_FTE, QCF_FTEDEBUG, QCF_KK7} qcc_targetformat_t;
typedef enum {QCF_STANDARD, QCF_HEXEN2, QCF_DARKPLACES, QCF_FTE, QCF_FTEDEBUG, QCF_KK7, QCF_QTEST} qcc_targetformat_t;
extern qcc_targetformat_t qcc_targetformat;

View File

@ -826,6 +826,7 @@ pbool QCC_OPCodeValid(QCC_opcode_t *op)
{
case QCF_STANDARD:
case QCF_KK7:
case QCF_QTEST:
if (num < OP_MULSTORE_F)
return true;
return false;

View File

@ -868,6 +868,8 @@ pbool QCC_PR_Precompiler(void)
qcc_targetformat = QCF_STANDARD;
else if (!QC_strcasecmp(msg, "DEBUG"))
qcc_targetformat = QCF_FTEDEBUG;
else if (!QC_strcasecmp(msg, "QTEST"))
qcc_targetformat = QCF_QTEST;
else
QCC_PR_ParseWarning(WARN_BADTARGET, "Unknown target \'%s\'. Ignored.", msg);
}

View File

@ -259,6 +259,7 @@ struct {
{QCF_FTE, "fte"},
{QCF_DARKPLACES,"darkplaces"},
{QCF_DARKPLACES,"dp"},
{QCF_QTEST, "qtest"},
{0, NULL}
};
@ -568,7 +569,7 @@ pbool QCC_WriteData (int crc)
int i, len;
pbool debugtarget = false;
pbool types = false;
int outputsize = 16;
int outputsttype = PST_DEFAULT;
pbool warnedunref = false;
if (numstatements==1 && numfunctions==1 && numglobaldefs==1 && numfielddefs==1)
@ -597,7 +598,7 @@ pbool QCC_WriteData (int crc)
if (numpr_globals > 65530 )
{
printf("Forcing target to FTE32 due to numpr_globals\n");
outputsize = 32;
outputsttype = PST_FTE32;
}
else if (qcc_targetformat == QCF_HEXEN2)
{
@ -623,7 +624,7 @@ pbool QCC_WriteData (int crc)
if (numpr_globals > 65530)
{
printf("Using 32 bit target due to numpr_globals\n");
outputsize = 32;
outputsttype = PST_FTE32;
}
if (qcc_targetformat == QCF_DARKPLACES)
@ -663,7 +664,14 @@ pbool QCC_WriteData (int crc)
printf("Warning: Saving is not supported. Ensure all engine read fields and globals are defined early on.\n");
printf("A KK compatible executor will be required (FTE/KK)\n");
outputsttype = PST_KKQWSV;
break;
case QCF_QTEST:
printf("Compiled QTest progs will most likely not work at all. YOU'VE BEEN WARNED!\n");
outputsttype = PST_QTEST;
break;
default:
Sys_Error("invalid progs type chosen!");
}
//part of how compilation works. This def is always present, and never used.
@ -923,9 +931,10 @@ strofs = (strofs+3)&~3;
for (i=0 ; i<numstatements ; i++)
switch(qcc_targetformat == QCF_KK7?32:outputsize) //KK7 sucks.
switch(outputsttype)
{
case 32:
case PST_KKQWSV:
case PST_FTE32:
for (i=0 ; i<numstatements ; i++)
{
statements[i].op = PRLittleLong/*PRLittleShort*/(statements[i].op);
@ -947,7 +956,32 @@ strofs = (strofs+3)&~3;
else
SafeWrite (h, statements, numstatements*sizeof(QCC_dstatement32_t));
break;
case 16:
case PST_QTEST:
#define qtst ((qtest_statement_t*) statements)
for (i=0 ; i<numstatements ; i++) // scale down from 16-byte internal to 12-byte qtest
{
QCC_dstatement_t stmt = statements[i];
qtst[i].line = 0; // no line support
qtst[i].op = PRLittleShort((unsigned short)stmt.op);
if (stmt.a < 0)
qtst[i].a = PRLittleShort((short)stmt.a);
else
qtst[i].a = (unsigned short)PRLittleShort((unsigned short)stmt.a);
if (stmt.b < 0)
qtst[i].b = PRLittleShort((short)stmt.b);
else
qtst[i].b = (unsigned short)PRLittleShort((unsigned short)stmt.b);
if (stmt.c < 0)
qtst[i].c = PRLittleShort((short)stmt.c);
else
qtst[i].c = (unsigned short)PRLittleShort((unsigned short)stmt.c);
}
// no compression
SafeWrite (h, qtst, numstatements*sizeof(qtest_statement_t));
#undef qtst
break;
case PST_DEFAULT:
#define statements16 ((QCC_dstatement16_t*) statements)
for (i=0 ; i<numstatements ; i++) //resize as we go - scaling down
{
@ -980,37 +1014,88 @@ strofs = (strofs+3)&~3;
SafeWrite (h, statements16, numstatements*sizeof(QCC_dstatement16_t));
break;
default:
Sys_Error("intsize error");
Sys_Error("structtype error");
}
progs.ofs_functions = SafeSeek (h, 0, SEEK_CUR);
progs.numfunctions = numfunctions;
for (i=0 ; i<numfunctions ; i++)
switch (outputsttype)
{
functions[i].first_statement = PRLittleLong (functions[i].first_statement);
functions[i].parm_start = PRLittleLong (functions[i].parm_start);
functions[i].s_name = PRLittleLong (functions[i].s_name);
functions[i].s_file = PRLittleLong (functions[i].s_file);
functions[i].numparms = PRLittleLong ((functions[i].numparms>MAX_PARMS)?MAX_PARMS:functions[i].numparms);
functions[i].locals = PRLittleLong (functions[i].locals);
case PST_QTEST:
{
// this sucks but the structures are just too different
qtest_function_t *qtestfuncs = (qtest_function_t *)qccHunkAlloc(sizeof(qtest_function_t)*numfunctions);
for (i=0 ; i<numfunctions ; i++)
{
int j;
qtestfuncs[i].unused1 = 0;
qtestfuncs[i].profile = 0;
qtestfuncs[i].first_statement = PRLittleLong (functions[i].first_statement);
qtestfuncs[i].parm_start = PRLittleLong (functions[i].parm_start);
qtestfuncs[i].s_name = PRLittleLong (functions[i].s_name);
qtestfuncs[i].s_file = PRLittleLong (functions[i].s_file);
qtestfuncs[i].numparms = PRLittleLong ((functions[i].numparms>MAX_PARMS)?MAX_PARMS:functions[i].numparms);
qtestfuncs[i].locals = PRLittleLong (functions[i].locals);
for (j = 0; j < MAX_PARMS; j++)
qtestfuncs[i].parm_size[j] = PRLittleLong((int)functions[i].parm_size[j]);
}
SafeWrite (h, qtestfuncs, numfunctions*sizeof(qtest_function_t));
}
break;
case PST_DEFAULT:
case PST_KKQWSV:
case PST_FTE32:
for (i=0 ; i<numfunctions ; i++)
{
functions[i].first_statement = PRLittleLong (functions[i].first_statement);
functions[i].parm_start = PRLittleLong (functions[i].parm_start);
functions[i].s_name = PRLittleLong (functions[i].s_name);
functions[i].s_file = PRLittleLong (functions[i].s_file);
functions[i].numparms = PRLittleLong ((functions[i].numparms>MAX_PARMS)?MAX_PARMS:functions[i].numparms);
functions[i].locals = PRLittleLong (functions[i].locals);
}
if (progs.blockscompressed&8)
{
SafeWrite (h, &len, sizeof(int)); //save for later
len = QC_encode(progfuncs, numfunctions*sizeof(QCC_dfunction_t), 2, (char *)functions, h); //write
i = SafeSeek (h, 0, SEEK_CUR);
SafeSeek(h, progs.ofs_functions, SEEK_SET);//seek back
len = PRLittleLong(len);
SafeWrite (h, &len, sizeof(int)); //write size.
SafeSeek(h, i, SEEK_SET);
}
else
SafeWrite (h, functions, numfunctions*sizeof(QCC_dfunction_t));
break;
default:
Sys_Error("structtype error");
}
if (progs.blockscompressed&8)
{
SafeWrite (h, &len, sizeof(int)); //save for later
len = QC_encode(progfuncs, numfunctions*sizeof(QCC_dfunction_t), 2, (char *)functions, h); //write
i = SafeSeek (h, 0, SEEK_CUR);
SafeSeek(h, progs.ofs_functions, SEEK_SET);//seek back
len = PRLittleLong(len);
SafeWrite (h, &len, sizeof(int)); //write size.
SafeSeek(h, i, SEEK_SET);
}
else
SafeWrite (h, functions, numfunctions*sizeof(QCC_dfunction_t));
switch(outputsize)
switch(outputsttype)
{
case 32:
case PST_QTEST:
// qtest needs a struct remap but should be able to get away with a simple swap here
for (i=0 ; i<numglobaldefs ; i++)
{
qtest_def_t qtdef = ((qtest_def_t *)qcc_globals)[i];
qcc_globals[i].type = qtdef.type;
qcc_globals[i].ofs = qtdef.ofs;
qcc_globals[i].s_name = qtdef.s_name;
}
for (i=0 ; i<numfielddefs ; i++)
{
qtest_def_t qtdef = ((qtest_def_t *)fields)[i];
fields[i].type = qtdef.type;
fields[i].ofs = qtdef.ofs;
fields[i].s_name = qtdef.s_name;
}
// passthrough.. reuse FTE32 code
case PST_FTE32:
progs.ofs_globaldefs = SafeSeek (h, 0, SEEK_CUR);
progs.numglobaldefs = numglobaldefs;
for (i=0 ; i<numglobaldefs ; i++)
@ -1056,7 +1141,8 @@ strofs = (strofs+3)&~3;
else
SafeWrite (h, fields, numfielddefs*sizeof(QCC_ddef_t));
break;
case 16:
case PST_KKQWSV:
case PST_DEFAULT:
#define qcc_globals16 ((QCC_ddef16_t*)qcc_globals)
#define fields16 ((QCC_ddef16_t*)fields)
progs.ofs_globaldefs = SafeSeek (h, 0, SEEK_CUR);
@ -1105,7 +1191,7 @@ strofs = (strofs+3)&~3;
SafeWrite (h, fields16, numfielddefs*sizeof(QCC_ddef16_t));
break;
default:
Sys_Error("intsize error");
Sys_Error("structtype error");
}
progs.ofs_globals = SafeSeek (h, 0, SEEK_CUR);
@ -1147,6 +1233,9 @@ strofs = (strofs+3)&~3;
switch(qcc_targetformat)
{
case QCF_QTEST:
progs.version = PROG_QTESTVERSION;
break;
case QCF_KK7:
progs.version = PROG_KKQWSVVERSION;
break;
@ -1159,7 +1248,7 @@ strofs = (strofs+3)&~3;
case QCF_FTEDEBUG:
progs.version = PROG_EXTENDEDVERSION;
if (outputsize == 32)
if (outputsttype == PST_FTE32)
progs.secondaryversion = PROG_SECONDARYVERSION32;
else
progs.secondaryversion = PROG_SECONDARYVERSION16;

View File

@ -2862,7 +2862,10 @@ void QCBUILTIN PF_svtraceline (progfuncs_t *prinst, struct globalvars_s *pr_glob
v1 = G_VECTOR(OFS_PARM0);
v2 = G_VECTOR(OFS_PARM1);
nomonsters = G_FLOAT(OFS_PARM2);
ent = G_EDICT(prinst, OFS_PARM3);
if (*svprogfuncs->callargc == 3) // QTEST
ent = PROG_TO_EDICT(prinst, pr_global_struct->self);
else
ent = G_EDICT(prinst, OFS_PARM3);
if (sv_antilag.ival == 2)
nomonsters |= MOVE_LAGGED;