]> git.rm.cloudns.org Git - voretournament/voretournament.git/commitdiff
Latest fteqcc and netradiant sources
authorMirceaKitsune <sonichedgehog_hyperblast00@yahoo.com>
Thu, 14 Jul 2011 20:11:53 +0000 (23:11 +0300)
committerMirceaKitsune <sonichedgehog_hyperblast00@yahoo.com>
Thu, 14 Jul 2011 20:11:53 +0000 (23:11 +0300)
69 files changed:
misc/source/fteqcc-src/comprout.c
misc/source/fteqcc-src/execloop.h
misc/source/fteqcc-src/hash.c
misc/source/fteqcc-src/hash.h
misc/source/fteqcc-src/initlib.c
misc/source/fteqcc-src/pr_comp.h
misc/source/fteqcc-src/pr_edict.c
misc/source/fteqcc-src/pr_exec.c
misc/source/fteqcc-src/pr_multi.c
misc/source/fteqcc-src/pr_x86.c
misc/source/fteqcc-src/progsint.h
misc/source/fteqcc-src/progslib.h
misc/source/fteqcc-src/qcc.h
misc/source/fteqcc-src/qcc_cmdlib.c
misc/source/fteqcc-src/qcc_pr_comp.c
misc/source/fteqcc-src/qcc_pr_lex.c
misc/source/fteqcc-src/qccmain.c
misc/source/fteqcc-src/qcd_main.c
misc/source/fteqcc-src/qcdecomp.c
misc/source/netradiant-src/Makefile
misc/source/netradiant-src/contrib/bobtoolz/DPatch.h
misc/source/netradiant-src/contrib/bobtoolz/DShape.h
misc/source/netradiant-src/download-gamepacks.sh
misc/source/netradiant-src/install-dylibs.sh
misc/source/netradiant-src/install-gamepack.sh
misc/source/netradiant-src/libs/memory/allocator.h
misc/source/netradiant-src/libs/picomodel.h
misc/source/netradiant-src/libs/picomodel/lwo/lwo2.c
misc/source/netradiant-src/libs/picomodel/lwo/lwob.c
misc/source/netradiant-src/libs/picomodel/picomodel.c
misc/source/netradiant-src/libs/picomodel/pm_ase.c
misc/source/netradiant-src/libs/picomodel/pm_fm.c
misc/source/netradiant-src/libs/picomodel/pm_md2.c
misc/source/netradiant-src/libs/picomodel/pm_obj.c
misc/source/netradiant-src/libs/typesystem.h
misc/source/netradiant-src/plugins/vfspk3/vfs.cpp
misc/source/netradiant-src/radiant/brushmodule.cpp
misc/source/netradiant-src/radiant/csg.cpp
misc/source/netradiant-src/radiant/entityinspector.cpp
misc/source/netradiant-src/radiant/entityinspector.h
misc/source/netradiant-src/radiant/groupdialog.h
misc/source/netradiant-src/radiant/mainframe.cpp
misc/source/netradiant-src/radiant/mainframe.h
misc/source/netradiant-src/radiant/map.cpp
misc/source/netradiant-src/radiant/qe3.cpp
misc/source/netradiant-src/radiant/select.cpp
misc/source/netradiant-src/radiant/selection.cpp
misc/source/netradiant-src/tools/quake3/common/imagelib.c
misc/source/netradiant-src/tools/quake3/common/scriplib.c
misc/source/netradiant-src/tools/quake3/common/vfs.c
misc/source/netradiant-src/tools/quake3/q3map2/convert_ase.c
misc/source/netradiant-src/tools/quake3/q3map2/convert_map.c
misc/source/netradiant-src/tools/quake3/q3map2/convert_obj.c
misc/source/netradiant-src/tools/quake3/q3map2/facebsp.c
misc/source/netradiant-src/tools/quake3/q3map2/image.c
misc/source/netradiant-src/tools/quake3/q3map2/light.c
misc/source/netradiant-src/tools/quake3/q3map2/light_bounce.c
misc/source/netradiant-src/tools/quake3/q3map2/light_trace.c
misc/source/netradiant-src/tools/quake3/q3map2/light_ydnar.c
misc/source/netradiant-src/tools/quake3/q3map2/lightmaps_ydnar.c
misc/source/netradiant-src/tools/quake3/q3map2/main.c
misc/source/netradiant-src/tools/quake3/q3map2/map.c
misc/source/netradiant-src/tools/quake3/q3map2/model.c
misc/source/netradiant-src/tools/quake3/q3map2/patch.c
misc/source/netradiant-src/tools/quake3/q3map2/path_init.c
misc/source/netradiant-src/tools/quake3/q3map2/shaders.c
misc/source/netradiant-src/tools/quake3/q3map2/surface.c
misc/source/netradiant-src/tools/quake3/q3map2/surface_meta.c
misc/source/netradiant-src/tools/quake3/q3map2/tjunction.c

index a2a7a3bd80340b9f1b722c280a88214b2329c383..2a2f96156d57a0892c88bbf5b88f55499fe09ebc 100644 (file)
@@ -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;
index 365c93a496df56f8c04ccec63113e638ce7d64c0..08d0ce9fd55a4bde5e18ccf80efbf902856bb080 100644 (file)
@@ -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;
index 2b7b91202f65bdb7f7266a0fbc4d4e4add956719..44ac211d3dbfe1371240f38f02bc60f9209de871 100644 (file)
@@ -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)
        {
index 778e67a571d967d42942d22f4500ef89b2f7baae..e07c17d2278b60f780bfb85086f7533535738b96 100644 (file)
@@ -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
index 1ca5728b38a811a47e0727b6590850e86b549a0b..8ee0f99a2cef5f18de5767ae943304be93178766 100644 (file)
@@ -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 ; i<pr_progstate[pnum].progs->numglobaldefs ; 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 ; i<pr_progstate[pnum].progs->numglobaldefs ; 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)
        {
index 13b93bce2aadb7f08be658654e075b453c27c3f6..d6c34a96ed70db5eece3d6c3725236dda3361a26 100644 (file)
@@ -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;
index d6c2119986a5dcf1be41b8fc25c4ef9cde16e33c..a67b36851e358328db2960f22406f15069a86cb2 100644 (file)
@@ -305,17 +305,18 @@ unsigned int ED_FindGlobalOfs (progfuncs_t *progfuncs, char *name)
 {
        ddef16_t *d16;
        ddef32_t *d32;
-       switch(current_progstate->intsize)
+       switch(current_progstate->structtype)
        {
-       case 24:
-       case 16:
+       case PST_KKQWSV:
+       case PST_DEFAULT:
                d16 = ED_FindGlobal16(progfuncs, name);
                return d16?d16->ofs:0;
-       case 32:
+       case PST_QTEST:
+       case PST_FTE32:
                d32 = ED_FindGlobal32(progfuncs, name);
                return d32?d32->ofs:0;
        }
-       Sys_Error("ED_FindGlobalOfs - bad intsize");
+       Sys_Error("ED_FindGlobalOfs - bad struct type");
        return 0;
 }
 
@@ -398,22 +399,23 @@ unsigned int *ED_FindGlobalOfsFromProgs (progfuncs_t *progfuncs, char *name, pro
        ddef16_t                *def16;
        ddef32_t                *def32;
        static unsigned int pos;
-       switch(pr_progstate[prnum].intsize)
+       switch(pr_progstate[prnum].structtype)
        {
-       case 16:
-       case 24:
+       case PST_DEFAULT:
+       case PST_KKQWSV:
                def16 = ED_FindTypeGlobalFromProgs16(progfuncs, name, prnum, type);
                if (!def16)
                        return NULL;
                pos = def16->ofs;
                return &pos;
-       case 32:
+       case PST_QTEST:
+       case PST_FTE32:
                def32 = ED_FindTypeGlobalFromProgs32(progfuncs, name, prnum, type);
                if (!def32)
                        return NULL;
                return &def32->ofs;
        }
-       Sys_Error("ED_FindGlobalOfsFromProgs - bad intsize");
+       Sys_Error("ED_FindGlobalOfsFromProgs - bad struct type");
        return 0;
 }
 
@@ -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 ; i<pr_progs->numglobaldefs ; 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 ; i<pr_progs->numglobaldefs ; 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 ; i<pr_progs->numfunctions; i++)
+       switch(current_progstate->structtype)
        {
+       case PST_QTEST:
+               // qtest needs a struct remap
+               for (i=0 ; i<pr_progs->numfunctions; 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; j<MAX_PARMS;j++)
+                               fnc[i].parm_size[j] = PRLittleLong (qtfunc.parm_size[j]);
+
+                       fnc[i].s_name += stringadjust;
+                       fnc[i].s_file += stringadjust;
+               }
+               break;
+       case PST_KKQWSV:
+       case PST_DEFAULT:
+       case PST_FTE32:
+               for (i=0 ; i<pr_progs->numfunctions; i++)
+               {
 #ifndef NOENDIAN
-               fnc[i].first_statement  = PRLittleLong (fnc[i].first_statement);
-               fnc[i].parm_start       = PRLittleLong (fnc[i].parm_start);
-               fnc[i].s_name   = (string_t)PRLittleLong ((long)fnc[i].s_name);
-               fnc[i].s_file   = (string_t)PRLittleLong ((long)fnc[i].s_file);
-               fnc[i].numparms = PRLittleLong (fnc[i].numparms);
-               fnc[i].locals   = PRLittleLong (fnc[i].locals);
+                       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 ; i<pr_progs->numglobaldefs ; i++)
                {
@@ -2764,7 +2822,26 @@ retry:
                }
 
                break;
-       case 32:
+       case PST_QTEST:
+               // qtest needs a struct remap
+               for (i=0 ; i<pr_progs->numglobaldefs ; i++)
+               {
+                       qtest_def_t qtdef = ((qtest_def_t *)pr_globaldefs32)[i];
+
+                       pr_globaldefs32[i].type = qtdef.type;
+                       pr_globaldefs32[i].s_name = qtdef.s_name;
+                       pr_globaldefs32[i].ofs = qtdef.ofs;
+               }
+               for (i=0 ; i<pr_progs->numfielddefs ; i++)
+               {
+                       qtest_def_t qtdef = ((qtest_def_t *)pr_fielddefs32)[i];
+
+                       pr_fielddefs32[i].type = qtdef.type;
+                       pr_fielddefs32[i].s_name = qtdef.s_name;
+                       pr_fielddefs32[i].ofs = qtdef.ofs;
+               }
+               // passthrough
+       case PST_FTE32:
                for (i=0 ; i<pr_progs->numglobaldefs ; i++)
                {
 #ifndef NOENDIAN
@@ -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 ; i<pr_progs->numstatements ; i++)
+               {
+                       qtest_statement_t qtst = ((qtest_statement_t*)st16)[i];
+
+                       st16[i].op = PRLittleShort(qtst.op);
+                       st16[i].a = PRLittleShort(qtst.a);
+                       st16[i].b = PRLittleShort(qtst.b);
+                       st16[i].c = PRLittleShort(qtst.c);
+                       // could use the line info as lno information maybe? is it really worth it?
+                       // also never assuming h2 calling mechanism
+               }
+               break;
+       case PST_DEFAULT:
                for (i=0 ; i<pr_progs->numstatements ; i++)
                {
 #ifndef NOENDIAN
@@ -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 ; i<pr_progs->numstatements ; i++)
-               {
-#ifndef NOENDIAN
-                       pr_statements32[i].op = PRLittleLong(pr_statements32[i].op);
-                       pr_statements32[i].a = PRLittleLong(pr_statements32[i].a);
-                       pr_statements32[i].b = PRLittleLong(pr_statements32[i].b);
-                       pr_statements32[i].c = PRLittleLong(pr_statements32[i].c);
-#endif
-                       if (pr_statements32[i].op >= OP_CALL1 && pr_statements32[i].op <= OP_CALL8)
-                       {
-                               if (pr_statements32[i].b)
-                                       hexencalling = true;
-
-                       }
-               }
-               if (hexencalling)
-               {
-                       for (i=0 ; i<pr_progs->numstatements ; i++)
-                       {
-                               if (pr_statements32[i].op >= OP_CALL1 && pr_statements32[i].op <= OP_CALL8)
-                                       pr_statements32[i].op += OP_CALL1H - OP_CALL1;
-                       }
-               }
-               break;
-       case 32:
+       case PST_KKQWSV:        //24 sucks. Guess why.
+       case PST_FTE32:
                for (i=0 ; i<pr_progs->numstatements ; 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 ; i<pr_progs->numglobaldefs ; i++)
                {
                        if (pr_types)
@@ -2960,7 +3030,8 @@ retry:
                        }
                }
                break;
