aboutsummaryrefslogtreecommitdiff
path: root/engines/cruise/decompiler.cpp
diff options
context:
space:
mode:
authorVincent Hamm2007-04-27 12:58:35 +0000
committerVincent Hamm2007-04-27 12:58:35 +0000
commitc01aa37caaadb2e65667b1156a907e92e859fee8 (patch)
tree5c55328c78f6f1664f4f46baadee583fcff977ef /engines/cruise/decompiler.cpp
parentedd9b31a483c07066537663a01c265d99d69ada7 (diff)
downloadscummvm-rg350-c01aa37caaadb2e65667b1156a907e92e859fee8.tar.gz
scummvm-rg350-c01aa37caaadb2e65667b1156a907e92e859fee8.tar.bz2
scummvm-rg350-c01aa37caaadb2e65667b1156a907e92e859fee8.zip
Add cruise source code for scummvm
svn-id: r26605
Diffstat (limited to 'engines/cruise/decompiler.cpp')
-rw-r--r--engines/cruise/decompiler.cpp1549
1 files changed, 1549 insertions, 0 deletions
diff --git a/engines/cruise/decompiler.cpp b/engines/cruise/decompiler.cpp
new file mode 100644
index 0000000000..bb0c4af816
--- /dev/null
+++ b/engines/cruise/decompiler.cpp
@@ -0,0 +1,1549 @@
+/* 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 {
+
+#include <stdarg.h>
+
+#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,"_addObject(%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,"_removeObjectFromList(%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_16(%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_18(%s,%s,%s,%s,%s,%s,%s)",popDecomp(),popDecomp(),popDecomp(),popDecomp(),popDecomp(),popDecomp(),popDecomp());
+ pushDecomp(tempbuffer);
+ break;
+ }
+ case 0x19:
+ {
+ sprintf(tempbuffer,"_op_19(%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_5C(%s,%s)",popDecomp(),popDecomp());
+ pushDecomp(tempbuffer);
+ break;
+ }
+ case 0x5E:
+ {
+ sprintf(tempbuffer,"_op_5E(%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_76(%s,%s)",popDecomp(),popDecomp());
+ pushDecomp(tempbuffer);
+ break;
+ }
+ case 0x77:
+ {
+ sprintf(tempbuffer,"_op_77(%s)",popDecomp());
+ pushDecomp(tempbuffer);
+ break;
+ }
+ case 0x78:
+ {
+ sprintf(tempbuffer,"_op_78(%s)",popDecomp());
+ pushDecomp(tempbuffer);
+ break;
+ }
+ case 0x79:
+ {
+ sprintf(tempbuffer,"_EnterPlayerMenu(%s)",popDecomp());
+ pushDecomp(tempbuffer);
+ break;
+ }
+ case 0x7B:
+ {
+ sprintf(tempbuffer,"_op_7B(%s)",popDecomp());
+ pushDecomp(tempbuffer);
+ break;
+ }
+ case 0x7C:
+ {
+ sprintf(tempbuffer,"_op_7C(%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
+