diff options
author | Matthew Hoops | 2011-09-22 14:50:24 -0400 |
---|---|---|
committer | Matthew Hoops | 2011-09-22 14:50:24 -0400 |
commit | 897c585f05b30d7431541f774383ace8f8f5201a (patch) | |
tree | 77e7565398f577df51c5414343acdc5addcbbefd | |
parent | 3417e39c7a7452f00c1f6d712e9fe04f4feba431 (diff) | |
download | scummvm-rg350-897c585f05b30d7431541f774383ace8f8f5201a.tar.gz scummvm-rg350-897c585f05b30d7431541f774383ace8f8f5201a.tar.bz2 scummvm-rg350-897c585f05b30d7431541f774383ace8f8f5201a.zip |
PEGASUS: Add the InventoryPicture class (and its derivatives)
-rwxr-xr-x | engines/pegasus/items/inventorypicture.cpp | 367 | ||||
-rwxr-xr-x | engines/pegasus/items/inventorypicture.h | 125 | ||||
-rw-r--r-- | engines/pegasus/module.mk | 1 | ||||
-rw-r--r-- | engines/pegasus/pegasus.cpp | 11 | ||||
-rw-r--r-- | engines/pegasus/pegasus.h | 1 |
5 files changed, 501 insertions, 4 deletions
diff --git a/engines/pegasus/items/inventorypicture.cpp b/engines/pegasus/items/inventorypicture.cpp new file mode 100755 index 0000000000..5c8010b297 --- /dev/null +++ b/engines/pegasus/items/inventorypicture.cpp @@ -0,0 +1,367 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * Additional copyright for this file: + * Copyright (C) 1995-1997 Presto Studios, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#include "pegasus/pegasus.h" +#include "pegasus/transition.h" +#include "pegasus/items/inventorypicture.h" +#include "pegasus/items/biochips/biochipitem.h" +#include "pegasus/items/inventory/inventoryitem.h" + +namespace Pegasus { + +InventoryPicture::InventoryPicture(const tDisplayElementID id, InputHandler *nextHandler, Inventory *inventory) : + InputHandler(nextHandler), Picture(id), _panelMovie(kNoDisplayElement){ + _inventory = inventory; + _lastReferenceCount = 0xffffffff; + + if (_inventory->getNumItems() > 0) { + _currentItemIndex = 0; + _currentItem = (Item *)_inventory->getItemAt(0); + } else { + _currentItemIndex = -1; + _currentItem = 0; + } + + _active = false; + _shouldDrawHighlight = true; + _itemsPerRow = 1; + _numberOfRows = 1; + _itemWidth = 0; + _itemHeight = 0; + _itemX = 0; + _itemY = 0; +} + +void InventoryPicture::initInventoryImage(Transition *transition) { + initFromPICTFile(_pictName, true); + _panelMovie.shareSurface(this); + _panelMovie.initFromMovieFile(_movieName); + _panelMovie.getBounds(_highlightBounds); + _panelMovie.setTriggeredElement(transition); + _highlightImage.initFromPICTFile(_highlightName, true); +} + +void InventoryPicture::throwAwayInventoryImage() { + if (isSurfaceValid()) { + _panelMovie.releaseMovie(); + _highlightImage.deallocateSurface(); + deallocateSurface(); + } +} + +void InventoryPicture::getItemXY(uint32 index, tCoordType &x, tCoordType &y) { + x = (index % _itemsPerRow) * _itemWidth + _itemX; + y = (index / _itemsPerRow) * _itemHeight + _itemY; +} + +void InventoryPicture::drawItemHighlight(const Common::Rect &r) { + if (_highlightImage.isSurfaceValid()) { + Common::Rect r2 = _highlightBounds; + Common::Rect bounds; + getBounds(bounds); + + r2.translate(bounds.left, bounds.top); + r2 = r2.findIntersectingRect(r); + if (!r2.isEmpty()) { + Common::Rect r1 = r2; + r1.translate(-bounds.left - _highlightBounds.left, -bounds.top - _highlightBounds.top); + _highlightImage.drawImage(r1, r2); + } + } +} + +void InventoryPicture::draw(const Common::Rect &r) { + Picture::draw(r); + if (_inventory->getNumItems() != 0 && _shouldDrawHighlight) + drawItemHighlight(r); +} + +// Assumes index >= 0. +void InventoryPicture::setCurrentItemIndex(int32 index) { + if (index >= _inventory->getNumItems()) + index = _inventory->getNumItems() - 1; + + Item *currentItem = 0; + if (index >= 0) + currentItem = (Item *)_inventory->getItemAt(index); + + if (currentItem != _currentItem) { + if (_currentItem) { + if (_currentItem->isSelected()) + _currentItem->deselect(); + + if (_active) + unhighlightCurrentItem(); + } + + _currentItemIndex = index; + _currentItem = currentItem; + if (_currentItem) { + _currentItem->select(); + + if (_active) + highlightCurrentItem(); + } + + if (_active) + triggerRedraw(); + } +} + +void InventoryPicture::setCurrentItemID(tItemID id) { + int32 index = _inventory->findIndexOf(id); + if (index >= 0) + setCurrentItemIndex(index); +} + +tInventoryResult InventoryPicture::addInventoryItem(Item *item) { + tInventoryResult result = _inventory->addItem(item); + + if (result == kInventoryOK) + setCurrentItemIndex(_inventory->findIndexOf(item)); + + return result; +} + +tInventoryResult InventoryPicture::removeInventoryItem(Item *item) { + tInventoryResult result = _inventory->removeItem(item); + + if (result == kInventoryOK) + setCurrentItemIndex(getCurrentItemIndex()); + + return result; +} + +void InventoryPicture::removeAllItems() { + _inventory->removeAllItems(); + setCurrentItemIndex(0); +} + +bool InventoryPicture::itemInInventory(Item *item) { + return _inventory->itemInInventory(item); +} + +bool InventoryPicture::itemInInventory(const tItemID id) { + return _inventory->itemInInventory(id); +} + +void InventoryPicture::panelUp() { + allowInput(true); +} + +// Must ensure that the picture matches the _inventory member variable. +void InventoryPicture::activateInventoryPicture() { + if (_active) + return; + + allowInput(false); + + if (_lastReferenceCount != _inventory->getReferenceCount()) { + uint32 numItems = _inventory->getNumItems(); + + tCoordType x, y; + getItemXY(0, x, y); + _panelMovie.moveElementTo(x, y); + _panelMovie.show(); + + for (uint32 i = 0; i < numItems; i++) { + Item *item = (Item *)_inventory->getItemAt(i); + if (item == _currentItem) + item->select(); + + getItemXY(i, x, y); + _panelMovie.moveElementTo(x, y); + _panelMovie.setTime(getItemPanelTime(item)); + _panelMovie.redrawMovieWorld(); + } + + _panelMovie.setTime(0); + uint32 numSlots = _itemsPerRow * _numberOfRows; + + for (uint32 i = numItems; i < numSlots; i++) { + getItemXY(i, x, y); + _panelMovie.moveElementTo(x, y); + _panelMovie.redrawMovieWorld(); + } + + _lastReferenceCount = _inventory->getReferenceCount(); + } + + show(); // *** Do we really need this? + if (_currentItem) + highlightCurrentItem(); + + _active = true; +} + +void InventoryPicture::deactivateInventoryPicture() { + if (!_active) + return; + + _active = false; + allowInput(false); + _panelMovie.hide(); + hide(); + + if (_inventory->getNumItems() != 0) + if (!_currentItem->isActive()) + _currentItem->activate(); +} + +void InventoryPicture::handleInput(const Input &input, const Hotspot *cursorSpot) { + if (_active) { + if (input.upButtonDown()) { + if (_currentItemIndex - _itemsPerRow >= 0) + setCurrentItemIndex(_currentItemIndex - _itemsPerRow); + } else if (input.downButtonDown()) { + if (_currentItemIndex + _itemsPerRow < _inventory->getNumItems()) + setCurrentItemIndex(_currentItemIndex + _itemsPerRow); + } else if (input.leftButtonDown()) { + if ((_currentItemIndex % _itemsPerRow) != 0) + setCurrentItemIndex(_currentItemIndex - 1); + } else if (input.rightButtonDown()) { + if (((_currentItemIndex + 1) % _itemsPerRow) != 0 && _currentItemIndex + 1 < _inventory->getNumItems()) + setCurrentItemIndex(_currentItemIndex + 1); + } + } + + InputHandler::handleInput(input, cursorSpot); +} + +void InventoryPicture::highlightCurrentItem() { + tCoordType x, y; + getItemXY(_currentItemIndex, x, y); + _highlightBounds.moveTo(x, y); +} + +InventoryItemsPicture::InventoryItemsPicture(const tDisplayElementID id, InputHandler *nextHandler, Inventory *inventory) : + InventoryPicture(id, nextHandler, inventory) { + _pictName = "Images/Items/Inventory/Inventory Panel"; + _movieName = "Images/Items/Inventory/Inventory Panel Movie"; + _highlightName = "Images/Items/Inventory/Inventory Hilite"; + + _itemsPerRow = 3; + _numberOfRows = 3; + _itemWidth = 88; + _itemHeight = 64; + _itemX = 8; + _itemY = 26; + _isLooping = true; +} + +void InventoryItemsPicture::loopCurrentItem() { + if (_isLooping) { + tCoordType x, y; + getItemXY(_currentItemIndex, x, y); + _panelMovie.moveElementTo(x, y); + _highlightBounds.moveTo(x, y); + + TimeValue start, stop; + ((InventoryItem *)_currentItem)->getPanelTimes(start, stop); + _panelMovie.stop(); + _panelMovie.setFlags(0); + _panelMovie.setSegment(start, stop); + _panelMovie.setFlags(kLoopTimeBase); + _panelMovie.setTime(((InventoryItem *)_currentItem)->getAnimationTime()); + _panelMovie.start(); + } +} + +void InventoryItemsPicture::highlightCurrentItem() { + InventoryPicture::highlightCurrentItem(); + loopCurrentItem(); +} + +void InventoryItemsPicture::unhighlightCurrentItem() { + InventoryPicture::unhighlightCurrentItem(); + _panelMovie.stop(); + _panelMovie.setFlags(0); + ((InventoryItem *)_currentItem)->setAnimationTime(_panelMovie.getTime()); +} + +TimeValue InventoryItemsPicture::getItemPanelTime(Item *item) { + TimeValue start, stop; + ((InventoryItem *)item)->getPanelTimes(start, stop); + ((InventoryItem *)item)->setAnimationTime(start); + return start; +} + +void InventoryItemsPicture::deactivateInventoryPicture() { + if (_active) { + InventoryPicture::deactivateInventoryPicture(); + _panelMovie.stop(); + _panelMovie.setFlags(0); + _panelMovie.setSegment(0, _panelMovie.getDuration()); + _isLooping = true; + } +} + +void InventoryItemsPicture::playEndMessage(DisplayElement *pushElement) { + Movie endMessage(0); + + _shouldDrawHighlight = false; + endMessage.shareSurface(this); + endMessage.initFromMovieFile("Images/Caldoria/A56 Congrats"); + endMessage.moveElementTo(kFinalMessageLeft - kInventoryPushLeft, kFinalMessageTop - kInventoryPushTop); + endMessage.setTriggeredElement(pushElement); + endMessage.start(); + + while (endMessage.isRunning()) { + ((PegasusEngine *)g_engine)->refreshDisplay(); + g_system->delayMillis(10); + } + + endMessage.stop(); +} + +BiochipPicture::BiochipPicture(const tDisplayElementID id, InputHandler *nextHandler, Inventory *inventory) : + InventoryPicture(id, nextHandler, inventory) { + _pictName = "Images/Items/Biochips/Biochip Panel"; + _movieName = "Images/Items/Biochips/Biochip Panel Movie"; + _highlightName = "Images/Items/Biochips/BioChip Hilite"; + + _itemsPerRow = 4; + _numberOfRows = 2; + _itemWidth = 46; + _itemHeight = 46; + _itemX = 4; + _itemY = 24; +} + +void BiochipPicture::unhighlightCurrentItem() { + InventoryPicture::unhighlightCurrentItem(); + tCoordType x, y; + getItemXY(_currentItemIndex, x, y); + _panelMovie.show(); + _panelMovie.moveElementTo(x, y); + _panelMovie.setTime(getItemPanelTime(_currentItem)); + _panelMovie.redrawMovieWorld(); +} + +TimeValue BiochipPicture::getItemPanelTime(Item *item) { + return ((BiochipItem *)item)->getPanelTime(); +} + +} // End of namespace Pegasus diff --git a/engines/pegasus/items/inventorypicture.h b/engines/pegasus/items/inventorypicture.h new file mode 100755 index 0000000000..034354df09 --- /dev/null +++ b/engines/pegasus/items/inventorypicture.h @@ -0,0 +1,125 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * Additional copyright for this file: + * Copyright (C) 1995-1997 Presto Studios, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifndef PEGASUS_ITEMS_INVENTORYPICTURE_H +#define PEGASUS_ITEMS_INVENTORYPICTURE_H + +#include "pegasus/input.h" +#include "pegasus/movie.h" +#include "pegasus/surface.h" + +namespace Pegasus { + +class Inventory; +class Item; +class Input; +class Transition; + +class InventoryPicture : public InputHandler, public Picture { +public: + InventoryPicture(const tDisplayElementID, InputHandler *, Inventory *); + virtual ~InventoryPicture() {} + + void initInventoryImage(Transition *); + void throwAwayInventoryImage(); + + void panelUp(); + void activateInventoryPicture(); + void deactivateInventoryPicture(); + void handleInput(const Input &, const Hotspot *); + bool wantsCursor() { return false; } + + tInventoryResult addInventoryItem(Item *); + tInventoryResult removeInventoryItem(Item *); + void removeAllItems(); + Item *getCurrentItem() { return _currentItem; } + void setCurrentItemIndex(int32); + void setCurrentItemID(tItemID); + int32 getCurrentItemIndex() { return _currentItemIndex; } + bool itemInInventory(Item *); + bool itemInInventory(const tItemID); + +protected: + void getItemXY(uint32, tCoordType &, tCoordType &); + void draw(const Common::Rect &); + void drawItemHighlight(const Common::Rect &); + virtual void highlightCurrentItem(); + virtual void unhighlightCurrentItem() {} + virtual TimeValue getItemPanelTime(Item *) = 0; + + Inventory *_inventory; + uint32 _lastReferenceCount; + Frame _highlightImage; + Movie _panelMovie; + int32 _currentItemIndex; + Item *_currentItem; + Common::Rect _highlightBounds; + bool _active, _shouldDrawHighlight; + + Common::String _pictName; + Common::String _movieName; + Common::String _highlightName; + uint16 _itemsPerRow; + uint16 _numberOfRows; + uint16 _itemWidth; + uint16 _itemHeight; + uint16 _itemX; + uint16 _itemY; +}; + +class InventoryItemsPicture : public InventoryPicture { +public: + InventoryItemsPicture(const tDisplayElementID, InputHandler *, Inventory *); + virtual ~InventoryItemsPicture() {} + + void deactivateInventoryPicture(); + + void disableLooping() { _isLooping = false; } + + void playEndMessage(DisplayElement *); + +protected: + virtual void highlightCurrentItem(); + virtual void unhighlightCurrentItem(); + virtual TimeValue getItemPanelTime(Item *); + void loopCurrentItem(); + + InputHandler *_previousHandler; + bool _isLooping; +}; + +class BiochipPicture : public InventoryPicture { +public: + BiochipPicture(const tDisplayElementID, InputHandler *, Inventory *); + virtual ~BiochipPicture() {} + +protected: + virtual void unhighlightCurrentItem(); + virtual TimeValue getItemPanelTime(Item *); +}; + +} // End of namespace Pegasus + +#endif diff --git a/engines/pegasus/module.mk b/engines/pegasus/module.mk index 485b10787a..cc0b3ec7cc 100644 --- a/engines/pegasus/module.mk +++ b/engines/pegasus/module.mk @@ -20,6 +20,7 @@ MODULE_OBJS = \ transition.o \ util.o \ items/inventory.o \ + items/inventorypicture.o \ items/item.o \ items/itemlist.o \ items/biochips/biochipitem.o \ diff --git a/engines/pegasus/pegasus.cpp b/engines/pegasus/pegasus.cpp index b71295a72a..f12513601a 100644 --- a/engines/pegasus/pegasus.cpp +++ b/engines/pegasus/pegasus.cpp @@ -115,8 +115,7 @@ Common::Error PegasusEngine::run() { checkCallBacks(); checkNotifications(); InputHandler::pollForInput(); - giveIdleTime(); - _gfx->updateDisplay(); + refreshDisplay(); } return Common::kNoError; @@ -755,8 +754,7 @@ void PegasusEngine::doInterfaceOverview() { overviewText.setTime(time * 3 + 2, 15); overviewText.redrawMovieWorld(); - giveIdleTime(); - _gfx->updateDisplay(); + refreshDisplay(); } if (shouldQuit()) @@ -806,4 +804,9 @@ void PegasusEngine::showTempScreen(const Common::String &fileName) { } } +void PegasusEngine::refreshDisplay() { + giveIdleTime(); + _gfx->updateDisplay(); +} + } // End of namespace Pegasus diff --git a/engines/pegasus/pegasus.h b/engines/pegasus/pegasus.h index 7ad978d009..73a95c9a10 100644 --- a/engines/pegasus/pegasus.h +++ b/engines/pegasus/pegasus.h @@ -88,6 +88,7 @@ public: void swapLoadAllowed(bool allow) { _loadAllowed = allow; } void delayShell(TimeValue time, TimeScale scale); void resetIntroTimer(); + void refreshDisplay(); protected: Common::Error run(); |