[Scummvm-cvs-logs] scummvm master -> de3f6a19ed6ca98ad152f5038c1db1f70f2c72ed

bluegr md5 at scummvm.org
Thu Jun 7 10:28:57 CEST 2012


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:
de3f6a19ed SCI: Initial implementation of kScrollWindow, used in some SCI21 games


Commit: de3f6a19ed6ca98ad152f5038c1db1f70f2c72ed
    https://github.com/scummvm/scummvm/commit/de3f6a19ed6ca98ad152f5038c1db1f70f2c72ed
Author: Filippos Karapetis (md5 at scummvm.org)
Date: 2012-06-07T01:27:59-07:00

Commit Message:
SCI: Initial implementation of kScrollWindow, used in some SCI21 games

This is used in LSL6 hires and SQ6. This initial implementation is hackish
and only works in SQ6 (nothing is shown in LSL6)

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



diff --git a/engines/sci/engine/kernel_tables.h b/engines/sci/engine/kernel_tables.h
index 4ddf053..254a479 100644
--- a/engines/sci/engine/kernel_tables.h
+++ b/engines/sci/engine/kernel_tables.h
@@ -564,7 +564,7 @@ static SciKernelMapEntry s_kernelMap[] = {
 	{ MAP_CALL(GetSierraProfileInt), SIG_EVERYWHERE,         "rri",                   NULL,            NULL },
 	{ MAP_CALL(CelInfo),           SIG_EVERYWHERE,           "iiiiii",                NULL,            NULL },
 	{ MAP_CALL(SetLanguage),       SIG_EVERYWHERE,           "r",                     NULL,            NULL },
-	{ MAP_CALL(ScrollWindow),      SIG_EVERYWHERE,           "(.*)",                  NULL,            NULL },
+	{ MAP_CALL(ScrollWindow),      SIG_EVERYWHERE,           "io(.*)",                NULL,            NULL },
 	{ MAP_CALL(SetFontRes),        SIG_EVERYWHERE,           "ii",                    NULL,            NULL },
 	{ MAP_CALL(Font),              SIG_EVERYWHERE,           "i(.*)",                 NULL,            NULL },
 	{ MAP_CALL(Bitmap),            SIG_EVERYWHERE,           "(.*)",                  NULL,            NULL },
diff --git a/engines/sci/engine/kgraphics32.cpp b/engines/sci/engine/kgraphics32.cpp
index 2bb8288..71c4949 100644
--- a/engines/sci/engine/kgraphics32.cpp
+++ b/engines/sci/engine/kgraphics32.cpp
@@ -308,103 +308,91 @@ reg_t kCelInfo(EngineState *s, int argc, reg_t *argv) {
 }
 
 reg_t kScrollWindow(EngineState *s, int argc, reg_t *argv) {
-	// Used by Phantasmagoria 1 and SQ6. In SQ6, it is used for the messages
-	// shown in the scroll window at the bottom of the screen.
-
-	// TODO: This is all a stub/skeleton, thus we're invoking kStub() for now
-	kStub(s, argc, argv);
-
-	switch (argv[0].toUint16()) {
+	// Used by SQ6 and LSL6 hires for the text area in the bottom of the
+	// screen. The relevant scripts also exist in Phantasmagoria 1, but they're
+	// unused. This is always called by scripts 64906 (ScrollerWindow) and
+	// 64907 (ScrollableWindow).
+
+	reg_t kWindow = argv[1];
+	uint16 op = argv[0].toUint16();
+	switch (op) {
 	case 0:	// Init
-		// 2 parameters
-		// argv[1] points to the scroll object (e.g. textScroller in SQ6)
-		// argv[2] is an integer (e.g. 0x32)
-		break;
-	case 1: // Show message
+		g_sci->_gfxFrameout->initScrollText(argv[2].toUint16());	// maxItems
+		g_sci->_gfxFrameout->clearScrollTexts();
+		return argv[1];	// kWindow
+	case 1: // Show message, called by ScrollableWindow::addString
+	case 14: // Modify message, called by ScrollableWindow::modifyString
 		// 5 or 6 parameters
 		// Seems to be called with 5 parameters when the narrator speaks, and
 		// with 6 when Roger speaks
-		// argv[1] unknown (usually 0)
-		// argv[2] the text to show
-		// argv[3] a small integer (e.g. 0x32)
-		// argv[4] a small integer (e.g. 0x54)
-		// argv[5] optional, unknown (usually 0)
-		warning("kScrollWindow: '%s'", s->_segMan->getString(argv[2]).c_str());
-		break;
-	case 2: // Clear
-		// 2 parameters
-		// TODO
-		break;
-	case 3: // Page up
-		// 2 parameters
-		// TODO
-		break;
-	case 4: // Page down
-		// 2 parameters
-		// TODO
+		{
+		Common::String text = s->_segMan->getString(argv[2]);
+		uint16 x = 0;//argv[3].toUint16();	// TODO: can't be x (values are all wrong)
+		uint16 y = 0;//argv[4].toUint16();	// TODO: can't be y (values are all wrong)
+		// TODO: argv[5] is an optional unknown parameter (an integer set to 0)
+		g_sci->_gfxFrameout->addScrollTextEntry(text, kWindow, x, y, (op == 14));
+		}
 		break;
-	case 5: // Up arrow
-		// 2 parameters
-		// TODO
+	case 2: // Clear, called by ScrollableWindow::erase
+		g_sci->_gfxFrameout->clearScrollTexts();
 		break;
-	case 6: // Down arrow
-		// 2 parameters
+	case 3: // Page up, called by ScrollableWindow::scrollTo
 		// TODO
+		kStub(s, argc, argv);
 		break;
-	case 7: // Home
-		// 2 parameters
+	case 4: // Page down, called by ScrollableWindow::scrollTo
 		// TODO
+		kStub(s, argc, argv);
 		break;
-	case 8: // End
-		// 2 parameters
-		// TODO
+	case 5: // Up arrow, called by ScrollableWindow::scrollTo
+		g_sci->_gfxFrameout->prevScrollText();
 		break;
-	case 9: // Resize
-		// 3 parameters
-		// TODO
+	case 6: // Down arrow, called by ScrollableWindow::scrollTo
+		g_sci->_gfxFrameout->nextScrollText();
 		break;
-	case 10: // Where
-		// 3 parameters
-		// TODO
+	case 7: // Home, called by ScrollableWindow::scrollTo
+		g_sci->_gfxFrameout->firstScrollText();
 		break;
-	case 11: // Go
-		// 4 parameters
-		// TODO
+	case 8: // End, called by ScrollableWindow::scrollTo
+		g_sci->_gfxFrameout->lastScrollText();
 		break;
-	case 12: // Insert
-		// 7 parameters
+	case 9: // Resize, called by ScrollableWindow::resize and ScrollerWindow::resize
 		// TODO
+		kStub(s, argc, argv);
 		break;
-	case 13: // Delete
-		// 3 parameters
+	case 10: // Where, called by ScrollableWindow::where
 		// TODO
+		// argv[2] is an unknown integer
+		kStub(s, argc, argv);
 		break;
-	case 14: // Modify
-		// 7 or 8 parameters
+	case 11: // Go, called by ScrollableWindow::scrollTo
+		// 2 extra parameters here
 		// TODO
+		kStub(s, argc, argv);
 		break;
-	case 15: // Hide
-		// 2 parameters
+	case 12: // Insert, called by ScrollableWindow::insertString
+		// 3 extra parameters here
 		// TODO
+		kStub(s, argc, argv);
 		break;
-	case 16: // Show
-		// 2 parameters
-		// TODO
+	// case 13 (Delete) is handled below
+	// case 14 (Modify) is handled above
+	case 15: // Hide, called by ScrollableWindow::hide
+		g_sci->_gfxFrameout->toggleScrollText(false);
 		break;
-	case 17: // Destroy
-		// 2 parameters
-		// TODO
+	case 16: // Show, called by ScrollableWindow::show
+		g_sci->_gfxFrameout->toggleScrollText(true);
 		break;
-	case 18: // Text
-		// 2 parameters
-		// TODO
+	case 17: // Destroy, called by ScrollableWindow::dispose
+		g_sci->_gfxFrameout->clearScrollTexts();
 		break;
-	case 19: // Reconstruct
-		// 3 parameters
-		// TODO
+	case 13: // Delete, unused
+	case 18: // Text, unused
+	case 19: // Reconstruct, unused
+		error("kScrollWindow: Unused subop %d invoked", op);
 		break;
 	default:
-		error("kScrollWindow: unknown subop %d", argv[0].toUint16());
+		error("kScrollWindow: unknown subop %d", op);
 		break;
 	}
 
diff --git a/engines/sci/graphics/frameout.cpp b/engines/sci/graphics/frameout.cpp
index 709a708..4505810 100644
--- a/engines/sci/graphics/frameout.cpp
+++ b/engines/sci/graphics/frameout.cpp
@@ -59,6 +59,9 @@ GfxFrameout::GfxFrameout(SegManager *segMan, ResourceManager *resMan, GfxCoordAd
 	_coordAdjuster = (GfxCoordAdjuster32 *)coordAdjuster;
 	_scriptsRunningWidth = 320;
 	_scriptsRunningHeight = 200;
+	_curScrollText = -1;
+	_showScrollText = false;
+	_maxScrollTexts = 0;
 }
 
 GfxFrameout::~GfxFrameout() {
@@ -69,6 +72,46 @@ void GfxFrameout::clear() {
 	deletePlaneItems(NULL_REG);
 	_planes.clear();
 	deletePlanePictures(NULL_REG);
+	clearScrollTexts();
+}
+
+void GfxFrameout::clearScrollTexts() {
+	_scrollTexts.clear();
+	_curScrollText = -1;
+}
+
+void GfxFrameout::addScrollTextEntry(Common::String &text, reg_t kWindow, uint16 x, uint16 y, bool replace) {
+	//reg_t bitmapHandle = g_sci->_gfxText32->createScrollTextBitmap(text, kWindow);
+	// HACK: We set the container dimensions manually
+	reg_t bitmapHandle = g_sci->_gfxText32->createScrollTextBitmap(text, kWindow, 480, 70);
+	ScrollTextEntry textEntry;
+	textEntry.bitmapHandle = bitmapHandle;
+	textEntry.kWindow = kWindow;
+	textEntry.x = x;
+	textEntry.y = y;
+	if (!replace || _scrollTexts.size() == 0) {
+		if (_scrollTexts.size() > _maxScrollTexts) {
+			_scrollTexts.remove_at(0);
+			_curScrollText--;
+		}
+		_scrollTexts.push_back(textEntry);
+		_curScrollText++;
+	} else {
+		_scrollTexts.pop_back();
+		_scrollTexts.push_back(textEntry);
+	}
+}
+
+void GfxFrameout::showCurrentScrollText() {
+	if (!_showScrollText || _curScrollText < 0)
+		return;
+
+	uint16 size = (uint16)_scrollTexts.size();
+	if (size > 0) {
+		assert(_curScrollText < size);
+		ScrollTextEntry textEntry = _scrollTexts[_curScrollText];
+		g_sci->_gfxText32->drawScrollTextBitmap(textEntry.kWindow, textEntry.bitmapHandle, textEntry.x, textEntry.y);
+	}
 }
 
 void GfxFrameout::kernelAddPlane(reg_t object) {
@@ -673,6 +716,8 @@ void GfxFrameout::kernelFrameout() {
 		}
 	}
 
+	showCurrentScrollText();
+
 	_screen->copyToScreen();
 
 	g_sci->getEngineState()->_throttleTrigger = true;
diff --git a/engines/sci/graphics/frameout.h b/engines/sci/graphics/frameout.h
index ec4de62..2d2ca65 100644
--- a/engines/sci/graphics/frameout.h
+++ b/engines/sci/graphics/frameout.h
@@ -76,6 +76,15 @@ struct PlanePictureEntry {
 
 typedef Common::List<PlanePictureEntry> PlanePictureList;
 
+struct ScrollTextEntry {
+	reg_t bitmapHandle;
+	reg_t kWindow;
+	uint16 x;
+	uint16 y;
+};
+
+typedef Common::Array<ScrollTextEntry> ScrollTextList;
+
 class GfxCache;
 class GfxCoordAdjuster32;
 class GfxPaint32;
@@ -104,6 +113,18 @@ public:
 	void addPlanePicture(reg_t object, GuiResourceId pictureId, uint16 startX, uint16 startY = 0);
 	void deletePlanePictures(reg_t object);
 	void clear();
+
+	// Scroll text functions
+	void addScrollTextEntry(Common::String &text, reg_t kWindow, uint16 x, uint16 y, bool replace);
+	void showCurrentScrollText();
+	void initScrollText(uint16 maxItems) { _maxScrollTexts = maxItems; }
+	void clearScrollTexts();
+	void firstScrollText() { if (_scrollTexts.size() > 0) _curScrollText = 0; }
+	void lastScrollText() { if (_scrollTexts.size() > 0) _curScrollText = _scrollTexts.size() - 1; }
+	void prevScrollText() { if (_curScrollText > 0) _curScrollText--; }
+	void nextScrollText() { if (_curScrollText + 1 < (uint16)_scrollTexts.size()) _curScrollText++; }
+	void toggleScrollText(bool show) { _showScrollText = show; }
+
 	void printPlaneList(Console *con);
 	void printPlaneItemList(Console *con, reg_t planeObject);
 
@@ -127,6 +148,10 @@ private:
 	FrameoutList _screenItems;
 	PlaneList _planes;
 	PlanePictureList _planePictures;
+	ScrollTextList _scrollTexts;
+	int16 _curScrollText;
+	bool _showScrollText;
+	uint16 _maxScrollTexts;
 
 	void sortPlanes();
 
diff --git a/engines/sci/graphics/text32.cpp b/engines/sci/graphics/text32.cpp
index cd24ca5..8ac9582 100644
--- a/engines/sci/graphics/text32.cpp
+++ b/engines/sci/graphics/text32.cpp
@@ -49,9 +49,12 @@ GfxText32::GfxText32(SegManager *segMan, GfxCache *fonts, GfxScreen *screen)
 GfxText32::~GfxText32() {
 }
 
+reg_t GfxText32::createScrollTextBitmap(Common::String text, reg_t textObject, uint16 maxWidth, uint16 maxHeight, reg_t prevHunk) {
+	return createTextBitmapInternal(text, textObject, maxWidth, maxHeight, prevHunk);
+
+}
 reg_t GfxText32::createTextBitmap(reg_t textObject, uint16 maxWidth, uint16 maxHeight, reg_t prevHunk) {
 	reg_t stringObject = readSelector(_segMan, textObject, SELECTOR(text));
-
 	// The object in the text selector of the item can be either a raw string
 	// or a Str object. In the latter case, we need to access the object's data
 	// selector to get the raw string.
@@ -59,6 +62,11 @@ reg_t GfxText32::createTextBitmap(reg_t textObject, uint16 maxWidth, uint16 maxH
 		stringObject = readSelector(_segMan, stringObject, SELECTOR(data));
 
 	Common::String text = _segMan->getString(stringObject);
+
+	return createTextBitmapInternal(text, textObject, maxWidth, maxHeight, prevHunk);
+}
+
+reg_t GfxText32::createTextBitmapInternal(Common::String &text, reg_t textObject, uint16 maxWidth, uint16 maxHeight, reg_t prevHunk) {
 	// HACK: The character offsets of the up and down arrow buttons are off by one
 	// in GK1, for some unknown reason. Fix them here.
 	if (text.size() == 1 && (text[0] == 29 || text[0] == 30)) {
@@ -91,7 +99,11 @@ reg_t GfxText32::createTextBitmap(reg_t textObject, uint16 maxWidth, uint16 maxH
 	reg_t memoryId = NULL_REG;
 	if (prevHunk.isNull()) {
 		memoryId = _segMan->allocateHunkEntry("TextBitmap()", entrySize);
-		writeSelector(_segMan, textObject, SELECTOR(bitmap), memoryId);
+
+		// Scroll text objects have no bitmap selector!
+		ObjVarRef varp;
+		if (lookupSelector(_segMan, textObject, SELECTOR(bitmap), &varp, NULL) == kSelectorVariable)
+			writeSelector(_segMan, textObject, SELECTOR(bitmap), memoryId);
 	} else {
 		memoryId = prevHunk;
 	}
@@ -175,6 +187,24 @@ void GfxText32::disposeTextBitmap(reg_t hunkId) {
 
 void GfxText32::drawTextBitmap(int16 x, int16 y, Common::Rect planeRect, reg_t textObject) {
 	reg_t hunkId = readSelector(_segMan, textObject, SELECTOR(bitmap));
+	drawTextBitmapInternal(x, y, planeRect, textObject, hunkId);
+}
+
+void GfxText32::drawScrollTextBitmap(reg_t textObject, reg_t hunkId, uint16 x, uint16 y) {
+	/*reg_t plane = readSelector(_segMan, textObject, SELECTOR(plane));
+	Common::Rect planeRect;
+	planeRect.top = readSelectorValue(_segMan, plane, SELECTOR(top));
+	planeRect.left = readSelectorValue(_segMan, plane, SELECTOR(left));
+	planeRect.bottom = readSelectorValue(_segMan, plane, SELECTOR(bottom));
+	planeRect.right = readSelectorValue(_segMan, plane, SELECTOR(right));
+
+	drawTextBitmapInternal(x, y, planeRect, textObject, hunkId);*/
+
+	// HACK: we pretty much ignore the plane rect and x, y...
+	drawTextBitmapInternal(0, 0, Common::Rect(20, 390, 600, 460), textObject, hunkId);
+}
+
+void GfxText32::drawTextBitmapInternal(int16 x, int16 y, Common::Rect planeRect, reg_t textObject, reg_t hunkId) {
 	uint16 backColor = readSelectorValue(_segMan, textObject, SELECTOR(back));
 	// Sanity check: Check if the hunk is set. If not, either the game scripts
 	// didn't set it, or an old saved game has been loaded, where it wasn't set.
@@ -188,8 +218,9 @@ void GfxText32::drawTextBitmap(int16 x, int16 y, Common::Rect planeRect, reg_t t
 	byte *memoryPtr = _segMan->getHunkPointer(hunkId);
 
 	if (!memoryPtr) {
-		// Happens when restoring in some SCI32 games
-		warning("Attempt to draw an invalid text bitmap");
+		// Happens when restoring in some SCI32 games (e.g. SQ6).
+		// Commented out to reduce console spam
+		//warning("Attempt to draw an invalid text bitmap");
 		return;
 	}
 
diff --git a/engines/sci/graphics/text32.h b/engines/sci/graphics/text32.h
index 3505de8..ce78003 100644
--- a/engines/sci/graphics/text32.h
+++ b/engines/sci/graphics/text32.h
@@ -33,13 +33,17 @@ public:
 	GfxText32(SegManager *segMan, GfxCache *fonts, GfxScreen *screen);
 	~GfxText32();
 	reg_t createTextBitmap(reg_t textObject, uint16 maxWidth = 0, uint16 maxHeight = 0, reg_t prevHunk = NULL_REG);
-	void disposeTextBitmap(reg_t hunkId);
+	reg_t createScrollTextBitmap(Common::String text, reg_t textObject, uint16 maxWidth = 0, uint16 maxHeight = 0, reg_t prevHunk = NULL_REG);
 	void drawTextBitmap(int16 x, int16 y, Common::Rect planeRect, reg_t textObject);
+	void drawScrollTextBitmap(reg_t textObject, reg_t hunkId, uint16 x, uint16 y);
+	void disposeTextBitmap(reg_t hunkId);
 	int16 GetLongest(const char *text, int16 maxWidth, GfxFont *font);
 
 	void kernelTextSize(const char *text, int16 font, int16 maxWidth, int16 *textWidth, int16 *textHeight);
 
 private:
+	reg_t createTextBitmapInternal(Common::String &text, reg_t textObject, uint16 maxWidth, uint16 maxHeight, reg_t hunkId);
+	void drawTextBitmapInternal(int16 x, int16 y, Common::Rect planeRect, reg_t textObject, reg_t hunkId);
 	int16 Size(Common::Rect &rect, const char *text, GuiResourceId fontId, int16 maxWidth);
 	void Width(const char *text, int16 from, int16 len, GuiResourceId orgFontId, int16 &textWidth, int16 &textHeight, bool restoreFont);
 	void StringWidth(const char *str, GuiResourceId orgFontId, int16 &textWidth, int16 &textHeight);






More information about the Scummvm-git-logs mailing list