[Scummvm-cvs-logs] SF.net SVN: scummvm:[55791] scummvm/trunk/engines/sci

mthreepwood at users.sourceforge.net mthreepwood at users.sourceforge.net
Sun Feb 6 01:05:28 CET 2011


Revision: 55791
          http://scummvm.svn.sourceforge.net/scummvm/?rev=55791&view=rev
Author:   mthreepwood
Date:     2011-02-06 00:05:27 +0000 (Sun, 06 Feb 2011)

Log Message:
-----------
SCI: Improve Mac SCI1.1+ cursor support

The scripts can pass a list of view id's from the DOS version that get remapped to CURS/crsr id's. GK1 cursors now work and Phantasmagoria uses the correct ones.

Modified Paths:
--------------
    scummvm/trunk/engines/sci/engine/kmisc.cpp
    scummvm/trunk/engines/sci/graphics/cursor.cpp
    scummvm/trunk/engines/sci/graphics/cursor.h

Modified: scummvm/trunk/engines/sci/engine/kmisc.cpp
===================================================================
--- scummvm/trunk/engines/sci/engine/kmisc.cpp	2011-02-05 21:58:44 UTC (rev 55790)
+++ scummvm/trunk/engines/sci/engine/kmisc.cpp	2011-02-06 00:05:27 UTC (rev 55791)
@@ -31,6 +31,7 @@
 #include "sci/engine/state.h"
 #include "sci/engine/kernel.h"
 #include "sci/engine/gc.h"
+#include "sci/graphics/cursor.h"
 #include "sci/graphics/maciconbar.h"
 #include "sci/console.h"
 
@@ -338,38 +339,77 @@
 	return s->r_acc;
 }
 
