aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--engines/voyeur/animation.cpp31
-rw-r--r--engines/voyeur/animation.h7
-rw-r--r--engines/voyeur/files.cpp1
-rw-r--r--engines/voyeur/voyeur.cpp2
-rw-r--r--engines/voyeur/voyeur.h33
-rw-r--r--engines/voyeur/voyeur_game.cpp160
6 files changed, 230 insertions, 4 deletions
diff --git a/engines/voyeur/animation.cpp b/engines/voyeur/animation.cpp
index b862f3a8d9..0fc5669c66 100644
--- a/engines/voyeur/animation.cpp
+++ b/engines/voyeur/animation.cpp
@@ -22,6 +22,7 @@
#include "voyeur/animation.h"
#include "voyeur/staticres.h"
+#include "voyeur/voyeur.h"
#include "common/memstream.h"
#include "common/system.h"
#include "audio/decoders/raw.h"
@@ -97,6 +98,27 @@ RL2Decoder::RL2VideoTrack *RL2Decoder::getVideoTrack() {
return (RL2VideoTrack *)track;
}
+void RL2Decoder::play(::Voyeur::VoyeurEngine *vm) {
+ vm->_eventsManager.getMouseInfo();
+
+ while (!vm->shouldQuit() && !endOfVideo() && !vm->_eventsManager._mouseClicked) {
+ if (hasDirtyPalette()) {
+ const byte *palette = getPalette();
+ vm->_graphicsManager.setPalette(palette, 0, 256);
+ }
+
+ if (needsUpdate()) {
+ const Graphics::Surface *frame = decodeNextFrame();
+
+ Common::copy((const byte *)frame->getPixels(), (const byte *)frame->getPixels() + 320 * 200,
+ (byte *)vm->_graphicsManager._screenSurface.getPixels());
+ }
+
+ vm->_eventsManager.getMouseInfo();
+ g_system->delayMillis(10);
+ }
+}
+
/*------------------------------------------------------------------------*/
RL2Decoder::RL2FileHeader::RL2FileHeader() {
@@ -288,18 +310,19 @@ void RL2Decoder::RL2VideoTrack::rl2DecodeFrameWithoutTransparency(int screenOffs
--frameSize;
} else if (nextByte > 0x80) {
// Lower 7 bits a run length for the following byte
- byte runLength = _fileStream->readByte();
- assert(frameSize >= runLength);
+ int runLength = _fileStream->readByte();
+ runLength = MIN(runLength, frameSize);
+
Common::fill(destP, destP + runLength, nextByte & 0x7f);
destP += runLength;
frameSize -= runLength;
} else {
// Follow byte run length for zeroes. If zero, indicates end of image
- byte runLength = _fileStream->readByte();
+ int runLength = _fileStream->readByte();
if (runLength == 0)
break;
- assert(frameSize >= runLength);
+ runLength = MIN(runLength, frameSize);
Common::fill(destP, destP + runLength, 0);
destP += runLength;
frameSize -= runLength;
diff --git a/engines/voyeur/animation.h b/engines/voyeur/animation.h
index 9f1a2ab833..c68c670fbb 100644
--- a/engines/voyeur/animation.h
+++ b/engines/voyeur/animation.h
@@ -30,6 +30,12 @@
#include "common/rect.h"
#include "common/stream.h"
+namespace Voyeur {
+
+class VoyeurEngine;
+
+}
+
namespace Video {
/**
@@ -149,6 +155,7 @@ public:
void clearDirtyRects();
void copyDirtyRectsToBuffer(uint8 *dst, uint pitch);
RL2VideoTrack *getVideoTrack();
+ void play(::Voyeur::VoyeurEngine *vm);
};
} // End of namespace Video
diff --git a/engines/voyeur/files.cpp b/engines/voyeur/files.cpp
index 1b33c5f997..1e08acb489 100644
--- a/engines/voyeur/files.cpp
+++ b/engines/voyeur/files.cpp
@@ -454,6 +454,7 @@ BVoyBoltFile::BVoyBoltFile(BoltFilesState &state): BoltFile("bvoy.blt", state) {
void BVoyBoltFile::initResource(int resType) {
switch (resType) {
case 2:
+ // Also used for point list, and ending credits credit data
sInitRect();
break;
case 8:
diff --git a/engines/voyeur/voyeur.cpp b/engines/voyeur/voyeur.cpp
index 051c8b955d..fa9b12e70f 100644
--- a/engines/voyeur/voyeur.cpp
+++ b/engines/voyeur/voyeur.cpp
@@ -102,6 +102,8 @@ Common::Error VoyeurEngine::run() {
_voy._field478 |= 0x80;
playStamp();
+ if (!shouldQuit())
+ doTailTitle();
}
//doHeadTitle();
diff --git a/engines/voyeur/voyeur.h b/engines/voyeur/voyeur.h
index 2dde65c5d3..8cf13259dc 100644
--- a/engines/voyeur/voyeur.h
+++ b/engines/voyeur/voyeur.h
@@ -84,11 +84,44 @@ private:
void playStamp();
void initStamp();
void closeStamp();
+
+ /**
+ * Shows the game ending title animation
+ */
+ void doTailTitle();
+
+ /**
+ * Shows the game ending credits
+ */
+ void doClosingCredits();
+
+ /**
+ * Shows the final anti-piracy message before exiting the game
+ */
+ void doPiracy();
+
void reviewTape();
+
+ /**
+ * Shows the TV gossip animation
+ */
void doGossip();
+
+ /**
+ * Shows the animation of the VCR tape during the 'Call the Police' sequence
+ */
void doTapePlaying();
+
+ /**
+ * Does a check as to whether a murder has been witnessed
+ */
bool checkForMurder();
+
+ /**
+ * Does a check for whether incriminating evidence has been revealed
+ */
bool checkForIncriminate();
+
void playAVideoEvent(int eventIndex);
int getChooseButton();
protected:
diff --git a/engines/voyeur/voyeur_game.cpp b/engines/voyeur/voyeur_game.cpp
index 740bf1728a..c0989e2206 100644
--- a/engines/voyeur/voyeur_game.cpp
+++ b/engines/voyeur/voyeur_game.cpp
@@ -225,6 +225,166 @@ void VoyeurEngine::closeStamp() {
ThreadResource::unloadAllStacks(this);
}
+void VoyeurEngine::doTailTitle() {
+ _bVoy->freeBoltGroup(0x100);
+ (*_graphicsManager._vPort)->setupViewPort(NULL);
+ _graphicsManager.screenReset();
+
+ if (_bVoy->getBoltGroup(0x600)) {
+ ::Video::RL2Decoder decoder;
+ decoder.loadFile("a1100200.rl2");
+ decoder.start();
+ decoder.play(this);
+
+ if (!shouldQuit() && !_eventsManager._mouseClicked) {
+ doClosingCredits();
+
+ if (!shouldQuit() && !_eventsManager._mouseClicked) {
+ _graphicsManager.screenReset();
+
+ PictureResource *pic = _bVoy->boltEntry(0x602)._picResource;
+ CMapResource *pal = _bVoy->boltEntry(0x603)._cMapResource;
+
+ (*_graphicsManager._vPort)->setupViewPort(pic);
+ pal->startFade();
+ flipPageAndWaitForFade();
+ _eventsManager.delayClick(300);
+
+ pic = _bVoy->boltEntry(0x604)._picResource;
+ pal = _bVoy->boltEntry(0x605)._cMapResource;
+
+ (*_graphicsManager._vPort)->setupViewPort(pic);
+ pal->startFade();
+ flipPageAndWaitForFade();
+ _eventsManager.delayClick(120);
+
+ _soundManager.stopVOCPlay();
+ }
+ }
+
+ _bVoy->freeBoltGroup(0x600);
+ }
+
+ if (!shouldQuit()) {
+ _bVoy->getBoltGroup(0x100);
+ doPiracy();
+ }
+}
+
+void VoyeurEngine::doClosingCredits() {
+ if (!_bVoy->getBoltGroup(0x400))
+ return;
+
+ const char *msg = (const char *)_bVoy->memberAddr(0x404);
+ const byte *yList = (const byte *)_bVoy->memberAddr(0x405);
+
+ (*_graphicsManager._vPort)->setupViewPort(NULL);
+ _graphicsManager.setColor(1, 180, 180, 180);
+ _graphicsManager.setColor(2, 200, 200, 200);
+ _eventsManager._intPtr.field38 = true;
+ _eventsManager._intPtr._hasPalette = true;
+
+ _graphicsManager._fontPtr->_curFont = _bVoy->boltEntry(0x402)._fontResource;
+ _graphicsManager._fontPtr->_foreColor = 2;
+ _graphicsManager._fontPtr->_backColor = 2;
+ _graphicsManager._fontPtr->_fontSaveBack = false;
+ _graphicsManager._fontPtr->_fontFlags = 0;
+
+ _soundManager.startVOCPlay(152);
+ FontInfoResource &fi = *_graphicsManager._fontPtr;
+
+ for (int idx = 0; idx < 78; ++idx) {
+ byte *entry = yList + idx * 6;
+ int flags = READ_LE_UINT16(entry + 4);
+
+ if (flags & 0x10)
+ (*_graphicsManager->_vPort)->sFillPic();
+
+ if (flags & 1) {
+ fi._foreColor = 1;
+ fi._curFont = _bVoy->boltEntry(0x402)._fontResource;
+ fi.justify = true;
+ fi.justifyWidth = 384;
+ fi._justifyHeight = 240;
+ fi._pos = Common::Point(0, READ_LE_UINT16(entry));
+
+ (*_graphicsManager._vPort)->drawText(msg);
+ msg += strlen(msg) + 1;
+ }
+
+ if (flags & 0x40) {
+ fi._foreColor = 2;
+ fi._curFont = _bVoy->boltEntry(0x400)._fontResource;
+ fi.justify = true;
+ fi.justifyWidth = 384;
+ fi._justifyHeight = 240;
+ fi._pos = Common::Point(0, READ_LE_UINT16(entry));
+
+ (*_graphicsManager._vPort)->drawText(msg);
+ msg += strlen(msg) + 1;
+ }
+
+ if (flags & 2) {
+ fi._foreColor = 1;
+ fi._curFont = _bVoy->boltEntry(0x400)._fontResource;
+ fi.justify = false;
+ fi.justifyWidth = 384;
+ fi._justifyHeight = 240;
+ fi._pos = Common::Point(38, READ_LE_UINT16(entry));
+
+ (*_graphicsManager._vPort)->drawText(msg);
+ msg += strlen(msg) + 1;
+
+ fi._foreColor = 2;
+ fi.justify = false;
+ fi.justifyWidth = 384;
+ fi._justifyHeight = 240;
+ fi._pos = Common::Point(198, READ_LE_UINT16(entry));
+
+ (*_graphicsManager._vPort)->drawText(msg);
+ msg += strlen(msg) + 1;
+ }
+
+ if (flags & 4) {
+ fi._foreColor = 1;
+ fi._curFont = _bVoy->boltEntry(0x402)._fontResource;
+ fi.justify = true;
+ fi.justifyWidth = 384;
+ fi._justifyHeight = 240;
+ fi._pos = Common::Point(0, READ_LE_UINT16(entry));
+
+ (*_graphicsManager._vPort)->drawText(msg);
+ msg += strlen(msg) + 1;
+
+ fi._foreColor = 2;
+ fi._curFont = _bVoy->boltEntry(0x400)._fontResource;
+ fi.justify = true;
+ fi.justifyWidth = 384;
+ fi._justifyHeight = 240;
+ fi._pos = Common::Point(0, READ_LE_UINT16(entry) + 13);
+
+ (*_graphicsManager._vPort)->drawText(msg);
+ msg += strlen(msg) + 1;
+ }
+
+ if (flags & 0x20) {
+ flipPageAndWait();
+ _eventsManager.delayClick(READ_LE_UINT16(entry + 2) * 60);
+ }
+
+ if (shouldQuit() || _eventsManager._mouseClicked)
+ break;
+ }
+
+ _soundManager.stopVOCPlay();
+ _graphicsManager._fontPtr->_curFont = _bVoy->boltEntry(0x101)._fontResource;
+ _bVoy->freeBoltGroup(0x400);
+}
+
+void VoyeurEngine::doPiracy() {
+
+}
+
void VoyeurEngine::reviewTape() {
// int var22 = 0;
int si = 0;