aboutsummaryrefslogtreecommitdiff
path: root/engines/hopkins/objects.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'engines/hopkins/objects.cpp')
-rw-r--r--engines/hopkins/objects.cpp3910
1 files changed, 3910 insertions, 0 deletions
diff --git a/engines/hopkins/objects.cpp b/engines/hopkins/objects.cpp
new file mode 100644
index 0000000000..b37dac2f6e
--- /dev/null
+++ b/engines/hopkins/objects.cpp
@@ -0,0 +1,3910 @@
+/* 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.
+ *
+ */
+
+#include "hopkins/objects.h"
+
+#include "hopkins/dialogs.h"
+#include "hopkins/files.h"
+#include "hopkins/globals.h"
+#include "hopkins/hopkins.h"
+
+#include "common/system.h"
+#include "graphics/palette.h"
+#include "common/file.h"
+#include "common/rect.h"
+#include "engines/util.h"
+
+namespace Hopkins {
+
+ObjectsManager::ObjectsManager() {
+ for (int i = 0; i < 6; ++i)
+ Common::fill((byte *)&_sprite[i], (byte *)&_sprite[i] + sizeof(SpriteItem), 0);
+
+ for (int i = 0; i < 36; ++i)
+ Common::fill((byte *)&_bob[i], (byte *)&_bob[i] + sizeof(BobItem), 0);
+
+ _helicopterFl = false;
+ _priorityFl = false;
+ _oldBorderPos = Common::Point(0, 0);
+ _oldBorderSpriteIndex = 0;
+ _borderPos = Common::Point(0, 0);
+ _borderSpriteIndex = 0;
+ _saveLoadX = _saveLoadY = 0;
+ _oldInventoryPosX = _oldInventoryPosY = 0;
+ _oldCharacterPosX = _oldCharacterPosY = 0;
+ _eraseVisibleCounter = 0;
+ _saveLoadSprite = g_PTRNUL;
+ _saveLoadSprite2 = g_PTRNUL;
+ _spritePtr = g_PTRNUL;
+ _oldSpriteData = g_PTRNUL;
+ PERSO_ON = false;
+ _saveLoadFl = false;
+ _visibleFl = false;
+ BOBTOUS = false;
+ _zoneNum = 0;
+ _forceZoneFl = false;
+ _changeVerbFl = false;
+ _verb = 0;
+ _changeHeadFl = false;
+ _disableFl = false;
+ _twoCharactersFl = false;
+ _characterPos = Common::Point(0, 0);
+ _startSpriteIndex = 0;
+ OBSSEUL = false;
+ _jumpVerb = 0;
+ _jumpZone = 0;
+ _oldSpriteIndex = 0;
+ _oldFlipFl = false;
+ _curObjectIndex = 0;
+ _forestFl = false;
+ _mapCarPosX = _mapCarPosY = 0;
+ _forestSprite = NULL;
+ _gestureBuf = NULL;
+ _curGestureFile = 0;
+ _headSprites = NULL;
+}
+
+ObjectsManager::~ObjectsManager() {
+ _vm->_globals.freeMemory(_forestSprite);
+ _vm->_globals.freeMemory(_gestureBuf);
+ _vm->_globals.freeMemory(_headSprites);
+}
+
+void ObjectsManager::setParent(HopkinsEngine *vm) {
+ _vm = vm;
+}
+
+void ObjectsManager::clearAll() {
+ _forestFl = false;
+ _forestSprite = _vm->_globals.freeMemory(_forestSprite);
+ _curGestureFile = 0;
+ _gestureBuf = _vm->_globals.freeMemory(_gestureBuf);
+}
+
+/**
+ * Change Object
+ */
+void ObjectsManager::changeObject(int objIndex) {
+ _vm->_eventsManager._objectBuf = loadObjectFromFile(objIndex, true);
+ _curObjectIndex = objIndex;
+}
+
+byte *ObjectsManager::loadObjectFromFile(int objIndex, bool mode) {
+ byte *dataP = NULL;
+ int objectFileNum = _vm->_globals._objectAuthIcons[objIndex]._objectFileNum;
+ int idx = _vm->_globals._objectAuthIcons[objIndex]._idx;
+
+ if (mode)
+ ++idx;
+
+ if (objectFileNum != _vm->_globals._curObjectFileNum) {
+ if (_vm->_globals._objectDataBuf != g_PTRNUL)
+ ObjectsManager::removeObjectDataBuf();
+ if (objectFileNum == 1) {
+ _vm->_globals._objectDataBuf = ObjectsManager::loadSprite("OBJET1.SPR");
+ }
+ _vm->_globals._curObjectFileNum = objectFileNum;
+ }
+
+ int width = ObjectsManager::getWidth(_vm->_globals._objectDataBuf, idx);
+ int height = ObjectsManager::getHeight(_vm->_globals._objectDataBuf, idx);
+ _vm->_globals._objectWidth = width;
+ _vm->_globals._objectHeight = height;
+
+ if (mode) {
+ sprite_alone(_vm->_globals._objectDataBuf, _vm->_eventsManager._objectBuf, idx);
+ dataP = _vm->_eventsManager._objectBuf;
+ } else {
+ dataP = _vm->_globals.allocMemory(height * width);
+ if (dataP == g_PTRNUL)
+ error("CAPTURE_OBJET");
+
+ capture_mem_sprite(_vm->_globals._objectDataBuf, dataP, idx);
+ }
+
+ return dataP;
+}
+
+/**
+ * Remove an Object from the inventory
+ */
+void ObjectsManager::removeObject(int objIndex) {
+ int idx;
+ for (idx = 1; idx <= 32; ++idx) {
+ if (_vm->_globals._inventory[idx] == objIndex)
+ break;
+ }
+
+ if (idx <= 32) {
+ if (idx == 32) {
+ _vm->_globals._inventory[32] = 0;
+ } else {
+ for (int i = idx; i < 32; ++i)
+ _vm->_globals._inventory[i] = _vm->_globals._inventory[i + 1];
+ }
+ }
+ changeObject(14);
+
+}
+
+/**
+ * Set Offset XY
+ */
+void ObjectsManager::setOffsetXY(byte *data, int idx, int xp, int yp, bool isSize) {
+ byte *startP = data + 3;
+ for (int i = idx; i; --i)
+ startP += READ_LE_UINT32(startP) + 16;
+
+ byte *rectP = startP + 8;
+ if (isSize) {
+ // Set size
+ byte *pointP = rectP + 4;
+ WRITE_LE_UINT16(pointP, xp);
+ WRITE_LE_UINT16(pointP + 2, yp);
+ } else {
+ // Set position
+ WRITE_LE_UINT16(rectP, xp);
+ WRITE_LE_UINT16(rectP + 2, yp);
+ }
+}
+
+int ObjectsManager::getOffsetX(const byte *spriteData, int spriteIndex, bool isSize) {
+ const byte *v3 = spriteData + 3;
+ for (int i = spriteIndex; i; --i)
+ v3 += READ_LE_UINT32(v3) + 16;
+
+ const byte *v5 = v3 + 8;
+ int result = READ_LE_INT16(v5);
+ if (isSize)
+ result = READ_LE_INT16(v5 + 4);
+
+ return result;
+}
+
+int ObjectsManager::getOffsetY(const byte *spriteData, int spriteIndex, bool isSize) {
+ const byte *v3 = spriteData + 3;
+ for (int i = spriteIndex; i; --i)
+ v3 += READ_LE_UINT32(v3) + 16;
+
+ const byte *v5 = v3 + 10;
+ int result = READ_LE_INT16(v5);
+ if (isSize)
+ result = READ_LE_INT16(v5 + 4);
+
+ return result;
+}
+
+/**
+ * Get Width
+ */
+int ObjectsManager::getWidth(const byte *objectData, int idx) {
+ const byte *rectP = objectData + 3;
+ for (int i = idx; i; --i)
+ rectP += READ_LE_UINT32(rectP) + 16;
+
+ return READ_LE_INT16(rectP + 4);
+}
+
+/**
+ * Get height
+ */
+int ObjectsManager::getHeight(const byte *objectData, int idx) {
+ const byte *rectP = objectData + 3;
+ for (int i = idx; i; --i)
+ rectP += READ_LE_UINT32(rectP) + 16;
+
+ return READ_LE_INT16(rectP + 6);
+}
+
+void ObjectsManager::sprite_alone(const byte *objectData, byte *sprite, int objIndex) {
+ const byte *objP = objectData + 3;
+ for (int i = objIndex; i; --i) {
+ objP += READ_LE_UINT32(objP) + 16;
+ }
+
+ objP += 4;
+ int result = READ_LE_INT16(objP) * READ_LE_INT16(objP + 2);
+
+ memcpy(sprite + 3, objP - 4, result + 16);
+}
+
+void ObjectsManager::capture_mem_sprite(const byte *objectData, byte *sprite, int objIndex) {
+ const byte *objP = objectData + 3;
+ for (int i = objIndex; i; --i) {
+ objP += READ_LE_UINT32(objP) + 16;
+ }
+
+ objP += 4;
+ int result = READ_LE_INT16(objP) * READ_LE_INT16(objP + 2);
+ memcpy(sprite, objP + 12, result);
+}
+
+void ObjectsManager::removeObjectDataBuf() {
+ _vm->_globals._curObjectFileNum = 0;
+ _vm->_globals._objectDataBuf = _vm->_globals.freeMemory(_vm->_globals._objectDataBuf);
+}
+
+/**
+ * Load Sprite from file
+ */
+byte *ObjectsManager::loadSprite(const Common::String &file) {
+ return _vm->_fileManager.loadFile(file);
+}
+
+/**
+ * Add Object
+ */
+void ObjectsManager::addObject(int objIndex) {
+ int arrIndex = 0;
+ for (;;) {
+ ++arrIndex;
+ if ((!_vm->_globals._inventory[arrIndex]) || (arrIndex == 32))
+ break;;
+ }
+
+ _vm->_globals._inventory[arrIndex] = objIndex;
+}
+
+/**
+ * Display Sprite
+ */
+void ObjectsManager::displaySprite() {
+ int clipX;
+ int clipY;
+ bool loopCondFl;
+ uint16 arr[50];
+
+ // Handle copying any background areas that text are going to be drawn on
+ _vm->_globals._sortedDisplayCount = 0;
+ for (int idx = 0; idx <= 10; ++idx) {
+ if (_vm->_fontManager._textList[idx]._enabledFl && _vm->_fontManager._text[idx]._textType != 2) {
+ clipX = _vm->_fontManager._textList[idx]._pos.x - 2;
+
+ if (clipX < _vm->_graphicsManager._minX)
+ clipX = _vm->_graphicsManager._minX;
+
+ clipY = _vm->_fontManager._textList[idx]._pos.y - 2;
+ if (clipY < _vm->_graphicsManager._minY)
+ clipY = _vm->_graphicsManager._minY;
+
+ _vm->_graphicsManager.copySurface(_vm->_graphicsManager._vesaScreen, clipX, clipY,
+ _vm->_fontManager._textList[idx]._width + 4, _vm->_fontManager._textList[idx]._height + 4,
+ _vm->_graphicsManager._vesaBuffer, clipX, clipY);
+ _vm->_fontManager._textList[idx]._enabledFl = false;
+ }
+ }
+
+ if (!PERSO_ON) {
+ for (int idx = 0; idx < MAX_SPRITE; ++idx) {
+ if (_vm->_globals.Liste[idx]._visibleFl) {
+ clipX = _vm->_globals.Liste[idx]._posX - 2;
+ if (clipX < _vm->_graphicsManager._minX)
+ clipX = _vm->_graphicsManager._minX;
+
+ clipY = _vm->_globals.Liste[idx]._posY - 2;
+ if (clipY < _vm->_graphicsManager._minY)
+ clipY = _vm->_graphicsManager._minY;
+
+ _vm->_graphicsManager.copySurface(_vm->_graphicsManager._vesaScreen, clipX, clipY,
+ _vm->_globals.Liste[idx]._width + 4, _vm->_globals.Liste[idx]._height + 4,
+ _vm->_graphicsManager._vesaBuffer, clipX, clipY);
+ _vm->_globals.Liste[idx]._visibleFl = false;
+ }
+ }
+ }
+
+ displayBobAnim();
+ displayVBob();
+
+ if (!PERSO_ON) {
+ // Handle drawing characters on the screen
+ for (int idx = 0; idx < MAX_SPRITE; ++idx) {
+ _vm->_globals.Liste[idx]._visibleFl = false;
+ if (_sprite[idx]._animationType == 1) {
+ computeSprite(idx);
+ if (_sprite[idx]._activeFl)
+ beforeSort(SORT_SPRITE, idx, _sprite[idx]._height + _sprite[idx]._destY);
+ }
+ }
+
+ if (_vm->_globals._hidingActiveFl)
+ checkHidingItem();
+ }
+
+ if (_priorityFl && _vm->_globals._sortedDisplayCount) {
+ for (int i = 1; i <= 48; i++)
+ arr[i] = i;
+
+ do {
+ loopCondFl = false;
+ for (int sortIdx = 1; sortIdx < _vm->_globals._sortedDisplayCount; sortIdx++) {
+ if (_vm->_globals._sortedDisplay[arr[sortIdx]]._priority > _vm->_globals._sortedDisplay[arr[sortIdx + 1]]._priority) {
+ SWAP(arr[sortIdx], arr[sortIdx + 1]);
+ loopCondFl = true;
+ }
+ }
+ } while (loopCondFl);
+
+ for (int sortIdx = 1; sortIdx < _vm->_globals._sortedDisplayCount + 1; sortIdx++) {
+ int idx = arr[sortIdx];
+ switch (_vm->_globals._sortedDisplay[idx]._sortMode) {
+ case SORT_BOB:
+ setBobInfo(_vm->_globals._sortedDisplay[idx]._index);
+ break;
+ case SORT_SPRITE:
+ DEF_SPRITE(_vm->_globals._sortedDisplay[idx]._index);
+ break;
+ case SORT_HIDING:
+ displayHiding(_vm->_globals._sortedDisplay[idx]._index);
+ break;
+ default:
+ break;
+ }
+ _vm->_globals._sortedDisplay[idx]._sortMode = SORT_NONE;
+ }
+ } else {
+ for (int idx = 1; idx < _vm->_globals._sortedDisplayCount + 1; ++idx) {
+ switch (_vm->_globals._sortedDisplay[idx]._sortMode) {
+ case SORT_BOB:
+ setBobInfo(_vm->_globals._sortedDisplay[idx]._index);
+ break;
+ case SORT_SPRITE:
+ DEF_SPRITE(_vm->_globals._sortedDisplay[idx]._index);
+ break;
+ case SORT_HIDING:
+ displayHiding(_vm->_globals._sortedDisplay[idx]._index);
+ break;
+ default:
+ break;
+ }
+ _vm->_globals._sortedDisplay[idx]._sortMode = SORT_NONE;
+ }
+ }
+
+ // Reset the Sort array
+ for (int idx = 0; idx < 50; ++idx) {
+ _vm->_globals._sortedDisplay[idx]._sortMode = SORT_NONE;
+ _vm->_globals._sortedDisplay[idx]._index = 0;
+ _vm->_globals._sortedDisplay[idx]._priority = 0;
+ }
+
+ _vm->_globals._sortedDisplayCount = 0;
+ if (_vm->_dialogsManager._inventDisplayedFl) {
+ _vm->_graphicsManager.restoreSurfaceRect(_vm->_graphicsManager._vesaBuffer, _vm->_dialogsManager._inventWin1, _vm->_dialogsManager._inventX, _vm->_dialogsManager._inventY, _vm->_dialogsManager._inventWidth, _vm->_dialogsManager._inventHeight);
+ if (_oldBorderPos.x && _oldBorderPos.y)
+ _vm->_graphicsManager.Sprite_Vesa(_vm->_graphicsManager._vesaBuffer, _vm->_dialogsManager._inventBuf2, _oldBorderPos.x + 300, _oldBorderPos.y + 300, _oldBorderSpriteIndex + 1);
+ if (_borderPos.x && _borderPos.y)
+ _vm->_graphicsManager.Sprite_Vesa(_vm->_graphicsManager._vesaBuffer, _vm->_dialogsManager._inventBuf2, _borderPos.x + 300, _borderPos.y + 300, _borderSpriteIndex);
+ _vm->_graphicsManager.addVesaSegment(_vm->_dialogsManager._inventX, _vm->_dialogsManager._inventY, _vm->_dialogsManager._inventX + _vm->_dialogsManager._inventWidth, _vm->_dialogsManager._inventY + _vm->_dialogsManager._inventHeight);
+ }
+
+ if (_saveLoadFl) {
+ _vm->_graphicsManager.restoreSurfaceRect(_vm->_graphicsManager._vesaBuffer, _saveLoadSprite, _vm->_eventsManager._startPos.x + 183, 60, 274, 353);
+ if (_saveLoadX && _saveLoadY)
+ _vm->_graphicsManager.Sprite_Vesa(_vm->_graphicsManager._vesaBuffer, _saveLoadSprite2, _saveLoadX + _vm->_eventsManager._startPos.x + 300, _saveLoadY + 300, 0);
+
+ _vm->_graphicsManager.addVesaSegment(_vm->_eventsManager._startPos.x + 183, 60, _vm->_eventsManager._startPos.x + 457, 413);
+ }
+
+ // If the Options dialog is activated, draw the elements
+ if (_vm->_globals._optionDialogFl) {
+ _vm->_graphicsManager.Sprite_Vesa(_vm->_graphicsManager._vesaBuffer, _vm->_globals._optionDialogSpr,
+ _vm->_eventsManager._startPos.x + 464, 407, 0);
+ _vm->_graphicsManager.Sprite_Vesa(_vm->_graphicsManager._vesaBuffer, _vm->_globals._optionDialogSpr,
+ _vm->_eventsManager._startPos.x + 657, 556, _vm->_globals._menuSpeed);
+ _vm->_graphicsManager.Sprite_Vesa(_vm->_graphicsManager._vesaBuffer, _vm->_globals._optionDialogSpr,
+ _vm->_eventsManager._startPos.x + 731, 495, _vm->_globals._menuTextOff);
+ _vm->_graphicsManager.Sprite_Vesa(_vm->_graphicsManager._vesaBuffer, _vm->_globals._optionDialogSpr,
+ _vm->_eventsManager._startPos.x + 731, 468, _vm->_globals._menuVoiceOff);
+ _vm->_graphicsManager.Sprite_Vesa(_vm->_graphicsManager._vesaBuffer, _vm->_globals._optionDialogSpr,
+ _vm->_eventsManager._startPos.x + 731, 441, _vm->_globals._menuSoundOff);
+ _vm->_graphicsManager.Sprite_Vesa(_vm->_graphicsManager._vesaBuffer, _vm->_globals._optionDialogSpr,
+ _vm->_eventsManager._startPos.x + 731, 414, _vm->_globals._menuMusicOff);
+ _vm->_graphicsManager.Sprite_Vesa(_vm->_graphicsManager._vesaBuffer, _vm->_globals._optionDialogSpr,
+ _vm->_eventsManager._startPos.x + 600, 522, _vm->_globals._menuDisplayType);
+ _vm->_graphicsManager.Sprite_Vesa(_vm->_graphicsManager._vesaBuffer, _vm->_globals._optionDialogSpr,
+ _vm->_eventsManager._startPos.x + 611, 502, _vm->_globals._menuScrollSpeed);
+ _vm->_graphicsManager.addVesaSegment(_vm->_eventsManager._startPos.x + 164, 107, _vm->_eventsManager._startPos.x + 498, 320);
+ }
+
+ // Loop to draw any on-screen text
+ for (int idx = 0; idx <= 10; ++idx) {
+ if (_vm->_fontManager._text[idx]._textOnFl) {
+ if ((_vm->_fontManager._text[idx]._textType < 2) || (_vm->_fontManager._text[idx]._textType > 3))
+ _vm->_fontManager.box(idx,
+ _vm->_fontManager._text[idx]._messageId, _vm->_fontManager._text[idx]._filename,
+ _vm->_eventsManager._startPos.x + _vm->_fontManager._text[idx]._pos.x, _vm->_fontManager._text[idx]._pos.y);
+ else
+ _vm->_fontManager.box(idx,
+ _vm->_fontManager._text[idx]._messageId, _vm->_fontManager._text[idx]._filename,
+ _vm->_fontManager._text[idx]._pos.x, _vm->_fontManager._text[idx]._pos.y);
+ _vm->_fontManager._textList[idx]._enabledFl = true;
+
+ if ((_vm->_fontManager._text[idx]._textType < 2) || (_vm->_fontManager._text[idx]._textType > 3))
+ _vm->_fontManager._textList[idx]._pos.x = _vm->_eventsManager._startPos.x + _vm->_fontManager._text[idx]._pos.x;
+ else
+ _vm->_fontManager._textList[idx]._pos.x = _vm->_fontManager._text[idx]._pos.x;
+
+ _vm->_fontManager._textList[idx]._pos.y = _vm->_fontManager._text[idx]._pos.y;
+ _vm->_fontManager._textList[idx]._width = _vm->_fontManager._text[idx]._width;
+ _vm->_fontManager._textList[idx]._height = _vm->_fontManager._text[idx]._height;
+
+ if (_vm->_fontManager._textList[idx]._pos.x < _vm->_graphicsManager._minX)
+ _vm->_fontManager._textList[idx]._pos.x = _vm->_graphicsManager._minX - 1;
+ if (_vm->_fontManager._textList[idx]._pos.y < _vm->_graphicsManager._minY)
+ _vm->_fontManager._textList[idx]._pos.y = _vm->_graphicsManager._minY - 1;
+
+ int posX = _vm->_fontManager._textList[idx]._pos.x;
+ if (_vm->_fontManager._textList[idx]._width + posX > _vm->_graphicsManager._maxX)
+ _vm->_fontManager._textList[idx]._width = _vm->_graphicsManager._maxX - posX;
+ int posY = _vm->_fontManager._textList[idx]._pos.y;
+ if (_vm->_fontManager._textList[idx]._height + posY > _vm->_graphicsManager._maxY)
+ _vm->_fontManager._textList[idx]._height = _vm->_graphicsManager._maxY - posY;
+ if (_vm->_fontManager._textList[idx]._width <= 0 || _vm->_fontManager._textList[idx]._height <= 0)
+ _vm->_fontManager._textList[idx]._enabledFl = false;
+ }
+ }
+
+ _vm->_dialogsManager.inventAnim();
+}
+
+void ObjectsManager::initBob() {
+ for (int idx = 0; idx < 35; ++idx)
+ resetBob(idx);
+}
+
+void ObjectsManager::resetBob(int idx) {
+ BobItem &bob = _bob[idx];
+ ListeItem &item = _vm->_globals.Liste2[idx];
+
+ bob.field0 = 0;
+ bob._spriteData = g_PTRNUL;
+ bob._xp = 0;
+ bob._yp = 0;
+ bob._frameIndex = 0;
+ bob._animDataIdx = 0;
+ bob.field12 = 0;
+ bob.field14 = 0;
+ bob._disabledAnimationFl = false;
+ bob._animData = g_PTRNUL;
+ bob.field1C = false;
+ bob.field1E = 0;
+ bob.field20 = 0;
+ bob.field22 = 0;
+ bob.field34 = false;
+ bob._zoomFactor = 0;
+ bob._flipFl = false;
+ bob._oldX2 = 0;
+
+ item._visibleFl = false;
+ item._posX = 0;
+ item._posY = 0;
+ item._width = 0;
+ item._height = 0;
+}
+
+void ObjectsManager::setBobInfo(int idx) {
+ if (!_bob[idx]._activeFl)
+ return;
+
+ int xp = _bob[idx]._oldX;
+ int yp = _bob[idx]._oldY;
+
+ if (_bob[idx]._isSpriteFl)
+ _vm->_graphicsManager.Sprite_Vesa(_vm->_graphicsManager._vesaBuffer, _bob[idx]._spriteData,
+ xp + 300, yp + 300, _bob[idx]._frameIndex);
+ else
+ _vm->_graphicsManager.Affiche_Perfect(_vm->_graphicsManager._vesaBuffer,
+ _bob[idx]._spriteData, xp + 300, yp + 300, _bob[idx]._frameIndex,
+ _bob[idx]._zoomOutFactor, _bob[idx]._zooInmFactor,
+ _bob[idx]._flipFl);
+
+ _vm->_globals.Liste2[idx]._visibleFl = true;
+ _vm->_globals.Liste2[idx]._posX = xp;
+ _vm->_globals.Liste2[idx]._posY = yp;
+
+ _vm->_globals.Liste2[idx]._width = _bob[idx]._oldWidth;
+ _vm->_globals.Liste2[idx]._height = _bob[idx]._oldHeight;
+
+ if (_vm->_globals.Liste2[idx]._posX < _vm->_graphicsManager._minX) {
+ _vm->_globals.Liste2[idx]._width -= _vm->_graphicsManager._minX - _vm->_globals.Liste2[idx]._posX;
+ _vm->_globals.Liste2[idx]._posX = _vm->_graphicsManager._minX;
+ }
+
+ if (_vm->_globals.Liste2[idx]._posY < _vm->_graphicsManager._minY) {
+ _vm->_globals.Liste2[idx]._height -= _vm->_graphicsManager._minY - _vm->_globals.Liste2[idx]._posY;
+ _vm->_globals.Liste2[idx]._posY = _vm->_graphicsManager._minY;
+ }
+
+ if (_vm->_globals.Liste2[idx]._width + _vm->_globals.Liste2[idx]._posX > _vm->_graphicsManager._maxX)
+ _vm->_globals.Liste2[idx]._width = _vm->_graphicsManager._maxX - _vm->_globals.Liste2[idx]._posX;
+
+ if (_vm->_globals.Liste2[idx]._height + _vm->_globals.Liste2[idx]._posY > _vm->_graphicsManager._maxY)
+ _vm->_globals.Liste2[idx]._height = _vm->_graphicsManager._maxY - _vm->_globals.Liste2[idx]._posY;
+
+ if (_vm->_globals.Liste2[idx]._width <= 0 || _vm->_globals.Liste2[idx]._height <= 0)
+ _vm->_globals.Liste2[idx]._visibleFl = false;
+
+ if (_vm->_globals.Liste2[idx]._visibleFl)
+ _vm->_graphicsManager.addVesaSegment(
+ _vm->_globals.Liste2[idx]._posX,
+ _vm->_globals.Liste2[idx]._posY,
+ _vm->_globals.Liste2[idx]._posX + _vm->_globals.Liste2[idx]._width,
+ _vm->_globals.Liste2[idx]._posY + _vm->_globals.Liste2[idx]._height);
+}
+
+void ObjectsManager::displayBob(int idx) {
+ _priorityFl = true;
+
+ if (_bob[idx].field0)
+ return;
+
+ resetBob(idx);
+
+ const byte *data = _vm->_globals._animBqe[idx]._data;
+ int bankIdx = READ_LE_INT16(data);
+ if (!bankIdx)
+ return;
+ if ((!_vm->_globals.Bank[bankIdx]._loadedFl) || (!READ_LE_UINT16(data + 24)))
+ return;
+
+
+ int16 v9 = READ_LE_INT16(data + 2);
+ int16 v8 = READ_LE_INT16(data + 4);
+ // data[6] isn't used, read skipped
+ int16 v6 = READ_LE_INT16(data + 8);
+
+ if (!v9)
+ v9 = 1;
+ if (!v6)
+ v6 = -1;
+
+ _bob[idx]._isSpriteFl = false;
+
+ if (_vm->_globals.Bank[bankIdx]._fileHeader == 1) {
+ _bob[idx]._isSpriteFl = true;
+ _bob[idx]._zoomFactor = 0;
+ _bob[idx]._flipFl = false;
+ }
+
+ _bob[idx]._animData = _vm->_globals._animBqe[idx]._data;
+ _bob[idx].field0 = 10;
+ _bob[idx]._spriteData = _vm->_globals.Bank[bankIdx]._data;
+
+ _bob[idx].field1E = v9;
+ _bob[idx].field20 = v6;
+ _bob[idx].field22 = v8;
+}
+
+void ObjectsManager::hideBob(int idx) {
+ if ((_bob[idx].field0 == 3) || (_bob[idx].field0 == 10))
+ _bob[idx].field0++;
+}
+
+void ObjectsManager::BOB_OFFSET(int idx, int offset) {
+ _bob[idx]._oldX2 = offset;
+}
+
+void ObjectsManager::SCBOB(int idx) {
+ HidingItem *hid = &_vm->_globals._hidingItem[idx];
+ if (hid->_useCount == 0)
+ return;
+
+ for (int i = 0; i <= 20; i++) {
+ if ((_bob[i].field0) && (!_bob[i]._disabledAnimationFl) && (!_bob[i].field34) && (_bob[i]._frameIndex != 250)) {
+ int oldRight = _bob[i]._oldX + _bob[i]._oldWidth;
+ int oldBottom = _bob[i]._oldY + _bob[i]._oldHeight;
+ int cachedRight = hid->_width + hid->_x;
+
+ if ((oldBottom > hid->_y) && (oldBottom < hid->field14 +hid->_height + hid->_y)) {
+ if ((oldRight >= hid->_x && oldRight <= cachedRight)
+ || (cachedRight >= _bob[i]._oldWidth && _bob[i]._oldWidth >= hid->_x)
+ || (cachedRight >= _bob[i]._oldWidth && _bob[i]._oldWidth >= hid->_x)
+ || (_bob[i]._oldWidth >= hid->_x && oldRight <= cachedRight)
+ || (_bob[i]._oldWidth <= hid->_x && oldRight >= cachedRight))
+ ++hid->_useCount;
+ }
+ }
+ }
+}
+
+void ObjectsManager::CALCUL_BOB(int idx) {
+ _bob[idx]._activeFl = false;
+ if (_bob[idx]._isSpriteFl) {
+ _bob[idx]._flipFl = false;
+ _bob[idx]._zoomFactor = 0;
+ }
+
+ int spriteIdx = _bob[idx]._frameIndex;
+ if (spriteIdx == 250)
+ return;
+
+ int deltaY, deltaX;
+ if (_bob[idx]._flipFl) {
+ deltaX = getOffsetX(_bob[idx]._spriteData, spriteIdx, true);
+ deltaY = getOffsetY(_bob[idx]._spriteData, _bob[idx]._frameIndex, true);
+ } else {
+ deltaX = getOffsetX(_bob[idx]._spriteData, spriteIdx, false);
+ deltaY = getOffsetY(_bob[idx]._spriteData, _bob[idx]._frameIndex, false);
+ }
+
+ int negZoom = 0;
+ int posZoom = 0;
+ if (_bob[idx]._zoomFactor < 0) {
+ negZoom = -_bob[idx]._zoomFactor;
+ if (negZoom > 95)
+ negZoom = 95;
+ } else
+ posZoom = _bob[idx]._zoomFactor;
+
+ if (posZoom) {
+ if (deltaX >= 0)
+ deltaX = _vm->_graphicsManager.zoomIn(deltaX, posZoom);
+ else
+ deltaX = -_vm->_graphicsManager.zoomIn(-deltaX, posZoom);
+
+ if (deltaY >= 0)
+ deltaY = _vm->_graphicsManager.zoomIn(deltaY, posZoom);
+ else
+ deltaY = -_vm->_graphicsManager.zoomIn(abs(deltaX), posZoom);
+ }
+
+ if (negZoom) {
+ if (deltaX >= 0)
+ deltaX = _vm->_graphicsManager.zoomOut(deltaX, negZoom);
+ else
+ deltaX = -_vm->_graphicsManager.zoomOut(-deltaX, negZoom);
+
+ if (deltaY >= 0)
+ deltaY = _vm->_graphicsManager.zoomOut(deltaY, negZoom);
+ else
+ deltaY = -_vm->_graphicsManager.zoomOut(abs(deltaX), negZoom);
+ }
+
+ int newX = _bob[idx]._xp - deltaX;
+ int newY = _bob[idx]._yp - deltaY;
+ _bob[idx]._activeFl = true;
+ _bob[idx]._oldX = newX;
+ _bob[idx]._oldY = newY;
+ _bob[idx]._zooInmFactor = posZoom;
+ _bob[idx]._zoomOutFactor = negZoom;
+
+ _vm->_globals.Liste2[idx]._visibleFl = true;
+ _vm->_globals.Liste2[idx]._posX = newX;
+ _vm->_globals.Liste2[idx]._posY = newY;
+
+ int width = getWidth(_bob[idx]._spriteData, _bob[idx]._frameIndex);
+ int height = getHeight(_bob[idx]._spriteData, _bob[idx]._frameIndex);
+
+ if (posZoom) {
+ width = _vm->_graphicsManager.zoomIn(width, posZoom);
+ height = _vm->_graphicsManager.zoomIn(height, posZoom);
+ }
+ if (negZoom) {
+ height = _vm->_graphicsManager.zoomOut(height, negZoom);
+ width = _vm->_graphicsManager.zoomOut(width, negZoom);
+ }
+
+ _vm->_globals.Liste2[idx]._width = width;
+ _vm->_globals.Liste2[idx]._height = height;
+ _bob[idx]._oldWidth = width;
+ _bob[idx]._oldHeight = height;
+}
+
+void ObjectsManager::checkHidingItem() {
+ for (int hidingItemIdx = 0; hidingItemIdx <= 19; hidingItemIdx++) {
+ HidingItem *hid = &_vm->_globals._hidingItem[hidingItemIdx];
+ if (hid->_useCount == 0)
+ continue;
+
+ int _oldUseCount = hid->_useCount;
+ for (int spriteIdx = 0; spriteIdx <= 4; spriteIdx++) {
+ const SpriteItem *spr = &_sprite[spriteIdx];
+ if (spr->_animationType == 1 && spr->_spriteIndex != 250) {
+ int right = spr->_width + spr->_destX;
+ int bottom = spr->_height + spr->_destY;
+ int hidingRight = hid->_width + hid->_x;
+
+ if (bottom > hid->_y && bottom < (hid->field14 + hid->_height + hid->_y)) {
+ if ((right >= hid->_x && right <= hidingRight)
+ || (hidingRight >= spr->_destX && hid->_x <= spr->_destX)
+ || (hidingRight >= spr->_destX && hid->_x <= spr->_destX)
+ || (hid->_x <= spr->_destX && right <= hidingRight)
+ || (hid->_x >= spr->_destX && right >= hidingRight))
+ ++hid->_useCount;
+ }
+ }
+ }
+
+ SCBOB(hidingItemIdx);
+ if (hid->_useCount != _oldUseCount) {
+ int priority = hid->field14 + hid->_height + hid->_y;
+ if (priority > 440)
+ priority = 500;
+
+ beforeSort(SORT_HIDING, hidingItemIdx, priority);
+ hid->_useCount = 1;
+ hid->field10 = true;
+ } else if (hid->field10) {
+ hid->field10 = false;
+ hid->_useCount = 1;
+ }
+
+ }
+}
+
+void ObjectsManager::DEF_SPRITE(int idx) {
+ SpriteItem *spr = &_sprite[idx];
+ if (!spr->_activeFl)
+ return;
+
+ if (spr->_rleFl)
+ _vm->_graphicsManager.Sprite_Vesa(_vm->_graphicsManager._vesaBuffer, spr->_spriteData,
+ spr->_destX + 300, spr->_destY + 300, spr->_spriteIndex);
+ else
+ _vm->_graphicsManager.Affiche_Perfect(_vm->_graphicsManager._vesaBuffer, spr->_spriteData,
+ spr->_destX + 300, spr->_destY + 300, spr->_spriteIndex, spr->_reducePct, spr->_zoomPct, spr->_flipFl);
+
+ ListeItem *list = &_vm->_globals.Liste[idx];
+ list->_width = spr->_width;
+ list->_height = spr->_height;
+
+ if (list->_posX < _vm->_graphicsManager._minX) {
+ list->_width -= _vm->_graphicsManager._minX - list->_posX;
+ list->_posX = _vm->_graphicsManager._minX;
+ }
+
+ if (list->_posY < _vm->_graphicsManager._minY) {
+ list->_height -= _vm->_graphicsManager._minY - list->_posY;
+ list->_posY = _vm->_graphicsManager._minY;
+ }
+
+ if (list->_width + list->_posX > _vm->_graphicsManager._maxX)
+ list->_width = _vm->_graphicsManager._maxX - list->_posX;
+
+ if (list->_height + list->_posY > _vm->_graphicsManager._maxY)
+ list->_height = _vm->_graphicsManager._maxY - list->_posY;
+
+ if (list->_width <= 0 || list->_height <= 0)
+ list->_visibleFl = false;
+
+ if (list->_visibleFl)
+ _vm->_graphicsManager.addVesaSegment( list->_posX, list->_posY, list->_posX + list->_width, list->_posY + list->_height);
+}
+
+void ObjectsManager::displayHiding(int idx) {
+ HidingItem *hid = &_vm->_globals._hidingItem[idx];
+
+ _vm->_graphicsManager.Sprite_Vesa(_vm->_graphicsManager._vesaBuffer, _vm->_globals._hidingItemData[1],
+ hid->_x + 300, hid->_y + 300, hid->_spriteIndex);
+ _vm->_graphicsManager.addVesaSegment(hid->_x, hid->_y, hid->_x + hid->_width, hid->_y + hid->_height);
+}
+
+// Compute Sprite
+void ObjectsManager::computeSprite(int idx) {
+ SpriteItem *spr = &_sprite[idx];
+
+ spr->_activeFl = false;
+ int spriteIndex = spr->_spriteIndex;
+ if (spriteIndex == 250)
+ return;
+
+ int offX;
+ int offY;
+ if (spr->_flipFl) {
+ offX = getOffsetX(spr->_spriteData, spriteIndex, true);
+ offY = getOffsetY(spr->_spriteData, spr->_spriteIndex, true);
+ } else {
+ offX = getOffsetX(spr->_spriteData, spriteIndex, false);
+ offY = getOffsetY(spr->_spriteData, spr->_spriteIndex, false);
+ }
+
+ int tmpX = spr->field12 + offX;
+ int deltaX = tmpX;
+ int tmpY = spr->field14 + offY;
+ int deltaY = tmpY;
+ int zoomPercent = 0;
+ int reducePercent = 0;
+
+ if (spr->_zoomFactor < 0) {
+ reducePercent = -spr->_zoomFactor;
+ if (reducePercent > 95)
+ reducePercent = 95;
+ } else
+ zoomPercent = spr->_zoomFactor;
+
+ if (zoomPercent) {
+ if (tmpX >= 0)
+ deltaX = _vm->_graphicsManager.zoomIn(tmpX, zoomPercent);
+ else
+ deltaX = -_vm->_graphicsManager.zoomIn(-tmpX, zoomPercent);
+
+ if (tmpY >= 0) {
+ deltaY = _vm->_graphicsManager.zoomIn(tmpY, zoomPercent);
+ } else {
+ tmpY = abs(tmpX);
+ deltaY = -_vm->_graphicsManager.zoomIn(tmpY, zoomPercent);
+ }
+ } else if (reducePercent) {
+ if (tmpX >= 0)
+ deltaX = _vm->_graphicsManager.zoomOut(tmpX, reducePercent);
+ else
+ deltaX = -_vm->_graphicsManager.zoomOut(-tmpX, reducePercent);
+
+ if (tmpY >= 0) {
+ deltaY = _vm->_graphicsManager.zoomOut(tmpY, reducePercent);
+ } else {
+ tmpY = abs(tmpX);
+ deltaY = -_vm->_graphicsManager.zoomOut(tmpY, reducePercent);
+ }
+ }
+
+ int newPosX = spr->_spritePos.x - deltaX;
+ int newPosY = spr->_spritePos.y - deltaY;
+ spr->_destX = newPosX;
+ spr->_destY = newPosY;
+ spr->_activeFl = true;
+ spr->_zoomPct = zoomPercent;
+ spr->_reducePct = reducePercent;
+
+ _vm->_globals.Liste[idx]._visibleFl = true;
+ _vm->_globals.Liste[idx]._posX = newPosX;
+ _vm->_globals.Liste[idx]._posY = newPosY;
+
+ int width = getWidth(spr->_spriteData, spr->_spriteIndex);
+ int height = getHeight(spr->_spriteData, spr->_spriteIndex);
+
+ if (zoomPercent) {
+ width = _vm->_graphicsManager.zoomIn(width, zoomPercent);
+ height = _vm->_graphicsManager.zoomIn(height, zoomPercent);
+ } else if (reducePercent) {
+ height = _vm->_graphicsManager.zoomOut(height, reducePercent);
+ width = _vm->_graphicsManager.zoomOut(width, reducePercent);
+ }
+
+ spr->_width = width;
+ spr->_height = height;
+}
+
+// Before Sort
+void ObjectsManager::beforeSort(SortMode sortMode, int index, int priority) {
+ ++_vm->_globals._sortedDisplayCount;
+ assert (_vm->_globals._sortedDisplayCount <= 48);
+
+ _vm->_globals._sortedDisplay[_vm->_globals._sortedDisplayCount]._sortMode = sortMode;
+ _vm->_globals._sortedDisplay[_vm->_globals._sortedDisplayCount]._index = index;
+ _vm->_globals._sortedDisplay[_vm->_globals._sortedDisplayCount]._priority = priority;
+}
+
+// Display BOB Anim
+void ObjectsManager::displayBobAnim() {
+ for (int idx = 1; idx <= 35; idx++) {
+ if (idx <= 20 && PERSO_ON) {
+ _bob[idx].field1C = false;
+ continue;
+ }
+
+ if (_bob[idx].field0 != 10)
+ continue;
+
+ _bob[idx].field1C = false;
+ int v1 = _bob[idx].field20;
+ if (v1 == -1)
+ v1 = 50;
+ if (_bob[idx]._animData == g_PTRNUL || _bob[idx]._disabledAnimationFl || v1 <= 0) {
+ if (_bob[idx].field1E == 1 || _bob[idx].field1E == 2)
+ _bob[idx].field1C = true;
+ continue;
+ }
+
+ if (_bob[idx].field12 == _bob[idx].field14) {
+ _bob[idx].field1C = true;
+ } else {
+ _bob[idx].field14++;
+ _bob[idx].field1C = false;
+ }
+
+ if (!_bob[idx].field1C) {
+ if (_bob[idx].field1E == 1 || _bob[idx].field1E == 2)
+ _bob[idx].field1C = true;
+ continue;
+ }
+
+ byte *dataPtr = _bob[idx]._animData + 20;
+ int dataIdx = _bob[idx]._animDataIdx;
+ _bob[idx]._xp = READ_LE_INT16(dataPtr + 2 * dataIdx);
+ if (_vm->_globals._lockedAnims[idx]._enableFl)
+ _bob[idx]._xp = _vm->_globals._lockedAnims[idx]._posX;
+ if ( PERSO_ON && idx > 20 )
+ _bob[idx]._xp += _vm->_eventsManager._startPos.x;
+
+ _bob[idx]._yp = READ_LE_INT16(dataPtr + 2 * dataIdx + 2);
+ _bob[idx].field12 = READ_LE_INT16(dataPtr + 2 * dataIdx + 4);
+ _bob[idx]._zoomFactor = READ_LE_INT16(dataPtr + 2 * dataIdx + 6);
+ _bob[idx]._frameIndex = dataPtr[2 * dataIdx + 8];
+ _bob[idx]._flipFl = (dataPtr[2 * dataIdx + 9] != 0);
+ _bob[idx]._animDataIdx += 5;
+
+ int v5 = _bob[idx].field12;
+ if (v5 > 0) {
+ int v6 = v5 / _vm->_globals._speed;
+ _bob[idx].field12 = v5 / _vm->_globals._speed;
+ if (v6 > 0) {
+ _bob[idx].field14 = 1;
+ if (_bob[idx].field1E == 1 || _bob[idx].field1E == 2)
+ _bob[idx].field1C = true;
+ continue;
+ }
+
+ _bob[idx].field12 = 1;
+ }
+ if (!_bob[idx].field12) {
+ if (_bob[idx].field20 > 0)
+ _bob[idx].field20--;
+ if (_bob[idx].field20 != -1 && _bob[idx].field20 <= 0) {
+ _bob[idx].field0 = 11;
+ } else {
+ _bob[idx]._animDataIdx = 0;
+ byte *v21 = _bob[idx]._animData + 20;
+ _bob[idx]._xp = READ_LE_INT16(v21);
+
+ if (_vm->_globals._lockedAnims[idx]._enableFl)
+ _bob[idx]._xp = _vm->_globals._lockedAnims[idx]._posX;
+ if (PERSO_ON && idx > 20)
+ _bob[idx]._xp += _vm->_eventsManager._startPos.x;
+
+ _bob[idx]._yp = READ_LE_INT16(v21 + 2);
+ _bob[idx].field12 = READ_LE_INT16(v21 + 4);
+ _bob[idx]._zoomFactor = READ_LE_INT16(v21 + 6);
+ _bob[idx]._frameIndex = v21[8];
+ _bob[idx]._flipFl = (v21[9] != 0);
+ _bob[idx]._animDataIdx += 5;
+ int v10 = _bob[idx].field12;
+
+ if (v10 > 0) {
+ int v11 = v10 / _vm->_globals._speed;
+ _bob[idx].field12 = v11;
+ // Original code. It can't be negative, so the check is on == 0
+ if (v11 <= 0)
+ _bob[idx].field12 = 1;
+ }
+ }
+ }
+
+ _bob[idx].field14 = 1;
+ if (_bob[idx].field1E == 1 || _bob[idx].field1E == 2)
+ _bob[idx].field1C = true;
+ }
+
+ if (!PERSO_ON && BOBTOUS) {
+ for (int i = 0; i < 35; i++) {
+ if (_bob[i].field0 == 10 && !_bob[i]._disabledAnimationFl)
+ _bob[i].field1C = true;
+ }
+ }
+
+ BOBTOUS = false;
+
+ for (int i = 1; i <= 35; i++) {
+ if (i > 20 || !PERSO_ON) {
+ if ((_bob[i].field0 == 10) && (_bob[i].field1C)) {
+ if ((_bob[i].field1E != 2) && (_bob[i].field1E != 4)) {
+ if (_vm->_globals.Liste2[i]._visibleFl) {
+ _vm->_graphicsManager.copySurface(_vm->_graphicsManager._vesaScreen,
+ _vm->_globals.Liste2[i]._posX, _vm->_globals.Liste2[i]._posY,
+ _vm->_globals.Liste2[i]._width, _vm->_globals.Liste2[i]._height,
+ _vm->_graphicsManager._vesaBuffer, _vm->_globals.Liste2[i]._posX,
+ _vm->_globals.Liste2[i]._posY);
+ _vm->_globals.Liste2[i]._visibleFl = false;
+ }
+ }
+ }
+
+ if (_bob[i].field0 == 11) {
+ if (_vm->_globals.Liste2[i]._visibleFl) {
+ _vm->_graphicsManager.copySurface(_vm->_graphicsManager._vesaScreen,
+ _vm->_globals.Liste2[i]._posX, _vm->_globals.Liste2[i]._posY,
+ _vm->_globals.Liste2[i]._width, _vm->_globals.Liste2[i]._height,
+ _vm->_graphicsManager._vesaBuffer,
+ _vm->_globals.Liste2[i]._posX, _vm->_globals.Liste2[i]._posY);
+ _vm->_globals.Liste2[i]._visibleFl = false;
+ }
+
+ _bob[i].field0 = 0;
+ }
+ }
+ }
+
+ for (int i = 1; i <= 35; i++) {
+ _bob[i]._oldY = 0;
+ if (_bob[i].field0 == 10 && !_bob[i]._disabledAnimationFl && _bob[i].field1C) {
+ CALCUL_BOB(i);
+ int v19 = _bob[i]._oldX2 + _bob[i]._oldHeight + _bob[i]._oldY;
+
+ if (v19 > 450)
+ v19 = 600;
+
+ if (_bob[i]._activeFl)
+ beforeSort(SORT_BOB, i, v19);
+ }
+ }
+}
+
+// Display VBOB
+void ObjectsManager::displayVBob() {
+ int width, height;
+
+ for (int idx = 0; idx <= 29; idx++) {
+ VBobItem *vbob = &_vm->_globals.VBob[idx];
+ if (vbob->field4 == 4) {
+ width = getWidth(vbob->_spriteData, vbob->_frameIndex);
+ height = getHeight(vbob->_spriteData, vbob->_frameIndex);
+
+ _vm->_graphicsManager.restoreSurfaceRect(_vm->_graphicsManager._vesaScreen, vbob->_surface,
+ vbob->_xp, vbob->_yp, width, height);
+
+ _vm->_graphicsManager.restoreSurfaceRect(_vm->_graphicsManager._vesaBuffer, vbob->_surface,
+ vbob->_xp, vbob->_yp, width, height);
+
+ _vm->_graphicsManager.addVesaSegment(vbob->_xp, vbob->_yp, vbob->_xp + width, height + vbob->_yp);
+ vbob->_surface = _vm->_globals.freeMemory(vbob->_surface);
+
+ vbob->field4 = 0;
+ vbob->_spriteData = g_PTRNUL;
+ vbob->_xp = 0;
+ vbob->_yp = 0;
+ vbob->_oldX = 0;
+ vbob->_oldY = 0;
+ vbob->_frameIndex = 0;
+ vbob->_oldFrameIndex = 0;
+ vbob->_oldSpriteData = g_PTRNUL;
+ }
+
+ if (vbob->field4 == 3) {
+ width = getWidth(vbob->_oldSpriteData, vbob->_oldFrameIndex);
+ height = getHeight(vbob->_oldSpriteData, vbob->_oldFrameIndex);
+
+ _vm->_graphicsManager.restoreSurfaceRect(_vm->_graphicsManager._vesaScreen, vbob->_surface,
+ vbob->_oldX, vbob->_oldY, width, height);
+
+ _vm->_graphicsManager.restoreSurfaceRect(_vm->_graphicsManager._vesaBuffer, vbob->_surface,
+ vbob->_oldX, vbob->_oldY, width, height);
+
+ _vm->_graphicsManager.addVesaSegment(vbob->_oldX, vbob->_oldY, vbob->_oldX + width, vbob->_oldY + height);
+
+ vbob->field4 = 1;
+ vbob->_oldSpriteData = vbob->_spriteData;
+
+ vbob->_surface = _vm->_globals.freeMemory(vbob->_surface);
+
+ vbob->_oldX = vbob->_xp;
+ vbob->_oldY = vbob->_yp;
+ vbob->_oldFrameIndex = vbob->_frameIndex;
+ }
+
+ if (vbob->field4 == 1) {
+ width = getWidth(vbob->_spriteData, vbob->_frameIndex);
+ height = getHeight(vbob->_spriteData, vbob->_frameIndex);
+
+ vbob->_surface = _vm->_globals.freeMemory(vbob->_surface);
+
+ byte *surface = _vm->_globals.allocMemory(height * width);
+ vbob->_surface = surface;
+
+ _vm->_graphicsManager.copySurfaceRect(_vm->_graphicsManager._vesaScreen, surface,
+ vbob->_xp, vbob->_yp, width, height);
+
+ byte *v10 = vbob->_spriteData;
+ if (*v10 == 78) {
+ _vm->_graphicsManager.Affiche_Perfect(_vm->_graphicsManager._vesaScreen, v10,
+ vbob->_xp + 300, vbob->_yp + 300, vbob->_frameIndex, 0, 0, false);
+
+ _vm->_graphicsManager.Affiche_Perfect(_vm->_graphicsManager._vesaBuffer, vbob->_spriteData,
+ vbob->_xp + 300, vbob->_yp + 300, vbob->_frameIndex, 0, 0, false);
+ } else {
+ _vm->_graphicsManager.Sprite_Vesa(_vm->_graphicsManager._vesaBuffer, v10,
+ vbob->_xp + 300, vbob->_yp + 300, vbob->_frameIndex);
+
+ _vm->_graphicsManager.Sprite_Vesa(_vm->_graphicsManager._vesaScreen, vbob->_spriteData,
+ vbob->_xp + 300, vbob->_yp + 300, vbob->_frameIndex);
+ }
+
+ _vm->_graphicsManager.addVesaSegment(vbob->_xp, vbob->_yp , vbob->_xp + width, vbob->_yp + height);
+ vbob->field4 = 2;
+ }
+ }
+}
+
+/**
+ * Get Sprite X coordinate
+ */
+int ObjectsManager::getSpriteX(int idx) {
+ assert (idx <= MAX_SPRITE);
+ return _sprite[idx]._spritePos.x;
+}
+
+/**
+ * Get Sprite Y coordinate
+ */
+int ObjectsManager::getSpriteY(int idx) {
+ assert (idx <= MAX_SPRITE);
+ return _sprite[idx]._spritePos.y;
+}
+
+/**
+ * Clear sprite structure
+ */
+void ObjectsManager::clearSprite() {
+ for (int idx = 0; idx < MAX_SPRITE; idx++) {
+ _sprite[idx]._spriteData = g_PTRNUL;
+ _sprite[idx]._animationType = 0;
+ }
+
+ for (int idx = 0; idx < MAX_SPRITE; idx++) {
+ ListeItem *list = &_vm->_globals.Liste[idx];
+ list->_visibleFl = false;
+ list->_posX = 0;
+ list->_posY = 0;
+ list->_width = 0;
+ list->_height = 0;
+ }
+}
+
+void ObjectsManager::animateSprite(int idx) {
+ assert (idx <= MAX_SPRITE);
+ _sprite[idx]._animationType = 1;
+}
+
+void ObjectsManager::addStaticSprite(const byte *spriteData, Common::Point pos, int idx, int spriteIndex, int zoomFactor, bool flipFl, int a8, int a9) {
+ assert (idx <= MAX_SPRITE);
+
+ SpriteItem *spr = &_sprite[idx];
+ spr->_spriteData = spriteData;
+ spr->_spritePos = pos;
+ spr->_spriteIndex = spriteIndex;
+ spr->_zoomFactor = zoomFactor;
+ spr->_flipFl = flipFl;
+ spr->field12 = a8;
+ spr->field14 = a9;
+ spr->_animationType = 0;
+
+ if (READ_BE_UINT24(spriteData) == MKTAG24('R', 'L', 'E')) {
+ spr->_rleFl = true;
+ spr->_zoomFactor = 0;
+ spr->_flipFl = false;
+ } else
+ spr->_rleFl = false;
+
+}
+
+/**
+ * Freeze sprite animation and free its memory
+ */
+void ObjectsManager::removeSprite(int idx) {
+ // Type 3 was also used by freeSprite(), which has been removed as it wasn't used
+ _sprite[idx]._animationType = 3;
+}
+
+/**
+ * Set Sprite X coordinate
+ */
+void ObjectsManager::setSpriteX(int idx, int xp) {
+ assert (idx <= MAX_SPRITE);
+ _sprite[idx]._spritePos.x = xp;
+}
+
+/**
+ * Set Sprite Y coordinate
+ */
+void ObjectsManager::setSpriteY(int idx, int yp) {
+ assert (idx <= MAX_SPRITE);
+ _sprite[idx]._spritePos.y = yp;
+}
+
+/**
+ * Set Sprite Index
+ */
+void ObjectsManager::setSpriteIndex(int idx, int spriteIndex) {
+ assert (idx <= MAX_SPRITE);
+ _sprite[idx]._spriteIndex = spriteIndex;
+}
+
+// Set Sprite Size
+void ObjectsManager::setSpriteZoom(int idx, int zoomFactor) {
+ assert (idx <= MAX_SPRITE);
+ if (!_sprite[idx]._rleFl)
+ _sprite[idx]._zoomFactor = zoomFactor;
+}
+
+void ObjectsManager::setFlipSprite(int idx, bool flipFl) {
+ assert (idx <= MAX_SPRITE);
+ if (!_sprite[idx]._rleFl)
+ _sprite[idx]._flipFl = flipFl;
+}
+
+void ObjectsManager::GOHOME() {
+ if (_vm->_linesManager._route == (RouteItem *)g_PTRNUL)
+ return;
+
+ if (_vm->_globals.Compteur > 1) {
+ --_vm->_globals.Compteur;
+ return;
+ }
+
+ int newPosX;
+ int newPosY;
+ Directions newDirection;
+
+ int oldPosX = 0;
+ int oldPosY = 0;
+ int oldFrameIdx = 0;
+ _vm->_globals.Compteur = 0;
+ if (_vm->_globals._oldDirection == DIR_NONE) {
+ computeAndSetSpriteSize();
+ newPosX = _vm->_linesManager._route->_x;
+ newPosY = _vm->_linesManager._route->_y;
+ newDirection = _vm->_linesManager._route->_dir;
+ _vm->_linesManager._route++;
+
+ if (newPosX != -1 || newPosY != -1) {
+ _vm->_globals._oldDirection = newDirection;
+ _vm->_globals._oldDirectionSpriteIdx = newDirection + 59;
+ _vm->_globals._oldFrameIndex = 0;
+ _oldCharacterPosX = newPosX;
+ _oldCharacterPosY = newPosY;
+ } else {
+ setSpriteIndex(0, _vm->_globals._oldDirection + 59);
+ _vm->_globals._actionDirection = DIR_NONE;
+ int zoneId;
+ if (_vm->_globals._actionMoveTo)
+ zoneId = _vm->_globals._saveData->_data[svField2];
+ else
+ zoneId = _zoneNum;
+ _vm->_linesManager._route = (RouteItem *)g_PTRNUL;
+ computeAndSetSpriteSize();
+ setFlipSprite(0, false);
+ _vm->_globals.Compteur = 0;
+ _vm->_linesManager._route = (RouteItem *)g_PTRNUL;
+ _vm->_globals._oldDirection = DIR_NONE;
+ if (zoneId > 0) {
+ if (_vm->_linesManager.ZONEP[zoneId]._destX && _vm->_linesManager.ZONEP[zoneId]._destY && _vm->_linesManager.ZONEP[zoneId]._destY != 31) {
+ if (_vm->_linesManager.ZONEP[zoneId]._spriteIndex == -1) {
+ _vm->_linesManager.ZONEP[zoneId]._destX = 0;
+ _vm->_linesManager.ZONEP[zoneId]._destY = 0;
+ _vm->_linesManager.ZONEP[zoneId]._spriteIndex = 0;
+ } else {
+ setSpriteIndex(0, _vm->_linesManager.ZONEP[zoneId]._spriteIndex);
+ _vm->_globals._actionDirection = _vm->_linesManager.ZONEP[zoneId]._spriteIndex - 59;
+ }
+ }
+ }
+ }
+ _vm->_globals.Compteur = 0;
+ return;
+ }
+ if (_vm->_globals._oldDirection == DIR_RIGHT) {
+ if (_vm->_globals._oldFrameIndex < 24 || _vm->_globals._oldFrameIndex > 35) {
+ oldPosX = _oldCharacterPosX;
+ oldPosY = _oldCharacterPosY;
+ oldFrameIdx = 24;
+ } else {
+ int deltaX = _vm->_globals._hopkinsItem[_vm->_globals._oldFrameIndex]._speedX;
+ int deltaY = _vm->_globals._hopkinsItem[_vm->_globals._oldFrameIndex]._speedY;
+
+ if (_sprite[0]._zoomFactor < 0) {
+ deltaX = _vm->_graphicsManager.zoomOut(deltaX, -_sprite[0]._zoomFactor);
+ deltaY = _vm->_graphicsManager.zoomOut(deltaY, -_sprite[0]._zoomFactor);
+ } else if (_sprite[0]._zoomFactor > 0) {
+ deltaX = _vm->_graphicsManager.zoomIn(deltaX, _sprite[0]._zoomFactor);
+ deltaY = _vm->_graphicsManager.zoomIn(deltaY, _sprite[0]._zoomFactor);
+ }
+ oldPosX = _oldCharacterPosX + deltaX;
+ oldPosY = _oldCharacterPosY + deltaY;
+ oldFrameIdx = _vm->_globals._oldFrameIndex + 1;
+ if (oldFrameIdx > 35)
+ oldFrameIdx = 24;
+ }
+ _vm->_globals.Compteur = 5 / _vm->_globals._speed;
+ }
+ if (_vm->_globals._oldDirection == DIR_LEFT) {
+ if (_vm->_globals._oldFrameIndex < 24 || _vm->_globals._oldFrameIndex > 35) {
+ oldPosX = _oldCharacterPosX;
+ oldPosY = _oldCharacterPosY;
+ oldFrameIdx = 24;
+ } else {
+ int deltaX = _vm->_globals._hopkinsItem[_vm->_globals._oldFrameIndex]._speedX;
+ int deltaY = _vm->_globals._hopkinsItem[_vm->_globals._oldFrameIndex]._speedY;
+ if (_sprite[0]._zoomFactor < 0) {
+ deltaX = _vm->_graphicsManager.zoomOut(deltaX, -_sprite[0]._zoomFactor);
+ deltaY = _vm->_graphicsManager.zoomOut(deltaY, -_sprite[0]._zoomFactor);
+ } else if (_sprite[0]._zoomFactor > 0) {
+ deltaX = _vm->_graphicsManager.zoomIn(deltaX, _sprite[0]._zoomFactor);
+ deltaY = _vm->_graphicsManager.zoomIn(deltaY, _sprite[0]._zoomFactor);
+ }
+ oldPosX = _oldCharacterPosX - deltaX;
+ oldPosY = _oldCharacterPosY - deltaY;
+ oldFrameIdx = _vm->_globals._oldFrameIndex + 1;
+ if (oldFrameIdx > 35)
+ oldFrameIdx = 24;
+ }
+ _vm->_globals.Compteur = 5 / _vm->_globals._speed;
+ }
+ if (_vm->_globals._oldDirection == DIR_UP) {
+ if (_vm->_globals._oldFrameIndex > 11) {
+ oldPosX = _oldCharacterPosX;
+ oldPosY = _oldCharacterPosY;
+ oldFrameIdx = 0;
+ } else {
+ int deltaY = abs(_vm->_globals._hopkinsItem[_vm->_globals._oldFrameIndex]._speedY);
+ if (_sprite[0]._zoomFactor < 0) {
+ deltaY = _vm->_graphicsManager.zoomOut(deltaY, -_sprite[0]._zoomFactor);
+ } else if (_sprite[0]._zoomFactor > 0) {
+ deltaY = _vm->_graphicsManager.zoomIn(deltaY, _sprite[0]._zoomFactor);
+ }
+ oldPosX = _oldCharacterPosX;
+ oldPosY = _oldCharacterPosY - deltaY;
+ oldFrameIdx = _vm->_globals._oldFrameIndex + 1;
+ if (oldFrameIdx > 11)
+ oldFrameIdx = 0;
+ }
+ _vm->_globals.Compteur = 4 / _vm->_globals._speed;
+ }
+
+ if (_vm->_globals._oldDirection == DIR_DOWN) {
+ if (_vm->_globals._oldFrameIndex < 48 || _vm->_globals._oldFrameIndex > 59) {
+ oldPosX = _oldCharacterPosX;
+ oldPosY = _oldCharacterPosY;
+ oldFrameIdx = 48;
+ } else {
+ int deltaY = abs(_vm->_globals._hopkinsItem[_vm->_globals._oldFrameIndex]._speedY);
+ if (_sprite[0]._zoomFactor < 0) {
+ deltaY = _vm->_graphicsManager.zoomOut(deltaY, -_sprite[0]._zoomFactor);
+ } else if (_sprite[0]._zoomFactor > 0) {
+ deltaY = _vm->_graphicsManager.zoomIn(deltaY, _sprite[0]._zoomFactor);
+ }
+ oldPosX = _oldCharacterPosX;
+ oldPosY = deltaY + _oldCharacterPosY;
+ oldFrameIdx = _vm->_globals._oldFrameIndex + 1;
+ if (oldFrameIdx > 59)
+ oldFrameIdx = 48;
+ }
+ _vm->_globals.Compteur = 4 / _vm->_globals._speed;
+ }
+ if (_vm->_globals._oldDirection == DIR_UP_RIGHT) {
+ if (_vm->_globals._oldFrameIndex < 12 || _vm->_globals._oldFrameIndex > 23) {
+ oldPosX = _oldCharacterPosX;
+ oldPosY = _oldCharacterPosY;
+ oldFrameIdx = 12;
+ } else {
+ int deltaX = _vm->_globals._hopkinsItem[_vm->_globals._oldFrameIndex]._speedX;
+ int deltaY = _vm->_globals._hopkinsItem[_vm->_globals._oldFrameIndex]._speedY;
+ if (_sprite[0]._zoomFactor < 0) {
+ deltaX = _vm->_graphicsManager.zoomOut(deltaX, -_sprite[0]._zoomFactor);
+ deltaY = _vm->_graphicsManager.zoomOut(deltaY, -_sprite[0]._zoomFactor);
+ }
+ if (_sprite[0]._zoomFactor > 0) {
+ deltaX = _vm->_graphicsManager.zoomIn(deltaX, _sprite[0]._zoomFactor);
+ deltaY = _vm->_graphicsManager.zoomIn(deltaY, _sprite[0]._zoomFactor);
+ }
+ oldPosX = deltaX + _oldCharacterPosX;
+ oldPosY = _oldCharacterPosY + deltaY;
+ oldFrameIdx = _vm->_globals._oldFrameIndex + 1;
+ if (oldFrameIdx > 23)
+ oldFrameIdx = 12;
+ }
+ _vm->_globals.Compteur = 5 / _vm->_globals._speed;
+ }
+ if (_vm->_globals._oldDirection == DIR_UP_LEFT) {
+ if (_vm->_globals._oldFrameIndex < 12 || _vm->_globals._oldFrameIndex > 23) {
+ oldPosX = _oldCharacterPosX;
+ oldPosY = _oldCharacterPosY;
+ oldFrameIdx = 12;
+ } else {
+ int deltaX = _vm->_globals._hopkinsItem[_vm->_globals._oldFrameIndex]._speedX;
+ int deltaY = _vm->_globals._hopkinsItem[_vm->_globals._oldFrameIndex]._speedY;
+ if (_sprite[0]._zoomFactor < 0) {
+ deltaX = _vm->_graphicsManager.zoomOut(deltaX, -_sprite[0]._zoomFactor);
+ deltaY = _vm->_graphicsManager.zoomOut(deltaY, -_sprite[0]._zoomFactor);
+ } else if (_sprite[0]._zoomFactor > 0) {
+ deltaX = _vm->_graphicsManager.zoomIn(deltaX, _sprite[0]._zoomFactor);
+ deltaY = _vm->_graphicsManager.zoomIn(deltaY, _sprite[0]._zoomFactor);
+ }
+ oldPosX = _oldCharacterPosX - deltaX;
+ oldPosY = _oldCharacterPosY + deltaY;
+ oldFrameIdx = _vm->_globals._oldFrameIndex + 1;
+ if (oldFrameIdx > 23)
+ oldFrameIdx = 12;
+ }
+ _vm->_globals.Compteur = 5 / _vm->_globals._speed;
+ }
+ if (_vm->_globals._oldDirection == DIR_DOWN_RIGHT) {
+ if (_vm->_globals._oldFrameIndex < 36 || _vm->_globals._oldFrameIndex > 47) {
+ oldPosX = _oldCharacterPosX;
+ oldPosY = _oldCharacterPosY;
+ oldFrameIdx = 36;
+ } else {
+ int deltaX = _vm->_globals._hopkinsItem[_vm->_globals._oldFrameIndex]._speedX;
+ int deltaY = _vm->_globals._hopkinsItem[_vm->_globals._oldFrameIndex]._speedY;
+ if (_sprite[0]._zoomFactor < 0) {
+ deltaX = _vm->_graphicsManager.zoomOut(deltaX, -_sprite[0]._zoomFactor);
+ deltaY = _vm->_graphicsManager.zoomOut(deltaY, -_sprite[0]._zoomFactor);
+ }
+ if (_sprite[0]._zoomFactor > 0) {
+ deltaX = _vm->_graphicsManager.zoomIn(deltaX, _sprite[0]._zoomFactor);
+ deltaY = _vm->_graphicsManager.zoomIn(deltaY, _sprite[0]._zoomFactor);
+ }
+ oldPosX = deltaX + _oldCharacterPosX;
+ oldPosY = _oldCharacterPosY + deltaY;
+ oldFrameIdx = _vm->_globals._oldFrameIndex + 1;
+ if (oldFrameIdx > 47)
+ oldFrameIdx = 36;
+ }
+ _vm->_globals.Compteur = 5 / _vm->_globals._speed;
+ }
+ if (_vm->_globals._oldDirection == DIR_DOWN_LEFT) {
+ if (_vm->_globals._oldFrameIndex < 36 || _vm->_globals._oldFrameIndex > 47) {
+ oldPosX = _oldCharacterPosX;
+ oldPosY = _oldCharacterPosY;
+ oldFrameIdx = 36;
+ } else {
+ int deltaX = _vm->_globals._hopkinsItem[_vm->_globals._oldFrameIndex]._speedX;
+ int deltaY = _vm->_globals._hopkinsItem[_vm->_globals._oldFrameIndex]._speedY;
+ if (_sprite[0]._zoomFactor < 0) {
+ deltaX = _vm->_graphicsManager.zoomOut(deltaX, -_sprite[0]._zoomFactor);
+ deltaY = _vm->_graphicsManager.zoomOut(deltaY, -_sprite[0]._zoomFactor);
+ }
+ if (_sprite[0]._zoomFactor > 0) {
+ deltaX = _vm->_graphicsManager.zoomIn(deltaX, _sprite[0]._zoomFactor);
+ deltaY = _vm->_graphicsManager.zoomIn(deltaY, _sprite[0]._zoomFactor);
+ }
+ oldPosX = _oldCharacterPosX - deltaX;
+ oldPosY = _oldCharacterPosY + deltaY;
+ oldFrameIdx = _vm->_globals._oldFrameIndex + 1;
+ if (oldFrameIdx > 47)
+ oldFrameIdx = 36;
+ }
+ _vm->_globals.Compteur = 5 / _vm->_globals._speed;
+ }
+ bool loopCond = false;
+ do {
+ newPosX = _vm->_linesManager._route->_x;
+ newPosY = _vm->_linesManager._route->_y;
+ newDirection = (Directions)_vm->_linesManager._route->_dir;
+ _vm->_linesManager._route++;
+
+ if (newPosX == -1 && newPosY == -1) {
+ int zoneId;
+ if (_vm->_globals._actionMoveTo)
+ zoneId = _vm->_globals._saveData->_data[svField2];
+ else
+ zoneId = _zoneNum;
+ setSpriteIndex(0, _vm->_globals._oldDirection + 59);
+ _vm->_globals._actionDirection = DIR_NONE;
+ _vm->_linesManager._route = (RouteItem *)g_PTRNUL;
+ computeAndSetSpriteSize();
+ setFlipSprite(0, false);
+ _vm->_globals.Compteur = 0;
+ _vm->_globals._oldDirection = DIR_NONE;
+ _oldCharacterPosX = getSpriteX(0);
+ _oldCharacterPosY = getSpriteY(0);
+
+ if (zoneId > 0) {
+ if (_vm->_linesManager.ZONEP[zoneId]._destX && _vm->_linesManager.ZONEP[zoneId]._destY && _vm->_linesManager.ZONEP[zoneId]._destY != 31) {
+ if ( _vm->_linesManager.ZONEP[zoneId]._spriteIndex == -1) {
+ _vm->_linesManager.ZONEP[zoneId]._destX = 0;
+ _vm->_linesManager.ZONEP[zoneId]._destY = 0;
+ _vm->_linesManager.ZONEP[zoneId]._spriteIndex = 0;
+ } else {
+ setSpriteIndex(0, _vm->_linesManager.ZONEP[zoneId]._spriteIndex);
+ _vm->_globals._actionDirection = _vm->_linesManager.ZONEP[zoneId]._spriteIndex - 59;
+ }
+ }
+ }
+ _vm->_globals.Compteur = 0;
+ return;
+ }
+ if (_vm->_globals._oldDirection != newDirection)
+ break;
+ if ((newDirection == DIR_RIGHT && newPosX >= oldPosX) || (_vm->_globals._oldDirection == DIR_LEFT && newPosX <= oldPosX) ||
+ (_vm->_globals._oldDirection == DIR_UP && newPosY <= oldPosY) || (_vm->_globals._oldDirection == DIR_DOWN && newPosY >= oldPosY) ||
+ (_vm->_globals._oldDirection == DIR_UP_RIGHT && newPosX >= oldPosX) || (_vm->_globals._oldDirection == DIR_UP_LEFT && newPosX <= oldPosX) ||
+ (_vm->_globals._oldDirection == DIR_DOWN_RIGHT && newPosX >= oldPosX) || (_vm->_globals._oldDirection == DIR_DOWN_LEFT && newPosX <= oldPosX))
+ loopCond = true;
+ } while (!loopCond);
+ if (loopCond) {
+ computeAndSetSpriteSize();
+ if ((_vm->_globals._oldDirection == DIR_DOWN_LEFT) || (_vm->_globals._oldDirection == DIR_LEFT) || (_vm->_globals._oldDirection == DIR_UP_LEFT))
+ setFlipSprite(0, true);
+
+ if ((_vm->_globals._oldDirection == DIR_UP) || (_vm->_globals._oldDirection == DIR_UP_RIGHT) || (_vm->_globals._oldDirection == DIR_RIGHT) ||
+ (_vm->_globals._oldDirection == DIR_DOWN_RIGHT) || (_vm->_globals._oldDirection == DIR_DOWN))
+ setFlipSprite(0, false);
+
+ setSpriteX(0, newPosX);
+ setSpriteY(0, newPosY);
+ setSpriteIndex(0, oldFrameIdx);
+ } else {
+ if ((_vm->_globals._oldDirection == DIR_DOWN_LEFT) || (_vm->_globals._oldDirection == DIR_LEFT) || (_vm->_globals._oldDirection == DIR_UP_LEFT))
+ setFlipSprite(0, true);
+
+ if ((_vm->_globals._oldDirection == DIR_UP) || (_vm->_globals._oldDirection == DIR_UP_RIGHT) || (_vm->_globals._oldDirection == DIR_RIGHT) ||
+ (_vm->_globals._oldDirection == DIR_DOWN_RIGHT) || (_vm->_globals._oldDirection == DIR_DOWN))
+ setFlipSprite(0, false);
+ _vm->_globals.Compteur = 0;
+ }
+ _vm->_globals._oldDirection = newDirection;
+ _vm->_globals._oldDirectionSpriteIdx = newDirection + 59;
+ _vm->_globals._oldFrameIndex = oldFrameIdx;
+ _oldCharacterPosX = newPosX;
+ _oldCharacterPosY = newPosY;
+}
+
+void ObjectsManager::GOHOME2() {
+ if (_vm->_linesManager._route == (RouteItem *)g_PTRNUL)
+ return;
+
+ int realSpeed = 2;
+ if (_vm->_globals._speed == 2)
+ realSpeed = 4;
+ else if (_vm->_globals._speed == 3)
+ realSpeed = 6;
+
+ int countColisionPixel = 0;
+
+ for (;;) {
+ int nexPosX = _vm->_linesManager._route->_x;
+ int newPosY = _vm->_linesManager._route->_y;
+ Directions newDirection = (Directions)_vm->_linesManager._route->_dir;
+ _vm->_linesManager._route++;
+
+ if ((nexPosX == -1) && (newPosY == -1))
+ break;
+
+ ++countColisionPixel;
+ if (countColisionPixel >= realSpeed) {
+ _vm->_globals._lastDirection = newDirection;
+ setSpriteX(0, nexPosX);
+ setSpriteY(0, newPosY);
+ switch (_vm->_globals._lastDirection) {
+ case DIR_UP:
+ setSpriteIndex(0, 4);
+ break;
+ case DIR_RIGHT:
+ setSpriteIndex(0, 5);
+ break;
+ case DIR_DOWN:
+ setSpriteIndex(0, 6);
+ break;
+ case DIR_LEFT:
+ setSpriteIndex(0, 7);
+ break;
+ default:
+ break;
+ }
+
+ return;
+ }
+ }
+
+ switch (_vm->_globals._lastDirection) {
+ case DIR_UP:
+ setSpriteIndex(0, 0);
+ break;
+ case DIR_RIGHT:
+ setSpriteIndex(0, 1);
+ break;
+ case DIR_DOWN:
+ setSpriteIndex(0, 2);
+ break;
+ case DIR_LEFT:
+ setSpriteIndex(0, 3);
+ break;
+ default:
+ break;
+ }
+
+ _vm->_linesManager._route = (RouteItem *)g_PTRNUL;
+}
+
+/**
+ * Load Zone
+ */
+void ObjectsManager::loadZone(const Common::String &file) {
+ for (int i = 1; i <= 100; i++) {
+ _vm->_linesManager.ZONEP[i]._destX = 0;
+ _vm->_linesManager.ZONEP[i]._destY = 0;
+ _vm->_linesManager.ZONEP[i]._spriteIndex = 0;
+ _vm->_linesManager.ZONEP[i]._verbFl1 = 0;
+ _vm->_linesManager.ZONEP[i]._verbFl2 = 0;
+ _vm->_linesManager.ZONEP[i]._verbFl3 = 0;
+ _vm->_linesManager.ZONEP[i]._verbFl4 = 0;
+ _vm->_linesManager.ZONEP[i]._verbFl5 = 0;
+ _vm->_linesManager.ZONEP[i]._verbFl6 = 0;
+ _vm->_linesManager.ZONEP[i]._verbFl7 = 0;
+ _vm->_linesManager.ZONEP[i]._verbFl8 = 0;
+ _vm->_linesManager.ZONEP[i]._verbFl9 = 0;
+ _vm->_linesManager.ZONEP[i]._verbFl10 = 0;
+ _vm->_linesManager.ZONEP[i]._messageId = 0;
+ _vm->_linesManager.ZONEP[i]._enabledFl = false;
+ }
+
+ Common::File f;
+ if (!f.exists(file))
+ error("File not found : %s", file.c_str());
+
+ byte *ptr = _vm->_fileManager.loadFile(file);
+ int bufId = 0;
+ int zoneLineIdx = 0;
+ int bobZoneIdx;
+ do {
+ bobZoneIdx = READ_LE_INT16((uint16 *)ptr + bufId);
+ if (bobZoneIdx != -1) {
+ _vm->_linesManager.addZoneLine(
+ zoneLineIdx,
+ READ_LE_UINT16((uint16 *)ptr + bufId + 1),
+ READ_LE_UINT16((uint16 *)ptr + bufId + 2),
+ READ_LE_UINT16((uint16 *)ptr + bufId + 3),
+ READ_LE_UINT16((uint16 *)ptr + bufId + 4),
+ bobZoneIdx);
+ _vm->_linesManager.ZONEP[bobZoneIdx]._enabledFl = true;
+ }
+ bufId += 5;
+ ++zoneLineIdx;
+ } while (bobZoneIdx != -1);
+
+ for (int i = 1; i <= 100; i++) {
+ _vm->_linesManager.ZONEP[i]._destX = READ_LE_INT16((uint16 *)ptr + bufId);
+ _vm->_linesManager.ZONEP[i]._destY = READ_LE_INT16((uint16 *)ptr + bufId + 1);
+ _vm->_linesManager.ZONEP[i]._spriteIndex = READ_LE_INT16((uint16 *)ptr + bufId + 2);
+ bufId += 3;
+ }
+
+ byte *v9 = (ptr + 10 * zoneLineIdx + 606);
+ bufId = 0;
+ for (int i = 1; i <= 100; i++) {
+ _vm->_linesManager.ZONEP[i]._verbFl1 = v9[bufId];
+ _vm->_linesManager.ZONEP[i]._verbFl2 = v9[bufId + 1];
+ _vm->_linesManager.ZONEP[i]._verbFl3 = v9[bufId + 2];
+ _vm->_linesManager.ZONEP[i]._verbFl4 = v9[bufId + 3];
+ _vm->_linesManager.ZONEP[i]._verbFl5 = v9[bufId + 4];
+ _vm->_linesManager.ZONEP[i]._verbFl6 = v9[bufId + 5];
+ _vm->_linesManager.ZONEP[i]._verbFl7 = v9[bufId + 6];
+ _vm->_linesManager.ZONEP[i]._verbFl8 = v9[bufId + 7];
+ _vm->_linesManager.ZONEP[i]._verbFl9 = v9[bufId + 8];
+ _vm->_linesManager.ZONEP[i]._verbFl10 = v9[bufId + 9];
+
+ bufId += 10;
+ }
+ v9 += 1010;
+ for (int i = 0; i < 100; i++)
+ _vm->_linesManager.ZONEP[i + 1]._messageId = READ_LE_UINT16(v9 + 2 * i);
+
+ _vm->_globals.freeMemory(ptr);
+ _vm->_linesManager.CARRE_ZONE();
+}
+
+void ObjectsManager::handleCityMap() {
+ _vm->_dialogsManager._inventFl = false;
+ _vm->_eventsManager._gameKey = KEY_NONE;
+ _vm->_linesManager.setMaxLineIdx(1);
+ _vm->_globals._characterMaxPosY = 440;
+ _vm->_globals._cityMapEnabledFl = true;
+ _vm->_graphicsManager._noFadingFl = false;
+ _vm->_globals._freezeCharacterFl = false;
+ _spritePtr = g_PTRNUL;
+ _vm->_globals._exitId = 0;
+ _vm->_globals._checkDistanceFl = true;
+ _vm->_soundManager.playSound(31);
+ _vm->_globals.iRegul = 1;
+ _vm->_graphicsManager.loadImage("PLAN");
+ _vm->_linesManager.loadLines("PLAN.OB2");
+ _vm->_globals.loadHidingItems("PLAN.CA2");
+ loadZone("PLAN.ZO2");
+ _spritePtr = _vm->_fileManager.loadFile("VOITURE.SPR");
+ _vm->_animationManager.loadAnim("PLAN");
+ _vm->_graphicsManager.displayAllBob();
+ _vm->_graphicsManager.initScreen("PLAN", 2, false);
+ for (int i = 0; i <= 15; i++)
+ _vm->_globals.B_CACHE_OFF(i);
+ _vm->_globals.B_CACHE_OFF(19);
+ _vm->_globals.B_CACHE_OFF(20);
+ _vm->_globals.enableHiding();
+
+ if (!_mapCarPosX && !_mapCarPosY) {
+ _mapCarPosX = 900;
+ _mapCarPosY = 319;
+ }
+ addStaticSprite(_spritePtr, Common::Point(_mapCarPosX, _mapCarPosY), 0, 1, 0, false, 5, 5);
+ _vm->_eventsManager.setMouseXY(_mapCarPosX, _mapCarPosY);
+ _vm->_eventsManager.mouseOn();
+ _vm->_graphicsManager.scrollScreen(getSpriteX(0) - 320);
+ _vm->_graphicsManager._scrollOffset = getSpriteX(0) - 320;
+ animateSprite(0);
+ _vm->_linesManager._route = (RouteItem *)g_PTRNUL;
+ _vm->_graphicsManager.SETCOLOR3(252, 100, 100, 100);
+ _vm->_graphicsManager.SETCOLOR3(253, 100, 100, 100);
+ _vm->_graphicsManager.SETCOLOR3(251, 100, 100, 100);
+ _vm->_graphicsManager.SETCOLOR3(254, 0, 0, 0);
+
+ for (int i = 0; i <= 4; i++)
+ _vm->_eventsManager.VBL();
+
+ _vm->_globals.iRegul = 1;
+ _vm->_graphicsManager.fadeInLong();
+ _vm->_eventsManager.changeMouseCursor(4);
+ _vm->_graphicsManager._noFadingFl = false;
+
+ bool loopCond = false;
+ do {
+ int mouseButton = _vm->_eventsManager.getMouseButton();
+ if (mouseButton) {
+ if (_vm->_globals._saveData->_data[svField170] == 1 && !_vm->_globals._saveData->_data[svField171]) {
+ _vm->_globals._saveData->_data[svField171] = 1;
+ _vm->_globals._introSpeechOffFl = true;
+ _vm->_talkManager.startAnimatedCharacterDialogue("APPEL1.pe2");
+ _vm->_globals._introSpeechOffFl = false;
+ mouseButton = 0;
+ }
+ if (_vm->_globals._saveData->_data[svField80] == 1 && !_vm->_globals._saveData->_data[svField172]) {
+ _vm->_globals._saveData->_data[svField172] = 1;
+ _vm->_globals._introSpeechOffFl = true;
+ _vm->_talkManager.startAnimatedCharacterDialogue("APPEL2.pe2");
+ _vm->_globals._introSpeechOffFl = false;
+ mouseButton = 0;
+ _vm->_eventsManager._curMouseButton = 0;
+ }
+ if (mouseButton == 1)
+ handleLeftButton();
+ }
+
+ _vm->_linesManager.checkZone();
+ GOHOME2();
+
+ if (_vm->_linesManager._route == (RouteItem *)g_PTRNUL && _vm->_globals._actionMoveTo)
+ PARADISE();
+ _vm->_eventsManager.VBL();
+
+ if (_vm->_globals._exitId)
+ loopCond = true;
+ } while (!_vm->shouldQuit() && !loopCond);
+
+ if (!_vm->_graphicsManager._noFadingFl)
+ _vm->_graphicsManager.fadeOutLong();
+ _vm->_globals.iRegul = 0;
+ _vm->_graphicsManager._noFadingFl = false;
+ _mapCarPosX = getSpriteX(0);
+ _mapCarPosY = getSpriteY(0);
+ removeSprite(0);
+ _spritePtr = _vm->_globals.freeMemory(_spritePtr);
+ clearScreen();
+ _vm->_globals._cityMapEnabledFl = false;
+}
+
+/**
+ * Handle Left button
+ */
+void ObjectsManager::handleLeftButton() {
+ _vm->_fontManager.hideText(9);
+ int destX = _vm->_eventsManager.getMouseX();
+ int destY = _vm->_eventsManager.getMouseY();
+
+ if (!_vm->_dialogsManager._inventFl && !_vm->_globals._cityMapEnabledFl &&
+ destX > _vm->_graphicsManager._scrollOffset - 30 && destX < _vm->_graphicsManager._scrollOffset + 50 &&
+ destY > -30 && destY < 50) {
+ int oldMouseCursor = _vm->_eventsManager._mouseCursorId;
+ _vm->_dialogsManager._inventFl = true;
+ _vm->_dialogsManager.showInventory();
+ _vm->_dialogsManager._inventFl = false;
+ _vm->_eventsManager._gameKey = KEY_NONE;
+ if (!_vm->_globals._exitId) {
+ _vm->_dialogsManager._inventFl = false;
+ _vm->_eventsManager._mouseCursorId = oldMouseCursor;
+ }
+ return;
+ }
+ if (_vm->_globals._saveData->_data[svField354] == 1 && !_vm->_globals._cityMapEnabledFl
+ && destX >= 533 && destX <= 559 && destY >= 26 && destY <= 59) {
+ changeCharacterHead(CHARACTER_HOPKINS_CLONE, CHARACTER_HOPKINS);
+ return;
+ }
+ if (_vm->_globals._saveData->_data[svField356] == 1 && !_vm->_globals._cityMapEnabledFl
+ && destX >= 533 && destX <= 559 && destY >= 26 && destY <= 48) {
+ changeCharacterHead(CHARACTER_SAMANTHA, CHARACTER_HOPKINS);
+ return;
+ }
+ if (_vm->_globals._saveData->_data[svField357] == 1) {
+ if (_vm->_globals._saveData->_data[svField353] == 1 && !_vm->_globals._cityMapEnabledFl
+ && destX >= 533 && destX <= 559 && destY >= 26 && destY <= 59) {
+ changeCharacterHead(CHARACTER_HOPKINS, CHARACTER_HOPKINS_CLONE);
+ return;
+ }
+ if (_vm->_globals._saveData->_data[svField355] == 1 && !_vm->_globals._cityMapEnabledFl
+ && destX >= 567 && destX <= 593 && destY >= 26 && destY <= 59) {
+ changeCharacterHead(CHARACTER_HOPKINS, CHARACTER_SAMANTHA);
+ return;
+ }
+ }
+ if (_vm->_globals._cityMapEnabledFl && _vm->_globals._actionMoveTo) {
+ _vm->_linesManager.checkZone();
+ if (_zoneNum <= 0)
+ return;
+ int routeIdx = 0;
+ do {
+ _vm->_linesManager.essai2[routeIdx] = _vm->_linesManager._route[routeIdx];
+ ++routeIdx;
+ } while (_vm->_linesManager._route[routeIdx]._x != -1);
+
+ _vm->_linesManager.essai2[routeIdx].invalidate();;
+ }
+
+ if (_vm->_globals._actionMoveTo) {
+ _vm->_linesManager.checkZone();
+ _vm->_globals._actionMoveTo = false;
+ _vm->_globals._saveData->_data[svField1] = 0;
+ _vm->_globals._saveData->_data[svField2] = 0;
+ }
+
+ if (_vm->_globals._cityMapEnabledFl && (_vm->_eventsManager._mouseCursorId != 4 || _zoneNum <= 0))
+ return;
+ if (_zoneNum != -1 && _zoneNum != 0) {
+ if (_vm->_linesManager.ZONEP[_zoneNum]._destX && _vm->_linesManager.ZONEP[_zoneNum]._destY && _vm->_linesManager.ZONEP[_zoneNum]._destY != 31) {
+ destX = _vm->_linesManager.ZONEP[_zoneNum]._destX;
+ destY = _vm->_linesManager.ZONEP[_zoneNum]._destY;
+ }
+ }
+ _vm->_globals._actionMoveTo = false;
+ RouteItem *oldRoute = _vm->_linesManager._route;
+ _vm->_linesManager._route = (RouteItem *)g_PTRNUL;
+ if (_forestFl && _zoneNum >= 20 && _zoneNum <= 23) {
+ if (getSpriteY(0) > 374 && getSpriteY(0) <= 410) {
+ _vm->_linesManager._route = (RouteItem *)g_PTRNUL;
+ setSpriteIndex(0, _vm->_globals._oldDirectionSpriteIdx);
+ _vm->_globals._actionDirection = DIR_NONE;
+ _vm->_linesManager._route = (RouteItem *)g_PTRNUL;
+ computeAndSetSpriteSize();
+ setFlipSprite(0, false);
+ _vm->_globals.Compteur = 0;
+ _vm->_globals._oldDirection = DIR_NONE;
+ } else {
+ _vm->_linesManager._route = _vm->_linesManager.PARCOURS2(getSpriteX(0), getSpriteY(0), getSpriteX(0), 390);
+ if (_vm->_linesManager._route != (RouteItem *)g_PTRNUL)
+ _vm->_linesManager.PACOURS_PROPRE(_vm->_linesManager._route);
+ _oldCharacterPosX = getSpriteX(0);
+ _oldCharacterPosY = getSpriteY(0);
+ _vm->_globals.Compteur = 0;
+ if (_vm->_linesManager._route != (RouteItem *)g_PTRNUL || oldRoute == _vm->_linesManager._route) {
+ _vm->_globals._oldDirection = DIR_NONE;
+ } else {
+ _vm->_linesManager._route = oldRoute;
+ }
+ }
+ } else {
+ if (!_vm->_globals._freezeCharacterFl && !_vm->_globals._cityMapEnabledFl) {
+ _vm->_linesManager._route = _vm->_linesManager.PARCOURS2(getSpriteX(0), getSpriteY(0), destX, destY);
+ if (_vm->_linesManager._route != (RouteItem *)g_PTRNUL)
+ _vm->_linesManager.PACOURS_PROPRE(_vm->_linesManager._route);
+ _oldCharacterPosX = getSpriteX(0);
+ _oldCharacterPosY = getSpriteY(0);
+ _vm->_globals.Compteur = 0;
+ if (_vm->_linesManager._route != (RouteItem *)g_PTRNUL || oldRoute == _vm->_linesManager._route)
+ _vm->_globals._oldDirection = DIR_NONE;
+ else
+ _vm->_linesManager._route = oldRoute;
+ }
+ }
+
+ if (!_vm->_globals._freezeCharacterFl && _vm->_globals._cityMapEnabledFl)
+ _vm->_linesManager._route = _vm->_linesManager.cityMapCarRoute(getSpriteX(0), getSpriteY(0), destX, destY);
+
+ if (_zoneNum != -1 && _zoneNum != 0) {
+ if (_vm->_eventsManager._mouseCursorId == 23)
+ _vm->_globals._saveData->_data[svField1] = 5;
+ else
+ _vm->_globals._saveData->_data[svField1] = _vm->_eventsManager._mouseCursorId;
+
+ if (_vm->_globals._cityMapEnabledFl)
+ _vm->_globals._saveData->_data[svField1] = 6;
+ _vm->_globals._saveData->_data[svField2] = _zoneNum;
+ _vm->_globals._saveData->_data[svField3] = _curObjectIndex;
+ _vm->_globals._actionMoveTo = true;
+ }
+ _vm->_fontManager.hideText(5);
+ _vm->_graphicsManager.SETCOLOR4(251, 100, 100, 100);
+ if (_vm->_globals._screenId == 20 && _vm->_globals._saveData->_data[svField132] == 1
+ && _curObjectIndex == 20 && _zoneNum == 12
+ && _vm->_eventsManager._mouseCursorId == 23) {
+ // Special case for throwing darts at the switch in Purgatory - the player shouldn't move
+ _vm->_linesManager._route = (RouteItem *)g_PTRNUL;
+ getSpriteX(0);
+ getSpriteY(0);
+ }
+}
+
+void ObjectsManager::PARADISE() {
+ char result = _vm->_globals._saveData->_data[svField1];
+ if (result && _vm->_globals._saveData->_data[svField2] && result != 4 && result > 3) {
+ _vm->_fontManager.hideText(5);
+ if (!_forestFl || _zoneNum < 20 || _zoneNum > 23) {
+ if (_vm->_graphicsManager._largeScreenFl) {
+ _vm->_graphicsManager._scrollStatus = 2;
+ if (_vm->_eventsManager._startPos.x + 320 - getSpriteX(0) > 160) {
+ bool loopCond = false;
+ do {
+ _vm->_graphicsManager._scrollPosX -= _vm->_graphicsManager._scrollSpeed;
+ if (_vm->_graphicsManager._scrollPosX < 0) {
+ _vm->_graphicsManager._scrollPosX = 0;
+ loopCond = true;
+ }
+ if (_vm->_graphicsManager._scrollPosX > SCREEN_WIDTH) {
+ _vm->_graphicsManager._scrollPosX = SCREEN_WIDTH;
+ loopCond = true;
+ }
+ if (_vm->_eventsManager.getMouseX() > _vm->_graphicsManager._scrollPosX + 620)
+ _vm->_eventsManager.setMouseXY(_vm->_eventsManager._mousePos.x - 4, _vm->_eventsManager.getMouseY());
+
+ _vm->_eventsManager.VBL();
+ } while (!loopCond && _vm->_eventsManager._startPos.x > getSpriteX(0) - 320);
+ } else if (_vm->_eventsManager._startPos.x + 320 - getSpriteX(0) < -160) {
+ bool loopCond = false;
+ do {
+ _vm->_graphicsManager._scrollPosX += _vm->_graphicsManager._scrollSpeed;
+ if (_vm->_graphicsManager._scrollPosX < 0) {
+ _vm->_graphicsManager._scrollPosX = 0;
+ loopCond = true;
+ }
+ if (_vm->_graphicsManager._scrollPosX > SCREEN_WIDTH) {
+ _vm->_graphicsManager._scrollPosX = SCREEN_WIDTH;
+ loopCond = true;
+ }
+ if (_vm->_eventsManager.getMouseX() < _vm->_graphicsManager._scrollPosX + 10)
+ _vm->_eventsManager.setMouseXY(_vm->_eventsManager._mousePos.x + 4, _vm->_eventsManager.getMouseY());
+
+ _vm->_eventsManager.VBL();
+ } while (!loopCond && _vm->_eventsManager._startPos.x < getSpriteX(0) - 320);
+ }
+ if (_vm->_eventsManager.getMouseX() > _vm->_graphicsManager._scrollPosX + 620)
+ _vm->_eventsManager.setMouseXY(_vm->_graphicsManager._scrollPosX + 610, 0);
+ if (_vm->_eventsManager.getMouseX() < _vm->_graphicsManager._scrollPosX + 10)
+ _vm->_eventsManager.setMouseXY(_vm->_graphicsManager._scrollPosX + 10, 0);
+ _vm->_eventsManager.VBL();
+ _vm->_graphicsManager._scrollStatus = 0;
+ }
+ _vm->_talkManager.REPONSE(_vm->_globals._saveData->_data[svField2], _vm->_globals._saveData->_data[svField1]);
+ } else {
+ _vm->_talkManager.REPONSE2(_vm->_globals._saveData->_data[svField2], _vm->_globals._saveData->_data[svField1]);
+ }
+ _vm->_eventsManager.changeMouseCursor(4);
+ if (_zoneNum != -1 && _zoneNum != 0 && !_vm->_linesManager.ZONEP[_zoneNum]._enabledFl) {
+ _zoneNum = -1;
+ _forceZoneFl = true;
+ }
+ if (_zoneNum != _vm->_globals._saveData->_data[svField2] || _zoneNum == -1 || _zoneNum == 0) {
+ _vm->_eventsManager._mouseCursorId = 4;
+ _changeVerbFl = false;
+ } else {
+ _vm->_eventsManager._mouseCursorId = _vm->_globals._saveData->_data[svField1];
+ if (_changeVerbFl) {
+ nextVerbIcon();
+ _changeVerbFl = false;
+ }
+ if (_vm->_eventsManager._mouseCursorId == 5)
+ _vm->_eventsManager._mouseCursorId = 4;
+ }
+ if (_vm->_eventsManager._mouseCursorId != 23)
+ _vm->_eventsManager.changeMouseCursor(_vm->_eventsManager._mouseCursorId);
+ _zoneNum = 0;
+ _vm->_globals._saveData->_data[svField1] = 0;
+ _vm->_globals._saveData->_data[svField2] = 0;
+ }
+ if (_vm->_globals._cityMapEnabledFl) {
+ _vm->_eventsManager._mouseCursorId = 0;
+ _vm->_eventsManager.changeMouseCursor(0);
+ }
+ if (_vm->_globals._freezeCharacterFl && _vm->_eventsManager._mouseCursorId == 4) {
+ if (_zoneNum != -1 && _zoneNum != 0)
+ handleRightButton();
+ }
+ _vm->_globals._actionMoveTo = false;
+}
+
+/**
+ * Clear Screen
+ */
+void ObjectsManager::clearScreen() {
+ clearSprite();
+ _vm->_graphicsManager.endDisplayBob();
+ _vm->_fontManager.hideText(5);
+ _vm->_fontManager.hideText(9);
+ _vm->_globals.clearVBob();
+ _vm->_animationManager.clearAnim();
+ _vm->_linesManager.clearAllZones();
+ _vm->_linesManager.resetLines();
+ _vm->_globals.resetHidingItems();
+
+ for (int i = 0; i <= 48; i++) {
+ _vm->_linesManager.BOBZONE[i] = 0;
+ _vm->_linesManager.BOBZONE_FLAG[i] = false;
+ }
+ _vm->_eventsManager._mouseCursorId = 4;
+ _verb = 4;
+ _zoneNum = 0;
+ _forceZoneFl = true;
+ _vm->_linesManager.resetLinesNumb();
+ _vm->_linesManager.resetLastLine();
+ _vm->_linesManager._route = (RouteItem *)g_PTRNUL;
+ _vm->_globals._answerBuffer = _vm->_globals.freeMemory(_vm->_globals._answerBuffer);
+ _vm->_globals.SPRITE_ECRAN = _vm->_globals.freeMemory(_vm->_globals.SPRITE_ECRAN);
+ _vm->_eventsManager._startPos.x = 0;
+ _vm->_eventsManager._mouseSpriteId = 0;
+ _vm->_globals._saveData->_data[svField1] = 0;
+ _vm->_globals._saveData->_data[svField2] = 0;
+ _vm->_globals._actionMoveTo = false;
+ _forceZoneFl = true;
+ _changeVerbFl = false;
+ _vm->_linesManager._route = (RouteItem *)g_PTRNUL;
+ _vm->_globals._oldDirection = DIR_NONE;
+ _vm->_graphicsManager.resetVesaSegment();
+}
+
+/**
+ * Change the currently active player face / Head
+ * @param oldCharacter Previously played character
+ * @param newCharacter New character to play
+ */
+void ObjectsManager::changeCharacterHead(PlayerCharacter oldCharacter, PlayerCharacter newCharacter) {
+ CharacterLocation *loc;
+
+ _changeHeadFl = true;
+ _vm->_graphicsManager.copySurface(_vm->_graphicsManager._vesaScreen, 532, 25, 65, 40, _vm->_graphicsManager._vesaBuffer, 532, 25);
+ _vm->_graphicsManager.addVesaSegment(532, 25, 597, 65);
+ _vm->_globals._checkDistanceFl = true;
+ _vm->_linesManager._route = (RouteItem *)g_PTRNUL;
+
+ if (oldCharacter == CHARACTER_SAMANTHA && newCharacter == CHARACTER_HOPKINS
+ && _vm->_globals._saveData->_realHopkins._location == _vm->_globals._screenId) {
+ _changeHeadFl = false;
+ loc = &_vm->_globals._saveData->_samantha;
+ loc->_pos.x = getSpriteX(0);
+ loc->_pos.y = getSpriteY(0);
+ loc->_startSpriteIndex = 64;
+ loc->_location = _vm->_globals._screenId;
+ loc->_zoomFactor = _sprite[0]._animationType;
+
+ removeSprite(1);
+ addStaticSprite(_headSprites, loc->_pos, 1, 3, loc->_zoomFactor, false, 20, 127);
+ animateSprite(1);
+ removeSprite(0);
+
+ _vm->_globals._saveData->_data[svField354] = 0;
+ _vm->_globals._saveData->_data[svField356] = 0;
+ _vm->_globals._saveData->_data[svField357] = 1;
+
+ loc = &_vm->_globals._saveData->_realHopkins;
+ _vm->_globals.PERSO = _vm->_fileManager.loadFile("PERSO.SPR");
+ _vm->_globals._characterType = 0;
+ addStaticSprite(_vm->_globals.PERSO, loc->_pos, 0, 64, loc->_zoomFactor, false, 34, 190);
+ animateSprite(0);
+ _vm->_globals.loadCharacterData();
+ } else if (oldCharacter == CHARACTER_HOPKINS && newCharacter == CHARACTER_SAMANTHA
+ && _vm->_globals._saveData->_samantha._location == _vm->_globals._screenId) {
+ _changeHeadFl = false;
+ loc = &_vm->_globals._saveData->_realHopkins;
+ loc->_pos.x = getSpriteX(0);
+ loc->_pos.y = getSpriteY(0);
+ loc->_startSpriteIndex = 64;
+ loc->_location = _vm->_globals._screenId;
+ loc->_zoomFactor = _sprite[0]._zoomFactor;
+
+ removeSprite(1);
+ addStaticSprite(_headSprites, loc->_pos, 1, 2, loc->_zoomFactor, false, 34, 190);
+ animateSprite(1);
+ removeSprite(0);
+
+ _vm->_globals._saveData->_data[svField354] = 0;
+ _vm->_globals._saveData->_data[svField356] = 1;
+ _vm->_globals._saveData->_data[svField357] = 0;
+
+ loc = &_vm->_globals._saveData->_samantha;
+ _vm->_globals.PERSO = _vm->_fileManager.loadFile("PSAMAN.SPR");
+ _vm->_globals._characterType = 2;
+ addStaticSprite(_vm->_globals.PERSO, loc->_pos, 0, 64, loc->_zoomFactor, false, 20, 127);
+ animateSprite(0);
+ _vm->_globals.loadCharacterData();
+ } else {
+ switch (oldCharacter) {
+ case CHARACTER_HOPKINS:
+ loc = &_vm->_globals._saveData->_realHopkins;
+ loc->_pos.x = getSpriteX(0);
+ loc->_pos.y = getSpriteY(0);
+ loc->_startSpriteIndex = 64;
+ loc->_location = _vm->_globals._screenId;
+ loc->_zoomFactor = _sprite[0]._zoomFactor;
+ break;
+ case CHARACTER_HOPKINS_CLONE:
+ loc = &_vm->_globals._saveData->_cloneHopkins;
+ loc->_pos.x = getSpriteX(0);
+ loc->_pos.y = getSpriteY(0);
+ loc->_startSpriteIndex = 64;
+ loc->_location = _vm->_globals._screenId;
+ loc->_zoomFactor = _sprite[0]._zoomFactor;
+ break;
+ case CHARACTER_SAMANTHA:
+ loc = &_vm->_globals._saveData->_samantha;
+ loc->_pos.x = getSpriteX(0);
+ loc->_pos.y = getSpriteY(0);
+ loc->_startSpriteIndex = 64;
+ loc->_location = _vm->_globals._screenId;
+ loc->_zoomFactor = _sprite[0]._zoomFactor;
+ break;
+ default:
+ break;
+ }
+
+ switch (newCharacter) {
+ case CHARACTER_HOPKINS:
+ _vm->_globals._saveData->_data[svField121] = 0;
+ _vm->_globals._saveData->_data[svField354] = 0;
+ _vm->_globals._saveData->_data[svField356] = 0;
+ _vm->_globals._saveData->_data[svField357] = 1;
+ _vm->_globals._exitId = _vm->_globals._saveData->_realHopkins._location;
+ break;
+ case CHARACTER_HOPKINS_CLONE:
+ _vm->_globals._saveData->_data[svField121] = 1;
+ _vm->_globals._saveData->_data[svField354] = 1;
+ _vm->_globals._saveData->_data[svField356] = 0;
+ _vm->_globals._saveData->_data[svField357] = 0;
+ _vm->_globals._exitId = _vm->_globals._saveData->_cloneHopkins._location;
+ break;
+ case CHARACTER_SAMANTHA:
+ _vm->_globals._saveData->_data[svField121] = 0;
+ _vm->_globals._saveData->_data[svField354] = 0;
+ _vm->_globals._saveData->_data[svField356] = 1;
+ _vm->_globals._saveData->_data[svField357] = 0;
+ _vm->_globals._exitId = _vm->_globals._saveData->_samantha._location;
+ break;
+ }
+ }
+}
+
+// Check Size
+void ObjectsManager::computeAndSetSpriteSize() {
+ int size = _vm->_globals._spriteSize[getSpriteY(0)];
+ if (_vm->_globals._characterType == 1) {
+ size = 20 * (5 * abs(size) - 100) / -80;
+ } else if (_vm->_globals._characterType == 2) {
+ size = 20 * (5 * abs(size) - 165) / -67;
+ }
+ setSpriteZoom(0, size);
+}
+
+/**
+ * Get next verb icon (or text)
+ */
+void ObjectsManager::nextVerbIcon() {
+ _vm->_eventsManager._mouseCursorId++;
+
+ for(;;) {
+ if (_vm->_eventsManager._mouseCursorId == 4) {
+ if (!_vm->_globals._freezeCharacterFl || _zoneNum == -1 || _zoneNum == 0)
+ return;
+
+ ++_vm->_eventsManager._mouseCursorId;
+ }
+
+ if (_vm->_eventsManager._mouseCursorId == 5 || _vm->_eventsManager._mouseCursorId == 6) {
+ _vm->_eventsManager._mouseCursorId = 6;
+ if (_vm->_linesManager.ZONEP[_zoneNum]._verbFl1 == 1)
+ return;
+
+ ++_vm->_eventsManager._mouseCursorId;
+ }
+
+ if (_vm->_eventsManager._mouseCursorId == 7) {
+ if (_vm->_linesManager.ZONEP[_zoneNum]._verbFl2 == 1)
+ return;
+
+ ++_vm->_eventsManager._mouseCursorId;
+ }
+
+ if (_vm->_eventsManager._mouseCursorId == 8) {
+ if (_vm->_linesManager.ZONEP[_zoneNum]._verbFl3 == 1)
+ return;
+
+ ++_vm->_eventsManager._mouseCursorId;
+ }
+
+ if (_vm->_eventsManager._mouseCursorId == 9) {
+ if (_vm->_linesManager.ZONEP[_zoneNum]._verbFl4 == 1)
+ return;
+
+ ++_vm->_eventsManager._mouseCursorId;
+ }
+
+ if (_vm->_eventsManager._mouseCursorId == 10) {
+ if (_vm->_linesManager.ZONEP[_zoneNum]._verbFl5 == 1)
+ return;
+ ++_vm->_eventsManager._mouseCursorId;
+ }
+
+ if (_vm->_eventsManager._mouseCursorId == 11) {
+ if (_vm->_linesManager.ZONEP[_zoneNum]._verbFl6 == 1)
+ return;
+
+ ++_vm->_eventsManager._mouseCursorId;
+ }
+
+ if (_vm->_eventsManager._mouseCursorId == 12) {
+ if (_vm->_linesManager.ZONEP[_zoneNum]._verbFl7 == 1)
+ return;
+
+ ++_vm->_eventsManager._mouseCursorId;
+ }
+
+ if (_vm->_eventsManager._mouseCursorId == 13) {
+ if (_vm->_linesManager.ZONEP[_zoneNum]._verbFl8 == 1)
+ return;
+
+ ++_vm->_eventsManager._mouseCursorId;
+ }
+
+ if (_vm->_eventsManager._mouseCursorId == 14) {
+ if (_vm->_linesManager.ZONEP[_zoneNum]._verbFl9 == 1)
+ return;
+
+ ++_vm->_eventsManager._mouseCursorId;
+ }
+
+ if (_vm->_eventsManager._mouseCursorId == 15) {
+ if (_vm->_linesManager.ZONEP[_zoneNum]._verbFl10 == 1)
+ return;
+
+ ++_vm->_eventsManager._mouseCursorId;
+ }
+
+ if (_vm->_eventsManager._mouseCursorId == 16) {
+ if (_vm->_linesManager.ZONEP[_zoneNum]._verbFl1 == 2)
+ return;
+
+ ++_vm->_eventsManager._mouseCursorId;
+ }
+
+ if (_vm->_eventsManager._mouseCursorId == 17) {
+ if (_vm->_linesManager.ZONEP[_zoneNum]._verbFl4 == 2)
+ return;
+
+ ++_vm->_eventsManager._mouseCursorId;
+ }
+
+ if (_vm->_eventsManager._mouseCursorId == 18) {
+ if (_vm->_linesManager.ZONEP[_zoneNum]._verbFl5 == 2)
+ return;
+
+ ++_vm->_eventsManager._mouseCursorId;
+ }
+
+ if (_vm->_eventsManager._mouseCursorId == 19) {
+ if (_vm->_linesManager.ZONEP[_zoneNum]._verbFl6 == 2)
+ return;
+
+ ++_vm->_eventsManager._mouseCursorId;
+ }
+
+ if (_vm->_eventsManager._mouseCursorId == 20) {
+ if (_vm->_linesManager.ZONEP[_zoneNum]._verbFl7 == 2)
+ return;
+
+ ++_vm->_eventsManager._mouseCursorId;
+ }
+
+ if (_vm->_eventsManager._mouseCursorId == 21) {
+ if (_vm->_linesManager.ZONEP[_zoneNum]._verbFl10 == 2)
+ return;
+
+ ++_vm->_eventsManager._mouseCursorId;
+ }
+
+ if (_vm->_eventsManager._mouseCursorId == 22) {
+ if (_vm->_linesManager.ZONEP[_zoneNum]._verbFl8 == 2)
+ return;
+
+ ++_vm->_eventsManager._mouseCursorId;
+ }
+
+ if (_vm->_eventsManager._mouseCursorId == 23) {
+ if (_vm->_linesManager.ZONEP[_zoneNum]._verbFl3 == 2)
+ return;
+
+ ++_vm->_eventsManager._mouseCursorId;
+ }
+
+ if (_vm->_eventsManager._mouseCursorId == 24) {
+ if (_vm->_linesManager.ZONEP[_zoneNum]._verbFl4 == 3)
+ return;
+
+ ++_vm->_eventsManager._mouseCursorId;
+ }
+
+ if (_vm->_eventsManager._mouseCursorId == 25) {
+ if (_vm->_linesManager.ZONEP[_zoneNum]._verbFl9 == 2)
+ return;
+ }
+ _vm->_eventsManager._mouseCursorId = 4;
+ }
+}
+
+/**
+ * Handle Right button
+ */
+void ObjectsManager::handleRightButton() {
+ if (_zoneNum != -1 && _zoneNum != 0) {
+ nextVerbIcon();
+ if (_vm->_eventsManager._mouseCursorId != 23)
+ _vm->_eventsManager.changeMouseCursor(_vm->_eventsManager._mouseCursorId);
+ _verb = _vm->_eventsManager._mouseCursorId;
+ }
+}
+
+/**
+ * Prepare border used to highlight the place below mouse cursor, in the inventory.
+ * Also set the mouse cursor
+ */
+void ObjectsManager::initBorder(int zoneIdx) {
+ _oldBorderPos = _borderPos;
+ _oldBorderSpriteIndex = _borderSpriteIndex;
+ if (zoneIdx >= 1 && zoneIdx <= 6)
+ _borderPos.y = 120;
+ else if (zoneIdx >= 7 && zoneIdx <= 12)
+ _borderPos.y = 158;
+ else if (zoneIdx >= 13 && zoneIdx <= 18)
+ _borderPos.y = 196;
+ else if (zoneIdx >= 19 && zoneIdx <= 24)
+ _borderPos.y = 234;
+ else if (zoneIdx >= 25 && zoneIdx <= 29)
+ _borderPos.y = 272;
+ else if (zoneIdx == 30)
+ _borderPos.y = 272;
+ else if (zoneIdx == 31)
+ _borderPos.y = 290;
+
+ if (zoneIdx == 1 || zoneIdx == 7 || zoneIdx == 13 || zoneIdx == 19 || zoneIdx == 25)
+ _borderPos.x = _vm->_graphicsManager._scrollOffset + 158;
+ else if (zoneIdx == 2 || zoneIdx == 8 || zoneIdx == 14 || zoneIdx == 20 || zoneIdx == 26)
+ _borderPos.x = _vm->_graphicsManager._scrollOffset + 212;
+ else if (zoneIdx == 3 || zoneIdx == 9 || zoneIdx == 15 || zoneIdx == 21 || zoneIdx == 27)
+ _borderPos.x = _vm->_graphicsManager._scrollOffset + 266;
+ else if (zoneIdx == 4 || zoneIdx == 10 || zoneIdx == 16 || zoneIdx == 22 || zoneIdx == 28)
+ _borderPos.x = _vm->_graphicsManager._scrollOffset + 320;
+ else if (zoneIdx == 5 || zoneIdx == 11 || zoneIdx == 17 || zoneIdx == 23 || zoneIdx == 29)
+ _borderPos.x = _vm->_graphicsManager._scrollOffset + 374;
+ else if (zoneIdx == 6 || zoneIdx == 12 || zoneIdx == 18 || zoneIdx == 24 || zoneIdx == 30 || zoneIdx == 31)
+ _borderPos.x = _vm->_graphicsManager._scrollOffset + 428;
+
+ if (zoneIdx >= 1 && zoneIdx <= 29)
+ _borderSpriteIndex = 0;
+ else if (zoneIdx == 30 || zoneIdx == 31)
+ _borderSpriteIndex = 2;
+ else if (!zoneIdx || zoneIdx == 32) {
+ _borderPos = Common::Point(0, 0);
+ _borderSpriteIndex = 0;
+ }
+
+ if (!zoneIdx)
+ _vm->_eventsManager._mouseCursorId = 0;
+ else if (zoneIdx >= 1 && zoneIdx <= 28)
+ _vm->_eventsManager._mouseCursorId = 8;
+ else if (zoneIdx == 29)
+ _vm->_eventsManager._mouseCursorId = 1;
+ else if (zoneIdx == 30)
+ _vm->_eventsManager._mouseCursorId = 2;
+ else if (zoneIdx == 31)
+ _vm->_eventsManager._mouseCursorId = 3;
+ else if (zoneIdx == 32)
+ _vm->_eventsManager._mouseCursorId = 16;
+
+ if (zoneIdx >= 1 && zoneIdx <= 28 && !_vm->_globals._inventory[zoneIdx]) {
+ _vm->_eventsManager._mouseCursorId = 0;
+ _borderPos = Common::Point(0, 0);
+ _borderSpriteIndex = 0;
+ }
+
+ if (_vm->_eventsManager._mouseCursorId != 23)
+ _vm->_eventsManager.changeMouseCursor(_vm->_eventsManager._mouseCursorId);
+ _vm->_eventsManager.getMouseX();
+ _vm->_eventsManager.getMouseY();
+}
+
+/**
+ * Get next icon for an object in the inventory
+ */
+void ObjectsManager::nextObjectIcon(int idx) {
+ if (_vm->_eventsManager._mouseCursorId == 0 || _vm->_eventsManager._mouseCursorId == 2 ||
+ _vm->_eventsManager._mouseCursorId == 3 || _vm->_eventsManager._mouseCursorId == 16)
+ return;
+
+ int nextCursorId = _vm->_eventsManager._mouseCursorId + 1;
+ if (nextCursorId > 25)
+ nextCursorId = 6;
+
+ do {
+ if (nextCursorId == 2 || nextCursorId == 5 || nextCursorId == 6) {
+ _vm->_eventsManager._mouseCursorId = 6;
+ if (_vm->_globals._objectAuthIcons[_vm->_globals._inventory[idx]]._flag1 == 1)
+ return;
+ nextCursorId++;
+ }
+ if (nextCursorId == 7) {
+ _vm->_eventsManager._mouseCursorId = 7;
+ if (_vm->_globals._objectAuthIcons[_vm->_globals._inventory[idx]]._flag2 == 1)
+ return;
+ nextCursorId++;
+ }
+ if (nextCursorId == 8) {
+ _vm->_eventsManager._mouseCursorId = 8;
+ return;
+ }
+ if (nextCursorId == 9 || nextCursorId == 10) {
+ _vm->_eventsManager._mouseCursorId = 10;
+ if (_vm->_globals._objectAuthIcons[_vm->_globals._inventory[idx]]._flag6 == 1)
+ return;
+ nextCursorId = 11;
+ }
+
+ if (nextCursorId == 11) {
+ _vm->_eventsManager._mouseCursorId = 11;
+ if (_vm->_globals._objectAuthIcons[_vm->_globals._inventory[idx]]._flag3 == 1)
+ return;
+ nextCursorId++;
+ }
+
+ if (nextCursorId == 12 || nextCursorId == 13) {
+ _vm->_eventsManager._mouseCursorId = 13;
+ if (_vm->_globals._objectAuthIcons[_vm->_globals._inventory[idx]]._flag4 == 1)
+ return;
+ nextCursorId = 14;
+ }
+
+ if (nextCursorId == 14 || nextCursorId == 15) {
+ _vm->_eventsManager._mouseCursorId = 15;
+ if (_vm->_globals._objectAuthIcons[_vm->_globals._inventory[idx]]._flag5 == 1)
+ return;
+ nextCursorId = 23;
+ }
+
+ if (nextCursorId >= 16 && nextCursorId <= 23) {
+ _vm->_eventsManager._mouseCursorId = 23;
+ if (_vm->_globals._objectAuthIcons[_vm->_globals._inventory[idx]]._flag5 == 2)
+ return;
+ nextCursorId = 24;
+ }
+
+ if (nextCursorId == 24 || nextCursorId == 25) {
+ _vm->_eventsManager._mouseCursorId = 25;
+ }
+
+ nextCursorId = 6;
+ } while (_vm->_globals._objectAuthIcons[_vm->_globals._inventory[idx]]._flag6 != 2);
+}
+
+void ObjectsManager::takeInventoryObject(int idx) {
+ if (_vm->_eventsManager._mouseCursorId == 8)
+ changeObject(idx);
+}
+
+void ObjectsManager::OPTI_OBJET() {
+ byte *data;
+ Common::String file;
+ int lastOpcodeResult = 1;
+
+ file = "OBJET1.ini";
+ data = _vm->_fileManager.searchCat(file, 1);
+ if (data == g_PTRNUL) {
+ data = _vm->_fileManager.loadFile(file);
+ if (data == g_PTRNUL)
+ error("INI file %s not found", file.c_str());
+ }
+
+ if (READ_BE_UINT24(data) != MKTAG24('I', 'N', 'I'))
+ error("File %s is not an INI file", file.c_str());
+
+ for (;;) {
+ int opcodeType = _vm->_scriptManager.handleOpcode(data + 20 * lastOpcodeResult);
+ if (_vm->shouldQuit())
+ return;
+
+ if (opcodeType == 2)
+ lastOpcodeResult = _vm->_scriptManager.handleGoto(data + 20 * lastOpcodeResult);
+ else if (opcodeType == 3)
+ lastOpcodeResult = _vm->_scriptManager.handleIf(data, lastOpcodeResult);
+
+ if (lastOpcodeResult == -1)
+ error("defective IFF function");
+
+ if (opcodeType == 1 || opcodeType == 4)
+ ++lastOpcodeResult;
+ else if (!opcodeType || opcodeType == 5)
+ break;
+ }
+
+ _vm->_globals.freeMemory(data);
+}
+
+void ObjectsManager::handleSpecialGames() {
+ byte *oldPalette;
+
+ switch (_vm->_globals._screenId) {
+ case 5:
+ if ((getSpriteY(0) > 399) || _vm->_globals._saveData->_data[svField173])
+ break;
+
+ _vm->_globals._saveData->_data[svField173] = 1;
+ _vm->_globals._introSpeechOffFl = true;
+ _vm->_talkManager.startAnimatedCharacterDialogue("flicspe1.pe2");
+ _vm->_globals._introSpeechOffFl = false;
+
+ if (_vm->_globals._censorshipFl)
+ break;
+
+ oldPalette = _vm->_globals.allocMemory(1000);
+ memcpy(oldPalette, _vm->_graphicsManager._palette, 769);
+
+ _vm->_saveLoadManager.saveFile("TEMP1.SCR", _vm->_graphicsManager._vesaScreen, 307200);
+
+ if (!_vm->_graphicsManager._lineNbr)
+ _vm->_graphicsManager._scrollOffset = 0;
+ _vm->_graphicsManager.NB_SCREEN(true);
+ _vm->_soundManager._specialSoundNum = 198;
+ PERSO_ON = true;
+ _vm->_animationManager.NO_SEQ = true;
+ _vm->_animationManager._clearAnimationFl = false;
+ _vm->_animationManager.playAnim("otage.ANM", 1, 24, 500);
+ _vm->_animationManager.NO_SEQ = false;
+ _vm->_soundManager._specialSoundNum = 0;
+ _vm->_graphicsManager.NB_SCREEN(false);
+
+ _vm->_saveLoadManager.load("TEMP1.SCR", _vm->_graphicsManager._vesaScreen);
+ g_system->getSavefileManager()->removeSavefile("TEMP1.SCR");
+
+ PERSO_ON = false;
+ memcpy(_vm->_graphicsManager._palette, oldPalette, 769);
+ _vm->_graphicsManager.setPaletteVGA256(_vm->_graphicsManager._palette);
+ _vm->_globals.freeMemory(oldPalette);
+ _vm->_graphicsManager.lockScreen();
+ _vm->_graphicsManager.m_scroll16(_vm->_graphicsManager._vesaScreen, _vm->_eventsManager._startPos.x, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, 0);
+ _vm->_graphicsManager.unlockScreen();
+ memcpy(_vm->_graphicsManager._vesaBuffer, _vm->_graphicsManager._vesaScreen, 614399);
+
+ _vm->_graphicsManager._scrollStatus = 0;
+ _vm->_graphicsManager.DD_VBL();
+ break;
+ case 20:
+ _vm->_globals._saveData->_data[svField132] = (getSpriteX(0) > 65 && getSpriteX(0) <= 124 && getSpriteY(0) > 372 && getSpriteY(0) <= 398) ? 1 : 0;
+ break;
+ case 35:
+ if (_vm->_globals._prevScreenId == 16)
+ handleForest(35, 500, 555, 100, 440, 1);
+ else if (_vm->_globals._prevScreenId == 36)
+ handleForest(35, 6, 84, 100, 440, 4);
+ break;
+ case 36:
+ if (_vm->_globals._prevScreenId == 35)
+ handleForest(36, 551, 633, 100, 440, 2);
+ else if (_vm->_globals._prevScreenId == 37)
+ handleForest(36, 6, 84, 100, 440, 4);
+ break;
+ case 37:
+ if (_vm->_globals._prevScreenId == 36)
+ handleForest(37, 551, 633, 100, 440, 1);
+ else if (_vm->_globals._prevScreenId == 38)
+ handleForest(37, 392, 529, 100, 440, 2);
+ break;
+ case 38:
+ if (_vm->_globals._prevScreenId == 37)
+ handleForest(38, 133, 252, 100, 440, 4);
+ else if (_vm->_globals._prevScreenId == 39)
+ handleForest(38, 6, 84, 100, 440, 3);
+ break;
+ case 39:
+ if (_vm->_globals._prevScreenId == 38)
+ handleForest(39, 551, 633, 100, 440, 2);
+ else if (_vm->_globals._prevScreenId == 40)
+ handleForest(39, 6, 84, 100, 440, 3);
+ break;
+ case 40:
+ if (_vm->_globals._prevScreenId == 39)
+ handleForest(40, 133, 252, 100, 440, 4);
+ else if (_vm->_globals._prevScreenId == 41)
+ handleForest(40, 392, 529, 100, 440, 2);
+ break;
+ case 41:
+ if (_vm->_globals._prevScreenId == 40)
+ handleForest(41, 551, 633, 100, 440, 1);
+ else if (_vm->_globals._prevScreenId == 17)
+ handleForest(41, 6, 84, 100, 440, 3);
+ break;
+ case 57:
+ _vm->_globals._disableInventFl = true;
+ if (_vm->_globals._saveData->_data[svField261] == 1 && getBobAnimDataIdx(5) == 37) {
+ stopBobAnimation(5);
+ setBobAnimDataIdx(5, 0);
+ setBobAnimation(6);
+ _vm->_globals._saveData->_data[svField261] = 2;
+ _vm->_linesManager.disableZone(15);
+ _vm->_soundManager.playSoundFile("SOUND75.WAV");
+ }
+ if (_vm->_globals._saveData->_data[svField261] == 2 && getBobAnimDataIdx(6) == 6) {
+ stopBobAnimation(6);
+ setBobAnimDataIdx(6, 0);
+ setBobAnimation(7);
+ _vm->_linesManager.enableZone(14);
+ _vm->_globals._saveData->_data[svField261] = 3;
+ }
+ _vm->_globals._disableInventFl = false;
+ break;
+ case 93:
+ if (_vm->_globals._saveData->_data[svField333])
+ break;
+
+ _vm->_globals._disableInventFl = true;
+ do
+ _vm->_eventsManager.VBL();
+ while (getBobAnimDataIdx(8) != 3);
+ _vm->_globals._introSpeechOffFl = true;
+ _vm->_talkManager.startAnimatedCharacterDialogue("GM3.PE2");
+ stopBobAnimation(8);
+ _vm->_globals._saveData->_data[svField333] = 1;
+ _vm->_globals._disableInventFl = false;
+ break;
+ }
+}
+
+void ObjectsManager::BOB_VIVANT(int idx) {
+ int startPos = 10 * idx;
+ if (!READ_LE_UINT16(_vm->_talkManager._characterAnim + startPos + 4))
+ return;
+
+ int xp = READ_LE_INT16(_vm->_talkManager._characterAnim + startPos);
+ int yp = READ_LE_INT16(_vm->_talkManager._characterAnim + startPos + 2);
+ int spriteIndex = _vm->_talkManager._characterAnim[startPos + 8];
+
+ _vm->_graphicsManager.fastDisplay(_vm->_talkManager._characterSprite, xp, yp, spriteIndex);
+}
+
+void ObjectsManager::VBOB(byte *src, int idx, int xp, int yp, int frameIndex) {
+ if (idx > 29)
+ error("MAX_VBOB exceeded");
+
+ VBobItem *vbob = &_vm->_globals.VBob[idx];
+ if (vbob->field4 <= 1) {
+ vbob->field4 = 1;
+ vbob->_xp = xp;
+ vbob->_yp = yp;
+ vbob->_frameIndex = frameIndex;
+ vbob->_oldX = xp;
+ vbob->_oldY = yp;
+ vbob->_oldFrameIndex = frameIndex;
+ vbob->_spriteData = src;
+ vbob->_oldSpriteData = src;
+ vbob->_surface = _vm->_globals.freeMemory(vbob->_surface);
+ } else if (vbob->field4 == 2 || vbob->field4 == 4) {
+ vbob->field4 = 3;
+ vbob->_oldX = vbob->_xp;
+ vbob->_oldY = vbob->_yp;
+ vbob->_oldSpriteData = vbob->_spriteData;
+ vbob->_oldFrameIndex = vbob->_frameIndex;
+ vbob->_xp = xp;
+ vbob->_yp = yp;
+ vbob->_frameIndex = frameIndex;
+ vbob->_spriteData = src;
+ }
+}
+
+void ObjectsManager::VBOB_OFF(int idx) {
+ if (idx > 29)
+ error("MAX_VBOB exceeded");
+
+ VBobItem *vbob = &_vm->_globals.VBob[idx];
+ if (vbob->field4 <= 1)
+ vbob->field4 = 0;
+ else
+ vbob->field4 = 4;
+}
+
+void ObjectsManager::doActionBack(int idx) {
+ if (_curGestureFile != 1) {
+ _gestureBuf = _vm->_globals.freeMemory(_gestureBuf);
+ _curGestureFile = 1;
+ _gestureBuf = _vm->_fileManager.loadFile("DOS.SPR");
+ }
+
+ switch (idx) {
+ case 1:
+ ACTION(_gestureBuf, "0,1,2,3,4,5,6,7,8,8,8,8,8,8,7,6,5,4,3,2,1,0,-1,", 0, 0, 8, false);
+ break;
+ case 2:
+ SPACTION(_gestureBuf, "0,1,2,3,4,5,6,7,8,9,10,11,12,13,-1,", 0, 0, 8, false);
+ break;
+ case 3:
+ SPACTION1(_gestureBuf, "12,11,10,9,8,7,6,5,4,3,2,1,0,-1,", 0, 0, 8);
+ break;
+ case 4:
+ ACTION(_gestureBuf, "0,1,2,3,4,5,6,7,8,8,8,8,8,8,9,10,11,12,13,12,11,12,13,12,11,12,13,12,11,10,9,8,7,6,5,4,3,2,1,0,-1,", 0, 0, 8, false);
+ break;
+ case 5:
+ SPACTION(_gestureBuf, "15,16,17,18,19,20,21,-1,", 0, 0, 8, false);
+ break;
+ case 6:
+ SPACTION1(_gestureBuf, "20,19,18,17,16,15,-1,", 0, 0, 8);
+ break;
+ case 7:
+ SPACTION(_gestureBuf, "15,16,17,18,19,20,21,22,23,24,-1,", 0, 0, 8, false);
+ break;
+ case 8:
+ SPACTION1(_gestureBuf, "23,22,21,20,19,18,17,16,15,-1,", 0, 0, 8);
+ break;
+ case 9:
+ SPACTION(_gestureBuf, "15,16,17,18,19,20,21,22,23,24,-1,", 0, 0, 8, false);
+ break;
+ case 10:
+ SPACTION1(_gestureBuf, "23,22,21,20,19,18,17,16,15,-1,", 0, 0, 8);
+ break;
+ }
+}
+
+void ObjectsManager::doActionRight(int idx) {
+ if (_curGestureFile != 3) {
+ _gestureBuf = _vm->_globals.freeMemory(_gestureBuf);
+ _curGestureFile = 3;
+ _gestureBuf = _vm->_fileManager.loadFile("PROFIL.SPR");
+ }
+
+ switch (idx) {
+ case 1:
+ ACTION(_gestureBuf, "20,19,18,17,16,15,14,13,13,13,13,13,14,15,16,17,18,19,20,-1,", 0, 0, 8, false);
+ break;
+ case 2:
+ SPACTION(_gestureBuf, "1,2,3,4,5,6,7,8,-1,", 0, 0, 8, false);
+ break;
+ case 3:
+ SPACTION1(_gestureBuf, "9,10,11,12,13,14,15,16,17,18,19,20,-1,", 0, 0, 8);
+ break;
+ case 4:
+ ACTION(_gestureBuf, "1,2,3,4,5,6,7,8,8,7,6,5,4,3,2,1,-1,", 0, 0, 8, false);
+ break;
+ case 5:
+ SPACTION(_gestureBuf, "23,24,25,-1,", 0, 0, 8, false);
+ break;
+ case 6:
+ SPACTION1(_gestureBuf, "24,,23,-1,", 0, 0, 8);
+ break;
+ case 7:
+ SPACTION(_gestureBuf, "23,24,25,26,27,-1,", 0, 0, 8, false);
+ break;
+ case 8:
+ SPACTION1(_gestureBuf, "26,25,24,23,-1,", 0, 0, 8);
+ break;
+ case 9:
+ SPACTION(_gestureBuf, "23,24,25,26,27,28,29,-1,", 0, 0, 8, false);
+ break;
+ case 10:
+ SPACTION1(_gestureBuf, "28,27,26,25,24,23,-1,", 0, 0, 8);
+ break;
+ }
+}
+
+void ObjectsManager::doActionDiagRight(int idx) {
+ if (_curGestureFile != 4) {
+ _gestureBuf = _vm->_globals.freeMemory(_gestureBuf);
+ _curGestureFile = 4;
+ _gestureBuf = _vm->_fileManager.loadFile("3Q.SPR");
+ }
+
+ switch (idx) {
+ case 1:
+ ACTION(_gestureBuf, "0,1,2,3,4,5,6,7,8,8,8,8,8,7,6,5,4,3,2,1,0,-1,", 0, 0, 8, false);
+ break;
+ case 2:
+ SPACTION(_gestureBuf, "0,1,2,3,4,5,6,7,8,9,10,11,12,-1,", 0, 0, 8, false);
+ break;
+ case 3:
+ SPACTION1(_gestureBuf, "11,10,9,8,7,6,5,4,3,2,1,0,-1,", 0, 0, 8);
+ break;
+ case 4:
+ ACTION(_gestureBuf, "0,1,2,3,4,5,6,7,8,9,10,11,12,11,12,11,12,11,12,11,10,9,8,7,6,5,4,3,2,1,0,-1,", 0, 0, 8, false);
+ break;
+ case 5:
+ SPACTION(_gestureBuf, "15,16,17,18,-1,", 0, 0, 8, false);
+ break;
+ case 6:
+ SPACTION1(_gestureBuf, "17,16,15,-1,", 0, 0, 8);
+ break;
+ case 7:
+ SPACTION(_gestureBuf, "15,16,17,18,19,20-1,", 0, 0, 8, false);
+ break;
+ case 8:
+ SPACTION1(_gestureBuf, "19,18,17,16,15,-1,", 0, 0, 8);
+ break;
+ case 9:
+ SPACTION(_gestureBuf, "15,16,17,18,19,20,21,-1,", 0, 0, 8, false);
+ break;
+ case 10:
+ SPACTION1(_gestureBuf, "20,19,18,17,15,-1,", 0, 0, 8);
+ break;
+ }
+}
+
+void ObjectsManager::doActionFront(int idx) {
+ if (_curGestureFile != 2) {
+ _gestureBuf = _vm->_globals.freeMemory(_gestureBuf);
+ _curGestureFile = 2;
+ _gestureBuf = _vm->_fileManager.loadFile("FACE.SPR");
+ }
+
+ switch (idx) {
+ case 1:
+ ACTION(_gestureBuf, "0,1,2,3,4,5,6,7,9,9,9,9,9,9,7,6,5,4,3,2,1,0,-1,", 0, 0, 8, false);
+ break;
+ case 2:
+ SPACTION(_gestureBuf, "0,1,2,3,4,5,6,7,9,10,11,12,13,14,15,-1,", 0, 0, 8, false);
+ break;
+ case 3:
+ SPACTION1(_gestureBuf, "14,13,12,11,10,9,7,6,5,4,3,2,1,0,-1,", 0, 0, 8);
+ break;
+ case 4:
+ ACTION(_gestureBuf, "0,1,2,3,4,5,6,7,9,10,11,12,13,14,13,12,11,10,9,7,6,5,4,3,2,1,0,-1,", 0, 0, 8, false);
+ break;
+ }
+}
+
+void ObjectsManager::doActionDiagLeft(int idx) {
+ if (_curGestureFile != 4) {
+ _gestureBuf = _vm->_globals.freeMemory(_gestureBuf);
+ _curGestureFile = 4;
+ _gestureBuf = _vm->_fileManager.loadFile("3Q.SPR");
+ }
+
+ switch (idx) {
+ case 1:
+ ACTION(_gestureBuf, "0,1,2,3,4,5,6,7,8,8,8,8,8,7,6,5,4,3,2,1,0,-1,", 0, 0, 8, true);
+ break;
+ case 2:
+ SPACTION(_gestureBuf, "0,1,2,3,4,5,6,7,8,9,10,11,12,-1,", 0, 0, 8, true);
+ break;
+ case 3:
+ SPACTION1(_gestureBuf, "11,10,9,8,7,6,5,4,3,2,1,0,-1,", 0, 0, 8);
+ break;
+ case 4:
+ ACTION(_gestureBuf, "0,1,2,3,4,5,6,7,8,9,10,11,12,11,12,11,12,11,12,11,10,9,8,7,6,5,4,3,2,1,0,-1,", 0, 0, 8, true);
+ break;
+ case 5:
+ SPACTION(_gestureBuf, "15,16,17,18,-1,", 0, 0, 8, true);
+ break;
+ case 6:
+ SPACTION1(_gestureBuf, "17,16,15,-1,", 0, 0, 8);
+ break;
+ case 7:
+ SPACTION(_gestureBuf, "15,16,17,18,19,20,-1,", 0, 0, 8, true);
+ break;
+ case 8:
+ SPACTION1(_gestureBuf, "19,18,17,16,15,-1,", 0, 0, 8);
+ break;
+ case 9:
+ SPACTION(_gestureBuf, "15,16,17,18,19,20,21,-1,", 0, 0, 8, true);
+ break;
+ case 10:
+ SPACTION1(_gestureBuf, "20,19,18,17,15,-1,", 0, 0, 8);
+ break;
+ }
+}
+
+void ObjectsManager::doActionLeft(int idx) {
+ if (_curGestureFile != 3) {
+ _gestureBuf = _vm->_globals.freeMemory(_gestureBuf);
+ _curGestureFile = 3;
+ _gestureBuf = _vm->_fileManager.loadFile("PROFIL.SPR");
+ }
+
+ switch (idx) {
+ case 1:
+ ACTION(_gestureBuf, "20,19,18,17,16,15,14,13,13,13,13,13,14,15,16,17,18,19,20,-1,", 0, 0, 8, true);
+ break;
+ case 2:
+ SPACTION(_gestureBuf, "1,2,3,4,5,6,7,8,-1,", 0, 0, 8, true);
+ break;
+ case 3:
+ SPACTION1(_gestureBuf, "9,10,11,12,13,14,15,16,17,18,19,20,-1,", 0, 0, 8);
+ break;
+ case 4:
+ ACTION(_gestureBuf, "1,2,3,4,5,6,7,8,8,7,6,5,4,3,2,1,-1,", 0, 0, 8, true);
+ break;
+ case 5:
+ SPACTION(_gestureBuf, "23,24,25,-1,", 0, 0, 8, true);
+ break;
+ case 6:
+ SPACTION1(_gestureBuf, "24,,23,-1,", 0, 0, 8);
+ break;
+ case 7:
+ SPACTION(_gestureBuf, "23,24,25,26,27,-1,", 0, 0, 8, true);
+ break;
+ case 8:
+ SPACTION1(_gestureBuf, "26,25,24,23,-1,", 0, 0, 8);
+ break;
+ case 9:
+ SPACTION(_gestureBuf, "23,24,25,26,27,28,29,-1,", 0, 0, 8, true);
+ break;
+ case 10:
+ SPACTION1(_gestureBuf, "28,27,26,25,24,23,-1,", 0, 0, 8);
+ break;
+ }
+}
+
+void ObjectsManager::OPTI_ONE(int idx, int animIdx, int destPosi, int animAction) {
+ // Set Hopkins animation and position
+ if (animAction != 3) {
+ setBobAnimation(idx);
+ setBobAnimDataIdx(idx, animIdx);
+ }
+
+ // Make Hopkins walk to the expected place
+ do {
+ _vm->_eventsManager.VBL();
+ } while (destPosi != getBobAnimDataIdx(idx));
+
+ if (!animAction)
+ stopBobAnimation(idx);
+ else if (animAction == 4) {
+ _vm->_graphicsManager.fastDisplay(_bob[idx]._spriteData,
+ _bob[idx]._oldX, _bob[idx]._oldY, _bob[idx]._frameIndex);
+ stopBobAnimation(idx);
+ _vm->_eventsManager.VBL();
+ }
+}
+
+int ObjectsManager::getBobAnimDataIdx(int idx) {
+ return _bob[idx]._animDataIdx / 5;
+}
+
+void ObjectsManager::setBobAnimDataIdx(int idx, int animIdx) {
+ _bob[idx]._animDataIdx = 5 * animIdx;
+ _bob[idx].field12 = 0;
+ _bob[idx].field14 = 0;
+}
+
+/**
+ * Set Hopkins animation
+ */
+void ObjectsManager::setBobAnimation(int idx) {
+ if (!_bob[idx]._disabledAnimationFl)
+ return;
+
+ _bob[idx]._disabledAnimationFl = false;
+ _bob[idx]._animDataIdx = 5;
+ _bob[idx]._frameIndex = 250;
+ _bob[idx].field12 = 0;
+ _bob[idx].field14 = 0;
+}
+
+/**
+ * Stop Hopkins animation
+ */
+void ObjectsManager::stopBobAnimation(int idx) {
+ _bob[idx]._disabledAnimationFl = true;
+}
+
+/**
+ * Get X position
+ */
+int ObjectsManager::getBobPosX(int idx) {
+ return _bob[idx]._xp;
+}
+
+int ObjectsManager::getBobPosY(int idx) {
+ return _bob[idx]._yp;
+}
+
+int ObjectsManager::getBobFrameIndex(int idx) {
+ return _bob[idx]._frameIndex;
+}
+
+void ObjectsManager::loadLinkFile(const Common::String &file) {
+ Common::File f;
+ Common::String filename = file + ".LNK";
+ byte *ptr = _vm->_fileManager.searchCat(filename, 3);
+ size_t nbytes = _vm->_globals._catalogSize;
+ if (ptr == g_PTRNUL) {
+ if (!f.open(filename))
+ error("Error opening file - %s", filename.c_str());
+
+ nbytes = f.size();
+ ptr = _vm->_globals.allocMemory(nbytes);
+ if (g_PTRNUL == ptr)
+ error("INILINK");
+ _vm->_fileManager.readStream(f, ptr, nbytes);
+ f.close();
+ }
+ if (!OBSSEUL) {
+ for (int idx = 0; idx < 500; ++idx)
+ _vm->_globals._spriteSize[idx] = READ_LE_INT16((uint16 *)ptr + idx);
+
+ _vm->_globals.resetHidingItems();
+
+ Common::String filename2 = Common::String((const char *)ptr + 1000);
+ if (!filename2.empty()) {
+ _vm->_globals._hidingItemData[1] = _vm->_fileManager.searchCat(filename2, 8);
+
+ if (_vm->_globals._hidingItemData[1] || _vm->_globals._hidingItemData[1] == g_PTRNUL) {
+ _vm->_globals._hidingItemData[1] = _vm->_fileManager.loadFile(filename2);
+ } else {
+ _vm->_globals._hidingItemData[1] = _vm->_fileManager.loadFile("RES_SLI.RES");
+ }
+
+ int curDataCacheId = 60;
+ byte *curDataPtr = ptr + 1000;
+ for (int hidingIdx = 0; hidingIdx <= 21; hidingIdx++) {
+ HidingItem *hid = &_vm->_globals._hidingItem[hidingIdx];
+ int curSpriteId = READ_LE_INT16(curDataPtr + 2 * curDataCacheId);
+ hid->_spriteIndex = curSpriteId;
+ hid->_x = READ_LE_INT16(curDataPtr + 2 * curDataCacheId + 2);
+ hid->_y = READ_LE_INT16(curDataPtr + 2 * curDataCacheId + 4);
+ hid->field14 = READ_LE_INT16(curDataPtr + 2 * curDataCacheId + 8);
+
+ if (!_vm->_globals._hidingItemData[1]) {
+ hid->_useCount = 0;
+ } else {
+ hid->_spriteData = _vm->_globals._hidingItemData[1];
+ hid->_width = getWidth(_vm->_globals._hidingItemData[1], curSpriteId);
+ hid->_height = getHeight(_vm->_globals._hidingItemData[1], curSpriteId);
+ hid->_useCount = 1;
+ }
+ if (!hid->_x && !hid->_y && !hid->_spriteIndex)
+ hid->_useCount = 0;
+
+ curDataCacheId += 5;
+ }
+ _vm->_globals.enableHiding();
+ }
+ }
+
+ _vm->_linesManager.resetLines();
+ for (size_t idx = 0; idx < nbytes - 3; idx++) {
+ if (READ_BE_UINT24(&ptr[idx]) == MKTAG24('O', 'B', '2')) {
+ byte *curDataPtr = &ptr[idx + 4];
+ int lineDataIdx = 0;
+ int curLineIdx = 0;
+ _vm->_linesManager.resetLinesNumb();
+ Directions curDirection;
+ do {
+ curDirection = (Directions)READ_LE_INT16(curDataPtr + 2 * lineDataIdx);
+ if (curDirection != DIR_NONE) {
+ _vm->_linesManager.addLine(
+ curLineIdx,
+ curDirection,
+ READ_LE_INT16(curDataPtr + 2 * lineDataIdx + 2),
+ READ_LE_INT16(curDataPtr + 2 * lineDataIdx + 4),
+ READ_LE_INT16(curDataPtr + 2 * lineDataIdx + 6),
+ READ_LE_INT16(curDataPtr + 2 * lineDataIdx + 8));
+ }
+ lineDataIdx += 5;
+ ++curLineIdx;
+ } while (curDirection != DIR_NONE);
+ _vm->_linesManager.initRoute();
+ }
+ }
+
+ if (!OBSSEUL) {
+ for (size_t idx = 0; idx < nbytes - 3; idx++) {
+ if (READ_BE_UINT24(&ptr[idx]) == MKTAG24('Z', 'O', '2')) {
+ byte *curDataPtr = &ptr[idx + 4];
+ int curDataIdx = 0;
+ for (int i = 1; i <= 100; i++) {
+ _vm->_linesManager.ZONEP[i]._destX = 0;
+ _vm->_linesManager.ZONEP[i]._destY = 0;
+ _vm->_linesManager.ZONEP[i]._spriteIndex = 0;
+ _vm->_linesManager.ZONEP[i]._verbFl1 = 0;
+ _vm->_linesManager.ZONEP[i]._verbFl2 = 0;
+ _vm->_linesManager.ZONEP[i]._verbFl3 = 0;
+ _vm->_linesManager.ZONEP[i]._verbFl4 = 0;
+ _vm->_linesManager.ZONEP[i]._verbFl5 = 0;
+ _vm->_linesManager.ZONEP[i]._verbFl6 = 0;
+ _vm->_linesManager.ZONEP[i]._verbFl7 = 0;
+ _vm->_linesManager.ZONEP[i]._verbFl8 = 0;
+ _vm->_linesManager.ZONEP[i]._verbFl9 = 0;
+ _vm->_linesManager.ZONEP[i]._verbFl10 = 0;
+ _vm->_linesManager.ZONEP[i]._messageId = 0;
+ }
+
+ int curLineIdx = 0;
+ int v28;
+ do {
+ v28 = READ_LE_INT16(curDataPtr + 2 * curDataIdx);
+ if (v28 != -1) {
+ _vm->_linesManager.addZoneLine(
+ curLineIdx,
+ READ_LE_INT16(curDataPtr + 2 * curDataIdx + 2),
+ READ_LE_INT16(curDataPtr + 2 * curDataIdx + 4),
+ READ_LE_INT16(curDataPtr + 2 * curDataIdx + 6),
+ READ_LE_INT16(curDataPtr + 2 * curDataIdx + 8),
+ v28);
+ _vm->_linesManager.ZONEP[v28]._enabledFl = true;
+ }
+ curDataIdx += 5;
+ ++curLineIdx;
+ } while (v28 != -1);
+ for (int i = 1; i <= 100; i++) {
+ _vm->_linesManager.ZONEP[i]._destX = READ_LE_INT16(curDataPtr + 2 * curDataIdx);
+ _vm->_linesManager.ZONEP[i]._destY = READ_LE_INT16(curDataPtr + 2 * curDataIdx + 2);
+ _vm->_linesManager.ZONEP[i]._spriteIndex = READ_LE_INT16(curDataPtr + 2 * curDataIdx + 4);
+ curDataIdx += 3;
+ }
+
+ byte *v22 = ptr + idx + (10 * curLineIdx + 606) + 4;
+ for (int i = 1; i <= 100; i++) {
+ int j = (i - 1) * 10;
+ _vm->_linesManager.ZONEP[i]._verbFl1 = v22[j];
+ _vm->_linesManager.ZONEP[i]._verbFl2 = v22[j + 1];
+ _vm->_linesManager.ZONEP[i]._verbFl3 = v22[j + 2];
+ _vm->_linesManager.ZONEP[i]._verbFl4 = v22[j + 3];
+ _vm->_linesManager.ZONEP[i]._verbFl5 = v22[j + 4];
+ _vm->_linesManager.ZONEP[i]._verbFl6 = v22[j + 5];
+ _vm->_linesManager.ZONEP[i]._verbFl7 = v22[j + 6];
+ _vm->_linesManager.ZONEP[i]._verbFl8 = v22[j + 7];
+ _vm->_linesManager.ZONEP[i]._verbFl9 = v22[j + 8];
+ _vm->_linesManager.ZONEP[i]._verbFl10 = v22[j + 9];
+ }
+ int dep = 1010;
+ for (int i = 1; i <= 100; i++) {
+ _vm->_linesManager.ZONEP[i]._messageId = READ_LE_INT16(v22 + dep);
+ dep += 2;
+ }
+ _vm->_linesManager.CARRE_ZONE();
+ }
+ }
+ }
+ _vm->_globals.freeMemory(ptr);
+}
+
+void ObjectsManager::SPECIAL_INI() {
+ switch (_vm->_globals._screenId) {
+ case 17:
+ if (_vm->_globals._prevScreenId == 20) {
+ _vm->_globals._disableInventFl = true;
+ _vm->_graphicsManager.SETCOLOR3(252, 100, 100, 100);
+ _vm->_graphicsManager.SETCOLOR3(253, 100, 100, 100);
+ _vm->_graphicsManager.SETCOLOR3(251, 100, 100, 100);
+ _vm->_graphicsManager.SETCOLOR3(254, 0, 0, 0);
+ for (int i = 0; i <= 4; i++)
+ _vm->_eventsManager.VBL();
+ _vm->_graphicsManager.fadeInLong();
+ animateSprite(0);
+ for (int i = 0; i <= 4; i++)
+ _vm->_eventsManager.VBL();
+ VBOB(_vm->_globals.SPRITE_ECRAN, 5, 15, 28, 1);
+ _vm->_fontManager.hideText(9);
+ bool displayedTxtFl = false;
+ if (!_vm->_soundManager._textOffFl) {
+ _vm->_fontManager.initTextBuffers(9, 383, _vm->_globals._textFilename, 220, 72, 6, 36, 253);
+ _vm->_fontManager.showText(9);
+ displayedTxtFl = true;
+ }
+ if (!_vm->_soundManager._voiceOffFl)
+ _vm->_soundManager.mixVoice(383, 4, displayedTxtFl);
+ _vm->_globals._saveData->_data[svField270] = 1;
+ _vm->_globals._saveData->_data[svField300] = 1;
+ _vm->_globals._saveData->_data[svField320] = 1;
+ if (_vm->_soundManager._voiceOffFl) {
+ for (int i = 0; i <= 199; i++)
+ _vm->_eventsManager.VBL();
+ }
+ _vm->_fontManager.hideText(9);
+ VBOB_OFF(5);
+ for (int i = 0; i <= 3; i++)
+ _vm->_eventsManager.VBL();
+ _vm->_graphicsManager._noFadingFl = true;
+ _vm->_globals._disableInventFl = false;
+ }
+ break;
+
+ case 18:
+ if (_vm->_globals._prevScreenId == 17) {
+ _vm->_eventsManager._mouseSpriteId = 4;
+ for (int i = 0; i <= 4; i++)
+ _vm->_eventsManager.VBL();
+ _vm->_graphicsManager.fadeInLong();
+ _vm->_globals.iRegul = 1;
+ _vm->_globals._disableInventFl = false;
+ _vm->_graphicsManager._noFadingFl = true;
+ _vm->_globals._introSpeechOffFl = true;
+ _vm->_talkManager.startAnimatedCharacterDialogue("MAGE1.pe2");
+ _vm->_graphicsManager._noFadingFl = true;
+ _vm->_globals._disableInventFl = false;
+ }
+ break;
+
+ case 35:
+ case 36:
+ case 37:
+ case 38:
+ case 39:
+ case 40:
+ case 41:
+ _vm->_linesManager.BOBZONE[20] = 1;
+ _vm->_linesManager.BOBZONE[21] = 2;
+ _vm->_linesManager.BOBZONE[22] = 3;
+ _vm->_linesManager.BOBZONE[23] = 4;
+ _vm->_linesManager.BOBZONE_FLAG[20] = true;
+ _vm->_linesManager.BOBZONE_FLAG[21] = true;
+ _vm->_linesManager.BOBZONE_FLAG[22] = true;
+ _vm->_linesManager.BOBZONE_FLAG[23] = true;
+ enableVerb(20, 5);
+ enableVerb(21, 5);
+ enableVerb(22, 5);
+ enableVerb(23, 5);
+ _vm->_linesManager.ZONEP[20]._messageId = 30;
+ _vm->_linesManager.ZONEP[21]._messageId = 30;
+ _vm->_linesManager.ZONEP[22]._messageId = 30;
+ _vm->_linesManager.ZONEP[23]._messageId = 30;
+ for (int i = 200; i <= 214; i++) {
+ if (_vm->_globals._saveData->_data[i] != 2)
+ _vm->_globals._saveData->_data[i] = 0;
+ }
+ break;
+
+ case 73:
+ if (!_vm->_globals._saveData->_data[svField318]) {
+ _vm->_globals.resetHidingUseCount(0);
+ _vm->_globals.resetHidingUseCount(1);
+ }
+ break;
+
+ case 93:
+ if (!_vm->_globals._saveData->_data[svField333])
+ setBobAnimation(8);
+ break;
+ }
+}
+
+void ObjectsManager::OPTI_BOBON(int idx1, int idx2, int idx3, int anim1Idx, int anim2Idx, int anim3Idx) {
+ if (idx1 != -1)
+ setBobAnimation(idx1);
+ if (idx2 != -1)
+ setBobAnimation(idx2);
+ if (idx3 != -1)
+ setBobAnimation(idx3);
+ if (idx1 != -1)
+ setBobAnimDataIdx(idx1, anim1Idx);
+ if (idx2 != -1)
+ setBobAnimDataIdx(idx2, anim2Idx);
+ if (idx3 != -1)
+ setBobAnimDataIdx(idx3, anim3Idx);
+}
+
+void ObjectsManager::SCI_OPTI_ONE(int idx, int animIdx, int a3, int a4) {
+ _vm->_eventsManager._curMouseButton = 0;
+ _vm->_eventsManager._mouseButton = 0;
+
+ if (a4 != 3) {
+ setBobAnimation(idx);
+ setBobAnimDataIdx(idx, animIdx);
+ }
+
+ do {
+ _vm->_eventsManager.VBL();
+ if (_vm->_eventsManager._curMouseButton)
+ break;
+ } while (a3 != getBobAnimDataIdx(idx));
+ if (!a4)
+ stopBobAnimation(idx);
+}
+
+void ObjectsManager::disableVerb(int idx, int a2) {
+ switch (a2) {
+ case 6:
+ case 16:
+ _vm->_linesManager.ZONEP[idx]._verbFl1 = 0;
+ break;
+ case 7:
+ _vm->_linesManager.ZONEP[idx]._verbFl2 = 0;
+ break;
+ case 5:
+ case 8:
+ _vm->_linesManager.ZONEP[idx]._verbFl3 = 0;
+ break;
+ case 9:
+ case 17:
+ case 24:
+ _vm->_linesManager.ZONEP[idx]._verbFl4 = 0;
+ break;
+ case 10:
+ case 18:
+ _vm->_linesManager.ZONEP[idx]._verbFl5 = 0;
+ break;
+ case 11:
+ case 19:
+ _vm->_linesManager.ZONEP[idx]._verbFl6 = 0;
+ break;
+ case 12:
+ case 20:
+ _vm->_linesManager.ZONEP[idx]._verbFl7 = 0;
+ break;
+ case 13:
+ case 22:
+ _vm->_linesManager.ZONEP[idx]._verbFl8 = 0;
+ case 14:
+ case 21:
+ case 25:
+ _vm->_linesManager.ZONEP[idx]._verbFl9 = 0;
+ break;
+ case 15:
+ _vm->_linesManager.ZONEP[idx]._verbFl10 = 0;
+ break;
+ }
+ _changeVerbFl = true;
+}
+
+void ObjectsManager::enableVerb(int idx, int a2) {
+ switch (a2) {
+ case 5:
+ _vm->_linesManager.ZONEP[idx]._verbFl3 = 2;
+ break;
+ case 6:
+ _vm->_linesManager.ZONEP[idx]._verbFl1 = 1;
+ break;
+ case 7:
+ _vm->_linesManager.ZONEP[idx]._verbFl2 = 1;
+ break;
+ case 8:
+ _vm->_linesManager.ZONEP[idx]._verbFl3 = 1;
+ break;
+ case 9:
+ _vm->_linesManager.ZONEP[idx]._verbFl4 = 1;
+ break;
+ case 10:
+ _vm->_linesManager.ZONEP[idx]._verbFl5 = 1;
+ break;
+ case 11:
+ _vm->_linesManager.ZONEP[idx]._verbFl6 = 1;
+ break;
+ case 12:
+ _vm->_linesManager.ZONEP[idx]._verbFl7 = 1;
+ break;
+ case 13:
+ _vm->_linesManager.ZONEP[idx]._verbFl8 = 1;
+ break;
+ case 14:
+ _vm->_linesManager.ZONEP[idx]._verbFl8 = 1;
+ break;
+ case 15:
+ _vm->_linesManager.ZONEP[idx]._verbFl9 = 1;
+ break;
+ case 16:
+ _vm->_linesManager.ZONEP[idx]._verbFl1 = 2;
+ break;
+ case 17:
+ _vm->_linesManager.ZONEP[idx]._verbFl4 = 2;
+ break;
+ case 18:
+ _vm->_linesManager.ZONEP[idx]._verbFl5 = 2;
+ break;
+ case 19:
+ _vm->_linesManager.ZONEP[idx]._verbFl6 = 2;
+ break;
+ case 20:
+ _vm->_linesManager.ZONEP[idx]._verbFl7 = 2;
+ break;
+ case 21:
+ _vm->_linesManager.ZONEP[idx]._verbFl9 = 2;
+ break;
+ case 22:
+ _vm->_linesManager.ZONEP[idx]._verbFl8 = 2;
+ break;
+ case 24:
+ _vm->_linesManager.ZONEP[idx]._verbFl4 = 3;
+ break;
+ case 25:
+ _vm->_linesManager.ZONEP[idx]._verbFl9 = 2;
+ break;
+ }
+}
+
+void ObjectsManager::ACTION(const byte *spriteData, const Common::String &actionStr, int a3, int a4, int speed, bool flipFl) {
+ Common::String tmpStr = "";
+ int realSpeed = speed;
+ if (_vm->_globals._speed == 2)
+ realSpeed = speed / 2;
+ else if (_vm->_globals._speed == 3)
+ realSpeed = speed / 3;
+ const byte *oldSpriteData = _sprite[0]._spriteData;
+ int spriteIndex = _sprite[0]._spriteIndex;
+ bool oldFlipFl = _sprite[0]._flipFl;
+ _sprite[0].field12 += a3;
+ _sprite[0].field14 += a4;
+ _sprite[0]._flipFl = flipFl;
+
+ int idx = 0;
+ for (int strPos = 0; ; strPos++) {
+ bool tokenCompleteFl = false;
+ char curChar = actionStr[strPos];
+ if (curChar == ',') {
+ idx = atoi(tmpStr.c_str());
+ tmpStr = "";
+ tokenCompleteFl = true;
+ } else {
+ tmpStr += curChar;
+ }
+
+ if (tokenCompleteFl) {
+ if (idx == -1) {
+ _sprite[0]._spriteData = oldSpriteData;
+ _sprite[0]._spriteIndex = spriteIndex;
+ _sprite[0].field12 -= a3;
+ _sprite[0].field14 -= a4;
+ _sprite[0]._flipFl = oldFlipFl;
+ } else {
+ _sprite[0]._spriteData = spriteData;
+ _sprite[0]._spriteIndex = idx;
+ }
+ for (int i = 0; i < realSpeed; i++)
+ _vm->_eventsManager.VBL();
+ if (idx == -1)
+ break;
+ }
+ }
+}
+
+void ObjectsManager::SPACTION(byte *spriteData, const Common::String &animationSeq, int a3, int a4, int speed, bool flipFl) {
+ Common::String tmpStr = "";
+
+ int realSpeed = speed;
+ if (_vm->_globals._speed == 2)
+ realSpeed = speed / 2;
+ else if (_vm->_globals._speed == 3)
+ realSpeed = speed / 3;
+
+ _oldSpriteData = _sprite[0]._spriteData;
+ _oldSpriteIndex = _sprite[0]._spriteIndex;
+ _oldFlipFl = _sprite[0]._flipFl;
+ _sprite[0].field12 += a3;
+ _sprite[0].field14 += a4;
+ _sprite[0]._flipFl = flipFl;
+
+ uint strPos = 0;
+ int spriteIndex = 0;
+ do {
+ bool completeTokenFl = false;
+ do {
+ char nextChar = animationSeq[strPos];
+ if ((animationSeq[strPos] == ',') || (strPos == animationSeq.size() - 1)) {
+ // Safeguard: if the sequence doesn't end with a coma, simulate it's present.
+ if (animationSeq[strPos] != ',')
+ tmpStr += nextChar;
+ spriteIndex = atoi(tmpStr.c_str());
+ tmpStr = "";
+ completeTokenFl = true;
+ } else {
+ tmpStr += nextChar;
+ }
+ ++strPos;
+ } while (!completeTokenFl);
+
+ if (spriteIndex != -1) {
+ _sprite[0]._spriteData = spriteData;
+ _sprite[0]._spriteIndex = spriteIndex;
+ }
+ for (int i = 0; i < realSpeed; i++)
+ _vm->_eventsManager.VBL();
+ } while (spriteIndex != -1);
+}
+
+void ObjectsManager::SPACTION1(byte *spriteData, const Common::String &animString, int a3, int a4, int speed) {
+ Common::String tmpStr = "";
+ int realSpeed = speed;
+ if (_vm->_globals._speed == 2)
+ realSpeed = speed / 2;
+ else if (_vm->_globals._speed == 3)
+ realSpeed = speed / 3;
+
+ int spriteIndex = 0;
+ bool completeTokenFl;
+ char nextChar;
+
+ for (int idx = 0; ; idx++) {
+ completeTokenFl = false;
+ nextChar = animString[idx];
+ if (nextChar == ',') {
+ spriteIndex = atoi(tmpStr.c_str());
+ tmpStr = "";
+ completeTokenFl = true;
+ } else {
+ tmpStr += nextChar;
+ }
+
+ if (completeTokenFl) {
+ if (spriteIndex == -1) {
+ _sprite[0]._spriteData = _oldSpriteData;
+ _sprite[0]._spriteIndex = _oldSpriteIndex;
+ _sprite[0].field12 -= a3;
+ _sprite[0].field14 -= a4;
+ _sprite[0]._flipFl = _oldFlipFl;
+ } else {
+ _sprite[0]._spriteData = spriteData;
+ _sprite[0]._spriteIndex = spriteIndex;
+ }
+
+ for (int i = 0; i < realSpeed; i++)
+ _vm->_eventsManager.VBL();
+
+ if (spriteIndex == -1)
+ break;
+ }
+ }
+}
+
+void ObjectsManager::handleForest(int screenId, int minX, int maxX, int minY, int maxY, int idx) {
+ int savegameIdx = screenId;
+ if (_vm->_globals._screenId != screenId)
+ return;
+
+ switch (_vm->_globals._screenId) {
+ case 35:
+ if (idx > 2)
+ savegameIdx = 201;
+ else
+ savegameIdx = 200;
+ break;
+ case 36:
+ if (idx > 2)
+ savegameIdx = 203;
+ else
+ savegameIdx = 202;
+ break;
+ case 37:
+ if (idx > 2)
+ savegameIdx = 205;
+ else
+ savegameIdx = 204;
+ break;
+ case 38:
+ if (idx > 2)
+ savegameIdx = 207;
+ else
+ savegameIdx = 206;
+ break;
+ case 39:
+ if (idx > 2)
+ savegameIdx = 209;
+ else
+ savegameIdx = 208;
+ break;
+ case 40:
+ if (idx > 2)
+ savegameIdx = 211;
+ else
+ savegameIdx = 210;
+ break;
+ case 41:
+ if (idx > 2)
+ savegameIdx = 213;
+ else
+ savegameIdx = 212;
+ break;
+ }
+
+ if (_vm->_globals._saveData->_data[savegameIdx] == 2)
+ return;
+
+ if (_vm->_globals._saveData->_data[savegameIdx]) {
+ if (_vm->_globals._saveData->_data[savegameIdx] == 1) {
+ if (((idx == 1 || idx == 2) && getBobAnimDataIdx(idx) == 26) || ((idx == 3 || idx == 4) && getBobAnimDataIdx(idx) == 27)) {
+ _vm->_dialogsManager._removeInventFl = true;
+ _vm->_soundManager.playSample(1);
+ _vm->_globals._saveData->_data[savegameIdx] = 4;
+ }
+ }
+ if (_vm->_globals._saveData->_data[savegameIdx] == 4) {
+ if (idx >= 1 && idx <= 4 && getBobAnimDataIdx(idx) > 30)
+ _vm->_globals._saveData->_data[savegameIdx] = 3;
+ }
+ if (_vm->_globals._saveData->_data[savegameIdx] == 3) {
+ _vm->_graphicsManager.FADE_LINUX = 2;
+ _vm->_animationManager.playAnim("CREVE2.ANM", 100, 24, 500);
+ _vm->_globals._exitId = 150;
+ _vm->_graphicsManager._noFadingFl = true;
+ hideBob(1);
+ hideBob(2);
+ hideBob(3);
+ hideBob(4);
+ }
+ } else if (minX < getSpriteX(0)
+ && maxX > getSpriteX(0)
+ && minY < getSpriteY(0)
+ && maxY > getSpriteY(0)) {
+ if (idx >= 1 && idx <= 4)
+ setBobAnimation(idx);
+ _vm->_globals._saveData->_data[savegameIdx] = 1;
+ }
+}
+
+void ObjectsManager::lockAnimX(int idx, int x) {
+ _vm->_globals._lockedAnims[idx]._enableFl = true;
+ _vm->_globals._lockedAnims[idx]._posX = x;
+}
+
+/**
+ * Game scene control method
+ */
+void ObjectsManager::PERSONAGE(const Common::String &backgroundFile, const Common::String &linkFile,
+ const Common::String &animFile, const Common::String &s4, int soundNum, bool initializeScreen) {
+ _vm->_dialogsManager._inventFl = false;
+ _vm->_eventsManager._gameKey = KEY_NONE;
+ _vm->_dialogsManager._removeInventFl = false;
+ _vm->_graphicsManager._scrollOffset = 0;
+ _vm->_globals._cityMapEnabledFl = false;
+ _vm->_globals.iRegul = 1;
+ _vm->_soundManager.playSound(soundNum);
+ _vm->_linesManager._route = (RouteItem *)g_PTRNUL;
+ _vm->_globals._freezeCharacterFl = true;
+ _vm->_globals._exitId = 0;
+ if (!backgroundFile.empty())
+ _vm->_graphicsManager.loadImage(backgroundFile);
+ if (!linkFile.empty())
+ loadLinkFile(linkFile);
+ if (!animFile.empty())
+ _vm->_animationManager.loadAnim(animFile);
+ _vm->_graphicsManager.displayAllBob();
+ if (!s4.empty()) {
+ if (initializeScreen)
+ _vm->_graphicsManager.initScreen(s4, 0, initializeScreen);
+ else
+ _vm->_graphicsManager.initScreen(s4, 2, initializeScreen);
+ }
+ _vm->_eventsManager.mouseOn();
+ if (_vm->_globals._screenId == 61) {
+ addStaticSprite(_vm->_globals.PERSO, Common::Point(330, 418), 0, 60, 0, false, 34, 190);
+ animateSprite(0);
+ _vm->_linesManager._route = (RouteItem *)g_PTRNUL;
+ computeAndSetSpriteSize();
+ }
+ _vm->_graphicsManager.SETCOLOR3(252, 100, 100, 100);
+ _vm->_graphicsManager.SETCOLOR3(253, 100, 100, 100);
+ _vm->_graphicsManager.SETCOLOR3(251, 100, 100, 100);
+ _vm->_graphicsManager.SETCOLOR3(254, 0, 0, 0);
+ _vm->_eventsManager.changeMouseCursor(4);
+ for (int i = 0; i <= 4; i++)
+ _vm->_eventsManager.VBL();
+ _vm->_graphicsManager.fadeInLong();
+ if (_vm->_globals._screenId == 61) {
+ _vm->_animationManager.playSequence("OUVRE.SEQ", 10, 4, 10);
+ stopBobAnimation(3);
+ _vm->_globals._checkDistanceFl = true;
+ _oldCharacterPosX = getSpriteX(0);
+ _vm->_globals._oldDirection = DIR_NONE;
+ _vm->_globals.Compteur = 0;
+ _vm->_linesManager._route = (RouteItem *)g_PTRNUL;
+ _vm->_linesManager._route = _vm->_linesManager.PARCOURS2(getSpriteX(0), getSpriteY(0), 330, 345);
+ _vm->_globals._checkDistanceFl = true;
+ do {
+ GOHOME();
+ _vm->_eventsManager.VBL();
+ } while (_vm->_linesManager._route != (RouteItem *)g_PTRNUL);
+ setSpriteIndex(0, 64);
+ }
+ do {
+ int mouseButton = _vm->_eventsManager.getMouseButton();
+ if (mouseButton == 1) {
+ handleLeftButton();
+ mouseButton = 1;
+ } else if (mouseButton == 2)
+ handleRightButton();
+ _vm->_dialogsManager.testDialogOpening();
+ _vm->_linesManager.checkZone();
+ if (_vm->_globals._actionMoveTo)
+ PARADISE();
+ if (!_vm->_globals._exitId)
+ _vm->_eventsManager.VBL();
+
+ if (_vm->_globals._exitId)
+ break;
+ } while (!_vm->shouldQuit());
+ if (_vm->shouldQuit())
+ return;
+
+ _vm->_graphicsManager.fadeOutLong();
+ if (!animFile.empty())
+ _vm->_graphicsManager.endDisplayBob();
+ if (_vm->_globals._screenId == 61)
+ removeSprite(0);
+ clearScreen();
+ _vm->_globals.iRegul = 0;
+}
+
+/**
+ * Game scene control method
+ */
+void ObjectsManager::PERSONAGE2(const Common::String &backgroundFile, const Common::String &linkFile,
+ const Common::String &animFile, const Common::String &s4, int soundNum, bool initializeScreen) {
+ _vm->_dialogsManager._inventFl = false;
+ _vm->_eventsManager._gameKey = KEY_NONE;
+ _verb = 4;
+ _vm->_graphicsManager._scrollOffset = 0;
+ _vm->_dialogsManager._removeInventFl = false;
+ _vm->_globals._cityMapEnabledFl = false;
+ _vm->_graphicsManager._noFadingFl = false;
+ _vm->_globals._freezeCharacterFl = false;
+ _vm->_globals._exitId = 0;
+ _vm->_globals._checkDistanceFl = true;
+ _vm->_soundManager.playSound(soundNum);
+ _vm->_globals.iRegul = 1;
+ if (!backgroundFile.empty())
+ _vm->_graphicsManager.loadImage(backgroundFile);
+ if (!linkFile.empty())
+ loadLinkFile(linkFile);
+ if (!animFile.empty()) {
+ _vm->_animationManager.loadAnim(animFile);
+ _vm->_graphicsManager.displayAllBob();
+ }
+ if (!s4.empty()) {
+ if (initializeScreen)
+ _vm->_graphicsManager.initScreen(s4, 0, initializeScreen);
+ else
+ _vm->_graphicsManager.initScreen(s4, 2, initializeScreen);
+ }
+ _vm->_eventsManager.mouseOn();
+ _vm->_eventsManager._mouseCursorId = 4;
+ _vm->_graphicsManager.SETCOLOR3(252, 100, 100, 100);
+ _vm->_graphicsManager.SETCOLOR3(253, 100, 100, 100);
+ _vm->_graphicsManager.SETCOLOR3(251, 100, 100, 100);
+ _vm->_graphicsManager.SETCOLOR3(254, 0, 0, 0);
+ if (_vm->_globals._characterType) {
+ if (!_vm->_globals._saveData->_data[svField122] && !_vm->_globals._saveData->_data[svField356]) {
+ _vm->_globals.PERSO = _vm->_fileManager.loadFile("PERSO.SPR");
+ _vm->_globals._characterType = 0;
+ }
+ }
+ if (!_vm->_globals._characterType) {
+ if (_vm->_globals._saveData->_data[svField122] == 1) {
+ _vm->_globals.PERSO = _vm->_fileManager.loadFile("HOPFEM.SPR");
+ _vm->_globals._characterType = 1;
+ }
+ }
+ if (_vm->_globals._characterType != 2 && _vm->_globals._saveData->_data[svField356] == 1) {
+ _vm->_globals.PERSO = _vm->_fileManager.loadFile("PSAMAN.SPR");
+ _vm->_globals._characterType = 2;
+ }
+ _vm->_globals.loadCharacterData();
+ switch (_vm->_globals._characterType) {
+ case 0:
+ addStaticSprite(_vm->_globals.PERSO, _characterPos, 0, _startSpriteIndex, 0, false, 34, 190);
+ break;
+ case 1:
+ addStaticSprite(_vm->_globals.PERSO, _characterPos, 0, _startSpriteIndex, 0, false, 28, 155);
+ break;
+ case 2:
+ addStaticSprite(_vm->_globals.PERSO, _characterPos, 0, _startSpriteIndex, 0, false, 20, 127);
+ break;
+ }
+ _vm->_eventsManager.setMouseXY(_characterPos);
+ if (_vm->_graphicsManager._largeScreenFl)
+ _vm->_graphicsManager._scrollPosX = (int16)getSpriteX(0) - 320;
+ computeAndSetSpriteSize();
+ animateSprite(0);
+ _vm->_globals.enableHiding();
+ _vm->_linesManager._route = (RouteItem *)g_PTRNUL;
+ computeAndSetSpriteSize();
+ SPECIAL_INI();
+ _vm->_eventsManager._mouseSpriteId = 4;
+ _oldCharacterPosX = _characterPos.x;
+ _oldCharacterPosY = _characterPos.y;
+ _vm->_globals._oldDirection = DIR_NONE;
+ _vm->_globals.Compteur = 0;
+
+ for (int idx = 0; idx < 5; ++idx)
+ _vm->_eventsManager.VBL();
+
+ _vm->_globals.iRegul = 1;
+ if (!_vm->_graphicsManager._noFadingFl)
+ _vm->_graphicsManager.fadeInLong();
+ _vm->_graphicsManager._noFadingFl = false;
+ _vm->_eventsManager.changeMouseCursor(4);
+
+ int xCheck = 0;
+ int yCheck = 0;
+
+ bool breakFlag = false;
+ while (!_vm->shouldQuit() && !breakFlag) {
+ int mouseButtons = _vm->_eventsManager.getMouseButton();
+ if (mouseButtons) {
+ if (mouseButtons == 1) {
+ if (_verb == 16 && _vm->_eventsManager._mouseCursorId == 16) {
+ int xp = _vm->_eventsManager.getMouseX();
+ int yp = _vm->_eventsManager.getMouseY();
+
+ if ((xCheck == xp) && (yCheck == yp)) {
+ _vm->_linesManager._route = (RouteItem *)g_PTRNUL;
+ PARADISE();
+ if (_vm->_globals._exitId)
+ breakFlag = true;
+ }
+ xCheck = xp;
+ yCheck = yp;
+ }
+ handleLeftButton();
+ } else if (mouseButtons == 2) {
+ handleRightButton();
+ }
+ }
+ if (!_vm->_globals._exitId) {
+ _vm->_dialogsManager.testDialogOpening();
+ _vm->_linesManager.checkZone();
+ if (_vm->_linesManager._route == (RouteItem *)g_PTRNUL
+ || (GOHOME(), _vm->_linesManager._route == (RouteItem *)g_PTRNUL)) {
+ if (_vm->_globals._actionMoveTo)
+ PARADISE();
+ }
+ handleSpecialGames();
+ _vm->_eventsManager.VBL();
+ if (!_vm->_globals._exitId)
+ continue;
+ }
+ breakFlag = true;
+ }
+
+ if (_vm->_globals._exitId != 8 || _vm->_globals._screenId != 5 || !_helicopterFl) {
+ if (!_vm->_graphicsManager._noFadingFl)
+ _vm->_graphicsManager.fadeOutLong();
+ _vm->_graphicsManager._noFadingFl = false;
+ removeSprite(0);
+ if (_twoCharactersFl) {
+ removeSprite(1);
+ _twoCharactersFl = false;
+ }
+ if (!animFile.empty())
+ _vm->_graphicsManager.endDisplayBob();
+ clearScreen();
+ } else {
+ _helicopterFl = false;
+ }
+ _vm->_globals.iRegul = 0;
+}
+
+void ObjectsManager::setVerb(int id) {
+ _verb = id;
+}
+} // End of namespace Hopkins