aboutsummaryrefslogtreecommitdiff
path: root/engines
diff options
context:
space:
mode:
Diffstat (limited to 'engines')
-rw-r--r--engines/sherlock/graphics.cpp26
-rw-r--r--engines/sherlock/graphics.h8
-rw-r--r--engines/sherlock/objects.cpp104
-rw-r--r--engines/sherlock/objects.h5
-rw-r--r--engines/sherlock/people.h2
-rw-r--r--engines/sherlock/scene.cpp107
-rw-r--r--engines/sherlock/scene.h8
-rw-r--r--engines/sherlock/sherlock.cpp3
-rw-r--r--engines/sherlock/sherlock.h3
9 files changed, 251 insertions, 15 deletions
diff --git a/engines/sherlock/graphics.cpp b/engines/sherlock/graphics.cpp
index a4990fb6c6..8c096e3c72 100644
--- a/engines/sherlock/graphics.cpp
+++ b/engines/sherlock/graphics.cpp
@@ -27,12 +27,22 @@
namespace Sherlock {
-Surface::Surface(uint16 width, uint16 height) {
+Surface::Surface(uint16 width, uint16 height): _freePixels(true) {
create(width, height, Graphics::PixelFormat::createFormatCLUT8());
}
+Surface::Surface(Surface &src, const Common::Rect &r) : _freePixels(false) {
+ setPixels(src.getBasePtr(r.left, r.top));
+ w = r.width();
+ h = r.height();
+ pitch = src.pitch;
+ format = Graphics::PixelFormat::createFormatCLUT8();
+}
+
+
Surface::~Surface() {
- free();
+ if (_freePixels)
+ free();
}
/**
@@ -131,9 +141,19 @@ void Surface::transBlitFrom(const Graphics::Surface &src, const Common::Point &p
}
}
-
+/**
+ * Fill a given area of the surface with a given color
+ */
void Surface::fillRect(int x1, int y1, int x2, int y2, byte color) {
Graphics::Surface::fillRect(Common::Rect(x1, y1, x2, y2), color);
}
+/**
+ * Return a sub-area of the surface as a new surface object. The surfaces
+ * are shared in common, so changes in the sub-surface affects the original.
+ */
+Surface Surface::getSubArea(const Common::Rect &r) {
+ return Surface(*this, r);
+}
+
} // End of namespace Sherlock
diff --git a/engines/sherlock/graphics.h b/engines/sherlock/graphics.h
index 82c48307d7..0536c016bf 100644
--- a/engines/sherlock/graphics.h
+++ b/engines/sherlock/graphics.h
@@ -29,11 +29,15 @@
namespace Sherlock {
class Surface : public Graphics::Surface {
+private:
+ bool _freePixels;
protected:
virtual void addDirtyRect(const Common::Rect &r) {}
+
+ Surface(Surface &src, const Common::Rect &r);
public:
Surface(uint16 width, uint16 height);
- ~Surface();
+ ~Surface();
void blitFrom(const Graphics::Surface &src);
void blitFrom(const Graphics::Surface &src, const Common::Point &pt);
@@ -43,6 +47,8 @@ public:
bool flipped = false, int overrideColor = 0);
void fillRect(int x1, int y1, int x2, int y2, byte color);
+
+ Surface getSubArea(const Common::Rect &r);
};
} // End of namespace Sherlock
diff --git a/engines/sherlock/objects.cpp b/engines/sherlock/objects.cpp
index 63e4bdf621..a12939e787 100644
--- a/engines/sherlock/objects.cpp
+++ b/engines/sherlock/objects.cpp
@@ -24,9 +24,15 @@
#include "sherlock/sherlock.h"
#include "sherlock/people.h"
#include "sherlock/scene.h"
+#include "common/util.h"
namespace Sherlock {
+#define UPPER_LIMIT 0
+#define LOWER_LIMIT CONTROLS_Y
+#define LEFT_LIMIT 0
+#define RIGHT_LIMIT SHERLOCK_SCREEN_WIDTH
+
SherlockEngine *Sprite::_vm;
/**
@@ -56,14 +62,106 @@ void Sprite::clear() {
_numFrames = 0;
}
+/**
+ * Updates the image frame poiner for the sprite
+ */
void Sprite::setImageFrame() {
- // TODO: check this
- int imageNumber = (*_sequences)[_sequenceNumber][_frameNumber];
+ int imageNumber = (*_sequences)[_sequenceNumber][_frameNumber] +
+ (*_sequences)[_sequenceNumber][0] - 2;
_imageFrame = &(*_images)[imageNumber];
}
+/**
+ * This adjusts the sprites position, as well as it's animation sequence:
+ */
void Sprite::adjustSprite() {
- // TODO
+ People &people = *_vm->_people;
+ Scene &scene = *_vm->_scene;
+ int checkFrame = _allow ? MAX_FRAME : 32000;
+
+ if (_type == INVALID || (_type == CHARACTER && _vm->_animating))
+ return;
+
+ if (!_vm->_talkCounter && _type == CHARACTER && _walkCount) {
+ // Handle active movement for the sprite
+ _position += _delta;
+ --_walkCount;
+
+ if (!_walkCount) {
+ // If there any points left for the character to walk to along the
+ // route to a destination, then move to the next point
+ if (!people._walkTo.empty()) {
+ people._walkDest = people._walkTo.pop();
+ people.setWalking();
+ } else {
+ people.gotoStand(*this);
+ }
+ }
+ }
+
+ if (_type == CHARACTER && !_vm->_onChessboard) {
+ if ((_position.y / 100) > LOWER_LIMIT) {
+ _position.y = LOWER_LIMIT * 100;
+ people.gotoStand(*this);
+ }
+
+ if ((_position.y / 100) < UPPER_LIMIT) {
+ _position.y = UPPER_LIMIT * 100;
+ people.gotoStand(*this);
+ }
+
+ if ((_position.x / 100) < LEFT_LIMIT) {
+ _position.x = LEFT_LIMIT * 100;
+ people.gotoStand(*this);
+ }
+ } else if (!_vm->_onChessboard) {
+ _position.y = CLIP((int)_position.y, UPPER_LIMIT, LOWER_LIMIT);
+ _position.x = CLIP((int)_position.x, LEFT_LIMIT, RIGHT_LIMIT);
+ }
+
+ if (!_vm->_onChessboard || (_vm->_slowChess = !_vm->_slowChess))
+ ++_frameNumber;
+
+ if ((*_sequences)[_sequenceNumber][_frameNumber] == 0) {
+ switch (_sequenceNumber) {
+ case STOP_UP:
+ case STOP_DOWN:
+ case STOP_LEFT:
+ case STOP_RIGHT:
+ case STOP_UPRIGHT:
+ case STOP_UPLEFT:
+ case STOP_DOWNRIGHT:
+ case STOP_DOWNLEFT:
+ // We're in a stop sequence, so reset back to the last frame, so
+ // the character is shown as standing still
+ --_frameNumber;
+ break;
+
+ default:
+ // Move 1 past the first frame - we need to compensate, since we
+ // already passed the frame increment
+ _frameNumber = 1;
+ break;
+ }
+ }
+
+ // Update the _imageFrame to point to the new frame's image
+ setImageFrame();
+
+ // Check to see if character has entered an exit zone
+ if (!_walkCount && scene._walkedInScene && scene._goToRoom == -1) {
+ Common::Rect charRect(_position.x / 100 - 5, _position.y / 100 - 2,
+ _position.x / 100 + 5, _position.y / 100 + 2);
+ Exit *exit = scene.checkForExit(charRect);
+
+ if (exit) {
+ scene._hsavedPos = exit->_people;
+ scene._hsavedFs = exit->_peopleDir;
+
+ if (scene._hsavedFs > 100 && scene._hsavedPos.x < 1)
+ scene._hsavedPos.x = 100;
+ }
+ }
}
/*----------------------------------------------------------------*/
diff --git a/engines/sherlock/objects.h b/engines/sherlock/objects.h
index b1207867e4..d9f1c7409e 100644
--- a/engines/sherlock/objects.h
+++ b/engines/sherlock/objects.h
@@ -66,6 +66,11 @@ enum AType {
NOWALK_ZONE = 13 // Player cannot walk here
};
+// Different levels for sprites to be at
+enum {
+ BEHIND = 0, NORMAL_BEHIND = 1, NORMAL_FORWARD = 2, FORWARD = 3
+};
+
#define MAX_HOLMES_SEQUENCE 16
#define MAX_FRAME 30
diff --git a/engines/sherlock/people.h b/engines/sherlock/people.h
index be9be006e8..e58fd33ef2 100644
--- a/engines/sherlock/people.h
+++ b/engines/sherlock/people.h
@@ -70,6 +70,8 @@ public:
Sprite &operator[](PeopleId id) { return _data[id]; }
+ bool isHolmesActive() const { return _walkLoaded && _holmesOn; }
+
void reset();
bool loadWalk();
diff --git a/engines/sherlock/scene.cpp b/engines/sherlock/scene.cpp
index 13db8d9b94..9fbec6b776 100644
--- a/engines/sherlock/scene.cpp
+++ b/engines/sherlock/scene.cpp
@@ -49,10 +49,12 @@ void BgfileheaderInfo::synchronize(Common::SeekableReadStream &s) {
/*----------------------------------------------------------------*/
void Exit::synchronize(Common::SeekableReadStream &s) {
- _position.x = s.readSint16LE();
- _position.y = s.readSint16LE();
- _size.x = s.readSint16LE();
- _size.y = s.readSint16LE();
+ int xp = s.readSint16LE();
+ int yp = s.readSint16LE();
+ int xSize = s.readSint16LE();
+ int ySize = s.readSint16LE();
+ _bounds = Common::Rect(xp, yp, xp + xSize, yp + ySize);
+
_scene = s.readSint16LE();
_allow = s.readSint16LE();
_people.x = s.readSint16LE();
@@ -623,13 +625,106 @@ int Scene::toggleObject(const Common::String &name) {
*/
void Scene::updateBackground() {
People &people = *_vm->_people;
- //setDisplayBounds(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCENE_HEIGHT);
+ Screen &screen = *_vm->_screen;
+ Surface surface = screen._backBuffer.getSubArea(
+ Common::Rect(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCENE_HEIGHT));
+ Sprite &player = people[AL];
// Update Holmes if he's turned on
if (people._holmesOn)
- people[AL].adjustSprite();
+ player.adjustSprite();
+
+ // Flag the bg shapes which need to be redrawn
+ checkBgShapes(player._imageFrame, Common::Point(player._position.x / 100,
+ player._position.y / 100));
+
+ // Draw all active shapes which are behind the person
+ for (uint idx = 0; idx < _bgShapes.size(); ++idx) {
+ if (_bgShapes[idx]._type == ACTIVE_BG_SHAPE && _bgShapes[idx]._misc == BEHIND)
+ surface.transBlitFrom(_bgShapes[idx]._imageFrame->_frame,
+ _bgShapes[idx]._position, _bgShapes[idx]._flags & 2);
+ }
+
+ // Draw all canimations which are behind the person
+ for (uint idx = 0; idx < _canimShapes.size(); ++idx) {
+ if (_canimShapes[idx]._type == ACTIVE_BG_SHAPE && _canimShapes[idx]._misc == BEHIND)
+ surface.transBlitFrom(_canimShapes[idx]._imageFrame->_frame,
+ _canimShapes[idx]._position, _canimShapes[idx]._flags & 2);
+ }
+
+ // Draw all active shapes which are normal and behind the person
+ for (uint idx = 0; idx < _bgShapes.size(); ++idx) {
+ if (_bgShapes[idx]._type == ACTIVE_BG_SHAPE && _bgShapes[idx]._misc == NORMAL_BEHIND)
+ surface.transBlitFrom(_bgShapes[idx]._imageFrame->_frame,
+ _bgShapes[idx]._position, _bgShapes[idx]._flags & 2);
+ }
+
+ // Draw all canimations which are normal and behind the person
+ for (uint idx = 0; idx < _canimShapes.size(); ++idx) {
+ if (_canimShapes[idx]._type == ACTIVE_BG_SHAPE && _canimShapes[idx]._misc == NORMAL_BEHIND)
+ surface.transBlitFrom(_canimShapes[idx]._imageFrame->_frame,
+ _canimShapes[idx]._position, _canimShapes[idx]._flags & 2);
+ }
+
+ // Draw the player if he's active
+ if (player._type == CHARACTER && people.isHolmesActive()) {
+ bool flipped = player._sequenceNumber == WALK_LEFT || player._sequenceNumber == STOP_LEFT ||
+ player._sequenceNumber == WALK_UPLEFT || player._sequenceNumber == STOP_UPLEFT ||
+ player._sequenceNumber == WALK_DOWNRIGHT || player._sequenceNumber == STOP_DOWNRIGHT;
+
+ surface.transBlitFrom(player._imageFrame->_frame,
+ Common::Point(player._position.x / 100, player._position.y / 100), flipped);
+ }
+ // Draw all static and active shapes that are NORMAL and are in front of the player
+ for (uint idx = 0; idx < _bgShapes.size(); ++idx) {
+ if ((_bgShapes[idx]._type == ACTIVE_BG_SHAPE || _bgShapes[idx]._type == STATIC_BG_SHAPE) &&
+ _bgShapes[idx]._misc == NORMAL_FORWARD)
+ surface.transBlitFrom(_bgShapes[idx]._imageFrame->_frame,
+ _bgShapes[idx]._position, _bgShapes[idx]._flags & 2);
+ }
+
+ // Draw all static and active canimations that are NORMAL and are in front of the player
+ for (uint idx = 0; idx < _canimShapes.size(); ++idx) {
+ if ((_canimShapes[idx]._type == ACTIVE_BG_SHAPE || _canimShapes[idx]._type == STATIC_BG_SHAPE) &&
+ _canimShapes[idx]._misc == NORMAL_FORWARD)
+ surface.transBlitFrom(_canimShapes[idx]._imageFrame->_frame,
+ _canimShapes[idx]._position, _canimShapes[idx]._flags & 2);
+ }
+
+ // Draw all static and active shapes that are FORWARD
+ for (uint idx = 0; idx < _bgShapes.size(); ++idx) {
+ _bgShapes[idx]._oldPosition = _bgShapes[idx]._position;
+ _bgShapes[idx]._oldSize = Common::Point(_bgShapes[idx]._imageFrame->_frame.w,
+ _bgShapes[idx]._imageFrame->_frame.h);
+
+ if ((_bgShapes[idx]._type == ACTIVE_BG_SHAPE || _bgShapes[idx]._type == STATIC_BG_SHAPE) &&
+ _bgShapes[idx]._misc == FORWARD)
+ surface.transBlitFrom(_bgShapes[idx]._imageFrame->_frame,
+ _bgShapes[idx]._position, _bgShapes[idx]._flags & 2);
+ }
+
+ // Draw all static and active canimations that are forward
+ for (uint idx = 0; idx < _canimShapes.size(); ++idx) {
+ if ((_canimShapes[idx]._type == ACTIVE_BG_SHAPE || _canimShapes[idx]._type == STATIC_BG_SHAPE) &&
+ _canimShapes[idx]._misc == FORWARD)
+ surface.transBlitFrom(_canimShapes[idx]._imageFrame->_frame,
+ _canimShapes[idx]._position, _canimShapes[idx]._flags & 2);
+ }
+}
+
+Exit *Scene::checkForExit(const Common::Rect &r) {
+ for (uint idx = 0; idx < _exits.size(); ++idx) {
+ if (_exits[idx]._bounds.intersects(r))
+ return &_exits[idx];
+ }
+ return nullptr;
}
+void Scene::checkBgShapes(ImageFrame *frame, const Common::Point &pt) {
+ // TODO
+}
+
+
} // End of namespace Sherlock
diff --git a/engines/sherlock/scene.h b/engines/sherlock/scene.h
index a4b94652c8..8986b62bf5 100644
--- a/engines/sherlock/scene.h
+++ b/engines/sherlock/scene.h
@@ -59,8 +59,7 @@ struct BgfileheaderInfo {
};
struct Exit {
- Common::Point _position;
- Common::Point _size;
+ Common::Rect _bounds;
int _scene;
int _allow;
@@ -100,6 +99,8 @@ private:
int toggleObject(const Common::String &name);
void updateBackground();
+
+ void checkBgShapes(ImageFrame *frame, const Common::Point &pt);
public:
int _currentScene;
int _goToRoom;
@@ -134,6 +135,7 @@ public:
Common::Array<SceneSound> _sounds;
Common::Point _hsavedPos;
int _hsavedFs;
+ Common::Array<Object> _canimShapes;
public:
Scene(SherlockEngine *vm);
~Scene();
@@ -143,6 +145,8 @@ public:
void selectScene();
void checkSceneFlags(bool mode);
+
+ Exit *checkForExit(const Common::Rect &r);
};
} // End of namespace Sherlock
diff --git a/engines/sherlock/sherlock.cpp b/engines/sherlock/sherlock.cpp
index 2787e2b924..257cbb2cab 100644
--- a/engines/sherlock/sherlock.cpp
+++ b/engines/sherlock/sherlock.cpp
@@ -45,6 +45,9 @@ SherlockEngine::SherlockEngine(OSystem *syst, const SherlockGameDescription *gam
_justLoaded = false;
_talkToAbort = false;
_onChessboard = false;
+ _slowChess = false;
+ _animating = false;
+ _talkCounter = 0;
}
SherlockEngine::~SherlockEngine() {
diff --git a/engines/sherlock/sherlock.h b/engines/sherlock/sherlock.h
index 1607cec974..7ce28cfdd7 100644
--- a/engines/sherlock/sherlock.h
+++ b/engines/sherlock/sherlock.h
@@ -98,6 +98,9 @@ public:
Common::Array<Common::Point> _map; // Map locations for each scene
bool _talkToAbort;
bool _onChessboard;
+ bool _slowChess;
+ bool _animating;
+ int _talkCounter;
public:
SherlockEngine(OSystem *syst, const SherlockGameDescription *gameDesc);
virtual ~SherlockEngine();