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

bluegr bluegr at gmail.com
Sat Sep 4 12:21:16 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:
aa7b3470a0 TINSEL: Simplify font loading and handling


Commit: aa7b3470a023bfe8bb08145c4476c3bfb2a25ed8
    https://github.com/scummvm/scummvm/commit/aa7b3470a023bfe8bb08145c4476c3bfb2a25ed8
Author: Filippos Karapetis (bluegr at gmail.com)
Date: 2021-09-04T15:21:07+03:00

Commit Message:
TINSEL: Simplify font loading and handling

This introduces a new helper method, GetFont(), which loads font data
using a memory stream and handles endianess reads internally. This
simplifies font loading and endianess handling considerably, and allows
for the usage of a common font struct for all engine versions

Changed paths:
    engines/tinsel/font.cpp
    engines/tinsel/handle.cpp
    engines/tinsel/handle.h
    engines/tinsel/text.cpp
    engines/tinsel/text.h


diff --git a/engines/tinsel/font.cpp b/engines/tinsel/font.cpp
index d7dee32f2e..bb4f66e6b5 100644
--- a/engines/tinsel/font.cpp
+++ b/engines/tinsel/font.cpp
@@ -43,22 +43,19 @@ SCNHANDLE Font::GetTalkFontHandle() {
 }
 
 void Font::FettleFontPal(SCNHANDLE fontPal) {
-	const FONT *pFont;
 	IMAGE *pImg;
 
 	assert(fontPal);
 	assert(_hTagFont); // Tag font not declared
 	assert(_hTalkFont); // Talk font not declared
 
-	pFont = (const FONT *)_vm->_handle->LockMem(_hTagFont);
-	pImg = (IMAGE *)_vm->_handle->LockMem(FROM_32(pFont->fontInit.hObjImg)); // get image for char 0
+	pImg = (IMAGE *)_vm->_handle->LockMem(_vm->_handle->GetFontImageHandle(_hTagFont)); // get image for char 0
 	if (!TinselV2)
 		pImg->hImgPal = TO_32(fontPal);
 	else
 		pImg->hImgPal = 0;
 
-	pFont = (const FONT *)_vm->_handle->LockMem(_hTalkFont);
-	pImg = (IMAGE *)_vm->_handle->LockMem(FROM_32(pFont->fontInit.hObjImg)); // get image for char 0
+	pImg = (IMAGE *)_vm->_handle->LockMem(_vm->_handle->GetFontImageHandle(_hTalkFont)); // get image for char 0
 	if (!TinselV2)
 		pImg->hImgPal = TO_32(fontPal);
 	else
diff --git a/engines/tinsel/handle.cpp b/engines/tinsel/handle.cpp
index b5c3a1b6a0..defe08a2d2 100644
--- a/engines/tinsel/handle.cpp
+++ b/engines/tinsel/handle.cpp
@@ -24,6 +24,7 @@
 #define BODGE
 
 #include "common/file.h"
+#include "common/memstream.h"
 #include "common/textconsole.h"
 
 #include "tinsel/drives.h"
@@ -297,6 +298,47 @@ void Handle::LoadFile(MEMHANDLE *pH) {
 	error(CANNOT_FIND_FILE, szFilename);
 }
 
+/**
+ * Return a font specified by a SCHNHANDLE
+ * Handles endianess internally
+ * @param offset			Handle and offset to data
+ * @return FONT structure
+*/
+FONT *Handle::GetFont(SCNHANDLE offset) {
+	byte *fontData = LockMem(offset);
+	const bool isBE = TinselV1Mac || TinselV1Saturn;
+	const uint32 size = (TinselV3 ? 12 * 4 : 11 * 4) + 300 * 4;	// FONT struct size
+	Common::MemoryReadStreamEndian *fontStream = new Common::MemoryReadStreamEndian(fontData, size, isBE);
+
+	FONT *font = new FONT();
+	font->xSpacing = fontStream->readSint32();
+	font->ySpacing = fontStream->readSint32();
+	font->xShadow = fontStream->readSint32();
+	font->yShadow = fontStream->readSint32();
+	font->spaceSize = fontStream->readSint32();
+	font->baseColor = TinselV3 ? fontStream->readSint32() : 0;
+	font->fontInit.hObjImg = fontStream->readUint32();
+	font->fontInit.objFlags = fontStream->readSint32();
+	font->fontInit.objID = fontStream->readSint32();
+	font->fontInit.objX = fontStream->readSint32();
+	font->fontInit.objY = fontStream->readSint32();
+	font->fontInit.objZ = fontStream->readSint32();
+	for (int i = 0; i < 300; i++)
+		font->fontDef[i] = fontStream->readUint32();
+
+	delete fontStream;
+
+	return font;
+}
+
+SCNHANDLE Handle::GetFontImageHandle(SCNHANDLE offset) {
+	FONT *font = GetFont(offset);
+	SCNHANDLE handle = font->fontInit.hObjImg;
+	delete font;
+
+	return handle;
+}
+
 /**
  * Compute and return the address specified by a SCNHANDLE.
  * @param offset			Handle and offset to data
diff --git a/engines/tinsel/handle.h b/engines/tinsel/handle.h
index 55790fd361..06bbebed9e 100644
--- a/engines/tinsel/handle.h
+++ b/engines/tinsel/handle.h
@@ -33,6 +33,7 @@ class File;
 
 namespace Tinsel {
 
+struct FONT;
 struct MEMHANDLE;
 
 class Handle {
@@ -45,6 +46,8 @@ public:
 	 */
 	void SetupHandleTable();
 
+	FONT *GetFont(SCNHANDLE offset);
+	SCNHANDLE GetFontImageHandle(SCNHANDLE offset);
 	byte *LockMem(SCNHANDLE offset);
 
 	void LockScene(SCNHANDLE offset);
diff --git a/engines/tinsel/text.cpp b/engines/tinsel/text.cpp
index 89e2ed594c..9cb0263482 100644
--- a/engines/tinsel/text.cpp
+++ b/engines/tinsel/text.cpp
@@ -35,24 +35,6 @@ namespace Tinsel {
 /** 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
@@ -69,7 +51,7 @@ int StringLengthPix(char *szStr, const FONT *pFont) {
 			if (c & 0x80)
 				c = ((c & ~0x80) << 8) + *++szStr;
 		}
-		hImg = GetFontDef(pFont, c);
+		hImg = pFont->fontDef[c];
 
 		if (hImg) {
 			// there is a IMAGE for this character
@@ -79,14 +61,14 @@ int StringLengthPix(char *szStr, const FONT *pFont) {
 			strLen += FROM_16(pChar->imgWidth);
 		} else
 			// use width of space character
-			strLen += FROM_32(pFont->spaceSize);
+			strLen += pFont->spaceSize;
 
 		// finally add the inter-character spacing
-		strLen += FROM_32(pFont->xSpacing);
+		strLen += pFont->xSpacing;
 	}
 
 	// return length of line in pixels - minus inter-char spacing for last character
-	strLen -= FROM_32(pFont->xSpacing);
+	strLen -= pFont->xSpacing;
 	return (strLen > 0) ? strLen : 0;
 }
 
@@ -141,15 +123,16 @@ OBJECT *ObjectTextOut(OBJECT **pList, char *szStr, int color,
 	assert(pList);
 
 	// get font pointer
-	const FONT *pFont = (const FONT *)_vm->_handle->LockMem(hFont);
-	const OBJ_INIT *pFontInit = TinselV3 ? (&((const T3_FONT *)pFont)->fontInit) : (&pFont->fontInit);
+	FONT *pFont = _vm->_handle->GetFont(hFont);
+	const OBJ_INIT *pFontInit = &pFont->fontInit;
 
 	// init head of text list
 	pFirst = nullptr;
 
 	// get image for capital W
-	assert(GetFontDef(pFont, (int)'W'));
-	pImg = (const IMAGE *)_vm->_handle->LockMem(GetFontDef(pFont, (int)'W'));
+	SCNHANDLE imgHandle = pFont->fontDef[(int)'W'];
+	assert(imgHandle);
+	pImg = (const IMAGE *)_vm->_handle->LockMem(imgHandle);
 
 	// get height of capital W for offset to next line
 	yOffset = FROM_16(pImg->imgHeight) & ~C16_FLAG_MASK;
@@ -164,32 +147,24 @@ OBJECT *ObjectTextOut(OBJECT **pList, char *szStr, int color,
 				if (c & 0x80)
 					c = ((c & ~0x80) << 8) + *++szStr;
 			}
-			hImg = GetFontDef(pFont, c);
+			hImg = pFont->fontDef[c];
 
 			if (hImg == 0) {
 				// no image for this character
 
 				// add font spacing for a space character
-				xJustify += FROM_32(pFont->spaceSize);
+				xJustify += pFont->spaceSize;
 			} else {	// printable character
 
 				int aniX, aniY;		// char image animation offsets
 
-				OBJ_INIT oi;
-				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)
 					// first time - init head of list
-					pFirst = pChar = InitObject(&oi);	// FIXME: endian issue using fontInit!!!
+					pFirst = pChar = InitObject(pFontInit);
 				else
 					// chain to multi-char list
-					pChar = pChar->pSlave = InitObject(&oi);	// FIXME: endian issue using fontInit!!!
+					pChar = pChar->pSlave = InitObject(pFontInit);
 
 				// convert image handle to pointer
 				pImg = (const IMAGE *)_vm->_handle->LockMem(hImg);
@@ -208,9 +183,7 @@ OBJECT *ObjectTextOut(OBJECT **pList, char *szStr, int color,
 				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);
-				}
+				g_t3fontBaseColor = TinselV3 ? pFont->baseColor : 0;
 
 				// get Y animation offset
 				GetAniOffset(hImg, pChar->flags, &aniX, &aniY);
@@ -232,8 +205,8 @@ OBJECT *ObjectTextOut(OBJECT **pList, char *szStr, int color,
 					CopyObject(pShad, pChar);
 
 					// add shadow offsets to characters position
-					pShad->xPos += intToFrac(FROM_32(pFont->xShadow));
-					pShad->yPos += intToFrac(FROM_32(pFont->yShadow));
+					pShad->xPos += intToFrac(pFont->xShadow);
+					pShad->yPos += intToFrac(pFont->yShadow);
 
 					// shadow is behind the character
 					pShad->zPos--;
@@ -265,14 +238,14 @@ OBJECT *ObjectTextOut(OBJECT **pList, char *szStr, int color,
 			}
 
 			// finally add the inter-character spacing
-			xJustify += FROM_32(pFont->xSpacing);
+			xJustify += pFont->xSpacing;
 
 			// next character in string
 			++szStr;
 		}
 
 		// adjust the text y position and add the inter-line spacing
-		yPos += yOffset + FROM_32(pFont->ySpacing);
+		yPos += yOffset + pFont->ySpacing;
 
 		// check for newline
 		if (c == LF_CHAR)
@@ -280,6 +253,8 @@ OBJECT *ObjectTextOut(OBJECT **pList, char *szStr, int color,
 			++szStr;
 	}
 
+	delete pFont;
+
 	// return head of list
 	return pFirst;
 }
@@ -298,9 +273,11 @@ bool IsCharImage(SCNHANDLE hFont, char c) {
 		return false;
 
 	// get font pointer
-	const FONT *pFont = (const FONT *)_vm->_handle->LockMem(hFont);
+	FONT *pFont = _vm->_handle->GetFont(hFont);
+	bool result = pFont->fontDef[c2] != 0;
+	delete pFont;
 
-	return GetFontDef(pFont, c2) != 0;
+	return result;
 }
 
 uint32 t3GetBaseColor()
diff --git a/engines/tinsel/text.h b/engines/tinsel/text.h
index 271e28e3a0..5bea6d6e1c 100644
--- a/engines/tinsel/text.h
+++ b/engines/tinsel/text.h
@@ -45,25 +45,12 @@ enum {
 #define C16_MAP		0xC000
 #define C16_FLAG_MASK	(C16_240 | C16_224 | C16_MAP)
 
-#include "common/pack-start.h"	// START STRUCT PACKING
-
 /**
  * Text font data structure.
  * @note only the pointer is used so the size of fontDef[] is not important.
  * It is currently set at 300 because it suited me for debugging.
  */
 struct 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
-	OBJ_INIT fontInit;		///< structure used to init text objects
-	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
@@ -72,9 +59,7 @@ struct T3_FONT {
 	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
+};
 
 
 /** structure for passing the correct parameters to ObjectTextOut */




More information about the Scummvm-git-logs mailing list