[Scummvm-cvs-logs] CVS: scummvm/scumm actor.cpp,1.229.2.9,1.229.2.10 camera.cpp,2.23,2.23.2.1 script_v2.cpp,2.230.2.4,2.230.2.5 script_v5.cpp,1.226.2.2,1.226.2.3 script_v6.cpp,1.293.2.15,1.293.2.16 script_v6he.cpp,2.15.2.6,2.15.2.7 script_v8.cpp,2.229.2.5,2.229.2.6 scumm.h,1.369.2.8,1.369.2.9 scummvm.cpp,2.577.2.23,2.577.2.24 string.cpp,1.193.2.5,1.193.2.6 verbs.cpp,1.93.2.1,1.93.2.2

Max Horn fingolfin at users.sourceforge.net
Sun Jul 18 15:17:04 CEST 2004


Update of /cvsroot/scummvm/scummvm/scumm
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv5370/scumm

Modified Files:
      Tag: branch-0-6-0
	actor.cpp camera.cpp script_v2.cpp script_v5.cpp script_v6.cpp 
	script_v6he.cpp script_v8.cpp scumm.h scummvm.cpp string.cpp 
	verbs.cpp 
Log Message:
Backported improved localization code (for The Dig & FT)

Index: actor.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/scumm/actor.cpp,v
retrieving revision 1.229.2.9
retrieving revision 1.229.2.10
diff -u -d -r1.229.2.9 -r1.229.2.10
--- actor.cpp	18 Jul 2004 04:43:21 -0000	1.229.2.9
+++ actor.cpp	18 Jul 2004 22:15:51 -0000	1.229.2.10
@@ -1155,12 +1155,14 @@
 	return 0;
 }
 
