diff --git a/engines/pegasus/constants.h b/engines/pegasus/constants.h index 7a63cfc9dbed..509c9f3892bb 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 1a22831f5ea0..cf4a29ee155f 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 73f6c49d3c95..269443c6afaa 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 NeighborhoodActionQueue; + +class Neighborhood : public MMIDObject { public: Neighborhood(PegasusEngine *vm, const Common::String &resName, tNeighborhoodID id); virtual ~Neighborhood(); @@ -79,12 +107,22 @@ class Neighborhood { 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 @@ class Neighborhood { 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 5fcac1134a9b..5db1d90a3c7b 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 62ce51a60564..99607d432cc2 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 @@ class Sound { // 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 @@ class Sound { //void attachFader(SoundFader *fader); protected: - Audio::RewindableAudioStream *_aiffStream; + Audio::SeekableAudioStream *_stream; Audio::SoundHandle _handle; byte _volume;