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

mthreepwood at users.sourceforge.net mthreepwood at users.sourceforge.net
Tue May 18 06:17:59 CEST 2010


Revision: 49070
          http://scummvm.svn.sourceforge.net/scummvm/?rev=49070&view=rev
Author:   mthreepwood
Date:     2010-05-18 04:17:58 +0000 (Tue, 18 May 2010)

Log Message:
-----------
Add initial support for KQ6 Mac. Wrapper functions for read/writing to pointers are now used (found in util.*) for code that has different endianness in SCI1.1+ Mac games. Add support for Mac 'snd ' and 'CURS' resources. QFG1 Mac is not yet playable due to script compression.

Modified Paths:
--------------
    scummvm/trunk/engines/sci/engine/kernel.cpp
    scummvm/trunk/engines/sci/engine/kgraphics.cpp
    scummvm/trunk/engines/sci/engine/kmisc.cpp
    scummvm/trunk/engines/sci/engine/message.cpp
    scummvm/trunk/engines/sci/engine/script.cpp
    scummvm/trunk/engines/sci/engine/scriptdebug.cpp
    scummvm/trunk/engines/sci/engine/segment.cpp
    scummvm/trunk/engines/sci/engine/segment.h
    scummvm/trunk/engines/sci/engine/vm.cpp
    scummvm/trunk/engines/sci/engine/vm.h
    scummvm/trunk/engines/sci/graphics/cursor.cpp
    scummvm/trunk/engines/sci/graphics/cursor.h
    scummvm/trunk/engines/sci/graphics/view.cpp
    scummvm/trunk/engines/sci/module.mk
    scummvm/trunk/engines/sci/resource.cpp
    scummvm/trunk/engines/sci/sound/audio.cpp

Added Paths:
-----------
    scummvm/trunk/engines/sci/util.cpp
    scummvm/trunk/engines/sci/util.h

Modified: scummvm/trunk/engines/sci/engine/kernel.cpp
===================================================================
--- scummvm/trunk/engines/sci/engine/kernel.cpp	2010-05-17 23:29:44 UTC (rev 49069)
+++ scummvm/trunk/engines/sci/engine/kernel.cpp	2010-05-18 04:17:58 UTC (rev 49070)
@@ -335,9 +335,9 @@
 	DEFUN("Intersections", kIntersections, "iiiiriiiri"),
 	DEFUN("ResCheck", kResCheck, "iii*"),
 	DEFUN("SetQuitStr", kSetQuitStr, "r"),
-	DEFUN("ShowMovie", kShowMovie, "..*"),
+	DEFUN("ShowMovie", kShowMovie, ".*"),
 	DEFUN("SetVideoMode", kSetVideoMode, "i"),
-	DEFUN("Platform", kPlatform, "i*"),
+	DEFUN("Platform", kPlatform, "i.*"),
 	DEFUN("TextColors", kTextColors, ".*"),
 	DEFUN("TextFonts", kTextFonts, ".*"),
 	DEFUN("Portrait", kPortrait, ".*"),
@@ -757,10 +757,16 @@
 		break;
 
 	case SCI_VERSION_1_1:
-		// In KQ6CD, the empty kSetSynonyms function has been replaced
-		// with kPortrait
-		if (gameId == "kq6")
-			_kernelNames[0x26] = "Portrait";
+		// In KQ6 CD, the empty kSetSynonyms function has been replaced
+		// with kPortrait. In KQ6 Mac, kPlayBack has been replaced by
+		// kShowMovie.
+		if (gameId == "kq6") {
+			if (g_sci->getPlatform() == Common::kPlatformMacintosh)
+				_kernelNames[0x84] = "ShowMovie";
+			else
+				_kernelNames[0x26] = "Portrait";
+		}
+
 		_kernelNames[0x71] = "PalVary";
 		_kernelNames[0x7c] = "Message";
 		break;

Modified: scummvm/trunk/engines/sci/engine/kgraphics.cpp
===================================================================
--- scummvm/trunk/engines/sci/engine/kgraphics.cpp	2010-05-17 23:29:44 UTC (rev 49069)
+++ scummvm/trunk/engines/sci/engine/kgraphics.cpp	2010-05-18 04:17:58 UTC (rev 49070)
@@ -159,7 +159,10 @@
 		hotspot = new Common::Point(argv[3].toSint16(), argv[4].toSint16());
 		// Fallthrough
 	case 3:
-		g_sci->_gfxCursor->kernelSetView(argv[0].toUint16(), argv[1].toUint16(), argv[2].toUint16(), hotspot);
+		if (g_sci->getPlatform() == Common::kPlatformMacintosh)
+			g_sci->_gfxCursor->kernelSetMacCursor(argv[0].toUint16(), argv[1].toUint16(), argv[2].toUint16(), hotspot);
+		else
+			g_sci->_gfxCursor->kernelSetView(argv[0].toUint16(), argv[1].toUint16(), argv[2].toUint16(), hotspot);
 		break;
 	default :
 		warning("kSetCursor: Unhandled case: %d arguments given", argc);
@@ -1086,22 +1089,29 @@
 		g_sci->_gfxCursor->kernelHide();
 
 	if (argv[0].segment != 0) {
-		// DOS SEQ
-		// SEQ's are called with no subops, just the string and delay
-		Common::String filename = s->_segMan->getString(argv[0]);
-		int delay = argv[1].toUint16(); // Time between frames in ticks
+		if (g_sci->getPlatform() == Common::kPlatformMacintosh) {
+			// Mac QuickTime
+			// The only argument is the string for the video
+			warning("TODO: Play QuickTime movie '%s'", s->_segMan->getString(argv[0]).c_str());
+			return s->r_acc;
+		} else {
+			// DOS SEQ
+			// SEQ's are called with no subops, just the string and delay
+			Common::String filename = s->_segMan->getString(argv[0]);
+			int delay = argv[1].toUint16(); // Time between frames in ticks
 
-		SeqDecoder *seqDecoder = new SeqDecoder();
-		Graphics::VideoPlayer *player = new Graphics::VideoPlayer(seqDecoder);
-		if (seqDecoder->loadFile(filename.c_str(), delay)) {
-			player->playVideo();
-			playedVideo = true;
-		} else {
-			warning("Failed to open movie file %s", filename.c_str());
+			SeqDecoder *seqDecoder = new SeqDecoder();
+			Graphics::VideoPlayer *player = new Graphics::VideoPlayer(seqDecoder);
+			if (seqDecoder->loadFile(filename.c_str(), delay)) {
+				player->playVideo();
+				playedVideo = true;
+			} else {
+				warning("Failed to open movie file %s", filename.c_str());
+			}
+			seqDecoder->closeFile();
+			delete player;
+			delete seqDecoder;
 		}
-		seqDecoder->closeFile();
-		delete player;
-		delete seqDecoder;
 	} else {
 		// Windows AVI (Macintosh QuickTime? Need to check KQ6 Macintosh)
 		// TODO: This appears to be some sort of subop. case 0 contains the string

Modified: scummvm/trunk/engines/sci/engine/kmisc.cpp
===================================================================
--- scummvm/trunk/engines/sci/engine/kmisc.cpp	2010-05-17 23:29:44 UTC (rev 49069)
+++ scummvm/trunk/engines/sci/engine/kmisc.cpp	2010-05-18 04:17:58 UTC (rev 49070)
@@ -294,6 +294,19 @@
 	return s->r_acc;
 }
 
+// kIconBar is really a subop of kPlatform for SCI1.1 Mac
+reg_t kIconBar(EngineState *s, int argc, reg_t *argv) {
+	// TODO...
+
+	if (argv[0].toUint16() == 4 && argv[1].toUint16() == 0)
+		for (int i = 0; i < argv[2].toUint16(); i++)
+			warning("kIconBar: Icon Object %d = %04x:%04x", i, PRINT_REG(argv[i + 3]));
+
+	// Other calls seem to handle selecting/deselecting them
+
+	return NULL_REG;
+}
+
 enum kSciPlatforms {
 	kSciPlatformDOS = 1,
 	kSciPlatformWindows = 2
@@ -337,6 +350,9 @@
 		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);
+		// Otherwise, fall through
 	case kPlatformGetPlatform:
 		return make_reg(0, (isWindows) ? kSciPlatformWindows : kSciPlatformDOS);
 	case kPlatformUnk5:

Modified: scummvm/trunk/engines/sci/engine/message.cpp
===================================================================
--- scummvm/trunk/engines/sci/engine/message.cpp	2010-05-17 23:29:44 UTC (rev 49069)
+++ scummvm/trunk/engines/sci/engine/message.cpp	2010-05-18 04:17:58 UTC (rev 49070)
@@ -23,9 +23,11 @@
  *
  */
 
+
 #include "sci/engine/message.h"
 #include "sci/engine/kernel.h"
 #include "sci/engine/seg_manager.h"
+#include "sci/util.h"
 
 namespace Sci {
 
@@ -43,7 +45,7 @@
 			return false;
 
 		// Read message count from last word in header
-		_messageCount = READ_LE_UINT16(_data + _headerSize - 2);
+		_messageCount = READ_SCI11ENDIAN_UINT16(_data + _headerSize - 2);
 
 		if (_messageCount * _recordSize + _headerSize > _size)
 			return false;
@@ -124,7 +126,7 @@
 				record.tuple = tuple;
 				record.refTuple = MessageTuple(recordPtr[7], recordPtr[8], recordPtr[9]);
 				record.talker = recordPtr[4];
-				record.string = (const char *)_data + READ_LE_UINT16(recordPtr + 5);
+				record.string = (const char *)_data + READ_SCI11ENDIAN_UINT16(recordPtr + 5);
 				return true;
 			}
 			recordPtr += _recordSize;
@@ -143,7 +145,7 @@
 	}
 
 	MessageReader *reader;
