[Scummvm-cvs-logs] scummvm master -> 3adaf2f999c4af74534beb7d02638aba8cc81a1e

dreammaster dreammaster at scummvm.org
Sun Jun 21 14:47:45 CEST 2015


This automated email contains information about 1 new commit which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .

Summary:
3adaf2f999 SHERLOCK: RT: Implement inventory handleEvents


Commit: 3adaf2f999c4af74534beb7d02638aba8cc81a1e
    https://github.com/scummvm/scummvm/commit/3adaf2f999c4af74534beb7d02638aba8cc81a1e
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2015-06-21T08:46:38-04:00

Commit Message:
SHERLOCK: RT: Implement inventory handleEvents

Changed paths:
    engines/sherlock/inventory.h
    engines/sherlock/tattoo/tattoo.cpp
    engines/sherlock/tattoo/tattoo.h
    engines/sherlock/tattoo/tattoo_map.cpp
    engines/sherlock/tattoo/tattoo_user_interface.cpp
    engines/sherlock/tattoo/tattoo_user_interface.h
    engines/sherlock/tattoo/widget_base.cpp
    engines/sherlock/tattoo/widget_base.h
    engines/sherlock/tattoo/widget_inventory.cpp
    engines/sherlock/tattoo/widget_inventory.h
    engines/sherlock/tattoo/widget_verbs.cpp
    engines/sherlock/tattoo/widget_verbs.h



diff --git a/engines/sherlock/inventory.h b/engines/sherlock/inventory.h
index a2c317f..019f5ed 100644
--- a/engines/sherlock/inventory.h
+++ b/engines/sherlock/inventory.h
@@ -62,7 +62,11 @@ struct InventoryItem {
 	Common::String _examine;
 	int _lookFlag;
 
-	InventoryItem() : _requiredFlag(0), _lookFlag(0) {}
+	// Rose Tattoo fields
+	int _requiredFlag1;
+	UseType _verb;
+
+	InventoryItem() : _requiredFlag(0), _lookFlag(0), _requiredFlag1(0) {}
 	InventoryItem(int requiredFlag, const Common::String &name,
 		const Common::String &description, const Common::String &examine);
 
diff --git a/engines/sherlock/tattoo/tattoo.cpp b/engines/sherlock/tattoo/tattoo.cpp
index 60705f6..bc4e7d5 100644
--- a/engines/sherlock/tattoo/tattoo.cpp
+++ b/engines/sherlock/tattoo/tattoo.cpp
@@ -24,6 +24,7 @@
 #include "sherlock/tattoo/tattoo.h"
 #include "sherlock/tattoo/tattoo_resources.h"
 #include "sherlock/tattoo/tattoo_scene.h"
+#include "sherlock/tattoo/widget_base.h"
 #include "sherlock/people.h"
 
 namespace Sherlock {
@@ -38,6 +39,10 @@ TattooEngine::TattooEngine(OSystem *syst, const SherlockGameDescription *gameDes
 	_allowFastMode = true;
 }
 
+TattooEngine::~TattooEngine() {
+	WidgetBase::freeInterfaceImages();
+}
+
 void TattooEngine::showOpening() {
 	// TODO
 }
@@ -48,6 +53,9 @@ void TattooEngine::initialize() {
 	// Initialize the base engine
 	SherlockEngine::initialize();
 
+	// Further initialization
+	WidgetBase::setInterfaceImages(new ImageFile("intrface.vgs"));
+
 	// Initialise the global flags
 	_flags.resize(3200);
 	_flags[1] = _flags[4] = _flags[76] = true;
@@ -105,6 +113,10 @@ void TattooEngine::eraseCredits() {
 	// TODO
 }
 
+void TattooEngine::doHangManPuzzle() {
+	// TODO
+}
+
 } // End of namespace Tattoo
 
 } // End of namespace Sherlock
diff --git a/engines/sherlock/tattoo/tattoo.h b/engines/sherlock/tattoo/tattoo.h
index 39f4934..d7d21155 100644
--- a/engines/sherlock/tattoo/tattoo.h
+++ b/engines/sherlock/tattoo/tattoo.h
@@ -59,7 +59,7 @@ public:
 	bool _fastMode, _allowFastMode;
 public:
 	TattooEngine(OSystem *syst, const SherlockGameDescription *gameDesc);
-	virtual ~TattooEngine() {}
+	virtual ~TattooEngine();
 
 	/**
 	 * Draw credits on the screen
@@ -75,6 +75,8 @@ public:
 	 * Erase any area of the screen covered by credits
 	 */
 	void eraseCredits();
+
+	void doHangManPuzzle();
 };
 
 } // End of namespace Tattoo
