From 933e6751943fcb28fdb1b616f9834bd4f231f63d Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sat, 6 Jun 2015 22:40:29 -0400 Subject: SHERLOCK: Setting up game specific People descendant classes --- engines/sherlock/tattoo/tattoo_people.cpp | 39 +++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 engines/sherlock/tattoo/tattoo_people.cpp (limited to 'engines/sherlock/tattoo/tattoo_people.cpp') diff --git a/engines/sherlock/tattoo/tattoo_people.cpp b/engines/sherlock/tattoo/tattoo_people.cpp new file mode 100644 index 0000000000..e0f4102abb --- /dev/null +++ b/engines/sherlock/tattoo/tattoo_people.cpp @@ -0,0 +1,39 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#include "sherlock/tattoo/tattoo_people.h" + +namespace Sherlock { + +namespace Tattoo { + +void TattooPeople::setListenSequence(int speaker, int sequenceNum) { + // TODO +} + +void TattooPeople::setTalkSequence(int speaker, int sequenceNum) { + // TODO +} + +} // End of namespace Tattoo + +} // End of namespace Sherlock -- cgit v1.2.3 From 02ff4ce4950e09afb634feae4a7a854644418019 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 7 Jun 2015 11:37:15 -0400 Subject: SHERLOCK: Implemented talk/listen sequence methods --- engines/sherlock/tattoo/tattoo_people.cpp | 171 +++++++++++++++++++++++++++++- 1 file changed, 169 insertions(+), 2 deletions(-) (limited to 'engines/sherlock/tattoo/tattoo_people.cpp') diff --git a/engines/sherlock/tattoo/tattoo_people.cpp b/engines/sherlock/tattoo/tattoo_people.cpp index e0f4102abb..b253afd1da 100644 --- a/engines/sherlock/tattoo/tattoo_people.cpp +++ b/engines/sherlock/tattoo/tattoo_people.cpp @@ -21,17 +21,184 @@ */ #include "sherlock/tattoo/tattoo_people.h" +#include "sherlock/tattoo/tattoo_talk.h" +#include "sherlock/sherlock.h" namespace Sherlock { namespace Tattoo { void TattooPeople::setListenSequence(int speaker, int sequenceNum) { - // TODO + Scene &scene = *_vm->_scene; + + // If no speaker is specified, then nothing needs to be done + if (speaker == -1) + return; + + int objNum = findSpeaker(speaker); + if (objNum < 256 && objNum != -1) { + // See if the Object has to wait for an Abort Talk Code + Object &obj = scene._bgShapes[objNum]; + if (obj.hasAborts()) + obj._gotoSeq = sequenceNum; + else + obj.setObjTalkSequence(sequenceNum); + } else if (objNum != -1) { + objNum -= 256; + Person &person = _data[objNum]; + + int newDir = person._sequenceNumber; + switch (person._sequenceNumber) { + case WALK_UP: + case STOP_UP: + case WALK_UPRIGHT: + case STOP_UPRIGHT: + case TALK_UPRIGHT: + case LISTEN_UPRIGHT: + newDir = LISTEN_UPRIGHT; + break; + case WALK_RIGHT: + case STOP_RIGHT: + case TALK_RIGHT: + case LISTEN_RIGHT: + newDir = LISTEN_RIGHT; + break; + case WALK_DOWNRIGHT: + case STOP_DOWNRIGHT: + case TALK_DOWNRIGHT: + case LISTEN_DOWNRIGHT: + newDir = LISTEN_DOWNRIGHT; + break; + case WALK_DOWN: + case STOP_DOWN: + case WALK_DOWNLEFT: + case STOP_DOWNLEFT: + case TALK_DOWNLEFT: + case LISTEN_DOWNLEFT: + newDir = LISTEN_DOWNLEFT; + break; + case WALK_LEFT: + case STOP_LEFT: + case TALK_LEFT: + case LISTEN_LEFT: + newDir = LISTEN_LEFT; + break; + case WALK_UPLEFT: + case STOP_UPLEFT: + case TALK_UPLEFT: + case LISTEN_UPLEFT: + newDir = LISTEN_UPLEFT; + break; + + default: + break; + } + + // See if the NPC's Seq has to wait for an Abort Talk Code + if (person.hasAborts()) { + person._gotoSeq = newDir; + } else { + if (person._seqTo) { + // Reset to previous value + person._walkSequences[person._sequenceNumber]._sequences[person._frameNumber] = person._seqTo; + person._seqTo = 0; + } + + person._sequenceNumber = newDir; + person._frameNumber = 0; + person.checkWalkGraphics(); + } + } } void TattooPeople::setTalkSequence(int speaker, int sequenceNum) { - // TODO + People &people = *_vm->_people; + Scene &scene = *_vm->_scene; + TattooTalk &talk = *(TattooTalk *)_vm->_talk; + + // If no speaker is specified, then nothing needs to be done + if (speaker == -1) + return; + + int objNum = people.findSpeaker(speaker); + if (objNum != -1 && objNum < 256) { + Object &obj = scene._bgShapes[objNum]; + + // See if the Object has to wait for an Abort Talk Code + if (obj.hasAborts()) { + talk.pushTalkSequence(&obj); + obj._gotoSeq = sequenceNum; + } + else { + obj.setObjTalkSequence(sequenceNum); + } + } + else if (objNum != -1) { + objNum -= 256; + Person &person = people[objNum]; + int newDir = person._sequenceNumber; + + switch (newDir) { + case WALK_UP: + case STOP_UP: + case WALK_UPRIGHT: + case STOP_UPRIGHT: + case TALK_UPRIGHT: + case LISTEN_UPRIGHT: + newDir = TALK_UPRIGHT; + break; + case WALK_RIGHT: + case STOP_RIGHT: + case TALK_RIGHT: + case LISTEN_RIGHT: + newDir = TALK_RIGHT; + break; + case WALK_DOWNRIGHT: + case STOP_DOWNRIGHT: + case TALK_DOWNRIGHT: + case LISTEN_DOWNRIGHT: + newDir = TALK_DOWNRIGHT; + break; + case WALK_DOWN: + case STOP_DOWN: + case WALK_DOWNLEFT: + case STOP_DOWNLEFT: + case TALK_DOWNLEFT: + case LISTEN_DOWNLEFT: + newDir = TALK_DOWNLEFT; + break; + case WALK_LEFT: + case STOP_LEFT: + case TALK_LEFT: + case LISTEN_LEFT: + newDir = TALK_LEFT; + break; + case WALK_UPLEFT: + case STOP_UPLEFT: + case TALK_UPLEFT: + case LISTEN_UPLEFT: + newDir = TALK_UPLEFT; + break; + default: + break; + } + + // See if the NPC's sequence has to wait for an Abort Talk Code + if (person.hasAborts()) { + person._gotoSeq = newDir; + } + else { + if (person._seqTo) { + // Reset to previous value + person._walkSequences[person._sequenceNumber]._sequences[person._frameNumber] = person._seqTo; + person._seqTo = 0; + } + + person._sequenceNumber = newDir; + person._frameNumber = 0; + person.checkWalkGraphics(); + } + } } } // End of namespace Tattoo -- cgit v1.2.3 From 9b837c308f3175586aaceb273c6d11bfc778fbb1 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 7 Jun 2015 14:26:57 -0400 Subject: SHERLOCK: Fix for switching speakers --- engines/sherlock/tattoo/tattoo_people.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'engines/sherlock/tattoo/tattoo_people.cpp') diff --git a/engines/sherlock/tattoo/tattoo_people.cpp b/engines/sherlock/tattoo/tattoo_people.cpp index b253afd1da..4e4f11b983 100644 --- a/engines/sherlock/tattoo/tattoo_people.cpp +++ b/engines/sherlock/tattoo/tattoo_people.cpp @@ -186,8 +186,7 @@ void TattooPeople::setTalkSequence(int speaker, int sequenceNum) { // See if the NPC's sequence has to wait for an Abort Talk Code if (person.hasAborts()) { person._gotoSeq = newDir; - } - else { + } else { if (person._seqTo) { // Reset to previous value person._walkSequences[person._sequenceNumber]._sequences[person._frameNumber] = person._seqTo; -- cgit v1.2.3 From af2a1a33514ae101d1df52e6a978296ed0bef68b Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 7 Jun 2015 19:18:14 -0400 Subject: SHERLOCK: Refactoring, cleanup, and fixes for savegame code --- engines/sherlock/tattoo/tattoo_people.cpp | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) (limited to 'engines/sherlock/tattoo/tattoo_people.cpp') diff --git a/engines/sherlock/tattoo/tattoo_people.cpp b/engines/sherlock/tattoo/tattoo_people.cpp index 4e4f11b983..6952c876c0 100644 --- a/engines/sherlock/tattoo/tattoo_people.cpp +++ b/engines/sherlock/tattoo/tattoo_people.cpp @@ -200,6 +200,28 @@ void TattooPeople::setTalkSequence(int speaker, int sequenceNum) { } } +void TattooPeople::synchronize(Serializer &s) { + s.syncAsByte(_holmesOn); + + for (int idx = 0; idx < MAX_CHARACTERS; ++idx) { + Person &p = _data[idx]; + s.syncAsSint32LE(p._position.x); + s.syncAsSint32LE(p._position.y); + s.syncAsSint16LE(p._sequenceNumber); + s.syncAsSint16LE(p._type); + s.syncString(p._walkVGSName); + s.syncString(p._description); + s.syncString(p._examine); + } + + s.syncAsSint16LE(_holmesQuotient); + + if (s.isLoading()) { + _hSavedPos = _player._position; + _hSavedFacing = _player._sequenceNumber; + } +} + } // End of namespace Tattoo } // End of namespace Sherlock -- cgit v1.2.3 From f5a1b626b710c368e79ab27c13cf2be4ccdcb30f Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Mon, 8 Jun 2015 08:31:51 -0400 Subject: SHERLOCK: Move Scalpel map code to ScalpelMap --- engines/sherlock/tattoo/tattoo_people.cpp | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'engines/sherlock/tattoo/tattoo_people.cpp') diff --git a/engines/sherlock/tattoo/tattoo_people.cpp b/engines/sherlock/tattoo/tattoo_people.cpp index 6952c876c0..61f79c471c 100644 --- a/engines/sherlock/tattoo/tattoo_people.cpp +++ b/engines/sherlock/tattoo/tattoo_people.cpp @@ -222,6 +222,10 @@ void TattooPeople::synchronize(Serializer &s) { } } +void TattooPeople::gotoStand(Sprite &sprite) { + error("TODO: gotoStand"); +} + } // End of namespace Tattoo } // End of namespace Sherlock -- cgit v1.2.3 From 3d0e2cb5b000bfa9ff731fc6a83ec402bd9f7aad Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Thu, 11 Jun 2015 22:02:33 -0400 Subject: SHERLOCK: Beginning of descendent Person classes Tattoo has some different Sprite methods, and since Person descends from Sprite, need to create descendents from it. And this has also necessitated some refactoring of People class's _data array --- engines/sherlock/tattoo/tattoo_people.cpp | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) (limited to 'engines/sherlock/tattoo/tattoo_people.cpp') diff --git a/engines/sherlock/tattoo/tattoo_people.cpp b/engines/sherlock/tattoo/tattoo_people.cpp index 61f79c471c..cc50a32b7b 100644 --- a/engines/sherlock/tattoo/tattoo_people.cpp +++ b/engines/sherlock/tattoo/tattoo_people.cpp @@ -28,6 +28,20 @@ namespace Sherlock { namespace Tattoo { +void TattooPerson::adjustSprite() { + // TODO + warning("TODO: TattooPerson::adjustSprite"); +} + +/*----------------------------------------------------------------*/ + +TattooPeople::TattooPeople(SherlockEngine *vm) : People(vm) { + for (int idx = 0; idx < 6; ++idx) + _data.push_back(new TattooPerson()); +} + + + void TattooPeople::setListenSequence(int speaker, int sequenceNum) { Scene &scene = *_vm->_scene; @@ -45,7 +59,7 @@ void TattooPeople::setListenSequence(int speaker, int sequenceNum) { obj.setObjTalkSequence(sequenceNum); } else if (objNum != -1) { objNum -= 256; - Person &person = _data[objNum]; + Person &person = *_data[objNum]; int newDir = person._sequenceNumber; switch (person._sequenceNumber) { @@ -203,8 +217,8 @@ void TattooPeople::setTalkSequence(int speaker, int sequenceNum) { void TattooPeople::synchronize(Serializer &s) { s.syncAsByte(_holmesOn); - for (int idx = 0; idx < MAX_CHARACTERS; ++idx) { - Person &p = _data[idx]; + for (uint idx = 0; idx < _data.size(); ++idx) { + Person &p = *_data[idx]; s.syncAsSint32LE(p._position.x); s.syncAsSint32LE(p._position.y); s.syncAsSint16LE(p._sequenceNumber); @@ -217,8 +231,8 @@ void TattooPeople::synchronize(Serializer &s) { s.syncAsSint16LE(_holmesQuotient); if (s.isLoading()) { - _hSavedPos = _player._position; - _hSavedFacing = _player._sequenceNumber; + _hSavedPos = _data[PLAYER]->_position; + _hSavedFacing = _data[PLAYER]->_sequenceNumber; } } -- cgit v1.2.3 From a97715f9dcca2022a8f502ded4e4843f076b4687 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Thu, 11 Jun 2015 22:55:36 -0400 Subject: SHERLOCK: Refactor gotoStand into Person classes --- engines/sherlock/tattoo/tattoo_people.cpp | 84 ++++++++++++++++++++++++++++--- 1 file changed, 78 insertions(+), 6 deletions(-) (limited to 'engines/sherlock/tattoo/tattoo_people.cpp') diff --git a/engines/sherlock/tattoo/tattoo_people.cpp b/engines/sherlock/tattoo/tattoo_people.cpp index cc50a32b7b..0e08eb5fd7 100644 --- a/engines/sherlock/tattoo/tattoo_people.cpp +++ b/engines/sherlock/tattoo/tattoo_people.cpp @@ -21,6 +21,7 @@ */ #include "sherlock/tattoo/tattoo_people.h" +#include "sherlock/tattoo/tattoo_scene.h" #include "sherlock/tattoo/tattoo_talk.h" #include "sherlock/sherlock.h" @@ -29,8 +30,83 @@ namespace Sherlock { namespace Tattoo { void TattooPerson::adjustSprite() { - // TODO - warning("TODO: TattooPerson::adjustSprite"); + People &people = *_vm->_people; + TattooScene &scene = *(TattooScene *)_vm->_scene; + + if (_type == INVALID) + return; + + if (_type == CHARACTER && _status) { + // Sprite waiting to move, so restart walk + _walkCount = _status; + _status = 0; + + people._walkDest = _walkTo.front(); + setWalking(); + } else if (_type == CHARACTER && _walkCount) { + if (_walkCount > 10) { + people._walkDest = _walkTo.front(); + setWalking(); + } + + _position += _delta; + if (_walkCount) + --_walkCount; + + if (!_walkCount) { + // If there are remaining points to walk, move to the next one + people._walkDest = _walkTo.pop(); + setWalking(); + } else { + gotoStand(); + } + } + + if (_type != CHARACTER) { + if (_position.y > SHERLOCK_SCREEN_HEIGHT) + _position.y = SHERLOCK_SCREEN_HEIGHT; + + if (_position.y < UPPER_LIMIT) + _position.y = UPPER_LIMIT; + + if (_position.x < LEFT_LIMIT) + _position.x = LEFT_LIMIT; + + if (_position.x > RIGHT_LIMIT) + _position.x = RIGHT_LIMIT; + } + + int frameNum = _frameNumber; + if (frameNum == -1) + frameNum = 0; + int idx = _walkSequences[_sequenceNumber][frameNum]; + if (idx > _maxFrames) + idx = 1; + + // Set the image frame + if (_altSeq) + _imageFrame = &(*_altImages)[idx - 1]; + else + _imageFrame = &(*_images)[idx - 1]; + + // 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)) { + people._hSavedPos = scene._exits[scene._exitZone]._newPosition; + people._hSavedFacing = scene._exits[scene._exitZone]._newFacing; + + if (people._hSavedFacing > 100 && people._hSavedPos.x < 1) + people._hSavedPos.x = 100; + } +} + +void TattooPerson::gotoStand() { + error("TODO: gotoStand"); +} + +void TattooPerson::setWalking() { + error("TODO: setWalking"); } /*----------------------------------------------------------------*/ @@ -236,10 +312,6 @@ void TattooPeople::synchronize(Serializer &s) { } } -void TattooPeople::gotoStand(Sprite &sprite) { - error("TODO: gotoStand"); -} - } // End of namespace Tattoo } // End of namespace Sherlock -- cgit v1.2.3 From 82b3559d69c26067b4d8238e07f937a62b27a648 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Thu, 11 Jun 2015 23:48:01 -0400 Subject: SHERLOCK: RT: Implemented gotoStand --- engines/sherlock/tattoo/tattoo_people.cpp | 125 +++++++++++++++++++++++++++++- 1 file changed, 124 insertions(+), 1 deletion(-) (limited to 'engines/sherlock/tattoo/tattoo_people.cpp') diff --git a/engines/sherlock/tattoo/tattoo_people.cpp b/engines/sherlock/tattoo/tattoo_people.cpp index 0e08eb5fd7..6558231149 100644 --- a/engines/sherlock/tattoo/tattoo_people.cpp +++ b/engines/sherlock/tattoo/tattoo_people.cpp @@ -29,6 +29,8 @@ namespace Sherlock { namespace Tattoo { +#define FACING_PLAYER 16 + void TattooPerson::adjustSprite() { People &people = *_vm->_people; TattooScene &scene = *(TattooScene *)_vm->_scene; @@ -102,7 +104,128 @@ void TattooPerson::adjustSprite() { } void TattooPerson::gotoStand() { - error("TODO: gotoStand"); + People &people = *_vm->_people; + + // If the misc field is set, then we're running a special talk sequence, so don't interrupt it. + if (_misc) + return; + + _walkTo.clear(); + _walkCount = 0; + int oldFacing = _sequenceNumber; + + // If the person was talking or listening, just return it to the standing sequence + // in the direction they were pointing + if (_sequenceNumber >= TALK_UPRIGHT && _sequenceNumber <= LISTEN_UPLEFT) { + switch (_sequenceNumber) { + case TALK_UPRIGHT: + case LISTEN_UPRIGHT: + _sequenceNumber = STOP_UPRIGHT; + break; + case TALK_RIGHT: + case LISTEN_RIGHT: + _sequenceNumber = STOP_RIGHT; + break; + case TALK_DOWNRIGHT: + case LISTEN_DOWNRIGHT: + _sequenceNumber = STOP_DOWNRIGHT; + break; + case TALK_DOWNLEFT: + case LISTEN_DOWNLEFT: + _sequenceNumber = STOP_DOWNLEFT; + break; + case TALK_LEFT: + case LISTEN_LEFT: + _sequenceNumber = STOP_LEFT; + break; + case TALK_UPLEFT: + case LISTEN_UPLEFT: + _sequenceNumber = STOP_UPLEFT; + break; + default: + break; + } + + if (_seqTo) { + // Reset to previous value + _walkSequences[oldFacing]._sequences[_frameNumber] = _seqTo; + _seqTo = 0; + } + + // Set the Frame number to the last frame so we don't move + _frameNumber = 0; + + checkWalkGraphics(); + + _oldWalkSequence = -1; + people._allowWalkAbort = true; + return; + } + + // If the sprite that is stopping is an NPC and he is supposed to face a certain direction + // when he stops, set that direction here + int npc = -1; + for (int idx = 1; idx < MAX_CHARACTERS; ++idx) { + if (_imageFrame == people[idx]._imageFrame) + npc = idx; + } + + 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) + 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)) { + // 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)) { + // Holmes is below the NPC so reset the facing to the diagonal downs + if (people[npc]._npcFacing == STOP_RIGHT) + people[npc]._npcFacing = STOP_DOWNRIGHT; + else + people[npc]._npcFacing = STOP_DOWNLEFT; + } + } + } + + _sequenceNumber = people[npc]._npcFacing; + } else { + switch (_sequenceNumber) { + case WALK_UP: _sequenceNumber = STOP_UP; break; + case WALK_UPRIGHT: _sequenceNumber = STOP_UPRIGHT; break; + case WALK_RIGHT: _sequenceNumber = STOP_RIGHT; break; + case WALK_DOWNRIGHT: _sequenceNumber = STOP_DOWNRIGHT; break; + case WALK_DOWN: _sequenceNumber = STOP_DOWN; break; + case WALK_DOWNLEFT: _sequenceNumber = STOP_DOWNLEFT;break; + case WALK_LEFT: _sequenceNumber = STOP_LEFT; break; + case WALK_UPLEFT: _sequenceNumber = STOP_UPLEFT; break; + } + } + + // Only restart the frame number at 0 if the new sequence is different from the last sequence + // so we don't let Holmes repeat standing. + if (_oldWalkSequence != -1) { + if (_seqTo) { + // Reset to previous value + _walkSequences[oldFacing]._sequences[_frameNumber] = _seqTo; + _seqTo = 0; + } + + _frameNumber = 0; + } + + checkWalkGraphics(); + + _oldWalkSequence = -1; + people._allowWalkAbort = true; } void TattooPerson::setWalking() { -- cgit v1.2.3 From ed29691b2facecdfac934f90841f69e81c12e697 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Fri, 12 Jun 2015 19:37:53 -0400 Subject: SHERLOCK: RT: Move RT fields added to Person to TattooPerson --- engines/sherlock/tattoo/tattoo_people.cpp | 53 ++++++++++++++++++++++++++++++- 1 file changed, 52 insertions(+), 1 deletion(-) (limited to 'engines/sherlock/tattoo/tattoo_people.cpp') diff --git a/engines/sherlock/tattoo/tattoo_people.cpp b/engines/sherlock/tattoo/tattoo_people.cpp index 6558231149..bea105fee0 100644 --- a/engines/sherlock/tattoo/tattoo_people.cpp +++ b/engines/sherlock/tattoo/tattoo_people.cpp @@ -31,6 +31,20 @@ namespace Tattoo { #define FACING_PLAYER 16 +TattooPerson::TattooPerson() : Person() { + Common::fill(&_npcPath[0], &_npcPath[MAX_NPC_PATH], 0); + _tempX = _tempScaleVal = 0; + _npcIndex = 0; + _npcStack = 0; + _npcMoved = false; + _npcFacing = -1; + _resetNPCPath = true; + _savedNpcSequence = 0; + _savedNpcFrame = 0; + _updateNPCPath = false; + _npcPause = false; +} + void TattooPerson::adjustSprite() { People &people = *_vm->_people; TattooScene &scene = *(TattooScene *)_vm->_scene; @@ -104,7 +118,7 @@ void TattooPerson::adjustSprite() { } void TattooPerson::gotoStand() { - People &people = *_vm->_people; + TattooPeople &people = *(TattooPeople *)_vm->_people; // If the misc field is set, then we're running a special talk sequence, so don't interrupt it. if (_misc) @@ -232,6 +246,16 @@ void TattooPerson::setWalking() { error("TODO: setWalking"); } +void TattooPerson::clearNPC() { + Common::fill(&_npcPath[0], &_npcPath[MAX_NPC_PATH], 0); + _npcIndex = _npcStack = 0; + _npcName = ""; +} + +void TattooPerson::updateNPC() { + // TODO +} + /*----------------------------------------------------------------*/ TattooPeople::TattooPeople(SherlockEngine *vm) : People(vm) { @@ -413,6 +437,33 @@ void TattooPeople::setTalkSequence(int speaker, int sequenceNum) { } } + +int TattooPeople::findSpeaker(int speaker) { + int result = People::findSpeaker(speaker); + const char *portrait = _characters[speaker]._portrait; + + // Fallback that Rose Tattoo uses if no speaker was found + if (result == -1) { + bool flag = _vm->readFlags(76); + + if (_data[PLAYER]->_type == CHARACTER && ((speaker == 0 && flag) || (speaker == 1 && !flag))) + return -1; + + for (uint idx = 1; idx < _data.size(); ++idx) { + TattooPerson &p = (*this)[idx]; + + if (p._type == CHARACTER) { + Common::String name(p._name.c_str(), p._name.c_str() + 4); + + if (name.equalsIgnoreCase(portrait) && p._npcName[4] >= '0' && p._npcName[4] <= '9') + return idx + 256; + } + } + } + + return -1; +} + void TattooPeople::synchronize(Serializer &s) { s.syncAsByte(_holmesOn); -- cgit v1.2.3 From 8ac4ab484c588ce37e551e94d691c83864f0fe02 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Fri, 12 Jun 2015 20:01:27 -0400 Subject: SHERLOCK: Split up loadWalk into descendent classes --- engines/sherlock/tattoo/tattoo_people.cpp | 61 +++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) (limited to 'engines/sherlock/tattoo/tattoo_people.cpp') diff --git a/engines/sherlock/tattoo/tattoo_people.cpp b/engines/sherlock/tattoo/tattoo_people.cpp index bea105fee0..f70b079760 100644 --- a/engines/sherlock/tattoo/tattoo_people.cpp +++ b/engines/sherlock/tattoo/tattoo_people.cpp @@ -486,6 +486,67 @@ void TattooPeople::synchronize(Serializer &s) { } } +bool TattooPeople::loadWalk() { + Resources &res = *_vm->_res; + bool result = false; + + for (int idx = 0; idx < MAX_CHARACTERS; ++idx) { + if (!_data[idx]->_walkLoaded && (_data[idx]->_type == CHARACTER || _data[idx]->_type == HIDDEN_CHARACTER)) { + if (_data[idx]->_type == HIDDEN_CHARACTER) + _data[idx]->_type = INVALID; + + // See if this is one of the more used Walk Graphics stored in WALK.LIB + for (int libNum = 0; libNum < NUM_IN_WALK_LIB; ++libNum) { + if (!_data[idx]->_walkVGSName.compareToIgnoreCase(WALK_LIB_NAMES[libNum])) { + _useWalkLib = true; + break; + } + } + + // Load the images for the character + _data[idx]->_images = new ImageFile(_data[idx]->_walkVGSName, false); + _data[idx]->_numFrames = _data[idx]->_images->size(); + + // Load walk sequence data + Common::String fname = Common::String(_data[idx]->_walkVGSName.c_str(), strchr(_data[idx]->_walkVGSName.c_str(), '.')); + fname += ".SEQ"; + + // Load the walk sequence data + Common::SeekableReadStream *stream = res.load(fname, _useWalkLib ? "walk.lib" : "vgs.lib"); + + _data[idx]->_walkSequences.resize(stream->readByte()); + + for (uint seqNum = 0; seqNum < _data[idx]->_walkSequences.size(); ++seqNum) + _data[idx]->_walkSequences[seqNum].load(*stream); + + // Close the sequences resource + delete stream; + _useWalkLib = false; + + _data[idx]->_frameNumber = 0; + _data[idx]->setImageFrame(); + + // Set the stop Frames pointers + for (int dirNum = 0; dirNum < 8; ++dirNum) { + int count = 0; + while (_data[idx]->_walkSequences[dirNum + 8][count] != 0) + ++count; + count += 2; + count = _data[idx]->_walkSequences[dirNum + 8][count] - 1; + _data[idx]->_stopFrames[dirNum] = &(*_data[idx]->_images)[count]; + } + + result = true; + _data[idx]->_walkLoaded = true; + } else if (_data[idx]->_type != CHARACTER) { + _data[idx]->_walkLoaded = false; + } + } + + _forceWalkReload = false; + return result; +} + } // End of namespace Tattoo } // End of namespace Sherlock -- cgit v1.2.3 From 803c06beb919b35d29bb65ec2e7e48caca69c730 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Fri, 12 Jun 2015 23:23:16 -0400 Subject: SHERLOCK: RT: Implement startCAnim --- engines/sherlock/tattoo/tattoo_people.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'engines/sherlock/tattoo/tattoo_people.cpp') 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; } } -- cgit v1.2.3 From 864dc6acb7915f9b45ce958ff0ad645de74019d5 Mon Sep 17 00:00:00 2001 From: Filippos Karapetis Date: Sat, 13 Jun 2015 23:27:21 +0300 Subject: SHERLOCK: Initial implementation of the NPC-related opcodes This includes cmdWalkHolmesAndNPCToCAnimation, cmdWalkNPCToCAnimation, cmdWalkNPCToCoords and cmdWalkHomesAndNPCToCoords --- engines/sherlock/tattoo/tattoo_people.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'engines/sherlock/tattoo/tattoo_people.cpp') diff --git a/engines/sherlock/tattoo/tattoo_people.cpp b/engines/sherlock/tattoo/tattoo_people.cpp index 7560ca1593..609d3d73d3 100644 --- a/engines/sherlock/tattoo/tattoo_people.cpp +++ b/engines/sherlock/tattoo/tattoo_people.cpp @@ -243,7 +243,7 @@ void TattooPerson::gotoStand() { } void TattooPerson::setWalking() { - error("TODO: setWalking"); + warning("TODO: setWalking"); } void TattooPerson::clearNPC() { @@ -253,7 +253,11 @@ void TattooPerson::clearNPC() { } void TattooPerson::updateNPC() { - // TODO + warning("TODO: updateNPC"); +} + +void TattooPerson::pushNPCPath() { + warning("TODO: pushNPCPath"); } /*----------------------------------------------------------------*/ -- cgit v1.2.3 From 02f582d5af02411bbe943014788cbad6f8e6b12b Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sat, 13 Jun 2015 16:48:34 -0400 Subject: SHERLOCK: RT: Implement setWalking --- engines/sherlock/tattoo/tattoo_people.cpp | 177 +++++++++++++++++++++++++++++- 1 file changed, 176 insertions(+), 1 deletion(-) (limited to 'engines/sherlock/tattoo/tattoo_people.cpp') diff --git a/engines/sherlock/tattoo/tattoo_people.cpp b/engines/sherlock/tattoo/tattoo_people.cpp index 609d3d73d3..e2cfea63c9 100644 --- a/engines/sherlock/tattoo/tattoo_people.cpp +++ b/engines/sherlock/tattoo/tattoo_people.cpp @@ -31,6 +31,32 @@ namespace Tattoo { #define FACING_PLAYER 16 +static const int WALK_SPEED_X[99] = { + 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 98, 90, 90, 90, 90, 90, 91, 90, 90, + 90, 90,100, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90,100, 90, + 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90,103, 90, 90, 90, 90, 90, 90, 90, + 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, + 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90 +}; + +static const int WALK_SPEED_Y[99] = { + 28, 28, 28, 28, 28, 28, 28, 28, 28, 32, 32, 32, 28, 28, 28, 28, 28, 26, 28, 28, + 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, + 32, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 31, 28, 28, 28, 28, 28, 28, 28, + 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, + 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28 +}; + +static const int WALK_SPEED_DIAG_X[99] = { + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 90, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50 +}; + +/*----------------------------------------------------------------*/ + TattooPerson::TattooPerson() : Person() { Common::fill(&_npcPath[0], &_npcPath[MAX_NPC_PATH], 0); _tempX = _tempScaleVal = 0; @@ -243,7 +269,156 @@ void TattooPerson::gotoStand() { } void TattooPerson::setWalking() { - warning("TODO: setWalking"); + People &people = *_vm->_people; + TattooScene &scene = *(TattooScene *)_vm->_scene; + int oldDirection, oldFrame; + Common::Point delta; + + // Flag that player has now walked in the scene + scene._walkedInScene = true; + + // Stop any previous walking, since a new dest is being set + _walkCount = 0; + oldDirection = _sequenceNumber; + oldFrame = _frameNumber; + + // Set speed to use horizontal and vertical movement + int scaleVal = scene.getScaleVal(_position); + Common::Point speed(MAX(WALK_SPEED_X[scene._currentScene - 1] * SCALE_THRESHOLD / scaleVal, 2), + MAX(WALK_SPEED_Y[scene._currentScene - 1] * SCALE_THRESHOLD / scaleVal, 2)); + Common::Point diagSpeed(MAX((WALK_SPEED_Y[scene._currentScene - 1] - 2) * SCALE_THRESHOLD / scaleVal, 2), + MAX(WALK_SPEED_DIAG_X[scene._currentScene - 1] * SCALE_THRESHOLD / scaleVal, 2)); + + // 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 + int temp; + if (people._walkDest.x >= (temp = _imageFrame->_frame.w / 2)) + people._walkDest.x -= temp; + + delta = Common::Point( + ABS(_position.x / FIXED_INT_MULTIPLIER - people._walkDest.x), + ABS(_position.y / FIXED_INT_MULTIPLIER - people._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 + people._walkDest = _walkTo.pop(); + } + + // 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 setting the delta x depending on direction + if (people._walkDest.x < (_position.x / FIXED_INT_MULTIPLIER)) { + _sequenceNumber = WALK_LEFT; + _delta.x = speed.x * -FIXED_INT_MULTIPLIER; + } else { + _sequenceNumber = WALK_RIGHT; + _delta.x = speed.x * FIXED_INT_MULTIPLIER; + } + + // 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 + _delta.y = (delta.y * FIXED_INT_MULTIPLIER) / (delta.x / speed.x); + if (people._walkDest.y < (_position.y / FIXED_INT_MULTIPLIER)) + _delta.y = -_delta.y; + + // Set how many times we should add the delta to the player's position + _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 + _delta = Point32(0, 0); + _position = Point32(people._walkDest.x * FIXED_INT_MULTIPLIER, people._walkDest.y * FIXED_INT_MULTIPLIER); + + _walkCount = 1; + } + + // See if the sequence needs to be changed for diagonal walking + if (_delta.y > 1500) { + if (_sequenceNumber == WALK_LEFT || _sequenceNumber == WALK_RIGHT) { + _delta.x = _delta.x / speed.x * diagSpeed.x; + _delta.y = (delta.y * FIXED_INT_MULTIPLIER) / (delta.x * 10 / diagSpeed.x); + } + + switch (_sequenceNumber) { + case WALK_LEFT: + _sequenceNumber = WALK_DOWNLEFT; + break; + case WALK_RIGHT: + _sequenceNumber = WALK_DOWNRIGHT; + break; + } + } else if (_delta.y < -1500) { + if (_sequenceNumber == WALK_LEFT || _sequenceNumber == WALK_RIGHT) { + _delta.x = _delta.x / speed.x * diagSpeed.x; + _delta.y = -1 * (delta.y * FIXED_INT_MULTIPLIER) / (delta.x * 10 / diagSpeed.x); + } + + switch (_sequenceNumber) { + case WALK_LEFT: + _sequenceNumber = WALK_UPLEFT; + break; + case WALK_RIGHT: + _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 (people._walkDest.y < (_position.y / FIXED_INT_MULTIPLIER)) { + _sequenceNumber = WALK_UP; + _delta.y = speed.y * -FIXED_INT_MULTIPLIER; + } else { + _sequenceNumber = WALK_DOWN; + _delta.y = speed.y * FIXED_INT_MULTIPLIER; + } + + // Set the delta x + _delta.x = (delta.x * FIXED_INT_MULTIPLIER) / (delta.y / speed.y); + if (people._walkDest.x < (_position.x / FIXED_INT_MULTIPLIER)) + _delta.x = -_delta.x; + + _walkCount = delta.y / speed.y; + } + } + + // 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 (_sequenceNumber != _oldWalkSequence) { + if (_seqTo) { + // Reset to previous value + _walkSequences[oldDirection]._sequences[_frameNumber] = _seqTo; + _seqTo = 0; + } + _frameNumber = 0; + } + + checkWalkGraphics(); + _oldWalkSequence = _sequenceNumber; + + if (!_walkCount && _walkTo.empty()) + gotoStand(); + + // 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 (_sequenceNumber == oldDirection) + _frameNumber = oldFrame; } void TattooPerson::clearNPC() { -- cgit v1.2.3 From 2909c968e5e9895160c693be825c2c7aa88e4b5c Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sat, 13 Jun 2015 17:59:45 -0400 Subject: SHERLOCK: RT: Fix initial facing of characters within scene --- engines/sherlock/tattoo/tattoo_people.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'engines/sherlock/tattoo/tattoo_people.cpp') diff --git a/engines/sherlock/tattoo/tattoo_people.cpp b/engines/sherlock/tattoo/tattoo_people.cpp index e2cfea63c9..ebada5627c 100644 --- a/engines/sherlock/tattoo/tattoo_people.cpp +++ b/engines/sherlock/tattoo/tattoo_people.cpp @@ -684,7 +684,7 @@ bool TattooPeople::loadWalk() { // Load the images for the character _data[idx]->_images = new ImageFile(_data[idx]->_walkVGSName, false); - _data[idx]->_numFrames = _data[idx]->_images->size(); + _data[idx]->_maxFrames = _data[idx]->_images->size(); // Load walk sequence data Common::String fname = Common::String(_data[idx]->_walkVGSName.c_str(), strchr(_data[idx]->_walkVGSName.c_str(), '.')); -- cgit v1.2.3 From 8629feb410068c084741de1bc2126ed6cd53a4cd Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 14 Jun 2015 00:43:19 -0400 Subject: SHERLOCK: RT: Implemented walk setup --- engines/sherlock/tattoo/tattoo_people.cpp | 45 ++++++++++++++++++++++--------- 1 file changed, 32 insertions(+), 13 deletions(-) (limited to 'engines/sherlock/tattoo/tattoo_people.cpp') diff --git a/engines/sherlock/tattoo/tattoo_people.cpp b/engines/sherlock/tattoo/tattoo_people.cpp index ebada5627c..cec8cd9bdf 100644 --- a/engines/sherlock/tattoo/tattoo_people.cpp +++ b/engines/sherlock/tattoo/tattoo_people.cpp @@ -286,18 +286,28 @@ void TattooPerson::setWalking() { int scaleVal = scene.getScaleVal(_position); Common::Point speed(MAX(WALK_SPEED_X[scene._currentScene - 1] * SCALE_THRESHOLD / scaleVal, 2), MAX(WALK_SPEED_Y[scene._currentScene - 1] * SCALE_THRESHOLD / scaleVal, 2)); - Common::Point diagSpeed(MAX((WALK_SPEED_Y[scene._currentScene - 1] - 2) * SCALE_THRESHOLD / scaleVal, 2), - MAX(WALK_SPEED_DIAG_X[scene._currentScene - 1] * SCALE_THRESHOLD / scaleVal, 2)); + Common::Point diagSpeed(MAX(WALK_SPEED_DIAG_X[scene._currentScene - 1] * SCALE_THRESHOLD / scaleVal, 2), + MAX((WALK_SPEED_Y[scene._currentScene - 1] - 2) * SCALE_THRESHOLD / scaleVal, 2)); // 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 - int temp; - if (people._walkDest.x >= (temp = _imageFrame->_frame.w / 2)) - people._walkDest.x -= temp; + if (_centerWalk || !_walkTo.empty()) { + // Since we want the player to be centered on the ultimate destination, and the player + // is drawn from the left side, move the cursor half the width of the player to center it + delta = Common::Point(_position.x / FIXED_INT_MULTIPLIER - people._walkDest.x, + _position.y / FIXED_INT_MULTIPLIER - people._walkDest.y); + + int dir; + if (ABS(delta.x) > ABS(delta.y)) + dir = (delta.x < 0) ? WALK_LEFT : WALK_RIGHT; + else + dir = (delta.y < 0) ? WALK_UP : WALK_DOWN; + + int scaleVal = scene.getScaleVal(Point32(people._walkDest.x * FIXED_INT_MULTIPLIER, + people._walkDest.y * FIXED_INT_MULTIPLIER)); + people._walkDest.x -= _stopFrames[dir]->sDrawXSize(scaleVal) / 2; + } delta = Common::Point( ABS(_position.x / FIXED_INT_MULTIPLIER - people._walkDest.x), @@ -321,22 +331,22 @@ void TattooPerson::setWalking() { // as setting the delta x depending on direction if (people._walkDest.x < (_position.x / FIXED_INT_MULTIPLIER)) { _sequenceNumber = WALK_LEFT; - _delta.x = speed.x * -FIXED_INT_MULTIPLIER; + _delta.x = speed.x * -(FIXED_INT_MULTIPLIER / 10); } else { _sequenceNumber = WALK_RIGHT; - _delta.x = speed.x * FIXED_INT_MULTIPLIER; + _delta.x = speed.x * (FIXED_INT_MULTIPLIER / 10); } // 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) { + if ((delta.x * 10) >= speed.x) { // Det the delta y - _delta.y = (delta.y * FIXED_INT_MULTIPLIER) / (delta.x / speed.x); + _delta.y = (delta.y * FIXED_INT_MULTIPLIER) / ((delta.x * 10) / speed.x); if (people._walkDest.y < (_position.y / FIXED_INT_MULTIPLIER)) _delta.y = -_delta.y; // Set how many times we should add the delta to the player's position - _walkCount = delta.x / speed.x; + _walkCount = (delta.x * 10) / 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 @@ -365,6 +375,7 @@ void TattooPerson::setWalking() { if (_sequenceNumber == WALK_LEFT || _sequenceNumber == WALK_RIGHT) { _delta.x = _delta.x / speed.x * diagSpeed.x; _delta.y = -1 * (delta.y * FIXED_INT_MULTIPLIER) / (delta.x * 10 / diagSpeed.x); + _walkCount = (delta.x * 10) / diagSpeed.x; } switch (_sequenceNumber) { @@ -435,6 +446,14 @@ void TattooPerson::pushNPCPath() { warning("TODO: pushNPCPath"); } +Common::Point TattooPerson::getSourcePoint() const { + TattooScene &scene = *(TattooScene *)_vm->_scene; + int scaleVal = scene.getScaleVal(_position); + + return Common::Point(_position.x / FIXED_INT_MULTIPLIER + _imageFrame->sDrawXSize(scaleVal) / 2, + _position.y / FIXED_INT_MULTIPLIER); +} + /*----------------------------------------------------------------*/ TattooPeople::TattooPeople(SherlockEngine *vm) : People(vm) { -- cgit v1.2.3 From 5b65b76a8fc7525402816d7c5393866cafa038d3 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 14 Jun 2015 09:39:20 -0400 Subject: SHERLOCK: RT: Fix initialization of character animation sequences --- engines/sherlock/tattoo/tattoo_people.cpp | 40 +++++++++++++++++-------------- 1 file changed, 22 insertions(+), 18 deletions(-) (limited to 'engines/sherlock/tattoo/tattoo_people.cpp') diff --git a/engines/sherlock/tattoo/tattoo_people.cpp b/engines/sherlock/tattoo/tattoo_people.cpp index cec8cd9bdf..2bdf1164ab 100644 --- a/engines/sherlock/tattoo/tattoo_people.cpp +++ b/engines/sherlock/tattoo/tattoo_people.cpp @@ -689,55 +689,59 @@ bool TattooPeople::loadWalk() { bool result = false; for (int idx = 0; idx < MAX_CHARACTERS; ++idx) { - if (!_data[idx]->_walkLoaded && (_data[idx]->_type == CHARACTER || _data[idx]->_type == HIDDEN_CHARACTER)) { - if (_data[idx]->_type == HIDDEN_CHARACTER) - _data[idx]->_type = INVALID; + Person &person = *_data[idx]; + + if (!person._walkLoaded && (person._type == CHARACTER || person._type == HIDDEN_CHARACTER)) { + if (person._type == HIDDEN_CHARACTER) + person._type = INVALID; // See if this is one of the more used Walk Graphics stored in WALK.LIB for (int libNum = 0; libNum < NUM_IN_WALK_LIB; ++libNum) { - if (!_data[idx]->_walkVGSName.compareToIgnoreCase(WALK_LIB_NAMES[libNum])) { + if (!person._walkVGSName.compareToIgnoreCase(WALK_LIB_NAMES[libNum])) { _useWalkLib = true; break; } } // Load the images for the character - _data[idx]->_images = new ImageFile(_data[idx]->_walkVGSName, false); - _data[idx]->_maxFrames = _data[idx]->_images->size(); + person._images = new ImageFile(person._walkVGSName, false); + person._maxFrames = person._images->size(); // Load walk sequence data - Common::String fname = Common::String(_data[idx]->_walkVGSName.c_str(), strchr(_data[idx]->_walkVGSName.c_str(), '.')); + Common::String fname = Common::String(person._walkVGSName.c_str(), strchr(person._walkVGSName.c_str(), '.')); fname += ".SEQ"; // Load the walk sequence data Common::SeekableReadStream *stream = res.load(fname, _useWalkLib ? "walk.lib" : "vgs.lib"); - _data[idx]->_walkSequences.resize(stream->readByte()); + person._walkSequences.resize(stream->readByte()); - for (uint seqNum = 0; seqNum < _data[idx]->_walkSequences.size(); ++seqNum) - _data[idx]->_walkSequences[seqNum].load(*stream); + for (uint seqNum = 0; seqNum < person._walkSequences.size(); ++seqNum) + person._walkSequences[seqNum].load(*stream); // Close the sequences resource delete stream; _useWalkLib = false; - _data[idx]->_frameNumber = 0; - _data[idx]->setImageFrame(); + person._sequences = &person._walkSequences[person._sequenceNumber]._sequences[0]; + person._seqSize = person._walkSequences[person._sequenceNumber]._sequences.size(); + person._frameNumber = 0; + person.setImageFrame(); // Set the stop Frames pointers for (int dirNum = 0; dirNum < 8; ++dirNum) { int count = 0; - while (_data[idx]->_walkSequences[dirNum + 8][count] != 0) + while (person._walkSequences[dirNum + 8][count] != 0) ++count; count += 2; - count = _data[idx]->_walkSequences[dirNum + 8][count] - 1; - _data[idx]->_stopFrames[dirNum] = &(*_data[idx]->_images)[count]; + count = person._walkSequences[dirNum + 8][count] - 1; + person._stopFrames[dirNum] = &(*person._images)[count]; } result = true; - _data[idx]->_walkLoaded = true; - } else if (_data[idx]->_type != CHARACTER) { - _data[idx]->_walkLoaded = false; + person._walkLoaded = true; + } else if (person._type != CHARACTER) { + person._walkLoaded = false; } } -- cgit v1.2.3 From b26bc296194c3a745fa9d222862ce1ad12a13e3e Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 14 Jun 2015 10:57:05 -0400 Subject: SHERLOCK: RT: Fix player animation when enterng scene --- engines/sherlock/tattoo/tattoo_people.cpp | 2 -- 1 file changed, 2 deletions(-) (limited to 'engines/sherlock/tattoo/tattoo_people.cpp') diff --git a/engines/sherlock/tattoo/tattoo_people.cpp b/engines/sherlock/tattoo/tattoo_people.cpp index 2bdf1164ab..a8c906a41a 100644 --- a/engines/sherlock/tattoo/tattoo_people.cpp +++ b/engines/sherlock/tattoo/tattoo_people.cpp @@ -461,8 +461,6 @@ TattooPeople::TattooPeople(SherlockEngine *vm) : People(vm) { _data.push_back(new TattooPerson()); } - - void TattooPeople::setListenSequence(int speaker, int sequenceNum) { Scene &scene = *_vm->_scene; -- cgit v1.2.3 From 275064ad23a46d5c034c75201249511e6026556d Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 14 Jun 2015 11:58:28 -0400 Subject: SHERLOCK: RT: Fix player movement whilst walking --- engines/sherlock/tattoo/tattoo_people.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'engines/sherlock/tattoo/tattoo_people.cpp') diff --git a/engines/sherlock/tattoo/tattoo_people.cpp b/engines/sherlock/tattoo/tattoo_people.cpp index a8c906a41a..3d472bc9d2 100644 --- a/engines/sherlock/tattoo/tattoo_people.cpp +++ b/engines/sherlock/tattoo/tattoo_people.cpp @@ -97,10 +97,12 @@ void TattooPerson::adjustSprite() { if (!_walkCount) { // If there are remaining points to walk, move to the next one - people._walkDest = _walkTo.pop(); - setWalking(); - } else { - gotoStand(); + if (!_walkTo.empty()) { + people._walkDest = _walkTo.pop(); + setWalking(); + } else { + gotoStand(); + } } } -- cgit v1.2.3 From 724fe7e4f68b796bd0e5b79cd28c873ba32cdff4 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 14 Jun 2015 12:10:26 -0400 Subject: SHERLOCK: Move _walkDest from People to Person --- engines/sherlock/tattoo/tattoo_people.cpp | 33 +++++++++++++++---------------- 1 file changed, 16 insertions(+), 17 deletions(-) (limited to 'engines/sherlock/tattoo/tattoo_people.cpp') diff --git a/engines/sherlock/tattoo/tattoo_people.cpp b/engines/sherlock/tattoo/tattoo_people.cpp index 3d472bc9d2..bb57ec93cf 100644 --- a/engines/sherlock/tattoo/tattoo_people.cpp +++ b/engines/sherlock/tattoo/tattoo_people.cpp @@ -83,11 +83,11 @@ void TattooPerson::adjustSprite() { _walkCount = _status; _status = 0; - people._walkDest = _walkTo.front(); + _walkDest = _walkTo.front(); setWalking(); } else if (_type == CHARACTER && _walkCount) { if (_walkCount > 10) { - people._walkDest = _walkTo.front(); + _walkDest = _walkTo.front(); setWalking(); } @@ -98,7 +98,7 @@ void TattooPerson::adjustSprite() { if (!_walkCount) { // If there are remaining points to walk, move to the next one if (!_walkTo.empty()) { - people._walkDest = _walkTo.pop(); + _walkDest = _walkTo.pop(); setWalking(); } else { gotoStand(); @@ -271,7 +271,6 @@ void TattooPerson::gotoStand() { } void TattooPerson::setWalking() { - People &people = *_vm->_people; TattooScene &scene = *(TattooScene *)_vm->_scene; int oldDirection, oldFrame; Common::Point delta; @@ -297,8 +296,8 @@ void TattooPerson::setWalking() { if (_centerWalk || !_walkTo.empty()) { // Since we want the player to be centered on the ultimate destination, and the player // is drawn from the left side, move the cursor half the width of the player to center it - delta = Common::Point(_position.x / FIXED_INT_MULTIPLIER - people._walkDest.x, - _position.y / FIXED_INT_MULTIPLIER - people._walkDest.y); + delta = Common::Point(_position.x / FIXED_INT_MULTIPLIER - _walkDest.x, + _position.y / FIXED_INT_MULTIPLIER - _walkDest.y); int dir; if (ABS(delta.x) > ABS(delta.y)) @@ -306,14 +305,14 @@ void TattooPerson::setWalking() { else dir = (delta.y < 0) ? WALK_UP : WALK_DOWN; - int scaleVal = scene.getScaleVal(Point32(people._walkDest.x * FIXED_INT_MULTIPLIER, - people._walkDest.y * FIXED_INT_MULTIPLIER)); - people._walkDest.x -= _stopFrames[dir]->sDrawXSize(scaleVal) / 2; + int scaleVal = scene.getScaleVal(Point32(_walkDest.x * FIXED_INT_MULTIPLIER, + _walkDest.y * FIXED_INT_MULTIPLIER)); + _walkDest.x -= _stopFrames[dir]->sDrawXSize(scaleVal) / 2; } delta = Common::Point( - ABS(_position.x / FIXED_INT_MULTIPLIER - people._walkDest.x), - ABS(_position.y / FIXED_INT_MULTIPLIER - people._walkDest.y) + ABS(_position.x / FIXED_INT_MULTIPLIER - _walkDest.x), + ABS(_position.y / FIXED_INT_MULTIPLIER - _walkDest.y) ); // If we're ready to move a sufficient distance, that's it. Otherwise, @@ -322,7 +321,7 @@ void TattooPerson::setWalking() { break; // Pop next walk segment off the walk route stack - people._walkDest = _walkTo.pop(); + _walkDest = _walkTo.pop(); } // If a sufficient move is being done, then start the move @@ -331,7 +330,7 @@ void TattooPerson::setWalking() { if (delta.x >= delta.y) { // Set the initial frame sequence for the left and right, as well // as setting the delta x depending on direction - if (people._walkDest.x < (_position.x / FIXED_INT_MULTIPLIER)) { + if (_walkDest.x < (_position.x / FIXED_INT_MULTIPLIER)) { _sequenceNumber = WALK_LEFT; _delta.x = speed.x * -(FIXED_INT_MULTIPLIER / 10); } else { @@ -344,7 +343,7 @@ void TattooPerson::setWalking() { if ((delta.x * 10) >= speed.x) { // Det the delta y _delta.y = (delta.y * FIXED_INT_MULTIPLIER) / ((delta.x * 10) / speed.x); - if (people._walkDest.y < (_position.y / FIXED_INT_MULTIPLIER)) + if (_walkDest.y < (_position.y / FIXED_INT_MULTIPLIER)) _delta.y = -_delta.y; // Set how many times we should add the delta to the player's position @@ -353,7 +352,7 @@ void TattooPerson::setWalking() { // 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 _delta = Point32(0, 0); - _position = Point32(people._walkDest.x * FIXED_INT_MULTIPLIER, people._walkDest.y * FIXED_INT_MULTIPLIER); + _position = Point32(_walkDest.x * FIXED_INT_MULTIPLIER, _walkDest.y * FIXED_INT_MULTIPLIER); _walkCount = 1; } @@ -392,7 +391,7 @@ void TattooPerson::setWalking() { } else { // Major movement is vertical, so set the sequence for up and down, // and set the delta Y depending on the direction - if (people._walkDest.y < (_position.y / FIXED_INT_MULTIPLIER)) { + if (_walkDest.y < (_position.y / FIXED_INT_MULTIPLIER)) { _sequenceNumber = WALK_UP; _delta.y = speed.y * -FIXED_INT_MULTIPLIER; } else { @@ -402,7 +401,7 @@ void TattooPerson::setWalking() { // Set the delta x _delta.x = (delta.x * FIXED_INT_MULTIPLIER) / (delta.y / speed.y); - if (people._walkDest.x < (_position.x / FIXED_INT_MULTIPLIER)) + if (_walkDest.x < (_position.x / FIXED_INT_MULTIPLIER)) _delta.x = -_delta.x; _walkCount = delta.y / speed.y; -- cgit v1.2.3 From bc0a839175899462bc4a79a6e4f3853ac5ee9aaf Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 14 Jun 2015 15:34:11 -0400 Subject: SHERLOCK: RT: Move more methods from Sprite to TattooPerson --- engines/sherlock/tattoo/tattoo_people.cpp | 136 +++++++++++++++++++++++++++++- 1 file changed, 133 insertions(+), 3 deletions(-) (limited to 'engines/sherlock/tattoo/tattoo_people.cpp') diff --git a/engines/sherlock/tattoo/tattoo_people.cpp b/engines/sherlock/tattoo/tattoo_people.cpp index bb57ec93cf..72abdc371d 100644 --- a/engines/sherlock/tattoo/tattoo_people.cpp +++ b/engines/sherlock/tattoo/tattoo_people.cpp @@ -30,6 +30,38 @@ namespace Sherlock { namespace Tattoo { #define FACING_PLAYER 16 +#define NUM_ADJUSTED_WALKS 21 + +struct AdjustWalk { + char _vgsName[9]; + int _xAdjust; + int _flipXAdjust; + int _yAdjust; +} ; + +static const AdjustWalk ADJUST_WALKS[NUM_ADJUSTED_WALKS] = { + { "TUPRIGHT", -7, -19, 6 }, + { "TRIGHT", 8, -14, 0 }, + { "TDOWNRG", 14, -12, 0 }, + { "TWUPRIGH", 12, 4, 2 }, + { "TWRIGHT", 31, -14, 0 }, + { "TWDOWNRG", 6, -24, 0 }, + { "HTUPRIGH", 2, -20, 0 }, + { "HTRIGHT", 28, -20, 0 }, + { "HTDOWNRG", 8, -2, 0 }, + { "GTUPRIGH", 4, -12, 0 }, + { "GTRIGHT", 12, -16, 0 }, + { "GTDOWNRG", 10, -18, 0 }, + { "JTUPRIGH", 8, -10, 0 }, + { "JTRIGHT", 22, -6, 0 }, + { "JTDOWNRG", 4, -20, 0 }, + { "CTUPRIGH", 10, 0, 0 }, + { "CTRIGHT", 26, -22, 0 }, + { "CTDOWNRI", 16, 4, 0 }, + { "ITUPRIGH", 0, 0, 0 }, + { "ITRIGHT", 20, 0, 0 }, + { "ITDOWNRG", 8, 0, 0 } +}; static const int WALK_SPEED_X[99] = { 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 98, 90, 90, 90, 90, 90, 91, 90, 90, @@ -71,6 +103,15 @@ TattooPerson::TattooPerson() : Person() { _npcPause = false; } +void TattooPerson::freeAltGraphics() { + if (_altImages != nullptr) { + delete _altImages; + _altImages = nullptr; + } + + _altSeq = 0; +} + void TattooPerson::adjustSprite() { People &people = *_vm->_people; TattooScene &scene = *(TattooScene *)_vm->_scene; @@ -455,6 +496,95 @@ Common::Point TattooPerson::getSourcePoint() const { _position.y / FIXED_INT_MULTIPLIER); } +void TattooPerson::setObjTalkSequence(int seq) { + assert(seq != -1 && _type == CHARACTER); + + if (_seqTo) { + // reset to previous value + _walkSequences[_sequenceNumber]._sequences[_frameNumber] = _seqTo; + _seqTo = 0; + } + + _sequenceNumber = _gotoSeq; + _frameNumber = 0; + checkWalkGraphics(); +} + +void TattooPerson::checkWalkGraphics() { + People &people = *_vm->_people; + + if (_images == nullptr) { + freeAltGraphics(); + return; + } + + Common::String filename = Common::String::format("%s.vgs", _walkSequences[_sequenceNumber]._vgsName.c_str()); + + // Set the adjust depending on if we have to fine tune the x position of this particular graphic + _adjust.x = _adjust.y = 0; + + for (int idx = 0; idx < NUM_ADJUSTED_WALKS; ++idx) { + if (!scumm_strnicmp(_walkSequences[_sequenceNumber]._vgsName.c_str(), ADJUST_WALKS[idx]._vgsName, + strlen(ADJUST_WALKS[idx]._vgsName))) { + if (_walkSequences[_sequenceNumber]._horizFlip) + _adjust.x = ADJUST_WALKS[idx]._flipXAdjust; + else + _adjust.x = ADJUST_WALKS[idx]._xAdjust; + + _adjust.y = ADJUST_WALKS[idx]._yAdjust; + break; + } + } + + // See if we're already using Alternate Graphics + if (_altSeq) { + // See if the VGS file called for is different than the alternate graphics already loaded + if (!_walkSequences[_sequenceNumber]._vgsName.compareToIgnoreCase(_walkSequences[_altSeq - 1]._vgsName)) { + // Different AltGraphics, Free the old ones + freeAltGraphics(); + } + } + + // If there is no Alternate Sequence set, see if we need to load a new one + if (!_altSeq) { + int npcNum = -1; + // Find which NPC this is so we can check the name of the graphics loaded + for (int idx = 0; idx < MAX_CHARACTERS; ++idx) { + if (this == &people[idx]) { + npcNum = idx; + break; + } + } + + if (npcNum != -1) { + // See if the VGS file called for is different than the main graphics which are already loaded + if (!filename.compareToIgnoreCase(people[npcNum]._walkVGSName)) { + // See if this is one of the more used Walk Graphics stored in WALK.LIB + for (int idx = 0; idx < NUM_IN_WALK_LIB; ++idx) { + if (!scumm_stricmp(filename.c_str(), WALK_LIB_NAMES[idx])) { + people._useWalkLib = true; + break; + } + } + + _altImages = new ImageFile(filename); + people._useWalkLib = false; + + _altSeq = _sequenceNumber + 1; + } + } + } + + // If this is a different seqeunce from the current sequence, reset the appropriate variables + if (_sequences != &_walkSequences[_sequenceNumber]._sequences[0]) { + _seqTo = _seqCounter = _seqCounter2 = _seqStack = _startSeq = 0; + _sequences = &_walkSequences[_sequenceNumber]._sequences[0]; + _seqSize = _walkSequences[_sequenceNumber]._sequences.size(); + } + + setImageFrame(); +} + /*----------------------------------------------------------------*/ TattooPeople::TattooPeople(SherlockEngine *vm) : People(vm) { @@ -479,7 +609,7 @@ void TattooPeople::setListenSequence(int speaker, int sequenceNum) { obj.setObjTalkSequence(sequenceNum); } else if (objNum != -1) { objNum -= 256; - Person &person = *_data[objNum]; + TattooPerson &person = (*this)[objNum]; int newDir = person._sequenceNumber; switch (person._sequenceNumber) { @@ -546,7 +676,7 @@ void TattooPeople::setListenSequence(int speaker, int sequenceNum) { } void TattooPeople::setTalkSequence(int speaker, int sequenceNum) { - People &people = *_vm->_people; + TattooPeople &people = *(TattooPeople *)_vm->_people; Scene &scene = *_vm->_scene; TattooTalk &talk = *(TattooTalk *)_vm->_talk; @@ -569,7 +699,7 @@ void TattooPeople::setTalkSequence(int speaker, int sequenceNum) { } else if (objNum != -1) { objNum -= 256; - Person &person = people[objNum]; + TattooPerson &person = people[objNum]; int newDir = person._sequenceNumber; switch (newDir) { -- cgit v1.2.3 From 6ab3857597980e9f525354557d247b1dbb2c144a Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 14 Jun 2015 15:53:03 -0400 Subject: SHERLOCK: RT: Fix loading of _altImages when necessary --- engines/sherlock/tattoo/tattoo_people.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'engines/sherlock/tattoo/tattoo_people.cpp') diff --git a/engines/sherlock/tattoo/tattoo_people.cpp b/engines/sherlock/tattoo/tattoo_people.cpp index 72abdc371d..80f2484c6b 100644 --- a/engines/sherlock/tattoo/tattoo_people.cpp +++ b/engines/sherlock/tattoo/tattoo_people.cpp @@ -558,7 +558,7 @@ void TattooPerson::checkWalkGraphics() { if (npcNum != -1) { // See if the VGS file called for is different than the main graphics which are already loaded - if (!filename.compareToIgnoreCase(people[npcNum]._walkVGSName)) { + if (filename.compareToIgnoreCase(people[npcNum]._walkVGSName) != 0) { // See if this is one of the more used Walk Graphics stored in WALK.LIB for (int idx = 0; idx < NUM_IN_WALK_LIB; ++idx) { if (!scumm_stricmp(filename.c_str(), WALK_LIB_NAMES[idx])) { -- cgit v1.2.3 From 8429adcb5109fb7334cb96560abe051b72b28044 Mon Sep 17 00:00:00 2001 From: Torbjörn Andersson Date: Sun, 14 Jun 2015 22:59:50 +0200 Subject: SHERLOCK: Silence two other GCC warnings --- engines/sherlock/tattoo/tattoo_people.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'engines/sherlock/tattoo/tattoo_people.cpp') diff --git a/engines/sherlock/tattoo/tattoo_people.cpp b/engines/sherlock/tattoo/tattoo_people.cpp index 80f2484c6b..30a87ce7e0 100644 --- a/engines/sherlock/tattoo/tattoo_people.cpp +++ b/engines/sherlock/tattoo/tattoo_people.cpp @@ -346,7 +346,7 @@ void TattooPerson::setWalking() { else dir = (delta.y < 0) ? WALK_UP : WALK_DOWN; - int scaleVal = scene.getScaleVal(Point32(_walkDest.x * FIXED_INT_MULTIPLIER, + scaleVal = scene.getScaleVal(Point32(_walkDest.x * FIXED_INT_MULTIPLIER, _walkDest.y * FIXED_INT_MULTIPLIER)); _walkDest.x -= _stopFrames[dir]->sDrawXSize(scaleVal) / 2; } -- cgit v1.2.3 From 142812e843f9ecb8fbe76b3d32e89b5a17674511 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 14 Jun 2015 21:37:39 -0400 Subject: SHERLOCK: RT: Fix walking with segments more than 10 steps long --- engines/sherlock/tattoo/tattoo_people.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'engines/sherlock/tattoo/tattoo_people.cpp') diff --git a/engines/sherlock/tattoo/tattoo_people.cpp b/engines/sherlock/tattoo/tattoo_people.cpp index 30a87ce7e0..b582b86dbc 100644 --- a/engines/sherlock/tattoo/tattoo_people.cpp +++ b/engines/sherlock/tattoo/tattoo_people.cpp @@ -128,7 +128,7 @@ void TattooPerson::adjustSprite() { setWalking(); } else if (_type == CHARACTER && _walkCount) { if (_walkCount > 10) { - _walkDest = _walkTo.front(); + _walkDest = _nextDest; setWalking(); } @@ -315,6 +315,7 @@ void TattooPerson::setWalking() { TattooScene &scene = *(TattooScene *)_vm->_scene; int oldDirection, oldFrame; Common::Point delta; + _nextDest = _walkDest; // Flag that player has now walked in the scene scene._walkedInScene = true; -- cgit v1.2.3 From 8abce6b025b1b4d8f50605875967f234b4b58312 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Wed, 17 Jun 2015 20:45:37 -0400 Subject: SHERLOCK: RT: Implement walkToCoords --- engines/sherlock/tattoo/tattoo_people.cpp | 99 ++++++++++++++++++++++++++++++- 1 file changed, 97 insertions(+), 2 deletions(-) (limited to 'engines/sherlock/tattoo/tattoo_people.cpp') diff --git a/engines/sherlock/tattoo/tattoo_people.cpp b/engines/sherlock/tattoo/tattoo_people.cpp index b582b86dbc..cde17fee60 100644 --- a/engines/sherlock/tattoo/tattoo_people.cpp +++ b/engines/sherlock/tattoo/tattoo_people.cpp @@ -23,7 +23,7 @@ #include "sherlock/tattoo/tattoo_people.h" #include "sherlock/tattoo/tattoo_scene.h" #include "sherlock/tattoo/tattoo_talk.h" -#include "sherlock/sherlock.h" +#include "sherlock/tattoo/tattoo.h" namespace Sherlock { @@ -99,7 +99,7 @@ TattooPerson::TattooPerson() : Person() { _resetNPCPath = true; _savedNpcSequence = 0; _savedNpcFrame = 0; - _updateNPCPath = false; + _updateNPCPath = true; _npcPause = false; } @@ -475,6 +475,101 @@ void TattooPerson::setWalking() { _frameNumber = oldFrame; } +void TattooPerson::walkToCoords(const Point32 &destPos, int destDir) { + TattooEngine &vm = *(TattooEngine *)_vm; + Events &events = *_vm->_events; + TattooPeople &people = *(TattooPeople *)_vm->_people; + TattooScene &scene = *(TattooScene *)_vm->_scene; + Talk &talk = *_vm->_talk; + + CursorId oldCursor = events.getCursor(); + events.setCursor(WAIT); + + _walkDest = Common::Point(_position.x / FIXED_INT_MULTIPLIER, _position.y / FIXED_INT_MULTIPLIER); + + bool isHolmes = this == &people[HOLMES]; + if (isHolmes) { + people._allowWalkAbort = true; + } else { + // Clear the path Variables + _npcIndex = _npcPause; + Common::fill(_npcPath, _npcPath + 100, 0); + _npcFacing = destDir; + } + + _centerWalk = false; + + // Only move the person if they're going an appreciable distance + if (ABS(_walkDest.x - (_position.x / FIXED_INT_MULTIPLIER)) > 8 || + ABS(_walkDest.y - (_position.y / FIXED_INT_MULTIPLIER)) > 4) { + goAllTheWay(); + + do { + // Keep doing animations whilst walk is in progress + events.wait(1); + scene.doBgAnim(); + + if (events.kbHit()) { + Common::KeyState keyState = events.getKey(); + + if (keyState.keycode == Common::KEYCODE_ESCAPE && vm._runningProlog) { + vm.setFlags(-76); + vm.setFlags(396); + scene._goToScene = 1; + talk._talkToAbort = true; + } + } + } while (!_vm->shouldQuit() && _walkCount && !talk._talkToAbort); + } + + _centerWalk = true; + if (!isHolmes) + _updateNPCPath = true; + + if (!talk._talkToAbort) { + // put character exactly on right spot + _position = destPos; + + if (_sequenceNumber != destDir) { + // Facing character to correct ending direction + _sequenceNumber = destDir; + gotoStand(); + } + + if (!isHolmes) + _updateNPCPath = false; + + // Secondary walking wait loop + do { + events.wait(1); + scene.doBgAnim(); + + // See if we're past the initial goto stand sequence + for (int idx = 0; idx < _frameNumber; ++idx) { + if (_walkSequences[_sequenceNumber][idx] == 0) + break; + } + + if (events.kbHit()) { + Common::KeyState keyState = events.getKey(); + + if (keyState.keycode == Common::KEYCODE_ESCAPE && vm._runningProlog) { + vm.setFlags(-76); + vm.setFlags(396); + scene._goToScene = 1; + talk._talkToAbort = true; + } + } + } while (!_vm->shouldQuit()); + + if (!isHolmes) + _updateNPCPath = true; + + if (!talk._talkToAbort) + events.setCursor(oldCursor); + } +} + void TattooPerson::clearNPC() { Common::fill(&_npcPath[0], &_npcPath[MAX_NPC_PATH], 0); _npcIndex = _npcStack = 0; -- cgit v1.2.3 From 65b794a7505aeb5ab1667e8fd9ac5de687478757 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Wed, 17 Jun 2015 21:41:05 -0400 Subject: SHERLOCK: RT: Implement updateNPC --- engines/sherlock/tattoo/tattoo_people.cpp | 219 +++++++++++++++++++++++++++++- 1 file changed, 217 insertions(+), 2 deletions(-) (limited to 'engines/sherlock/tattoo/tattoo_people.cpp') diff --git a/engines/sherlock/tattoo/tattoo_people.cpp b/engines/sherlock/tattoo/tattoo_people.cpp index cde17fee60..6c1e064916 100644 --- a/engines/sherlock/tattoo/tattoo_people.cpp +++ b/engines/sherlock/tattoo/tattoo_people.cpp @@ -100,7 +100,8 @@ TattooPerson::TattooPerson() : Person() { _savedNpcSequence = 0; _savedNpcFrame = 0; _updateNPCPath = true; - _npcPause = false; + _npcPause = 0; + _lookHolmes = false; } void TattooPerson::freeAltGraphics() { @@ -577,7 +578,221 @@ void TattooPerson::clearNPC() { } void TattooPerson::updateNPC() { - warning("TODO: updateNPC"); + People &people = *_vm->_people; + Talk &talk = *_vm->_talk; + + // If the NPC isn't on, or it's in Talk or Listen Mode, then return without doing anything + if (_type != CHARACTER || _sequenceNumber >= TALK_UPRIGHT) + return; + + // If the NPC is paused, just decrement his pause counter and exit + if (_npcPause) { + // Decrement counter + --_npcPause; + + // Now see if we need to update the NPC's frame sequence so that he faces Holmes + if (_lookHolmes) { + // See where Holmes is with respect to the NPC (x coordinate) + _npcFacing = (people[HOLMES]._position.x < _position.x) ? STOP_LEFT : STOP_RIGHT; + + // See where Holmes is with respect to the NPC (y coordinate) + if (people[HOLMES]._position.y < (_position.y - 10 * FIXED_INT_MULTIPLIER)) { + // Holmes is above the NPC so reset the facing to a diagonal up + _npcFacing = (_npcFacing == STOP_RIGHT) ? STOP_UPRIGHT : STOP_UPLEFT; + } else if (people[HOLMES]._position.y > (_position.y + 10 * FIXED_INT_MULTIPLIER)) { + // Holmes is below the NPC so reset the facing to a diagonal down + _npcFacing = (_npcFacing == STOP_RIGHT) ? STOP_DOWNRIGHT : STOP_DOWNLEFT; + } + + // See if we need to set the old_walk_sequence so the NPC will put his arms + // up if he turns another way + if (_sequenceNumber != _npcFacing) + _oldWalkSequence = _sequenceNumber; + + gotoStand(); + } + } else { + // Reset the look flag so the NPC won't face Holmes anymore + _lookHolmes = false; + + // See if the NPC is stopped or not. Don't do anything if he's moving + if (!_walkCount) { + // If there is no new command, reset the path back to the beginning + if (!_npcPath[_npcIndex]) + _npcIndex = 0; + + // The NPC is stopped and any pause he was doing is done. We can now see what + // the next command in the NPC path is. + + // Scan Past any NPC Path Labels since they do nothing except mark places for If's and Goto's + while (_npcPath[_npcIndex] == NPCPATH_PATH_LABEL) + _npcIndex += 2; + + if (_npcPath[_npcIndex]) { + _npcFacing = -1; + + switch (_npcPath[_npcIndex]) { + case NPCPATH_SET_DEST: { + // Set the NPC's new destination + int xp = (_npcPath[_npcIndex + 1] - 1) * 256 + _npcPath[_npcIndex + 2] - 1; + if (xp > 16384) + xp = -1 * (xp - 16384); + _walkDest.x = xp; + _walkDest.y = (_npcPath[_npcIndex + 3] - 1) * 256 + _npcPath[_npcIndex + 4] - 1; + _npcFacing = _npcPath[_npcIndex + 5] - 1; + + goAllTheWay(); + _npcIndex += 6; + break; + } + + case NPCPATH_PAUSE: + // Set the NPC to pause where he is + _npcPause = (_npcPath[_npcIndex + 1] - 1) * 256 + _npcPath[_npcIndex + 2] - 1; + _npcIndex += 3; + break; + + case NPCPATH_SET_TALK_FILE: { + // Set the NPC's Talk File to use if Holmes talks to them + ++_npcIndex; + + _npcName = ""; + for (int idx = 0; idx < 8; ++idx) { + if (_npcPath[_npcIndex + idx] != '~') + _npcName += _npcPath[_npcIndex + idx]; + else + break; + } + + _npcIndex += 8; + break; + } + + case NPCPATH_CALL_TALK_FILE: { + // Call a Talk File + ++_npcIndex; + + Common::String name; + for (int idx = 0; idx < 8; ++idx) { + if (_npcPath[_npcIndex + idx] != '~') + name += _npcPath[_npcIndex + idx]; + else + break; + } + + _npcIndex += 8; + talk.talkTo(name); + break; + } + + case NPCPATH_TAKE_NOTES: + // Set the NPC to Pause where he is and set his frame sequences + // so he takes notes while he's paused + _npcPause = (_npcPath[_npcIndex + 1] - 1) * 256 + _npcPath[_npcIndex + 2] - 1; + _npcIndex += 3; + break; + + case NPCPATH_FACE_HOLMES: + // Set the NPC to Pause where he is and set his look flag so he will always face Holmes + // while he is paused + _npcPause = (_npcPath[_npcIndex + 1] - 1) * 256 + _npcPath[_npcIndex + 2] - 1; + _lookHolmes = true; + _npcIndex += 3; + break; + + //case NPCPATH_PATH_LABEL: // No implementation needed here + + case NPCPATH_GOTO_LABEL: { + // Goto NPC Path Label + int label = _npcPath[_npcIndex + 1]; + _npcIndex = 0; + + // Scan through NPC path data to find the label + bool found = false; + while (!found) { + switch (_npcPath[_npcIndex]) { + case NPCPATH_SET_DEST: + _npcIndex += 6; + break; + case NPCPATH_PAUSE: + case NPCPATH_TAKE_NOTES: + case NPCPATH_FACE_HOLMES: + _npcIndex += 3; + break; + case NPCPATH_SET_TALK_FILE: + case NPCPATH_CALL_TALK_FILE: + _npcIndex += 8; + break; + case NPCPATH_PATH_LABEL: + if (_npcPath[_npcIndex + 1] == label) + found = true; + _npcIndex += 2; + break; + case NPCPATH_GOTO_LABEL: + _npcIndex += 2; + break; + case NPCPATH_IFFLAG_GOTO_LABEL: + _npcIndex += 4; + break; + } + } + break; + } + + case NPCPATH_IFFLAG_GOTO_LABEL: { + // If FLAG then Goto Label + int flag = (_npcPath[_npcIndex + 1] - 1) * 256 + _npcPath[_npcIndex + 2] - 1 - (_npcPath[_npcIndex + 2] == 1 ? 1 : 0); + + // Set the value the flag should be for the if statement to succeed + bool flagVal = flag < 16384; + + int label = _npcPath[_npcIndex + 3]; + _npcIndex += 4; + + // If the flag is set Correctly, move the NPC Index to the given label + if (_vm->readFlags(flag & 16383) == flagVal) { + _npcIndex = 0; + bool found = false; + while (!found) + { + switch (_npcPath[_npcIndex]) + { + case NPCPATH_SET_DEST: + _npcIndex += 6; + break; + case NPCPATH_PAUSE: + case NPCPATH_TAKE_NOTES: + case NPCPATH_FACE_HOLMES: + _npcIndex += 3; + break; + case NPCPATH_SET_TALK_FILE: + case NPCPATH_CALL_TALK_FILE: + _npcIndex += 8; + break; + case NPCPATH_PATH_LABEL: + if (_npcPath[_npcIndex + 1] == label) + found = true; + _npcIndex += 2; + break; + case NPCPATH_GOTO_LABEL: + _npcIndex += 2; + break; + case NPCPATH_IFFLAG_GOTO_LABEL: + _npcIndex += 4; + break; + } + } + } + + break; + } + + default: + break; + } + } + } + } } void TattooPerson::pushNPCPath() { -- cgit v1.2.3 From 94d7928dbc7ea1d2de0e82f69a3b5d255f2319fd Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Wed, 17 Jun 2015 22:04:52 -0400 Subject: SHERLOCK: RT: Implemented pullNPCPath --- engines/sherlock/tattoo/tattoo_people.cpp | 56 +++++++++++++++++++++++++++++-- 1 file changed, 53 insertions(+), 3 deletions(-) (limited to 'engines/sherlock/tattoo/tattoo_people.cpp') diff --git a/engines/sherlock/tattoo/tattoo_people.cpp b/engines/sherlock/tattoo/tattoo_people.cpp index 6c1e064916..3895f43831 100644 --- a/engines/sherlock/tattoo/tattoo_people.cpp +++ b/engines/sherlock/tattoo/tattoo_people.cpp @@ -89,11 +89,26 @@ static const int WALK_SPEED_DIAG_X[99] = { /*----------------------------------------------------------------*/ +SavedNPCPath::SavedNPCPath() { + Common::fill(&_path[0], &_path[MAX_NPC_PATH], 0); + _npcIndex = 0; + _npcPause = 0; + _npcFacing = 0; + _lookHolmes = false; +} + +SavedNPCPath::SavedNPCPath(byte path[MAX_NPC_PATH], int npcIndex, int npcPause, const Common::Point &walkDest, + int npcFacing, bool lookHolmes) : _npcIndex(npcIndex), _npcPause(npcPause), _walkDest(walkDest), + _npcFacing(npcFacing), _lookHolmes(lookHolmes) { + Common::copy(&path[0], &path[MAX_NPC_PATH], &_path[0]); +} + +/*----------------------------------------------------------------*/ + TattooPerson::TattooPerson() : Person() { Common::fill(&_npcPath[0], &_npcPath[MAX_NPC_PATH], 0); _tempX = _tempScaleVal = 0; _npcIndex = 0; - _npcStack = 0; _npcMoved = false; _npcFacing = -1; _resetNPCPath = true; @@ -573,7 +588,8 @@ void TattooPerson::walkToCoords(const Point32 &destPos, int destDir) { void TattooPerson::clearNPC() { Common::fill(&_npcPath[0], &_npcPath[MAX_NPC_PATH], 0); - _npcIndex = _npcStack = 0; + _npcIndex = 0; + _pathStack.clear(); _npcName = ""; } @@ -796,7 +812,41 @@ void TattooPerson::updateNPC() { } void TattooPerson::pushNPCPath() { - warning("TODO: pushNPCPath"); + assert(_pathStack.size() < 2); + SavedNPCPath savedPath(_npcPath, _npcIndex, _npcPause, _position, _sequenceNumber, _lookHolmes); + _pathStack.push(savedPath); +} + +void TattooPerson::pullNPCPath() { + // Pop the stack entry and restore the fields + SavedNPCPath path = _pathStack.pop(); + Common::copy(&path._path[0], &path._path[MAX_NPC_PATH], &_npcPath[0]); + _npcIndex = path._npcIndex; + _npcPause = path._npcPause; + + // Handle the first case if the NPC was paused + if (_npcPause) { + _walkDest = Common::Point(path._walkDest.x / FIXED_INT_MULTIPLIER, path._walkDest.y / FIXED_INT_MULTIPLIER); + _npcFacing = path._npcFacing; + _lookHolmes = path._lookHolmes; + + // See if the NPC was moved + if (_walkDest.x != (_position.x / FIXED_INT_MULTIPLIER) || + _walkDest.y != (_position.y / FIXED_INT_MULTIPLIER)) { + goAllTheWay(); + _npcPause = 0; + _npcIndex -= 3; + } else { + // See if we need to set the old walk sequence so the NPC will put his arms up if he turns another way + if (_npcFacing != _sequenceNumber) + _oldWalkSequence = _sequenceNumber; + + gotoStand(); + } + } else { + // Handle the second case if the NPC was in motion + _npcIndex -= 6; + } } Common::Point TattooPerson::getSourcePoint() const { -- cgit v1.2.3 From f6c710e5b33b72723c4983bc498a4127497d772e Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Thu, 18 Jun 2015 08:29:57 -0400 Subject: SHERLOCK: RT: Create pullNPCPaths to call each NPC's pullNPCPath method --- engines/sherlock/tattoo/tattoo_people.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'engines/sherlock/tattoo/tattoo_people.cpp') diff --git a/engines/sherlock/tattoo/tattoo_people.cpp b/engines/sherlock/tattoo/tattoo_people.cpp index 3895f43831..217064fb4a 100644 --- a/engines/sherlock/tattoo/tattoo_people.cpp +++ b/engines/sherlock/tattoo/tattoo_people.cpp @@ -1239,6 +1239,17 @@ bool TattooPeople::loadWalk() { return result; } + +void TattooPeople::pullNPCPaths() { + for (int idx = 1; idx < MAX_CHARACTERS; ++idx) { + TattooPerson &p = (*this)[idx]; + if (p._npcMoved) { + while (!p._pathStack.empty()) + p.pullNPCPath(); + } + } +} + } // End of namespace Tattoo } // End of namespace Sherlock -- cgit v1.2.3 From ae885686a562d551ed83e5c45af06f3b92f0500f Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sat, 27 Jun 2015 22:17:49 -0400 Subject: SHERLOCK: RT: Fix walking with a very close dest --- engines/sherlock/tattoo/tattoo_people.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'engines/sherlock/tattoo/tattoo_people.cpp') diff --git a/engines/sherlock/tattoo/tattoo_people.cpp b/engines/sherlock/tattoo/tattoo_people.cpp index 217064fb4a..b4c96fe22a 100644 --- a/engines/sherlock/tattoo/tattoo_people.cpp +++ b/engines/sherlock/tattoo/tattoo_people.cpp @@ -556,14 +556,17 @@ void TattooPerson::walkToCoords(const Point32 &destPos, int destDir) { _updateNPCPath = false; // Secondary walking wait loop - do { + bool done = false; + while (!done && !_vm->shouldQuit()) { events.wait(1); scene.doBgAnim(); // See if we're past the initial goto stand sequence for (int idx = 0; idx < _frameNumber; ++idx) { - if (_walkSequences[_sequenceNumber][idx] == 0) + if (_walkSequences[_sequenceNumber][idx] == 0) { + done = true; break; + } } if (events.kbHit()) { @@ -576,7 +579,7 @@ void TattooPerson::walkToCoords(const Point32 &destPos, int destDir) { talk._talkToAbort = true; } } - } while (!_vm->shouldQuit()); + } if (!isHolmes) _updateNPCPath = true; -- cgit v1.2.3 From 704dd8140b28668feeb3849c7c13044d8eb122ed Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Wed, 1 Jul 2015 19:18:26 -0400 Subject: SHERLOCK: RT: Fix missing code in setWalking --- engines/sherlock/tattoo/tattoo_people.cpp | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) (limited to 'engines/sherlock/tattoo/tattoo_people.cpp') diff --git a/engines/sherlock/tattoo/tattoo_people.cpp b/engines/sherlock/tattoo/tattoo_people.cpp index b4c96fe22a..42a7d26a7d 100644 --- a/engines/sherlock/tattoo/tattoo_people.cpp +++ b/engines/sherlock/tattoo/tattoo_people.cpp @@ -420,6 +420,8 @@ void TattooPerson::setWalking() { if (_sequenceNumber == WALK_LEFT || _sequenceNumber == WALK_RIGHT) { _delta.x = _delta.x / speed.x * diagSpeed.x; _delta.y = (delta.y * FIXED_INT_MULTIPLIER) / (delta.x * 10 / diagSpeed.x); + + _walkCount = delta.x * 10 / diagSpeed.x; } switch (_sequenceNumber) { @@ -434,6 +436,7 @@ void TattooPerson::setWalking() { if (_sequenceNumber == WALK_LEFT || _sequenceNumber == WALK_RIGHT) { _delta.x = _delta.x / speed.x * diagSpeed.x; _delta.y = -1 * (delta.y * FIXED_INT_MULTIPLIER) / (delta.x * 10 / diagSpeed.x); + _walkCount = (delta.x * 10) / diagSpeed.x; } @@ -453,16 +456,25 @@ void TattooPerson::setWalking() { _sequenceNumber = WALK_UP; _delta.y = speed.y * -FIXED_INT_MULTIPLIER; } else { + speed.y = diagSpeed.y; _sequenceNumber = WALK_DOWN; _delta.y = speed.y * FIXED_INT_MULTIPLIER; } // Set the delta x - _delta.x = (delta.x * FIXED_INT_MULTIPLIER) / (delta.y / speed.y); - if (_walkDest.x < (_position.x / FIXED_INT_MULTIPLIER)) + if (delta.y * 10 / speed.y) + _delta.x = (delta.x * FIXED_INT_MULTIPLIER) / (delta.y * 10 / speed.y); + else + _delta.x = (delta.x * FIXED_INT_MULTIPLIER) / delta.y; + + if (_walkDest.x < _position.y / FIXED_INT_MULTIPLIER) _delta.x = -_delta.x; - _walkCount = delta.y / speed.y; + // Set how many times we should add the delta's to the players position + if (delta.y * 10 / speed.y) + _walkCount = delta.y * 10 / speed.y; + else + _walkCount = delta.y; } } @@ -501,7 +513,7 @@ void TattooPerson::walkToCoords(const Point32 &destPos, int destDir) { CursorId oldCursor = events.getCursor(); events.setCursor(WAIT); - _walkDest = Common::Point(_position.x / FIXED_INT_MULTIPLIER, _position.y / FIXED_INT_MULTIPLIER); + _walkDest = Common::Point(destPos.x / FIXED_INT_MULTIPLIER, destPos.y / FIXED_INT_MULTIPLIER); bool isHolmes = this == &people[HOLMES]; if (isHolmes) { -- cgit v1.2.3 From 10e3e4811cb930dcfc5a5e6422b07b7a6f24ef67 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Thu, 2 Jul 2015 19:21:10 -0400 Subject: SHERLOCK: RT: Fix moving too far vertically when walking --- engines/sherlock/tattoo/tattoo_people.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'engines/sherlock/tattoo/tattoo_people.cpp') diff --git a/engines/sherlock/tattoo/tattoo_people.cpp b/engines/sherlock/tattoo/tattoo_people.cpp index 42a7d26a7d..f22ce87574 100644 --- a/engines/sherlock/tattoo/tattoo_people.cpp +++ b/engines/sherlock/tattoo/tattoo_people.cpp @@ -454,11 +454,11 @@ void TattooPerson::setWalking() { // and set the delta Y depending on the direction if (_walkDest.y < (_position.y / FIXED_INT_MULTIPLIER)) { _sequenceNumber = WALK_UP; - _delta.y = speed.y * -FIXED_INT_MULTIPLIER; + _delta.y = speed.y * -(FIXED_INT_MULTIPLIER / 10); } else { speed.y = diagSpeed.y; _sequenceNumber = WALK_DOWN; - _delta.y = speed.y * FIXED_INT_MULTIPLIER; + _delta.y = speed.y * (FIXED_INT_MULTIPLIER / 10); } // Set the delta x -- cgit v1.2.3 From 480003f48d0cb8fd0fa40cb8a3ebab8dc8597f8a Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Thu, 2 Jul 2015 20:53:40 -0400 Subject: SHERLOCK: RT: Cleanup of Exit class and fix exiting scenes --- engines/sherlock/tattoo/tattoo_people.cpp | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) (limited to 'engines/sherlock/tattoo/tattoo_people.cpp') diff --git a/engines/sherlock/tattoo/tattoo_people.cpp b/engines/sherlock/tattoo/tattoo_people.cpp index f22ce87574..23366f17db 100644 --- a/engines/sherlock/tattoo/tattoo_people.cpp +++ b/engines/sherlock/tattoo/tattoo_people.cpp @@ -23,6 +23,7 @@ #include "sherlock/tattoo/tattoo_people.h" #include "sherlock/tattoo/tattoo_scene.h" #include "sherlock/tattoo/tattoo_talk.h" +#include "sherlock/tattoo/tattoo_user_interface.h" #include "sherlock/tattoo/tattoo.h" namespace Sherlock { @@ -131,6 +132,7 @@ void TattooPerson::freeAltGraphics() { void TattooPerson::adjustSprite() { People &people = *_vm->_people; TattooScene &scene = *(TattooScene *)_vm->_scene; + TattooUserInterface &ui = *(TattooUserInterface *)_vm->_ui; if (_type == INVALID) return; @@ -192,13 +194,17 @@ 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 && + if (!_walkCount && ui._exitZone != -1 && scene._walkedInScene && scene._goToScene == -1 && !_description.compareToIgnoreCase(people[HOLMES]._description)) { - people._hSavedPos = scene._exits[scene._exitZone]._newPosition; - people._hSavedFacing = scene._exits[scene._exitZone]._newFacing; + Exit &exit = scene._exits[ui._exitZone]; + scene._goToScene = exit._scene; - if (people._hSavedFacing > 100 && people._hSavedPos.x < 1) - people._hSavedPos.x = 100; + if (exit._newPosition.x != 0) { + people._savedPos = exit._newPosition; + + if (people._savedPos._facing > 100 && people._savedPos.x < 1) + people._savedPos.x = 100; + } } } @@ -1184,8 +1190,9 @@ void TattooPeople::synchronize(Serializer &s) { s.syncAsSint16LE(_holmesQuotient); if (s.isLoading()) { - _hSavedPos = _data[HOLMES]->_position; - _hSavedFacing = _data[HOLMES]->_sequenceNumber; + _savedPos.x = _data[HOLMES]->_position.x; + _savedPos.y = _data[HOLMES]->_position.y; + _savedPos._facing = _data[HOLMES]->_sequenceNumber; } } -- cgit v1.2.3 From 39544c1728524f3ebc729c8d90ca0f191078d3a4 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sat, 4 Jul 2015 10:39:03 -0400 Subject: SHERLOCK: RT: Additional constants for flags and characters --- engines/sherlock/tattoo/tattoo_people.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'engines/sherlock/tattoo/tattoo_people.cpp') diff --git a/engines/sherlock/tattoo/tattoo_people.cpp b/engines/sherlock/tattoo/tattoo_people.cpp index 23366f17db..5956d98144 100644 --- a/engines/sherlock/tattoo/tattoo_people.cpp +++ b/engines/sherlock/tattoo/tattoo_people.cpp @@ -1153,9 +1153,9 @@ int TattooPeople::findSpeaker(int speaker) { // Fallback that Rose Tattoo uses if no speaker was found if (result == -1) { - bool flag = _vm->readFlags(76); + bool flag = _vm->readFlags(FLAG_PLAYER_IS_HOLMES); - if (_data[HOLMES]->_type == CHARACTER && ((speaker == 0 && flag) || (speaker == 1 && !flag))) + if (_data[HOLMES]->_type == CHARACTER && ((speaker == HOLMES && flag) || (speaker == WATSON && !flag))) return -1; for (uint idx = 1; idx < _data.size(); ++idx) { -- cgit v1.2.3 From 8570f052a39eb6ba4efe3764eb152076fbcd2f76 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 5 Jul 2015 19:16:54 -0400 Subject: SHERLOCK: RT: Cleanup and fleshing out of saving --- engines/sherlock/tattoo/tattoo_people.cpp | 61 ++++++++++++++++++++++++++----- 1 file changed, 51 insertions(+), 10 deletions(-) (limited to 'engines/sherlock/tattoo/tattoo_people.cpp') diff --git a/engines/sherlock/tattoo/tattoo_people.cpp b/engines/sherlock/tattoo/tattoo_people.cpp index 5956d98144..a7d7d2426c 100644 --- a/engines/sherlock/tattoo/tattoo_people.cpp +++ b/engines/sherlock/tattoo/tattoo_people.cpp @@ -967,6 +967,55 @@ void TattooPerson::checkWalkGraphics() { setImageFrame(); } +void TattooPerson::synchronize(Serializer &s) { + s.syncAsSint32LE(_position.x); + s.syncAsSint32LE(_position.y); + s.syncAsSint16LE(_sequenceNumber); + s.syncAsSint16LE(_type); + s.syncString(_walkVGSName); + s.syncString(_description); + s.syncString(_examine); + + // NPC specific properties + s.syncBytes(&_npcPath[0], MAX_NPC_PATH); + s.syncString(_npcName); + s.syncAsSint32LE(_npcPause); + s.syncAsByte(_lookHolmes); + s.syncAsByte(_updateNPCPath); + + // Walk to list + uint count = _walkTo.size(); + s.syncAsUint16LE(count); + if (s.isLoading()) { + // Load path + for (uint idx = 0; idx < count; ++count) { + int xp = 0, yp = 0; + s.syncAsSint16LE(xp); + s.syncAsSint16LE(yp); + _walkTo.push(Common::Point(xp, yp)); + } + } else { + // Save path + Common::Array path; + + // Save the points of the path + for (uint idx = 0; idx < count; ++idx) { + Common::Point pt = _walkTo.pop(); + s.syncAsSint16LE(pt.x); + s.syncAsSint16LE(pt.y); + path.push_back(pt); + } + + // Re-add the pending points back to the _walkTo queue + for (uint idx = 0; idx < count; ++idx) + _walkTo.push(path[idx]); + } + + // Verbs + for (int idx = 0; idx < 2; ++idx) + _use[idx].synchronize(s); +} + /*----------------------------------------------------------------*/ TattooPeople::TattooPeople(SherlockEngine *vm) : People(vm) { @@ -1176,16 +1225,8 @@ int TattooPeople::findSpeaker(int speaker) { void TattooPeople::synchronize(Serializer &s) { s.syncAsByte(_holmesOn); - for (uint idx = 0; idx < _data.size(); ++idx) { - Person &p = *_data[idx]; - s.syncAsSint32LE(p._position.x); - s.syncAsSint32LE(p._position.y); - s.syncAsSint16LE(p._sequenceNumber); - s.syncAsSint16LE(p._type); - s.syncString(p._walkVGSName); - s.syncString(p._description); - s.syncString(p._examine); - } + for (uint idx = 0; idx < _data.size(); ++idx) + (*this)[idx].synchronize(s); s.syncAsSint16LE(_holmesQuotient); -- cgit v1.2.3 From ada51dbdfb3111f309732e17abcbcc4fd1034fdc Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Mon, 6 Jul 2015 20:26:37 -0400 Subject: SHERLOCK: RT: Fix characters walking off-screen --- engines/sherlock/tattoo/tattoo_people.cpp | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) (limited to 'engines/sherlock/tattoo/tattoo_people.cpp') diff --git a/engines/sherlock/tattoo/tattoo_people.cpp b/engines/sherlock/tattoo/tattoo_people.cpp index a7d7d2426c..81f68b46ae 100644 --- a/engines/sherlock/tattoo/tattoo_people.cpp +++ b/engines/sherlock/tattoo/tattoo_people.cpp @@ -1313,6 +1313,31 @@ void TattooPeople::pullNPCPaths() { } } +const Common::Point TattooPeople::restrictToZone(int zoneId, const Common::Point &destPos) { + Scene &scene = *_vm->_scene; + Screen &screen = *_vm->_screen; + Common::Rect &r = scene._zones[zoneId]; + + if (destPos.x < 0 || destPos.x > screen._backBuffer1.w()) + return destPos; + else if (destPos.y < r.top && r.left < destPos.x && destPos.x < r.right) + return Common::Point(destPos.x, r.top); + else if (destPos.y > r.bottom && r.left < destPos.x && destPos.x < r.right) + return Common::Point(destPos.x, r.bottom); + else if (destPos.x < r.left && r.top < destPos.y && destPos.y < r.bottom) + return Common::Point(r.left, destPos.y); + else if (destPos.x > r.right && r.top < destPos.y && destPos.y < r.bottom) + return Common::Point(r.bottom, destPos.y); + + // Find which corner of the zone the point is closet to + if (destPos.x <= r.left) { + return Common::Point(r.left, (destPos.y <= r.top) ? r.top : r.bottom); + } else { + return Common::Point(r.right, (destPos.y <= r.top) ? r.top : r.bottom); + } +} + + } // End of namespace Tattoo } // End of namespace Sherlock -- cgit v1.2.3 From 6bc2a633a2921d589f8226160d19243a9ee99699 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Tue, 7 Jul 2015 08:19:39 -0400 Subject: SHERLOCK: RT: Fix Valgrind issues --- engines/sherlock/tattoo/tattoo_people.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'engines/sherlock/tattoo/tattoo_people.cpp') diff --git a/engines/sherlock/tattoo/tattoo_people.cpp b/engines/sherlock/tattoo/tattoo_people.cpp index 81f68b46ae..d89a2e7a55 100644 --- a/engines/sherlock/tattoo/tattoo_people.cpp +++ b/engines/sherlock/tattoo/tattoo_people.cpp @@ -988,7 +988,7 @@ void TattooPerson::synchronize(Serializer &s) { s.syncAsUint16LE(count); if (s.isLoading()) { // Load path - for (uint idx = 0; idx < count; ++count) { + for (uint idx = 0; idx < count; ++idx) { int xp = 0, yp = 0; s.syncAsSint16LE(xp); s.syncAsSint16LE(yp); -- cgit v1.2.3 From 348f2b5f3248247eeee7cf02fe08bdf01b9a78cf Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 12 Jul 2015 10:29:56 -0400 Subject: SHERLOCK: RT: Implement walkHolmesToNPC --- engines/sherlock/tattoo/tattoo_people.cpp | 89 +++++++++++++++++++++++++++++++ 1 file changed, 89 insertions(+) (limited to 'engines/sherlock/tattoo/tattoo_people.cpp') diff --git a/engines/sherlock/tattoo/tattoo_people.cpp b/engines/sherlock/tattoo/tattoo_people.cpp index d89a2e7a55..c166df7836 100644 --- a/engines/sherlock/tattoo/tattoo_people.cpp +++ b/engines/sherlock/tattoo/tattoo_people.cpp @@ -1016,6 +1016,95 @@ void TattooPerson::synchronize(Serializer &s) { _use[idx].synchronize(s); } +void TattooPerson::walkHolmesToNPC() { + Events &events = *_vm->_events; + TattooScene &scene = *(TattooScene *)_vm->_scene; + TattooPeople &people = *(TattooPeople *)_vm->_people; + Screen &screen = *_vm->_screen; + Talk &talk = *_vm->_talk; + TattooPerson &holmes = people[HOLMES]; + int facing; + + // If the NPC is moving, stop him at his current position + if (_walkCount) { + // Reset the facing so the NPC will stop facing the direction he was going, + // rather than the direction he was supposed to when he finished wlaking + _npcFacing = -1; + gotoStand(); + } + + int scaleVal = scene.getScaleVal(_position); + ImageFrame &imgFrame = (*holmes._images)[0]; + + // Clear the path variables + memset(_npcPath, 0, 100); + + // Set the NPC path so he pauses for 250 while looking at Holmes + _npcPath[0] = 6; + _npcPath[1] = 1; + _npcPath[2] = 251; + _npcIndex = 0; + _npcPause = 250; + _lookHolmes = true; + + // See where Holmes is with respect to the NPC (x coords) + if (holmes._position.x < _position.x) { + _walkDest.x = MAX(_position.x / FIXED_INT_MULTIPLIER - imgFrame.sDrawXSize(scaleVal), 0); + } else { + _walkDest.x = MIN(_position.x / FIXED_INT_MULTIPLIER + imgFrame.sDrawXSize(scaleVal) * 2, + screen._backBuffer1.w() - 1); + } + + // See where Holmes is with respect to the NPC (y coords) + if (holmes._position.y < (_position.y - imgFrame.sDrawXSize(scaleVal) * 500)) { + _walkDest.y = MAX(_position.y / FIXED_INT_MULTIPLIER - imgFrame.sDrawXSize(scaleVal) / 2, 0); + } else { + if (holmes._position.y > (_position.y + imgFrame.sDrawXSize(scaleVal) * 500)) { + // Holmes is below the NPC + _walkDest.y = MIN(_position.y / FIXED_INT_MULTIPLIER + imgFrame.sDrawXSize(scaleVal) / 2, + SHERLOCK_SCREEN_HEIGHT - 1); + } else { + // Holmes is roughly on the same Y as the NPC + _walkDest.y = _position.y / FIXED_INT_MULTIPLIER; + } + } + + events.setCursor(WAIT); + + _walkDest.x += 10; + people._allowWalkAbort = true; + holmes.goAllTheWay(); + + // Do doBgAnim should be called over and over until walk is done + do { + events.wait(1); + scene.doBgAnim(); + } while (holmes._walkCount); + + if (!talk._talkToAbort) { + // Setup correct direction for Holmes to face + + // See where Holmes is with respect to the NPC (x coords) + facing = (holmes._position.x < _position.x) ? STOP_RIGHT : STOP_LEFT; + + // See where Holmes is with respect to the NPC (y coords) + if (holmes._position.y < (_position.y - (10 * FIXED_INT_MULTIPLIER))) { + // Holmes is above the NPC. Reset the facing to the diagonal downs + facing = (facing == STOP_RIGHT) ? STOP_DOWNRIGHT : STOP_DOWNLEFT; + } else { + if (holmes._position.y > (_position.y + 10 * FIXED_INT_MULTIPLIER)) { + // Holmes is below the NPC. Reset the facing to the diagonal ups + facing = (facing == STOP_RIGHT) ? STOP_UPRIGHT : STOP_UPLEFT; + } + } + + holmes._sequenceNumber = facing; + holmes.gotoStand(); + + events.setCursor(ARROW); + } +} + /*----------------------------------------------------------------*/ TattooPeople::TattooPeople(SherlockEngine *vm) : People(vm) { -- cgit v1.2.3 From 918f6c06a61e777ba200335a3595d90e21bdc6dd Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 12 Jul 2015 20:47:44 -0400 Subject: SHERLOCK: RT: Fix Holmes walking when moving to talk to character --- engines/sherlock/tattoo/tattoo_people.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'engines/sherlock/tattoo/tattoo_people.cpp') diff --git a/engines/sherlock/tattoo/tattoo_people.cpp b/engines/sherlock/tattoo/tattoo_people.cpp index c166df7836..7aaa0a082c 100644 --- a/engines/sherlock/tattoo/tattoo_people.cpp +++ b/engines/sherlock/tattoo/tattoo_people.cpp @@ -1049,23 +1049,23 @@ void TattooPerson::walkHolmesToNPC() { // See where Holmes is with respect to the NPC (x coords) if (holmes._position.x < _position.x) { - _walkDest.x = MAX(_position.x / FIXED_INT_MULTIPLIER - imgFrame.sDrawXSize(scaleVal), 0); + holmes._walkDest.x = MAX(_position.x / FIXED_INT_MULTIPLIER - imgFrame.sDrawXSize(scaleVal), 0); } else { - _walkDest.x = MIN(_position.x / FIXED_INT_MULTIPLIER + imgFrame.sDrawXSize(scaleVal) * 2, + holmes._walkDest.x = MIN(_position.x / FIXED_INT_MULTIPLIER + imgFrame.sDrawXSize(scaleVal) * 2, screen._backBuffer1.w() - 1); } // See where Holmes is with respect to the NPC (y coords) if (holmes._position.y < (_position.y - imgFrame.sDrawXSize(scaleVal) * 500)) { - _walkDest.y = MAX(_position.y / FIXED_INT_MULTIPLIER - imgFrame.sDrawXSize(scaleVal) / 2, 0); + holmes._walkDest.y = MAX(_position.y / FIXED_INT_MULTIPLIER - imgFrame.sDrawXSize(scaleVal) / 2, 0); } else { if (holmes._position.y > (_position.y + imgFrame.sDrawXSize(scaleVal) * 500)) { // Holmes is below the NPC - _walkDest.y = MIN(_position.y / FIXED_INT_MULTIPLIER + imgFrame.sDrawXSize(scaleVal) / 2, + holmes._walkDest.y = MIN(_position.y / FIXED_INT_MULTIPLIER + imgFrame.sDrawXSize(scaleVal) / 2, SHERLOCK_SCREEN_HEIGHT - 1); } else { // Holmes is roughly on the same Y as the NPC - _walkDest.y = _position.y / FIXED_INT_MULTIPLIER; + holmes._walkDest.y = _position.y / FIXED_INT_MULTIPLIER; } } -- cgit v1.2.3