diff options
Diffstat (limited to 'engines/pegasus')
-rw-r--r-- | engines/pegasus/elements.cpp | 241 | ||||
-rw-r--r-- | engines/pegasus/elements.h | 139 | ||||
-rw-r--r-- | engines/pegasus/graphics.cpp | 131 | ||||
-rw-r--r-- | engines/pegasus/graphics.h | 46 | ||||
-rw-r--r-- | engines/pegasus/module.mk | 1 |
5 files changed, 385 insertions, 173 deletions
diff --git a/engines/pegasus/elements.cpp b/engines/pegasus/elements.cpp new file mode 100644 index 0000000000..132c19a02a --- /dev/null +++ b/engines/pegasus/elements.cpp @@ -0,0 +1,241 @@ +/* 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/elements.h" +#include "pegasus/graphics.h" + +namespace Pegasus { + +DisplayElement::DisplayElement(const tDisplayElementID id) : IDObject(id) { + _elementIsDisplaying = false; + _elementIsVisible = false; + _elementOrder = 0; + _triggeredElement = this; + _nextElement = 0; +} + +DisplayElement::~DisplayElement() { + if (isDisplaying()) + ((PegasusEngine *)g_engine)->_gfx->removeDisplayElement(this); +} + +void DisplayElement::setDisplayOrder(const tDisplayOrder order) { + if (_elementOrder != order) { + _elementOrder = order; + if (isDisplaying()) { + ((PegasusEngine *)g_engine)->_gfx->removeDisplayElement(this); + ((PegasusEngine *)g_engine)->_gfx->addDisplayElement(this); + triggerRedraw(); + } + } +} + +void DisplayElement::startDisplaying() { + if (!isDisplaying()) { + ((PegasusEngine *)g_engine)->_gfx->addDisplayElement(this); + triggerRedraw(); + } +} + +void DisplayElement::stopDisplaying() { + if (isDisplaying()) { + triggerRedraw(); + ((PegasusEngine *)g_engine)->_gfx->removeDisplayElement(this); + } +} + +void DisplayElement::setBounds(const tCoordType left, const tCoordType top, const tCoordType right, const tCoordType bottom) { + _bounds = Common::Rect(left, top, right, bottom); +} + +void DisplayElement::getBounds(Common::Rect &r) const { + r = _bounds; +} + +void DisplayElement::sizeElement(const tCoordType h, const tCoordType v) { + _bounds.right = _bounds.left + h; + _bounds.bottom = _bounds.top + v; +} + +void DisplayElement::moveElementTo(const tCoordType h, const tCoordType v) { + _bounds.moveTo(h, v); +} + +void DisplayElement::moveElement(const tCoordType dh, const tCoordType dv) { + _bounds.translate(dh, dv); +} + +void DisplayElement::getLocation(tCoordType &h, tCoordType &v) const { + h = _bounds.left; + v = _bounds.top; +} + +void DisplayElement::centerElementAt(const tCoordType h, const tCoordType v) { + _bounds.moveTo(h - (_bounds.width() / 2), v - (_bounds.height() / 2)); +} + +void DisplayElement::getCenter(tCoordType &h, tCoordType &v) const { + h = (_bounds.left + _bounds.right) / 2; + v = (_bounds.top + _bounds.bottom) / 2; +} + +void DisplayElement::setBounds(const Common::Rect &r) { + if (r != _bounds) { + triggerRedraw(); + _bounds = r; + triggerRedraw(); + } +} + +void DisplayElement::hide() { + if (_elementIsVisible) { + triggerRedraw(); + _elementIsVisible = false; + } +} + +void DisplayElement::show() { + if (!_elementIsVisible) { + _elementIsVisible = true; + triggerRedraw(); + } +} + +// Only invalidates this element's bounding rectangle if all these conditions are true: +// -- The triggered element is this element. +// -- The element is displaying on the display list. +// -- The element is visible. +// -- The element is part of the active layer OR is one of the reserved items. +void DisplayElement::triggerRedraw() { + GraphicsManager *gfx = ((PegasusEngine *)g_engine)->_gfx; + + if (_triggeredElement == this) { + if (validToDraw(gfx->getBackOfActiveLayer(), gfx->getFrontOfActiveLayer())) + gfx->invalRect(_bounds); + } else { + _triggeredElement->triggerRedraw(); + } +} + +void DisplayElement::setTriggeredElement(DisplayElement *element) { + if (element) + _triggeredElement = element; + else + _triggeredElement = this; +} + +bool DisplayElement::validToDraw(tDisplayOrder backLayer, tDisplayOrder frontLayer) { + return isDisplaying() && _elementIsVisible && + (getObjectID() <= kHighestReservedElementID || + (getDisplayOrder() >= backLayer && + getDisplayOrder() <= frontLayer)); +} + +DropHighlight::DropHighlight(const tDisplayElementID id) : DisplayElement(id) { + _highlightColor = g_system->getScreenFormat().RGBToColor(0x48, 0x80, 0xD8); + _thickness = 2; + _cornerDiameter = 0; +} + +void DropHighlight::draw(const Common::Rect &) { + Graphics::Surface *screen = g_system->lockScreen(); + + // Since this is only used in two different ways, I'm only + // going to implement it in those two ways. Deal with it. + + Common::Rect rect = _bounds; + screen->frameRect(rect, _highlightColor); + rect.grow(1); + screen->frameRect(rect, _highlightColor); + + if (_cornerDiameter == 8 && _thickness == 4) { + rect.grow(1); + screen->frameRect(rect, _highlightColor); + screen->hLine(rect.left + 1, rect.top - 1, rect.right - 2, _highlightColor); + screen->hLine(rect.left + 1, rect.bottom, rect.right - 2, _highlightColor); + screen->vLine(rect.left - 1, rect.top + 1, rect.bottom - 2, _highlightColor); + screen->vLine(rect.right, rect.top + 1, rect.bottom - 2, _highlightColor); + } + + g_system->unlockScreen(); +} + +EnergyBar::EnergyBar(const tDisplayElementID id) : DisplayElement(id) { + _maxEnergy = 0; + _energyLevel = 0; + _barColor = 0; +} + +void EnergyBar::checkRedraw() { + if (_elementIsVisible) { + Common::Rect r; + calcLevelRect(r); + if (r != _levelRect) + triggerRedraw(); + } +} + +void EnergyBar::setEnergyLevel(const uint32 newLevel) { + if (_energyLevel != newLevel) { + _energyLevel = newLevel; + checkRedraw(); + } +} + +void EnergyBar::setMaxEnergy(const uint32 newMax) { + if (_maxEnergy != newMax) { + if (_energyLevel > newMax) + _energyLevel = newMax; + _maxEnergy = newMax; + checkRedraw(); + } +} + +void EnergyBar::setBounds(const Common::Rect &r) { + DisplayElement::setBounds(r); + checkRedraw(); +} + +void EnergyBar::draw(const Common::Rect &r) { + Common::Rect levelRect; + calcLevelRect(levelRect); + + if (r.intersects(levelRect)) { + Graphics::Surface *screen = g_system->lockScreen(); + screen->fillRect(levelRect, _barColor); + g_system->lockScreen(); + } +} + +void EnergyBar::calcLevelRect(Common::Rect &r) const { + if (_maxEnergy > 0) { + r = _bounds; + r.left = r.right - _bounds.width() * _energyLevel / _maxEnergy; + } else { + r = Common::Rect(0, 0, 0, 0); + } +} + +} // End of namespace Pegasus diff --git a/engines/pegasus/elements.h b/engines/pegasus/elements.h new file mode 100644 index 0000000000..2fc7a3abd3 --- /dev/null +++ b/engines/pegasus/elements.h @@ -0,0 +1,139 @@ +/* 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_ELEMENTS_H +#define PEGASUS_ELEMENTS_H + +#include "common/rect.h" +#include "common/str.h" +#include "common/system.h" +#include "graphics/pict.h" +#include "graphics/surface.h" + +#include "pegasus/pegasus.h" +#include "pegasus/util.h" + +namespace Pegasus { + +class DisplayElement : public IDObject { +friend class GraphicsManager; +public: + DisplayElement(const tDisplayElementID); + virtual ~DisplayElement(); + + void setDisplayOrder(const tDisplayOrder); + tDisplayOrder getDisplayOrder() const { return _elementOrder; } + + bool validToDraw(tDisplayOrder, tDisplayOrder); + + virtual void draw(const Common::Rect&) {} + bool isDisplaying() { return _elementIsDisplaying; } + virtual void startDisplaying(); + virtual void stopDisplaying(); + + virtual void show(); + virtual void hide(); + bool isVisible() { return _elementIsVisible; } + + // triggerRedraw only triggers a draw if the element is displaying and visible. + void triggerRedraw(); + void setTriggeredElement(DisplayElement *); + + virtual void setBounds(const tCoordType, const tCoordType, const tCoordType, const tCoordType); + virtual void setBounds(const Common::Rect&); + virtual void getBounds(Common::Rect&) const; + virtual void sizeElement(const tCoordType, const tCoordType); + virtual void moveElementTo(const tCoordType, const tCoordType); + virtual void moveElement(const tCoordType, const tCoordType); + virtual void getLocation(tCoordType&, tCoordType&) const; + virtual void getCenter(tCoordType&, tCoordType&) const; + virtual void centerElementAt(const tCoordType, const tCoordType); + +protected: + Common::Rect _bounds; + bool _elementIsVisible; + DisplayElement *_triggeredElement; + + // Used only by PegasusEngine + bool _elementIsDisplaying; + tDisplayOrder _elementOrder; + DisplayElement *_nextElement; +}; + +// I'm using the proper "highlight" instead of the evil +// QuickDraw "hilite" :P (deal with it!) +class DropHighlight : public DisplayElement { +public: + DropHighlight(const tDisplayElementID); + virtual ~DropHighlight() {} + + void setHighlightColor(const uint32 &highlight) { _highlightColor = highlight; } + void getHighlightColor(uint32 &highlight) const { highlight = _highlightColor; } + + void setHighlightThickness(const uint16 thickness) { _thickness = thickness; } + uint16 getHighlightThickness() const { return _thickness; } + + void setHighlightCornerDiameter(const uint16 diameter) { _cornerDiameter = diameter; } + uint16 getHighlightCornerDiameter() const { return _cornerDiameter; } + + virtual void draw(const Common::Rect&); + +protected: + uint32 _highlightColor; + uint16 _thickness; + uint16 _cornerDiameter; +}; + +class EnergyBar : public DisplayElement { +public: + EnergyBar(const tDisplayElementID); + virtual ~EnergyBar() {} + + void getBarColor(uint32 &color) const { color = _barColor; } + void setBarColor(const uint32 &color) { _barColor = color; } + + long getEnergyLevel() const { return _energyLevel; } + void setEnergyLevel(const uint32); + + long getMaxEnergy() const { return _maxEnergy; } + void setMaxEnergy(const uint32); + + virtual void setBounds(const Common::Rect&); + + virtual void draw(const Common::Rect&); + +protected: + void calcLevelRect(Common::Rect&) const; + void checkRedraw(); + + uint32 _energyLevel; + uint32 _maxEnergy; + Common::Rect _levelRect; + uint32 _barColor; +}; + +} // End of namespace Pegasus + +#endif diff --git a/engines/pegasus/graphics.cpp b/engines/pegasus/graphics.cpp index cec8595362..abff3df15a 100644 --- a/engines/pegasus/graphics.cpp +++ b/engines/pegasus/graphics.cpp @@ -23,139 +23,14 @@ * */ -#include "pegasus/graphics.h" - -#include "common/endian.h" #include "common/file.h" #include "common/textconsole.h" #include "engines/util.h" -namespace Pegasus { - -DisplayElement::DisplayElement(const tDisplayElementID id) : IDObject(id) { - _elementIsDisplaying = false; - _elementIsVisible = false; - _elementOrder = 0; - _triggeredElement = this; - _nextElement = 0; -} - -DisplayElement::~DisplayElement() { - if (isDisplaying()) - ((PegasusEngine *)g_engine)->_gfx->removeDisplayElement(this); -} - -void DisplayElement::setDisplayOrder(const tDisplayOrder order) { - if (_elementOrder != order) { - _elementOrder = order; - if (isDisplaying()) { - ((PegasusEngine *)g_engine)->_gfx->removeDisplayElement(this); - ((PegasusEngine *)g_engine)->_gfx->addDisplayElement(this); - triggerRedraw(); - } - } -} - -void DisplayElement::startDisplaying() { - if (!isDisplaying()) { - ((PegasusEngine *)g_engine)->_gfx->addDisplayElement(this); - triggerRedraw(); - } -} - -void DisplayElement::stopDisplaying() { - if (isDisplaying()) { - triggerRedraw(); - ((PegasusEngine *)g_engine)->_gfx->removeDisplayElement(this); - } -} - -void DisplayElement::setBounds(const tCoordType left, const tCoordType top, const tCoordType right, const tCoordType bottom) { - _bounds = Common::Rect(left, top, right, bottom); -} - -void DisplayElement::getBounds(Common::Rect &r) const { - r = _bounds; -} - -void DisplayElement::sizeElement(const tCoordType h, const tCoordType v) { - _bounds.right = _bounds.left + h; - _bounds.bottom = _bounds.top + v; -} - -void DisplayElement::moveElementTo(const tCoordType h, const tCoordType v) { - _bounds.moveTo(h, v); -} - -void DisplayElement::moveElement(const tCoordType dh, const tCoordType dv) { - _bounds.translate(dh, dv); -} - -void DisplayElement::getLocation(tCoordType &h, tCoordType &v) const { - h = _bounds.left; - v = _bounds.top; -} - -void DisplayElement::centerElementAt(const tCoordType h, const tCoordType v) { - _bounds.moveTo(h - (_bounds.width() / 2), v - (_bounds.height() / 2)); -} - -void DisplayElement::getCenter(tCoordType &h, tCoordType &v) const { - h = (_bounds.left + _bounds.right) / 2; - v = (_bounds.top + _bounds.bottom) / 2; -} - -void DisplayElement::setBounds(const Common::Rect &r) { - if (r != _bounds) { - triggerRedraw(); - _bounds = r; - triggerRedraw(); - } -} - -void DisplayElement::hide() { - if (_elementIsVisible) { - triggerRedraw(); - _elementIsVisible = false; - } -} - -void DisplayElement::show() { - if (!_elementIsVisible) { - _elementIsVisible = true; - triggerRedraw(); - } -} - -// Only invalidates this element's bounding rectangle if all these conditions are true: -// -- The triggered element is this element. -// -- The element is displaying on the display list. -// -- The element is visible. -// -- The element is part of the active layer OR is one of the reserved items. -void DisplayElement::triggerRedraw() { - GraphicsManager *gfx = ((PegasusEngine *)g_engine)->_gfx; - - if (_triggeredElement == this) { - if (validToDraw(gfx->getBackOfActiveLayer(), gfx->getFrontOfActiveLayer())) - gfx->invalRect(_bounds); - } else { - _triggeredElement->triggerRedraw(); - } -} - -void DisplayElement::setTriggeredElement(DisplayElement *element) { - if (element) - _triggeredElement = element; - else - _triggeredElement = this; -} +#include "pegasus/elements.h" +#include "pegasus/graphics.h" -bool DisplayElement::validToDraw(tDisplayOrder backLayer, tDisplayOrder frontLayer) { - return isDisplaying() && _elementIsVisible && - (getObjectID() <= kHighestReservedElementID || - (getDisplayOrder() >= backLayer && - getDisplayOrder() <= frontLayer)); -} +namespace Pegasus { GraphicsManager::GraphicsManager(PegasusEngine *vm) : _vm(vm) { initGraphics(640, 480, true, NULL); diff --git a/engines/pegasus/graphics.h b/engines/pegasus/graphics.h index 6778adb323..d8919e5b5c 100644 --- a/engines/pegasus/graphics.h +++ b/engines/pegasus/graphics.h @@ -37,51 +37,6 @@ namespace Pegasus { -class DisplayElement : public IDObject { -friend class GraphicsManager; -public: - DisplayElement(const tDisplayElementID); - virtual ~DisplayElement(); - - void setDisplayOrder(const tDisplayOrder); - tDisplayOrder getDisplayOrder() const { return _elementOrder; } - - bool validToDraw(tDisplayOrder, tDisplayOrder); - - virtual void draw(const Common::Rect&) {} - bool isDisplaying() { return _elementIsDisplaying; } - virtual void startDisplaying(); - virtual void stopDisplaying(); - - virtual void show(); - virtual void hide(); - bool isVisible() { return _elementIsVisible; } - - // triggerRedraw only triggers a draw if the element is displaying and visible. - void triggerRedraw(); - void setTriggeredElement(DisplayElement *); - - virtual void setBounds(const tCoordType, const tCoordType, const tCoordType, const tCoordType); - virtual void setBounds(const Common::Rect&); - virtual void getBounds(Common::Rect&) const; - virtual void sizeElement(const tCoordType, const tCoordType); - virtual void moveElementTo(const tCoordType, const tCoordType); - virtual void moveElement(const tCoordType, const tCoordType); - virtual void getLocation(tCoordType&, tCoordType&) const; - virtual void getCenter(tCoordType&, tCoordType&) const; - virtual void centerElementAt(const tCoordType, const tCoordType); - -protected: - Common::Rect _bounds; - bool _elementIsVisible; - DisplayElement *_triggeredElement; - - // Used only by PegasusEngine - bool _elementIsDisplaying; - tDisplayOrder _elementOrder; - DisplayElement *_nextElement; -}; - enum { kImageCacheSize = 10 }; @@ -92,6 +47,7 @@ struct ImageCache { uint32 lastUsed; }; +class DisplayElement; class PegasusEngine; class GraphicsManager { diff --git a/engines/pegasus/module.mk b/engines/pegasus/module.mk index 06cfd0318e..0f697f397e 100644 --- a/engines/pegasus/module.mk +++ b/engines/pegasus/module.mk @@ -5,6 +5,7 @@ MODULE_OBJS = \ credits.o \ cursor.o \ detection.o \ + elements.o \ gamestate.o \ graphics.o \ hotspot.o \ |