aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--engines/sci/resource.cpp175
-rw-r--r--engines/sci/resource.h2
2 files changed, 122 insertions, 55 deletions
diff --git a/engines/sci/resource.cpp b/engines/sci/resource.cpp
index f946f753d4..55059a1089 100644
--- a/engines/sci/resource.cpp
+++ b/engines/sci/resource.cpp
@@ -1252,14 +1252,8 @@ bool AudioResource::findAudEntrySCI1(uint16 audioNumber, byte &volume, uint32 &o
return false;
}
-bool AudioResource::findAudEntrySCI11(uint32 audioNumber, uint32 volume, uint32 &offset, bool getSync, uint32 *size) {
- // 65535.MAP structure:
- // =========
- // 6 byte entries:
- // w nEntry
- // dw offset
-
- // Other map files:
+bool AudioResource::findAudEntrySCI11Late(uint32 audioNumber, uint32 &offset, bool getSync, uint32 *size) {
+ // Map structure:
// ===============
// Header:
// dw baseOffset
@@ -1275,6 +1269,114 @@ bool AudioResource::findAudEntrySCI11(uint32 audioNumber, uint32 volume, uint32
uint32 n;
offset = 0;
+ byte *ptr = _audioMapSCI11->data;
+
+ offset = READ_UINT32(ptr);
+ ptr += 4;
+
+ while (ptr < _audioMapSCI11->data + _audioMapSCI11->size) {
+ n = READ_BE_UINT32(ptr);
+ ptr += 4;
+
+ if (n == 0xffffffff)
+ break;
+
+ offset += (READ_UINT16(ptr) | (ptr[2] << 16));
+ ptr += 3;
+
+ int syncSkip = 0;
+
+ if (n & 0x80) {
+ n ^= 0x80;
+
+ if (getSync) {
+ if (size)
+ *size = READ_UINT16(ptr);
+ } else {
+ syncSkip = READ_UINT16(ptr);
+ }
+
+ ptr += 2;
+
+ if (n & 0x40) {
+ n ^= 0x40;
+
+ if (!getSync)
+ syncSkip += READ_UINT16(ptr);
+
+ ptr += 2;
+ }
+
+ offset += syncSkip;
+
+ if (n == audioNumber)
+ return true;
+
+ } else {
+ if (n == audioNumber)
+ return !getSync;
+ }
+
+ offset -= syncSkip;
+ }
+
+ return false;
+}
+
+bool AudioResource::findAudEntrySCI11Early(uint32 audioNumber, uint32 &offset, bool getSync, uint32 *size) {
+ // Map structure:
+ // ===============
+ // 10-byte entries:
+ // b noun
+ // b verb
+ // b cond
+ // b seq
+ // dw offset
+ // w syncSize + syncAscSize
+
+ uint32 n;
+ offset = 0;
+
+ byte *ptr = _audioMapSCI11->data;
+
+ while (ptr < _audioMapSCI11->data + _audioMapSCI11->size) {
+ n = READ_BE_UINT32(ptr);
+ ptr += 4;
+
+ if (n == 0xffffffff)
+ break;
+
+ offset = READ_UINT32(ptr);
+ ptr += 4;
+
+ int syncSize = READ_UINT16(ptr);
+ ptr += 2;
+
+ if (n == audioNumber) {
+ if (getSync) {
+ if (size)
+ *size = syncSize;
+ return true;
+ } else {
+ offset += syncSize;
+ return true;
+ }
+ }
+ }
+
+ return false;
+}
+
+bool AudioResource::findAudEntrySCI11(uint32 audioNumber, uint32 volume, uint32 &offset, bool getSync, uint32 *size) {
+ // 65535.MAP structure:
+ // =========
+ // 6 byte entries:
+ // w nEntry
+ // dw offset
+
+ uint32 n;
+ offset = 0;
+
if (_audioMapSCI11 && _audioMapSCI11->number != volume) {
_resMgr->unlockResource(_audioMapSCI11, _audioMapSCI11->number, kResourceTypeMap);
_audioMapSCI11 = 0;
@@ -1301,53 +1403,16 @@ bool AudioResource::findAudEntrySCI11(uint32 audioNumber, uint32 volume, uint32
return true;
}
} else {
- offset = READ_UINT32(ptr);
- ptr += 4;
-
- while (ptr < _audioMapSCI11->data + _audioMapSCI11->size) {
- n = READ_BE_UINT32(ptr);
- ptr += 4;
-
- if (n == 0xffffffff)
- break;
-
- offset += (READ_UINT16(ptr) | (ptr[2] << 16));
- ptr += 3;
-
- int syncSkip = 0;
-
- if (n & 0x80) {
- n ^= 0x80;
-
- if (getSync) {
- if (size)
- *size = READ_UINT16(ptr);
- } else {
- syncSkip = READ_UINT16(ptr);
- }
-
- ptr += 2;
-
- if (n & 0x40) {
- n ^= 0x40;
-
- if (!getSync)
- syncSkip += READ_UINT16(ptr);
-
- ptr += 2;
- }
-
- offset += syncSkip;
-
- if (n == audioNumber)
- return true;
-
- } else {
- if (n == audioNumber)
- return !getSync;
- }
-
- offset -= syncSkip;
+ // In early SCI1.1 the map is terminated with 10x 0xff, in late SCI1.1
+ // with 11x 0xff. If we look at the 11th last byte in an early SCI1.1
+ // map, this will be the high byte of the Sync length of the last entry.
+ // As Sync resources are relative small, we should never encounter a
+ // Sync with a size of 0xffnn. As such, the following heuristic should be
+ // sufficient to tell these map formats apart.
+ if (_audioMapSCI11->size >= 11 && (ptr[_audioMapSCI11->size - 11] == 0xff))
+ return findAudEntrySCI11Late(audioNumber, offset, getSync, size);
+ else {
+ return findAudEntrySCI11Early(audioNumber, offset, getSync, size);
}
}
diff --git a/engines/sci/resource.h b/engines/sci/resource.h
index a693f696db..b1ae3d23ba 100644
--- a/engines/sci/resource.h
+++ b/engines/sci/resource.h
@@ -343,6 +343,8 @@ private:
bool findAudEntrySCI1(uint16 audioNumber, byte &volume, uint32 &offset, uint32 &size);
bool findAudEntrySCI11(uint32 audioNumber, uint32 volume, uint32 &offset, bool getSync = false, uint32 *size = NULL);
+ bool findAudEntrySCI11Late(uint32 audioNumber, uint32 &offset, bool getSync, uint32 *size);
+ bool findAudEntrySCI11Early(uint32 audioNumber, uint32 &offset, bool getSync, uint32 *size);
};
} // End of namespace Sci