Index: scumm/actor.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/scumm/actor.cpp,v
retrieving revision 1.389
diff -u -r1.389 actor.cpp
--- scumm/actor.cpp	31 Oct 2005 19:48:48 -0000	1.389
+++ scumm/actor.cpp	1 Nov 2005 02:48:01 -0000
@@ -1360,10 +1360,13 @@
 	}
 	_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 @@
 	VAR(VAR_HAVE_MSG) = 0xFF;
 	if (VAR_CHARCOUNT != 0xFF)
 		VAR(VAR_CHARCOUNT) = 0;
+	_haveActorSpeechMsg = true;
 	CHARSET_1();
 }
 
@@ -1449,6 +1453,33 @@
 	}
 }
 
+#ifndef DISABLE_SCUMM_7_8
+void ScummEngine_v7::stopTalk() {
+	_sound->stopTalkSound();
+
+	_haveMsg = 0;
+	_talkDelay = 0;
+
+	int act = getTalkingActor();
+	if (act && act < 0x80) {
+		Actor *a = derefActor(act, "stopTalk");
+		if (!_string[0].no_talk_anim) {
+			a->runActorTalkScript(a->_talkStopFrame);
+			_useTalkAnims = false;
+		}
+		if (_version == 7) {
+			setTalkingActor(0xFF);
+		}
+	}
+	_keepText = false;
+	clearSubtitleQueue();
+	if (_version == 8) {
+		setTalkingActor(0);
+		VAR(VAR_HAVE_MSG) = 0;
+	}
+}
+#endif
+
 void ScummEngine::stopTalk() {
 	int act;
 
@@ -1460,19 +1491,16 @@
 	act = getTalkingActor();
 	if (act && act < 0x80) {
 		Actor *a = derefActor(act, "stopTalk");
-		if ((_version >= 7 && !_string[0].no_talk_anim) ||
-			(_version <= 6 && a->isInCurrentRoom() && _useTalkAnims)) {
+		if (a->isInCurrentRoom() && _useTalkAnims) {
 			a->runActorTalkScript(a->_talkStopFrame);
 			_useTalkAnims = false;
 		}
-		if (_version <= 7 && _heversion == 0)
+		if (_heversion == 0)
 			setTalkingActor(0xFF);
 		a->_heTalking = false;
 	}
-	if (_version == 8 || _heversion >= 60)
+	if (_heversion >= 60)
 		setTalkingActor(0);
-	if (_version == 8)
-		VAR(VAR_HAVE_MSG) = 0;
 	_keepText = false;
 	_charset->restoreCharsetBg();
 }
Index: scumm/intern.h
===================================================================
RCS file: /cvsroot/scummvm/scummvm/scumm/intern.h,v
retrieving revision 2.538
diff -u -r2.538 intern.h
--- scumm/intern.h	27 Oct 2005 06:51:41 -0000	2.538
+++ scumm/intern.h	1 Nov 2005 02:48:03 -0000
@@ -1338,6 +1338,18 @@
 	int _languageIndexSize;
 	char _lastStringTag[12+1];
 
+	struct SubtitleText {
+		byte text[256];
+		byte charset;
+		byte color;
+		int16 xpos, ypos;
+		bool actorSpeechMsg;
+	};
+
+	int _subtitleQueuePos;
+	SubtitleText _subtitleQueue[20];
+
+
 protected:
 	virtual void setupScummVars();
 	virtual void initScummVars();
@@ -1358,11 +1370,17 @@
 	virtual int getObjectIdFromOBIM(const byte *obim);
 
 	virtual void actorTalk(const byte *msg);
+	virtual void stopTalk();
 	virtual void translateText(const byte *text, byte *trans_buff);
 	virtual void loadLanguageBundle();
 	void playSpeech(const byte *ptr);
 
 	virtual void drawVerb(int verb, int mode);
+
+	virtual void CHARSET_1();
+	void addSubtitleToQueue(const byte *text, int x, int y, byte color, byte charset);
+	void processSubtitleQueue();
+	void clearSubtitleQueue();
 };
 
 class ScummEngine_v8 : public ScummEngine_v7 {
Index: scumm/saveload.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/scumm/saveload.cpp,v
retrieving revision 1.253
diff -u -r1.253 saveload.cpp
--- scumm/saveload.cpp	1 Nov 2005 02:43:54 -0000	1.253
+++ scumm/saveload.cpp	1 Nov 2005 02:48:06 -0000
@@ -730,6 +730,7 @@
 		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)),
