diff options
-rw-r--r-- | engines/sci/engine/kevent.cpp | 14 | ||||
-rw-r--r-- | engines/sci/engine/kmisc.cpp | 19 | ||||
-rw-r--r-- | engines/sci/engine/selector.cpp | 1 | ||||
-rw-r--r-- | engines/sci/engine/selector.h | 1 | ||||
-rw-r--r-- | engines/sci/graphics/cursor.cpp | 3 | ||||
-rw-r--r-- | engines/sci/graphics/maciconbar.cpp | 150 | ||||
-rw-r--r-- | engines/sci/graphics/maciconbar.h | 15 |
7 files changed, 170 insertions, 33 deletions
diff --git a/engines/sci/engine/kevent.cpp b/engines/sci/engine/kevent.cpp index 2540861a93..725b78341b 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 0061f3aa1c..723aece819 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 798dbf529c..957a836e3e 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 6038ad0c36..8a47984204 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 9d1c3dabd6..3b95a5c955 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 f0931e0121..6cf4f269a7 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 0db9454eb7..3ac5475147 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 |