Logo Search packages:      
Sourcecode: scummvm version File versions  Download package

decompiler.cpp

/* ScummVM - Graphic Adventure Engine
 *
 * ScummVM is the legal property of its developers, whose names
 * are too numerous to list here. Please refer to the COPYRIGHT
 * file distributed with this source distribution.
 *
 * 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: https://scummvm.svn.sourceforge.net/svnroot/scummvm/scummvm/tags/release-0-11-1/engines/cruise/decompiler.cpp $
 * $Id: decompiler.cpp 30944 2008-02-23 22:50:18Z sev $
 *
 */

#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->numRelocGlob; 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->numRelocGlob; 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->numSymbGlob; i++) {
                  if (varIdx == currentDecompOvl->arraySymbGlob[i].idx) {
                        if (((currentDecompOvl->arraySymbGlob[i].var4 & 0xF0) == 0) && varType != 0x20) {   // var
                              strcpy(outputName,
                                  currentDecompOvl->arrayNameSymbGlob +
                                  currentDecompOvl->arraySymbGlob[i].
                                  offsetToName);
                              return;
                        }
                        if ((currentDecompOvl->arraySymbGlob[i].var4) == 20 && varType == 0x20) {     // script
                              strcpy(outputName,
                                  currentDecompOvl->arrayNameSymbGlob +
                                  currentDecompOvl->arraySymbGlob[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();

      strcpy(buffer1, stack1);
      strcpy(buffer2, stack2);

      pushDecomp(buffer1);
      pushDecomp(buffer2);

      return 0;
}

int decompFunction(void) {
      currentScriptOpcodeType = getByteFromDecompScriptReal();
//    addDecomp("OP_%X", currentScriptOpcodeType);
      switch (currentScriptOpcodeType) {
      case 0x1:
            {
                  pushDecomp("_setdoFade()");
                  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_TrackAnim(%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, "_getlowMemory()");
                  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, j;

      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);
                  destLineIdx = -1;

                  for (j = 0; j < positionInDecompileLineTable; j++) {
                        if (decompileLineTable[j].lineOffset == destLine) {
                              destLineIdx = j;
                              break;
                        }
                  }

                  assert(destLineIdx != -1);

                  if (destLineIdx > i) {
                        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->arrayProc[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

Generated by  Doxygen 1.6.0   Back to index