diff options
author | Matthew Hoops | 2011-12-15 00:02:10 -0500 |
---|---|---|
committer | Matthew Hoops | 2011-12-15 00:02:10 -0500 |
commit | 4b93bc6456aae0912c909d4349845544e1c9d23f (patch) | |
tree | 6a2fbba6935896ca17c52f7245fbdda51d120129 | |
parent | a328f32fed85743f85b26876b9ade388d4eb0bbd (diff) | |
download | scummvm-rg350-4b93bc6456aae0912c909d4349845544e1c9d23f.tar.gz scummvm-rg350-4b93bc6456aae0912c909d4349845544e1c9d23f.tar.bz2 scummvm-rg350-4b93bc6456aae0912c909d4349845544e1c9d23f.zip |
PEGASUS: Add Norad Delta
And with that, ladies and gentlemen, Pegasus Prime is officially completable in ScummVM.
20 files changed, 2993 insertions, 493 deletions
diff --git a/engines/pegasus/constants.h b/engines/pegasus/constants.h index cc096ddfb0..c6d4e45dcc 100755 --- a/engines/pegasus/constants.h +++ b/engines/pegasus/constants.h @@ -736,9 +736,6 @@ static const tGameMode kModeInventoryPick = kLastGameShellMode + 1; static const tGameMode kModeBiochipPick = kModeInventoryPick + 1; static const tGameMode kModeInfoScreen = kModeBiochipPick + 1; -// TODO: Remove me -static const tRoomID kNorad41 = 0; - } // End of namespace Pegasus #endif diff --git a/engines/pegasus/module.mk b/engines/pegasus/module.mk index e19b45eeeb..cb44a04171 100644 --- a/engines/pegasus/module.mk +++ b/engines/pegasus/module.mk @@ -82,6 +82,8 @@ MODULE_OBJS = \ neighborhood/norad/alpha/noradalpha.o \ neighborhood/norad/alpha/panorama.o \ neighborhood/norad/alpha/panoramascroll.o \ + neighborhood/norad/delta/globegame.o \ + neighborhood/norad/delta/noraddelta.o \ neighborhood/prehistoric/prehistoric.o \ neighborhood/tsa/fulltsa.o \ neighborhood/tsa/tinytsa.o \ diff --git a/engines/pegasus/neighborhood/norad/alpha/ecrmonitor.cpp b/engines/pegasus/neighborhood/norad/alpha/ecrmonitor.cpp index 1dc770ae36..2af4335cc5 100755 --- a/engines/pegasus/neighborhood/norad/alpha/ecrmonitor.cpp +++ b/engines/pegasus/neighborhood/norad/alpha/ecrmonitor.cpp @@ -24,6 +24,7 @@ */ #include "pegasus/pegasus.h" +#include "pegasus/neighborhood/norad/constants.h" #include "pegasus/neighborhood/norad/norad.h" #include "pegasus/neighborhood/norad/alpha/ecrmonitor.h" diff --git a/engines/pegasus/neighborhood/norad/alpha/fillingstation.cpp b/engines/pegasus/neighborhood/norad/alpha/fillingstation.cpp index a858e75928..c115f903b0 100755 --- a/engines/pegasus/neighborhood/norad/alpha/fillingstation.cpp +++ b/engines/pegasus/neighborhood/norad/alpha/fillingstation.cpp @@ -26,6 +26,7 @@ #include "pegasus/gamestate.h" #include "pegasus/pegasus.h" #include "pegasus/items/inventory/airmask.h" +#include "pegasus/neighborhood/norad/constants.h" #include "pegasus/neighborhood/norad/alpha/fillingstation.h" #include "pegasus/neighborhood/norad/alpha/noradalpha.h" diff --git a/engines/pegasus/neighborhood/norad/alpha/noradalpha.cpp b/engines/pegasus/neighborhood/norad/alpha/noradalpha.cpp index 46bebf699a..3bab3b822d 100755 --- a/engines/pegasus/neighborhood/norad/alpha/noradalpha.cpp +++ b/engines/pegasus/neighborhood/norad/alpha/noradalpha.cpp @@ -28,6 +28,7 @@ #include "pegasus/pegasus.h" #include "pegasus/ai/ai_area.h" #include "pegasus/items/inventory/airmask.h" +#include "pegasus/neighborhood/norad/constants.h" #include "pegasus/neighborhood/norad/subcontrolroom.h" #include "pegasus/neighborhood/norad/alpha/ecrmonitor.h" #include "pegasus/neighborhood/norad/alpha/fillingstation.h" diff --git a/engines/pegasus/neighborhood/norad/alpha/noradalpha.h b/engines/pegasus/neighborhood/norad/alpha/noradalpha.h index 72a7ac6339..9b96d136ec 100755 --- a/engines/pegasus/neighborhood/norad/alpha/noradalpha.h +++ b/engines/pegasus/neighborhood/norad/alpha/noradalpha.h @@ -30,33 +30,6 @@ namespace Pegasus { -const TimeValue kAlphaBumpIntoWallIn = 0; -const TimeValue kAlphaBumpIntoWallOut = 303; - -const TimeValue kAlphaAccessDeniedIn = 303; -const TimeValue kAlphaAccessDeniedOut = 3045; - -const TimeValue kAlphaRegDoorCloseIn = 3045; -const TimeValue kAlphaRegDoorCloseOut = 4476; - -const TimeValue kAlphaElevatorDoorCloseIn = 4476; -const TimeValue kAlphaElevatorDoorCloseOut = 5071; - -const TimeValue kAlphaCantTransportIn = 5071; -const TimeValue kAlphaCantTransportOut = 9348; - -const TimeValue kPressureDoorIntro1In = 9348; -const TimeValue kPressureDoorIntro1Out = 11061; - -const TimeValue kPressureDoorIntro2In = 11061; -const TimeValue kPressureDoorIntro2Out = 14098; - -const TimeValue kN22ReplyIn = 14098; -const TimeValue kN22ReplyOut = 18442; - -const TimeValue kLoadClawIntroIn = 18442; -const TimeValue kLoadClawIntroOut = 20698; - class Item; class NoradAlpha : public Norad { diff --git a/engines/pegasus/neighborhood/norad/constants.h b/engines/pegasus/neighborhood/norad/constants.h new file mode 100755 index 0000000000..8d5eff4a95 --- /dev/null +++ b/engines/pegasus/neighborhood/norad/constants.h @@ -0,0 +1,755 @@ +/* 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_NEIGHBORHOOD_NORAD_CONSTANTS_H +#define PEGASUS_NEIGHBORHOOD_NORAD_CONSTANTS_H + +#include "pegasus/constants.h" + +namespace Pegasus { + +// Norad Alpha spot constants + +const TimeValue kAlphaBumpIntoWallIn = 0; +const TimeValue kAlphaBumpIntoWallOut = 303; + +const TimeValue kAlphaAccessDeniedIn = 303; +const TimeValue kAlphaAccessDeniedOut = 3045; + +const TimeValue kAlphaRegDoorCloseIn = 3045; +const TimeValue kAlphaRegDoorCloseOut = 4476; + +const TimeValue kAlphaElevatorDoorCloseIn = 4476; +const TimeValue kAlphaElevatorDoorCloseOut = 5071; + +const TimeValue kAlphaCantTransportIn = 5071; +const TimeValue kAlphaCantTransportOut = 9348; + +const TimeValue kAlphaPressureDoorIntro1In = 9348; +const TimeValue kAlphaPressureDoorIntro1Out = 11061; + +const TimeValue kAlphaPressureDoorIntro2In = 11061; +const TimeValue kAlphaPressureDoorIntro2Out = 14098; + +const TimeValue kN22ReplyIn = 14098; +const TimeValue kN22ReplyOut = 18442; + +const TimeValue kAlphaLoadClawIntroIn = 18442; +const TimeValue kAlphaLoadClawIntroOut = 20698; + +// Norad Delta spot constants + +const TimeValue kDeltaBumpIntoWallIn = 0; +const TimeValue kDeltaBumpIntoWallOut = 303; + +const TimeValue kDeltaAccessDeniedIn = 303; +const TimeValue kDeltaAccessDeniedOut = 3045; + +const TimeValue kDeltaRegDoorCloseIn = 3045; +const TimeValue kDeltaRegDoorCloseOut = 4476; + +const TimeValue kDeltaElevatorDoorCloseIn = 4476; +const TimeValue kDeltaElevatorDoorCloseOut = 5071; + +const TimeValue kPressureDoorIntro1In = 5071; +const TimeValue kPressureDoorIntro1Out = 6784; + +const TimeValue kPressureDoorIntro2In = 6784; +const TimeValue kPressureDoorIntro2Out = 9821; + +const TimeValue kLoadClawIntroIn = 9821; +const TimeValue kLoadClawIntroOut = 12077; + +const TimeValue kHoldForRetinalIn = 12077; +const TimeValue kHoldForRetinalOut = 14104; + +const TimeValue kRetinalScanFailedIn = 14104; +const TimeValue kRetinalScanFailedOut = 17538; + +const TimeValue kAddisAbabaIn = 17538; +const TimeValue kAddisAbabaOut = 19263; + +const TimeValue kBangkokIn = 19263; +const TimeValue kBangkokOut = 20201; + +const TimeValue kBonnIn = 20201; +const TimeValue kBonnOut = 20915; + +const TimeValue kDublinIn = 20915; +const TimeValue kDublinOut = 21660; + +const TimeValue kHonoluluIn = 21660; +const TimeValue kHonoluluOut = 22498; + +const TimeValue kMadridIn = 22498; +const TimeValue kMadridOut = 23474; + +const TimeValue kReykjavikIn = 23474; +const TimeValue kReykjavikOut = 24488; + +const TimeValue kSanAntonioIn = 24488; +const TimeValue kSanAntonioOut = 25561; + +const TimeValue kSeoulIn = 25561; +const TimeValue kSeoulOut = 26461; + +const TimeValue kSvortalskIn = 26461; +const TimeValue kSvortalskOut = 27582; + +const TimeValue kSiloBeepIn = 27582; +const TimeValue kSiloBeepOut = 27721; + +const TimeValue kAllSilosDeactivatedIn = 27721; +const TimeValue kAllSilosDeactivatedOut = 28928; + +const TimeValue kGlobalLaunchOverrideIn = 28928; +const TimeValue kGlobalLaunchOverrideOut = 30736; + +const TimeValue kLaunchSiloSelectedIn = 30736; +const TimeValue kLaunchSiloSelectedOut = 31660; + +const TimeValue kLaunchToProceedIn = 31660; +const TimeValue kLaunchToProceedOut = 32536; + +const TimeValue kMaximumDeactivationIn = 32536; +const TimeValue kMaximumDeactivationOut = 34337; + +const TimeValue kMissileLaunchedIn = 34337; +const TimeValue kMissileLaunchedOut = 35082; + +const TimeValue kNewLaunchSiloIn = 35082; +const TimeValue kNewLaunchSiloOut = 36320; + +const TimeValue kStrikeAuthorizedIn = 36320; +const TimeValue kStrikeAuthorizedOut = 37393; + +const TimeValue kPrimaryTargetIn = 37393; +const TimeValue kPrimaryTargetOut = 38628; + +const TimeValue kSiloDeactivatedIn = 38628; +const TimeValue kSiloDeactivatedOut = 39566; + +const TimeValue kStrikeCodeRejectedIn = 39566; +const TimeValue kStrikeCodeRejectedOut = 41056; + +const TimeValue kToDeactivateIn = 41056; +const TimeValue kToDeactivateOut = 46494; + +const TimeValue kTwoMinutesIn = 46494; +const TimeValue kTwoMinutesOut = 47166; + +const TimeValue kOneMinuteIn = 47166; +const TimeValue kOneMinuteOut = 47856; + +const TimeValue kFiftySecondsIn = 47856; +const TimeValue kFiftySecondsOut = 48691; + +const TimeValue kFortySecondsIn = 48691; +const TimeValue kFortySecondsOut = 49500; + +const TimeValue kThirtySecondsIn = 49500; +const TimeValue kThirtySecondsOut = 50362; + +const TimeValue kTwentySecondsIn = 50362; +const TimeValue kTwentySecondsOut = 51245; + +const TimeValue kTenSecondsIn = 51245; +const TimeValue kTenSecondsOut = 52069; + +const TimeValue kGiveUpHumanIn = 52069; +const TimeValue kGiveUpHumanOut = 55023; + +const TimeValue kIJustBrokeIn = 55023; +const TimeValue kIJustBrokeOut = 59191; + +const TimeValue kTheOnlyGoodHumanIn = 59191; +const TimeValue kTheOnlyGoodHumanOut = 62379; + +const TimeValue kYouAreRunningIn = 62379; +const TimeValue kYouAreRunningOut = 64201; + +const TimeValue kYouCannotPossiblyIn = 64201; +const TimeValue kYouCannotPossiblyOut = 65740; + +const TimeValue kYouWillFailIn = 65740; +const TimeValue kYouWillFailOut = 67217; + +const tCanOpenDoorReason kCantOpenBadPressure = kCantOpenLastReason + 1; + +const tNotificationFlags kAirTimerExpiredFlag = kLastNeighborhoodNotificationFlag << 1; + +const uint16 kNoradWarningVolume = 0x100 / 3; +const uint16 kNoradSuckWindVolume = 0x100 / 2; + +const int16 kElevatorCompassAngle = -40; +const int16 kSubPlatformCompassAngle = 45; +const int16 kSubControlCompassAngle = -10; + +// Norad interactions. + +const tInteractionID kNoradGlobeGameInteractionID = 0; +const tInteractionID kNoradECRMonitorInteractionID = 1; +const tInteractionID kNoradFillingStationInteractionID = 2; +const tInteractionID kNoradElevatorInteractionID = 3; +const tInteractionID kNoradPressureDoorInteractionID = 4; +const tInteractionID kNoradSubControlRoomInteractionID = 5; +const tInteractionID kNoradSubPlatformInteractionID = 6; + +///////////////////////////////////////////// +// +// Norad Alpha + +const tCoordType kECRSlideShowLeft = kNavAreaLeft + 78; +const tCoordType kECRSlideShowTop = kNavAreaTop + 1; + +const tCoordType kECRPanLeft = kNavAreaLeft + 78 + 5; +const tCoordType kECRPanTop = kNavAreaTop + 1 + 4; +const tCoordType kECRPanRight = kECRPanLeft + 213; +const tCoordType kECRPanBottom = kECRPanTop + 241; + +const tCoordType kNoradAlphaElevatorControlsLeft = kNavAreaLeft + 332; +const tCoordType kNoradAlphaElevatorControlsTop = kNavAreaTop + 127; + +const tCoordType kNoradAlpha01LeftSideLeft = kNavAreaLeft + 0; +const tCoordType kNoradAlpha01LeftSideTop = kNavAreaTop + 0; + +const tCoordType kNoradAlpha01RightSideLeft = kNavAreaLeft + 240; +const tCoordType kNoradAlpha01RightSideTop = kNavAreaTop + 12; + +const tCoordType kNoradUpperLevelsLeft = kNavAreaLeft + 98; +const tCoordType kNoradUpperLevelsTop = kNavAreaTop + 31; + +const tCoordType kNoradUpperTypeLeft = kNoradUpperLevelsLeft + 114; +const tCoordType kNoradUpperTypeTop = kNoradUpperLevelsTop + 8; + +const tCoordType kNoradUpperUpLeft = kNavAreaLeft + 361; +const tCoordType kNoradUpperUpTop = kNavAreaTop + 32; + +const tCoordType kNoradUpperDownLeft = kNavAreaLeft + 367; +const tCoordType kNoradUpperDownTop = kNavAreaTop + 66; + +const tCoordType kNoradLowerLevelsLeft = kNavAreaLeft + 74; +const tCoordType kNoradLowerLevelsTop = kNavAreaTop + 157; + +const tCoordType kNoradLowerTypeLeft = kNoradLowerLevelsLeft + 144; +const tCoordType kNoradLowerTypeTop = kNoradLowerLevelsTop + 9; + +const tCoordType kNoradLowerUpLeft = kNavAreaLeft + 380; +const tCoordType kNoradLowerUpTop = kNavAreaTop + 164; + +const tCoordType kNoradLowerDownLeft = kNavAreaLeft + 388; +const tCoordType kNoradLowerDownTop = kNavAreaTop + 212; + +const tCoordType kNoradPlatformLeft = kNavAreaLeft + 36; +const tCoordType kNoradPlatformTop = kNavAreaTop + 87; + +const tCoordType kNoradSubControlLeft = kNavAreaLeft + 0; +const tCoordType kNoradSubControlTop = kNavAreaTop + 84; + +const tCoordType kNoradSubControlPinchLeft = kNoradSubControlLeft + 106; +const tCoordType kNoradSubControlPinchTop = kNoradSubControlTop + 86; + +const tCoordType kNoradSubControlDownLeft = kNoradSubControlLeft + 66; +const tCoordType kNoradSubControlDownTop = kNoradSubControlTop + 106; + +const tCoordType kNoradSubControlRightLeft = kNoradSubControlLeft + 83; +const tCoordType kNoradSubControlRightTop = kNoradSubControlTop + 90; + +const tCoordType kNoradSubControlLeftLeft = kNoradSubControlLeft + 56; +const tCoordType kNoradSubControlLeftTop = kNoradSubControlTop + 91; + +const tCoordType kNoradSubControlUpLeft = kNoradSubControlLeft + 66; +const tCoordType kNoradSubControlUpTop = kNoradSubControlTop + 81; + +const tCoordType kNoradSubControlCCWLeft = kNoradSubControlLeft + 29; +const tCoordType kNoradSubControlCCWTop = kNoradSubControlTop + 88; + +const tCoordType kNoradSubControlCWLeft = kNoradSubControlLeft + 0; +const tCoordType kNoradSubControlCWTop = kNoradSubControlTop + 89; + +const tCoordType kNoradClawMonitorLeft = kNavAreaLeft + 288; +const tCoordType kNoradClawMonitorTop = kNavAreaTop + 97; + +const tCoordType kNoradGreenBallAtALeft = kNoradClawMonitorLeft + 179; +const tCoordType kNoradGreenBallAtATop = kNoradClawMonitorTop + 82; + +const tCoordType kNoradGreenBallAtBLeft = kNoradClawMonitorLeft + 130; +const tCoordType kNoradGreenBallAtBTop = kNoradClawMonitorTop + 73; + +const tCoordType kNoradGreenBallAtCLeft = kNoradClawMonitorLeft + 110; +const tCoordType kNoradGreenBallAtCTop = kNoradClawMonitorTop + 26; + +const tCoordType kNoradGreenBallAtDLeft = kNoradClawMonitorLeft + 21; +const tCoordType kNoradGreenBallAtDTop = kNoradClawMonitorTop + 49; + +///////////////////////////////////////////// +// +// Norad Delta + +const tCoordType kGlobeMonitorLeft = kNavAreaLeft + 360; +const tCoordType kGlobeMonitorTop = kNavAreaTop + 144; + +const tCoordType kGlobeLeft = kNavAreaLeft + 172; +const tCoordType kGlobeTop = kNavAreaTop; + +const tCoordType kGlobeCircleLeftLeft = kNavAreaLeft + 186; +const tCoordType kGlobeCircleLeftTop = kNavAreaTop + 41; + +const tCoordType kGlobeCircleRightLeft = kNavAreaLeft + 321; +const tCoordType kGlobeCircleRightTop = kNavAreaTop + 41; + +const tCoordType kGlobeCircleUpLeft = kNavAreaLeft + 220; +const tCoordType kGlobeCircleUpTop = kNavAreaTop + 7; + +const tCoordType kGlobeCircleDownLeft = kNavAreaLeft + 220; +const tCoordType kGlobeCircleDownTop = kNavAreaTop + 142; + +const tCoordType kGlobeUpperLeftHiliteLeft = kNavAreaLeft + 207; +const tCoordType kGlobeUpperLeftHiliteTop = kNavAreaTop + 28; + +const tCoordType kGlobeUpperRightHiliteLeft = kNavAreaLeft + 307; +const tCoordType kGlobeUpperRightHiliteTop = kNavAreaTop + 28; + +const tCoordType kGlobeLowerLeftHiliteLeft = kNavAreaLeft + 207; +const tCoordType kGlobeLowerLeftHiliteTop = kNavAreaTop + 128; + +const tCoordType kGlobeLowerRightHiliteLeft = kNavAreaLeft + 307; +const tCoordType kGlobeLowerRightHiliteTop = kNavAreaTop + 128; + +const tCoordType kGlobeLeftMotionHiliteLeft = kNavAreaLeft + 182; +const tCoordType kGlobeLeftMotionHiliteTop = kNavAreaTop + 60; + +const tCoordType kGlobeRightMotionHiliteLeft = kNavAreaLeft + 331; +const tCoordType kGlobeRightMotionHiliteTop = kNavAreaTop + 60; + +const tCoordType kGlobeUpMotionHiliteLeft = kNavAreaLeft + 239; +const tCoordType kGlobeUpMotionHiliteTop = kNavAreaTop + 3; + +const tCoordType kGlobeDownMotionHiliteLeft = kNavAreaLeft + 239; +const tCoordType kGlobeDownMotionHiliteTop = kNavAreaTop + 152; + +const tCoordType kGlobeUpperNamesLeft = kNavAreaLeft + 368; +const tCoordType kGlobeUpperNamesTop = kNavAreaTop + 188; + +const tCoordType kGlobeLowerNamesLeft = kNavAreaLeft + 368; +const tCoordType kGlobeLowerNamesTop = kNavAreaTop + 212; + +const tCoordType kGlobeCountdownLeft = kNavAreaLeft + 478; +const tCoordType kGlobeCountdownTop = kNavAreaTop + 164; + +// Norad Alpha display IDs. + +const tDisplayElementID kECRSlideShowMovieID = kNeighborhoodDisplayID; +const tDisplayElementID kECRPanID = kECRSlideShowMovieID + 1; +const tDisplayElementID kNoradAlphaDeathMovieID = kECRPanID + 1; +const tDisplayElementID kNoradElevatorControlsID = kNoradAlphaDeathMovieID + 1; +const tDisplayElementID kN01LeftSideID = kNoradElevatorControlsID + 1; +const tDisplayElementID kN01RightSideID = kN01LeftSideID + 1; +const tDisplayElementID kPressureDoorLevelsID = kN01RightSideID + 1; +const tDisplayElementID kPressureDoorTypeID = kPressureDoorLevelsID + 1; +const tDisplayElementID kPressureDoorUpButtonID = kPressureDoorTypeID + 1; +const tDisplayElementID kPressureDoorDownButtonID = kPressureDoorUpButtonID + 1; +const tDisplayElementID kPlatformMonitorID = kPressureDoorDownButtonID + 1; +const tDisplayElementID kSubControlMonitorID = kPlatformMonitorID + 1; +const tDisplayElementID kClawMonitorID = kSubControlMonitorID + 1; +const tDisplayElementID kSubControlPinchID = kClawMonitorID + 1; +const tDisplayElementID kSubControlDownID = kSubControlPinchID + 1; +const tDisplayElementID kSubControlRightID = kSubControlDownID + 1; +const tDisplayElementID kSubControlLeftID = kSubControlRightID + 1; +const tDisplayElementID kSubControlUpID = kSubControlLeftID + 1; +const tDisplayElementID kSubControlCCWID = kSubControlUpID + 1; +const tDisplayElementID kSubControlCWID = kSubControlCCWID + 1; +const tDisplayElementID kClawMonitorGreenBallID = kSubControlCWID + 1; + +// Norad Delta display IDs. + +const tDisplayElementID kGlobeMonitorID = kNeighborhoodDisplayID; +const tDisplayElementID kGlobeMovieID = kGlobeMonitorID + 14; +const tDisplayElementID kGlobeCircleLeftID = kGlobeMovieID + 1; +const tDisplayElementID kGlobeCircleRightID = kGlobeCircleLeftID + 1; +const tDisplayElementID kGlobeCircleUpID = kGlobeCircleRightID + 1; +const tDisplayElementID kGlobeCircleDownID = kGlobeCircleUpID + 1; +const tDisplayElementID kMotionHiliteLeftID = kGlobeCircleDownID + 1; +const tDisplayElementID kMotionHiliteRightID = kMotionHiliteLeftID + 1; +const tDisplayElementID kMotionHiliteUpID = kMotionHiliteRightID + 1; +const tDisplayElementID kMotionHiliteDownID = kMotionHiliteUpID + 1; +const tDisplayElementID kTargetHiliteUpperLeftID = kMotionHiliteDownID + 1; +const tDisplayElementID kTargetHiliteUpperRightID = kTargetHiliteUpperLeftID + 1; +const tDisplayElementID kTargetHiliteLowerLeftID = kTargetHiliteUpperRightID + 1; +const tDisplayElementID kTargetHiliteLowerRightID = kTargetHiliteLowerLeftID + 1; +const tDisplayElementID kGlobeUpperNamesID = kTargetHiliteLowerRightID + 1; +const tDisplayElementID kGlobeLowerNamesID = kGlobeUpperNamesID + 1; +const tDisplayElementID kGlobeCountdownID = kGlobeLowerNamesID + 1; + +// Norad Alpha: + +const tDisplayOrder kECRMonitorOrder = kMonitorLayer; +const tDisplayOrder kECRPanOrder = kECRMonitorOrder + 1; + +const tDisplayOrder kN01LeftSideOrder = kMonitorLayer; +const tDisplayOrder kN01RightSideOrder = kN01LeftSideOrder + 1; + +const tDisplayOrder kElevatorControlsOrder = kMonitorLayer; + +const tDisplayOrder kPressureLevelsOrder = kMonitorLayer; +const tDisplayOrder kPressureTypeOrder = kPressureLevelsOrder + 1; +const tDisplayOrder kPressureUpOrder = kPressureTypeOrder + 1; +const tDisplayOrder kPressureDownOrder = kPressureUpOrder + 1; + +const tDisplayOrder kPlatformOrder = kMonitorLayer; + +const tDisplayOrder kSubControlOrder = kMonitorLayer; +const tDisplayOrder kClawMonitorOrder = kSubControlOrder + 1; +const tDisplayOrder kSubControlPinchOrder = kClawMonitorOrder + 1; +const tDisplayOrder kSubControlDownOrder = kSubControlPinchOrder + 1; +const tDisplayOrder kSubControlRightOrder = kSubControlDownOrder + 1; +const tDisplayOrder kSubControlLeftOrder = kSubControlRightOrder + 1; +const tDisplayOrder kSubControlUpOrder = kSubControlLeftOrder + 1; +const tDisplayOrder kSubControlCCWOrder = kSubControlUpOrder + 1; +const tDisplayOrder kSubControlCWOrder = kSubControlCCWOrder + 1; +const tDisplayOrder kClawMonitorGreenBallOrder = kSubControlCWOrder + 1; + +// Norad Delta: + +const tDisplayOrder kGlobeMonitorLayer = kMonitorLayer; +const tDisplayOrder kGlobeMovieLayer = kGlobeMonitorLayer + 1; +const tDisplayOrder kGlobeCircleLayer = kGlobeMovieLayer + 1; +const tDisplayOrder kGlobeHilitesLayer = kGlobeCircleLayer + 1; +const tDisplayOrder kGlobeUpperNamesLayer = kGlobeHilitesLayer + 1; +const tDisplayOrder kGlobeLowerNamesLayer = kGlobeUpperNamesLayer + 1; +const tDisplayOrder kGlobeCountdownLayer = kGlobeLowerNamesLayer + 1; + +// Norad Alpha Tables + +const TimeScale kNoradAlphaMovieScale = 600; +const TimeScale kNoradAlphaFramesPerSecond = 15; +const TimeScale kNoradAlphaFrameDuration = 40; + +// Alternate IDs. + +const tAlternateID kAltNoradAlphaNormal = 0; + +// Room IDs. + +const tRoomID kNorad01 = 0; +const tRoomID kNorad01East = 1; +const tRoomID kNorad01West = 2; +const tRoomID kNorad02 = 3; +const tRoomID kNorad03 = 4; +const tRoomID kNorad04 = 5; +const tRoomID kNorad05 = 6; +const tRoomID kNorad06 = 7; +const tRoomID kNorad07 = 8; +const tRoomID kNorad07North = 9; +const tRoomID kNorad08 = 10; +const tRoomID kNorad09 = 11; +const tRoomID kNorad10 = 12; +const tRoomID kNorad10East = 13; +const tRoomID kNorad11 = 14; +const tRoomID kNorad11South = 15; +const tRoomID kNorad12 = 16; +const tRoomID kNorad12South = 17; +const tRoomID kNorad13 = 18; +const tRoomID kNorad14 = 19; +const tRoomID kNorad15 = 20; +const tRoomID kNorad16 = 21; +const tRoomID kNorad17 = 22; +const tRoomID kNorad18 = 23; +const tRoomID kNorad19 = 24; +const tRoomID kNorad19West = 25; +const tRoomID kNorad21 = 26; +const tRoomID kNorad21West = 27; +const tRoomID kNorad22 = 28; +const tRoomID kNorad22West = 29; + +// Hot Spot Activation IDs. + + +// Hot Spot IDs. + +const tHotSpotID kNorad01ECRSpotID = 5000; +const tHotSpotID kNorad01GasSpotID = 5001; +const tHotSpotID kNorad01ECROutSpotID = 5002; +const tHotSpotID kNorad01GasOutSpotID = 5003; +const tHotSpotID kNorad01MonitorSpotID = 5004; +const tHotSpotID kNorad01IntakeSpotID = 5005; +const tHotSpotID kNorad01DispenseSpotID = 5006; +const tHotSpotID kNorad01ArSpotID = 5007; +const tHotSpotID kNorad01CO2SpotID = 5008; +const tHotSpotID kNorad01HeSpotID = 5009; +const tHotSpotID kNorad01OSpotID = 5010; +const tHotSpotID kNorad01NSpotID = 5011; +const tHotSpotID kN01GasCanisterSpotID = 5012; +const tHotSpotID kN01ArgonCanisterSpotID = 5013; +const tHotSpotID kN01AirMaskSpotID = 5014; +const tHotSpotID kN01NitrogenCanisterSpotID = 5015; +const tHotSpotID kN01GasOutletSpotID = 5016; +const tHotSpotID kNorad07DoorSpotID = 5017; +const tHotSpotID kNorad07DoorOutSpotID = 5018; +const tHotSpotID kNorad10DoorSpotID = 5019; +const tHotSpotID kNorad10EastOutSpotID = 5020; +const tHotSpotID kAlphaUpperPressureDoorUpSpotID = 5021; +const tHotSpotID kAlphaUpperPressureDoorDownSpotID = 5022; +const tHotSpotID kNorad11ElevatorSpotID = 5023; +const tHotSpotID kNorad11ElevatorOutSpotID = 5024; +const tHotSpotID kNorad11ElevatorDownSpotID = 5025; +const tHotSpotID kNorad12ElevatorSpotID = 5026; +const tHotSpotID kNorad12ElevatorOutSpotID = 5027; +const tHotSpotID kNorad12ElevatorUpSpotID = 5028; +const tHotSpotID kNorad19MonitorSpotID = 5029; +const tHotSpotID kNorad19MonitorOutSpotID = 5030; +const tHotSpotID kNorad19ActivateMonitorSpotID = 5031; +const tHotSpotID kNorad21WestSpotID = 5032; +const tHotSpotID kNorad21WestOutSpotID = 5033; +const tHotSpotID kAlphaLowerPressureDoorUpSpotID = 5034; +const tHotSpotID kAlphaLowerPressureDoorDownSpotID = 5035; +const tHotSpotID kNorad22MonitorSpotID = 5036; +const tHotSpotID kNorad22MonitorOutSpotID = 5037; +const tHotSpotID kNorad22LaunchPrepSpotID = 5038; +const tHotSpotID kNorad22ClawControlSpotID = 5039; +const tHotSpotID kNorad22ClawPinchSpotID = 5040; +const tHotSpotID kNorad22ClawDownSpotID = 5041; +const tHotSpotID kNorad22ClawRightSpotID = 5042; +const tHotSpotID kNorad22ClawLeftSpotID = 5043; +const tHotSpotID kNorad22ClawUpSpotID = 5044; +const tHotSpotID kNorad22ClawCCWSpotID = 5045; +const tHotSpotID kNorad22ClawCWSpotID = 5046; + +// Extra sequence IDs. + +const tExtraID kNoradArriveFromTSA = 0; +const tExtraID kNorad01RobotTaunt = 1; +const tExtraID kNorad01ZoomInWithGasCanister = 2; +const tExtraID kN01WGasCanister = 3; +const tExtraID kNorad01ZoomOutWithGasCanister = 4; +const tExtraID kN01WZEmptyLit = 5; +const tExtraID kN01WZGasCanisterDim = 6; +const tExtraID kN01WZGasCanisterLit = 7; +const tExtraID kN01WZArgonCanisterDim = 8; +const tExtraID kN01WZArgonCanisterLit = 9; +const tExtraID kN01WZAirMaskDim = 10; +const tExtraID kN01WZAirMaskLit = 11; +const tExtraID kN01WZNitrogenCanisterDim = 12; +const tExtraID kN01WZNitrogenCanisterLit = 13; +const tExtraID kNorad04EastDeath = 14; +const tExtraID kNorad19PrepSub = 15; +const tExtraID kNorad19ExitToSub = 16; +const tExtraID kNorad22SouthIntro = 17; +const tExtraID kNorad22SouthReply = 18; +const tExtraID kNorad22SouthFinish = 19; +const tExtraID kN22ClawFromAToB = 20; +const tExtraID kN22ClawALoop = 21; +const tExtraID kN22ClawAPinch = 22; +const tExtraID kN22ClawACounterclockwise = 23; +const tExtraID kN22ClawAClockwise = 24; +const tExtraID kN22ClawFromBToA = 25; +const tExtraID kN22ClawFromBToC = 26; +const tExtraID kN22ClawFromBToD = 27; +const tExtraID kN22ClawBLoop = 28; +const tExtraID kN22ClawBPinch = 29; +const tExtraID kN22ClawBCounterclockwise = 30; +const tExtraID kN22ClawBClockwise = 31; +const tExtraID kN22ClawFromCToB = 32; +const tExtraID kN22ClawCLoop = 33; +const tExtraID kN22ClawCPinch = 34; +const tExtraID kN22ClawCCounterclockwise = 35; +const tExtraID kN22ClawCClockwise = 36; +const tExtraID kN22ClawFromDToB = 37; +const tExtraID kN22ClawDLoop = 38; +const tExtraID kN22ClawDPinch = 39; +const tExtraID kN22ClawDCounterclockwise = 40; +const tExtraID kN22ClawDClockwise = 41; + + +// Norad Delta Extra sequence IDs. + +const tExtraID kArriveFromSubChase = 0; +const tExtraID kN59ZoomWithRobot = 1; +const tExtraID kN59RobotApproaches = 2; +const tExtraID kN59RobotPunchLoop = 3; +const tExtraID kN59PlayerWins1 = 4; +const tExtraID kN59PlayerWins2 = 5; +const tExtraID kN59RobotWins = 6; +const tExtraID kN59RobotHeadOpens = 7; +const tExtraID kN59Biochips111 = 8; +const tExtraID kN59Biochips011 = 9; +const tExtraID kN59Biochips101 = 10; +const tExtraID kN59Biochips001 = 11; +const tExtraID kN59Biochips110 = 12; +const tExtraID kN59Biochips010 = 13; +const tExtraID kN59Biochips100 = 14; +const tExtraID kN59Biochips000 = 15; +const tExtraID kN59RobotDisappears = 16; +const tExtraID kN60ClawFromAToB = 17; +const tExtraID kN60ClawALoop = 18; +const tExtraID kN60ClawAPinch = 19; +const tExtraID kN60ClawACounterclockwise = 20; +const tExtraID kN60ClawAClockwise = 21; +const tExtraID kN60ClawFromBToA = 22; +const tExtraID kN60ClawFromBToC = 23; +const tExtraID kN60ClawFromBToD = 24; +const tExtraID kN60ClawBLoop = 25; +const tExtraID kN60ClawBPinch = 26; +const tExtraID kN60ClawBCounterclockwise = 27; +const tExtraID kN60ClawBClockwise = 28; +const tExtraID kN60ClawFromCToB = 29; +const tExtraID kN60ClawCLoop = 30; +const tExtraID kN60ClawCPinch = 31; +const tExtraID kN60ClawCCounterclockwise = 32; +const tExtraID kN60ClawCClockwise = 33; +const tExtraID kN60ClawFromDToB = 34; +const tExtraID kN60ClawDLoop = 35; +const tExtraID kN60ClawDPinch = 36; +const tExtraID kN60ClawDCounterclockwise = 37; +const tExtraID kN60ClawDClockwise = 38; +const tExtraID kN60RobotApproaches = 39; +const tExtraID kN60FirstMistake = 40; +const tExtraID kN60ArmActivated = 41; +const tExtraID kN60SecondMistake = 42; +const tExtraID kN60ArmToPositionB = 43; +const tExtraID kN60ThirdMistake = 44; +const tExtraID kN60ArmGrabsRobot = 45; +const tExtraID kN60FourthMistake = 46; +const tExtraID kN60ArmCarriesRobotToPositionA = 47; +const tExtraID kN60PlayerFollowsRobotToDoor = 48; +const tExtraID kN60RobotHeadOpens = 49; +const tExtraID kN60Biochips111 = 50; +const tExtraID kN60Biochips011 = 51; +const tExtraID kN60Biochips101 = 52; +const tExtraID kN60Biochips001 = 53; +const tExtraID kN60Biochips110 = 54; +const tExtraID kN60Biochips010 = 55; +const tExtraID kN60Biochips100 = 56; +const tExtraID kN60Biochips000 = 57; +const tExtraID kN60RobotDisappears = 58; +const tExtraID kNoradDeltaRetinalScanBad = 59; +const tExtraID kNoradDeltaRetinalScanGood = 60; +const tExtraID kN79BrightView = 61; + +// Norad Delta Tables + +const TimeScale kNoradDeltaMovieScale = 600; +const TimeScale kNoradDeltaFramesPerSecond = 15; +const TimeScale kNoradDeltaFrameDuration = 40; + +// Alternate IDs. + +const tAlternateID kAltNoradDeltaNormal = 0; + +// Room IDs. + +const tRoomID kNorad41 = 0; +const tRoomID kNorad42 = 1; +const tRoomID kNorad43 = 2; +const tRoomID kNorad44 = 3; +const tRoomID kNorad45 = 4; +const tRoomID kNorad46 = 5; +const tRoomID kNorad47 = 6; +const tRoomID kNorad48 = 7; +const tRoomID kNorad48South = 8; +const tRoomID kNorad49 = 9; +const tRoomID kNorad49South = 10; +const tRoomID kNorad50 = 11; +const tRoomID kNorad50East = 12; +const tRoomID kNorad51 = 13; +const tRoomID kNorad52 = 14; +const tRoomID kNorad53 = 15; +const tRoomID kNorad54 = 16; +const tRoomID kNorad54North = 17; +const tRoomID kNorad55 = 18; +const tRoomID kNorad56 = 19; +const tRoomID kNorad57 = 20; +const tRoomID kNorad58 = 21; +const tRoomID kNorad59 = 22; +const tRoomID kNorad59West = 23; +const tRoomID kNorad60 = 24; +const tRoomID kNorad60West = 25; +const tRoomID kNorad61 = 26; +const tRoomID kNorad62 = 27; +const tRoomID kNorad63 = 28; +const tRoomID kNorad64 = 29; +const tRoomID kNorad65 = 30; +const tRoomID kNorad66 = 31; +const tRoomID kNorad67 = 32; +const tRoomID kNorad68 = 33; +const tRoomID kNorad68West = 34; +const tRoomID kNorad69 = 35; +const tRoomID kNorad78 = 36; +const tRoomID kNorad79 = 37; +const tRoomID kNorad79West = 38; + +// Hot Spot Activation IDs. + + +// Hot Spot IDs. + +const tHotSpotID kNorad48ElevatorSpotID = 5000; +const tHotSpotID kNorad48ElevatorOutSpotID = 5001; +const tHotSpotID kNorad48ElevatorUpSpotID = 5002; +const tHotSpotID kNorad49ElevatorSpotID = 5003; +const tHotSpotID kNorad49ElevatorOutSpotID = 5004; +const tHotSpotID kNorad49ElevatorDownSpotID = 5005; +const tHotSpotID kNorad50DoorSpotID = 5006; +const tHotSpotID kNorad50DoorOutSpotID = 5007; +const tHotSpotID kDeltaUpperPressureDoorUpSpotID = 5008; +const tHotSpotID kDeltaUpperPressureDoorDownSpotID = 5009; +const tHotSpotID kNorad54DoorSpotID = 5010; +const tHotSpotID kNorad54DoorOutSpotID = 5011; +const tHotSpotID kNorad59WestSpotID = 5012; +const tHotSpotID kNorad59WestOutSpotID = 5013; +const tHotSpotID kDeltaLowerPressureDoorUpSpotID = 5014; +const tHotSpotID kDeltaLowerPressureDoorDownSpotID = 5015; +const tHotSpotID kDelta59RobotHeadSpotID = 5016; +const tHotSpotID kDelta59RobotShieldBiochipSpotID = 5017; +const tHotSpotID kDelta59RobotOpMemBiochipSpotID = 5018; +const tHotSpotID kDelta59RobotRetinalBiochipSpotID = 5019; +const tHotSpotID kNorad60MonitorSpotID = 5020; +const tHotSpotID kNorad60MonitorOutSpotID = 5021; +const tHotSpotID kNorad60LaunchPrepSpotID = 5022; +const tHotSpotID kNorad60ClawControlSpotID = 5023; +const tHotSpotID kNorad60ClawPinchSpotID = 5024; +const tHotSpotID kNorad60ClawDownSpotID = 5025; +const tHotSpotID kNorad60ClawRightSpotID = 5026; +const tHotSpotID kNorad60ClawLeftSpotID = 5027; +const tHotSpotID kNorad60ClawUpSpotID = 5028; +const tHotSpotID kNorad60ClawCCWSpotID = 5029; +const tHotSpotID kNorad60ClawCWSpotID = 5030; +const tHotSpotID kDelta60RobotHeadSpotID = 5031; +const tHotSpotID kDelta60RobotShieldBiochipSpotID = 5032; +const tHotSpotID kDelta60RobotOpMemBiochipSpotID = 5033; +const tHotSpotID kDelta60RobotRetinalBiochipSpotID = 5034; +const tHotSpotID kNorad68WestSpotID = 5035; +const tHotSpotID kNorad68WestOutSpotID = 5036; +const tHotSpotID kNorad79WestSpotID = 5037; +const tHotSpotID kNorad79WestOutSpotID = 5038; +const tHotSpotID kNorad79SpinLeftSpotID = 5039; +const tHotSpotID kNorad79SpinRightSpotID = 5040; +const tHotSpotID kNorad79SpinUpSpotID = 5041; +const tHotSpotID kNorad79SpinDownSpotID = 5042; +const tHotSpotID kNorad79SiloAreaSpotID = 5043; + +} // End of namespace Pegasus + +#endif diff --git a/engines/pegasus/neighborhood/norad/delta/globegame.cpp b/engines/pegasus/neighborhood/norad/delta/globegame.cpp new file mode 100755 index 0000000000..39cccc64fc --- /dev/null +++ b/engines/pegasus/neighborhood/norad/delta/globegame.cpp @@ -0,0 +1,1064 @@ +/* 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 "pegasus/cursor.h" +#include "pegasus/pegasus.h" +#include "pegasus/neighborhood/norad/constants.h" +#include "pegasus/neighborhood/norad/delta/globegame.h" +#include "pegasus/neighborhood/norad/delta/noraddelta.h" + +namespace Pegasus { + +static const TimeValue kDurationPerFrame = 600 / 15; +static const TimeValue kDurationPerRow = kNumLongSlices * kDurationPerFrame; +static const short kVerticalDuration = 16; + +GlobeTracker::GlobeTracker(Movie *globeMovie, Picture *leftHighlight, Picture *rightHighlight, + Picture *upHighlight, Picture *downHighlight) { + _globeMovie = globeMovie; + _leftHighlight = leftHighlight; + _rightHighlight = rightHighlight; + _upHighlight = upHighlight; + _downHighlight = downHighlight; +} + +void GlobeTracker::setTrackParameters(const Hotspot *trackSpot, GlobeTrackDirection direction) { + _trackSpot = trackSpot; + _trackDirection = direction; + + TimeValue time, newTime, start; + + switch (_trackDirection) { + case kTrackLeft: + time = _globeMovie->getTime(); + + if (((time / kDurationPerRow) & 1) == 0) { + start = (time / kDurationPerRow + 1) * kDurationPerRow; + newTime = start + kDurationPerRow - time % kDurationPerRow; + } else { + start = (time / kDurationPerRow) * kDurationPerRow; + newTime = time; + } + + _globeMovie->setSegment(start, start + kDurationPerRow); + + if (newTime != time) { + _globeMovie->setTime(newTime); + _globeMovie->redrawMovieWorld(); + } + + _globeMovie->setFlags(kLoopTimeBase); + break; + case kTrackRight: + time = _globeMovie->getTime(); + + if (((time / kDurationPerRow) & 1) == 0) { + start = (time / kDurationPerRow) * kDurationPerRow; + newTime = time; + } else { + start = (time / kDurationPerRow - 1) * kDurationPerRow; + newTime = start + kDurationPerRow - time % kDurationPerRow; + } + + _globeMovie->setSegment(start, start + kDurationPerRow); + + if (newTime != time) { + _globeMovie->setTime(newTime); + _globeMovie->redrawMovieWorld(); + } + + _globeMovie->setFlags(kLoopTimeBase); + break; + case kTrackUp: + case kTrackDown: + _globeMovie->setSegment(0, _globeMovie->getDuration()); + _globeMovie->setFlags(0); + break; + } +} + +void GlobeTracker::activateHotspots() { + Tracker::activateHotspots(); + + if (_trackSpot) + g_allHotspots.activateOneHotspot(_trackSpot->getObjectID()); +} + +bool GlobeTracker::stopTrackingInput(const Input &input) { + return !JMPPPInput::isPressingInput(input); +} + +void GlobeTracker::continueTracking(const Input &input) { + Common::Point where; + input.getInputLocation(where); + + if (g_allHotspots.findHotspot(where) == _trackSpot) + trackGlobeMovie(); + else + stopGlobeMovie(); +} + +void GlobeTracker::startTracking(const Input &input) { + Tracker::startTracking(input); + trackGlobeMovie(); +} + +void GlobeTracker::stopTracking(const Input &input) { + Tracker::stopTracking(input); + stopGlobeMovie(); +} + +void GlobeTracker::trackGlobeMovie() { + TimeValue time; + + switch (_trackDirection) { + case kTrackLeft: + if (!_globeMovie->isRunning()) + _globeMovie->start(); + + _leftHighlight->show(); + break; + case kTrackRight: + if (!_globeMovie->isRunning()) + _globeMovie->start(); + + _rightHighlight->show(); + break; + case kTrackUp: + time = _globeMovie->getTime(); + + if (_trackTime == 0) { + _trackTime = tickCount(); + } else if ((int)time - (int)kDurationPerRow * 2 >= 0 && (int)tickCount() >= _trackTime + kVerticalDuration) { + _trackTime = tickCount(); + _globeMovie->setTime(time - kDurationPerRow * 2); + _globeMovie->redrawMovieWorld(); + } + + _upHighlight->show(); + break; + case kTrackDown: + time = _globeMovie->getTime(); + + if (_trackTime == 0) { + _trackTime = tickCount(); + } else if (time + kDurationPerRow * 2 < _globeMovie->getDuration() && (int)tickCount() >= _trackTime + kVerticalDuration) { + _trackTime = tickCount(); + _globeMovie->setTime(time + kDurationPerRow * 2); + _globeMovie->redrawMovieWorld(); + } + + _downHighlight->show(); + break; + } +} + +void GlobeTracker::stopGlobeMovie() { + switch (_trackDirection) { + case kTrackLeft: + _leftHighlight->hide(); + _globeMovie->stop(); + break; + case kTrackRight: + _rightHighlight->hide(); + _globeMovie->stop(); + break; + case kTrackUp: + _upHighlight->hide(); + _trackTime = tickCount() - kVerticalDuration; + break; + case kTrackDown: + _downHighlight->hide(); + _trackTime = tickCount() - kVerticalDuration; + break; + } +} + +// Globe game PICTs: + +static const tResIDType kGlobeCircleLeftPICTID = 300; +static const tResIDType kGlobeCircleRightPICTID = 301; +static const tResIDType kGlobeCircleUpPICTID = 302; +static const tResIDType kGlobeCircleDownPICTID = 303; +static const tResIDType kTargetUpperLeftPICTID = 304; +static const tResIDType kTargetUpperRightPICTID = 305; +static const tResIDType kTargetLowerLeftPICTID = 306; +static const tResIDType kTargetLowerRightPICTID = 307; +static const tResIDType kMotionHiliteLeftPICTID = 308; +static const tResIDType kMotionHiliteRightPICTID = 309; +static const tResIDType kMotionHiliteUpPICTID = 310; +static const tResIDType kMotionHiliteDownPICTID = 311; + +const tResIDType kGlobeCountdownDigitsID = 350; + +static const int kGlobeCountdownWidth = 28; +static const int kGlobeCountdownHeight = 12; +static const int kGlobeCountdownOffset1 = 12; +static const int kGlobeCountdownOffset2 = 20; + +GlobeCountdown::GlobeCountdown(const tDisplayElementID id) : IdlerAnimation(id) { + _digits.getImageFromPICTResource(((PegasusEngine *)g_engine)->_resFork, kGlobeCountdownDigitsID); + + Common::Rect r; + _digits.getSurfaceBounds(r); + _digitOffset = r.width() / 10; + setScale(1); + sizeElement(kGlobeCountdownWidth, kGlobeCountdownHeight); +} + +void GlobeCountdown::setDisplayOrder(const tDisplayOrder order) { + IdlerAnimation::setDisplayOrder(order); +} + +void GlobeCountdown::show() { + IdlerAnimation::show(); +} + +void GlobeCountdown::hide() { + IdlerAnimation::hide(); +} + +void GlobeCountdown::moveElementTo(const tCoordType x, const tCoordType y) { + IdlerAnimation::moveElementTo(x, y); +} + +void GlobeCountdown::setCountdownTime(const int numSeconds) { + stop(); + setSegment(0, numSeconds); + setTime(numSeconds); +} + +void GlobeCountdown::startCountdown() { + setRate(-1); +} + +void GlobeCountdown::stopCountdown() { + stop(); +} + +void GlobeCountdown::draw(const Common::Rect &) { + Common::Rect r1; + _digits.getSurfaceBounds(r1); + r1.right = r1.left + _digitOffset; + Common::Rect r2 = r1; + TimeValue time = getTime(); + + Common::Rect bounds; + getBounds(bounds); + + if (time > 60 * 9 + 59) { + r2.moveTo(bounds.left, bounds.top); + r1.moveTo(9 * _digitOffset, 0); + _digits.copyToCurrentPort(r1, r2); + + r2.moveTo(bounds.left + kGlobeCountdownOffset1, bounds.top); + r1.moveTo(5 * _digitOffset, 0); + _digits.copyToCurrentPort(r1, r2); + + r2.moveTo(bounds.left + kGlobeCountdownOffset2, bounds.top); + r1.moveTo(9 * _digitOffset, 0); + _digits.copyToCurrentPort(r1, r2); + } else { + r2.moveTo(bounds.left, bounds.top); + r1.moveTo((time / 60) * _digitOffset, 0); + _digits.copyToCurrentPort(r1, r2); + + time %= 60; + r2.moveTo(bounds.left + kGlobeCountdownOffset1, bounds.top); + r1.moveTo((time / 10) * _digitOffset, 0); + _digits.copyToCurrentPort(r1, r2); + + r2.moveTo(bounds.left + kGlobeCountdownOffset2, bounds.top); + r1.moveTo((time % 10) * _digitOffset, 0); + _digits.copyToCurrentPort(r1, r2); + } +} + +const int16 GlobeGame::_siloCoords[kNumAllSilos][2] = { + { 60, -151 }, // Anchorage, Alaska + { 6, 39 }, // Addis Ababa, Ethiopia + { -22, 44 }, // Antaro, Madagascar + { 30, -83 }, // Atlanta, Georgia + { -41, 173 }, // Auckland, New Zealand + { 39, -78 }, // Baltimore, Maryland + { 11, 101 }, // Bangkok, Thailand + { 2, -75 }, // Bogota, Colombia + { 46, 4 }, // Bonn, Germany + { 51, -7 }, // Dublin, Ireland + { 28, -1 }, // El Menia, Algeria + { 67, -111 }, // Ellesmere, Canada + { 43, -107 }, // Glasgow, Montana + { 61, -48 }, // Godthab, Greenland + { 19, -157 }, // Honolulu, Hawaii + { 6, 5 }, // Ibadan, Nigeria + { -29, 26 }, // Johannesburg, South Africa + { 46, 92 }, // Kobdo, Mongolia + { -15, -63 }, // La Paz, Bolivia + { -35, -61 }, // La Plata, Argentina + { -9, -76 }, // Lima, Peru + { 38, -4 }, // Madrid, Spain + { -8, -51 }, // Manaus, Brazil + { 13, 120 }, // Manila, Phillipines + { -35, 143 }, // Melbourne, Australia + { 60, -161 }, // Nome, Alaska + { -7, 142 }, // Papua, New Guinea + { -32, 117 }, // Perth, West Australia + { 34, -114 }, // Phoenix, Arizona + { 18, -71 }, // Port-Au-Prince, Haiti + { 42, -121 }, // Portland, Oregon + { 61, -20 }, // Reykjavik, Iceland + { -22, -46 }, // Rio de Janeiro + { 27, -101 }, // San Antonio, Texas + { 34, 126 }, // Seoul, Korea + { 37, -87 }, // Saint Louis, Missouri + { 60, 30 }, // Saint Petersberg, Russia + { 56, 12 }, // Stockholm, Sweden + { 51, 105 }, // Svortalsk, Siberia + { 36, -96 } // Tulsa, Oklahoma +}; + +const int16 GlobeGame::_targetSilo[kNumTargetSilos] = { + 14, 9, 1, 33, 6, 8, 34, 31, 38, 21 +}; + +const short GlobeGame::_timeLimit[kNumTargetSilos] = { + 120, 110, 100, 90, 80, 70, 60, 50, 40, 30 +}; + +const TimeValue GlobeGame::_siloName[kNumTargetSilos][2] = { + { kHonoluluIn, kHonoluluOut }, + { kDublinIn, kDublinOut }, + { kAddisAbabaIn, kAddisAbabaOut }, + { kSanAntonioIn, kSanAntonioOut }, + { kBangkokIn, kBangkokOut }, + { kBonnIn, kBonnOut }, + { kSeoulIn, kSeoulOut }, + { kReykjavikIn, kReykjavikOut }, + { kSvortalskIn, kSvortalskOut }, + { kMadridIn, kMadridOut } +}; + +// From globe room models + +static const GlobeGame::Point3D kCameraLocation = { 0.53f, 4.4f, -0.86f }; +static const GlobeGame::Point3D kGlobeCenter = { -31.5f, 8.0f, 0.0f }; +static const float kGlobeRadius = 8.25f; +static const int16 kDegreesPerLongSlice = 360 / kNumLongSlices; +static const int16 kDegreesPerLatSlice = 25; +static const int16 kLongOrigin = -95; + +// Other constants. + +static const float kTanFieldOfView = 0.7082373180482f; +static const float kPicturePlaneDistance = 10.0f; // Completely arbitrary. +static const int16 kLatError = 2; +static const int16 kLongError = 2; +static const TimeValue kGlobeMovieStartTime = 2 * 2 * kNumLongSlices * 600 / 15; + +static const TimeValue kTimePerGlobeFrame = 40; + +static const tNotificationFlags kGlobeSplash1Finished = 1; +static const tNotificationFlags kGlobeTimerExpired = kGlobeSplash1Finished << 1; +static const tNotificationFlags kMaxDeactivatedFinished = kGlobeTimerExpired << 1; + +static const tNotificationFlags kGlobeNotificationFlags = kGlobeSplash1Finished | + kGlobeTimerExpired | + kMaxDeactivatedFinished; + +static const int16 kSplash1End = 4; +static const int16 kSplash2End = 5; +static const int16 kSplash3Start = 8; +static const int16 kSplash3Stop = 9; +static const int16 kSplash4Start = 9; +static const int16 kSplash4Stop = 10; +static const int16 kNewLaunchSiloTime = 10; +static const int16 kSiloDeactivatedTime = 11; +static const int16 kMissileLaunchedTime = 12; +static const int16 kMaxDeactivatedStart = 13; +static const int16 kMaxDeactivatedStop = 23; + +static const int16 kGamePlaying = 1; +static const int16 kGameOver = 2; + +enum { + kGameIntro, + kPlayingRobotIntro, + kPlayingStrikeAuthorized, + kPlayingPrimaryTarget, + kPlayingNewSilo1, + kPlayingNewSilo2, + kPlayingNewSilo3, + kPlayingTime, + kPlayingInstructions, + kWaitingForPlayer, + kSiloDeactivated, + kRobotTaunting, + kDelayingPlayer, + kPlayerWon1, + kPlayerWon2, + kPlayerLost1 +}; + +// TODO: Use ScummVM equivalent + +static const float kPI = 3.1415926535f; + +float degreesToRadians(float angle) { + return (angle * kPI) / 180; +} + +float radiansToDegrees(float angle) { + return (angle * 180) / kPI; +} + +GlobeGame::GlobeGame(Neighborhood* handler) : GameInteraction(kNoradGlobeGameInteractionID, handler), + _monitorMovie(kGlobeMonitorID), _globeMovie(kGlobeMovieID), _upperNamesMovie(kGlobeUpperNamesID), + _lowerNamesMovie(kGlobeLowerNamesID), _globeNotification(kNoradGlobeNotificationID, (PegasusEngine *)g_engine), + _globeCircleLeft(kGlobeCircleLeftID), _globeCircleRight(kGlobeCircleRightID), + _globeCircleUp(kGlobeCircleUpID), _globeCircleDown(kGlobeCircleDownID), + _motionHighlightLeft(kMotionHiliteLeftID), _motionHighlightRight(kMotionHiliteRightID), + _motionHighlightUp(kMotionHiliteUpID), _motionHighlightDown(kMotionHiliteDownID), + _targetHighlightUpperLeft(kTargetHiliteUpperLeftID), _targetHighlightUpperRight(kTargetHiliteUpperRightID), + _targetHighlightLowerLeft(kTargetHiliteLowerLeftID), _targetHighlightLowerRight(kTargetHiliteLowerRightID), + _globeTracker(&_globeMovie, &_motionHighlightLeft, &_motionHighlightRight, &_motionHighlightUp, + &_motionHighlightDown), _countdown(kGlobeCountdownID) { + _neighborhoodNotification = handler->getNeighborhoodNotification(); +} + +void GlobeGame::openInteraction() { + _monitorMovie.initFromMovieFile("Images/Norad Delta/N79 Left Monitor"); + _monitorMovie.moveElementTo(kGlobeMonitorLeft, kGlobeMonitorTop); + _monitorMovie.setDisplayOrder(kGlobeMonitorLayer); + _monitorMovie.startDisplaying(); + _monitorMovie.setSegment(0, kSplash1End * _monitorMovie.getScale()); + _monitorMovie.show(); + + _monitorCallBack.setNotification(&_globeNotification); + _monitorCallBack.initCallBack(&_monitorMovie, kCallBackAtExtremes); + _monitorCallBack.setCallBackFlag(kGlobeSplash1Finished); + _monitorCallBack.scheduleCallBack(kTriggerAtStop, 0, 0); + + _upperNamesMovie.initFromMovieFile("Images/Norad Delta/Upper Names"); + _upperNamesMovie.moveElementTo(kGlobeUpperNamesLeft, kGlobeUpperNamesTop); + _upperNamesMovie.setDisplayOrder(kGlobeUpperNamesLayer); + _upperNamesMovie.startDisplaying(); + + _lowerNamesMovie.initFromMovieFile("Images/Norad Delta/Lower Names"); + _lowerNamesMovie.moveElementTo(kGlobeLowerNamesLeft, kGlobeLowerNamesTop); + _lowerNamesMovie.setDisplayOrder(kGlobeLowerNamesLayer); + _lowerNamesMovie.startDisplaying(); + + _globeMovie.initFromMovieFile("Images/Norad Delta/Spinning Globe"); + _globeMovie.moveElementTo(kGlobeLeft, kGlobeTop); + _globeMovie.setDisplayOrder(kGlobeMovieLayer); + _globeMovie.startDisplaying(); + _globeMovie.setTime(kGlobeMovieStartTime); + _globeMovie.redrawMovieWorld(); + + _globeCircleLeft.initFromPICTResource(((PegasusEngine *)g_engine)->_resFork, kGlobeCircleLeftPICTID, true); + _globeCircleLeft.moveElementTo(kGlobeCircleLeftLeft, kGlobeCircleLeftTop); + _globeCircleLeft.setDisplayOrder(kGlobeCircleLayer); + _globeCircleLeft.startDisplaying(); + + _globeCircleRight.initFromPICTResource(((PegasusEngine *)g_engine)->_resFork, kGlobeCircleRightPICTID, true); + _globeCircleRight.moveElementTo(kGlobeCircleRightLeft, kGlobeCircleRightTop); + _globeCircleRight.setDisplayOrder(kGlobeCircleLayer); + _globeCircleRight.startDisplaying(); + + _globeCircleUp.initFromPICTResource(((PegasusEngine *)g_engine)->_resFork, kGlobeCircleUpPICTID, true); + _globeCircleUp.moveElementTo(kGlobeCircleUpLeft, kGlobeCircleUpTop); + _globeCircleUp.setDisplayOrder(kGlobeCircleLayer); + _globeCircleUp.startDisplaying(); + + _globeCircleDown.initFromPICTResource(((PegasusEngine *)g_engine)->_resFork, kGlobeCircleDownPICTID, true); + _globeCircleDown.moveElementTo(kGlobeCircleDownLeft, kGlobeCircleDownTop); + _globeCircleDown.setDisplayOrder(kGlobeCircleLayer); + _globeCircleDown.startDisplaying(); + + _motionHighlightLeft.initFromPICTResource(((PegasusEngine *)g_engine)->_resFork, kMotionHiliteLeftPICTID, true); + _motionHighlightLeft.moveElementTo(kGlobeLeftMotionHiliteLeft, kGlobeLeftMotionHiliteTop); + _motionHighlightLeft.setDisplayOrder(kGlobeHilitesLayer); + _motionHighlightLeft.startDisplaying(); + + _motionHighlightRight.initFromPICTResource(((PegasusEngine *)g_engine)->_resFork, kMotionHiliteRightPICTID, true); + _motionHighlightRight.moveElementTo(kGlobeRightMotionHiliteLeft, kGlobeRightMotionHiliteTop); + _motionHighlightRight.setDisplayOrder(kGlobeCircleLayer); + _motionHighlightRight.startDisplaying(); + + _motionHighlightUp.initFromPICTResource(((PegasusEngine *)g_engine)->_resFork, kMotionHiliteUpPICTID, true); + _motionHighlightUp.moveElementTo(kGlobeUpMotionHiliteLeft, kGlobeUpMotionHiliteTop); + _motionHighlightUp.setDisplayOrder(kGlobeHilitesLayer); + _motionHighlightUp.startDisplaying(); + + _motionHighlightDown.initFromPICTResource(((PegasusEngine *)g_engine)->_resFork, kMotionHiliteDownPICTID, true); + _motionHighlightDown.moveElementTo(kGlobeDownMotionHiliteLeft, kGlobeDownMotionHiliteTop); + _motionHighlightDown.setDisplayOrder(kGlobeHilitesLayer); + _motionHighlightDown.startDisplaying(); + + _targetHighlightUpperLeft.initFromPICTResource(((PegasusEngine *)g_engine)->_resFork, kTargetUpperLeftPICTID, true); + _targetHighlightUpperLeft.moveElementTo(kGlobeUpperLeftHiliteLeft, kGlobeUpperLeftHiliteTop); + _targetHighlightUpperLeft.setDisplayOrder(kGlobeHilitesLayer); + _targetHighlightUpperLeft.startDisplaying(); + + _targetHighlightUpperRight.initFromPICTResource(((PegasusEngine *)g_engine)->_resFork, kTargetUpperRightPICTID, true); + _targetHighlightUpperRight.moveElementTo(kGlobeUpperRightHiliteLeft, kGlobeUpperRightHiliteTop); + _targetHighlightUpperRight.setDisplayOrder(kGlobeHilitesLayer); + _targetHighlightUpperRight.startDisplaying(); + + _targetHighlightLowerLeft.initFromPICTResource(((PegasusEngine *)g_engine)->_resFork, kTargetLowerLeftPICTID, true); + _targetHighlightLowerLeft.moveElementTo(kGlobeLowerLeftHiliteLeft, kGlobeLowerLeftHiliteTop); + _targetHighlightLowerLeft.setDisplayOrder(kGlobeHilitesLayer); + _targetHighlightLowerLeft.startDisplaying(); + + _targetHighlightLowerRight.initFromPICTResource(((PegasusEngine *)g_engine)->_resFork, kTargetLowerRightPICTID, true); + _targetHighlightLowerRight.moveElementTo(kGlobeLowerRightHiliteLeft, kGlobeLowerRightHiliteTop); + _targetHighlightLowerRight.setDisplayOrder(kGlobeHilitesLayer); + _targetHighlightLowerRight.startDisplaying(); + + _countdown.setDisplayOrder(kGlobeCountdownLayer); + _countdown.moveElementTo(kGlobeCountdownLeft, kGlobeCountdownTop); + _countdown.startDisplaying(); + _countdown.setCountdownTime(_timeLimit[0]); + + _countdownCallBack.setNotification(&_globeNotification); + _countdownCallBack.initCallBack(&_countdown, kCallBackAtExtremes); + _countdownCallBack.setCallBackFlag(kGlobeTimerExpired); + _countdownCallBack.scheduleCallBack(kTriggerAtStart, 0, 0); + + _globeNotification.notifyMe(this, kGlobeNotificationFlags, kGlobeNotificationFlags); + + _gameState = kGameIntro; + _currentSiloIndex = 0; + _playedInstructions = false; + + _neighborhoodNotification->notifyMe(this, kDelayCompletedFlag | kSpotSoundCompletedFlag, kDelayCompletedFlag | kSpotSoundCompletedFlag); +} + +void GlobeGame::initInteraction() { + _monitorMovie.start(); + _monitorMovie.redrawMovieWorld(); +} + +void GlobeGame::closeInteraction() { + _monitorMovie.stop(); + _monitorMovie.stopDisplaying(); + _monitorMovie.releaseMovie(); + _monitorCallBack.releaseCallBack(); + + _globeMovie.stop(); + _globeMovie.stopDisplaying(); + _globeMovie.releaseMovie(); + _globeNotification.cancelNotification(this); + + _upperNamesMovie.stop(); + _upperNamesMovie.stopDisplaying(); + _upperNamesMovie.releaseMovie(); + + _lowerNamesMovie.stop(); + _lowerNamesMovie.stopDisplaying(); + _lowerNamesMovie.releaseMovie(); + + _countdown.hide(); + _countdown.stopDisplaying(); + _countdownCallBack.releaseCallBack(); + + _globeCircleLeft.stopDisplaying(); + _globeCircleLeft.deallocateSurface(); + _globeCircleRight.stopDisplaying(); + _globeCircleRight.deallocateSurface(); + _globeCircleUp.stopDisplaying(); + _globeCircleUp.deallocateSurface(); + _globeCircleDown.stopDisplaying(); + _globeCircleDown.deallocateSurface(); + + _motionHighlightLeft.stopDisplaying(); + _motionHighlightLeft.deallocateSurface(); + _motionHighlightRight.stopDisplaying(); + _motionHighlightRight.deallocateSurface(); + _motionHighlightUp.stopDisplaying(); + _motionHighlightUp.deallocateSurface(); + _motionHighlightDown.stopDisplaying(); + _motionHighlightDown.deallocateSurface(); + + _targetHighlightUpperLeft.stopDisplaying(); + _targetHighlightUpperLeft.deallocateSurface(); + _targetHighlightUpperRight.stopDisplaying(); + _targetHighlightUpperRight.deallocateSurface(); + _targetHighlightLowerLeft.stopDisplaying(); + _targetHighlightLowerLeft.deallocateSurface(); + _targetHighlightLowerRight.stopDisplaying(); + _targetHighlightLowerRight.deallocateSurface(); + + _neighborhoodNotification->cancelNotification(this); +} + +void GlobeGame::receiveNotification(Notification *notification, const tNotificationFlags flags) { + TimeScale scale = _monitorMovie.getScale(); + + if (notification == _neighborhoodNotification) { + switch (_gameState) { + case kPlayingRobotIntro: + _monitorMovie.stop(); + _monitorMovie.setSegment(0, _monitorMovie.getDuration()); + _monitorMovie.setTime(kSplash2End * scale - 1); + _monitorMovie.setFlags(0); + + _owner->requestDelay(1, 2, kFilterNoInput, 0); + _owner->requestSpotSound(kStrikeAuthorizedIn, kStrikeAuthorizedOut, + kFilterNoInput, kSpotSoundCompletedFlag); + _gameState = kPlayingStrikeAuthorized; + break; + case kPlayingStrikeAuthorized: + _monitorMovie.setSegment(kSplash3Start * scale, kSplash3Stop * scale); + _monitorMovie.setTime(kSplash3Start * scale); + _monitorMovie.redrawMovieWorld(); + + _owner->requestDelay(1, 3, kFilterNoInput, 0); + _owner->requestSpotSound(kPrimaryTargetIn, kPrimaryTargetOut, kFilterNoInput, 0); + _owner->requestDelay(1, 5, kFilterNoInput, kDelayCompletedFlag); + _monitorMovie.start(); + _gameState = kPlayingPrimaryTarget; + break; + case kPlayingPrimaryTarget: + _monitorMovie.stop(); + _monitorMovie.setSegment(0, _monitorMovie.getDuration()); + _monitorMovie.setTime(kNewLaunchSiloTime * scale); + _owner->requestSpotSound(kNewLaunchSiloIn, kNewLaunchSiloOut, kFilterNoInput, + kSpotSoundCompletedFlag); + _gameState = kPlayingNewSilo1; + break; + case kPlayingNewSilo1: + _monitorMovie.stop(); + _monitorMovie.setSegment(0, _monitorMovie.getDuration()); + _owner->requestDelay(1, 3, kFilterNoInput, kDelayCompletedFlag); + _gameState = kPlayingNewSilo2; + break; + case kPlayingNewSilo2: + _upperNamesMovie.show(); + _upperNamesMovie.setTime(_currentSiloIndex * _upperNamesMovie.getScale()); + _upperNamesMovie.redrawMovieWorld(); + _monitorMovie.setTime(kSplash4Stop * scale - 1); + _monitorMovie.redrawMovieWorld(); + _owner->requestSpotSound(_siloName[_currentSiloIndex][0], _siloName[_currentSiloIndex][1], kFilterNoInput, 0); + _owner->requestDelay(1, 3, kFilterNoInput, 0); + _owner->requestSpotSound(kLaunchToProceedIn, kLaunchToProceedOut, kFilterNoInput, 0); + _owner->requestDelay(1, 5, kFilterNoInput, kDelayCompletedFlag); + _gameState = kPlayingNewSilo3; + break; + case kPlayingNewSilo3: + _countdown.stopCountdown(); + _countdown.setCountdownTime(_timeLimit[_currentSiloIndex]); + _countdown.show(); + _gameState = kPlayingTime; + + if (_timeLimit[_currentSiloIndex] >= 120) + _owner->requestSpotSound(kTwoMinutesIn, kTwoMinutesOut, kFilterNoInput, 0); + else if (_timeLimit[_currentSiloIndex] >= 60) + _owner->requestSpotSound(kOneMinuteIn, kOneMinuteOut, kFilterNoInput, 0); + + switch (_timeLimit[_currentSiloIndex] % 60) { + case 0: + _owner->requestDelay(1, 5, kFilterNoInput, kDelayCompletedFlag); + break; + case 10: + _owner->requestDelay(1, 5, kFilterNoInput, 0); + _owner->requestSpotSound(kTenSecondsIn, kTenSecondsOut, kFilterNoInput, + kSpotSoundCompletedFlag); + break; + case 20: + _owner->requestDelay(1, 5, kFilterNoInput, 0); + _owner->requestSpotSound(kTwentySecondsIn, kTwentySecondsOut, + kFilterNoInput, kSpotSoundCompletedFlag); + break; + case 30: + _owner->requestDelay(1, 5, kFilterNoInput, 0); + _owner->requestSpotSound(kThirtySecondsIn, kThirtySecondsOut, + kFilterNoInput, kSpotSoundCompletedFlag); + break; + case 40: + _owner->requestDelay(1, 5, kFilterNoInput, 0); + _owner->requestSpotSound(kFortySecondsIn, kFortySecondsOut, + kFilterNoInput, kSpotSoundCompletedFlag); + break; + case 50: + _owner->requestDelay(1, 5, kFilterNoInput, 0); + _owner->requestSpotSound(kFiftySecondsIn, kFiftySecondsOut, + kFilterNoInput, kSpotSoundCompletedFlag); + break; + } + case kPlayingTime: + _gameState = kPlayingInstructions; + _globeMovie.show(); + _globeCircleLeft.show(); + _globeCircleRight.show(); + _globeCircleUp.show(); + _globeCircleDown.show(); + + if (_playedInstructions) { + receiveNotification(notification, flags); + } else { + _owner->requestSpotSound(kToDeactivateIn, kToDeactivateOut, kFilterNoInput, + kSpotSoundCompletedFlag); + _playedInstructions = true; + } + break; + case kPlayingInstructions: + _gameState = kWaitingForPlayer; + _countdown.startCountdown(); + break; + case kSiloDeactivated: + _gameState = kRobotTaunting; + + switch (_currentSiloIndex) { + case 3: + _owner->requestSpotSound(kYouCannotPossiblyIn, kYouCannotPossiblyOut, + kFilterNoInput, kSpotSoundCompletedFlag); + break; + case 5: + _owner->requestSpotSound(kYouWillFailIn, kYouWillFailOut, kFilterNoInput, + kSpotSoundCompletedFlag); + break; + case 7: + _owner->requestSpotSound(kGiveUpHumanIn, kGiveUpHumanOut, kFilterNoInput, + kSpotSoundCompletedFlag); + break; + case 9: + _owner->requestSpotSound(kYouAreRunningIn, kYouAreRunningOut, + kFilterNoInput, kSpotSoundCompletedFlag); + break; + default: + _owner->requestSpotSound(kNewLaunchSiloIn, kNewLaunchSiloOut, + kFilterNoInput, kSpotSoundCompletedFlag); + _monitorMovie.setTime(kNewLaunchSiloTime * scale); + _monitorMovie.redrawMovieWorld(); + _gameState = kPlayingNewSilo1; + break; + } + break; + case kRobotTaunting: + _owner->requestDelay(1, 1, kFilterNoInput, 0); + _owner->requestSpotSound(kNewLaunchSiloIn, kNewLaunchSiloOut, kFilterNoInput, kSpotSoundCompletedFlag); + _monitorMovie.setTime(kNewLaunchSiloTime * scale); + _monitorMovie.redrawMovieWorld(); + _gameState = kPlayingNewSilo1; + break; + case kDelayingPlayer: + _gameState = kWaitingForPlayer; + break; + case kPlayerLost1: + _owner->recallToTSAFailure(); + break; + case kPlayerWon2: + ((NoradDelta *)_owner)->finishedGlobeGame(); + _owner->requestDeleteCurrentInteraction(); + break; + default: + break; + } + } else if (notification == &_globeNotification) { + ExtraTable::Entry entry; + + switch (flags) { + case kGlobeSplash1Finished: + _owner->getExtraEntry(kN79BrightView, entry); + _monitorMovie.stop(); + _monitorMovie.setSegment(kSplash1End * scale, kSplash2End * scale); + _monitorMovie.setFlags(kLoopTimeBase); + _monitorMovie.start(); + _owner->showViewFrame(entry.movieStart); + _owner->requestSpotSound(kIJustBrokeIn, kIJustBrokeOut, kFilterNoInput, 0); + _owner->requestDelay(1, 2, kFilterNoInput, kDelayCompletedFlag); + _gameState = kPlayingRobotIntro; + break; + case kGlobeTimerExpired: + // Missile launched, player loses. + _owner->requestSpotSound(kMissileLaunchedIn, kMissileLaunchedOut, kFilterNoInput, kSpotSoundCompletedFlag); + _gameState = kPlayerLost1; + break; + case kMaxDeactivatedFinished: + _monitorMovie.stop(); + _monitorMovie.setSegment(0, _monitorMovie.getDuration()); + _owner->requestDelay(1, 2, kFilterNoInput, 0); + _owner->requestSpotSound(kTheOnlyGoodHumanIn, kTheOnlyGoodHumanOut, kFilterNoInput, 0); + _owner->requestDelay(1, 2, kFilterNoInput, kDelayCompletedFlag); + _gameState = kPlayerWon2; + break; + default: + break; + } + } +} + +// Prevent the player from getting up until the game is over. + +void GlobeGame::handleInput(const Input &input, const Hotspot *cursorSpot) { + Common::Point where; + input.getInputLocation(where); + Hotspot *spot = g_allHotspots.findHotspot(where); + + if (((PegasusEngine *)g_engine)->_cursor->isVisible() && spot != 0 && + spot->getObjectID() == kNorad79SiloAreaSpotID && findClickedSilo(input) != -1) { + _targetHighlightUpperLeft.show(); + _targetHighlightUpperRight.show(); + _targetHighlightLowerLeft.show(); + _targetHighlightLowerRight.show(); + } else { + _targetHighlightUpperLeft.hide(); + _targetHighlightUpperRight.hide(); + _targetHighlightLowerLeft.hide(); + _targetHighlightLowerRight.hide(); + } + + // Interrupt certain inputs to prevent player from switching modes. + InputHandler::handleInput(input, cursorSpot); +} + +int16 GlobeGame::findClickedSilo(const Input &input) { + Common::Point screenPoint; + input.getInputLocation(screenPoint); + screenPoint.x -= kNavAreaLeft; + screenPoint.y -= kNavAreaTop; + + Line3D ray; + screenPointTo3DPoint(screenPoint.x, screenPoint.y, ray.pt2); + ray.pt1 = kCameraLocation; + + Point3D globePoint; + if (lineHitsGlobe(ray, globePoint)) { + int16 latOrigin, longOrigin, latitude, longitude; + globeMovieFrameToOrigin(_globeMovie.getTime() / kTimePerGlobeFrame, latOrigin, longOrigin); + globePointToLatLong(globePoint, latOrigin, longOrigin, latitude, longitude); + + for (int16 i = 0; i < kNumAllSilos; i++) + if (_siloCoords[i][0] >= latitude - kLatError && _siloCoords[i][0] <= latitude + kLatError && + _siloCoords[i][1] >= longitude - kLongError && _siloCoords[i][1] <= longitude + kLongError) + return i; + } + + return -1; +} + +void GlobeGame::spinGlobe(const Input &input, const Hotspot *spot, GlobeTrackDirection trackDirection) { + _globeTracker.setTrackParameters(spot, trackDirection); + _globeTracker.startTracking(input); +} + +void GlobeGame::clickGlobe(const Input &input) { + int16 newSilo = findClickedSilo(input); + + if (newSilo != -1) { + _targetHighlightUpperLeft.hide(); + _targetHighlightUpperRight.hide(); + _targetHighlightLowerLeft.hide(); + _targetHighlightLowerRight.hide(); + _lowerNamesMovie.show(); + _lowerNamesMovie.setTime(newSilo * _lowerNamesMovie.getScale()); + _lowerNamesMovie.redrawMovieWorld(); + _owner->requestSpotSound(kSiloBeepIn, kSiloBeepOut, kFilterNoInput, 0); + + if (newSilo == _targetSilo[_currentSiloIndex]) { + _currentSiloIndex++; + _countdown.stopCountdown(); + _owner->requestSpotSound(kSiloDeactivatedIn, kSiloDeactivatedOut, kFilterNoInput, 0); + + if (_currentSiloIndex == kNumTargetSilos) { + // Player won. + _owner->requestDelay(1, 2, kFilterNoInput, 0); + _upperNamesMovie.hide(); + _lowerNamesMovie.hide(); + _countdown.hide(); + _monitorMovie.setSegment(kMaxDeactivatedStart * _monitorMovie.getScale(), + kMaxDeactivatedStop * _monitorMovie.getScale()); + _monitorMovie.setTime(kMaxDeactivatedStart * _monitorMovie.getScale()); + _monitorCallBack.setCallBackFlag(kMaxDeactivatedFinished); + _monitorCallBack.scheduleCallBack(kTriggerAtStop, 0, 0); + _monitorMovie.start(); + _owner->requestSpotSound(kMaximumDeactivationIn, kMaximumDeactivationOut, + kFilterNoInput, kSpotSoundCompletedFlag); + _gameState = kPlayerWon1; + } else { + _owner->requestDelay(2, 1, kFilterNoInput, kDelayCompletedFlag); + _upperNamesMovie.hide(); + _lowerNamesMovie.hide(); + _countdown.hide(); + _monitorMovie.setTime(kSiloDeactivatedTime * _monitorMovie.getScale()); + _monitorMovie.redrawMovieWorld(); + _gameState = kSiloDeactivated; + } + } else { + _owner->requestDelay(5, 1, kFilterNoInput, kDelayCompletedFlag); + _gameState = kDelayingPlayer; + // Play "incorrect" sound? + } + } +} + +void GlobeGame::clickInHotspot(const Input &input, const Hotspot *spot) { + switch (spot->getObjectID()) { + case kNorad79SpinLeftSpotID: + spinGlobe(input, spot, kTrackLeft); + break; + case kNorad79SpinRightSpotID: + spinGlobe(input, spot, kTrackRight); + break; + case kNorad79SpinUpSpotID: + spinGlobe(input, spot, kTrackUp); + break; + case kNorad79SpinDownSpotID: + spinGlobe(input, spot, kTrackDown); + break; + case kNorad79SiloAreaSpotID: + clickGlobe(input); + break; + default: + GameInteraction::clickInHotspot(input, spot); + break; + } +} + +void GlobeGame::activateHotspots() { + GameInteraction::activateHotspots(); + + switch (_gameState) { + case kWaitingForPlayer: + g_allHotspots.deactivateOneHotspot(kNorad79WestOutSpotID); + g_allHotspots.activateOneHotspot(kNorad79SpinLeftSpotID); + g_allHotspots.activateOneHotspot(kNorad79SpinRightSpotID); + g_allHotspots.activateOneHotspot(kNorad79SpinUpSpotID); + g_allHotspots.activateOneHotspot(kNorad79SpinDownSpotID); + g_allHotspots.activateOneHotspot(kNorad79SiloAreaSpotID); + break; + default: + g_allHotspots.deactivateOneHotspot(kNorad79WestOutSpotID); + break; + } +} + +void GlobeGame::globeMovieFrameToOrigin(int16 frameNum, int16 &latOrigin, int16 &longOrigin) { + latOrigin = kDegreesPerLatSlice * 2 - (frameNum / (kNumLongSlices * 2)) * kDegreesPerLatSlice; + frameNum %= kNumLongSlices * 2; + + if (frameNum >= kNumLongSlices) + longOrigin = kLongOrigin + (kNumLongSlices * 2 - 1 - frameNum) * kDegreesPerLongSlice; + else + longOrigin = kLongOrigin + frameNum * kDegreesPerLongSlice; + + if (longOrigin > 180) + longOrigin -= 360; +} + +void GlobeGame::globePointToLatLong(const GlobeGame::Point3D &pt, int16 latOrigin, int16 longOrigin, + int16 &latitude, int16 &longitude) { + Point3D scratch = pt; + + // Translate globe center to origin. + scratch.x -= kGlobeCenter.x; + scratch.y -= kGlobeCenter.y; + scratch.z -= kGlobeCenter.z; + + // Rotate around z axis latOrigin degrees to bring equator parallel with XZ plane + float theta = degreesToRadians(latOrigin); + float s = sin(theta); + float c = cos(theta); + float x = scratch.x * c - scratch.y * s; + float y = scratch.y * c + scratch.x * s; + scratch.x = x; + scratch.y = y; + + // Calculate latitude + latitude = (int16)radiansToDegrees(asin(scratch.y / kGlobeRadius)); + + // Rotate around y axis longOrigin degrees to bring longitude 0 to positive X axis + theta = degreesToRadians(longOrigin); + s = sin(theta); + c = cos(theta); + x = scratch.x * c - scratch.z * s; + float z = scratch.z * c + scratch.x * s; + scratch.x = x; + scratch.z = z; + + // Calculate longitude + longitude = (int16)radiansToDegrees(acos(scratch.x / sqrt(scratch.x * scratch.x + scratch.z * scratch.z))); + + if (scratch.z < 0) + longitude = -longitude; +} + +// h, v in [0, 511][0, 255] +// Looking down negative x axis. +void GlobeGame::screenPointTo3DPoint(int16 h, int16 v, GlobeGame::Point3D &pt) { + pt.x = kCameraLocation.x - kPicturePlaneDistance; + pt.y = kCameraLocation.y + (128 - v) * kPicturePlaneDistance * kTanFieldOfView / 256; + pt.z = kCameraLocation.z + (h - 256) * kPicturePlaneDistance * kTanFieldOfView / 256; +} + +// Fundamentals of Three-Dimensional Graphics, by Alan Watt +// pp. 163-164 +bool GlobeGame::lineHitsGlobe(const GlobeGame::Line3D &line, GlobeGame::Point3D &pt) { + float i = line.pt2.x - line.pt1.x; + float j = line.pt2.y - line.pt1.y; + float k = line.pt2.z - line.pt1.z; + float a = i * i + j * j + k * k; + float b = 2 * i * (line.pt1.x - kGlobeCenter.x) + 2 * j * (line.pt1.y - kGlobeCenter.y) + + 2 * k * (line.pt1.z - kGlobeCenter.z); + float c = kGlobeCenter.x * kGlobeCenter.x + kGlobeCenter.y * kGlobeCenter.y + + kGlobeCenter.z * kGlobeCenter.z + line.pt1.x * line.pt1.x + line.pt1.y * line.pt1.y + + line.pt1.z * line.pt1.z + -2 * (kGlobeCenter.x * line.pt1.x + kGlobeCenter.y * line.pt1.y + + kGlobeCenter.z * line.pt1.z) - kGlobeRadius * kGlobeRadius; + + // Solve quadratic equation of a, b, c. + float t = b * b - 4 * a * c; + + if (t >= 0.0f) { + // Return smaller root, which corresponds to closest intersection point. + t = (-b - sqrt(t)) / (2 * a); + pt.x = i * t + line.pt1.x; + pt.y = j * t + line.pt1.y; + pt.z = k * t + line.pt1.z; + return true; + } + + return false; +} + +bool GlobeGame::canSolve() { + return _gameState != kPlayerWon1 && _gameState != kPlayerWon2 && _gameState != kPlayerLost1; +} + +void GlobeGame::doSolve() { + _owner->requestDelay(1, 2, kFilterNoInput, 0); + _upperNamesMovie.hide(); + _lowerNamesMovie.hide(); + _countdown.hide(); + _monitorMovie.setSegment(kMaxDeactivatedStart * _monitorMovie.getScale(), kMaxDeactivatedStop * _monitorMovie.getScale()); + _monitorMovie.setTime(kMaxDeactivatedStart * _monitorMovie.getScale()); + _monitorCallBack.setCallBackFlag(kMaxDeactivatedFinished); + _monitorCallBack.scheduleCallBack(kTriggerAtStop, 0, 0); + _monitorMovie.start(); + _owner->requestSpotSound(kMaximumDeactivationIn, kMaximumDeactivationOut, kFilterNoInput, kSpotSoundCompletedFlag); + _gameState = kPlayerWon1; +} + +} // End of namespace Pegasus diff --git a/engines/pegasus/neighborhood/norad/delta/globegame.h b/engines/pegasus/neighborhood/norad/delta/globegame.h new file mode 100755 index 0000000000..e2fe318f09 --- /dev/null +++ b/engines/pegasus/neighborhood/norad/delta/globegame.h @@ -0,0 +1,169 @@ +/* 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_NEIGHBORHOOD_NORAD_DELTA_GLOBEGAME_H +#define PEGASUS_NEIGHBORHOOD_NORAD_DELTA_GLOBEGAME_H + +#include "pegasus/interaction.h" +#include "pegasus/movie.h" +#include "pegasus/notification.h" + +namespace Pegasus { + +enum GlobeTrackDirection { + kTrackLeft, + kTrackRight, + kTrackUp, + kTrackDown +}; + +// This class assumes that the globe movie is built at 15 frames per second with a +// time scale of 600, yielding 40 time unit per frame. + +class GlobeTracker : public Tracker { +public: + GlobeTracker(Movie *, Picture *, Picture *, Picture *, Picture *); + virtual ~GlobeTracker() {} + + void setTrackParameters(const Hotspot *, GlobeTrackDirection); + void continueTracking(const Input &); + void startTracking(const Input &); + void stopTracking(const Input &); + void activateHotspots(); + bool stopTrackingInput(const Input &); + +protected: + void trackGlobeMovie(); + void stopGlobeMovie(); + + Movie *_globeMovie; + Picture *_leftHighlight; + Picture *_rightHighlight; + Picture *_upHighlight; + Picture *_downHighlight; + const Hotspot *_trackSpot; + int _trackTime; + GlobeTrackDirection _trackDirection; +}; + +class GlobeCountdown : public IdlerAnimation { +public: + GlobeCountdown(const tDisplayElementID); + virtual ~GlobeCountdown() {} + + void setCountdownTime(const int); + void startCountdown(); + void stopCountdown(); + + void setDisplayOrder(const tDisplayOrder); + void show(); + void hide(); + void moveElementTo(const tCoordType, const tCoordType); + + void draw(const Common::Rect &); + +protected: + Surface _digits; + int16 _digitOffset; +}; + +static const int16 kNumAllSilos = 40; +static const int16 kNumTargetSilos = 10; +static const int16 kNumLongSlices = 72; + +class GlobeGame : public GameInteraction, public NotificationReceiver { +public: + GlobeGame(Neighborhood *); + virtual ~GlobeGame() {} + + void handleInput(const Input &, const Hotspot *); + void clickInHotspot(const Input &, const Hotspot *); + void activateHotspots(); + + bool canSolve(); + void doSolve(); + + struct Point3D { + float x, y, z; + }; + + struct Line3D { + Point3D pt1, pt2; + }; + +protected: + // Latitude (-90 - 90) and longitude (-180 - 180) + static const int16 _siloCoords[kNumAllSilos][2]; + + static const int16 _targetSilo[kNumTargetSilos]; + static const int16 _timeLimit[kNumTargetSilos]; + static const TimeValue _siloName[kNumTargetSilos][2]; + + void openInteraction(); + void initInteraction(); + void closeInteraction(); + + void receiveNotification(Notification *, const tNotificationFlags); + + void spinGlobe(const Input &, const Hotspot *, GlobeTrackDirection); + void clickGlobe(const Input &); + + int16 findClickedSilo(const Input &); + + void globeMovieFrameToOrigin(int16, int16 &, int16 &); + void globePointToLatLong(const Point3D &, int16, int16, int16 &, int16 &); + void screenPointTo3DPoint(int16, int16, Point3D &); + bool lineHitsGlobe(const Line3D &, Point3D &); + + Movie _monitorMovie; + Movie _globeMovie; + Movie _upperNamesMovie; + Movie _lowerNamesMovie; + Notification _globeNotification; + NotificationCallBack _monitorCallBack; + GlobeTracker _globeTracker; + Picture _globeCircleLeft; + Picture _globeCircleRight; + Picture _globeCircleUp; + Picture _globeCircleDown; + Picture _motionHighlightLeft; + Picture _motionHighlightRight; + Picture _motionHighlightUp; + Picture _motionHighlightDown; + Picture _targetHighlightUpperLeft; + Picture _targetHighlightUpperRight; + Picture _targetHighlightLowerLeft; + Picture _targetHighlightLowerRight; + GlobeCountdown _countdown; + NotificationCallBack _countdownCallBack; + int16 _gameState; + int16 _currentSiloIndex; + Notification *_neighborhoodNotification; + bool _playedInstructions; +}; + +} // End of namespace Pegasus + +#endif diff --git a/engines/pegasus/neighborhood/norad/delta/noraddelta.cpp b/engines/pegasus/neighborhood/norad/delta/noraddelta.cpp new file mode 100755 index 0000000000..8f4df726a2 --- /dev/null +++ b/engines/pegasus/neighborhood/norad/delta/noraddelta.cpp @@ -0,0 +1,869 @@ +/* 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 "pegasus/energymonitor.h" +#include "pegasus/gamestate.h" +#include "pegasus/interface.h" +#include "pegasus/pegasus.h" +#include "pegasus/ai/ai_area.h" +#include "pegasus/items/biochips/opticalchip.h" +#include "pegasus/items/biochips/retscanchip.h" +#include "pegasus/items/inventory/airmask.h" +#include "pegasus/neighborhood/norad/constants.h" +#include "pegasus/neighborhood/norad/subcontrolroom.h" +#include "pegasus/neighborhood/norad/delta/globegame.h" +#include "pegasus/neighborhood/norad/delta/noraddelta.h" + +namespace Pegasus { + +const uint32 NoradDelta::_noradDeltaClawExtras[22] = { + kN60ClawFromAToB, + kN60ClawALoop, + kN60ClawAPinch, + kN60ClawACounterclockwise, + kN60ClawAClockwise, + kN60ClawFromBToA, + kN60ClawFromBToC, + kN60ClawFromBToD, + kN60ClawBLoop, + kN60ClawBPinch, + kN60ClawBCounterclockwise, + kN60ClawBClockwise, + kN60ClawFromCToB, + kN60ClawCLoop, + kN60ClawCPinch, + kN60ClawCCounterclockwise, + kN60ClawCClockwise, + kN60ClawFromDToB, + kN60ClawDLoop, + kN60ClawDPinch, + kN60ClawDCounterclockwise, + kN60ClawDClockwise +}; + +NoradDelta::NoradDelta(InputHandler *nextHandler, PegasusEngine *owner) : Norad(nextHandler, owner, "Norad Delta", kNoradDeltaID) { + _elevatorUpRoomID = kNorad49South; + _elevatorDownRoomID = kNorad48South; + _elevatorUpSpotID = kNorad48ElevatorUpSpotID; + _elevatorDownSpotID = kNorad49ElevatorDownSpotID; + + // Pressure door stuff. + + _subRoomEntryRoom1 = kNorad50; + _subRoomEntryDir1 = kEast; + _subRoomEntryRoom2 = kNorad59; + _subRoomEntryDir2 = kWest; + _upperPressureDoorRoom = kNorad50East; + _lowerPressureDoorRoom = kNorad59West; + + _upperPressureDoorUpSpotID = kDeltaUpperPressureDoorUpSpotID; + _upperPressureDoorDownSpotID = kDeltaUpperPressureDoorDownSpotID; + _upperPressureDoorAbortSpotID = kNorad50DoorOutSpotID; + + _lowerPressureDoorUpSpotID = kDeltaLowerPressureDoorUpSpotID; + _lowerPressureDoorDownSpotID = kDeltaLowerPressureDoorDownSpotID; + _lowerPressureDoorAbortSpotID = kNorad59WestOutSpotID; + + _pressureSoundIn = kPressureDoorIntro1In; + _pressureSoundOut = kPressureDoorIntro1Out; + _equalizeSoundIn = kPressureDoorIntro2In; + _equalizeSoundOut = kPressureDoorIntro2Out; + _accessDeniedIn = kDeltaAccessDeniedIn; + _accessDeniedOut = kDeltaAccessDeniedOut; + + GameState.setNoradSubPrepState(kSubDamaged); + + _subControlRoom = kNorad60West; +} + +void NoradDelta::init() { + Norad::init(); + + // Little fix for the retinal scan zoom in spot... + Hotspot *hotspot = g_allHotspots.findHotspotByID(kNorad68WestSpotID); + hotspot->setMaskedHotspotFlags(kZoomInSpotFlag, kZoomInSpotFlag | kZoomOutSpotFlag); + + hotspot = g_allHotspots.findHotspotByID(kNorad79WestSpotID); + hotspot->setMaskedHotspotFlags(kZoomInSpotFlag, kZoomInSpotFlag | kZoomOutSpotFlag); + + hotspot = g_allHotspots.findHotspotByID(kDelta59RobotShieldBiochipSpotID); + hotspot->setMaskedHotspotFlags(kPickUpBiochipSpotFlag, kPickUpBiochipSpotFlag); + HotspotInfoTable::Entry *hotspotEntry = findHotspotEntry(kDelta59RobotShieldBiochipSpotID); + hotspotEntry->hotspotItem = kShieldBiochip; + + hotspot = g_allHotspots.findHotspotByID(kDelta59RobotOpMemBiochipSpotID); + hotspot->setMaskedHotspotFlags(kPickUpBiochipSpotFlag, kPickUpBiochipSpotFlag); + hotspotEntry = findHotspotEntry(kDelta59RobotOpMemBiochipSpotID); + hotspotEntry->hotspotItem = kOpticalBiochip; + + hotspot = g_allHotspots.findHotspotByID(kDelta59RobotRetinalBiochipSpotID); + hotspot->setMaskedHotspotFlags(kPickUpBiochipSpotFlag, kPickUpBiochipSpotFlag); + hotspotEntry = findHotspotEntry(kDelta59RobotRetinalBiochipSpotID); + hotspotEntry->hotspotItem = kRetinalScanBiochip; + + hotspot = g_allHotspots.findHotspotByID(kDelta60RobotShieldBiochipSpotID); + hotspot->setMaskedHotspotFlags(kPickUpBiochipSpotFlag, kPickUpBiochipSpotFlag); + hotspotEntry = findHotspotEntry(kDelta60RobotShieldBiochipSpotID); + hotspotEntry->hotspotItem = kShieldBiochip; + + hotspot = g_allHotspots.findHotspotByID(kDelta60RobotOpMemBiochipSpotID); + hotspot->setMaskedHotspotFlags(kPickUpBiochipSpotFlag, kPickUpBiochipSpotFlag); + hotspotEntry = findHotspotEntry(kDelta60RobotOpMemBiochipSpotID); + hotspotEntry->hotspotItem = kOpticalBiochip; + + hotspot = g_allHotspots.findHotspotByID(kDelta60RobotRetinalBiochipSpotID); + hotspot->setMaskedHotspotFlags(kPickUpBiochipSpotFlag, kPickUpBiochipSpotFlag); + hotspotEntry = findHotspotEntry(kDelta60RobotRetinalBiochipSpotID); + hotspotEntry->hotspotItem = kRetinalScanBiochip; +} + +void NoradDelta::start() { + if (g_energyMonitor) { + g_energyMonitor->stopEnergyDraining(); + g_energyMonitor->restoreLastEnergyValue(); + _vm->resetEnergyDeathReason(); + g_energyMonitor->startEnergyDraining(); + } + + Norad::start(); +} + +void NoradDelta::setUpAIRules() { + Neighborhood::setUpAIRules(); + + if (g_AIArea) { + AIPlayMessageAction *messageAction = new AIPlayMessageAction("Images/AI/Norad/XN07NE", false); + AILocationCondition *locCondition = new AILocationCondition(1); + locCondition->addLocation(MakeRoomView(kNorad68, kWest)); + AIRule *rule = new AIRule(locCondition, messageAction); + g_AIArea->addAIRule(rule); + } +} + +void NoradDelta::getExtraCompassMove(const ExtraTable::Entry &entry, FaderMoveSpec &compassMove) { + switch (entry.extra) { + case kArriveFromSubChase: + compassMove.makeTwoKnotFaderSpec(kNoradDeltaMovieScale, entry.movieStart, 20, entry.movieEnd, 90); + compassMove.insertFaderKnot(entry.movieStart + 25 * kNoradDeltaFrameDuration, 20); + compassMove.insertFaderKnot(entry.movieStart + 94 * kNoradDeltaFrameDuration, 45); + compassMove.insertFaderKnot(entry.movieStart + 101 * kNoradDeltaFrameDuration, 45); + compassMove.insertFaderKnot(entry.movieStart + 146 * kNoradDeltaFrameDuration, 90 + 15); + compassMove.insertFaderKnot(entry.movieStart + 189 * kNoradDeltaFrameDuration, 90 + 15); + compassMove.insertFaderKnot(entry.movieStart + 204 * kNoradDeltaFrameDuration, 90 + 30); + compassMove.insertFaderKnot(entry.movieStart + 214 * kNoradDeltaFrameDuration, 90 + 20); + compassMove.insertFaderKnot(entry.movieStart + 222 * kNoradDeltaFrameDuration, 90 + 20); + compassMove.insertFaderKnot(entry.movieStart + 228 * kNoradDeltaFrameDuration, 90 + 10); + compassMove.insertFaderKnot(entry.movieStart + 245 * kNoradDeltaFrameDuration, 90 + 85); + compassMove.insertFaderKnot(entry.movieStart + 262 * kNoradDeltaFrameDuration, 90 + 70); + compassMove.insertFaderKnot(entry.movieStart + 273 * kNoradDeltaFrameDuration, 90 + 80); + compassMove.insertFaderKnot(entry.movieStart + 287 * kNoradDeltaFrameDuration, 90); + break; + case kN60PlayerFollowsRobotToDoor: + compassMove.makeTwoKnotFaderSpec(kNoradDeltaMovieScale, entry.movieStart, 270 + kSubControlCompassAngle, + entry.movieEnd, 270 - 15); + compassMove.insertFaderKnot(entry.movieStart + 280, 270 + kSubControlCompassAngle); + compassMove.insertFaderKnot(entry.movieStart + 920, 360); + compassMove.insertFaderKnot(entry.movieStart + 1840, 360); + compassMove.insertFaderKnot(entry.movieStart + 2520, 270); + compassMove.insertFaderKnot(entry.movieStart + 3760, 270); + compassMove.insertFaderKnot(entry.movieStart + 4640, 270 + kSubControlCompassAngle); + break; + case kN59PlayerWins2: + compassMove.makeTwoKnotFaderSpec(kNoradDeltaMovieScale, entry.movieStart, 270, entry.movieEnd, 280); + compassMove.insertFaderKnot(entry.movieEnd - 1000, 270); + default: + Norad::getExtraCompassMove(entry, compassMove); + break; + } +} + +GameInteraction *NoradDelta::makeInteraction(const tInteractionID interactionID) { + if (interactionID == kNoradGlobeGameInteractionID) + return new GlobeGame(this); + + return Norad::makeInteraction(interactionID); +} + +void NoradDelta::playClawMonitorIntro() { + playSpotSoundSync(kLoadClawIntroIn, kLoadClawIntroOut); +} + +void NoradDelta::getExitEntry(const tRoomID room, const tDirectionConstant direction, ExitTable::Entry &entry) { + Norad::getExitEntry(room, direction, entry); + + if (room == kNorad61 && direction == kSouth) + entry.movieStart += kNoradDeltaFrameDuration; +} + +void NoradDelta::getZoomEntry(const tHotSpotID id, ZoomTable::Entry &zoomEntry) { + Norad::getZoomEntry(id, zoomEntry); + + if (id == kNorad59WestSpotID && GameState.getNoradPlayedGlobeGame()) { + ExtraTable::Entry extraEntry; + getExtraEntry(kN59ZoomWithRobot, extraEntry); + zoomEntry.movieStart = extraEntry.movieStart; + zoomEntry.movieEnd = extraEntry.movieEnd; + } +} + +void NoradDelta::loadAmbientLoops() { +/* + Logic: + + loop sound 1: + if room == kNorad79West + if player globe game + play kNoradGlobeLoop2SoundNum + else + play kNoradRedAlertLoopSoundNum + else if room >= kNorad78 && room <= kNorad79 + play kNoradGlobeLoop2SoundNum + else if gassed, + if room >= kNorad41 && room <= kNorad49South + play kNoradNewSubLoopSoundNum, kNoradWarningVolume + else if room >= kNorad59 && room <= kNorad60West + play kNoradSubControlLoopSoundNum, kNoradWarningVolume + else + play kNoradWarningLoopSoundNum, kNoradWarningVolume + else + play nothing + loop sound 2: + if gassed and not wearing air mask + if room == kNorad54North + play breathing unmanned loop + else + play breathing + else + if room == kNorad54North + play unmanned loop + else + play nothing +*/ + + if (GameState.getNoradArrivedFromSub()) { + tRoomID room = GameState.getCurrentRoom(); + + if (room == kNorad79West) { + if (_privateFlags.getFlag(kNoradPrivateFinishedGlobeGameFlag)) + loadLoopSound1("Sounds/Norad/GlobAmb2.22K.AIFF"); + else + loadLoopSound1("Sounds/Norad/RedAlert.22K.AIFF"); + } else if (room >= kNorad78 && room <= kNorad79) { + // clone2727 says: This looks like it should be loadLoopSound1... + loadLoopSound2("Sounds/Norad/RedAlert.22K.AIFF"); + } else if (GameState.getNoradGassed()) { + if (room >= kNorad41 && room <= kNorad49South) + loadLoopSound1("Sounds/Norad/NEW SUB AMB.22K.AIFF", kNoradWarningVolume * 3); + else if (room >= kNorad59 && room <= kNorad60West) + loadLoopSound1("Sounds/Norad/SUB CONTRL LOOP.22K.AIFF", kNoradWarningVolume * 3); + else + loadLoopSound1("Sounds/Norad/WARNING LOOP.22K.AIFF", kNoradWarningVolume); + } else { + loadLoopSound1(""); + } + + if (GameState.getNoradGassed() && !g_airMask->isAirFilterOn()) { + if (room == kNorad54North) + loadLoopSound2("Sounds/Norad/Breathing Typing.22K.AIFF", 0x100 / 2); + else + loadLoopSound2("Sounds/Norad/SUCKING WIND.22K.AIFF", kNoradSuckWindVolume, 0, 0); + } else { + if (room == kNorad54North) + loadLoopSound2("Sounds/Norad/N54NAS.22K.AIFF", 0x100 / 2); + else + loadLoopSound2(""); + } + } else { + // Start them off at zero... + if (GameState.getNoradGassed()) + loadLoopSound1("Sounds/Norad/NEW SUB AMB.22K.AIFF", 0, 0, 0); + if (!g_airMask->isAirFilterOn()) + loadLoopSound2("Sounds/Norad/SUCKING WIND.22K.AIFF", 0, 0, 0); + } +} + +void NoradDelta::checkContinuePoint(const tRoomID room, const tDirectionConstant direction) { + switch (MakeRoomView(room, direction)) { + case MakeRoomView(kNorad41, kEast): + case MakeRoomView(kNorad49, kEast): + case MakeRoomView(kNorad49, kWest): + case MakeRoomView(kNorad61, kSouth): + case MakeRoomView(kNorad68, kEast): + case MakeRoomView(kNorad79, kWest): + makeContinuePoint(); + break; + } +} + +void NoradDelta::arriveAt(const tRoomID room, const tDirectionConstant direction) { + if (room != kNorad68) + GameState.setNoradRetScanGood(false); + + Norad::arriveAt(room, direction); + + FaderMoveSpec loop1Spec, loop2Spec; + ExtraTable::Entry entry; + + switch (room) { + case kNorad41: + if (direction == kEast && !GameState.getNoradArrivedFromSub()) { + GameState.setNoradPlayedGlobeGame(false); + + GameState.setNoradBeatRobotWithClaw(false); + GameState.setNoradBeatRobotWithDoor(false); + GameState.setNoradRetScanGood(false); + + GameState.setScoringExitedSub(true); + + getExtraEntry(kArriveFromSubChase, entry); + + loop1Spec.makeTwoKnotFaderSpec(kNoradDeltaMovieScale, 0, 0, entry.movieEnd - + entry.movieStart, kNoradWarningVolume); + loop1Spec.insertFaderKnot(7320, 0); + loop1Spec.insertFaderKnot(7880, kNoradWarningVolume); + + loop2Spec.makeTwoKnotFaderSpec(kNoradDeltaMovieScale, 0, 0, entry.movieEnd - + entry.movieStart, kNoradSuckWindVolume); + loop1Spec.insertFaderKnot(7320, 0); + loop1Spec.insertFaderKnot(7880, kNoradSuckWindVolume); + + startExtraSequence(kArriveFromSubChase, kExtraCompletedFlag, kFilterNoInput); + + startLoop1Fader(loop1Spec); + startLoop2Fader(loop2Spec); + } + break; + case kNorad54North: + GameState.setScoringSawRobotAt54North(true); + break; + case kNorad68: + if (GameState.getNoradRetScanGood()) + openDoor(); + break; + case kNorad68West: + arriveAtNorad68West(); + break; + case kNorad79West: + arriveAtNorad79West(); + break; + default: + break; + } +} + +void NoradDelta::doorOpened() { + Norad::doorOpened(); + GameState.setNoradRetScanGood(false); +} + +void NoradDelta::arriveAtNorad68West() { + playSpotSoundSync(kHoldForRetinalIn, kHoldForRetinalOut); + + BiochipItem *retScan = _vm->getCurrentBiochip(); + + if (retScan != 0 && retScan->getObjectID() == kRetinalScanBiochip) { + ((RetScanChip *)retScan)->searchForLaser(); + succeedRetinalScan(); + } else { + failRetinalScan(); + } +} + +void NoradDelta::arriveAtNorad79West() { + if (!GameState.getNoradPlayedGlobeGame()) + newInteraction(kNoradGlobeGameInteractionID); +} + +void NoradDelta::bumpIntoWall() { + requestSpotSound(kDeltaBumpIntoWallIn, kDeltaBumpIntoWallOut, kFilterNoInput, 0); + Neighborhood::bumpIntoWall(); +} + +void NoradDelta::failRetinalScan() { + startExtraSequence(kNoradDeltaRetinalScanBad, kExtraCompletedFlag, kFilterNoInput); +} + +void NoradDelta::succeedRetinalScan() { + startExtraSequence(kNoradDeltaRetinalScanGood, kExtraCompletedFlag, kFilterNoInput); + GameState.setNoradRetScanGood(true); + GameState.setScoringUsedRetinalChip(true); +} + +void NoradDelta::getDoorEntry(const tRoomID room, const tDirectionConstant direction, DoorTable::Entry &entry) { + Norad::getDoorEntry(room, direction, entry); + + if (room == kNorad68 && direction == kWest && !GameState.getNoradRetScanGood()) + entry.flags = kDoorPresentMask | kDoorLockedMask; +} + +void NoradDelta::finishedGlobeGame() { + GameState.setNoradPlayedGlobeGame(true); + _privateFlags.setFlag(kNoradPrivateFinishedGlobeGameFlag, true); + GameState.setScoringFinishedGlobeGame(true); + loadAmbientLoops(); + g_AIArea->playAIMovie(kRightAreaSignature, "Images/AI/Norad/XN60WD1", false, kWarningInterruption); +} + +bool NoradDelta::playingAgainstRobot() { + return GameState.getNoradPlayedGlobeGame(); +} + +void NoradDelta::getClawInfo(tHotSpotID &outSpotID, tHotSpotID &prepSpotID, tHotSpotID &clawControlSpotID, tHotSpotID &pinchClawSpotID, + tHotSpotID &moveClawDownSpotID, tHotSpotID &moveClawRightSpotID, tHotSpotID &moveClawLeftSpotID, tHotSpotID &moveClawUpSpotID, + tHotSpotID &clawCCWSpotID, tHotSpotID &clawCWSpotID, uint32 &clawPosition, const uint32 *&clawExtraIDs) { + outSpotID = kNorad60MonitorOutSpotID; + prepSpotID = kNorad60LaunchPrepSpotID; + clawControlSpotID = kNorad60ClawControlSpotID; + pinchClawSpotID = kNorad60ClawPinchSpotID; + moveClawDownSpotID = kNorad60ClawDownSpotID; + moveClawRightSpotID = kNorad60ClawRightSpotID; + moveClawLeftSpotID = kNorad60ClawLeftSpotID; + moveClawUpSpotID = kNorad60ClawUpSpotID; + clawCCWSpotID = kNorad60ClawCCWSpotID; + clawCWSpotID = kNorad60ClawCWSpotID; + clawPosition = kClawAtC; + clawExtraIDs = _noradDeltaClawExtras; +} + +void NoradDelta::playerBeatRobotWithDoor() { + GameState.setNoradBeatRobotWithDoor(true); + updateViewFrame(); + GameState.setScoringStoppedNoradRobot(true); + g_AIArea->playAIMovie(kRightAreaSignature, "Images/AI/Norad/XN59WD", false, kWarningInterruption); +} + +void NoradDelta::playerBeatRobotWithClaw() { + GameState.setNoradBeatRobotWithClaw(true); + updateViewFrame(); + GameState.setScoringStoppedNoradRobot(true); + GameState.setScoringNoradGandhi(true); + g_AIArea->playAIMovie(kRightAreaSignature, "Images/AI/Norad/XN59WD", false, kWarningInterruption); +} + +TimeValue NoradDelta::getViewTime(const tRoomID room, const tDirectionConstant direction) { + ExtraTable::Entry entry; + + if (room == kNorad41 && direction == kSouth && !GameState.getNoradArrivedFromSub()) { + getExtraEntry(kArriveFromSubChase, entry); + return entry.movieStart; + } + + if (GameState.getNoradBeatRobotWithDoor()) { + if (_privateFlags.getFlag(kNoradPrivateRobotHeadOpenFlag)) { + uint32 extraID = kN59Biochips111; + if (_privateFlags.getFlag(kNoradPrivateGotShieldChipFlag)) + extraID += 1; + if (_privateFlags.getFlag(kNoradPrivateGotOpticalChipFlag)) + extraID += 2; + if (_privateFlags.getFlag(kNoradPrivateGotRetScanChipFlag)) + extraID += 4; + getExtraEntry(extraID, entry); + return entry.movieStart; + } + + getExtraEntry(kN59RobotHeadOpens, entry); + return entry.movieStart; + } else if (GameState.getNoradBeatRobotWithClaw()) { + if (_privateFlags.getFlag(kNoradPrivateRobotHeadOpenFlag)) { + uint32 extraID = kN60Biochips111; + if (_privateFlags.getFlag(kNoradPrivateGotShieldChipFlag)) + extraID += 1; + if (_privateFlags.getFlag(kNoradPrivateGotOpticalChipFlag)) + extraID += 2; + if (_privateFlags.getFlag(kNoradPrivateGotRetScanChipFlag)) + extraID += 4; + getExtraEntry(extraID, entry); + return entry.movieStart; + } + + getExtraEntry(kN60RobotHeadOpens, entry); + return entry.movieStart; + } + + return Norad::getViewTime(room, direction); +} + +void NoradDelta::openDoor() { + if (GameState.getCurrentRoom() == kNorad59 && GameState.getCurrentDirection() == kWest && GameState.getNoradPlayedGlobeGame()) { + Input scratch; + InputHandler::_inputHandler->clickInHotspot(scratch, g_allHotspots.findHotspotByID(kNorad59WestSpotID)); + } else { + Norad::openDoor(); + } +} + +void NoradDelta::activateHotspots() { + Norad::activateHotspots(); + + if (GameState.getCurrentRoom() == kNorad59West && GameState.getCurrentDirection() == kWest && GameState.getNoradBeatRobotWithDoor()) { + g_allHotspots.deactivateOneHotspot(kNorad59WestOutSpotID); + + if (_privateFlags.getFlag(kNoradPrivateRobotHeadOpenFlag)) { + if (!_privateFlags.getFlag(kNoradPrivateGotShieldChipFlag)) + g_allHotspots.activateOneHotspot(kDelta59RobotShieldBiochipSpotID); + else + g_allHotspots.deactivateOneHotspot(kDelta59RobotShieldBiochipSpotID); + + if (!_privateFlags.getFlag(kNoradPrivateGotOpticalChipFlag)) + g_allHotspots.activateOneHotspot(kDelta59RobotOpMemBiochipSpotID); + else + g_allHotspots.deactivateOneHotspot(kDelta59RobotOpMemBiochipSpotID); + + if (!_privateFlags.getFlag(kNoradPrivateGotRetScanChipFlag)) + g_allHotspots.activateOneHotspot(kDelta59RobotRetinalBiochipSpotID); + else + g_allHotspots.deactivateOneHotspot(kDelta59RobotRetinalBiochipSpotID); + } else + g_allHotspots.activateOneHotspot(kDelta59RobotHeadSpotID); + } else if (GameState.getCurrentRoom() == kNorad60West && GameState.getCurrentDirection() == kWest && + GameState.getNoradBeatRobotWithClaw()) { + g_allHotspots.deactivateOneHotspot(kNorad60MonitorOutSpotID); + + if (_privateFlags.getFlag(kNoradPrivateRobotHeadOpenFlag)) { + if (!_privateFlags.getFlag(kNoradPrivateGotShieldChipFlag)) + g_allHotspots.activateOneHotspot(kDelta60RobotShieldBiochipSpotID); + else + g_allHotspots.deactivateOneHotspot(kDelta60RobotShieldBiochipSpotID); + + if (!_privateFlags.getFlag(kNoradPrivateGotOpticalChipFlag)) + g_allHotspots.activateOneHotspot(kDelta60RobotOpMemBiochipSpotID); + else + g_allHotspots.deactivateOneHotspot(kDelta60RobotOpMemBiochipSpotID); + + if (!_privateFlags.getFlag(kNoradPrivateGotRetScanChipFlag)) + g_allHotspots.activateOneHotspot(kDelta60RobotRetinalBiochipSpotID); + else + g_allHotspots.deactivateOneHotspot(kDelta60RobotRetinalBiochipSpotID); + } else { + g_allHotspots.activateOneHotspot(kDelta60RobotHeadSpotID); + } + } else if (GameState.getCurrentRoomAndView() == MakeRoomView(kNorad50, kEast)) { + if (GameState.isCurrentDoorOpen()) + g_allHotspots.deactivateOneHotspot(kNorad50DoorSpotID); + } else if (GameState.getCurrentRoomAndView() == MakeRoomView(kNorad59, kWest)) { + if (GameState.isCurrentDoorOpen()) + g_allHotspots.deactivateOneHotspot(kNorad59WestSpotID); + } +} + +void NoradDelta::clickInHotspot(const Input &input, const Hotspot *clickedSpot) { + switch (clickedSpot->getObjectID()) { + case kDelta59RobotHeadSpotID: + startExtraSequence(kN59RobotHeadOpens, kExtraCompletedFlag, kFilterNoInput); + break; + case kDelta60RobotHeadSpotID: + startExtraSequence(kN60RobotHeadOpens, kExtraCompletedFlag, kFilterNoInput); + break; + default: + Norad::clickInHotspot(input, clickedSpot); + break; + } +} + +void NoradDelta::receiveNotification(Notification *notification, const tNotificationFlags flags) { + Norad::receiveNotification(notification, flags); + + if ((flags & kExtraCompletedFlag) != 0) { + RetScanChip *retScan; + Input dummy; + + switch (_lastExtra) { + case kArriveFromSubChase: + GameState.setNoradArrivedFromSub(true); + GameState.setCurrentRoom(kNoRoomID); + GameState.setCurrentDirection(kNoDirection); + arriveAt(kNorad41, kEast); + break; + case kN59RobotHeadOpens: + case kN60RobotHeadOpens: + _privateFlags.setFlag(kNoradPrivateRobotHeadOpenFlag, true); + break; + case kNoradDeltaRetinalScanBad: + retScan = (RetScanChip *)_vm->getCurrentBiochip(); + retScan->setItemState(kNormalItem); + playSpotSoundSync(kRetinalScanFailedIn, kRetinalScanFailedOut); + downButton(dummy); + break; + case kNoradDeltaRetinalScanGood: + retScan = (RetScanChip *)_vm->getCurrentBiochip(); + retScan->setItemState(kNormalItem); + downButton(dummy); + break; + case kN59RobotDisappears: + case kN60RobotDisappears: + recallToTSASuccess(); + break; + } + + _interruptionFilter = kFilterAllInput; + } + + g_AIArea->checkMiddleArea(); +} + +void NoradDelta::pickedUpItem(Item *item) { + switch (item->getObjectID()) { + case kShieldBiochip: + if (_privateFlags.getFlag(kNoradPrivateGotShieldChipFlag) && + _privateFlags.getFlag(kNoradPrivateGotRetScanChipFlag) && + _privateFlags.getFlag(kNoradPrivateGotOpticalChipFlag)) { + GameState.setNoradFinished(true); + + if (GameState.getCurrentRoom() == kNorad59West) + startExtraSequence(kN59RobotDisappears, kExtraCompletedFlag, kFilterNoInput); + else + startExtraSequence(kN60RobotDisappears, kExtraCompletedFlag, kFilterNoInput); + } + break; + case kRetinalScanBiochip: + if (_privateFlags.getFlag(kNoradPrivateGotShieldChipFlag) && + _privateFlags.getFlag(kNoradPrivateGotRetScanChipFlag) && + _privateFlags.getFlag(kNoradPrivateGotOpticalChipFlag)) { + GameState.setNoradFinished(true); + + if (GameState.getCurrentRoom() == kNorad59West) + startExtraSequence(kN59RobotDisappears, kExtraCompletedFlag, kFilterNoInput); + else + startExtraSequence(kN60RobotDisappears, kExtraCompletedFlag, kFilterNoInput); + } + break; + case kOpticalBiochip: + g_opticalChip->addPoseidon(); + GameState.setScoringGotNoradOpMemChip(); + + if (_privateFlags.getFlag(kNoradPrivateGotShieldChipFlag) && + _privateFlags.getFlag(kNoradPrivateGotRetScanChipFlag) && + _privateFlags.getFlag(kNoradPrivateGotOpticalChipFlag)) { + GameState.setNoradFinished(true); + + if (GameState.getCurrentRoom() == kNorad59West) + startExtraSequence(kN59RobotDisappears, kExtraCompletedFlag, kFilterNoInput); + else + startExtraSequence(kN60RobotDisappears, kExtraCompletedFlag, kFilterNoInput); + } + break; + } + + Norad::pickedUpItem(item); +} + +void NoradDelta::takeItemFromRoom(Item *item) { + switch (item->getObjectID()) { + case kShieldBiochip: + _privateFlags.setFlag(kNoradPrivateGotShieldChipFlag, true); + break; + case kRetinalScanBiochip: + _privateFlags.setFlag(kNoradPrivateGotRetScanChipFlag, true); + break; + case kOpticalBiochip: + _privateFlags.setFlag(kNoradPrivateGotOpticalChipFlag, true); + break; + } + + Norad::takeItemFromRoom(item); +} + +void NoradDelta::dropItemIntoRoom(Item *item, Hotspot *hotspot) { + switch (item->getObjectID()) { + case kShieldBiochip: + _privateFlags.setFlag(kNoradPrivateGotShieldChipFlag, false); + break; + case kOpticalBiochip: + _privateFlags.setFlag(kNoradPrivateGotOpticalChipFlag, false); + break; + case kRetinalScanBiochip: + _privateFlags.setFlag(kNoradPrivateGotRetScanChipFlag, false); + break; + } + + Norad::dropItemIntoRoom(item, hotspot); +} + +Hotspot *NoradDelta::getItemScreenSpot(Item *item, DisplayElement *element) { + tHotSpotID id = kNoHotSpotID; + + switch (item->getObjectID()) { + case kShieldBiochip: + if (GameState.getNoradBeatRobotWithDoor()) + id = kDelta59RobotShieldBiochipSpotID; + else + id = kDelta60RobotShieldBiochipSpotID; + break; + case kOpticalBiochip: + if (GameState.getNoradBeatRobotWithDoor()) + id = kDelta59RobotOpMemBiochipSpotID; + else + id = kDelta60RobotOpMemBiochipSpotID; + break; + case kRetinalScanBiochip: + if (GameState.getNoradBeatRobotWithDoor()) + id = kDelta59RobotRetinalBiochipSpotID; + else + id = kDelta60RobotRetinalBiochipSpotID; + break; + } + + if (id != kNoHotSpotID) + return g_allHotspots.findHotspotByID(id); + + return Norad::getItemScreenSpot(item, element); +} + +Common::String NoradDelta::getEnvScanMovie() { + return "Images/AI/Norad/XNE2"; +} + +uint NoradDelta::getNumHints() { + uint numHints = Neighborhood::getNumHints(); + + if (numHints == 0) { + switch (GameState.getCurrentRoomAndView()) { + case MakeRoomView(kNorad60, kWest): + if (GameState.getNoradPlayedGlobeGame()) + numHints = 2; + else + numHints = 1; + break; + case MakeRoomView(kNorad59, kNorth): + case MakeRoomView(kNorad59, kSouth): + case MakeRoomView(kNorad59, kEast): + case MakeRoomView(kNorad59, kWest): + case MakeRoomView(kNorad60, kNorth): + case MakeRoomView(kNorad60, kSouth): + case MakeRoomView(kNorad60, kEast): + if (GameState.getNoradPlayedGlobeGame()) + numHints = 2; + break; + case MakeRoomView(kNorad68, kWest): + if (_vm->playerHasItemID(kRetinalScanBiochip)) { + BiochipItem *retScan = _vm->getCurrentBiochip(); + if (retScan == 0 || retScan->getObjectID() != kRetinalScanBiochip) + numHints = 2; + } else if (!GameState.isCurrentDoorOpen()) { + numHints = 2; + } + break; + } + } + + return numHints; +} + +Common::String NoradDelta::getHintMovie(uint hintNum) { + Common::String movieName = Neighborhood::getHintMovie(hintNum); + + if (movieName.empty()) { + switch (GameState.getCurrentRoomAndView()) { + case MakeRoomView(kNorad60, kWest): + if (GameState.getNoradPlayedGlobeGame()) { + if (hintNum == 1) + return "Images/AI/Norad/XN60WD2"; + + return "Images/AI/Norad/XN60WD3"; + } + + return "Images/AI/Globals/XGLOB1C"; + case MakeRoomView(kNorad59, kNorth): + case MakeRoomView(kNorad59, kSouth): + case MakeRoomView(kNorad59, kEast): + case MakeRoomView(kNorad59, kWest): + case MakeRoomView(kNorad60, kNorth): + case MakeRoomView(kNorad60, kSouth): + case MakeRoomView(kNorad60, kEast): + if (hintNum == 1) + return "Images/AI/Norad/XN60WD2"; + + return "Images/AI/Norad/XN60WD3"; + case MakeRoomView(kNorad68, kWest): + if (_vm->playerHasItemID(kRetinalScanBiochip)) { + if (hintNum == 1) + return "Images/AI/Globals/XGLOB1A"; + + return "Images/AI/Globals/XGLOB1C"; + } + + if (hintNum == 1) + return "Images/AI/Globals/XGLOB1B"; + + return "Images/AI/Globals/XGLOB3B"; + } + } + + return movieName; +} + +void NoradDelta::closeDoorOffScreen(const tRoomID room, const tDirectionConstant) { + switch (room) { + case kNorad47: + case kNorad48: + case kNorad41: + case kNorad42: + playSpotSoundSync(kDeltaElevatorDoorCloseIn, kDeltaElevatorDoorCloseOut); + break; + default: + playSpotSoundSync(kDeltaRegDoorCloseIn, kDeltaRegDoorCloseOut); + break; + } +} + +bool NoradDelta::canSolve() { + if (Norad::canSolve()) + return true; + + if (GameState.getCurrentRoomAndView() == MakeRoomView(kNorad68, kWest)) { + BiochipItem *biochip = _vm->getCurrentBiochip(); + if (biochip != 0 && biochip->getObjectID() != kRetinalScanBiochip) + return true; + } + + return false; +} + +void NoradDelta::doSolve() { + Norad::doSolve(); + + if (GameState.getCurrentRoomAndView() == MakeRoomView(kNorad68, kWest)) { + if (!_vm->playerHasItemID(kRetinalScanBiochip)) + _vm->addItemToBiochips((BiochipItem *)g_allItems.findItemByID(kRetinalScanBiochip)); + + BiochipItem *biochip = _vm->getCurrentBiochip(); + if (biochip != 0 && biochip->getObjectID() != kRetinalScanBiochip && g_interface) + g_interface->setCurrentBiochipID(kRetinalScanBiochip); + + Hotspot *spot = g_allHotspots.findHotspotByID(kNorad68WestSpotID); + Input scratch; + InputHandler::_inputHandler->clickInHotspot(scratch, spot); + } +} + +Common::String NoradDelta::getSoundSpotsName() { + return "Sounds/Norad/Norad Delta Spots"; +} + +Common::String NoradDelta::getNavMovieName() { + return "Images/Norad Delta/Norad Delta.movie"; +} + +} // End of namespace Pegasus diff --git a/engines/pegasus/neighborhood/norad/delta/noraddelta.h b/engines/pegasus/neighborhood/norad/delta/noraddelta.h new file mode 100755 index 0000000000..69798b5189 --- /dev/null +++ b/engines/pegasus/neighborhood/norad/delta/noraddelta.h @@ -0,0 +1,117 @@ +/* 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_NEIGHBORHOOD_NORAD_DELTA_NORADDELTA_H +#define PEGASUS_NEIGHBORHOOD_NORAD_DELTA_NORADDELTA_H + +#include "pegasus/neighborhood/norad/norad.h" + +namespace Pegasus { + +class NoradDelta : public Norad { +public: + NoradDelta(InputHandler *, PegasusEngine *); + virtual ~NoradDelta() {} + + void init(); + + void start(); + + void getExtraCompassMove(const ExtraTable::Entry &, FaderMoveSpec &); + + void finishedGlobeGame(); + + virtual GameInteraction *makeInteraction(const tInteractionID); + + void playClawMonitorIntro(); + + virtual void getClawInfo(tHotSpotID &outSpotID, tHotSpotID &prepSpotID, tHotSpotID &clawControlSpotID, + tHotSpotID &pinchClawSpotID, tHotSpotID &moveClawDownSpotID, tHotSpotID &moveClawRightSpotID, + tHotSpotID &moveClawLeftSpotID, tHotSpotID &moveClawUpSpotID, tHotSpotID &clawCCWSpotID, + tHotSpotID &clawCWSpotID, uint32 &, const uint32 *&); + + void playerBeatRobotWithClaw(); + void playerBeatRobotWithDoor(); + + void loadAmbientLoops(); + + void setUpAIRules(); + Common::String getEnvScanMovie(); + uint getNumHints(); + Common::String getHintMovie(uint); + void closeDoorOffScreen(const tRoomID, const tDirectionConstant); + + void checkContinuePoint(const tRoomID, const tDirectionConstant); + + bool canSolve(); + void doSolve(); + + void doorOpened(); + +protected: + enum { + kNoradPrivateArrivedFromSubFlag, + kNoradPrivateFinishedGlobeGameFlag, + kNoradPrivateRobotHeadOpenFlag, + kNoradPrivateGotShieldChipFlag, + kNoradPrivateGotOpticalChipFlag, + kNoradPrivateGotRetScanChipFlag, + kNumNoradPrivateFlags + }; + + static const uint32 _noradDeltaClawExtras[22]; + + void getExitEntry(const tRoomID, const tDirectionConstant, ExitTable::Entry &); + void getZoomEntry(const tHotSpotID, ZoomTable::Entry &); + virtual void arriveAt(const tRoomID, const tDirectionConstant); + void arriveAtNorad68West(); + void arriveAtNorad79West(); + TimeValue getViewTime(const tRoomID, const tDirectionConstant); + void openDoor(); + void activateHotspots(); + void clickInHotspot(const Input &, const Hotspot *); + void receiveNotification(Notification *, const tNotificationFlags); + void pickedUpItem(Item *item); + void takeItemFromRoom(Item *item); + void dropItemIntoRoom(Item *item, Hotspot *); + Hotspot *getItemScreenSpot(Item *, DisplayElement *); + + virtual bool playingAgainstRobot(); + + void failRetinalScan(); + void succeedRetinalScan(); + void getDoorEntry(const tRoomID, const tDirectionConstant, DoorTable::Entry &); + + void bumpIntoWall(); + + FlagsArray<byte, kNumNoradPrivateFlags> _privateFlags; + + Common::String getSoundSpotsName(); + Common::String getNavMovieName(); +}; + +} // End of namespace Pegasus + +#endif diff --git a/engines/pegasus/neighborhood/norad/norad.cpp b/engines/pegasus/neighborhood/norad/norad.cpp index 931d854f3a..8e891f37c1 100755 --- a/engines/pegasus/neighborhood/norad/norad.cpp +++ b/engines/pegasus/neighborhood/norad/norad.cpp @@ -28,6 +28,7 @@ #include "pegasus/pegasus.h" #include "pegasus/ai/ai_area.h" #include "pegasus/items/inventory/airmask.h" +#include "pegasus/neighborhood/norad/constants.h" #include "pegasus/neighborhood/norad/norad.h" #include "pegasus/neighborhood/norad/noradelevator.h" #include "pegasus/neighborhood/norad/pressuredoor.h" diff --git a/engines/pegasus/neighborhood/norad/norad.h b/engines/pegasus/neighborhood/norad/norad.h index 5e818901dc..eb4c480bf8 100755 --- a/engines/pegasus/neighborhood/norad/norad.h +++ b/engines/pegasus/neighborhood/norad/norad.h @@ -30,462 +30,6 @@ namespace Pegasus { -const tCanOpenDoorReason kCantOpenBadPressure = kCantOpenLastReason + 1; - -const tNotificationFlags kAirTimerExpiredFlag = kLastNeighborhoodNotificationFlag << 1; - -const uint16 kNoradWarningVolume = 0x100 / 3; -const uint16 kNoradSuckWindVolume = 0x100 / 2; - -const int16 kElevatorCompassAngle = -40; -const int16 kSubPlatformCompassAngle = 45; -const int16 kSubControlCompassAngle = -10; - -// Norad interactions. - -const tInteractionID kNoradGlobeGameInteractionID = 0; -const tInteractionID kNoradECRMonitorInteractionID = 1; -const tInteractionID kNoradFillingStationInteractionID = 2; -const tInteractionID kNoradElevatorInteractionID = 3; -const tInteractionID kNoradPressureDoorInteractionID = 4; -const tInteractionID kNoradSubControlRoomInteractionID = 5; -const tInteractionID kNoradSubPlatformInteractionID = 6; - -///////////////////////////////////////////// -// -// Norad Alpha - -const tCoordType kECRSlideShowLeft = kNavAreaLeft + 78; -const tCoordType kECRSlideShowTop = kNavAreaTop + 1; - -const tCoordType kECRPanLeft = kNavAreaLeft + 78 + 5; -const tCoordType kECRPanTop = kNavAreaTop + 1 + 4; -const tCoordType kECRPanRight = kECRPanLeft + 213; -const tCoordType kECRPanBottom = kECRPanTop + 241; - -const tCoordType kNoradAlphaElevatorControlsLeft = kNavAreaLeft + 332; -const tCoordType kNoradAlphaElevatorControlsTop = kNavAreaTop + 127; - -const tCoordType kNoradAlpha01LeftSideLeft = kNavAreaLeft + 0; -const tCoordType kNoradAlpha01LeftSideTop = kNavAreaTop + 0; - -const tCoordType kNoradAlpha01RightSideLeft = kNavAreaLeft + 240; -const tCoordType kNoradAlpha01RightSideTop = kNavAreaTop + 12; - -const tCoordType kNoradUpperLevelsLeft = kNavAreaLeft + 98; -const tCoordType kNoradUpperLevelsTop = kNavAreaTop + 31; - -const tCoordType kNoradUpperTypeLeft = kNoradUpperLevelsLeft + 114; -const tCoordType kNoradUpperTypeTop = kNoradUpperLevelsTop + 8; - -const tCoordType kNoradUpperUpLeft = kNavAreaLeft + 361; -const tCoordType kNoradUpperUpTop = kNavAreaTop + 32; - -const tCoordType kNoradUpperDownLeft = kNavAreaLeft + 367; -const tCoordType kNoradUpperDownTop = kNavAreaTop + 66; - -const tCoordType kNoradLowerLevelsLeft = kNavAreaLeft + 74; -const tCoordType kNoradLowerLevelsTop = kNavAreaTop + 157; - -const tCoordType kNoradLowerTypeLeft = kNoradLowerLevelsLeft + 144; -const tCoordType kNoradLowerTypeTop = kNoradLowerLevelsTop + 9; - -const tCoordType kNoradLowerUpLeft = kNavAreaLeft + 380; -const tCoordType kNoradLowerUpTop = kNavAreaTop + 164; - -const tCoordType kNoradLowerDownLeft = kNavAreaLeft + 388; -const tCoordType kNoradLowerDownTop = kNavAreaTop + 212; - -const tCoordType kNoradPlatformLeft = kNavAreaLeft + 36; -const tCoordType kNoradPlatformTop = kNavAreaTop + 87; - -const tCoordType kNoradSubControlLeft = kNavAreaLeft + 0; -const tCoordType kNoradSubControlTop = kNavAreaTop + 84; - -const tCoordType kNoradSubControlPinchLeft = kNoradSubControlLeft + 106; -const tCoordType kNoradSubControlPinchTop = kNoradSubControlTop + 86; - -const tCoordType kNoradSubControlDownLeft = kNoradSubControlLeft + 66; -const tCoordType kNoradSubControlDownTop = kNoradSubControlTop + 106; - -const tCoordType kNoradSubControlRightLeft = kNoradSubControlLeft + 83; -const tCoordType kNoradSubControlRightTop = kNoradSubControlTop + 90; - -const tCoordType kNoradSubControlLeftLeft = kNoradSubControlLeft + 56; -const tCoordType kNoradSubControlLeftTop = kNoradSubControlTop + 91; - -const tCoordType kNoradSubControlUpLeft = kNoradSubControlLeft + 66; -const tCoordType kNoradSubControlUpTop = kNoradSubControlTop + 81; - -const tCoordType kNoradSubControlCCWLeft = kNoradSubControlLeft + 29; -const tCoordType kNoradSubControlCCWTop = kNoradSubControlTop + 88; - -const tCoordType kNoradSubControlCWLeft = kNoradSubControlLeft + 0; -const tCoordType kNoradSubControlCWTop = kNoradSubControlTop + 89; - -const tCoordType kNoradClawMonitorLeft = kNavAreaLeft + 288; -const tCoordType kNoradClawMonitorTop = kNavAreaTop + 97; - -const tCoordType kNoradGreenBallAtALeft = kNoradClawMonitorLeft + 179; -const tCoordType kNoradGreenBallAtATop = kNoradClawMonitorTop + 82; - -const tCoordType kNoradGreenBallAtBLeft = kNoradClawMonitorLeft + 130; -const tCoordType kNoradGreenBallAtBTop = kNoradClawMonitorTop + 73; - -const tCoordType kNoradGreenBallAtCLeft = kNoradClawMonitorLeft + 110; -const tCoordType kNoradGreenBallAtCTop = kNoradClawMonitorTop + 26; - -const tCoordType kNoradGreenBallAtDLeft = kNoradClawMonitorLeft + 21; -const tCoordType kNoradGreenBallAtDTop = kNoradClawMonitorTop + 49; - -///////////////////////////////////////////// -// -// Norad Delta - -const tCoordType kGlobeMonitorLeft = kNavAreaLeft + 360; -const tCoordType kGlobeMonitorTop = kNavAreaTop + 144; - -const tCoordType kGlobeLeft = kNavAreaLeft + 172; -const tCoordType kGlobeTop = kNavAreaTop; - -const tCoordType kGlobeCircleLeftLeft = kNavAreaLeft + 186; -const tCoordType kGlobeCircleLeftTop = kNavAreaTop + 41; - -const tCoordType kGlobeCircleRightLeft = kNavAreaLeft + 321; -const tCoordType kGlobeCircleRightTop = kNavAreaTop + 41; - -const tCoordType kGlobeCircleUpLeft = kNavAreaLeft + 220; -const tCoordType kGlobeCircleUpTop = kNavAreaTop + 7; - -const tCoordType kGlobeCircleDownLeft = kNavAreaLeft + 220; -const tCoordType kGlobeCircleDownTop = kNavAreaTop + 142; - -const tCoordType kGlobeUpperLeftHiliteLeft = kNavAreaLeft + 207; -const tCoordType kGlobeUpperLeftHiliteTop = kNavAreaTop + 28; - -const tCoordType kGlobeUpperRightHiliteLeft = kNavAreaLeft + 307; -const tCoordType kGlobeUpperRightHiliteTop = kNavAreaTop + 28; - -const tCoordType kGlobeLowerLeftHiliteLeft = kNavAreaLeft + 207; -const tCoordType kGlobeLowerLeftHiliteTop = kNavAreaTop + 128; - -const tCoordType kGlobeLowerRightHiliteLeft = kNavAreaLeft + 307; -const tCoordType kGlobeLowerRightHiliteTop = kNavAreaTop + 128; - -const tCoordType kGlobeLeftMotionHiliteLeft = kNavAreaLeft + 182; -const tCoordType kGlobeLeftMotionHiliteTop = kNavAreaTop + 60; - -const tCoordType kGlobeRightMotionHiliteLeft = kNavAreaLeft + 331; -const tCoordType kGlobeRightMotionHiliteTop = kNavAreaTop + 60; - -const tCoordType kGlobeUpMotionHiliteLeft = kNavAreaLeft + 239; -const tCoordType kGlobeUpMotionHiliteTop = kNavAreaTop + 3; - -const tCoordType kGlobeDownMotionHiliteLeft = kNavAreaLeft + 239; -const tCoordType kGlobeDownMotionHiliteTop = kNavAreaTop + 152; - -const tCoordType kGlobeUpperNamesLeft = kNavAreaLeft + 368; -const tCoordType kGlobeUpperNamesTop = kNavAreaTop + 188; - -const tCoordType kGlobeLowerNamesLeft = kNavAreaLeft + 368; -const tCoordType kGlobeLowerNamesTop = kNavAreaTop + 212; - -const tCoordType kGlobeCountdownLeft = kNavAreaLeft + 478; -const tCoordType kGlobeCountdownTop = kNavAreaTop + 164; - -// Norad Alpha display IDs. - -const tDisplayElementID kECRSlideShowMovieID = kNeighborhoodDisplayID; -const tDisplayElementID kECRPanID = kECRSlideShowMovieID + 1; -const tDisplayElementID kNoradAlphaDeathMovieID = kECRPanID + 1; -const tDisplayElementID kNoradElevatorControlsID = kNoradAlphaDeathMovieID + 1; -const tDisplayElementID kN01LeftSideID = kNoradElevatorControlsID + 1; -const tDisplayElementID kN01RightSideID = kN01LeftSideID + 1; -const tDisplayElementID kPressureDoorLevelsID = kN01RightSideID + 1; -const tDisplayElementID kPressureDoorTypeID = kPressureDoorLevelsID + 1; -const tDisplayElementID kPressureDoorUpButtonID = kPressureDoorTypeID + 1; -const tDisplayElementID kPressureDoorDownButtonID = kPressureDoorUpButtonID + 1; -const tDisplayElementID kPlatformMonitorID = kPressureDoorDownButtonID + 1; -const tDisplayElementID kSubControlMonitorID = kPlatformMonitorID + 1; -const tDisplayElementID kClawMonitorID = kSubControlMonitorID + 1; -const tDisplayElementID kSubControlPinchID = kClawMonitorID + 1; -const tDisplayElementID kSubControlDownID = kSubControlPinchID + 1; -const tDisplayElementID kSubControlRightID = kSubControlDownID + 1; -const tDisplayElementID kSubControlLeftID = kSubControlRightID + 1; -const tDisplayElementID kSubControlUpID = kSubControlLeftID + 1; -const tDisplayElementID kSubControlCCWID = kSubControlUpID + 1; -const tDisplayElementID kSubControlCWID = kSubControlCCWID + 1; -const tDisplayElementID kClawMonitorGreenBallID = kSubControlCWID + 1; - -// Norad Delta display IDs. - -const tDisplayElementID kGlobeMonitorID = kNeighborhoodDisplayID; -const tDisplayElementID kGlobeMovieID = kGlobeMonitorID + 14; -const tDisplayElementID kGlobeCircleLeftID = kGlobeMovieID + 1; -const tDisplayElementID kGlobeCircleRightID = kGlobeCircleLeftID + 1; -const tDisplayElementID kGlobeCircleUpID = kGlobeCircleRightID + 1; -const tDisplayElementID kGlobeCircleDownID = kGlobeCircleUpID + 1; -const tDisplayElementID kMotionHiliteLeftID = kGlobeCircleDownID + 1; -const tDisplayElementID kMotionHiliteRightID = kMotionHiliteLeftID + 1; -const tDisplayElementID kMotionHiliteUpID = kMotionHiliteRightID + 1; -const tDisplayElementID kMotionHiliteDownID = kMotionHiliteUpID + 1; -const tDisplayElementID kTargetHiliteUpperLeftID = kMotionHiliteDownID + 1; -const tDisplayElementID kTargetHiliteUpperRightID = kTargetHiliteUpperLeftID + 1; -const tDisplayElementID kTargetHiliteLowerLeftID = kTargetHiliteUpperRightID + 1; -const tDisplayElementID kTargetHiliteLowerRightID = kTargetHiliteLowerLeftID + 1; -const tDisplayElementID kGlobeUpperNamesID = kTargetHiliteLowerRightID + 1; -const tDisplayElementID kGlobeLowerNamesID = kGlobeUpperNamesID + 1; -const tDisplayElementID kGlobeCountdownID = kGlobeLowerNamesID + 1; - -// Norad Alpha: - -const tDisplayOrder kECRMonitorOrder = kMonitorLayer; -const tDisplayOrder kECRPanOrder = kECRMonitorOrder + 1; - -const tDisplayOrder kN01LeftSideOrder = kMonitorLayer; -const tDisplayOrder kN01RightSideOrder = kN01LeftSideOrder + 1; - -const tDisplayOrder kElevatorControlsOrder = kMonitorLayer; - -const tDisplayOrder kPressureLevelsOrder = kMonitorLayer; -const tDisplayOrder kPressureTypeOrder = kPressureLevelsOrder + 1; -const tDisplayOrder kPressureUpOrder = kPressureTypeOrder + 1; -const tDisplayOrder kPressureDownOrder = kPressureUpOrder + 1; - -const tDisplayOrder kPlatformOrder = kMonitorLayer; - -const tDisplayOrder kSubControlOrder = kMonitorLayer; -const tDisplayOrder kClawMonitorOrder = kSubControlOrder + 1; -const tDisplayOrder kSubControlPinchOrder = kClawMonitorOrder + 1; -const tDisplayOrder kSubControlDownOrder = kSubControlPinchOrder + 1; -const tDisplayOrder kSubControlRightOrder = kSubControlDownOrder + 1; -const tDisplayOrder kSubControlLeftOrder = kSubControlRightOrder + 1; -const tDisplayOrder kSubControlUpOrder = kSubControlLeftOrder + 1; -const tDisplayOrder kSubControlCCWOrder = kSubControlUpOrder + 1; -const tDisplayOrder kSubControlCWOrder = kSubControlCCWOrder + 1; -const tDisplayOrder kClawMonitorGreenBallOrder = kSubControlCWOrder + 1; - -// Norad Delta: - -const tDisplayOrder kGlobeMonitorLayer = kMonitorLayer; -const tDisplayOrder kGlobeMovieLayer = kGlobeMonitorLayer + 1; -const tDisplayOrder kGlobeCircleLayer = kGlobeMovieLayer + 1; -const tDisplayOrder kGlobeHilitesLayer = kGlobeCircleLayer + 1; -const tDisplayOrder kGlobeUpperNamesLayer = kGlobeHilitesLayer + 1; -const tDisplayOrder kGlobeLowerNamesLayer = kGlobeUpperNamesLayer + 1; -const tDisplayOrder kGlobeCountdownLayer = kGlobeLowerNamesLayer + 1; - - -// Norad Alpha constants - -const TimeScale kNoradAlphaMovieScale = 600; -const TimeScale kNoradAlphaFramesPerSecond = 15; -const TimeScale kNoradAlphaFrameDuration = 40; - -// Alternate IDs. - -const tAlternateID kAltNoradAlphaNormal = 0; - -// Room IDs. - -const tRoomID kNorad01 = 0; -const tRoomID kNorad01East = 1; -const tRoomID kNorad01West = 2; -const tRoomID kNorad02 = 3; -const tRoomID kNorad03 = 4; -const tRoomID kNorad04 = 5; -const tRoomID kNorad05 = 6; -const tRoomID kNorad06 = 7; -const tRoomID kNorad07 = 8; -const tRoomID kNorad07North = 9; -const tRoomID kNorad08 = 10; -const tRoomID kNorad09 = 11; -const tRoomID kNorad10 = 12; -const tRoomID kNorad10East = 13; -const tRoomID kNorad11 = 14; -const tRoomID kNorad11South = 15; -const tRoomID kNorad12 = 16; -const tRoomID kNorad12South = 17; -const tRoomID kNorad13 = 18; -const tRoomID kNorad14 = 19; -const tRoomID kNorad15 = 20; -const tRoomID kNorad16 = 21; -const tRoomID kNorad17 = 22; -const tRoomID kNorad18 = 23; -const tRoomID kNorad19 = 24; -const tRoomID kNorad19West = 25; -const tRoomID kNorad21 = 26; -const tRoomID kNorad21West = 27; -const tRoomID kNorad22 = 28; -const tRoomID kNorad22West = 29; - -// Hot Spot Activation IDs. - - -// Hot Spot IDs. - -const tHotSpotID kNorad01ECRSpotID = 5000; -const tHotSpotID kNorad01GasSpotID = 5001; -const tHotSpotID kNorad01ECROutSpotID = 5002; -const tHotSpotID kNorad01GasOutSpotID = 5003; -const tHotSpotID kNorad01MonitorSpotID = 5004; -const tHotSpotID kNorad01IntakeSpotID = 5005; -const tHotSpotID kNorad01DispenseSpotID = 5006; -const tHotSpotID kNorad01ArSpotID = 5007; -const tHotSpotID kNorad01CO2SpotID = 5008; -const tHotSpotID kNorad01HeSpotID = 5009; -const tHotSpotID kNorad01OSpotID = 5010; -const tHotSpotID kNorad01NSpotID = 5011; -const tHotSpotID kN01GasCanisterSpotID = 5012; -const tHotSpotID kN01ArgonCanisterSpotID = 5013; -const tHotSpotID kN01AirMaskSpotID = 5014; -const tHotSpotID kN01NitrogenCanisterSpotID = 5015; -const tHotSpotID kN01GasOutletSpotID = 5016; -const tHotSpotID kNorad07DoorSpotID = 5017; -const tHotSpotID kNorad07DoorOutSpotID = 5018; -const tHotSpotID kNorad10DoorSpotID = 5019; -const tHotSpotID kNorad10EastOutSpotID = 5020; -const tHotSpotID kAlphaUpperPressureDoorUpSpotID = 5021; -const tHotSpotID kAlphaUpperPressureDoorDownSpotID = 5022; -const tHotSpotID kNorad11ElevatorSpotID = 5023; -const tHotSpotID kNorad11ElevatorOutSpotID = 5024; -const tHotSpotID kNorad11ElevatorDownSpotID = 5025; -const tHotSpotID kNorad12ElevatorSpotID = 5026; -const tHotSpotID kNorad12ElevatorOutSpotID = 5027; -const tHotSpotID kNorad12ElevatorUpSpotID = 5028; -const tHotSpotID kNorad19MonitorSpotID = 5029; -const tHotSpotID kNorad19MonitorOutSpotID = 5030; -const tHotSpotID kNorad19ActivateMonitorSpotID = 5031; -const tHotSpotID kNorad21WestSpotID = 5032; -const tHotSpotID kNorad21WestOutSpotID = 5033; -const tHotSpotID kAlphaLowerPressureDoorUpSpotID = 5034; -const tHotSpotID kAlphaLowerPressureDoorDownSpotID = 5035; -const tHotSpotID kNorad22MonitorSpotID = 5036; -const tHotSpotID kNorad22MonitorOutSpotID = 5037; -const tHotSpotID kNorad22LaunchPrepSpotID = 5038; -const tHotSpotID kNorad22ClawControlSpotID = 5039; -const tHotSpotID kNorad22ClawPinchSpotID = 5040; -const tHotSpotID kNorad22ClawDownSpotID = 5041; -const tHotSpotID kNorad22ClawRightSpotID = 5042; -const tHotSpotID kNorad22ClawLeftSpotID = 5043; -const tHotSpotID kNorad22ClawUpSpotID = 5044; -const tHotSpotID kNorad22ClawCCWSpotID = 5045; -const tHotSpotID kNorad22ClawCWSpotID = 5046; - -// Extra sequence IDs. - -const tExtraID kNoradArriveFromTSA = 0; -const tExtraID kNorad01RobotTaunt = 1; -const tExtraID kNorad01ZoomInWithGasCanister = 2; -const tExtraID kN01WGasCanister = 3; -const tExtraID kNorad01ZoomOutWithGasCanister = 4; -const tExtraID kN01WZEmptyLit = 5; -const tExtraID kN01WZGasCanisterDim = 6; -const tExtraID kN01WZGasCanisterLit = 7; -const tExtraID kN01WZArgonCanisterDim = 8; -const tExtraID kN01WZArgonCanisterLit = 9; -const tExtraID kN01WZAirMaskDim = 10; -const tExtraID kN01WZAirMaskLit = 11; -const tExtraID kN01WZNitrogenCanisterDim = 12; -const tExtraID kN01WZNitrogenCanisterLit = 13; -const tExtraID kNorad04EastDeath = 14; -const tExtraID kNorad19PrepSub = 15; -const tExtraID kNorad19ExitToSub = 16; -const tExtraID kNorad22SouthIntro = 17; -const tExtraID kNorad22SouthReply = 18; -const tExtraID kNorad22SouthFinish = 19; -const tExtraID kN22ClawFromAToB = 20; -const tExtraID kN22ClawALoop = 21; -const tExtraID kN22ClawAPinch = 22; -const tExtraID kN22ClawACounterclockwise = 23; -const tExtraID kN22ClawAClockwise = 24; -const tExtraID kN22ClawFromBToA = 25; -const tExtraID kN22ClawFromBToC = 26; -const tExtraID kN22ClawFromBToD = 27; -const tExtraID kN22ClawBLoop = 28; -const tExtraID kN22ClawBPinch = 29; -const tExtraID kN22ClawBCounterclockwise = 30; -const tExtraID kN22ClawBClockwise = 31; -const tExtraID kN22ClawFromCToB = 32; -const tExtraID kN22ClawCLoop = 33; -const tExtraID kN22ClawCPinch = 34; -const tExtraID kN22ClawCCounterclockwise = 35; -const tExtraID kN22ClawCClockwise = 36; -const tExtraID kN22ClawFromDToB = 37; -const tExtraID kN22ClawDLoop = 38; -const tExtraID kN22ClawDPinch = 39; -const tExtraID kN22ClawDCounterclockwise = 40; -const tExtraID kN22ClawDClockwise = 41; - - -// Norad Delta Extra sequence IDs. - -const tExtraID kArriveFromSubChase = 0; -const tExtraID kN59ZoomWithRobot = 1; -const tExtraID kN59RobotApproaches = 2; -const tExtraID kN59RobotPunchLoop = 3; -const tExtraID kN59PlayerWins1 = 4; -const tExtraID kN59PlayerWins2 = 5; -const tExtraID kN59RobotWins = 6; -const tExtraID kN59RobotHeadOpens = 7; -const tExtraID kN59Biochips111 = 8; -const tExtraID kN59Biochips011 = 9; -const tExtraID kN59Biochips101 = 10; -const tExtraID kN59Biochips001 = 11; -const tExtraID kN59Biochips110 = 12; -const tExtraID kN59Biochips010 = 13; -const tExtraID kN59Biochips100 = 14; -const tExtraID kN59Biochips000 = 15; -const tExtraID kN59RobotDisappears = 16; -const tExtraID kN60ClawFromAToB = 17; -const tExtraID kN60ClawALoop = 18; -const tExtraID kN60ClawAPinch = 19; -const tExtraID kN60ClawACounterclockwise = 20; -const tExtraID kN60ClawAClockwise = 21; -const tExtraID kN60ClawFromBToA = 22; -const tExtraID kN60ClawFromBToC = 23; -const tExtraID kN60ClawFromBToD = 24; -const tExtraID kN60ClawBLoop = 25; -const tExtraID kN60ClawBPinch = 26; -const tExtraID kN60ClawBCounterclockwise = 27; -const tExtraID kN60ClawBClockwise = 28; -const tExtraID kN60ClawFromCToB = 29; -const tExtraID kN60ClawCLoop = 30; -const tExtraID kN60ClawCPinch = 31; -const tExtraID kN60ClawCCounterclockwise = 32; -const tExtraID kN60ClawCClockwise = 33; -const tExtraID kN60ClawFromDToB = 34; -const tExtraID kN60ClawDLoop = 35; -const tExtraID kN60ClawDPinch = 36; -const tExtraID kN60ClawDCounterclockwise = 37; -const tExtraID kN60ClawDClockwise = 38; -const tExtraID kN60RobotApproaches = 39; -const tExtraID kN60FirstMistake = 40; -const tExtraID kN60ArmActivated = 41; -const tExtraID kN60SecondMistake = 42; -const tExtraID kN60ArmToPositionB = 43; -const tExtraID kN60ThirdMistake = 44; -const tExtraID kN60ArmGrabsRobot = 45; -const tExtraID kN60FourthMistake = 46; -const tExtraID kN60ArmCarriesRobotToPositionA = 47; -const tExtraID kN60PlayerFollowsRobotToDoor = 48; -const tExtraID kN60RobotHeadOpens = 49; -const tExtraID kN60Biochips111 = 50; -const tExtraID kN60Biochips011 = 51; -const tExtraID kN60Biochips101 = 52; -const tExtraID kN60Biochips001 = 53; -const tExtraID kN60Biochips110 = 54; -const tExtraID kN60Biochips010 = 55; -const tExtraID kN60Biochips100 = 56; -const tExtraID kN60Biochips000 = 57; -const tExtraID kN60RobotDisappears = 58; -const tExtraID kNoradDeltaRetinalScanBad = 59; -const tExtraID kNoradDeltaRetinalScanGood = 60; -const tExtraID kN79BrightView = 61; - -const tRoomID kNorad59West = 23; -const tRoomID kNorad60West = 25; - // This is the code common to both Norad Alpha and Norad Delta class Norad : public Neighborhood { diff --git a/engines/pegasus/neighborhood/norad/noradelevator.cpp b/engines/pegasus/neighborhood/norad/noradelevator.cpp index 98b3d2949e..0cdc818cab 100755 --- a/engines/pegasus/neighborhood/norad/noradelevator.cpp +++ b/engines/pegasus/neighborhood/norad/noradelevator.cpp @@ -25,6 +25,7 @@ #include "pegasus/gamestate.h" #include "pegasus/pegasus.h" +#include "pegasus/neighborhood/norad/constants.h" #include "pegasus/neighborhood/norad/norad.h" #include "pegasus/neighborhood/norad/noradelevator.h" diff --git a/engines/pegasus/neighborhood/norad/pressuredoor.cpp b/engines/pegasus/neighborhood/norad/pressuredoor.cpp index 59adb09e2e..7cb483f63a 100755 --- a/engines/pegasus/neighborhood/norad/pressuredoor.cpp +++ b/engines/pegasus/neighborhood/norad/pressuredoor.cpp @@ -26,8 +26,10 @@ #include "pegasus/gamestate.h" #include "pegasus/pegasus.h" #include "pegasus/ai/ai_area.h" +#include "pegasus/neighborhood/norad/constants.h" #include "pegasus/neighborhood/norad/norad.h" #include "pegasus/neighborhood/norad/pressuredoor.h" +#include "pegasus/neighborhood/norad/delta/noraddelta.h" namespace Pegasus { @@ -338,8 +340,7 @@ void PressureDoor::receiveNotification(Notification *notification, const tNotifi break; case kRobotDead: allowInput(true); - // TODO - //((NoradDelta *)owner)->playerBeatRobotWithDoor(); + ((NoradDelta *)owner)->playerBeatRobotWithDoor(); owner->requestDeleteCurrentInteraction(); break; } diff --git a/engines/pegasus/neighborhood/norad/subcontrolroom.cpp b/engines/pegasus/neighborhood/norad/subcontrolroom.cpp index 9174a72494..0515f967e8 100755 --- a/engines/pegasus/neighborhood/norad/subcontrolroom.cpp +++ b/engines/pegasus/neighborhood/norad/subcontrolroom.cpp @@ -25,8 +25,10 @@ #include "pegasus/gamestate.h" #include "pegasus/pegasus.h" +#include "pegasus/neighborhood/norad/constants.h" #include "pegasus/neighborhood/norad/norad.h" #include "pegasus/neighborhood/norad/subcontrolroom.h" +#include "pegasus/neighborhood/norad/delta/noraddelta.h" namespace Pegasus { @@ -658,8 +660,7 @@ void SubControlRoom::receiveNotification(Notification *notification, const tNoti owner->startExtraSequence(kN60PlayerFollowsRobotToDoor, kExtraCompletedFlag, kFilterAllInput); break; case kPlayerWon: - // TODO - //((NoradDelta *)owner)->playerBeatRobotWithClaw(); + ((NoradDelta *)owner)->playerBeatRobotWithClaw(); owner->requestDeleteCurrentInteraction(); break; case kRobotWon: diff --git a/engines/pegasus/neighborhood/norad/subplatform.cpp b/engines/pegasus/neighborhood/norad/subplatform.cpp index 2665ab4ec5..dd2058c3d9 100755 --- a/engines/pegasus/neighborhood/norad/subplatform.cpp +++ b/engines/pegasus/neighborhood/norad/subplatform.cpp @@ -26,6 +26,7 @@ #include "pegasus/gamestate.h" #include "pegasus/pegasus.h" #include "pegasus/ai/ai_area.h" +#include "pegasus/neighborhood/norad/constants.h" #include "pegasus/neighborhood/norad/norad.h" #include "pegasus/neighborhood/norad/subplatform.h" #include "pegasus/neighborhood/norad/alpha/noradalpha.h" diff --git a/engines/pegasus/neighborhood/tsa/fulltsa.cpp b/engines/pegasus/neighborhood/tsa/fulltsa.cpp index 3d19cc3370..3884f0f246 100755 --- a/engines/pegasus/neighborhood/tsa/fulltsa.cpp +++ b/engines/pegasus/neighborhood/tsa/fulltsa.cpp @@ -31,7 +31,7 @@ #include "pegasus/items/biochips/aichip.h" #include "pegasus/items/biochips/opticalchip.h" #include "pegasus/neighborhood/caldoria/caldoria.h" -#include "pegasus/neighborhood/norad/alpha/noradalpha.h" +#include "pegasus/neighborhood/norad/constants.h" #include "pegasus/neighborhood/prehistoric/prehistoric.h" #include "pegasus/neighborhood/mars/constants.h" #include "pegasus/neighborhood/tsa/fulltsa.h" diff --git a/engines/pegasus/neighborhood/tsa/tinytsa.cpp b/engines/pegasus/neighborhood/tsa/tinytsa.cpp index a2e2ef85f6..da3a55c17f 100755 --- a/engines/pegasus/neighborhood/tsa/tinytsa.cpp +++ b/engines/pegasus/neighborhood/tsa/tinytsa.cpp @@ -30,7 +30,7 @@ #include "pegasus/items/biochips/aichip.h" #include "pegasus/items/biochips/opticalchip.h" #include "pegasus/neighborhood/mars/constants.h" -#include "pegasus/neighborhood/norad/alpha/noradalpha.h" +#include "pegasus/neighborhood/norad/constants.h" #include "pegasus/neighborhood/tsa/tinytsa.h" #include "pegasus/neighborhood/wsc/wsc.h" diff --git a/engines/pegasus/pegasus.cpp b/engines/pegasus/pegasus.cpp index de2e7f422d..e5a17769b8 100644 --- a/engines/pegasus/pegasus.cpp +++ b/engines/pegasus/pegasus.cpp @@ -63,7 +63,9 @@ #include "pegasus/neighborhood/neighborhood.h" #include "pegasus/neighborhood/caldoria/caldoria.h" #include "pegasus/neighborhood/mars/mars.h" +#include "pegasus/neighborhood/norad/constants.h" #include "pegasus/neighborhood/norad/alpha/noradalpha.h" +#include "pegasus/neighborhood/norad/delta/noraddelta.h" #include "pegasus/neighborhood/prehistoric/prehistoric.h" #include "pegasus/neighborhood/tsa/fulltsa.h" #include "pegasus/neighborhood/tsa/tinytsa.h" @@ -1374,7 +1376,7 @@ void PegasusEngine::makeNeighborhood(tNeighborhoodID neighborhoodID, Neighborhoo break; case kNoradDeltaID: createInterface(); - error("TODO: Norad Delta"); + neighborhood = new NoradDelta(g_AIArea, this); break; default: error("Unknown neighborhood %d", neighborhoodID); |