diff options
author | David Corrales | 2007-05-26 20:23:24 +0000 |
---|---|---|
committer | David Corrales | 2007-05-26 20:23:24 +0000 |
commit | 3646c968c9578c2a94d65ebd5fb06ec835f8c51d (patch) | |
tree | 8b57b339ebb31a1d7a67f1678aa5dc5c7759070a /engines/cruise/decompiler.cpp | |
parent | d1f56d93f934150f4b579c2e90564e2bf035f113 (diff) | |
parent | ac45c5b33d834acbc9718f89be76e49d403a4d2c (diff) | |
download | scummvm-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.cpp | 1598 |
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 |