aboutsummaryrefslogtreecommitdiff
path: root/engines
diff options
context:
space:
mode:
Diffstat (limited to 'engines')
-rw-r--r--engines/pegasus/elements.cpp241
-rw-r--r--engines/pegasus/elements.h139
-rw-r--r--engines/pegasus/graphics.cpp131
-rw-r--r--engines/pegasus/graphics.h46
-rw-r--r--engines/pegasus/module.mk1
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 \