@@ -951,6 +952,13 @@
 		updateCursor();
 		_system->warpMouse(_mouse.x, _mouse.y);
 	}
+	
+	// Before V61, we reused the _haveMsg flag to handle "alternative" speech sound
+	// files (see charset code 10). Behave like the original, rather.
+	if (s->isLoading() && s->getVersion() < VER(61)) {
+		_haveActorSpeechMsg = (_haveMsg != 0xFE);
+		_haveMsg = 0xFF;
+	}
 
 	//
 	// Save/load actors
@@ -1189,9 +1197,26 @@
 #ifndef DISABLE_SCUMM_7_8
 void ScummEngine_v7::saveOrLoad(Serializer *s) {
 	ScummEngine::saveOrLoad(s);
+	
+	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()
+	};
 
-	assert(_imuseDigital);
 	_imuseDigital->saveOrLoad(s);
+
+	s->saveLoadArrayOf(_subtitleQueue, ARRAYSIZE(_subtitleQueue), sizeof(_subtitleQueue[0]), subtitleQueueEntries);
+	s->saveLoadEntries(this, V7Entries);
 }
 #endif
 
Index: scumm/saveload.h
===================================================================
RCS file: /cvsroot/scummvm/scummvm/scumm/saveload.h,v
retrieving revision 1.71
diff -u -r1.71 saveload.h
--- scumm/saveload.h	1 Nov 2005 02:43:54 -0000	1.71
+++ scumm/saveload.h	1 Nov 2005 02:48:07 -0000
@@ -45,7 +45,7 @@
  * 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
Index: scumm/scumm.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/scumm/scumm.cpp,v
retrieving revision 1.621
diff -u -r1.621 scumm.cpp
--- scumm/scumm.cpp	28 Oct 2005 18:55:56 -0000	1.621
+++ scumm/scumm.cpp	1 Nov 2005 02:48:15 -0000
@@ -1124,6 +1124,7 @@
 	_palDirtyMin = 0;
 	_palDirtyMax = 0;
 	_haveMsg = 0;
+	_haveActorSpeechMsg = false;
 	_useTalkAnims = false;
 	_defaultTalkDelay = 0;
 	_midiDriver = MD_NULL;
@@ -1581,6 +1582,7 @@
 	_existLanguageFile = false;
 	_languageBuffer = NULL;
 	_languageIndex = NULL;
