From 00c98c519e85ee7d3f7f2a262e80a2b24b1914e0 Mon Sep 17 00:00:00 2001 From: Andrew Kurushin Date: Thu, 6 Jan 2005 19:15:01 +0000 Subject: - implement faceTowards (script function & etc) - implement debug actor walk path (press f6) svn-id: r16456 --- saga/actor.cpp | 76 +++++++++++++++++++++++++++++++++++++++++++++++++++------ saga/actor.h | 27 +++++++++++++++++--- saga/input.cpp | 5 +++- saga/render.cpp | 3 +++ saga/render.h | 3 ++- saga/script.h | 2 +- saga/sfuncs.cpp | 20 ++++++++++----- 7 files changed, 117 insertions(+), 19 deletions(-) diff --git a/saga/actor.cpp b/saga/actor.cpp index a562ea4088..5325057ce3 100644 --- a/saga/actor.cpp +++ b/saga/actor.cpp @@ -138,6 +138,9 @@ Actor::Actor(SagaEngine *vm) : _vm(vm) { return; } + _debugPoints = NULL; + _debugPointsAlloced = _debugPointsCount = 0; + _centerActor = _protagonist = NULL; _lastTickMsec = 0; @@ -193,6 +196,7 @@ Actor::~Actor() { ActorData *actor; debug(9, "Actor::~Actor()"); + free(_debugPoints); free(_pathCell); //release resources for (i = 0; i < ACTORCOUNT; i++) { @@ -299,6 +303,37 @@ void Actor::realLocation(ActorLocation &location, uint16 objectId, uint16 walkFl } } +void Actor::actorFaceTowardsPoint(uint16 actorId, const ActorLocation &toLocation) { + ActorData *actor; + ActorLocation delta; + + actor = getActor(actorId); + + // tiled stuff + if (_vm->_scene->getMode() == SCENE_MODE_ISO) { + //todo: it + } else { + toLocation.delta(actor->location, delta); + + if (ABS(delta.y) > ABS(delta.x * 2)) { + actor->facingDirection = (delta.y > 0) ? kDirDown : kDirUp; + } else { + actor->facingDirection = (delta.x > 0) ? kDirRight : kDirLeft; + } + } +} + +void Actor::actorFaceTowardsObject(uint16 actorId, uint16 objectId) { + ActorData *actor; + + if (IS_VALID_ACTOR_ID(objectId)) { + actor = getActor(objectId); + actorFaceTowardsPoint(actorId, actor->location); + } else { + warning("ObjectId unsupported"); //todo: do it + } +} + ActorData *Actor::getActor(uint16 actorId) { ActorData *actor; @@ -556,8 +591,8 @@ void Actor::handleActions(int msec, bool setup) { //todo: dragon stuff - if (actor->index == 2) - debug(9, "Action: %d Flags: %x", actor->currentAction, actor->flags); +/* if (actor->index == 2) + debug(9, "Action: %d Flags: %x", actor->currentAction, actor->flags);*/ switch(actor->currentAction) { case kActionWait: @@ -568,7 +603,7 @@ void Actor::handleActions(int msec, bool setup) { } if (actor->targetObject != ID_NOTHING) { - //todo: facetowardsobject + actorFaceTowardsObject(actor->actorId, actor->targetObject); } if (actor->flags & kCycle) { @@ -829,8 +864,8 @@ void Actor::calcActorScreenPosition(ActorData *actor) { actor->location.toScreenPointXYZ(actor->screenPosition); } - if (actor->index == 2) - debug(9, "act: %d. x: %d y: %d", actor->index, actor->screenPosition.x, actor->screenPosition.y); + /*if (actor->index == 2) + debug(9, "act: %d. x: %d y: %d", actor->index, actor->screenPosition.x, actor->screenPosition.y);*/ } void Actor::createDrawOrderList() { @@ -1314,6 +1349,7 @@ void Actor::findActorPath(ActorData *actor, const Point &fromPoint, const Point int i; Rect intersect; + _debugPointsCount = 0; actor->walkStepsCount = 0; if (fromPoint == toPoint) { @@ -1325,7 +1361,7 @@ void Actor::findActorPath(ActorData *actor, const Point &fromPoint, const Point for (iteratorPoint.x = 0; iteratorPoint.x < _xCellCount; iteratorPoint.x++) { maskType = _vm->_scene->getBGMaskType(iteratorPoint); cellValue = maskType ? kPathCellBarrier : kPathCellEmpty; - setPathCell(iteratorPoint, cellValue); + setPathCell(iteratorPoint, cellValue); } } @@ -1343,7 +1379,16 @@ void Actor::findActorPath(ActorData *actor, const Point &fromPoint, const Point } } +#if 1 + for (iteratorPoint.y = 0; iteratorPoint.y < _yCellCount; iteratorPoint.y++) { + for (iteratorPoint.x = 0; iteratorPoint.x < _xCellCount; iteratorPoint.x++) { + if (getPathCell(iteratorPoint) == kPathCellBarrier) { + addDebugPoint(iteratorPoint, 24); + } + } + } +#endif if (scanPathLine(fromPoint, toPoint)) { actor->addWalkStepPoint(fromPoint); @@ -1466,6 +1511,8 @@ int Actor::fillPathArray(const Point &fromPoint, const Point &toPoint, Point &be if (validPathCellPoint(fromPoint)) { setPathCell(fromPoint, 0); + + addDebugPoint(fromPoint, 0x8a); } pathDirectionIterator = pathDirectionList.begin(); @@ -1480,7 +1527,8 @@ int Actor::fillPathArray(const Point &fromPoint, const Point &toPoint, Point &be if (validPathCellPoint(nextPoint) && (getPathCell(nextPoint) == kPathCellEmpty)) { setPathCell(nextPoint, samplePathDirection->direction); - + + addDebugPoint(nextPoint, samplePathDirection->direction + 96); newPathDirectionIterator = pathDirectionList.pushBack(); pathDirection = newPathDirectionIterator.operator->(); pathDirection->x = nextPoint.x; @@ -1848,6 +1896,20 @@ void Actor::removePathPoints() { _pathNodeIndex = j - 1; } +void Actor::drawPathTest() { + int i; + SURFACE *surface; + surface = _vm->_gfx->getBackBuffer(); + if (_debugPoints == NULL) { + return; + } + + + for (i = 0; i < _debugPointsCount; i++) { + *((byte *)surface->pixels + (_debugPoints[i].point.y * surface->pitch) + _debugPoints[i].point.x) = _debugPoints[i].color; + } +} + /* // Console wrappers - must be safe to run // TODO - checkup ALL arguments, cause wrong arguments may fall function with "error" diff --git a/saga/actor.h b/saga/actor.h index 48dda0ce27..bb2323d1eb 100644 --- a/saga/actor.h +++ b/saga/actor.h @@ -123,7 +123,7 @@ enum PathCellType { struct PathDirectionData { int direction; - int x; + int x; int y; }; @@ -151,10 +151,10 @@ struct ActorLocation { ActorLocation() { x = y = z = 0; } - int distance(const ActorLocation &location) { + int distance(const ActorLocation &location) const { return MAX(ABS(x - location.x), ABS(y - location.y)); } - void delta(const ActorLocation &location, ActorLocation &result) { + void delta(const ActorLocation &location, ActorLocation &result) const { result.x = x - location.x; result.y = y - location.y; result.z = z - location.z; @@ -286,11 +286,15 @@ public: int drawActors(); void updateActorsScene(); // calls from scene loading to update Actors info + void drawPathTest(); + bool actorEndWalk(uint16 actorId, bool recurse); bool actorWalkTo(uint16 actorId, const ActorLocation &toLocation); ActorData *getActor(uint16 actorId); ActorFrameRange *getActorFrameRange(uint16 actorId, int frameType); void realLocation(ActorLocation &location, uint16 objectId, uint16 walkFlags); + void actorFaceTowardsPoint(uint16 actorId, const ActorLocation &toLocation); + void actorFaceTowardsObject(uint16 actorId, uint16 objectId); // speech void actorSpeech(uint16 actorId, const char **strings, int stringsCount, uint16 sampleResourceId, int speechFlags); @@ -362,6 +366,23 @@ private: PathNode _newPathNodeList[PATH_NODE_MAX]; int _pathNodeIndex; +public: +//path debug - use with care + struct DebugPoint { + Point point; + byte color; + }; + DebugPoint *_debugPoints; + int _debugPointsCount; + int _debugPointsAlloced; + void addDebugPoint(const Point &point, byte color) { + if (_debugPointsCount + 1 > _debugPointsAlloced) { + _debugPointsAlloced += 1000; + _debugPoints = (DebugPoint*) realloc(_debugPoints, _debugPointsAlloced * sizeof(*_debugPoints)); + } + _debugPoints[_debugPointsCount].color = color; + _debugPoints[_debugPointsCount++].point = point; + } }; inline int16 quickDistance(const Point &point1, const Point &point2) { diff --git a/saga/input.cpp b/saga/input.cpp index c2c8e39510..e8d391a635 100644 --- a/saga/input.cpp +++ b/saga/input.cpp @@ -67,6 +67,9 @@ int SagaEngine::processInput() { case 285: // F4 _render->toggleFlag(RF_OBJECTMAP_TEST); break; + case 287: // F6 + _render->toggleFlag(RF_ACTOR_PATH_TEST); + break; case 9: // Tab _script->SThreadDebugStep(); break; @@ -84,7 +87,7 @@ int SagaEngine::processInput() { switch (_interface->getMode()) { case kPanelNull: if (_scene->isInDemo()) - _scene->skipScene(); + _scene->skipScene(); else _actor->abortAllSpeeches(); break; diff --git a/saga/render.cpp b/saga/render.cpp index e55e59df75..7d75de1efa 100644 --- a/saga/render.cpp +++ b/saga/render.cpp @@ -136,6 +136,9 @@ int Render::drawScene() { // Draw queued actors _vm->_actor->drawActors(); + if (getFlags() & RF_ACTOR_PATH_TEST) { + _vm->_actor->drawPathTest(); + } } // Draw queued text strings diff --git a/saga/render.h b/saga/render.h index 5607cbdcf7..c217b09b77 100644 --- a/saga/render.h +++ b/saga/render.h @@ -38,7 +38,8 @@ enum RENDER_FLAGS { RF_OBJECTMAP_TEST = 0x08, RF_RENDERPAUSE = 0x10, RF_GAMEPAUSE = 0x20, - RF_PLACARD = 0x40 + RF_PLACARD = 0x40, + RF_ACTOR_PATH_TEST = 0x80 }; struct BUFFER_INFO { diff --git a/saga/script.h b/saga/script.h index f045696fbb..cbc1c3c3d2 100644 --- a/saga/script.h +++ b/saga/script.h @@ -323,7 +323,7 @@ private: int sfLockUser(SCRIPTFUNC_PARAMS); int SF_preDialog(SCRIPTFUNC_PARAMS); int SF_killActorThreads(SCRIPTFUNC_PARAMS); - int SF_faceTowards(SCRIPTFUNC_PARAMS); + int sfFaceTowards(SCRIPTFUNC_PARAMS); int sfSetFollower(SCRIPTFUNC_PARAMS); int SF_gotoScene(SCRIPTFUNC_PARAMS); int SF_setObjImage(SCRIPTFUNC_PARAMS); diff --git a/saga/sfuncs.cpp b/saga/sfuncs.cpp index 5c65c5e6f5..d4162ccfd4 100644 --- a/saga/sfuncs.cpp +++ b/saga/sfuncs.cpp @@ -62,7 +62,7 @@ void Script::setupScriptFuncList(void) { OPCODE(sfLockUser), OPCODE(SF_preDialog), OPCODE(SF_killActorThreads), - OPCODE(SF_faceTowards), + OPCODE(sfFaceTowards), OPCODE(sfSetFollower), OPCODE(SF_gotoScene), OPCODE(SF_setObjImage), @@ -324,11 +324,19 @@ int Script::SF_killActorThreads(SCRIPTFUNC_PARAMS) { } // Script function #14 (0x0E) -int Script::SF_faceTowards(SCRIPTFUNC_PARAMS) { - ScriptDataWord param1 = thread->pop(); - ScriptDataWord param2 = thread->pop(); +// Param1: actor id +// Param2: object id +int Script::sfFaceTowards(SCRIPTFUNC_PARAMS) { + int16 actorId; + int16 targetObject; + ActorData *actor; + + actorId = getSWord(thread->pop()); + targetObject = getSWord(thread->pop()); + + actor = _vm->_actor->getActor(actorId); + actor->targetObject = targetObject; - debug(1, "stub: SF_faceTowards(%d, %d)", param1, param2); return SUCCESS; } @@ -945,7 +953,7 @@ int Script::sfPlacard(SCRIPTFUNC_PARAMS) { PALENTRY *pal; EVENT event; EVENT *q_event; - + thread->wait(kWaitTypePlacard); _vm->_interface->rememberMode(); -- cgit v1.2.3