aboutsummaryrefslogtreecommitdiff
path: root/engines/sherlock/tattoo
diff options
context:
space:
mode:
authorPaul Gilbert2015-06-12 23:23:16 -0400
committerPaul Gilbert2015-06-12 23:23:16 -0400
commit803c06beb919b35d29bb65ec2e7e48caca69c730 (patch)
treedcce1cc2ed3ff46c7238e3d801a4567b90f71d8c /engines/sherlock/tattoo
parent6221c1de82bae650158b54a4b04f8f319416ac63 (diff)
downloadscummvm-rg350-803c06beb919b35d29bb65ec2e7e48caca69c730.tar.gz
scummvm-rg350-803c06beb919b35d29bb65ec2e7e48caca69c730.tar.bz2
scummvm-rg350-803c06beb919b35d29bb65ec2e7e48caca69c730.zip
SHERLOCK: RT: Implement startCAnim
Diffstat (limited to 'engines/sherlock/tattoo')
-rw-r--r--engines/sherlock/tattoo/tattoo.cpp2
-rw-r--r--engines/sherlock/tattoo/tattoo.h1
-rw-r--r--engines/sherlock/tattoo/tattoo_people.cpp14
-rw-r--r--engines/sherlock/tattoo/tattoo_scene.cpp126
-rw-r--r--engines/sherlock/tattoo/tattoo_talk.cpp2
5 files changed, 136 insertions, 9 deletions
diff --git a/engines/sherlock/tattoo/tattoo.cpp b/engines/sherlock/tattoo/tattoo.cpp
index 0961601487..60803c7fbb 100644
--- a/engines/sherlock/tattoo/tattoo.cpp
+++ b/engines/sherlock/tattoo/tattoo.cpp
@@ -33,6 +33,7 @@ namespace Tattoo {
TattooEngine::TattooEngine(OSystem *syst, const SherlockGameDescription *gameDesc) :
SherlockEngine(syst, gameDesc) {
_creditsActive = false;
+ _runningProlog = false;
}
void TattooEngine::showOpening() {
@@ -48,6 +49,7 @@ void TattooEngine::initialize() {
// Initialise the global flags
_flags.resize(3200);
_flags[1] = _flags[4] = _flags[76] = true;
+ _runningProlog = true;
// Add some more files to the cache
_res->addToCache("walk.lib");
diff --git a/engines/sherlock/tattoo/tattoo.h b/engines/sherlock/tattoo/tattoo.h
index 28fa77f409..6cafc3fe52 100644
--- a/engines/sherlock/tattoo/tattoo.h
+++ b/engines/sherlock/tattoo/tattoo.h
@@ -49,6 +49,7 @@ protected:
virtual void startScene();
public:
bool _creditsActive;
+ bool _runningProlog;
public:
TattooEngine(OSystem *syst, const SherlockGameDescription *gameDesc);
virtual ~TattooEngine() {}
diff --git a/engines/sherlock/tattoo/tattoo_people.cpp b/engines/sherlock/tattoo/tattoo_people.cpp
index f70b079760..7560ca1593 100644
--- a/engines/sherlock/tattoo/tattoo_people.cpp
+++ b/engines/sherlock/tattoo/tattoo_people.cpp
@@ -108,7 +108,7 @@ void TattooPerson::adjustSprite() {
// See if the player has come to a stop after clicking on an Arrow zone to leave the scene.
// If so, this will set up the exit information for the scene transition
if (!_walkCount && scene._exitZone != -1 && scene._walkedInScene && scene._goToScene != -1 &&
- !_description.compareToIgnoreCase(people[PLAYER]._description)) {
+ !_description.compareToIgnoreCase(people[HOLMES]._description)) {
people._hSavedPos = scene._exits[scene._exitZone]._newPosition;
people._hSavedFacing = scene._exits[scene._exitZone]._newFacing;
@@ -187,20 +187,20 @@ void TattooPerson::gotoStand() {
if (npc != -1 && people[npc]._npcFacing != -1) {
if (people[npc]._npcFacing == FACING_PLAYER) {
// See where Holmes is with respect to the NPC (x coords)
- if (people[PLAYER]._position.x < people[npc]._position.x)
+ if (people[HOLMES]._position.x < people[npc]._position.x)
people[npc]._npcFacing = STOP_LEFT;
else
people[npc]._npcFacing = STOP_RIGHT;
// See where Holmes is with respect to the NPC (y coords)
- if (people[PLAYER]._position.y < people[npc]._position.y - (10 * FIXED_INT_MULTIPLIER)) {
+ if (people[HOLMES]._position.y < people[npc]._position.y - (10 * FIXED_INT_MULTIPLIER)) {
// Holmes is above the NPC so reset the facing to the diagonal ups
if (people[npc]._npcFacing == STOP_RIGHT)
people[npc]._npcFacing = STOP_UPRIGHT;
else
people[npc]._npcFacing = STOP_UPLEFT;
} else {
- if (people[PLAYER]._position.y > people[npc]._position.y + (10 * FIXED_INT_MULTIPLIER)) {
+ if (people[HOLMES]._position.y > people[npc]._position.y + (10 * FIXED_INT_MULTIPLIER)) {
// Holmes is below the NPC so reset the facing to the diagonal downs
if (people[npc]._npcFacing == STOP_RIGHT)
people[npc]._npcFacing = STOP_DOWNRIGHT;
@@ -446,7 +446,7 @@ int TattooPeople::findSpeaker(int speaker) {
if (result == -1) {
bool flag = _vm->readFlags(76);
- if (_data[PLAYER]->_type == CHARACTER && ((speaker == 0 && flag) || (speaker == 1 && !flag)))
+ if (_data[HOLMES]->_type == CHARACTER && ((speaker == 0 && flag) || (speaker == 1 && !flag)))
return -1;
for (uint idx = 1; idx < _data.size(); ++idx) {
@@ -481,8 +481,8 @@ void TattooPeople::synchronize(Serializer &s) {
s.syncAsSint16LE(_holmesQuotient);
if (s.isLoading()) {
- _hSavedPos = _data[PLAYER]->_position;
- _hSavedFacing = _data[PLAYER]->_sequenceNumber;
+ _hSavedPos = _data[HOLMES]->_position;
+ _hSavedFacing = _data[HOLMES]->_sequenceNumber;
}
}
diff --git a/engines/sherlock/tattoo/tattoo_scene.cpp b/engines/sherlock/tattoo/tattoo_scene.cpp
index ce20f17730..a64c86b24b 100644
--- a/engines/sherlock/tattoo/tattoo_scene.cpp
+++ b/engines/sherlock/tattoo/tattoo_scene.cpp
@@ -803,10 +803,134 @@ void TattooScene::setupBGArea(const byte cMap[PALETTE_SIZE]) {
}
}
+#define ADJUST_COORD(COORD) if (COORD != -1) COORD *= FIXED_INT_MULTIPLIER
+
int TattooScene::startCAnim(int cAnimNum, int playRate) {
- error("TODO: startCAnim");
+ TattooEngine &vm = *(TattooEngine *)_vm;
+ Events &events = *_vm->_events;
+ TattooPeople &people = *(TattooPeople *)_vm->_people;
+ Resources &res = *_vm->_res;
+ Talk &talk = *_vm->_talk;
+ UserInterface &ui = *_vm->_ui;
+
+ // Exit immediately if the anim number is out of range, or the anim doesn't have a position specified
+ if (cAnimNum < 0 || cAnimNum >= (int)_cAnim.size() || _cAnim[cAnimNum]._position.x == -1)
+ // Return out of range error
+ return -1;
+
+ // Get the co-ordinates that the Player & NPC #1 must walk to and end on
+ CAnim &cAnim = _cAnim[cAnimNum];
+ PositionFacing goto1 = cAnim._goto[0];
+ PositionFacing goto2 = cAnim._goto[1];
+ PositionFacing teleport1 = cAnim._teleport[0];
+ PositionFacing teleport2 = cAnim._teleport[1];
+
+ // If the co-ordinates are valid (not -1), adjust them by the fixed int multiplier
+ ADJUST_COORD(goto1.x);
+ ADJUST_COORD(goto1.y);
+ ADJUST_COORD(goto2.x);
+ ADJUST_COORD(goto2.y);
+ ADJUST_COORD(teleport1.x);
+ ADJUST_COORD(teleport1.y);
+ ADJUST_COORD(teleport2.x);
+ ADJUST_COORD(teleport2.y);
+
+ // See if the Player must walk to a position before the animation starts
+ SpriteType savedPlayerType = people[HOLMES]._type;
+ if (goto1.x != -1 && people[HOLMES]._type == CHARACTER) {
+ if (people[HOLMES]._position != goto1)
+ people[HOLMES].walkToCoords(goto1, goto1._facing);
+ }
+
+ if (talk._talkToAbort)
+ return 1;
+
+ // See if NPC #1 must walk to a position before the animation starts
+ SpriteType savedNPCType = people[WATSON]._type;
+ if (goto2.x != -1 && people[WATSON]._type == CHARACTER) {
+ if (people[WATSON]._position != goto2)
+ people[WATSON].walkToCoords(goto2, goto2._facing);
+ }
+
+ if (talk._talkToAbort)
+ return 1;
+
+ // Turn the player (and NPC #1 if neccessary) off before running the canimation
+ if (teleport1.x != -1 && savedPlayerType == CHARACTER)
+ people[HOLMES]._type = REMOVE;
+
+ if (teleport2.x != -1 && savedNPCType == CHARACTER)
+ people[WATSON]._type = REMOVE;
+
+ if (ui._windowOpen)
+ ui.banishWindow();
+
+ //_activeCAnim._filesize = cAnim._size;
+
+ // Open up the room resource file and get the data for the animation
+ Common::SeekableReadStream *stream = res.load(_rrmName);
+ stream->seek(44 + cAnimNum * 4);
+ stream->seek(stream->readUint32LE());
+ Common::SeekableReadStream *animStream = stream->readStream(cAnim._size);
+ delete stream;
+
+ // Set up the active animation
+ _activeCAnim._position = cAnim._position;
+ _activeCAnim._oldBounds = Common::Rect(0, 0, 0, 0);
+ _activeCAnim._flags = cAnim._flags;
+ _activeCAnim._scaleVal = cAnim._scaleVal;
+ _activeCAnim._zPlacement = 0;
+
+ _activeCAnim.load(animStream);
+
+ while (_activeCAnim.active() && !_vm->shouldQuit()) {
+ doBgAnim();
+
+ events.pollEvents();
+ if (events.kbHit()) {
+ Common::KeyState keyState = events.getKey();
+
+ if (keyState.keycode == Common::KEYCODE_ESCAPE && vm._runningProlog) {
+ _vm->setFlags(-76);
+ _vm->setFlags(396);
+ _goToScene = 1;
+ talk._talkToAbort = true;
+ _activeCAnim.close();
+ }
+ }
+ }
+
+ // Turn the people back on
+ people[HOLMES]._type = savedPlayerType;
+ if (teleport2.x != -1)
+ people[WATSON]._type = savedNPCType;
+
+ // Teleport the Player to the ending coordinates if necessary
+ if (teleport1.x != -1 && savedPlayerType == CHARACTER) {
+ people[HOLMES]._position = teleport1;
+ people[HOLMES]._sequenceNumber = teleport1._facing;
+ people[HOLMES].gotoStand();
+ }
+
+ // Teleport Watson to the ending coordinates if necessary
+ if (teleport2.x != -1 && savedNPCType == CHARACTER) {
+ people[WATSON]._position = teleport2;
+ people[WATSON]._sequenceNumber = teleport2._facing;
+ people[WATSON].gotoStand();
+ }
+
+ // Flag the Canimation to be cleared
+ _activeCAnim._zPlacement = REMOVE;
+ _activeCAnim._removeBounds = _activeCAnim._oldBounds;
+
+ // Free up the animation
+ _activeCAnim.close();
+
+ return 1;
}
+#undef ADJUST_COORD
+
void TattooScene::setNPCPath(int npc) {
TattooPeople &people = *(TattooPeople *)_vm->_people;
Talk &talk = *_vm->_talk;
diff --git a/engines/sherlock/tattoo/tattoo_talk.cpp b/engines/sherlock/tattoo/tattoo_talk.cpp
index 28c0132dd9..3768d12497 100644
--- a/engines/sherlock/tattoo/tattoo_talk.cpp
+++ b/engines/sherlock/tattoo/tattoo_talk.cpp
@@ -243,7 +243,7 @@ OpcodeReturn TattooTalk::cmdWalkHolmesToCoords(const byte *&str) {
x = -1 * (x - 16384);
// TODO: The RT walkToCoords call has an extra parameter, person, which is 0 (Holmes) here
warning("TODO: cmdWalkHolmesToCoords - call RT walkToCoords variant");
- people[PLAYER].walkToCoords(Point32(x * FIXED_INT_MULTIPLIER,
+ people[HOLMES].walkToCoords(Point32(x * FIXED_INT_MULTIPLIER,
((str[2] - 1) * 256 + str[3] - 1) * FIXED_INT_MULTIPLIER), DIRECTION_CONVERSION[str[4] - 1]);
if (_talkToAbort)
return RET_EXIT;