diff options
Diffstat (limited to 'engines/parallaction')
-rw-r--r-- | engines/parallaction/animation.cpp | 12 | ||||
-rw-r--r-- | engines/parallaction/commands.cpp | 4 | ||||
-rw-r--r-- | engines/parallaction/intro.cpp | 2 | ||||
-rw-r--r-- | engines/parallaction/inventory.cpp | 1 | ||||
-rw-r--r-- | engines/parallaction/location.cpp | 13 | ||||
-rw-r--r-- | engines/parallaction/parallaction.cpp | 8 | ||||
-rw-r--r-- | engines/parallaction/parallaction.h | 20 | ||||
-rw-r--r-- | engines/parallaction/saveload.cpp | 12 | ||||
-rw-r--r-- | engines/parallaction/staticres.cpp | 2 | ||||
-rw-r--r-- | engines/parallaction/walk.cpp | 128 | ||||
-rw-r--r-- | engines/parallaction/walk.h | 23 | ||||
-rw-r--r-- | engines/parallaction/zone.cpp | 1 |
12 files changed, 114 insertions, 112 deletions
diff --git a/engines/parallaction/animation.cpp b/engines/parallaction/animation.cpp index d084e85567..83977617e6 100644 --- a/engines/parallaction/animation.cpp +++ b/engines/parallaction/animation.cpp @@ -152,6 +152,7 @@ Animation *Parallaction::parseAnimation(Script& script, Node *list, char *name) void Parallaction::freeAnimations() { Animation *v4 = (Animation*)_animations._next; + while (v4) { Animation *v = (Animation*)v4->_next; delete v4; @@ -462,7 +463,6 @@ void jobRunScripts(void *parm, Job *j) { Animation *a = (Animation*)_vm->_animations._next; StaticCnv v18; - WalkNode *v4 = NULL; if (a->_flags & kFlagsCharacter) a->_z = a->_top + a->height(); for ( ; a; a = (Animation*)a->_next) { @@ -539,10 +539,11 @@ void jobRunScripts(void *parm, Job *j) { } break; - case INST_MOVE: // move - v4 = buildWalkPath(*(*inst)->_opA._pvalue, *(*inst)->_opB._pvalue); + case INST_MOVE: { // move + WalkNodeList *v4 = _vm->_char._builder.buildPath(*(*inst)->_opA._pvalue, *(*inst)->_opB._pvalue); _vm->addJob(&jobWalk, v4, kPriority19 ); _engineFlags |= kEngineWalking; + } break; case INST_PUT: // put @@ -631,7 +632,6 @@ void wrapLocalVar(LocalVariable *local) { void Parallaction::sortAnimations() { Node v14; - memset(&v14, 0, sizeof(Node)); _char._ani._z = _char._ani.height() + _char._ani._top; @@ -654,8 +654,8 @@ void Parallaction::sortAnimations() { vC = v4; } - memcpy(&_animations, &v14, sizeof(Node)); - + _animations._prev = v14._prev; + _animations._next = v14._next; _animations._next->_prev = &_animations; return; diff --git a/engines/parallaction/commands.cpp b/engines/parallaction/commands.cpp index 340019491f..087abed156 100644 --- a/engines/parallaction/commands.cpp +++ b/engines/parallaction/commands.cpp @@ -20,6 +20,8 @@ * */ +#include "common/stdafx.h" + #include "parallaction/parallaction.h" #include "parallaction/parser.h" #include "parallaction/commands.h" @@ -312,7 +314,7 @@ void Parallaction::runCommands(CommandList& list, Zone *z) { continue; } - WalkNode *vC = buildWalkPath(u->_move._x, u->_move._y); + WalkNodeList *vC = _vm->_char._builder.buildPath(u->_move._x, u->_move._y); addJob(&jobWalk, vC, kPriority19 ); _engineFlags |= kEngineWalking; diff --git a/engines/parallaction/intro.cpp b/engines/parallaction/intro.cpp index eec52673a3..6995b41644 100644 --- a/engines/parallaction/intro.cpp +++ b/engines/parallaction/intro.cpp @@ -20,6 +20,8 @@ * */ +#include "common/stdafx.h" + #include "parallaction/parallaction.h" #include "parallaction/menu.h" #include "parallaction/music.h" diff --git a/engines/parallaction/inventory.cpp b/engines/parallaction/inventory.cpp index ca326c90ce..0e6a003b23 100644 --- a/engines/parallaction/inventory.cpp +++ b/engines/parallaction/inventory.cpp @@ -20,6 +20,7 @@ * */ +#include "common/stdafx.h" #include "parallaction/parallaction.h" #include "parallaction/disk.h" diff --git a/engines/parallaction/location.cpp b/engines/parallaction/location.cpp index d35739e299..3c3aaab540 100644 --- a/engines/parallaction/location.cpp +++ b/engines/parallaction/location.cpp @@ -20,6 +20,8 @@ * */ +#include "common/stdafx.h" + #include "parallaction/parallaction.h" #include "parallaction/graphics.h" #include "parallaction/disk.h" @@ -143,7 +145,7 @@ void Parallaction::parseLocation(const char *filename) { parseZone(*_locationScript, &_zones, _tokens[1]); } if (!scumm_stricmp(_tokens[0], "NODES")) { - parseWalkNodes(*_locationScript, &_location._walkNodes); + parseWalkNodes(*_locationScript, _location._walkNodes); } if (!scumm_stricmp(_tokens[0], "ANIMATION")) { parseAnimation(*_locationScript, &_animations, _tokens[1]); @@ -185,9 +187,7 @@ void Parallaction::freeLocation() { debugC(7, kDebugLocation, "freeLocation: localflags names freed"); - // TODO (LIST): this should be replaced by a call to _location._walkNodes.clear() - freeNodeList(_location._walkNodes._next); - _location._walkNodes._next = NULL; + _location._walkNodes.clear(); debugC(7, kDebugLocation, "freeLocation: walk nodes freed"); // TODO (LIST): helperNode should be rendered useless by the use of a Common::List<> @@ -230,7 +230,7 @@ void Parallaction::freeLocation() { -void Parallaction::parseWalkNodes(Script& script, Node *list) { +void Parallaction::parseWalkNodes(Script& script, WalkNodeList &list) { fillBuffers(script, true); while (scumm_stricmp(_tokens[0], "ENDNODES")) { @@ -242,8 +242,7 @@ void Parallaction::parseWalkNodes(Script& script, Node *list) { atoi(_tokens[2]) - _char._ani.height() ); - addNode(list, v4); - + list.push_front(v4); } fillBuffers(script, true); diff --git a/engines/parallaction/parallaction.cpp b/engines/parallaction/parallaction.cpp index 3e3b06a693..9aa5e1e3fe 100644 --- a/engines/parallaction/parallaction.cpp +++ b/engines/parallaction/parallaction.cpp @@ -185,8 +185,6 @@ int Parallaction::init() { _location._startPosition.x = -1000; _location._startPosition.y = -1000; _location._startFrame = 0; - _location._walkNodes._prev = NULL; - _location._walkNodes._next = NULL; if (getFeatures() & GF_DEMO) strcpy(_location._name, "fognedemo"); @@ -416,7 +414,6 @@ void Parallaction::runGame() { void Parallaction::processInput(InputData *data) { Zone *z; - WalkNode *v4; switch (data->_event) { case kEvEnterZone: @@ -480,15 +477,16 @@ void Parallaction::processInput(InputData *data) { _procCurrentHoverItem = data->_inventoryIndex; break; - case kEvWalk: + case kEvWalk: { debugC(2, kDebugInput, "processInput: kEvWalk"); _hoverZone = NULL; changeCursor(kCursorArrow); if (_vm->_char._ani._flags & kFlagsRemove) break; if ((_vm->_char._ani._flags & kFlagsActive) == 0) break; - v4 = buildWalkPath(data->_mousePos.x, data->_mousePos.y); + WalkNodeList *v4 = _vm->_char._builder.buildPath(data->_mousePos.x, data->_mousePos.y); addJob(&jobWalk, v4, kPriority19); _engineFlags |= kEngineWalking; // inhibits processing of input until walking is over + } break; case kEvQuitGame: diff --git a/engines/parallaction/parallaction.h b/engines/parallaction/parallaction.h index c311aa93a9..796bbbc65c 100644 --- a/engines/parallaction/parallaction.h +++ b/engines/parallaction/parallaction.h @@ -23,15 +23,18 @@ #ifndef PARALLACTION_H #define PARALLACTION_H +#include "common/str.h" +#include "gui/dialog.h" +#include "gui/widget.h" + #include "engines/engine.h" + #include "parallaction/defs.h" #include "parallaction/inventory.h" #include "parallaction/parser.h" #include "parallaction/disk.h" +#include "parallaction/walk.h" #include "parallaction/zone.h" -#include "common/str.h" -#include "gui/dialog.h" -#include "gui/widget.h" namespace GUI { class ListWidget; @@ -224,9 +227,9 @@ class MidiPlayer; struct Location { Common::Point _startPosition; - uint16 _startFrame; - Node _walkNodes; - char _name[100]; + uint16 _startFrame; + WalkNodeList _walkNodes; + char _name[100]; CommandList _aCommands; CommandList _commands; @@ -240,8 +243,9 @@ struct Character { StaticCnv *_head; Cnv *_talk; Cnv *_objs; + PathBuilder _builder; - Character() { + Character() : _builder(&_ani) { _talk = NULL; _head = NULL; _objs = NULL; @@ -430,7 +434,7 @@ protected: // members void parseZone(Script &script, Node *list, char *name); void parseZoneTypeBlock(Script &script, Zone *z); - void parseWalkNodes(Script& script, Node *list); + void parseWalkNodes(Script& script, WalkNodeList &list); void displayCharacterComment(ExamineData *data); void displayItemComment(ExamineData *data); diff --git a/engines/parallaction/saveload.cpp b/engines/parallaction/saveload.cpp index 3514488093..5ad54adeea 100644 --- a/engines/parallaction/saveload.cpp +++ b/engines/parallaction/saveload.cpp @@ -20,18 +20,18 @@ * */ - -#include "parallaction/parallaction.h" -#include "parallaction/disk.h" -#include "parallaction/graphics.h" -#include "parallaction/zone.h" - +#include "common/stdafx.h" #include "common/savefile.h" #include "gui/widget.h" #include "gui/ListWidget.h" #include "gui/message.h" +#include "parallaction/parallaction.h" +#include "parallaction/disk.h" +#include "parallaction/graphics.h" +#include "parallaction/zone.h" + /* Nippon Safes savefiles are called 'game.0' to 'game.9'. The game conventiently allows users to * give meanigful name to savegames, and it uses an extra file 'savegame' to keep track of these * names. diff --git a/engines/parallaction/staticres.cpp b/engines/parallaction/staticres.cpp index 076ad8bf5d..9c3bc47b60 100644 --- a/engines/parallaction/staticres.cpp +++ b/engines/parallaction/staticres.cpp @@ -20,6 +20,8 @@ * */ +#include "common/stdafx.h" + #include "parallaction/parallaction.h" #include "parallaction/graphics.h" diff --git a/engines/parallaction/walk.cpp b/engines/parallaction/walk.cpp index 5aee5c3be8..8ed3d61757 100644 --- a/engines/parallaction/walk.cpp +++ b/engines/parallaction/walk.cpp @@ -31,9 +31,6 @@ namespace Parallaction { uint16 walkFunc1(int16, int16, WalkNode *); - -WalkNode _NULL_WALKNODE(); - static byte *_buffer; static uint16 _doorData1 = 1000; @@ -41,17 +38,11 @@ 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 // -void correctPathPoint(Common::Point &to) { +void PathBuilder::correctPathPoint(Common::Point &to) { if (queryPath(to.x, to.y)) return; @@ -84,71 +75,61 @@ void correctPathPoint(Common::Point &to) { 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 } return; } -uint32 buildSubPath(const Common::Point& pos, const Common::Point& stop, WalkNode* root) { - - WalkNode *v48 = root; +uint32 PathBuilder::buildSubPath(const Common::Point& pos, const Common::Point& stop) { uint32 v28 = 0; uint32 v2C = 0; uint32 v34 = pos.sqrDist(stop); // square distance from current position and target uint32 v30 = v34; + _subPath.clear(); + Common::Point v20(pos); while (true) { - WalkNode *nearestNode = NULL; - WalkNode *locNode = (WalkNode*)_vm->_location._walkNodes._next; + WalkNodeList::iterator nearest = _vm->_location._walkNodes.end(); + WalkNodeList::iterator locNode = _vm->_location._walkNodes.begin(); // scans location path nodes searching for the nearest Node // which can't be farther than the target position // otherwise no _closest_node is selected - while (locNode != NULL) { + while (locNode != _vm->_location._walkNodes.end()) { Common::Point v8; - locNode->getPoint(v8); + (*locNode)->getPoint(v8); v2C = v8.sqrDist(stop); v28 = v8.sqrDist(v20); if (v2C < v34 && v28 < v30) { v30 = v28; - nearestNode = locNode; + nearest = locNode; } - locNode = (WalkNode*)locNode->_next; + locNode++; } - if (nearestNode == NULL) break; + if (nearest == _vm->_location._walkNodes.end()) break; - nearestNode->getPoint(v20); + (*nearest)->getPoint(v20); v34 = v30 = v20.sqrDist(stop); - addNode(v48, new WalkNode(*nearestNode)); - v48 = (WalkNode*)v48->_next; + _subPath.push_back(new WalkNode(**nearest)); } return v34; @@ -158,8 +139,8 @@ uint32 buildSubPath(const Common::Point& pos, const Common::Point& stop, WalkNod // // x, y: mouse click (foot) coordinates // -WalkNode *buildWalkPath(uint16 x, uint16 y) { - debugC(1, kDebugWalk, "buildWalkPath to (%i, %i)", x, y); +WalkNodeList *PathBuilder::buildPath(uint16 x, uint16 y) { + debugC(1, kDebugWalk, "PathBuilder::buildPath to (%i, %i)", x, y); Common::Point to(x, y); correctPathPoint(to); @@ -173,33 +154,35 @@ WalkNode *buildWalkPath(uint16 x, uint16 y) { // destination directly reachable debugC(1, kDebugWalk, "direct move to (%i, %i)", to.x, to.y); delete v44; - return v48; - } - // path is obstructed: find alternative + _list = new WalkNodeList; + _list->push_back(v48); + return _list; + } - WalkNode dummy; - addNode(&dummy, v48); + // path is obstructed: look for alternative + _list = new WalkNodeList; + _list->push_back(v48); Common::Point stop(v48->_x, v48->_y); Common::Point pos(_vm->_char._ani._left, _vm->_char._ani._top); - v48 = &dummy; - uint32 v34 = buildSubPath(pos, stop, v48); + uint32 v34 = buildSubPath(pos, stop); if (v38 != 0 && v34 > v38) { // no alternative path (gap?) - // TODO (LIST): tempPath.clear() - freeNodeList(dummy._next); - return v44; + _list->clear(); + _list->push_back(v44); + return _list; } + _list->insert(_list->begin(), _subPath.begin(), _subPath.end()); - ((WalkNode*)(dummy._next))->getPoint(stop); + (*_list->begin())->getPoint(stop); - v48 = &dummy; - buildSubPath(pos, stop, v48); + buildSubPath(pos, stop); + _list->insert(_list->begin(), _subPath.begin(), _subPath.end()); delete v44; - return (WalkNode*)dummy._next; + return _list; } @@ -326,53 +309,42 @@ int16 selectWalkFrame(const Common::Point& pos, const WalkNode* from) { return v16; } -WalkNode* getNextPathNode(const Common::Point& pos, WalkNode* curNode) { - - if ((curNode->_x == pos.x) && (curNode->_y == pos.y)) { - - if (curNode->_next == NULL) return NULL; - - WalkNode *tmp = curNode; - curNode = (WalkNode*)curNode->_next; - free(tmp); - - debugC(1, kDebugWalk, "jobWalk moving to next node (%i, %i)", tmp->_x, tmp->_y); - } - - return curNode; - +void finalizeWalk(WalkNodeList *list) { + checkDoor(); + delete list; } void jobWalk(void *parm, Job *j) { - WalkNode *node = (WalkNode*)parm; + WalkNodeList *list = (WalkNodeList*)parm; Common::Point pos(_vm->_char._ani._left, _vm->_char._ani._top); - _vm->_char._ani._oldPos = pos; - node = getNextPathNode(pos, node); - if (node == NULL) { + WalkNodeList::iterator it = list->begin(); + + if ((*it)->_x == pos.x && (*it)->_y == pos.y) { + debugC(1, kDebugWalk, "jobWalk moving to next node (%i, %i)", (*it)->_x, (*it)->_y); + it = list->erase(it); + } + if (it == list->end()) { debugC(1, kDebugWalk, "jobWalk reached last node"); j->_finished = 1; - checkDoor(); - free(node); + finalizeWalk(list); return; } - j->_parm = node; + j->_parm = list; // selectWalkFrame must be performed before position is changed by clipMove - int16 v16 = selectWalkFrame(pos, node); - - clipMove(pos, node); + int16 v16 = selectWalkFrame(pos, *it); + clipMove(pos, *it); _vm->_char._ani._left = pos.x; _vm->_char._ani._top = pos.y; if (pos == _vm->_char._ani._oldPos) { + debugC(1, kDebugWalk, "jobWalk was blocked by an unforeseen obstacle"); j->_finished = 1; - checkDoor(); - //TODO (LIST): this should become path.clear() - freeNodeList(node); + finalizeWalk(list); } else { _vm->_char._ani._frame = v16 + walkData2 + 1; } @@ -453,7 +425,7 @@ WalkNode::WalkNode() : _x(0), _y(0) { WalkNode::WalkNode(int32 x, int32 y) : _x(x), _y(y) { } -WalkNode::WalkNode(const WalkNode& w) : Node(), _x(w._x), _y(w._y) { +WalkNode::WalkNode(const WalkNode& w) : _x(w._x), _y(w._y) { } void WalkNode::getPoint(Common::Point &p) const { @@ -461,6 +433,8 @@ void WalkNode::getPoint(Common::Point &p) const { p.y = _y; } +PathBuilder::PathBuilder(Animation *anim) : _anim(anim), _list(0) { +} } // namespace Parallaction diff --git a/engines/parallaction/walk.h b/engines/parallaction/walk.h index 5bc33c3c3e..8b8e189df7 100644 --- a/engines/parallaction/walk.h +++ b/engines/parallaction/walk.h @@ -27,7 +27,10 @@ namespace Parallaction { -struct WalkNode : public Node { +struct Animation; +struct Job; + +struct WalkNode { int32 _x; int32 _y; @@ -39,14 +42,30 @@ public: void getPoint(Common::Point &p) const; }; +typedef ManagedList<WalkNode*> WalkNodeList; -WalkNode *buildWalkPath(uint16 x, uint16 y); +//WalkNode *buildWalkPath(uint16 x, uint16 y); void jobWalk(void*, Job *j); uint16 checkDoor(); void setPath(byte *path); void initWalk(); uint16 queryPath(uint16 x, uint16 y); +class PathBuilder { + + Animation *_anim; + + WalkNodeList *_list; + WalkNodeList _subPath; + + void correctPathPoint(Common::Point &to); + uint32 buildSubPath(const Common::Point& pos, const Common::Point& stop); + +public: + PathBuilder(Animation *anim); + WalkNodeList* buildPath(uint16 x, uint16 y); + +}; } diff --git a/engines/parallaction/zone.cpp b/engines/parallaction/zone.cpp index e36d2b327f..85e6f8edc9 100644 --- a/engines/parallaction/zone.cpp +++ b/engines/parallaction/zone.cpp @@ -606,6 +606,7 @@ Zone::Zone() { } Zone::~Zone() { + printf("~Zone(%s)\n", _label._text); switch (_type & 0xFFFF) { case kZoneExamine: |