[Scummvm-cvs-logs] CVS: scummvm/scumm scumm.h,1.229,1.230 scummvm.cpp,2.192,2.193 string.cpp,1.124,1.125

Max Horn fingolfin at users.sourceforge.net
Fri May 30 16:25:06 CEST 2003


Update of /cvsroot/scummvm/scummvm/scumm
In directory sc8-pr-cvs1:/tmp/cvs-serv22066

Modified Files:
	scumm.h scummvm.cpp string.cpp 
Log Message:
Use language index for The Dig, too

Index: scumm.h
===================================================================
RCS file: /cvsroot/scummvm/scummvm/scumm/scumm.h,v
retrieving revision 1.229
retrieving revision 1.230
diff -u -d -r1.229 -r1.230
--- scumm.h	30 May 2003 22:57:18 -0000	1.229
+++ scumm.h	30 May 2003 23:24:29 -0000	1.230
@@ -255,7 +255,7 @@
 };
 
 struct LangIndexNode {
-	char tag[9];
+	char tag[12+1];
 	int32 offset;
 };
 
@@ -1065,7 +1065,7 @@
 	bool _existLanguageFile;
 	char *_languageBuffer;
 	LangIndexNode *_languageIndex;
-	int _languageStrCount;
+	int _languageIndexSize;
 	byte _transText[500];
 
 	void loadLanguageBundle();

Index: scummvm.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/scumm/scummvm.cpp,v
retrieving revision 2.192
retrieving revision 2.193
diff -u -d -r2.192 -r2.193
--- scummvm.cpp	30 May 2003 20:13:29 -0000	2.192
+++ scummvm.cpp	30 May 2003 23:24:29 -0000	2.193
@@ -390,7 +390,6 @@
 	_existLanguageFile = false;
 	_languageBuffer = NULL;
 	_languageIndex = NULL;
-	_languageStrCount = 0;
 	memset(_transText,0,sizeof(_transText));
 
 	//

Index: string.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/scumm/string.cpp,v
retrieving revision 1.124
retrieving revision 1.125
diff -u -d -r1.124 -r1.125
--- string.cpp	30 May 2003 22:57:19 -0000	1.124
+++ string.cpp	30 May 2003 23:24:29 -0000	1.125
@@ -766,6 +766,8 @@
 		_existLanguageFile = false;
 		return;
 	}
+	
+	_existLanguageFile = true;
 
 	size = file.size();
 	_languageBuffer = (char *)calloc(1, size+1);
@@ -775,48 +777,99 @@
 	// Create an index of the language file.
 	// FIXME: Extend this mechanism to also cover The Dig?
 
