From aca16977f4adf9c8fdff0e3256536d7f6064346d Mon Sep 17 00:00:00 2001 From: MirceaKitsune Date: Thu, 14 Jul 2011 23:11:53 +0300 Subject: [PATCH] Latest fteqcc and netradiant sources --- misc/source/fteqcc-src/comprout.c | 2 +- misc/source/fteqcc-src/execloop.h | 40 +- misc/source/fteqcc-src/hash.c | 98 +- misc/source/fteqcc-src/hash.h | 29 +- misc/source/fteqcc-src/initlib.c | 91 +- misc/source/fteqcc-src/pr_comp.h | 111 ++- misc/source/fteqcc-src/pr_edict.c | 368 +++++--- misc/source/fteqcc-src/pr_exec.c | 167 ++-- misc/source/fteqcc-src/pr_multi.c | 20 +- misc/source/fteqcc-src/pr_x86.c | 886 +++++++++++------- misc/source/fteqcc-src/progsint.h | 36 +- misc/source/fteqcc-src/progslib.h | 57 +- misc/source/fteqcc-src/qcc.h | 23 +- misc/source/fteqcc-src/qcc_cmdlib.c | 88 +- misc/source/fteqcc-src/qcc_pr_comp.c | 568 +++++------ misc/source/fteqcc-src/qcc_pr_lex.c | 380 ++++---- misc/source/fteqcc-src/qccmain.c | 454 +++++---- misc/source/fteqcc-src/qcd_main.c | 4 + misc/source/fteqcc-src/qcdecomp.c | 68 +- misc/source/netradiant-src/Makefile | 9 +- .../netradiant-src/contrib/bobtoolz/DPatch.h | 1 + .../netradiant-src/contrib/bobtoolz/DShape.h | 1 + .../netradiant-src/download-gamepacks.sh | 4 +- misc/source/netradiant-src/install-dylibs.sh | 8 +- .../source/netradiant-src/install-gamepack.sh | 8 +- .../netradiant-src/libs/memory/allocator.h | 1 + misc/source/netradiant-src/libs/picomodel.h | 4 +- .../netradiant-src/libs/picomodel/lwo/lwo2.c | 4 +- .../netradiant-src/libs/picomodel/lwo/lwob.c | 4 +- .../netradiant-src/libs/picomodel/picomodel.c | 7 +- .../netradiant-src/libs/picomodel/pm_ase.c | 8 +- .../netradiant-src/libs/picomodel/pm_fm.c | 2 - .../netradiant-src/libs/picomodel/pm_md2.c | 2 - .../netradiant-src/libs/picomodel/pm_obj.c | 6 +- misc/source/netradiant-src/libs/typesystem.h | 1 + .../netradiant-src/plugins/vfspk3/vfs.cpp | 23 +- .../netradiant-src/radiant/brushmodule.cpp | 4 + misc/source/netradiant-src/radiant/csg.cpp | 14 +- .../radiant/entityinspector.cpp | 9 + .../netradiant-src/radiant/entityinspector.h | 1 + .../netradiant-src/radiant/groupdialog.h | 2 + .../netradiant-src/radiant/mainframe.cpp | 86 +- .../source/netradiant-src/radiant/mainframe.h | 2 + misc/source/netradiant-src/radiant/map.cpp | 2 + misc/source/netradiant-src/radiant/qe3.cpp | 9 +- misc/source/netradiant-src/radiant/select.cpp | 75 +- .../netradiant-src/radiant/selection.cpp | 6 +- .../tools/quake3/common/imagelib.c | 3 +- .../tools/quake3/common/scriplib.c | 3 +- .../netradiant-src/tools/quake3/common/vfs.c | 19 +- .../tools/quake3/q3map2/convert_ase.c | 2 +- .../tools/quake3/q3map2/convert_map.c | 12 - .../tools/quake3/q3map2/convert_obj.c | 7 +- .../tools/quake3/q3map2/facebsp.c | 4 + .../tools/quake3/q3map2/image.c | 5 +- .../tools/quake3/q3map2/light.c | 5 - .../tools/quake3/q3map2/light_bounce.c | 2 - .../tools/quake3/q3map2/light_trace.c | 6 +- .../tools/quake3/q3map2/light_ydnar.c | 8 +- .../tools/quake3/q3map2/lightmaps_ydnar.c | 15 +- .../netradiant-src/tools/quake3/q3map2/main.c | 2 +- .../netradiant-src/tools/quake3/q3map2/map.c | 13 +- .../tools/quake3/q3map2/model.c | 26 +- .../tools/quake3/q3map2/patch.c | 4 +- .../tools/quake3/q3map2/path_init.c | 115 ++- .../tools/quake3/q3map2/shaders.c | 4 +- .../tools/quake3/q3map2/surface.c | 4 +- .../tools/quake3/q3map2/surface_meta.c | 5 +- .../tools/quake3/q3map2/tjunction.c | 5 - 69 files changed, 2404 insertions(+), 1658 deletions(-) diff --git a/misc/source/fteqcc-src/comprout.c b/misc/source/fteqcc-src/comprout.c index a2a7a3bd..2a2f9615 100644 --- a/misc/source/fteqcc-src/comprout.c +++ b/misc/source/fteqcc-src/comprout.c @@ -61,7 +61,7 @@ pbool PreCompile(void) qccClearHunk(); strcpy(qcc_gamedir, ""); - qcchunk = malloc(qcchunksize=128*1024*1024); + qcchunk = malloc(qcchunksize=256*1024*1024); while(!qcchunk && qcchunksize > 8*1024*1024) { qcchunksize /= 2; diff --git a/misc/source/fteqcc-src/execloop.h b/misc/source/fteqcc-src/execloop.h index 365c93a4..08d0ce9f 100644 --- a/misc/source/fteqcc-src/execloop.h +++ b/misc/source/fteqcc-src/execloop.h @@ -49,11 +49,11 @@ cont: //last statement may have been a breakpoint st = pr_statements + s; reeval: + switch (st->op & ~0x8000) #else st++; -#endif - switch (st->op) +#endif { case OP_ADD_F: OPC->_float = OPA->_float + OPB->_float; @@ -101,16 +101,16 @@ reeval: OPC->_vector[2] = OPB->_float / OPA->_vector[2]; break; - case OP_BITAND: + case OP_BITAND_F: OPC->_float = (float)((int)OPA->_float & (int)OPB->_float); break; - case OP_BITOR: + case OP_BITOR_F: OPC->_float = (float)((int)OPA->_float | (int)OPB->_float); break; - case OP_GE: + case OP_GE_F: OPC->_float = (float)(OPA->_float >= OPB->_float); break; case OP_GE_I: @@ -123,7 +123,7 @@ reeval: OPC->_float = (float)(OPA->_float >= OPB->_int); break; - case OP_LE: + case OP_LE_F: OPC->_float = (float)(OPA->_float <= OPB->_float); break; case OP_LE_I: @@ -136,7 +136,7 @@ reeval: OPC->_float = (float)(OPA->_float <= OPB->_int); break; - case OP_GT: + case OP_GT_F: OPC->_float = (float)(OPA->_float > OPB->_float); break; case OP_GT_I: @@ -149,7 +149,7 @@ reeval: OPC->_float = (float)(OPA->_float > OPB->_int); break; - case OP_LT: + case OP_LT_F: OPC->_float = (float)(OPA->_float < OPB->_float); break; case OP_LT_I: @@ -162,10 +162,10 @@ reeval: OPC->_float = (float)(OPA->_float < OPB->_int); break; - case OP_AND: + case OP_AND_F: OPC->_float = (float)(OPA->_float && OPB->_float); break; - case OP_OR: + case OP_OR_F: OPC->_float = (float)(OPA->_float || OPB->_float); break; @@ -511,7 +511,7 @@ reeval: st += (sofs)st->b - 1; // offset the s++ break; - case OP_IFNOT: + case OP_IFNOT_I: RUNAWAYCHECK(); if (!OPA->_int) st += (sofs)st->b - 1; // offset the s++ @@ -529,7 +529,7 @@ reeval: st += (sofs)st->b - 1; // offset the s++ break; - case OP_IF: + case OP_IF_I: RUNAWAYCHECK(); if (OPA->_int) st += (sofs)st->b - 1; // offset the s++ @@ -575,8 +575,7 @@ reeval: fnum = OPA->function; if ((fnum & ~0xff000000)==0) { - pr_trace++; - printf("NULL function from qc (%s).\n", progfuncs->stringtable + pr_xfunction->s_name); + PR_RunError(progfuncs, "NULL function from qc (%s).\n", progfuncs->stringtable + pr_xfunction->s_name); #ifndef DEBUGABLE goto cont; #endif @@ -742,7 +741,7 @@ if (pr_typecurrent != 0) break; - //array/structure reading/riting. + //array/structure reading/writing. case OP_GLOBALADDRESS: OPC->_int = ENGINEPOINTER(&OPA->_int + OPB->_int); break; @@ -825,8 +824,7 @@ if (pr_typecurrent != 0) { PR_RunError(progfuncs, "array index out of bounds: %s[%d]", PR_GlobalStringNoContents(progfuncs, st->a), i); } - t = (eval_t *)&pr_globals[(uofs)st->a - +((int)OPB->_float)*3]; + t = (eval_t *)&pr_globals[(uofs)st->a + i*3]; OPC->_vector[0] = t->_vector[0]; OPC->_vector[1] = t->_vector[1]; OPC->_vector[2] = t->_vector[2]; @@ -1110,14 +1108,6 @@ if (pr_typecurrent != 0) st = &pr_statements[s]; //let the user move execution pr_xstatement = s = st-pr_statements; -#if 0 //fakeop stuff - not practical, the rest of the code is more optimised, st needs to point at the correct statement - memcpy(&fakeop, st, sizeof(dstatement_t)); //don't hit the new statement as a break point, cos it's probably the same one. - fakeop.op &= ~0x8000; - st = &fakeop; //a little remapping... -#else - st->op &= ~0x8000; //just remove the breakpoint and go around again, but this time in the debugger. -#endif - goto reeval; //reexecute } pr_xstatement = st-pr_statements; diff --git a/misc/source/fteqcc-src/hash.c b/misc/source/fteqcc-src/hash.c index 2b7b9120..44ac211d 100644 --- a/misc/source/fteqcc-src/hash.c +++ b/misc/source/fteqcc-src/hash.c @@ -9,21 +9,21 @@ #endif // hash init assumes we get clean memory -void Hash_InitTable(hashtable_t *table, int numbucks, void *mem) +void Hash_InitTable(hashtable_t *table, unsigned int numbucks, void *mem) { table->numbuckets = numbucks; table->bucket = (bucket_t **)mem; } -int Hash_Key(const char *name, int modulus) +unsigned int Hash_Key(const char *name, unsigned int modulus) { //fixme: optimize. unsigned int key; for (key=0;*name; name++) key += ((key<<3) + (key>>28) + *name); - return (int)(key%modulus); + return (key%modulus); } -int Hash_KeyInsensative(const char *name, int modulus) +unsigned int Hash_KeyInsensative(const char *name, unsigned int modulus) { //fixme: optimize. unsigned int key; for (key=0;*name; name++) @@ -34,12 +34,12 @@ int Hash_KeyInsensative(const char *name, int modulus) key += ((key<<3) + (key>>28) + *name); } - return (int)(key%modulus); + return (key%modulus); } void *Hash_Get(hashtable_t *table, const char *name) { - int bucknum = Hash_Key(name, table->numbuckets); + unsigned int bucknum = Hash_Key(name, table->numbuckets); bucket_t *buck; buck = table->bucket[bucknum]; @@ -55,7 +55,7 @@ void *Hash_Get(hashtable_t *table, const char *name) } void *Hash_GetInsensative(hashtable_t *table, const char *name) { - int bucknum = Hash_KeyInsensative(name, table->numbuckets); + unsigned int bucknum = Hash_KeyInsensative(name, table->numbuckets); bucket_t *buck; buck = table->bucket[bucknum]; @@ -69,9 +69,9 @@ void *Hash_GetInsensative(hashtable_t *table, const char *name) } return NULL; } -void *Hash_GetKey(hashtable_t *table, int key) +void *Hash_GetKey(hashtable_t *table, unsigned int key) { - int bucknum = key%table->numbuckets; + unsigned int bucknum = key%table->numbuckets; bucket_t *buck; buck = table->bucket[bucknum]; @@ -85,21 +85,46 @@ void *Hash_GetKey(hashtable_t *table, int key) } return NULL; } -void *Hash_GetNext(hashtable_t *table, char *name, void *old) +/*Does _NOT_ support items that are added with two names*/ +void *Hash_GetNextKey(hashtable_t *table, unsigned int key, void *old) { - int bucknum = Hash_Key(name, table->numbuckets); + unsigned int bucknum = key%table->numbuckets; bucket_t *buck; buck = table->bucket[bucknum]; while(buck) { - if (!STRCMP(name, buck->key.string)) - { - if (buck->data == old) //found the old one - break; - } + if (buck->data == old) //found the old one + break; + buck = buck->next; + } + if (!buck) + return NULL; + + buck = buck->next;//don't return old + while(buck) + { + if (buck->key.value == key) + return buck->data; + + buck = buck->next; + } + return NULL; +} +/*Does _NOT_ support items that are added with two names*/ +void *Hash_GetNext(hashtable_t *table, const char *name, void *old) +{ + unsigned int bucknum = Hash_Key(name, table->numbuckets); + bucket_t *buck; + + buck = table->bucket[bucknum]; + while(buck) + { + if (buck->data == old) //found the old one +// if (!STRCMP(name, buck->key.string)) + break; buck = buck->next; } if (!buck) @@ -115,18 +140,19 @@ void *Hash_GetNext(hashtable_t *table, char *name, void *old) } return NULL; } -void *Hash_GetNextInsensative(hashtable_t *table, char *name, void *old) +/*Does _NOT_ support items that are added with two names*/ +void *Hash_GetNextInsensative(hashtable_t *table, const char *name, void *old) { - int bucknum = Hash_KeyInsensative(name, table->numbuckets); + unsigned int bucknum = Hash_KeyInsensative(name, table->numbuckets); bucket_t *buck; buck = table->bucket[bucknum]; while(buck) { - if (!STRCMP(name, buck->key.string)) + if (buck->data == old) //found the old one { - if (buck->data == old) //found the old one +// if (!stricmp(name, buck->key.string)) break; } @@ -138,7 +164,7 @@ void *Hash_GetNextInsensative(hashtable_t *table, char *name, void *old) buck = buck->next;//don't return old while(buck) { - if (!STRCMP(name, buck->key.string)) + if (!stricmp(name, buck->key.string)) return buck->data; buck = buck->next; @@ -147,9 +173,9 @@ void *Hash_GetNextInsensative(hashtable_t *table, char *name, void *old) } -void *Hash_Add(hashtable_t *table, char *name, void *data, bucket_t *buck) +void *Hash_Add(hashtable_t *table, const char *name, void *data, bucket_t *buck) { - int bucknum = Hash_Key(name, table->numbuckets); + unsigned int bucknum = Hash_Key(name, table->numbuckets); buck->data = data; buck->key.string = name; @@ -158,9 +184,9 @@ void *Hash_Add(hashtable_t *table, char *name, void *data, bucket_t *buck) return buck; } -void *Hash_AddInsensative(hashtable_t *table, char *name, void *data, bucket_t *buck) +void *Hash_AddInsensative(hashtable_t *table, const char *name, void *data, bucket_t *buck) { - int bucknum = Hash_KeyInsensative(name, table->numbuckets); + unsigned int bucknum = Hash_KeyInsensative(name, table->numbuckets); buck->data = data; buck->key.string = name; @@ -169,9 +195,9 @@ void *Hash_AddInsensative(hashtable_t *table, char *name, void *data, bucket_t * return buck; } -void *Hash_AddKey(hashtable_t *table, int key, void *data, bucket_t *buck) +void *Hash_AddKey(hashtable_t *table, unsigned int key, void *data, bucket_t *buck) { - int bucknum = key%table->numbuckets; + unsigned int bucknum = key%table->numbuckets; buck->data = data; buck->key.value = key; @@ -181,14 +207,12 @@ void *Hash_AddKey(hashtable_t *table, int key, void *data, bucket_t *buck) return buck; } -void Hash_Remove(hashtable_t *table, char *name) +void Hash_Remove(hashtable_t *table, const char *name) { - int bucknum = Hash_Key(name, table->numbuckets); + unsigned int bucknum = Hash_Key(name, table->numbuckets); bucket_t *buck; buck = table->bucket[bucknum]; - if(!buck) - return; if (!STRCMP(name, buck->key.string)) { @@ -210,14 +234,12 @@ void Hash_Remove(hashtable_t *table, char *name) return; } -void Hash_RemoveData(hashtable_t *table, char *name, void *data) +void Hash_RemoveData(hashtable_t *table, const char *name, void *data) { - int bucknum = Hash_Key(name, table->numbuckets); + unsigned int bucknum = Hash_Key(name, table->numbuckets); bucket_t *buck; buck = table->bucket[bucknum]; - if(!buck) - return; if (buck->data == data) if (!STRCMP(name, buck->key.string)) @@ -242,14 +264,12 @@ void Hash_RemoveData(hashtable_t *table, char *name, void *data) } -void Hash_RemoveKey(hashtable_t *table, int key) +void Hash_RemoveKey(hashtable_t *table, unsigned int key) { - int bucknum = key%table->numbuckets; + unsigned int bucknum = key%table->numbuckets; bucket_t *buck; buck = table->bucket[bucknum]; - if(!buck) - return; if (buck->key.value == key) { diff --git a/misc/source/fteqcc-src/hash.h b/misc/source/fteqcc-src/hash.h index 778e67a5..e07c17d2 100644 --- a/misc/source/fteqcc-src/hash.h +++ b/misc/source/fteqcc-src/hash.h @@ -5,34 +5,35 @@ #ifndef HASH_H__ #define HASH_H__ -#define Hash_BytesForBuckets(b) (sizeof(bucket_t)*b) +#define Hash_BytesForBuckets(b) (sizeof(bucket_t*)*(b)) #define STRCMP(s1,s2) (((*s1)!=(*s2)) || strcmp(s1+1,s2+1)) //saves about 2-6 out of 120 - expansion of idea from fastqcc typedef struct bucket_s { void *data; union { const char *string; - int value; + unsigned int value; } key; struct bucket_s *next; } bucket_t; typedef struct hashtable_s { - int numbuckets; + unsigned int numbuckets; bucket_t **bucket; } hashtable_t; -void Hash_InitTable(hashtable_t *table, int numbucks, void *mem); //mem must be 0 filled. (memset(mem, 0, size)) -int Hash_Key(const char *name, int modulus); +void Hash_InitTable(hashtable_t *table, unsigned int numbucks, void *mem); //mem must be 0 filled. (memset(mem, 0, size)) +unsigned int Hash_Key(const char *name, unsigned int modulus); void *Hash_Get(hashtable_t *table, const char *name); void *Hash_GetInsensative(hashtable_t *table, const char *name); -void *Hash_GetKey(hashtable_t *table, int key); -void *Hash_GetNext(hashtable_t *table, char *name, void *old); -void *Hash_GetNextInsensative(hashtable_t *table, char *name, void *old); -void *Hash_Add(hashtable_t *table, char *name, void *data, bucket_t *buck); -void *Hash_AddInsensative(hashtable_t *table, char *name, void *data, bucket_t *buck); -void Hash_Remove(hashtable_t *table, char *name); -void Hash_RemoveData(hashtable_t *table, char *name, void *data); -void Hash_RemoveKey(hashtable_t *table, int key); -void *Hash_AddKey(hashtable_t *table, int key, void *data, bucket_t *buck); +void *Hash_GetKey(hashtable_t *table, unsigned int key); +void *Hash_GetNext(hashtable_t *table, const char *name, void *old); +void *Hash_GetNextInsensative(hashtable_t *table, const char *name, void *old); +void *Hash_GetNextKey(hashtable_t *table, unsigned int key, void *old); +void *Hash_Add(hashtable_t *table, const char *name, void *data, bucket_t *buck); +void *Hash_AddInsensative(hashtable_t *table, const char *name, void *data, bucket_t *buck); +void Hash_Remove(hashtable_t *table, const char *name); +void Hash_RemoveData(hashtable_t *table, const char *name, void *data); +void Hash_RemoveKey(hashtable_t *table, unsigned int key); +void *Hash_AddKey(hashtable_t *table, unsigned int key, void *data, bucket_t *buck); #endif diff --git a/misc/source/fteqcc-src/initlib.c b/misc/source/fteqcc-src/initlib.c index 1ca5728b..8ee0f99a 100644 --- a/misc/source/fteqcc-src/initlib.c +++ b/misc/source/fteqcc-src/initlib.c @@ -111,11 +111,6 @@ void PR_Configure (progfuncs_t *progfuncs, int addressable_size, int max_progs) unsigned int i; edictrun_t *e; -// int a; -#ifdef QCJIT - prinst->usejit = true; -#endif - max_fields_size=0; fields_size = 0; progfuncs->stringtable = 0; @@ -232,15 +227,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); @@ -251,7 +247,44 @@ func_t PR_FindFunc(progfuncs_t *progfuncs, char *funcname, progsnum_t pnum) return 0; } -eval_t *PR_FindGlobal(progfuncs_t *progfuncs, char *globname, progsnum_t pnum) +void QC_FindPrefixedGlobals(progfuncs_t *progfuncs, char *prefix, void (*found) (progfuncs_t *progfuncs, char *name, union eval_s *val, etype_t type) ) +{ + unsigned int i; + ddef16_t *def16; + ddef32_t *def32; + int len = strlen(prefix); + unsigned int pnum; + + for (pnum = 0; pnum < maxprogs; pnum++) + { + if (!pr_progstate[pnum].progs) + continue; + + switch(pr_progstate[pnum].structtype) + { + case PST_DEFAULT: + case PST_KKQWSV: + for (i=1 ; inumglobaldefs ; i++) + { + def16 = &pr_progstate[pnum].globaldefs16[i]; + if (!strncmp(def16->s_name+progfuncs->stringtable,prefix, len)) + found(progfuncs, def16->s_name+progfuncs->stringtable, (eval_t *)&pr_progstate[pnum].globals[def16->ofs], def16->type); + } + break; + case PST_QTEST: + case PST_FTE32: + for (i=1 ; inumglobaldefs ; i++) + { + def32 = &pr_progstate[pnum].globaldefs32[i]; + if (!strncmp(def32->s_name+progfuncs->stringtable,prefix, len)) + found(progfuncs, def32->s_name+progfuncs->stringtable, (eval_t *)&pr_progstate[pnum].globals[def32->ofs], def32->type); + } + break; + } + } +} + +eval_t *PR_FindGlobal(progfuncs_t *progfuncs, char *globname, progsnum_t pnum, etype_t *type) { unsigned int i; ddef16_t *var16; @@ -265,7 +298,7 @@ eval_t *PR_FindGlobal(progfuncs_t *progfuncs, char *globname, progsnum_t pnum) { if (!pr_progstate[i].progs) continue; - ev = PR_FindGlobal(progfuncs, globname, i); + ev = PR_FindGlobal(progfuncs, globname, i, type); if (ev) return ev; } @@ -273,18 +306,23 @@ 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; + if (type) + *type = var16->type; 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; + if (type) + *type = var32->type; return (eval_t *)&pr_progstate[pnum].globals[var32->ofs]; } Sys_Error("Error with def size (PR_FindGlobal)"); @@ -308,12 +346,9 @@ char *PR_VarString (progfuncs_t *progfuncs, int first) if (G_STRING(OFS_PARM0+i*3)) { s=G_STRING((OFS_PARM0+i*3)) + progfuncs->stringtable; + if (strlen(out) + strlen(s) + 1 >= sizeof(out)) + return out; strcat (out, s); - -//#ifdef PARANOID - if (strlen(out)+1 >= sizeof(out)) - Sys_Error("VarString (builtin call ending with strings) exceeded maximum string length of %i chars", sizeof(out)); -//#endif } } return out; @@ -463,7 +498,7 @@ char *PR_RemoveProgsString (progfuncs_t *progfuncs, string_t str) return NULL; } -char *PR_StringToNative (progfuncs_t *progfuncs, string_t str) +char *ASMCALL PR_StringToNative (progfuncs_t *progfuncs, string_t str) { if ((unsigned int)str & 0xc0000000) { @@ -647,7 +682,8 @@ progfuncs_t deffuncs = { PR_StringToNative, 0, PR_QueryField, - QC_ClearEdict + QC_ClearEdict, + QC_FindPrefixedGlobals }; #undef printf @@ -677,6 +713,7 @@ progexterns_t defexterns = { //used when loading a game NULL, //builtin_t *(*builtinsfor) (int num); //must return a pointer to the builtins that were used before the state was saved. NULL, //void (*loadcompleate) (int edictsize); //notification to reset any pointers. + NULL, (void*)malloc, //void *(*memalloc) (int size); //small string allocation malloced and freed randomly by the executor. (use memalloc if you want) free, //void (*memfree) (void * mem); @@ -736,6 +773,14 @@ void CloseProgs(progfuncs_t *inst) free(inst->addressablehunk); #endif + if (inst->prinst->allocedstrings) + f(inst->prinst->allocedstrings); + inst->prinst->allocedstrings = NULL; + if (inst->prinst->tempstrings) + f(inst->prinst->tempstrings); + inst->prinst->tempstrings = NULL; + + /* while(inst->prinst->extensionbuiltin) { diff --git a/misc/source/fteqcc-src/pr_comp.h b/misc/source/fteqcc-src/pr_comp.h index 13b93bce..d6c34a96 100644 --- a/misc/source/fteqcc-src/pr_comp.h +++ b/misc/source/fteqcc-src/pr_comp.h @@ -31,7 +31,7 @@ typedef int QCC_string_t; #define RESERVED_OFS 28 -enum { +enum qcop_e { OP_DONE, //0 OP_MUL_F, OP_MUL_V, @@ -55,10 +55,10 @@ enum { OP_NE_E, OP_NE_FNC, - OP_LE, //20 - OP_GE, - OP_LT, - OP_GT, + OP_LE_F, //20 + OP_GE_F, + OP_LT_F, + OP_GT_F, OP_LOAD_F, OP_LOAD_V, @@ -89,8 +89,8 @@ enum { OP_NOT_S, OP_NOT_ENT, OP_NOT_FNC, - OP_IF, - OP_IFNOT, //50 + OP_IF_I, + OP_IFNOT_I, //50 OP_CALL0, //careful... hexen2 and q1 have different calling conventions OP_CALL1, //remap hexen2 calls to OP_CALL2H OP_CALL2, @@ -102,11 +102,11 @@ enum { OP_CALL8, OP_STATE, //60 OP_GOTO, - OP_AND, - OP_OR, + OP_AND_F, + OP_OR_F, - OP_BITAND, - OP_BITOR, + OP_BITAND_F, + OP_BITOR_F, //these following ones are Hexen 2 constants. @@ -184,10 +184,10 @@ enum { OP_ADD_I, OP_ADD_FI, - OP_ADD_IF, //110 + OP_ADD_IF, OP_SUB_I, - OP_SUB_FI, + OP_SUB_FI, //120 OP_SUB_IF, OP_CONV_ITOF, @@ -196,10 +196,10 @@ enum { OP_CP_FTOI, OP_LOAD_I, OP_STOREP_I, - OP_STOREP_IF, //120 + OP_STOREP_IF, OP_STOREP_FI, - OP_BITAND_I, + OP_BITAND_I, //130 OP_BITOR_I, OP_MUL_I, @@ -210,11 +210,11 @@ enum { OP_IFNOT_S, OP_IF_S, - OP_NOT_I, //130 + OP_NOT_I, OP_DIV_VF, - OP_XOR_I, + OP_XOR_I, //140 OP_RSHIFT_I, OP_LSHIFT_I, @@ -224,9 +224,9 @@ enum { OP_LOADA_F, OP_LOADA_V, OP_LOADA_S, - OP_LOADA_ENT, //140 - OP_LOADA_FLD, - OP_LOADA_FNC, + OP_LOADA_ENT, + OP_LOADA_FLD, + OP_LOADA_FNC, //150 OP_LOADA_I, OP_STORE_P, //152... erm.. wait... @@ -236,9 +236,9 @@ enum { OP_LOADP_V, OP_LOADP_S, OP_LOADP_ENT, - OP_LOADP_FLD, //150 + OP_LOADP_FLD, OP_LOADP_FNC, - OP_LOADP_I, + OP_LOADP_I, //160 OP_LE_I, OP_GE_I, @@ -248,10 +248,10 @@ enum { OP_LE_IF, OP_GE_IF, OP_LT_IF, - OP_GT_IF, //160 + OP_GT_IF, OP_LE_FI, - OP_GE_FI, + OP_GE_FI, //170 OP_LT_FI, OP_GT_FI, @@ -263,12 +263,12 @@ enum { OP_ADD_SF, //(char*)c = (char*)a + (float)b OP_SUB_S, //(float)c = (char*)a - (char*)b OP_STOREP_C,//(float)c = *(char*)b = (float)a - OP_LOADP_C, //(float)c = *(char*) //170 + OP_LOADP_C, //(float)c = *(char*) //------------------------------------- OP_MUL_IF, - OP_MUL_FI, + OP_MUL_FI, //180 OP_MUL_VI, OP_MUL_IV, OP_DIV_IF, @@ -276,9 +276,9 @@ enum { OP_BITAND_IF, OP_BITOR_IF, OP_BITAND_FI, - OP_BITOR_FI, //180 + OP_BITOR_FI, OP_AND_I, - OP_OR_I, + OP_OR_I, //190 OP_AND_IF, OP_OR_IF, OP_AND_FI, @@ -288,9 +288,9 @@ enum { //erm... FTEQCC doesn't make use of these... These are for DP. OP_GSTOREP_I, - OP_GSTOREP_F, //190 + OP_GSTOREP_F, OP_GSTOREP_ENT, - OP_GSTOREP_FLD, // integers + OP_GSTOREP_FLD, // integers //200 OP_GSTOREP_S, OP_GSTOREP_FNC, // pointers OP_GSTOREP_V, @@ -298,9 +298,9 @@ enum { OP_GLOAD_I, OP_GLOAD_F, OP_GLOAD_FLD, - OP_GLOAD_ENT, //200 + OP_GLOAD_ENT, OP_GLOAD_S, - OP_GLOAD_FNC, + OP_GLOAD_FNC, //210 OP_BOUNDCHECK, //back to ones that we do use. @@ -320,7 +320,7 @@ enum { These ops are emulated out, always, and are only present in the compiler. */ - OP_BITSET_I, + OP_BITSET_I, //220 OP_BITSETP_I, OP_MULSTORE_I, @@ -332,7 +332,7 @@ enum { OP_ADDSTOREP_I, OP_SUBSTOREP_I, - OP_MULSTORE_IF, + OP_MULSTORE_IF, //230 OP_MULSTOREP_IF, OP_DIVSTORE_IF, OP_DIVSTOREP_IF, @@ -343,16 +343,47 @@ enum { OP_MULSTORE_FI, OP_MULSTOREP_FI, - OP_DIVSTORE_FI, + OP_DIVSTORE_FI, //240 OP_DIVSTOREP_FI, OP_ADDSTORE_FI, OP_ADDSTOREP_FI, OP_SUBSTORE_FI, OP_SUBSTOREP_FI, - OP_NUMOPS + OP_NUMOPS //246 }; +#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 @@ -507,7 +536,7 @@ typedef struct int secondaryversion; //Constant - to say that any version 7 progs are actually ours, not someone else's alterations. } dprograms_t; -#define standard_dprograms_t_size ((int)&((dprograms_t*)NULL)->ofsfiles) +#define standard_dprograms_t_size ((size_t)&((dprograms_t*)NULL)->ofsfiles) #endif @@ -536,5 +565,5 @@ typedef struct typeinfo_s int ofs; //inside a structure. int size; - char *name; + string_t name; } typeinfo_t; diff --git a/misc/source/fteqcc-src/pr_edict.c b/misc/source/fteqcc-src/pr_edict.c index d6c21199..a67b3685 100644 --- a/misc/source/fteqcc-src/pr_edict.c +++ b/misc/source/fteqcc-src/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; } @@ -500,7 +502,17 @@ char *PR_ValueString (progfuncs_t *progfuncs, etype_t type, eval_t *val) sprintf (line, "%s", PR_StringToNative(progfuncs, val->string)); break; case ev_entity: - sprintf (line, "entity %i", NUM_FOR_EDICT(progfuncs, (struct edict_s *)PROG_TO_EDICT(progfuncs, val->edict)) ); + fielddef = ED_FindField(progfuncs, "classname"); + if (fielddef && val->edict < sv_num_edicts) + { + edictrun_t *ed; + string_t *v; + ed = (edictrun_t *)EDICT_NUM(progfuncs, val->edict); + v = (string_t *)((char *)edvars(ed) + fielddef->ofs*4); + sprintf (line, "entity %i(%s)", val->edict, PR_StringToNative(progfuncs, *v)); + } + else + sprintf (line, "entity %i", val->edict); break; case ev_function: if (!val->function) @@ -511,8 +523,13 @@ char *PR_ValueString (progfuncs_t *progfuncs, etype_t type, eval_t *val) sprintf (line, "Bad function"); else { - f = pr_progstate[(val->function & 0xff000000)>>24].functions + (val->function & ~0xff000000); - sprintf (line, "%i:%s()", (val->function & 0xff000000)>>24, f->s_name+progfuncs->stringtable); + if ((val->function &~0xff000000) >= pr_progs->numfunctions) + sprintf(line, "bad function %i:%i\n", (val->function & 0xff000000)>>24, val->function & ~0xff000000); + else + { + f = pr_progstate[(val->function & 0xff000000)>>24].functions + (val->function & ~0xff000000); + sprintf (line, "%i:%s()", (val->function & 0xff000000)>>24, f->s_name+progfuncs->stringtable); + } } } break; @@ -796,10 +813,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) @@ -815,7 +832,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) @@ -832,7 +850,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 ""; } @@ -843,17 +861,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); @@ -861,7 +880,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); @@ -1033,7 +1052,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]; @@ -1043,11 +1062,11 @@ pbool ED_ParseEpair (progfuncs_t *progfuncs, void *base, ddefXX_t *key, char *s, string_t st; dfunction_t *func; - int type; + int type = 0; // warning about beign used without initializing it - switch(bits) + switch(structtype) { - case 16: + case PST_DEFAULT: d = (void *)((int *)base + ((ddef16_t*)key)->ofs); if (pr_types) @@ -1055,7 +1074,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) @@ -1064,7 +1083,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; } @@ -1091,9 +1110,17 @@ pbool ED_ParseEpair (progfuncs_t *progfuncs, void *base, ddefXX_t *key, char *s, { while (*v && *v != ' ') v++; - *v = 0; - ((float *)d)[i] = (float)atof (w); - w = v = v+1; + if (!*v) + { + ((float *)d)[i] = (float)atof (w); + w = v; + } + else + { + *v = 0; + ((float *)d)[i] = (float)atof (w); + w = v = v+1; + } } break; @@ -1148,6 +1175,7 @@ char *ED_ParseEdict (progfuncs_t *progfuncs, char *data, edictrun_t *ent) pbool init; char keyname[256]; int n; + int nest = 1; // eval_t *val; @@ -1163,12 +1191,20 @@ char *ED_ParseEdict (progfuncs_t *progfuncs, char *data, edictrun_t *ent) // parse key data = QCC_COM_Parse (data); if (qcc_token[0] == '}') + { + if (--nest) + continue; break; + } + if (qcc_token[0] == '{' && !qcc_token[1]) + nest++; if (!data) { printf ("ED_ParseEntity: EOF without closing brace\n"); return NULL; } + if (nest > 1) + continue; strncpy (keyname, qcc_token, sizeof(keyname)-1); keyname[sizeof(keyname)-1] = 0; @@ -1186,7 +1222,7 @@ char *ED_ParseEdict (progfuncs_t *progfuncs, char *data, edictrun_t *ent) if (!data) { printf ("ED_ParseEntity: EOF without closing brace\n"); - return NULL; + return NULL; } if (qcc_token[0] == '}') @@ -1216,12 +1252,14 @@ char *ED_ParseEdict (progfuncs_t *progfuncs, char *data, edictrun_t *ent) if (!strcmp(keyname, "light")) //Quake lighthack - allows a field name and a classname to go by the same thing in the level editor if ((key = ED_FindField (progfuncs, "light_lev"))) goto cont; + if (externs->badfield && externs->badfield(progfuncs, (struct edict_s*)ent, keyname, qcc_token)) + continue; printf ("'%s' is not a field\n", keyname); continue; } 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"); @@ -1263,10 +1301,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]; @@ -1331,7 +1369,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]; @@ -1385,7 +1424,7 @@ add32: } break; default: - Sys_Error("Bad number of bits in SaveEnts"); + Sys_Error("Bad struct type in SaveEnts"); } return buffer; @@ -1696,6 +1735,11 @@ int LoadEnts(progfuncs_t *progfuncs, char *file, float killonspawnflags) file = QCC_COM_Parse(file); if (file == NULL) break; //finished reading file + else if (!strcmp(qcc_token, "Version")) + { + file = QCC_COM_Parse(file); + //qcc_token is a version number + } else if (!strcmp(qcc_token, "entity")) { if (entsize == 0 && resethunk) //edicts have not yet been initialized, and this is a compleate load (memsize has been set) @@ -1849,10 +1893,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); @@ -1861,10 +1905,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); @@ -1873,11 +1918,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"); } } @@ -1947,10 +1992,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); @@ -1959,10 +2004,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); @@ -1971,11 +2017,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"); } } } @@ -2372,7 +2418,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) { @@ -2383,17 +2433,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 @@ -2468,16 +2518,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); @@ -2486,16 +2536,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); @@ -2504,16 +2554,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); @@ -2627,40 +2677,48 @@ retry: current_progstate->edict_size = pr_progs->entityfields * 4 + externs->edictsize; // byte swap the lumps - for (i=0 ; inumfunctions; i++) + switch(current_progstate->structtype) { + case PST_QTEST: + // qtest needs a struct remap + for (i=0 ; inumfunctions; i++) + { + 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); + 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)) - { - 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; - } - } + fnc[i].s_name += stringadjust; + fnc[i].s_file += stringadjust; } -*/ - fnc[i].s_name += stringadjust; - fnc[i].s_file += stringadjust; + break; + default: + Sys_Error("Bad struct type"); } //actual global values @@ -2680,7 +2738,7 @@ retry: pr_types[i].num_parms = PRLittleLong(current_progstate->types[i].num_parms); pr_types[i].ofs = PRLittleLong(current_progstate->types[i].ofs); pr_types[i].size = PRLittleLong(current_progstate->types[i].size); - pr_types[i].name = (char *)PRLittleLong((long)current_progstate->types[i].name); + pr_types[i].name = PRLittleLong(current_progstate->types[i].name); #endif pr_types[i].name += stringadjust; } @@ -2690,10 +2748,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++) { @@ -2764,7 +2822,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 @@ -2790,7 +2867,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); } @@ -2808,14 +2885,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 @@ -2827,8 +2917,10 @@ retry: if (st16[i].op >= OP_CALL1 && st16[i].op <= OP_CALL8) { if (st16[i].b) + { hexencalling = true; - + break; + } } } if (hexencalling) @@ -2841,32 +2933,8 @@ retry: } break; - case 24: //24 sucks. Guess why. - 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; - - } - } - 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: + case PST_KKQWSV: //24 sucks. Guess why. + case PST_FTE32: for (i=0 ; inumstatements ; i++) { #ifndef NOENDIAN @@ -2878,8 +2946,10 @@ retry: if (pr_statements32[i].op >= OP_CALL1 && pr_statements32[i].op <= OP_CALL8) { if (pr_statements32[i].b) + { hexencalling = true; - + break; + } } } if (hexencalling) @@ -2897,7 +2967,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; } @@ -2911,10 +2981,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) @@ -2960,7 +3030,8 @@ retry: } } break; - case 32: + case PST_QTEST: + case PST_FTE32: for (i=0 ; inumglobaldefs ; i++) { if (pr_types) @@ -3013,7 +3084,7 @@ retry: } break; default: - Sys_Error("Bad int size"); + Sys_Error("Bad struct type"); } if ((isfriked && pr_typecurrent)) //friked progs only allow one file. @@ -3031,13 +3102,13 @@ retry: 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, NULL); 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]; @@ -3065,9 +3136,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]; @@ -3092,7 +3164,7 @@ retry: break; } - eval = PR_FindGlobal(progfuncs, "__ext__fasttrackarrays", PR_CURRENT); + eval = PR_FindGlobal(progfuncs, "__ext__fasttrackarrays", PR_CURRENT, NULL); if (eval) //we support these opcodes eval->_float = true; diff --git a/misc/source/fteqcc-src/pr_exec.c b/misc/source/fteqcc-src/pr_exec.c index bdd2af95..97956039 100644 --- a/misc/source/fteqcc-src/pr_exec.c +++ b/misc/source/fteqcc-src/pr_exec.c @@ -7,6 +7,22 @@ #define Host_Error Sys_Error +// I put the following here to resolve "undefined reference to `__imp__vsnprintf'" with MinGW64 ~ Moodles +#ifdef _WIN32 + #if (_MSC_VER >= 1400) + //with MSVC 8, use MS extensions + #define snprintf linuxlike_snprintf_vc8 + int VARGS linuxlike_snprintf_vc8(char *buffer, int size, const char *format, ...) LIKEPRINTF(3); + #define vsnprintf(a, b, c, d) vsnprintf_s(a, b, _TRUNCATE, c, d) + #else + //msvc crap + #define snprintf linuxlike_snprintf + int VARGS linuxlike_snprintf(char *buffer, int size, const char *format, ...) LIKEPRINTF(3); + #define vsnprintf linuxlike_vsnprintf + int VARGS linuxlike_vsnprintf(char *buffer, int size, const char *format, va_list argptr); + #endif +#endif + //============================================================================= @@ -28,7 +44,7 @@ return; for ( ; i<10 ; i++) printf (" "); } - + if (s->op == OP_IF || s->op == OP_IFNOT) printf ("%sbranch %i",PR_GlobalString(progfuncs, s->a),s->b); else if (s->op == OP_GOTO) @@ -84,13 +100,13 @@ void PR_StackTrace (progfuncs_t *progfuncs) int *globalbase; #endif progs = -1; - + if (pr_depth == 0) { printf ("\n"); return; } - + #ifdef STACKTRACE globalbase = (int *)pr_globals + pr_xfunction->parm_start - pr_xfunction->locals; #endif @@ -100,7 +116,7 @@ void PR_StackTrace (progfuncs_t *progfuncs) for (i=pr_depth ; i>0 ; i--) { f = pr_stack[i].f; - + if (!f) { printf ("\n"); @@ -216,8 +232,8 @@ void VARGS PR_RunError (progfuncs_t *progfuncs, char *error, ...) printf ("\n"); //editbadfile(pr_strings + pr_xfunction->s_file, -1); - -// pr_depth = 0; // dump the stack so host_error can shutdown functions + +// pr_depth = 0; // dump the stack so host_error can shutdown functions // prinst->exitdepth = 0; Abort ("%s", string); @@ -239,12 +255,12 @@ Returns the new program statement counter ==================== */ void PR_AbortStack (progfuncs_t *progfuncs); -int PR_EnterFunction (progfuncs_t *progfuncs, dfunction_t *f, int progsnum) +int ASMCALL PR_EnterFunction (progfuncs_t *progfuncs, dfunction_t *f, int progsnum) { int i, j, c, o; pr_stack[pr_depth].s = pr_xstatement; - pr_stack[pr_depth].f = pr_xfunction; + pr_stack[pr_depth].f = pr_xfunction; pr_stack[pr_depth].progsnum = progsnum; pr_stack[pr_depth].pushed = pr_spushed; pr_depth++; @@ -296,7 +312,7 @@ int PR_EnterFunction (progfuncs_t *progfuncs, dfunction_t *f, int progsnum) PR_LeaveFunction ==================== */ -int PR_LeaveFunction (progfuncs_t *progfuncs) +int ASMCALL PR_LeaveFunction (progfuncs_t *progfuncs) { int i, c; @@ -330,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++) @@ -361,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++) @@ -383,10 +400,10 @@ 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; } - + *val = (eval_t *)&pr_progstate[pr_typecurrent].globals[def32->ofs]; return &def; } @@ -426,7 +443,7 @@ char *EvaluateDebugString(progfuncs_t *progfuncs, char *key) c = strchr(key, '.'); if (c) *c = '\0'; - def = ED_FindLocalOrGlobal(progfuncs, key, &val); + def = ED_FindLocalOrGlobal(progfuncs, key, &val); if (!def) { if (atoi(key)) @@ -440,13 +457,13 @@ char *EvaluateDebugString(progfuncs_t *progfuncs, char *key) } if (c) *c = '.'; if (!def) - { + { return "(Bad string)"; - } + } type = def->type; //go through ent vars - c = strchr(key, '.'); + c = strchr(key, '.'); while(c) { c2 = c+1; @@ -461,10 +478,10 @@ char *EvaluateDebugString(progfuncs_t *progfuncs, char *key) if (c)*c = '.'; if (!fdef) return "(Bad string)"; - val = (eval_t *) (((char *)PROG_TO_EDICT(progfuncs, val->_int)->fields) + fdef->ofs*4); + val = (eval_t *) (((char *)PROG_TO_EDICT(progfuncs, val->_int)->fields) + fdef->ofs*4); type = fdef->type; } - + if (assignment) { assignment++; @@ -473,7 +490,7 @@ char *EvaluateDebugString(progfuncs_t *progfuncs, char *key) case ev_string: *(string_t *)val = PR_StringToProgs(progfuncs, ED_NewString (progfuncs, assignment, 0)); break; - + case ev_float: *(float *)val = (float)atof (assignment); break; @@ -481,7 +498,7 @@ char *EvaluateDebugString(progfuncs_t *progfuncs, char *key) case ev_integer: *(int *)val = atoi (assignment); break; - + /* case ev_vector: strcpy (string, assignment); v = string; @@ -504,7 +521,7 @@ char *EvaluateDebugString(progfuncs_t *progfuncs, char *key) fdef = ED_FindField (progfuncs, assignment); if (!fdef) { - int l,nl = strlen(assignment); + size_t l,nl = strlen(assignment); strcpy(buf, "Can't find field "); l = strlen(buf); if (nl > sizeof(buf)-l-2) @@ -537,7 +554,7 @@ char *EvaluateDebugString(progfuncs_t *progfuncs, char *key) func = ED_FindFunction (progfuncs, s, &i, progsnum); if (!func) { - int l,nl = strlen(s); + size_t l,nl = strlen(s); assignment[-1] = '='; @@ -573,25 +590,26 @@ void SetExecutionToLine(progfuncs_t *progfuncs, int linenum) int snum; dfunction_t *f = pr_xfunction; - switch(current_progstate->intsize) + switch(current_progstate->structtype) { - case 16: - for (snum = f->first_statement; pr_progstate[pn].linenums[snum] < linenum; snum++) + case PST_DEFAULT: + case PST_QTEST: + 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: - for (snum = f->first_statement; pr_progstate[pn].linenums[snum] < linenum; snum++) + 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) return; } break; default: - Sys_Error("Bad intsize"); + Sys_Error("Bad struct type"); snum = 0; } debugstatement = snum; @@ -606,7 +624,7 @@ int PR_ToggleBreakpoint(progfuncs_t *progfuncs, char *filename, int linenum, int unsigned int i; int pn = pr_typecurrent; dfunction_t *f; - int op; + int op = 0; //warning about not being initialized before use for (pn = 0; (unsigned)pn < maxprogs; pn++) { @@ -632,17 +650,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) @@ -673,19 +692,20 @@ 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; - } + } } goto cont; } @@ -700,17 +720,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) { @@ -740,17 +761,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; } @@ -772,7 +794,7 @@ static char *lastfile = 0; int pn = pr_typecurrent; int i; - dfunction_t *f = pr_xfunction; + dfunction_t *f = pr_xfunction; if (f && pr_progstate[pn].linenums && externs->useeditor) { @@ -806,7 +828,7 @@ static char *lastfile = 0; externs->useeditor(progfuncs, f->s_file+progfuncs->stringtable, -1, 0, NULL); return statement; } - + return statement; } @@ -821,7 +843,7 @@ void PR_ExecuteCode (progfuncs_t *progfuncs, int s) { eval_t *t, *swtch=NULL; - int swtchtype; + int swtchtype = 0; //warning about not being initialized before use dstatement16_t *st16; dstatement32_t *st32; dfunction_t *newf; @@ -837,9 +859,9 @@ void PR_ExecuteCode (progfuncs_t *progfuncs, int s) prinst->continuestatement = -1; #ifdef QCJIT - if (prinst->usejit) + if (prinst->jit) { - PR_EnterJIT(progfuncs, s); + PR_EnterJIT(progfuncs, prinst->jit, s); return; } #endif @@ -866,9 +888,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) @@ -881,16 +904,16 @@ restart: //jumped to when the progs might have changed. #endif #undef DEBUGABLE } - + while(1) { #include "execloop.h" - } + } #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) @@ -903,7 +926,7 @@ restart: //jumped to when the progs might have changed. #endif #undef DEBUGABLE } - + while(1) { #ifdef SEPARATEINCLUDES @@ -912,11 +935,11 @@ restart: //jumped to when the progs might have changed. #include "execloop.h" #endif } -#undef INTSIZE +#undef INTSIZE Sys_Error("PR_ExecuteProgram - should be unreachable"); break; default: - Sys_Error("PR_ExecuteProgram - bad intsize"); + Sys_Error("PR_ExecuteProgram - bad structtype"); } } @@ -1035,7 +1058,7 @@ struct qcthread_s *PR_ForkStack(progfuncs_t *progfuncs) int localsoffset, baselocalsoffset; qcthread_t *thread = memalloc(sizeof(qcthread_t)); dfunction_t *f; - + //copy out the functions stack. for (i = 0,localsoffset=0; i < ed; i++) { @@ -1048,7 +1071,7 @@ struct qcthread_s *PR_ForkStack(progfuncs_t *progfuncs) baselocalsoffset = localsoffset; for (i = ed; i < pr_depth; i++) { - thread->fstack[i-ed].fnum = pr_stack[i].f - pr_progstate[pr_stack[i].progsnum].functions; + thread->fstack[i-ed].fnum = pr_stack[i].f - pr_progstate[pr_stack[i].progsnum].functions; thread->fstack[i-ed].progsnum = pr_stack[i].progsnum; thread->fstack[i-ed].statement = pr_stack[i].s; @@ -1138,7 +1161,7 @@ void PR_ResumeThread (progfuncs_t *progfuncs, struct qcthread_s *thread) else { pr_stack[pr_depth].progsnum = thread->fstack[i].progsnum; - pr_stack[pr_depth].f = pr_progstate[thread->fstack[i].progsnum].functions + thread->fstack[i].fnum; + pr_stack[pr_depth].f = pr_progstate[thread->fstack[i].progsnum].functions + thread->fstack[i].fnum; pr_stack[pr_depth].s = thread->fstack[i].statement; } @@ -1158,7 +1181,7 @@ void PR_ResumeThread (progfuncs_t *progfuncs, struct qcthread_s *thread) if (ls != thread->lstackused) PR_RunError(progfuncs, "Thread stores incorrect locals count\n"); - + f = &pr_functions[fnum]; // thread->lstackused -= f->locals; //the current function is the odd one out. diff --git a/misc/source/fteqcc-src/pr_multi.c b/misc/source/fteqcc-src/pr_multi.c index 5a1ade75..b66b8b5e 100644 --- a/misc/source/fteqcc-src/pr_multi.c +++ b/misc/source/fteqcc-src/pr_multi.c @@ -90,10 +90,11 @@ progsnum_t PR_LoadProgs(progfuncs_t *progfuncs, char *s, int headercrc, builtin_ { current_progstate->builtins = builtins; current_progstate->numbuiltins = numbuiltins; + if (a <= progfuncs->numprogs) + progfuncs->numprogs = a+1; #ifdef QCJIT - if (prinst->usejit) - prinst->usejit = PR_GenerateJit(progfuncs); + prinst->jit = PR_GenerateJit(progfuncs); #endif if (oldtype>=0) PR_SwitchProgs(progfuncs, oldtype); @@ -205,7 +206,7 @@ void QC_FlushProgsOffsets(progfuncs_t *progfuncs) //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) +int QC_RegisterFieldVar(progfuncs_t *progfuncs, unsigned int type, char *name, signed long engineofs, signed long progsofs) { // progstate_t *p; // int pnum; @@ -231,7 +232,7 @@ int QC_RegisterFieldVar(progfuncs_t *progfuncs, unsigned int type, char *name, i { if (field[i].type != type) { - printf("Field type mismatch on \"%s\"\n", name); + printf("Field type mismatch on \"%s\". %i != %i\n", name, field[i].type, type); continue; } if (!progfuncs->fieldadjust && engineofs>=0) @@ -296,7 +297,7 @@ int QC_RegisterFieldVar(progfuncs_t *progfuncs, unsigned int type, char *name, i } }*/ if (engineofs&3) - Sys_Error("field %s is %i&3", name, engineofs); + Sys_Error("field %s is %i&3", name, (int)engineofs); field[fnum].ofs = ofs = engineofs/4; } else @@ -358,10 +359,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 +393,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/misc/source/fteqcc-src/pr_x86.c b/misc/source/fteqcc-src/pr_x86.c index 4ebfdda2..9f217b33 100644 --- a/misc/source/fteqcc-src/pr_x86.c +++ b/misc/source/fteqcc-src/pr_x86.c @@ -10,16 +10,31 @@ optimisations: instructions need to be chained. stuff that writes to C should be cacheable, etc. maybe we don't even need to do the write to C it should also be possible to fold in eq+ifnot, so none of this silly storeing of floats in equality tests + this means that we need to track which vars are cached and in what form: fpreg, ireg+floatasint, ireg+float. + certain qccx hacks can use fpu operations on ints, so do what the instruction says, rather than considering an add an add regardless of types. + + OP_AND_F, OP_OR_F etc will generally result in ints, and we should be able to keep them as ints if they combine with other ints. + + some instructions are jump sites. any cache must be flushed before the start of the instruction. + some variables are locals, and will only ever be written by a single instruction, then read by the following instruction. such temps do not need to be written, or are overwritten later in the function anyway. + such locals need to be calculated PER FUNCTION as (fte)qcc can overlap locals making multiple distinct locals on a single offset. + + store locals on a proper stack instead of the current absurd mechanism. + eax - tmp ebx - prinst->edicttable ecx - tmp edx - tmp - esi - + esi - debug opcode number edi - tmp (because its preserved by subfunctions - ebp - + ebp - to use gas to provide binary opcodes: vim -N blob.s && as blob.s && objdump.exe -d a.out + + + notable mods to test: + prydon gate, due to fpu mangling to carry values between maps */ #define PROGSUSED @@ -29,59 +44,135 @@ optimisations: static float ta, tb, nullfloat=0; -unsigned int *statementjumps; //[MAX_STATEMENTS*2] -unsigned char **statementoffsets; //[MAX_STATEMENTS] -unsigned int numjumps; -unsigned char *code; -unsigned int codesize; -unsigned int jitstatements; - -void EmitByte(unsigned char byte) +struct jitstate { - code[codesize++] = byte; + unsigned int *statementjumps; //[MAX_STATEMENTS*3] + unsigned char **statementoffsets; //[MAX_STATEMENTS] + unsigned int numjumps; + unsigned char *code; + unsigned int codesize; + unsigned int jitstatements; +}; + +static void EmitByte(struct jitstate *jit, unsigned char byte) +{ + jit->code[jit->codesize++] = byte; } -void Emit4Byte(unsigned int value) +static void Emit4Byte(struct jitstate *jit, unsigned int value) { - code[codesize++] = (value>> 0)&0xff; - code[codesize++] = (value>> 8)&0xff; - code[codesize++] = (value>>16)&0xff; - code[codesize++] = (value>>24)&0xff; + jit->code[jit->codesize++] = (value>> 0)&0xff; + jit->code[jit->codesize++] = (value>> 8)&0xff; + jit->code[jit->codesize++] = (value>>16)&0xff; + jit->code[jit->codesize++] = (value>>24)&0xff; } -void EmitAdr(void *value) +static void EmitAdr(struct jitstate *jit, void *value) { - Emit4Byte((unsigned int)value); + Emit4Byte(jit, (unsigned int)value); } -void EmitFloat(float value) +static void EmitFloat(struct jitstate *jit, float value) { union {float f; unsigned int i;} u; u.f = value; - Emit4Byte(u.i); + Emit4Byte(jit, u.i); } -void Emit2Byte(unsigned short value) +static void Emit2Byte(struct jitstate *jit, unsigned short value) { - code[codesize++] = (value>> 0)&0xff; - code[codesize++] = (value>> 8)&0xff; + jit->code[jit->codesize++] = (value>> 0)&0xff; + jit->code[jit->codesize++] = (value>> 8)&0xff; } -void EmitFOffset(void *func, int bias) +static void EmitFOffset(struct jitstate *jit, void *func, int bias) { union {void *f; unsigned int i;} u; u.f = func; - u.i -= (unsigned int)&code[codesize+bias]; - Emit4Byte(u.i); + u.i -= (unsigned int)&jit->code[jit->codesize+bias]; + Emit4Byte(jit, u.i); } -void Emit4ByteJump(int statementnum, int offset) +static void Emit4ByteJump(struct jitstate *jit, int statementnum, int offset) { - statementjumps[numjumps++] = codesize; - statementjumps[numjumps++] = statementnum; - statementjumps[numjumps++] = offset; + jit->statementjumps[jit->numjumps++] = jit->codesize; + jit->statementjumps[jit->numjumps++] = statementnum; + jit->statementjumps[jit->numjumps++] = offset; //the offset is filled in later - codesize += 4; + jit->codesize += 4; } -void FixupJumps(void) +enum +{ + REG_EAX, + REG_ECX, + REG_EDX, + REG_EBX, + REG_ESP, + REG_EBP, + REG_ESI, + REG_EDI +}; +#define XOR(sr,dr) EmitByte(0x31);EmitByte(0xc0 | (sr<<3) | dr); +#define CLEARREG(reg) XOR(reg,reg) +#define LOADREG(addr, reg) if (reg == REG_EAX) {EmitByte(0xa1);} else {EmitByte(0x8b); EmitByte((reg<<3) | 0x05);} EmitAdr(addr); +#define STOREREG(reg, addr) if (reg == REG_EAX) {EmitByte(0xa3);} else {EmitByte(0x89); EmitByte((reg<<3) | 0x05);} EmitAdr(addr); +#define STOREF(f, addr) EmitByte(0xc7);EmitByte(0x05); EmitAdr(addr);EmitFloat(f); +#define STOREI(i, addr) EmitByte(0xc7);EmitByte(0x05); EmitAdr(addr);Emit4Byte(i); +#define SETREGI(val,reg) EmitByte(0xbe);Emit4Byte(val); + +static void *LocalLoc(struct jitstate *jit) +{ + return &jit->code[jit->codesize]; +} +static void *LocalJmp(struct jitstate *jit, int cond) +{ + /*floating point ops don't set the sign flag, thus we use the 'above/below' instructions instead of 'greater/less' instructions*/ + if (cond == OP_GOTO) + EmitByte(jit, 0xeb); //jmp + else if (cond == OP_LE_F) + EmitByte(jit, 0x76); //jbe + else if (cond == OP_GE_F) + EmitByte(jit, 0x73); //jae + else if (cond == OP_LT_F) + EmitByte(jit, 0x72); //jb + else if (cond == OP_GT_F) + EmitByte(jit, 0x77); //ja + else if (cond == OP_LE_I) + EmitByte(jit, 0x7e); //jle + else if (cond == OP_LT_I) + EmitByte(jit, 0x7c); //jl + else if ((cond >= OP_NE_F && cond <= OP_NE_FNC) || cond == OP_NE_I) + EmitByte(jit, 0x75); //jne + else if ((cond >= OP_EQ_F && cond <= OP_EQ_FNC) || cond == OP_EQ_I) + EmitByte(jit, 0x74); //je +#if defined(DEBUG) && defined(_WIN32) + else + { + OutputDebugString("oh noes!\n"); + return NULL; + } +#endif + + EmitByte(jit, 0); + + return LocalLoc(jit); +} +static void LocalJmpLoc(void *jmp, void *loc) +{ + int offs; + unsigned char *a = jmp; + offs = (char *)loc - (char *)jmp; +#if defined(DEBUG) && defined(_WIN32) + if (offs > 127 || offs <= -128) + { + OutputDebugStringA("bad jump\n"); + a[-2] = 0xcd; + a[-1] = 0xcc; + return; + } +#endif + a[-1] = offs; +} + +static void FixupJumps(struct jitstate *jit) { unsigned int j; unsigned char *codesrc; @@ -90,15 +181,15 @@ void FixupJumps(void) unsigned int v; - for (j = 0; j < numjumps;) + for (j = 0; j < jit->numjumps;) { - v = statementjumps[j++]; - codesrc = &code[v]; + v = jit->statementjumps[j++]; + codesrc = &jit->code[v]; - v = statementjumps[j++]; - codedst = statementoffsets[v]; + v = jit->statementjumps[j++]; + codedst = jit->statementoffsets[v]; - v = statementjumps[j++]; + v = jit->statementjumps[j++]; offset = (int)(codedst - (codesrc-v)); //3rd term because the jump is relative to the instruction start, not the instruction's offset codesrc[0] = (offset>> 0)&0xff; @@ -108,53 +199,81 @@ void FixupJumps(void) } } -int PR_LeaveFunction (progfuncs_t *progfuncs); -int PR_EnterFunction (progfuncs_t *progfuncs, dfunction_t *f, int progsnum); +int ASMCALL PR_LeaveFunction (progfuncs_t *progfuncs); +int ASMCALL PR_EnterFunction (progfuncs_t *progfuncs, dfunction_t *f, int progsnum); + +void PR_CloseJit(struct jitstate *jit) +{ + free(jit->statementjumps); + free(jit->statementoffsets); + free(jit->code); +} + +#define EmitByte(v) EmitByte(jit, v) +#define EmitAdr(v) EmitAdr(jit, v) +#define EmitFOffset(a,b) EmitFOffset(jit, a, b) +#define Emit4ByteJump(a,b) Emit4ByteJump(jit, a, b) +#define Emit4Byte(v) Emit4Byte(jit, v) +#define EmitFloat(v) EmitFloat(jit, v) +#define LocalJmp(v) LocalJmp(jit, v) +#define LocalLoc() LocalLoc(jit) + -pbool PR_GenerateJit(progfuncs_t *progfuncs) +struct jitstate *PR_GenerateJit(progfuncs_t *progfuncs) { + struct jitstate *jit; + + void *j0, *l0; + void *j1, *l1; + void *j2, *l2; unsigned int i; dstatement16_t *op = (dstatement16_t*)current_progstate->statements; unsigned int numstatements = current_progstate->progs->numstatements; int *glob = (int*)current_progstate->globals; if (current_progstate->numbuiltins) - return false; - - jitstatements = numstatements; + return NULL; + jit = malloc(sizeof(*jit)); + jit->jitstatements = numstatements; - statementjumps = malloc(numstatements*12); - statementoffsets = malloc(numstatements*4); - code = malloc(numstatements*500); + jit->statementjumps = malloc(numstatements*12); + jit->statementoffsets = malloc(numstatements*4); + jit->code = malloc(numstatements*500); + if (!jit->code) + return NULL; - numjumps = 0; - codesize = 0; + jit->numjumps = 0; + jit->codesize = 0; for (i = 0; i < numstatements; i++) { - statementoffsets[i] = &code[codesize]; + jit->statementoffsets[i] = &jit->code[jit->codesize]; + + /*DEBUG*/ + SETREGI(op[i].op, REG_ESI); + switch(op[i].op) { //jumps - case OP_IF: + case OP_IF_I: //integer compare //if a, goto b //cmpl $0,glob[A] EmitByte(0x83);EmitByte(0x3d);EmitAdr(glob + op[i].a);EmitByte(0x0); - //jnz B + //jne B EmitByte(0x0f);EmitByte(0x85);Emit4ByteJump(i + (signed short)op[i].b, -4); break; - case OP_IFNOT: + case OP_IFNOT_I: //integer compare //if !a, goto b //cmpl $0,glob[A] EmitByte(0x83);EmitByte(0x3d);EmitAdr(glob + op[i].a);EmitByte(0x0); - //jz B + //je B EmitByte(0x0f);EmitByte(0x84);Emit4ByteJump(i + (signed short)op[i].b, -4); break; @@ -173,25 +292,19 @@ pbool PR_GenerateJit(progfuncs_t *progfuncs) { //assumption: anything that returns address 0 is a void or zero return. //thus clear eax and copy that to the return vector. - EmitByte(0x31);EmitByte(0xc0); - EmitByte(0xa3);EmitAdr(glob + OFS_RETURN+0); - EmitByte(0xa3);EmitAdr(glob + OFS_RETURN+1); - EmitByte(0xa3);EmitAdr(glob + OFS_RETURN+2); + CLEARREG(REG_EAX); + STOREREG(REG_EAX, glob + OFS_RETURN+0); + STOREREG(REG_EAX, glob + OFS_RETURN+1); + STOREREG(REG_EAX, glob + OFS_RETURN+2); } else { - //movl glob[A+0],eax - EmitByte(0xa1);EmitAdr(glob + op[i].a+0); - //movl glob[A+0],edx - EmitByte(0x8b);EmitByte(0x0d);EmitAdr(glob + op[i].a+1); - //movl glob[A+0],ecx - EmitByte(0x8b);EmitByte(0x15);EmitAdr(glob + op[i].a+2); - //movl eax, glob[OFS_RET+0] - EmitByte(0xa3);EmitAdr(glob + OFS_RETURN+0); - //movl edx, glob[OFS_RET+0] - EmitByte(0x89);EmitByte(0x15);EmitAdr(glob + OFS_RETURN+1); - //movl ecx, glob[OFS_RET+0] - EmitByte(0x89);EmitByte(0x15);EmitAdr(glob + OFS_RETURN+2); + LOADREG(glob + op[i].a+0, REG_EAX); + LOADREG(glob + op[i].a+1, REG_EDX); + LOADREG(glob + op[i].a+2, REG_ECX); + STOREREG(REG_EAX, glob + OFS_RETURN+0); + STOREREG(REG_EDX, glob + OFS_RETURN+1); + STOREREG(REG_ECX, glob + OFS_RETURN+2); } //call leavefunction to get the return address @@ -207,14 +320,17 @@ pbool PR_GenerateJit(progfuncs_t *progfuncs) // cmp prinst->exitdepth,%edx EmitByte(0x3b);EmitByte(0x15);EmitAdr(&prinst->exitdepth); // je returntoc - EmitByte(0x74);EmitByte(0x09); -// mov statementoffsets[%eax*4],%eax - EmitByte(0x8b);EmitByte(0x04);EmitByte(0x85);EmitAdr(statementoffsets+1); -// jmp eax - EmitByte(0xff);EmitByte(0xe0); + j1 = LocalJmp(OP_EQ_E); +// mov statementoffsets[%eax*4],%eax + EmitByte(0x8b);EmitByte(0x04);EmitByte(0x85);EmitAdr(jit->statementoffsets+1); +// jmp *eax + EmitByte(0xff);EmitByte(0xe0); // returntoc: + l1 = LocalLoc(); // ret EmitByte(0xc3); + + LocalJmpLoc(j1,l1); break; //function calls @@ -229,13 +345,13 @@ pbool PR_GenerateJit(progfuncs_t *progfuncs) case OP_CALL8: //save the state in place the rest of the engine can cope with //movl $i, pr_xstatement - EmitByte(0xc7);EmitByte(0x05);EmitAdr(&pr_xstatement);Emit4Byte(i); + EmitByte( 0xc7);EmitByte(0x05);EmitAdr(&pr_xstatement);Emit4Byte(i); //movl $(op[i].op-OP_CALL0), pr_argc - EmitByte(0xc7);EmitByte(0x05);EmitAdr(&pr_argc);Emit4Byte(op[i].op-OP_CALL0); + EmitByte( 0xc7);EmitByte(0x05);EmitAdr(&pr_argc);Emit4Byte(op[i].op-OP_CALL0); //figure out who we're calling, and what that involves //%eax = glob[A] - EmitByte(0xa1); EmitAdr(glob + op[i].a); + LOADREG(glob + op[i].a, REG_EAX); //eax is now the func num //mov %eax,%ecx @@ -247,7 +363,7 @@ pbool PR_GenerateJit(progfuncs_t *progfuncs) //cmp %ecx,pr_typecurrent EmitByte(0x39); EmitByte(0x0d); EmitAdr(&pr_typecurrent); //je sameprogs - EmitByte(0x74); EmitByte(0x3); + j1 = LocalJmp(OP_EQ_I); { //can't handle switching progs @@ -266,6 +382,8 @@ pbool PR_GenerateJit(progfuncs_t *progfuncs) EmitByte(0xc3); } //sameprogs: + l1 = LocalLoc(); + LocalJmpLoc(j1,l1); //andl $0x00ffffff, %eax EmitByte(0x25);Emit4Byte(0x00ffffff); @@ -286,9 +404,9 @@ pbool PR_GenerateJit(progfuncs_t *progfuncs) //cmp $0,%edx EmitByte(0x83);EmitByte(0xfa);EmitByte(0x00); //jl isabuiltin - EmitByte(0x7c);EmitByte(22); - + j1 = LocalJmp(OP_LT_I); { + /* call the function*/ //push %ecx EmitByte(0x51); //push %eax @@ -302,10 +420,12 @@ pbool PR_GenerateJit(progfuncs_t *progfuncs) //eax is now the next statement number (first of the new function, usually equal to ecx, but not always) //jmp statementoffsets[%eax*4] - EmitByte(0xff);EmitByte(0x24);EmitByte(0x85);EmitAdr(statementoffsets+1); + EmitByte(0xff);EmitByte(0x24);EmitByte(0x85);EmitAdr(jit->statementoffsets+1); } + /*its a builtin, figure out which, and call it*/ //isabuiltin: - + l1 = LocalLoc(); + LocalJmpLoc(j1,l1); //push current_progstate->globals EmitByte(0x68);EmitAdr(current_progstate->globals); @@ -321,23 +441,21 @@ pbool PR_GenerateJit(progfuncs_t *progfuncs) //but that builtin might have been Abort() - //mov prinst->continuestatement,%eax - EmitByte(0xa1);EmitAdr(&prinst->continuestatement); - //eax is now prinst->continuestatement - + LOADREG(&prinst->continuestatement, REG_EAX); //cmp $-1,%eax EmitByte(0x83);EmitByte(0xf8);EmitByte(0xff); //je donebuiltincall - EmitByte(0x74);EmitByte(10+8); + j1 = LocalJmp(OP_EQ_I); { -EmitByte(0xcc); - //jmp statementoffsets[%eax*4] - EmitByte(0xff);EmitByte(0x24);EmitByte(0x85);EmitAdr(statementoffsets+1); - //mov $-1,prinst->continuestatement - EmitByte(0xc7);EmitByte(0x05);EmitAdr(&prinst->continuestatement+1);Emit4Byte((unsigned int)-1); + EmitByte(0xc7);EmitByte(0x05);EmitAdr(&prinst->continuestatement);Emit4Byte((unsigned int)-1); + + //jmp statementoffsets[%eax*4] + EmitByte(0xff);EmitByte(0x24);EmitByte(0x85);EmitAdr(jit->statementoffsets); } //donebuiltincall: + l1 = LocalLoc(); + LocalJmpLoc(j1,l1); break; case OP_MUL_F: @@ -374,24 +492,29 @@ EmitByte(0xcc); break; case OP_NOT_F: - //flds glob[A] - EmitByte(0xd9);EmitByte(0x05);EmitAdr(glob + op[i].a); //fldz EmitByte(0xd9);EmitByte(0xee); + //fcomps glob[A] + EmitByte(0xd8); EmitByte(0x1d); EmitAdr(glob + op[i].a); //fnstsw %ax EmitByte(0xdf);EmitByte(0xe0); //testb 0x40,%ah EmitByte(0xf6);EmitByte(0xc4);EmitByte(0x40); - //je noteq - EmitByte(0x74);EmitByte(0x0c); - //movl 1.0f,glob[C] - EmitByte(0xc7);EmitByte(0x05);EmitAdr(glob + op[i].c);EmitFloat(0.0f); - //jmp end - EmitByte(0xeb);EmitByte(0x0a); - //noteq: - //movl 0.0f,glob[C] - EmitByte(0xc7);EmitByte(0x05);EmitAdr(glob + op[i].c);EmitFloat(1.0f); + + j1 = LocalJmp(OP_NE_F); + { + STOREF(0.0f, glob + op[i].c); + j2 = LocalJmp(OP_GOTO); + } + { + //noteq: + l1 = LocalLoc(); + STOREF(1.0f, glob + op[i].c); + } //end: + l2 = LocalLoc(); + LocalJmpLoc(j1,l1); + LocalJmpLoc(j2,l2); break; case OP_STORE_F: @@ -399,26 +522,17 @@ EmitByte(0xcc); case OP_STORE_ENT: case OP_STORE_FLD: case OP_STORE_FNC: - //movl glob[A],eax - EmitByte(0xa1);EmitAdr(glob + op[i].a); - //movl eax,glob[B] - EmitByte(0xa3);EmitAdr(glob + op[i].b); + LOADREG(glob + op[i].a, REG_EAX); + STOREREG(REG_EAX, glob + op[i].b); break; case OP_STORE_V: - //movl glob[A+0],eax - EmitByte(0xa1);EmitAdr(glob + op[i].a+0); - //movl glob[A+1],edx - EmitByte(0x8b);EmitByte(0x0d);EmitAdr(glob + op[i].a+1); - //movl glob[A+2],ecx - EmitByte(0x8b);EmitByte(0x15);EmitAdr(glob + op[i].a+2); - - //movl eax, glob[B+0] - EmitByte(0xa3);EmitAdr(glob + op[i].b+0); - //movl edx, glob[B+1] - EmitByte(0x89);EmitByte(0x15);EmitAdr(glob + op[i].b+1); - //movl ecx, glob[B+2] - EmitByte(0x89);EmitByte(0x15);EmitAdr(glob + op[i].b+2); + LOADREG(glob + op[i].a+0, REG_EAX); + LOADREG(glob + op[i].a+1, REG_EDX); + LOADREG(glob + op[i].a+2, REG_ECX); + STOREREG(REG_EAX, glob + op[i].b+0); + STOREREG(REG_EDX, glob + op[i].b+1); + STOREREG(REG_ECX, glob + op[i].b+2); break; case OP_LOAD_F: @@ -430,10 +544,9 @@ EmitByte(0xcc); //a is the ent number, b is the field //c is the dest - //movl glob[A+0],eax - EmitByte(0xa1);EmitAdr(glob + op[i].a); - //mov glob[B],ecx - EmitByte(0x8b); EmitByte(0x0d);EmitAdr(glob + op[i].b); + LOADREG(glob + op[i].a, REG_EAX); + LOADREG(glob + op[i].b, REG_ECX); + //FIXME: bound eax (ent number) //FIXME: bound ecx (field index) //mov (ebx,eax,4).%eax @@ -443,22 +556,20 @@ EmitByte(0xcc); EmitByte(0x8b);EmitByte(0x50);EmitByte((int)&((edictrun_t*)NULL)->fields); //edx is now the field array for that ent - //mov fieldajust(%edx,%ecx,4),%eax //offset = progfuncs->fieldadjust + //mov fieldajust(%edx,%ecx,4),%eax EmitByte(0x8b); EmitByte(0x84); EmitByte(0x8a); Emit4Byte(progfuncs->fieldadjust*4); - //mov edx,glob[C] - EmitByte(0xa3);EmitAdr(glob + op[i].c); + + STOREREG(REG_EAX, glob + op[i].c) if (op[i].op == OP_LOAD_V) { - //mov fieldajust+4(%edx,%ecx,4),%eax //offset = progfuncs->fieldadjust + //mov fieldajust+4(%edx,%ecx,4),%eax EmitByte(0x8b); EmitByte(0x84); EmitByte(0x8a); Emit4Byte(4+progfuncs->fieldadjust*4); - //mov edx,glob[C+1] - EmitByte(0xa3);EmitAdr(glob + op[i].c+1); + STOREREG(REG_EAX, glob + op[i].c+1) - //mov fieldajust+8(%edx,%ecx,4),%eax //offset = progfuncs->fieldadjust - EmitByte(0x8b); EmitByte(0x84); EmitByte(0x8a); Emit4Byte(4+progfuncs->fieldadjust*4); - //mov edx,glob[C+1] - EmitByte(0xa3);EmitAdr(glob + op[i].c+2); + //mov fieldajust+8(%edx,%ecx,4),%eax + EmitByte(0x8b); EmitByte(0x84); EmitByte(0x8a); Emit4Byte(8+progfuncs->fieldadjust*4); + STOREREG(REG_EAX, glob + op[i].c+2) } break; @@ -466,10 +577,9 @@ EmitByte(0xcc); //a is the ent number, b is the field //c is the dest - //movl glob[A+0],eax - EmitByte(0xa1);EmitAdr(glob + op[i].a); - //mov glob[B],ecx - EmitByte(0x8b); EmitByte(0x0d);EmitAdr(glob + op[i].b); + LOADREG(glob + op[i].a, REG_EAX); + LOADREG(glob + op[i].b, REG_ECX); + //FIXME: bound eax (ent number) //FIXME: bound ecx (field index) //mov (ebx,eax,4).%eax @@ -481,8 +591,7 @@ EmitByte(0xcc); //mov fieldajust(%edx,%ecx,4),%eax //offset = progfuncs->fieldadjust //EmitByte(0x8d); EmitByte(0x84); EmitByte(0x8a); EmitByte(progfuncs->fieldadjust*4); EmitByte(0x8d); EmitByte(0x84); EmitByte(0x8a); Emit4Byte(progfuncs->fieldadjust*4); - //mov edx,glob[C] - EmitByte(0xa3);EmitAdr(glob + op[i].c); + STOREREG(REG_EAX, glob + op[i].c); break; case OP_STOREP_F: @@ -490,118 +599,111 @@ EmitByte(0xcc); case OP_STOREP_ENT: case OP_STOREP_FLD: case OP_STOREP_FNC: - //movl glob[A],eax - EmitByte(0xa1);EmitAdr(glob + op[i].a); - //mov glob[B],ecx - EmitByte(0x8b); EmitByte(0x0d);EmitAdr(glob + op[i].b); + LOADREG(glob + op[i].a, REG_EAX); + LOADREG(glob + op[i].b, REG_ECX); //mov %eax,(%ecx) EmitByte(0x89);EmitByte(0x01); break; case OP_STOREP_V: - //mov glob[B],ecx - EmitByte(0x8b); EmitByte(0x0d);EmitAdr(glob + op[i].b); - //movl glob[A],eax - EmitByte(0xa1);EmitAdr(glob + op[i].a+0); + LOADREG(glob + op[i].b, REG_ECX); + + LOADREG(glob + op[i].a+0, REG_EAX); //mov %eax,0(%ecx) EmitByte(0x89);EmitByte(0x01); - //movl glob[A],eax - EmitByte(0xa1);EmitAdr(glob + op[i].a+0); + + LOADREG(glob + op[i].a+1, REG_EAX); //mov %eax,4(%ecx) EmitByte(0x89);EmitByte(0x41);EmitByte(0x04); - //movl glob[A],eax - EmitByte(0xa1);EmitAdr(glob + op[i].a+0); + + LOADREG(glob + op[i].a+2, REG_EAX); //mov %eax,8(%ecx) EmitByte(0x89);EmitByte(0x41);EmitByte(0x08); break; + case OP_NE_I: + case OP_NE_E: + case OP_NE_FNC: + case OP_EQ_I: case OP_EQ_E: case OP_EQ_FNC: //integer equality - //movl glob[A],%eax - EmitByte(0xa1);EmitAdr(glob + op[i].a); - //cmp glob[B],%eax - EmitByte(0x3b); EmitByte(0x0f); EmitAdr(glob + op[i].b); - //je 12 - EmitByte(0x74);EmitByte(0x0c); - //mov 0.0f,glob[C] - EmitByte(0xc7);EmitByte(0x05); EmitAdr(glob + op[i].a);EmitFloat(0.0f); - //jmp 10 - EmitByte(0xeb);EmitByte(0x0a); - //mov 1.0f,glob[C] - EmitByte(0xc7);EmitByte(0x05); EmitAdr(glob + op[i].a);EmitFloat(1.0f); - break; + LOADREG(glob + op[i].a, REG_EAX); - case OP_NE_E: - case OP_NE_FNC: - //integer equality - //movl glob[A],%eax - EmitByte(0xa1);EmitAdr(glob + op[i].a); //cmp glob[B],%eax - EmitByte(0x3b); EmitByte(0x0f); EmitAdr(glob + op[i].b); - //je 12 - EmitByte(0x74);EmitByte(0x0c); - //mov 0.0f,glob[C] - EmitByte(0xc7);EmitByte(0x05); EmitAdr(glob + op[i].a);EmitFloat(1.0f); - //jmp 10 - EmitByte(0xeb);EmitByte(0x0a); - //mov 1.0f,glob[C] - EmitByte(0xc7);EmitByte(0x05); EmitAdr(glob + op[i].a);EmitFloat(0.0f); + EmitByte(0x3b); EmitByte(0x04); EmitByte(0x25); EmitAdr(glob + op[i].b); + j1 = LocalJmp(op[i].op); + { + STOREF(0.0f, glob + op[i].c); + j2 = LocalJmp(OP_GOTO); + } + { + l1 = LocalLoc(); + STOREF(1.0f, glob + op[i].c); + } + l2 = LocalLoc(); + LocalJmpLoc(j1,l1); + LocalJmpLoc(j2,l2); break; + case OP_NOT_I: case OP_NOT_ENT: case OP_NOT_FNC: - //cmp glob[B],%eax - EmitByte(0x8c); EmitByte(0x3d); EmitAdr(glob + op[i].a);EmitByte(0x00); - //je 12 - EmitByte(0x74);EmitByte(0x0c); - //mov 0.0f,glob[C] - EmitByte(0xc7);EmitByte(0x05); EmitAdr(glob + op[i].a);EmitFloat(0.0f); - //jmp 10 - EmitByte(0xeb);EmitByte(0x0a); - //mov 1.0f,glob[C] - EmitByte(0xc7);EmitByte(0x05); EmitAdr(glob + op[i].c);EmitFloat(1.0f); + //cmp glob[B],$0 + EmitByte(0x83); EmitByte(0x3d); EmitAdr(glob + op[i].a); EmitByte(0x00); + j1 = LocalJmp(OP_NE_I); + { + STOREF(1.0f, glob + op[i].c); + j2 = LocalJmp(OP_GOTO); + } + { + l1 = LocalLoc(); + STOREF(0.0f, glob + op[i].c); + } + l2 = LocalLoc(); + LocalJmpLoc(j1,l1); + LocalJmpLoc(j2,l2); break; - case OP_BITOR: //floats... + case OP_BITOR_F: //floats... //flds glob[A] EmitByte(0xd9); EmitByte(0x05);EmitAdr(glob + op[i].a); //flds glob[B] EmitByte(0xd9); EmitByte(0x05);EmitAdr(glob + op[i].b); //fistp tb - EmitByte(0xdf); EmitByte(0x1d);EmitAdr(&tb); + EmitByte(0xdb); EmitByte(0x1d);EmitAdr(&tb); //fistp ta - EmitByte(0xdf); EmitByte(0x1d);EmitAdr(&ta); - //mov ta,%eax - EmitByte(0xa1); EmitAdr(&ta); - //and tb,%eax + EmitByte(0xdb); EmitByte(0x1d);EmitAdr(&ta); + LOADREG(&ta, REG_EAX) + //or %eax,tb EmitByte(0x09); EmitByte(0x05);EmitAdr(&tb); //fild tb - EmitByte(0xdf); EmitByte(0x05);EmitAdr(&tb); + EmitByte(0xdb); EmitByte(0x05);EmitAdr(&tb); //fstps glob[C] EmitByte(0xd9); EmitByte(0x1d);EmitAdr(glob + op[i].c); break; - case OP_BITAND: + case OP_BITAND_F: //flds glob[A] EmitByte(0xd9); EmitByte(0x05);EmitAdr(glob + op[i].a); //flds glob[B] EmitByte(0xd9); EmitByte(0x05);EmitAdr(glob + op[i].b); //fistp tb - EmitByte(0xdf); EmitByte(0x1d);EmitAdr(&tb); + EmitByte(0xdb); EmitByte(0x1d);EmitAdr(&tb); //fistp ta - EmitByte(0xdf); EmitByte(0x1d);EmitAdr(&ta); - //mov ta,%eax - EmitByte(0xa1); EmitAdr(&ta); + EmitByte(0xdb); EmitByte(0x1d);EmitAdr(&ta); + /*two args are now at ta and tb*/ + LOADREG(&ta, REG_EAX) //and tb,%eax EmitByte(0x21); EmitByte(0x05);EmitAdr(&tb); + /*we just wrote the int value to tb, convert that to a float and store it at c*/ //fild tb - EmitByte(0xdf); EmitByte(0x05);EmitAdr(&tb); + EmitByte(0xdb); EmitByte(0x05);EmitAdr(&tb); //fstps glob[C] EmitByte(0xd9); EmitByte(0x1d);EmitAdr(glob + op[i].c); break; - case OP_AND: + case OP_AND_F: //test floats properly, so we don't get confused with -0.0 //flds glob[A] @@ -612,7 +714,7 @@ EmitByte(0xcc); EmitByte(0xdf); EmitByte(0xe0); //test $0x40,%ah EmitByte(0xf6); EmitByte(0xc4);EmitByte(0x40); - //je onefalse + //jz onefalse EmitByte(0x75); EmitByte(0x1f); //flds glob[B] @@ -623,7 +725,7 @@ EmitByte(0xcc); EmitByte(0xdf); EmitByte(0xe0); //test $0x40,%ah EmitByte(0xf6); EmitByte(0xc4);EmitByte(0x40); - //jne onefalse + //jnz onefalse EmitByte(0x75); EmitByte(0x0c); //mov float0,glob[C] @@ -636,7 +738,7 @@ EmitByte(0xcc); EmitByte(0xc7); EmitByte(0x05); EmitAdr(glob + op[i].c); EmitFloat(0.0f); //done: break; - case OP_OR: + case OP_OR_F: //test floats properly, so we don't get confused with -0.0 //flds glob[A] @@ -674,18 +776,16 @@ EmitByte(0xcc); case OP_EQ_S: case OP_NE_S: + { //put a in ecx + LOADREG(glob + op[i].a, REG_ECX); //put b in edi - //mov a,%ecx - EmitByte(0x8b); EmitByte(0x0d); EmitAdr(glob + op[i].a); - //mov b,%edi - EmitByte(0x8b); EmitByte(0x3d); EmitAdr(glob + op[i].b); - + LOADREG(glob + op[i].b, REG_EDI); +/* //early out if they're equal //cmp %ecx,%edi - EmitByte(0x39); EmitByte(0xd1); - //je _true - EmitByte(0x74); EmitByte(0x68); + EmitByte(0x39); EmitByte(0xc0 | (REG_EDI<<3) | REG_ECX); + j1c = LocalJmp(OP_EQ_S); //if a is 0, check if b is "" //jecxz ais0 @@ -707,31 +807,30 @@ EmitByte(0xcc); EmitByte(0x83); EmitByte(0xc4); EmitByte(0x08); //cmpb $0,(%eax) EmitByte(0x80); EmitByte(0x38); EmitByte(0x00); + j1b = LocalJmp(OP_EQ_S); + j0b = LocalJmp(OP_GOTO); + } + + //ais0: + { + //push edi + EmitByte(0x57); + //push progfuncs + EmitByte(0x68); EmitAdr(progfuncs); + //call PR_StringToNative + EmitByte(0xe8); EmitFOffset(PR_StringToNative,4); + //add $8,%esp + EmitByte(0x83); EmitByte(0xc4); EmitByte(0x08); + //cmpb $0,(%eax) + EmitByte(0x80); EmitByte(0x38); EmitByte(0x00); //je _true - EmitByte(0x74); EmitByte(0x4b); + EmitByte(0x74); EmitByte(0x36); //jmp _false - EmitByte(0xeb); EmitByte(0x3d); - - //ais0: - { - //push edi - EmitByte(0x57); - //push progfuncs - EmitByte(0x68); EmitAdr(progfuncs); - //call PR_StringToNative - EmitByte(0xe8); EmitFOffset(PR_StringToNative,4); - //add $8,%esp - EmitByte(0x83); EmitByte(0xc4); EmitByte(0x08); - //cmpb $0,(%eax) - EmitByte(0x80); EmitByte(0x38); EmitByte(0x00); - //je _true - EmitByte(0x74); EmitByte(0x36); - //jmp _false - EmitByte(0xeb); EmitByte(0x28); - } + EmitByte(0xeb); EmitByte(0x28); } //bnot0: - +*/ +LOADREG(glob + op[i].a, REG_ECX); //push ecx EmitByte(0x51); //push progfuncs @@ -741,6 +840,7 @@ EmitByte(0xcc); //push %eax EmitByte(0x50); +LOADREG(glob + op[i].b, REG_EDI); //push %edi EmitByte(0x57); //push progfuncs @@ -757,28 +857,35 @@ EmitByte(0xcc); EmitByte(0xe8); EmitFOffset(strcmp,4); //add $16,%esp EmitByte(0x83); EmitByte(0xc4); EmitByte(0x10); + //cmp $0,%eax EmitByte(0x83); EmitByte(0xf8); EmitByte(0x00); - //je _true - EmitByte(0x74); EmitByte(0x0c); -//_false: - //mov 0.0f,c - EmitByte(0xc7); EmitByte(0x05); EmitAdr(glob + op[i].c); EmitFloat((op[i].op == OP_NE_S)?1.0f:0.0f); - //jmp done - EmitByte(0xeb); EmitByte(0x0a); -//_true: - //mov 1.0f,c - EmitByte(0xc7); EmitByte(0x05); EmitAdr(glob + op[i].c); EmitFloat((op[i].op == OP_NE_S)?0.0f:1.0f); -//_done: + j1 = LocalJmp(OP_EQ_S); + { + l0 = LocalLoc(); + STOREF((op[i].op == OP_NE_S)?1.0f:0.0f, glob + op[i].c); + j2 = LocalJmp(OP_GOTO); + } + { + l1 = LocalLoc(); + STOREF((op[i].op == OP_NE_S)?0.0f:1.0f, glob + op[i].c); + } + l2 = LocalLoc(); + +// LocalJmpLoc(j0b, l0); + LocalJmpLoc(j1, l1); +// LocalJmpLoc(j1b, l1); + LocalJmpLoc(j2, l2); + } break; case OP_NOT_S: - //mov A,%eax - EmitByte(0xa1);EmitAdr(glob + op[i].a); + LOADREG(glob + op[i].a, REG_EAX) + //cmp $0,%eax EmitByte(0x83); EmitByte(0xf8); EmitByte(0x00); - //je _true - EmitByte(0x74); EmitByte(0x1f); + j2 = LocalJmp(OP_EQ_S); + //push %eax EmitByte(0x50); //push progfuncs @@ -787,19 +894,22 @@ EmitByte(0xcc); EmitByte(0xe8); EmitFOffset(PR_StringToNative,4); //add $8,%esp EmitByte(0x83); EmitByte(0xc4); EmitByte(0x08); + //cmpb $0,(%eax) EmitByte(0x80); EmitByte(0x38); EmitByte(0x00); - //je _true - EmitByte(0x74); EmitByte(0x0c); -//_false: - //mov 0.0f,c - EmitByte(0xc7); EmitByte(0x05); EmitAdr(glob + op[i].c); EmitFloat(0.0f); - //jmp done - EmitByte(0xeb); EmitByte(0x0a); -//_true: - //mov 1.0f,c - EmitByte(0xc7); EmitByte(0x05); EmitAdr(glob + op[i].c); EmitFloat(1.0f); -//_done: + j1 = LocalJmp(OP_EQ_S); + { + STOREF(0.0f, glob + op[i].c); + j0 = LocalJmp(OP_GOTO); + } + { + l1 = LocalLoc(); + STOREF(1.0f, glob + op[i].c); + } + l2 = LocalLoc(); + LocalJmpLoc(j2, l1); + LocalJmpLoc(j1, l1); + LocalJmpLoc(j0, l2); break; case OP_ADD_V: @@ -875,42 +985,31 @@ EmitByte(0xcc); case OP_EQ_F: case OP_NE_F: - case OP_LE: - case OP_GE: - case OP_LT: - case OP_GT: + case OP_LE_F: + case OP_GE_F: + case OP_LT_F: + case OP_GT_F: //flds glob[A] - EmitByte(0xd9);EmitByte(0x05);EmitAdr(glob + op[i].a); - //flds glob[B] EmitByte(0xd9);EmitByte(0x05);EmitAdr(glob + op[i].b); + //flds glob[B] + EmitByte(0xd9);EmitByte(0x05);EmitAdr(glob + op[i].a); //fcomip %st(1),%st EmitByte(0xdf);EmitByte(0xe9); //fstp %st(0) (aka: pop) EmitByte(0xdd);EmitByte(0xd8); - //jcc _true - if (op[i].op == OP_LE) - EmitByte(0x7e); //jle - else if (op[i].op == OP_GE) - EmitByte(0x7d); //jge - else if (op[i].op == OP_LT) - EmitByte(0x7c); //jl - else if (op[i].op == OP_GT) - EmitByte(0x7f); //jg - else if (op[i].op == OP_NE_F) - EmitByte(0x75); //jne - else - EmitByte(0x74); //je - EmitByte(0x0c); -//_false: - //mov 0.0f,c - EmitByte(0xc7); EmitByte(0x05); EmitAdr(glob + op[i].c); EmitFloat(0.0f); - //jmp done - EmitByte(0xeb); EmitByte(0x0a); -//_true: - //mov 1.0f,c - EmitByte(0xc7); EmitByte(0x05); EmitAdr(glob + op[i].c); EmitFloat(1.0f); -//_done: + j1 = LocalJmp(op[i].op); + { + STOREF(0.0f, glob + op[i].c); + j2 = LocalJmp(OP_GOTO); + } + { + l1 = LocalLoc(); + STOREF(1.0f, glob + op[i].c); + } + l2 = LocalLoc(); + LocalJmpLoc(j1,l1); + LocalJmpLoc(j2,l2); break; case OP_MUL_FV: @@ -934,21 +1033,21 @@ EmitByte(0xcc); EmitByte(0xd9);EmitByte(0x05);EmitAdr(glob + f); //flds glob[V0] - EmitByte(0xd8);EmitByte(0x0d);EmitAdr(glob + v+0); + EmitByte(0xd9);EmitByte(0x05);EmitAdr(glob + v+0); //fmul st(1) EmitByte(0xd8);EmitByte(0xc9); //fstps glob[C] EmitByte(0xd9);EmitByte(0x1d);EmitAdr(glob + op[i].c+0); //flds glob[V0] - EmitByte(0xd8);EmitByte(0x0d);EmitAdr(glob + v+1); + EmitByte(0xd9);EmitByte(0x05);EmitAdr(glob + v+1); //fmul st(1) EmitByte(0xd8);EmitByte(0xc9); //fstps glob[C] EmitByte(0xd9);EmitByte(0x1d);EmitAdr(glob + op[i].c+1); //flds glob[V0] - EmitByte(0xd8);EmitByte(0x0d);EmitAdr(glob + v+2); + EmitByte(0xd9);EmitByte(0x05);EmitAdr(glob + v+2); //fmul st(1) EmitByte(0xd8);EmitByte(0xc9); //fstps glob[C] @@ -972,8 +1071,8 @@ EmitByte(0xcc); //add $12,%esp EmitByte(0x83); EmitByte(0xc4); EmitByte(0x0c); break; -#if 0 - case OP_NOT_V: +#if 1 +/* case OP_NOT_V: //flds 0 //flds glob[A+0] //fcomip %st(1),%st @@ -990,8 +1089,18 @@ EmitByte(0xcc); //mov 0,C //done: break; - +*/ + + case OP_NOT_V: + EmitByte(0xcd);EmitByte(op[i].op); + printf("QCJIT: instruction %i is not implemented\n", op[i].op); + break; +#endif + case OP_NE_V: case OP_EQ_V: + { + void *f0, *f1, *f2, *floc; +//compare v[0] //flds glob[A] EmitByte(0xd9);EmitByte(0x05);EmitAdr(glob + op[i].a+0); //flds glob[B] @@ -1001,54 +1110,151 @@ EmitByte(0xcc); //fstp %st(0) (aka: pop) EmitByte(0xdd);EmitByte(0xd8); - //jncc _true - if (op[i].op == OP_NE_V) - EmitByte(0x74); //je - else - EmitByte(0x75); //jne - EmitByte(0x0c); -//_false0: - //mov 0.0f,c - EmitByte(0xc7); EmitByte(0x05); EmitAdr(glob + op[i].c); EmitFloat(1.0f); - //jmp done - EmitByte(0xeb); EmitByte(0x0a); + /*if the condition is true, don't fail*/ + j1 = LocalJmp(op[i].op); + { + STOREF(0.0f, glob + op[i].c); + f0 = LocalJmp(OP_GOTO); + } + l1 = LocalLoc(); + LocalJmpLoc(j1,l1); +//compare v[1] + //flds glob[A] + EmitByte(0xd9);EmitByte(0x05);EmitAdr(glob + op[i].a+1); + //flds glob[B] + EmitByte(0xd9);EmitByte(0x05);EmitAdr(glob + op[i].b+1); + //fcomip %st(1),%st + EmitByte(0xdf);EmitByte(0xe9); + //fstp %st(0) (aka: pop) + EmitByte(0xdd);EmitByte(0xd8); -//_true: - //mov 1.0f,c - EmitByte(0xc7); EmitByte(0x05); EmitAdr(glob + op[i].c); EmitFloat(0.0f); -//_done: + /*if the condition is true, don't fail*/ + j1 = LocalJmp(op[i].op); + { + STOREF(0.0f, glob + op[i].c); + f1 = LocalJmp(OP_GOTO); + } + l1 = LocalLoc(); + LocalJmpLoc(j1,l1); + +//compare v[2] + //flds glob[A] + EmitByte(0xd9);EmitByte(0x05);EmitAdr(glob + op[i].a+2); + //flds glob[B] + EmitByte(0xd9);EmitByte(0x05);EmitAdr(glob + op[i].b+2); + //fcomip %st(1),%st + EmitByte(0xdf);EmitByte(0xe9); + //fstp %st(0) (aka: pop) + EmitByte(0xdd);EmitByte(0xd8); + + /*if the condition is true, don't fail*/ + j1 = LocalJmp(op[i].op); + { + STOREF(0.0f, glob + op[i].c); + f2 = LocalJmp(OP_GOTO); + } + l1 = LocalLoc(); + LocalJmpLoc(j1,l1); + +//success! + STOREF(1.0f, glob + op[i].c); + + floc = LocalLoc(); + LocalJmpLoc(f0,floc); + LocalJmpLoc(f1,floc); + LocalJmpLoc(f2,floc); break; + } + /*fteqcc generates these from reading 'fast arrays', and are part of hexenc extras*/ + case OP_FETCH_GBL_F: + case OP_FETCH_GBL_S: + case OP_FETCH_GBL_E: + case OP_FETCH_GBL_FNC: + case OP_FETCH_GBL_V: + { + unsigned int max = ((unsigned int*)glob)[op[i].a-1]; + unsigned int base = op[i].a; + //flds glob[B] + EmitByte(0xd9); EmitByte(0x05);EmitAdr(glob + op[i].b); + //fistp ta + EmitByte(0xdb); EmitByte(0x1d);EmitAdr(&ta); + LOADREG(&ta, REG_EAX) + //FIXME: if eax >= $max, abort - case OP_EQ_V: - EmitByte(0xcd);EmitByte(op[i].op); - printf("QCJIT: instruction %i is not implemented\n", op[i].op); + if (op[i].op == OP_FETCH_GBL_V) + { + /*scale the index by 3*/ + SETREGI(3, REG_EDX) + //mul %edx + EmitByte(0xf7); EmitByte(0xe2); + } + + //lookup global + //mov &glob[base](,%eax,4),%edx + EmitByte(0x8b);EmitByte(0x14);EmitByte(0x85);Emit4Byte((unsigned int)(glob + base+0)); + STOREREG(REG_EDX, glob + op[i].c+0) + if (op[i].op == OP_FETCH_GBL_V) + { + //mov &glob[base+1](,%eax,4),%edx + EmitByte(0x8b);EmitByte(0x14);EmitByte(0x85);Emit4Byte((unsigned int)(glob + base+1)); + STOREREG(REG_EDX, glob + op[i].c+1) + //mov &glob[base+2](,%eax,4),%edx + EmitByte(0x8b);EmitByte(0x14);EmitByte(0x85);Emit4Byte((unsigned int)(glob + base+2)); + STOREREG(REG_EDX, glob + op[i].c+2) + } break; + } - case OP_NE_V: - EmitByte(0xcd);EmitByte(op[i].op); - printf("QCJIT: instruction %i is not implemented\n", op[i].op); + /*fteqcc generates these from writing 'fast arrays'*/ + case OP_GLOBALADDRESS: + LOADREG(glob + op[i].b, REG_EAX); + //lea &glob[A](, %eax, 4),%eax + EmitByte(0x8d);EmitByte(0x04);EmitByte(0x85);EmitAdr(glob + op[i].b+2); + STOREREG(REG_EAX, glob + op[i].c); + break; +// case OP_BOUNDCHECK: + //FIXME: assert b <= a < c + break; + case OP_CONV_FTOI: + //flds glob[A] + EmitByte(0xd9); EmitByte(0x05);EmitAdr(glob + op[i].a); + //fistp glob[C] + EmitByte(0xdb); EmitByte(0x1d);EmitAdr(glob + op[i].c); + break; + case OP_MUL_I: + LOADREG(glob + op[i].a, REG_EAX); + //mull glob[C] (arg*eax => edx:eax) + EmitByte(0xfc); EmitByte(0x25);EmitAdr(glob + op[i].b); + STOREREG(REG_EAX, glob + op[i].c); break; - case OP_NOT_V: - EmitByte(0xcd);EmitByte(op[i].op); - printf("QCJIT: instruction %i is not implemented\n", op[i].op); + /*other extended opcodes*/ + case OP_BITOR_I: + LOADREG(glob + op[i].a, REG_EAX) + //or %eax,tb + EmitByte(0x0b); EmitByte(0x05);EmitAdr(glob + op[i].b); + STOREREG(REG_EAX, glob + op[i].c); break; -#endif + + default: - printf("QCJIT: Extended instruction set %i is not supported, not using jit.\n", op[i].op); + { + enum qcop_e e = op[i].op; + printf("QCJIT: Extended instruction set %i is not supported, not using jit.\n", e); + } - free(statementjumps); //[MAX_STATEMENTS] - free(statementoffsets); //[MAX_STATEMENTS] - free(code); - statementoffsets = NULL; - return false; + free(jit->statementjumps); //[MAX_STATEMENTS] + free(jit->statementoffsets); //[MAX_STATEMENTS] + free(jit->code); + free(jit); + return NULL; } } - FixupJumps(); + FixupJumps(jit); #ifdef _WIN32 { @@ -1056,22 +1262,32 @@ EmitByte(0xcc); //this memory is on the heap. //this means that we must maintain read/write protection, or libc will crash us - VirtualProtect(code, codesize, PAGE_EXECUTE_READWRITE, &old); + VirtualProtect(jit->code, jit->codesize, PAGE_EXECUTE_READWRITE, &old); } #endif -// externs->WriteFile("jit.x86", code, codesize); +// externs->WriteFile("jit.x86", jit->code, jit->codesize); - return true; + return jit; +} + +float foo(float arg) +{ + float f; + if (!arg) + f = 1; + else + f = 0; + return f; } -void PR_EnterJIT(progfuncs_t *progfuncs, int statement) +void PR_EnterJIT(progfuncs_t *progfuncs, struct jitstate *jit, int statement) { #ifdef __GNUC__ //call, it clobbers pretty much everything. - asm("call *%0" :: "r"(statementoffsets[statement+1]),"b"(prinst->edicttable):"cc","memory","eax","ecx","edx"); + asm("call *%0" :: "r"(jit->statementoffsets[statement+1]),"b"(prinst->edicttable):"cc","memory","eax","ecx","edx"); #elif defined(_MSC_VER) - void *entry = statementoffsets[statement+1]; + void *entry = jit->statementoffsets[statement+1]; void *edicttable = prinst->edicttable; __asm { pushad diff --git a/misc/source/fteqcc-src/progsint.h b/misc/source/fteqcc-src/progsint.h index 39c316e5..e0d5cd46 100644 --- a/misc/source/fteqcc-src/progsint.h +++ b/misc/source/fteqcc-src/progsint.h @@ -1,5 +1,6 @@ #ifdef _WIN32 - + #define _CRT_SECURE_NO_WARNINGS + #define _CRT_NONSTDC_NO_WARNINGS #ifndef AVAIL_ZLIB #ifdef _MSC_VER //#define AVAIL_ZLIB @@ -28,10 +29,6 @@ typedef unsigned char qbyte; #include -#if defined(_M_IX86) || defined(__i386__) -//#define QCJIT -#endif - #define DLL_PROG #ifndef PROGSUSED #define PROGSUSED @@ -44,6 +41,11 @@ extern int hunksize; #include "progtype.h" #include "progslib.h" +#ifdef _MSC_VER +#pragma warning(disable : 4244) +#pragma warning(disable : 4267) +#endif + //extern progfuncs_t *progfuncs; #define prinst progfuncs->prinst @@ -100,7 +102,7 @@ void QC_InitShares(progfuncs_t *progfuncs); void QC_StartShares(progfuncs_t *progfuncs); void QC_AddSharedVar(progfuncs_t *progfuncs, int num, int type); void QC_AddSharedFieldVar(progfuncs_t *progfuncs, int num, char *stringtable); -int QC_RegisterFieldVar(progfuncs_t *progfuncs, unsigned int type, char *name, int requestedpos, int originalofs); +int QC_RegisterFieldVar(progfuncs_t *progfuncs, unsigned int type, char *name, signed long requestedpos, signed long originalofs); pbool Decompile(progfuncs_t *progfuncs, char *fname); int PR_ToggleBreakpoint(progfuncs_t *progfuncs, char *filename, int linenum, int flag); void StripExtension (char *path); @@ -155,11 +157,18 @@ char *SaveEnts(progfuncs_t *progfuncs, char *mem, int *size, int mode); int LoadEnts(progfuncs_t *progfuncs, char *file, float killonspawnflags); char *SaveEnt (progfuncs_t *progfuncs, char *buf, int *size, struct edict_s *ed); struct edict_s *RestoreEnt (progfuncs_t *progfuncs, char *buf, int *size, struct edict_s *ed); -char *PF_VarString (int first); 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 +200,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 { @@ -335,7 +344,7 @@ void PR_SetBuiltins(int type); typedef struct prinst_s { #ifdef QCJIT - pbool usejit; + struct jitstate *jit; #endif char **tempstrings; int maxtempstrings; @@ -438,7 +447,7 @@ var(unsigned int, addressablesize); } prinst_t; extern vec3_t vec3_origin; -eval_t *PR_FindGlobal(progfuncs_t *prfuncs, char *globname, progsnum_t pnum); +eval_t *PR_FindGlobal(progfuncs_t *prfuncs, char *globname, progsnum_t pnum, etype_t *type); ddef16_t *ED_FindTypeGlobalFromProgs16 (progfuncs_t *progfuncs, char *name, progsnum_t prnum, int type); ddef32_t *ED_FindTypeGlobalFromProgs32 (progfuncs_t *progfuncs, char *name, progsnum_t prnum, int type); ddef16_t *ED_FindGlobalFromProgs16 (progfuncs_t *progfuncs, char *name, progsnum_t prnum); @@ -460,7 +469,7 @@ ddef32_t *ED_FindGlobal32 (progfuncs_t *progfuncs, char *name); ddef32_t *ED_GlobalAtOfs32 (progfuncs_t *progfuncs, unsigned int ofs); string_t PR_StringToProgs (progfuncs_t *inst, char *str); -char *PR_StringToNative (progfuncs_t *inst, string_t str); +char *ASMCALL PR_StringToNative (progfuncs_t *inst, string_t str); void PR_FreeTemps (progfuncs_t *progfuncs, int depth); @@ -469,8 +478,9 @@ char *PR_GlobalStringNoContents (progfuncs_t *progfuncs, int ofs); pbool CompileFile(progfuncs_t *progfuncs, char *filename); -pbool PR_GenerateJit(progfuncs_t *progfuncs); -void PR_EnterJIT(progfuncs_t *progfuncs, int statement); +struct jitstate; +struct jitstate *PR_GenerateJit(progfuncs_t *progfuncs); +void PR_EnterJIT(progfuncs_t *progfuncs, struct jitstate *jitstate, int statement); char *QCC_COM_Parse (char *data); extern char qcc_token[1024]; diff --git a/misc/source/fteqcc-src/progslib.h b/misc/source/fteqcc-src/progslib.h index f3f4488a..1e9b6125 100644 --- a/misc/source/fteqcc-src/progslib.h +++ b/misc/source/fteqcc-src/progslib.h @@ -1,26 +1,6 @@ #ifndef PROGSLIB_H #define PROGSLIB_H -/*#define true 1 -#define false 0 - -#define PITCH 0 -#define YAW 1 -#define ROLL 2 - -typedef char bool; -//typedef float vec3_t[3]; -typedef int progsnum_t; -typedef int func_t; -#ifndef COMPILER -typedef char *string_t; -#endif -//typedef struct globalvars_s globalvars_t; -//typedef struct edict_s edict_t; -#define globalvars_t void -#define edict_t void -*/ - #ifdef _MSC_VER #define VARGS __cdecl #endif @@ -34,13 +14,24 @@ typedef char *string_t; #define VARGS #endif +#if defined(_M_IX86) || defined(__i386__) +//#define QCJIT +#endif + +#ifdef QCJIT +#define ASMCALL VARGS +#else +#define ASMCALL +#endif +#define QCBUILTIN ASMCALL + struct edict_s; struct entvars_s; struct globalvars_s; struct qcthread_s; typedef struct progfuncs_s progfuncs_t; -typedef void (*builtin_t) (progfuncs_t *prinst, struct globalvars_s *gvars); +typedef void (ASMCALL *builtin_t) (progfuncs_t *prinst, struct globalvars_s *gvars); //used by progs engine. All nulls is reset. typedef struct { @@ -95,7 +86,7 @@ struct progfuncs_s { char *(*saveent) (progfuncs_t *prinst, char *buf, int *size, struct edict_s *ed); //will save just one entities vars struct edict_s *(*restoreent) (progfuncs_t *prinst, char *buf, int *size, struct edict_s *ed); //will restore the entity that had it's values saved (can use NULL for ed) - union eval_s *(*FindGlobal) (progfuncs_t *prinst, char *name, progsnum_t num); //find a pointer to the globals value + union eval_s *(*FindGlobal) (progfuncs_t *prinst, char *name, progsnum_t num, etype_t *type); //find a pointer to the globals value char *(*AddString) (progfuncs_t *prinst, char *val, int minlength); //dump a string into the progs memory (for setting globals and whatnot) void *(*Tempmem) (progfuncs_t *prinst, int ammount, char *whatfor); //grab some mem for as long as the progs stays loaded @@ -132,7 +123,7 @@ struct progfuncs_s { int lastcalledbuiltinnumber; //useful with non-implemented opcodes. - int (*RegisterFieldVar) (progfuncs_t *prinst, unsigned int type, char *name, int requestedpos, int originalofs); + int (*RegisterFieldVar) (progfuncs_t *prinst, unsigned int type, char *name, signed long requestedpos, signed long originalofs); char *tempstringbase; //for engine's use. Store your base tempstring pointer here. int tempstringnum; //for engine's use. @@ -140,20 +131,21 @@ struct progfuncs_s { string_t (*TempString) (progfuncs_t *prinst, char *str); string_t (*StringToProgs) (progfuncs_t *prinst, char *str); - char *(*StringToNative) (progfuncs_t *prinst, string_t str); + char *(ASMCALL *StringToNative) (progfuncs_t *prinst, string_t str); int stringtablesize; int (*QueryField) (progfuncs_t *prinst, unsigned int fieldoffset, etype_t *type, char **name, evalc_t *fieldcache); //find info on a field definition at an offset void (*EntClear) (progfuncs_t *progfuncs, struct edict_s *e); + void (*FindPrefixGlobals) (progfuncs_t *progfuncs, char *prefix, void (*found) (progfuncs_t *progfuncs, char *name, union eval_s *val, etype_t type) ); }; typedef struct progexterns_s { int progsversion; //PROGSTRUCT_VERSION - unsigned char *(*ReadFile) (char *fname, void *buffer, int len); - int (*FileSize) (char *fname); //-1 if file does not exist - pbool (*WriteFile) (char *name, void *data, int len); + unsigned char *(*ReadFile) (const char *fname, void *buffer, int len); + int (*FileSize) (const char *fname); //-1 if file does not exist + pbool (*WriteFile) (const char *name, void *data, int len); int (VARGS *printf) (const char *, ...) LIKEPRINTF(1); void (VARGS *Sys_Error) (const char *, ...) LIKEPRINTF(1); void (VARGS *Abort) (char *, ...) LIKEPRINTF(1); @@ -161,15 +153,16 @@ typedef struct progexterns_s { void (*entspawn) (struct edict_s *ent, int loading); //ent has been spawned, but may not have all the extra variables (that may need to be set) set pbool (*entcanfree) (struct edict_s *ent); //return true to stop ent from being freed - void (*stateop) (progfuncs_t *prinst, float var, func_t func); //what to do on qc's state opcode. - void (*cstateop) (progfuncs_t *prinst, float vara, float varb, func_t currentfunc); //a hexen2 opcode. - void (*cwstateop) (progfuncs_t *prinst, float vara, float varb, func_t currentfunc); //a hexen2 opcode. - void (*thinktimeop) (progfuncs_t *prinst, struct edict_s *ent, float varb); //a hexen2 opcode. + void (ASMCALL *stateop) (progfuncs_t *prinst, float var, func_t func); //what to do on qc's state opcode. + void (ASMCALL *cstateop) (progfuncs_t *prinst, float vara, float varb, func_t currentfunc); //a hexen2 opcode. + void (ASMCALL *cwstateop) (progfuncs_t *prinst, float vara, float varb, func_t currentfunc); //a hexen2 opcode. + void (ASMCALL *thinktimeop) (progfuncs_t *prinst, struct edict_s *ent, float varb); //a hexen2 opcode. //used when loading a game builtin_t *(*builtinsfor) (int num, int headercrc); //must return a pointer to the builtins that were used before the state was saved. void (*loadcompleate) (int edictsize); //notification to reset any pointers. + pbool (*badfield)(progfuncs_t *prinst, struct edict_s *ent, const char *keyname, const char *value); //called for any fields that are not registered void *(VARGS *memalloc) (int size); //small string allocation malloced and freed randomly by the executor. (use malloc if you want) void (VARGS *memfree) (void * mem); @@ -257,7 +250,7 @@ typedef union eval_s #define PR_PrintEdict(pf,ed) (*pf->PrintEdict) (pf, ed) #define PR_FindFunction(pf, name, num) (*pf->FindFunction) (pf, name, num) -#define PR_FindGlobal(pf, name, progs) (*pf->FindGlobal) (pf, name, progs) +#define PR_FindGlobal(pf, name, progs, type) (*pf->FindGlobal) (pf, name, progs, type) #define PR_AddString(pf, ed, len) (*pf->AddString) (pf, ed, len) #define PR_Alloc(pf,size) (*pf->Tempmem) (pf, size) diff --git a/misc/source/fteqcc-src/qcc.h b/misc/source/fteqcc-src/qcc.h index e71ad165..5c2cd2ed 100644 --- a/misc/source/fteqcc-src/qcc.h +++ b/misc/source/fteqcc-src/qcc.h @@ -42,7 +42,7 @@ extern float (*PRLittleFloat) (float l); #define MAX_ERRORS 10 -#define MAX_NAME 64 // chars long +#define MAX_NAME 128 // chars long extern unsigned int MAX_REGS; @@ -60,11 +60,10 @@ extern int MAX_FUNCTIONS; extern int MAX_CONSTANTS; #define MAXCONSTANTLENGTH 64 -#define MAXCONSTANTVALUELENGTH 1024 #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; @@ -320,6 +319,7 @@ typedef struct temp_s { pbool used; unsigned int size; } temp_t; +void QCC_PurgeTemps(void); //not written typedef struct QCC_def_s @@ -343,6 +343,7 @@ typedef struct QCC_def_s pbool shared; pbool saved; pbool isstatic; + pbool subscoped_away; temp_t *temp; } QCC_def_t; @@ -406,7 +407,7 @@ extern QCC_pr_info_t pr; typedef struct { char name[MAXCONSTANTLENGTH]; - char value[MAXCONSTANTVALUELENGTH]; + char *value; char params[MAXCONSTANTPARAMS][MAXCONSTANTPARAMLENGTH]; int numparams; pbool used; @@ -479,6 +480,7 @@ extern pbool flag_hashonly; extern pbool flag_fasttrackarrays; extern pbool flag_assume_integer; extern pbool flag_msvcstyle; +extern pbool flag_filetimes; extern pbool opt_overlaptemps; extern pbool opt_shortenifnots; @@ -541,6 +543,7 @@ CompilerConstant_t *QCC_PR_DefineName(char *name); void QCC_RemapOffsets(unsigned int firststatement, unsigned int laststatement, unsigned int min, unsigned int max, unsigned int newmin); #ifndef COMMONINLINES +pbool QCC_PR_CheckImmediate (char *string); pbool QCC_PR_CheckToken (char *string); pbool QCC_PR_CheckName (char *string); void QCC_PR_Expect (char *string); @@ -549,6 +552,7 @@ pbool QCC_PR_CheckKeyword(int keywordenabled, char *string); void VARGS QCC_PR_ParseError (int errortype, char *error, ...); void VARGS QCC_PR_ParseWarning (int warningtype, char *error, ...); void VARGS QCC_PR_Warning (int type, char *file, int line, char *error, ...); +void VARGS QCC_PR_Note (int type, char *file, int line, char *error, ...); void QCC_PR_ParsePrintDef (int warningtype, QCC_def_t *def); void VARGS QCC_PR_ParseErrorPrintDef (int errortype, QCC_def_t *def, char *error, ...); @@ -624,7 +628,6 @@ enum { ERR_TOOMANYPAKFILES, ERR_PRECOMPILERCONSTANTTOOLONG, ERR_MACROTOOMANYPARMS, - ERR_CONSTANTTOOLONG, ERR_TOOMANYFRAMEMACROS, //limitations, some are imposed by compiler, some arn't. @@ -798,6 +801,9 @@ void QCC_PR_EmitArrayGetFunction(QCC_def_t *scope, char *arrayname); void QCC_PR_EmitArraySetFunction(QCC_def_t *scope, char *arrayname); void QCC_PR_EmitClassFromFunction(QCC_def_t *scope, char *tname); +void PostCompile(void); +pbool PreCompile(void); + //============================================================================= extern char pr_immediate_string[8192]; @@ -828,6 +834,7 @@ extern int numtypeinfos; extern int maxtypeinfos; extern int ForcedCRC; +extern pbool defaultnoref; extern pbool defaultstatic; extern int *qcc_tempofs; @@ -901,6 +908,6 @@ char *TypeName(QCC_type_t *type); void QCC_PR_IncludeChunk (char *data, pbool duplicate, char *filename); void QCC_PR_IncludeChunkEx(char *data, pbool duplicate, char *filename, CompilerConstant_t *cnst); pbool QCC_PR_UnInclude(void); -extern void *(*pHash_Get)(hashtable_t *table, char *name); -extern void *(*pHash_GetNext)(hashtable_t *table, char *name, void *old); -extern void *(*pHash_Add)(hashtable_t *table, char *name, void *data, bucket_t *); +extern void *(*pHash_Get)(hashtable_t *table, const char *name); +extern void *(*pHash_GetNext)(hashtable_t *table, const char *name, void *old); +extern void *(*pHash_Add)(hashtable_t *table, const char *name, void *data, bucket_t *); diff --git a/misc/source/fteqcc-src/qcc_cmdlib.c b/misc/source/fteqcc-src/qcc_cmdlib.c index 8d0f874a..f93e3e9c 100644 --- a/misc/source/fteqcc-src/qcc_cmdlib.c +++ b/misc/source/fteqcc-src/qcc_cmdlib.c @@ -10,6 +10,24 @@ extern jmp_buf qcccompileerror; #endif +// I put the following here to resolve "undefined reference to `__imp__vsnprintf'" with MinGW64 ~ Moodles +#ifdef __MINGW64__ +#ifndef QCCONLY + #if (_MSC_VER >= 1400) + //with MSVC 8, use MS extensions + #define snprintf linuxlike_snprintf_vc8 + int VARGS linuxlike_snprintf_vc8(char *buffer, int size, const char *format, ...) LIKEPRINTF(3); + #define vsnprintf(a, b, c, d) vsnprintf_s(a, b, _TRUNCATE, c, d) + #else + //msvc crap + #define snprintf linuxlike_snprintf + int VARGS linuxlike_snprintf(char *buffer, int size, const char *format, ...) LIKEPRINTF(3); + #define vsnprintf linuxlike_vsnprintf + int VARGS linuxlike_vsnprintf(char *buffer, int size, const char *format, va_list argptr); + #endif +#endif +#endif + // set these before calling CheckParm int myargc; char **myargv; @@ -83,13 +101,13 @@ int QCC_Long (int l) float QCC_SwapFloat (float l) { union {qbyte b[4]; float f;} in, out; - + in.f = l; out.b[0] = in.b[3]; out.b[1] = in.b[2]; out.b[2] = in.b[1]; out.b[3] = in.b[0]; - + return out.f; } @@ -138,13 +156,13 @@ double I_FloatTime (void) static int secbase; gettimeofday(&tp, &tzp); - + if (!secbase) { secbase = tp.tv_sec; return tp.tv_usec/1000000.0; } - + return (tp.tv_sec - secbase) + tp.tv_usec/1000000.0; } @@ -155,7 +173,7 @@ double I_FloatTime (void) int QC_strncasecmp (const char *s1, const char *s2, int n) { int c1, c2; - + while (1) { c1 = *s1++; @@ -163,7 +181,7 @@ int QC_strncasecmp (const char *s1, const char *s2, int n) if (!n--) return 0; // strings are equal until end point - + if (c1 != c2) { if (c1 >= 'a' && c1 <= 'z') @@ -178,7 +196,7 @@ int QC_strncasecmp (const char *s1, const char *s2, int n) // s1++; // s2++; } - + return -1; } @@ -210,13 +228,13 @@ char *QCC_COM_Parse (char *data) { int c; int len; - + len = 0; qcc_token[0] = 0; - + if (!data) return NULL; - + // skip whitespace skipwhite: while ( (c = *data) <= ' ') @@ -228,7 +246,7 @@ skipwhite: } data++; } - + // skip // comments if (c=='/' && data[1] == '/') { @@ -245,7 +263,7 @@ skipwhite: data+=2; goto skipwhite; } - + // handle quoted strings specially if (c == '\"') @@ -297,7 +315,7 @@ skipwhite: if (c=='{' || c=='}'|| c==')'|| c=='(' || c=='\'' || c==':' || c=='\"' || c==',') break; } while (c>32); - + qcc_token[len] = 0; return data; } @@ -307,13 +325,13 @@ char *QCC_COM_Parse2 (char *data) { int c; int len; - + len = 0; qcc_token[0] = 0; - + if (!data) return NULL; - + // skip whitespace skipwhite: while ( (c = *data) <= ' ') @@ -325,7 +343,7 @@ skipwhite: } data++; } - + // skip // comments if (c=='/' && data[1] == '/') { @@ -333,7 +351,7 @@ skipwhite: data++; goto skipwhite; } - + // handle quoted strings specially if (c == '\"') @@ -389,7 +407,7 @@ skipwhite: break; } } - + qcc_token[len] = 0; return data; } @@ -403,7 +421,7 @@ skipwhite: len++; c = *data; } while ((c>= 'a' && c <= 'z') || (c>= 'A' && c <= 'Z') || c == '_'); - + qcc_token[len] = 0; return data; } @@ -419,7 +437,7 @@ skipwhite: char *VARGS qcva (char *text, ...) { va_list argptr; - static char msg[2048]; + static char msg[2048]; va_start (argptr,text); QC_vsnprintf (msg,sizeof(msg)-1, text,argptr); @@ -475,7 +493,7 @@ void VARGS QCC_Error (int errortype, const char *error, ...) { extern int numsourcefiles; va_list argptr; - char msg[2048]; + char msg[2048]; va_start (argptr,error); QC_vsnprintf (msg,sizeof(msg)-1, error,argptr); @@ -489,7 +507,7 @@ void VARGS QCC_Error (int errortype, const char *error, ...) numsourcefiles = 0; #ifndef QCC - longjmp(qcccompileerror, 1); + longjmp(qcccompileerror, 1); #else print ("Press any key\n"); getch(); @@ -532,7 +550,7 @@ int SafeOpenWrite (char *filename) int handle; umask (0); - + handle = open(filename,O_WRONLY | O_CREAT | O_TRUNC | O_BINARY , 0666); @@ -776,7 +794,7 @@ int SafeOpenWrite (char *filename, int maxsize) void ResizeBuf(int hand, int newsize) { -// int wasmal = qccfile[hand].buffismalloc; +// int wasmal = qccfile[hand].buffismalloc; char *nb; if (qccfile[hand].buffsize >= newsize) @@ -792,7 +810,7 @@ void ResizeBuf(int hand, int newsize) // qccfile[hand].buffismalloc = false; // nb = memalloc(newsize); // } - + memcpy(nb, qccfile[hand].buff, qccfile[hand].maxofs); // if (wasmal) free(qccfile[hand].buff); @@ -826,7 +844,7 @@ int SafeSeek(int hand, int ofs, int mode) } void SafeClose(int hand) { - externs->WriteFile(qccfile[hand].name, qccfile[hand].buff, qccfile[hand].maxofs); + externs->WriteFile(qccfile[hand].name, qccfile[hand].buff, qccfile[hand].maxofs); // if (qccfile[hand].buffismalloc) free(qccfile[hand].buff); // else @@ -847,21 +865,21 @@ long QCC_LoadFile (char *filename, void **bufferptr) return -1; // Abort("failed to find file %s", filename); } - mem = qccHunkAlloc(sizeof(qcc_cachedsourcefile_t) + len+2); + mem = qccHunkAlloc(sizeof(qcc_cachedsourcefile_t) + len+2); ((qcc_cachedsourcefile_t*)mem)->next = qcc_sourcefile; qcc_sourcefile = (qcc_cachedsourcefile_t*)mem; - qcc_sourcefile->size = len; - mem += sizeof(qcc_cachedsourcefile_t); + qcc_sourcefile->size = len; + mem += sizeof(qcc_cachedsourcefile_t); strcpy(qcc_sourcefile->filename, filename); qcc_sourcefile->file = mem; qcc_sourcefile->type = FT_CODE; - + externs->ReadFile(filename, mem, len+2); mem[len] = '\n'; mem[len+1] = '\0'; *bufferptr=mem; - + return len; } void QCC_AddFile (char *filename) @@ -871,12 +889,12 @@ void QCC_AddFile (char *filename) len = externs->FileSize(filename); if (len < 0) Abort("failed to find file %s", filename); - mem = qccHunkAlloc(sizeof(qcc_cachedsourcefile_t) + len+1); + mem = qccHunkAlloc(sizeof(qcc_cachedsourcefile_t) + len+1); ((qcc_cachedsourcefile_t*)mem)->next = qcc_sourcefile; qcc_sourcefile = (qcc_cachedsourcefile_t*)mem; - qcc_sourcefile->size = len; - mem += sizeof(qcc_cachedsourcefile_t); + qcc_sourcefile->size = len; + mem += sizeof(qcc_cachedsourcefile_t); strcpy(qcc_sourcefile->filename, filename); qcc_sourcefile->file = mem; qcc_sourcefile->type = FT_DATA; diff --git a/misc/source/fteqcc-src/qcc_pr_comp.c b/misc/source/fteqcc-src/qcc_pr_comp.c index e37d4ff2..a2699877 100644 --- a/misc/source/fteqcc-src/qcc_pr_comp.c +++ b/misc/source/fteqcc-src/qcc_pr_comp.c @@ -79,6 +79,7 @@ pbool flag_hashonly; //Allows use of only #constant for precompiler constants, pbool flag_fasttrackarrays; //Faster arrays, dynamically detected, activated only in supporting engines. pbool flag_msvcstyle; //MSVC style warnings, so msvc's ide works properly pbool flag_assume_integer; //5 - is that an integer or a float? qcc says float. but we support int too, so maybe we want that instead? +pbool flag_filetimes; 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. @@ -128,9 +129,9 @@ int optres_logicops; int optres_test1; int optres_test2; -void *(*pHash_Get)(hashtable_t *table, char *name); -void *(*pHash_GetNext)(hashtable_t *table, char *name, void *old); -void *(*pHash_Add)(hashtable_t *table, char *name, void *data, bucket_t *); +void *(*pHash_Get)(hashtable_t *table, const char *name); +void *(*pHash_GetNext)(hashtable_t *table, const char *name, void *old); +void *(*pHash_Add)(hashtable_t *table, const char *name, void *data, bucket_t *); QCC_def_t *QCC_PR_DummyDef(QCC_type_t *type, char *name, QCC_def_t *scope, int arraysize, unsigned int ofs, int referable, pbool saved); QCC_type_t *QCC_PR_NewType (char *name, int basictype); @@ -221,13 +222,13 @@ QCC_opcode_t pr_opcodes[] = {6, "==", "EQ_S", 5, ASSOC_LEFT, &type_string, &type_string, &type_float}, {6, "==", "EQ_E", 5, ASSOC_LEFT, &type_entity, &type_entity, &type_float}, {6, "==", "EQ_FNC", 5, ASSOC_LEFT, &type_function, &type_function, &type_float}, - + {6, "!=", "NE_F", 5, ASSOC_LEFT, &type_float, &type_float, &type_float}, {6, "!=", "NE_V", 5, ASSOC_LEFT, &type_vector, &type_vector, &type_float}, {6, "!=", "NE_S", 5, ASSOC_LEFT, &type_string, &type_string, &type_float}, {6, "!=", "NE_E", 5, ASSOC_LEFT, &type_entity, &type_entity, &type_float}, {6, "!=", "NE_FNC", 5, ASSOC_LEFT, &type_function, &type_function, &type_float}, - + {6, "<=", "LE", 5, ASSOC_LEFT, &type_float, &type_float, &type_float}, {6, ">=", "GE", 5, ASSOC_LEFT, &type_float, &type_float, &type_float}, {6, "<", "LT", 5, ASSOC_LEFT, &type_float, &type_float, &type_float}, @@ -257,31 +258,31 @@ QCC_opcode_t pr_opcodes[] = {6, "=", "STOREP_FNC", 6, ASSOC_RIGHT, &type_pointer, &type_function, &type_function}, {6, "", "RETURN", -1, ASSOC_LEFT, &type_float, &type_void, &type_void}, - + {6, "!", "NOT_F", -1, ASSOC_LEFT, &type_float, &type_void, &type_float}, {6, "!", "NOT_V", -1, ASSOC_LEFT, &type_vector, &type_void, &type_float}, {6, "!", "NOT_S", -1, ASSOC_LEFT, &type_vector, &type_void, &type_float}, {6, "!", "NOT_ENT", -1, ASSOC_LEFT, &type_entity, &type_void, &type_float}, {6, "!", "NOT_FNC", -1, ASSOC_LEFT, &type_function, &type_void, &type_float}, - + {6, "", "IF", -1, ASSOC_RIGHT, &type_float, NULL, &type_void}, {6, "", "IFNOT", -1, ASSOC_RIGHT, &type_float, NULL, &type_void}, - + // calls returns REG_RETURN {6, "", "CALL0", -1, ASSOC_LEFT, &type_function, &type_void, &type_void}, {6, "", "CALL1", -1, ASSOC_LEFT, &type_function, &type_void, &type_void}, - {6, "", "CALL2", -1, ASSOC_LEFT, &type_function, &type_void, &type_void}, - {6, "", "CALL3", -1, ASSOC_LEFT, &type_function, &type_void, &type_void}, + {6, "", "CALL2", -1, ASSOC_LEFT, &type_function, &type_void, &type_void}, + {6, "", "CALL3", -1, ASSOC_LEFT, &type_function, &type_void, &type_void}, {6, "", "CALL4", -1, ASSOC_LEFT, &type_function, &type_void, &type_void}, {6, "", "CALL5", -1, ASSOC_LEFT, &type_function, &type_void, &type_void}, {6, "", "CALL6", -1, ASSOC_LEFT, &type_function, &type_void, &type_void}, {6, "", "CALL7", -1, ASSOC_LEFT, &type_function, &type_void, &type_void}, {6, "", "CALL8", -1, ASSOC_LEFT, &type_function, &type_void, &type_void}, - + {6, "", "STATE", -1, ASSOC_LEFT, &type_float, &type_float, &type_void}, - + {6, "", "GOTO", -1, ASSOC_RIGHT, NULL, &type_void, &type_void}, - + {6, "&&", "AND", 7, ASSOC_LEFT, &type_float, &type_float, &type_float}, {6, "||", "OR", 7, ASSOC_LEFT, &type_float, &type_float, &type_float}, @@ -348,8 +349,8 @@ QCC_opcode_t pr_opcodes[] = //Later are additions by DMW. {7, "", "CALL1H", -1, ASSOC_LEFT, &type_function, &type_vector, &type_void}, - {7, "", "CALL2H", -1, ASSOC_LEFT, &type_function, &type_vector, &type_vector}, - {7, "", "CALL3H", -1, ASSOC_LEFT, &type_function, &type_vector, &type_vector}, + {7, "", "CALL2H", -1, ASSOC_LEFT, &type_function, &type_vector, &type_vector}, + {7, "", "CALL3H", -1, ASSOC_LEFT, &type_function, &type_vector, &type_vector}, {7, "", "CALL4H", -1, ASSOC_LEFT, &type_function, &type_vector, &type_vector}, {7, "", "CALL5H", -1, ASSOC_LEFT, &type_function, &type_vector, &type_vector}, {7, "", "CALL6H", -1, ASSOC_LEFT, &type_function, &type_vector, &type_vector}, @@ -363,7 +364,7 @@ QCC_opcode_t pr_opcodes[] = {7, "+", "ADD_I", 4, ASSOC_LEFT, &type_integer, &type_integer, &type_integer}, {7, "+", "ADD_FI", 4, ASSOC_LEFT, &type_float, &type_integer, &type_float}, {7, "+", "ADD_IF", 4, ASSOC_LEFT, &type_integer, &type_float, &type_float}, - + {7, "-", "SUB_I", 4, ASSOC_LEFT, &type_integer, &type_integer, &type_integer}, {7, "-", "SUB_FI", 4, ASSOC_LEFT, &type_float, &type_integer, &type_float}, {7, "-", "SUB_IF", 4, ASSOC_LEFT, &type_integer, &type_float, &type_float}, @@ -471,7 +472,7 @@ QCC_opcode_t pr_opcodes[] = {7, "!=", "NE_IF", 5, ASSOC_LEFT, &type_integer, &type_float, &type_integer}, {7, "!=", "NE_FI", 5, ASSOC_LEFT, &type_float, &type_float, &type_integer}, - + @@ -663,12 +664,12 @@ QCC_opcode_t *opcodeprioritized[TOP_PRIORITY+1][128] = &pr_opcodes[OP_DIV_I], &pr_opcodes[OP_DIV_VF], - &pr_opcodes[OP_BITAND], + &pr_opcodes[OP_BITAND_F], &pr_opcodes[OP_BITAND_I], &pr_opcodes[OP_BITAND_IF], &pr_opcodes[OP_BITAND_FI], - &pr_opcodes[OP_BITOR], + &pr_opcodes[OP_BITOR_F], &pr_opcodes[OP_BITOR_I], &pr_opcodes[OP_BITOR_IF], &pr_opcodes[OP_BITOR_FI], @@ -704,7 +705,7 @@ QCC_opcode_t *opcodeprioritized[TOP_PRIORITY+1][128] = &pr_opcodes[OP_EQ_I], &pr_opcodes[OP_EQ_IF], &pr_opcodes[OP_EQ_FI], - + &pr_opcodes[OP_NE_F], &pr_opcodes[OP_NE_V], &pr_opcodes[OP_NE_S], @@ -713,20 +714,20 @@ QCC_opcode_t *opcodeprioritized[TOP_PRIORITY+1][128] = &pr_opcodes[OP_NE_I], &pr_opcodes[OP_NE_IF], &pr_opcodes[OP_NE_FI], - - &pr_opcodes[OP_LE], + + &pr_opcodes[OP_LE_F], &pr_opcodes[OP_LE_I], &pr_opcodes[OP_LE_IF], &pr_opcodes[OP_LE_FI], - &pr_opcodes[OP_GE], + &pr_opcodes[OP_GE_F], &pr_opcodes[OP_GE_I], &pr_opcodes[OP_GE_IF], &pr_opcodes[OP_GE_FI], - &pr_opcodes[OP_LT], + &pr_opcodes[OP_LT_F], &pr_opcodes[OP_LT_I], &pr_opcodes[OP_LT_IF], &pr_opcodes[OP_LT_FI], - &pr_opcodes[OP_GT], + &pr_opcodes[OP_GT_F], &pr_opcodes[OP_GT_I], &pr_opcodes[OP_GT_IF], &pr_opcodes[OP_GT_FI], @@ -807,11 +808,11 @@ QCC_opcode_t *opcodeprioritized[TOP_PRIORITY+1][128] = NULL }, { //7 - &pr_opcodes[OP_AND], + &pr_opcodes[OP_AND_F], &pr_opcodes[OP_AND_I], &pr_opcodes[OP_AND_IF], &pr_opcodes[OP_AND_FI], - &pr_opcodes[OP_OR], + &pr_opcodes[OP_OR_F], &pr_opcodes[OP_OR_I], &pr_opcodes[OP_OR_IF], &pr_opcodes[OP_OR_FI], @@ -828,6 +829,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; @@ -1000,7 +1002,7 @@ pbool QCC_OPCodeValid(QCC_opcode_t *op) case OP_LOADA_FNC: case OP_LOADA_V: return false; //DPFIXME: DP does not bounds check these properly. I won't generate them. - + case OP_CONV_ITOF: case OP_CONV_FTOI: return true; //these look fine. @@ -1022,7 +1024,7 @@ pbool QCC_OPCodeValid(QCC_opcode_t *op) case OP_IFNOT_S: case OP_IF_S: return true; - + case OP_IFNOT_F: //added, but not in dp yet case OP_IF_F: return false; @@ -1100,7 +1102,7 @@ static int QCC_ShouldConvert(QCC_def_t *var, etype_t wanted) if (var->type->type == ev_pointer && var->type->aux_type) { if (var->type->aux_type->type == ev_float && wanted == ev_integer) - return OP_CP_FTOI; + return OP_CP_FTOI; if (var->type->aux_type->type == ev_integer && wanted == ev_float) return OP_CP_ITOF; @@ -1148,7 +1150,7 @@ QCC_def_t *QCC_SupplyConversion(QCC_def_t *var, etype_t wanted) if (o <= 0) //no conversion return var; - + return QCC_PR_Statement(&pr_opcodes[o], var, NULL, NULL); //conversion return value } @@ -1197,7 +1199,7 @@ gofs_t QCC_GetFreeOffsetSpace(unsigned int size) prev = fofs; } } - + ofs = numpr_globals; numpr_globals+=size; @@ -1256,7 +1258,7 @@ static QCC_def_t *QCC_GetTemp(QCC_type_t *type) #endif var_c = (void *)qccHunkAlloc (sizeof(QCC_def_t)); - memset (var_c, 0, sizeof(QCC_def_t)); + memset (var_c, 0, sizeof(QCC_def_t)); var_c->type = type; var_c->name = "temp"; @@ -1286,7 +1288,7 @@ static QCC_def_t *QCC_GetTemp(QCC_type_t *type) t->size = type->size; t->next = functemps; functemps = t; - + t->ofs = QCC_GetFreeOffsetSpace(t->size); numtemps+=t->size; @@ -1371,6 +1373,10 @@ static void QCC_FreeTemps(void) #else #define QCC_FreeTemps() #endif +void QCC_PurgeTemps(void) +{ + functemps = NULL; +} //temps that are still in use over a function call can be considered dodgy. //we need to remap these to locally defined temps, on return from the function so we know we got them all. @@ -1385,6 +1391,7 @@ static void QCC_LockActiveTemps(void) t->scope = pr_scope; t = t->next; } + } static void QCC_LockTemp(QCC_def_t *d) @@ -1494,14 +1501,14 @@ static void QCC_fprintfLocals(FILE *f, gofs_t paramstart, gofs_t paramend) { if (var->ofs >= paramstart && var->ofs < paramend) continue; - fprintf(f, "local %s %s;\n", TypeName(var->type), var->name); + fprintf(f, "local %s %s; /* at %d */\n", TypeName(var->type), var->name, var->ofs); } for (t = functemps, i = 0; t; t = t->next, i++) { if (t->lastfunc == pr_scope) { - fprintf(f, "local %s temp_%i;\n", (t->size == 1)?"float":"vector", i); + fprintf(f, "local %s temp_%i; /* at %d */\n", (t->size == 1)?"float":"vector", i, t->ofs); } } } @@ -1637,7 +1644,7 @@ QCC_def_t *QCC_PR_Statement ( QCC_opcode_t *op, QCC_def_t *var_a, QCC_def_t *var // } // //can't convert the left componant of an assignment operation // if (var_b && var_b->type && var_b->type != op->type_b->type) -// var_b = QCC_SupplyConversion(var_b, op->type_b->type->type); +// var_b = QCC_SupplyConversion(var_b, op->type_b->type->type); } } @@ -1670,10 +1677,10 @@ QCC_def_t *QCC_PR_Statement ( QCC_opcode_t *op, QCC_def_t *var_a, QCC_def_t *var //both are constants switch (op - pr_opcodes) //improve some of the maths. { - case OP_BITOR: + case OP_BITOR_F: optres_constantarithmatic++; return QCC_MakeFloatDef((float)((int)G_FLOAT(var_a->ofs) | (int)G_FLOAT(var_b->ofs))); - case OP_BITAND: + case OP_BITAND_F: optres_constantarithmatic++; return QCC_MakeFloatDef((float)((int)G_FLOAT(var_a->ofs) & (int)G_FLOAT(var_b->ofs))); case OP_MUL_F: @@ -1708,10 +1715,10 @@ QCC_def_t *QCC_PR_Statement ( QCC_opcode_t *op, QCC_def_t *var_a, QCC_def_t *var optres_constantarithmatic++; return QCC_MakeIntDef(G_INT(var_a->ofs) - G_INT(var_b->ofs)); - case OP_AND: + case OP_AND_F: optres_constantarithmatic++; return QCC_MakeIntDef(G_INT(var_a->ofs) && G_INT(var_b->ofs)); - case OP_OR: + case OP_OR_F: optres_constantarithmatic++; return QCC_MakeIntDef(G_INT(var_a->ofs) || G_INT(var_b->ofs)); case OP_MUL_V: //mul_f is actually a dot-product @@ -1746,8 +1753,8 @@ QCC_def_t *QCC_PR_Statement ( QCC_opcode_t *op, QCC_def_t *var_a, QCC_def_t *var //a is const, b is not switch (op - pr_opcodes) { - case OP_BITOR: - case OP_OR: + case OP_BITOR_F: + case OP_OR_F: case OP_ADD_F: if (G_FLOAT(var_a->ofs) == 0) { @@ -1764,8 +1771,8 @@ QCC_def_t *QCC_PR_Statement ( QCC_opcode_t *op, QCC_def_t *var_a, QCC_def_t *var return var_b; } break; - case OP_BITAND: - case OP_AND: + case OP_BITAND_F: + case OP_AND_F: if (G_FLOAT(var_a->ofs) != 0) { optres_constantarithmatic++; @@ -1809,8 +1816,8 @@ QCC_def_t *QCC_PR_Statement ( QCC_opcode_t *op, QCC_def_t *var_a, QCC_def_t *var //b is const, a is not switch (op - pr_opcodes) { - case OP_BITOR: - case OP_OR: + case OP_BITOR_F: + case OP_OR_F: case OP_SUB_F: case OP_ADD_F: if (G_FLOAT(var_b->ofs) == 0) @@ -1830,7 +1837,7 @@ QCC_def_t *QCC_PR_Statement ( QCC_opcode_t *op, QCC_def_t *var_a, QCC_def_t *var } break; //no bitand_f, I don't trust the casts - case OP_AND: + case OP_AND_F: if (G_FLOAT(var_b->ofs) != 0) { optres_constantarithmatic++; @@ -1880,13 +1887,13 @@ QCC_def_t *QCC_PR_Statement ( QCC_opcode_t *op, QCC_def_t *var_a, QCC_def_t *var switch (op - pr_opcodes) { - case OP_AND: + case OP_AND_F: if (var_a->ofs == var_b->ofs) QCC_PR_ParseWarning(WARN_CONSTANTCOMPARISON, "Parameter offsets for && are the same"); if (var_a->constant || var_b->constant) QCC_PR_ParseWarning(WARN_CONSTANTCOMPARISON, "Result of comparison is constant"); break; - case OP_OR: + case OP_OR_F: if (var_a->ofs == var_b->ofs) QCC_PR_ParseWarning(WARN_CONSTANTCOMPARISON, "Parameters for || are the same"); if (var_a->constant || var_b->constant) @@ -1907,10 +1914,10 @@ QCC_def_t *QCC_PR_Statement ( QCC_opcode_t *op, QCC_def_t *var_a, QCC_def_t *var case OP_NE_E: case OP_NE_FNC: - case OP_LE: - case OP_GE: - case OP_LT: - case OP_GT: + case OP_LE_F: + case OP_GE_F: + case OP_LT_F: + case OP_GT_F: if ((var_a->constant && var_b->constant && !var_a->temp && !var_b->temp) || var_a->ofs == var_b->ofs) QCC_PR_ParseWarning(WARN_CONSTANTCOMPARISON, "Result of comparison is constant"); break; @@ -1918,8 +1925,8 @@ QCC_def_t *QCC_PR_Statement ( QCC_opcode_t *op, QCC_def_t *var_a, QCC_def_t *var case OP_IFNOT_S: case OP_IF_F: case OP_IFNOT_F: - case OP_IF: - case OP_IFNOT: + case OP_IF_I: + case OP_IFNOT_I: // if (var_a->type->type == ev_function && !var_a->temp) // QCC_PR_ParseWarning(WARN_CONSTANTCOMPARISON, "Result of comparison is constant"); if (var_a->constant && !var_a->temp) @@ -1931,7 +1938,7 @@ QCC_def_t *QCC_PR_Statement ( QCC_opcode_t *op, QCC_def_t *var_a, QCC_def_t *var if (numstatements) { //optimise based on last statement. - if (op - pr_opcodes == OP_IFNOT) + if (op - pr_opcodes == OP_IFNOT_I) { if (opt_shortenifnots && var_a && (statements[numstatements-1].op == OP_NOT_F || statements[numstatements-1].op == OP_NOT_FNC || statements[numstatements-1].op == OP_NOT_ENT)) { @@ -1941,7 +1948,7 @@ QCC_def_t *QCC_PR_Statement ( QCC_opcode_t *op, QCC_def_t *var_a, QCC_def_t *var if (statements[numstatements-1].op == OP_NOT_F) op = &pr_opcodes[OP_IF_F]; else - op = &pr_opcodes[OP_IF]; + op = &pr_opcodes[OP_IF_I]; numstatements--; QCC_FreeTemp(var_a); memcpy(&nvara, var_a, sizeof(nvara)); @@ -2020,7 +2027,7 @@ QCC_def_t *QCC_PR_Statement ( QCC_opcode_t *op, QCC_def_t *var_a, QCC_def_t *var } } simplestore=false; - + statement = &statements[numstatements]; numstatements++; @@ -2036,7 +2043,7 @@ QCC_def_t *QCC_PR_Statement ( QCC_opcode_t *op, QCC_def_t *var_a, QCC_def_t *var numstatements++; QCC_FreeTemp(var_a); - op = &pr_opcodes[OP_IF]; + op = &pr_opcodes[OP_IF_I]; break; case OP_IFNOT_S: @@ -2047,7 +2054,7 @@ QCC_def_t *QCC_PR_Statement ( QCC_opcode_t *op, QCC_def_t *var_a, QCC_def_t *var numstatements++; QCC_FreeTemp(var_a); - op = &pr_opcodes[OP_IFNOT]; + op = &pr_opcodes[OP_IFNOT_I]; break; case OP_IF_F: @@ -2058,7 +2065,7 @@ QCC_def_t *QCC_PR_Statement ( QCC_opcode_t *op, QCC_def_t *var_a, QCC_def_t *var numstatements++; QCC_FreeTemp(var_a); - op = &pr_opcodes[OP_IF]; + op = &pr_opcodes[OP_IF_I]; break; case OP_IFNOT_F: @@ -2069,7 +2076,7 @@ QCC_def_t *QCC_PR_Statement ( QCC_opcode_t *op, QCC_def_t *var_a, QCC_def_t *var numstatements++; QCC_FreeTemp(var_a); - op = &pr_opcodes[OP_IFNOT]; + op = &pr_opcodes[OP_IFNOT_I]; break; case OP_ADDSTORE_F: @@ -2192,7 +2199,7 @@ QCC_def_t *QCC_PR_Statement ( QCC_opcode_t *op, QCC_def_t *var_a, QCC_def_t *var var_c = var_a; break; case OP_BITSET: - op = &pr_opcodes[OP_BITOR]; + op = &pr_opcodes[OP_BITOR_F]; var_c = var_b; var_b = var_a; var_a = var_c; @@ -2206,11 +2213,11 @@ QCC_def_t *QCC_PR_Statement ( QCC_opcode_t *op, QCC_def_t *var_a, QCC_def_t *var QCC_UnFreeTemp(var_b); numstatements--; - var_c = QCC_PR_Statement(&pr_opcodes[OP_BITAND], var_b, var_a, NULL); + var_c = QCC_PR_Statement(&pr_opcodes[OP_BITAND_F], var_b, var_a, NULL); QCC_FreeTemp(var_c); statement = &statements[numstatements]; numstatements++; - + QCC_FreeTemp(var_a); QCC_FreeTemp(var_b); @@ -2250,19 +2257,17 @@ QCC_def_t *QCC_PR_Statement ( QCC_opcode_t *op, QCC_def_t *var_a, QCC_def_t *var if (statements[st].c == var_b->ofs) break; - if (statements[st].op >= OP_CALL0 && statements[st].op <= OP_CALL8 || statements[st].op >= OP_CALL1H && statements[st].op <= OP_CALL8H) + if ((statements[st].op >= OP_CALL0 && statements[st].op <= OP_CALL8) || (statements[st].op >= OP_CALL1H && statements[st].op <= OP_CALL8H)) need_lock = true; - //printf("%s\n", pr_opcodes[statements[st].op].opname); - if (statements[st].c == var_b->ofs) QCC_PR_ParseWarning(0, "Temp-reuse may have broken your %s", op->name); } if (st < 0) QCC_PR_ParseError(ERR_INTERNAL, "XSTOREP_F: pointer was not generated from previous statement"); var_c = QCC_GetTemp(*op->type_c); - if(need_lock) - QCC_LockTemp(var_c); // this will cause the temp to be remapped by QCC_RemapLockedTemps + if (need_lock) + QCC_LockTemp(var_c); /*that temp needs to be preserved over calls*/ statement_linenums[statement-statements] = statement_linenums[st]; statement->op = OP_ADDRESS; @@ -2320,7 +2325,7 @@ QCC_def_t *QCC_PR_Statement ( QCC_opcode_t *op, QCC_def_t *var_a, QCC_def_t *var statement->op = OP_DIV_F; break; case OP_BITSETP: - statement->op = OP_BITOR; + statement->op = OP_BITOR_F; break; case OP_BITSETP_I: statement->op = OP_BITOR_I; @@ -2328,7 +2333,7 @@ QCC_def_t *QCC_PR_Statement ( QCC_opcode_t *op, QCC_def_t *var_a, QCC_def_t *var case OP_BITCLRP: //float pointer float temp = QCC_GetTemp(type_float); - statement->op = OP_BITAND; + statement->op = OP_BITAND_F; statement->a = var_c ? var_c->ofs : 0; statement->b = var_a ? var_a->ofs : 0; statement->c = temp->ofs; @@ -2367,7 +2372,6 @@ QCC_def_t *QCC_PR_Statement ( QCC_opcode_t *op, QCC_def_t *var_a, QCC_def_t *var op = &pr_opcodes[OP_STOREP_F]; QCC_FreeTemp(var_c); - var_c = NULL; QCC_FreeTemp(var_b); @@ -2391,7 +2395,7 @@ QCC_def_t *QCC_PR_Statement ( QCC_opcode_t *op, QCC_def_t *var_a, QCC_def_t *var if (statements[st].c == var_b->ofs) break; - if (statements[st].op >= OP_CALL0 && statements[st].op <= OP_CALL8 || statements[st].op >= OP_CALL1H && statements[st].op <= OP_CALL8H) + if ((statements[st].op >= OP_CALL0 && statements[st].op <= OP_CALL8) || (statements[st].op >= OP_CALL1H && statements[st].op <= OP_CALL8H)) need_lock = true; if (statements[st].c == var_b->ofs) @@ -2400,8 +2404,8 @@ QCC_def_t *QCC_PR_Statement ( QCC_opcode_t *op, QCC_def_t *var_a, QCC_def_t *var if (st < 0) QCC_PR_ParseError(ERR_INTERNAL, "XSTOREP_V couldn't find pointer generation"); var_c = QCC_GetTemp(*op->type_c); - if(need_lock) - QCC_LockTemp(var_c); // this will cause the temp to be remapped by QCC_RemapLockedTemps + if (need_lock) + QCC_LockTemp(var_c); /*that temp needs to be preserved over calls*/ statement_linenums[statement-statements] = statement_linenums[st]; statement->op = OP_ADDRESS; @@ -2446,8 +2450,8 @@ QCC_def_t *QCC_PR_Statement ( QCC_opcode_t *op, QCC_def_t *var_a, QCC_def_t *var op = &pr_opcodes[OP_STOREP_V]; - - + + QCC_FreeTemp(var_c); var_c = NULL; QCC_FreeTemp(var_b); @@ -2463,7 +2467,7 @@ QCC_def_t *QCC_PR_Statement ( QCC_opcode_t *op, QCC_def_t *var_a, QCC_def_t *var if (outstatement) *outstatement = statement; - + statement_linenums[statement-statements] = pr_source_line; statement->op = op - pr_opcodes; statement->a = var_a ? var_a->ofs : 0; @@ -2535,7 +2539,7 @@ QCC_dstatement_t *QCC_PR_SimpleStatement( int op, int var_a, int var_b, int var_ void QCC_PR_Statement3 ( QCC_opcode_t *op, QCC_def_t *var_a, QCC_def_t *var_b, QCC_def_t *var_c, int force) { - QCC_dstatement_t *statement; + QCC_dstatement_t *statement; if (!force && !QCC_OPCodeValid(op)) { @@ -2544,9 +2548,9 @@ void QCC_PR_Statement3 ( QCC_opcode_t *op, QCC_def_t *var_a, QCC_def_t *var_b, Q QCC_PR_ParseError(ERR_BADEXTENSION, "Opcode \"%s|%s\" not valid for target\n", op->name, op->opname); } - statement = &statements[numstatements]; + statement = &statements[numstatements]; numstatements++; - + statement_linenums[statement-statements] = pr_source_line; statement->op = op - pr_opcodes; statement->a = var_a ? var_a->ofs : 0; @@ -2611,7 +2615,7 @@ QCC_def_t *QCC_PR_ParseImmediate (void) } } else if (pr_immediate_type == type_integer) - { + { if ( G_INT(cn->ofs) == pr_immediate._int ) { QCC_PR_Lex (); @@ -2628,7 +2632,7 @@ QCC_def_t *QCC_PR_ParseImmediate (void) return cn; } } - else + else QCC_PR_ParseError (ERR_BADIMMEDIATETYPE, "weird immediate type"); } @@ -2649,9 +2653,9 @@ QCC_def_t *QCC_PR_ParseImmediate (void) if (pr_immediate_type == type_string) pr_immediate.string = QCC_CopyString (pr_immediate_string); - + memcpy (qcc_pr_globals + cn->ofs, &pr_immediate, 4*type_size[pr_immediate_type->type]); - + QCC_PR_Lex (); return cn; @@ -2665,7 +2669,7 @@ void QCC_PrecacheSound (QCC_def_t *e, int ch) if (e->type->type != ev_string) return; - + if (!e->ofs || e->temp || !e->constant) return; n = G_STRING(e->ofs); @@ -2692,9 +2696,9 @@ void QCC_PrecacheModel (QCC_def_t *e, int ch) if (e->type->type != ev_string) return; - + if (!e->ofs || e->temp || !e->constant) - return; + return; n = G_STRING(e->ofs); if (!*n) return; @@ -2728,9 +2732,9 @@ void QCC_SetModel (QCC_def_t *e) if (e->type->type != ev_string) return; - + if (!e->ofs || e->temp || !e->constant) - return; + return; n = G_STRING(e->ofs); if (!*n) return; @@ -2755,7 +2759,7 @@ void QCC_PrecacheTexture (QCC_def_t *e, int ch) if (e->type->type != ev_string) return; - + if (!e->ofs || e->temp || !e->constant) return; n = G_STRING(e->ofs); @@ -2782,7 +2786,7 @@ void QCC_PrecacheFile (QCC_def_t *e, int ch) if (e->type->type != ev_string) return; - + if (!e->ofs || e->temp || !e->constant) return; n = G_STRING(e->ofs); @@ -2865,7 +2869,7 @@ QCC_def_t *QCC_PR_GenerateFunctionCall (QCC_def_t *func, QCC_def_t *arglist[], i } else np = t->num_parms; - + if (strchr(func->name, ':') && laststatement && statements[laststatement-1].op == OP_LOAD_FNC && statements[laststatement-1].c == func->ofs) { //we're entering OO code with a different self. //eg: other.touch(self) @@ -2974,7 +2978,7 @@ QCC_def_t *QCC_PR_GenerateFunctionCall (QCC_def_t *func, QCC_def_t *arglist[], i } } } - + //restore the class owner if (oself) QCC_PR_SimpleStatement(OP_STORE_ENT, oself->ofs, d->ofs, 0, false); @@ -3033,12 +3037,11 @@ PR_ParseFunctionCall */ QCC_def_t *QCC_PR_ParseFunctionCall (QCC_def_t *func) //warning, the func could have no name set if it's a field call. { - QCC_def_t *e, *d, *old, *oself, *out; + QCC_def_t *e, *d, *old = {0}, *oself, *out; // warning: ‘oldÂ’ may be used uninitialized in this function int arg; QCC_type_t *t, *p; int extraparms=false; int np; - int laststatement = numstatements; int callconvention; @@ -3097,7 +3100,7 @@ QCC_def_t *QCC_PR_ParseFunctionCall (QCC_def_t *func) //warning, the func could out = QCC_GetTemp(type_float); else out = &def_ret; - + if (e) { if (d) @@ -3123,7 +3126,7 @@ QCC_def_t *QCC_PR_ParseFunctionCall (QCC_def_t *func) //warning, the func could } else old = NULL; - + if (e) { if (d) @@ -3134,8 +3137,8 @@ QCC_def_t *QCC_PR_ParseFunctionCall (QCC_def_t *func) //warning, the func could if ((!d->constant || !e->constant) && G_FLOAT(d->ofs) >= G_FLOAT(d->ofs)) { - t = QCC_PR_Statement(&pr_opcodes[OP_GT], d, e, NULL); - QCC_FreeTemp(QCC_PR_Statement(&pr_opcodes[OP_IFNOT], t, 0, &st)); + t = QCC_PR_Statement(&pr_opcodes[OP_GT_F], d, e, NULL); + QCC_FreeTemp(QCC_PR_Statement(&pr_opcodes[OP_IFNOT_I], t, 0, &st)); st->b = 3; t = QCC_PR_Statement(&pr_opcodes[OP_SUB_F], d, e, NULL); @@ -3146,7 +3149,7 @@ QCC_def_t *QCC_PR_ParseFunctionCall (QCC_def_t *func) //warning, the func could QCC_FreeTemp(QCC_PR_Statement(&pr_opcodes[OP_GOTO], 0, 0, &st)); st->a = 3; } - + t = QCC_PR_Statement(&pr_opcodes[OP_SUB_F], e, d, NULL); QCC_PR_SimpleStatement(OP_MUL_F, OFS_RETURN, t->ofs, OFS_RETURN, false); QCC_FreeTemp(t); @@ -3227,7 +3230,7 @@ QCC_def_t *QCC_PR_ParseFunctionCall (QCC_def_t *func) //warning, the func could out = QCC_GetTemp(type_vector); else out = &def_ret; - + if (e) { if (d) @@ -3253,7 +3256,7 @@ QCC_def_t *QCC_PR_ParseFunctionCall (QCC_def_t *func) //warning, the func could } else old = NULL; - + if (e) { if (d) @@ -3264,8 +3267,8 @@ QCC_def_t *QCC_PR_ParseFunctionCall (QCC_def_t *func) //warning, the func could if ((!d->constant || !e->constant) && G_FLOAT(d->ofs) >= G_FLOAT(d->ofs)) { t = QCC_GetTemp(type_float); - QCC_PR_SimpleStatement(OP_GT, d->ofs+2, e->ofs+2, t->ofs, false); - QCC_PR_SimpleStatement(OP_IFNOT, t->ofs, 3, 0, false); + QCC_PR_SimpleStatement(OP_GT_F, d->ofs+2, e->ofs+2, t->ofs, false); + QCC_PR_SimpleStatement(OP_IFNOT_I, t->ofs, 3, 0, false); QCC_PR_SimpleStatement(OP_SUB_F, d->ofs+2, e->ofs+2, t->ofs, false); QCC_PR_SimpleStatement(OP_MUL_F, OFS_RETURN, t->ofs, OFS_RETURN+2, false); @@ -3274,22 +3277,22 @@ QCC_def_t *QCC_PR_ParseFunctionCall (QCC_def_t *func) //warning, the func could QCC_PR_SimpleStatement(OP_GOTO, 3, 0, 0, false); } - + t = QCC_GetTemp(type_float); QCC_PR_SimpleStatement(OP_SUB_F, d->ofs+2, e->ofs+2, t->ofs, false); QCC_PR_SimpleStatement(OP_MUL_F, OFS_RETURN, t->ofs, OFS_RETURN+2, false); QCC_FreeTemp(t); QCC_PR_SimpleStatement(OP_ADD_F, OFS_RETURN, d->ofs+2, OFS_RETURN+2, false); - - + + QCC_PR_SimpleStatement(OP_CALL0, func->ofs, 0, 0, false); if ((!d->constant || !e->constant) && G_FLOAT(d->ofs) >= G_FLOAT(d->ofs)) { t = QCC_GetTemp(type_float); - QCC_PR_SimpleStatement(OP_GT, d->ofs+1, e->ofs+1, t->ofs, false); - QCC_PR_SimpleStatement(OP_IFNOT, t->ofs, 3, 0, false); + QCC_PR_SimpleStatement(OP_GT_F, d->ofs+1, e->ofs+1, t->ofs, false); + QCC_PR_SimpleStatement(OP_IFNOT_I, t->ofs, 3, 0, false); QCC_PR_SimpleStatement(OP_SUB_F, d->ofs+1, e->ofs+1, t->ofs, false); QCC_PR_SimpleStatement(OP_MUL_F, OFS_RETURN, t->ofs, OFS_RETURN+1, false); @@ -3298,7 +3301,7 @@ QCC_def_t *QCC_PR_ParseFunctionCall (QCC_def_t *func) //warning, the func could QCC_PR_SimpleStatement(OP_GOTO, 3, 0, 0, false); } - + t = QCC_GetTemp(type_float); QCC_PR_SimpleStatement(OP_SUB_F, d->ofs+1, e->ofs+1, t->ofs, false); QCC_PR_SimpleStatement(OP_MUL_F, OFS_RETURN, t->ofs, OFS_RETURN+1, false); @@ -3311,8 +3314,8 @@ QCC_def_t *QCC_PR_ParseFunctionCall (QCC_def_t *func) //warning, the func could if ((!d->constant || !e->constant) && G_FLOAT(d->ofs) >= G_FLOAT(d->ofs)) { t = QCC_GetTemp(type_float); - QCC_PR_SimpleStatement(OP_GT, d->ofs, e->ofs, t->ofs, false); - QCC_PR_SimpleStatement(OP_IFNOT, t->ofs, 3, 0, false); + QCC_PR_SimpleStatement(OP_GT_F, d->ofs, e->ofs, t->ofs, false); + QCC_PR_SimpleStatement(OP_IFNOT_I, t->ofs, 3, 0, false); QCC_PR_SimpleStatement(OP_SUB_F, d->ofs, e->ofs, t->ofs, false); QCC_PR_SimpleStatement(OP_MUL_F, OFS_RETURN, t->ofs, OFS_RETURN, false); @@ -3321,7 +3324,7 @@ QCC_def_t *QCC_PR_ParseFunctionCall (QCC_def_t *func) //warning, the func could QCC_PR_SimpleStatement(OP_GOTO, 3, 0, 0, false); } - + t = QCC_GetTemp(type_float); QCC_PR_SimpleStatement(OP_SUB_F, d->ofs, e->ofs, t->ofs, false); QCC_PR_SimpleStatement(OP_MUL_F, OFS_RETURN, t->ofs, OFS_RETURN, false); @@ -3401,7 +3404,7 @@ QCC_def_t *QCC_PR_ParseFunctionCall (QCC_def_t *func) //warning, the func could QCC_PR_Expect(")"); } - + if (def_ret.temp->used) { old = QCC_GetTemp(def_ret.type); @@ -3444,7 +3447,7 @@ QCC_def_t *QCC_PR_ParseFunctionCall (QCC_def_t *func) //warning, the func could return d; } - + def_ret.type = rettype; return &def_ret; } @@ -3674,7 +3677,7 @@ int typechecks; QCC_def_t *QCC_MakeIntDef(int value) { QCC_def_t *cn; - + // check for a constant with the same value for (cn=pr.def_head.next ; cn ; cn=cn->next) { @@ -3689,9 +3692,9 @@ QCC_def_t *QCC_MakeIntDef(int value) typechecks++; if ( G_INT(cn->ofs) == value ) - { + { return cn; - } + } } // allocate a new one @@ -3709,9 +3712,9 @@ QCC_def_t *QCC_MakeIntDef(int value) // copy the immediate to the global area cn->ofs = QCC_GetFreeOffsetSpace (type_size[type_integer->type]); - - G_INT(cn->ofs) = value; - + + G_INT(cn->ofs) = value; + return cn; } @@ -3719,7 +3722,7 @@ QCC_def_t *QCC_MakeIntDef(int value) QCC_def_t *QCC_MakeVectorDef(float a, float b, float c) { QCC_def_t *cn; - + // check for a constant with the same value for (cn=pr.def_head.next ; cn ; cn=cn->next) { @@ -3736,9 +3739,9 @@ QCC_def_t *QCC_MakeVectorDef(float a, float b, float c) if ( G_FLOAT(cn->ofs+0) == a && G_FLOAT(cn->ofs+1) == b && G_FLOAT(cn->ofs+2) == c) - { + { return cn; - } + } } // allocate a new one @@ -3756,7 +3759,7 @@ QCC_def_t *QCC_MakeVectorDef(float a, float b, float c) // copy the immediate to the global area cn->ofs = QCC_GetFreeOffsetSpace (type_size[type_vector->type]); - + G_FLOAT(cn->ofs+0) = a; G_FLOAT(cn->ofs+1) = b; G_FLOAT(cn->ofs+2) = c; @@ -3797,11 +3800,11 @@ QCC_def_t *QCC_MakeFloatDef(float value) // copy the immediate to the global area cn->ofs = QCC_GetFreeOffsetSpace (type_size[type_integer->type]); - + Hash_AddKey(&floatconstdefstable, fi.i, cn, qccHunkAlloc(sizeof(bucket_t))); - - G_FLOAT(cn->ofs) = value; - + + G_FLOAT(cn->ofs) = value; + return cn; } @@ -3840,13 +3843,13 @@ QCC_def_t *QCC_MakeStringDef(char *value) // copy the immediate to the global area cn->ofs = QCC_GetFreeOffsetSpace (type_size[type_integer->type]); - + string = QCC_CopyString (value); pHash_Add(tbl, strings+string, cn, qccHunkAlloc(sizeof(bucket_t))); - - G_INT(cn->ofs) = string; - + + G_INT(cn->ofs) = string; + return cn; } @@ -3953,7 +3956,7 @@ void QCC_PR_EmitFieldsForMembers(QCC_type_t *clas) ft = QCC_PR_FindType(ft); sprintf(membername, "__f_%s_%i", ft->name, ++basictypefield[mt->type]); f = QCC_PR_GetDef(ft, membername, NULL, true, 1, true); - + for (o = 0; o < m->type->size; o++) ((int *)qcc_pr_globals)[o+a*mt->size+m->ofs] = ((int *)qcc_pr_globals)[o+f->ofs]; @@ -4055,7 +4058,7 @@ void QCC_PR_EmitClassFromFunction(QCC_def_t *scope, char *tname) if (!virt) QCC_Error(ERR_INTERNAL, "spawn function was not defined\n"); QCC_PR_SimpleStatement(OP_CALL0, virt->ofs, 0, 0, false); //calling convention doesn't come into it. - + QCC_FreeTemp(QCC_PR_Statement(&pr_opcodes[OP_STORE_ENT], &def_ret, ed, NULL)); ed->references = 1; //there may be no functions. @@ -4120,7 +4123,7 @@ QCC_def_t *QCC_PR_ParseValue (QCC_type_t *assumeclass, pbool allowarrayassign) }; char membername[2048]; - + // if the token is an immediate, allocate a constant for it if (pr_token_type == tt_immediate) return QCC_PR_ParseImmediate (); @@ -4165,7 +4168,7 @@ QCC_def_t *QCC_PR_ParseValue (QCC_type_t *assumeclass, pbool allowarrayassign) // look through the defs od = d = QCC_PR_GetDef (NULL, name, pr_scope, false, 0, false); - + if (!d) { if ( (!strcmp(name, "random" )) || @@ -4213,12 +4216,12 @@ reloop: QCC_type_t *newtype; if (ao) { - numstatements--; //remove the last statement + numstatements--; //remove the last statement nd = QCC_PR_Expression (TOP_PRIORITY, 0); QCC_PR_Expect("]"); - if (d->type->size != 1) //we need to multiply it to find the offset. + if (d->type->size != 1) //we need to multiply it to find the offset. { if (ao->type->type == ev_integer) nd = QCC_PR_Statement(&pr_opcodes[OP_MUL_I], nd, QCC_MakeIntDef(d->type->size), NULL); //get add part @@ -4295,7 +4298,7 @@ reloop: nd = QCC_PR_Statement(&pr_opcodes[OP_LOADA_V], d, ao, NULL); //get pointer to precise def. break; case ev_entity: - nd = QCC_PR_Statement(&pr_opcodes[OP_LOADA_ENT], d, ao, NULL); //get pointer to precise def. + nd = QCC_PR_Statement(&pr_opcodes[OP_LOADA_ENT], d, ao, NULL); //get pointer to precise def. break; case ev_field: nd = QCC_PR_Statement(&pr_opcodes[OP_LOADA_FLD], d, ao, NULL); //get pointer to precise def. @@ -4438,7 +4441,7 @@ reloop: def_parms[0].type = type_float; funcretr = QCC_PR_GetDef(type_function, qcva("ArrayGet*%s", d->name), NULL, true, 1, false); - + args[0] = ao; nd = QCC_PR_GenerateFunctionCall(funcretr, args, 1); nd->type = d->type->aux_type; @@ -4498,7 +4501,7 @@ reloop: nd = QCC_PR_Statement(&pr_opcodes[OP_LOADA_V], d, QCC_PR_Statement (&pr_opcodes[OP_CONV_FTOI], ao, 0, NULL), NULL); //get pointer to precise def. break; case ev_entity: - nd = QCC_PR_Statement(&pr_opcodes[OP_LOADA_ENT], d, QCC_PR_Statement (&pr_opcodes[OP_CONV_FTOI], ao, 0, NULL), NULL); //get pointer to precise def. + nd = QCC_PR_Statement(&pr_opcodes[OP_LOADA_ENT], d, QCC_PR_Statement (&pr_opcodes[OP_CONV_FTOI], ao, 0, NULL), NULL); //get pointer to precise def. break; case ev_field: nd = QCC_PR_Statement(&pr_opcodes[OP_LOADA_FLD], d, QCC_PR_Statement (&pr_opcodes[OP_CONV_FTOI], ao, 0, NULL), NULL); //get pointer to precise def. @@ -4526,7 +4529,7 @@ reloop: } else QCC_PR_ParseError(ERR_BADARRAYINDEXTYPE, "Array offset is not of integer or float type"); - + d->type = newtype; goto reloop; } @@ -4550,7 +4553,7 @@ reloop: d = od; nd = QCC_MakeIntDef(type->ofs); - ao = QCC_PR_Statement(&pr_opcodes[OP_ADD_I], ao, nd, NULL); //get add part + ao = QCC_PR_Statement(&pr_opcodes[OP_ADD_I], ao, nd, NULL); //get add part //so that we may offset it and readd it. } @@ -4568,7 +4571,7 @@ reloop: nd = QCC_PR_Statement(&pr_opcodes[OP_LOADP_V], d, ao, NULL); //get pointer to precise def. break; case ev_entity: - nd = QCC_PR_Statement(&pr_opcodes[OP_LOADP_ENT], d, ao, NULL); //get pointer to precise def. + nd = QCC_PR_Statement(&pr_opcodes[OP_LOADP_ENT], d, ao, NULL); //get pointer to precise def. break; case ev_field: nd = QCC_PR_Statement(&pr_opcodes[OP_LOADP_FLD], d, ao, NULL); //get pointer to precise def. @@ -4590,7 +4593,7 @@ reloop: QCC_PR_ParseError(ERR_NOVALIDOPCODES, "No op available. Try assembler"); nd = NULL; break; - } + } d=nd; break; @@ -4600,7 +4603,7 @@ reloop: for (j = type->num_parms; j;j--) type++; } - } + } if (!i) QCC_PR_ParseError (ERR_MEMBERNOTVALID, "\"%s\" is not a member of \"%s\"", pr_token, od->type->name); @@ -4624,7 +4627,7 @@ reloop: d = od; nd = QCC_MakeIntDef(type->ofs); - ao = QCC_PR_Statement(&pr_opcodes[OP_ADD_I], ao, nd, NULL); //get add part + ao = QCC_PR_Statement(&pr_opcodes[OP_ADD_I], ao, nd, NULL); //get add part //so that we may offset it and readd it. } @@ -4642,7 +4645,7 @@ reloop: nd = QCC_PR_Statement(&pr_opcodes[OP_LOADA_V], d, ao, NULL); //get pointer to precise def. break; case ev_entity: - nd = QCC_PR_Statement(&pr_opcodes[OP_LOADA_ENT], d, ao, NULL); //get pointer to precise def. + nd = QCC_PR_Statement(&pr_opcodes[OP_LOADA_ENT], d, ao, NULL); //get pointer to precise def. break; case ev_field: nd = QCC_PR_Statement(&pr_opcodes[OP_LOADA_FLD], d, ao, NULL); //get pointer to precise def. @@ -4664,7 +4667,7 @@ reloop: QCC_PR_ParseError(ERR_NOVALIDOPCODES, "No op available. Try assembler"); nd = NULL; break; - } + } d=nd; break; @@ -4674,7 +4677,7 @@ reloop: for (j = type->num_parms; j;j--) type++; } - } + } if (!i) QCC_PR_ParseError (ERR_MEMBERNOTVALID, "\"%s\" is not a member of \"%s\"", pr_token, od->type->name); @@ -4694,7 +4697,7 @@ reloop: break; } } -*/ +*/ if (!keyword_class) return d; @@ -4729,7 +4732,7 @@ reloop: case ev_field: d = QCC_PR_Statement(&pr_opcodes[OP_LOAD_FLD], d, field, NULL); nd = (void *)qccHunkAlloc (sizeof(QCC_def_t)); - memset (nd, 0, sizeof(QCC_def_t)); + memset (nd, 0, sizeof(QCC_def_t)); nd->type = field->type->aux_type; nd->ofs = d->ofs; nd->temp = d->temp; @@ -4746,7 +4749,7 @@ reloop: { //complicated for a typecast d = QCC_PR_Statement(&pr_opcodes[OP_LOAD_FNC], d, field, NULL); nd = (void *)qccHunkAlloc (sizeof(QCC_def_t)); - memset (nd, 0, sizeof(QCC_def_t)); + memset (nd, 0, sizeof(QCC_def_t)); nd->type = field->type->aux_type; nd->ofs = d->ofs; nd->temp = d->temp; @@ -4763,7 +4766,7 @@ reloop: else QCC_PR_IncludeChunk(".", false, NULL); } - } + } return d; } @@ -4824,7 +4827,7 @@ QCC_def_t *QCC_PR_Term (void) } return e; } - + if (QCC_PR_CheckToken ("!")) { e = QCC_PR_Expression (NOT_PRIORITY, EXPR_DISALLOW_COMMA|EXPR_WARN_ABOVE_1); @@ -4969,7 +4972,7 @@ QCC_def_t *QCC_PR_Term (void) } return e2; } - + if (QCC_PR_CheckToken ("(")) { if (QCC_PR_CheckKeyword(keyword_float, "float")) //check for type casts @@ -4988,7 +4991,7 @@ QCC_def_t *QCC_PR_Term (void) QCC_PR_ParseWarning (0, "Not all vars make sence as floats"); e2 = (void *)qccHunkAlloc (sizeof(QCC_def_t)); - memset (e2, 0, sizeof(QCC_def_t)); + memset (e2, 0, sizeof(QCC_def_t)); e2->type = type_float; e2->ofs = e->ofs; e2->constant = true; @@ -5004,7 +5007,7 @@ QCC_def_t *QCC_PR_Term (void) QCC_PR_Expect (")"); e = QCC_PR_Term(); e2 = (void *)qccHunkAlloc (sizeof(QCC_def_t)); - memset (e2, 0, sizeof(QCC_def_t)); + memset (e2, 0, sizeof(QCC_def_t)); e2->type = classtype; e2->ofs = e->ofs; e2->constant = true; @@ -5064,7 +5067,7 @@ int QCC_canConv(QCC_def_t *from, etype_t to) return 1; } } - + /* if (from->type->type == ev_pointer && from->type->aux_type->type == to) return 1; @@ -5112,7 +5115,7 @@ QCC_def_t *QCC_PR_Expression (int priority, int exprflags) if (QCC_PR_CheckToken ("?")) { QCC_dstatement32_t *fromj, *elsej; - QCC_FreeTemp(QCC_PR_Statement(&pr_opcodes[OP_IFNOT], e, NULL, &fromj)); + QCC_FreeTemp(QCC_PR_Statement(&pr_opcodes[OP_IFNOT_I], e, NULL, &fromj)); e = QCC_PR_Expression(TOP_PRIORITY, 0); e2 = QCC_GetTemp(e->type); QCC_FreeTemp(QCC_PR_Statement(&pr_opcodes[(e2->type->size>=3)?OP_STORE_V:OP_STORE_F], e, e2, NULL)); @@ -5223,9 +5226,9 @@ QCC_def_t *QCC_PR_Expression (int priority, int exprflags) optres_logicops++; st = &statements[numstatements]; if (*op->name == '&') //statement 3 because we don't want to optimise this into if from not ifnot - QCC_PR_Statement3(&pr_opcodes[OP_IFNOT], e, NULL, NULL, false); + QCC_PR_Statement3(&pr_opcodes[OP_IFNOT_I], e, NULL, NULL, false); else - QCC_PR_Statement3(&pr_opcodes[OP_IF], e, NULL, NULL, false); + QCC_PR_Statement3(&pr_opcodes[OP_IF_I], e, NULL, NULL, false); } e2 = QCC_PR_Expression (priority-1, exprflags); @@ -5247,10 +5250,10 @@ QCC_def_t *QCC_PR_Expression (int priority, int exprflags) } else type_c = ev_void; - + oldop = op; bestop = NULL; - numconversions = 32767; + numconversions = 32767; while (op) { if (!(type_c != ev_void && type_c != (*op->type_c)->type)) @@ -5307,7 +5310,7 @@ QCC_def_t *QCC_PR_Expression (int priority, int exprflags) if (c == 0)//can't get less conversions than 0... break; } - } + } else break; } @@ -5368,13 +5371,13 @@ QCC_def_t *QCC_PR_Expression (int priority, int exprflags) } else e = QCC_PR_Statement (op, e, e2, NULL); - + if (type_c != ev_void/* && type_c != ev_string*/) // field access gets type from field e->type = e2->type->aux_type; if (priority > 1 && exprflags & EXPR_WARN_ABOVE_1) QCC_PR_ParseWarning(0, "You may wish to add brackets after that ! operator"); - + break; } if (!op) @@ -5519,7 +5522,7 @@ QCC_def_t *QCC_PR_Expression (int priority, int exprflags) QCC_FreeTemp(e); return QCC_PR_Expression(TOP_PRIORITY, exprflags); } - + return e; } @@ -5585,14 +5588,18 @@ void QCC_PR_ParseStatement (void) if (pr_subscopedlocals) { - for (e2 = pr.localvars; e2 != e; e2 = e2->nextlocal) + for (e2 = pr.localvars; e2 != e; e2 = e2->nextlocal) { - Hash_RemoveData(&localstable, e2->name, e2); + if (!e2->subscoped_away) + { + Hash_RemoveData(&localstable, e2->name, e2); + e2->subscoped_away = true; + } } } return; } - + if (QCC_PR_CheckKeyword(keyword_return, "return")) { /*if (pr_classtype) @@ -5631,7 +5638,7 @@ void QCC_PR_ParseStatement (void) QCC_PR_Expect (";"); return; } - + if (QCC_PR_CheckKeyword(keyword_while, "while")) { continues = num_continues; @@ -5672,7 +5679,7 @@ void QCC_PR_ParseStatement (void) else if (!typecmp( e->type, type_float) && (flag_iffloat||QCC_OPCodeValid(&pr_opcodes[OP_IFNOT_F]))) //special case, as negative 0 is also zero QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_IFNOT_F], e, 0, &patch1)); else - QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_IFNOT], e, 0, &patch1)); + QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_IFNOT_I], e, 0, &patch1)); } QCC_PR_Expect (")"); //after the line number is noted.. QCC_PR_ParseStatement (); @@ -5756,7 +5763,7 @@ void QCC_PR_ParseStatement (void) numtemp = 0; if (e) - QCC_FreeTemp(QCC_PR_Statement(&pr_opcodes[OP_IFNOT], e, 0, &patch1)); + QCC_FreeTemp(QCC_PR_Statement(&pr_opcodes[OP_IFNOT_I], e, 0, &patch1)); else patch1 = NULL; if (!QCC_PR_CheckToken(";")) @@ -5774,7 +5781,7 @@ void QCC_PR_ParseStatement (void) if (breaks != num_breaks) { for(i = breaks; i < num_breaks; i++) - { + { patch1 = &statements[pr_breaks[i]]; statements[pr_breaks[i]].a = &statements[numstatements] - patch1; } @@ -5823,7 +5830,7 @@ void QCC_PR_ParseStatement (void) else if (!typecmp( e->type, type_float) && (flag_iffloat||QCC_OPCodeValid(&pr_opcodes[OP_IFNOT_F]))) QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_IF_F], e, NULL, &patch2)); else - QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_IF], e, NULL, &patch2)); + QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_IF_I], e, NULL, &patch2)); patch2->b = patch1 - patch2; } @@ -5852,10 +5859,10 @@ void QCC_PR_ParseStatement (void) return; } - + if (QCC_PR_CheckKeyword(keyword_local, "local")) { - QCC_type_t *functionsclasstype = pr_classtype; + QCC_type_t *functionsclasstype = pr_classtype; // if (locals_end != numpr_globals) //is this breaking because of locals? // QCC_PR_ParseWarning("local vars after temp vars\n"); QCC_PR_ParseDefs (NULL); @@ -5899,7 +5906,7 @@ void QCC_PR_ParseStatement (void) QCC_PR_Expect(";"); return; } - + if (QCC_PR_CheckKeyword(keyword_if, "if")) { pbool negate = QCC_PR_CheckKeyword(keyword_not, "not"); @@ -5921,7 +5928,7 @@ void QCC_PR_ParseStatement (void) else if (!typecmp( e->type, type_float) && (flag_iffloat||QCC_OPCodeValid(&pr_opcodes[OP_IFNOT_F]))) QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_IF_F], e, 0, &patch1)); else - QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_IF], e, 0, &patch1)); + QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_IF_I], e, 0, &patch1)); } else { @@ -5933,7 +5940,7 @@ void QCC_PR_ParseStatement (void) else if (!typecmp( e->type, type_float) && (flag_iffloat||QCC_OPCodeValid(&pr_opcodes[OP_IFNOT_F]))) QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_IFNOT_F], e, 0, &patch1)); else - QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_IFNOT], e, 0, &patch1)); + QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_IFNOT_I], e, 0, &patch1)); } QCC_PR_Expect (")"); //close bracket is after we save the statement to mem (so debugger does not show the if statement as being on the line after @@ -6018,7 +6025,7 @@ void QCC_PR_ParseStatement (void) //default: // break; //} - + //to // x = CONDITION, goto start @@ -6036,7 +6043,7 @@ void QCC_PR_ParseStatement (void) //x is emitted in an opcode, stored as a register that we cannot access later. //it should be possible to nest these. - + switchtype = e->type; switch(switchtype->type) { @@ -6072,7 +6079,7 @@ void QCC_PR_ParseStatement (void) QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_GOTO], e, 0, &patch1)); QCC_PR_Expect (")"); //close bracket is after we save the statement to mem (so debugger does not show the if statement as being on the line after - + oldst = numstatements; QCC_PR_ParseStatement (); @@ -6134,18 +6141,18 @@ void QCC_PR_ParseStatement (void) if (e->type->type == ev_float) { - e2 = QCC_PR_Statement (&pr_opcodes[OP_GE], e, pr_casesdef[i], NULL); - e3 = QCC_PR_Statement (&pr_opcodes[OP_LE], e, pr_casesdef2[i], NULL); - e2 = QCC_PR_Statement (&pr_opcodes[OP_AND], e2, e3, NULL); - QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_IF], e2, 0, &patch3)); + e2 = QCC_PR_Statement (&pr_opcodes[OP_GE_F], e, pr_casesdef[i], NULL); + e3 = QCC_PR_Statement (&pr_opcodes[OP_LE_F], e, pr_casesdef2[i], NULL); + e2 = QCC_PR_Statement (&pr_opcodes[OP_AND_F], e2, e3, NULL); + QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_IF_I], e2, 0, &patch3)); patch3->b = &statements[pr_cases[i]] - patch3; } else if (e->type->type == ev_integer) { e2 = QCC_PR_Statement (&pr_opcodes[OP_GE_I], e, pr_casesdef[i], NULL); e3 = QCC_PR_Statement (&pr_opcodes[OP_LE_I], e, pr_casesdef2[i], NULL); - e2 = QCC_PR_Statement (&pr_opcodes[OP_AND], e2, e3, NULL); - QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_IF], e2, 0, &patch3)); + e2 = QCC_PR_Statement (&pr_opcodes[OP_AND_I], e2, e3, NULL); + QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_IF_I], e2, 0, &patch3)); patch3->b = &statements[pr_cases[i]] - patch3; } else @@ -6191,7 +6198,7 @@ void QCC_PR_ParseStatement (void) e2 = NULL; break; } - QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_IF], e2, 0, &patch3)); + QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_IF_I], e2, 0, &patch3)); } else { @@ -6200,12 +6207,12 @@ void QCC_PR_ParseStatement (void) else if (e->type->type == ev_float) QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_IFNOT_F], e, 0, &patch3)); else - QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_IFNOT], e, 0, &patch3)); + QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_IFNOT_I], e, 0, &patch3)); } patch3->b = &statements[pr_cases[i]] - patch3; } } - } + } } if (defaultcase>=0) { @@ -6471,7 +6478,7 @@ void QCC_PR_ParseState (void) if (s1->type->type != ev_float || def->type->type != ev_float) QCC_PR_ParseError(ERR_STATETYPEMISMATCH, "state type mismatch"); - + if (QCC_OPCodeValid(&pr_opcodes[OP_CSTATE])) QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_CSTATE], s1, def, NULL)); @@ -6495,20 +6502,20 @@ void QCC_PR_ParseState (void) //make sure the frame is within the bounds given. ftemp = frame->temp; frame->temp = NULL; - t1 = QCC_PR_Statement(&pr_opcodes[OP_LT], frame, s1, NULL); - t2 = QCC_PR_Statement(&pr_opcodes[OP_GT], frame, def, NULL); - t1 = QCC_PR_Statement(&pr_opcodes[OP_OR], t1, t2, NULL); - QCC_PR_SimpleStatement(OP_IFNOT, t1->ofs, 2, 0, false); + t1 = QCC_PR_Statement(&pr_opcodes[OP_LT_F], frame, s1, NULL); + t2 = QCC_PR_Statement(&pr_opcodes[OP_GT_F], frame, def, NULL); + t1 = QCC_PR_Statement(&pr_opcodes[OP_OR_F], t1, t2, NULL); + QCC_PR_SimpleStatement(OP_IFNOT_I, t1->ofs, 2, 0, false); QCC_FreeTemp(t1); QCC_FreeTemp(QCC_PR_Statement(&pr_opcodes[OP_STORE_F], s1, frame, NULL)); QCC_PR_SimpleStatement(OP_GOTO, t1->ofs, 13, 0, false); - t1 = QCC_PR_Statement(&pr_opcodes[OP_GE], def, s1, NULL); - QCC_PR_SimpleStatement(OP_IFNOT, t1->ofs, 7, 0, false); + t1 = QCC_PR_Statement(&pr_opcodes[OP_GE_F], def, s1, NULL); + QCC_PR_SimpleStatement(OP_IFNOT_I, t1->ofs, 7, 0, false); QCC_FreeTemp(t1); //this block is the 'it's in a forwards direction' QCC_PR_SimpleStatement(OP_ADD_F, frame->ofs, QCC_MakeFloatDef(1)->ofs, frame->ofs, false); - t1 = QCC_PR_Statement(&pr_opcodes[OP_GT], frame, def, NULL); - QCC_PR_SimpleStatement(OP_IFNOT, t1->ofs,2, 0, false); + t1 = QCC_PR_Statement(&pr_opcodes[OP_GT_F], frame, def, NULL); + QCC_PR_SimpleStatement(OP_IFNOT_I, t1->ofs,2, 0, false); QCC_FreeTemp(t1); QCC_FreeTemp(QCC_PR_Statement(&pr_opcodes[OP_STORE_F], s1, frame, NULL)); QCC_UnFreeTemp(frame); @@ -6518,14 +6525,14 @@ void QCC_PR_ParseState (void) QCC_PR_SimpleStatement(OP_GOTO, 6, 0, 0, false); //reverse animation. QCC_PR_SimpleStatement(OP_SUB_F, frame->ofs, QCC_MakeFloatDef(1)->ofs, frame->ofs, false); - t1 = QCC_PR_Statement(&pr_opcodes[OP_LT], frame, s1, NULL); - QCC_PR_SimpleStatement(OP_IFNOT, t1->ofs,2, 0, false); + t1 = QCC_PR_Statement(&pr_opcodes[OP_LT_F], frame, s1, NULL); + QCC_PR_SimpleStatement(OP_IFNOT_I, t1->ofs,2, 0, false); QCC_FreeTemp(t1); QCC_FreeTemp(QCC_PR_Statement(&pr_opcodes[OP_STORE_F], def, frame, NULL)); QCC_UnFreeTemp(frame); if (cycle_wrapped) QCC_FreeTemp(QCC_PR_Statement(&pr_opcodes[OP_STORE_F], QCC_MakeFloatDef(1), cycle_wrapped, NULL)); - + //self.frame = frame happens with the normal state opcode. QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_STATE], frame, pr_scope, NULL)); @@ -6534,20 +6541,20 @@ void QCC_PR_ParseState (void) } return; } - + if (pr_token_type != tt_immediate || pr_immediate_type != type_float) QCC_PR_ParseError (ERR_STATETYPEMISMATCH, "state frame must be a number"); s1 = QCC_PR_ParseImmediate (); - + QCC_PR_CheckToken (","); name = QCC_PR_ParseName (); pr_scope = NULL; def = QCC_PR_GetDef (type_function, name, NULL, true, 1, false); pr_scope = sc; - + QCC_PR_Expect ("]"); - + QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_STATE], s1, def, NULL)); } @@ -6630,7 +6637,7 @@ void QCC_PR_ParseAsm(void) } } else - { + { if (pr_opcodes[op].type_a != &type_void) a = QCC_PR_ParseValue(pr_classtype, false); else @@ -6646,7 +6653,7 @@ void QCC_PR_ParseAsm(void) QCC_PR_Statement3(&pr_opcodes[op], a, b, c, true); } - + QCC_PR_Expect(";"); return; } @@ -6879,7 +6886,7 @@ void QCC_CheckForDeadAndMissingReturns(int first, int last, int rettype) if (statements[last-1].op == OP_DONE) last--; //don't want the done - + if (rettype != ev_void) if (statements[last-1].op != OP_RETURN) { @@ -7145,7 +7152,7 @@ void QCC_Marshal_Locals(int first, int laststatement) locals_start = MAX_REGS; locals_end = newofs; - + optres_locals_marshalling+=newofs-MAX_REGS; for (local = pr.localvars; local; local = local->nextlocal) @@ -7196,9 +7203,9 @@ void QCC_WriteAsmFunction(QCC_def_t *sc, unsigned int firststatement, gofs_t fir break; } if (param) - fprintf(asmfile, "%s %s", TypeName(type), param->name); + fprintf(asmfile, "%s %s /* at %d */", TypeName(type), param->name, o); else - fprintf(asmfile, "%s", TypeName(type)); + fprintf(asmfile, "%s /* at %d */", TypeName(type), o); o += type->size; } @@ -7311,7 +7318,7 @@ QCC_function_t *QCC_PR_ParseImmediateStatements (QCC_type_t *type) if (type->num_parms < 0) QCC_PR_ParseError (ERR_FUNCTIONWITHVARGS, "QC function with variable arguments and function body"); - + f->builtin = 0; // // define the parms @@ -7514,9 +7521,9 @@ void QCC_PR_ArrayRecurseDivideRegular(QCC_def_t *array, QCC_def_t *index, int mi QCC_def_t *eq; if (min == max || min+1 == max) { - eq = QCC_PR_Statement(pr_opcodes+OP_LT, index, QCC_MakeFloatDef(min+0.5f), NULL); + eq = QCC_PR_Statement(pr_opcodes+OP_LT_F, index, QCC_MakeFloatDef(min+0.5f), NULL); QCC_UnFreeTemp(index); - QCC_FreeTemp(QCC_PR_Statement(pr_opcodes+OP_IFNOT, eq, 0, &st)); + QCC_FreeTemp(QCC_PR_Statement(pr_opcodes+OP_IFNOT_I, eq, 0, &st)); st->b = 2; QCC_PR_Statement(pr_opcodes+OP_RETURN, 0, 0, &st); st->a = array->ofs + min*array->type->size; @@ -7527,9 +7534,9 @@ void QCC_PR_ArrayRecurseDivideRegular(QCC_def_t *array, QCC_def_t *index, int mi if (max-min>4) { - eq = QCC_PR_Statement(pr_opcodes+OP_LT, index, QCC_MakeFloatDef(mid+0.5f), NULL); + eq = QCC_PR_Statement(pr_opcodes+OP_LT_F, index, QCC_MakeFloatDef(mid+0.5f), NULL); QCC_UnFreeTemp(index); - QCC_FreeTemp(QCC_PR_Statement(pr_opcodes+OP_IFNOT, eq, 0, &st)); + QCC_FreeTemp(QCC_PR_Statement(pr_opcodes+OP_IFNOT_I, eq, 0, &st)); } else st = NULL; @@ -7548,9 +7555,9 @@ void QCC_PR_ArrayRecurseDivideUsingVectors(QCC_def_t *array, QCC_def_t *index, i QCC_def_t *eq; if (min == max || min+1 == max) { - eq = QCC_PR_Statement(pr_opcodes+OP_LT, index, QCC_MakeFloatDef(min+0.5f), NULL); + eq = QCC_PR_Statement(pr_opcodes+OP_LT_F, index, QCC_MakeFloatDef(min+0.5f), NULL); QCC_UnFreeTemp(index); - QCC_FreeTemp(QCC_PR_Statement(pr_opcodes+OP_IFNOT, eq, 0, &st)); + QCC_FreeTemp(QCC_PR_Statement(pr_opcodes+OP_IFNOT_I, eq, 0, &st)); st->b = 2; QCC_PR_Statement(pr_opcodes+OP_RETURN, 0, 0, &st); st->a = array->ofs + min*3; @@ -7561,9 +7568,9 @@ void QCC_PR_ArrayRecurseDivideUsingVectors(QCC_def_t *array, QCC_def_t *index, i if (max-min>4) { - eq = QCC_PR_Statement(pr_opcodes+OP_LT, index, QCC_MakeFloatDef(mid+0.5f), NULL); + eq = QCC_PR_Statement(pr_opcodes+OP_LT_F, index, QCC_MakeFloatDef(mid+0.5f), NULL); QCC_UnFreeTemp(index); - QCC_FreeTemp(QCC_PR_Statement(pr_opcodes+OP_IFNOT, eq, 0, &st)); + QCC_FreeTemp(QCC_PR_Statement(pr_opcodes+OP_IFNOT_I, eq, 0, &st)); } else st = NULL; @@ -7599,7 +7606,7 @@ QCC_def_t *QCC_PR_EmitArrayGetVector(QCC_def_t *array) locals_end = numpr_globals; df->locals = locals_end - df->parm_start; QCC_PR_Statement3(pr_opcodes+OP_DIV_F, index, QCC_MakeFloatDef(3), temp, false); - QCC_PR_Statement3(pr_opcodes+OP_BITAND, temp, temp, temp, false);//round down to int + QCC_PR_Statement3(pr_opcodes+OP_BITAND_F, temp, temp, temp, false);//round down to int QCC_PR_ArrayRecurseDivideUsingVectors(array, temp, 0, (array->arraysize+2)/3); //round up @@ -7653,7 +7660,7 @@ void QCC_PR_EmitArrayGetFunction(QCC_def_t *scope, char *arrayname) if (fasttrackpossible) { - QCC_PR_Statement(pr_opcodes+OP_IFNOT, fasttrackpossible, NULL, &st); + QCC_PR_Statement(pr_opcodes+OP_IFNOT_I, 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. @@ -7679,15 +7686,15 @@ void QCC_PR_EmitArrayGetFunction(QCC_def_t *scope, char *arrayname) div3 = QCC_PR_GetDef(type_float, "div3___", def, true, 1, false); intdiv3 = QCC_PR_GetDef(type_float, "intdiv3___", def, true, 1, false); - eq = QCC_PR_Statement(pr_opcodes+OP_GE, index, QCC_MakeFloatDef((float)def->arraysize), NULL); //escape clause - should call some sort of error function instead.. that'd rule! - QCC_FreeTemp(QCC_PR_Statement(pr_opcodes+OP_IFNOT, eq, 0, &st)); + eq = QCC_PR_Statement(pr_opcodes+OP_GE_F, index, QCC_MakeFloatDef((float)def->arraysize), NULL); //escape clause - should call some sort of error function instead.. that'd rule! + QCC_FreeTemp(QCC_PR_Statement(pr_opcodes+OP_IFNOT_I, eq, 0, &st)); st->b = 2; QCC_PR_Statement(pr_opcodes+OP_RETURN, QCC_MakeFloatDef(0), 0, &st); div3->references++; - QCC_PR_Statement3(pr_opcodes+OP_BITAND, index, index, index, false); + QCC_PR_Statement3(pr_opcodes+OP_BITAND_F, index, index, index, false); QCC_PR_Statement3(pr_opcodes+OP_DIV_F, index, QCC_MakeFloatDef(3), div3, false); - QCC_PR_Statement3(pr_opcodes+OP_BITAND, div3, div3, intdiv3, false); + QCC_PR_Statement3(pr_opcodes+OP_BITAND_F, div3, div3, intdiv3, false); QCC_PR_Statement3(pr_opcodes+OP_STORE_F, index, &def_parms[0], NULL, false); QCC_PR_Statement3(pr_opcodes+OP_CALL1, vectortrick, NULL, NULL, false); @@ -7701,20 +7708,20 @@ void QCC_PR_EmitArrayGetFunction(QCC_def_t *scope, char *arrayname) QCC_PR_Statement3(pr_opcodes+OP_SUB_F, index, div3, index, false); QCC_FreeTemp(div3); - eq = QCC_PR_Statement(pr_opcodes+OP_LT, index, QCC_MakeFloatDef(0+0.5f), NULL); - QCC_FreeTemp(QCC_PR_Statement(pr_opcodes+OP_IFNOT, eq, 0, &st)); + eq = QCC_PR_Statement(pr_opcodes+OP_LT_F, index, QCC_MakeFloatDef(0+0.5f), NULL); + QCC_FreeTemp(QCC_PR_Statement(pr_opcodes+OP_IFNOT_I, eq, 0, &st)); st->b = 2; QCC_PR_Statement(pr_opcodes+OP_RETURN, 0, 0, &st); st->a = ret->ofs + 0; - eq = QCC_PR_Statement(pr_opcodes+OP_LT, index, QCC_MakeFloatDef(1+0.5f), NULL); - QCC_FreeTemp(QCC_PR_Statement(pr_opcodes+OP_IFNOT, eq, 0, &st)); + eq = QCC_PR_Statement(pr_opcodes+OP_LT_F, index, QCC_MakeFloatDef(1+0.5f), NULL); + QCC_FreeTemp(QCC_PR_Statement(pr_opcodes+OP_IFNOT_I, eq, 0, &st)); st->b = 2; QCC_PR_Statement(pr_opcodes+OP_RETURN, 0, 0, &st); st->a = ret->ofs + 1; - eq = QCC_PR_Statement(pr_opcodes+OP_LT, index, QCC_MakeFloatDef(2+0.5), NULL); - QCC_FreeTemp(QCC_PR_Statement(pr_opcodes+OP_IFNOT, eq, 0, &st)); + eq = QCC_PR_Statement(pr_opcodes+OP_LT_F, index, QCC_MakeFloatDef(2+0.5), NULL); + QCC_FreeTemp(QCC_PR_Statement(pr_opcodes+OP_IFNOT_I, eq, 0, &st)); st->b = 2; QCC_PR_Statement(pr_opcodes+OP_RETURN, 0, 0, &st); st->a = ret->ofs + 2; @@ -7723,7 +7730,7 @@ void QCC_PR_EmitArrayGetFunction(QCC_def_t *scope, char *arrayname) } else { - QCC_PR_Statement3(pr_opcodes+OP_BITAND, index, index, index, false); + QCC_PR_Statement3(pr_opcodes+OP_BITAND_F, index, index, index, false); QCC_PR_ArrayRecurseDivideRegular(def, index, 0, def->arraysize); } @@ -7748,7 +7755,7 @@ void QCC_PR_ArraySetRecurseDivide(QCC_def_t *array, QCC_def_t *index, QCC_def_t { eq = QCC_PR_Statement(pr_opcodes+OP_EQ_F, index, QCC_MakeFloatDef((float)min), NULL); QCC_UnFreeTemp(index); - QCC_FreeTemp(QCC_PR_Statement(pr_opcodes+OP_IFNOT, eq, 0, &st)); + QCC_FreeTemp(QCC_PR_Statement(pr_opcodes+OP_IFNOT_I, eq, 0, &st)); st->b = 3; if (array->type->size == 3) QCC_PR_Statement(pr_opcodes+OP_STORE_V, value, array, &st); @@ -7763,9 +7770,9 @@ void QCC_PR_ArraySetRecurseDivide(QCC_def_t *array, QCC_def_t *index, QCC_def_t if (max-min>4) { - eq = QCC_PR_Statement(pr_opcodes+OP_LT, index, QCC_MakeFloatDef((float)mid), NULL); + eq = QCC_PR_Statement(pr_opcodes+OP_LT_F, index, QCC_MakeFloatDef((float)mid), NULL); QCC_UnFreeTemp(index); - QCC_FreeTemp(QCC_PR_Statement(pr_opcodes+OP_IFNOT, eq, 0, &st)); + QCC_FreeTemp(QCC_PR_Statement(pr_opcodes+OP_IFNOT_I, eq, 0, &st)); } else st = NULL; @@ -7812,7 +7819,7 @@ void QCC_PR_EmitArraySetFunction(QCC_def_t *scope, char *arrayname) { QCC_dstatement_t *st; - QCC_PR_Statement(pr_opcodes+OP_IFNOT, fasttrackpossible, NULL, &st); + QCC_PR_Statement(pr_opcodes+OP_IFNOT_I, 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, true); //address stuff is integer based, but standard qc (which this accelerates in supported engines) only supports floats @@ -7830,7 +7837,7 @@ void QCC_PR_EmitArraySetFunction(QCC_def_t *scope, char *arrayname) st->b = &statements[numstatements] - st; } - QCC_PR_Statement3(pr_opcodes+OP_BITAND, index, index, index, false); + QCC_PR_Statement3(pr_opcodes+OP_BITAND_F, index, index, index, false); QCC_PR_ArraySetRecurseDivide(def, index, value, 0, def->arraysize); QCC_PR_Statement(pr_opcodes+OP_DONE, 0, 0, NULL); @@ -7909,7 +7916,7 @@ QCC_def_t *QCC_PR_DummyDef(QCC_type_t *type, char *name, QCC_def_t *scope, int a strcpy (def->name, newname); def->type = type; - def->scope = scope; + def->scope = scope; def->saved = saved; // if (arraysize>1) @@ -7927,7 +7934,7 @@ QCC_def_t *QCC_PR_DummyDef(QCC_type_t *type, char *name, QCC_def_t *scope, int a { int partnum; QCC_type_t *parttype; - parttype = type->param; + parttype = type->param; for (partnum = 0; partnum < type->num_parms; partnum++) { switch (parttype->type) @@ -7947,7 +7954,7 @@ QCC_def_t *QCC_PR_DummyDef(QCC_type_t *type, char *name, QCC_def_t *scope, int a case ev_float: case ev_string: case ev_entity: - case ev_field: + case ev_field: case ev_pointer: case ev_integer: case ev_struct: @@ -7965,7 +7972,7 @@ QCC_def_t *QCC_PR_DummyDef(QCC_type_t *type, char *name, QCC_def_t *scope, int a break; } parttype=parttype->next; - } + } } else if (type->type == ev_vector) { //do the vector thing. @@ -7995,7 +8002,7 @@ QCC_def_t *QCC_PR_DummyDef(QCC_type_t *type, char *name, QCC_def_t *scope, int a { if (!pHash_Get(&globalstable, "end_sys_fields")) first->references++; //anything above needs to be left in, and so warning about not using it is just going to pee people off. - if (arraysize <= 1) + if (arraysize <= 1 && first->type->type != ev_field) first->constant = false; if (scope) pHash_Add(&localstable, first->name, first, qccHunkAlloc(sizeof(bucket_t))); @@ -8003,7 +8010,7 @@ QCC_def_t *QCC_PR_DummyDef(QCC_type_t *type, char *name, QCC_def_t *scope, int a pHash_Add(&globalstable, first->name, first, qccHunkAlloc(sizeof(bucket_t))); if (!scope && asmfile) - fprintf(asmfile, "%s %s;\n", TypeName(first->type), first->name); + fprintf(asmfile, "%s %s; /* at %d */\n", TypeName(first->type), first->name, first->ofs); } return first; @@ -8255,11 +8262,11 @@ QCC_def_t *QCC_PR_DummyFieldDef(QCC_type_t *type, char *name, QCC_def_t *scope, strcpy (def->name, newname); def->type = type; - def->scope = scope; + def->scope = scope; def->ofs = QCC_GetFreeOffsetSpace(1); ((int *)qcc_pr_globals)[def->ofs] = *fieldofs; - *fieldofs++; + fieldofs++; if (!first) first = def; } @@ -8340,7 +8347,7 @@ QCC_def_t *QCC_PR_DummyFieldDef(QCC_type_t *type, char *name, QCC_def_t *scope, type = parttype; parttype=parttype->next; - } + } } } @@ -8371,14 +8378,13 @@ void QCC_PR_ParseDefs (char *classname) QCC_def_t *def, *d; QCC_function_t *f; QCC_dfunction_t *df; - int i; - extern pbool defaultstatic; + int i = 0; // warning: ‘iÂ’ may be used uninitialized in this function pbool shared=false; pbool isstatic=defaultstatic; pbool externfnc=false; pbool isconstant = false; pbool isvar = false; - pbool noref = false; + pbool noref = defaultnoref; pbool nosave = false; pbool allocatenew = true; pbool inlinefunction = false; @@ -8425,6 +8431,8 @@ void QCC_PR_ParseDefs (char *classname) if (QCC_PR_CheckToken("}")) break; QCC_PR_Expect(","); + if (QCC_PR_CheckToken("}")) + break; // accept trailing comma } } else @@ -8465,6 +8473,8 @@ void QCC_PR_ParseDefs (char *classname) if (QCC_PR_CheckToken("}")) break; QCC_PR_Expect(","); + if (QCC_PR_CheckToken("}")) + break; // accept trailing comma } } QCC_PR_Expect(";"); @@ -8904,7 +8914,7 @@ void QCC_PR_ParseDefs (char *classname) } //check for an array - + if ( QCC_PR_CheckToken ("[") ) { char *oldprfile = pr_file_p; @@ -9018,7 +9028,7 @@ void QCC_PR_ParseDefs (char *classname) def->references++; if (!def->initialized && shared) //shared count as initiialised - { + { def->shared = shared; def->initialized = true; } @@ -9109,13 +9119,14 @@ void QCC_PR_ParseDefs (char *classname) continue; } -#pragma message("this is experimental") if (pr_scope) { d = QCC_PR_Expression(TOP_PRIORITY, EXPR_DISALLOW_COMMA); + if (typecmp(def->type, d->type)) + QCC_PR_ParseError (ERR_BADIMMEDIATETYPE, "wrong immediate type for %s", name); if (d->constant) { - for (i = 0; i < d->type->size; i++) + for (i = 0; (unsigned)i < def->type->size; i++) G_INT(def->ofs+i) = G_INT(d->ofs+i); def->constant = !isvar; def->initialized = 1; @@ -9162,14 +9173,14 @@ void QCC_PR_ParseDefs (char *classname) } continue; } - + else if (type->type == ev_function) { if (isvar) def->constant = false; else def->constant = true; - if (QCC_PR_CheckImmediate("0")) + if (QCC_PR_CheckImmediate("0") || QCC_PR_CheckImmediate("0i")) { def->constant = 0; def->initialized = 1; //fake function @@ -9269,7 +9280,7 @@ void QCC_PR_ParseDefs (char *classname) { df->parm_size[i] = parm->size; } - + continue; } @@ -9284,7 +9295,7 @@ void QCC_PR_ParseDefs (char *classname) def->constant = false; // if (constant) // QCC_PR_ParseError("const used on a struct isn't useful"); - + //FIXME: should do this recursivly QCC_PR_Expect("{"); for (arraypart = 0; arraypart < arraysize; arraypart++) @@ -9383,7 +9394,7 @@ void QCC_PR_ParseDefs (char *classname) d->ofs = def->ofs+arraypart*type->size+parttype->ofs+i; */ - G_INT(def->ofs+arraypart*type->size+parttype->ofs+i) = 0; + G_INT(def->ofs+arraypart*type->size+parttype->ofs+i) = 0; } QCC_PR_Expect("}"); } @@ -9431,7 +9442,7 @@ void QCC_PR_ParseDefs (char *classname) } break; default: - QCC_PR_ParseError(ERR_TYPEINVALIDINSTRUCT, "type %i not valid in a struct", parttype->type); + QCC_PR_ParseError(ERR_TYPEINVALIDINSTRUCT, "type %i not valid in a struct", parttype->type); QCC_PR_Lex(); break; } @@ -9699,13 +9710,20 @@ void QCC_PR_ParseDefs (char *classname) def->initialized = 1; } - if (isconstant && type->type == ev_field) - def->constant = 2; //special flag on fields, 2, makes the pointer obtained from them also constant. + if (type->type == ev_field) + { + if (isconstant) + def->constant = 2; //special flag on fields, 2, makes the pointer obtained from them also constant. + else if (isvar) + def->constant = 0; + else + def->constant = 1; + } else def->constant = isconstant; } - + } while (QCC_PR_CheckToken (",")); if (type->type == ev_function) @@ -9725,7 +9743,7 @@ compiles the 0 terminated text, adding defintions to the pr structure ============ */ pbool QCC_PR_CompileFile (char *string, char *filename) -{ +{ jmp_buf oldjb; if (!pr.memory) QCC_Error (ERR_INTERNAL, "PR_CompileFile: Didn't clear"); @@ -9733,7 +9751,7 @@ pbool QCC_PR_CompileFile (char *string, char *filename) QCC_PR_ClearGrabMacros (); // clear the frame macros compilingfile = filename; - + if (opt_filenames) { optres_filenames += strlen(filename); @@ -9782,11 +9800,11 @@ pbool QCC_PR_CompileFile (char *string, char *filename) } pr_scope = NULL; // outside all functions - + QCC_PR_ParseDefs (NULL); } memcpy(&pr_parse_abort, &oldjb, sizeof(oldjb)); - + return (pr_error_count == 0); } diff --git a/misc/source/fteqcc-src/qcc_pr_lex.c b/misc/source/fteqcc-src/qcc_pr_lex.c index 286da96f..9bdd11c4 100644 --- a/misc/source/fteqcc-src/qcc_pr_lex.c +++ b/misc/source/fteqcc-src/qcc_pr_lex.c @@ -6,6 +6,24 @@ #endif #include "time.h" +// I put the following here to resolve "undefined reference to `__imp__vsnprintf'" with MinGW64 ~ Moodles +#ifdef __MINGW64__ +#ifndef QCCONLY + #if (_MSC_VER >= 1400) + //with MSVC 8, use MS extensions + #define snprintf linuxlike_snprintf_vc8 + int VARGS linuxlike_snprintf_vc8(char *buffer, int size, const char *format, ...) LIKEPRINTF(3); + #define vsnprintf(a, b, c, d) vsnprintf_s(a, b, _TRUNCATE, c, d) + #else + //msvc crap + #define snprintf linuxlike_snprintf + int VARGS linuxlike_snprintf(char *buffer, int size, const char *format, ...) LIKEPRINTF(3); + #define vsnprintf linuxlike_vsnprintf + int VARGS linuxlike_vsnprintf(char *buffer, int size, const char *format, va_list argptr); + #endif +#endif +#endif + #define MEMBERFIELDNAME "__m%s" #define STRCMP(s1,s2) (((*s1)!=(*s2)) || strcmp(s1+1,s2+1)) //saves about 2-6 out of 120 - expansion of idea from fastqcc @@ -159,8 +177,7 @@ extern char qccmsourcedir[]; //also meant to include it. void QCC_FindBestInclude(char *newfile, char *currentfile, char *rootpath) { - char fullname[10248]; - char *stripfrom; + char fullname[1024]; int doubledots; char *end = fullname; @@ -169,6 +186,7 @@ void QCC_FindBestInclude(char *newfile, char *currentfile, char *rootpath) return; doubledots = 0; + /*count how far up we need to go*/ while(!strncmp(newfile, "../", 3) || !strncmp(newfile, "..\\", 3)) { newfile+=3; @@ -177,31 +195,37 @@ void QCC_FindBestInclude(char *newfile, char *currentfile, char *rootpath) currentfile += strlen(rootpath); //could this be bad? - for(stripfrom = currentfile+strlen(currentfile)-1; stripfrom>currentfile; stripfrom--) + strcpy(fullname, rootpath); + end = fullname+strlen(end); + if (*fullname && end[-1] != '/') + { + strcpy(end, "/"); + end = end+strlen(end); + } + strcpy(end, currentfile); + end = end+strlen(end); + + while (end > fullname) { - if (*stripfrom == '/' || *stripfrom == '\\') + end--; + /*stop at the slash, unless we're meant to go further*/ + if (*end == '/' || *end == '\\') { - if (doubledots>0) - doubledots--; - else + if (!doubledots) { - stripfrom++; + end++; break; } + doubledots--; } } - strcpy(end, rootpath); end = end+strlen(end); - if (*fullname && end[-1] != '/') - { - strcpy(end, "/"); - end = end+strlen(end); - } - strncpy(end, currentfile, stripfrom - currentfile); end += stripfrom - currentfile; *end = '\0'; + strcpy(end, newfile); QCC_Include(fullname); } +pbool defaultnoref; pbool defaultstatic; int ForcedCRC; int QCC_PR_LexInteger (void); @@ -212,10 +236,10 @@ pbool QCC_PR_SimpleGetToken (void); int ParsePrecompilerIf(void) { CompilerConstant_t *c; - int eval; - char *start = pr_file_p; + int eval = 0; + //char *start = pr_file_p; //warning: unused variable âstartâ if (!QCC_PR_SimpleGetToken()) - { + { if (*pr_file_p == '(') { eval = ParsePrecompilerIf(); @@ -364,7 +388,7 @@ pbool QCC_PR_Precompiler(void) eval = true; if (ifmode == 1) - eval = eval?false:true; + eval = eval?false:true; } while(*pr_file_p != '\n' && *pr_file_p != '\0') //read on until the end of the line @@ -469,11 +493,11 @@ pbool QCC_PR_Precompiler(void) } } else if (!strncmp(directive, "endif", 5)) - { + { while(*pr_file_p != '\n' && *pr_file_p != '\0') //read on until the end of the line { pr_file_p++; - } + } if (ifs <= 0) QCC_PR_ParseError(ERR_NOPRECOMPILERIF, "unmatched #endif"); else @@ -485,9 +509,9 @@ pbool QCC_PR_Precompiler(void) return true; } else if (!strncmp(directive, "error", 5)) - { + { pr_file_p = directive+5; - for (a = 0; a < 1023 && pr_file_p[a] != '\n' && pr_file_p[a] != '\0'; a++) + for (a = 0; a < sizeof(msg)-1 && pr_file_p[a] != '\n' && pr_file_p[a] != '\0'; a++) msg[a] = pr_file_p[a]; msg[a-1] = '\0'; @@ -500,7 +524,7 @@ pbool QCC_PR_Precompiler(void) QCC_PR_ParseError(ERR_HASHERROR, "#Error: %s", msg); } else if (!strncmp(directive, "warning", 7)) - { + { pr_file_p = directive+7; for (a = 0; a < 1023 && pr_file_p[a] != '\n' && pr_file_p[a] != '\0'; a++) msg[a] = pr_file_p[a]; @@ -515,7 +539,7 @@ pbool QCC_PR_Precompiler(void) QCC_PR_ParseWarning(WARN_PRECOMPILERMESSAGE, "#warning: %s", msg); } else if (!strncmp(directive, "message", 7)) - { + { pr_file_p = directive+7; for (a = 0; a < 1023 && pr_file_p[a] != '\n' && pr_file_p[a] != '\0'; a++) msg[a] = pr_file_p[a]; @@ -532,7 +556,7 @@ pbool QCC_PR_Precompiler(void) else if (!strncmp(directive, "copyright", 9)) { pr_file_p = directive+9; - for (a = 0; a < 1023 && pr_file_p[a] != '\n' && pr_file_p[a] != '\0'; a++) + for (a = 0; a < sizeof(msg)-1 && pr_file_p[a] != '\n' && pr_file_p[a] != '\0'; a++) msg[a] = pr_file_p[a]; msg[a-1] = '\0'; @@ -552,14 +576,14 @@ pbool QCC_PR_Precompiler(void) pr_file_p=directive+4; if (!strncmp(pr_file_p, "id", 2)) pr_file_p+=3; - else + else { - ifmode = QCC_PR_LexInteger(); + ifmode = QCC_PR_LexInteger(); if (ifmode == 0) ifmode = 1; pr_file_p++; } - for (a = 0; a < 1023 && pr_file_p[a] != '\n' && pr_file_p[a] != '\0'; a++) + for (a = 0; a < sizeof(msg)-1 && pr_file_p[a] != '\n' && pr_file_p[a] != '\0'; a++) msg[a] = pr_file_p[a]; msg[a-1] = '\0'; @@ -574,17 +598,17 @@ pbool QCC_PR_Precompiler(void) else if (ifmode <= 5) strcpy(QCC_Packname[ifmode-1], msg); else - QCC_PR_ParseError(ERR_TOOMANYPACKFILES, "No more than 5 packs are allowed"); + QCC_PR_ParseError(ERR_TOOMANYPACKFILES, "No more than 5 packs are allowed"); } else if (!strncmp(directive, "forcecrc", 8)) - { + { pr_file_p=directive+8; - ForcedCRC = QCC_PR_LexInteger(); + ForcedCRC = QCC_PR_LexInteger(); pr_file_p++; - - for (a = 0; a < 1023 && pr_file_p[a] != '\n' && pr_file_p[a] != '\0'; a++) + + for (a = 0; a < sizeof(msg)-1 && pr_file_p[a] != '\n' && pr_file_p[a] != '\0'; a++) msg[a] = pr_file_p[a]; msg[a-1] = '\0'; @@ -592,7 +616,7 @@ pbool QCC_PR_Precompiler(void) while(*pr_file_p != '\n' && *pr_file_p != '\0') //read on until the end of the line { pr_file_p++; - } + } } else if (!strncmp(directive, "includelist", 11)) { @@ -623,7 +647,7 @@ pbool QCC_PR_Precompiler(void) if (*pr_file_p == '\r') pr_file_p++; - for (a = 0; a < 1023 && pr_file_p[a] != '\n' && pr_file_p[a] != '\0'; a++) + for (a = 0; a < sizeof(msg)-1 && pr_file_p[a] != '\n' && pr_file_p[a] != '\0'; a++) msg[a] = pr_file_p[a]; msg[a-1] = '\0'; @@ -633,7 +657,7 @@ pbool QCC_PR_Precompiler(void) pr_file_p++; } } - + while(*pr_file_p != '\n' && *pr_file_p != '\0') //read on until the end of the line { pr_file_p++; @@ -664,7 +688,7 @@ pbool QCC_PR_Precompiler(void) { if (*pr_file_p == '\n') { - QCC_PR_ParseError(0, "#include continued over line boundy\n"); + QCC_PR_ParseError(0, "#include continued over line boundry\n"); break; } msg[a++] = *pr_file_p; @@ -686,7 +710,7 @@ pbool QCC_PR_Precompiler(void) } } else if (!strncmp(directive, "datafile", 8)) - { + { pr_file_p=directive+8; while(*pr_file_p <= ' ') @@ -698,7 +722,7 @@ pbool QCC_PR_Precompiler(void) pr_file_p++; - for (a = 0; a < 1023 && pr_file_p[a] != '\n' && pr_file_p[a] != '\0'; a++) + for (a = 0; a < sizeof(msg)-1 && pr_file_p[a] != '\n' && pr_file_p[a] != '\0'; a++) msg[a] = pr_file_p[a]; msg[a-1] = '\0'; @@ -721,8 +745,8 @@ pbool QCC_PR_Precompiler(void) printf("Outputfile: %s\n", destfile); pr_file_p++; - - for (a = 0; a < 1023 && pr_file_p[a] != '\n' && pr_file_p[a] != '\0'; a++) + + for (a = 0; a < sizeof(msg)-1 && pr_file_p[a] != '\n' && pr_file_p[a] != '\0'; a++) msg[a] = pr_file_p[a]; msg[a-1] = '\0'; @@ -750,7 +774,7 @@ pbool QCC_PR_Precompiler(void) } msg[a++] = *pr_file_p; } - + msg[a] = '\0'; { char *end; @@ -799,6 +823,10 @@ pbool QCC_PR_Precompiler(void) { ForcedCRC = atoi(msg); } + else if (!strncmp(qcc_token, "noref", 8)) + { + defaultnoref = atoi(msg); + } else if (!strncmp(qcc_token, "defaultstatic", 13)) { defaultstatic = atoi(msg); @@ -807,7 +835,7 @@ pbool QCC_PR_Precompiler(void) { #define MAXSOURCEFILESLIST 8 extern char sourcefileslist[MAXSOURCEFILESLIST][1024]; - extern int currentsourcefile; + //extern int currentsourcefile; // warning: unused variable âcurrentsourcefileâ extern int numsourcefiles; int i; @@ -845,6 +873,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); } @@ -863,7 +893,7 @@ pbool QCC_PR_Precompiler(void) #ifndef QCCONLY p=0; - s2 = qcc_token; + s2 = qcc_token; if (!strncmp(s2, "./", 2)) s2+=2; else @@ -1014,7 +1044,7 @@ void QCC_PR_LexString (void) int c; int len; char tmpbuf[2048]; - + char *text; char *oldf; int oldline; @@ -1083,12 +1113,12 @@ void QCC_PR_LexString (void) pr_file_p = oldf-1; QCC_PR_LexWhitespace(); if (*pr_file_p != '\"') //annother string - break; + break; } QCC_PR_LexWhitespace(); - text = pr_file_p; - + text = pr_file_p; + } while (1); strcpy(pr_token, tmpbuf); @@ -1106,7 +1136,7 @@ void QCC_PR_LexString (void) char *end, *cnst; int texttype=0; - + len = 0; pr_file_p++; do @@ -1231,7 +1261,7 @@ void QCC_PR_LexString (void) pr_token[len] = 0; pr_token_type = tt_immediate; pr_immediate_type = type_string; - strcpy (pr_immediate_string, pr_token); + strcpy (pr_immediate_string, pr_token); return; } else if (c == '#') @@ -1308,7 +1338,7 @@ int QCC_PR_LexInteger (void) { int c; int len; - + len = 0; c = *pr_file_p; if (pr_file_p[0] == '0' && pr_file_p[1] == 'x') @@ -1358,7 +1388,7 @@ void QCC_PR_LexNumber (void) base = 10; while((c = *pr_file_p)) - { + { if (c >= '0' && c <= '9') { pr_token[tokenlen++] = c; @@ -1395,7 +1425,7 @@ void QCC_PR_LexNumber (void) break; } else - { + { break; } pr_file_p++; @@ -1447,7 +1477,7 @@ float QCC_PR_LexFloat (void) { int c; int len; - + len = 0; c = *pr_file_p; do @@ -1471,7 +1501,7 @@ Parses a single quoted vector void QCC_PR_LexVector (void) { int i; - + pr_file_p++; if (*pr_file_p == '\\') @@ -1549,7 +1579,7 @@ void QCC_PR_LexName (void) { int c; int len; - + len = 0; c = *pr_file_p; do @@ -1558,11 +1588,11 @@ void QCC_PR_LexName (void) len++; pr_file_p++; c = *pr_file_p; - } while ( (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_' - || (c >= '0' && c <= '9')); + } while ( (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_' + || (c >= '0' && c <= '9')); pr_token[len] = 0; - pr_token_type = tt_name; + pr_token_type = tt_name; } /* @@ -1575,9 +1605,9 @@ void QCC_PR_LexPunctuation (void) int i; int len; char *p; - + pr_token_type = tt_punct; - + for (i=0 ; (p = pr_punctuation[i]) != NULL ; i++) { len = strlen(p); @@ -1592,11 +1622,11 @@ void QCC_PR_LexPunctuation (void) return; } } - + QCC_PR_ParseError (ERR_UNKNOWNPUCTUATION, "Unknown punctuation"); } - + /* ============== PR_LexWhitespace @@ -1605,7 +1635,7 @@ PR_LexWhitespace void QCC_PR_LexWhitespace (void) { int c; - + while (1) { // skip whitespace @@ -1625,7 +1655,7 @@ void QCC_PR_LexWhitespace (void) pr_file_p++; } } - + // skip // comments if (c=='/' && pr_file_p[1] == '/') { @@ -1637,7 +1667,7 @@ void QCC_PR_LexWhitespace (void) QCC_PR_NewLine(false); continue; } - + // skip /* */ comments if (c=='/' && pr_file_p[1] == '*') { @@ -1658,7 +1688,7 @@ void QCC_PR_LexWhitespace (void) pr_file_p+=2; continue; } - + break; // a real character has been found } } @@ -1834,7 +1864,7 @@ Deals with counting sequence numbers and replacing frame macros ============== */ void QCC_PR_LexGrab (void) -{ +{ pr_file_p++; // skip the $ // if (!QCC_PR_SimpleGetToken ()) // QCC_PR_ParseError ("hanging $"); @@ -1843,7 +1873,7 @@ void QCC_PR_LexGrab (void) QCC_PR_LexMacroName(); if (!*pr_token) QCC_PR_ParseError (ERR_BADFRAMEMACRO, "hanging $"); - + // check for $frame if (!STRCMP (pr_token, "frame") || !STRCMP (pr_token, "framesave")) { @@ -1873,7 +1903,7 @@ void QCC_PR_LexGrab (void) { QCC_PR_LexMacroName (); pr_macrovalue = atoi(pr_token); - + QCC_PR_Lex (); } else if (!STRCMP (pr_token, "framerestore")) @@ -1881,7 +1911,7 @@ void QCC_PR_LexGrab (void) QCC_PR_LexMacroName (); QCC_PR_ExpandMacro(); pr_macrovalue = (int)pr_immediate._float; - + QCC_PR_Lex (); } else if (!STRCMP (pr_token, "modelname")) @@ -1900,7 +1930,7 @@ void QCC_PR_LexGrab (void) pr_macrovalue = i; else i = 0; - + QCC_PR_Lex (); } // look for a frame name macro @@ -1924,38 +1954,6 @@ pbool QCC_PR_UndefineName(char *name) Hash_Remove(&compconstantstable, name); return true; - /* - a = c-CompilerConstant; -// for (a = 0; a < numCompilerConstants; a++) - { -// if (!STRCMP(name, CompilerConstant[a].name)) - { - memmove(&CompilerConstant[a], &CompilerConstant[a+1], sizeof(CompilerConstant_t) * (numCompilerConstants-a)); - numCompilerConstants--; - - - - - if (!STRCMP(name, "OP_NODUP")) - qccop_noduplicatestrings = false; - - if (!STRCMP(name, "OP_COMP_ALL")) //group - { - QCC_PR_UndefineName("OP_COMP_STATEMENTS"); - QCC_PR_UndefineName("OP_COMP_DEFS"); - QCC_PR_UndefineName("OP_COMP_FIELDS"); - QCC_PR_UndefineName("OP_COMP_FUNCTIONS"); - QCC_PR_UndefineName("OP_COMP_STRINGS"); - QCC_PR_UndefineName("OP_COMP_GLOBALS"); - QCC_PR_UndefineName("OP_COMP_LINES"); - QCC_PR_UndefineName("OP_COMP_TYPES"); - } - - return true; - } - } -// return false; -*/ } CompilerConstant_t *QCC_PR_DefineName(char *name) @@ -1967,10 +1965,10 @@ CompilerConstant_t *QCC_PR_DefineName(char *name) // QCC_PR_ParseError("Too many compiler constants - %i >= %i", numCompilerConstants, MAX_CONSTANTS); if (strlen(name) >= MAXCONSTANTLENGTH || !*name) - QCC_PR_ParseError(ERR_CONSTANTTOOLONG, "Compiler constant name length is too long or short"); - + QCC_PR_ParseError(ERR_NAMETOOLONG, "Compiler constant name length is too long or short"); + cnst = pHash_Get(&compconstantstable, name); - if (cnst ) + if (cnst) { QCC_PR_ParseWarning(WARN_DUPLICATEDEFINITION, "Duplicate definition for Precompiler constant %s", name); Hash_Remove(&compconstantstable, name); @@ -1982,57 +1980,12 @@ CompilerConstant_t *QCC_PR_DefineName(char *name) cnst->numparams = 0; strcpy(cnst->name, name); cnst->namelen = strlen(name); - *cnst->value = '\0'; + cnst->value = cnst->name + strlen(cnst->name); for (i = 0; i < MAXCONSTANTPARAMS; i++) cnst->params[i][0] = '\0'; pHash_Add(&compconstantstable, cnst->name, cnst, qccHunkAlloc(sizeof(bucket_t))); - if (!STRCMP(name, "OP_NODUP")) - opt_noduplicatestrings = true; - - - if (!STRCMP(name, "OP_TIME")) //group - optimize for a fast compiler - { - QCC_PR_UndefineName("OP_SIZE"); - QCC_PR_UndefineName("OP_SPEED"); - - QCC_PR_UndefineName("OP_NODUP"); - QCC_PR_UndefineName("OP_COMP_ALL"); - } - - if (!STRCMP(name, "OP_SPEED")) //group - optimize run speed - { - QCC_PR_UndefineName("OP_SIZE"); - QCC_PR_UndefineName("OP_TIME"); - -// QCC_PR_UndefineName("OP_NODUP"); - QCC_PR_UndefineName("OP_COMP_ALL"); - } - - if (!STRCMP(name, "OP_SIZE")) //group - produce small output. - { - QCC_PR_UndefineName("OP_SPEED"); - QCC_PR_UndefineName("OP_TIME"); - - QCC_PR_DefineName("OP_NODUP"); - QCC_PR_DefineName("OP_COMP_ALL"); - } - - if (!STRCMP(name, "OP_COMP_ALL")) //group - compress the output - { - QCC_PR_DefineName("OP_COMP_STATEMENTS"); - QCC_PR_DefineName("OP_COMP_DEFS"); - QCC_PR_DefineName("OP_COMP_FIELDS"); - QCC_PR_DefineName("OP_COMP_FUNCTIONS"); - QCC_PR_DefineName("OP_COMP_STRINGS"); - QCC_PR_DefineName("OP_COMP_GLOBALS"); - QCC_PR_DefineName("OP_COMP_LINES"); - QCC_PR_DefineName("OP_COMP_TYPES"); - } - - - return cnst; } @@ -2048,13 +2001,15 @@ void QCC_PR_ConditionCompilation(void) { char *oldval; char *d; + char *dbuf; + int dbuflen; char *s; int quote=false; CompilerConstant_t *cnst; QCC_PR_SimpleGetToken (); - if (!QCC_PR_SimpleGetToken ()) + if (!QCC_PR_SimpleGetToken ()) QCC_PR_ParseError(ERR_NONAME, "No name defined for compiler constant"); cnst = pHash_Get(&compconstantstable, pr_token); @@ -2098,11 +2053,21 @@ void QCC_PR_ConditionCompilation(void) else cnst->numparams = -1; s = pr_file_p; - d = cnst->value; + d = dbuf = NULL; + dbuflen = 0; while(*s == ' ' || *s == '\t') s++; while(1) { + if ((d - dbuf) + 2 >= dbuflen) + { + int len = d - dbuf; + dbuflen = (len+128) * 2; + dbuf = qccHunkAlloc(dbuflen); + memcpy(dbuf, d - len, len); + d = dbuf + len; + } + if( *s == '\\' ) { // read over a newline if necessary @@ -2116,7 +2081,7 @@ void QCC_PR_ConditionCompilation(void) *d++ = *s++; } } - } + } else if(*s == '\r' || *s == '\n' || *s == '\0') { break; @@ -2132,11 +2097,8 @@ void QCC_PR_ConditionCompilation(void) s++; } *d = '\0'; - d--; - while(*d<= ' ' && d >= cnst->value) - *d-- = '\0'; - if (strlen(cnst->value) >= sizeof(cnst->value)) //this is too late. - QCC_PR_ParseError(ERR_CONSTANTTOOLONG, "Macro %s too long (%i not %i)", cnst->name, strlen(cnst->value), sizeof(cnst->value)); + + cnst->value = dbuf; if (oldval) { //we always warn if it was already defined @@ -2389,7 +2351,7 @@ int QCC_PR_CheakCompConst(void) return true; } if (!strncmp(pr_file_p, "__FILE__", 8)) - { + { static char retbuf[256]; sprintf(retbuf, "\"%s\"", strings + s_file); pr_file_p = retbuf; @@ -2408,7 +2370,7 @@ int QCC_PR_CheakCompConst(void) return true; } if (!strncmp(pr_file_p, "__FUNC__", 8)) - { + { static char retbuf[256]; sprintf(retbuf, "\"%s\"",pr_scope->name); pr_file_p = retbuf; @@ -2431,12 +2393,12 @@ int QCC_PR_CheakCompConst(void) char *QCC_PR_CheakCompConstString(char *def) { char *s; - + CompilerConstant_t *c; c = pHash_Get(&compconstantstable, def); - if (c) + if (c) { s = QCC_PR_CheakCompConstString(c->value); return s; @@ -2448,14 +2410,6 @@ CompilerConstant_t *QCC_PR_CheckCompConstDefined(char *def) { CompilerConstant_t *c = pHash_Get(&compconstantstable, def); return c; - /*int a; - for (a = 0; a < numCompilerConstants; a++) - { - if (!strncmp(def, CompilerConstant[a].name, CompilerConstant[a].namelen+1)) - return &CompilerConstant[a]; - } - return NULL; - */ } //============================================================================ @@ -2472,11 +2426,11 @@ void QCC_PR_Lex (void) int c; pr_token[0] = 0; - + if (!pr_file_p) { if (QCC_PR_UnInclude()) - { + { QCC_PR_Lex(); return; } @@ -2489,7 +2443,7 @@ void QCC_PR_Lex (void) if (!pr_file_p) { if (QCC_PR_UnInclude()) - { + { QCC_PR_Lex(); return; } @@ -2498,11 +2452,11 @@ void QCC_PR_Lex (void) } c = *pr_file_p; - + if (!c) { if (QCC_PR_UnInclude()) - { + { QCC_PR_Lex(); return; } @@ -2563,7 +2517,7 @@ void QCC_PR_Lex (void) return; } - + if ( (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_' ) { if (flag_hashonly || !QCC_PR_CheakCompConst()) //look for a macro. @@ -2572,7 +2526,7 @@ void QCC_PR_Lex (void) if (pr_token_type == tt_eof) { if (QCC_PR_UnInclude()) - { + { QCC_PR_Lex(); return; } @@ -2580,13 +2534,13 @@ void QCC_PR_Lex (void) } return; } - + if (c == '$') { QCC_PR_LexGrab (); return; } - + // parse symbol strings until a non-symbol is found QCC_PR_LexPunctuation (); } @@ -2654,7 +2608,7 @@ void VARGS QCC_PR_ParseError (int errortype, char *error, ...) printf ("%s(%i) : error: %s\n", strings + s_file, pr_source_line, string); else printf ("%s:%i: error: %s\n", strings + s_file, pr_source_line, string); - + longjmp (pr_parse_abort, 1); } void VARGS QCC_PR_ParseErrorPrintDef (int errortype, QCC_def_t *def, char *error, ...) @@ -2676,7 +2630,7 @@ void VARGS QCC_PR_ParseErrorPrintDef (int errortype, QCC_def_t *def, char *error printf ("%s:%i: error: %s\n", strings + s_file, pr_source_line, string); QCC_PR_ParsePrintDef(WARN_ERROR, def); - + longjmp (pr_parse_abort, 1); } void VARGS QCC_PR_ParseWarning (int type, char *error, ...) @@ -2710,6 +2664,30 @@ void VARGS QCC_PR_ParseWarning (int type, char *error, ...) } } +void VARGS QCC_PR_Note (int type, char *file, int line, char *error, ...) +{ + va_list argptr; + char string[1024]; + + if (qccwarningdisabled[type]) + return; + + va_start (argptr,error); + QC_vsnprintf (string,sizeof(string)-1, error,argptr); + va_end (argptr); + + QCC_PR_PrintScope(); + if (file) + { + if (flag_msvcstyle) + printf ("%s(%i) : note: %s\n", file, line, string); + else + printf ("%s:%i: note: %s\n", file, line, string); + } + else + printf ("note: %s\n", string); +} + void VARGS QCC_PR_Warning (int type, char *file, int line, char *error, ...) { va_list argptr; @@ -2770,7 +2748,7 @@ pbool QCC_PR_CheckToken (char *string) if (STRCMP (string, pr_token)) return false; - + QCC_PR_Lex (); return true; } @@ -2782,7 +2760,7 @@ pbool QCC_PR_CheckImmediate (char *string) if (STRCMP (string, pr_token)) return false; - + QCC_PR_Lex (); return true; } @@ -2791,7 +2769,7 @@ pbool QCC_PR_CheckName(char *string) { if (pr_token_type != tt_name) return false; - if (flag_caseinsensative) + if (flag_caseinsensative) { if (stricmp (string, pr_token)) return false; @@ -2809,7 +2787,7 @@ pbool QCC_PR_CheckKeyword(int keywordenabled, char *string) { if (!keywordenabled) return false; - if (flag_caseinsensative) + if (flag_caseinsensative) { if (stricmp (string, pr_token)) return false; @@ -2836,14 +2814,14 @@ char *QCC_PR_ParseName (void) { static char ident[MAX_NAME]; char *ret; - + if (pr_token_type != tt_name) - QCC_PR_ParseError (ERR_NOTANAME, "\"%s\" - not a name", pr_token); + QCC_PR_ParseError (ERR_NOTANAME, "\"%s\" - not a name", pr_token); if (strlen(pr_token) >= MAX_NAME-1) QCC_PR_ParseError (ERR_NAMETOOLONG, "name too long"); strcpy (ident, pr_token); QCC_PR_Lex (); - + ret = qccHunkAlloc(strlen(ident)+1); strcpy(ret, ident); return ret; @@ -2992,7 +2970,7 @@ QCC_type_t *QCC_PR_FindType (QCC_type_t *type) // check = &qcc_typeinfo[t]; if (typecmp(&qcc_typeinfo[t], type)) continue; - + // c2 = check->next; // n2 = type->next; @@ -3142,7 +3120,7 @@ QCC_type_t *QCC_PR_ParseFunctionType (int newtype, QCC_type_t *returntype) strcpy (pr_parm_names[ftype->num_parms], ""); ftype->num_parms++; } while (QCC_PR_CheckToken (",")); - + QCC_PR_Expect (")"); } recursivefunctiontype--; @@ -3219,7 +3197,7 @@ QCC_type_t *QCC_PR_ParseFunctionTypeReacc (int newtype, QCC_type_t *returntype) strcpy (pr_parm_names[ftype->num_parms], name); ftype->num_parms++; } while (QCC_PR_CheckToken (";")); - + QCC_PR_Expect (")"); } recursivefunctiontype--; @@ -3312,7 +3290,7 @@ QCC_type_t *QCC_PR_ParseType (int newtype) { newt = &qcc_typeinfo[i]; break; - } + } } if (newt && forwarddeclaration) @@ -3334,7 +3312,7 @@ QCC_type_t *QCC_PR_ParseType (int newtype) return NULL; } - + if (QCC_PR_CheckToken(":")) { @@ -3450,7 +3428,7 @@ QCC_type_t *QCC_PR_ParseType (int newtype) newt = QCC_PR_NewType("union", ev_union); newt->size=0; QCC_PR_Expect("{"); - + type = NULL; if (QCC_PR_CheckToken(",")) QCC_PR_ParseError(ERR_NOTANAME, "element missing name"); @@ -3477,7 +3455,7 @@ QCC_type_t *QCC_PR_ParseType (int newtype) if (newparm->size > newt->size) newt->size = newparm->size; newt->num_parms++; - + if (type) type->next = newparm; else @@ -3519,7 +3497,7 @@ QCC_type_t *QCC_PR_ParseType (int newtype) } } QCC_PR_Lex (); - + if (QCC_PR_CheckToken ("(")) //this is followed by parameters. Must be a function. { type_inlinefunction = true; @@ -3529,7 +3507,7 @@ QCC_type_t *QCC_PR_ParseType (int newtype) { if (newtype) { - type = QCC_PR_DuplicateType(type); + type = QCC_PR_DuplicateType(type); } return type; diff --git a/misc/source/fteqcc-src/qccmain.c b/misc/source/fteqcc-src/qccmain.c index a410ab08..cad17a6c 100644 --- a/misc/source/fteqcc-src/qccmain.c +++ b/misc/source/fteqcc-src/qccmain.c @@ -2,14 +2,17 @@ #define PROGSUSED #include "qcc.h" -int mkdir(const char *path); +#include +#ifdef _WIN32 +#include +#endif + +#include "errno.h" char QCC_copyright[1024]; int QCC_packid; char QCC_Packname[5][128]; -extern QCC_def_t *functemps; //floats/strings/funcs/ents... - extern int optres_test1; extern int optres_test2; @@ -235,9 +238,10 @@ compiler_flag_t compiler_flag[] = { {&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 (without iffloat also enabled). 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_msvcstyle, FLAG_MIDCOMPILE,"msvcstyle", "MSVC-style errors", "Generates warning and error messages in a format that msvc understands, to facilitate ide integration."}, + {&flag_filetimes, 0, "filetimes", "Check Filetimes", "Recompiles the progs only if the file times are modified."}, {&flag_fasttrackarrays, FLAG_MIDCOMPILE|FLAG_ASDEFAULT,"fastarrays","fast arrays where possible", "Generates extra instructions inside array handling functions to detect engine and use extension opcodes only in supporting engines.\nAdds a global which is set by the engine if the engine supports the extra opcodes. Note that this applies to all arrays or none."}, {&flag_assume_integer, FLAG_MIDCOMPILE,"assumeint", "Assume Integers", "Numerical constants are assumed to be integers, instead of floats."}, - {&pr_subscopedlocals, FLAG_MIDCOMPILE,"subscope", "Subscoped locals", "Allow locals to only be valid in the block they are defined in (like in C)."}, + {&pr_subscopedlocals, FLAG_MIDCOMPILE, "subscope", "Subscoped Locals", "Restrict the scope of locals to the block they are actually defined within, as in C."}, {NULL} }; @@ -258,6 +262,7 @@ struct { {QCF_FTE, "fte"}, {QCF_DARKPLACES,"darkplaces"}, {QCF_DARKPLACES,"dp"}, + {QCF_QTEST, "qtest"}, {0, NULL} }; @@ -278,6 +283,7 @@ void QCC_BspModels (void) char *m; char cmd[1024]; char name[256]; + size_t result; p = QCC_CheckParm ("-bspmodels"); if (!p) @@ -285,7 +291,7 @@ void QCC_BspModels (void) if (p == myargc-1) QCC_Error (ERR_BADPARMS, "-bspmodels must preceed a game directory"); gamedir = myargv[p+1]; - + for (i=0 ; istrings ; s--) if (!strcmp(s, str)) return s-strings; - + old = strofs; strcpy (strings+strofs, str); strofs += strlen(str)+1; @@ -341,7 +350,7 @@ int QCC_CopyDupBackString (char *str) void QCC_PrintStrings (void) { int i, l, j; - + for (i=0 ; i 65530 ) { printf("Forcing target to FTE32 due to numpr_globals\n"); - outputsize = 32; + outputsttype = PST_FTE32; } else if (qcc_targetformat == QCF_HEXEN2) { @@ -621,7 +631,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) @@ -639,6 +649,12 @@ pbool QCC_WriteData (int crc) if (compressoutput) progs.blockscompressed |=128; //types //include a type block? types = debugtarget;//!!QCC_PR_CheckCompConstDefined("TYPES"); //useful for debugging and saving (maybe, anyway...). + if (sizeof(char *) != sizeof(string_t)) + { + //qcc_typeinfo_t has a char* inside it, which changes size + printf("AMD64 builds cannot write typeinfo structures\n"); + types = false; + } if (verbose) { @@ -655,7 +671,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. @@ -690,8 +713,8 @@ pbool QCC_WriteData (int crc) h=0; def->references = h; - - + + if (!h) h = 1; if (comp_x) @@ -708,6 +731,11 @@ pbool QCC_WriteData (int crc) QCC_PR_Warning(WARN_NOTREFERENCEDCONST, strings + def->s_file, def->s_line, "%s no references", def->name); else QCC_PR_Warning(WARN_NOTREFERENCED, strings + def->s_file, def->s_line, "%s no references", def->name); + if (!warnedunref) + { + QCC_PR_Note(WARN_NOTREFERENCED, NULL, 0, "You can use the noref prefix or pragma to silence this message."); + warnedunref = true; + } if (opt_unreferenced && def->type->type != ev_field) { @@ -740,7 +768,7 @@ pbool QCC_WriteData (int crc) // numfunctions++; } - else if (def->type->type == ev_field)// && !def->constant) + else if (def->type->type == ev_field && def->constant) { dd = &fields[numfielddefs]; numfielddefs++; @@ -863,7 +891,7 @@ strofs = (strofs+3)&~3; printf ("%6i numfielddefs (%i unique) (of %i)\n", numfielddefs, pr.size_fields, MAX_FIELDS); printf ("%6i numpr_globals (of %i)\n", numpr_globals, MAX_REGS); } - + if (!*destfile) strcpy(destfile, "progs.dat"); if (verbose) @@ -882,7 +910,7 @@ strofs = (strofs+3)&~3; progs.numstrings = strofs; if (progs.blockscompressed&16) - { + { SafeWrite (h, &len, sizeof(int)); //save for later len = QC_encode(progfuncs, strofs*sizeof(char), 2, (char *)strings, h); //write i = SafeSeek (h, 0, SEEK_CUR); @@ -910,9 +938,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); - 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); + 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"); } - 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 ; inext) { if (d->type->type != ev_field) @@ -1321,13 +1430,13 @@ char *QCC_PR_ValueString (etype_t type, void *val) static char line[256]; QCC_def_t *def; QCC_dfunction_t *f; - + switch (type) { case ev_string: sprintf (line, "%s", QCC_PR_String(strings + *(int *)val)); break; - case ev_entity: + case ev_entity: sprintf (line, "entity %i", *(int *)val); break; case ev_function: @@ -1360,7 +1469,7 @@ char *QCC_PR_ValueString (etype_t type, void *val) sprintf (line, "bad type %i", type); break; } - + return line; } @@ -1378,7 +1487,7 @@ padded to 20 field width QCC_def_t *def; void *val; static char line[128]; - + val = (void *)&qcc_pr_globals[ofs]; def = pr_global_defs[ofs]; if (!def) @@ -1386,12 +1495,12 @@ padded to 20 field width sprintf (line,"%i(?""?""?)", ofs); else sprintf (line,"%i(%s)", ofs, def->name); - + i = strlen(line); for ( ; i<16 ; i++) strcat (line," "); strcat (line," "); - + return line; } @@ -1402,7 +1511,7 @@ char *QCC_PR_GlobalString (gofs_t ofs) QCC_def_t *def; void *val; static char line[128]; - + val = (void *)&qcc_pr_globals[ofs]; def = pr_global_defs[ofs]; if (!def) @@ -1414,12 +1523,12 @@ char *QCC_PR_GlobalString (gofs_t ofs) } else sprintf (line,"%i(%s)", ofs, def->name); - + i = strlen(line); for ( ; i<16 ; i++) strcat (line," "); strcat (line," "); - + return line; }*/ @@ -1441,12 +1550,12 @@ PR_PrintStatement /*void QCC_PR_PrintStatement (QCC_dstatement_t *s) { int i; - + printf ("%4i : %4i : %s ", (int)(s - statements), statement_linenums[s-statements], pr_opcodes[s->op].opname); i = strlen(pr_opcodes[s->op].opname); for ( ; i<10 ; i++) printf (" "); - + if (s->op == OP_IF || s->op == OP_IFNOT) printf ("%sbranch %i",QCC_PR_GlobalString(s->a),s->b); else if (s->op == OP_GOTO) @@ -1479,7 +1588,7 @@ PR_PrintDefs /*void QCC_PR_PrintDefs (void) { QCC_def_t *d; - + for (d=pr.def_head.next ; d ; d=d->next) QCC_PR_PrintOfs (d->ofs); }*/ @@ -1493,7 +1602,7 @@ QCC_type_t *QCC_PR_NewType (char *name, int basictype) qcc_typeinfo[numtypeinfos].name = name; qcc_typeinfo[numtypeinfos].num_parms = 0; qcc_typeinfo[numtypeinfos].param = NULL; - qcc_typeinfo[numtypeinfos].size = type_size[basictype]; + qcc_typeinfo[numtypeinfos].size = type_size[basictype]; numtypeinfos++; @@ -1514,7 +1623,7 @@ void QCC_PR_BeginCompilation (void *memory, int memsize) extern struct freeoffset_s *freeofs; int i; char name[16]; - + pr.memory = memory; pr.max_memory = memsize; @@ -1523,20 +1632,20 @@ void QCC_PR_BeginCompilation (void *memory, int memsize) QCC_PR_ResetErrorScope(); pr_scope = NULL; -/* numpr_globals = RESERVED_OFS; - +/* numpr_globals = RESERVED_OFS; + for (i=0 ; inext) { @@ -1606,6 +1715,7 @@ int QCC_PR_FinishCompilation (void) // if (!f || (!f->code && !f->builtin) ) if (d->initialized==0) { + s_file = d->s_file; if (!strncmp(d->name, "ArrayGet*", 9)) { QCC_PR_EmitArrayGetFunction(d, d->name+9); @@ -1627,6 +1737,7 @@ int QCC_PR_FinishCompilation (void) bodylessfuncs = true; errors = true; } + s_file = NULL; // errors = true; } else if (d->initialized==2) @@ -1748,7 +1859,7 @@ static void Add3(char *p, unsigned short *crc, char *file) { char *s; for(s=p;*s;s++) - QCC_CRC_ProcessByte(crc, *s); + QCC_CRC_ProcessByte(crc, *s); } #define ADD3(p) Add3(p, &crc, file) @@ -1764,7 +1875,7 @@ unsigned short QCC_PR_WriteProgdefs (char *filename) file[0] = '\0'; QCC_CRC_Init (&crc); - + // print global vars until the first field is defined //ADD: crc and dump @@ -1779,7 +1890,7 @@ unsigned short QCC_PR_WriteProgdefs (char *filename) ADD2("File generated by FTEQCC, relevent for engine modding only, the generated crc must be the same as your engine expects."); ADD(" */\n\ntypedef struct"); ADD2(" globalvars_s"); - ADD(qcva("\n{")); + ADD(qcva("\n{")); ADD2("\tint pad;\n" "\tint ofs_return[3];\n" //makes it easier with the get globals func "\tint ofs_parm0[3];\n" @@ -1797,7 +1908,7 @@ unsigned short QCC_PR_WriteProgdefs (char *filename) break; if (d->ofstype->type) { case ev_float: @@ -1834,10 +1945,10 @@ unsigned short QCC_PR_WriteProgdefs (char *filename) { if (!strcmp (d->name, "end_sys_fields")) break; - + if (d->type->type != ev_field) continue; - + switch (d->type->aux_type->type) { case ev_float: @@ -1877,7 +1988,7 @@ unsigned short QCC_PR_WriteProgdefs (char *filename) if (d->type->type != ev_field) continue; if (f) - ADD2(",\n"); + ADD2(",\n"); ADD2(qcva("\t{%i,\t%i,\t\"%s\"}",G_INT(d->ofs), d->type->aux_type->type, d->name)); f = 1; } @@ -1963,14 +2074,14 @@ unsigned short QCC_PR_WriteProgdefs (char *filename) int i; QCC_dstatement_t *ds; QCC_dfunction_t *df; - + for (i=0 ; ifirst_statement; while (1) @@ -2049,7 +2160,7 @@ void QCC_CreatePath (char *path) { /* char *ofs; - + for (ofs = path+1 ; *ofs ; ofs++) { if (*ofs == '/') @@ -2080,12 +2191,12 @@ void QCC_PackFile (char *src, char *name) #if 1 char *f; #else - int in; + int in; int count; char buf[4096]; #endif - + if ( (qbyte *)pf - (qbyte *)pfiles > sizeof(pfiles) ) QCC_Error (ERR_TOOMANYPAKFILES, "Too many files in pak file"); @@ -2118,7 +2229,7 @@ void QCC_PackFile (char *src, char *name) printf ("%64s : %7i\n", pf->name, remaining); packbytes += remaining; - + while (remaining) { if (remaining < sizeof(buf)) @@ -2149,15 +2260,15 @@ void QCC_CopyFile (char *src, char *dest) int in, out; int remaining, count; char buf[4096]; - + print ("%s to %s\n", src, dest); in = SafeOpenRead (src); remaining = filelength (in); - + QCC_CreatePath (dest); out = SafeOpenWrite (dest, remaining+10); - + while (remaining) { if (remaining < sizeof(buf)) @@ -2170,7 +2281,7 @@ void QCC_CopyFile (char *src, char *dest) } close (in); - SafeClose (out); + SafeClose (out); */ } @@ -2202,7 +2313,7 @@ void _QCC_CopyFiles (int blocknum, int copytype, char *srcdir, char *destdir) for (i=0 ; i= sizeof(cnst->value)) - QCC_Error(ERR_PRECOMPILERCONSTANTTOOLONG, "Compiler constant value is too long\n"); - strncpy(cnst->value, val, sizeof(cnst->value)-1); - cnst->value[sizeof(cnst->value)-1] = '\0'; + cnst->value = qccHunkAlloc(strlen(val)+1); + memcpy(cnst->value, val, strlen(val)+1); } } @@ -2424,7 +2533,7 @@ void QCC_PR_CommandLinePrecompilerOptions (void) if (!optimisations[p].enabled) QCC_PR_Warning(0, NULL, WARN_BADPARAMS, "Unrecognised optimisation parameter (%s)", myargv[i]); } - + else if ( !strnicmp(myargv[i], "-K", 2) || !strnicmp(myargv[i], "/K", 2) ) { p = 0; @@ -2759,7 +2868,7 @@ void QCC_main (int argc, char **argv) //as part of the quake engine MAX_REGS = 65536; MAX_STRINGS = 1000000; - MAX_GLOBALS = 32768; + MAX_GLOBALS = 65535; MAX_FIELDS = 2048; MAX_STATEMENTS = 0x80000; MAX_FUNCTIONS = 16384; @@ -2800,10 +2909,10 @@ void QCC_main (int argc, char **argv) //as part of the quake engine MAX_FUNCTIONS = atoi(qcc_token); } else if (!strcmp(qcc_token, "MAX_TYPES")) { s = QCC_COM_Parse(s); - maxtypeinfos = atoi(qcc_token); + maxtypeinfos = atoi(qcc_token); } else if (!strcmp(qcc_token, "MAX_TEMPS")) { s = QCC_COM_Parse(s); - max_temps = atoi(qcc_token); + max_temps = atoi(qcc_token); } else if (!strcmp(qcc_token, "CONSTANTS")) { s = QCC_COM_Parse(s); MAX_CONSTANTS = atoi(qcc_token); @@ -2865,7 +2974,7 @@ void QCC_main (int argc, char **argv) //as part of the quake engine numtemps = 0; - functemps=NULL; + QCC_PurgeTemps(); strings = (void *)qccHunkAlloc(sizeof(char) * MAX_STRINGS); strofs = 1; @@ -2889,11 +2998,11 @@ void QCC_main (int argc, char **argv) //as part of the quake engine Hash_InitTable(&stringconstdefstable_dotranslate, MAX_REGS, qccHunkAlloc(Hash_BytesForBuckets(MAX_REGS))); dotranslate=0; dotranslate_count=0; - + // pr_global_defs = (QCC_def_t **)qccHunkAlloc(sizeof(QCC_def_t *) * MAX_REGS); qcc_globals = (void *)qccHunkAlloc(sizeof(QCC_ddef_t) * MAX_GLOBALS); - numglobaldefs=0; + numglobaldefs=0; fields = (void *)qccHunkAlloc(sizeof(QCC_ddef_t) * MAX_FIELDS); numfielddefs=0; @@ -2930,7 +3039,7 @@ memset(pr_immediate_string, 0, sizeof(pr_immediate_string)); #ifdef MAX_EXTRA_PARMS memset(&extra_parms, 0, sizeof(extra_parms)); #endif - + if ( QCC_CheckParm ("/?") || QCC_CheckParm ("?") || QCC_CheckParm ("-?") || QCC_CheckParm ("-help") || QCC_CheckParm ("--help")) { printf ("qcc looks for progs.src in the current directory.\n"); @@ -2950,7 +3059,7 @@ memset(pr_immediate_string, 0, sizeof(pr_immediate_string)); printf ("-Wall to give a stupid number of warnings\n"); printf ("-Ttarget to set a output format\n"); printf ("-Fautoproto to enable automatic prototyping\n"); - printf ("-Fsubscope to enable subscopes\n"); + printf ("-Fsubscope to make locals specific to their subscope\n"); qcc_compileactive = false; return; @@ -2967,7 +3076,7 @@ memset(pr_immediate_string, 0, sizeof(pr_immediate_string)); if (opt_locals_marshalling) printf("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\nLocals marshalling might be buggy. Use with caution\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n"); - + p = QCC_CheckParm ("-src"); if (p && p < argc-1 ) { @@ -2995,12 +3104,12 @@ memset(pr_immediate_string, 0, sizeof(pr_immediate_string)); if (!p || p >= argc-1 || argv[p+1][0] == '-') p = QCC_CheckParm ("-srcfile"); if (p && p < argc-1 ) - sprintf (qccmprogsdat, "%s%s", qccmsourcedir, argv[p+1]); + sprintf (qccmprogsdat, "%s", argv[p+1]); else { //look for a preprogs.src... :o) - sprintf (qccmprogsdat, "%spreprogs.src", qccmsourcedir); + sprintf (qccmprogsdat, "preprogs.src"); if (externs->FileSize(qccmprogsdat) <= 0) - sprintf (qccmprogsdat, "%sprogs.src", qccmsourcedir); + sprintf (qccmprogsdat, "progs.src"); } numsourcefiles = 0; @@ -3019,12 +3128,11 @@ memset(pr_immediate_string, 0, sizeof(pr_immediate_string)); if (currentsourcefile) printf("-------------------------------------\n"); - strcpy(qccmprogsdat, sourcefileslist[currentsourcefile++]); - + sprintf (qccmprogsdat, "%s%s", qccmsourcedir, sourcefileslist[currentsourcefile++]); printf ("Source file: %s\n", qccmprogsdat); if (QCC_LoadFile (qccmprogsdat, (void *)&qccmsrc) == -1) - { + { return; } } @@ -3057,7 +3165,7 @@ memset(pr_immediate_string, 0, sizeof(pr_immediate_string)); } if (*qcc_token == '#') - { + { void StartNewStyleCompile(void); newstyle: newstylesource = true; @@ -3081,7 +3189,7 @@ newstyle: #ifndef QCCONLY p=0; - s2 = strcpy(destfile2, destfile); + s2 = strcpy(destfile2, destfile); if (!strncmp(s2, "./", 2)) s2+=2; else @@ -3113,8 +3221,37 @@ newstyle: } #endif + if (flag_filetimes) + { + struct stat s, os; + pbool modified = false; + + if (stat(destfile, &os) != -1) + { + while ((pr_file_p=QCC_COM_Parse(pr_file_p))) + { + if (stat(qcc_token, &s) == -1 || s.st_mtime > os.st_mtime) + { + printf("%s changed\n", qcc_token); + modified = true; + break; + } + } + if (!modified) + { + printf("No changes\n"); + qcc_compileactive = false; + return; + } + else + { + pr_file_p = qccmsrc; + } + } + } + printf ("outputfile: %s\n", destfile); - + pr_dumpasm = false; currentchunk = NULL; @@ -3161,7 +3298,7 @@ void QCC_ContinueCompile(void) strcpy (qccmfilename, qccmsourcedir); while(1) { - if (!strncmp(s, "..\\", 3)) + if (!strncmp(s, "..\\", 3) || !strncmp(s, "../", 3)) { s2 = qccmfilename + strlen(qccmfilename)-2; while (s2>=qccmfilename) @@ -3173,10 +3310,13 @@ void QCC_ContinueCompile(void) } s2--; } - s+=3; - continue; + if (s2>=qccmfilename) + { + s+=3; + continue; + } } - if (!strncmp(s, ".\\", 2)) + if (!strncmp(s, ".\\", 2) || !strncmp(s, "./", 2)) { s+=2; continue; @@ -3197,7 +3337,7 @@ void QCC_ContinueCompile(void) QCC_Error (ERR_PARSEERRORS, "Errors have occured\n"); } void QCC_FinishCompile(void) -{ +{ pbool donesomething; int crc; // int p; @@ -3205,7 +3345,7 @@ void QCC_FinishCompile(void) if (setjmp(pr_parse_abort)) QCC_Error(ERR_INTERNAL, ""); - + if (!QCC_PR_FinishCompilation ()) { QCC_Error (ERR_PARSEERRORS, "compilation errors"); @@ -3238,10 +3378,10 @@ void QCC_FinishCompile(void) // write progdefs.h crc = QCC_PR_WriteProgdefs ("progdefs.h"); - + // write data file donesomething = QCC_WriteData (crc); - + // regenerate bmodels if -bspmodels QCC_BspModels (); @@ -3300,7 +3440,7 @@ void QCC_FinishCompile(void) printf("optres_test1 %i\n", optres_test1); if (optres_test2) printf("optres_test2 %i\n", optres_test2); - + printf("numtemps %i\n", numtemps); } if (!flag_msvcstyle) @@ -3381,7 +3521,7 @@ void new_QCC_ContinueCompile(void) } pr_scope = NULL; // outside all functions - + QCC_PR_ParseDefs (NULL); } @@ -3444,12 +3584,12 @@ void new_QCC_ContinueCompile(void) QCC_PR_ClearGrabMacros (); // clear the frame macros compilingfile = filename; - + pr_file_p = qccmsrc2; s_file = QCC_CopyString (filename); pr_source_line = 0; - + QCC_PR_NewLine (); QCC_PR_Lex (); // read first token @@ -3462,16 +3602,16 @@ void new_QCC_ContinueCompile(void) return false; QCC_PR_SkipToSemicolon (); if (pr_token_type == tt_eof) - return false; + return false; } pr_scope = NULL; // outside all functions - + QCC_PR_ParseDefs (); } } return (pr_error_count == 0); - + }*/ diff --git a/misc/source/fteqcc-src/qcd_main.c b/misc/source/fteqcc-src/qcd_main.c index f98e5336..20c6f7ca 100644 --- a/misc/source/fteqcc-src/qcd_main.c +++ b/misc/source/fteqcc-src/qcd_main.c @@ -8,7 +8,11 @@ #define ZEXPORT VARGS #include "../libs/zlib.h" +#ifdef _WIN64 +# pragma comment (lib, "../libs/zlib64.lib") +#else # pragma comment (lib, "../libs/zlib.lib") +#endif #else #include #endif diff --git a/misc/source/fteqcc-src/qcdecomp.c b/misc/source/fteqcc-src/qcdecomp.c index d1fcabf5..24fc433f 100644 --- a/misc/source/fteqcc-src/qcdecomp.c +++ b/misc/source/fteqcc-src/qcdecomp.c @@ -5,6 +5,22 @@ #define MAX_PARMS 8 +// I put the following here to resolve "undefined reference to `__imp__vsnprintf'" with MinGW64 ~ Moodles +#ifdef _WIN32 + #if (_MSC_VER >= 1400) + //with MSVC 8, use MS extensions + #define snprintf linuxlike_snprintf_vc8 + int VARGS linuxlike_snprintf_vc8(char *buffer, int size, const char *format, ...) LIKEPRINTF(3); + #define vsnprintf(a, b, c, d) vsnprintf_s(a, b, _TRUNCATE, c, d) + #else + //msvc crap + #define snprintf linuxlike_snprintf + int VARGS linuxlike_snprintf(char *buffer, int size, const char *format, ...) LIKEPRINTF(3); + #define vsnprintf linuxlike_vsnprintf + int VARGS linuxlike_vsnprintf(char *buffer, int size, const char *format, va_list argptr); + #endif +#endif + typedef struct QCC_type_s { etype_t type; @@ -13,7 +29,7 @@ typedef struct QCC_type_s // function types are more complex struct QCC_type_s *aux_type; // return type or field type int num_parms; // -1 = variable args -// struct QCC_type_s *parm_types[MAX_PARMS]; // only [num_parms] allocated +// struct QCC_type_s *parm_types[MAX_PARMS]; // only [num_parms] allocated int ofs; //inside a structure. int size; @@ -107,7 +123,7 @@ char *VarAtOfs(progfuncs_t *progfuncs, int ofs) typen = current_progstate->types[def->type & ~DEF_SHARED].type; else typen = def->type & ~(DEF_SHARED|DEF_SAVEGLOBAL); - + evaluateimmediate: // return PR_UglyValueString(def->type, (eval_t *)¤t_progstate->globals[def->ofs]); switch(typen) @@ -173,7 +189,7 @@ int ImmediateReadLater(progfuncs_t *progfuncs, progstate_t *progs, unsigned int dstatement16_t *st; if (ofsflags[ofs] & 8) return false; //this is a global/local/pramater, not a temp - if (!(ofsflags[ofs] & 3)) + if (!(ofsflags[ofs] & 3)) return false; //this is a constant. for (st = &((dstatement16_t*)progs->statements)[firstst]; ; st++,firstst++) { //if written, return false, if read, return true. @@ -313,7 +329,7 @@ int WriteStatement(progfuncs_t *progfuncs, progstate_t *progs, int stnum, int fi st = &((dstatement16_t*)progs->statements)[stnum]; switch(st->op) { - case OP_IFNOT: + case OP_IFNOT_I: count = (signed short)st->b; writes(file, "if ("); WriteStatementProducingOfs(progfuncs, progs, stnum, firstpossible, st->a); @@ -359,7 +375,7 @@ int WriteStatement(progfuncs_t *progfuncs, progstate_t *progs, int stnum, int fi writes(file, "}\r\n"); } break; - case OP_IF: + case OP_IF_I: longjmp(decompilestatementfailure, 1); break; case OP_GOTO: @@ -453,7 +469,7 @@ void WriteAsmStatements(progfuncs_t *progfuncs, progstate_t *progs, int num, int def->s_name = (char*)malloc(strlen(mem)+1)-progfuncs->stringtable; strcpy(def->s_name+progfuncs->stringtable, mem); } - + if (current_progstate->types) writes(f, "%s %s", current_progstate->types[def->type&~(DEF_SHARED|DEF_SAVEGLOBAL)].name, def->s_name); else @@ -471,7 +487,7 @@ void WriteAsmStatements(progfuncs_t *progfuncs, progstate_t *progs, int num, int case ev_vector: writes(f, "%s %s", "vector", progfuncs->stringtable+def->s_name); break; - default: + default: writes(f, "%s %s", "randomtype", progfuncs->stringtable+def->s_name); break; } @@ -542,7 +558,7 @@ void WriteAsmStatements(progfuncs_t *progfuncs, progstate_t *progs, int num, int writes(f, ";\r\n"); return; } - + fileofs = SafeSeek(f, 0, SEEK_CUR); if (setjmp(decompilestatementfailure)) { @@ -555,7 +571,7 @@ void WriteAsmStatements(progfuncs_t *progfuncs, progstate_t *progs, int num, int { def = ED_GlobalAtOfs16(progfuncs, ofs); if (def) - { + { v = (eval_t *)&((int *)progs->globals)[def->ofs]; if (current_progstate->types) writes(f, "\tlocal %s %s;\r\n", current_progstate->types[def->type&~(DEF_SHARED|DEF_SAVEGLOBAL)].name, def->s_name); @@ -583,11 +599,11 @@ void WriteAsmStatements(progfuncs_t *progfuncs, progstate_t *progs, int num, int case ev_vector: if (v->_vector[0] || v->_vector[1] || v->_vector[2]) writes(f, "\tlocal vector %s = '%f %f %f';\r\n", progfuncs->stringtable+def->s_name, v->_vector[0], v->_vector[1], v->_vector[2]); - else + else writes(f, "\tlocal %s %s;\r\n", "vector", progfuncs->stringtable+def->s_name); ofs+=2; //skip floats; break; - default: + default: writes(f, "\tlocal %s %s;\r\n", "randomtype", progfuncs->stringtable+def->s_name); break; } @@ -600,7 +616,7 @@ void WriteAsmStatements(progfuncs_t *progfuncs, progstate_t *progs, int num, int st = &((dstatement16_t*)progs->statements)[stn]; if (!st->op) //end of function statement! break; - op = &pr_opcodes[st->op]; + op = &pr_opcodes[st->op]; writes(f, "\t%s", op->opname); if (op->priority==-1&&op->associative==ASSOC_RIGHT) //last param is a goto @@ -651,7 +667,7 @@ void WriteAsmStatements(progfuncs_t *progfuncs, progstate_t *progs, int num, int writes(f, " %s", VarAtOfs(progfuncs, st->c)); } } - + writes(f, ";\r\n"); stn++; @@ -671,7 +687,7 @@ void WriteAsmStatements(progfuncs_t *progfuncs, progstate_t *progs, int num, int { def = ED_GlobalAtOfs16(progfuncs, ofs); if (def) - { + { v = (eval_t *)&((int *)progs->globals)[def->ofs]; if (current_progstate->types) writes(f, "\tlocal %s %s;\r\n", current_progstate->types[def->type&~(DEF_SHARED|DEF_SAVEGLOBAL)].name, def->s_name); @@ -698,12 +714,12 @@ void WriteAsmStatements(progfuncs_t *progfuncs, progstate_t *progs, int num, int break; case ev_vector: if (v->_vector[0] || v->_vector[1] || v->_vector[2]) - writes(f, "\tlocal vector %s = '%f %f %f';\r\n", def->s_name, v->_vector[0], v->_vector[1], v->_vector[2]); - else + writes(f, "\tlocal vector %s = '%f %f %f';\r\n", progfuncs->stringtable+def->s_name, v->_vector[0], v->_vector[1], v->_vector[2]); + else writes(f, "\tlocal %s %s;\r\n", "vector",progfuncs->stringtable+def->s_name); ofs+=2; //skip floats; break; - default: + default: writes(f, "\tlocal %s %s;\r\n", "randomtype", progfuncs->stringtable+def->s_name); break; } @@ -736,7 +752,7 @@ void FigureOutTypes(progfuncs_t *progfuncs) dstatement16_t *st; int parmofs[8]; - + ofstype = realloc(ofstype, sizeof(*ofstype)*65535); ofsflags = realloc(ofsflags, sizeof(*ofsflags)*65535); @@ -752,9 +768,9 @@ void FigureOutTypes(progfuncs_t *progfuncs) type_float = QCC_PR_NewType("float", ev_float); type_vector = QCC_PR_NewType("vector", ev_vector); type_entity = QCC_PR_NewType("entity", ev_entity); - type_field = QCC_PR_NewType("field", ev_field); + type_field = QCC_PR_NewType("field", ev_field); type_function = QCC_PR_NewType("function", ev_function); - type_pointer = QCC_PR_NewType("pointer", ev_pointer); + type_pointer = QCC_PR_NewType("pointer", ev_pointer); type_integer = QCC_PR_NewType("integer", ev_integer); // type_variant = QCC_PR_NewType("__variant", ev_variant); @@ -843,7 +859,7 @@ pbool Decompile(progfuncs_t *progfuncs, char *fname) qccprogfuncs = progfuncs; op=current_progstate; - + if (!PR_ReallyLoadProgs(progfuncs, fname, -1, &progs, false)) { return false; @@ -892,7 +908,7 @@ pbool Decompile(progfuncs_t *progfuncs, char *fname) if (v->string && *(pr_strings+v->_int)) writes(f, "string %s = \"%s\";\r\n", progfuncs->stringtable+pr_globaldefs16[i].s_name, pr_strings+v->_int); else - writes(f, "string %s;\r\n", pr_globaldefs16[i].s_name); + writes(f, "string %s;\r\n", progfuncs->stringtable+pr_globaldefs16[i].s_name); break; case ev_float: if (v->_float) @@ -947,10 +963,10 @@ pbool Decompile(progfuncs_t *progfuncs, char *fname) break; case ev_function: -//wierd +//wierd WriteAsmStatements(progfuncs, &progs, ((int *)progs.globals)[pr_globaldefs16[i].ofs], f, pr_globaldefs16[i].s_name+progfuncs->stringtable); break; - + case ev_pointer: writes(f, "pointer %s;\r\n", progfuncs->stringtable+pr_globaldefs16[i].s_name); break; @@ -964,9 +980,9 @@ pbool Decompile(progfuncs_t *progfuncs, char *fname) case ev_struct: writes(f, "struct %s;\r\n", progfuncs->stringtable+pr_globaldefs16[i].s_name); break; - default: + default: break; - + } } diff --git a/misc/source/netradiant-src/Makefile b/misc/source/netradiant-src/Makefile index b0a1d4a2..8f7d036c 100644 --- a/misc/source/netradiant-src/Makefile +++ b/misc/source/netradiant-src/Makefile @@ -179,7 +179,7 @@ ifeq ($(OS),Win32) CPPFLAGS_COMMON += -DWIN32 -D_WIN32 -D_inline=inline CFLAGS_COMMON += -mms-bitfields LDFLAGS_DLL = --dll -Wl,--add-stdcall-alias - LIBS_COMMON = -lws2_32 -luser32 -lgdi32 + LIBS_COMMON = -lws2_32 -luser32 -lgdi32 -lole32 EXE ?= exe A = a DLL = dll @@ -506,6 +506,7 @@ $(INSTALLDIR)/q3map2.$(EXE): \ tools/quake3/q3map2/vis.o \ tools/quake3/q3map2/writebsp.o \ libddslib.$(A) \ + libfilematch.$(A) \ libjpeg6.$(A) \ libl_net.$(A) \ libmathlib.$(A) \ @@ -603,6 +604,7 @@ $(INSTALLDIR)/q3data.$(EXE): \ tools/quake3/q3data/q3data.o \ tools/quake3/q3data/stripper.o \ tools/quake3/q3data/video.o \ + libfilematch.$(A) \ libl_net.$(A) \ libmathlib.$(A) \ $(if $(findstring $(OS),Win32),icons/q3data.o,) \ @@ -700,6 +702,10 @@ $(INSTALLDIR)/radiant.$(EXE): \ libxmllib.$(A) \ $(if $(findstring $(OS),Win32),icons/radiant.o,) \ +libfilematch.$(A): CPPFLAGS_EXTRA := -Ilibs +libfilematch.$(A): \ + libs/filematch.o \ + libcmdlib.$(A): CPPFLAGS_EXTRA := -Ilibs libcmdlib.$(A): \ libs/cmdlib/cmdlib.o \ @@ -856,6 +862,7 @@ $(INSTALLDIR)/modules/vfspk3.$(DLL): \ plugins/vfspk3/archive.o \ plugins/vfspk3/vfs.o \ plugins/vfspk3/vfspk3.o \ + libfilematch.$(A) \ $(INSTALLDIR)/plugins/bobtoolz.$(DLL): LIBS_EXTRA := $(LIBS_GLIB) $(LIBS_GTK) $(INSTALLDIR)/plugins/bobtoolz.$(DLL): CPPFLAGS_EXTRA := $(CPPFLAGS_GLIB) $(CPPFLAGS_GTK) -Ilibs -Iinclude diff --git a/misc/source/netradiant-src/contrib/bobtoolz/DPatch.h b/misc/source/netradiant-src/contrib/bobtoolz/DPatch.h index 5a956f92..a10773d6 100644 --- a/misc/source/netradiant-src/contrib/bobtoolz/DPatch.h +++ b/misc/source/netradiant-src/contrib/bobtoolz/DPatch.h @@ -25,6 +25,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #define AFX_DPATCH_H__26C6B083_CE5B_420B_836B_1DDA733C04CE__INCLUDED_ #include +#include typedef struct { diff --git a/misc/source/netradiant-src/contrib/bobtoolz/DShape.h b/misc/source/netradiant-src/contrib/bobtoolz/DShape.h index 3c4ed75e..29bca7fc 100644 --- a/misc/source/netradiant-src/contrib/bobtoolz/DShape.h +++ b/misc/source/netradiant-src/contrib/bobtoolz/DShape.h @@ -28,6 +28,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #pragma once #endif // _MSC_VER > 1000 +#include #include "mathlib.h" #include "DMap.h" class DBrush; diff --git a/misc/source/netradiant-src/download-gamepacks.sh b/misc/source/netradiant-src/download-gamepacks.sh index 2d6c1b78..f31c5443 100644 --- a/misc/source/netradiant-src/download-gamepacks.sh +++ b/misc/source/netradiant-src/download-gamepacks.sh @@ -150,11 +150,13 @@ mkdir -p games pack DarkPlacesPack GPL svn https://zerowing.idsoftware.com/svn/radiant.gamepacks/DarkPlacesPack/branches/1.5/ pack NexuizPack GPL gitdir git://git.icculus.org/divverent/nexuiz.git misc/netradiant-NexuizPack master pack OpenArenaPack unknown zip1 http://ingar.satgnu.net/files/gtkradiant/gamepacks/OpenArenaPack.zip +pack OsirionPack GPL zip1 http://ingar.satgnu.net/files/gtkradiant/gamepacks/OsirionPack.zip pack Q3Pack proprietary svn https://zerowing.idsoftware.com/svn/radiant.gamepacks/Q3Pack/trunk/ -r29 pack Quake2Pack proprietary zip1 http://ingar.satgnu.net/files/gtkradiant/gamepacks/Quake2Pack.zip pack Quake2WorldPack GPL svn svn://jdolan.dyndns.org/quake2world/trunk/gtkradiant pack QuakePack proprietary zip1 http://ingar.satgnu.net/files/gtkradiant/gamepacks/QuakePack.zip pack TremulousPack proprietary zip1 http://ingar.satgnu.net/files/gtkradiant/gamepacks/TremulousPack.zip pack UFOAIPack proprietary svn https://zerowing.idsoftware.com/svn/radiant.gamepacks/UFOAIPack/branches/1.5/ -pack WarsowPack GPL svn https://svn.bountysource.com/wswpack/trunk/netradiant/games/WarsowPack/ +#pack WarsowPack GPL svn https://svn.bountysource.com/wswpack/trunk/netradiant/games/WarsowPack/ +pack WarsowPack GPL zip1 http://ingar.satgnu.net/files/gtkradiant/gamepacks/WarsowPack.zip pack XonoticPack GPL git git://git.xonotic.org/xonotic/netradiant-xonoticpack.git diff --git a/misc/source/netradiant-src/install-dylibs.sh b/misc/source/netradiant-src/install-dylibs.sh index 798a7d14..9f4e3e2b 100644 --- a/misc/source/netradiant-src/install-dylibs.sh +++ b/misc/source/netradiant-src/install-dylibs.sh @@ -24,19 +24,25 @@ finkgetdeps() finkgetdeps "$INSTALLDIR/radiant.$EXE" echo Warning: this only works if only ONE version of gtk-2.0 and pango is installed -for LIB in "$MACLIBDIR"/gtk-2.0/*/loaders/libpixbufloader-bmp.so; do +LAST= +for LIB in "$MACLIBDIR"/gtk-2.0/*/loaders/libpixbufloader-bmp.so "$MACLIBDIR"/gdk-pixbuf-2.0/*/loaders/libpixbufloader-bmp.so; do + [ -f "$LIB" ] || continue LAST=$LIB done cp -L "$LAST" "$INSTALLDIR" finkgetdeps "$LAST" +LAST= for LIB in "$MACLIBDIR"/pango/*/modules/pango-basic-fc.so; do + [ -f "$LIB" ] || continue LAST=$LIB done cp -L "$LAST" "$INSTALLDIR" finkgetdeps "$LAST" +LAST= for LIB in "$MACLIBDIR"/pango/*/modules/pango-basic-x.so; do + [ -f "$LIB" ] || continue LAST=$LIB done cp -L "$LAST" "$INSTALLDIR" diff --git a/misc/source/netradiant-src/install-gamepack.sh b/misc/source/netradiant-src/install-gamepack.sh index 1f149666..3a36c200 100644 --- a/misc/source/netradiant-src/install-gamepack.sh +++ b/misc/source/netradiant-src/install-gamepack.sh @@ -16,8 +16,12 @@ if [ -d "$pack/tools" ]; then pack="$pack/tools" fi for GAMEFILE in "$pack/games"/*.game; do - $CP "$GAMEFILE" "$dest/games/" + if [ x"$GAMEFILE" != x"$pack/games/*.game" ]; then + $CP "$GAMEFILE" "$dest/games/" + fi done for GAMEDIR in "$pack"/*.game; do - $CP_R "$GAMEDIR" "$dest/" + if [ x"$GAMEDIR" != x"$pack/*.game" ]; then + $CP_R "$GAMEDIR" "$dest/" + fi done diff --git a/misc/source/netradiant-src/libs/memory/allocator.h b/misc/source/netradiant-src/libs/memory/allocator.h index c513d708..ebaeeb5b 100644 --- a/misc/source/netradiant-src/libs/memory/allocator.h +++ b/misc/source/netradiant-src/libs/memory/allocator.h @@ -23,6 +23,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #define INCLUDED_MEMORY_ALLOCATOR_H #include +#include #if 0 diff --git a/misc/source/netradiant-src/libs/picomodel.h b/misc/source/netradiant-src/libs/picomodel.h index 1e6f8920..a771e943 100644 --- a/misc/source/netradiant-src/libs/picomodel.h +++ b/misc/source/netradiant-src/libs/picomodel.h @@ -258,7 +258,7 @@ void PicoSetShaderShininess( picoShader_t *shader, float value ); void PicoSetSurfaceData( picoSurface_t *surface, void *data ); void PicoSetSurfaceType( picoSurface_t *surface, picoSurfaceType_t type ); -void PicoSetSurfaceName( picoSurface_t *surface, char *name ); +void PicoSetSurfaceName( picoSurface_t *surface, const char *name ); void PicoSetSurfaceShader( picoSurface_t *surface, picoShader_t *shader ); void PicoSetSurfaceXYZ( picoSurface_t *surface, int num, picoVec3_t xyz ); void PicoSetSurfaceNormal( picoSurface_t *surface, int num, picoVec3_t normal ); @@ -341,7 +341,7 @@ void PicoFixSurfaceNormals( picoSurface_t *surface ); int PicoRemapModel( picoModel_t *model, char *remapFile ); -void PicoAddTriangleToModel( picoModel_t *model, picoVec3_t** xyz, picoVec3_t** normals, int numSTs, picoVec2_t **st, int numColors, picoColor_t **colors, picoShader_t* shader, picoIndex_t* smoothingGroup); +void PicoAddTriangleToModel( picoModel_t *model, picoVec3_t** xyz, picoVec3_t** normals, int numSTs, picoVec2_t **st, int numColors, picoColor_t **colors, picoShader_t* shader, const char *name, picoIndex_t* smoothingGroup); /* end marker */ #ifdef __cplusplus diff --git a/misc/source/netradiant-src/libs/picomodel/lwo/lwo2.c b/misc/source/netradiant-src/libs/picomodel/lwo/lwo2.c index 56c756c3..9e45bfa1 100644 --- a/misc/source/netradiant-src/libs/picomodel/lwo/lwo2.c +++ b/misc/source/netradiant-src/libs/picomodel/lwo/lwo2.c @@ -272,7 +272,7 @@ Fail: int lwValidateObject( const char *filename, picoMemStream_t *fp, unsigned int *failID, int *failpos ) { - unsigned int id, formsize, type; + unsigned int id, type; /* open the file */ @@ -282,7 +282,7 @@ int lwValidateObject( const char *filename, picoMemStream_t *fp, unsigned int *f set_flen( 0 ); id = getU4( fp ); - formsize = getU4( fp ); + /* formsize = */ getU4( fp ); type = getU4( fp ); if ( 12 != get_flen() ) { return PICO_PMV_ERROR_SIZE; diff --git a/misc/source/netradiant-src/libs/picomodel/lwo/lwob.c b/misc/source/netradiant-src/libs/picomodel/lwo/lwob.c index f12e3a36..cb2a70ea 100644 --- a/misc/source/netradiant-src/libs/picomodel/lwo/lwob.c +++ b/misc/source/netradiant-src/libs/picomodel/lwo/lwob.c @@ -712,7 +712,7 @@ Fail: int lwValidateObject5( const char *filename, picoMemStream_t *fp, unsigned int *failID, int *failpos ) { - unsigned int id, formsize, type; + unsigned int id, type; /* open the file */ @@ -723,7 +723,7 @@ int lwValidateObject5( const char *filename, picoMemStream_t *fp, unsigned int * set_flen( 0 ); id = getU4( fp ); - formsize = getU4( fp ); + /* formsize = */ getU4( fp ); type = getU4( fp ); if ( 12 != get_flen() ) { return PICO_PMV_ERROR_SIZE; diff --git a/misc/source/netradiant-src/libs/picomodel/picomodel.c b/misc/source/netradiant-src/libs/picomodel/picomodel.c index aed467ca..86ec08bd 100644 --- a/misc/source/netradiant-src/libs/picomodel/picomodel.c +++ b/misc/source/netradiant-src/libs/picomodel/picomodel.c @@ -912,7 +912,7 @@ void PicoSetSurfaceType( picoSurface_t *surface, picoSurfaceType_t type ) -void PicoSetSurfaceName( picoSurface_t *surface, char *name ) +void PicoSetSurfaceName( picoSurface_t *surface, const char *name ) { if( surface == NULL || name == NULL ) return; @@ -2214,7 +2214,7 @@ Chooses an appropriate surface based on the shader, or adds a new surface if nec void PicoAddTriangleToModel( picoModel_t *model, picoVec3_t** xyz, picoVec3_t** normals, int numSTs, picoVec2_t **st, int numColors, picoColor_t **colors, - picoShader_t* shader, picoIndex_t* smoothingGroup ) + picoShader_t* shader, const char *name, picoIndex_t* smoothingGroup ) { int i,j; int vertDataIndex; @@ -2224,6 +2224,7 @@ void PicoAddTriangleToModel( picoModel_t *model, picoVec3_t** xyz, picoVec3_t** for ( i = 0 ; i < model->numSurfaces ; i++ ) { workSurface = model->surface[i]; + if ( !name || !strcmp(workSurface->name, name) ) if ( workSurface->shader == shader ) { break; @@ -2243,7 +2244,7 @@ void PicoAddTriangleToModel( picoModel_t *model, picoVec3_t** xyz, picoVec3_t** /* do surface setup */ PicoSetSurfaceType( workSurface, PICO_TRIANGLES ); - PicoSetSurfaceName( workSurface, shader->name ); + PicoSetSurfaceName( workSurface, name ? name : shader->name ); PicoSetSurfaceShader( workSurface, shader ); } diff --git a/misc/source/netradiant-src/libs/picomodel/pm_ase.c b/misc/source/netradiant-src/libs/picomodel/pm_ase.c index 31c448e6..6905431e 100644 --- a/misc/source/netradiant-src/libs/picomodel/pm_ase.c +++ b/misc/source/netradiant-src/libs/picomodel/pm_ase.c @@ -452,7 +452,7 @@ static void _ase_submit_triangles_unshared ( picoModel_t* model , aseMaterial_t* #endif -static void _ase_submit_triangles( picoModel_t* model , aseMaterial_t* materials , aseVertex_t* vertices, aseTexCoord_t* texcoords, aseColor_t* colors, aseFace_t* faces, int numFaces ) +static void _ase_submit_triangles( picoModel_t* model , aseMaterial_t* materials , aseVertex_t* vertices, aseTexCoord_t* texcoords, aseColor_t* colors, aseFace_t* faces, int numFaces, const char *name ) { aseFacesIter_t i = faces, end = faces + numFaces; for(; i != end; ++i) @@ -492,7 +492,7 @@ static void _ase_submit_triangles( picoModel_t* model , aseMaterial_t* materials } /* submit the triangle to the model */ - PicoAddTriangleToModel ( model , xyz , normal , 1 , st , 1 , color , subMtl->shader, smooth ); + PicoAddTriangleToModel ( model , xyz , normal , 1 , st , 1 , color , subMtl->shader, name, smooth ); } } } @@ -599,7 +599,7 @@ static picoModel_t *_ase_load( PM_PARAMS_LOAD ) else if (!_pico_stricmp(p->token,"*mesh")) { /* finish existing surface */ - _ase_submit_triangles(model, materials, vertices, texcoords, colors, faces, numFaces); + _ase_submit_triangles(model, materials, vertices, texcoords, colors, faces, numFaces, lastNodeName); _pico_free(faces); _pico_free(vertices); _pico_free(texcoords); @@ -1152,7 +1152,7 @@ static picoModel_t *_ase_load( PM_PARAMS_LOAD ) } /* ydnar: finish existing surface */ - _ase_submit_triangles(model, materials, vertices, texcoords, colors, faces, numFaces); + _ase_submit_triangles(model, materials, vertices, texcoords, colors, faces, numFaces, lastNodeName); _pico_free(faces); _pico_free(vertices); _pico_free(texcoords); diff --git a/misc/source/netradiant-src/libs/picomodel/pm_fm.c b/misc/source/netradiant-src/libs/picomodel/pm_fm.c index 1065160e..0fc65813 100644 --- a/misc/source/netradiant-src/libs/picomodel/pm_fm.c +++ b/misc/source/netradiant-src/libs/picomodel/pm_fm.c @@ -208,7 +208,6 @@ static picoModel_t *_fm_load( PM_PARAMS_LOAD ) { int i, j, dups, dup_index; int fm_file_pos; - short tot_numVerts; index_LUT_t *p_index_LUT, *p_index_LUT2, *p_index_LUT3; index_DUP_LUT_t *p_index_LUT_DUPS; @@ -458,7 +457,6 @@ static picoModel_t *_fm_load( PM_PARAMS_LOAD ) } // Fill in Look Up Table, and allocate/fill Linked List from vert array as needed for dup STs per Vert. - tot_numVerts = fm_head->numXYZ; dups = 0; triangle = tri_verts; diff --git a/misc/source/netradiant-src/libs/picomodel/pm_md2.c b/misc/source/netradiant-src/libs/picomodel/pm_md2.c index d53f7029..19b5689c 100644 --- a/misc/source/netradiant-src/libs/picomodel/pm_md2.c +++ b/misc/source/netradiant-src/libs/picomodel/pm_md2.c @@ -329,7 +329,6 @@ static int _md2_canload( PM_PARAMS_CANLOAD ) static picoModel_t *_md2_load( PM_PARAMS_LOAD ) { int i, j, dups, dup_index; - short tot_numVerts; index_LUT_t *p_index_LUT, *p_index_LUT2, *p_index_LUT3; index_DUP_LUT_t *p_index_LUT_DUPS; md2Triangle_t *p_md2Triangle; @@ -491,7 +490,6 @@ static picoModel_t *_md2_load( PM_PARAMS_LOAD ) } // Fill in Look Up Table, and allocate/fill Linked List from vert array as needed for dup STs per Vert. - tot_numVerts = md2->numXYZ; dups = 0; for(i=0; inumTris; i++) { diff --git a/misc/source/netradiant-src/libs/picomodel/pm_obj.c b/misc/source/netradiant-src/libs/picomodel/pm_obj.c index 7f269faa..1f77eeb1 100644 --- a/misc/source/netradiant-src/libs/picomodel/pm_obj.c +++ b/misc/source/netradiant-src/libs/picomodel/pm_obj.c @@ -694,7 +694,7 @@ static picoModel_t *_obj_load( PM_PARAMS_LOAD ) if(curSurface == NULL) { - _pico_printf( PICO_ERROR,"No group defined for faces, so creating an autoSurface in OBJ, line %d.",p->curLine); + _pico_printf( PICO_WARNING,"No group defined for faces, so creating an autoSurface in OBJ, line %d.",p->curLine); AUTO_GROUPNAME(autoGroupNameBuf); NEW_SURFACE(autoGroupNameBuf); } @@ -869,7 +869,7 @@ static picoModel_t *_obj_load( PM_PARAMS_LOAD ) if(curFace != 0 || curSurface == NULL) { - _pico_printf( PICO_ERROR,"No group defined for usemtl, so creating an autoSurface in OBJ, line %d.",p->curLine); + _pico_printf( PICO_WARNING,"No group defined for usemtl, so creating an autoSurface in OBJ, line %d.",p->curLine); AUTO_GROUPNAME(autoGroupNameBuf); NEW_SURFACE(autoGroupNameBuf); } @@ -884,7 +884,7 @@ static picoModel_t *_obj_load( PM_PARAMS_LOAD ) shader = PicoFindShader( model, name, 1 ); if (shader == NULL) { - _pico_printf( PICO_ERROR,"Undefined material name in OBJ, line %d. Making a default shader.",p->curLine); + _pico_printf( PICO_WARNING,"Undefined material name in OBJ, line %d. Making a default shader.",p->curLine); /* create a new pico shader */ shader = PicoNewShader( model ); diff --git a/misc/source/netradiant-src/libs/typesystem.h b/misc/source/netradiant-src/libs/typesystem.h index f16d4199..67c0680f 100644 --- a/misc/source/netradiant-src/libs/typesystem.h +++ b/misc/source/netradiant-src/libs/typesystem.h @@ -24,6 +24,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #include +#include #include "generic/callback.h" #include "generic/static.h" diff --git a/misc/source/netradiant-src/plugins/vfspk3/vfs.cpp b/misc/source/netradiant-src/plugins/vfspk3/vfs.cpp index b47942ba..86a2ac85 100644 --- a/misc/source/netradiant-src/plugins/vfspk3/vfs.cpp +++ b/misc/source/netradiant-src/plugins/vfspk3/vfs.cpp @@ -60,6 +60,7 @@ ArchiveModules& FileSystemQ3API_getArchiveModules(); #include "stream/stringstream.h" #include "os/path.h" #include "moduleobservers.h" +#include "filematch.h" #define VFS_MAXDIRS 64 @@ -315,9 +316,17 @@ void InitDirectory(const char* directory, ArchiveModules& archiveModules) for(j = 0; j < g_numForbiddenDirs; ++j) { - if(!string_compare_nocase_upper(directory, g_strForbiddenDirs[j]) - || (string_length(directory) > string_length(g_strForbiddenDirs[j]) && directory[string_length(directory) - string_length(g_strForbiddenDirs[j]) - 1] == '/' && !string_compare_nocase_upper(directory + string_length(directory) - string_length(g_strForbiddenDirs[j]), g_strForbiddenDirs[j]))) + char* dbuf = g_strdup(directory); + if(*dbuf && dbuf[strlen(dbuf)-1] == '/') + dbuf[strlen(dbuf)-1] = 0; + const char *p = strrchr(dbuf, '/'); + p = (p ? (p+1) : dbuf); + if(matchpattern(p, g_strForbiddenDirs[j], TRUE)) + { + g_free(dbuf); break; + } + g_free(dbuf); } if(j < g_numForbiddenDirs) { @@ -380,9 +389,13 @@ void InitDirectory(const char* directory, ArchiveModules& archiveModules) if(name == 0) break; - for(j = 0; j < g_numForbiddenDirs; ++j) - if(!string_compare_nocase_upper(name, g_strForbiddenDirs[j])) - break; + for(j = 0; j < g_numForbiddenDirs; ++j) + { + const char *p = strrchr(name, '/'); + p = (p ? (p+1) : name); + if(matchpattern(p, g_strForbiddenDirs[j], TRUE)) + break; + } if(j < g_numForbiddenDirs) continue; diff --git a/misc/source/netradiant-src/radiant/brushmodule.cpp b/misc/source/netradiant-src/radiant/brushmodule.cpp index 21cec0ee..3cdf77a8 100644 --- a/misc/source/netradiant-src/radiant/brushmodule.cpp +++ b/misc/source/netradiant-src/radiant/brushmodule.cpp @@ -118,6 +118,10 @@ void Brush_Construct(EBrushType type) { g_showAlternativeTextureProjectionOption = true; + const char *value = g_pGameDescription->getKeyValue("brush_primit"); + if(!string_empty(value)) + g_useAlternativeTextureProjection.m_latched = atoi(value); + GlobalPreferenceSystem().registerPreference( "AlternativeTextureProjection", BoolImportStringCaller(g_useAlternativeTextureProjection.m_latched), diff --git a/misc/source/netradiant-src/radiant/csg.cpp b/misc/source/netradiant-src/radiant/csg.cpp index f30fb980..a0afdeeb 100644 --- a/misc/source/netradiant-src/radiant/csg.cpp +++ b/misc/source/netradiant-src/radiant/csg.cpp @@ -397,12 +397,16 @@ public: for(brush_vector_t::const_iterator i = out.begin(); i != out.end(); ++i) { ++m_after; - NodeSmartReference node((new BrushNode())->node()); (*i)->removeEmptyFaces(); - ASSERT_MESSAGE(!(*i)->empty(), "brush left with no faces after subtract"); - Node_getBrush(node)->copy(*(*i)); - delete (*i); - Node_getTraversable(path.parent())->insert(node); + if(!(*i)->empty()) + { + NodeSmartReference node((new BrushNode())->node()); + Node_getBrush(node)->copy(*(*i)); + delete (*i); + Node_getTraversable(path.parent())->insert(node); + } + else + delete (*i); } Path_deleteTop(path); } diff --git a/misc/source/netradiant-src/radiant/entityinspector.cpp b/misc/source/netradiant-src/radiant/entityinspector.cpp index b5636780..95f03f73 100644 --- a/misc/source/netradiant-src/radiant/entityinspector.cpp +++ b/misc/source/netradiant-src/radiant/entityinspector.cpp @@ -76,6 +76,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #include "entity.h" #include "mainframe.h" #include "textureentry.h" +#include "groupdialog.h" GtkEntry* numeric_entry_new() { @@ -1760,3 +1761,11 @@ void EntityInspector_destroy() GlobalEntityClassManager().detach(g_EntityInspector); } +const char *EntityInspector_getCurrentKey() +{ + if(!GroupDialog_isShown()) + return 0; + if(GroupDialog_getPage() != g_page_entity) + return 0; + return gtk_entry_get_text(g_entityKeyEntry); +} diff --git a/misc/source/netradiant-src/radiant/entityinspector.h b/misc/source/netradiant-src/radiant/entityinspector.h index 62a69ab6..130c9657 100644 --- a/misc/source/netradiant-src/radiant/entityinspector.h +++ b/misc/source/netradiant-src/radiant/entityinspector.h @@ -27,5 +27,6 @@ typedef struct _GtkWindow GtkWindow; GtkWidget* EntityInspector_constructWindow(GtkWindow* parent); void EntityInspector_construct(); void EntityInspector_destroy(); +const char *EntityInspector_getCurrentKey(); #endif diff --git a/misc/source/netradiant-src/radiant/groupdialog.h b/misc/source/netradiant-src/radiant/groupdialog.h index 92caffab..38f399be 100644 --- a/misc/source/netradiant-src/radiant/groupdialog.h +++ b/misc/source/netradiant-src/radiant/groupdialog.h @@ -44,5 +44,7 @@ GtkWidget* GroupDialog_addPage(const char* tabLabel, GtkWidget* widget, const St void GroupDialog_showPage(GtkWidget* page); void GroupDialog_updatePageTitle(GtkWidget* page); +bool GroupDialog_isShown(); +GtkWidget* GroupDialog_getPage(); #endif diff --git a/misc/source/netradiant-src/radiant/mainframe.cpp b/misc/source/netradiant-src/radiant/mainframe.cpp index c8a739b6..546ba9d7 100644 --- a/misc/source/netradiant-src/radiant/mainframe.cpp +++ b/misc/source/netradiant-src/radiant/mainframe.cpp @@ -184,22 +184,88 @@ void VFS_Destroy() // Home Paths +#ifdef WIN32 +#include +#include +const GUID qFOLDERID_SavedGames = {0x4C5C32FF, 0xBB9D, 0x43b0, {0xB5, 0xB4, 0x2D, 0x72, 0xE5, 0x4E, 0xAA, 0xA4}}; +#define qREFKNOWNFOLDERID GUID +#define qKF_FLAG_CREATE 0x8000 +#define qKF_FLAG_NO_ALIAS 0x1000 +typedef HRESULT (WINAPI qSHGetKnownFolderPath_t) (qREFKNOWNFOLDERID rfid, DWORD dwFlags, HANDLE hToken, PWSTR *ppszPath); +static qSHGetKnownFolderPath_t *qSHGetKnownFolderPath; +#endif void HomePaths_Realise() { -#if defined(POSIX) - const char* prefix = g_pGameDescription->getKeyValue("prefix"); - if(!string_empty(prefix)) + do { - StringOutputStream path(256); - path << DirectoryCleaned(g_get_home_dir()) << prefix << "/"; - g_qeglobals.m_userEnginePath = path.c_str(); - Q_mkdir(g_qeglobals.m_userEnginePath.c_str()); - } - else + const char* prefix = g_pGameDescription->getKeyValue("prefix"); + if(!string_empty(prefix)) + { + StringOutputStream path(256); + +#if defined(__APPLE__) + path.clear(); + path << DirectoryCleaned(g_get_home_dir()) << "Library/Application Support" << (prefix+1) << "/"; + if(file_is_directory(path.c_str())) + { + g_qeglobals.m_userEnginePath = path.c_str(); + break; + } #endif - { + +#if defined(WIN32) + TCHAR mydocsdir[MAX_PATH + 1]; + wchar_t *mydocsdirw; + HMODULE shfolder = LoadLibrary("shfolder.dll"); + if(shfolder) + qSHGetKnownFolderPath = (qSHGetKnownFolderPath_t *) GetProcAddress(shfolder, "SHGetKnownFolderPath"); + else + qSHGetKnownFolderPath = NULL; + CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); + if(qSHGetKnownFolderPath && qSHGetKnownFolderPath(qFOLDERID_SavedGames, qKF_FLAG_CREATE | qKF_FLAG_NO_ALIAS, NULL, &mydocsdirw) == S_OK) + { + memset(mydocsdir, 0, sizeof(mydocsdir)); + wcstombs(mydocsdir, mydocsdirw, sizeof(mydocsdir)-1); + CoTaskMemFree(mydocsdirw); + path.clear(); + path << DirectoryCleaned(mydocsdir) << (prefix+1) << "/"; + if(file_is_directory(path.c_str())) + { + g_qeglobals.m_userEnginePath = path.c_str(); + CoUninitialize(); + FreeLibrary(shfolder); + break; + } + } + CoUninitialize(); + if(shfolder) + FreeLibrary(shfolder); + if(SHGetFolderPath(NULL, CSIDL_PERSONAL, NULL, 0, mydocsdir)) + { + path.clear(); + path << DirectoryCleaned(mydocsdir) << "My Games/" << (prefix+1) << "/"; + // win32: only add it if it already exists + if(file_is_directory(path.c_str())) + { + g_qeglobals.m_userEnginePath = path.c_str(); + break; + } + } +#endif + +#if defined(POSIX) + path.clear(); + path << DirectoryCleaned(g_get_home_dir()) << prefix << "/"; + g_qeglobals.m_userEnginePath = path.c_str(); + break; +#endif + } + g_qeglobals.m_userEnginePath = EnginePath_get(); } + while(0); + + Q_mkdir(g_qeglobals.m_userEnginePath.c_str()); { StringOutputStream path(256); diff --git a/misc/source/netradiant-src/radiant/mainframe.h b/misc/source/netradiant-src/radiant/mainframe.h index 5997abd3..d011f319 100644 --- a/misc/source/netradiant-src/radiant/mainframe.h +++ b/misc/source/netradiant-src/radiant/mainframe.h @@ -283,4 +283,6 @@ void XYWindowDestroyed_disconnect(SignalHandlerId id); MouseEventHandlerId XYWindowMouseDown_connect(const MouseEventHandler& handler); void XYWindowMouseDown_disconnect(MouseEventHandlerId id); +extern GtkWidget* g_page_entity; + #endif diff --git a/misc/source/netradiant-src/radiant/map.cpp b/misc/source/netradiant-src/radiant/map.cpp index 57245990..ec412965 100644 --- a/misc/source/netradiant-src/radiant/map.cpp +++ b/misc/source/netradiant-src/radiant/map.cpp @@ -1690,6 +1690,8 @@ tryDecompile: output.push_string((type && *type) ? type : "quake3"); output.push_string(" -fs_basepath \""); output.push_string(EnginePath_get()); + output.push_string(" -fs_homepath \""); + output.push_string(g_qeglobals.m_userEnginePath.c_str()); output.push_string("\" -fs_game "); output.push_string(gamename_get()); output.push_string(" -convert -format "); diff --git a/misc/source/netradiant-src/radiant/qe3.cpp b/misc/source/netradiant-src/radiant/qe3.cpp index 67ffebec..19d1d37c 100644 --- a/misc/source/netradiant-src/radiant/qe3.cpp +++ b/misc/source/netradiant-src/radiant/qe3.cpp @@ -78,22 +78,19 @@ void QE_InitVFS() const char* gamename = gamename_get(); const char* basegame = basegame_get(); -#if defined(POSIX) const char* userRoot = g_qeglobals.m_userEnginePath.c_str(); -#endif const char* globalRoot = EnginePath_get(); // if we have a mod dir if(!string_equal(gamename, basegame)) { -#if defined(POSIX) // ~/./ + if(userRoot) { StringOutputStream userGamePath(256); userGamePath << userRoot << gamename << '/'; GlobalFileSystem().initDirectory(userGamePath.c_str()); } -#endif // / { @@ -103,14 +100,13 @@ void QE_InitVFS() } } -#if defined(POSIX) // ~/./ + if(userRoot) { StringOutputStream userBasePath(256); userBasePath << userRoot << basegame << '/'; GlobalFileSystem().initDirectory(userBasePath.c_str()); } -#endif // / { @@ -175,6 +171,7 @@ void bsp_init() build_set_variable("RadiantPath", AppPath_get()); build_set_variable("ExecutableType", RADIANT_EXECUTABLE); build_set_variable("EnginePath", EnginePath_get()); + build_set_variable("UserEnginePath", g_qeglobals.m_userEnginePath.c_str()); build_set_variable("MonitorAddress", (g_WatchBSP_Enabled) ? "127.0.0.1:39000" : ""); build_set_variable("GameName", gamename_get()); diff --git a/misc/source/netradiant-src/radiant/select.cpp b/misc/source/netradiant-src/radiant/select.cpp index 5889fd5a..f4e8b7f9 100644 --- a/misc/source/netradiant-src/radiant/select.cpp +++ b/misc/source/netradiant-src/radiant/select.cpp @@ -47,6 +47,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #include "mainframe.h" #include "grid.h" #include "map.h" +#include "entityinspector.h" @@ -289,13 +290,16 @@ void Select_Delete (void) class InvertSelectionWalker : public scene::Graph::Walker { SelectionSystem::EMode m_mode; - mutable Selectable* m_selectable; public: InvertSelectionWalker(SelectionSystem::EMode mode) - : m_mode(mode), m_selectable(0) + : m_mode(mode) { } bool pre(const scene::Path& path, scene::Instance& instance) const + { + return true; + } + void post(const scene::Path& path, scene::Instance& instance) const { Selectable* selectable = Instance_getSelectable(instance); if(selectable) @@ -304,26 +308,17 @@ public: { case SelectionSystem::eEntity: if(Node_isEntity(path.top()) != 0) - { - m_selectable = path.top().get().visible() ? selectable : 0; - } + if(path.top().get().visible()) + selectable->setSelected(!selectable->isSelected()); break; case SelectionSystem::ePrimitive: - m_selectable = path.top().get().visible() ? selectable : 0; + if(path.top().get().visible()) + selectable->setSelected(!selectable->isSelected()); break; case SelectionSystem::eComponent: break; } } - return true; - } - void post(const scene::Path& path, scene::Instance& instance) const - { - if(m_selectable != 0) - { - m_selectable->setSelected(!m_selectable->isSelected()); - m_selectable = 0; - } } }; @@ -658,13 +653,13 @@ void FindReplaceTextures(const char* pFind, const char* pReplace, bool bSelected } } -typedef std::vector Classnames; +typedef std::vector PropertyValues; -bool classnames_match_entity(const Classnames& classnames, Entity* entity) +bool propertyvalues_contain(const PropertyValues& propertyvalues, const char *str) { - for(Classnames::const_iterator i = classnames.begin(); i != classnames.end(); ++i) + for(PropertyValues::const_iterator i = propertyvalues.begin(); i != propertyvalues.end(); ++i) { - if(string_equal(entity->getKeyValue("classname"), *i)) + if(string_equal(str, *i)) { return true; } @@ -672,19 +667,20 @@ bool classnames_match_entity(const Classnames& classnames, Entity* entity) return false; } -class EntityFindByClassnameWalker : public scene::Graph::Walker +class EntityFindByPropertyValueWalker : public scene::Graph::Walker { - const Classnames& m_classnames; + const PropertyValues& m_propertyvalues; + const char *m_prop; public: - EntityFindByClassnameWalker(const Classnames& classnames) - : m_classnames(classnames) + EntityFindByPropertyValueWalker(const char *prop, const PropertyValues& propertyvalues) + : m_propertyvalues(propertyvalues), m_prop(prop) { } bool pre(const scene::Path& path, scene::Instance& instance) const { Entity* entity = Node_getEntity(path.top()); if(entity != 0 - && classnames_match_entity(m_classnames, entity)) + && propertyvalues_contain(m_propertyvalues, entity->getKeyValue(m_prop))) { Instance_getSelectable(instance)->setSelected(true); } @@ -692,17 +688,18 @@ public: } }; -void Scene_EntitySelectByClassnames(scene::Graph& graph, const Classnames& classnames) +void Scene_EntitySelectByPropertyValues(scene::Graph& graph, const char *prop, const PropertyValues& propertyvalues) { - graph.traverse(EntityFindByClassnameWalker(classnames)); + graph.traverse(EntityFindByPropertyValueWalker(prop, propertyvalues)); } -class EntityGetSelectedClassnamesWalker : public scene::Graph::Walker +class EntityGetSelectedPropertyValuesWalker : public scene::Graph::Walker { - Classnames& m_classnames; + PropertyValues& m_propertyvalues; + const char *m_prop; public: - EntityGetSelectedClassnamesWalker(Classnames& classnames) - : m_classnames(classnames) + EntityGetSelectedPropertyValuesWalker(const char *prop, PropertyValues& propertyvalues) + : m_propertyvalues(propertyvalues), m_prop(prop) { } bool pre(const scene::Path& path, scene::Instance& instance) const @@ -714,16 +711,17 @@ public: Entity* entity = Node_getEntity(path.top()); if(entity != 0) { - m_classnames.push_back(entity->getKeyValue("classname")); + if(!propertyvalues_contain(m_propertyvalues, entity->getKeyValue(m_prop))) + m_propertyvalues.push_back(entity->getKeyValue(m_prop)); } } return true; } }; -void Scene_EntityGetClassnames(scene::Graph& graph, Classnames& classnames) +void Scene_EntityGetPropertyValues(scene::Graph& graph, const char *prop, PropertyValues& propertyvalues) { - graph.traverse(EntityGetSelectedClassnamesWalker(classnames)); + graph.traverse(EntityGetSelectedPropertyValuesWalker(prop, propertyvalues)); } void Select_AllOfType() @@ -738,12 +736,15 @@ void Select_AllOfType() } else { - Classnames classnames; - Scene_EntityGetClassnames(GlobalSceneGraph(), classnames); + PropertyValues propertyvalues; + const char *prop = EntityInspector_getCurrentKey(); + if(!prop || !*prop) + prop = "classname"; + Scene_EntityGetPropertyValues(GlobalSceneGraph(), prop, propertyvalues); GlobalSelectionSystem().setSelectedAll(false); - if(!classnames.empty()) + if(!propertyvalues.empty()) { - Scene_EntitySelectByClassnames(GlobalSceneGraph(), classnames); + Scene_EntitySelectByPropertyValues(GlobalSceneGraph(), prop, propertyvalues); } else { diff --git a/misc/source/netradiant-src/radiant/selection.cpp b/misc/source/netradiant-src/radiant/selection.cpp index 3b477990..d2283d45 100644 --- a/misc/source/netradiant-src/radiant/selection.cpp +++ b/misc/source/netradiant-src/radiant/selection.cpp @@ -3872,7 +3872,9 @@ const ModifierFlags c_modifier_toggle_face = c_modifier_toggle | c_modifier_face const ModifierFlags c_modifier_replace_face = c_modifier_replace | c_modifier_face; const ButtonIdentifier c_button_texture = c_buttonMiddle; -const ModifierFlags c_modifier_apply_texture = c_modifierControl | c_modifierShift; +const ModifierFlags c_modifier_apply_texture1 = c_modifierControl | c_modifierShift; +const ModifierFlags c_modifier_apply_texture2 = c_modifierControl; +const ModifierFlags c_modifier_apply_texture3 = c_modifierShift; const ModifierFlags c_modifier_copy_texture = c_modifierNone; class Selector_ @@ -4094,7 +4096,7 @@ public: ConstructSelectionTest(scissored, SelectionBoxForPoint(&devicePosition[0], &m_selector.m_epsilon[0])); SelectionVolume volume(scissored); - if(modifiers == c_modifier_apply_texture) + if(modifiers == c_modifier_apply_texture1 || modifiers == c_modifier_apply_texture2 || modifiers == c_modifier_apply_texture3) { Scene_applyClosestTexture(volume); } diff --git a/misc/source/netradiant-src/tools/quake3/common/imagelib.c b/misc/source/netradiant-src/tools/quake3/common/imagelib.c index 31e31850..b95fe971 100644 --- a/misc/source/netradiant-src/tools/quake3/common/imagelib.c +++ b/misc/source/netradiant-src/tools/quake3/common/imagelib.c @@ -678,7 +678,6 @@ void LoadBMP (const char *filename, byte **pic, byte **palette, int *width, int { byte *out; int i; - int bfSize; int bfOffBits; int structSize; int bcWidth; @@ -701,7 +700,7 @@ void LoadBMP (const char *filename, byte **pic, byte **palette, int *width, int Error ("%s is not a bmp file", filename); } - bfSize = bufLittleLong (in, len, &pos); + /* bfSize = */ bufLittleLong (in, len, &pos); bufLittleShort(in, len, &pos); bufLittleShort(in, len, &pos); bfOffBits = bufLittleLong (in, len, &pos); diff --git a/misc/source/netradiant-src/tools/quake3/common/scriplib.c b/misc/source/netradiant-src/tools/quake3/common/scriplib.c index 47196e53..5502d35a 100644 --- a/misc/source/netradiant-src/tools/quake3/common/scriplib.c +++ b/misc/source/netradiant-src/tools/quake3/common/scriplib.c @@ -296,12 +296,11 @@ Returns qtrue if there is another token on the line ============== */ qboolean TokenAvailable (void) { - int oldLine, oldScriptLine; + int oldLine; qboolean r; /* save */ oldLine = scriptline; - oldScriptLine = script->line; /* test */ r = GetToken( qtrue ); diff --git a/misc/source/netradiant-src/tools/quake3/common/vfs.c b/misc/source/netradiant-src/tools/quake3/common/vfs.c index 86a749c7..9c75cb3a 100644 --- a/misc/source/netradiant-src/tools/quake3/common/vfs.c +++ b/misc/source/netradiant-src/tools/quake3/common/vfs.c @@ -46,6 +46,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include #include "cmdlib.h" +#include "filematch.h" #include "mathlib.h" #include "inout.h" #include "vfs.h" @@ -160,9 +161,17 @@ void vfsInitDirectory (const char *path) for(j = 0; j < g_numForbiddenDirs; ++j) { - if(!Q_stricmp(path, g_strForbiddenDirs[j]) - || (strlen(path) > strlen(g_strForbiddenDirs[j]) && path[strlen(path) - strlen(g_strForbiddenDirs[j]) - 1] == '/' && !Q_stricmp(path + strlen(path) - strlen(g_strForbiddenDirs[j]), g_strForbiddenDirs[j]))) + char* dbuf = g_strdup(path); + if(*dbuf && dbuf[strlen(dbuf)-1] == '/') + dbuf[strlen(dbuf)-1] = 0; + const char *p = strrchr(dbuf, '/'); + p = (p ? (p+1) : dbuf); + if(matchpattern(p, g_strForbiddenDirs[j], TRUE)) + { + g_free(dbuf); break; + } + g_free(dbuf); } if(j < g_numForbiddenDirs) return; @@ -191,8 +200,12 @@ void vfsInitDirectory (const char *path) break; for(j = 0; j < g_numForbiddenDirs; ++j) - if(!Q_stricmp(name, g_strForbiddenDirs[j])) + { + const char *p = strrchr(name, '/'); + p = (p ? (p+1) : name); + if(matchpattern(p, g_strForbiddenDirs[j], TRUE)) break; + } if(j < g_numForbiddenDirs) continue; diff --git a/misc/source/netradiant-src/tools/quake3/q3map2/convert_ase.c b/misc/source/netradiant-src/tools/quake3/q3map2/convert_ase.c index 56262311..f16a9d08 100644 --- a/misc/source/netradiant-src/tools/quake3/q3map2/convert_ase.c +++ b/misc/source/netradiant-src/tools/quake3/q3map2/convert_ase.c @@ -165,7 +165,7 @@ static void ConvertSurface( FILE *f, bspModel_t *model, int modelNum, bspDrawSur fprintf( f, "\t*PROP_RECVSHADOW\t1\r\n" ); if(lightmapsAsTexcoord) { - if(ds->lightmapNum[0] >= 0 && ds->lightmapNum[0] + deluxemap < numLightmapsASE) + if(ds->lightmapNum[0] >= 0 && ds->lightmapNum[0] + (int)deluxemap < numLightmapsASE) fprintf( f, "\t*MATERIAL_REF\t%d\r\n", ds->lightmapNum[0] + deluxemap ); else Sys_Printf( "WARNING: lightmap %d out of range, not exporting\n", ds->lightmapNum[0] + deluxemap ); diff --git a/misc/source/netradiant-src/tools/quake3/q3map2/convert_map.c b/misc/source/netradiant-src/tools/quake3/q3map2/convert_map.c index 0f37665d..418ee27a 100644 --- a/misc/source/netradiant-src/tools/quake3/q3map2/convert_map.c +++ b/misc/source/netradiant-src/tools/quake3/q3map2/convert_map.c @@ -215,11 +215,9 @@ static void ConvertBrush( FILE *f, int num, bspBrush_t *brush, vec3_t origin, qb side_t *buildSide; bspShader_t *shader; char *texture; - bspPlane_t *plane; plane_t *buildPlane; vec3_t pts[ 3 ]; bspDrawVert_t *vert[3]; - int valid; /* start brush */ @@ -256,9 +254,6 @@ static void ConvertBrush( FILE *f, int num, bspBrush_t *brush, vec3_t origin, qb //if( !Q_stricmp( shader->shader, "default" ) || !Q_stricmp( shader->shader, "noshader" ) ) // continue; - /* get plane */ - plane = &bspPlanes[ side->planeNum ]; - /* add build side */ buildSide = &buildBrush->sides[ buildBrush->numsides ]; buildBrush->numsides++; @@ -300,7 +295,6 @@ static void ConvertBrush( FILE *f, int num, bspBrush_t *brush, vec3_t origin, qb // - (triangles) // - find the triangle that has most in common with our side GetBestSurfaceTriangleMatchForBrushside(buildSide, vert); - valid = 0; /* get texture name */ if( !Q_strncasecmp( buildSide->shaderInfo->shader, "textures/", 9 ) ) @@ -369,7 +363,6 @@ static void ConvertBrush( FILE *f, int num, bspBrush_t *brush, vec3_t origin, qb ); VectorSet(buildSide->texMat[i], D0 / D, D1 / D, D2 / D); } - valid = 1; } else fprintf(stderr, "degenerate triangle found when solving texMat equations for\n(%f %f %f) (%f %f %f) (%f %f %f)\n( %f %f %f )\n( %f %f %f ) -> ( %f %f )\n( %f %f %f ) -> ( %f %f )\n( %f %f %f ) -> ( %f %f )\n", @@ -390,7 +383,6 @@ static void ConvertBrush( FILE *f, int num, bspBrush_t *brush, vec3_t origin, qb buildSide->texMat[0][0], buildSide->texMat[0][1], FRAC(buildSide->texMat[0][2]), buildSide->texMat[1][0], buildSide->texMat[1][1], FRAC(buildSide->texMat[1][2]), texture, - // DEBUG: valid ? 0 : C_DETAIL 0 ); } @@ -450,7 +442,6 @@ static void ConvertBrush( FILE *f, int num, bspBrush_t *brush, vec3_t origin, qb ); VectorSet(sts[i], D0 / D, D1 / D, D2 / D); } - valid = 1; } else fprintf(stderr, "degenerate triangle found when solving texDef equations\n"); // FIXME add stuff here @@ -482,7 +473,6 @@ static void ConvertBrush( FILE *f, int num, bspBrush_t *brush, vec3_t origin, qb pts[ 2 ][ 0 ], pts[ 2 ][ 1 ], pts[ 2 ][ 2 ], texture, shift[0], shift[1], rotate, scale[0], scale[1], - // DEBUG: valid ? 0 : C_DETAIL 0 ); } @@ -511,7 +501,6 @@ static void ConvertBrush( FILE *f, int num, bspBrush_t *brush, vec3_t origin, qb 1.0f/16.0f, 0.0f, 0.0f, 0.0f, 1.0f/16.0f, 0.0f, texture, - // DEBUG: valid ? 0 : C_DETAIL 0 ); } @@ -523,7 +512,6 @@ static void ConvertBrush( FILE *f, int num, bspBrush_t *brush, vec3_t origin, qb pts[ 2 ][ 0 ], pts[ 2 ][ 1 ], pts[ 2 ][ 2 ], texture, 0.0f, 0.0f, 0.0f, 0.25f, 0.25f, - // DEBUG: valid ? 0 : C_DETAIL 0 ); } diff --git a/misc/source/netradiant-src/tools/quake3/q3map2/convert_obj.c b/misc/source/netradiant-src/tools/quake3/q3map2/convert_obj.c index 08e75e11..15c1e06c 100644 --- a/misc/source/netradiant-src/tools/quake3/q3map2/convert_obj.c +++ b/misc/source/netradiant-src/tools/quake3/q3map2/convert_obj.c @@ -51,7 +51,7 @@ int objVertexCount = 0; int objLastShaderNum = -1; static void ConvertSurfaceToOBJ( FILE *f, bspModel_t *model, int modelNum, bspDrawSurface_t *ds, int surfaceNum, vec3_t origin ) { - int i, v, face, a, b, c; + int i, v, a, b, c; bspDrawVert_t *dv; /* ignore patches for now */ @@ -77,7 +77,7 @@ static void ConvertSurfaceToOBJ( FILE *f, bspModel_t *model, int modelNum, bspDr fprintf(f, "usemtl lm_%04d\r\n", ds->lightmapNum[0] + deluxemap); objLastShaderNum = ds->lightmapNum[0] + deluxemap; } - if(ds->lightmapNum[0] + deluxemap < firstLightmap) + if(ds->lightmapNum[0] + (int)deluxemap < firstLightmap) { Sys_Printf( "WARNING: lightmap %d out of range (exporting anyway)\n", ds->lightmapNum[0] + deluxemap ); firstLightmap = ds->lightmapNum[0] + deluxemap; @@ -114,7 +114,6 @@ static void ConvertSurfaceToOBJ( FILE *f, bspModel_t *model, int modelNum, bspDr /* export faces */ for( i = 0; i < ds->numIndexes; i += 3 ) { - face = (i / 3); a = bspDrawIndexes[ i + ds->firstIndex ]; c = bspDrawIndexes[ i + ds->firstIndex + 1 ]; b = bspDrawIndexes[ i + ds->firstIndex + 2 ]; @@ -160,7 +159,7 @@ exports a bsp shader to an ase chunk static void ConvertShaderToMTL( FILE *f, bspShader_t *shader, int shaderNum ) { shaderInfo_t *si; - char *c, filename[ 1024 ]; + char filename[ 1024 ]; /* get shader */ diff --git a/misc/source/netradiant-src/tools/quake3/q3map2/facebsp.c b/misc/source/netradiant-src/tools/quake3/q3map2/facebsp.c index 9291f564..f9f2f207 100644 --- a/misc/source/netradiant-src/tools/quake3/q3map2/facebsp.c +++ b/misc/source/netradiant-src/tools/quake3/q3map2/facebsp.c @@ -244,7 +244,9 @@ void BuildFaceTree_r( node_t *node, face_t *list ) winding_t *frontWinding, *backWinding; int i; int splitPlaneNum, compileFlags; +#if 0 qboolean isstruct = qfalse; +#endif /* count faces left */ @@ -282,8 +284,10 @@ void BuildFaceTree_r( node_t *node, face_t *list ) continue; } +#if 0 if(!(split->compileFlags & C_DETAIL)) isstruct = 1; +#endif /* determine which side the face falls on */ side = WindingOnPlaneSide( split->w, plane->normal, plane->dist ); diff --git a/misc/source/netradiant-src/tools/quake3/q3map2/image.c b/misc/source/netradiant-src/tools/quake3/q3map2/image.c index 929b15d9..7ce08aaa 100644 --- a/misc/source/netradiant-src/tools/quake3/q3map2/image.c +++ b/misc/source/netradiant-src/tools/quake3/q3map2/image.c @@ -127,7 +127,7 @@ static void LoadPNGBuffer( byte *buffer, int size, byte **pixels, int *width, in png_struct *png; png_info *info, *end; pngBuffer_t pb; - int bitDepth, colorType, channels; + int bitDepth, colorType; png_uint_32 w, h, i; byte **rowPointers; @@ -196,9 +196,6 @@ static void LoadPNGBuffer( byte *buffer, int size, byte **pixels, int *width, in png_get_IHDR( png, info, &w, &h, &bitDepth, &colorType, NULL, NULL, NULL ); - /* read number of channels */ - channels = png_get_channels( png, info ); - /* the following will probably bork on certain types of png images, but hey... */ /* force indexed/gray/trans chunk to rgb */ diff --git a/misc/source/netradiant-src/tools/quake3/q3map2/light.c b/misc/source/netradiant-src/tools/quake3/q3map2/light.c index 9323b8c8..5d5dfc5e 100644 --- a/misc/source/netradiant-src/tools/quake3/q3map2/light.c +++ b/misc/source/netradiant-src/tools/quake3/q3map2/light.c @@ -148,7 +148,6 @@ static void CreateSkyLights( vec3_t color, float value, int iterations, float fi int angleSteps, elevationSteps; float angle, elevation; float angleStep, elevationStep; - float step, start; sun_t sun; @@ -156,10 +155,6 @@ static void CreateSkyLights( vec3_t color, float value, int iterations, float fi if( value <= 0.0f || iterations < 2 ) return; - /* calculate some stuff */ - step = 2.0f / (iterations - 1); - start = -1.0f; - /* basic sun setup */ VectorCopy( color, sun.color ); sun.deviance = 0.0f; diff --git a/misc/source/netradiant-src/tools/quake3/q3map2/light_bounce.c b/misc/source/netradiant-src/tools/quake3/q3map2/light_bounce.c index 7db00613..0e59ddeb 100644 --- a/misc/source/netradiant-src/tools/quake3/q3map2/light_bounce.c +++ b/misc/source/netradiant-src/tools/quake3/q3map2/light_bounce.c @@ -626,14 +626,12 @@ void RadLightForTriangles( int num, int lightmapNum, rawLightmap_t *lm, shaderIn { int i, j, k, v; bspDrawSurface_t *ds; - surfaceInfo_t *info; float *radVertexLuxel; radWinding_t rw; /* get surface */ ds = &bspDrawSurfaces[ num ]; - info = &surfaceInfos[ num ]; /* each triangle is a potential emitter */ rw.numVerts = 3; diff --git a/misc/source/netradiant-src/tools/quake3/q3map2/light_trace.c b/misc/source/netradiant-src/tools/quake3/q3map2/light_trace.c index 8e79244e..84e4ab0e 100644 --- a/misc/source/netradiant-src/tools/quake3/q3map2/light_trace.c +++ b/misc/source/netradiant-src/tools/quake3/q3map2/light_trace.c @@ -1220,7 +1220,11 @@ static void PopulateTraceNodes( void ) /* external model */ default: - frame = IntForKey( e, "_frame" ); + frame = 0; + if(strcmp("", ValueForKey( e, "_frame"))) + frame = IntForKey(e, "_frame"); + else if(strcmp("", ValueForKey( e, "frame"))) + frame = IntForKey(e, "frame"); model = LoadModel( value, frame ); if( model == NULL ) continue; diff --git a/misc/source/netradiant-src/tools/quake3/q3map2/light_ydnar.c b/misc/source/netradiant-src/tools/quake3/q3map2/light_ydnar.c index f60e6645..f291e7a5 100644 --- a/misc/source/netradiant-src/tools/quake3/q3map2/light_ydnar.c +++ b/misc/source/netradiant-src/tools/quake3/q3map2/light_ydnar.c @@ -1788,7 +1788,7 @@ static void SubsampleRawLuxel_r( rawLightmap_t *lm, trace_t *trace, vec3_t sampl vec3_t deluxel[ 3 ]; vec3_t origin[ 4 ], normal[ 4 ]; float biasDirs[ 4 ][ 2 ] = { { -1.0f, -1.0f }, { 1.0f, -1.0f }, { -1.0f, 1.0f }, { 1.0f, 1.0f } }; - vec3_t color, direction, total; + vec3_t color, direction = { 0, 0, 0 }, total; /* limit check */ @@ -3204,7 +3204,7 @@ determines if two clusters are visible to each other using the PVS qboolean ClusterVisible( int a, int b ) { - int portalClusters, leafBytes; + int leafBytes; byte *pvs; @@ -3221,7 +3221,7 @@ qboolean ClusterVisible( int a, int b ) return qtrue; /* get pvs data */ - portalClusters = ((int *) bspVisBytes)[ 0 ]; + /* portalClusters = ((int *) bspVisBytes)[ 0 ]; */ leafBytes = ((int*) bspVisBytes)[ 1 ]; pvs = bspVisBytes + VIS_HEADER_SIZE + (a * leafBytes); @@ -4052,7 +4052,7 @@ void SetupFloodLight( void ) v5=floodlightIntensity; v6=floodlightDirectionScale; - sscanf( value, "%lf %lf %lf %lf %lf %lf", &v1, &v2, &v3, &v4, &v5); + sscanf( value, "%lf %lf %lf %lf %lf %lf", &v1, &v2, &v3, &v4, &v5, &v6); floodlightRGB[0]=v1; floodlightRGB[1]=v2; diff --git a/misc/source/netradiant-src/tools/quake3/q3map2/lightmaps_ydnar.c b/misc/source/netradiant-src/tools/quake3/q3map2/lightmaps_ydnar.c index 080f26ec..5c534053 100644 --- a/misc/source/netradiant-src/tools/quake3/q3map2/lightmaps_ydnar.c +++ b/misc/source/netradiant-src/tools/quake3/q3map2/lightmaps_ydnar.c @@ -593,10 +593,10 @@ based on AllocateLightmapForSurface() qboolean AddSurfaceToRawLightmap( int num, rawLightmap_t *lm ) { bspDrawSurface_t *ds, *ds2; - surfaceInfo_t *info, *info2; + surfaceInfo_t *info; int num2, n, i, axisNum; float s, t, d, len, sampleSize; - vec3_t mins, maxs, origin, faxis, size, exactSize, delta, normalized, vecs[ 2 ]; + vec3_t mins, maxs, origin, faxis, size, delta, normalized, vecs[ 2 ]; vec4_t plane; bspDrawVert_t *verts; @@ -672,7 +672,6 @@ qboolean AddSurfaceToRawLightmap( int num, rawLightmap_t *lm ) /* round to the lightmap resolution */ for( i = 0; i < 3; i++ ) { - exactSize[ i ] = lm->maxs[ i ] - lm->mins[ i ]; mins[ i ] = sampleSize * floor( lm->mins[ i ] / sampleSize ); maxs[ i ] = sampleSize * ceil( lm->maxs[ i ] / sampleSize ); size[ i ] = (maxs[ i ] - mins[ i ]) / sampleSize + 1.0f; @@ -763,7 +762,6 @@ qboolean AddSurfaceToRawLightmap( int num, rawLightmap_t *lm ) /* get surface */ num2 = lightSurfaces[ lm->firstLightSurface + n ]; ds2 = &bspDrawSurfaces[ num2 ]; - info2 = &surfaceInfos[ num2 ]; verts = &yDrawVerts[ ds2->firstVert ]; /* set the lightmap texture coordinates in yDrawVerts in [0, superSample * lm->customWidth] space */ @@ -786,7 +784,6 @@ qboolean AddSurfaceToRawLightmap( int num, rawLightmap_t *lm ) /* get first drawsurface */ num2 = lightSurfaces[ lm->firstLightSurface ]; ds2 = &bspDrawSurfaces[ num2 ]; - info2 = &surfaceInfos[ num2 ]; verts = &yDrawVerts[ ds2->firstVert ]; /* calculate lightmap origin */ @@ -940,7 +937,7 @@ void SetupSurfaceLightmaps( void ) int i, j, k, s,num, num2; bspModel_t *model; bspLeaf_t *leaf; - bspDrawSurface_t *ds, *ds2; + bspDrawSurface_t *ds; surfaceInfo_t *info, *info2; rawLightmap_t *lm; qboolean added; @@ -1154,7 +1151,6 @@ void SetupSurfaceLightmaps( void ) { /* get info and attempt early out */ num2 = sortSurfaces[ j ]; - ds2 = &bspDrawSurfaces[ num2 ]; info2 = &surfaceInfos[ num2 ]; if( info2->hasLightmap == qfalse || info2->lm != NULL ) continue; @@ -1215,7 +1211,7 @@ void StitchSurfaceLightmaps( void ) numStitched, numCandidates, numLuxels, f, fOld, start; rawLightmap_t *lm, *a, *b, *c[ MAX_STITCH_CANDIDATES ]; float *luxel, *luxel2, *origin, *origin2, *normal, *normal2, - sampleSize, average[ 3 ], totalColor, ootc, *luxels[ MAX_STITCH_LUXELS ]; + sampleSize, average[ 3 ], totalColor, ootc; /* disabled for now */ @@ -1330,7 +1326,6 @@ void StitchSurfaceLightmaps( void ) /* add luxel */ //% VectorSet( luxel2, 255, 0, 255 ); - luxels[ numLuxels++ ] = luxel2; VectorAdd( average, luxel2, average ); totalColor += luxel2[ 3 ]; } @@ -1921,7 +1916,7 @@ for a given surface lightmap, find output lightmap pages and positions for it #define LIGHTMAP_RESERVE_COUNT 1 static void FindOutLightmaps( rawLightmap_t *lm ) { - int i, j, k, lightmapNum, xMax, yMax, x, y, sx, sy, ox, oy, offset; + int i, j, k, lightmapNum, xMax, yMax, x = -1, y = -1, sx, sy, ox, oy, offset; outLightmap_t *olm; surfaceInfo_t *info; float *luxel, *deluxel; diff --git a/misc/source/netradiant-src/tools/quake3/q3map2/main.c b/misc/source/netradiant-src/tools/quake3/q3map2/main.c index 074a4a43..5ee35cd5 100644 --- a/misc/source/netradiant-src/tools/quake3/q3map2/main.c +++ b/misc/source/netradiant-src/tools/quake3/q3map2/main.c @@ -989,7 +989,7 @@ int AnalyzeBSP( int argc, char **argv ) lump = (byte*) header + offset; lumpInt = LittleLong( (int) *((int*) lump) ); lumpFloat = LittleFloat( (float) *((float*) lump) ); - memcpy( lumpString, (char*) lump, (length < sizeof(lumpString) ? length : sizeof(lumpString)-1) ); + memcpy( lumpString, (char*) lump, ((size_t)length < sizeof(lumpString) ? (size_t)length : sizeof(lumpString)-1) ); lumpString[ sizeof(lumpString)-1 ] = '\0'; /* print basic lump info */ diff --git a/misc/source/netradiant-src/tools/quake3/q3map2/map.c b/misc/source/netradiant-src/tools/quake3/q3map2/map.c index 95bb3d1f..9534bdb3 100644 --- a/misc/source/netradiant-src/tools/quake3/q3map2/map.c +++ b/misc/source/netradiant-src/tools/quake3/q3map2/map.c @@ -490,7 +490,7 @@ void SetBrushContents( brush_t *b ) int contentFlags, compileFlags; side_t *s; int i; - qboolean mixed; + //% qboolean mixed; /* get initial compile flags from first side */ @@ -498,7 +498,7 @@ void SetBrushContents( brush_t *b ) contentFlags = s->contentFlags; compileFlags = s->compileFlags; b->contentShader = s->shaderInfo; - mixed = qfalse; + //% mixed = qfalse; /* get the content/compile flags for every side in the brush */ for( i = 1; i < b->numsides; i++, s++ ) @@ -506,8 +506,8 @@ void SetBrushContents( brush_t *b ) s = &b->sides[ i ]; if( s->shaderInfo == NULL ) continue; - if( s->contentFlags != contentFlags || s->compileFlags != compileFlags ) - mixed = qtrue; + //% if( s->contentFlags != contentFlags || s->compileFlags != compileFlags ) + //% mixed = qtrue; contentFlags |= s->contentFlags; compileFlags |= s->compileFlags; @@ -1196,9 +1196,6 @@ parses a brush out of a map file and sets it up static void ParseBrush( qboolean onlyLights, qboolean noCollapseGroups ) { - brush_t *b; - - /* parse the brush out of the map */ ParseRawBrush( onlyLights ); @@ -1241,7 +1238,7 @@ static void ParseBrush( qboolean onlyLights, qboolean noCollapseGroups ) } /* finish the brush */ - b = FinishBrush(noCollapseGroups); + FinishBrush(noCollapseGroups); } diff --git a/misc/source/netradiant-src/tools/quake3/q3map2/model.c b/misc/source/netradiant-src/tools/quake3/q3map2/model.c index a56134c8..2b3bb7ed 100644 --- a/misc/source/netradiant-src/tools/quake3/q3map2/model.c +++ b/misc/source/netradiant-src/tools/quake3/q3map2/model.c @@ -208,7 +208,7 @@ adds a picomodel into the bsp void InsertModel( const char *name, int skin, int frame, m4x4_t transform, remap_t *remap, shaderInfo_t *celShader, int eNum, int castShadows, int recvShadows, int spawnFlags, float lightmapScale, int lightmapSampleSize, float shadeAngle ) { - int i, j, k, s, numSurfaces; + int i, j, s, numSurfaces; m4x4_t identity, nTransform; picoModel_t *model; picoShader_t *shader; @@ -333,12 +333,6 @@ void InsertModel( const char *name, int skin, int frame, m4x4_t transform, remap if( PicoGetSurfaceType( surface ) != PICO_TRIANGLES ) continue; - /* allocate a surface (ydnar: gs mods) */ - ds = AllocDrawSurface( SURFACE_TRIANGLES ); - ds->entityNum = eNum; - ds->castShadows = castShadows; - ds->recvShadows = recvShadows; - /* get shader name */ shader = PicoGetSurfaceShader( surface ); if( shader == NULL ) @@ -401,6 +395,12 @@ void InsertModel( const char *name, int skin, int frame, m4x4_t transform, remap else si = ShaderInfoForShader( picoShaderName ); + /* allocate a surface (ydnar: gs mods) */ + ds = AllocDrawSurface( SURFACE_TRIANGLES ); + ds->entityNum = eNum; + ds->castShadows = castShadows; + ds->recvShadows = recvShadows; + /* set shader */ ds->shaderInfo = si; @@ -747,7 +747,11 @@ void AddTriangleModels( entity_t *e ) } /* get model frame */ - frame = IntForKey( e2, "_frame" ); + frame = 0; + if(strcmp("", ValueForKey( e2, "_frame"))) + frame = IntForKey(e2, "_frame"); + else if(strcmp("", ValueForKey( e2, "frame"))) + frame = IntForKey(e2, "frame"); /* worldspawn (and func_groups) default to cast/recv shadows in worldspawn group */ if( e == entities ) @@ -888,7 +892,11 @@ void AddTriangleModels( entity_t *e ) if( shadeAngle > 0.0f ) Sys_Printf( "misc_model has shading angle of %.4f\n", shadeAngle ); - skin = IntForKey(e2, "skin"); + skin = 0; + if(strcmp("", ValueForKey( e2, "_skin"))) + skin = IntForKey(e2, "_skin"); + else if(strcmp("", ValueForKey( e2, "skin"))) + skin = IntForKey(e2, "skin"); /* insert the model */ InsertModel( model, skin, frame, transform, remap, celShader, mapEntityNum, castShadows, recvShadows, spawnFlags, lightmapScale, lightmapSampleSize, shadeAngle ); diff --git a/misc/source/netradiant-src/tools/quake3/q3map2/patch.c b/misc/source/netradiant-src/tools/quake3/q3map2/patch.c index 9cd707e2..b977dc7d 100644 --- a/misc/source/netradiant-src/tools/quake3/q3map2/patch.c +++ b/misc/source/netradiant-src/tools/quake3/q3map2/patch.c @@ -266,8 +266,10 @@ void ParsePatch( qboolean onlyLights ) GetToken(qtrue); if (g_bBrushPrimit!=BPRIMIT_OLDBRUSHES && strcmp(token,"}")) { - // NOTE: we leak that! ep = ParseEPair(); + free(ep->key); + free(ep->value); + free(ep); } else UnGetToken(); diff --git a/misc/source/netradiant-src/tools/quake3/q3map2/path_init.c b/misc/source/netradiant-src/tools/quake3/q3map2/path_init.c index 83383e22..4994c5f5 100644 --- a/misc/source/netradiant-src/tools/quake3/q3map2/path_init.c +++ b/misc/source/netradiant-src/tools/quake3/q3map2/path_init.c @@ -62,7 +62,7 @@ PathLokiGetHomeDir() gets the user's home dir (for ~/.q3a) */ -char *LokiGetHomeDir( void ) +char *LokiGetHomeDir(void) { #ifndef Q_UNIX return NULL; @@ -70,6 +70,7 @@ char *LokiGetHomeDir( void ) char *home; uid_t id; struct passwd *pwd; + static char homeBuf[MAX_OS_PATH]; /* get the home environment variable */ @@ -89,9 +90,11 @@ char *LokiGetHomeDir( void ) } endpwent(); } + + snprintf(homeBuf, sizeof(homeBuf), "%s/.", home); /* return it */ - return home; + return homeBuf; #endif } @@ -104,23 +107,32 @@ initializes some paths on linux/os x void LokiInitPaths( char *argv0 ) { + char *home; + + if(!homePath) + { + /* get home dir */ + home = LokiGetHomeDir(); + if( home == NULL ) + home = "."; + + /* set home path */ + homePath = home; + } + else + home = homePath; + #ifndef Q_UNIX /* this is kinda crap, but hey */ strcpy( installPath, "../" ); #else char temp[ MAX_OS_PATH ]; char last0[ 2 ]; - char *home; char *path; char *last; qboolean found; - /* get home dir */ - home = LokiGetHomeDir(); - if( home == NULL ) - home = "."; - /* do some path divining */ strcpy( temp, argv0 ); if( strrchr( argv0, '/' ) ) @@ -177,9 +189,6 @@ void LokiInitPaths( char *argv0 ) *(strrchr( installPath, '/' )) = '\0'; *(strrchr( installPath, '/' ) + 1) = '\0'; } - - /* set home path */ - homePath = home; #endif } @@ -272,28 +281,51 @@ adds a base path to the beginning of the list, prefixed by ~/ void AddHomeBasePath( char *path ) { - #ifdef Q_UNIX - int i; - char temp[ MAX_OS_PATH ]; - - - /* dummy check */ - if( path == NULL || path[ 0 ] == '\0' ) - return; + int i; + char temp[ MAX_OS_PATH ]; + int homePathLen; + + if(!homePath) + return; + + /* dummy check */ + if( path == NULL || path[ 0 ] == '\0' ) + return; + + /* strip leading dot, if homePath does not end in /. */ + homePathLen = strlen(homePath); + if(!strcmp(path, ".")) + { + /* -fs_homebase . means that -fs_home is to be used as is */ + strcpy(temp, homePath); + } + else if(homePathLen >= 2 && !strcmp(homePath + homePathLen - 2, "/.")) + { + /* remove trailing /. of homePath */ + homePathLen -= 2; + + /* concatenate home dir and path */ + sprintf( temp, "%.*s/%s", homePathLen, homePath, path ); + } + else + { + /* remove leading . of path */ + if(path[0] == '.') + ++path; - /* make a hole */ - for( i = (MAX_BASE_PATHS - 2); i >= 0; i-- ) - basePaths[ i + 1 ] = basePaths[ i ]; - /* concatenate home dir and path */ sprintf( temp, "%s/%s", homePath, path ); - - /* add it to the list */ - basePaths[ 0 ] = safe_malloc( strlen( temp ) + 1 ); - strcpy( basePaths[ 0 ], temp ); - CleanPath( basePaths[ 0 ] ); - numBasePaths++; - #endif + } + + /* make a hole */ + for( i = (MAX_BASE_PATHS - 2); i >= 0; i-- ) + basePaths[ i + 1 ] = basePaths[ i ]; + + /* add it to the list */ + basePaths[ 0 ] = safe_malloc( strlen( temp ) + 1 ); + strcpy( basePaths[ 0 ], temp ); + CleanPath( basePaths[ 0 ] ); + numBasePaths++; } @@ -411,7 +443,17 @@ void InitPaths( int *argc, char **argv ) argv[ i ] = NULL; } - /* -fs_nohomebase */ + /* -fs_home */ + else if( strcmp( argv[ i ], "-fs_home" ) == 0 ) + { + if( ++i >= *argc ) + Error( "Out of arguments: No path specified after %s.", argv[ i - 1 ] ); + argv[ i - 1 ] = NULL; + homePath = argv[i]; + argv[ i ] = NULL; + } + + /* -fs_homebase */ else if( strcmp( argv[ i ], "-fs_homebase" ) == 0 ) { if( ++i >= *argc ) @@ -420,6 +462,17 @@ void InitPaths( int *argc, char **argv ) homeBasePath = argv[i]; argv[ i ] = NULL; } + + /* -fs_homepath - sets both of them */ + else if( strcmp( argv[ i ], "-fs_homepath" ) == 0 ) + { + if( ++i >= *argc ) + Error( "Out of arguments: No path specified after %s.", argv[ i - 1 ] ); + argv[ i - 1 ] = NULL; + homePath = argv[i]; + homeBasePath = "."; + argv[ i ] = NULL; + } } /* remove processed arguments */ diff --git a/misc/source/netradiant-src/tools/quake3/q3map2/shaders.c b/misc/source/netradiant-src/tools/quake3/q3map2/shaders.c index 3bf6cbe1..dcbf79d2 100644 --- a/misc/source/netradiant-src/tools/quake3/q3map2/shaders.c +++ b/misc/source/netradiant-src/tools/quake3/q3map2/shaders.c @@ -687,7 +687,7 @@ void FinishShader( shaderInfo_t *si ) { int x, y; float st[ 2 ], o[ 2 ], dist, bestDist; - vec4_t color, bestColor, delta; + vec4_t color, delta; /* don't double-dip */ @@ -727,8 +727,6 @@ void FinishShader( shaderInfo_t *si ) dist = delta[ 0 ] * delta[ 0 ] + delta[ 1 ] * delta[ 1 ] + delta[ 2 ] * delta[ 2 ] + delta[ 3 ] * delta[ 3 ]; if( dist < bestDist ) { - VectorCopy( color, bestColor ); - bestColor[ 3 ] = color[ 3 ]; si->stFlat[ 0 ] = st[ 0 ]; si->stFlat[ 1 ] = st[ 1 ]; } diff --git a/misc/source/netradiant-src/tools/quake3/q3map2/surface.c b/misc/source/netradiant-src/tools/quake3/q3map2/surface.c index ca4f5fa6..b5dd724e 100644 --- a/misc/source/netradiant-src/tools/quake3/q3map2/surface.c +++ b/misc/source/netradiant-src/tools/quake3/q3map2/surface.c @@ -2147,7 +2147,7 @@ subdivides a patch into an approximate curve and filters it into the tree static int FilterPatchIntoTree( mapDrawSurface_t *ds, tree_t *tree ) { - int x, y, refs; + int x, y, refs = 0; for(y = 0; y + 2 < ds->patchHeight; y += 2) for(x = 0; x + 2 < ds->patchWidth; x += 2) @@ -3108,7 +3108,7 @@ int AddSurfaceModelsToTriangle_r( mapDrawSurface_t *ds, surfaceModel_t *model, b /* roll the dice (model's odds scaled by vertex alpha) */ odds = model->odds * (tri[ 0 ]->color[ 0 ][ 3 ] + tri[ 0 ]->color[ 0 ][ 3 ] + tri[ 0 ]->color[ 0 ][ 3 ]) / 765.0f; r = Random(); - if( r > model->odds ) + if( r > odds ) return 0; /* calculate scale */ diff --git a/misc/source/netradiant-src/tools/quake3/q3map2/surface_meta.c b/misc/source/netradiant-src/tools/quake3/q3map2/surface_meta.c index 0e300dde..8a684855 100644 --- a/misc/source/netradiant-src/tools/quake3/q3map2/surface_meta.c +++ b/misc/source/netradiant-src/tools/quake3/q3map2/surface_meta.c @@ -1402,7 +1402,7 @@ static int AddMetaTriangleToSurface( mapDrawSurface_t *ds, metaTriangle_t *tri, int i, score, coincident, ai, bi, ci, oldTexRange[ 2 ]; float lmMax; vec3_t mins, maxs; - qboolean inTexRange, es, et; + qboolean inTexRange; mapDrawSurface_t old; @@ -1518,9 +1518,6 @@ static int AddMetaTriangleToSurface( mapDrawSurface_t *ds, metaTriangle_t *tri, oldTexRange[ 1 ] = ds->texRange[ 1 ]; inTexRange = CalcSurfaceTextureRange( ds ); - es = (ds->texRange[ 0 ] > oldTexRange[ 0 ]) ? qtrue : qfalse; - et = (ds->texRange[ 1 ] > oldTexRange[ 1 ]) ? qtrue : qfalse; - if( inTexRange == qfalse && ds->numIndexes > 0 ) { memcpy( ds, &old, sizeof( *ds ) ); diff --git a/misc/source/netradiant-src/tools/quake3/q3map2/tjunction.c b/misc/source/netradiant-src/tools/quake3/q3map2/tjunction.c index cde7ece4..1ecd1ac3 100644 --- a/misc/source/netradiant-src/tools/quake3/q3map2/tjunction.c +++ b/misc/source/netradiant-src/tools/quake3/q3map2/tjunction.c @@ -330,23 +330,18 @@ void FixSurfaceJunctions( mapDrawSurface_t *ds ) { int i, j, k; edgeLine_t *e; edgePoint_t *p; - int originalVerts; int counts[MAX_SURFACE_VERTS]; int originals[MAX_SURFACE_VERTS]; - int firstVert[MAX_SURFACE_VERTS]; bspDrawVert_t verts[MAX_SURFACE_VERTS], *v1, *v2; int numVerts; float start, end, frac, c; vec3_t delta; - originalVerts = ds->numVerts; - numVerts = 0; for ( i = 0 ; i < ds->numVerts ; i++ ) { counts[i] = 0; - firstVert[i] = numVerts; // copy first vert if ( numVerts == MAX_SURFACE_VERTS ) { -- 2.39.2