diff options
-rw-r--r-- | engines/hugo/display.cpp | 11 | ||||
-rw-r--r-- | engines/hugo/display.h | 2 | ||||
-rw-r--r-- | engines/hugo/hugo.cpp | 29 | ||||
-rw-r--r-- | engines/hugo/hugo.h | 1 | ||||
-rw-r--r-- | engines/hugo/mouse.cpp | 65 | ||||
-rw-r--r-- | engines/hugo/mouse.h | 10 | ||||
-rw-r--r-- | engines/hugo/object.cpp | 13 | ||||
-rw-r--r-- | engines/hugo/route.cpp | 27 | ||||
-rw-r--r-- | engines/hugo/route.h | 6 |
9 files changed, 91 insertions, 73 deletions
diff --git a/engines/hugo/display.cpp b/engines/hugo/display.cpp index 37b3e6e97b..a2902e3b9d 100644 --- a/engines/hugo/display.cpp +++ b/engines/hugo/display.cpp @@ -40,6 +40,7 @@ #include "hugo/inventory.h" #include "hugo/util.h" #include "hugo/object.h" +#include "hugo/mouse.h" namespace Hugo { /** @@ -658,20 +659,16 @@ bool Screen::isOverlapping(const rect_t *rectA, const rect_t *rectB) const { } /** - * Display exit hotspots in God Mode ('PPG') + * Display active boundaries in God Mode ('PPG') * Light Red = Exit hotspots * Light Green = Visible objects * White = Fixed objects, parts of background */ -void Screen::drawHotspots() { +void Screen::drawBoundaries() { if (!_vm->getGameStatus().godModeFl) return; - for (int i = 0; _vm->_hotspots[i].screenIndex >= 0; i++) { - hotspot_t *hotspot = &_vm->_hotspots[i]; - if (hotspot->screenIndex == _vm->_hero->screenIndex) - drawRectangle(false, hotspot->x1, hotspot->y1, hotspot->x2, hotspot->y2, _TLIGHTRED); - } + _vm->_mouse->drawHotspots(); for (int i = 0; i < _vm->_object->_numObj; i++) { object_t *obj = &_vm->_object->_objects[i]; // Get pointer to object diff --git a/engines/hugo/display.h b/engines/hugo/display.h index 575d47c37b..21e9fe2e9c 100644 --- a/engines/hugo/display.h +++ b/engines/hugo/display.h @@ -61,7 +61,7 @@ public: void displayFrame(const int sx, const int sy, seq_t *seq, const bool foreFl); void displayList(dupdate_t update, ...); void displayRect(const int16 x, const int16 y, const int16 dx, const int16 dy); - void drawHotspots(); + void drawBoundaries(); void drawRectangle(const bool filledFl, const int16 x1, const int16 y1, const int16 x2, const int16 y2, const int color); void drawShape(const int x, const int y, const int color1, const int color2); void drawStatusText(); diff --git a/engines/hugo/hugo.cpp b/engines/hugo/hugo.cpp index 97fe82c615..4a8b74fc1c 100644 --- a/engines/hugo/hugo.cpp +++ b/engines/hugo/hugo.cpp @@ -54,7 +54,7 @@ maze_t _maze; // Default to not in maze hugo_boot_t _boot; // Boot info structure file HugoEngine::HugoEngine(OSystem *syst, const HugoGameDescription *gd) : Engine(syst), _gameDescription(gd), - _arrayReqs(0), _hotspots(0), _invent(0), _uses(0), _catchallList(0), _backgroundObjects(0), _points(0), _cmdList(0), + _arrayReqs(0), _invent(0), _uses(0), _catchallList(0), _backgroundObjects(0), _points(0), _cmdList(0), _screenActs(0), _hero(0), _heroImage(0), _defltTunes(0), _introX(0), _introY(0), _maxInvent(0), _numBonuses(0), _numScreens(0), _tunesNbr(0), _soundSilence(0), _soundTest(0), _screenStates(0), _score(0), _maxscore(0), _backgroundObjectsSize(0), _screenActsSize(0), _usesSize(0), _lastTime(0), _curTime(0) @@ -90,7 +90,7 @@ HugoEngine::~HugoEngine() { free(_arrayReqs); } - free(_hotspots); + _mouse->freeHotspots(); free(_invent); if (_uses) { @@ -249,7 +249,7 @@ Common::Error HugoEngine::run() { _status.doQuitFl = false; while (!_status.doQuitFl) { - _screen->drawHotspots(); + _screen->drawBoundaries(); g_system->updateScreen(); runMachine(); @@ -413,28 +413,7 @@ bool HugoEngine::loadHugoDat() { // Read _arrayReqs _arrayReqs = loadLongArray(in); - // Read _hotspots - for (int varnt = 0; varnt < _numVariant; varnt++) { - int numRows = in.readUint16BE(); - hotspot_t *wrkHotspots = (hotspot_t *)malloc(sizeof(hotspot_t) * numRows); - - for (int i = 0; i < numRows; i++) { - wrkHotspots[i].screenIndex = in.readSint16BE(); - wrkHotspots[i].x1 = in.readSint16BE(); - wrkHotspots[i].y1 = in.readSint16BE(); - wrkHotspots[i].x2 = in.readSint16BE(); - wrkHotspots[i].y2 = in.readSint16BE(); - wrkHotspots[i].actIndex = in.readUint16BE(); - wrkHotspots[i].viewx = in.readSint16BE(); - wrkHotspots[i].viewy = in.readSint16BE(); - wrkHotspots[i].direction = in.readSint16BE(); - } - - if (varnt == _gameVariant) - _hotspots = wrkHotspots; - else - free(wrkHotspots); - } + _mouse->loadHotspots(in); int numElem, numSubElem; //Read _invent diff --git a/engines/hugo/hugo.h b/engines/hugo/hugo.h index 720e97e7bd..b73b24eccf 100644 --- a/engines/hugo/hugo.h +++ b/engines/hugo/hugo.h @@ -251,7 +251,6 @@ public: command_t _line; // Line of user text input config_t _config; // User's config uint16 **_arrayReqs; - hotspot_t *_hotspots; int16 *_invent; uses_t *_uses; uint16 _usesSize; diff --git a/engines/hugo/mouse.cpp b/engines/hugo/mouse.cpp index 73ba915192..9bbc60f04b 100644 --- a/engines/hugo/mouse.cpp +++ b/engines/hugo/mouse.cpp @@ -84,13 +84,12 @@ void MouseHandler::cursorText(const char *buffer, const int16 cx, const int16 cy * Find the exit hotspot containing cx, cy. * Return hotspot index or -1 if not found. */ -int16 MouseHandler::findExit(const int16 cx, const int16 cy) { - debugC(2, kDebugMouse, "findExit(%d, %d)", cx, cy); +int16 MouseHandler::findExit(const int16 cx, const int16 cy, byte screenId) { + debugC(2, kDebugMouse, "findExit(%d, %d, %d)", cx, cy, screenId); - int i = 0; - for (hotspot_t *hotspot = _vm->_hotspots; hotspot->screenIndex >= 0; i++, hotspot++) { - if (hotspot->screenIndex == *_vm->_screen_p) { - if (cx >= hotspot->x1 && cx <= hotspot->x2 && cy >= hotspot->y1 && cy <= hotspot->y2) + for (int i = 0; _hotspots[i].screenIndex >= 0; i++) { + if (_hotspots[i].screenIndex == screenId) { + if (cx >= _hotspots[i].x1 && cx <= _hotspots[i].x2 && cy >= _hotspots[i].y1 && cy <= _hotspots[i].y2) return i; } } @@ -174,20 +173,20 @@ void MouseHandler::processLeftClick(const int16 objId, const int16 cx, const int _vm->_screen->displayList(kDisplayAdd, 0, kDibOffY, kXPix, kInvDy); break; case kExitHotspot: // Walk to exit hotspot - i = findExit(cx, cy); - x = _vm->_hotspots[i].viewx; - y = _vm->_hotspots[i].viewy; + i = findExit(cx, cy, *_vm->_screen_p); + x = _hotspots[i].viewx; + y = _hotspots[i].viewy; if (x >= 0) { // Hotspot refers to an exit // Special case of immediate exit if (_jumpExitFl) { // Get rid of iconbar if necessary if (_vm->_inventory->getInventoryState() != kInventoryOff) _vm->_inventory->setInventoryState(kInventoryUp); - _vm->_scheduler->insertActionList(_vm->_hotspots[i].actIndex); + _vm->_scheduler->insertActionList(_hotspots[i].actIndex); } else { // Set up route to exit spot - if (_vm->_hotspots[i].direction == Common::KEYCODE_RIGHT) + if (_hotspots[i].direction == Common::KEYCODE_RIGHT) x -= kHeroMaxWidth; - else if (_vm->_hotspots[i].direction == Common::KEYCODE_LEFT) + else if (_hotspots[i].direction == Common::KEYCODE_LEFT) x += kHeroMaxWidth; if (!_vm->_route->startRoute(kRouteExit, i, x, y)) Utils::Box(kBoxAny, "%s", _vm->_text->getTextMouse(kMsNoWayText)); // Can't get there @@ -278,8 +277,8 @@ void MouseHandler::mouseHandler() { // Process cursor over an exit hotspot if (objId == -1) { - int i = findExit(cx, cy); - if (i != -1 && _vm->_hotspots[i].viewx >= 0) { + int i = findExit(cx, cy, *_vm->_screen_p); + if (i != -1 && _hotspots[i].viewx >= 0) { objId = kExitHotspot; cursorText(_vm->_text->getTextMouse(kMsExit), cx, cy, U_FONT8, _TBRIGHTWHITE); } @@ -294,4 +293,42 @@ void MouseHandler::mouseHandler() { resetRightButton(); } +/** + * Load hotspots data from hugo.dat + */ +void MouseHandler::loadHotspots(Common::ReadStream &in) { + // Read _hotspots + for (int varnt = 0; varnt < _vm->_numVariant; varnt++) { + int numRows = in.readUint16BE(); + hotspot_t *wrkHotspots = (hotspot_t *)malloc(sizeof(hotspot_t) * numRows); + + for (int i = 0; i < numRows; i++) { + wrkHotspots[i].screenIndex = in.readSint16BE(); + wrkHotspots[i].x1 = in.readSint16BE(); + wrkHotspots[i].y1 = in.readSint16BE(); + wrkHotspots[i].x2 = in.readSint16BE(); + wrkHotspots[i].y2 = in.readSint16BE(); + wrkHotspots[i].actIndex = in.readUint16BE(); + wrkHotspots[i].viewx = in.readSint16BE(); + wrkHotspots[i].viewy = in.readSint16BE(); + wrkHotspots[i].direction = in.readSint16BE(); + } + + if (varnt == _vm->_gameVariant) + _hotspots = wrkHotspots; + else + free(wrkHotspots); + } +} + +/** + * Display hotspot boundaries for the current screen + */ +void MouseHandler::drawHotspots() const { + for (int i = 0; _hotspots[i].screenIndex >= 0; i++) { + hotspot_t *hotspot = &_hotspots[i]; + if (hotspot->screenIndex == _vm->_hero->screenIndex) + _vm->_screen->drawRectangle(false, hotspot->x1, hotspot->y1, hotspot->x2, hotspot->y2, _TLIGHTRED); + } +} } // End of namespace Hugo diff --git a/engines/hugo/mouse.h b/engines/hugo/mouse.h index a335233ab7..eae13b48fb 100644 --- a/engines/hugo/mouse.h +++ b/engines/hugo/mouse.h @@ -46,11 +46,19 @@ public: void setJumpExitFl(bool fl) { _jumpExitFl = fl; } void setMouseX(int x) { _mouseX = x; } void setMouseY(int y) { _mouseY = y; } + void freeHotspots() { free(_hotspots); } bool getJumpExitFl() const { return _jumpExitFl; } int getMouseX() const { return _mouseX; } int getMouseY() const { return _mouseY; } + int16 getDirection(const int16 hotspotId) const { return _hotspots[hotspotId].direction; } + int16 getHotspotActIndex(const int16 hotspotId) const { return _hotspots[hotspotId].actIndex; } + + void drawHotspots() const; + int16 findExit(const int16 cx, const int16 cy, byte screenId); + void loadHotspots(Common::ReadStream &in); + private: HugoEngine *_vm; @@ -65,6 +73,7 @@ private: kMsExit = 1 }; + hotspot_t *_hotspots; bool _leftButtonFl; // Left mouse button pressed bool _rightButtonFl; // Right button pressed int _mouseX; @@ -72,7 +81,6 @@ private: bool _jumpExitFl; // Allowed to jump to a screen exit void cursorText(const char *buffer, const int16 cx, const int16 cy, const uif_t fontId, const int16 color); - int16 findExit(const int16 cx, const int16 cy); void processRightClick(const int16 objId, const int16 cx, const int16 cy); void processLeftClick(const int16 objId, const int16 cx, const int16 cy); }; diff --git a/engines/hugo/object.cpp b/engines/hugo/object.cpp index 1fa5293992..b909df45bb 100644 --- a/engines/hugo/object.cpp +++ b/engines/hugo/object.cpp @@ -44,6 +44,7 @@ #include "hugo/schedule.h" #include "hugo/text.h" #include "hugo/inventory.h" +#include "hugo/mouse.h" namespace Hugo { @@ -746,14 +747,10 @@ void ObjectHandler::boundaryCollision(object_t *obj) { x = obj->x + obj->currImagePtr->x1; int y = obj->y + obj->currImagePtr->y2; - for (int i = 0; _vm->_hotspots[i].screenIndex >= 0; i++) { - hotspot_t *hotspot = &_vm->_hotspots[i]; - if (hotspot->screenIndex == obj->screenIndex) - if ((x >= hotspot->x1) && (x <= hotspot->x2) && (y >= hotspot->y1) && (y <= hotspot->y2)) { - _vm->_scheduler->insertActionList(hotspot->actIndex); - break; - } - } + int16 index = _vm->_mouse->findExit(x, y, obj->screenIndex); + if (index >= 0) + _vm->_scheduler->insertActionList(_vm->_mouse->getHotspotActIndex(index)); + } else { // Check whether an object collided with HERO int dx = _vm->_hero->x + _vm->_hero->currImagePtr->x1 - obj->x - obj->currImagePtr->x1; diff --git a/engines/hugo/route.cpp b/engines/hugo/route.cpp index fd7bb84a9d..c122439c70 100644 --- a/engines/hugo/route.cpp +++ b/engines/hugo/route.cpp @@ -39,13 +39,14 @@ #include "hugo/route.h" #include "hugo/object.h" #include "hugo/inventory.h" +#include "hugo/mouse.h" namespace Hugo { Route::Route(HugoEngine *vm) : _vm(vm) { _oldWalkDirection = 0; _routeIndex = -1; // Hero not following a route - _go_for = kRouteSpace; // Hero walking to space - _go_id = -1; // Hero not walking to anything + _routeType = kRouteSpace; // Hero walking to space + _routeObjId = -1; // Hero not walking to anything } /** @@ -442,26 +443,26 @@ void Route::processRoute() { // Arrived at final node? if (--_routeIndex < 0) { // See why we walked here - switch (_go_for) { + switch (_routeType) { case kRouteExit: // Walked to an exit, proceed into it - setWalk(_vm->_hotspots[_go_id].direction); + setWalk(_vm->_mouse->getDirection(_routeObjId)); break; case kRouteLook: // Look at an object if (turnedFl) { - _vm->_object->lookObject(&_vm->_object->_objects[_go_id]); + _vm->_object->lookObject(&_vm->_object->_objects[_routeObjId]); turnedFl = false; } else { - setDirection(_vm->_object->_objects[_go_id].direction); + setDirection(_vm->_object->_objects[_routeObjId].direction); _routeIndex++; // Come round again turnedFl = true; } break; case kRouteGet: // Get (or use) an object if (turnedFl) { - _vm->_object->useObject(_go_id); + _vm->_object->useObject(_routeObjId); turnedFl = false; } else { - setDirection(_vm->_object->_objects[_go_id].direction); + setDirection(_vm->_object->_objects[_routeObjId].direction); _routeIndex++; // Come round again turnedFl = true; } @@ -493,8 +494,8 @@ void Route::processRoute() { * go_for is the purpose, id indexes the exit or object to walk to * Returns FALSE if route not found */ -bool Route::startRoute(const go_t go_for, const int16 id, int16 cx, int16 cy) { - debugC(1, kDebugRoute, "startRoute(%d, %d, %d, %d)", go_for, id, cx, cy); +bool Route::startRoute(const go_t routeType, const int16 objId, int16 cx, int16 cy) { + debugC(1, kDebugRoute, "startRoute(%d, %d, %d, %d)", routeType, objId, cx, cy); // Don't attempt to walk if user does not have control if (_vm->_hero->pathType != kPathUser) @@ -504,11 +505,11 @@ bool Route::startRoute(const go_t go_for, const int16 id, int16 cx, int16 cy) { if (_vm->_inventory->getInventoryState() != kInventoryOff) _vm->_inventory->setInventoryState(kInventoryUp); - _go_for = go_for; // Purpose of trip - _go_id = id; // Index of exit/object + _routeType = routeType; // Purpose of trip + _routeObjId = objId; // Index of exit/object // Adjust destination to center hero if walking to cursor - if (_go_for == kRouteSpace) + if (_routeType == kRouteSpace) cx -= kHeroMinWidth / 2; bool foundFl = false; // TRUE if route found ok diff --git a/engines/hugo/route.h b/engines/hugo/route.h index 5b1eb9bff4..727c7d77eb 100644 --- a/engines/hugo/route.h +++ b/engines/hugo/route.h @@ -58,7 +58,7 @@ public: int16 getRouteIndex() const {return _routeIndex; } void processRoute(); - bool startRoute(const go_t go_for, const int16 id, int16 cx, int16 cy); + bool startRoute(const go_t routeType, const int16 objId, int16 cx, int16 cy); void setDirection(const uint16 keyCode); void setWalk(const uint16 direction); @@ -73,8 +73,8 @@ private: uint16 _oldWalkDirection; // Last direction char int16 _routeIndex; // Index into route list, or -1 - go_t _go_for; // Purpose of an automatic route - int16 _go_id; // Index of exit of object walking to + go_t _routeType; // Purpose of an automatic route + int16 _routeObjId; // Index of exit of object walking to byte _boundaryMap[kYPix][kXPix]; // Boundary byte map segment_t _segment[kMaxSeg]; // List of points in fill-path |