diff --git a/engines/sherlock/tattoo/tattoo_map.cpp b/engines/sherlock/tattoo/tattoo_map.cpp
index b8f1b6c..365c14a 100644
--- a/engines/sherlock/tattoo/tattoo_map.cpp
+++ b/engines/sherlock/tattoo/tattoo_map.cpp
@@ -306,7 +306,6 @@ void TattooMap::drawMapIcons() {
 
 void TattooMap::checkMapNames(bool slamIt) {
 	Events &events = *_vm->_events;
-	Screen &screen = *_vm->_screen;
 	Common::Point mousePos = events.mousePos() + _currentScroll;
 
 	// See if the mouse is pointing at any of the map locations
diff --git a/engines/sherlock/tattoo/tattoo_user_interface.cpp b/engines/sherlock/tattoo/tattoo_user_interface.cpp
index d12f0e7..322655f 100644
--- a/engines/sherlock/tattoo/tattoo_user_interface.cpp
+++ b/engines/sherlock/tattoo/tattoo_user_interface.cpp
@@ -575,7 +575,7 @@ void TattooUserInterface::doFileControl() {
 }
 
 void TattooUserInterface::doInventoryControl() {
-	warning("TODO: ui control (inventory)");
+	_inventoryWidget.handleEvents();
 }
 
 void TattooUserInterface::doVerbControl() {
@@ -644,6 +644,10 @@ void TattooUserInterface::freeMenu() {
 	}
 }
 
+void TattooUserInterface::putMessage(const Common::String &str) {
+	// TODO
+}
+
 } // End of namespace Tattoo
 
 } // End of namespace Sherlock
diff --git a/engines/sherlock/tattoo/tattoo_user_interface.h b/engines/sherlock/tattoo/tattoo_user_interface.h
index 35e1cb8..935e076 100644
--- a/engines/sherlock/tattoo/tattoo_user_interface.h
+++ b/engines/sherlock/tattoo/tattoo_user_interface.h
@@ -188,6 +188,8 @@ public:
 	 * Pick up the selected object
 	 */
 	void pickUpObject(int objNum);
