[Scummvm-cvs-logs] scummvm master -> 445980f010e236edf7af19673f4f01f5ed5a97ab

csnover csnover at users.noreply.github.com
Fri Mar 4 04:31:26 CET 2016


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

Summary:
9a280d3965 SCI32: Add all kBitmap signatures
445980f010 SCI32: Fix misidentification of createFontBitmap(CelInfo &)


Commit: 9a280d396532c9ac38cfd8589012dd47e659d002
    https://github.com/scummvm/scummvm/commit/9a280d396532c9ac38cfd8589012dd47e659d002
Author: Colin Snover (github.com at zetafleet.com)
Date: 2016-03-03T20:31:10-06:00

Commit Message:
SCI32: Add all kBitmap signatures

Not all SCI2.1late/SCI3 function signatures are fully known yet,
but all subops are now represented in the kernel tables.

Changed paths:
    engines/sci/engine/kernel.h
    engines/sci/engine/kernel_tables.h
    engines/sci/engine/kgraphics32.cpp
    engines/sci/graphics/celobj32.cpp
    engines/sci/graphics/celobj32.h
    engines/sci/graphics/text32.cpp
    engines/sci/graphics/text32.h



diff --git a/engines/sci/engine/kernel.h b/engines/sci/engine/kernel.h
index 3a6809a..f844d96 100644
--- a/engines/sci/engine/kernel.h
+++ b/engines/sci/engine/kernel.h
@@ -460,7 +460,22 @@ reg_t kUpdateScreenItem(EngineState *s, int argc, reg_t *argv);
 reg_t kDeleteScreenItem(EngineState *s, int argc, reg_t *argv);
 
 reg_t kCreateTextBitmap(EngineState *s, int argc, reg_t *argv);
-reg_t kDisposeTextBitmap(EngineState *s, int argc, reg_t *argv);
+reg_t kBitmap(EngineState *s, int argc, reg_t *argv);
+reg_t kBitmapCreate(EngineState *s, int argc, reg_t *argv);
+reg_t kBitmapDestroy(EngineState *s, int argc, reg_t *argv);
+reg_t kBitmapDrawLine(EngineState *s, int argc, reg_t *argv);
+reg_t kBitmapDrawView(EngineState *s, int argc, reg_t *argv);
+reg_t kBitmapDrawText(EngineState *s, int argc, reg_t *argv);
+reg_t kBitmapDrawColor(EngineState *s, int argc, reg_t *argv);
+reg_t kBitmapDrawBitmap(EngineState *s, int argc, reg_t *argv);
+reg_t kBitmapInvert(EngineState *s, int argc, reg_t *argv);
+reg_t kBitmapSetDisplace(EngineState *s, int argc, reg_t *argv);
+reg_t kBitmapCreateFromView(EngineState *s, int argc, reg_t *argv);
+reg_t kBitmapCopyPixels(EngineState *s, int argc, reg_t *argv);
+reg_t kBitmapClone(EngineState *s, int argc, reg_t *argv);
+reg_t kBitmapGetInfo(EngineState *s, int argc, reg_t *argv);
+reg_t kBitmapScale(EngineState *s, int argc, reg_t *argv);
+reg_t kBitmapCreateFromUnknown(EngineState *s, int argc, reg_t *argv);
 
 reg_t kAddPlane(EngineState *s, int argc, reg_t *argv);
 reg_t kDeletePlane(EngineState *s, int argc, reg_t *argv);
@@ -521,7 +536,6 @@ reg_t kScrollWindow(EngineState *s, int argc, reg_t *argv);
 reg_t kSetFontHeight(EngineState *s, int argc, reg_t *argv);
 reg_t kSetFontRes(EngineState *s, int argc, reg_t *argv);
 reg_t kFont(EngineState *s, int argc, reg_t *argv);
-reg_t kBitmap(EngineState *s, int argc, reg_t *argv);
 reg_t kAddLine(EngineState *s, int argc, reg_t *argv);
 reg_t kUpdateLine(EngineState *s, int argc, reg_t *argv);
 reg_t kDeleteLine(EngineState *s, int argc, reg_t *argv);
