aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Gilbert2015-06-14 00:43:19 -0400
committerPaul Gilbert2015-06-14 00:43:19 -0400
commit8629feb410068c084741de1bc2126ed6cd53a4cd (patch)
treee381bdd2a4a8ad92d55fbbab78d6bba6d46b4332
parent5531cf9fd503c3e74b8a32f6b12f2243bac68c06 (diff)
downloadscummvm-rg350-8629feb410068c084741de1bc2126ed6cd53a4cd.tar.gz
scummvm-rg350-8629feb410068c084741de1bc2126ed6cd53a4cd.tar.bz2
scummvm-rg350-8629feb410068c084741de1bc2126ed6cd53a4cd.zip
SHERLOCK: RT: Implemented walk setup
-rw-r--r--engines/sherlock/objects.cpp302
-rw-r--r--engines/sherlock/people.cpp3
-rw-r--r--engines/sherlock/people.h5
-rw-r--r--engines/sherlock/scalpel/scalpel_people.cpp5
-rw-r--r--engines/sherlock/scalpel/scalpel_people.h5
-rw-r--r--engines/sherlock/scalpel/scalpel_scene.cpp1
-rw-r--r--engines/sherlock/tattoo/tattoo_people.cpp45
-rw-r--r--engines/sherlock/tattoo/tattoo_people.h5
-rw-r--r--engines/sherlock/tattoo/tattoo_scene.cpp2
-rw-r--r--engines/sherlock/tattoo/tattoo_scene.h2
-rw-r--r--engines/sherlock/tattoo/tattoo_user_interface.cpp6
11 files changed, 217 insertions, 164 deletions
diff --git a/engines/sherlock/objects.cpp b/engines/sherlock/objects.cpp
index 1c184df547..29c5d73ad9 100644
--- a/engines/sherlock/objects.cpp
+++ b/engines/sherlock/objects.cpp
@@ -226,174 +226,184 @@ void Sprite::checkSprite() {
Common::Rect objBounds;
Common::Point spritePt(_position.x / FIXED_INT_MULTIPLIER, _position.y / FIXED_INT_MULTIPLIER);
- if (!talk._talkCounter && _type == CHARACTER) {
- pt = _walkCount ? _position + _delta : _position;
- pt.x /= FIXED_INT_MULTIPLIER;
- pt.y /= FIXED_INT_MULTIPLIER;
-
- for (uint idx = 0; idx < scene._bgShapes.size() && !talk._talkToAbort; ++idx) {
- Object &obj = scene._bgShapes[idx];
- if (obj._aType <= PERSON || obj._type == INVALID || obj._type == HIDDEN)
- continue;
-
- if (obj._type == NO_SHAPE) {
- objBounds = Common::Rect(obj._position.x, obj._position.y,
- obj._position.x + obj._noShapeSize.x + 1, obj._position.y + obj._noShapeSize.y + 1);
- } else {
- int xp = obj._position.x + obj._imageFrame->_offset.x;
- int yp = obj._position.y + obj._imageFrame->_offset.y;
- objBounds = Common::Rect(xp, yp,
- xp + obj._imageFrame->_frame.w + 1, yp + obj._imageFrame->_frame.h + 1);
- }
+ if (_type != CHARACTER || (IS_SERRATED_SCALPEL && talk._talkCounter))
+ return;
- if (objBounds.contains(pt)) {
- if (objBounds.contains(spritePt)) {
- // Current point is already inside the the bounds, so impact occurred
- // on a previous call. So simply do nothing until we're clear of the box
- switch (obj._aType) {
- case TALK_MOVE:
- if (_walkCount) {
- // Holmes is moving
- obj._type = HIDDEN;
- obj.setFlagsAndToggles();
- talk.talkTo(obj._use[0]._target);
- }
- break;
+ pt = _walkCount ? _position + _delta : _position;
+ pt.x /= FIXED_INT_MULTIPLIER;
+ pt.y /= FIXED_INT_MULTIPLIER;
- case PAL_CHANGE:
- case PAL_CHANGE2:
- if (_walkCount) {
- int palStart = atoi(obj._use[0]._names[0].c_str()) * 3;
- int palLength = atoi(obj._use[0]._names[1].c_str()) * 3;
- int templ = atoi(obj._use[0]._names[2].c_str()) * 3;
- if (templ == 0)
- templ = 100;
-
- // Ensure only valid palette change data found
- if (palLength > 0) {
- // Figure out how far into the shape Holmes is so that we
- // can figure out what percentage of the original palette
- // to set the current palette to
- int palPercent = (pt.x - objBounds.left) * 100 / objBounds.width();
- palPercent = palPercent * templ / 100;
- if (obj._aType == PAL_CHANGE)
- // Invert percentage
- palPercent = 100 - palPercent;
-
- for (int i = palStart; i < (palStart + palLength); ++i)
- screen._sMap[i] = screen._cMap[i] * palPercent / 100;
-
- events.pollEvents();
- screen.setPalette(screen._sMap);
- }
- }
- break;
+ if (IS_ROSE_TATTOO) {
+ // TODO: Needs to be called
+ //checkObject(1001);
+
+ // For Rose Tattoo, we only do the further processing for Sherlock
+ if (this != &people[HOLMES])
+ return;
+ }
+
+ for (uint idx = 0; idx < scene._bgShapes.size() && !talk._talkToAbort; ++idx) {
+ Object &obj = scene._bgShapes[idx];
+ if (obj._aType <= PERSON || obj._type == INVALID || obj._type == HIDDEN)
+ continue;
+
+ if (obj._type == NO_SHAPE) {
+ objBounds = Common::Rect(obj._position.x, obj._position.y,
+ obj._position.x + obj._noShapeSize.x + 1, obj._position.y + obj._noShapeSize.y + 1);
+ } else {
+ int xp = obj._position.x + obj._imageFrame->_offset.x;
+ int yp = obj._position.y + obj._imageFrame->_offset.y;
+ objBounds = Common::Rect(xp, yp,
+ xp + obj._imageFrame->_frame.w + 1, yp + obj._imageFrame->_frame.h + 1);
+ }
- case TALK:
- case TALK_EVERY:
+ if (objBounds.contains(pt)) {
+ if (objBounds.contains(spritePt)) {
+ // Current point is already inside the the bounds, so impact occurred
+ // on a previous call. So simply do nothing until we're clear of the box
+ switch (obj._aType) {
+ case TALK_MOVE:
+ if (_walkCount) {
+ // Holmes is moving
obj._type = HIDDEN;
obj.setFlagsAndToggles();
talk.talkTo(obj._use[0]._target);
- break;
-
- default:
- break;
}
- } else {
- // New impact just occurred
- switch (obj._aType) {
- case BLANK_ZONE:
- // A blank zone masks out all other remaining zones underneath it.
- // If this zone is hit, exit the outer loop so we do not check anymore
- return;
-
- case SOLID:
- case TALK:
- // Stop walking
- if (obj._aType == TALK) {
- obj.setFlagsAndToggles();
- talk.talkTo(obj._use[0]._target);
- } else {
- gotoStand();
- }
- break;
+ break;
- case TALK_EVERY:
- if (obj._aType == TALK_EVERY) {
- obj._type = HIDDEN;
- obj.setFlagsAndToggles();
- talk.talkTo(obj._use[0]._target);
- } else {
- gotoStand();
+ case PAL_CHANGE:
+ case PAL_CHANGE2:
+ if (_walkCount) {
+ int palStart = atoi(obj._use[0]._names[0].c_str()) * 3;
+ int palLength = atoi(obj._use[0]._names[1].c_str()) * 3;
+ int templ = atoi(obj._use[0]._names[2].c_str()) * 3;
+ if (templ == 0)
+ templ = 100;
+
+ // Ensure only valid palette change data found
+ if (palLength > 0) {
+ // Figure out how far into the shape Holmes is so that we
+ // can figure out what percentage of the original palette
+ // to set the current palette to
+ int palPercent = (pt.x - objBounds.left) * 100 / objBounds.width();
+ palPercent = palPercent * templ / 100;
+ if (obj._aType == PAL_CHANGE)
+ // Invert percentage
+ palPercent = 100 - palPercent;
+
+ for (int i = palStart; i < (palStart + palLength); ++i)
+ screen._sMap[i] = screen._cMap[i] * palPercent / 100;
+
+ events.pollEvents();
+ screen.setPalette(screen._sMap);
}
- break;
+ }
+ break;
- case FLAG_SET:
+ case TALK:
+ case TALK_EVERY:
+ obj._type = HIDDEN;
+ obj.setFlagsAndToggles();
+ talk.talkTo(obj._use[0]._target);
+ break;
+
+ default:
+ break;
+ }
+ } else {
+ // New impact just occurred
+ switch (obj._aType) {
+ case BLANK_ZONE:
+ // A blank zone masks out all other remaining zones underneath it.
+ // If this zone is hit, exit the outer loop so we do not check anymore
+ return;
+
+ case SOLID:
+ case TALK:
+ // Stop walking
+ if (obj._aType == TALK) {
obj.setFlagsAndToggles();
+ talk.talkTo(obj._use[0]._target);
+ } else {
+ gotoStand();
+ }
+ break;
+
+ case TALK_EVERY:
+ if (obj._aType == TALK_EVERY) {
obj._type = HIDDEN;
- break;
+ obj.setFlagsAndToggles();
+ talk.talkTo(obj._use[0]._target);
+ } else {
+ gotoStand();
+ }
+ break;
- case WALK_AROUND:
- if (objBounds.contains(people[HOLMES]._walkTo.front())) {
- // Reached zone
- gotoStand();
- } else {
- // Destination not within box, walk to best corner
- Common::Point walkPos;
-
- if (spritePt.x >= objBounds.left && spritePt.x < objBounds.right) {
- // Impact occurred due to vertical movement. Determine whether to
- // travel to the left or right side
- if (_delta.x > 0)
- // Go to right side
+ case FLAG_SET:
+ obj.setFlagsAndToggles();
+ obj._type = HIDDEN;
+ break;
+
+ case WALK_AROUND:
+ if (objBounds.contains(people[HOLMES]._walkTo.front())) {
+ // Reached zone
+ gotoStand();
+ } else {
+ // Destination not within box, walk to best corner
+ Common::Point walkPos;
+
+ if (spritePt.x >= objBounds.left && spritePt.x < objBounds.right) {
+ // Impact occurred due to vertical movement. Determine whether to
+ // travel to the left or right side
+ if (_delta.x > 0)
+ // Go to right side
+ walkPos.x = objBounds.right + CLEAR_DIST_X;
+ else if (_delta.x < 0) {
+ // Go to left side
+ walkPos.x = objBounds.left - CLEAR_DIST_X;
+ } else {
+ // Going straight up or down. So choose best side
+ if (spritePt.x >= (objBounds.left + objBounds.width() / 2))
walkPos.x = objBounds.right + CLEAR_DIST_X;
- else if (_delta.x < 0) {
- // Go to left side
+ else
walkPos.x = objBounds.left - CLEAR_DIST_X;
- } else {
- // Going straight up or down. So choose best side
- if (spritePt.x >= (objBounds.left + objBounds.width() / 2))
- walkPos.x = objBounds.right + CLEAR_DIST_X;
- else
- walkPos.x = objBounds.left - CLEAR_DIST_X;
- }
-
- walkPos.y = (_delta.y >= 0) ? objBounds.top - CLEAR_DIST_Y :
- objBounds.bottom + CLEAR_DIST_Y;
- } else {
- // Impact occurred due to horizontal movement
- if (_delta.y > 0)
- // Go to bottom of box
+ }
+
+ walkPos.y = (_delta.y >= 0) ? objBounds.top - CLEAR_DIST_Y :
+ objBounds.bottom + CLEAR_DIST_Y;
+ } else {
+ // Impact occurred due to horizontal movement
+ if (_delta.y > 0)
+ // Go to bottom of box
+ walkPos.y = objBounds.bottom + CLEAR_DIST_Y;
+ else if (_delta.y < 0)
+ // Go to top of box
+ walkPos.y = objBounds.top - CLEAR_DIST_Y;
+ else {
+ // Going straight horizontal, so choose best side
+ if (spritePt.y >= (objBounds.top + objBounds.height() / 2))
walkPos.y = objBounds.bottom + CLEAR_DIST_Y;
- else if (_delta.y < 0)
- // Go to top of box
+ else
walkPos.y = objBounds.top - CLEAR_DIST_Y;
- else {
- // Going straight horizontal, so choose best side
- if (spritePt.y >= (objBounds.top + objBounds.height() / 2))
- walkPos.y = objBounds.bottom + CLEAR_DIST_Y;
- else
- walkPos.y = objBounds.top - CLEAR_DIST_Y;
- }
-
- walkPos.x = (_delta.x >= 0) ? objBounds.left - CLEAR_DIST_X :
- objBounds.right + CLEAR_DIST_X;
}
- walkPos.x += people[HOLMES]._imageFrame->_frame.w / 2;
- people._walkDest = walkPos;
- people[HOLMES]._walkTo.push(walkPos);
- people[HOLMES].setWalking();
+ walkPos.x = (_delta.x >= 0) ? objBounds.left - CLEAR_DIST_X :
+ objBounds.right + CLEAR_DIST_X;
}
- break;
-
- case DELTA:
- _position.x += 200;
- break;
- default:
- break;
+ walkPos.x += people[HOLMES]._imageFrame->_frame.w / 2;
+ people._walkDest = walkPos;
+ people[HOLMES]._walkTo.push(walkPos);
+ people[HOLMES].setWalking();
}
+ break;
+
+ case DELTA:
+ _position.x += 200;
+ break;
+
+ default:
+ break;
}
}
}
diff --git a/engines/sherlock/people.cpp b/engines/sherlock/people.cpp
index 349be671a4..7cdaab7626 100644
--- a/engines/sherlock/people.cpp
+++ b/engines/sherlock/people.cpp
@@ -73,8 +73,7 @@ Person::Person() : Sprite() {
void Person::goAllTheWay() {
People &people = *_vm->_people;
Scene &scene = *_vm->_scene;
- Common::Point srcPt(_position.x / FIXED_INT_MULTIPLIER + frameWidth() / 2,
- _position.y / FIXED_INT_MULTIPLIER);
+ Common::Point srcPt = getSourcePoint();
// Get the zone the player is currently in
_srcZone = scene.whichZone(srcPt);
diff --git a/engines/sherlock/people.h b/engines/sherlock/people.h
index 19e050ead1..5b5aac6908 100644
--- a/engines/sherlock/people.h
+++ b/engines/sherlock/people.h
@@ -57,6 +57,11 @@ struct PersonData {
};
class Person : public Sprite {
+protected:
+ /**
+ * Get the source position for a character potentially affected by scaling
+ */
+ virtual Common::Point getSourcePoint() const = 0;
public:
Common::Queue<Common::Point> _walkTo;
int _srcZone, _destZone;
diff --git a/engines/sherlock/scalpel/scalpel_people.cpp b/engines/sherlock/scalpel/scalpel_people.cpp
index 89f3eeaeb6..72d8d32812 100644
--- a/engines/sherlock/scalpel/scalpel_people.cpp
+++ b/engines/sherlock/scalpel/scalpel_people.cpp
@@ -334,6 +334,11 @@ void ScalpelPerson::setWalking() {
_frameNumber = oldFrame;
}
+Common::Point ScalpelPerson::getSourcePoint() const {
+ return Common::Point(_position.x / FIXED_INT_MULTIPLIER + frameWidth() / 2,
+ _position.y / FIXED_INT_MULTIPLIER);
+}
+
/*----------------------------------------------------------------*/
ScalpelPeople::ScalpelPeople(SherlockEngine *vm) : People(vm) {
diff --git a/engines/sherlock/scalpel/scalpel_people.h b/engines/sherlock/scalpel/scalpel_people.h
index 9d1214bc68..dc1258308f 100644
--- a/engines/sherlock/scalpel/scalpel_people.h
+++ b/engines/sherlock/scalpel/scalpel_people.h
@@ -42,6 +42,11 @@ enum ScalpelSequences {
};
class ScalpelPerson : public Person {
+protected:
+ /**
+ * Get the source position for a character potentially affected by scaling
+ */
+ virtual Common::Point getSourcePoint() const;
public:
ScalpelPerson() : Person() {}
virtual ~ScalpelPerson() {}
diff --git a/engines/sherlock/scalpel/scalpel_scene.cpp b/engines/sherlock/scalpel/scalpel_scene.cpp
index c4da8e09a0..723939211a 100644
--- a/engines/sherlock/scalpel/scalpel_scene.cpp
+++ b/engines/sherlock/scalpel/scalpel_scene.cpp
@@ -135,7 +135,6 @@ void ScalpelScene::drawAllShapes() {
screen.resetDisplayBounds();
}
-
void ScalpelScene::checkBgShapes() {
People &people = *_vm->_people;
Person &holmes = people[HOLMES];
diff --git a/engines/sherlock/tattoo/tattoo_people.cpp b/engines/sherlock/tattoo/tattoo_people.cpp
index ebada5627c..cec8cd9bdf 100644
--- a/engines/sherlock/tattoo/tattoo_people.cpp
+++ b/engines/sherlock/tattoo/tattoo_people.cpp
@@ -286,18 +286,28 @@ void TattooPerson::setWalking() {
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));
+ Common::Point diagSpeed(MAX(WALK_SPEED_DIAG_X[scene._currentScene - 1] * SCALE_THRESHOLD / scaleVal, 2),
+ MAX((WALK_SPEED_Y[scene._currentScene - 1] - 2) * 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;
+ if (_centerWalk || !_walkTo.empty()) {
+ // Since we want the player to be centered on the ultimate destination, and the player
+ // is drawn from the left side, move the cursor half the width of the player to center it
+ delta = Common::Point(_position.x / FIXED_INT_MULTIPLIER - people._walkDest.x,
+ _position.y / FIXED_INT_MULTIPLIER - people._walkDest.y);
+
+ int dir;
+ if (ABS(delta.x) > ABS(delta.y))
+ dir = (delta.x < 0) ? WALK_LEFT : WALK_RIGHT;
+ else
+ dir = (delta.y < 0) ? WALK_UP : WALK_DOWN;
+
+ int scaleVal = scene.getScaleVal(Point32(people._walkDest.x * FIXED_INT_MULTIPLIER,
+ people._walkDest.y * FIXED_INT_MULTIPLIER));
+ people._walkDest.x -= _stopFrames[dir]->sDrawXSize(scaleVal) / 2;
+ }
delta = Common::Point(
ABS(_position.x / FIXED_INT_MULTIPLIER - people._walkDest.x),
@@ -321,22 +331,22 @@ void TattooPerson::setWalking() {
// 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;
+ _delta.x = speed.x * -(FIXED_INT_MULTIPLIER / 10);
} else {
_sequenceNumber = WALK_RIGHT;
- _delta.x = speed.x * FIXED_INT_MULTIPLIER;
+ _delta.x = speed.x * (FIXED_INT_MULTIPLIER / 10);
}
// 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) {
+ if ((delta.x * 10) >= speed.x) {
// Det the delta y
- _delta.y = (delta.y * FIXED_INT_MULTIPLIER) / (delta.x / speed.x);
+ _delta.y = (delta.y * FIXED_INT_MULTIPLIER) / ((delta.x * 10) / 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;
+ _walkCount = (delta.x * 10) / 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
@@ -365,6 +375,7 @@ void TattooPerson::setWalking() {
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);
+ _walkCount = (delta.x * 10) / diagSpeed.x;
}
switch (_sequenceNumber) {
@@ -435,6 +446,14 @@ void TattooPerson::pushNPCPath() {
warning("TODO: pushNPCPath");
}
+Common::Point TattooPerson::getSourcePoint() const {
+ TattooScene &scene = *(TattooScene *)_vm->_scene;
+ int scaleVal = scene.getScaleVal(_position);
+
+ return Common::Point(_position.x / FIXED_INT_MULTIPLIER + _imageFrame->sDrawXSize(scaleVal) / 2,
+ _position.y / FIXED_INT_MULTIPLIER);
+}
+
/*----------------------------------------------------------------*/
TattooPeople::TattooPeople(SherlockEngine *vm) : People(vm) {
diff --git a/engines/sherlock/tattoo/tattoo_people.h b/engines/sherlock/tattoo/tattoo_people.h
index 50a0cb13ce..25a76b66f9 100644
--- a/engines/sherlock/tattoo/tattoo_people.h
+++ b/engines/sherlock/tattoo/tattoo_people.h
@@ -74,6 +74,11 @@ enum TattooSequences {
class TattooPerson: public Person {
private:
bool checkCollision() const;
+protected:
+ /**
+ * Get the source position for a character potentially affected by scaling
+ */
+ virtual Common::Point getSourcePoint() const;
public:
int _npcIndex;
int _npcStack;
diff --git a/engines/sherlock/tattoo/tattoo_scene.cpp b/engines/sherlock/tattoo/tattoo_scene.cpp
index ad7d5c0f55..1cc7b65289 100644
--- a/engines/sherlock/tattoo/tattoo_scene.cpp
+++ b/engines/sherlock/tattoo/tattoo_scene.cpp
@@ -720,7 +720,7 @@ void TattooScene::doBgAnimDrawSprites() {
}
}
-int TattooScene::getScaleVal(const Common::Point &pt) {
+int TattooScene::getScaleVal(const Point32 &pt) {
bool found = false;
int result = SCALE_THRESHOLD;
Common::Point pos(pt.x / FIXED_INT_MULTIPLIER, pt.y / FIXED_INT_MULTIPLIER);
diff --git a/engines/sherlock/tattoo/tattoo_scene.h b/engines/sherlock/tattoo/tattoo_scene.h
index 849144e07c..5561b77aa4 100644
--- a/engines/sherlock/tattoo/tattoo_scene.h
+++ b/engines/sherlock/tattoo/tattoo_scene.h
@@ -119,7 +119,7 @@ public:
* 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);
+ int getScaleVal(const Point32 &pt);
/**
* Draw all objects and characters.
diff --git a/engines/sherlock/tattoo/tattoo_user_interface.cpp b/engines/sherlock/tattoo/tattoo_user_interface.cpp
index 915acde400..e6a6430a3e 100644
--- a/engines/sherlock/tattoo/tattoo_user_interface.cpp
+++ b/engines/sherlock/tattoo/tattoo_user_interface.cpp
@@ -403,6 +403,12 @@ void TattooUserInterface::doStandardControl() {
}
}
}
+ static bool flag = false;
+ if (!flag) {
+ flag = true;
+ people._walkDest = Common::Point(235, 370);
+ people[HOLMES].goAllTheWay();
+ }
}
void TattooUserInterface::doLookControl() {