diff options
| author | Matthew Hoops | 2010-05-18 04:17:58 +0000 | 
|---|---|---|
| committer | Matthew Hoops | 2010-05-18 04:17:58 +0000 | 
| commit | 3dda73d9a2b65da0dad2d184c52f5ebbee682b59 (patch) | |
| tree | b6169db546b692ff9ef889826deda4bfa0b76bf4 | |
| parent | 0fe2ba6a0dd1bc7a3edda7ed8deaeba10f39ab9b (diff) | |
| download | scummvm-rg350-3dda73d9a2b65da0dad2d184c52f5ebbee682b59.tar.gz scummvm-rg350-3dda73d9a2b65da0dad2d184c52f5ebbee682b59.tar.bz2 scummvm-rg350-3dda73d9a2b65da0dad2d184c52f5ebbee682b59.zip | |
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.
svn-id: r49070
| -rw-r--r-- | engines/sci/engine/kernel.cpp | 18 | ||||
| -rw-r--r-- | engines/sci/engine/kgraphics.cpp | 40 | ||||
| -rw-r--r-- | engines/sci/engine/kmisc.cpp | 16 | ||||
| -rw-r--r-- | engines/sci/engine/message.cpp | 8 | ||||
| -rw-r--r-- | engines/sci/engine/script.cpp | 39 | ||||
| -rw-r--r-- | engines/sci/engine/scriptdebug.cpp | 58 | ||||
| -rw-r--r-- | engines/sci/engine/segment.cpp | 22 | ||||
| -rw-r--r-- | engines/sci/engine/segment.h | 17 | ||||
| -rw-r--r-- | engines/sci/engine/vm.cpp | 8 | ||||
| -rw-r--r-- | engines/sci/engine/vm.h | 2 | ||||
| -rw-r--r-- | engines/sci/graphics/cursor.cpp | 52 | ||||
| -rw-r--r-- | engines/sci/graphics/cursor.h | 1 | ||||
| -rw-r--r-- | engines/sci/graphics/view.cpp | 87 | ||||
| -rw-r--r-- | engines/sci/module.mk | 1 | ||||
| -rw-r--r-- | engines/sci/resource.cpp | 61 | ||||
| -rw-r--r-- | engines/sci/sound/audio.cpp | 59 | ||||
| -rw-r--r-- | engines/sci/util.cpp | 54 | ||||
| -rw-r--r-- | engines/sci/util.h | 41 | 
18 files changed, 404 insertions, 180 deletions
| diff --git a/engines/sci/engine/kernel.cpp b/engines/sci/engine/kernel.cpp index 4700c59597..122af1c36b 100644 --- a/engines/sci/engine/kernel.cpp +++ b/engines/sci/engine/kernel.cpp @@ -335,9 +335,9 @@ SciKernelFunction kfunct_mappers[] = {  	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 @@ void Kernel::setDefaultKernelNames(Common::String gameId) {  		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; diff --git a/engines/sci/engine/kgraphics.cpp b/engines/sci/engine/kgraphics.cpp index 452f708864..87f51a1a74 100644 --- a/engines/sci/engine/kgraphics.cpp +++ b/engines/sci/engine/kgraphics.cpp @@ -159,7 +159,10 @@ static reg_t kSetCursorSci11(EngineState *s, int argc, reg_t *argv) {  		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 @@ reg_t kShowMovie(EngineState *s, int argc, reg_t *argv) {  		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 - -		SeqDecoder *seqDecoder = new SeqDecoder(); -		Graphics::VideoPlayer *player = new Graphics::VideoPlayer(seqDecoder); -		if (seqDecoder->loadFile(filename.c_str(), delay)) { -			player->playVideo(); -			playedVideo = true; +		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 { -			warning("Failed to open movie file %s", filename.c_str()); +			// 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->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 diff --git a/engines/sci/engine/kmisc.cpp b/engines/sci/engine/kmisc.cpp index 96241b8b7c..450dca3770 100644 --- a/engines/sci/engine/kmisc.cpp +++ b/engines/sci/engine/kmisc.cpp @@ -294,6 +294,19 @@ reg_t kMemory(EngineState *s, int argc, reg_t *argv) {  	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 @@ reg_t kPlatform(EngineState *s, int argc, reg_t *argv) {  		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: diff --git a/engines/sci/engine/message.cpp b/engines/sci/engine/message.cpp index a4f5da2b4e..07f8792471 100644 --- a/engines/sci/engine/message.cpp +++ b/engines/sci/engine/message.cpp @@ -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 @@ public:  			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 @@ public:  				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 @@ bool MessageState::getRecord(CursorStack &stack, bool recurse, MessageRecord &re  	}  	MessageReader *reader; -	int version = READ_LE_UINT16(res->data) / 1000; +	int version = READ_SCI11ENDIAN_UINT32(res->data) / 1000;  	switch (version) {  	case 2: diff --git a/engines/sci/engine/script.cpp b/engines/sci/engine/script.cpp index 98fc47e2c0..289140215e 100644 --- a/engines/sci/engine/script.cpp +++ b/engines/sci/engine/script.cpp @@ -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 @@ void SegManager::createClassTable() {  	_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 @@ reg_t SegManager::getClassAddress(int classnr, ScriptLoadType lock, reg_t caller  			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 @@ void SegManager::scriptInitialiseLocals(reg_t location) {  	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 @@ void SegManager::scriptInitialiseLocals(reg_t location) {  		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 @@ void SegManager::scriptRelocateExportsSci11(SegmentId seg) {  		/* 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::scriptRelocateExportsSci11(SegmentId seg) {  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 @@ void SegManager::scriptInitialiseObjectsSci11(SegmentId seg) {  			_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 @@ void SegManager::scriptInitialiseObjectsSci11(SegmentId seg) {  		// 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 @@ int script_instantiate_sci11(ResourceManager *resMan, SegManager *segMan, int sc  	_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 @@ int script_instantiate_sci11(ResourceManager *resMan, SegManager *segMan, int sc  	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; diff --git a/engines/sci/engine/scriptdebug.cpp b/engines/sci/engine/scriptdebug.cpp index 57c9f47f24..da8e74e2d1 100644 --- a/engines/sci/engine/scriptdebug.cpp +++ b/engines/sci/engine/scriptdebug.cpp @@ -95,7 +95,7 @@ int propertyOffsetToId(SegManager *segMan, int prop_ofs, reg_t objp) {  		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 @@ reg_t disassemble(EngineState *s, reg_t pos, int print_bw_tag, int print_bytecod  		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 @@ reg_t disassemble(EngineState *s, reg_t pos, int print_bw_tag, int print_bytecod  			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 @@ reg_t disassemble(EngineState *s, reg_t pos, int print_bw_tag, int print_bytecod  			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 @@ reg_t disassemble(EngineState *s, reg_t pos, int print_bw_tag, int print_bytecod  			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 @@ void script_debug(EngineState *s, bool bp) {  			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 script_debug(EngineState *s, bool bp) {  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 @@ void Kernel::dumpScriptObject(char *data, int seeker, int objsize) {  	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::dumpScriptObject(char *data, int seeker, int objsize) {  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 @@ void Kernel::dumpScriptClass(char *data, int seeker, int objsize) {  	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 @@ void Kernel::dissectScript(int scriptNumber, Vocabulary *vocab) {  	}  	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 @@ void Kernel::dissectScript(int scriptNumber, Vocabulary *vocab) {  		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); diff --git a/engines/sci/engine/segment.cpp b/engines/sci/engine/segment.cpp index 5804e5823e..0c6bb93aed 100644 --- a/engines/sci/engine/segment.cpp +++ b/engines/sci/engine/segment.cpp @@ -253,18 +253,18 @@ int Script::relocateObject(Object &obj, SegmentId segment, int location) {  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::scriptRelocate(reg_t block) {  }  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::setLockers(int lockers) {  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 @@ uint16 SegManager::validateExportFunc(int pubfunct, SegmentId seg) {  	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 @@ void Script::mcpyInOut(int dst, const void *src, size_t n) {  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 @@ int Object::locateVarSelector(SegManager *segMan, Selector slc) {  	}  	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 diff --git a/engines/sci/engine/segment.h b/engines/sci/engine/segment.h index 0b60675a6b..28959f087a 100644 --- a/engines/sci/engine/segment.h +++ b/engines/sci/engine/segment.h @@ -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 @@ public:  	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 @@ public:  			_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]; } diff --git a/engines/sci/engine/vm.cpp b/engines/sci/engine/vm.cpp index 3683795a79..eb12ca4203 100644 --- a/engines/sci/engine/vm.cpp +++ b/engines/sci/engine/vm.cpp @@ -650,11 +650,11 @@ int readPMachineInstruction(const byte *src, byte &extOpcode, int16 opparams[4])  			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 @@ int readPMachineInstruction(const byte *src, byte &extOpcode, int16 opparams[4])  			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 @@ int readPMachineInstruction(const byte *src, byte &extOpcode, int16 opparams[4])  			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; diff --git a/engines/sci/engine/vm.h b/engines/sci/engine/vm.h index bc99f529aa..67e7835fb4 100644 --- a/engines/sci/engine/vm.h +++ b/engines/sci/engine/vm.h @@ -107,7 +107,7 @@ struct Class {  	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 { diff --git a/engines/sci/graphics/cursor.cpp b/engines/sci/graphics/cursor.cpp index e756c773ed..2f8393f9ac 100644 --- a/engines/sci/graphics/cursor.cpp +++ b/engines/sci/graphics/cursor.cpp @@ -205,6 +205,58 @@ void GfxCursor::kernelSetView(GuiResourceId viewNum, int loopNum, int celNum, Co  	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); diff --git a/engines/sci/graphics/cursor.h b/engines/sci/graphics/cursor.h index c0b5f9a478..6d92b3cf5f 100644 --- a/engines/sci/graphics/cursor.h +++ b/engines/sci/graphics/cursor.h @@ -52,6 +52,7 @@ public:  	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(); diff --git a/engines/sci/graphics/view.cpp b/engines/sci/graphics/view.cpp index 5ce323751c..2ba14fbd8f 100644 --- a/engines/sci/graphics/view.cpp +++ b/engines/sci/graphics/view.cpp @@ -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 @@ void GfxView::initData(GuiResourceId resourceId) {  	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 @@ void GfxView::initData(GuiResourceId resourceId) {  			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 @@ void GfxView::unpackCel(int16 loopNo, int16 celNo, byte *outPtr, uint32 pixelCou  	} 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)); -					pixelNo += runLength; -					break; -				case 0xC0: // fill with transparent +			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; +					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); diff --git a/engines/sci/module.mk b/engines/sci/module.mk index 852f97b225..8c4d666ba7 100644 --- a/engines/sci/module.mk +++ b/engines/sci/module.mk @@ -7,6 +7,7 @@ MODULE_OBJS := \  	event.o \  	resource.o \  	sci.o \ +	util.o \  	engine/features.o \  	engine/game.o \  	engine/gc.o \ diff --git a/engines/sci/resource.cpp b/engines/sci/resource.cpp index 42f5d15a2c..4888dbd4cb 100644 --- a/engines/sci/resource.cpp +++ b/engines/sci/resource.cpp @@ -29,6 +29,7 @@  #include "common/macresman.h"  #include "sci/resource.h" +#include "sci/util.h"  namespace Sci { @@ -581,6 +582,15 @@ int ResourceManager::addAppropriateSources() {  			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::scanNewSources() {  }  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 @@ int ResourceManager::readResourceMapSCI1(ResourceSource *map) {  	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 @@ int ResourceManager::readMacResourceFork(ResourceSource *source) {  		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 @@ int ResourceManager::readMacResourceFork(ResourceSource *source) {  			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 @@ int ResourceManager::readMacResourceFork(ResourceSource *source) {  				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 @@ void ResourceManager::detectSciVersion() {  	// 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 @@ void ResourceManager::detectSciVersion() {  		// 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; diff --git a/engines/sci/sound/audio.cpp b/engines/sci/sound/audio.cpp index b162667890..331561eea4 100644 --- a/engines/sci/sound/audio.cpp +++ b/engines/sci/sound/audio.cpp @@ -271,31 +271,42 @@ Audio::RewindableAudioStream *AudioPlayer::getAudioStream(uint32 number, uint32  				Common::MemoryReadStream dataStream(audioRes->data, audioRes->size, DisposeAfterUse::NO);  				data = readSOLAudio(&dataStream, size, audioFlags, flags);  			} +		} 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; + +			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 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); - -					// 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; -			} +			// 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) diff --git a/engines/sci/util.cpp b/engines/sci/util.cpp new file mode 100644 index 0000000000..9bda73ae4a --- /dev/null +++ b/engines/sci/util.cpp @@ -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 diff --git a/engines/sci/util.h b/engines/sci/util.h new file mode 100644 index 0000000000..5c4b95b8c4 --- /dev/null +++ b/engines/sci/util.h @@ -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 | 
