aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWalter van Niftrik2009-06-04 14:29:20 +0000
committerWalter van Niftrik2009-06-04 14:29:20 +0000
commit9e196ce9f5094ae0a12f0dea6167748477ad82c4 (patch)
tree53389365df4d9f6d6e1a72c5512e48df429ac624
parentc3206f36717a60bc331d5b3aa857fcae3b570ce9 (diff)
downloadscummvm-rg350-9e196ce9f5094ae0a12f0dea6167748477ad82c4.tar.gz
scummvm-rg350-9e196ce9f5094ae0a12f0dea6167748477ad82c4.tar.bz2
scummvm-rg350-9e196ce9f5094ae0a12f0dea6167748477ad82c4.zip
SCI: Message: Added support for escape sequences.
svn-id: r41169
-rw-r--r--engines/sci/engine/kstring.cpp12
-rw-r--r--engines/sci/engine/message.cpp56
-rw-r--r--engines/sci/engine/message.h2
3 files changed, 60 insertions, 10 deletions
diff --git a/engines/sci/engine/kstring.cpp b/engines/sci/engine/kstring.cpp
index 20f0f4793b..3898664921 100644
--- a/engines/sci/engine/kstring.cpp
+++ b/engines/sci/engine/kstring.cpp
@@ -713,7 +713,7 @@ reg_t kMessage(EngineState *s, int funct_nr, int argc, reg_t *argv) {
case K_MESSAGE_NEXT: {
reg_t bufferReg;
char *buffer = NULL;
- const char *str;
+ Common::String str;
reg_t retval;
if (func == K_MESSAGE_GET) {
@@ -735,18 +735,18 @@ reg_t kMessage(EngineState *s, int funct_nr, int argc, reg_t *argv) {
else
retval = make_reg(0, s->_msgState.getTalker());
} else {
- str = DUMMY_MESSAGE;
+ str = Common::String(DUMMY_MESSAGE);
retval = NULL_REG;
}
if (!bufferReg.isNull()) {
- int len = strlen(str) + 1;
+ int len = str.size() + 1;
buffer = kernel_dereference_char_pointer(s, bufferReg, len);
if (buffer) {
- strcpy(buffer, str);
+ strcpy(buffer, str.c_str());
} else {
- warning("Message: buffer %04x:%04x invalid or too small to hold the following text of %i bytes: '%s'", PRINT_REG(bufferReg), len, str);
+ warning("Message: buffer %04x:%04x invalid or too small to hold the following text of %i bytes: '%s'", PRINT_REG(bufferReg), len, str.c_str());
// Set buffer to empty string if possible
buffer = kernel_dereference_char_pointer(s, bufferReg, 1);
@@ -763,7 +763,7 @@ reg_t kMessage(EngineState *s, int funct_nr, int argc, reg_t *argv) {
MessageState tempState;
if (tempState.loadRes(s->resmgr, UKPV(1), false) && tempState.findTuple(tuple) && tempState.getMessage())
- return make_reg(0, strlen(tempState.getText()) + 1);
+ return make_reg(0, tempState.getText().size() + 1);
else
return NULL_REG;
}
diff --git a/engines/sci/engine/message.cpp b/engines/sci/engine/message.cpp
index 61151e3218..4f5efa106c 100644
--- a/engines/sci/engine/message.cpp
+++ b/engines/sci/engine/message.cpp
@@ -153,9 +153,59 @@ int MessageState::getLastModule() {
return _lastReturnedModule;
}
-char *MessageState::getText() {
- int offset = READ_LE_UINT16(_engineCursor.index_record + ((_version == 2101) ? 2 : 5));
- return (char *)_currentResource->data + offset;
+Common::String MessageState::getText() {
+ char *str = (char *)_currentResource->data + READ_LE_UINT16(_engineCursor.index_record + ((_version == 2101) ? 2 : 5));
+
+ Common::String strippedStr;
+ Common::String skippedSubstr;
+ bool skipping = false;
+
+ for (uint i = 0; i < strlen(str); i++) {
+ if (skipping) {
+ // Skip stage direction
+ skippedSubstr += str[i];
+
+ // Hopefully these locale-dependant functions are good enough
+ if (islower(str[i]) || isdigit(str[i])) {
+ // Lowercase or digit found, this is not a stage direction
+ strippedStr += skippedSubstr;
+ skipping = false;
+ } else if (str[i] == ')') {
+ // End of stage direction, skip trailing white space
+ while ((i + 1 < strlen(str)) && isspace(str[i + 1]))
+ i++;
+ skipping = false;
+ }
+ } else {
+ if (str[i] == '(') {
+ // Start skipping stage direction
+ skippedSubstr = str[i];
+ skipping = true;
+ } else if (str[i] == '\\') {
+ // Escape sequence
+ if ((i + 2 < strlen(str)) && isdigit(str[i + 1]) && isdigit(str[i + 2])) {
+ // Hex escape sequence
+ char hexStr[3];
+
+ hexStr[0] = str[++i];
+ hexStr[1] = str[++i];
+ hexStr[2] = 0;
+
+ char *endptr;
+ int hexNr = strtol(hexStr, &endptr, 16);
+ if (*endptr == 0)
+ strippedStr += hexNr;
+ } else if (i + 1 < strlen(str)) {
+ // Literal escape sequence
+ strippedStr += str[++i];
+ }
+ } else {
+ strippedStr += str[i];
+ }
+ }
+ }
+
+ return strippedStr;
}
void MessageState::gotoNext() {
diff --git a/engines/sci/engine/message.h b/engines/sci/engine/message.h
index b1cdb8ad99..5e30095a0c 100644
--- a/engines/sci/engine/message.h
+++ b/engines/sci/engine/message.h
@@ -54,7 +54,7 @@ public:
MessageTuple getRefTuple();
int getMessage();
void gotoNext();
- char *getText();
+ Common::String getText();
int getTalker();
int getLength();
MessageTuple &getLastTuple();