-       case 32:
+       case PST_QTEST:
+       case PST_FTE32:
                for (i=0 ; i<pr_progs->numglobaldefs ; 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;
 
index bdd2af95989ef5934a9fe8680033190706cc0d2a..9795603937c8c0cc86b6f0435c36cbe2f98d5521 100644 (file)
@@ -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 ("<NO STACK>\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 ("<NO FUNCTION>\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.
index 5a1ade756b60896490d444e9c26af387d2be8946..b66b8b5e781cb2411bab3c9cf2d5f0800b310edd 100644 (file)
@@ -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 ; i<pr_progs->numfielddefs; 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 ; i<pr_progs->numfielddefs; i++)
                {
                        if (!strcmp(pr_fielddefs32[i].s_name+stringtable, pr_globaldefs32[num].s_name+stringtable))
index 4ebfdda2016f94562e59e56bf3577a6d020f3994..9f217b339ef96f677a873ced7f716f356c1df491 100644 (file)
@@ -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\r
        it should also be possible to fold in eq+ifnot, so none of this silly storeing of floats in equality tests\r
 \r
+       this means that we need to track which vars are cached and in what form: fpreg, ireg+floatasint, ireg+float.\r
+       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.\r
+\r
+       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.\r
+\r
+       some instructions are jump sites. any cache must be flushed before the start of the instruction.\r
+       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.\r
+       such locals need to be calculated PER FUNCTION as (fte)qcc can overlap locals making multiple distinct locals on a single offset.\r
+\r
+       store locals on a proper stack instead of the current absurd mechanism.\r
+\r
        eax - tmp\r
        ebx - prinst->edicttable\r
        ecx     - tmp\r
        edx - tmp\r
-       esi - \r
+       esi - debug opcode number\r
        edi - tmp (because its preserved by subfunctions\r
-       ebp - \r
+       ebp -\r
 \r
   to use gas to provide binary opcodes:\r
   vim -N blob.s && as blob.s && objdump.exe -d a.out\r
+\r
+\r
+  notable mods to test:\r
+  prydon gate, due to fpu mangling to carry values between maps\r
 */\r
 \r
 #define PROGSUSED\r
@@ -29,59 +44,135 @@ optimisations:
 \r
 static float ta, tb, nullfloat=0;\r
 \r
-unsigned int *statementjumps;  //[MAX_STATEMENTS*2]\r
-unsigned char **statementoffsets; //[MAX_STATEMENTS]\r
-unsigned int numjumps;\r
-unsigned char *code;\r
-unsigned int codesize;\r
-unsigned int jitstatements;\r
-\r
-void EmitByte(unsigned char byte)\r
+struct jitstate\r
 {\r
-       code[codesize++] = byte;\r
+       unsigned int *statementjumps;   //[MAX_STATEMENTS*3]\r
+       unsigned char **statementoffsets; //[MAX_STATEMENTS]\r
+       unsigned int numjumps;\r
+       unsigned char *code;\r
+       unsigned int codesize;\r
+       unsigned int jitstatements;\r
+};\r
+\r
+static void EmitByte(struct jitstate *jit, unsigned char byte)\r
+{\r
+       jit->code[jit->codesize++] = byte;\r
 }\r
-void Emit4Byte(unsigned int value)\r
+static void Emit4Byte(struct jitstate *jit, unsigned int value)\r
 {\r
-       code[codesize++] = (value>> 0)&0xff;\r
-       code[codesize++] = (value>> 8)&0xff;\r
-       code[codesize++] = (value>>16)&0xff;\r
-       code[codesize++] = (value>>24)&0xff;\r
+       jit->code[jit->codesize++] = (value>> 0)&0xff;\r
+       jit->code[jit->codesize++] = (value>> 8)&0xff;\r
+       jit->code[jit->codesize++] = (value>>16)&0xff;\r
+       jit->code[jit->codesize++] = (value>>24)&0xff;\r
 }\r
-void EmitAdr(void *value)\r
+static void EmitAdr(struct jitstate *jit, void *value)\r
 {\r
-       Emit4Byte((unsigned int)value);\r
+       Emit4Byte(jit, (unsigned int)value);\r
 }\r
-void EmitFloat(float value)\r
+static void EmitFloat(struct jitstate *jit, float value)\r
 {\r
        union {float f; unsigned int i;} u;\r
        u.f = value;\r
-       Emit4Byte(u.i);\r
+       Emit4Byte(jit, u.i);\r
 }\r
-void Emit2Byte(unsigned short value)\r
+static void Emit2Byte(struct jitstate *jit, unsigned short value)\r
 {\r
-       code[codesize++] = (value>> 0)&0xff;\r
-       code[codesize++] = (value>> 8)&0xff;\r
+       jit->code[jit->codesize++] = (value>> 0)&0xff;\r
+       jit->code[jit->codesize++] = (value>> 8)&0xff;\r
 }\r
 \r
-void EmitFOffset(void *func, int bias)\r
+static void EmitFOffset(struct jitstate *jit, void *func, int bias)\r
 {\r
        union {void *f; unsigned int i;} u;\r
        u.f = func;\r
-       u.i -= (unsigned int)&code[codesize+bias];\r
-       Emit4Byte(u.i);\r
+       u.i -= (unsigned int)&jit->code[jit->codesize+bias];\r
+       Emit4Byte(jit, u.i);\r
 }\r
 \r
-void Emit4ByteJump(int statementnum, int offset)\r
+static void Emit4ByteJump(struct jitstate *jit, int statementnum, int offset)\r
 {\r
-       statementjumps[numjumps++] = codesize;\r
-       statementjumps[numjumps++] = statementnum;\r
-       statementjumps[numjumps++] = offset;\r
+       jit->statementjumps[jit->numjumps++] = jit->codesize;\r
+       jit->statementjumps[jit->numjumps++] = statementnum;\r
+       jit->statementjumps[jit->numjumps++] = offset;\r
 \r
        //the offset is filled in later\r
-       codesize += 4;\r
+       jit->codesize += 4;\r
 }\r
 \r
-void FixupJumps(void)\r
+enum\r
+{\r
+       REG_EAX,\r
+       REG_ECX,\r
+       REG_EDX,\r
+       REG_EBX,\r
+       REG_ESP,\r
+       REG_EBP,\r
+       REG_ESI,\r
+       REG_EDI\r
+};\r
+#define XOR(sr,dr) EmitByte(0x31);EmitByte(0xc0 | (sr<<3) | dr);\r
+#define CLEARREG(reg) XOR(reg,reg)\r
+#define LOADREG(addr, reg) if (reg == REG_EAX) {EmitByte(0xa1);} else {EmitByte(0x8b); EmitByte((reg<<3) | 0x05);} EmitAdr(addr);\r
+#define STOREREG(reg, addr) if (reg == REG_EAX) {EmitByte(0xa3);} else {EmitByte(0x89); EmitByte((reg<<3) | 0x05);} EmitAdr(addr);\r
+#define STOREF(f, addr) EmitByte(0xc7);EmitByte(0x05); EmitAdr(addr);EmitFloat(f);\r
+#define STOREI(i, addr) EmitByte(0xc7);EmitByte(0x05); EmitAdr(addr);Emit4Byte(i);\r
+#define SETREGI(val,reg) EmitByte(0xbe);Emit4Byte(val);\r
+\r
+static void *LocalLoc(struct jitstate *jit)\r
+{\r
+       return &jit->code[jit->codesize];\r
+}\r
+static void *LocalJmp(struct jitstate *jit, int cond)\r
+{\r
+       /*floating point ops don't set the sign flag, thus we use the 'above/below' instructions instead of 'greater/less' instructions*/\r
+       if (cond == OP_GOTO)\r
+               EmitByte(jit, 0xeb);    //jmp\r
+       else if (cond == OP_LE_F)\r
+               EmitByte(jit, 0x76);    //jbe\r
+       else if (cond == OP_GE_F)\r
+               EmitByte(jit, 0x73);    //jae\r
+       else if (cond == OP_LT_F)\r
+               EmitByte(jit, 0x72);    //jb\r
+       else if (cond == OP_GT_F)\r
+               EmitByte(jit, 0x77);    //ja\r
+       else if (cond == OP_LE_I)\r
+               EmitByte(jit, 0x7e);    //jle\r
+       else if (cond == OP_LT_I)\r
+               EmitByte(jit, 0x7c);    //jl\r
+       else if ((cond >= OP_NE_F && cond <= OP_NE_FNC) || cond == OP_NE_I)\r
+               EmitByte(jit, 0x75);    //jne\r
+       else if ((cond >= OP_EQ_F && cond <= OP_EQ_FNC) || cond == OP_EQ_I)\r
+               EmitByte(jit, 0x74);    //je\r
+#if defined(DEBUG) && defined(_WIN32)\r
+       else\r
+       {\r
+               OutputDebugString("oh noes!\n");\r
+               return NULL;\r
+       }\r
+#endif\r
+\r
+       EmitByte(jit, 0);\r
+\r
+       return LocalLoc(jit);\r
+}\r
+static void LocalJmpLoc(void *jmp, void *loc)\r
+{\r
+       int offs;\r
+       unsigned char *a = jmp;\r
+       offs = (char *)loc - (char *)jmp;\r
+#if defined(DEBUG) && defined(_WIN32)\r
+       if (offs > 127 || offs <= -128)\r
+       {\r
+               OutputDebugStringA("bad jump\n");\r
+               a[-2] = 0xcd;\r
+               a[-1] = 0xcc;\r
+               return;\r
+       }\r
+#endif\r
+       a[-1] = offs;\r
+}\r
+\r
+static void FixupJumps(struct jitstate *jit)\r
 {\r
        unsigned int j;\r
        unsigned char *codesrc;\r
@@ -90,15 +181,15 @@ void FixupJumps(void)
 \r
        unsigned int v;\r
 \r
-       for (j = 0; j < numjumps;)\r
+       for (j = 0; j < jit->numjumps;)\r
        {\r
-               v = statementjumps[j++];\r
-               codesrc = &code[v];\r
+               v = jit->statementjumps[j++];\r
+               codesrc = &jit->code[v];\r
 \r
-               v = statementjumps[j++];\r
-               codedst = statementoffsets[v];\r
+               v = jit->statementjumps[j++];\r
+               codedst = jit->statementoffsets[v];\r
 \r
-               v = statementjumps[j++];\r
+               v = jit->statementjumps[j++];\r
                offset = (int)(codedst - (codesrc-v));  //3rd term because the jump is relative to the instruction start, not the instruction's offset\r
 \r
                codesrc[0] = (offset>> 0)&0xff;\r
@@ -108,53 +199,81 @@ void FixupJumps(void)
        }\r
 }\r
 \r
-int PR_LeaveFunction (progfuncs_t *progfuncs);\r
-int PR_EnterFunction (progfuncs_t *progfuncs, dfunction_t *f, int progsnum);\r
+int ASMCALL PR_LeaveFunction (progfuncs_t *progfuncs);\r
+int ASMCALL PR_EnterFunction (progfuncs_t *progfuncs, dfunction_t *f, int progsnum);\r
+\r
+void PR_CloseJit(struct jitstate *jit)\r
+{\r
+       free(jit->statementjumps);\r
+       free(jit->statementoffsets);\r
+       free(jit->code);\r
+}\r
+\r
+#define EmitByte(v) EmitByte(jit, v)\r
+#define EmitAdr(v) EmitAdr(jit, v)\r
+#define EmitFOffset(a,b) EmitFOffset(jit, a, b)\r
+#define Emit4ByteJump(a,b) Emit4ByteJump(jit, a, b)\r
+#define Emit4Byte(v) Emit4Byte(jit, v)\r
+#define EmitFloat(v) EmitFloat(jit, v)\r
+#define LocalJmp(v) LocalJmp(jit, v)\r
+#define LocalLoc() LocalLoc(jit)\r
+\r
 \r
-pbool PR_GenerateJit(progfuncs_t *progfuncs)\r
+struct jitstate *PR_GenerateJit(progfuncs_t *progfuncs)\r
 {\r
+       struct jitstate *jit;\r
+\r
+       void *j0, *l0;\r
+       void *j1, *l1;\r
+       void *j2, *l2;\r
        unsigned int i;\r
        dstatement16_t *op = (dstatement16_t*)current_progstate->statements;\r
        unsigned int numstatements = current_progstate->progs->numstatements;\r
        int *glob = (int*)current_progstate->globals;\r
 \r
        if (current_progstate->numbuiltins)\r
-               return false;\r
-\r
-       jitstatements = numstatements;\r
+               return NULL;\r
+       jit = malloc(sizeof(*jit));\r
+       jit->jitstatements = numstatements;\r
 \r
-       statementjumps = malloc(numstatements*12);\r
-       statementoffsets = malloc(numstatements*4);\r
-       code = malloc(numstatements*500);\r
+       jit->statementjumps = malloc(numstatements*12);\r
+       jit->statementoffsets = malloc(numstatements*4);\r
+       jit->code = malloc(numstatements*500);\r
+       if (!jit->code)\r
+               return NULL;\r
 \r
-       numjumps = 0;\r
-       codesize = 0;\r
+       jit->numjumps = 0;\r
+       jit->codesize = 0;\r
 \r
 \r
 \r
        for (i = 0; i < numstatements; i++)\r
        {\r
-               statementoffsets[i] = &code[codesize];\r
+               jit->statementoffsets[i] = &jit->code[jit->codesize];\r
+\r
+               /*DEBUG*/\r
+               SETREGI(op[i].op, REG_ESI);\r
+\r
                switch(op[i].op)\r
                {\r
                //jumps\r
-               case OP_IF:\r
+               case OP_IF_I:\r
                        //integer compare\r
                        //if a, goto b\r
 \r
                        //cmpl $0,glob[A]\r
                        EmitByte(0x83);EmitByte(0x3d);EmitAdr(glob + op[i].a);EmitByte(0x0);\r
-                       //jnz B\r
+                       //jne B\r
                        EmitByte(0x0f);EmitByte(0x85);Emit4ByteJump(i + (signed short)op[i].b, -4);\r
                        break;\r
 \r
-               case OP_IFNOT:\r
+               case OP_IFNOT_I:\r
                        //integer compare\r
                        //if !a, goto b\r
 \r
                        //cmpl $0,glob[A]\r
                        EmitByte(0x83);EmitByte(0x3d);EmitAdr(glob + op[i].a);EmitByte(0x0);\r
-                       //jz B\r
+                       //je B\r
                        EmitByte(0x0f);EmitByte(0x84);Emit4ByteJump(i + (signed short)op[i].b, -4);\r
                        break;\r
 \r
@@ -173,25 +292,19 @@ pbool PR_GenerateJit(progfuncs_t *progfuncs)
                        {\r
                                //assumption: anything that returns address 0 is a void or zero return.\r
                                //thus clear eax and copy that to the return vector.\r
-                               EmitByte(0x31);EmitByte(0xc0);\r
-                               EmitByte(0xa3);EmitAdr(glob + OFS_RETURN+0);\r
-                               EmitByte(0xa3);EmitAdr(glob + OFS_RETURN+1);\r
-                               EmitByte(0xa3);EmitAdr(glob + OFS_RETURN+2);\r
+                               CLEARREG(REG_EAX);\r
+                               STOREREG(REG_EAX, glob + OFS_RETURN+0);\r
+                               STOREREG(REG_EAX, glob + OFS_RETURN+1);\r
+                               STOREREG(REG_EAX, glob + OFS_RETURN+2);\r
                        }\r
                        else\r
                        {\r
-                               //movl glob[A+0],eax\r
-                               EmitByte(0xa1);EmitAdr(glob + op[i].a+0);\r
-                               //movl glob[A+0],edx\r
-                               EmitByte(0x8b);EmitByte(0x0d);EmitAdr(glob + op[i].a+1);\r
-                               //movl glob[A+0],ecx\r
-                               EmitByte(0x8b);EmitByte(0x15);EmitAdr(glob + op[i].a+2);\r
-                               //movl eax, glob[OFS_RET+0]\r
-                               EmitByte(0xa3);EmitAdr(glob + OFS_RETURN+0);\r
-                               //movl edx, glob[OFS_RET+0]\r
-                               EmitByte(0x89);EmitByte(0x15);EmitAdr(glob + OFS_RETURN+1);\r
-                               //movl ecx, glob[OFS_RET+0]\r
-                               EmitByte(0x89);EmitByte(0x15);EmitAdr(glob + OFS_RETURN+2);\r
+                               LOADREG(glob + op[i].a+0, REG_EAX);\r
+                               LOADREG(glob + op[i].a+1, REG_EDX);\r
+                               LOADREG(glob + op[i].a+2, REG_ECX);\r
+                               STOREREG(REG_EAX, glob + OFS_RETURN+0);\r
+                               STOREREG(REG_EDX, glob + OFS_RETURN+1);\r
+                               STOREREG(REG_ECX, glob + OFS_RETURN+2);\r
                        }\r
                        \r
                        //call leavefunction to get the return address\r
@@ -207,14 +320,17 @@ pbool PR_GenerateJit(progfuncs_t *progfuncs)
 //                     cmp prinst->exitdepth,%edx\r
                        EmitByte(0x3b);EmitByte(0x15);EmitAdr(&prinst->exitdepth);\r
 //                     je returntoc\r
-                       EmitByte(0x74);EmitByte(0x09);\r
-//                     mov statementoffsets[%eax*4],%eax\r
-                       EmitByte(0x8b);EmitByte(0x04);EmitByte(0x85);EmitAdr(statementoffsets+1);\r
-//                     jmp eax\r
-                       EmitByte(0xff);EmitByte(0xe0);\r
+                       j1 = LocalJmp(OP_EQ_E);\r
+//                             mov statementoffsets[%eax*4],%eax\r
+                               EmitByte(0x8b);EmitByte(0x04);EmitByte(0x85);EmitAdr(jit->statementoffsets+1);\r
+//                             jmp *eax\r
+                               EmitByte(0xff);EmitByte(0xe0);\r
 //                     returntoc:\r
+                       l1 = LocalLoc();\r
 //                     ret\r
                        EmitByte(0xc3);\r
+\r
+                       LocalJmpLoc(j1,l1);\r
                        break;\r
 \r
                //function calls\r
@@ -229,13 +345,13 @@ pbool PR_GenerateJit(progfuncs_t *progfuncs)
                case OP_CALL8:\r
                //save the state in place the rest of the engine can cope with\r
                        //movl $i, pr_xstatement\r
-                       EmitByte(0xc7);EmitByte(0x05);EmitAdr(&pr_xstatement);Emit4Byte(i);\r
+                       EmitByte( 0xc7);EmitByte(0x05);EmitAdr(&pr_xstatement);Emit4Byte(i);\r
                        //movl $(op[i].op-OP_CALL0), pr_argc\r
-                       EmitByte(0xc7);EmitByte(0x05);EmitAdr(&pr_argc);Emit4Byte(op[i].op-OP_CALL0);\r
+                       EmitByte( 0xc7);EmitByte(0x05);EmitAdr(&pr_argc);Emit4Byte(op[i].op-OP_CALL0);\r
 \r
                //figure out who we're calling, and what that involves\r
                        //%eax = glob[A]\r
-                       EmitByte(0xa1); EmitAdr(glob + op[i].a);\r
+                       LOADREG(glob + op[i].a, REG_EAX);\r
                //eax is now the func num\r
 \r
                        //mov %eax,%ecx\r
@@ -247,7 +363,7 @@ pbool PR_GenerateJit(progfuncs_t *progfuncs)
                        //cmp %ecx,pr_typecurrent\r
                        EmitByte(0x39); EmitByte(0x0d); EmitAdr(&pr_typecurrent);\r
                        //je sameprogs\r
-                       EmitByte(0x74); EmitByte(0x3);\r
+                       j1 = LocalJmp(OP_EQ_I);\r
                        {\r
                                //can't handle switching progs\r
 \r
@@ -266,6 +382,8 @@ pbool PR_GenerateJit(progfuncs_t *progfuncs)
                                EmitByte(0xc3);\r
                        }\r
                        //sameprogs:\r
+                       l1 = LocalLoc();\r
+                       LocalJmpLoc(j1,l1);\r
 \r
                        //andl $0x00ffffff, %eax\r
                        EmitByte(0x25);Emit4Byte(0x00ffffff);\r
@@ -286,9 +404,9 @@ pbool PR_GenerateJit(progfuncs_t *progfuncs)
                        //cmp $0,%edx\r
                        EmitByte(0x83);EmitByte(0xfa);EmitByte(0x00);\r
                        //jl isabuiltin\r
-                       EmitByte(0x7c);EmitByte(22);\r
-       \r
+                       j1 = LocalJmp(OP_LT_I);\r
                        {\r
+                               /* call the function*/\r
                                //push %ecx\r
                                EmitByte(0x51);\r
                                //push %eax\r
@@ -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)\r
 \r
                                //jmp statementoffsets[%eax*4]\r
-                               EmitByte(0xff);EmitByte(0x24);EmitByte(0x85);EmitAdr(statementoffsets+1);\r
+                               EmitByte(0xff);EmitByte(0x24);EmitByte(0x85);EmitAdr(jit->statementoffsets+1);\r
                        }\r
+                       /*its a builtin, figure out which, and call it*/\r
                        //isabuiltin:\r
-\r
+                       l1 = LocalLoc();\r
+                       LocalJmpLoc(j1,l1);\r
 \r
                        //push current_progstate->globals\r
                        EmitByte(0x68);EmitAdr(current_progstate->globals);\r
@@ -321,23 +441,21 @@ pbool PR_GenerateJit(progfuncs_t *progfuncs)
 \r
                //but that builtin might have been Abort()\r
 \r
-                       //mov prinst->continuestatement,%eax\r
-                       EmitByte(0xa1);EmitAdr(&prinst->continuestatement);\r
-               //eax is now prinst->continuestatement\r
-\r
+                       LOADREG(&prinst->continuestatement, REG_EAX);\r
                        //cmp $-1,%eax\r
                        EmitByte(0x83);EmitByte(0xf8);EmitByte(0xff);\r
                        //je donebuiltincall\r
-                       EmitByte(0x74);EmitByte(10+8);\r
+                       j1 = LocalJmp(OP_EQ_I);\r
                        {\r
-EmitByte(0xcc);\r
-                               //jmp statementoffsets[%eax*4]\r
-                               EmitByte(0xff);EmitByte(0x24);EmitByte(0x85);EmitAdr(statementoffsets+1);\r
-\r
                                //mov $-1,prinst->continuestatement\r
-                               EmitByte(0xc7);EmitByte(0x05);EmitAdr(&prinst->continuestatement+1);Emit4Byte((unsigned int)-1);\r
+                               EmitByte(0xc7);EmitByte(0x05);EmitAdr(&prinst->continuestatement);Emit4Byte((unsigned int)-1);\r
+\r
+                               //jmp statementoffsets[%eax*4]\r
+                               EmitByte(0xff);EmitByte(0x24);EmitByte(0x85);EmitAdr(jit->statementoffsets);\r
                        }\r
                        //donebuiltincall:\r
+                       l1 = LocalLoc();\r
+                       LocalJmpLoc(j1,l1);\r
                        break;\r
 \r
                case OP_MUL_F:\r
@@ -374,24 +492,29 @@ EmitByte(0xcc);
                        break;\r
 \r
                case OP_NOT_F:\r
-                       //flds glob[A]\r
-                       EmitByte(0xd9);EmitByte(0x05);EmitAdr(glob + op[i].a);\r
                        //fldz\r
                        EmitByte(0xd9);EmitByte(0xee);\r
+                       //fcomps        glob[A]\r
+                       EmitByte(0xd8); EmitByte(0x1d); EmitAdr(glob + op[i].a);\r
                        //fnstsw %ax\r
                        EmitByte(0xdf);EmitByte(0xe0);\r
                        //testb 0x40,%ah\r
                        EmitByte(0xf6);EmitByte(0xc4);EmitByte(0x40);\r
-                       //je noteq\r
-                       EmitByte(0x74);EmitByte(0x0c);\r
-                       //movl 1.0f,glob[C]\r
-                       EmitByte(0xc7);EmitByte(0x05);EmitAdr(glob + op[i].c);EmitFloat(0.0f);\r
-                       //jmp end\r
-                       EmitByte(0xeb);EmitByte(0x0a);\r
-                       //noteq:\r
-                       //movl 0.0f,glob[C]\r
-                       EmitByte(0xc7);EmitByte(0x05);EmitAdr(glob + op[i].c);EmitFloat(1.0f);\r
+                       \r
+                       j1 = LocalJmp(OP_NE_F);\r
+                       {\r
+                               STOREF(0.0f, glob + op[i].c);\r
+                               j2 = LocalJmp(OP_GOTO);\r
+                       }\r
+                       {\r
+                               //noteq:\r
+                               l1 = LocalLoc();\r
+                               STOREF(1.0f, glob + op[i].c);\r
+                       }\r
                        //end:\r
+                       l2 = LocalLoc();\r
+                       LocalJmpLoc(j1,l1);\r
+                       LocalJmpLoc(j2,l2);\r
                        break;\r
 \r
                case OP_STORE_F:\r
@@ -399,26 +522,17 @@ EmitByte(0xcc);
                case OP_STORE_ENT:\r
                case OP_STORE_FLD:\r
                case OP_STORE_FNC:\r
-                       //movl glob[A],eax\r
-                       EmitByte(0xa1);EmitAdr(glob + op[i].a);\r
-                       //movl eax,glob[B]\r
-                       EmitByte(0xa3);EmitAdr(glob + op[i].b);\r
+                       LOADREG(glob + op[i].a, REG_EAX);\r
+                       STOREREG(REG_EAX, glob + op[i].b);\r
                        break;\r
 \r
                case OP_STORE_V:\r
-                       //movl glob[A+0],eax\r
-                       EmitByte(0xa1);EmitAdr(glob + op[i].a+0);\r
-                       //movl glob[A+1],edx\r
-                       EmitByte(0x8b);EmitByte(0x0d);EmitAdr(glob + op[i].a+1);\r
-                       //movl glob[A+2],ecx\r
-                       EmitByte(0x8b);EmitByte(0x15);EmitAdr(glob + op[i].a+2);\r
-\r
-                       //movl eax, glob[B+0]\r
-                       EmitByte(0xa3);EmitAdr(glob + op[i].b+0);\r
-                       //movl edx, glob[B+1]\r
-                       EmitByte(0x89);EmitByte(0x15);EmitAdr(glob + op[i].b+1);\r
-                       //movl ecx, glob[B+2]\r
-                       EmitByte(0x89);EmitByte(0x15);EmitAdr(glob + op[i].b+2);\r
+                       LOADREG(glob + op[i].a+0, REG_EAX);\r
+                       LOADREG(glob + op[i].a+1, REG_EDX);\r
+                       LOADREG(glob + op[i].a+2, REG_ECX);\r
+                       STOREREG(REG_EAX, glob + op[i].b+0);\r
+                       STOREREG(REG_EDX, glob + op[i].b+1);\r
+                       STOREREG(REG_ECX, glob + op[i].b+2);\r
                        break;\r
 \r
                case OP_LOAD_F:\r
@@ -430,10 +544,9 @@ EmitByte(0xcc);
                //a is the ent number, b is the field\r
                //c is the dest\r
 \r
-                       //movl glob[A+0],eax\r
-                       EmitByte(0xa1);EmitAdr(glob + op[i].a);\r
-                       //mov glob[B],ecx\r
-                       EmitByte(0x8b); EmitByte(0x0d);EmitAdr(glob + op[i].b);\r
+                       LOADREG(glob + op[i].a, REG_EAX);\r
+                       LOADREG(glob + op[i].b, REG_ECX);\r
+\r
                //FIXME: bound eax (ent number)\r
                //FIXME: bound ecx (field index)\r
                        //mov (ebx,eax,4).%eax\r
@@ -443,22 +556,20 @@ EmitByte(0xcc);
                        EmitByte(0x8b);EmitByte(0x50);EmitByte((int)&((edictrun_t*)NULL)->fields);\r
                //edx is now the field array for that ent\r
 \r
-                       //mov fieldajust(%edx,%ecx,4),%eax      //offset = progfuncs->fieldadjust\r
+                       //mov fieldajust(%edx,%ecx,4),%eax\r
                        EmitByte(0x8b); EmitByte(0x84); EmitByte(0x8a); Emit4Byte(progfuncs->fieldadjust*4);\r
-                       //mov edx,glob[C]\r
-                       EmitByte(0xa3);EmitAdr(glob + op[i].c);\r
+\r
+                       STOREREG(REG_EAX, glob + op[i].c)\r
 \r
                        if (op[i].op == OP_LOAD_V)\r
                        {\r
-                               //mov fieldajust+4(%edx,%ecx,4),%eax    //offset = progfuncs->fieldadjust\r
+                               //mov fieldajust+4(%edx,%ecx,4),%eax\r
                                EmitByte(0x8b); EmitByte(0x84); EmitByte(0x8a); Emit4Byte(4+progfuncs->fieldadjust*4);\r
-                               //mov edx,glob[C+1]\r
-                               EmitByte(0xa3);EmitAdr(glob + op[i].c+1);\r
+                               STOREREG(REG_EAX, glob + op[i].c+1)\r
 \r
-                               //mov fieldajust+8(%edx,%ecx,4),%eax    //offset = progfuncs->fieldadjust\r
-                               EmitByte(0x8b); EmitByte(0x84); EmitByte(0x8a); Emit4Byte(4+progfuncs->fieldadjust*4);\r
-                               //mov edx,glob[C+1]\r
-                               EmitByte(0xa3);EmitAdr(glob + op[i].c+2);\r
+                               //mov fieldajust+8(%edx,%ecx,4),%eax\r
+                               EmitByte(0x8b); EmitByte(0x84); EmitByte(0x8a); Emit4Byte(8+progfuncs->fieldadjust*4);\r
+                               STOREREG(REG_EAX, glob + op[i].c+2)\r
                        }\r
                        break;\r
 \r
@@ -466,10 +577,9 @@ EmitByte(0xcc);
                        //a is the ent number, b is the field\r
                //c is the dest\r
 \r
-                       //movl glob[A+0],eax\r
-                       EmitByte(0xa1);EmitAdr(glob + op[i].a);\r
-                       //mov glob[B],ecx\r
-                       EmitByte(0x8b); EmitByte(0x0d);EmitAdr(glob + op[i].b);\r
+                       LOADREG(glob + op[i].a, REG_EAX);\r
+                       LOADREG(glob + op[i].b, REG_ECX);\r
+\r
                //FIXME: bound eax (ent number)\r
                //FIXME: bound ecx (field index)\r
                        //mov (ebx,eax,4).%eax\r
@@ -481,8 +591,7 @@ EmitByte(0xcc);
                        //mov fieldajust(%edx,%ecx,4),%eax      //offset = progfuncs->fieldadjust\r
                        //EmitByte(0x8d); EmitByte(0x84); EmitByte(0x8a); EmitByte(progfuncs->fieldadjust*4);\r
                        EmitByte(0x8d); EmitByte(0x84); EmitByte(0x8a); Emit4Byte(progfuncs->fieldadjust*4);\r
-                       //mov edx,glob[C]\r
-                       EmitByte(0xa3);EmitAdr(glob + op[i].c);\r
+                       STOREREG(REG_EAX, glob + op[i].c);\r
                        break;\r
 \r
                case OP_STOREP_F:\r
@@ -490,118 +599,111 @@ EmitByte(0xcc);
                case OP_STOREP_ENT:\r
                case OP_STOREP_FLD:\r
                case OP_STOREP_FNC:\r
-                       //movl glob[A],eax\r
-                       EmitByte(0xa1);EmitAdr(glob + op[i].a);\r
-                       //mov glob[B],ecx\r
-                       EmitByte(0x8b); EmitByte(0x0d);EmitAdr(glob + op[i].b);\r
+                       LOADREG(glob + op[i].a, REG_EAX);\r
+                       LOADREG(glob + op[i].b, REG_ECX);\r
                        //mov %eax,(%ecx)\r
                        EmitByte(0x89);EmitByte(0x01);\r
                        break;\r
 \r
                case OP_STOREP_V:\r
-                       //mov glob[B],ecx\r
-                       EmitByte(0x8b); EmitByte(0x0d);EmitAdr(glob + op[i].b);\r
-                       //movl glob[A],eax\r
-                       EmitByte(0xa1);EmitAdr(glob + op[i].a+0);\r
+                       LOADREG(glob + op[i].b, REG_ECX);\r
+\r
+                       LOADREG(glob + op[i].a+0, REG_EAX);\r
                        //mov %eax,0(%ecx)\r
                        EmitByte(0x89);EmitByte(0x01);\r
-                       //movl glob[A],eax\r
-                       EmitByte(0xa1);EmitAdr(glob + op[i].a+0);\r
+\r
+                       LOADREG(glob + op[i].a+1, REG_EAX);\r
                        //mov %eax,4(%ecx)\r
                        EmitByte(0x89);EmitByte(0x41);EmitByte(0x04);\r
-                       //movl glob[A],eax\r
-                       EmitByte(0xa1);EmitAdr(glob + op[i].a+0);\r
+\r
+                       LOADREG(glob + op[i].a+2, REG_EAX);\r
                        //mov %eax,8(%ecx)\r
                        EmitByte(0x89);EmitByte(0x41);EmitByte(0x08);\r
                        break;\r
 \r
+               case OP_NE_I:\r
+               case OP_NE_E:\r
+               case OP_NE_FNC:\r
+               case OP_EQ_I:\r
                case OP_EQ_E:\r
                case OP_EQ_FNC:\r
                        //integer equality\r
-                       //movl glob[A],%eax\r
-                       EmitByte(0xa1);EmitAdr(glob + op[i].a);\r
-                       //cmp glob[B],%eax\r
-                       EmitByte(0x3b); EmitByte(0x0f); EmitAdr(glob + op[i].b);\r
-                       //je 12\r
-                       EmitByte(0x74);EmitByte(0x0c);\r
-                       //mov 0.0f,glob[C]\r
-                       EmitByte(0xc7);EmitByte(0x05); EmitAdr(glob + op[i].a);EmitFloat(0.0f);\r
-                       //jmp 10\r
-                       EmitByte(0xeb);EmitByte(0x0a);\r
-                       //mov 1.0f,glob[C]\r
-                       EmitByte(0xc7);EmitByte(0x05); EmitAdr(glob + op[i].a);EmitFloat(1.0f);\r
-                       break;\r
+                       LOADREG(glob + op[i].a, REG_EAX);\r
 \r
-               case OP_NE_E:\r
-               case OP_NE_FNC:\r
-                       //integer equality\r
-                       //movl glob[A],%eax\r
-                       EmitByte(0xa1);EmitAdr(glob + op[i].a);\r
                        //cmp glob[B],%eax\r
-                       EmitByte(0x3b); EmitByte(0x0f); EmitAdr(glob + op[i].b);\r
-                       //je 12\r
-                       EmitByte(0x74);EmitByte(0x0c);\r
-                       //mov 0.0f,glob[C]\r
-                       EmitByte(0xc7);EmitByte(0x05); EmitAdr(glob + op[i].a);EmitFloat(1.0f);\r
-                       //jmp 10\r
-                       EmitByte(0xeb);EmitByte(0x0a);\r
-                       //mov 1.0f,glob[C]\r
-                       EmitByte(0xc7);EmitByte(0x05); EmitAdr(glob + op[i].a);EmitFloat(0.0f);\r
+                       EmitByte(0x3b); EmitByte(0x04); EmitByte(0x25); EmitAdr(glob + op[i].b);\r
+                       j1 = LocalJmp(op[i].op);\r
+                       {\r
+                               STOREF(0.0f, glob + op[i].c);\r
+                               j2 = LocalJmp(OP_GOTO);\r
+                       }\r
+                       {\r
+                               l1 = LocalLoc();\r
+                               STOREF(1.0f, glob + op[i].c);\r
+                       }\r
+                       l2 = LocalLoc();\r
+                       LocalJmpLoc(j1,l1);\r
+                       LocalJmpLoc(j2,l2);\r
                        break;\r
 \r
+               case OP_NOT_I:\r
                case OP_NOT_ENT:\r
                case OP_NOT_FNC:\r
-                       //cmp glob[B],%eax\r
-                       EmitByte(0x8c); EmitByte(0x3d); EmitAdr(glob + op[i].a);EmitByte(0x00);\r
-                       //je 12\r
-                       EmitByte(0x74);EmitByte(0x0c);\r
-                       //mov 0.0f,glob[C]\r
-                       EmitByte(0xc7);EmitByte(0x05); EmitAdr(glob + op[i].a);EmitFloat(0.0f);\r
-                       //jmp 10\r
-                       EmitByte(0xeb);EmitByte(0x0a);\r
-                       //mov 1.0f,glob[C]\r
-                       EmitByte(0xc7);EmitByte(0x05); EmitAdr(glob + op[i].c);EmitFloat(1.0f);\r
+                       //cmp glob[B],$0\r
+                       EmitByte(0x83); EmitByte(0x3d); EmitAdr(glob + op[i].a); EmitByte(0x00); \r
+                       j1 = LocalJmp(OP_NE_I);\r
+                       {\r
+                               STOREF(1.0f, glob + op[i].c);\r
+                               j2 = LocalJmp(OP_GOTO);\r
+                       }\r
+                       {\r
+                               l1 = LocalLoc();\r
+                               STOREF(0.0f, glob + op[i].c);\r
+                       }\r
+                       l2 = LocalLoc();\r
+                       LocalJmpLoc(j1,l1);\r
+                       LocalJmpLoc(j2,l2);\r
                        break;\r
 \r
-               case OP_BITOR:  //floats...\r
+               case OP_BITOR_F:        //floats...\r
                        //flds glob[A]\r
                        EmitByte(0xd9); EmitByte(0x05);EmitAdr(glob + op[i].a);\r
                        //flds glob[B]\r
                        EmitByte(0xd9); EmitByte(0x05);EmitAdr(glob + op[i].b);\r
                        //fistp tb\r
-                       EmitByte(0xdf); EmitByte(0x1d);EmitAdr(&tb);\r
+                       EmitByte(0xdb); EmitByte(0x1d);EmitAdr(&tb);\r
                        //fistp ta\r
-                       EmitByte(0xdf); EmitByte(0x1d);EmitAdr(&ta);\r
-                       //mov ta,%eax\r
-                       EmitByte(0xa1); EmitAdr(&ta);\r
-                       //and tb,%eax\r
+                       EmitByte(0xdb); EmitByte(0x1d);EmitAdr(&ta);\r
+                       LOADREG(&ta, REG_EAX)\r
+                       //or %eax,tb\r
                        EmitByte(0x09); EmitByte(0x05);EmitAdr(&tb);\r
                        //fild tb\r
-                       EmitByte(0xdf); EmitByte(0x05);EmitAdr(&tb);\r
+                       EmitByte(0xdb); EmitByte(0x05);EmitAdr(&tb);\r
                        //fstps glob[C]\r
                        EmitByte(0xd9); EmitByte(0x1d);EmitAdr(glob + op[i].c);\r
                        break;\r
 \r
-               case OP_BITAND:\r
+               case OP_BITAND_F:\r
                        //flds glob[A]\r
                        EmitByte(0xd9); EmitByte(0x05);EmitAdr(glob + op[i].a);\r
                        //flds glob[B]\r
                        EmitByte(0xd9); EmitByte(0x05);EmitAdr(glob + op[i].b);\r
                        //fistp tb\r
-                       EmitByte(0xdf); EmitByte(0x1d);EmitAdr(&tb);\r
+                       EmitByte(0xdb); EmitByte(0x1d);EmitAdr(&tb);\r
                        //fistp ta\r
-                       EmitByte(0xdf); EmitByte(0x1d);EmitAdr(&ta);\r
-                       //mov ta,%eax\r
-                       EmitByte(0xa1); EmitAdr(&ta);\r
+                       EmitByte(0xdb); EmitByte(0x1d);EmitAdr(&ta);\r
+                       /*two args are now at ta and tb*/\r
+                       LOADREG(&ta, REG_EAX)\r
                        //and tb,%eax\r
                        EmitByte(0x21); EmitByte(0x05);EmitAdr(&tb);\r
+                       /*we just wrote the int value to tb, convert that to a float and store it at c*/\r
                        //fild tb\r
-                       EmitByte(0xdf); EmitByte(0x05);EmitAdr(&tb);\r
+                       EmitByte(0xdb); EmitByte(0x05);EmitAdr(&tb);\r
                        //fstps glob[C]\r
                        EmitByte(0xd9); EmitByte(0x1d);EmitAdr(glob + op[i].c);\r
                        break;\r
 \r
-               case OP_AND:\r
+               case OP_AND_F:\r
                        //test floats properly, so we don't get confused with -0.0\r
 \r
                        //flds  glob[A]\r
@@ -612,7 +714,7 @@ EmitByte(0xcc);
                        EmitByte(0xdf); EmitByte(0xe0);\r
                        //test  $0x40,%ah\r
                        EmitByte(0xf6); EmitByte(0xc4);EmitByte(0x40);\r
-                       //je onefalse\r
+                       //jz onefalse\r
                        EmitByte(0x75); EmitByte(0x1f);\r
 \r
                        //flds  glob[B]\r
@@ -623,7 +725,7 @@ EmitByte(0xcc);
                        EmitByte(0xdf); EmitByte(0xe0);\r
                        //test  $0x40,%ah\r
                        EmitByte(0xf6); EmitByte(0xc4);EmitByte(0x40);\r
-                       //jne onefalse\r
+                       //jnz onefalse\r
                        EmitByte(0x75); EmitByte(0x0c);\r
 \r
                        //mov float0,glob[C]\r
@@ -636,7 +738,7 @@ EmitByte(0xcc);
                        EmitByte(0xc7); EmitByte(0x05); EmitAdr(glob + op[i].c); EmitFloat(0.0f);\r
                        //done:\r
                        break;\r
-               case OP_OR:\r
+               case OP_OR_F:\r
                        //test floats properly, so we don't get confused with -0.0\r
 \r
                        //flds  glob[A]\r
@@ -674,18 +776,16 @@ EmitByte(0xcc);
 \r
                case OP_EQ_S:\r
                case OP_NE_S:\r
+                       {\r
                        //put a in ecx\r
+                       LOADREG(glob + op[i].a, REG_ECX);\r
                        //put b in edi\r
-                       //mov a,%ecx\r
-                       EmitByte(0x8b); EmitByte(0x0d); EmitAdr(glob + op[i].a);\r
-                       //mov b,%edi\r
-                       EmitByte(0x8b); EmitByte(0x3d); EmitAdr(glob + op[i].b);\r
-\r
+                       LOADREG(glob + op[i].b, REG_EDI);\r
+/*\r
                        //early out if they're equal\r
                        //cmp %ecx,%edi\r
-                       EmitByte(0x39); EmitByte(0xd1);\r
-                       //je _true\r
-                       EmitByte(0x74); EmitByte(0x68);\r
+                       EmitByte(0x39); EmitByte(0xc0 | (REG_EDI<<3) | REG_ECX);\r
+                       j1c = LocalJmp(OP_EQ_S);\r
 \r
                        //if a is 0, check if b is ""\r
                        //jecxz ais0\r
@@ -707,31 +807,30 @@ EmitByte(0xcc);
                                EmitByte(0x83); EmitByte(0xc4); EmitByte(0x08);\r
                                //cmpb $0,(%eax)\r
                                EmitByte(0x80); EmitByte(0x38); EmitByte(0x00);\r
+                               j1b = LocalJmp(OP_EQ_S);\r
+                               j0b = LocalJmp(OP_GOTO);\r
+                       }\r
+\r
+                       //ais0:\r
+                       {\r
+                               //push edi\r
+                               EmitByte(0x57);\r
+                               //push progfuncs\r
+                               EmitByte(0x68); EmitAdr(progfuncs);\r
+                               //call PR_StringToNative\r
+                               EmitByte(0xe8); EmitFOffset(PR_StringToNative,4);\r
+                               //add $8,%esp\r
+                               EmitByte(0x83); EmitByte(0xc4); EmitByte(0x08);\r
+                               //cmpb $0,(%eax)\r
+                               EmitByte(0x80); EmitByte(0x38); EmitByte(0x00);\r
                                //je _true\r
-                               EmitByte(0x74); EmitByte(0x4b);\r
+                               EmitByte(0x74); EmitByte(0x36);\r
                                //jmp _false\r
-                               EmitByte(0xeb); EmitByte(0x3d);\r
-\r
-                               //ais0:\r
-                               {\r
-                                       //push edi\r
-                                       EmitByte(0x57);\r
-                                       //push progfuncs\r
-                                       EmitByte(0x68); EmitAdr(progfuncs);\r
-                                       //call PR_StringToNative\r
-                                       EmitByte(0xe8); EmitFOffset(PR_StringToNative,4);\r
-                                       //add $8,%esp\r
-                                       EmitByte(0x83); EmitByte(0xc4); EmitByte(0x08);\r
-                                       //cmpb $0,(%eax)\r
-                                       EmitByte(0x80); EmitByte(0x38); EmitByte(0x00);\r
-                                       //je _true\r
-                                       EmitByte(0x74); EmitByte(0x36);\r
-                                       //jmp _false\r
-                                       EmitByte(0xeb); EmitByte(0x28);\r
-                               }\r
+                               EmitByte(0xeb); EmitByte(0x28);\r
                        }\r
                        //bnot0:\r
-\r
+*/\r
+LOADREG(glob + op[i].a, REG_ECX);\r
                        //push ecx\r
                        EmitByte(0x51);\r
                        //push progfuncs\r
@@ -741,6 +840,7 @@ EmitByte(0xcc);
                        //push %eax\r
                        EmitByte(0x50);\r
 \r
+LOADREG(glob + op[i].b, REG_EDI);\r
                        //push %edi\r
                        EmitByte(0x57);\r
                        //push progfuncs\r
@@ -757,28 +857,35 @@ EmitByte(0xcc);
                        EmitByte(0xe8); EmitFOffset(strcmp,4);\r
                        //add $16,%esp\r
                        EmitByte(0x83); EmitByte(0xc4); EmitByte(0x10);\r
+\r
                        //cmp $0,%eax\r
                        EmitByte(0x83); EmitByte(0xf8); EmitByte(0x00);\r
-                       //je _true\r
-                       EmitByte(0x74); EmitByte(0x0c);\r
-//_false:\r
-                       //mov 0.0f,c\r
-                       EmitByte(0xc7); EmitByte(0x05); EmitAdr(glob + op[i].c); EmitFloat((op[i].op == OP_NE_S)?1.0f:0.0f);\r
-                       //jmp done\r
-                       EmitByte(0xeb); EmitByte(0x0a);\r
-//_true:\r
-                       //mov 1.0f,c\r
-                       EmitByte(0xc7); EmitByte(0x05); EmitAdr(glob + op[i].c); EmitFloat((op[i].op == OP_NE_S)?0.0f:1.0f);\r
-//_done:\r
+                       j1 = LocalJmp(OP_EQ_S);\r
+                       {\r
+                               l0 = LocalLoc();\r
+                               STOREF((op[i].op == OP_NE_S)?1.0f:0.0f, glob + op[i].c);\r
+                               j2 = LocalJmp(OP_GOTO);\r
+                       }\r
+                       {\r
+                               l1 = LocalLoc();\r
+                               STOREF((op[i].op == OP_NE_S)?0.0f:1.0f, glob + op[i].c);\r
+                       }\r
+                       l2 = LocalLoc();\r
+\r
+//                     LocalJmpLoc(j0b, l0);\r
+                       LocalJmpLoc(j1, l1);\r
+//                     LocalJmpLoc(j1b, l1);\r
+                       LocalJmpLoc(j2, l2);\r
+                       }\r
                        break;\r
 \r
                case OP_NOT_S:\r
-                       //mov A,%eax\r
-                       EmitByte(0xa1);EmitAdr(glob + op[i].a);\r
+                       LOADREG(glob + op[i].a, REG_EAX)\r
+\r
                        //cmp $0,%eax\r
                        EmitByte(0x83); EmitByte(0xf8); EmitByte(0x00);\r
-                       //je _true\r
-                       EmitByte(0x74); EmitByte(0x1f);\r
+                       j2 = LocalJmp(OP_EQ_S);\r
+\r
                        //push %eax\r
                        EmitByte(0x50);\r
                        //push progfuncs\r
@@ -787,19 +894,22 @@ EmitByte(0xcc);
                        EmitByte(0xe8); EmitFOffset(PR_StringToNative,4);\r
                        //add $8,%esp\r
                        EmitByte(0x83); EmitByte(0xc4); EmitByte(0x08);\r
+\r
                        //cmpb $0,(%eax)\r
                        EmitByte(0x80); EmitByte(0x38); EmitByte(0x00);\r
-                       //je _true\r
-                       EmitByte(0x74); EmitByte(0x0c);\r
-//_false:\r
-                       //mov 0.0f,c\r
-                       EmitByte(0xc7); EmitByte(0x05); EmitAdr(glob + op[i].c); EmitFloat(0.0f);\r
-                       //jmp done\r
-                       EmitByte(0xeb); EmitByte(0x0a);\r
-//_true:\r
-                       //mov 1.0f,c\r
-                       EmitByte(0xc7); EmitByte(0x05); EmitAdr(glob + op[i].c); EmitFloat(1.0f);\r
-//_done:\r
+                       j1 = LocalJmp(OP_EQ_S);\r
+                       {\r
+                               STOREF(0.0f, glob + op[i].c);\r
+                               j0 = LocalJmp(OP_GOTO);\r
+                       }\r
+                       {\r
+                               l1 = LocalLoc();\r
+                               STOREF(1.0f, glob + op[i].c);\r
+                       }\r
+                       l2 = LocalLoc();\r
+                       LocalJmpLoc(j2, l1);\r
+                       LocalJmpLoc(j1, l1);\r
+                       LocalJmpLoc(j0, l2);\r
                        break;\r
 \r
                case OP_ADD_V:\r
@@ -875,42 +985,31 @@ EmitByte(0xcc);
 \r
                case OP_EQ_F:\r
                case OP_NE_F:\r
-               case OP_LE:\r
-               case OP_GE:\r
-               case OP_LT:\r
-               case OP_GT:\r
+               case OP_LE_F:\r
+               case OP_GE_F:\r
+               case OP_LT_F:\r
+               case OP_GT_F:\r
                        //flds glob[A]\r
-                       EmitByte(0xd9);EmitByte(0x05);EmitAdr(glob + op[i].a);\r
-                       //flds glob[B]\r
                        EmitByte(0xd9);EmitByte(0x05);EmitAdr(glob + op[i].b);\r
+                       //flds glob[B]\r
+                       EmitByte(0xd9);EmitByte(0x05);EmitAdr(glob + op[i].a);\r
                        //fcomip %st(1),%st\r
                        EmitByte(0xdf);EmitByte(0xe9);\r
                        //fstp %st(0)   (aka: pop)\r
                        EmitByte(0xdd);EmitByte(0xd8);\r
 \r
-                       //jcc _true\r
-                       if (op[i].op == OP_LE)\r
-                               EmitByte(0x7e); //jle\r
-                       else if (op[i].op == OP_GE)\r
-                               EmitByte(0x7d); //jge\r
-                       else if (op[i].op == OP_LT)\r
-                               EmitByte(0x7c); //jl\r
-                       else if (op[i].op == OP_GT)\r
-                               EmitByte(0x7f); //jg\r
-                       else if (op[i].op == OP_NE_F)\r
-                               EmitByte(0x75); //jne\r
-                       else\r
-                               EmitByte(0x74); //je\r
-                       EmitByte(0x0c);\r
-//_false:\r
-                       //mov 0.0f,c\r
-                       EmitByte(0xc7); EmitByte(0x05); EmitAdr(glob + op[i].c); EmitFloat(0.0f);\r
-                       //jmp done\r
-                       EmitByte(0xeb); EmitByte(0x0a);\r
-//_true:\r
-                       //mov 1.0f,c\r
-                       EmitByte(0xc7); EmitByte(0x05); EmitAdr(glob + op[i].c); EmitFloat(1.0f);\r
-//_done:\r
+                       j1 = LocalJmp(op[i].op);\r
+                       {\r
+                               STOREF(0.0f, glob + op[i].c);\r
+                               j2 = LocalJmp(OP_GOTO);\r
+                       }\r
+                       {\r
+                               l1 = LocalLoc();\r
+                               STOREF(1.0f, glob + op[i].c);\r
+                       }\r
+                       l2 = LocalLoc();\r
+                       LocalJmpLoc(j1,l1);\r
+                       LocalJmpLoc(j2,l2);\r
                        break;\r
 \r
                case OP_MUL_FV:\r
@@ -934,21 +1033,21 @@ EmitByte(0xcc);
                                EmitByte(0xd9);EmitByte(0x05);EmitAdr(glob + f);\r
 \r
                                //flds glob[V0]\r
-                               EmitByte(0xd8);EmitByte(0x0d);EmitAdr(glob + v+0);\r
+                               EmitByte(0xd9);EmitByte(0x05);EmitAdr(glob + v+0);\r
                                //fmul st(1)\r
                                EmitByte(0xd8);EmitByte(0xc9);\r
                                //fstps glob[C]\r
                                EmitByte(0xd9);EmitByte(0x1d);EmitAdr(glob + op[i].c+0);\r
 \r
                                //flds glob[V0]\r
-                               EmitByte(0xd8);EmitByte(0x0d);EmitAdr(glob + v+1);\r
+                               EmitByte(0xd9);EmitByte(0x05);EmitAdr(glob + v+1);\r
                                //fmul st(1)\r
                                EmitByte(0xd8);EmitByte(0xc9);\r
                                //fstps glob[C]\r
                                EmitByte(0xd9);EmitByte(0x1d);EmitAdr(glob + op[i].c+1);\r
 \r
                                //flds glob[V0]\r
-                               EmitByte(0xd8);EmitByte(0x0d);EmitAdr(glob + v+2);\r
+                               EmitByte(0xd9);EmitByte(0x05);EmitAdr(glob + v+2);\r
                                //fmul st(1)\r
                                EmitByte(0xd8);EmitByte(0xc9);\r
                                //fstps glob[C]\r
@@ -972,8 +1071,8 @@ EmitByte(0xcc);
                        //add $12,%esp\r
                        EmitByte(0x83); EmitByte(0xc4); EmitByte(0x0c);\r
                        break;\r
-#if 0\r
-               case OP_NOT_V:\r
+#if 1\r
+/*             case OP_NOT_V:\r
                        //flds 0\r
                        //flds glob[A+0]\r
                        //fcomip %st(1),%st\r
@@ -990,8 +1089,18 @@ EmitByte(0xcc);
                        //mov 0,C\r
                        //done:\r
                        break;\r
-\r
+*/\r
+                       \r
+               case OP_NOT_V:\r
+                       EmitByte(0xcd);EmitByte(op[i].op);\r
+                       printf("QCJIT: instruction %i is not implemented\n", op[i].op);\r
+                       break;\r
+#endif\r
+               case OP_NE_V:\r
                case OP_EQ_V:\r
+               {\r
+                       void *f0, *f1, *f2, *floc;\r
+//compare v[0]\r
                        //flds glob[A]\r
                        EmitByte(0xd9);EmitByte(0x05);EmitAdr(glob + op[i].a+0);\r
                        //flds glob[B]\r
@@ -1001,54 +1110,151 @@ EmitByte(0xcc);
                        //fstp %st(0)   (aka: pop)\r
                        EmitByte(0xdd);EmitByte(0xd8);\r
 \r
-                       //jncc _true\r
-                       if (op[i].op == OP_NE_V)\r
-                               EmitByte(0x74); //je\r
-                       else\r
-                               EmitByte(0x75); //jne\r
-                       EmitByte(0x0c);\r
-//_false0:\r
-                       //mov 0.0f,c\r
-                       EmitByte(0xc7); EmitByte(0x05); EmitAdr(glob + op[i].c); EmitFloat(1.0f);\r
-                       //jmp done\r
-                       EmitByte(0xeb); EmitByte(0x0a);\r
+                       /*if the condition is true, don't fail*/\r
+                       j1 = LocalJmp(op[i].op);\r
+                       {\r
+                               STOREF(0.0f, glob + op[i].c);\r
+                               f0 = LocalJmp(OP_GOTO);\r
+                       }\r
+                       l1 = LocalLoc();\r
+                       LocalJmpLoc(j1,l1);\r
 \r
+//compare v[1]\r
+                       //flds glob[A]\r
+                       EmitByte(0xd9);EmitByte(0x05);EmitAdr(glob + op[i].a+1);\r
+                       //flds glob[B]\r
+                       EmitByte(0xd9);EmitByte(0x05);EmitAdr(glob + op[i].b+1);\r
+                       //fcomip %st(1),%st\r
+                       EmitByte(0xdf);EmitByte(0xe9);\r
+                       //fstp %st(0)   (aka: pop)\r
+                       EmitByte(0xdd);EmitByte(0xd8);\r
 \r
-//_true:\r
-                       //mov 1.0f,c\r
-                       EmitByte(0xc7); EmitByte(0x05); EmitAdr(glob + op[i].c); EmitFloat(0.0f);\r
-//_done:\r
+                       /*if the condition is true, don't fail*/\r
+                       j1 = LocalJmp(op[i].op);\r
+                       {\r
+                               STOREF(0.0f, glob + op[i].c);\r
+                               f1 = LocalJmp(OP_GOTO);\r
+                       }\r
+                       l1 = LocalLoc();\r
+                       LocalJmpLoc(j1,l1);\r
+\r
+//compare v[2]\r
+                       //flds glob[A]\r
+                       EmitByte(0xd9);EmitByte(0x05);EmitAdr(glob + op[i].a+2);\r
+                       //flds glob[B]\r
+                       EmitByte(0xd9);EmitByte(0x05);EmitAdr(glob + op[i].b+2);\r
+                       //fcomip %st(1),%st\r
+                       EmitByte(0xdf);EmitByte(0xe9);\r
+                       //fstp %st(0)   (aka: pop)\r
+                       EmitByte(0xdd);EmitByte(0xd8);\r
+\r
+                       /*if the condition is true, don't fail*/\r
+                       j1 = LocalJmp(op[i].op);\r
+                       {\r
+                               STOREF(0.0f, glob + op[i].c);\r
+                               f2 = LocalJmp(OP_GOTO);\r
+                       }\r
+                       l1 = LocalLoc();\r
+                       LocalJmpLoc(j1,l1);\r
+\r
+//success!\r
+                       STOREF(1.0f, glob + op[i].c);\r
+\r
+                       floc = LocalLoc();\r
+                       LocalJmpLoc(f0,floc);\r
+                       LocalJmpLoc(f1,floc);\r
+                       LocalJmpLoc(f2,floc);\r
                        break;\r
+               }\r
 \r
+               /*fteqcc generates these from reading 'fast arrays', and are part of hexenc extras*/\r
+               case OP_FETCH_GBL_F:\r
+               case OP_FETCH_GBL_S:\r
+               case OP_FETCH_GBL_E:\r
+               case OP_FETCH_GBL_FNC:\r
+               case OP_FETCH_GBL_V:\r
+               {\r
+                       unsigned int max = ((unsigned int*)glob)[op[i].a-1];\r
+                       unsigned int base = op[i].a;\r
+                       //flds glob[B]\r
+                       EmitByte(0xd9); EmitByte(0x05);EmitAdr(glob + op[i].b);\r
+                       //fistp ta\r
+                       EmitByte(0xdb); EmitByte(0x1d);EmitAdr(&ta);\r
+                       LOADREG(&ta, REG_EAX)\r
+                       //FIXME: if eax >= $max, abort\r
 \r
-               case OP_EQ_V:\r
-                       EmitByte(0xcd);EmitByte(op[i].op);\r
-                       printf("QCJIT: instruction %i is not implemented\n", op[i].op);\r
+                       if (op[i].op == OP_FETCH_GBL_V)\r
+                       {\r
+                               /*scale the index by 3*/\r
+                               SETREGI(3, REG_EDX)\r
+                               //mul %edx\r
+                               EmitByte(0xf7); EmitByte(0xe2);\r
+                       }\r
+\r
+                       //lookup global\r
+                       //mov &glob[base](,%eax,4),%edx\r
+                       EmitByte(0x8b);EmitByte(0x14);EmitByte(0x85);Emit4Byte((unsigned int)(glob + base+0));\r
+                       STOREREG(REG_EDX, glob + op[i].c+0)\r
+                       if (op[i].op == OP_FETCH_GBL_V)\r
+                       {\r
+                               //mov &glob[base+1](,%eax,4),%edx\r
+                               EmitByte(0x8b);EmitByte(0x14);EmitByte(0x85);Emit4Byte((unsigned int)(glob + base+1));\r
+                               STOREREG(REG_EDX, glob + op[i].c+1)\r
+                               //mov &glob[base+2](,%eax,4),%edx\r
+                               EmitByte(0x8b);EmitByte(0x14);EmitByte(0x85);Emit4Byte((unsigned int)(glob + base+2));\r
+                               STOREREG(REG_EDX, glob + op[i].c+2)\r
+                       }\r
                        break;\r
+               }\r
 \r
-               case OP_NE_V:\r
-                       EmitByte(0xcd);EmitByte(op[i].op);\r
-                       printf("QCJIT: instruction %i is not implemented\n", op[i].op);\r
+               /*fteqcc generates these from writing 'fast arrays'*/\r
+               case OP_GLOBALADDRESS:\r
+                       LOADREG(glob + op[i].b, REG_EAX);\r
+                       //lea &glob[A](, %eax, 4),%eax\r
+                       EmitByte(0x8d);EmitByte(0x04);EmitByte(0x85);EmitAdr(glob + op[i].b+2);\r
+                       STOREREG(REG_EAX, glob + op[i].c);\r
+                       break;\r
+//             case OP_BOUNDCHECK:\r
+                       //FIXME: assert b <= a < c\r
+                       break;\r
+               case OP_CONV_FTOI:\r
+                       //flds glob[A]\r
+                       EmitByte(0xd9); EmitByte(0x05);EmitAdr(glob + op[i].a);\r
+                       //fistp glob[C]\r
+                       EmitByte(0xdb); EmitByte(0x1d);EmitAdr(glob + op[i].c);\r
+                       break;\r
+               case OP_MUL_I:\r
+                       LOADREG(glob + op[i].a, REG_EAX);\r
+                       //mull glob[C]       (arg*eax => edx:eax)\r
+                       EmitByte(0xfc); EmitByte(0x25);EmitAdr(glob + op[i].b);\r
+                       STOREREG(REG_EAX, glob + op[i].c);\r
                        break;\r
 \r
-               case OP_NOT_V:\r
-                       EmitByte(0xcd);EmitByte(op[i].op);\r
-                       printf("QCJIT: instruction %i is not implemented\n", op[i].op);\r
+               /*other extended opcodes*/\r
+               case OP_BITOR_I:\r
+                       LOADREG(glob + op[i].a, REG_EAX)\r
+                       //or %eax,tb\r
+                       EmitByte(0x0b); EmitByte(0x05);EmitAdr(glob + op[i].b);\r
+                       STOREREG(REG_EAX, glob + op[i].c);\r
                        break;\r
-#endif\r
+\r
+\r
                default:\r
-                       printf("QCJIT: Extended instruction set %i is not supported, not using jit.\n", op[i].op);\r
+                       {\r
+                               enum qcop_e e = op[i].op;\r
+                       printf("QCJIT: Extended instruction set %i is not supported, not using jit.\n", e);\r
+                       }\r
 \r
 \r
-                       free(statementjumps);   //[MAX_STATEMENTS]\r
-                       free(statementoffsets); //[MAX_STATEMENTS]\r
-                       free(code);\r
-                       statementoffsets = NULL;\r
-                       return false;\r
+                       free(jit->statementjumps);      //[MAX_STATEMENTS]\r
+                       free(jit->statementoffsets); //[MAX_STATEMENTS]\r
+                       free(jit->code);\r
+                       free(jit);\r
+                       return NULL;\r
                }\r
        }\r
 \r
-       FixupJumps();\r
+       FixupJumps(jit);\r
 \r
 #ifdef _WIN32\r
        {\r
@@ -1056,22 +1262,32 @@ EmitByte(0xcc);
 \r
                //this memory is on the heap.\r
                //this means that we must maintain read/write protection, or libc will crash us\r
-               VirtualProtect(code, codesize, PAGE_EXECUTE_READWRITE, &old);\r
+               VirtualProtect(jit->code, jit->codesize, PAGE_EXECUTE_READWRITE, &old);\r
        }\r
 #endif\r
 \r
-//     externs->WriteFile("jit.x86", code, codesize);\r
+//     externs->WriteFile("jit.x86", jit->code, jit->codesize);\r
 \r
-       return true;\r
+       return jit;\r
+}\r
+\r
+float foo(float arg)\r
+{\r
+       float f;\r
+       if (!arg)\r
+               f = 1;\r
+       else\r
+               f = 0;\r
+       return f;\r
 }\r
 \r
-void PR_EnterJIT(progfuncs_t *progfuncs, int statement)\r
+void PR_EnterJIT(progfuncs_t *progfuncs, struct jitstate *jit, int statement)\r
 {\r
 #ifdef __GNUC__\r
        //call, it clobbers pretty much everything.\r
-       asm("call *%0" :: "r"(statementoffsets[statement+1]),"b"(prinst->edicttable):"cc","memory","eax","ecx","edx");\r
+       asm("call *%0" :: "r"(jit->statementoffsets[statement+1]),"b"(prinst->edicttable):"cc","memory","eax","ecx","edx");\r
 #elif defined(_MSC_VER)\r
-       void *entry = statementoffsets[statement+1];\r
+       void *entry = jit->statementoffsets[statement+1];\r
        void *edicttable = prinst->edicttable;\r
        __asm {\r
                pushad\r
index 39c316e507c1dee03dd114ca545a13a10b04673a..e0d5cd461d7f84e78d1d46f887959bb52f78063e 100644 (file)
@@ -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
 typedef unsigned char qbyte;
 #include <stdio.h>
 
-#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];
index f3f4488a49ff4c3fe2e65376fd86bea8a8530211..1e9b612556091cc78a2e71f20b32a8761ce9d0eb 100644 (file)
@@ -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)
 
index e71ad165dffa57ab04918ec989be487dcec57eb0..5c2cd2ed79ca1e61d54be0ac78bb668665e484b4 100644 (file)
@@ -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 *);
index 8d0f874ac92fc3202754b718dedb2f0ee62fc834..f93e3e9c19683e8e884803e36543417f135d8eb0 100644 (file)
 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;
index e37d4ff2dc749855f9eb2171e8b6f68c65b1ca55..a269987703a6747564f4569afb90c175b73c269e 100644 (file)
@@ -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>", "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>", "IF",                    -1, ASSOC_RIGHT,                                &type_float, NULL, &type_void},
   {6, "<IFNOT>", "IFNOT",      -1, ASSOC_RIGHT,                        &type_float, NULL, &type_void},
-  
+
 // calls returns REG_RETURN
  {6, "<CALL0>", "CALL0",       -1, ASSOC_LEFT,                 &type_function, &type_void, &type_void},
  {6, "<CALL1>", "CALL1",       -1, ASSOC_LEFT,                 &type_function, &type_void, &type_void},
- {6, "<CALL2>", "CALL2",       -1, ASSOC_LEFT,                 &type_function, &type_void, &type_void}, 
- {6, "<CALL3>", "CALL3",       -1, ASSOC_LEFT,                 &type_function, &type_void, &type_void}, 
+ {6, "<CALL2>", "CALL2",       -1, ASSOC_LEFT,                 &type_function, &type_void, &type_void},
+ {6, "<CALL3>", "CALL3",       -1, ASSOC_LEFT,                 &type_function, &type_void, &type_void},
  {6, "<CALL4>", "CALL4",       -1, ASSOC_LEFT,                 &type_function, &type_void, &type_void},
  {6, "<CALL5>", "CALL5",       -1, ASSOC_LEFT,                 &type_function, &type_void, &type_void},
  {6, "<CALL6>", "CALL6",       -1, ASSOC_LEFT,                 &type_function, &type_void, &type_void},
  {6, "<CALL7>", "CALL7",       -1, ASSOC_LEFT,                 &type_function, &type_void, &type_void},
  {6, "<CALL8>", "CALL8",       -1, ASSOC_LEFT,                 &type_function, &type_void, &type_void},
-  
+
  {6, "<STATE>", "STATE",       -1, ASSOC_LEFT,                 &type_float, &type_float, &type_void},
-  
+
  {6, "<GOTO>", "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>", "CALL1H",     -1, ASSOC_LEFT,                 &type_function, &type_vector, &type_void},
- {7, "<CALL2H>", "CALL2H",     -1, ASSOC_LEFT,                 &type_function, &type_vector, &type_vector}, 
- {7, "<CALL3H>", "CALL3H",     -1, ASSOC_LEFT,                 &type_function, &type_vector, &type_vector}, 
+ {7, "<CALL2H>", "CALL2H",     -1, ASSOC_LEFT,                 &type_function, &type_vector, &type_vector},
+ {7, "<CALL3H>", "CALL3H",     -1, ASSOC_LEFT,                 &type_function, &type_vector, &type_vector},
  {7, "<CALL4H>", "CALL4H",     -1, ASSOC_LEFT,                 &type_function, &type_vector, &type_vector},
  {7, "<CALL5H>", "CALL5H",     -1, ASSOC_LEFT,                 &type_function, &type_vector, &type_vector},
  {7, "<CALL6H>", "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: \91old\92 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: \91i\92 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);
 }
 
index 286da96f66e3453e3021a5befee5fdff2b31f894..9bdd11c42d543d22c0c0e5a8f3ea069da45b7107 100644 (file)
@@ -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;
index a410ab084b686fe6517b619804acd52b6db8b688..cad17a6cb73e8db1788c6fb63b777afdd33a3dec 100644 (file)
@@ -2,14 +2,17 @@
 
 #define PROGSUSED
 #include "qcc.h"
-int mkdir(const char *path);
+#include <sys/stat.h>
+#ifdef _WIN32
+#include <direct.h>
+#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 ; i<nummodels ; i++)
        {
                m = precache_models[i];
@@ -294,7 +300,10 @@ void QCC_BspModels (void)
                strcpy (name, m);
                name[strlen(m)-4] = 0;
                sprintf (cmd, "qbsp %s/%s ; light -extra %s/%s", gamedir, name, gamedir, name);
-               system (cmd);
+               result = system (cmd); // do something with the result
+
+               if (result != 0)
+                       QCC_Error(ERR_INTERNAL, "QCC_BspModels() system returned non zero (failure) with: qbsp %s/%s ; light -extra %s/%s (%i)\n", gamedir, name, gamedir, name, errno);
        }
 }
 
@@ -331,7 +340,7 @@ int QCC_CopyDupBackString (char *str)
        for (s = strings+strofs-1; s>strings ; 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<strofs ; i += l)
        {
                l = strlen(strings+i) + 1;
@@ -365,7 +374,7 @@ void QCC_PrintStrings (void)
 {
        int             i,j;
        QCC_dfunction_t *d;
-       
+
        for (i=0 ; i<numfunctions ; i++)
        {
                d = &functions[i];
@@ -380,7 +389,7 @@ void QCC_PrintFields (void)
 {
        int             i;
        QCC_ddef_t      *d;
-       
+
        for (i=0 ; i<numfielddefs ; i++)
        {
                d = &fields[i];
@@ -392,7 +401,7 @@ void QCC_PrintGlobals (void)
 {
        int             i;
        QCC_ddef_t      *d;
-       
+
        for (i=0 ; i<numglobaldefs ; i++)
        {
                d = &qcc_globals[i];
@@ -455,7 +464,7 @@ int WriteSourceFiles(int h, dprograms_t *progs, pbool sourceaswell)
                num++;
        }
 
-       ofs = SafeSeek(h, 0, SEEK_CUR); 
+       ofs = SafeSeek(h, 0, SEEK_CUR);
        SafeWrite(h, &num, sizeof(int));
        SafeWrite(h, idf, sizeof(includeddatafile_t)*num);
 
@@ -471,7 +480,7 @@ void QCC_InitData (void)
        int             i;
 
        qcc_sourcefile = NULL;
-       
+
        numstatements = 1;
        strofs = 1;
        numfunctions = 1;
@@ -479,7 +488,7 @@ void QCC_InitData (void)
        numfielddefs = 1;
 
        memset(&ret_temp, 0, sizeof(ret_temp));
-       
+
        def_ret.ofs = OFS_RETURN;
        def_ret.name = "return";
        def_ret.temp = &ret_temp;
@@ -567,7 +576,8 @@ pbool QCC_WriteData (int crc)
        int                     i, len;
        pbool debugtarget = false;
        pbool types = false;
-       int outputsize = 16;
+       int outputsttype = PST_DEFAULT;
+       pbool warnedunref = false;
 
        if (numstatements==1 && numfunctions==1 && numglobaldefs==1 && numfielddefs==1)
        {
@@ -595,7 +605,7 @@ pbool QCC_WriteData (int crc)
                if (numpr_globals > 65530 )
                {
                        printf("Forcing target to FTE32 due to numpr_globals\n");
-                       outputsize = 32;
+                       outputsttype = PST_FTE32;
                }
                else if (qcc_targetformat == QCF_HEXEN2)
                {
@@ -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 ; i<numstatements ; i++)
 
-       switch(qcc_targetformat == QCF_KK7?32:outputsize)       //KK7 sucks.
+       switch(outputsttype)
        {
-       case 32:
+       case PST_KKQWSV:
+       case PST_FTE32:
                for (i=0 ; i<numstatements ; i++)
                {
                        statements[i].op = PRLittleLong/*PRLittleShort*/(statements[i].op);
@@ -920,9 +949,9 @@ strofs = (strofs+3)&~3;
                        statements[i].b = PRLittleLong/*PRLittleShort*/(statements[i].b);
                        statements[i].c = PRLittleLong/*PRLittleShort*/(statements[i].c);
                }
-               
+
                if (progs.blockscompressed&1)
-               {               
+               {
                        SafeWrite (h, &len, sizeof(int));       //save for later
                        len = QC_encode(progfuncs, numstatements*sizeof(QCC_dstatement32_t), 2, (char *)statements, h); //write
                        i = SafeSeek (h, 0, SEEK_CUR);
@@ -934,7 +963,32 @@ strofs = (strofs+3)&~3;
                else
                        SafeWrite (h, statements, numstatements*sizeof(QCC_dstatement32_t));
                break;
-       case 16:
+       case PST_QTEST:
+#define qtst ((qtest_statement_t*) statements)
+               for (i=0 ; i<numstatements ; i++) // scale down from 16-byte internal to 12-byte qtest
+               {
+                       QCC_dstatement_t stmt = statements[i];
+                       qtst[i].line = 0; // no line support
+                       qtst[i].op = PRLittleShort((unsigned short)stmt.op);
+                       if (stmt.a < 0)
+                               qtst[i].a = PRLittleShort((short)stmt.a);
+                       else
+                               qtst[i].a = (unsigned short)PRLittleShort((unsigned short)stmt.a);
+                       if (stmt.b < 0)
+                               qtst[i].b = PRLittleShort((short)stmt.b);
+                       else
+                               qtst[i].b = (unsigned short)PRLittleShort((unsigned short)stmt.b);
+                       if (stmt.c < 0)
+                               qtst[i].c = PRLittleShort((short)stmt.c);
+                       else
+                               qtst[i].c = (unsigned short)PRLittleShort((unsigned short)stmt.c);
+               }
+
+               // no compression
+               SafeWrite (h, qtst, numstatements*sizeof(qtest_statement_t));
+#undef qtst
+               break;
+       case PST_DEFAULT:
 #define statements16 ((QCC_dstatement16_t*) statements)
                for (i=0 ; i<numstatements ; i++)       //resize as we go - scaling down
                {
@@ -952,9 +1006,9 @@ strofs = (strofs+3)&~3;
                        else
                                statements16[i].c = (unsigned short)PRLittleShort((unsigned short)statements[i].c);
                }
-               
+
                if (progs.blockscompressed&1)
-               {               
+               {
                        SafeWrite (h, &len, sizeof(int));       //save for later
                        len = QC_encode(progfuncs, numstatements*sizeof(QCC_dstatement16_t), 2, (char *)statements16, h);       //write
                        i = SafeSeek (h, 0, SEEK_CUR);
@@ -967,37 +1021,88 @@ strofs = (strofs+3)&~3;
                        SafeWrite (h, statements16, numstatements*sizeof(QCC_dstatement16_t));
                break;
        default:
-               Sys_Error("intsize error");
+               Sys_Error("structtype error");
        }
 
        progs.ofs_functions = SafeSeek (h, 0, SEEK_CUR);
        progs.numfunctions = numfunctions;
-       for (i=0 ; i<numfunctions ; i++)
+
+       switch (outputsttype)
        {
-               functions[i].first_statement = PRLittleLong (functions[i].first_statement);
-               functions[i].parm_start = PRLittleLong (functions[i].parm_start);
-               functions[i].s_name = PRLittleLong (functions[i].s_name);
-               functions[i].s_file = PRLittleLong (functions[i].s_file);
-               functions[i].numparms = PRLittleLong ((functions[i].numparms>MAX_PARMS)?MAX_PARMS:functions[i].numparms);
-               functions[i].locals = PRLittleLong (functions[i].locals);
-       }
+       case PST_QTEST:
+               {
+                       // this sucks but the structures are just too different
+                       qtest_function_t *qtestfuncs = (qtest_function_t *)qccHunkAlloc(sizeof(qtest_function_t)*numfunctions);
 
-       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 ; i<numfunctions ; i++)
+                       {
+                               int j;
+
+                               qtestfuncs[i].unused1 = 0;
+                               qtestfuncs[i].profile = 0;
+                               qtestfuncs[i].first_statement = PRLittleLong (functions[i].first_statement);
+                               qtestfuncs[i].parm_start = PRLittleLong (functions[i].parm_start);
+                               qtestfuncs[i].s_name = PRLittleLong (functions[i].s_name);
+                               qtestfuncs[i].s_file = PRLittleLong (functions[i].s_file);
+                               qtestfuncs[i].numparms = PRLittleLong ((functions[i].numparms>MAX_PARMS)?MAX_PARMS:functions[i].numparms);
+                               qtestfuncs[i].locals = PRLittleLong (functions[i].locals);
+                               for (j = 0; j < MAX_PARMS; j++)
+                                       qtestfuncs[i].parm_size[j] = PRLittleLong((int)functions[i].parm_size[j]);
+                       }
+
+                       SafeWrite (h, qtestfuncs, numfunctions*sizeof(qtest_function_t));
+               }
+               break;
+       case PST_DEFAULT:
+       case PST_KKQWSV:
+       case PST_FTE32:
+               for (i=0 ; i<numfunctions ; i++)
+               {
+                       functions[i].first_statement = PRLittleLong (functions[i].first_statement);
+                       functions[i].parm_start = PRLittleLong (functions[i].parm_start);
+                       functions[i].s_name = PRLittleLong (functions[i].s_name);
+                       functions[i].s_file = PRLittleLong (functions[i].s_file);
+                       functions[i].numparms = PRLittleLong ((functions[i].numparms>MAX_PARMS)?MAX_PARMS:functions[i].numparms);
+                       functions[i].locals = PRLittleLong (functions[i].locals);
+               }
+
+               if (progs.blockscompressed&8)
+               {
+                       SafeWrite (h, &len, sizeof(int));       //save for later
+                       len = QC_encode(progfuncs, numfunctions*sizeof(QCC_dfunction_t), 2, (char *)functions, h);      //write
+                       i = SafeSeek (h, 0, SEEK_CUR);
+                       SafeSeek(h, progs.ofs_functions, SEEK_SET);//seek back
+                       len = PRLittleLong(len);
+                       SafeWrite (h, &len, sizeof(int));       //write size.
+                       SafeSeek(h, i, SEEK_SET);
+               }
+               else
+                       SafeWrite (h, functions, numfunctions*sizeof(QCC_dfunction_t));
+               break;
+       default:
+               Sys_Error("structtype error");
        }
-       else
-               SafeWrite (h, functions, numfunctions*sizeof(QCC_dfunction_t));
 
-       switch(outputsize)
+       switch(outputsttype)
        {
-       case 32:
+       case PST_QTEST:
+               // qtest needs a struct remap but should be able to get away with a simple swap here
+               for (i=0 ; i<numglobaldefs ; i++)
+               {
+                       qtest_def_t qtdef = ((qtest_def_t *)qcc_globals)[i];
+                       qcc_globals[i].type = qtdef.type;
+                       qcc_globals[i].ofs = qtdef.ofs;
+                       qcc_globals[i].s_name = qtdef.s_name;
+               }
+               for (i=0 ; i<numfielddefs ; i++)
+               {
+                       qtest_def_t qtdef = ((qtest_def_t *)fields)[i];
+                       fields[i].type = qtdef.type;
+                       fields[i].ofs = qtdef.ofs;
+                       fields[i].s_name = qtdef.s_name;
+               }
+               // passthrough.. reuse FTE32 code
+       case PST_FTE32:
                progs.ofs_globaldefs = SafeSeek (h, 0, SEEK_CUR);
                progs.numglobaldefs = numglobaldefs;
                for (i=0 ; i<numglobaldefs ; i++)
@@ -1008,7 +1113,7 @@ strofs = (strofs+3)&~3;
                }
 
                if (progs.blockscompressed&2)
-               {               
+               {
                        SafeWrite (h, &len, sizeof(int));       //save for later
                        len = QC_encode(progfuncs, numglobaldefs*sizeof(QCC_ddef_t), 2, (char *)qcc_globals, h);        //write
                        i = SafeSeek (h, 0, SEEK_CUR);
@@ -1031,7 +1136,7 @@ strofs = (strofs+3)&~3;
                }
 
                if (progs.blockscompressed&4)
-               {               
+               {
                        SafeWrite (h, &len, sizeof(int));       //save for later
                        len = QC_encode(progfuncs, numfielddefs*sizeof(QCC_ddef_t), 2, (char *)fields, h);      //write
                        i = SafeSeek (h, 0, SEEK_CUR);
@@ -1043,7 +1148,8 @@ strofs = (strofs+3)&~3;
                else
                        SafeWrite (h, fields, numfielddefs*sizeof(QCC_ddef_t));
                break;
-       case 16:
+       case PST_KKQWSV:
+       case PST_DEFAULT:
 #define qcc_globals16 ((QCC_ddef16_t*)qcc_globals)
 #define fields16 ((QCC_ddef16_t*)fields)
                progs.ofs_globaldefs = SafeSeek (h, 0, SEEK_CUR);
@@ -1056,7 +1162,7 @@ strofs = (strofs+3)&~3;
                }
 
                if (progs.blockscompressed&2)
-               {               
+               {
                        SafeWrite (h, &len, sizeof(int));       //save for later
                        len = QC_encode(progfuncs, numglobaldefs*sizeof(QCC_ddef16_t), 2, (char *)qcc_globals16, h);    //write
                        i = SafeSeek (h, 0, SEEK_CUR);
@@ -1079,7 +1185,7 @@ strofs = (strofs+3)&~3;
                }
 
                if (progs.blockscompressed&4)
-               {               
+               {
                        SafeWrite (h, &len, sizeof(int));       //save for later
                        len = QC_encode(progfuncs, numfielddefs*sizeof(QCC_ddef16_t), 2, (char *)fields16, h);  //write
                        i = SafeSeek (h, 0, SEEK_CUR);
@@ -1092,7 +1198,7 @@ strofs = (strofs+3)&~3;
                        SafeWrite (h, fields16, numfielddefs*sizeof(QCC_ddef16_t));
                break;
        default:
-               Sys_Error("intsize error");
+               Sys_Error("structtype error");
        }
 
        progs.ofs_globals = SafeSeek (h, 0, SEEK_CUR);
@@ -1102,7 +1208,7 @@ strofs = (strofs+3)&~3;
                ((int *)qcc_pr_globals)[i] = PRLittleLong (((int *)qcc_pr_globals)[i]);
 
        if (progs.blockscompressed&32)
-       {               
+       {
                SafeWrite (h, &len, sizeof(int));       //save for later
                len = QC_encode(progfuncs, numpr_globals*4, 2, (char *)qcc_pr_globals, h);      //write
                i = SafeSeek (h, 0, SEEK_CUR);
@@ -1112,7 +1218,7 @@ strofs = (strofs+3)&~3;
                SafeSeek(h, i, SEEK_SET);
        }
        else
-               SafeWrite (h, qcc_pr_globals, numpr_globals*4); 
+               SafeWrite (h, qcc_pr_globals, numpr_globals*4);
 
        if (types)
        for (i=0 ; i<numtypeinfos ; i++)
@@ -1121,7 +1227,7 @@ strofs = (strofs+3)&~3;
                        qcc_typeinfo[i].aux_type = (QCC_type_t*)(qcc_typeinfo[i].aux_type - qcc_typeinfo);
                if (qcc_typeinfo[i].next)
                        qcc_typeinfo[i].next = (QCC_type_t*)(qcc_typeinfo[i].next - qcc_typeinfo);
-               qcc_typeinfo[i].name = (char *)QCC_CopyDupBackString(qcc_typeinfo[i].name);
+               qcc_typeinfo[i].name = (char*)QCC_CopyDupBackString(qcc_typeinfo[i].name);
        }
 
        progs.ofsfiles = 0;
@@ -1134,6 +1240,9 @@ strofs = (strofs+3)&~3;
 
        switch(qcc_targetformat)
        {
+       case QCF_QTEST:
+               progs.version = PROG_QTESTVERSION;
+               break;
        case QCF_KK7:
                progs.version = PROG_KKQWSVVERSION;
                break;
@@ -1146,19 +1255,19 @@ strofs = (strofs+3)&~3;
        case QCF_FTEDEBUG:
                progs.version = PROG_EXTENDEDVERSION;
 
-               if (outputsize == 32)
+               if (outputsttype == PST_FTE32)
                        progs.secondaryversion = PROG_SECONDARYVERSION32;
                else
                        progs.secondaryversion = PROG_SECONDARYVERSION16;
 
                progs.ofsbodylessfuncs = SafeSeek (h, 0, SEEK_CUR);
-               progs.numbodylessfuncs = WriteBodylessFuncs(h);         
+               progs.numbodylessfuncs = WriteBodylessFuncs(h);
 
                if (debugtarget)
                {
                        progs.ofslinenums = SafeSeek (h, 0, SEEK_CUR);
                        if (progs.blockscompressed&64)
-                       {               
+                       {
                                SafeWrite (h, &len, sizeof(int));       //save for later
                                len = QC_encode(progfuncs, numstatements*sizeof(int), 2, (char *)statement_linenums, h);        //write
                                i = SafeSeek (h, 0, SEEK_CUR);
@@ -1177,7 +1286,7 @@ strofs = (strofs+3)&~3;
                {
                        progs.ofs_types = SafeSeek (h, 0, SEEK_CUR);
                        if (progs.blockscompressed&128)
-                       {               
+                       {
                                SafeWrite (h, &len, sizeof(int));       //save for later
                                len = QC_encode(progfuncs, sizeof(QCC_type_t)*numtypeinfos, 2, (char *)qcc_typeinfo, h);        //write
                                i = SafeSeek (h, 0, SEEK_CUR);
@@ -1188,7 +1297,7 @@ strofs = (strofs+3)&~3;
                        }
                        else
                                SafeWrite (h, qcc_typeinfo, sizeof(QCC_type_t)*numtypeinfos);
-                       progs.numtypes = numtypeinfos;          
+                       progs.numtypes = numtypeinfos;
                }
                else
                {
@@ -1210,9 +1319,9 @@ strofs = (strofs+3)&~3;
 // qbyte swap the header and write it out
 
        for (i=0 ; i<sizeof(progs)/4 ; i++)
-               ((int *)&progs)[i] = PRLittleLong ( ((int *)&progs)[i] );               
+               ((int *)&progs)[i] = PRLittleLong ( ((int *)&progs)[i] );
+
 
-       
        SafeSeek (h, 0, SEEK_SET);
        SafeWrite (h, &progs, sizeof(progs));
        SafeClose (h);
@@ -1259,7 +1368,7 @@ char *QCC_PR_String (char *string)
 {
        static char buf[80];
        char    *s;
-       
+
        s = buf;
        *s++ = '"';
        while (string && *string)
@@ -1297,7 +1406,7 @@ char *QCC_PR_String (char *string)
 QCC_def_t      *QCC_PR_DefForFieldOfs (gofs_t ofs)
 {
        QCC_def_t       *d;
-       
+
        for (d=pr.def_head.next ; d ; d=d->next)
        {
                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 ; i<RESERVED_OFS ; i++)
                pr_global_defs[i] = &def_void;
 */
-       
+
        type_void = QCC_PR_NewType("void", ev_void);
        type_string = QCC_PR_NewType("string", ev_string);
        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);
 
@@ -1552,7 +1661,7 @@ void      QCC_PR_BeginCompilation (void *memory, int memsize)
                type_integer = QCC_PR_NewType("integer", ev_integer);
        if (keyword_int)
                type_integer = QCC_PR_NewType("int", ev_integer);
-       
+
 
 
        if (output_parms)
@@ -1594,9 +1703,9 @@ int QCC_PR_FinishCompilation (void)
 {
        QCC_def_t               *d;
        int     errors;
-       
+
        errors = false;
-       
+
 // check to make sure all functions prototyped have code
        for (d=pr.def_head.next ; d ; d=d->next)
        {
@@ -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->ofs<RESERVED_OFS)
                        continue;
-                       
+
                switch (d->type->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 ; i<numfunctions ; i++)
                if (!strcmp (name, strings + functions[i].s_name))
                        break;
        if (i==numfunctions)
                QCC_Error (ERR_NOFUNC, "No function named \"%s\"", name);
-       df = functions + i;     
-       
+       df = functions + i;
+
        printf ("Statements for function %s:\n", name);
        ds = statements + df->first_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<numsounds ; i++)
        {
                if (precache_sounds_block[i] != blocknum)
-                       continue;               
+                       continue;
                sprintf (srcfile,"%s%s",srcdir, precache_sounds[i]);
                sprintf (destfile,"%s%s",destdir, precache_sounds[i]);
                if (copytype == 1)
@@ -2265,7 +2376,7 @@ void _QCC_CopyFiles (int blocknum, int copytype, char *srcdir, char *destdir)
                else
                        QCC_PackFile (srcfile, precache_files[i]);
        }
-       
+
        if (copytype == 2)
        {
                header.id[0] = 'P';
@@ -2275,18 +2386,18 @@ void _QCC_CopyFiles (int blocknum, int copytype, char *srcdir, char *destdir)
                dirlen = (qbyte *)pf - (qbyte *)pfiles;
                header.dirofs = PRLittleLong(SafeSeek (packhandle, 0, SEEK_CUR));
                header.dirlen = PRLittleLong(dirlen);
-               
+
                SafeWrite (packhandle, pfiles, dirlen);
-       
+
                SafeSeek (packhandle, 0, SEEK_SET);
                SafeWrite (packhandle, &header, sizeof(header));
-               SafeClose (packhandle); 
-       
+               SafeClose (packhandle);
+
        // do a crc of the file
                QCC_CRC_Init (&crc);
                for (i=0 ; i<dirlen ; i++)
                        QCC_CRC_ProcessByte (&crc, ((qbyte *)pfiles)[i]);
-       
+
                i = pf - pfiles;
                printf ("%i files packed in %i bytes (%i crc)\n",i, packbytes, crc);
        }
@@ -2296,7 +2407,7 @@ void QCC_CopyFiles (void)
 {
        char *s;
        char    srcdir[1024], destdir[1024];
-       int             p;                                      
+       int             p;
 
        if (verbose)
        {
@@ -2327,7 +2438,7 @@ void QCC_CopyFiles (void)
 
        for ( p = 0; p < 5; p++)
        {
-               s = QCC_Packname[p];            
+               s = QCC_Packname[p];
                if (!*s)
                        continue;
                strcpy(destdir, s);
@@ -2351,7 +2462,7 @@ void QCC_CopyFiles (void)
                        strcat (srcdir, "/");
                DefaultExtension (destdir, ".pak");
 
-       
+
                copytype = 2;
 
                _QCC_CopyFiles(blocknum, copytype, srcdir, destdir);
@@ -2383,10 +2494,8 @@ void QCC_PR_CommandLinePrecompilerOptions (void)
                        cnst = QCC_PR_DefineName(name);
                        if (val)
                        {
-                               if (strlen(val)+1 >= 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);
-       
+
 }*/
 
 
index f98e5336a301aa83a9300db241917d55e27041a7..20c6f7ca0e09d1d153a854fa8a596c7ef91f20e4 100644 (file)
@@ -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 <zlib.h>
 #endif
index d1fcabf519c4e6464ac5b8486d99c374e73c5b17..24fc433f604e28c8ce37124fe6a1655ff89ec17f 100644 (file)
@@ -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 *)&current_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;
-                       
+
                }
        }
 
index b0a1d4a27f13939635580c63a1b06c4ba21f821f..8f7d036c4dfb2224c0d617d64495ac788ab427c9 100644 (file)
@@ -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
index 5a956f926ec3c5428854d091a634b728b505f29c..a10773d6fc8f5c307516b23373db556d7e10f047 100644 (file)
@@ -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 <list>
+#include <stdlib.h>
 
 typedef struct
 {      
index 3c4ed75e5f54bdeb1a8ac4ec787174b38f0cddff..29bca7fc9130e1cd6e4b0afdfcf8a56854e40964 100644 (file)
@@ -28,6 +28,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 #pragma once
 #endif // _MSC_VER > 1000
 
+#include <stdlib.h>
 #include "mathlib.h"
 #include "DMap.h"
 class DBrush;
index 2d6c1b7890e9047a8a46e35910e5303ed1519b3a..f31c5443561df176a8b667d0448bd5ef43562221 100644 (file)
@@ -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
index 798a7d142adcfe1e00af7757efe3fdff85d391f8..9f4e3e2b9a349b64c9915073b3dcf49c1cd7b8e8 100644 (file)
@@ -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"
index 1f14966653cb80b7c00f6966b7f9717bb2defb45..3a36c200ecdd6a6c3e1f788903d249ad25f877b7 100644 (file)
@@ -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
index c513d708d7a8594e63544a549c1284b672951ad5..ebaeeb5ba756a166279534642d17541a213051dc 100644 (file)
@@ -23,6 +23,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 #define INCLUDED_MEMORY_ALLOCATOR_H
 
 #include <memory>
+#include <stddef.h>
 
 #if 0
 
index 1e6f8920d8807d7af3c4e31afbb0d54c51e5d9be..a771e9438d3fae7cba27e58dffb831ffaeee76d7 100644 (file)
@@ -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
index 56c756c325d62302ea700d922999bf7ca05e28c9..9e45bfa1fe57f1f928334dc221cc781b4907096f 100644 (file)
@@ -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;
index f12e3a362b86a9fe4bd4bbdda60a2827bcd28ae0..cb2a70eae4de33a2d1e13ec91f3438f6a6d2e9f0 100644 (file)
@@ -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;
index aed467cacd49edbe0005ff2852dbb8a3d8bf6a26..86ec08bde5d001fb2e43caa8e57b3f605b3760ea 100644 (file)
@@ -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 );
        }
 
index 31c448e68c0fb7e21d781c8106aa40f1c9575703..6905431e3234c0b2e569502bad636da009dff90e 100644 (file)
@@ -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);
index 1065160e64792f4bb15d37b768a24abc0b05e1c9..0fc6581360a95943e57c20dbd668f6f13f9d35df 100644 (file)
@@ -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;
 
index d53f70295467081d1296d15a2b40b23cd33bf946..19b5689ccd070895411c970f70efd3146c2a359f 100644 (file)
@@ -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; i<md2->numTris; i++)
        {
index 7f269faa009b1a23063041ad7e2cf166014c9d8a..1f77eeb1191d7a464b383f0deb8748b839ec264a 100644 (file)
@@ -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 );
index f16d419973e7bd3e0117329675adaddf1ba873e8..67c0680f38c63d13e7d5c32b2196a27fb04bc728 100644 (file)
@@ -24,6 +24,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 
 
 #include <list>
+#include <vector>
 #include "generic/callback.h"
 #include "generic/static.h"
 
index b47942ba9149e2394fdaafc35cc2783b47c26902..86a2ac85f4cead9909bd9a033ac73e255fb1f4ed 100644 (file)
@@ -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;
 
index 21cec0ee8b8ff385cc766cf8f47e452bc301c128..3cdf77a829a04b2f8aac9bb7208b688d5b22e3d5 100644 (file)
@@ -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),
index f30fb9808a1a6ca9180f7203e5bbd7672616a7be..a0afdeeb852efccb4fd4beea624cce24305713ca 100644 (file)
@@ -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);
         }
index b5636780bfda49a39627ecb35ef0848185680d5a..95f03f7378326bd34f4cd01a204b1589fce58056 100644 (file)
@@ -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);
+}
index 62a69ab6644237c7213fde9b86dce5967ebc34c8..130c9657eceaa1f65def7e42bcede5381a118adb 100644 (file)
@@ -27,5 +27,6 @@ typedef struct _GtkWindow GtkWindow;
 GtkWidget* EntityInspector_constructWindow(GtkWindow* parent);
 void EntityInspector_construct();
 void EntityInspector_destroy();
+const char *EntityInspector_getCurrentKey();
 
 #endif
index 92caffabe2689be8af5d2f8114cc986a0a2875e6..38f399be01646299e47cc73eec3847267a7d1453 100644 (file)
@@ -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
index c8a739b6f6939952f32845849e74b8c5b6252d5e..546ba9d7a772d8df5965d4a74d37b3628d3beeb6 100644 (file)
@@ -184,22 +184,88 @@ void VFS_Destroy()
 
 // Home Paths
 
+#ifdef WIN32
+#include <shlobj.h>
+#include <objbase.h>
+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);
index 5997abd34e286fc9d36c3c9fe2049e025c3f207a..d011f3198cc32c8ec8d3fc9ec44a5db97fb0d69d 100644 (file)
@@ -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
index 572459907e56867d1e820a877da5c78dc226f7eb..ec412965883f92352d5465d50c8b9fe61ea3133d 100644 (file)
@@ -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 ");
index 67ffebeccb3d38e5a88405cbe307b1821f30959a..19d1d37c0df4dd1ae45c5f36637faa4d983578eb 100644 (file)
@@ -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)
     // ~/.<gameprefix>/<fs_game>
+    if(userRoot)
     {
       StringOutputStream userGamePath(256);
       userGamePath << userRoot << gamename << '/';
       GlobalFileSystem().initDirectory(userGamePath.c_str());
     }
-#endif
 
     // <fs_basepath>/<fs_game>
     {
@@ -103,14 +100,13 @@ void QE_InitVFS()
     }
   }
 
-#if defined(POSIX)
   // ~/.<gameprefix>/<fs_main>
+  if(userRoot)
   {
     StringOutputStream userBasePath(256);
     userBasePath << userRoot << basegame << '/';
     GlobalFileSystem().initDirectory(userBasePath.c_str());
   }
-#endif
 
   // <fs_basepath>/<fs_main>
   {
@@ -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());
 
index 5889fd5a1c69fb9d3753f18eb2e86c68d43a7ff4..f4e8b7f9d6f0af3bcda2389513448424448eea6a 100644 (file)
@@ -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<const char*> Classnames;
+typedef std::vector<const char*> 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
     {
index 3b4779905eca61df0ff25f04daec989d0dd76b66..d2283d4537452ccb93c185e68716427b1278dc9a 100644 (file)
@@ -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);
       }
index 31e31850bdfb9b141a6f0f943bb0104566058472..b95fe971749b935258406bc4c08261b1ba5f0ed5 100644 (file)
@@ -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);
index 47196e53aa9ce9cea642698032334f526eec882c..5502d35af3de3162471ebc10d63331c5bd1c07fc 100644 (file)
@@ -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 );
index 86a749c754ca2cadc9a647f9c9fa3e2d52594209..9c75cb3a8549b0dc5fba3d1cc63069ce3672ffdd 100644 (file)
@@ -46,6 +46,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include <sys/stat.h>
 
 #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;
 
index 56262311b77bcd124ffeea19d836ce742a38b77d..f16a9d08478e65703834d7a663cb6b07abe220a7 100644 (file)
@@ -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 );
index 0f37665d672aef5ba8136d2d23bed45416db7c02..418ee27a10750e5403d783ef33aa81ac9e6fabdc 100644 (file)
@@ -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
                                           );
                        }
index 08e75e11c08041a525487f6695f093cc530e3b03..15c1e06c05be173cac9040002178b1042382a402 100644 (file)
@@ -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 */
index 9291f5649fc8dc63decd9e77f6e7293b2d60f815..f9f2f2075570b624b29ab4f7a4dbc520a2ea0490 100644 (file)
@@ -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 );
index 929b15d96cf5ec6c5e256955c16d0b40f0d9fdda..7ce08aaaf88e5e3d621bf3b3e757f53e7e7f3546 100644 (file)
@@ -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 */
index 9323b8c8e3b7a4430244b7b6c12354b92466c6df..5d5dfc5e9aa4cdb77bbd646fb4ec1d6cf4a2c7a8 100644 (file)
@@ -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;
index 7db00613b6fae9ea28530bb5b610335a3df922a3..0e59ddeb451ded78f158b14ba9eba9eb6f6c1f2e 100644 (file)
@@ -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;
index 8e79244e542dbebed1661275af89e0f52ca07397..84e4ab0eef12c97709e15eec8b606f3326cdfd9b 100644 (file)
@@ -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;
index f60e6645e4b57844c9ed96b9dc23ff6f8ba67fbe..f291e7a5871da5303bceeb9bb8fc688f1401026a 100644 (file)
@@ -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;
index 080f26ec5002441991c97388ecb5028fc577fa08..5c5340534e14f60a87c6557327a097f67ca2e375 100644 (file)
@@ -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;
index 074a4a437732d5621022af0037d2b15c074687ca..5ee35cd5f88049cc7ec097515570c29984c3d97b 100644 (file)
@@ -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 */
index 95bb3d1f74141968c369d8fe3ccd34b72fc45afc..9534bdb3111912190a8d972cb20133b116f6a4f1 100644 (file)
@@ -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);
 }
 
 
index a56134c82777066c33851d4a8e33f60e6ad6c22a..2b3bb7ed5f0059d5c1cc18862c65e47517b36f08 100644 (file)
@@ -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 );
index 9cd707e224284fb3f2770bafb4e07e0847c77f07..b977dc7dc4bfab4c02436a503906408e8cff3a02 100644 (file)
@@ -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();
index 83383e2287ba3cdae523ab375748b7cb2387b046..4994c5f5712af05ac4fa3c7e967e97d86ecffaed 100644 (file)
@@ -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 */
index 3bf6cbe1ea4d1eb401954dfe9bf61d99eece5ce3..dcbf79d2c99b088129cf7ed3ee5ed3f48179a1f9 100644 (file)
@@ -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 ];
                        }
index ca4f5fa6ebd28138f4978040c365524d4d7d292a..b5dd724e15d9ee564b548f465129ec8d80108ff3 100644 (file)
@@ -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 */
index 0e300dde069625a8547b19dcfdaad38a7b19bdfe..8a6848559b13a5e114ebf62e506407a097ed5781 100644 (file)
@@ -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 ) );
index cde7ece495bdb6fffcec38192ae4579401b75221..1ecd1ac3d04a9557d0ae3269ecf82e20410e2ce8 100644 (file)
@@ -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 ) {