diff options
-rw-r--r-- | scumm/actor.cpp | 9 | ||||
-rw-r--r-- | scumm/script_v6.cpp | 13 | ||||
-rw-r--r-- | scumm/script_v6he.cpp | 8 | ||||
-rw-r--r-- | scumm/script_v8.cpp | 10 | ||||
-rw-r--r-- | scumm/scumm.h | 1 | ||||
-rw-r--r-- | scumm/string.cpp | 153 |
6 files changed, 72 insertions, 122 deletions
diff --git a/scumm/actor.cpp b/scumm/actor.cpp index b128251bb8..024a8886be 100644 --- a/scumm/actor.cpp +++ b/scumm/actor.cpp @@ -1147,14 +1147,11 @@ int ScummEngine::getActorFromPos(int x, int y) { void ScummEngine::actorTalk(const byte *msg) { Actor *a; + _lastStringTag[0] = 0; addMessageToStack(msg, _charsetBuffer, sizeof(_charsetBuffer)); - while ((_gameId == GID_DIG || _gameId == GID_CMI) && (_charsetBuffer[0] == '/')) { - translateText(_charsetBuffer, _transText); - if (_transText[0] != '/') - playSpeech(_charsetBuffer); - memcpy(_charsetBuffer, _transText, MIN(sizeof(_charsetBuffer), sizeof(_transText))); - } + // Play associated speech, if any + playSpeech((byte *)_lastStringTag); // FIXME: Workaround for bugs #770039 and #770049 if (_gameId == GID_LOOM || _gameId == GID_LOOM256) { diff --git a/scumm/script_v6.cpp b/scumm/script_v6.cpp index 6c9156e1b5..76f9b8c162 100644 --- a/scumm/script_v6.cpp +++ b/scumm/script_v6.cpp @@ -2482,11 +2482,6 @@ void ScummEngine_v6::o6_kernelSetFunctions() { byte buf_input[300]; const byte *message = getStringAddressVar(VAR_STRING2DRAW); - if ((_gameId == GID_DIG) && !(_features & GF_DEMO)) { - translateText(message, _transText); - message = _transText; - } - addMessageToStack(message, buf_input, sizeof(buf_input)); enqueueText(buf_input, args[3], args[4], args[2], args[1], true); break;} @@ -3106,20 +3101,18 @@ void ScummEngine_v6::decodeParseString(int m, int n) { _string[m].no_talk_anim = true; break; case 75: // SO_TEXTSTRING - translateText(_scriptPointer, _transText); - switch (m) { case 0: actorTalk(_scriptPointer); break; case 1: - drawString(1, _transText); + drawString(1, _scriptPointer); break; case 2: - unkMessage1(_transText); + unkMessage1(_scriptPointer); break; case 3: - unkMessage2(_transText); + unkMessage2(_scriptPointer); break; } _scriptPointer += resStrLen(_scriptPointer) + 1; diff --git a/scumm/script_v6he.cpp b/scumm/script_v6he.cpp index 881685013a..4919276558 100644 --- a/scumm/script_v6he.cpp +++ b/scumm/script_v6he.cpp @@ -1439,20 +1439,18 @@ void ScummEngine_v6he::decodeParseString(int m, int n) { _string[m].no_talk_anim = true; break; case 75: // SO_TEXTSTRING - translateText(_scriptPointer, _transText); - switch (m) { case 0: actorTalk(_scriptPointer); break; case 1: - drawString(1, _transText); + drawString(1, _scriptPointer); break; case 2: - unkMessage1(_transText); + unkMessage1(_scriptPointer); break; case 3: - unkMessage2(_transText); + unkMessage2(_scriptPointer); break; } _scriptPointer += resStrLen(_scriptPointer) + 1; diff --git a/scumm/script_v8.cpp b/scumm/script_v8.cpp index 314fb4c84a..a8963164b4 100644 --- a/scumm/script_v8.cpp +++ b/scumm/script_v8.cpp @@ -513,24 +513,22 @@ void ScummEngine_v8::decodeParseString(int m, int n) { _string[m].no_talk_anim = true; break; case 0xD1: // SO_PRINT_STRING - translateText(_scriptPointer, _transText); - switch (m) { case 0: actorTalk(_scriptPointer); break; case 1: - drawString(1, _transText); + drawString(1, _scriptPointer); break; case 2: - unkMessage1(_transText); + unkMessage1(_scriptPointer); break; case 3: - unkMessage2(_transText); + unkMessage2(_scriptPointer); break; case 5:{ byte buffer[256]; - addMessageToStack(_transText, buffer, sizeof(buffer)); + addMessageToStack(_scriptPointer, buffer, sizeof(buffer)); enqueueText(buffer, _string[m].xpos, _string[m].ypos, _string[m].color, _string[m].charset, _string[m].center); } break; diff --git a/scumm/scumm.h b/scumm/scumm.h index 71af8d3840..3fbbff5a4d 100644 --- a/scumm/scumm.h +++ b/scumm/scumm.h @@ -1078,6 +1078,7 @@ protected: char *_languageBuffer; LangIndexNode *_languageIndex; int _languageIndexSize; + char _lastStringTag[12+1]; byte _transText[512]; void loadLanguageBundle(); diff --git a/scumm/string.cpp b/scumm/string.cpp index d03d554336..a95eee03c2 100644 --- a/scumm/string.cpp +++ b/scumm/string.cpp @@ -470,7 +470,8 @@ void ScummEngine::addMessageToStack(const byte *msg, byte *dstBuffer, int dstBuf uint num = 0; uint32 val; byte chr; - byte buf[512]; + const byte *buf; + byte transBuf[384]; if (dstBuffer) { _msgPtrToAdd = dstBuffer; @@ -481,21 +482,11 @@ void ScummEngine::addMessageToStack(const byte *msg, byte *dstBuffer, int dstBuf return; } - while ((buf[num++] = chr = *msg++) != 0) { - if (num >= sizeof(buf)) - error("Message stack overflow"); - - if (chr == 0xff) { // 0xff is an escape character - buf[num++] = chr = *msg++; // followed by a "command" code - if (chr != 1 && chr != 2 && chr != 3 && chr != 8) { - buf[num++] = *msg++; // and some commands are followed by parameters to the functions below - buf[num++] = *msg++; // these are numbers of names, strings, verbs, variables, etc - if (_version == 8) { - buf[num++] = *msg++; - buf[num++] = *msg++; - } - } - } + if (_version >= 7 && msg[0] == '/') { + translateText(msg, transBuf); + buf = transBuf; + } else { + buf = msg; } num = 0; @@ -590,13 +581,7 @@ void ScummEngine::addNameToStack(int var) { if (num) { const byte *ptr = getObjOrActorName(num); if (ptr) { - if ((_version >= 7) && (ptr[0] == '/')) { - byte buf[128]; - translateText(ptr, buf); - addMessageToStack(buf, 0, 0); - } else { - addMessageToStack(ptr, 0, 0); - } + addMessageToStack(ptr, 0, 0); } } } @@ -620,13 +605,7 @@ void ScummEngine::addStringToStack(int var) { if (var) { ptr = getStringAddress(var); if (ptr) { - if ((_version >= 7) && (ptr[0] == '/')) { - byte buf[128]; - translateText(ptr, buf); - addMessageToStack(buf, 0, 0); - } else { - addMessageToStack(ptr, 0, 0); - } + addMessageToStack(ptr, 0, 0); } } } @@ -863,15 +842,9 @@ void ScummEngine::loadLanguageBundle() { } void ScummEngine::playSpeech(const byte *ptr) { - if ((_gameId == GID_DIG || _gameId == GID_CMI) && (ptr[0] == '/')) { + if ((_gameId == GID_DIG || _gameId == GID_CMI) && ptr[0]) { char pointer[20]; - int i, j; - - for (i = 0, j = 0; (ptr[i] != '/' || j == 0) && j < 19; i++) { - if (ptr[i] != '/') - pointer[j++] = ptr[i]; - } - pointer[j] = 0; + strcpy(pointer, (const char *)ptr); // Play speech if (!(_features & GF_DEMO) && (_gameId == GID_CMI)) // CMI demo does not have .IMX for voice @@ -884,71 +857,61 @@ void ScummEngine::playSpeech(const byte *ptr) { } void ScummEngine::translateText(const byte *text, byte *trans_buff) { - int l; + LangIndexNode target; + int i; - if ((text[0] == '/') && _existLanguageFile) { - LangIndexNode target; - LangIndexNode *found = NULL; - + if (_version >= 7 && text[0] == '/') { // copy name from text /..../ - for (l = 0; (l < 12) && (text[l + 1] != '/'); l++) - target.tag[l] = toupper(text[l + 1]); - target.tag[l] = 0; - - // HACK: These are used for the object line when - // using one object on another. I don't know if the - // text in the language file is a placeholder or if - // we're supposed to use it, but at least in the - // English version things will work so much better if - // we can't find translations for these. - - if (strcmp(target.tag, "PU_M001") != 0 && strcmp(target.tag, "PU_M002") != 0) - found = (LangIndexNode *)bsearch(&target, _languageIndex, _languageIndexSize, sizeof(LangIndexNode), indexCompare); - if (found != NULL) { - strcpy((char *)trans_buff, _languageBuffer + found->offset); - - // FIXME / TODO: Maybe this should be enabled for Full Throttle, too? - if ((_gameId == GID_DIG) && !(_features & GF_DEMO)) { - // Replace any '%___' by the corresponding special codes in the source text - const byte *src = text; - char *dst = (char *)trans_buff; - - while ((dst = strstr(dst, "%___"))) { - // Search for a special code in the message. They have - // the form: 255-byte OP-byte ARG-int16 - while (*src && *src != 0xFF) { - src++; + for (i = 0; (i < 12) && (text[i + 1] != '/'); i++) + _lastStringTag[i] = target.tag[i] = toupper(text[i + 1]); + _lastStringTag[i] = target.tag[i] = 0; + text += i + 2; + + if (_existLanguageFile) { + LangIndexNode *found = NULL; + + // HACK: These are used for the object line when + // using one object on another. I don't know if the + // text in the language file is a placeholder or if + // we're supposed to use it, but at least in the + // English version things will work so much better if + // we can't find translations for these. + + if (strcmp(target.tag, "PU_M001") != 0 && strcmp(target.tag, "PU_M002") != 0) + found = (LangIndexNode *)bsearch(&target, _languageIndex, _languageIndexSize, sizeof(LangIndexNode), indexCompare); + if (found != NULL) { + strcpy((char *)trans_buff, _languageBuffer + found->offset); + + // FIXME / TODO: Maybe this should be enabled for Full Throttle, too? + if ((_gameId == GID_DIG) && !(_features & GF_DEMO)) { + // Replace any '%___' by the corresponding special codes in the source text + const byte *src = text; + char *dst = (char *)trans_buff; + + while ((dst = strstr(dst, "%___"))) { + // Search for a special code in the message. They have + // the form: 255-byte OP-byte ARG-int16 + while (*src && *src != 0xFF) { + src++; + } + + // Replace the %___ by the special code + if (*src == 0xFF) { + memcpy(dst, src, 4); + src += 4; + dst += 4; + } else + break; } - - // Replace the %___ by the special code - if (*src == 0xFF) { - memcpy(dst, src, 4); - src += 4; - dst += 4; - } else - break; } - } - - return; - } - } - byte *pointer = (byte *)strchr((const char *)text + 1, '/'); - if (pointer != NULL) { - pointer++; - if (_gameId == GID_CMI) { - memcpy(trans_buff, pointer, resStrLen(pointer) + 1); - } else if (_gameId == GID_DIG) { - l = 0; - while (*pointer != '/' && *pointer != 0xff && *pointer != 0) { - trans_buff[l++] = *pointer++; + return; } - trans_buff[l] = '\0'; } - } else { - memcpy(trans_buff, text, resStrLen(text) + 1); } + + // Default: just copy the string + memcpy(trans_buff, text, resStrLen(text) + 1); } } // End of namespace Scumm |