diff options
Diffstat (limited to 'engines/sci/resource_audio.cpp')
-rw-r--r-- | engines/sci/resource_audio.cpp | 124 |
1 files changed, 46 insertions, 78 deletions
diff --git a/engines/sci/resource_audio.cpp b/engines/sci/resource_audio.cpp index a5501cdb84..2cd157a631 100644 --- a/engines/sci/resource_audio.cpp +++ b/engines/sci/resource_audio.cpp @@ -36,7 +36,6 @@ AudioVolumeResourceSource::AudioVolumeResourceSource(ResourceManager *resMan, co : VolumeResourceSource(name, map, volNum, kSourceAudioVolume) { _audioCompressionType = 0; - _audioCompressionOffsetMapping = NULL; /* * Check if this audio volume got compressed by our tool. If that is the @@ -49,36 +48,37 @@ AudioVolumeResourceSource::AudioVolumeResourceSource(ResourceManager *resMan, co return; fileStream->seek(0, SEEK_SET); - uint32 compressionType = fileStream->readUint32BE(); + const uint32 compressionType = fileStream->readUint32BE(); switch (compressionType) { case MKTAG('M','P','3',' '): case MKTAG('O','G','G',' '): case MKTAG('F','L','A','C'): - // Detected a compressed audio volume _audioCompressionType = compressionType; - // Now read the whole offset mapping table for later usage - int32 recordCount = fileStream->readUint32LE(); - if (!recordCount) - error("compressed audio volume doesn't contain any entries"); - int32 *offsetMapping = new int32[(recordCount + 1) * 2]; - _audioCompressionOffsetMapping = offsetMapping; - for (int recordNo = 0; recordNo < recordCount; recordNo++) { - *offsetMapping++ = fileStream->readUint32LE(); - *offsetMapping++ = fileStream->readUint32LE(); + const uint32 numEntries = fileStream->readUint32LE(); + if (!numEntries) { + error("Compressed audio volume %s has no relocation table entries", name.c_str()); } - // Put ending zero - *offsetMapping++ = 0; - *offsetMapping++ = fileStream->size(); + + CompressedTableEntry *lastEntry = nullptr; + for (uint i = 0; i < numEntries; ++i) { + CompressedTableEntry nextEntry; + const uint32 sourceOffset = fileStream->readUint32LE(); + nextEntry.offset = fileStream->readUint32LE(); + if (lastEntry != nullptr) { + lastEntry->size = nextEntry.offset - lastEntry->offset; + } + + _compressedOffsets.setVal(sourceOffset, nextEntry); + lastEntry = &_compressedOffsets.getVal(sourceOffset); + } + + lastEntry->size = fileStream->size() - lastEntry->offset; } if (_resourceFile) delete fileStream; } -AudioVolumeResourceSource::~AudioVolumeResourceSource() { - delete[] _audioCompressionOffsetMapping; -} - bool Resource::loadFromWaveFile(Common::SeekableReadStream *file) { byte *ptr = new byte[_size]; _data = ptr; @@ -315,7 +315,7 @@ int ResourceManager::readAudioMapSCI11(IntMapResourceSource *map) { Common::SeekableReadStream *fileStream = getVolumeFile(src); if (!fileStream) { - warning("Failed to open file stream for %s", mapResId.toString().c_str()); + warning("Failed to open file stream for %s", src->getLocationName().c_str()); return SCI_ERROR_NO_RESOURCE_FILES_FOUND; } @@ -383,17 +383,21 @@ int ResourceManager::readAudioMapSCI11(IntMapResourceSource *map) { offset = ptr.getUint32LE(); ptr += 4; - // The size is not stored in the map and the entries have no order. - // We need to dig into the audio resource in the volume to get the size. - stream->seek(offset + 1); - byte headerSize = stream->readByte(); - if (headerSize != 11 && headerSize != 12) { - error("Unexpected header size in %s: should be 11 or 12, got %d", audioResId.toString().c_str(), headerSize); - } - - stream->skip(7); - uint32 size = stream->readUint32LE() + headerSize + 2; + uint32 size; + if (src->getAudioCompressionType() == 0) { + // The size is not stored in the map and the entries have no order. + // We need to dig into the audio resource in the volume to get the size. + stream->seek(offset + 1); + byte headerSize = stream->readByte(); + if (headerSize != 11 && headerSize != 12) { + error("Unexpected header size in %s: should be 11 or 12, got %d", audioResId.toString().c_str(), headerSize); + } + stream->skip(7); + size = stream->readUint32LE() + headerSize + 2; + } else { + size = 0; + } addResource(audioResId, src, offset, size, map->getLocationName()); } } else { @@ -406,7 +410,7 @@ int ResourceManager::readAudioMapSCI11(IntMapResourceSource *map) { while (ptr != mapRes->cend()) { uint32 n = ptr.getUint32BE(); - int syncSize = 0; + uint32 syncSize = 0; ptr += 4; if (n == 0xffffffff) @@ -436,7 +440,7 @@ int ResourceManager::readAudioMapSCI11(IntMapResourceSource *map) { if (g_sci->getGameId() == GID_KQ6 && (n & 0x40)) { // This seems to define the size of raw lipsync data (at least // in KQ6 CD Windows). - int kq6HiresSyncSize = ptr.getUint16LE(); + uint32 kq6HiresSyncSize = ptr.getUint16LE(); ptr += 2; if (kq6HiresSyncSize > 0) { @@ -924,52 +928,16 @@ void AudioVolumeResourceSource::loadResource(ResourceManager *resMan, Resource * if (!fileStream) return; - if (_audioCompressionType) { - // this file is compressed, so lookup our offset in the offset-translation table and get the new offset - // also calculate the compressed size by using the next offset - int32 *mappingTable = _audioCompressionOffsetMapping; - int32 compressedOffset = 0; - - do { - if (*mappingTable == res->_fileOffset) { - mappingTable++; - compressedOffset = *mappingTable; - // Go to next compressed offset and use that to calculate size of compressed sample - switch (res->getType()) { - case kResourceTypeSync: - case kResourceTypeSync36: - case kResourceTypeRave: - // we should already have a (valid) size - break; - default: - mappingTable += 2; - res->_size = *mappingTable - compressedOffset; - } - break; - } - mappingTable += 2; - } while (*mappingTable); - - if (!compressedOffset) - error("could not translate offset to compressed offset in audio volume"); - fileStream->seek(compressedOffset, SEEK_SET); - - switch (res->getType()) { - case kResourceTypeAudio: - case kResourceTypeAudio36: - // Directly read the stream, compressed audio wont have resource type id and header size for SCI1.1 - res->loadFromAudioVolumeSCI1(fileStream); - if (_resourceFile) - delete fileStream; - return; - default: - break; - } - } else { - // original file, directly seek to given offset and get SCI1/SCI1.1 audio resource - fileStream->seek(res->_fileOffset, SEEK_SET); - } - if (getSciVersion() < SCI_VERSION_1_1) + fileStream->seek(res->_fileOffset, SEEK_SET); + + // For compressed audio, using loadFromAudioVolumeSCI1 is a hack to bypass + // the resource type checking in loadFromAudioVolumeSCI11 (since + // loadFromAudioVolumeSCI1 does nothing more than read raw data) + if (_audioCompressionType != 0 && + (res->getType() == kResourceTypeAudio || + res->getType() == kResourceTypeAudio36)) { + res->loadFromAudioVolumeSCI1(fileStream); + } else if (getSciVersion() < SCI_VERSION_1_1) res->loadFromAudioVolumeSCI1(fileStream); else res->loadFromAudioVolumeSCI11(fileStream); |