-// kIconBar is really a subop of kPlatform for SCI1.1 Mac
+#ifdef ENABLE_SCI32
+reg_t kGetConfig(EngineState *s, int argc, reg_t *argv) {
+	Common::String setting = s->_segMan->getString(argv[0]);
+	reg_t data = readSelector(s->_segMan, argv[1], SELECTOR(data));
+
+	warning("Get config setting %s", setting.c_str());
+	s->_segMan->strcpy(data, "");
+	return argv[1];
+}
+#endif
+
+// kIconBar is really a subop of kMacPlatform for SCI1.1 Mac
 reg_t kIconBar(EngineState *s, int argc, reg_t *argv) {
+	// Mac versions use their own tertiary platform functions
+	// to handle the outside-of-the-screen icon bar.
+
 	// QFG1 Mac calls this function to load the Mac icon bar (of which
 	// the resources do exist), but the game completely ignores it and
 	// uses the standard icon bar for the game. We do the same.
 	if (!g_sci->hasMacIconBar())
 		return NULL_REG;
 
-	// TODO...
+	switch (argv[0].toUint16()) {
+	case 0:
+		// Add the icons
+		for (int i = 0; i < argv[1].toUint16(); i++)
+			g_sci->_gfxMacIconBar->addIcon(argv[i + 2]);
 
-	if (argv[0].toUint16() == 4 && argv[1].toUint16() == 0) {
-		for (int i = 0; i < argv[2].toUint16(); i++)
-			g_sci->_gfxMacIconBar->addIcon(argv[i + 3]);
-
-		g_sci->_gfxMacIconBar->drawIcons();		
+		g_sci->_gfxMacIconBar->drawIcons();
+		break;
+	case 2:
+	case 3:
+	case 4:
+		// TODO: Other calls seem to handle selecting/deselecting them
+		break;
+	default:
+		warning("Unknown kIconBar subop %d", argv[0].toUint16());
 	}
 
-	// Other calls seem to handle selecting/deselecting them
-
 	return NULL_REG;
 }
 
-#ifdef ENABLE_SCI32
-reg_t kGetConfig(EngineState *s, int argc, reg_t *argv) {
-	Common::String setting = s->_segMan->getString(argv[0]);
-	reg_t data = readSelector(s->_segMan, argv[1], SELECTOR(data));
+// kMacPlatform is really a subop of kPlatform for SCI1.1+ Mac
+reg_t kMacPlatform(EngineState *s, int argc, reg_t *argv) {
+	// Mac versions use their own secondary platform functions
+	// to do various things. Why didn't they just declare a new
+	// kernel function?
 
-	warning("Get config setting %s", setting.c_str());
-	s->_segMan->strcpy(data, "");
-	return argv[1];
+	switch (argv[0].toUint16()) {
+	case 0:
+		// Set Mac cursor remap
+		g_sci->_gfxCursor->setMacCursorRemapList(argc - 1, argv + 1);
+		break;
+	case 1:
+		// Unknown
+		break;
+	case 2:
+		// Unknown
+		break;
+	case 3:
+		// Unknown
+		break;
+	case 4:
+		// Handle icon bar code
+		return kIconBar(s, argc - 1, argv + 1);
+	default:
+		warning("Unknown kMacPlatform subop %d", argv[0].toUint16());
+	}
+
+	return s->r_acc;
 }
-#endif
 
 enum kSciPlatforms {
 	kSciPlatformDOS = 1,
@@ -415,8 +455,8 @@
 		warning("STUB: kPlatform(CDCheck)");
 		break;
 	case kPlatformUnk0:
-		if (g_sci->getPlatform() == Common::kPlatformMacintosh && getSciVersion() == SCI_VERSION_1_1)
-			return kIconBar(s, argc - 1, argv + 1);
+		if (g_sci->getPlatform() == Common::kPlatformMacintosh && getSciVersion() >= SCI_VERSION_1_1 && argc > 1)
+			return kMacPlatform(s, argc - 1, argv + 1);
 		// Otherwise, fall through
 	case kPlatformGetPlatform:
 		return make_reg(0, (isWindows) ? kSciPlatformWindows : kSciPlatformDOS);

Modified: scummvm/trunk/engines/sci/graphics/cursor.cpp
===================================================================
--- scummvm/trunk/engines/sci/graphics/cursor.cpp	2011-02-05 21:58:44 UTC (rev 55790)
+++ scummvm/trunk/engines/sci/graphics/cursor.cpp	2011-02-06 00:05:27 UTC (rev 55791)
@@ -223,70 +223,6 @@
 	delete cursorHotspot;
 }
 
-void GfxCursor::kernelSetMacCursor(GuiResourceId viewNum, int loopNum, int celNum, Common::Point *hotspot) {
-	// See http://developer.apple.com/legacy/mac/library/documentation/mac/QuickDraw/QuickDraw-402.html
-	// for more information.
-
-	// View 998 seems to be a fake resource used to call for Mac cursor resources.
-	// For other resources, they're still in the views, so use them.
-	if (viewNum != 998) {
-		kernelSetView(viewNum, loopNum, celNum, hotspot);
-		return;
-	}
-
-	// TODO: What about the 2000 resources? Inventory items? How to handle?
-	// Update: Perhaps these are handled like the Windows cursors in KQ6?
-	// TODO: 1000 + celNum won't work for GK1
-
-	Resource *resource = _resMan->findResource(ResourceId(kResourceTypeCursor, 1000 + celNum), false);
-
-	if (!resource) {
-		warning("Mac cursor %d not found", 1000 + celNum);
-		return;
-	}
-
-	assert(resource);
-
-	if (resource->size == 32 * 2 + 4) {
-		// Mac CURS cursor
-		byte *cursorBitmap = new byte[16 * 16];
-		byte *data = resource->data;
-
-		// Get B&W data
-		for (byte i = 0; i < 32; i++) {
-			byte imageByte = *data++;
-			for (byte b = 0; b < 8; b++)
-				cursorBitmap[i * 8 + b] = (byte)((imageByte & (0x80 >> b)) > 0 ? 0x00 : 0xFF);
-		}
-
-		// Apply mask data
-		for (byte i = 0; i < 32; i++) {
-			byte imageByte = *data++;
-			for (byte b = 0; b < 8; b++)
-				if ((imageByte & (0x80 >> b)) == 0)
-					cursorBitmap[i * 8 + b] = SCI_CURSOR_SCI0_TRANSPARENCYCOLOR; // Doesn't matter, just is transparent
-		}
-
-		uint16 hotspotX = READ_BE_UINT16(data);
-		uint16 hotspotY = READ_BE_UINT16(data + 2);
-
-		CursorMan.replaceCursor(cursorBitmap, 16, 16, hotspotX, hotspotY, SCI_CURSOR_SCI0_TRANSPARENCYCOLOR);
-
-		delete[] cursorBitmap;
-	} else {
-		// Mac crsr cursor
-		byte *cursorBitmap, *palette;
-		int width, height, hotspotX, hotspotY, palSize, keycolor;
-		Common::MacResManager::convertCrsrCursor(resource->data, resource->size, &cursorBitmap, &width, &height, &hotspotX, &hotspotY, &keycolor, true, &palette, &palSize);
-		CursorMan.replaceCursor(cursorBitmap, width, height, hotspotX, hotspotY, keycolor);
-		CursorMan.replaceCursorPalette(palette, 0, palSize);
-		free(cursorBitmap);
-		free(palette);
-	}
-
-	kernelShow();
-}
-
 // this list contains all mandatory set cursor changes, that need special handling
 //  ffs. GfxCursor::setPosition (below)
 //    Game,            newPosition, validRect
@@ -489,4 +425,97 @@
 	_event->getSciEvent(SCI_EVENT_PEEK);
 }
 
+void GfxCursor::kernelSetMacCursor(GuiResourceId viewNum, int loopNum, int celNum, Common::Point *hotspot) {
+	// Here we try to map the view number onto the cursor. What they did was keep the
+	// kSetCursor calls the same, but perform remapping on the cursors. They also took
+	// it a step further and added a new kPlatform sub-subop that handles remapping
+	// automatically. 
+
+	if (_macCursorRemap.empty()) {
+		// The scripts have given us no remapping, so let's try to do this manually.
+		// First try and see if the view resource exists. If it does, we're just using
+		// that cursor (QFG1/Hoyle4 do not use Mac cursors, although they have them).
+		if (_resMan->testResource(ResourceId(kResourceTypeView, viewNum))) {
+			CursorMan.disableCursorPalette(true);
+			kernelSetView(viewNum, loopNum, celNum, hotspot);
+			return;
+		}
+
+		// KQ6 seems to use this mapping for its cursors
+		viewNum = loopNum * 1000 + celNum;
+	} else {
+		// If we do have the list, we'll be using a remap based on what the
+		// scripts have given us.
+		for (uint32 i = 0; i < _macCursorRemap.size(); i++) {
+			if (viewNum == _macCursorRemap[i]) {
+				viewNum = (i + 1) * 0x100 + loopNum * 0x10 + celNum;
+				break;
+			}
+
+			if (i == _macCursorRemap.size())
+				error("Unmatched Mac cursor %d", viewNum);
+		}
+	}
+
+	Resource *resource = _resMan->findResource(ResourceId(kResourceTypeCursor, viewNum), false);
+
+	if (!resource) {
+		warning("Mac cursor %d not found", viewNum);
+		return;
+	}
+
+	CursorMan.disableCursorPalette(false);
+
+	assert(resource);
+
+	if (resource->size == 32 * 2 + 4) {
+		// Mac CURS cursor
+		// See http://developer.apple.com/legacy/mac/library/documentation/mac/QuickDraw/QuickDraw-402.html
+		// for more information.
+		byte *cursorBitmap = new byte[16 * 16];
+		byte *data = resource->data;
+
+		// Get B&W data
+		for (byte i = 0; i < 32; i++) {
+			byte imageByte = *data++;
+			for (byte b = 0; b < 8; b++)
+				cursorBitmap[i * 8 + b] = (byte)((imageByte & (0x80 >> b)) > 0 ? 1 : 2);
+		}
+
+		// Apply mask data
+		for (byte i = 0; i < 32; i++) {
+			byte imageByte = *data++;
+			for (byte b = 0; b < 8; b++)
+				if ((imageByte & (0x80 >> b)) == 0)
+					cursorBitmap[i * 8 + b] = 0; // Doesn't matter, just is transparent
+		}
+
+		uint16 hotspotX = READ_BE_UINT16(data);
+		uint16 hotspotY = READ_BE_UINT16(data + 2);
+
+		static const byte cursorPalette[] = { 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00 };
+
+		CursorMan.replaceCursor(cursorBitmap, 16, 16, hotspotX, hotspotY, 0);
+		CursorMan.replaceCursorPalette(cursorPalette, 1, 2);
+
+		delete[] cursorBitmap;
+	} else {
+		// Mac crsr cursor
+		byte *cursorBitmap, *palette;
+		int width, height, hotspotX, hotspotY, palSize, keycolor;
+		Common::MacResManager::convertCrsrCursor(resource->data, resource->size, &cursorBitmap, &width, &height, &hotspotX, &hotspotY, &keycolor, true, &palette, &palSize);
+		CursorMan.replaceCursor(cursorBitmap, width, height, hotspotX, hotspotY, keycolor);
+		CursorMan.replaceCursorPalette(palette, 0, palSize);
+		free(cursorBitmap);
+		free(palette);
+	}
+
+	kernelShow();
+}
+
+void GfxCursor::setMacCursorRemapList(int cursorCount, reg_t *cursors) {
+	for (int i = 0; i < cursorCount; i++)
+		_macCursorRemap.push_back(cursors[i].toUint16());
+}
+
 } // End of namespace Sci

