diff options
-rw-r--r-- | engines/sci/engine/ksound.cpp | 26 | ||||
-rw-r--r-- | engines/sci/resource.cpp | 94 | ||||
-rw-r--r-- | engines/sci/resource.h | 12 |
3 files changed, 119 insertions, 13 deletions
diff --git a/engines/sci/engine/ksound.cpp b/engines/sci/engine/ksound.cpp index f1d8ab7e45..8322be4d86 100644 --- a/engines/sci/engine/ksound.cpp +++ b/engines/sci/engine/ksound.cpp @@ -797,7 +797,7 @@ reg_t kDoSound_SCI1(EngineState *s, int funct_nr, int argc, reg_t *argv) { break; } case _K_SCI1_SOUND_GET_AUDIO_CAPABILITY : { - return NULL_REG; + return make_reg(0, 1);//NULL_REG; } case _K_SCI1_SOUND_PLAY_HANDLE : { int looping = GET_SEL32V(obj, loop); @@ -996,6 +996,11 @@ reg_t kDoSound(EngineState *s, int funct_nr, int argc, reg_t *argv) { // Used for speech playback in CD games reg_t kDoAudio(EngineState *s, int funct_nr, int argc, reg_t *argv) { + printf("kDoAudio called with %d parameters: ", argc); + for (int i = 0; i < argc; i++) + printf("%d, ", SKPV(i)); + printf("\n"); + Audio::Mixer *mixer = g_system->getMixer(); int sampleLen = 0; @@ -1012,11 +1017,20 @@ reg_t kDoAudio(EngineState *s, int funct_nr, int argc, reg_t *argv) { // Try to load from an external patch file first Sci::Resource* audioRes = s->resmgr->findResource(kResourceTypeAudio, UKPV(1), 1); - if (audioRes) { - audioStream = s->sound.audioResource->getAudioStream(audioRes, &sampleLen); - } else { - // No patch file found, read it from the audio volume - audioStream = s->sound.audioResource->getAudioStream(UKPV(1), &sampleLen); + if (s->_gameName == "KQ5") { + if (audioRes) { + audioStream = s->sound.audioResource->getAudioStreamKQ5CD(audioRes, &sampleLen); + } else { + // No patch file found, read it from the audio volume + audioStream = s->sound.audioResource->getAudioStreamKQ5CD(UKPV(1), &sampleLen); + } + } else if (s->_gameName == "Kq6") { + if (audioRes) { + audioStream = s->sound.audioResource->getAudioStreamKQ6Floppy(audioRes, &sampleLen); + } else { + // No patch file found, read it from the audio volume + audioStream = s->sound.audioResource->getAudioStreamKQ6Floppy(UKPV(1), &sampleLen); + } } if (audioStream) diff --git a/engines/sci/resource.cpp b/engines/sci/resource.cpp index c9faaf0231..73f4bf7bd2 100644 --- a/engines/sci/resource.cpp +++ b/engines/sci/resource.cpp @@ -1208,7 +1208,7 @@ int AudioResource::getAudioPosition() { } } -bool AudioResource::findAudEntry(uint16 audioNumber, byte& volume, uint32& offset, uint32& size) { +bool AudioResource::findAudEntryKQ5CD(uint16 audioNumber, byte& volume, uint32& offset, uint32& size) { // AUDIO00X.MAP contains 10-byte entries: // w nEntry // dw offset+volume (as in resource.map) @@ -1235,13 +1235,13 @@ bool AudioResource::findAudEntry(uint16 audioNumber, byte& volume, uint32& offse return false; } -Audio::AudioStream* AudioResource::getAudioStream(uint16 audioNumber, int* sampleLen) { +Audio::AudioStream* AudioResource::getAudioStreamKQ5CD(uint16 audioNumber, int* sampleLen) { Audio::AudioStream *audioStream = 0; byte volume; uint32 offset; uint32 size; - if (findAudEntry(audioNumber, volume, offset, size)) { + if (findAudEntryKQ5CD(audioNumber, volume, offset, size)) { uint32 start = offset * 1000 / _audioRate; uint32 duration = size * 1000 / _audioRate; @@ -1271,9 +1271,95 @@ Audio::AudioStream* AudioResource::getAudioStream(uint16 audioNumber, int* sampl return audioStream; } -Audio::AudioStream* AudioResource::getAudioStream(Resource* audioRes, int* sampleLen) { +bool AudioResource::findAudEntryKQ6Floppy(uint16 audioNumber, uint32& offset) { + // 65535.MAP contains 8-byte entries: + // w nEntry + // dw offset + // w unknown + uint16 n; + offset = 0; + int cur = 0; + int fileSize = 0; + + // Load audio map + Common::File* audioMapFile = new Common::File(); + if (audioMapFile->open("65535.map")) { + _audioMap = new byte[audioMapFile->size()]; + audioMapFile->read(_audioMap, audioMapFile->size()); + fileSize = audioMapFile->size(); + audioMapFile->close(); + delete audioMapFile; + } else { + _audioMap = 0; + return false; + } + + byte *ptr = _audioMap; + while (cur < fileSize) { + n = READ_UINT16(ptr); + if (n == audioNumber) { + offset = READ_LE_UINT32(ptr + 2); + delete[] _audioMap; + _audioMap = 0; + return true; + } + ptr += 8; + cur += 8; + } + + delete[] _audioMap; + _audioMap = 0; + return false; +} + +Audio::AudioStream* AudioResource::getAudioStreamKQ6Floppy(uint16 audioNumber, int* sampleLen) { + Audio::AudioStream *audioStream = 0; + uint32 offset; + uint32 size; + + if (findAudEntryKQ6Floppy(audioNumber, offset)) { + Common::File* audioFile = new Common::File(); + if (audioFile->open("resource.aud")) { + audioFile->seek(offset); + // Read audio file info + // Audio files are actually Sierra Audio files. + // Check here for more info: http://wiki.multimedia.cx/index.php?title=Sierra_Audio + audioFile->readByte(); // skip version + audioFile->readByte(); // skip header size + audioFile->readUint32LE(); // skip "SOL" + 0 + _audioRate = audioFile->readUint16LE(); + audioFile->readByte(); // skip flags + size = audioFile->readUint16LE(); + byte *soundbuff = (byte *)malloc(size); + audioFile->read(soundbuff, size); + audioFile->close(); + delete audioFile; + + audioStream = Audio::makeLinearInputStream(soundbuff, size, _audioRate, + Audio::Mixer::FLAG_AUTOFREE | Audio::Mixer::FLAG_UNSIGNED, 0, 0); + } + + *sampleLen = size * 60 / _audioRate; + } + + return audioStream; +} + +Audio::AudioStream* AudioResource::getAudioStreamKQ5CD(Resource* audioRes, int* sampleLen) { *sampleLen = audioRes->size * 60 / _audioRate; return Audio::makeLinearInputStream(audioRes->data, audioRes->size, _audioRate, Audio::Mixer::FLAG_UNSIGNED, 0, 0); } +Audio::AudioStream* AudioResource::getAudioStreamKQ6Floppy(Resource* audioRes, int* sampleLen) { + // Read audio file info + // Audio files are actually Sierra Audio files. + // Check here for more info: http://wiki.multimedia.cx/index.php?title=Sierra_Audio + _audioRate = READ_UINT16(audioRes->data + 6); + uint32 size = READ_UINT16(audioRes->data + 9); + + *sampleLen = size * 60 / _audioRate; + return Audio::makeLinearInputStream(audioRes->data + 11, size, _audioRate, Audio::Mixer::FLAG_UNSIGNED, 0, 0); +} + + } // End of namespace Sci diff --git a/engines/sci/resource.h b/engines/sci/resource.h index f3593ded32..6f527645a7 100644 --- a/engines/sci/resource.h +++ b/engines/sci/resource.h @@ -312,8 +312,12 @@ public: Audio::SoundHandle* getAudioHandle() { return &_audioHandle; } int getAudioPosition(); - Audio::AudioStream* getAudioStream(uint16 audioNumber, int* sampleLen); - Audio::AudioStream* getAudioStream(Resource* audioRes, int* sampleLen); + + // TODO: these need better names + Audio::AudioStream* getAudioStreamKQ5CD(uint16 audioNumber, int* sampleLen); + Audio::AudioStream* getAudioStreamKQ5CD(Resource* audioRes, int* sampleLen); + Audio::AudioStream* getAudioStreamKQ6Floppy(uint16 audioNumber, int* sampleLen); + Audio::AudioStream* getAudioStreamKQ6Floppy(Resource* audioRes, int* sampleLen); void stop() { g_system->getMixer()->stopHandle(_audioHandle); } void pause() { g_system->getMixer()->pauseHandle(_audioHandle, true); } @@ -325,7 +329,9 @@ private: int16 _lang; byte *_audioMap; - bool findAudEntry(uint16 audioNumber, byte& volume, uint32& offset, uint32& size); + // TODO: these need better names + bool findAudEntryKQ5CD(uint16 audioNumber, byte& volume, uint32& offset, uint32& size); + bool findAudEntryKQ6Floppy(uint16 audioNumber, uint32& offset); }; } // End of namespace Sci |