aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFilippos Karapetis2010-06-05 14:09:52 +0000
committerFilippos Karapetis2010-06-05 14:09:52 +0000
commite9f35fbf4ce36b2a7cbdada429c5e7a2d49cbab8 (patch)
tree2e6f44766c87448e7e53168baa98fca019580ae0
parentb9065aa2d23d87c5da887ebe1f685230a4693827 (diff)
downloadscummvm-rg350-e9f35fbf4ce36b2a7cbdada429c5e7a2d49cbab8.tar.gz
scummvm-rg350-e9f35fbf4ce36b2a7cbdada429c5e7a2d49cbab8.tar.bz2
scummvm-rg350-e9f35fbf4ce36b2a7cbdada429c5e7a2d49cbab8.zip
Rewrote the remaining parts of the ResourceManager class to work with file streams, thus removing the SCI_detection hack in the fallback detector
svn-id: r49438
-rw-r--r--engines/sci/detection.cpp23
-rw-r--r--engines/sci/resource.cpp105
-rw-r--r--engines/sci/resource_audio.cpp26
3 files changed, 88 insertions, 66 deletions
diff --git a/engines/sci/detection.cpp b/engines/sci/detection.cpp
index aba2b0b74e..adec23c95e 100644
--- a/engines/sci/detection.cpp
+++ b/engines/sci/detection.cpp
@@ -373,19 +373,6 @@ const ADGameDescription *SciMetaEngine::fallbackDetect(const Common::FSList &fsl
filename.toLowercase();
if (filename.contains("resource.map") || filename.contains("resmap.00") || filename.contains("Data1")) {
- // HACK: resource.map is located in the same directory as the other resource files,
- // therefore add the directory here, so that the game files can be opened later on
- // We now add the parent directory temporary to our SearchMan so the engine code
- // used in the detection can access all files via Common::File without any problems.
- // In all branches returning from this function, we need to have a call to
- // SearchMan.remove to remove it from the default directory pool again.
- //
- // A proper solution to remove this hack would be to have the code, which is needed
- // for detection, to operate on Stream objects, so they can be easily called from
- // the detection code. This might be easily to achieve through refactoring the
- // code needed for detection.
- assert(!SearchMan.hasArchive("SCI_detection"));
- SearchMan.addDirectory("SCI_detection", file->getParent());
foundResMap = true;
}
@@ -429,7 +416,6 @@ const ADGameDescription *SciMetaEngine::fallbackDetect(const Common::FSList &fsl
// If these files aren't found, it can't be SCI
if (!foundResMap && !foundRes000) {
- SearchMan.remove("SCI_detection");
return 0;
}
@@ -437,11 +423,10 @@ const ADGameDescription *SciMetaEngine::fallbackDetect(const Common::FSList &fsl
ViewType gameViews = resMan->getViewType();
// Have we identified the game views? If not, stop here
+ // Can't be SCI (or unsupported SCI views). Pinball Creep by sierra also uses resource.map/resource.000 files
+ // but doesnt share sci format at all, if we dont return 0 here we will detect this game as SCI
if (gameViews == kViewUnknown) {
- SearchMan.remove("SCI_detection");
delete resMan;
- // Can't be SCI (or unsupported SCI views). Pinball Creep by sierra also uses resource.map/resource.000 files
- // but doesnt share sci format at all, if we dont return 0 here we will detect this game as SCI
return 0;
}
@@ -449,7 +434,6 @@ const ADGameDescription *SciMetaEngine::fallbackDetect(const Common::FSList &fsl
// Is SCI32 compiled in? If not, and this is a SCI32 game,
// stop here
if (getSciVersion() >= SCI_VERSION_2) {
- SearchMan.remove("SCI_detection");
delete resMan;
return (const ADGameDescription *)&s_fallbackDesc;
}
@@ -468,7 +452,6 @@ const ADGameDescription *SciMetaEngine::fallbackDetect(const Common::FSList &fsl
// If we don't have a game id, the game is not SCI
if (sierraGameId.empty()) {
- SearchMan.remove("SCI_detection");
delete resMan;
return 0;
}
@@ -522,8 +505,6 @@ const ADGameDescription *SciMetaEngine::fallbackDetect(const Common::FSList &fsl
if (s_fallbackDesc.flags & ADGF_DEMO)
s_fallbackDesc.extra = "demo";
- SearchMan.remove("SCI_detection");
-
return (const ADGameDescription *)&s_fallbackDesc;
}
diff --git a/engines/sci/resource.cpp b/engines/sci/resource.cpp
index 449effd737..b17117a1cd 100644
--- a/engines/sci/resource.cpp
+++ b/engines/sci/resource.cpp
@@ -371,6 +371,8 @@ void ResourceManager::loadResource(Resource *res) {
case kSourceWave:
fileStream->seek(res->_fileOffset, SEEK_SET);
loadFromWaveFile(res, fileStream);
+ if (res->_source->resourceFile)
+ delete fileStream;
return;
case kSourceAudioVolume:
@@ -408,6 +410,8 @@ void ResourceManager::loadResource(Resource *res) {
case kResourceTypeAudio36:
// Directly read the stream, compressed audio wont have resource type id and header size for SCI1.1
loadFromAudioVolumeSCI1(res, fileStream);
+ if (res->_source->resourceFile)
+ delete fileStream;
return;
default:
break;
@@ -420,11 +424,18 @@ void ResourceManager::loadResource(Resource *res) {
loadFromAudioVolumeSCI1(res, fileStream);
else
loadFromAudioVolumeSCI11(res, fileStream);
+
+ if (res->_source->resourceFile)
+ delete fileStream;
return;
default:
fileStream->seek(res->_fileOffset, SEEK_SET);
int error = decompress(res, fileStream);
+
+ if (res->_source->resourceFile)
+ delete fileStream;
+
if (error) {
warning("Error %d occured while reading %s from resource file: %s",
error, res->_id.toString().c_str(), sci_error_types[error]);
@@ -437,19 +448,6 @@ Resource *ResourceManager::testResource(ResourceId id) {
return _resMap.getVal(id, NULL);
}
-int sci0_get_compression_method(Common::ReadStream &stream) {
- uint16 compressionMethod;
-
- stream.readUint16LE();
- stream.readUint16LE();
- stream.readUint16LE();
- compressionMethod = stream.readUint16LE();
- if (stream.err())
- return SCI_ERROR_IO_ERROR;
-
- return compressionMethod;
-}
-
int ResourceManager::addAppropriateSources() {
Common::ArchiveMemberList files;
@@ -1205,25 +1203,34 @@ void ResourceManager::readResourcePatches(ResourceSource *source) {
}
int ResourceManager::readResourceMapSCI0(ResourceSource *map) {
- Common::File file;
+ Common::SeekableReadStream *fileStream = 0;
Resource *res;
ResourceType type;
uint16 number, id;
uint32 offset;
- if (!file.open(map->location_name))
- return SCI_ERROR_RESMAP_NOT_FOUND;
+ if (map->resourceFile) {
+ fileStream = map->resourceFile->createReadStream();
+ if (!fileStream)
+ return SCI_ERROR_RESMAP_NOT_FOUND;
+ } else {
+ Common::File *file = new Common::File();
+ if (!file->open(map->location_name))
+ return SCI_ERROR_RESMAP_NOT_FOUND;
+ fileStream = file;
+ }
- file.seek(0, SEEK_SET);
+ fileStream->seek(0, SEEK_SET);
byte bMask = (_mapVersion == kResVersionSci1Middle) ? 0xF0 : 0xFC;
byte bShift = (_mapVersion == kResVersionSci1Middle) ? 28 : 26;
do {
- id = file.readUint16LE();
- offset = file.readUint32LE();
+ id = fileStream->readUint16LE();
+ offset = fileStream->readUint32LE();
- if (file.eos() || file.err()) {
+ if (fileStream->eos() || fileStream->err()) {
+ delete fileStream;
warning("Error while reading %s", map->location_name.c_str());
return SCI_ERROR_RESMAP_NOT_FOUND;
}
@@ -1252,15 +1259,26 @@ int ResourceManager::readResourceMapSCI0(ResourceSource *map) {
res->_id = resId;
_resMap.setVal(resId, res);
}
- } while (!file.eos());
+ } while (!fileStream->eos());
+
+ delete fileStream;
return 0;
}
int ResourceManager::readResourceMapSCI1(ResourceSource *map) {
- Common::File file;
+ Common::SeekableReadStream *fileStream = 0;
Resource *res;
- if (!file.open(map->location_name))
- return SCI_ERROR_RESMAP_NOT_FOUND;
+
+ if (map->resourceFile) {
+ fileStream = map->resourceFile->createReadStream();
+ if (!fileStream)
+ return SCI_ERROR_RESMAP_NOT_FOUND;
+ } else {
+ Common::File *file = new Common::File();
+ if (!file->open(map->location_name))
+ return SCI_ERROR_RESMAP_NOT_FOUND;
+ fileStream = file;
+ }
resource_index_t resMap[32];
memset(resMap, 0, sizeof(resource_index_t) * 32);
@@ -1271,8 +1289,8 @@ int ResourceManager::readResourceMapSCI1(ResourceSource *map) {
// Read resource type and offsets to resource offsets block from .MAP file
// The last entry has type=0xFF (0x1F) and offset equals to map file length
do {
- type = file.readByte() & 0x1F;
- resMap[type].wOffset = file.readUint16LE();
+ type = fileStream->readByte() & 0x1F;
+ resMap[type].wOffset = fileStream->readUint16LE();
resMap[prevtype].wSize = (resMap[type].wOffset
- resMap[prevtype].wOffset) / nEntrySize;
prevtype = type;
@@ -1283,18 +1301,18 @@ int ResourceManager::readResourceMapSCI1(ResourceSource *map) {
for (type = 0; type < 32; type++) {
if (resMap[type].wOffset == 0) // this resource does not exist in map
continue;
- file.seek(resMap[type].wOffset);
+ fileStream->seek(resMap[type].wOffset);
for (int i = 0; i < resMap[type].wSize; i++) {
- uint16 number = file.readUint16LE();
+ uint16 number = fileStream->readUint16LE();
int volume_nr = 0;
if (_mapVersion == kResVersionSci11) {
// offset stored in 3 bytes
- off = file.readUint16LE();
- off |= file.readByte() << 16;
+ off = fileStream->readUint16LE();
+ off |= fileStream->readByte() << 16;
off <<= 1;
} else {
// offset/volume stored in 4 bytes
- off = file.readUint32LE();
+ off = fileStream->readUint32LE();
if (_mapVersion < kResVersionSci11) {
volume_nr = off >> 28; // most significant 4 bits
off &= 0x0FFFFFFF; // least significant 28 bits
@@ -1302,7 +1320,8 @@ int ResourceManager::readResourceMapSCI1(ResourceSource *map) {
// in SCI32 it's a plain offset
}
}
- if (file.eos() || file.err()) {
+ if (fileStream->eos() || fileStream->err()) {
+ delete fileStream;
warning("Error while reading %s", map->location_name.c_str());
return SCI_ERROR_RESMAP_NOT_FOUND;
}
@@ -1322,6 +1341,8 @@ int ResourceManager::readResourceMapSCI1(ResourceSource *map) {
}
}
}
+
+ delete fileStream;
return 0;
}
@@ -1574,7 +1595,7 @@ ResourceCompression ResourceManager::getViewCompression() {
// Test 10 views to see if any are compressed
for (int i = 0; i < 1000; i++) {
- Common::File *file;
+ Common::SeekableReadStream *fileStream = 0;
Resource *res = testResource(ResourceId(kResourceTypeView, i));
if (!res)
@@ -1583,16 +1604,26 @@ ResourceCompression ResourceManager::getViewCompression() {
if (res->_source->source_type != kSourceVolume)
continue;
- file = getVolumeFile(res->_source->location_name.c_str());
- if (!file)
+ if (res->_source->resourceFile)
+ fileStream = res->_source->resourceFile->createReadStream();
+ else
+ fileStream = getVolumeFile(res->_source->location_name.c_str());
+
+ if (!fileStream)
continue;
- file->seek(res->_fileOffset, SEEK_SET);
+ fileStream->seek(res->_fileOffset, SEEK_SET);
uint32 szPacked;
ResourceCompression compression;
- if (readResourceInfo(res, file, szPacked, compression))
+ if (readResourceInfo(res, fileStream, szPacked, compression)) {
+ if (res->_source->resourceFile)
+ delete fileStream;
continue;
+ }
+
+ if (res->_source->resourceFile)
+ delete fileStream;
if (compression != kCompNone)
return compression;
diff --git a/engines/sci/resource_audio.cpp b/engines/sci/resource_audio.cpp
index 67bac974fc..ebc549c772 100644
--- a/engines/sci/resource_audio.cpp
+++ b/engines/sci/resource_audio.cpp
@@ -33,13 +33,20 @@
namespace Sci {
void ResourceManager::checkIfAudioVolumeIsCompressed(ResourceSource *source) {
- Common::File *file = getVolumeFile(source->location_name.c_str());
- if (!file) {
+ Common::SeekableReadStream *fileStream;
+
+ if (source->resourceFile)
+ fileStream = source->resourceFile->createReadStream();
+ else
+ fileStream = getVolumeFile(source->location_name.c_str());
+
+ if (!fileStream) {
warning("Failed to open %s", source->location_name.c_str());
return;
}
- file->seek(0, SEEK_SET);
- uint32 compressionType = file->readUint32BE();
+
+ fileStream->seek(0, SEEK_SET);
+ uint32 compressionType = fileStream->readUint32BE();
switch (compressionType) {
case MKID_BE('MP3 '):
case MKID_BE('OGG '):
@@ -47,19 +54,22 @@ void ResourceManager::checkIfAudioVolumeIsCompressed(ResourceSource *source) {
// Detected a compressed audio volume
source->audioCompressionType = compressionType;
// Now read the whole offset mapping table for later usage
- int32 recordCount = file->readUint32LE();
+ int32 recordCount = fileStream->readUint32LE();
if (!recordCount)
error("compressed audio volume doesn't contain any entries!");
int32 *offsetMapping = new int32[(recordCount + 1) * 2];
source->audioCompressionOffsetMapping = offsetMapping;
for (int recordNo = 0; recordNo < recordCount; recordNo++) {
- *offsetMapping++ = file->readUint32LE();
- *offsetMapping++ = file->readUint32LE();
+ *offsetMapping++ = fileStream->readUint32LE();
+ *offsetMapping++ = fileStream->readUint32LE();
}
// Put ending zero
*offsetMapping++ = 0;
- *offsetMapping++ = file->size();
+ *offsetMapping++ = fileStream->size();
}
+
+ if (source->resourceFile)
+ delete fileStream;
}
bool ResourceManager::loadFromWaveFile(Resource *res, Common::SeekableReadStream *file) {