-void ScummEngine::actorTalk() {
+void ScummEngine::actorTalk(const byte *msg) {
 	Actor *a;
 
-	_msgPtrToAdd = _charsetBuffer;
-	_messagePtr = addMessageToStack(_messagePtr);
-	assert((int)(_msgPtrToAdd - _charsetBuffer) < (int)(sizeof(_charsetBuffer)));
+	_lastStringTag[0] = 0;
+	addMessageToStack(msg, _charsetBuffer, sizeof(_charsetBuffer));
+	
+	// Play associated speech, if any
+	playSpeech((byte *)_lastStringTag);
 
 	// FIXME: Workaround for bugs #770039 and #770049 
 	if (_gameId == GID_LOOM || _gameId == GID_LOOM256) {
@@ -1260,11 +1262,6 @@
 	_charset->restoreCharsetBg();
 }
 
-void ScummEngine::clearMsgQueue() {
-	_messagePtr = (const byte *)" ";
-	stopTalk();
-}
-
 void Actor::setActorCostume(int c) {
 	int i;
 

Index: camera.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/scumm/camera.cpp,v
retrieving revision 2.23
retrieving revision 2.23.2.1
diff -u -d -r2.23 -r2.23.2.1
--- camera.cpp	8 Jan 2004 21:21:40 -0000	2.23
+++ camera.cpp	18 Jul 2004 22:15:51 -0000	2.23.2.1
@@ -373,19 +373,6 @@
 	if (!(_features & GF_NEW_CAMERA)) {
 		int old;
 
-// Exactly why is this code needed for Monkey Island 1?
-// Seems to be the real cause of lock up at title screen
-// in Amiga and PC demo versions.
-/*
-		// MI1 compatibilty
-		if (act == 0) {
-			camera._mode = kNormalCameraMode;
-			camera._follows = 0;
-			camera._movingToActor = false;
-			return;
-		}
-*/
-
 		old = camera._follows;
 		setCameraFollows(derefActor(act, "actorFollowCamera"));
 		if (camera._follows != old)

Index: script_v2.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/scumm/script_v2.cpp,v
retrieving revision 2.230.2.4
retrieving revision 2.230.2.5
diff -u -d -r2.230.2.4 -r2.230.2.5
--- script_v2.cpp	13 Mar 2004 12:53:43 -0000	2.230.2.4
+++ script_v2.cpp	18 Jul 2004 22:15:51 -0000	2.230.2.5
@@ -428,8 +428,7 @@
 			_string[textSlot].color = v1_mm_actor_speech_color[_actorToPrintStrFor];
 	}
 
-	_messagePtr = buffer;
-	actorTalk();
+	actorTalk(buffer);
 }
 
 int ScummEngine_v2::readVar(uint var) {
@@ -438,7 +437,6 @@
 
 	checkRange(_numVariables - 1, 0, var, "Variable %d out of range(r)");
 	debug(6, "readvar(%d) = %d", var, _scummVars[var]);
-
 	return _scummVars[var];
 }
 
@@ -1056,15 +1054,13 @@
 		ptr++;
 	}
 
-	_messagePtr = (byte*)sentence;
-
 	sentenceline.top = virtscr[2].topline;
 	sentenceline.bottom = virtscr[2].topline + 8;
 	sentenceline.left = 0;
 	sentenceline.right = 319;
 	restoreBG(sentenceline);
 
-	drawString(2);
+	drawString(2, (byte*)sentence);
 }
 
 void ScummEngine_v2::o2_ifClassOfIs() {

Index: script_v5.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/scumm/script_v5.cpp,v
retrieving revision 1.226.2.2
retrieving revision 1.226.2.3
diff -u -d -r1.226.2.2 -r1.226.2.3
--- script_v5.cpp	11 Apr 2004 20:56:49 -0000	1.226.2.2
+++ script_v5.cpp	18 Jul 2004 22:15:51 -0000	1.226.2.3
@@ -1649,7 +1649,7 @@
 	a = derefActor(act, "o5_putActorInRoom");
 	
 	if (a->visible && _currentRoom != room && getTalkingActor() == a->number) {
-		clearMsgQueue();
+		stopTalk();
 	}
 	a->room = room;
 	if (!room)
@@ -2696,6 +2696,7 @@
 
 void ScummEngine_v5::decodeParseString() {
 	int textSlot;
+	const byte *msg;
 
 	switch (_actorToPrintStrFor) {
 	case 252:
@@ -2778,19 +2779,21 @@
 			}
 			break;
 		case 15:	// SO_TEXTSTRING
-			_messagePtr = _scriptPointer;
+			msg = _scriptPointer;
+			_scriptPointer += resStrLen(_scriptPointer) + 1;
+
 			switch (textSlot) {
 			case 0:
-				actorTalk();
+				actorTalk(msg);
 				break;
 			case 1:
-				drawString(1);
+				drawString(1, msg);
 				break;
 			case 2:
-				unkMessage1();
+				unkMessage1(msg);
 				break;
 			case 3:
-				unkMessage2();
+				unkMessage2(msg);
 				break;
 			}
 
@@ -2806,8 +2809,6 @@
 				_string[textSlot].t_ypos = _string[textSlot].ypos;
  				_string[textSlot].t_color = _string[textSlot].color;
 			}
-
-			_scriptPointer = _messagePtr;
 			return;
 		default:
 			warning("ScummEngine_v5::decodeParseString: Unhandled case %d", _opcode & 0xF);

Index: script_v6.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/scumm/script_v6.cpp,v
retrieving revision 1.293.2.15
retrieving revision 1.293.2.16
diff -u -d -r1.293.2.15 -r1.293.2.16
--- script_v6.cpp	17 Jul 2004 08:27:55 -0000	1.293.2.15
+++ script_v6.cpp	18 Jul 2004 22:15:52 -0000	1.293.2.16
@@ -1167,7 +1167,7 @@
 		room = a->room;
 	} else {
 		if (a->visible && _currentRoom != room && getTalkingActor() == a->number) {
-			clearMsgQueue();
+			stopTalk();
 		}
 		if (room != 0)
 			a->room = room;
@@ -2327,11 +2327,10 @@
 void ScummEngine_v6::o6_talkActor() {
 	_actorToPrintStrFor = pop();
 
-	_messagePtr = translateTextAndPlaySpeech(_scriptPointer);
-	_scriptPointer += resStrLen(_scriptPointer) + 1;
-
 	setStringVars(0);
-	actorTalk();
+	actorTalk(_scriptPointer);
+
+	_scriptPointer += resStrLen(_scriptPointer) + 1;
 }
 
 void ScummEngine_v6::o6_talkEgo() {
@@ -2515,33 +2514,11 @@
 			break;
 		case 16:
 		case 17:{
-			const byte *message;
-			byte buf_input[300], buf_output[300];
-			_messagePtr = getStringAddressVar(VAR_STRING2DRAW);
-			message = _msgPtrToAdd = buf_input;
-			addMessageToStack(_messagePtr);
-			if ((_gameId == GID_DIG) && !(_features & GF_DEMO)) {
-				byte buf_trans[300];
-				char *t_ptr = (char *)buf_input;
-				buf_output[0] = 0;
-				while (t_ptr != NULL) {
-					if (*t_ptr == '/') {
-						translateText((byte *)t_ptr, buf_trans);
-						// hack 
-						if (strstr((char *)buf_trans, "%___") != 0) {
-							strcat((char *)buf_output, " ");
-						} else {
-							strcat((char *)buf_output, (char *)buf_trans);
-						}
-					}
-					t_ptr = strchr((char *)t_ptr + 1, '/');
-					if (t_ptr == NULL)
-						break;
-					t_ptr = strchr((char *)t_ptr + 1, '/');
-				}
-				message = buf_output;
-			}
-			enqueueText(message, args[3], args[4], args[2], args[1], true);
+			byte buf_input[300];
+			const byte *message = getStringAddressVar(VAR_STRING2DRAW);
+
+			addMessageToStack(message, buf_input, sizeof(buf_input));
+			enqueueText(buf_input, args[3], args[4], args[2], args[1], true);
 			break;}
 		case 20:
 			// it's used for turn on/off 'RadioChatter' effect for voice in the dig, but i's not needed
@@ -3180,32 +3157,28 @@
 		_string[m].no_talk_anim = true;
 		break;
 	case 75:		// SO_TEXTSTRING
-		_messagePtr = translateTextAndPlaySpeech(_scriptPointer);
-		_scriptPointer += resStrLen(_scriptPointer)+ 1;
-
 		switch (m) {
 		case 0:
-			actorTalk();
+			actorTalk(_scriptPointer);
 			break;
 		case 1:
-			drawString(1);
+			drawString(1, _scriptPointer);
 			break;
 		case 2:
-			unkMessage1();
+			unkMessage1(_scriptPointer);
 			break;
 		case 3:
-			unkMessage2();
+			unkMessage2(_scriptPointer);
 			break;
 		}
-		return;
-	case 0xF9:
-		error("decodeParseString case 0xF9 stub");
-		return;
+		_scriptPointer += resStrLen(_scriptPointer) + 1;
+
+		break;
 	case 0xFE:
 		setStringVars(m);
 		if (n)
 			_actorToPrintStrFor = pop();
-		return;
+		break;
 	case 0xFF:
 		_string[m].t_xpos = _string[m].xpos;
 		_string[m].t_ypos = _string[m].ypos;
@@ -3215,7 +3188,7 @@
 		_string[m].t_right = _string[m].right;
 		_string[m].t_color = _string[m].color;
 		_string[m].t_charset = _string[m].charset;
-		return;
+		break;
 	default:
 		error("decodeParseString: default case 0x%x", b);
 	}

Index: script_v6he.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/scumm/script_v6he.cpp,v
retrieving revision 2.15.2.6
retrieving revision 2.15.2.7
diff -u -d -r2.15.2.6 -r2.15.2.7
--- script_v6he.cpp	15 Jul 2004 05:43:55 -0000	2.15.2.6
+++ script_v6he.cpp	18 Jul 2004 22:15:52 -0000	2.15.2.7
@@ -16,7 +16,7 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  *
- * $Header
+ * $Header$
  *
  */
 
@@ -1086,9 +1086,7 @@
 	int mode, len, slot, l, r;
 	byte filename[100];
 
-	_msgPtrToAdd = filename;
-	_messagePtr = _scriptPointer;
-	addMessageToStack(_messagePtr);
+	addMessageToStack(_scriptPointer, filename, sizeof(filename));
 
 	len = resStrLen(_scriptPointer);
 	_scriptPointer += len + 1;
@@ -1133,9 +1131,7 @@
 	int len, r;
 	byte filename[100];
 
-	_msgPtrToAdd = filename;
-	_messagePtr = _scriptPointer;
-	addMessageToStack(_messagePtr);
+	addMessageToStack(_scriptPointer, filename, sizeof(filename));
 
 	len = resStrLen(_scriptPointer);
 	_scriptPointer += len + 1;
@@ -1152,9 +1148,7 @@
 	int len, r1, r2;
 	byte filename[100],filename2[100];
 
-	_msgPtrToAdd = filename;
-	_messagePtr = _scriptPointer;
-	addMessageToStack(_messagePtr);
+	addMessageToStack(_scriptPointer, filename, sizeof(filename));
 
 	len = resStrLen(_scriptPointer);
 	_scriptPointer += len + 1;
@@ -1164,9 +1158,7 @@
 			break;
 	}
 
