Initial commit
This commit is contained in:
458
engines/pegasus/neighborhood/norad/alpha/subchase.cpp
Normal file
458
engines/pegasus/neighborhood/norad/alpha/subchase.cpp
Normal file
@@ -0,0 +1,458 @@
|
||||
/* 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-2013 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "pegasus/pegasus.h"
|
||||
#include "pegasus/gamestate.h"
|
||||
#include "pegasus/neighborhood/norad/alpha/subchase.h"
|
||||
#include "pegasus/neighborhood/norad/alpha/noradalpha.h"
|
||||
#include "pegasus/neighborhood/norad/constants.h"
|
||||
|
||||
namespace Pegasus {
|
||||
|
||||
static const TimeScale kSubChaseScale = 600;
|
||||
|
||||
static const DisplayOrder kSubChaseOrder = 27000;
|
||||
|
||||
// Segment start and end points.
|
||||
|
||||
static const TimeValue kIntroStart = 0;
|
||||
static const TimeValue kIntroEnd = 2400;
|
||||
static const TimeValue kDialogStart = kIntroEnd;
|
||||
static const TimeValue kDialogEnd = 20920;
|
||||
static const TimeValue kBranch1Start = kDialogEnd;
|
||||
static const TimeValue kBranch1End = 32120;
|
||||
static const TimeValue kBranch2LeftStart = kBranch1End;
|
||||
static const TimeValue kBranch2LeftEnd = 48080;
|
||||
static const TimeValue kBranch3Start = kBranch2LeftEnd;
|
||||
static const TimeValue kBranch3End = 61080;
|
||||
static const TimeValue kBranch4Start = kBranch3End;
|
||||
static const TimeValue kBranch4End = 84080;
|
||||
static const TimeValue kBranch5Start = kBranch4End;
|
||||
static const TimeValue kBranch5End = 94840;
|
||||
static const TimeValue kBranch6Start = kBranch5End;
|
||||
static const TimeValue kBranch6End = 106040;
|
||||
static const TimeValue kBranch7LeftStart = kBranch6End;
|
||||
static const TimeValue kBranch7LeftEnd = 118840;
|
||||
static const TimeValue kExitStart = kBranch7LeftEnd;
|
||||
static const TimeValue kExitEnd = 133200;
|
||||
static const TimeValue kBranch2RightStart = 133200;
|
||||
static const TimeValue kBranch2RightEnd = 149160;
|
||||
static const TimeValue kBranch7RightStart = 168000;
|
||||
static const TimeValue kBranch7RightEnd = 180800;
|
||||
|
||||
// Death start and end points.
|
||||
|
||||
static const TimeValue kDeath4Start = 149160;
|
||||
static const TimeValue kDeath4End = 158040;
|
||||
static const TimeValue kDeath5Start = kDeath4End;
|
||||
static const TimeValue kDeath5End = 163760;
|
||||
static const TimeValue kDeath6Start = kDeath5End;
|
||||
static const TimeValue kDeath6End = 168000;
|
||||
static const TimeValue kDeath7Start = 180800;
|
||||
static const TimeValue kDeath7End = 187040;
|
||||
|
||||
// Chase state.
|
||||
|
||||
enum {
|
||||
kSubDialog,
|
||||
kSubBranch1,
|
||||
kSubBranch2Left,
|
||||
kSubBranch2Right,
|
||||
kSubBranch3,
|
||||
kSubBranch4,
|
||||
kSubBranch5,
|
||||
kSubBranch6,
|
||||
kSubBranch7Left,
|
||||
kSubBranch7Right,
|
||||
kSubExit
|
||||
};
|
||||
|
||||
void HintTimerEvent::fire() {
|
||||
subChase->hintTimerExpired(*this);
|
||||
}
|
||||
|
||||
void BlinkTimerEvent::fire() {
|
||||
subChase->blinkTimerExpired(*this);
|
||||
}
|
||||
|
||||
SubChase::SubChase(Neighborhood *handler) : ChaseInteraction(kNoradSubChaseInteractionID, handler,
|
||||
kNoradSubChaseNotificationID, g_vm), _subMovie(kNoDisplayElement),
|
||||
_hintPict(kNoDisplayElement), _blinkPict(kNoDisplayElement), _canSteerSub(true) {
|
||||
}
|
||||
|
||||
void SubChase::setSoundFXLevel(const uint16 fxLevel) {
|
||||
_subMovie.setVolume(fxLevel);
|
||||
}
|
||||
|
||||
void SubChase::openInteraction() {
|
||||
_subMovie.initFromMovieFile("Images/Norad Alpha/Sub Chase Movie");
|
||||
_subMovie.setVolume(g_vm->getSoundFXLevel());
|
||||
_subMovie.moveElementTo(0, 0);
|
||||
_subMovie.setDisplayOrder(kSubChaseOrder);
|
||||
_subMovie.startDisplaying();
|
||||
_subMovie.show();
|
||||
|
||||
_subCallBack.setNotification(&_chaseNotification);
|
||||
_subCallBack.initCallBack(&_subMovie, kCallBackAtExtremes);
|
||||
|
||||
ChaseInteraction::openInteraction();
|
||||
|
||||
_steerPict.setDisplayOrder(kSubChaseOrder + 1);
|
||||
_steerPict.moveElementTo(kNoradSubSteerLeft, kNoradSubSteerTop);
|
||||
|
||||
_hintPict.initFromPICTFile("Images/Norad Alpha/Sub Chase steerk1.pict", true);
|
||||
_hintPict.setDisplayOrder(kSubChaseOrder + 1);
|
||||
_hintPict.moveElementTo(kNoradSubHintLeft, kNoradSubHintTop);
|
||||
_blinkPict.initFromPICTFile("Images/Norad Alpha/Sub Chase steerk0.pict", true);
|
||||
_blinkPict.setDisplayOrder(kSubChaseOrder + 1);
|
||||
_blinkPict.moveElementTo(kNoradSubHintLeft, kNoradSubHintTop);
|
||||
}
|
||||
|
||||
void SubChase::initInteraction() {
|
||||
_canSteerSub = !GameState.getWalkthroughMode();
|
||||
|
||||
_owner->playMovieSegment(&_subMovie, kIntroStart, kIntroEnd);
|
||||
|
||||
_subCallBack.scheduleCallBack(kTriggerAtStop, 0, 0);
|
||||
|
||||
if (_canSteerSub) {
|
||||
_steerPict.startDisplaying();
|
||||
_hintPict.startDisplaying();
|
||||
_blinkPict.startDisplaying();
|
||||
startHintTimer(20000 - kDialogStart, kSubChaseScale, kStartedHint);
|
||||
_subCallBack.setCallBackFlag(kChaseEnteredBranchZone);
|
||||
_subMovie.setSegment(kDialogStart, kBranch1End - kDecisionTime);
|
||||
} else {
|
||||
_subCallBack.setCallBackFlag(kChaseFinished);
|
||||
_subMovie.setSegment(kDialogStart, kExitEnd);
|
||||
}
|
||||
|
||||
_subState = kSubDialog;
|
||||
_subMovie.setTime(kDialogStart);
|
||||
_subMovie.start();
|
||||
|
||||
ChaseInteraction::initInteraction();
|
||||
}
|
||||
|
||||
void SubChase::closeInteraction() {
|
||||
_subMovie.stop();
|
||||
_subMovie.stopDisplaying();
|
||||
_subMovie.releaseMovie();
|
||||
_subCallBack.releaseCallBack();
|
||||
|
||||
_hintPict.hide();
|
||||
_hintPict.deallocateSurface();
|
||||
|
||||
_blinkPict.hide();
|
||||
_blinkPict.deallocateSurface();
|
||||
|
||||
ChaseInteraction::closeInteraction();
|
||||
}
|
||||
|
||||
void SubChase::receiveNotification(Notification *notification, const NotificationFlags flags) {
|
||||
if (notification == &_chaseNotification && flags == kChaseFinished) {
|
||||
if (_subState != kSubDialog && _subState != kSubExit) {
|
||||
// We died
|
||||
((NoradAlpha *)_owner)->die(kDeathSubDestroyed);
|
||||
} else {
|
||||
_subMovie.stopDisplaying();
|
||||
g_vm->_gfx->enableErase();
|
||||
g_vm->_gfx->updateDisplay();
|
||||
g_vm->_gfx->disableErase();
|
||||
g_vm->jumpToNewEnvironment(kNoradDeltaID, kNorad41, kEast);
|
||||
}
|
||||
}
|
||||
ChaseInteraction::receiveNotification(notification, flags);
|
||||
}
|
||||
|
||||
void SubChase::handleInput(const Input &input, const Hotspot *cursorSpot) {
|
||||
if (_subMovie.getTime() < kBranch1Start && input.anyInput()) {
|
||||
if (_canSteerSub) {
|
||||
if (!_blinkFuse.isFuseLit()) {
|
||||
// If the hint is not blinking then it must not be running, so display it
|
||||
_hintPict.show();
|
||||
startBlinkTimer(10, 10, kEnteredBlinkState);
|
||||
}
|
||||
_subState = kSubBranch1;
|
||||
startHintTimer(3000, kSubChaseScale, kEndedHint);
|
||||
} else {
|
||||
_subState = kSubExit;
|
||||
}
|
||||
_subMovie.setTime(kBranch1Start);
|
||||
} else {
|
||||
ChaseInteraction::handleInput(input, cursorSpot);
|
||||
}
|
||||
}
|
||||
|
||||
void SubChase::setUpBranch() {
|
||||
TimeValue branchStart, branchEnd;
|
||||
|
||||
branchStart = 0;
|
||||
branchEnd = 0;
|
||||
switch (_subState) {
|
||||
case kSubDialog:
|
||||
case kSubBranch1:
|
||||
branchStart = kBranch1End - kDecisionTime;
|
||||
branchEnd = kBranch1End;
|
||||
break;
|
||||
case kSubBranch2Left:
|
||||
branchStart = kBranch2LeftEnd - kDecisionTime;
|
||||
branchEnd = kBranch2LeftEnd;
|
||||
break;
|
||||
case kSubBranch2Right:
|
||||
branchStart = kBranch2RightEnd - kDecisionTime;
|
||||
branchEnd = kBranch2RightEnd;
|
||||
break;
|
||||
case kSubBranch3:
|
||||
branchStart = kBranch3End - kDecisionTime;
|
||||
branchEnd = kBranch3End;
|
||||
break;
|
||||
case kSubBranch4:
|
||||
branchStart = kBranch4End - kDecisionTime;
|
||||
branchEnd = kBranch4End;
|
||||
break;
|
||||
case kSubBranch5:
|
||||
branchStart = kBranch5End - kDecisionTime;
|
||||
branchEnd = kBranch5End;
|
||||
break;
|
||||
case kSubBranch6:
|
||||
branchStart = kBranch6End - kDecisionTime;
|
||||
branchEnd = kBranch6End;
|
||||
break;
|
||||
case kSubBranch7Left:
|
||||
branchStart = kBranch7LeftEnd - kDecisionTime;
|
||||
branchEnd = kBranch7LeftEnd;
|
||||
break;
|
||||
case kSubBranch7Right:
|
||||
branchStart = kBranch7RightEnd - kDecisionTime;
|
||||
branchEnd = kBranch7RightEnd;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
_subMovie.setSegment(branchStart, branchEnd);
|
||||
|
||||
_subCallBack.setCallBackFlag(kChaseExitedBranchZone);
|
||||
_subCallBack.scheduleCallBack(kTriggerAtStop, 0, 0);
|
||||
}
|
||||
|
||||
void SubChase::branchLeft() {
|
||||
TimeValue branchStart, branchEnd;
|
||||
NotificationFlags flag;
|
||||
|
||||
branchStart = 0;
|
||||
branchEnd = 0;
|
||||
flag = 0;
|
||||
switch (_subState) {
|
||||
case kSubDialog:
|
||||
case kSubBranch1:
|
||||
branchStart = kBranch2LeftStart;
|
||||
branchEnd = kBranch2LeftEnd;
|
||||
// Don't show the controls hint when we approach the whale
|
||||
// since the branch segments here are identical
|
||||
flag = kChaseExitedBranchZone;
|
||||
_subState = kSubBranch2Left;
|
||||
break;
|
||||
case kSubBranch2Left:
|
||||
case kSubBranch2Right:
|
||||
branchStart = kBranch3Start;
|
||||
branchEnd = kBranch3End - kDecisionTime;
|
||||
flag = kChaseEnteredBranchZone;
|
||||
_subState = kSubBranch3;
|
||||
break;
|
||||
case kSubBranch3:
|
||||
branchStart = kBranch4Start;
|
||||
branchEnd = kBranch4End - kDecisionTime;
|
||||
flag = kChaseEnteredBranchZone;
|
||||
_subState = kSubBranch4;
|
||||
break;
|
||||
case kSubBranch4:
|
||||
branchStart = kDeath5Start;
|
||||
branchEnd = kDeath5End;
|
||||
flag = kChaseFinished;
|
||||
_subState = kSubBranch5;
|
||||
break;
|
||||
case kSubBranch5:
|
||||
branchStart = kBranch6Start;
|
||||
branchEnd = kBranch6End - kDecisionTime;
|
||||
flag = kChaseEnteredBranchZone;
|
||||
_subState = kSubBranch6;
|
||||
break;
|
||||
case kSubBranch6:
|
||||
branchStart = kBranch7LeftStart;
|
||||
branchEnd = kBranch7LeftEnd;
|
||||
flag = kChaseExitedBranchZone;
|
||||
_subState = kSubBranch7Left;
|
||||
break;
|
||||
case kSubBranch7Left:
|
||||
case kSubBranch7Right:
|
||||
branchStart = kExitStart;
|
||||
branchEnd = kExitEnd;
|
||||
flag = kChaseFinished;
|
||||
_subState = kSubExit;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
_subMovie.setSegment(branchStart, branchEnd);
|
||||
_subMovie.setTime(branchStart);
|
||||
|
||||
_subCallBack.setCallBackFlag(flag);
|
||||
_subCallBack.scheduleCallBack(kTriggerAtStop, 0, 0);
|
||||
}
|
||||
|
||||
void SubChase::branchRight() {
|
||||
TimeValue branchStart, branchEnd;
|
||||
NotificationFlags flag;
|
||||
|
||||
branchStart = 0;
|
||||
branchEnd = 0;
|
||||
flag = 0;
|
||||
switch (_subState) {
|
||||
case kSubDialog:
|
||||
case kSubBranch1:
|
||||
branchStart = kBranch2RightStart;
|
||||
branchEnd = kBranch2RightEnd;
|
||||
// Don't show the controls hint when we approach the whale
|
||||
// since the branch segments here are identical
|
||||
flag = kChaseExitedBranchZone;
|
||||
_subState = kSubBranch2Right;
|
||||
break;
|
||||
case kSubBranch2Left:
|
||||
case kSubBranch2Right:
|
||||
branchStart = kBranch3Start;
|
||||
branchEnd = kBranch3End - kDecisionTime;
|
||||
flag = kChaseEnteredBranchZone;
|
||||
_subState = kSubBranch3;
|
||||
break;
|
||||
case kSubBranch3:
|
||||
branchStart = kDeath4Start;
|
||||
branchEnd = kDeath4End;
|
||||
flag = kChaseFinished;
|
||||
_subState = kSubBranch4;
|
||||
break;
|
||||
case kSubBranch4:
|
||||
branchStart = kBranch5Start;
|
||||
branchEnd = kBranch5End - kDecisionTime;
|
||||
flag = kChaseEnteredBranchZone;
|
||||
_subState = kSubBranch5;
|
||||
break;
|
||||
case kSubBranch5:
|
||||
branchStart = kDeath6Start;
|
||||
branchEnd = kDeath6End;
|
||||
flag = kChaseFinished;
|
||||
_subState = kSubBranch6;
|
||||
break;
|
||||
case kSubBranch6:
|
||||
if (g_vm->getRandomBit()) {
|
||||
branchStart = kBranch7RightStart;
|
||||
branchEnd = kBranch7RightEnd;
|
||||
flag = kChaseExitedBranchZone;
|
||||
} else {
|
||||
branchStart = kDeath7Start;
|
||||
branchEnd = kDeath7End;
|
||||
flag = kChaseFinished;
|
||||
}
|
||||
_subState = kSubBranch7Right;
|
||||
break;
|
||||
case kSubBranch7Left:
|
||||
case kSubBranch7Right:
|
||||
branchStart = kExitStart;
|
||||
branchEnd = kExitEnd;
|
||||
flag = kChaseFinished;
|
||||
_subState = kSubExit;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
_subMovie.setSegment(branchStart, branchEnd);
|
||||
_subMovie.setTime(branchStart);
|
||||
|
||||
_subCallBack.setCallBackFlag(flag);
|
||||
_subCallBack.scheduleCallBack(kTriggerAtStop, 0, 0);
|
||||
}
|
||||
|
||||
void SubChase::dontBranch() {
|
||||
if (g_vm->getRandomBit())
|
||||
branchLeft();
|
||||
else
|
||||
branchRight();
|
||||
}
|
||||
|
||||
void SubChase::startHintTimer(TimeValue time, TimeScale scale, HintTimerCode code) {
|
||||
if (_canSteerSub) {
|
||||
_hintFuse.primeFuse(time, scale);
|
||||
_hintEvent.subChase = this;
|
||||
_hintEvent.theEvent = code;
|
||||
_hintFuse.setFunctor(new Common::Functor0Mem<void, HintTimerEvent>(&_hintEvent, &HintTimerEvent::fire));
|
||||
_hintFuse.lightFuse();
|
||||
}
|
||||
}
|
||||
|
||||
void SubChase::hintTimerExpired(HintTimerEvent &event) {
|
||||
switch (event.theEvent) {
|
||||
case kStartedHint:
|
||||
_hintPict.show();
|
||||
startBlinkTimer(10, 10, kEnteredBlinkState);
|
||||
startHintTimer(3920, kSubChaseScale, kEndedHint);
|
||||
break;
|
||||
case kEndedHint:
|
||||
_hintPict.hide();
|
||||
_blinkPict.hide();
|
||||
_blinkFuse.stopFuse();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void SubChase::startBlinkTimer(TimeValue time, TimeScale scale, BlinkTimerCode code) {
|
||||
_blinkFuse.primeFuse(time, scale);
|
||||
_blinkEvent.subChase = this;
|
||||
_blinkEvent.theEvent = code;
|
||||
_blinkFuse.setFunctor(new Common::Functor0Mem<void, BlinkTimerEvent>(&_blinkEvent, &BlinkTimerEvent::fire));
|
||||
_blinkFuse.lightFuse();
|
||||
}
|
||||
|
||||
void SubChase::blinkTimerExpired(BlinkTimerEvent &event) {
|
||||
switch (event.theEvent) {
|
||||
case kEnteredBlinkState:
|
||||
_hintPict.hide();
|
||||
_blinkPict.show();
|
||||
startBlinkTimer(5, 10, kExitedBlinkState);
|
||||
break;
|
||||
case kExitedBlinkState:
|
||||
_blinkPict.hide();
|
||||
_hintPict.show();
|
||||
startBlinkTimer(10, 10, kEnteredBlinkState);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
} // End of namespace Pegasus
|
||||
Reference in New Issue
Block a user