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

m_kiewitz at users.sourceforge.net m_kiewitz at users.sourceforge.net
Mon Jul 5 16:36:32 CEST 2010


Revision: 50678
          http://scummvm.svn.sourceforge.net/scummvm/?rev=50678&view=rev
Author:   m_kiewitz
Date:     2010-07-05 14:36:31 +0000 (Mon, 05 Jul 2010)

Log Message:
-----------
SCI: implemented new kernel call signature format

Modified Paths:
--------------
    scummvm/trunk/engines/sci/console.cpp
    scummvm/trunk/engines/sci/engine/kernel.cpp
    scummvm/trunk/engines/sci/engine/kernel.h

Modified: scummvm/trunk/engines/sci/console.cpp
===================================================================
--- scummvm/trunk/engines/sci/console.cpp	2010-07-05 13:06:58 UTC (rev 50677)
+++ scummvm/trunk/engines/sci/console.cpp	2010-07-05 14:36:31 UTC (rev 50678)
@@ -2042,18 +2042,18 @@
 	int t = g_sci->getKernel()->findRegType(val);
 
 	switch (t) {
-	case KSIG_LIST:
+	case SIG_TYPE_LIST:
 		DebugPrintf("List");
 		break;
-	case KSIG_OBJECT:
+	case SIG_TYPE_OBJECT:
 		DebugPrintf("Object");
 		break;
-	case KSIG_REF:
+	case SIG_TYPE_REFERENCE:
 		DebugPrintf("Reference");
 		break;
-	case KSIG_ARITHMETIC:
-		DebugPrintf("Arithmetic");
-	case KSIG_ARITHMETIC | KSIG_NULL:
+	case SIG_TYPE_INTEGER:
+		DebugPrintf("Integer");
+	case SIG_TYPE_INTEGER | SIG_TYPE_NULL:
 		DebugPrintf("Null");
 		break;
 	default:
@@ -2137,7 +2137,7 @@
 		switch (type) {
 		case 0:
 			break;
-		case KSIG_LIST: {
+		case SIG_TYPE_LIST: {
 			List *list = _engine->_gamestate->_segMan->lookupList(reg);
 
 			DebugPrintf("list\n");
@@ -2148,15 +2148,15 @@
 				DebugPrintf("Invalid list.\n");
 		}
 			break;
-		case KSIG_NODE:
+		case SIG_TYPE_NODE:
 			DebugPrintf("list node\n");
 			printNode(reg);
 			break;
-		case KSIG_OBJECT:
+		case SIG_TYPE_OBJECT:
 			DebugPrintf("object\n");
 			printObject(reg);
 			break;
-		case KSIG_REF: {
+		case SIG_TYPE_REFERENCE: {
 			switch (_engine->_gamestate->_segMan->getSegmentType(reg.segment)) {
 #ifdef ENABLE_SCI32
 				case SEG_TYPE_STRING: {
@@ -2198,7 +2198,7 @@
 			}
 			break;
 		}
-		case KSIG_ARITHMETIC:
+		case SIG_TYPE_INTEGER:
 			DebugPrintf("arithmetic value\n  %d (%04x)\n", (int16) reg.offset, reg.offset);
 			break;
 		default:
@@ -3149,27 +3149,30 @@
 	int segType = g_sci->getKernel()->findRegType(variable);
 	SegManager *segMan = g_sci->getEngineState()->_segMan;
 
-	segType &= KSIG_ARITHMETIC | KSIG_OBJECT | KSIG_REF | KSIG_NODE | KSIG_LIST;
+	segType &= SIG_TYPE_INTEGER | SIG_TYPE_OBJECT | SIG_TYPE_REFERENCE | SIG_TYPE_NODE | SIG_TYPE_LIST | SIG_TYPE_UNINITIALIZED;
 
 	switch (segType) {
-	case KSIG_ARITHMETIC: {
+	case SIG_TYPE_INTEGER: {
 		uint16 content = variable.toUint16();
 		if (content >= 10)
 			DebugPrintf(" (%dd)", content);
 		break;
 	}
-	case KSIG_OBJECT:
+	case SIG_TYPE_OBJECT:
 		DebugPrintf(" (object '%s')", segMan->getObjectName(variable));
 		break;
-	case KSIG_REF:
+	case SIG_TYPE_REFERENCE:
 		DebugPrintf(" (reference)");
 		break;
-	case KSIG_NODE:
+	case SIG_TYPE_NODE:
 		DebugPrintf(" (node)");
 		break;
-	case KSIG_LIST:
+	case SIG_TYPE_LIST:
 		DebugPrintf(" (list)");
 		break;
+	case SIG_TYPE_UNINITIALIZED:
+		DebugPrintf(" (uninitialized)");
+		break;
 	default:
 		DebugPrintf(" (??\?)");
 	}

Modified: scummvm/trunk/engines/sci/engine/kernel.cpp
===================================================================
--- scummvm/trunk/engines/sci/engine/kernel.cpp	2010-07-05 13:06:58 UTC (rev 50677)
+++ scummvm/trunk/engines/sci/engine/kernel.cpp	2010-07-05 14:36:31 UTC (rev 50678)
@@ -206,7 +206,7 @@
 // i* -> optional multiple integers
 // .* -> any parameters afterwards (or none)
 
-//    gameID,       scriptNr,lvl,         object-name, method-name,    call,index,replace
+//    gameID,       scriptNr,lvl,         object-name, method-name,    call, index,   replace
 static const SciWorkaroundEntry kDisposeScript_workarounds[] = {
 	{ GID_QFG1,           64,  0,               "rm64", "dispose",        -1,    0, { 1,    0 } }, // parameter 0 is an object when leaving graveyard
 	SCI_WORKAROUNDENTRY_TERMINATOR
@@ -226,6 +226,8 @@
 };
 
 #define SIG_SCIALL  SCI_VERSION_NONE, SCI_VERSION_NONE
+#define SIG_SCI0    SCI_VERSION_NONE, SCI_VERSION_01
+#define SIG_SCI1    SCI_VERSION_1_EGA, SCI_VERSION_1_LATE
 #define SIG_SCI11   SCI_VERSION_1_1, SCI_VERSION_1_1
 #define SIG_SCI16    SCI_VERSION_NONE, SCI_VERSION_1_1
 #define SIG_SCI32    SCI_VERSION_2, SCI_VERSION_NONE
@@ -245,129 +247,133 @@
 
 //    name,                        version/platform,         signature,              sub-signatures,  workarounds
 static SciKernelMapEntry s_kernelMap[] = {
-    { MAP_CALL(Load),              SIG_EVERYWHERE,           "iii*",                 NULL,            NULL },
-    { MAP_CALL(UnLoad),            SIG_EVERYWHERE,           "iRi*",                 NULL,            NULL },
+    { MAP_CALL(Load),              SIG_EVERYWHERE,           "ii(i*)",               NULL,            NULL },
+    { MAP_CALL(UnLoad),            SIG_EVERYWHERE,           "i[ri]",                NULL,            NULL },
 	//  ^^ - in SQ1 when leaving ulence flats bar, kUnLoad is called with just one argument (FIXME?)
-    { MAP_CALL(ScriptID),          SIG_EVERYWHERE,           "Ioi*",                 NULL,            NULL },
-    { MAP_CALL(DisposeScript),     SIG_EVERYWHERE,           "ii*",                  NULL,            kDisposeScript_workarounds },
+    { MAP_CALL(ScriptID),          SIG_EVERYWHERE,           "[io](i)",              NULL,            NULL },
+    { MAP_CALL(DisposeScript),     SIG_EVERYWHERE,           "i(i*)",                NULL,            kDisposeScript_workarounds },
     { MAP_CALL(Clone),             SIG_EVERYWHERE,           "o",                    NULL,            NULL },
     { MAP_CALL(DisposeClone),      SIG_EVERYWHERE,           "o",                    NULL,            NULL },
     { MAP_CALL(IsObject),          SIG_EVERYWHERE,           ".",                    NULL,            NULL },
     { MAP_CALL(RespondsTo),        SIG_EVERYWHERE,           ".i",                   NULL,            NULL },
-    { MAP_CALL(DrawPic),           SIG_EVERYWHERE,           "i*",                   NULL,            NULL },
-    { MAP_CALL(PicNotValid),       SIG_EVERYWHERE,           "i*",                   NULL,            NULL },
-    { MAP_CALL(Animate),           SIG_EVERYWHERE,           "LI*",                  NULL,            NULL },
-	// ^^ FIXME - More like (li?)?
-    { MAP_CALL(SetNowSeen),        SIG_EVERYWHERE,           "oi*",                  NULL,            NULL },
-	// ^^ FIXME - The second parameter is ignored
+    { MAP_CALL(DrawPic),           SIG_EVERYWHERE,           "i(i)(i)(i)",           NULL,            NULL },
+    { MAP_CALL(PicNotValid),       SIG_EVERYWHERE,           "(i)",                  NULL,            NULL },
+    { MAP_CALL(Animate),           SIG_EVERYWHERE,           "(l0)(i)",              NULL,            NULL },
+    { MAP_CALL(SetNowSeen),        SIG_EVERYWHERE,           "o(i)",                 NULL,            NULL },
     { MAP_CALL(NumLoops),          SIG_EVERYWHERE,           "o",                    NULL,            NULL },
     { MAP_CALL(NumCels),           SIG_EVERYWHERE,           "o",                    NULL,            NULL },
-    { MAP_CALL(CelWide),           SIG_EVERYWHERE,           "iOi*",                 NULL,            NULL },
-    { MAP_CALL(CelHigh),           SIG_EVERYWHERE,           "iOi*",                 NULL,            NULL },
-    { MAP_CALL(DrawCel),           SIG_SCI11, SIGFOR_PC,     "iiiiii*i*r*",          NULL,            NULL },
-    { MAP_CALL(DrawCel),           SIG_EVERYWHERE,           "iiiiii*i*",            NULL,            NULL },
-    { MAP_CALL(AddToPic),          SIG_EVERYWHERE,           "Il*",                  NULL,            NULL },
-    { MAP_CALL(NewWindow),         SIG_SCIALL, SIGFOR_MAC,   "*.",                   NULL,            NULL },
-    { MAP_CALL(NewWindow),         SIG_EVERYWHERE,           "iiiiZRi*",             NULL,            NULL },
+    { MAP_CALL(CelWide),           SIG_EVERYWHERE,           "ii(i)",                NULL,            NULL },
+    { MAP_CALL(CelHigh),           SIG_EVERYWHERE,           "ii(i)",                NULL,            NULL },
+    { MAP_CALL(DrawCel),           SIG_SCI11, SIGFOR_PC,     "iiiii(i)(i)(r)",       NULL,            NULL },
+    { MAP_CALL(DrawCel),           SIG_EVERYWHERE,           "iiiii(i)(i)",          NULL,            NULL },
+    { MAP_CALL(AddToPic),          SIG_EVERYWHERE,           "[il](iiiiii)",         NULL,            NULL },
+    { MAP_CALL(NewWindow),         SIG_SCIALL, SIGFOR_MAC,   ".*",                   NULL,            NULL },
+    { MAP_CALL(NewWindow),         SIG_SCI0, SIGFOR_ALL,     "iiii[r0]i(i)(i)(i)",   NULL,            NULL },
+    { MAP_CALL(NewWindow),         SIG_SCI1, SIGFOR_ALL,     "iiii[ir]i(i)(i)([ir])(i)(i)(i)(i)", NULL, NULL },
+    { MAP_CALL(NewWindow),         SIG_SCI11, SIGFOR_ALL,    "iiiiiiii[r0]i(i)(i)(i)", NULL,          NULL },
     { MAP_CALL(GetPort),           SIG_EVERYWHERE,           "",                     NULL,            NULL },
-    { MAP_CALL(SetPort),           SIG_EVERYWHERE,           "ii*",                  NULL,            NULL },
-    { MAP_CALL(DisposeWindow),     SIG_EVERYWHERE,           "ii*",                  NULL,            NULL },
+    { MAP_CALL(SetPort),           SIG_EVERYWHERE,           "i(iii)(i)(i)(i)",      NULL,            NULL },
+    { MAP_CALL(DisposeWindow),     SIG_EVERYWHERE,           "i(i)",                 NULL,            NULL },
     { MAP_CALL(DrawControl),       SIG_EVERYWHERE,           "o",                    NULL,            NULL },
     { MAP_CALL(HiliteControl),     SIG_EVERYWHERE,           "o",                    NULL,            NULL },
-    { MAP_CALL(EditControl),       SIG_EVERYWHERE,           "ZoZo",                 NULL,            NULL },
-    { MAP_CALL(TextSize),          SIG_EVERYWHERE,           "rZrii*r*",             NULL,            NULL },
-    { MAP_CALL(Display),           SIG_EVERYWHERE,           ".*",                   NULL,            NULL },
-    { MAP_CALL(GetEvent),          SIG_SCIALL, SIGFOR_MAC,   "ioi*",                 NULL,            NULL },
+    { MAP_CALL(EditControl),       SIG_EVERYWHERE,           "[o0][o0]",             NULL,            NULL },
+    { MAP_CALL(TextSize),          SIG_EVERYWHERE,           "r[r0]i(i)(r0)",        NULL,            NULL },
+    { MAP_CALL(Display),           SIG_EVERYWHERE,           "[ir]([ir]*)",          NULL,            NULL }, // subop
+    { MAP_CALL(GetEvent),          SIG_SCIALL, SIGFOR_MAC,   "io(i*)",               NULL,            NULL },
     { MAP_CALL(GetEvent),          SIG_EVERYWHERE,           "io",                   NULL,            NULL },
-    { MAP_CALL(GlobalToLocal),     SIG_EVERYWHERE,           "oo*",                  NULL,            NULL },
-    { MAP_CALL(LocalToGlobal),     SIG_EVERYWHERE,           "oo*",                  NULL,            NULL },
+    { MAP_CALL(GlobalToLocal),     SIG_SCI32, SIGFOR_ALL,    "oo",                   NULL,            NULL },
+    { MAP_CALL(GlobalToLocal),     SIG_EVERYWHERE,           "o",                    NULL,            NULL },
+    { MAP_CALL(LocalToGlobal),     SIG_SCI32, SIGFOR_ALL,    "oo",                   NULL,            NULL },
+    { MAP_CALL(LocalToGlobal),     SIG_EVERYWHERE,           "o",                    NULL,            NULL },
     { MAP_CALL(MapKeyToDir),       SIG_EVERYWHERE,           "o",                    NULL,            NULL },
     { MAP_CALL(DrawMenuBar),       SIG_EVERYWHERE,           "i",                    NULL,            NULL },
-    { MAP_CALL(MenuSelect),        SIG_EVERYWHERE,           "oi*",                  NULL,            NULL },
+    { MAP_CALL(MenuSelect),        SIG_EVERYWHERE,           "o(i)",                 NULL,            NULL },
     { MAP_CALL(AddMenu),           SIG_EVERYWHERE,           "rr",                   NULL,            NULL },
-    { MAP_CALL(DrawStatus),        SIG_EVERYWHERE,           "Zri*",                 NULL,            NULL },
+    { MAP_CALL(DrawStatus),        SIG_EVERYWHERE,           "[r0](i)(i)",           NULL,            NULL },
     { MAP_CALL(Parse),             SIG_EVERYWHERE,           "ro",                   NULL,            NULL },
-    { MAP_CALL(Said),              SIG_EVERYWHERE,           "Zr",                   NULL,            NULL },
+    { MAP_CALL(Said),              SIG_EVERYWHERE,           "[r0]",                 NULL,            NULL },
     { MAP_CALL(SetSynonyms),       SIG_EVERYWHERE,           "o",                    NULL,            NULL },
     { MAP_CALL(HaveMouse),         SIG_EVERYWHERE,           "",                     NULL,            NULL },
-    { MAP_CALL(SetCursor),         SIG_EVERYWHERE,           "i*",                   NULL,            NULL },
+    { MAP_CALL(SetCursor),         SIG_EVERYWHERE,           "i(i*)",                NULL,            NULL },
     { MAP_CALL(MoveCursor),        SIG_EVERYWHERE,           "ii",                   NULL,            NULL },
     { MAP_CALL(FOpen),             SIG_EVERYWHERE,           "ri",                   NULL,            NULL },
     { MAP_CALL(FPuts),             SIG_EVERYWHERE,           "ir",                   NULL,            NULL },
     { MAP_CALL(FGets),             SIG_EVERYWHERE,           "rii",                  NULL,            NULL },
     { MAP_CALL(FClose),            SIG_EVERYWHERE,           "i",                    NULL,            NULL },
-    { MAP_CALL(SaveGame),          SIG_EVERYWHERE,           "rirr*",                NULL,            NULL },
-    { MAP_CALL(RestoreGame),       SIG_EVERYWHERE,           "rir*",                 NULL,            NULL },
+    { MAP_CALL(SaveGame),          SIG_EVERYWHERE,           "rir(r)",               NULL,            NULL },
+    { MAP_CALL(RestoreGame),       SIG_EVERYWHERE,           "rir",                  NULL,            NULL },
     { MAP_CALL(RestartGame),       SIG_EVERYWHERE,           "",                     NULL,            NULL },
-    { MAP_CALL(GameIsRestarting),  SIG_EVERYWHERE,           "i*",                   NULL,            NULL },
-    { MAP_CALL(DoSound),           SIG_EVERYWHERE,           "iIo*",                 NULL,            NULL },
+    { MAP_CALL(GameIsRestarting),  SIG_EVERYWHERE,           "(i)",                  NULL,            NULL },
+    { MAP_CALL(DoSound),           SIG_EVERYWHERE,           "i([io])(i)(iii)(i)",   NULL,            NULL }, // subop
     { MAP_CALL(NewList),           SIG_EVERYWHERE,           "",                     NULL,            NULL },
     { MAP_CALL(DisposeList),       SIG_EVERYWHERE,           "l",                    NULL,            NULL },
     { MAP_CALL(NewNode),           SIG_EVERYWHERE,           "..",                   NULL,            NULL },
-    { MAP_CALL(FirstNode),         SIG_EVERYWHERE,           "Zl",                   NULL,            NULL },
+    { MAP_CALL(FirstNode),         SIG_EVERYWHERE,           "[l0]",                 NULL,            NULL },
     { MAP_CALL(LastNode),          SIG_EVERYWHERE,           "l",                    NULL,            NULL },
     { MAP_CALL(EmptyList),         SIG_EVERYWHERE,           "l",                    NULL,            NULL },
     { MAP_CALL(NextNode),          SIG_EVERYWHERE,           "n",                    NULL,            NULL },
     { MAP_CALL(PrevNode),          SIG_EVERYWHERE,           "n",                    NULL,            NULL },
-    { MAP_CALL(NodeValue),         SIG_EVERYWHERE,           "Zn",                   NULL,            NULL },
+    { MAP_CALL(NodeValue),         SIG_EVERYWHERE,           "[n0]",                 NULL,            NULL },
     { MAP_CALL(AddAfter),          SIG_EVERYWHERE,           "lnn",                  NULL,            NULL },
     { MAP_CALL(AddToFront),        SIG_EVERYWHERE,           "ln",                   NULL,            NULL },
     { MAP_CALL(AddToEnd),          SIG_EVERYWHERE,           "ln",                   NULL,            NULL },
     { MAP_CALL(FindKey),           SIG_EVERYWHERE,           "l.",                   NULL,            NULL },
     { MAP_CALL(DeleteKey),         SIG_EVERYWHERE,           "l.",                   NULL,            NULL },
-    { MAP_CALL(Random),            SIG_EVERYWHERE,           "i*",                   NULL,            NULL },
-    { MAP_CALL(Abs),               SIG_EVERYWHERE,           "Oi",                   NULL,            NULL },
+    { MAP_CALL(Random),            SIG_EVERYWHERE,           "ii",                   NULL,            NULL },
+    { MAP_CALL(Abs),               SIG_EVERYWHERE,           "[io]",                 NULL,            NULL },
+	//  ^^ FIXME hoyle
     { MAP_CALL(Sqrt),              SIG_EVERYWHERE,           "i",                    NULL,            NULL },
-    { MAP_CALL(GetAngle),          SIG_EVERYWHERE,           "iiiii*",               NULL,            NULL },
+    { MAP_CALL(GetAngle),          SIG_EVERYWHERE,           "iiii",                 NULL,            NULL },
 	 // ^^ FIXME - occasionally KQ6 passes a 5th argument by mistake
-    { MAP_CALL(GetDistance),       SIG_EVERYWHERE,           "iiiii*",               NULL,            NULL },
+    { MAP_CALL(GetDistance),       SIG_EVERYWHERE,           "ii(i)(i)(i)(i)",       NULL,            NULL },
     { MAP_CALL(Wait),              SIG_EVERYWHERE,           "i",                    NULL,            NULL },
-    { MAP_CALL(GetTime),           SIG_EVERYWHERE,           "i*",                   NULL,            NULL },
+    { MAP_CALL(GetTime),           SIG_EVERYWHERE,           "(i)",                  NULL,            NULL },
     { MAP_CALL(StrEnd),            SIG_EVERYWHERE,           "r",                    NULL,            NULL },
     { MAP_CALL(StrCat),            SIG_EVERYWHERE,           "rr",                   NULL,            NULL },
-    { MAP_CALL(StrCmp),            SIG_EVERYWHERE,           "rri*",                 NULL,            NULL },
-    { MAP_CALL(StrLen),            SIG_EVERYWHERE,           "Zr",                   NULL,            NULL },
-    { MAP_CALL(StrCpy),            SIG_EVERYWHERE,           "rZri*",                NULL,            NULL },
-    { MAP_CALL(Format),            SIG_EVERYWHERE,           "r.*",                  NULL,            NULL },
-    { MAP_CALL(GetFarText),        SIG_EVERYWHERE,           "iiZr",                 NULL,            NULL },
+    { MAP_CALL(StrCmp),            SIG_EVERYWHERE,           "rr(i)",                NULL,            NULL },
+    { MAP_CALL(StrLen),            SIG_EVERYWHERE,           "[r0]",                 NULL,            NULL },
+    { MAP_CALL(StrCpy),            SIG_EVERYWHERE,           "[r0]r(i)",             NULL,            NULL },
+    { MAP_CALL(Format),            SIG_EVERYWHERE,           "r(.*)",                NULL,            NULL },
+    { MAP_CALL(GetFarText),        SIG_EVERYWHERE,           "ii[r0]",               NULL,            NULL },
     { MAP_CALL(ReadNumber),        SIG_EVERYWHERE,           "r",                    NULL,            NULL },
     { MAP_CALL(BaseSetter),        SIG_EVERYWHERE,           "o",                    NULL,            NULL },
     { MAP_CALL(DirLoop),           SIG_EVERYWHERE,           "oi",                   NULL,            NULL },
-    { MAP_CALL(CanBeHere),         SIG_EVERYWHERE,           "ol*",                  NULL,            NULL },
-    { MAP_CALL(CantBeHere),        SIG_EVERYWHERE,           "ol*",                  NULL,            NULL },
-    { MAP_CALL(OnControl),         SIG_EVERYWHERE,           "i*",                   NULL,            NULL },
-    { MAP_CALL(InitBresen),        SIG_EVERYWHERE,           "oi*",                  NULL,            NULL },
+    { MAP_CALL(CanBeHere),         SIG_EVERYWHERE,           "o(l)",                 NULL,            NULL },
+    { MAP_CALL(CantBeHere),        SIG_EVERYWHERE,           "o(l)",                 NULL,            NULL },
+    { MAP_CALL(OnControl),         SIG_EVERYWHERE,           "ii(i)(i)(i)",          NULL,            NULL },
+    { MAP_CALL(InitBresen),        SIG_EVERYWHERE,           "o(i)",                 NULL,            NULL },
     { MAP_CALL(DoBresen),          SIG_EVERYWHERE,           "o",                    NULL,            NULL },
     { MAP_CALL(DoAvoider),         SIG_EVERYWHERE,           "o",                    NULL,            NULL },
     { MAP_CALL(SetJump),           SIG_EVERYWHERE,           "oiii",                 NULL,            NULL },
-    { MAP_CALL(SetDebug),          SIG_EVERYWHERE,           "i*",                   NULL,            NULL },
+    { MAP_CALL(SetDebug),          SIG_EVERYWHERE,           "(i*)",                 NULL,            NULL },
     { MAP_CALL(MemoryInfo),        SIG_EVERYWHERE,           "i",                    NULL,            NULL },
     { MAP_CALL(GetMenu),           SIG_EVERYWHERE,           "i.",                   NULL,            NULL },
-    { MAP_CALL(SetMenu),           SIG_EVERYWHERE,           "i.*",                  NULL,            NULL },
+    { MAP_CALL(SetMenu),           SIG_EVERYWHERE,           "i(.*)",                NULL,            NULL },
     { MAP_CALL(GetSaveFiles),      SIG_EVERYWHERE,           "rrr",                  NULL,            NULL },
     { MAP_CALL(GetCWD),            SIG_EVERYWHERE,           "r",                    NULL,            NULL },
-    { MAP_CALL(CheckFreeSpace),    SIG_EVERYWHERE,           "r.*",                  NULL,            NULL },
+    { MAP_CALL(CheckFreeSpace),    SIG_SCI32, SIGFOR_ALL,    "r.*",                  NULL,            NULL },
+    { MAP_CALL(CheckFreeSpace),    SIG_EVERYWHERE,           "r",                    NULL,            NULL },
     { MAP_CALL(ValidPath),         SIG_EVERYWHERE,           "r",                    NULL,            NULL },
-    { MAP_CALL(CoordPri),          SIG_EVERYWHERE,           "ii*",                  NULL,            NULL },
-    { MAP_CALL(StrAt),             SIG_EVERYWHERE,           "rii*",                 NULL,            NULL },
-    { MAP_CALL(DeviceInfo),        SIG_EVERYWHERE,           "i.*",                  NULL,            NULL },
-    { MAP_CALL(GetSaveDir),        SIG_SCI32, SIGFOR_ALL,    "r*",                   NULL,            NULL },
+    { MAP_CALL(CoordPri),          SIG_EVERYWHERE,           "i(i)",                 NULL,            NULL },
+    { MAP_CALL(StrAt),             SIG_EVERYWHERE,           "ri(i)",                NULL,            NULL },
+    { MAP_CALL(DeviceInfo),        SIG_EVERYWHERE,           "i(r)(r)(i)",           NULL,            NULL }, // subop
+    { MAP_CALL(GetSaveDir),        SIG_SCI32, SIGFOR_ALL,    "(r*)",                 NULL,            NULL },
     { MAP_CALL(GetSaveDir),        SIG_EVERYWHERE,           "",                     NULL,            NULL },
     { MAP_CALL(CheckSaveGame),     SIG_EVERYWHERE,           ".*",                   NULL,            NULL },
-    { MAP_CALL(ShakeScreen),       SIG_EVERYWHERE,           "ii*",                  NULL,            NULL },
+    { MAP_CALL(ShakeScreen),       SIG_EVERYWHERE,           "(i)(i)",               NULL,            NULL },
     { MAP_CALL(FlushResources),    SIG_EVERYWHERE,           "i",                    NULL,            NULL },
     { MAP_CALL(TimesSin),          SIG_EVERYWHERE,           "ii",                   NULL,            NULL },
     { MAP_CALL(TimesCos),          SIG_EVERYWHERE,           "ii",                   NULL,            NULL },
-    { MAP_CALL(Graph),             SIG_EVERYWHERE,           ".*",                   NULL,            NULL },
-    { MAP_CALL(Joystick),          SIG_EVERYWHERE,           ".*",                   NULL,            NULL },
-    { MAP_CALL(FileIO),            SIG_EVERYWHERE,           "i.*",                  NULL,            NULL },
-    { MAP_CALL(Memory),            SIG_EVERYWHERE,           "i.*",                  NULL,            NULL },
+    { MAP_CALL(Graph),             SIG_EVERYWHERE,           "i(.*)",                NULL,            NULL }, // subop
+    { MAP_CALL(Joystick),          SIG_EVERYWHERE,           "i(.*)",                NULL,            NULL }, // subop
+    { MAP_CALL(FileIO),            SIG_EVERYWHERE,           "i(.*)",                NULL,            NULL }, // subop
+    { MAP_CALL(Memory),            SIG_EVERYWHERE,           "i(.*)",                NULL,            NULL }, // subop
     { MAP_CALL(Sort),              SIG_EVERYWHERE,           "ooo",                  NULL,            NULL },
-    { MAP_CALL(AvoidPath),         SIG_EVERYWHERE,           "ii.*",                 NULL,            NULL },
-    { MAP_CALL(Lock),              SIG_EVERYWHERE,           "iii*",                 NULL,            NULL },
-    { MAP_CALL(Palette),           SIG_EVERYWHERE,           "i.*",                  NULL,            NULL },
+    { MAP_CALL(AvoidPath),         SIG_EVERYWHERE,           "ii(.*)",               NULL,            NULL },
+    { MAP_CALL(Lock),              SIG_EVERYWHERE,           "ii(i)",                NULL,            NULL },
+    { MAP_CALL(Palette),           SIG_EVERYWHERE,           "i(.*)",                NULL,            NULL }, // subop
     { MAP_CALL(IsItSkip),          SIG_EVERYWHERE,           "iiiii",                NULL,            NULL },
-    { MAP_CALL(StrSplit),          SIG_EVERYWHERE,           "rrZr",                 NULL,            NULL },
+    { MAP_CALL(StrSplit),          SIG_EVERYWHERE,           "rr[r0]",               NULL,            NULL },
     { "CosMult", kTimesCos,        SIG_EVERYWHERE,           "ii",                   NULL,            NULL },
     { "SinMult", kTimesSin,        SIG_EVERYWHERE,           "ii",                   NULL,            NULL },
     { MAP_CALL(CosDiv),            SIG_EVERYWHERE,           "ii",                   NULL,            NULL },
@@ -375,31 +381,31 @@
     { MAP_CALL(SinDiv),            SIG_EVERYWHERE,           "ii",                   NULL,            NULL },
     { MAP_CALL(TimesCot),          SIG_EVERYWHERE,           "ii",                   NULL,            NULL },
     { MAP_CALL(TimesTan),          SIG_EVERYWHERE,           "ii",                   NULL,            NULL },
-    { MAP_CALL(Message),           SIG_EVERYWHERE,           ".*",                   NULL,            NULL },
+    { MAP_CALL(Message),           SIG_EVERYWHERE,           "i(.*)",                NULL,            NULL }, // subop
     { MAP_CALL(GetMessage),        SIG_EVERYWHERE,           "iiir",                 NULL,            NULL },
-    { MAP_CALL(DoAudio),           SIG_EVERYWHERE,           ".*",                   NULL,            NULL },
-    { MAP_CALL(DoSync),            SIG_EVERYWHERE,           ".*",                   NULL,            NULL },
-    { MAP_CALL(MemorySegment),     SIG_EVERYWHERE,           "iri*",                 NULL,            NULL },
+    { MAP_CALL(DoAudio),           SIG_EVERYWHERE,           "i(.*)",                NULL,            NULL }, // subop
+    { MAP_CALL(DoSync),            SIG_EVERYWHERE,           "i(.*)",                NULL,            NULL }, // subop
+    { MAP_CALL(MemorySegment),     SIG_EVERYWHERE,           "ir(i)",                NULL,            NULL }, // subop
     { MAP_CALL(Intersections),     SIG_EVERYWHERE,           "iiiiriiiri",           NULL,            NULL },
     { MAP_CALL(MergePoly),         SIG_EVERYWHERE,           "rli",                  NULL,            NULL },
-    { MAP_CALL(ResCheck),          SIG_EVERYWHERE,           "iii*",                 NULL,            NULL },
+    { MAP_CALL(ResCheck),          SIG_EVERYWHERE,           "ii(iiii)",             NULL,            NULL },
     { MAP_CALL(SetQuitStr),        SIG_EVERYWHERE,           "r",                    NULL,            NULL },
-    { MAP_CALL(ShowMovie),         SIG_EVERYWHERE,           ".*",                   NULL,            NULL },
+    { MAP_CALL(ShowMovie),         SIG_EVERYWHERE,           "(.*)",                 NULL,            NULL },
     { MAP_CALL(SetVideoMode),      SIG_EVERYWHERE,           "i",                    NULL,            NULL },
-    { MAP_CALL(Platform),          SIG_EVERYWHERE,           ".*",                   NULL,            NULL },
-    { MAP_CALL(TextColors),        SIG_EVERYWHERE,           ".*",                   NULL,            NULL },
-    { MAP_CALL(TextFonts),         SIG_EVERYWHERE,           ".*",                   NULL,            NULL },
-    { MAP_CALL(Portrait),          SIG_EVERYWHERE,           ".*",                   NULL,            NULL },
-    { MAP_CALL(PalVary),           SIG_EVERYWHERE,           "ii*",                  NULL,            NULL },
+    { MAP_CALL(Platform),          SIG_EVERYWHERE,           "(.*)",                 NULL,            NULL },
+    { MAP_CALL(TextColors),        SIG_EVERYWHERE,           "(i*)",                 NULL,            NULL },
+    { MAP_CALL(TextFonts),         SIG_EVERYWHERE,           "(i*)",                 NULL,            NULL },
+    { MAP_CALL(Portrait),          SIG_EVERYWHERE,           "i(.*)",                NULL,            NULL }, // subop
+    { MAP_CALL(PalVary),           SIG_EVERYWHERE,           "i(i*)",                NULL,            NULL }, // subop
     { MAP_CALL(AssertPalette),     SIG_EVERYWHERE,           "i",                    NULL,            NULL },
-    { MAP_CALL(Empty),             SIG_EVERYWHERE,           ".*",                   NULL,            NULL },
+    { MAP_CALL(Empty),             SIG_EVERYWHERE,           "(.*)",                 NULL,            NULL },
 
 #ifdef ENABLE_SCI32
     // SCI2 Kernel Functions
     { MAP_CALL(IsHiRes),           SIG_EVERYWHERE,           "",                     NULL,            NULL },
-    { MAP_CALL(Array),             SIG_EVERYWHERE,           ".*",                   NULL,            NULL },
+    { MAP_CALL(Array),             SIG_EVERYWHERE,           "(.*)",                 NULL,            NULL },
     { MAP_CALL(ListAt),            SIG_EVERYWHERE,           "li",                   NULL,            NULL },
-    { MAP_CALL(String),            SIG_EVERYWHERE,           ".*",                   NULL,            NULL },
+    { MAP_CALL(String),            SIG_EVERYWHERE,           "(.*)",                 NULL,            NULL },
     { MAP_CALL(AddScreenItem),     SIG_EVERYWHERE,           "o",                    NULL,            NULL },
     { MAP_CALL(UpdateScreenItem),  SIG_EVERYWHERE,           "o",                    NULL,            NULL },
     { MAP_CALL(DeleteScreenItem),  SIG_EVERYWHERE,           "o",                    NULL,            NULL },
@@ -409,23 +415,23 @@
     { MAP_CALL(RepaintPlane),      SIG_EVERYWHERE,           "o",                    NULL,            NULL },
     { MAP_CALL(GetHighPlanePri),   SIG_EVERYWHERE,           "",                     NULL,            NULL },
     { MAP_CALL(FrameOut),          SIG_EVERYWHERE,           "",                     NULL,            NULL },
-    { MAP_CALL(ListEachElementDo), SIG_EVERYWHERE,           "li.*",                 NULL,            NULL },
-    { MAP_CALL(ListFirstTrue),     SIG_EVERYWHERE,           "li.*",                 NULL,            NULL },
-    { MAP_CALL(ListAllTrue),       SIG_EVERYWHERE,           "li.*",                 NULL,            NULL },
-    { MAP_CALL(ListIndexOf),       SIG_EVERYWHERE,           "lZo",                  NULL,            NULL },
-    { MAP_CALL(OnMe),              SIG_EVERYWHERE,           "iio.*",                NULL,            NULL },
+    { MAP_CALL(ListEachElementDo), SIG_EVERYWHERE,           "li(.*)",               NULL,            NULL },
+    { MAP_CALL(ListFirstTrue),     SIG_EVERYWHERE,           "li(.*)",               NULL,            NULL },
+    { MAP_CALL(ListAllTrue),       SIG_EVERYWHERE,           "li(.*)",               NULL,            NULL },
+    { MAP_CALL(ListIndexOf),       SIG_EVERYWHERE,           "l[o0]",                NULL,            NULL },
+    { MAP_CALL(OnMe),              SIG_EVERYWHERE,           "iio(.*)",              NULL,            NULL },
     { MAP_CALL(InPolygon),         SIG_EVERYWHERE,           "iio",                  NULL,            NULL },
-    { MAP_CALL(CreateTextBitmap),  SIG_EVERYWHERE,           "i.*",                  NULL,            NULL },
+    { MAP_CALL(CreateTextBitmap),  SIG_EVERYWHERE,           "i(.*)",                NULL,            NULL },
 
     // SCI2.1 Kernel Functions
-    { MAP_CALL(Save),              SIG_EVERYWHERE,           ".*",                   NULL,            NULL },
-    { MAP_CALL(List),              SIG_EVERYWHERE,           ".*",                   NULL,            NULL },
-    { MAP_CALL(Robot),             SIG_EVERYWHERE,           ".*",                   NULL,            NULL },
-    { MAP_CALL(PlayVMD),           SIG_EVERYWHERE,           ".*",                   NULL,            NULL },
-    { MAP_CALL(IsOnMe),            SIG_EVERYWHERE,           "iio.*",                NULL,            NULL },
+    { MAP_CALL(Save),              SIG_EVERYWHERE,           "(.*)",                 NULL,            NULL },
+    { MAP_CALL(List),              SIG_EVERYWHERE,           "(.*)",                 NULL,            NULL },
+    { MAP_CALL(Robot),             SIG_EVERYWHERE,           "(.*)",                 NULL,            NULL },
+    { MAP_CALL(PlayVMD),           SIG_EVERYWHERE,           "(.*)",                 NULL,            NULL },
+    { MAP_CALL(IsOnMe),            SIG_EVERYWHERE,           "iio(.*)",              NULL,            NULL },
     { MAP_CALL(MulDiv),            SIG_EVERYWHERE,           "iii",                  NULL,            NULL },
-    { MAP_CALL(Text),              SIG_EVERYWHERE,           ".*",                   NULL,            NULL },
-    { MAP_CALL(CD),           	   SIG_EVERYWHERE,           ".*",                   NULL,            NULL },
+    { MAP_CALL(Text),              SIG_EVERYWHERE,           "(.*)",                 NULL,            NULL },
+    { MAP_CALL(CD),           	   SIG_EVERYWHERE,           "(.*)",                 NULL,            NULL },
     { NULL, NULL,                  SIG_EVERYWHERE,           NULL,                   NULL,            NULL }
 #endif
 };
@@ -514,77 +520,349 @@
 	}
 }
 
-static char *compileKernelSignature(const char *s) {
-	const char *src = s;
-	char *result;
-	bool ellipsis = false;
-	int index = 0;
+// this parses a written kernel signature into an internal memory format
+// [io] -> either integer or object
+// (io) -> optionally integer AND an object
+// (i) -> optional integer
+// . -> any type
+// i* -> optional multiple integers
+// .* -> any parameters afterwards (or none)
+static uint16 *parseKernelSignature(const char *kernelName, const char *writtenSig) {
+	const char *curPos;
+	char curChar;
+	uint16 *result = NULL;
+	uint16 *writePos = NULL;
+	int size = 0;
+	bool validType = false;
+	bool optionalType = false;
+	bool eitherOr = false;
+	bool optional = false;
+	bool hadOptional = false;
 
-	if (!src)
-		return 0; // NULL signature: Nothing to do
+	// First, we check how many bytes the result will be
+	//  we also check, if the written signature makes any sense
+	curPos = writtenSig;
+	while (*curPos) {
+		switch (*curPos) {
+		case '[': // either or
+			if (eitherOr)
+				error("signature for k%s: '[' used within '[]'", kernelName);
+			eitherOr = true;
+			validType = false;
+			break;
+		case ']': // either or end
+			if (!eitherOr)
+				error("signature for k%s: ']' used without leading '['", kernelName);
+			if (!validType)
+				error("signature for k%s: '[]' does not surround valid type(s)", kernelName);
+			eitherOr = false;
+			validType = false;
+			size++;
+			break;
+		case '(': // optional
+			if (optional)
+				error("signature for k%s: '(' used within '()' brackets", kernelName);
+			if (eitherOr)
+				error("signature for k%s: '(' used within '[]' brackets", kernelName);
+			optional = true;
+			validType = false;
+			optionalType = false;
+			break;
+		case ')': // optional end
+			if (!optional)
+				error("signature for k%s: ')' used without leading '('", kernelName);
+			if (!optionalType)
+				error("signature for k%s: '()' does not to surround valid type(s)", kernelName);
+			optional = false;
+			validType = false;
+			hadOptional = true;
+			break;
+		case '0': // allowed types
+		case 'i':
+		case 'o':
+		case 'r':
+		case 'l':
+		case 'n':
+		case '.':
+			if ((hadOptional) & (!optional))
+				error("signature for k%s: non-optional type may not follow optional type", kernelName);
+			validType = true;
+			if (optional)
+				optionalType = true;
+			if (!eitherOr)
+				size++;
+			break;
+		case '*': // accepts more of the same parameter (must be last char)
+			if (!validType) {
+				if ((writtenSig == curPos) || (*(curPos - 1) != ']'))
+					error("signature for k%s: a valid type must be in front of '*'", kernelName);
+			}
+			if (eitherOr)
+				error("signature for k%s: '*' may not be inside '[]'", kernelName);
+			if (optional) {
+				if ((*(curPos + 1) != ')') || (*(curPos + 2) != 0))
+					error("signature for k%s: '*' may only be used for last type", kernelName);
+			} else {
+				if (*(curPos + 1) != 0)
+					error("signature for k%s: '*' may only be used for last type", kernelName);
+			}
+			break;
+		default:
+			error("signature for k%s: '%c' unknown", kernelName, *curPos);
+		}
+		curPos++;
+	}
 
-	result = (char *)malloc(strlen(s) + 1);
+	uint16 signature = 0;
 
-	while (*src) {
-		char c;
-		char v = 0;
-
-		if (ellipsis) {
-			error("Failed compiling kernel function signature '%s': non-terminal ellipsis '%c'", s, *src);
+	// Now we allocate buffer with required size and fill it
+	result = new uint16[size + 1];
+	writePos = result;
+	curPos = writtenSig;
+	do {
+		curChar = *curPos;
+		if (!eitherOr) {
+			// not within either-or, check if next character forces output
+			switch (curChar) {
+			case 0:
+			case '[':
+			case '(':
+			case ')':
+			case 'i':
+			case 'o':
+			case 'r':
+			case 'l':
+			case 'n':
+			case '.':
+				// and we also got some signature pending?
+				if (signature) {
+					if (optional) {
+						signature |= SIG_IS_OPTIONAL;
+						if (curChar != ')')
+							signature |= SIG_NEEDS_MORE;
+					}
+					*writePos = signature;
+					writePos++;
+					signature = 0;
+				}
+			}
 		}
+		switch (curChar) {
+		case '[': // either or
+			eitherOr = true;
+			break;
+		case ']': // either or end
+			eitherOr = false;
+			break;
+		case '(': // optional
+			optional = true;
+			break;
+		case ')': // optional end
+			optional = false;
+			break;
+		case '0':
+			if (signature & SIG_TYPE_NULL)
+				error("signature for k%s: NULL specified more than once", kernelName);
+			signature |= SIG_TYPE_NULL;
+			break;
+		case 'i':
+			if (signature & SIG_TYPE_INTEGER)
+				error("signature for k%s: integer specified more than once", kernelName);
+			signature |= SIG_TYPE_INTEGER | SIG_TYPE_NULL;
+			break;
+		case 'o':
+			if (signature & SIG_TYPE_OBJECT)
+				error("signature for k%s: object specified more than once", kernelName);
+			signature |= SIG_TYPE_OBJECT;
+			break;
+		case 'r':
+			if (signature & SIG_TYPE_REFERENCE)
+				error("signature for k%s: reference specified more than once", kernelName);
+			signature |= SIG_TYPE_REFERENCE;
+			break;
+		case 'l':
+			if (signature & SIG_TYPE_LIST)
+				error("signature for k%s: list specified more than once", kernelName);
+			signature |= SIG_TYPE_LIST;
+			break;
+		case 'n':
+			if (signature & SIG_TYPE_NODE)
+				error("signature for k%s: node specified more than once", kernelName);
+			signature |= SIG_TYPE_NODE;
+			break;
+		case '.':
+			signature |= SIG_MAYBE_ANY;
+			break;
+		case '*': // accepts more of the same parameter
+			signature |= SIG_MORE_MAY_FOLLOW;
+			break;
+		default:
+			break;
+		}
+		curPos++;
+	} while (curChar);
 
-		do {
-			char cc;
-			cc = c = *src++;
-			if (c >= 'A' || c <= 'Z')
-				cc = c | KSIG_SPEC_SUM_DONE;
+	// Write terminator
+	*writePos = 0;
 
-			switch (cc) {
-			case KSIG_SPEC_LIST:
-				v |= KSIG_LIST;
-				break;
+	return result;
+}
 
-			case KSIG_SPEC_NODE:
-				v |= KSIG_NODE;
-				break;
+int Kernel::findRegType(reg_t reg) {
+	// No segment? Must be integer
+	if (!reg.segment)
+		return SIG_TYPE_INTEGER | (reg.offset ? 0 : SIG_TYPE_NULL);
 
-			case KSIG_SPEC_REF:
-				v |= KSIG_REF;
-				break;
+	if (reg.segment == 0xFFFF)
+		return SIG_TYPE_UNINITIALIZED;
 
-			case KSIG_SPEC_OBJECT:
-				v |= KSIG_OBJECT;
-				break;
+	// Otherwise it's an object
+	SegmentObj *mobj = _segMan->getSegmentObj(reg.segment);
+	if (!mobj)
+		return 0; // Invalid
 
-			case KSIG_SPEC_ARITHMETIC:
-				v |= KSIG_ARITHMETIC;
-				break;
+	if (!mobj->isValidOffset(reg.offset))
+		error("[KERN] ref %04x:%04x is invalid", PRINT_REG(reg));
 
-			case KSIG_SPEC_NULL:
-				v |= KSIG_NULL;
-				break;
+	switch (mobj->getType()) {
+	case SEG_TYPE_SCRIPT:
+		if (reg.offset <= (*(Script *)mobj).getBufSize() &&
+			reg.offset >= -SCRIPT_OBJECT_MAGIC_OFFSET &&
+		    RAW_IS_OBJECT((*(Script *)mobj).getBuf(reg.offset)) ) {
+			return ((Script *)mobj)->getObject(reg.offset) ? SIG_TYPE_OBJECT : SIG_TYPE_REFERENCE;
+		} else
+			return SIG_TYPE_REFERENCE;
+	case SEG_TYPE_CLONES:
+		return SIG_TYPE_OBJECT;
+	case SEG_TYPE_LOCALS:
+	case SEG_TYPE_STACK:
+	case SEG_TYPE_SYS_STRINGS:
+	case SEG_TYPE_DYNMEM:
+	case SEG_TYPE_HUNK:
+#ifdef ENABLE_SCI32
+	case SEG_TYPE_ARRAY:
+	case SEG_TYPE_STRING:
+#endif
+		return SIG_TYPE_REFERENCE;
+	case SEG_TYPE_LISTS:
+		return SIG_TYPE_LIST;
+	case SEG_TYPE_NODES:
+		return SIG_TYPE_NODE;
+	default:
+		return 0;
+	}
+}
 
-			case KSIG_SPEC_ANY:
-				v |= KSIG_ANY;
-				break;
+struct SignatureDebugType {
+	uint16 typeCheck;
+	const char *text;
+};
 
-			case KSIG_SPEC_ELLIPSIS:
-				v |= KSIG_ELLIPSIS;
-				ellipsis = true;
-				break;
+static const SignatureDebugType signatureDebugTypeList[] = {
+	{ SIG_TYPE_NULL,          "null" },
+	{ SIG_TYPE_INTEGER,       "integer" },
+	{ SIG_TYPE_UNINITIALIZED, "uninitialized" },
+	{ SIG_TYPE_OBJECT,        "object" },
+	{ SIG_TYPE_REFERENCE,     "reference" },
+	{ SIG_TYPE_LIST,          "list" },
+	{ SIG_TYPE_NODE,          "node" },
+	{ 0,                      NULL }
+};
 
-			default:
-				error("ERROR compiling kernel function signature '%s': (%02x / '%c') not understood", s, c, c);
+static void kernelSignatureDebugType(const uint16 type) {
+	bool firstPrint = true;
+
+	const SignatureDebugType *list = signatureDebugTypeList;
+	while (list->typeCheck) {
+		if (type & list->typeCheck) {
+			if (!firstPrint)
+				printf(", ");
+			printf("%s", list->text);
+			firstPrint = false;
+		}
+		list++;
+	}
+}
+
+// Shows kernel call signature and current arguments for debugging purposes
+void Kernel::signatureDebug(const uint16 *sig, int argc, const reg_t *argv) {
+	int argnr = 0;
+	while (*sig || argc) {
+		printf("parameter %d: ", argnr++);
+		if (argc) {
+			reg_t parameter = *argv;
+			printf("%04x:%04x (", PRINT_REG(parameter));
+			int regType = findRegType(parameter);
+			if (regType)
+				kernelSignatureDebugType(regType);
+			else
+				printf("unknown type of %04x:%04x", PRINT_REG(parameter));
+			printf(")");
+			argv++;
+			argc--;
+		} else {
+			printf("not passed");
+		}
+		if (*sig) {
+			const uint16 signature = *sig;
+			if ((signature & SIG_MAYBE_ANY) == SIG_MAYBE_ANY) {
+				printf(", may be any");
+			} else {
+				printf(", should be ");
+				kernelSignatureDebugType(signature);
 			}
-		} while (*src && (*src == KSIG_SPEC_ELLIPSIS || (c < 'a' && c != KSIG_SPEC_ANY)));
+			if (signature & SIG_IS_OPTIONAL)
+				printf(" (optional)");
+			if (signature & SIG_NEEDS_MORE)
+				printf(" (needs more)");
+			if (signature & SIG_MORE_MAY_FOLLOW)
+				printf(" (more may follow)");
+			sig++;
+		}
+		printf("\n");
+	}
+}
 
-		// To handle sum types
-		result[index++] = v;
+bool Kernel::signatureMatch(const uint16 *sig, int argc, const reg_t *argv) {
+	uint16 nextSig = *sig;
+	uint16 curSig = nextSig;
+	while (nextSig && argc) {
+		curSig = nextSig;
+		int type = findRegType(*argv);
+		if (!type)
+			return false; // couldn't determine type
+
+		if (!(type & curSig))
+			return false; // type mismatch
+
+		if (!(curSig & SIG_MORE_MAY_FOLLOW)) {
+			sig++;
+			nextSig = *sig;
+		} else {
+			nextSig |= SIG_IS_OPTIONAL; // more may follow -> assumes followers are optional
+		}
+		argv++;
+		argc--;
 	}
 
-	result[index] = 0;
-
-	return result;
+	// Too many arguments?
+	if (argc)
+		return false;
+	// Signature end reached?
+	if (nextSig == 0)
+		return true;
+	// current parameter is optional?
+	if (curSig & SIG_IS_OPTIONAL) {
+		// yes, check if nothing more is required
+		if (!(curSig & SIG_NEEDS_MORE))
+			return true;
+	} else {
+		// no, check if next parameter is optional
+		if (nextSig & SIG_IS_OPTIONAL)
+			return true;
+	}
+	// Too few arguments or more optional arguments required
+	return false;
 }
 
 void Kernel::mapFunctions() {
@@ -645,8 +923,8 @@
 		bool nameMatch = false;
 		while (kernelMap->name) {
 			if (sought_name == kernelMap->name) {
-				if ((kernelMap->fromVersion == SCI_VERSION_NONE) || (kernelMap->fromVersion >= myVersion))
-					if ((kernelMap->toVersion == SCI_VERSION_NONE) || (kernelMap->toVersion <= myVersion))
+				if ((kernelMap->fromVersion == SCI_VERSION_NONE) || (kernelMap->fromVersion <= myVersion))
+					if ((kernelMap->toVersion == SCI_VERSION_NONE) || (kernelMap->toVersion >= myVersion))
 						if (platformMask & kernelMap->forPlatform)
 							break;
 				nameMatch = true;
@@ -658,7 +936,7 @@
 			// A match was found
 			if (kernelMap->function) {
 				_kernelFuncs[functNr].func = kernelMap->function;
-				_kernelFuncs[functNr].signature = compileKernelSignature(kernelMap->signature);
+				_kernelFuncs[functNr].signature = parseKernelSignature(kernelMap->name, kernelMap->signature);
 				_kernelFuncs[functNr].workarounds = kernelMap->workarounds;
 				_kernelFuncs[functNr].isDummy = false;
 				++mapped;
@@ -680,147 +958,6 @@
 	return;
 }
 
-int Kernel::findRegType(reg_t reg) {
-	// No segment? Must be arithmetic
-	if (!reg.segment)
-		return reg.offset ? KSIG_ARITHMETIC : KSIG_ARITHMETIC | KSIG_NULL;
-
-	if (reg.segment == 0xFFFF)
-		return KSIG_UNINITIALIZED;
-
-	// Otherwise it's an object
-	SegmentObj *mobj = _segMan->getSegmentObj(reg.segment);
-	if (!mobj)
-		return 0; // Invalid
-
-	if (!mobj->isValidOffset(reg.offset))
-		error("[KERN] ref %04x:%04x is invalid", PRINT_REG(reg));
-
-	switch (mobj->getType()) {
-	case SEG_TYPE_SCRIPT:
-		if (reg.offset <= (*(Script *)mobj).getBufSize() &&
-			reg.offset >= -SCRIPT_OBJECT_MAGIC_OFFSET &&
-		    RAW_IS_OBJECT((*(Script *)mobj).getBuf(reg.offset)) ) {
-			return ((Script *)mobj)->getObject(reg.offset) ? KSIG_OBJECT : KSIG_REF;
-		} else
-			return KSIG_REF;
-	case SEG_TYPE_CLONES:
-		return KSIG_OBJECT;
-	case SEG_TYPE_LOCALS:
-	case SEG_TYPE_STACK:
-	case SEG_TYPE_SYS_STRINGS:
-	case SEG_TYPE_DYNMEM:
-	case SEG_TYPE_HUNK:
-#ifdef ENABLE_SCI32
-	case SEG_TYPE_ARRAY:
-	case SEG_TYPE_STRING:
-#endif
-		return KSIG_REF;
-	case SEG_TYPE_LISTS:
-		return KSIG_LIST;
-	case SEG_TYPE_NODES:
-		return KSIG_NODE;
-	default:
-		return 0;
-	}
-}
-
-struct SignatureDebugType {
-	char typeCheck;
-	const char *text;
-};
-
-static const SignatureDebugType signatureDebugTypeList[] = {
-	{ KSIG_NULL,          "null" },
-	{ KSIG_ARITHMETIC,    "value" },
-	{ KSIG_UNINITIALIZED, "uninitialized" },
-	{ KSIG_OBJECT,        "object" },
-	{ KSIG_REF,           "reference" },
-	{ KSIG_LIST,          "list" },
-	{ KSIG_NODE,          "node" },
-	{ 0,                  NULL }
-};
-
-static void kernelSignatureDebugType(const char type) {
-	bool firstPrint = true;
-
-	const SignatureDebugType *list = signatureDebugTypeList;
-	while (list->typeCheck) {
-		if (type & list->typeCheck) {
-			if (!firstPrint)
-				printf(", ");
-			printf("%s", list->text);
-			firstPrint = false;
-		}
-		list++;
-	}
-}
-
-// Shows kernel call signature and current arguments for debugging purposes
-void Kernel::signatureDebug(const char *sig, int argc, const reg_t *argv) {
-	int argnr = 0;
-	while (*sig || argc) {
-		printf("parameter %d: ", argnr++);
-		if (argc) {
-			reg_t parameter = *argv;
-			printf("%04x:%04x (", PRINT_REG(parameter));
-			int regType = findRegType(parameter);
-			if (regType)
-				kernelSignatureDebugType(regType);
-			else
-				printf("unknown type of %04x:%04x", PRINT_REG(parameter));
-			printf(")");
-			argv++;
-			argc--;
-		} else {
-			printf("not passed");
-		}
-		if (*sig) {
-			const char signature = *sig;
-			if ((signature & KSIG_ANY) == KSIG_ANY) {
-				printf(", may be any");
-			} else {
-				printf(", should be ");
-				kernelSignatureDebugType(signature);
-			}
-			if (signature & KSIG_ELLIPSIS)
-				printf(" (optional)");
-			sig++;
-		}
-		printf("\n");
-	}
-}
-
-bool Kernel::signatureMatch(const char *sig, int argc, const reg_t *argv) {
-	// Always "match" if no signature is given
-	if (!sig)
-		return true;
-
-	while (*sig && argc) {
-		if ((*sig & KSIG_ANY) != KSIG_ANY) {
-			int type = findRegType(*argv);
-
-			if (!type)
-				return false; // couldn't determine type
-
-			if (!(type & *sig))
-				return false; // type mismatch
-
-		}
-		if (!(*sig & KSIG_ELLIPSIS))
-			++sig;
-		++argv;
-		--argc;
-	}
-
-	if (argc)
-		return false; // Too many arguments
-	if (*sig == 0 || (*sig & KSIG_ELLIPSIS))
-		return true;
-
-	return false; // Too few arguments
-}
-
 void Kernel::setDefaultKernelNames() {
 	_kernelNames = Common::StringArray(s_defaultKernelNames, ARRAYSIZE(s_defaultKernelNames));
 

Modified: scummvm/trunk/engines/sci/engine/kernel.h
===================================================================
--- scummvm/trunk/engines/sci/engine/kernel.h	2010-07-05 13:06:58 UTC (rev 50677)
+++ scummvm/trunk/engines/sci/engine/kernel.h	2010-07-05 14:36:31 UTC (rev 50678)
@@ -96,20 +96,23 @@
 
 // ---- Kernel signatures -----------------------------------------------------
 
-
-// Compiled signatures
+// internal kernel signature data
 enum {
-	KSIG_LIST          = 0x01,
-	KSIG_NODE          = 0x02,
-	KSIG_OBJECT        = 0x04,
-	KSIG_REF           = 0x08,
-	KSIG_ARITHMETIC    = 0x10,
-	KSIG_UNINITIALIZED = 0x20,
-	KSIG_NULL          = 0x40,
-	KSIG_ANY           = 0x5f,
-	KSIG_ELLIPSIS      = 0x80
+	SIG_TYPE_NULL          =  0x01, // may be 0:0       [0]
+	SIG_TYPE_INTEGER       =  0x02, // may be 0:*       [i], automatically also allows null
+	SIG_TYPE_UNINITIALIZED =  0x04, // may be FFFF:*    -> not allowable, only used for comparsion
+	SIG_TYPE_OBJECT        =  0x10, // may be object    [o]
+	SIG_TYPE_REFERENCE     =  0x20, // may be reference [r]
+	SIG_TYPE_LIST          =  0x40, // may be list      [l]
+	SIG_TYPE_NODE          =  0x80, // may be node      [n]
+	SIG_IS_OPTIONAL        = 0x100, // is optional
+	SIG_NEEDS_MORE         = 0x200, // needs at least one additional parameter following
+	SIG_MORE_MAY_FOLLOW    = 0x400, // may have more parameters of the same type following
 };
 
+// this does not include SIG_TYPE_UNINITIALIZED, because we can not allow uninitialized values anywhere
+#define SIG_MAYBE_ANY    (SIG_TYPE_NULL | SIG_TYPE_INTEGER | SIG_TYPE_OBJECT | SIG_TYPE_REFERENCE | SIG_TYPE_LIST | SIG_TYPE_NODE)
+
 // ----------------------------------------------------------------------------
 
 /* Generic description: */
@@ -132,7 +135,7 @@
 	KernelFunc *func; /**< The actual function */
 	Common::String origName; /**< Original name, in case we couldn't map it */
 	bool isDummy;
-	char *signature;
+	uint16 *signature;
 	const SciWorkaroundEntry *workarounds;
 };
 
@@ -175,16 +178,15 @@
 	 * If no signature is given (i.e., if sig is NULL), this is always
 	 * treated as a match.
 	 *
-	 * @param segMan pointer to the segment manager
 	 * @param sig	 signature to test against
 	 * @param argc	 number of arguments to test
 	 * @param argv	 argument list
 	 * @return true if the signature was matched, false otherwise
 	 */
-	bool signatureMatch(const char *sig, int argc, const reg_t *argv);
+	bool signatureMatch(const uint16 *sig, int argc, const reg_t *argv);
 
 	// Prints out debug information in case a signature check fails
-	void signatureDebug(const char *sig, int argc, const reg_t *argv);
+	void signatureDebug(const uint16 *sig, int argc, const reg_t *argv);
 
 	/**
 	 * Determines the type of the object indicated by reg.


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