aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xengines/pegasus/cursor.cpp179
-rwxr-xr-xengines/pegasus/cursor.h84
-rw-r--r--engines/pegasus/graphics.cpp78
-rw-r--r--engines/pegasus/graphics.h15
-rw-r--r--engines/pegasus/module.mk1
-rw-r--r--engines/pegasus/overview.cpp7
-rw-r--r--engines/pegasus/pegasus.cpp19
-rw-r--r--engines/pegasus/pegasus.h2
8 files changed, 284 insertions, 101 deletions
diff --git a/engines/pegasus/cursor.cpp b/engines/pegasus/cursor.cpp
new file mode 100755
index 0000000000..c0af27bdce
--- /dev/null
+++ b/engines/pegasus/cursor.cpp
@@ -0,0 +1,179 @@
+/* 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 "common/events.h"
+#include "common/stream.h"
+#include "common/system.h"
+#include "graphics/cursorman.h"
+#include "graphics/pict.h"
+#include "graphics/surface.h"
+
+#include "pegasus/cursor.h"
+#include "pegasus/pegasus.h"
+
+namespace Pegasus {
+
+Cursor::Cursor() {
+ _cursorObscured = false;
+ _index = -1;
+}
+
+Cursor::~Cursor() {
+ for (uint32 i = 0; i < _info.size(); i++) {
+ if (_info[i].surface) {
+ _info[i].surface->free();
+ delete _info[i].surface;
+ }
+ delete[] _info[i].palette;
+ }
+}
+
+void Cursor::addCursorFrames(uint16 id) {
+ PegasusEngine *vm = (PegasusEngine *)g_engine;
+ Common::SeekableReadStream *cursStream = vm->_resFork->getResource(MKTAG('C', 'u', 'r', 's'), id);
+ if (!cursStream)
+ error("Could not load cursor frames set %d", id);
+
+ uint16 frameCount = cursStream->readUint16BE();
+ for (uint16 i = 0; i < frameCount; i++) {
+ CursorInfo info;
+ info.tag = cursStream->readUint16BE();
+ info.hotspot.x = cursStream->readUint16BE();
+ info.hotspot.y = cursStream->readUint16BE();
+ info.surface = 0;
+ info.palette = 0;
+ info.colorCount = 0;
+ _info.push_back(info);
+ }
+
+ delete cursStream;
+
+ setCurrentFrameIndex(0);
+}
+
+void Cursor::setCurrentFrameIndex(int32 index) {
+ if (_index != index) {
+ _index = index;
+ if (index != -1) {
+ loadCursorImage(_info[index]);
+ CursorMan.replaceCursorPalette(_info[index].palette, 0, _info[index].colorCount);
+ CursorMan.replaceCursor((byte *)_info[index].surface->pixels, _info[index].surface->w, _info[index].surface->h, _info[index].hotspot.x, _info[index].hotspot.y, 0);
+ }
+ }
+}
+
+int32 Cursor::getCurrentFrameIndex() const {
+ return _index;
+}
+
+void Cursor::show() {
+ if (!isVisible())
+ CursorMan.showMouse(true);
+
+ _cursorObscured = false;
+}
+
+void Cursor::hide() {
+ CursorMan.showMouse(false);
+ setCurrentFrameIndex(0);
+}
+
+void Cursor::hideUntilMoved() {
+ if (!_cursorObscured) {
+ hide();
+ _cursorObscured = true;
+ }
+}
+
+void Cursor::useIdleTime() {
+ if (g_system->getEventManager()->getMousePos() != _cursorLocation) {
+ _cursorLocation = g_system->getEventManager()->getMousePos();
+ if (_index != -1 && _cursorObscured)
+ show();
+ }
+}
+
+void Cursor::getCursorLocation(Common::Point &pt) const {
+ pt = _cursorLocation;
+}
+
+bool Cursor::isVisible() {
+ return CursorMan.isVisible();
+}
+
+void Cursor::loadCursorImage(CursorInfo &cursorInfo) {
+ if (cursorInfo.surface)
+ return;
+
+ cursorInfo.surface = new Graphics::Surface();
+
+ PegasusEngine *vm = (PegasusEngine *)g_engine;
+ Common::SeekableReadStream *cicnStream = vm->_resFork->getResource(MKTAG('c', 'i', 'c', 'n'), cursorInfo.tag);
+
+ if (!cicnStream)
+ error("Failed to find color icon %d", cursorInfo.tag);
+
+ // PixMap section
+ Graphics::PictDecoder::PixMap pixMap = Graphics::PictDecoder::readPixMap(cicnStream);
+
+ // Mask section
+ cicnStream->readUint32BE(); // mask baseAddr
+ uint16 maskRowBytes = cicnStream->readUint16BE(); // mask rowBytes
+ cicnStream->skip(3 * 2); // mask rect
+ /* uint16 maskHeight = */ cicnStream->readUint16BE();
+
+ // Bitmap section
+ cicnStream->readUint32BE(); // baseAddr
+ uint16 rowBytes = cicnStream->readUint16BE();
+ cicnStream->readUint16BE(); // top
+ cicnStream->readUint16BE(); // left
+ uint16 height = cicnStream->readUint16BE(); // bottom
+ cicnStream->readUint16BE(); // right
+
+ // Data section
+ cicnStream->readUint32BE(); // icon handle
+ cicnStream->skip(maskRowBytes * height); // FIXME: maskHeight doesn't work here, though the specs say it should
+ cicnStream->skip(rowBytes * height);
+
+ // Palette section
+ cicnStream->readUint32BE(); // always 0
+ cicnStream->readUint16BE(); // always 0
+ cursorInfo.colorCount = cicnStream->readUint16BE() + 1;
+
+ cursorInfo.palette = new byte[256 * cursorInfo.colorCount];
+ for (uint16 i = 0; i < cursorInfo.colorCount; i++) {
+ cicnStream->readUint16BE();
+ cursorInfo.palette[i * 3] = cicnStream->readUint16BE() >> 8;
+ cursorInfo.palette[i * 3 + 1] = cicnStream->readUint16BE() >> 8;
+ cursorInfo.palette[i * 3 + 2] = cicnStream->readUint16BE() >> 8;
+ }
+
+ // PixMap data
+ cursorInfo.surface->create(pixMap.rowBytes, pixMap.bounds.height(), Graphics::PixelFormat::createFormatCLUT8());
+ cicnStream->read(cursorInfo.surface->pixels, pixMap.rowBytes * pixMap.bounds.height());
+ delete cicnStream;
+}
+
+} // End of namespace Pegasus
diff --git a/engines/pegasus/cursor.h b/engines/pegasus/cursor.h
new file mode 100755
index 0000000000..ada82e3967
--- /dev/null
+++ b/engines/pegasus/cursor.h
@@ -0,0 +1,84 @@
+/* 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_CURSOR_H
+#define PEGASUS_CURSOR_H
+
+#include "common/array.h"
+#include "common/rect.h"
+
+#include "pegasus/timers.h"
+
+namespace Graphics {
+ struct Surface;
+}
+
+namespace Pegasus {
+
+// The original cursor code was in the graphics code directly,
+// unlike ScummVM where we have the cursor code separate. We're
+// going to go with CursorManager here and therefore not inherit
+// from the Sprite class.
+
+class Cursor : private Idler {
+public:
+ Cursor();
+ virtual ~Cursor();
+
+ void addCursorFrames(uint16 id);
+
+ void setCurrentFrameIndex(int32 index);
+ int32 getCurrentFrameIndex() const;
+
+ void show();
+ void hide();
+ void hideUntilMoved();
+ bool isVisible();
+
+ void getCursorLocation(Common::Point &) const;
+
+protected:
+ virtual void useIdleTime();
+
+private:
+ struct CursorInfo {
+ uint16 tag;
+ Common::Point hotspot;
+ Graphics::Surface *surface;
+ byte *palette;
+ uint16 colorCount;
+ };
+
+ Common::Point _cursorLocation;
+ Common::Array<CursorInfo> _info;
+ bool _cursorObscured;
+ int _index;
+
+ void loadCursorImage(CursorInfo &cursorInfo);
+};
+
+} // End of namespace Pegasus
+
+#endif
diff --git a/engines/pegasus/graphics.cpp b/engines/pegasus/graphics.cpp
index 2042b8f712..28aafdb04f 100644
--- a/engines/pegasus/graphics.cpp
+++ b/engines/pegasus/graphics.cpp
@@ -26,7 +26,6 @@
#include "common/file.h"
#include "common/textconsole.h"
#include "engines/util.h"
-#include "graphics/cursorman.h"
namespace Pegasus {
@@ -135,83 +134,6 @@ uint32 GraphicsManager::getColor(byte r, byte g, byte b) {
return _vm->_system->getScreenFormat().RGBToColor(r, g, b);
}
-void GraphicsManager::setCursor(uint16 cursor) {
- Common::SeekableReadStream *cicnStream = _vm->_resFork->getResource(MKTAG('c', 'i', 'c', 'n'), cursor);
-
- // PixMap section
- Graphics::PictDecoder::PixMap pixMap = _pictDecoder->readPixMap(cicnStream);
-
- // Mask section
- cicnStream->readUint32BE(); // mask baseAddr
- uint16 maskRowBytes = cicnStream->readUint16BE(); // mask rowBytes
- cicnStream->skip(3 * 2); // mask rect
- /* uint16 maskHeight = */ cicnStream->readUint16BE();
-
- // Bitmap section
- cicnStream->readUint32BE(); // baseAddr
- uint16 rowBytes = cicnStream->readUint16BE();
- cicnStream->readUint16BE(); // top
- cicnStream->readUint16BE(); // left
- uint16 height = cicnStream->readUint16BE(); // bottom
- cicnStream->readUint16BE(); // right
-
- // Data section
- cicnStream->readUint32BE(); // icon handle
- cicnStream->skip(maskRowBytes * height); // FIXME: maskHeight doesn't work here, though the specs say it should
- cicnStream->skip(rowBytes * height);
-
- // Palette section
- cicnStream->readUint32BE(); // always 0
- cicnStream->readUint16BE(); // always 0
- uint16 colorCount = cicnStream->readUint16BE() + 1;
-
- byte *colors = new byte[256 * 3];;
- for (uint16 i = 0; i < colorCount; i++) {
- cicnStream->readUint16BE();
- colors[i * 3] = cicnStream->readUint16BE() >> 8;
- colors[i * 3 + 1] = cicnStream->readUint16BE() >> 8;
- colors[i * 3 + 2] = cicnStream->readUint16BE() >> 8;
- }
-
- // PixMap data
- byte *data = new byte[pixMap.rowBytes * pixMap.bounds.height()];
- cicnStream->read(data, pixMap.rowBytes * pixMap.bounds.height());
- delete cicnStream;
-
- // Now to go get the hotspots
- Common::SeekableReadStream *cursStream = NULL;
-
- if (cursor >= kMainCursor && cursor <= kGrabbingHand)
- cursStream = _vm->_resFork->getResource(MKTAG('C', 'u', 'r', 's'), kMainCursor);
- else // if (cursor == kTargetingReticle1 || cursor == kTargetingReticle2)
- cursStream = _vm->_resFork->getResource(MKTAG('C', 'u', 'r', 's'), kTargetingReticle1);
-
- // Go through the stream until we find the right cursor hotspot
- uint16 x = 0, y = 0;
- uint16 numHotspots = cursStream->readUint16BE();
-
- for (uint16 i = 0; i < numHotspots; i++) {
- uint16 res = cursStream->readUint16BE();
- uint16 tempX = cursStream->readUint16BE();
- uint16 tempY = cursStream->readUint16BE();
-
- if (res == cursor) {
- x = tempX;
- y = tempY;
- break;
- }
- }
-
- // We have the bitmap and the hotspot, let's do this!
- CursorMan.replaceCursorPalette(colors, 0, colorCount);
- CursorMan.replaceCursor(data, pixMap.rowBytes, pixMap.bounds.height(), x, y, 0);
- CursorMan.showMouse(true);
- _vm->_system->updateScreen();
-
- delete[] colors;
- delete[] data;
-}
-
int GraphicsManager::getImageSlot(const Common::String &filename) {
// Let's find a match, an open slot, or the oldest image slot
uint32 oldestAge = 0xffffffff;
diff --git a/engines/pegasus/graphics.h b/engines/pegasus/graphics.h
index 7607c626d5..41353735b1 100644
--- a/engines/pegasus/graphics.h
+++ b/engines/pegasus/graphics.h
@@ -34,20 +34,6 @@
namespace Pegasus {
enum {
- // The main cursors
- kMainCursor = 128,
- kZoomInCursor = 129,
- kZoomOutCursor = 130,
- kPointingCursor = 131,
- kInteractHand = 132,
- kGrabbingHand = 133,
-
- // Reticles when using the Mars shuttle
- kTargetingReticle1 = 900,
- kTargetingReticle2 = 901
-};
-
-enum {
kImageCacheSize = 10
};
@@ -66,7 +52,6 @@ public:
void drawPict(Common::String filename, int x, int y, bool updateScreen = true);
void drawPictTransparent(Common::String filename, int x, int y, uint32 transparency, bool updateScreen = true);
- void setCursor(uint16 cursor);
uint32 getColor(byte r, byte g, byte b);
private:
diff --git a/engines/pegasus/module.mk b/engines/pegasus/module.mk
index 50e9b54dd3..06cfd0318e 100644
--- a/engines/pegasus/module.mk
+++ b/engines/pegasus/module.mk
@@ -3,6 +3,7 @@ MODULE := engines/pegasus
MODULE_OBJS = \
console.o \
credits.o \
+ cursor.o \
detection.o \
gamestate.o \
graphics.o \
diff --git a/engines/pegasus/overview.cpp b/engines/pegasus/overview.cpp
index adbfbdbbe8..8e82708a0f 100644
--- a/engines/pegasus/overview.cpp
+++ b/engines/pegasus/overview.cpp
@@ -25,13 +25,14 @@
#include "graphics/cursorman.h"
#include "video/qt_decoder.h"
+#include "pegasus/cursor.h"
#include "pegasus/pegasus.h"
namespace Pegasus {
void PegasusEngine::runInterfaceOverview() {
- CursorMan.showMouse(true);
- _gfx->setCursor(kPointingCursor);
+ _cursor->setCurrentFrameIndex(3);
+ _cursor->show();
Video::QuickTimeDecoder *overviewVideo = new Video::QuickTimeDecoder();
if (!overviewVideo->loadFile("Images/Interface/Overview Mac.movie"))
@@ -103,7 +104,7 @@ void PegasusEngine::runInterfaceOverview() {
_system->delayMillis(10);
}
- CursorMan.showMouse(false);
+ _cursor->hide();
delete overviewVideo;
}
diff --git a/engines/pegasus/pegasus.cpp b/engines/pegasus/pegasus.cpp
index d6b3d541fa..f604a2488a 100644
--- a/engines/pegasus/pegasus.cpp
+++ b/engines/pegasus/pegasus.cpp
@@ -32,6 +32,7 @@
#include "gui/saveload.h"
#include "pegasus/console.h"
+#include "pegasus/cursor.h"
#include "pegasus/gamestate.h"
#include "pegasus/pegasus.h"
#include "pegasus/timers.h"
@@ -42,7 +43,7 @@
//#define RUN_INTERFACE_TEST
#ifdef RUN_INTERFACE_TEST
-#include "pegasus/MMShell/Sounds/MMSound.h"
+#include "pegasus/sound.h"
#endif
namespace Pegasus {
@@ -57,6 +58,7 @@ PegasusEngine::~PegasusEngine() {
delete _inventoryLid;
delete _biochipLid;
delete _console;
+ delete _cursor;
}
Common::Error PegasusEngine::run() {
@@ -66,6 +68,7 @@ Common::Error PegasusEngine::run() {
_resFork = new Common::MacResManager();
_inventoryLid = new Common::MacResManager();
_biochipLid = new Common::MacResManager();
+ _cursor = new Cursor();
_gameMode = kIntroMode;
_adventureMode = true;
@@ -78,8 +81,13 @@ Common::Error PegasusEngine::run() {
if (!_biochipLid->open("Images/Lids/Biochip Lid Sequence") || !_biochipLid->hasResFork())
error("Could not open Biochip Lid Sequence");
+ // Initialize items
createItems();
+ // Initialize cursors
+ _cursor->addCursorFrames(0x80); // Main
+ _cursor->addCursorFrames(900); // Mars Shuttle
+
if (!isDemo() && !detectOpeningClosingDirectory()) {
Common::String message = "Missing intro directory. ";
@@ -116,11 +124,12 @@ Common::Error PegasusEngine::run() {
#if defined(RUN_SUB_MOVIE)
_video->playMovie("Images/Norad Alpha/Sub Chase Movie");
#elif defined(RUN_INTERFACE_TEST)
+ _cursor->setCurrentFrameIndex(0);
+ _cursor->show();
drawInterface();
- _gfx->setCursor(kMainCursor);
- MMSound sound;
- sound.InitFromAIFFFile("Sounds/Caldoria/Apartment Music.aiff");
- sound.LoopSound();
+ Sound sound;
+ sound.initFromAIFFFile("Sounds/Caldoria/Apartment Music.aiff");
+ sound.loopSound();
while (!shouldQuit()) {
Common::Event event;
diff --git a/engines/pegasus/pegasus.h b/engines/pegasus/pegasus.h
index e0135657bd..35ee117ed4 100644
--- a/engines/pegasus/pegasus.h
+++ b/engines/pegasus/pegasus.h
@@ -48,6 +48,7 @@ class SoundManager;
class VideoManager;
class GraphicsManager;
class Idler;
+class Cursor;
static const int kViewScreenOffset = 64;
@@ -131,6 +132,7 @@ private:
// Idlers
Common::List<Idler *> _idlers;
void giveIdleTime();
+ Cursor *_cursor;
// Items
void createItems();