-	_msgPtrToAdd = filename2;
-	_messagePtr = _scriptPointer;
-	addMessageToStack(_messagePtr);
+	addMessageToStack(_scriptPointer, filename2, sizeof(filename2));
 
 	len = resStrLen(_scriptPointer);
 	_scriptPointer += len + 1;
@@ -1403,9 +1395,7 @@
 	int len, r;
 	byte filename[100];
 
-	_msgPtrToAdd = filename;
-	_messagePtr = _scriptPointer;
-	addMessageToStack(_messagePtr);
+	addMessageToStack(_scriptPointer, filename, sizeof(filename));
 
 	len = resStrLen(_scriptPointer);
 	_scriptPointer += len + 1;
@@ -1455,24 +1445,23 @@
 		_string[m].no_talk_anim = true;
 		break;
 	case 75:		// SO_TEXTSTRING
-		_messagePtr = translateTextAndPlaySpeech(_scriptPointer);
-		_scriptPointer += resStrLen(_scriptPointer)+ 1;
-
 		switch (m) {
 		case 0:
-			actorTalk();
+			actorTalk(_scriptPointer);
 			break;
 		case 1:
-			drawString(1);
+			drawString(1, _scriptPointer);
 			break;
 		case 2:
-			unkMessage1();
+			unkMessage1(_scriptPointer);
 			break;
 		case 3:
-			unkMessage2();
+			unkMessage2(_scriptPointer);
 			break;
 		}
-		return;
+		_scriptPointer += resStrLen(_scriptPointer) + 1;
+
+		break;
 	case 0xF9:
 		c = pop();
 		if (c == 1) {
@@ -1483,12 +1472,12 @@
 			getStackList(args, ARRAYSIZE(args));
 		}
 		warning("decodeParseString case 0xF9 stub");
-		return;
+		break;
 	case 0xFE:
 		setStringVars(m);
 		if (n)
 			_actorToPrintStrFor = pop();
-		return;
+		break;
 	case 0xFF:
 		_string[m].t_xpos = _string[m].xpos;
 		_string[m].t_ypos = _string[m].ypos;
@@ -1498,7 +1487,7 @@
 		_string[m].t_right = _string[m].right;
 		_string[m].t_color = _string[m].color;
 		_string[m].t_charset = _string[m].charset;
-		return;
+		break;
 	default:
 		error("decodeParseString: default case 0x%x", b);
 	}