+
+	void putMessage(const Common::String &str);
 public:
 	/**
 	 * Resets the user interface
diff --git a/engines/sherlock/tattoo/widget_base.cpp b/engines/sherlock/tattoo/widget_base.cpp
index a9422de..682961f 100644
--- a/engines/sherlock/tattoo/widget_base.cpp
+++ b/engines/sherlock/tattoo/widget_base.cpp
@@ -29,8 +29,18 @@ namespace Sherlock {
 
 namespace Tattoo {
 
+ImageFile *WidgetBase::_interfaceImages;
+
+void WidgetBase::setInterfaceImages(ImageFile *images) {
+	_interfaceImages = images;
+}
+
+void WidgetBase::freeInterfaceImages() {
+	delete _interfaceImages;
+	_interfaceImages = nullptr;
+}
+
 WidgetBase::WidgetBase(SherlockEngine *vm) : _vm(vm) {
-	_images = nullptr;
 }
 
 void WidgetBase::summonWindow() {
@@ -135,32 +145,38 @@ void WidgetBase::checkMenuPosition() {
 		_bounds.moveTo(_bounds.left, SHERLOCK_SCREEN_HEIGHT - _bounds.height());
 }
 
-void WidgetBase::makeInfoArea() {
+void WidgetBase::makeInfoArea(Surface &s) {
+	ImageFile &images = *_interfaceImages;
+
 	// Draw the four corners of the Info Box
-	_surface.transBlitFrom((*_images)[0], Common::Point(0, 0));
-	_surface.transBlitFrom((*_images)[1], Common::Point(_bounds.width() - (*_images)[1]._width, 0));
-	_surface.transBlitFrom((*_images)[2], Common::Point(0, _bounds.height() - (*_images)[2]._height));
-	_surface.transBlitFrom((*_images)[3], Common::Point(_bounds.width() - (*_images)[3]._width, _bounds.height()));
+	s.transBlitFrom(images[0], Common::Point(0, 0));
+	s.transBlitFrom(images[1], Common::Point(s.w() - images[1]._width, 0));
+	s.transBlitFrom(images[2], Common::Point(0, s.h() - images[2]._height));
+	s.transBlitFrom(images[3], Common::Point(s.w() - images[3]._width, s.h()));
 
 	// Draw the top of the Info Box
-	_surface.hLine((*_images)[0]._width, 0, _bounds.width() - (*_images)[1]._width, INFO_TOP);
-	_surface.hLine((*_images)[0]._width, 1, _bounds.width() - (*_images)[1]._width, INFO_MIDDLE);
-	_surface.hLine((*_images)[0]._width, 2, _bounds.width() - (*_images)[1]._width, INFO_BOTTOM);
+	s.hLine(images[0]._width, 0, s.w() - images[1]._width, INFO_TOP);
+	s.hLine(images[0]._width, 1, s.w() - images[1]._width, INFO_MIDDLE);
+	s.hLine(images[0]._width, 2, s.w() - images[1]._width, INFO_BOTTOM);
 
 	// Draw the bottom of the Info Box
-	_surface.hLine((*_images)[0]._width, _bounds.height()- 3, _bounds.width() - (*_images)[1]._width, INFO_TOP);
-	_surface.hLine((*_images)[0]._width, _bounds.height()- 2, _bounds.width() - (*_images)[1]._width, INFO_MIDDLE);
-	_surface.hLine((*_images)[0]._width, _bounds.height()- 1, _bounds.width() - (*_images)[1]._width, INFO_BOTTOM);
+	s.hLine(images[0]._width, s.h()- 3, s.w() - images[1]._width, INFO_TOP);
+	s.hLine(images[0]._width, s.h()- 2, s.w() - images[1]._width, INFO_MIDDLE);
+	s.hLine(images[0]._width, s.h()- 1, s.w() - images[1]._width, INFO_BOTTOM);
 
 	// Draw the left Side of the Info Box
-	_surface.vLine(0, (*_images)[0]._height, _bounds.height()- (*_images)[2]._height, INFO_TOP);
-	_surface.vLine(1, (*_images)[0]._height, _bounds.height()- (*_images)[2]._height, INFO_MIDDLE);
-	_surface.vLine(2, (*_images)[0]._height, _bounds.height()- (*_images)[2]._height, INFO_BOTTOM);
+	s.vLine(0, images[0]._height, s.h()- images[2]._height, INFO_TOP);
+	s.vLine(1, images[0]._height, s.h()- images[2]._height, INFO_MIDDLE);
+	s.vLine(2, images[0]._height, s.h()- images[2]._height, INFO_BOTTOM);
 
 	// Draw the right Side of the Info Box
-	_surface.vLine(_bounds.width() - 3, (*_images)[0]._height, _bounds.height()- (*_images)[2]._height, INFO_TOP);
-	_surface.vLine(_bounds.width() - 2, (*_images)[0]._height, _bounds.height()- (*_images)[2]._height, INFO_MIDDLE);
-	_surface.vLine(_bounds.width() - 1, (*_images)[0]._height, _bounds.height()- (*_images)[2]._height, INFO_BOTTOM);
+	s.vLine(s.w() - 3, images[0]._height, s.h()- images[2]._height, INFO_TOP);
+	s.vLine(s.w() - 2, images[0]._height, s.h()- images[2]._height, INFO_MIDDLE);
+	s.vLine(s.w() - 1, images[0]._height, s.h()- images[2]._height, INFO_BOTTOM);
+}
+
+void WidgetBase::makeInfoArea() {
+	makeInfoArea(_surface);
 }
 
 const Common::Point &WidgetBase::getCurrentScroll() const {
@@ -168,6 +184,9 @@ const Common::Point &WidgetBase::getCurrentScroll() const {
 	return ui._currentScroll;
 }
 
+void WidgetBase::checkTabbingKeys(int numOptions) {
+}
+
 } // End of namespace Tattoo
 
 } // End of namespace Sherlock
diff --git a/engines/sherlock/tattoo/widget_base.h b/engines/sherlock/tattoo/widget_base.h
index 7e546db..9d2ddcf 100644
--- a/engines/sherlock/tattoo/widget_base.h
+++ b/engines/sherlock/tattoo/widget_base.h
@@ -39,10 +39,11 @@ class WidgetBase {
 private:
 	Common::Rect _oldBounds;
 protected:
+	static ImageFile *_interfaceImages;
+protected:
 	SherlockEngine *_vm;
 	Common::Rect _bounds;
 	Surface _surface;
-	ImageFile *_images;
 	bool _outsideMenu;
 
 	/**
@@ -55,6 +56,14 @@ protected:
 	 */
 	void checkMenuPosition();
 
+	/**
+	 * Draw a window frame around the dges of the passed surface
+	 */
+	void makeInfoArea(Surface &s);
+
+	/**
+	 * Draw a window frame around the widget's surface
+	 */
 	void makeInfoArea();
 
 	/**
@@ -62,6 +71,16 @@ protected:
 	 */
 	virtual const Common::Point &getCurrentScroll() const;
 public:
