diff options
-rw-r--r-- | engines/sci/engine/kscripts.cpp | 8 | ||||
-rw-r--r-- | engines/sci/resource.cpp | 119 | ||||
-rw-r--r-- | engines/sci/resource.h | 26 |
3 files changed, 124 insertions, 29 deletions
diff --git a/engines/sci/engine/kscripts.cpp b/engines/sci/engine/kscripts.cpp index 029943b070..0286f7454a 100644 --- a/engines/sci/engine/kscripts.cpp +++ b/engines/sci/engine/kscripts.cpp @@ -38,7 +38,7 @@ namespace Sci { // Loads arbitrary resources of type 'restype' with resource numbers 'resnrs' // This implementation ignores all resource numbers except the first one. reg_t kLoad(EngineState *s, int argc, reg_t *argv) { - ResourceType restype = (ResourceType)(argv[0].toUint16() & 0x7f); + ResourceType restype = g_sci->getResMan()->convertResType(argv[0].toUint16()); int resnr = argv[1].toUint16(); // Request to dynamically allocate hunk memory for later use @@ -53,7 +53,7 @@ reg_t kLoad(EngineState *s, int argc, reg_t *argv) { // 1 or 3+ parameters is not right according to sierra sci reg_t kUnLoad(EngineState *s, int argc, reg_t *argv) { if (argc >= 2) { - ResourceType restype = (ResourceType)(argv[0].toUint16() & 0x7f); + ResourceType restype = g_sci->getResMan()->convertResType(argv[0].toUint16()); reg_t resnr = argv[1]; // WORKAROUND for a broken script in room 320 in Castle of Dr. Brain. @@ -73,7 +73,7 @@ reg_t kUnLoad(EngineState *s, int argc, reg_t *argv) { reg_t kLock(EngineState *s, int argc, reg_t *argv) { int state = argc > 2 ? argv[2].toUint16() : 1; - ResourceType type = (ResourceType)(argv[0].toUint16() & 0x7f); + ResourceType type = g_sci->getResMan()->convertResType(argv[0].toUint16()); ResourceId id = ResourceId(type, argv[1].toUint16()); Resource *which; @@ -115,7 +115,7 @@ reg_t kLock(EngineState *s, int argc, reg_t *argv) { reg_t kResCheck(EngineState *s, int argc, reg_t *argv) { Resource *res = NULL; - ResourceType restype = (ResourceType)(argv[0].toUint16() & 0x7f); + ResourceType restype = g_sci->getResMan()->convertResType(argv[0].toUint16()); if (restype == kResourceTypeVMD) { char fileName[10]; diff --git a/engines/sci/resource.cpp b/engines/sci/resource.cpp index 731f4dd573..f3c52e6760 100644 --- a/engines/sci/resource.cpp +++ b/engines/sci/resource.cpp @@ -108,30 +108,115 @@ static const char *sci_error_types[] = { "SCI version is unsupported" }; -// These are the 20 resource types supported by SCI1.1 -static const char *resourceTypeNames[] = { +static const char *s_resourceTypeNames[] = { "view", "pic", "script", "text", "sound", "memory", "vocab", "font", "cursor", "patch", "bitmap", "palette", "cdaudio", "audio", "sync", "message", "map", "heap", - "audio36", "sync36", "", "", "robot", "vmd" + "audio36", "sync36", "xlate", "robot", "vmd", + "chunk", "macibin", "macibis", "macpict" }; -static const char *resourceTypeSuffixes[] = { +static const char *s_resourceTypeSuffixes[] = { "v56", "p56", "scr", "tex", "snd", - " ", "voc", "fon", "cur", "pat", + "", "voc", "fon", "cur", "pat", "bit", "pal", "cda", "aud", "syn", - "msg", "map", "hep", "aud", "syn", - "trn", " ", "rbt", "vmd" -}; + "msg", "map", "hep", "", "", + "trn", "rbt", "vmd", "chk", "", + "", "" +}; const char *getResourceTypeName(ResourceType restype) { if (restype != kResourceTypeInvalid) - return resourceTypeNames[restype]; + return s_resourceTypeNames[restype]; else return "invalid"; } +struct ResTypeMap { + byte sciType; + ResourceType type; +}; + +static const ResTypeMap s_resTypeMapSci0[] = { + { 0, kResourceTypeView }, + { 1, kResourceTypePic }, + { 2, kResourceTypeScript }, + { 3, kResourceTypeText }, + { 4, kResourceTypeSound }, + { 5, kResourceTypeMemory }, + { 6, kResourceTypeVocab }, + { 7, kResourceTypeFont }, + { 8, kResourceTypeCursor }, + { 9, kResourceTypePatch }, + { 10, kResourceTypeBitmap }, + { 11, kResourceTypePalette }, + { 12, kResourceTypeCdAudio }, + { 13, kResourceTypeAudio }, + { 14, kResourceTypeSync }, + { 15, kResourceTypeMessage }, + { 16, kResourceTypeMap }, + { 17, kResourceTypeHeap }, + { 18, kResourceTypeAudio36 }, + { 19, kResourceTypeSync36 }, + { 20, kResourceTypeTranslation }, +}; + +#ifdef ENABLE_SCI32 +static const ResTypeMap s_resTypeMapSci21[] = { + { 0, kResourceTypeView }, + { 1, kResourceTypePic }, + { 2, kResourceTypeScript }, + { 3, kResourceTypeText }, + { 4, kResourceTypeSound }, + { 5, kResourceTypeMemory }, + { 6, kResourceTypeVocab }, + { 7, kResourceTypeFont }, + { 8, kResourceTypeCursor }, + { 9, kResourceTypePatch }, + { 10, kResourceTypeBitmap }, + { 11, kResourceTypePalette }, + // 12 is Wave, but SCI seems to just store it in Audio resources + { 13, kResourceTypeAudio }, + { 14, kResourceTypeSync }, + { 15, kResourceTypeMessage }, + { 16, kResourceTypeMap }, + { 17, kResourceTypeHeap }, + { 18, kResourceTypeChunk }, + { 19, kResourceTypeAudio36 }, + { 20, kResourceTypeSync36 }, + { 21, kResourceTypeTranslation }, + { 22, kResourceTypeRobot }, + { 23, kResourceTypeVMD } +}; +#endif + +ResourceType ResourceManager::convertResType(byte type) { + type &= 0x7f; + uint32 tableSize = 0; + const ResTypeMap *map = 0; + + if (_mapVersion != kResVersionSci32) { + // SCI0 - SCI2 + tableSize = ARRAYSIZE(s_resTypeMapSci0); + map = s_resTypeMapSci0; + } else { + // SCI2.1+ +#ifdef ENABLE_SCI32 + tableSize = ARRAYSIZE(s_resTypeMapSci21); + map = s_resTypeMapSci21; +#else + error("SCI32 support not compiled in"); +#endif + } + + for (uint32 i = 0; i < tableSize; i++) + if (map[i].sciType == type) + return map[i].type; + + return kResourceTypeInvalid; +} + //-- Resource main functions -- Resource::Resource(ResourceId id) : _id(id) { data = NULL; @@ -337,7 +422,7 @@ void MacResourceForkResourceSource::loadResource(ResourceManager *resMan, Resour Common::SeekableReadStream *stream = _macResMan->getResource(resTypeToMacTag(res->getType()), res->getNumber()); if (!stream) - error("Could not get Mac resource fork resource: %d %d", res->getType(), res->getNumber()); + error("Could not get Mac resource fork resource: %s %d", getResourceTypeName(res->getType()), res->getNumber()); int error = res->decompress(resMan->getVolVersion(), stream); if (error) { @@ -1097,7 +1182,7 @@ void ResourceManager::processPatch(ResourceSource *source, ResourceType resource return; } - byte patchType = fileStream->readByte() & 0x7F; + byte patchType = convertResType(fileStream->readByte()); byte patchDataOffset = fileStream->readByte(); delete fileStream; @@ -1235,7 +1320,11 @@ void ResourceManager::readResourcePatches() { const char *szResType; ResourceSource *psrcPatch; - for (int i = kResourceTypeView; i <= kResourceTypeHeap; ++i) { + for (int i = kResourceTypeView; i <= kResourceTypeInvalid; ++i) { + // Ignore the types that can't be patched (and Robot/VMD is handled externally for now) + if (!s_resourceTypeSuffixes[i] || i == kResourceTypeRobot || i == kResourceTypeVMD) + continue; + files.clear(); szResType = getResourceTypeName((ResourceType)i); // SCI0 naming - type.nnn @@ -1244,7 +1333,7 @@ void ResourceManager::readResourcePatches() { SearchMan.listMatchingMembers(files, mask); // SCI1 and later naming - nnn.typ mask = "*."; - mask += resourceTypeSuffixes[i]; + mask += s_resourceTypeSuffixes[i]; SearchMan.listMatchingMembers(files, mask); for (Common::ArchiveMemberList::const_iterator x = files.begin(); x != files.end(); ++x) { @@ -1308,7 +1397,7 @@ int ResourceManager::readResourceMapSCI0(ResourceSource *map) { if (offset == 0xFFFFFFFF) break; - type = (ResourceType)(id >> 11); + type = convertResType(id >> 11); number = id & 0x7FF; ResourceId resId = ResourceId(type, number); // adding a new resource @@ -1393,7 +1482,7 @@ int ResourceManager::readResourceMapSCI1(ResourceSource *map) { warning("Error while reading %s", map->getLocationName().c_str()); return SCI_ERROR_RESMAP_NOT_FOUND; } - resId = ResourceId((ResourceType)type, number); + 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 diff --git a/engines/sci/resource.h b/engines/sci/resource.h index f66b5b3956..d7acf3b9d6 100644 --- a/engines/sci/resource.h +++ b/engines/sci/resource.h @@ -95,22 +95,21 @@ enum ResourceType { kResourceTypeHeap, kResourceTypeAudio36, kResourceTypeSync36, - kResourceTypeUnknown1, // Translation, currently unsupported - kResourceTypeUnknown2, + kResourceTypeTranslation, // Currently unsupported kResourceTypeRobot, kResourceTypeVMD, - kResourceTypeInvalid, + kResourceTypeChunk, - // Mac-only resources, these resource types are self-defined - // Numbers subject to change - kResourceTypeMacIconBarPictN = -1, // IBIN resources (icon bar, not selected) - kResourceTypeMacIconBarPictS = -2, // IBIS resources (icon bar, selected) - kResourceTypeMacPict = -3 // PICT resources (inventory) + // Mac-only resources + kResourceTypeMacIconBarPictN, // IBIN resources (icon bar, not selected) + kResourceTypeMacIconBarPictS, // IBIS resources (icon bar, selected) + kResourceTypeMacPict, // PICT resources (inventory) + + kResourceTypeInvalid }; const char *getResourceTypeName(ResourceType restype); - enum ResVersion { kResVersionUnknown, kResVersionSci0Sci1Early, @@ -126,7 +125,7 @@ class ResourceSource; class ResourceId { static inline ResourceType fixupType(ResourceType type) { - if (type < kResourceTypeMacPict || type > kResourceTypeInvalid) + if (type == kResourceTypeInvalid) return kResourceTypeInvalid; return type; } @@ -344,6 +343,13 @@ public: */ reg_t findGameObject(bool addSci11ScriptOffset = true); + /** + * Converts a map resource type to our type + * @param sciType The type from the map/patch + * @return The ResourceType + */ + ResourceType convertResType(byte type); + protected: // Maximum number of bytes to allow being allocated for resources // Note: maxMemory will not be interpreted as a hard limit, only as a restriction |