Logo Search packages:      
Sourcecode: scummvm version File versions

script.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-13-1/engines/cruise/script.cpp $
 * $Id: script.cpp 35870 2009-01-16 02:43:41Z fingolfin $
 *
 */

#include "cruise/cruise_main.h"

namespace Cruise {

scriptInstanceStruct relHead;
scriptInstanceStruct procHead;

scriptInstanceStruct *currentScriptPtr;

int8 getByteFromScript(void) {
      int8 var = *(int8*)(currentData3DataPtr + currentScriptPtr->var4);

      currentScriptPtr->var4 = currentScriptPtr->var4 + 1;

      return (var);
}

short int getShortFromScript(void) {
      short int var = *(int16 *)(currentData3DataPtr + currentScriptPtr->var4);

      currentScriptPtr->var4 = currentScriptPtr->var4 + 2;

      flipShort(&var);

      return (var);
}

// load opcode
int32 opcodeType0(void) {
      int index = 0;

      switch (currentScriptOpcodeType) {
      case 0: {
            pushVar(getShortFromScript());
            return (0);
      }
      case 5:
            index = saveOpcodeVar;
      case 1: {
            uint8 *address = 0;
            int type = getByteFromScript();
            int ovl = getByteFromScript();
            short int offset = getShortFromScript();
            offset += index;

            int typ7 = type & 7;

            if (!typ7) {
                  return (-10); // unresloved link
            }

            if (!ovl) {
                  address = scriptDataPtrTable[typ7];
            } else      { // TODO:
                  if (!overlayTable[ovl].alreadyLoaded) {
                        return (-7);
                  }

                  if (!overlayTable[ovl].ovlData) {
                        return (-4);
                  }

                  if (typ7 == 5) {
                        address = overlayTable[ovl].ovlData->data4Ptr;
                  } else {
                        assert(0);
                  }
            }

            address += offset;

            int size = (type >> 3) & 3;

            if (size == 1) {
                  address += index;
                  pushVar(loadShort(address));
                  return (0);
            } else if (size == 2) {
                  pushVar(*address);
                  return (0);
            } else {
                  printf("Unsupported code in opcodeType0 case 1!\n");
                  exit(1);
            }

            return (0);
      }
      case 2: {
            int16 var_16;
            int di = getByteFromScript();
            int si = getByteFromScript();
            int var_2 = getShortFromScript();

            if (!si) {
                  si = currentScriptPtr->overlayNumber;
            }

            if (getSingleObjectParam(si, var_2, di, &var_16)) {
                  return -10;
            }

            pushVar(var_16);
            return (0);

            break;
      }
      default: {
            printf("Unsupported type %d in opcodeType0\n",
                   currentScriptOpcodeType);
            exit(1);
      }
      }

      return 0;
}

// save opcode
int32 opcodeType1(void) {
      int var = popVar();
      int offset = 0;

      switch (currentScriptOpcodeType) {
      case 0: {
            return (0); // strange, but happens also in original interpreter
      }
      case 5: {
            offset = saveOpcodeVar;
      }
      case 1: {
            int var_A = 0;

            int byte1 = getByteFromScript();
            int byte2 = getByteFromScript();

            int short1 = getShortFromScript();

            int var_6 = byte1 & 7;

            int var_C = short1;

            uint8 *ptr = 0;
            int type2;

            if (!var_6)
                  return (-10);

            var_C = short1;

            if (byte2) {
                  if (!overlayTable[byte2].alreadyLoaded) {
                        return (-7);
                  }

                  if (!overlayTable[byte2].ovlData) {
                        return (-4);
                  }

                  if (var_6 == 5) {
                        ptr = overlayTable[byte2].ovlData->data4Ptr + var_C;
                  } else {
                        ASSERT(0);
                  }
            } else {
                  ptr = scriptDataPtrTable[var_6] + var_C;
            }

            type2 = ((byte1 & 0x18) >> 3);

            switch (type2) {
            case 1: {
                  saveShort(ptr + var_A + offset * 2, var);
                  return 0;
            }
            case 2: {
                  *(ptr + var_A + offset) = var;
                  return (0);
            }
            default: {
                  printf("Unsupported code in opcodeType1 case 1!\n");
                  exit(1);
            }
            }

            break;
      }
      case 2: {
            int mode = getByteFromScript();
            int di = getByteFromScript();
            int var_4 = getShortFromScript();

            if (!di) {
                  di = currentScriptPtr->overlayNumber;
            }

            if ((var == 0x85) && !strcmp((char*)currentCtpName, "S26.CTP") && !di && mode == 1) { // patch in bar
                  var = 0x87;
            }

            setObjectPosition(di, var_4, mode, var);

            break;
      }
      case 4: {
            saveOpcodeVar = var;
            break;
      }
      default: {
            printf("Unsupported type %d in opcodeType1\n",
                   currentScriptOpcodeType);
            exit(1);
      }
      }

      return (0);
}

int32 opcodeType2(void) {
      int index = 0;
      switch (currentScriptOpcodeType) {
      case 5:
            index = saveOpcodeVar;
      case 1: {
            uint8* adresse = NULL;
            int type = getByteFromScript();
            int overlay = getByteFromScript();

            int firstOffset;
            int offset;
            firstOffset = offset = getShortFromScript();
            offset += index;

            int typ7 = type & 7;
            if (!typ7) {
                  return (-10);
            }
            if (!overlay) {
                  adresse = scriptDataPtrTable[typ7];
            } else {
                  if (!overlayTable[overlay].alreadyLoaded) {
                        return (-7);
                  }
                  if (!overlayTable[overlay].ovlData) {
                        return (-4);
                  }
                  ASSERT(0);
            }

            adresse += offset;
            int size = (type >> 3) & 3;

            if (size == 1) {
                  adresse += index;
                  pushPtr(adresse);
            } else if (size == 2) {
                  pushPtr(adresse);
            }

      }
      }

      return 0;
}

int32 opcodeType10(void) {    // break
      return (0);
}

int32 opcodeType11(void) {    // break
      return (1);
}

int32 opcodeType4(void) {           // test
      int boolVar = 0;

      int var1 = popVar();
      int var2 = popVar();

      switch (currentScriptOpcodeType) {
      case 0: {
            if (var2 != var1)
                  boolVar = 1;
            break;
      }
      case 1: {
            if (var2 == var1)
                  boolVar = 1;
            break;
      }
      case 2: {
            if (var2 < var1)
                  boolVar = 1;
            break;
      }
      case 3: {
            if (var2 <= var1)
                  boolVar = 1;
            break;
      }
      case 4: {
            if (var2 > var1)
                  boolVar = 1;
            break;
      }
      case 5: {
            if (var2 >= var1)
                  boolVar = 1;
            break;
      }

      }

      pushVar(boolVar);

      return (0);
}

int32 opcodeType6(void) {
      int si = 0;

      int pop = popVar();

      if (!pop)
            si = 1;

      if (pop < 0) {
            si |= 4;
      }

      if (pop > 0) {
            si |= 2;
      }

      currentScriptPtr->ccr = si;

      return (0);
}

int32 opcodeType7(void) {
      int var1 = popVar();
      int var2 = popVar();

      pushVar(var1);
      pushVar(var2);

      return (0);
}

int32 opcodeType5(void) {
      int offset = currentScriptPtr->var4;
      int short1 = getShortFromScript();
      int newSi = short1 + offset;
      int bitMask = currentScriptPtr->ccr;

      switch (currentScriptOpcodeType) {
      case 0: {
            if (!(bitMask & 1)) {
                  currentScriptPtr->var4 = newSi;
            }
            break;
      }
      case 1: {
            if (bitMask & 1) {
                  currentScriptPtr->var4 = newSi;
            }
            break;
      }
      case 2: {
            if (bitMask & 2) {
                  currentScriptPtr->var4 = newSi;
            }
            break;
      }
      case 3: {
            if (bitMask & 3) {
                  currentScriptPtr->var4 = newSi;
            }
            break;
      }
      case 4: {
            if (bitMask & 4) {
                  currentScriptPtr->var4 = newSi;
            }
            break;
      }
      case 5: {
            if (bitMask & 5) {
                  currentScriptPtr->var4 = newSi;
            }
            break;
      }
      case 6: {
            break;      // never
      }
      case 7: {
            currentScriptPtr->var4 = newSi;     //always
            break;
      }
      }

      return (0);
}

int32 opcodeType3(void) {     // math
      int pop1 = popVar();
      int pop2 = popVar();

      switch (currentScriptOpcodeType) {
      case 0: {
            pushVar(pop1 + pop2);
            return (0);
      }
      case 1: {
            pushVar(pop1 / pop2);
            return (0);
      }
      case 2: {
            pushVar(pop1 - pop2);
            return (0);
      }
      case 3: {
            pushVar(pop1 * pop2);
            return (0);
      }
      case 4: {
            pushVar(pop1 % pop2);
            return (0);
      }
      case 7:
      case 5: {
            pushVar(pop2 | pop1);
            return (0);
      }
      case 6: {
            pushVar(pop2 & pop1);
            return (0);
      }
      }

      return 0;
}

int32 opcodeType9(void) {           // stop script
      //printf("Stop a script of overlay %s\n",overlayTable[currentScriptPtr->overlayNumber].overlayName);
      currentScriptPtr->scriptNumber = -1;
      return (1);
}

void setupFuncArray() {
      int i;

      for (i = 0; i < 64; i++) {
            opcodeTypeTable[i] = NULL;
      }

      opcodeTypeTable[1] = opcodeType0;
      opcodeTypeTable[2] = opcodeType1;
      opcodeTypeTable[3] = opcodeType2;
      opcodeTypeTable[4] = opcodeType3;
      opcodeTypeTable[5] = opcodeType4;
      opcodeTypeTable[6] = opcodeType5;
      opcodeTypeTable[7] = opcodeType6;
      opcodeTypeTable[8] = opcodeType7;
      opcodeTypeTable[9] = opcodeType8;
      opcodeTypeTable[10] = opcodeType9;
      opcodeTypeTable[11] = opcodeType10;
      opcodeTypeTable[12] = opcodeType11;
}

int removeScript(int overlay, int idx, scriptInstanceStruct *headPtr) {
      scriptInstanceStruct *scriptPtr;

      scriptPtr = headPtr->nextScriptPtr;

      if (scriptPtr) {
            do {
                  if (scriptPtr->overlayNumber == overlay
                          && (scriptPtr->scriptNumber == idx || idx == -1)) {
                        scriptPtr->scriptNumber = -1;
                  }

                  scriptPtr = scriptPtr->nextScriptPtr;
            } while (scriptPtr);
      }

      return (0);
}

uint8 *attacheNewScriptToTail(scriptInstanceStruct *scriptHandlePtr, int16 overlayNumber, int16 param, int16 arg0, int16 arg1, int16 arg2, scriptTypeEnum scriptType) {
      int useArg3Neg = 0;
      ovlData3Struct *data3Ptr;
      scriptInstanceStruct *tempPtr;
      int var_C;
      scriptInstanceStruct *oldTail;

      //printf("Starting script %d of overlay %s\n",param,overlayTable[overlayNumber].overlayName);

      if (scriptType < 0) {
            useArg3Neg = 1;
            scriptType = (scriptTypeEnum) - scriptType;
      }

      if (scriptType == 20) {
            data3Ptr = getOvlData3Entry(overlayNumber, param);
      } else {
            if (scriptType == 30) {
                  data3Ptr = scriptFunc1Sub2(overlayNumber, param);
            } else {
                  return (NULL);
            }
      }

      if (!data3Ptr) {
            return (NULL);
      }

      if (!data3Ptr->dataPtr) {
            return (NULL);
      }

      var_C = data3Ptr->sysKey;

      oldTail = scriptHandlePtr;

      while (oldTail->nextScriptPtr) {    // go to the end of the list
            oldTail = oldTail->nextScriptPtr;
      }

      tempPtr =
          (scriptInstanceStruct *)
          mallocAndZero(sizeof(scriptInstanceStruct));

      if (!tempPtr)
            return (NULL);

      tempPtr->var6 = NULL;

      if (var_C) {
            tempPtr->var6 = (uint8 *) mallocAndZero(var_C);
      }

      tempPtr->varA = var_C;
      tempPtr->nextScriptPtr = NULL;
      tempPtr->var4 = 0;

      tempPtr->scriptNumber = param;
      tempPtr->overlayNumber = overlayNumber;

      if (scriptType == 20) { // Obj or not ?
            tempPtr->sysKey = useArg3Neg;
      } else {
            tempPtr->sysKey = 1;
      }

      tempPtr->freeze = 0;
      tempPtr->type = scriptType;
      tempPtr->var18 = arg2;
      tempPtr->var16 = arg1;
      tempPtr->var1A = arg0;
      tempPtr->nextScriptPtr = oldTail->nextScriptPtr;      // should always be NULL as it's the tail

      oldTail->nextScriptPtr = tempPtr;   // attache the new node to the list

      return (tempPtr->var6);
}

int executeScripts(scriptInstanceStruct *ptr) {
      int numScript2;
      ovlData3Struct *ptr2;
      ovlDataStruct *ovlData;
      uint8 opcodeType;

      numScript2 = ptr->scriptNumber;

      if (ptr->type == 20) {
            ptr2 = getOvlData3Entry(ptr->overlayNumber, numScript2);

            if (!ptr2) {
                  return (-4);
            }
      } else {
            if (ptr->type == 30) {
                  ptr2 = scriptFunc1Sub2(ptr->overlayNumber, numScript2);

                  if (!ptr2) {
                        return (-4);
                  }
            } else {
                  return (-6);
            }
      }

      if (!overlayTable[ptr->overlayNumber].alreadyLoaded) {
            return (-7);
      }

      ovlData = overlayTable[ptr->overlayNumber].ovlData;

      if (!ovlData)
            return (-4);

      currentData3DataPtr = ptr2->dataPtr;

      scriptDataPtrTable[1] = (uint8 *) ptr->var6;
      scriptDataPtrTable[2] = getDataFromData3(ptr2, 1);
      scriptDataPtrTable[5] = ovlData->data4Ptr;      // free strings
      scriptDataPtrTable[6] = ovlData->ptr8;

      currentScriptPtr = ptr;

      positionInStack = 0;

      do {
            if (currentScriptPtr->var4 == 290
                    && currentScriptPtr->overlayNumber == 4
                    && currentScriptPtr->scriptNumber == 0) {
                  currentScriptPtr->var4 = 923;
            }
            opcodeType = getByteFromScript();

            //    printf("opType: %d\n",(opcodeType&0xFB)>>3);

            currentScriptOpcodeType = opcodeType & 7;

            if (!opcodeTypeTable[(opcodeType & 0xFB) >> 3]) {
                  printf("Unsupported opcode type %d\n", (opcodeType & 0xFB) >> 3);
                  exit(1);
                  return (-21);
            }
      } while (!opcodeTypeTable[(opcodeType & 0xFB) >> 3]());

      currentScriptPtr = NULL;

      return (0);
}

void manageScripts(scriptInstanceStruct *scriptHandle) {
      scriptInstanceStruct *ptr = scriptHandle;

      if (ptr) {
            do {
                  if (!overlayTable[ptr->overlayNumber].executeScripts) {
                        if ((ptr->scriptNumber != -1) && (ptr->freeze == 0) && (ptr->sysKey != 0)) {
                              executeScripts(ptr);
                        }

                        if (ptr->sysKey == 0) {
                              ptr->sysKey = 1;
                        }
                  }

                  ptr = ptr->nextScriptPtr;

            } while (ptr);
      }
}

} // End of namespace Cruise

Generated by  Doxygen 1.6.0   Back to index