+	/**
+	 * Sets the interface images used for drawing the various types of window elements
+	 */
+	static void setInterfaceImages(ImageFile *images);
+
+	/**
+	 * Frees the interface images
+	 */
+	static void freeInterfaceImages();
+public:
 	WidgetBase(SherlockEngine *vm);
 	virtual ~WidgetBase() {}
 
@@ -76,6 +95,11 @@ public:
 	void draw();
 
 	/**
+	 * Used by some descendents to check for keys to mouse the mouse within the dialog
+	 */
+	void checkTabbingKeys(int numOptions);
+
+	/**
 	 * Summon the window
 	 */
 	virtual void summonWindow();
diff --git a/engines/sherlock/tattoo/widget_inventory.cpp b/engines/sherlock/tattoo/widget_inventory.cpp
index dfa4736..ee8faa3 100644
--- a/engines/sherlock/tattoo/widget_inventory.cpp
+++ b/engines/sherlock/tattoo/widget_inventory.cpp
@@ -21,6 +21,7 @@
  */
 
 #include "sherlock/tattoo/widget_inventory.h"
+#include "sherlock/tattoo/tattoo_scene.h"
 #include "sherlock/tattoo/tattoo_user_interface.h"
 #include "sherlock/tattoo/tattoo.h"
 
