aboutsummaryrefslogtreecommitdiff
path: root/engines/sci/engine/segment.h
diff options
context:
space:
mode:
Diffstat (limited to 'engines/sci/engine/segment.h')
-rw-r--r--engines/sci/engine/segment.h64
1 files changed, 56 insertions, 8 deletions
diff --git a/engines/sci/engine/segment.h b/engines/sci/engine/segment.h
index e8f0be3a79..7e2189ea68 100644
--- a/engines/sci/engine/segment.h
+++ b/engines/sci/engine/segment.h
@@ -542,7 +542,14 @@ public:
*/
reg_t getAsID(const uint16 index) {
if (getSciVersion() >= SCI_VERSION_3) {
- resize(index);
+ // SCI3 resizes arrays automatically when out-of-bounds indices are
+ // passed, but it has an off-by-one error, always passing the index
+ // instead of `index + 1` on a read. This happens to work in SSCI
+ // only because the resize method there actually allocates memory
+ // for `index + 25` elements when growing the array, and it always
+ // grows the array on its first resize because it decides whether to
+ // grow based on byte size including an extra array header.
+ resize(index + 1);
} else {
assert(index < _size);
}
@@ -573,7 +580,8 @@ public:
*/
void setFromID(const uint16 index, const reg_t value) {
if (getSciVersion() >= SCI_VERSION_3) {
- resize(index);
+ // This code is different from SSCI; see getAsID for an explanation
+ resize(index + 1);
} else {
assert(index < _size);
}
@@ -599,7 +607,8 @@ public:
assert(_type == kArrayTypeInt16);
if (getSciVersion() >= SCI_VERSION_3) {
- resize(index);
+ // This code is different from SSCI; see getAsID for an explanation
+ resize(index + 1);
} else {
assert(index < _size);
}
@@ -616,6 +625,7 @@ public:
assert(_type == kArrayTypeInt16);
if (getSciVersion() >= SCI_VERSION_3) {
+ // This code is different from SSCI; see getAsID for an explanation
resize(index + 1);
} else {
assert(index < _size);
@@ -632,7 +642,8 @@ public:
assert(_type == kArrayTypeString || _type == kArrayTypeByte);
if (getSciVersion() >= SCI_VERSION_3) {
- resize(index);
+ // This code is different from SSCI; see getAsID for an explanation
+ resize(index + 1);
} else {
assert(index < _size);
}
@@ -648,7 +659,8 @@ public:
assert(_type == kArrayTypeString || _type == kArrayTypeByte);
if (getSciVersion() >= SCI_VERSION_3) {
- resize(index);
+ // This code is different from SSCI; see getAsID for an explanation
+ resize(index + 1);
} else {
assert(index < _size);
}
@@ -664,7 +676,8 @@ public:
assert(_type == kArrayTypeID || _type == kArrayTypeInt16);
if (getSciVersion() >= SCI_VERSION_3) {
- resize(index);
+ // This code is different from SSCI; see getAsID for an explanation
+ resize(index + 1);
} else {
assert(index < _size);
}
@@ -791,15 +804,15 @@ public:
while (*source != '\0' && *source != showChar && *source <= kWhitespaceBoundary) {
++source;
}
- strcpy((char *)target, (char *)source);
+ memmove(target, source, Common::strnlen((char *)source, _size - 1) + 1);
}
if (flags & kArrayTrimRight) {
source = data + strlen((char *)data) - 1;
while (source > data && *source != showChar && *source <= kWhitespaceBoundary) {
+ *source = '\0';
--source;
}
- *source = '\0';
}
if (flags & kArrayTrimCenter) {
@@ -855,6 +868,29 @@ public:
Common::strlcpy((char *)_data, string.c_str(), string.size() + 1);
}
+ Common::String toDebugString() const {
+ const char *type;
+ switch(_type) {
+ case kArrayTypeID:
+ type = "reg_t";
+ break;
+ case kArrayTypeByte:
+ type = "byte";
+ break;
+ case kArrayTypeInt16:
+ type = "int16";
+ break;
+ case kArrayTypeString:
+ type = "string";
+ break;
+ case kArrayTypeInvalid:
+ type = "invalid";
+ break;
+ }
+
+ return Common::String::format("type %s; %u entries; %u bytes", type, size(), byteSize());
+ }
+
protected:
void *_data;
SciArrayType _type;
@@ -1136,8 +1172,20 @@ public:
*pixel++ = (uint8)color;
}
}
+
+ Common::String toString() const {
+ return Common::String::format("%dx%d; res %dx%d; origin %dx%d; skip color %u; %s; %s)",
+ getWidth(), getHeight(),
+ getXResolution(), getYResolution(),
+ getOrigin().x, getOrigin().y,
+ getSkipColor(),
+ getRemap() ? "remap" : "no remap",
+ getShouldGC() ? "GC" : "no GC");
+ }
};
+#undef BITMAP_PROPERTY
+
struct BitmapTable : public SegmentObjTable<SciBitmap> {
BitmapTable() : SegmentObjTable<SciBitmap>(SEG_TYPE_BITMAP) {}