[Scummvm-git-logs] scummvm master -> 97dae516e2ee7111e1a9c7b4874cdf9c0a679310

bluegr noreply at scummvm.org
Mon Jan 22 06:50:57 UTC 2024


This automated email contains information about 5 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .

Summary:
073469293f SCI: Add cyrillic input support for text-based games
7fad58be1d SCI: Add detection table entries for russian translate of
3f1c050cbe SCI: More information. Moved vocab parse into separate function
a1171dce97 SCI: Apply suggestions from code review
97dae516e2 SCI: Fix after code review


Commit: 073469293f24628b22898a2abc18be2bee883498
    https://github.com/scummvm/scummvm/commit/073469293f24628b22898a2abc18be2bee883498
Author: Иван Марчуков (marchukov.ivan at gmail.com)
Date: 2024-01-22T08:50:52+02:00

Commit Message:
SCI: Add cyrillic input support for text-based games

Changed paths:
    backends/events/sdl/sdl-events.cpp
    engines/sci/engine/file.cpp
    engines/sci/engine/kfile.cpp
    engines/sci/event.cpp
    engines/sci/parser/vocabulary.cpp
    engines/sci/parser/vocabulary.h


diff --git a/backends/events/sdl/sdl-events.cpp b/backends/events/sdl/sdl-events.cpp
index 127855c6ec5..629cced6ef0 100644
--- a/backends/events/sdl/sdl-events.cpp
+++ b/backends/events/sdl/sdl-events.cpp
@@ -129,6 +129,10 @@ int SdlEventSource::mapKey(SDL_Keycode sdlKey, SDL_Keymod mod, Uint16 unicode) {
 				// We allow Hebrew characters
 				if (unicode >= 0x05D0 && unicode <= 0x05EA)
 					return unicode;
+				
+				// Cyrillic
+				if (unicode >= 0x0400 && unicode <= 0x045F)
+					return unicode;
 
 				// We must not restrict as much as when Ctrl/Alt-modifiers are active, otherwise
 				// we wouldn't let umlauts through for SDL1. For SDL1 umlauts may set for example KEYCODE_QUOTE, KEYCODE_MINUS, etc.
diff --git a/engines/sci/engine/file.cpp b/engines/sci/engine/file.cpp
index fa392640f4d..f0dacacb833 100644
--- a/engines/sci/engine/file.cpp
+++ b/engines/sci/engine/file.cpp
@@ -340,6 +340,9 @@ bool fillSavegameDesc(const Common::String &filename, SavegameDesc &desc) {
 	if (g_sci->getLanguage() == Common::HE_ISR) {
 		Common::U32String nameU32String = meta.name.decode(Common::kUtf8);
 		nameString = nameU32String.encode(Common::kWindows1255);
+	} else if (g_sci->getLanguage() == Common::RU_RUS) {
+		Common::U32String nameU32String = meta.name.decode(Common::kUtf8);
+		nameString = nameU32String.encode(Common::kDos866);
 	}
 
 	Common::strlcpy(desc.name, nameString.c_str(), sizeof(desc.name));
diff --git a/engines/sci/engine/kfile.cpp b/engines/sci/engine/kfile.cpp
index 268ffbf8669..1a84766f4e4 100644
--- a/engines/sci/engine/kfile.cpp
+++ b/engines/sci/engine/kfile.cpp
@@ -1099,6 +1099,9 @@ reg_t kSaveGame(EngineState *s, int argc, reg_t *argv) {
 		if (g_sci->getLanguage() == Common::HE_ISR) {
 			Common::U32String u32string = game_description.decode(Common::kWindows1255);
 			game_description = u32string.encode(Common::kUtf8);
+		} else if (g_sci->getLanguage() == Common::RU_RUS) {
+			Common::U32String u32string = game_description.decode(Common::kDos866);
+			game_description = u32string.encode(Common::kUtf8);
 		};
 
 
diff --git a/engines/sci/event.cpp b/engines/sci/event.cpp
index a5c0ae0c980..99c955b3fc1 100644
--- a/engines/sci/event.cpp
+++ b/engines/sci/event.cpp
@@ -364,7 +364,9 @@ SciEvent EventManager::getScummVMEvent() {
 		if (g_sci->getLanguage() == Common::RU_RUS) {
 			// Convert UTF16 to CP866
 			if (input.character >= 0x400 && input.character <= 0x4ff) {
-				if (input.character >= 0x440)
+				if (input.character == 0x401)
+					input.character = 0xf0;
+				else if (input.character >= 0x440)
 					input.character = input.character - 0x410 + 0xb0;
 				else
 					input.character = input.character - 0x410 + 0x80;
diff --git a/engines/sci/parser/vocabulary.cpp b/engines/sci/parser/vocabulary.cpp
index c6790bf07d8..6d212d04929 100644
--- a/engines/sci/parser/vocabulary.cpp
+++ b/engines/sci/parser/vocabulary.cpp
@@ -188,6 +188,45 @@ bool Vocabulary::loadParserWords() {
 		seeker += 3;
 	}
 
+	// Additional translated words
+	{
+		resource = _resMan->findResource(ResourceId(kResourceTypeVocab, VOCAB_RESOURCE_SCI0_LOC_VOCAB), 0);
+		if (!resource) return true;
+
+		seeker = 0;
+		while (seeker < resource->size()) {
+			byte c;
+
+			currentWordPos = resource->getUint8At(seeker++); // Parts of previous words may be re-used
+
+			do {
+				if (seeker == resource->size()) {
+					return true;
+				}
+				c = resource->getUint8At(seeker++);
+				assert(currentWordPos < ARRAYSIZE(currentWord) - 1);
+				currentWord[currentWordPos++] = (c & 0x7f) | 0x80; // add 0x80 for upper character table
+			} while (c < 0x80);
+
+			if (seeker == resource->size()) {
+				return true;
+			}
+
+			currentWord[currentWordPos] = 0;
+
+			// Now decode class and group:
+			c = resource->getUint8At(seeker + 1);
+			ResultWord newWord;
+			newWord._class = ((resource->getUint8At(seeker)) << 4) | ((c & 0xf0) >> 4);
+			newWord._group = (resource->getUint8At(seeker + 2)) | ((c & 0x0f) << 8);
+
+			// Add this to the list of possible class,group pairs for this word
+			_parserWords[currentWord].push_back(newWord);
+
+			seeker += 3;
+		}
+	}
+
 	return true;
 }
 
@@ -655,19 +694,42 @@ static const byte lowerCaseMap[256] = {
 	0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff  // 0xf0
 };
 
+static const byte lowerCaseMap866[256] = {
+	0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, // 0x00
+	0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, // 0x10
+	0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, // 0x20
+	0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, // 0x30
+	0x40,  'a',  'b',  'c',  'd',  'e',  'f',  'g',  'h',  'i',  'j',  'k',  'l',  'm',  'n',  'o', // 0x40
+	 'p',  'q',  'r',  's',  't',  'u',  'v',  'w',  'x',  'y',  'z', 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, // 0x50
+	0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, // 0x60
+	0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, // 0x70
+	0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, // 0x80
+	0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, // 0x90
+	0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, // 0xa0
+	0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, // 0xb0
+	0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, // 0xc0
+	0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, // 0xd0
+	0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, // 0xe0
+	0xa5, 0xa5, 0xf3, 0xf3, 0xf5, 0xf5, 0xf7, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff  // 0xf0
+};
+
 bool Vocabulary::tokenizeString(ResultWordListList &retval, const char *sentence, char **error) {
 	char currentWord[VOCAB_MAX_WORDLENGTH] = "";
 	int pos_in_sentence = 0;
 	unsigned char c;
 	int wordLen = 0;
+	const byte * lcMap = lowerCaseMap;
 
 	*error = nullptr;
 
+	if (g_sci->getLanguage() == Common::RU_RUS)
+		lcMap = lowerCaseMap866;
+
 	do {
 		c = sentence[pos_in_sentence++];
 
 		if (Common::isAlnum(c) || (c == '-' && wordLen) || (c >= 0x80)) {
-			currentWord[wordLen] = lowerCaseMap[c];
+			currentWord[wordLen] = lcMap[c];
 			++wordLen;
 		} else if (c == ' ' || c == '\0') {
 			// Continue on this word. Words may contain a '-', but may not start with
diff --git a/engines/sci/parser/vocabulary.h b/engines/sci/parser/vocabulary.h
index f4b20b5966a..77fc908fd42 100644
--- a/engines/sci/parser/vocabulary.h
+++ b/engines/sci/parser/vocabulary.h
@@ -47,6 +47,7 @@ enum {
 	VOCAB_RESOURCE_SELECTORS = 997,
 
 	VOCAB_RESOURCE_SCI0_MAIN_VOCAB = 0,
+	VOCAB_RESOURCE_SCI0_LOC_VOCAB = 1,
 	VOCAB_RESOURCE_SCI0_PARSE_TREE_BRANCHES = 900,
 	VOCAB_RESOURCE_SCI0_SUFFIX_VOCAB = 901,
 


Commit: 7fad58be1d994a256089389c81c2fde9ae5e8266
    https://github.com/scummvm/scummvm/commit/7fad58be1d994a256089389c81c2fde9ae5e8266
Author: Иван Марчуков (marchukov.ivan at gmail.com)
Date: 2024-01-22T08:50:52+02:00

Commit Message:
SCI: Add detection table entries for russian translate of

Conquests of Camelot, Laura Bow and Police Quest 2

Changed paths:
    engines/sci/detection_tables.h


diff --git a/engines/sci/detection_tables.h b/engines/sci/detection_tables.h
index 6b0279e2724..9205d4f843a 100644
--- a/engines/sci/detection_tables.h
+++ b/engines/sci/detection_tables.h
@@ -423,6 +423,19 @@ static const struct ADGameDescription SciGameDescriptions[] = {
 		AD_LISTEND},
 		Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO, GUIO_STD16_UNDITHER	},
 
+	// Conquests of Camelot - Russian fan translation
+	// Executable scanning reports "0.000.685", Floppy label reports "1.001, 0.000.685", VERSION file reports "1.001.000"
+	// SCI interpreter version 0.000.685
+	{"camelot", "", {
+		{"resource.map", 0, "95eca3991906dfd7ed26d193df07596f", 7278},
+		{"resource.001", 0, "8e1a3a8c588007404b532b8dfacc1460", 596774},
+		{"resource.002", 0, "8e1a3a8c588007404b532b8dfacc1460", 722250},
+		{"resource.003", 0, "8e1a3a8c588007404b532b8dfacc1460", 723712},
+		{"resource.004", 0, "8e1a3a8c588007404b532b8dfacc1460", 729143},
+		{"Translate.RU", 0, "3f730611f55257821b964f96eafea0ba", 171},
+		AD_LISTEND},
+		Common::RU_RUS, Common::kPlatformDOS, 0, GUIO_STD16_UNDITHER	},
+
 	// Conquests of Camelot - English DOS (from jvprat)
 	// Executable scanning reports "0.000.685", Floppy label reports "1.001, 0.000.685", VERSION file reports "1.001.000"
 	// SCI interpreter version 0.000.685
@@ -2610,6 +2623,24 @@ static const struct ADGameDescription SciGameDescriptions[] = {
 		{"PATCHES/font.008", 0, "8abefd3b44827ff26e2ad298f9e76a2b", 3029},
 		AD_LISTEND},
 		Common::HE_ISR, Common::kPlatformDOS, 0, GUIO_STD16_UNDITHER },
+		
+	// Laura Bow - Russian fan translation
+	// SCI interpreter version 0.000.631
+	{"laurabow", "", {
+		{"resource.map", 0, "b1905f6aa68ff65a057b080b1eae954c", 12030},
+		{"resource.001", 0, "e45c888d9c7c04aec0a20e9f820b79ff", 108032},
+		{"resource.002", 0, "e45c888d9c7c04aec0a20e9f820b79ff", 354680},
+		{"resource.003", 0, "e45c888d9c7c04aec0a20e9f820b79ff", 361815},
+		{"resource.004", 0, "e45c888d9c7c04aec0a20e9f820b79ff", 339714},
+		{"resource.005", 0, "e45c888d9c7c04aec0a20e9f820b79ff", 327465},
+		{"resource.006", 0, "e45c888d9c7c04aec0a20e9f820b79ff", 328390},
+		{"resource.007", 0, "e45c888d9c7c04aec0a20e9f820b79ff", 317687},
+		{"resource.008", 0, "e45c888d9c7c04aec0a20e9f820b79ff", 352345},
+		{"resource.009", 0, "e45c888d9c7c04aec0a20e9f820b79ff", 257355},
+		{"resource.010", 0, "e45c888d9c7c04aec0a20e9f820b79ff", 356093},
+		{"Translate.RU", 0, "3f730611f55257821b964f96eafea0ba", 171},
+		AD_LISTEND},
+		Common::RU_RUS, Common::kPlatformDOS, 0, GUIO_STD16_UNDITHER	},
 
 	// Laura Bow - English DOS (from FRG)
 	// SCI interpreter version 0.000.631
@@ -4264,6 +4295,17 @@ static const struct ADGameDescription SciGameDescriptions[] = {
 		AD_LISTEND},
 		Common::EN_ANY, Common::kPlatformDOS, 0, GUIO_STD16_UNDITHER	},
 
+	// Police Quest 2 - Russian DOS (from the Police Quest Collection)
+	// Executable scanning reports "0.000.490"
+	{"pq2", "", {
+		{"resource.map", 0, "28a6f471c7900c2c92da40eecb615d9d", 4584},
+		{"resource.001", 0, "77f02def3094af804fd2371db25b7100", 509525},
+		{"resource.002", 0, "77f02def3094af804fd2371db25b7100", 546000},
+		{"resource.003", 0, "77f02def3094af804fd2371db25b7100", 591851},
+		{"Translate.RU", 0, "3f730611f55257821b964f96eafea0ba", 171},
+		AD_LISTEND},
+		Common::RU_RUS, Common::kPlatformDOS, 0, GUIO_STD16_UNDITHER	},
+
 	// Police Quest 2 - English DOS (from the Police Quest Collection)
 	// Executable scanning reports "0.000.490"
 	{"pq2", "", {


Commit: 3f1c050cbedfa3f11a6a0d6aa790a6427a5f11b5
    https://github.com/scummvm/scummvm/commit/3f1c050cbedfa3f11a6a0d6aa790a6427a5f11b5
Author: Иван Марчуков (marchukov.ivan at gmail.com)
Date: 2024-01-22T08:50:52+02:00

Commit Message:
SCI: More information. Moved vocab parse into separate function

Changed paths:
    engines/sci/detection_tables.h
    engines/sci/event.cpp
    engines/sci/parser/vocabulary.cpp
    engines/sci/parser/vocabulary.h


diff --git a/engines/sci/detection_tables.h b/engines/sci/detection_tables.h
index 9205d4f843a..4a6a7b8bd95 100644
--- a/engines/sci/detection_tables.h
+++ b/engines/sci/detection_tables.h
@@ -423,7 +423,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
 		AD_LISTEND},
 		Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO, GUIO_STD16_UNDITHER	},
 
-	// Conquests of Camelot - Russian fan translation
+	// Conquests of Camelot - Russian fan translation by https://github.com/deadman2000/RuSCI
 	// Executable scanning reports "0.000.685", Floppy label reports "1.001, 0.000.685", VERSION file reports "1.001.000"
 	// SCI interpreter version 0.000.685
 	{"camelot", "", {
@@ -432,7 +432,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
 		{"resource.002", 0, "8e1a3a8c588007404b532b8dfacc1460", 722250},
 		{"resource.003", 0, "8e1a3a8c588007404b532b8dfacc1460", 723712},
 		{"resource.004", 0, "8e1a3a8c588007404b532b8dfacc1460", 729143},
-		{"Translate.RU", 0, "3f730611f55257821b964f96eafea0ba", 171},
+		{"Translate.RU", 0, "3f730611f55257821b964f96eafea0ba", 171}, // Text file for translate detection
 		AD_LISTEND},
 		Common::RU_RUS, Common::kPlatformDOS, 0, GUIO_STD16_UNDITHER	},
 
@@ -2624,7 +2624,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
 		AD_LISTEND},
 		Common::HE_ISR, Common::kPlatformDOS, 0, GUIO_STD16_UNDITHER },
 		
-	// Laura Bow - Russian fan translation
+	// Laura Bow - Russian fan translation by https://github.com/deadman2000/RuSCI
 	// SCI interpreter version 0.000.631
 	{"laurabow", "", {
 		{"resource.map", 0, "b1905f6aa68ff65a057b080b1eae954c", 12030},
@@ -2638,7 +2638,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
 		{"resource.008", 0, "e45c888d9c7c04aec0a20e9f820b79ff", 352345},
 		{"resource.009", 0, "e45c888d9c7c04aec0a20e9f820b79ff", 257355},
 		{"resource.010", 0, "e45c888d9c7c04aec0a20e9f820b79ff", 356093},
-		{"Translate.RU", 0, "3f730611f55257821b964f96eafea0ba", 171},
+		{"Translate.RU", 0, "3f730611f55257821b964f96eafea0ba", 171}, // Text file for translate detection
 		AD_LISTEND},
 		Common::RU_RUS, Common::kPlatformDOS, 0, GUIO_STD16_UNDITHER	},
 
@@ -4295,14 +4295,14 @@ static const struct ADGameDescription SciGameDescriptions[] = {
 		AD_LISTEND},
 		Common::EN_ANY, Common::kPlatformDOS, 0, GUIO_STD16_UNDITHER	},
 
-	// Police Quest 2 - Russian DOS (from the Police Quest Collection)
+	// Police Quest 2 - fan translate by https://github.com/deadman2000/RuSCI
 	// Executable scanning reports "0.000.490"
 	{"pq2", "", {
 		{"resource.map", 0, "28a6f471c7900c2c92da40eecb615d9d", 4584},
 		{"resource.001", 0, "77f02def3094af804fd2371db25b7100", 509525},
 		{"resource.002", 0, "77f02def3094af804fd2371db25b7100", 546000},
 		{"resource.003", 0, "77f02def3094af804fd2371db25b7100", 591851},
-		{"Translate.RU", 0, "3f730611f55257821b964f96eafea0ba", 171},
+		{"Translate.RU", 0, "3f730611f55257821b964f96eafea0ba", 171}, // Text file for translate detection
 		AD_LISTEND},
 		Common::RU_RUS, Common::kPlatformDOS, 0, GUIO_STD16_UNDITHER	},
 
diff --git a/engines/sci/event.cpp b/engines/sci/event.cpp
index 99c955b3fc1..cbd0f425398 100644
--- a/engines/sci/event.cpp
+++ b/engines/sci/event.cpp
@@ -364,7 +364,7 @@ SciEvent EventManager::getScummVMEvent() {
 		if (g_sci->getLanguage() == Common::RU_RUS) {
 			// Convert UTF16 to CP866
 			if (input.character >= 0x400 && input.character <= 0x4ff) {
-				if (input.character == 0x401)
+				if (input.character == 0x401) // Cyrillic Ё (401h UTF-16) is 0xf0 in CP866
 					input.character = 0xf0;
 				else if (input.character >= 0x440)
 					input.character = input.character - 0x410 + 0xb0;
diff --git a/engines/sci/parser/vocabulary.cpp b/engines/sci/parser/vocabulary.cpp
index 6d212d04929..02997d7bbf7 100644
--- a/engines/sci/parser/vocabulary.cpp
+++ b/engines/sci/parser/vocabulary.cpp
@@ -188,46 +188,56 @@ bool Vocabulary::loadParserWords() {
 		seeker += 3;
 	}
 
-	// Additional translated words
-	{
-		resource = _resMan->findResource(ResourceId(kResourceTypeVocab, VOCAB_RESOURCE_SCI0_LOC_VOCAB), 0);
-		if (!resource) return true;
+	// Russian translation can contain translated vocab in special format
+	if (g_sci->getLanguage() == Common::RU_RUS)
+		loadTranslatedWords();
 
-		seeker = 0;
-		while (seeker < resource->size()) {
-			byte c;
+	return true;
+}
 
-			currentWordPos = resource->getUint8At(seeker++); // Parts of previous words may be re-used
+void Vocabulary::loadTranslatedWords()
+{
+	// This is special fanmade format similar to VOCAB.000 (see https://wiki.scummvm.org/index.php?title=SCI/Specifications/SCI_in_action/Parser#Vocabulary_file_formats)
+	// but all characters is from upper character table (80h..FFh)
 
-			do {
-				if (seeker == resource->size()) {
-					return true;
-				}
-				c = resource->getUint8At(seeker++);
-				assert(currentWordPos < ARRAYSIZE(currentWord) - 1);
-				currentWord[currentWordPos++] = (c & 0x7f) | 0x80; // add 0x80 for upper character table
-			} while (c < 0x80);
+	Resource *resource = _resMan->findResource(ResourceId(kResourceTypeVocab, VOCAB_RESOURCE_SCUMM_LOC_VOCAB), 0);
+	if (!resource) return;
+	
+	char currentWord[VOCAB_MAX_WORDLENGTH] = "";
+	int currentWordPos = 0;
+
+	uint32 seeker = 0;
+	while (seeker < resource->size()) {
+		byte c;
+
+		currentWordPos = resource->getUint8At(seeker++); // Parts of previous words may be re-used
 
+		do {
 			if (seeker == resource->size()) {
-				return true;
+				return;
 			}
+			c = resource->getUint8At(seeker++);
+			assert(currentWordPos < ARRAYSIZE(currentWord) - 1);
+			currentWord[currentWordPos++] = (c & 0x7f) | 0x80; // add 0x80 for upper character table
+		} while (c < 0x80);
 
-			currentWord[currentWordPos] = 0;
+		if (seeker == resource->size()) {
+			return;
+		}
+
+		currentWord[currentWordPos] = 0;
 
-			// Now decode class and group:
-			c = resource->getUint8At(seeker + 1);
-			ResultWord newWord;
-			newWord._class = ((resource->getUint8At(seeker)) << 4) | ((c & 0xf0) >> 4);
-			newWord._group = (resource->getUint8At(seeker + 2)) | ((c & 0x0f) << 8);
+		// Now decode class and group:
+		c = resource->getUint8At(seeker + 1);
+		ResultWord newWord;
+		newWord._class = ((resource->getUint8At(seeker)) << 4) | ((c & 0xf0) >> 4);
+		newWord._group = (resource->getUint8At(seeker + 2)) | ((c & 0x0f) << 8);
 
-			// Add this to the list of possible class,group pairs for this word
-			_parserWords[currentWord].push_back(newWord);
+		// Add this to the list of possible class,group pairs for this word
+		_parserWords[currentWord].push_back(newWord);
 
-			seeker += 3;
-		}
+		seeker += 3;
 	}
-
-	return true;
 }
 
 const char *Vocabulary::getAnyWordFromGroup(int group) {
diff --git a/engines/sci/parser/vocabulary.h b/engines/sci/parser/vocabulary.h
index 77fc908fd42..2155f4d9751 100644
--- a/engines/sci/parser/vocabulary.h
+++ b/engines/sci/parser/vocabulary.h
@@ -47,7 +47,7 @@ enum {
 	VOCAB_RESOURCE_SELECTORS = 997,
 
 	VOCAB_RESOURCE_SCI0_MAIN_VOCAB = 0,
-	VOCAB_RESOURCE_SCI0_LOC_VOCAB = 1,
+	VOCAB_RESOURCE_SCUMM_LOC_VOCAB = 1, // Special fanmade format for vocab translate
 	VOCAB_RESOURCE_SCI0_PARSE_TREE_BRANCHES = 900,
 	VOCAB_RESOURCE_SCI0_SUFFIX_VOCAB = 901,
 
@@ -352,6 +352,12 @@ private:
 	 * @return true on success, false on failure
 	 */
 	bool loadParserWords();
+	
+	/**
+	 * Loads additional translated words from special format vocabulary.
+	 * @return true on success, false on failure
+	 */
+	void loadTranslatedWords();
 
 	/**
 	 * Loads all suffixes from the suffix vocabulary.


Commit: a1171dce97496aca63e7f548323c05f81e1695ab
    https://github.com/scummvm/scummvm/commit/a1171dce97496aca63e7f548323c05f81e1695ab
Author: Marchukov Ivan (marchukov.ivan at gmail.com)
Date: 2024-01-22T08:50:52+02:00

Commit Message:
SCI: Apply suggestions from code review

Co-authored-by: Filippos Karapetis <bluegr at gmail.com>

Changed paths:
    engines/sci/parser/vocabulary.cpp


diff --git a/engines/sci/parser/vocabulary.cpp b/engines/sci/parser/vocabulary.cpp
index 02997d7bbf7..2b43f997534 100644
--- a/engines/sci/parser/vocabulary.cpp
+++ b/engines/sci/parser/vocabulary.cpp
@@ -197,8 +197,9 @@ bool Vocabulary::loadParserWords() {
 
 void Vocabulary::loadTranslatedWords()
 {
-	// This is special fanmade format similar to VOCAB.000 (see https://wiki.scummvm.org/index.php?title=SCI/Specifications/SCI_in_action/Parser#Vocabulary_file_formats)
-	// but all characters is from upper character table (80h..FFh)
+	// This is special fan made format similar to VOCAB.000 (see
+	// https://wiki.scummvm.org/index.php?title=SCI/Specifications/SCI_in_action/Parser#Vocabulary_file_formats)
+	// but all characters used are in the upper character range (80h..FFh)
 
 	Resource *resource = _resMan->findResource(ResourceId(kResourceTypeVocab, VOCAB_RESOURCE_SCUMM_LOC_VOCAB), 0);
 	if (!resource) return;
@@ -728,7 +729,7 @@ bool Vocabulary::tokenizeString(ResultWordListList &retval, const char *sentence
 	int pos_in_sentence = 0;
 	unsigned char c;
 	int wordLen = 0;
-	const byte * lcMap = lowerCaseMap;
+	const byte *lcMap = lowerCaseMap;
 
 	*error = nullptr;
 


Commit: 97dae516e2ee7111e1a9c7b4874cdf9c0a679310
    https://github.com/scummvm/scummvm/commit/97dae516e2ee7111e1a9c7b4874cdf9c0a679310
Author: Иван Марчуков (marchukov.ivan at gmail.com)
Date: 2024-01-22T08:50:52+02:00

Commit Message:
SCI: Fix after code review

Changed paths:
    engines/sci/detection_tables.h
    engines/sci/parser/vocabulary.cpp


diff --git a/engines/sci/detection_tables.h b/engines/sci/detection_tables.h
index 4a6a7b8bd95..1c891c92529 100644
--- a/engines/sci/detection_tables.h
+++ b/engines/sci/detection_tables.h
@@ -432,7 +432,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
 		{"resource.002", 0, "8e1a3a8c588007404b532b8dfacc1460", 722250},
 		{"resource.003", 0, "8e1a3a8c588007404b532b8dfacc1460", 723712},
 		{"resource.004", 0, "8e1a3a8c588007404b532b8dfacc1460", 729143},
-		{"Translate.RU", 0, "3f730611f55257821b964f96eafea0ba", 171}, // Text file for translate detection
+		{"Translate.RU", 0, "3f730611f55257821b964f96eafea0ba", 171}, // Text file for detecting translation
 		AD_LISTEND},
 		Common::RU_RUS, Common::kPlatformDOS, 0, GUIO_STD16_UNDITHER	},
 
@@ -2638,7 +2638,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
 		{"resource.008", 0, "e45c888d9c7c04aec0a20e9f820b79ff", 352345},
 		{"resource.009", 0, "e45c888d9c7c04aec0a20e9f820b79ff", 257355},
 		{"resource.010", 0, "e45c888d9c7c04aec0a20e9f820b79ff", 356093},
-		{"Translate.RU", 0, "3f730611f55257821b964f96eafea0ba", 171}, // Text file for translate detection
+		{"Translate.RU", 0, "3f730611f55257821b964f96eafea0ba", 171}, // Text file for detecting translation
 		AD_LISTEND},
 		Common::RU_RUS, Common::kPlatformDOS, 0, GUIO_STD16_UNDITHER	},
 
@@ -4302,7 +4302,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
 		{"resource.001", 0, "77f02def3094af804fd2371db25b7100", 509525},
 		{"resource.002", 0, "77f02def3094af804fd2371db25b7100", 546000},
 		{"resource.003", 0, "77f02def3094af804fd2371db25b7100", 591851},
-		{"Translate.RU", 0, "3f730611f55257821b964f96eafea0ba", 171}, // Text file for translate detection
+		{"Translate.RU", 0, "3f730611f55257821b964f96eafea0ba", 171}, // Text file for detecting translation
 		AD_LISTEND},
 		Common::RU_RUS, Common::kPlatformDOS, 0, GUIO_STD16_UNDITHER	},
 
diff --git a/engines/sci/parser/vocabulary.cpp b/engines/sci/parser/vocabulary.cpp
index 2b43f997534..5c64ee5aba2 100644
--- a/engines/sci/parser/vocabulary.cpp
+++ b/engines/sci/parser/vocabulary.cpp
@@ -195,14 +195,14 @@ bool Vocabulary::loadParserWords() {
 	return true;
 }
 
-void Vocabulary::loadTranslatedWords()
-{
+void Vocabulary::loadTranslatedWords() {
 	// This is special fan made format similar to VOCAB.000 (see
 	// https://wiki.scummvm.org/index.php?title=SCI/Specifications/SCI_in_action/Parser#Vocabulary_file_formats)
 	// but all characters used are in the upper character range (80h..FFh)
 
 	Resource *resource = _resMan->findResource(ResourceId(kResourceTypeVocab, VOCAB_RESOURCE_SCUMM_LOC_VOCAB), 0);
-	if (!resource) return;
+	if (!resource)
+		return;
 	
 	char currentWord[VOCAB_MAX_WORDLENGTH] = "";
 	int currentWordPos = 0;
@@ -214,7 +214,7 @@ void Vocabulary::loadTranslatedWords()
 		currentWordPos = resource->getUint8At(seeker++); // Parts of previous words may be re-used
 
 		do {
-			if (seeker == resource->size()) {
+			if (seeker >= resource->size()) {
 				return;
 			}
 			c = resource->getUint8At(seeker++);
@@ -222,10 +222,6 @@ void Vocabulary::loadTranslatedWords()
 			currentWord[currentWordPos++] = (c & 0x7f) | 0x80; // add 0x80 for upper character table
 		} while (c < 0x80);
 
-		if (seeker == resource->size()) {
-			return;
-		}
-
 		currentWord[currentWordPos] = 0;
 
 		// Now decode class and group:




More information about the Scummvm-git-logs mailing list