Index: script_v8.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/scumm/script_v8.cpp,v
retrieving revision 2.229.2.5
retrieving revision 2.229.2.6
diff -u -d -r2.229.2.5 -r2.229.2.6
--- script_v8.cpp	17 Jul 2004 08:27:55 -0000	2.229.2.5
+++ script_v8.cpp	18 Jul 2004 22:15:52 -0000	2.229.2.6
@@ -513,30 +513,28 @@
 		_string[m].no_talk_anim = true;
 		break;
 	case 0xD1:		// SO_PRINT_STRING
-		_messagePtr = translateTextAndPlaySpeech(_scriptPointer);
-		_scriptPointer += resStrLen(_scriptPointer)+ 1;
-
 		switch (m) {
 		case 0:
-			actorTalk();
+			actorTalk(_scriptPointer);
 			break;
 		case 1:
-			drawString(1);
+			drawString(1, _scriptPointer);
 			break;
 		case 2:
-			unkMessage1();
+			unkMessage1(_scriptPointer);
 			break;
 		case 3:
-			unkMessage2();
+			unkMessage2(_scriptPointer);
 			break;
 		case 5:{
 			byte buffer[256];
-			_msgPtrToAdd = buffer;
-			addMessageToStack(_messagePtr);
+			addMessageToStack(_scriptPointer, buffer, sizeof(buffer));
 			enqueueText(buffer, _string[m].xpos, _string[m].ypos, _string[m].color, _string[m].charset, _string[m].center);
 			}
 			break;
 		}
+		_scriptPointer += resStrLen(_scriptPointer) + 1;
+
 		break;
 	case 0xD2:		// SO_PRINT_WRAP Set print wordwrap
 		//warning("decodeParseString: SO_PRINT_WRAP");
@@ -1538,13 +1536,14 @@
 	int oldID = _charset->getCurID(); 
 	int width;
 	const byte *msg = _scriptPointer;
+	byte transBuf[512];
 	
 	// Skip to the next instruction
 	_scriptPointer += resStrLen(_scriptPointer) + 1;
 
 	if (msg[0] == '/') {
-		translateText(msg, _transText);
-		msg = _transText;
+		translateText(msg, transBuf);
+		msg = transBuf;
 	} 
 
 

Index: scumm.h
===================================================================
RCS file: /cvsroot/scummvm/scummvm/scumm/scumm.h,v
retrieving revision 1.369.2.8
retrieving revision 1.369.2.9
diff -u -d -r1.369.2.8 -r1.369.2.9
--- scumm.h	18 Jul 2004 13:49:31 -0000	1.369.2.8
+++ scumm.h	18 Jul 2004 22:15:52 -0000	1.369.2.9
@@ -396,19 +396,14 @@
 	int32& scummVar(byte var, const char *varName, const char *file, int line)
 	{
 		if (var == 0xFF) {
-			warning("Illegal access to variable %s in file %s, line %d", varName, file, line);
-			// Return a fake memory location, so that at least no innocent variable
-			// gets overwritten.
-			static int32 fake;
-			fake = 0;
-			return fake;
+			error("Illegal access to variable %s in file %s, line %d", varName, file, line);
 		}
 		return _scummVars[var];
 	}
 	int32 scummVar(byte var, const char *varName, const char *file, int line) const
 	{
 		if (var == 0xFF) {
-			warning("Illegal access to variable %s in file %s, line %d", varName, file, line);
+			error("Illegal access to variable %s in file %s, line %d", varName, file, line);
 		}
 		return _scummVars[var];
 	}
@@ -514,7 +509,7 @@
 	const byte *_scriptPointer, *_scriptOrgPointer;
 	byte _opcode, _currentScript;
 	uint16 _curExecScript;
-	byte **_lastCodePtr;
+	const byte * const *_lastCodePtr;
 	int _resultVarNumber, _scummStackPos;
 	int _vmStack[150];
 	int _keyScriptKey, _keyScriptNo;
@@ -772,7 +767,7 @@
 	SentenceTab _sentence[NUM_SENTENCE];
 	StringTab _string[6];
 	int16 _talkDelay;
-	void actorTalk();
+	void actorTalk(const byte *msg);
 	void stopTalk();
 	int getTalkingActor();		// Wrapper around VAR_TALK_ACTOR for V1 Maniac
 	void setTalkingActor(int variable);
@@ -1056,24 +1051,21 @@
 	int _charsetBufPos;
 	byte _charsetBuffer[512];
 
-protected:
+	bool _keepText;
+
 	void initCharset(int charset);
 
 	void CHARSET_1();
-	void drawString(int a);
-	const byte *addMessageToStack(const byte *msg);
-	void addIntToStack(int var);
-	void addVerbToStack(int var);
-	void addNameToStack(int var);
-	void addStringToStack(int var);
-	void unkMessage1();
-	void unkMessage2();
-public:
-	void clearMsgQueue();	// Used by Actor::putActor
-protected:
-	byte *_msgPtrToAdd;
-	const byte *_messagePtr;
-	bool _keepText;
+	void drawString(int a, const byte *msg);
+	void unkMessage1(const byte *msg);
+	void unkMessage2(const byte *msg);
+
+	int addMessageToStack(const byte *msg, byte *dst, int dstSize);
+	int addIntToStack(byte *dst, int dstSize, int var);
+	int addVerbToStack(byte *dst, int dstSize, int var);
+	int addNameToStack(byte *dst, int dstSize, int var);
+	int addStringToStack(byte *dst, int dstSize, int var);
+
 public:
 	Common::Language _language;
 protected:
