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
This commit is contained in:
Gregory Montoir 2005-11-02 21:47:44 +00:00
parent 5e75092dec
commit c84d1ada32
7 changed files with 328 additions and 216 deletions

View File

@ -1360,10 +1360,13 @@ void ScummEngine_v7::actorTalk(const byte *msg) {
} }
_charsetBufPos = 0; _charsetBufPos = 0;
_talkDelay = 0; _talkDelay = 0;
_haveMsg = 0xFF; _haveMsg = 1;
if (_version == 7) if (_version == 7)
VAR(VAR_HAVE_MSG) = 0xFF; VAR(VAR_HAVE_MSG) = 0xFF;
_haveActorSpeechMsg = true;
CHARSET_1(); CHARSET_1();
if (_version == 8)
VAR(VAR_HAVE_MSG) = (_string[0].no_talk_anim) ? 2 : 1;
} }
#endif #endif
@ -1428,6 +1431,7 @@ void ScummEngine::actorTalk(const byte *msg) {
VAR(VAR_HAVE_MSG) = 0xFF; VAR(VAR_HAVE_MSG) = 0xFF;
if (VAR_CHARCOUNT != 0xFF) if (VAR_CHARCOUNT != 0xFF)
VAR(VAR_CHARCOUNT) = 0; VAR(VAR_CHARCOUNT) = 0;
_haveActorSpeechMsg = true;
CHARSET_1(); CHARSET_1();
} }
@ -1474,8 +1478,14 @@ void ScummEngine::stopTalk() {
if (_version == 8) if (_version == 8)
VAR(VAR_HAVE_MSG) = 0; VAR(VAR_HAVE_MSG) = 0;
_keepText = false; _keepText = false;
if (_version >= 7) {
#ifndef DISABLE_SCUMM_7_8
((ScummEngine_v7 *)this)->clearSubtitleQueue();
#endif
} else {
_charset->restoreCharsetBg(); _charset->restoreCharsetBg();
} }
}
void Actor::setActorCostume(int c) { void Actor::setActorCostume(int c) {
int i; int i;

View File

@ -516,6 +516,13 @@ protected:
int _smushFrameRate; int _smushFrameRate;
struct TextObject {
int16 xpos, ypos;
byte color;
byte charset;
byte text[256];
};
/** BlastObjects to draw */ /** BlastObjects to draw */
struct BlastObject { struct BlastObject {
uint16 number; uint16 number;
@ -528,13 +535,9 @@ protected:
int _blastObjectQueuePos; int _blastObjectQueuePos;
BlastObject _blastObjectQueue[128]; BlastObject _blastObjectQueue[128];
struct BlastText { struct BlastText : TextObject {
int16 xpos, ypos;
Common::Rect rect; Common::Rect rect;
byte color;
byte charset;
bool center; bool center;
byte text[256];
}; };
int _blastTextQueuePos; int _blastTextQueuePos;
@ -1004,6 +1007,8 @@ protected:
int findObject(int x, int y, int num, int *args); int findObject(int x, int y, int num, int *args);
int getSoundResourceSize(int id); int getSoundResourceSize(int id);
virtual bool handleNextCharsetCode(Actor *a, int *c);
/* HE version 72 script opcodes */ /* HE version 72 script opcodes */
void o72_pushDWord(); void o72_pushDWord();
void o72_getScriptString(); void o72_getScriptString();
@ -1338,6 +1343,17 @@ public:
int _languageIndexSize; int _languageIndexSize;
char _lastStringTag[12+1]; 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: protected:
virtual void setupScummVars(); virtual void setupScummVars();
virtual void initScummVars(); virtual void initScummVars();

View File

@ -730,6 +730,7 @@ void ScummEngine::saveOrLoad(Serializer *s) {
MKLINE(ScummEngine, _charsetBufPos, sleInt16, VER(10)), MKLINE(ScummEngine, _charsetBufPos, sleInt16, VER(10)),
MKLINE(ScummEngine, _haveMsg, sleByte, VER(8)), MKLINE(ScummEngine, _haveMsg, sleByte, VER(8)),
MKLINE(ScummEngine, _haveActorSpeechMsg, sleByte, VER(61)),
MKLINE(ScummEngine, _useTalkAnims, sleByte, VER(8)), MKLINE(ScummEngine, _useTalkAnims, sleByte, VER(8)),
MKLINE(ScummEngine, _talkDelay, sleInt16, VER(8)), MKLINE(ScummEngine, _talkDelay, sleInt16, VER(8)),
@ -952,6 +953,13 @@ void ScummEngine::saveOrLoad(Serializer *s) {
_system->warpMouse(_mouse.x, _mouse.y); _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 // Save/load actors
// //
@ -1190,8 +1198,25 @@ void ScummEngine_v5::saveOrLoad(Serializer *s) {
void ScummEngine_v7::saveOrLoad(Serializer *s) { void ScummEngine_v7::saveOrLoad(Serializer *s) {
ScummEngine::saveOrLoad(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); _imuseDigital->saveOrLoad(s);
s->saveLoadArrayOf(_subtitleQueue, ARRAYSIZE(_subtitleQueue), sizeof(_subtitleQueue[0]), subtitleQueueEntries);
s->saveLoadEntries(this, V7Entries);
} }
#endif #endif

View File

@ -45,7 +45,7 @@ namespace Scumm {
* only saves/loads those which are valid for the version of the savegame * only saves/loads those which are valid for the version of the savegame
* which is being loaded/saved currently. * 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 * An auxillary macro, used to specify savegame versions. We use this instead

View File

@ -1128,6 +1128,7 @@ ScummEngine::ScummEngine(GameDetector *detector, OSystem *syst, const ScummGameS
_palDirtyMin = 0; _palDirtyMin = 0;
_palDirtyMax = 0; _palDirtyMax = 0;
_haveMsg = 0; _haveMsg = 0;
_haveActorSpeechMsg = false;
_useTalkAnims = false; _useTalkAnims = false;
_defaultTalkDelay = 0; _defaultTalkDelay = 0;
_midiDriver = MD_NULL; _midiDriver = MD_NULL;
@ -1585,6 +1586,7 @@ ScummEngine_v7::ScummEngine_v7(GameDetector *detector, OSystem *syst, const Scum
_existLanguageFile = false; _existLanguageFile = false;
_languageBuffer = NULL; _languageBuffer = NULL;
_languageIndex = NULL; _languageIndex = NULL;
clearSubtitleQueue();
} }
ScummEngine_v7::~ScummEngine_v7() { ScummEngine_v7::~ScummEngine_v7() {
@ -1939,6 +1941,7 @@ void ScummEngine::scummInit() {
_charsetBufPos = 0; _charsetBufPos = 0;
_haveMsg = 0; _haveMsg = 0;
_haveActorSpeechMsg = false;
_varwatch = -1; _varwatch = -1;
_screenStartStrip = 0; _screenStartStrip = 0;
@ -2296,7 +2299,7 @@ int ScummEngine::scummLoop(int delta) {
VAR(VAR_CAMERA_POS_X) = camera._cur.x; VAR(VAR_CAMERA_POS_X) = camera._cur.x;
} }
if (_version <= 7) if (_version <= 7)
VAR(VAR_HAVE_MSG) = (_haveMsg == 0xFE) ? 0xFF : _haveMsg; VAR(VAR_HAVE_MSG) = _haveMsg;
if (_platform == Common::kPlatformC64 && _gameId == GID_MANIAC) { if (_platform == Common::kPlatformC64 && _gameId == GID_MANIAC) {
// TODO // TODO

View File

@ -1093,6 +1093,7 @@ protected:
byte *_palManipIntermediatePal; byte *_palManipIntermediatePal;
byte _haveMsg; byte _haveMsg;
bool _haveActorSpeechMsg;
bool _useTalkAnims; bool _useTalkAnims;
uint16 _defaultTalkDelay; uint16 _defaultTalkDelay;
int _tempMusic; int _tempMusic;
@ -1161,6 +1162,7 @@ protected:
void printString(int m, const byte *msg); void printString(int m, const byte *msg);
virtual bool handleNextCharsetCode(Actor *a, int *c);
void CHARSET_1(); void CHARSET_1();
void drawString(int a, const byte *msg); void drawString(int a, const byte *msg);
void debugMessage(const byte *msg); void debugMessage(const byte *msg);

View File

@ -95,17 +95,212 @@ void ScummEngine::showMessageDialog(const byte *msg) {
VAR(VAR_KEYPRESS) = runDialog(dialog); 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_a = 0;
uint32 talk_sound_b = 0; uint32 talk_sound_b = 0;
int i, t, c; int i, color, frme, c, oldy;
int frme; bool endLoop = false;
Actor *a; byte *buffer = _charsetBuffer + _charsetBufPos;
byte *buffer; while (!endLoop) {
int code = (_heversion >= 80) ? 127 : 64; c = *buffer++;
char value[32]; 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);
}
bool cmi_pos_hack = false; #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
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) if (!_haveMsg)
return; return;
@ -166,13 +361,12 @@ void ScummEngine::CHARSET_1() {
_charset->setCurID(_string[0].charset); _charset->setCurID(_string[0].charset);
if (_version >= 5) if (_version >= 5)
for (i = 0; i < 4; i++) memcpy(_charsetColorMap, _charsetData[_charset->getCurID()], 4);
_charsetColorMap[i] = _charsetData[_charset->getCurID()][i];
if (_talkDelay) if (_talkDelay)
return; 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) if ((_sound->_sfxMode & 2) == 0)
stopTalk(); stopTalk();
return; return;
@ -183,15 +377,19 @@ void ScummEngine::CHARSET_1() {
_useTalkAnims = true; _useTalkAnims = true;
} }
// Always set to 60 _talkDelay = (VAR_DEFAULT_TALK_DELAY != 0xFF) ? VAR(VAR_DEFAULT_TALK_DELAY) : 60;
if (_version <= 6)
_talkDelay = 60;
else
_talkDelay = VAR(VAR_DEFAULT_TALK_DELAY);
if (!_keepText) { if (!_keepText) {
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(); _charset->restoreCharsetBg();
} }
}
t = _charset->_right - _string[0].xpos - 1; t = _charset->_right - _string[0].xpos - 1;
if (_charset->_center) { if (_charset->_center) {
@ -200,25 +398,21 @@ void ScummEngine::CHARSET_1() {
t *= 2; t *= 2;
} }
buffer = _charsetBuffer + _charsetBufPos;
if (_version > 3) if (_version > 3)
_charset->addLinebreaks(0, buffer, 0, t); _charset->addLinebreaks(0, _charsetBuffer + _charsetBufPos, 0, t);
if (_charset->_center) { if (_charset->_center) {
_charset->_nextLeft -= _charset->getStringWidth(0, buffer) / 2; _charset->_nextLeft -= _charset->getStringWidth(0, _charsetBuffer + _charsetBufPos) / 2;
if (_charset->_nextLeft < 0) if (_charset->_nextLeft < 0)
_charset->_nextLeft = 0; _charset->_nextLeft = 0;
} }
_charset->_disableOffsX = _charset->_firstChar = !_keepText; _charset->_disableOffsX = _charset->_firstChar = !_keepText;
do { while (handleNextCharsetCode(a, &c)) {
c = *buffer++;
if (c == 0) { if (c == 0) {
// End of text reached, set _haveMsg to 1 so that the text will be // End of text reached, set _haveMsg accordingly
// removed next time CHARSET_1 is called. _haveMsg = (_version >= 7) ? 2 : 1;
_haveMsg = 1;
_keepText = false; _keepText = false;
break; break;
} }
@ -233,9 +427,16 @@ void ScummEngine::CHARSET_1() {
if (c == 13) { if (c == 13) {
newLine:; newLine:;
_charset->_nextLeft = _string[0].xpos; _charset->_nextLeft = _string[0].xpos;
if (_charset->_center) { #ifndef DISABLE_SCUMM_7_8
_charset->_nextLeft -= _charset->getStringWidth(0, buffer) / 2; 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, _charsetBuffer + _charsetBufPos) / 2;
}
if (_platform == Common::kPlatformC64 && _gameId == GID_MANIAC) { if (_platform == Common::kPlatformC64 && _gameId == GID_MANIAC) {
break; break;
} else if (!(_platform == Common::kPlatformFMTowns) && _string[0].height) { } else if (!(_platform == Common::kPlatformFMTowns) && _string[0].height) {
@ -250,188 +451,44 @@ void ScummEngine::CHARSET_1() {
continue; 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);
}
} else {
loc_avoid_ks_fe:
_charset->_left = _charset->_nextLeft; _charset->_left = _charset->_nextLeft;
_charset->_top = _charset->_nextTop; _charset->_top = _charset->_nextTop;
if (c & 0x80 && _useCJKMode) if (_version >= 7) {
if (_language == Common::JA_JPN && !checkSJISCode(c)) { #ifndef DISABLE_SCUMM_7_8
c = 0x20; //not in S-JIS if (subtitleLine == subtitleBuffer) {
subtitlePos.x = _charset->_left;
subtitlePos.y = _charset->_top;
}
*subtitleLine++ = c;
*subtitleLine = '\0';
#endif
} else { } 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;
}
}
if (_version <= 3) { if (_version <= 3) {
_charset->printChar(c); _charset->printChar(c);
} else { } else {
if (_features & GF_HE_NOSUBTITLES) { if (_features & GF_HE_NOSUBTITLES) {
// HE games which use sprites for subtitles // 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)) { } else if (_heversion >= 60 && !ConfMan.getBool("subtitles") && _sound->isSoundRunning(1)) {
// Special case for HE games // Special case for HE games
} else if ((_gameId == GID_LOOM256) && !ConfMan.getBool("subtitles") && (_sound->pollCD())) { } else if ((_gameId == GID_LOOM256) && !ConfMan.getBool("subtitles") && (_sound->pollCD())) {
// Special case for loomcd, since it only uses CD audio.for sound // 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 // Subtitles are turned off, and there is a voice version
// of this message -> don't print it. // of this message -> don't print it.
} else { } else {
_charset->printChar(c); _charset->printChar(c);
} }
} }
if (cmi_pos_hack) {
cmi_pos_hack = false;
_charset->_top -= 6;
}
_charset->_nextLeft = _charset->_left; _charset->_nextLeft = _charset->_left;
_charset->_nextTop = _charset->_top; _charset->_nextTop = _charset->_top;
}
if (_version <= 2) { if (_version <= 2) {
_talkDelay += _defaultTalkDelay; _talkDelay += _defaultTalkDelay;
VAR(VAR_CHARCOUNT)++; VAR(VAR_CHARCOUNT)++;
} else } else {
_talkDelay += (int)VAR(VAR_CHARINC); _talkDelay += (int)VAR(VAR_CHARINC);
}
// Handle line overflow for V3 // Handle line overflow for V3
if (_version == 3 && _charset->_nextLeft > _screenWidth) { if (_version == 3 && _charset->_nextLeft > _screenWidth) {
_charset->_nextLeft = _screenWidth; _charset->_nextLeft = _screenWidth;
@ -441,13 +498,12 @@ loc_avoid_ks_fe:
goto newLine; goto newLine;
} }
} }
} while (c != 2 && c != 3);
_charsetBufPos = buffer - _charsetBuffer; #ifndef DISABLE_SCUMM_7_8
if (_version >= 7 && subtitleLine != subtitleBuffer) {
// TODO Verify this is correct spot ((ScummEngine_v7 *)this)->addSubtitleToQueue(subtitleBuffer, subtitlePos, _charsetColor, _charset->getCurID());
if (_version == 8) }
VAR(VAR_HAVE_MSG) = (_string[0].no_talk_anim) ? 2 : 1; #endif
} }
void ScummEngine::drawString(int a, const byte *msg) { void ScummEngine::drawString(int a, const byte *msg) {
@ -859,7 +915,7 @@ void ScummEngine_v6::removeBlastTexts() {
} }
#ifndef DISABLE_SCUMM_7_8 #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 *i1 = (const ScummEngine_v7::LangIndexNode *) p1;
const ScummEngine_v7::LangIndexNode *i2 = (const ScummEngine_v7::LangIndexNode *) p2; const ScummEngine_v7::LangIndexNode *i2 = (const ScummEngine_v7::LangIndexNode *) p2;