1
2 #include "qcc.h"
3 #include "decomp.h"
4
5 #include <stdio.h>
6
7 extern opcode_t pr_opcodes [];
8
9
10 FILE *Decompileofile;
11 FILE *Decompileprogssrc;
12 FILE *Decompileprofile;
13 char *DecompileFilesSeen[1024];
14 int DecompileFileCtr = 0;
15 char *DecompileProfiles[MAX_FUNCTIONS];
16
17 char *type_names[8] =
18 {
19 "void",
20 "string",
21 "float",
22 "vector",
23 "entity",
24 "ev_field",
25 "void()",
26 "ev_pointer"
27 };
28
temp_type(unsigned short temp,dstatement_t * start,dfunction_t * df)29 char *temp_type (unsigned short temp, dstatement_t *start, dfunction_t *df)
30 {
31 int i;
32 dstatement_t *stat;
33 stat = start - 1;
34 // determine the type of a temp
35
36 while(stat > statements)
37 {
38 if (temp == stat->a)
39 return type_names[pr_opcodes[stat->op].type_a->type->type];
40 else if (temp == stat->b)
41 return type_names[pr_opcodes[stat->op].type_b->type->type];
42 else if (temp == stat->c)
43 return type_names[pr_opcodes[stat->op].type_c->type->type];
44 stat--;
45 }
46
47 // method 2
48 // find a call to this function
49 for (i = 0; i < numstatements; i++)
50 {
51 stat = &statements[i];
52
53 if (stat->op >= OP2_CALL0 && stat->op <= OP2_CALL8 && ((eval_t *)&pr_globals[stat->a])->function == df - functions)
54 {
55 for(i++; i < numstatements; i++)
56 {
57 stat = &statements[i];
58 if (OFS_RETURN == stat->a && pr_opcodes[stat->op].type_a->type->type != ev_void)
59 return type_names[pr_opcodes[stat->op].type_a->type->type];
60 else if (OFS_RETURN == stat->b && pr_opcodes[stat->op].type_b->type->type != ev_void)
61 return type_names[pr_opcodes[stat->op].type_b->type->type];
62 else if (stat->op == OP2_DONE)
63 break;
64 else if (stat->op >= OP2_CALL0 && stat->op <= OP2_CALL8 && stat->a != df - functions)
65 break;
66 }
67 }
68 }
69
70 printf("Warning: Could not determine return type for %s\n", df->s_name + strings);
71
72 return "float";
73
74 }
75
IsConstant(ddef_t * def)76 boolean IsConstant(ddef_t *def)
77 {
78
79 int i;
80 dstatement_t *d;
81
82 if (def->type & DEF_SAVEGLOBGAL)
83 return false;
84
85 for (i = 1; i < numstatements; i++)
86 {
87 d = &statements[i];
88 if (d->b == def->ofs)
89 {
90 if (pr_opcodes[d->op].right_associative)
91 {
92 if (d->op - OP2_STORE_F < 6)
93 {
94 return false;
95 }
96 }
97 }
98 }
99 return true;
100 }
101
type_name(ddef_t * def)102 char *type_name (ddef_t *def)
103 {
104 ddef_t *j;
105
106 static char fname [1024];
107
108 switch(def->type)
109 {
110 case ev_field:
111 case ev_pointer:
112 j = GetField(def->s_name + strings);
113 if (j)
114 return va(".%s",type_names[j->type]);
115 else
116 return type_names[def->type];
117 case ev_void:
118 case ev_string:
119 case ev_entity:
120 case ev_vector:
121 case ev_float:
122 return type_names[def->type];
123 case ev_function:
124 return "void()";
125 default:
126 return "float";
127 }
128 };
129 extern float pr_globals[MAX_REGS];
130 extern int numpr_globals;
131
132 extern char strings[MAX_STRINGS];
133 extern int strofs;
134
135 extern dstatement_t statements[MAX_STATEMENTS];
136 extern int numstatements;
137 extern int statement_linenums[MAX_STATEMENTS];
138
139 extern dfunction_t functions[MAX_FUNCTIONS];
140 extern int numfunctions;
141
142 extern ddef_t globals[MAX_GLOBALS];
143 extern int numglobaldefs;
144
145 extern ddef_t fields[MAX_FIELDS];
146 extern int numfielddefs;
147
148 int maindecstatus = 6;
149
150 #define FILELISTSIZE 62
151
152
153
154 /*
155 ===============
156 PR_String
157
158 Returns a string suitable for printing (no newlines, max 60 chars length)
159 ===============
160 */
PR_String(char * string)161 char *PR_String (char *string)
162 {
163 static char buf[80];
164 char *s;
165
166 s = buf;
167 *s++ = '"';
168 while (string && *string)
169 {
170 if (s == buf + sizeof(buf) - 2)
171 break;
172 if (*string == '\n')
173 {
174 *s++ = '\\';
175 *s++ = 'n';
176 }
177 else if (*string == '"')
178 {
179 *s++ = '\\';
180 *s++ = '"';
181 }
182 else
183 *s++ = *string;
184 string++;
185 if (s - buf > 60)
186 {
187 *s++ = '.';
188 *s++ = '.';
189 *s++ = '.';
190 break;
191 }
192 }
193 *s++ = '"';
194 *s++ = 0;
195 return buf;
196 }
197 /*
198 ============
199 PR_ValueString
200
201 Returns a string describing *data in a type specific manner
202 =============
203 */
204
205
PR_ValueString(etype_t type,void * val)206 char *PR_ValueString (etype_t type, void *val)
207 {
208 static char line[256];
209
210 dfunction_t *f;
211
212 switch (type)
213 {
214 case ev_string:
215 sprintf (line, "%s", PR_String(strings + *(int *)val));
216 break;
217 case ev_entity:
218 sprintf (line, "entity %i", *(int *)val);
219 break;
220 case ev_function:
221 f = functions + *(int *)val;
222 if (!f)
223 sprintf (line, "undefined function");
224 else
225 sprintf (line, "%s()", strings + f->s_name);
226 break;
227 /*
228 case ev_field:
229 def = PR_DefForFieldOfs ( *(int *)val );
230 sprintf (line, ".%s", def->name);
231 break;
232 */
233 case ev_void:
234 sprintf (line, "void");
235 break;
236 case ev_float:
237 {
238 unsigned int high = *(unsigned int*)val & 0xff000000;
239 if (high == 0xff000000 || !high)
240 sprintf (line, "%%%d", *(int*)val);
241 else
242 sprintf (line, "%5.1f", *(float *)val);
243 }
244 break;
245 case ev_vector:
246 sprintf (line, "'%5.1f %5.1f %5.1f'", ((float *)val)[0], ((float *)val)[1], ((float *)val)[2]);
247 break;
248 case ev_pointer:
249 sprintf (line, "pointer");
250 break;
251 default:
252 sprintf (line, "bad type %i", type);
253 break;
254 }
255
256 return line;
257 }
258
259
260 static char *filenames[] =
261 {
262 "makevectors", "defs.qc",
263 "button_wait", "buttons.qc",
264 "anglemod", "ai.qc",
265 "boss_face", "boss.qc",
266 "info_intermission", "client.qc",
267 "CanDamage", "combat.qc",
268 "demon1_stand1", "demon.qc",
269 "dog_bite", "dog.qc",
270 "door_blocked", "doors.qc",
271 "Laser_Touch", "enforcer.qc",
272 "knight_attack", "fight.qc",
273 "f_stand1", "fish.qc",
274 "hknight_shot", "hknight.qc",
275 "SUB_regen", "items.qc",
276 "knight_stand1", "knight.qc",
277 "info_null", "misc.qc",
278 "monster_use", "monsters.qc",
279 "OgreGrenadeExplode", "ogre.qc",
280 "old_idle1", "oldone.qc",
281 "plat_spawn_inside_trigger", "plats.qc",
282 "player_stand1", "player.qc",
283 "shal_stand", "shalrath.qc",
284 "sham_stand1", "shambler.qc",
285 "army_stand1", "soldier.qc",
286 "SUB_Null", "subs.qc",
287 "tbaby_stand1", "tarbaby.qc",
288 "trigger_reactivate", "triggers.qc",
289 "W_Precache", "weapons.qc",
290 "LaunchMissile", "wizard.qc",
291 "main", "world.qc",
292 "zombie_stand1", "zombie.qc"
293 };
294
295 static char *builtins[] =
296 {
297
298 NULL,
299 "void (vector ang)",
300 "void (entity e, vector o)",
301 "void (entity e, string m)",
302 "void (entity e, vector min, vector max)",
303 NULL,
304 "void ()",
305 "float ()",
306 "void (entity e, float chan, string samp, float vol, float atten)",
307 "vector (vector v)",
308 "void (string e)",
309 "void (string e)",
310 "float (vector v)",
311 "float (vector v)",
312 "entity ()",
313 "void (entity e)",
314 "void (vector v1, vector v2, float nomonsters, entity forent)",
315 "entity ()",
316 "entity (entity start, .string fld, string match)",
317 "string (string s)",
318 "string (string s)",
319 "void (entity client, string s)",
320 "entity (vector org, float rad)",
321 "void (string s)",
322 "void (entity client, string s)",
323 "void (string s)",
324 "string (float f)",
325 "string (vector v)",
326 "void ()",
327 "void ()",
328 "void ()",
329 "void (entity e)",
330 "float (float yaw, float dist)",
331 NULL,
332 "float (float yaw, float dist)",
333 "void (float style, string value)",
334 "float (float v)",
335 "float (float v)",
336 "float (float v)",
337 NULL,
338 "float (entity e)",
339 "float (vector v)",
340 NULL,
341 "float (float f)",
342 "vector (entity e, float speed)",
343 "float (string s)",
344 "void (string s)",
345 "entity (entity e)",
346 "void (vector o, vector d, float color, float count)",
347 "void ()",
348 NULL,
349 "vector (vector v)",
350 "void (float to, float f)",
351 "void (float to, float f)",
352 "void (float to, float f)",
353 "void (float to, float f)",
354 "void (float to, float f)",
355 "void (float to, float f)",
356 "void (float to, string s)",
357 "void (float to, entity s)",
358 NULL,
359 NULL,
360 NULL,
361 NULL,
362 NULL,
363 NULL,
364 NULL,
365 "void (float step)",
366 "string (string s)",
367 "void (entity e)",
368 "void (string s)",
369 NULL,
370 "void (string var, string val)",
371 "void (entity client, string s, ...)",
372 "void (vector pos, string samp, float vol, float atten)",
373 "string (string s)",
374 "string (string s)",
375 "string (string s)",
376 "void (entity e)",
377 "void(entity killer, entity killee)",
378 "string(entity e, string key)",
379 "float(string s)",
380 "void(vector where, float set)"
381
382 };
383
384 char *DecompileValueString(etype_t type, void *val);
385 ddef_t *DecompileGetParameter(gofs_t ofs);
386 char *DecompilePrintParameter(ddef_t * def);
387
DecompileReadData(char * srcfile)388 void DecompileReadData(char *srcfile)
389 {
390 dprograms_t progs;
391 int h, i;
392 void *p;
393 char name[1024];
394
395 h = SafeOpenRead(srcfile);
396 SafeRead(h, &progs, sizeof(progs));
397
398 lseek(h, progs.ofs_strings, SEEK_SET);
399 strofs = progs.numstrings;
400 SafeRead(h, strings, strofs);
401
402 lseek(h, progs.ofs_statements, SEEK_SET);
403 numstatements = progs.numstatements;
404 SafeRead(h, statements, numstatements * sizeof(dstatement_t));
405
406 lseek(h, progs.ofs_functions, SEEK_SET);
407 numfunctions = progs.numfunctions;
408 SafeRead(h, functions, numfunctions * sizeof(dfunction_t));
409
410 lseek(h, progs.ofs_globaldefs, SEEK_SET);
411 numglobaldefs = progs.numglobaldefs;
412 SafeRead(h, globals, numglobaldefs * sizeof(ddef_t));
413
414 lseek(h, progs.ofs_fielddefs, SEEK_SET);
415 numfielddefs = progs.numfielddefs;
416 SafeRead(h, fields, numfielddefs * sizeof(ddef_t));
417
418 lseek(h, progs.ofs_globals, SEEK_SET);
419 numpr_globals = progs.numglobals;
420 SafeRead(h, pr_globals, numpr_globals * 4);
421 printf("Decompiling...\n");
422 printf("Read Data from %s:\n", srcfile);
423 printf("Total Size is %6i\n", (int)lseek(h, 0, SEEK_END));
424 printf("Version Code is %i\n", progs.version);
425 printf("CRC is %i\n", progs.crc);
426 printf("%6i strofs\n", strofs);
427 printf("%6i numstatements\n", numstatements);
428 printf("%6i numfunctions\n", numfunctions);
429 printf("%6i numglobaldefs\n", numglobaldefs);
430 printf("%6i numfielddefs\n", numfielddefs);
431 printf("%6i numpr_globals\n", numpr_globals);
432 printf("----------------------\n");
433
434 // fix up the functions
435 for (i = 1; i < numfunctions; i++)
436 {
437 if (strlen(functions[i].s_name + strings) <= 0)
438 {
439 sprintf(name, "function%i", i);
440 name[strlen(name)] = 0;
441 p = malloc(strlen(name + 1));
442 strcpy(p, name);
443 functions[i].s_name = (char *)p - strings;
444 }
445 }
446 }
447
448 int
DecompileGetFunctionIdxByName(char * name)449 DecompileGetFunctionIdxByName(char *name)
450 {
451
452 int i;
453
454 for (i = 1; i < numfunctions; i++)
455 if (!strcmp(name, strings + functions[i].s_name))
456 {
457 break;
458 }
459 return i;
460 }
461
462 int
DecompileAlreadySeen(char * fname)463 DecompileAlreadySeen(char *fname)
464 {
465
466 int i;
467 char *knew;
468
469 if (DecompileFileCtr > 1000)
470 {
471 printf("Fatal Error - too many source files.\n");
472 exit(1);
473 }
474
475 for (i = 0; i < DecompileFileCtr; i++)
476 {
477 if (!strcmp(fname, DecompileFilesSeen[i]))
478 return 1;
479 }
480
481 knew = (char *)malloc(strlen(fname) + 1);
482 strcpy(knew, fname);
483 DecompileFilesSeen[DecompileFileCtr] = knew;
484 DecompileFileCtr++;
485
486
487
488 return 0;
489 }
490
491 void
DecompileCalcProfiles(void)492 DecompileCalcProfiles(void)
493 {
494
495 int i, j, ps;
496 char *knew;
497 static char fname[512];
498 static char line[512];
499 dfunction_t *df;
500 dstatement_t *ds, *rds;
501 ddef_t *par;
502 unsigned short dom;
503
504 for (i = 1; i < numfunctions; i++)
505 {
506
507 df = functions + i;
508 fname[0] = '\0';
509 line[0] = '\0';
510 DecompileProfiles[i] = NULL;
511
512 if (df->first_statement <= 0)
513 {
514 if ((df->first_statement > -82) && builtins[-df->first_statement])
515 sprintf(fname, "%s %s", builtins[-df->first_statement], strings + functions[i].s_name);
516 else
517 {
518 sprintf(fname, "void () %s", strings + functions[i].s_name, strings + functions[i].s_name);
519 printf("Warning: unknown builtin %s\n", strings + functions[i].s_name);
520 }
521 }
522 else
523 {
524
525 ds = statements + df->first_statement;
526 rds = NULL;
527
528 /*
529 * find a return statement, to determine the result type
530 */
531
532 while (1)
533 {
534 dom = (ds->op) % 100;
535 if (!dom)
536 break;
537 if (dom == OP2_RETURN)
538 {
539 if (ds->a != 0)
540 {
541 if (DecompileGetParameter(ds->a))
542 {
543 rds = ds;
544 break;
545 }
546 }
547 if (rds == NULL)
548 rds = ds;
549
550 }
551 ds++;
552 }
553
554 /*
555 * print the return type
556 */
557
558 if ((rds != NULL) && (rds->a != 0))
559 {
560 par = DecompileGetParameter(rds->a);
561
562 if (par)
563 {
564 sprintf(fname, "%s ", type_name(par));
565 }
566 else
567 {
568 sprintf(fname, "%s ", temp_type(rds->a, rds, df));
569 }
570 }
571 else
572 {
573 sprintf(fname, "void ");
574 }
575 strcat(fname, "(");
576
577 /*
578 * determine overall parameter size
579 */
580
581 for (j = 0, ps = 0; j < df->numparms; j++)
582 ps += df->parm_size[j];
583
584 if (ps > 0)
585 {
586 for (j = df->parm_start; j < (df->parm_start) + ps; j++)
587 {
588 line[0] = '\0';
589 par = DecompileGetParameter(j);
590
591 if (!par)
592 {
593 //Error("Error - No parameter names with offset %i.", j);
594 printf("No parameter names with offset %i\n", j);
595 if (j < (df->parm_start) + ps - 1)
596 sprintf(line, "float par%i, ", j - df->parm_start);
597 else
598 sprintf(line, "float par%i", j - df->parm_start);
599 }
600 else
601 {
602 if (par->type == ev_vector)
603 j += 2;
604 if (j < (df->parm_start) + ps - 1)
605 {
606 sprintf(line, "%s, ", DecompilePrintParameter(par));
607 }
608 else
609 {
610 sprintf(line, "%s", DecompilePrintParameter(par));
611 }
612 }
613 strcat(fname, line);
614 }
615 }
616 strcat(fname, ") ");
617 line[0] = '\0';
618 sprintf(line, strings + functions[i].s_name);
619 strcat(fname, line);
620
621 }
622
623 if (i >= MAX_FUNCTIONS)
624 {
625 printf("Fatal Error - too many functions.\n");
626 exit(1);
627 }
628 knew = (char *)malloc(strlen(fname) + 1);
629 strcpy(knew, fname);
630 DecompileProfiles[i] = knew;
631 }
632
633 }
634
DecompileGlobal(gofs_t ofs,def_t * req_t)635 char *DecompileGlobal(gofs_t ofs, def_t * req_t)
636 {
637 int i;
638 ddef_t *def;
639 static char line[256];
640 char *res;
641 char found = 0;
642
643 line[0] = '\0';
644
645 def = NULL;
646
647 for (i = 0; i < numglobaldefs; i++)
648 {
649 def = &globals[i];
650
651 if (def->ofs == ofs)
652 {
653 /*
654 printf("DecompileGlobal - Found %i at %i.\n", ofs, (int)def);
655 */
656 found = 1;
657 break;
658 }
659 }
660
661 if (found)
662 {
663
664 if (!strcmp(strings + def->s_name, "IMMEDIATE"))
665 sprintf(line, "%s", DecompileValueString((etype_t)(def->type), &pr_globals[def->ofs]));
666 else
667 {
668
669 sprintf(line, "%s", strings + def->s_name);
670 if (def->type == ev_vector && req_t == &def_float)
671 strcat(line, "_x");
672
673 }
674 res = (char *)malloc(strlen(line) + 1);
675 strcpy(res, line);
676
677 return res;
678 }
679 return NULL;
680 }
681
682 gofs_t
DecompileScaleIndex(dfunction_t * df,gofs_t ofs)683 DecompileScaleIndex(dfunction_t *df, gofs_t ofs)
684 {
685 gofs_t nofs = 0;
686
687 if (ofs > RESERVED_OFS)
688 nofs = ofs - df->parm_start + RESERVED_OFS;
689 else
690 nofs = ofs;
691
692 return nofs;
693 }
694
695 #define MAX_NO_LOCAL_IMMEDIATES 4096 /* dln: increased, not enough! */
696
DecompileImmediate(dfunction_t * df,gofs_t ofs,int fun,char * knew)697 char *DecompileImmediate(dfunction_t *df, gofs_t ofs, int fun, char *knew)
698 {
699 int i;
700 char *res;
701 static char *IMMEDIATES[MAX_NO_LOCAL_IMMEDIATES];
702 gofs_t nofs;
703
704 // free 'em all
705
706 if (fun == 0)
707 {
708
709 //printf("DecompileImmediate - Initializing function environment.\n");
710
711
712 for (i = 0; i < MAX_NO_LOCAL_IMMEDIATES; i++)
713 {
714 if (IMMEDIATES[i])
715 {
716 free(IMMEDIATES[i]);
717 IMMEDIATES[i] = NULL;
718 }
719 }
720 return NULL;
721 }
722 nofs = DecompileScaleIndex(df, ofs);
723 // printf("DecompileImmediate - Index scale: %i -> %i.\n", ofs, nofs);
724
725
726 // check consistency
727
728 if ((nofs <= 0) || (nofs > MAX_NO_LOCAL_IMMEDIATES - 1))
729 {
730 printf("Fatal Error - Index (%i) out of bounds.\n", nofs);
731 exit(1);
732 }
733
734 // insert at nofs
735
736 if (fun == 1)
737 {
738
739 if (IMMEDIATES[nofs])
740 free(IMMEDIATES[nofs]);
741
742 IMMEDIATES[nofs] = (char *)malloc(strlen(knew) + 1);
743 strcpy(IMMEDIATES[nofs], knew);
744
745 // printf("DecompileImmediate - Putting \"%s\" at index %i.\n", knew, nofs);
746
747 }
748 // get from nofs
749
750 else if (fun == 2)
751 {
752
753 if (IMMEDIATES[nofs])
754 {
755
756 // printf("DecompileImmediate - Reading \"%s\" at index %i.\n", IMMEDIATES[nofs], nofs);
757
758 res = (char *)malloc(strlen(IMMEDIATES[nofs]) + 1);
759 strcpy(res, IMMEDIATES[nofs]);
760
761 return res;
762 }
763 else
764 {
765 printf("Fatal Error - %i not defined.\n", nofs);
766 exit(1);
767 }
768 }
769 return NULL;
770 }
771
DecompileGet(dfunction_t * df,gofs_t ofs,def_t * req_t)772 char *DecompileGet(dfunction_t *df, gofs_t ofs, def_t *req_t)
773 {
774 char *farg1;
775 farg1 = NULL;
776
777 farg1 = DecompileGlobal(ofs, req_t);
778
779 if (farg1 == NULL)
780 farg1 = DecompileImmediate(df, ofs, 2, NULL);
781
782 /*
783 if (arg1)
784 printf("DecompileGet - found \"%s\".\n", farg1);
785 */
786
787 return farg1;
788 }
789
790 void DecompilePrintStatement(dstatement_t *s);
791
DecompileIndent(int c)792 void DecompileIndent(int c)
793 {
794 int i;
795
796 if (c < 0)
797 c = 0;
798
799 for (i = 0; i < c; i++)
800 {
801 fprintf(Decompileofile, "\t");
802 }
803 }
804
DecompileDecompileStatement(dfunction_t * df,dstatement_t * s,int * indent)805 void DecompileDecompileStatement(dfunction_t * df, dstatement_t * s, int *indent)
806 {
807 static char line[512];
808 static char fnam[512];
809 char *arg1, *arg2, *arg3;
810 int nargs, i, j;
811 dstatement_t *t;
812 unsigned short dom, doc, ifc, tom;
813 def_t *typ1, *typ2, *typ3;
814 ddef_t *par;
815 dstatement_t *k;
816 int dum;
817
818
819 arg1 = arg2 = arg3 = NULL;
820
821 line[0] = '\0';
822 fnam[0] = '\0';
823
824 dom = s->op;
825
826 doc = dom / 10000;
827 ifc = (dom % 10000) / 100;
828
829 // use program flow information
830
831 for (i = 0; i < ifc; i++)
832 {
833 (*indent)--;
834 DecompileIndent(*indent);
835 fprintf(Decompileofile, "}\n");//FrikaC style modification
836 }
837 for (i = 0; i < doc; i++)
838 {
839 DecompileIndent(*indent);
840 fprintf(Decompileofile, "do\n");
841 DecompileIndent(*indent);
842 fprintf(Decompileofile, "{\n");
843 (*indent)++;
844 }
845
846 /*
847 * remove all program flow information
848 */
849 s->op %= 100;
850 typ1 = pr_opcodes[s->op].type_a;
851 typ2 = pr_opcodes[s->op].type_b;
852 typ3 = pr_opcodes[s->op].type_c;
853
854 /*
855 * printf("DecompileDecompileStatement - decompiling %i (%i):\n",(int)(s - statements),dom);
856 * DecompilePrintStatement (s);
857 */
858 /*
859 * states are handled at top level
860 */
861 if (s->op == OP2_DONE)
862 {
863
864 }
865 else if (s->op == OP2_STATE)
866 {
867
868 par = DecompileGetParameter(s->a);
869 if (!par)
870 {
871 printf("Error - Can't determine frame number.\n");
872 exit(1);
873 }
874 arg2 = DecompileGet(df, s->b, NULL);
875 if (!arg2)
876 {
877 printf("Error - No state parameter with offset %i.\n", s->b);
878 exit(1);
879 }
880 DecompileIndent(*indent);
881 fprintf(Decompileofile, "state [ %s, %s ];\n", DecompileValueString((etype_t)(par->type), &pr_globals[par->ofs]), arg2);
882
883 // free(arg2);
884 }
885 else if (s->op == OP2_RETURN)
886 {
887 DecompileIndent(*indent);
888 fprintf(Decompileofile, "return");
889
890 if (s->a)
891 {
892 fprintf(Decompileofile, " ");
893 arg1 = DecompileGet(df, s->a, typ1);
894 fprintf(Decompileofile, "(%s)", arg1);
895 }
896 fprintf(Decompileofile, ";\n");
897
898 }
899 else if ((OP2_MUL_F <= s->op && s->op <= OP2_SUB_V) ||
900 (OP2_EQ_F <= s->op && s->op <= OP2_GT) ||
901 (OP2_AND <= s->op && s->op <= OP2_BITOR))
902 {
903
904 arg1 = DecompileGet(df, s->a, typ1);
905 arg2 = DecompileGet(df, s->b, typ2);
906 arg3 = DecompileGlobal(s->c, typ3);
907
908 if (arg3)
909 {
910 DecompileIndent(*indent);
911 fprintf(Decompileofile, "%s = %s %s %s;\n", arg3, arg1, pr_opcodes[s->op].name, arg2);
912 }
913 else
914 {
915 sprintf(line, "(%s %s %s)", arg1, pr_opcodes[s->op].name, arg2);
916 DecompileImmediate(df, s->c, 1, line);
917 }
918
919 }
920 else if (OP2_LOAD_F <= s->op && s->op <= OP2_ADDRESS)
921 {
922
923 // RIGHT HERE
924
925 arg1 = DecompileGet(df, s->a, typ1);
926 arg2 = DecompileGet(df, s->b, typ2);
927 arg3 = DecompileGlobal(s->c, typ3);
928
929 if (arg3) {
930 DecompileIndent(*indent);
931 fprintf(Decompileofile, "%s = %s.%s;\n", arg3, arg1, arg2);
932 } else {
933 sprintf(line, "%s.%s", arg1, arg2);
934 DecompileImmediate(df, s->c, 1, line);
935 }
936 } else if (OP2_STORE_F <= s->op && s->op <= OP2_STORE_FNC) {
937
938 arg1 = DecompileGet(df, s->a, typ1);
939 arg3 = DecompileGlobal(s->b, typ2);
940
941 if (arg3) {
942 DecompileIndent(*indent);
943 fprintf(Decompileofile, "%s = %s;\n", arg3, arg1);
944 } else {
945 sprintf(line, "%s", arg1);
946 DecompileImmediate(df, s->b, 1, line);
947 }
948
949 } else if (OP2_STOREP_F <= s->op && s->op <= OP2_STOREP_FNC) {
950
951 arg1 = DecompileGet(df, s->a, typ2);
952 arg2 = DecompileGet(df, s->b, typ2);
953
954 DecompileIndent(*indent);
955 fprintf(Decompileofile, "%s = %s;\n", arg2, arg1);
956
957 } else if (OP2_NOT_F <= s->op && s->op <= OP2_NOT_FNC) {
958
959 arg1 = DecompileGet(df, s->a, typ1);
960 sprintf(line, "!%s", arg1);
961 DecompileImmediate(df, s->c, 1, line);
962
963 }
964 else if (OP2_CALL0 <= s->op && s->op <= OP2_CALL8)
965 {
966
967 nargs = s->op - OP2_CALL0;
968
969 arg1 = DecompileGet(df, s->a, NULL);
970 sprintf(line, "%s (", arg1);
971 sprintf(fnam, "%s", arg1);
972
973 for (i = 0; i < nargs; i++)
974 {
975
976 typ1 = NULL;
977
978 j = 4 + 3 * i;
979
980 if (arg1)
981 free(arg1);
982
983 arg1 = DecompileGet(df, j, typ1);
984 strcat(line, arg1);
985
986 #ifndef DONT_USE_DIRTY_TRICKS
987 if (!strcmp(fnam, "WriteCoord"))
988 if (!strcmp(arg1, "org") || !strcmp(arg1, "trace_endpos") || !strcmp(arg1, "p1") || !strcmp(arg1, "p2") || !strcmp(arg1, "o"))
989 strcat(line, "_x");
990 #endif
991
992 if (i < nargs - 1)
993 strcat(line, ", ");//frikqcc modified
994 }
995
996 strcat(line, ")");
997 DecompileImmediate(df, 1, 1, line);
998
999 /*
1000 * if ( ( ( (s+1)->a != 1) && ( (s+1)->b != 1) &&
1001 * ( (s+2)->a != 1) && ( (s+2)->b != 1) ) ||
1002 * ( ((s+1)->op) % 100 == OP2_CALL0 ) ) {
1003 * DecompileIndent(*indent);
1004 * fprintf(Decompileofile,"%s;\n",line);
1005 * }
1006 */
1007
1008 if ((((s + 1)->a != 1) && ((s + 1)->b != 1) &&
1009 ((s + 2)->a != 1) && ((s + 2)->b != 1)) ||
1010 ((((s + 1)->op) % 100 == OP2_CALL0) && ((((s + 2)->a != 1)) || ((s + 2)->b != 1)))) {
1011 DecompileIndent(*indent);
1012 fprintf(Decompileofile, "%s;\n", line);
1013 }
1014 } else if (s->op == OP2_IF || s->op == OP2_IFNOT) {
1015
1016 arg1 = DecompileGet(df, s->a, NULL);
1017 arg2 = DecompileGlobal(s->a, NULL);
1018
1019 if (s->op == OP2_IFNOT)
1020 {
1021
1022 if (s->b < 1)
1023 {
1024 printf("Found a negative IFNOT jump.\n");
1025 exit(1);
1026 }
1027
1028 /*
1029 * get instruction right before the target
1030 */
1031 t = s + s->b - 1;
1032 tom = t->op % 100;
1033
1034 if (tom != OP2_GOTO) {
1035
1036 /*
1037 * pure if
1038 */
1039 DecompileIndent(*indent);
1040 fprintf(Decompileofile, "if (%s)\n", arg1);//FrikaC modified
1041 DecompileIndent(*indent);
1042 fprintf(Decompileofile, "{\n");
1043
1044 (*indent)++;
1045
1046 } else {
1047
1048 if (t->a > 0) {
1049 /*
1050 * ite
1051 */
1052
1053 DecompileIndent(*indent);
1054 fprintf(Decompileofile, "if (%s)\n", arg1);//FrikaC modified
1055 DecompileIndent(*indent);
1056 fprintf(Decompileofile, "{\n");
1057
1058 (*indent)++;
1059
1060 } else {
1061
1062
1063 if ((t->a + s->b) > 1) {
1064 /*
1065 * pure if
1066 */
1067
1068 DecompileIndent(*indent);
1069 fprintf(Decompileofile, "if (%s)\n", arg1);//FrikaC modified
1070 DecompileIndent(*indent);
1071 fprintf(Decompileofile, "{\n");
1072 (*indent)++;
1073 } else {
1074
1075 dum = 1;
1076 for (k = t + (t->a); k < s; k++) {
1077 tom = k->op % 100;
1078 if (tom == OP2_GOTO || tom == OP2_IF || tom == OP2_IFNOT)
1079 dum = 0;
1080 }
1081 if (dum)
1082 {
1083
1084 DecompileIndent(*indent);
1085 fprintf(Decompileofile, "while (%s)\n", arg1);
1086 DecompileIndent(*indent); //FrikaC
1087 fprintf(Decompileofile, "{\n");
1088 (*indent)++;
1089 } else {
1090
1091 DecompileIndent(*indent);
1092
1093
1094 fprintf(Decompileofile, "if (%s)\n", arg1);//FrikaC modified
1095 DecompileIndent(*indent);
1096 fprintf(Decompileofile, "{\n");
1097 (*indent)++;
1098 }
1099 }
1100 }
1101 }
1102
1103 }
1104 else
1105 {
1106 /*
1107 * do ... while
1108 */
1109
1110 (*indent)--;
1111 fprintf(Decompileofile, "\n");
1112 DecompileIndent(*indent);
1113 fprintf(Decompileofile, "} while (%s);\n", arg1);
1114
1115 }
1116
1117 }
1118 else if (s->op == OP2_GOTO)
1119 {
1120
1121 if (s->a > 0)
1122 {
1123 /*
1124 * else
1125 */
1126 (*indent)--;
1127 DecompileIndent(*indent);
1128 fprintf(Decompileofile, "}\n");
1129 DecompileIndent(*indent);
1130 fprintf(Decompileofile, "else\n");
1131 DecompileIndent(*indent);
1132 fprintf(Decompileofile, "{\n");
1133 (*indent)++;
1134
1135 }
1136 else
1137 {
1138 /*
1139 * while
1140 */
1141 (*indent)--;
1142
1143 DecompileIndent(*indent);
1144 fprintf(Decompileofile, "}\n");
1145
1146 }
1147
1148 }
1149 else
1150 {
1151 if (s->op <= OP2_BITOR)
1152 printf("Warnint: Unknown usage of OP_%s", pr_opcodes[s->op].opname);
1153 else
1154 printf("Warning: Unknown command\n");
1155
1156 }
1157
1158
1159 // printf("DecompileDecompileStatement - Current line is \"%s\"\n", line);
1160
1161
1162 if (arg1)
1163 free(arg1);
1164 if (arg2)
1165 free(arg2);
1166 if (arg3)
1167 free(arg3);
1168
1169 return;
1170 }
1171
DecompileDecompileFunction(dfunction_t * df)1172 void DecompileDecompileFunction(dfunction_t * df)
1173 {
1174 dstatement_t *ds;
1175 int indent;
1176
1177 // Initialize
1178
1179 DecompileImmediate(df, 0, 0, NULL);
1180
1181 indent = 1;
1182
1183 ds = statements + df->first_statement;
1184 if(ds->op == OP2_STATE)
1185 ds++;
1186 while (1)
1187 {
1188
1189 DecompileDecompileStatement(df, ds, &indent);
1190 if (!ds->op)
1191 break;
1192 ds++;
1193 }
1194
1195 if (indent != 1)
1196 {
1197 printf("Warning: Indentation structure corrupt\n");
1198
1199 }
1200 }
1201
DecompileString(char * string)1202 char *DecompileString(char *string)
1203 {
1204 static char buf[255];
1205 char *s;
1206 int c = 1;
1207
1208 s = buf;
1209 *s++ = '"';
1210 while (string && *string)
1211 {
1212 if (c == sizeof(buf) - 2)
1213 break;
1214 if (*string == '\n')
1215 {
1216 *s++ = '\\';
1217 *s++ = 'n';
1218 c++;
1219 }
1220 else if (*string == '"')
1221 {
1222 *s++ = '\\';
1223 *s++ = '"';
1224 c++;
1225 }
1226 else
1227 {
1228 *s++ = *string;
1229 c++;
1230 }
1231 string++;
1232 if (c > (int)(sizeof(buf) - 10))
1233 {
1234 *s++ = '.';
1235 *s++ = '.';
1236 *s++ = '.';
1237 c += 3;
1238 break;
1239 }
1240 }
1241 *s++ = '"';
1242 *s++ = 0;
1243 return buf;
1244 }
1245
DecompileValueString(etype_t type,void * val)1246 char *DecompileValueString(etype_t type, void *val)
1247 {
1248 static char line[1024];
1249
1250 line[0] = '\0';
1251
1252 switch (type)
1253 {
1254 case ev_string:
1255 sprintf(line, "%s", DecompileString(strings + *(int *)val));
1256 break;
1257 case ev_void:
1258 sprintf(line, "void");
1259 break;
1260 case ev_float:
1261 if (*(float *)val > 999999 || *(float *)val < -999999) // ugh
1262 sprintf(line, "%.f", *(float *)val);
1263 else if ((*(float *)val < 0.001) && (*(float *)val > 0))
1264 sprintf(line, "%.6f", *(float *)val);
1265 else
1266 sprintf(line, "%g", *(float *)val);
1267 break;
1268 case ev_vector:
1269 sprintf(line, "'%g %g %g'", ((float *)val)[0], ((float *)val)[1], ((float *)val)[2]);
1270 break;
1271 default:
1272 sprintf(line, "bad type %i", type);
1273 break;
1274 }
1275
1276 return line;
1277 }
1278
DecompilePrintParameter(ddef_t * def)1279 char *DecompilePrintParameter(ddef_t * def)
1280 {
1281 static char line[128];
1282
1283 line[0] = '0';
1284
1285 if (!strcmp(strings + def->s_name, "IMMEDIATE"))
1286 {
1287 sprintf(line, "%s", DecompileValueString((etype_t)(def->type), &pr_globals[def->ofs]));
1288 }
1289 else
1290 {
1291 sprintf(line, "%s %s", type_name(def), strings + def->s_name);
1292 }
1293 return line;
1294 }
1295
GetField(char * name)1296 ddef_t *GetField(char *name)
1297 {
1298 int i;
1299 ddef_t *d;
1300
1301 for (i = 1; i < numfielddefs; i++)
1302 {
1303 d = &fields[i];
1304
1305 if (!strcmp(strings + d->s_name, name))
1306 return d;
1307 }
1308 return NULL;
1309 }
DecompileGetParameter(gofs_t ofs)1310 ddef_t *DecompileGetParameter(gofs_t ofs)
1311 {
1312 int i;
1313 ddef_t *def;
1314
1315 def = NULL;
1316
1317 for (i = 0; i < numglobaldefs; i++)
1318 {
1319 def = &globals[i];
1320
1321 if (def->ofs == ofs)
1322 {
1323 return def;
1324 }
1325 }
1326
1327 return NULL;
1328 }
1329
DecompileFunction(char * name)1330 void DecompileFunction(char *name)
1331 {
1332 int i, findex, ps;
1333 dstatement_t *ds, *ts;
1334 dfunction_t *df;
1335 ddef_t *par;
1336 char *arg2;
1337 unsigned short dom, tom;
1338 int j, start, end;
1339 dfunction_t *dfpred;
1340 ddef_t *ef;
1341 static char line[256];
1342 dstatement_t *k;
1343 int dum;
1344
1345
1346 for (i = 1; i < numfunctions; i++)
1347 if (!strcmp(name, strings + functions[i].s_name))
1348 break;
1349 if (i == numfunctions)
1350 {
1351 printf("Fatal Error: No function named \"%s\"\n", name);
1352 exit(1);
1353 }
1354 df = functions + i;
1355
1356 findex = i;
1357
1358 // Check ''local globals''
1359
1360 dfpred = df - 1;
1361
1362 for (j = 0, ps = 0; j < dfpred->numparms; j++)
1363 ps += dfpred->parm_size[j];
1364
1365 start = dfpred->parm_start + dfpred->locals + ps;
1366
1367 if (dfpred->first_statement < 0 && df->first_statement > 0)
1368 start -= 1;
1369
1370 if (start == 0)
1371 start = 1;
1372
1373 end = df->parm_start;
1374
1375 for (j = start; j < end; j++)
1376 {
1377
1378 par = DecompileGetParameter(j);
1379
1380 if (par)
1381 {
1382 if (par->type & (1 << 15))
1383 par->type -= (1 << 15);
1384
1385 if (par->type == ev_function)
1386 {
1387
1388 if (strcmp(strings + par->s_name, "IMMEDIATE"))
1389 if (strcmp(strings + par->s_name, name))
1390 {
1391 fprintf(Decompileofile, "%s;\n", DecompileProfiles[DecompileGetFunctionIdxByName(strings + par->s_name)]);
1392 }
1393 }
1394 else if (par->type != ev_pointer)
1395 if (strcmp(strings + par->s_name, "IMMEDIATE"))
1396 {
1397
1398 if (par->type == ev_field)
1399 {
1400
1401 ef = GetField(strings + par->s_name);
1402
1403 if (!ef)
1404 {
1405 printf("Fatal Error: Could not locate a field named \"%s\"\n", strings + par->s_name);
1406 exit(1);
1407 }
1408 if (ef->type == ev_vector)
1409 j += 3;
1410
1411 #ifndef DONT_USE_DIRTY_TRICKS
1412 if ((ef->type == ev_function) && !strcmp(strings + ef->s_name, "th_pain"))
1413 {
1414 fprintf(Decompileofile, ".void(entity attacker, float damage) th_pain;\n");
1415 }
1416 else
1417 #endif
1418
1419 fprintf(Decompileofile, ".%s %s;\n", type_name(ef), strings + ef->s_name);
1420
1421 }
1422 else
1423 {
1424
1425 if (par->type == ev_vector)
1426 j += 2;
1427
1428 if (par->type == ev_entity || par->type == ev_void)
1429 {
1430
1431 fprintf(Decompileofile, "%s %s;\n", type_name(par), strings + par->s_name);
1432
1433 }
1434 else
1435 {
1436
1437 line[0] = '\0';
1438 sprintf(line, "%s", DecompileValueString((etype_t)(par->type), &pr_globals[par->ofs]));
1439
1440 if (IsConstant(par))
1441 {
1442 fprintf(Decompileofile, "%s %s = %s;\n", type_name(par), strings + par->s_name, line);
1443 }
1444 else
1445 {
1446 if (pr_globals[par->ofs] != 0)
1447 fprintf(Decompileofile, "%s %s /* = %s */;\n", type_name(par), strings + par->s_name, line);
1448 else
1449 fprintf(Decompileofile, "%s %s;\n", type_name(par), strings + par->s_name, line);
1450 }
1451 }
1452 }
1453 }
1454 }
1455 }
1456 /*
1457 * Check ''local globals''
1458 */
1459
1460 if (df->first_statement <= 0)
1461 {
1462
1463 fprintf(Decompileofile, "%s", DecompileProfiles[findex]);
1464 fprintf(Decompileofile, " = #%i; \n", -df->first_statement);
1465
1466 return;
1467 }
1468 ds = statements + df->first_statement;
1469
1470 while (1)
1471 {
1472
1473 dom = (ds->op) % 100;
1474
1475 if (!dom)
1476 break;
1477 else if (dom == OP2_GOTO)
1478 {
1479 // check for i-t-e
1480 if (ds->a > 0)
1481 {
1482 ts = ds + ds->a;
1483 ts->op += 100; // mark the end of a if/ite construct
1484 }
1485 }
1486 else if (dom == OP2_IFNOT)
1487 {
1488 // check for pure if
1489
1490 ts = ds + ds->b;
1491 tom = (ts - 1)->op % 100;
1492
1493 if (tom != OP2_GOTO)
1494 ts->op += 100; // mark the end of a if/ite construct
1495 else if ((ts - 1)->a < 0)
1496 {
1497
1498 /*
1499 arg2 = DecompileGlobal(ds->a, NULL);
1500
1501 if (!((((ts - 1)->a + ds->b) == 0) ||
1502 ((arg2 != NULL) && (((ts - 1)->a + ds->b) == 1))))
1503 (ts - 1)->op += 100;
1504
1505 if (arg2)
1506 free(arg2);
1507 */
1508
1509 if (((ts - 1)->a + ds->b) > 1)
1510 {
1511 // pure if
1512 ts->op += 100; // mark the end of a if/ite construct
1513 }
1514 else
1515 {
1516
1517 dum = 1;
1518 for (k = (ts - 1) + ((ts - 1)->a); k < ds; k++)
1519 {
1520 tom = k->op % 100;
1521 if (tom == OP2_GOTO || tom == OP2_IF || tom == OP2_IFNOT)
1522 dum = 0;
1523 }
1524 if (!dum)
1525 {
1526 // pure if
1527 ts->op += 100; // mark the end of a if/ite construct
1528 }
1529 }
1530 }
1531 }
1532 else if (dom == OP2_IF)
1533 {
1534 ts = ds + ds->b;
1535 ts->op += 10000; // mark the start of a do construct
1536
1537 }
1538 ds++;
1539 }
1540
1541 /*
1542 * print the prototype
1543 */
1544 fprintf(Decompileofile, "\n%s", DecompileProfiles[findex]);
1545
1546 // handle state functions
1547
1548 ds = statements + df->first_statement;
1549
1550 if (ds->op == OP2_STATE)
1551 {
1552
1553 par = DecompileGetParameter(ds->a);
1554 if (!par)
1555 {
1556 printf("Fatal Error - Can't determine frame number.");
1557 exit(1);
1558 }
1559
1560 arg2 = DecompileGet(df, ds->b, NULL);
1561 if (!arg2)
1562 {
1563 printf("Fatal Error - No state parameter with offset %i.", ds->b);
1564 exit(1);
1565 }
1566
1567 fprintf(Decompileofile, " = [ %s, %s ]", DecompileValueString((etype_t)(par->type), &pr_globals[par->ofs]), arg2);
1568
1569 free(arg2);
1570
1571 }
1572 else
1573 {
1574 fprintf(Decompileofile, " =");
1575 }
1576 fprintf(Decompileofile, "\n{\n");
1577
1578 /*
1579 fprintf(Decompileprofile, "%s", DecompileProfiles[findex]);
1580 fprintf(Decompileprofile, ") %s;\n", name);
1581 */
1582
1583 /*
1584 * calculate the parameter size
1585 */
1586
1587 for (j = 0, ps = 0; j < df->numparms; j++)
1588 ps += df->parm_size[j];
1589
1590 /*
1591 * print the locals
1592 */
1593
1594 if (df->locals > 0) {
1595
1596 if ((df->parm_start) + df->locals - 1 >= (df->parm_start) + ps)
1597 {
1598
1599 for (i = df->parm_start + ps; i < (df->parm_start) + df->locals; i++)
1600 {
1601
1602 par = DecompileGetParameter(i);
1603
1604 if (!par)
1605 {
1606 // temps
1607 continue;
1608 }
1609 else
1610 {
1611 if (!strcmp(strings + par->s_name, "IMMEDIATE"))
1612 continue; // immediates don't belong
1613 if (par->type == ev_function)
1614 {
1615 printf("Warning Fields and functions must be global\n");
1616 }
1617 else
1618 fprintf(Decompileofile, "\tlocal %s;\n", DecompilePrintParameter(par));
1619 if (par->type == ev_vector)
1620 i += 2;
1621 }
1622 }
1623
1624 fprintf(Decompileofile, "\n");
1625
1626 }
1627 }
1628 /*
1629 * do the hard work
1630 */
1631
1632 DecompileDecompileFunction(df);
1633
1634 fprintf(Decompileofile, "};\n");
1635 }
1636 extern boolean safedecomp;
1637 int fake_name;
1638 char synth_name[1024]; // fake name part2
1639
TrySynthName(char * first)1640 boolean TrySynthName(char *first)
1641 {
1642 int i;
1643
1644 // try to figure out the filename
1645 // based on the first function in the file
1646 for (i=0; i < FILELISTSIZE; i+=2)
1647 {
1648 if (!strcmp(filenames[i], first))
1649 {
1650 sprintf(synth_name, filenames[i + 1]);
1651 return true;
1652 }
1653 }
1654 return false;
1655 }
1656
DecompileDecompileFunctions(void)1657 void DecompileDecompileFunctions(void)
1658 {
1659 int i;
1660 unsigned int o;
1661 dfunction_t *d;
1662 boolean bogusname;
1663 FILE *f;
1664 char fname[512];
1665
1666 DecompileCalcProfiles();
1667
1668 Decompileprogssrc = fopen("progs.src", "w");
1669 if (!Decompileprogssrc)
1670 {
1671 printf("Fatal Error - Could not open \"progs.src\" for output.\n");
1672 exit(1);
1673 }
1674
1675 fprintf(Decompileprogssrc, "./progs.dat\n\n");
1676 /*
1677 Decompileprofile = fopen("!profile.qc", "w");
1678 if (!Decompileprofile)
1679 Error("DecompileDecompileFunctions - Could not open \"!profile.qc\" for output.");
1680 fprintf(Decompileprogssrc, "!profile.qc\n");
1681 */
1682
1683 for (i = 1; i < numfunctions; i++)
1684 {
1685 d = &functions[i];
1686
1687 fname[0] = '\0';
1688 if (d->s_file <= strofs && d->s_file >= 0)
1689 sprintf(fname, "%s", strings + d->s_file);
1690 // FrikaC -- not sure if this is cool or what?
1691 bogusname = false;
1692 if (strlen(fname) <= 0)
1693 bogusname = true;
1694 else for (o = 0; o < strlen(fname); o++)
1695 {
1696 if ((fname[o] < 'a' || fname[o] > 'z') &&
1697 (fname[o] < '0' || fname[o] > '9') &&
1698 (fname[o] <'A' || fname[o] > 'Z') &&
1699 (fname[o] != '.' && fname[o] != '!' && fname[o] != '_'))
1700 {
1701 if (fname[o] == '/')
1702 fname[o] = '.';
1703 else if (fname[o] == '\\')
1704 fname[o] = '.';
1705 else
1706 {
1707 bogusname = true;
1708 break;
1709 }
1710 }
1711 }
1712
1713 if (bogusname)
1714 {
1715 if (!DecompileAlreadySeen(fname))
1716 {
1717 synth_name[0] = 0;
1718 if(!TrySynthName(va("%s", strings + d->s_name)))
1719 fake_name++;
1720 }
1721 if (synth_name[0])
1722 sprintf(fname, synth_name);
1723 else
1724 sprintf(fname, "frik%i.qc", fake_name);
1725 }
1726
1727
1728
1729 if (!DecompileAlreadySeen(fname))
1730 {
1731 printf("decompiling %s...\n", fname);
1732 fprintf(Decompileprogssrc, "%s\n", fname);
1733 f = fopen(fname, "w");
1734 }
1735 else
1736 f = fopen(fname, "a+");
1737 if (!f)
1738 {
1739 printf("Fatal Error - Could not open \"%s\" for output.\n", fname);
1740 exit(1);
1741 }
1742 Decompileofile = f;
1743 DecompileFunction(strings + d->s_name);
1744
1745 if (fclose(f))
1746 {
1747 printf("Fatal Error - Could not close \"%s\" properly.\n", fname);
1748 exit(1);
1749 }
1750
1751 }
1752 if (fclose(Decompileprogssrc))
1753 {
1754 printf("Fatal Error - Could not close \"progs.src\" properly.\n");
1755 exit(1);
1756 }
1757 }
1758
DecompileProgsDat(char * name)1759 void DecompileProgsDat(char *name)
1760 {
1761 DecompileReadData(name);
1762 DecompileDecompileFunctions();
1763
1764 }
1765
DecompileGlobalStringNoContents(gofs_t ofs)1766 char *DecompileGlobalStringNoContents(gofs_t ofs)
1767 {
1768 int i;
1769 ddef_t *def;
1770 static char line[128];
1771
1772 line[0] = '0';
1773 sprintf(line, "%i(???)", ofs);
1774
1775 for (i = 0; i < numglobaldefs; i++)
1776 {
1777 def = &globals[i];
1778
1779 if (def->ofs == ofs)
1780 {
1781 line[0] = '0';
1782 sprintf(line, "%i(%s)", def->ofs, strings + def->s_name);
1783 break;
1784 }
1785 }
1786
1787 i = strlen(line);
1788 for (; i < 16; i++)
1789 strcat(line, " ");
1790 strcat(line, " ");
1791
1792 return line;
1793 }
1794
DecompileGlobalString(gofs_t ofs)1795 char *DecompileGlobalString(gofs_t ofs)
1796 {
1797 char *s;
1798 int i;
1799 ddef_t *def;
1800 static char line[128];
1801
1802 line[0] = '0';
1803 sprintf(line, "%i(???)", ofs);
1804
1805 for (i = 0; i < numglobaldefs; i++)
1806 {
1807 def = &globals[i];
1808
1809 if (def->ofs == ofs)
1810 {
1811
1812 line[0] = '0';
1813 if (!strcmp(strings + def->s_name, "IMMEDIATE"))
1814 {
1815 s = PR_ValueString((etype_t)(def->type), &pr_globals[ofs]);
1816 sprintf(line, "%i(%s)", def->ofs, s);
1817 }
1818 else
1819 sprintf(line, "%i(%s)", def->ofs, strings + def->s_name);
1820 }
1821 }
1822
1823 i = strlen(line);
1824 for (; i < 16; i++)
1825 strcat(line, " ");
1826 strcat(line, " ");
1827
1828 return line;
1829 }
1830
DecompilePrintStatement(dstatement_t * s)1831 void DecompilePrintStatement(dstatement_t * s)
1832 {
1833 int i;
1834
1835 printf("%4i : %s ", (int)(s - statements), pr_opcodes[s->op].opname);
1836 i = strlen(pr_opcodes[s->op].opname);
1837 for (; i < 10; i++)
1838 printf(" ");
1839
1840 if (s->op == OP2_IF || s->op == OP2_IFNOT)
1841 printf("%sbranch %i", DecompileGlobalString(s->a), s->b);
1842 else if (s->op == OP2_GOTO)
1843 {
1844 printf("branch %i", s->a);
1845 }
1846 else if ((unsigned)(s->op - OP2_STORE_F) < 6)
1847 {
1848 printf("%s", DecompileGlobalString(s->a));
1849 printf("%s", DecompileGlobalStringNoContents(s->b));
1850 }
1851 else
1852 {
1853 if (s->a)
1854 printf("%s", DecompileGlobalString(s->a));
1855 if (s->b)
1856 printf("%s", DecompileGlobalString(s->b));
1857 if (s->c)
1858 printf("%s", DecompileGlobalStringNoContents(s->c));
1859 }
1860 printf("\n");
1861 }
1862
DecompilePrintFunction(char * name)1863 void DecompilePrintFunction(char *name)
1864 {
1865 int i;
1866 dstatement_t *ds;
1867 dfunction_t *df;
1868
1869 for (i = 0; i < numfunctions; i++)
1870 if (!strcmp(name, strings + functions[i].s_name))
1871 break;
1872 if (i == numfunctions)
1873 {
1874 printf("Fatal Error: No function names \"%s\"\n", name);
1875 exit(1);
1876 }
1877 df = functions + i;
1878
1879 printf("Statements for %s:\n", name);
1880 ds = statements + df->first_statement;
1881 while (1)
1882 {
1883 DecompilePrintStatement(ds);
1884
1885 if (!ds->op)
1886 break;
1887 ds++;
1888 }
1889 }
1890
1891