aboutsummaryrefslogtreecommitdiff
path: root/engines/draci
diff options
context:
space:
mode:
authorRobert Špalek2009-11-07 04:56:28 +0000
committerRobert Špalek2009-11-07 04:56:28 +0000
commitf534c12289cca1152fc57545aeab12d5973720ed (patch)
tree4a51a7d87fd99d933db504f75d8ebdf541cf39d4 /engines/draci
parent638305fcbb9a1c53425b546a0deb2ea6c3208f5a (diff)
downloadscummvm-rg350-f534c12289cca1152fc57545aeab12d5973720ed.tar.gz
scummvm-rg350-f534c12289cca1152fc57545aeab12d5973720ed.tar.bz2
scummvm-rg350-f534c12289cca1152fc57545aeab12d5973720ed.zip
Add helper functions to retrieve dragon position from the animation.
To implement proper walking, I have to respect the relative shifts defined by the sprites as opposed to apply some constant velocity. svn-id: r45714
Diffstat (limited to 'engines/draci')
-rw-r--r--engines/draci/animation.cpp5
-rw-r--r--engines/draci/animation.h1
-rw-r--r--engines/draci/game.cpp30
-rw-r--r--engines/draci/game.h1
-rw-r--r--engines/draci/walking.cpp17
-rw-r--r--engines/draci/walking.h2
6 files changed, 42 insertions, 14 deletions
diff --git a/engines/draci/animation.cpp b/engines/draci/animation.cpp
index 9d56c89674..ffdfa6c1e2 100644
--- a/engines/draci/animation.cpp
+++ b/engines/draci/animation.cpp
@@ -64,6 +64,11 @@ Displacement Animation::getCurrentFrameDisplacement() const {
return dis;
}
+Common::Point Animation::getCurrentFramePosition() const {
+ Displacement dis = getCurrentFrameDisplacement();
+ return Common::Point(dis.relX, dis.relY);
+}
+
void Animation::setLooping(bool looping) {
_looping = looping;
debugC(7, kDraciAnimationDebugLevel, "Setting looping to %d on animation %d",
diff --git a/engines/draci/animation.h b/engines/draci/animation.h
index 9fd5a87f97..1fe5d4c814 100644
--- a/engines/draci/animation.h
+++ b/engines/draci/animation.h
@@ -99,6 +99,7 @@ public:
int getRelativeY() const { return _displacement.relY; }
const Displacement &getDisplacement() const { return _displacement; } // displacement of the whole animation
Displacement getCurrentFrameDisplacement() const; // displacement of the current frame (includes _shift)
+ Common::Point getCurrentFramePosition() const; // with displacement and shift applied
int getIndex() const { return _index; }
void setIndex(int index) { _index = index; }
diff --git a/engines/draci/game.cpp b/engines/draci/game.cpp
index baaca70508..dde305d848 100644
--- a/engines/draci/game.cpp
+++ b/engines/draci/game.cpp
@@ -984,7 +984,7 @@ void Game::setHeroPosition(const Common::Point &p) {
void Game::positionHero(const Common::Point &p, SightDirection dir) {
setHeroPosition(p);
Common::Point mousePos(_vm->_mouse->getPosX(), _vm->_mouse->getPosY());
- playHeroAnimation(_walkingState.animationForSightDirection(dir, _hero, mousePos, WalkingPath()));
+ playHeroAnimation(WalkingState::animationForSightDirection(dir, _hero, mousePos, WalkingPath()));
}
Common::Point Game::findNearestWalkable(int x, int y) const {
@@ -1477,16 +1477,12 @@ void Game::positionAnimAsHero(Animation *anim) {
// Fetch current frame
Drawable *frame = anim->getCurrentFrame();
- // Fetch base dimensions of the frame
- uint height = frame->getHeight();
- uint width = frame->getWidth();
-
// We naturally want the dragon to position its feet to the location of the
// click but sprites are drawn from their top-left corner so we subtract
// the current height of the dragon's sprite
Common::Point p = _hero;
- p.x -= (int)(scale * width) / 2;
- p.y -= (int)(scale * height);
+ p.x -= (int)(scale * frame->getWidth() / 2);
+ p.y -= (int)(scale * frame->getHeight());
// Since _persons[] is used for placing talking text, we use the non-adjusted x value
// so the text remains centered over the dragon.
@@ -1499,6 +1495,26 @@ void Game::positionAnimAsHero(Animation *anim) {
anim->setRelative(p.x, p.y);
}
+void Game::positionHeroAsAnim(Animation *anim) {
+ // Check out where the hero has moved to by composing the relative
+ // shifts of the sprites.
+ _hero = anim->getCurrentFramePosition();
+
+ // Update our hero coordinates (don't forget that our control point is
+ // elsewhere).
+ Drawable *frame = anim->getCurrentFrame();
+ _hero.x += (int) (anim->getScaleX() * frame->getWidth() / 2);
+ _hero.y += (int) (anim->getScaleY() * frame->getHeight());
+
+ // Clear the animation's shift so that by updating the coordinates the
+ // animation will stay in place.
+ anim->clearShift();
+
+ // Call the inverse procedure to calculate new scaling factors.
+ // TODO: what about rounding errors?
+ positionAnimAsHero(anim);
+}
+
void Game::pushNewRoom() {
_pushedNewRoom = _newRoom;
_pushedNewGate = _newGate;
diff --git a/engines/draci/game.h b/engines/draci/game.h
index f57b917e91..d905f68bd8 100644
--- a/engines/draci/game.h
+++ b/engines/draci/game.h
@@ -215,6 +215,7 @@ public:
int getHeroX() const { return _hero.x; }
int getHeroY() const { return _hero.y; }
void positionAnimAsHero(Animation *anim);
+ void positionHeroAsAnim(Animation *anim);
void playHeroAnimation(int anim_index);
int loadAnimation(uint animNum, uint z);
diff --git a/engines/draci/walking.cpp b/engines/draci/walking.cpp
index fc194bf9d8..fed91dd8ef 100644
--- a/engines/draci/walking.cpp
+++ b/engines/draci/walking.cpp
@@ -522,11 +522,16 @@ bool WalkingState::continueWalking() {
// We are walking in the middle of an edge. The animation phase has
// just changed. Update the position of the hero.
- _position += 4; // TODO: compute shifts properly from the animation
- Common::Point newPos = WalkingMap::interpolate(
- _path[_segment], _path[_segment+1], _position, _length);
- _vm->_game->setHeroPosition(newPos);
- _vm->_game->positionAnimAsHero(anim);
+ _vm->_game->positionHeroAsAnim(anim);
+ // TODO: take the [XY] coordinate determined by the animation, update
+ // the other one so that the hero stays on the edge, remove _position
+ // and _length, and instead test reaching the destination by computing
+ // the scalar product
+ _position += 4;
+ // Common::Point newPos = WalkingMap::interpolate(
+ // _path[_segment], _path[_segment+1], _position, _length);
+ // _vm->_game->setHeroPosition(newPos);
+ // _vm->_game->positionAnimAsHero(anim);
// If the hero has reached the end of the edge, start transition to the
// next phase. This will increment _segment, either immediately (if no
@@ -698,7 +703,7 @@ Movement WalkingState::transitionBetweenAnimations(Movement previous, Movement n
}
}
-Movement WalkingState::animationForSightDirection(SightDirection dir, const Common::Point &hero, const Common::Point &mouse, const WalkingPath &path) const {
+Movement WalkingState::animationForSightDirection(SightDirection dir, const Common::Point &hero, const Common::Point &mouse, const WalkingPath &path) {
switch (dir) {
case kDirectionMouse:
return mouse.x < hero.x ? kStopLeft : kStopRight;
diff --git a/engines/draci/walking.h b/engines/draci/walking.h
index 6c8d9b9b07..a3dae88eb7 100644
--- a/engines/draci/walking.h
+++ b/engines/draci/walking.h
@@ -132,7 +132,7 @@ public:
// direction. The direction can be smart and in that case this
// function needs to know the whole last path, the current position of
// the hero, or the mouse position.
- Movement animationForSightDirection(SightDirection dir, const Common::Point &hero, const Common::Point &mouse, const WalkingPath &path) const;
+ static Movement animationForSightDirection(SightDirection dir, const Common::Point &hero, const Common::Point &mouse, const WalkingPath &path);
private:
DraciEngine *_vm;