@@ -1081,10 +1073,10 @@
 	char *_languageBuffer;
 	LangIndexNode *_languageIndex;
 	int _languageIndexSize;
-	byte _transText[500];
+	char _lastStringTag[12+1];
 
 	void loadLanguageBundle();
-	const byte *translateTextAndPlaySpeech(const byte *ptr);
+	void playSpeech(const byte *ptr);
 public:
 	void translateText(const byte *text, byte *trans_buff);	// Used by class ScummDialog
 

Index: scummvm.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/scumm/Attic/scummvm.cpp,v
retrieving revision 2.577.2.23
retrieving revision 2.577.2.24
diff -u -d -r2.577.2.23 -r2.577.2.24
--- scummvm.cpp	18 Jul 2004 13:49:31 -0000	2.577.2.23
+++ scummvm.cpp	18 Jul 2004 22:15:52 -0000	2.577.2.24
@@ -488,14 +488,11 @@
 	_copyProtection = false;
 	_demoMode = false;
 	_confirmExit = false;
-	_msgPtrToAdd = NULL;
-	_messagePtr = NULL;
 	_talkDelay = 0;
 	_keepText = false;
 	_existLanguageFile = false;
 	_languageBuffer = NULL;
 	_languageIndex = NULL;
-	memset(_transText, 0, sizeof(_transText));
 	_costumeRenderer = NULL;
 	_2byteFontPtr = 0;
 	_V1_talkingActor = 0;
@@ -1971,7 +1968,7 @@
 	CHECK_HEAP;
 	debugC(DEBUG_GENERAL, "Loading room %d", room);
 
-	clearMsgQueue();
+	stopTalk();
 
 	fadeOut(_switchRoomEffect2);
 	_newEffect = _switchRoomEffect;

Index: string.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/scumm/string.cpp,v
retrieving revision 1.193.2.5
retrieving revision 1.193.2.6
diff -u -d -r1.193.2.5 -r1.193.2.6
--- string.cpp	17 Jul 2004 08:27:56 -0000	1.193.2.5
+++ string.cpp	18 Jul 2004 22:15:53 -0000	1.193.2.6
@@ -46,10 +46,9 @@
 	st->charset = st->t_charset;
 }
 
