aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--engines/sci/detection.cpp4
-rw-r--r--engines/sci/resource.cpp38
-rw-r--r--engines/sci/resource.h9
-rw-r--r--engines/sci/resource_audio.cpp38
-rw-r--r--engines/sci/resource_intern.h5
5 files changed, 75 insertions, 19 deletions
diff --git a/engines/sci/detection.cpp b/engines/sci/detection.cpp
index f5797dc106..ad2b0f31a5 100644
--- a/engines/sci/detection.cpp
+++ b/engines/sci/detection.cpp
@@ -565,8 +565,8 @@ const ADGameDescription *SciMetaEngine::fallbackDetect(const FileMap &allFiles,
// the file should be over 10MB, as it contains all the game speech and is usually
// around 450MB+. The size check is for some floppy game versions like KQ6 floppy, which
// also have a small resource.aud file
- if (allFiles.contains("resource.aud") || allFiles.contains("audio001.002")) {
- Common::FSNode file = allFiles.contains("resource.aud") ? allFiles["resource.aud"] : allFiles["audio001.002"];
+ if (allFiles.contains("resource.aud") || allFiles.contains("resaud.001") || allFiles.contains("audio001.002")) {
+ Common::FSNode file = allFiles.contains("resource.aud") ? allFiles["resource.aud"] : (allFiles.contains("resaud.001") ? allFiles["resaud.001"] : allFiles["audio001.002"]);
Common::SeekableReadStream *tmpStream = file.createReadStream();
if (tmpStream->size() > 10 * 1024 * 1024) {
// We got a CD version, so set the CD flag accordingly
diff --git a/engines/sci/resource.cpp b/engines/sci/resource.cpp
index 26b8a32861..f2321f5589 100644
--- a/engines/sci/resource.cpp
+++ b/engines/sci/resource.cpp
@@ -573,6 +573,9 @@ Resource *ResourceManager::testResource(ResourceId id) {
}
int ResourceManager::addAppropriateSources() {
+#ifdef ENABLE_SCI32
+ _multiDiscAudio = false;
+#endif
if (Common::File::exists("resource.map")) {
// SCI0-SCI2 file naming scheme
ResourceSource *map = addExternalMap("resource.map");
@@ -615,6 +618,10 @@ int ResourceManager::addAppropriateSources() {
if (mapFiles.empty() || files.empty() || mapFiles.size() != files.size())
return 0;
+ if (Common::File::exists("resaud.001")) {
+ _multiDiscAudio = true;
+ }
+
for (Common::ArchiveMemberList::const_iterator mapIterator = mapFiles.begin(); mapIterator != mapFiles.end(); ++mapIterator) {
Common::String mapName = (*mapIterator)->getName();
int mapNumber = atoi(strrchr(mapName.c_str(), '.') + 1);
@@ -1747,11 +1754,42 @@ int ResourceManager::readResourceMapSCI1(ResourceSource *map) {
// if we use the first entries in the resource file, half of the
// game will be English and umlauts will also be missing :P
if (resource->_source->getSourceType() == kSourceVolume) {
+ // Maps are read during the scanning process (below), so
+ // need to be treated as unallocated in order for the new
+ // data from this volume to be picked up and used
+ if (resId.getType() == kResourceTypeMap) {
+ resource->_status = kResStatusNoMalloc;
+ }
resource->_source = source;
resource->_fileOffset = fileOffset;
resource->size = 0;
}
}
+
+#ifdef ENABLE_SCI32
+ // Different CDs may have different audio maps on each disc. The
+ // ResourceManager does not know how to deal with this; it expects
+ // each resource ID to be unique across an entire game. To work
+ // around this problem, all audio maps from this disc must be
+ // processed immediately, since they will be replaced by the audio
+ // map from the next disc on the next call to readResourceMapSCI1
+ if (_multiDiscAudio && resId.getType() == kResourceTypeMap) {
+ IntMapResourceSource *audioMap = static_cast<IntMapResourceSource *>(addSource(new IntMapResourceSource("MAP", mapVolumeNr, resId.getNumber())));
+ Common::String volumeName;
+ if (resId.getNumber() == 65535) {
+ volumeName = Common::String::format("RESSFX.%03d", mapVolumeNr);
+ } else {
+ volumeName = Common::String::format("RESAUD.%03d", mapVolumeNr);
+ }
+
+ ResourceSource *audioVolume = addSource(new AudioVolumeResourceSource(this, volumeName, audioMap, mapVolumeNr));
+ if (!audioMap->_scanned) {
+ audioVolume->_scanned = true;
+ audioMap->_scanned = true;
+ audioMap->scanSource(this);
+ }
+ }
+#endif
}
}
diff --git a/engines/sci/resource.h b/engines/sci/resource.h
index 49cc52399e..70db5909b7 100644
--- a/engines/sci/resource.h
+++ b/engines/sci/resource.h
@@ -296,6 +296,7 @@ protected:
typedef Common::HashMap<ResourceId, Resource *, ResourceIdHash> ResourceMap;
+class IntMapResourceSource;
class ResourceManager {
// FIXME: These 'friend' declarations are meant to be a temporary hack to
// ease transition to the ResourceSource class system.
@@ -414,6 +415,12 @@ private:
*/
int16 _currentDiscNo;
+ /**
+ * If true, the game has multiple audio volumes that contain different
+ * audio files for each disc.
+ */
+ bool _multiDiscAudio;
+
public:
#endif
@@ -538,7 +545,7 @@ protected:
* @param map The map
* @return 0 on success, an SCI_ERROR_* code otherwise
*/
- int readAudioMapSCI11(ResourceSource *map);
+ int readAudioMapSCI11(IntMapResourceSource *map);
/**
* Reads SCI1 audio map files.
diff --git a/engines/sci/resource_audio.cpp b/engines/sci/resource_audio.cpp
index 5ab443a16d..cbc4a02739 100644
--- a/engines/sci/resource_audio.cpp
+++ b/engines/sci/resource_audio.cpp
@@ -277,7 +277,7 @@ void ResourceManager::removeAudioResource(ResourceId resId) {
// w syncSize (iff seq has bit 7 set)
// w syncAscSize (iff seq has bit 6 set)
-int ResourceManager::readAudioMapSCI11(ResourceSource *map) {
+int ResourceManager::readAudioMapSCI11(IntMapResourceSource *map) {
#ifndef ENABLE_SCI32
// SCI32 support is not built in. Check if this is a SCI32 game
// and if it is abort here.
@@ -286,17 +286,19 @@ int ResourceManager::readAudioMapSCI11(ResourceSource *map) {
#endif
uint32 offset = 0;
- Resource *mapRes = findResource(ResourceId(kResourceTypeMap, map->_volumeNumber), false);
+ Resource *mapRes = findResource(ResourceId(kResourceTypeMap, map->_mapNumber), false);
if (!mapRes) {
- warning("Failed to open %i.MAP", map->_volumeNumber);
+ warning("Failed to open %i.MAP", map->_mapNumber);
return SCI_ERROR_RESMAP_NOT_FOUND;
}
- ResourceSource *src = findVolume(map, 0);
+ ResourceSource *src = findVolume(map, map->_volumeNumber);
- if (!src)
+ if (!src) {
+ warning("Failed to find volume for %i.MAP", map->_mapNumber);
return SCI_ERROR_NO_RESOURCE_FILES_FOUND;
+ }
byte *ptr = mapRes->data;
@@ -309,7 +311,7 @@ int ResourceManager::readAudioMapSCI11(ResourceSource *map) {
break;
}
- if (map->_volumeNumber == 65535) {
+ if (map->_mapNumber == 65535) {
while (ptr < mapRes->data + mapRes->size) {
uint16 n = READ_LE_UINT16(ptr);
ptr += 2;
@@ -327,7 +329,7 @@ int ResourceManager::readAudioMapSCI11(ResourceSource *map) {
addResource(ResourceId(kResourceTypeAudio, n), src, offset);
}
- } else if (map->_volumeNumber == 0 && entrySize == 10 && ptr[3] == 0) {
+ } else if (map->_mapNumber == 0 && entrySize == 10 && ptr[3] == 0) {
// QFG3 demo format
// ptr[3] would be 'seq' in the normal format and cannot possibly be 0
while (ptr < mapRes->data + mapRes->size) {
@@ -344,7 +346,7 @@ int ResourceManager::readAudioMapSCI11(ResourceSource *map) {
addResource(ResourceId(kResourceTypeAudio, n), src, offset, size);
}
- } else if (map->_volumeNumber == 0 && entrySize == 8 && READ_LE_UINT16(ptr + 2) == 0xffff) {
+ } else if (map->_mapNumber == 0 && entrySize == 8 && READ_LE_UINT16(ptr + 2) == 0xffff) {
// LB2 Floppy/Mother Goose SCI1.1 format
Common::SeekableReadStream *stream = getVolumeFile(src);
@@ -400,7 +402,7 @@ int ResourceManager::readAudioMapSCI11(ResourceSource *map) {
// 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);
+ addResource(ResourceId(kResourceTypeSync36, map->_mapNumber, n & 0xffffff3f), src, offset, syncSize);
}
if (n & 0x40) {
@@ -410,12 +412,12 @@ int ResourceManager::readAudioMapSCI11(ResourceSource *map) {
ptr += 2;
if (kq6HiresSyncSize > 0) {
- addResource(ResourceId(kResourceTypeRave, map->_volumeNumber, n & 0xffffff3f), src, offset + syncSize, kq6HiresSyncSize);
+ addResource(ResourceId(kResourceTypeRave, map->_mapNumber, n & 0xffffff3f), src, offset + syncSize, kq6HiresSyncSize);
syncSize += kq6HiresSyncSize;
}
}
- addResource(ResourceId(kResourceTypeAudio36, map->_volumeNumber, n & 0xffffff3f), src, offset + syncSize);
+ addResource(ResourceId(kResourceTypeAudio36, map->_mapNumber, n & 0xffffff3f), src, offset + syncSize);
}
}
@@ -937,13 +939,21 @@ void AudioVolumeResourceSource::loadResource(ResourceManager *resMan, Resource *
}
bool ResourceManager::addAudioSources() {
+#ifdef ENABLE_SCI32
+ // Multi-disc audio is added during addAppropriateSources for those titles
+ // that require it
+ if (_multiDiscAudio) {
+ return true;
+ }
+#endif
+
Common::List<ResourceId> resources = listResources(kResourceTypeMap);
Common::List<ResourceId>::iterator itr;
for (itr = resources.begin(); itr != resources.end(); ++itr) {
- ResourceSource *src = addSource(new IntMapResourceSource("MAP", itr->getNumber()));
+ ResourceSource *src = addSource(new IntMapResourceSource("MAP", 0, itr->getNumber()));
- if ((itr->getNumber() == 65535) && Common::File::exists("RESOURCE.SFX"))
+ if (itr->getNumber() == 65535 && Common::File::exists("RESOURCE.SFX"))
addSource(new AudioVolumeResourceSource(this, "RESOURCE.SFX", src, 0));
else if (Common::File::exists("RESOURCE.AUD"))
addSource(new AudioVolumeResourceSource(this, "RESOURCE.AUD", src, 0));
@@ -991,7 +1001,7 @@ void ResourceManager::changeAudioDirectory(Common::String path) {
if ((it->getNumber() == 65535))
continue;
- ResourceSource *src = addSource(new IntMapResourceSource(mapName, it->getNumber()));
+ ResourceSource *src = addSource(new IntMapResourceSource(mapName, 0, it->getNumber()));
addSource(new AudioVolumeResourceSource(this, audioResourceName, src, 0));
}
diff --git a/engines/sci/resource_intern.h b/engines/sci/resource_intern.h
index 461d684005..fe4b0a97f4 100644
--- a/engines/sci/resource_intern.h
+++ b/engines/sci/resource_intern.h
@@ -134,8 +134,9 @@ public:
class IntMapResourceSource : public ResourceSource {
public:
- IntMapResourceSource(const Common::String &name, int volNum)
- : ResourceSource(kSourceIntMap, name, volNum) {
+ uint16 _mapNumber;
+ IntMapResourceSource(const Common::String &name, int volNum, int mapNum)
+ : ResourceSource(kSourceIntMap, name, volNum), _mapNumber(mapNum) {
}
virtual void scanSource(ResourceManager *resMan);