aboutsummaryrefslogtreecommitdiff
path: root/engines/cruise/decompiler.cpp
diff options
context:
space:
mode:
authorDavid Corrales2007-05-26 20:23:24 +0000
committerDavid Corrales2007-05-26 20:23:24 +0000
commit3646c968c9578c2a94d65ebd5fb06ec835f8c51d (patch)
tree8b57b339ebb31a1d7a67f1678aa5dc5c7759070a /engines/cruise/decompiler.cpp
parentd1f56d93f934150f4b579c2e90564e2bf035f113 (diff)
parentac45c5b33d834acbc9718f89be76e49d403a4d2c (diff)
downloadscummvm-rg350-3646c968c9578c2a94d65ebd5fb06ec835f8c51d.tar.gz
scummvm-rg350-3646c968c9578c2a94d65ebd5fb06ec835f8c51d.tar.bz2
scummvm-rg350-3646c968c9578c2a94d65ebd5fb06ec835f8c51d.zip
Merged the fs branch with trunk. r26472:26948
svn-id: r26949
Diffstat (limited to 'engines/cruise/decompiler.cpp')
-rw-r--r--engines/cruise/decompiler.cpp1598
1 files changed, 1598 insertions, 0 deletions
diff --git a/engines/cruise/decompiler.cpp b/engines/cruise/decompiler.cpp
new file mode 100644
index 0000000000..072fa171fd
--- /dev/null
+++ b/engines/cruise/decompiler.cpp
@@ -0,0 +1,1598 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2006 The ScummVM project
+ *
+ * cinE Engine is (C) 2004-2005 by CinE Team
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "cruise/cruise_main.h"
+
+namespace Cruise {
+
+#ifdef DUMP_SCRIPT
+
+#define numMaxLignes 100000
+#define lineMaxSize 10000
+
+int currentLineType = 0;
+
+struct decompileLineStruct {
+ int lineOffset;
+ char line[lineMaxSize];
+ int indent;
+ int type;
+ int pendingElse;
+};
+
+struct decompileLineStruct decompileLineTable[numMaxLignes];
+
+int positionInDecompileLineTable;
+
+int failed;
+
+char *currentDecompScript;
+scriptInstanceStruct dummy;
+scriptInstanceStruct *currentDecompScriptPtr = &dummy;
+
+uint8 *getDataFromData3(ovlData3Struct * ptr, int param);
+
+opcodeTypeFunction decompOpcodeTypeTable[64];
+
+int currentLineIdx = 0;
+
+unsigned long int currentOffset;
+
+unsigned long int dumpIdx = 0;
+
+FILE *fHandle = NULL;
+
+#define DECOMPILER_STACK_DEPTH 100
+#define DECOMPILER_STACK_ENTRY_SIZE 5000
+
+char tempbuffer[5000];
+
+char decompileStack[DECOMPILER_STACK_DEPTH][DECOMPILER_STACK_ENTRY_SIZE];
+
+unsigned long int decompileStackPosition = 0;
+
+uint8 stringName[256];
+
+ovlData3Struct *currentScript;
+
+ovlDataStruct *currentDecompOvl;
+int currentDecompScriptIdx;
+
+char decompSaveOpcodeVar[256];
+
+uint8 *getStringNameFromIdx(uint16 stringTypeIdx, char *offset) {
+ switch (stringTypeIdx & 7) {
+ case 2:
+ {
+ sprintf(stringName, "\"%s\"",
+ currentScript->dataPtr +
+ currentScript->offsetToSubData3 + atoi(offset));
+ break;
+ }
+ case 5:
+ {
+ sprintf(stringName, "vars[%s]", offset);
+ break;
+ }
+ default:
+ {
+ sprintf(stringName, "string[%d][%s]",
+ stringTypeIdx & 7, offset);
+ break;
+ }
+ }
+
+ return stringName;
+}
+
+char *resolveMessage(char *messageIdxString) {
+ char buffer[500];
+ int variable;
+
+ variable = atoi(messageIdxString);
+ sprintf(buffer, "%d", variable);
+
+ if (strcmp(buffer, messageIdxString)) {
+ return messageIdxString;
+ } else {
+ return currentDecompOvl->stringTable[atoi(messageIdxString)].
+ string;
+ }
+}
+
+void pushDecomp(char *string, ...) {
+ va_list va;
+
+ va_start(va, string);
+ vsprintf(decompileStack[decompileStackPosition], string, va);
+ va_end(va);
+
+ // fprintf(fHandle, "----> %s\n",decompileStack[decompileStackPosition]);
+
+ decompileStackPosition++;
+}
+
+void resolveDecompShort(char *buffer) {
+ ovlData3Struct *data3Ptr = currentScript;
+
+ {
+ int i;
+
+ importScriptStruct *importEntry =
+ (importScriptStruct *) (data3Ptr->dataPtr +
+ data3Ptr->offsetToImportData);
+
+ for (i = 0; i < data3Ptr->numImport; i++) {
+ switch (importEntry->type) {
+ case 20: // script
+ case 30:
+ case 40:
+ case 50:
+ {
+ if (importEntry->offset == currentDecompScriptPtr->var4 - 3) // param1
+ {
+ sprintf(buffer,
+ data3Ptr->dataPtr +
+ data3Ptr->
+ offsetToImportName +
+ importEntry->offsetToName);
+ return;
+ }
+ if (importEntry->offset == currentDecompScriptPtr->var4 - 6) // param2
+ {
+ sprintf(buffer, "linkedIdx");
+ return;
+ }
+ break;
+ }
+ default:
+ {
+ if (importEntry->offset ==
+ currentDecompScriptPtr->var4 - 4) {
+ sprintf(buffer,
+ data3Ptr->dataPtr +
+ data3Ptr->
+ offsetToImportName +
+ importEntry->offsetToName);
+ return;
+ }
+ }
+ }
+ importEntry++;
+ }
+ }
+
+ buffer[0] = 0;
+
+}
+
+void resolveDecompChar(char *buffer) {
+ ovlData3Struct *data3Ptr = currentScript;
+
+ {
+ int i;
+
+ importScriptStruct *importEntry =
+ (importScriptStruct *) (data3Ptr->dataPtr +
+ data3Ptr->offsetToImportData);
+
+ for (i = 0; i < data3Ptr->numImport; i++) {
+ switch (importEntry->type) {
+ default:
+ {
+ if (importEntry->offset ==
+ currentDecompScriptPtr->var4 - 2) {
+ sprintf(buffer,
+ data3Ptr->dataPtr +
+ data3Ptr->
+ offsetToImportName +
+ importEntry->offsetToName);
+ return;
+ }
+ }
+ }
+ importEntry++;
+ }
+ }
+
+ buffer[0] = 0;
+
+}
+
+char *popDecomp() {
+ // printf("<----\n");
+
+ if (!decompileStackPosition) {
+ return ("");
+ }
+
+ decompileStackPosition--;
+
+ return decompileStack[decompileStackPosition];
+}
+
+void getByteFromDecompScript(char *buffer) {
+ short int var = currentDecompScript[currentDecompScriptPtr->var4];
+
+ currentDecompScriptPtr->var4 = currentDecompScriptPtr->var4 + 1;
+
+ if (var == -1) {
+ resolveDecompChar(buffer);
+
+ if (buffer[0])
+ return;
+ }
+
+ sprintf(buffer, "%d", var);
+}
+
+char getByteFromDecompScriptReal(void) {
+ short int var = currentDecompScript[currentDecompScriptPtr->var4];
+
+ currentDecompScriptPtr->var4 = currentDecompScriptPtr->var4 + 1;
+
+ return var;
+}
+
+void getShortFromDecompScript(char *buffer) {
+ short int var =
+ *(int16 *) (currentDecompScript + currentDecompScriptPtr->var4);
+
+ currentDecompScriptPtr->var4 = currentDecompScriptPtr->var4 + 2;
+
+ flipShort(&var);
+
+ if (var == -1) {
+ resolveDecompShort(buffer);
+
+ if (buffer[0])
+ return;
+ }
+
+ sprintf(buffer, "%d", var);
+}
+
+short int getShortFromDecompScriptReal(void) {
+ short int var =
+ *(int16 *) (currentDecompScript + currentDecompScriptPtr->var4);
+
+ currentDecompScriptPtr->var4 = currentDecompScriptPtr->var4 + 2;
+
+ flipShort(&var);
+
+ return var;
+}
+
+void addDecomp(char *string, ...) {
+ va_list va;
+
+ /* fprintf(fHandle,"%d: ",currentLineIdx);
+ *
+ * va_start(va,string);
+ * vfprintf(fHandle,string,va);
+ * va_end(va);
+ *
+ * fprintf(fHandle,"\n"); */
+
+ struct decompileLineStruct *pLineStruct =
+ &decompileLineTable[positionInDecompileLineTable++];
+
+ pLineStruct->lineOffset = currentLineIdx;
+ pLineStruct->indent = 0;
+ pLineStruct->type = currentLineType;
+ pLineStruct->line[0] = 0;
+ pLineStruct->pendingElse = 0;
+
+ va_start(va, string);
+ vsprintf(pLineStruct->line, string, va);
+ va_end(va);
+
+ currentLineIdx = currentDecompScriptPtr->var4;
+ currentLineType = 0;
+
+ /*printf("%d: ",currentOffset);
+ *
+ * va_start(va,string);
+ * vprintf(string,va);
+ * va_end(va);
+ *
+ * printf("\n"); */
+}
+
+void resolveVarName(char *ovlIdxString, int varType, char *varIdxString,
+ char *outputName) {
+ int varIdx = atoi(varIdxString);
+
+ strcpy(outputName, "");
+
+ if (varType == 2) {
+ strcpy(outputName, getStringNameFromIdx(varType,
+ varIdxString));
+ return;
+ }
+ if (varType == 1) {
+ sprintf(outputName, "localVar_%s", varIdxString);
+ return;
+ }
+
+ if (!strcmp(ovlIdxString, "0")) {
+ int i;
+
+ for (i = 0; i < currentDecompOvl->numExport; i++) {
+ if (varIdx == currentDecompOvl->exportDataPtr[i].idx) {
+ if (((currentDecompOvl->exportDataPtr[i].var4 & 0xF0) == 0) && varType != 0x20) // var
+ {
+ strcpy(outputName,
+ currentDecompOvl->exportNamesPtr +
+ currentDecompOvl->exportDataPtr[i].
+ offsetToName);
+ return;
+ }
+ if ((currentDecompOvl->exportDataPtr[i].var4) == 20 && varType == 0x20) // script
+ {
+ strcpy(outputName,
+ currentDecompOvl->exportNamesPtr +
+ currentDecompOvl->exportDataPtr[i].
+ offsetToName);
+ return;
+ }
+ }
+ }
+ sprintf(outputName, "ovl(%s).[%d][%s]", ovlIdxString, varType,
+ varIdxString);
+ } else {
+ strcpy(outputName, ovlIdxString);
+ }
+}
+
+int decompLoadVar(void) {
+ switch (currentScriptOpcodeType) {
+ case 0:
+ {
+ char buffer[256];
+
+ getShortFromDecompScript(buffer);
+
+ pushDecomp(buffer);
+
+ return (0);
+ }
+ // string
+ case 1:
+ {
+ char buffer1[256];
+ char buffer2[256];
+ char buffer3[256];
+ char varName[256];
+
+ getByteFromDecompScript(buffer1);
+ getByteFromDecompScript(buffer2);
+
+ getShortFromDecompScript(buffer3);
+
+ resolveVarName(buffer2, atoi(buffer1) & 7, buffer3,
+ varName);
+
+ pushDecomp("%s", varName);
+ return (0);
+ }
+ case 2:
+ {
+ char buffer1[256];
+ char buffer2[256];
+ char buffer3[256];
+ char varName[256];
+
+ getByteFromDecompScript(buffer1);
+ getByteFromDecompScript(buffer2);
+
+ getShortFromDecompScript(buffer3);
+
+ resolveVarName(buffer2, atoi(buffer1) & 7, buffer3,
+ varName);
+
+ pushDecomp("%s", varName);
+ return (0);
+ }
+ case 5:
+ {
+ char buffer1[256];
+ char buffer2[256];
+ char buffer3[256];
+ char varName[256];
+
+ getByteFromDecompScript(buffer1);
+ getByteFromDecompScript(buffer2);
+
+ getShortFromDecompScript(buffer3);
+
+ resolveVarName(buffer2, atoi(buffer1) & 7, buffer3,
+ varName);
+
+ pushDecomp("%s[%s]", varName, decompSaveOpcodeVar);
+ return (0);
+ }
+ default:
+ {
+ printf("Unsupported type %d in opcodeType0\n",
+ currentScriptOpcodeType);
+ failed = 1;
+ }
+ }
+}
+
+int decompSaveVar(void) {
+// int var = popVar();
+
+ switch (currentScriptOpcodeType) {
+ case 0:
+ {
+ addDecomp(popDecomp());
+ return (0);
+ }
+ // modify string
+ case 1:
+ {
+ char buffer1[256];
+ char buffer2[256];
+ char buffer3[256];
+ char varName[256];
+ uint8 type;
+
+ getByteFromDecompScript(buffer1);
+ getByteFromDecompScript(buffer2);
+
+ getShortFromDecompScript(buffer3);
+
+ type = atoi(buffer1) & 7;
+
+ resolveVarName(buffer2, type, buffer3, varName);
+
+ addDecomp("%s = %s", varName, popDecomp());
+ break;
+ }
+ case 2:
+ {
+ char buffer1[256];
+ char buffer2[256];
+ char buffer3[256];
+
+ getByteFromDecompScript(buffer1);
+ getByteFromDecompScript(buffer2);
+
+ getShortFromDecompScript(buffer3);
+
+ addDecomp("ovl(%s).setVar(%s,%s) = %s", buffer2,
+ buffer1, buffer3, popDecomp());
+ break;
+ }
+ case 4:
+ {
+ strcpy(decompSaveOpcodeVar, popDecomp());
+ break;
+ }
+ case 5:
+ {
+ char buffer1[256];
+ char buffer2[256];
+ char buffer3[256];
+ char varName[256];
+ uint8 type;
+
+ getByteFromDecompScript(buffer1);
+ getByteFromDecompScript(buffer2);
+
+ getShortFromDecompScript(buffer3);
+
+ type = atoi(buffer1) & 7;
+
+ resolveVarName(buffer2, type, buffer3, varName);
+
+ addDecomp("%s[%s] = %s", varName, decompSaveOpcodeVar,
+ popDecomp());
+ break;
+ }
+ default:
+ {
+ printf("Unsupported type %d in opcodeType1\n",
+ currentScriptOpcodeType);
+ failed = 1;
+ }
+ }
+
+ return (0);
+}
+
+int decompOpcodeType2(void) {
+ switch (currentScriptOpcodeType) {
+ case 1:
+ {
+ char buffer3[256];
+ char varName[256];
+ int byte1 = getByteFromDecompScriptReal();
+ int byte2 = getByteFromDecompScriptReal();
+ getShortFromDecompScript(buffer3);
+
+ resolveVarName("0", byte1 & 7, buffer3, varName);
+
+ pushDecomp(varName);
+
+ break;
+ }
+ case 5:
+ {
+ int byte1 = getByteFromDecompScriptReal();
+ int byte2 = getByteFromDecompScriptReal();
+ short int short1 = getShortFromDecompScriptReal();
+
+ int8 *ptr = scriptDataPtrTable[byte1 & 7] + short1;
+
+ if ((byte1 & 7) == 2) {
+ pushDecomp("\"%s\"[%s]", ptr,
+ decompSaveOpcodeVar);
+ } else if ((byte1 & 7) == 5) {
+ pushDecomp("freeString[%d][%s]", short1,
+ decompSaveOpcodeVar);
+ } else {
+ printf("Unsupported type %d in opcodeType2\n",
+ byte1 & 7);
+ failed = 1;
+ }
+ break;
+ }
+ default:
+ {
+ printf("Unsupported type %d in opcodeType2\n",
+ currentScriptOpcodeType);
+ failed = 1;
+ }
+ }
+ return (0);
+}
+
+int decompMath(void) {
+ char *param1 = popDecomp();
+ char *param2 = popDecomp();
+
+ switch (currentScriptOpcodeType) {
+ case 0:
+ {
+ sprintf(tempbuffer, "%s+%s", param1, param2);
+ pushDecomp(tempbuffer);
+ break;
+ }
+ case 1:
+ {
+ sprintf(tempbuffer, "%s/%s", param1, param2);
+ pushDecomp(tempbuffer);
+ break;
+ }
+ case 2:
+ {
+ sprintf(tempbuffer, "%s-%s", param1, param2);
+ pushDecomp(tempbuffer);
+ break;
+ }
+ case 3:
+ {
+ sprintf(tempbuffer, "%s*%s", param1, param2);
+ pushDecomp(tempbuffer);
+ break;
+ }
+ case 4:
+ {
+ sprintf(tempbuffer, "%s\%%s", param1, param2);
+ pushDecomp(tempbuffer);
+ break;
+ }
+ case 5:
+ case 7:
+ {
+ sprintf(tempbuffer, "%s|%s", param1, param2);
+ pushDecomp(tempbuffer);
+ break;
+ }
+ case 6:
+ {
+ sprintf(tempbuffer, "%s&%s", param1, param2);
+ pushDecomp(tempbuffer);
+ break;
+ }
+
+ default:
+ {
+ sprintf(tempbuffer, "decompMath(%d,%s,%s)",
+ currentScriptOpcodeType, param1, param2);
+ pushDecomp(tempbuffer);
+ break;
+ }
+ }
+ return (0);
+}
+
+int decompBoolCompare(void) {
+ char *param1;
+ char *param2;
+
+ param1 = popDecomp();
+ param2 = popDecomp();
+
+ sprintf(tempbuffer, "compare(%s,%s)", param1, param2);
+ pushDecomp(tempbuffer);
+
+ return 0;
+}
+
+int decompTest(void) {
+ unsigned long int oldOffset = currentDecompScriptPtr->var4;
+ short int offset = getShortFromDecompScriptReal();
+
+ switch (currentScriptOpcodeType) {
+ case 0:
+ {
+ currentLineType = 1;
+ addDecomp("test '!(bitMask & 1)' and goto %d",
+ offset + oldOffset);
+ break;
+ }
+ case 1:
+ {
+ currentLineType = 1;
+ addDecomp("test '(bitMask & 1)' and goto %d",
+ offset + oldOffset);
+ break;
+ }
+ case 2:
+ {
+ currentLineType = 1;
+ addDecomp("test '(bitMask & 2)' and goto %d",
+ offset + oldOffset);
+ break;
+ }
+ case 3:
+ {
+ currentLineType = 1;
+ addDecomp("test '(bitMask & 3)' and goto %d",
+ offset + oldOffset);
+ break;
+ }
+ case 4:
+ {
+ currentLineType = 1;
+ addDecomp("test '(bitMask & 4)' and goto %d",
+ offset + oldOffset);
+ break;
+ }
+ case 5:
+ {
+ currentLineType = 1;
+ addDecomp("test '(bitMask & 5)' and goto %d",
+ offset + oldOffset);
+ break;
+ }
+ case 6:
+ {
+ currentLineType = 2;
+ addDecomp("test 'never' and goto %d",
+ offset + oldOffset);
+ break;
+ }
+ case 7:
+ {
+ currentLineType = 3;
+ addDecomp("goto %d", offset + oldOffset);
+ break;
+ }
+
+ }
+
+ return 0;
+}
+
+int decompCompare(void) {
+ char *param;
+
+ param = popDecomp();
+
+ addDecomp("sign(%s)", param);
+
+/*
+ if(!pop)
+ si = 1;
+
+ if(pop<0)
+ {
+ si |= 4;
+ }
+
+ if(pop>0)
+ {
+ si |= 2;
+ }
+
+ currentScriptPtr->bitMask = si;
+*/
+
+ return 0;
+}
+
+int decompSwapStack(void) {
+ char *stack1;
+ char *stack2;
+ char buffer1[4000];
+ char buffer2[4000];
+
+ stack1 = popDecomp();
+ stack2 = popDecomp();
+
+ strcpyuint8(buffer1, stack1);
+ strcpyuint8(buffer2, stack2);
+
+ pushDecomp(buffer1);
+ pushDecomp(buffer2);
+
+ return 0;
+}
+
+int decompFunction(void) {
+ currentScriptOpcodeType = getByteFromDecompScriptReal();
+// addDecomp("OP_%X", currentScriptOpcodeType);
+ switch (currentScriptOpcodeType) {
+ case 0x1:
+ {
+ pushDecomp("_setMain5()");
+ break;
+ }
+ case 0x2:
+ {
+ pushDecomp("_prepareFade()");
+ break;
+ }
+ case 0x3:
+ {
+ sprintf(tempbuffer, "_loadBackground(%s,%s)",
+ popDecomp(), popDecomp());
+ pushDecomp(tempbuffer);
+ break;
+ }
+ case 0x4:
+ {
+ sprintf(tempbuffer, "_loadFullBundle(%s,%s)",
+ popDecomp(), popDecomp());
+ pushDecomp(tempbuffer);
+ break;
+ }
+ case 0x5:
+ {
+ sprintf(tempbuffer, "_addCell(%s,%s,%s)", popDecomp(),
+ popDecomp(), popDecomp());
+ pushDecomp(tempbuffer);
+ break;
+ }
+ case 0x6:
+ {
+ unsigned long int numArg = atoi(popDecomp());
+ char *ovlStr;
+ char *idxStr;
+ int i;
+ char functionName[100];
+
+ idxStr = popDecomp();
+ ovlStr = popDecomp();
+
+ resolveVarName(ovlStr, 0x20, idxStr, functionName);
+
+ sprintf(tempbuffer, "_startASync(%s", functionName);
+
+ for (i = 0; i < numArg; i++) {
+ strcatuint8(tempbuffer, ",");
+ strcatuint8(tempbuffer, popDecomp());
+ }
+
+ strcatuint8(tempbuffer, ")");
+
+ pushDecomp(tempbuffer);
+ break;
+ }
+ case 0x7:
+ {
+ char *var1;
+ char *objIdxStr;
+ char *ovlStr;
+ char varName[256];
+ int i;
+
+ var1 = popDecomp();
+ objIdxStr = popDecomp();
+ ovlStr = popDecomp();
+
+ sprintf(tempbuffer,
+ "_createObjectFromOvlData(ovl:%s,dataIdx:%s,%s)",
+ ovlStr, objIdxStr, var1);
+ pushDecomp(tempbuffer);
+ break;
+ }
+ case 0x8:
+ {
+ sprintf(tempbuffer, "_removeCell(%s,%s,%s)",
+ popDecomp(), popDecomp(), popDecomp());
+ pushDecomp(tempbuffer);
+ break;
+ }
+ case 0x9:
+ {
+ pushDecomp("_freeobjectList()");
+ break;
+ }
+ case 0xA:
+ {
+ sprintf(tempbuffer, "_removeScript(ovl(%s),%s)",
+ popDecomp(), popDecomp());
+ pushDecomp(tempbuffer);
+ break;
+ }
+ case 0xB:
+ {
+ sprintf(tempbuffer, "_resetFilesEntries(%s,%s)",
+ popDecomp(), popDecomp());
+ pushDecomp(tempbuffer);
+ break;
+ }
+ case 0xC:
+ {
+ sprintf(tempbuffer, "_loadOverlay(%s)", popDecomp());
+ pushDecomp(tempbuffer);
+ break;
+ }
+ case 0xD:
+ {
+ sprintf(tempbuffer, "_palManipulation(%s,%s,%s,%s,%s)",
+ popDecomp(), popDecomp(), popDecomp(), popDecomp(),
+ popDecomp());
+ pushDecomp(tempbuffer);
+ break;
+ }
+ case 0xE:
+ {
+ sprintf(tempbuffer, "_playSample(%s,%s,%s,%s)",
+ popDecomp(), popDecomp(), popDecomp(),
+ popDecomp());
+ pushDecomp(tempbuffer);
+ break;
+ }
+ case 0x10:
+ {
+ sprintf(tempbuffer, "_releaseScript2(%s)",
+ popDecomp());
+ pushDecomp(tempbuffer);
+ break;
+ }
+ case 0x11:
+ {
+ sprintf(tempbuffer, "_getOverlayIdx(%s)", popDecomp());
+ pushDecomp(tempbuffer);
+ break;
+ }
+ case 0x13:
+ {
+ sprintf(tempbuffer,
+ "_displayMessage(%s,\"%s\",%s,%s,%s,%s)",
+ popDecomp(), resolveMessage(popDecomp()),
+ popDecomp(), popDecomp(), popDecomp(),
+ popDecomp());
+ pushDecomp(tempbuffer);
+ break;
+ }
+ case 0x14:
+ {
+ sprintf(tempbuffer, "_removeObject(ovl(%s),%s)",
+ popDecomp(), popDecomp());
+ pushDecomp(tempbuffer);
+ break;
+ }
+ case 0x15:
+ {
+ pushDecomp("_pauseScript()");
+ break;
+ }
+ case 0x16:
+ {
+ sprintf(tempbuffer,
+ "_Op_FreezeCell(%s,%s,%s,%s,%s,%s)", popDecomp(),
+ popDecomp(), popDecomp(), popDecomp(), popDecomp(),
+ popDecomp());
+ pushDecomp(tempbuffer);
+ break;
+ }
+ case 0x17:
+ {
+ sprintf(tempbuffer, "_loadCtp(%s)", popDecomp());
+ pushDecomp(tempbuffer);
+ break;
+ }
+ case 0x18:
+ {
+ sprintf(tempbuffer,
+ "_Op_AddAnimation(%s,%s,%s,%s,%s,%s,%s)",
+ popDecomp(), popDecomp(), popDecomp(), popDecomp(),
+ popDecomp(), popDecomp(), popDecomp());
+ pushDecomp(tempbuffer);
+ break;
+ }
+ case 0x19:
+ {
+ sprintf(tempbuffer, "_Op_RemoveAnimation(%s,%s,%s)",
+ popDecomp(), popDecomp(), popDecomp());
+ pushDecomp(tempbuffer);
+ break;
+ }
+ case 0x1A:
+ {
+ sprintf(tempbuffer, "_setupScaleFormula(%s,%s,%s,%s)",
+ popDecomp(), popDecomp(), popDecomp(),
+ popDecomp());
+ pushDecomp(tempbuffer);
+ break;
+ }
+ case 0x1E:
+ {
+ sprintf(tempbuffer, "_op_1E(%s,%s,%s,%s,%s,%s)",
+ popDecomp(), popDecomp(), popDecomp(), popDecomp(),
+ popDecomp(), popDecomp());
+ pushDecomp(tempbuffer);
+ break;
+ }
+ case 0x21:
+ {
+ sprintf(tempbuffer, "_isActorLoaded(%s,%s,%s)",
+ popDecomp(), popDecomp(), popDecomp());
+ pushDecomp(tempbuffer);
+ break;
+ }
+ case 0x22:
+ {
+ sprintf(tempbuffer, "_computeScale(%s)", popDecomp());
+ pushDecomp(tempbuffer);
+ break;
+ }
+ case 0x23:
+ {
+ sprintf(tempbuffer, "_convertToScale(%s,%s)",
+ popDecomp(), popDecomp());
+ pushDecomp(tempbuffer);
+ break;
+ }
+ case 0x24:
+ {
+ sprintf(tempbuffer, "_op_24(%s,%s,%s,%s)", popDecomp(),
+ popDecomp(), popDecomp(), popDecomp());
+ pushDecomp(tempbuffer);
+ break;
+ }
+ case 0x27:
+ {
+ sprintf(tempbuffer, "_getWalkBoxCollision(%s,%s)",
+ popDecomp(), popDecomp());
+ pushDecomp(tempbuffer);
+ break;
+ }
+ case 0x28:
+ {
+ sprintf(tempbuffer, "_changeSaveAllowedState(%s)",
+ popDecomp());
+ pushDecomp(tempbuffer);
+ break;
+ }
+ case 0x29:
+ {
+ pushDecomp("_freeAllPerso()");
+ break;
+ }
+ case 0x2B:
+ {
+ sprintf(tempbuffer, "_getProcIdx(%s,%s)", popDecomp(),
+ popDecomp());
+ pushDecomp(tempbuffer);
+ break;
+ }
+ case 0x2C:
+ {
+ sprintf(tempbuffer, "_setObjectPosition(%s,%s,%s)",
+ popDecomp(), popDecomp(), popDecomp());
+ pushDecomp(tempbuffer);
+ break;
+ }
+ case 0x2E:
+ {
+ sprintf(tempbuffer, "_releaseScript(%s)", popDecomp());
+ pushDecomp(tempbuffer);
+ break;
+ }
+ case 0x2F:
+ {
+ sprintf(tempbuffer, "_addBackgroundIncrust(%s,%s,%s)",
+ popDecomp(), popDecomp(), popDecomp());
+ pushDecomp(tempbuffer);
+ break;
+ }
+ case 0x30:
+ {
+ sprintf(tempbuffer, "_removeBackgroundIncrust(%s,%s)",
+ popDecomp(), popDecomp());
+ pushDecomp(tempbuffer);
+ break;
+ }
+ case 0x31:
+ {
+ sprintf(tempbuffer, "_op_31(%s,%s)", popDecomp(),
+ popDecomp());
+ pushDecomp(tempbuffer);
+ break;
+ }
+ case 0x32:
+ {
+ pushDecomp("_freeBackgroundInscrustList()");
+ break;
+ }
+ case 0x35:
+ {
+ sprintf(tempbuffer, "_op35(%s)", popDecomp());
+ pushDecomp(tempbuffer);
+ break;
+ }
+ case 0x37:
+ {
+ sprintf(tempbuffer, "_op37(%s,%s)", popDecomp(),
+ popDecomp());
+ pushDecomp(tempbuffer);
+ break;
+ }
+ case 0x38:
+ {
+ sprintf(tempbuffer, "_removeBackground(%s)",
+ popDecomp());
+ pushDecomp(tempbuffer);
+ break;
+ }
+ case 0x39:
+ {
+ sprintf(tempbuffer, "_SetActiveBackgroundPlane(%s)",
+ popDecomp());
+ pushDecomp(tempbuffer);
+ break;
+ }
+ case 0x3A:
+ {
+ sprintf(tempbuffer, "_setVar49(%s)", popDecomp());
+ pushDecomp(tempbuffer);
+ break;
+ }
+ case 0x3B:
+ {
+ pushDecomp("_op3B()");
+ break;
+ }
+ case 0x3C:
+ {
+ sprintf(tempbuffer, "_rand(%s)", popDecomp());
+ pushDecomp(tempbuffer);
+ break;
+ }
+ case 0x3D:
+ {
+ sprintf(tempbuffer, "_loadMusic(%s)", popDecomp());
+ pushDecomp(tempbuffer);
+ break;
+ }
+ case 0x3E:
+ {
+ pushDecomp("_op_3E()");
+ break;
+ }
+ case 0x3F:
+ {
+ pushDecomp("_op_3F()");
+ break;
+ }
+ case 0x40:
+ {
+ pushDecomp("_op_40()");
+ break;
+ }
+ case 0x41:
+ {
+ sprintf(tempbuffer, "_isFileLoaded2(%s)", popDecomp());
+ pushDecomp(tempbuffer);
+ break;
+ }
+ case 0x45:
+ {
+ pushDecomp("_stopSound()");
+ break;
+ }
+ case 0x49:
+ {
+ sprintf(tempbuffer, "_op49(%s)", popDecomp());
+ pushDecomp(tempbuffer);
+ break;
+ }
+ case 0x54:
+ {
+ sprintf(tempbuffer, "_setFontVar(%s)", popDecomp());
+ pushDecomp(tempbuffer);
+ break;
+ }
+ case 0x56:
+ {
+ sprintf(tempbuffer, "_changeCutSceneState(%s)",
+ popDecomp());
+ pushDecomp(tempbuffer);
+ break;
+ }
+ case 0x57:
+ {
+ pushDecomp("_getMouseX()");
+ break;
+ }
+ case 0x58:
+ {
+ pushDecomp("_getMouseY()");
+ break;
+ }
+ case 0x59:
+ {
+ pushDecomp("_getMouse3()");
+ break;
+ }
+ case 0x5A:
+ {
+ sprintf(tempbuffer, "_isFileLoaded(%s)", popDecomp());
+ pushDecomp(tempbuffer);
+ break;
+ }
+ case 0x5B:
+ {
+ pushDecomp("_regenerateBackgroundIncrust()");
+ break;
+ }
+ case 0x5C:
+ {
+ sprintf(tempbuffer, "_Op_AddCellC(%s,%s)", popDecomp(),
+ popDecomp());
+ pushDecomp(tempbuffer);
+ break;
+ }
+ case 0x5E:
+ {
+ sprintf(tempbuffer, "_Op_AddCellE(%s)", popDecomp());
+ pushDecomp(tempbuffer);
+ break;
+ }
+ case 0x60:
+ {
+ sprintf(tempbuffer, "_op_60(%s,%s,%s,%s,%s)",
+ popDecomp(), popDecomp(), popDecomp(), popDecomp(),
+ popDecomp());
+ pushDecomp(tempbuffer);
+ break;
+ }
+ case 0x61:
+ {
+ sprintf(tempbuffer, "_op61(%s,%s)", popDecomp(),
+ popDecomp());
+ pushDecomp(tempbuffer);
+ break;
+ }
+ case 0x62:
+ {
+ pushDecomp("_pauseCallingScript()");
+ break;
+ }
+ case 0x63:
+ {
+ pushDecomp("_resumeScript()");
+ break;
+ }
+ case 0x64:
+ {
+ unsigned long int numArg = atoi(popDecomp());
+ char *ovlStr;
+ char *idxStr;
+ int i;
+ char functionName[256];
+
+ idxStr = popDecomp();
+ ovlStr = popDecomp();
+
+ resolveVarName(ovlStr, 0x20, idxStr, functionName);
+
+ sprintf(tempbuffer, "%s(", functionName);
+
+ for (i = 0; i < numArg; i++) {
+ if (i)
+ strcatuint8(tempbuffer, ",");
+ strcatuint8(tempbuffer, popDecomp());
+ }
+
+ strcatuint8(tempbuffer, ")");
+
+ pushDecomp(tempbuffer);
+ break;
+ }
+ case 0x65:
+ {
+ sprintf(tempbuffer,
+ "_addWaitObject(%s,%s,%s,%s,%s,%s,%s,%s,%s,%s)",
+ popDecomp(), popDecomp(), popDecomp(), popDecomp(),
+ popDecomp(), popDecomp(), popDecomp(), popDecomp(),
+ popDecomp(), popDecomp());
+ pushDecomp(tempbuffer);
+ break;
+ }
+ case 0x66:
+ {
+ sprintf(tempbuffer, "_op_66(%s,%s)", popDecomp(),
+ popDecomp());
+ pushDecomp(tempbuffer);
+ break;
+ }
+ case 0x67:
+ {
+ sprintf(tempbuffer, "_loadAudioResource(%s,%s)",
+ popDecomp(), popDecomp());
+ pushDecomp(tempbuffer);
+ break;
+ }
+ case 0x68:
+ {
+ pushDecomp("_freeMediumVar()");
+ break;
+ }
+ case 0x6A:
+ {
+ sprintf(tempbuffer, "_op_6A(%s)", popDecomp());
+ pushDecomp(tempbuffer);
+ break;
+ }
+ case 0x6B:
+ {
+ sprintf(tempbuffer, "_loadData(%s,%s,%s,%s)",
+ popDecomp(), popDecomp(), popDecomp(),
+ popDecomp());
+ pushDecomp(tempbuffer);
+ break;
+ }
+ case 0x6C:
+ {
+ sprintf(tempbuffer, "_op_6C(%s,%s)", popDecomp(),
+ popDecomp());
+ pushDecomp(tempbuffer);
+ break;
+ }
+ case 0x6D:
+ {
+ sprintf(tempbuffer, "_strcpy(%s,%s)", popDecomp(),
+ popDecomp());
+ pushDecomp(tempbuffer);
+ break;
+ }
+ case 0x6E:
+ {
+ sprintf(tempbuffer, "_op_6E(%s,%s)", popDecomp(),
+ popDecomp());
+ pushDecomp(tempbuffer);
+ break;
+ }
+ case 0x6F:
+ {
+ unsigned long int numArg = atoi(popDecomp());
+ char *ovlStr;
+ char *idxStr;
+ int i;
+
+ idxStr = popDecomp();
+ ovlStr = popDecomp();
+
+ sprintf(tempbuffer, "_op_6F(%s,%s", idxStr, ovlStr);
+
+ for (i = 0; i < numArg; i++) {
+ strcatuint8(tempbuffer, ",");
+ strcatuint8(tempbuffer, popDecomp());
+ }
+
+ strcatuint8(tempbuffer, ")");
+
+ pushDecomp(tempbuffer);
+ break;
+ }
+ case 0x70:
+ {
+ sprintf(tempbuffer, "_comment(%s)", popDecomp());
+ pushDecomp(tempbuffer);
+ break;
+ }
+ case 0x71:
+ {
+ sprintf(tempbuffer, "_op71(%s,%s,%s,%s,%s)",
+ popDecomp(), popDecomp(), popDecomp(), popDecomp(),
+ popDecomp());
+ pushDecomp(tempbuffer);
+ break;
+ }
+ case 0x72:
+ {
+ sprintf(tempbuffer, "_op72(%s,%s)", popDecomp(),
+ popDecomp(), popDecomp());
+ pushDecomp(tempbuffer);
+ break;
+ }
+ case 0x73:
+ {
+ sprintf(tempbuffer, "_op73(%s)", popDecomp());
+ pushDecomp(tempbuffer);
+ break;
+ }
+ case 0x74:
+ {
+ sprintf(tempbuffer, "_getInitVar1()");
+ pushDecomp(tempbuffer);
+ break;
+ }
+ case 0x76:
+ {
+ sprintf(tempbuffer, "_Op_InitializeState6(%s,%s)",
+ popDecomp(), popDecomp());
+ pushDecomp(tempbuffer);
+ break;
+ }
+ case 0x77:
+ {
+ sprintf(tempbuffer, "_Op_InitializeState7(%s)",
+ popDecomp());
+ pushDecomp(tempbuffer);
+ break;
+ }
+ case 0x78:
+ {
+ sprintf(tempbuffer, "_Op_InitializeState8(%s)",
+ popDecomp());
+ pushDecomp(tempbuffer);
+ break;
+ }
+ case 0x79:
+ {
+ sprintf(tempbuffer, "_EnterPlayerMenu(%s)",
+ popDecomp());
+ pushDecomp(tempbuffer);
+ break;
+ }
+ case 0x7B:
+ {
+ sprintf(tempbuffer, "_Op_InitializeStateB(%s)",
+ popDecomp());
+ pushDecomp(tempbuffer);
+ break;
+ }
+ case 0x7C:
+ {
+ sprintf(tempbuffer, "_Op_InitializeStateC(%s)",
+ popDecomp());
+ pushDecomp(tempbuffer);
+ break;
+ }
+ case 0x7D:
+ {
+ pushDecomp("_freeAllMenu()");
+ break;
+ }
+ default:
+ {
+ addDecomp("OP_%X", currentScriptOpcodeType);
+ printf("OPCODE: %X\n", currentScriptOpcodeType);
+ failed = 1;
+ break;
+ }
+ }
+
+// pushDecomp("functionDummyPush");
+
+ return (0);
+}
+
+uint8 stop = 0;
+
+int decompStop(void) {
+ stop = 1;
+ addDecomp("stop\n");
+ return 0;
+}
+
+int decompBreak(void) {
+ addDecomp("break");
+ return 0;
+}
+
+void generateIndentation(void) {
+ int i;
+
+ for (i = 0; i < positionInDecompileLineTable; i++) {
+ if (decompileLineTable[i].type != 0) {
+ char *gotoStatement;
+ int destLine;
+ int destLineIdx;
+
+ gotoStatement =
+ strstr(decompileLineTable[i].line, "goto");
+ assert(gotoStatement);
+ gotoStatement = strchr(gotoStatement, ' ') + 1;
+
+ destLine = atoi(gotoStatement);
+
+ {
+ int j;
+
+ destLineIdx = -1;
+
+ for (j = 0; j < positionInDecompileLineTable;
+ j++) {
+ if (decompileLineTable[j].lineOffset ==
+ destLine) {
+ destLineIdx = j;
+ break;
+ }
+ }
+
+ assert(destLineIdx != -1);
+
+ if (destLineIdx > i) {
+ int j;
+
+ for (j = i + 1; j < destLineIdx; j++) {
+ decompileLineTable[j].indent++;
+ }
+
+ if (strstr(decompileLineTable
+ [destLineIdx - 1].line,
+ "goto") ==
+ decompileLineTable[destLineIdx -
+ 1].line) {
+ //decompileLineTable[destLineIdx-1].pendingElse = 1;
+ }
+ }
+ }
+ }
+ }
+}
+
+void dumpScript(uint8 *ovlName, ovlDataStruct *ovlData, int idx) {
+ uint8 opcodeType;
+ char buffer[256];
+ int i;
+
+ char temp[256];
+ char scriptName[256];
+
+ sprintf(temp, "%d", idx);
+
+ failed = 0;
+
+ currentScript = &ovlData->data3Table[idx];
+
+ currentDecompScript = currentScript->dataPtr;
+ currentDecompScriptPtr->var4 = 0;
+
+ currentDecompOvl = ovlData;
+ currentDecompScriptIdx = idx;
+
+ currentLineIdx = 0;
+ positionInDecompileLineTable = 0;
+ currentLineType = 0;
+
+ resolveVarName("0", 0x20, temp, scriptName);
+
+ printf("decompiling script %d - %s\n", idx, scriptName);
+
+ // return;
+
+// scriptDataPtrTable[1] = *(char**)(ptr+0x6);
+ scriptDataPtrTable[2] = getDataFromData3(currentScript, 1); // strings
+ scriptDataPtrTable[5] = ovlData->data4Ptr; // free strings
+ scriptDataPtrTable[6] = ovlData->ptr8;
+
+ stop = 0;
+
+ sprintf(buffer, "%s-%02d-%s.txt", ovlName, idx, scriptName);
+ fHandle = fopen(buffer, "w+");
+
+ decompileStackPosition = 0;
+
+ for (i = 0; i < 64; i++) {
+ decompOpcodeTypeTable[i] = NULL;
+ }
+
+ decompOpcodeTypeTable[1] = decompLoadVar;
+ decompOpcodeTypeTable[2] = decompSaveVar;
+ decompOpcodeTypeTable[3] = decompOpcodeType2;
+ decompOpcodeTypeTable[4] = decompMath;
+ decompOpcodeTypeTable[5] = decompBoolCompare;
+ decompOpcodeTypeTable[6] = decompTest;
+ decompOpcodeTypeTable[7] = decompCompare;
+ decompOpcodeTypeTable[8] = decompSwapStack;
+ decompOpcodeTypeTable[9] = decompFunction;
+ decompOpcodeTypeTable[10] = decompStop;
+ decompOpcodeTypeTable[12] = decompBreak;
+
+ do {
+ currentOffset = currentDecompScriptPtr->var4;
+
+ opcodeType = getByteFromDecompScriptReal();
+
+ currentScriptOpcodeType = opcodeType & 7;
+
+ if (!decompOpcodeTypeTable[(opcodeType & 0xFB) >> 3]) {
+ printf("Unsupported opcode type %d in decomp\n",
+ (opcodeType & 0xFB) >> 3);
+ return;
+ }
+
+ //printf("Optype: %d\n",(opcodeType&0xFB)>>3);
+
+ decompOpcodeTypeTable[(opcodeType & 0xFB) >> 3] ();
+
+ if (failed) {
+ printf("Aborting decompilation..\n");
+ fclose(fHandle);
+ return;
+ }
+
+ } while (!stop);
+
+ dumpIdx++;
+
+ generateIndentation();
+
+ for (i = 0; i < positionInDecompileLineTable; i++) {
+ int j;
+
+ if (decompileLineTable[i].pendingElse) {
+ fprintf(fHandle, "%05d:\t",
+ decompileLineTable[i].lineOffset);
+ fprintf(fHandle, "else", decompileLineTable[i].line);
+ fprintf(fHandle, "\n");
+ }
+
+ fprintf(fHandle, "%05d:\t", decompileLineTable[i].lineOffset);
+ for (j = 0; j < decompileLineTable[i].indent; j++) {
+ fprintf(fHandle, "\t");
+ }
+ fprintf(fHandle, "%s", decompileLineTable[i].line);
+ fprintf(fHandle, "\n");
+ }
+
+ fclose(fHandle);
+}
+
+#endif
+
+} // End of namespace Cruise