From 23ad830af38c65d15abcb419cf3c52cdfe0c8270 Mon Sep 17 00:00:00 2001 From: Scott Percival Date: Thu, 28 May 2020 00:25:09 +0800 Subject: [PATCH] DIRECTOR: LINGO: Add functionHandlers lookup, stop overriding _builtins --- engines/director/lingo/lingo-codegen.cpp | 6 ++--- engines/director/lingo/lingo-events.cpp | 17 +------------- engines/director/lingo/lingo.cpp | 29 ++++++++++++++++++++---- engines/director/lingo/lingo.h | 5 ++-- 4 files changed, 32 insertions(+), 25 deletions(-) diff --git a/engines/director/lingo/lingo-codegen.cpp b/engines/director/lingo/lingo-codegen.cpp index 1809322ca08..9b64f5d6e6a 100644 --- a/engines/director/lingo/lingo-codegen.cpp +++ b/engines/director/lingo/lingo-codegen.cpp @@ -283,9 +283,9 @@ Symbol *Lingo::define(Common::String &name, int nargs, ScriptData *code) { sym->type = HANDLER; if (!_eventHandlerTypeIds.contains(name)) { - _builtins[name] = sym; + _archives[_archiveIndex].functionHandlers[name] = sym; } else { - _handlers[ENTITY_INDEX(_eventHandlerTypeIds[name.c_str()], _currentEntityId)] = sym; + _archives[_archiveIndex].eventHandlers[ENTITY_INDEX(_eventHandlerTypeIds[name.c_str()], _currentEntityId)] = sym; } } else { // we don't want to be here. The getHandler call should have used the EntityId and the result @@ -660,7 +660,7 @@ void Lingo::codeFactory(Common::String &name) { sym->parens = true; sym->u.bltin = LB::b_factory; - _handlers[ENTITY_INDEX(_eventHandlerTypeIds[name.c_str()], _currentEntityId)] = sym; + _archives[_archiveIndex].eventHandlers[ENTITY_INDEX(_eventHandlerTypeIds[name.c_str()], _currentEntityId)] = sym; } } diff --git a/engines/director/lingo/lingo-events.cpp b/engines/director/lingo/lingo-events.cpp index 0beb8cfde9e..afcb9d848ee 100644 --- a/engines/director/lingo/lingo-events.cpp +++ b/engines/director/lingo/lingo-events.cpp @@ -94,21 +94,6 @@ ScriptType Lingo::event2script(LEvent ev) { return kNoneScript; } -Symbol *Lingo::getHandler(Common::String &name) { - if (!_eventHandlerTypeIds.contains(name)) { - if (_builtins.contains(name)) - return _builtins[name]; - - return NULL; - } - - uint32 entityIndex = ENTITY_INDEX(_eventHandlerTypeIds[name], _currentEntityId); - if (!_handlers.contains(entityIndex)) - return NULL; - - return _handlers[entityIndex]; -} - void Lingo::primaryEventHandler(LEvent event) { /* When an event occurs the message [...] is first sent to a * primary event handler: [... if exists it is executed] and the @@ -330,7 +315,7 @@ void Lingo::processEvent(LEvent event, ScriptType st, int entityId, int channelI if (!_eventHandlerTypes.contains(event)) error("processEvent: Unknown event %d for entity %d", event, entityId); - if (_handlers.contains(ENTITY_INDEX(event, entityId))) { + if (_archives[_archiveIndex].eventHandlers.contains(ENTITY_INDEX(event, entityId))) { debugC(1, kDebugEvents, "Lingo::processEvent(%s, %s, %d), _eventHandler", _eventHandlerTypes[event], scriptType2str(st), entityId); executeHandler(_eventHandlerTypes[event]); // D4+ Events } else if (_vm->getVersion() < 4 && event == kEventNone && getScriptContext(st, entityId)) { diff --git a/engines/director/lingo/lingo.cpp b/engines/director/lingo/lingo.cpp index 499e87b6909..c5ceb68ee01 100644 --- a/engines/director/lingo/lingo.cpp +++ b/engines/director/lingo/lingo.cpp @@ -190,9 +190,6 @@ Lingo::~Lingo() { for (SymbolHash::iterator it = _globalvars.begin(); it != _globalvars.end(); ++it) delete it->_value; - - for (Common::HashMap::iterator it = _handlers.begin(); it != _handlers.end(); ++it) - delete it->_value; } ScriptContext *Lingo::getScriptContext(ScriptType type, uint16 id) { @@ -214,6 +211,30 @@ Common::String Lingo::getName(uint16 id) { return result; } +Symbol *Lingo::getHandler(Common::String &name) { + if (!_eventHandlerTypeIds.contains(name)) { + // local scripts + if (_archives[0].functionHandlers.contains(name)) + return _archives[0].functionHandlers[name]; + + // shared scripts + if (_archives[1].functionHandlers.contains(name)) + return _archives[1].functionHandlers[name]; + + if (_builtins.contains(name)) + return _builtins[name]; + + return NULL; + } + + uint32 entityIndex = ENTITY_INDEX(_eventHandlerTypeIds[name], _currentEntityId); + // event handlers should only be defined locally, the score in a shared file is ignored + if (_archives[0].eventHandlers.contains(entityIndex)) + return _archives[0].eventHandlers[entityIndex]; + + return NULL; +} + const char *Lingo::findNextDefinition(const char *s) { const char *res = s; @@ -413,7 +434,7 @@ void Lingo::restartLingo() { // custom menus // // NOTE: - // tuneousScript is not reset + // timeoutScript is not reset } int Lingo::getAlignedType(Datum &d1, Datum &d2) { diff --git a/engines/director/lingo/lingo.h b/engines/director/lingo/lingo.h index 00cb1fd26e4..36188f5a19c 100644 --- a/engines/director/lingo/lingo.h +++ b/engines/director/lingo/lingo.h @@ -255,9 +255,10 @@ struct LingoEvent { struct LingoArchive { ScriptContextHash scriptContexts[kMaxScriptType + 1]; Common::Array names; + Common::HashMap eventHandlers; + SymbolHash functionHandlers; }; - class Lingo { public: @@ -419,6 +420,7 @@ public: ScriptContext *_currentScriptContext; uint16 _currentScriptFunction; ScriptData *_currentScript; + bool _returning; bool _nextRepeat; LexerDefineState _indef; @@ -436,7 +438,6 @@ public: Common::Array _labelstack; SymbolHash _builtins; - Common::HashMap _handlers; int _linenumber; int _colnumber;