Modified: scummvm/trunk/engines/sci/graphics/cursor.h
===================================================================
--- scummvm/trunk/engines/sci/graphics/cursor.h	2011-02-05 21:58:44 UTC (rev 55790)
+++ scummvm/trunk/engines/sci/graphics/cursor.h	2011-02-06 00:05:27 UTC (rev 55791)
@@ -26,6 +26,7 @@
 #ifndef SCI_GRAPHICS_CURSOR_H
 #define SCI_GRAPHICS_CURSOR_H
 
+#include "common/array.h"
 #include "common/hashmap.h"
 
 namespace Sci {
@@ -85,6 +86,8 @@
 	void kernelSetPos(Common::Point pos);
 	void kernelMoveCursor(Common::Point pos);
 
+	void setMacCursorRemapList(int cursorCount, reg_t *cursors);
+
 private:
 	void purgeCache();
 
@@ -119,6 +122,9 @@
 	// graphics, like SSCI did. These look very ugly, which is why
 	// they aren't enabled by default.
 	bool _useOriginalKQ6WinCursors;
+
+	// Mac versions of games use a remap list to remap their cursors
+	Common::Array<uint16> _macCursorRemap;
 };
 
 } // End of namespace Sci


This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.




More information about the Scummvm-git-logs mailing list