-	int version = READ_LE_UINT16(res->data) / 1000;
+	int version = READ_SCI11ENDIAN_UINT32(res->data) / 1000;
 
 	switch (version) {
 	case 2:

Modified: scummvm/trunk/engines/sci/engine/script.cpp
===================================================================
--- scummvm/trunk/engines/sci/engine/script.cpp	2010-05-17 23:29:44 UTC (rev 49069)
+++ scummvm/trunk/engines/sci/engine/script.cpp	2010-05-18 04:17:58 UTC (rev 49070)
@@ -25,6 +25,7 @@
 
 #include "sci/sci.h"
 #include "sci/resource.h"
+#include "sci/util.h"
 #include "sci/engine/features.h"
 #include "sci/engine/state.h"
 #include "sci/engine/kernel.h"
@@ -128,7 +129,7 @@
 	_classtable.resize(totalClasses);
 
 	for (uint16 classNr = 0; classNr < totalClasses; classNr++) {
-		uint16 scriptNr = READ_LE_UINT16(vocab996->data + classNr * 4 + 2);
+		uint16 scriptNr = READ_SCI11ENDIAN_UINT16(vocab996->data + classNr * 4 + 2);
 
 		_classtable[classNr].reg = NULL_REG;
 		_classtable[classNr].script = scriptNr;
@@ -150,8 +151,7 @@
 			getScriptSegment(the_class->script, lock);
 
 			if (!the_class->reg.segment) {
-				error("[VM] Trying to instantiate class %x by instantiating script 0x%x (%03d) failed;"
-				          " Entering debugger.", classnr, the_class->script, the_class->script);
+				error("[VM] Trying to instantiate class %x by instantiating script 0x%x (%03d) failed;", classnr, the_class->script, the_class->script);
 				return NULL_REG;
 			}
 		} else
@@ -181,7 +181,7 @@
 	VERIFY(location.offset + 1 < (uint16)scr->_bufSize, "Locals beyond end of script\n");
 
 	if (getSciVersion() >= SCI_VERSION_1_1)
-		count = READ_LE_UINT16(scr->_buf + location.offset - 2);
+		count = READ_SCI11ENDIAN_UINT16(scr->_buf + location.offset - 2);
 	else
 		count = (READ_LE_UINT16(scr->_buf + location.offset - 2) - 4) >> 1;
 	// half block size
@@ -199,7 +199,7 @@
 		byte *base = (byte *)(scr->_buf + location.offset);
 
 		for (i = 0; i < count; i++)
-			locals->_locals[i] = make_reg(0, READ_LE_UINT16(base + i * 2));
+			locals->_locals[i] = make_reg(0, READ_SCI11ENDIAN_UINT16(base + i * 2));
 	}
 }
 
@@ -209,9 +209,10 @@
 		/* We are forced to use an ugly heuristic here to distinguish function
 		   exports from object/class exports. The former kind points into the
 		   script resource, the latter into the heap resource.  */
