[Scummvm-git-logs] scummvm master -> 1f95f5c161d8123d4d674dae2917dc6b180ca6aa

stevenhoefel stevenhoefel at hotmail.com
Wed Jan 11 22:58:58 CET 2017


This automated email contains information about 1 new commit which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .

Summary:
1f95f5c161 DIRECTOR: Hook Lingo events through. Tie in frame events.


Commit: 1f95f5c161d8123d4d674dae2917dc6b180ca6aa
    https://github.com/scummvm/scummvm/commit/1f95f5c161d8123d4d674dae2917dc6b180ca6aa
Author: stevenhoefel (stevenhoefel at hotmail.com)
Date: 2017-01-12T08:58:48+11:00

Commit Message:
DIRECTOR: Hook Lingo events through. Tie in frame events.

Changed paths:
    engines/director/lingo/lingo-builtins.cpp
    engines/director/lingo/lingo-code.cpp
    engines/director/lingo/lingo-codegen.cpp
    engines/director/lingo/lingo-gr.cpp
    engines/director/lingo/lingo-gr.y
    engines/director/lingo/lingo-lex.cpp
    engines/director/lingo/lingo-lex.l
    engines/director/lingo/lingo.cpp
    engines/director/lingo/lingo.h
    engines/director/score.cpp


diff --git a/engines/director/lingo/lingo-builtins.cpp b/engines/director/lingo/lingo-builtins.cpp
index 8da9722..f26990c 100644
--- a/engines/director/lingo/lingo-builtins.cpp
+++ b/engines/director/lingo/lingo-builtins.cpp
@@ -172,7 +172,7 @@ void Lingo::initBuiltIns() {
 		sym->parens = blt->parens;
 		sym->u.bltin = blt->func;
 
-		_handlers[blt->name] = sym;
+		_builtins[blt->name] = sym;
 
 		_functions[(void *)sym->u.s] = new FuncDesc(blt->name, "");
 	}
