aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xengines/pegasus/constants.h246
-rw-r--r--engines/pegasus/neighborhood/neighborhood.cpp125
-rw-r--r--engines/pegasus/neighborhood/neighborhood.h52
-rwxr-xr-xengines/pegasus/sound.cpp45
-rwxr-xr-xengines/pegasus/sound.h14
5 files changed, 466 insertions, 16 deletions
diff --git a/engines/pegasus/constants.h b/engines/pegasus/constants.h
index 7a63cfc9db..509c9f3892 100755
--- a/engines/pegasus/constants.h
+++ b/engines/pegasus/constants.h
@@ -221,6 +221,252 @@ const TimeValue kPlasmaImpactTime = kTwoSeconds;
const TimeValue kNoradAirMaskTimeLimit = kOneMinute + kFifteenSeconds;
+enum {
+ kButtonDownBit = 0,
+ kAutoButtonBit = 1,
+ kBitsPerButton = 2,
+
+ kButtonDownMask = 1 << kButtonDownBit,
+ kAutoButtonMask = 1 << kAutoButtonBit,
+
+ kButtonStateBits = kButtonDownMask | kAutoButtonMask,
+
+ kRawButtonUp = 0,
+ kRawButtonDown = kButtonDownMask | kAutoButtonMask,
+
+ kButtonUp = 0,
+ kButtonDown = kButtonDownMask,
+ kButtonAutoUp = kAutoButtonMask,
+ kButtonAutoDown = kButtonDownMask | kAutoButtonMask
+};
+
+enum {
+ kUpButtonNum = 0,
+ kLeftButtonNum = 1,
+ kDownButtonNum = 2,
+ kRightButtonNum = 3,
+ kLeftFireButtonNum = 4,
+ kRightFireButtonNum = 5,
+ kOneButtonNum = 6,
+ kTwoButtonNum = 7,
+ kThreeButtonNum = 8,
+ kFourButtonNum = 9,
+ kMod1ButtonNum = 10,
+ kMod2ButtonNum = 11,
+ kMod3ButtonNum = 12
+};
+
+enum {
+ kUpButtonShift = kUpButtonNum * kBitsPerButton,
+ kLeftButtonShift = kLeftButtonNum * kBitsPerButton,
+ kDownButtonShift = kDownButtonNum * kBitsPerButton,
+ kRightButtonShift = kRightButtonNum * kBitsPerButton,
+ kLeftFireButtonShift = kLeftFireButtonNum * kBitsPerButton,
+ kRightFireButtonShift = kRightFireButtonNum * kBitsPerButton,
+ kOneButtonShift = kOneButtonNum * kBitsPerButton,
+ kTwoButtonShift = kTwoButtonNum * kBitsPerButton,
+ kThreeButtonShift = kThreeButtonNum * kBitsPerButton,
+ kFourButtonShift = kFourButtonNum * kBitsPerButton,
+ kMod1ButtonShift = kMod1ButtonNum * kBitsPerButton,
+ kMod2ButtonShift = kMod2ButtonNum * kBitsPerButton,
+ kMod3ButtonShift = kMod3ButtonNum * kBitsPerButton
+};
+
+enum {
+ kAllUpBits = (kButtonUp << kUpButtonShift) |
+ (kButtonUp << kLeftButtonShift) |
+ (kButtonUp << kDownButtonShift) |
+ (kButtonUp << kRightButtonShift) |
+ (kButtonUp << kLeftFireButtonShift) |
+ (kButtonUp << kRightFireButtonShift) |
+ (kButtonUp << kOneButtonShift) |
+ (kButtonUp << kTwoButtonShift) |
+ (kButtonUp << kThreeButtonShift) |
+ (kButtonUp << kFourButtonShift) |
+ (kButtonUp << kMod1ButtonShift) |
+ (kButtonUp << kMod2ButtonShift) |
+ (kButtonUp << kMod3ButtonShift),
+ kDirectionBits = (kButtonDownMask << kUpButtonShift) |
+ (kButtonDownMask << kLeftButtonShift) |
+ (kButtonDownMask << kDownButtonShift) |
+ (kButtonDownMask << kRightButtonShift),
+ kButtonBits = (kButtonDownMask << kLeftFireButtonShift) |
+ (kButtonDownMask << kRightFireButtonShift) |
+ (kButtonDownMask << kOneButtonShift) |
+ (kButtonDownMask << kTwoButtonShift) |
+ (kButtonDownMask << kThreeButtonShift) |
+ (kButtonDownMask << kFourButtonShift) |
+ (kButtonDownMask << kMod1ButtonShift) |
+ (kButtonDownMask << kMod2ButtonShift) |
+ (kButtonDownMask << kMod3ButtonShift),
+ kAllButtonDownBits = kDirectionBits | kButtonBits,
+ kAllAutoBits = (kAutoButtonMask << kUpButtonShift) |
+ (kAutoButtonMask << kLeftButtonShift) |
+ (kAutoButtonMask << kDownButtonShift) |
+ (kAutoButtonMask << kRightButtonShift) |
+ (kAutoButtonMask << kLeftFireButtonShift) |
+ (kAutoButtonMask << kRightFireButtonShift) |
+ (kAutoButtonMask << kOneButtonShift) |
+ (kAutoButtonMask << kTwoButtonShift) |
+ (kAutoButtonMask << kThreeButtonShift) |
+ (kAutoButtonMask << kFourButtonShift) |
+ (kAutoButtonMask << kMod1ButtonShift) |
+ (kAutoButtonMask << kMod2ButtonShift) |
+ (kAutoButtonMask << kMod3ButtonShift),
+
+ kFilterUpButton = kButtonDownMask << kUpButtonShift,
+ kFilterUpAuto = kAutoButtonMask << kUpButtonShift,
+ kFilterUpButtonAny = kFilterUpButton | kFilterUpAuto,
+ kFilterLeftButton = kButtonDownMask << kLeftButtonShift,
+ kFilterLeftAuto = kAutoButtonMask << kLeftButtonShift,
+ kFilterLeftButtonAny = kFilterLeftButton | kFilterLeftAuto,
+ kFilterDownButton = kButtonDownMask << kDownButtonShift,
+ kFilterDownAuto = kAutoButtonMask << kDownButtonShift,
+ kFilterDownButtonAny = kFilterDownButton | kFilterDownAuto,
+ kFilterRightButton = kButtonDownMask << kRightButtonShift,
+ kFilterRightAuto = kAutoButtonMask << kRightButtonShift,
+ kFilterRightButtonAny = kFilterRightButton | kFilterRightAuto,
+ kFilterLeftFireButton = kButtonDownMask << kLeftFireButtonShift,
+ kFilterLeftFireAuto = kAutoButtonMask << kLeftFireButtonShift,
+ kFilterLeftFireButtonAny = kFilterLeftFireButton | kFilterLeftFireAuto,
+ kFilterRightFireButton = kButtonDownMask << kRightFireButtonShift,
+ kFilterRightFireAuto = kAutoButtonMask << kRightFireButtonShift,
+ kFilterRightFireButtonAny = kFilterRightFireButton | kFilterRightFireAuto,
+ kFilterOneButton = kButtonDownMask << kOneButtonShift,
+ kFilterOneAuto = kAutoButtonMask << kOneButtonShift,
+ kFilterOneButtonAny = kFilterOneButton | kFilterOneAuto,
+ kFilterTwoButton = kButtonDownMask << kTwoButtonShift,
+ kFilterTwoAuto = kAutoButtonMask << kTwoButtonShift,
+ kFilterTwoButtonAny = kFilterTwoButton | kFilterTwoAuto,
+ kFilterThreeButton = kButtonDownMask << kThreeButtonShift,
+ kFilterThreeAuto = kAutoButtonMask << kThreeButtonShift,
+ kFilterThreeButtonAny = kFilterThreeButton | kFilterThreeAuto,
+ kFilterFourButton = kButtonDownMask << kFourButtonShift,
+ kFilterFourAuto = kAutoButtonMask << kFourButtonShift,
+ kFilterFourButtonAny = kFilterFourButton | kFilterFourAuto,
+ kFilterMod1Button = kButtonDownMask << kMod1ButtonShift,
+ kFilterMod1Auto = kAutoButtonMask << kMod1ButtonShift,
+ kFilterMod1ButtonAny = kFilterMod1Button | kFilterMod1Auto,
+ kFilterMod2Button = kButtonDownMask << kMod2ButtonShift,
+ kFilterMod2Auto = kAutoButtonMask << kMod2ButtonShift,
+ kFilterMod2ButtonAny = kFilterMod2Button | kFilterMod2Auto,
+ kFilterMod3Button = kButtonDownMask << kMod3ButtonShift,
+ kFilterMod3Auto = kAutoButtonMask << kMod3ButtonShift,
+ kFilterMod3ButtonAny = kFilterMod3Button | kFilterMod3Auto,
+
+ kFilterNoInput = 0,
+ kFilterAllInput = kFilterUpButton |
+ kFilterUpAuto |
+ kFilterLeftButton |
+ kFilterLeftAuto |
+ kFilterDownButton |
+ kFilterDownAuto |
+ kFilterRightButton |
+ kFilterRightAuto |
+ kFilterLeftFireButton |
+ kFilterLeftFireAuto |
+ kFilterRightFireButton |
+ kFilterRightFireAuto |
+ kFilterOneButton |
+ kFilterOneAuto |
+ kFilterTwoButton |
+ kFilterTwoAuto |
+ kFilterThreeButton |
+ kFilterThreeAuto |
+ kFilterFourButton |
+ kFilterFourAuto |
+ kFilterMod1Button |
+ kFilterMod1Auto |
+ kFilterMod2Button |
+ kFilterMod2Auto |
+ kFilterMod3Button |
+ kFilterMod3Auto,
+
+ kFilterAllDirections = kFilterUpButton |
+ kFilterUpAuto |
+ kFilterLeftButton |
+ kFilterLeftAuto |
+ kFilterDownButton |
+ kFilterDownAuto |
+ kFilterRightButton |
+ kFilterRightAuto,
+
+ kFilterButtons = kFilterOneButton |
+ kFilterOneAuto |
+ kFilterTwoButton |
+ kFilterTwoAuto |
+ kFilterThreeButton |
+ kFilterThreeAuto |
+ kFilterFourButton |
+ kFilterFourAuto,
+
+ kFilterFireButtons = kFilterLeftFireButton |
+ kFilterLeftFireAuto |
+ kFilterRightFireButton |
+ kFilterRightFireAuto,
+
+ kFilterAllButtons = kFilterLeftFireButton |
+ kFilterLeftFireAuto |
+ kFilterRightFireButton |
+ kFilterRightFireAuto |
+ kFilterOneButton |
+ kFilterOneAuto |
+ kFilterTwoButton |
+ kFilterTwoAuto |
+ kFilterThreeButton |
+ kFilterThreeAuto |
+ kFilterFourButton |
+ kFilterFourAuto |
+ kFilterMod1Button |
+ kFilterMod1Auto |
+ kFilterMod2Button |
+ kFilterMod2Auto |
+ kFilterMod3Button |
+ kFilterMod3Auto,
+
+ kFilterAllInputNoAuto = kFilterUpButton |
+ kFilterLeftButton |
+ kFilterDownButton |
+ kFilterRightButton |
+ kFilterLeftFireButton |
+ kFilterRightFireButton |
+ kFilterOneButton |
+ kFilterTwoButton |
+ kFilterThreeButton |
+ kFilterFourButton |
+ kFilterMod1Button |
+ kFilterMod2Button |
+ kFilterMod3Button
+};
+
+const tNotificationID kNeighborhoodNotificationID = 1;
+const tNotificationID kLastNeighborhoodNotificationID = kNeighborhoodNotificationID;
+
+const tNotificationFlags kNeighborhoodMovieCompletedFlag = 1;
+const tNotificationFlags kMoveForwardCompletedFlag = kNeighborhoodMovieCompletedFlag << 1;
+const tNotificationFlags kStrideCompletedFlag = kMoveForwardCompletedFlag << 1;
+const tNotificationFlags kTurnCompletedFlag = kStrideCompletedFlag << 1;
+const tNotificationFlags kSpotCompletedFlag = kTurnCompletedFlag << 1;
+const tNotificationFlags kDoorOpenCompletedFlag = kSpotCompletedFlag << 1;
+const tNotificationFlags kExtraCompletedFlag = kDoorOpenCompletedFlag << 1;
+const tNotificationFlags kSpotSoundCompletedFlag = kExtraCompletedFlag << 1;
+const tNotificationFlags kDelayCompletedFlag = kSpotSoundCompletedFlag << 1;
+const tNotificationFlags kActionRequestCompletedFlag = kDelayCompletedFlag << 1;
+const tNotificationFlags kDeathExtraCompletedFlag = kActionRequestCompletedFlag << 1;
+const tNotificationFlags kLastNeighborhoodNotificationFlag = kDeathExtraCompletedFlag;
+
+const tNotificationFlags kNeighborhoodFlags = kNeighborhoodMovieCompletedFlag |
+ kMoveForwardCompletedFlag |
+ kStrideCompletedFlag |
+ kTurnCompletedFlag |
+ kSpotCompletedFlag |
+ kDoorOpenCompletedFlag |
+ kExtraCompletedFlag |
+ kSpotSoundCompletedFlag |
+ kDelayCompletedFlag |
+ kActionRequestCompletedFlag |
+ kDeathExtraCompletedFlag;
+
} // End of namespace Pegasus
#endif
diff --git a/engines/pegasus/neighborhood/neighborhood.cpp b/engines/pegasus/neighborhood/neighborhood.cpp
index 1a22831f5e..cf4a29ee15 100644
--- a/engines/pegasus/neighborhood/neighborhood.cpp
+++ b/engines/pegasus/neighborhood/neighborhood.cpp
@@ -32,9 +32,10 @@
namespace Pegasus {
-Neighborhood::Neighborhood(PegasusEngine *vm, const Common::String &resName, tNeighborhoodID id) : _vm(vm), _resName(resName) {
+Neighborhood::Neighborhood(PegasusEngine *vm, const Common::String &resName, tNeighborhoodID id) : MMIDObject(id), _vm(vm), _resName(resName) {
GameState.setOpenDoorLocation(kNoRoomID, kNoDirection);
_currentAlternate = 0;
+ _interruptionFilter = kFilterAllInput;
}
Neighborhood::~Neighborhood() {
@@ -96,6 +97,7 @@ void Neighborhood::init() {
delete stream;
createNeighborhoodSpots();
+ loadSoundSpots();
// TODO: AI, movies, notifications, buncha other stuff
}
@@ -268,4 +270,125 @@ void Neighborhood::createNeighborhoodSpots() {
delete hotspotList;
}
+void Neighborhood::loadSoundSpots() {
+ // TODO: Eventually push to the subclasses
+
+ Common::String fileName = "Sounds/";
+
+ switch (getObjectID()) {
+ case kCaldoriaID:
+ fileName += "Caldoria/Caldoria Spots";
+ break;
+ case kFullTSAID:
+ case kFinalTSAID:
+ case kTinyTSAID:
+ fileName += "TSA/TSA Spots";
+ break;
+ case kPrehistoricID:
+ fileName += "Prehistoric/Prehistoric Spots";
+ break;
+ case kMarsID:
+ fileName += "Mars/Mars Spots";
+ break;
+ case kWSCID:
+ fileName += "World Science Center/WSC Spots";
+ break;
+ case kNoradAlphaID:
+ fileName += "Norad/Norad Alpha Spots";
+ break;
+ case kNoradDeltaID:
+ fileName += "Norad/Norad Delta Spots";
+ break;
+ }
+
+ _spotSounds.initFromQuickTime(fileName);
+}
+
+void Neighborhood::popActionQueue() {
+ if (!_actionQueue.empty()) {
+ tQueueRequest topRequest = _actionQueue.pop();
+
+ switch (topRequest.requestType) {
+ case kNavExtraRequest:
+ // TODO
+ break;
+ case kSpotSoundRequest:
+ _spotSounds.stopSound();
+ break;
+ case kDelayRequest:
+ // TODO
+ break;
+ }
+
+ serviceActionQueue();
+ }
+}
+
+void Neighborhood::serviceActionQueue() {
+ if (!_actionQueue.empty()) {
+ tQueueRequest &topRequest = _actionQueue.front();
+
+ if (!topRequest.playing) {
+ topRequest.playing = true;
+ switch (topRequest.requestType) {
+ case kNavExtraRequest:
+ // TODO
+ break;
+ case kSpotSoundRequest:
+ _spotSounds.stopSound();
+ _spotSounds.playSoundSegment(topRequest.start, topRequest.stop);
+ _interruptionFilter = topRequest.interruptionFilter;
+ // TODO: stop trigger
+ break;
+ case kDelayRequest:
+ // TODO
+ break;
+ }
+ }
+ } else {
+ _interruptionFilter = kFilterAllInput;
+ }
+}
+
+void Neighborhood::requestAction(const tQueueRequestType requestType, const tExtraID extra, const TimeValue in, const TimeValue out,
+ const tInputBits interruptionFilter, const tNotificationFlags flags) {
+
+ tQueueRequest request;
+
+ request.requestType = requestType;
+ request.extra = extra;
+ request.start = in;
+ request.stop = out;
+ request.interruptionFilter = interruptionFilter;
+ request.playing = false;
+ request.flags = flags | kActionRequestCompletedFlag;
+
+ // TODO: notification
+
+ _actionQueue.push(request);
+ if (_actionQueue.size() == 1)
+ serviceActionQueue();
+}
+
+void Neighborhood::requestExtraSequence(const tExtraID whichExtra, const tNotificationFlags flags, const tInputBits interruptionFilter) {
+ requestAction(kNavExtraRequest, whichExtra, 0, 0, interruptionFilter, flags);
+}
+
+void Neighborhood::requestSpotSound(const TimeValue in, const TimeValue out, const tInputBits interruptionFilter, const tNotificationFlags flags) {
+ requestAction(kSpotSoundRequest, 0xFFFFFFFF, in, out, interruptionFilter, flags);
+}
+
+void Neighborhood::requestDelay(const TimeValue delayDuration, const TimeScale delayScale, const tInputBits interruptionFilter, const tNotificationFlags flags) {
+ requestAction(kDelayRequest, 0xFFFFFFFF, delayDuration, delayScale, interruptionFilter, flags);
+}
+
+bool operator==(const tQueueRequest &arg1, const tQueueRequest &arg2) {
+ return arg1.requestType == arg2.requestType && arg1.extra == arg2.extra &&
+ arg1.start == arg2.start && arg1.stop == arg2.stop;
+}
+
+bool operator!=(const tQueueRequest &arg1, const tQueueRequest &arg2) {
+ return !operator==(arg1, arg2);
+}
+
} // End of namespace Pegasus
diff --git a/engines/pegasus/neighborhood/neighborhood.h b/engines/pegasus/neighborhood/neighborhood.h
index 73f6c49d3c..269443c6af 100644
--- a/engines/pegasus/neighborhood/neighborhood.h
+++ b/engines/pegasus/neighborhood/neighborhood.h
@@ -26,9 +26,12 @@
#ifndef PEGASUS_NEIGHBORHOOD_H
#define PEGASUS_NEIGHBORHOOD_H
+#include "common/queue.h"
#include "common/str.h"
#include "pegasus/hotspot.h"
+#include "pegasus/sound.h"
+#include "pegasus/MMShell/Utilities/MMIDObject.h"
#include "pegasus/neighborhood/door.h"
#include "pegasus/neighborhood/exit.h"
#include "pegasus/neighborhood/extra.h"
@@ -40,6 +43,7 @@
namespace Pegasus {
+class MMNotification;
class PegasusEngine;
// Pegasus Prime neighborhood id's
@@ -52,11 +56,35 @@ const tNeighborhoodID kMarsID = 5;
const tNeighborhoodID kWSCID = 6;
const tNeighborhoodID kNoradAlphaID = 7;
const tNeighborhoodID kNoradDeltaID = 8;
-// The sub chase is not really a neighborhood, but we define a constant that is used
-// to allow an easy transition out of Norad Alpha.
+// The sub chase is not really a neighborhood, but we define a constant that is used
+// to allow an easy transition out of Norad Alpha.
const tNeighborhoodID kNoradSubChaseID = 1000;
-class Neighborhood {
+enum tQueueRequestType {
+ kNavExtraRequest,
+ kSpotSoundRequest,
+ kDelayRequest
+};
+
+// For delay requests, start is interpreted as the total delay and stop is interpreted
+// as the scale the delay is in.
+// For extra requests, start and stop are not used.
+struct tQueueRequest {
+ tQueueRequestType requestType;
+ tExtraID extra;
+ TimeValue start, stop;
+ tInputBits interruptionFilter;
+ bool playing;
+ tNotificationFlags flags;
+ MMNotification *notification;
+};
+
+bool operator==(const tQueueRequest &arg1, const tQueueRequest &arg2);
+bool operator!=(const tQueueRequest &arg1, const tQueueRequest &arg2);
+
+typedef Common::Queue<tQueueRequest> NeighborhoodActionQueue;
+
+class Neighborhood : public MMIDObject {
public:
Neighborhood(PegasusEngine *vm, const Common::String &resName, tNeighborhoodID id);
virtual ~Neighborhood();
@@ -79,12 +107,22 @@ public:
tCanTurnReason canTurn(tTurnDirection turn, tDirectionConstant &nextDir);
tCanOpenDoorReason canOpenDoor(DoorTable::Entry &entry);
+ void requestExtraSequence(const tExtraID, const tNotificationFlags, const tInputBits interruptionFilter);
+ void requestSpotSound(const TimeValue, const TimeValue, const tInputBits interruptionFilter, const tNotificationFlags);
+ void requestDelay(const TimeValue, const TimeScale, const tInputBits interruptionFilter, const tNotificationFlags);
+
+ virtual bool actionQueueEmpty() { return _actionQueue.empty(); }
+
protected:
virtual void createNeighborhoodSpots();
+ virtual void loadSoundSpots();
+
+ void popActionQueue();
+ void serviceActionQueue();
+ void requestAction(const tQueueRequestType, const tExtraID, const TimeValue, const TimeValue, const tInputBits, const tNotificationFlags);
PegasusEngine *_vm;
Common::String _resName;
- tNeighborhoodID _neighborhoodID;
DoorTable _doorTable;
ExitTable _exitTable;
@@ -98,6 +136,12 @@ protected:
tAlternateID _currentAlternate;
HotspotList _neighborhoodHotspots;
+
+ NeighborhoodActionQueue _actionQueue;
+
+ Sound _spotSounds;
+
+ tInputBits _interruptionFilter;
};
} // End of namespace Pegasus
diff --git a/engines/pegasus/sound.cpp b/engines/pegasus/sound.cpp
index 5fcac1134a..5db1d90a3c 100755
--- a/engines/pegasus/sound.cpp
+++ b/engines/pegasus/sound.cpp
@@ -25,6 +25,7 @@
#include "audio/audiostream.h"
#include "audio/decoders/aiff.h"
+#include "audio/decoders/quicktime.h"
#include "common/file.h"
#include "common/system.h"
@@ -33,7 +34,7 @@
namespace Pegasus {
Sound::Sound() {
- _aiffStream = 0;
+ _stream = 0;
_volume = 0xFF;
}
@@ -43,17 +44,25 @@ Sound::~Sound() {
void Sound::disposeSound() {
stopSound();
- delete _aiffStream; _aiffStream = 0;
+ delete _stream; _stream = 0;
}
void Sound::initFromAIFFFile(const Common::String &fileName) {
+ disposeSound();
+
Common::File *file = new Common::File();
if (!file->open(fileName)) {
delete file;
return;
}
- _aiffStream = Audio::makeAIFFStream(file, DisposeAfterUse::YES);
+ _stream = Audio::makeAIFFStream(file, DisposeAfterUse::YES);
+}
+
+void Sound::initFromQuickTime(const Common::String &fileName) {
+ disposeSound();
+
+ _stream = Audio::makeQuickTimeStream(fileName);
}
#if 0
@@ -81,7 +90,7 @@ void Sound::playSound() {
setVolume(_fader->getFaderValue());
#endif
- g_system->getMixer()->playStream(Audio::Mixer::kPlainSoundType, &_handle, _aiffStream, -1, _volume, 0, DisposeAfterUse::NO);
+ g_system->getMixer()->playStream(Audio::Mixer::kPlainSoundType, &_handle, _stream, -1, _volume, 0, DisposeAfterUse::NO);
}
void Sound::loopSound() {
@@ -91,7 +100,7 @@ void Sound::loopSound() {
stopSound();
// Create a looping stream
- Audio::AudioStream *loopStream = new Audio::LoopingAudioStream(_aiffStream, 0, DisposeAfterUse::NO);
+ Audio::AudioStream *loopStream = new Audio::LoopingAudioStream(_stream, 0, DisposeAfterUse::NO);
#if 0
// TODO!
@@ -103,7 +112,29 @@ void Sound::loopSound() {
g_system->getMixer()->playStream(Audio::Mixer::kPlainSoundType, &_handle, loopStream, -1, _volume, 0, DisposeAfterUse::YES);
}
-void Sound::stopSound(void) {
+void Sound::playSoundSegment(uint32 start, uint32 end) {
+ if (!isSoundLoaded())
+ return;
+
+ stopSound();
+
+ Audio::AudioStream *subStream = new Audio::SubSeekableAudioStream(_stream, Audio::Timestamp(0, start, 600), Audio::Timestamp(0, end, 600), DisposeAfterUse::NO);
+
+ g_system->getMixer()->playStream(Audio::Mixer::kPlainSoundType, &_handle, subStream, -1, _volume, 0, DisposeAfterUse::YES);
+}
+
+void Sound::loopSoundSegment(uint32 start, uint32 end) {
+ if (!isSoundLoaded())
+ return;
+
+ stopSound();
+
+ Audio::AudioStream *subLoopStream = new Audio::SubLoopingAudioStream(_stream, 0, Audio::Timestamp(0, start, 600), Audio::Timestamp(0, end, 600), DisposeAfterUse::NO);
+
+ g_system->getMixer()->playStream(Audio::Mixer::kPlainSoundType, &_handle, subLoopStream, -1, _volume, 0, DisposeAfterUse::YES);
+}
+
+void Sound::stopSound() {
g_system->getMixer()->stopHandle(_handle);
}
@@ -120,7 +151,7 @@ bool Sound::isPlaying() {
}
bool Sound::isSoundLoaded() const {
- return _aiffStream != 0;
+ return _stream != 0;
}
} // End of namespace Pegasus
diff --git a/engines/pegasus/sound.h b/engines/pegasus/sound.h
index 62ce51a605..99607d432c 100755
--- a/engines/pegasus/sound.h
+++ b/engines/pegasus/sound.h
@@ -30,14 +30,13 @@
#include "common/str.h"
namespace Audio {
- class AudioStream;
- class RewindableAudioStream;
+ class SeekableAudioStream;
}
namespace Pegasus {
// TODO!
-//class MMSoundFader;
+//class SoundFader;
// Things you might want to do with sound:
// Start it
@@ -59,10 +58,17 @@ public:
// not using the resource fork string resources.
void initFromAIFFFile(const Common::String &fileName);
+ // Unlike the original game, we're going to use a regular
+ // audio stream for sound spots. The original treated them
+ // as movies.
+ void initFromQuickTime(const Common::String &fileName);
+
void disposeSound();
bool isSoundLoaded() const;
void playSound();
void loopSound();
+ void playSoundSegment(uint32 start, uint32 end);
+ void loopSoundSegment(uint32 start, uint32 end);
void stopSound();
void setVolume(const uint16 volume);
bool isPlaying();
@@ -71,7 +77,7 @@ public:
//void attachFader(SoundFader *fader);
protected:
- Audio::RewindableAudioStream *_aiffStream;
+ Audio::SeekableAudioStream *_stream;
Audio::SoundHandle _handle;
byte _volume;