[Scummvm-git-logs] scummvm master -> 8a87d1030c706db7fede0b5ece0aeabdf1a671cb

sluicebox noreply at scummvm.org
Mon Dec 13 18:45:44 UTC 2021


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

Summary:
b38d5b28ba SCI: kTextSize cleanup
8a87d1030c SCI: Fix newline handling in Japanese PQ2


Commit: b38d5b28ba2cbf3844ab75b005a91b138f515182
    https://github.com/scummvm/scummvm/commit/b38d5b28ba2cbf3844ab75b005a91b138f515182
Author: sluicebox (22204938+sluicebox at users.noreply.github.com)
Date: 2021-12-13T11:29:23-07:00

Commit Message:
SCI: kTextSize cleanup

Changed paths:
    engines/sci/engine/kgraphics.cpp


diff --git a/engines/sci/engine/kgraphics.cpp b/engines/sci/engine/kgraphics.cpp
index 8455ef048e..94a42d9544 100644
--- a/engines/sci/engine/kgraphics.cpp
+++ b/engines/sci/engine/kgraphics.cpp
@@ -331,38 +331,38 @@ reg_t kGraphSaveUpscaledHiresBox(EngineState *s, int argc, reg_t *argv) {
 }
 
 reg_t kTextSize(EngineState *s, int argc, reg_t *argv) {
-	int16 textWidth, textHeight;
-	Common::String text = s->_segMan->getString(argv[1]);
 	reg_t *dest = s->_segMan->derefRegPtr(argv[0], 4);
-	int maxwidth = (argc > 3) ? argv[3].toUint16() : 0;
-	int font_nr = argv[2].toUint16();
+	Common::String text = s->_segMan->getString(argv[1]);
+	int font = argv[2].toUint16();
+	int maxWidth = (argc > 3) ? argv[3].toUint16() : 0;
 
 	if (!dest) {
 		debugC(kDebugLevelStrings, "GetTextSize: Empty destination");
 		return s->r_acc;
 	}
 
-	Common::String sep_str;
-	const char *sep = nullptr;
+	const char *separator = nullptr;
 	if ((argc > 4) && (argv[4].getSegment())) {
-		sep_str = s->_segMan->getString(argv[4]);
-		sep = sep_str.c_str();
+		Common::String separatorString = s->_segMan->getString(argv[4]);
+		separator = separatorString.c_str();
 	}
 
-	dest[0] = dest[1] = NULL_REG;
+	dest[0] = NULL_REG;
+	dest[1] = NULL_REG;
 
 	if (text.empty()) { // Empty text
-		dest[2] = dest[3] = make_reg(0, 0);
+		dest[2] = NULL_REG;
+		dest[3] = NULL_REG;
 		debugC(kDebugLevelStrings, "GetTextSize: Empty string");
 		return s->r_acc;
 	}
 
-	textWidth = dest[3].toUint16(); textHeight = dest[2].toUint16();
-
 	uint16 languageSplitter = 0;
-	Common::String splitText = g_sci->strSplitLanguage(text.c_str(), &languageSplitter, sep);
+	Common::String splitText = g_sci->strSplitLanguage(text.c_str(), &languageSplitter, separator);
 
-	g_sci->_gfxText16->kernelTextSize(splitText.c_str(), languageSplitter, font_nr, maxwidth, &textWidth, &textHeight);
+	int16 textWidth;
+	int16 textHeight;
+	g_sci->_gfxText16->kernelTextSize(splitText.c_str(), languageSplitter, font, maxWidth, &textWidth, &textHeight);
 
 	// One of the game texts in LB2 German contains loads of spaces in
 	// its end. We trim the text here, otherwise the graphics code will
@@ -378,7 +378,7 @@ reg_t kTextSize(EngineState *s, int argc, reg_t *argv) {
 			// Copy over the trimmed string...
 			s->_segMan->strcpy(argv[1], text.c_str());
 			// ...and recalculate bounding box dimensions
-			g_sci->_gfxText16->kernelTextSize(splitText.c_str(), languageSplitter, font_nr, maxwidth, &textWidth, &textHeight);
+			g_sci->_gfxText16->kernelTextSize(splitText.c_str(), languageSplitter, font, maxWidth, &textWidth, &textHeight);
 		}
 	}
 