+	clearSubtitleQueue();
 }
 
 ScummEngine_v7::~ScummEngine_v7() {
@@ -1935,6 +1937,7 @@
 
 	_charsetBufPos = 0;
 	_haveMsg = 0;
+	_haveActorSpeechMsg = false;
 
 	_varwatch = -1;
 	_screenStartStrip = 0;
@@ -2292,7 +2295,7 @@
 		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
Index: scumm/scumm.h
===================================================================
RCS file: /cvsroot/scummvm/scummvm/scumm/scumm.h,v
retrieving revision 1.654
diff -u -r1.654 scumm.h
--- scumm/scumm.h	1 Nov 2005 02:43:54 -0000	1.654
+++ scumm/scumm.h	1 Nov 2005 02:48:22 -0000
@@ -877,7 +877,7 @@
 	int _NES_talkColor;
 
 	virtual void actorTalk(const byte *msg);
-	void stopTalk();
+	virtual void stopTalk();
 	int getTalkingActor();		// Wrapper around VAR_TALK_ACTOR for V1 Maniac
 	void setTalkingActor(int variable);
 
@@ -1093,6 +1093,7 @@
 	byte *_palManipIntermediatePal;
 
 	byte _haveMsg;
+	bool _haveActorSpeechMsg;
 	bool _useTalkAnims;
 	uint16 _defaultTalkDelay;
 	int _tempMusic;
@@ -1161,7 +1162,7 @@
 
 	void printString(int m, const byte *msg);
 
-	void CHARSET_1();
+	virtual void CHARSET_1();
 	void drawString(int a, const byte *msg);
 	void debugMessage(const byte *msg);
 	void showMessageDialog(const byte *msg);
Index: scumm/string.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/scumm/string.cpp,v
retrieving revision 1.306
diff -u -r1.306 string.cpp
--- scumm/string.cpp	18 Oct 2005 01:30:21 -0000	1.306
+++ scumm/string.cpp	1 Nov 2005 02:48:23 -0000
@@ -105,8 +105,6 @@
 	int code = (_heversion >= 80) ? 127 : 64;
 	char value[32];
 
-	bool cmi_pos_hack = false;
-
 	if (!_haveMsg)
 		return;
 
@@ -172,7 +170,7 @@
 	if (_talkDelay)
 		return;
 
-	if ((_version <= 7 && _haveMsg == 1) || (_version == 8 && VAR(VAR_HAVE_MSG))) {
+	if (_haveMsg == 1) {
 		if ((_sound->_sfxMode & 2) == 0)
 			stopTalk();
 		return;
@@ -183,11 +181,7 @@
 		_useTalkAnims = true;
 	}
 
-	// Always set to 60
-	if (_version <= 6)
-		_talkDelay = 60;
-	else
-		_talkDelay = VAR(VAR_DEFAULT_TALK_DELAY);
+	_talkDelay = 60;
 
 	if (!_keepText) {
 		_charset->restoreCharsetBg();
@@ -223,13 +217,6 @@
 			break;
 		}
 
-		// FIXME: This is a workaround for bug #864030: 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;
-
 		if (c == 13) {
 		newLine:;
 			_charset->_nextLeft = _string[0].xpos;
@@ -300,18 +287,13 @@
 				_sound->startHETalkSound(talk_sound_a);
 				break;
 			case 119:
-				if (_haveMsg != 0xFE)
-					_haveMsg = 0xFF;
+				_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:
@@ -321,8 +303,7 @@
 				_keepText = true;
 				break;
 			case 3:
-				if (_haveMsg != 0xFE)
-					_haveMsg = 0xFF;
+				_haveMsg = 0xFF;
 				_keepText = false;
 				break;
 			case 8:
@@ -333,8 +314,8 @@
 				// sentences.
 				break;
 			case 9:
-				frme = *buffer++;
-				frme |= *buffer++ << 8;
+				frme = buffer[0] | (buffer[1] << 8);
+				buffer += 2;
 				if (a)
 					a->startAnimActor(frme);
 				break;
@@ -343,28 +324,17 @@
 				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;
+				_haveActorSpeechMsg = false;
 				break;
 			case 12:
 				int color;
-				color = *buffer++;
-				color |= *buffer++ << 8;
+				color = buffer[0] | (buffer[1] << 8);
+				buffer += 2;
 				if (color == 0xFF)
 					_charset->setColor(_charsetColor);
 				else
@@ -388,42 +358,24 @@
 				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;
-					}
-				}
 			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) {
@@ -444,10 +396,6 @@
 	} while (c != 2 && c != 3);
 
 	_charsetBufPos = buffer - _charsetBuffer;
-
-	// TODO Verify this is correct spot
-	if (_version == 8)
-		VAR(VAR_HAVE_MSG) = (_string[0].no_talk_anim) ? 2 : 1;
 }
 
 void ScummEngine::drawString(int a, const byte *msg) {
@@ -859,7 +807,216 @@
 }
 
 #ifndef DISABLE_SCUMM_7_8
