aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGregory Montoir2005-11-02 21:47:44 +0000
committerGregory Montoir2005-11-02 21:47:44 +0000
commitc84d1ada32bb2093ee7a5d20a73b9c342eca4f11 (patch)
treec076ef2e604e2ca87ff2f03edd3cd36cfbe55d14
parent5e75092decb10ee760d62e2b42272b70eda05e2e (diff)
downloadscummvm-rg350-c84d1ada32bb2093ee7a5d20a73b9c342eca4f11.tar.gz
scummvm-rg350-c84d1ada32bb2093ee7a5d20a73b9c342eca4f11.tar.bz2
scummvm-rg350-c84d1ada32bb2093ee7a5d20a73b9c342eca4f11.zip
To match the original v7/v8 interpreters, use BlastTexts to display the subtitles. This allows to fix the bug #1092993. As this is quite an important change, regressions may appear. You've been warned :)
svn-id: r19398
-rw-r--r--scumm/actor.cpp14
-rw-r--r--scumm/intern.h26
-rw-r--r--scumm/saveload.cpp27
-rw-r--r--scumm/saveload.h2
-rw-r--r--scumm/scumm.cpp5
-rw-r--r--scumm/scumm.h2
-rw-r--r--scumm/string.cpp464
7 files changed, 326 insertions, 214 deletions
diff --git a/scumm/actor.cpp b/scumm/actor.cpp
index dc85f41b9c..c2e76fc97b 100644
--- a/scumm/actor.cpp
+++ b/scumm/actor.cpp
@@ -1360,10 +1360,13 @@ void ScummEngine_v7::actorTalk(const byte *msg) {
}
_charsetBufPos = 0;
_talkDelay = 0;
- _haveMsg = 0xFF;
+ _haveMsg = 1;
if (_version == 7)
VAR(VAR_HAVE_MSG) = 0xFF;
+ _haveActorSpeechMsg = true;
CHARSET_1();
+ if (_version == 8)
+ VAR(VAR_HAVE_MSG) = (_string[0].no_talk_anim) ? 2 : 1;
}
#endif
@@ -1428,6 +1431,7 @@ void ScummEngine::actorTalk(const byte *msg) {
VAR(VAR_HAVE_MSG) = 0xFF;
if (VAR_CHARCOUNT != 0xFF)
VAR(VAR_CHARCOUNT) = 0;
+ _haveActorSpeechMsg = true;
CHARSET_1();
}
@@ -1474,7 +1478,13 @@ void ScummEngine::stopTalk() {
if (_version == 8)
VAR(VAR_HAVE_MSG) = 0;
_keepText = false;
- _charset->restoreCharsetBg();
+ if (_version >= 7) {
+#ifndef DISABLE_SCUMM_7_8
+ ((ScummEngine_v7 *)this)->clearSubtitleQueue();
+#endif
+ } else {
+ _charset->restoreCharsetBg();
+ }
}
void Actor::setActorCostume(int c) {
diff --git a/scumm/intern.h b/scumm/intern.h
index 7f77340da6..37dcb24cc3 100644
--- a/scumm/intern.h
+++ b/scumm/intern.h
@@ -516,6 +516,13 @@ protected:
int _smushFrameRate;
+ struct TextObject {
+ int16 xpos, ypos;
+ byte color;
+ byte charset;
+ byte text[256];
+ };
+
/** BlastObjects to draw */
struct BlastObject {
uint16 number;
@@ -528,13 +535,9 @@ protected:
int _blastObjectQueuePos;
BlastObject _blastObjectQueue[128];
- struct BlastText {
- int16 xpos, ypos;
+ struct BlastText : TextObject {
Common::Rect rect;
- byte color;
- byte charset;
bool center;
- byte text[256];
};
int _blastTextQueuePos;
@@ -1004,6 +1007,8 @@ protected:
int findObject(int x, int y, int num, int *args);
int getSoundResourceSize(int id);
+ virtual bool handleNextCharsetCode(Actor *a, int *c);
+
/* HE version 72 script opcodes */
void o72_pushDWord();
void o72_getScriptString();
@@ -1338,6 +1343,17 @@ public:
int _languageIndexSize;
char _lastStringTag[12+1];
+ struct SubtitleText : TextObject {
+ bool actorSpeechMsg;
+ };
+
+ int _subtitleQueuePos;
+ SubtitleText _subtitleQueue[20];
+
+ void processSubtitleQueue();
+ void addSubtitleToQueue(const byte *text, const Common::Point &pos, byte color, byte charset);
+ void clearSubtitleQueue();
+
protected:
virtual void setupScummVars();
virtual void initScummVars();
diff --git a/scumm/saveload.cpp b/scumm/saveload.cpp
index 88fead21b9..282308c3e8 100644
--- a/scumm/saveload.cpp
+++ b/scumm/saveload.cpp
@@ -730,6 +730,7 @@ void ScummEngine::saveOrLoad(Serializer *s) {
MKLINE(ScummEngine, _charsetBufPos, sleInt16, VER(10)),
MKLINE(ScummEngine, _haveMsg, sleByte, VER(8)),
+ MKLINE(ScummEngine, _haveActorSpeechMsg, sleByte, VER(61)),
MKLINE(ScummEngine, _useTalkAnims, sleByte, VER(8)),
MKLINE(ScummEngine, _talkDelay, sleInt16, VER(8)),
@@ -952,6 +953,13 @@ void ScummEngine::saveOrLoad(Serializer *s) {
_system->warpMouse(_mouse.x, _mouse.y);
}
+ // Before V61, we re-used the _haveMsg flag to handle "alternative" speech
+ // sound files (see charset code 10).
+ if (s->isLoading() && s->getVersion() < VER(61)) {
+ _haveActorSpeechMsg = (_haveMsg != 0xFE);
+ _haveMsg = 0xFF;
+ }
+
//
// Save/load actors
//
@@ -1190,8 +1198,25 @@ void ScummEngine_v5::saveOrLoad(Serializer *s) {
void ScummEngine_v7::saveOrLoad(Serializer *s) {
ScummEngine::saveOrLoad(s);
- assert(_imuseDigital);
+ const SaveLoadEntry subtitleQueueEntries[] = {
+ MKARRAY(SubtitleText, text[0], sleByte, 256, VER(61)),
+ MKLINE(SubtitleText, charset, sleByte, VER(61)),
+ MKLINE(SubtitleText, color, sleByte, VER(61)),
+ MKLINE(SubtitleText, xpos, sleInt16, VER(61)),
+ MKLINE(SubtitleText, ypos, sleInt16, VER(61)),
+ MKLINE(SubtitleText, actorSpeechMsg, sleByte, VER(61)),
+ MKEND()
+ };
+
+ const SaveLoadEntry V7Entries[] = {
+ MKLINE(ScummEngine_v7, _subtitleQueuePos, sleInt32, VER(61)),
+ MKEND()
+ };
+
_imuseDigital->saveOrLoad(s);
+
+ s->saveLoadArrayOf(_subtitleQueue, ARRAYSIZE(_subtitleQueue), sizeof(_subtitleQueue[0]), subtitleQueueEntries);
+ s->saveLoadEntries(this, V7Entries);
}
#endif
diff --git a/scumm/saveload.h b/scumm/saveload.h
index 15453a4043..6c75ea7cd5 100644
--- a/scumm/saveload.h
+++ b/scumm/saveload.h
@@ -45,7 +45,7 @@ namespace Scumm {
* only saves/loads those which are valid for the version of the savegame
* which is being loaded/saved currently.
*/
-#define CURRENT_VER 60
+#define CURRENT_VER 61
/**
* An auxillary macro, used to specify savegame versions. We use this instead
diff --git a/scumm/scumm.cpp b/scumm/scumm.cpp
index b52faccb15..89ed2519db 100644
--- a/scumm/scumm.cpp
+++ b/scumm/scumm.cpp
@@ -1128,6 +1128,7 @@ ScummEngine::ScummEngine(GameDetector *detector, OSystem *syst, const ScummGameS
_palDirtyMin = 0;
_palDirtyMax = 0;
_haveMsg = 0;
+ _haveActorSpeechMsg = false;
_useTalkAnims = false;
_defaultTalkDelay = 0;
_midiDriver = MD_NULL;
@@ -1585,6 +1586,7 @@ ScummEngine_v7::ScummEngine_v7(GameDetector *detector, OSystem *syst, const Scum
_existLanguageFile = false;
_languageBuffer = NULL;
_languageIndex = NULL;
+ clearSubtitleQueue();
}
ScummEngine_v7::~ScummEngine_v7() {
@@ -1939,6 +1941,7 @@ void ScummEngine::scummInit() {
_charsetBufPos = 0;
_haveMsg = 0;
+ _haveActorSpeechMsg = false;
_varwatch = -1;
_screenStartStrip = 0;
@@ -2296,7 +2299,7 @@ int ScummEngine::scummLoop(int delta) {
VAR(VAR_CAMERA_POS_X) = camera._cur.x;
}
if (_version <= 7)
- VAR(VAR_HAVE_MSG) = (_haveMsg == 0xFE) ? 0xFF : _haveMsg;
+ VAR(VAR_HAVE_MSG) = _haveMsg;
if (_platform == Common::kPlatformC64 && _gameId == GID_MANIAC) {
// TODO
diff --git a/scumm/scumm.h b/scumm/scumm.h
index 219a47825a..657f7e0102 100644
--- a/scumm/scumm.h
+++ b/scumm/scumm.h
@@ -1093,6 +1093,7 @@ protected:
byte *_palManipIntermediatePal;
byte _haveMsg;
+ bool _haveActorSpeechMsg;
bool _useTalkAnims;
uint16 _defaultTalkDelay;
int _tempMusic;
@@ -1161,6 +1162,7 @@ protected:
void printString(int m, const byte *msg);
+ virtual bool handleNextCharsetCode(Actor *a, int *c);
void CHARSET_1();
void drawString(int a, const byte *msg);
void debugMessage(const byte *msg);
diff --git a/scumm/string.cpp b/scumm/string.cpp
index 64a4fcb28a..1e554e5234 100644
--- a/scumm/string.cpp
+++ b/scumm/string.cpp
@@ -95,17 +95,212 @@ void ScummEngine::showMessageDialog(const byte *msg) {
VAR(VAR_KEYPRESS) = runDialog(dialog);
}
-void ScummEngine::CHARSET_1() {
+#ifndef DISABLE_SCUMM_7_8
+void ScummEngine_v7::processSubtitleQueue() {
+ for (int i = 0; i < _subtitleQueuePos; ++i) {
+ SubtitleText *st = &_subtitleQueue[i];
+ if (!ConfMan.getBool("subtitles") || VAR(VAR_VOICE_MODE) == 0)
+ // subtitles are disabled, don't display the text
+ continue;
+ if (!ConfMan.getBool("subtitles") && (!st->actorSpeechMsg || _mixer->isSoundHandleActive(_sound->_talkChannelHandle)))
+ // 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
+
+bool ScummEngine::handleNextCharsetCode(Actor *a, int *code) {
uint32 talk_sound_a = 0;
uint32 talk_sound_b = 0;
- int i, t, c;
- int frme;
- Actor *a;
- byte *buffer;
- int code = (_heversion >= 80) ? 127 : 64;
+ int i, color, frme, c, oldy;
+ bool endLoop = false;
+ byte *buffer = _charsetBuffer + _charsetBufPos;
+ while (!endLoop) {
+ c = *buffer++;
+ if (!(c == 0xFF || (_version <= 6 && c == 0xFE))) {
+ break;
+ }
+ c = *buffer++;
+ switch (c) {
+ case 1:
+ c = 13; // new line
+ endLoop = true;
+ break;
+ case 2:
+ _haveMsg = 0;
+ _keepText = true;
+ endLoop = true;
+ break;
+ case 3:
+ _haveMsg = (_version >= 7) ? 1 : 0xFF;
+ _keepText = false;
+ 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 (_heversion >= 60) {
+ _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;
+ for (i = 0; i < 4; i++)
+ _charsetColorMap[i] = _charsetData[_charset->getCurID()][i];
+ _charset->_nextTop -= _charset->getFontHeight() - oldy;
+ break;
+ default:
+ error("handleNextCharsetCode: invalid code %d", c);
+ }
+ }
+ _charsetBufPos = buffer - _charsetBuffer;
+ *code = c;
+ return (c != 2 && c != 3);
+}
+
+#ifndef DISABLE_HE
+bool ScummEngine_v72he::handleNextCharsetCode(Actor *a, int *code) {
+ const int charsetCode = (_heversion >= 80) ? 127 : 64;
+ uint32 talk_sound_a = 0;
+ uint32 talk_sound_b = 0;
+ int i, c;
char value[32];
+ byte *buffer = _charsetBuffer + _charsetBufPos;
+ do {
+ c = *buffer++;
+ if (c != charsetCode) {
+ break;
+ }
+ c = *buffer++;
+ switch (c) {
+ case 84:
+ i = 0;
+ memset(value, 0, 32);
+ c = *buffer++;
+ while (c != 44) {
+ value[i] = c;
+ c = *buffer++;
+ i++;
+ }
+ value[i] = 0;
+ talk_sound_a = atoi(value);
+ i = 0;
+ memset(value, 0, 32);
+ c = *buffer++;
+ while (c != charsetCode) {
+ value[i] = c;
+ c = *buffer++;
+ i++;
+ }
+ value[i] = 0;
+ talk_sound_b = atoi(value);
+ _sound->startHETalkSound(talk_sound_a);
+ break;
+ case 104:
+ _haveMsg = 0;
+ _keepText = true;
+ break;
+ case 110:
+ c = 13; // new line
+ break;
+ case 116:
+ i = 0;
+ memset(value, 0, 32);
+ c = *buffer++;
+ while (c != charsetCode) {
+ value[i] = c;
+ c = *buffer++;
+ i++;
+ }
+ value[i] = 0;
+ talk_sound_a = atoi(value);
+ talk_sound_b = 0;
+ _sound->startHETalkSound(talk_sound_a);
+ break;
+ case 119:
+ _haveMsg = 0xFF;
+ _keepText = false;
+ break;
+ default:
+ error("handleNextCharsetCode: invalid code %d", c);
+ }
+ } while (c != 13);
+ _charsetBufPos = buffer - _charsetBuffer;
+ *code = c;
+ return true;
+}
+#endif
- bool cmi_pos_hack = false;
+void ScummEngine::CHARSET_1() {
+ Actor *a;
+ int t, c = 0;
+#ifndef DISABLE_SCUMM_7_8
+ byte subtitleBuffer[200];
+ byte *subtitleLine = subtitleBuffer;
+ Common::Point subtitlePos;
+
+ if (_version >= 7) {
+ ((ScummEngine_v7 *)this)->processSubtitleQueue();
+ }
+#endif
if (!_haveMsg)
return;
@@ -166,13 +361,12 @@ void ScummEngine::CHARSET_1() {
_charset->setCurID(_string[0].charset);
if (_version >= 5)
- for (i = 0; i < 4; i++)
- _charsetColorMap[i] = _charsetData[_charset->getCurID()][i];
+ memcpy(_charsetColorMap, _charsetData[_charset->getCurID()], 4);
if (_talkDelay)
return;
- if ((_version <= 7 && _haveMsg == 1) || (_version == 8 && VAR(VAR_HAVE_MSG))) {
+ if ((_version <= 6 && _haveMsg == 1) || (_version == 7 && _haveMsg != 1) || (_version == 8 && VAR(VAR_HAVE_MSG))) {
if ((_sound->_sfxMode & 2) == 0)
stopTalk();
return;
@@ -183,14 +377,18 @@ void ScummEngine::CHARSET_1() {
_useTalkAnims = true;
}
- // Always set to 60
- if (_version <= 6)
- _talkDelay = 60;
- else
- _talkDelay = VAR(VAR_DEFAULT_TALK_DELAY);
+ _talkDelay = (VAR_DEFAULT_TALK_DELAY != 0xFF) ? VAR(VAR_DEFAULT_TALK_DELAY) : 60;
if (!_keepText) {
- _charset->restoreCharsetBg();
+ if (_version >= 7) {
+#ifndef DISABLE_SCUMM_7_8
+ ((ScummEngine_v7 *)this)->clearSubtitleQueue();
+ _charset->_nextLeft = _string[0].xpos;
+ _charset->_nextTop = _string[0].ypos;
+#endif
+ } else {
+ _charset->restoreCharsetBg();
+ }
}
t = _charset->_right - _string[0].xpos - 1;
@@ -200,25 +398,21 @@ void ScummEngine::CHARSET_1() {
t *= 2;
}
- buffer = _charsetBuffer + _charsetBufPos;
-
if (_version > 3)
- _charset->addLinebreaks(0, buffer, 0, t);
+ _charset->addLinebreaks(0, _charsetBuffer + _charsetBufPos, 0, t);
if (_charset->_center) {
- _charset->_nextLeft -= _charset->getStringWidth(0, buffer) / 2;
+ _charset->_nextLeft -= _charset->getStringWidth(0, _charsetBuffer + _charsetBufPos) / 2;
if (_charset->_nextLeft < 0)
_charset->_nextLeft = 0;
}
_charset->_disableOffsX = _charset->_firstChar = !_keepText;
- do {
- c = *buffer++;
+ while (handleNextCharsetCode(a, &c)) {
if (c == 0) {
- // End of text reached, set _haveMsg to 1 so that the text will be
- // removed next time CHARSET_1 is called.
- _haveMsg = 1;
+ // End of text reached, set _haveMsg accordingly
+ _haveMsg = (_version >= 7) ? 2 : 1;
_keepText = false;
break;
}
@@ -233,9 +427,16 @@ void ScummEngine::CHARSET_1() {
if (c == 13) {
newLine:;
_charset->_nextLeft = _string[0].xpos;
+#ifndef DISABLE_SCUMM_7_8
+ if (_version >= 7 && subtitleLine != subtitleBuffer) {
+ ((ScummEngine_v7 *)this)->addSubtitleToQueue(subtitleBuffer, subtitlePos, _charsetColor, _charset->getCurID());
+ subtitleLine = subtitleBuffer;
+ }
+#endif
if (_charset->_center) {
- _charset->_nextLeft -= _charset->getStringWidth(0, buffer) / 2;
+ _charset->_nextLeft -= _charset->getStringWidth(0, _charsetBuffer + _charsetBufPos) / 2;
}
+
if (_platform == Common::kPlatformC64 && _gameId == GID_MANIAC) {
break;
} else if (!(_platform == Common::kPlatformFMTowns) && _string[0].height) {
@@ -250,204 +451,59 @@ void ScummEngine::CHARSET_1() {
continue;
}
- if (_heversion >= 72 && c == code) {
- c = *buffer++;
- switch (c) {
- case 84:
- i = 0;
- memset(value, 0, 32);
- c = *buffer++;
- while (c != 44) {
- value[i] = c;
- c = *buffer++;
- i++;
- }
- value[i] = 0;
- talk_sound_a = atoi(value);
-
- i = 0;
- memset(value, 0, 32);
- c = *buffer++;
- while (c != code) {
- value[i] = c;
- c = *buffer++;
- i++;
- }
- value[i] = 0;
- talk_sound_b = atoi(value);
-
- _sound->startHETalkSound(talk_sound_a);
- break;
- case 104:
- _haveMsg = 0;
- _keepText = true;
- break;
- case 110:
- goto newLine;
- case 116:
- i = 0;
- memset(value, 0, 32);
- c = *buffer++;
- while (c != code) {
- value[i] = c;
- c = *buffer++;
- i++;
- }
- value[i] = 0;
- talk_sound_a = atoi(value);
- talk_sound_b = 0;
-
- _sound->startHETalkSound(talk_sound_a);
- break;
- case 119:
- if (_haveMsg != 0xFE)
- _haveMsg = 0xFF;
- _keepText = false;
- break;
- default:
- error("CHARSET_1: invalid code %d", c);
- }
- } else if (c == 0xFE || c == 0xFF) {
- // WORKAROUND to avoid korean code 0xfe treated as charset message code.
- if (c == 0xFE && checkKSCode(*(buffer + 1), c) && _useCJKMode) {
- goto loc_avoid_ks_fe;
- }
- c = *buffer++;
- switch (c) {
- case 1:
- goto newLine;
- case 2:
- _haveMsg = 0;
- _keepText = true;
- break;
- case 3:
- if (_haveMsg != 0xFE)
- _haveMsg = 0xFF;
- _keepText = false;
- 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++;
- frme |= *buffer++ << 8;
- 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 (_heversion >= 60) {
- _sound->startHETalkSound(talk_sound_a);
- } else {
- _sound->talkSound(talk_sound_a, talk_sound_b, 2);
- }
-
- // Set flag that speech variant exist of this msg.
- // This is actually a hack added by ScummVM; the original did
- // subtitle hiding in some other way. I am not sure exactly
- // how, though.
- // FIXME: This is actually a rather ugly hack, and we should consider
- // replacing it with something better; problem is that _haveMsg is saved,
- // so we need to cope with old save games if we ever change this.
- // And BTW Fingolfin was responsible for this silly bad hack. Stupid me! :-).
- if (_haveMsg == 0xFF)
- _haveMsg = 0xFE;
- break;
- case 12:
- int color;
- color = *buffer++;
- color |= *buffer++ << 8;
- if (color == 0xFF)
- _charset->setColor(_charsetColor);
- else
- _charset->setColor(color);
- break;
- case 13:
- debug(0, "CHARSET_1: Unknown opcode 13 %d", READ_LE_UINT16(buffer));
- buffer += 2;
- break;
- case 14: {
- int oldy = _charset->getFontHeight();
-
- _charset->setCurID(*buffer++);
- buffer += 2;
- for (i = 0; i < 4; i++)
- _charsetColorMap[i] = _charsetData[_charset->getCurID()][i];
- _charset->_nextTop -= _charset->getFontHeight() - oldy;
- break;
- }
- default:
- error("CHARSET_1: invalid code %d", c);
+ _charset->_left = _charset->_nextLeft;
+ _charset->_top = _charset->_nextTop;
+ if (_version >= 7) {
+#ifndef DISABLE_SCUMM_7_8
+ if (subtitleLine == subtitleBuffer) {
+ subtitlePos.x = _charset->_left;
+ subtitlePos.y = _charset->_top;
}
- } else {
-loc_avoid_ks_fe:
- _charset->_left = _charset->_nextLeft;
- _charset->_top = _charset->_nextTop;
- if (c & 0x80 && _useCJKMode)
- if (_language == Common::JA_JPN && !checkSJISCode(c)) {
- c = 0x20; //not in S-JIS
- } else {
- c += *buffer++ * 256; //LE
- if (_gameId == GID_CMI) { //HACK: This fixes korean text position in COMI (off by 6 pixel)
- cmi_pos_hack = true;
- _charset->_top += 6;
- }
- }
+ *subtitleLine++ = c;
+ *subtitleLine = '\0';
+#endif
+ } else {
if (_version <= 3) {
_charset->printChar(c);
} else {
if (_features & GF_HE_NOSUBTITLES) {
// HE games which use sprites for subtitles
- } else if ((_imuseDigital && _sound->isSoundRunning(kTalkSoundID)) && (!ConfMan.getBool("subtitles") || VAR(VAR_VOICE_MODE) == 0)) {
- // Special case for games using imuse digital.for sound
} else if (_heversion >= 60 && !ConfMan.getBool("subtitles") && _sound->isSoundRunning(1)) {
// Special case for HE games
} else if ((_gameId == GID_LOOM256) && !ConfMan.getBool("subtitles") && (_sound->pollCD())) {
// Special case for loomcd, since it only uses CD audio.for sound
- } else if (!ConfMan.getBool("subtitles") && (_haveMsg == 0xFE || _mixer->isSoundHandleActive(_sound->_talkChannelHandle))) {
+ } 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);
}
}
- if (cmi_pos_hack) {
- cmi_pos_hack = false;
- _charset->_top -= 6;
- }
-
_charset->_nextLeft = _charset->_left;
_charset->_nextTop = _charset->_top;
- if (_version <= 2) {
- _talkDelay += _defaultTalkDelay;
- VAR(VAR_CHARCOUNT)++;
- } else
- _talkDelay += (int)VAR(VAR_CHARINC);
-
- // Handle line overflow for V3
- if (_version == 3 && _charset->_nextLeft > _screenWidth) {
- _charset->_nextLeft = _screenWidth;
- }
- // Handle line breaks for V1-V2
- if (_version <= 2 && _charset->_nextLeft > _screenWidth) {
- goto newLine;
- }
}
- } while (c != 2 && c != 3);
- _charsetBufPos = buffer - _charsetBuffer;
+ if (_version <= 2) {
+ _talkDelay += _defaultTalkDelay;
+ VAR(VAR_CHARCOUNT)++;
+ } else {
+ _talkDelay += (int)VAR(VAR_CHARINC);
+ }
+ // Handle line overflow for V3
+ if (_version == 3 && _charset->_nextLeft > _screenWidth) {
+ _charset->_nextLeft = _screenWidth;
+ }
+ // Handle line breaks for V1-V2
+ if (_version <= 2 && _charset->_nextLeft > _screenWidth) {
+ goto newLine;
+ }
+ }
- // TODO Verify this is correct spot
- if (_version == 8)
- VAR(VAR_HAVE_MSG) = (_string[0].no_talk_anim) ? 2 : 1;
+#ifndef DISABLE_SCUMM_7_8
+ if (_version >= 7 && subtitleLine != subtitleBuffer) {
+ ((ScummEngine_v7 *)this)->addSubtitleToQueue(subtitleBuffer, subtitlePos, _charsetColor, _charset->getCurID());
+ }
+#endif
}
void ScummEngine::drawString(int a, const byte *msg) {
@@ -859,7 +915,7 @@ void ScummEngine_v6::removeBlastTexts() {
}
#ifndef DISABLE_SCUMM_7_8
-int indexCompare(const void *p1, const void *p2) {
+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;