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

peterkohaut peterkohaut at users.noreply.github.com
Sun Aug 1 23:09:57 UTC 2021


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

Summary:
e242a76694 TINSEL: Added Noir font rendering


Commit: e242a766940c688ea9b69fbf241dcd333ab7078e
    https://github.com/scummvm/scummvm/commit/e242a766940c688ea9b69fbf241dcd333ab7078e
Author: Peter Kohaut (peter.kohaut at gmail.com)
Date: 2021-08-02T01:08:29+02:00

Commit Message:
TINSEL: Added Noir font rendering

Changed paths:
    engines/tinsel/actors.cpp
    engines/tinsel/graphics.cpp
    engines/tinsel/graphics.h
    engines/tinsel/text.cpp
    engines/tinsel/text.h
    engines/tinsel/tinlib.cpp


diff --git a/engines/tinsel/actors.cpp b/engines/tinsel/actors.cpp
index a8e06bf141..6770eea252 100644
--- a/engines/tinsel/actors.cpp
+++ b/engines/tinsel/actors.cpp
@@ -622,17 +622,33 @@ void Actor::GetActorMidTop(int ano, int *x, int *y) {
 
 	pActor = GetMover(ano);
 
-	if (pActor)
+	if (pActor) {
 		GetMoverMidTop(pActor, x, y);
-	else if (TinselV2) {
+	} else if (TinselV3) {
+		int i;
+		for (i = 0; i < MAX_REELS; i++) {
+			if (_actorInfo[ano-1].presObjs[i] && MultiHasShape(_actorInfo[ano-1].presObjs[i])) {
+				break;
+			}
+		}
+
+		if (i == MAX_REELS) {
+			*x = 320;
+			*y = 144;
+		} else {
+			*x = (GetActorLeft(ano) + GetActorRight(ano)) / 2;
+			*y = GetActorTop(ano);
+		}
+	} else if (TinselV2) {
 		*x = (GetActorLeft(ano) + GetActorRight(ano)) / 2;
 		*y = GetActorTop(ano);
 	} else if (_actorInfo[ano - 1].presObj) {
 		*x = (MultiLeftmost(_actorInfo[ano - 1].presObj)
 		      + MultiRightmost(_actorInfo[ano - 1].presObj)) / 2;
 		*y = MultiHighest(_actorInfo[ano - 1].presObj);
-	} else
+	} else {
 		GetActorPos(ano, x, y);		// The best we can do!
+	}
 }
 
 /**
diff --git a/engines/tinsel/graphics.cpp b/engines/tinsel/graphics.cpp
index da64931436..e25603e683 100644
--- a/engines/tinsel/graphics.cpp
+++ b/engines/tinsel/graphics.cpp
@@ -1002,6 +1002,38 @@ static void PackedWrtNonZero(DRAWOBJECT *pObj, uint8 *srcP, uint8 *destP,
 	}
 }
 
+static void t3WrtText(DRAWOBJECT *pObj, uint8 *srcP, uint8 *destP) {
+	bool applyClipping = (pObj->flags & DMA_CLIP) != 0;
+
+	if (applyClipping) {
+		srcP += (pObj->topClip * pObj->width * 2);
+
+		pObj->height -= pObj->topClip + pObj->botClip;
+		pObj->width -= pObj->leftClip + pObj->rightClip;
+	}
+
+	uint32 baseColor = t3GetBaseColor();
+
+	for (int y = 0; y < pObj->height; ++y) {
+		// Get the position to start writing out from
+		uint8 *tempP = destP;
+		srcP += pObj->leftClip * 2;
+		for (int x = 0; x < pObj->width; ++x) {
+			uint32 color = READ_LE_UINT16(srcP);
+			if (color != 0xF81F) { // "zero" for Tinsel 3 - magenta in 565
+				if (color == baseColor) {
+					color = pObj->constant;
+				}
+				WRITE_UINT16(tempP, color);
+			}
+			tempP += 2;
+			srcP += 2;
+		}
+		srcP += pObj->rightClip * 2;
+		destP += SCREEN_WIDTH * 2;
+	}
+}
+
 //----------------- MAIN FUNCTIONS ---------------------
 
 /**
@@ -1042,7 +1074,7 @@ void DrawObject(DRAWOBJECT *pObj) {
 		return;
 
 	// If writing constant data, don't bother locking the data pointer and reading src details
-	if ((pObj->flags & DMA_CONST) == 0) {
+	if (((pObj->flags & DMA_CONST) == 0) || (TinselV3 && pObj->flags == 5)) {
 		if (TinselV2) {
 			srcPtr = (byte *)_vm->_handle->LockMem(pObj->hBits);
 			pObj->charBase = nullptr;
@@ -1172,6 +1204,11 @@ void DrawObject(DRAWOBJECT *pObj) {
 		case 0xC4:	// draw transparent surface with clipping
 			WrtTrans(pObj, destPtr, typeId == 0xC4);
 			break;
+		case 0x05:	// TinselV3, draw text with color replacement without clipping
+		case 0x45:	// TinselV3, draw text with color replacement with clipping
+			assert(TinselV3);
+			t3WrtText(pObj, srcPtr, destPtr);
+			break;
 		default:
 			error("Unknown drawing type %d", typeId);
 		}
diff --git a/engines/tinsel/graphics.h b/engines/tinsel/graphics.h
index 0f05dfcaa7..5da7d0feb0 100644
--- a/engines/tinsel/graphics.h
+++ b/engines/tinsel/graphics.h
@@ -25,6 +25,7 @@
 #define TINSEL_GRAPHICS_H
 
 #include "tinsel/dw.h"
+#include "tinsel/text.h"
 
 #include "common/rect.h"
 #include "common/system.h"
diff --git a/engines/tinsel/text.cpp b/engines/tinsel/text.cpp
index 02ddc9272e..89e2ed594c 100644
--- a/engines/tinsel/text.cpp
+++ b/engines/tinsel/text.cpp
@@ -30,6 +30,29 @@
 
 namespace Tinsel {
 
+
+//----------------- LOCAL GLOBAL DATA --------------------
+/** TinselV3, base color for the text color replacement */
+static uint32 g_t3fontBaseColor;
+
+/**
+ * Returns the handle for the character image.
+ * @param pFont			Which font to use
+ * @param c				Index of the character
+ */
+SCNHANDLE GetFontDef(const FONT *pFont, int c)
+{
+	if (TinselV3)
+	{
+		const T3_FONT *pT3Font = (const T3_FONT *)pFont;
+		return FROM_32(pT3Font->fontDef[c]);
+	}
+	else
+	{
+		return FROM_32(pFont->fontDef[c]);
+	}
+}
+
 /**
  * Returns the length of one line of a string in pixels.
  * @param szStr			String
@@ -46,7 +69,7 @@ int StringLengthPix(char *szStr, const FONT *pFont) {
 			if (c & 0x80)
 				c = ((c & ~0x80) << 8) + *++szStr;
 		}
-		hImg = FROM_32(pFont->fontDef[c]);
+		hImg = GetFontDef(pFont, c);
 
 		if (hImg) {
 			// there is a IMAGE for this character
@@ -119,13 +142,14 @@ OBJECT *ObjectTextOut(OBJECT **pList, char *szStr, int color,
 
 	// get font pointer
 	const FONT *pFont = (const FONT *)_vm->_handle->LockMem(hFont);
+	const OBJ_INIT *pFontInit = TinselV3 ? (&((const T3_FONT *)pFont)->fontInit) : (&pFont->fontInit);
 
 	// init head of text list
 	pFirst = nullptr;
 
 	// get image for capital W
-	assert(pFont->fontDef[(int)'W']);
-	pImg = (const IMAGE *)_vm->_handle->LockMem(FROM_32(pFont->fontDef[(int)'W']));
+	assert(GetFontDef(pFont, (int)'W'));
+	pImg = (const IMAGE *)_vm->_handle->LockMem(GetFontDef(pFont, (int)'W'));
 
 	// get height of capital W for offset to next line
 	yOffset = FROM_16(pImg->imgHeight) & ~C16_FLAG_MASK;
@@ -140,7 +164,7 @@ OBJECT *ObjectTextOut(OBJECT **pList, char *szStr, int color,
 				if (c & 0x80)
 					c = ((c & ~0x80) << 8) + *++szStr;
 			}
-			hImg = FROM_32(pFont->fontDef[c]);
+			hImg = GetFontDef(pFont, c);
 
 			if (hImg == 0) {
 				// no image for this character
@@ -152,12 +176,12 @@ OBJECT *ObjectTextOut(OBJECT **pList, char *szStr, int color,
 				int aniX, aniY;		// char image animation offsets
 
 				OBJ_INIT oi;
-				oi.hObjImg  = FROM_32(pFont->fontInit.hObjImg);
-				oi.objFlags = FROM_32(pFont->fontInit.objFlags);
-				oi.objID    = FROM_32(pFont->fontInit.objID);
-				oi.objX     = FROM_32(pFont->fontInit.objX);
-				oi.objY     = FROM_32(pFont->fontInit.objY);
-				oi.objZ     = FROM_32(pFont->fontInit.objZ);
+				oi.hObjImg  = FROM_32(pFontInit->hObjImg);
+				oi.objFlags = FROM_32(pFontInit->objFlags);
+				oi.objID    = FROM_32(pFontInit->objID);
+				oi.objX     = FROM_32(pFontInit->objX);
+				oi.objY     = FROM_32(pFontInit->objY);
+				oi.objZ     = FROM_32(pFontInit->objZ);
 
 				// allocate and init a character object
 				if (pFirst == NULL)
@@ -183,6 +207,11 @@ OBJECT *ObjectTextOut(OBJECT **pList, char *szStr, int color,
 				// set characters color - only effective for mono fonts
 				pChar->constant = color;
 
+				// set the base font color to be replaced with supplied color, only for Tinsel V3
+				if (TinselV3) {
+					g_t3fontBaseColor = FROM_32(((const T3_FONT*)pFont)->baseColor);
+				}
+
 				// get Y animation offset
 				GetAniOffset(hImg, pChar->flags, &aniX, &aniY);
 
@@ -271,7 +300,13 @@ bool IsCharImage(SCNHANDLE hFont, char c) {
 	// get font pointer
 	const FONT *pFont = (const FONT *)_vm->_handle->LockMem(hFont);
 
-	return pFont->fontDef[c2] != 0;
+	return GetFontDef(pFont, c2) != 0;
 }
 
+uint32 t3GetBaseColor()
+{
+	return g_t3fontBaseColor;
+}
+
+
 } // End of namespace Tinsel
diff --git a/engines/tinsel/text.h b/engines/tinsel/text.h
index 5d39540d8f..271e28e3a0 100644
--- a/engines/tinsel/text.h
+++ b/engines/tinsel/text.h
@@ -62,6 +62,18 @@ struct FONT {
 	SCNHANDLE fontDef[300];	///< image handle array for all characters in the font
 } PACKED_STRUCT;
 
+
+struct T3_FONT {
+	int xSpacing;			///< x spacing between characters
+	int ySpacing;			///< y spacing between characters
+	int xShadow;			///< x shadow offset
+	int yShadow;			///< y shadow offset
+	int spaceSize;			///< x spacing to use for a space character
+	int baseColor;			///< base color which can be replaced, specific to Tinsel 3
+	OBJ_INIT fontInit;		///< structure used to init text objects
+	SCNHANDLE fontDef[300];	///< image handle array for all characters in the font
+} PACKED_STRUCT;
+
 #include "common/pack-end.h"	// END STRUCT PACKING
 
 
@@ -105,6 +117,8 @@ bool IsCharImage(		// Is there an image for this character in this font?
 	SCNHANDLE hFont,	// which font to use
 	char c);		// character to test
 
+uint32 t3GetBaseColor();
+
 } // End of namespace Tinsel
 
 #endif	// TINSEL_TEXT_H
diff --git a/engines/tinsel/tinlib.cpp b/engines/tinsel/tinlib.cpp
index 5528e421c2..4939f4b05b 100644
--- a/engines/tinsel/tinlib.cpp
+++ b/engines/tinsel/tinlib.cpp
@@ -3391,18 +3391,24 @@ static void TalkOrSay(CORO_PARAM, SPEECH_TYPE speechType, SCNHANDLE hText, int x
 			if ((_ctx->whatSort == IS_SAY) || (_ctx->whatSort == IS_TALK))
 				_vm->_actor->GetActorMidTop(_ctx->actor, &_ctx->x, &_ctx->y);
 
-			if (!TinselV0)
+			if (!TinselV0) {
 				SetTextPal(_vm->_actor->GetActorRGB(_ctx->actor));
-			if (TinselV2)
+			}
+			if (TinselV2) {
 				LoadSubString(hText, _ctx->sub, _vm->_font->TextBufferAddr(), TBUFSZ);
-			else {
+			} else {
 				LoadStringRes(hText, _vm->_font->TextBufferAddr(), TBUFSZ);
 
 				_ctx->y -= _ctx->Toffset;
 			}
 
+			int color = 0;
+			if (TinselV3) {
+				color = _vm->_actor->GetActorRGB(_ctx->actor);
+			}
+
 			_ctx->pText = ObjectTextOut(_vm->_bg->GetPlayfieldList(FIELD_STATUS),
-					_vm->_font->TextBufferAddr(), 0, _ctx->x - _ctx->Loffset, _ctx->y - _ctx->Toffset,
+					_vm->_font->TextBufferAddr(), color, _ctx->x - _ctx->Loffset, _ctx->y - _ctx->Toffset,
 					_vm->_font->GetTalkFontHandle(), TXT_CENTER);
 			assert(_ctx->pText); // talk() string produced NULL text;
 




More information about the Scummvm-git-logs mailing list