-int indexCompare(const void *p1, const void *p2) {
+
+void ScummEngine_v7::addSubtitleToQueue(const byte *text, int x, int y, 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 = x;
+		st->ypos = y;
+		st->color = color;
+		st->charset = charset;
+		st->actorSpeechMsg = _haveActorSpeechMsg;
+		++_subtitleQueuePos;
+	}
+}
+
+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::clearSubtitleQueue() {
+	memset(_subtitleQueue, 0, sizeof(_subtitleQueue));
+	_subtitleQueuePos = 0;
+}
+
+void ScummEngine_v7::CHARSET_1() {	
+	uint32 talk_sound_a = 0;
+	uint32 talk_sound_b = 0;
+	int t, c, frme;
+	Actor *a;
+	byte *buffer;
+	byte subtitleBuffer[200];
+	byte *subtitleLine = subtitleBuffer;
+	Common::Point subtitlePos;
+
+	processSubtitleQueue();
+
+	if (!_haveMsg)
+		return;
+
+	a = NULL;
+	if (getTalkingActor() != 0xFF)
+		a = derefActorSafe(getTalkingActor(), "CHARSET_1");
+
+	if (a && _string[0].overhead != 0) {
+		int s;
+
+		_string[0].xpos = a->_pos.x - virtscr[0].xstart;
+		_string[0].ypos = a->_pos.y - a->getElevation() - _screenTop;
+
+		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);
+
+	memcpy(_charsetColorMap, _charsetData[_charset->getCurID()], 4);
+
+	if (_talkDelay)
+		return;
+
+	if ((_version == 7 && _haveMsg != 1) || (_version == 8 && VAR(VAR_HAVE_MSG))) {
+		if ((_sound->_sfxMode & 2) == 0)
+			stopTalk();
+		return;
+	}
+
+	if (a && !_string[0].no_talk_anim) {
+		a->runActorTalkScript(a->_talkStartFrame);
+		_useTalkAnims = true;
+	}
+
+	_talkDelay = VAR(VAR_DEFAULT_TALK_DELAY);
+
+	if (!_keepText) {
+		clearSubtitleQueue();
+		_charset->_nextLeft = _string[0].xpos;
+		_charset->_nextTop = _string[0].ypos;
+	}
+
+	t = _charset->_right - _string[0].xpos - 1;
+	if (_charset->_center) {
+		if (t > _charset->_nextLeft)
+			t = _charset->_nextLeft;
+		t *= 2;
+	}
+
+	buffer = _charsetBuffer + _charsetBufPos;
+
+	_charset->addLinebreaks(0, buffer, 0, t);
+
+	if (_charset->_center) {
+		_charset->_nextLeft -= _charset->getStringWidth(0, buffer) / 2;
+		if (_charset->_nextLeft < 0)
+			_charset->_nextLeft = 0;
+	}
+
+	do {
+		c = *buffer++;
+		if (c == 0) {
+			_haveMsg = 2;
+			_keepText = false;
+			break;
+		}
+
+		// FIXME: This is a workaround for bug #864030: 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;
+
+		if (c == 13) {
+newLine:
+			_charset->_nextLeft = _string[0].xpos;
+			if (subtitleLine != subtitleBuffer) {
+				addSubtitleToQueue(subtitleBuffer, subtitlePos.x, subtitlePos.y, _charsetColor, _charset->getCurID());
+				subtitleLine = subtitleBuffer;
+			}
+			if (_charset->_center) {
+				_charset->_nextLeft -= _charset->getStringWidth(0, buffer) / 2;
+			}
+			_charset->_nextTop += _charset->getFontHeight();
+			continue;
+		}
+		
+		if (c == 0xFF) {
+			c = *buffer++;
+			switch (c) {
+			case 1:
+				goto newLine;
+			case 2:
+				_haveMsg = 0;
+				_keepText = true;
+				break;
+			case 3:
+				_haveMsg = 1;
+				_keepText = false;
+				break;
+			case 9:
+				frme = buffer[0] | (buffer[1] << 8);
+				buffer += 2;
+				if (a)
+					a->startAnimActor(frme);
+				break;
+			case 10:
+				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;
+				_sound->talkSound(talk_sound_a, talk_sound_b, 2);
+				_haveActorSpeechMsg = false;
+				break;
+			default:
+				error("CHARSET_1: invalid code %d", c);
+			}
+		} else {
+			_charset->_left = _charset->_nextLeft;
+			_charset->_top = _charset->_nextTop;
+			if (subtitleLine == subtitleBuffer) {
+				subtitlePos.x = _charset->_left;
+				subtitlePos.y = _charset->_top;
+			}
+			*subtitleLine++ = c;
+			*subtitleLine = '\0';
+			_talkDelay += (int)VAR(VAR_CHARINC);
+		}
+	} while (c != 2 && c != 3);
+
+	_charsetBufPos = buffer - _charsetBuffer;
+	if (subtitleLine != subtitleBuffer) {
+		addSubtitleToQueue(subtitleBuffer, subtitlePos.x, subtitlePos.y, _charsetColor, _charset->getCurID());
+	}
+}
+
+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;
 
