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; | 