@@ -31,14 +32,26 @@ namespace Tattoo {
 #define INVENTORY_XSIZE 70			// Width of the box that surrounds inventory items
 #define INVENTORY_YSIZE 70			// Height of the box that surrounds inventory items
 #define NUM_INVENTORY_SHOWN 8		// Number of Inventory Items Shown
+#define MAX_INV_COMMANDS 10			// Maximum elements in dialog
 #define BUTTON_SIZE 15				// Button width/height
 
-WidgetInventory::WidgetInventory(SherlockEngine *vm) : WidgetBase(vm) {
+// TODO: Refactor into FixedText
+#define S_INV6 "Foolscap"
+#define S_INV7 "Damp Paper"
+#define S_SOLVE "Solve"
+#define S_LOOK "Look"
+#define S_NO_EFFECT "No effect..."
+#define S_WITH "with"
+
+WidgetInventory::WidgetInventory(SherlockEngine *vm) : WidgetBase(vm), _tooltipWidget(vm) {
 	_invMode = 0;
 	_invVerbMode = 0;
 	_invSelect = _oldInvSelect = 0;
 	_selector = _oldSelector = 0;
+	_invVerbSelect = _oldInvVerbSelect = -1;
 	_dialogTimer = -1;
+	_scrollHighlight = 0;
+	_swapItems = false;
 }
 
 void WidgetInventory::load(int mode) {
@@ -72,7 +85,7 @@ void WidgetInventory::load(int mode) {
 	_surface.fill(TRANSPARENCY);
 
 	// Draw the window background and then the inventory on top of it
-	makeInfoArea();
+	makeInfoArea(_surface);
 	drawInventory();
 }
 
@@ -187,6 +200,354 @@ void WidgetInventory::drawDialogRect(const Common::Rect &r, bool raised) {
 	}
 }
 
+void WidgetInventory::handleEvents() {
+	TattooEngine &vm = *(TattooEngine *)_vm;
+	Events &events = *_vm->_events;
+	Inventory &inv = *_vm->_inventory;
+	People &people = *_vm->_people;
+	TattooScene &scene = *(TattooScene *)_vm->_scene;
+	TattooUserInterface &ui = *(TattooUserInterface *)_vm->_ui;
+	Common::Point mousePos = events.mousePos();
+
+	if (_invVerbMode == 1)
+		checkTabbingKeys(MAX_INV_COMMANDS);
+	else if (_invVerbMode == 0)
+		checkInvTabbingKeys();
+
+	if (_invVerbMode != 1)
+		updateDescription();
+
+	// Flag is they started pressing outside of the menu
+	if (events._firstPress && !_bounds.contains(mousePos))
+		_outsideMenu = true;
+
+	if (_invVerbMode != 3)
+		highlightControls();
+
+	// See if they released a mouse button button
+	if (events._released || events._rightReleased || ui._keyState.keycode == Common::KEYCODE_ESCAPE) {
+		_dialogTimer = -1;
+		_scrollHighlight = 0;
+
+		// See if they have a Verb List open for an Inventry Item
+		if (_invVerbMode == 1) {
+			// An inventory item's Verb List is open
+
+			// See if they want to close the menu (by clicking outside the menu)
+			Common::Rect innerBounds = _bounds;
+			innerBounds.grow(-3);
+			
+			if (_outsideMenu && !innerBounds.contains(mousePos)) {
+				banishWindow();
+				_invVerbMode = 0;
+			} else if (innerBounds.contains(mousePos)) {
+				_outsideMenu = false;
+
+				// Check if they are trying to solve the Foolscap puzzle, or looking at the completed puzzle
+				bool doHangman = !inv[_invSelect]._name.compareToIgnoreCase(S_INV6) &&
+					!_inventCommands[_invVerbSelect].compareToIgnoreCase(S_SOLVE);
+				doHangman |= (!inv[_invSelect]._name.compareToIgnoreCase(S_INV6) || !inv[_invSelect]._name.compareToIgnoreCase(S_INV7))
+					&& _inventCommands[_invVerbSelect].compareToIgnoreCase(S_LOOK) && vm.readFlags(299);
+
+				if (doHangman) {
+					// Close the entire Inventory and return to Standard Mode
+					banishWindow();
+					_invVerbMode = 0;
+
+					_tooltipWidget.banishWindow();
+					banishWindow();
+					inv.freeInv();
+
+					events.clearEvents();
+					events.setCursor(ARROW);
+					ui._menuMode = scene._labTableScene ? LAB_MODE : STD_MODE;
+
+					scene.doBgAnim();
+					vm.doHangManPuzzle();
+				} else if (_invVerbSelect == 0) {
+					// They have released the mouse on the Look Verb command, so Look at the inventory item
+					ui._invLookFlag = true;
+					inv.freeInv();
+					ui._windowOpen = false;
+					ui._lookPos = mousePos;
+					ui.printObjectDesc(inv[_invSelect]._examine, true);
+				} else {
+					// Clear the window
+					banishWindow();
+					_invVerbMode = 3;
+					ui._oldBgFound = -1;
+
+					// See if the selected Verb with the selected Iventory Item, is to be used by itself
+					if (!_inventCommands[_invVerbSelect].compareToIgnoreCase(inv[_invSelect]._verb._verb) ||
+						!inv[_invSelect]._verb._target.compareToIgnoreCase("*SELF")) {
+						inv.freeInv();
+						
+						ui._menuMode = scene._labTableScene ? LAB_MODE : STD_MODE;
+						events.clearEvents();
+						ui.checkAction(inv[_invSelect]._verb, 2000);
+					} else {
+						_invVerb = _inventCommands[_invVerbSelect];
+					}
+				}
+
+				// If we are still in Inventory Mode, setup the graphic to float in front of the mouse cursor
+				if (ui._menuMode == INV_MODE) {
+					ImageFrame &imgFrame = (*inv._invShapes[_invSelect - inv._invIndex])[0];
+					_invGraphicBounds = Common::Rect(imgFrame._width, imgFrame._height);
+					_invGraphicBounds.moveTo(mousePos.x - _invGraphicBounds.width() / 2,
+						mousePos.y - _invGraphicBounds.height() / 2);
+
+					// Constrain it to the screen
+					if (_invGraphicBounds.left < 0)
+						_invGraphicBounds.moveTo(0, _invGraphicBounds.top);
+					if (_invGraphicBounds.top < 0)
+						_invGraphicBounds.moveTo(_invGraphicBounds.left, 0);
+					if (_invGraphicBounds.right > SHERLOCK_SCREEN_WIDTH)
+						_invGraphicBounds.moveTo(SHERLOCK_SCREEN_WIDTH - _invGraphicBounds.width(), _invGraphicBounds.top);
+					if (_invGraphicBounds.bottom > SHERLOCK_SCREEN_HEIGHT)
+						_invGraphicBounds.moveTo(_invGraphicBounds.left, SHERLOCK_SCREEN_HEIGHT - _invGraphicBounds.height());
+
+					// Make a copy of the inventory image
+					_invGraphic.create(imgFrame._width, imgFrame._height);
+					_invGraphic.blitFrom(imgFrame, Common::Point(0, 0));
+				}
+			}
+		} else if (_invVerbMode == 3) {
+			// Selecting object after inventory verb has been selected
+			_tooltipWidget.banishWindow();
+			_invGraphic.free();
+			inv.freeInv();
+
+			ui._menuMode = scene._labTableScene ? LAB_MODE : STD_MODE;
+			events.clearEvents();
+
+			if (ui._keyState.keycode != Common::KEYCODE_ESCAPE) {
+				// If user pointed at an item, use the selected inventory item with this item
+				bool found = false;
+				if (ui._bgFound != -1) {
+					if (ui._personFound) {
+						for (int idx = 0; idx < 2; ++idx) {
+							if (!people[ui._bgFound - 1000]._use[idx]._verb.compareToIgnoreCase(_invVerb) &&
+								!people[ui._bgFound - 1000]._use[idx]._target.compareToIgnoreCase(_invTarget)) {
+								ui.checkAction(people[ui._bgFound - 1000]._use[idx], ui._bgFound);
+								found = true;
+							}
+						}
+					} else {
+						for (int idx = 0; idx < 6; ++idx) {
+							if (!ui._bgShape->_use[idx]._verb.compareToIgnoreCase(_invVerb) &&
+									!ui._bgShape->_use[idx]._target.compareToIgnoreCase(_invTarget)) {
+								ui.checkAction(ui._bgShape->_use[idx], ui._bgFound);
+								found = true;
+							}
+						}
+					}
+				}
+
+				if (!found)
+					ui.putMessage(S_NO_EFFECT);
+			}
+		} else if ((_outsideMenu && !_bounds.contains(mousePos)) || ui._keyState.keycode == Common::KEYCODE_ESCAPE) {
+			// Want to close the window (clicked outside of it). So close the window and return to Standard 
+			banishWindow();
+			inv.freeInv();
+
+			events.clearEvents();
+			events.setCursor(ARROW);
+			banishWindow();
+			ui._menuMode = scene._labTableScene ? LAB_MODE : STD_MODE;
+		} else if (_bounds.contains(mousePos)) {
+			// Mouse button was released inside the inventory window
+			_outsideMenu = false;
+		
+			//  See if they are pointing at one of the inventory items
+			if (_invSelect != -1) {
+				// See if they are in Use Obj with Inv. Mode (they right clicked on an item 
+				// in the room and selected "Use with Inv.")
+				if (_invMode == 1) {
+					_tooltipWidget.banishWindow();
+					banishWindow();
+
+					// See if the item in the room that they started with was a person
+					bool found = false;
+					if (ui._activeObj >= 1000) {
+						// Object was a person, activate anything in his two verb fields
+						for (int idx = 0; idx < 2; ++idx) {
+							if (!people[ui._activeObj - 1000]._use[idx]._target.compareToIgnoreCase(inv[_invSelect]._name)) {
+								ui.checkAction(people[ui._activeObj - 1000]._use[idx], ui._activeObj);
+								found = true;
+							}
+						}
+					} else {
+						// Object was a regular object, activate anything in its verb fields
+						for (int idx = 0; idx < 6; ++idx) {
+							if (!scene._bgShapes[ui._activeObj]._use[idx]._target.compareToIgnoreCase(inv[_invSelect]._name)) {
+								ui.checkAction(scene._bgShapes[ui._activeObj]._use[idx], ui._activeObj);
+								found = true;
+							}
+						}
+					}
+					if (!found)
+						ui.putMessage(S_NO_EFFECT);
+
+				} else {
+					// See if they right clicked on an item
+					if (events._rightReleased) {
+						_invVerbMode = 1;
+						_oldInvVerbSelect = -1;
+						_tooltipWidget.banishWindow();
+
+						// Keep track of the name of the inventory object so we can check it against the target fields 
+						// of verbs when we activate it
+						_invTarget = inv[_invSelect]._name;
+
+						// Make the Verb List for this Inventory Item
+						_inventCommands.clear();
+						_inventCommands.push_back(S_LOOK);
+
+						// Default the Action word to "with"
+						_action = _vm->getLanguage() == Common::GR_GRE ? "" : S_WITH;
+						_swapItems = false;
+
+						// Search all the bgshapes for any matching Target Fields
+						for (uint idx = 0; idx < scene._bgShapes.size(); ++idx) {
+							Object &obj = scene._bgShapes[idx];
+
+							if (obj._type != INVALID && obj._type != HIDDEN) {
+								for (int useNum = 0; useNum < 6; ++useNum) {
+									if (obj._use[useNum]._verb.hasPrefix("*") && 
+											!obj._use[useNum]._target.compareToIgnoreCase(inv[_invSelect]._name)) {
+										// Make sure the Verb is not already in the list
+										bool found1 = false;
+										for (uint cmdNum = 0; cmdNum < _inventCommands.size() && !found1; ++cmdNum) {
+											if (!_inventCommands[cmdNum].compareToIgnoreCase(obj._use[useNum]._verb))
+												found1 = true;
+										}
+
+										if (!found1) {
+											_inventCommands.push_back(obj._use[useNum]._verb);
+
+											// Check for any Special Action commands
+											for (int nameNum = 0; nameNum < 4; ++nameNum) {
+												if (!scumm_strnicmp(obj._use[useNum]._names[nameNum].c_str(), "*V", 2)) {
+													if (!scumm_strnicmp(obj._use[useNum]._names[nameNum].c_str(), "*VSWAP", 6))
+														_swapItems = true;
+													else
+														_action = Common::String(obj._use[useNum]._names[nameNum].c_str() + 2);
+												}
+											}
+										}
+									}
+								}
+							}
+						}
+
+						// Search the NPCs for matches as well
+						for (int idx = 1; idx < MAX_CHARACTERS; ++idx) {
+							for (int useNum = 0; useNum < 2; ++useNum) {
+								if (!people[idx]._use[useNum]._target.compareToIgnoreCase(inv[_invSelect]._name) &&
+										!people[idx]._use[useNum]._verb.empty() && !people[idx]._use[useNum]._verb.hasPrefix(" ")) {
+									bool found1 = false;
+									for (uint cmdNum = 0; cmdNum < _inventCommands.size() && !found1; ++cmdNum) {
+										if (!_inventCommands[cmdNum].compareToIgnoreCase(people[idx]._use[cmdNum]._verb))
+											found1 = true;
+									}
+
+									if (!found1)
+										_inventCommands.push_back(people[idx]._use[useNum]._verb);
+								}
+							}
+						}
+
+						// Finally see if the item itself has a verb
+						if (!inv[_invSelect]._verb._verb.empty()) {
+							// Don't add "Solve" to the Foolscap if it's already been "Solved"
+							if (inv[_invSelect]._verb._verb.compareToIgnoreCase(S_SOLVE) || !vm.readFlags(299))
+								_inventCommands.push_back(inv[_invSelect]._verb._verb);
+						}
+
+						// Now find the widest command in the _inventCommands array
+						int width = 0;
+						for (uint idx = 0; idx < _inventCommands.size(); ++idx)
+							width = MAX(width, _surface.stringWidth(_inventCommands[idx]));
+
+						// Set up bounds for the menu
+						_menuBounds = Common::Rect(width + _surface.widestChar() * 2 + 6,
+							(_surface.fontHeight() + 7) * _inventCommands.size() + 3);
+						_menuBounds.moveTo(mousePos.x + _menuBounds.width() / 2, mousePos.y + _menuBounds.height() / 2);
+
+						// Create the surface
+						_menuSurface.create(_menuBounds.width(), _menuBounds.height());
+						_surface.fill(TRANSPARENCY);
+						makeInfoArea(_menuSurface);
+
+						// Draw the Verb commands and the lines separating them
+						ImageFile &images = *_interfaceImages;
+						for (int idx = 0; idx < (int)_inventCommands.size(); ++idx) {
+							_menuSurface.writeString(_inventCommands[idx], Common::Point((_menuBounds.width() -
+								_menuSurface.stringWidth(_inventCommands[idx])) / 2, (_menuSurface.fontHeight() + 7) * idx + 5), INFO_TOP);
+
+							if (idx < (int)_inventCommands.size()- 1) {
+								_menuSurface.vLine(3, (_menuSurface.fontHeight() + 7) * (idx + 1), _menuBounds.right - 4, INFO_TOP);
+								_menuSurface.vLine(3, (_menuSurface.fontHeight() + 7) * (idx + 1) + 1, _menuBounds.right - 4, INFO_MIDDLE);
+								_menuSurface.vLine(3, (_menuSurface.fontHeight() + 7) * (idx + 1) + 2, _menuBounds.right - 4, INFO_BOTTOM);
+								
+								_menuSurface.transBlitFrom(images[4], Common::Point(0, (_menuSurface.fontHeight() + 7) * (idx + 1)));
+								_menuSurface.transBlitFrom(images[5], Common::Point(_menuBounds.width() - images[5]._width,
+									(_menuSurface.fontHeight() + 7) * (idx + 1) - 1));
+							}
+						}
+					} else {		
+						// They left clicked on an inventory item, so Look at it
+
+						// Check if they are looking at the solved Foolscap
+						if ((!inv[_invSelect]._name.compareToIgnoreCase(S_INV6) || !inv[_invSelect]._name.compareToIgnoreCase(S_INV7))
+								&& vm.readFlags(299)) {
+							banishWindow();
+							_tooltipWidget.erase();
+
+							_invVerbMode = 0;
+							inv.freeInv();
+							
+							events.clearEvents();
+							events.setCursor(ARROW);
+							ui._menuMode = scene._labTableScene ? LAB_MODE : STD_MODE;
+
+							scene.doBgAnim();
+							vm.doHangManPuzzle();
+						} else {
+							ui._invLookFlag = true;
+							inv.freeInv();
+
+							_tooltipWidget.banishWindow();
+							ui._windowOpen = false;
+							ui._lookPos = mousePos;
+							ui.printObjectDesc(inv[_invSelect]._examine, true);
+						}
+					}
+				}
+			}
+		}
+	}
+}
+
+void WidgetInventory::updateDescription() {
+
+}
+
+void WidgetInventory::checkInvTabbingKeys() {
+}
+
+void WidgetInventory::highlightControls() {
+	// TODO
+}
+
+void WidgetInventory::banishWindow() {
+	WidgetBase::banishWindow();
+
+	_menuSurface.free();
+	_menuBounds = _oldMenuBounds = Common::Rect(0, 0, 0, 0);
+}
 
 } // End of namespace Tattoo
 
diff --git a/engines/sherlock/tattoo/widget_inventory.h b/engines/sherlock/tattoo/widget_inventory.h
index 34e25ee..29bcdaa 100644
--- a/engines/sherlock/tattoo/widget_inventory.h
+++ b/engines/sherlock/tattoo/widget_inventory.h
@@ -25,6 +25,7 @@
 
 #include "common/scummsys.h"
 #include "sherlock/tattoo/widget_base.h"
+#include "sherlock/tattoo/widget_tooltip.h"
 
 namespace Sherlock {
 
@@ -37,7 +38,19 @@ private:
 	int _invVerbMode;
 	int _invSelect, _oldInvSelect;
 	int _selector, _oldSelector;
+	int _invVerbSelect, _oldInvVerbSelect;
 	int _dialogTimer;
+	int _scrollHighlight;
+	Common::StringArray _inventCommands;
+	WidgetTooltip _tooltipWidget;
+	Common::String _invVerb;
+	Common::String _invTarget;
+	Common::String _action;
+	Common::Rect _invGraphicBounds;
+	Surface _invGraphic;
+	bool _swapItems;
+	Common::Rect _menuBounds, _oldMenuBounds;
+	Surface _menuSurface;
 
 	/**
 	 * Draw the scrollbar for the dialog
@@ -48,6 +61,21 @@ private:
 	 * Draws all the dialog rectangles for any items that need them
 	 */
 	void drawDialogRect(const Common::Rect &r, bool raised);
+
+	/**
+	 * Displays the description of any inventory item the moues cursor is over
+	 */
+	void updateDescription();
+
+	/**
+	 * Check for keys to mouse the mouse within the inventory dialog
+	 */
+	void checkInvTabbingKeys();
+
+	/**
+	 * Highlights the controls
+	 */
+	void highlightControls();
 public:
 	int _invMode;
 public:
@@ -60,6 +88,16 @@ public:
 	 * Draw the inventory on the surface
 	 */
 	void drawInventory();
+
+	/**
+	 * Handle events whilst the widget is on-screen
+	 */
+	virtual void handleEvents();
+
+	/**
+	 * Close a currently active menu
+	 */
+	virtual void banishWindow();
 };
 
 } // End of namespace Tattoo
diff --git a/engines/sherlock/tattoo/widget_verbs.cpp b/engines/sherlock/tattoo/widget_verbs.cpp
index dfe317b..9cf4794 100644
--- a/engines/sherlock/tattoo/widget_verbs.cpp
+++ b/engines/sherlock/tattoo/widget_verbs.cpp
@@ -230,10 +230,6 @@ void WidgetVerbs::execute() {
 	}
 }
 
-void WidgetVerbs::checkTabbingKeys(int numOptions) {
-	// TODO
-}
-
 void WidgetVerbs::highlightVerbControls() {
 	Events &events = *_vm->_events;
 	Screen &screen = *_vm->_screen;
diff --git a/engines/sherlock/tattoo/widget_verbs.h b/engines/sherlock/tattoo/widget_verbs.h
index 82b9325..fa41b3e 100644
--- a/engines/sherlock/tattoo/widget_verbs.h
+++ b/engines/sherlock/tattoo/widget_verbs.h
@@ -58,8 +58,6 @@ public:
 	 * Process input for the dialog
 	 */
 	void execute();
-
-	void checkTabbingKeys(int numOptions);
 };
 
 } // End of namespace Tattoo






More information about the Scummvm-git-logs mailing list