[Scummvm-cvs-logs] scummvm master -> 952d1a084c851a33d8094e384f80890141d63157

waltervn waltervn at users.sourceforge.net
Wed Mar 9 21:44:02 CET 2011


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:
952d1a084c SCI: Implement Mac iconbar event handling.


Commit: 952d1a084c851a33d8094e384f80890141d63157
    https://github.com/scummvm/scummvm/commit/952d1a084c851a33d8094e384f80890141d63157
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2011-03-09T12:05:19-08:00

Commit Message:
SCI: Implement Mac iconbar event handling.

Changed paths:
    engines/sci/engine/kevent.cpp
    engines/sci/engine/kmisc.cpp
    engines/sci/engine/selector.cpp
    engines/sci/engine/selector.h
    engines/sci/graphics/cursor.cpp
    engines/sci/graphics/maciconbar.cpp
    engines/sci/graphics/maciconbar.h



diff --git a/engines/sci/engine/kevent.cpp b/engines/sci/engine/kevent.cpp
index 2540861..725b783 100644
--- a/engines/sci/engine/kevent.cpp
+++ b/engines/sci/engine/kevent.cpp
@@ -35,6 +35,7 @@
 #include "sci/event.h"
 #include "sci/graphics/coordadjuster.h"
 #include "sci/graphics/cursor.h"
