+++ /dev/null
-#ifndef MINIMAL
-
-#include "progsint.h"
-#include "setjmp.h"
-
-#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;
-
- struct QCC_type_s *next;
-// 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
-
- int ofs; //inside a structure.
- int size;
- char *name;
-
-} QCC_type_t;
-
-
-extern QCC_type_t *qcc_typeinfo;
-extern int numtypeinfos;
-extern int maxtypeinfos;
-extern QCC_type_t *type_void;// = {ev_void/*, &def_void*/};
-extern QCC_type_t *type_string;// = {ev_string/*, &def_string*/};
-extern QCC_type_t *type_float;// = {ev_float/*, &def_float*/};
-extern QCC_type_t *type_vector;// = {ev_vector/*, &def_vector*/};
-extern QCC_type_t *type_entity;// = {ev_entity/*, &def_entity*/};
-extern QCC_type_t *type_field;// = {ev_field/*, &def_field*/};
-extern QCC_type_t *type_function;// = {ev_function/*, &def_function*/,NULL,&type_void};
-// type_function is a void() function used for state defs
-extern QCC_type_t *type_pointer;// = {ev_pointer/*, &def_pointer*/};
-extern QCC_type_t *type_integer;// = {ev_integer/*, &def_integer*/};
-extern QCC_type_t *type_floatpointer;
-extern QCC_type_t *type_intpointer;
-
-extern QCC_type_t *type_floatfield;// = {ev_field/*, &def_field*/, NULL, &type_float};
-QCC_type_t *QCC_PR_NewType (char *name, int basictype, pbool typedefed);
-
-
-jmp_buf decompilestatementfailure;
-
-#if 0
-pbool Decompile(progfuncs_t *progfuncs, char *fname)
-{
- return false;
-}
-#else
-
-QCC_type_t **ofstype;
-qbyte *ofsflags;
-
-int SafeOpenWrite (char *filename, int maxsize);
-void SafeWrite(int hand, void *buf, long count);
-int SafeSeek(int hand, int ofs, int mode);
-void SafeClose(int hand);
-void VARGS writes(int hand, char *msg, ...)
-{
- va_list va;
- char buf[4192];
-
- va_start(va, msg);
- Q_vsnprintf (buf,sizeof(buf)-1, msg, va);
- va_end(va);
-
- SafeWrite(hand, buf, strlen(buf));
-};
-
-char *PR_UglyValueString (etype_t type, eval_t *val);
-ddef16_t *ED_GlobalAtOfs16 (progfuncs_t *progfuncs, int ofs);
-char *VarAtOfs(progfuncs_t *progfuncs, int ofs)
-{
- static char buf [4192];
- ddef16_t *def;
- int typen;
-
- if (ofsflags[ofs]&8)
- def = ED_GlobalAtOfs16(progfuncs, ofs);
- else
- def = NULL;
- if (!def)
- {
- if (ofsflags[ofs]&3)
- {
- if (ofstype[ofs])
- sprintf(buf, "_v_%s_%i", ofstype[ofs]->name, ofs);
- else
- sprintf(buf, "_v_%i", ofs);
- }
- else
- {
- if (ofstype[ofs])
- {
- typen = ofstype[ofs]->type;
- goto evaluateimmediate;
- }
- else
- sprintf(buf, "_c_%i", ofs);
- }
- return buf;
- }
- if (!def->s_name[progfuncs->stringtable] || !strcmp(progfuncs->stringtable+def->s_name, "IMMEDIATE"))
- {
- if (current_progstate->types)
- typen = current_progstate->types[def->type & ~DEF_SHARED].type;
- else
- typen = def->type & ~(DEF_SHARED|DEF_SAVEGLOBAL);
-
-evaluateimmediate:
-// return PR_UglyValueString(def->type, (eval_t *)¤t_progstate->globals[def->ofs]);
- switch(typen)
- {
- case ev_float:
- sprintf(buf, "%f", G_FLOAT(ofs));
- return buf;
- case ev_vector:
- sprintf(buf, "\'%f %f %f\'", G_FLOAT(ofs), G_FLOAT(ofs+1), G_FLOAT(ofs+2));
- return buf;
- case ev_string:
- {
- char *s, *s2;
- s = buf;
- *s++ = '\"';
- s2 = pr_strings+G_INT(ofs);
-
-
- if (s2)
- while(*s2)
- {
- if (*s2 == '\n')
- {
- *s++ = '\\';
- *s++ = 'n';
- s2++;
- }
- else if (*s2 == '\"')
- {
- *s++ = '\\';
- *s++ = '\"';
- s2++;
- }
- else if (*s2 == '\t')
- {
- *s++ = '\\';
- *s++ = 't';
- s2++;
- }
- else
- *s++=*s2++;
- }
- *s++ = '\"';
- *s++ = '\0';
- }
- return buf;
- case ev_pointer:
- sprintf(buf, "_c_pointer_%i", ofs);
- return buf;
- default:
- sprintf(buf, "_c_%i", ofs);
- return buf;
- }
- }
- return def->s_name+progfuncs->stringtable;
-}
-
-
-int file;
-
-int ImmediateReadLater(progfuncs_t *progfuncs, progstate_t *progs, unsigned int ofs, int firstst)
-{
- dstatement16_t *st;
- if (ofsflags[ofs] & 8)
- return false; //this is a global/local/pramater, not a temp
- 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.
- if (st->op >= OP_CALL0 && st->op <= OP_CALL8)
- {
- if (ofs == OFS_RETURN)
- return false;
- if (ofs < OFS_PARM0 + 3*((unsigned int)st->op - OP_CALL0))
- return true;
- }
- else if (pr_opcodes[st->op].associative == ASSOC_RIGHT)
- {
- if (ofs == st->b)
- return false;
- if (ofs == st->a)
- return true;
- }
- else
- {
- if (st->a == ofs)
- return true;
- if (st->b == ofs)
- return true;
- if (st->c == ofs)
- return false;
- }
-
- if (st->op == OP_DONE || st->op == OP_RETURN) //we missed our chance. (return/done ends any code coherancy).
- return false;
- }
- return false;
-}
-int ProductReadLater(progfuncs_t *progfuncs, progstate_t *progs, int stnum)
-{
- dstatement16_t *st;
- st = &((dstatement16_t*)progs->statements)[stnum];
- if (pr_opcodes[st->op].priority == -1)
- {
- if (st->op >= OP_CALL0 && st->op <= OP_CALL7)
- return ImmediateReadLater(progfuncs, progs, OFS_RETURN, stnum+1);
- return false;//these don't have products...
- }
-
- if (pr_opcodes[st->op].associative == ASSOC_RIGHT)
- return ImmediateReadLater(progfuncs, progs, st->b, stnum+1);
- else
- return ImmediateReadLater(progfuncs, progs, st->c, stnum+1);
-}
-
-void WriteStatementProducingOfs(progfuncs_t *progfuncs, progstate_t *progs, int lastnum, int firstpossible, int ofs) //recursive, works backwards
-{
- int i;
- dstatement16_t *st;
- ddef16_t *def;
- if (ofs == 0)
- longjmp(decompilestatementfailure, 1);
- for (; lastnum >= firstpossible; lastnum--)
- {
- st = &((dstatement16_t*)progs->statements)[lastnum];
- if (st->op >= OP_CALL0 && st->op < OP_CALL7)
- {
- if (ofs != OFS_RETURN)
- continue;
- WriteStatementProducingOfs(progfuncs, progs, lastnum-1, firstpossible, st->a);
- writes(file, "(");
- for (i = 0; i < st->op - OP_CALL0; i++)
- {
- WriteStatementProducingOfs(progfuncs, progs, lastnum-1, firstpossible, OFS_PARM0 + i*3);
- if (i != st->op - OP_CALL0-1)
- writes(file, ", ");
- }
- writes(file, ")");
- return;
- }
- else if (pr_opcodes[st->op].associative == ASSOC_RIGHT)
- {
- if (st->b != ofs)
- continue;
- if (!ImmediateReadLater(progfuncs, progs, st->b, lastnum+1))
- {
- writes(file, "(");
- WriteStatementProducingOfs(progfuncs, progs, lastnum-1, firstpossible, st->b);
- writes(file, " ");
- writes(file, pr_opcodes[st->op].name);
- writes(file, " ");
- WriteStatementProducingOfs(progfuncs, progs, lastnum-1, firstpossible, st->a);
- writes(file, ")");
- return;
- }
- WriteStatementProducingOfs(progfuncs, progs, lastnum-1, firstpossible, st->a);
- return;
- }
- else
- {
- if (st->c != ofs)
- continue;
-
- if (!ImmediateReadLater(progfuncs, progs, st->c, lastnum+1))
- {
- WriteStatementProducingOfs(progfuncs, progs, lastnum-1, firstpossible, st->c);
- writes(file, " = ");
- }
- writes(file, "(");
- WriteStatementProducingOfs(progfuncs, progs, lastnum-1, firstpossible, st->a);
-
- if (!strcmp(pr_opcodes[st->op].name, "."))
- writes(file, pr_opcodes[st->op].name); //extra spaces around .s are ugly.
- else
- {
- writes(file, " ");
- writes(file, pr_opcodes[st->op].name);
- writes(file, " ");
- }
- WriteStatementProducingOfs(progfuncs, progs, lastnum-1, firstpossible, st->b);
- writes(file, ")");
- return;
- }
- }
-
- def = ED_GlobalAtOfs16(progfuncs, ofs);
- if (def)
- {
- if (!strcmp(def->s_name+progfuncs->stringtable, "IMMEDIATE"))
- writes(file, "%s", VarAtOfs(progfuncs, ofs));
- else
- writes(file, "%s", progfuncs->stringtable+def->s_name);
- }
- else
- writes(file, "%s", VarAtOfs(progfuncs, ofs));
-// longjmp(decompilestatementfailure, 1);
-}
-
-int WriteStatement(progfuncs_t *progfuncs, progstate_t *progs, int stnum, int firstpossible)
-{
- int count, skip;
- dstatement16_t *st;
- st = &((dstatement16_t*)progs->statements)[stnum];
- switch(st->op)
- {
- case OP_IFNOT_I:
- count = (signed short)st->b;
- writes(file, "if (");
- WriteStatementProducingOfs(progfuncs, progs, stnum, firstpossible, st->a);
- writes(file, ")\r\n");
- writes(file, "{\r\n");
- firstpossible = stnum+1;
- count--;
- stnum++;
- while(count)
- {
- if (ProductReadLater(progfuncs, progs, stnum))
- {
- count--;
- stnum++;
- continue;
- }
- skip = WriteStatement(progfuncs, progs, stnum, firstpossible);
- count-=skip;
- stnum+=skip;
- }
- writes(file, "}\r\n");
- st = &((dstatement16_t*)progs->statements)[stnum];
- if (st->op == OP_GOTO)
- {
- count = (signed short)st->b;
- count--;
- stnum++;
-
- writes(file, "else\r\n");
- writes(file, "{\r\n");
- while(count)
- {
- if (ProductReadLater(progfuncs, progs, stnum))
- {
- count--;
- stnum++;
- continue;
- }
- skip = WriteStatement(progfuncs, progs, stnum, firstpossible);
- count-=skip;
- stnum+=skip;
- }
- writes(file, "}\r\n");
- }
- break;
- case OP_IF_I:
- longjmp(decompilestatementfailure, 1);
- break;
- case OP_GOTO:
- longjmp(decompilestatementfailure, 1);
- break;
- case OP_RETURN:
- case OP_DONE:
- if (st->a)
- WriteStatementProducingOfs(progfuncs, progs, stnum-1, firstpossible, st->a);
- break;
- case OP_CALL0:
- case OP_CALL1:
- case OP_CALL2:
- case OP_CALL3:
- case OP_CALL4:
- case OP_CALL5:
- case OP_CALL6:
- case OP_CALL7:
- WriteStatementProducingOfs(progfuncs, progs, stnum, firstpossible, OFS_RETURN);
- writes(file, ";\r\n");
- break;
- default:
- if (pr_opcodes[st->op].associative == ASSOC_RIGHT)
- WriteStatementProducingOfs(progfuncs, progs, stnum, firstpossible, st->b);
- else
- WriteStatementProducingOfs(progfuncs, progs, stnum, firstpossible, st->c);
- writes(file, ";\r\n");
- break;
- }
-
- return 1;
-}
-
-void WriteAsmStatements(progfuncs_t *progfuncs, progstate_t *progs, int num, int f, char *functionname)
-{
- int stn = progs->functions[num].first_statement;
- QCC_opcode_t *op;
- dstatement16_t *st = NULL;
- eval_t *v;
-
- ddef16_t *def;
- int ofs,i;
-
- int fileofs;
-
- if (!functionname && stn<0)
- {
- //we wrote this one...
- return;
- }
-
- if (stn>=0)
- {
- for (stn = progs->functions[num].first_statement; stn < (signed int)pr_progs->numstatements; stn++)
- {
- st = &((dstatement16_t*)progs->statements)[stn];
- if (st->op == OP_DONE || st->op == OP_RETURN)
- {
- if (!st->a)
- writes(f, "void(");
- else if (ofstype[st->a])
- {
- writes(f, "%s", ofstype[st->a]->name);
- writes(f, "(");
- }
- else
- writes(f, "function(");
- break;
- }
- }
- st=NULL;
- stn = progs->functions[num].first_statement;
- }
- else
- writes(f, "function(");
- for (ofs = progs->functions[num].parm_start, i = 0; i < progs->functions[num].numparms; i++, ofs+=progs->functions[num].parm_size[i])
- {
- ofsflags[ofs] |= 4;
-
- def = ED_GlobalAtOfs16(progfuncs, ofs);
- if (def && stn>=0)
- {
- if (st)
- writes(f, ", ");
- st = (void *)0xffff;
-
- if (!def->s_name[progfuncs->stringtable])
- {
- char mem[64];
- sprintf(mem, "_p_%i", def->ofs);
- 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
- switch(def->type&~(DEF_SHARED|DEF_SAVEGLOBAL))
- {
- case ev_string:
- writes(f, "%s %s", "string", progfuncs->stringtable+def->s_name);
- break;
- case ev_float:
- writes(f, "%s %s", "float", progfuncs->stringtable+def->s_name);
- break;
- case ev_entity:
- writes(f, "%s %s", "entity", progfuncs->stringtable+def->s_name);
- break;
- case ev_vector:
- writes(f, "%s %s", "vector", progfuncs->stringtable+def->s_name);
- break;
- default:
- writes(f, "%s %s", "randomtype", progfuncs->stringtable+def->s_name);
- break;
- }
- }
- }
- for (ofs = progs->functions[num].parm_start+progs->functions[num].numparms, i = progs->functions[num].numparms; i < progs->functions[num].locals; i++, ofs+=1)
- ofsflags[ofs] |= 4;
-
- if (!progfuncs->stringtable[progs->functions[num].s_name])
- {
- char mem[64];
- if (!functionname)
- {
- sprintf(mem, "_bi_%i", num);
- progs->functions[num].s_name = (char*)malloc(strlen(mem)+1)-progfuncs->stringtable;
- strcpy(progs->functions[num].s_name+progfuncs->stringtable, mem);
- }
- else
- {
- progs->functions[num].s_name = (char*)malloc(strlen(functionname)+1)-progfuncs->stringtable;
- strcpy(progs->functions[num].s_name+progfuncs->stringtable, functionname);
- }
- }
-
- writes(f, ") %s", progfuncs->stringtable+progs->functions[num].s_name);
-
- if (stn < 0)
- {
- stn*=-1;
- writes(f, " = #%i;\r\n", stn);
-/*
- for (ofs = progs->functions[num].parm_start, i = 0; i < progs->functions[num].numparms; i++, ofs+=progs->functions[num].parm_size[i])
- {
- def = ED_GlobalAtOfs16(progfuncs, ofs);
- if (def)
- {
- def->ofs = 0xffff;
-
- if (progs->types)
- {
- if (progs->types[def->type & ~(DEF_SHARED|DEF_SAVEGLOBAL)].type == ev_vector)
- {
- def = ED_GlobalAtOfs16(progfuncs, ofs);
- def->ofs = 0xffff;
- def = ED_GlobalAtOfs16(progfuncs, ofs+1);
- def->ofs = 0xffff;
- def = ED_GlobalAtOfs16(progfuncs, ofs+2);
- def->ofs = 0xffff;
- }
- }
- else if ((def->type & (~(DEF_SHARED|DEF_SAVEGLOBAL))) == ev_vector)
- {
- def = ED_GlobalAtOfs16(progfuncs, ofs);
- def->ofs = 0xffff;
- def = ED_GlobalAtOfs16(progfuncs, ofs+1);
- def->ofs = 0xffff;
- def = ED_GlobalAtOfs16(progfuncs, ofs+2);
- def->ofs = 0xffff;
- }
- }
- }
- */
- return;
- }
-
- if (functionname) //parsing defs
- {
- writes(f, ";\r\n");
- return;
- }
-
- fileofs = SafeSeek(f, 0, SEEK_CUR);
- if (setjmp(decompilestatementfailure))
- {
- writes(f, "*/\r\n");
- // SafeSeek(f, fileofs, SEEK_SET);
- writes(f, " = asm {\r\n");
-
- stn = progs->functions[num].first_statement;
- for (ofs = progs->functions[num].parm_start+progs->functions[num].numparms, i = progs->functions[num].numparms; i < progs->functions[num].locals; i++, ofs+=1)
- {
- 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);
- else
- {
- if (!progfuncs->stringtable[def->s_name])
- {
- char mem[64];
- sprintf(mem, "_l_%i", def->ofs);
- def->s_name = (char*)malloc(strlen(mem)+1)-progfuncs->stringtable;
- strcpy(def->s_name+progfuncs->stringtable, mem);
- }
-
- switch(def->type&~(DEF_SHARED|DEF_SAVEGLOBAL))
- {
- case ev_string:
- writes(f, "\tlocal %s %s;\r\n", "string", progfuncs->stringtable+def->s_name);
- break;
- case ev_float:
- writes(f, "\tlocal %s %s;\r\n", "float", progfuncs->stringtable+def->s_name);
- break;
- case ev_entity:
- writes(f, "\tlocal %s %s;\r\n", "entity", progfuncs->stringtable+def->s_name);
- break;
- 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
- writes(f, "\tlocal %s %s;\r\n", "vector", progfuncs->stringtable+def->s_name);
- ofs+=2; //skip floats;
- break;
- default:
- writes(f, "\tlocal %s %s;\r\n", "randomtype", progfuncs->stringtable+def->s_name);
- break;
- }
- }
- }
- }
-
- while(1)
- {
- st = &((dstatement16_t*)progs->statements)[stn];
- if (!st->op) //end of function statement!
- break;
- op = &pr_opcodes[st->op];
- writes(f, "\t%s", op->opname);
-
- if (op->priority==-1&&op->associative==ASSOC_RIGHT) //last param is a goto
- {
- if (op->type_b == &type_void)
- {
- if (st->a)
- writes(f, " %i", (signed short)st->a);
- }
- else if (op->type_c == &type_void)
- {
- if (st->a)
- writes(f, " %s", VarAtOfs(progfuncs, st->a));
- if (st->b)
- writes(f, " %i", (signed short)st->b);
- }
- else
- {
- if (st->a)
- writes(f, " %s", VarAtOfs(progfuncs, st->a));
- if (st->b)
- writes(f, " %s", VarAtOfs(progfuncs, st->b));
- if (st->c) //rightness means it uses a as c
- writes(f, " %i", (signed short)st->c);
- }
- }
- else
- {
- if (st->a)
- {
- if (op->type_a == NULL)
- writes(f, " %i", (signed short)st->a);
- else
- writes(f, " %s", VarAtOfs(progfuncs, st->a));
- }
- if (st->b)
- {
- if (op->type_b == NULL)
- writes(f, " %i", (signed short)st->b);
- else
- writes(f, " %s", VarAtOfs(progfuncs, st->b));
- }
- if (st->c && op->associative != ASSOC_RIGHT) //rightness means it uses a as c
- {
- if (op->type_c == NULL)
- writes(f, " %i", (signed short)st->c);
- else
- writes(f, " %s", VarAtOfs(progfuncs, st->c));
- }
- }
-
- writes(f, ";\r\n");
-
- stn++;
- }
- }
- else
- {
- if (!strcmp(progfuncs->stringtable+progs->functions[num].s_name, "SUB_Remove"))
- file = 0;
- file = f;
-
- writes(f, "/*\r\n");
-
- writes(f, " =\r\n{\r\n");
-
- for (ofs = progs->functions[num].parm_start+progs->functions[num].numparms, i = progs->functions[num].numparms; i < progs->functions[num].locals; i++, ofs+=1)
- {
- 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);
- else
- {
- if (!def->s_name[progfuncs->stringtable])
- {
- char mem[64];
- sprintf(mem, "_l_%i", def->ofs);
- def->s_name = (char*)malloc(strlen(mem)+1)-progfuncs->stringtable;
- strcpy(def->s_name+progfuncs->stringtable, mem);
- }
-
- switch(def->type&~(DEF_SHARED|DEF_SAVEGLOBAL))
- {
- case ev_string:
- writes(f, "\tlocal %s %s;\r\n", "string", progfuncs->stringtable+def->s_name);
- break;
- case ev_float:
- writes(f, "\tlocal %s %s;\r\n", "float", progfuncs->stringtable+def->s_name);
- break;
- case ev_entity:
- writes(f, "\tlocal %s %s;\r\n", "entity", progfuncs->stringtable+def->s_name);
- break;
- 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
- writes(f, "\tlocal %s %s;\r\n", "vector",progfuncs->stringtable+def->s_name);
- ofs+=2; //skip floats;
- break;
- default:
- writes(f, "\tlocal %s %s;\r\n", "randomtype", progfuncs->stringtable+def->s_name);
- break;
- }
- }
- }
- }
-
-
- for (stn = progs->functions[num].first_statement; stn < (signed int)pr_progs->numstatements; stn++)
- {
- if (ProductReadLater(progfuncs, progs, stn))
- continue;
-
- st = &((dstatement16_t*)progs->statements)[stn];
- if (!st->op)
- break;
- WriteStatement(progfuncs, progs, stn, progs->functions[num].first_statement);
- }
-
- longjmp(decompilestatementfailure, 1);
- }
- writes(f, "};\r\n");
-}
-
-void FigureOutTypes(progfuncs_t *progfuncs)
-{
- ddef16_t *def;
- QCC_opcode_t *op;
- unsigned int i,p;
- dstatement16_t *st;
-
- int parmofs[8];
-
- ofstype = realloc(ofstype, sizeof(*ofstype)*65535);
- ofsflags = realloc(ofsflags, sizeof(*ofsflags)*65535);
-
- maxtypeinfos=256;
- qcc_typeinfo = (void *)realloc(qcc_typeinfo, sizeof(QCC_type_t)*maxtypeinfos);
- numtypeinfos = 0;
-
- memset(ofstype, 0, sizeof(*ofstype)*65535);
- memset(ofsflags, 0, sizeof(*ofsflags)*65535);
-
- type_void = QCC_PR_NewType("void", ev_void, true);
- type_string = QCC_PR_NewType("string", ev_string, true);
- type_float = QCC_PR_NewType("float", ev_float, true);
- type_vector = QCC_PR_NewType("vector", ev_vector, true);
- type_entity = QCC_PR_NewType("entity", ev_entity, true);
- type_field = QCC_PR_NewType("field", ev_field, false);
- type_function = QCC_PR_NewType("function", ev_function, false);
- type_pointer = QCC_PR_NewType("pointer", ev_pointer, false);
- type_integer = QCC_PR_NewType("integer", ev_integer, true);
-
-// type_variant = QCC_PR_NewType("__variant", ev_variant);
-
- type_floatfield = QCC_PR_NewType("fieldfloat", ev_field, false);
- type_floatfield->aux_type = type_float;
- type_pointer->aux_type = QCC_PR_NewType("pointeraux", ev_float, false);
-
- type_function->aux_type = type_void;
-
- for (i = 0,st = pr_statements16; i < pr_progs->numstatements; i++,st++)
- {
- op = &pr_opcodes[st->op];
- if (st->op >= OP_CALL1 && st->op <= OP_CALL8)
- {
- for (p = 0; p < (unsigned int)st->op-OP_CALL0; p++)
- {
- ofstype[parmofs[p]] = ofstype[OFS_PARM0+p*3];
- }
- }
- else if (op->associative == ASSOC_RIGHT)
- { //assignment
- ofsflags[st->b] |= 1;
- if (st->b >= OFS_PARM0 && st->b < RESERVED_OFS)
- parmofs[(st->b-OFS_PARM0)/3] = st->a;
-
-// if (st->op != OP_STORE_F || st->b>RESERVED_OFS) //optimising compilers fix the OP_STORE_V, it's the storef that becomes meaningless (this is the only time that we need this sort of info anyway)
- {
- if (op->type_c && op->type_c != &type_void)
- ofstype[st->a] = *op->type_c;
- if (op->type_b && op->type_b != &type_void)
- ofstype[st->b] = *op->type_b;
- }
- }
- else if (op->type_c)
- {
- ofsflags[st->c] |= 2;
-
- if (st->c >= OFS_PARM0 && st->b < RESERVED_OFS) //too complicated
- parmofs[(st->b-OFS_PARM0)/3] = 0;
-
-// if (st->op != OP_STORE_F || st->b>RESERVED_OFS) //optimising compilers fix the OP_STORE_V, it's the storef that becomes meaningless (this is the only time that we need this sort of info anyway)
- {
- if (op->type_a && op->type_a != &type_void)
- ofstype[st->a] = *op->type_a;
- if (op->type_b && op->type_b != &type_void)
- ofstype[st->b] = *op->type_b;
- if (op->type_c && op->type_c != &type_void)
- ofstype[st->c] = *op->type_c;
- }
- }
- }
-
-
- for (i=0 ; i<pr_progs->numglobaldefs ; i++)
- {
- def = &pr_globaldefs16[i];
- ofsflags[def->ofs] |= 8;
- switch(def->type)
- {
- case ev_float:
- ofstype[def->ofs] = type_float;
- break;
- case ev_string:
- ofstype[def->ofs] = type_string;
- break;
- case ev_vector:
- ofstype[def->ofs] = type_vector;
- break;
- default:
- break;
- }
- }
-}
-
-pbool Decompile(progfuncs_t *progfuncs, char *fname)
-{
- extern progfuncs_t *qccprogfuncs;
- unsigned int i;
- unsigned int fld=0;
- eval_t *v;
-// char *filename;
- int f, type;
-
- progstate_t progs, *op;
-
- qccprogfuncs = progfuncs;
- op=current_progstate;
-
- if (!PR_ReallyLoadProgs(progfuncs, fname, -1, &progs, false))
- {
- return false;
- }
-
- f=SafeOpenWrite("qcdtest/defs.qc", 1024*512);
-
- writes(f, "//Decompiled code can contain little type info.\r\n#define NOWARNINGS\r\n");
-
- FigureOutTypes(progfuncs);
-
- for (i = 1; i < progs.progs->numglobaldefs; i++)
- {
- if (!strcmp(progfuncs->stringtable+pr_globaldefs16[i].s_name, "IMMEDIATE"))
- continue;
-
- if (ofsflags[pr_globaldefs16[i].ofs] & 4)
- continue; //this is a local.
-
- if (current_progstate->types)
- type = progs.types[pr_globaldefs16[i].type & ~(DEF_SHARED|DEF_SAVEGLOBAL)].type;
- else
- type = pr_globaldefs16[i].type & ~(DEF_SHARED|DEF_SAVEGLOBAL);
- v = (eval_t *)&((int *)progs.globals)[pr_globaldefs16[i].ofs];
-
- if (!progfuncs->stringtable[pr_globaldefs16[i].s_name])
- {
- char mem[64];
- if (ofsflags[pr_globaldefs16[i].ofs] & 3)
- {
- ofsflags[pr_globaldefs16[i].ofs] &= ~8;
- continue; //this is a constant...
- }
-
- sprintf(mem, "_g_%i", pr_globaldefs16[i].ofs);
- pr_globaldefs16[i].s_name = (char*)malloc(strlen(mem)+1)-progfuncs->stringtable;
- strcpy(pr_globaldefs16[i].s_name+progfuncs->stringtable, mem);
- }
-
- switch(type)
- {
- case ev_void:
- writes(f, "void %s;\r\n", progfuncs->stringtable+pr_globaldefs16[i].s_name);
- break;
- case ev_string:
- 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", progfuncs->stringtable+pr_globaldefs16[i].s_name);
- break;
- case ev_float:
- if (v->_float)
- writes(f, "float %s = %f;\r\n", progfuncs->stringtable+pr_globaldefs16[i].s_name, v->_float);
- else
- writes(f, "float %s;\r\n", progfuncs->stringtable+pr_globaldefs16[i].s_name);
- break;
- case ev_vector:
- if (v->_vector[0] || v->_vector[1] || v->_vector[2])
- writes(f, "vector %s = '%f %f %f';\r\n", progfuncs->stringtable+pr_globaldefs16[i].s_name, v->_vector[0], v->_vector[1], v->_vector[2]);
- else
- writes(f, "vector %s;\r\n", progfuncs->stringtable+pr_globaldefs16[i].s_name);
- i+=3;//skip the floats
- break;
- case ev_entity:
- writes(f, "entity %s;\r\n", progfuncs->stringtable+pr_globaldefs16[i].s_name);
- break;
- case ev_field:
-//wierd
- fld++;
- if (!v->_int)
- writes(f, "var ");
- switch(pr_fielddefs16[fld].type)
- {
- case ev_string:
- writes(f, ".string %s;", progfuncs->stringtable+pr_globaldefs16[i].s_name);
- break;
-
- case ev_float:
- writes(f, ".float %s;", progfuncs->stringtable+pr_globaldefs16[i].s_name);
- break;
-
- case ev_vector:
- writes(f, ".float %s;", progfuncs->stringtable+pr_globaldefs16[i].s_name);
- break;
-
- case ev_entity:
- writes(f, ".float %s;", progfuncs->stringtable+pr_globaldefs16[i].s_name);
- break;
-
- case ev_function:
- writes(f, ".void() %s;", progfuncs->stringtable+pr_globaldefs16[i].s_name);
- break;
-
- default:
- writes(f, "field %s;", progfuncs->stringtable+pr_globaldefs16[i].s_name);
- break;
- }
- if (v->_int)
- writes(f, "/* %i */", v->_int);
- writes(f, "\r\n");
- break;
-
- case ev_function:
-//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;
- case ev_integer:
- writes(f, "integer %s;\r\n", progfuncs->stringtable+pr_globaldefs16[i].s_name);
- break;
-
- case ev_union:
- writes(f, "union %s;\r\n", progfuncs->stringtable+pr_globaldefs16[i].s_name);
- break;
- case ev_struct:
- writes(f, "struct %s;\r\n", progfuncs->stringtable+pr_globaldefs16[i].s_name);
- break;
- default:
- break;
-
- }
- }
-
- for (i = 0; i < progs.progs->numfunctions; i++)
- {
- WriteAsmStatements(progfuncs, &progs, i, f, NULL);
- }
-
- SafeClose(f);
-
- current_progstate=op;
-
- return true;
-}
-#endif
-
-#endif