diff options
author | Nicola Mettifogo | 2007-03-20 19:45:17 +0000 |
---|---|---|
committer | Nicola Mettifogo | 2007-03-20 19:45:17 +0000 |
commit | 9494a9f02522be5c25b980a36d00a4d6710ece02 (patch) | |
tree | b5af7defadbea558496488fc253f2f9c7f63e71b /engines/parallaction/walk.cpp | |
parent | abf59db15e375b34a75e1bf637982a267b9ecce9 (diff) | |
download | scummvm-rg350-9494a9f02522be5c25b980a36d00a4d6710ece02.tar.gz scummvm-rg350-9494a9f02522be5c25b980a36d00a4d6710ece02.tar.bz2 scummvm-rg350-9494a9f02522be5c25b980a36d00a4d6710ece02.zip |
some refactoring for walking code
svn-id: r26260
Diffstat (limited to 'engines/parallaction/walk.cpp')
-rw-r--r-- | engines/parallaction/walk.cpp | 234 |
1 files changed, 122 insertions, 112 deletions
diff --git a/engines/parallaction/walk.cpp b/engines/parallaction/walk.cpp index 0c36c1190f..311a65904e 100644 --- a/engines/parallaction/walk.cpp +++ b/engines/parallaction/walk.cpp @@ -41,74 +41,81 @@ static Zone *_zoneTrap = NULL; static uint16 walkData1 = 0; static uint16 walkData2 = 0; // next walk frame +#if 0 static int16 walkData3 = -1000; // unused - +#endif int32 dotProduct(const Common::Point &p1, const Common::Point &p2) { return p1.x * p2.x + p1.y * p2.y; } +// adjusts position towards nearest walkable point // -// x, y: mouse click (foot) coordinates -// -WalkNode *buildWalkPath(uint16 x, uint16 y) { - debugC(1, kDebugWalk, "buildWalkPath to (%i, %i)", x, y); - - Common::Point to(x, y); - - int16 left, bottom, right, top, close, closeY, closeX; - - // looks for closest usable path Point - if (queryPath(to.x, to.y) == 0) { +void correctPathPoint(Common::Point &to) { - right = left = to.x; + if (queryPath(to.x, to.y)) return; - do { - right++; - } while ((queryPath(right, to.y) == 0) && (right < SCREEN_WIDTH)); - - do { - left--; - } while ((queryPath(left, to.y) == 0) && (left > 0)); - - right = (right == SCREEN_WIDTH) ? 1000 : right - to.x; - left = (left == 0) ? 1000 : to.x - left; - - top = bottom = to.y; - - do { - top--; - } while ((queryPath(to.x, top) == 0) && (top > 0)); + int16 right = to.x; + int16 left = to.x; + do { + right++; + } while ((queryPath(right, to.y) == 0) && (right < SCREEN_WIDTH)); + do { + left--; + } while ((queryPath(left, to.y) == 0) && (left > 0)); + right = (right == SCREEN_WIDTH) ? 1000 : right - to.x; + left = (left == 0) ? 1000 : to.x - left; - do { - bottom++; - } while ((queryPath(to.x, bottom) == 0) && (bottom < SCREEN_HEIGHT)); - top = (top == 0) ? 1000 : to.y - top; - bottom = (bottom == SCREEN_HEIGHT) ? 1000 : bottom - to.y; + int16 top = to.y; + int16 bottom = to.y; + do { + top--; + } while ((queryPath(to.x, top) == 0) && (top > 0)); + do { + bottom++; + } while ((queryPath(to.x, bottom) == 0) && (bottom < SCREEN_HEIGHT)); + top = (top == 0) ? 1000 : to.y - top; + bottom = (bottom == SCREEN_HEIGHT) ? 1000 : bottom - to.y; + + + int16 closeX = (right >= left) ? left : right; + int16 closeY = (top >= bottom) ? bottom : top; + int16 close = (closeX >= closeY) ? closeY : closeX; + if (close == right) { + to.x += right; +#if 0 + walkData3 = (_vm->_char._ani.getFrameNum() == 20) ? 7 : 9; +#endif + } else + if (close == left) { + to.x -= left; +#if 0 + walkData3 = 0; +#endif + } else + if (close == top) { + to.y -= top; + } else + if (close == bottom) { + to.y += bottom; +#if 0 + walkData3 = (_vm->_char._ani.getFrameNum() == 20) ? 17 : 21; +#endif + } - closeX = (right >= left) ? left : right; - closeY = (top >= bottom) ? bottom : top; + return; - close = (closeX >= closeY) ? closeY : closeX; +} - if (close == right) { - to.x += right; - walkData3 = (_vm->_char._ani.getFrameNum() == 20) ? 7 : 9; - } else - if (close == left) { - to.x -= left; - walkData3 = 0; - } else - if (close == top) { - to.y -= top; - } else - if (close == bottom) { - to.y += bottom; - walkData3 = (_vm->_char._ani.getFrameNum() == 20) ? 17 : 21; - } +// +// x, y: mouse click (foot) coordinates +// +WalkNode *buildWalkPath(uint16 x, uint16 y) { + debugC(1, kDebugWalk, "buildWalkPath to (%i, %i)", x, y); - } + Common::Point to(x, y); + correctPathPoint(to); debugC(1, kDebugWalk, "found closest path point at (%i, %i)", to.x, to.y); WalkNode *v48 = new WalkNode(to.x - _vm->_char._ani.width() / 2, to.y - _vm->_char._ani.height()); @@ -225,8 +232,8 @@ WalkNode *buildWalkPath(uint16 x, uint16 y) { // x,y : top left coordinates // // 0 : Point not reachable -// 1 : Point reachable -// other values: square distance to target (not reachable) +// 1 : Point reachable in a straight line +// other values: square distance to target (point not reachable in a straight line) // uint16 walkFunc1(int16 x, int16 y, WalkNode *Node) { @@ -281,40 +288,30 @@ uint16 walkFunc1(int16 x, int16 y, WalkNode *Node) { return 1; } +void clipMove(Common::Point& pos, const WalkNode* from) { -void jobWalk(void *parm, Job *j) { - WalkNode *node = (WalkNode*)parm; - - int16 _si = _vm->_char._ani._left; - int16 _di = _vm->_char._ani._top; - -// debugC(1, kDebugWalk, "jobWalk to (%i, %i)", node->_x + _vm->_char._ani.width() / 2, node->_y + _vm->_char._ani.height()); - - _vm->_char._ani._oldLeft = _si; - _vm->_char._ani._oldTop = _di; - - if ((node->_x == _si) && (node->_y == _di)) { - if (node->_next == NULL) { - - debugC(1, kDebugWalk, "jobWalk reached last node"); + if ((pos.x < from->_x) && (pos.x < SCREEN_WIDTH) && (queryPath(_vm->_char._ani.width()/2 + pos.x + 2, _vm->_char._ani.height() + pos.y) != 0)) { + pos.x = (pos.x + 2 < from->_x) ? pos.x + 2 : from->_x; + } - j->_finished = 1; - checkDoor(); - free(node); - return; - } + if ((pos.x > from->_x) && (pos.x > -20) && (queryPath(_vm->_char._ani.width()/2 + pos.x - 2, _vm->_char._ani.height() + pos.y) != 0)) { + pos.x = (pos.x - 2 > from->_x) ? pos.x - 2 : from->_x; + } + if ((pos.y < from->_y) && (pos.y < (SCREEN_HEIGHT - _vm->_char._ani.height())) && (queryPath(_vm->_char._ani.width()/2 + pos.x, _vm->_char._ani.height() + pos.y + 2) != 0)) { + pos.y = (pos.y + 2 <= from->_y) ? pos.y + 2 : from->_y; + } - WalkNode *tmp = (WalkNode*)node->_next; - j->_parm = node->_next; - free(node); + if ((pos.y > from->_y) && (pos.y > -20) && (queryPath(_vm->_char._ani.width()/2 + pos.x, _vm->_char._ani.height() + pos.y- 2) != 0)) { + pos.y = (pos.y - 2 >= from->_y) ? pos.y - 2 :from->_y; + } - debugC(1, kDebugWalk, "jobWalk moving to next node (%i, %i)", tmp->_x, tmp->_y); + return; +} - node = (WalkNode*)tmp; - } +int16 selectWalkFrame(const Common::Point& pos, const WalkNode* from) { - Common::Point dist(node->_x - _vm->_char._ani._left, node->_y - _vm->_char._ani._top); + Common::Point dist(from->_x - pos.x, from->_y - pos.y); if (dist.x < 0) dist.x = -dist.x; @@ -328,11 +325,11 @@ void jobWalk(void *parm, Job *j) { if (_vm->_char._ani.getFrameNum() == 20) { if (dist.x > dist.y) { - walkData2 = (node->_x > _si) ? 0 : 7; + walkData2 = (from->_x > pos.x) ? 0 : 7; walkData1 %= 12; v16 = walkData1 / 2; } else { - walkData2 = (node->_y > _di) ? 14 : 17; + walkData2 = (from->_y > pos.y) ? 14 : 17; walkData1 %= 8; v16 = walkData1 / 4; } @@ -340,57 +337,69 @@ void jobWalk(void *parm, Job *j) { } else { if (dist.x > dist.y) { - walkData2 = (node->_x > _si) ? 0 : 9; + walkData2 = (from->_x > pos.x) ? 0 : 9; walkData1 %= 16; v16 = walkData1 / 2; } else { - walkData2 = (node->_y > _di) ? 18 : 21; + walkData2 = (from->_y > pos.y) ? 18 : 21; walkData1 %= 8; v16 = walkData1 / 4; } } -// StaticCnv v14; -// v14._width = _vm->_char._ani.width(); -// v14._height = _vm->_char._ani.height(); -// v14._data0 = _vm->_char._ani._cnv._array[_vm->_char._ani._frame]; -// v14._data1 = _vm->_char._ani._cnv.field_8[_vm->_char._ani._frame]; + return v16; +} - if ((_si < node->_x) && (_si < SCREEN_WIDTH) && (queryPath(_vm->_char._ani.width()/2 + _si + 2, _vm->_char._ani.height() + _di) != 0)) { -// printf("walk right\n"); - _si = (_si + 2 < node->_x) ? _si + 2 : node->_x; - } +WalkNode* getNextPathNode(const Common::Point& pos, WalkNode* curNode) { - if ((_si > node->_x) && (_si > -20) && (queryPath(_vm->_char._ani.width()/2 + _si - 2, _vm->_char._ani.height() + _di) != 0)) { -// printf("walk left\n"); - _si = (_si - 2 > node->_x) ? _si - 2 :node->_x; - } + if ((curNode->_x == pos.x) && (curNode->_y == pos.y)) { + + if (curNode->_next == NULL) return NULL; + + WalkNode *tmp = curNode; + curNode = (WalkNode*)curNode->_next; + free(tmp); - if ((_di < node->_y) && (_di < (SCREEN_HEIGHT - _vm->_char._ani.height())) && (queryPath(_vm->_char._ani.width()/2 + _si, _vm->_char._ani.height() + _di + 2) != 0)) { -// printf("walk down\n"); - _di = (_di + 2 <= node->_y) ? _di + 2 : node->_y; + debugC(1, kDebugWalk, "jobWalk moving to next node (%i, %i)", tmp->_x, tmp->_y); } - if ((_di > node->_y) && (_di > -20) && (queryPath(_vm->_char._ani.width()/2 + _si, _vm->_char._ani.height() + _di - 2) != 0)) { -// printf("walk up\n"); - _di = (_di - 2 >= node->_y) ? _di - 2 : node->_y; + return curNode; + +} + +void jobWalk(void *parm, Job *j) { + WalkNode *node = (WalkNode*)parm; + + Common::Point pos(_vm->_char._ani._left, _vm->_char._ani._top); + + _vm->_char._ani._oldLeft = pos.x; + _vm->_char._ani._oldTop = pos.y; + + node = getNextPathNode(pos, node); + if (node == NULL) { + debugC(1, kDebugWalk, "jobWalk reached last node"); + j->_finished = 1; + checkDoor(); + free(node); + return; } + j->_parm = node; + + // selectWalkFrame must be performed before position is changed by clipMove + int16 v16 = selectWalkFrame(pos, node); -// printf("hitZone: %i, %i\n", _si, _di); - _vm->_char._ani._left = _si; - _vm->_char._ani._top = _di; + clipMove(pos, node); - if ((_si == _vm->_char._ani._oldLeft) && (_di == _vm->_char._ani._oldTop)) { + _vm->_char._ani._left = pos.x; + _vm->_char._ani._top = pos.y; + if ((pos.x == _vm->_char._ani._oldLeft) && (pos.y == _vm->_char._ani._oldTop)) { j->_finished = 1; checkDoor(); freeNodeList(node); - } else { - _vm->_char._ani._frame = v16 + walkData2 + 1; - } return; @@ -465,3 +474,4 @@ void initWalk() { } // namespace Parallaction + |