Initial commit

This commit is contained in:
2026-02-02 04:50:13 +01:00
commit 5b11698731
22592 changed files with 7677434 additions and 0 deletions

View File

@@ -0,0 +1,539 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* Additional copyright for this file:
* Copyright (C) 1995-2013 Presto Studios, Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "pegasus/pegasus.h"
#include "pegasus/neighborhood/mars/canyonchase.h"
#include "pegasus/neighborhood/mars/mars.h"
namespace Pegasus {
// Segment start and end points.
//static const TimeValue kPrepStart = 0;
static const TimeValue kPrepEnd = 3000;
static const TimeValue kLaunchStart = kPrepEnd;
static const TimeValue kLaunchEnd = 6640;
static const TimeValue kBranch1Start = kLaunchEnd;
static const TimeValue kBranch1End = 22240;
static const TimeValue kBranch2Start = kBranch1End;
static const TimeValue kBranch2End = 28440;
static const TimeValue kBranch3Start = kBranch2End;
static const TimeValue kBranch3End = 38640;
static const TimeValue kBranch4Start = kBranch3End;
static const TimeValue kBranch4End = 43880;
static const TimeValue kBranch5Start = kBranch4End;
static const TimeValue kBranch5End = 58680;
static const TimeValue kExitStart = kBranch5End;
static const TimeValue kExitEnd = 66480;
static const TimeValue kExitLoopPoint = 66200;
static const TimeValue kExitGenoPoint = 62560;
// Death start and end points.
static const TimeValue kDeath1Start = 0;
static const TimeValue kDeath1End = 2400;
static const TimeValue kDeath2Start = kDeath1End;
static const TimeValue kDeath2End = 4720;
static const TimeValue kDeath3Start = kDeath2End;
static const TimeValue kDeath3End = 7120;
static const TimeValue kDeath4Start = kDeath3End;
static const TimeValue kDeath4End = 9280;
static const TimeValue kDeath5Start = kDeath4End;
static const TimeValue kDeath5End = 12000;
// Chase state.
enum {
kCanyonLaunch,
kCanyonBranch1Left,
kCanyonBranch1Right,
kCanyonBranch2Left,
kCanyonBranch2Right,
kCanyonBranch3Left,
kCanyonBranch4Left,
kCanyonBranch4Right,
kCanyonBranch5Left,
kCanyonBranch5Right,
kCanyonExit,
kCanyonLoop
};
void MusicTimerEvent::fire() {
canyonChase->musicTimerExpired(*this);
}
CanyonChase::CanyonChase(Neighborhood *handler) : ChaseInteraction(kMarsCanyonChaseInteractionID, handler,
kMarsCanyonChaseNotificationID, g_vm), _canyonMovie1(kNoDisplayElement),
_canyonMovie2(kNoDisplayElement), _deathMovie(kNoDisplayElement), _genoMovie(kNoDisplayElement) {
_currentMovie = nullptr;
_currentCallBack = nullptr;
}
void CanyonChase::setSoundFXLevel(const uint16 fxLevel) {
_canyonMovie1.setVolume(fxLevel);
_canyonMovie2.setVolume(fxLevel);
_deathMovie.setVolume(fxLevel);
}
void CanyonChase::setAmbienceLevel(const uint16 level) {
_genoMovie.setVolume(level);
_musicFader.setMasterVolume(level);
}
void CanyonChase::startCanyonMusicLoop(void) {
FaderMoveSpec spec;
_musicLoop.loopSound();
spec.makeTwoKnotFaderSpec(10, 0, 0, 1, 255);
_musicFader.startFader(spec);
}
void CanyonChase::stopCanyonMusicLoop(const long ticks) {
FaderMoveSpec spec;
spec.makeTwoKnotFaderSpec(10, 0, 255, ticks, 0);
_musicFader.startFader(spec);
}
void CanyonChase::openInteraction() {
_canyonMovie1.initFromMovieFile("Images/Mars/Canyon_hq1.mov");
_canyonMovie1.setVolume(g_vm->getSoundFXLevel());
_canyonMovie1.moveElementTo(kShuttleWindowLeft, kShuttleWindowTop);
_canyonMovie1.setDisplayOrder(kShuttleMonitorOrder);
_canyon1CallBack.setNotification(&_chaseNotification);
_canyon1CallBack.initCallBack(&_canyonMovie1, kCallBackAtExtremes);
_canyon1CallBack.setCallBackFlag(kChaseEnteredBranchZone);
_canyon1CallBack.scheduleCallBack(kTriggerAtStop, 0, 0);
_canyonMovie2.initFromMovieFile("Images/Mars/Canyon_hq2.mov");
_canyonMovie2.setVolume(g_vm->getSoundFXLevel());
_canyonMovie2.moveElementTo(kShuttleWindowLeft, kShuttleWindowTop);
_canyonMovie2.setDisplayOrder(kShuttleMonitorOrder);
_canyon2CallBack.setNotification(&_chaseNotification);
_canyon2CallBack.initCallBack(&_canyonMovie2, kCallBackAtExtremes);
_canyon2CallBack.setCallBackFlag(kChaseEnteredBranchZone);
_canyon2CallBack.scheduleCallBack(kTriggerAtStop, 0, 0);
_deathMovie.initFromMovieFile("Images/Mars/Canyon_hqD.mov");
_deathMovie.setVolume(g_vm->getSoundFXLevel());
_deathMovie.moveElementTo(kShuttleWindowLeft, kShuttleWindowTop);
_deathMovie.setDisplayOrder(kShuttleMonitorOrder);
_deathCallBack.setNotification(&_chaseNotification);
_deathCallBack.initCallBack(&_deathMovie, kCallBackAtExtremes);
_deathCallBack.setCallBackFlag(kChaseFinished);
_deathCallBack.scheduleCallBack(kTriggerAtStop, 0, 0);
_musicLoop.attachFader(&_musicFader);
_musicLoop.initFromAIFFFile("Sounds/Mars/Canyon Loop.44K.16.AIFF");
_musicFader.setMasterVolume(g_vm->getAmbienceLevel());
ChaseInteraction::openInteraction();
_steerPict.setDisplayOrder(kShuttleMonitorOrder + 1);
_steerPict.moveElementTo(kShuttleSteerLeft, kShuttleSteerTop);
}
void CanyonChase::initInteraction() {
_steerPict.startDisplaying();
// Launch branch is identical in both movies
_canyonState = kCanyonLaunch;
_canyonMovie1.setSegment(kLaunchStart, kLaunchEnd - kDecisionTime);
_canyonMovie1.setTime(kLaunchStart);
switchTo(_canyonMovie1, _canyon1CallBack);
startCanyonMusicLoop();
ChaseInteraction::initInteraction();
}
void CanyonChase::closeInteraction() {
_canyonMovie1.stop();
_canyonMovie1.stopDisplaying();
_canyonMovie1.releaseMovie();
_canyon1CallBack.releaseCallBack();
_canyonMovie2.stop();
_canyonMovie2.stopDisplaying();
_canyonMovie2.releaseMovie();
_canyon2CallBack.releaseCallBack();
_deathMovie.stop();
_deathMovie.stopDisplaying();
_deathMovie.releaseMovie();
_deathCallBack.releaseCallBack();
_genoMovie.stop();
_genoMovie.stopDisplaying();
_genoMovie.releaseMovie();
_genoCallBack.releaseCallBack();
ChaseInteraction::closeInteraction();
}
void CanyonChase::receiveNotification(Notification *notification, const NotificationFlags flags) {
Input input;
if (notification == &_chaseNotification && flags == kChaseFinished) {
if (_canyonState == kCanyonLoop) {
// Swallow the notification if we loop back to the beginning
InputDevice.getInput(input, kFilterAllInput);
if (JMPPPInput::isEasterEggModifierInput(input)) {
stopCanyonMusicLoop(15);
doGenoChase();
} else {
_canyonMovie2.setSegment(kExitGenoPoint, kExitLoopPoint - kDecisionTime);
_canyonMovie2.setTime(kExitGenoPoint);
switchTo(_canyonMovie2, _canyon2CallBack);
_canyon2CallBack.setCallBackFlag(kChaseEnteredBranchZone);
_canyon2CallBack.scheduleCallBack(kTriggerAtStop, 0, 0);
_canyonState = kCanyonLaunch;
}
return;
} else if (_canyonState != kCanyonExit) {
// We died
((Mars *)_owner)->die(kDeathRanIntoCanyonWall);
}
}
ChaseInteraction::receiveNotification(notification, flags);
}
void CanyonChase::setUpBranch() {
TimeValue branchStart, branchEnd;
branchStart = 0;
branchEnd = 0;
switch (_canyonState) {
case kCanyonLaunch:
case kCanyonExit:
branchStart = kLaunchEnd - kDecisionTime;
branchEnd = kLaunchEnd;
break;
case kCanyonBranch1Left:
case kCanyonBranch1Right:
branchStart = kBranch1End - kDecisionTime;
branchEnd = kBranch1End;
break;
case kCanyonBranch2Left:
case kCanyonBranch2Right:
branchStart = kBranch2End - kDecisionTime;
branchEnd = kBranch2End;
break;
case kCanyonBranch3Left:
branchStart = kBranch3End - kDecisionTime;
branchEnd = kBranch3End;
break;
case kCanyonBranch4Left:
case kCanyonBranch4Right:
branchStart = kBranch4End - kDecisionTime;
branchEnd = kBranch4End;
break;
case kCanyonBranch5Left:
case kCanyonBranch5Right:
branchStart = kBranch5End - kDecisionTime;
branchEnd = kBranch5End;
break;
default:
break;
}
_currentMovie->setSegment(branchStart, branchEnd);
// Need to call SetTime here in case we loop
_currentMovie->setTime(branchStart);
_currentCallBack->setCallBackFlag(kChaseExitedBranchZone);
_currentCallBack->scheduleCallBack(kTriggerAtStop, 0, 0);
}
void CanyonChase::branchLeft() {
TimeValue branchStart, branchEnd;
Movie *movie;
NotificationCallBack *callBack;
branchStart = 0;
branchEnd = 0;
switch (_canyonState) {
case kCanyonLaunch:
branchStart = kBranch1Start;
branchEnd = kBranch1End - kDecisionTime;
_canyonState = kCanyonBranch1Left;
break;
case kCanyonBranch1Left:
case kCanyonBranch1Right:
branchStart = kBranch2Start;
branchEnd = kBranch2End - kDecisionTime;
_canyonState = kCanyonBranch2Left;
break;
case kCanyonBranch2Left:
case kCanyonBranch2Right:
branchStart = kBranch3Start;
branchEnd = kBranch3End - kDecisionTime;
_canyonState = kCanyonBranch3Left;
break;
case kCanyonBranch3Left:
branchStart = kBranch4Start;
branchEnd = kBranch4End - kDecisionTime;
_canyonState = kCanyonBranch4Left;
break;
case kCanyonBranch4Left:
case kCanyonBranch4Right:
branchStart = kBranch5Start;
branchEnd = kBranch5End - kDecisionTime;
_canyonState = kCanyonBranch5Left;
break;
case kCanyonBranch5Left:
case kCanyonBranch5Right:
dontBranch();
return;
default:
break;
}
// Left branches are in hq2 (except exit)
// Segment 5 branches are switched
if (_canyonState == kCanyonBranch5Left || _canyonState == kCanyonBranch5Right) {
movie = &_canyonMovie1;
callBack = &_canyon1CallBack;
} else {
movie = &_canyonMovie2;
callBack = &_canyon2CallBack;
}
movie->setSegment(branchStart, branchEnd);
movie->setTime(branchStart);
switchTo(*movie, *callBack);
callBack->setCallBackFlag(kChaseEnteredBranchZone);
callBack->scheduleCallBack(kTriggerAtStop, 0, 0);
}
void CanyonChase::branchRight() {
TimeValue branchStart, branchEnd;
NotificationFlags flag;
Movie *movie;
NotificationCallBack *callBack;
branchStart = 0;
branchEnd = 0;
flag = 0;
switch (_canyonState) {
case kCanyonLaunch:
branchStart = kBranch1Start;
branchEnd = kBranch1End - kDecisionTime;
_canyonState = kCanyonBranch1Right;
flag = kChaseEnteredBranchZone;
break;
case kCanyonBranch1Left:
case kCanyonBranch1Right:
branchStart = kBranch2Start;
branchEnd = kBranch2End - kDecisionTime;
_canyonState = kCanyonBranch2Right;
flag = kChaseEnteredBranchZone;
break;
case kCanyonBranch2Left:
case kCanyonBranch2Right:
dontBranch();
return;
case kCanyonBranch3Left:
branchStart = kBranch4Start;
branchEnd = kBranch4End - kDecisionTime;
_canyonState = kCanyonBranch4Right;
flag = kChaseEnteredBranchZone;
break;
case kCanyonBranch4Left:
case kCanyonBranch4Right:
branchStart = kBranch5Start;
branchEnd = kBranch5End - kDecisionTime;
_canyonState = kCanyonBranch5Right;
flag = kChaseEnteredBranchZone;
break;
case kCanyonBranch5Left:
case kCanyonBranch5Right:
// Exit loop branch is in hq2
branchStart = kExitStart;
branchEnd = kExitEnd;
_canyonState = kCanyonExit;
flag = kChaseFinished;
startMusicTimer(kCanyonChaseStart + kCanyonChaseExitedTime - kExitStart, kMovieTicksPerSecond,
kCanyonExited);
break;
default:
break;
}
// Right branches are in hq1 (except exit)
// Segment 5 branches are switched
if (_canyonState == kCanyonBranch5Left || _canyonState == kCanyonBranch5Right) {
movie = &_canyonMovie2;
callBack = &_canyon2CallBack;
} else {
movie = &_canyonMovie1;
callBack = &_canyon1CallBack;
}
movie->setSegment(branchStart, branchEnd);
movie->setTime(branchStart);
switchTo(*movie, *callBack);
callBack->setCallBackFlag(flag);
callBack->scheduleCallBack(kTriggerAtStop, 0, 0);
}
void CanyonChase::dontBranch() {
TimeValue branchStart, branchEnd;
branchStart = 0;
branchEnd = 0;
switch (_canyonState) {
case kCanyonLaunch:
branchStart = kDeath1Start;
branchEnd = kDeath1End;
break;
case kCanyonBranch1Left:
case kCanyonBranch1Right:
branchStart = kDeath2Start;
branchEnd = kDeath2End;
break;
case kCanyonBranch2Left:
case kCanyonBranch2Right:
branchStart = kDeath3Start;
branchEnd = kDeath3End;
break;
case kCanyonBranch3Left:
branchStart = kDeath4Start;
branchEnd = kDeath4End;
break;
case kCanyonBranch4Left:
case kCanyonBranch4Right:
branchStart = kDeath5Start;
branchEnd = kDeath5End;
break;
case kCanyonBranch5Left:
case kCanyonBranch5Right:
_canyonMovie2.setSegment(kExitStart, kExitGenoPoint);
_canyonMovie2.setTime(kExitStart);
switchTo(_canyonMovie2, _canyon2CallBack);
_canyon2CallBack.setCallBackFlag(kChaseFinished);
_canyon2CallBack.scheduleCallBack(kTriggerAtStop, 0, 0);
_canyonState = kCanyonLoop;
return;
default:
break;
}
_deathMovie.setSegment(branchStart, branchEnd);
_deathMovie.setTime(branchStart);
switchTo(_deathMovie, _deathCallBack);
startMusicTimer(10, 10, kCanyonRanIntoWall);
}
void CanyonChase::showControlsHint() {
((Mars *)_owner)->_lowerLeftShuttleMovie.setTime(kShuttleLowerLeftKeypadHintTime);
((Mars *)_owner)->_lowerLeftShuttleMovie.redrawMovieWorld();
ChaseInteraction::showControlsHint();
}
void CanyonChase::hideControlsHint() {
((Mars *)_owner)->_lowerLeftShuttleMovie.setTime(kShuttleLowerLeftCollisionTime);
((Mars *)_owner)->_lowerLeftShuttleMovie.redrawMovieWorld();
ChaseInteraction::hideControlsHint();
}
void CanyonChase::switchTo(Movie &movie, NotificationCallBack &callBack) {
if (_currentMovie != &movie) {
if (_currentMovie != nullptr) {
_currentMovie->stop();
_currentMovie->hide();
_currentMovie->stopDisplaying();
}
_currentMovie = &movie;
_currentMovie->startDisplaying();
_currentMovie->show();
_currentMovie->start();
}
if (_currentCallBack != &callBack) {
_currentCallBack = &callBack;
}
}
void CanyonChase::startMusicTimer(TimeValue time, TimeScale scale, MusicTimerCode code) {
_musicFuse.primeFuse(time, scale);
_musicEvent.canyonChase = this;
_musicEvent.theEvent = code;
_musicFuse.setFunctor(new Common::Functor0Mem<void, MusicTimerEvent>(&_musicEvent, &MusicTimerEvent::fire));
_musicFuse.lightFuse();
}
void CanyonChase::musicTimerExpired(MusicTimerEvent &event) {
FaderMoveSpec spec;
switch (event.theEvent) {
case kCanyonRanIntoWall:
stopCanyonMusicLoop(5);
break;
case kCanyonExited:
spec.makeTwoKnotFaderSpec(20, 0, 255, 5, 160);
_musicFader.startFader(spec);
startMusicTimer(kCanyonChaseFadedTime, kMovieTicksPerSecond, kCanyonFaded);
break;
case kCanyonFaded:
spec.makeTwoKnotFaderSpec(10, 0, 160, 30, 0);
_musicFader.startFader(spec);
((Mars *)_owner)->startMarsTimer(kLaunchTubeDVDReachedTime, kMovieTicksPerSecond,
kMarsLaunchTubeReached);
break;
default:
break;
}
}
void CanyonChase::doGenoChase() {
_genoMovie.initFromMovieFile("Images/Mars/Canyon_hqG.mov");
_genoMovie.setVolume(g_vm->getAmbienceLevel());
_genoMovie.moveElementTo(kShuttleWindowLeft, kShuttleWindowTop);
_genoMovie.setDisplayOrder(kShuttleMonitorOrder);
_genoMovie.startDisplaying();
_genoMovie.show();
_genoMovie.start();
_genoCallBack.setNotification(&_chaseNotification);
_genoCallBack.initCallBack(&_genoMovie, kCallBackAtExtremes);
_genoCallBack.setCallBackFlag(kChaseFinished);
_genoCallBack.scheduleCallBack(kTriggerAtStop, 0, 0);
_canyonState = kCanyonExit;
((Mars *)_owner)->startMarsTimer(_genoMovie.getDuration() - 5 * kMovieTicksPerSecond,
kMovieTicksPerSecond, kMarsLaunchTubeReached);
}
} // End of namespace Pegasus

View File

@@ -0,0 +1,107 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* Additional copyright for this file:
* Copyright (C) 1995-2013 Presto Studios, Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef PEGASUS_NEIGHBORHOOD_MARS_CANYONCHASE_H
#define PEGASUS_NEIGHBORHOOD_MARS_CANYONCHASE_H
#include "pegasus/chase.h"
#include "pegasus/fader.h"
#include "pegasus/movie.h"
#include "pegasus/sound.h"
namespace Pegasus {
class CanyonChase;
class Mars;
enum MusicTimerCode {
kCanyonRanIntoWall,
kCanyonExited,
kCanyonFaded
};
struct MusicTimerEvent {
CanyonChase *canyonChase;
MusicTimerCode theEvent;
void fire();
};
class CanyonChase : public ChaseInteraction {
friend class Mars;
friend struct MusicTimerEvent;
public:
CanyonChase(Neighborhood *);
virtual ~CanyonChase() {}
void setSoundFXLevel(const uint16);
void setAmbienceLevel(const uint16);
protected:
void startCanyonMusicLoop();
void stopCanyonMusicLoop(const long);
void openInteraction();
void initInteraction();
void closeInteraction();
void receiveNotification(Notification *, const NotificationFlags);
void setUpBranch();
void branchLeft();
void branchRight();
void dontBranch();
void showControlsHint();
void hideControlsHint();
void switchTo(Movie &, NotificationCallBack &);
void startMusicTimer(TimeValue, TimeScale, MusicTimerCode);
void musicTimerExpired(MusicTimerEvent &);
void doGenoChase();
Movie _canyonMovie1;
Movie _canyonMovie2;
Movie _deathMovie;
Movie _genoMovie;
NotificationCallBack _canyon1CallBack;
NotificationCallBack _canyon2CallBack;
NotificationCallBack _deathCallBack;
NotificationCallBack _genoCallBack;
Sound _musicLoop;
SoundFader _musicFader;
FuseFunction _musicFuse;
MusicTimerEvent _musicEvent;
Movie *_currentMovie;
NotificationCallBack *_currentCallBack;
short _canyonState;
};
} // End of namespace Pegasus
#endif

