aboutsummaryrefslogtreecommitdiff
path: root/engines/sherlock/scalpel/scalpel_scene.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'engines/sherlock/scalpel/scalpel_scene.cpp')
-rw-r--r--engines/sherlock/scalpel/scalpel_scene.cpp230
1 files changed, 230 insertions, 0 deletions
diff --git a/engines/sherlock/scalpel/scalpel_scene.cpp b/engines/sherlock/scalpel/scalpel_scene.cpp
index e0ad3a7b6d..95a58be99d 100644
--- a/engines/sherlock/scalpel/scalpel_scene.cpp
+++ b/engines/sherlock/scalpel/scalpel_scene.cpp
@@ -21,16 +21,34 @@
*/
#include "sherlock/scalpel/scalpel_scene.h"
+#include "sherlock/scalpel/scalpel_map.h"
#include "sherlock/scalpel/scalpel_people.h"
#include "sherlock/scalpel/scalpel.h"
#include "sherlock/events.h"
#include "sherlock/people.h"
#include "sherlock/screen.h"
+#include "sherlock/sherlock.h"
namespace Sherlock {
namespace Scalpel {
+bool ScalpelScene::loadScene(const Common::String &filename) {
+ ScalpelMap &map = *(ScalpelMap *)_vm->_map;
+ bool result = Scene::loadScene(filename);
+
+ if (!_vm->isDemo()) {
+ // Reset the previous map location and position on overhead map
+ map._oldCharPoint = _currentScene;
+
+ map._overPos.x = (map[_currentScene].x - 6) * FIXED_INT_MULTIPLIER;
+ map._overPos.y = (map[_currentScene].y + 9) * FIXED_INT_MULTIPLIER;
+
+ }
+
+ return result;
+}
+
void ScalpelScene::drawAllShapes() {
People &people = *_vm->_people;
Screen &screen = *_vm->_screen;
@@ -467,6 +485,218 @@ void ScalpelScene::doBgAnim() {
}
}
+int ScalpelScene::startCAnim(int cAnimNum, int playRate) {
+ Events &events = *_vm->_events;
+ ScalpelMap &map = *(ScalpelMap *)_vm->_map;
+ People &people = *_vm->_people;
+ Resources &res = *_vm->_res;
+ Talk &talk = *_vm->_talk;
+ UserInterface &ui = *_vm->_ui;
+ Point32 tpPos, walkPos;
+ int tpDir, walkDir;
+ int tFrames = 0;
+ 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;
+ }
+
+ CursorId oldCursor = events.getCursor();
+ events.setCursor(WAIT);
+
+ 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 (talk._talkToAbort)
+ return 1;
+
+ // Add new anim shape entry for displaying the animation
+ _canimShapes.push_back(Object());
+ Object &cObj = _canimShapes[_canimShapes.size() - 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._oldSize = 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->readStream(cAnim._size) :
+ Resources::decompressLZ(*rrmStream, cAnim._size);
+ res.addToCache(fname, *imgStream);
+
+ delete imgStream;
+ delete rrmStream;
+ }
+
+ // Now load the resource as an image
+ cObj._images = new ImageFile(fname);
+ cObj._imageFrame = &(*cObj._images)[0];
+ cObj._maxFrames = cObj._images->size();
+
+ 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();
+ ++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)
+ ui.printObjectDesc();
+
+ doBgAnim();
+
+ // Repeat same frame
+ int temp = repeat;
+ while (--temp > 0) {
+ cObj._frameNumber--;
+ doBgAnim();
+
+ if (_vm->shouldQuit())
+ return 0;
+ }
+
+ 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];
+
+ // Unless anim shape has already been freed, set it to REMOVE so doBgAnim can free it
+ if (_canimShapes.indexOf(cObj) != -1)
+ cObj.checkObject();
+
+ if (gotoCode > 0 && !talk._talkToAbort) {
+ _goToScene = gotoCode;
+
+ if (_goToScene < 97 && map[_goToScene].x) {
+ map._overPos = map[_goToScene];
+ }
+ }
+
+ people.loadWalk();
+
+ if (tpPos.x != -1 && !talk._talkToAbort) {
+ // Teleport to ending coordinates
+ people[AL]._position = tpPos;
+ people[AL]._sequenceNumber = tpDir;
+
+ people.gotoStand(people[AL]);
+ }
+
+ events.setCursor(oldCursor);
+
+ return 1;
+}
+
} // End of namespace Scalpel
} // End of namespace Sherlock