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

game.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/gob/game.cpp $
 * $Id: game.cpp 30944 2008-02-23 22:50:18Z sev $
 *
 */


#include "common/endian.h"

#include "gob/gob.h"
#include "gob/game.h"
#include "gob/global.h"
#include "gob/util.h"
#include "gob/dataio.h"
#include "gob/inter.h"
#include "gob/parse.h"
#include "gob/draw.h"
#include "gob/mult.h"
#include "gob/music.h"

namespace Gob {

Game::Game(GobEngine *vm) : _vm(vm) {
      _extTable = 0;
      _totFileData = 0;
      _totResourceTable = 0;
      _imFileData = 0;
      _extHandle = 0;
      _collisionAreas = 0;
      _shouldPushColls = 0;

      _captureCount = 0;

      _foundTotLoc = false;
      _totTextData = 0;

      _collStackSize = 0;

      for (int i = 0; i < 5; i++) {
            _collStack[i] = 0;
            _collStackElemSizes[i] = 0;
      }

      _infIns = 0;
      _infogrames = 0;

      _curTotFile[0] = 0;
      _curExtFile[0] = 0;
      _totToLoad[0] = 0;

      _startTimeKey = 0;
      _mouseButtons = 0;

      _lastCollKey = 0;
      _lastCollAreaIndex = 0;
      _lastCollId = 0;

      _activeCollResId = 0;
      _activeCollIndex = 0;
      _handleMouse = 0;
      _forceHandleMouse = 0;
      _menuLevel = 0;
      _noScroll = true;
      _preventScroll = false;
      _scrollHandleMouse = false;

      _tempStr[0] = 0;
      _curImaFile[0] = 0;
      _collStr[0] = 0;

      _backupedCount = 0;
      _curBackupPos = 0;

      for (int i = 0; i < 5; i++) {
            _cursorHotspotXArray[i] = 0;
            _cursorHotspotYArray[i] = 0;
            _totTextDataArray[i] = 0;
            _totFileDataArray[i] = 0;
            _totResourceTableArray[i] = 0;
            _extTableArray[i] = 0;
            _extHandleArray[i] = 0;
            _imFileDataArray[i] = 0;
            _variablesArray[i] = 0;
            _curTotFileArray[i][0] = 0;
      }
}

Game::~Game() {
      delete _infIns;

      for (int i = 0; i < 60; i++)
            _soundSamples[i].free();
}

byte *Game::loadExtData(int16 itemId, int16 *pResWidth,
            int16 *pResHeight, uint32 *dataSize) {
      int16 commonHandle;
      int16 itemsCount;
      int32 offset;
      uint32 size;
      uint32 realSize;
      ExtItem *item;
      bool isPacked;
      int16 handle;
      int32 tableSize;
      char path[20];
      byte *dataBuf;
      byte *packedBuf;
      byte *dataPtr;

      itemId -= 30000;
      if (_extTable == 0)
            return 0;

      commonHandle = -1;
      itemsCount = _extTable->itemsCount;
      item = &_extTable->items[itemId];
      tableSize = szGame_ExtTable + szGame_ExtItem * itemsCount;

      offset = item->offset;
      size = item->size;
      isPacked = (item->width & 0x8000) != 0;

      if ((pResWidth != 0) && (pResHeight != 0)) {
            *pResWidth = item->width & 0x7FFF;

            if (*pResWidth & 0x4000)
                  size += 1 << 16;
            if (*pResWidth & 0x2000)
                  size += 2 << 16;
            if (*pResWidth & 0x1000)
                  size += 4 << 16;

            *pResWidth &= 0xFFF;

            *pResHeight = item->height;
            debugC(7, kDebugFileIO, "loadExtData(%d, %d, %d)",
                        itemId, *pResWidth, *pResHeight);
      }

      debugC(7, kDebugFileIO, "loadExtData(%d, 0, 0)", itemId);

      if (item->height == 0)
            size += (item->width & 0x7FFF) << 16;

      debugC(7, kDebugFileIO, "size: %d off: %d", size, offset);
      if (offset < 0) {
            offset = -(offset + 1);
            tableSize = 0;
            _vm->_dataIO->closeData(_extHandle);
            strcpy(path, "commun.ex1");
            path[strlen(path) - 1] = *(_totFileData + 0x3C) + '0';
            commonHandle = _vm->_dataIO->openData(path);
            handle = commonHandle;
      } else
            handle = _extHandle;

      DataStream *stream = _vm->_dataIO->openAsStream(handle);

      debugC(7, kDebugFileIO, "off: %d size: %d", offset, tableSize);
      stream->seek(offset + tableSize);
      realSize = size;
      if (isPacked)
            dataBuf = new byte[size + 2];
      else
            dataBuf = new byte[size];

      dataPtr = dataBuf;
      while (size > 32000) {
            // BUG: huge->far conversion. Need normalization?
            stream->read(dataPtr, 32000);
            size -= 32000;
            dataPtr += 32000;
      }
      stream->read(dataPtr, size);

      delete stream;
      if (commonHandle != -1) {
            _vm->_dataIO->closeData(commonHandle);
            _extHandle = _vm->_dataIO->openData(_curExtFile);
      }

      if (isPacked) {
            packedBuf = dataBuf;
            realSize = READ_LE_UINT32(packedBuf);
            dataBuf = new byte[realSize];
            _vm->_dataIO->unpackData(packedBuf, dataBuf);
            delete[] packedBuf;
      }

      if (dataSize)
            *dataSize = realSize;
      return dataBuf;
}

void Game::freeCollision(int16 id) {
      for (int i = 0; i < 250; i++) {
            if (_collisionAreas[i].id == id)
                  _collisionAreas[i].left = 0xFFFF;
      }
}

void Game::capturePush(int16 left, int16 top, int16 width, int16 height) {
      int16 right;

      if (_captureCount == 20)
            error("Game::capturePush(): Capture stack overflow!");

      _captureStack[_captureCount].left = left;
      _captureStack[_captureCount].top = top;
      _captureStack[_captureCount].right = left + width;
      _captureStack[_captureCount].bottom = top + height;

      _vm->_draw->_spriteTop = top;
      _vm->_draw->_spriteBottom = height;

      right = left + width - 1;
      left &= 0xFFF0;
      right |= 0xF;

      _vm->_draw->initSpriteSurf(30 + _captureCount, right - left + 1, height, 0);

      _vm->_draw->_sourceSurface = 21;
      _vm->_draw->_destSurface = 30 + _captureCount;

      _vm->_draw->_spriteLeft = left;
      _vm->_draw->_spriteRight = right - left + 1;
      _vm->_draw->_destSpriteX = 0;
      _vm->_draw->_destSpriteY = 0;
      _vm->_draw->_transparency = 0;
      _vm->_draw->spriteOperation(0);
      _captureCount++;
}

void Game::capturePop(char doDraw) {
      if (_captureCount <= 0)
            return;

      _captureCount--;
      if (doDraw) {
            _vm->_draw->_destSpriteX = _captureStack[_captureCount].left;
            _vm->_draw->_destSpriteY = _captureStack[_captureCount].top;
            _vm->_draw->_spriteRight =
                _captureStack[_captureCount].width();
            _vm->_draw->_spriteBottom =
                _captureStack[_captureCount].height();

            _vm->_draw->_transparency = 0;
            _vm->_draw->_sourceSurface = 30 + _captureCount;
            _vm->_draw->_destSurface = 21;
            _vm->_draw->_spriteLeft = _vm->_draw->_destSpriteX & 0xF;
            _vm->_draw->_spriteTop = 0;
            _vm->_draw->spriteOperation(0);
      }
      _vm->_draw->freeSprite(30 + _captureCount);
}

byte *Game::loadTotResource(int16 id, int16 *dataSize) {
      TotResItem *itemPtr;
      int32 offset;

      itemPtr = &_totResourceTable->items[id];
      offset = itemPtr->offset;
      if (dataSize)
            *dataSize = itemPtr->size;

      if (offset < 0) {
            offset = (-offset - 1) * 4;
            return _imFileData + (int32) READ_LE_UINT32(_imFileData + offset);
      } else
            return _totResourceTable->dataPtr + szGame_TotResTable +
                szGame_TotResItem * _totResourceTable->itemsCount + offset;
}

void Game::freeSoundSlot(int16 slot) {
      if (slot == -1)
            slot = _vm->_parse->parseValExpr();

      if ((slot < 0) || (slot >= 60) || _soundSamples[slot].empty())
            return;

      SoundDesc &sample = _soundSamples[slot];

      if (sample.getType() == SOUND_ADL)
            if (_vm->_adlib && (_vm->_adlib->getIndex() == slot))
                  _vm->_adlib->stopPlay();

      _vm->_snd->freeSample(sample);
}

void Game::evaluateScroll(int16 x, int16 y) {
      if (_preventScroll || !_scrollHandleMouse || (_menuLevel > 0))
            return;

      if (_noScroll || (_vm->_global->_videoMode != 0x14))
            return;

      if ((x == 0) && (_vm->_draw->_scrollOffsetX > 0)) {
            uint16 off;

            off = MIN(_vm->_draw->_cursorWidth, _vm->_draw->_scrollOffsetX);
            off = MAX(off / 2, 1);
            _vm->_draw->_scrollOffsetX -= off;
      } else if ((y == 0) && (_vm->_draw->_scrollOffsetY > 0)) {
            uint16 off;

            off = MIN(_vm->_draw->_cursorHeight, _vm->_draw->_scrollOffsetY);
            off = MAX(off / 2, 1);
            _vm->_draw->_scrollOffsetY -= off;
      }

      int16 cursorRight = x + _vm->_draw->_cursorWidth;
      int16 screenRight = _vm->_draw->_scrollOffsetX + _vm->_width;
      int16 cursorBottom = y + _vm->_draw->_cursorHeight;
      int16 screenBottom = _vm->_draw->_scrollOffsetY + _vm->_height;

      if ((cursorRight >= _vm->_width) &&
                  (screenRight < _vm->_video->_surfWidth)) {
            uint16 off;

            off = MIN(_vm->_draw->_cursorWidth,
                        (int16) (_vm->_video->_surfWidth - screenRight));
            off = MAX(off / 2, 1);

            _vm->_draw->_scrollOffsetX += off;

            _vm->_util->setMousePos(_vm->_width - _vm->_draw->_cursorWidth, y);
      } else if ((cursorBottom >= (_vm->_height - _vm->_video->_splitHeight2)) &&
                  (screenBottom < _vm->_video->_surfHeight)) {
            uint16 off;

            off = MIN(_vm->_draw->_cursorHeight,
                        (int16) (_vm->_video->_surfHeight - screenBottom));
            off = MAX(off / 2, 1);

            _vm->_draw->_scrollOffsetY += off;

            _vm->_util->setMousePos(x, _vm->_height - _vm->_video->_splitHeight2 -
                        _vm->_draw->_cursorHeight);
      }

      _vm->_util->setScrollOffset();
}

int16 Game::checkKeys(int16 *pMouseX, int16 *pMouseY,
            int16 *pButtons, char handleMouse) {

      _vm->_util->processInput(true);

      if (_vm->_mult->_multData && _vm->_global->_inter_variables &&
                  (VAR(58) != 0)) {
            if (_vm->_mult->_multData->frameStart != (int) VAR(58) - 1)
                  _vm->_mult->_multData->frameStart++;
            else
                  _vm->_mult->_multData->frameStart = 0;

            _vm->_mult->playMult(_vm->_mult->_multData->frameStart + VAR(57),
                        _vm->_mult->_multData->frameStart + VAR(57), 1, handleMouse);
      }

      if ((_vm->_inter->_soundEndTimeKey != 0) &&
          (_vm->_util->getTimeKey() >= _vm->_inter->_soundEndTimeKey)) {
            _vm->_snd->stopSound(_vm->_inter->_soundStopVal);
            _vm->_inter->_soundEndTimeKey = 0;
      }

      if (pMouseX && pMouseY && pButtons) {
            _vm->_util->getMouseState(pMouseX, pMouseY, pButtons);

            if (*pButtons == 3)
                  *pButtons = 0;
      }

      return _vm->_util->checkKey();
}

int16 Game::adjustKey(int16 key) {
      if (key <= 0x60 || key >= 0x7B)
            return key;

      return key - 0x20;
}

int32 Game::loadTotFile(const char *path) {
      int16 handle;
      int32 size;

      size = -1;
      handle = _vm->_dataIO->openData(path);
      if (handle >= 0) {
            _vm->_dataIO->closeData(handle);
            size = _vm->_dataIO->getDataSize(path);
            _totFileData = _vm->_dataIO->getData(path);
      } else
            _totFileData = 0;

      return size;
}

void Game::loadExtTable(void) {
      int16 count;

      // Function is correct. [sev]

      _extHandle = _vm->_dataIO->openData(_curExtFile);
      if (_extHandle < 0)
            return;

      DataStream *stream = _vm->_dataIO->openAsStream(_extHandle);
      count = stream->readUint16LE();

      stream->seek(0);
      _extTable = new ExtTable;
      _extTable->items = 0;
      if (count)
            _extTable->items = new ExtItem[count];

      _extTable->itemsCount = stream->readUint16LE();
      _extTable->unknown = stream->readByte();

      for (int i = 0; i < count; i++) {
            _extTable->items[i].offset = stream->readUint32LE();
            _extTable->items[i].size = stream->readUint16LE();
            _extTable->items[i].width = stream->readUint16LE();
            _extTable->items[i].height = stream->readUint16LE();
      }

      delete stream;
}

void Game::loadImFile(void) {
      char path[20];
      int16 handle;

      if ((_totFileData[0x3D] != 0) && (_totFileData[0x3B] == 0))
            return;

      strcpy(path, "commun.im1");
      if (_totFileData[0x3B] != 0)
            path[strlen(path) - 1] = '0' + _totFileData[0x3B];

      handle = _vm->_dataIO->openData(path);
      if (handle < 0)
            return;

      _vm->_dataIO->closeData(handle);
      _imFileData = _vm->_dataIO->getData(path);
}

void Game::start(void) {
      _collisionAreas = new Collision[250];
      memset(_collisionAreas, 0, 250 * sizeof(Collision));

      prepareStart();
      playTot(-2);

      delete[] _collisionAreas;
      _vm->_draw->closeScreen();

      for (int i = 0; i < SPRITES_COUNT; i++)
            _vm->_draw->freeSprite(i);
      _vm->_draw->_scummvmCursor = 0;
}

// flagbits: 0 = freeInterVariables, 1 = skipPlay
void Game::totSub(int8 flags, const char *newTotFile) {
      int8 curBackupPos;

      if (_backupedCount >= 5)
            return;

      _cursorHotspotXArray[_backupedCount] = _vm->_draw->_cursorHotspotXVar;
      _cursorHotspotYArray[_backupedCount] = _vm->_draw->_cursorHotspotYVar;
      _totTextDataArray[_backupedCount] = _totTextData;
      _totFileDataArray[_backupedCount] = _totFileData;
      _totResourceTableArray[_backupedCount] = _totResourceTable;
      _extTableArray[_backupedCount] = _extTable;
      _extHandleArray[_backupedCount] = _extHandle;
      _imFileDataArray[_backupedCount] = _imFileData;
      _variablesArray[_backupedCount] = _vm->_global->_inter_variables;
      _variablesSizesArray[_backupedCount] = _vm->_global->_inter_variablesSizes;
      strcpy(_curTotFileArray[_backupedCount], _curTotFile);

      curBackupPos = _curBackupPos;
      _backupedCount++;
      _curBackupPos = _backupedCount;

      _totTextData = 0;
      _totFileData = 0;
      _totResourceTable = 0;
      if (flags & 1) {
            _vm->_global->_inter_variables = 0;
            _vm->_global->_inter_variablesSizes = 0;
      }

      strncpy0(_curTotFile, newTotFile, 9);
      strcat(_curTotFile, ".TOT");

      if (_vm->_inter->_terminate != 0)
            return;

      pushCollisions(0);

      if (flags & 2)
            playTot(-1);
      else
            playTot(0);

      if (_vm->_inter->_terminate != 2)
            _vm->_inter->_terminate = 0;

      popCollisions();

      if ((flags & 1) && _vm->_global->_inter_variables) {
            delete[] _vm->_global->_inter_variables;
            delete[] _vm->_global->_inter_variablesSizes;
      }

      _backupedCount--;
      _curBackupPos = curBackupPos;

      _vm->_draw->_cursorHotspotXVar = _cursorHotspotXArray[_backupedCount];
      _vm->_draw->_cursorHotspotYVar = _cursorHotspotYArray[_backupedCount];
      _totTextData = _totTextDataArray[_backupedCount];
      _totFileData = _totFileDataArray[_backupedCount];
      _totResourceTable = _totResourceTableArray[_backupedCount];
      _extTable = _extTableArray[_backupedCount];
      _extHandle = _extHandleArray[_backupedCount];
      _imFileData = _imFileDataArray[_backupedCount];
      _vm->_global->_inter_variables = _variablesArray[_backupedCount];
      _vm->_global->_inter_variablesSizes = _variablesSizesArray[_backupedCount];
      strcpy(_curTotFile, _curTotFileArray[_backupedCount]);
      strcpy(_curExtFile, _curTotFile);
      _curExtFile[strlen(_curExtFile) - 4] = '\0';
      strcat(_curExtFile, ".EXT");
}

void Game::switchTotSub(int16 index, int16 skipPlay) {
      int16 backupedCount;
      int16 curBackupPos;

      if ((_backupedCount - index) < 1)
            return;

      int16 newPos = _curBackupPos - index - ((index >= 0) ? 1 : 0);
      // WORKAROUND: Some versions don't make the MOVEMENT menu item unselectable
      // in the dreamland screen, resulting in a crash when it's clicked.
      if ((_vm->getGameType() == kGameTypeGob2) && (index == -1) && (skipPlay == 7) &&
          !scumm_stricmp(_curTotFileArray[newPos], "gob06.tot"))
            return;

      curBackupPos = _curBackupPos;
      backupedCount = _backupedCount;
      if (_curBackupPos == _backupedCount) {
            _cursorHotspotXArray[_backupedCount] = _vm->_draw->_cursorHotspotXVar;
            _cursorHotspotYArray[_backupedCount] = _vm->_draw->_cursorHotspotYVar;
            _totTextDataArray[_backupedCount] = _totTextData;
            _totFileDataArray[_backupedCount] = _totFileData;
            _totResourceTableArray[_backupedCount] = _totResourceTable;
            _extTableArray[_backupedCount] = _extTable;
            _extHandleArray[_backupedCount] = _extHandle;
            _imFileDataArray[_backupedCount] = _imFileData;
            _variablesArray[_backupedCount] = _vm->_global->_inter_variables;
            _variablesSizesArray[_backupedCount] = _vm->_global->_inter_variablesSizes;
            strcpy(_curTotFileArray[_backupedCount], _curTotFile);
            _backupedCount++;
      }
      _curBackupPos -= index;
      if (index >= 0)
            _curBackupPos--;

      _vm->_draw->_cursorHotspotXVar = _cursorHotspotXArray[_curBackupPos];
      _vm->_draw->_cursorHotspotYVar = _cursorHotspotYArray[_curBackupPos];
      _totTextData = _totTextDataArray[_curBackupPos];
      _totFileData = _totFileDataArray[_curBackupPos];
      _totResourceTable = _totResourceTableArray[_curBackupPos];
      _imFileData = _imFileDataArray[_curBackupPos];
      _extTable = _extTableArray[_curBackupPos];
      _extHandle = _extHandleArray[_curBackupPos];
      _vm->_global->_inter_variables = _variablesArray[_curBackupPos];
      _vm->_global->_inter_variablesSizes = _variablesSizesArray[_curBackupPos];
      strcpy(_curTotFile, _curTotFileArray[_curBackupPos]);
      strcpy(_curExtFile, _curTotFile);
      _curExtFile[strlen(_curExtFile) - 4] = '\0';
      strcat(_curExtFile, ".EXT");

      if (_vm->_inter->_terminate != 0)
            return;

      _vm->_game->pushCollisions(0);
      _vm->_game->playTot(skipPlay);

      if (_vm->_inter->_terminate != 2)
            _vm->_inter->_terminate = 0;

      _vm->_game->popCollisions();

      _curBackupPos = curBackupPos;
      _backupedCount = backupedCount;
      _vm->_draw->_cursorHotspotXVar = _cursorHotspotXArray[_curBackupPos];
      _vm->_draw->_cursorHotspotYVar = _cursorHotspotYArray[_curBackupPos];
      _totTextData = _totTextDataArray[_curBackupPos];
      _totFileData = _totFileDataArray[_curBackupPos];
      _totResourceTable = _totResourceTableArray[_curBackupPos];
      _extTable = _extTableArray[_curBackupPos];
      _extHandle = _extHandleArray[_curBackupPos];
      _imFileData = _imFileDataArray[_curBackupPos];
      _vm->_global->_inter_variables = _variablesArray[_curBackupPos];
      _vm->_global->_inter_variablesSizes = _variablesSizesArray[_curBackupPos];
      strcpy(_curTotFile, _curTotFileArray[_curBackupPos]);
      strcpy(_curExtFile, _curTotFile);
      _curExtFile[strlen(_curExtFile) - 4] = '\0';
      strcat(_curExtFile, ".EXT");
}

int16 Game::openLocTextFile(char *locTextFile, int language) {
      int n;

      n = strlen(locTextFile);
      if (n < 4)
            return -1;

      locTextFile[n - 4] = 0;
      switch (language) {
      case 0:
            strcat(locTextFile, ".dat");
            break;
      case 1:
            strcat(locTextFile, ".all");
            break;
      case 3:
            strcat(locTextFile, ".esp");
            break;
      case 4:
            strcat(locTextFile, ".ita");
            break;
      case 5:
            strcat(locTextFile, ".usa");
            break;
      case 6:
            strcat(locTextFile, ".ndl");
            break;
      case 7:
            strcat(locTextFile, ".kor");
            break;
      case 8:
            strcat(locTextFile, ".isr");
            break;
      default:
            strcat(locTextFile, ".ang");
            break;
      }
      return _vm->_dataIO->openData(locTextFile);
}

byte *Game::loadLocTexts(int32 *dataSize) {
      char locTextFile[20];
      int16 handle;
      int i;

      strcpy(locTextFile, _curTotFile);

      handle = openLocTextFile(locTextFile, _vm->_global->_languageWanted);
      if (handle >= 0) {

            _foundTotLoc = true;
            _vm->_global->_language = _vm->_global->_languageWanted;

      } else if (!_foundTotLoc) {
            bool found = false;

            if (_vm->_global->_languageWanted == 2) {
                  handle = openLocTextFile(locTextFile, 5);
                  if (handle >= 0) {
                        _vm->_global->_language = 5;
                        found = true;
                  }
            } else if (_vm->_global->_languageWanted == 5) {
                  handle = openLocTextFile(locTextFile, 2);
                  if (handle >= 0) {
                        _vm->_global->_language = 2;
                        found = true;
                  }
            }

            if (!found) {
                  for (i = 0; i < 10; i++) {
                        handle = openLocTextFile(locTextFile, i);
                        if (handle >= 0) {
                              _vm->_global->_language = i;
                              break;
                        }
                  }
            }

      }

      debugC(1, kDebugFileIO, "Using language %d for %s",
                  _vm->_global->_language, _curTotFile);

      if (handle >= 0) {
            _vm->_dataIO->closeData(handle);

            if (dataSize)
                  *dataSize = _vm->_dataIO->getDataSize(locTextFile);

            return _vm->_dataIO->getData(locTextFile);
      }
      return 0;
}

void Game::setCollisions(void) {
      byte *savedIP;
      uint16 left;
      uint16 top;
      uint16 width;
      uint16 height;
      Collision *collArea;

      for (collArea = _collisionAreas; collArea->left != 0xFFFF; collArea++) {
            if (((collArea->id & 0xC000) != 0x8000) || (collArea->funcSub == 0))
                  continue;

            savedIP = _vm->_global->_inter_execPtr;
            _vm->_global->_inter_execPtr = _totFileData + collArea->funcSub;
            left = _vm->_parse->parseValExpr();
            top = _vm->_parse->parseValExpr();
            width = _vm->_parse->parseValExpr();
            height = _vm->_parse->parseValExpr();
            if ((_vm->_draw->_renderFlags & RENDERFLAG_CAPTUREPOP) &&
                        (left != 0xFFFF)) {
                  left += _vm->_draw->_backDeltaX;
                  top += _vm->_draw->_backDeltaY;
            }
            if (_vm->_draw->_needAdjust != 2) {
                  _vm->_draw->adjustCoords(0, &left, &top);
                  if ((collArea->flags & 0x0F) < 3)
                        _vm->_draw->adjustCoords(2, &width, &height);
                  else {
                        height &= 0xFFFE;
                        _vm->_draw->adjustCoords(2, 0, &height);
                  }
            }
            collArea->left = left;
            collArea->top = top;
            collArea->right = left + width - 1;
            collArea->bottom = top + height - 1;
            _vm->_global->_inter_execPtr = savedIP;
      }
}

void Game::collSub(uint16 offset) {
      byte *savedIP;
      int16 collStackSize;

      savedIP = _vm->_global->_inter_execPtr;
      _vm->_global->_inter_execPtr = _totFileData + offset;

      _shouldPushColls = 1;
      collStackSize = _collStackSize;

      _vm->_inter->funcBlock(0);

      if (collStackSize != _collStackSize)
            popCollisions();

      _shouldPushColls = 0;
      _vm->_global->_inter_execPtr = savedIP;
      setCollisions();
}

void Game::collAreaSub(int16 index, int8 enter) {
      uint16 collId;

      collId = _collisionAreas[index].id & 0xF000;

      if ((collId == 0xA000) || (collId == 0x9000)) {
            if (enter == 0)
                  WRITE_VAR(17, _collisionAreas[index].id & 0x0FFF);
            else
                  WRITE_VAR(17, -(_collisionAreas[index].id & 0x0FFF));
      }

      if (enter != 0) {
            if (_collisionAreas[index].funcEnter != 0)
                  collSub(_collisionAreas[index].funcEnter);
      } else {
            if (_collisionAreas[index].funcLeave != 0)
                  collSub(_collisionAreas[index].funcLeave);
      }
}

} // End of namespace Gob

Generated by  Doxygen 1.6.0   Back to index