aboutsummaryrefslogtreecommitdiff
path: root/engines/sci
diff options
context:
space:
mode:
Diffstat (limited to 'engines/sci')
-rw-r--r--engines/sci/engine/kernel32.cpp54
1 files changed, 36 insertions, 18 deletions
diff --git a/engines/sci/engine/kernel32.cpp b/engines/sci/engine/kernel32.cpp
index e093fa6fdf..d2a3362aca 100644
--- a/engines/sci/engine/kernel32.cpp
+++ b/engines/sci/engine/kernel32.cpp
@@ -525,14 +525,10 @@ reg_t kString(EngineState *s, int argc, reg_t *argv) {
case 1: // Size
return make_reg(0, s->_segMan->getString(argv[1]).size());
case 2: { // At (return value at an index)
- Common::String string = s->_segMan->getString(argv[1]);
-
- if (argv[2].toUint16() >= string.size()) {
- warning("kString(At): Out of bounds: %d/%d\n", argv[2].toUint16(), string.size());
- return NULL_REG;
- }
+ if (argv[1].segment == s->_segMan->getStringSegmentId())
+ return make_reg(0, s->_segMan->lookupString(argv[1])->getRawData()[argv[2].toUint16()]);
- return make_reg(0, string[argv[2].toUint16()]);
+ return make_reg(0, s->_segMan->getString(argv[1])[argv[2].toUint16()]);
}
case 3: { // Atput (put value at an index)
SciString *string = s->_segMan->lookupString(argv[1]);
@@ -571,16 +567,28 @@ reg_t kString(EngineState *s, int argc, reg_t *argv) {
return argv[1];
}
case 6: { // Cpy
- Common::String string2 = s->_segMan->getString(argv[3]);
+ const char *string2 = 0;
+ uint32 string2Size = 0;
+
+ if (argv[3].segment == s->_segMan->getStringSegmentId()) {
+ SciString *string = s->_segMan->lookupString(argv[3]);
+ string2 = string->getRawData();
+ string2Size = string->getSize();
+ } else {
+ Common::String string = s->_segMan->getString(argv[3]);
+ string2 = string.c_str();
+ string2Size = string.size() + 1;
+ }
+
uint32 index1 = argv[2].toUint16();
uint32 index2 = argv[4].toUint16();
// The original engine ignores bad copies too
- if (index2 > string2.size())
+ if (index2 > string2Size)
break;
// A count of -1 means fill the rest of the array
- uint32 count = argv[5].toSint16() == -1 ? string2.size() - index2 + 1 : argv[5].toUint16();
+ uint32 count = argv[5].toSint16() == -1 ? string2Size - index2 + 1 : argv[5].toUint16();
// We have a special case here for argv[1] being a system string
if (argv[1].segment == s->_segMan->getSysStringsSegment()) {
@@ -592,7 +600,7 @@ reg_t kString(EngineState *s, int argc, reg_t *argv) {
s->_segMan->sysStrings->_strings[sysStringId]._value = (char *)calloc(index1 + count, sizeof(char));
}
- strncpy(s->_segMan->sysStrings->_strings[sysStringId]._value + index1, string2.c_str() + index2, count);
+ strncpy(s->_segMan->sysStrings->_strings[sysStringId]._value + index1, string2 + index2, count);
} else {
SciString *string1 = s->_segMan->lookupString(argv[1]);
@@ -602,7 +610,7 @@ reg_t kString(EngineState *s, int argc, reg_t *argv) {
// Note: We're accessing from c_str() here because the string's size ignores
// the trailing 0 and therefore triggers an assert when doing string2[i + index2].
for (uint16 i = 0; i < count; i++)
- string1->setValue(i + index1, string2.c_str()[i + index2]);
+ string1->setValue(i + index1, string2[i + index2]);
}
} return argv[1];
@@ -616,15 +624,25 @@ reg_t kString(EngineState *s, int argc, reg_t *argv) {
return make_reg(0, strcmp(string1.c_str(), string2.c_str()));
}
case 8: { // Dup
- Common::String string = s->_segMan->getString(argv[1]);
+ const char *rawString = 0;
+ uint32 size = 0;
+
+ if (argv[1].segment == s->_segMan->getStringSegmentId()) {
+ SciString *string = s->_segMan->lookupString(argv[1]);
+ rawString = string->getRawData();
+ size = string->getSize();
+ } else {
+ Common::String string = s->_segMan->getString(argv[1]);
+ rawString = string.c_str();
+ size = string.size() + 1;
+ }
+
reg_t stringHandle;
SciString *dupString = s->_segMan->allocateString(&stringHandle);
- dupString->setSize(string.size() + 1);
-
- for (uint32 i = 0; i < string.size(); i++)
- dupString->setValue(i, string.c_str()[i]);
+ dupString->setSize(size);
- dupString->setValue(dupString->getSize() - 1, 0);
+ for (uint32 i = 0; i < size; i++)
+ dupString->setValue(i, rawString[i]);
return stringHandle;
}