aboutsummaryrefslogtreecommitdiff
path: root/engines/sci
diff options
context:
space:
mode:
authorColin Snover2017-09-08 20:54:48 -0500
committerColin Snover2017-09-08 21:10:51 -0500
commit7eedfdbeaf2d1349a368ea308219f0f185322c0d (patch)
tree63d95e284e2f94ff302683ea9c3e0343d04849a4 /engines/sci
parent5228aa29fa632249c835f98fbc4cfc01fa5f222b (diff)
downloadscummvm-rg350-7eedfdbeaf2d1349a368ea308219f0f185322c0d.tar.gz
scummvm-rg350-7eedfdbeaf2d1349a368ea308219f0f185322c0d.tar.bz2
scummvm-rg350-7eedfdbeaf2d1349a368ea308219f0f185322c0d.zip
SCI32: Fix kString signatures to allow null references where appropriate
The original interpreter allowed most string references to be null references, in which case it would substitute an empty string.
Diffstat (limited to 'engines/sci')
-rw-r--r--engines/sci/engine/kernel_tables.h40
-rw-r--r--engines/sci/engine/kstring.cpp28
2 files changed, 36 insertions, 32 deletions
diff --git a/engines/sci/engine/kernel_tables.h b/engines/sci/engine/kernel_tables.h
index f4f96ad253..0f7b9cac6f 100644
--- a/engines/sci/engine/kernel_tables.h
+++ b/engines/sci/engine/kernel_tables.h
@@ -533,34 +533,34 @@ static const SciKernelMapSubEntry kString_subops[] = {
// 3)
{ SIG_THRU_SCI21MID, 0, MAP_CALL(StringNew), "i(i)", NULL },
{ SIG_THRU_SCI21MID, 1, MAP_CALL(ArrayGetSize), "r", NULL },
- { SIG_THRU_SCI21MID, 2, MAP_CALL(StringGetChar), "ri", NULL },
+ { SIG_THRU_SCI21MID, 2, MAP_CALL(StringGetChar), "[0r]i", NULL },
{ SIG_THRU_SCI21MID, 3, MAP_CALL(ArraySetElements), "ri(i*)", kArraySetElements_workarounds },
{ SIG_THRU_SCI21MID, 4, MAP_CALL(StringFree), "[0r]", NULL },
{ SIG_THRU_SCI21MID, 5, MAP_CALL(ArrayFill), "rii", kArrayFill_workarounds },
{ SIG_THRU_SCI21MID, 6, MAP_CALL(ArrayCopy), "ririi", NULL },
- { SIG_SCI32, 7, MAP_CALL(StringCompare), "rr(i)", NULL },
+ { SIG_SCI32, 7, MAP_CALL(StringCompare), "[0r][0r](i)", NULL },
{ SIG_THRU_SCI21MID, 8, MAP_CALL(ArrayDuplicate), "r", NULL },
{ SIG_THRU_SCI21MID, 9, MAP_CALL(StringGetData), "[0or]", NULL },
- { SIG_THRU_SCI21MID, 10, MAP_CALL(StringLength), "r", NULL },
- { SIG_THRU_SCI21MID, 11, MAP_CALL(StringFormat), "[ro](.*)", NULL },
- { SIG_THRU_SCI21MID, 12, MAP_CALL(StringFormatAt), "r[ro](.*)", NULL },
- { SIG_THRU_SCI21MID, 13, MAP_CALL(StringToInteger), "r", NULL },
- { SIG_THRU_SCI21MID, 14, MAP_CALL(StringTrim), "ri(i)", NULL },
- { SIG_THRU_SCI21MID, 15, MAP_CALL(StringToUpperCase), "r", NULL },
- { SIG_THRU_SCI21MID, 16, MAP_CALL(StringToLowerCase), "r", NULL },
- { SIG_THRU_SCI21MID, 17, MAP_CALL(StringReplaceSubstring), "rrrr", NULL },
- { SIG_THRU_SCI21MID, 18, MAP_CALL(StringReplaceSubstringEx), "rrrr", NULL },
-
- { SIG_SINCE_SCI21LATE, 8, MAP_CALL(StringLength), "r", NULL },
+ { SIG_THRU_SCI21MID, 10, MAP_CALL(StringLength), "[0r]", NULL },
+ { SIG_THRU_SCI21MID, 11, MAP_CALL(StringFormat), "[0ro](.*)", NULL },
+ { SIG_THRU_SCI21MID, 12, MAP_CALL(StringFormatAt), "r[0ro](.*)", NULL },
+ { SIG_THRU_SCI21MID, 13, MAP_CALL(StringToInteger), "[0r]", NULL },
+ { SIG_THRU_SCI21MID, 14, MAP_CALL(StringTrim), "[0r]i(i)", NULL },
+ { SIG_THRU_SCI21MID, 15, MAP_CALL(StringToUpperCase), "[0r]", NULL },
+ { SIG_THRU_SCI21MID, 16, MAP_CALL(StringToLowerCase), "[0r]", NULL },
+ { SIG_THRU_SCI21MID, 17, MAP_CALL(StringReplaceSubstring), "[0r][0r][0r][0r]", NULL },
+ { SIG_THRU_SCI21MID, 18, MAP_CALL(StringReplaceSubstringEx), "[0r][0r][0r][0r]", NULL },
+
+ { SIG_SINCE_SCI21LATE, 8, MAP_CALL(StringLength), "[0r]", NULL },
{ SIG_SINCE_SCI21LATE, 9, MAP_CALL(StringFormat), "[0ro](.*)", NULL },
- { SIG_SINCE_SCI21LATE,10, MAP_CALL(StringFormatAt), "r[0ro](.*)", NULL },
- { SIG_SINCE_SCI21LATE,11, MAP_CALL(StringToInteger), "r", NULL },
- { SIG_SINCE_SCI21LATE,12, MAP_CALL(StringTrim), "ri(i)", NULL },
- { SIG_SINCE_SCI21LATE,13, MAP_CALL(StringToUpperCase), "r", NULL },
- { SIG_SINCE_SCI21LATE,14, MAP_CALL(StringToLowerCase), "r", NULL },
- { SIG_SINCE_SCI21LATE,15, MAP_CALL(StringReplaceSubstring), "rrrr", NULL },
- { SIG_SINCE_SCI21LATE,16, MAP_CALL(StringReplaceSubstringEx), "rrrr", NULL },
+ { SIG_SINCE_SCI21LATE,10, MAP_CALL(StringFormatAt), "[0r][0ro](.*)", NULL },
+ { SIG_SINCE_SCI21LATE,11, MAP_CALL(StringToInteger), "[0r]", NULL },
+ { SIG_SINCE_SCI21LATE,12, MAP_CALL(StringTrim), "[0r]i(i)", NULL },
+ { SIG_SINCE_SCI21LATE,13, MAP_CALL(StringToUpperCase), "[0r]", NULL },
+ { SIG_SINCE_SCI21LATE,14, MAP_CALL(StringToLowerCase), "[0r]", NULL },
+ { SIG_SINCE_SCI21LATE,15, MAP_CALL(StringReplaceSubstring), "[0r][0r][0r][0r]", NULL },
+ { SIG_SINCE_SCI21LATE,16, MAP_CALL(StringReplaceSubstringEx), "[0r][0r][0r][0r]", NULL },
SCI_SUBOPENTRY_TERMINATOR
};
diff --git a/engines/sci/engine/kstring.cpp b/engines/sci/engine/kstring.cpp
index 3c6a0424f8..5bab422425 100644
--- a/engines/sci/engine/kstring.cpp
+++ b/engines/sci/engine/kstring.cpp
@@ -803,26 +803,30 @@ Common::String format(const Common::String &source, int argc, const reg_t *argv)
}
reg_t kStringFormat(EngineState *s, int argc, reg_t *argv) {
- reg_t stringHandle;
- SciArray &target = *s->_segMan->allocateArray(kArrayTypeString, 0, &stringHandle);
- reg_t source = argv[0];
- // Str objects may be passed in place of direct references to string data
- if (s->_segMan->isObject(argv[0])) {
- source = readSelector(s->_segMan, argv[0], SELECTOR(data));
- }
- target.fromString(format(s->_segMan->getString(source), argc - 1, argv + 1));
- return stringHandle;
+ Common::Array<reg_t> args;
+ args.resize(argc + 1);
+ args[0] = NULL_REG;
+ Common::copy(argv, argv + argc, &args[1]);
+ return kStringFormatAt(s, args.size(), &args[0]);
}
reg_t kStringFormatAt(EngineState *s, int argc, reg_t *argv) {
- SciArray &target = *s->_segMan->lookupArray(argv[0]);
+ reg_t stringHandle;
+ SciArray *target;
+ if (argv[0].isNull()) {
+ target = s->_segMan->allocateArray(kArrayTypeString, 0, &stringHandle);
+ } else {
+ target = s->_segMan->lookupArray(argv[0]);
+ stringHandle = argv[0];
+ }
+
reg_t source = argv[1];
// Str objects may be passed in place of direct references to string data
if (s->_segMan->isObject(argv[1])) {
source = readSelector(s->_segMan, argv[1], SELECTOR(data));
}
- target.fromString(format(s->_segMan->getString(source), argc - 2, argv + 2));
- return argv[0];
+ target->fromString(format(s->_segMan->getString(source), argc - 2, argv + 2));
+ return stringHandle;
}
reg_t kStringToInteger(EngineState *s, int argc, reg_t *argv) {