aboutsummaryrefslogtreecommitdiff
path: root/engines
diff options
context:
space:
mode:
authorMatthew Hoops2011-09-16 19:06:22 -0400
committerMatthew Hoops2011-09-16 19:06:22 -0400
commitda74436aa4d1c25f5120caa75197c2c4d9e0d1bc (patch)
tree0bf1df507774652ad57bbcbfa81b87849854d6ca /engines
parent2ae8a97c4d915b04e9824f2478812041e4c088f0 (diff)
downloadscummvm-rg350-da74436aa4d1c25f5120caa75197c2c4d9e0d1bc.tar.gz
scummvm-rg350-da74436aa4d1c25f5120caa75197c2c4d9e0d1bc.tar.bz2
scummvm-rg350-da74436aa4d1c25f5120caa75197c2c4d9e0d1bc.zip
PEGASUS: Implement fader support
Diffstat (limited to 'engines')
-rwxr-xr-xengines/pegasus/fader.cpp214
-rwxr-xr-xengines/pegasus/fader.h130
-rw-r--r--engines/pegasus/module.mk1
-rwxr-xr-xengines/pegasus/sound.cpp13
-rwxr-xr-xengines/pegasus/sound.h9
-rwxr-xr-xengines/pegasus/timers.h1
6 files changed, 352 insertions, 16 deletions
diff --git a/engines/pegasus/fader.cpp b/engines/pegasus/fader.cpp
new file mode 100755
index 0000000000..c3cfe9d263
--- /dev/null
+++ b/engines/pegasus/fader.cpp
@@ -0,0 +1,214 @@
+/* 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/fader.h"
+#include "pegasus/util.h"
+
+namespace Pegasus {
+
+Fader::Fader() {
+ _currentValue = 0;
+ _currentFaderMove._numKnots = 0;
+}
+
+void Fader::setFaderValue(const uint32 newValue) {
+ _currentValue = newValue;
+}
+
+bool Fader::initFaderMove(const FaderMoveSpec &spec) {
+ bool faderMoves = false;
+ uint32 value = 0;
+
+ if (spec._numKnots > 0) {
+ stopFader();
+ value = spec._knots[0].knotValue;
+ TimeValue startTime = spec._knots[0].knotTime;
+
+ if (startTime != 0xffffffff) {
+ if (spec._numKnots > 1) {
+ TimeValue stopTime = spec._knots[spec._numKnots - 1].knotTime;
+
+ if (spec._faderScale > 0) {
+ if (stopTime > startTime) {
+ for (uint32 i = 1; i < spec._numKnots; ++i) {
+ if (spec._knots[i - 1].knotValue != spec._knots[i].knotValue) {
+ faderMoves = true;
+ break;
+ }
+ }
+
+ if (faderMoves)
+ _currentFaderMove = spec;
+ } else if (spec._knots[spec._numKnots - 1].knotValue != value) {
+ value = spec._knots[spec._numKnots - 1].knotValue;
+ }
+ }
+ }
+ }
+ }
+
+ setFaderValue(value);
+ return faderMoves;
+}
+
+void Fader::startFader(const FaderMoveSpec &spec) {
+ if (initFaderMove(spec)) {
+ setFlags(0);
+ setScale(spec._faderScale);
+ setSegment(spec._knots[0].knotTime, spec._knots[spec._numKnots - 1].knotTime);
+ setTime(spec._knots[0].knotTime);
+ start();
+ }
+}
+
+void Fader::startFaderSync(const FaderMoveSpec &spec) {
+ if (initFaderMove(spec)) {
+ setFlags(0);
+ setScale(spec._faderScale);
+ setSegment(spec._knots[0].knotTime, spec._knots[spec._numKnots - 1].knotTime);
+ setTime(spec._knots[0].knotTime);
+ start();
+
+ while (isFading())
+ useIdleTime();
+
+ // Once more, for good measure, to make sure that there are no boundary
+ // condition problems.
+ useIdleTime();
+ stopFader();
+ }
+}
+
+void Fader::loopFader(const FaderMoveSpec &spec) {
+ if (initFaderMove(spec)) {
+ setFlags(kLoopTimeBase);
+ setScale(spec._faderScale);
+ setSegment(spec._knots[0].knotTime, spec._knots[spec._numKnots - 1].knotTime);
+ setTime(spec._knots[0].knotTime);
+ start();
+ }
+}
+
+void Fader::stopFader() {
+ stop();
+}
+
+void Fader::pauseFader() {
+ stopFader();
+}
+
+void Fader::continueFader() {
+ if (getTime() < getStop())
+ start();
+}
+
+void Fader::timeChanged(const TimeValue newTime) {
+ if (_currentFaderMove._numKnots != 0) {
+ uint32 i;
+ for (i = 0; i < _currentFaderMove._numKnots; i++)
+ if (_currentFaderMove._knots[i].knotTime > newTime)
+ break;
+
+ uint32 newValue;
+ if (i == 0)
+ newValue = _currentFaderMove._knots[0].knotValue;
+ else if (i == _currentFaderMove._numKnots)
+ newValue = _currentFaderMove._knots[i - 1].knotValue;
+ else
+ newValue = linearInterp(_currentFaderMove._knots[i - 1].knotTime, _currentFaderMove._knots[i].knotTime, newTime, _currentFaderMove._knots[i - 1].knotValue, _currentFaderMove._knots[i].knotValue);
+
+ if (newValue != _currentValue)
+ setFaderValue(newValue);
+ }
+}
+
+void FaderMoveSpec::makeOneKnotFaderSpec(const uint32 knotValue) {
+ _numKnots = 1;
+ _knots[0].knotTime = 0;
+ _knots[0].knotValue = knotValue;
+}
+
+void FaderMoveSpec::makeTwoKnotFaderSpec(const TimeScale faderScale, const TimeValue time1, const uint32 value1, const TimeValue time2, const uint32 value2) {
+ _numKnots = 2;
+ _faderScale = faderScale;
+ _knots[0].knotTime = time1;
+ _knots[0].knotValue = value1;
+ _knots[1].knotTime = time2;
+ _knots[1].knotValue = value2;
+}
+
+void FaderMoveSpec::insertFaderKnot(const TimeValue knotTime, const uint32 knotValue) {
+ if (_numKnots != kMaxFaderKnots) {
+ uint32 index;
+ for (index = 0; index < _numKnots; index++) {
+ if (knotTime == _knots[index].knotTime) {
+ _knots[index].knotValue = knotValue;
+ return;
+ } else if (knotTime < _knots[index].knotTime) {
+ break;
+ }
+ }
+
+ for (uint32 i = _numKnots; i > index; i--)
+ _knots[i] = _knots[i - 1];
+
+ _knots[index].knotTime = knotTime;
+ _knots[index].knotValue = knotValue;
+ _numKnots++;
+ }
+}
+
+void FaderAnimation::setFaderValue(const uint32 newValue) {
+ if (getFaderValue() != newValue) {
+ Fader::setFaderValue(newValue);
+ triggerRedraw();
+ }
+}
+
+SoundFader::SoundFader() {
+ _sound = 0;
+ _masterVolume = 0xff;
+}
+
+void SoundFader::attachSound(Sound *sound) {
+ if (!sound && isFading())
+ stopFader();
+
+ _sound = sound;
+}
+
+void SoundFader::setFaderValue(const uint32 newVolume) {
+ if (_sound)
+ _sound->setVolume((newVolume * _masterVolume) >> 8);
+
+ _currentValue = newVolume;
+}
+
+void SoundFader::setMasterVolume(const uint16 masterVolume) {
+ _masterVolume = masterVolume;
+ setFaderValue(getFaderValue());
+}
+
+} // End of namespace Pegasus
diff --git a/engines/pegasus/fader.h b/engines/pegasus/fader.h
new file mode 100755
index 0000000000..5ca1a5c3e9
--- /dev/null
+++ b/engines/pegasus/fader.h
@@ -0,0 +1,130 @@
+/* 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_FADER_H
+#define PEGASUS_FADER_H
+
+#include "pegasus/elements.h"
+#include "pegasus/timers.h"
+
+namespace Pegasus {
+
+class Fader;
+
+class FaderMoveSpec {
+friend class Fader;
+public:
+ FaderMoveSpec() {
+ _faderScale = kDefaultTimeScale;
+ _numKnots = 0;
+ }
+
+ FaderMoveSpec(const TimeScale scale) {
+ _faderScale = scale;
+ _numKnots = 0;
+ }
+
+ void setFaderScale(const TimeScale scale) { _faderScale = scale; }
+ TimeScale getFaderScale() const { return _faderScale; }
+
+ void makeOneKnotFaderSpec(const uint32);
+ void makeTwoKnotFaderSpec(const TimeScale, const TimeValue, const uint32, const TimeValue, const uint32);
+
+ void insertFaderKnot(const TimeValue, const uint32);
+
+ uint32 getNumKnots() const { return _numKnots; }
+ uint32 getNthKnotTime(const uint32 index) const { return _knots[index].knotTime; }
+ uint32 getNthKnotValue(const uint32 index) const { return _knots[index].knotValue; }
+
+protected:
+ struct FaderKnot {
+ TimeValue knotTime;
+ uint32 knotValue;
+ };
+
+ TimeScale _faderScale;
+ uint32 _numKnots;
+
+ static const uint32 kMaxFaderKnots = 20;
+ FaderKnot _knots[kMaxFaderKnots];
+};
+
+class Fader : private IdlerTimeBase {
+public:
+ Fader();
+ virtual ~Fader() {}
+
+ virtual void setFaderValue(const uint32);
+ uint32 getFaderValue() const { return _currentValue; }
+ virtual void startFader(const FaderMoveSpec &);
+ virtual void startFaderSync(const FaderMoveSpec &);
+ virtual void loopFader(const FaderMoveSpec &);
+ virtual void stopFader();
+ virtual bool isFading() { return isRunning(); }
+
+ void pauseFader();
+ void continueFader();
+
+ void getCurrentFaderMove(FaderMoveSpec &spec) { spec = _currentFaderMove; }
+
+protected:
+ bool initFaderMove(const FaderMoveSpec &);
+ virtual void timeChanged(const TimeValue);
+
+ uint32 _currentValue;
+ FaderMoveSpec _currentFaderMove;
+};
+
+class FaderAnimation : public DisplayElement, public Fader {
+public:
+ FaderAnimation(const tDisplayElementID id) : DisplayElement(id) {}
+ virtual ~FaderAnimation() {}
+
+ void setFaderValue(const uint32);
+};
+
+class Sound;
+
+class SoundFader : public Fader {
+friend class Sound;
+public:
+ SoundFader();
+ virtual ~SoundFader() {}
+
+ void setFaderValue(const uint32);
+
+ void setMasterVolume(const uint16);
+ uint16 getMasterVolume() const { return _masterVolume; }
+
+protected:
+ void attachSound(Sound *);
+
+ Sound *_sound;
+ uint16 _masterVolume;
+};
+
+} // End of namespace Pegasus
+
+#endif
diff --git a/engines/pegasus/module.mk b/engines/pegasus/module.mk
index 0f697f397e..ca262cbc98 100644
--- a/engines/pegasus/module.mk
+++ b/engines/pegasus/module.mk
@@ -6,6 +6,7 @@ MODULE_OBJS = \
cursor.o \
detection.o \
elements.o \
+ fader.o \
gamestate.o \
graphics.o \
hotspot.o \
diff --git a/engines/pegasus/sound.cpp b/engines/pegasus/sound.cpp
index 5db1d90a3c..847106aa4d 100755
--- a/engines/pegasus/sound.cpp
+++ b/engines/pegasus/sound.cpp
@@ -29,6 +29,7 @@
#include "common/file.h"
#include "common/system.h"
+#include "pegasus/fader.h"
#include "pegasus/sound.h"
namespace Pegasus {
@@ -36,6 +37,7 @@ namespace Pegasus {
Sound::Sound() {
_stream = 0;
_volume = 0xFF;
+ _fader = 0;
}
Sound::~Sound() {
@@ -65,18 +67,15 @@ void Sound::initFromQuickTime(const Common::String &fileName) {
_stream = Audio::makeQuickTimeStream(fileName);
}
-#if 0
-// TODO!
void Sound::attachFader(SoundFader *fader) {
if (_fader)
- _fader->attachSound(NULL);
+ _fader->attachSound(0);
_fader = fader;
if (_fader)
_fader->attachSound(this);
}
-#endif
void Sound::playSound() {
if (!isSoundLoaded())
@@ -84,11 +83,8 @@ void Sound::playSound() {
stopSound();
-#if 0
- // TODO!
if (_fader)
setVolume(_fader->getFaderValue());
-#endif
g_system->getMixer()->playStream(Audio::Mixer::kPlainSoundType, &_handle, _stream, -1, _volume, 0, DisposeAfterUse::NO);
}
@@ -102,12 +98,9 @@ void Sound::loopSound() {
// Create a looping stream
Audio::AudioStream *loopStream = new Audio::LoopingAudioStream(_stream, 0, DisposeAfterUse::NO);
-#if 0
- // TODO!
// Assume that if there is a fader, we're going to fade the sound in.
if (_fader)
setVolume(0);
-#endif
g_system->getMixer()->playStream(Audio::Mixer::kPlainSoundType, &_handle, loopStream, -1, _volume, 0, DisposeAfterUse::YES);
}
diff --git a/engines/pegasus/sound.h b/engines/pegasus/sound.h
index 99607d432c..f66c3f4250 100755
--- a/engines/pegasus/sound.h
+++ b/engines/pegasus/sound.h
@@ -35,8 +35,7 @@ namespace Audio {
namespace Pegasus {
-// TODO!
-//class SoundFader;
+class SoundFader;
// Things you might want to do with sound:
// Start it
@@ -73,16 +72,14 @@ public:
void setVolume(const uint16 volume);
bool isPlaying();
- // TODO!
- //void attachFader(SoundFader *fader);
+ void attachFader(SoundFader *fader);
protected:
Audio::SeekableAudioStream *_stream;
Audio::SoundHandle _handle;
byte _volume;
- // TODO!
- //SoundFader *_fader;
+ SoundFader *_fader;
};
} // End of namespace Pegasus
diff --git a/engines/pegasus/timers.h b/engines/pegasus/timers.h
index 9ce3093820..52f420eb90 100755
--- a/engines/pegasus/timers.h
+++ b/engines/pegasus/timers.h
@@ -26,6 +26,7 @@
#ifndef PEGASUS_TIMERS_H
#define PEGASUS_TIMERS_H
+#include "common/list.h"
#include "common/rational.h"
#include "pegasus/constants.h"