PRINCE: Sounds and voices - fix and update

This commit is contained in:
lukaslw 2014-07-26 05:33:33 +02:00
parent 687a168747
commit 97d10f94ec
4 changed files with 54 additions and 31 deletions

View file

@ -101,7 +101,7 @@ PrinceEngine::PrinceEngine(OSystem *syst, const PrinceGameDescription *gameDesc)
DebugMan.enableDebugChannel("script"); DebugMan.enableDebugChannel("script");
memset(_voiceStream, 0, sizeof(_voiceStream)); memset(_audioStream, 0, sizeof(_audioStream));
gDebugLevel = 10; gDebugLevel = 10;
} }
@ -183,6 +183,8 @@ PrinceEngine::~PrinceEngine() {
free(_coordsBuf); free(_coordsBuf);
_mobPriorityList.clear(); _mobPriorityList.clear();
freeAllSamples();
} }
GUI::Debugger *PrinceEngine::getDebugger() { GUI::Debugger *PrinceEngine::getDebugger() {
@ -380,9 +382,7 @@ bool PrinceEngine::loadLocation(uint16 locationNr) {
_flicPlayer.close(); _flicPlayer.close();
memset(_textSlots, 0, sizeof(_textSlots)); memset(_textSlots, 0, sizeof(_textSlots));
for(uint32 sampleId = 0; sampleId < MAX_SAMPLES; sampleId++) { freeAllSamples();
stopSample(sampleId);
}
debugEngine("PrinceEngine::loadLocation %d", locationNr); debugEngine("PrinceEngine::loadLocation %d", locationNr);
const Common::FSNode gameDataDir(ConfMan.get("path")); const Common::FSNode gameDataDir(ConfMan.get("path"));
@ -590,23 +590,35 @@ bool PrinceEngine::playNextFrame() {
} }
void PrinceEngine::playSample(uint16 sampleId, uint16 loopType) { void PrinceEngine::playSample(uint16 sampleId, uint16 loopType) {
if (_voiceStream[sampleId]) { if (_audioStream[sampleId]) {
if (_mixer->isSoundIDActive(sampleId)) { if (_mixer->isSoundIDActive(sampleId)) {
return; return;
} }
_audioStream[sampleId]->rewind();
Audio::AudioStream *audioStream = Audio::makeWAVStream(_voiceStream[sampleId], DisposeAfterUse::YES); _mixer->playStream(Audio::Mixer::kSFXSoundType, &_soundHandle[sampleId], _audioStream[sampleId], sampleId, Audio::Mixer::kMaxChannelVolume, 0, DisposeAfterUse::NO);
if (loopType) {
audioStream = new Audio::LoopingAudioStream((Audio::RewindableAudioStream*)audioStream, 0, DisposeAfterUse::NO);
}
_mixer->playStream(Audio::Mixer::kSFXSoundType, &_soundHandle[sampleId], audioStream, sampleId);
} }
} }
void PrinceEngine::stopSample(uint16 sampleId) { void PrinceEngine::stopSample(uint16 sampleId) {
_mixer->stopID(sampleId); _mixer->stopID(sampleId);
_voiceStream[sampleId] = nullptr; }
void PrinceEngine::stopAllSamples() {
_mixer->stopAll();
}
void PrinceEngine::freeSample(uint16 sampleId) {
if (_audioStream[sampleId] != nullptr) {
delete _audioStream[sampleId];
_audioStream[sampleId] = nullptr;
}
}
void PrinceEngine::freeAllSamples() {
for (int sampleId = 0; sampleId < kMaxSamples; sampleId++) {
stopSample(sampleId);
freeSample(sampleId);
}
} }
bool PrinceEngine::loadSample(uint32 sampleSlot, const Common::String &streamName) { bool PrinceEngine::loadSample(uint32 sampleSlot, const Common::String &streamName) {
@ -622,11 +634,15 @@ bool PrinceEngine::loadSample(uint32 sampleSlot, const Common::String &streamNam
debugEngine("loadSample slot %d, name %s", sampleSlot, normalizedPath.c_str()); debugEngine("loadSample slot %d, name %s", sampleSlot, normalizedPath.c_str());
stopSample(sampleSlot); stopSample(sampleSlot);
_voiceStream[sampleSlot] = SearchMan.createReadStreamForMember(normalizedPath); freeSample(sampleSlot);
if (_voiceStream[sampleSlot] == nullptr) { Common::SeekableReadStream *sampleStream = SearchMan.createReadStreamForMember(normalizedPath);
if (sampleStream == nullptr) {
delete sampleStream;
error("Can't load sample %s to slot %d", normalizedPath.c_str(), sampleSlot); error("Can't load sample %s to slot %d", normalizedPath.c_str(), sampleSlot);
} }
return _voiceStream[sampleSlot] == nullptr; _audioStream[sampleSlot] = Audio::makeWAVStream(sampleStream, DisposeAfterUse::NO);
delete sampleStream;
return true;
} }
bool PrinceEngine::loadVoice(uint32 slot, uint32 sampleSlot, const Common::String &streamName) { bool PrinceEngine::loadVoice(uint32 slot, uint32 sampleSlot, const Common::String &streamName) {
@ -638,26 +654,27 @@ bool PrinceEngine::loadVoice(uint32 slot, uint32 sampleSlot, const Common::Strin
} }
stopSample(sampleSlot); stopSample(sampleSlot);
_voiceStream[sampleSlot] = SearchMan.createReadStreamForMember(streamName); freeSample(sampleSlot);
if (!_voiceStream[sampleSlot]) { Common::SeekableReadStream *sampleStream = SearchMan.createReadStreamForMember(streamName);
if (sampleStream == nullptr) {
debug("Can't open %s", streamName.c_str()); debug("Can't open %s", streamName.c_str());
return false; return false;
} }
uint32 id = _voiceStream[sampleSlot]->readUint32LE(); uint32 id = sampleStream->readUint32LE();
if (id != MKTAG('F', 'F', 'I', 'R')) { if (id != MKTAG('F', 'F', 'I', 'R')) {
error("It's not RIFF file %s", streamName.c_str()); error("It's not RIFF file %s", streamName.c_str());
return false; return false;
} }
_voiceStream[sampleSlot]->skip(0x20); sampleStream->skip(0x20);
id = _voiceStream[sampleSlot]->readUint32LE(); id = sampleStream->readUint32LE();
if (id != MKTAG('a', 't', 'a', 'd')) { if (id != MKTAG('a', 't', 'a', 'd')) {
error("No data section in %s id %04x", streamName.c_str(), id); error("No data section in %s id %04x", streamName.c_str(), id);
return false; return false;
} }
id = _voiceStream[sampleSlot]->readUint32LE(); id = sampleStream->readUint32LE();
debugEngine("SetVoice slot %d time %04x", slot, id); debugEngine("SetVoice slot %d time %04x", slot, id);
id <<= 3; id <<= 3;
id /= 22050; id /= 22050;
@ -671,8 +688,9 @@ bool PrinceEngine::loadVoice(uint32 slot, uint32 sampleSlot, const Common::Strin
} }
debugEngine("SetVoice slot %d time %04x", slot, id); debugEngine("SetVoice slot %d time %04x", slot, id);
_voiceStream[sampleSlot]->seek(0); sampleStream->seek(SEEK_SET);
_audioStream[sampleSlot] = Audio::makeWAVStream(sampleStream, DisposeAfterUse::NO);
delete sampleStream;
return true; return true;
} }
@ -2619,6 +2637,8 @@ void PrinceEngine::displayInventory() {
_interpreter->storeNewPC(0); _interpreter->storeNewPC(0);
stopAllSamples();
prepareInventoryToView(); prepareInventoryToView();
while (!shouldQuit()) { while (!shouldQuit()) {

View file

@ -275,6 +275,9 @@ public:
void playSample(uint16 sampleId, uint16 loopType); void playSample(uint16 sampleId, uint16 loopType);
void stopSample(uint16 sampleId); void stopSample(uint16 sampleId);
void stopAllSamples();
void freeSample(uint16 sampleId);
void freeAllSamples();
void setVoice(uint16 slot, uint32 sampleSlot, uint16 flag); void setVoice(uint16 slot, uint32 sampleSlot, uint16 flag);
@ -572,9 +575,9 @@ private:
Font *_font; Font *_font;
MusicPlayer *_midiPlayer; MusicPlayer *_midiPlayer;
static const uint32 MAX_SAMPLES = 60; static const uint32 kMaxSamples = 60;
Common::SeekableReadStream *_voiceStream[MAX_SAMPLES]; Audio::RewindableAudioStream *_audioStream[kMaxSamples];
Audio::SoundHandle _soundHandle[MAX_SAMPLES]; Audio::SoundHandle _soundHandle[kMaxSamples];
Common::Array<PScr *> _pscrList; Common::Array<PScr *> _pscrList;
Common::Array<DrawNode> _drawNodeList; Common::Array<DrawNode> _drawNodeList;

View file

@ -548,10 +548,10 @@ void Interpreter::O_SETSAMPLE() {
debugInterpreter("O_SETSAMPLE %d %s", sampleId, sampleName); debugInterpreter("O_SETSAMPLE %d %s", sampleId, sampleName);
} }
// TODO
void Interpreter::O_FREESAMPLE() { void Interpreter::O_FREESAMPLE() {
uint16 sample = readScriptFlagValue(); uint16 sampleId = readScriptFlagValue();
debugInterpreter("O_FREESAMPLE %d", sample); _vm->freeSample(sampleId);
debugInterpreter("O_FREESAMPLE sampleId: %d", sampleId);
} }
void Interpreter::O_PLAYSAMPLE() { void Interpreter::O_PLAYSAMPLE() {

View file

@ -217,6 +217,6 @@ void MusicPlayer::sendToChannel(byte channel, uint32 b) {
_channelsTable[channel]->send(b); _channelsTable[channel]->send(b);
} }
} // End of namespace CGE }
/* vim: set tabstop=4 expandtab!: */ /* vim: set tabstop=4 expandtab!: */