aboutsummaryrefslogtreecommitdiff
path: root/engines/sherlock
diff options
context:
space:
mode:
authorPaul Gilbert2015-03-21 18:18:12 -0400
committerPaul Gilbert2015-03-21 18:18:12 -0400
commit26c51680741882b7ee60a0e24227e6c6918aab0e (patch)
treeb8dedbccec43475ba96927b7c0f0055529462c97 /engines/sherlock
parent8f4b4a7bc269bf454ab90d003f1cc55104c175b6 (diff)
downloadscummvm-rg350-26c51680741882b7ee60a0e24227e6c6918aab0e.tar.gz
scummvm-rg350-26c51680741882b7ee60a0e24227e6c6918aab0e.tar.bz2
scummvm-rg350-26c51680741882b7ee60a0e24227e6c6918aab0e.zip
SHERLOCK: Implemented checkObject and some support methods
Diffstat (limited to 'engines/sherlock')
-rw-r--r--engines/sherlock/animation.cpp2
-rw-r--r--engines/sherlock/events.cpp11
-rw-r--r--engines/sherlock/events.h6
-rw-r--r--engines/sherlock/objects.cpp170
-rw-r--r--engines/sherlock/objects.h25
-rw-r--r--engines/sherlock/people.cpp5
-rw-r--r--engines/sherlock/people.h2
-rw-r--r--engines/sherlock/resources.cpp12
-rw-r--r--engines/sherlock/resources.h1
-rw-r--r--engines/sherlock/scalpel/scalpel.cpp6
-rw-r--r--engines/sherlock/scene.cpp285
-rw-r--r--engines/sherlock/scene.h9
-rw-r--r--engines/sherlock/sherlock.cpp1
-rw-r--r--engines/sherlock/sound.cpp11
-rw-r--r--engines/sherlock/sound.h8
15 files changed, 521 insertions, 33 deletions
diff --git a/engines/sherlock/animation.cpp b/engines/sherlock/animation.cpp
index 2b12005079..a7f91e91cd 100644
--- a/engines/sherlock/animation.cpp
+++ b/engines/sherlock/animation.cpp
@@ -144,7 +144,7 @@ bool Animation::playPrologue(const Common::String &filename, int minDelay, int f
Common::String::format("%s%01d", baseName.c_str(), soundNumber) :
Common::String::format("%s%02d", baseName.c_str(), soundNumber);
- if (sound._voicesEnabled)
+ if (sound._voicesOn)
sound.playSound(fname);
}
diff --git a/engines/sherlock/events.cpp b/engines/sherlock/events.cpp
index ecdbdbe8d7..69e89e7157 100644
--- a/engines/sherlock/events.cpp
+++ b/engines/sherlock/events.cpp
@@ -33,7 +33,7 @@ namespace Sherlock {
EventsManager::EventsManager(SherlockEngine *vm) {
_vm = vm;
_cursorImages = nullptr;
- _cursorIndex = -1;
+ _cursorId = INVALID_CURSOR;
_frameCounter = 1;
_priorFrameTime = 0;
_mouseClicked = false;
@@ -57,11 +57,14 @@ void EventsManager::loadCursors(const Common::String &filename) {
/**
* Set the cursor to show
*/
-void EventsManager::changeCursor(int cursorIndex) {
- _cursorIndex = cursorIndex;
+void EventsManager::changeCursor(CursorId cursorId) {
+ if (cursorId == _cursorId)
+ return;
+
+ _cursorId = cursorId;
// Set the cursor data
- Graphics::Surface &s = (*_cursorImages)[cursorIndex];
+ Graphics::Surface &s = (*_cursorImages)[cursorId];
CursorMan.replaceCursor(s.getPixels(), s.w, s.h, s.w / 2, s.h / 2, 0xff);
showCursor();
diff --git a/engines/sherlock/events.h b/engines/sherlock/events.h
index 0fa6bf3a5e..8965489e27 100644
--- a/engines/sherlock/events.h
+++ b/engines/sherlock/events.h
@@ -33,6 +33,8 @@ namespace Sherlock {
#define GAME_FRAME_RATE 60
#define GAME_FRAME_TIME (1000 / GAME_FRAME_RATE)
+enum CursorId { ARROW = 0, MAGNIFY = 1, WAIT = 2, INVALID_CURSOR = -1 };
+
class SherlockEngine;
class EventsManager {
@@ -45,7 +47,7 @@ private:
bool checkForNextFrameCounter();
public:
- int _cursorIndex;
+ CursorId _cursorId;
byte _mouseButtons;
bool _mouseClicked;
Common::Stack<Common::KeyState> _pendingKeys;
@@ -55,7 +57,7 @@ public:
void loadCursors(const Common::String &filename);
- void changeCursor(int cursorIndex);
+ void changeCursor(CursorId cursorId);
void showCursor();
diff --git a/engines/sherlock/objects.cpp b/engines/sherlock/objects.cpp
index a12939e787..ece96457db 100644
--- a/engines/sherlock/objects.cpp
+++ b/engines/sherlock/objects.cpp
@@ -77,7 +77,6 @@ void Sprite::setImageFrame() {
void Sprite::adjustSprite() {
People &people = *_vm->_people;
Scene &scene = *_vm->_scene;
- int checkFrame = _allow ? MAX_FRAME : 32000;
if (_type == INVALID || (_type == CHARACTER && _vm->_animating))
return;
@@ -202,6 +201,17 @@ void UseType::synchronize(Common::SeekableReadStream &s) {
/*----------------------------------------------------------------*/
+SherlockEngine *Object::_vm;
+bool Object::_countCAnimFrames;
+
+void Object::setVm(SherlockEngine *vm) {
+ _vm = vm;
+ _countCAnimFrames = false;
+}
+
+/**
+ * Load the object data from the passed stream
+ */
void Object::synchronize(Common::SeekableReadStream &s) {
char buffer[50];
@@ -225,8 +235,8 @@ void Object::synchronize(Common::SeekableReadStream &s) {
_sequenceNumber = s.readSint16LE();
_position.x = s.readSint16LE();
_position.y = s.readSint16LE();
- _movement.x = s.readSint16LE();
- _movement.y = s.readSint16LE();
+ _delta.x = s.readSint16LE();
+ _delta.y = s.readSint16LE();
_type = (SpriteType)s.readUint16LE();
_oldPosition.x = s.readSint16LE();
_oldPosition.y = s.readSint16LE();
@@ -268,6 +278,9 @@ void Object::synchronize(Common::SeekableReadStream &s) {
_use[idx].synchronize(s);
}
+/**
+ * Toggle the type of an object between hidden and active
+ */
void Object::toggleHidden() {
if (_type != HIDDEN && _type != HIDE_SHAPE && _type != INVALID) {
if (_seqTo != 0)
@@ -303,6 +316,153 @@ void Object::toggleHidden() {
}
}
+/**
+ * Check the state of the object
+ */
+void Object::checkObject(Object &o) {
+ Scene &scene = *_vm->_scene;
+ Sound &sound = *_vm->_sound;
+ int checkFrame = _allow ? MAX_FRAME : 32000;
+ bool codeFound;
+
+ if (_seqTo) {
+ byte *ptr = &_sequences[_frameNumber];
+ if (*ptr == _seqTo) {
+ // The sequence is completed
+ *ptr = _seqTo + SEQ_TO_CODE + 128; // Reset to normal
+ _seqTo = 0;
+ } else {
+ // Continue doing sequence
+ if (*ptr > _seqTo)
+ *ptr--;
+ else
+ *ptr++;
+
+ return;
+ }
+ }
+
+ ++_frameNumber;
+
+ do {
+ // Check for end of sequence
+ codeFound = checkEndOfSequence();
+
+ if (_sequences[_frameNumber] >= 128 && _frameNumber < checkFrame) {
+ codeFound = true;
+ int v = _sequences[_frameNumber];
+
+ if (v >= 228) {
+ // Goto code found
+ v -= 228;
+ _seqcounter2 = _seqCounter;
+ _seqStack = _frameNumber + 1;
+ setObjSequence(v, false);
+ } else if (v >= SOUND_CODE && (v <= (SOUND_CODE + 29))) {
+ codeFound = true;
+ ++_frameNumber;
+ v -= SOUND_CODE;
+
+ if (sound._soundOn && !_countCAnimFrames) {
+ if (!scene._sounds[v - 1]._name.empty() && sound._digitized)
+ sound.playLoadedSound(v - 1, 0);
+ }
+ } else if (v >= FLIP_CODE && v <= (FLIP_CODE + 2)) {
+ // Flip code
+ codeFound = true;
+ ++_frameNumber;
+ v -= FLIP_CODE;
+
+ // Alter the flipped status
+ switch (v) {
+ case 0:
+ // Clear the flag
+ _flags &= ~2;
+ break;
+ case 1:
+ // Set the flag
+ _flags |= 2;
+ break;
+ case 2:
+ // Toggle the flag
+ _flags ^= 2;
+ break;
+ default:
+ break;
+ }
+ } else {
+ v -= 128;
+
+ // 68-99 is a squence code
+ if (v > SEQ_TO_CODE) {
+ byte *p = &_sequences[_frameNumber];
+ v -= SEQ_TO_CODE; // # from 1-32
+ _seqTo = v;
+ *p = *(p - 1);
+
+ if (*p > 128)
+ // If the high bit is set, convert to a real frame
+ *p -= (byte)(SEQ_TO_CODE - 128);
+
+ if (*p > _seqTo)
+ *p -= 1;
+ else
+ *p += 1;
+
+ // Will be incremented below to return back to original value
+ --_frameNumber;
+ v = 0;
+ } else if (v == 10) {
+ // Set delta for objects
+ Common::Point pt(_sequences[_frameNumber + 1], _sequences[_frameNumber + 2]);
+ if (pt.x > 128)
+ pt.x = (pt.x - 128) * -1;
+ else
+ pt.x--;
+
+ if (pt.y > 128)
+ pt.y = (pt.y - 128) * -1;
+ else
+ pt.y;
+
+ _delta = pt;
+ _frameNumber += 2;
+ } else if (v < 4) {
+ for (int idx = 0; idx < 4; ++idx) {
+ o.checkNameForCodes(_use[v]._names[idx], nullptr);
+ }
+
+ if (_use[v]._useFlag)
+ _vm->setFlags(_use[v]._useFlag);
+ }
+
+ ++_frameNumber;
+ }
+ }
+ } while (codeFound);
+}
+
+bool Object::checkEndOfSequence() const {
+ // TODO
+ return false;
+}
+
+void Object::setObjSequence(int seq, bool wait) {
+ // TODO
+}
+
+/**
+* Checks for codes
+* @param name The name to check for codes
+* @param messages If provided, any messages to be returned
+* @returns 0 if no codes are found, 1 if codes were found
+*/
+int Object::checkNameForCodes(const Common::String &name, Common::StringArray *messages) {
+
+ // TODO
+ return 0;
+}
+
/*----------------------------------------------------------------*/
void CAnim::synchronize(Common::SeekableReadStream &s) {
@@ -318,10 +478,10 @@ void CAnim::synchronize(Common::SeekableReadStream &s) {
_flags = s.readByte();
_goto.x = s.readSint16LE();
_goto.y = s.readSint16LE();
- _sequenceNumber = s.readSint16LE();
+ _gotoDir = s.readSint16LE();
_teleportPos.x = s.readSint16LE();
_teleportPos.y = s.readSint16LE();
- _teleportS = s.readSint16LE();
+ _teleportDir = s.readSint16LE();
}
/*----------------------------------------------------------------*/
diff --git a/engines/sherlock/objects.h b/engines/sherlock/objects.h
index d9f1c7409e..d7442f928f 100644
--- a/engines/sherlock/objects.h
+++ b/engines/sherlock/objects.h
@@ -137,7 +137,18 @@ struct UseType {
void synchronize(Common::SeekableReadStream &s);
};
-struct Object {
+class Object {
+private:
+ static SherlockEngine *_vm;
+
+ bool checkEndOfSequence() const;
+
+ void setObjSequence(int seq, bool wait);
+public:
+ static bool _countCAnimFrames;
+
+ static void setVm(SherlockEngine *vm);
+public:
Common::String _name; // Name
Common::String _description; // Description
Common::String _examine; // Examine in-depth description
@@ -151,7 +162,7 @@ struct Object {
int _sequenceNumber; // Sequence being used
SpriteType _type; // Object type
Common::Point _position; // Current position
- Common::Point _movement; // Momvement amount
+ Common::Point _delta; // Momvement amount
Common::Point _oldPosition; // Old position
Common::Point _oldSize; // Image's old size
Common::Point _goto; // Walk destination
@@ -185,19 +196,23 @@ struct Object {
void synchronize(Common::SeekableReadStream &s);
void toggleHidden();
+
+ void checkObject(Object &o);
+
+ int checkNameForCodes(const Common::String &name, Common::StringArray *messages);
};
struct CAnim {
Common::String _name; // Name
- int _sequences[MAX_FRAME]; // Animation sequences
+ byte _sequences[MAX_FRAME]; // Animation sequences
Common::Point _position; // Position
int _size; // Size of uncompressed animation
SpriteType _type;
int _flags; // Tells if can be walked behind
Common::Point _goto; // coords holmes should walk to before starting canim
- int _sequenceNumber;
+ int _gotoDir;
Common::Point _teleportPos; // Location Holmes shoul teleport to after
- int _teleportS; // playing canim
+ int _teleportDir; // playing canim
void synchronize(Common::SeekableReadStream &s);
};
diff --git a/engines/sherlock/people.cpp b/engines/sherlock/people.cpp
index 998fe4f0cf..43d3422f1a 100644
--- a/engines/sherlock/people.cpp
+++ b/engines/sherlock/people.cpp
@@ -289,4 +289,9 @@ void People::gotoStand(Sprite &sprite) {
_allowWalkAbort = true;
}
+void People::walkToCoords(const Common::Point &destPos, int destDir) {
+ // TODO
+ warning("TODO: walkToCoords");
+}
+
} // End of namespace Sherlock
diff --git a/engines/sherlock/people.h b/engines/sherlock/people.h
index e58fd33ef2..d2d7e92512 100644
--- a/engines/sherlock/people.h
+++ b/engines/sherlock/people.h
@@ -79,6 +79,8 @@ public:
void setWalking();
void gotoStand(Sprite &sprite);
+
+ void walkToCoords(const Common::Point &destPos, int destDir);
};
} // End of namespace Sherlock
diff --git a/engines/sherlock/resources.cpp b/engines/sherlock/resources.cpp
index 66feca6bd5..9e25a8dd6e 100644
--- a/engines/sherlock/resources.cpp
+++ b/engines/sherlock/resources.cpp
@@ -129,7 +129,7 @@ void Resources::addToCache(const Common::String &filename) {
}
/**
- * Adds a resource from a library file tot he cache
+ * Adds a resource from a library file to the cache
*/
void Resources::addToCache(const Common::String &filename, const Common::String &libFilename) {
// Get the resource
@@ -140,6 +140,16 @@ void Resources::addToCache(const Common::String &filename, const Common::String
delete stream;
}
+/**
+ * Adds a given stream to the cache under the given name
+ */
+void Resources::addToCache(const Common::String &filename, Common::SeekableReadStream &stream) {
+ _cache.load(filename, stream);
+}
+
+/**
+ * Returns a stream for a given file
+ */
Common::SeekableReadStream *Resources::load(const Common::String &filename) {
// First check if the file is directly in the cache
if (_cache.isCached(filename))
diff --git a/engines/sherlock/resources.h b/engines/sherlock/resources.h
index 2f9222c1fd..1d8c601e77 100644
--- a/engines/sherlock/resources.h
+++ b/engines/sherlock/resources.h
@@ -76,6 +76,7 @@ public:
void addToCache(const Common::String &filename);
void addToCache(const Common::String &filename, const Common::String &libFilename);
+ void addToCache(const Common::String &filename, Common::SeekableReadStream &stream);
bool isInCache(const Common::String &filename) const { return _cache.isCached(filename); }
Common::SeekableReadStream *load(const Common::String &filename);
diff --git a/engines/sherlock/scalpel/scalpel.cpp b/engines/sherlock/scalpel/scalpel.cpp
index 2477f2894f..b8c7661966 100644
--- a/engines/sherlock/scalpel/scalpel.cpp
+++ b/engines/sherlock/scalpel/scalpel.cpp
@@ -183,7 +183,7 @@ bool ScalpelEngine::showOfficeCutscene() {
void ScalpelEngine::startScene() {
if (_scene->_goToRoom == 100 || _scene->_goToRoom == 98) {
// Chessboard selection
- if (_sound->_musicEnabled) {
+ if (_sound->_musicOn) {
if (_sound->loadSong(100)) {
if (_sound->_music)
_sound->startSong();
@@ -208,7 +208,7 @@ void ScalpelEngine::startScene() {
case 52:
case 53:
case 70:
- if (_sound->_musicEnabled && _sound->loadSong(_scene->_goToRoom)) {
+ if (_sound->_musicOn && _sound->loadSong(_scene->_goToRoom)) {
if (_sound->_music)
_sound->startSong();
}
@@ -325,7 +325,7 @@ void ScalpelEngine::startScene() {
}
_events->loadCursors("rmouse.vgs");
- _events->changeCursor(0);
+ _events->changeCursor(ARROW);
if (_scene->_goToRoom == 99) {
// Chess Board
diff --git a/engines/sherlock/scene.cpp b/engines/sherlock/scene.cpp
index 9fbec6b776..8158dfc705 100644
--- a/engines/sherlock/scene.cpp
+++ b/engines/sherlock/scene.cpp
@@ -98,6 +98,7 @@ Scene::Scene(SherlockEngine *vm): _vm(vm) {
_invGraphicItems = 0;
_hsavedPos = Common::Point(-1, -1);
_hsavedFs = -1;
+ _cAnimFramePause = 0;
_controlPanel = new ImageFile("controls.vgs");
_controls = nullptr; // new ImageFile("menu.all");
@@ -124,7 +125,7 @@ void Scene::selectScene() {
// Load the scene
Common::String sceneFile = Common::String::format("res%02d", _goToRoom);
- Common::String roomName = Common::String::format("res%02d.rrm", _goToRoom);
+ _rrmName = Common::String::format("res%02d.rrm", _goToRoom);
_currentScene = _goToRoom;
_goToRoom = -1;
@@ -312,7 +313,7 @@ bool Scene::loadScene(const Common::String &filename) {
_sounds[idx].synchronize(*rrmStream);
// If sound is turned on, load the sounds into memory
- if (sound._sfxEnabled) {
+ if (sound._soundOn) {
for (int idx = 0; idx < numSounds; ++idx) {
sound.loadSound(_sounds[idx]._name, _sounds[idx]._priority);
_sounds[idx]._name = "";
@@ -374,7 +375,7 @@ bool Scene::loadScene(const Common::String &filename) {
checkInventory();
// Handle starting any music for the scene
- if (sound._musicEnabled && sound.loadSong(_currentScene)) {
+ if (sound._musicOn && sound.loadSong(_currentScene)) {
if (sound._music)
sound.startSong();
}
@@ -516,6 +517,7 @@ void Scene::transitionToScene() {
STOP_DOWNLEFT, STOP_LEFT, STOP_UPLEFT
};
People &people = *_vm->_people;
+ Screen &screen = *_vm->_screen;
if (_hsavedPos.x < 1) {
// No exit information from last scene-check entrance info
@@ -539,7 +541,7 @@ void Scene::transitionToScene() {
}
}
- int startcAnimNum = -1;
+ int cAnimNum = -1;
if (_hsavedFs < 101) {
// Standard info, so set it
@@ -547,7 +549,7 @@ void Scene::transitionToScene() {
people[PLAYER]._sequenceNumber = _hsavedFs;
} else {
// It's canimation information
- startcAnimNum = _hsavedFs - 101;
+ cAnimNum = _hsavedFs - 101;
// Prevent Holmes from being drawn
people[PLAYER]._position = Common::Point(0, 0);
@@ -599,7 +601,22 @@ void Scene::transitionToScene() {
}
updateBackground();
- // TODO
+
+ if (screen._fadeStyle)
+ screen.randomTransition();
+ else
+ screen.blitFrom(screen._backBuffer);
+
+ if (cAnimNum != -1) {
+ CAnim &c = _cAnim[cAnimNum];
+ Common::Point pt = c._position;
+
+ c._position = Common::Point(-1, -1);
+ people[AL]._position = Common::Point(0, 0);
+
+ startCAnim(cAnimNum, 1);
+ c._position = pt;
+ }
}
/**
@@ -722,9 +739,265 @@ Exit *Scene::checkForExit(const Common::Rect &r) {
return nullptr;
}
+/**
+ * Checks all the background shapes. If a background shape is animating,
+ * it will flag it as needing to be drawn. If a non-animating shape is
+ * colliding with another shape, it will also flag it as needing drawing
+ */
void Scene::checkBgShapes(ImageFrame *frame, const Common::Point &pt) {
+ // Iterate through the shapes
+ for (uint idx = 0; idx < _bgShapes.size(); ++idx) {
+ Object &obj = _bgShapes[idx];
+ if (obj._type == STATIC_BG_SHAPE || obj._type == ACTIVE_BG_SHAPE) {
+ if ((obj._flags & 5) == 1) {
+ obj._misc = (pt.y < (obj._position.y + obj._imageFrame->_frame.h - 1)) ?
+ NORMAL_FORWARD : NORMAL_BEHIND;
+ } else if (!(obj._flags & 1)) {
+ obj._misc = BEHIND;
+ } else if (obj._flags & 4) {
+ obj._misc = FORWARD;
+ }
+ }
+ }
+
+ // Iterate through the canimshapes
+ for (uint idx = 0; idx < _canimShapes.size(); ++idx) {
+ Object &obj = _canimShapes[idx];
+ if (obj._type == STATIC_BG_SHAPE || obj._type == ACTIVE_BG_SHAPE) {
+ if ((obj._flags & 5) == 1) {
+ obj._misc = (pt.y < (obj._position.y + obj._imageFrame->_frame.h - 1)) ?
+ NORMAL_FORWARD : NORMAL_BEHIND;
+ }
+ else if (!(obj._flags & 1)) {
+ obj._misc = BEHIND;
+ }
+ else if (obj._flags & 4) {
+ obj._misc = FORWARD;
+ }
+ }
+ }
+}
+
+/**
+ * Attempt to start a canimation sequence. It will load the requisite graphics, and
+ * then copy the canim object into the _canimShapes array to start the animation.
+ *
+ * @param cAnimNum The canim object within the current scene
+ * @param playRate Play rate. 0 is invalid; 1=normal speed, 2=1/2 speed, etc.
+ * A negative playRate can also be specified to play the animation in reverse
+ */
+int Scene::startCAnim(int cAnimNum, int playRate) {
+ EventsManager &events = *_vm->_events;
+ People &people = *_vm->_people;
+ Resources &res = *_vm->_res;
+ Common::Point tpPos, walkPos;
+ int tpDir, walkDir;
+ int tFrames;
+ int gotoCode = -1;
+
+ // Validation
+ if (cAnimNum >= (int)_cAnim.size())
+ // number out of bounds
+ return -1;
+ if (_canimShapes.size() >= 3 || playRate == 0)
+ // Too many active animations, or invalid play rate
+ return 0;
+
+ CAnim &cAnim = _cAnim[cAnimNum];
+ if (playRate < 0) {
+ // Reverse direction
+ walkPos = cAnim._teleportPos;
+ walkDir = cAnim._teleportDir;
+ tpPos = cAnim._goto;
+ tpDir = cAnim._gotoDir;
+ } else {
+ // Forward direction
+ walkPos = cAnim._goto;
+ walkDir = cAnim._gotoDir;
+ tpPos = cAnim._teleportPos;
+ tpDir = cAnim._teleportDir;
+ }
+
+ events.changeCursor(WAIT);
+ _canimShapes.push_back(Object());
+ Object &cObj = _canimShapes[_canimShapes.size() - 1];
+
+ if (walkPos.x != -1) {
+ // Holmes must walk to the walk point before the cAnimation is started
+ if (people[AL]._position != walkPos)
+ people.walkToCoords(walkPos, walkDir);
+ }
+
+ if (_vm->_talkToAbort)
+ return 1;
+
+ // Copy the canimation into the bgShapes type canimation structure so it can be played
+ cObj._allow = cAnimNum + 1; // Keep track of the parent structure
+ cObj._name = _cAnim[cAnimNum]._name; // Copy name
+
+ // Remove any attempt to draw object frame
+ if (cAnim._type == NO_SHAPE && cAnim._sequences[0] < 100)
+ cAnim._sequences[0] = 0;
+
+ cObj._sequences = cAnim._sequences;
+ cObj._images = nullptr;
+ cObj._position = cAnim._position;
+ cObj._delta = Common::Point(0, 0);
+ cObj._type = cAnim._type;
+ cObj._flags = cAnim._flags;
+
+ cObj._maxFrames = 0;
+ cObj._frameNumber = -1;
+ cObj._sequenceNumber = cAnimNum;
+ cObj._oldPosition = Common::Point(0, 0);
+ cObj._oldPosition = Common::Point(0, 0);
+ cObj._goto = Common::Point(0, 0);
+ cObj._status = 0;
+ cObj._misc = 0;
+ cObj._imageFrame = nullptr;
+
+ if (cAnim._name.size() > 0 && cAnim._type != NO_SHAPE) {
+ if (tpPos.x != -1)
+ people[AL]._type = REMOVE;
+
+ Common::String fname = cAnim._name + ".vgs";
+ if (!res.isInCache(fname)) {
+ // Set up RRM scene data
+ Common::SeekableReadStream *rrmStream = res.load(_rrmName);
+ rrmStream->seek(44 + cAnimNum * 4);
+ rrmStream->seek(rrmStream->readUint32LE());
+
+ // Load the canimation into the cache
+ Common::SeekableReadStream *imgStream = !_lzwMode ? rrmStream :
+ decompressLZ(*rrmStream, cAnim._size);
+ res.addToCache(fname, *imgStream);
+
+ if (_lzwMode)
+ delete imgStream;
+
+ delete rrmStream;
+ }
+
+ // Now load the resource as an image
+ cObj._maxFrames = cObj._images->size();
+ cObj._images = new ImageFile(fname);
+ cObj._imageFrame = &(*cObj._images)[0];
+
+ int frames = 0;
+ if (playRate < 0) {
+ // Reverse direction
+ // Count number of frames
+ while (cObj._sequences[frames] && frames < MAX_FRAME)
+ ++frames;
+ }
+ else {
+ // Forward direction
+ Object::_countCAnimFrames = true;
+
+ while (cObj._type == ACTIVE_BG_SHAPE) {
+ cObj.checkObject(_bgShapes[0]);
+ ++frames;
+
+ if (frames >= 1000)
+ error("CAnim has infinite loop sequence");
+ }
+
+ if (frames > 1)
+ --frames;
+
+ Object::_countCAnimFrames = false;
+
+ cObj._type = cAnim._type;
+ cObj._frameNumber = -1;
+ cObj._position = cAnim._position;
+ cObj._delta = Common::Point(0, 0);
+ }
+
+ // Return if animation has no frames in it
+ if (frames == 0)
+ return -2;
+
+ ++frames;
+ int repeat = ABS(playRate);
+ int dir;
+
+ if (playRate < 0) {
+ // Play in reverse
+ dir = -2;
+ cObj._frameNumber = frames - 3;
+ } else {
+ dir = 0;
+ }
+
+ tFrames = frames - 1;
+ int pauseFrame = (_cAnimFramePause) ? frames - _cAnimFramePause : -1;
+
+ while (--frames) {
+ if (frames == pauseFrame)
+ printObjDesc(_cAnimStr, true);
+
+ doBgAnim();
+
+ // Repeat same frame
+ int temp = repeat;
+ while (--temp > 0) {
+ cObj._frameNumber--;
+ doBgAnim();
+ }
+
+ cObj._frameNumber += dir;
+ }
+
+ people[AL]._type = CHARACTER;
+ }
+
+ // Teleport to ending coordinates if necessary
+ if (tpPos.x != -1) {
+ people[AL]._position = tpPos; // Place the player
+ people[AL]._sequenceNumber = tpDir;
+ people.gotoStand(people[AL]);
+ }
+
+ if (playRate < 0)
+ // Reverse direction - set to end sequence
+ cObj._frameNumber = tFrames - 1;
+
+ if (cObj._frameNumber <= 26)
+ gotoCode = cObj._sequences[cObj._frameNumber + 3];
+
+ // Set canim to REMOVE type and free memory
+ cObj.checkObject(_bgShapes[0]);
+
+ if (gotoCode > 0 && !_vm->_talkToAbort) {
+ _goToRoom = gotoCode;
+
+ if (_goToRoom < 97 && _vm->_map[_goToRoom].x) {
+ _overPos = _vm->_map[_goToRoom];
+ }
+ }
+
+ people.loadWalk();
+
+ if (tpPos.x != -1 && !_vm->_talkToAbort) {
+ // Teleport to ending coordinates
+ people[AL]._position = tpPos;
+ people[AL]._sequenceNumber = tpDir;
+
+ people.gotoStand(people[AL]);
+ }
+
+ return 1;
+}
+
+void Scene::printObjDesc(const Common::String &str, bool firstTime) {
// TODO
}
+/**
+ * Animate all objects and people.
+ */
+void Scene::doBgAnim() {
+ // TODO
+}
} // End of namespace Sherlock
diff --git a/engines/sherlock/scene.h b/engines/sherlock/scene.h
index 8986b62bf5..06ca2f4c0d 100644
--- a/engines/sherlock/scene.h
+++ b/engines/sherlock/scene.h
@@ -87,6 +87,9 @@ struct SceneSound {
class Scene {
private:
SherlockEngine *_vm;
+ Common::String _rrmName;
+ int _cAnimFramePause;
+ Common::String _cAnimStr;
bool loadScene(const Common::String &filename);
@@ -101,6 +104,10 @@ private:
void updateBackground();
void checkBgShapes(ImageFrame *frame, const Common::Point &pt);
+
+ int startCAnim(int cAnimNum, int playRate);
+
+ void doBgAnim();
public:
int _currentScene;
int _goToRoom;
@@ -147,6 +154,8 @@ public:
void checkSceneFlags(bool mode);
Exit *checkForExit(const Common::Rect &r);
+
+ void printObjDesc(const Common::String &str, bool firstTime);
};
} // End of namespace Sherlock
diff --git a/engines/sherlock/sherlock.cpp b/engines/sherlock/sherlock.cpp
index 257cbb2cab..756be22846 100644
--- a/engines/sherlock/sherlock.cpp
+++ b/engines/sherlock/sherlock.cpp
@@ -70,6 +70,7 @@ void SherlockEngine::initialize() {
DebugMan.addDebugChannel(kDebugScript, "scripts", "Script debug level");
ImageFile::setVm(this);
+ Object::setVm(this);
Sprite::setVm(this);
_res = new Resources();
_animation = new Animation(this);
diff --git a/engines/sherlock/sound.cpp b/engines/sherlock/sound.cpp
index 61c740ea3f..0917f83e89 100644
--- a/engines/sherlock/sound.cpp
+++ b/engines/sherlock/sound.cpp
@@ -25,11 +25,12 @@
namespace Sherlock {
Sound::Sound(SherlockEngine *vm): _vm(vm) {
- _sfxEnabled = true;
- _musicEnabled = true;
- _voicesEnabled = true;
+ _soundOn = true;
+ _musicOn = true;
+ _voicesOn = true;
_playingEpilogue = false;
_music = false;
+ _digitized = false;
}
void Sound::loadSound(const Common::String &name, int priority) {
@@ -44,6 +45,10 @@ void Sound::cacheSound(const Common::String &name, int index) {
// TODO
}
+void Sound::playLoadedSound(int bufNum, int waitMode) {
+ // TODO
+}
+
void Sound::playCachedSound(int index) {
// TODO
}
diff --git a/engines/sherlock/sound.h b/engines/sherlock/sound.h
index 9d323833f1..b6e645a28f 100644
--- a/engines/sherlock/sound.h
+++ b/engines/sherlock/sound.h
@@ -38,17 +38,19 @@ class Sound {
private:
SherlockEngine *_vm;
public:
- bool _sfxEnabled;
- bool _musicEnabled;
- bool _voicesEnabled;
+ bool _soundOn;
+ bool _musicOn;
+ bool _voicesOn;
bool _playingEpilogue;
bool _music;
+ bool _digitized;
public:
Sound(SherlockEngine *vm);
void loadSound(const Common::String &name, int priority);
void playSound(const Common::String &name, WaitType waitType = WAIT_RETURN_IMMEDIATELY);
void cacheSound(const Common::String &name, int index);
+ void playLoadedSound(int bufNum, int waitMode);
void playCachedSound(int index);
void clearCache();
void stopSound();