-	if (_gameId == GID_CMI) {
-		int32 i;
-		char *ptr = _languageBuffer;
+	int32 i;
+	char *ptr = _languageBuffer;
 
-		// Count the number of lines in the language file.
+	// Count the number of lines in the language file.
 
-		_languageStrCount = 0;
+	_languageIndexSize = 0;
 
-		for (;;) {
-			ptr = strpbrk(ptr, "\n\r");
-			if (ptr == NULL)
-				break;
-			while (*ptr == '\n' || *ptr == '\r')
-				ptr++;
-			_languageStrCount++;
-		}
+	for (;;) {
+		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
-		// tags and offsets. I did consider using a balanced tree
-		// instead, but the extra overhead in the node structure would
-		// easily have doubled the memory consumption of the index.
+	// Fill the language file index. This is just an array of
+	// tags and offsets. I did consider using a balanced tree
+	// instead, but the extra overhead in the node structure would
+	// easily have doubled the memory consumption of the index.
 
-		_languageIndex = (LangIndexNode *)calloc(_languageStrCount, sizeof(LangIndexNode));
+	_languageIndex = (LangIndexNode *)calloc(_languageIndexSize, sizeof(LangIndexNode));
 
-		ptr = _languageBuffer;
+	ptr = _languageBuffer;
 
-		for (i = 0; i < _languageStrCount; i++) {
-			int j;
+	if (_gameId == GID_DIG) {
+		int lineCount = _languageIndexSize;
+		const char *baseTag = "";
+		byte enc = 0;	// Initially assume the language file is not encoded
+		
+		// We'll determine the real index size as we go.
+		_languageIndexSize = 0;
+		for (i = 0; i < lineCount; i++) {
+			if (*ptr == '!') {
+				// Don't know what a line with '!' means, just ignore it
+			} else if (*ptr == 'e') {
+				// File is encoded!
+				enc = 0x13;
+			} else if (*ptr == '@') {
+				// A new 'base tag'
+				baseTag = ptr + 1;
+			} else if (*ptr == '#') {
+				// Number of subtags following a given basetag. We don't need that
+				// information so we just skip it
+			} else if (isdigit(*ptr)) {
+				int idx = 0;
+				// A number (up to three digits)...
+				while (isdigit(*ptr)) {
+					idx = idx * 10 + (*ptr - '0');
+					ptr++;
+				}
+				
+				// ...followed by a slash...
+				assert(*ptr == '/');
+				ptr++;
+				
+				// ...and then the translated message, possibly encoded
+				_languageIndex[_languageIndexSize].offset = ptr - _languageBuffer;
+				
+				// Decode string if necessary.
+				if (enc) {
+					while (*ptr != '\n' && *ptr != '\r')
+						*ptr++ ^= enc;
+				}
+				
+				// The tag is the basetag, followed by a dot and then the index
+				sprintf(_languageIndex[_languageIndexSize].tag, "%s.%03d", baseTag, idx);
+				
+				// That was another index entry
+				_languageIndexSize++;
+			}
 
+			// Skip over newlines (and turn them into null bytes)
+			ptr = strpbrk(ptr, "\n\r");
+			if (ptr == NULL)
+				break;
+			while (*ptr == '\n' || *ptr == '\r')
+				*ptr++ = 0;
+		}
+	} else {
+		for (i = 0; i < _languageIndexSize; i++) {
 			// First 8 chars in the line give the string ID / 'tag'
-			for (j = 0; j < 8 && !isspace(*ptr); j++, ptr++)
+			for (int j = 0; j < 8 && !isspace(*ptr); j++, ptr++)
 				_languageIndex[i].tag[j] = toupper(*ptr);
 			_languageIndex[i].tag[j] = 0;
-
+	
 			// After that follows a single space which we skip
 			assert(isspace(*ptr));
 			ptr++;
 			
 			// Then comes the translated string: we record an offset to that.
 			_languageIndex[i].offset = ptr - _languageBuffer;
-
-//skip:
+	
 			// Skip over newlines (and turn them into null bytes)
 			ptr = strpbrk(ptr, "\n\r");
 			if (ptr == NULL)
@@ -824,137 +877,37 @@
 			while (*ptr == '\n' || *ptr == '\r')
 				*ptr++ = 0;
 		}
-
-		// Conceptually, it may be more elegant to construct the
-		// index so that it is sorted, or otherwise ordered, from the
-		// start. However, this is less error-prone and likely to be
-		// much more optimized than anything I might implement.
-
-		qsort(_languageIndex, _languageStrCount, sizeof(LangIndexNode), indexCompare);
 	}
-	
-	_existLanguageFile = true;
+
+	// Sort the index nodes. We'll later use bsearch on it, which is just as efficient
+	// as using a binary tree, speed wise.
+	qsort(_languageIndex, _languageIndexSize, sizeof(LangIndexNode), indexCompare);
 }
 
 void Scumm::translateText(const byte *text, byte *trans_buff) {
 	int l;
 	
 	if ((text[0] == '/') && _existLanguageFile) {
-		if (_gameId == GID_CMI) {
-			LangIndexNode target;
-			LangIndexNode *found = NULL;
-	
-			// copy name from text /..../
-			for (l = 0; (l < 8) && (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 (strcmp(target.tag, "PU_M001") != 0 && strcmp(target.tag, "PU_M002") != 0)
-				found = (LangIndexNode *)bsearch(&target, _languageIndex, _languageStrCount, sizeof(LangIndexNode), indexCompare);
-			if (found != NULL) {
-				strcpy((char *)trans_buff, _languageBuffer + found->offset);
-				return;
-			}
-		} else if (_gameId == GID_DIG) {
-			// FIXME: This code really could stand a rewrite
-			// It's rather inefficient and if a string isn't found it'll read past the
-			// end of the _languageBuffer.
-			char name[12+1], tmp[500], tmp2[20], num_s[20], number[4], enc;
-			int32 num, j, k, r, pos = 0;
-			char *buf = _languageBuffer;
-	
-			// copy name from text /..../
-			for (l = 0; (l < 12) && (text[l + 1] != '.'); l++) {
-				name[l] = text[l + 1];
-			}
-			name[l] = 0;
-			l++;
-			// get number from text /..../
-			number[0] = text[l + 1];
-			number[1] = text[l + 2];
-			number[2] = text[l + 3];
-			number[3] = 0;
-			num = atol(number);
-			sprintf(num_s, "%d", num);
-	
-			// determine is file encoded
-			if (buf[0] == 'e') {
-				enc = 0x13;
-				pos += 3;
-			} else if (buf[3] == 'e') {
-				enc = 0x13;
-				pos += 6;
-			} else {
-				enc = 0;
-			}
-	
-			// skip translation if flag 'h' exist
-			if (buf[pos] == 'h') {
-				pos += 3;
-				byte *pointer = (byte *)strchr((const char *)text + 1, '/');
-				if (pointer != NULL)
-					memcpy(trans_buff, pointer + 1, resStrLen(pointer + 1) + 1);
-				else
-					trans_buff[0] = '\0';
-				return;
-			}
-	
-			for(;;) {
-				// search char @
-				if (buf[pos++] == '@') {
-					// copy name after @ to endline
-					l = 0;
-					do {
-						tmp[l++] = buf[pos++];
-					} while((buf[pos] != 0x0d) && (buf[pos + 1] != 0x0a) && (l < 19));
-					tmp[l] = 0;
-					pos += 2;
-					// compare 'name' with above name
-					if (strcmp(tmp, name) == 0) {
-						// get number lines of 'name' after '#'
-						l = 0;
-						if (buf[pos++] == '#') {
-							do {
-								tmp[l++] = buf[pos++];
-							} while((buf[pos] != 0x0d) && (buf[pos + 1] != 0x0a) && (l < 19));
-							tmp[l] = 0;
-							pos += 2;
-							l = atol(tmp);
-							// get number of line
-							for(r = 0; r < l; r++) {
-								j = 0;
-								do {
-									tmp2[j++] = buf[pos++];
-								} while(buf[pos] != '/');
-								tmp2[j] = 0;
-								// compare if is right line
-								if (strcmp(tmp2, num_s) == 0) {
-									k = 0;
-									pos++;
-									// copy translated text to tran_buffer
-									do {
-										trans_buff[k++] = (buf[pos++]) ^ enc;
-									} while((buf[pos] != 0x0d) && (buf[pos + 1] != 0x0a));
-									trans_buff[k] = 0;
-									return;
-								}
-								// goto next line
-								do { 
-									pos++;
-								}	while((buf[pos] != 0x0d) && (buf[pos + 1] != 0x0a));
-								pos += 2;
-							}
-						}
-					}
-				}
-			}
+		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 (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;
 		}
 	}
 	





More information about the Scummvm-git-logs mailing list