diff options
| -rw-r--r-- | engines/sci/engine/kernel.cpp | 1 | ||||
| -rw-r--r-- | engines/sci/engine/kernel.h | 1 | ||||
| -rw-r--r-- | engines/sci/engine/kernel32.cpp | 69 | 
3 files changed, 58 insertions, 13 deletions
diff --git a/engines/sci/engine/kernel.cpp b/engines/sci/engine/kernel.cpp index 1a56c44c74..1a2fdc03c3 100644 --- a/engines/sci/engine/kernel.cpp +++ b/engines/sci/engine/kernel.cpp @@ -341,6 +341,7 @@ SciKernelFunction kfunct_mappers[] = {  	// SCI2 Kernel Functions  	DEFUN("IsHiRes", kIsHiRes, ""),  	DEFUN("Array", kArray, ".*"), +	DEFUN("ListAt", kListAt, ".*"),  	DEFUN("String", kString, ".*"),  	DEFUN("AddScreenItem", kAddScreenItem, "o"),  	DEFUN("UpdateScreenItem", kUpdateScreenItem, "o"), diff --git a/engines/sci/engine/kernel.h b/engines/sci/engine/kernel.h index 0af34345e7..75276c9228 100644 --- a/engines/sci/engine/kernel.h +++ b/engines/sci/engine/kernel.h @@ -394,6 +394,7 @@ reg_t kTextFonts(EngineState *s, int argc, reg_t *argv);  // 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 kListAt(EngineState *s, int argc, reg_t *argv);  reg_t kString(EngineState *s, int argc, reg_t *argv);  // "Screen items" in SCI32 are views  reg_t kAddScreenItem(EngineState *s, int argc, reg_t *argv); diff --git a/engines/sci/engine/kernel32.cpp b/engines/sci/engine/kernel32.cpp index a59bf4e22f..b6c86e826a 100644 --- a/engines/sci/engine/kernel32.cpp +++ b/engines/sci/engine/kernel32.cpp @@ -456,6 +456,34 @@ reg_t kArray(EngineState *s, int argc, reg_t *argv) {  	return NULL_REG;  } +reg_t kListAt(EngineState *s, int argc, reg_t *argv) { +	if (argc != 2) { +		warning("kListAt called with %d parameters", argc); +		return NULL_REG; +	} + +	List *list = s->_segMan->lookupList(argv[0]); +	reg_t curAddress = list->first; +	Node *curNode = s->_segMan->lookupNode(curAddress); +	reg_t curObject = curNode->value; +	int16 listIndex = argv[1].toUint16(); +	int curIndex = 0; + +	while (curIndex != listIndex) { +		if (curNode->succ.isNull()) {	// end of the list? +			return NULL_REG; +		} + +		curAddress = curNode->succ; +		curNode = s->_segMan->lookupNode(curAddress); +		curObject = curNode->value; + +		curIndex++; +	} + +	return curObject; +} +  reg_t kString(EngineState *s, int argc, reg_t *argv) {	  	switch (argv[0].toUint16()) {  	case 0: { // New @@ -695,22 +723,37 @@ reg_t kFrameOut(EngineState *s, int argc, reg_t *argv) {  }  reg_t kListEachElementDo(EngineState *s, int argc, reg_t *argv) { +	List *list = s->_segMan->lookupList(argv[0]); + +	reg_t curAddress = list->first; +	Node *curNode = s->_segMan->lookupNode(curAddress); +	reg_t curObject; + +	while (curNode) { +		curObject = curNode->value; + +		// FIXME: Yes, this is an ugly hack... +		if (argc == 2) { +			invoke_selector(s, curObject, argv[1].toUint16(), kContinueOnInvalidSelector, argv, argc, 0); +		} else if (argc == 3) { +			invoke_selector(s, curObject, argv[1].toUint16(), kContinueOnInvalidSelector, argv, argc, 1, argv[2]); +		} else if (argc == 4) { +			invoke_selector(s, curObject, argv[1].toUint16(), kContinueOnInvalidSelector, argv, argc, 2, argv[2], argv[3]); +		} else if (argc == 5) { +			invoke_selector(s, curObject, argv[1].toUint16(), kContinueOnInvalidSelector, argv, argc, 3, argv[2], argv[3], argv[4]); +		} else { +			warning("kListEachElementDo: called with %d params", argc); +		} -	// Called with 2 or 3 parameters -	// object, selector and optionally a third unknown parameter - -	// With 2 parameters, the selector can be: -	// - 0x45 (doit) -	// - 0x5c (delete) -	// - 0xfd (check) +		// Lookup node again, since the nodetable it was in may have been reallocated +		curNode = s->_segMan->lookupNode(curAddress); -	// With 3 parameters, the selector can be: -	// - 0x145 (checkDetail) -	// - 0x211 (newRoom) - that one seems a bit odd +		curAddress = curNode->succ; +		curNode = s->_segMan->lookupNode(curAddress); +	} -	// TODO -	return NULL_REG; +	return s->r_acc;  }  reg_t kOnMe(EngineState *s, int argc, reg_t *argv) { @@ -720,7 +763,7 @@ reg_t kOnMe(EngineState *s, int argc, reg_t *argv) {  	// TODO  	warning("kOnMe: (%d, %d) on object %04x:%04x", argv[0].toUint16(), argv[1].toUint16(), PRINT_REG(argv[2])); -	return NULL_REG; +	return s->r_acc;  }  } // End of namespace Sci  | 
