diff options
| -rw-r--r-- | engines/sci/engine/kernel.cpp | 11 | ||||
| -rw-r--r-- | engines/sci/engine/kernel.h | 9 | ||||
| -rw-r--r-- | engines/sci/engine/kernel32.cpp | 233 | ||||
| -rw-r--r-- | engines/sci/engine/kevent.cpp | 6 | ||||
| -rw-r--r-- | engines/sci/engine/kfile.cpp | 4 | ||||
| -rw-r--r-- | engines/sci/engine/kgraphics.cpp | 2 | ||||
| -rw-r--r-- | engines/sci/engine/kscripts.cpp | 3 | ||||
| -rw-r--r-- | engines/sci/engine/script.cpp | 4 | ||||
| -rw-r--r-- | engines/sci/engine/seg_manager.cpp | 86 | ||||
| -rw-r--r-- | engines/sci/engine/seg_manager.h | 15 | ||||
| -rw-r--r-- | engines/sci/engine/segment.cpp | 41 | ||||
| -rw-r--r-- | engines/sci/engine/segment.h | 111 | ||||
| -rw-r--r-- | engines/sci/engine/vm.h | 4 | ||||
| -rw-r--r-- | engines/sci/gui/gui_dummy.h | 55 | ||||
| -rw-r--r-- | engines/sci/sci.cpp | 23 | 
15 files changed, 592 insertions, 15 deletions
| diff --git a/engines/sci/engine/kernel.cpp b/engines/sci/engine/kernel.cpp index 73c65245cd..717e850c3f 100644 --- a/engines/sci/engine/kernel.cpp +++ b/engines/sci/engine/kernel.cpp @@ -187,7 +187,7 @@ SciKernelFunction kfunct_mappers[] = {  	/*00*/	DEFUN("Load", kLoad, "iii*"),  	/*01*/	DEFUN("UnLoad", kUnLoad, "i.*"),  	/*02*/	DEFUN("ScriptID", kScriptID, "Ioi*"), -	/*03*/	DEFUN("DisposeScript", kDisposeScript, "Oi"), // Work around QfG1 bug +	/*03*/	DEFUN("DisposeScript", kDisposeScript, "Oii*"), // Work around QfG1 bug  	/*04*/	DEFUN("Clone", kClone, "o"),  	/*05*/	DEFUN("DisposeClone", kDisposeClone, "o"),  	/*06*/	DEFUN("IsObject", kIsObject, "."), @@ -217,7 +217,7 @@ SciKernelFunction kfunct_mappers[] = {  	// FIXME: signature check removed (set to .*) as kGetEvent is different in Mac versions  	/*1c*/	DEFUN("GetEvent", kGetEvent, ".*"),  	///*1c*/	DEFUN("GetEvent", kGetEvent, "io"), -	/*1d*/	DEFUN("GlobalToLocal", kGlobalToLocal, "o"), +	/*1d*/	DEFUN("GlobalToLocal", kGlobalToLocal, "oo*"),  	/*1e*/	DEFUN("LocalToGlobal", kLocalToGlobal, "o"),  	/*1f*/	DEFUN("MapKeyToDir", kMapKeyToDir, "o"),  	/*20*/	DEFUN("DrawMenuBar", kDrawMenuBar, "i"), @@ -336,6 +336,13 @@ SciKernelFunction kfunct_mappers[] = {  	DEFUN("TextColors", kTextColors, ".*"),  	DEFUN("TextFonts", kTextFonts, ".*"),  	DEFUN("Portrait", kPortrait, ".*"), +	 +#ifdef ENABLE_SCI32 +	// SCI32 Kernel Functions +	DEFUN("IsHiRes", kIsHiRes, ""), +	DEFUN("Array", kArray, ".*"), +	DEFUN("String", kString, ".*"), +#endif  	// its a stub, but its needed for Pharkas to work  	DEFUN("PalVary", kPalVary, "ii*"), diff --git a/engines/sci/engine/kernel.h b/engines/sci/engine/kernel.h index 758f9ae9d7..0e94fa5bc8 100644 --- a/engines/sci/engine/kernel.h +++ b/engines/sci/engine/kernel.h @@ -390,6 +390,13 @@ reg_t kPlatform(EngineState *s, int argc, reg_t *argv);  reg_t kTextColors(EngineState *s, int argc, reg_t *argv);  reg_t kTextFonts(EngineState *s, int argc, reg_t *argv); +#ifdef ENABLE_SCI32 +// SCI2 Kernel Functions +reg_t kIsHiRes(EngineState *s, int argc, reg_t *argv); +reg_t kArray(EngineState *s, int argc, reg_t *argv); +reg_t kString(EngineState *s, int argc, reg_t *argv); +#endif +  } // End of namespace Sci -#endif // SCI_ENGIENE_KERNEL_H +#endif // SCI_ENGINE_KERNEL_H diff --git a/engines/sci/engine/kernel32.cpp b/engines/sci/engine/kernel32.cpp index 4c8b486653..c6ac0324d9 100644 --- a/engines/sci/engine/kernel32.cpp +++ b/engines/sci/engine/kernel32.cpp @@ -23,12 +23,14 @@   *   */ +#ifdef ENABLE_SCI32 +  #include "sci/engine/kernel.h" +#include "sci/engine/segment.h" +#include "sci/engine/state.h"  namespace Sci { -#ifdef ENABLE_SCI32 -  static const char *sci2_default_knames[] = {  	/*0x00*/ "Load",  	/*0x01*/ "UnLoad", @@ -341,6 +343,231 @@ void Kernel::setKernelNamesSci21() {  	_kernelNames = Common::StringList(sci21_default_knames, ARRAYSIZE(sci21_default_knames));  } -#endif	// ENABLE_SCI32 +// SCI2 Kernel Functions + +reg_t kIsHiRes(EngineState *s, int argc, reg_t *argv) { +	// Returns 0 if the screen width or height is less than 640 or 400, respectively. +	if (g_system->getWidth() < 640 || g_system->getHeight() < 400) +		return make_reg(0, 0); + +	return make_reg(0, 1); +} + +reg_t kArray(EngineState *s, int argc, reg_t *argv) { +	switch (argv[0].toUint16()) { +	case 0: { // New +		reg_t arrayHandle; +		SciArray<reg_t> *array = s->_segMan->allocateArray(&arrayHandle); +		array->setType(argv[2].toUint16()); +		array->setSize(argv[1].toUint16()); +		return arrayHandle; +		} +	case 1: { // Size +		SciArray<reg_t> *array = s->_segMan->lookupArray(argv[1]); +		return make_reg(0, array->getSize()); +		} +	case 2: { // At +		SciArray<reg_t> *array = s->_segMan->lookupArray(argv[1]); +		return array->getValue(argv[2].toUint16()); +		} +	case 3: { // Atput +		SciArray<reg_t> *array = s->_segMan->lookupArray(argv[1]); + +		uint32 index = argv[2].toUint16(); +		uint32 count = argc - 3; + +		if (index + count > 65535) +			break; + +		if (array->getSize() < index + count) +			array->setSize(index + count); + +		for (uint16 i = 0; i < count; i++) +			array->setValue(i + index, argv[i + 3]); + +		return argv[1]; // We also have to return the handle +		} +	case 4: // Free +		s->_segMan->freeArray(argv[1]); +		return s->r_acc; +	case 5: { // Fill +		SciArray<reg_t> *array = s->_segMan->lookupArray(argv[1]); +		uint16 index = argv[2].toUint16(); + +		// A count of -1 means fill the rest of the array +		uint16 count = argv[3].toSint16() == -1 ? array->getSize() - index : argv[3].toUint16(); + +		if (array->getSize() < index + count) +			array->setSize(index + count); + +		for (uint16 i = 0; i < count; i++) +			array->setValue(i + index, argv[4]); + +		return argv[1]; +		} +	case 6: { // Cpy +		SciArray<reg_t> *array1 = s->_segMan->lookupArray(argv[1]); +		SciArray<reg_t> *array2 = s->_segMan->lookupArray(argv[3]); +		uint32 index1 = argv[2].toUint16(); +		uint32 index2 = argv[4].toUint16(); + +		// The original engine ignores bad copies too +		if (index2 > array2->getSize()) +			break; + +		// A count of -1 means fill the rest of the array +		uint32 count = argv[5].toSint16() == -1 ? array2->getSize() - index2 : argv[5].toUint16(); + +		if (array1->getSize() < index1 + count) +			array1->setSize(index1 + count); + +		for (uint16 i = 0; i < count; i++) +			array1->setValue(i + index1, array2->getValue(i + index2)); + +		return argv[1]; +		} +	case 7: // Cmp +		// Not implemented in SSCI +		return s->r_acc; +	case 8: { // Dup +		SciArray<reg_t> *array = s->_segMan->lookupArray(argv[1]); +		reg_t arrayHandle; +		SciArray<reg_t> *dupArray = s->_segMan->allocateArray(&arrayHandle); +		*dupArray = SciArray<reg_t>(*array); +		return arrayHandle; +		} +	case 9: // Getdata +		if (!s->_segMan->isHeapObject(argv[1])) +			return argv[1]; +	 +		return GET_SEL32(s->_segMan, argv[1], data); +	default: +		error("Unknown kArray subop %d", argv[0].toUint16()); +	} +	 +	return NULL_REG; +} + +reg_t kString(EngineState *s, int argc, reg_t *argv) {	 +	switch (argv[0].toUint16()) { +	case 0: { // New +		reg_t stringHandle; +		SciString *string = s->_segMan->allocateString(&stringHandle); +		string->setType(3); +		string->setSize(argv[1].toUint16()); +		return stringHandle; +		} +	case 1: // Size +		return make_reg(0, s->_segMan->getString(argv[1]).size()); +	case 2:  // At +		return make_reg(0, s->_segMan->getString(argv[1])[argv[2].toUint16()]); +	case 3: { // Atput +		SciString *string = s->_segMan->lookupString(argv[1]); + +		uint32 index = argv[2].toUint16(); +		uint32 count = argc - 3; + +		if (index + count > 65535) +			break; + +		if (string->getSize() < index + count) +			string->setSize(index + count); + +		for (uint16 i = 0; i < count; i++) +			string->setValue(i + index, argv[i + 3].toUint16()); + +		return argv[1]; // We also have to return the handle +		} +	case 4: // Free +		s->_segMan->freeString(argv[1]); +		return s->r_acc; +	case 5: { // Fill +		SciString *string = s->_segMan->lookupString(argv[1]); +		uint16 index = argv[2].toUint16(); + +		// A count of -1 means fill the rest of the array +		uint16 count = argv[3].toSint16() == -1 ? string->getSize() - index : argv[3].toUint16(); + +		if (string->getSize() < index + count) +			string->setSize(index + count); + +		for (uint16 i = 0; i < count; i++) +			string->setValue(i + index, argv[4].toUint16()); + +		return argv[1]; +		} +	case 6: { // Cpy +		SciString *string1 = s->_segMan->lookupString(argv[1]); +		Common::String string2 = s->_segMan->getString(argv[3]); +		uint32 index1 = argv[2].toUint16(); +		uint32 index2 = argv[4].toUint16(); + +		// The original engine ignores bad copies too +		if (index2 > string2.size()) +			break; + +		// A count of -1 means fill the rest of the array +		uint32 count = argv[5].toSint16() == -1 ? string2.size() - index2 : argv[5].toUint16(); + +		if (string1->getSize() < index1 + count) +			string1->setSize(index1 + count); + +		for (uint16 i = 0; i < count; i++) +			string1->setValue(i + index1, string2[i + index2]); + +		return argv[1]; +		} +	case 7: { // Cmp +		Common::String string1, string2; + +		if (argv[1].isNull()) +			string1 = ""; +		else +			string1 = s->_segMan->lookupString(argv[1])->toString(); +			 +		if (argv[2].isNull()) +			string2 = ""; +		else +			string2 = s->_segMan->lookupString(argv[2])->toString(); +			 +		if (argc == 4) // Strncmp +			return make_reg(0, strncmp(string1.c_str(), string2.c_str(), argv[3].toUint16())); +		else           // Strcmp +			return make_reg(0, strcmp(string1.c_str(), string2.c_str())); +		} +	case 8: { // Dup +		SciString *string = s->_segMan->lookupString(argv[1]); +		reg_t stringHandle; +		SciString *dupString = s->_segMan->allocateString(&stringHandle); +		*dupString = SciString(*string); +		return stringHandle; +		} +	case 9: // Getdata +		if (!s->_segMan->isHeapObject(argv[1])) +			return argv[1]; +	 +		return GET_SEL32(s->_segMan, argv[1], data); +	case 10: { // Stringlen +		SciString *sciString = s->_segMan->lookupString(argv[1]); +		Common::String string = sciString->toString(); +		return make_reg(0, string.size()); +		} +	case 11: // Printf +		warning("kString(Printf)"); +		break; +	case 12: // Printf Buf +		warning("kString(PrintfBuf)"); +		break; +	case 13: // atoi +		warning("kString(atoi)"); +		break; +	default: +		error("Unknown kString subop %d", argv[0].toUint16()); +	} + +	return NULL_REG; +}  } // End of namespace Sci + +#endif	// ENABLE_SCI32 diff --git a/engines/sci/engine/kevent.cpp b/engines/sci/engine/kevent.cpp index 02e1961d80..ffdc597652 100644 --- a/engines/sci/engine/kevent.cpp +++ b/engines/sci/engine/kevent.cpp @@ -205,6 +205,12 @@ reg_t kMapKeyToDir(EngineState *s, int argc, reg_t *argv) {  }  reg_t kGlobalToLocal(EngineState *s, int argc, reg_t *argv) { +#ifdef ENABLE_SCI32 +	// SCI32 has an extra argument for a plane here +	if (argc > 1) +		warning("kGlobalToLocal Plane: %04x:%04x", PRINT_REG(argv[1])); +#endif +  	reg_t obj = argc ? argv[0] : NULL_REG; // Can this really happen? Lars  	SegManager *segMan = s->_segMan; diff --git a/engines/sci/engine/kfile.cpp b/engines/sci/engine/kfile.cpp index c3b5f0f296..a7a39042dc 100644 --- a/engines/sci/engine/kfile.cpp +++ b/engines/sci/engine/kfile.cpp @@ -377,8 +377,8 @@ reg_t kDeviceInfo(EngineState *s, int argc, reg_t *argv) {  reg_t kGetSaveDir(EngineState *s, int argc, reg_t *argv) {  #ifdef ENABLE_SCI32  	// TODO: SCI32 uses a parameter here. -	if (argc > 0) -		warning("kGetSaveDir called with a parameter"); +	if (argc > 0)  +		warning("kGetSaveDir called with %d parameter(s): %04x:%04x", argc, PRINT_REG(argv[0]));  #endif  	return make_reg(s->sys_strings_segment, SYS_STRING_SAVEDIR); diff --git a/engines/sci/engine/kgraphics.cpp b/engines/sci/engine/kgraphics.cpp index 0a836f581d..e5ca2d8fb4 100644 --- a/engines/sci/engine/kgraphics.cpp +++ b/engines/sci/engine/kgraphics.cpp @@ -292,7 +292,7 @@ reg_t kGraph(EngineState *s, int argc, reg_t *argv) {  		break;  	default: -		error("Unsupported kGraph() operation %04x", argv[0].toSint16()); +		warning("Unsupported kGraph() operation %04x", argv[0].toSint16());  	}  #ifdef INCLUDE_OLDGFX diff --git a/engines/sci/engine/kscripts.cpp b/engines/sci/engine/kscripts.cpp index 52e66e7fb5..51fe7b887c 100644 --- a/engines/sci/engine/kscripts.cpp +++ b/engines/sci/engine/kscripts.cpp @@ -225,7 +225,8 @@ reg_t kDisposeScript(EngineState *s, int argc, reg_t *argv) {  	if (argc != 2) {  		return s->r_acc;  	} else { -		// This exists in the KQ5CD interpreter, but a test case hasn't been found yet +		// This exists in the KQ5CD and GK1 interpreter. We know it is used when GK1 starts +		// up, before the Sierra logo.  		warning("kDisposeScript called with 2 parameters, still untested");  		return argv[1];  	} diff --git a/engines/sci/engine/script.cpp b/engines/sci/engine/script.cpp index 7bd8402663..0bab7f31ae 100644 --- a/engines/sci/engine/script.cpp +++ b/engines/sci/engine/script.cpp @@ -237,6 +237,10 @@ void Kernel::mapSelectors() {  	FIND_SELECTOR(topString);  	FIND_SELECTOR(scaleX);  	FIND_SELECTOR(scaleY); + +#ifdef ENABLE_SCI32 +	FIND_SELECTOR(data); +#endif  }  void Kernel::dumpScriptObject(char *data, int seeker, int objsize) { diff --git a/engines/sci/engine/seg_manager.cpp b/engines/sci/engine/seg_manager.cpp index 79f2e88f9e..5db6b88136 100644 --- a/engines/sci/engine/seg_manager.cpp +++ b/engines/sci/engine/seg_manager.cpp @@ -53,6 +53,11 @@ SegManager::SegManager(ResourceManager *resMan) {  	Lists_seg_id = 0;  	Nodes_seg_id = 0;  	Hunks_seg_id = 0; +	 +#ifdef ENABLE_SCI32 +	Arrays_seg_id = 0; +	String_seg_id = 0; +#endif  	_exportsAreWide = false;  	_resMan = resMan; @@ -1250,4 +1255,85 @@ void SegManager::createClassTable() {  	_resMan->unlockResource(vocab996);  } +#ifdef ENABLE_SCI32 +SciArray<reg_t> *SegManager::allocateArray(reg_t *addr) { +	ArrayTable *table; +	int offset; + +	if (!Arrays_seg_id) { +		table = (ArrayTable *)allocSegment(new ArrayTable(), &(Arrays_seg_id)); +	} else +		table = (ArrayTable *)_heap[Arrays_seg_id]; + +	offset = table->allocEntry(); + +	*addr = make_reg(Arrays_seg_id, offset); +	return &(table->_table[offset]); +} + +SciArray<reg_t> *SegManager::lookupArray(reg_t addr) { +	if (_heap[addr.segment]->getType() != SEG_TYPE_ARRAY) +		error("Attempt to use non-array %04x:%04x as array", PRINT_REG(addr)); + +	ArrayTable *arrayTable = (ArrayTable *)_heap[addr.segment]; + +	if (!arrayTable->isValidEntry(addr.offset)) +		error("Attempt to use non-array %04x:%04x as array", PRINT_REG(addr)); + +	return &(arrayTable->_table[addr.offset]); +} + +void SegManager::freeArray(reg_t addr) { +	if (_heap[addr.segment]->getType() != SEG_TYPE_ARRAY) +		error("Attempt to use non-array %04x:%04x as array", PRINT_REG(addr)); + +	ArrayTable *arrayTable = (ArrayTable *)_heap[addr.segment]; + +	if (!arrayTable->isValidEntry(addr.offset)) +		error("Attempt to use non-array %04x:%04x as array", PRINT_REG(addr)); + +	arrayTable->freeEntry(addr.offset); +} + +SciString *SegManager::allocateString(reg_t *addr) { +	StringTable *table; +	int offset; + +	if (!String_seg_id) { +		table = (StringTable *)allocSegment(new StringTable(), &(String_seg_id)); +	} else +		table = (StringTable *)_heap[String_seg_id]; + +	offset = table->allocEntry(); + +	*addr = make_reg(String_seg_id, offset); +	return &(table->_table[offset]); +} + +SciString *SegManager::lookupString(reg_t addr) { +	if (_heap[addr.segment]->getType() != SEG_TYPE_STRING) +		error("Attempt to use non-string %04x:%04x as string", PRINT_REG(addr)); + +	StringTable *stringTable = (StringTable *)_heap[addr.segment]; + +	if (!stringTable->isValidEntry(addr.offset)) +		error("Attempt to use non-string %04x:%04x as string", PRINT_REG(addr)); + +	return &(stringTable->_table[addr.offset]); +} + +void SegManager::freeString(reg_t addr) { +	if (_heap[addr.segment]->getType() != SEG_TYPE_STRING) +		error("Attempt to use non-string %04x:%04x as string", PRINT_REG(addr)); + +	StringTable *stringTable = (StringTable *)_heap[addr.segment]; + +	if (!stringTable->isValidEntry(addr.offset)) +		error("Attempt to use non-string %04x:%04x as string", PRINT_REG(addr)); + +	stringTable->freeEntry(addr.offset); +} + +#endif +  } // End of namespace Sci diff --git a/engines/sci/engine/seg_manager.h b/engines/sci/engine/seg_manager.h index 2e785b1341..4d385e0d32 100644 --- a/engines/sci/engine/seg_manager.h +++ b/engines/sci/engine/seg_manager.h @@ -440,6 +440,16 @@ public:  public: // TODO: make private  	Common::Array<SegmentObj *> _heap;  	Common::Array<Class> _classtable; /**< Table of all classes */ +	 +#ifdef ENABLE_SCI32 +	SciArray<reg_t> *allocateArray(reg_t *addr); +	SciArray<reg_t> *lookupArray(reg_t addr); +	void freeArray(reg_t addr); +	SciString *allocateString(reg_t *addr); +	SciString *lookupString(reg_t addr); +	void freeString(reg_t addr); +	SegmentId getStringSegmentId() { return String_seg_id; } +#endif  private:  	/** Map script ids to segment ids. */ @@ -454,6 +464,11 @@ private:  	SegmentId Nodes_seg_id; ///< ID of the (a) node segment  	SegmentId Hunks_seg_id; ///< ID of the (a) hunk segment +#ifdef ENABLE_SCI32 +	SegmentId Arrays_seg_id; +	SegmentId String_seg_id; +#endif +  private:  	SegmentObj *allocSegment(SegmentObj *mem, SegmentId *segid);  	LocalVariables *allocLocalsSegment(Script *scr, int count); diff --git a/engines/sci/engine/segment.cpp b/engines/sci/engine/segment.cpp index fee8a9f4a7..e8b47727ba 100644 --- a/engines/sci/engine/segment.cpp +++ b/engines/sci/engine/segment.cpp @@ -66,6 +66,14 @@ SegmentObj *SegmentObj::createSegmentObj(SegmentType type) {  	case SEG_TYPE_DYNMEM:  		mem = new DynMem();  		break; +#ifdef ENABLE_SCI32 +	case SEG_TYPE_ARRAY: +		mem = new ArrayTable(); +		break; +	case SEG_TYPE_STRING: +		mem = new StringTable(); +		break; +#endif  	default:  		error("Unknown SegmentObj type %d", type);  		break; @@ -478,5 +486,38 @@ void DynMem::listAllDeallocatable(SegmentId segId, void *param, NoteCallback not  	(*note)(param, make_reg(segId, 0));  } +#ifdef ENABLE_SCI32 + +Common::String SciString::toString() { +	if (_type != 3) +		error("SciString::toString(): Array is not a string"); + +	Common::String string; +	for (uint32 i = 0; i < _size && _data[i] != 0; i++) +		string += _data[i]; + +	return string; +} + +void SciString::fromString(Common::String string) { +	if (_type != 3) +		error("SciString::fromString(): Array is not a string"); + +	if (string.size() > _size) +		setSize(string.size()); +		 +	for (uint32 i = 0; i < string.size(); i++) +		_data[i] = string[i]; +} + +SegmentRef StringTable::dereference(reg_t pointer) { +	SegmentRef ret; +	ret.isRaw = false; +	ret.maxSize = _table[pointer.offset].getSize(); +	ret.raw = (byte*)_table[pointer.offset].getRawData(); +	return ret; +} + +#endif  } // End of namespace Sci diff --git a/engines/sci/engine/segment.h b/engines/sci/engine/segment.h index 7266dc3b38..a6ffeb773a 100644 --- a/engines/sci/engine/segment.h +++ b/engines/sci/engine/segment.h @@ -63,6 +63,11 @@ enum SegmentType {  	SEG_TYPE_HUNK = 8,  	SEG_TYPE_DYNMEM = 9,  	SEG_TYPE_STRING_FRAG = 10,	// obsolete, we keep it to be able to load old saves +	 +#ifdef ENABLE_SCI32 +	SEG_TYPE_ARRAY = 11, +	SEG_TYPE_STRING = 12, +#endif  	SEG_TYPE_MAX // For sanity checking  }; @@ -659,6 +664,112 @@ public:  	virtual void saveLoadWithSerializer(Common::Serializer &ser);  }; +#ifdef ENABLE_SCI32 + +template <typename T> +class SciArray { +public: +	SciArray() { +		_type = -1; +		_data = NULL; +		_size = 0; +		_actualSize = 0; +	} + +	~SciArray() { +		delete[] _data; +	} + +	void setType(byte type) { +		if (_type >= 0) +			error("SciArray::setType(): Type already set"); + +		_type = type; +	} +	 +	void setSize(uint32 size) { +		if (_type < 0) +			error("SciArray::setSize(): No type set"); + +		// Check if we don't have to do anything +		if (_size == size) +			return; + +		// Check if we don't have to expand the array +		if (size <= _actualSize) { +			_size = size; +			return; +		} + +		// So, we're going to have to create an array of some sort +		T *newArray = new T[size]; + +		// Check if we never created an array before +		if (!_data) { +			_data = newArray; +			return; +		} + +		// Copy data from the old array to the new +		memcpy(newArray, _data, _size * sizeof(T)); + +		// Now set the new array to the old and set the sizes +		delete[] _data; +		_data = newArray; +		_size = _actualSize = size; +	} +	 +	T getValue(uint16 index) { +		if (index >= _size) +			error("SciArray::getValue(): %d is out of bounds (%d)", index, _size); + +		return _data[index]; +	} +	 +	void setValue(uint16 index, T value) { +		if (index >= _size) +			error("SciArray::setValue(): %d is out of bounds (%d)", index, _size); + +		_data[index] = value; +	} +	 +	byte getType() { return _type; } +	uint32 getSize() { return _size; } +	T *getRawData() { return _data; } +	 +	//Common::String toString(); +	//void fromString(Common::String string); + +protected: +	int8 _type; +	T *_data; +	uint32 _size; // _size holds the number of entries that the scripts have requested +	uint32 _actualSize; // _actualSize is the actual numbers of entries allocated +}; + +class SciString : public SciArray<char> { +public: +	SciString() : SciArray<char>() {} +	 +	Common::String toString(); +	void fromString(Common::String string); +}; + +struct ArrayTable : public Table<SciArray<reg_t> > { +	ArrayTable() : Table<SciArray<reg_t> >(SEG_TYPE_ARRAY) {} + +	virtual void saveLoadWithSerializer(Common::Serializer &ser) {} +}; + +struct StringTable : public Table<SciString> { +	StringTable() : Table<SciString>(SEG_TYPE_STRING) {} + +	virtual void saveLoadWithSerializer(Common::Serializer &ser) {} +	SegmentRef dereference(reg_t pointer); +}; + +#endif +  } // End of namespace Sci diff --git a/engines/sci/engine/vm.h b/engines/sci/engine/vm.h index def56cbcb9..25bca2148c 100644 --- a/engines/sci/engine/vm.h +++ b/engines/sci/engine/vm.h @@ -195,6 +195,10 @@ struct SelectorCache {  	// Used for auto detection purposes  	Selector overlay;	///< Used to determine if a game is using old gfx functions or not  	Selector setCursor; ///< For cursor semantics autodetection +	 +#ifdef ENABLE_SCI32 +	Selector data; // Used by Array() +#endif  };  // A reference to an object's variable. diff --git a/engines/sci/gui/gui_dummy.h b/engines/sci/gui/gui_dummy.h new file mode 100644 index 0000000000..6ba5a8c8de --- /dev/null +++ b/engines/sci/gui/gui_dummy.h @@ -0,0 +1,55 @@ +/* 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_GUI_DUMMY_H +#define SCI_GUI_DUMMY_H + +#include "sci/gui/gui.h" + +namespace Sci { + +class SciGuiDummy : public SciGui { +public: +	SciGuiDummy(EngineState *s, SciGuiScreen *screen, SciGuiPalette *palette, SciGuiCursor *cursor) : SciGui(s, screen, palette, cursor) {} +	virtual ~SciGuiDummy() {} + +	virtual uint16 onControl(byte screenMask, Common::Rect rect) { return 0; } +	virtual void animate(reg_t listReference, bool cycle, int argc, reg_t *argv) {} +	virtual void addToPicList(reg_t listReference, int argc, reg_t *argv) {} +	virtual void addToPicView(GuiResourceId viewId, GuiViewLoopNo loopNo, GuiViewCelNo celNo, int16 leftPos, int16 topPos, int16 priority, int16 control) {} +	virtual void setNowSeen(reg_t objectReference) {} +	virtual bool canBeHere(reg_t curObject, reg_t listReference) { return false; } +	virtual bool isItSkip(GuiResourceId viewId, int16 loopNo, int16 celNo, Common::Point position) { return false; } +	virtual void baseSetter(reg_t object) {} + +	virtual int16 getCelWidth(GuiResourceId viewId, int16 loopNo, int16 celNo) { return 0; } +	virtual int16 getCelHeight(GuiResourceId viewId, int16 loopNo, int16 celNo) { return 0; } +	virtual int16 getLoopCount(GuiResourceId viewId) { return 0; } +	virtual int16 getCelCount(GuiResourceId viewId, int16 loopNo) { return 0; } +}; + +} // End of namespace Sci + +#endif diff --git a/engines/sci/sci.cpp b/engines/sci/sci.cpp index 5daa8e2e23..c9e33ac85f 100644 --- a/engines/sci/sci.cpp +++ b/engines/sci/sci.cpp @@ -44,6 +44,9 @@  #include "sci/sfx/audio.h"  #include "sci/sfx/soundcmd.h"  #include "sci/gui/gui.h" +#ifdef ENABLE_SCI32 +#include "sci/gui/gui_dummy.h" +#endif  #include "sci/gui/gui_palette.h"  #include "sci/gui/gui_cursor.h"  #include "sci/gui/gui_screen.h" @@ -114,11 +117,12 @@ Common::Error SciEngine::run() {  		return Common::kNoGameDataFoundError;  	} -	bool upscaledHires = false; -  	// Scale the screen, if needed -	if (!strcmp(getGameID(), "kq6") && getPlatform() == Common::kPlatformWindows) -		upscaledHires = true; +	bool upscaledHires = (!strcmp(getGameID(), "kq6")  +#ifdef ENABLE_SCI32 +							|| getSciVersion() >= SCI_VERSION_2 +#endif +							) && getPlatform() == Common::kPlatformWindows;  	// TODO: Detect japanese editions and set upscaledHires on those as well  	// TODO: Possibly look at first picture resource and determine if its hires or not @@ -144,6 +148,12 @@ Common::Error SciEngine::run() {  	if (script_init_engine(_gamestate))  		return Common::kUnknownError; +#ifdef ENABLE_SCI32 +	if (getSciVersion() >= SCI_VERSION_2) { +		// Falsify the Views with a Dummy GUI +		_gamestate->_gui = new SciGuiDummy(_gamestate, screen, palette, cursor); +	} else { +#endif  #ifdef INCLUDE_OLDGFX  	#ifndef USE_OLDGFX  		_gamestate->_gui = new SciGui(_gamestate, screen, palette, cursor);    // new @@ -151,7 +161,10 @@ Common::Error SciEngine::run() {  		_gamestate->_gui = new SciGui32(_gamestate, screen, palette, cursor);  // old  	#endif  #else -	_gamestate->_gui = new SciGui(_gamestate, screen, palette, cursor); +		_gamestate->_gui = new SciGui(_gamestate, screen, palette, cursor); +#endif +#ifdef ENABLE_SCI32 +	}  #endif  	if (game_init(_gamestate)) { /* Initialize */ | 
