From 59421ff1c67155e2236fb78b2b2290e63d2c613f Mon Sep 17 00:00:00 2001
From: Matthew Hoops
Date: Tue, 1 Nov 2011 21:11:21 -0400
Subject: PEGASUS: Add the ECR monitor

Panorama not 100% working yet, but the mask does :P
---
 engines/pegasus/module.mk                          |   1 +
 .../neighborhood/norad/alpha/ecrmonitor.cpp        | 218 +++++++++++++++++++++
 .../pegasus/neighborhood/norad/alpha/ecrmonitor.h  |  65 ++++++
 .../neighborhood/norad/alpha/noradalpha.cpp        |   5 +-
 4 files changed, 286 insertions(+), 3 deletions(-)
 create mode 100755 engines/pegasus/neighborhood/norad/alpha/ecrmonitor.cpp
 create mode 100755 engines/pegasus/neighborhood/norad/alpha/ecrmonitor.h

(limited to 'engines/pegasus')

diff --git a/engines/pegasus/module.mk b/engines/pegasus/module.mk
index e4f1172baa..d4ea537612 100644
--- a/engines/pegasus/module.mk
+++ b/engines/pegasus/module.mk
@@ -76,6 +76,7 @@ MODULE_OBJS = \
 	neighborhood/norad/pressuretracker.o \
 	neighborhood/norad/subcontrolroom.o \
 	neighborhood/norad/subplatform.o \
+	neighborhood/norad/alpha/ecrmonitor.o \
 	neighborhood/norad/alpha/fillingstation.o \
 	neighborhood/norad/alpha/noradalpha.o \
 	neighborhood/norad/alpha/panorama.o \
