[Scummvm-git-logs] scummvm master -> f059104708e4a95fd3a52d2ea6041f89604e45db

sdelamarre noreply at scummvm.org
Wed Sep 24 21:39:13 UTC 2025


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

Summary:
37c99eac12 GOB: Copy Draw_v2::printTotText to Draw_Playtoons before specializing it
b7d2a7f7b3 GOB: Fixes in drawButton()
f059104708 GOB: Implement printTotText() extensions found in Adi4


Commit: 37c99eac126df2134d8a421c38eecc07fc2b0641
    https://github.com/scummvm/scummvm/commit/37c99eac126df2134d8a421c38eecc07fc2b0641
Author: Simon Delamarre (simon.delamarre14 at gmail.com)
Date: 2025-09-24T23:38:29+02:00

Commit Message:
GOB: Copy Draw_v2::printTotText to Draw_Playtoons before specializing it

Changed paths:
    engines/gob/draw.h
    engines/gob/draw_playtoons.cpp


diff --git a/engines/gob/draw.h b/engines/gob/draw.h
index 74bf5cd85f8..6653093d7af 100644
--- a/engines/gob/draw.h
+++ b/engines/gob/draw.h
@@ -313,6 +313,7 @@ class Draw_Playtoons: public Draw_v2 {
 public:
 	Draw_Playtoons(GobEngine *vm);
 	~Draw_Playtoons() override {}
+	void printTotText(int16 id) override;
 	void spriteOperation(int16 operation, bool ttsAddHotspotText = true) override;
 };
 
diff --git a/engines/gob/draw_playtoons.cpp b/engines/gob/draw_playtoons.cpp
index aa8118a0cec..96b0bc9b046 100644
--- a/engines/gob/draw_playtoons.cpp
+++ b/engines/gob/draw_playtoons.cpp
@@ -28,16 +28,468 @@
 #include "common/endian.h"
 
 #include "gob/draw.h"
-#include "gob/inter.h"
 #include "gob/game.h"
-#include "gob/resources.h"
+#include "gob/global.h"
+#include "gob/inter.h"
 #include "gob/hotspots.h"
