From 694758fd2a0e98513c436e02cdf13d690fe9565d Mon Sep 17 00:00:00 2001 From: Arnaud Boutonné Date: Sun, 3 Oct 2010 08:08:42 +0000 Subject: HUGO: Clean-up svn-id: r52988 --- engines/hugo/route.cpp | 149 ++++++++++++++++++++++++++----------------------- 1 file changed, 80 insertions(+), 69 deletions(-) (limited to 'engines/hugo/route.cpp') diff --git a/engines/hugo/route.cpp b/engines/hugo/route.cpp index deb4dc27d5..9b3d929543 100644 --- a/engines/hugo/route.cpp +++ b/engines/hugo/route.cpp @@ -45,10 +45,10 @@ Route::Route(HugoEngine &vm) : _vm(vm) { // Face hero in new direction, based on cursor key input by user. void Route::setDirection(uint16 keyCode) { - object_t *obj = _vm._hero; // Pointer to hero object - debugC(1, kDebugRoute, "setDirection(%d)", keyCode); + object_t *obj = _vm._hero; // Pointer to hero object + // Set first image in sequence switch (keyCode) { case Common::KEYCODE_UP: @@ -81,11 +81,11 @@ void Route::setDirection(uint16 keyCode) { // Set hero walking, based on cursor key input by user. // Hitting same key twice will stop hero. void Route::setWalk(uint16 direction) { - object_t *obj = _vm._hero; // Pointer to hero object - static uint16 oldDirection = 0; // Last direction char - debugC(1, kDebugRoute, "setWalk(%d)", direction); + static uint16 oldDirection = 0; // Last direction char + object_t *obj = _vm._hero; // Pointer to hero object + if (_vm.getGameStatus().storyModeFl || obj->pathType != USER) // Make sure user has control return; @@ -148,13 +148,12 @@ void Route::setWalk(uint16 direction) { // around this, make sure any narrow gaps are 2 or more pixels high. // An example of this was the blocking guard in Hugo1/Dead-End. void Route::segment(int16 x, int16 y) { - int16 x1, x2; // Range of segment + debugC(1, kDebugRoute, "segment(%d, %d)", x, y); + // Note use of static - can't waste stack static image_pt p; // Ptr to _boundaryMap[y] static segment_t *seg_p; // Ptr to segment - debugC(1, kDebugRoute, "segment(%d, %d)", x, y); - // Bomb out if stack exhausted // Vinterstum: Is this just a safeguard, or actually used? //_fullStackFl = _stackavail () < 256; @@ -162,16 +161,21 @@ void Route::segment(int16 x, int16 y) { // Find and fill on either side of point p = _boundaryMap[y]; - for (x1 = x; x1 > 0; x1--) + int16 x1, x2; // Range of segment + for (x1 = x; x1 > 0; x1--) { if (p[x1] == 0) { p[x1] = kMapFill; - } else + } else { break; - for (x2 = x + 1; x2 < XPIX; x2++) + } + } + for (x2 = x + 1; x2 < XPIX; x2++) { if (p[x2] == 0) { p[x2] = kMapFill; - } else + } else { break; + } + } x1++; x2--; @@ -190,48 +194,59 @@ void Route::segment(int16 x, int16 y) { if (_vm._hero->x < x1) { // Hero x not in segment, search x1..x2 // Find all segments above current - for (x = x1; !(_routeFoundFl | _fullStackFl | _fullSegmentFl) && x <= x2; x++) + for (x = x1; !(_routeFoundFl | _fullStackFl | _fullSegmentFl) && x <= x2; x++) { if (_boundaryMap[y - 1][x] == 0) segment(x, y - 1); + } // Find all segments below current - for (x = x1; !(_routeFoundFl | _fullStackFl | _fullSegmentFl) && x <= x2; x++) + for (x = x1; !(_routeFoundFl | _fullStackFl | _fullSegmentFl) && x <= x2; x++) { if (_boundaryMap[y + 1][x] == 0) segment(x, y + 1); + } } else if (_vm._hero->x + HERO_MAX_WIDTH > x2) { // Hero x not in segment, search x1..x2 // Find all segments above current - for (x = x2; !(_routeFoundFl | _fullStackFl | _fullSegmentFl) && x >= x1; x--) + for (x = x2; !(_routeFoundFl | _fullStackFl | _fullSegmentFl) && x >= x1; x--) { if (_boundaryMap[y - 1][x] == 0) segment(x, y - 1); + } // Find all segments below current - for (x = x2; !(_routeFoundFl | _fullStackFl | _fullSegmentFl) && x >= x1; x--) + for (x = x2; !(_routeFoundFl | _fullStackFl | _fullSegmentFl) && x >= x1; x--) { if (_boundaryMap[y + 1][x] == 0) segment(x, y + 1); + } } else { // Organize search around hero x position - this gives // better chance for more direct route. - for (x = _vm._hero->x; !(_routeFoundFl | _fullStackFl | _fullSegmentFl) && x <= x2; x++) + for (x = _vm._hero->x; !(_routeFoundFl | _fullStackFl | _fullSegmentFl) && x <= x2; x++) { if (_boundaryMap[y - 1][x] == 0) segment(x, y - 1); - for (x = x1; !(_routeFoundFl | _fullStackFl | _fullSegmentFl) && x < _vm._hero->x; x++) + } + + for (x = x1; !(_routeFoundFl | _fullStackFl | _fullSegmentFl) && x < _vm._hero->x; x++) { if (_boundaryMap[y - 1][x] == 0) segment(x, y - 1); - for (x = _vm._hero->x; !(_routeFoundFl | _fullStackFl | _fullSegmentFl) && x <= x2; x++) + } + + for (x = _vm._hero->x; !(_routeFoundFl | _fullStackFl | _fullSegmentFl) && x <= x2; x++) { if (_boundaryMap[y + 1][x] == 0) segment(x, y + 1); - for (x = x1; !(_routeFoundFl | _fullStackFl | _fullSegmentFl) && x < _vm._hero->x; x++) + } + + for (x = x1; !(_routeFoundFl | _fullStackFl | _fullSegmentFl) && x < _vm._hero->x; x++) { if (_boundaryMap[y + 1][x] == 0) segment(x, y + 1); + } } // If found, surface, leaving trail back to hero if (_routeFoundFl) { // Bomb out if too many segments (leave one spare) - if (_segmentNumb >= kMaxSeg - 1) + if (_segmentNumb >= kMaxSeg - 1) { _fullSegmentFl = true; - else { + } else { // Create segment seg_p = &_segment[_segmentNumb]; seg_p->y = y; @@ -243,15 +258,15 @@ void Route::segment(int16 x, int16 y) { } // Create and return ptr to new node. Initialize with previous node. -// Returns NULL if MAX_NODES exceeded +// Returns 0 if MAX_NODES exceeded Point *Route::newNode() { debugC(1, kDebugRoute, "newNode"); if (_routeListIndex >= kMaxNodes) // Too many nodes - return(NULL); // Incomplete route - failure + return 0; // Incomplete route - failure _routeListIndex++; _route[_routeListIndex] = _route[_routeListIndex - 1]; // Initialize with previous node - return(&_route[_routeListIndex]); + return &_route[_routeListIndex]; } // Construct route to cx, cy. Return TRUE if successful. @@ -259,13 +274,6 @@ Point *Route::newNode() { // 2. Construct list of segments segment[] from hero to destination // 3. Compress to shortest route in route[] bool Route::findRoute(int16 cx, int16 cy) { - int16 i, j, x, y; // Loop on coordinates - int16 x1, x2, dx; // Overlap between segments - int16 herox1, herox2, heroy; // Current hero baseline - object_t *obj; // Ptr to object - segment_t *seg_p; // Ptr to segment - Point *routeNode; // Ptr to route node - debugC(1, kDebugRoute, "findRoute(%d, %d)", cx, cy); // Initialize for search @@ -276,32 +284,39 @@ bool Route::findRoute(int16 cx, int16 cy) { _heroWidth = HERO_MIN_WIDTH; // Minimum width of hero _destY = cy; // Destination coords _destX = cx; // Destination coords - herox1 = _vm._hero->x + _vm._hero->currImagePtr->x1; // Hero baseline - herox2 = _vm._hero->x + _vm._hero->currImagePtr->x2; // Hero baseline - heroy = _vm._hero->y + _vm._hero->currImagePtr->y2; // Hero baseline + + int16 herox1 = _vm._hero->x + _vm._hero->currImagePtr->x1; // Hero baseline + int16 herox2 = _vm._hero->x + _vm._hero->currImagePtr->x2; // Hero baseline + int16 heroy = _vm._hero->y + _vm._hero->currImagePtr->y2; // Hero baseline // Store all object baselines into objbound (except hero's = [0]) - for (i = 1, obj = &_vm._objects[i]; i < _vm._numObj; i++, obj++) + object_t *obj; // Ptr to object + int i; + for (i = 1, obj = &_vm._objects[i]; i < _vm._numObj; i++, obj++) { if ((obj->screenIndex == *_vm._screen_p) && (obj->cycling != INVISIBLE) && (obj->priority == FLOATING)) _vm.storeBoundary(obj->oldx + obj->currImagePtr->x1, obj->oldx + obj->currImagePtr->x2, obj->oldy + obj->currImagePtr->y2); + } // Combine objbound and boundary bitmaps to local byte map - for (y = 0; y < YPIX; y++) - for (x = 0; x < XBYTES; x++) + for (int16 y = 0; y < YPIX; y++) { + for (int16 x = 0; x < XBYTES; x++) { for (i = 0; i < 8; i++) _boundaryMap[y][x * 8 + i] = ((_vm.getObjectBoundaryOverlay()[y * XBYTES + x] | _vm.getBoundaryOverlay()[y * XBYTES + x]) & (0x80 >> i)) ? kMapBound : 0; - + } + } + // Clear all object baselines from objbound - for (i = 0, obj = _vm._objects; i < _vm._numObj; i++, obj++) + for (i = 0, obj = _vm._objects; i < _vm._numObj; i++, obj++) { if ((obj->screenIndex == *_vm._screen_p) && (obj->cycling != INVISIBLE) && (obj->priority == FLOATING)) _vm.clearBoundary(obj->oldx + obj->currImagePtr->x1, obj->oldx + obj->currImagePtr->x2, obj->oldy + obj->currImagePtr->y2); - + } + // Search from hero to destination segment(herox1, heroy); // Not found or not enough stack or MAX_SEG exceeded if (!_routeFoundFl || _fullStackFl || _fullSegmentFl) { - return(false); + return false; } // Now find the route of nodes from destination back to hero @@ -315,29 +330,30 @@ bool Route::findRoute(int16 cx, int16 cy) { _segment[_segmentNumb].x2 = herox2; _segmentNumb++; + Point *routeNode; // Ptr to route node // Look in segments[] for straight lines from destination to hero for (i = 0, _routeListIndex = 0; i < _segmentNumb - 1; i++) { - if ((routeNode = newNode()) == NULL) // New node for new segment - return(false); // Too many nodes + if ((routeNode = newNode()) == 0) // New node for new segment + return false; // Too many nodes routeNode->y = _segment[i].y; // Look ahead for furthest straight line - for (j = i + 1; j < _segmentNumb; j++) { - seg_p = &_segment[j]; + for (int16 j = i + 1; j < _segmentNumb; j++) { + segment_t *seg_p = &_segment[j]; // Can we get to this segment from previous node? - if (seg_p->x1 <= routeNode->x && seg_p->x2 >= routeNode->x + _heroWidth - 1) + if (seg_p->x1 <= routeNode->x && seg_p->x2 >= routeNode->x + _heroWidth - 1) { routeNode->y = seg_p->y; // Yes, keep updating node - else { + } else { // No, create another node on previous segment to reach it - if ((routeNode = newNode()) == NULL) // Add new route node - return (false); // Too many nodes + if ((routeNode = newNode()) == 0) // Add new route node + return false; // Too many nodes // Find overlap between old and new segments - x1 = MAX(_segment[j - 1].x1, seg_p->x1); - x2 = MIN(_segment[j - 1].x2, seg_p->x2); + int16 x1 = MAX(_segment[j - 1].x1, seg_p->x1); + int16 x2 = MIN(_segment[j - 1].x2, seg_p->x2); // If room, add a little offset to reduce staircase effect - dx = HERO_MAX_WIDTH >> 1; + int16 dx = HERO_MAX_WIDTH >> 1; if (x2 - x1 < _heroWidth + dx) dx = 0; @@ -364,18 +380,15 @@ bool Route::findRoute(int16 cx, int16 cy) { // Process hero in route mode - called from Move_objects() void Route::processRoute() { - int16 herox, heroy; // Hero position - Point *routeNode; // Ptr to current route node - static bool turnedFl = false; // Used to get extra cylce for turning - - status_t &gameStatus = _vm.getGameStatus(); - debugC(1, kDebugRoute, "processRoute"); + static bool turnedFl = false; // Used to get extra cylce for turning + // Current hero position - herox = _vm._hero->x + _vm._hero->currImagePtr->x1; - heroy = _vm._hero->y + _vm._hero->currImagePtr->y2; - routeNode = &_route[gameStatus.routeIndex]; + int16 herox = _vm._hero->x + _vm._hero->currImagePtr->x1; + int16 heroy = _vm._hero->y + _vm._hero->currImagePtr->y2; + status_t &gameStatus = _vm.getGameStatus(); + Point *routeNode = &_route[gameStatus.routeIndex]; // Arrived at node? if (abs(herox - routeNode->x) < DX + 1 && abs(heroy - routeNode->y) < DY) { @@ -422,11 +435,11 @@ void Route::processRoute() { // Set direction of travel if at a node // Note realignment when changing to (thinner) up/down sprite, // otherwise hero could bump into boundaries along route. - if (herox < routeNode->x) + if (herox < routeNode->x) { setWalk(Common::KEYCODE_RIGHT); - else if (herox > routeNode->x) + } else if (herox > routeNode->x) { setWalk(Common::KEYCODE_LEFT); - else if (heroy < routeNode->y) { + } else if (heroy < routeNode->y) { setWalk(Common::KEYCODE_DOWN); _vm._hero->x = _vm._hero->oldx = routeNode->x - _vm._hero->currImagePtr->x1; } else if (heroy > routeNode->y) { @@ -440,16 +453,13 @@ 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(go_t go_for, int16 id, int16 cx, int16 cy) { - bool foundFl = false; // TRUE if route found ok - - status_t &gameStatus = _vm.getGameStatus(); - debugC(1, kDebugRoute, "startRoute(%d, %d, %d, %d)", go_for, id, cx, cy); // Don't attempt to walk if user does not have control if (_vm._hero->pathType != USER) return false; + status_t &gameStatus = _vm.getGameStatus(); // if inventory showing, make it go away if (gameStatus.inventoryState != I_OFF) gameStatus.inventoryState = I_UP; @@ -461,6 +471,7 @@ bool Route::startRoute(go_t go_for, int16 id, int16 cx, int16 cy) { if (gameStatus.go_for == GO_SPACE) cx -= HERO_MIN_WIDTH / 2; + bool foundFl = false; // TRUE if route found ok if ((foundFl = findRoute(cx, cy))) { // Found a route? gameStatus.routeIndex = _routeListIndex; // Node index _vm._hero->vx = _vm._hero->vy = 0; // Stop manual motion -- cgit v1.2.3