aboutsummaryrefslogtreecommitdiff
path: root/engines/sherlock
diff options
context:
space:
mode:
authorPaul Gilbert2015-03-21 11:24:35 -0400
committerPaul Gilbert2015-03-21 11:24:35 -0400
commitb6076dd52458320f39442bc225ef8b0ce531ea51 (patch)
treedd8ac2cc125e2fe43ea431437b55c8df37160fad /engines/sherlock
parent06fbefc7875b37dd531b65c42087e4e6782c03a6 (diff)
downloadscummvm-rg350-b6076dd52458320f39442bc225ef8b0ce531ea51.tar.gz
scummvm-rg350-b6076dd52458320f39442bc225ef8b0ce531ea51.tar.bz2
scummvm-rg350-b6076dd52458320f39442bc225ef8b0ce531ea51.zip
SHERLOCK: Implemented setWalking
Diffstat (limited to 'engines/sherlock')
-rw-r--r--engines/sherlock/objects.cpp17
-rw-r--r--engines/sherlock/objects.h18
-rw-r--r--engines/sherlock/people.cpp204
-rw-r--r--engines/sherlock/people.h20
-rw-r--r--engines/sherlock/scene.cpp2
-rw-r--r--engines/sherlock/scene.h2
-rw-r--r--engines/sherlock/sherlock.cpp15
-rw-r--r--engines/sherlock/sherlock.h1
8 files changed, 240 insertions, 39 deletions
diff --git a/engines/sherlock/objects.cpp b/engines/sherlock/objects.cpp
index 3fc9901a38..63e4bdf621 100644
--- a/engines/sherlock/objects.cpp
+++ b/engines/sherlock/objects.cpp
@@ -21,9 +21,14 @@
*/
#include "sherlock/objects.h"
+#include "sherlock/sherlock.h"
+#include "sherlock/people.h"
+#include "sherlock/scene.h"
namespace Sherlock {
+SherlockEngine *Sprite::_vm;
+
/**
* Reset the data for the sprite
*/
@@ -39,7 +44,7 @@ void Sprite::clear() {
_allow = 0;
_frameNumber = _sequenceNumber = 0;
_position.x = _position.y = 0;
- _movement.x = _movement.y = 0;
+ _delta.x = _delta.y = 0;
_oldPosition.x = _oldPosition.y = 0;
_oldSize.x = _oldSize.y = 0;
_goto.x = _goto.y = 0;
@@ -57,15 +62,7 @@ void Sprite::setImageFrame() {
_imageFrame = &(*_images)[imageNumber];
}
-void Sprite::adjustSprite(bool onChessboard) {
- // TODO
-}
-
-void Sprite::gotoStand() {
- // TODO
-}
-
-void Sprite::setWalking() {
+void Sprite::adjustSprite() {
// TODO
}
diff --git a/engines/sherlock/objects.h b/engines/sherlock/objects.h
index a1bdc5933c..b1207867e4 100644
--- a/engines/sherlock/objects.h
+++ b/engines/sherlock/objects.h
@@ -74,7 +74,10 @@ enum AType {
#define FLIP_CODE (64 + 128)
#define SOUND_CODE (34 + 128)
-struct Sprite {
+class Sprite {
+private:
+ static SherlockEngine *_vm;
+public:
Common::String _name; // Name
Common::String _description; // Description
Common::StringArray _examine; // Examine in-depth description
@@ -88,7 +91,7 @@ struct Sprite {
int _frameNumber; // Frame number in rame sequence to draw
int _sequenceNumber; // Sequence being used
Common::Point _position; // Current position
- Common::Point _movement; // Momvement amount
+ Common::Point _delta; // Momvement delta
Common::Point _oldPosition; // Old position
Common::Point _oldSize; // Image's old size
Common::Point _goto; // Walk destination
@@ -98,18 +101,15 @@ struct Sprite {
int _status; // Status: open/closed, moved/not moved
int8 _misc; // Miscellaneous use
int _numFrames; // How many frames the object has
-
+public:
Sprite() { clear(); }
-
+ static void setVm(SherlockEngine *vm) { _vm = vm; }
+
void clear();
void setImageFrame();
- void adjustSprite(bool onChessboard = false);
-
- void gotoStand();
-
- void setWalking();
+ void adjustSprite();
};
struct ActionType {
diff --git a/engines/sherlock/people.cpp b/engines/sherlock/people.cpp
index b187b65ad4..998fe4f0cf 100644
--- a/engines/sherlock/people.cpp
+++ b/engines/sherlock/people.cpp
@@ -21,9 +21,15 @@
*/
#include "sherlock/people.h"
+#include "sherlock/sherlock.h"
namespace Sherlock {
+// Walk speeds
+#define MWALK_SPEED 2
+#define XWALK_SPEED 4
+#define YWALK_SPEED 1
+
// Characer animation sequences
static const uint8 CHARACTER_SEQUENCES[MAX_HOLMES_SEQUENCE][MAX_FRAME] = {
{ 29, 1, 2, 3, 4, 5, 6, 7, 0 }, // Walk Right
@@ -45,9 +51,11 @@ static const uint8 CHARACTER_SEQUENCES[MAX_HOLMES_SEQUENCE][MAX_FRAME] = {
};
-People::People(SherlockEngine *vm) : _vm(vm) {
+People::People(SherlockEngine *vm) : _vm(vm), _player(_data[0]) {
_walkLoaded = false;
_holmesOn = true;
+ _oldWalkSequence = -1;
+ _allowWalkAbort = false;
}
People::~People() {
@@ -65,7 +73,7 @@ void People::reset() {
p._sequences = &CHARACTER_SEQUENCES;
p._imageFrame = nullptr;
p._frameNumber = 1;
- p._movement = Common::Point(0, 0);
+ p._delta = Common::Point(0, 0);
p._oldPosition = Common::Point(0, 0);
p._oldSize = Common::Point(0, 0);
p._misc = 0;
@@ -89,4 +97,196 @@ bool People::loadWalk() {
}
}
+/**
+* Set the variables for moving a character from one poisition to another
+* in a straight line - goAllTheWay must have been previously called to
+* check for any obstacles in the path.
+*/
+void People::setWalking() {
+ Scene &scene = *_vm->_scene;
+ int oldDirection, oldFrame;
+ Common::Point speed, delta;
+ int temp;
+
+ // Flag that player has now walked in the scene
+ scene._walkedInScene = true;
+
+ // Stop any previous walking, since a new dest is being set
+ _player._walkCount = 0;
+ oldDirection = _player._sequenceNumber;
+ oldFrame = _player._frameNumber;
+
+ // Set speed to use horizontal and vertical movement
+ if (_vm->_onChessboard) {
+ speed = Common::Point(MWALK_SPEED, MWALK_SPEED);
+ } else {
+ speed = Common::Point(XWALK_SPEED, YWALK_SPEED);
+ }
+
+ // 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
+ if (_walkDest.x >= (temp = _player._imageFrame->_frame.w / 2))
+ _walkDest.x -= temp;
+
+ delta = Common::Point(
+ ABS(_player._position.x / 100 - _walkDest.x),
+ ABS(_player._position.y / 100 - _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
+ _walkDest = _walkTo.pop();
+ } while (!_vm->shouldQuit());
+
+ // 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 settting the delta x depending on direction
+ if (_walkDest.x < (_player._position.x / 100)) {
+ _player._sequenceNumber = _vm->_onChessboard ? MAP_LEFT : WALK_LEFT;
+ _player._delta.x = speed.x * -100;
+ } else {
+ _player._sequenceNumber = _vm->_onChessboard ? MAP_RIGHT : WALK_RIGHT;
+ _player._delta.x = speed.x * 100;
+ }
+
+ // 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
+ _player._delta.y = (delta.y * 100) / (delta.x / speed.x);
+ if (_walkDest.y < (_player._position.y / 100))
+ _player._delta.y = -_player._delta.y;
+
+ // Set how many times we should add the delta to the player's position
+ _player._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
+ _player._delta = Common::Point(0, 0);
+ _player._position = Common::Point(_walkDest.x * 100, _walkDest.y * 100);
+ _player._walkCount = 1;
+ }
+
+ // See if the sequence needs to be changed for diagonal walking
+ if (_player._delta.y > 150) {
+ if (!_vm->_onChessboard) {
+ switch (_player._sequenceNumber) {
+ case WALK_LEFT:
+ _player._sequenceNumber = WALK_DOWNLEFT;
+ break;
+ case WALK_RIGHT:
+ _player._sequenceNumber = WALK_DOWNRIGHT;
+ break;
+ }
+ }
+ } else if (_player._delta.y < -150) {
+ if (!_vm->_onChessboard) {
+ switch (_player._sequenceNumber) {
+ case WALK_LEFT:
+ _player._sequenceNumber = WALK_UPLEFT;
+ break;
+ case WALK_RIGHT:
+ _player._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 (_walkDest.y < (_player._position.y / 100)) {
+ _player._sequenceNumber = WALK_UP;
+ _player._delta.y = speed.y * -100;
+ } else {
+ _player._sequenceNumber = WALK_DOWN;
+ _player._delta.y = speed.y * 100;
+ }
+
+ // If we're on the overhead map, set the sequence so we keep moving
+ // in the same direction
+ _player._sequenceNumber = (oldDirection == -1) ? MAP_RIGHT : oldDirection;
+
+ // Set the delta x
+ _player._delta.x = (delta.x * 100) / (delta.y / speed.y);
+ if (_walkDest.x < (_player._position.x / 100))
+ _player._delta.x = -_player._delta.x;
+ }
+ }
+
+ // 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 (_player._sequenceNumber != _oldWalkSequence)
+ _player._frameNumber = 0;
+ _oldWalkSequence = _player._sequenceNumber;
+
+ if (!_player._walkCount)
+ gotoStand(_player);
+
+ // 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 (_player._sequenceNumber == oldDirection)
+ _player._frameNumber = oldFrame;
+}
+
+/**
+ * Bring a moving character to a standing position. If the Scalpel chessboard
+ * is being displayed, then the chraracter will always face down.
+ */
+void People::gotoStand(Sprite &sprite) {
+ Scene &scene = *_vm->_scene;
+ _walkTo.clear();
+ sprite._walkCount = 0;
+
+ switch (sprite._sequenceNumber) {
+ case WALK_UP:
+ sprite._sequenceNumber = STOP_UP; break;
+ case WALK_DOWN:
+ sprite._sequenceNumber = STOP_DOWN; break;
+ case TALK_LEFT:
+ case WALK_LEFT:
+ sprite._sequenceNumber = STOP_LEFT; break;
+ case TALK_RIGHT:
+ case WALK_RIGHT:
+ sprite._sequenceNumber = STOP_RIGHT; break;
+ case WALK_UPRIGHT:
+ sprite._sequenceNumber = STOP_UPRIGHT; break;
+ case WALK_UPLEFT:
+ sprite._sequenceNumber = STOP_UPLEFT; break;
+ case WALK_DOWNRIGHT:
+ sprite._sequenceNumber = STOP_DOWNRIGHT; break;
+ case WALK_DOWNLEFT:
+ sprite._sequenceNumber = STOP_DOWNLEFT; break;
+ default:
+ break;
+ }
+
+ // Only restart frame at 0 if the sequence number has changed
+ if (_oldWalkSequence != -1 || sprite._sequenceNumber == STOP_UP)
+ sprite._frameNumber = 0;
+
+ if (_vm->_onChessboard) {
+ sprite._sequenceNumber = 0;
+ _data[AL]._position.x = (_vm->_map[scene._charPoint].x - 6) * 100;
+ _data[AL]._position.y = (_vm->_map[scene._charPoint].x + 10) * 100;
+ }
+
+ _oldWalkSequence = -1;
+ _allowWalkAbort = true;
+}
+
} // End of namespace Sherlock
diff --git a/engines/sherlock/people.h b/engines/sherlock/people.h
index 74a4575af6..be9be006e8 100644
--- a/engines/sherlock/people.h
+++ b/engines/sherlock/people.h
@@ -24,6 +24,7 @@
#define SHERLOCK_PEOPLE_H
#include "common/scummsys.h"
+#include "common/stack.h"
#include "sherlock/objects.h"
namespace Sherlock {
@@ -39,10 +40,14 @@ enum PeopleId {
// Animation sequence identifiers for characters
enum {
WALK_RIGHT = 0, WALK_DOWN = 1, WALK_LEFT = 2, WALK_UP = 3, STOP_LEFT = 4,
- STOP_DOWN = 5, STOP_RIGHT = 6, STOP_UP = 7, WALK_UPRIGHT = 8,
+ STOP_DOWN = 5, STOP_RIGHT = 6, STOP_UP = 7, WALK_UPRIGHT = 8,
WALK_DOWNRIGHT = 9, WALK_UPLEFT = 10, WALK_DOWNLEFT = 11,
STOP_UPRIGHT = 12, STOP_UPLEFT = 13, STOP_DOWNRIGHT = 14,
- STOP_DOWNLEFT = 15, TALK_RIGHT = 6, TALK_LEFT = 4
+ STOP_DOWNLEFT = 15, TALK_RIGHT = 6, TALK_LEFT = 4,
+};
+enum {
+ MAP_UP = 1, MAP_UPRIGHT = 2, MAP_RIGHT = 1, MAP_DOWNRIGHT = 4,
+ MAP_DOWN = 5, MAP_DOWNLEFT = 6, MAP_LEFT = 2, MAP_UPLEFT = 8
};
class SherlockEngine;
@@ -51,18 +56,27 @@ class People {
private:
SherlockEngine *_vm;
Sprite _data[MAX_PEOPLE];
+ Sprite &_player;
bool _walkLoaded;
+ int _oldWalkSequence;
+ bool _allowWalkAbort;
public:
+ Common::Point _walkDest;
+ Common::Stack<Common::Point> _walkTo;
bool _holmesOn;
public:
People(SherlockEngine *vm);
~People();
+ Sprite &operator[](PeopleId id) { return _data[id]; }
+
void reset();
bool loadWalk();
- Sprite &operator[](PeopleId id) { return _data[id]; }
+ void setWalking();
+
+ void gotoStand(Sprite &sprite);
};
} // End of namespace Sherlock
diff --git a/engines/sherlock/scene.cpp b/engines/sherlock/scene.cpp
index 8875327dcf..13db8d9b94 100644
--- a/engines/sherlock/scene.cpp
+++ b/engines/sherlock/scene.cpp
@@ -86,7 +86,7 @@ Scene::Scene(SherlockEngine *vm): _vm(vm) {
_currentScene = -1;
_goToRoom = -1;
_changes = false;
- _oldCharPoint = 0;
+ _charPoint = _oldCharPoint = 0;
_windowOpen = _infoFlag = false;
_menuMode = _keyboardInput = 0;
_walkedInScene = false;
diff --git a/engines/sherlock/scene.h b/engines/sherlock/scene.h
index 5625bb1f5b..a4b94652c8 100644
--- a/engines/sherlock/scene.h
+++ b/engines/sherlock/scene.h
@@ -108,7 +108,7 @@ public:
bool _savedStats[SCENES_COUNT][9];
Common::Point _bigPos;
Common::Point _overPos;
- int _oldCharPoint;
+ int _charPoint, _oldCharPoint;
ImageFile *_controls;
ImageFile *_controlPanel;
bool _windowOpen, _infoFlag;
diff --git a/engines/sherlock/sherlock.cpp b/engines/sherlock/sherlock.cpp
index 60e32bda82..2787e2b924 100644
--- a/engines/sherlock/sherlock.cpp
+++ b/engines/sherlock/sherlock.cpp
@@ -44,6 +44,7 @@ SherlockEngine::SherlockEngine(OSystem *syst, const SherlockGameDescription *gam
_useEpilogue2 = false;
_justLoaded = false;
_talkToAbort = false;
+ _onChessboard = false;
}
SherlockEngine::~SherlockEngine() {
@@ -65,20 +66,8 @@ void SherlockEngine::initialize() {
DebugMan.addDebugChannel(kDebugScript, "scripts", "Script debug level");
- /*
- int midiDriver = MidiDriver::detectMusicDriver(MDT_MIDI | MDT_ADLIB | MDT_PREFER_MIDI);
- bool native_mt32 = ((midiDriver == MD_MT32) || ConfMan.getBool("native_mt32"));
-
- MidiDriver *driver = MidiDriver::createMidi(midiDriver);
- if (native_mt32)
- driver->property(MidiDriver::PROP_CHANNEL_MASK, 0x03FE);
-
- _midi = new MidiPlayer(this, driver);
- _midi->setGM(true);
- _midi->setNativeMT32(native_mt32);
- */
-
ImageFile::setVm(this);
+ Sprite::setVm(this);
_res = new Resources();
_animation = new Animation(this);
_debugger = new Debugger(this);
diff --git a/engines/sherlock/sherlock.h b/engines/sherlock/sherlock.h
index 84b6c48f12..1607cec974 100644
--- a/engines/sherlock/sherlock.h
+++ b/engines/sherlock/sherlock.h
@@ -97,6 +97,7 @@ public:
Common::Point _over; // Old map position
Common::Array<Common::Point> _map; // Map locations for each scene
bool _talkToAbort;
+ bool _onChessboard;
public:
SherlockEngine(OSystem *syst, const SherlockGameDescription *gameDesc);
virtual ~SherlockEngine();