mirror of
https://github.com/libretro/scummvm.git
synced 2025-04-12 11:43:00 +00:00
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:
parent
5e75092dec
commit
c84d1ada32
@ -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) {
|
||||
|
@ -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();
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
468
scumm/string.cpp
468
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;
|
||||
char value[32];
|
||||
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);
|
||||
}
|
||||
|
||||
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)
|
||||
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;
|
||||
if (_charset->_center) {
|
||||
_charset->_nextLeft -= _charset->getStringWidth(0, buffer) / 2;
|
||||
#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, _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);
|
||||
_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 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->_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;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user