PRINCE: Sounds and voices - fix and update
This commit is contained in:
parent
687a168747
commit
97d10f94ec
4 changed files with 54 additions and 31 deletions
|
@ -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()) {
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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() {
|
||||||
|
|
|
@ -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!: */
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue