aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Gilbert2015-06-13 16:48:34 -0400
committerPaul Gilbert2015-06-13 16:48:34 -0400
commit02f582d5af02411bbe943014788cbad6f8e6b12b (patch)
treebd13c550c8f4315774d64367db2914a18ee313e4
parent864dc6acb7915f9b45ce958ff0ad645de74019d5 (diff)
downloadscummvm-rg350-02f582d5af02411bbe943014788cbad6f8e6b12b.tar.gz
scummvm-rg350-02f582d5af02411bbe943014788cbad6f8e6b12b.tar.bz2
scummvm-rg350-02f582d5af02411bbe943014788cbad6f8e6b12b.zip
SHERLOCK: RT: Implement setWalking
-rw-r--r--engines/sherlock/scalpel/scalpel_people.cpp24
-rw-r--r--engines/sherlock/tattoo/tattoo_people.cpp177
-rw-r--r--engines/sherlock/tattoo/tattoo_scene.h12
-rw-r--r--engines/sherlock/tattoo/tattoo_user_interface.cpp2
4 files changed, 195 insertions, 20 deletions
diff --git a/engines/sherlock/scalpel/scalpel_people.cpp b/engines/sherlock/scalpel/scalpel_people.cpp
index 31be9b4cbc..89f3eeaeb6 100644
--- a/engines/sherlock/scalpel/scalpel_people.cpp
+++ b/engines/sherlock/scalpel/scalpel_people.cpp
@@ -241,10 +241,10 @@ void ScalpelPerson::setWalking() {
// Set the initial frame sequence for the left and right, as well
// as setting the delta x depending on direction
if (people._walkDest.x < (_position.x / FIXED_INT_MULTIPLIER)) {
- _sequenceNumber = (map._active ? (int)MAP_LEFT : (int)Scalpel::WALK_LEFT);
+ _sequenceNumber = (map._active ? (int)MAP_LEFT : (int)WALK_LEFT);
_delta.x = speed.x * -FIXED_INT_MULTIPLIER;
} else {
- _sequenceNumber = (map._active ? (int)MAP_RIGHT : (int)Scalpel::WALK_RIGHT);
+ _sequenceNumber = (map._active ? (int)MAP_RIGHT : (int)WALK_RIGHT);
_delta.x = speed.x * FIXED_INT_MULTIPLIER;
}
@@ -271,22 +271,22 @@ void ScalpelPerson::setWalking() {
if (_delta.y > 150) {
if (!map._active) {
switch (_sequenceNumber) {
- case Scalpel::WALK_LEFT:
- _sequenceNumber = Scalpel::WALK_DOWNLEFT;
+ case WALK_LEFT:
+ _sequenceNumber = WALK_DOWNLEFT;
break;
- case Scalpel::WALK_RIGHT:
- _sequenceNumber = Scalpel::WALK_DOWNRIGHT;
+ case WALK_RIGHT:
+ _sequenceNumber = WALK_DOWNRIGHT;
break;
}
}
} else if (_delta.y < -150) {
if (!map._active) {
switch (_sequenceNumber) {
- case Scalpel::WALK_LEFT:
- _sequenceNumber = Scalpel::WALK_UPLEFT;
+ case WALK_LEFT:
+ _sequenceNumber = WALK_UPLEFT;
break;
- case Scalpel::WALK_RIGHT:
- _sequenceNumber = Scalpel::WALK_UPRIGHT;
+ case WALK_RIGHT:
+ _sequenceNumber = WALK_UPRIGHT;
break;
}
}
@@ -295,10 +295,10 @@ void ScalpelPerson::setWalking() {
// Major movement is vertical, so set the sequence for up and down,
// and set the delta Y depending on the direction
if (people._walkDest.y < (_position.y / FIXED_INT_MULTIPLIER)) {
- _sequenceNumber = Scalpel::WALK_UP;
+ _sequenceNumber = WALK_UP;
_delta.y = speed.y * -FIXED_INT_MULTIPLIER;
} else {
- _sequenceNumber = Scalpel::WALK_DOWN;
+ _sequenceNumber = WALK_DOWN;
_delta.y = speed.y * FIXED_INT_MULTIPLIER;
}
diff --git a/engines/sherlock/tattoo/tattoo_people.cpp b/engines/sherlock/tattoo/tattoo_people.cpp
index 609d3d73d3..e2cfea63c9 100644
--- a/engines/sherlock/tattoo/tattoo_people.cpp
+++ b/engines/sherlock/tattoo/tattoo_people.cpp
@@ -31,6 +31,32 @@ namespace Tattoo {
#define FACING_PLAYER 16
+static const int WALK_SPEED_X[99] = {
+ 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 98, 90, 90, 90, 90, 90, 91, 90, 90,
+ 90, 90,100, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90,100, 90,
+ 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90,103, 90, 90, 90, 90, 90, 90, 90,
+ 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90,
+ 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90
+};
+
+static const int WALK_SPEED_Y[99] = {
+ 28, 28, 28, 28, 28, 28, 28, 28, 28, 32, 32, 32, 28, 28, 28, 28, 28, 26, 28, 28,
+ 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
+ 32, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 31, 28, 28, 28, 28, 28, 28, 28,
+ 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
+ 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28
+};
+
+static const int WALK_SPEED_DIAG_X[99] = {
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 90, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50
+};
+
+/*----------------------------------------------------------------*/
+
TattooPerson::TattooPerson() : Person() {
Common::fill(&_npcPath[0], &_npcPath[MAX_NPC_PATH], 0);
_tempX = _tempScaleVal = 0;
@@ -243,7 +269,156 @@ void TattooPerson::gotoStand() {
}
void TattooPerson::setWalking() {
- warning("TODO: setWalking");
+ People &people = *_vm->_people;
+ TattooScene &scene = *(TattooScene *)_vm->_scene;
+ int oldDirection, oldFrame;
+ Common::Point delta;
+
+ // Flag that player has now walked in the scene
+ scene._walkedInScene = true;
+
+ // Stop any previous walking, since a new dest is being set
+ _walkCount = 0;
+ oldDirection = _sequenceNumber;
+ oldFrame = _frameNumber;
+
+ // Set speed to use horizontal and vertical movement
+ int scaleVal = scene.getScaleVal(_position);
+ Common::Point speed(MAX(WALK_SPEED_X[scene._currentScene - 1] * SCALE_THRESHOLD / scaleVal, 2),
+ MAX(WALK_SPEED_Y[scene._currentScene - 1] * SCALE_THRESHOLD / scaleVal, 2));
+ Common::Point diagSpeed(MAX((WALK_SPEED_Y[scene._currentScene - 1] - 2) * SCALE_THRESHOLD / scaleVal, 2),
+ MAX(WALK_SPEED_DIAG_X[scene._currentScene - 1] * SCALE_THRESHOLD / scaleVal, 2));
+
+ // If the player is already close to the given destination that no walking is needed,
+ // move to the next straight line segment in the overall walking route, if there is one
+ for (;;) {
+ // Since we want the player to be centered on the destination they
+ // clicked, but characters draw positions start at their left, move
+ // the destination half the character width to draw him centered
+ int temp;
+ if (people._walkDest.x >= (temp = _imageFrame->_frame.w / 2))
+ people._walkDest.x -= temp;
+
+ delta = Common::Point(
+ ABS(_position.x / FIXED_INT_MULTIPLIER - people._walkDest.x),
+ ABS(_position.y / FIXED_INT_MULTIPLIER - people._walkDest.y)
+ );
+
+ // If we're ready to move a sufficient distance, that's it. Otherwise,
+ // move onto the next portion of the walk path, if there is one
+ if ((delta.x > 3 || delta.y > 0) || _walkTo.empty())
+ break;
+
+ // Pop next walk segment off the walk route stack
+ people._walkDest = _walkTo.pop();
+ }
+
+ // If a sufficient move is being done, then start the move
+ if (delta.x > 3 || delta.y) {
+ // See whether the major movement is horizontal or vertical
+ if (delta.x >= delta.y) {
+ // Set the initial frame sequence for the left and right, as well
+ // as setting the delta x depending on direction
+ if (people._walkDest.x < (_position.x / FIXED_INT_MULTIPLIER)) {
+ _sequenceNumber = WALK_LEFT;
+ _delta.x = speed.x * -FIXED_INT_MULTIPLIER;
+ } else {
+ _sequenceNumber = WALK_RIGHT;
+ _delta.x = speed.x * FIXED_INT_MULTIPLIER;
+ }
+
+ // See if the x delta is too small to be divided by the speed, since
+ // this would cause a divide by zero error
+ if (delta.x >= speed.x) {
+ // Det the delta y
+ _delta.y = (delta.y * FIXED_INT_MULTIPLIER) / (delta.x / speed.x);
+ if (people._walkDest.y < (_position.y / FIXED_INT_MULTIPLIER))
+ _delta.y = -_delta.y;
+
+ // Set how many times we should add the delta to the player's position
+ _walkCount = delta.x / speed.x;
+ } else {
+ // The delta x was less than the speed (ie. we're really close to
+ // the destination). So set delta to 0 so the player won't move
+ _delta = Point32(0, 0);
+ _position = Point32(people._walkDest.x * FIXED_INT_MULTIPLIER, people._walkDest.y * FIXED_INT_MULTIPLIER);
+
+ _walkCount = 1;
+ }
+
+ // See if the sequence needs to be changed for diagonal walking
+ if (_delta.y > 1500) {
+ if (_sequenceNumber == WALK_LEFT || _sequenceNumber == WALK_RIGHT) {
+ _delta.x = _delta.x / speed.x * diagSpeed.x;
+ _delta.y = (delta.y * FIXED_INT_MULTIPLIER) / (delta.x * 10 / diagSpeed.x);
+ }
+
+ switch (_sequenceNumber) {
+ case WALK_LEFT:
+ _sequenceNumber = WALK_DOWNLEFT;
+ break;
+ case WALK_RIGHT:
+ _sequenceNumber = WALK_DOWNRIGHT;
+ break;
+ }
+ } else if (_delta.y < -1500) {
+ if (_sequenceNumber == WALK_LEFT || _sequenceNumber == WALK_RIGHT) {
+ _delta.x = _delta.x / speed.x * diagSpeed.x;
+ _delta.y = -1 * (delta.y * FIXED_INT_MULTIPLIER) / (delta.x * 10 / diagSpeed.x);
+ }
+
+ switch (_sequenceNumber) {
+ case WALK_LEFT:
+ _sequenceNumber = WALK_UPLEFT;
+ break;
+ case WALK_RIGHT:
+ _sequenceNumber = WALK_UPRIGHT;
+ break;
+ }
+ }
+ } else {
+ // Major movement is vertical, so set the sequence for up and down,
+ // and set the delta Y depending on the direction
+ if (people._walkDest.y < (_position.y / FIXED_INT_MULTIPLIER)) {
+ _sequenceNumber = WALK_UP;
+ _delta.y = speed.y * -FIXED_INT_MULTIPLIER;
+ } else {
+ _sequenceNumber = WALK_DOWN;
+ _delta.y = speed.y * FIXED_INT_MULTIPLIER;
+ }
+
+ // Set the delta x
+ _delta.x = (delta.x * FIXED_INT_MULTIPLIER) / (delta.y / speed.y);
+ if (people._walkDest.x < (_position.x / FIXED_INT_MULTIPLIER))
+ _delta.x = -_delta.x;
+
+ _walkCount = delta.y / speed.y;
+ }
+ }
+
+ // See if the new walk sequence is the same as the old. If it's a new one,
+ // we need to reset the frame number to zero so it's animation starts at
+ // it's beginning. Otherwise, if it's the same sequence, we can leave it
+ // as is, so it keeps the animation going at wherever it was up to
+ if (_sequenceNumber != _oldWalkSequence) {
+ if (_seqTo) {
+ // Reset to previous value
+ _walkSequences[oldDirection]._sequences[_frameNumber] = _seqTo;
+ _seqTo = 0;
+ }
+ _frameNumber = 0;
+ }
+
+ checkWalkGraphics();
+ _oldWalkSequence = _sequenceNumber;
+
+ if (!_walkCount && _walkTo.empty())
+ gotoStand();
+
+ // If the sequence is the same as when we started, then Holmes was standing still and we're trying
+ // to re-stand him, so reset Holmes' rame to the old frame number from before it was reset to 0
+ if (_sequenceNumber == oldDirection)
+ _frameNumber = oldFrame;
}
void TattooPerson::clearNPC() {
diff --git a/engines/sherlock/tattoo/tattoo_scene.h b/engines/sherlock/tattoo/tattoo_scene.h
index 427396d48b..849144e07c 100644
--- a/engines/sherlock/tattoo/tattoo_scene.h
+++ b/engines/sherlock/tattoo/tattoo_scene.h
@@ -64,12 +64,6 @@ private:
void doBgAnimDrawSprites();
/**
- * Returns the scale value for the passed co-ordinates. This is taken from the scene's
- * scale zones, interpolating inbetween the top and bottom values of the zones as needed
- */
- int getScaleVal(const Common::Point &pt);
-
- /**
* Makes a greyscale translation table for each palette entry in the table
*/
void setupBGArea(const byte cMap[PALETTE_SIZE]);
@@ -122,6 +116,12 @@ public:
TattooScene(SherlockEngine *vm);
/**
+ * Returns the scale value for the passed co-ordinates. This is taken from the scene's
+ * scale zones, interpolating inbetween the top and bottom values of the zones as needed
+ */
+ int getScaleVal(const Common::Point &pt);
+
+ /**
* Draw all objects and characters.
*/
virtual void doBgAnim();
diff --git a/engines/sherlock/tattoo/tattoo_user_interface.cpp b/engines/sherlock/tattoo/tattoo_user_interface.cpp
index fffde83cc6..915acde400 100644
--- a/engines/sherlock/tattoo/tattoo_user_interface.cpp
+++ b/engines/sherlock/tattoo/tattoo_user_interface.cpp
@@ -370,7 +370,7 @@ void TattooUserInterface::doStandardControl() {
if (events._rightReleased) {
// Show the verbs menu for the highlighted object
activateVerbMenu(!noDesc);
- } else if (_personFound || (_bgFound < 1000 && _bgShape->_aType == PERSON)) {
+ } else if (_personFound || (_bgFound != -1 && _bgFound < 1000 && _bgShape->_aType == PERSON)) {
// The object found is a person (the default for people is TALK)
talk.talk(_bgFound);
_activeObj = -1;