View File

@@ -0,0 +1,966 @@
/* 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 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef PEGASUS_NEIGHBORHOOD_MARS_CONSTANTS_H
#define PEGASUS_NEIGHBORHOOD_MARS_CONSTANTS_H
#include "pegasus/constants.h"
namespace Pegasus {
// Element Coordinates
static const CoordType kPodScreenLeft = kNavAreaLeft + 88;
static const CoordType kPodScreenTop = kNavAreaTop + 204;
static const CoordType kPodSteerLeft = kNavAreaLeft + 212;
static const CoordType kPodSteerTop = kNavAreaTop + 232;
static const CoordType kUndoHiliteLeft = kNavAreaLeft + 140;
static const CoordType kUndoHiliteTop = kNavAreaTop + 36;
static const CoordType kCurrentGuessLeft = kNavAreaLeft + 146;
static const CoordType kCurrentGuessTop = kNavAreaTop + 90;
static const CoordType kReactorChoiceHiliteLeft = kNavAreaLeft + 116;
static const CoordType kReactorChoiceHiliteTop = kNavAreaTop + 158;
static const CoordType kReactorHistoryLeft = kNavAreaLeft + 302;
static const CoordType kReactorHistoryTop = kNavAreaTop + 39;
static const CoordType kAnswerLeft = kNavAreaLeft + 304;
static const CoordType kAnswerTop = kNavAreaTop + 180;
static const CoordType kShuttle1Left = 0;
static const CoordType kShuttle1Top = 0;
static const CoordType kShuttle2Left = 0;
static const CoordType kShuttle2Top = 96;
static const CoordType kShuttle3Left = 500;
static const CoordType kShuttle3Top = 96;
static const CoordType kShuttle4Left = 0;
static const CoordType kShuttle4Top = 320;
static const CoordType kShuttleWindowLeft = 140;
static const CoordType kShuttleWindowTop = 96;
static const CoordType kShuttleWindowWidth = 360;
static const CoordType kShuttleWindowHeight = 224;
static const CoordType kShuttleWindowMidH = (kShuttleWindowLeft * 2 + kShuttleWindowWidth) / 2;
static const CoordType kShuttleWindowMidV = (kShuttleWindowTop * 2 + kShuttleWindowHeight) / 2;
static const CoordType kShuttleLeftLeft = 0;
static const CoordType kShuttleLeftTop = 128;
static const CoordType kShuttleRightLeft = 506;
static const CoordType kShuttleRightTop = 128;
static const CoordType kShuttleLowerLeftLeft = 74;
static const CoordType kShuttleLowerLeftTop = 358;
static const CoordType kShuttleLowerRightLeft = 486;
static const CoordType kShuttleLowerRightTop = 354;
static const CoordType kShuttleCenterLeft = 260;
static const CoordType kShuttleCenterTop = 336;
static const CoordType kShuttleUpperLeftLeft = 30;
static const CoordType kShuttleUpperLeftTop = 32;
static const CoordType kShuttleUpperRightLeft = 506;
static const CoordType kShuttleUpperRightTop = 52;
static const CoordType kShuttleLeftEnergyLeft = 110;
static const CoordType kShuttleLeftEnergyTop = 186;
static const CoordType kShuttleRightEnergyLeft = 510;
static const CoordType kShuttleRightEnergyTop = 186;
static const CoordType kShuttleEnergyLeft = 186;
static const CoordType kShuttleEnergyTop = 60;
static const CoordType kShuttleEnergyWidth = 252;
static const CoordType kShuttleEnergyHeight = 22;
static const CoordType kShuttleSteerLeft = kShuttleWindowLeft + 136;
static const CoordType kShuttleSteerTop = kShuttleWindowTop + 196;
static const CoordType kPlanetStartLeft = kShuttleWindowLeft;
static const CoordType kPlanetStartTop = kShuttleWindowTop + kShuttleWindowHeight;
static const CoordType kPlanetStopLeft = kShuttleWindowLeft;
static const CoordType kPlanetStopTop = kShuttleWindowTop + kShuttleWindowHeight - 100;
static const CoordType kShuttleTractorLeft = kShuttleWindowLeft + 6;
static const CoordType kShuttleTractorTop = kShuttleWindowTop + 56;
static const CoordType kShuttleTractorWidth = 348;
static const CoordType kShuttleTractorHeight = 112;
static const CoordType kShuttleJunkLeft = kShuttleWindowLeft + 6;
static const CoordType kShuttleJunkTop = kShuttleWindowTop + 6;
static const DisplayOrder kShuttlePlanetOrder = kInterfaceLayer;
static const DisplayOrder kShuttleAlienShipOrder = kShuttlePlanetOrder + 1;
static const DisplayOrder kShuttleRobotShipOrder = kShuttleAlienShipOrder + 1;
static const DisplayOrder kShuttleTractorBeamMovieOrder = kShuttleRobotShipOrder + 1;
static const DisplayOrder kShuttleWeaponBackOrder = kShuttleTractorBeamMovieOrder + 1;
static const DisplayOrder kShuttleJunkOrder = kShuttleWeaponBackOrder + 1;
static const DisplayOrder kShuttleWeaponFrontOrder = kShuttleJunkOrder + 1;
static const DisplayOrder kShuttleTractorBeamOrder = kShuttleWeaponFrontOrder + 1;
static const DisplayOrder kShuttleHUDOrder = kShuttleTractorBeamOrder + 1;
static const DisplayOrder kShuttleBackgroundOrder = kShuttleHUDOrder + 1;
static const DisplayOrder kShuttleMonitorOrder = kShuttleBackgroundOrder + 1;
static const DisplayOrder kShuttleStatusOrder = kShuttleMonitorOrder + 1;
static const TimeValue kShuttleSwingStart = 0;
static const TimeValue kShuttleSwingStop = 5 * 600;
static const TimeValue kCanyonChaseStart = kShuttleSwingStop;
static const TimeValue kCanyonChaseCDStop = 60 * 600 + 43 * 600 + 14 * 40;
static const TimeValue kCanyonChaseDVDStop = 60 * 600 + 50 * 600 + 12 * 40;
static const TimeValue kCanyonChaseExitedTime = 60 * 600 + 40 * 600 + 13 * 40 - kCanyonChaseStart;
static const TimeValue kCanyonChaseFadedTime = 60 * 600 + 43 * 600 + 6 * 40 - kCanyonChaseStart -
kCanyonChaseExitedTime;
static const TimeValue kLaunchTubeCDReachedTime = 60 * 600 + 38 * 600 - kCanyonChaseStart;
static const TimeValue kLaunchTubeDVDReachedTime = 60 * 600 + 45 * 600 - kCanyonChaseStart -
kCanyonChaseExitedTime - kCanyonChaseFadedTime;
static const TimeValue kCanyonChaseCDFinishedTime = kCanyonChaseCDStop - kCanyonChaseStart -
kLaunchTubeCDReachedTime;
static const TimeValue kCanyonChaseDVDFinishedTime = kCanyonChaseDVDStop - kCanyonChaseStart -
kCanyonChaseExitedTime - kCanyonChaseFadedTime -
kLaunchTubeDVDReachedTime;
// Left shuttle.
static const TimeValue kShuttleLeftIntroStart = 0;
static const TimeValue kShuttleLeftIntroStop = 400;
static const TimeValue kShuttleLeftBlankTime = 400;
static const TimeValue kShuttleLeftNormalTime = 440;
static const TimeValue kShuttleLeftAutoTestTime = 480;
static const TimeValue kShuttleLeftDamagedTime = 520;
static const TimeValue kShuttleLeftDampingTime = 560;
static const TimeValue kShuttleLeftGravitonTime = 600;
static const TimeValue kShuttleLeftTractorTime = 640;
// Right shuttle.
static const TimeValue kShuttleRightIntroStart = 0;
static const TimeValue kShuttleRightIntroStop = 400;
static const TimeValue kShuttleRightDestroyedStart = 400;
static const TimeValue kShuttleRightDestroyedStop = 840;
static const TimeValue kShuttleRightBlankTime = 840;
static const TimeValue kShuttleRightNormalTime = 880;
static const TimeValue kShuttleRightDamagedTime = 920;
static const TimeValue kShuttleRightTargetLockTime = 960;
static const TimeValue kShuttleRightGravitonTime = 1000;
static const TimeValue kShuttleRightOverloadTime = 1040;
// Lower Left shuttle.
static const TimeValue kShuttleLowerLeftCollisionTime = 0;
static const TimeValue kShuttleLowerLeftTubeTime = 40;
static const TimeValue kShuttleLowerLeftAutopilotTime = 80;
static const TimeValue kShuttleLowerLeftKeypadHintTime = 120;
// Lower Right shuttle.
static const TimeValue kShuttleLowerRightOffTime = 0;
static const TimeValue kShuttleLowerRightTrackingTime = 40;
static const TimeValue kShuttleLowerRightTransportTime = 80;
static const TimeValue kShuttleLowerRightTransportHiliteTime = 120;
// Center shuttle.
static const TimeValue kShuttleCenterBoardingTime = 0;
static const TimeValue kShuttleCenterCheckTime = 40;
static const TimeValue kShuttleCenterNavCompTime = 80;
static const TimeValue kShuttleCenterCommTime = 120;
static const TimeValue kShuttleCenterWeaponsTime = 160;
static const TimeValue kShuttleCenterAllSystemsTime = 200;
static const TimeValue kShuttleCenterSecureLooseTime = 240;
static const TimeValue kShuttleCenterAutoTestTime = 280;
static const TimeValue kShuttleCenterLaunchTime = 320;
static const TimeValue kShuttleCenterEnterTubeTime = 360;
static const TimeValue kShuttleCenterTargetSightedTime = 400;
static const TimeValue kShuttleCenterVerifyingTime = 440;
static const TimeValue kShuttleCenterScanningTime = 480;
static const TimeValue kShuttleCenterSafeTime = 520;
// Upper Left shuttle.
static const TimeValue kShuttleUpperLeftDimTime = 0;
static const TimeValue kShuttleUpperLeftDampingTime = 40;
static const TimeValue kShuttleUpperLeftGravitonTime = 80;
static const TimeValue kShuttleUpperLeftTractorTime = 120;
// Upper Right shuttle.
static const TimeValue kShuttleUpperRightLockedTime = 0;
static const TimeValue kShuttleUpperRightArmedTime = 40;
static const TimeValue kShuttleUpperRightAlienDestroyedTime = 80;
static const TimeValue kShuttleUpperRightOverloadTime = 120;
static const TimeValue kShuttleUpperRightTargetDestroyedTime = 160;
// Shuttle distance
static const int kShuttleDistance = 500;
static const int kJunkMaxDistance = kShuttleDistance;
static const int kJunkMinDistance = 40;
static const int kEnergyBeamMaxDistance = kShuttleDistance;
static const int kEnergyBeamMinDistance = 40;
static const int kGravitonMaxDistance = kShuttleDistance;
static const int kGravitonMinDistance = 40;
static const TimeValue kMarsOxyMaskOnIn = 0;
static const TimeValue kMarsOxyMaskOnOut = 1560;
static const TimeValue kMarsAirlockButtonBeepIn = 1560;
static const TimeValue kMarsAirlockButtonBeepOut = 1620;
static const TimeValue kMarsColorMatchingButtonBeepIn = 1620;
static const TimeValue kMarsColorMatchingButtonBeepOut = 1680;
static const TimeValue kMarsKioskBeepIn = 1680;
static const TimeValue kMarsKioskBeepOut = 1740;
static const TimeValue kMarsBumpIntoWallIn = 1740;
static const TimeValue kMarsBumpIntoWallOut = 1888;
static const TimeValue kMarsGantryDoorCloseIn = 1888;
static const TimeValue kMarsGantryDoorCloseOut = 2866;
static const TimeValue kMarsTransportDoorCloseIn = 2866;
static const TimeValue kMarsTransportDoorCloseOut = 3593;
static const TimeValue kMarsAirlockPressurizeIn = 3593;
static const TimeValue kMarsAirlockPressurizeOut = 4766;
static const TimeValue kMarsBigAirlockDoorCloseIn = 4766;
static const TimeValue kMarsBigAirlockDoorCloseOut = 7872;
static const TimeValue kMarsSmallAirlockDoorCloseIn = 7872;
static const TimeValue kMarsSmallAirlockDoorCloseOut = 10000;
static const TimeValue kMarsMazeDoorCloseIn = 10000;
static const TimeValue kMarsMazeDoorCloseOut = 10969;
static const TimeValue kMarsRobotTakesTransportIn = 10969;
static const TimeValue kMarsRobotTakesTransportOut = 12802;
static const TimeValue kMarsPodDepartedUpperPlatformIn = 12802;
static const TimeValue kMarsPodDepartedUpperPlatformOut = 15783;
static const TimeValue kMarsPodDepartedLowerPlatformIn = 15783;
static const TimeValue kMarsPodDepartedLowerPlatformOut = 18736;
static const TimeValue kMarsPodArrivedUpperPlatformIn = 18736;
static const TimeValue kMarsPodArrivedUpperPlatformOut = 21605;
static const TimeValue kMarsCheckInRequiredIn = 21605;
static const TimeValue kMarsCheckInRequiredOut = 27463;
static const TimeValue kMarsCantOpenShuttleIn = 27463;
static const TimeValue kMarsCantOpenShuttleOut = 29214;
static const TimeValue kMarsShuttleLockOverrideIn = 29214;
static const TimeValue kMarsShuttleLockOverrideOut = 30330;
static const TimeValue kMarsNoShuttleIn = 30330;
static const TimeValue kMarsNoShuttleOut = 31502;
static const TimeValue kMustBeUnlockedIn = 31502;
static const TimeValue kMustBeUnlockedOut = 33960;
static const TimeValue kColorMatchBlueIn = 33960;
static const TimeValue kColorMatchBlueOut = 34240;
static const TimeValue kColorMatchRedIn = 34240;
static const TimeValue kColorMatchRedOut = 34538;
static const TimeValue kColorMatchGreenIn = 34538;
static const TimeValue kColorMatchGreenOut = 34827;
static const TimeValue kColorMatchYellowIn = 34827;
static const TimeValue kColorMatchYellowOut = 35162;
static const TimeValue kColorMatchPurpleIn = 35162;
static const TimeValue kColorMatchPurpleOut = 35426;
static const TimeValue kColorMatchZeroNodesIn = 35426;
static const TimeValue kColorMatchZeroNodesOut = 36376;
static const TimeValue kColorMatchOneNodeIn = 36376;
static const TimeValue kColorMatchOneNodeOut = 37209;
static const TimeValue kColorMatchTwoNodesIn = 37209;
static const TimeValue kColorMatchTwoNodesOut = 37983;
static const TimeValue kColorMatchThreeNodesIn = 37983;
static const TimeValue kColorMatchThreeNodesOut = 38784;
static const TimeValue kMarsShuttle1DepartedIn = 38784;
static const TimeValue kMarsShuttle1DepartedOut = 40323;
static const TimeValue kMarsShuttle2DepartedIn = 40323;
static const TimeValue kMarsShuttle2DepartedOut = 41824;
static const TimeValue kShuttleCockpitIn = 41824;
static const TimeValue kShuttleCockpitOut = 43126;
static const TimeValue kShuttleOnboardIn = 43126;
static const TimeValue kShuttleOnboardOut = 44284;
static const TimeValue kShuttleNavigationIn = 44284;
static const TimeValue kShuttleNavigationOut = 46049;
static const TimeValue kShuttleCommunicationIn = 46049;
static const TimeValue kShuttleCommunicationOut = 47288;
static const TimeValue kShuttleAutoTestingIn = 47288;
static const TimeValue kShuttleAutoTestingOut = 48179;
static const TimeValue kMarsThrusterAutoTestIn = 48179;
static const TimeValue kMarsThrusterAutoTestOut = 49979;
static const TimeValue kShuttleAllSystemsIn = 49979;
static const TimeValue kShuttleAllSystemsOut = 51065;
static const TimeValue kShuttleSecureLooseIn = 51065;
static const TimeValue kShuttleSecureLooseOut = 52346;
static const TimeValue kShuttlePrepareForDropIn = 52346;
static const TimeValue kShuttlePrepareForDropOut = 53216;
static const TimeValue kShuttleAllClearIn = 53216;
static const TimeValue kShuttleAllClearOut = 54031;
static const TimeValue kShuttleConfiguringIn = 54031;
static const TimeValue kShuttleConfiguringOut = 54994;
static const TimeValue kShuttleGeneratingIn = 54994;
static const TimeValue kShuttleGeneratingOut = 56033;
static const TimeValue kShuttleBreakawayIn = 56033;
static const TimeValue kShuttleBreakawayOut = 57346;
static const TimeValue kMarsAtmosphericBreakawayIn = 57346;
static const TimeValue kMarsAtmosphericBreakawayOut = 59237;
static const TimeValue kMarsCockpitChatterIn = 59237;
static const TimeValue kMarsCockpitChatterOut = 70344;
static const TimeValue kShuttleDamperDescIn = 70344;
static const TimeValue kShuttleDamperDescOut = 73262;
static const TimeValue kShuttleGravitonDescIn = 73262;
static const TimeValue kShuttleGravitonDescOut = 75296;
static const TimeValue kShuttleTractorDescIn = 75296;
static const TimeValue kShuttleTractorDescOut = 78381;
static const TimeValue kShuttleTargetSightedIn = 78381;
static const TimeValue kShuttleTargetSightedOut = 79074;
static const TimeValue kShuttleAutopilotEngagedIn = 79074;
static const TimeValue kShuttleAutopilotEngagedOut = 80414;
static const TimeValue kMarsEDBBlastIn = 80414;
static const TimeValue kMarsEDBBlastOut = 80705;
static const TimeValue kMarsGravitonBlastIn = 80705;
static const TimeValue kMarsGravitonBlastOut = 81199;
static const TimeValue kMarsJunkCollisionIn = 81199;
static const TimeValue kMarsJunkCollisionOut = 81961;
static const TimeValue kShuttleGravitonIn = 81961;
static const TimeValue kShuttleGravitonOut = 82587;
static const TimeValue kShuttleDampingBeamIn = 82587;
static const TimeValue kShuttleDampingBeamOut = 83331;
static const TimeValue kShuttleTractorBeamIn = 83331;
static const TimeValue kShuttleTractorBeamOut = 83802;
static const TimeValue kShuttleHullBreachIn = 83802;
static const TimeValue kShuttleHullBreachOut = 84721;
static const TimeValue kShuttleWingDamageIn = 84721;
static const TimeValue kShuttleWingDamageOut = 85640;
static const TimeValue kShuttleHullDamageIn = 85640;
static const TimeValue kShuttleHullDamageOut = 86513;
static const TimeValue kShuttleEnergyTooLowIn = 86513;
static const TimeValue kShuttleEnergyTooLowOut = 87578;
static const TimeValue kShuttleTractorLimitedIn = 87578;
static const TimeValue kShuttleTractorLimitedOut = 89164;
static const TimeValue kShuttleCantHoldIn = 89164;
static const TimeValue kShuttleCantHoldOut = 90945;
static const TimeValue kShuttleBrokeFreeIn = 90945;
static const TimeValue kShuttleBrokeFreeOut = 92322;
static const TimeValue kShuttleDestroyedIn = 92322;
static const TimeValue kShuttleDestroyedOut = 93189;
static const TimeValue kShuttleCoordinatesIn = 93189;
static const TimeValue kShuttleCoordinatesOut = 94018;
static const TimeValue kShuttleScanningIn = 94018;
static const TimeValue kShuttleScanningOut = 94975;
static const TimeValue kShuttleSafeIn = 94975;
static const TimeValue kShuttleSafeOut = 96176;
static const TimeValue kShuttleOverloadedIn = 96176;
static const TimeValue kShuttleOverloadedOut = 101308;
static const TimeScale kMarsMovieScale = 600;
static const TimeScale kMarsFramesPerSecond = 15;
static const TimeScale kMarsFrameDuration = 40;
// Alternate IDs.
static const AlternateID kAltMarsNormal = 0;
static const AlternateID kAltMarsPodAtMars34 = 1;
static const AlternateID kAltMarsTookCard = 2;
static const AlternateID kAltMars35AirlockEast = 3;
static const AlternateID kAltMars35AirlockWest = 4;
static const AlternateID kAltMarsPodAtMars45 = 5;
static const AlternateID kAltMarsTookMask = 6;
static const AlternateID kAltMarsMaskOnFiller = 7;
static const AlternateID kAltMars60AirlockEast = 8;
static const AlternateID kAltMars60AirlockWest = 9;
// Room IDs.
static const RoomID kMars0A = 0;
static const RoomID kMars00 = 1;
static const RoomID kMars01 = 2;
static const RoomID kMars02 = 3;
static const RoomID kMars03 = 4;
static const RoomID kMars04 = 5;
static const RoomID kMars05 = 6;
static const RoomID kMars06 = 7;
static const RoomID kMars07 = 8;
static const RoomID kMars08 = 9;
static const RoomID kMars09 = 10;
static const RoomID kMars10 = 11;
static const RoomID kMars11 = 12;
static const RoomID kMars12 = 13;
static const RoomID kMars13 = 14;
static const RoomID kMars14 = 15;
static const RoomID kMars15 = 16;
static const RoomID kMars16 = 17;
static const RoomID kMars17 = 18;
static const RoomID kMars18 = 19;
static const RoomID kMars19 = 20;
static const RoomID kMars20 = 21;
static const RoomID kMars21 = 22;
static const RoomID kMars22 = 23;
static const RoomID kMars23 = 24;
static const RoomID kMars24 = 25;
static const RoomID kMars25 = 26;
static const RoomID kMars26 = 27;
static const RoomID kMars27 = 28;
static const RoomID kMars28 = 29;
static const RoomID kMars29 = 30;
static const RoomID kMars30 = 31;
static const RoomID kMars31 = 32;
static const RoomID kMars31South = 33;
static const RoomID kMars32 = 34;
static const RoomID kMars33 = 35;
static const RoomID kMars33North = 36;
static const RoomID kMars34 = 37;
static const RoomID kMars35 = 38;
static const RoomID kMars36 = 39;
static const RoomID kMars37 = 40;
static const RoomID kMars38 = 41;
static const RoomID kMars39 = 42;
static const RoomID kMars41 = 43;
static const RoomID kMars42 = 44;
static const RoomID kMars43 = 45;
static const RoomID kMars44 = 46;
static const RoomID kMars45 = 47;
static const RoomID kMars46 = 48;
static const RoomID kMars47 = 49;
static const RoomID kMars48 = 50;
static const RoomID kMars49 = 51;
static const RoomID kMars50 = 52;
static const RoomID kMars51 = 53;
static const RoomID kMars52 = 54;
static const RoomID kMars54 = 55;
static const RoomID kMars56 = 56;
static const RoomID kMars58 = 57;
static const RoomID kMars60 = 58;
static const RoomID kMarsRobotShuttle = 59;
static const RoomID kMarsMaze004 = 60;
static const RoomID kMarsMaze005 = 61;
static const RoomID kMarsMaze006 = 62;
static const RoomID kMarsMaze007 = 63;
static const RoomID kMarsMaze008 = 64;
static const RoomID kMarsMaze009 = 65;
static const RoomID kMarsMaze010 = 66;
static const RoomID kMarsMaze011 = 67;
static const RoomID kMarsMaze012 = 68;
static const RoomID kMarsMaze015 = 69;
static const RoomID kMarsMaze016 = 70;
static const RoomID kMarsMaze017 = 71;
static const RoomID kMarsMaze018 = 72;
static const RoomID kMarsMaze019 = 73;
static const RoomID kMarsMaze020 = 74;
static const RoomID kMarsMaze021 = 75;
static const RoomID kMarsMaze022 = 76;
static const RoomID kMarsMaze023 = 77;
static const RoomID kMarsMaze024 = 78;
static const RoomID kMarsMaze025 = 79;
static const RoomID kMarsMaze026 = 80;
static const RoomID kMarsMaze027 = 81;
static const RoomID kMarsMaze028 = 82;
static const RoomID kMarsMaze031 = 83;
static const RoomID kMarsMaze032 = 84;
static const RoomID kMarsMaze033 = 85;
static const RoomID kMarsMaze034 = 86;
static const RoomID kMarsMaze035 = 87;
static const RoomID kMarsMaze036 = 88;
static const RoomID kMarsMaze037 = 89;
static const RoomID kMarsMaze038 = 90;
static const RoomID kMarsMaze039 = 91;
static const RoomID kMarsMaze042 = 92;
static const RoomID kMarsMaze043 = 93;
static const RoomID kMarsMaze044 = 94;
static const RoomID kMarsMaze045 = 95;
static const RoomID kMarsMaze046 = 96;
static const RoomID kMarsMaze047 = 97;
static const RoomID kMarsMaze049 = 98;
static const RoomID kMarsMaze050 = 99;
static const RoomID kMarsMaze051 = 100;
static const RoomID kMarsMaze052 = 101;
static const RoomID kMarsMaze053 = 102;
static const RoomID kMarsMaze054 = 103;
static const RoomID kMarsMaze055 = 104;
static const RoomID kMarsMaze056 = 105;
static const RoomID kMarsMaze057 = 106;
static const RoomID kMarsMaze058 = 107;
static const RoomID kMarsMaze059 = 108;
static const RoomID kMarsMaze060 = 109;
static const RoomID kMarsMaze061 = 110;
static const RoomID kMarsMaze063 = 111;
static const RoomID kMarsMaze064 = 112;
static const RoomID kMarsMaze065 = 113;
static const RoomID kMarsMaze066 = 114;
static const RoomID kMarsMaze067 = 115;
static const RoomID kMarsMaze068 = 116;
static const RoomID kMarsMaze069 = 117;
static const RoomID kMarsMaze070 = 118;
static const RoomID kMarsMaze071 = 119;
static const RoomID kMarsMaze072 = 120;
static const RoomID kMarsMaze074 = 121;
static const RoomID kMarsMaze076 = 122;
static const RoomID kMarsMaze078 = 123;
static const RoomID kMarsMaze079 = 124;
static const RoomID kMarsMaze081 = 125;
static const RoomID kMarsMaze083 = 126;
static const RoomID kMarsMaze084 = 127;
static const RoomID kMarsMaze085 = 128;
static const RoomID kMarsMaze086 = 129;
static const RoomID kMarsMaze087 = 130;
static const RoomID kMarsMaze088 = 131;
static const RoomID kMarsMaze089 = 132;
static const RoomID kMarsMaze090 = 133;
static const RoomID kMarsMaze091 = 134;
static const RoomID kMarsMaze092 = 135;
static const RoomID kMarsMaze093 = 136;
static const RoomID kMarsMaze098 = 137;
static const RoomID kMarsMaze099 = 138;
static const RoomID kMarsMaze100 = 139;
static const RoomID kMarsMaze101 = 140;
static const RoomID kMarsMaze104 = 141;
static const RoomID kMarsMaze105 = 142;
static const RoomID kMarsMaze106 = 143;
static const RoomID kMarsMaze107 = 144;
static const RoomID kMarsMaze108 = 145;
static const RoomID kMarsMaze111 = 146;
static const RoomID kMarsMaze113 = 147;
static const RoomID kMarsMaze114 = 148;
static const RoomID kMarsMaze115 = 149;
static const RoomID kMarsMaze116 = 150;
static const RoomID kMarsMaze117 = 151;
static const RoomID kMarsMaze118 = 152;
static const RoomID kMarsMaze119 = 153;
static const RoomID kMarsMaze120 = 154;
static const RoomID kMarsMaze121 = 155;
static const RoomID kMarsMaze122 = 156;
static const RoomID kMarsMaze123 = 157;
static const RoomID kMarsMaze124 = 158;
static const RoomID kMarsMaze125 = 159;
static const RoomID kMarsMaze126 = 160;
static const RoomID kMarsMaze127 = 161;
static const RoomID kMarsMaze128 = 162;
static const RoomID kMarsMaze129 = 163;
static const RoomID kMarsMaze130 = 164;
static const RoomID kMarsMaze131 = 165;
static const RoomID kMarsMaze132 = 166;
static const RoomID kMarsMaze133 = 167;
static const RoomID kMarsMaze136 = 168;
static const RoomID kMarsMaze137 = 169;
static const RoomID kMarsMaze138 = 170;
static const RoomID kMarsMaze139 = 171;
static const RoomID kMarsMaze140 = 172;
static const RoomID kMarsMaze141 = 173;
static const RoomID kMarsMaze142 = 174;
static const RoomID kMarsMaze143 = 175;
static const RoomID kMarsMaze144 = 176;
static const RoomID kMarsMaze145 = 177;
static const RoomID kMarsMaze146 = 178;
static const RoomID kMarsMaze147 = 179;
static const RoomID kMarsMaze148 = 180;
static const RoomID kMarsMaze149 = 181;
static const RoomID kMarsMaze152 = 182;
static const RoomID kMarsMaze153 = 183;
static const RoomID kMarsMaze154 = 184;
static const RoomID kMarsMaze155 = 185;
static const RoomID kMarsMaze156 = 186;
static const RoomID kMarsMaze157 = 187;
static const RoomID kMarsMaze159 = 188;
static const RoomID kMarsMaze160 = 189;
static const RoomID kMarsMaze161 = 190;
static const RoomID kMarsMaze162 = 191;
static const RoomID kMarsMaze163 = 192;
static const RoomID kMarsMaze164 = 193;
static const RoomID kMarsMaze165 = 194;
static const RoomID kMarsMaze166 = 195;
static const RoomID kMarsMaze167 = 196;
static const RoomID kMarsMaze168 = 197;
static const RoomID kMarsMaze169 = 198;
static const RoomID kMarsMaze170 = 199;
static const RoomID kMarsMaze171 = 200;
static const RoomID kMarsMaze172 = 201;
static const RoomID kMarsMaze173 = 202;
static const RoomID kMarsMaze174 = 203;
static const RoomID kMarsMaze175 = 204;
static const RoomID kMarsMaze177 = 205;
static const RoomID kMarsMaze178 = 206;
static const RoomID kMarsMaze179 = 207;
static const RoomID kMarsMaze180 = 208;
static const RoomID kMarsMaze181 = 209;
static const RoomID kMarsMaze182 = 210;
static const RoomID kMarsMaze183 = 211;
static const RoomID kMarsMaze184 = 212;
static const RoomID kMarsMaze187 = 213;
static const RoomID kMarsMaze188 = 214;
static const RoomID kMarsMaze189 = 215;
static const RoomID kMarsMaze190 = 216;
static const RoomID kMarsMaze191 = 217;
static const RoomID kMarsMaze192 = 218;
static const RoomID kMarsMaze193 = 219;
static const RoomID kMarsMaze194 = 220;
static const RoomID kMarsMaze195 = 221;
static const RoomID kMarsMaze198 = 222;
static const RoomID kMarsMaze199 = 223;
static const RoomID kMarsMaze200 = 224;
static const RoomID kMarsDeathRoom = 225;
// Hot Spot Activation IDs.
static const HotSpotActivationID kActivationReadyForKiosk = 1;
static const HotSpotActivationID kActivationKioskChoice = 2;
static const HotSpotActivationID kActivationTunnelMapReady = 3;
static const HotSpotActivationID kActivateMarsPodClosed = 4;
static const HotSpotActivationID kActivateMarsPodOpen = 5;
static const HotSpotActivationID kActivateReadyToPressurizeAirlock = 6;
static const HotSpotActivationID kActivateAirlockPressurized = 7;
static const HotSpotActivationID kActivateMaskOnHolder = 8;
static const HotSpotActivationID kActivateMaskOnFiller = 9;
static const HotSpotActivationID kActivateReactorPlatformOut = 10;
static const HotSpotActivationID kActivateReactorPlatformIn = 11;
static const HotSpotActivationID kActivateReactorAskLowerScreen = 12;
static const HotSpotActivationID kActivateReactorReadyForNitrogen = 13;
static const HotSpotActivationID kActivateReactorReadyForCrowBar = 14;
static const HotSpotActivationID kActivateReactorAskOperation = 15;
static const HotSpotActivationID kActivateReactorRanEvaluation = 16;
static const HotSpotActivationID kActivateReactorRanDiagnostics = 17;
static const HotSpotActivationID kActivateReactorAnalyzed = 18;
static const HotSpotActivationID kActivateReactorInstructions = 19;
static const HotSpotActivationID kActivateReactorInGame = 20;
static const HotSpotActivationID kActivateReactorBombSafe = 21;
static const HotSpotActivationID kActivateReactorBombExposed = 22;
static const HotSpotActivationID kActivationRobotHeadClosed = 23;
static const HotSpotActivationID kActivationRobotHeadOpen = 24;
// Hot Spot IDs.
static const HotSpotID kMars11NorthKioskSpotID = 5000;
static const HotSpotID kMars11NorthKioskSightsSpotID = 5001;
static const HotSpotID kMars11NorthKioskColonySpotID = 5002;
static const HotSpotID kMars12NorthKioskSpotID = 5003;
static const HotSpotID kMars12NorthKioskSightsSpotID = 5004;
static const HotSpotID kMars12NorthKioskColonySpotID = 5005;
static const HotSpotID kMars31SouthSpotID = 5006;
static const HotSpotID kMars31SouthOutSpotID = 5007;
static const HotSpotID kMars31SouthCardSpotID = 5008;
static const HotSpotID kMars33NorthSpotID = 5009;
static const HotSpotID kMars33NorthOutSpotID = 5010;
static const HotSpotID kMars33NorthMonitorSpotID = 5011;
static const HotSpotID kMars34NorthCardDropSpotID = 5012;
static const HotSpotID kMars34SouthOpenStorageSpotID = 5013;
static const HotSpotID kMars34SouthCloseStorageSpotID = 5014;
static const HotSpotID kMars34SouthCrowbarSpotID = 5015;
static const HotSpotID kMars35EastPressurizeSpotID = 5016;
static const HotSpotID kMars35EastSpinSpotID = 5017;
static const HotSpotID kMars35WestPressurizeSpotID = 5018;
static const HotSpotID kMars35WestSpinSpotID = 5019;
static const HotSpotID kMars45NorthOpenStorageSpotID = 5020;
static const HotSpotID kMars45NorthCloseStorageSpotID = 5021;
static const HotSpotID kMars45NorthCrowbarSpotID = 5022;
static const HotSpotID kAttackRobotHotSpotID = 5023;
static const HotSpotID kMars49AirMaskSpotID = 5024;
static const HotSpotID kMars49AirMaskFilledSpotID = 5025;
static const HotSpotID kMars49AirFillingDropSpotID = 5026;
static const HotSpotID kMars52MoveLeftSpotID = 5027;
static const HotSpotID kMars52MoveRightSpotID = 5028;
static const HotSpotID kMars52ExtractSpotID = 5029;
static const HotSpotID kMars53RetractSpotID = 5030;
static const HotSpotID kMars54MoveLeftSpotID = 5031;
static const HotSpotID kMars54MoveRightSpotID = 5032;
static const HotSpotID kMars54ExtractSpotID = 5033;
static const HotSpotID kMars55RetractSpotID = 5034;
static const HotSpotID kMars56MoveLeftSpotID = 5035;
static const HotSpotID kMars56MoveRightSpotID = 5036;
static const HotSpotID kMars56ExtractSpotID = 5037;
static const HotSpotID kMars57RetractSpotID = 5038;
static const HotSpotID kMars57LowerScreenSpotID = 5039;
static const HotSpotID kMars57Retract2SpotID = 5040;
static const HotSpotID kMars57DropNitrogenSpotID = 5041;
static const HotSpotID kMars57DropCrowBarSpotID = 5042;
static const HotSpotID kMars57CantOpenPanelSpotID = 5043;
static const HotSpotID kMars57ShieldEvaluationSpotID = 5044;
static const HotSpotID kMars57MeasureOutputSpotID = 5045;
static const HotSpotID kMars57RunDiagnosticsSpotID = 5046;
static const HotSpotID kMars57BackToOperationMenuSpotID = 5047;
static const HotSpotID kMars57AnalyzeObjectSpotID = 5048;
static const HotSpotID kMars57RemoveObjectMenuSpotID = 5049;
static const HotSpotID kMars57CircuitLinkSpotID = 5050;
static const HotSpotID kMars57CancelCircuitLinkSpotID = 5051;
static const HotSpotID kMars57GameInstructionsSpotID = 5052;
static const HotSpotID kMars57UndoMoveSpotID = 5053;
static const HotSpotID kMars57RedMoveSpotID = 5054;
static const HotSpotID kMars57YellowMoveSpotID = 5055;
static const HotSpotID kMars57GreenMoveSpotID = 5056;
static const HotSpotID kMars57BlueMoveSpotID = 5057;
static const HotSpotID kMars57PurpleMoveSpotID = 5058;
static const HotSpotID kMars57LowerScreenSafelySpotID = 5059;
static const HotSpotID kMars57GrabBombSpotID = 5060;
static const HotSpotID kMars58MoveLeftSpotID = 5061;
static const HotSpotID kMars58MoveRightSpotID = 5062;
static const HotSpotID kMars58ExtractSpotID = 5063;
static const HotSpotID kMars59RetractSpotID = 5064;
static const HotSpotID kMars60EastPressurizeSpotID = 5065;
static const HotSpotID kMars60EastSpinSpotID = 5066;
static const HotSpotID kMars60WestPressurizeSpotID = 5067;
static const HotSpotID kMars60WestSpinSpotID = 5068;
static const HotSpotID kRobotShuttleOpenHeadSpotID = 5069;
static const HotSpotID kRobotShuttleMapChipSpotID = 5070;
static const HotSpotID kRobotShuttleOpticalChipSpotID = 5071;
static const HotSpotID kRobotShuttleShieldChipSpotID = 5072;
// Extra sequence IDs.
static const ExtraID kMarsArrivalFromTSA = 0;
static const ExtraID kMars0AWatchShuttleDepart = 1;
static const ExtraID kRobotThrowsPlayer = 2;
static const ExtraID kMarsInfoKioskIntro = 3;
static const ExtraID kMarsColonyInfo = 4;
static const ExtraID kMarsSightsInfo = 5;
static const ExtraID kRobotOnWayToShuttle = 6;
static const ExtraID kMars31SouthZoomInNoCard = 7;
static const ExtraID kMars31SouthViewNoCard = 8;
static const ExtraID kMars31SouthZoomOutNoCard = 9;
static const ExtraID kMars31SouthZoomViewNoCard = 10;
static const ExtraID kMars33SlideShow1 = 11;
static const ExtraID kMars33SlideShow2 = 12;
static const ExtraID kMars33SlideShow3 = 13;
static const ExtraID kMars33SlideShow4 = 14;
static const ExtraID kMars34SpotOpenWithBar = 15;
static const ExtraID kMars34SpotCloseWithBar = 16;
static const ExtraID kMars34SpotOpenNoBar = 17;
static const ExtraID kMars34SpotCloseNoBar = 18;
static const ExtraID kMars34ViewOpenWithBar = 19;
static const ExtraID kMars34ViewOpenNoBar = 20;
static const ExtraID kMars34NorthPodGreeting = 21;
static const ExtraID kMarsTurnOnPod = 22;
static const ExtraID kMarsTakePodToMars45 = 23;
static const ExtraID kMars35WestSpinAirlockToEast = 24;
static const ExtraID kMars35EastSpinAirlockToWest = 25;
static const ExtraID kMars45SpotOpenWithBar = 26;
static const ExtraID kMars45SpotCloseWithBar = 27;
static const ExtraID kMars45SpotOpenNoBar = 28;
static const ExtraID kMars45SpotCloseNoBar = 29;
static const ExtraID kMars45ViewOpenWithBar = 30;
static const ExtraID kMars45ViewOpenNoBar = 31;
static const ExtraID kMars48RobotApproaches = 32;
static const ExtraID kMars48RobotKillsPlayer = 33;
static const ExtraID kMars48RobotLoops = 34;
static const ExtraID kMars48RobotView = 35;
static const ExtraID kMars48RobotDefends = 36;
static const ExtraID kMars49SouthViewMaskFilling = 37;
static const ExtraID kMars52SpinLeft = 38;
static const ExtraID kMars52SpinRight = 39;
static const ExtraID kMars52Extend = 40;
static const ExtraID kMars53Retract = 41;
static const ExtraID kMars54SpinLeft = 42;
static const ExtraID kMars54SpinRight = 43;
static const ExtraID kMars54Extend = 44;
static const ExtraID kMars55Retract = 45;
static const ExtraID kMars56SpinLeft = 46;
static const ExtraID kMars56SpinRight = 47;
static const ExtraID kMars56ExtendWithBomb = 48;
static const ExtraID kMars56ExtendNoBomb = 49;
static const ExtraID kMars57RetractWithBomb = 50;
static const ExtraID kMars57RetractNoBomb = 51;
static const ExtraID kMars57LowerScreenClosed = 52;
static const ExtraID kMars57CantOpenPanel = 53;
static const ExtraID kMars57FreezeLock = 54;
static const ExtraID kMars57BreakLock = 55;
static const ExtraID kMars57LockFrozenView = 56;
static const ExtraID kMars57ThawLock = 57;
static const ExtraID kMars57OpenPanel = 58;
static const ExtraID kMars57OpenPanelChoices = 59;
static const ExtraID kMars57ShieldEvaluation = 60;
static const ExtraID kMars57MeasureOutput = 61;
static const ExtraID kMars57ShieldOkayLoop = 62;
static const ExtraID kMars57RunDiagnostics = 63;
static const ExtraID kMars57BombExplodes = 64;
static const ExtraID kMars57BombAnalysis = 65;
static const ExtraID kMars57DontLink = 66;
static const ExtraID kMars57CircuitLink = 67;
static const ExtraID kMars57GameLevel1 = 68;
static const ExtraID kMars57GameLevel2 = 69;
static const ExtraID kMars57GameLevel3 = 70;
static const ExtraID kMars57BombExplodesInGame = 71;
static const ExtraID kMars57GameSolved = 72;
static const ExtraID kMars57ExposeBomb = 73;
static const ExtraID kMars57BackToNormal = 74;
static const ExtraID kMars57ViewOpenNoBomb = 75;
static const ExtraID kMars58SpinLeft = 76;
static const ExtraID kMars58SpinRight = 77;
static const ExtraID kMars58Extend = 78;
static const ExtraID kMars59Retract = 79;
static const ExtraID kMars60WestSpinAirlockToEast = 80;
static const ExtraID kMars60EastSpinAirlockToWest = 81;
static const ExtraID kMarsRobotHeadOpen = 82;
static const ExtraID kMarsRobotHeadClose = 83;
static const ExtraID kMarsRobotHead000 = 84;
static const ExtraID kMarsRobotHead001 = 85;
static const ExtraID kMarsRobotHead010 = 86;
static const ExtraID kMarsRobotHead011 = 87;
static const ExtraID kMarsRobotHead100 = 88;
static const ExtraID kMarsRobotHead101 = 89;
static const ExtraID kMarsRobotHead110 = 90;
static const ExtraID kMarsRobotHead111 = 91;
static const ExtraID kMarsMaze007RobotApproach = 92;
static const ExtraID kMarsMaze007RobotLoop = 93;
static const ExtraID kMarsMaze007RobotDeath = 94;
static const ExtraID kMarsMaze015SouthRobotApproach = 95;
static const ExtraID kMarsMaze015SouthRobotLoop = 96;
static const ExtraID kMarsMaze015SouthRobotDeath = 97;
static const ExtraID kMarsMaze101EastRobotApproach = 98;
static const ExtraID kMarsMaze101EastRobotLoop = 99;
static const ExtraID kMarsMaze101EastRobotDeath = 100;
static const ExtraID kMarsMaze104WestLoop = 101;
static const ExtraID kMarsMaze104WestDeath = 102;
static const ExtraID kMarsMaze133SouthApproach = 103;
static const ExtraID kMarsMaze133SouthLoop = 104;
static const ExtraID kMarsMaze133SouthDeath = 105;
static const ExtraID kMarsMaze136NorthApproach = 106;
static const ExtraID kMarsMaze136NorthLoop = 107;
static const ExtraID kMarsMaze136NorthDeath = 108;
static const ExtraID kMarsMaze184WestLoop = 109;
static const ExtraID kMarsMaze184WestDeath = 110;
static const ExtraID kMars200DeathInBucket = 111;
// Mars interactions.
static const InteractionID kMarsTunnelPodInteractionID = 0;
static const InteractionID kMarsCanyonChaseInteractionID = 1;
static const ResIDType kReactorUndoHilitePICTID = 900;
static const int16 kMars52Compass = 90;
static const int16 kMars54Compass = 180;
static const int16 kMars56Compass = 270;
static const int16 kMars58Compass = 0;
} // End of namespace Pegasus
#endif

View File

@@ -0,0 +1,69 @@
/* 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 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "pegasus/pegasus.h"
#include "pegasus/neighborhood/mars/energybeam.h"
namespace Pegasus {
static const TimeValue kEnergyBeamTime = kOneSecond * kShuttleWeaponScale / 2;
static const CoordType kEnergyBeamOriginH = kShuttleWindowMidH;
static const CoordType kEnergyBeamOriginV = kShuttleWindowTop + kShuttleWindowHeight;
static const float kBeamXOrigin = convertScreenHToSpaceX(kEnergyBeamOriginH, kEnergyBeamMinDistance);
static const float kBeamYOrigin = convertScreenVToSpaceY(kEnergyBeamOriginV, kEnergyBeamMinDistance);
static const float kBeamZOrigin = kEnergyBeamMinDistance;
EnergyBeam::EnergyBeam() {
_weaponDuration = kEnergyBeamTime;
setSegment(0, kEnergyBeamTime);
_weaponOrigin = Point3D(kBeamXOrigin, kBeamYOrigin, kBeamZOrigin);
}
void EnergyBeam::draw(const Common::Rect &) {
static const int kBeamColorRed1 = 224;
static const int kBeamColorRed2 = 64;
Graphics::Surface *surface = g_vm->_gfx->getWorkArea();
byte red = linearInterp(0, kEnergyBeamTime, _lastTime, kBeamColorRed1, kBeamColorRed2);
uint32 color = surface->format.RGBToColor(red, 0, 0);
Point3D startPoint;
if (_weaponTime < 0.1)
startPoint = _weaponOrigin;
else
linearInterp(_weaponOrigin, _weaponTarget, _weaponTime - 0.1, startPoint);
Common::Point lineStart;
project3DTo2D(startPoint, lineStart);
Common::Point lineEnd;
project3DTo2D(_weaponLocation, lineEnd);
surface->drawThickLine(lineStart.x, lineStart.y, lineEnd.x, lineEnd.y, 2, 1, color);
}
} // End of namespace Pegasus

View File

@@ -0,0 +1,42 @@
/* 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 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef PEGASUS_NEIGHBORHOOD_MARS_ENERGYBEAM_H
#define PEGASUS_NEIGHBORHOOD_MARS_ENERGYBEAM_H
#include "pegasus/neighborhood/mars/shuttleweapon.h"
namespace Pegasus {
class EnergyBeam : public ShuttleWeapon {
public:
EnergyBeam();
~EnergyBeam() override {}
void draw(const Common::Rect &) override;
};
} // End of namespace Pegasus
#endif

View File

@@ -0,0 +1,133 @@
/* 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 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "pegasus/neighborhood/mars/gravitoncannon.h"
#include "pegasus/neighborhood/mars/robotship.h"
#include "pegasus/neighborhood/mars/spacejunk.h"
namespace Pegasus {
static const TimeValue kGravitonTime = kOneSecond * kShuttleWeaponScale;
static const CoordType kGravitonOriginH = kShuttleWindowLeft - 1;
static const CoordType kGravitonOriginV = kShuttleWindowMidV;
static const float kGravitonXOrigin = convertScreenHToSpaceX(kGravitonOriginH, kGravitonMinDistance);
static const float kGravitonYOrigin = convertScreenVToSpaceY(kGravitonOriginV, kGravitonMinDistance);
static const float kGravitonZOrigin = kGravitonMinDistance;
// Width of graviton sprite...
static const CoordType kGravitonMaxScreenWidth = 78;
static const CoordType kGravitonMaxScreenHeight = 46;
static const float kGravitonWidth = convertScreenHToSpaceX(kShuttleWindowMidH + kGravitonMaxScreenWidth / 2, kGravitonMinDistance)
- convertScreenHToSpaceX(kShuttleWindowMidH - kGravitonMaxScreenWidth / 2, kGravitonMinDistance);
static const float kGravitonHeight = convertScreenVToSpaceY(kShuttleWindowMidV - kGravitonMaxScreenHeight / 2, kGravitonMinDistance)
- convertScreenVToSpaceY(kShuttleWindowMidV + kGravitonMaxScreenHeight / 2, kGravitonMinDistance);
GravitonCannon::GravitonCannon() {
_weaponDuration = kGravitonTime;
setSegment(0, kGravitonTime);
_weaponOrigin = Point3D(kGravitonXOrigin, kGravitonYOrigin, kGravitonZOrigin);
_rightOrigin = Point3D(-kGravitonXOrigin, kGravitonYOrigin, kGravitonZOrigin);
}
void GravitonCannon::initShuttleWeapon() {
ShuttleWeapon::initShuttleWeapon();
_gravitonImage.getImageFromPICTFile("Images/Mars/Graviton Cannon");
_gravitonImage.getSurfaceBounds(_gravitonBounds);
}
void GravitonCannon::cleanUpShuttleWeapon() {
_gravitonImage.deallocateSurface();
ShuttleWeapon::cleanUpShuttleWeapon();
}
void GravitonCannon::draw(const Common::Rect &) {
// Left graviton...
Point3D pt3D = _weaponLocation;
pt3D.translate(-kGravitonWidth / 2, kGravitonHeight / 2, 0);
Common::Point pt2D;
project3DTo2D(pt3D, pt2D);
Common::Rect gravitonRect;
gravitonRect.left = pt2D.x;
gravitonRect.top = pt2D.y;
pt3D.translate(kGravitonWidth, -kGravitonHeight, 0);
project3DTo2D(pt3D, pt2D);
gravitonRect.right = pt2D.x;
gravitonRect.bottom = pt2D.y;
_gravitonImage.scaleTransparentCopy(_gravitonBounds, gravitonRect);
// Right graviton...
pt3D = _rightLocation;
pt3D.translate(-kGravitonWidth / 2, kGravitonHeight / 2, 0);
project3DTo2D(pt3D, pt2D);
gravitonRect.left = pt2D.x;
gravitonRect.top = pt2D.y;
pt3D.translate(kGravitonWidth, -kGravitonHeight, 0);
project3DTo2D(pt3D, pt2D);
gravitonRect.right = pt2D.x;
gravitonRect.bottom = pt2D.y;
_gravitonImage.scaleTransparentCopy(_gravitonBounds, gravitonRect);
}
void GravitonCannon::updateWeaponPosition() {
ShuttleWeapon::updateWeaponPosition();
if (_weaponTime != 1.0)
linearInterp(_rightOrigin, _weaponTarget, _weaponTime, _rightLocation);
}
bool GravitonCannon::collisionWithJunk(Common::Point &impactPoint) {
if (getDisplayOrder() == kShuttleWeaponFrontOrder) {
Point3D junkPosition;
g_spaceJunk->getJunkPosition(junkPosition);
if (junkPosition.z < _weaponLocation.z) {
setDisplayOrder(kShuttleWeaponBackOrder);
project3DTo2D(_weaponLocation, impactPoint);
if (g_spaceJunk->pointInJunk(impactPoint))
return true;
project3DTo2D(_rightLocation, impactPoint);
return g_spaceJunk->pointInJunk(impactPoint);
}
}
return false;
}
void GravitonCannon::hitJunk(Common::Point impactPoint) {
g_spaceJunk->hitByGravitonCannon(impactPoint);
}
void GravitonCannon::hitShuttle(Common::Point impactPoint) {
g_robotShip->hitByGravitonCannon(impactPoint);
}
} // End of namespace Pegasus

View File

@@ -0,0 +1,56 @@
/* 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 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef PEGASUS_NEIGHBORHOOD_MARS_GRAVITONCANNON_H
#define PEGASUS_NEIGHBORHOOD_MARS_GRAVITONCANNON_H
#include "pegasus/surface.h"
#include "pegasus/neighborhood/mars/shuttleweapon.h"
namespace Pegasus {
class GravitonCannon : public ShuttleWeapon {
public:
GravitonCannon();
~GravitonCannon() override {}
void initShuttleWeapon() override;
void cleanUpShuttleWeapon() override;
void draw(const Common::Rect &) override;
protected:
void updateWeaponPosition() override;
bool collisionWithJunk(Common::Point &impactPoint) override;
void hitJunk(Common::Point impactPoint) override;
void hitShuttle(Common::Point impactPoint) override;
Surface _gravitonImage;
Common::Rect _gravitonBounds;
Point3D _rightOrigin, _rightLocation;
};
} // End of namespace Pegasus
#endif

View File

@@ -0,0 +1,75 @@
/* 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 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "pegasus/neighborhood/mars/hermite.h"
namespace Pegasus {
CoordType hermite(CoordType p1, CoordType p4, CoordType r1, CoordType r4, int32 time, int32 duration) {
float t = (float)time / duration;
float tsq = t * t;
float tcu = t * tsq;
float tcu2 = tcu + tcu;
float tsq2 = tsq + tsq;
float tsq3 = tsq2 + tsq;
return (CoordType)((tcu2 - tsq3 + 1) * p1 + (tsq3 - tcu2) * p4 + (tcu - tsq2 + t) * r1 + (tcu - tsq) * r4);
}
CoordType dHermite(CoordType p1, CoordType p4, CoordType r1, CoordType r4, int32 time, int32 duration) {
float t = (float)time / duration;
float t2 = t + t;
float t4 = t2 + t2;
float t6 = t4 + t2;
float tsq = t * t;
float tsq3 = tsq + tsq + tsq;
float tsq6 = tsq3 + tsq3;
return (CoordType)((tsq6 - t6) * p1 + (t6 - tsq6) * p4 + (tsq3 - t4 + 1) * r1 + (tsq3 - t2) * r4);
}
void hermite(Common::Point p1, Common::Point p4, Common::Point r1, Common::Point r4, int32 time, int32 duration, Common::Point &result) {
float t = (float)time / duration;
float tsq = t * t;
float tcu = t * tsq;
float tcu2 = tcu + tcu;
float tsq2 = tsq + tsq;
float tsq3 = tsq2 + tsq;
result.x = (int16)((tcu2 - tsq3 + 1) * p1.x + (tsq3 - tcu2) * p4.x + (tcu - tsq2 + t) * r1.x + (tcu - tsq) * r4.x);
result.y = (int16)((tcu2 - tsq3 + 1) * p1.y + (tsq3 - tcu2) * p4.y + (tcu - tsq2 + t) * r1.y + (tcu - tsq) * r4.y);
}
void dHermite(Common::Point p1, Common::Point p4, Common::Point r1, Common::Point r4, int32 time, int32 duration, Common::Point &result) {
float t = (float)time / duration;
float t2 = t + t;
float t4 = t2 + t2;
float t6 = t4 + t2;
float tsq = t * t;
float tsq3 = tsq + tsq + tsq;
float tsq6 = tsq3 + tsq3;
result.x = (int16)((tsq6 - t6) * p1.x + (t6 - tsq6) * p4.x + (tsq3 - t4 + 1) * r1.x + (tsq3 - t2) * r4.x);
result.y = (int16)((tsq6 - t6) * p1.y + (t6 - tsq6) * p4.y + (tsq3 - t4 + 1) * r1.y + (tsq3 - t2) * r4.y);
}
} // End of namespace Pegasus

View File

@@ -0,0 +1,40 @@
/* 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 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef PEGASUS_NEIGHBORHOOD_MARS_HERMITE_H
#define PEGASUS_NEIGHBORHOOD_MARS_HERMITE_H
#include "common/rect.h"
#include "pegasus/types.h"
namespace Pegasus {
CoordType hermite(CoordType p1, CoordType p4, CoordType r1, CoordType r4, int32 t, int32 duration);
CoordType dHermite(CoordType p1, CoordType p4, CoordType r1, CoordType r4, int32 t, int32 duration);
void hermite(Common::Point p1, Common::Point p4, Common::Point r1, Common::Point r4, int32 t, int32 duration, Common::Point &result);
void dHermite(Common::Point p1, Common::Point p4, Common::Point r1, Common::Point r4, int32 t, int32 duration, Common::Point &result);
} // End of namespace Pegasus
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,258 @@
/* 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 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef PEGASUS_NEIGHBORHOOD_MARS_MARS_H
#define PEGASUS_NEIGHBORHOOD_MARS_MARS_H
#include "pegasus/neighborhood/neighborhood.h"
#include "pegasus/neighborhood/mars/constants.h"
#include "pegasus/neighborhood/mars/energybeam.h"
#include "pegasus/neighborhood/mars/gravitoncannon.h"
#include "pegasus/neighborhood/mars/planetmover.h"
#include "pegasus/neighborhood/mars/reactor.h"
#include "pegasus/neighborhood/mars/robotship.h"
#include "pegasus/neighborhood/mars/shuttleenergymeter.h"
#include "pegasus/neighborhood/mars/shuttlehud.h"
#include "pegasus/neighborhood/mars/spacejunk.h"
#include "pegasus/neighborhood/mars/tractorbeam.h"
namespace Pegasus {
class CanyonChase;
class InventoryItem;
class Mars;
class TunnelPod;
enum MarsTimerCode {
kMarsPodCautionDisplayed,
kMarsPodCautionDismissed,
kMarsCanyonChaseExited,
kMarsCanyonChaseFaded,
kMarsLaunchTubeReached,
kMarsCanyonChaseFinished,
kMarsSpaceChaseFinished // Player ran out of time...
};
struct MarsTimerEvent {
Mars *mars;
MarsTimerCode event;
void fire();
};
enum ShuttleWeaponSelection {
kNoWeapon,
kEnergyBeam,
kGravitonCannon,
kTractorBeam
};
class Mars : public Neighborhood {
friend class CanyonChase;
friend class TunnelPod;
friend struct MarsTimerEvent;
public:
Mars(InputHandler *, PegasusEngine *);
~Mars() override;
GameInteraction *makeInteraction(const InteractionID) override;
void flushGameState() override;
uint16 getDateResID() const override;
AirQuality getAirQuality(const RoomID) override;
void checkAirMask() override;
void showBigExplosion(const Common::Rect &, const DisplayOrder);
void showLittleExplosion(const Common::Rect &, const DisplayOrder);
void hitByJunk();
void decreaseRobotShuttleEnergy(const int, Common::Point impactPoint);
void setUpNextDropTime();
Common::Path getBriefingMovie() override;
Common::Path getEnvScanMovie() override;
uint getNumHints() override;
Common::Path getHintMovie(uint) override;
void shieldOn() override;
void shieldOff() override;
void checkContinuePoint(const RoomID, const DirectionConstant) override;
void setSoundFXLevel(const uint16) override;
void setAmbienceLevel(const uint16) override;
bool canSolve() override;
void doSolve() override;
bool inColorMatchingGame();
protected:
enum {
kMarsPrivatePodStorageOpenFlag,
kMarsPrivatePodTurnLeftFlag,
kMarsPrivatePodTurnRightFlag,
kMarsPrivateRobotTiredOfWaitingFlag,
kMarsPrivatePlatformZoomedInFlag,
kMarsPrivateBombExposedFlag,
kMarsPrivateDraggingBombFlag,
kMarsPrivateInSpaceChaseFlag,
kMarsPrivateGotMapChipFlag,
kMarsPrivateGotOpticalChipFlag,
kMarsPrivateGotShieldChipFlag,
kNumMarsPrivateFlags
};
void init() override;
void start() override;
void setUpAIRules() override;
void arriveAt(const RoomID, const DirectionConstant) override;
void takeItemFromRoom(Item *) override;
void dropItemIntoRoom(Item *, Hotspot *) override;
void activateHotspots() override;
void activateOneHotspot(HotspotInfoTable::Entry &, Hotspot *) override;
void clickInHotspot(const Input &, const Hotspot *) override;
InputBits getInputFilter() override;
TimeValue getViewTime(const RoomID, const DirectionConstant) override;
void getZoomEntry(const HotSpotID, ZoomTable::Entry &) override;
void findSpotEntry(const RoomID, const DirectionConstant, SpotFlags, SpotTable::Entry &) override;
CanOpenDoorReason canOpenDoor(DoorTable::Entry &) override;
void openDoor() override;
void closeDoorOffScreen(const RoomID, const DirectionConstant) override;
void startDoorOpenMovie(const TimeValue, const TimeValue) override;
void startExitMovie(const ExitTable::Entry &) override;
int16 getStaticCompassAngle(const RoomID, const DirectionConstant) override;
void getExitCompassMove(const ExitTable::Entry &, FaderMoveSpec &) override;
void getExtraCompassMove(const ExtraTable::Entry &, FaderMoveSpec &) override;
void turnTo(const DirectionConstant) override;
void startExtraSequence(const ExtraID, const NotificationFlags, const InputBits) override;
void receiveNotification(Notification *, const NotificationFlags) override;
void doorOpened() override;
void startUpFromFinishedTunnelPod();
void setUpReactorEnergyDrain();
Hotspot *getItemScreenSpot(Item *, DisplayElement *) override;
void lockThawed();
void robotTiredOfWaiting();
void setUpReactorLevel1();
void setUpNextReactorLevel();
void makeColorSequence();
void doUndoOneGuess();
void doReactorGuess(int32 guess);
void bombExplodesInGame();
void didntFindBomb();
CanMoveForwardReason canMoveForward(ExitTable::Entry &) override;
void cantMoveThatWay(CanMoveForwardReason) override;
void moveForward() override;
void bumpIntoWall() override;
void turnLeft() override;
void turnRight() override;
void airStageExpired();
void loadAmbientLoops() override;
void checkAirlockDoors();
void pickedUpItem(Item *item) override;
void cantOpenDoor(CanOpenDoorReason) override;
void launchMaze007Robot();
void launchMaze015Robot();
void launchMaze101Robot();
void launchMaze104Robot();
void launchMaze133Robot();
void launchMaze136Robot();
void launchMaze184Robot();
void timerExpired(const uint32) override;
void showRobotAtReactor();
void spotCompleted() override;
void doCanyonChase(void);
void startMarsTimer(TimeValue, TimeScale, MarsTimerCode);
void marsTimerExpired(MarsTimerEvent &);
void throwAwayMarsShuttle();
void startUpFromFinishedSpaceChase();
void startUpFromSpaceChase();
void transportOutFromSpaceChase(bool);
void spaceChaseClick(const Input &, const HotSpotID);
void updateCursor(const Common::Point &, const Hotspot *) override;
void playSpaceAmbient();
Common::Path getSoundSpotsName() override;
Common::Path getNavMovieName() override;
Movie _extraMovie;
NotificationCallBack _extraMovieCallBack;
InventoryItem *_attackingItem;
FuseFunction _bombFuse;
FuseFunction _noAirFuse;
FuseFunction _utilityFuse;
FlagsArray<byte, kNumMarsPrivateFlags> _privateFlags;
uint _reactorStage, _nextGuess;
int32 _currentGuess[3];
ReactorGuess _guessObject;
Picture _undoPict;
ReactorHistory _guessHistory;
ReactorChoiceHighlight _choiceHighlight;
Picture _shuttleInterface1;
Picture _shuttleInterface2;
Picture _shuttleInterface3;
Picture _shuttleInterface4;
Movie _canyonChaseMovie;
Sound _musicLoop;
SoundFader _musicFader;
MarsTimerEvent _marsEvent;
Movie _leftShuttleMovie;
Movie _rightShuttleMovie;
Movie _lowerLeftShuttleMovie;
Movie _lowerRightShuttleMovie;
Movie _centerShuttleMovie;
Movie _upperLeftShuttleMovie;
Movie _upperRightShuttleMovie;
Movie _leftDamageShuttleMovie;
Movie _rightDamageShuttleMovie;
ShuttleEnergyMeter _shuttleEnergyMeter;
Movie _planetMovie;
PlanetMover _planetMover;
RobotShip _robotShip;
ShuttleHUD _shuttleHUD;
TractorBeam _tractorBeam;
SpaceJunk _junk;
EnergyBeam _energyBeam;
GravitonCannon _gravitonCannon;
Hotspot _energyChoiceSpot;
Hotspot _gravitonChoiceSpot;
Hotspot _tractorChoiceSpot;
Hotspot _shuttleViewSpot;
Hotspot _shuttleTransportSpot;
ShuttleWeaponSelection _weaponSelection;
ScalingMovie _explosions;
NotificationCallBack _explosionCallBack;
};
} // End of namespace Pegasus
#endif

View File

@@ -0,0 +1,103 @@
/* 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 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "pegasus/movie.h"
#include "pegasus/pegasus.h"
#include "pegasus/neighborhood/mars/constants.h"
#include "pegasus/neighborhood/mars/hermite.h"
#include "pegasus/neighborhood/mars/planetmover.h"
#include "pegasus/neighborhood/mars/shuttleenergymeter.h"
namespace Pegasus {
static const TimeScale kRovingScale = kTractorBeamScale;
static const TimeValue kRovingTime = kTenSeconds * kRovingScale;
static const TimeValue kRovingSlop = kTwoSeconds * kRovingScale;
static const CoordType kMaxVelocity = 20;
PlanetMover::PlanetMover() {
setScale(kRovingScale);
_dropping = false;
_planetMovie = nullptr;
}
void PlanetMover::startMoving(Movie *planetMovie) {
_planetMovie = planetMovie;
_p4 = kPlanetStartTop;
_r4 = g_vm->getRandomNumber(kMaxVelocity - 1);
if (_r4 + _p4 < kPlanetStopTop)
_r4 = kPlanetStopTop - _p4;
newDestination();
}
void PlanetMover::stopMoving() {
stop();
}
void PlanetMover::dropPlanetOutOfSight() {
stop();
CoordType currentLoc = hermite(_p1, _p4, _r1, _r4, _lastTime, _duration);
CoordType currentV = dHermite(_p1, _p4, _r1, _r4, _lastTime, _duration);
_p1 = currentLoc;
_r1 = currentV;
_p4 = kPlanetStartTop;
_r4 = 0;
_duration = kTractorBeamTime - kTractorBeamScale;
_dropping = true;
setSegment(0, _duration);
setTime(0);
start();
}
void PlanetMover::newDestination() {
_p1 = _p4;
_r1 = _r4;
_p4 = kPlanetStopTop + g_vm->getRandomNumber(kPlanetStartTop - kPlanetStopTop - 1);
_r4 = g_vm->getRandomNumber(kMaxVelocity - 1);
if (_r4 + _p4 < kPlanetStopTop)
_r4 = kPlanetStopTop - _p4;
stop();
_duration = kRovingTime + g_vm->getRandomNumber(kRovingSlop - 1);
setSegment(0, _duration);
setTime(0);
start();
}
void PlanetMover::timeChanged(const TimeValue) {
if (_planetMovie) {
_planetMovie->moveElementTo(kPlanetStartLeft, hermite(_p1, _p4, _r1, _r4, _lastTime, _duration));
if (_lastTime == _duration) {
if (_dropping)
stop();
else
newDestination();
}
}
}
} // End of namespace Pegasus

View File

@@ -0,0 +1,56 @@
/* 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 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef PEGASUS_NEIGHBORHOOD_MARS_PLANETMOVER_H
#define PEGASUS_NEIGHBORHOOD_MARS_PLANETMOVER_H
#include "pegasus/timers.h"
namespace Pegasus {
class Movie;
class PlanetMover : IdlerTimeBase {
public:
PlanetMover();
~PlanetMover() override {}
void startMoving(Movie *);
void stopMoving();
void dropPlanetOutOfSight();
protected:
void newDestination();
void timeChanged(const TimeValue) override;
Movie *_planetMovie;
CoordType _p1, _p4, _r1, _r4;
TimeValue _duration;
bool _dropping;
};
} // End of namespace Pegasus
#endif

View File

@@ -0,0 +1,296 @@
/* 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 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* aint32 with this program; if not, write to the Free Software
*
*/
#include "pegasus/pegasus.h"
#include "pegasus/neighborhood/mars/reactor.h"
namespace Pegasus {
static const CoordType kCurrentGuessWidth = 121;
static const CoordType kCurrentGuessHeight = 23;
static const CoordType kOneGuessWidth = 25;
static const CoordType kOneGuessHeight = 23;
static const ResIDType kReactorChoicesPICTID = 905;
static const CoordType kCurrentGuessLeft = kNavAreaLeft + 146;
static const CoordType kCurrentGuessTop = kNavAreaTop + 90;
ReactorGuess::ReactorGuess(const DisplayElementID id) : DisplayElement(id) {
setBounds(kCurrentGuessLeft, kCurrentGuessTop, kCurrentGuessLeft + kCurrentGuessWidth,
kCurrentGuessTop + kCurrentGuessHeight);
setDisplayOrder(kMonitorLayer);
_currentGuess[0] = -1;
_currentGuess[1] = -1;
_currentGuess[2] = -1;
}
void ReactorGuess::initReactorGuess() {
_colors.getImageFromPICTResource(g_vm->_resFork, kReactorChoicesPICTID);
startDisplaying();
show();
}
void ReactorGuess::disposeReactorGuess() {
stopDisplaying();
_colors.deallocateSurface();
}
void ReactorGuess::setGuess(int32 a, int32 b, int32 c) {
_currentGuess[0] = a;
_currentGuess[1] = b;
_currentGuess[2] = c;
triggerRedraw();
}
void ReactorGuess::draw(const Common::Rect &) {
if (_colors.isSurfaceValid()) {
Common::Rect r1(0, 0, kOneGuessWidth, kOneGuessHeight);
Common::Rect r2 = r1;
for (int i = 0; i < 3; i++) {
if (_currentGuess[i] >= 0) {
r1.moveTo(kOneGuessWidth * _currentGuess[i], 0);
r2.moveTo(kCurrentGuessLeft + 48 * i, kCurrentGuessTop);
_colors.copyToCurrentPortTransparent(r1, r2);
}
}
}
}
static const CoordType kReactorChoiceHiliteWidth = 166;
static const CoordType kReactorChoiceHiliteHeight = 26;
static const CoordType kChoiceHiliteLefts[6] = {
0,
34,
34 + 34,
34 + 34 + 32,
34 + 34 + 32 + 34,
34 + 34 + 32 + 34 + 32
};
static const ResIDType kReactorChoiceHilitePICTID = 901;
static const CoordType kReactorChoiceHiliteLeft = kNavAreaLeft + 116;
static const CoordType kReactorChoiceHiliteTop = kNavAreaTop + 158;
ReactorChoiceHighlight::ReactorChoiceHighlight(const DisplayElementID id) : DisplayElement(id) {
setBounds(kReactorChoiceHiliteLeft, kReactorChoiceHiliteTop, kReactorChoiceHiliteLeft + kReactorChoiceHiliteWidth,
kReactorChoiceHiliteTop + kReactorChoiceHiliteHeight);
setDisplayOrder(kMonitorLayer);
}
void ReactorChoiceHighlight::initReactorChoiceHighlight() {
_colors.getImageFromPICTResource(g_vm->_resFork, kReactorChoiceHilitePICTID);
startDisplaying();
show();
}
void ReactorChoiceHighlight::disposeReactorChoiceHighlight() {
stopDisplaying();
_colors.deallocateSurface();
}
void ReactorChoiceHighlight::draw(const Common::Rect &) {
if (_colors.isSurfaceValid()) {
for (int i = 0; i < 5; ++i) {
if (_choices.getFlag(i)) {
Common::Rect r1(0, 0, kChoiceHiliteLefts[i + 1] - kChoiceHiliteLefts[i], kReactorChoiceHiliteHeight);
Common::Rect r2 = r1;
r1.moveTo(kChoiceHiliteLefts[i], 0);
r2.moveTo(kReactorChoiceHiliteLeft + kChoiceHiliteLefts[i], kReactorChoiceHiliteTop);
_colors.copyToCurrentPort(r1, r2);
}
}
}
}
static const CoordType kReactorHistoryWidth = 128;
static const CoordType kReactorHistoryHeight = 168;
static const CoordType kColorWidths[5] = { 24, 25, 25, 26, 27 };
static const CoordType kColorHeights[5] = { 14, 15, 17, 17, 19};
static const CoordType kHistoryLefts[5][3] = {
{ 302 + kNavAreaLeft, 329 + kNavAreaLeft, 357 + kNavAreaLeft },
{ 302 + kNavAreaLeft, 331 + kNavAreaLeft, 360 + kNavAreaLeft },
{ 303 + kNavAreaLeft, 333 + kNavAreaLeft, 363 + kNavAreaLeft },
{ 304 + kNavAreaLeft, 335 + kNavAreaLeft, 366 + kNavAreaLeft },
{ 305 + kNavAreaLeft, 337 + kNavAreaLeft, 369 + kNavAreaLeft }
};
static const CoordType kHistoryTops[5] = {
39 + kNavAreaTop,
61 + kNavAreaTop,
84 + kNavAreaTop,
110 + kNavAreaTop,
137 + kNavAreaTop
};
static const CoordType kOneAnswerWidth = 35;
static const CoordType kOneAnswerHeight = 27;
static const CoordType kDigitWidth = 16;
static const CoordType kDigitHeight = 12;
static const CoordType kCorrectCountLefts[5] = {
388 + kNavAreaLeft,
392 + kNavAreaLeft,
398 + kNavAreaLeft,
402 + kNavAreaLeft,
406 + kNavAreaLeft
};
static const CoordType kCorrectCountTops[5] = {
40 + kNavAreaTop,
62 + kNavAreaTop,
86 + kNavAreaTop,
112 + kNavAreaTop,
140 + kNavAreaTop
};
static const ResIDType kReactorDigitsPICTID = 902;
static const ResIDType kReactorHistoryPICTID = 903;
static const ResIDType kReactorAnswerPICTID = 904;
static const CoordType kReactorHistoryLeft = kNavAreaLeft + 302;
static const CoordType kReactorHistoryTop = kNavAreaTop + 39;
static const CoordType kAnswerLeft = kNavAreaLeft + 304;
static const CoordType kAnswerTop = kNavAreaTop + 180;
ReactorHistory::ReactorHistory(const DisplayElementID id) : DisplayElement(id) {
setBounds(kReactorHistoryLeft, kReactorHistoryTop, kReactorHistoryLeft + kReactorHistoryWidth,
kReactorHistoryTop + kReactorHistoryHeight);
setDisplayOrder(kMonitorLayer);
_numGuesses = 0;
_answer[0] = -1;
_answer[1] = -1;
_answer[2] = -1;
_showAnswer = false;
}
void ReactorHistory::initReactorHistory() {
_colors.getImageFromPICTResource(g_vm->_resFork, kReactorHistoryPICTID);
_digits.getImageFromPICTResource(g_vm->_resFork, kReactorDigitsPICTID);
_answerColors.getImageFromPICTResource(g_vm->_resFork, kReactorAnswerPICTID);
startDisplaying();
show();
}
void ReactorHistory::disposeReactorHistory() {
stopDisplaying();
_colors.deallocateSurface();
}
void ReactorHistory::addGuess(int32 a, int32 b, int32 c) {
_history[_numGuesses][0] = a;
_history[_numGuesses][1] = b;
_history[_numGuesses][2] = c;
_numGuesses++;
triggerRedraw();
}
void ReactorHistory::clearHistory() {
_numGuesses = 0;
_showAnswer = false;
triggerRedraw();
}
void ReactorHistory::setAnswer(int32 a, int32 b, int32 c) {
_answer[0] = a;
_answer[1] = b;
_answer[2] = c;
}
void ReactorHistory::showAnswer() {
_showAnswer = true;
triggerRedraw();
}
bool ReactorHistory::isSolved() {
for (int i = 0; i < _numGuesses; i++)
if (_history[i][0] == _answer[0] && _history[i][1] == _answer[1] && _history[i][2] == _answer[2])
return true;
return false;
}
void ReactorHistory::draw(const Common::Rect &) {
static const CoordType kColorTops[5] = {
0,
kColorHeights[0],
(CoordType)(kColorHeights[0] + kColorHeights[1]),
(CoordType)(kColorHeights[0] + kColorHeights[1] + kColorHeights[2]),
(CoordType)(kColorHeights[0] + kColorHeights[1] + kColorHeights[2] + kColorHeights[3]),
};
if (_colors.isSurfaceValid() && _digits.isSurfaceValid()) {
for (int i = 0; i < _numGuesses; ++i) {
Common::Rect r1(0, 0, kColorWidths[i], kColorHeights[i]);
Common::Rect r2 = r1;
Common::Rect r3(0, 0, kDigitWidth, kDigitHeight);
Common::Rect r4 = r3;
int correct = 0;
for (int j = 0; j < 3; ++j) {
r1.moveTo(kColorWidths[i] * _history[i][j], kColorTops[i]);
r2.moveTo(kHistoryLefts[i][j], kHistoryTops[i]);
_colors.copyToCurrentPortTransparent(r1, r2);
if (_history[i][j] == _answer[j])
correct++;
}
r3.moveTo(kDigitWidth * correct, 0);
r4.moveTo(kCorrectCountLefts[i], kCorrectCountTops[i]);
_digits.copyToCurrentPort(r3, r4);
}
if (_showAnswer && _answerColors.isSurfaceValid()) {
Common::Rect r1(0, 0, kOneAnswerWidth, kOneAnswerHeight);
Common::Rect r2 = r1;
for (int i = 0; i < 3; i++) {
r1.moveTo(kOneAnswerWidth * _answer[i], 0);
r2.moveTo(kAnswerLeft + 34 * i, kAnswerTop);
_answerColors.copyToCurrentPortTransparent(r1, r2);
}
}
}
}
int32 ReactorHistory::getCurrentNumCorrect() {
int correct = 0;
for (int i = 0; i < 3; i++)
if (_history[_numGuesses - 1][i] == _answer[i])
correct++;
return correct;
}
} // End of namespace Pegasus