diff --git a/engines/sci/engine/kernel_tables.h b/engines/sci/engine/kernel_tables.h
index 88702e1..6258197 100644
--- a/engines/sci/engine/kernel_tables.h
+++ b/engines/sci/engine/kernel_tables.h
@@ -65,12 +65,14 @@ struct SciKernelMapSubEntry {
 #define SIG_SCI1             SCI_VERSION_1_EGA_ONLY, SCI_VERSION_1_LATE
 #define SIG_SCI11            SCI_VERSION_1_1, SCI_VERSION_1_1
 #define SIG_SINCE_SCI11      SCI_VERSION_1_1, SCI_VERSION_NONE
+#define SIG_SCI2             SCI_VERSION_2, SCI_VERSION_2
 #define SIG_SCI21EARLY       SCI_VERSION_2_1_EARLY, SCI_VERSION_2_1_EARLY
 #define SIG_UNTIL_SCI21EARLY SCI_VERSION_2, SCI_VERSION_2_1_EARLY
 #define SIG_UNTIL_SCI21MID   SCI_VERSION_2, SCI_VERSION_2_1_MIDDLE
 #define SIG_SINCE_SCI21      SCI_VERSION_2_1_EARLY, SCI_VERSION_3
 #define SIG_SINCE_SCI21MID   SCI_VERSION_2_1_MIDDLE, SCI_VERSION_3
 #define SIG_SINCE_SCI21LATE  SCI_VERSION_2_1_LATE, SCI_VERSION_3
+#define SIG_SCI3             SCI_VERSION_3, SCI_VERSION_3
 
 #define SIG_SCI16          SCI_VERSION_NONE, SCI_VERSION_1_1
 #define SIG_SCI32          SCI_VERSION_2, SCI_VERSION_NONE
@@ -300,6 +302,28 @@ static const SciKernelMapSubEntry kText_subops[] = {
 };
 
 //    version,         subId, function-mapping,                    signature,              workarounds
+static const SciKernelMapSubEntry kBitmap_subops[] = {
+	{ SIG_SINCE_SCI21,     0, MAP_CALL(BitmapCreate),              "iiii(i)(i)(i)",        NULL },
+	{ SIG_SINCE_SCI21,     1, MAP_CALL(BitmapDestroy),             "r",                    NULL },
+	{ SIG_SINCE_SCI21,     2, MAP_CALL(BitmapDrawLine),            "riiiii(i)(i)",         NULL },
+	{ SIG_SINCE_SCI21,     3, MAP_CALL(BitmapDrawView),            "riii(i)(i)(0)(i)(i)",  NULL },
+	{ SIG_SINCE_SCI21,     4, MAP_CALL(BitmapDrawText),            "rriiiiiiiiiii",        NULL },
+	{ SIG_SINCE_SCI21,     5, MAP_CALL(BitmapDrawColor),           "riiiii",               NULL },
+	{ SIG_SINCE_SCI21,     6, MAP_CALL(BitmapDrawBitmap),          "rr(i)(i)(i)",          NULL },
+	{ SIG_SINCE_SCI21,     7, MAP_CALL(BitmapInvert),              "riiiiii",              NULL },
+	{ SIG_SINCE_SCI21MID,  8, MAP_CALL(BitmapSetDisplace),         "rii",                  NULL },
+	{ SIG_SINCE_SCI21MID,  9, MAP_CALL(BitmapCreateFromView),      "iii(i)(i)(i)([r0])",   NULL },
+	{ SIG_SINCE_SCI21MID, 10, MAP_CALL(BitmapCopyPixels),          "rr",                   NULL },
+	{ SIG_SINCE_SCI21MID, 11, MAP_CALL(BitmapClone),               "r",                    NULL },
+	{ SIG_SINCE_SCI21LATE, 12, MAP_CALL(BitmapGetInfo),            "r(i)(i)",              NULL },
+	{ SIG_SINCE_SCI21LATE, 13, MAP_CALL(BitmapScale),              "r...ii",               NULL },
+	{ SIG_SCI3,           14, MAP_CALL(BitmapCreateFromUnknown),   "......",               NULL },
+	{ SIG_SCI3,           15, MAP_EMPTY(Bitmap),                   "(.*)",                 NULL },
+	{ SIG_SCI3,           16, MAP_EMPTY(Bitmap),                   "(.*)",                 NULL },
+	SCI_SUBOPENTRY_TERMINATOR
+};
+
+//    version,         subId, function-mapping,                    signature,              workarounds
 static const SciKernelMapSubEntry kList_subops[] = {
 	{ SIG_SINCE_SCI21,     0, MAP_CALL(NewList),                   "",                     NULL },
 	{ SIG_SINCE_SCI21,     1, MAP_CALL(DisposeList),               "l",                    NULL },
@@ -607,7 +631,7 @@ static SciKernelMapEntry s_kernelMap[] = {
 	{ MAP_CALL(CreateTextBitmap),  SIG_EVERYWHERE,           "i(.*)",                 NULL,            NULL },
 	{ MAP_CALL(DeletePlane),       SIG_EVERYWHERE,           "o",                     NULL,            NULL },
 	{ MAP_CALL(DeleteScreenItem),  SIG_EVERYWHERE,           "o",                     NULL,            NULL },
-	{ MAP_CALL(DisposeTextBitmap), SIG_EVERYWHERE,           "r",                     NULL,            NULL },
+	{ "DisposeTextBitmap", kBitmapDestroy, SIG_SCI2, SIGFOR_ALL, "r",                 NULL,            NULL },
 	{ MAP_CALL(FrameOut),          SIG_EVERYWHERE,           "(i)",                   NULL,            NULL },
 	{ MAP_CALL(GetHighPlanePri),   SIG_EVERYWHERE,           "",                      NULL,            NULL },
 	{ MAP_CALL(InPolygon),         SIG_EVERYWHERE,           "iio",                   NULL,            NULL },
@@ -693,7 +717,7 @@ static SciKernelMapEntry s_kernelMap[] = {
 	{ MAP_CALL(ScrollWindow),      SIG_EVERYWHERE,           "i(.*)",                 kScrollWindow_subops, NULL },
 	{ MAP_CALL(SetFontRes),        SIG_SCI21EARLY, SIGFOR_ALL, "ii",                  NULL,            NULL },
 	{ MAP_CALL(Font),              SIG_SINCE_SCI21MID, SIGFOR_ALL, "i(.*)",           kFont_subops,    NULL },
-	{ MAP_CALL(Bitmap),            SIG_EVERYWHERE,           "(.*)",                  NULL,            NULL },
+	{ MAP_CALL(Bitmap),            SIG_EVERYWHERE,           "(.*)",                  kBitmap_subops,  NULL },
 	{ MAP_CALL(AddLine),           SIG_EVERYWHERE,           "oiiiiiiiii",            NULL,            NULL },
 	{ MAP_CALL(UpdateLine),        SIG_EVERYWHERE,           "[r0]oiiiiiiiii",        NULL,            NULL },
 	{ MAP_CALL(DeleteLine),        SIG_EVERYWHERE,           "[r0]o",                 NULL,            NULL },
diff --git a/engines/sci/engine/kgraphics32.cpp b/engines/sci/engine/kgraphics32.cpp
index 36f637b..8fa7b96 100644
--- a/engines/sci/engine/kgraphics32.cpp
+++ b/engines/sci/engine/kgraphics32.cpp
@@ -49,11 +49,12 @@
 #include "sci/graphics/text16.h"
 #include "sci/graphics/view.h"
 #ifdef ENABLE_SCI32
-#include "sci/graphics/palette32.h"
+#include "sci/graphics/celobj32.h"
 #include "sci/graphics/controls32.h"
 #include "sci/graphics/font.h"	// TODO: remove once kBitmap is moved in a separate class
-#include "sci/graphics/text32.h"
 #include "sci/graphics/frameout.h"
+#include "sci/graphics/palette32.h"
+#include "sci/graphics/text32.h"
 #endif
 
 namespace Sci {
@@ -209,11 +210,6 @@ reg_t kCreateTextBitmap(EngineState *s, int argc, reg_t *argv) {
 	}
 }
 
-reg_t kDisposeTextBitmap(EngineState *s, int argc, reg_t *argv) {
-	g_sci->_gfxText32->disposeTextBitmap(argv[0]);
-	return s->r_acc;
-}
-
 reg_t kText(EngineState *s, int argc, reg_t *argv) {
 	if (!s)
 		return make_reg(0, getSciVersion());
@@ -503,183 +499,171 @@ reg_t kSetFontRes(EngineState *s, int argc, reg_t *argv) {
 	return NULL_REG;
 }
 
-// TODO: Eventually, all of the kBitmap operations should be put
-// in a separate class
+reg_t kBitmap(EngineState *s, int argc, reg_t *argv) {
+	if (!s)
+		return make_reg(0, getSciVersion());
+	error("not supposed to call this");
+}
 
-// NOTE: This size is correct only for SCI2.1mid; the size for
-// SCI2/2.1early is 36
-#define BITMAP_HEADER_SIZE 46
+reg_t kBitmapCreate(EngineState *s, int argc, reg_t *argv) {
+	uint32 bitmapHeaderSize = CelObjMem::getBitmapHeaderSize();
+	int16 width = argv[0].toSint16();
+	int16 height = argv[1].toSint16();
+	int16 skipColor = argv[2].toSint16();
+	int16 backColor = argv[3].toSint16();
+	int16 scaledWidth = argc > 4 ? argv[4].toSint16() : g_sci->_gfxText32->_scaledWidth;
+	int16 scaledHeight = argc > 5 ? argv[5].toSint16() : g_sci->_gfxText32->_scaledHeight;
+	bool useRemap = argc > 6 ? argv[6].toSint16() : false;
 
-reg_t kBitmap(EngineState *s, int argc, reg_t *argv) {
-	// Used for bitmap operations in SCI2.1 and SCI3.
-	// This is the SCI2.1 version, the functionality seems to have changed in SCI3.
+	reg_t bitmapMemId = s->_segMan->allocateHunkEntry("Bitmap()", width * height + bitmapHeaderSize);
+	byte *bitmap = s->_segMan->getHunkPointer(bitmapMemId);
+	memset(bitmap + bitmapHeaderSize, backColor, width * height);
+	CelObjMem::buildBitmapHeader(bitmap, width, height, skipColor, 0, 0, scaledWidth, scaledHeight, 0, useRemap);
+	return bitmapMemId;
+}
 
-	switch (argv[0].toUint16()) {
-	case 0:	// init bitmap surface
-		{
-		// 6 params, called e.g. from TextView::init() in Torin's Passage,
-		// script 64890 and TransView::init() in script 64884
-		uint16 width = argv[1].toUint16();
-		uint16 height = argv[2].toUint16();
-		//uint16 skip = argv[3].toUint16();
-		uint16 back = argv[4].toUint16();	// usually equals skip
-		//uint16 width2 = (argc >= 6) ? argv[5].toUint16() : 0;
-		//uint16 height2 = (argc >= 7) ? argv[6].toUint16() : 0;
-		//uint16 transparentFlag = (argc >= 8) ? argv[7].toUint16() : 0;
-
-		// TODO: skip, width2, height2, transparentFlag
-		// (used for transparent bitmaps)
-		int entrySize = width * height + BITMAP_HEADER_SIZE;
-		reg_t memoryId = s->_segMan->allocateHunkEntry("Bitmap()", entrySize);
-		byte *memoryPtr = s->_segMan->getHunkPointer(memoryId);
-		memset(memoryPtr, 0, BITMAP_HEADER_SIZE);	// zero out the bitmap header
-		memset(memoryPtr + BITMAP_HEADER_SIZE, back, width * height);
-		// Save totalWidth, totalHeight
-		// TODO: Save the whole bitmap header, like SSCI does
-		WRITE_SCI11ENDIAN_UINT16(memoryPtr, width);
-		WRITE_SCI11ENDIAN_UINT16(memoryPtr + 2, height);
-		WRITE_SCI11ENDIAN_UINT16(memoryPtr + 4, 0);
-		WRITE_SCI11ENDIAN_UINT16(memoryPtr + 6, 0);
-		memoryPtr[8] = 0;
-		WRITE_SCI11ENDIAN_UINT16(memoryPtr + 10, 0);
-		WRITE_SCI11ENDIAN_UINT16(memoryPtr + 20, BITMAP_HEADER_SIZE);
-		WRITE_SCI11ENDIAN_UINT32(memoryPtr + 28, 46);
-		WRITE_SCI11ENDIAN_UINT16(memoryPtr + 36, width);
-		WRITE_SCI11ENDIAN_UINT16(memoryPtr + 38, width);
-		return memoryId;
-		}
-		break;
-	case 1:	// dispose text bitmap surface
-		return kDisposeTextBitmap(s, argc - 1, argv + 1);
-	case 2:	// dispose bitmap surface, with extra param
-		// 2 params, called e.g. from MenuItem::dispose in Torin's Passage,
-		// script 64893
-		warning("kBitmap(2), unk1 %d, bitmap ptr %04x:%04x", argv[1].toUint16(), PRINT_REG(argv[2]));
-		break;
-	case 3:	// tiled surface
-		{
-		// 6 params, called e.g. from TiledBitmap::resize() in Torin's Passage,
-		// script 64869
-		reg_t hunkId = argv[1];	// obtained from kBitmap(0)
-		// The tiled view seems to always have 2 loops.
-		// These loops need to have 1 cel in loop 0 and 8 cels in loop 1.
-		uint16 viewNum = argv[2].toUint16();	// vTiles selector
-		uint16 loop = argv[3].toUint16();
-		uint16 cel = argv[4].toUint16();
-		uint16 x = argv[5].toUint16();
-		uint16 y = argv[6].toUint16();
-
-		byte *memoryPtr = s->_segMan->getHunkPointer(hunkId);
-		// Get totalWidth, totalHeight
-		uint16 totalWidth = READ_LE_UINT16(memoryPtr);
-		uint16 totalHeight = READ_LE_UINT16(memoryPtr + 2);
-		byte *bitmap = memoryPtr + BITMAP_HEADER_SIZE;
-
-		GfxView *view = g_sci->_gfxCache->getView(viewNum);
-		uint16 tileWidth = view->getWidth(loop, cel);
-		uint16 tileHeight = view->getHeight(loop, cel);
-		const byte *tileBitmap = view->getBitmap(loop, cel);
-		uint16 width = MIN<uint16>(totalWidth - x, tileWidth);
-		uint16 height = MIN<uint16>(totalHeight - y, tileHeight);
-
-		for (uint16 curY = 0; curY < height; curY++) {
-			for (uint16 curX = 0; curX < width; curX++) {
-				bitmap[(curY + y) * totalWidth + (curX + x)] = tileBitmap[curY * tileWidth + curX];
-			}
-		}
+reg_t kBitmapDestroy(EngineState *s, int argc, reg_t *argv) {
+	s->_segMan->freeHunkEntry(argv[0]);
+	return NULL_REG;
+}
 
-		}
-		break;
-	case 4:	// add text to bitmap
-		{
-			warning("kBitmap(4)");
-			return NULL_REG;
-		}
-#if 0
-		// 13 params, called e.g. from TextButton::createBitmap() in Torin's Passage,
-		// script 64894
-		reg_t hunkId = argv[1];	// obtained from kBitmap(0)
-		Common::String text = s->_segMan->getString(argv[2]);
-		uint16 textX = argv[3].toUint16();
-		uint16 textY = argv[4].toUint16();
-		//reg_t unk5 = argv[5];
-		//reg_t unk6 = argv[6];
-		//reg_t unk7 = argv[7];	// skip?
-		//reg_t unk8 = argv[8];	// back?
-		//reg_t unk9 = argv[9];
-		uint16 fontId = argv[10].toUint16();
-		//uint16 mode = argv[11].toUint16();
-		uint16 dimmed = argv[12].toUint16();
-		//warning("kBitmap(4): bitmap ptr %04x:%04x, font %d, mode %d, dimmed %d - text: \"%s\"",
-		//		PRINT_REG(bitmapPtr), font, mode, dimmed, text.c_str());
-		uint16 foreColor = 255;	// TODO
-
-		byte *memoryPtr = s->_segMan->getHunkPointer(hunkId);
-		// Get totalWidth, totalHeight
-		uint16 totalWidth = READ_LE_UINT16(memoryPtr);
-		uint16 totalHeight = READ_LE_UINT16(memoryPtr + 2);
-		byte *bitmap = memoryPtr + BITMAP_HEADER_SIZE;
-
-		GfxFont *font = g_sci->_gfxCache->getFont(fontId);
-
-		int16 charCount = 0;
-		uint16 curX = textX, curY = textY;
-		const char *txt = text.c_str();
-
-		while (*txt) {
-			charCount = g_sci->_gfxText32->GetLongest(txt, totalWidth, font);
-			if (charCount == 0)
-				break;
-
-			for (int i = 0; i < charCount; i++) {
-				unsigned char curChar = txt[i];
-				font->drawToBuffer(curChar, curY, curX, foreColor, dimmed, bitmap, totalWidth, totalHeight);
-				curX += font->getCharWidth(curChar);
-			}
-
-			curX = textX;
-			curY += font->getHeight();
-			txt += charCount;
-			while (*txt == ' ')
-				txt++; // skip over breaking spaces
-		}
+reg_t kBitmapDrawLine(EngineState *s, int argc, reg_t *argv) {
+	// bitmapMemId, (x1, y1, x2, y2) OR (x2, y2, x1, y1), line color, unknown int, unknown int
+	return kStubNull(s, argc + 1, argv - 1);
+}
+
+reg_t kBitmapDrawView(EngineState *s, int argc, reg_t *argv) {
+	// viewId, loopNo, celNo, displace x, displace y, unused, view x, view y
+
+	// called e.g. from TiledBitmap::resize() in Torin's Passage, script 64869
+	// The tiled view seems to always have 2 loops.
+	// These loops need to have 1 cel in loop 0 and 8 cels in loop 1.
+
+	return kStubNull(s, argc + 1, argv - 1);
 
+#if 0
+	// tiled surface
+	// 6 params, called e.g. from TiledBitmap::resize() in Torin's Passage,
+	// script 64869
+	reg_t hunkId = argv[1];	// obtained from kBitmap(0)
+	// The tiled view seems to always have 2 loops.
+	// These loops need to have 1 cel in loop 0 and 8 cels in loop 1.
+	uint16 viewNum = argv[2].toUint16();	// vTiles selector
+	uint16 loop = argv[3].toUint16();
+	uint16 cel = argv[4].toUint16();
+	uint16 x = argv[5].toUint16();
+	uint16 y = argv[6].toUint16();
+
+	byte *memoryPtr = s->_segMan->getHunkPointer(hunkId);
+	// Get totalWidth, totalHeight
+	uint16 totalWidth = READ_LE_UINT16(memoryPtr);
+	uint16 totalHeight = READ_LE_UINT16(memoryPtr + 2);
+	byte *bitmap = memoryPtr + BITMAP_HEADER_SIZE;
+
+	GfxView *view = g_sci->_gfxCache->getView(viewNum);
+	uint16 tileWidth = view->getWidth(loop, cel);
+	uint16 tileHeight = view->getHeight(loop, cel);
+	const byte *tileBitmap = view->getBitmap(loop, cel);
+	uint16 width = MIN<uint16>(totalWidth - x, tileWidth);
+	uint16 height = MIN<uint16>(totalHeight - y, tileHeight);
+
+	for (uint16 curY = 0; curY < height; curY++) {
+		for (uint16 curX = 0; curX < width; curX++) {
+			bitmap[(curY + y) * totalWidth + (curX + x)] = tileBitmap[curY * tileWidth + curX];
 		}
-		break;
+	}
 #endif
-	case 5:	// fill with color
-		{
-		// 6 params, called e.g. from TextView::init() and TextView::draw()
-		// in Torin's Passage, script 64890
-		reg_t hunkId = argv[1];	// obtained from kBitmap(0)
-		uint16 x = argv[2].toUint16();
-		uint16 y = argv[3].toUint16();
-		uint16 fillWidth = argv[4].toUint16();	// width - 1
-		uint16 fillHeight = argv[5].toUint16();	// height - 1
-		uint16 back = argv[6].toUint16();
-
-		byte *memoryPtr = s->_segMan->getHunkPointer(hunkId);
-		// Get totalWidth, totalHeight
-		uint16 totalWidth = READ_LE_UINT16(memoryPtr);
-		uint16 totalHeight = READ_LE_UINT16(memoryPtr + 2);
-		uint16 width = MIN<uint16>(totalWidth - x, fillWidth);
-		uint16 height = MIN<uint16>(totalHeight - y, fillHeight);
-		byte *bitmap = memoryPtr + BITMAP_HEADER_SIZE;
-
-		for (uint16 curY = 0; curY < height; curY++) {
-			for (uint16 curX = 0; curX < width; curX++) {
-				bitmap[(curY + y) * totalWidth + (curX + x)] = back;
-			}
-		}
+}
+
+reg_t kBitmapDrawText(EngineState *s, int argc, reg_t *argv) {
+	// called e.g. from TextButton::createBitmap() in Torin's Passage, script 64894
+
+	// bitmap, text, textLeft, textTop, textRight, textBottom, foreColor, backColor, skipColor, fontNo, alignment, borderColor, dimmed
+	return kStubNull(s, argc + 1, argv - 1);
+}
 
+reg_t kBitmapDrawColor(EngineState *s, int argc, reg_t *argv) {
+	// bitmap, left, top, right, bottom, color
+
+	// called e.g. from TextView::init() and TextView::draw() in Torin's Passage, script 64890
+	return kStubNull(s, argc + 1, argv - 1);
+#if 0
+	reg_t hunkId = argv[1];	// obtained from kBitmap(0)
+	uint16 x = argv[2].toUint16();
+	uint16 y = argv[3].toUint16();
+	uint16 fillWidth = argv[4].toUint16();	// width - 1
+	uint16 fillHeight = argv[5].toUint16();	// height - 1
+	uint16 back = argv[6].toUint16();
+
+	byte *memoryPtr = s->_segMan->getHunkPointer(hunkId);
+	// Get totalWidth, totalHeight
+	uint16 totalWidth = READ_LE_UINT16(memoryPtr);
+	uint16 totalHeight = READ_LE_UINT16(memoryPtr + 2);
+	uint16 width = MIN<uint16>(totalWidth - x, fillWidth);
+	uint16 height = MIN<uint16>(totalHeight - y, fillHeight);
+	byte *bitmap = memoryPtr + BITMAP_HEADER_SIZE;
+
+	for (uint16 curY = 0; curY < height; curY++) {
+		for (uint16 curX = 0; curX < width; curX++) {
+			bitmap[(curY + y) * totalWidth + (curX + x)] = back;
 		}
-		break;
-	default:
-		kStub(s, argc, argv);
-		break;
 	}
+#endif
+}
 
-	return s->r_acc;
+reg_t kBitmapDrawBitmap(EngineState *s, int argc, reg_t *argv) {
+	// target bitmap, source bitmap, x, y, unknown boolean
+
+	return kStubNull(s, argc + 1, argv - 1);
+}
+
+reg_t kBitmapInvert(EngineState *s, int argc, reg_t *argv) {
+	// bitmap, left, top, right, bottom, foreColor, backColor
+
+	return kStubNull(s, argc + 1, argv - 1);
+}
+
+reg_t kBitmapSetDisplace(EngineState *s, int argc, reg_t *argv) {
+	// bitmap, x, y
+
+	return kStubNull(s, argc + 1, argv - 1);
+}
+
+reg_t kBitmapCreateFromView(EngineState *s, int argc, reg_t *argv) {
+	// viewId, loopNo, celNo, skipColor, backColor, useRemap, source overlay bitmap
+
+	return kStub(s, argc + 1, argv - 1);
+}
+
+reg_t kBitmapCopyPixels(EngineState *s, int argc, reg_t *argv) {
+	// target bitmap, source bitmap
+
+	return kStubNull(s, argc + 1, argv - 1);
+}
+
+reg_t kBitmapClone(EngineState *s, int argc, reg_t *argv) {
+	// bitmap
+
+	return kStub(s, argc + 1, argv - 1);
+}
+
+reg_t kBitmapGetInfo(EngineState *s, int argc, reg_t *argv) {
+	// bitmap
+
+	// argc 1 = get width
+	// argc 2 = pixel at row 0 col n
+	// argc 3 = pixel at row n col n
+	return kStub(s, argc + 1, argv - 1);
+}
+
+reg_t kBitmapScale(EngineState *s, int argc, reg_t *argv) {
+	// TODO: SCI3
+	return kStubNull(s, argc + 1, argv - 1);
+}
+
+reg_t kBitmapCreateFromUnknown(EngineState *s, int argc, reg_t *argv) {
+	// TODO: SCI3
+	return kStub(s, argc + 1, argv - 1);
 }
 
 // Used for edit boxes in save/load dialogs. It's a rewritten version of kEditControl,
diff --git a/engines/sci/graphics/celobj32.cpp b/engines/sci/graphics/celobj32.cpp
index 62db02b..787d295 100644
--- a/engines/sci/graphics/celobj32.cpp
+++ b/engines/sci/graphics/celobj32.cpp
@@ -968,6 +968,40 @@ byte *CelObjPic::getResPointer() const {
 
 #pragma mark -
 #pragma mark CelObjMem
+void CelObjMem::buildBitmapHeader(byte *bitmap, const int16 width, const int16 height, const uint8 skipColor, const int16 displaceX, const int16 displaceY, const int16 scaledWidth, const int16 scaledHeight, const uint32 hunkPaletteOffset, const bool useRemap) {
+	const uint16 bitmapHeaderSize = getBitmapHeaderSize();
+
+	WRITE_SCI11ENDIAN_UINT16(bitmap + 0, width);
+	WRITE_SCI11ENDIAN_UINT16(bitmap + 2, height);
+	WRITE_SCI11ENDIAN_UINT16(bitmap + 4, (uint16)displaceX);
+	WRITE_SCI11ENDIAN_UINT16(bitmap + 6, (uint16)displaceY);
+	bitmap[8] = skipColor;
+	bitmap[9] = 0;
+	WRITE_SCI11ENDIAN_UINT16(bitmap + 10, 0);
+
+	if (useRemap) {
+		bitmap[10] |= 2;
+	}
+
+	WRITE_SCI11ENDIAN_UINT32(bitmap + 12, width * height);
+	WRITE_SCI11ENDIAN_UINT32(bitmap + 16, 0);
+
+	if (hunkPaletteOffset) {
+		WRITE_SCI11ENDIAN_UINT32(bitmap + 20, hunkPaletteOffset + bitmapHeaderSize);
+	} else {
+		WRITE_SCI11ENDIAN_UINT32(bitmap + 20, 0);
+	}
+
+	WRITE_SCI11ENDIAN_UINT32(bitmap + 24, bitmapHeaderSize);
+	WRITE_SCI11ENDIAN_UINT32(bitmap + 28, bitmapHeaderSize);
+	WRITE_SCI11ENDIAN_UINT32(bitmap + 32, 0);
+
+	if (bitmapHeaderSize >= 40) {
+		WRITE_SCI11ENDIAN_UINT16(bitmap + 36, scaledWidth);
+		WRITE_SCI11ENDIAN_UINT16(bitmap + 38, scaledHeight);
+	}
+}
+
 CelObjMem::CelObjMem(const reg_t bitmap) {
 	_info.type = kCelTypeMem;
 	_info.bitmap = bitmap;
@@ -976,8 +1010,9 @@ CelObjMem::CelObjMem(const reg_t bitmap) {
 	_celHeaderOffset = 0;
 	_transparent = true;
 
+	const uint32 bitmapHeaderSize = getBitmapHeaderSize();
 	byte *bitmapData = g_sci->getEngineState()->_segMan->getHunkPointer(bitmap);
-	if (bitmapData == nullptr || READ_SCI11ENDIAN_UINT32(bitmapData + 28) != 46) {
+	if (bitmapData == nullptr || READ_SCI11ENDIAN_UINT32(bitmapData + 28) != bitmapHeaderSize) {
 		error("Invalid Text bitmap %04x:%04x", PRINT_REG(bitmap));
 	}
 
@@ -986,8 +1021,12 @@ CelObjMem::CelObjMem(const reg_t bitmap) {
 	_displace.x = READ_SCI11ENDIAN_UINT16(bitmapData + 4);
 	_displace.y = READ_SCI11ENDIAN_UINT16(bitmapData + 6);
 	_transparentColor = bitmapData[8];
-	_scaledWidth = READ_SCI11ENDIAN_UINT16(bitmapData + 36);
-	_scaledHeight = READ_SCI11ENDIAN_UINT16(bitmapData + 38);
+	if (bitmapHeaderSize >= 40) {
+		_scaledWidth = READ_SCI11ENDIAN_UINT16(bitmapData + 36);
+		_scaledHeight = READ_SCI11ENDIAN_UINT16(bitmapData + 38);
+	} else {
+		error("TODO: SCI2 bitmaps not implemented yet!");
+	}
 	_hunkPaletteOffset = READ_SCI11ENDIAN_UINT16(bitmapData + 20);
 	_remap = (READ_SCI11ENDIAN_UINT16(bitmapData + 10) & 2) ? true : false;
 }
diff --git a/engines/sci/graphics/celobj32.h b/engines/sci/graphics/celobj32.h
index 1422b76..5707333 100644
--- a/engines/sci/graphics/celobj32.h
+++ b/engines/sci/graphics/celobj32.h
@@ -547,6 +547,34 @@ public:
  */
 class CelObjMem : public CelObj {
 public:
+	/**
+	 * Writes a bitmap header to the given data buffer.
+	 */
+	static void buildBitmapHeader(byte *bitmap, const int16 width, const int16 height, const uint8 skipColor, const int16 displaceX, const int16 displaceY, const int16 scaledWidth, const int16 scaledHeight, const uint32 hunkPaletteOffset, const bool useRemap);
+
+	/**
+	 * Gets the size of the bitmap header for the current
+	 * engine version.
+	 */
+	inline static uint32 getBitmapHeaderSize() {
+		// TODO: These values are accurate for each engine, but there may be no reason
+		// to not simply just always use size 40, since SCI2.1mid does not seem to
+		// actually store any data above byte 40, and SCI2 did not allow bitmaps with
+		// scaling resolutions other than the default (320x200). Perhaps SCI3 used
+		// the extra bytes, or there is some reason why they tried to align the header
+		// size with other headers like pic headers?
+//		uint32 bitmapHeaderSize;
+//		if (getSciVersion() >= SCI_VERSION_2_1_MIDDLE) {
+//			bitmapHeaderSize = 46;
+//		} else if (getSciVersion() == SCI_VERSION_2_1_EARLY) {
+//			bitmapHeaderSize = 40;
+//		} else {
+//			bitmapHeaderSize = 36;
+//		}
+//		return bitmapHeaderSize;
+		return 46;
+	}
+
 	CelObjMem(reg_t bitmap);
 	virtual ~CelObjMem() override {};
 
diff --git a/engines/sci/graphics/text32.cpp b/engines/sci/graphics/text32.cpp
index d7738b2..ca132d8 100644
--- a/engines/sci/graphics/text32.cpp
+++ b/engines/sci/graphics/text32.cpp
@@ -29,6 +29,7 @@
 #include "sci/engine/selector.h"
 #include "sci/engine/state.h"
 #include "sci/graphics/cache.h"
+#include "sci/graphics/celobj32.h"
 #include "sci/graphics/compare.h"
 #include "sci/graphics/font.h"
 #include "sci/graphics/frameout.h"
@@ -59,37 +60,6 @@ GfxText32::GfxText32(SegManager *segMan, GfxCache *fonts, GfxScreen *screen) :
 		_font = _cache->getFont(_defaultFontId);
 	}
 
-#define BITMAP_HEADER_SIZE 46
-void GfxText32::buildBitmapHeader(byte *bitmap, const int16 width, const int16 height, const uint8 skipColor, const int16 displaceX, const int16 displaceY, const int16 scaledWidth, const int16 scaledHeight, const uint32 hunkPaletteOffset, const bool useRemap) const {
-
-	WRITE_SCI11ENDIAN_UINT16(bitmap + 0, width);
-	WRITE_SCI11ENDIAN_UINT16(bitmap + 2, height);
-	WRITE_SCI11ENDIAN_UINT16(bitmap + 4, (uint16)displaceX);
-	WRITE_SCI11ENDIAN_UINT16(bitmap + 6, (uint16)displaceY);
-	bitmap[8] = skipColor;
-	bitmap[9] = 0;
-	WRITE_SCI11ENDIAN_UINT16(bitmap + 10, 0);
-
-	if (useRemap) {
-		bitmap[10] |= 2;
-	}
-
-	WRITE_SCI11ENDIAN_UINT32(bitmap + 12, width * height);
-	WRITE_SCI11ENDIAN_UINT32(bitmap + 16, 0);
-
-	if (hunkPaletteOffset) {
-		WRITE_SCI11ENDIAN_UINT32(bitmap + 20, hunkPaletteOffset + BITMAP_HEADER_SIZE);
-	} else {
-		WRITE_SCI11ENDIAN_UINT32(bitmap + 20, 0);
-	}
-
-	WRITE_SCI11ENDIAN_UINT32(bitmap + 24, BITMAP_HEADER_SIZE);
-	WRITE_SCI11ENDIAN_UINT32(bitmap + 28, BITMAP_HEADER_SIZE);
-	WRITE_SCI11ENDIAN_UINT32(bitmap + 32, 0);
-	WRITE_SCI11ENDIAN_UINT16(bitmap + 36, scaledWidth);
-	WRITE_SCI11ENDIAN_UINT16(bitmap + 38, scaledHeight);
-}
-
 reg_t GfxText32::createFontBitmap(int16 width, int16 height, const Common::Rect &rect, const Common::String &text, const uint8 foreColor, const uint8 backColor, const uint8 skipColor, const GuiResourceId fontId, const TextAlign alignment, const int16 borderColor, const bool dimmed, const bool doScaling, reg_t *outBitmapObject) {
 
 	_field_22 = 0;
@@ -128,10 +98,10 @@ reg_t GfxText32::createFontBitmap(int16 width, int16 height, const Common::Rect
 		_textRect = Common::Rect();
 	}
 
-	_bitmap = _segMan->allocateHunkEntry("FontBitmap()", _width * _height + BITMAP_HEADER_SIZE);
+	_bitmap = _segMan->allocateHunkEntry("FontBitmap()", _width * _height + CelObjMem::getBitmapHeaderSize());
 
 	byte *bitmap = _segMan->getHunkPointer(_bitmap);
-	buildBitmapHeader(bitmap, _width, _height, _skipColor, 0, 0, _scaledWidth, _scaledHeight, 0, false);
+	CelObjMem::buildBitmapHeader(bitmap, _width, _height, _skipColor, 0, 0, _scaledWidth, _scaledHeight, 0, false);
 
 	erase(bitmapRect, false);
 
@@ -526,10 +496,6 @@ void GfxText32::erase(const Common::Rect &rect, const bool doScaling) {
 	buffer.fillRect(targetRect, _backColor);
 }
 
-void GfxText32::disposeTextBitmap(reg_t hunkId) {
-	_segMan->freeHunkEntry(hunkId);
-}
-
 int16 GfxText32::getStringWidth(const Common::String &text) {
 	// TODO: The fact that this double-scales the text makes it
 	// seem pretty unlikely that this is ever called in real life
diff --git a/engines/sci/graphics/text32.h b/engines/sci/graphics/text32.h
index f9a302a..d95792a 100644
--- a/engines/sci/graphics/text32.h
+++ b/engines/sci/graphics/text32.h
@@ -132,11 +132,6 @@ private:
 	 */
 	Common::Point _drawPosition;
 
-	// TODO: This is general for all CelObjMem and should be
-	// put in a single location, like maybe as a static
-	// method of CelObjMem?!
-	void buildBitmapHeader(byte *bitmap, const int16 width, const int16 height, const uint8 skipColor, const int16 displaceX, const int16 displaceY, const int16 scaledWidth, const int16 scaledHeight, const uint32 hunkPaletteOffset, const bool useRemap) const;
-
 	void drawFrame(const Common::Rect &rect, const int16 size, const uint8 color, const bool doScaling);
 	void drawTextBox();
 	void erase(const Common::Rect &rect, const bool doScaling);


Commit: 445980f010e236edf7af19673f4f01f5ed5a97ab
    https://github.com/scummvm/scummvm/commit/445980f010e236edf7af19673f4f01f5ed5a97ab
Author: Colin Snover (github.com at zetafleet.com)
Date: 2016-03-03T21:29:53-06:00

Commit Message:
SCI32: Fix misidentification of createFontBitmap(CelInfo &)

Changed paths:
    engines/sci/engine/kgraphics32.cpp
    engines/sci/graphics/text32.cpp
    engines/sci/graphics/text32.h



diff --git a/engines/sci/engine/kgraphics32.cpp b/engines/sci/engine/kgraphics32.cpp
index 8fa7b96..0463b12 100644
--- a/engines/sci/engine/kgraphics32.cpp
+++ b/engines/sci/engine/kgraphics32.cpp
@@ -206,7 +206,7 @@ reg_t kCreateTextBitmap(EngineState *s, int argc, reg_t *argv) {
 		celInfo.loopNo = readSelectorValue(segMan, object, SELECTOR(loop));
 		celInfo.celNo = readSelectorValue(segMan, object, SELECTOR(cel));
 		reg_t out;
-		return g_sci->_gfxText32->createTitledFontBitmap(celInfo, rect, text, foreColor, backColor, fontId, skipColor, borderColor, dimmed, &out);
+		return g_sci->_gfxText32->createFontBitmap(celInfo, rect, text, foreColor, backColor, fontId, skipColor, borderColor, dimmed, &out);
 	}
 }
 
diff --git a/engines/sci/graphics/text32.cpp b/engines/sci/graphics/text32.cpp
index ca132d8..8e3222f 100644
--- a/engines/sci/graphics/text32.cpp
+++ b/engines/sci/graphics/text32.cpp
@@ -115,9 +115,68 @@ reg_t GfxText32::createFontBitmap(int16 width, int16 height, const Common::Rect
 	return _bitmap;
 }
 
-reg_t GfxText32::createTitledFontBitmap(CelInfo32 &celInfo, Common::Rect &rect, Common::String &text, int16 foreColor, int16 backColor, int font, int16 skipColor, int16 borderColor, bool dimmed, void *unknown1) {
-	warning("TODO: createTitledFontBitmap");
-	return NULL_REG;
+reg_t GfxText32::createFontBitmap(const CelInfo32 &celInfo, const Common::Rect &rect, const Common::String &text, const int16 foreColor, const int16 backColor, const GuiResourceId fontId, const int16 skipColor, const int16 borderColor, const bool dimmed, reg_t *outBitmapObject) {
+	_field_22 = 0;
+	_borderColor = borderColor;
+	_text = text;
+	_textRect = rect;
+	_foreColor = foreColor;
+	_dimmed = dimmed;
+
+	setFont(fontId);
+
+	int16 scriptWidth = g_sci->_gfxFrameout->getCurrentBuffer().scriptWidth;
+	int16 scriptHeight = g_sci->_gfxFrameout->getCurrentBuffer().scriptHeight;
+
+	int borderSize = 1;
+	mulinc(_textRect, Ratio(_scaledWidth, scriptWidth), Ratio(_scaledHeight, scriptHeight));
+
+	CelObjView view(celInfo.resourceId, celInfo.loopNo, celInfo.celNo);
+	_skipColor = view._transparentColor;
+	_width = view._width * _scaledWidth / view._scaledWidth;
+	_height = view._height * _scaledHeight / view._scaledHeight;
+
+	Common::Rect bitmapRect(_width, _height);
+	if (_textRect.intersects(bitmapRect)) {
+		_textRect.clip(bitmapRect);
+	} else {
+		_textRect = Common::Rect();
+	}
+
+	_bitmap = _segMan->allocateHunkEntry("FontBitmap()", _width * _height + CelObjMem::getBitmapHeaderSize());
+	byte *bitmap = _segMan->getHunkPointer(_bitmap);
+	CelObjMem::buildBitmapHeader(bitmap, _width, _height, _skipColor, 0, 0, _scaledWidth, _scaledHeight, 0, false);
+
+	Buffer buffer(_width, _height, bitmap + READ_SCI11ENDIAN_UINT32(bitmap + 28));
+
+	// NOTE: The engine filled the bitmap pixels with 11 here, which is silly
+	// because then it just erased the bitmap using the skip color. So we don't
+	// fill the bitmap redundantly here.
+
+	_backColor = _skipColor;
+	erase(bitmapRect, false);
+	_backColor = backColor;
+
+	view.draw(buffer, bitmapRect, Common::Point(0, 0), false, Ratio(_scaledWidth, view._scaledWidth), Ratio(_scaledHeight, view._scaledHeight));
+
+	if (_backColor != skipColor && _foreColor != skipColor) {
+		erase(_textRect, false);
+	}
+
+	if (text.size() > 0) {
+		if (_foreColor == skipColor) {
+			error("TODO: Implement transparent text");
+		} else {
+			if (borderColor != -1) {
+				drawFrame(bitmapRect, borderSize, _borderColor, false);
+			}
+
+			drawTextBox();
+		}
+	}
+
+	*outBitmapObject = _bitmap;
+	return _bitmap;
 }
 
 void GfxText32::setFont(const GuiResourceId fontId) {
diff --git a/engines/sci/graphics/text32.h b/engines/sci/graphics/text32.h
index d95792a..5de54d3 100644
--- a/engines/sci/graphics/text32.h
+++ b/engines/sci/graphics/text32.h
@@ -202,11 +202,16 @@ public:
 	 */
 	GfxFont *_font;
 
+	/**
+	 * Creates a plain font bitmap with a flat color
+	 * background.
+	 */
 	reg_t createFontBitmap(int16 width, int16 height, const Common::Rect &rect, const Common::String &text, const uint8 foreColor, const uint8 backColor, const uint8 skipColor, const GuiResourceId fontId, TextAlign alignment, const int16 borderColor, bool dimmed, const bool doScaling, reg_t *outBitmapObject);
 
-	reg_t createTitledFontBitmap(CelInfo32 &celInfo, Common::Rect &rect, Common::String &text, int16 foreColor, int16 backColor, int font, int16 skipColor, int16 borderColor, bool dimmed, void *unknown1);
-
-	void disposeTextBitmap(reg_t hunkId);
+	/**
+	 * Creates a font bitmap with a view background.
+	 */
+	reg_t createFontBitmap(const CelInfo32 &celInfo, const Common::Rect &rect, const Common::String &text, const int16 foreColor, const int16 backColor, const GuiResourceId fontId, const int16 skipColor, const int16 borderColor, const bool dimmed, reg_t *outBitmapObject);
 
 	/**
 	 * Sets the font to be used for rendering and






More information about the Scummvm-git-logs mailing list