Commit: 8a87d1030c706db7fede0b5ece0aeabdf1a671cb
    https://github.com/scummvm/scummvm/commit/8a87d1030c706db7fede0b5ece0aeabdf1a671cb
Author: sluicebox (22204938+sluicebox at users.noreply.github.com)
Date: 2021-12-13T11:43:35-07:00

Commit Message:
SCI: Fix newline handling in Japanese PQ2

Many PQ2 Japanese strings contain escaped newlines ("\n") which we have
not been handling. We have been handling these in getSciLanguageString()
when returning Japanese text but that's not where SSCI does this work.
PQ2's Print procedure in script 255 parses Japanese text itself and our
getSciLanguageString() is never involved.

Now Japanese newline handling is done in the core text measuring and
drawing functions, which is closer to where SSCI did it, but without the
hack of having GetLongest() patch out Japanese newlines like in SSCI.

Fixes bug #13154

Changed paths:
    engines/sci/engine/state.cpp
    engines/sci/graphics/text16.cpp
    engines/sci/graphics/text16.h
    engines/sci/sci.h


diff --git a/engines/sci/engine/state.cpp b/engines/sci/engine/state.cpp
index d78718036a..9b5ab9acb4 100644
--- a/engines/sci/engine/state.cpp
+++ b/engines/sci/engine/state.cpp
@@ -261,24 +261,6 @@ Common::String SciEngine::getSciLanguageString(const Common::String &str, kLangu
 				switch (curChar) {
 				case 0: // Terminator NUL
 					return fullWidth;
-				case '\\':
-					// "\n", "\N", "\r" and "\R" were overwritten with SPACE + 0x0D in PC-9801 SSCI
-					//  inside GetLongest() (text16). We do it here, because it's much cleaner and
-					//  we have to process the text here anyway.
-					//  Occurs for example in Police Quest 2 intro
-					curChar2 = *(textPtr + 1);
-					switch (curChar2) {
-					case 'n':
-					case 'N':
-					case 'r':
-					case 'R':
-						fullWidth += ' ';
-						fullWidth += 0x0D; // CR
-						textPtr += 2;
-						continue;
-					default:
-						break;
-					}
 				default:
 					break;
 				}
diff --git a/engines/sci/graphics/text16.cpp b/engines/sci/graphics/text16.cpp
index 2ed898ddab..11238b0124 100644
--- a/engines/sci/graphics/text16.cpp
+++ b/engines/sci/graphics/text16.cpp
@@ -202,6 +202,7 @@ int16 GfxText16::GetLongest(const char *&textPtr, int16 maxWidth, GuiResourceId
 	uint16 curWidth = 0, tempWidth = 0;
 	GuiResourceId previousFontId = GetFontId();
 	int16 previousPenColor = _ports->_curPort->penClr;
+	bool escapedNewLine = false;
 
 	GetFont();
 	if (!_font)
@@ -212,6 +213,14 @@ int16 GfxText16::GetLongest(const char *&textPtr, int16 maxWidth, GuiResourceId
 		if (_font->isDoubleByte(curChar)) {
 			curChar |= (*(const byte *)(textPtr + 1)) << 8;
 		}
+		if (escapedNewLine) {
+			escapedNewLine = false;
+			curChar = 0x0D;
+		} else if (isJapaneseNewLine(curChar, *(textPtr + 1))) {
+			escapedNewLine = true;
+			curChar = ' ';
+		}
+
 		switch (curChar) {
 		case 0x7C:
 			if (getSciVersion() >= SCI_VERSION_1_1) {
@@ -373,6 +382,7 @@ void GfxText16::Width(const char *text, int16 from, int16 len, GuiResourceId org
 	int16 previousPenColor = _ports->_curPort->penClr;
 
 	textWidth = 0; textHeight = 0;
+	bool escapedNewLine = false;
 
 	GetFont();
 	if (_font) {
@@ -383,6 +393,14 @@ void GfxText16::Width(const char *text, int16 from, int16 len, GuiResourceId org
 				curChar |= (*(const byte *)text++) << 8;
 				len--;
 			}
+			if (escapedNewLine) {
+				escapedNewLine = false;
+				curChar = 0x0D;
+			} else if (isJapaneseNewLine(curChar, *text)) {
+				escapedNewLine = true;
+				curChar = ' ';
+			}
+
 			switch (curChar) {
 			case 0x0A:
 			case 0x0D:
@@ -490,12 +508,21 @@ void GfxText16::Draw(const char *text, int16 from, int16 len, GuiResourceId orgF
 	rect.top = _ports->_curPort->curTop;
 	rect.bottom = rect.top + _ports->_curPort->fontHeight;
 	text += from;
+	bool escapedNewLine = false;
 	while (len--) {
 		curChar = (*(const byte *)text++);
 		if (_font->isDoubleByte(curChar)) {
 			curChar |= (*(const byte *)text++) << 8;
 			len--;
 		}
+		if (escapedNewLine) {
+			escapedNewLine = false;
+			curChar = 0x0D;
+		} else if (isJapaneseNewLine(curChar, *text)) {
+			escapedNewLine = true;
+			curChar = ' ';
+		}
+
 		switch (curChar) {
 		case 0x0A:
 		case 0x0D:
@@ -735,6 +762,17 @@ bool GfxText16::SwitchToFont900OnSjis(const char *text, uint16 languageSplitter)
 	return false;
 }
 
+// In PC-9801 SSCI, "\n", "\N", "\r" and "\R" were overwritten with SPACE + 0x0D
+// inside GetLongest() (text16). This was a bit of a hack since it meant this
+// version altered the input that it's normally only supposed to be measuring.
+// Instead, we detect the newline sequences during string processing loops and
+// apply the substitute characters on the fly. PQ2 is the only game known to use
+// this feature. "\n" appears in most of its Japanese strings.
+bool GfxText16::isJapaneseNewLine(int16 curChar, int16 nextChar) {
+	return g_sci->getLanguage() == Common::JA_JPN &&
+		curChar == '\\' && (nextChar == 'n' || nextChar == 'N' || nextChar == 'r' || nextChar == 'R');
+}
+
 reg_t GfxText16::allocAndFillReferenceRectArray() {
 	uint rectCount = _codeRefRects.size();
 	if (rectCount) {
diff --git a/engines/sci/graphics/text16.h b/engines/sci/graphics/text16.h
index 1f53c5b4b0..d00e4bd9ba 100644
--- a/engines/sci/graphics/text16.h
+++ b/engines/sci/graphics/text16.h
@@ -80,6 +80,7 @@ private:
 	void init();
 	bool SwitchToFont1001OnKorean(const char *text, uint16 languageSplitter);
 	bool SwitchToFont900OnSjis(const char *text, uint16 languageSplitter);
+	static bool isJapaneseNewLine(int16 curChar, int16 nextChar);
 
 	GfxCache *_cache;
 	GfxPorts *_ports;
diff --git a/engines/sci/sci.h b/engines/sci/sci.h
index 6ca99befe2..85491bb5b8 100644
--- a/engines/sci/sci.h
+++ b/engines/sci/sci.h
@@ -228,7 +228,7 @@ public:
 	void setSciLanguage(kLanguage lang);
 	void setSciLanguage();
 
-	Common::String getSciLanguageString(const Common::String &str, kLanguage lang, kLanguage *lang2 = NULL, uint16 *languageSplitter = NULL) const;
+	Common::String getSciLanguageString(const Common::String &str, kLanguage requestedLanguage, kLanguage *secondaryLanguage = nullptr, uint16 *languageSplitter = nullptr) const;
 
 	// Check if vocabulary needs to get switched (in multilingual parser games)
 	void checkVocabularySwitch();




More information about the Scummvm-git-logs mailing list