View File

@@ -0,0 +1,107 @@
/* 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 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef PEGASUS_NEIGHBORHOOD_MARS_REACTOR_H
#define PEGASUS_NEIGHBORHOOD_MARS_REACTOR_H
#include "pegasus/elements.h"
#include "pegasus/surface.h"
#include "pegasus/util.h"
namespace Pegasus {
class ReactorGuess : public DisplayElement {
public:
ReactorGuess(const DisplayElementID);
~ReactorGuess() override {}
void initReactorGuess();
void disposeReactorGuess();
void setGuess(int32, int32, int32);
void draw(const Common::Rect &) override;
protected:
int32 _currentGuess[3];
Surface _colors;
};
class ReactorChoiceHighlight : public DisplayElement {
public:
ReactorChoiceHighlight(const DisplayElementID);
~ReactorChoiceHighlight() override {}
void initReactorChoiceHighlight();
void disposeReactorChoiceHighlight();
void resetHighlight() {
_choices.clearAllFlags();
triggerRedraw();
}
bool choiceHighlighted(uint32 whichChoice) { return _choices.getFlag(whichChoice); }
void draw(const Common::Rect &) override;
void highlightChoice(uint32 whichChoice) {
_choices.setFlag(whichChoice);
triggerRedraw();
}
protected:
Surface _colors;
FlagsArray<byte, 5> _choices;
};
class ReactorHistory : public DisplayElement {
public:
ReactorHistory(const DisplayElementID);
~ReactorHistory() override {}
void initReactorHistory();
void disposeReactorHistory();
void draw(const Common::Rect &) override;
void addGuess(int32, int32, int32);
int32 getNumGuesses() { return _numGuesses; }
void clearHistory();
void setAnswer(int32, int32, int32);
void showAnswer();
bool isSolved();
int32 getCurrentNumCorrect();
protected:
Surface _colors, _digits, _answerColors;
int32 _answer[3];
int32 _history[5][3];
int32 _numGuesses;
bool _showAnswer;
};
} // End of namespace Pegasus
#endif

View File

@@ -0,0 +1,266 @@
/* 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 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "pegasus/gamestate.h"
#include "pegasus/pegasus.h"
#include "pegasus/neighborhood/mars/hermite.h"
#include "pegasus/neighborhood/mars/mars.h"
#include "pegasus/neighborhood/mars/robotship.h"
#include "pegasus/neighborhood/mars/spacechase3d.h"
#include "pegasus/neighborhood/mars/spacejunk.h"
namespace Pegasus {
static const TimeScale kRovingScale = kTractorBeamScale;
static const TimeValue kRovingTime = kSixSeconds * kRovingScale;
static const TimeValue kRovingSlop = kThreeSeconds * kRovingScale;
static const int kNumSpriteColumns = 15;
static const int kNumSpriteRows = 16;
static const CoordType kInitialLocationLeft = kShuttleWindowLeft - 50;
static const CoordType kInitialLocationTop = kShuttleWindowTop - 50;
static const CoordType kInitialLocationWidth = kShuttleWindowWidth + 100;
static const CoordType kInitialLocationHeight = kShuttleWindowHeight + 100;
static const CoordType kVelocityVectorLength = 100;
static const CoordType kVelocityVectorSlop = 50;
static const CoordType kRovingLeft = kShuttleWindowLeft + 20;
static const CoordType kRovingTop = kShuttleWindowTop + 20;
static const CoordType kRovingWidth = kShuttleWindowMidH - kRovingLeft;
static const CoordType kRovingHeight = kShuttleWindowMidV - kRovingTop;
RobotShip *g_robotShip = nullptr;
RobotShip::RobotShip() : _spritesMovie(kNoDisplayElement) {
g_robotShip = this;
_shipRange = Common::Rect(kShuttleWindowLeft, kShuttleWindowTop, kShuttleWindowLeft + kShuttleWindowWidth,
kShuttleWindowTop + kShuttleWindowHeight);
setScale(kRovingScale);
_currentLocation.x = 0;
_currentLocation.y = 0;
_snaring = false;
_dropJunkFuse.setFunctor(new Common::Functor0Mem<void, RobotShip>(this, &RobotShip::timeToDropJunk));
_duration = 0xFFFFFFFF;
}
RobotShip::~RobotShip() {
g_robotShip = nullptr;
}
void RobotShip::initRobotShip() {
_spritesMovie.initFromMovieFile("Images/Mars/Ship.movie", true);
_spritesMovie.setDisplayOrder(kShuttleRobotShipOrder);
_spritesMovie.moveElementTo(kPlanetStartLeft, kPlanetStartTop);
_spritesMovie.startDisplaying();
_spritesMovie.show();
Common::Rect r;
_spritesMovie.getBounds(r);
_shipWidth = r.width();
_shipHeight = r.height();
_dead = false;
}
void RobotShip::cleanUpRobotShip() {
_dropJunkFuse.stopFuse();
_spritesMovie.stopDisplaying();
_spritesMovie.releaseMovie();
}
void RobotShip::startMoving() {
if (g_vm->getRandomBit()) {
_p4.x = kInitialLocationLeft + g_vm->getRandomNumber(kInitialLocationWidth - 1);
if (g_vm->getRandomBit())
_p4.y = kInitialLocationTop;
else
_p4.y = kInitialLocationTop + kInitialLocationHeight;
} else {
_p4.y = kInitialLocationTop + g_vm->getRandomNumber(kInitialLocationHeight - 1);
if (g_vm->getRandomBit())
_p4.x = kInitialLocationLeft;
else
_p4.x = kInitialLocationLeft + kInitialLocationWidth;
}
makeVelocityVector(_p4.x, _p4.y, kShuttleWindowLeft + kShuttleWindowWidth / 2,
kShuttleWindowTop + kShuttleWindowHeight / 2, _r4);
newDestination();
setUpNextDropTime();
}
void RobotShip::killRobotShip() {
cleanUpRobotShip();
_dead = true;
}
void RobotShip::setUpNextDropTime() {
if (!isSnared()) {
_dropJunkFuse.primeFuse(kJunkDropBaseTime + g_vm->getRandomNumber(kJunkDropSlopTime));
_dropJunkFuse.lightFuse();
}
}
void RobotShip::timeToDropJunk() {
if (g_spaceJunk) {
CoordType x, y;
_spritesMovie.getCenter(x, y);
g_spaceJunk->launchJunk(g_vm->getRandomNumber(24), x, y);
}
}
void RobotShip::newDestination() {
_p1 = _p4;
_r1 = _r4;
_p4.x = kRovingLeft + g_vm->getRandomNumber(kRovingWidth - 1);
_p4.y = kRovingTop + g_vm->getRandomNumber(kRovingHeight - 1);
if (g_vm->getRandomNumber(7) < 6) {
if (!sameSign(_p4.x - kShuttleWindowMidH, kShuttleWindowMidH - _p1.x)) {
if (sign(_p4.x - kShuttleWindowMidH) > 0)
_p4.x -= kRovingWidth;
else
_p4.x += kRovingWidth;
}
}
if (g_vm->getRandomNumber(7) < 6) {
if (!sameSign(_p4.y - kShuttleWindowMidV, kShuttleWindowMidV - _p1.y)) {
if (sign(_p4.y - kShuttleWindowMidV) > 0)
_p4.y -= kRovingHeight;
else
_p4.y += kRovingHeight;
}
}
makeVelocityVector(_p4.x, _p4.y, kShuttleWindowLeft + kShuttleWindowWidth / 2,
kShuttleWindowTop + kShuttleWindowHeight / 2, _r4);
stop();
_duration = kRovingTime + g_vm->getRandomNumber(kRovingSlop - 1);
setSegment(0, _duration);
setTime(0);
start();
}
void RobotShip::moveRobotTo(CoordType x, CoordType y) {
_currentLocation.x = x;
_currentLocation.y = y;
if (_spritesMovie.isMovieValid()) {
_spritesMovie.moveElementTo(x - (_shipWidth >> 1), y - (_shipHeight >> 1));
if (x < _shipRange.left)
x = 0;
else if (x > _shipRange.right - 1)
x = _shipRange.width() - 1;
else
x -= _shipRange.left;
if (y < _shipRange.top)
y = 0;
else if (y > _shipRange.bottom - 1)
y = _shipRange.height() - 1;
else
y -= _shipRange.top;
x = kNumSpriteColumns * x / _shipRange.width();
y = kNumSpriteRows * y / _shipRange.height();
_spritesMovie.setTime(40 * (x + y * kNumSpriteColumns));
_spritesMovie.redrawMovieWorld();
}
}
bool RobotShip::pointInShuttle(Common::Point &pt) {
Common::Rect r;
_spritesMovie.getBounds(r);
int dx = r.width() / 4;
int dy = r.height() / 6;
r.left += dx;
r.right -= dx;
r.top += dy;
r.bottom -= dy;
return r.contains(pt);
}
void RobotShip::hitByEnergyBeam(Common::Point impactPoint) {
((Mars *)g_neighborhood)->decreaseRobotShuttleEnergy(1, impactPoint);
setGlowing(true);
g_vm->delayShell(1, 3);
setGlowing(false);
}
void RobotShip::hitByGravitonCannon(Common::Point impactPoint) {
GameState.setMarsHitRobotWithCannon(true);
((Mars *)g_neighborhood)->decreaseRobotShuttleEnergy(6, impactPoint);
}
void RobotShip::snareByTractorBeam() {
_dropJunkFuse.stopFuse();
stop();
Common::Point currentV;
dHermite(_p1, _p4, _r1, _r4, _lastTime, _duration, currentV);
_p1 = _currentLocation;
_r1 = currentV;
_p4.x = kShuttleWindowMidH;
_p4.y = kShuttleWindowMidV;
_r4.x = 0;
_r4.y = 0;
_duration = kTractorBeamTime;
_snaring = true;
setSegment(0, _duration);
setTime(0);
start();
}
void RobotShip::timeChanged(const TimeValue) {
Common::Point newLocation;
hermite(_p1, _p4, _r1, _r4, _lastTime, _duration, newLocation);
moveRobotTo(newLocation.x, newLocation.y);
if (_lastTime == _duration) {
if (_snaring)
stop();
else
newDestination();
}
}
void RobotShip::makeVelocityVector(CoordType x1, CoordType y1, CoordType x2, CoordType y2, Common::Point &vector) {
CoordType length = g_vm->getRandomNumber(kVelocityVectorSlop - 1) + kVelocityVectorLength;
vector.x = x2 - x1;
vector.y = y2 - y1;
float oldLength = sqrt((float)(vector.x * vector.x + vector.y * vector.y));
vector.x = (int)(vector.x * length / oldLength);
vector.y = (int)(vector.y * length / oldLength);
}
} // End of namespace Pegasus

View File

@@ -0,0 +1,83 @@
/* 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 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef PEGASUS_NEIGHBORHOOD_MARS_ROBOTSHIP_H
#define PEGASUS_NEIGHBORHOOD_MARS_ROBOTSHIP_H
#include "pegasus/movie.h"
namespace Pegasus {
static const CoordType kShuttleMovieWidth = 114;
static const CoordType kShuttleMovieHeight = 42;
class RobotShip : IdlerTimeBase {
public:
RobotShip();
~RobotShip() override;
void initRobotShip();
void cleanUpRobotShip();
void startMoving();
void killRobotShip();
bool pointInShuttle(Common::Point&);
void hitByEnergyBeam(Common::Point impactPoint);
void hitByGravitonCannon(Common::Point impactPoint);
void getShuttleBounds(Common::Rect &r) { _spritesMovie.getBounds(r); }
void setGlowing(const bool glowing) { _spritesMovie.setGlowing(glowing); }
void snareByTractorBeam();
bool isSnared() { return _snaring && getTime() == _duration; }
bool isDead() { return _dead; }
void setUpNextDropTime();
protected:
void newDestination();
void moveRobotTo(CoordType, CoordType);
void timeToDropJunk();
void timeChanged(const TimeValue) override;
void makeVelocityVector(CoordType, CoordType, CoordType, CoordType, Common::Point &);
GlowingMovie _spritesMovie;
Common::Rect _shipRange;
int _shipWidth, _shipHeight;
Common::Point _p1, _p4, _r1, _r4, _currentLocation;
FuseFunction _dropJunkFuse;
TimeValue _duration;
bool _snaring, _dead;
};
extern RobotShip *g_robotShip;
} // End of namespace Pegasus
#endif

View File

@@ -0,0 +1,115 @@
/* 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 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "pegasus/neighborhood/mars/constants.h"
#include "pegasus/neighborhood/mars/shuttleenergymeter.h"
namespace Pegasus {
ShuttleEnergyMeter::ShuttleEnergyMeter() : FaderAnimation(kNoDisplayElement) {
setBounds(kShuttleEnergyLeft, kShuttleEnergyTop, kShuttleEnergyLeft + kShuttleEnergyWidth,
kShuttleEnergyTop + kShuttleEnergyHeight);
setDisplayOrder(kShuttleStatusOrder);
setFaderValue(0);
}
void ShuttleEnergyMeter::initShuttleEnergyMeter() {
_meterImage.getImageFromPICTFile("Images/Mars/Shuttle Energy.pict");
_lowWarning.getImageFromPICTFile("Images/Mars/Shuttle Low Energy.pict");
startDisplaying();
show();
}
void ShuttleEnergyMeter::disposeShuttleEnergyMeter() {
stopFader();
hide();
stopDisplaying();
_meterImage.deallocateSurface();
_lowWarning.deallocateSurface();
}
void ShuttleEnergyMeter::draw(const Common::Rect &) {
int32 currentValue = getFaderValue();
Common::Rect r1, r2, bounds;
getBounds(bounds);
if (currentValue < kLowShuttleEnergy) {
_lowWarning.getSurfaceBounds(r1);
r2 = r1;
r2.moveTo(bounds.left, bounds.top);
_lowWarning.copyToCurrentPort(r1, r2);
}
_meterImage.getSurfaceBounds(r1);
r1.right = r1.left + r1.width() * currentValue / kFullShuttleEnergy;
r2 = r1;
r2.moveTo(bounds.left + 102, bounds.top + 6);
_meterImage.copyToCurrentPort(r1, r2);
}
void ShuttleEnergyMeter::powerUpMeter() {
FaderMoveSpec moveSpec;
moveSpec.makeTwoKnotFaderSpec(kThirtyTicksPerSecond, 0, 0, 45, kFullShuttleEnergy);
startFader(moveSpec);
}
void ShuttleEnergyMeter::setEnergyValue(const int32 value) {
stopFader();
FaderMoveSpec moveSpec;
moveSpec.makeTwoKnotFaderSpec(kFifteenTicksPerSecond, value * 3, value, kFullShuttleEnergy * 3, kFullShuttleEnergy);
startFader(moveSpec);
}
void ShuttleEnergyMeter::drainForTractorBeam() {
stopFader();
TimeValue startTime = 0, stopTime;
int32 startValue = getFaderValue(), stopValue;
if (startValue < kTractorBeamEnergy) {
stopTime = startValue * kTractorBeamTime / kTractorBeamEnergy;
stopValue = 0;
} else {
stopTime = kTractorBeamTime;
stopValue = startValue - kTractorBeamEnergy;
}
FaderMoveSpec moveSpec;
moveSpec.makeTwoKnotFaderSpec(kTractorBeamScale, startTime, startValue, stopTime, stopValue);
startFader(moveSpec);
}
int32 ShuttleEnergyMeter::getEnergyValue() const {
return getFaderValue();
}
void ShuttleEnergyMeter::dropEnergyValue(const int32 delta) {
setEnergyValue(getFaderValue() - delta);
}
bool ShuttleEnergyMeter::enoughEnergyForTractorBeam() const {
return getEnergyValue() >= kTractorBeamEnergy;
}
} // End of namespace Pegasus

View File

@@ -0,0 +1,72 @@
/* 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 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef PEGASUS_NEIGHBORHOOD_MARS_SHUTTLEENERGYMETER_H
#define PEGASUS_NEIGHBORHOOD_MARS_SHUTTLEENERGYMETER_H
#include "pegasus/fader.h"
#include "pegasus/surface.h"
namespace Pegasus {
static const int32 kFullShuttleEnergy = 100;
// Low is 20 percent
static const int32 kLowShuttleEnergy = kFullShuttleEnergy * 20 / 100;
static const int32 kMinDampingEnergy = 15;
static const int32 kMinGravitonEnergy = 63;
static const TimeScale kTractorBeamScale = kFifteenTicksPerSecond;
static const TimeValue kTractorBeamTime = kFiveSeconds * kTractorBeamScale;
static const int32 kTractorBeamEnergy = kLowShuttleEnergy;
class ShuttleEnergyMeter : public FaderAnimation {
public:
ShuttleEnergyMeter();
~ShuttleEnergyMeter() override {}
void initShuttleEnergyMeter();
void disposeShuttleEnergyMeter();
void powerUpMeter();
void setEnergyValue(const int32);
int32 getEnergyValue() const;
void dropEnergyValue(const int32);
void drainForTractorBeam();
bool enoughEnergyForTractorBeam() const;
void draw(const Common::Rect &) override;
protected:
Surface _meterImage;
Surface _lowWarning;
};
} // End of namespace Pegasus
#endif

View File

@@ -0,0 +1,247 @@
/* 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 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "pegasus/pegasus.h"
#include "pegasus/neighborhood/mars/constants.h"
#include "pegasus/neighborhood/mars/robotship.h"
#include "pegasus/neighborhood/mars/shuttlehud.h"
namespace Pegasus {
enum {
kHUDTargetGridLeft = kShuttleWindowLeft + 16,
kHUDTargetGridTop = kShuttleWindowTop + 8,
kHUDTargetGridWidth = 328,
kHUDTargetGridHeight = 206,
kHUDRS232Left = kHUDTargetGridLeft + 264,
kHUDRS232Top = kHUDTargetGridTop + 2,
kHUDLockLeft = kShuttleWindowLeft + 101,
kHUDLockTop = kShuttleWindowTop + 49,
kHUDLockWidth = 145,
kHUDLockHeight = 124,
kTractorLockWidth = 50,
kTractorLockHeight = 30,
kTractorLockLeft = kShuttleWindowMidH - kTractorLockWidth / 2,
kTractorLockTop = kShuttleWindowMidV - kTractorLockHeight / 2,
kTractorLockRight = kTractorLockLeft + kTractorLockWidth,
kTractorLockBottom = kTractorLockTop + kTractorLockHeight
};
static const uint16 s_RS232Data[] = {
0xF0E1, 0xCE70,
0xF9E1, 0xEF78,
0x4900, 0x2108,
0x79C0, 0xE738,
0x70E1, 0xC770,
0x5821, 0x0140,
0x4DE1, 0xEF78,
0x45C1, 0xEE78
};
static const uint16 s_lockData[] = {
0xE007, 0xFE1F, 0xF8E0, 0x7000,
0xE00F, 0xFF3F, 0xFCE0, 0xE000,
0xE00E, 0x0738, 0x1CE1, 0xC000,
0xE00E, 0x0738, 0x00FF, 0x8000,
0xE00E, 0x0738, 0x00FF, 0x0000,
0xE00E, 0x0738, 0x00E3, 0x8000,
0xE00E, 0x0738, 0x1CE1, 0xC000,
0xFFCF, 0xFF3F, 0xFCE0, 0xE000,
0xFFC7, 0xFE1F, 0xF8E0, 0x7000
};
#define drawHUDLockLine(x1, y1, x2, y2, penX, penY, color) \
screen->drawThickLine((x1) + kHUDLockLeft, (y1) + kHUDLockTop, \
(x2) + kHUDLockLeft, (y2) + kHUDLockTop, penX, penY, color)
#define drawHUDLockArrows(offset, color) \
drawHUDLockLine(63, 0 + (offset), 68, 5 + (offset), 1, 3, color); \
drawHUDLockLine(71, 8 + (offset), 77, 14 + (offset), 1, 3, color); \
drawHUDLockLine(78, 14 + (offset), 84, 8 + (offset), 1, 3, color); \
drawHUDLockLine(87, 5 + (offset), 92, 0 + (offset), 1, 3, color); \
drawHUDLockLine(63, 121 - (offset), 68, 116 - (offset), 1, 3, color); \
drawHUDLockLine(71, 113 - (offset), 77, 107 - (offset), 1, 3, color); \
drawHUDLockLine(78, 107 - (offset), 84, 113 - (offset), 1, 3, color); \
drawHUDLockLine(87, 116 - (offset), 92, 121 - (offset), 1, 3, color); \
\
drawHUDLockLine(13 + (offset), 47, 18 + (offset), 52, 3, 1, color); \
drawHUDLockLine(21 + (offset), 55, 27 + (offset), 61, 3, 1, color); \
drawHUDLockLine(27 + (offset), 62, 21 + (offset), 68, 3, 1, color); \
drawHUDLockLine(18 + (offset), 71, 13 + (offset), 76, 3, 1, color); \
drawHUDLockLine(142 - (offset), 47, 137 - (offset), 52, 3, 1, color); \
drawHUDLockLine(134 - (offset), 55, 128 - (offset), 61, 3, 1, color); \
drawHUDLockLine(128 - (offset), 62, 134 - (offset), 68, 3, 1, color); \
drawHUDLockLine(137 - (offset), 71, 142 - (offset), 76, 3, 1, color)
ShuttleHUD::ShuttleHUD() : DisplayElement(kNoDisplayElement) {
_lightGreen = g_system->getScreenFormat().RGBToColor(0, 204, 0);
_gridDarkGreen = g_system->getScreenFormat().RGBToColor(0, 85, 0);
_lockDarkGreen1 = g_system->getScreenFormat().RGBToColor(0, 68, 0);
_lockDarkGreen2 = g_system->getScreenFormat().RGBToColor(0, 65, 0);
_targetLocked = false;
setBounds(kShuttleWindowLeft, kShuttleWindowTop, kShuttleWindowLeft + kShuttleWindowWidth,
kShuttleWindowTop + kShuttleWindowHeight);
setDisplayOrder(kShuttleHUDOrder);
}
void ShuttleHUD::initShuttleHUD() {
startDisplaying();
startIdling();
}
void ShuttleHUD::cleanUpShuttleHUD() {
stopIdling();
stopDisplaying();
}
void ShuttleHUD::showTargetGrid() {
show();
}
void ShuttleHUD::hideTargetGrid() {
hide();
unlockOnTarget();
}
void ShuttleHUD::useIdleTime() {
if (isVisible()) {
Common::Rect r;
g_robotShip->getShuttleBounds(r);
if (r.left < kTractorLockRight && r.right > kTractorLockLeft && r.top < kTractorLockBottom && r.bottom > kTractorLockTop)
lockOnTarget();
else
unlockOnTarget();
}
}
void ShuttleHUD::lockOnTarget() {
if (!_targetLocked) {
_targetLocked = true;
triggerRedraw();
}
}
void ShuttleHUD::unlockOnTarget() {
if (_targetLocked) {
_targetLocked = false;
triggerRedraw();
}
}
void ShuttleHUD::draw(const Common::Rect &) {
Graphics::Surface *screen = g_vm->_gfx->getWorkArea();
for (int y = 0; y < 35; y++) {
Common::Rect r;
if (y & 1) {
if (y == 17) {
r = Common::Rect(0, 0, 4, 2);
r.moveTo(kHUDTargetGridLeft + 8, y * 6 + kHUDTargetGridTop);
screen->fillRect(r, _gridDarkGreen);
r.moveTo(kHUDTargetGridLeft + kHUDTargetGridWidth - 12, y * 6 + kHUDTargetGridTop);
screen->fillRect(r, _gridDarkGreen);
r = Common::Rect(0, 0, 6, 2);
r.moveTo(kHUDTargetGridLeft + 2, y * 6 + kHUDTargetGridTop);
screen->fillRect(r, _lightGreen);
r.moveTo(kHUDTargetGridLeft + kHUDTargetGridWidth - 8, y * 6 + kHUDTargetGridTop);
screen->fillRect(r, _lightGreen);
r = Common::Rect(0, 0, 23, 2);
r.moveTo(kHUDTargetGridLeft + 12, y * 6 + kHUDTargetGridTop);
screen->fillRect(r, _lightGreen);
r.moveTo(kHUDTargetGridLeft + kHUDTargetGridWidth - 35, y * 6 + kHUDTargetGridTop);
screen->fillRect(r, _lightGreen);
} else if (y == 1 || y == 15 || y == 19 || y == 33) {
r = Common::Rect(0, 0, 4, 2);
r.moveTo(kHUDTargetGridLeft + 2, y * 6 + kHUDTargetGridTop);
screen->fillRect(r, _gridDarkGreen);
r.moveTo(kHUDTargetGridLeft + kHUDTargetGridWidth - 6, y * 6 + kHUDTargetGridTop);
screen->fillRect(r, _gridDarkGreen);
r = Common::Rect(0, 0, 15, 2);
r.moveTo(kHUDTargetGridLeft + 8, y * 6 + kHUDTargetGridTop);
screen->fillRect(r, _gridDarkGreen);
r.moveTo(kHUDTargetGridLeft + kHUDTargetGridWidth - 23, y * 6 + kHUDTargetGridTop);
screen->fillRect(r, _gridDarkGreen);
} else {
r = Common::Rect(0, 0, 4, 2);
r.moveTo(kHUDTargetGridLeft + 2, y * 6 + kHUDTargetGridTop);
screen->fillRect(r, _gridDarkGreen);
r.moveTo(kHUDTargetGridLeft + kHUDTargetGridWidth - 6, y * 6 + kHUDTargetGridTop);
screen->fillRect(r, _gridDarkGreen);
r = Common::Rect(0, 0, 10, 2);
r.moveTo(kHUDTargetGridLeft + 8, y * 6 + kHUDTargetGridTop);
screen->fillRect(r, _gridDarkGreen);
r.moveTo(kHUDTargetGridLeft + kHUDTargetGridWidth - 18, y * 6 + kHUDTargetGridTop);
screen->fillRect(r, _gridDarkGreen);
}
} else {
r = Common::Rect(0, 0, 2, 2);
r.moveTo(kHUDTargetGridLeft, y * 6 + kHUDTargetGridTop);
screen->fillRect(r, _gridDarkGreen);
r.moveTo(kHUDTargetGridLeft + kHUDTargetGridWidth - 2, y * 6 + kHUDTargetGridTop);
screen->fillRect(r, _gridDarkGreen);
r = Common::Rect(0, 0, 4, 2);
r.moveTo(kHUDTargetGridLeft + 8, y * 6 + kHUDTargetGridTop);
screen->fillRect(r, _gridDarkGreen);
r.moveTo(kHUDTargetGridLeft + kHUDTargetGridWidth - 12, y * 6 + kHUDTargetGridTop);
screen->fillRect(r, _gridDarkGreen);
}
}
drawOneBitImageOr(screen, s_RS232Data, 2, Common::Rect(kHUDRS232Left, kHUDRS232Top,
kHUDRS232Left + 29, kHUDRS232Top + 8), _gridDarkGreen);
if (_targetLocked) {
drawHUDLockArrows(0, _lockDarkGreen2);
drawHUDLockArrows(12, _lockDarkGreen1);
drawHUDLockArrows(24, _lightGreen);
drawOneBitImageOr(screen, s_lockData, 4, Common::Rect(kHUDLockLeft, kHUDLockTop + 115,
kHUDLockLeft + 52, kHUDLockTop + 115 + 9), _lightGreen);
}
}
void ShuttleHUD::drawOneBitImageOr(Graphics::Surface *screen, const uint16 *data, int pitch, const Common::Rect &bounds, uint32 color) {
for (int y = 0; y < bounds.height(); y++) {
for (int x = 0; x < bounds.width(); x++) {
if ((data[y * pitch + x / 16] & (1 << (15 - (x % 16)))) != 0) {
if (screen->format.bytesPerPixel == 2)
WRITE_UINT16((byte *)screen->getBasePtr(x + bounds.left, y + bounds.top), color);
else
WRITE_UINT32((byte *)screen->getBasePtr(x + bounds.left, y + bounds.top), color);
}
}
}
}
} // End of namespace Pegasus

View File

@@ -0,0 +1,59 @@
/* 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 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef PEGASUS_NEIGHBORHOOD_MARS_SHUTTLEHUD_H
#define PEGASUS_NEIGHBORHOOD_MARS_SHUTTLEHUD_H
#include "pegasus/elements.h"
#include "pegasus/timers.h"
namespace Pegasus {
class ShuttleHUD : public DisplayElement, public Idler {
public:
ShuttleHUD();
void showTargetGrid();
void hideTargetGrid();
void initShuttleHUD();
void cleanUpShuttleHUD();
bool isTargetLocked() { return _targetLocked; }
void draw(const Common::Rect &) override;
protected:
void useIdleTime() override;
void lockOnTarget();
void unlockOnTarget();
void drawOneBitImageOr(Graphics::Surface *, const uint16 *, int, const Common::Rect &, uint32);
bool _targetLocked;
uint32 _lightGreen, _gridDarkGreen, _lockDarkGreen1, _lockDarkGreen2;
};
} // End of namespace Pegasus
#endif

View File

@@ -0,0 +1,128 @@
/* 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 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "pegasus/neighborhood/mars/constants.h"
#include "pegasus/neighborhood/mars/robotship.h"
#include "pegasus/neighborhood/mars/shuttleweapon.h"
#include "pegasus/neighborhood/mars/spacejunk.h"
namespace Pegasus {
ShuttleWeapon::ShuttleWeapon() : IdlerAnimation(kNoDisplayElement) {
setScale(kShuttleWeaponScale);
_weaponDuration = kShuttleWeaponScale * 2;
setSegment(0, _weaponDuration);
setBounds(kShuttleWindowLeft, kShuttleWindowTop, kShuttleWindowLeft + kShuttleWindowWidth,
kShuttleWindowTop + kShuttleWindowHeight);
setDisplayOrder(kShuttleWeaponFrontOrder);
}
void ShuttleWeapon::initShuttleWeapon() {
startDisplaying();
}
void ShuttleWeapon::cleanUpShuttleWeapon() {
stop();
hide();
stopDisplaying();
}
bool ShuttleWeapon::canFireWeapon() {
return !isRunning();
}
void ShuttleWeapon::fireWeapon(const CoordType hStop, const CoordType vStop) {
if (!isRunning()) {
stop();
setTime(0);
show();
Common::Point pt2D(hStop, vStop);
project2DTo3D(pt2D, kShuttleDistance, _weaponTarget);
_weaponTime = 0;
setDisplayOrder(kShuttleWeaponFrontOrder);
start();
}
}
void ShuttleWeapon::updateWeaponPosition() {
_weaponTime = (float)_lastTime / _weaponDuration;
linearInterp(_weaponOrigin, _weaponTarget, _weaponTime, _weaponLocation);
if (_weaponTime == 1.0) {
stop();
hide();
} else {
triggerRedraw();
}
}
void ShuttleWeapon::timeChanged(const TimeValue) {
updateWeaponPosition();
bool hit = false;
Common::Point impactPoint;
if (g_spaceJunk->isJunkFlying()) {
hit = collisionWithJunk(impactPoint);
if (hit) {
stop();
hide();
hitJunk(impactPoint);
}
}
if (!hit && _weaponTime == 1.0 && collisionWithShuttle(impactPoint))
hitShuttle(impactPoint);
}
bool ShuttleWeapon::collisionWithJunk(Common::Point &impactPoint) {
if (getDisplayOrder() == kShuttleWeaponFrontOrder) {
Point3D junkPosition;
g_spaceJunk->getJunkPosition(junkPosition);
if (junkPosition.z < _weaponLocation.z) {
setDisplayOrder(kShuttleWeaponBackOrder);
project3DTo2D(_weaponLocation, impactPoint);
return g_spaceJunk->pointInJunk(impactPoint);
}
}
return false;
}
bool ShuttleWeapon::collisionWithShuttle(Common::Point &impactPoint) {
project3DTo2D(_weaponLocation, impactPoint);
return g_robotShip->pointInShuttle(impactPoint);
}
void ShuttleWeapon::hitJunk(Common::Point impactPoint) {
g_spaceJunk->hitByEnergyBeam(impactPoint);
}
void ShuttleWeapon::hitShuttle(Common::Point impactPoint) {
g_robotShip->hitByEnergyBeam(impactPoint);
}
} // End of namespace Pegasus

View File

@@ -0,0 +1,67 @@
/* 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 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef PEGASUS_NEIGHBORHOOD_MARS_SHUTTLEWEAPON_H
#define PEGASUS_NEIGHBORHOOD_MARS_SHUTTLEWEAPON_H
#include "pegasus/elements.h"
#include "pegasus/neighborhood/mars/spacechase3d.h"
namespace Pegasus {
// Can fire multiple times?
// For now, no...
// clone2727 adds: And now forever
static const TimeScale kShuttleWeaponScale = kFifteenTicksPerSecond;
class ShuttleWeapon : public IdlerAnimation {
public:
ShuttleWeapon();
~ShuttleWeapon() override {}
virtual void initShuttleWeapon();
virtual void cleanUpShuttleWeapon();
virtual void fireWeapon(const CoordType, const CoordType);
bool canFireWeapon();
protected:
void timeChanged(const TimeValue) override;
virtual void updateWeaponPosition();
virtual bool collisionWithJunk(Common::Point &impactPoint);
bool collisionWithShuttle(Common::Point &impactPoint);
virtual void hitJunk(Common::Point impactPoint);
virtual void hitShuttle(Common::Point impactPoint);
Point3D _weaponOrigin, _weaponTarget;
Point3D _weaponLocation;
float _weaponTime;
TimeValue _weaponDuration;
};
} // End of namespace Pegasus
#endif

View File

@@ -0,0 +1,105 @@
/* 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 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "pegasus/neighborhood/mars/spacechase3d.h"
namespace Pegasus {
void project3DTo2D(const Point3D &pt3D, Common::Point &pt2D) {
pt2D.x = (int)convertSpaceXToScreenH(pt3D.x, pt3D.z);
pt2D.y = (int)convertSpaceYToScreenV(pt3D.y, pt3D.z);
}
void project2DTo3D(const Common::Point &pt2D, const float screenDistance, Point3D &pt3D) {
pt3D.x = convertScreenHToSpaceX(pt2D.x, screenDistance);
pt3D.y = convertScreenVToSpaceY(pt2D.y, screenDistance);
pt3D.z = screenDistance;
}
void linearInterp(const Point3D &pt1, const Point3D &pt2, const float t, Point3D &pt3) {
pt3.x = pt1.x + (pt2.x - pt1.x) * t;
pt3.y = pt1.y + (pt2.y - pt1.y) * t;
pt3.z = pt1.z + (pt2.z - pt1.z) * t;
}
void linearInterp(const Point3D &pt1, const float x2, const float y2, const float z2, const float t, Point3D &pt3) {
pt3.x = pt1.x + (x2 - pt1.x) * t;
pt3.y = pt1.y + (y2 - pt1.y) * t;
pt3.z = pt1.z + (z2 - pt1.z) * t;
}
void linearInterp(const float x1, const float y1, const float z1, const Point3D &pt2, const float t, Point3D &pt3) {
pt3.x = x1 + (pt2.x - x1) * t;
pt3.y = y1 + (pt2.y - y1) * t;
pt3.z = z1 + (pt2.z - z1) * t;
}
void linearInterp(const float x1, const float y1, const float z1, const float x2, const float y2, const float z2,
const float t, Point3D &pt3) {
pt3.x = x1 + (x2 - x1) * t;
pt3.y = y1 + (y2 - y1) * t;
pt3.z = z1 + (z2 - z1) * t;
}
void linearInterp(const Common::Point &pt1, const Common::Point &pt2, const float t, Common::Point &pt3) {
pt3.x = (int)(pt1.x + (pt2.x - pt1.x) * t);
pt3.y = (int)(pt1.y + (pt2.y - pt1.y) * t);
}
void linearInterp(const Common::Point &pt1, const float h2, const float v2, const float t, Common::Point &pt3) {
pt3.x = (int)(pt1.x + (h2 - pt1.x) * t);
pt3.y = (int)(pt1.y + (v2 - pt1.y) * t);
}
void linearInterp(const float h1, const float v1, const Common::Point &pt2, const float t, Common::Point &pt3) {
pt3.x = (int)(h1 + (pt2.x - h1) * t);
pt3.y = (int)(v1 + (pt2.y - v1) * t);
}
void linearInterp(const float h1, const float v1, const float h2, const float v2, const float t, Common::Point &pt3) {
pt3.x = (int)(h1 + (h2 - h1) * t);
pt3.y = (int)(v1 + (v2 - v1) * t);
}
float linearInterp(const float arg1, const float arg2, const float t) {
return arg1 + (arg2 - arg1) * t;
}
bool isNegative(int a) {
return a < 0;
}
bool isPositive(int a) {
return a > 0;
}
int sign(int a) {
return isNegative(a) ? -1 : isPositive(a) ? 1 : 0;
}
bool sameSign(int a, int b) {
return sign(a) == sign(b);
}
} // End of namespace Pegasus

View File

@@ -0,0 +1,90 @@
/* 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 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef PEGASUS_NEIGHBORHOOD_MARS_SPACECHASE3D_H
#define PEGASUS_NEIGHBORHOOD_MARS_SPACECHASE3D_H
#include "pegasus/neighborhood/mars/constants.h"
namespace Pegasus {
// This is approximately right for a field of view of 72 degrees
// (Should be set to the tangent of FOV).
//static const float kTangentFOV = 0.76254;
static const float kTangentFOV = 1.0;
// Define these as macros and they can be used to define constants...
#define convertSpaceXToScreenH(x, z) \
((x) / (z) * (kScreenWidth / (2 * kTangentFOV)) + kShuttleWindowMidH)
#define convertSpaceYToScreenV(y, z) \
(kShuttleWindowMidV - (y) / (z) * (kScreenWidth / (2 * kTangentFOV)))
#define convertScreenHToSpaceX(x, d) \
(((2.0F * kTangentFOV) / kScreenWidth) * ((float)(x) - kShuttleWindowMidH) * (d))
#define convertScreenVToSpaceY(y, d) \
(((2.0F * kTangentFOV) / kScreenWidth) * ((float)kShuttleWindowMidV - (y)) * (d))
struct Point3D {
float x, y, z;
Point3D() : x(0), y(0), z(0) {}
Point3D(float x1, float y1, float z1) : x(x1), y(y1), z(z1) {}
bool operator==(const Point3D &p) const { return x == p.x && y == p.y && z == p.z; }
bool operator!=(const Point3D &p) const { return x != p.x || y != p.y || z != p.z; }
void translate(float dx, float dy, float dz) {
x += dx;
y += dy;
z += dz;
}
};
static const int kScreenWidth = kShuttleWindowWidth;
bool isNegative(int a);
bool isPositive(int a);
int sign(int a);
bool sameSign(int a, int b);
void project3DTo2D(const Point3D &pt3D, Common::Point &pt2D);
void project2DTo3D(const Common::Point &pt2D, const float screenDistance, Point3D &pt3D);
void linearInterp(const Point3D &pt1, const Point3D &pt2, const float t, Point3D &pt3);
void linearInterp(const Point3D &pt1, const float x2, const float y2, const float z2, const float t, Point3D &pt3);
void linearInterp(const float x1, const float y1, const float z1, const Point3D &pt2, const float t, Point3D &pt3);
void linearInterp(const float x1, const float y1, const float z1, const float x2,
const float y2, const float z2, const float t, Point3D &pt3);
void linearInterp(const Common::Point &pt1, const Common::Point &pt2, const float t, Common::Point &pt3);
void linearInterp(const Common::Point &pt1, const float h2, const float v2, const float t, Common::Point &pt3);
void linearInterp(const float h1, const float v1, const Common::Point &pt2, const float t, Common::Point &pt3);
void linearInterp(const float h1, const float v1, const float h2, const float v2, const float t, Common::Point &pt3);
float linearInterp(const float arg1, const float arg2, const float t);
} // End of namespace Pegasus
#endif

View File

@@ -0,0 +1,211 @@
/* 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 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "pegasus/pegasus.h"
#include "pegasus/neighborhood/mars/mars.h"
#include "pegasus/neighborhood/mars/spacejunk.h"
namespace Pegasus {
static const CoordType kMaxBounceSize = 90;
static const CoordType kBounceTargetHRange = 640 - kMaxBounceSize - 2;
static const CoordType kBounceTargetVRange = 480 - kMaxBounceSize - 2;
static const float kJunkXTarget = 0;
static const float kJunkYTarget = 0;
static const float kJunkZTarget = kJunkMinDistance;
SpaceJunk *g_spaceJunk = nullptr;
SpaceJunk::SpaceJunk(const DisplayElementID id) : ScalingMovie(id) {
_timer.setScale(kJunkTimeScale);
_bouncing = false;
g_spaceJunk = this;
}
SpaceJunk::~SpaceJunk() {
g_spaceJunk = nullptr;
}
void SpaceJunk::launchJunk(int16 whichJunk, CoordType xOrigin, CoordType yOrigin) {
_bouncing = false;
TimeValue startTime = whichJunk * 16 * 40;
TimeValue stopTime = startTime + 16 * 40;
_launchPoint = Point3D(convertScreenHToSpaceX(xOrigin, kJunkMaxDistance),
convertScreenVToSpaceY(yOrigin, kJunkMaxDistance), kJunkMaxDistance);
startIdling();
stop();
setFlags(0);
setSegment(startTime, stopTime);
setFlags(kLoopTimeBase);
setTime(startTime);
start();
show();
_timer.stop();
_timer.setSegment(0, kJunkTravelTime);
_timer.setTime(0);
// Force it to set up correctly from the get-go
useIdleTime();
_timer.start();
}
void SpaceJunk::setCenter(const CoordType centerX, const CoordType centerY) {
_center.x = centerX;
_center.y = centerY;
Common::Rect r;
getBounds(r);
r.moveTo(CLIP<int>(centerX - (r.width() >> 1), 0, 640 - r.width()), CLIP<int>(centerY - (r.height() >> 1), 0, 480 - r.height()));
setBounds(r);
}
void SpaceJunk::setScaleSize(const CoordType size) {
Common::Rect r;
r.left = _center.x - (size >> 1);
r.top = _center.y - (size >> 1);
r.right = r.left + size;
r.bottom = r.top + size;
setBounds(r);
}
void SpaceJunk::useIdleTime() {
if (_bouncing) {
TimeValue time = _timer.getTime();
Common::Point pt;
pt.x = linearInterp(0, _bounceTime, time, _bounceStart.x, _bounceStop.x);
pt.y = linearInterp(0, _bounceTime, time, _bounceStart.y, _bounceStop.y);
CoordType size = linearInterp(0, _bounceTime, time, _bounceSizeStart, _bounceSizeStop);
setCenter(pt.x, pt.y);
setScaleSize(size);
if (time == _bounceTime) {
stop();
stopIdling();
hide();
((Mars *)g_neighborhood)->setUpNextDropTime();
}
} else {
float t = (float)_timer.getTime() / kJunkTravelTime;
linearInterp(_launchPoint, kJunkXTarget, kJunkYTarget, kJunkZTarget, t, _junkPosition);
Common::Point pt2D;
project3DTo2D(_junkPosition, pt2D);
setCenter(pt2D.x, pt2D.y);
setScaleSize((int)(convertSpaceYToScreenV(_junkPosition.y - kJunkSize / 2, _junkPosition.z) -
convertSpaceYToScreenV(_junkPosition.y + kJunkSize / 2, _junkPosition.z)));
if (t == 1.0) {
rebound(kCollisionReboundTime);
((Mars *)g_neighborhood)->hitByJunk();
}
}
}
bool SpaceJunk::pointInJunk(const Common::Point &pt) {
Common::Rect r;
getBounds(r);
int dx = r.width() / 4;
int dy = r.height() / 4;
r.left += dx;
r.right -= dx;
r.top += dy;
r.top -= dy;
return r.contains(pt);
}
void SpaceJunk::rebound(const TimeValue reboundTime) {
Common::Rect bounds;
getBounds(bounds);
_bounceStart.x = (bounds.left + bounds.right) >> 1;
_bounceStart.y = (bounds.top + bounds.bottom) >> 1;
switch (g_vm->getRandomNumber(3)) {
case 0:
_bounceStop.x = kMaxBounceSize / 2 + 1 + g_vm->getRandomNumber(kBounceTargetHRange - 1);
_bounceStop.y = kMaxBounceSize / 2 + 1;
break;
case 1:
_bounceStop.x = kMaxBounceSize / 2 + 1 + g_vm->getRandomNumber(kBounceTargetHRange - 1);
_bounceStop.y = 480 - kMaxBounceSize / 2 + 1;
break;
case 2:
_bounceStop.x = kMaxBounceSize / 2 + 1;
_bounceStop.y = kMaxBounceSize / 2 + 1 + g_vm->getRandomNumber(kBounceTargetVRange - 1);
break;
case 3:
_bounceStop.x = 640 - kMaxBounceSize / 2 + 1;
_bounceStop.y = kMaxBounceSize / 2 + 1 + g_vm->getRandomNumber(kBounceTargetVRange - 1);
break;
default:
break;
}
_bounceSizeStart = bounds.width();
_bounceSizeStop = MIN(_bounceSizeStart, kMaxBounceSize);
_timer.stop();
_timer.setSegment(0, reboundTime);
_bounceTime = reboundTime;
_timer.setTime(0);
_timer.start();
_bouncing = true;
}
void SpaceJunk::hitByEnergyBeam(Common::Point) {
rebound(kWeaponReboundTime);
setGlowing(true);
g_vm->delayShell(1, 3);
setGlowing(false);
}
void SpaceJunk::hitByGravitonCannon(Common::Point impactPoint) {
stop();
stopIdling();
hide();
Common::Rect r;
getBounds(r);
r = Common::Rect::center(impactPoint.x, impactPoint.y, r.width(), r.height());
((Mars *)g_neighborhood)->showBigExplosion(r, kShuttleJunkOrder);
((Mars *)g_neighborhood)->setUpNextDropTime();
}
void SpaceJunk::getJunkPosition(Point3D &position) {
position = _junkPosition;
}
bool SpaceJunk::isJunkFlying() {
return isIdling();
}
} // End of namespace Pegasus

View File

@@ -0,0 +1,77 @@
/* 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 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef PEGASUS_NEIGHBORHOOD_MARS_SPACEJUNK_H
#define PEGASUS_NEIGHBORHOOD_MARS_SPACEJUNK_H
#include "pegasus/movie.h"
#include "pegasus/neighborhood/mars/constants.h"
#include "pegasus/neighborhood/mars/spacechase3d.h"
namespace Pegasus {
static const CoordType kJunkMaxScreenSize = 250;
static const float kJunkSize = convertScreenVToSpaceY(kShuttleWindowMidV - kJunkMaxScreenSize / 2, kJunkMinDistance) -
convertScreenVToSpaceY(kShuttleWindowMidV + kJunkMaxScreenSize / 2, kJunkMinDistance);
class SpaceJunk : public ScalingMovie, public Idler {
public:
SpaceJunk(const DisplayElementID);
~SpaceJunk() override;
void setCenter(const CoordType, const CoordType);
void setScaleSize(const CoordType);
void useIdleTime() override;
void launchJunk(int16, CoordType, CoordType);
void getJunkPosition(Point3D &);
bool isJunkFlying();
bool pointInJunk(const Common::Point &);
void hitByEnergyBeam(Common::Point impactPoint);
void hitByGravitonCannon(Common::Point impactPoint);
bool junkFlying() { return _timer.isRunning(); }
protected:
void rebound(const TimeValue);
TimeBase _timer;
Point3D _launchPoint, _junkPosition;
Common::Point _center;
bool _bouncing;
Common::Point _bounceStart, _bounceStop;
CoordType _bounceSizeStart, _bounceSizeStop;
TimeValue _bounceTime;
};
extern SpaceJunk *g_spaceJunk;
} // End of namespace Pegasus
#endif

View File

@@ -0,0 +1,138 @@
/* 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 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "pegasus/pegasus.h"
#include "pegasus/neighborhood/mars/constants.h"
#include "pegasus/neighborhood/mars/tractorbeam.h"
namespace Pegasus {
TractorBeam::TractorBeam() : DisplayElement(kNoDisplayElement) {
setBounds(kShuttleTractorLeft, kShuttleTractorTop, kShuttleTractorLeft + kShuttleTractorWidth,
kShuttleTractorTop + kShuttleTractorHeight);
setDisplayOrder(kShuttleTractorBeamOrder);
}
static const int kHalfWidth = kShuttleTractorWidth >> 1;
static const int kHalfHeight = kShuttleTractorHeight >> 1;
static const int kW3Vert = kHalfHeight * kHalfHeight * kHalfHeight;
static const int kW3Div2Vert = kW3Vert >> 1;
static const int kW3Horiz = kHalfWidth * kHalfWidth * kHalfWidth;
static const int kW3Div2Horiz = kW3Horiz >> 1;
static const int kMaxLevel = 50;
static const int kAVert = -2 * kMaxLevel;
static const int kBVert = 3 * kMaxLevel * kHalfHeight;
#define READ_PIXEL(ptr) \
if (screen->format.bytesPerPixel == 2) \
color = READ_UINT16(ptr); \
else \
color = READ_UINT32(ptr); \
screen->format.colorToRGB(color, r, g, b)
#define WRITE_PIXEL(ptr) \
color = screen->format.RGBToColor(r, g, b); \
if (screen->format.bytesPerPixel == 2) \
WRITE_UINT16(ptr, color); \
else \
WRITE_UINT32(ptr, color)
#define DO_BLEND(ptr) \
READ_PIXEL(ptr); \
g += (((0xff - g) * blendHoriz) >> 8); \
b += (((0xff - b) * blendHoriz) >> 8); \
WRITE_PIXEL(ptr)
void TractorBeam::draw(const Common::Rect &) {
Graphics::Surface *screen = g_vm->_gfx->getWorkArea();
// Set up vertical DDA.
int blendVert = 0;
int dVert = 0;
int d1Vert = kAVert + kBVert;
int d2Vert = 6 * kAVert + 2 * kBVert;
int d3Vert = 6 * kAVert;
byte *rowPtrTop = (byte *)screen->getBasePtr(_bounds.left, _bounds.top);
byte *rowPtrBottom = (byte *)screen->getBasePtr(_bounds.left, _bounds.top + ((kHalfHeight << 1) - 1));
for (int y = kHalfHeight; y > 0; y--) {
// Set up horizontal DDA
int A = -2 * blendVert;
int B = 3 * blendVert * kHalfWidth;
int blendHoriz = 0;
int dHoriz = 0;
int d1Horiz = A + B;
int d2Horiz = 6 * A + 2 * B;
int d3Horiz = 6 * A;
byte *pTopLeft = rowPtrTop;
byte *pTopRight = rowPtrTop + (kHalfWidth * 2 - 1) * screen->format.bytesPerPixel;
byte *pBottomLeft = rowPtrBottom;
byte *pBottomRight = rowPtrBottom + (kHalfWidth * 2 - 1) * screen->format.bytesPerPixel;
for (int x = kHalfWidth; x > 0; x--) {
byte r, g, b;
uint32 color;
DO_BLEND(pTopLeft);
DO_BLEND(pTopRight);
DO_BLEND(pBottomLeft);
DO_BLEND(pBottomRight);
pTopLeft += screen->format.bytesPerPixel;
pBottomLeft += screen->format.bytesPerPixel;
pTopRight -= screen->format.bytesPerPixel;
pBottomRight -= screen->format.bytesPerPixel;
while (dHoriz > kW3Div2Horiz) {
blendHoriz++;
dHoriz -= kW3Horiz;
}
dHoriz += d1Horiz;
d1Horiz += d2Horiz;
d2Horiz += d3Horiz;
}
rowPtrTop += screen->pitch;
rowPtrBottom -= screen->pitch;
while (dVert > kW3Div2Vert) {
blendVert++;
dVert -= kW3Vert;
}
dVert += d1Vert;
d1Vert += d2Vert;
d2Vert += d3Vert;
}
}
} // End of namespace Pegasus

View File

@@ -0,0 +1,42 @@
/* 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 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef PEGASUS_NEIGHBORHOOD_MARS_TRACTORBEAM_H
#define PEGASUS_NEIGHBORHOOD_MARS_TRACTORBEAM_H
#include "pegasus/elements.h"
namespace Pegasus {
class TractorBeam : public DisplayElement {
public:
TractorBeam();
~TractorBeam() override {}
void draw(const Common::Rect &) override;
};
} // End of namespace Pegasus
#endif

View File

@@ -0,0 +1,372 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* Additional copyright for this file:
* Copyright (C) 1995-2013 Presto Studios, Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "pegasus/pegasus.h"
#include "pegasus/items/biochips/arthurchip.h"
#include "pegasus/neighborhood/mars/tunnelpod.h"
#include "pegasus/neighborhood/mars/mars.h"
namespace Pegasus {
// Segment start and end points.
static const TimeValue kLaunchStart = 315754;
static const TimeValue kLaunchEnd = 319392;
static const TimeValue kBranch1MainStart = 0;
static const TimeValue kBranch1MainEnd = 3600;
static const TimeValue kBranch2MainStart = kBranch1MainEnd;
static const TimeValue kBranch2MainEnd = 13200;
static const TimeValue kBranch3MainStart = kBranch2MainEnd;
static const TimeValue kBranch3MainEnd = 20400;
static const TimeValue kFinishMainStart = kBranch3MainEnd;
static const TimeValue kFinishMainEnd = 30640;
static const TimeValue kBranch2AltStart = 0;
static const TimeValue kBranch2AltEnd = 13200;
static const TimeValue kBranch3AltStart = kBranch2AltEnd;
static const TimeValue kBranch3AltEnd = 22800;
static const TimeValue kFinishAltStart = kBranch3AltEnd;
static const TimeValue kFinishAltEnd = 33640;
// Tunnel state.
enum {
kTunnelLaunch,
kTunnelBranch1Left,
kTunnelBranch2Left,
kTunnelBranch2Right,
kTunnelBranch3Left,
kTunnelBranch3Right,
kTunnelFinish
};
TunnelPod::TunnelPod(Neighborhood *handler) : ChaseInteraction(kMarsTunnelPodInteractionID, handler,
kMarsTunnelPodNotificationID, g_vm), _tunnelMainMovie(kNoDisplayElement),
_tunnelAltMovie(kNoDisplayElement), _deathMovie(kNoDisplayElement) {
_currentMovie = nullptr;
_currentCallBack = nullptr;
}
void TunnelPod::setSoundFXLevel(const uint16 fxLevel) {
_tunnelMainMovie.setVolume(fxLevel);
_tunnelAltMovie.setVolume(fxLevel);
_deathMovie.setVolume(fxLevel);
}
void TunnelPod::openInteraction() {
((Mars *)_owner)->_navMovie.stop();
_tunnelCallBack.setNotification(&_chaseNotification);
_tunnelCallBack.initCallBack(&((Mars *)_owner)->_navMovie, kCallBackAtExtremes);
_tunnelCallBack.setCallBackFlag(kChaseEnteredBranchZone);
_tunnelCallBack.scheduleCallBack(kTriggerAtStop, 0, 0);
_tunnelMainMovie.initFromMovieFile("Images/Mars/Pod 2345M.mov");
_tunnelMainMovie.setVolume(g_vm->getSoundFXLevel());
_tunnelMainMovie.moveElementTo(kNavAreaLeft, kNavAreaTop);
_tunnelMainMovie.setDisplayOrder(kNavMovieOrder);
_tunnelMainCallBack.setNotification(&_chaseNotification);
_tunnelMainCallBack.initCallBack(&_tunnelMainMovie, kCallBackAtExtremes);
_tunnelMainCallBack.setCallBackFlag(kChaseEnteredBranchZone);
_tunnelMainCallBack.scheduleCallBack(kTriggerAtStop, 0, 0);
_tunnelAltMovie.initFromMovieFile("Images/Mars/Pod 345A.mov");
_tunnelAltMovie.setVolume(g_vm->getSoundFXLevel());
_tunnelAltMovie.moveElementTo(kNavAreaLeft, kNavAreaTop);
_tunnelAltMovie.setDisplayOrder(kNavMovieOrder);
_tunnelAltCallBack.setNotification(&_chaseNotification);
_tunnelAltCallBack.initCallBack(&_tunnelAltMovie, kCallBackAtExtremes);
_tunnelAltCallBack.setCallBackFlag(kChaseEnteredBranchZone);
_tunnelAltCallBack.scheduleCallBack(kTriggerAtStop, 0, 0);
_deathMovie.initFromMovieFile("Images/Mars/Pod 2D.mov");
_deathMovie.setVolume(g_vm->getSoundFXLevel());
_deathMovie.moveElementTo(kNavAreaLeft, kNavAreaTop);
_deathMovie.setDisplayOrder(kNavMovieOrder);
_deathCallBack.setNotification(&_chaseNotification);
_deathCallBack.initCallBack(&_deathMovie, kCallBackAtExtremes);
_deathCallBack.setCallBackFlag(kChaseFinished);
_deathCallBack.scheduleCallBack(kTriggerAtStop, 0 ,0);
ChaseInteraction::openInteraction();
_steerPict.setDisplayOrder(kNavMovieOrder + 1);
_steerPict.moveElementTo(kPodSteerLeft, kPodSteerTop);
}
void TunnelPod::initInteraction() {
_steerPict.startDisplaying();
_tunnelState = kTunnelLaunch;
((Mars *)_owner)->_navMovie.setSegment(kLaunchStart, kLaunchEnd - kDecisionTime);
((Mars *)_owner)->_navMovie.setTime(kLaunchStart);
((Mars *)_owner)->_navMovie.start();
_currentMovie = &((Mars *)_owner)->_navMovie;
_currentCallBack = &_tunnelCallBack;
ChaseInteraction::initInteraction();
if (g_arthurChip)
g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBB27", kArthurMarsTurnedOnTransport);
}
void TunnelPod::closeInteraction() {
((Mars *)_owner)->_navMovie.stop();
if (_tunnelState == kTunnelFinish) {
// Only bring nack the nav movie if we successfully finished the chase
((Mars *)_owner)->_navMovie.startDisplaying();
((Mars *)_owner)->_navMovie.show();
}
_tunnelCallBack.releaseCallBack();
_tunnelAltMovie.stop();
_tunnelAltMovie.stopDisplaying();
_tunnelAltMovie.releaseMovie();
_tunnelAltCallBack.releaseCallBack();
_deathMovie.stop();
_deathMovie.stopDisplaying();
_deathMovie.releaseMovie();
_deathCallBack.releaseCallBack();
ChaseInteraction::closeInteraction();
}
void TunnelPod::receiveNotification(Notification *notification, const NotificationFlags flags) {
if (notification == &_chaseNotification && flags == kChaseFinished) {
if (_tunnelState != kTunnelFinish) {
// We died
((Mars *)_owner)->die(kDeathCollidedWithPod);
} else {
((Mars *)_owner)->startUpFromFinishedTunnelPod();
}
}
ChaseInteraction::receiveNotification(notification, flags);
}
void TunnelPod::setUpBranch() {
TimeValue branchStart, branchEnd;
branchStart = 0;
branchEnd = 0;
switch (_tunnelState) {
case kTunnelLaunch:
branchStart = kLaunchEnd - kDecisionTime;
branchEnd = kLaunchEnd;
break;
case kTunnelBranch1Left:
branchStart = kBranch1MainEnd - kDecisionTime;
branchEnd = kBranch1MainEnd;
break;
case kTunnelBranch2Left:
branchStart = kBranch2AltEnd - kDecisionTime;
branchEnd = kBranch2AltEnd;
break;
case kTunnelBranch2Right:
branchStart = kBranch2MainEnd - kDecisionTime;
branchEnd = kBranch2MainEnd;
break;
case kTunnelBranch3Left:
branchStart = kBranch3MainEnd - kDecisionTime;
branchEnd = kBranch3MainEnd;
break;
case kTunnelBranch3Right:
branchStart = kBranch3AltEnd - kDecisionTime;
branchEnd = kBranch3AltEnd;
break;
default:
break;
}
_currentMovie->setSegment(branchStart, branchEnd);
_currentCallBack->setCallBackFlag(kChaseExitedBranchZone);
_currentCallBack->scheduleCallBack(kTriggerAtStop, 0, 0);
}
void TunnelPod::branchLeft() {
TimeValue branchStart, branchEnd;
NotificationFlags flag;
Movie *movie;
NotificationCallBack *callBack;
branchStart = 0;
branchEnd = 0;
flag = 0;
movie = nullptr;
callBack = nullptr;
switch (_tunnelState) {
case kTunnelLaunch:
branchStart = kBranch1MainStart;
branchEnd = kBranch1MainEnd - kDecisionTime;
_tunnelState = kTunnelBranch1Left;
flag = kChaseEnteredBranchZone;
movie = &_tunnelMainMovie;
callBack = &_tunnelMainCallBack;
break;
case kTunnelBranch1Left:
branchStart = kBranch2AltStart;
branchEnd = kBranch2AltEnd - kDecisionTime;
_tunnelState = kTunnelBranch2Left;
flag = kChaseEnteredBranchZone;
movie = &_tunnelAltMovie;
callBack = &_tunnelAltCallBack;
break;
case kTunnelBranch2Left:
case kTunnelBranch2Right:
branchStart = kBranch3MainStart;
branchEnd = kBranch3MainEnd - kDecisionTime;
_tunnelState = kTunnelBranch3Left;
flag = kChaseEnteredBranchZone;
movie = &_tunnelMainMovie;
callBack = &_tunnelMainCallBack;
break;
case kTunnelBranch3Left:
case kTunnelBranch3Right:
branchStart = kFinishAltStart;
branchEnd = kFinishAltEnd;
_tunnelState = kTunnelFinish;
flag = kChaseFinished;
movie = &_tunnelAltMovie;
callBack = &_tunnelAltCallBack;
break;
default:
break;
}
movie->setSegment(branchStart, branchEnd);
movie->setTime(branchStart);
switchTo(*movie, *callBack);
callBack->setCallBackFlag(flag);
callBack->scheduleCallBack(kTriggerAtStop, 0, 0);
}
void TunnelPod::branchRight() {
TimeValue branchStart, branchEnd;
NotificationFlags flag;
Movie *movie;
NotificationCallBack *callBack;
branchStart = 0;
branchEnd = 0;
flag = 0;
movie = nullptr;
callBack = nullptr;
switch (_tunnelState) {
case kTunnelLaunch:
switchTo(_deathMovie, _deathCallBack);
return;
case kTunnelBranch1Left:
branchStart = kBranch2MainStart;
branchEnd = kBranch2MainEnd - kDecisionTime;
_tunnelState = kTunnelBranch2Right;
flag = kChaseEnteredBranchZone;
movie = &_tunnelMainMovie;
callBack = &_tunnelMainCallBack;
break;
case kTunnelBranch2Left:
case kTunnelBranch2Right:
branchStart = kBranch3AltStart;
branchEnd = kBranch3AltEnd - kDecisionTime;
_tunnelState = kTunnelBranch3Right;
flag = kChaseEnteredBranchZone;
movie = &_tunnelAltMovie;
callBack = &_tunnelAltCallBack;
break;
case kTunnelBranch3Left:
case kTunnelBranch3Right:
branchStart = kFinishMainStart;
branchEnd = kFinishMainEnd;
_tunnelState = kTunnelFinish;
flag = kChaseFinished;
movie = &_tunnelMainMovie;
callBack = &_tunnelMainCallBack;
break;
default:
break;
}
movie->setSegment(branchStart, branchEnd);
movie->setTime(branchStart);
switchTo(*movie, *callBack);
callBack->setCallBackFlag(flag);
callBack->scheduleCallBack(kTriggerAtStop, 0, 0);
}
void TunnelPod::dontBranch() {
switch (_tunnelState) {
case kTunnelLaunch:
case kTunnelBranch1Left:
if (_currentMovie == &_tunnelAltMovie)
branchLeft();
else
branchRight();
break;
case kTunnelBranch2Left:
case kTunnelBranch2Right:
if (_currentMovie == &_tunnelAltMovie)
branchRight();
else
branchLeft();
break;
case kTunnelBranch3Left:
case kTunnelBranch3Right:
if (_currentMovie == &_tunnelAltMovie)
branchLeft();
else
branchRight();
break;
default:
break;
}
}
void TunnelPod::switchTo(Movie &movie, NotificationCallBack &callBack) {
if (_currentMovie != &movie) {
if (_currentMovie != nullptr) {
_currentMovie->stop();
_currentMovie->hide();
_currentMovie->stopDisplaying();
}
_currentMovie = &movie;
_currentMovie->startDisplaying();
_currentMovie->show();
_currentMovie->start();
}
if (_currentCallBack != &callBack) {
_currentCallBack = &callBack;
}
}
} // End of namespace Pegasus

View File

@@ -0,0 +1,75 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* Additional copyright for this file:
* Copyright (C) 1995-2013 Presto Studios, Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef PEGASUS_NEIGHBORHOOD_MARS_TUNNELPOD_H
#define PEGASUS_NEIGHBORHOOD_MARS_TUNNELPOD_H
#include "pegasus/chase.h"
#include "pegasus/movie.h"
namespace Pegasus {
class Mars;
class TunnelPod : public ChaseInteraction {
friend class Mars;
friend struct MusicTimerEvent;
public:
TunnelPod(Neighborhood *);
virtual ~TunnelPod() {}
void setSoundFXLevel(const uint16);
protected:
void openInteraction();
void initInteraction();
void closeInteraction();
void receiveNotification(Notification *, const NotificationFlags);
void setUpBranch();
void branchLeft();
void branchRight();
void dontBranch();
void switchTo(Movie &, NotificationCallBack &);
Movie _tunnelMainMovie;
Movie _tunnelAltMovie;
Movie _deathMovie;
NotificationCallBack _tunnelCallBack;
NotificationCallBack _tunnelMainCallBack;
NotificationCallBack _tunnelAltCallBack;
NotificationCallBack _deathCallBack;
Movie *_currentMovie;
NotificationCallBack *_currentCallBack;
short _tunnelState;
};
} // End of namespace Pegasus
#endif