aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--engines/sci/engine/kernel.cpp1
-rw-r--r--engines/sci/engine/kernel.h1
-rw-r--r--engines/sci/engine/kernel32.cpp69
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