Added part of the framework for playing sounds

svn-id: r28545
This commit is contained in:
Paul Gilbert 2007-08-12 11:08:44 +00:00
parent 52292983b0
commit c247257721
2 changed files with 268 additions and 3 deletions

View File

@ -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) {
}
void SoundManager::playSound(uint16 soundId) {
// 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::musicInterface_KillAll() {
}
void SoundManager::musicInterface_ContinuePlaying() {
}
void SoundManager::musicInterface_TrashReverb() {
}

View File

@ -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