Add sound effects support for PC version of BRA.
svn-id: r39716
This commit is contained in:
parent
9131f20587
commit
4979179621
5 changed files with 91 additions and 67 deletions
|
@ -404,7 +404,7 @@ Common::SeekableReadStream* DosDisk_br::loadMusic(const char* name) {
|
||||||
|
|
||||||
Common::SeekableReadStream* DosDisk_br::loadSound(const char* name) {
|
Common::SeekableReadStream* DosDisk_br::loadSound(const char* name) {
|
||||||
debugC(5, kDebugDisk, "DosDisk_br::loadSound");
|
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) {
|
Common::SeekableReadStream* AmigaDisk_br::loadSound(const char* name) {
|
||||||
debugC(5, kDebugDisk, "AmigaDisk_br::loadSound");
|
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] = {
|
static const uint16 objectsMax[5] = {
|
||||||
|
|
|
@ -960,10 +960,12 @@ bool CharacterName::dummy() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Parallaction::beep() {
|
void Parallaction::beep() {
|
||||||
_soundMan->execute(SC_SETSFXCHANNEL, 3);
|
if (getGameType() == GType_Nippon) {
|
||||||
_soundMan->execute(SC_SETSFXVOLUME, 127);
|
_soundMan->execute(SC_SETSFXCHANNEL, 3);
|
||||||
_soundMan->execute(SC_SETSFXLOOPING, (int32)0);
|
_soundMan->execute(SC_SETSFXVOLUME, 127);
|
||||||
_soundMan->execute(SC_PLAYSFX, "beep");
|
_soundMan->execute(SC_SETSFXLOOPING, (int32)0);
|
||||||
|
_soundMan->execute(SC_PLAYSFX, "beep");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Parallaction::scheduleLocationSwitch(const char *location) {
|
void Parallaction::scheduleLocationSwitch(const char *location) {
|
||||||
|
|
|
@ -141,7 +141,7 @@ public:
|
||||||
void pause(bool p);
|
void pause(bool p);
|
||||||
};
|
};
|
||||||
|
|
||||||
#define NUM_AMIGA_CHANNELS 4
|
#define NUM_SFX_CHANNELS 4
|
||||||
|
|
||||||
class AmigaSoundMan_ns : public SoundMan_ns {
|
class AmigaSoundMan_ns : public SoundMan_ns {
|
||||||
|
|
||||||
|
@ -155,7 +155,7 @@ class AmigaSoundMan_ns : public SoundMan_ns {
|
||||||
bool dispose;
|
bool dispose;
|
||||||
Audio::SoundHandle handle;
|
Audio::SoundHandle handle;
|
||||||
uint32 flags;
|
uint32 flags;
|
||||||
} _channels[NUM_AMIGA_CHANNELS];
|
} _channels[NUM_SFX_CHANNELS];
|
||||||
|
|
||||||
void loadChannelData(const char *filename, Channel *ch);
|
void loadChannelData(const char *filename, Channel *ch);
|
||||||
|
|
||||||
|
@ -193,11 +193,23 @@ protected:
|
||||||
virtual void stopMusic() = 0;
|
virtual void stopMusic() = 0;
|
||||||
virtual void pause(bool p) = 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:
|
public:
|
||||||
SoundMan_br(Parallaction_br *vm);
|
SoundMan_br(Parallaction_br *vm);
|
||||||
|
~SoundMan_br();
|
||||||
|
|
||||||
virtual void playSfx(const char *filename, uint channel, bool looping, int volume = -1) { }
|
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);
|
virtual void execute(int command, const char *parm);
|
||||||
void setMusicFile(const char *parm);
|
void setMusicFile(const char *parm);
|
||||||
|
@ -207,6 +219,8 @@ class DosSoundMan_br : public SoundMan_br {
|
||||||
|
|
||||||
MidiPlayer_MSC *_midiPlayer;
|
MidiPlayer_MSC *_midiPlayer;
|
||||||
|
|
||||||
|
void loadChannelData(const char *filename, Channel *ch);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
DosSoundMan_br(Parallaction_br *vm, MidiDriver *midiDriver);
|
DosSoundMan_br(Parallaction_br *vm, MidiDriver *midiDriver);
|
||||||
~DosSoundMan_br();
|
~DosSoundMan_br();
|
||||||
|
@ -216,7 +230,6 @@ public:
|
||||||
void pause(bool p);
|
void pause(bool p);
|
||||||
|
|
||||||
void playSfx(const char *filename, uint channel, bool looping, int volume);
|
void playSfx(const char *filename, uint channel, bool looping, int volume);
|
||||||
void stopSfx(uint channel);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class AmigaSoundMan_br : public SoundMan_br {
|
class AmigaSoundMan_br : public SoundMan_br {
|
||||||
|
@ -224,16 +237,7 @@ class AmigaSoundMan_br : public SoundMan_br {
|
||||||
Audio::AudioStream *_musicStream;
|
Audio::AudioStream *_musicStream;
|
||||||
Audio::SoundHandle _musicHandle;
|
Audio::SoundHandle _musicHandle;
|
||||||
|
|
||||||
struct Channel {
|
void loadChannelData(const char *filename, Channel *ch);
|
||||||
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);
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
AmigaSoundMan_br(Parallaction_br *vm);
|
AmigaSoundMan_br(Parallaction_br *vm);
|
||||||
|
@ -244,7 +248,6 @@ public:
|
||||||
void pause(bool p);
|
void pause(bool p);
|
||||||
|
|
||||||
void playSfx(const char *filename, uint channel, bool looping, int volume);
|
void playSfx(const char *filename, uint channel, bool looping, int volume);
|
||||||
void stopSfx(uint channel);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Parallaction
|
} // namespace Parallaction
|
||||||
|
|
|
@ -401,12 +401,37 @@ DosSoundMan_br::~DosSoundMan_br() {
|
||||||
delete _midiPlayer;
|
delete _midiPlayer;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DosSoundMan_br::playSfx(const char *filename, uint channel, bool looping, int volume) {
|
void DosSoundMan_br::loadChannelData(const char *filename, Channel *ch) {
|
||||||
warning("SC_PLAYSFX not yet supported!");
|
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) {
|
void DosSoundMan_br::playSfx(const char *filename, uint channel, bool looping, int volume) {
|
||||||
warning("SC_STOPSFX not yet supported!");
|
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() {
|
void DosSoundMan_br::playMusic() {
|
||||||
|
@ -429,40 +454,22 @@ void DosSoundMan_br::pause(bool p) {
|
||||||
|
|
||||||
AmigaSoundMan_br::AmigaSoundMan_br(Parallaction_br *vm) : SoundMan_br(vm) {
|
AmigaSoundMan_br::AmigaSoundMan_br(Parallaction_br *vm) : SoundMan_br(vm) {
|
||||||
_musicStream = 0;
|
_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() {
|
AmigaSoundMan_br::~AmigaSoundMan_br() {
|
||||||
stopMusic();
|
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);
|
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);
|
Audio::A8SVXDecoder decoder(*stream, ch->header, ch->data, ch->dataSize);
|
||||||
decoder.decode();
|
decoder.decode();
|
||||||
ch->dispose = true;
|
ch->dispose = true;
|
||||||
delete stream;
|
delete stream;
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AmigaSoundMan_br::playSfx(const char *filename, uint channel, bool looping, int volume) {
|
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");
|
warning("unknown sfx channel");
|
||||||
return;
|
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);
|
debugC(1, kDebugAudio, "AmigaSoundMan_ns::playSfx(%s, %i)", filename, channel);
|
||||||
|
|
||||||
Channel *ch = &_channels[channel];
|
Channel *ch = &_channels[channel];
|
||||||
if (!loadChannelData(filename, ch))
|
loadChannelData(filename, ch);
|
||||||
return;
|
|
||||||
|
|
||||||
uint32 loopStart, loopEnd, flags;
|
uint32 loopStart = 0, loopEnd = 0, flags = 0;
|
||||||
if (looping) {
|
if (looping) {
|
||||||
// the standard way to loop 8SVX audio implies use of the oneShotHiSamples and
|
// the standard way to loop 8SVX audio implies use of the oneShotHiSamples and
|
||||||
// repeatHiSamples fields, but Nippon Safes handles loops according to flags
|
// 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;
|
loopStart = 0;
|
||||||
loopEnd = ch->header.oneShotHiSamples + ch->header.repeatHiSamples;
|
loopEnd = ch->header.oneShotHiSamples + ch->header.repeatHiSamples;
|
||||||
flags = Audio::Mixer::FLAG_LOOP;
|
flags = Audio::Mixer::FLAG_LOOP;
|
||||||
} else {
|
|
||||||
loopStart = loopEnd = 0;
|
|
||||||
flags = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (volume == -1) {
|
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);
|
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() {
|
void AmigaSoundMan_br::playMusic() {
|
||||||
stopMusic();
|
stopMusic();
|
||||||
|
|
||||||
|
@ -544,12 +533,42 @@ void AmigaSoundMan_br::pause(bool p) {
|
||||||
|
|
||||||
SoundMan_br::SoundMan_br(Parallaction_br *vm) : _vm(vm) {
|
SoundMan_br::SoundMan_br(Parallaction_br *vm) : _vm(vm) {
|
||||||
_mixer = _vm->_mixer;
|
_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) {
|
void SoundMan_br::setMusicFile(const char *name) {
|
||||||
_musicFile = 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) {
|
void SoundMan_br::execute(int command, const char *parm) {
|
||||||
uint32 n = parm ? strtoul(parm, 0, 10) : 0;
|
uint32 n = parm ? strtoul(parm, 0, 10) : 0;
|
||||||
bool b = (n == 1) ? true : false;
|
bool b = (n == 1) ? true : false;
|
||||||
|
|
|
@ -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) {
|
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");
|
warning("unknown sfx channel");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -421,7 +421,7 @@ void AmigaSoundMan_ns::playSfx(const char *filename, uint channel, bool looping,
|
||||||
}
|
}
|
||||||
|
|
||||||
void AmigaSoundMan_ns::stopSfx(uint channel) {
|
void AmigaSoundMan_ns::stopSfx(uint channel) {
|
||||||
if (channel >= NUM_AMIGA_CHANNELS) {
|
if (channel >= NUM_SFX_CHANNELS) {
|
||||||
warning("unknown sfx channel");
|
warning("unknown sfx channel");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue