aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Gilbert2007-08-12 11:08:44 +0000
committerPaul Gilbert2007-08-12 11:08:44 +0000
commitc247257721f4e42b18d5dbc87f088fbfed278f00 (patch)
treeb0954f6cd39d25827febc6571a8dcccbe7da0718
parent52292983b03641fdef2d45dabb1d137b25cd6481 (diff)
downloadscummvm-rg350-c247257721f4e42b18d5dbc87f088fbfed278f00.tar.gz
scummvm-rg350-c247257721f4e42b18d5dbc87f088fbfed278f00.tar.bz2
scummvm-rg350-c247257721f4e42b18d5dbc87f088fbfed278f00.zip
Added part of the framework for playing sounds
svn-id: r28545
-rw-r--r--engines/lure/sound.cpp236
-rw-r--r--engines/lure/sound.h35
2 files changed, 268 insertions, 3 deletions
diff --git a/engines/lure/sound.cpp b/engines/lure/sound.cpp
index 6961e4c7cc..8b927cca9d 100644
--- a/engines/lure/sound.cpp
+++ b/engines/lure/sound.cpp
@@ -21,16 +21,250 @@
*/
#include "lure/sound.h"
+#include "lure/game.h"
+#include "lure/res.h"
+#include "lure/room.h"
DECLARE_SINGLETON(Lure::SoundManager);
namespace Lure {
+SoundManager::SoundManager() {
+ _descs = Disk::getReference().getEntry(SOUND_DESC_RESOURCE_ID);
+ _numDescs = _descs->size() / sizeof(SoundDescResource);
+
+ for (int channelNum = 0; channelNum < NUM_CHANNELS; ++channelNum)
+ _channels[channelNum] = 0;
+}
+
+void SoundManager::bellsBodge() {
+ Resources &res = Resources::getReference();
+ Room &room = Room::getReference();
+
+ RoomData *roomData = res.getRoom(room.roomNumber());
+ if (roomData->areaFlag != res.fieldList().getField(AREA_FLAG)) {
+ res.fieldList().setField(AREA_FLAG, roomData->areaFlag);
+
+ switch (roomData->areaFlag) {
+ case 0:
+ killSound(1);
+ break;
+ case 1:
+ addSound(2);
+ killSound(33);
+ break;
+ case 2:
+ setVolume(0, 15);
+ // Deliberate fall through
+ default:
+ killSound(1);
+ break;
+ }
+ }
+}
+
void SoundManager::killSounds() {
+ // Stop the player playing all sounds
+ musicInterface_KillAll();
+
+ // Clear the active sounds
+ _activeSounds.clear();
+ for (int channelNum = 0; channelNum < NUM_CHANNELS; ++channelNum)
+ _channels[channelNum] = 0;
+}
+
+void SoundManager::addSound(uint8 soundIndex, bool tidyFlag) {
+ Game &game = Game::getReference();
+
+ if (tidyFlag)
+ tidySounds();
+
+ if (game.preloadFlag())
+ // Don't add a sound if in room preloading
+ return;
+
+ SoundDescResource &rec = soundDescs()[soundIndex];
+ int numChannels = (rec.numChannels >> 2) & 3;
+
+ int channelCtr = 0;
+ while (channelCtr < NUM_CHANNELS) {
+ if (_channels[channelCtr] == 0) {
+ bool foundSpace = true;
+
+ int channelCtr2 = 0;
+ while (channelCtr2 < numChannels) {
+ foundSpace = _channels[channelCtr2] == 0;
+ if (!foundSpace) break;
+ ++channelCtr2;
+ }
+
+ if (foundSpace)
+ break;
+ }
+
+ ++channelCtr;
+ }
+
+ if (channelCtr == 8)
+ // No channels free
+ return;
+
+ // Mark the found channels as in use
+ for (int channelCtr2 = 0; channelCtr2 < numChannels; ++channelCtr2)
+ _channels[channelCtr + channelCtr2] = 1;
+
+ SoundDescResource *newEntry = new SoundDescResource();
+ newEntry->soundNumber = rec.soundNumber;
+ newEntry->channel = channelCtr;
+ newEntry->numChannels = numChannels;
+ newEntry->flags = rec.flags;
+ newEntry->volume = rec.volume;
+ _activeSounds.push_back(newEntry);
+
+ musicInterface_Play(rec.soundNumber, false, channelCtr);
+ setVolume(rec.soundNumber, rec.volume);
+}
+
+void SoundManager::addSound2(uint8 soundIndex) {
+ tidySounds();
+
+ if (soundIndex == 6)
+ // Chinese torture
+ addSound(6);
+ else
+ {
+ SoundDescResource &descEntry = soundDescs()[soundIndex];
+ SoundDescResource *rec = findSound(descEntry.soundNumber);
+ if (rec == NULL)
+ // Sound isn't active, so go and add it
+ addSound(soundIndex, false);
+ }
+}
+
+
+void SoundManager::stopSound(uint8 soundIndex) {
+ SoundDescResource &rec = soundDescs()[soundIndex];
+ musicInterface_Stop(rec.soundNumber & 0x7f);
+}
+
+void SoundManager::killSound(uint8 soundNumber) {
+ musicInterface_Stop(soundNumber & 0x7f);
+}
+
+void SoundManager::setVolume(uint8 soundNumber, uint8 volume) {
+ SoundDescResource *entry = findSound(soundNumber);
+ if (entry == NULL) return;
+
+ // Special check is done for Adlib in original game, to ignore any volume changes
+}
+
+SoundDescResource *SoundManager::findSound(uint8 soundNumber) {
+ ManagedList<SoundDescResource *>::iterator i;
+
+ for (i = _activeSounds.begin(); i != _activeSounds.end(); ++i) {
+ SoundDescResource *rec = *i;
+
+ if (rec->soundNumber == soundNumber)
+ return rec;
+ }
+
+ // Signal that sound wasn't found
+ return NULL;
+}
+
+void SoundManager::tidySounds() {
+ ManagedList<SoundDescResource *>::iterator i = _activeSounds.begin();
+
+ while (i != _activeSounds.end()) {
+ SoundDescResource *rec = *i;
+
+ if (musicInterface_CheckPlaying(rec->soundNumber & 0x7f))
+ // Still playing, so move to next entry
+ ++i;
+ else {
+ // Mark the channels that it used as now being free
+ for (int channelCtr = 0; channelCtr < rec->numChannels; ++channelCtr)
+ _channels[rec->channel + channelCtr] = 0;
+
+ i = _activeSounds.erase(i);
+ }
+ }
+}
+
+void SoundManager::removeSounds() {
+ bellsBodge();
+
+ ManagedList<SoundDescResource *>::iterator i = _activeSounds.begin();
+
+ while (i != _activeSounds.end()) {
+ SoundDescResource *rec = *i;
+
+ if ((rec->flags & SF_IN_USE) != 0)
+ musicInterface_Stop(rec->soundNumber);
+
+ ++i;
+ }
+}
+
+void SoundManager::restoreSounds() {
+
+ ManagedList<SoundDescResource *>::iterator i = _activeSounds.begin();
+
+ while (i != _activeSounds.end()) {
+ SoundDescResource *rec = *i;
+
+ if ((rec->numChannels != 0) && ((rec->flags & SF_RESTORE) != 0)) {
+ for (int channelCtr = 0; channelCtr < rec->numChannels; ++channelCtr)
+ _channels[rec->channel + channelCtr] = 1;
+
+ musicInterface_Play(rec->soundNumber, false, rec->channel);
+ musicInterface_SetVolume(rec->soundNumber, rec->volume);
+ }
+
+ ++i;
+ }
+}
+
+
+/*------------------------------------------------------------------------*/
+
+// musicInterface_CheckPlaying
+// Play the specified sound
+
+void SoundManager::musicInterface_Play(uint8 soundNumber, bool isEffect, uint8 channelNumber) {
+
+}
+
+// musicInterface_Stop
+// Stops the specified sound from playing
+
+void SoundManager::musicInterface_Stop(uint8 soundNumber) {
+
+}
+
+// musicInterface_CheckPlaying
+// Returns true if a sound is still player
+
+bool SoundManager::musicInterface_CheckPlaying(uint8 soundNumber) {
+ return true;
+}
+
+// musicInterface_SetVolume
+// Sets the volume of the specified channel
+
+void SoundManager::musicInterface_SetVolume(uint8 channelNum, uint8 volume) {
}
-void SoundManager::playSound(uint16 soundId) {
+void SoundManager::musicInterface_KillAll() {
+
+}
+
+void SoundManager::musicInterface_ContinuePlaying() {
+
+}
+
+void SoundManager::musicInterface_TrashReverb() {
}
diff --git a/engines/lure/sound.h b/engines/lure/sound.h
index 4a7422d77f..95cb5f6f88 100644
--- a/engines/lure/sound.h
+++ b/engines/lure/sound.h
@@ -24,14 +24,45 @@
#define LURE_SOUND_H
#include "lure/luredefs.h"
+#include "lure/disk.h"
+#include "lure/memory.h"
#include "common/singleton.h"
namespace Lure {
+#define NUM_CHANNELS 8
+
class SoundManager: public Common::Singleton<SoundManager> {
+private:
+ MemoryBlock *_descs;
+ int _numDescs;
+ SoundDescResource *soundDescs() { return (SoundDescResource *) _descs->data(); }
+ ManagedList<SoundDescResource *> _activeSounds;
+ byte _channels[NUM_CHANNELS];
+
+ void bellsBodge();
public:
- static void killSounds();
- static void playSound(uint16 soundId);
+ SoundManager();
+
+ void killSounds();
+ void addSound(uint8 soundIndex, bool tidyFlag = true);
+ void addSound2(uint8 soundIndex);
+ void stopSound(uint8 soundIndex);
+ void killSound(uint8 soundNumber);
+ void setVolume(uint8 soundNumber, uint8 volume);
+ void tidySounds();
+ SoundDescResource *findSound(uint8 soundNumber);
+ void removeSounds();
+ void restoreSounds();
+
+ // The following methods implement the external sound player module
+ void musicInterface_Play(uint8 soundNumber, bool isEffect, uint8 channelNumber);
+ void musicInterface_Stop(uint8 soundNumber);
+ bool musicInterface_CheckPlaying(uint8 soundNumber);
+ void musicInterface_SetVolume(uint8 channelNum, uint8 volume);
+ void musicInterface_KillAll();
+ void musicInterface_ContinuePlaying();
+ void musicInterface_TrashReverb();
};
} // End of namespace Lure