-		uint16 location = READ_LE_UINT16((byte *)(scr->_exportTable + i));
-		if ((location < scr->_heapSize - 1) && (READ_LE_UINT16(scr->_heapStart + location) == SCRIPT_OBJECT_MAGIC_NUMBER)) {
-			WRITE_LE_UINT16((byte *)(scr->_exportTable + i), location + scr->_heapStart - scr->_buf);
+		uint16 location = READ_SCI11ENDIAN_UINT16((byte *)(scr->_exportTable + i));
+
+		if ((location < scr->_heapSize - 1) && (READ_SCI11ENDIAN_UINT16(scr->_heapStart + location) == SCRIPT_OBJECT_MAGIC_NUMBER)) {
+			WRITE_SCI11ENDIAN_UINT16((byte *)(scr->_exportTable + i), location + scr->_heapStart - scr->_buf);
 		} else {
 			// Otherwise it's probably a function export,
 			// and we don't need to do anything.
@@ -221,12 +222,12 @@
 
 void SegManager::scriptInitialiseObjectsSci11(SegmentId seg) {
 	Script *scr = getScript(seg);
-	byte *seeker = scr->_heapStart + 4 + READ_LE_UINT16(scr->_heapStart + 2) * 2;
+	byte *seeker = scr->_heapStart + 4 + READ_SCI11ENDIAN_UINT16(scr->_heapStart + 2) * 2;
 
-	while (READ_LE_UINT16(seeker) == SCRIPT_OBJECT_MAGIC_NUMBER) {
-		if (READ_LE_UINT16(seeker + 14) & SCRIPT_INFO_CLASS) {
+	while (READ_SCI11ENDIAN_UINT16(seeker) == SCRIPT_OBJECT_MAGIC_NUMBER) {
+		if (READ_SCI11ENDIAN_UINT16(seeker + 14) & SCRIPT_INFO_CLASS) {
 			int classpos = seeker - scr->_buf;
-			int species = READ_LE_UINT16(seeker + 10);
+			int species = READ_SCI11ENDIAN_UINT16(seeker + 10);
 
 			if (species < 0 || species >= (int)_classtable.size()) {
 				error("Invalid species %d(0x%x) not in interval [0,%d) while instantiating script %d",
@@ -237,11 +238,11 @@
 			_classtable[species].reg.segment = seg;
 			_classtable[species].reg.offset = classpos;
 		}
-		seeker += READ_LE_UINT16(seeker + 2) * 2;
+		seeker += READ_SCI11ENDIAN_UINT16(seeker + 2) * 2;
 	}
 
-	seeker = scr->_heapStart + 4 + READ_LE_UINT16(scr->_heapStart + 2) * 2;
-	while (READ_LE_UINT16(seeker) == SCRIPT_OBJECT_MAGIC_NUMBER) {
+	seeker = scr->_heapStart + 4 + READ_SCI11ENDIAN_UINT16(scr->_heapStart + 2) * 2;
+	while (READ_SCI11ENDIAN_UINT16(seeker) == SCRIPT_OBJECT_MAGIC_NUMBER) {
 		reg_t reg;
 		Object *obj;
 
@@ -270,7 +271,7 @@
 		// to be sufficient.
 		obj->setClassScriptSelector(make_reg(0, scr->_nr));
 
-		seeker += READ_LE_UINT16(seeker + 2) * 2;
+		seeker += READ_SCI11ENDIAN_UINT16(seeker + 2) * 2;
 	}
 }
 
@@ -514,12 +515,12 @@
 
 	_heapStart = script->size;
 	if (script->size & 2)
-		_heapStart ++;
+		_heapStart++;
 
 	scr->mcpyInOut(0, script->data, script->size);
 	scr->mcpyInOut(_heapStart, heap->data, heap->size);
 
-	if (READ_LE_UINT16(script->data + 6) > 0)
+	if (READ_SCI11ENDIAN_UINT16(script->data + 6) > 0)
 		scr->setExportTableOffset(6);
 
 	reg.segment = seg_id;
@@ -529,7 +530,7 @@
 	segMan->scriptRelocateExportsSci11(seg_id);
 	segMan->scriptInitialiseObjectsSci11(seg_id);
 
-	reg.offset = READ_LE_UINT16(heap->data);
+	reg.offset = READ_SCI11ENDIAN_UINT16(heap->data);
 	scr->heapRelocate(reg);
 
 	return seg_id;

Modified: scummvm/trunk/engines/sci/engine/scriptdebug.cpp
===================================================================
--- scummvm/trunk/engines/sci/engine/scriptdebug.cpp	2010-05-17 23:29:44 UTC (rev 49069)
+++ scummvm/trunk/engines/sci/engine/scriptdebug.cpp	2010-05-18 04:17:58 UTC (rev 49070)
@@ -95,7 +95,7 @@
 		return -1;
 	}
 
-	return READ_LE_UINT16(selectoroffset + prop_ofs);
+	return READ_SCI11ENDIAN_UINT16(selectoroffset + prop_ofs);
 }
 
 // Disassembles one command from the heap, returns address of next command or 0 if a ret was encountered.
@@ -164,7 +164,7 @@
 
 		case Script_Word:
 		case Script_SWord:
-			printf(" %04x", 0xffff & (scr[retval.offset] | (scr[retval.offset+1] << 8)));
+			printf(" %04x", READ_SCI11ENDIAN_UINT16(&scr[retval.offset]));
 			retval.offset += 2;
 			break;
 
@@ -178,7 +178,7 @@
 			if (opsize)
 				param_value = scr[retval.offset++];
 			else {
-				param_value = 0xffff & (scr[retval.offset] | (scr[retval.offset+1] << 8));
+				param_value = READ_SCI11ENDIAN_UINT16(&scr[retval.offset]);
 				retval.offset += 2;
 			}
 
@@ -195,7 +195,7 @@
 			if (opsize)
 				param_value = scr[retval.offset++];
 			else {
-				param_value = 0xffff & (scr[retval.offset] | (scr[retval.offset+1] << 8));
+				param_value = READ_SCI11ENDIAN_UINT16(&scr[retval.offset]);
 				retval.offset += 2;
 			}
 			printf(opsize ? " %02x" : " %04x", param_value);
@@ -205,7 +205,7 @@
 			if (opsize)
 				param_value = scr[retval.offset++];
 			else {
-				param_value = 0xffff & (scr[retval.offset] | (scr[retval.offset+1] << 8));
+				param_value = READ_SCI11ENDIAN_UINT16(&scr[retval.offset]);
 				retval.offset += 2;
 			}
 			printf(opsize ? " %02x  [%04x]" : " %04x  [%04x]", param_value, (0xffff) & (retval.offset + param_value));
@@ -337,7 +337,7 @@
 			int opcode = scriptState.xs->addr.pc.offset >= code_buf_size ? 0 : code_buf[scriptState.xs->addr.pc.offset];
 			int op = opcode >> 1;
 			int paramb1 = scriptState.xs->addr.pc.offset + 1 >= code_buf_size ? 0 : code_buf[scriptState.xs->addr.pc.offset + 1];
-			int paramf1 = (opcode & 1) ? paramb1 : (scriptState.xs->addr.pc.offset + 2 >= code_buf_size ? 0 : (int16)READ_LE_UINT16(code_buf + scriptState.xs->addr.pc.offset + 1));
+			int paramf1 = (opcode & 1) ? paramb1 : (scriptState.xs->addr.pc.offset + 2 >= code_buf_size ? 0 : (int16)READ_SCI11ENDIAN_UINT16(code_buf + scriptState.xs->addr.pc.offset + 1));
 
 			switch (g_debugState.seeking) {
 			case kDebugSeekSpecialCallk:
@@ -397,9 +397,9 @@
 
 void Kernel::dumpScriptObject(char *data, int seeker, int objsize) {
 	int selectors, overloads, selectorsize;
-	int species = (int16)READ_LE_UINT16((unsigned char *) data + 8 + seeker);
-	int superclass = (int16)READ_LE_UINT16((unsigned char *) data + 10 + seeker);
-	int namepos = (int16)READ_LE_UINT16((unsigned char *) data + 14 + seeker);
+	int species = (int16)READ_SCI11ENDIAN_UINT16((unsigned char *) data + 8 + seeker);
+	int superclass = (int16)READ_SCI11ENDIAN_UINT16((unsigned char *) data + 10 + seeker);
+	int namepos = (int16)READ_SCI11ENDIAN_UINT16((unsigned char *) data + 14 + seeker);
 	int i = 0;
 
 	printf("Object\n");
@@ -410,28 +410,28 @@
 	printf("Name: %s\n", namepos ? ((char *)(data + namepos)) : "<unknown>");
 	printf("Superclass: %x\n", superclass);
 	printf("Species: %x\n", species);
-	printf("-info-:%x\n", (int16)READ_LE_UINT16((unsigned char *) data + 12 + seeker) & 0xffff);
+	printf("-info-:%x\n", (int16)READ_SCI11ENDIAN_UINT16((unsigned char *) data + 12 + seeker) & 0xffff);
 
-	printf("Function area offset: %x\n", (int16)READ_LE_UINT16((unsigned char *) data + seeker + 4));
-	printf("Selectors [%x]:\n", selectors = (selectorsize = (int16)READ_LE_UINT16((unsigned char *) data + seeker + 6)));
+	printf("Function area offset: %x\n", (int16)READ_SCI11ENDIAN_UINT16((unsigned char *) data + seeker + 4));
+	printf("Selectors [%x]:\n", selectors = (selectorsize = (int16)READ_SCI11ENDIAN_UINT16((unsigned char *) data + seeker + 6)));
 
 	seeker += 8;
 
 	while (selectors--) {
-		printf("  [#%03x] = 0x%x\n", i++, (int16)READ_LE_UINT16((unsigned char *)data + seeker) & 0xffff);
+		printf("  [#%03x] = 0x%x\n", i++, (int16)READ_SCI11ENDIAN_UINT16((unsigned char *)data + seeker) & 0xffff);
 		seeker += 2;
 	}
 
-	printf("Overridden functions: %x\n", selectors = overloads = (int16)READ_LE_UINT16((unsigned char *)data + seeker));
+	printf("Overridden functions: %x\n", selectors = overloads = (int16)READ_SCI11ENDIAN_UINT16((unsigned char *)data + seeker));
 
 	seeker += 2;
 
 	if (overloads < 100)
 		while (overloads--) {
-			int selector = (int16)READ_LE_UINT16((unsigned char *) data + (seeker));
+			int selector = (int16)READ_SCI11ENDIAN_UINT16((unsigned char *) data + (seeker));
 
 			printf("  [%03x] %s: @", selector & 0xffff, (selector >= 0 && selector < (int)_selectorNames.size()) ? _selectorNames[selector].c_str() : "<?>");
-			printf("%04x\n", (int16)READ_LE_UINT16((unsigned char *)data + seeker + selectors*2 + 2) & 0xffff);
+			printf("%04x\n", (int16)READ_SCI11ENDIAN_UINT16((unsigned char *)data + seeker + selectors*2 + 2) & 0xffff);
 
 			seeker += 2;
 		}
@@ -439,9 +439,9 @@
 
 void Kernel::dumpScriptClass(char *data, int seeker, int objsize) {
 	int selectors, overloads, selectorsize;
-	int species = (int16)READ_LE_UINT16((unsigned char *) data + 8 + seeker);
-	int superclass = (int16)READ_LE_UINT16((unsigned char *) data + 10 + seeker);
-	int namepos = (int16)READ_LE_UINT16((unsigned char *) data + 14 + seeker);
+	int species = (int16)READ_SCI11ENDIAN_UINT16((unsigned char *) data + 8 + seeker);
+	int superclass = (int16)READ_SCI11ENDIAN_UINT16((unsigned char *) data + 10 + seeker);
+	int namepos = (int16)READ_SCI11ENDIAN_UINT16((unsigned char *) data + 14 + seeker);
 
 	printf("Class\n");
 
@@ -450,35 +450,35 @@
 	printf("Name: %s\n", namepos ? ((char *)data + namepos) : "<unknown>");
 	printf("Superclass: %x\n", superclass);
 	printf("Species: %x\n", species);
-	printf("-info-:%x\n", (int16)READ_LE_UINT16((unsigned char *)data + 12 + seeker) & 0xffff);
+	printf("-info-:%x\n", (int16)READ_SCI11ENDIAN_UINT16((unsigned char *)data + 12 + seeker) & 0xffff);
 
-	printf("Function area offset: %x\n", (int16)READ_LE_UINT16((unsigned char *)data + seeker + 4));
-	printf("Selectors [%x]:\n", selectors = (selectorsize = (int16)READ_LE_UINT16((unsigned char *)data + seeker + 6)));
+	printf("Function area offset: %x\n", (int16)READ_SCI11ENDIAN_UINT16((unsigned char *)data + seeker + 4));
+	printf("Selectors [%x]:\n", selectors = (selectorsize = (int16)READ_SCI11ENDIAN_UINT16((unsigned char *)data + seeker + 6)));
 
 	seeker += 8;
 	selectorsize <<= 1;
 
 	while (selectors--) {
-		int selector = (int16)READ_LE_UINT16((unsigned char *) data + (seeker) + selectorsize);
+		int selector = (int16)READ_SCI11ENDIAN_UINT16((unsigned char *) data + (seeker) + selectorsize);
 
 		printf("  [%03x] %s = 0x%x\n", 0xffff & selector, (selector >= 0 && selector < (int)_selectorNames.size()) ? _selectorNames[selector].c_str() : "<?>",
-		          (int16)READ_LE_UINT16((unsigned char *)data + seeker) & 0xffff);
+		          (int16)READ_SCI11ENDIAN_UINT16((unsigned char *)data + seeker) & 0xffff);
 
 		seeker += 2;
 	}
 
 	seeker += selectorsize;
 
-	printf("Overloaded functions: %x\n", selectors = overloads = (int16)READ_LE_UINT16((unsigned char *)data + seeker));
+	printf("Overloaded functions: %x\n", selectors = overloads = (int16)READ_SCI11ENDIAN_UINT16((unsigned char *)data + seeker));
 
 	seeker += 2;
 
 	while (overloads--) {
-		int selector = (int16)READ_LE_UINT16((unsigned char *)data + (seeker));
+		int selector = (int16)READ_SCI11ENDIAN_UINT16((unsigned char *)data + (seeker));
 		fprintf(stderr, "selector=%d; selectorNames.size() =%d\n", selector, _selectorNames.size());
 		printf("  [%03x] %s: @", selector & 0xffff, (selector >= 0 && selector < (int)_selectorNames.size()) ?
 		          _selectorNames[selector].c_str() : "<?>");
-		printf("%04x\n", (int16)READ_LE_UINT16((unsigned char *)data + seeker + selectors * 2 + 2) & 0xffff);
+		printf("%04x\n", (int16)READ_SCI11ENDIAN_UINT16((unsigned char *)data + seeker + selectors * 2 + 2) & 0xffff);
 
 		seeker += 2;
 	}
@@ -495,7 +495,7 @@
 	}
 
 	while (_seeker < script->size) {
-		int objtype = (int16)READ_LE_UINT16(script->data + _seeker);
+		int objtype = (int16)READ_SCI11ENDIAN_UINT16(script->data + _seeker);
 		int objsize;
 		unsigned int seeker = _seeker + 4;
 
@@ -508,7 +508,7 @@
 
 		printf("\n");
 
-		objsize = (int16)READ_LE_UINT16(script->data + _seeker + 2);
+		objsize = (int16)READ_SCI11ENDIAN_UINT16(script->data + _seeker + 2);
 
 		printf("Obj type #%x, size 0x%x: ", objtype, objsize);
 

Modified: scummvm/trunk/engines/sci/engine/segment.cpp
===================================================================
--- scummvm/trunk/engines/sci/engine/segment.cpp	2010-05-17 23:29:44 UTC (rev 49069)
+++ scummvm/trunk/engines/sci/engine/segment.cpp	2010-05-18 04:17:58 UTC (rev 49070)
@@ -253,18 +253,18 @@
 void Script::scriptAddCodeBlock(reg_t location) {
 	CodeBlock cb;
 	cb.pos = location;
-	cb.size = READ_LE_UINT16(_buf + location.offset - 2);
+	cb.size = READ_SCI11ENDIAN_UINT16(_buf + location.offset - 2);
 	_codeBlocks.push_back(cb);
 }
 
 void Script::scriptRelocate(reg_t block) {
-	VERIFY(block.offset < (uint16)_bufSize && READ_LE_UINT16(_buf + block.offset) * 2 + block.offset < (uint16)_bufSize,
+	VERIFY(block.offset < (uint16)_bufSize && READ_SCI11ENDIAN_UINT16(_buf + block.offset) * 2 + block.offset < (uint16)_bufSize,
 	       "Relocation block outside of script\n");
 
-	int count = READ_LE_UINT16(_buf + block.offset);
+	int count = READ_SCI11ENDIAN_UINT16(_buf + block.offset);
 
 	for (int i = 0; i <= count; i++) {
-		int pos = READ_LE_UINT16(_buf + block.offset + 2 + (i * 2));
+		int pos = READ_SCI11ENDIAN_UINT16(_buf + block.offset + 2 + (i * 2));
 		if (!pos)
 			continue; // FIXME: A hack pending investigation
 
@@ -302,16 +302,16 @@
 }
 
 void Script::heapRelocate(reg_t block) {
-	VERIFY(block.offset < (uint16)_heapSize && READ_LE_UINT16(_heapStart + block.offset) * 2 + block.offset < (uint16)_bufSize,
+	VERIFY(block.offset < (uint16)_heapSize && READ_SCI11ENDIAN_UINT16(_heapStart + block.offset) * 2 + block.offset < (uint16)_bufSize,
 	       "Relocation block outside of script\n");
 
 	if (_relocated)
 		return;
 	_relocated = true;
-	int count = READ_LE_UINT16(_heapStart + block.offset);
+	int count = READ_SCI11ENDIAN_UINT16(_heapStart + block.offset);
 
 	for (int i = 0; i < count; i++) {
-		int pos = READ_LE_UINT16(_heapStart + block.offset + 2 + (i * 2)) + _scriptSize;
+		int pos = READ_SCI11ENDIAN_UINT16(_heapStart + block.offset + 2 + (i * 2)) + _scriptSize;
 
 		if (!relocateLocal(block.segment, pos)) {
 			bool done = false;
@@ -359,7 +359,7 @@
 void Script::setExportTableOffset(int offset) {
 	if (offset) {
 		_exportTable = (uint16 *)(_buf + offset + 2);
-		_numExports = READ_LE_UINT16((byte *)(_exportTable - 1));
+		_numExports = READ_SCI11ENDIAN_UINT16((byte *)(_exportTable - 1));
 	} else {
 		_exportTable = NULL;
 		_numExports = 0;
@@ -380,7 +380,7 @@
 
 	if (_exportsAreWide)
 		pubfunct *= 2;
-	uint16 offset = READ_LE_UINT16((byte *)(scr->_exportTable + pubfunct));
+	uint16 offset = READ_SCI11ENDIAN_UINT16((byte *)(scr->_exportTable + pubfunct));
 	VERIFY(offset < scr->_bufSize, "invalid export function pointer");
 
 	return offset;
@@ -413,7 +413,7 @@
 
 int16 Script::getHeap(uint16 offset) const {
 	assert(offset + 1 < (int)_bufSize);
-	return READ_LE_UINT16(_buf + offset);
+	return READ_SCI11ENDIAN_UINT16(_buf + offset);
 //	return (_buf[offset] | (_buf[offset+1]) << 8);
 }
 
@@ -695,7 +695,7 @@
 	}
 
 	for (uint i = 0; i < varnum; i++)
-		if (READ_LE_UINT16(buf + (i << 1)) == slc) // Found it?
+		if (READ_SCI11ENDIAN_UINT16(buf + (i << 1)) == slc) // Found it?
 			return i; // report success
 
 	return -1; // Failed

Modified: scummvm/trunk/engines/sci/engine/segment.h
===================================================================
--- scummvm/trunk/engines/sci/engine/segment.h	2010-05-17 23:29:44 UTC (rev 49069)
+++ scummvm/trunk/engines/sci/engine/segment.h	2010-05-18 04:17:58 UTC (rev 49070)
@@ -29,6 +29,7 @@
 #include "common/serializer.h"
 #include "sci/engine/vm.h"
 #include "sci/engine/vm_types.h"	// for reg_t
+#include "sci/util.h"
 
 namespace Sci {
 
@@ -228,16 +229,16 @@
 	reg_t getClassScriptSelector() { return _variables[4]; }
 	void setClassScriptSelector(reg_t value) { _variables[4] = value; }
 
-	Selector getVarSelector(uint16 i) { return *(_baseVars + i); }
+	Selector getVarSelector(uint16 i) { return READ_SCI11ENDIAN_UINT16(_baseVars + i); }
 
 	reg_t getFunction(uint16 i) {
 		uint16 offset = (getSciVersion() < SCI_VERSION_1_1) ? _methodCount + 1 + i : i * 2 + 2;
-		return make_reg(_pos.segment, READ_LE_UINT16((byte *) (_baseMethod + offset)));
+		return make_reg(_pos.segment, READ_SCI11ENDIAN_UINT16((byte *) (_baseMethod + offset)));
 	}
 
 	Selector getFuncSelector(uint16 i) {
 		uint16 offset = (getSciVersion() < SCI_VERSION_1_1) ? i : i * 2 + 1;
-		return READ_LE_UINT16((byte *) (_baseMethod + offset));
+		return READ_SCI11ENDIAN_UINT16((byte *) (_baseMethod + offset));
 	}
 
 	/**
@@ -280,14 +281,14 @@
 			_baseMethod = (uint16 *)(data + READ_LE_UINT16(data + SCRIPT_FUNCTAREAPTR_OFFSET));
 			_methodCount = READ_LE_UINT16(_baseMethod - 1);
 		} else {
-			_variables.resize(READ_LE_UINT16(data + 2));
-			_baseVars = (uint16 *)(buf + READ_LE_UINT16(data + 4));
-			_baseMethod = (uint16 *)(buf + READ_LE_UINT16(data + 6));
-			_methodCount = READ_LE_UINT16(_baseMethod);
+			_variables.resize(READ_SCI11ENDIAN_UINT16(data + 2));
+			_baseVars = (uint16 *)(buf + READ_SCI11ENDIAN_UINT16(data + 4));
+			_baseMethod = (uint16 *)(buf + READ_SCI11ENDIAN_UINT16(data + 6));
+			_methodCount = READ_SCI11ENDIAN_UINT16(_baseMethod);
 		}
 
 		for (uint i = 0; i < _variables.size(); i++)
-			_variables[i] = make_reg(0, READ_LE_UINT16(data + (i * 2)));
+			_variables[i] = make_reg(0, READ_SCI11ENDIAN_UINT16(data + (i * 2)));
 	}
 
 	reg_t getVariable(uint var) { return _variables[var]; }

Modified: scummvm/trunk/engines/sci/engine/vm.cpp
===================================================================
--- scummvm/trunk/engines/sci/engine/vm.cpp	2010-05-17 23:29:44 UTC (rev 49069)
+++ scummvm/trunk/engines/sci/engine/vm.cpp	2010-05-18 04:17:58 UTC (rev 49070)
@@ -650,11 +650,11 @@
 			break;
 
 		case Script_Word:
-			opparams[i] = READ_LE_UINT16(src + offset);
+			opparams[i] = READ_SCI11ENDIAN_UINT16(src + offset);
 			offset += 2;
 			break;
 		case Script_SWord:
-			opparams[i] = (int16)READ_LE_UINT16(src + offset);
+			opparams[i] = (int16)READ_SCI11ENDIAN_UINT16(src + offset);
 			offset += 2;
 			break;
 
@@ -670,7 +670,7 @@
 			if (extOpcode & 1) {
 				opparams[i] = src[offset++];
 			} else {
-				opparams[i] = READ_LE_UINT16(src + offset);
+				opparams[i] = READ_SCI11ENDIAN_UINT16(src + offset);
 				offset += 2;
 			}
 			break;
@@ -680,7 +680,7 @@
 			if (extOpcode & 1) {
 				opparams[i] = (int8)src[offset++];
 			} else {
-				opparams[i] = (int16)READ_LE_UINT16(src + offset);
+				opparams[i] = (int16)READ_SCI11ENDIAN_UINT16(src + offset);
 				offset += 2;
 			}
 			break;

Modified: scummvm/trunk/engines/sci/engine/vm.h
===================================================================
--- scummvm/trunk/engines/sci/engine/vm.h	2010-05-17 23:29:44 UTC (rev 49069)
+++ scummvm/trunk/engines/sci/engine/vm.h	2010-05-18 04:17:58 UTC (rev 49070)
@@ -107,7 +107,7 @@
 	reg_t reg; ///< offset; script-relative offset, segment: 0 if not instantiated
 };
 
-#define RAW_IS_OBJECT(datablock) (READ_LE_UINT16(((byte *) datablock) + SCRIPT_OBJECT_MAGIC_OFFSET) == SCRIPT_OBJECT_MAGIC_NUMBER)
+#define RAW_IS_OBJECT(datablock) (READ_SCI11ENDIAN_UINT16(((byte *) datablock) + SCRIPT_OBJECT_MAGIC_OFFSET) == SCRIPT_OBJECT_MAGIC_NUMBER)
 
 /** Contains selector IDs for a few selected selectors */
 struct SelectorCache {

Modified: scummvm/trunk/engines/sci/graphics/cursor.cpp
===================================================================
--- scummvm/trunk/engines/sci/graphics/cursor.cpp	2010-05-17 23:29:44 UTC (rev 49069)
+++ scummvm/trunk/engines/sci/graphics/cursor.cpp	2010-05-18 04:17:58 UTC (rev 49070)
@@ -205,6 +205,58 @@
 	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 for the Mac CURS 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?
+	// TODO: What games does this work for? At least it does for KQ6.
+	// TODO: Stop asking rhetorical questions.
+
+	Resource *resource = _resMan->findResource(ResourceId(kResourceTypeCursor, 1000 + celNum), false);
+
+	if (!resource) {
+		warning("CURS %d not found", 1000 + celNum);
+		return;
+	}
+
+	assert(resource);
+
+	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;
+
+	kernelShow();
+}
+
 void GfxCursor::setPosition(Common::Point pos) {
 	if (!_upscaledHires) {
 		g_system->warpMouse(pos.x, pos.y);

Modified: scummvm/trunk/engines/sci/graphics/cursor.h
===================================================================
--- scummvm/trunk/engines/sci/graphics/cursor.h	2010-05-17 23:29:44 UTC (rev 49069)
+++ scummvm/trunk/engines/sci/graphics/cursor.h	2010-05-18 04:17:58 UTC (rev 49070)
@@ -52,6 +52,7 @@
 	bool isVisible();
 	void kernelSetShape(GuiResourceId resourceId);
 	void kernelSetView(GuiResourceId viewNum, int loopNum, int celNum, Common::Point *hotspot);
+	void kernelSetMacCursor(GuiResourceId viewNum, int loopNum, int celNum, Common::Point *hotspot);
 	void setPosition(Common::Point pos);
 	Common::Point getPosition();
 	void refreshPosition();

Modified: scummvm/trunk/engines/sci/graphics/view.cpp
===================================================================
--- scummvm/trunk/engines/sci/graphics/view.cpp	2010-05-17 23:29:44 UTC (rev 49069)
+++ scummvm/trunk/engines/sci/graphics/view.cpp	2010-05-18 04:17:58 UTC (rev 49070)
@@ -24,6 +24,7 @@
  */
 
 #include "sci/sci.h"
+#include "sci/util.h"
 #include "sci/engine/state.h"
 #include "sci/graphics/screen.h"
 #include "sci/graphics/palette.h"
@@ -168,11 +169,11 @@
 
 	case kViewVga11: // View-format SCI1.1+
 		// HeaderSize:WORD LoopCount:BYTE Unknown:BYTE Version:WORD Unknown:WORD PaletteOffset:WORD
-		headerSize = READ_LE_UINT16(_resourceData + 0) + 2; // headerSize is not part of the header, so its added
+		headerSize = READ_SCI11ENDIAN_UINT16(_resourceData + 0) + 2; // headerSize is not part of the header, so its added
 		assert(headerSize >= 16);
 		_loopCount = _resourceData[2];
 		assert(_loopCount);
-		palOffset = READ_LE_UINT32(_resourceData + 8);
+		palOffset = READ_SCI11ENDIAN_UINT32(_resourceData + 8);
 		// FIXME: After LoopCount there is another byte and its set for view 50 within Laura Bow 2 CD, check what it means
 
 		loopData = _resourceData + headerSize;
@@ -203,22 +204,24 @@
 			celCount = loopData[2];
 			_loop[loopNo].celCount = celCount;
 
-			celData = _resourceData + READ_LE_UINT32(loopData + 12);
+			celData = _resourceData + READ_SCI11ENDIAN_UINT32(loopData + 12);
 
 			// read cel info
 			_loop[loopNo].cel = new CelInfo[celCount];
 			for (celNo = 0; celNo < celCount; celNo++) {
 				cel = &_loop[loopNo].cel[celNo];
-				cel->width = READ_LE_UINT16(celData);
-				assert(cel->width);
-				cel->height = READ_LE_UINT16(celData + 2);
-				assert(cel->height);
-				cel->displaceX = READ_LE_UINT16(celData + 4);
-				cel->displaceY = READ_LE_UINT16(celData + 6);
+				cel->width = READ_SCI11ENDIAN_UINT16(celData);
+				cel->height = READ_SCI11ENDIAN_UINT16(celData + 2);
+				cel->displaceX = READ_SCI11ENDIAN_UINT16(celData + 4);
+				cel->displaceY = READ_SCI11ENDIAN_UINT16(celData + 6);
+
+				assert(cel->width && cel->height);
+
 				cel->clearKey = celData[8];
 				cel->offsetEGA = 0;
-				cel->offsetRLE = READ_LE_UINT32(celData + 24);
-				cel->offsetLiteral = READ_LE_UINT32(celData + 28);
+				cel->offsetRLE = READ_SCI11ENDIAN_UINT32(celData + 24);
+				cel->offsetLiteral = READ_SCI11ENDIAN_UINT32(celData + 28);
+
 				cel->rawBitmap = 0;
 				if (_loop[loopNo].mirrorFlag)
 					cel->displaceX = -cel->displaceX;
@@ -351,39 +354,41 @@
 	} else {
 		literalPtr = _resourceData + celInfo->offsetLiteral;
 		if (celInfo->offsetRLE) {
-			// decompression for data that has separate rle and literal streams
-			while (pixelNo < pixelCount) {
-				pixel = *rlePtr++;
-				runLength = pixel & 0x3F;
-				switch (pixel & 0xC0) {
-				case 0: // copy bytes as-is
-					while (runLength-- && pixelNo < pixelCount)
-						outPtr[pixelNo++] = *literalPtr++;
-					break;
-				case 0x80: // fill with color
-					memset(outPtr + pixelNo, *literalPtr++, MIN<uint32>(runLength, pixelCount - pixelNo));
+			if (g_sci->getPlatform() == Common::kPlatformMacintosh && getSciVersion() >= SCI_VERSION_1_1) {
+				// Crazy-Ass compression for SCI1.1+ Mac
+				while (pixelNo < pixelCount) {
+					uint32 pixelLine = pixelNo;
+					runLength = *rlePtr++;
 					pixelNo += runLength;
-					break;
-				case 0xC0: // fill with transparent
-					pixelNo += runLength;
-					break;
+					runLength = *rlePtr++;
+					while (runLength-- && pixelNo < pixelCount) {
+						outPtr[pixelNo] = *literalPtr++;
+						if (outPtr[pixelNo] == 255)
+							outPtr[pixelNo] = 0;
+						pixelNo++;
+					}
+					pixelNo = pixelLine + celInfo->width;
 				}
+			} else {
+				// decompression for data that has separate rle and literal streams
+				while (pixelNo < pixelCount) {
+					pixel = *rlePtr++;
+					runLength = pixel & 0x3F;
+					switch (pixel & 0xC0) {
+					case 0: // copy bytes as-is
+						while (runLength-- && pixelNo < pixelCount)
+							outPtr[pixelNo++] = *literalPtr++;
+						break;
+					case 0x80: // fill with color
+						memset(outPtr + pixelNo, *literalPtr++, MIN<uint32>(runLength, pixelCount - pixelNo));
+						pixelNo += runLength;
+						break;
+					case 0xC0: // fill with transparent
+						pixelNo += runLength;
+						break;
+					}
+				}
 			}
-			// Crazy-Ass mac compression for clone2727
-			// uint32 pixelLine;
-			// while (pixelNo < pixelCount) {
-			// 	pixelLine = pixelNo;
-			// 	runLength = *rlePtr++;
-			// 	pixelNo += runLength;
-			// 	runLength = *rlePtr++;
-			// 	while (runLength-- && pixelNo < pixelCount) {
-			// 		outPtr[pixelNo] = *literalPtr++;
-			// 		if (outPtr[pixelNo] == 255)
-			// 			outPtr[pixelNo] = 0;
-			// 		pixelNo++;
-			// 	}
-			// 	pixelNo = pixelLine + celInfo->width;
-			// }
 		} else {
 			// literal stream only, so no compression
 			memcpy(outPtr, literalPtr, pixelCount);

Modified: scummvm/trunk/engines/sci/module.mk
===================================================================
--- scummvm/trunk/engines/sci/module.mk	2010-05-17 23:29:44 UTC (rev 49069)
+++ scummvm/trunk/engines/sci/module.mk	2010-05-18 04:17:58 UTC (rev 49070)
@@ -7,6 +7,7 @@
 	event.o \
 	resource.o \
 	sci.o \
+	util.o \
 	engine/features.o \
 	engine/game.o \
 	engine/gc.o \

Modified: scummvm/trunk/engines/sci/resource.cpp
===================================================================
--- scummvm/trunk/engines/sci/resource.cpp	2010-05-17 23:29:44 UTC (rev 49069)
+++ scummvm/trunk/engines/sci/resource.cpp	2010-05-18 04:17:58 UTC (rev 49070)
@@ -29,6 +29,7 @@
 #include "common/macresman.h"
 
 #include "sci/resource.h"
+#include "sci/util.h"
 
 namespace Sci {
 
@@ -581,6 +582,15 @@
 			addSource(0, kSourceMacResourceFork, filename.c_str(), atoi(filename.c_str() + 4));
 		}
 #ifdef ENABLE_SCI32
+		// Mac SCI32 games have extra folders for patches
+		addPatchDir("Robot Folder");
+		addPatchDir("Sound Folder");
+		addPatchDir("Voices Folder");
+		//addPatchDir("VMD Folder");
+
+		// There can also be a "Patches" resource fork with patches
+		if (Common::File::exists("Patches"))
+			addSource(0, kSourceMacResourceFork, "Patches", 100);
 	} else {
 		// SCI2.1-SCI3 file naming scheme
 		Common::ArchiveMemberList mapFiles;
@@ -750,11 +760,8 @@
 }
 
 void ResourceManager::freeResourceSources() {
-	for (Common::List<ResourceSource *>::iterator it = _sources.begin(); it != _sources.end(); ++it) {
-		if ((*it)->source_type == kSourceMacResourceFork)
-			(*it)->macResMan.close();
+	for (Common::List<ResourceSource *>::iterator it = _sources.begin(); it != _sources.end(); ++it)
 		delete *it;
-	}
 
 	_sources.clear();
 }
@@ -1452,18 +1459,32 @@
 	return 0;
 }
 
-static const uint32 resourceTypeMacTags[] = {
-	'V56 ', 'P56 ', 'SCR ', 'TEX ', 'SND ',
-		 0, 'VOC ', 'FON ',      0, 'Pat ', // 'CURS is a mac cursor, not sure if it goes in
-	     0, 'PAL ',      0,      0,      0,
-	'MSG ',      0, 'HEP '
+struct {
+	uint32 tag;
+	ResourceType type;
+} static const macResTagMap[] = {
+	{ MKID_BE('V56 '), kResourceTypeView },
+	{ MKID_BE('P56 '), kResourceTypePic },
+	{ MKID_BE('SCR '), kResourceTypeScript },
+	{ MKID_BE('TEX '), kResourceTypeText },
+	{ MKID_BE('SND '), kResourceTypeSound },
+	{ MKID_BE('VOC '), kResourceTypeVocab },
+	{ MKID_BE('FON '), kResourceTypeFont },
+	{ MKID_BE('CURS'), kResourceTypeCursor },
+	{ MKID_BE('crsr'), kResourceTypeCursor },
+	{ MKID_BE('Pat '), kResourceTypePatch },
+	{ MKID_BE('PAL '), kResourceTypePalette },
+	{ MKID_BE('snd '), kResourceTypeAudio },
+	{ MKID_BE('MSG '), kResourceTypeMessage },
+	{ MKID_BE('HEP '), kResourceTypeHeap }
 };
 
 static uint32 resTypeToMacTag(ResourceType type) {
-	if (type >= ARRAYSIZE(resourceTypeMacTags))
-		return 0;
+	for (uint32 i = 0; i < ARRAYSIZE(macResTagMap); i++)
+		if (macResTagMap[i].type == type)
+			return macResTagMap[i].tag;
 
-	return resourceTypeMacTags[type];
+	return 0;
 }
 
 int ResourceManager::readMacResourceFork(ResourceSource *source) {
@@ -1476,9 +1497,9 @@
 		ResourceType type = kResourceTypeInvalid;
 
 		// Map the Mac tags to our ResourceType
-		for (uint32 j = 0; j < ARRAYSIZE(resourceTypeMacTags); j++)
-			if (tagArray[i] == resourceTypeMacTags[j]) {
-				type = (ResourceType)j;
+		for (uint32 j = 0; j < ARRAYSIZE(macResTagMap); j++)
+			if (tagArray[i] == macResTagMap[j].tag) {
+				type = macResTagMap[j].type;
 				break;
 			}
 
@@ -1492,7 +1513,7 @@
 
 			Resource *newrsc = NULL;
 
-			// Prepare destination, if neccessary
+			// Prepare destination, if neccessary. Resource forks may contain patches.
 			if (!_resMap.contains(resId)) {
 				newrsc = new Resource;
 				_resMap.setVal(resId, newrsc);
@@ -1500,11 +1521,11 @@
 				newrsc = _resMap.getVal(resId);
 
 			// Get the size of the file
-			Common::SeekableReadStream *stream = source->macResMan.getResource(tagArray[i], idArray[j]);;
+			Common::SeekableReadStream *stream = source->macResMan.getResource(tagArray[i], idArray[j]);
 			uint32 fileSize = stream->size();
 			delete stream;
 
-			// Overwrite everything, because we're patching
+			// Overwrite everything
 			newrsc->_id = resId;
 			newrsc->_status = kResStatusNoMalloc;
 			newrsc->_source = source;
@@ -2045,7 +2066,7 @@
 	// Set view type
 	if (viewCompression == kCompDCL
 		|| _volVersion == kResVersionSci11 // pq4demo
-		|| _volVersion == kResVersionSci11Mac // FIXME: Is this right?
+		|| _volVersion == kResVersionSci11Mac
 #ifdef ENABLE_SCI32
 		|| viewCompression == kCompSTACpack
 		|| _volVersion == kResVersionSci32 // kq7
@@ -2064,6 +2085,8 @@
 		// TODO: Decide between SCI2 and SCI2.1
 		if (Common::File::exists("resource.cfg"))
 			s_sciVersion = SCI_VERSION_1_1;
+		else if (Common::File::exists("Patches"))
+			s_sciVersion = SCI_VERSION_2_1;
 		else
 			s_sciVersion = SCI_VERSION_2;
 		return;

Modified: scummvm/trunk/engines/sci/sound/audio.cpp
===================================================================
--- scummvm/trunk/engines/sci/sound/audio.cpp	2010-05-17 23:29:44 UTC (rev 49069)
+++ scummvm/trunk/engines/sci/sound/audio.cpp	2010-05-18 04:17:58 UTC (rev 49070)
@@ -271,31 +271,42 @@
 				Common::MemoryReadStream dataStream(audioRes->data, audioRes->size, DisposeAfterUse::NO);
 				data = readSOLAudio(&dataStream, size, audioFlags, flags);
 			}
-		} else {
-			// SCI1 or WAVE file
-			if (audioRes->size > 4) {
-				if (memcmp(audioRes->data, "RIFF", 4) == 0) {
-					// WAVE detected
-					Common::MemoryReadStream *waveStream = new Common::MemoryReadStream(audioRes->data, audioRes->size, DisposeAfterUse::NO);
+		} else if (audioRes->size > 4 && READ_BE_UINT32(audioRes->data) == MKID_BE('RIFF')) {
+			// WAVE detected
+			Common::MemoryReadStream *waveStream = new Common::MemoryReadStream(audioRes->data, audioRes->size, DisposeAfterUse::NO);
 
-					// Calculate samplelen from WAVE header
-					int waveSize = 0, waveRate = 0;
-					byte waveFlags = 0;
-					Audio::loadWAVFromStream(*waveStream, waveSize, waveRate, waveFlags);
-					*sampleLen = (waveFlags & Audio::FLAG_16BITS ? waveSize >> 1 : waveSize) * 60 / waveRate;
+			// Calculate samplelen from WAVE header
+			int waveSize = 0, waveRate = 0;
+			byte waveFlags = 0;
+			Audio::loadWAVFromStream(*waveStream, waveSize, waveRate, waveFlags);
+			*sampleLen = (waveFlags & Audio::FLAG_16BITS ? waveSize >> 1 : waveSize) * 60 / waveRate;
 
-					waveStream->seek(0, SEEK_SET);
-					audioStream = Audio::makeWAVStream(waveStream, DisposeAfterUse::YES);
-				}
-			}
-			if (!audioStream) {
-				// SCI1 raw audio
-				size = audioRes->size;
-				data = (byte *)malloc(size);
-				assert(data);
-				memcpy(data, audioRes->data, size);
-				flags = Audio::FLAG_UNSIGNED;
-			}
+			waveStream->seek(0, SEEK_SET);
+			audioStream = Audio::makeWAVStream(waveStream, DisposeAfterUse::YES);
+		} else if (audioRes->size > 14 && READ_BE_UINT16(audioRes->data) == 1 && READ_BE_UINT16(audioRes->data + 2) == 1
+				&& READ_BE_UINT16(audioRes->data + 4) == 5 && READ_BE_UINT32(audioRes->data + 10) == 0x00018051) {
+			// Mac snd detected
+			// See http://developer.apple.com/legacy/mac/library/documentation/mac/Sound/Sound-60.html#HEADING60-15 for more details
+
+			uint32 soundHeaderOffset = READ_BE_UINT32(audioRes->data + 16);
+			assert(READ_BE_UINT32(audioRes->data + soundHeaderOffset) == 0);
+			size = READ_BE_UINT32(audioRes->data + soundHeaderOffset + 4);
+			_audioRate = READ_BE_UINT16(audioRes->data + soundHeaderOffset + 8); // Really floating point, but we're just truncating
+
+			if (*(audioRes->data + soundHeaderOffset + 20) != 0)
+				error("Unhandled Mac snd extended/compressed header");
+
+			data = (byte *)malloc(size);
+			memcpy(data, audioRes->data + soundHeaderOffset + 22, size);
+			flags = Audio::FLAG_UNSIGNED;
+		} else {
+			// SCI1 raw audio
+			size = audioRes->size;
+			data = (byte *)malloc(size);
+			assert(data);
+			memcpy(data, audioRes->data, size);
+			flags = Audio::FLAG_UNSIGNED;
+			_audioRate = 11025;
 		}
 
 		if (data)

Added: scummvm/trunk/engines/sci/util.cpp
===================================================================
--- scummvm/trunk/engines/sci/util.cpp	                        (rev 0)
+++ scummvm/trunk/engines/sci/util.cpp	2010-05-18 04:17:58 UTC (rev 49070)
@@ -0,0 +1,54 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "common/endian.h"
+
+#include "sci/util.h"
+#include "sci/sci.h"
+
+namespace Sci {
+
+uint16 READ_SCI11ENDIAN_UINT16(const void *ptr) {
+	if (g_sci->getPlatform() == Common::kPlatformMacintosh && getSciVersion() >= SCI_VERSION_1_1)
+		return READ_BE_UINT16(ptr);
+
+	return READ_LE_UINT16(ptr);
+}
+
+uint32 READ_SCI11ENDIAN_UINT32(const void *ptr) {
+	if (g_sci->getPlatform() == Common::kPlatformMacintosh && getSciVersion() >= SCI_VERSION_1_1)
+		return READ_BE_UINT32(ptr);
+
+	return READ_LE_UINT32(ptr);
+}
+
+void WRITE_SCI11ENDIAN_UINT16(void *ptr, uint16 val) {
+	if (g_sci->getPlatform() == Common::kPlatformMacintosh && getSciVersion() >= SCI_VERSION_1_1)
+		WRITE_BE_UINT16(ptr, val);
+	else
+		WRITE_LE_UINT16(ptr, val);
+}
+
+} // End of namespace Sci


Property changes on: scummvm/trunk/engines/sci/util.cpp
___________________________________________________________________
Added: svn:mime-type
   + text/plain
Added: svn:keywords
   + Date Rev Author URL Id
Added: svn:eol-style
   + native

Added: scummvm/trunk/engines/sci/util.h
===================================================================
--- scummvm/trunk/engines/sci/util.h	                        (rev 0)
+++ scummvm/trunk/engines/sci/util.h	2010-05-18 04:17:58 UTC (rev 49070)
@@ -0,0 +1,41 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef SCI_UTIL_H
+#define SCI_UTIL_H
+
+#include "common/scummsys.h"
+
+namespace Sci {
+
+// Wrappers for reading integer values for SCI1.1+.
+// Mac versions have big endian data for some fields.
+uint16 READ_SCI11ENDIAN_UINT16(const void *ptr);
+uint32 READ_SCI11ENDIAN_UINT32(const void *ptr);
+void WRITE_SCI11ENDIAN_UINT16(void *ptr, uint16 val);
+
+} // End of namespace Sci
+
+#endif


Property changes on: scummvm/trunk/engines/sci/util.h
___________________________________________________________________
Added: svn:mime-type
   + text/plain
Added: svn:keywords
   + Date Rev Author URL Id
Added: svn:eol-style
   + native


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