Logo Search packages:      
Sourcecode: scummvm version File versions

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

#include "cruise/cruise.h"
#include "cruise/cruise_main.h"
#include "cruise/cell.h"
#include "common/util.h"

namespace Cruise {

//#define FUNCTION_DEBUG

int16 Op_LoadOverlay(void) {
      char *pOverlayName;
      char overlayName[38] = "";
      int overlayLoadResult;

      pOverlayName = (char *) popPtr();

      if (strlen(pOverlayName) == 0)
            return 0;

      strcpy(overlayName, pOverlayName);
      strToUpper(overlayName);

      //gfxModuleData.field_84();
      //gfxModuleData.field_84();

      overlayLoadResult = loadOverlay(overlayName);

      updateAllScriptsImports();

      strcpy(nextOverlay, overlayName);

      return(overlayLoadResult);
}

int16 Op_Strcpy(void) {
      char *ptr1 = (char *)popPtr();
      char *ptr2 = (char *)popPtr();

      //printf("strcpy %s\n",ptr1);

      while (*ptr1) {
            *ptr2 = *ptr1;

            ptr2++;
            ptr1++;
      }

      *ptr2 = 0;

      return (0);
}

int16 Op_Exec(void) {
      int scriptIdx;
      int ovlIdx;
      uint8 *ptr;
      uint8 *ptr2;

      short int popTable[256];      // TODO: check original size;

      int numOfArgToPop = popVar();

      int i = 0;

      for (i = 0; i < numOfArgToPop; i++) {
            popTable[numOfArgToPop - i - 1] = popVar();
      }

      scriptIdx = popVar();
      ovlIdx = popVar();

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

      ptr = attacheNewScriptToTail(&procHead, ovlIdx, scriptIdx, currentScriptPtr->type, currentScriptPtr->scriptNumber, currentScriptPtr->overlayNumber, scriptType_MinusPROC);

      if (!ptr)
            return (0);

      if (numOfArgToPop <= 0) {
            return (0);
      }

      ptr2 = ptr;

      for (i = 0; i < numOfArgToPop; i++) {
            saveShort(ptr2, popTable[i]);
            ptr2 += 2;
      }

      return (0);
}

int16 Op_AddProc(void) {
      int pop1 = popVar();
      int pop2;
      int overlay;
      int param[160];

      for (long int i = 0; i < pop1; i++) {
            param[i] = popVar();
      }

      pop2 = popVar();
      overlay = popVar();

      if (!overlay)
            overlay = currentScriptPtr->overlayNumber;

      if (!overlay)
            return (0);

      uint8* procBss = attacheNewScriptToTail(&procHead, overlay, pop2, currentScriptPtr->type, currentScriptPtr->scriptNumber, currentScriptPtr->overlayNumber, scriptType_PROC);

      if (procBss) {
            for (long int i = 0; i < pop1; i++) {
                  int16* ptr = (int16*)(procBss + i * 2);
                  *ptr = param[i];
                  flipShort(ptr);
            }
      }

      return (0);
}

int16 Op_Narrator(void) {
      int pop1 = popVar();
      int pop2 = popVar();

      if (!pop2)
            pop2 = currentScriptPtr->overlayNumber;

      narratorOvl = pop2;
      narratorIdx = pop1;

      return (0);
}

int16 Op_GetMouseX(void) {    // TODO: implement properly
      int16 dummy;
      int16 mouseX;
      int16 mouseY;
      int16 mouseButton;

      getMouseStatus(&dummy, &mouseX, &mouseButton, &mouseY);

      return (mouseX);
}

int16 Op_GetMouseY(void) {    // TODO: implement properly
      int16 dummy;
      int16 mouseX;
      int16 mouseY;
      int16 mouseButton;

      getMouseStatus(&dummy, &mouseX, &mouseButton, &mouseY);

      return (mouseY);
}

int16 Op_Random(void) {       // TODO: implement
      int var = popVar();

      if (var < 2) {
            return (0);
      }

      return (g_cruise->_rnd.getRandomNumber(var - 1));
}

int16 Op_PlayFX(void) {       // TODO: implement
      popVar();
      popVar();
      popVar();
      popVar();

      // printf("Op_PlayFX, implement (sound related)\n");

      return (0);
}

int16 Op_FreeCT(void) {
      freeCTP();
      return (0);
}

void freeObjectList(cellStruct *pListHead) {
      int var_2 = 0;
      cellStruct *pCurrent = pListHead->next;

      while (pCurrent) {
            cellStruct *pNext = pCurrent->next;

            if (pCurrent->freeze == 0) {
                  free(pCurrent->gfxPtr);
                  free(pCurrent);
            }

            var_2 = 1;

            pCurrent = pNext;
      }

      if (var_2) {
            resetPtr(pListHead);
      }
}

int16 Op_FreeCell(void) {
      freeObjectList(&cellHead);
      return (0);
}

int16 Op_freeBackgroundInscrustList(void) {
      freeBackgroundIncrustList(&backgroundIncrustHead);
      return (0);
}


int16 Op_UnmergeBackgroundIncrust(void) {
      int obj = popVar();
      int ovl = popVar();

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

      unmergeBackgroundIncrust(&backgroundIncrustHead, ovl, obj);

      return (0);
}

int16 Op_FreePreload(void) {
      // TODO: implement
      printf("Op_FreePreload, implement\n");
      return (0);
}

int16 Op_RemoveMessage(void) {
      int idx;
      int overlay;

      idx = popVar();
      overlay = popVar();

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

      removeCell(&cellHead, overlay, idx, 5, masterScreen);

      return (0);
}

int16 Op_FindSet(void) {
      int16 i;
      char name[36] = "";
      char *ptr;

      ptr = (char *) popPtr();

      if (!ptr) {
            return -1;
      }

      strcpy(name, ptr);
      strToUpper(name);

      for (i = 0; i < 257; i++) {
            if (!strcmp(name, filesDatabase[i].subData.name)) {
                  return (i);
            }
      }

      return -1;
}

int16 Op_RemoveFrame(void) {
      int var1 = popVar();
      int var2 = popVar();

      resetFileEntryRange(var2, var1);

      return (0);
}

int16 Op_comment(void) {
      char *var;

      var = (char *)popPtr();

      printf("COMMENT: \"%s\"\n", var);

      return (0);
}

int16 Op_RemoveProc(void) {
      int idx;
      int overlay;

      idx = popVar();
      overlay = popVar();

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

      removeScript(overlay, idx, &procHead);

      return (0);
}

int16 Op_FreeOverlay(void) {
      char localName[36] = "";
      char *namePtr;

      namePtr = (char *) popPtr();

      strcpy(localName, namePtr);

      if (localName[0]) {
            strToUpper(localName);
            releaseOverlay((char *)localName);
      }

      return 0;
}

int16 Op_FindProc(void) {
      char name[36] = "";
      char *ptr;
      int param;

      ptr = (char *)popPtr();

      strcpy(name, ptr);

      param = getProcParam(popVar(), 20, name);

      return param;
}

int16 Op_KillMenu(void) {
      // TODO: implement
      printf("Op_KillMenu, implement\n");

      return 0;
}

int16 Op_UserMenu(void) {
      int oldValue = entrerMenuJoueur;
      entrerMenuJoueur = popVar();

      return oldValue;
}

int16 Op_UserOn(void) {
      int oldValue = userEnabled;
      int newValue = popVar();

      if (newValue != -1) {
            userEnabled = newValue;
      }

      return oldValue;
}

int16 Op_Display(void) {
      int oldValue = displayOn;
      int newValue = popVar();

      if (newValue != -1) {
            displayOn = newValue;
      }

      return oldValue;
}

int16 Op_FreezeParent(void) {
      if (currentScriptPtr->var1A == 20) {
            changeScriptParamInList(currentScriptPtr->var18, currentScriptPtr->var16, &procHead, -1, 9997);
      } else if (currentScriptPtr->var1A == 30) {
            changeScriptParamInList(currentScriptPtr->var18, currentScriptPtr->var16, &relHead, -1, 9997);
      }

      return 0;
}

int16 Op_LoadBackground(void) {
      int result = 0;
      char bgName[36] = "";
      char *ptr;
      int bgIdx;

      ptr = (char *) popPtr();

      strcpy(bgName, ptr);

      bgIdx = popVar();

      if (bgIdx >= 0 || bgIdx < 8) {
            strToUpper(bgName);

            gfxModuleData_gfxWaitVSync();
            gfxModuleData_gfxWaitVSync();

            result = loadBackground(bgName, bgIdx);
      }

      changeCursor(CURSOR_NORMAL);

      return result;
}

int16 Op_FrameExist(void) {
      int param;

      param = popVar();

      if (param < 0 || param > 255) {
            return 0;
      }

      if (filesDatabase[param].subData.ptr) {
            return 1;
      }

      return 0;
}

int16 Op_LoadFrame(void) {
      int param1;
      int param2;
      int param3;
      char name[36] = "";
      char *ptr;

      ptr = (char *) popPtr();

      strcpy(name, ptr);

      param1 = popVar();
      param2 = popVar();
      param3 = popVar();

      if (param3 >= 0 || param3 < 257) {
            strToUpper(name);

            gfxModuleData_gfxWaitVSync();
            gfxModuleData_gfxWaitVSync();

            lastAni[0] = 0;

            loadFileRange(name, param2, param3, param1);

            lastAni[0] = 0;
      }

      changeCursor(CURSOR_NORMAL);
      return 0;
}

int16 Op_LoadAbs(void) {
      int param1;
//  int param2;
//  int param3;
      char name[36] = "";
      char *ptr;
      int result = 0;

      ptr = (char *) popPtr();

      strcpy(name, ptr);

      param1 = popVar();

      if (param1 >= 0 || param1 < 257) {
            strToUpper(name);

            gfxModuleData_gfxWaitVSync();
            gfxModuleData_gfxWaitVSync();

            result = loadFullBundle(name, param1);
      }

      changeCursor(CURSOR_NORMAL);
      return result;
}

int16 Op_InitializeState(void) {
      int param1 = popVar();
      int objIdx = popVar();
      int ovlIdx = popVar();

      if (!ovlIdx)
            ovlIdx = currentScriptPtr->overlayNumber;

#ifdef FUNCTION_DEBUG
      printf("Init %s state to %d\n", getObjectName(objIdx, overlayTable[ovlIdx].ovlData->arrayNameObj), param1);
#endif

      objInit(ovlIdx, objIdx, param1);

      return (0);
}

int16 Op_GetlowMemory(void) {
      return lowMemory;
}

int16 Op_FadeOut(void) {
      for (long int i = 0; i < 256; i += 32) {
            for (long int j = 0; j < 256; j++) {
                  int offsetTable[3];
                  offsetTable[0] = -32;
                  offsetTable[1] = -32;
                  offsetTable[2] = -32;
                  calcRGB(&workpal[3*j], &workpal[3*j], offsetTable);
            }
            gfxModuleData_setPal256(workpal);
            gfxModuleData_flipScreen();
      }

      memset(globalScreen, 0, 320 * 200);
      flip();

      fadeFlag = 1;
      PCFadeFlag = 1;

      return 0;
}

int16 isOverlayLoaded(const char * name) {
      int16 i;

      for (i = 1; i < numOfLoadedOverlay; i++) {
            if (!strcmp(overlayTable[i].overlayName, name) && overlayTable[i].alreadyLoaded) {
                  return i;
            }
      }

      return 0;
}

int16 Op_FindOverlay(void) {
      char name[36] = "";
      char *ptr;

      ptr = (char *) popPtr();

      strcpy(name, ptr);
      strToUpper(name);

      return (isOverlayLoaded(name));
}

int16 Op_WriteObject(void) {
      int16 returnParam;

      int16 param1 = popVar();
      int16 param2 = popVar();
      int16 param3 = popVar();
      int16 param4 = popVar();

      getSingleObjectParam(param4, param3, param2, &returnParam);
      setObjectPosition(param4, param3, param2, param1);

      return returnParam;
}

int16 Op_ReadObject(void) {
      int16 returnParam;

      int member = popVar();
      int obj = popVar();
      int ovl = popVar();

      getSingleObjectParam(ovl, obj, member, &returnParam);

      return returnParam;
}

int16 Op_FadeIn(void) {
      doFade = 1;
      return 0;
}

int16 Op_GetMouseButton(void) {
      int16 dummy;
      int16 mouseX;
      int16 mouseY;
      int16 mouseButton;

      getMouseStatus(&dummy, &mouseX, &mouseButton, &mouseY);

      if (mouseButton)
            return 1;
      return 0;
}

int16 Op_AddCell(void) {
      int16 objType = popVar();
      int16 objIdx = popVar();
      int16 overlayIdx = popVar();

      if (!overlayIdx)
            overlayIdx = currentScriptPtr->overlayNumber;

      addCell(&cellHead, overlayIdx, objIdx, objType, masterScreen, currentScriptPtr->overlayNumber, currentScriptPtr->scriptNumber, currentScriptPtr->type);

      return 0;
}

int16 Op_AddBackgroundIncrust(void) {

      int16 objType = popVar();
      int16 objIdx = popVar();
      int16 overlayIdx = popVar();

      if (!overlayIdx)
            overlayIdx = currentScriptPtr->overlayNumber;

      addBackgroundIncrust(overlayIdx, objIdx, &backgroundIncrustHead, currentScriptPtr->scriptNumber, currentScriptPtr->overlayNumber, masterScreen, objType);

      return 0;
}

int16 Op_RemoveCell(void) {
      int objType = popVar();
      int objectIdx = popVar();
      int ovlNumber = popVar();

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

      removeCell(&cellHead, ovlNumber, objectIdx, objType, masterScreen);

      return 0;
}

int16 fontFileIndex;

int16 Op_SetFont(void) {
      fontFileIndex = popVar();

      return 0;
}

int16 Op_UnfreezeParent(void) {
      if (currentScriptPtr->var1A == 0x14) {
            changeScriptParamInList(currentScriptPtr->var18, currentScriptPtr->var16, &procHead, -1, 0);
      } else if (currentScriptPtr->var1A == 0x1E) {
            changeScriptParamInList(currentScriptPtr->var18, currentScriptPtr->var16, &relHead, -1, 0);
      }

      return 0;
}

int16 protectionCode = 0;

int16 Op_ProtectionFlag(void) {
      int16 temp = protectionCode;
      int16 newVar;

      newVar = popVar();
      if (newVar != -1) {
            protectionCode = newVar;
      }
      return temp;
}

int16 Op_AddMessage(void) {
      int16 color = popVar();
      int16 var_2 = popVar();
      int16 var_4 = popVar();
      int16 var_6 = popVar();
      int16 var_8 = popVar();
      int16 overlayIdx = popVar();

      if (!overlayIdx)
            overlayIdx = currentScriptPtr->overlayNumber;

      if (color == -1) {
            color = findHighColor();
      } else {
            if (CVTLoaded) {
                  color = cvtPalette[color];
            }
      }

      createTextObject(&cellHead, overlayIdx, var_8, var_6, var_4, var_2, color, masterScreen, currentScriptPtr->overlayNumber, currentScriptPtr->scriptNumber);

      return 0;
}

int16 Op_Preload(void) {
      popPtr();
      popVar();

      return 0;
}

int16 Op_LoadCt(void) {
      return initCt((char*)popPtr());
}

int16 Op_LoadSong(void) {
      popPtr();
      return 0;
}

int16 Op_EndAnim(void) {
      int param1 = popVar();
      int param2 = popVar();
      int overlay = popVar();

      if (!overlay)
            overlay = currentScriptPtr->overlayNumber;

      return mainProc13(overlay, param2, &actorHead, param1);
}

int16 Op_Protect(void) {
      popPtr();
      popVar();

      return 0;
}

int16 Op_AutoCell(void) {
      cellStruct *pObject;

      int signal = popVar();
      int loop = popVar();
      int wait = popVar();
      int animStep = popVar();
      int end = popVar();
      int start = popVar();
      int type = popVar();
      int change = popVar();
      int obj = popVar();
      int overlay = popVar();

      if (!overlay)
            overlay = currentScriptPtr->overlayNumber;

      pObject = addCell(&cellHead, overlay, obj, 4, masterScreen, currentScriptPtr->overlayNumber, currentScriptPtr->scriptNumber, currentScriptPtr->type);

      if (!pObject)
            return 0;

      pObject->animSignal = signal;
      pObject->animLoop = loop;
      pObject->animWait = wait;
      pObject->animStep = animStep;
      pObject->animEnd = end;
      pObject->animStart = start;
      pObject->animType = type;
      pObject->animChange = change;

      if (type) {
            if (currentScriptPtr->type == scriptType_PROC) {
                  changeScriptParamInList(currentScriptPtr->overlayNumber, currentScriptPtr->scriptNumber, &procHead, -1, 9996);
            } else if (currentScriptPtr->type == scriptType_REL) {
                  changeScriptParamInList(currentScriptPtr->overlayNumber, currentScriptPtr->scriptNumber, &relHead, -1, 9996);
            }
      }

      if (change == 5) {
            objInit(pObject->overlay, pObject->idx, start);
      } else {
            setObjectPosition(pObject->overlay, pObject->idx, pObject->animChange, start);
      }

      if (wait < 0) {
            objectParamsQuery params;

            getMultipleObjectParam(overlay, obj, &params);
            pObject->animCounter = params.state2 - 1;
      }

      return 0;
}

int16 Op_Sizeof(void) {
      objectParamsQuery params;
      int index = popVar();
      int overlay = popVar();

      if (!overlay)
            overlay = currentScriptPtr->overlayNumber;

      getMultipleObjectParam(overlay, index, &params);

      return params.nbState - 1;
}

int16 Op_SetActiveBackground(void) {
      int currentPlane = masterScreen;
      int newPlane = popVar();

      if (newPlane >= 0 && newPlane < 8) {
            if (backgroundPtrtable[newPlane]) {
                  masterScreen = newPlane;
                  switchPal = 1;
            }
      }

      return currentPlane;
}

int16 Op_RemoveBackground(void) {
      int backgroundIdx = popVar();

      if (backgroundIdx > 0 && backgroundIdx < 8) {
            if (backgroundPtrtable[backgroundIdx])
                  free(backgroundPtrtable[backgroundIdx]);

            if (masterScreen == backgroundIdx)
                  masterScreen = 0;

            strcpy(backgroundTable[backgroundIdx].name, "");
      } else {
            strcpy(backgroundTable[0].name, "");
      }

      return (0);
}

int vblLimit;

int16 Op_VBL(void) {
      vblLimit = popVar();
      return 0;
}

int op7BVar = 0;

int16 Op_Sec(void) {
      int di = popVar();
      int si = 1 - op7BVar;
      int sign;

      if (di) {
            sign = di / (ABS(di));
      } else {
            sign = 0;
      }

      op7BVar = -sign;

      return si;
}

int16 Op_RemoveBackgroundIncrust(void) {
      int idx = popVar();
      int overlay = popVar();

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

      removeBackgroundIncrust(overlay, idx, &backgroundIncrustHead);

      return 0;
}

int16 Op_SetColor(void) {
      int colorB = popVar();
      int colorG = popVar();
      int colorR = popVar();
      int endIdx = popVar();
      int startIdx = popVar();

      int i;

#define convertRatio 36.571428571428571428571428571429

      for (i = startIdx; i <= endIdx; i++) {
            int offsetTable[3];

            offsetTable[0] = (int)(colorR * convertRatio);
            offsetTable[1] = (int)(colorG * convertRatio);
            offsetTable[2] = (int)(colorB * convertRatio);

            if (CVTLoaded) {
                  int colorIdx = cvtPalette[i];
                  calcRGB(&palScreen[masterScreen][3*colorIdx], &workpal[3*colorIdx], offsetTable);
            } else {
                  calcRGB(&palScreen[masterScreen][3*i], &workpal[3*i], offsetTable);
            }
      }

      gfxModuleData_setPal256(workpal);

      return 0;
}

int16 Op_Inventory(void) {
      int si = var41;

      var41 = popVar();

      return si;
}

int16 Op_RemoveOverlay(void) {
      int overlayIdx;

      overlayIdx = popVar();

      if (strlen(overlayTable[overlayIdx].overlayName)) {
            releaseOverlay(overlayTable[overlayIdx].overlayName);
      }

      return 0;
}

int16 Op_ComputeLine(void) {
      int y2 = popVar();
      int x2 = popVar();
      int y1 = popVar();
      int x1 = popVar();

      point* pDest = (point*)popPtr();

      int maxValue = cor_droite(x1, y1, x2, y2, pDest);

      flipGen(pDest, maxValue * 4);

      return maxValue;
}

int16 Op_FindMsg(void) {
      int si = popVar();
      popVar();

      return si;
}

int16 Op_SetZoom(void) {
      var46 = popVar();
      var45 = popVar();
      var42 = popVar();
      var39 = popVar();
      return 0;
}

int16 computeZoom(int param) {
      return (((param - var46) * (var39 - var42)) / (var45 - var46)) + var42;
}

int16 subOp23(int param1, int param2) {
      return (param1 * param2) >> 8;
}

int16 Op_GetStep(void) {
      int si = popVar();
      int dx = popVar();

      return subOp23(dx, si);
}

int16 Op_GetZoom(void) {
      return (computeZoom(popVar()));
}

actorStruct *addAnimation(actorStruct * pHead, int overlay, int objIdx, int param, int param2) {
      actorStruct *pPrevious = pHead;
      actorStruct *pCurrent = pHead->next;

      // go to the end of the list
      while (pCurrent) {
            pPrevious = pCurrent;
            pCurrent = pPrevious->next;
      }

      if (pCurrent && (pCurrent->overlayNumber == overlay)
              && (pCurrent->idx == objIdx) && (pCurrent->type == param2)) {
            return NULL;
      }

      actorStruct *pNewElement = (actorStruct *) malloc(sizeof(actorStruct));
      if (!pNewElement)
            return NULL;

      pNewElement->next = pPrevious->next;
      pPrevious->next = pNewElement;

      if (!pCurrent) {
            pCurrent = pHead;
      }

      pNewElement->prev = pCurrent->prev;
      pCurrent->prev = pNewElement;

      pNewElement->idx = objIdx;
      pNewElement->type = param2;
      pNewElement->pathId = -1;
      pNewElement->overlayNumber = overlay;
      pNewElement->startDirection = param;
      pNewElement->nextDirection = -1;
      pNewElement->stepX = 5;
      pNewElement->stepY = 2;
      pNewElement->phase = ANIM_PHASE_WAIT;
      pNewElement->flag = 0;
      pNewElement->freeze = 0;

      return pNewElement;
}

int removeAnimation(actorStruct * pHead, int overlay, int objIdx, int objType) {
      actorStruct* pl;
      actorStruct* pl2;
      actorStruct* pl3;
      actorStruct* pl4;

      int dir = 0;

      pl = pHead;
      pl2 = pl;
      pl = pl2->next;

      while (pl) {
            pl2 = pl;

            if (((pl->overlayNumber == overlay) || (overlay == -1)) &&
                    ((pl->idx == objIdx) || (objIdx == -1)) &&
                    ((pl->type == objType) || (objType == -1))) {
                  pl->type = -1;
            }

            pl = pl2->next;
      }

      pl = pHead;
      pl2 = pl;
      pl = pl2->next;

      while (pl) {
            if (pl->type == -1) {
                  pl4 = pl->next;
                  pl2->next = pl4;
                  pl3 = pl4;

                  if (pl3 == NULL)
                        pl3 = pHead;

                  pl3->prev = pl->prev;

                  dir = pl->startDirection;

                  if (pl->idx >= 0)
                        freePerso(pl->idx);

                  free(pl);
                  pl = pl4;
            } else {
                  pl2 = pl;
                  pl = pl2->next;
            }
      }

      return dir;
}

int flag_obstacle;            // computedVar14Bis

// add animation
int16 Op_AddAnimation(void) {
      int stepY = popVar();
      int stepX = popVar();
      int direction = popVar();
      int start = popVar();
      int type = popVar();
      int obj = popVar();
      int overlay = popVar();

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

      if (direction >= 0 && direction <= 3) {
            actorStruct *si;

            si = addAnimation(&actorHead, overlay, obj, direction, type);

            if (si) {
                  objectParamsQuery params;

                  getMultipleObjectParam(overlay, obj, &params);

                  si->x = params.X;
                  si->y = params.Y;
                  si->x_dest = -1;
                  si->y_dest = -1;
                  si->endDirection = -1;
                  si->start = start;
                  si->stepX = stepX;
                  si->stepY = stepY;

                  int newFrame = ABS(raoul_end[direction][0]) - 1;

                  int zoom = computeZoom(params.Y);

                  if (raoul_end[direction][0] < 0) {
                        zoom = -zoom;
                  }

                  getPixel(params.X, params.Y);

                  setObjectPosition(overlay, obj, 3, newFrame + start);
                  setObjectPosition(overlay, obj, 4, zoom);
                  setObjectPosition(overlay, obj, 5, computedVar14);

                  animationStart = false;
            }
      }

      return 0;
}

int16 Op_RemoveAnimation(void) {
      int objType = popVar();
      int objIdx = popVar();
      int ovlIdx = popVar();

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

      return removeAnimation(&actorHead, ovlIdx, objIdx, objType);
}

int16 Op_regenerateBackgroundIncrust(void) {
      regenerateBackgroundIncrust(&backgroundIncrustHead);
      return 0;
}

int16 Op_SetStringColors(void) {
      // TODO: here ignore if low color mode

      subColor = (uint8) popVar();
      itemColor = (uint8) popVar();
      selectColor = (uint8) popVar();
      titleColor = (uint8) popVar();

      return 0;
}

int16 Op_TrackAnim(void) {          // setup actor position
      actorStruct *pActor;

      int var0 = popVar();
      int actorY = popVar();
      int actorX = popVar();
      int var1 = popVar();
      int var2 = popVar();
      int overlay = popVar();

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

      pActor = findActor(&actorHead, overlay, var2, var1);

      if (!pActor) {
            return 1;
      }

      animationStart = false;

      pActor->x_dest = actorX;
      pActor->y_dest = actorY;
      pActor->flag = 1;
      pActor->endDirection = var0;

      return 0;
}

int16 Op_StopSong(void) {
      printf("Partial op 45 stop sound\n");

      return 0;
}

int16 Op_BgName(void) {
      char* bgName = (char*)popPtr();
      int bgIdx = popVar();

      if ((bgIdx >= 0) && (bgIdx < 8) && bgName) {
            strcpy(bgName, backgroundTable[bgIdx].name);

            if (strlen(bgName))
                  return 1;

            return 0;
      }

      return 0;
}

int16 Op_StopFX(void) {
      int fxIdx = popVar();

      printf("StopFX(%d)\n", fxIdx);

      return 0;
}

int16 Op_PlaySong(void) {
      printf("PlaySong()\n");

      return 0;
}

void setVar49Value(int value) {
      flagCt = value;
}

int16 Op_CTOn(void) {
      setVar49Value(1);
      return 0;
}

int16 Op_CTOff(void) {
      setVar49Value(0);
      return 0;
}

int16 Op_FadeSong(void) {
      printf("FadeSong()\n");
      return 0;
}

int16 Op_FreeSong(void) {
      printf("FreeSong()\n");
      //freeStuff1();
      freeStuff2();

      playMusic2 = 0;
      playMusic = 0;
      return 0;
}

int16 Op_FreezeOverlay(void) {
      //int var0;
      //int var1;
      int temp;

      int var0 = popVar();
      int var1 = popVar();

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

      temp = overlayTable[var1].executeScripts;
      overlayTable[var1].executeScripts = var0;

      return temp;
}

int16 Op_FreezeCell(void) {
      int newFreezz = popVar();
      int oldFreeze = popVar();
      int backgroundPlante = popVar();
      int objType = popVar();
      int objIdx = popVar();
      int overlayIdx = popVar();

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

      freezeCell(&cellHead, overlayIdx, objIdx, objType, backgroundPlante, oldFreeze, newFreezz);

      return 0;
}

void Op_60Sub(int overlayIdx, actorStruct * pActorHead, int _var0, int _var1, int _var2, int _var3) {
      actorStruct *pActor = findActor(pActorHead, overlayIdx, _var0, _var3);

      if (pActor) {
            if ((pActor->freeze == _var2) || (_var2 == -1)) {
                  pActor->freeze = _var1;
            }
      }
}

int16 Op_FreezeAni(void) {
      /*
       * int var0;
       * int var1;
       * int var2;
       * int var3;
       * int var4;
       */

      int var0 = popVar();
      int var1 = popVar();
      int var2 = popVar();
      int var3 = popVar();
      int var4 = popVar();

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

      Op_60Sub(var4, &actorHead, var3, var0, var1, var2);

      return 0;
}

int16 Op_Itoa(void) {
      int nbp = popVar();
      int param[160];
      char txt[40];
      char format[30];
      char nbf[20];

      for (int i = nbp - 1; i >= 0; i--)
            param[i] = popVar();

      int val = popVar();
      char* pDest = (char*)popPtr();

      if (!nbp)
            sprintf(txt, "%d", val);
      else {
            strcpy(format, "%");
            sprintf(nbf, "%d", param[0]);
            strcat(format, nbf);
            strcat(format, "d");
            sprintf(txt, format, val);
      }

      for (int i = 0; txt[i]; i++)
            *(pDest++) = txt[i];
      *(pDest++) = '\0';

      return 0;
}

int16 Op_Strcat(void) {
      char *pSource = (char *)popPtr();
      char *pDest = (char *)popPtr();

      while (*pDest)
            pDest++;

      while (*pSource)
            *(pDest++) = *(pSource++);
      *(pDest++) = '\0';

      return 0;
}

int16 Op_FindSymbol(void) {
      int var0 = popVar();
      char *ptr = (char *)popPtr();
      int var1 = popVar();

      if (!var1)
            var1 = currentScriptPtr->overlayNumber;

      return getProcParam(var1, var0, ptr);
}

int16 Op_FindObject(void) {
      char var_26[36];
      char *ptr = (char *)popPtr();
      int overlayIdx;

      var_26[0] = 0;

      if (ptr) {
            strcpy(var_26, ptr);
      }

      overlayIdx = popVar();

      if (!overlayIdx)
            overlayIdx = currentScriptPtr->overlayNumber;

      return getProcParam(overlayIdx, 40, var_26);
}

int16 Op_SetObjectAtNode(void) {
      int16 node = popVar();
      int16 obj = popVar();
      int16 ovl = popVar();

      if (!ovl)
            ovl = currentScriptPtr->overlayNumber;

      int nodeInfo[2];

      if (!getNode(nodeInfo, node)) {
            setObjectPosition(ovl, obj, 0, nodeInfo[0]);
            setObjectPosition(ovl, obj, 1, nodeInfo[1]);
            setObjectPosition(ovl, obj, 2, nodeInfo[1]);
            setObjectPosition(ovl, obj, 4, computeZoom(nodeInfo[1]));
      }

      return 0;
}

int16 Op_GetNodeX(void) {
      int16 node = popVar();

      int nodeInfo[2];

      int result = getNode(nodeInfo, node);

      ASSERT(result == 0);

      return nodeInfo[0];
}

int16 Op_GetNodeY(void) {
      int16 node = popVar();

      int nodeInfo[2];

      int result = getNode(nodeInfo, node);

      ASSERT(result == 0);

      return nodeInfo[1];
}

int16 Op_SongExist(void) {
      char* songName = (char*)popPtr();

      printf("Unimplemented \"Op_SongExist\": %s\n", songName);

      return 0;
}

int16 Op_SetNodeState(void) {
      int16 state = popVar();
      int16 node = popVar();

      return setNodeState(node, state);
}

int16 Op_SetNodeColor(void) {
      int16 color = popVar();
      int16 node = popVar();

      return setNodeColor(node, color);
}

int16 Op_SetXDial(void) {
      int16 old;

      old = xdial;
      xdial = popVar();

      return old;
}

int16 Op_DialogOn(void) {
      dialogueObj = popVar();
      dialogueOvl = popVar();

      if (dialogueOvl == 0)
            dialogueOvl = currentScriptPtr->overlayNumber;

      dialogueEnabled = true;

      return 0;
}

int16 Op_DialogOff(void) {
      dialogueEnabled = false;

      objectReset();

      if (menuTable[0]) {
            freeMenu(menuTable[0]);
            menuTable[0] = NULL;
            changeCursor(CURSOR_NORMAL);
            currentActiveMenu = -1;
      }

      return 0;
}

int16 Op_LinkObjects(void) {
      int type = popVar();
      int obj2 = popVar();
      int ovl2 = popVar();
      int obj = popVar();
      int ovl = popVar();

      if (!ovl)
            ovl = currentScriptPtr->overlayNumber;
      if (!ovl2)
            ovl2 = currentScriptPtr->overlayNumber;

      linkCell(&cellHead, ovl, obj, type, ovl2, obj2);

      return 0;
}

int16 Op_UserDelay(void) {
      int delay = popVar();

      if (delay >= 0) {
            userDelay = delay;
      }

      return userDelay;
}

int16 Op_UserWait(void) {
      userWait = 1;
      if (currentScriptPtr->type == scriptType_PROC) {
            changeScriptParamInList(currentScriptPtr->overlayNumber, currentScriptPtr->scriptNumber, &procHead, -1, 9999);
      } else if (currentScriptPtr->type == scriptType_REL) {
            changeScriptParamInList(currentScriptPtr->overlayNumber, currentScriptPtr->scriptNumber, &relHead, -1, 9999);
      }

      return 0;
}

opcodeFunction opcodeTablePtr[] = {
      NULL, // 0x00
      Op_FadeIn,
      Op_FadeOut,
      Op_LoadBackground,
      Op_LoadAbs,
      Op_AddCell,
      Op_AddProc,
      Op_InitializeState,
      Op_RemoveCell,
      Op_FreeCell,
      Op_RemoveProc,
      Op_RemoveFrame,
      Op_LoadOverlay,
      Op_SetColor,
      Op_PlayFX,
      NULL, // used to be debug

      Op_FreeOverlay, // 0x10
      Op_FindOverlay,
      NULL, // used to be exec debug
      Op_AddMessage,
      Op_RemoveMessage,
      Op_UserWait,
      Op_FreezeCell,
      Op_LoadCt,
      Op_AddAnimation,
      Op_RemoveAnimation,
      Op_SetZoom,
      Op_SetObjectAtNode,
      Op_SetNodeState,
      Op_SetNodeColor,
      Op_TrackAnim,
      Op_GetNodeX,

      Op_GetNodeY, // 0x20
      Op_EndAnim,
      Op_GetZoom,
      Op_GetStep,
      Op_SetStringColors,
      NULL, // xClick
      NULL, // yClick
      NULL, // getPixel
      Op_UserOn,
      Op_FreeCT,
      Op_FindObject,
      Op_FindProc,
      Op_WriteObject,
      Op_ReadObject,
      Op_RemoveOverlay,
      Op_AddBackgroundIncrust,

      Op_RemoveBackgroundIncrust, // 0x30
      Op_UnmergeBackgroundIncrust,
      Op_freeBackgroundInscrustList,
      Op_DialogOn,
      Op_DialogOff,
      Op_UserDelay,
      NULL, // ThemeReset
      Op_Narrator,
      Op_RemoveBackground,
      Op_SetActiveBackground,
      Op_CTOn,
      Op_CTOff,
      Op_Random,
      Op_LoadSong,
      Op_PlaySong,
      Op_FadeSong,

      Op_FreeSong, // 0x40
      Op_FrameExist,
      NULL, // SetVolume
      Op_SongExist,
      NULL, // TrackPos
      Op_StopSong,
      NULL, // RestoreSong
      NULL, // SongSize
      NULL, // SetPattern
      NULL, // SongLoop
      NULL, // SongPlayed
      Op_LinkObjects,
      NULL, // UserClick
      NULL, // XMenuItem
      NULL, // YMenuItem
      NULL, // Menu

      NULL, // AutoControl 0x50
      NULL, // MouseMove
      NULL, // MouseEnd
      NULL, // MsgExist
      Op_SetFont,
      NULL, // MergeMsg
      Op_Display,
      Op_GetMouseX,
      Op_GetMouseY,
      Op_GetMouseButton,
      Op_FindSet,
      Op_regenerateBackgroundIncrust,
      Op_BgName,
      NULL, // loopFX
      Op_StopFX,
      NULL, // freqFX

      Op_FreezeAni, // 0x60
      Op_FindMsg,
      Op_FreezeParent,
      Op_UnfreezeParent,
      Op_Exec,
      Op_AutoCell,
      Op_Sizeof,
      Op_Preload,
      Op_FreePreload,
      NULL, // DeletePreload
      Op_VBL,
      Op_LoadFrame,
      Op_FreezeOverlay,
      Op_Strcpy,
      Op_Strcat,
      Op_Itoa,

      Op_comment, // 0x70
      Op_ComputeLine,
      Op_FindSymbol,
      Op_SetXDial,
      Op_GetlowMemory,
      NULL, // aniDir
      Op_Protect,
      NULL, // Cls
      Op_Inventory,
      Op_UserMenu,
      NULL, // GetChar
      Op_Sec,
      Op_ProtectionFlag,
      Op_KillMenu,
};

void setupOpcodeTable(void) {
//    int i;

      /*    for (i = 0; i < 256; i++) {
                  opcodeTablePtr[i] = NULL;
            }

            opcodeTablePtr[0x1] = Op_FadeIn;
            opcodeTablePtr[0x2] = Op_FadeOut;
            opcodeTablePtr[0x3] = Op_LoadBackground;
            opcodeTablePtr[0x4] = Op_LoadAbs;
            opcodeTablePtr[0x5] = Op_AddCell;
            opcodeTablePtr[0x6] = Op_AddProc;
            opcodeTablePtr[0x7] = Op_InitializeState;
            opcodeTablePtr[0x8] = Op_RemoveCell;
            opcodeTablePtr[0x9] = Op_FreeCell;
            opcodeTablePtr[0xA] = Op_RemoveProc;
            opcodeTablePtr[0xB] = Op_RemoveFrame;
            opcodeTablePtr[0xC] = Op_LoadOverlay;
            opcodeTablePtr[0xD] = Op_SetColor;
            opcodeTablePtr[0xE] = Op_PlayFX;
            opcodeTablePtr[0xF] = NULL;   // used to be debug
            opcodeTablePtr[0x10] = Op_FreeOverlay;
            opcodeTablePtr[0x11] = Op_FindOverlay;
            opcodeTablePtr[0x12] = NULL;  // used to be exec debug
            opcodeTablePtr[0x13] = Op_AddMessage;
            opcodeTablePtr[0x14] = Op_RemoveMessage;
            opcodeTablePtr[0x15] = Op_UserWait;
            opcodeTablePtr[0x16] = Op_FreezeCell;
            opcodeTablePtr[0x17] = Op_LoadCt;
            opcodeTablePtr[0x18] = Op_AddAnimation;
            opcodeTablePtr[0x19] = Op_RemoveAnimation;
            opcodeTablePtr[0x1A] = Op_SetZoom;
            opcodeTablePtr[0x1B] = Op_SetObjectAtNode;
            opcodeTablePtr[0x1D] = Op_SetNodeColor;
            opcodeTablePtr[0x1E] = Op_TrackAnim;
            opcodeTablePtr[0x1F] = Op_GetNodeX;
            opcodeTablePtr[0x20] = Op_GetNodeY;
            opcodeTablePtr[0x21] = Op_EndAnim;
            opcodeTablePtr[0x22] = Op_GetZoom;
            opcodeTablePtr[0x23] = Op_GetStep;
            opcodeTablePtr[0x24] = Op_SetStringColors;
            opcodeTablePtr[0x28] = Op_UserOn;
            opcodeTablePtr[0x29] = Op_FreeCT;
            opcodeTablePtr[0x2A] = Op_FindObject;
            opcodeTablePtr[0x2B] = Op_FindProc;
            opcodeTablePtr[0x2C] = Op_WriteObject;
            opcodeTablePtr[0x2E] = Op_RemoveOverlay;
            opcodeTablePtr[0x2F] = Op_AddBackgroundIncrust;
            opcodeTablePtr[0x30] = Op_RemoveBackgroundIncrust;
            opcodeTablePtr[0x31] = Op_UnmergeBackgroundIncrust;
            opcodeTablePtr[0x32] = Op_freeBackgroundInscrustList;
            opcodeTablePtr[0x33] = Op_DialogOn;
            opcodeTablePtr[0x34] = Op_DialogOff;
            opcodeTablePtr[0x35] = Op_UserDelay;
            opcodeTablePtr[0x37] = Op_Narrator;
            opcodeTablePtr[0x38] = Op_RemoveBackground;
            opcodeTablePtr[0x39] = Op_SetActiveBackground;
            opcodeTablePtr[0x3A] = Op_CTOn;
            opcodeTablePtr[0x3B] = Op_CTOff;
            opcodeTablePtr[0x3C] = Op_Random;
            opcodeTablePtr[0x3D] = Op_LoadSong;
            opcodeTablePtr[0x3E] = Op_PlaySong;
            opcodeTablePtr[0x3F] = Op_FadeSong;
            opcodeTablePtr[0x40] = Op_FreeSong;
            opcodeTablePtr[0x41] = Op_FrameExist;
            opcodeTablePtr[0x43] = Op_SongExist;
            opcodeTablePtr[0x45] = Op_StopSong;
            opcodeTablePtr[0x4B] = Op_LinkObjects;
            opcodeTablePtr[0x54] = Op_SetFont;
            opcodeTablePtr[0x56] = Op_Display;
            opcodeTablePtr[0x57] = Op_GetMouseX;
            opcodeTablePtr[0x58] = Op_GetMouseY;
            opcodeTablePtr[0x59] = Op_GetMouseButton;
            opcodeTablePtr[0x5A] = Op_FindSet;
            opcodeTablePtr[0x5B] = Op_regenerateBackgroundIncrust;
            opcodeTablePtr[0x5C] = Op_BgName;
            opcodeTablePtr[0x5E] = Op_StopFX;
            opcodeTablePtr[0x60] = Op_FreezeAni;
            opcodeTablePtr[0x61] = Op_FindMsg;
            opcodeTablePtr[0x62] = Op_FreezeParent;
            opcodeTablePtr[0x63] = Op_UnfreezeParent;
            opcodeTablePtr[0x64] = Op_Exec;
            opcodeTablePtr[0x65] = Op_AutoCell;
            opcodeTablePtr[0x66] = Op_Sizeof;
            opcodeTablePtr[0x67] = Op_Preload;
            opcodeTablePtr[0x68] = Op_FreePreload;
            opcodeTablePtr[0x6A] = Op_VBL;
            opcodeTablePtr[0x6B] = Op_LoadFrame;
            opcodeTablePtr[0x6C] = Op_FreezeOverlay;
            opcodeTablePtr[0x6D] = Op_Strcpy;
            opcodeTablePtr[0x6E] = Op_Strcat;
            opcodeTablePtr[0x6F] = Op_Itoa;
            opcodeTablePtr[0x70] = Op_comment;
            opcodeTablePtr[0x71] = Op_ComputeLine;
            opcodeTablePtr[0x72] = Op_FindSymbol;
            opcodeTablePtr[0x73] = Op_SetXDial;
            opcodeTablePtr[0x74] = Op_GetlowMemory;
            opcodeTablePtr[0x76] = Op_Protect;
            opcodeTablePtr[0x79] = Op_UserMenu;
            opcodeTablePtr[0x78] = Op_Inventory;
            opcodeTablePtr[0x7B] = Op_Sec;
            opcodeTablePtr[0x7C] = Op_ProtectionFlag;
            opcodeTablePtr[0x7D] = Op_KillMenu;*/
      // TODO: copy the opcodes here
}

int32 opcodeType8(void) {
      int opcode = getByteFromScript();

      if (!opcode)
            return (-21);

      if (opcode > 0x100)
            return (-21);

      if (opcode < ARRAYSIZE(opcodeTablePtr) && opcodeTablePtr[opcode]) {
            //    printf("Function: %d\n",opcode);
            pushVar(opcodeTablePtr[opcode]());
            return (0);
      } else {
            printf("Unsupported opcode %d in opcode type 8\n", opcode);
            pushVar(0);
            // exit(1);
      }

      return 0;

}

} // End of namespace Cruise

Generated by  Doxygen 1.6.0   Back to index