aboutsummaryrefslogtreecommitdiff
path: root/engines/gob
diff options
context:
space:
mode:
Diffstat (limited to 'engines/gob')
-rw-r--r--engines/gob/draw_v1.cpp29
-rw-r--r--engines/gob/draw_v2.cpp42
-rw-r--r--engines/gob/game.cpp128
-rw-r--r--engines/gob/game.h169
-rw-r--r--engines/gob/game_fascin.cpp155
-rw-r--r--engines/gob/game_v1.cpp1220
-rw-r--r--engines/gob/game_v2.cpp1344
-rw-r--r--engines/gob/game_v6.cpp1009
-rw-r--r--engines/gob/hotspots.cpp1706
-rw-r--r--engines/gob/hotspots.h177
-rw-r--r--engines/gob/inter.cpp3
-rw-r--r--engines/gob/inter_v1.cpp3
-rw-r--r--engines/gob/inter_v2.cpp61
-rw-r--r--engines/gob/inter_v6.cpp21
-rw-r--r--engines/gob/module.mk3
15 files changed, 1958 insertions, 4112 deletions
diff --git a/engines/gob/draw_v1.cpp b/engines/gob/draw_v1.cpp
index 94ee32a031..625b738b8a 100644
--- a/engines/gob/draw_v1.cpp
+++ b/engines/gob/draw_v1.cpp
@@ -33,6 +33,7 @@
#include "gob/util.h"
#include "gob/game.h"
#include "gob/resources.h"
+#include "gob/hotspots.h"
#include "gob/scenery.h"
#include "gob/inter.h"
#include "gob/sound/sound.h"
@@ -58,7 +59,6 @@ void Draw_v1::blitCursor() {
}
void Draw_v1::animateCursor(int16 cursor) {
- Game::Collision *ptr;
int16 cursorIndex = cursor;
int16 newX = 0, newY = 0;
uint16 hotspotX = 0, hotspotY = 0;
@@ -66,29 +66,10 @@ void Draw_v1::animateCursor(int16 cursor) {
_showCursor = 2;
if (cursorIndex == -1) {
- cursorIndex = 0;
- for (ptr = _vm->_game->_collisionAreas; ptr->left != 0xFFFF; ptr++) {
- if (ptr->flags & 0xFFF0)
- continue;
+ cursorIndex =
+ _vm->_game->_hotspots->findCursor(_vm->_global->_inter_mouseX,
+ _vm->_global->_inter_mouseY);
- if (ptr->left > _vm->_global->_inter_mouseX)
- continue;
-
- if (ptr->right < _vm->_global->_inter_mouseX)
- continue;
-
- if (ptr->top > _vm->_global->_inter_mouseY)
- continue;
-
- if (ptr->bottom < _vm->_global->_inter_mouseY)
- continue;
-
- if ((ptr->flags & 0xF) < 3)
- cursorIndex = 1;
- else
- cursorIndex = 3;
- break;
- }
if (_cursorAnimLow[cursorIndex] == -1)
cursorIndex = 1;
}
@@ -317,7 +298,7 @@ void Draw_v1::printTotText(int16 id) {
_renderFlags = savedFlags;
if (_renderFlags & RENDERFLAG_COLLISIONS)
- _vm->_game->checkCollisions(0, 0, 0, 0);
+ _vm->_game->_hotspots->check(0, 0);
if ((_renderFlags & RENDERFLAG_CAPTUREPOP) && *_vm->_scenery->_pCaptureCounter != 0) {
(*_vm->_scenery->_pCaptureCounter)--;
diff --git a/engines/gob/draw_v2.cpp b/engines/gob/draw_v2.cpp
index 2843456f42..e09c565b79 100644
--- a/engines/gob/draw_v2.cpp
+++ b/engines/gob/draw_v2.cpp
@@ -34,6 +34,7 @@
#include "gob/game.h"
#include "gob/script.h"
#include "gob/resources.h"
+#include "gob/hotspots.h"
#include "gob/scenery.h"
#include "gob/inter.h"
#include "gob/video.h"
@@ -82,7 +83,6 @@ void Draw_v2::blitCursor() {
}
void Draw_v2::animateCursor(int16 cursor) {
- Game::Collision *ptr;
int16 cursorIndex = cursor;
int16 newX = 0, newY = 0;
uint16 hotspotX = 0, hotspotY = 0;
@@ -91,32 +91,10 @@ void Draw_v2::animateCursor(int16 cursor) {
// .-- _draw_animateCursorSUB1 ---
if (cursorIndex == -1) {
- cursorIndex = 0;
- for (ptr = _vm->_game->_collisionAreas; ptr->left != 0xFFFF; ptr++) {
- if ((ptr->flags & 0xF00) || (ptr->id & 0x4000))
- continue;
-
- if (ptr->left > _vm->_global->_inter_mouseX)
- continue;
-
- if (ptr->right < _vm->_global->_inter_mouseX)
- continue;
-
- if (ptr->top > _vm->_global->_inter_mouseY)
- continue;
-
- if (ptr->bottom < _vm->_global->_inter_mouseY)
- continue;
-
- if ((ptr->flags & 0xF000) == 0) {
- if ((ptr->flags & 0xF) >= 3) {
- cursorIndex = 3;
- break;
- } else if (((ptr->flags & 0xF0) != 0x10) && (cursorIndex == 0))
- cursorIndex = 1;
- } else if (cursorIndex == 0)
- cursorIndex = (ptr->flags >> 12) & 0xF;
- }
+ cursorIndex =
+ _vm->_game->_hotspots->findCursor(_vm->_global->_inter_mouseX,
+ _vm->_global->_inter_mouseY);
+
if (_cursorAnimLow[cursorIndex] == -1)
cursorIndex = 1;
}
@@ -407,8 +385,8 @@ void Draw_v2::printTotText(int16 id) {
adjustCoords(2, &rectRight, &rectBottom);
if (colId != -1)
- _vm->_game->addNewCollision(colId + 0xD000, rectLeft, rectTop,
- rectRight, rectBottom, 2, 0, 0, 0);
+ _vm->_game->_hotspots->add(colId + 0xD000, rectLeft, rectTop,
+ rectRight, rectBottom, (uint16) Hotspots::kTypeClick, 0, 0, 0, 0);
if (_needAdjust != 2)
printTextCentered(colCmd & 0x0F, rectLeft + 4, rectTop + 4,
@@ -501,8 +479,8 @@ void Draw_v2::printTotText(int16 id) {
rectBottom = destY + (int16)READ_LE_UINT16(ptr + 6);
adjustCoords(2, &rectLeft, &rectTop);
adjustCoords(2, &rectRight, &rectBottom);
- _vm->_game->addNewCollision(colId + 0x0D000, rectLeft, rectTop,
- rectRight, rectBottom, 2, 0, 0, 0);
+ _vm->_game->_hotspots->add(colId + 0x0D000, rectLeft, rectTop,
+ rectRight, rectBottom, (uint16) Hotspots::kTypeClick, 0, 0, 0, 0);
ptr += 8;
}
break;
@@ -604,7 +582,7 @@ void Draw_v2::printTotText(int16 id) {
if (!(_renderFlags & RENDERFLAG_COLLISIONS))
return;
- _vm->_game->checkCollisions(0, 0, 0, 0);
+ _vm->_game->_hotspots->check(0, 0);
if (*_vm->_scenery->_pCaptureCounter != 0) {
(*_vm->_scenery->_pCaptureCounter)--;
diff --git a/engines/gob/game.cpp b/engines/gob/game.cpp
index f69b899ce1..b75726cc75 100644
--- a/engines/gob/game.cpp
+++ b/engines/gob/game.cpp
@@ -33,6 +33,7 @@
#include "gob/variables.h"
#include "gob/script.h"
#include "gob/resources.h"
+#include "gob/hotspots.h"
#include "gob/inter.h"
#include "gob/draw.h"
#include "gob/mult.h"
@@ -169,30 +170,14 @@ bool Environments::has(Resources *resources, uint8 startEnv, int16 except) const
Game::Game(GobEngine *vm) : _vm(vm) {
- _collisionAreas = 0;
- _shouldPushColls = 0;
-
_captureCount = 0;
- _collStackSize = 0;
-
- for (int i = 0; i < 5; i++) {
- _collStack[i] = 0;
- _collStackElemSizes[i] = 0;
- }
-
_curTotFile[0] = 0;
_totToLoad[0] = 0;
_startTimeKey = 0;
_mouseButtons = kMouseButtonsNone;
- _lastCollKey = 0;
- _lastCollAreaIndex = 0;
- _lastCollId = 0;
-
- _activeCollResId = 0;
- _activeCollIndex = 0;
_handleMouse = 0;
_forceHandleMouse = 0;
_menuLevel = 0;
@@ -203,7 +188,6 @@ Game::Game(GobEngine *vm) : _vm(vm) {
_noCd = false;
_tempStr[0] = 0;
- _collStr[0] = 0;
_numEnvironments = 0;
_curEnvironment = 0;
@@ -211,19 +195,14 @@ Game::Game(GobEngine *vm) : _vm(vm) {
_environments = new Environments(_vm);
_script = new Script(_vm);
_resources = new Resources(_vm);
+ _hotspots = new Hotspots(_vm);
}
Game::~Game() {
delete _environments;
delete _script;
delete _resources;
-}
-
-void Game::freeCollision(int16 id) {
- for (int i = 0; i < 250; i++) {
- if (_collisionAreas[i].id == id)
- _collisionAreas[i].left = 0xFFFF;
- }
+ delete _hotspots;
}
void Game::capturePush(int16 left, int16 top, int16 width, int16 height) {
@@ -379,21 +358,10 @@ int16 Game::checkKeys(int16 *pMouseX, int16 *pMouseY,
return _vm->_util->checkKey();
}
-int16 Game::adjustKey(int16 key) {
- if (key <= 0x60 || key >= 0x7B)
- return key;
-
- return key - 0x20;
-}
-
void Game::start(void) {
- _collisionAreas = new Collision[250];
- memset(_collisionAreas, 0, 250 * sizeof(Collision));
-
prepareStart();
playTot(-2);
- delete[] _collisionAreas;
_vm->_draw->closeScreen();
for (int i = 0; i < SPRITES_COUNT; i++)
@@ -430,7 +398,7 @@ void Game::totSub(int8 flags, const char *newTotFile) {
return;
}
- pushCollisions(0);
+ _hotspots->push(0, true);
if (flags & 2)
playTot(-1);
@@ -440,7 +408,7 @@ void Game::totSub(int8 flags, const char *newTotFile) {
if (_vm->_inter->_terminate != 2)
_vm->_inter->_terminate = 0;
- popCollisions();
+ _hotspots->pop();
if ((flags & 1) && _vm->_inter->_variables) {
_vm->_inter->delocateVars();
@@ -488,13 +456,13 @@ void Game::switchTotSub(int16 index, int16 skipPlay) {
return;
}
- pushCollisions(0);
+ _hotspots->push(0, true);
playTot(skipPlay);
if (_vm->_inter->_terminate != 2)
_vm->_inter->_terminate = 0;
- popCollisions();
+ _hotspots->pop();
clearUnusedEnvironment();
@@ -503,87 +471,6 @@ void Game::switchTotSub(int16 index, int16 skipPlay) {
_environments->get(_curEnvironment);
}
-void Game::setCollisions(byte arg_0) {
- uint16 left;
- uint16 top;
- uint16 width;
- uint16 height;
- Collision *collArea;
-
- for (collArea = _collisionAreas; collArea->left != 0xFFFF; collArea++) {
- if (((collArea->id & 0xC000) != 0x8000) || (collArea->funcSub == 0))
- continue;
-
- _script->call(collArea->funcSub);
-
- left = _script->readValExpr();
- top = _script->readValExpr();
- width = _script->readValExpr();
- height = _script->readValExpr();
- if ((_vm->_draw->_renderFlags & RENDERFLAG_CAPTUREPOP) &&
- (left != 0xFFFF)) {
- left += _vm->_draw->_backDeltaX;
- top += _vm->_draw->_backDeltaY;
- }
- if (_vm->_draw->_needAdjust != 2) {
- _vm->_draw->adjustCoords(0, &left, &top);
- if ((collArea->flags & 0x0F) < 3)
- _vm->_draw->adjustCoords(2, &width, &height);
- else {
- height &= 0xFFFE;
- _vm->_draw->adjustCoords(2, 0, &height);
- }
- }
- collArea->left = left;
- collArea->top = top;
- collArea->right = left + width - 1;
- collArea->bottom = top + height - 1;
-
- _script->pop();
- }
-}
-
-void Game::collSub(uint16 offset) {
- int16 collStackSize;
-
- _script->call(offset);
-
- _shouldPushColls = 1;
- collStackSize = _collStackSize;
-
- _vm->_inter->funcBlock(0);
-
- if (collStackSize != _collStackSize)
- popCollisions();
-
- _shouldPushColls = 0;
-
- _script->pop();
-
- setCollisions();
-}
-
-void Game::collAreaSub(int16 index, int8 enter) {
- uint16 collId;
-
- collId = _collisionAreas[index].id & 0xF000;
-
- if ((collId == 0xA000) || (collId == 0x9000)) {
- if (enter == 0)
- WRITE_VAR(17, _collisionAreas[index].id & 0x0FFF);
- else
- WRITE_VAR(17, -(_collisionAreas[index].id & 0x0FFF));
- }
-
- if (enter != 0) {
- if (_collisionAreas[index].funcEnter != 0)
- collSub(_collisionAreas[index].funcEnter);
- } else {
- if (_collisionAreas[index].funcLeave != 0)
- collSub(_collisionAreas[index].funcLeave);
- }
-}
-
void Game::clearUnusedEnvironment() {
if (!_environments->has(_script)) {
delete _script;
@@ -593,7 +480,6 @@ void Game::clearUnusedEnvironment() {
delete _resources;
_resources = 0;
}
-
}
} // End of namespace Gob
diff --git a/engines/gob/game.h b/engines/gob/game.h
index eb579d44a4..e6a7a4c089 100644
--- a/engines/gob/game.h
+++ b/engines/gob/game.h
@@ -33,6 +33,7 @@ namespace Gob {
class Script;
class Resources;
class Variables;
+class Hotspots;
class Environments {
public:
@@ -69,37 +70,9 @@ private:
class Game {
public:
-
-#include "common/pack-start.h" // START STRUCT PACKING
-
- struct Collision {
- int16 id;
- uint16 left;
- uint16 top;
- uint16 right;
- uint16 bottom;
- int16 flags;
- int16 key;
- uint16 funcEnter;
- uint16 funcLeave;
- uint16 funcSub;
- Script *script;
- } PACKED_STRUCT;
-
- struct InputDesc {
- int16 fontIndex;
- int16 backColor;
- int16 frontColor;
- byte *ptr;
- } PACKED_STRUCT;
-
-#include "common/pack-end.h" // END STRUCT PACKING
-
- Collision *_collisionAreas;
- Collision *_collStack[5];
-
- Script *_script;
+ Script *_script;
Resources *_resources;
+ Hotspots *_hotspots;
char _curTotFile[14];
char _totToLoad[20];
@@ -113,6 +86,9 @@ public:
bool _noCd;
+ byte _handleMouse;
+ char _forceHandleMouse;
+
Game(GobEngine *vm);
virtual ~Game();
@@ -130,54 +106,19 @@ public:
virtual void totSub(int8 flags, const char *newTotFile);
virtual void switchTotSub(int16 index, int16 skipPlay);
- void freeCollision(int16 id);
-
virtual void playTot(int16 skipPlay) = 0;
- virtual void clearCollisions(void) = 0;
- virtual int16 addNewCollision(int16 id, uint16 left, uint16 top,
- uint16 right, uint16 bottom, int16 flags, int16 key,
- uint16 funcEnter, uint16 funcLeave, uint16 funcSub = 0) = 0;
- virtual void collisionsBlock(void) = 0;
- virtual int16 multiEdit(int16 time, int16 index, int16 *pCurPos,
- InputDesc *inpDesc, int16 *collResId,
- int16 *collIndex, bool mono = true) = 0;
- virtual int16 inputArea(int16 xPos, int16 yPos, int16 width, int16 height,
- int16 backColor, int16 frontColor, char *str, int16 fontIndex,
- char inpType, int16 *pTotTime, int16 *collResId,
- int16 *collIndex, bool mono = true) = 0;
- virtual int16 checkCollisions(byte handleMouse, int16 deltaTime,
- int16 *pResId, int16 *pResIndex) = 0;
-
virtual void prepareStart(void) = 0;
- virtual void pushCollisions(char all) = 0;
- virtual void popCollisions(void) = 0;
-
protected:
- int16 _lastCollKey;
- int16 _lastCollAreaIndex;
- int16 _lastCollId;
-
- int16 _activeCollResId;
- int16 _activeCollIndex;
- byte _handleMouse;
- char _forceHandleMouse;
uint32 _menuLevel;
char _tempStr[256];
- int16 _collStackSize;
- int16 _collStackElemSizes[5];
-
- char _shouldPushColls;
-
// Capture
Common::Rect _captureStack[20];
int16 _captureCount;
- char _collStr[256];
-
// For totSub()
int8 _curEnvironment;
int8 _numEnvironments;
@@ -185,125 +126,41 @@ protected:
GobEngine *_vm;
- virtual int16 adjustKey(int16 key);
-
- void collAreaSub(int16 index, int8 enter);
-
- virtual void setCollisions(byte arg_0 = 1);
- virtual void collSub(uint16 offset);
-
- virtual int16 checkMousePoint(int16 all, int16 *resId, int16 *resIndex) = 0;
-
void clearUnusedEnvironment();
};
class Game_v1 : public Game {
public:
- virtual void playTot(int16 skipPlay);
-
- virtual void clearCollisions(void);
- virtual int16 addNewCollision(int16 id, uint16 left, uint16 top,
- uint16 right, uint16 bottom, int16 flags, int16 key,
- uint16 funcEnter, uint16 funcLeave, uint16 funcSub = 0);
- virtual void collisionsBlock(void);
- virtual int16 multiEdit(int16 time, int16 index, int16 *pCurPos,
- InputDesc *inpDesc, int16 *collResId,
- int16 *collIndex, bool mono = true);
- virtual int16 inputArea(int16 xPos, int16 yPos, int16 width, int16 height,
- int16 backColor, int16 frontColor, char *str, int16 fontIndex,
- char inpType, int16 *pTotTime, int16 *collResId,
- int16 *collIndex, bool mono = true);
- virtual int16 checkCollisions(byte handleMouse, int16 deltaTime,
- int16 *pResId, int16 *pResIndex);
-
- virtual void prepareStart(void);
-
- virtual void pushCollisions(char all);
- virtual void popCollisions(void);
-
Game_v1(GobEngine *vm);
virtual ~Game_v1() {}
-protected:
- virtual int16 checkMousePoint(int16 all, int16 *resId, int16 *resIndex);
-};
-
-class Game_v2 : public Game_v1 {
-public:
virtual void playTot(int16 skipPlay);
- virtual void clearCollisions(void);
- virtual int16 addNewCollision(int16 id, uint16 left, uint16 top,
- uint16 right, uint16 bottom, int16 flags, int16 key,
- uint16 funcEnter, uint16 funcLeave, uint16 funcSub = 0);
- virtual void collisionsBlock(void);
- virtual int16 multiEdit(int16 time, int16 index, int16 *pCurPos,
- InputDesc *inpDesc, int16 *collResId,
- int16 *collIndex, bool mono = true);
- virtual int16 inputArea(int16 xPos, int16 yPos, int16 width, int16 height,
- int16 backColor, int16 frontColor, char *str, int16 fontIndex,
- char inpType, int16 *pTotTime, int16 *collResId,
- int16 *collIndex, bool mono = true);
- virtual int16 checkCollisions(byte handleMouse, int16 deltaTime,
- int16 *pResId, int16 *pResIndex);
-
virtual void prepareStart(void);
+};
- virtual void pushCollisions(char all);
- virtual void popCollisions(void);
-
+class Game_v2 : public Game_v1 {
+public:
Game_v2(GobEngine *vm);
virtual ~Game_v2() {}
-protected:
- struct CollLast {
- int16 key;
- int16 id;
- int16 areaIndex;
- };
-
- CollLast _collLasts[5];
+ virtual void playTot(int16 skipPlay);
- virtual int16 checkMousePoint(int16 all, int16 *resId, int16 *resIndex);
+ virtual void prepareStart(void);
};
class Game_v6 : public Game_v2 {
public:
- virtual void totSub(int8 flags, const char *newTotFile);
-
- virtual int16 addNewCollision(int16 id, uint16 left, uint16 top,
- uint16 right, uint16 bottom, int16 flags, int16 key,
- uint16 funcEnter, uint16 funcLeave, uint16 funcSub = 0);
-
- virtual void prepareStart(void);
-
- virtual void pushCollisions(char all);
-
- virtual int16 checkCollisions(byte handleMouse, int16 deltaTime,
- int16 *pResId, int16 *pResIndex);
- virtual void collisionsBlock(void);
-
Game_v6(GobEngine *vm);
virtual ~Game_v6() {}
-protected:
- uint32 _someTimeDly;
-
- virtual void setCollisions(byte arg_0 = 1);
- virtual void collSub(uint16 offset);
-
- virtual int16 adjustKey(int16 key);
-
- virtual int16 checkMousePoint(int16 all, int16 *resId, int16 *resIndex);
+ virtual void totSub(int8 flags, const char *newTotFile);
- void collSubReenter();
+ virtual void prepareStart(void);
};
class Game_Fascination : public Game_v2 {
public:
- virtual int16 checkCollisions(byte handleMouse, int16 deltaTime,
- int16 *pResId, int16 *pResIndex);
-
Game_Fascination(GobEngine *vm);
virtual ~Game_Fascination() {}
};
diff --git a/engines/gob/game_fascin.cpp b/engines/gob/game_fascin.cpp
index 1387bf1de1..20480f778f 100644
--- a/engines/gob/game_fascin.cpp
+++ b/engines/gob/game_fascin.cpp
@@ -45,159 +45,4 @@ namespace Gob {
Game_Fascination::Game_Fascination(GobEngine *vm) : Game_v2(vm) {
}
-int16 Game_Fascination::checkCollisions(byte handleMouse, int16 deltaTime, int16 *pResId,
- int16 *pResIndex) {
- int16 resIndex;
- int16 key;
- int16 oldIndex;
- int16 oldId;
- int16 newkey;
- uint32 timeKey;
-
- _scrollHandleMouse = handleMouse != 0;
-
- if (deltaTime >= -1) {
- _lastCollKey = 0;
- _lastCollAreaIndex = 0;
- _lastCollId = 0;
- }
-
- if (pResId != 0)
- *pResId = 0;
-
- resIndex = 0;
-
- if ((_vm->_draw->_cursorIndex == -1) &&
- (handleMouse != 0) && (_lastCollKey == 0)) {
- _lastCollKey = checkMousePoint(1, &_lastCollId, &_lastCollAreaIndex);
-
- if ((_lastCollKey != 0) && (_lastCollId & 0x8000))
- collAreaSub(_lastCollAreaIndex, 1);
- }
-
- if (handleMouse != 0) {
- if ((handleMouse==1) && (_vm->_draw->_renderFlags & RENDERFLAG_UNKNOWN))
- warning("checkCollisions : RENDERFLAG_UNKNOWN - Unknown behavior");
- _vm->_draw->animateCursor(-1);
- }
-
- timeKey = _vm->_util->getTimeKey();
- while (1) {
- if (_vm->_inter->_terminate || _vm->shouldQuit()) {
- if (handleMouse)
- _vm->_draw->blitCursor();
- return 0;
- }
-
- if (!_vm->_draw->_noInvalidated) {
- if (handleMouse != 0)
- _vm->_draw->animateCursor(-1);
- else
- _vm->_draw->blitInvalidated();
- _vm->_video->waitRetrace();
- }
-
- key = checkKeys(&_vm->_global->_inter_mouseX,
- &_vm->_global->_inter_mouseY, &_mouseButtons, handleMouse);
-
- if ((handleMouse == 0) && (_mouseButtons != kMouseButtonsNone)) {
- _vm->_util->waitMouseRelease(0);
- key = 3;
- }
-
- if (key != 0) {
-
- if (handleMouse & 1)
- _vm->_draw->blitCursor();
-
- if (pResId != 0)
- *pResId = 0;
-
- if (pResIndex != 0)
- *pResIndex = 0;
-
- if (_lastCollKey != 0)
- collAreaSub(_lastCollAreaIndex, 0);
-
- _lastCollKey = 0;
- if (key != 0)
- return key;
- }
-
- if (handleMouse != 0) {
- if (_mouseButtons != kMouseButtonsNone) {
- if (deltaTime > 0) {
- _vm->_draw->animateCursor(2);
- _vm->_util->delay(deltaTime);
- } else if (handleMouse & 1)
- _vm->_util->waitMouseRelease(1);
- _vm->_draw->animateCursor(-1);
-
- if (pResId != 0)
- *pResId = 0;
-
- key = checkMousePoint(0, pResId, &resIndex);
- if (pResIndex != 0)
- *pResIndex = resIndex;
-
- if ((key != 0) || ((pResId != 0) && (*pResId != 0))) {
- if ((handleMouse & 1) &&
- ((deltaTime <= 0) || (_mouseButtons == kMouseButtonsNone)))
- _vm->_draw->blitCursor();
-
- if ((_lastCollKey != 0) && (key != _lastCollKey))
- collAreaSub(_lastCollAreaIndex, 0);
-
- _lastCollKey = 0;
- return key;
- }
-
- if (handleMouse & 4)
- return 0;
-
- if (_lastCollKey != 0)
- collAreaSub(_lastCollAreaIndex, 0);
-
- _lastCollKey = checkMousePoint(1, &_lastCollId, &_lastCollAreaIndex);
- if ((_lastCollKey != 0) && (_lastCollId & 0x8000))
- collAreaSub(_lastCollAreaIndex, 1);
- } else if ((_vm->_global->_inter_mouseX != _vm->_draw->_cursorX) ||
- (_vm->_global->_inter_mouseY != _vm->_draw->_cursorY)) {
-
- oldIndex = _lastCollAreaIndex;
- oldId = _lastCollId;
- newkey = checkMousePoint(1, &_lastCollId, &_lastCollAreaIndex);
-
- if (newkey != _lastCollKey) {
- if ((_lastCollKey != 0) && (oldId & 0x8000))
- collAreaSub(oldIndex, 0);
-
- _lastCollKey = newkey;
-
- if ((newkey != 0) && (_lastCollId & 0x8000))
- collAreaSub(_lastCollAreaIndex, 1);
- }
- }
- }
-
- if ((deltaTime < 0) && (key == 0) && (_mouseButtons == kMouseButtonsNone)) {
- uint32 curtime = _vm->_util->getTimeKey();
- if ((curtime + deltaTime) > timeKey) {
- if (pResId != 0)
- *pResId = 0;
-
- if (pResIndex != 0)
- *pResIndex = 0;
-
- return 0;
- }
- }
-
- if (handleMouse != 0)
- _vm->_draw->animateCursor(-1);
-
- _vm->_util->delay(10);
- }
-}
-
} // End of namespace Gob
diff --git a/engines/gob/game_v1.cpp b/engines/gob/game_v1.cpp
index ca6a7044cb..5948a21b9c 100644
--- a/engines/gob/game_v1.cpp
+++ b/engines/gob/game_v1.cpp
@@ -160,294 +160,7 @@ void Game_v1::playTot(int16 skipPlay) {
_script->pop();
}
-void Game_v1::clearCollisions() {
- for (int i = 0; i < 250; i++) {
- _collisionAreas[i].id = 0;
- _collisionAreas[i].left = 0xFFFF;
- }
-}
-
-int16 Game_v1::addNewCollision(int16 id, uint16 left, uint16 top,
- uint16 right, uint16 bottom, int16 flags, int16 key,
- uint16 funcEnter, uint16 funcLeave, uint16 funcSub) {
- Collision *ptr;
-
- debugC(5, kDebugCollisions, "addNewCollision");
- debugC(5, kDebugCollisions, "id = %X", id);
- debugC(5, kDebugCollisions, "left = %d, top = %d, right = %d, bottom = %d",
- left, top, right, bottom);
- debugC(5, kDebugCollisions, "flags = %X, key = %X", flags, key);
- debugC(5, kDebugCollisions, "funcEnter = %d, funcLeave = %d",
- funcEnter, funcLeave);
-
- for (int i = 0; i < 250; i++) {
- if (_collisionAreas[i].left != 0xFFFF)
- continue;
-
- ptr = &_collisionAreas[i];
- ptr->id = id;
- ptr->left = left;
- ptr->top = top;
- ptr->right = right;
- ptr->bottom = bottom;
- ptr->flags = flags;
- ptr->key = key;
- ptr->funcEnter = funcEnter;
- ptr->funcLeave = funcLeave;
- ptr->funcSub = funcSub;
- ptr->script = 0;
-
- return i;
- }
- error("Game_v1::addNewCollision(): Collision array full");
- return 0;
-}
-
-void Game_v1::pushCollisions(char all) {
- Collision *srcPtr;
- Collision *destPtr;
- int16 size;
-
- debugC(1, kDebugCollisions, "pushCollisions");
- for (size = 0, srcPtr = _collisionAreas; srcPtr->left != 0xFFFF; srcPtr++) {
- if (all || (srcPtr->id & 0x8000))
- size++;
- }
-
- destPtr = new Collision[size];
- _collStack[_collStackSize] = destPtr;
- _collStackElemSizes[_collStackSize] = size;
- _collStackSize++;
-
- for (srcPtr = _collisionAreas; srcPtr->left != 0xFFFF; srcPtr++) {
- if (all || (srcPtr->id & 0x8000)) {
- memcpy(destPtr, srcPtr, sizeof(Collision));
- srcPtr->left = 0xFFFF;
- destPtr++;
- }
- }
-}
-
-void Game_v1::popCollisions(void) {
- Collision *destPtr;
- Collision *srcPtr;
-
- debugC(1, kDebugCollisions, "popCollision");
-
- _collStackSize--;
- for (destPtr = _collisionAreas; destPtr->left != 0xFFFF; destPtr++)
- ;
-
- srcPtr = _collStack[_collStackSize];
- memcpy(destPtr, srcPtr,
- _collStackElemSizes[_collStackSize] * sizeof(Collision));
-
- delete[] _collStack[_collStackSize];
-}
-
-int16 Game_v1::checkCollisions(byte handleMouse, int16 deltaTime,
- int16 *pResId, int16 *pResIndex) {
- int16 resIndex;
- int16 key;
- int16 oldIndex;
- int16 oldId;
- uint32 timeKey;
- bool firstIteration = true;
-
- if (deltaTime >= -1) {
- _lastCollKey = 0;
- _lastCollAreaIndex = 0;
- _lastCollId = 0;
- }
-
- if (pResId != 0)
- *pResId = 0;
-
- resIndex = 0;
-
- timeKey = _vm->_util->getTimeKey();
-
- if ((_vm->_draw->_cursorIndex == -1) && (handleMouse != 0) &&
- (_lastCollKey == 0)) {
- _lastCollKey = checkMousePoint(1, &_lastCollId, &_lastCollAreaIndex);
-
- if ((_lastCollKey != 0) && ((_lastCollId & 0x8000) != 0)) {
- _script->call(_collisionAreas[_lastCollAreaIndex].funcEnter);
- _vm->_inter->funcBlock(0);
- _script->pop();
- }
- }
-
- if (handleMouse != 0)
- _vm->_draw->animateCursor(-1);
-
- while (1) {
- if (_vm->_inter->_terminate) {
- if (handleMouse)
- _vm->_draw->blitCursor();
- return 0;
- }
-
- if (!_vm->_draw->_noInvalidated) {
- if (handleMouse)
- _vm->_draw->animateCursor(-1);
- else
- _vm->_draw->blitInvalidated();
- }
-
- // NOTE: the original asm does the below checkKeys call
- // _before_ this check. However, that can cause keypresses to get lost
- // since there's a return statement in this check.
- // Additionally, I added a 'deltaTime == -1' check there, since
- // when this function is called with deltaTime == -1 in inputArea,
- // and the return value is then discarded.
- if (deltaTime < 0) {
- uint32 curtime = _vm->_util->getTimeKey();
- if ((deltaTime == -1) || (((curtime + deltaTime) > timeKey) && !firstIteration)) {
- if (pResId != 0)
- *pResId = 0;
-
- if (pResIndex != 0)
- *pResIndex = 0;
-
- return 0;
- }
- }
-
- key = checkKeys(&_vm->_global->_inter_mouseX,
- &_vm->_global->_inter_mouseY, &_mouseButtons, handleMouse);
-
- if ((handleMouse == 0) && (_mouseButtons != kMouseButtonsNone)) {
- _vm->_util->waitMouseRelease(0);
- key = 3;
- }
-
- if (key != 0) {
-
- if (handleMouse == 1)
- _vm->_draw->blitCursor();
-
- if (pResId != 0)
- *pResId = 0;
-
- if (pResIndex != 0)
- *pResIndex = 0;
-
- if ((_lastCollKey != 0) &&
- (_collisionAreas[_lastCollAreaIndex].funcLeave != 0)) {
-
- _script->call(_collisionAreas[_lastCollAreaIndex].funcLeave);
- _vm->_inter->funcBlock(0);
- _script->pop();
- }
-
- _lastCollKey = 0;
- if (key != 0)
- return key;
- }
-
- if (handleMouse != 0) {
- if (_mouseButtons != kMouseButtonsNone) {
- oldIndex = 0;
-
- _vm->_draw->animateCursor(2);
- if (deltaTime <= 0) {
- if (handleMouse == 1)
- _vm->_util->waitMouseRelease(1);
- } else if (deltaTime > 0)
- _vm->_util->delay(deltaTime);
-
- _vm->_draw->animateCursor(-1);
- if (pResId != 0)
- *pResId = 0;
-
- key = checkMousePoint(0, pResId, &resIndex);
-
- if (pResIndex != 0)
- *pResIndex = resIndex;
-
- if ((key != 0) || ((pResId != 0) && (*pResId != 0))) {
- if ((handleMouse == 1) &&
- ((deltaTime <= 0) || (_mouseButtons == kMouseButtonsNone)))
- _vm->_draw->blitCursor();
-
- if ((_lastCollKey != 0) &&
- (_collisionAreas[_lastCollAreaIndex].funcLeave != 0)) {
-
- _script->call(_collisionAreas[_lastCollAreaIndex].funcLeave);
- _vm->_inter->funcBlock(0);
- _script->pop();
-
- }
- _lastCollKey = 0;
- return key;
- }
-
- if ((_lastCollKey != 0) &&
- (_collisionAreas[_lastCollAreaIndex].funcLeave != 0)) {
-
- _script->call(_collisionAreas[_lastCollAreaIndex].funcLeave);
- _vm->_inter->funcBlock(0);
- _script->pop();
-
- }
-
- _lastCollKey =
- checkMousePoint(1, &_lastCollId, &_lastCollAreaIndex);
-
- if ((_lastCollKey != 0) && ((_lastCollId & 0x8000) != 0)) {
-
- _script->call(_collisionAreas[_lastCollAreaIndex].funcEnter);
- _vm->_inter->funcBlock(0);
- _script->pop();
-
- }
- } else {
-
- if ((handleMouse != 0) &&
- ((_vm->_global->_inter_mouseX != _vm->_draw->_cursorX) ||
- (_vm->_global->_inter_mouseY != _vm->_draw->_cursorY))) {
- oldIndex = _lastCollAreaIndex;
- oldId = _lastCollId;
-
- key = checkMousePoint(1, &_lastCollId, &_lastCollAreaIndex);
-
- if (key != _lastCollKey) {
- if ((_lastCollKey != 0) && ((oldId & 0x8000) != 0)) {
-
- _script->call(_collisionAreas[oldIndex].funcLeave);
- _vm->_inter->funcBlock(0);
- _script->pop();
-
- }
-
- _lastCollKey = key;
- if ((_lastCollKey != 0) && ((_lastCollId & 0x8000) != 0)) {
-
- _script->call(_collisionAreas[_lastCollAreaIndex].funcEnter);
- _vm->_inter->funcBlock(0);
- _script->pop();
-
- }
-
- }
- }
- }
- }
-
- if (handleMouse != 0)
- _vm->_draw->animateCursor(-1);
-
- if (deltaTime < -10)
- _vm->_util->delay(10);
-
- firstIteration = false;
- }
-}
-
void Game_v1::prepareStart(void) {
- clearCollisions();
-
_vm->_global->_pPaletteDesc->unused2 = _vm->_draw->_unusedPalette2;
_vm->_global->_pPaletteDesc->unused1 = _vm->_draw->_unusedPalette1;
_vm->_global->_pPaletteDesc->vgaPal = _vm->_draw->_vgaPalette;
@@ -489,937 +202,4 @@ void Game_v1::prepareStart(void) {
_startTimeKey = _vm->_util->getTimeKey();
}
-void Game_v1::collisionsBlock(void) {
- InputDesc descArray[20];
- int16 array[250];
- byte count;
- int16 collResId;
- int16 curCmd;
- int16 cmd;
- int16 cmdHigh;
- int16 key;
- int16 flags;
- uint16 left;
- uint16 top;
- uint16 width;
- uint16 height;
- int16 var_22;
- int16 index;
- int16 curEditIndex;
- int16 deltaTime;
- int16 descIndex2;
- int16 stackPos2;
- int16 descIndex;
- int16 timeVal;
- char *str;
- int16 savedCollStackSize;
- int16 i;
- int16 counter;
- int16 var_24;
- int16 var_26;
- int16 collStackPos;
- Collision *collPtr;
- uint32 timeKey;
-
- if (_shouldPushColls)
- pushCollisions(1);
-
- collResId = -1;
- _script->skip(1);
- count = _script->readByte();
- _handleMouse = _script->readByte();
- deltaTime = 1000 * _script->readByte();
- descIndex2 = _script->readByte();
- stackPos2 = _script->readByte();
- descIndex = _script->readByte();
-
- if ((stackPos2 != 0) || (descIndex != 0))
- deltaTime /= 100;
-
- timeVal = deltaTime;
- _script->skip(1);
-
- uint32 startPos = _script->pos();
-
- WRITE_VAR(16, 0);
- var_22 = 0;
- index = 0;
- curEditIndex = 0;
-
- for (curCmd = 0; curCmd < count; curCmd++) {
- array[curCmd] = 0;
- cmd = _script->readByte();
-
- if ((cmd & 0x40) != 0) {
- cmd -= 0x40;
- cmdHigh = _script->readByte();
- cmdHigh <<= 8;
- } else
- cmdHigh = 0;
-
- if ((cmd & 0x80) != 0) {
- left = _script->readValExpr();
- top = _script->readValExpr();
- width = _script->readValExpr();
- height = _script->readValExpr();
- } else {
- left = _script->readUint16();
- top = _script->readUint16();
- width = _script->readUint16();
- height = _script->readUint16();
- }
- cmd &= 0x7F;
-
- debugC(1, kDebugCollisions, "collisionsBlock(%d)", cmd);
-
- switch (cmd) {
- case 3:
- case 4:
- case 5:
- case 6:
- case 7:
- case 8:
- case 9:
- case 10:
-
- _vm->_util->clearKeyBuf();
- var_22 = 1;
- key = _script->readVarIndex();
- descArray[index].fontIndex = _script->readInt16();
- descArray[index].backColor = _script->readByte();
- descArray[index].frontColor = _script->readByte();
-
- if ((cmd < 5) || (cmd > 8)) {
- descArray[index].ptr = 0;
- } else {
- descArray[index].ptr = _script->getData() + _script->pos() + 2;
- _script->skip(_script->readInt16());
- }
-
- if (left == 0xFFFF)
- break;
-
- if ((cmd & 1) == 0) {
- addNewCollision(curCmd + 0x8000, left, top, left + width *
- _vm->_draw->_fonts[descArray[index].fontIndex]->itemWidth - 1,
- top + height - 1, cmd, key, 0, _script->pos());
-
- _script->skip(_script->peekUint16(2) + 2);
- } else {
- addNewCollision(curCmd + 0x8000, left, top, left + width *
- _vm->_draw->_fonts[descArray[index].fontIndex]->itemWidth - 1,
- top + height - 1, cmd, key, 0, 0);
- }
- index++;
- break;
-
- case 21:
- key = _script->readInt16();
- array[curCmd] = _script->readInt16();
- flags = _script->readInt16() & 3;
-
- addNewCollision(curCmd + 0x8000, left, top,
- left + width - 1, top + height - 1,
- (flags << 4) + cmdHigh + 2, key, _script->pos(), 0);
-
- _script->skip(_script->peekUint16(2) + 2);
- break;
-
- case 20:
- collResId = curCmd;
- // Fall through to case 2
-
- case 2:
- key = _script->readInt16();
- array[curCmd] = _script->readInt16();
- flags = _script->readInt16() & 3;
-
- addNewCollision(curCmd + 0x8000, left, top,
- left + width - 1,
- top + height - 1,
- (flags << 4) + cmdHigh + 2, key, 0, _script->pos());
-
- _script->skip(_script->peekUint16(2) + 2);
- break;
-
- case 0:
- _script->skip(6);
- startPos = _script->pos();
- _script->skip(_script->peekUint16(2) + 2);
- key = curCmd + 0xA000;
-
- addNewCollision(curCmd + 0x8000, left, top,
- left + width - 1, top + height - 1,
- cmd + cmdHigh, key,
- startPos, _script->pos());
-
- _script->skip(_script->peekUint16(2) + 2);
- break;
-
- case 1:
- key = _script->readInt16();
- array[curCmd] = _script->readInt16();
- flags = _script->readInt16() & 3;
-
- startPos = _script->pos();
- _script->skip(_script->peekUint16(2) + 2);
- if (key == 0)
- key = curCmd + 0xA000;
-
- addNewCollision(curCmd + 0x8000, left, top,
- left + width - 1, top + height - 1,
- (flags << 4) + cmd + cmdHigh, key,
- startPos, _script->pos());
-
- _script->skip(_script->peekUint16(2) + 2);
- break;
- }
- }
-
- _forceHandleMouse = 0;
- _vm->_util->clearKeyBuf();
-
- do {
- if (var_22 != 0) {
- key = multiEdit(deltaTime, index, &curEditIndex,
- descArray, &_activeCollResId, &_activeCollIndex);
-
- if (key == kKeyReturn) {
- for (i = 0; i < 250; i++) {
- if (_collisionAreas[i].left == 0xFFFF)
- continue;
-
- if ((_collisionAreas[i].id & 0x8000) == 0)
- continue;
-
- if ((_collisionAreas[i].flags & 1) != 0)
- continue;
-
- if ((_collisionAreas[i].flags & 0x0F) <= 2)
- continue;
-
- collResId = _collisionAreas[i].id;
- _activeCollResId = collResId;
- collResId &= 0x7FFF;
- _activeCollIndex = i;
- break;
- }
- break;
- }
- } else
- key = checkCollisions(_handleMouse, -deltaTime,
- &_activeCollResId, &_activeCollIndex);
-
- if (((key & 0xFF) >= ' ') && ((key & 0xFF) <= 0xFF) &&
- ((key >> 8) > 1) && ((key >> 8) < 12))
- key = '0' + (((key >> 8) - 1) % 10) + (key & 0xFF00);
-
- if (_activeCollResId == 0) {
- if (key != 0) {
- for (i = 0; i < 250; i++) {
- if (_collisionAreas[i].left == 0xFFFF)
- continue;
-
- if ((_collisionAreas[i].id & 0x8000) == 0)
- continue;
-
- if ((_collisionAreas[i].key == key) ||
- (_collisionAreas[i].key == 0x7FFF)) {
-
- _activeCollResId = _collisionAreas[i].id;
- _activeCollIndex = i;
- break;
- }
- }
-
- if (_activeCollResId == 0) {
- for (i = 0; i < 250; i++) {
- if (_collisionAreas[i].left == 0xFFFF)
- continue;
-
- if ((_collisionAreas[i].id & 0x8000) == 0)
- continue;
-
- if ((_collisionAreas[i].key & 0xFF00) != 0)
- continue;
-
- if (_collisionAreas[i].key == 0)
- continue;
-
- if ((adjustKey(key & 0xFF) == adjustKey(_collisionAreas[i].key)) ||
- (_collisionAreas[i].key == 0x7FFF)) {
- _activeCollResId = _collisionAreas[i].id;
- _activeCollIndex = i;
- break;
- }
- }
- }
- } else {
-
- if ((deltaTime != 0) && (VAR(16) == 0)) {
- if (stackPos2 != 0) {
- collStackPos = 0;
- collPtr = _collisionAreas;
-
- for (i = 0, collPtr = _collisionAreas;
- collPtr->left != 0xFFFF; i++, collPtr++) {
-
- if ((collPtr->id & 0x8000) == 0)
- continue;
-
- collStackPos++;
- if (collStackPos != stackPos2)
- continue;
-
- _activeCollResId = collPtr->id;
- _activeCollIndex = i;
- WRITE_VAR(2, _vm->_global->_inter_mouseX);
- WRITE_VAR(3, _vm->_global->_inter_mouseY);
- WRITE_VAR(4, (uint32) _mouseButtons);
- WRITE_VAR(16, array[(uint16) _activeCollResId & ~0x8000]);
-
- if (collPtr->funcLeave != 0) {
- timeKey = _vm->_util->getTimeKey();
-
- uint32 savedPos = _script->pos();
-
- _script->seek(collPtr->funcLeave);
-
- _shouldPushColls = 1;
- savedCollStackSize = _collStackSize;
- _vm->_inter->funcBlock(0);
-
- if (savedCollStackSize != _collStackSize)
- popCollisions();
-
- _shouldPushColls = 0;
-
- _script->seek(savedPos);
-
- deltaTime = timeVal -
- (_vm->_util->getTimeKey() - timeKey);
-
- if (deltaTime < 2)
- deltaTime = 2;
- }
-
- if (VAR(16) == 0)
- _activeCollResId = 0;
- break;
- }
- } else {
- if (descIndex != 0) {
- counter = 0;
- for (i = 0; i < 250; i++) {
- if (_collisionAreas[i].left == 0xFFFF)
- continue;
-
- if ((_collisionAreas[i].id & 0x8000) == 0)
- continue;
-
- counter++;
- if (counter != descIndex)
- continue;
-
- _activeCollResId = _collisionAreas[i].id;
- _activeCollIndex = i;
- break;
- }
- } else {
- for (i = 0; i < 250; i++) {
- if (_collisionAreas[i].left == 0xFFFF)
- continue;
-
- if ((_collisionAreas[i].id & 0x8000) == 0)
- continue;
-
- _activeCollResId = _collisionAreas[i].id;
- _activeCollIndex = i;
- break;
- }
- }
- }
- } else {
- if (descIndex2 != 0) {
- counter = 0;
- for (i = 0; i < 250; i++) {
- if (_collisionAreas[i].left == 0xFFFF)
- continue;
-
- if ((_collisionAreas[i].id & 0x8000) == 0)
- continue;
-
- counter++;
- if (counter != descIndex2)
- continue;
-
- _activeCollResId = _collisionAreas[i].id;
- _activeCollIndex = i;
- break;
- }
- }
- }
- }
- }
-
- if (_activeCollResId == 0)
- continue;
-
- if (_collisionAreas[_activeCollIndex].funcLeave != 0)
- continue;
-
- WRITE_VAR(2, _vm->_global->_inter_mouseX);
- WRITE_VAR(3, _vm->_global->_inter_mouseY);
- WRITE_VAR(4, (uint32) _mouseButtons);
- WRITE_VAR(16, array[(uint16) _activeCollResId & ~0x8000]);
-
- if (_collisionAreas[_activeCollIndex].funcEnter != 0) {
- uint32 savedPos = _script->pos();
-
- _script->seek(_collisionAreas[_activeCollIndex].funcEnter);
-
- _shouldPushColls = 1;
-
- collStackPos = _collStackSize;
- _vm->_inter->funcBlock(0);
- if (collStackPos != _collStackSize)
- popCollisions();
- _shouldPushColls = 0;
-
- _script->seek(savedPos);
- }
-
- WRITE_VAR(16, 0);
- _activeCollResId = 0;
- }
- while ((_activeCollResId == 0) && !_vm->_inter->_terminate && !_vm->shouldQuit());
-
- if (((uint16) _activeCollResId & ~0x8000) == collResId) {
- collStackPos = 0;
- var_24 = 0;
- var_26 = 1;
- for (i = 0; i < 250; i++) {
- if (_collisionAreas[i].left == 0xFFFF)
- continue;
-
- if ((_collisionAreas[i].id & 0x8000) == 0)
- continue;
-
- if ((_collisionAreas[i].flags & 0x0F) < 3)
- continue;
-
- if ((_collisionAreas[i].flags & 0x0F) > 10)
- continue;
-
- if ((_collisionAreas[i].flags & 0x0F) > 8) {
- char *ptr;
- strncpy0(_tempStr, GET_VARO_STR(_collisionAreas[i].key), 255);
- while ((ptr = strchr(_tempStr, ' ')) != 0) {
- _vm->_util->cutFromStr(_tempStr, (ptr - _tempStr), 1);
- ptr = strchr(_tempStr, ' ');
- }
- WRITE_VARO_STR(_collisionAreas[i].key, _tempStr);
- }
-
- if (((_collisionAreas[i].flags & 0x0F) >= 5) &&
- ((_collisionAreas[i].flags & 0x0F) <= 8)) {
- str = (char *) descArray[var_24].ptr;
-
- strncpy0(_tempStr, GET_VARO_STR(_collisionAreas[i].key), 255);
-
- if ((_collisionAreas[i].flags & 0x0F) < 7)
- _vm->_util->cleanupStr(_tempStr);
-
- int16 pos = 0;
- do {
- strncpy0(_collStr, str, 255);
- pos += strlen(str) + 1;
-
- str += strlen(str) + 1;
-
- if ((_collisionAreas[i].flags & 0x0F) < 7)
- _vm->_util->cleanupStr(_collStr);
-
- if (strcmp(_tempStr, _collStr) == 0) {
- WRITE_VAR(17, VAR(17) + 1);
- WRITE_VAR(17 + var_26, 1);
- break;
- }
- } while (READ_LE_UINT16(descArray[var_24].ptr - 2) > pos);
- collStackPos++;
- } else {
- WRITE_VAR(17 + var_26, 2);
- }
- var_24++;
- var_26++;
- }
-
- if (collStackPos != (int16) VAR(17))
- WRITE_VAR(17, 0);
- else
- WRITE_VAR(17, 1);
- }
-
- if (!_vm->_inter->_terminate) {
- _script->seek(_collisionAreas[_activeCollIndex].funcLeave);
-
- WRITE_VAR(2, _vm->_global->_inter_mouseX);
- WRITE_VAR(3, _vm->_global->_inter_mouseY);
- WRITE_VAR(4, (uint32) _mouseButtons);
-
- if (VAR(16) == 0)
- WRITE_VAR(16, array[(uint16) _activeCollResId & ~0x8000]);
- } else
- _script->setFinished(true);
-
- for (curCmd = 0; curCmd < count; curCmd++)
- freeCollision(curCmd + 0x8000);
-}
-
-int16 Game_v1::multiEdit(int16 time, int16 index, int16 *pCurPos,
- InputDesc * inpDesc, int16 *collResId, int16 *collIndex, bool mono) {
- Collision *collArea;
- int16 descInd;
- int16 key;
- int16 found = -1;
- int16 i;
-
- descInd = 0;
- for (i = 0; i < 250; i++) {
- collArea = &_collisionAreas[i];
-
- if (collArea->left == 0xFFFF)
- continue;
-
- if ((collArea->id & 0x8000) == 0)
- continue;
-
- if ((collArea->flags & 0x0F) < 3)
- continue;
-
- if ((collArea->flags & 0x0F) > 10)
- continue;
-
- strncpy0(_tempStr, GET_VARO_STR(collArea->key), 255);
-
- _vm->_draw->_destSpriteX = collArea->left;
- _vm->_draw->_destSpriteY = collArea->top;
- _vm->_draw->_spriteRight = collArea->right - collArea->left + 1;
- _vm->_draw->_spriteBottom = collArea->bottom - collArea->top + 1;
-
- _vm->_draw->_destSurface = 21;
-
- _vm->_draw->_backColor = inpDesc[descInd].backColor;
- _vm->_draw->_frontColor = inpDesc[descInd].frontColor;
- _vm->_draw->_textToPrint = _tempStr;
- _vm->_draw->_transparency = 1;
- _vm->_draw->_fontIndex = inpDesc[descInd].fontIndex;
- _vm->_draw->spriteOperation(DRAW_FILLRECT);
- _vm->_draw->_destSpriteY +=
- ((collArea->bottom - collArea->top + 1) - 8) / 2;
-
- _vm->_draw->spriteOperation(DRAW_PRINTTEXT);
- descInd++;
- }
-
- for (i = 0; i < 40; i++)
- WRITE_VAR_OFFSET(i * 4 + 0x44, 0);
-
- while (1) {
- descInd = 0;
-
- for (i = 0; i < 250; i++) {
- collArea = &_collisionAreas[i];
-
- if (collArea->left == 0xFFFF)
- continue;
-
- if ((collArea->id & 0x8000) == 0)
- continue;
-
- if ((collArea->flags & 0x0F) < 3)
- continue;
-
- if ((collArea->flags & 0x0F) > 10)
- continue;
-
- if (descInd == *pCurPos) {
- found = i;
- break;
- }
-
- descInd++;
- }
-
- assert(found != -1);
-
- collArea = &_collisionAreas[found];
-
- key = inputArea(collArea->left, collArea->top,
- collArea->right - collArea->left + 1,
- collArea->bottom - collArea->top + 1,
- inpDesc[*pCurPos].backColor, inpDesc[*pCurPos].frontColor,
- GET_VARO_STR(collArea->key), inpDesc[*pCurPos].fontIndex,
- collArea->flags, &time, collResId, collIndex);
-
- if (_vm->_inter->_terminate)
- return 0;
-
- switch (key) {
- case kKeyNone:
- if (*collResId == 0)
- return 0;
-
- if ((_collisionAreas[*collIndex].flags & 0x0F) < 3)
- return 0;
-
- if ((_collisionAreas[*collIndex].flags & 0x0F) > 10)
- return 0;
-
- *pCurPos = 0;
- for (i = 0; i < 250; i++) {
- collArea = &_collisionAreas[i];
-
- if (collArea->left == 0xFFFF)
- continue;
-
- if ((collArea->id & 0x8000) == 0)
- continue;
-
- if ((collArea->flags & 0x0F) < 3)
- continue;
-
- if ((collArea->flags & 0x0F) > 10)
- continue;
-
- if (i == *collIndex)
- break;
-
- pCurPos[0]++;
- }
- break;
-
- case kKeyF1:
- case kKeyF2:
- case kKeyF3:
- case kKeyF4:
- case kKeyF5:
- case kKeyF6:
- case kKeyF7:
- case kKeyF8:
- case kKeyF9:
- case kKeyF10:
- return key;
-
- case kKeyReturn:
-
- if (index == 1)
- return key;
-
- if (*pCurPos == index - 1) {
- *pCurPos = 0;
- break;
- }
-
- pCurPos[0]++;
- break;
-
- case kKeyDown:
- if (index - 1 > *pCurPos)
- pCurPos[0]++;
- break;
-
- case kKeyUp:
- if (*pCurPos > 0)
- pCurPos[0]--;
- break;
- }
- }
-}
-
-int16 Game_v1::inputArea(int16 xPos, int16 yPos, int16 width, int16 height,
- int16 backColor, int16 frontColor, char *str, int16 fontIndex,
- char inpType, int16 *pTotTime, int16 *collResId, int16 *collIndex, bool mono) {
- int16 handleMouse;
- uint32 editSize;
- Video::FontDesc *pFont;
- char curSym;
- int16 key;
- const char *str1;
- const char *str2;
- int16 i;
- uint32 pos;
- int16 flag;
- int16 savedKey;
-
- if ((_handleMouse != 0) &&
- ((_vm->_global->_useMouse != 0) || (_forceHandleMouse != 0)))
- handleMouse = 1;
- else
- handleMouse = 0;
-
- pos = strlen(str);
- pFont = _vm->_draw->_fonts[fontIndex];
- editSize = width / pFont->itemWidth;
-
- while (1) {
- strncpy0(_tempStr, str, 254);
- strcat(_tempStr, " ");
- if (strlen(_tempStr) > editSize)
- strncpy0(_tempStr, str, 255);
-
- _vm->_draw->_destSpriteX = xPos;
- _vm->_draw->_destSpriteY = yPos;
- _vm->_draw->_spriteRight = editSize * pFont->itemWidth;
- _vm->_draw->_spriteBottom = height;
-
- _vm->_draw->_destSurface = 21;
- _vm->_draw->_backColor = backColor;
- _vm->_draw->_frontColor = frontColor;
- _vm->_draw->_textToPrint = _tempStr;
- _vm->_draw->_transparency = 1;
- _vm->_draw->_fontIndex = fontIndex;
- _vm->_draw->spriteOperation(DRAW_FILLRECT);
-
- _vm->_draw->_destSpriteY = yPos + (height - 8) / 2;
-
- _vm->_draw->spriteOperation(DRAW_PRINTTEXT);
- if (pos == editSize)
- pos--;
-
- curSym = _tempStr[pos];
-
- flag = 1;
-
- while (1) {
- _tempStr[0] = curSym;
- _tempStr[1] = 0;
-
- _vm->_draw->_destSpriteX = xPos + pFont->itemWidth * pos;
- _vm->_draw->_destSpriteY = yPos + height - 1;
- _vm->_draw->_spriteRight = pFont->itemWidth;
- _vm->_draw->_spriteBottom = 1;
- _vm->_draw->_destSurface = 21;
- _vm->_draw->_backColor = frontColor;
- _vm->_draw->spriteOperation(DRAW_FILLRECT);
-
- if (flag != 0)
- key = checkCollisions(handleMouse, -1, collResId, collIndex);
- flag = 0;
-
- key = checkCollisions(handleMouse, -300, collResId, collIndex);
-
- if (*pTotTime > 0) {
- *pTotTime -= 300;
- if (*pTotTime <= 1) {
- key = 0;
- *collResId = 0;
- break;
- }
- }
-
- _tempStr[0] = curSym;
- _tempStr[1] = 0;
- _vm->_draw->_destSpriteX = xPos + pFont->itemWidth * pos;
- _vm->_draw->_destSpriteY = yPos + height - 1;
- _vm->_draw->_spriteRight = pFont->itemWidth;
- _vm->_draw->_spriteBottom = 1;
- _vm->_draw->_destSurface = 21;
- _vm->_draw->_backColor = backColor;
- _vm->_draw->_frontColor = frontColor;
- _vm->_draw->_textToPrint = _tempStr;
- _vm->_draw->_transparency = 1;
- _vm->_draw->spriteOperation(DRAW_FILLRECT);
-
- _vm->_draw->_destSpriteY = yPos + (height - 8) / 2;
- _vm->_draw->spriteOperation(DRAW_PRINTTEXT);
-
- if ((key != 0) || (*collResId != 0))
- break;
-
- key = checkCollisions(handleMouse, -300, collResId, collIndex);
-
- if (*pTotTime > 0) {
- *pTotTime -= 300;
- if (*pTotTime <= 1) {
- key = 0;
- *collResId = 0;
- break;
- }
- }
-
- if ((key != 0) || (*collResId != 0))
- break;
-
- if (_vm->_inter->_terminate)
- return 0;
- }
-
- if ((key == 0) || (*collResId != 0) || _vm->_inter->_terminate)
- return 0;
-
- switch (key) {
- case kKeyRight:
- if ((pos < strlen(str)) && (pos < (editSize - 1))) {
- pos++;
- continue;
- }
- return kKeyDown;
-
- case kKeyLeft:
- if (pos > 0) {
- pos--;
- continue;
- }
- return kKeyUp;
-
- case kKeyBackspace:
- if (pos > 0) {
- _vm->_util->cutFromStr(str, pos - 1, 1);
- pos--;
- continue;
- }
-
- case kKeyDelete:
- if (pos >= strlen(str))
- continue;
-
- _vm->_util->cutFromStr(str, pos, 1);
- continue;
-
- case kKeyReturn:
- case kKeyF1:
- case kKeyF2:
- case kKeyF3:
- case kKeyF4:
- case kKeyF5:
- case kKeyF6:
- case kKeyF7:
- case kKeyF8:
- case kKeyF9:
- case kKeyF10:
- case kKeyUp:
- case kKeyDown:
- return key;
-
- case kKeyEscape:
- if (_vm->_global->_useMouse != 0)
- continue;
-
- _forceHandleMouse = !_forceHandleMouse;
-
- if ((_handleMouse != 0) &&
- ((_vm->_global->_useMouse != 0) || (_forceHandleMouse != 0)))
- handleMouse = 1;
- else
- handleMouse = 0;
-
- if (_vm->_global->_pressedKeys[1] == 0)
- continue;
-
- while (_vm->_global->_pressedKeys[1] != 0)
- ;
- continue;
-
- default:
-
- savedKey = key;
- key &= 0xFF;
-
- if (((inpType == 9) || (inpType == 10)) &&
- (key >= ' ') && (key <= 0xFF)) {
- str1 = "0123456789-.,+ ";
- str2 = "0123456789-,,+ ";
-
- if (((savedKey >> 8) > 1) && ((savedKey >> 8) < 12))
- key = ((savedKey >> 8) - 1) % 10 + '0';
-
- for (i = 0; str1[i] != 0; i++) {
- if (key == str1[i]) {
- key = str2[i];
- break;
- }
- }
-
- if (i == (int16) strlen(str1))
- key = 0;
- }
-
- if ((key >= ' ') && (key <= 0xFF)) {
- if (editSize == strlen(str))
- _vm->_util->cutFromStr(str, strlen(str) - 1, 1);
-
- if ((key >= 'a') && (key <= 'z'))
- key += ('A' - 'a');
-
- pos++;
- _tempStr[0] = key;
- _tempStr[1] = 0;
-
- _vm->_util->insertStr(_tempStr, str, pos - 1);
- }
-
- }
- }
-}
-
-int16 Game_v1::checkMousePoint(int16 all, int16 *resId, int16 *resIndex) {
- Collision *ptr;
- int16 i;
-
- if (resId != 0)
- *resId = 0;
-
- *resIndex = 0;
-
- ptr = _collisionAreas;
- for (i = 0; ptr->left != 0xFFFF; ptr++, i++) {
- if (all) {
- if ((ptr->flags & 0xF) > 1)
- continue;
-
- if ((ptr->flags & 0xFF00) != 0)
- continue;
-
- if ((_vm->_global->_inter_mouseX < ptr->left) ||
- (_vm->_global->_inter_mouseX > ptr->right) ||
- (_vm->_global->_inter_mouseY < ptr->top) ||
- (_vm->_global->_inter_mouseY > ptr->bottom))
- continue;
-
- if (resId != 0)
- *resId = ptr->id;
-
- *resIndex = i;
- return ptr->key;
- } else {
- if ((ptr->flags & 0xFF00) != 0)
- continue;
-
- if (((ptr->flags & 0xF) != 1) && ((ptr->flags & 0xF) != 2))
- continue;
-
- if ((((ptr->flags & 0xF0) >> 4) != (((int32) _mouseButtons) - 1))
- && (((ptr->flags & 0xF0) >> 4) != 2))
- continue;
-
- if ((_vm->_global->_inter_mouseX < ptr->left) ||
- (_vm->_global->_inter_mouseX > ptr->right) ||
- (_vm->_global->_inter_mouseY < ptr->top) ||
- (_vm->_global->_inter_mouseY > ptr->bottom))
- continue;
-
- if (resId != 0)
- *resId = ptr->id;
- *resIndex = i;
- return ptr->key;
- }
- }
-
- if ((_mouseButtons != kMouseButtonsLeft) && (all == 0))
- return kKeyEscape;
-
- return 0;
-}
-
} // End of namespace Gob
diff --git a/engines/gob/game_v2.cpp b/engines/gob/game_v2.cpp
index db4e87287f..9cc4da3cc9 100644
--- a/engines/gob/game_v2.cpp
+++ b/engines/gob/game_v2.cpp
@@ -179,268 +179,7 @@ void Game_v2::playTot(int16 skipPlay) {
_script->pop();
}
-void Game_v2::clearCollisions() {
- _lastCollKey = 0;
-
- for (int i = 0; i < 150; i++)
- _collisionAreas[i].left = 0xFFFF;
-}
-
-int16 Game_v2::addNewCollision(int16 id, uint16 left, uint16 top,
- uint16 right, uint16 bottom, int16 flags, int16 key,
- uint16 funcEnter, uint16 funcLeave, uint16 funcSub) {
- Collision *ptr;
-
- debugC(5, kDebugCollisions, "addNewCollision");
- debugC(5, kDebugCollisions, "id = %X", id);
- debugC(5, kDebugCollisions, "left = %d, top = %d, right = %d, bottom = %d",
- left, top, right, bottom);
- debugC(5, kDebugCollisions, "flags = %X, key = %X", flags, key);
- debugC(5, kDebugCollisions, "funcEnter = %d, funcLeave = %d",
- funcEnter, funcLeave);
-
- for (int i = 0; i < 150; i++) {
- if ((_collisionAreas[i].left != 0xFFFF) && (_collisionAreas[i].id != id))
- continue;
-
- ptr = &_collisionAreas[i];
- ptr->id = id;
- ptr->left = left;
- ptr->top = top;
- ptr->right = right;
- ptr->bottom = bottom;
- ptr->flags = flags;
- ptr->key = key;
- ptr->funcEnter = funcEnter;
- ptr->funcLeave = funcLeave;
- ptr->funcSub = funcSub;
- ptr->script = 0;
-
- return i;
- }
- error("Game_v2::addNewCollision(): Collision array full");
- return 0;
-}
-
-void Game_v2::pushCollisions(char all) {
- Collision *srcPtr;
- Collision *destPtr;
- int16 size;
-
- debugC(1, kDebugCollisions, "pushCollisions");
- for (size = 0, srcPtr = _collisionAreas; srcPtr->left != 0xFFFF; srcPtr++)
- if (all || (((uint16) srcPtr->id) >= 20))
- size++;
-
- destPtr = new Collision[size];
- _collStack[_collStackSize] = destPtr;
-
- if (_vm->_inter->_terminate)
- return;
-
- _collStackElemSizes[_collStackSize] = size;
-
- if (_shouldPushColls != 0)
- _collStackElemSizes[_collStackSize] |= 0x8000;
-
- _shouldPushColls = 0;
- _collLasts[_collStackSize].key = _lastCollKey;
- _collLasts[_collStackSize].id = _lastCollId;
- _collLasts[_collStackSize].areaIndex = _lastCollAreaIndex;
- _lastCollKey = 0;
- _lastCollId = 0;
- _lastCollAreaIndex = 0;
- _collStackSize++;
-
- for (srcPtr = _collisionAreas; srcPtr->left != 0xFFFF; srcPtr++) {
- if (all || (((uint16) srcPtr->id) >= 20)) {
- memcpy(destPtr, srcPtr, sizeof(Collision));
- srcPtr->left = 0xFFFF;
- destPtr++;
- }
- }
-}
-
-void Game_v2::popCollisions(void) {
- Collision *destPtr;
- Collision *srcPtr;
-
- debugC(1, kDebugCollisions, "popCollision");
-
- _collStackSize--;
-
- _shouldPushColls = _collStackElemSizes[_collStackSize] & 0x8000 ? 1 : 0;
- _collStackElemSizes[_collStackSize] &= 0x7FFF;
-
- _lastCollKey = _collLasts[_collStackSize].key;
- _lastCollId = _collLasts[_collStackSize].id;
- _lastCollAreaIndex = _collLasts[_collStackSize].areaIndex;
-
- for (destPtr = _collisionAreas; destPtr->left != 0xFFFF; destPtr++)
- ;
-
- srcPtr = _collStack[_collStackSize];
- memcpy(destPtr, srcPtr,
- _collStackElemSizes[_collStackSize] * sizeof(Collision));
-
- delete[] _collStack[_collStackSize];
-}
-
-int16 Game_v2::checkCollisions(byte handleMouse, int16 deltaTime, int16 *pResId,
- int16 *pResIndex) {
- int16 resIndex;
- int16 key;
- int16 oldIndex;
- int16 oldId;
- int16 newkey;
- uint32 timeKey;
-
- _scrollHandleMouse = handleMouse != 0;
-
- if (deltaTime >= -1) {
- _lastCollKey = 0;
- _lastCollAreaIndex = 0;
- _lastCollId = 0;
- }
-
- if (pResId != 0)
- *pResId = 0;
-
- resIndex = 0;
-
- if ((_vm->_draw->_cursorIndex == -1) &&
- (handleMouse != 0) && (_lastCollKey == 0)) {
- _lastCollKey = checkMousePoint(1, &_lastCollId, &_lastCollAreaIndex);
-
- if ((_lastCollKey != 0) && (_lastCollId & 0x8000))
- collAreaSub(_lastCollAreaIndex, 1);
- }
-
- if (handleMouse != 0)
- _vm->_draw->animateCursor(-1);
-
- timeKey = _vm->_util->getTimeKey();
- while (1) {
- if (_vm->_inter->_terminate || _vm->shouldQuit()) {
- if (handleMouse)
- _vm->_draw->blitCursor();
- return 0;
- }
-
- if (!_vm->_draw->_noInvalidated) {
- if (handleMouse != 0)
- _vm->_draw->animateCursor(-1);
- else
- _vm->_draw->blitInvalidated();
- _vm->_video->waitRetrace();
- }
-
- key = checkKeys(&_vm->_global->_inter_mouseX,
- &_vm->_global->_inter_mouseY, &_mouseButtons, handleMouse);
-
- if ((handleMouse == 0) && (_mouseButtons != kMouseButtonsNone)) {
- _vm->_util->waitMouseRelease(0);
- key = 3;
- }
-
- if (key != 0) {
-
- if (handleMouse & 1)
- _vm->_draw->blitCursor();
-
- if (pResId != 0)
- *pResId = 0;
-
- if (pResIndex != 0)
- *pResIndex = 0;
-
- if (_lastCollKey != 0)
- collAreaSub(_lastCollAreaIndex, 0);
-
- _lastCollKey = 0;
- if (key != 0)
- return key;
- }
-
- if (handleMouse != 0) {
- if (_mouseButtons != kMouseButtonsNone) {
- if (deltaTime > 0) {
- _vm->_draw->animateCursor(2);
- _vm->_util->delay(deltaTime);
- } else if (handleMouse & 1)
- _vm->_util->waitMouseRelease(1);
- _vm->_draw->animateCursor(-1);
-
- if (pResId != 0)
- *pResId = 0;
-
- key = checkMousePoint(0, pResId, &resIndex);
- if (pResIndex != 0)
- *pResIndex = resIndex;
-
- if ((key != 0) || ((pResId != 0) && (*pResId != 0))) {
- if ((handleMouse & 1) &&
- ((deltaTime <= 0) || (_mouseButtons == kMouseButtonsNone)))
- _vm->_draw->blitCursor();
-
- if ((_lastCollKey != 0) && (key != _lastCollKey))
- collAreaSub(_lastCollAreaIndex, 0);
-
- _lastCollKey = 0;
- return key;
- }
-
- if (handleMouse & 4)
- return 0;
-
- if (_lastCollKey != 0)
- collAreaSub(_lastCollAreaIndex, 0);
-
- _lastCollKey = checkMousePoint(1, &_lastCollId, &_lastCollAreaIndex);
- if ((_lastCollKey != 0) && (_lastCollId & 0x8000))
- collAreaSub(_lastCollAreaIndex, 1);
- } else if ((_vm->_global->_inter_mouseX != _vm->_draw->_cursorX) ||
- (_vm->_global->_inter_mouseY != _vm->_draw->_cursorY)) {
-
- oldIndex = _lastCollAreaIndex;
- oldId = _lastCollId;
- newkey = checkMousePoint(1, &_lastCollId, &_lastCollAreaIndex);
-
- if (newkey != _lastCollKey) {
- if ((_lastCollKey != 0) && (oldId & 0x8000))
- collAreaSub(oldIndex, 0);
-
- _lastCollKey = newkey;
-
- if ((newkey != 0) && (_lastCollId & 0x8000))
- collAreaSub(_lastCollAreaIndex, 1);
- }
- }
- }
-
- if ((deltaTime < 0) && (key == 0) && (_mouseButtons == kMouseButtonsNone)) {
- uint32 curtime = _vm->_util->getTimeKey();
- if ((curtime + deltaTime) > timeKey) {
- if (pResId != 0)
- *pResId = 0;
-
- if (pResIndex != 0)
- *pResIndex = 0;
-
- return 0;
- }
- }
-
- if (handleMouse != 0)
- _vm->_draw->animateCursor(-1);
-
- _vm->_util->delay(10);
- }
-}
-
void Game_v2::prepareStart(void) {
- clearCollisions();
-
_vm->_global->_pPaletteDesc->unused2 = _vm->_draw->_unusedPalette2;
_vm->_global->_pPaletteDesc->unused1 = _vm->_draw->_unusedPalette1;
_vm->_global->_pPaletteDesc->vgaPal = _vm->_draw->_vgaPalette;
@@ -476,1087 +215,4 @@ void Game_v2::prepareStart(void) {
_startTimeKey = _vm->_util->getTimeKey();
}
-void Game_v2::collisionsBlock(void) {
- InputDesc descArray[20];
- int16 array[250];
- byte count;
- int16 collResId;
- int16 curCmd;
- int16 cmd;
- int16 cmdHigh;
- int16 key;
- int16 flags;
- uint16 left;
- uint16 top;
- uint16 width;
- uint16 height;
- int16 var_1C;
- int16 index;
- int16 curEditIndex;
- int16 deltaTime;
- int16 stackPos2;
- int16 descIndex;
- int16 timeVal;
- char *str;
- int16 i;
- int16 counter;
- int16 var_24;
- int16 var_26;
- int16 collStackPos;
- Collision *collPtr;
- Collision *collArea;
- int16 timeKey;
- byte collAreaStart;
- uint32 startPos;
- uint32 offsetPos;
-
- if (_shouldPushColls)
- pushCollisions(0);
-
- collAreaStart = 0;
- while (_collisionAreas[collAreaStart].left != 0xFFFF)
- collAreaStart++;
- collArea = &_collisionAreas[collAreaStart];
-
- _shouldPushColls = 0;
- collResId = -1;
-
- _script->skip(1);
- count = _script->readByte();
-
- _handleMouse = _script->readByte();
- deltaTime = 1000 * _script->readByte();
- _script->skip(1);
- stackPos2 = _script->readByte();
- descIndex = _script->readByte();
-
- if ((stackPos2 != 0) || (descIndex != 0))
- deltaTime /= 100;
-
- timeVal = deltaTime;
- _script->skip(1);
-
- startPos = _script->pos();
- WRITE_VAR(16, 0);
-
- var_1C = 0;
- index = 0;
- curEditIndex = 0;
-
- for (curCmd = 0; curCmd < count; curCmd++) {
- array[curCmd] = 0;
- cmd = _script->readByte();
-
- if ((cmd & 0x40) != 0) {
- cmd -= 0x40;
- cmdHigh = _script->readByte();
- cmdHigh <<= 8;
- } else
- cmdHigh = 0;
-
- if ((cmd & 0x80) != 0) {
- offsetPos = _script->pos();
- left = _script->readValExpr();
- top = _script->readValExpr();
- width = _script->readValExpr();
- height = _script->readValExpr();
- } else {
- offsetPos = 0;
- left = _script->readUint16();
- top = _script->readUint16();
- width = _script->readUint16();
- height = _script->readUint16();
- }
-
- if ((_vm->_draw->_renderFlags & RENDERFLAG_CAPTUREPOP) && (left != 0xFFFF)) {
- left += _vm->_draw->_backDeltaX;
- top += _vm->_draw->_backDeltaY;
- }
-
- if (left != 0xFFFF) {
- _vm->_draw->adjustCoords(0, &left, &top);
- if (((cmd & 0x3F) < 20) && ((cmd & 0x3F) >= 3)) {
- if (_vm->_draw->_needAdjust != 2)
- height &= 0xFFFE;
- _vm->_draw->adjustCoords(0, 0, &width);
- } else
- _vm->_draw->adjustCoords(0, &height, &width);
- }
-
- cmd &= 0x7F;
- debugC(1, kDebugCollisions, "collisionsBlock(%d)", cmd);
-
- switch (cmd) {
- case 0:
- _script->skip(6);
- startPos = _script->pos();
- _script->skip(_script->peekUint16(2) + 2);
- key = curCmd + 0xA000;
-
- addNewCollision(curCmd + 0x8000, left, top,
- left + width - 1, top + height - 1,
- cmd + cmdHigh, key, startPos,
- _script->pos(), offsetPos);
-
- _script->skip(_script->peekUint16(2) + 2);
-
- break;
-
- case 1:
- key = _script->readInt16();
- array[curCmd] = _script->readInt16();
- flags = _script->readInt16();
-
- startPos = _script->pos();
- _script->skip(_script->peekUint16(2) + 2);
-
- if (key == 0)
- key = curCmd + 0xA000;
-
- addNewCollision(curCmd + 0x8000, left, top,
- left + width - 1, top + height - 1,
- (flags << 4) + cmd + cmdHigh, key, startPos,
- _script->pos(), offsetPos);
-
- _script->skip(_script->peekUint16(2) + 2);
- break;
-
- case 3:
- case 4:
- case 5:
- case 6:
- case 7:
- case 8:
- case 9:
- case 10:
- _vm->_util->clearKeyBuf();
- var_1C = 1;
- key = _script->readVarIndex();
- descArray[index].fontIndex = _script->readInt16();
- descArray[index].backColor = _script->readByte();
- descArray[index].frontColor = _script->readByte();
-
- if ((cmd >= 5) && (cmd <= 8)) {
- descArray[index].ptr = _script->getData() + _script->pos() + 2;
- _script->skip(_script->peekUint16() + 2);
- } else
- descArray[index].ptr = 0;
-
- if (left == 0xFFFF) {
- if ((cmd & 1) == 0) {
- _script->skip(_script->peekUint16(2) + 2);
- }
- break;
- }
-
- if ((cmd & 1) == 0) {
- addNewCollision(curCmd + 0x8000, left, top, left + width *
- _vm->_draw->_fonts[descArray[index].fontIndex]-> itemWidth - 1,
- top + height - 1, cmd, key, 0,
- _script->pos());
-
- _script->skip(_script->peekUint16(2) + 2);
- } else
- addNewCollision(curCmd + 0x8000, left, top, left + width *
- _vm->_draw->_fonts[descArray[index].fontIndex]-> itemWidth - 1,
- top + height - 1, cmd, key, 0, 0);
-
- index++;
- break;
-
- case 11:
- _script->skip(6);
- for (i = 0; i < 150; i++) {
- if ((_collisionAreas[i].id & 0xF000) == 0xE000) {
- _collisionAreas[i].id &= 0xBFFF;
- _collisionAreas[i].funcEnter =
- _script->pos();
- _collisionAreas[i].funcLeave =
- _script->pos();
- }
- }
- _script->skip(_script->peekUint16(2) + 2);
- break;
-
- case 12:
- _script->skip(6);
- for (i = 0; i < 150; i++) {
- if ((_collisionAreas[i].id & 0xF000) == 0xD000) {
- _collisionAreas[i].id &= 0xBFFF;
- _collisionAreas[i].funcEnter =
- _script->pos();
- _collisionAreas[i].funcLeave =
- _script->pos();
- }
- }
- _script->skip(_script->peekUint16(2) + 2);
- break;
-
- case 20:
- collResId = curCmd;
- // Fall through to case 2
-
- case 2:
- key = _script->readInt16();
- array[curCmd] = _script->readInt16();
- flags = _script->readInt16();
-
- addNewCollision(curCmd + 0x8000, left, top,
- left + width - 1, top + height - 1,
- (flags << 4) + cmdHigh + 2, key, 0,
- _script->pos(), offsetPos);
-
- _script->skip(_script->peekUint16(2) + 2);
-
- break;
-
- case 21:
- key = _script->readInt16();
- array[curCmd] = _script->readInt16();
- flags = _script->readInt16() & 3;
-
- addNewCollision(curCmd + 0x8000, left, top,
- left + width - 1, top + height - 1,
- (flags << 4) + cmdHigh + 2, key,
- _script->pos(), 0, offsetPos);
-
- _script->skip(_script->peekUint16(2) + 2);
-
- break;
- }
- }
-
- _forceHandleMouse = 0;
- _vm->_util->clearKeyBuf();
-
- do {
- if (var_1C != 0) {
- key = multiEdit(deltaTime, index, &curEditIndex, descArray,
- &_activeCollResId, &_activeCollIndex);
-
- WRITE_VAR(55, curEditIndex);
- if (key == kKeyReturn) {
- for (i = 0; i < 150; i++) {
- if (_collisionAreas[i].left == 0xFFFF)
- break;
-
- if ((_collisionAreas[i].id & 0xC000) != 0x8000)
- continue;
-
- if ((_collisionAreas[i].flags & 1) != 0)
- continue;
-
- if ((_collisionAreas[i].flags & 0x0F) <= 2)
- continue;
-
- _activeCollResId = _collisionAreas[i].id;
- collResId = _collisionAreas[i].id & 0x7FFF;
- _activeCollIndex = i;
- break;
- }
- break;
- }
- } else
- key = checkCollisions(_handleMouse, -deltaTime,
- &_activeCollResId, &_activeCollIndex);
-
- if (((key & 0xFF) >= ' ') && ((key & 0xFF) <= 0xFF) &&
- ((key >> 8) > 1) && ((key >> 8) < 12))
- key = '0' + (((key >> 8) - 1) % 10) + (key & 0xFF00);
-
- if (_activeCollResId == 0) {
- if (key != 0) {
- for (i = 0; i < 150; i++) {
- if (_collisionAreas[i].left == 0xFFFF)
- break;
-
- if ((_collisionAreas[i].id & 0xC000) != 0x8000)
- continue;
-
- if ((_collisionAreas[i].key == key) ||
- (_collisionAreas[i].key == 0x7FFF)) {
- _activeCollResId = _collisionAreas[i].id;
- _activeCollIndex = i;
- break;
- }
- }
-
- if (_activeCollResId == 0) {
- for (i = 0; i < 150; i++) {
- if (_collisionAreas[i].left == 0xFFFF)
- break;
-
- if ((_collisionAreas[i].id & 0xC000) != 0x8000)
- continue;
-
- if ((_collisionAreas[i].key & 0xFF00) != 0)
- continue;
-
- if (_collisionAreas[i].key == 0)
- continue;
-
- if ((adjustKey(key & 0xFF) == adjustKey(_collisionAreas[i].key)) ||
- (_collisionAreas[i].key == 0x7FFF)) {
- _activeCollResId = _collisionAreas[i].id;
- _activeCollIndex = i;
- break;
- }
- }
- }
- } else if (deltaTime != 0) {
- if (stackPos2 != 0) {
- collStackPos = 0;
-
- for (i = 0, collPtr = collArea; collPtr->left != 0xFFFF; i++, collPtr++) {
- if ((collPtr->id & 0xF000) != 0x8000)
- continue;
-
- collStackPos++;
- if (collStackPos != stackPos2)
- continue;
-
- _activeCollResId = collPtr->id;
- _activeCollIndex = i + collAreaStart;
- _vm->_inter->storeMouse();
- if (VAR(16) != 0)
- break;
-
- if ((_activeCollResId & 0xF000) == 0x8000)
- WRITE_VAR(16, array[_activeCollResId & 0xFFF]);
- else
- WRITE_VAR(16, _activeCollResId & 0xFFF);
-
- if (collPtr->funcLeave != 0) {
- int16 collResIdBak = _activeCollResId;
- int16 collIndexBak = _activeCollIndex;
-
- timeKey = _vm->_util->getTimeKey();
- collSub(collPtr->funcLeave);
-
- _activeCollResId = collResIdBak;
- _activeCollIndex = collIndexBak;
-
- _vm->_inter->animPalette();
-
- deltaTime = timeVal - (_vm->_util->getTimeKey() - timeKey);
-
- if (deltaTime < 2)
- deltaTime = 2;
- if (deltaTime > timeVal)
- deltaTime = timeVal;
- }
-
- if (VAR(16) == 0)
- _activeCollResId = 0;
- break;
- }
- } else {
- if (descIndex != 0) {
-
- counter = 0;
- for (i = 0, collPtr = collArea; collPtr->left != 0xFFFF; i++, collPtr++) {
- if ((collPtr->id & 0xF000) == 0x8000)
- if (++counter == descIndex) {
- _activeCollResId = collPtr->id;
- _activeCollIndex = i + collAreaStart;
- break;
- }
- }
-
- } else {
-
- for (i = 0, collPtr = _collisionAreas; collPtr->left != 0xFFFF; i++, collPtr++) {
- if ((collPtr->id & 0xF000) == 0x8000) {
- _activeCollResId = collPtr->id;
- _activeCollIndex = i;
- break;
- }
- }
- if ((_lastCollKey != 0) &&
- (_collisionAreas[_lastCollAreaIndex].funcLeave != 0))
- collSub(_collisionAreas[_lastCollAreaIndex].funcLeave);
- _lastCollKey = 0;
- }
-
- }
- }
- }
-
- if ((_activeCollResId == 0) ||
- (_collisionAreas[_activeCollIndex].funcLeave != 0))
- continue;
-
- _vm->_inter->storeMouse();
- if ((_activeCollResId & 0xF000) == 0x8000)
- WRITE_VAR(16, array[_activeCollResId & 0xFFF]);
- else
- WRITE_VAR(16, _activeCollResId & 0xFFF);
-
- if (_collisionAreas[_activeCollIndex].funcEnter != 0)
- collSub(_collisionAreas[_activeCollIndex].funcEnter);
-
- WRITE_VAR(16, 0);
- _activeCollResId = 0;
- }
- while ((_activeCollResId == 0) && !_vm->_inter->_terminate && !_vm->shouldQuit());
-
- if ((_activeCollResId & 0xFFF) == collResId) {
- collStackPos = 0;
- var_24 = 0;
- var_26 = 1;
- for (i = 0; i < 150; i++) {
- if (_collisionAreas[i].left == 0xFFFF)
- continue;
-
- if ((_collisionAreas[i].id & 0xC000) == 0x8000)
- continue;
-
- if ((_collisionAreas[i].flags & 0x0F) < 3)
- continue;
-
- if ((_collisionAreas[i].flags & 0x0F) > 10)
- continue;
-
- if ((_collisionAreas[i].flags & 0x0F) > 8) {
- char *ptr;
- strncpy0(_tempStr, GET_VARO_STR(_collisionAreas[i].key), 255);
- while ((ptr = strchr(_tempStr, ' ')))
- _vm->_util->cutFromStr(_tempStr, (ptr - _tempStr), 1);
- if (_vm->_language == 2)
- while ((ptr = strchr(_tempStr, '.')))
- *ptr = ',';
- WRITE_VARO_STR(_collisionAreas[i].key, _tempStr);
- }
-
- if (((_collisionAreas[i].flags & 0x0F) >= 5) &&
- ((_collisionAreas[i].flags & 0x0F) <= 8)) {
- str = (char *) descArray[var_24].ptr;
-
- strncpy0(_tempStr, GET_VARO_STR(_collisionAreas[i].key), 255);
-
- if ((_collisionAreas[i].flags & 0x0F) < 7)
- _vm->_util->cleanupStr(_tempStr);
-
- int16 pos = 0;
- do {
- strncpy0(_collStr, str, 255);
- pos += strlen(str) + 1;
-
- str += strlen(str) + 1;
-
- if ((_collisionAreas[i].flags & 0x0F) < 7)
- _vm->_util->cleanupStr(_collStr);
-
- if (strcmp(_tempStr, _collStr) == 0) {
- WRITE_VAR(17, VAR(17) + 1);
- WRITE_VAR(17 + var_26, 1);
- break;
- }
- } while (READ_LE_UINT16(descArray[var_24].ptr - 2) > pos);
- collStackPos++;
- } else {
- WRITE_VAR(17 + var_26, 2);
- }
- var_24++;
- var_26++;
- }
-
- if (collStackPos != (int16) VAR(17))
- WRITE_VAR(17, 0);
- else
- WRITE_VAR(17, 1);
- }
-
- if (_handleMouse == 1)
- _vm->_draw->blitCursor();
-
- if (!_vm->_inter->_terminate) {
- _script->seek(_collisionAreas[_activeCollIndex].funcLeave);
-
- _vm->_inter->storeMouse();
- if (VAR(16) == 0) {
- if ((_activeCollResId & 0xF000) == 0x8000)
- WRITE_VAR(16, array[_activeCollResId & 0xFFF]);
- else
- WRITE_VAR(16, _activeCollResId & 0xFFF);
- }
- } else
- _script->setFinished(true);
-
- for (curCmd = 0; curCmd < count; curCmd++)
- freeCollision(curCmd + 0x8000);
-
- for (i = 0; i < 150; i++) {
- if (((_collisionAreas[i].id & 0xF000) == 0xA000) ||
- ((_collisionAreas[i].id & 0xF000) == 0x9000))
- _collisionAreas[i].id |= 0x4000;
- }
-}
-
-int16 Game_v2::multiEdit(int16 time, int16 index, int16 *pCurPos,
- InputDesc * inpDesc, int16 *collResId, int16 *collIndex, bool mono) {
- Collision *collArea;
- int16 descInd;
- int16 key;
- int16 found = -1;
- int16 i;
- byte *fontExtraBak = 0;
- int16 needAdjust = 0;
-
- descInd = 0;
- for (i = 0; i < 150; i++) {
- collArea = &_collisionAreas[i];
-
- if (collArea->left == 0xFFFF)
- continue;
-
- if ((collArea->id & 0xC000) != 0x8000)
- continue;
-
- if ((collArea->flags & 0x0F) < 3)
- continue;
-
- if ((collArea->flags & 0x0F) > 10)
- continue;
-
- strncpy0(_tempStr, GET_VARO_STR(collArea->key), 255);
-
- _vm->_draw->_destSpriteX = collArea->left;
- _vm->_draw->_destSpriteY = collArea->top;
- _vm->_draw->_spriteRight = collArea->right - collArea->left + 1;
- _vm->_draw->_spriteBottom = collArea->bottom - collArea->top + 1;
-
- _vm->_draw->_destSurface = 21;
-
- _vm->_draw->_backColor = inpDesc[descInd].backColor;
- _vm->_draw->_frontColor = inpDesc[descInd].frontColor;
- _vm->_draw->_textToPrint = _tempStr;
- _vm->_draw->_transparency = 1;
- _vm->_draw->_fontIndex = inpDesc[descInd].fontIndex;
-
- if (mono) {
- fontExtraBak = _vm->_draw->_fonts[_vm->_draw->_fontIndex]->extraData;
- needAdjust = _vm->_draw->_needAdjust;
- _vm->_draw->_needAdjust = 2;
- _vm->_draw->_fonts[_vm->_draw->_fontIndex]->extraData = 0;
- }
-
- _vm->_draw->spriteOperation(DRAW_FILLRECT | 0x10);
-
- _vm->_draw->_destSpriteY += ((collArea->bottom - collArea->top + 1) -
- _vm->_draw->_fonts[_vm->_draw->_fontIndex]->itemHeight) / 2;
- _vm->_draw->spriteOperation(DRAW_PRINTTEXT | 0x10);
-
- if (mono) {
- _vm->_draw->_needAdjust = needAdjust;
- _vm->_draw->_fonts[_vm->_draw->_fontIndex]->extraData = fontExtraBak;
- }
-
- descInd++;
- }
-
- for (i = 0; i < 40; i++)
- WRITE_VAR_OFFSET(i * 4 + 0x44, 0);
-
- while (1) {
- descInd = 0;
-
- for (i = 0; i < 150; i++) {
- collArea = &_collisionAreas[i];
-
- if (collArea->left == 0xFFFF)
- continue;
-
- if ((collArea->id & 0xC000) != 0x8000)
- continue;
-
- if ((collArea->flags & 0x0F) < 3)
- continue;
-
- if ((collArea->flags & 0x0F) > 10)
- continue;
-
- if (descInd == *pCurPos) {
- found = i;
- break;
- }
-
- descInd++;
- }
-
- assert(found != -1);
-
- collArea = &_collisionAreas[found];
-
- key = inputArea(collArea->left, collArea->top,
- collArea->right - collArea->left + 1,
- collArea->bottom - collArea->top + 1,
- inpDesc[*pCurPos].backColor, inpDesc[*pCurPos].frontColor,
- GET_VARO_STR(collArea->key), inpDesc[*pCurPos].fontIndex,
- collArea->flags, &time, collResId, collIndex, mono);
-
- if (_vm->_inter->_terminate)
- return 0;
-
- switch (key) {
- case kKeyNone:
- if (*collResId == 0)
- return 0;
-
- if (_mouseButtons != kMouseButtonsNone) {
- for (collArea = _collisionAreas, i = 0;
- collArea->left != 0xFFFF; collArea++, i++) {
- if ((collArea->flags & 0xF00))
- continue;
-
- if ((collArea->id & 0x4000))
- continue;
-
- if ((collArea->left > _vm->_global->_inter_mouseX) ||
- (collArea->right < _vm->_global->_inter_mouseX) ||
- (collArea->top > _vm->_global->_inter_mouseY) ||
- (collArea->bottom < _vm->_global->_inter_mouseY))
- continue;
-
- if ((collArea->id & 0xF000))
- continue;
-
- if ((collArea->flags & 0x0F) < 3)
- continue;
-
- if ((collArea->flags & 0x0F) > 10)
- continue;
-
- *collIndex = i;
- }
- }
-
- if ((_collisionAreas[*collIndex].flags & 0x0F) < 3)
- return 0;
-
- if ((_collisionAreas[*collIndex].flags & 0x0F) > 10)
- return 0;
-
- *pCurPos = 0;
- for (i = 0; i < 150; i++) {
- collArea = &_collisionAreas[i];
-
- if (collArea->left == 0xFFFF)
- continue;
-
- if ((collArea->id & 0xC000) != 0x8000)
- continue;
-
- if ((collArea->flags & 0x0F) < 3)
- continue;
-
- if ((collArea->flags & 0x0F) > 10)
- continue;
-
- if (i != *collIndex)
- pCurPos[0]++;
- }
- break;
-
- case kKeyF1:
- case kKeyF2:
- case kKeyF3:
- case kKeyF4:
- case kKeyF5:
- case kKeyF6:
- case kKeyF7:
- case kKeyF8:
- case kKeyF9:
- case kKeyF10:
- return key;
-
- case kKeyReturn:
-
- if (index == 1)
- return key;
-
- if (*pCurPos == index - 1) {
- *pCurPos = 0;
- break;
- }
-
- pCurPos[0]++;
- break;
-
- case kKeyDown:
- if (index - 1 > *pCurPos)
- pCurPos[0]++;
- break;
-
- case kKeyUp:
- if (*pCurPos > 0)
- pCurPos[0]--;
- break;
- }
- }
-}
-
-int16 Game_v2::inputArea(int16 xPos, int16 yPos, int16 width, int16 height,
- int16 backColor, int16 frontColor, char *str, int16 fontIndex,
- char inpType, int16 *pTotTime, int16 *collResId, int16 *collIndex, bool mono) {
- byte handleMouse;
- uint32 editSize;
- Video::FontDesc *pFont;
- char curSym;
- int16 key;
- const char *str1;
- const char *str2;
- int16 i;
- uint32 pos;
- int16 flag;
- int16 savedKey;
- byte *fontExtraBak = 0;
- int16 needAdjust = 0;
-
- if ((_handleMouse != 0) &&
- ((_vm->_global->_useMouse != 0) || (_forceHandleMouse != 0)))
- handleMouse = 1;
- else
- handleMouse = 0;
-
- pos = strlen(str);
- pFont = _vm->_draw->_fonts[fontIndex];
- editSize = (!mono && pFont->extraData) ? 0 : (width / pFont->itemWidth);
-
- while (1) {
- strncpy0(_tempStr, str, 254);
- strcat(_tempStr, " ");
- if ((editSize != 0) && strlen(_tempStr) > editSize)
- strncpy0(_tempStr, str, 255);
-
- if (mono) {
- fontExtraBak = _vm->_draw->_fonts[fontIndex]->extraData;
- needAdjust = _vm->_draw->_needAdjust;
- _vm->_draw->_needAdjust = 2;
- _vm->_draw->_fonts[fontIndex]->extraData = 0;
- }
-
- _vm->_draw->_destSpriteX = xPos;
- _vm->_draw->_destSpriteY = yPos;
- _vm->_draw->_spriteRight = mono ? (editSize * pFont->itemWidth) : width;
- _vm->_draw->_spriteBottom = height;
-
- _vm->_draw->_destSurface = 21;
- _vm->_draw->_backColor = backColor;
- _vm->_draw->_frontColor = frontColor;
- _vm->_draw->_textToPrint = _tempStr;
- _vm->_draw->_transparency = 1;
- _vm->_draw->_fontIndex = fontIndex;
- _vm->_draw->spriteOperation(DRAW_FILLRECT | 0x10 );
-
- _vm->_draw->_destSpriteY = yPos + (height - pFont->itemHeight) / 2;
- _vm->_draw->spriteOperation(DRAW_PRINTTEXT | 0x10);
-
- if (mono) {
- _vm->_draw->_needAdjust = needAdjust;
- _vm->_draw->_fonts[fontIndex]->extraData = fontExtraBak;
- }
-
- if ((editSize != 0) && (pos == editSize))
- pos--;
-
- curSym = _tempStr[pos];
-
- flag = 1;
-
- if (_vm->_inter->_variables)
- WRITE_VAR(56, pos);
-
- while (1) {
- if (mono) {
- fontExtraBak = _vm->_draw->_fonts[fontIndex]->extraData;
- needAdjust = _vm->_draw->_needAdjust;
- _vm->_draw->_needAdjust = 2;
- _vm->_draw->_fonts[fontIndex]->extraData = 0;
- }
-
- _tempStr[0] = curSym;
- _tempStr[1] = 0;
-
- if (pFont->extraData) {
- _vm->_draw->_destSpriteY = yPos;
- _vm->_draw->_spriteBottom = height;
- _vm->_draw->_spriteRight = 1;
-
- _vm->_draw->_destSpriteX = xPos;
- for (uint32 j = 0; j < pos; j++)
- _vm->_draw->_destSpriteX += pFont->extraData[str[j] - pFont->startItem];
-
- } else {
- _vm->_draw->_destSpriteX = xPos + pFont->itemWidth * pos;
- _vm->_draw->_destSpriteY = yPos + height - 1;
- _vm->_draw->_spriteRight = pFont->itemWidth;
- _vm->_draw->_spriteBottom = 1;
- }
-
- _vm->_draw->_destSurface = 21;
- _vm->_draw->_backColor = frontColor;
- _vm->_draw->spriteOperation(DRAW_FILLRECT | 0x10);
-
- if (mono) {
- _vm->_draw->_needAdjust = needAdjust;
- _vm->_draw->_fonts[fontIndex]->extraData = fontExtraBak;
- }
-
- if (flag != 0) {
- key = checkCollisions(handleMouse, -1, collResId, collIndex);
- if (key == 0)
- key = checkCollisions(handleMouse, -300, collResId, collIndex);
- flag = 0;
- } else
- key = checkCollisions(handleMouse, -300, collResId, collIndex);
-
- if (mono) {
- fontExtraBak = _vm->_draw->_fonts[fontIndex]->extraData;
- needAdjust = _vm->_draw->_needAdjust;
- _vm->_draw->_needAdjust = 2;
- _vm->_draw->_fonts[fontIndex]->extraData = 0;
- }
-
- _tempStr[0] = curSym;
- _tempStr[1] = 0;
-
- if (pFont->extraData) {
- _vm->_draw->_destSpriteY = yPos;
- _vm->_draw->_spriteBottom = height;
- _vm->_draw->_spriteRight = 1;
-
- _vm->_draw->_destSpriteX = xPos;
- for (uint32 j = 0; j < pos; j++)
- _vm->_draw->_destSpriteX += pFont->extraData[str[j] - pFont->startItem];
-
- } else {
- _vm->_draw->_destSpriteX = xPos + pFont->itemWidth * pos;
- _vm->_draw->_destSpriteY = yPos + height - 1;
- _vm->_draw->_spriteRight = pFont->itemWidth;
- _vm->_draw->_spriteBottom = 1;
- }
-
- _vm->_draw->_destSurface = 21;
- _vm->_draw->_backColor = backColor;
- _vm->_draw->_frontColor = frontColor;
- _vm->_draw->_textToPrint = _tempStr;
- _vm->_draw->_transparency = 1;
- _vm->_draw->_fontIndex = fontIndex;
- _vm->_draw->spriteOperation(DRAW_FILLRECT | 0x10);
-
- _vm->_draw->_destSpriteY = yPos + (height - pFont->itemHeight) / 2;
- _vm->_draw->spriteOperation(DRAW_PRINTTEXT | 0x10);
-
- if (mono) {
- _vm->_draw->_needAdjust = needAdjust;
- _vm->_draw->_fonts[fontIndex]->extraData = fontExtraBak;
- }
-
- if ((key != 0) || (*collResId != 0))
- break;
-
- key = checkCollisions(handleMouse, -300, collResId, collIndex);
-
- if ((key != 0) || (*collResId != 0) ||
- _vm->_inter->_terminate || _vm->shouldQuit())
- break;
-
- if (*pTotTime > 0) {
- *pTotTime -= 600;
- if (*pTotTime <= 1) {
- key = 0;
- *collResId = 0;
- break;
- }
- }
- }
-
- if ((key == 0) || (*collResId != 0) ||
- _vm->_inter->_terminate || _vm->shouldQuit())
- return 0;
-
- switch (key) {
- case kKeyRight:
- if ((pos > strlen(str)) || (pos > (editSize - 1)) || (editSize == 0)) {
- pos++;
- continue;
- }
- return kKeyDown;
-
- case kKeyLeft:
- if (pos > 0) {
- pos--;
- continue;
- }
- return kKeyUp;
-
- case kKeyBackspace:
- if (pos > 0) {
- _vm->_util->cutFromStr(str, pos - 1, 1);
- pos--;
- continue;
- } else {
- if (pos < strlen(str))
- _vm->_util->cutFromStr(str, pos, 1);
- }
-
- case kKeyDelete:
- if (pos >= strlen(str))
- continue;
-
- _vm->_util->cutFromStr(str, pos, 1);
- continue;
-
- case kKeyReturn:
- case kKeyF1:
- case kKeyF2:
- case kKeyF3:
- case kKeyF4:
- case kKeyF5:
- case kKeyF6:
- case kKeyF7:
- case kKeyF8:
- case kKeyF9:
- case kKeyF10:
- case kKeyUp:
- case kKeyDown:
- return key;
-
- case kKeyEscape:
- if (_vm->_global->_useMouse != 0)
- continue;
-
- _forceHandleMouse = !_forceHandleMouse;
-
- if ((_handleMouse != 0) &&
- ((_vm->_global->_useMouse != 0) || (_forceHandleMouse != 0)))
- handleMouse = 1;
- else
- handleMouse = 0;
-
- while (_vm->_global->_pressedKeys[1] != 0)
- ;
- continue;
-
- default:
-
- savedKey = key;
- key &= 0xFF;
-
- if (((inpType == 9) || (inpType == 10)) &&
- (key >= ' ') && (key <= 0xFF)) {
- str1 = "0123456789-.,+ ";
- str2 = "0123456789-,,+ ";
-
- if ((((savedKey >> 8) > 1) && ((savedKey >> 8) < 12)) &&
- ((_vm->_global->_pressedKeys[42] != 0) ||
- (_vm->_global->_pressedKeys[56] != 0)))
- key = ((savedKey >> 8) - 1) % 10 + '0';
-
- for (i = 0; str1[i] != 0; i++) {
- if (key == str1[i]) {
- key = str2[i];
- break;
- }
- }
-
- if (i == (int16) strlen(str1))
- key = 0;
- }
-
- if ((key >= ' ') && (key <= 0xFF)) {
- if (editSize == 0) {
- int length = _vm->_draw->stringLength(str, fontIndex) +
- pFont->extraData[' ' - pFont->startItem] +
- pFont->extraData[key - pFont->startItem];
-
- if (length > width)
- continue;
-
- if (((int32) strlen(str)) >= (_vm->_global->_inter_animDataSize * 4 - 1))
- continue;
-
- } else {
- if (strlen(str) > editSize)
- continue;
- else if (editSize == strlen(str))
- _vm->_util->cutFromStr(str, strlen(str) - 1, 1);
- }
-
- pos++;
- _tempStr[0] = key;
- _tempStr[1] = 0;
-
- _vm->_util->insertStr(_tempStr, str, pos - 1);
- }
-
- }
- }
-}
-
-int16 Game_v2::checkMousePoint(int16 all, int16 *resId, int16 *resIndex) {
- Collision *ptr;
- int16 i;
-
- if (resId != 0)
- *resId = 0;
-
- *resIndex = 0;
-
- ptr = _collisionAreas;
- for (i = 0; ptr->left != 0xFFFF; ptr++, i++) {
- if (ptr->id & 0x4000)
- continue;
-
- if (all) {
- if ((ptr->flags & 0xF) > 1)
- continue;
-
- if ((ptr->flags & 0xF00) != 0)
- continue;
-
- if ((_vm->_global->_inter_mouseX < ptr->left) ||
- (_vm->_global->_inter_mouseX > ptr->right) ||
- (_vm->_global->_inter_mouseY < ptr->top) ||
- (_vm->_global->_inter_mouseY > ptr->bottom))
- continue;
-
- if (resId != 0)
- *resId = ptr->id;
-
- *resIndex = i;
- return ptr->key;
- } else {
- if ((ptr->flags & 0xF00) != 0)
- continue;
-
- if ((ptr->flags & 0xF) < 1)
- continue;
-
- if ((((ptr->flags & 0xF0) >> 4) != (((int32) _mouseButtons) - 1)) &&
- (((ptr->flags & 0xF0) >> 4) != 2))
- continue;
-
- if ((_vm->_global->_inter_mouseX < ptr->left) ||
- (_vm->_global->_inter_mouseX > ptr->right) ||
- (_vm->_global->_inter_mouseY < ptr->top) ||
- (_vm->_global->_inter_mouseY > ptr->bottom))
- continue;
-
- if (resId != 0)
- *resId = ptr->id;
- *resIndex = i;
- if (((ptr->flags & 0xF) == 1) || ((ptr->flags & 0xF) == 2))
- return ptr->key;
- return 0;
- }
- }
-
- if ((_mouseButtons != kMouseButtonsLeft) && (all == 0))
- return kKeyEscape;
-
- return 0;
-}
-
} // End of namespace Gob
diff --git a/engines/gob/game_v6.cpp b/engines/gob/game_v6.cpp
index 985f72c23a..e8e08578b3 100644
--- a/engines/gob/game_v6.cpp
+++ b/engines/gob/game_v6.cpp
@@ -33,13 +33,13 @@
#include "gob/global.h"
#include "gob/script.h"
#include "gob/resources.h"
+#include "gob/hotspots.h"
#include "gob/inter.h"
#include "gob/draw.h"
namespace Gob {
Game_v6::Game_v6(GobEngine *vm) : Game_v2(vm) {
- _someTimeDly = 0;
}
// flagbits: 5 = freeInterVariables, 6 = skipPlay
@@ -75,7 +75,7 @@ void Game_v6::totSub(int8 flags, const char *newTotFile) {
return;
}
- pushCollisions(0);
+ _hotspots->push(0, true);
if (flags & 6)
playTot(-1);
@@ -85,8 +85,8 @@ void Game_v6::totSub(int8 flags, const char *newTotFile) {
if (_vm->_inter->_terminate < 2)
_vm->_inter->_terminate = 0;
- clearCollisions();
- popCollisions();
+_hotspots->clear();
+_hotspots->pop();
if ((flags & 5) && _vm->_inter->_variables) {
_vm->_inter->delocateVars();
@@ -99,45 +99,6 @@ void Game_v6::totSub(int8 flags, const char *newTotFile) {
_environments->get(_numEnvironments);
}
-int16 Game_v6::addNewCollision(int16 id, uint16 left, uint16 top,
- uint16 right, uint16 bottom, int16 flags, int16 key,
- uint16 funcEnter, uint16 funcLeave, uint16 funcSub) {
- Collision *ptr;
-
- debugC(5, kDebugCollisions, "addNewCollision");
- debugC(5, kDebugCollisions, "id = %X", id);
- debugC(5, kDebugCollisions, "left = %d, top = %d, right = %d, bottom = %d",
- left, top, right, bottom);
- debugC(5, kDebugCollisions, "flags = %X, key = %X", flags, key);
- debugC(5, kDebugCollisions, "funcEnter = %d, funcLeave = %d",
- funcEnter, funcLeave);
-
- for (int i = 0; i < 150; i++) {
- if ((_collisionAreas[i].left != 0xFFFF) && (_collisionAreas[i].id != id))
- continue;
-
- ptr = &_collisionAreas[i];
-
- if ((ptr->id & 0xBFFF) != (id & 0xBFFF))
- ptr->id = id;
-
- ptr->left = left;
- ptr->top = top;
- ptr->right = right;
- ptr->bottom = bottom;
- ptr->flags = flags;
- ptr->key = key;
- ptr->funcEnter = funcEnter;
- ptr->funcLeave = funcLeave;
- ptr->funcSub = funcSub;
- ptr->script = _script;
-
- return i;
- }
- error("Game_v6::addNewCollision(): Collision array full");
- return 0;
-}
-
void Game_v6::prepareStart(void) {
_noCd = false;
@@ -149,966 +110,4 @@ void Game_v6::prepareStart(void) {
Game_v2::prepareStart();
}
-void Game_v6::pushCollisions(char all) {
- Collision *srcPtr;
- Collision *destPtr;
- int16 size;
-
- debugC(1, kDebugCollisions, "pushCollisions");
- for (size = 0, srcPtr = _collisionAreas; srcPtr->left != 0xFFFF; srcPtr++) {
- if ( (all == 1) ||
- ((all == 0) && (((uint16) srcPtr->id) >= 20)) ||
- ((all == 2) && (((srcPtr->id & 0xF000) == 0xD000) ||
- ((srcPtr->id & 0xF000) == 0x4000) ||
- ((srcPtr->id & 0xF000) == 0xE000))))
- size++;
- }
-
- if (_collStackSize >= 5)
- error("Game_v6::pushCollisions: _collStackSize == %d", _collStackSize);
-
- destPtr = new Collision[size];
- _collStack[_collStackSize] = destPtr;
-
- if (_vm->_inter->_terminate)
- return;
-
- _collStackElemSizes[_collStackSize] = size;
-
- if (_shouldPushColls != 0)
- _collStackElemSizes[_collStackSize] |= 0x8000;
-
- _shouldPushColls = 0;
- _collLasts[_collStackSize].key = _lastCollKey;
- _collLasts[_collStackSize].id = _lastCollId;
- _collLasts[_collStackSize].areaIndex = _lastCollAreaIndex;
- _lastCollKey = 0;
- _lastCollId = 0;
- _lastCollAreaIndex = 0;
- _collStackSize++;
-
- for (srcPtr = _collisionAreas; srcPtr->left != 0xFFFF; srcPtr++) {
- if ( (all == 1) ||
- ((all == 0) && (((uint16) srcPtr->id) >= 20)) ||
- ((all == 2) && (((srcPtr->id & 0xF000) == 0xD000) ||
- ((srcPtr->id & 0xF000) == 0x4000) ||
- ((srcPtr->id & 0xF000) == 0xE000)))) {
-
- memcpy(destPtr, srcPtr, sizeof(Collision));
- srcPtr->left = 0xFFFF;
- destPtr++;
- }
- }
-}
-
-int16 Game_v6::checkCollisions(byte handleMouse, int16 deltaTime, int16 *pResId,
- int16 *pResIndex) {
- int16 resIndex;
- int16 key;
- uint32 timeKey;
-
- _scrollHandleMouse = handleMouse != 0;
-
- if (deltaTime >= -1) {
- _lastCollKey = 0;
- _lastCollAreaIndex = 0;
- _lastCollId = 0;
- }
-
- if (pResId != 0)
- *pResId = 0;
-
- resIndex = 0;
-
- if ((_lastCollKey != 0) &&
- ( (_collisionAreas[_lastCollAreaIndex].id != _lastCollId) ||
- (_collisionAreas[_lastCollAreaIndex].key != _lastCollKey))) {
-
- _lastCollKey = 0;
- _lastCollAreaIndex = 0;
- _lastCollId = 0;
- }
-
- if ((_vm->_draw->_cursorIndex == -1) &&
- (handleMouse != 0) && (_lastCollKey == 0)) {
- _lastCollKey = checkMousePoint(1, &_lastCollId, &_lastCollAreaIndex);
-
- if ((_lastCollKey != 0) && (_lastCollId & 0x8000))
- collAreaSub(_lastCollAreaIndex, 1);
- }
-
- if (handleMouse != 0)
- _vm->_draw->animateCursor(-1);
-
- timeKey = _vm->_util->getTimeKey();
- _vm->_draw->blitInvalidated();
- while (1) {
- if (_vm->_inter->_terminate || _vm->shouldQuit()) {
- if (handleMouse)
- _vm->_draw->blitCursor();
- return 0;
- }
-
- collSubReenter();
- if (!_vm->_draw->_noInvalidated) {
- if (handleMouse != 0)
- _vm->_draw->animateCursor(-1);
- else
- _vm->_draw->blitInvalidated();
- _vm->_video->waitRetrace();
- }
-
- key = checkKeys(&_vm->_global->_inter_mouseX,
- &_vm->_global->_inter_mouseY, &_mouseButtons, handleMouse);
-
- if ((handleMouse == 0) && (_mouseButtons != kMouseButtonsNone)) {
- _vm->_util->waitMouseRelease(0);
- key = 3;
- }
-
- if (key != 0) {
-
- if (handleMouse & 1)
- _vm->_draw->blitCursor();
-
- if (pResId != 0)
- *pResId = 0;
-
- if (pResIndex != 0)
- *pResIndex = 0;
-
- if ((_lastCollKey != 0) && (_lastCollId & 0x8000))
- collAreaSub(_lastCollAreaIndex, 0);
-
- _lastCollKey = 0;
- if (key != 0)
- return key;
-
- if (handleMouse)
- _vm->_draw->animateCursor(-1);
- }
-
- if (handleMouse != 0) {
- if (_mouseButtons != kMouseButtonsNone) {
-
- if (deltaTime > 0) {
- _vm->_draw->animateCursor(2);
- _vm->_util->delay(deltaTime);
- } else if (handleMouse & 1)
- _vm->_util->waitMouseRelease(1);
-
- _vm->_draw->animateCursor(-1);
-
- if (pResId != 0)
- *pResId = 0;
-
- key = checkMousePoint(0, pResId, &resIndex);
- if (pResIndex != 0)
- *pResIndex = resIndex;
-
- if ((key != 0) || ((pResId != 0) && (*pResId != 0))) {
- if ((handleMouse & 1) &&
- ((deltaTime <= 0) || (_mouseButtons == kMouseButtonsNone)))
- _vm->_draw->blitCursor();
-
- if (key != _lastCollKey)
- collAreaSub(_lastCollAreaIndex, 0);
-
- _lastCollKey = 0;
- return key;
- }
-
- if (handleMouse & 4)
- return 0;
-
- if (_lastCollKey != 0)
- collAreaSub(_lastCollAreaIndex, 0);
-
- _lastCollKey = checkMousePoint(1, &_lastCollId, &_lastCollAreaIndex);
- if ((_lastCollKey != 0) && (_lastCollId & 0x8000))
- collAreaSub(_lastCollAreaIndex, 1);
- } else
- collSubReenter();
- }
-
- if ((deltaTime == -2) && (key == 0) && (_mouseButtons == kMouseButtonsNone)) {
- if (pResId != 0)
- *pResId = 0;
-
- if (pResIndex != 0)
- *pResIndex = 0;
-
- return 0;
-
- } else if (handleMouse != 0)
- _vm->_draw->animateCursor(-1);
-
- if ((deltaTime < 0) && (key == 0) && (_mouseButtons == kMouseButtonsNone)) {
- uint32 curtime = _vm->_util->getTimeKey();
- if ((curtime + deltaTime) > timeKey) {
- if (pResId != 0)
- *pResId = 0;
-
- if (pResIndex != 0)
- *pResIndex = 0;
-
- return 0;
- }
- }
-
- _vm->_util->delay(10);
- }
-}
-
-void Game_v6::collisionsBlock(void) {
- InputDesc descArray[20];
- int16 array[300];
- byte count;
- int16 collResId;
- int16 curCmd;
- int16 cmd;
- int16 cmdHigh;
- int16 key;
- int16 flags;
- uint16 left;
- uint16 top;
- uint16 width;
- uint16 height;
- int16 deltaTime;
- int16 stackPos2;
- int16 descIndex;
- int16 timeVal;
- char *str;
- int16 i;
- int16 counter;
- int16 var_24;
- int16 var_26;
- int16 collStackPos;
- Collision *collPtr;
- Collision *collArea;
- byte collAreaStart;
- int16 activeCollResId = 0;
- int16 activeCollIndex = 0;
- uint32 startPos;
- uint32 offsetPos;
-
- if (_shouldPushColls)
- pushCollisions(0);
-
- collAreaStart = 0;
- while (_collisionAreas[collAreaStart].left != 0xFFFF)
- collAreaStart++;
- collArea = &_collisionAreas[collAreaStart];
-
- _shouldPushColls = 0;
- collResId = -1;
-
- _script->skip(1);
- count = _script->readByte();
-
- _handleMouse = _script->peekByte(0);
- deltaTime = 1000 * _script->peekByte(1);
- stackPos2 = _script->peekByte(3);
- descIndex = _script->peekByte(4);
- byte var_42 = _script->peekByte(5);
-
- if ((stackPos2 != 0) || (descIndex != 0)) {
- deltaTime /= 100;
- if (_script->peekByte(1) == 100)
- deltaTime = 2;
- }
-
- timeVal = deltaTime;
- _script->skip(6);
-
- startPos = _script->pos();
- WRITE_VAR(16, 0);
-
- byte var_41 = 0;
- int16 var_46 = 0;
- int16 var_1C = 0;
- int16 index = 0;
- int16 curEditIndex = 0;
- int right = 0, funcLeave = 0;
-
- for (curCmd = 0; curCmd < count; curCmd++) {
- array[curCmd] = 0;
- cmd = _script->readByte();
-
- if ((cmd & 0x40) != 0) {
- cmd -= 0x40;
- cmdHigh = _script->readByte();
- cmdHigh <<= 8;
- } else
- cmdHigh = 0;
-
- if ((cmd & 0x80) != 0) {
- offsetPos = _script->pos();
- left = _script->readValExpr();
- top = _script->readValExpr();
- width = _script->readValExpr();
- height = _script->readValExpr();
- } else {
- offsetPos = 0;
- left = _script->readUint16();
- top = _script->readUint16();
- width = _script->readUint16();
- height = _script->readUint16();
- }
-
- if ((_vm->_draw->_renderFlags & RENDERFLAG_CAPTUREPOP) && (left != 0xFFFF)) {
- left += _vm->_draw->_backDeltaX;
- top += _vm->_draw->_backDeltaY;
- }
-
- if (left != 0xFFFF) {
- _vm->_draw->adjustCoords(0, &left, &top);
- if (((cmd & 0x3F) < 20) && ((cmd & 0x3F) >= 3)) {
- if (_vm->_draw->_needAdjust != 2)
- height &= 0xFFFE;
- _vm->_draw->adjustCoords(0, 0, &width);
- } else
- _vm->_draw->adjustCoords(0, &height, &width);
- }
-
- cmd &= 0x7F;
- debugC(1, kDebugCollisions, "collisionsBlock(%d)", cmd);
-
- switch (cmd) {
- case 0:
- _script->skip(6);
- startPos = _script->pos();
- _script->skip(_script->peekUint16(2) + 2);
- key = curCmd + 0xA000;
-
- addNewCollision(curCmd + 0x8000, left, top,
- left + width - 1, top + height - 1,
- cmd + cmdHigh, key, startPos,
- _script->pos(), offsetPos);
-
- _script->skip(_script->peekUint16(2) + 2);
-
- break;
-
- case 1:
- key = _script->readInt16();
- array[curCmd] = _script->readInt16();
- flags = _script->readInt16();
-
- startPos = _script->pos();
- _script->skip(_script->peekUint16(2) + 2);
-
- if (key == 0)
- key = curCmd + 0xA000;
-
- addNewCollision(curCmd + 0x8000, left, top,
- left + width - 1, top + height - 1,
- (flags << 4) + cmd + cmdHigh, key, startPos,
- _script->pos(), offsetPos);
-
- _script->skip(_script->peekUint16(2) + 2);
-
- break;
-
- case 3:
- case 4:
- case 5:
- case 6:
- case 7:
- case 8:
- case 9:
- case 10:
- _vm->_util->clearKeyBuf();
- var_1C = 1;
- key = _script->readVarIndex();
- descArray[index].fontIndex = _script->readInt16();
- descArray[index].backColor = _script->readByte();
- descArray[index].frontColor = _script->readByte();
-
- if ((cmd >= 5) && (cmd <= 8)) {
- descArray[index].ptr = _script->getData() + _script->pos() + 2;
- _script->skip(_script->peekUint16() + 2);
- } else
- descArray[index].ptr = 0;
-
- if (left == 0xFFFF) {
- if ((cmd & 1) == 0) {
- _script->skip(_script->peekUint16(2) + 2);
- }
- break;
- }
-
- right = left + width - 1;
- if (!_vm->_draw->_fonts[descArray[index].fontIndex]->extraData)
- right = left + width * _vm->_draw->_fonts[descArray[index].fontIndex]->itemWidth - 1;
-
- funcLeave = 0;
- if (!(cmd & 1))
- funcLeave = _script->pos();
-
- addNewCollision(curCmd + 0x8000, left, top, right,
- top + height - 1, cmd, key, 0, funcLeave, 0);
-
- if (!(cmd & 1)) {
- _script->skip(_script->peekUint16(2) + 2);
- }
-
- index++;
- break;
-
- case 11:
- _script->skip(6);
- for (i = 0; i < 150; i++) {
- if ((_collisionAreas[i].id & 0xF000) == 0xE000) {
- _collisionAreas[i].id &= 0xBFFF;
- _collisionAreas[i].funcEnter =
- _script->pos();
- _collisionAreas[i].funcLeave =
- _script->pos();
- }
- }
- _script->skip(_script->peekUint16(2) + 2);
- break;
-
- case 12:
- _script->skip(6);
- for (i = 0; i < 150; i++) {
- if ((_collisionAreas[i].id & 0xF000) == 0xD000) {
- _collisionAreas[i].id &= 0xBFFF;
- _collisionAreas[i].funcEnter =
- _script->pos();
- _collisionAreas[i].funcLeave =
- _script->pos();
- }
- }
- _script->skip(_script->peekUint16(2) + 2);
- break;
-
- case 20:
- collResId = curCmd;
- // Fall through to case 2
-
- case 2:
- key = _script->readInt16();
- array[curCmd] = _script->readInt16();
- flags = _script->readInt16();
-
- addNewCollision(curCmd + 0x8000, left, top,
- left + width - 1, top + height - 1,
- (flags << 4) + cmdHigh + 2, key, 0,
- _script->pos(), offsetPos);
-
- _script->skip(_script->peekUint16(2) + 2);
-
- break;
-
- case 21:
- key = _script->readInt16();
- array[curCmd] = _script->readInt16();
- flags = _script->readInt16() & 3;
-
- addNewCollision(curCmd + 0x8000, left, top,
- left + width - 1, top + height - 1,
- (flags << 4) + cmdHigh + 2, key,
- _script->pos(), 0, offsetPos);
-
- _script->skip(_script->peekUint16(2) + 2);
-
- break;
- }
- }
-
- if (var_42 != 0)
- setCollisions(1);
-
- _forceHandleMouse = 0;
- _vm->_util->clearKeyBuf();
-
- do {
- if (var_1C != 0) {
- key = multiEdit(deltaTime, index, &curEditIndex, descArray,
- &activeCollResId, &activeCollIndex, false);
-
- WRITE_VAR(55, curEditIndex);
- if (key == kKeyReturn) {
- for (i = 0; i < 150; i++) {
- if (_collisionAreas[i].left == 0xFFFF)
- break;
-
- if ((_collisionAreas[i].id & 0xC000) != 0x8000)
- continue;
-
- if ((_collisionAreas[i].flags & 1) != 0)
- continue;
-
- if ((_collisionAreas[i].flags & 0x0F) <= 2)
- continue;
-
- activeCollResId = _collisionAreas[i].id;
- collResId = _collisionAreas[i].id & 0x7FFF;
- activeCollIndex = i;
- break;
- }
- break;
- }
- } else
- key = checkCollisions(_handleMouse, -deltaTime,
- &activeCollResId, &activeCollIndex);
-
- if (((key & 0xFF) >= ' ') && ((key & 0xFF) <= 0xFF) &&
- ((key >> 8) > 1) && ((key >> 8) < 12))
- key = '0' + (((key >> 8) - 1) % 10) + (key & 0xFF00);
-
- if (activeCollResId == 0) {
- if (key != 0) {
- for (i = 0; i < 150; i++) {
- if (_collisionAreas[i].left == 0xFFFF)
- break;
-
- if ((_collisionAreas[i].id & 0xC000) != 0x8000)
- continue;
-
- if ((_collisionAreas[i].key == key) ||
- (_collisionAreas[i].key == 0x7FFF)) {
- activeCollResId = _collisionAreas[i].id;
- activeCollIndex = i;
- break;
- }
- }
-
- if (activeCollResId == 0) {
- for (i = 0; i < 150; i++) {
- if (_collisionAreas[i].left == 0xFFFF)
- break;
-
- if ((_collisionAreas[i].id & 0xC000) != 0x8000)
- continue;
-
- if ((_collisionAreas[i].key & 0xFF00) != 0)
- continue;
-
- if (_collisionAreas[i].key == 0)
- continue;
-
- if (adjustKey(key & 0xFF) == adjustKey(_collisionAreas[i].key)) {
- activeCollResId = _collisionAreas[i].id;
- activeCollIndex = i;
- break;
- }
- }
- }
- } else if (deltaTime != 0) {
- if (stackPos2 != 0) {
- collStackPos = 0;
-
- for (i = 0, collPtr = collArea; collPtr->left != 0xFFFF; i++, collPtr++) {
- if ((collPtr->id & 0xF000) != 0x8000)
- continue;
-
- collStackPos++;
- if (collStackPos != stackPos2)
- continue;
-
- activeCollResId = collPtr->id;
- activeCollIndex = i + collAreaStart;
- _vm->_inter->storeMouse();
- if (VAR(16) != 0)
- break;
-
- if ((activeCollResId & 0xF000) == 0x8000)
- WRITE_VAR(16, array[activeCollResId & 0xFFF]);
- else
- WRITE_VAR(16, activeCollResId & 0xFFF);
-
- if (collPtr->funcLeave != 0) {
- uint32 timeKey = _vm->_util->getTimeKey();
- collSub(collPtr->funcLeave);
-
- if (timeVal != 2) {
- deltaTime = timeVal - (_vm->_util->getTimeKey() - timeKey);
-
- if ((deltaTime - var_46) < 3) {
- var_46 -= (deltaTime - 3);
- deltaTime = 3;
- } else if (var_46 != 0) {
- deltaTime -= var_46;
- var_46 = 0;
- }
-
- if (deltaTime > timeVal)
- deltaTime = timeVal;
-
- } else
- deltaTime = 2;
-
- }
-
- if (VAR(16) == 0)
- activeCollResId = 0;
- else
- var_41 = 1;
-
- break;
- }
- } else {
- if (descIndex != 0) {
-
- counter = 0;
- for (i = 0, collPtr = collArea; collPtr->left != 0xFFFF; i++, collPtr++) {
- if ((collPtr->id & 0xF000) == 0x8000)
- if (++counter == descIndex) {
- activeCollResId = collPtr->id;
- activeCollIndex = i + collAreaStart;
- break;
- }
- }
-
- } else {
-
- for (i = 0, collPtr = _collisionAreas; collPtr->left != 0xFFFF; i++, collPtr++) {
- if ((collPtr->id & 0xF000) == 0x8000) {
- activeCollResId = collPtr->id;
- activeCollIndex = i;
- break;
- }
- }
- if ((_lastCollKey != 0) &&
- (_collisionAreas[_lastCollAreaIndex].funcLeave != 0))
- collSub(_collisionAreas[_lastCollAreaIndex].funcLeave);
-
- _lastCollKey = 0;
- }
-
- }
- }
- }
-
- if (var_41 != 0)
- break;
-
- if ((activeCollResId == 0) ||
- (_collisionAreas[activeCollIndex].funcLeave != 0))
- continue;
-
- _vm->_inter->storeMouse();
- if ((activeCollResId & 0xF000) == 0x8000)
- WRITE_VAR(16, array[activeCollResId & 0xFFF]);
- else
- WRITE_VAR(16, activeCollResId & 0xFFF);
-
- if (_collisionAreas[activeCollIndex].funcEnter != 0)
- collSub(_collisionAreas[activeCollIndex].funcEnter);
-
- WRITE_VAR(16, 0);
- activeCollResId = 0;
- }
- while ((activeCollResId == 0) && !_vm->_inter->_terminate && !_vm->shouldQuit());
-
- if ((activeCollResId & 0xFFF) == collResId) {
- collStackPos = 0;
- var_24 = 0;
- var_26 = 1;
- for (i = 0; i < 150; i++) {
- if (_collisionAreas[i].left == 0xFFFF)
- continue;
-
- if ((_collisionAreas[i].id & 0xC000) != 0x8000)
- continue;
-
- if ((_collisionAreas[i].flags & 0x0F) < 3)
- continue;
-
- if ((_collisionAreas[i].flags & 0x0F) > 10)
- continue;
-
- if ((_collisionAreas[i].flags & 0x0F) > 8) {
- char *ptr;
- strncpy0(_tempStr, GET_VARO_STR(_collisionAreas[i].key), 255);
- while ((ptr = strchr(_tempStr, ' ')))
- _vm->_util->cutFromStr(_tempStr, (ptr - _tempStr), 1);
- if (_vm->_language == 2)
- while ((ptr = strchr(_tempStr, '.')))
- *ptr = ',';
- WRITE_VARO_STR(_collisionAreas[i].key, _tempStr);
- }
-
- if (((_collisionAreas[i].flags & 0x0F) >= 5) &&
- ((_collisionAreas[i].flags & 0x0F) <= 8)) {
- str = (char *) descArray[var_24].ptr;
-
- strncpy0(_tempStr, GET_VARO_STR(_collisionAreas[i].key), 255);
-
- if ((_collisionAreas[i].flags & 0x0F) < 7)
- _vm->_util->cleanupStr(_tempStr);
-
- int16 pos = 0;
- do {
- strncpy0(_collStr, str, 255);
- pos += strlen(str) + 1;
-
- str += strlen(str) + 1;
-
- if ((_collisionAreas[i].flags & 0x0F) < 7)
- _vm->_util->cleanupStr(_collStr);
-
- if (strcmp(_tempStr, _collStr) == 0) {
- WRITE_VAR(17, VAR(17) + 1);
- WRITE_VAR(17 + var_26, 1);
- break;
- }
- } while (READ_LE_UINT16(descArray[var_24].ptr - 2) > pos);
- collStackPos++;
- } else {
- WRITE_VAR(17 + var_26, 2);
- }
- var_24++;
- var_26++;
- }
-
- if (collStackPos != (int16) VAR(17))
- WRITE_VAR(17, 0);
- else
- WRITE_VAR(17, 1);
- }
-
- if (_handleMouse == 1)
- _vm->_draw->blitCursor();
-
- if (!_vm->_inter->_terminate && (var_41 == 0)) {
- _script->seek(_collisionAreas[activeCollIndex].funcLeave);
-
- _vm->_inter->storeMouse();
- if (VAR(16) == 0) {
- if ((activeCollResId & 0xF000) == 0x8000)
- WRITE_VAR(16, array[activeCollResId & 0xFFF]);
- else
- WRITE_VAR(16, activeCollResId & 0xFFF);
- }
- } else
- _script->setFinished(true);
-
- for (curCmd = 0; curCmd < count; curCmd++)
- freeCollision(curCmd + 0x8000);
-
- for (i = 0; i < 150; i++) {
- if (((_collisionAreas[i].id & 0xF000) == 0xA000) ||
- ((_collisionAreas[i].id & 0xF000) == 0x9000))
- _collisionAreas[i].id |= 0x4000;
- }
-}
-
-void Game_v6::setCollisions(byte arg_0) {
- for (Collision *collArea = _collisionAreas; collArea->left != 0xFFFF; collArea++) {
- if (((collArea->id & 0xC000) != 0x8000) || (collArea->funcSub == 0))
- continue;
-
- if (arg_0 == 0)
- if (collArea->flags & 0x80)
- continue;
-
- Script *curScript = _script;
-
- _script = collArea->script;
- if (!_script)
- _script = curScript;
-
- _script->call(collArea->funcSub);
-
- int16 left = _script->readValExpr();
- int16 top = _script->readValExpr();
- int16 width = _script->readValExpr();
- int16 height = _script->readValExpr();
- uint16 flags = 0;
-
- if ((collArea->id & 0xF000) == 0xA000)
- flags = _script->readValExpr();
-
- if ((_vm->_draw->_renderFlags & RENDERFLAG_CAPTUREPOP) &&
- (left != -1)) {
- left += _vm->_draw->_backDeltaX;
- top += _vm->_draw->_backDeltaY;
- }
- if (_vm->_draw->_needAdjust != 2) {
- _vm->_draw->adjustCoords(0, &left, &top);
- if ((collArea->flags & 0x0F) < 3)
- _vm->_draw->adjustCoords(2, &width, &height);
- else {
- height &= 0xFFFE;
- _vm->_draw->adjustCoords(2, 0, &height);
- }
- }
-
- if (left < 0) {
- width += left;
- left = 0;
- }
-
- if (top < 0) {
- height += top;
- top = 0;
- }
-
- collArea->left = left;
- collArea->top = top;
- collArea->right = left + width - 1;
- collArea->bottom = top + height - 1;
-
- if ((collArea->id & 0xF000) == 0xA000)
- collArea->flags = flags;
-
- _script->pop();
-
- _script = curScript;
- }
-}
-
-void Game_v6::collSub(uint16 offset) {
- int16 collStackSize;
-
- uint32 savedPos = _script->pos();
-
- _script->seek(offset);
-
- _shouldPushColls = 1;
- collStackSize = _collStackSize;
-
- _vm->_inter->funcBlock(0);
-
- if (collStackSize != _collStackSize)
- popCollisions();
-
- _shouldPushColls = 0;
-
- _script->seek(savedPos);
-
- if ((_vm->_util->getTimeKey() - _someTimeDly) > 500)
- setCollisions(0);
-}
-
-static const byte adjustTable[] = {
- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
- 0x20, 0x21, 0x21, 0x21, 0x21, 0x21, 0x20, 0x20,
- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
- 0x81, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
- 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
- 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12,
- 0x12, 0x12, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
- 0x40, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x04,
- 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
- 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
- 0x04, 0x04, 0x04, 0x40, 0x40, 0x40, 0x40, 0x40,
- 0x40, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x08,
- 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
- 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
- 0x08, 0x08, 0x08, 0x40, 0x40, 0x40, 0x40, 0x20,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
-};
-
-int16 Game_v6::adjustKey(int16 key) {
- if (key == -1)
- return -1;
-
- if (adjustTable[key & 0xFF] & 8)
- return ((key & 0xFF) - 0x20);
-
- return key & 0xFF;
-}
-
-int16 Game_v6::checkMousePoint(int16 all, int16 *resId, int16 *resIndex) {
- Collision *ptr;
- int16 i;
-
- if (resId != 0)
- *resId = 0;
-
- *resIndex = 0;
-
- ptr = _collisionAreas;
- for (i = 0; ptr->left != 0xFFFF; ptr++, i++) {
- if (ptr->id & 0x4000)
- continue;
-
- if (all) {
- if ((ptr->flags & 0xF) > 1)
- continue;
-
- if ((ptr->flags & 0xF00) != 0)
- continue;
-
- if ((_vm->_global->_inter_mouseX < ptr->left) ||
- (_vm->_global->_inter_mouseX > ptr->right) ||
- (_vm->_global->_inter_mouseY < ptr->top) ||
- (_vm->_global->_inter_mouseY > ptr->bottom))
- continue;
-
- if (resId != 0)
- *resId = ptr->id;
-
- *resIndex = i;
- return ptr->key;
- } else {
- if ((ptr->flags & 0xF00) != 0)
- continue;
-
- if ((ptr->flags & 0xF) < 1)
- continue;
-
- if ((((ptr->flags & 0x70) >> 4) != (((int32) _mouseButtons) - 1)) &&
- (((ptr->flags & 0x70) >> 4) != 2))
- continue;
-
- if ((_vm->_global->_inter_mouseX < ptr->left) ||
- (_vm->_global->_inter_mouseX > ptr->right) ||
- (_vm->_global->_inter_mouseY < ptr->top) ||
- (_vm->_global->_inter_mouseY > ptr->bottom))
- continue;
-
- if (resId != 0)
- *resId = ptr->id;
- *resIndex = i;
- if (((ptr->flags & 0xF) == 1) || ((ptr->flags & 0xF) == 2))
- return ptr->key;
- return 0;
- }
- }
-
- if ((_mouseButtons != kMouseButtonsLeft) && (all == 0))
- return kKeyEscape;
-
- return 0;
-}
-
-void Game_v6::collSubReenter() {
- int16 lastCollAreaIndex = _lastCollAreaIndex;
- int16 lastCollId = _lastCollId;
- int16 collKey = checkMousePoint(1, &_lastCollId, &_lastCollAreaIndex);
-
- if (collKey == _lastCollKey)
- return;
-
- if ((_lastCollKey != 0) && (lastCollId & 0x8000))
- collAreaSub(lastCollAreaIndex, 0);
-
- _lastCollKey = collKey;
-
- if ((_lastCollKey != 0) && (_lastCollId & 0x8000))
- collAreaSub(_lastCollAreaIndex, 1);
-}
-
} // End of namespace Gob
diff --git a/engines/gob/hotspots.cpp b/engines/gob/hotspots.cpp
new file mode 100644
index 0000000000..bed9d6a7cb
--- /dev/null
+++ b/engines/gob/hotspots.cpp
@@ -0,0 +1,1706 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "gob/hotspots.h"
+#include "gob/global.h"
+#include "gob/helper.h"
+#include "gob/draw.h"
+#include "gob/game.h"
+#include "gob/script.h"
+#include "gob/inter.h"
+
+namespace Gob {
+
+Hotspots::Hotspot::Hotspot() {
+ clear();
+}
+
+Hotspots::Hotspot::Hotspot(uint16 i,
+ uint16 l, uint16 t, uint16 r, uint16 b, uint16 f, uint16 k,
+ uint16 enter, uint16 leave, uint16 pos) {
+
+ id = i;
+ left = l;
+ top = t;
+ right = r;
+ bottom = b;
+ flags = f;
+ key = k;
+ funcEnter = enter;
+ funcLeave = leave;
+ funcPos = pos;
+ script = 0;
+}
+
+void Hotspots::Hotspot::clear() {
+ id = 0;
+ left = 0xFFFF;
+ top = 0;
+ right = 0;
+ bottom = 0;
+ flags = 0;
+ key = 0;
+ funcEnter = 0;
+ funcLeave = 0;
+ funcPos = 0;
+ script = 0;
+}
+
+Hotspots::Type Hotspots::Hotspot::getType() const {
+ return (Type) (flags & 0xF);
+}
+
+MouseButtons Hotspots::Hotspot::getButton() const {
+ uint8 buttonBits = ((flags & 0x70) >> 4);
+
+ if (buttonBits == 0)
+ return kMouseButtonsLeft;
+ if (buttonBits == 1)
+ return kMouseButtonsRight;
+ if (buttonBits == 2)
+ return kMouseButtonsAny;
+
+ return kMouseButtonsNone;
+}
+
+uint8 Hotspots::Hotspot::getWindow() const {
+ return (flags & 0x0F00) >> 8;
+}
+
+uint8 Hotspots::Hotspot::getCursor() const {
+ return (flags & 0xF000) >> 12;
+}
+
+bool Hotspots::Hotspot::isIn(uint16 x, uint16 y) const {
+ if (x < left)
+ return false;
+ if (x > right)
+ return false;
+ if (y < top)
+ return false;
+ if (y > bottom)
+ return false;
+
+ return true;
+}
+
+bool Hotspots::Hotspot::buttonMatch(MouseButtons button) const {
+ MouseButtons myButton = getButton();
+
+ if (myButton == kMouseButtonsAny)
+ return true;
+
+ if (myButton == kMouseButtonsNone)
+ return false;
+
+ if (myButton == button)
+ return true;
+
+ return false;
+}
+
+
+Hotspots::Hotspots(GobEngine *vm) : _vm(vm) {
+ _hotspots = new Hotspot[kHotspotCount];
+
+ _shouldPush = false;
+
+ _currentKey = 0;
+ _currentIndex = 0;
+ _currentId = 0;
+}
+
+Hotspots::~Hotspots() {
+ delete[] _hotspots;
+
+ while (!_stack.empty()) {
+ StackEntry backup = _stack.pop();
+
+ delete[] backup.hotspots;
+ }
+}
+
+void Hotspots::clear() {
+ _currentKey = 0;
+
+ for (int i = 0; i < kHotspotCount; i++)
+ _hotspots[i].clear();
+}
+
+uint16 Hotspots::add(uint16 id,
+ uint16 left, uint16 top, uint16 right, uint16 bottom,
+ uint16 flags, uint16 key,
+ uint16 funcEnter, uint16 funcLeave, uint16 funcPos) {
+
+ Hotspot hotspot(id, left, top, right, bottom,
+ flags, key, funcEnter, funcLeave, funcPos);
+
+ return add(hotspot);
+}
+
+uint16 Hotspots::add(const Hotspot &hotspot) {
+ for (int i = 0; i < kHotspotCount; i++) {
+ Hotspot &spot = _hotspots[i];
+
+ // free space => add same id => update
+ if (! ((spot.left == 0xFFFF) || (spot.id == hotspot.id)))
+ continue;
+
+ // When updating, keep bit 0x4000 intact
+ uint16 id = hotspot.id;
+ if ((spot.id & 0xBFFF) == (hotspot.id & 0xBFFF))
+ id = spot.id;
+
+ // Set
+ spot = hotspot;
+ spot.id = id;
+
+ // Remember the current script
+ spot.script = _vm->_game->_script;
+
+ return i;
+ }
+
+ error("Hotspots::add(): Hotspot array full");
+ return 0xFFFF;
+}
+
+void Hotspots::remove(uint16 id) {
+ for (int i = 0; i < kHotspotCount; i++) {
+ if (_hotspots[i].id == id)
+ _hotspots[i].clear();
+ }
+}
+
+void Hotspots::removeState(uint16 state) {
+ for (int i = 0; i < kHotspotCount; i++) {
+ Hotspot &spot = _hotspots[i];
+
+ if ((spot.id & 0xF000) == state)
+ spot.clear();
+ }
+}
+
+void Hotspots::recalculate(bool force) {
+ for (int i = 0; i < kHotspotCount; i++) {
+ Hotspot &spot = _hotspots[i];
+
+ if (spot.left == 0xFFFF)
+ // End reached
+ break;
+
+ if (!force && ((spot.flags & 0x80) != 0))
+ continue;
+
+ if (spot.funcPos == 0)
+ continue;
+
+ // Setting the needed script
+ Script *curScript = _vm->_game->_script;
+
+ _vm->_game->_script = spot.script;
+ if (!_vm->_game->_script)
+ _vm->_game->_script = curScript;
+
+ // Calling the function that contains the positions
+ _vm->_game->_script->call(spot.funcPos);
+
+ // Calculate positions
+ int16 left = _vm->_game->_script->readValExpr();
+ int16 top = _vm->_game->_script->readValExpr();
+ int16 width = _vm->_game->_script->readValExpr();
+ int16 height = _vm->_game->_script->readValExpr();
+
+ // Re-read the flags too, if applicable
+ uint16 flags = 0;
+ if ((spot.id & 0xF000) == 0xA000)
+ flags = _vm->_game->_script->readValExpr();
+
+ // Apply backDelta, if needed
+ if ((_vm->_draw->_renderFlags & RENDERFLAG_CAPTUREPOP) && (left != -1)) {
+ left += _vm->_draw->_backDeltaX;
+ top += _vm->_draw->_backDeltaY;
+ }
+
+ // Clamping
+ if (left < 0) {
+ width += left;
+ left = 0;
+ }
+ if (top < 0) {
+ height += top;
+ top = 0;
+ }
+
+ // Set the updated position
+ spot.left = left;
+ spot.top = top;
+ spot.right = left + width - 1;
+ spot.bottom = top + height - 1;
+
+ if ((spot.id & 0xF000) == 0xA000)
+ spot.flags = flags;
+
+ // Return
+ _vm->_game->_script->pop();
+
+ _vm->_game->_script = curScript;
+ }
+}
+
+void Hotspots::push(uint8 all, bool force) {
+ // Should we push at all?
+ if (!_shouldPush && !force)
+ return;
+
+ // Count the hotspots
+ uint32 size = 0;
+ for (int i = 0; i < kHotspotCount; i++) {
+ Hotspot &spot = _hotspots[i];
+
+ if (spot.left == 0xFFFF)
+ // End reached
+ break;
+
+ // Save all of them
+ if ( (all == 1) ||
+ // Don't save the global ones
+ ((all == 0) && (spot.id >= 20)) ||
+ // Only save the ones with the correct state
+ ((all == 2) && (((spot.id & 0xF000) == 0xD000) ||
+ ((spot.id & 0xF000) == 0x4000) ||
+ ((spot.id & 0xF000) == 0xE000)))) {
+ size++;
+ }
+
+ }
+
+ StackEntry backup;
+
+ backup.shouldPush = _shouldPush;
+ backup.size = size;
+ backup.key = _currentKey;
+ backup.id = _currentId;
+ backup.index = _currentIndex;
+
+ backup.hotspots = new Hotspot[size];
+
+ // Copy the hotspots
+ Hotspot *destPtr = backup.hotspots;
+ for (int i = 0; i < kHotspotCount; i++) {
+ Hotspot &spot = _hotspots[i];
+
+ if (spot.left == 0xFFFF)
+ // End reached
+ break;
+
+ // Save all of them
+ if ( (all == 1) ||
+ // Don't save the global ones
+ ((all == 0) && (spot.id >= 20)) ||
+ // Only save the ones with the correct state
+ ((all == 2) && (((spot.id & 0xF000) == 0xD000) ||
+ ((spot.id & 0xF000) == 0x4000) ||
+ ((spot.id & 0xF000) == 0xE000)))) {
+
+ memcpy(destPtr, &spot, sizeof(Hotspot));
+ destPtr++;
+
+ spot.left = 0xFFFF;
+ }
+
+ }
+
+ // Reset current state
+ _shouldPush = false;
+ _currentKey = 0;
+ _currentId = 0;
+ _currentIndex = 0;
+
+ _stack.push(backup);
+}
+
+void Hotspots::pop() {
+ assert(!_stack.empty());
+
+ StackEntry backup = _stack.pop();
+
+ // Find the end of the filled hotspot space
+ int i;
+ Hotspot *destPtr = _hotspots;
+ for (i = 0; i < kHotspotCount; i++, destPtr++)
+ if (destPtr->left == 0xFFFF)
+ break;
+
+ if (((uint32) (kHotspotCount - i)) < backup.size)
+ error("Hotspots::pop(): Not enough free space in the current Hotspot "
+ "array to pop %d elements (got %d)", backup.size, kHotspotCount - i);
+
+ memcpy(destPtr, backup.hotspots, backup.size * sizeof(Hotspot));
+
+ _shouldPush = backup.shouldPush;
+ _currentKey = backup.key;
+ _currentId = backup.id;
+ _currentIndex = backup.index;
+
+ delete[] backup.hotspots;
+}
+
+bool Hotspots::isValid(uint16 key, uint16 id, uint16 index) const {
+ if (index >= kHotspotCount)
+ return false;
+
+ if (key == 0)
+ return false;
+
+ if (!(id & 0x8000))
+ return false;
+
+ return true;
+}
+
+void Hotspots::call(uint16 offset) {
+ _vm->_game->_script->call(offset);
+
+ _shouldPush = true;
+
+ int16 stackSize = _stack.size();
+
+ _vm->_inter->funcBlock(0);
+
+ while (stackSize != _stack.size())
+ pop();
+
+ _shouldPush = false;
+
+ _vm->_game->_script->pop();
+
+ recalculate(false);
+}
+
+void Hotspots::enter(uint16 index) {
+ if (index >= kHotspotCount) {
+ warning("Hotspots::enter(): Index %d out of range", index);
+ return;
+ }
+
+ Hotspot &spot = _hotspots[index];
+
+ if (((spot.id & 0xF000) == 0xA000) || ((spot.id & 0xF000) == 0x9000))
+ WRITE_VAR(17, -(spot.id & 0x0FFF));
+
+ if (spot.funcEnter != 0)
+ call(spot.funcEnter);
+}
+
+void Hotspots::leave(uint16 index) {
+ if (index >= kHotspotCount) {
+ warning("Hotspots::leave(): Index %d out of range", index);
+ return;
+ }
+
+ Hotspot &spot = _hotspots[index];
+
+ if (((spot.id & 0xF000) == 0xA000) || ((spot.id & 0xF000) == 0x9000))
+ WRITE_VAR(17, spot.id & 0x0FFF);
+
+ if (spot.funcLeave != 0)
+ call(spot.funcLeave);
+}
+
+uint16 Hotspots::checkMouse(Type type, uint16 &id, uint16 &index) const {
+ id = 0;
+ index = 0;
+
+ if (type == kTypeMove) {
+
+ for (int i = 0; i < kHotspotCount; i++) {
+ Hotspot &spot = _hotspots[i];
+
+ if (spot.left == 0xFFFF)
+ break;
+
+ if (spot.id & 0x4000)
+ continue;
+
+ if (spot.getType() > kTypeMove)
+ continue;
+
+ if (spot.getWindow() != 0)
+ continue;
+
+ if (!spot.isIn(_vm->_global->_inter_mouseX, _vm->_global->_inter_mouseY))
+ continue;
+
+ id = spot.id;
+ index = i;
+
+ return spot.key;
+ }
+
+ return 0;
+
+ } else if (type == kTypeClick) {
+
+ for (int i = 0; i < kHotspotCount; i++) {
+ Hotspot &spot = _hotspots[i];
+
+ if (spot.left == 0xFFFF)
+ break;
+
+ if (spot.id & 0x4000)
+ continue;
+
+ if (spot.getWindow() != 0)
+ continue;
+
+ if (spot.getType() < kTypeMove)
+ continue;
+
+ if (!spot.isIn(_vm->_global->_inter_mouseX, _vm->_global->_inter_mouseY))
+ continue;
+
+ if (!spot.buttonMatch(_vm->_game->_mouseButtons))
+ continue;
+
+ id = spot.id;
+ index = i;
+
+ if ((spot.getType() == kTypeMove) || (spot.getType() == kTypeClick))
+ return spot.key;
+
+ return 0;
+ }
+
+ if (_vm->_game->_mouseButtons != kMouseButtonsLeft)
+ return kKeyEscape;
+
+ return 0;
+
+ }
+
+ return 0;
+}
+
+void Hotspots::checkHotspotChanged() {
+ uint16 key, id, index;
+
+ key = checkMouse(kTypeMove, id, index);
+
+ if (key == _currentKey)
+ return;
+
+ if (isValid(_currentKey, _currentId, _currentIndex))
+ leave(_currentIndex);
+
+ _currentKey = key;
+ _currentId = id;
+ _currentIndex = index;
+
+ if (isValid(key, id, index))
+ enter(index);
+}
+
+uint16 Hotspots::check(uint8 handleMouse, int16 delay, uint16 &id, uint16 &index) {
+ _vm->_game->_scrollHandleMouse = handleMouse != 0;
+
+ if (delay >= -1) {
+ _currentKey = 0;
+ _currentId = 0;
+ _currentIndex = 0;
+ }
+
+ id = 0;
+ index = 0;
+
+ if (handleMouse) {
+ if ((_vm->_draw->_cursorIndex == -1) && (_currentKey == 0)) {
+ _currentKey = checkMouse(kTypeMove, _currentId, _currentIndex);
+
+ if (isValid(_currentKey, _currentId, _currentIndex))
+ enter(_currentIndex);
+ }
+
+ _vm->_draw->animateCursor(-1);
+ }
+
+ uint32 startTime = _vm->_util->getTimeKey();
+
+ _vm->_draw->blitInvalidated();
+ _vm->_video->retrace();
+
+ uint16 key = 0;
+ while (key == 0) {
+
+ if (_vm->_inter->_terminate || _vm->shouldQuit()) {
+ if (handleMouse)
+ _vm->_draw->blitCursor();
+ return 0;
+ }
+
+ checkHotspotChanged();
+
+ if (!_vm->_draw->_noInvalidated) {
+ if (handleMouse)
+ _vm->_draw->animateCursor(-1);
+ else
+ _vm->_draw->blitInvalidated();
+ _vm->_video->waitRetrace();
+ }
+
+ key = _vm->_game->checkKeys(&_vm->_global->_inter_mouseX,
+ &_vm->_global->_inter_mouseY, &_vm->_game->_mouseButtons, handleMouse);
+
+ if (!handleMouse && (_vm->_game->_mouseButtons != kMouseButtonsNone)) {
+ _vm->_util->waitMouseRelease(0);
+ key = 3;
+ }
+
+ if (key != 0) {
+ if (handleMouse & 1)
+ _vm->_draw->blitCursor();
+
+ id = 0;
+ index = 0;
+
+ if (isValid(_currentKey, _currentId, _currentIndex))
+ leave(_currentIndex);
+
+ _currentKey = 0;
+ break;
+ }
+
+ if (handleMouse) {
+
+ if (_vm->_game->_mouseButtons != kMouseButtonsNone) {
+
+ if (delay > 0) {
+ _vm->_draw->animateCursor(2);
+ _vm->_util->delay(delay);
+ } else if (handleMouse & 1)
+ _vm->_util->waitMouseRelease(1);
+
+ _vm->_draw->animateCursor(-1);
+
+ key = checkMouse(kTypeClick, id, index);
+
+ if ((key != 0) || (id != 0)) {
+ if ( (handleMouse & 1) &&
+ ((delay <= 0) || (_vm->_game->_mouseButtons == kMouseButtonsNone)))
+ _vm->_draw->blitCursor();
+
+ if (key != _currentKey)
+ leave(_currentIndex);
+
+ _currentKey = 0;
+ break;
+ }
+
+ if (handleMouse & 4)
+ return 0;
+
+ if (_currentKey != 0)
+ leave(_currentIndex);
+
+ _currentKey = checkMouse(kTypeMove, _currentId, _currentIndex);
+ if (isValid(_currentKey, _currentId, _currentIndex))
+ enter(_currentIndex);
+
+ } else
+ checkHotspotChanged();
+
+ }
+
+ if ((delay == -2) && (key == 0) &&
+ (_vm->_game->_mouseButtons == kMouseButtonsNone)) {
+
+ id = 0;
+ index = 0;
+ break;
+ }
+
+ if (handleMouse)
+ _vm->_draw->animateCursor(-1);
+
+ if ((delay < 0) && (key == 0) &&
+ (_vm->_game->_mouseButtons == kMouseButtonsNone)) {
+
+ uint32 curTime = _vm->_util->getTimeKey();
+ // Timeout reached?
+ if ((curTime + delay) > startTime) {
+ id = 0;
+ index = 0;
+ break;
+ }
+
+ }
+
+ _vm->_util->delay(10);
+
+ }
+
+ return key;
+}
+
+uint16 Hotspots::check(uint8 handleMouse, int16 delay) {
+ uint16 id, index;
+
+ return Hotspots::check(handleMouse, delay, id, index);
+}
+
+uint16 Hotspots::readString(uint16 xPos, uint16 yPos, uint16 width, uint16 height,
+ uint16 backColor, uint16 frontColor, char *str, uint16 fontIndex,
+ Type type, int16 &duration, uint16 &id, uint16 index) {
+
+ if ((fontIndex >= 8) || !_vm->_draw->_fonts[fontIndex])
+ return 0;
+
+ bool handleMouse = false;
+ if ( (_vm->_game->_handleMouse != 0) &&
+ ((_vm->_global->_useMouse != 0) || (_vm->_game->_forceHandleMouse != 0)))
+ handleMouse = true;
+
+ Video::FontDesc &font = *_vm->_draw->_fonts[fontIndex];
+
+ bool monoSpaced = (font.extraData == 0);
+
+ uint32 pos = strlen(str);
+ uint32 editSize = monoSpaced ? 0 : (width / font.itemWidth);
+
+ uint16 key = 0;
+ char tempStr[256];
+
+ while (1) {
+ strncpy0(tempStr, str, 254);
+ strcat(tempStr, " ");
+ if ((editSize != 0) && strlen(tempStr) > editSize)
+ strncpy0(tempStr, str, 255);
+
+ _vm->_draw->_destSpriteX = xPos;
+ _vm->_draw->_destSpriteY = yPos;
+ _vm->_draw->_spriteRight = monoSpaced ? (editSize * font.itemWidth) : width;
+ _vm->_draw->_spriteBottom = height;
+
+ _vm->_draw->_destSurface = 21;
+ _vm->_draw->_backColor = backColor;
+ _vm->_draw->_frontColor = frontColor;
+ _vm->_draw->_textToPrint = tempStr;
+ _vm->_draw->_transparency = 1;
+ _vm->_draw->_fontIndex = fontIndex;
+ _vm->_draw->spriteOperation(DRAW_FILLRECT | 0x10 );
+
+ _vm->_draw->_destSpriteY = yPos + (height - font.itemHeight) / 2;
+ _vm->_draw->spriteOperation(DRAW_PRINTTEXT | 0x10);
+
+ if ((editSize != 0) && (pos == editSize))
+ pos--;
+
+ char curSym = tempStr[pos];
+
+ if (_vm->_inter->_variables)
+ WRITE_VAR(56, pos);
+
+ bool first = true;
+ while (1) {
+ tempStr[0] = curSym;
+ tempStr[1] = 0;
+
+ if (font.extraData) {
+ _vm->_draw->_destSpriteY = yPos;
+ _vm->_draw->_spriteBottom = height;
+ _vm->_draw->_spriteRight = 1;
+
+ _vm->_draw->_destSpriteX = xPos;
+ for (uint32 j = 0; j < pos; j++)
+ _vm->_draw->_destSpriteX += font.extraData[str[j] - font.startItem];
+
+ } else {
+ _vm->_draw->_destSpriteX = xPos + font.itemWidth * pos;
+ _vm->_draw->_destSpriteY = yPos + height - 1;
+ _vm->_draw->_spriteRight = font.itemWidth;
+ _vm->_draw->_spriteBottom = 1;
+ }
+
+ _vm->_draw->_destSurface = 21;
+ _vm->_draw->_backColor = frontColor;
+ _vm->_draw->spriteOperation(DRAW_FILLRECT | 0x10);
+
+ if (first) {
+ key = check(handleMouse, -1, id, index);
+
+ if (key == 0)
+ key = check(handleMouse, -300, id, index);
+
+ first = false;
+ } else
+ key = check(handleMouse, -300, id, index);
+
+ tempStr[0] = curSym;
+ tempStr[1] = 0;
+
+ if (font.extraData) {
+ _vm->_draw->_destSpriteY = yPos;
+ _vm->_draw->_spriteBottom = height;
+ _vm->_draw->_spriteRight = 1;
+
+ _vm->_draw->_destSpriteX = xPos;
+ for (uint32 j = 0; j < pos; j++)
+ _vm->_draw->_destSpriteX += font.extraData[str[j] - font.startItem];
+
+ } else {
+ _vm->_draw->_destSpriteX = xPos + font.itemWidth * pos;
+ _vm->_draw->_destSpriteY = yPos + height - 1;
+ _vm->_draw->_spriteRight = font.itemWidth;
+ _vm->_draw->_spriteBottom = 1;
+ }
+
+ _vm->_draw->_destSurface = 21;
+ _vm->_draw->_backColor = backColor;
+ _vm->_draw->_frontColor = frontColor;
+ _vm->_draw->_textToPrint = tempStr;
+ _vm->_draw->_transparency = 1;
+ _vm->_draw->_fontIndex = fontIndex;
+ _vm->_draw->spriteOperation(DRAW_FILLRECT | 0x10);
+
+ _vm->_draw->_destSpriteY = yPos + (height - font.itemHeight) / 2;
+ _vm->_draw->spriteOperation(DRAW_PRINTTEXT | 0x10);
+
+ if ((key != 0) || (id != 0))
+ break;
+
+ key = check(handleMouse, -300, id, index);
+
+ if ((key != 0) || (id != 0) ||
+ _vm->_inter->_terminate || _vm->shouldQuit())
+ break;
+
+ if (duration > 0) {
+ duration -= 600;
+ if (duration <= 1) {
+ key = 0;
+ id = 0;
+ break;
+ }
+ }
+ }
+
+ if ((key == 0) || (id != 0) ||
+ _vm->_inter->_terminate || _vm->shouldQuit())
+ return 0;
+
+ switch (key) {
+ case kKeyRight:
+ if ((pos > strlen(str)) || (pos > (editSize - 1)) || (editSize == 0)) {
+ pos++;
+ continue;
+ }
+ return kKeyDown;
+
+ case kKeyLeft:
+ if (pos > 0) {
+ pos--;
+ continue;
+ }
+ return kKeyUp;
+
+ case kKeyBackspace:
+ if (pos > 0) {
+ _vm->_util->cutFromStr(str, pos - 1, 1);
+ pos--;
+ continue;
+ } else {
+ if (pos < strlen(str))
+ _vm->_util->cutFromStr(str, pos, 1);
+ }
+
+ case kKeyDelete:
+ if (pos >= strlen(str))
+ continue;
+
+ _vm->_util->cutFromStr(str, pos, 1);
+ continue;
+
+ case kKeyReturn:
+ case kKeyF1:
+ case kKeyF2:
+ case kKeyF3:
+ case kKeyF4:
+ case kKeyF5:
+ case kKeyF6:
+ case kKeyF7:
+ case kKeyF8:
+ case kKeyF9:
+ case kKeyF10:
+ case kKeyUp:
+ case kKeyDown:
+ return key;
+
+ case kKeyEscape:
+ if (_vm->_global->_useMouse != 0)
+ continue;
+
+ _vm->_game->_forceHandleMouse = !_vm->_game->_forceHandleMouse;
+
+ handleMouse = false;
+ if ( (_vm->_game->_handleMouse != 0) &&
+ ((_vm->_global->_useMouse != 0) || (_vm->_game->_forceHandleMouse != 0)))
+ handleMouse = true;
+
+ while (_vm->_global->_pressedKeys[1] != 0)
+ ;
+ continue;
+
+ default:
+ uint16 savedKey = key;
+
+ key &= 0xFF;
+
+ if (((type == kTypeInputFloatNoLeave) || (type == kTypeInputFloatLeave)) &&
+ (key >= ' ') && (key <= 0xFF)) {
+ const char *str1 = "0123456789-.,+ ";
+ const char *str2 = "0123456789-,,+ ";
+
+ if ((((savedKey >> 8) > 1) && ((savedKey >> 8) < 12)) &&
+ ((_vm->_global->_pressedKeys[42] != 0) ||
+ (_vm->_global->_pressedKeys[56] != 0)))
+ key = ((savedKey >> 8) - 1) % 10 + '0';
+
+ int i;
+ for (i = 0; str1[i] != 0; i++) {
+ if (key == str1[i]) {
+ key = str2[i];
+ break;
+ }
+ }
+
+ if (i == (int16) strlen(str1))
+ key = 0;
+ }
+
+ if ((key >= ' ') && (key <= 0xFF)) {
+ if (editSize == 0) {
+ int length = _vm->_draw->stringLength(str, fontIndex) +
+ font.extraData[' ' - font.startItem] +
+ font.extraData[key - font.startItem];
+
+ if (length > width)
+ continue;
+
+ if (((int32) strlen(str)) >= (_vm->_global->_inter_animDataSize * 4 - 1))
+ continue;
+
+ } else {
+ if (strlen(str) > editSize)
+ continue;
+ else if (editSize == strlen(str))
+ _vm->_util->cutFromStr(str, strlen(str) - 1, 1);
+ }
+
+ pos++;
+ tempStr[0] = key;
+ tempStr[1] = 0;
+
+ _vm->_util->insertStr(tempStr, str, pos - 1);
+ }
+
+ }
+ }
+}
+
+uint16 Hotspots::handleInput(int16 time, uint16 maxPos, uint16 &curPos,
+ InputDesc *inpDesc, uint16 &id, uint16 &index) {
+
+ uint16 descInd = 0;
+ uint16 key = 0;
+ uint16 found = 0xFFFF;
+
+ for (int i = 0; i < kHotspotCount; i++) {
+ Hotspot &spot = _hotspots[i];
+
+ if (spot.left == 0xFFFF)
+ continue;
+
+ if ((spot.id & 0xC000) != 0x8000)
+ continue;
+
+ if (spot.getType() < kTypeInput1NoLeave)
+ continue;
+
+ if (spot.getType() > kTypeInputFloatLeave)
+ continue;
+
+ char tempStr[256];
+ strncpy0(tempStr, GET_VARO_STR(spot.key), 255);
+
+ _vm->_draw->_destSpriteX = spot.left;
+ _vm->_draw->_destSpriteY = spot.top;
+ _vm->_draw->_spriteRight = spot.right - spot.left + 1;
+ _vm->_draw->_spriteBottom = spot.bottom - spot.top + 1;
+
+ _vm->_draw->_destSurface = 21;
+
+ _vm->_draw->_backColor = inpDesc[descInd].backColor;
+ _vm->_draw->_frontColor = inpDesc[descInd].frontColor;
+ _vm->_draw->_textToPrint = tempStr;
+ _vm->_draw->_transparency = 1;
+ _vm->_draw->_fontIndex = inpDesc[descInd].fontIndex;
+
+ _vm->_draw->spriteOperation(DRAW_FILLRECT | 0x10);
+
+ _vm->_draw->_destSpriteY += ((spot.bottom - spot.top + 1) -
+ _vm->_draw->_fonts[_vm->_draw->_fontIndex]->itemHeight) / 2;
+ _vm->_draw->spriteOperation(DRAW_PRINTTEXT | 0x10);
+
+ descInd++;
+ }
+
+ for (int i = 0; i < 40; i++)
+ WRITE_VAR_OFFSET(i * 4 + 0x44, 0);
+
+ while (1) {
+ descInd = 0;
+
+ for (int i = 0; i < kHotspotCount; i++) {
+ Hotspot &spot = _hotspots[i];
+
+ if (spot.left == 0xFFFF)
+ continue;
+
+ if ((spot.id & 0xC000) != 0x8000)
+ continue;
+
+ if (spot.getType() < kTypeInput1NoLeave)
+ continue;
+
+ if (spot.getType() > kTypeInputFloatLeave)
+ continue;
+
+ if (descInd == curPos) {
+ found = i;
+ break;
+ }
+
+ descInd++;
+ }
+
+ assert(found != 0xFFFF);
+
+ Hotspot inputSpot = _hotspots[found];
+
+ key = readString(inputSpot.left, inputSpot.top,
+ inputSpot.right - inputSpot.left + 1,
+ inputSpot.bottom - inputSpot.top + 1,
+ inpDesc[curPos].backColor, inpDesc[curPos].frontColor,
+ GET_VARO_STR(inputSpot.key), inpDesc[curPos].fontIndex,
+ inputSpot.getType(), time, id, index);
+
+ if (_vm->_inter->_terminate)
+ return 0;
+
+ switch (key) {
+ case kKeyNone:
+ if (id == 0)
+ return 0;
+
+ if (_vm->_game->_mouseButtons != kMouseButtonsNone) {
+ for (int i = 0; i < kHotspotCount; i++) {
+ Hotspot &spot = _hotspots[i];
+
+ if (spot.left == 0xFFFF)
+ break;
+
+ if (spot.getWindow() != 0)
+ continue;
+
+ if ((spot.id & 0x4000))
+ continue;
+
+ if (!spot.isIn(_vm->_global->_inter_mouseX, _vm->_global->_inter_mouseY))
+ continue;
+
+ if ((spot.id & 0xF000))
+ continue;
+
+ if (spot.getType() < kTypeInput1NoLeave)
+ continue;
+
+ if (spot.getType() > kTypeInputFloatLeave)
+ continue;
+
+ index = i;
+ break;
+ }
+ }
+
+ if (_hotspots[index].getType() < kTypeInput1NoLeave)
+ return 0;
+
+ if (_hotspots[index].getType() > kTypeInputFloatLeave)
+ return 0;
+
+ curPos = 0;
+ for (int i = 0; i < kHotspotCount; i++) {
+ Hotspot &spot = _hotspots[i];
+
+ if (spot.left == 0xFFFF)
+ continue;
+
+ if ((spot.id & 0xC000) != 0x8000)
+ continue;
+
+ if (spot.getType() < kTypeInput1NoLeave)
+ continue;
+
+ if (spot.getType() > kTypeInputFloatLeave)
+ continue;
+
+ if (i == index)
+ break;
+
+ curPos++;
+ }
+ break;
+
+ case kKeyF1:
+ case kKeyF2:
+ case kKeyF3:
+ case kKeyF4:
+ case kKeyF5:
+ case kKeyF6:
+ case kKeyF7:
+ case kKeyF8:
+ case kKeyF9:
+ case kKeyF10:
+ return key;
+
+ case kKeyReturn:
+
+ if (maxPos == 1)
+ return key;
+
+ if (curPos == (maxPos - 1)) {
+ curPos = 0;
+ break;
+ }
+
+ curPos++;
+ break;
+
+ case kKeyDown:
+ if ((maxPos - 1) > curPos)
+ curPos++;
+ break;
+
+ case kKeyUp:
+ if (curPos > 0)
+ curPos--;
+ break;
+ }
+ }
+}
+
+void Hotspots::evaluate() {
+ InputDesc descArray[20];
+ int16 array[300];
+ char *str;
+ int16 counter;
+ int16 var_24;
+ int16 var_26;
+ int16 collStackPos;
+
+ push(0);
+
+ uint16 endIndex = 0;
+ while (_hotspots[endIndex].left != 0xFFFF)
+ endIndex++;
+
+ _shouldPush = false;
+
+ _vm->_game->_script->skip(1);
+
+ byte count = _vm->_game->_script->readByte();
+
+ _vm->_game->_handleMouse = _vm->_game->_script->peekByte(0);
+ int16 duration = _vm->_game->_script->peekByte(1);
+ byte stackPos2 = _vm->_game->_script->peekByte(3);
+ byte descIndex = _vm->_game->_script->peekByte(4);
+ bool needRecalculation = _vm->_game->_script->peekByte(5) != 0;
+
+ duration *= 1000;
+ if ((stackPos2 != 0) || (descIndex != 0)) {
+ duration /= 100;
+ if (_vm->_game->_script->peekByte(1) == 100)
+ duration = 2;
+ }
+
+ int16 timeVal = duration;
+
+ _vm->_game->_script->skip(6);
+
+ WRITE_VAR(16, 0);
+
+ byte var_41 = 0;
+ int16 var_46 = 0;
+
+ uint16 id = 0;
+ uint16 validId = 0xFFFF;
+ uint16 index = 0;
+
+ bool hasInput = false;
+ uint16 inputIndex = 0;
+
+ for (uint16 i = 0; i < count; i++) {
+ array[i] = 0;
+
+ byte type = _vm->_game->_script->readByte();
+ byte window = 0;
+
+ if ((type & 0x40) != 0) {
+ type -= 0x40;
+ window = _vm->_game->_script->readByte();
+ }
+
+ uint16 left, top, width, height, right, bottom;
+ uint32 funcEnter = 0, funcLeave = 0, funcPos = 0;
+ if ((type & 0x80) != 0) {
+ funcPos = _vm->_game->_script->pos();
+ left = _vm->_game->_script->readValExpr();
+ top = _vm->_game->_script->readValExpr();
+ width = _vm->_game->_script->readValExpr();
+ height = _vm->_game->_script->readValExpr();
+ } else {
+ funcPos = 0;
+ left = _vm->_game->_script->readUint16();
+ top = _vm->_game->_script->readUint16();
+ width = _vm->_game->_script->readUint16();
+ height = _vm->_game->_script->readUint16();
+ }
+
+ if ((_vm->_draw->_renderFlags & RENDERFLAG_CAPTUREPOP) && (left != 0xFFFF)) {
+ left += _vm->_draw->_backDeltaX;
+ top += _vm->_draw->_backDeltaY;
+ }
+
+ right = left + width - 1;
+ bottom = top + height - 1;
+
+ int16 key = 0;
+ int16 flags = 0;
+ Video::FontDesc *font = 0;
+
+ type &= 0x7F;
+ switch (type) {
+ case kTypeNone:
+ _vm->_game->_script->skip(6);
+
+ funcEnter = _vm->_game->_script->pos();
+ _vm->_game->_script->skipBlock();
+
+ funcLeave = _vm->_game->_script->pos();
+ _vm->_game->_script->skipBlock();
+
+ key = i + 0xA000;
+ flags = type + (window << 8);
+
+ add(i + 0x8000, left, top, right, bottom,
+ flags, key, funcEnter, funcLeave, funcPos);
+ break;
+
+ case kTypeMove:
+ key = _vm->_game->_script->readInt16();
+ array[i] = _vm->_game->_script->readInt16();
+ flags = _vm->_game->_script->readInt16();
+
+ funcEnter = _vm->_game->_script->pos();
+ _vm->_game->_script->skipBlock();
+
+ funcLeave = _vm->_game->_script->pos();
+ _vm->_game->_script->skipBlock();
+
+ if (key == 0)
+ key = i + 0xA000;
+ flags = type + (window << 8) + (flags << 4);
+
+ add(i + 0x8000, left, top, right, bottom,
+ flags, key, funcEnter, funcLeave, funcPos);
+ break;
+
+ case kTypeInput1NoLeave:
+ case kTypeInput1Leave:
+ case kTypeInput2NoLeave:
+ case kTypeInput2Leave:
+ case kTypeInput3NoLeave:
+ case kTypeInput3Leave:
+ case kTypeInputFloatNoLeave:
+ case kTypeInputFloatLeave:
+ hasInput = true;
+
+ _vm->_util->clearKeyBuf();
+
+ key = _vm->_game->_script->readVarIndex();
+ descArray[inputIndex].fontIndex = _vm->_game->_script->readInt16();
+ descArray[inputIndex].backColor = _vm->_game->_script->readByte();
+ descArray[inputIndex].frontColor = _vm->_game->_script->readByte();
+ descArray[inputIndex].ptr = 0;
+
+ if ((type >= kTypeInput2NoLeave) && (type <= kTypeInput3Leave)) {
+ descArray[inputIndex].ptr = _vm->_game->_script->getData() + _vm->_game->_script->pos() + 2;
+ _vm->_game->_script->skip(_vm->_game->_script->peekUint16() + 2);
+ }
+
+ if (left == 0xFFFF) {
+ if ((type & 1) == 0)
+ _vm->_game->_script->skipBlock();
+ break;
+ }
+
+ font = _vm->_draw->_fonts[descArray[inputIndex].fontIndex];
+ if (!font->extraData)
+ right = left + width * font->itemWidth - 1;
+
+ funcEnter = 0;
+ funcPos = 0;
+ funcLeave = 0;
+ if (!(type & 1)) {
+ funcLeave = _vm->_game->_script->pos();
+ _vm->_game->_script->skipBlock();
+ }
+
+ flags = type;
+
+ inputIndex++;
+
+ add(i + 0x8000, left, top, right, bottom,
+ flags, key, funcEnter, funcLeave, funcPos);
+
+ break;
+
+ case 11:
+ _vm->_game->_script->skip(6);
+
+ for (int j = 0; j < kHotspotCount; j++) {
+ Hotspot &spot = _hotspots[j];
+
+ if ((spot.id & 0xF000) == 0xE000) {
+ spot.id &= 0xBFFF;
+ spot.funcEnter = _vm->_game->_script->pos();
+ spot.funcLeave = _vm->_game->_script->pos();
+ }
+ }
+
+ _vm->_game->_script->skipBlock();
+ break;
+
+ case 12:
+ _vm->_game->_script->skip(6);
+
+ for (int j = 0; j < kHotspotCount; j++) {
+ Hotspot &spot = _hotspots[j];
+
+ if ((spot.id & 0xF000) == 0xD000) {
+ spot.id &= 0xBFFF;
+ spot.funcEnter = _vm->_game->_script->pos();
+ spot.funcLeave = _vm->_game->_script->pos();
+ }
+ }
+
+ _vm->_game->_script->skipBlock();
+ break;
+
+ case 20:
+ validId = i;
+ // Fall through to case 2
+ case kTypeClick:
+ key = _vm->_game->_script->readInt16();
+ array[i] = _vm->_game->_script->readInt16();
+ flags = _vm->_game->_script->readInt16();
+
+ funcEnter = 0;
+
+ funcLeave = _vm->_game->_script->pos();
+ _vm->_game->_script->skipBlock();
+
+ flags = 2 + (window << 8) + (flags << 4);
+
+ add(i + 0x8000, left, top, right, bottom,
+ flags, key, funcEnter, funcLeave, funcPos);
+ break;
+
+ case 21:
+ key = _vm->_game->_script->readInt16();
+ array[i] = _vm->_game->_script->readInt16();
+ flags = _vm->_game->_script->readInt16() & 3;
+
+ funcEnter = _vm->_game->_script->pos();
+ _vm->_game->_script->skipBlock();
+
+ funcLeave = 0;
+
+ flags = 2 + (window << 8) + (flags << 4);
+
+ add(i + 0x8000, left, top, right, bottom,
+ flags, key, funcEnter, funcLeave, funcPos);
+ break;
+ }
+ }
+
+ if (needRecalculation)
+ recalculate(true);
+
+ _vm->_game->_forceHandleMouse = 0;
+ _vm->_util->clearKeyBuf();
+
+ do {
+ uint16 key = 0;
+ if (hasInput) {
+ uint16 curEditIndex = 0;
+
+ key = handleInput(duration, inputIndex, curEditIndex, descArray, id, index);
+
+ WRITE_VAR(55, curEditIndex);
+ if (key == kKeyReturn) {
+ for (int i = 0; i < kHotspotCount; i++) {
+ Hotspot &spot = _hotspots[i];
+
+ if (spot.left == 0xFFFF)
+ break;
+
+ if ((spot.id & 0xC000) != 0x8000)
+ continue;
+
+ if ((spot.getType() & 1) != 0)
+ continue;
+
+ if (spot.getType() <= kTypeClick)
+ continue;
+
+ id = spot.id;
+ validId = spot.id & 0x7FFF;
+ index = i;
+ break;
+ }
+ break;
+ }
+ } else
+ key = check(_vm->_game->_handleMouse, -duration, id, index);
+
+ if (((key & 0xFF) >= ' ') && ((key & 0xFF) <= 0xFF) &&
+ ((key >> 8) > 1) && ((key >> 8) < 12))
+ key = '0' + (((key >> 8) - 1) % 10) + (key & 0xFF00);
+
+ if (id == 0) {
+ if (key != 0) {
+ for (int i = 0; i < kHotspotCount; i++) {
+ Hotspot &spot = _hotspots[i];
+
+ if (spot.left == 0xFFFF)
+ break;
+
+ if ((spot.id & 0xC000) != 0x8000)
+ continue;
+
+ if ((spot.key == key) || (spot.key == 0x7FFF)) {
+ id = spot.id;
+ index = i;
+ break;
+ }
+ }
+
+ if (id == 0) {
+ for (int i = 0; i < kHotspotCount; i++) {
+ Hotspot &spot = _hotspots[i];
+
+ if (spot.left == 0xFFFF)
+ break;
+
+ if ((spot.id & 0xC000) != 0x8000)
+ continue;
+
+ if ((spot.key & 0xFF00) != 0)
+ continue;
+
+ if (spot.key == 0)
+ continue;
+
+ if (toupper(key & 0xFF) == toupper(spot.key)) {
+ id = spot.id;
+ index = i;
+ break;
+ }
+ }
+ }
+ } else if (duration != 0) {
+ if (stackPos2 != 0) {
+ collStackPos = 0;
+
+ for (int i = endIndex; i < kHotspotCount; i++) {
+ Hotspot &spot = _hotspots[i];
+
+ if (spot.left == 0xFFFF)
+ break;
+
+ if ((spot.id & 0xF000) != 0x8000)
+ continue;
+
+ collStackPos++;
+ if (collStackPos != stackPos2)
+ continue;
+
+ id = spot.id;
+ index = i;
+ _vm->_inter->storeMouse();
+ if (VAR(16) != 0)
+ break;
+
+ if ((id & 0xF000) == 0x8000)
+ WRITE_VAR(16, array[id & 0xFFF]);
+ else
+ WRITE_VAR(16, id & 0xFFF);
+
+ if (spot.funcLeave != 0) {
+ uint32 timeKey = _vm->_util->getTimeKey();
+ call(spot.funcLeave);
+
+ if (timeVal != 2) {
+ duration = timeVal - (_vm->_util->getTimeKey() - timeKey);
+
+ if ((duration - var_46) < 3) {
+ var_46 -= (duration - 3);
+ duration = 3;
+ } else if (var_46 != 0) {
+ duration -= var_46;
+ var_46 = 0;
+ }
+
+ if (duration > timeVal)
+ duration = timeVal;
+
+ } else
+ duration = 2;
+
+ }
+
+ if (VAR(16) == 0)
+ id = 0;
+ else
+ var_41 = 1;
+
+ break;
+ }
+
+ } else {
+ if (descIndex != 0) {
+
+ counter = 0;
+ for (int i = endIndex; i < kHotspotCount; i++) {
+ Hotspot &spot = _hotspots[i];
+
+ if (spot.left == 0xFFFF)
+ break;
+
+ if ((spot.id & 0xF000) == 0x8000) {
+ if (++counter == descIndex) {
+ id = spot.id;
+ index = i;
+ break;
+ }
+ }
+
+ }
+
+ } else {
+
+ for (int i = 0; i < kHotspotCount; i++) {
+ Hotspot &spot = _hotspots[i];
+
+ if (spot.left == 0xFFFF)
+ break;
+
+ if ((spot.id & 0xF000) == 0x8000) {
+ id = spot.id;
+ index = i;
+ break;
+ }
+ }
+
+ if ((_currentKey != 0) && (_hotspots[_currentIndex].funcLeave != 0))
+ call(_hotspots[_currentIndex].funcLeave);
+
+ _currentKey = 0;
+ }
+
+ }
+ }
+ }
+
+ if (var_41 != 0)
+ break;
+
+ if ((id == 0) || (_hotspots[index].funcLeave != 0))
+ continue;
+
+ _vm->_inter->storeMouse();
+
+ if ((id & 0xF000) == 0x8000)
+ WRITE_VAR(16, array[id & 0xFFF]);
+ else
+ WRITE_VAR(16, id & 0xFFF);
+
+ if (_hotspots[index].funcEnter != 0)
+ call(_hotspots[index].funcEnter);
+
+ WRITE_VAR(16, 0);
+ id = 0;
+ }
+ while ((id == 0) && !_vm->_inter->_terminate && !_vm->shouldQuit());
+
+ char tempStr[256];
+ if ((id & 0xFFF) == validId) {
+ collStackPos = 0;
+ var_24 = 0;
+ var_26 = 1;
+ for (int i = 0; i < kHotspotCount; i++) {
+ Hotspot &spot = _hotspots[i];
+
+ if (spot.left == 0xFFFF)
+ continue;
+
+ if ((spot.id & 0xC000) != 0x8000)
+ continue;
+
+ if (spot.getType() < kTypeInput1NoLeave)
+ continue;
+
+ if (spot.getType() > kTypeInputFloatLeave)
+ continue;
+
+ if (spot.getType() > kTypeInput3Leave) {
+ char *ptr;
+ strncpy0(tempStr, GET_VARO_STR(spot.key), 255);
+ while ((ptr = strchr(tempStr, ' ')))
+ _vm->_util->cutFromStr(tempStr, (ptr - tempStr), 1);
+ if (_vm->_global->_language == kLanguageBritish)
+ while ((ptr = strchr(tempStr, '.')))
+ *ptr = ',';
+ WRITE_VARO_STR(spot.key, tempStr);
+ }
+
+ if ((spot.getType() >= kTypeInput2NoLeave) && (spot.getType() <= kTypeInput3Leave)) {
+ str = (char *) descArray[var_24].ptr;
+
+ strncpy0(tempStr, GET_VARO_STR(spot.key), 255);
+
+ if (spot.getType() < kTypeInput3NoLeave)
+ _vm->_util->cleanupStr(tempStr);
+
+ int16 pos = 0;
+ do {
+ char spotStr[256];
+
+ strncpy0(spotStr, str, 255);
+ pos += strlen(str) + 1;
+
+ str += strlen(str) + 1;
+
+ if (spot.getType() < kTypeInput3NoLeave)
+ _vm->_util->cleanupStr(spotStr);
+
+ if (strcmp(tempStr, spotStr) == 0) {
+ WRITE_VAR(17, VAR(17) + 1);
+ WRITE_VAR(17 + var_26, 1);
+ break;
+ }
+ } while (READ_LE_UINT16(descArray[var_24].ptr - 2) > pos);
+ collStackPos++;
+ } else {
+ WRITE_VAR(17 + var_26, 2);
+ }
+ var_24++;
+ var_26++;
+ }
+
+ if (collStackPos != (int16) VAR(17))
+ WRITE_VAR(17, 0);
+ else
+ WRITE_VAR(17, 1);
+ }
+
+ if (_vm->_game->_handleMouse == 1)
+ _vm->_draw->blitCursor();
+
+ if (!_vm->_inter->_terminate && (var_41 == 0)) {
+ _vm->_game->_script->seek(_hotspots[index].funcLeave);
+
+ _vm->_inter->storeMouse();
+ if (VAR(16) == 0) {
+ if ((id & 0xF000) == 0x8000)
+ WRITE_VAR(16, array[id & 0xFFF]);
+ else
+ WRITE_VAR(16, id & 0xFFF);
+ }
+ } else
+ _vm->_game->_script->setFinished(true);
+
+ for (int i = 0; i < count; i++)
+ remove(i + 0x8000);
+
+ for (int i = 0; i < kHotspotCount; i++) {
+ Hotspot &spot = _hotspots[i];
+
+ if (((spot.id & 0xF000) == 0xA000) || ((spot.id & 0xF000) == 0x9000))
+ spot.id |= 0x4000;
+ }
+
+}
+
+int16 Hotspots::findCursor(uint16 x, uint16 y) const {
+ int16 cursor = 0;
+
+ for (int i = 0; i < kHotspotCount; i++) {
+ Hotspot &spot = _hotspots[i];
+
+ if (spot.left == 0xFFFF)
+ break;
+
+ if ((spot.getWindow() != 0) || (spot.id & 0x4000))
+ continue;
+
+ if (!spot.isIn(x, y))
+ continue;
+
+ if (spot.getCursor() == 0) {
+ if (spot.getType() >= kTypeInput1NoLeave) {
+ cursor = 3;
+ break;
+ } else if ((spot.getButton() != kMouseButtonsRight) && (cursor == 0))
+ cursor = 1;
+ } else if (cursor == 0)
+ cursor = spot.getCursor();
+ }
+
+ return cursor;
+}
+
+} // End of namespace Gob
diff --git a/engines/gob/hotspots.h b/engines/gob/hotspots.h
new file mode 100644
index 0000000000..0bafb94937
--- /dev/null
+++ b/engines/gob/hotspots.h
@@ -0,0 +1,177 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef GOB_HOTSPOTS_H
+#define GOB_HOTSPOTS_H
+
+#include "common/stack.h"
+
+#include "gob/util.h"
+
+namespace Gob {
+
+class Script;
+
+class Hotspots {
+public:
+ static const int kHotspotCount = 250;
+
+ enum Type {
+ kTypeNone = 0,
+ kTypeMove = 1,
+ kTypeClick = 2,
+ kTypeInput1NoLeave = 3,
+ kTypeInput1Leave = 4,
+ kTypeInput2NoLeave = 5,
+ kTypeInput2Leave = 6,
+ kTypeInput3NoLeave = 7,
+ kTypeInput3Leave = 8,
+ kTypeInputFloatNoLeave = 9,
+ kTypeInputFloatLeave = 10
+ };
+
+ Hotspots(GobEngine *vm);
+ ~Hotspots();
+
+ void clear();
+
+ /** Add a hotspot, returning the new index. */
+ uint16 add(uint16 id,
+ uint16 left, uint16 top, uint16 right, uint16 bottom,
+ uint16 flags, uint16 key,
+ uint16 funcEnter, uint16 funcLeave, uint16 funcPos);
+
+ void remove(uint16 id);
+ void removeState(uint16 state);
+
+ /** Push the current hotspots onto the stack.
+ *
+ * @param all 0: Don't push global ones; 1: Push all; 2: Push only the ones with the correct state
+ * @param force Force a push although _shouldPush is false
+ */
+ void push(uint8 all, bool force = false);
+ /** Pop hotspots from the stack. */
+ void pop();
+
+ uint16 check(uint8 handleMouse, int16 delay, uint16 &id, uint16 &index);
+ uint16 check(uint8 handleMouse, int16 delay);
+
+ void evaluate();
+
+ int16 findCursor(uint16 x, uint16 y) const;
+
+private:
+ struct Hotspot {
+ uint16 id;
+ uint16 left;
+ uint16 top;
+ uint16 right;
+ uint16 bottom;
+ uint16 flags;
+ uint16 key;
+ uint16 funcEnter;
+ uint16 funcLeave;
+ uint16 funcPos;
+ Script *script;
+
+ Hotspot();
+ Hotspot(uint16 i,
+ uint16 l, uint16 t, uint16 r, uint16 b, uint16 f, uint16 k,
+ uint16 enter, uint16 leave, uint16 pos);
+
+ void clear();
+
+ Type getType() const;
+ MouseButtons getButton() const;
+ uint8 getWindow() const;
+ uint8 getCursor() const;
+
+ /** Are the specified coordinates in the hotspot? */
+ bool isIn(uint16 x, uint16 y) const;
+ /** Does the specified button trigger the hotspot? */
+ bool buttonMatch(MouseButtons button) const;
+ };
+
+ struct StackEntry {
+ bool shouldPush;
+ Hotspot *hotspots;
+ uint32 size;
+ uint32 key;
+ uint32 id;
+ uint32 index;
+ };
+
+ struct InputDesc {
+ uint16 fontIndex;
+ uint16 backColor;
+ uint16 frontColor;
+ byte *ptr;
+ };
+
+ GobEngine *_vm;
+
+ Hotspot *_hotspots;
+ Common::Stack<StackEntry> _stack;
+
+ bool _shouldPush;
+
+ uint16 _currentKey;
+ uint16 _currentIndex;
+ uint16 _currentId;
+
+ /** Add a hotspot, returning the new index. */
+ uint16 add(const Hotspot &hotspot);
+
+ /** Recalculate all hotspot parameters
+ *
+ * @param force Force recalculation of all hotspots, including global ones.
+ */
+ void recalculate(bool force);
+
+ bool isValid(uint16 key, uint16 id, uint16 index) const;
+
+ /** Call a hotspot subroutine. */
+ void call(uint16 offset);
+ /** Handling hotspot enter events. */
+ void enter(uint16 index);
+ /** Handling hotspot leave events. */
+ void leave(uint16 index);
+
+ /** Which hotspot is the mouse cursor currently at? */
+ uint16 checkMouse(Type type, uint16 &id, uint16 &index) const;
+
+void checkHotspotChanged();
+
+ uint16 readString(uint16 xPos, uint16 yPos, uint16 width, uint16 height,
+ uint16 backColor, uint16 frontColor, char *str, uint16 fontIndex,
+ Type type, int16 &duration, uint16 &id, uint16 index);
+
+ uint16 handleInput(int16 time, uint16 hotspotIndex, uint16 &curPos,
+ InputDesc *inpDesc, uint16 &id, uint16 &index);
+};
+
+} // End of namespace Gob
+
+#endif // GOB_HOTSPOTS_H
diff --git a/engines/gob/inter.cpp b/engines/gob/inter.cpp
index 5ec0647d29..afd215a00d 100644
--- a/engines/gob/inter.cpp
+++ b/engines/gob/inter.cpp
@@ -35,6 +35,7 @@
#include "gob/game.h"
#include "gob/expression.h"
#include "gob/script.h"
+#include "gob/hotspots.h"
#include "gob/scenery.h"
#include "gob/sound/sound.h"
@@ -334,7 +335,7 @@ void Inter::callSub(int16 retFlag) {
if (block == 1)
funcBlock(retFlag);
else if (block == 2)
- _vm->_game->collisionsBlock();
+ _vm->_game->_hotspots->evaluate();
else
error("Unknown block type %d in Inter::callSub()", block);
}
diff --git a/engines/gob/inter_v1.cpp b/engines/gob/inter_v1.cpp
index 23c9351dd4..7d32104552 100644
--- a/engines/gob/inter_v1.cpp
+++ b/engines/gob/inter_v1.cpp
@@ -37,6 +37,7 @@
#include "gob/expression.h"
#include "gob/script.h"
#include "gob/resources.h"
+#include "gob/hotspots.h"
#include "gob/goblin.h"
#include "gob/inter.h"
#include "gob/map.h"
@@ -1173,7 +1174,7 @@ bool Inter_v1::o1_keyFunc(OpFuncParams &params) {
case 0:
_vm->_draw->_showCursor &= ~2;
_vm->_util->longDelay(1);
- key = _vm->_game->checkCollisions(0, 0, 0, 0);
+ key = _vm->_game->_hotspots->check(0, 0);
storeKey(key);
_vm->_util->clearKeyBuf();
diff --git a/engines/gob/inter_v2.cpp b/engines/gob/inter_v2.cpp
index 82822330b1..d71a321db7 100644
--- a/engines/gob/inter_v2.cpp
+++ b/engines/gob/inter_v2.cpp
@@ -39,6 +39,7 @@
#include "gob/expression.h"
#include "gob/script.h"
#include "gob/resources.h"
+#include "gob/hotspots.h"
#include "gob/goblin.h"
#include "gob/map.h"
#include "gob/mult.h"
@@ -1177,66 +1178,48 @@ bool Inter_v2::o2_animPalInit(OpFuncParams &params) {
}
bool Inter_v2::o2_addCollision(OpFuncParams &params) {
- int16 id;
- int16 left, top, width, height;
- int16 flags;
- int16 key;
- int16 funcSub;
-
- id = _vm->_game->_script->readValExpr();
- funcSub = _vm->_game->_script->pos();
- left = _vm->_game->_script->readValExpr();
- top = _vm->_game->_script->readValExpr();
- width = _vm->_game->_script->readValExpr();
- height = _vm->_game->_script->readValExpr();
- flags = _vm->_game->_script->readValExpr();
- key = _vm->_game->_script->readInt16();
+ int16 id = _vm->_game->_script->readValExpr();
+ uint16 funcPos = _vm->_game->_script->pos();
+ int16 left = _vm->_game->_script->readValExpr();
+ int16 top = _vm->_game->_script->readValExpr();
+ uint16 width = _vm->_game->_script->readValExpr();
+ uint16 height = _vm->_game->_script->readValExpr();
+ uint16 flags = _vm->_game->_script->readValExpr();
+ uint16 key = _vm->_game->_script->readInt16();
if (key == 0)
key = ABS(id) + 41960;
- _vm->_draw->adjustCoords(0, &left, &top);
- _vm->_draw->adjustCoords(2, &width, &height);
-
if (left < 0) {
width += left;
- left = 0;
+ left = 0;
}
if (top < 0) {
height += top;
- top = 0;
+ top = 0;
}
int16 index;
if (id < 0)
- index = _vm->_game->addNewCollision(0xD000 - id, left & 0xFFFC, top & 0xFFFC,
- left + width + 3, top + height + 3, flags, key, 0, 0);
+ index = _vm->_game->_hotspots->add(0xD000 - id, left & 0xFFFC, top & 0xFFFC,
+ left + width + 3, top + height + 3, flags, key, 0, 0, funcPos);
else
- index = _vm->_game->addNewCollision(0xE000 + id, left, top,
- left + width - 1, top + height - 1, flags, key, 0, 0);
-
- _vm->_game->_collisionAreas[index].funcSub = funcSub;
+ index = _vm->_game->_hotspots->add(0xE000 + id, left, top,
+ left + width - 1, top + height - 1, flags, key, 0, 0, funcPos);
return false;
}
bool Inter_v2::o2_freeCollision(OpFuncParams &params) {
- int16 id;
+ int16 id = _vm->_game->_script->readValExpr();
- id = _vm->_game->_script->readValExpr();
- if (id == -2) {
- for (int i = 0; i < 150; i++) {
- if ((_vm->_game->_collisionAreas[i].id & 0xF000) == 0xD000)
- _vm->_game->_collisionAreas[i].left = 0xFFFF;
- }
- } else if (id == -1) {
- for (int i = 0; i < 150; i++) {
- if ((_vm->_game->_collisionAreas[i].id & 0xF000) == 0xE000)
- _vm->_game->_collisionAreas[i].left = 0xFFFF;
- }
- } else
- _vm->_game->freeCollision(0xE000 + id);
+ if (id == -2)
+ _vm->_game->_hotspots->removeState(0xD000);
+ else if (id == -1)
+ _vm->_game->_hotspots->removeState(0xE000);
+ else
+ _vm->_game->_hotspots->remove(0xE000 + id);
return false;
}
diff --git a/engines/gob/inter_v6.cpp b/engines/gob/inter_v6.cpp
index 14bfa1e840..b366d39d0d 100644
--- a/engines/gob/inter_v6.cpp
+++ b/engines/gob/inter_v6.cpp
@@ -36,6 +36,7 @@
#include "gob/expression.h"
#include "gob/script.h"
#include "gob/resources.h"
+#include "gob/hotspots.h"
#include "gob/draw.h"
#include "gob/sound/sound.h"
#include "gob/videoplayer.h"
@@ -359,29 +360,23 @@ bool Inter_v6::o6_freeCollision(OpFuncParams &params) {
switch (id + 5) {
case 0:
- _vm->_game->pushCollisions(1);
+ _vm->_game->_hotspots->push(1);
break;
case 1:
- _vm->_game->popCollisions();
+ _vm->_game->_hotspots->pop();
break;
case 2:
- _vm->_game->pushCollisions(2);
+ _vm->_game->_hotspots->push(2);
break;
case 3:
- for (int i = 0; i < 150; i++) {
- if (((_vm->_game->_collisionAreas[i].id & 0xF000) == 0xD000) ||
- ((_vm->_game->_collisionAreas[i].id & 0xF000) == 0x4000))
- _vm->_game->_collisionAreas[i].left = 0xFFFF;
- }
+ _vm->_game->_hotspots->removeState(0xD000);
+ _vm->_game->_hotspots->removeState(0x4000);
break;
case 4:
- for (int i = 0; i < 150; i++) {
- if ((_vm->_game->_collisionAreas[i].id & 0xF000) == 0xE000)
- _vm->_game->_collisionAreas[i].left = 0xFFFF;
- }
+ _vm->_game->_hotspots->removeState(0xE000);
break;
default:
- _vm->_game->freeCollision(0xE000 + id);
+ _vm->_game->_hotspots->remove(0xE000 + id);
break;
}
diff --git a/engines/gob/module.mk b/engines/gob/module.mk
index 695976da61..6c8b735019 100644
--- a/engines/gob/module.mk
+++ b/engines/gob/module.mk
@@ -22,7 +22,7 @@ MODULE_OBJS := \
goblin_v2.o \
goblin_v3.o \
goblin_v4.o \
- videoplayer.o \
+ hotspots.o \
init.o \
init_v1.o \
init_v2.o \
@@ -56,6 +56,7 @@ MODULE_OBJS := \
video_v1.o \
video_v2.o \
video_v6.o \
+ videoplayer.o \
demos/demoplayer.o \
demos/scnplayer.o \
demos/batplayer.o \