aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEugene Sandulenko2016-06-26 00:20:32 +0200
committerEugene Sandulenko2016-08-03 23:40:36 +0200
commit3d543c62ba44013d89af5bd0804147e1d6c6c56b (patch)
tree3f21ca5331c999a47ae7f9dc0a0ccae58fff8d4d
parent6dc858a041a41e01d466aa4e6d1527030ef93b85 (diff)
downloadscummvm-rg350-3d543c62ba44013d89af5bd0804147e1d6c6c56b.tar.gz
scummvm-rg350-3d543c62ba44013d89af5bd0804147e1d6c6c56b.tar.bz2
scummvm-rg350-3d543c62ba44013d89af5bd0804147e1d6c6c56b.zip
DIRECTOR: Lingo: Initial code for c_call()
-rw-r--r--engines/director/lingo/lingo-code.cpp34
-rw-r--r--engines/director/lingo/lingo.cpp1
-rw-r--r--engines/director/lingo/lingo.h11
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);