[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