diff options
| author | Gregory Montoir | 2005-11-02 21:47:44 +0000 | 
|---|---|---|
| committer | Gregory Montoir | 2005-11-02 21:47:44 +0000 | 
| commit | c84d1ada32bb2093ee7a5d20a73b9c342eca4f11 (patch) | |
| tree | c076ef2e604e2ca87ff2f03edd3cd36cfbe55d14 | |
| parent | 5e75092decb10ee760d62e2b42272b70eda05e2e (diff) | |
| download | scummvm-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.cpp | 14 | ||||
| -rw-r--r-- | scumm/intern.h | 26 | ||||
| -rw-r--r-- | scumm/saveload.cpp | 27 | ||||
| -rw-r--r-- | scumm/saveload.h | 2 | ||||
| -rw-r--r-- | scumm/scumm.cpp | 5 | ||||
| -rw-r--r-- | scumm/scumm.h | 2 | ||||
| -rw-r--r-- | scumm/string.cpp | 464 | 
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; | 
