diff options
-rw-r--r-- | engines/sherlock/inventory.cpp | 10 | ||||
-rw-r--r-- | engines/sherlock/inventory.h | 1 | ||||
-rw-r--r-- | engines/sherlock/people.cpp | 223 | ||||
-rw-r--r-- | engines/sherlock/people.h | 10 | ||||
-rw-r--r-- | engines/sherlock/talk.cpp | 59 | ||||
-rw-r--r-- | engines/sherlock/talk.h | 3 |
6 files changed, 276 insertions, 30 deletions
diff --git a/engines/sherlock/inventory.cpp b/engines/sherlock/inventory.cpp index 0ea85f32fc..9eedac7c6a 100644 --- a/engines/sherlock/inventory.cpp +++ b/engines/sherlock/inventory.cpp @@ -453,7 +453,15 @@ int Inventory::putItemInInventory(Object &obj) { * Copy the passed object into the inventory */ void Inventory::copyToInventory(Object &obj) { - // TODO + InventoryItem invItem; + invItem._name = obj._name; + invItem._description = obj._description; + invItem._examine = obj._examine; + invItem._lookFlag = obj._lookFlag; + invItem._requiredFlag = obj._requiredFlag; + + insert_at(_holdings, invItem); + ++_holdings; } /** diff --git a/engines/sherlock/inventory.h b/engines/sherlock/inventory.h index 722692a3b2..436d2bc18d 100644 --- a/engines/sherlock/inventory.h +++ b/engines/sherlock/inventory.h @@ -53,6 +53,7 @@ struct InventoryItem { Common::String _examine; int _lookFlag; + InventoryItem() : _requiredFlag(0), _lookFlag(0) {} InventoryItem(int requiredFlag, const Common::String &name, const Common::String &description, const Common::String &examine); }; diff --git a/engines/sherlock/people.cpp b/engines/sherlock/people.cpp index 9319fbb79d..5c7f9ef506 100644 --- a/engines/sherlock/people.cpp +++ b/engines/sherlock/people.cpp @@ -50,6 +50,145 @@ static const uint8 CHARACTER_SEQUENCES[MAX_HOLMES_SEQUENCE][MAX_FRAME] = { { 52, 1, 2, 3, 4, 0 } // Goto Stand Down Left }; +const char PORTRAITS[MAX_PEOPLE][5] = { + { "HOLM" }, // Sherlock Holmes + { "WATS" }, // Dr. Watson + { "LEST" }, // Inspector Lestrade + { "CON1" }, // Constable O'Brien + { "CON2" }, // Constable Lewis + { "SHEI" }, // Sheila Parker + { "HENR" }, // Henry Carruthers + { "LESL" }, // Lesley (flower girl) + { "USH1" }, // Usher #1 + { "USH2" }, // Usher #2 + { "FRED" }, // Fredrick Epstein + { "WORT" }, // Mrs. Worthington + { "COAC" }, // Coach + { "PLAY" }, // Player + { "WBOY" }, // Tim (Waterboy) + { "JAME" }, // James Sanders + { "BELL" }, // Belle (perfumerie) + { "GIRL" }, // Cleaning Girl (perfumerie) + { "EPST" }, // Epstien in the Opera Balcony + { "WIGG" }, // Wiggins + { "PAUL" }, // Paul (Brumwell / Carroway) + { "BART" }, // Bartender + { "DIRT" }, // Dirty Drunk + { "SHOU" }, // Shouting Drunk + { "STAG" }, // Staggering Drunk + { "BOUN" }, // Bouncer + { "SAND" }, // James Sanders - At Home + { "CORO" }, // The Coroner + { "EQUE" }, // The Equestrian Shop Keeper + { "GEOR" }, // George Blackwood + { "LARS" }, // Lars + { "PARK" }, // Sheila Parker (happy) + { "CHEM" }, // Chemist + { "GREG" }, // Inspector Gregson + { "LAWY" }, // Jacob Farthington Lawyer + { "MYCR" }, // Mycroft + { "SHER" }, // Old Sherman + { "CHMB" }, // Richard Chemist Stock boy + { "BARM" }, // Barman + { "DAND" }, // Dandy Player + { "ROUG" }, // Rough-looking Player + { "SPEC" }, // Spectator + { "HUNT" }, // Robert Hunt + { "VIOL" }, // Violet Secretary + { "PETT" }, // Pettigrew + { "APPL" }, // Augie (apple seller) + { "ANNA" }, // Anna Carroway + { "GUAR" }, // Guard + { "ANTO" }, // Antonio Caruso + { "TOBY" }, // Toby the Dog + { "KING" }, // Simon Kingsley + { "ALFR" }, // Alfred Tobacco Clerk + { "LADY" }, // Lady Brumwell + { "ROSA" }, // Madame Rosa + { "LADB" }, // Lady Brumwell + { "MOOR" }, // Joseph Moorehead + { "BEAL" }, // Mrs. Beale + { "LION" }, // Felix the Lion + { "HOLL" }, // Hollingston + { "CALL" }, // Constable Callaghan + { "JERE" }, // Sergeant Jeremy Duncan + { "LORD" }, // Lord Brumwell + { "NIGE" }, // Nigel Jameson + { "JONA" }, // Jonas (newspaper seller) + { "DUGA" }, // Constable Dugan + { "INSP" } // Inspector Lestrade (Scotland Yard) +}; + +const char *const NAMES[MAX_PEOPLE] = { + "Sherlock Holmes", + "Dr. Watson", + "Inspector Lestrade", + "Constable O'Brien", + "Constable Lewis", + "Sheila Parker", + "Henry Carruthers", + "Lesley", + "An Usher", + "An Usher", + "Fredrick Epstein", + "Mrs. Worthington", + "The Coach", + "A Player", + "Tim", + "James Sanders", + "Belle", + "Cleaning Girl", + "Fredrick Epstein", + "Wiggins", + "Paul", + "The Bartender", + "A Dirty Drunk", + "A Shouting Drunk", + "A Staggering Drunk", + "The Bouncer", + "James Sanders", + "The Coroner", + "Reginald Snipes", + "George Blackwood", + "Lars", + "Sheila Parker", + "The Chemist", + "Inspector Gregson", + "Jacob Farthington", + "Mycroft", + "Old Sherman", + "Richard", + "The Barman", + "A Dandy Player", + "A Rough-looking Player", + "A Spectator", + "Robert Hunt", + "Violet", + "Pettigrew", + "Augie", + "Anna Carroway", + "A Guard", + "Antonio Caruso", + "Toby the Dog", + "Simon Kingsley", + "Alfred", + "Lady Brumwell", + "Madame Rosa", + "Lady Brumwell", + "Joseph Moorehead", + "Mrs. Beale", + "Felix", + "Hollingston", + "Constable Callaghan", + "Sergeant Duncan", + "Lord Brumwell", + "Nigel Jaimeson", + "Jonas", + "Constable Dugan", + "Inspector Lestrade" +}; + +/*----------------------------------------------------------------*/ People::People(SherlockEngine *vm) : _vm(vm), _player(_data[0]) { _walkLoaded = false; @@ -63,6 +202,7 @@ People::People(SherlockEngine *vm) : _vm(vm), _player(_data[0]) { _talkPics = nullptr; _portraitSide = 0; _speakerFlip = false; + _holmesFlip = false; } People::~People() { @@ -440,6 +580,27 @@ void People::goAllTheWay() { } /** + * Finds the scene background object corresponding to a specified speaker + */ +int People::findSpeaker(int speaker) { + Scene &scene = *_vm->_scene; + + for (int idx = 0; idx < (int)scene._bgShapes.size(); ++idx) { + Object &obj = scene._bgShapes[idx]; + + if (obj._type == ACTIVE_BG_SHAPE) { + Common::String name(obj._name.c_str(), obj._name.c_str() + 4); + + if (scumm_stricmp(PORTRAITS[speaker], name.c_str()) == 0 + && obj._name[4] >= '0' && obj._name[4] <= '9') + return idx - 1; + } + } + + return -1; +} + +/** * Turn off any currently active portraits, and removes them from being drawn */ void People::clearTalking() { @@ -472,9 +633,65 @@ void People::clearTalking() { } } -int People::findSpeaker(int speaker) { - // TODO - return -1; +/** + * Setup the data for an animating speaker portrait at the top of the screen + */ +void People::setTalking(int speaker) { + Resources &res = *_vm->_res; + + // If no speaker is specified, then we can exit immediately + if (speaker == -1) + return; + + if (_portraitsOn) { + delete _talkPics; + _talkPics = new ImageFile("portrait.lib"); + + // Load portrait sequences + Common::SeekableReadStream *stream = res.load("sequence.txt"); + stream->seek(speaker * MAX_FRAME); + + int idx = 0; + do { + _portrait._sequences[idx] = stream->readByte(); + ++idx; + } while (idx < 2 || _portrait._sequences[idx - 2] || _portrait._sequences[idx - 1]); + + delete stream; + + _portrait._maxFrames = idx; + _portrait._frameNumber = 0; + _portrait._sequenceNumber = 0; + _portrait._images = _talkPics; + _portrait._imageFrame = &(*_talkPics)[0]; + _portrait._position = Common::Point(_portraitSide, 10); + _portrait._delta = Common::Point(0, 0); + _portrait._oldPosition = Common::Point(0, 0); + _portrait._goto = Common::Point(0, 0); + _portrait._flags = 5; + _portrait._status = 0; + _portrait._misc = 0; + _portrait._allow = 0; + _portrait._type = ACTIVE_BG_SHAPE; + _portrait._name = " "; + _portrait._description = " "; + _portrait._examine = " "; + _portrait._walkCount = 0; + + if (_holmesFlip || _speakerFlip) { + _portrait._flags |= 2; + + _holmesFlip = false; + _speakerFlip = false; + } + + if (_portraitSide == 20) + _portraitSide = 220; + else + _portraitSide = 20; + + _portraitLoaded = true; + } } } // End of namespace Sherlock diff --git a/engines/sherlock/people.h b/engines/sherlock/people.h index 1a846dded1..bec078d11e 100644 --- a/engines/sherlock/people.h +++ b/engines/sherlock/people.h @@ -34,7 +34,7 @@ enum PeopleId { PLAYER = 0, AL = 0, PEG = 1, - MAX_PEOPLE = 2 + MAX_PEOPLE = 66 }; // Animation sequence identifiers for characters @@ -66,8 +66,8 @@ private: bool _walkLoaded; int _oldWalkSequence; int _srcZone, _destZone; - ImageFile *_talkPics; public: + ImageFile *_talkPics; Common::Point _walkDest; Common::Stack<Common::Point> _walkTo; Person &_player; @@ -79,6 +79,7 @@ public: bool _allowWalkAbort; int _portraitSide; bool _speakerFlip; + bool _holmesFlip; public: People(SherlockEngine *vm); ~People(); @@ -102,9 +103,10 @@ public: void goAllTheWay(); - void clearTalking(); - int findSpeaker(int speaker); + + void clearTalking(); + void setTalking(int speaker); }; } // End of namespace Sherlock diff --git a/engines/sherlock/talk.cpp b/engines/sherlock/talk.cpp index 193c0f9a19..c97f2a0646 100644 --- a/engines/sherlock/talk.cpp +++ b/engines/sherlock/talk.cpp @@ -161,7 +161,6 @@ void Talk::talkTo(const Common::String &filename) { Scene &scene = *_vm->_scene; Screen &screen = *_vm->_screen; Scripts &scripts = *_vm->_scripts; - Talk &talk = *_vm->_talk; UserInterface &ui = *_vm->_ui; Common::Rect savedBounds = screen.getDisplayBounds(); bool abortFlag = false; @@ -202,10 +201,10 @@ void Talk::talkTo(const Common::String &filename) { people.gotoStand(people._player); } - if (talk._talkToAbort) + if (_talkToAbort) return; - talk.freeTalkVars(); + freeTalkVars(); // If any sequences have changed in the prior talk file, restore them if (_savedSequences.size() > 0) { @@ -928,8 +927,36 @@ void Talk::pushSequence(int speaker) { error("script stack overflow"); } +/** + * Change the sequence of the scene background object associated with the current speaker. + */ void Talk::setSequence(int speaker) { - // TODO + People &people = *_vm->_people; + Scene &scene = *_vm->_scene; + + // If no speaker is specified, then nothing needs to be done + if (speaker != -1) + return; + + if (speaker) { + int objNum = people.findSpeaker(speaker); + if (objNum != -1) { + Object &obj = scene._bgShapes[objNum]; + + if (obj._seqSize < MAX_TALK_SEQUENCES) { + warning("Tried to copy too many talk frames"); + } else { + for (int idx = 0; idx < MAX_TALK_SEQUENCES; ++idx) { + obj._sequences[idx] = TALK_SEQUENCES[speaker][idx]; + if (idx > 0 && !TALK_SEQUENCES[speaker][idx] && !TALK_SEQUENCES[speaker][idx - 1]) + return; + + obj._frameNumber = 0; + obj._sequenceNumber = 0; + } + } + } + } } /** @@ -1045,7 +1072,7 @@ void Talk::doScript(const Common::String &script) { } else { // Nope, so set the first speaker - setTalking(_speaker); + people.setTalking(_speaker); } } @@ -1068,7 +1095,7 @@ void Talk::doScript(const Common::String &script) { _scriptCurrentIndex = str - script.c_str(); if (!(_speaker & 128)) - clearTalking(); + people.clearTalking(); if (_talkToAbort) return; @@ -1077,7 +1104,7 @@ void Talk::doScript(const Common::String &script) { charCount = line = 0; _speaker = *++str - 1; - setTalking(_speaker); + people.setTalking(_speaker); pullSequence(); pushSequence(_speaker); setSequence(_speaker); @@ -1128,7 +1155,7 @@ void Talk::doScript(const Common::String &script) { _scriptCurrentIndex = str - script.c_str(); if (_speaker < 128) - clearTalking(); + people.clearTalking(); pullSequence(); if (_talkToAbort) return; @@ -1214,7 +1241,7 @@ void Talk::doScript(const Common::String &script) { _scriptCurrentIndex = str - script.c_str(); if (!(_speaker & 128)) - clearTalking(); + people.clearTalking(); pullSequence(); if (_talkToAbort) @@ -1426,11 +1453,13 @@ void Talk::doScript(const Common::String &script) { case WALK_TO_CANIMATION: { ++str; - int animIndex = str[0] - 1; + CAnim &anim = scene._cAnim[str[0] - 1]; // Save the current point in the script, since it might be intterupted by // doing bg anims in the next call, so we need to know where to return to _scriptCurrentIndex = (str + 1) - script.c_str(); + + people.walkToCoords(anim._goto, anim._gotoDir); if (_talkToAbort) return; break; @@ -1616,18 +1645,10 @@ void Talk::doScript(const Common::String &script) { pullSequence(); if (_speaker < 128) - clearTalking(); + people.clearTalking(); } } -void Talk::clearTalking() { - // TODO -} - -void Talk::setTalking(int speaker) { - // TODO -} - /** * When the talk window has been displayed, waits a period of time proportional to * the amount of text that's been displayed diff --git a/engines/sherlock/talk.h b/engines/sherlock/talk.h index 1b679a47bd..1a7dd587da 100644 --- a/engines/sherlock/talk.h +++ b/engines/sherlock/talk.h @@ -110,9 +110,6 @@ private: void doScript(const Common::String &script); - void clearTalking(); - void setTalking(int speaker); - int waitForMore(int delay); public: bool _talkToAbort; |