diff --git a/engines/director/lingo/lingo-code.cpp b/engines/director/lingo/lingo-code.cpp
index 4543e52..82c7d27 100644
--- a/engines/director/lingo/lingo-code.cpp
+++ b/engines/director/lingo/lingo-code.cpp
@@ -234,19 +234,19 @@ void Lingo::c_symbolpush() {
 }
 
 void Lingo::c_varpush() {
-	char *name = (char *)&(*g_lingo->_currentScript)[g_lingo->_pc];
+	Common::String name((char *)&(*g_lingo->_currentScript)[g_lingo->_pc]);
 	Datum d;
 
-	g_lingo->_pc += g_lingo->calcStringAlignment(name);
+	g_lingo->_pc += g_lingo->calcStringAlignment(name.c_str());
 
-	if (g_lingo->_handlers.contains(name)) {
+	if (g_lingo->getHandler(name) != NULL) {
 		d.type = HANDLER;
 		d.u.s = new Common::String(name);
 		g_lingo->push(d);
 		return;
 	}
 
-	d.u.sym = g_lingo->lookupVar(name);
+	d.u.sym = g_lingo->lookupVar(name.c_str());
 	if (d.u.sym->type == CASTREF) {
 		d.type = INT;
 		int val = d.u.sym->u.i;
@@ -984,22 +984,21 @@ void Lingo::c_call() {
 void Lingo::call(Common::String name, int nargs) {
 	bool dropArgs = false;
 
-	Symbol *sym;
+	Symbol *sym = g_lingo->getHandler(name);
 
-	if (!g_lingo->_handlers.contains(name)) {
+	if (!g_lingo->_eventHandlerTypeIds.contains(name)) {
 		Symbol *s = g_lingo->lookupVar(name.c_str(), false);
 		if (s && s->type == OBJECT) {
 			debugC(3, kDebugLingoExec,  "Dereferencing object reference: %s to %s", name.c_str(), s->u.s->c_str());
 			name = *s->u.s;
+			sym = g_lingo->getHandler(name);
 		}
 	}
 
-	if (!g_lingo->_handlers.contains(name)) {
+	if (sym == NULL) {
 		warning("Call to undefined handler '%s'. Dropping %d stack items", name.c_str(), nargs);
 		dropArgs = true;
 	} else {
-		sym = g_lingo->_handlers[name];
-
 		if (sym->type == BLTIN && sym->nargs != -1 && sym->nargs != nargs && sym->maxArgs != nargs) {
 			if (sym->nargs == sym->maxArgs)
 				warning("Incorrect number of arguments to handler '%s', expecting %d. Dropping %d stack items", name.c_str(), sym->nargs, nargs);
diff --git a/engines/director/lingo/lingo-codegen.cpp b/engines/director/lingo/lingo-codegen.cpp
index 930e992..f98ad0e 100644
--- a/engines/director/lingo/lingo-codegen.cpp
+++ b/engines/director/lingo/lingo-codegen.cpp
@@ -200,24 +200,23 @@ void Lingo::cleanLocalVars() {
 }
 
 void Lingo::define(Common::String &name, int start, int nargs, Common::String *prefix, int end) {
-	Symbol *sym;
-
 	if (prefix)
 		name = *prefix + "-" + name;
 
 	debugC(3, kDebugLingoCompile, "define(\"%s\", %d, %d, %d)", name.c_str(), start, _currentScript->size() - 1, nargs);
 
-	if (!_handlers.contains(name)) { // Create variable if it was not defined
+	Symbol *sym = getHandler(name);
+	if (sym == NULL) { // Create variable if it was not defined
 		sym = new Symbol;
 
 		sym->name = (char *)calloc(name.size() + 1, 1);
 		Common::strlcpy(sym->name, name.c_str(), name.size() + 1);
 		sym->type = HANDLER;
 
-		_handlers[name] = sym;
+		_handlers[ENTITY_INDEX(_eventHandlerTypeIds[name.c_str()], _currentEntityId)] = sym;
 	} else {
-		sym = g_lingo->_handlers[name];
-
+		//we don't want to be here. The getHandler call should have used the EntityId and the result
+		//should have been unique!
 		warning("Redefining handler '%s'", name.c_str());
 		delete sym->u.defn;
 	}
@@ -368,7 +367,7 @@ void Lingo::codeFactory(Common::String &name) {
 	sym->parens = true;
 	sym->u.bltin = g_lingo->b_factory;
 
-	_handlers[name] = sym;
+	_handlers[ENTITY_INDEX(_eventHandlerTypeIds[name.c_str()], _currentEntityId)] = sym;
 }
 
 }
diff --git a/engines/director/lingo/lingo-gr.cpp b/engines/director/lingo/lingo-gr.cpp
index 916072f..89e64cc 100644
--- a/engines/director/lingo/lingo-gr.cpp
+++ b/engines/director/lingo/lingo-gr.cpp
@@ -2433,7 +2433,7 @@ yyreduce:
   case 61:
 #line 394 "engines/director/lingo/lingo-gr.y"
     {
-		(yyval.code) = g_lingo->code1(g_lingo->_handlers[*(yyvsp[(1) - (1)].s)]->u.func);
+		(yyval.code) = g_lingo->code1(g_lingo->_builtins[*(yyvsp[(1) - (1)].s)]->u.func);
 		delete (yyvsp[(1) - (1)].s); ;}
     break;
 
@@ -2647,21 +2647,21 @@ yyreduce:
   case 105:
 #line 459 "engines/director/lingo/lingo-gr.y"
     {
-		g_lingo->code1(g_lingo->_handlers[*(yyvsp[(1) - (2)].s)]->u.func);
+		g_lingo->code1(g_lingo->_builtins[*(yyvsp[(1) - (2)].s)]->u.func);
 		delete (yyvsp[(1) - (2)].s); ;}
     break;
 
   case 106:
 #line 462 "engines/director/lingo/lingo-gr.y"
     {
-		g_lingo->code1(g_lingo->_handlers[*(yyvsp[(1) - (2)].s)]->u.func);
+		g_lingo->code1(g_lingo->_builtins[*(yyvsp[(1) - (2)].s)]->u.func);
 		delete (yyvsp[(1) - (2)].s); ;}
     break;
 
   case 107:
 #line 465 "engines/director/lingo/lingo-gr.y"
     {
-		g_lingo->code2(g_lingo->c_voidpush, g_lingo->_handlers[*(yyvsp[(1) - (1)].s)]->u.func);
+		g_lingo->code2(g_lingo->c_voidpush, g_lingo->_builtins[*(yyvsp[(1) - (1)].s)]->u.func);
 		delete (yyvsp[(1) - (1)].s); ;}
     break;
 
diff --git a/engines/director/lingo/lingo-gr.y b/engines/director/lingo/lingo-gr.y
index 60e780d..392850b 100644
--- a/engines/director/lingo/lingo-gr.y
+++ b/engines/director/lingo/lingo-gr.y
@@ -392,7 +392,7 @@ expr: INT		{ $$ = g_lingo->codeConst($1); }
 		$$ = g_lingo->code1(g_lingo->c_stringpush);
 		g_lingo->codeString($1->c_str()); }
 	| BLTINNOARGS 	{
-		$$ = g_lingo->code1(g_lingo->_handlers[*$1]->u.func);
+		$$ = g_lingo->code1(g_lingo->_builtins[*$1]->u.func);
 		delete $1; }
 	| ID '(' arglist ')'	{
 		$$ = g_lingo->codeFunc($1, $3);
@@ -457,13 +457,13 @@ func: tPUT expr				{ g_lingo->code1(g_lingo->c_printtop); }
 	| tGLOBAL globallist
 	| tINSTANCE instancelist
 	| BLTINONEARG expr		{
-		g_lingo->code1(g_lingo->_handlers[*$1]->u.func);
+		g_lingo->code1(g_lingo->_builtins[*$1]->u.func);
 		delete $1; }
 	| BLTINNOARGSORONE expr	{
-		g_lingo->code1(g_lingo->_handlers[*$1]->u.func);
+		g_lingo->code1(g_lingo->_builtins[*$1]->u.func);
 		delete $1; }
 	| BLTINNOARGSORONE 		{
-		g_lingo->code2(g_lingo->c_voidpush, g_lingo->_handlers[*$1]->u.func);
+		g_lingo->code2(g_lingo->c_voidpush, g_lingo->_builtins[*$1]->u.func);
 		delete $1; }
 	| BLTINARGLIST '(' arglist ')'	{ g_lingo->codeFunc($1, $3); }
 	| BLTINARGLIST arglist	{ g_lingo->codeFunc($1, $2); }
diff --git a/engines/director/lingo/lingo-lex.cpp b/engines/director/lingo/lingo-lex.cpp
index f3c498b..dc502cf 100644
--- a/engines/director/lingo/lingo-lex.cpp
+++ b/engines/director/lingo/lingo-lex.cpp
@@ -1443,19 +1443,19 @@ YY_RULE_SETUP
 				return tME;
 		}
 
-		if (g_lingo->_handlers.contains(yytext)) {
-			if (g_lingo->_handlers[yytext]->type == BLTIN && g_lingo->_handlers[yytext]->parens == false) {
-				if (g_lingo->_handlers[yytext]->nargs == 0) {
-					if (g_lingo->_handlers[yytext]->maxArgs == 0)
+		if (g_lingo->_builtins.contains(yytext)) {
+			if (g_lingo->_builtins[yytext]->type == BLTIN && g_lingo->_builtins[yytext]->parens == false) {
+				if (g_lingo->_builtins[yytext]->nargs == 0) {
+					if (g_lingo->_builtins[yytext]->maxArgs == 0)
 						return BLTINNOARGS;
-					else if (g_lingo->_handlers[yytext]->maxArgs == 1)
+					else if (g_lingo->_builtins[yytext]->maxArgs == 1)
 						return BLTINNOARGSORONE;
 					else
 						error("Incorrect setup for builtin: %s", yytext);
-				} else if (g_lingo->_handlers[yytext]->nargs == 1 &&
-							g_lingo->_handlers[yytext]->maxArgs == 1) {
+				} else if (g_lingo->_builtins[yytext]->nargs == 1 &&
+							g_lingo->_builtins[yytext]->maxArgs == 1) {
 					return BLTINONEARG;
-				} else if (g_lingo->_handlers[yytext]->nargs == -1) {
+				} else if (g_lingo->_builtins[yytext]->nargs == -1) {
 					return BLTINARGLIST;
 				} else {
 					error("Incorrect setup for builtin: %s", yytext);
diff --git a/engines/director/lingo/lingo-lex.l b/engines/director/lingo/lingo-lex.l
index 9d9dba7..e596c0b 100644
--- a/engines/director/lingo/lingo-lex.l
+++ b/engines/director/lingo/lingo-lex.l
@@ -252,19 +252,19 @@ whitespace [\t ]
 				return tME;
 		}
 
-		if (g_lingo->_handlers.contains(yytext)) {
-			if (g_lingo->_handlers[yytext]->type == BLTIN && g_lingo->_handlers[yytext]->parens == false) {
-				if (g_lingo->_handlers[yytext]->nargs == 0) {
-					if (g_lingo->_handlers[yytext]->maxArgs == 0)
+		if (g_lingo->_builtins.contains(yytext)) {
+			if (g_lingo->_builtins[yytext]->type == BLTIN && g_lingo->_builtins[yytext]->parens == false) {
+				if (g_lingo->_builtins[yytext]->nargs == 0) {
+					if (g_lingo->_builtins[yytext]->maxArgs == 0)
 						return BLTINNOARGS;
-					else if (g_lingo->_handlers[yytext]->maxArgs == 1)
+					else if (g_lingo->_builtins[yytext]->maxArgs == 1)
 						return BLTINNOARGSORONE;
 					else
 						error("Incorrect setup for builtin: %s", yytext);
-				} else if (g_lingo->_handlers[yytext]->nargs == 1 &&
-							g_lingo->_handlers[yytext]->maxArgs == 1) {
+				} else if (g_lingo->_builtins[yytext]->nargs == 1 &&
+							g_lingo->_builtins[yytext]->maxArgs == 1) {
 					return BLTINONEARG;
-				} else if (g_lingo->_handlers[yytext]->nargs == -1) {
+				} else if (g_lingo->_builtins[yytext]->nargs == -1) {
 					return BLTINARGLIST;
 				} else {
 					error("Incorrect setup for builtin: %s", yytext);
diff --git a/engines/director/lingo/lingo.cpp b/engines/director/lingo/lingo.cpp
index 1377b08..1fd4a43 100644
--- a/engines/director/lingo/lingo.cpp
+++ b/engines/director/lingo/lingo.cpp
@@ -34,7 +34,7 @@ Lingo *g_lingo;
 struct EventHandlerType {
 	LEvent handler;
 	const char *name;
-} static const eventHanlerDescs[] = {
+} static const eventHandlerDescs[] = {
 	{ kEventPrepareMovie,		"prepareMovie" },
 	{ kEventStartMovie,			"startMovie" },
 	{ kEventStopMovie,			"stopMovie" },
@@ -86,8 +86,10 @@ Symbol::Symbol() {
 Lingo::Lingo(DirectorEngine *vm) : _vm(vm) {
 	g_lingo = this;
 
-	for (const EventHandlerType *t = &eventHanlerDescs[0]; t->handler != kEventNone; ++t)
+	for (const EventHandlerType *t = &eventHandlerDescs[0]; t->handler != kEventNone; ++t) {
+		_eventHandlerTypeIds[t->name] = t->handler;
 		_eventHandlerTypes[t->handler] = t->name;
+	}
 
 	initBuiltIns();
 	initFuncs();
@@ -161,6 +163,7 @@ void Lingo::addCode(const char *code, ScriptType type, uint16 id) {
 	_currentScript = new ScriptData;
 	_currentScriptType = type;
 	_scripts[type][id] = _currentScript;
+	_currentEntityId = id;
 
 	_linenumber = _colnumber = 1;
 	_hadError = false;
@@ -268,8 +271,23 @@ ScriptType Lingo::event2script(LEvent ev) {
 	return kNoneScript;
 }
 
+Symbol *Lingo::getHandler(Common::String &name) {
+	if (!_eventHandlerTypeIds.contains(name))
+		return NULL;
+
+	uint32 entityIndex = ENTITY_INDEX(_eventHandlerTypeIds[name], _currentEntityId);
+	if (!_handlers.contains(entityIndex))
+		return NULL;
+
+	return _handlers[entityIndex];
+}
+
 void Lingo::processEvent(LEvent event, int entityId) {
-	if (entityId <= 0) return;
+	if (entityId <= 0) 
+		return;
+
+	_currentEntityId = entityId;
+
 	if (!_eventHandlerTypes.contains(event))
 		error("processEvent: Unknown event %d for entity %d", event, entityId);
 
@@ -277,8 +295,8 @@ void Lingo::processEvent(LEvent event, int entityId) {
 
 	if (st != kNoneScript) {
 		executeScript(st, entityId + 1);
-	} else if (_handlers.contains(_eventHandlerTypes[event])) {
-		call(_eventHandlerTypes[event], entityId);
+	} else if (_handlers.contains(ENTITY_INDEX(event, entityId))) {
+		call(_eventHandlerTypes[event], 0);
 		pop();
 	} else {
 		debugC(8, kDebugLingoExec, "STUB: processEvent(%s) for %d", _eventHandlerTypes[event], entityId);
diff --git a/engines/director/lingo/lingo.h b/engines/director/lingo/lingo.h
index a1daeaa..41d0444 100644
--- a/engines/director/lingo/lingo.h
+++ b/engines/director/lingo/lingo.h
@@ -73,6 +73,7 @@ enum LEvent {
 
 typedef void (*inst)(void);
 #define	STOP (inst)0
+#define ENTITY_INDEX(t,id) ((t) * 100000 + (id))
 
 typedef Common::Array<inst> ScriptData;
 typedef Common::Array<double> FloatArray;
@@ -178,6 +179,7 @@ public:
 	Common::String decodeInstruction(uint pc, uint *newPC = NULL);
 
 	ScriptType event2script(LEvent ev);
+	Symbol *getHandler(Common::String &name);
 
 	void processEvent(LEvent event, int entityId);
 
@@ -440,6 +442,7 @@ public:
 public:
 	ScriptData *_currentScript;
 	ScriptType _currentScriptType;
+	uint16 _currentEntityId;
 	bool _returning;
 	bool _indef;
 	bool _ignoreMe;
@@ -450,8 +453,9 @@ public:
 	TheEntityFieldHash _theEntityFields;
 	Common::Array<int> _labelstack;
 
-	SymbolHash _handlers;
+	SymbolHash _builtins;
 	Common::HashMap<Common::String, bool> _twoWordBuiltins;
+	Common::HashMap<uint32, Symbol *> _handlers;
 
 	int _linenumber;
 	int _colnumber;
@@ -475,6 +479,7 @@ private:
 	Datum pop(void);
 
 	Common::HashMap<uint32, const char *> _eventHandlerTypes;
+	Common::HashMap<Common::String, uint32> _eventHandlerTypeIds;
 	Common::HashMap<Common::String, Audio::AudioStream *> _audioAliases;
 
 	ScriptHash _scripts[kMaxScriptType + 1];
diff --git a/engines/director/score.cpp b/engines/director/score.cpp
index 2b74650..fb384c2 100644
--- a/engines/director/score.cpp
+++ b/engines/director/score.cpp
@@ -511,7 +511,7 @@ void Score::loadCastData(Common::SeekableSubReadStreamEndian &stream, uint16 id,
 
 		CastInfo *ci = new CastInfo();
 
-		if (castStrings.size() == 5) {
+		if (castStrings.size() >= 5) {
 			ci->script = castStrings[0];
 			ci->name = castStrings[1];
 			ci->directory = castStrings[2];





More information about the Scummvm-git-logs mailing list