Add sound effects support for PC version of BRA.

svn-id: r39716
This commit is contained in:
Travis Howell 2009-03-28 09:56:39 +00:00
parent 9131f20587
commit 4979179621
5 changed files with 91 additions and 67 deletions

View file

@ -404,7 +404,7 @@ Common::SeekableReadStream* DosDisk_br::loadMusic(const char* name) {
Common::SeekableReadStream* DosDisk_br::loadSound(const char* name) {
debugC(5, kDebugDisk, "DosDisk_br::loadSound");
return 0;
return openFile("sfx/" + Common::String(name), ".sfx");
}
@ -720,7 +720,7 @@ Common::SeekableReadStream* AmigaDisk_br::loadMusic(const char* name) {
Common::SeekableReadStream* AmigaDisk_br::loadSound(const char* name) {
debugC(5, kDebugDisk, "AmigaDisk_br::loadSound");
return tryOpenFile("sfx/" + Common::String(name), ".sfx");
return openFile("sfx/" + Common::String(name), ".sfx");
}
static const uint16 objectsMax[5] = {

View file

@ -960,10 +960,12 @@ bool CharacterName::dummy() const {
}
void Parallaction::beep() {
if (getGameType() == GType_Nippon) {
_soundMan->execute(SC_SETSFXCHANNEL, 3);
_soundMan->execute(SC_SETSFXVOLUME, 127);
_soundMan->execute(SC_SETSFXLOOPING, (int32)0);
_soundMan->execute(SC_PLAYSFX, "beep");
}
}
void Parallaction::scheduleLocationSwitch(const char *location) {

View file

@ -141,7 +141,7 @@ public:
void pause(bool p);
};
#define NUM_AMIGA_CHANNELS 4
#define NUM_SFX_CHANNELS 4
class AmigaSoundMan_ns : public SoundMan_ns {
@ -155,7 +155,7 @@ class AmigaSoundMan_ns : public SoundMan_ns {
bool dispose;
Audio::SoundHandle handle;
uint32 flags;
} _channels[NUM_AMIGA_CHANNELS];
} _channels[NUM_SFX_CHANNELS];
void loadChannelData(const char *filename, Channel *ch);
@ -193,11 +193,23 @@ protected:
virtual void stopMusic() = 0;
virtual void pause(bool p) = 0;
struct Channel {
Audio::Voice8Header header;
int8 *data;
uint32 dataSize;
bool dispose;
Audio::SoundHandle handle;
uint32 flags;
} _channels[NUM_SFX_CHANNELS];
virtual void loadChannelData(const char *filename, Channel *ch) = 0;
public:
SoundMan_br(Parallaction_br *vm);
~SoundMan_br();
virtual void playSfx(const char *filename, uint channel, bool looping, int volume = -1) { }
virtual void stopSfx(uint channel) { }
void stopSfx(uint channel);
virtual void execute(int command, const char *parm);
void setMusicFile(const char *parm);
@ -207,6 +219,8 @@ class DosSoundMan_br : public SoundMan_br {
MidiPlayer_MSC *_midiPlayer;
void loadChannelData(const char *filename, Channel *ch);
public:
DosSoundMan_br(Parallaction_br *vm, MidiDriver *midiDriver);
~DosSoundMan_br();
@ -216,7 +230,6 @@ public:
void pause(bool p);
void playSfx(const char *filename, uint channel, bool looping, int volume);
void stopSfx(uint channel);
};
class AmigaSoundMan_br : public SoundMan_br {
@ -224,16 +237,7 @@ class AmigaSoundMan_br : public SoundMan_br {
Audio::AudioStream *_musicStream;
Audio::SoundHandle _musicHandle;
struct Channel {
Audio::Voice8Header header;
int8 *data;
uint32 dataSize;
bool dispose;
Audio::SoundHandle handle;
uint32 flags;
} _channels[NUM_AMIGA_CHANNELS];
bool loadChannelData(const char *filename, Channel *ch);
void loadChannelData(const char *filename, Channel *ch);
public:
AmigaSoundMan_br(Parallaction_br *vm);
@ -244,7 +248,6 @@ public:
void pause(bool p);
void playSfx(const char *filename, uint channel, bool looping, int volume);
void stopSfx(uint channel);
};
} // namespace Parallaction

View file

@ -401,12 +401,37 @@ DosSoundMan_br::~DosSoundMan_br() {
delete _midiPlayer;
}
void DosSoundMan_br::playSfx(const char *filename, uint channel, bool looping, int volume) {
warning("SC_PLAYSFX not yet supported!");
void DosSoundMan_br::loadChannelData(const char *filename, Channel *ch) {
Common::SeekableReadStream *stream = _vm->_disk->loadSound(filename);
ch->dataSize = stream->size();
ch->data = (int8*)malloc(ch->dataSize);
if (stream->read(ch->data, ch->dataSize) != ch->dataSize)
error("DosSoundMan_br::loadChannelData: Read failed");
ch->dispose = true;
delete stream;
// TODO: Confirm sound rate
ch->header.samplesPerSec = 11025;
}
void DosSoundMan_br::stopSfx(uint channel) {
warning("SC_STOPSFX not yet supported!");
void DosSoundMan_br::playSfx(const char *filename, uint channel, bool looping, int volume) {
stopSfx(channel);
debugC(1, kDebugAudio, "DosSoundMan_br::playSfx(%s, %u, %i, %i)", filename, channel, looping, volume);
Channel *ch = &_channels[channel];
loadChannelData(filename, ch);
uint32 loopStart = 0, loopEnd = 0, flags = Audio::Mixer::FLAG_UNSIGNED;
if (looping) {
loopEnd = ch->dataSize;
flags |= Audio::Mixer::FLAG_LOOP;
}
_mixer->playRaw(Audio::Mixer::kSFXSoundType, &ch->handle, ch->data, ch->dataSize,
ch->header.samplesPerSec, flags, -1, volume, 0, loopStart, loopEnd);
}
void DosSoundMan_br::playMusic() {
@ -429,40 +454,22 @@ void DosSoundMan_br::pause(bool p) {
AmigaSoundMan_br::AmigaSoundMan_br(Parallaction_br *vm) : SoundMan_br(vm) {
_musicStream = 0;
_channels[0].data = 0;
_channels[0].dispose = false;
_channels[1].data = 0;
_channels[1].dispose = false;
_channels[2].data = 0;
_channels[2].dispose = false;
_channels[3].data = 0;
_channels[3].dispose = false;
}
AmigaSoundMan_br::~AmigaSoundMan_br() {
stopMusic();
stopSfx(0);
stopSfx(1);
stopSfx(2);
stopSfx(3);
}
bool AmigaSoundMan_br::loadChannelData(const char *filename, Channel *ch) {
void AmigaSoundMan_br::loadChannelData(const char *filename, Channel *ch) {
Common::SeekableReadStream *stream = _vm->_disk->loadSound(filename);
// NOTE: Sound files don't always exist
if (!stream)
return false;
Audio::A8SVXDecoder decoder(*stream, ch->header, ch->data, ch->dataSize);
decoder.decode();
ch->dispose = true;
delete stream;
return true;
}
void AmigaSoundMan_br::playSfx(const char *filename, uint channel, bool looping, int volume) {
if (channel >= NUM_AMIGA_CHANNELS) {
if (channel >= NUM_SFX_CHANNELS) {
warning("unknown sfx channel");
return;
}
@ -472,10 +479,9 @@ void AmigaSoundMan_br::playSfx(const char *filename, uint channel, bool looping,
debugC(1, kDebugAudio, "AmigaSoundMan_ns::playSfx(%s, %i)", filename, channel);
Channel *ch = &_channels[channel];
if (!loadChannelData(filename, ch))
return;
loadChannelData(filename, ch);
uint32 loopStart, loopEnd, flags;
uint32 loopStart = 0, loopEnd = 0, flags = 0;
if (looping) {
// the standard way to loop 8SVX audio implies use of the oneShotHiSamples and
// repeatHiSamples fields, but Nippon Safes handles loops according to flags
@ -483,9 +489,6 @@ void AmigaSoundMan_br::playSfx(const char *filename, uint channel, bool looping,
loopStart = 0;
loopEnd = ch->header.oneShotHiSamples + ch->header.repeatHiSamples;
flags = Audio::Mixer::FLAG_LOOP;
} else {
loopStart = loopEnd = 0;
flags = 0;
}
if (volume == -1) {
@ -496,20 +499,6 @@ void AmigaSoundMan_br::playSfx(const char *filename, uint channel, bool looping,
ch->header.samplesPerSec, flags, -1, volume, 0, loopStart, loopEnd);
}
void AmigaSoundMan_br::stopSfx(uint channel) {
if (channel >= NUM_AMIGA_CHANNELS) {
warning("unknown sfx channel");
return;
}
if (_channels[channel].dispose) {
debugC(1, kDebugAudio, "AmigaSoundMan_ns::stopSfx(%i)", channel);
_mixer->stopHandle(_channels[channel].handle);
free(_channels[channel].data);
_channels[channel].data = 0;
}
}
void AmigaSoundMan_br::playMusic() {
stopMusic();
@ -544,12 +533,42 @@ void AmigaSoundMan_br::pause(bool p) {
SoundMan_br::SoundMan_br(Parallaction_br *vm) : _vm(vm) {
_mixer = _vm->_mixer;
_channels[0].data = 0;
_channels[0].dispose = false;
_channels[1].data = 0;
_channels[1].dispose = false;
_channels[2].data = 0;
_channels[2].dispose = false;
_channels[3].data = 0;
_channels[3].dispose = false;
}
SoundMan_br::~SoundMan_br() {
stopSfx(0);
stopSfx(1);
stopSfx(2);
stopSfx(3);
}
void SoundMan_br::setMusicFile(const char *name) {
_musicFile = name;
}
void SoundMan_br::stopSfx(uint channel) {
if (channel >= NUM_SFX_CHANNELS) {
warning("unknown sfx channel");
return;
}
if (_channels[channel].dispose) {
debugC(1, kDebugAudio, "SoundMan_br::stopSfx(%i)", channel);
_mixer->stopHandle(_channels[channel].handle);
free(_channels[channel].data);
_channels[channel].data = 0;
}
}
void SoundMan_br::execute(int command, const char *parm) {
uint32 n = parm ? strtoul(parm, 0, 10) : 0;
bool b = (n == 1) ? true : false;

View file

@ -387,7 +387,7 @@ void AmigaSoundMan_ns::loadChannelData(const char *filename, Channel *ch) {
}
void AmigaSoundMan_ns::playSfx(const char *filename, uint channel, bool looping, int volume) {
if (channel >= NUM_AMIGA_CHANNELS) {
if (channel >= NUM_SFX_CHANNELS) {
warning("unknown sfx channel");
return;
}
@ -421,7 +421,7 @@ void AmigaSoundMan_ns::playSfx(const char *filename, uint channel, bool looping,
}
void AmigaSoundMan_ns::stopSfx(uint channel) {
if (channel >= NUM_AMIGA_CHANNELS) {
if (channel >= NUM_SFX_CHANNELS) {
warning("unknown sfx channel");
return;
}