aboutsummaryrefslogtreecommitdiff
path: root/engines/sherlock
diff options
context:
space:
mode:
authorPaul Gilbert2015-04-11 16:52:19 -0500
committerWillem Jan Palenstijn2015-05-07 22:49:22 +0200
commit0d4d8e878cfba4ea9c32dc46e4923886df95395c (patch)
tree4eb479d00414a3e6d6bd12538f4fff55b08b2d9a /engines/sherlock
parent96e04ab797253bbe853f172ea1d734ebe812d419 (diff)
downloadscummvm-rg350-0d4d8e878cfba4ea9c32dc46e4923886df95395c.tar.gz
scummvm-rg350-0d4d8e878cfba4ea9c32dc46e4923886df95395c.tar.bz2
scummvm-rg350-0d4d8e878cfba4ea9c32dc46e4923886df95395c.zip
SHERLOCK: Implemented stubbed talk and inventory methods
Diffstat (limited to 'engines/sherlock')
-rw-r--r--engines/sherlock/inventory.cpp10
-rw-r--r--engines/sherlock/inventory.h1
-rw-r--r--engines/sherlock/people.cpp223
-rw-r--r--engines/sherlock/people.h10
-rw-r--r--engines/sherlock/talk.cpp59
-rw-r--r--engines/sherlock/talk.h3
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;