Skip to content

Commit

Permalink
PEGASUS: Add the InventoryPicture class (and its derivatives)
Browse files Browse the repository at this point in the history
  • Loading branch information
Matthew Hoops committed Sep 22, 2011
1 parent 3417e39 commit 897c585
Show file tree
Hide file tree
Showing 5 changed files with 501 additions and 4 deletions.
367 changes: 367 additions & 0 deletions 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

0 comments on commit 897c585

Please sign in to comment.