diff --git a/engines/pegasus/neighborhood/norad/alpha/ecrmonitor.cpp b/engines/pegasus/neighborhood/norad/alpha/ecrmonitor.cpp
new file mode 100755
index 0000000000..1dc770ae36
--- /dev/null
+++ b/engines/pegasus/neighborhood/norad/alpha/ecrmonitor.cpp
@@ -0,0 +1,218 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * Additional copyright for this file:
+ * Copyright (C) 1995-1997 Presto Studios, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "pegasus/pegasus.h"
+#include "pegasus/neighborhood/norad/norad.h"
+#include "pegasus/neighborhood/norad/alpha/ecrmonitor.h"
+
+namespace Pegasus {
+
+static const tNotificationFlags kECRSection1FinishedFlag = 1;
+static const tNotificationFlags kECRPanFinishedFlag = kECRSection1FinishedFlag << 1;
+static const tNotificationFlags kECRSection2FinishedFlag = kECRPanFinishedFlag << 1;
+static const tNotificationFlags kECRNotificationFlags = kECRSection1FinishedFlag |
+													kECRPanFinishedFlag |
+													kECRSection2FinishedFlag;
+
+static const TimeValue kSection1Start = 0;
+static const TimeValue kSection1Stop = 25;
+static const TimeValue kPanStart = 0;
+static const TimeValue kPanStop = 20;
+static const TimeValue kSection2Start = 26;
+static const TimeValue kSection2Stop = 1000;
+
+// Seems to be a good value for a 20 second pan.
+static const tCoordType kPanPixelsPerFrame = 8;
+
+// Interesting times are in seconds.
+static const TimeValue s_ECRInterestingTimes[] = {
+	0, 1, 2, 10, 25, 26, 56, 64, 72, 80, 88, 94, 102, 108, 116, 999
+};
+
+// Index into s_ECRInterestingTimes of interesting time before security pan.
+static const int kBeforePanTime = 3;
+
+// Index into s_ECRInterestingTimes of interesting time after security pan.
+static const int kAfterPanTime = 5;
+
+NoradAlphaECRMonitor::NoradAlphaECRMonitor(Neighborhood *nextHandler) : GameInteraction(kNoradECRMonitorInteractionID, nextHandler),
+		_ecrSlideShowNotification(kNoradECRNotificationID, (PegasusEngine *)g_engine), _ecrMovie(kECRSlideShowMovieID),
+		_ecrPan(kECRPanID) {
+}
+
+void NoradAlphaECRMonitor::receiveNotification(Notification *, const tNotificationFlags flags) {
+	if (flags & kECRSection1FinishedFlag)
+		ecrSection1Finished();
+	else if (flags & kECRPanFinishedFlag)
+		ecrPanFinished();
+	else if (flags & kECRSection2FinishedFlag)
+		ecrSection2Finished();
+}
+
+int NoradAlphaECRMonitor::findCurrentInterestingTime() {	
+	TimeValue time = _ecrMovie.getTime();
+	TimeScale scale = _ecrMovie.getScale();
+
+	for (int i = ARRAYSIZE(s_ECRInterestingTimes) - 1; i >= 0; i--)
+		if (time >= s_ECRInterestingTimes[i] * scale)
+			return i;
+
+	return 0;
+}
+
+void NoradAlphaECRMonitor::skipToNextInterestingTime() {
+	if (_ecrMovie.isRunning()) {
+		int interestingTime = findCurrentInterestingTime();
+		_ecrMovie.setTime(s_ECRInterestingTimes[interestingTime + 1] * _ecrMovie.getScale());
+		_ecrMovie.redrawMovieWorld();
+	} else if (_ecrPan.isRunning()) {
+		_ecrPanCallBack.cancelCallBack();
+		ecrPanFinished();
+	}
+}
+
+void NoradAlphaECRMonitor::skipToPreviousInterestingTime() {
+	if (_ecrPan.isRunning()) {
+		_ecrPan.stop();
+		_ecrPan.stopDisplaying();
+		_ecrPanCallBack.cancelCallBack();
+
+		_ecrMovieCallBack.setCallBackFlag(kECRSection1FinishedFlag);
+		_ecrMovieCallBack.scheduleCallBack(kTriggerAtStop, 0, 0);
+
+		TimeScale scale = _ecrMovie.getScale();
+		_ecrMovie.setSegment(kSection1Start * scale, kSection1Stop * scale + 1);
+		_ecrMovie.setTime(s_ECRInterestingTimes[kBeforePanTime] * scale);
+		_ecrMovie.start();
+	} else {
+		int interestingTime = findCurrentInterestingTime();
+
+		if (interestingTime == kAfterPanTime) {
+			_ecrMovieCallBack.cancelCallBack();
+			TimeScale scale = _ecrMovie.getScale();
+			_ecrMovie.setSegment(kSection1Start * scale, kSection1Stop * scale + 1);
+			_ecrMovie.setTime(kSection1Stop * scale);
+			ecrSection1Finished();
+		} else if (interestingTime == 0) {
+			_ecrMovie.setTime(kSection1Start * _ecrMovie.getScale());
+			_ecrMovie.redrawMovieWorld();
+		} else {
+			_ecrMovie.setTime(s_ECRInterestingTimes[interestingTime - 1] * _ecrMovie.getScale());
+			_ecrMovie.redrawMovieWorld();
+		}
+	}
+}
+
+void NoradAlphaECRMonitor::handleInput(const Input &input, const Hotspot *cursorSpot) {
+	if (isInteracting()) {
+		if (input.rightButtonDown())
+			skipToNextInterestingTime();
+		else if (input.leftButtonDown())
+			skipToPreviousInterestingTime();
+		else
+			InputHandler::handleInput(input, cursorSpot);
+	} else {
+		InputHandler::handleInput(input, cursorSpot);
+	}
+}
+
+void NoradAlphaECRMonitor::ecrSection1Finished() {
+	_ecrMovie.stop();
+	_ecrPanCallBack.setNotification(&_ecrSlideShowNotification);
+	_ecrPanCallBack.initCallBack(&_ecrPan, kCallBackAtExtremes);
+	_ecrPanCallBack.setCallBackFlag(kECRPanFinishedFlag);
+	_ecrSlideShowNotification.notifyMe(this, kECRNotificationFlags, kECRNotificationFlags);
+	_ecrPanCallBack.scheduleCallBack(kTriggerAtStop, 0, 0);
+	_ecrPan.startDisplaying();
+	_ecrPan.show();
+
+	TimeScale scale = _ecrPan.getScale();
+	_ecrPan.setSegment(kPanStart * scale, kPanStop * scale);
+	_ecrPan.setTime(0);
+	_ecrPan.start();
+}
+
+void NoradAlphaECRMonitor::ecrPanFinished() {	
+	_ecrPan.stop();
+	_ecrPan.stopDisplaying();
+	_ecrMovieCallBack.setCallBackFlag(kECRSection2FinishedFlag);
+	_ecrMovieCallBack.scheduleCallBack(kTriggerAtStop, 0, 0);
+
+	TimeScale scale = _ecrMovie.getScale();
+	_ecrMovie.setSegment(kSection2Start * scale, kSection2Stop * scale);
+	_ecrMovie.start();
+}
+
+void NoradAlphaECRMonitor::ecrSection2Finished() {
+	_ecrMovie.stop();
+	_ecrMovie.stopDisplaying();
+}
+
+void NoradAlphaECRMonitor::openInteraction() {
+	// Initialize the security pan.
+	_ecrPan.initFromMovieFile("Images/Norad Alpha/Security Pan.pano");
+	_ecrPan.initMaskFromPICTFile("Images/Norad Alpha/Security Pan Mask");
+	_ecrPan.setBounds(Common::Rect(kECRPanLeft, kECRPanTop, kECRPanRight, kECRPanBottom));
+	_ecrPan.setDisplayOrder(kECRPanOrder);
+	_ecrPan.setScale(15); // 15 fps.
+
+	// Begin the lame ECR slide show.
+	// clone2727: I didn't say it :P
+	_ecrMovie.initFromMovieFile("Images/Norad Alpha/ECR Monitor Movie");
+
+	_ecrMovieCallBack.setNotification(&_ecrSlideShowNotification);
+	_ecrMovieCallBack.initCallBack(&_ecrMovie, kCallBackAtExtremes);
+	_ecrMovieCallBack.setCallBackFlag(kECRSection1FinishedFlag);
+
+	_ecrSlideShowNotification.notifyMe(this, kECRNotificationFlags, kECRNotificationFlags);
+	_ecrMovieCallBack.scheduleCallBack(kTriggerAtStop, 0, 0);
+
+	_ecrMovie.moveElementTo(kECRSlideShowLeft, kECRSlideShowTop);
+	_ecrMovie.setDisplayOrder(kECRMonitorOrder);
+	_ecrMovie.startDisplaying();
+	_ecrMovie.show();
+	_ecrMovie.redrawMovieWorld();
+
+	TimeScale scale = _ecrMovie.getScale();	
+	_ecrMovie.setSegment(kSection1Start * scale, kSection1Stop * scale + 1);
+
+	_ecrMovie.start();
+}
+
+void NoradAlphaECRMonitor::closeInteraction() {
+	_ecrMovieCallBack.releaseCallBack();
+	_ecrMovie.stop();
+	_ecrMovie.stopDisplaying();
+	_ecrMovie.releaseMovie();
+	_ecrMovieCallBack.releaseCallBack();
+
+	_ecrPanCallBack.releaseCallBack();
+	_ecrPan.stop();
+	_ecrPan.stopDisplaying();
+	_ecrPan.releasePanorama();
+	_ecrPanCallBack.releaseCallBack();
+}
+
+} // End of namespace Pegasus
diff --git a/engines/pegasus/neighborhood/norad/alpha/ecrmonitor.h b/engines/pegasus/neighborhood/norad/alpha/ecrmonitor.h
new file mode 100755
index 0000000000..329dae7310
--- /dev/null
+++ b/engines/pegasus/neighborhood/norad/alpha/ecrmonitor.h
@@ -0,0 +1,65 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * Additional copyright for this file:
+ * Copyright (C) 1995-1997 Presto Studios, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef PEGASUS_NEIGHBORHOOD_NORAD_ALPHA_ecrMONITOR_H
+#define PEGASUS_NEIGHBORHOOD_NORAD_ALPHA_ecrMONITOR_H
+
+#include "pegasus/interaction.h"
+#include "pegasus/notification.h"
+#include "pegasus/neighborhood/norad/alpha/panoramascroll.h"
+
+namespace Pegasus {
+
+class NoradAlphaECRMonitor : public GameInteraction, public NotificationReceiver {
+public:
+	NoradAlphaECRMonitor(Neighborhood *);
+	virtual ~NoradAlphaECRMonitor() {}
+
+	virtual void handleInput(const Input &, const Hotspot *);
+
+protected:
+	virtual void openInteraction();
+	virtual void closeInteraction();
+
+	virtual void receiveNotification(Notification *, const tNotificationFlags);
+
+	void ecrSection1Finished();
+	void ecrPanFinished();
+	void ecrSection2Finished();
+
+	int findCurrentInterestingTime();
+	void skipToNextInterestingTime();
+	void skipToPreviousInterestingTime();
+
+	Notification _ecrSlideShowNotification;
+	Movie _ecrMovie;
+	NotificationCallBack _ecrMovieCallBack;
+	PanoramaScroll _ecrPan;
+	NotificationCallBack _ecrPanCallBack;
+};
+
+} // End of namespace Pegasus
+
+#endif
diff --git a/engines/pegasus/neighborhood/norad/alpha/noradalpha.cpp b/engines/pegasus/neighborhood/norad/alpha/noradalpha.cpp
index c12623f6cc..46bebf699a 100755
--- a/engines/pegasus/neighborhood/norad/alpha/noradalpha.cpp
+++ b/engines/pegasus/neighborhood/norad/alpha/noradalpha.cpp
@@ -29,6 +29,7 @@
 #include "pegasus/ai/ai_area.h"
 #include "pegasus/items/inventory/airmask.h"
 #include "pegasus/neighborhood/norad/subcontrolroom.h"
+#include "pegasus/neighborhood/norad/alpha/ecrmonitor.h"
 #include "pegasus/neighborhood/norad/alpha/fillingstation.h"
 #include "pegasus/neighborhood/norad/alpha/noradalpha.h"
 
@@ -212,9 +213,7 @@ void NoradAlpha::playClawMonitorIntro() {
 GameInteraction *NoradAlpha::makeInteraction(const tInteractionID interactionID) {
 	switch (interactionID) {
 	case kNoradECRMonitorInteractionID:
-		// TODO
-		warning("Unhandled ECR monitor interaction");
-		break;
+		return new NoradAlphaECRMonitor(this);
 	case kNoradFillingStationInteractionID:
 		return new NoradAlphaFillingStation(this);
 	}
-- 
cgit v1.2.3