aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthew Hoops2010-07-18 00:16:19 +0000
committerMatthew Hoops2010-07-18 00:16:19 +0000
commitc128b87c779ab74deb494c48782fc8199c9672a5 (patch)
treed3e65cf79bc04a847f3d0ac6077cbe9b63ace89c
parentcd0997368cfc9f272888a96e80b1f4cc2379d0bc (diff)
downloadscummvm-rg350-c128b87c779ab74deb494c48782fc8199c9672a5.tar.gz
scummvm-rg350-c128b87c779ab74deb494c48782fc8199c9672a5.tar.bz2
scummvm-rg350-c128b87c779ab74deb494c48782fc8199c9672a5.zip
In SCI2.1, the type numbers inside resource maps/patches have changed slightly. We no longer use the number Sierra gives us directly, but use a function to convert to our ResourceType enum based on version. This allows us to read the chunk type from SCI2.1 (a form of script). Also, allow debugging of Mac-specific resources from the console.
svn-id: r50973
-rw-r--r--engines/sci/engine/kscripts.cpp8
-rw-r--r--engines/sci/resource.cpp119
-rw-r--r--engines/sci/resource.h26
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