[Scummvm-git-logs] scummvm branch-3-0 -> 3e6309674d706a33a4a779f64d43d95314b92621

sluicebox noreply at scummvm.org
Fri Dec 5 03:54:26 UTC 2025


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

Summary:
dcebd13de0 AGI: Fix RTL display for wrapped strings
69d5ef4d56 AGI: move display RTL prep into its own function
e0d82db705 AGI: In text.cpp remove intermediate static buffer for RTL preparation
3c2183895c AGI: restore default display() behavior
3e6309674d AGI: Update function signature in RTL code


Commit: dcebd13de021ad550dba5d90a79a055a5e78be51
    https://github.com/scummvm/scummvm/commit/dcebd13de021ad550dba5d90a79a055a5e78be51
Author: Sam Davidoff (sam at mfbtech.com)
Date: 2025-12-04T19:53:26-08:00

Commit Message:
AGI: Fix RTL display for wrapped strings

Word wrap text before calculating RTL position, and handle
multi-line and single-line text separately.

Changed paths:
    engines/agi/text.cpp


diff --git a/engines/agi/text.cpp b/engines/agi/text.cpp
index 56fb852ecf7..b2b0e4c8b45 100644
--- a/engines/agi/text.cpp
+++ b/engines/agi/text.cpp
@@ -247,13 +247,43 @@ void TextMgr::display(int16 textNr, int16 textRow, int16 textColumn) {
 	if (textNr >= 1 && textNr <= _vm->_game._curLogic->numTexts) {
 		logicTextPtr = _vm->_game._curLogic->texts[textNr - 1];
 		processedTextPtr = stringPrintf(logicTextPtr);
-		// For RTL languages, adjust the cursor position to right-align text
+
+		// Word wrap first to get the actual display width
+		int16 calculatedWidth = 0;
+		processedTextPtr = stringWordWrap(processedTextPtr, 40, &calculatedWidth);
+
+		// For RTL languages, right-align text (mirroring LTR behavior)
 		if (_vm->isLanguageRTL()) {
-			int textLength = strlen(processedTextPtr);
-			textColumn = MAX<int16>(0, 40 - textColumn - textLength);
-			charPos_Set(textRow, textColumn);
+			if (strchr(processedTextPtr, '\n') != nullptr) {
+				// For long strings that require a word wrap, we rely on the padding
+				// provided by rightAlign() in displayText() to handle the
+				// alignment. We only pad to 39 columns, because padding to 40
+				// leads to an extra row being inserted since the newline char
+				// pushes the line length to 40. The result is that word-wrapped
+				// lines in RTL always start indented one column. This is unavoidable
+				// without a much more significant change to word wrapping. If
+				// you need a line to start exactly on the right edge, then 
+				// manually split up the string into lines of 39 chars or less.
+				charPos_Set(textRow, 0);
+				_messageState.textSize_Width = 39;
+				// Prepend spaces for first-line indent. This mimics the behavior
+				// of LTR text, where the textColumn value determines the indent
+				// of the first line.
+				Common::String padded;
+				for (int16 i = 0; i < textColumn ; i++)
+					padded += ' ';
+				padded += processedTextPtr;
+				// Need to use a static buffer since processedTextPtr points to one
+				static char rtlBuffer[2000];
+				Common::strlcpy(rtlBuffer, padded.c_str(), sizeof(rtlBuffer));
+				processedTextPtr = rtlBuffer;
+			} else {
+				// For single (non-wrapped) lines, we simply manual position them
+				// indented in from the right to get RTL alignment
+				textColumn = MAX<int16>(0, 40 - textColumn - calculatedWidth);
+				charPos_Set(textRow, textColumn);
+			}
 		}
-		processedTextPtr = stringWordWrap(processedTextPtr, 40);
 
 #ifdef USE_TTS
 		if (!_vm->_game.gfxMode) {


Commit: 69d5ef4d56b695095320d0ed0ed573430d0edcc1
    https://github.com/scummvm/scummvm/commit/69d5ef4d56b695095320d0ed0ed573430d0edcc1
Author: Sam Davidoff (sam at mfbtech.com)
Date: 2025-12-04T19:53:34-08:00

Commit Message:
AGI: move display RTL prep into its own function

Changed paths:
    engines/agi/text.cpp
    engines/agi/text.h


diff --git a/engines/agi/text.cpp b/engines/agi/text.cpp
index b2b0e4c8b45..8448ae89116 100644
--- a/engines/agi/text.cpp
+++ b/engines/agi/text.cpp
@@ -242,47 +242,19 @@ void TextMgr::display(int16 textNr, int16 textRow, int16 textColumn) {
 	char *processedTextPtr   = nullptr;
 
 	charPos_Push();
-	charPos_Set(textRow, textColumn);
 
 	if (textNr >= 1 && textNr <= _vm->_game._curLogic->numTexts) {
 		logicTextPtr = _vm->_game._curLogic->texts[textNr - 1];
 		processedTextPtr = stringPrintf(logicTextPtr);
 
-		// Word wrap first to get the actual display width
 		int16 calculatedWidth = 0;
 		processedTextPtr = stringWordWrap(processedTextPtr, 40, &calculatedWidth);
 
-		// For RTL languages, right-align text (mirroring LTR behavior)
 		if (_vm->isLanguageRTL()) {
-			if (strchr(processedTextPtr, '\n') != nullptr) {
-				// For long strings that require a word wrap, we rely on the padding
-				// provided by rightAlign() in displayText() to handle the
-				// alignment. We only pad to 39 columns, because padding to 40
-				// leads to an extra row being inserted since the newline char
-				// pushes the line length to 40. The result is that word-wrapped
-				// lines in RTL always start indented one column. This is unavoidable
-				// without a much more significant change to word wrapping. If
-				// you need a line to start exactly on the right edge, then 
-				// manually split up the string into lines of 39 chars or less.
-				charPos_Set(textRow, 0);
-				_messageState.textSize_Width = 39;
-				// Prepend spaces for first-line indent. This mimics the behavior
-				// of LTR text, where the textColumn value determines the indent
-				// of the first line.
-				Common::String padded;
-				for (int16 i = 0; i < textColumn ; i++)
-					padded += ' ';
-				padded += processedTextPtr;
-				// Need to use a static buffer since processedTextPtr points to one
-				static char rtlBuffer[2000];
-				Common::strlcpy(rtlBuffer, padded.c_str(), sizeof(rtlBuffer));
-				processedTextPtr = rtlBuffer;
-			} else {
-				// For single (non-wrapped) lines, we simply manual position them
-				// indented in from the right to get RTL alignment
-				textColumn = MAX<int16>(0, 40 - textColumn - calculatedWidth);
-				charPos_Set(textRow, textColumn);
-			}
+			// handles setting cursor position and processing string for proper RTL alignment
+			processedTextPtr = displayAdjustRTL(textRow, textColumn, processedTextPtr, calculatedWidth);
+		} else {
+			charPos_Set(textRow, textColumn);
 		}
 
 #ifdef USE_TTS
@@ -315,6 +287,40 @@ void TextMgr::display(int16 textNr, int16 textRow, int16 textColumn) {
 	charPos_Pop();
 }
 
+char *TextMgr::displayAdjustRTL(int16 textRow, int16 textColumn, char *text, int16 calculatedWidth) {
+	static char rtlBuffer[2000];
+
+	if (strchr(text, '\n') != nullptr) {
+		// For multi-line strings, we rely on the padding provided by
+		// rightAlign() in displayText() to handle alignment. 
+		// Accordingloy, row position is set to 0 because alignment will
+		// be handled by rightAlign()'s zero padding
+		charPos_Set(textRow, 0);
+
+                // We only pad to 39 columns, because padding to 40 leads to an extra 
+		// row being inserted since the newline pushes the line length past 40. 
+		// The result is that word-wrapped lines in RTL always start indented
+		// one column from the right edge.
+		_messageState.textSize_Width = 39;
+
+		// Prepend spaces for first-line indent. This mimics the behavior
+		// of LTR text, where textColumn determines the first line indent.
+		Common::String padded;
+		for (int16 i = 0; i < textColumn; i++)
+			padded += ' ';
+		padded += text;
+		Common::strlcpy(rtlBuffer, padded.c_str(), sizeof(rtlBuffer));
+
+		return rtlBuffer;
+	} else {
+		// For single lines, we directly position them indented from the right edge
+		textColumn = MAX<int16>(0, 40 - textColumn - calculatedWidth);
+		charPos_Set(textRow, textColumn);
+
+		return text;
+	}
+}
+
 void TextMgr::displayTextInsideWindow(const char *textPtr, int16 windowRow, int16 windowColumn) {
 	if (!_messageState.window_Active)
 		return;
diff --git a/engines/agi/text.h b/engines/agi/text.h
index ad94a94e84a..ef0f4001256 100644
--- a/engines/agi/text.h
+++ b/engines/agi/text.h
@@ -120,6 +120,7 @@ public:
 	byte calculateTextBackground(byte background);
 
 	void display(int16 textNr, int16 textRow, int16 textColumn);
+	char *displayAdjustRTL(int16 textRow, int16 textColumn, char *text, int16 calculatedWidth);
 	void displayText(const char *textPtr, bool disabledLook = false);
 	void displayCharacter(byte character, bool disabledLook = false);
 


Commit: e0d82db705b8d1f28b8f19d5a51f4091ac174d14
    https://github.com/scummvm/scummvm/commit/e0d82db705b8d1f28b8f19d5a51f4091ac174d14
Author: Sam Davidoff (sam at mfbtech.com)
Date: 2025-12-04T19:53:48-08:00

Commit Message:
AGI: In text.cpp remove intermediate static buffer for RTL preparation

Changed paths:
    engines/agi/text.cpp


diff --git a/engines/agi/text.cpp b/engines/agi/text.cpp
index 8448ae89116..9201ba64fbf 100644
--- a/engines/agi/text.cpp
+++ b/engines/agi/text.cpp
@@ -288,37 +288,35 @@ void TextMgr::display(int16 textNr, int16 textRow, int16 textColumn) {
 }
 
 char *TextMgr::displayAdjustRTL(int16 textRow, int16 textColumn, char *text, int16 calculatedWidth) {
-	static char rtlBuffer[2000];
-
 	if (strchr(text, '\n') != nullptr) {
-		// For multi-line strings, we rely on the padding provided by
-		// rightAlign() in displayText() to handle alignment. 
-		// Accordingloy, row position is set to 0 because alignment will
-		// be handled by rightAlign()'s zero padding
+		// For multi-line strings, we rely on rightAlign() in displayText() 
+		// to pad each line to get proper right-alignment appearance.
 		charPos_Set(textRow, 0);
 
-                // We only pad to 39 columns, because padding to 40 leads to an extra 
-		// row being inserted since the newline pushes the line length past 40. 
+		// We only pad to 39 columns, because padding to 40 leads to an extra
+		// row being inserted since the newline pushes the line length past 40.
 		// The result is that word-wrapped lines in RTL always start indented
 		// one column from the right edge.
 		_messageState.textSize_Width = 39;
 
 		// Prepend spaces for first-line indent. This mimics the behavior
 		// of LTR text, where textColumn determines the first line indent.
+		// NOTE: This doesn't work perfectly if the first line's line break
+		// is autogenerated by word-wrapping because that happens before the
+		// indent is set. In that case, use a manual line break in your
+		// message to ensure you don't have more text than your indent
+		// position can accomodate
 		Common::String padded;
 		for (int16 i = 0; i < textColumn; i++)
 			padded += ' ';
 		padded += text;
-		Common::strlcpy(rtlBuffer, padded.c_str(), sizeof(rtlBuffer));
-
-		return rtlBuffer;
+		Common::strlcpy(text, padded.c_str(), 2000);
 	} else {
-		// For single lines, we directly position them indented from the right edge
+		// For single lines, position them indented from the right edge
 		textColumn = MAX<int16>(0, 40 - textColumn - calculatedWidth);
 		charPos_Set(textRow, textColumn);
-
-		return text;
 	}
+	return text;
 }
 
 void TextMgr::displayTextInsideWindow(const char *textPtr, int16 windowRow, int16 windowColumn) {


Commit: 3c2183895c642108eeb109ae72bc294b32d5d107
    https://github.com/scummvm/scummvm/commit/3c2183895c642108eeb109ae72bc294b32d5d107
Author: Sam Davidoff (sam at mfbtech.com)
Date: 2025-12-04T19:53:55-08:00

Commit Message:
AGI: restore default display() behavior

Changed paths:
    engines/agi/text.cpp


diff --git a/engines/agi/text.cpp b/engines/agi/text.cpp
index 9201ba64fbf..33ea9f9be2a 100644
--- a/engines/agi/text.cpp
+++ b/engines/agi/text.cpp
@@ -242,6 +242,7 @@ void TextMgr::display(int16 textNr, int16 textRow, int16 textColumn) {
 	char *processedTextPtr   = nullptr;
 
 	charPos_Push();
+	charPos_Set(textRow, textColumn);
 
 	if (textNr >= 1 && textNr <= _vm->_game._curLogic->numTexts) {
 		logicTextPtr = _vm->_game._curLogic->texts[textNr - 1];
@@ -253,9 +254,7 @@ void TextMgr::display(int16 textNr, int16 textRow, int16 textColumn) {
 		if (_vm->isLanguageRTL()) {
 			// handles setting cursor position and processing string for proper RTL alignment
 			processedTextPtr = displayAdjustRTL(textRow, textColumn, processedTextPtr, calculatedWidth);
-		} else {
-			charPos_Set(textRow, textColumn);
-		}
+		} 
 
 #ifdef USE_TTS
 		if (!_vm->_game.gfxMode) {


Commit: 3e6309674d706a33a4a779f64d43d95314b92621
    https://github.com/scummvm/scummvm/commit/3e6309674d706a33a4a779f64d43d95314b92621
Author: sluicebox (22204938+sluicebox at users.noreply.github.com)
Date: 2025-12-04T19:54:05-08:00

Commit Message:
AGI: Update function signature in RTL code

Changed paths:
    engines/agi/text.cpp
    engines/agi/text.h


diff --git a/engines/agi/text.cpp b/engines/agi/text.cpp
index 33ea9f9be2a..cc02816bce7 100644
--- a/engines/agi/text.cpp
+++ b/engines/agi/text.cpp
@@ -253,7 +253,7 @@ void TextMgr::display(int16 textNr, int16 textRow, int16 textColumn) {
 
 		if (_vm->isLanguageRTL()) {
 			// handles setting cursor position and processing string for proper RTL alignment
-			processedTextPtr = displayAdjustRTL(textRow, textColumn, processedTextPtr, calculatedWidth);
+			displayAdjustRTL(textRow, textColumn, processedTextPtr, calculatedWidth);
 		} 
 
 #ifdef USE_TTS
@@ -286,7 +286,7 @@ void TextMgr::display(int16 textNr, int16 textRow, int16 textColumn) {
 	charPos_Pop();
 }
 
-char *TextMgr::displayAdjustRTL(int16 textRow, int16 textColumn, char *text, int16 calculatedWidth) {
+void TextMgr::displayAdjustRTL(int16 textRow, int16 textColumn, char *text, int16 calculatedWidth) {
 	if (strchr(text, '\n') != nullptr) {
 		// For multi-line strings, we rely on rightAlign() in displayText() 
 		// to pad each line to get proper right-alignment appearance.
@@ -304,7 +304,7 @@ char *TextMgr::displayAdjustRTL(int16 textRow, int16 textColumn, char *text, int
 		// is autogenerated by word-wrapping because that happens before the
 		// indent is set. In that case, use a manual line break in your
 		// message to ensure you don't have more text than your indent
-		// position can accomodate
+		// position can accommodate
 		Common::String padded;
 		for (int16 i = 0; i < textColumn; i++)
 			padded += ' ';
@@ -315,7 +315,6 @@ char *TextMgr::displayAdjustRTL(int16 textRow, int16 textColumn, char *text, int
 		textColumn = MAX<int16>(0, 40 - textColumn - calculatedWidth);
 		charPos_Set(textRow, textColumn);
 	}
-	return text;
 }
 
 void TextMgr::displayTextInsideWindow(const char *textPtr, int16 windowRow, int16 windowColumn) {
diff --git a/engines/agi/text.h b/engines/agi/text.h
index ef0f4001256..54d61530ed3 100644
--- a/engines/agi/text.h
+++ b/engines/agi/text.h
@@ -120,7 +120,7 @@ public:
 	byte calculateTextBackground(byte background);
 
 	void display(int16 textNr, int16 textRow, int16 textColumn);
-	char *displayAdjustRTL(int16 textRow, int16 textColumn, char *text, int16 calculatedWidth);
+	void displayAdjustRTL(int16 textRow, int16 textColumn, char *text, int16 calculatedWidth);
 	void displayText(const char *textPtr, bool disabledLook = false);
 	void displayCharacter(byte character, bool disabledLook = false);
 




More information about the Scummvm-git-logs mailing list