aboutsummaryrefslogtreecommitdiff
path: root/engines/pegasus
diff options
context:
space:
mode:
authorMatthew Hoops2011-09-26 00:30:33 -0400
committerMatthew Hoops2011-09-26 00:30:44 -0400
commit24cc9568cbefe6570dd846874c0681f3c09521bd (patch)
treeb78a9ef64ae4c5cd2d3565ebfb00237a47b1094f /engines/pegasus
parent85e7d2d9a99a0b7663881c6b5e1ce066d2efc49c (diff)
downloadscummvm-rg350-24cc9568cbefe6570dd846874c0681f3c09521bd.tar.gz
scummvm-rg350-24cc9568cbefe6570dd846874c0681f3c09521bd.tar.bz2
scummvm-rg350-24cc9568cbefe6570dd846874c0681f3c09521bd.zip
PEGASUS: Implement the death menu
Diffstat (limited to 'engines/pegasus')
-rwxr-xr-xengines/pegasus/constants.h2
-rwxr-xr-xengines/pegasus/menu.cpp366
-rwxr-xr-xengines/pegasus/menu.h37
-rw-r--r--engines/pegasus/pegasus.cpp141
-rw-r--r--engines/pegasus/pegasus.h3
5 files changed, 505 insertions, 44 deletions
diff --git a/engines/pegasus/constants.h b/engines/pegasus/constants.h
index 4af10bf574..6678b70b2d 100755
--- a/engines/pegasus/constants.h
+++ b/engines/pegasus/constants.h
@@ -542,7 +542,7 @@ const tGameMenuCommand kMenuCmdDeathContinue = kMenuCmdQuit + 1;
const tGameMenuCommand kMenuCmdDeathQuitDemo = kMenuCmdDeathContinue + 1;
const tGameMenuCommand kMenuCmdDeathMainMenuDemo = kMenuCmdDeathQuitDemo + 1;
-const tGameMenuCommand kMenuCmdDeathRestore = kMenuCmdDeathContinue + 1;
+const tGameMenuCommand kMenuCmdDeathRestore = kMenuCmdDeathMainMenuDemo + 1;
const tGameMenuCommand kMenuCmdDeathMainMenu = kMenuCmdDeathRestore + 1;
const tGameMenuCommand kMenuCmdPauseSave = kMenuCmdDeathMainMenu + 1;
diff --git a/engines/pegasus/menu.cpp b/engines/pegasus/menu.cpp
index f4ec150eb8..fb6af17870 100755
--- a/engines/pegasus/menu.cpp
+++ b/engines/pegasus/menu.cpp
@@ -23,8 +23,10 @@
*
*/
+#include "pegasus/gamestate.h"
#include "pegasus/menu.h"
#include "pegasus/pegasus.h"
+#include "pegasus/scoring.h"
namespace Pegasus {
@@ -41,6 +43,34 @@ void GameMenu::restorePreviousHandler() {
InputHandler::setInputHandler(_previousHandler);
}
+void GameMenu::drawScore(tGameScoreType score, tGameScoreType total, const Common::Rect &scoreBounds, Surface *numbers) {
+ tCoordType x = scoreBounds.right;
+ drawNumber(total, x, scoreBounds.top, numbers);
+
+ x -= 12;
+ Common::Rect r1(120, 0, 132, 12); // The slash.
+ Common::Rect r2 = r1;
+ r2.moveTo(x, scoreBounds.top);
+ numbers->copyToCurrentPort(r1, r2);
+ drawNumber(score, x, scoreBounds.top, numbers);
+}
+
+void GameMenu::drawNumber(tGameScoreType number, tCoordType &x, tCoordType y, Surface *numbers) {
+ Common::Rect r1(0, 0, 12, 12); // Width, height of one digit
+ Common::Rect r2 = r1;
+ r2.moveTo(x - 12, y);
+
+ do {
+ uint16 digit = number % 10;
+ number /= 10;
+ r1.moveTo(digit * 12, 0);
+ numbers->copyToCurrentPort(r1, r2);
+ r2.translate(-12, 0);
+ } while (number != 0);
+
+ x = r2.right;
+}
+
enum {
kMainMenuStartDemo = 0,
kMainMenuCreditsDemo,
@@ -545,4 +575,340 @@ void CreditsMenu::handleInput(const Input &input, const Hotspot *cursorSpot) {
InputHandler::handleInput(input, cursorSpot);
}
+static const tCoordType kContinueLeft = 44;
+static const tCoordType kContinueTop = 336;
+
+static const tCoordType kContinueSelectLeft = 40;
+static const tCoordType kContinueSelectTopDemo = 331;
+static const tCoordType kContinueSelectTop = 332;
+
+static const tCoordType kMainMenuLeftDemo = 44;
+static const tCoordType kMainMenuTopDemo = 372;
+
+static const tCoordType kMainMenuSelectLeftDemo = 40;
+static const tCoordType kMainMenuSelectTopDemo = 367;
+
+static const tCoordType kQuitLeftDemo = 32;
+static const tCoordType kQuitTopDemo = 412;
+
+static const tCoordType kQuitSelectLeftDemo = 28;
+static const tCoordType kQuitSelectTopDemo = 408;
+
+static const tCoordType kRestoreLeftDeath = 44;
+static const tCoordType kRestoreTopDeath = 372;
+
+static const tCoordType kRestoreSelectLeftDeath = 40;
+static const tCoordType kRestoreSelectTopDeath = 368;
+
+static const tCoordType kMainMenuLeft = 32;
+static const tCoordType kMainMenuTop = 412;
+
+static const tCoordType kMainMenuSelectLeft = 28;
+static const tCoordType kMainMenuSelectTop = 408;
+
+enum {
+ kDeathScreenContinueDemo = 0,
+ kDeathScreenMainMenuDemo,
+ kDeathScreenQuitDemo,
+
+ kFirstDeathSelectionDemo = kDeathScreenContinueDemo,
+ kLastDeathSelectionDemo = kDeathScreenQuitDemo,
+
+ kDeathScreenContinue = 0,
+ kDeathScreenRestore,
+ kDeathScreenMainMenu,
+
+ kFirstDeathSelection = kDeathScreenContinue,
+ kLastDeathSelection = kDeathScreenMainMenu
+};
+
+// Never set the current input handler to the DeathMenu.
+DeathMenu::DeathMenu(const tDeathReason deathReason) : GameMenu(kDeathMenuID), _deathBackground(0), _continueButton(0),
+ _mainMenuButton(0), _quitButton(0), _restoreButton(0), _largeSelect(0), _smallSelect(0) {
+ PegasusEngine *vm = (PegasusEngine *)g_engine;
+ bool isDemo = vm->isDemo();
+
+ _playerWon = (deathReason == kPlayerWonGame);
+
+ Common::String prefix = "Images/";
+ Common::String imageName;
+ if (isDemo) {
+ prefix += "Demo/";
+ imageName = prefix;
+
+ switch (deathReason) {
+ case kDeathFallOffCliff:
+ imageName += "dPfall";
+ break;
+ case kDeathEatenByDinosaur:
+ imageName += "dPdino";
+ break;
+ case kDeathStranded:
+ imageName += "dPstuck";
+ break;
+ default:
+ imageName += "dPdemowin";
+ break;
+ }
+
+ imageName += ".pict";
+ } else {
+ prefix += "Death Screens/";
+ imageName = prefix;
+
+ static const char *fileNames[] = {
+ "dAunmade", "dAbombed", "dAshot", "dAassass", "dAnuked",
+ "dTunmade", "dTshot", "dPfall", "dPdino", "dPstuck",
+ "dNchoke", "dNcaught", "dNcaught", "dNsub", "dNrobot1",
+ "dNrobot2", "dMfall", "dMcaught", "dMtracks", "dMrobot",
+ "dMtoast", "dMexplo1", "dMexplo2", "dMchoke1", "dMchoke2",
+ "dMdroid", "dMfall", "dMgears", "dMshutt1", "dMshutt2",
+ "dWpoison", "dWcaught", "dWplasma", "dWshot", "dAfinale"
+ };
+
+ imageName += fileNames[deathReason - 1];
+ imageName += ".pict";
+ }
+
+ _deathBackground.initFromPICTFile(imageName);
+ _deathReason = deathReason;
+
+ if (!isDemo)
+ drawAllScores();
+
+ _deathBackground.setDisplayOrder(0);
+ _deathBackground.startDisplaying();
+ _deathBackground.show();
+
+ if (isDemo) {
+ if (_playerWon) // Make credits button...
+ _continueButton.initFromPICTFile(prefix + "Credits.pict");
+ else // Make continue button...
+ _continueButton.initFromPICTFile(prefix + "Continue.pict");
+
+ _mainMenuButton.initFromPICTFile(prefix + "MainMenu.pict");
+ _mainMenuButton.setDisplayOrder(1);
+ _mainMenuButton.moveElementTo(kMainMenuLeftDemo, kMainMenuTopDemo);
+ _mainMenuButton.startDisplaying();
+
+ _quitButton.initFromPICTFile(prefix + "Quit.pict");
+ _quitButton.setDisplayOrder(1);
+ _quitButton.moveElementTo(kQuitLeftDemo, kQuitTopDemo);
+ _quitButton.startDisplaying();
+
+ _menuSelection = kDeathScreenContinueDemo;
+ } else {
+ if (!_playerWon) {
+ _mainMenuButton.initFromPICTFile(prefix + "MainMenu.pict");
+ _mainMenuButton.setDisplayOrder(1);
+ _mainMenuButton.moveElementTo(kMainMenuLeft, kMainMenuTop);
+ _mainMenuButton.startDisplaying();
+
+ _restoreButton.initFromPICTFile(prefix + "Restore.pict");
+ _restoreButton.setDisplayOrder(1);
+ _restoreButton.moveElementTo(kRestoreLeftDeath, kRestoreTopDeath);
+ _restoreButton.startDisplaying();
+ }
+
+ _continueButton.initFromPICTFile(prefix + "Continue.pict");
+
+ _menuSelection = kDeathScreenContinue;
+ }
+
+ _smallSelect.initFromPICTFile(prefix + "SelectS.pict", true);
+ _smallSelect.setDisplayOrder(2);
+ _smallSelect.startDisplaying();
+
+ _continueButton.setDisplayOrder(1);
+ _continueButton.moveElementTo(kContinueLeft, kContinueTop);
+ _continueButton.startDisplaying();
+
+ if (isDemo || !_playerWon) {
+ _largeSelect.initFromPICTFile(prefix + "SelectL.pict", true);
+ _largeSelect.setDisplayOrder(2);
+ _largeSelect.startDisplaying();
+ } else {
+ _triumphSound.initFromQuickTime("Sounds/Caldoria/Galactic Triumph");
+ _triumphSound.playSound();
+ }
+
+ updateDisplay();
+}
+
+void DeathMenu::handleInput(const Input &input, const Hotspot *cursorSpot) {
+ PegasusEngine *vm = (PegasusEngine *)g_engine;
+
+ if (input.upButtonDown()) {
+ if (_menuSelection > (vm->isDemo() ? kFirstDeathSelectionDemo : kFirstDeathSelection)) {
+ _menuSelection--;
+ updateDisplay();
+ }
+ } else if (input.downButtonDown() && (vm->isDemo() || !_playerWon)) {
+ if (_menuSelection < (vm->isDemo() ? kLastDeathSelectionDemo : kLastDeathSelection)) {
+ _menuSelection++;
+ updateDisplay();
+ }
+ } else if (JMPPPInput::isMenuButtonPressInput(input)) {
+ if (vm->isDemo()) {
+ switch (_menuSelection) {
+ case kDeathScreenContinueDemo:
+ _continueButton.show();
+ vm->delayShell(kMenuButtonHiliteTime, kMenuButtonHiliteScale);
+ _continueButton.hide();
+ setLastCommand(kMenuCmdDeathContinue);
+ break;
+ case kDeathScreenQuitDemo:
+ _quitButton.show();
+ vm->delayShell(kMenuButtonHiliteTime, kMenuButtonHiliteScale);
+ _quitButton.hide();
+ setLastCommand(kMenuCmdDeathQuitDemo);
+ break;
+ case kDeathScreenMainMenuDemo:
+ _mainMenuButton.show();
+ vm->delayShell(kMenuButtonHiliteTime, kMenuButtonHiliteScale);
+ _mainMenuButton.hide();
+ setLastCommand(kMenuCmdDeathMainMenuDemo);
+ break;
+ }
+ } else {
+ switch (_menuSelection) {
+ case kDeathScreenContinue:
+ _continueButton.show();
+ vm->delayShell(kMenuButtonHiliteTime, kMenuButtonHiliteScale);
+ _continueButton.hide();
+ setLastCommand(kMenuCmdDeathContinue);
+ break;
+ case kDeathScreenRestore:
+ _restoreButton.show();
+ vm->delayShell(kMenuButtonHiliteTime, kMenuButtonHiliteScale);
+ _restoreButton.hide();
+ setLastCommand(kMenuCmdDeathRestore);
+ break;
+ case kDeathScreenMainMenu:
+ _mainMenuButton.show();
+ vm->delayShell(kMenuButtonHiliteTime, kMenuButtonHiliteScale);
+ _mainMenuButton.hide();
+ setLastCommand(kMenuCmdDeathMainMenu);
+ break;
+ }
+ }
+ }
+
+ InputHandler::handleInput(input, cursorSpot);
+}
+
+void DeathMenu::updateDisplay() {
+ if (((PegasusEngine *)g_engine)->isDemo()) {
+ switch (_menuSelection) {
+ case kDeathScreenContinueDemo:
+ _smallSelect.moveElementTo(kContinueSelectLeft, kContinueSelectTopDemo);
+ _smallSelect.show();
+ _largeSelect.hide();
+ break;
+ case kDeathScreenQuitDemo:
+ _largeSelect.moveElementTo(kQuitSelectLeftDemo, kQuitSelectTopDemo);
+ _largeSelect.show();
+ _smallSelect.hide();
+ break;
+ case kDeathScreenMainMenuDemo:
+ _smallSelect.moveElementTo(kMainMenuSelectLeftDemo, kMainMenuSelectTopDemo);
+ _smallSelect.show();
+ _largeSelect.hide();
+ break;
+ }
+ } else {
+ switch (_menuSelection) {
+ case kDeathScreenContinue:
+ _smallSelect.moveElementTo(kContinueSelectLeft, kContinueSelectTop);
+ _smallSelect.show();
+ _largeSelect.hide();
+ break;
+ case kDeathScreenRestore:
+ _smallSelect.moveElementTo(kRestoreSelectLeftDeath, kRestoreSelectTopDeath);
+ _smallSelect.show();
+ _largeSelect.hide();
+ break;
+ case kDeathScreenMainMenu:
+ _largeSelect.moveElementTo(kMainMenuSelectLeft, kMainMenuSelectTop);
+ _largeSelect.show();
+ _smallSelect.hide();
+ break;
+ }
+ }
+}
+
+void DeathMenu::drawAllScores() {
+ Surface numbers;
+ numbers.getImageFromPICTFile("Images/Death Screens/Numbers.pict");
+
+ Common::Rect scoreBounds;
+ tGameScoreType caldoriaTotal = 0;
+
+ switch (_deathReason) {
+ case kDeathCardBomb:
+ case kDeathShotBySinclair:
+ case kDeathSinclairShotDelegate:
+ case kDeathNuclearExplosion:
+ case kDeathGassedInNorad:
+ case kDeathWokeUpNorad:
+ case kDeathArrestedInNorad:
+ case kDeathSubDestroyed:
+ case kDeathRobotThroughNoradDoor:
+ case kDeathRobotSubControlRoom:
+ case kDeathWrongShuttleLock:
+ case kDeathArrestedInMars:
+ case kDeathRunOverByPod:
+ case kDeathDidntGetOutOfWay:
+ case kDeathReactorBurn:
+ case kDeathDidntFindMarsBomb:
+ case kDeathDidntDisarmMarsBomb:
+ case kDeathNoMaskInMaze:
+ case kDeathNoAirInMaze:
+ case kDeathGroundByMazebot:
+ case kDeathMissedOreBucket:
+ case kDeathDidntLeaveBucket:
+ case kDeathRanIntoCanyonWall:
+ case kDeathRanIntoSpaceJunk:
+ case kDeathDidntStopPoison:
+ case kDeathArrestedInWSC:
+ case kDeathHitByPlasma:
+ case kDeathShotOnCatwalk:
+ case kPlayerWonGame:
+ caldoriaTotal += kMaxCaldoriaTSAScoreAfter;
+ scoreBounds = Common::Rect(kDeathScreenScoreLeft, kDeathScreenScoreTop - kDeathScreenScoreSkipVert * 5,
+ kDeathScreenScoreLeft + kDeathScreenScoreWidth, kDeathScreenScoreTop - kDeathScreenScoreSkipVert * 5 + kDeathScreenScoreHeight);
+ drawScore(GameState.getGandhiScore(), kMaxGandhiScore, scoreBounds, &numbers);
+
+ scoreBounds.translate(0, kDeathScreenScoreSkipVert);
+ drawScore(GameState.getWSCScore(), kMaxWSCScore, scoreBounds, &numbers);
+
+ scoreBounds.translate(0, kDeathScreenScoreSkipVert);
+ drawScore(GameState.getNoradScore(), kMaxNoradScore, scoreBounds, &numbers);
+
+ scoreBounds.translate(0, kDeathScreenScoreSkipVert);
+ drawScore(GameState.getMarsScore(), kMaxMarsScore, scoreBounds, &numbers);
+ // fall through
+ case kDeathFallOffCliff:
+ case kDeathEatenByDinosaur:
+ case kDeathStranded:
+ case kDeathShotByTSARobots:
+ scoreBounds = Common::Rect(kDeathScreenScoreLeft, kDeathScreenScoreTop - kDeathScreenScoreSkipVert,
+ kDeathScreenScoreLeft + kDeathScreenScoreWidth, kDeathScreenScoreTop - kDeathScreenScoreSkipVert + kDeathScreenScoreHeight);
+ drawScore(GameState.getPrehistoricScore(), kMaxPrehistoricScore, scoreBounds, &numbers);
+ // fall through
+ case kDeathUncreatedInCaldoria:
+ case kDeathUncreatedInTSA:
+ scoreBounds = Common::Rect(kDeathScreenScoreLeft, kDeathScreenScoreTop, kDeathScreenScoreLeft + kDeathScreenScoreWidth,
+ kDeathScreenScoreTop + kDeathScreenScoreHeight);
+ caldoriaTotal += kMaxCaldoriaTSAScoreBefore;
+ drawScore(GameState.getCaldoriaTSAScore(), caldoriaTotal, scoreBounds, &numbers);
+
+ scoreBounds = Common::Rect(kDeathScreenScoreLeft, kDeathScreenScoreTop - kDeathScreenScoreSkipVert * 6,
+ kDeathScreenScoreLeft + kDeathScreenScoreWidth, kDeathScreenScoreTop - kDeathScreenScoreSkipVert * 6 + kDeathScreenScoreHeight);
+
+ drawScore(GameState.getTotalScore(), kMaxTotalScore, scoreBounds, &numbers);
+ break;
+ }
+}
+
} // End of namespace Pegasus
diff --git a/engines/pegasus/menu.h b/engines/pegasus/menu.h
index 581fb5fb86..17242208d1 100755
--- a/engines/pegasus/menu.h
+++ b/engines/pegasus/menu.h
@@ -52,6 +52,11 @@ protected:
InputHandler *_previousHandler;
tGameMenuCommand _lastCommand;
+
+ void drawScore(tGameScoreType, tGameScoreType, const Common::Rect &, Surface *);
+
+private:
+ void drawNumber(tGameScoreType, tCoordType &, tCoordType, Surface *);
};
class Hotspot;
@@ -91,7 +96,7 @@ protected:
class CreditsMenu : public GameMenu {
public:
- CreditsMenu(void);
+ CreditsMenu();
virtual ~CreditsMenu() {}
virtual void handleInput(const Input &input, const Hotspot *);
@@ -108,6 +113,36 @@ protected:
Picture _smallSelect;
};
+class DeathMenu : public GameMenu {
+public:
+ DeathMenu(const tDeathReason);
+ virtual ~DeathMenu() {}
+
+ virtual void handleInput(const Input &input, const Hotspot *);
+
+ bool playerWon() { return _playerWon; }
+
+protected:
+ void drawAllScores();
+
+ void updateDisplay();
+
+ bool _playerWon;
+ int _menuSelection;
+ tDeathReason _deathReason;
+
+ Picture _deathBackground;
+ Picture _continueButton;
+ Picture _restoreButton;
+ Picture _mainMenuButton;
+ Picture _quitButton;
+
+ Picture _largeSelect;
+ Picture _smallSelect;
+
+ Sound _triumphSound;
+};
+
} // End of namespace Pegasus
#endif
diff --git a/engines/pegasus/pegasus.cpp b/engines/pegasus/pegasus.cpp
index be5a22eeed..468f3a44b5 100644
--- a/engines/pegasus/pegasus.cpp
+++ b/engines/pegasus/pegasus.cpp
@@ -259,47 +259,7 @@ void PegasusEngine::runIntro() {
video->seekToTime(Audio::Timestamp(0, 10 * 600, 600));
- while (!shouldQuit() && !video->endOfVideo()) {
- 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 y = 0; y < frame->h; y++) {
- for (int x = 0; x < frame->w; x++) {
- 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, 0, 0, scaledFrame.w, scaledFrame.h);
- _system->updateScreen();
- scaledFrame.free();
- }
-
- Input input;
- InputHandler::getCurrentInputDevice()->getInput(input, kFilterAllInput);
- if (input.anyInput())
- break;
-
- _system->delayMillis(10);
- }
+ playMovieScaled(video, 0, 0);
delete video;
}
@@ -462,6 +422,8 @@ void PegasusEngine::loadFromContinuePoint() {
if (!loadFromStream(_continuePoint))
error("Failed loading continue point");
+
+ error("STUB: loadFromContinuePoint()");
}
Common::Error PegasusEngine::loadGameState(int slot) {
@@ -608,6 +570,7 @@ void PegasusEngine::doGameMenuCommand(const tGameMenuCommand command) {
}
break;
case kMenuCmdQuit:
+ case kMenuCmdDeathQuitDemo:
if (isDemo())
showTempScreen("Images/Demo/NGquitScrn.pict");
_system->quit();
@@ -622,6 +585,7 @@ void PegasusEngine::doGameMenuCommand(const tGameMenuCommand command) {
error("Start new game (walkthrough mode)");
break;
case kMenuCmdRestore:
+ case kMenuCmdDeathRestore:
error("Load game");
break;
case kMenuCmdCreditsMainMenu:
@@ -632,6 +596,53 @@ void PegasusEngine::doGameMenuCommand(const tGameMenuCommand command) {
// TODO: Fade in
resetIntroTimer();
break;
+ case kMenuCmdDeathContinue:
+ if (((DeathMenu *)_gameMenu)->playerWon()) {
+ if (isDemo()) {
+ showTempScreen("Images/Demo/DemoCredits.pict");
+ // TODO: Fade out
+ _gfx->updateDisplay();
+ // TODO: Fade in
+ } else {
+ // TODO: Fade out
+ useMenu(0);
+ _gfx->clearScreen();
+ _gfx->updateDisplay();
+
+ Video::SeekableVideoDecoder *video = new Video::QuickTimeDecoder();
+ if (!video->loadFile(_introDirectory + "/Closing.movie"))
+ error("Could not load closing movie");
+
+ uint16 x = (640 - video->getWidth() * 2) / 2;
+ uint16 y = (480 - video->getHeight() * 2) / 2;
+
+ playMovieScaled(video, x, y);
+
+ delete video;
+
+ if (shouldQuit())
+ return;
+
+ useMenu(new MainMenu());
+ _gfx->updateDisplay();
+ ((MainMenu *)_gameMenu)->startMainMenuLoop();
+ // TODO: Fade in
+ resetIntroTimer();
+ }
+ } else {
+ loadFromContinuePoint();
+ }
+ break;
+ case kMenuCmdDeathMainMenuDemo:
+ case kMenuCmdDeathMainMenu:
+ // TODO: Fade out
+ useMenu(new MainMenu());
+ _gfx->updateDisplay();
+ ((MainMenu *)_gameMenu)->startMainMenuLoop();
+ // TODO: Fade in
+ if (!isDemo())
+ resetIntroTimer();
+ break;
case kMenuCmdNoCommand:
break;
default:
@@ -961,4 +972,52 @@ void PegasusEngine::checkFlashlight() {
_neighborhood->checkFlashlight();
}
+bool PegasusEngine::playMovieScaled(Video::SeekableVideoDecoder *video, uint16 x, uint16 y) {
+ bool skipped = false;
+
+ while (!shouldQuit() && !video->endOfVideo() && !skipped) {
+ 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();
+ }
+
+ Input input;
+ InputHandler::getCurrentInputDevice()->getInput(input, kFilterAllInput);
+ if (input.anyInput())
+ skipped = true;
+
+ _system->delayMillis(10);
+ }
+
+ return skipped;
+}
+
} // End of namespace Pegasus
diff --git a/engines/pegasus/pegasus.h b/engines/pegasus/pegasus.h
index 6a5913d3a5..f881aa6f4c 100644
--- a/engines/pegasus/pegasus.h
+++ b/engines/pegasus/pegasus.h
@@ -40,7 +40,7 @@
#include "pegasus/neighborhood/neighborhood.h"
namespace Video {
- class QuickTimeDecoder;
+ class SeekableVideoDecoder;
}
namespace Pegasus {
@@ -187,6 +187,7 @@ private:
Hotspot _returnHotspot;
void showLoadDialog();
void showTempScreen(const Common::String &fileName);
+ bool playMovieScaled(Video::SeekableVideoDecoder *video, uint16 x, uint16 y);
// Menu
GameMenu *_gameMenu;