mirror of
https://github.com/libretro/scummvm.git
synced 2024-12-14 21:59:17 +00:00
SCI32: Enable multi-disc audio resources
Phant1, PQ:SWAT, GK2, and Phant2 all have different audio maps and audio volumes on each CD. In order to make this work within ScummVM, where CDs are never swapped, each RESOURCE.AUD for these games must be renamed to RESAUD.00x and each RESOURCE.SFX renamed to RESSFX.00x.
This commit is contained in:
parent
0a4a2567a3
commit
c4250c05d0
@ -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
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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));
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user