aboutsummaryrefslogtreecommitdiff
path: root/engines/sci/resource_audio.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'engines/sci/resource_audio.cpp')
-rw-r--r--engines/sci/resource_audio.cpp122
1 files changed, 76 insertions, 46 deletions
diff --git a/engines/sci/resource_audio.cpp b/engines/sci/resource_audio.cpp
index 744f05f2b9..8e1568f564 100644
--- a/engines/sci/resource_audio.cpp
+++ b/engines/sci/resource_audio.cpp
@@ -101,32 +101,34 @@ bool Resource::loadFromAudioVolumeSCI11(Common::SeekableReadStream *file) {
}
file->seek(-4, SEEK_CUR);
- ResourceType type = _resMan->convertResType(file->readByte());
- if (((getType() == kResourceTypeAudio || getType() == kResourceTypeAudio36) && (type != kResourceTypeAudio))
- || ((getType() == kResourceTypeSync || getType() == kResourceTypeSync36) && (type != kResourceTypeSync))) {
- warning("Resource type mismatch loading %s", _id.toString().c_str());
- unalloc();
- return false;
- }
-
- _headerSize = file->readByte();
-
- if (type == kResourceTypeAudio) {
- if (_headerSize != 7 && _headerSize != 11 && _headerSize != 12) {
- warning("Unsupported audio header");
+ // Rave-resources (King's Quest 6) don't have any header at all
+ if (getType() != kResourceTypeRave) {
+ ResourceType type = _resMan->convertResType(file->readByte());
+ if (((getType() == kResourceTypeAudio || getType() == kResourceTypeAudio36) && (type != kResourceTypeAudio))
+ || ((getType() == kResourceTypeSync || getType() == kResourceTypeSync36) && (type != kResourceTypeSync))) {
+ warning("Resource type mismatch loading %s", _id.toString().c_str());
unalloc();
return false;
}
+
+ _headerSize = file->readByte();
+
+ if (type == kResourceTypeAudio) {
+ if (_headerSize != 7 && _headerSize != 11 && _headerSize != 12) {
+ warning("Unsupported audio header");
+ unalloc();
+ return false;
+ }
- if (_headerSize != 7) { // Size is defined already from the map
- // Load sample size
- file->seek(7, SEEK_CUR);
- size = file->readUint32LE();
- // Adjust offset to point at the header data again
- file->seek(-11, SEEK_CUR);
+ if (_headerSize != 7) { // Size is defined already from the map
+ // Load sample size
+ file->seek(7, SEEK_CUR);
+ size = file->readUint32LE();
+ // Adjust offset to point at the header data again
+ file->seek(-11, SEEK_CUR);
+ }
}
}
-
return loadPatch(file);
}
@@ -395,15 +397,22 @@ int ResourceManager::readAudioMapSCI11(ResourceSource *map) {
syncSize = READ_LE_UINT16(ptr);
ptr += 2;
+ // FIXME: The sync36 resource seems to be two bytes too big in KQ6CD
+ // (bytes taken from the RAVE resource right after it)
if (syncSize > 0)
addResource(ResourceId(kResourceTypeSync36, map->_volumeNumber, n & 0xffffff3f), src, offset, syncSize);
}
if (n & 0x40) {
// This seems to define the size of raw lipsync data (at least
- // in kq6), may also just be general appended data.
- syncSize += READ_LE_UINT16(ptr);
+ // in KQ6 CD Windows).
+ int kq6HiresSyncSize = READ_LE_UINT16(ptr);
ptr += 2;
+
+ if (kq6HiresSyncSize > 0) {
+ addResource(ResourceId(kResourceTypeRave, map->_volumeNumber, n & 0xffffff3f), src, offset + syncSize, kq6HiresSyncSize);
+ syncSize += kq6HiresSyncSize;
+ }
}
addResource(ResourceId(kResourceTypeAudio36, map->_volumeNumber, n & 0xffffff3f), src, offset + syncSize);
@@ -590,6 +599,7 @@ SoundResource::SoundResource(uint32 resourceNr, ResourceManager *resMan, SciVers
_tracks->channels = new Channel[_tracks->channelCount];
memset(_tracks->channels, 0, sizeof(Channel) * _tracks->channelCount);
channel = &_tracks->channels[0];
+ channel->flags |= 2; // don't remap (SCI0 doesn't have remapping)
if (_soundVersion == SCI_VERSION_0_EARLY) {
channel->data = resource->data + 0x11;
channel->size = resource->size - 0x11;
@@ -667,33 +677,52 @@ SoundResource::SoundResource(uint32 resourceNr, ResourceManager *resMan, SciVers
channelNr = 0;
while (channelCount--) {
channel = &_tracks[trackNr].channels[channelNr];
- channel->prio = READ_LE_UINT16(data);
uint dataOffset = READ_LE_UINT16(data + 2);
- if (dataOffset < resource->size) {
- channel->data = resource->data + dataOffset;
- channel->size = READ_LE_UINT16(data + 4);
- channel->curPos = 0;
- // FIXME: number contains (low nibble) channel and (high nibble) flags
- // 0x20 is set on rhythm channels to prevent remapping
- channel->number = *channel->data;
- channel->poly = *(channel->data + 1);
- channel->time = channel->prev = 0;
- channel->data += 2; // skip over header
- channel->size -= 2; // remove header size
- if (channel->number == 0xFE) { // Digital channel
- _tracks[trackNr].digitalChannelNr = channelNr;
- _tracks[trackNr].digitalSampleRate = READ_LE_UINT16(channel->data);
- _tracks[trackNr].digitalSampleSize = READ_LE_UINT16(channel->data + 2);
- _tracks[trackNr].digitalSampleStart = READ_LE_UINT16(channel->data + 4);
- _tracks[trackNr].digitalSampleEnd = READ_LE_UINT16(channel->data + 6);
- channel->data += 8; // Skip over header
- channel->size -= 8;
- }
- _tracks[trackNr].channelCount++;
- channelNr++;
- } else {
+
+ if (dataOffset >= resource->size) {
warning("Invalid offset inside sound resource %d: track %d, channel %d", resourceNr, trackNr, channelNr);
+ data += 6;
+ continue;
+ }
+
+ channel->data = resource->data + dataOffset;
+ channel->size = READ_LE_UINT16(data + 4);
+ channel->curPos = 0;
+ channel->number = *channel->data;
+
+ channel->poly = *(channel->data + 1) & 0x0F;
+ channel->prio = *(channel->data + 1) >> 4;
+ channel->time = channel->prev = 0;
+ channel->data += 2; // skip over header
+ channel->size -= 2; // remove header size
+ if (channel->number == 0xFE) { // Digital channel
+ _tracks[trackNr].digitalChannelNr = channelNr;
+ _tracks[trackNr].digitalSampleRate = READ_LE_UINT16(channel->data);
+ _tracks[trackNr].digitalSampleSize = READ_LE_UINT16(channel->data + 2);
+ _tracks[trackNr].digitalSampleStart = READ_LE_UINT16(channel->data + 4);
+ _tracks[trackNr].digitalSampleEnd = READ_LE_UINT16(channel->data + 6);
+ channel->data += 8; // Skip over header
+ channel->size -= 8;
+ channel->flags = 0;
+ } else {
+ channel->flags = channel->number >> 4;
+ channel->number = channel->number & 0x0F;
+
+ // 0x20 is set on rhythm channels to prevent remapping
+ // CHECKME: Which SCI versions need that set manually?
+ channel->flags = (*channel->data) >> 4;
+ if (channel->number == 9)
+ channel->flags |= 2;
+ // Note: flag 1: channel start offset is 0 instead of 10
+ // (currently: everything 0)
+ // also: don't map the channel to device
+ // flag 2: don't remap
+ // flag 4: start muted
+ // QfG2 lacks flags 2 and 4, and uses (flags >= 1) as
+ // the condition for starting offset 0, without the "don't map"
}
+ _tracks[trackNr].channelCount++;
+ channelNr++;
data += 6;
}
} else {
@@ -856,6 +885,7 @@ void AudioVolumeResourceSource::loadResource(ResourceManager *resMan, Resource *
switch (res->getType()) {
case kResourceTypeSync:
case kResourceTypeSync36:
+ case kResourceTypeRave:
// we should already have a (valid) size
break;
default: