aboutsummaryrefslogtreecommitdiff
path: root/engines/sci/resource.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'engines/sci/resource.cpp')
-rw-r--r--engines/sci/resource.cpp119
1 files changed, 86 insertions, 33 deletions
diff --git a/engines/sci/resource.cpp b/engines/sci/resource.cpp
index 00f50714af..9809f10576 100644
--- a/engines/sci/resource.cpp
+++ b/engines/sci/resource.cpp
@@ -92,7 +92,7 @@ const char *getSciVersionDesc(SciVersion version) {
#undef SCI_REQUIRE_RESOURCE_FILES
-//#define SCI_VERBOSE_resMan 1
+//#define SCI_VERBOSE_RESMAN 1
static const char *sci_error_types[] = {
"No error",
@@ -142,7 +142,6 @@ static const ResourceType s_resTypeMapSci0[] = {
kResourceTypeTranslation // 0x14
};
-#ifdef ENABLE_SCI32
// TODO: 12 should be "Wave", but SCI seems to just store it in Audio resources
static const ResourceType s_resTypeMapSci21[] = {
kResourceTypeView, kResourceTypePic, kResourceTypeScript, kResourceTypeText, // 0x00-0x03
@@ -152,7 +151,6 @@ static const ResourceType s_resTypeMapSci21[] = {
kResourceTypeMap, kResourceTypeHeap, kResourceTypeChunk, kResourceTypeAudio36, // 0x10-0x13
kResourceTypeSync36, kResourceTypeTranslation, kResourceTypeRobot, kResourceTypeVMD // 0x14-0x17
};
-#endif
ResourceType ResourceManager::convertResType(byte type) {
type &= 0x7f;
@@ -163,7 +161,6 @@ ResourceType ResourceManager::convertResType(byte type) {
return s_resTypeMapSci0[type];
} else {
// SCI2.1+
-#ifdef ENABLE_SCI32
if (type < ARRAYSIZE(s_resTypeMapSci21)) {
// LSL6 hires doesn't have the chunk resource type, to match
// the resource types of the lowres version, thus we use the
@@ -173,9 +170,6 @@ ResourceType ResourceManager::convertResType(byte type) {
else
return s_resTypeMapSci21[type];
}
-#else
- error("SCI32 support not compiled in");
-#endif
}
return kResourceTypeInvalid;
@@ -490,8 +484,9 @@ void ResourceSource::loadResource(ResourceManager *resMan, Resource *res) {
int error = res->decompress(resMan->getVolVersion(), fileStream);
if (error) {
- warning("Error %d occurred while reading %s from resource file: %s",
- error, res->_id.toString().c_str(), sci_error_types[error]);
+ warning("Error %d occurred while reading %s from resource file %s: %s",
+ error, res->_id.toString().c_str(), res->getResourceLocation().c_str(),
+ sci_error_types[error]);
res->unalloc();
}
@@ -852,7 +847,16 @@ void ResourceManager::init() {
debugC(1, kDebugLevelResMan, "resMan: Detected Amiga graphic resources");
break;
default:
+#ifdef ENABLE_SCI32
error("resMan: Couldn't determine view type");
+#else
+ if (getSciVersion() >= SCI_VERSION_2) {
+ // SCI support isn't built in, thus the view type won't be determined for
+ // SCI2+ games. This will be handled further up, so throw no error here
+ } else {
+ error("resMan: Couldn't determine view type");
+ }
+#endif
}
#ifdef ENABLE_SCI32
@@ -904,7 +908,7 @@ void ResourceManager::addToLRU(Resource *res) {
}
_LRU.push_front(res);
_memoryLRU += res->size;
-#if SCI_VERBOSE_resMan
+#if SCI_VERBOSE_RESMAN
debug("Adding %s.%03d (%d bytes) to lru control: %d bytes total",
getResourceTypeName(res->type), res->number, res->size,
mgr->_memoryLRU);
@@ -935,7 +939,7 @@ void ResourceManager::freeOldResources() {
Resource *goner = *_LRU.reverse_begin();
removeFromLRU(goner);
goner->unalloc();
-#ifdef SCI_VERBOSE_resMan
+#ifdef SCI_VERBOSE_RESMAN
printf("resMan-debug: LRU: Freeing %s.%03d (%d bytes)\n", getResourceTypeName(goner->type), goner->number, goner->size);
#endif
}
@@ -1518,7 +1522,7 @@ int ResourceManager::readResourceMapSCI1(ResourceSource *map) {
} while (type != 0x1F); // the last entry is FF
// reading each type's offsets
- uint32 off = 0;
+ uint32 fileOffset = 0;
for (type = 0; type < 32; type++) {
if (resMap[type].wOffset == 0) // this resource does not exist in map
continue;
@@ -1528,15 +1532,15 @@ int ResourceManager::readResourceMapSCI1(ResourceSource *map) {
int volume_nr = 0;
if (_mapVersion == kResVersionSci11) {
// offset stored in 3 bytes
- off = fileStream->readUint16LE();
- off |= fileStream->readByte() << 16;
- off <<= 1;
+ fileOffset = fileStream->readUint16LE();
+ fileOffset |= fileStream->readByte() << 16;
+ fileOffset <<= 1;
} else {
// offset/volume stored in 4 bytes
- off = fileStream->readUint32LE();
+ fileOffset = fileStream->readUint32LE();
if (_mapVersion < kResVersionSci11) {
- volume_nr = off >> 28; // most significant 4 bits
- off &= 0x0FFFFFFF; // least significant 28 bits
+ volume_nr = fileOffset >> 28; // most significant 4 bits
+ fileOffset &= 0x0FFFFFFF; // least significant 28 bits
} else {
// in SCI32 it's a plain offset
}
@@ -1547,19 +1551,30 @@ int ResourceManager::readResourceMapSCI1(ResourceSource *map) {
return SCI_ERROR_RESMAP_NOT_FOUND;
}
resId = ResourceId(convertResType(type), number);
- // adding new resource only if it does not exist
- if (_resMap.contains(resId) == false) {
- // NOTE: We add the map's volume number here to the specified volume number
- // for SCI2.1 and SCI3 maps that are not resmap.000. The resmap.* files' numbers
- // need to be used in concurrence with the volume specified in the map to get
- // the actual resource file.
- int mapVolumeNr = volume_nr + map->_volumeNumber;
- ResourceSource *source = findVolume(map, mapVolumeNr);
- // FIXME: this code has serious issues with multiple RESMAP.* files (like in unmodified gk2)
- // adding a resource with source == NULL would crash later on
- if (!source)
- error("Unable to find volume for map %s volumeNr %d", map->getLocationName().c_str(), mapVolumeNr);
- addResource(resId, source, off);
+ // NOTE: We add the map's volume number here to the specified volume number
+ // for SCI2.1 and SCI3 maps that are not resmap.000. The resmap.* files' numbers
+ // need to be used in concurrence with the volume specified in the map to get
+ // the actual resource file.
+ int mapVolumeNr = volume_nr + map->_volumeNumber;
+ ResourceSource *source = findVolume(map, mapVolumeNr);
+ // FIXME: this code has serious issues with multiple RESMAP.* files (like in unmodified gk2)
+ // adding a resource with source == NULL would crash later on
+ if (!source)
+ error("Unable to find volume for map %s volumeNr %d", map->getLocationName().c_str(), mapVolumeNr);
+
+ Resource *resource = _resMap.getVal(resId, NULL);
+ if (!resource) {
+ addResource(resId, source, fileOffset);
+ } else {
+ // if resource is already present, change it to new content
+ // this is needed at least for pharkas/german. This version
+ // contains several duplicate resources INSIDE the resource
+ // data files like fonts, views, scripts, etc. And if we use
+ // the first entries, half of the game will be english and
+ // umlauts will also be missing :P
+ resource->_source = source;
+ resource->_fileOffset = fileOffset;
+ resource->size = 0;
}
}
}
@@ -1934,7 +1949,18 @@ void ResourceManager::detectSciVersion() {
s_sciVersion = SCI_VERSION_0_EARLY;
bool oldDecompressors = true;
- ResourceCompression viewCompression = getViewCompression();
+ ResourceCompression viewCompression;
+#ifdef ENABLE_SCI32
+ viewCompression = getViewCompression();
+#else
+ if (_volVersion == kResVersionSci32) {
+ // SCI32 support isn't built in, thus view detection will fail
+ viewCompression = kCompUnknown;
+ } else {
+ viewCompression = getViewCompression();
+ }
+#endif
+
if (viewCompression != kCompLZW) {
// If it's a different compression type from kCompLZW, the game is probably
// SCI_VERSION_1_EGA or later. If the views are uncompressed, it is
@@ -1955,8 +1981,18 @@ void ResourceManager::detectSciVersion() {
// SCI1.1 VGA views
_viewType = kViewVga11;
} else {
+#ifdef ENABLE_SCI32
// Otherwise we detect it from a view
_viewType = detectViewType();
+#else
+ if (_volVersion == kResVersionSci32 && viewCompression == kCompUnknown) {
+ // A SCI32 game, but SCI32 support is disabled. Force the view type
+ // to kViewVga11, as we can't read from the game's resource files
+ _viewType = kViewVga11;
+ } else {
+ _viewType = detectViewType();
+ }
+#endif
}
if (_volVersion == kResVersionSci11Mac) {
@@ -2062,7 +2098,7 @@ void ResourceManager::detectSciVersion() {
// is increment here, but ignore for all the regular sci1late games
// the problem is, we dont have access to that detection till later
// so maybe (part of?) that detection should get moved in here
- if ((g_sci->getGameId() == GID_LSL1) && (g_sci->getLanguage() == Common::ES_ESP)) {
+ if (g_sci && (g_sci->getGameId() == GID_LSL1) && (g_sci->getLanguage() == Common::ES_ESP)) {
s_sciVersion = SCI_VERSION_1_MIDDLE;
return;
}
@@ -2137,6 +2173,19 @@ bool ResourceManager::detectForPaletteMergingForSci11() {
return false;
}
+// is called on SCI0EARLY games to make sure that sound resources are in fact also SCI0EARLY
+bool ResourceManager::detectEarlySound() {
+ Resource *res = findResource(ResourceId(kResourceTypeSound, 1), 0);
+ if (res) {
+ if (res->size >= 0x22) {
+ if (READ_LE_UINT16(res->data + 0x1f) == 0) // channel 15 voice count + play mask is 0 in SCI0LATE
+ if (res->data[0x21] == 0) // last byte right before actual data is 0 as well
+ return false;
+ }
+ }
+ return true;
+}
+
// Functions below are based on PD code by Brian Provinciano (SCI Studio)
bool ResourceManager::hasOldScriptHeader() {
Resource *res = findResource(ResourceId(kResourceTypeScript, 0), 0);
@@ -2329,4 +2378,8 @@ Common::String ResourceManager::findSierraGameId() {
return sierraId;
}
+const Common::String &Resource::getResourceLocation() const {
+ return _source->getLocationName();
+}
+
} // End of namespace Sci