diff options
author | BLooperZ | 2019-08-17 20:08:40 +0300 |
---|---|---|
committer | Eugene Sandulenko | 2020-01-01 00:31:21 +0100 |
commit | 0625518e9f8ba094ddf90ae55a7bae3d236c0882 (patch) | |
tree | f5cb81db1ffeb97ac4781dcc6a630ba604c9b734 /engines/scumm | |
parent | 80218a52033e076f43a2938cb0288b931fa934a6 (diff) | |
download | scummvm-rg350-0625518e9f8ba094ddf90ae55a7bae3d236c0882.tar.gz scummvm-rg350-0625518e9f8ba094ddf90ae55a7bae3d236c0882.tar.bz2 scummvm-rg350-0625518e9f8ba094ddf90ae55a7bae3d236c0882.zip |
SCUMM: in-place verb strings reversal
Diffstat (limited to 'engines/scumm')
-rw-r--r-- | engines/scumm/string-orig.cpp | 1609 | ||||
-rw-r--r-- | engines/scumm/string.cpp | 89 | ||||
-rw-r--r-- | engines/scumm/verbs.cpp | 19 |
3 files changed, 9 insertions, 1708 deletions
diff --git a/engines/scumm/string-orig.cpp b/engines/scumm/string-orig.cpp deleted file mode 100644 index b76529650c..0000000000 --- a/engines/scumm/string-orig.cpp +++ /dev/null @@ -1,1609 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - */ - - - -#include "common/config-manager.h" -#include "audio/mixer.h" - -#include "scumm/actor.h" -#include "scumm/charset.h" -#include "scumm/dialogs.h" -#include "scumm/file.h" -#include "scumm/imuse_digi/dimuse.h" -#ifdef ENABLE_HE -#include "scumm/he/intern_he.h" -#endif -#include "scumm/resource.h" -#include "scumm/scumm.h" -#include "scumm/scumm_v6.h" -#include "scumm/scumm_v8.h" -#include "scumm/verbs.h" -#include "scumm/he/sound_he.h" - -namespace Scumm { - - - -#pragma mark - -#pragma mark --- "High level" message code --- -#pragma mark - - - -void ScummEngine::printString(int m, const byte *msg) { - switch (m) { - case 0: - actorTalk(msg); - break; - case 1: - drawString(1, msg); - break; - case 2: - debugMessage(msg); - break; - case 3: - showMessageDialog(msg); - break; - } -} - -#ifdef ENABLE_SCUMM_7_8 -void ScummEngine_v8::printString(int m, const byte *msg) { - if (m == 4) { - const StringTab &st = _string[m]; - enqueueText(msg, st.xpos, st.ypos, st.color, st.charset, st.center); - } else { - ScummEngine::printString(m, msg); - } -} -#endif - -void ScummEngine::debugMessage(const byte *msg) { - byte buffer[500]; - convertMessageToString(msg, buffer, sizeof(buffer)); - - if ((buffer[0] != 0xFF) && _debugMode) { - debug(0, "DEBUG: %s", buffer); - return; - } - - if (buffer[0] == 0xFF && buffer[1] == 10) { - uint32 a, b; - int channel = 0; - - a = buffer[2] | (buffer[3] << 8) | (buffer[6] << 16) | (buffer[7] << 24); - b = buffer[10] | (buffer[11] << 8) | (buffer[14] << 16) | (buffer[15] << 24); - - // Sam and Max uses a caching system, printing empty messages - // and setting VAR_V6_SOUNDMODE beforehand. See patch 609791. - if (_game.id == GID_SAMNMAX) - channel = VAR(VAR_V6_SOUNDMODE); - - if (channel != 2) - _sound->talkSound(a, b, 1, channel); - } -} - -void ScummEngine::showMessageDialog(const byte *msg) { - // Original COMI used different code at this point. - // Seemed to use blastText for the messages - byte buf[500]; - - convertMessageToString(msg, buf, sizeof(buf)); - - if (_string[3].color == 0) - _string[3].color = 4; - - InfoDialog dialog(this, (char *)buf); - VAR(VAR_KEYPRESS) = runDialog(dialog); -} - - -#pragma mark - -#pragma mark --- V6 blast text queue code --- -#pragma mark - - - -void ScummEngine_v6::enqueueText(const byte *text, int x, int y, byte color, byte charset, bool center) { - BlastText &bt = _blastTextQueue[_blastTextQueuePos++]; - assert(_blastTextQueuePos <= ARRAYSIZE(_blastTextQueue)); - - convertMessageToString(text, bt.text, sizeof(bt.text)); - bt.xpos = x; - bt.ypos = y; - bt.color = color; - bt.charset = charset; - bt.center = center; -} - -void ScummEngine_v6::drawBlastTexts() { - byte *buf; - int c; - int i; - - for (i = 0; i < _blastTextQueuePos; i++) { - - buf = _blastTextQueue[i].text; - - _charset->_top = _blastTextQueue[i].ypos + _screenTop; - _charset->_right = _screenWidth - 1; - _charset->_center = _blastTextQueue[i].center; - _charset->setColor(_blastTextQueue[i].color); - _charset->_disableOffsX = _charset->_firstChar = true; - _charset->setCurID(_blastTextQueue[i].charset); - - do { - _charset->_left = _blastTextQueue[i].xpos; - - // Center text if necessary - if (_charset->_center) { - _charset->_left -= _charset->getStringWidth(0, buf) / 2; - if (_charset->_left < 0) - _charset->_left = 0; - } - - do { - c = *buf++; - - // FIXME: This is a workaround for bugs #864030 and #1399843: - // In COMI, some text contains ASCII character 11 = 0xB. It's - // not quite clear what it is good for; so for now we just ignore - // it, which seems to match the original engine (BTW, traditionally, - // this is a 'vertical tab'). - if (c == 0x0B) - continue; - - // Some localizations may override colors - // See credits in Chinese COMI - if (_game.id == GID_CMI && _language == Common::ZH_TWN && - c == '^' && (buf == _blastTextQueue[i].text + 1)) { - if (*buf == 'c') { - int color = buf[3] - '0' + 10 *(buf[2] - '0'); - _charset->setColor(color); - - buf += 4; - c = *buf++; - } - } - - if (c != 0 && c != 0xFF && c != '\n') { - if (c & 0x80 && _useCJKMode) { - if (_language == Common::JA_JPN && !checkSJISCode(c)) { - c = 0x20; //not in S-JIS - } else { - c += *buf++ * 256; - } - } - _charset->printChar(c, true); - } - } while (c && c != '\n'); - - _charset->_top += _charset->getFontHeight(); - } while (c); - - _blastTextQueue[i].rect = _charset->_str; - } -} - -void ScummEngine_v6::removeBlastTexts() { - int i; - - for (i = 0; i < _blastTextQueuePos; i++) { - restoreBackground(_blastTextQueue[i].rect); - } - _blastTextQueuePos = 0; -} - - -#pragma mark - -#pragma mark --- V7 subtitle queue code --- -#pragma mark - - - -#ifdef ENABLE_SCUMM_7_8 -void ScummEngine_v7::processSubtitleQueue() { - for (int i = 0; i < _subtitleQueuePos; ++i) { - SubtitleText *st = &_subtitleQueue[i]; - if (!st->actorSpeechMsg && (!ConfMan.getBool("subtitles") || VAR(VAR_VOICE_MODE) == 0)) - // no subtitles and there's a speech variant of the message, don't display the text - continue; - enqueueText(st->text, st->xpos, st->ypos, st->color, st->charset, false); - } -} - -void ScummEngine_v7::addSubtitleToQueue(const byte *text, const Common::Point &pos, byte color, byte charset) { - if (text[0] && strcmp((const char *)text, " ") != 0) { - assert(_subtitleQueuePos < ARRAYSIZE(_subtitleQueue)); - SubtitleText *st = &_subtitleQueue[_subtitleQueuePos]; - int i = 0; - while (1) { - st->text[i] = text[i]; - if (!text[i]) - break; - ++i; - } - st->xpos = pos.x; - st->ypos = pos.y; - st->color = color; - st->charset = charset; - st->actorSpeechMsg = _haveActorSpeechMsg; - ++_subtitleQueuePos; - } -} - -void ScummEngine_v7::clearSubtitleQueue() { - memset(_subtitleQueue, 0, sizeof(_subtitleQueue)); - _subtitleQueuePos = 0; -} -#endif - - - -#pragma mark - -#pragma mark --- Core message/subtitle code --- -#pragma mark - - - -bool ScummEngine::handleNextCharsetCode(Actor *a, int *code) { - uint32 talk_sound_a = 0; - uint32 talk_sound_b = 0; - int color, frme, c = 0, oldy; - bool endLoop = false; - byte *buffer = _charsetBuffer + _charsetBufPos; - while (!endLoop) { - c = *buffer++; - if (!(c == 0xFF || (_game.version <= 6 && c == 0xFE))) { - break; - } - c = *buffer++; - - if (_newLineCharacter != 0 && c == _newLineCharacter) { - c = 13; - break; - } - - switch (c) { - case 1: - c = 13; // new line - _msgCount = _screenWidth; - endLoop = true; - break; - case 2: - _haveMsg = 0; - _keepText = true; - endLoop = true; - break; - case 3: - _haveMsg = (_game.version >= 7) ? 1 : 0xFF; - _keepText = false; - _msgCount = 0; - endLoop = true; - break; - case 8: - // Ignore this code here. Occurs e.g. in MI2 when you - // talk to the carpenter on scabb island. It works like - // code 1 (=newline) in verb texts, but is ignored in - // spoken text (i.e. here). Used for very long verb - // sentences. - break; - case 9: - frme = buffer[0] | (buffer[1] << 8); - buffer += 2; - if (a) - a->startAnimActor(frme); - break; - case 10: - // Note the similarity to the code in debugMessage() - talk_sound_a = buffer[0] | (buffer[1] << 8) | (buffer[4] << 16) | (buffer[5] << 24); - talk_sound_b = buffer[8] | (buffer[9] << 8) | (buffer[12] << 16) | (buffer[13] << 24); - buffer += 14; - if (_game.heversion >= 60) { - ((SoundHE *)_sound)->startHETalkSound(talk_sound_a); - } else { - _sound->talkSound(talk_sound_a, talk_sound_b, 2); - } - _haveActorSpeechMsg = false; - break; - case 12: - color = buffer[0] | (buffer[1] << 8); - buffer += 2; - if (color == 0xFF) - _charset->setColor(_charsetColor); - else - _charset->setColor(color); - break; - case 13: - debug(0, "handleNextCharsetCode: Unknown opcode 13 %d", READ_LE_UINT16(buffer)); - buffer += 2; - break; - case 14: - oldy = _charset->getFontHeight(); - _charset->setCurID(*buffer++); - buffer += 2; - memcpy(_charsetColorMap, _charsetData[_charset->getCurID()], 4); - _nextTop -= _charset->getFontHeight() - oldy; - break; - default: - error("handleNextCharsetCode: invalid code %d", c); - } - } - _charsetBufPos = buffer - _charsetBuffer; - *code = c; - return (c != 2 && c != 3); -} - -#ifdef ENABLE_HE -bool ScummEngine_v72he::handleNextCharsetCode(Actor *a, int *code) { - const int charsetCode = (_game.heversion >= 80) ? 127 : 64; - uint32 talk_sound_a = 0; - //uint32 talk_sound_b = 0; - int i, c = 0; - char value[32]; - bool endLoop = false; - bool endText = false; - byte *buffer = _charsetBuffer + _charsetBufPos; - while (!endLoop) { - c = *buffer++; - if (c != charsetCode) { - break; - } - c = *buffer++; - switch (c) { - case 84: - i = 0; - c = *buffer++; - while (c != 44) { - value[i] = c; - c = *buffer++; - i++; - } - value[i] = 0; - talk_sound_a = atoi(value); - i = 0; - c = *buffer++; - while (c != charsetCode) { - value[i] = c; - c = *buffer++; - i++; - } - value[i] = 0; - //talk_sound_b = atoi(value); - ((SoundHE *)_sound)->startHETalkSound(talk_sound_a); - break; - case 104: - _haveMsg = 0; - _keepText = true; - endLoop = endText = true; - break; - case 110: - c = 13; // new line - endLoop = true; - break; - case 116: - i = 0; - memset(value, 0, sizeof(value)); - c = *buffer++; - while (c != charsetCode) { - value[i] = c; - c = *buffer++; - i++; - } - value[i] = 0; - talk_sound_a = atoi(value); - //talk_sound_b = 0; - ((SoundHE *)_sound)->startHETalkSound(talk_sound_a); - break; - case 119: - _haveMsg = 0xFF; - _keepText = false; - endLoop = endText = true; - break; - default: - error("handleNextCharsetCode: invalid code %d", c); - } - } - _charsetBufPos = buffer - _charsetBuffer; - *code = c; - return (endText == 0); -} -#endif - -bool ScummEngine::newLine() { - _nextLeft = _string[0].xpos; - if (_charset->_center) { - _nextLeft -= _charset->getStringWidth(0, _charsetBuffer + _charsetBufPos) / 2; - if (_nextLeft < 0) - _nextLeft = _game.version >= 6 ? _string[0].xpos : 0; - } - - if (_game.version == 0) { - return false; - } else if (!(_game.platform == Common::kPlatformFMTowns) && _string[0].height) { - _nextTop += _string[0].height; - } else { - bool useCJK = _useCJKMode; - // SCUMM5 FM-Towns doesn't use the height of the ROM font here. - if (_game.platform == Common::kPlatformFMTowns && _game.version == 5) - _useCJKMode = false; - _nextTop += _charset->getFontHeight(); - _useCJKMode = useCJK; - } - if (_game.version > 3) { - // FIXME: is this really needed? - _charset->_disableOffsX = true; - } - return true; -} - -void ScummEngine::CHARSET_1() { - Actor *a; -#ifdef ENABLE_SCUMM_7_8 - byte subtitleBuffer[200]; - byte *subtitleLine = subtitleBuffer; - Common::Point subtitlePos; - - if (_game.version >= 7) { - ((ScummEngine_v7 *)this)->processSubtitleQueue(); - } -#endif - - if (_game.heversion >= 70 && _haveMsg == 3) { - stopTalk(); - return; - } - - if (!_haveMsg) - return; - - if (_game.version >= 4 && _game.version <= 6) { - // Do nothing while the camera is moving - if ((camera._dest.x / 8) != (camera._cur.x / 8) || camera._cur.x != camera._last.x) - return; - } - - a = NULL; - if (getTalkingActor() != 0xFF) - a = derefActorSafe(getTalkingActor(), "CHARSET_1"); - - if (a && _string[0].overhead) { - int s; - - _string[0].xpos = a->getPos().x - _virtscr[kMainVirtScreen].xstart; - _string[0].ypos = a->getPos().y - a->getElevation() - _screenTop; - - if (_game.version <= 5) { - - if (VAR(VAR_V5_TALK_STRING_Y) < 0) { - s = (a->_scaley * (int)VAR(VAR_V5_TALK_STRING_Y)) / 0xFF; - _string[0].ypos += (int)(((VAR(VAR_V5_TALK_STRING_Y) - s) / 2) + s); - } else { - _string[0].ypos = (int)VAR(VAR_V5_TALK_STRING_Y); - } - - } else { - s = a->_scalex * a->_talkPosX / 0xFF; - _string[0].xpos += ((a->_talkPosX - s) / 2) + s; - - s = a->_scaley * a->_talkPosY / 0xFF; - _string[0].ypos += ((a->_talkPosY - s) / 2) + s; - - if (_string[0].ypos > _screenHeight - 40) - _string[0].ypos = _screenHeight - 40; - } - - if (_string[0].ypos < 1) - _string[0].ypos = 1; - - if (_string[0].xpos < 80) - _string[0].xpos = 80; - if (_string[0].xpos > _screenWidth - 80) - _string[0].xpos = _screenWidth - 80; - } - - _charset->_top = _string[0].ypos + _screenTop; - _charset->_startLeft = _charset->_left = _string[0].xpos; - _charset->_right = _string[0].right; - _charset->_center = _string[0].center; - _charset->setColor(_charsetColor); - - if (a && a->_charset) - _charset->setCurID(a->_charset); - else - _charset->setCurID(_string[0].charset); - - if (_game.version >= 5) - memcpy(_charsetColorMap, _charsetData[_charset->getCurID()], 4); - -#ifndef DISABLE_TOWNS_DUAL_LAYER_MODE - if (_keepText && _game.platform == Common::kPlatformFMTowns) - memcpy(&_charset->_str, &_curStringRect, sizeof(Common::Rect)); -#endif - - if (_talkDelay) - return; - - if ((_game.version <= 6 && _haveMsg == 1) || - (_game.version == 7 && _haveMsg != 1)) { - - if (_game.heversion >= 60) { - if (_sound->isSoundRunning(1) == 0) - stopTalk(); - } else { - if ((_sound->_sfxMode & 2) == 0) - stopTalk(); - } - return; - } - - if (a && !_string[0].no_talk_anim) { - a->runActorTalkScript(a->_talkStartFrame); - _useTalkAnims = true; - } - - _talkDelay = (VAR_DEFAULT_TALK_DELAY != 0xFF) ? VAR(VAR_DEFAULT_TALK_DELAY) : 60; - - if (!_keepText) { - if (_game.version >= 7) { -#ifdef ENABLE_SCUMM_7_8 - ((ScummEngine_v7 *)this)->clearSubtitleQueue(); - _nextLeft = _string[0].xpos; - _nextTop = _string[0].ypos + _screenTop; -#endif - } else { -#ifndef DISABLE_TOWNS_DUAL_LAYER_MODE - if (_game.platform == Common::kPlatformFMTowns) - towns_restoreCharsetBg(); - else -#endif - restoreCharsetBg(); - } - _msgCount = 0; - } else if (_game.version <= 2) { - _talkDelay += _msgCount * _defaultTalkDelay; - } - - if (_game.version > 3) { - int maxwidth = _charset->_right - _string[0].xpos - 1; - if (_charset->_center) { - if (maxwidth > _nextLeft) - maxwidth = _nextLeft; - maxwidth *= 2; - } - - _charset->addLinebreaks(0, _charsetBuffer + _charsetBufPos, 0, maxwidth); - } - - if (_charset->_center) { - _nextLeft -= _charset->getStringWidth(0, _charsetBuffer + _charsetBufPos) / 2; - if (_nextLeft < 0) - _nextLeft = _game.version >= 6 ? _string[0].xpos : 0; - } - - _charset->_disableOffsX = _charset->_firstChar = !_keepText; - - int c = 0; - while (handleNextCharsetCode(a, &c)) { - if (c == 0) { - // End of text reached, set _haveMsg accordingly - _haveMsg = (_game.version >= 7) ? 2 : 1; - _keepText = false; - _msgCount = 0; - break; - } - - if (c == 13) { -#ifdef ENABLE_SCUMM_7_8 - if (_game.version >= 7 && subtitleLine != subtitleBuffer) { - ((ScummEngine_v7 *)this)->addSubtitleToQueue(subtitleBuffer, subtitlePos, _charsetColor, _charset->getCurID()); - subtitleLine = subtitleBuffer; - } -#endif - if (!newLine()) - break; - continue; - } - - // Handle line overflow for V3. See also bug #1306269. - if (_game.version == 3 && _nextLeft >= _screenWidth) { - _nextLeft = _screenWidth; - } - // Handle line breaks for V1-V2 - if (_game.version <= 2 && _nextLeft >= _screenWidth) { - if (!newLine()) - break; // FIXME: Is this necessary? Only would be relevant for v0 games - } - - _charset->_left = _nextLeft; - _charset->_top = _nextTop; - - if (_game.version >= 7) { -#ifdef ENABLE_SCUMM_7_8 - if (subtitleLine == subtitleBuffer) { - subtitlePos.x = _charset->_left; - // BlastText position is relative to the top of the screen, adjust y-coordinate - subtitlePos.y = _charset->_top - _screenTop; - } - *subtitleLine++ = c; - *subtitleLine = '\0'; -#endif - } else { - if (c & 0x80 && _useCJKMode) { - if (checkSJISCode(c)) { - byte *buffer = _charsetBuffer + _charsetBufPos; - c += *buffer++ * 256; //LE - _charsetBufPos = buffer - _charsetBuffer; - } - } - if (_game.version <= 3) { - _charset->printChar(c, false); - _msgCount += 1; - } else { - if (_game.features & GF_16BIT_COLOR) { - // HE games which use sprites for subtitles - } else if (_game.heversion >= 60 && !ConfMan.getBool("subtitles") && _sound->isSoundRunning(1)) { - // Special case for HE games - } else if (_game.id == GID_LOOM && !ConfMan.getBool("subtitles") && (_sound->pollCD())) { - // Special case for Loom (CD), since it only uses CD audio.for sound - } else if (!ConfMan.getBool("subtitles") && (!_haveActorSpeechMsg || _mixer->isSoundHandleActive(*_sound->_talkChannelHandle))) { - // Subtitles are turned off, and there is a voice version - // of this message -> don't print it. - } else { - _charset->printChar(c, false); - } - } - _nextLeft = _charset->_left; - _nextTop = _charset->_top; - } - - if (_game.version <= 2) { - _talkDelay += _defaultTalkDelay; - VAR(VAR_CHARCOUNT)++; - } else { - _talkDelay += (int)VAR(VAR_CHARINC); - } - } - -#ifndef DISABLE_TOWNS_DUAL_LAYER_MODE - if (_game.platform == Common::kPlatformFMTowns && (c == 0 || c == 2 || c == 3)) - memcpy(&_curStringRect, &_charset->_str, sizeof(Common::Rect)); -#endif - -#ifdef ENABLE_SCUMM_7_8 - if (_game.version >= 7 && subtitleLine != subtitleBuffer) { - ((ScummEngine_v7 *)this)->addSubtitleToQueue(subtitleBuffer, subtitlePos, _charsetColor, _charset->getCurID()); - } -#endif -} - -#ifdef ENABLE_SCUMM_7_8 -void ScummEngine_v7::CHARSET_1() { - if (_game.id == GID_FT) { - ScummEngine::CHARSET_1(); - return; - } - - byte subtitleBuffer[2048]; - byte *subtitleLine = subtitleBuffer; - Common::Point subtitlePos; - - processSubtitleQueue(); - - if (!_haveMsg) - return; - - Actor *a = NULL; - if (getTalkingActor() != 0xFF) - a = derefActorSafe(getTalkingActor(), "CHARSET_1"); - - StringTab saveStr = _string[0]; - if (a && _string[0].overhead) { - int s; - - _string[0].xpos = a->getPos().x - _virtscr[kMainVirtScreen].xstart; - s = a->_scalex * a->_talkPosX / 255; - _string[0].xpos += (a->_talkPosX - s) / 2 + s; - - _string[0].ypos = a->getPos().y - a->getElevation() - _screenTop; - s = a->_scaley * a->_talkPosY / 255; - _string[0].ypos += (a->_talkPosY - s) / 2 + s; - } - - _charset->setColor(_charsetColor); - - if (a && a->_charset) - _charset->setCurID(a->_charset); - else - _charset->setCurID(_string[0].charset); - - if (_talkDelay) - return; - - if (VAR(VAR_HAVE_MSG)) { - if ((_sound->_sfxMode & 2) == 0) { - stopTalk(); - } - return; - } - - if (a && !_string[0].no_talk_anim) { - a->runActorTalkScript(a->_talkStartFrame); - } - - if (!_keepText) { - clearSubtitleQueue(); - _nextLeft = _string[0].xpos; - _nextTop = _string[0].ypos + _screenTop; - } - - _charset->_disableOffsX = _charset->_firstChar = !_keepText; - - _talkDelay = VAR(VAR_DEFAULT_TALK_DELAY); - for (int i = _charsetBufPos; _charsetBuffer[i]; ++i) { - _talkDelay += VAR(VAR_CHARINC); - } - - if (_string[0].wrapping) { - _charset->addLinebreaks(0, _charsetBuffer, _charsetBufPos, _screenWidth - 20); - - struct { int pos, w; } substring[10]; - int count = 0; - int maxLineWidth = 0; - int lastPos = 0; - int code = 0; - while (handleNextCharsetCode(a, &code)) { - if (code == 13 || code == 0) { - *subtitleLine++ = '\0'; - assert(count < 10); - substring[count].w = _charset->getStringWidth(0, subtitleBuffer + lastPos); - if (maxLineWidth < substring[count].w) { - maxLineWidth = substring[count].w; - } - substring[count].pos = lastPos; - ++count; - lastPos = subtitleLine - subtitleBuffer; - } else { - *subtitleLine++ = code; - *subtitleLine = '\0'; - } - if (code == 0) { - break; - } - } - - int h = count * _charset->getFontHeight(); - h += _charset->getFontHeight() / 2; - subtitlePos.y = _string[0].ypos; - if (subtitlePos.y + h > _screenHeight - 10) { - subtitlePos.y = _screenHeight - 10 - h; - } - if (subtitlePos.y < 10) { - subtitlePos.y = 10; - } - - for (int i = 0; i < count; ++i) { - subtitlePos.x = _string[0].xpos; - if (_string[0].center) { - if (subtitlePos.x + maxLineWidth / 2 > _screenWidth - 10) { - subtitlePos.x = _screenWidth - 10 - maxLineWidth / 2; - } - if (subtitlePos.x - maxLineWidth / 2 < 10) { - subtitlePos.x = 10 + maxLineWidth / 2; - } - subtitlePos.x -= substring[i].w / 2; - } else { - if (subtitlePos.x + maxLineWidth > _screenWidth - 10) { - subtitlePos.x = _screenWidth - 10 - maxLineWidth; - } - if (subtitlePos.x - maxLineWidth < 10) { - subtitlePos.x = 10; - } - } - if (subtitlePos.y < _screenHeight - 10) { - addSubtitleToQueue(subtitleBuffer + substring[i].pos, subtitlePos, _charsetColor, _charset->getCurID()); - } - subtitlePos.y += _charset->getFontHeight(); - } - } else { - int code = 0; - subtitlePos.y = _string[0].ypos; - if (subtitlePos.y < 10) { - subtitlePos.y = 10; - } - while (handleNextCharsetCode(a, &code)) { - if (code == 13 || code == 0) { - subtitlePos.x = _string[0].xpos; - if (_string[0].center) { - subtitlePos.x -= _charset->getStringWidth(0, subtitleBuffer) / 2; - } - if (subtitlePos.x < 10) { - subtitlePos.x = 10; - } - if (subtitlePos.y < _screenHeight - 10) { - addSubtitleToQueue(subtitleBuffer, subtitlePos, _charsetColor, _charset->getCurID()); - subtitlePos.y += _charset->getFontHeight(); - } - subtitleLine = subtitleBuffer; - } else { - *subtitleLine++ = code; - } - *subtitleLine = '\0'; - if (code == 0) { - break; - } - } - } - _haveMsg = (_game.version == 8) ? 2 : 1; - _keepText = false; - _string[0] = saveStr; -} -#endif - -void ScummEngine::drawString(int a, const byte *msg) { - byte buf[270]; - byte *space; - int i, c; - byte fontHeight = 0; - uint color; - int code = (_game.heversion >= 80) ? 127 : 64; - - // drawString is not used in SCUMM v7 and v8 - assert(_game.version < 7); - - convertMessageToString(msg, buf, sizeof(buf)); - - _charset->_top = _string[a].ypos + _screenTop; - _charset->_startLeft = _charset->_left = _string[a].xpos; - _charset->_right = _string[a].right; - _charset->_center = _string[a].center; - _charset->setColor(_string[a].color); - _charset->_disableOffsX = _charset->_firstChar = true; - _charset->setCurID(_string[a].charset); - - // HACK: Correct positions of text in books in Indy3 Mac. - // See also patch #1851568. - if (_game.id == GID_INDY3 && _game.platform == Common::kPlatformMacintosh && a == 1) { - if (_currentRoom == 75) { - // Grail Diary Page 1 (Library) - if (_charset->_startLeft < 160) - _charset->_startLeft = _charset->_left = _string[a].xpos - 22; - else if (_charset->_startLeft < 200) - _charset->_startLeft = _charset->_left = _string[a].xpos - 10; - } else if (_currentRoom == 90) { - // Grail Diary Page 2 (Catacombs - Engravings) - if (_charset->_startLeft < 160) - _charset->_startLeft = _charset->_left = _string[a].xpos - 21; - else if (_charset->_startLeft < 200) - _charset->_startLeft = _charset->_left = _string[a].xpos - 15; - } else if (_currentRoom == 69) { - // Grail Diary Page 3 (Catacombs - Music) - if (_charset->_startLeft < 160) - _charset->_startLeft = _charset->_left = _string[a].xpos - 15; - else if (_charset->_startLeft < 200) - _charset->_startLeft = _charset->_left = _string[a].xpos - 10; - } else if (_currentRoom == 74) { - // Biplane Manual - _charset->_startLeft = _charset->_left = _string[a].xpos - 35; - } - } - - if (_game.version >= 5) - memcpy(_charsetColorMap, _charsetData[_charset->getCurID()], 4); - - fontHeight = _charset->getFontHeight(); - - if (_game.version >= 4) { - // trim from the right - byte *tmp = buf; - space = NULL; - while (*tmp) { - if (*tmp == ' ') { - if (!space) - space = tmp; - } else { - space = NULL; - } - tmp++; - } - if (space) - *space = '\0'; - } - - if (_charset->_center) { - _charset->_left -= _charset->getStringWidth(a, buf) / 2; - } - - if (!buf[0]) { - if (_game.version >= 5) { - buf[0] = ' '; - buf[1] = 0; - } else { - _charset->_str.left = _charset->_left; - _charset->_str.top = _charset->_top; - _charset->_str.right = _charset->_left; - _charset->_str.bottom = _charset->_top; - } - } - - for (i = 0; (c = buf[i++]) != 0;) { - if (_game.heversion >= 72 && c == code) { - c = buf[i++]; - switch (c) { - case 110: - if (_charset->_center) { - _charset->_left = _charset->_startLeft - _charset->getStringWidth(a, buf + i); - } else { - _charset->_left = _charset->_startLeft; - } - _charset->_top += fontHeight; - break; - } - } else if ((c == 0xFF || (_game.version <= 6 && c == 0xFE)) && (_game.heversion <= 71)) { - c = buf[i++]; - switch (c) { - case 9: - case 10: - case 13: - case 14: - i += 2; - break; - case 1: - case 8: - if (_charset->_center) { - _charset->_left = _charset->_startLeft - _charset->getStringWidth(a, buf + i); - } else { - _charset->_left = _charset->_startLeft; - } - if (!(_game.platform == Common::kPlatformFMTowns) && _string[0].height) { - _nextTop += _string[0].height; - } else { - _charset->_top += fontHeight; - } - break; - case 12: - color = buf[i] + (buf[i + 1] << 8); - i += 2; - if (color == 0xFF) - _charset->setColor(_string[a].color); - else - _charset->setColor(color); - break; - } - } else { - if (a == 1 && _game.version >= 6) { - // FIXME: The following code is a bit nasty. It is used for the - // Highway surfing game in Sam&Max; there, _blitAlso is set to - // true when writing the highscore numbers. It is also in DOTT - // for parts the intro and for drawing newspaper headlines. It - // is also used for scores in bowling mini game in fbear and - // for names in load/save screen of all HE games. Maybe it is - // also being used in other places. - // - // A better name for _blitAlso might be _imprintOnBackground - - if (_string[a].no_talk_anim == false) { - //debug(0, "Would have set _charset->_blitAlso = true (wanted to print '%c' = %d)", c, c); - _charset->_blitAlso = true; - } - } - if (c & 0x80 && _useCJKMode) { - if (checkSJISCode(c)) - c += buf[i++] * 256; - } - _charset->printChar(c, true); - _charset->_blitAlso = false; - } - } - - if (a == 0) { - _nextLeft = _charset->_left; - _nextTop = _charset->_top; - } - - _string[a].xpos = _charset->_str.right; - - if (_game.heversion >= 60) { - _string[a]._default.xpos = _string[a].xpos; - _string[a]._default.ypos = _string[a].ypos; - } -} - -int ScummEngine::convertMessageToString(const byte *msg, byte *dst, int dstSize) { - uint num = 0; - uint32 val; - byte chr; - byte lastChr = 0; - const byte *src; - byte *end; - byte transBuf[384]; - - assert(dst); - end = dst + dstSize; - - if (msg == NULL) { - debug(0, "Bad message in convertMessageToString, ignoring"); - return 0; - } - - if (_game.version >= 7) { - translateText(msg, transBuf); - src = transBuf; - } else { - src = msg; - } - - num = 0; - - while (1) { - chr = src[num++]; - if (chr == 0) - break; - - if (_game.id == GID_LOOM && _game.platform == Common::kPlatformPCEngine) { - // Code for TM character - if (chr == 0x0F && src[num] == 0x20) { - *dst++ = 0x5D; - *dst++ = 0x5E; - continue; - // Code for (C) character - } else if (chr == 0x1C && src[num] == 0x20) { - *dst++ = 0x3E; - *dst++ = 0x2A; - continue; - // Code for " character - } else if (chr == 0x19) { - *dst++ = 0x2F; - continue; - } - } - - if (chr == 0xFF) { - chr = src[num++]; - - // WORKAROUND for bug #985948, a script bug in Indy3. Apparently, - // a german 'sz' was encoded incorrectly as 0xFF2E. We replace - // this by the correct encoding here. See also ScummEngine::resStrLen(). - if (_game.id == GID_INDY3 && chr == 0x2E) { - *dst++ = 0xE1; - continue; - } - - // WORKAROUND for bug #1514457: Yet another script bug in Indy3. - // Once more a german 'sz' was encoded incorrectly, but this time - // they simply encoded it as 0xFF instead of 0xE1. Happens twice - // in script 71. - if (_game.id == GID_INDY3 && chr == 0x20 && vm.slot[_currentScript].number == 71) { - num--; - *dst++ = 0xE1; - continue; - } - - if (chr == 1 || chr == 2 || chr == 3 || chr == 8) { - // Simply copy these special codes - *dst++ = 0xFF; - *dst++ = chr; - } else { - val = (_game.version == 8) ? READ_LE_UINT32(src + num) : READ_LE_UINT16(src + num); - switch (chr) { - case 4: - dst += convertIntMessage(dst, end - dst, val); - break; - case 5: - dst += convertVerbMessage(dst, end - dst, val); - break; - case 6: - dst += convertNameMessage(dst, end - dst, val); - break; - case 7: - dst += convertStringMessage(dst, end - dst, val); - break; - case 9: - case 10: - case 12: - case 13: - case 14: - // Simply copy these special codes - *dst++ = 0xFF; - *dst++ = chr; - *dst++ = src[num+0]; - *dst++ = src[num+1]; - if (_game.version == 8) { - *dst++ = src[num+2]; - *dst++ = src[num+3]; - } - break; - default: - error("convertMessageToString(): string escape sequence %d unknown", chr); - } - num += (_game.version == 8) ? 4 : 2; - } - } else { - if ((chr != '@') || (_game.id == GID_CMI && _language == Common::ZH_TWN) || - (_game.id == GID_LOOM && _game.platform == Common::kPlatformPCEngine && _language == Common::JA_JPN) || - (_game.platform == Common::kPlatformFMTowns && _language == Common::JA_JPN && checkSJISCode(lastChr))) { - *dst++ = chr; - } - lastChr = chr; - } - - // Check for a buffer overflow - if (dst >= end) - error("convertMessageToString: buffer overflow"); - } - - // WORKAROUND: Russian The Dig pads messages with 03. No idea why - // it does not work as is with our rendering code, thus fixing it - // with a workaround. - if (_game.id == GID_DIG) { - while (*(dst - 1) == 0x03) - dst--; - } - *dst = 0; - - return dstSize - (end - dst); -} - -#ifdef ENABLE_HE -int ScummEngine_v72he::convertMessageToString(const byte *msg, byte *dst, int dstSize) { - uint num = 0; - byte chr; - const byte *src; - byte *end; - - assert(dst); - end = dst + dstSize; - - if (msg == NULL) { - debug(0, "Bad message in convertMessageToString, ignoring"); - return 0; - } - - src = msg; - num = 0; - - while (1) { - chr = src[num++]; - if (_game.heversion >= 80 && src[num - 1] == '(' && (src[num] == 'p' || src[num] == 'P')) { - // Filter out the following prefixes in subtitles - // (pickup4) - // (PU1) - // (PU2) - while (src[num++] != ')') - ; - continue; - } - if ((_game.features & GF_HE_LOCALIZED) && chr == '[') { - while (src[num++] != ']') - ; - continue; - } - - if (chr == 0) - break; - - *dst++ = chr; - - // Check for a buffer overflow - if (dst >= end) - error("convertMessageToString: buffer overflow"); - } - *dst = 0; - - return dstSize - (end - dst); -} -#endif - -int ScummEngine::convertIntMessage(byte *dst, int dstSize, int var) { - int num; - - num = readVar(var); - return snprintf((char *)dst, dstSize, "%d", num); -} - -int ScummEngine::convertVerbMessage(byte *dst, int dstSize, int var) { - int num, k; - - num = readVar(var); - if (num) { - for (k = 1; k < _numVerbs; k++) { - // Fix ZAK FM-TOWNS bug #1013617 by emulating exact (inconsistant?) behavior of the original code - if (num == _verbs[k].verbid && !_verbs[k].type && (!_verbs[k].saveid || (_game.version == 3 && _game.platform == Common::kPlatformFMTowns))) { - const byte *ptr = getResourceAddress(rtVerb, k); - return convertMessageToString(ptr, dst, dstSize); - } - } - } - return 0; -} - -int ScummEngine::convertNameMessage(byte *dst, int dstSize, int var) { - int num; - - num = readVar(var); - if (num) { - const byte *ptr = getObjOrActorName(num); - if (ptr) { - return convertMessageToString(ptr, dst, dstSize); - } - } - return 0; -} - -int ScummEngine::convertStringMessage(byte *dst, int dstSize, int var) { - const byte *ptr; - - if (_game.version <= 2) { - byte chr; - int i = 0; - while ((chr = (byte)_scummVars[var++])) { - if (chr != '@') { - *dst++ = chr; - i++; - } - } - - return i; - } - - if (_game.version == 3 || (_game.version >= 6 && _game.heversion < 72)) - var = readVar(var); - - if (var) { - ptr = getStringAddress(var); - if (ptr) { - return convertMessageToString(ptr, dst, dstSize); - } - } - return 0; -} - - -#pragma mark - -#pragma mark --- Charset initialisation --- -#pragma mark - - - -#ifdef ENABLE_HE -void ScummEngine_v80he::initCharset(int charsetno) { - ScummEngine::initCharset(charsetno); - VAR(VAR_CURRENT_CHARSET) = charsetno; -} -#endif - -void ScummEngine::initCharset(int charsetno) { - if (_game.id == GID_FT) { - if (!_res->isResourceLoaded(rtCharset, charsetno)) - loadCharset(charsetno); - } else { - if (!getResourceAddress(rtCharset, charsetno)) - loadCharset(charsetno); - } - - _string[0]._default.charset = charsetno; - _string[1]._default.charset = charsetno; - - memcpy(_charsetColorMap, _charsetData[charsetno], sizeof(_charsetColorMap)); -} - - -#pragma mark - -#pragma mark --- Translation/localization code --- -#pragma mark - - - -#ifdef ENABLE_SCUMM_7_8 -static int indexCompare(const void *p1, const void *p2) { - const ScummEngine_v7::LangIndexNode *i1 = (const ScummEngine_v7::LangIndexNode *) p1; - const ScummEngine_v7::LangIndexNode *i2 = (const ScummEngine_v7::LangIndexNode *) p2; - - return strcmp(i1->tag, i2->tag); -} - -// Create an index of the language file. -void ScummEngine_v7::loadLanguageBundle() { - ScummFile file; - int32 size; - - // if game is manually set to English, don't try to load localized text - if ((_language == Common::EN_ANY) || (_language == Common::EN_USA) || (_language == Common::EN_GRB)) { - warning("Language file is forced to be ignored"); - - _existLanguageFile = false; - return; - } - - if (_game.id == GID_DIG) { - openFile(file, "language.bnd"); - } else if (_game.id == GID_CMI) { - openFile(file, "language.tab"); - } else { - return; - } - if (file.isOpen() == false) { - _existLanguageFile = false; - return; - } - - _existLanguageFile = true; - - size = file.size(); - _languageBuffer = (char *)calloc(1, size+1); - file.read(_languageBuffer, size); - file.close(); - - int32 i; - char *ptr = _languageBuffer; - - // Count the number of lines in the language file. - for (_languageIndexSize = 0; ; _languageIndexSize++) { - ptr = strpbrk(ptr, "\n\r"); - if (ptr == NULL) - break; - while (*ptr == '\n' || *ptr == '\r') - ptr++; - } - - // Fill the language file index. This is just an array of - // tags and offsets. I did consider using a balanced tree - // instead, but the extra overhead in the node structure would - // easily have doubled the memory consumption of the index. - // And anyway, using qsort + bsearch gives us the exact same - // O(log(n)) access time anyway ;-). - - _languageIndex = (LangIndexNode *)calloc(_languageIndexSize, sizeof(LangIndexNode)); - - ptr = _languageBuffer; - - if (_game.id == GID_DIG) { - int lineCount = _languageIndexSize; - const char *baseTag = ""; - byte enc = 0; // Initially assume the language file is not encoded - - // We'll determine the real index size as we go. - _languageIndexSize = 0; - for (i = 0; i < lineCount; i++) { - if (*ptr == '!') { - // Don't know what a line with '!' means, just ignore it - } else if (*ptr == 'h') { - // File contains Korean text (Hangul). just ignore it - } else if (*ptr == 'j') { - // File contains Japanese text. just ignore it - } else if (*ptr == 'c') { - // File contains Chinese text. just ignore it - } else if (*ptr == 'e') { - // File is encoded! - enc = 0x13; - } else if (*ptr == '@') { - // A new 'base tag' - baseTag = ptr + 1; - } else if (*ptr == '#') { - // Number of subtags following a given basetag. We don't need that - // information so we just skip it - } else if (Common::isDigit(*ptr)) { - int idx = 0; - // A number (up to three digits)... - while (Common::isDigit(*ptr)) { - idx = idx * 10 + (*ptr - '0'); - ptr++; - } - - // ...followed by a slash... - assert(*ptr == '/'); - ptr++; - - // ...and then the translated message, possibly encoded - _languageIndex[_languageIndexSize].offset = ptr - _languageBuffer; - - // Decode string if necessary. - if (enc) { - while (*ptr != '\n' && *ptr != '\r') - *ptr++ ^= enc; - } - - // The tag is the basetag, followed by a dot and then the index - sprintf(_languageIndex[_languageIndexSize].tag, "%s.%03d", baseTag, idx); - - // That was another index entry - _languageIndexSize++; - } else { - error("Unknown language.bnd entry found: '%s'", ptr); - } - - // Skip over newlines (and turn them into null bytes) - ptr = strpbrk(ptr, "\n\r"); - if (ptr == NULL) - break; - while (*ptr == '\n' || *ptr == '\r') - *ptr++ = 0; - } - } else { - for (i = 0; i < _languageIndexSize; i++) { - // First 8 chars in the line give the string ID / 'tag' - int j; - for (j = 0; j < 8 && !Common::isSpace(*ptr); j++, ptr++) - _languageIndex[i].tag[j] = toupper(*ptr); - _languageIndex[i].tag[j] = 0; - - // After that follows a single space which we skip - assert(Common::isSpace(*ptr)); - ptr++; - - // Then comes the translated string: we record an offset to that. - _languageIndex[i].offset = ptr - _languageBuffer; - - // Skip over newlines (and turn them into null bytes) - ptr = strpbrk(ptr, "\n\r"); - if (ptr == NULL) - break; - while (*ptr == '\n' || *ptr == '\r') - *ptr++ = 0; - - // Convert '\n' code to a newline. See also bug #902415. - char *src, *dst; - src = dst = _languageBuffer + _languageIndex[i].offset; - while (*src) { - if (src[0] == '\\' && src[1] == 'n') { - *dst++ = '\n'; - src += 2; - } else { - *dst++ = *src++; - } - } - *dst = 0; - } - } - - // Sort the index nodes. We'll later use bsearch on it, which is just as efficient - // as using a binary tree, speed wise. - qsort(_languageIndex, _languageIndexSize, sizeof(LangIndexNode), indexCompare); -} - -void ScummEngine_v7::playSpeech(const byte *ptr) { - if (_game.id == GID_DIG && (ConfMan.getBool("speech_mute") || VAR(VAR_VOICE_MODE) == 2)) - return; - - if ((_game.id == GID_DIG || _game.id == GID_CMI) && ptr[0]) { - char pointer[20]; - strcpy(pointer, (const char *)ptr); - - // Play speech - if (!(_game.features & GF_DEMO) && (_game.id == GID_CMI)) // CMI demo does not have .IMX for voice - strcat(pointer, ".IMX"); - - _sound->stopTalkSound(); - _imuseDigital->stopSound(kTalkSoundID); - _imuseDigital->startVoice(kTalkSoundID, pointer); - _sound->talkSound(0, 0, 2); - } -} - -void ScummEngine_v7::translateText(const byte *text, byte *trans_buff) { - LangIndexNode target; - LangIndexNode *found = NULL; - int i; - - trans_buff[0] = 0; - _lastStringTag[0] = 0; - - if (_game.version >= 7 && text[0] == '/') { - // Extract the string tag from the text: /..../ - for (i = 0; (i < 12) && (text[i + 1] != '/'); i++) - _lastStringTag[i] = toupper(text[i + 1]); - _lastStringTag[i] = 0; - } - - // WORKAROUND for bug #1172655. - if (_game.id == GID_DIG) { - // Based on the second release of The Dig - // Only applies to the subtitles and not speech - if (!strcmp((const char *)text, "faint light")) - text = (const byte *)"/NEW.007/faint light"; - else if (!strcmp((const char *)text, "glowing crystal")) - text = (const byte *)"/NEW.008/glowing crystal"; - else if (!strcmp((const char *)text, "glowing crystals")) - text = (const byte *)"/NEW.009/glowing crystals"; - else if (!strcmp((const char *)text, "pit")) - text = (const byte *)"/NEW.010/pit"; - else if (!strcmp((const char *)text, "You wish.")) - text = (const byte *)"/NEW.011/You wish."; - else if (!strcmp((const char *)text, "In your dreams.")) - text = (const byte *)"/NEW.012/In your dreams"; - else if (!strcmp((const char *)text, "left")) - text = (const byte *)"/CATHPLAT.068/left"; - else if (!strcmp((const char *)text, "right")) - text = (const byte *)"/CATHPLAT.070/right"; - else if (!strcmp((const char *)text, "top")) - text = (const byte *)"/CATHPLAT.067/top"; - else if (!strcmp((const char *)text, "exit")) - text = (const byte *)"/SKY.008/exit"; - else if (!strcmp((const char *)text, "unattached lens")) - text = (const byte *)"/NEW.013/unattached lens"; - else if (!strcmp((const char *)text, "lens slot")) - text = (const byte *)"/NEW.014/lens slot"; - else if (!strcmp((const char *)text, "Jonathon Jackson")) - text = (const byte *)"Aram Gutowski"; - else if (!strcmp((const char *)text, "Brink")) - text = (const byte *)"/CREVICE.049/Brink"; - else if (!strcmp((const char *)text, "Robbins")) - text = (const byte *)"/NEST.061/Robbins"; - } - - - if (_game.version >= 7 && text[0] == '/') { - // Extract the string tag from the text: /..../ - for (i = 0; (i < 12) && (text[i + 1] != '/'); i++) - target.tag[i] = toupper(text[i + 1]); - target.tag[i] = 0; - text += i + 2; - - // If a language file was loaded, try to find a translated version - // by doing a lookup on the string tag. - if (_existLanguageFile) { - // HACK: These are used for the object line in COMI 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 (*text && 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); - - if ((_game.id == GID_DIG) && !(_game.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. - while (*src && *src != 0xFF) { - src++; - } - - // Replace the %___ by the special code. Luckily, we can do - // that in-place. - if (*src == 0xFF) { - memcpy(dst, src, 4); - src += 4; - dst += 4; - } else - break; - } - } - } else { - // Default: just copy the string - memcpy(trans_buff, text, resStrLen(text) + 1); - } -} - -#endif - -void ScummEngine::translateText(const byte *text, byte *trans_buff) { - // Default: just copy the string - memcpy(trans_buff, text, resStrLen(text) + 1); -} - -} // End of namespace Scumm
\ No newline at end of file diff --git a/engines/scumm/string.cpp b/engines/scumm/string.cpp index c8e7db2ab1..f50bcac697 100644 --- a/engines/scumm/string.cpp +++ b/engines/scumm/string.cpp @@ -248,10 +248,8 @@ void ScummEngine_v7::addSubtitleToQueue(const byte *text, const Common::Point &p assert(_subtitleQueuePos < ARRAYSIZE(_subtitleQueue)); SubtitleText *st = &_subtitleQueue[_subtitleQueuePos]; int i = 0; - - // int len = strlen((const char *)text); while (1) { - st->text[i] = text[i]; // text[len - i - 1]; + st->text[i] = text[i]; if (!text[i]) break; ++i; @@ -609,6 +607,7 @@ void ScummEngine::CHARSET_1() { _charset->addLinebreaks(0, _charsetBuffer + _charsetBufPos, 0, maxwidth); } + if (_charset->_center) { _nextLeft -= _charset->getStringWidth(0, _charsetBuffer + _charsetBufPos) / 2; if (_nextLeft < 0) @@ -637,21 +636,10 @@ void ScummEngine::CHARSET_1() { int start = 0; char* text = ltext + ll; - - - // for (int u = 0; u < strlen(text); u++) { - // char buffy[30] = {0}; - // sprintf(buffy, "[%d-%c],", text[u], text[u]); - // debugN(buffy); - // } - // debugN("\n"); - - char* current = text; while(1) { if (*current == 13 || *current == 0 || *current == -1 || *current == -2) { - - // ignore the line break for interface texts + // ignore the line break for verbs texts if (*(current + 1) == 8) { *(current + 1) = *current; *current = 8; @@ -690,9 +678,8 @@ void ScummEngine::CHARSET_1() { if (*current == 3) { break; } - if (*current == 0x0A) { + if (*current == 0x0A || *current == 0x0C) { start += 2; - i +=2; current += 2; } start++; @@ -708,17 +695,6 @@ void ScummEngine::CHARSET_1() { } break; } - - - // warning("REVERSED"); - // for (int u = 0; u < strlen(text); u++) { - // char buffy[30] = {0}; - // sprintf(buffy, "[%d-%c],", text[u], text[u]); - // debugN(buffy); - // } - // debugN("\n\n\n\n\n"); - - } while (handleNextCharsetCode(a, &c)) { @@ -752,7 +728,6 @@ void ScummEngine::CHARSET_1() { break; // FIXME: Is this necessary? Only would be relevant for v0 games } - // warning("SETTING"); _charset->_left = _nextLeft; _charset->_top = _nextTop; @@ -791,7 +766,6 @@ void ScummEngine::CHARSET_1() { _charset->printChar(c, false); } } - // warning("RESETING"); _nextLeft = _charset->_left; _nextTop = _charset->_top; } @@ -1001,14 +975,9 @@ void ScummEngine::drawString(int a, const byte *msg) { while (ltext[ll] == -1) { ll += 4; } - byte fin[270] = {0}; - - memcpy(fin, ltext, ll); int pos = 0; int start = 0; char* text = (char*)ltext + ll; - - strncpy((char*)fin + ll, text, strlen(text)); char* current = text; while(1) { if (*current == 13 || *current == 0 || *current == -1 || *current == -2) { @@ -1032,7 +1001,7 @@ void ScummEngine::drawString(int a, const byte *msg) { buff[pos - sthead] = stack[sthead]; --sthead; } - memcpy(fin + ll + start, buff, pos); + memcpy(text + start, buff, pos); start += pos + 1; pos = -1; if (*current == -1 || *current == -2) { @@ -1040,9 +1009,8 @@ void ScummEngine::drawString(int a, const byte *msg) { if (*current == 3) { break; } - if (*current == 0x0A) { + if (*current == 0x0A || *current == 0x0C) { start += 2; - pos +=2; current += 2; } start++; @@ -1058,7 +1026,6 @@ void ScummEngine::drawString(int a, const byte *msg) { } break; } - memcpy(buf, fin, start + pos + ll); if (_game.id == GID_INDY4 && ltext[0] == 127) { buf[start + pos + ll] = 127; @@ -1067,7 +1034,6 @@ void ScummEngine::drawString(int a, const byte *msg) { } - _charset->_top = _string[a].ypos + _screenTop; _charset->_startLeft = _charset->_left = _string[a].xpos; _charset->_right = _string[a].right; @@ -1128,7 +1094,6 @@ void ScummEngine::drawString(int a, const byte *msg) { if (_charset->_center) { _charset->_left -= _charset->getStringWidth(a, buf) / 2; } else if (_game.version >= 4 && _game.version < 7 && _game.id != GID_SAMNMAX && (_language == Common::HE_ISR || true)) { - // warning("FIRST BOTTTOMd"); if (_game.id != GID_INDY4 || buf[0] == 127) { if (_game.id == GID_INDY4 && buf[0] == 127) { buf[0] = 32; @@ -1198,7 +1163,6 @@ void ScummEngine::drawString(int a, const byte *msg) { if (_charset->_center) { _charset->_left = _charset->_startLeft - _charset->getStringWidth(a, buf + i); } else if (_game.version >= 4 && _game.version < 7 && (_language == Common::HE_ISR || true)) { - // warning("SECOND BOTTOM"); if (_charset->getStringWidth(a, buf + i) > _screenWidth) { int ll = 0; byte* ltext = buf + i; @@ -1493,20 +1457,7 @@ int ScummEngine::convertNameMessage(byte *dst, int dstSize, int var) { if (num) { const byte *ptr = getObjOrActorName(num); if (ptr) { - int retval = convertMessageToString(ptr, dst, dstSize); - - // if (_game.version >= 7 && (_language == Common::HE_ISR || true)) { - // byte rev[384] = {0}; - // int lens = strlen((const char *)dst); - - // for (int l = 0; l < lens; l++) { - // rev[l] = dst[lens - l - 1]; - // } - // rev[lens] = '\0'; - // strcpy((char *)dst, (const char *)rev); - // } - - return retval; + return convertMessageToString(ptr, dst, dstSize); } } return 0; @@ -1534,19 +1485,7 @@ int ScummEngine::convertStringMessage(byte *dst, int dstSize, int var) { if (var) { ptr = getStringAddress(var); if (ptr) { - int retval = convertMessageToString(ptr, dst, dstSize); - - // if (_game.version >= 7 && (_language == Common::HE_ISR || true)) { - // byte rev[384] = {0}; - // int lens = strlen((const char *)dst); - - // for (int l = 0; l < lens; l++) { - // rev[l] = dst[lens - l - 1]; - // } - // rev[lens] = '\0'; - // strcpy((char *)dst, (const char *)rev); - // } - return retval; + return convertMessageToString(ptr, dst, dstSize); } } return 0; @@ -1846,16 +1785,6 @@ void ScummEngine_v7::translateText(const byte *text, byte *trans_buff) { } if (found != NULL) { - //char rev[384] = {0}; - //strcpy(rev, _languageBuffer + found->offset); - //int len = strlen(rev); - //for (int l = 0; l < len; l++) { - // trans_buff[l] = rev[len - l - 1]; - //} - //trans_buff[len] = '\0'; - - // OR - strcpy((char *)trans_buff, _languageBuffer + found->offset); if ((_game.id == GID_DIG) && !(_game.features & GF_DEMO)) { @@ -1892,4 +1821,4 @@ void ScummEngine::translateText(const byte *text, byte *trans_buff) { memcpy(trans_buff, text, resStrLen(text) + 1); } -} // End of namespace Scumm +} // End of namespace Scumm
\ No newline at end of file diff --git a/engines/scumm/verbs.cpp b/engines/scumm/verbs.cpp index 7e1809408a..aca28a67a4 100644 --- a/engines/scumm/verbs.cpp +++ b/engines/scumm/verbs.cpp @@ -1002,8 +1002,6 @@ void ScummEngine_v7::drawVerb(int verb, int mode) { // occur in FT; subtype 10, which is used for the speech associated // with the string). byte buf[384] = {0}; - // byte rev[384] = {0}; - convertMessageToString(msg, buf, sizeof(buf)); msg = buf; while (*msg == 0xFF) @@ -1013,23 +1011,6 @@ void ScummEngine_v7::drawVerb(int verb, int mode) { int oldID = _charset->getCurID(); _charset->setCurID(vs->charset_nr); - // // reverse string for rtl support - // if ((_language == Common::HE_ISR || true)/* && !(_game.id == GID_FT && (_charset->getCurID() == 6 || _charset->getCurID() == 7))*/) { - - // int lens = strlen((const char *)msg); - - // for (int l = 0; l < lens; l++) { - // rev[l] = msg[lens - l - 1]; - // } - // rev[lens] = '\0'; - // msg = rev; - // } - - // char numt[10] ={0}; - // sprintf(numt, "%d, %d\n", _charset->getCurID(), oldID); - // warning(numt); - - // Compute the text rect if ((_language == Common::HE_ISR || true)/* && !(_game.id == GID_FT && (_charset->getCurID() == 6 || _charset->getCurID() == 7))*/) { vs->curRect.left = _screenWidth - _charset->getStringWidth(0, buf); |