-void ScummEngine::unkMessage1() {
+void ScummEngine::unkMessage1(const byte *msg) {
 	byte buffer[100];
-	_msgPtrToAdd = buffer;
-	_messagePtr = addMessageToStack(_messagePtr);
+	addMessageToStack(msg, buffer, sizeof(buffer));
 
 //	if ((_gameId == GID_CMI) && _debugMode) {	// In CMI, unkMessage1 is used for printDebug output
 	if ((buffer[0] != 0xFF) && _debugMode) {
@@ -72,22 +71,18 @@
 	}
 }
 
-void ScummEngine::unkMessage2() {
+void ScummEngine::unkMessage2(const byte *msg) {
+	// Original COMI used different code at this point.
+	// Seemed to use blastText for the messages
 	byte buf[100];
-	const byte *tmp;
 
-	_msgPtrToAdd = buf;
-	tmp = _messagePtr = addMessageToStack(_messagePtr);
+	addMessageToStack(msg, buf, sizeof(buf));
 
 	if (_string[3].color == 0)
 		_string[3].color = 4;
 
-	// FIXME: I know this is the right thing to do for MI1 and MI2. For
-	// all other games it's just a guess.
 	InfoDialog dialog(this, (char*)buf);
 	VAR(VAR_KEYPRESS) = runDialog(dialog);
-
-	_messagePtr = tmp;
 }
 
 void ScummEngine::CHARSET_1() {
@@ -345,15 +340,14 @@
 	_charset->_mask = _charset->_str;
 }
 
-void ScummEngine::drawString(int a) {
+void ScummEngine::drawString(int a, const byte *msg) {
 	byte buf[256];
 	byte *space;
 	int i, c;
 	byte fontHeight = 0;
 	uint color;
 
-	_msgPtrToAdd = buf;
-	_messagePtr = addMessageToStack(_messagePtr);
+	addMessageToStack(msg, buf, sizeof(buf));
 
 	_charset->_top = _string[a].ypos + _screenTop;
 	_charset->_startLeft = _charset->_left = _string[a].xpos;
@@ -370,18 +364,18 @@
 
 	fontHeight = _charset->getFontHeight();
 
-	_msgPtrToAdd = buf;
 
 	// trim from the right
+	byte *tmp = buf;
 	space = NULL;
-	while (*_msgPtrToAdd) {
-		if (*_msgPtrToAdd == ' ') {
+	while (*tmp) {
+		if (*tmp == ' ') {
 			if (!space)
-				space = _msgPtrToAdd;
+				space = tmp;
 		} else {
 			space = NULL;
 		}
-		_msgPtrToAdd++;
+		tmp++;
 	}
 	if (space)
 		*space = '\0';
@@ -392,6 +386,7 @@
 	if (_version < 7)
 		_charset->_ignoreCharsetMask = true;
 
+
 	if (!buf[0]) {
 		buf[0] = ' ';
 		buf[1] = 0;
@@ -468,67 +463,55 @@
 	}
 }
 
-const byte *ScummEngine::addMessageToStack(const byte *msg) {
+int ScummEngine::addMessageToStack(const byte *msg, byte *dst, int dstSize) {
 	uint num = 0;
 	uint32 val;
 	byte chr;
-	byte buf[512];
+	const byte *src;
+	byte *end;
+	byte transBuf[384];
+
+	assert(dst);
+	end = dst + dstSize;
 
 	if (msg == NULL) {
 		warning("Bad message in addMessageToStack, ignoring");
-		return NULL;
+		return 0;
 	}
 
-	while ((buf[num++] = chr = *msg++) != 0) {
-		if (num >= sizeof(buf))
-			error("Message stack overflow");
-
-		if (chr == 0xff) {	// 0xff is an escape character
-			buf[num++] = chr = *msg++;	// followed by a "command" code
-			if (chr != 1 && chr != 2 && chr != 3 && chr != 8) {
-				buf[num++] = *msg++;	// and some commands are followed by parameters to the functions below
-				buf[num++] = *msg++;	// these are numbers of names, strings, verbs, variables, etc
-				if (_version == 8) {
-					buf[num++] = *msg++;
-					buf[num++] = *msg++;
-				}
-			}
-		}
+	if (_version >= 7 && msg[0] == '/') {
+		translateText(msg, transBuf);
+		src = transBuf;
+	} else {
+		src = msg;
 	}
 
 	num = 0;
 
 	while (1) {
-		chr = buf[num++];
+		chr = src[num++];
 		if (chr == 0)
 			break;
 		if (chr == 0xFF) {
-			chr = buf[num++];
+			chr = src[num++];
 			if (chr == 1 || chr == 2 || chr == 3 || chr == 8) {
 				// Simply copy these special codes
-				*_msgPtrToAdd++ = 0xFF;
-				*_msgPtrToAdd++ = chr;
+				*dst++ = 0xFF;
+				*dst++ = chr;
 			} else {
-				val = (_version == 8) ? READ_LE_UINT32(buf + num) : READ_LE_UINT16(buf + num);
+				val = (_version == 8) ? READ_LE_UINT32(src + num) : READ_LE_UINT16(src + num);
 				switch (chr) {
 				case 4:
-					addIntToStack(val);
+					dst += addIntToStack(dst, end - dst, val);
 					break;
 				case 5:
-					addVerbToStack(val);
+					dst += addVerbToStack(dst, end - dst, val);
 					break;
 				case 6:
-					addNameToStack(val);
+					dst += addNameToStack(dst, end - dst, val);
 					break;
 				case 7:
-					if (_version <= 2) {
-						while ((chr = (byte) _scummVars[val++])) {
-							if (chr != '@')
-								*_msgPtrToAdd++ = chr;
-						}
-					} else {
-						addStringToStack(val);
-					}
+					dst += addStringToStack(dst, end - dst, val);
 					break;
 				case 9:
 				case 10:
@@ -536,13 +519,13 @@
 				case 13:
 				case 14:
 					// Simply copy these special codes
-					*_msgPtrToAdd++ = 0xFF;
-					*_msgPtrToAdd++ = chr;
-					*_msgPtrToAdd++ = buf[num+0];
-					*_msgPtrToAdd++ = buf[num+1];
+					*dst++ = 0xFF;
+					*dst++ = chr;
+					*dst++ = src[num+0];
+					*dst++ = src[num+1];
 					if (_version == 8) {
-						*_msgPtrToAdd++ = buf[num+2];
-						*_msgPtrToAdd++ = buf[num+3];
+						*dst++ = src[num+2];
+						*dst++ = src[num+3];
 					}
 					break;
 				default:
@@ -553,23 +536,27 @@
 			}
 		} else {
 			if (chr != '@') {
-				*_msgPtrToAdd++ = chr;
+				*dst++ = chr;
 			}
 		}
+	
+		// Check for a buffer overflow
+		if (dst >= end)
+			error("addMessageToStack: buffer overflow!");
 	}
-	*_msgPtrToAdd = 0;
-
-	return msg;
+	*dst = 0;
+	
+	return dstSize - (end - dst);
 }
 
-void ScummEngine::addIntToStack(int var) {
+int ScummEngine::addIntToStack(byte *dst, int dstSize, int var) {
 	int num;
 
 	num = readVar(var);
-	_msgPtrToAdd += sprintf((char *)_msgPtrToAdd, "%d", num);
+	return snprintf((char *)dst, dstSize, "%d", num);
 }
 
-void ScummEngine::addVerbToStack(int var) {
+int ScummEngine::addVerbToStack(byte *dst, int dstSize, int var) {
 	int num, k;
 
 	num = readVar(var);
@@ -577,48 +564,52 @@
 		for (k = 1; k < _numVerbs; k++) {
 			if (num == _verbs[k].verbid && !_verbs[k].type && !_verbs[k].saveid) {
 				const byte *ptr = getResourceAddress(rtVerb, k);
-				ptr = translateTextAndPlaySpeech(ptr);
-				addMessageToStack(ptr);
-				break;
+				return addMessageToStack(ptr, dst, dstSize);
 			}
 		}
 	}
+	return 0;
 }
 
-void ScummEngine::addNameToStack(int var) {
+int ScummEngine::addNameToStack(byte *dst, int dstSize, int var) {
 	int num;
-	const byte *ptr = 0;
 
 	num = readVar(var);
-	if (num)
-		ptr = getObjOrActorName(num);
-	if (ptr) {
-		if ((_version == 8) && (ptr[0] == '/')) {
-			translateText(ptr, _transText);
-			addMessageToStack(_transText);
-		} else {
-			addMessageToStack(ptr);
+	if (num) {
+		const byte *ptr = getObjOrActorName(num);
+		if (ptr) {
+			return addMessageToStack(ptr, dst, dstSize);
 		}
 	}
+	return 0;
 }
 
-void ScummEngine::addStringToStack(int var) {
+int ScummEngine::addStringToStack(byte *dst, int dstSize, int var) {
 	const byte *ptr;
 
+	if (_version <= 2) {
+		byte chr;
+		int i = 0;
+		while ((chr = (byte)_scummVars[var++])) {
+			if (chr != '@') {
+				*dst++ = chr;
+				i++;
+			}
+		}
+
+		return i;
+	}
+
 	if (_version == 3 || _version >= 6)
 		var = readVar(var);
 
 	if (var) {
 		ptr = getStringAddress(var);
 		if (ptr) {
-			if ((_version == 8) && (ptr[0] == '/')) {
-				translateText(ptr, _transText);
-				addMessageToStack(_transText);
-			} else {
-				addMessageToStack(ptr);
-			}
+			return addMessageToStack(ptr, dst, dstSize);
 		}
 	}
+	return 0;
 }
 
 void ScummEngine::initCharset(int charsetno) {
@@ -724,6 +715,7 @@
 	return strcmp(i1->tag, i2->tag);
 }
 
+// Create an index of the language file.
 void ScummEngine::loadLanguageBundle() {
 	File file;
 	int32 size;
@@ -747,23 +739,16 @@
 	file.read(_languageBuffer, size);
 	file.close();
 
-	// Create an index of the language file.
-	// FIXME: Extend this mechanism to also cover The Dig?
-
 	int32 i;
 	char *ptr = _languageBuffer;
 
 	// Count the number of lines in the language file.
-
-	_languageIndexSize = 0;
-
-	for (;;) {
+	for (_languageIndexSize = 0; ; _languageIndexSize++) {
 		ptr = strpbrk(ptr, "\n\r");
 		if (ptr == NULL)
 			break;
 		while (*ptr == '\n' || *ptr == '\r')
 			ptr++;
-		_languageIndexSize++;
 	}
 
 	// Fill the language file index. This is just an array of
@@ -858,75 +843,75 @@
 	qsort(_languageIndex, _languageIndexSize, sizeof(LangIndexNode), indexCompare);
 }
 
-const byte *ScummEngine::translateTextAndPlaySpeech(const byte *ptr) {
-	if ((_gameId == GID_DIG || _gameId == GID_CMI) && (ptr[0] == '/')) {
+void ScummEngine::playSpeech(const byte *ptr) {
+	if ((_gameId == GID_DIG || _gameId == GID_CMI) && ptr[0]) {
 		char pointer[20];
-		int i, j;
-
-		translateText(ptr, _transText);
-		for (i = 0, j = 0; (ptr[i] != '/' || j == 0) && j < 19; i++) {
-			if (ptr[i] != '/')
-				pointer[j++] = ptr[i];
-		}
-		pointer[j] = 0;
+		strcpy(pointer, (const char *)ptr);
 
 		// Play speech
 		if (!(_features & GF_DEMO) && (_gameId == GID_CMI)) // CMI demo does not have .IMX for voice
 			strcat(pointer, ".IMX");
-		// FIXME: This is a hack to distinguish between 'real' actor speech and
-		// some odd (?) other strings... there is probably a better way to do this.
-		// I just don't know which (yet).
-		if ((_gameId == GID_DIG) || (_gameId == GID_CMI && ptr[i+1] != 0 && ptr[i+1] != 255)) {
+
 			_sound->stopTalkSound();
 			_imuseDigital->startVoice(kTalkSoundID, pointer);
 			_sound->talkSound(0, 0, 2, -1);
 		}
-
-		ptr = _transText;
-	}
-	return ptr;
 }
 
 void ScummEngine::translateText(const byte *text, byte *trans_buff) {
-	int l;
+	LangIndexNode target;
+	LangIndexNode *found = NULL;
+	int i;
 	
-	if ((text[0] == '/') && _existLanguageFile) {
-		LangIndexNode target;
-		LangIndexNode *found = NULL;
-
-		// copy name from text /..../
-		for (l = 0; (l < 12) && (text[l + 1] != '/'); l++)
-			target.tag[l] = toupper(text[l + 1]);
-		target.tag[l] = 0;
-
-		// HACK: These are used for the object line when
-		// using one object on another. I don't know if the
-		// text in the language file is a placeholder or if
-		// we're supposed to use it, but at least in the
-		// English version things will work so much better if
-		// we can't find translations for these.
+	if (_version >= 7 && text[0] == '/') {
+		// Extract the string tag from the text: /..../
+		for (i = 0; (i < 12) && (text[i + 1] != '/'); i++)
+			_lastStringTag[i] = target.tag[i] = toupper(text[i + 1]);
+		_lastStringTag[i] = target.tag[i] = 0;
+		text += i + 2;
 
-		if (strcmp(target.tag, "PU_M001") != 0 && strcmp(target.tag, "PU_M002") != 0)
-			found = (LangIndexNode *)bsearch(&target, _languageIndex, _languageIndexSize, sizeof(LangIndexNode), indexCompare);
-		if (found != NULL) {
-			strcpy((char *)trans_buff, _languageBuffer + found->offset);
-			return;
+		// If a language file was loaded, try to find a translated version
+		// by doing a lookup on the string tag.
+		if (_existLanguageFile) {
+			// HACK: These are used for the object line when
+			// using one object on another. I don't know if the
+			// text in the language file is a placeholder or if
+			// we're supposed to use it, but at least in the
+			// English version things will work so much better if
+			// we can't find translations for these.
+	
+			if (strcmp(target.tag, "PU_M001") != 0 && strcmp(target.tag, "PU_M002") != 0)
+				found = (LangIndexNode *)bsearch(&target, _languageIndex, _languageIndexSize, sizeof(LangIndexNode), indexCompare);
 		}
 	}
-	
-	byte *pointer = (byte *)strchr((const char *)text + 1, '/');
-	if (pointer != NULL) {
-		pointer++;
-		if (_gameId == GID_CMI) {
-			memcpy(trans_buff, pointer, resStrLen(pointer) + 1);
-		} else if (_gameId == GID_DIG) {
-			l = 0;
-			while (*pointer != '/' && *pointer != 0xff && *pointer != 0) {
-				trans_buff[l++] = *pointer++;
+
+	if (found != NULL) {
+		strcpy((char *)trans_buff, _languageBuffer + found->offset);
+
+		// FIXME / TODO: Maybe this should be enabled for Full Throttle, too?
+		if ((_gameId == GID_DIG) && !(_features & GF_DEMO)) {
+			// Replace any '%___' by the corresponding special codes in the source text
+			const byte *src = text;
+			char *dst = (char *)trans_buff;
+
+			while ((dst = strstr(dst, "%___"))) {
+				// Search for a special code in the message.
+				while (*src && *src != 0xFF) {
+					src++;
+				}
+				
+				// Replace the %___ by the special code. Luckily, we can do
+				// that in-place.
+				if (*src == 0xFF) {
+					memcpy(dst, src, 4);
+					src += 4;
+					dst += 4;
+				} else
+					break;
 			}
-			trans_buff[l] = '\0';
 		}
 	} else {
+		// Default: just copy the string
 		memcpy(trans_buff, text, resStrLen(text) + 1);
 	}
 }

Index: verbs.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/scumm/verbs.cpp,v
retrieving revision 1.93.2.1
retrieving revision 1.93.2.2
diff -u -d -r1.93.2.1 -r1.93.2.2
--- verbs.cpp	17 Jul 2004 08:27:56 -0000	1.93.2.1
+++ verbs.cpp	18 Jul 2004 22:15:53 -0000	1.93.2.2
@@ -228,18 +228,18 @@
 		_string[1].xpos = v2_mouseover_boxes[i].rect.left;
 
 		_string[1].color = v2_mouseover_boxes[i].color;
-		_messagePtr = getObjOrActorName(obj);
-		assert(_messagePtr);
+
+		const byte *tmp = getObjOrActorName(obj);
+		assert(tmp);
 
 		// Prevent inventory entries from overflowing by truncating the text
 		// after 144/8 = 18 chars
 		byte msg[18 + 1];
 		msg[18] = 0;
-		strncpy((char *)msg, (const char *)_messagePtr, 18);
-		_messagePtr = msg;
+		strncpy((char *)msg, (const char *)tmp, 18);
 		
 		// Draw it
-		drawString(1);
+		drawString(1, msg);
 	}
 
 
@@ -248,8 +248,7 @@
 		_string[1].xpos = v2_mouseover_boxes[kInventoryUpArrow].rect.left;
 		_string[1].ypos = v2_mouseover_boxes[kInventoryUpArrow].rect.top + vs->topline;
 	        _string[1].color = v2_mouseover_boxes[kInventoryUpArrow].color;
-		_messagePtr = (const byte *)" \1\2";
-		drawString(1);
+		drawString(1, (const byte *)" \1\2");
 	}
 
 	// If necessary, draw "down" arrow
@@ -257,8 +256,7 @@
 		_string[1].xpos = v2_mouseover_boxes[kInventoryDownArrow].rect.left;
 		_string[1].ypos = v2_mouseover_boxes[kInventoryDownArrow].rect.top + vs->topline;
 	        _string[1].color = v2_mouseover_boxes[kInventoryDownArrow].color;
-		_messagePtr = (const byte *)" \3\4";
-		drawString(1);
+		drawString(1, (const byte *)" \3\4");
 	}
 }
 
@@ -402,19 +400,13 @@
 		   verb += _inventoryOffset;
 		 */
 
-		_messagePtr = getResourceAddress(rtVerb, verb);
-		if (!_messagePtr)
+		const byte *msg = getResourceAddress(rtVerb, verb);
+		if (!msg)
 			return;
-		assert(_messagePtr);
-
-		if ((_version == 8) && (_messagePtr[0] == '/')) {
-			translateText(_messagePtr, _transText);
-			_messagePtr = _transText;
-		}
 
 		tmp = _charset->_center;
 		_charset->_center = 0;
-		drawString(4);
+		drawString(4, msg);
 		_charset->_center = tmp;
 
 		vs->curRect.right = _charset->_str.right;





More information about the Scummvm-git-logs mailing list