diff --git a/engine/qclib/initlib.c b/engine/qclib/initlib.c index a043420f0..d0f0fe242 100644 --- a/engine/qclib/initlib.c +++ b/engine/qclib/initlib.c @@ -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; diff --git a/engine/qclib/pr_comp.h b/engine/qclib/pr_comp.h index 59ea8654f..463445d0d 100644 --- a/engine/qclib/pr_comp.h +++ b/engine/qclib/pr_comp.h @@ -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 diff --git a/engine/qclib/pr_edict.c b/engine/qclib/pr_edict.c index e0649d1b0..c3a355d9f 100644 --- a/engine/qclib/pr_edict.c +++ b/engine/qclib/pr_edict.c @@ -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 ; inumglobaldefs ; 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 ; inumglobaldefs ; 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 ; inumfunctions; 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 ; inumfunctions; 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; jnumfunctions; 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 ; inumglobaldefs ; i++) { @@ -2796,7 +2814,26 @@ retry: } break; - case 32: + case PST_QTEST: + // qtest needs a struct remap + for (i=0 ; inumglobaldefs ; 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 ; inumfielddefs ; 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 ; inumglobaldefs ; 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 ; inumstatements ; 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 ; inumstatements ; 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 ; inumstatements ; 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 ; inumstatements ; 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 ; inumstatements ; 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 ; inumglobaldefs ; i++) { if (pr_types) @@ -2996,7 +3022,8 @@ retry: } } break; - case 32: + case PST_QTEST: + case PST_FTE32: for (i=0 ; inumglobaldefs ; 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]; diff --git a/engine/qclib/pr_exec.c b/engine/qclib/pr_exec.c index b96c86007..7afbcf867 100644 --- a/engine/qclib/pr_exec.c +++ b/engine/qclib/pr_exec.c @@ -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"); } } diff --git a/engine/qclib/pr_multi.c b/engine/qclib/pr_multi.c index 64142837f..1cac75dbd 100644 --- a/engine/qclib/pr_multi.c +++ b/engine/qclib/pr_multi.c @@ -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 ; inumfielddefs; 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 ; inumfielddefs; i++) { if (!strcmp(pr_fielddefs32[i].s_name+stringtable, pr_globaldefs32[num].s_name+stringtable)) diff --git a/engine/qclib/progsint.h b/engine/qclib/progsint.h index 27fecf196..4c203d98e 100644 --- a/engine/qclib/progsint.h +++ b/engine/qclib/progsint.h @@ -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 { diff --git a/engine/qclib/qcc.h b/engine/qclib/qcc.h index 6a5dbe7d5..2cae198e8 100644 --- a/engine/qclib/qcc.h +++ b/engine/qclib/qcc.h @@ -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; diff --git a/engine/qclib/qcc_pr_comp.c b/engine/qclib/qcc_pr_comp.c index 2cb7e2158..e2387364f 100644 --- a/engine/qclib/qcc_pr_comp.c +++ b/engine/qclib/qcc_pr_comp.c @@ -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; diff --git a/engine/qclib/qcc_pr_lex.c b/engine/qclib/qcc_pr_lex.c index 6e5f42001..e80d4491c 100644 --- a/engine/qclib/qcc_pr_lex.c +++ b/engine/qclib/qcc_pr_lex.c @@ -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); } diff --git a/engine/qclib/qccmain.c b/engine/qclib/qccmain.c index 9436a8e76..122aa5e67 100644 --- a/engine/qclib/qccmain.c +++ b/engine/qclib/qccmain.c @@ -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 ; iMAX_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 ; iMAX_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 ; iMAX_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 ; icallargc == 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;