+#include "gob/resources.h"
+#include "gob/scenery.h"
+#include "gob/script.h"
 
 namespace Gob {
 
 Draw_Playtoons::Draw_Playtoons(GobEngine *vm) : Draw_v2(vm) {
 }
 
+void Draw_Playtoons::printTotText(int16 id) {
+	byte *dataPtr;
+	byte *ptr, *ptrEnd;
+	byte cmd;
+	int16 savedFlags;
+	int16 destX, destY;
+	int16 spriteRight, spriteBottom;
+	int16 val;
+	int16 rectLeft, rectTop, rectRight, rectBottom;
+	int16 size;
+
+	id &= 0xFFF;
+
+	_vm->validateLanguage();
+
+	TextItem *textItem = _vm->_game->_resources->getTextItem(id);
+	if (!textItem)
+		return;
+
+	size    = textItem->getSize();
+	dataPtr = textItem->getData();
+	ptr     = dataPtr;
+	_pattern = 0;
+
+	bool isSubtitle = (ptr[1] & 0x80) != 0;
+
+	if (isSubtitle && !_vm->_global->_doSubtitles) {
+		delete textItem;
+		return;
+	}
+
+	if (_renderFlags & RENDERFLAG_DOUBLECOORDS) {
+		destX = (READ_LE_UINT16(ptr) & 0x7FFF) * 2;
+		spriteRight = READ_LE_UINT16(ptr + 4) * 2 + 1;
+	} else {
+		// No mask used for Fascination
+		destX = READ_LE_UINT16(ptr);
+		if (_vm->getGameType() != kGameTypeFascination)
+			destX &= 0x7FFF;
+		spriteRight = READ_LE_UINT16(ptr + 4);
+	}
+
+	if (_renderFlags & RENDERFLAG_FROMSPLIT) {
+		int16 start;
+
+		start = _vm->_video->_splitStart;
+
+		destY = start;
+		spriteBottom = READ_LE_UINT16(ptr + 6) - READ_LE_UINT16(ptr + 2);
+
+		if (_renderFlags & RENDERFLAG_DOUBLECOORDS)
+			spriteBottom *= 3;
+
+		spriteBottom += start;
+
+		if (_renderFlags & RENDERFLAG_DOUBLECOORDS) {
+			spriteBottom += _backDeltaY;
+			destY += _backDeltaY;
+		}
+	} else {
+		destY = READ_LE_UINT16(ptr + 2);
+		spriteBottom = READ_LE_UINT16(ptr + 6);
+
+		if (_renderFlags & RENDERFLAG_DOUBLECOORDS) {
+			destY *= 2;
+			spriteBottom *= 2;
+		}
+	}
+
+	ptr += 8;
+
+	if (_renderFlags & RENDERFLAG_CAPTUREPUSH) {
+		_vm->_game->capturePush(destX, destY,
+				spriteRight - destX + 1, spriteBottom - destY + 1);
+		(*_vm->_scenery->_pCaptureCounter)++;
+	}
+
+	_destSpriteX = destX;
+	_destSpriteY = destY;
+	_spriteRight = spriteRight;
+	_spriteBottom = spriteBottom;
+	_destSurface = kBackSurface;
+
+	_backColor = *ptr++;
+	_transparency = 1;
+
+	if ((_vm->getGameType() == kGameTypeAdibou2 ||
+		 _vm->getGameType() == kGameTypeAdi4) &&
+		_backColor == 16)
+		_backColor = -1;
+
+	spriteOperation(DRAW_CLEARRECT);
+
+	_backColor = 0;
+	savedFlags = _renderFlags;
+	_renderFlags &= ~RENDERFLAG_NOINVALIDATE;
+
+	while ((_destSpriteX = READ_LE_UINT16(ptr)) != -1) {
+		_destSpriteX += destX;
+		_destSpriteY = READ_LE_UINT16(ptr + 2) + destY;
+		_spriteRight = READ_LE_UINT16(ptr + 4) + destX;
+		_spriteBottom = READ_LE_UINT16(ptr + 6) + destY;
+		ptr += 8;
+
+		cmd = *ptr++;
+		switch ((cmd & 0xF0) >> 4) {
+		case 0:
+			_frontColor = cmd & 0xF;
+			spriteOperation(DRAW_DRAWLINE);
+			break;
+		case 1:
+			_frontColor = cmd & 0xF;
+			spriteOperation(DRAW_DRAWBAR);
+			break;
+		case 2:
+			_backColor = cmd & 0xF;
+			spriteOperation(DRAW_FILLRECTABS);
+			break;
+		default:
+			break;
+		}
+	}
+	ptr += 2;
+
+	ptrEnd = ptr;
+	while (((ptrEnd - dataPtr) < size) && (*ptrEnd != 1)) {
+		// Converting to unknown commands/characters to spaces
+		if ((_vm->_game->_script->getVersionMinor() < 2) && (*ptrEnd > 3) && (*ptrEnd < 32))
+			*ptrEnd = 32;
+
+		switch (*ptrEnd) {
+		case 1:
+			break;
+
+		case 2:
+		case 5:
+			ptrEnd += 5;
+			break;
+
+		case 3:
+		case 4:
+			ptrEnd += 2;
+			break;
+
+		case 6:
+			ptrEnd++;
+			switch (*ptrEnd & 0xC0) {
+			case 0x40:
+				ptrEnd += 9;
+				break;
+			case 0x80:
+				ptrEnd += 3;
+				break;
+			case 0xC0:
+				ptrEnd += 11;
+				break;
+			default:
+				ptrEnd++;
+				break;
+			}
+			break;
+
+		case 10:
+			ptrEnd += (ptrEnd[1] * 2) + 2;
+			break;
+
+		default:
+			ptrEnd++;
+			break;
+		}
+	}
+	ptrEnd++;
+
+	int16 fontIndex = 0, frontColor = 0;
+	int16 strPos = 0, strPos2 = -1, strPosBak;
+	int16 offX = 0, offY = 0;
+	int16 colId = 0;
+	int16 colCmd = 0;
+	int16 width;
+	int16 maskChar = 0;
+	char mask[80], str[80], buf[50];
+
+	memset(mask, 0, 80);
+	memset(str, ' ', 80);
+	_backColor = 0;
+	_transparency = 1;
+
+#ifdef USE_TTS
+	Common::String ttsMessage;
+#endif
+	while (true) {
+		if ((((*ptr >= 1) && (*ptr <= 7)) || (*ptr == 10)) && (strPos != 0)) {
+			str[MAX(strPos, strPos2)] = 0;
+			strPosBak = strPos;
+			width = strlen(str) * _fonts[fontIndex]->getCharWidth();
+			adjustCoords(1, &width, nullptr);
+
+			if (colCmd & 0x0F) {
+				rectLeft = offX - 2;
+				rectTop = offY - 2;
+				rectRight = offX + width + 1;
+				rectBottom = _fonts[fontIndex]->getCharHeight();
+				adjustCoords(1, &rectBottom, nullptr);
+				rectBottom += offY + 1;
+				adjustCoords(0, &rectLeft, &rectTop);
+				adjustCoords(2, &rectRight, &rectBottom);
+
+				if (colId != -1)
+					_vm->_game->_hotspots->add(colId + 0xD000, rectLeft, rectTop,
+							rectRight, rectBottom, (uint16) Hotspots::kTypeClick, 0, 0, 0, 0);
+
+				if (_needAdjust != 2)
+					printTextCentered(colCmd & 0x0F, rectLeft + 4, rectTop + 4,
+							rectRight - 4, rectBottom - 4, str, fontIndex, frontColor);
+				else
+					printTextCentered(colCmd & 0x0F, rectLeft + 2, rectTop + 2,
+							rectRight - 2, rectBottom - 2, str, fontIndex, frontColor);
+
+			} else {
+				_destSpriteX = offX;
+				_destSpriteY = offY;
+				_fontIndex   = fontIndex;
+				_frontColor  = frontColor;
+				_textToPrint = str;
+#ifdef USE_TTS
+				ttsMessage += _textToPrint;
+				ttsMessage += " ";
+#endif
+
+				if (isSubtitle) {
+					_fontIndex  = _subtitleFont;
+					_frontColor = _subtitleColor;
+				}
+
+				if (_needAdjust != 2) {
+					if ((_destSpriteX >= destX) && (_destSpriteY >= destY) &&
+					    (((_fonts[_fontIndex]->getCharHeight() / 2) + _destSpriteY - 1) <= spriteBottom)) {
+						while (((_destSpriteX + width - 1) > spriteRight) && (width > 0)) {
+							width -= _fonts[_fontIndex]->getCharWidth() / 2;
+							str[strlen(str) - 1] = '\0';
+						}
+						spriteOperation(DRAW_PRINTTEXT, false);
+					}
+				} else
+					spriteOperation(DRAW_PRINTTEXT, false);
+
+				width = strlen(str);
+				for (strPos = 0; strPos < width; strPos++) {
+					if (mask[strPos] == '\0')
+						continue;
+
+					rectLeft = _fonts[fontIndex]->getCharWidth();
+					rectTop = _fonts[fontIndex]->getCharHeight();
+					adjustCoords(1, &rectLeft, &rectTop);
+					_destSpriteX = strPos * rectLeft + offX;
+					_spriteRight = _destSpriteX + rectLeft - 1;
+					_spriteBottom = offY + rectTop;
+					_destSpriteY = _spriteBottom;
+					spriteOperation(DRAW_DRAWLINE);
+				}
+			}
+
+			rectLeft = 0;
+			for (int i = 0; i < strPosBak; i++)
+				rectLeft += _fonts[_fontIndex]->getCharWidth(str[i]);
+
+			adjustCoords(1, &rectLeft, nullptr);
+			offX += rectLeft;
+			strPos = 0;
+			strPos2 = -1;
+			memset(mask, 0, 80);
+			memset(str, ' ', 80);
+		}
+
+		if (*ptr == 1)
+			break;
+
+		cmd = *ptr;
+		switch ((uint8) cmd) {
+		case 2:
+		case 5:
+			ptr++;
+			offX = destX + (int16)READ_LE_UINT16(ptr);
+			offY = destY + (int16)READ_LE_UINT16(ptr + 2);
+			if (_renderFlags & RENDERFLAG_DOUBLECOORDS) {
+				offX += (int16)READ_LE_UINT16(ptr);
+				offY += (int16)READ_LE_UINT16(ptr + 2);
+			}
+			ptr += 4;
+			break;
+
+		case 3:
+			ptr++;
+			fontIndex = ((*ptr & 0xF0) >> 4) & 7;
+			frontColor = *ptr & 0x0F;
+			ptr++;
+
+			if (isSubtitle) {
+				_subtitleFont  = fontIndex;
+				_subtitleColor = frontColor;
+			}
+			break;
+
+		case 4:
+			ptr++;
+			frontColor = *ptr++;
+
+			if (isSubtitle)
+				_subtitleColor = frontColor;
+			break;
+
+		case 6:
+			ptr++;
+			colCmd = *ptr++;
+			colId = -1;
+			if (colCmd & 0x80) {
+				colId = (int16)READ_LE_UINT16(ptr);
+				ptr += 2;
+			}
+			if (colCmd & 0x40) {
+				rectLeft = destX + (int16)READ_LE_UINT16(ptr);
+				rectRight = destX + (int16)READ_LE_UINT16(ptr + 2);
+				rectTop = destY + (int16)READ_LE_UINT16(ptr + 4);
+				rectBottom = destY + (int16)READ_LE_UINT16(ptr + 6);
+				adjustCoords(2, &rectLeft, &rectTop);
+				adjustCoords(2, &rectRight, &rectBottom);
+				_vm->_game->_hotspots->add(colId + 0x0D000, rectLeft, rectTop,
+						rectRight, rectBottom, (uint16) Hotspots::kTypeClick, 0, 0, 0, 0);
+				ptr += 8;
+			}
+			break;
+
+		case 7:
+			ptr++;
+			colCmd = 0;
+			break;
+
+		case 8:
+			ptr++;
+			maskChar = 1;
+			break;
+
+		case 9:
+			ptr++;
+			maskChar = 0;
+			break;
+
+		case 10:
+			str[0] = (char) 255;
+			WRITE_LE_UINT16(str + 1, ptr - _vm->_game->_resources->getTexts());
+			str[3] = 0;
+			ptr++;
+			for (int i = *ptr++; i > 0; i--) {
+				mask[strPos++] = maskChar;
+				ptr += 2;
+			}
+			break;
+
+		default:
+			str[strPos] = (char) cmd;
+			// fall through
+		case 32:
+			mask[strPos++] = maskChar;
+			ptr++;
+			break;
+
+		case 186:
+			cmd = ptrEnd[17] & 0x7F;
+			if (cmd == 0) {
+				val = READ_LE_UINT16(ptrEnd + 18) * 4;
+				Common::sprintf_s(buf, "%d", (int32)VAR_OFFSET(val));
+			} else if (cmd == 1) {
+				val = READ_LE_UINT16(ptrEnd + 18) * 4;
+				Common::strlcpy(buf, GET_VARO_STR(val), 20);
+			} else {
+				val = READ_LE_UINT16(ptrEnd + 18) * 4;
+				Common::sprintf_s(buf, "%d", (int32)VAR_OFFSET(val));
+				if (buf[0] == '-') {
+					while (strlen(buf) - 1 < (uint32)ptrEnd[17]) {
+						_vm->_util->insertStr("0", buf, 1);
+					}
+				} else {
+					while (strlen(buf) - 1 < (uint32)ptrEnd[17]) {
+						_vm->_util->insertStr("0", buf, 0);
+					}
+				}
+				if (_vm->_global->_language == 2)
+					_vm->_util->insertStr(".", buf, strlen(buf) + 1 - ptrEnd[17]);
+				else
+					_vm->_util->insertStr(",", buf, strlen(buf) + 1 - ptrEnd[17]);
+			}
+			memcpy(str + strPos, buf, strlen(buf));
+			memset(mask, maskChar, strlen(buf));
+			if (ptrEnd[17] & 0x80) {
+				strPos2 = strPos + strlen(buf);
+				strPos++;
+				ptrEnd += 23;
+				ptr++;
+			} else {
+				strPos += strlen(buf);
+				if (ptr[1] != ' ') {
+					if ((ptr[1] == 2) &&
+							(((int16)READ_LE_UINT16(ptr + 4)) == _destSpriteY)) {
+						ptr += 5;
+						str[strPos] = ' ';
+						mask[strPos++] = maskChar;
+					}
+				} else {
+					str[strPos] = ' ';
+					mask[strPos++] = maskChar;
+					while (ptr[1] == ' ')
+						ptr++;
+					if ((ptr[1] == 2) &&
+							(((int16)READ_LE_UINT16(ptr + 4)) == _destSpriteY))
+						ptr += 5;
+				}
+				ptrEnd += 23;
+				ptr++;
+			}
+			break;
+		}
+	}
+
+#ifdef USE_TTS
+	if (_previousTot != ttsMessage && !isSubtitle) {
+		if (_vm->_game->_hotspots->hoveringOverHotspot()) {
+			_vm->sayText(ttsMessage);
+		} else {
+			_vm->sayText(ttsMessage, Common::TextToSpeechManager::QUEUE);
+		}
+
+		_previousTot = ttsMessage;
+	}
+#endif
+
+	delete textItem;
+	_renderFlags = savedFlags;
+
+	if (!(_renderFlags & RENDERFLAG_COLLISIONS))
+		return;
+
+	_vm->_game->_hotspots->check(0, 0);
+
+	if (*_vm->_scenery->_pCaptureCounter != 0) {
+		(*_vm->_scenery->_pCaptureCounter)--;
+		_vm->_game->capturePop(1);
+	}
+}
+
 void Draw_Playtoons::spriteOperation(int16 operation, bool ttsAddHotspotText) {
 	int16 len;
 	int16 x, y;


Commit: b7d2a7f7b3fa79b2654416851fee4878c0a0d0d2
    https://github.com/scummvm/scummvm/commit/b7d2a7f7b3fa79b2654416851fee4878c0a0d0d2
Author: Simon Delamarre (simon.delamarre14 at gmail.com)
Date: 2025-09-24T23:38:29+02:00

Commit Message:
GOB: Fixes in drawButton()

Changed paths:
    engines/gob/draw.cpp


diff --git a/engines/gob/draw.cpp b/engines/gob/draw.cpp
index e6b856de69f..41be49d0299 100644
--- a/engines/gob/draw.cpp
+++ b/engines/gob/draw.cpp
@@ -504,7 +504,7 @@ void Draw::printTextCentered(int16 id, int16 left, int16 top, int16 right,
 }
 
 void Draw::drawButton(uint16 id, int16 left, int16 top, int16 right, int16 bottom,
-		char *paramStr, int16 fontIndex, int16 var4, int16 shortId) {
+		char *paramStr, int16 fontIndex, int16 color, int16 shortId) {
 
 	int16 width;
 	char tmpStr[128];
@@ -523,9 +523,9 @@ void Draw::drawButton(uint16 id, int16 left, int16 top, int16 right, int16 botto
 		WRITE_VAR(20, (uint32) (right - left + 1));
 		WRITE_VAR(21, (uint32) (bottom - top + 1));
 
-		if (_vm->_game->_script->peekUint16(41) >= '4') {
+		if (_vm->_game->_script->getVersionMinor() >= 4) {
 			WRITE_VAR(22, (uint32) fontIndex);
-			WRITE_VAR(23, (uint32) var4);
+			WRITE_VAR(23, (uint32) color);
 			if (id & 0x8000)
 				WRITE_VAR(24, (uint32) 1);
 			else
@@ -551,8 +551,8 @@ void Draw::drawButton(uint16 id, int16 left, int16 top, int16 right, int16 botto
 	if (*paramStr) {
 		_transparency = 1;
 		_fontIndex = fontIndex;
-		_frontColor = var4;
-		if (_vm->_game->_script->peekUint16(41) >= '4' && strchr(paramStr, 92)) {
+		_frontColor = color;
+		if (_vm->_game->_script->getVersionMinor() >= 4 && strchr(paramStr, '\\')) {
 			char str[80];
 			char *str2;
 			int16 strLen= 0;
@@ -562,7 +562,7 @@ void Draw::drawButton(uint16 id, int16 left, int16 top, int16 right, int16 botto
 			do {
 				strLen++;
 				str2++;
-				str2 = strchr(str2, 92);
+				str2 = strchr(str2, '\\');
 			} while (str2);
 			deltaY = (bottom - right + 1 - (strLen * _fonts[fontIndex]->getCharHeight())) / (strLen + 1);
 			offY = right + deltaY;
@@ -582,14 +582,14 @@ void Draw::drawButton(uint16 id, int16 left, int16 top, int16 right, int16 botto
 			}
 		} else {
 			_destSpriteX = left;
-			if (_vm->_game->_script->peekUint16(41) >= '4')
-				_destSpriteY = right + (bottom - right + 1 - _fonts[fontIndex]->getCharHeight()) / 2;
+			if (_vm->_game->_script->getVersionMinor() >= 4)
+				_destSpriteY = top + (bottom - top + 1 - _fonts[fontIndex]->getCharHeight()) / 2;
 			else
-				_destSpriteY = right;
+				_destSpriteY = top;
 			_textToPrint = paramStr;
 			width = stringLength(paramStr, fontIndex);
 			adjustCoords(1, &width, nullptr);
-			_destSpriteX += (top - left + 1 - width) / 2;
+			_destSpriteX += (right - left + 1 - width) / 2;
 			spriteOperation(DRAW_PRINTTEXT);
 		}
 	}


Commit: f059104708e4a95fd3a52d2ea6041f89604e45db
    https://github.com/scummvm/scummvm/commit/f059104708e4a95fd3a52d2ea6041f89604e45db
Author: Simon Delamarre (simon.delamarre14 at gmail.com)
Date: 2025-09-24T23:38:29+02:00

Commit Message:
GOB: Implement printTotText() extensions found in Adi4

Fix the input buttons used in many places in Adi4 applications.

Changed paths:
    engines/gob/draw.cpp
    engines/gob/draw.h
    engines/gob/draw_playtoons.cpp
    engines/gob/draw_v2.cpp
    engines/gob/inter_v7.cpp


diff --git a/engines/gob/draw.cpp b/engines/gob/draw.cpp
index 41be49d0299..fd306ea6b5f 100644
--- a/engines/gob/draw.cpp
+++ b/engines/gob/draw.cpp
@@ -54,6 +54,7 @@ Draw::Draw(GobEngine *vm) : _vm(vm) {
 	_destSpriteY = 0;
 	_backColor = 0;
 	_frontColor = 0;
+	_colorOffset = 0;
 	_transparency = 0;
 
 	_sourceSurface = 0;
diff --git a/engines/gob/draw.h b/engines/gob/draw.h
index 6653093d7af..5857fe50125 100644
--- a/engines/gob/draw.h
+++ b/engines/gob/draw.h
@@ -88,6 +88,7 @@ public:
 	int16 _destSpriteY;
 	int16 _backColor;
 	int16 _frontColor;
+	int16 _colorOffset;
 	int16 _transparency;
 
 	int16 _sourceSurface;
@@ -310,6 +311,18 @@ public:
 };
 
 class Draw_Playtoons: public Draw_v2 {
+private:
+	struct TotTextInfo {
+		Common::String str;
+		int16 rectLeft = 0;
+		int16 rectRight = 0;
+		int16 rectTop = 0;
+		int16 rectBottom = 0;
+		int16 colCmd = 0;
+		int16 fontIndex = 0;
+		int16 color = 0;
+	};
+
 public:
 	Draw_Playtoons(GobEngine *vm);
 	~Draw_Playtoons() override {}
diff --git a/engines/gob/draw_playtoons.cpp b/engines/gob/draw_playtoons.cpp
index 96b0bc9b046..f9a82af9bf6 100644
--- a/engines/gob/draw_playtoons.cpp
+++ b/engines/gob/draw_playtoons.cpp
@@ -110,8 +110,6 @@ void Draw_Playtoons::printTotText(int16 id) {
 		}
 	}
 
-	ptr += 8;
-
 	if (_renderFlags & RENDERFLAG_CAPTUREPUSH) {
 		_vm->_game->capturePush(destX, destY,
 				spriteRight - destX + 1, spriteBottom - destY + 1);
@@ -124,13 +122,15 @@ void Draw_Playtoons::printTotText(int16 id) {
 	_spriteBottom = spriteBottom;
 	_destSurface = kBackSurface;
 
-	_backColor = *ptr++;
-	_transparency = 1;
+	ptrEnd = ptr + 8;
+	ptr += 9;
 
-	if ((_vm->getGameType() == kGameTypeAdibou2 ||
-		 _vm->getGameType() == kGameTypeAdi4) &&
-		_backColor == 16)
+	if (*ptrEnd == 16)
 		_backColor = -1;
+	else
+		_backColor = *ptr + _colorOffset;
+
+	_transparency = 1;
 
 	spriteOperation(DRAW_CLEARRECT);
 
@@ -148,15 +148,15 @@ void Draw_Playtoons::printTotText(int16 id) {
 		cmd = *ptr++;
 		switch ((cmd & 0xF0) >> 4) {
 		case 0:
-			_frontColor = cmd & 0xF;
+			_frontColor = (cmd & 0xF) + _colorOffset;
 			spriteOperation(DRAW_DRAWLINE);
 			break;
 		case 1:
-			_frontColor = cmd & 0xF;
+			_frontColor = (cmd & 0xF) + _colorOffset;
 			spriteOperation(DRAW_DRAWBAR);
 			break;
 		case 2:
-			_backColor = cmd & 0xF;
+			_backColor = (cmd & 0xF) + _colorOffset;
 			spriteOperation(DRAW_FILLRECTABS);
 			break;
 		default:
@@ -168,8 +168,8 @@ void Draw_Playtoons::printTotText(int16 id) {
 	ptrEnd = ptr;
 	while (((ptrEnd - dataPtr) < size) && (*ptrEnd != 1)) {
 		// Converting to unknown commands/characters to spaces
-		if ((_vm->_game->_script->getVersionMinor() < 2) && (*ptrEnd > 3) && (*ptrEnd < 32))
-			*ptrEnd = 32;
+		if ((_vm->_game->_script->getVersionMinor() < 2) && (*ptrEnd > 3) && (*ptrEnd < ' '))
+			*ptrEnd = ' ';
 
 		switch (*ptrEnd) {
 		case 1:
@@ -177,17 +177,22 @@ void Draw_Playtoons::printTotText(int16 id) {
 
 		case 2:
 		case 5:
+		case 12:
 			ptrEnd += 5;
 			break;
 
 		case 3:
 		case 4:
+		case 15:
 			ptrEnd += 2;
 			break;
 
 		case 6:
 			ptrEnd++;
 			switch (*ptrEnd & 0xC0) {
+			case 0:
+				ptrEnd++;
+				break;
 			case 0x40:
 				ptrEnd += 9;
 				break;
@@ -197,9 +202,6 @@ void Draw_Playtoons::printTotText(int16 id) {
 			case 0xC0:
 				ptrEnd += 11;
 				break;
-			default:
-				ptrEnd++;
-				break;
 			}
 			break;
 
@@ -207,6 +209,11 @@ void Draw_Playtoons::printTotText(int16 id) {
 			ptrEnd += (ptrEnd[1] * 2) + 2;
 			break;
 
+		case 11:
+			do { ptrEnd++; } while (*ptrEnd != 0);
+			ptrEnd += 2;
+			break;
+
 		default:
 			ptrEnd++;
 			break;
@@ -221,13 +228,17 @@ void Draw_Playtoons::printTotText(int16 id) {
 	int16 colCmd = 0;
 	int16 width;
 	int16 maskChar = 0;
-	char mask[80], str[80], buf[50];
+	char mask[200], str[200], buf[50];
 
-	memset(mask, 0, 80);
-	memset(str, ' ', 80);
+	memset(mask, 0, 200);
+	memset(str, ' ', 200);
 	_backColor = 0;
 	_transparency = 1;
 
+	Common::Array<TotTextInfo> totTextInfos;
+	if (_vm->_game->_script->getVersionMinor() >= 4)
+		totTextInfos.resize(32);
+
 #ifdef USE_TTS
 	Common::String ttsMessage;
 #endif
@@ -235,7 +246,7 @@ void Draw_Playtoons::printTotText(int16 id) {
 		if ((((*ptr >= 1) && (*ptr <= 7)) || (*ptr == 10)) && (strPos != 0)) {
 			str[MAX(strPos, strPos2)] = 0;
 			strPosBak = strPos;
-			width = strlen(str) * _fonts[fontIndex]->getCharWidth();
+			width = stringLength(str, fontIndex);
 			adjustCoords(1, &width, nullptr);
 
 			if (colCmd & 0x0F) {
@@ -248,22 +259,49 @@ void Draw_Playtoons::printTotText(int16 id) {
 				adjustCoords(0, &rectLeft, &rectTop);
 				adjustCoords(2, &rectRight, &rectBottom);
 
-				if (colId != -1)
-					_vm->_game->_hotspots->add(colId + 0xD000, rectLeft, rectTop,
-							rectRight, rectBottom, (uint16) Hotspots::kTypeClick, 0, 0, 0, 0);
+				if (_vm->_game->_script->getVersionMinor() < 4 || colId < 1 || colId > 32) {
+					if (colId != -1) {
+						uint16 hotspotIdOff = (colCmd & 0x80) ? 0xD000 : 0x4000;
+						_vm->_game->_hotspots->add(colId + hotspotIdOff, rectLeft, rectTop,
+												   rectRight, rectBottom, (uint16) Hotspots::kTypeClick, 0, 0, 0, 0);
+					}
+
+					if (_needAdjust != 2 && _needAdjust < 10)
+						drawButton(colCmd & 0x0F, rectLeft + 4, rectTop + 4,
+								   rectRight - 4, rectBottom - 4, str, fontIndex, frontColor, colId);
+					else
+						drawButton(colCmd & 0x0F, rectLeft + 2, rectTop + 2,
+								   rectRight - 2, rectBottom - 2, str, fontIndex, frontColor, colId);
+				} else if (totTextInfos[colId - 1].str.empty()) {
+					totTextInfos[colId - 1].str = str;
+					totTextInfos[colId - 1].rectLeft = rectLeft;
+					totTextInfos[colId - 1].rectTop = rectTop;
+					totTextInfos[colId - 1].rectRight = rectRight;
+					totTextInfos[colId - 1].rectBottom = rectBottom;
+					totTextInfos[colId - 1].colCmd = colCmd;
+					totTextInfos[colId - 1].fontIndex = fontIndex;
+					totTextInfos[colId - 1].color = frontColor;
+				} else {
+					if (rectLeft < totTextInfos[colId - 1].rectLeft)
+						totTextInfos[colId - 1].rectLeft = rectLeft;
+
+					if (rectTop < totTextInfos[colId - 1].rectTop)
+						totTextInfos[colId - 1].rectTop = rectTop;
 
-				if (_needAdjust != 2)
-					printTextCentered(colCmd & 0x0F, rectLeft + 4, rectTop + 4,
-							rectRight - 4, rectBottom - 4, str, fontIndex, frontColor);
-				else
-					printTextCentered(colCmd & 0x0F, rectLeft + 2, rectTop + 2,
-							rectRight - 2, rectBottom - 2, str, fontIndex, frontColor);
+					if (rectRight > totTextInfos[colId - 1].rectRight)
+						totTextInfos[colId - 1].rectRight = rectRight;
 
+					if (rectBottom > totTextInfos[colId - 1].rectBottom)
+						totTextInfos[colId - 1].rectBottom = rectBottom;
+
+					totTextInfos[colId - 1].str += '\\';
+					totTextInfos[colId - 1].str += str;
+				}
 			} else {
 				_destSpriteX = offX;
 				_destSpriteY = offY;
 				_fontIndex   = fontIndex;
-				_frontColor  = frontColor;
+				_frontColor  = frontColor + _colorOffset;
 				_textToPrint = str;
 #ifdef USE_TTS
 				ttsMessage += _textToPrint;
@@ -288,14 +326,26 @@ void Draw_Playtoons::printTotText(int16 id) {
 					spriteOperation(DRAW_PRINTTEXT, false);
 
 				width = strlen(str);
+				rectLeft = offX;
 				for (strPos = 0; strPos < width; strPos++) {
-					if (mask[strPos] == '\0')
+					char charStrAtPos[2];
+					charStrAtPos[0] = str[strPos];
+					charStrAtPos[1] = '\0';
+
+					int16 charWidth = stringLength(charStrAtPos, fontIndex);
+					adjustCoords(1, &charWidth, nullptr);
+
+					if (mask[strPos] == '\0') {
+						rectLeft += charWidth;
 						continue;
+					}
+
+					_destSpriteX = rectLeft;
+					rectLeft += charWidth;
 
-					rectLeft = _fonts[fontIndex]->getCharWidth();
 					rectTop = _fonts[fontIndex]->getCharHeight();
-					adjustCoords(1, &rectLeft, &rectTop);
-					_destSpriteX = strPos * rectLeft + offX;
+					adjustCoords(1, nullptr, &rectTop);
+
 					_spriteRight = _destSpriteX + rectLeft - 1;
 					_spriteBottom = offY + rectTop;
 					_destSpriteY = _spriteBottom;
@@ -304,24 +354,28 @@ void Draw_Playtoons::printTotText(int16 id) {
 			}
 
 			rectLeft = 0;
-			for (int i = 0; i < strPosBak; i++)
-				rectLeft += _fonts[_fontIndex]->getCharWidth(str[i]);
+			if (_vm->_game->_script->getVersionMinor() < 4) {
+				rectLeft += strPosBak * _fonts[_fontIndex]->getCharWidth();
+			} else {
+				rectLeft += stringLength(str, fontIndex);
+			}
 
 			adjustCoords(1, &rectLeft, nullptr);
 			offX += rectLeft;
 			strPos = 0;
 			strPos2 = -1;
-			memset(mask, 0, 80);
-			memset(str, ' ', 80);
+			memset(mask, 0, 200);
+			memset(str, ' ', 200);
 		}
 
 		if (*ptr == 1)
 			break;
 
 		cmd = *ptr;
+
 		switch ((uint8) cmd) {
 		case 2:
-		case 5:
+		case 5: // Set dest coordinates
 			ptr++;
 			offX = destX + (int16)READ_LE_UINT16(ptr);
 			offY = destY + (int16)READ_LE_UINT16(ptr + 2);
@@ -329,10 +383,11 @@ void Draw_Playtoons::printTotText(int16 id) {
 				offX += (int16)READ_LE_UINT16(ptr);
 				offY += (int16)READ_LE_UINT16(ptr + 2);
 			}
+
 			ptr += 4;
 			break;
 
-		case 3:
+		case 3: // Set font and color
 			ptr++;
 			fontIndex = ((*ptr & 0xF0) >> 4) & 7;
 			frontColor = *ptr & 0x0F;
@@ -353,13 +408,14 @@ void Draw_Playtoons::printTotText(int16 id) {
 			break;
 
 		case 6:
-			ptr++;
-			colCmd = *ptr++;
+			colCmd = ptr[1];
 			colId = -1;
-			if (colCmd & 0x80) {
-				colId = (int16)READ_LE_UINT16(ptr);
-				ptr += 2;
+			if ((colCmd & 0x80) || (colCmd & 0x20)) {
+				colId = (int16)READ_LE_UINT16(ptr + 2);
+				ptrEnd = ptr + 4;
 			}
+			ptr = ptrEnd;
+
 			if (colCmd & 0x40) {
 				rectLeft = destX + (int16)READ_LE_UINT16(ptr);
 				rectRight = destX + (int16)READ_LE_UINT16(ptr + 2);
@@ -399,68 +455,136 @@ void Draw_Playtoons::printTotText(int16 id) {
 			}
 			break;
 
-		default:
-			str[strPos] = (char) cmd;
-			// fall through
-		case 32:
-			mask[strPos++] = maskChar;
+		case 11:
+			do {
+				ptrEnd = ptr;
+				ptr++;
+			} while (*ptr);
+			break;
+
+		case 12:
+			warning("STUB: DrawPlaytoons:printTotText, case 12");
+			break;
+
+		case 13:
+		case 14:
 			ptr++;
 			break;
 
-		case 186:
-			cmd = ptrEnd[17] & 0x7F;
-			if (cmd == 0) {
-				val = READ_LE_UINT16(ptrEnd + 18) * 4;
-				Common::sprintf_s(buf, "%d", (int32)VAR_OFFSET(val));
-			} else if (cmd == 1) {
-				val = READ_LE_UINT16(ptrEnd + 18) * 4;
-				Common::strlcpy(buf, GET_VARO_STR(val), 20);
-			} else {
-				val = READ_LE_UINT16(ptrEnd + 18) * 4;
-				Common::sprintf_s(buf, "%d", (int32)VAR_OFFSET(val));
-				if (buf[0] == '-') {
-					while (strlen(buf) - 1 < (uint32)ptrEnd[17]) {
-						_vm->_util->insertStr("0", buf, 1);
-					}
+		case 15:
+			ptr += 2;
+			break;
+
+		default:
+			if (*ptr == 186 && _vm->_game->_script->getVersionMinor() < 3) {
+				cmd = ptrEnd[17] & 0x7F;
+				if (cmd == 0) {
+					val = READ_LE_UINT16(ptrEnd + 18) * 4;
+					Common::sprintf_s(buf, "%d", (int32)VAR_OFFSET(val));
+				} else if (cmd == 1) {
+					val = READ_LE_UINT16(ptrEnd + 18) * 4;
+					Common::strlcpy(buf, GET_VARO_STR(val), 20);
 				} else {
-					while (strlen(buf) - 1 < (uint32)ptrEnd[17]) {
-						_vm->_util->insertStr("0", buf, 0);
+					val = READ_LE_UINT16(ptrEnd + 18) * 4;
+					Common::sprintf_s(buf, "%d", (int32)VAR_OFFSET(val));
+					if (buf[0] == '-') {
+						while (strlen(buf) - 1 < (uint32)ptrEnd[17]) {
+							_vm->_util->insertStr("0", buf, 1);
+						}
+					} else {
+						while (strlen(buf) - 1 < (uint32)ptrEnd[17]) {
+							_vm->_util->insertStr("0", buf, 0);
+						}
 					}
+					if (_vm->_global->_language == 2)
+						_vm->_util->insertStr(".", buf, strlen(buf) + 1 - ptrEnd[17]);
+					else
+						_vm->_util->insertStr(",", buf, strlen(buf) + 1 - ptrEnd[17]);
 				}
-				if (_vm->_global->_language == 2)
-					_vm->_util->insertStr(".", buf, strlen(buf) + 1 - ptrEnd[17]);
-				else
-					_vm->_util->insertStr(",", buf, strlen(buf) + 1 - ptrEnd[17]);
-			}
-			memcpy(str + strPos, buf, strlen(buf));
-			memset(mask, maskChar, strlen(buf));
-			if (ptrEnd[17] & 0x80) {
-				strPos2 = strPos + strlen(buf);
-				strPos++;
-				ptrEnd += 23;
-				ptr++;
-			} else {
-				strPos += strlen(buf);
-				if (ptr[1] != ' ') {
-					if ((ptr[1] == 2) &&
+				memcpy(str + strPos, buf, strlen(buf));
+				memset(mask, maskChar, strlen(buf));
+				if (ptrEnd[17] & 0x80) {
+					strPos2 = strPos + strlen(buf);
+					strPos++;
+					ptrEnd += 23;
+					ptr++;
+				} else {
+					strPos += strlen(buf);
+					if (ptr[1] != ' ') {
+						if ((ptr[1] == 2) &&
 							(((int16)READ_LE_UINT16(ptr + 4)) == _destSpriteY)) {
-						ptr += 5;
+							ptr += 5;
+							str[strPos] = ' ';
+							mask[strPos++] = maskChar;
+						}
+					} else {
 						str[strPos] = ' ';
 						mask[strPos++] = maskChar;
-					}
-				} else {
-					str[strPos] = ' ';
-					mask[strPos++] = maskChar;
-					while (ptr[1] == ' ')
-						ptr++;
-					if ((ptr[1] == 2) &&
+						while (ptr[1] == ' ')
+							ptr++;
+						if ((ptr[1] == 2) &&
 							(((int16)READ_LE_UINT16(ptr + 4)) == _destSpriteY))
-						ptr += 5;
+							ptr += 5;
+					}
+					ptrEnd += 23;
+					ptr++;
 				}
-				ptrEnd += 23;
-				ptr++;
+			} else {
+				if (*ptr != ' ') {
+					str[strPos] = *ptr;
+				}
+
+				mask[strPos] = maskChar;
+				strPos++;
 			}
-			break;
+
+			ptr++;
+		}
+	}
+
+	ptrEnd = ptr + 2;
+	if (_vm->_game->_script->getVersionMinor() >= 4 && ptr + 4 < dataPtr + size) {
+		int16 cmd2 = *ptrEnd;
+		if (cmd2 & 0x80)
+			cmd = (cmd2 & 0x7F) * 24;
+		else
+			cmd = (cmd2 & 0x7F) * 22;
+
+		ptr += cmd + 3;
+		int16 len = *ptr++;
+		if (len > 0)
+			warning("STUB: DrawPlaytoons:printTotText, len=%d", len);
+		ptrEnd = ptr;
+		for (strPos = 0; strPos < len; strPos++) {
+			byte *ptr2 = ptr + strPos * 0x4C;
+			int16 textIndex = (*ptr2 + 0x4A);
+			if (textIndex) {
+				warning("STUB: DrawPlaytoons:printTotText, strPos = %d, update tot text %d", strPos, textIndex);
+			} else {
+				warning("STUB: DrawPlaytoons:printTotText, strPos = %d, BLITSURF case", strPos);
+			}
+		}
+	}
+
+	ptr = ptrEnd;
+	if (_vm->_game->_script->getVersionMinor() >= 4) {
+		for (strPos = 0; strPos < (int16)totTextInfos.size(); strPos++) {
+			TotTextInfo &totTextInfo = totTextInfos[strPos];
+			if (totTextInfo.str.empty())
+				continue;
+
+			int hotspotIdOff = (totTextInfo.colCmd & 0x80) ? 0xD001 : 0x4001;
+			_vm->_game->_hotspots->add(strPos + hotspotIdOff, totTextInfo.rectLeft, totTextInfo.rectTop,
+									   totTextInfo.rectRight, totTextInfo.rectBottom, Hotspots::kTypeClick, 0, 0, 0, 0);
+
+			if (_needAdjust != 2 && _needAdjust < 10)
+				drawButton(totTextInfo.colCmd & 0x0F, totTextInfo.rectLeft + 4, totTextInfo.rectTop + 4,
+						   totTextInfo.rectRight - 4, totTextInfo.rectBottom - 4, totTextInfo.str.begin(),
+						   totTextInfo.fontIndex, totTextInfo.color, strPos + 1);
+			else
+				drawButton(totTextInfo.colCmd & 0x0F, totTextInfo.rectLeft + 2, totTextInfo.rectTop + 2,
+						   totTextInfo.rectRight - 2, totTextInfo.rectBottom - 2, totTextInfo.str.begin(),
+						   totTextInfo.fontIndex, totTextInfo.color, strPos + 1);
 		}
 	}
 
diff --git a/engines/gob/draw_v2.cpp b/engines/gob/draw_v2.cpp
index b56654d5e19..43bc16e5187 100644
--- a/engines/gob/draw_v2.cpp
+++ b/engines/gob/draw_v2.cpp
@@ -294,11 +294,6 @@ void Draw_v2::printTotText(int16 id) {
 	_backColor = *ptr++;
 	_transparency = 1;
 
-	if ((_vm->getGameType() == kGameTypeAdibou2 ||
-		 _vm->getGameType() == kGameTypeAdi4) &&
-		_backColor == 16)
-		_backColor = -1;
-
 	spriteOperation(DRAW_CLEARRECT);
 
 	_backColor = 0;
diff --git a/engines/gob/inter_v7.cpp b/engines/gob/inter_v7.cpp
index f0c751543b2..c4735722ee2 100644
--- a/engines/gob/inter_v7.cpp
+++ b/engines/gob/inter_v7.cpp
@@ -2163,7 +2163,9 @@ void Inter_v7::o7_startAdi4Application(OpGobParams &params) {
 		_vm->_dataIO->openArchive(appliStkFile, false);
 
 		Common::String appliIntroTotFile = appliAbbreviation + "INTRO";
+		_vm->_draw->_colorOffset = 10;
 		_vm->_game->totSub(1, appliIntroTotFile);
+		_vm->_draw->_colorOffset = 0;
 
 		_vm->_dataIO->closeArchive(false);
 	}




More information about the Scummvm-git-logs mailing list