+#include "sci/graphics/maciconbar.h"
 
 namespace Sci {
 
@@ -46,6 +47,13 @@ reg_t kGetEvent(EngineState *s, int argc, reg_t *argv) {
 	SegManager *segMan = s->_segMan;
 	Common::Point mousePos;
 
+	// For Mac games with an icon bar, handle possible icon bar events first
+	if (g_sci->hasMacIconBar()) {
+		reg_t iconObj = g_sci->_gfxMacIconBar->handleEvents();
+		if (!iconObj.isNull())
+			invokeSelector(s, iconObj, SELECTOR(select), argc, argv, 0, NULL);
+	}
+
 	// If there's a simkey pending, and the game wants a keyboard event, use the
 	// simkey instead of a normal event
 	if (g_debug_simulated_key && (mask & SCI_EVENT_KEYBOARD)) {
@@ -145,7 +153,11 @@ reg_t kGetEvent(EngineState *s, int argc, reg_t *argv) {
 		break;
 
 	default:
-		s->r_acc = NULL_REG; // Unknown or no event
+		// Return a null event
+		writeSelectorValue(segMan, obj, SELECTOR(type), SCI_EVENT_NONE);
+		writeSelectorValue(segMan, obj, SELECTOR(message), 0);
+		writeSelectorValue(segMan, obj, SELECTOR(modifiers), curEvent.modifiers & modifier_mask);
+		s->r_acc = NULL_REG;
 	}
 
 	if ((s->r_acc.offset) && (g_sci->_debugState.stopOnEvent)) {
diff --git a/engines/sci/engine/kmisc.cpp b/engines/sci/engine/kmisc.cpp
index 0061f3a..723aece 100644
--- a/engines/sci/engine/kmisc.cpp
+++ b/engines/sci/engine/kmisc.cpp
@@ -359,23 +359,22 @@ reg_t kIconBar(EngineState *s, int argc, reg_t *argv) {
 	case 0: // InitIconBar
 		for (int i = 0; i < argv[1].toUint16(); i++)
 			g_sci->_gfxMacIconBar->addIcon(argv[i + 2]);
-
-		// TODO: Should return icon bar handle
-		// Said handle is then used by DisposeIconBar
 		break;
 	case 1: // DisposeIconBar
 		warning("kIconBar(Dispose)");
 		break;
-	case 2: // EnableIconBar (0xffff = all)
-		debug(0, "kIconBar(Enable, %d)", argv[1].toUint16());
-		g_sci->_gfxMacIconBar->setIconEnabled(argv[1].toUint16(), true);
+	case 2: // EnableIconBar (-1 = all)
+		debug(0, "kIconBar(Enable, %i)", argv[1].toSint16());
+		g_sci->_gfxMacIconBar->setIconEnabled(argv[1].toSint16(), true);
 		break;
-	case 3: // DisableIconBar (0xffff = all)
-		debug(0, "kIconBar(Disable, %d)", argv[1].toUint16());
-		g_sci->_gfxMacIconBar->setIconEnabled(argv[1].toUint16(), false);
+	case 3: // DisableIconBar (-1 = all)
+		debug(0, "kIconBar(Disable, %i)", argv[1].toSint16());
+		g_sci->_gfxMacIconBar->setIconEnabled(argv[1].toSint16(), false);
 		break;
 	case 4: // SetIconBarIcon
-		warning("kIconBar(SetIcon, %d, %d)", argv[1].toUint16(), argv[2].toUint16());
+		debug(0, "kIconBar(SetIcon, %d, %d)", argv[1].toUint16(), argv[2].toUint16());
+		if (argv[2].toSint16() == -1)
+			g_sci->_gfxMacIconBar->setInventoryIcon(argv[2].toSint16());
 		break;
 	default:
 		error("Unknown kIconBar(%d)", argv[0].toUint16());
diff --git a/engines/sci/engine/selector.cpp b/engines/sci/engine/selector.cpp
index 798dbf5..957a836 100644
--- a/engines/sci/engine/selector.cpp
+++ b/engines/sci/engine/selector.cpp
@@ -165,6 +165,7 @@ void Kernel::mapSelectors() {
 	FIND_SELECTOR(vanishingX);
 	FIND_SELECTOR(vanishingY);
 	FIND_SELECTOR(iconIndex);
+	FIND_SELECTOR(select);
 
 #ifdef ENABLE_SCI32
 	FIND_SELECTOR(data);
diff --git a/engines/sci/engine/selector.h b/engines/sci/engine/selector.h
index 6038ad0..8a47984 100644
--- a/engines/sci/engine/selector.h
+++ b/engines/sci/engine/selector.h
@@ -130,6 +130,7 @@ struct SelectorCache {
 
 	// SCI1.1 Mac icon bar selectors
 	Selector iconIndex; ///< Used to index icon bar objects
+	Selector select;
 
 #ifdef ENABLE_SCI32
 	Selector data; // Used by Array()/String()
diff --git a/engines/sci/graphics/cursor.cpp b/engines/sci/graphics/cursor.cpp
index 9d1c3da..3b95a5c 100644
--- a/engines/sci/graphics/cursor.cpp
+++ b/engines/sci/graphics/cursor.cpp
@@ -39,6 +39,7 @@
 #include "sci/graphics/coordadjuster.h"
 #include "sci/graphics/view.h"
 #include "sci/graphics/cursor.h"
+#include "sci/graphics/maciconbar.h"
 
 namespace Sci {
 
@@ -444,6 +445,8 @@ void GfxCursor::kernelSetMacCursor(GuiResourceId viewNum, int loopNum, int celNu
 			else                     // Unknown cursor, ignored
 				return;
 		}
+		if (g_sci->hasMacIconBar())
+			g_sci->_gfxMacIconBar->setInventoryIcon(viewNum);
 	} else {
 		// If we do have the list, we'll be using a remap based on what the
 		// scripts have given us.
diff --git a/engines/sci/graphics/maciconbar.cpp b/engines/sci/graphics/maciconbar.cpp
index f0931e0..6cf4f26 100644
--- a/engines/sci/graphics/maciconbar.cpp
+++ b/engines/sci/graphics/maciconbar.cpp
@@ -27,6 +27,7 @@
 #include "sci/engine/kernel.h"
 #include "sci/engine/selector.h"
 #include "sci/engine/state.h"
+#include "sci/event.h"
 #include "sci/graphics/maciconbar.h"
 #include "sci/graphics/palette.h"
 #include "sci/graphics/screen.h"
@@ -40,9 +41,22 @@ namespace Sci {
 
 GfxMacIconBar::GfxMacIconBar() {
 	_lastX = 0;
+
+	if (g_sci->getGameId() == GID_FREDDYPHARKAS)
+		_inventoryIndex = 5;
+	else
+		_inventoryIndex = 4;
+
+	_inventoryIcon = 0;
+	_allDisabled = true;
 }
 
 GfxMacIconBar::~GfxMacIconBar() {
+	if (_inventoryIcon) {
+		_inventoryIcon->free();
+		delete _inventoryIcon;
+	}
+
 	for (uint32 i = 0; i < _iconBarItems.size(); i++) {
 		if (_iconBarItems[i].nonSelectedImage) {
 			_iconBarItems[i].nonSelectedImage->free();
@@ -62,7 +76,12 @@ void GfxMacIconBar::addIcon(reg_t obj) {
 
 	item.object = obj;
 	item.nonSelectedImage = createImage(iconIndex, false);
-	item.selectedImage = createImage(iconIndex, true);
+
+	if (iconIndex != _inventoryIndex)
+		item.selectedImage = createImage(iconIndex, true);
+	else
+		item.selectedImage = 0;
+
 	item.enabled = true;
 
 	// Start after the main viewing window and add a two pixel buffer
@@ -82,17 +101,33 @@ void GfxMacIconBar::drawIcons() {
 	// Draw the icons to the bottom of the screen
 
 	for (uint32 i = 0; i < _iconBarItems.size(); i++)
-		redrawIcon(i);
+		drawIcon(i, false);
 }
 
-void GfxMacIconBar::redrawIcon(uint16 iconIndex) {
+void GfxMacIconBar::drawIcon(uint16 iconIndex, bool selected) {
 	if (iconIndex >= _iconBarItems.size())
 		return;
 
-	if (_iconBarItems[iconIndex].enabled)
-		drawEnabledImage(_iconBarItems[iconIndex].nonSelectedImage, _iconBarItems[iconIndex].rect);
-	else
-		drawDisabledImage(_iconBarItems[iconIndex].nonSelectedImage, _iconBarItems[iconIndex].rect);
+	Common::Rect rect = _iconBarItems[iconIndex].rect;
+
+	if (isIconEnabled(iconIndex)) {
+		if (selected)
+			drawEnabledImage(_iconBarItems[iconIndex].selectedImage, rect);
+		else
+			drawEnabledImage(_iconBarItems[iconIndex].nonSelectedImage, rect);
+	} else
+		drawDisabledImage(_iconBarItems[iconIndex].nonSelectedImage, rect);
+
+	if ((iconIndex == _inventoryIndex) && _inventoryIcon) {
+		Common::Rect invRect = Common::Rect(0, 0, _inventoryIcon->w, _inventoryIcon->h);
+		invRect.moveTo(rect.left, rect.top);
+		invRect.translate((rect.width() - invRect.width()) / 2, (rect.height() - invRect.height()) / 2);
+
+		if (isIconEnabled(iconIndex))
+			drawEnabledImage(_inventoryIcon, invRect);
+		else
+			drawDisabledImage(_inventoryIcon, invRect);
+	}
 }
 
 void GfxMacIconBar::drawEnabledImage(Graphics::Surface *surface, const Common::Rect &rect) {
@@ -128,30 +163,49 @@ void GfxMacIconBar::drawDisabledImage(Graphics::Surface *surface, const Common::
 void GfxMacIconBar::drawSelectedImage(uint16 iconIndex) {
 	assert(iconIndex <= _iconBarItems.size());
 
-	// TODO
+	drawEnabledImage(_iconBarItems[iconIndex].selectedImage, _iconBarItems[iconIndex].rect);
 }
 
 bool GfxMacIconBar::isIconEnabled(uint16 iconIndex) const {
 	if (iconIndex >= _iconBarItems.size())
 		return false;
 
-	return _iconBarItems[iconIndex].enabled;
+	return !_allDisabled && _iconBarItems[iconIndex].enabled;
 }
 
-void GfxMacIconBar::setIconEnabled(uint16 iconIndex, bool enabled) {
-	if (iconIndex == 0xffff) {
-		for (uint32 i = 0; i < _iconBarItems.size(); i++)
-			_iconBarItems[i].enabled = enabled;
-	} else if (iconIndex < _iconBarItems.size()) {
+void GfxMacIconBar::setIconEnabled(int16 iconIndex, bool enabled) {
+	if (iconIndex < 0)
+		_allDisabled = !enabled;
+	else if (iconIndex < (int)_iconBarItems.size()) {
 		_iconBarItems[iconIndex].enabled = enabled;
 	}
 }
 
-Graphics::Surface *GfxMacIconBar::createImage(uint32 iconIndex, bool isSelected) {
-	Graphics::PictDecoder pictDecoder(Graphics::PixelFormat::createFormatCLUT8());
-	ResourceType type = isSelected ? kResourceTypeMacIconBarPictS : kResourceTypeMacIconBarPictN;
+void GfxMacIconBar::setInventoryIcon(int16 icon) {
+	Graphics::Surface *surface = 0;
+
+	if (icon >= 0)
+		surface = loadPict(ResourceId(kResourceTypeMacPict, icon));
+
+	if (_inventoryIcon) {
+		// Free old inventory icon if we're removing the inventory icon
+		// or setting a new one.
+		if ((icon < 0) || surface) {
+			_inventoryIcon->free();
+			delete _inventoryIcon;
+			_inventoryIcon = 0;
+		}
+	}
 
-	Resource *res = g_sci->getResMan()->findResource(ResourceId(type, iconIndex + 1), false);
+	if (surface)
+		_inventoryIcon = surface;
+
+	drawIcon(_inventoryIndex, false);
+}
+
+Graphics::Surface *GfxMacIconBar::loadPict(ResourceId id) {
+	Graphics::PictDecoder pictDecoder(Graphics::PixelFormat::createFormatCLUT8());
+	Resource *res = g_sci->getResMan()->findResource(id, false);
 
 	if (!res || res->size == 0)
 		return 0;
@@ -165,6 +219,11 @@ Graphics::Surface *GfxMacIconBar::createImage(uint32 iconIndex, bool isSelected)
 	return surface;
 }
 
+Graphics::Surface *GfxMacIconBar::createImage(uint32 iconIndex, bool isSelected) {
+	ResourceType type = isSelected ? kResourceTypeMacIconBarPictS : kResourceTypeMacIconBarPictN;
+	return loadPict(ResourceId(type, iconIndex + 1));
+}
+
 void GfxMacIconBar::remapColors(Graphics::Surface *surf, byte *palette) {
 	byte *pixels = (byte *)surf->pixels;
 
@@ -180,4 +239,59 @@ void GfxMacIconBar::remapColors(Graphics::Surface *surf, byte *palette) {
 	}
 }
 
+bool GfxMacIconBar::pointOnIcon(uint32 iconIndex, Common::Point point) {
+	return _iconBarItems[iconIndex].rect.contains(point);
+}
+
+reg_t GfxMacIconBar::handleEvents() {
+	// Peek event queue for a mouse button press
+	EventManager *evtMgr = g_sci->getEventManager();
+	SciEvent evt = evtMgr->getSciEvent(SCI_EVENT_MOUSE_PRESS | SCI_EVENT_PEEK);
+
+	// No mouse press found
+	if (evt.type == SCI_EVENT_NONE)
+		return NULL_REG;
+
+	// If the mouse is not over the icon bar, return
+	if (evt.mousePos.y < g_sci->_gfxScreen->getHeight())
+		return NULL_REG;
+
+	// Remove event from queue
+	evtMgr->getSciEvent(SCI_EVENT_MOUSE_PRESS);
+
+	// Mouse press on the icon bar, check the icon rectangles
+	uint iconNr;
+	for (iconNr = 0; iconNr < _iconBarItems.size(); iconNr++) {
+		if (pointOnIcon(iconNr, evt.mousePos) && isIconEnabled(iconNr))
+			break;
+	}
+
+	// Mouse press not on an icon
+	if (iconNr == _iconBarItems.size())
+		return NULL_REG;
+
+	drawIcon(iconNr, true);
+	bool isSelected = true;
+
+	// Wait for mouse release
+	while (evt.type != SCI_EVENT_MOUSE_RELEASE) {
+		// Mimic behavior of SSCI when moving mouse with button held down
+		if (isSelected != pointOnIcon(iconNr, evt.mousePos)) {
+			isSelected = !isSelected;
+			drawIcon(iconNr, isSelected);
+		}
+
+		evt = evtMgr->getSciEvent(SCI_EVENT_MOUSE_RELEASE);
+		g_system->delayMillis(10);
+	}
+
+	drawIcon(iconNr, false);
+
+	// If user moved away from the icon, we do nothing
+	if (pointOnIcon(iconNr, evt.mousePos))
+		return _iconBarItems[iconNr].object;
+
+	return NULL_REG;
+}
+
 } // End of namespace Sci
diff --git a/engines/sci/graphics/maciconbar.h b/engines/sci/graphics/maciconbar.h
index 0db9454..3ac5475 100644
--- a/engines/sci/graphics/maciconbar.h
+++ b/engines/sci/graphics/maciconbar.h
@@ -43,10 +43,9 @@ public:
 
 	void addIcon(reg_t obj);
 	void drawIcons();
-	void redrawIcon(uint16 index);
-	void drawSelectedImage(uint16 index);
-	bool isIconEnabled(uint16 index) const;
-	void setIconEnabled(uint16 index, bool enabled);
+	void setIconEnabled(int16 index, bool enabled);
+	void setInventoryIcon(int16 icon);
+	reg_t handleEvents();
 
 private:
 	struct IconBarItem {
@@ -59,12 +58,20 @@ private:
 
 	Common::Array<IconBarItem> _iconBarItems;
 	uint32 _lastX;
+	uint16 _inventoryIndex;
+	Graphics::Surface *_inventoryIcon;
+	bool _allDisabled;
 
+	Graphics::Surface *loadPict(ResourceId id);
 	Graphics::Surface *createImage(uint32 iconIndex, bool isSelected);
 	void remapColors(Graphics::Surface *surf, byte *palette);
 
+	void drawIcon(uint16 index, bool selected);
+	void drawSelectedImage(uint16 index);
+	bool isIconEnabled(uint16 index) const;
 	void drawEnabledImage(Graphics::Surface *surface, const Common::Rect &rect);
 	void drawDisabledImage(Graphics::Surface *surface, const Common::Rect &rect);
+	bool pointOnIcon(uint32 iconIndex, Common::Point point);
 };
 
 } // End of namespace Sci






More information about the Scummvm-git-logs mailing list