From 5062aaffcaba2c564e1f3181e46a186b2744e036 Mon Sep 17 00:00:00 2001 From: Matthew Hoops Date: Tue, 11 Oct 2011 19:45:36 -0400 Subject: PEGASUS: Implement the sub chase --- engines/pegasus/console.cpp | 3 +- engines/pegasus/constants.h | 1 + engines/pegasus/pegasus.cpp | 97 +++++++++++++++++++++++++++++++-------------- engines/pegasus/pegasus.h | 2 + 4 files changed, 72 insertions(+), 31 deletions(-) diff --git a/engines/pegasus/console.cpp b/engines/pegasus/console.cpp index e6738bc83f..f8008a0681 100644 --- a/engines/pegasus/console.cpp +++ b/engines/pegasus/console.cpp @@ -83,7 +83,8 @@ bool PegasusConsole::Cmd_Jump(int argc, const char **argv) { tRoomID room = (tRoomID)atoi(argv[2]); tDirectionConstant direction = (tDirectionConstant)atoi(argv[3]); - if (neighborhood < kCaldoriaID || neighborhood > kNoradDeltaID || neighborhood == kFinalTSAID) { + if ((neighborhood < kCaldoriaID || neighborhood > kNoradDeltaID || neighborhood == kFinalTSAID) && + neighborhood != kNoradSubChaseID) { DebugPrintf("Invalid neighborhood %d", neighborhood); return true; } diff --git a/engines/pegasus/constants.h b/engines/pegasus/constants.h index 1d70c7d621..ef7e30c449 100755 --- a/engines/pegasus/constants.h +++ b/engines/pegasus/constants.h @@ -738,6 +738,7 @@ static const tGameMode kModeInfoScreen = kModeBiochipPick + 1; // TODO: Remove me static const tRoomID kNorad01 = 0; +static const tRoomID kNorad41 = 0; static const tRoomID kMars0A = 0; const tRoomID kMars35 = 38; const tRoomID kMars39 = 42; diff --git a/engines/pegasus/pegasus.cpp b/engines/pegasus/pegasus.cpp index a696edaedc..a13a77d910 100644 --- a/engines/pegasus/pegasus.cpp +++ b/engines/pegasus/pegasus.cpp @@ -1091,34 +1091,8 @@ bool PegasusEngine::playMovieScaled(Video::SeekableVideoDecoder *video, uint16 x if (video->needsUpdate()) { const Graphics::Surface *frame = video->decodeNextFrame(); - // Scale up the frame doing some simple scaling - Graphics::Surface scaledFrame; - scaledFrame.create(frame->w * 2, frame->h * 2, frame->format); - const byte *src = (const byte *)frame->pixels; - byte *dst1 = (byte *)scaledFrame.pixels; - byte *dst2 = (byte *)scaledFrame.pixels + scaledFrame.pitch; - - for (int i = 0; i < frame->h; i++) { - for (int j = 0; j < frame->w; j++) { - memcpy(dst1, src, frame->format.bytesPerPixel); - dst1 += frame->format.bytesPerPixel; - memcpy(dst1, src, frame->format.bytesPerPixel); - dst1 += frame->format.bytesPerPixel; - memcpy(dst2, src, frame->format.bytesPerPixel); - dst2 += frame->format.bytesPerPixel; - memcpy(dst2, src, frame->format.bytesPerPixel); - dst2 += frame->format.bytesPerPixel; - src += frame->format.bytesPerPixel; - } - - src += frame->pitch - frame->format.bytesPerPixel * frame->w; - dst1 += scaledFrame.pitch * 2 - scaledFrame.format.bytesPerPixel * scaledFrame.w; - dst2 += scaledFrame.pitch * 2 - scaledFrame.format.bytesPerPixel * scaledFrame.w; - } - - _system->copyRectToScreen((byte *)scaledFrame.pixels, scaledFrame.pitch, x, y, scaledFrame.w, scaledFrame.h); - _system->updateScreen(); - scaledFrame.free(); + if (frame) + drawScaledFrame(frame, x, y); } Input input; @@ -1280,8 +1254,13 @@ void PegasusEngine::useNeighborhood(Neighborhood *neighborhood) { } void PegasusEngine::performJump(const tNeighborhoodID neighborhoodID) { - if (neighborhoodID == kNoradSubChaseID) - error("TODO: Sub chase"); + // Sub chase is special + if (neighborhoodID == kNoradSubChaseID) { + throwAwayEverything(); + doSubChase(); + jumpToNewEnvironment(kNoradDeltaID, kNorad41, kEast); + return; + } if (_neighborhood) useNeighborhood(0); @@ -1377,6 +1356,8 @@ void PegasusEngine::makeNeighborhood(tNeighborhoodID neighborhoodID, Neighborhoo case kTinyTSAID: neighborhood = new TinyTSA(g_AIArea, this); break; + default: + error("Unhandled neighborhood %d", neighborhoodID); } } @@ -1886,4 +1867,60 @@ void PegasusEngine::playEndMessage() { die(kPlayerWonGame); } +void PegasusEngine::doSubChase() { + static const uint32 endTime = 133200 * 1000 / 600; + + Video::SeekableVideoDecoder *video = new Video::QuickTimeDecoder(); + if (!video->loadFile("Images/Norad Alpha/Sub Chase Movie")) + error("Failed to load sub chase"); + + while (!shouldQuit() && !video->endOfVideo() && video->getElapsedTime() < endTime) { + if (video->needsUpdate()) { + const Graphics::Surface *frame = video->decodeNextFrame(); + + if (frame) + drawScaledFrame(frame, 0, 0); + } + + Common::Event event; + while (_eventMan->pollEvent(event)) + ; + + _system->delayMillis(10); + } + + delete video; +} + +void PegasusEngine::drawScaledFrame(const Graphics::Surface *frame, uint16 x, uint16 y) { + // Scale up the frame doing some simple scaling + Graphics::Surface scaledFrame; + scaledFrame.create(frame->w * 2, frame->h * 2, frame->format); + const byte *src = (const byte *)frame->pixels; + byte *dst1 = (byte *)scaledFrame.pixels; + byte *dst2 = (byte *)scaledFrame.pixels + scaledFrame.pitch; + + for (int i = 0; i < frame->h; i++) { + for (int j = 0; j < frame->w; j++) { + memcpy(dst1, src, frame->format.bytesPerPixel); + dst1 += frame->format.bytesPerPixel; + memcpy(dst1, src, frame->format.bytesPerPixel); + dst1 += frame->format.bytesPerPixel; + memcpy(dst2, src, frame->format.bytesPerPixel); + dst2 += frame->format.bytesPerPixel; + memcpy(dst2, src, frame->format.bytesPerPixel); + dst2 += frame->format.bytesPerPixel; + src += frame->format.bytesPerPixel; + } + + src += frame->pitch - frame->format.bytesPerPixel * frame->w; + dst1 += scaledFrame.pitch * 2 - scaledFrame.format.bytesPerPixel * scaledFrame.w; + dst2 += scaledFrame.pitch * 2 - scaledFrame.format.bytesPerPixel * scaledFrame.w; + } + + _system->copyRectToScreen((byte *)scaledFrame.pixels, scaledFrame.pitch, x, y, scaledFrame.w, scaledFrame.h); + _system->updateScreen(); + scaledFrame.free(); +} + } // End of namespace Pegasus diff --git a/engines/pegasus/pegasus.h b/engines/pegasus/pegasus.h index a09a9231b2..934d5c5891 100644 --- a/engines/pegasus/pegasus.h +++ b/engines/pegasus/pegasus.h @@ -241,6 +241,8 @@ private: void throwAwayEverything(); void shellGameInput(const Input &input, const Hotspot *cursorSpot); Common::RandomSource *_rnd; + void doSubChase(); + void drawScaledFrame(const Graphics::Surface *frame, uint16 x, uint16 y); // Menu GameMenu *_gameMenu; -- cgit v1.2.3