diff options
-rw-r--r-- | engines/director/lingo/lingo-code.cpp | 34 | ||||
-rw-r--r-- | engines/director/lingo/lingo.cpp | 1 | ||||
-rw-r--r-- | engines/director/lingo/lingo.h | 11 |
3 files changed, 43 insertions, 3 deletions
diff --git a/engines/director/lingo/lingo-code.cpp b/engines/director/lingo/lingo-code.cpp index ed5e787a2c..d614612812 100644 --- a/engines/director/lingo/lingo-code.cpp +++ b/engines/director/lingo/lingo-code.cpp @@ -397,6 +397,7 @@ void Lingo::define(Common::String &name, int start, int end, int nargs) { } sym->u.defn = new ScriptData(&(*_currentScript)[start], end - start + 1); + sym->nargs = nargs; } void Lingo::codeArg(Common::String &s) { @@ -412,7 +413,7 @@ int Lingo::codeId(Common::String &s) { int Lingo::codeId_(Common::String &name) { int ret; - if (!_handlers.contains(name)) { // This is a call + if (_handlers.contains(name)) { // This is a call ret = code1(c_call); codeString(name.c_str()); code1((inst)0); // Zero arguments @@ -428,7 +429,36 @@ int Lingo::codeId_(Common::String &name) { void Lingo::c_call() { - warning("STUB: c_call()"); + Common::String name((char *)&(*g_lingo->_currentScript)[g_lingo->_pc]); + g_lingo->_pc += g_lingo->calcStringAlignment(name.c_str()); + + if (!g_lingo->_handlers.contains(name)) { + error("Call to undefined handler '%s'", name.c_str()); + } + + Symbol *sym = g_lingo->_handlers[name]; + + int nargs = READ_UINT32(&(*g_lingo->_currentScript)[g_lingo->_pc++]); + + for (int i = nargs; i < sym->nargs; i++) { + Datum d; + + d.val = 0; // TODO, FIXME: Must be VOID + g_lingo->push(d); + } + + CFrame *fp = new CFrame; + + fp->sp = sym; + fp->retpc = g_lingo->_pc; + fp->retscript = g_lingo->_currentScript; + + g_lingo->_callstack.push_back(fp); + + g_lingo->_currentScript = sym->u.defn; + g_lingo->execute(0); + + g_lingo->_returning = 0; } void Lingo::c_procret() { diff --git a/engines/director/lingo/lingo.cpp b/engines/director/lingo/lingo.cpp index c56cde841c..332ee9356c 100644 --- a/engines/director/lingo/lingo.cpp +++ b/engines/director/lingo/lingo.cpp @@ -71,6 +71,7 @@ Symbol::Symbol() { name = NULL; type = VOID; u.str = NULL; + nargs = 0; } Lingo::Lingo(DirectorEngine *vm) : _vm(vm) { diff --git a/engines/director/lingo/lingo.h b/engines/director/lingo/lingo.h index ef07016bbd..3bbac61fe2 100644 --- a/engines/director/lingo/lingo.h +++ b/engines/director/lingo/lingo.h @@ -81,9 +81,10 @@ typedef struct Symbol { /* symbol table entry */ union { int val; /* VAR */ float fval; /* FLOAT */ - ScriptData *defn; /* FUNCTION, PROCEDURE */ + ScriptData *defn; /* FUNCTION, PROCEDURE */ char *str; /* STRING */ } u; + int nargs; Symbol(); } Symbol; @@ -95,6 +96,12 @@ typedef union Datum { /* interpreter stack type */ Datum() { val = 0; sym = NULL; } } Datum; +typedef struct CFrame { /* proc/func call stack frame */ + Symbol *sp; /* symbol table entry */ + int retpc; /* where to resume after return */ + ScriptData *retscript; /* which script to resume after return */ +} CFrame; + typedef Common::HashMap<int32, ScriptData *> ScriptHash; typedef Common::Array<Datum> StackData; typedef Common::HashMap<Common::String, Symbol *, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> SymbolHash; @@ -168,6 +175,8 @@ public: bool _returning; bool _indef; + Common::Array<CFrame *> _callstack; + private: int parse(const char *code); void push(Datum d); |