From 02a43f98af197b5c4cd6bd1fdab793540a2a1666 Mon Sep 17 00:00:00 2001 From: Scott Percival Date: Thu, 31 Oct 2019 23:29:40 +0800 Subject: DIRECTOR: Add ScriptContext struct to track all attributes of the current script. --- engines/director/lingo/lingo-bytecode.cpp | 21 ++++++++++++------ engines/director/lingo/lingo-events.cpp | 6 +++--- engines/director/lingo/lingo.cpp | 36 +++++++++++++++++++++---------- engines/director/lingo/lingo.h | 14 ++++++++---- engines/director/score.cpp | 2 +- 5 files changed, 53 insertions(+), 26 deletions(-) diff --git a/engines/director/lingo/lingo-bytecode.cpp b/engines/director/lingo/lingo-bytecode.cpp index 618909cfb8..87045e2738 100644 --- a/engines/director/lingo/lingo-bytecode.cpp +++ b/engines/director/lingo/lingo-bytecode.cpp @@ -71,14 +71,17 @@ void Lingo::initBytecode() { void Lingo::addCodeV4(Common::SeekableSubReadStreamEndian &stream, ScriptType type, uint16 id) { debugC(1, kDebugLingoCompile, "Add V4 bytecode for type %s with id %d", scriptType2str(type), id); - if (_scripts[type].contains(id)) { - delete _scripts[type][id]; + if (_scriptContexts[type].contains(id)) { + for (size_t j = 0; j < _scriptContexts[type][id]->functions.size(); j++) { + delete _scriptContexts[type][id]->functions[j]; + } + delete _scriptContexts[type][id]; } - _currentScript = new ScriptData; - _currentScriptType = type; - _scripts[type][id] = _currentScript; - _currentEntityId = id; + _currentScriptContext = new ScriptContext; + _currentScriptType = type; + _currentEntityId = id; + _scriptContexts[type][id] = _currentScriptContext; // read the Lscr header! // unk1 @@ -182,6 +185,10 @@ void Lingo::addCodeV4(Common::SeekableSubReadStreamEndian &stream, ScriptType ty // read each entry in the function table. stream.seek(functions_offset); for (uint16 i=0; ifunctions.push_back(new ScriptData); + _currentScript = _currentScriptContext->functions[_currentScriptFunction]; + uint16 name_index = stream.readUint16(); stream.readUint16(); uint32 length = stream.readUint32(); @@ -267,7 +274,7 @@ void Lingo::addCodeV4(Common::SeekableSubReadStreamEndian &stream, ScriptType ty } } - + free(code_store); } } diff --git a/engines/director/lingo/lingo-events.cpp b/engines/director/lingo/lingo-events.cpp index f3bf59b307..cc69cf4267 100644 --- a/engines/director/lingo/lingo-events.cpp +++ b/engines/director/lingo/lingo-events.cpp @@ -189,7 +189,7 @@ void Lingo::runMovieScript(LEvent event) { * window [p.81 of D4 docs] */ - for (uint i = 0; i < _scripts[kMovieScript].size(); i++) { + for (uint i = 0; i < _scriptContexts[kMovieScript].size(); i++) { processEvent(event, kMovieScript, i); @@ -301,10 +301,10 @@ void Lingo::processEvent(LEvent event, ScriptType st, int entityId) { if (_handlers.contains(ENTITY_INDEX(event, entityId))) { debugC(1, kDebugEvents, "Lingo::processEvent(%s, %s, %d), _eventHandler", _eventHandlerTypes[event], scriptType2str(st), entityId); call(_eventHandlerTypes[event], 0); // D4+ Events - } else if (event == kEventNone && _scripts[st].contains(entityId)) { + } else if (event == kEventNone && _scriptContexts[st].contains(entityId)) { debugC(1, kDebugEvents, "Lingo::processEvent(%s, %s, %d), script", _eventHandlerTypes[event], scriptType2str(st), entityId); - executeScript(st, entityId); // D3 list of scripts. + executeScript(st, entityId, 0); // D3 list of scripts. } else { debugC(3, kDebugLingoExec, "STUB: processEvent(%s) for %d", _eventHandlerTypes[event], entityId); } diff --git a/engines/director/lingo/lingo.cpp b/engines/director/lingo/lingo.cpp index 8be3408ad1..25e3ca4061 100644 --- a/engines/director/lingo/lingo.cpp +++ b/engines/director/lingo/lingo.cpp @@ -122,14 +122,19 @@ const char *Lingo::findNextDefinition(const char *s) { void Lingo::addCode(const char *code, ScriptType type, uint16 id) { debugC(1, kDebugLingoCompile, "Add code \"%s\" for type %s with id %d", code, scriptType2str(type), id); - if (_scripts[type].contains(id)) { - delete _scripts[type][id]; + if (_scriptContexts[type].contains(id)) { + delete _scriptContexts[type][id]; } - _currentScript = new ScriptData; + _currentScriptContext = new ScriptContext; _currentScriptType = type; - _scripts[type][id] = _currentScript; _currentEntityId = id; + _scriptContexts[type][id] = _currentScriptContext; + + // FIXME: unpack into seperate functions + _currentScriptFunction = 0; + _currentScriptContext->functions.push_back(new ScriptData); + _currentScript = _currentScriptContext->functions[_currentScriptFunction]; _linenumber = _colnumber = 1; _hadError = false; @@ -203,15 +208,20 @@ void Lingo::addCode(const char *code, ScriptType type, uint16 id) { } } -void Lingo::executeScript(ScriptType type, uint16 id) { - if (!_scripts[type].contains(id)) { +void Lingo::executeScript(ScriptType type, uint16 id, uint16 function) { + if (!_scriptContexts[type].contains(id)) { debugC(3, kDebugLingoExec, "Request to execute non-existant script type %d id %d", type, id); return; } + if (function >= _scriptContexts[type][id]->functions.size()) { + debugC(3, kDebugLingoExec, "Request to execute non-existant function %d in script type %d id %d", function, type, id); + return; + } - debugC(1, kDebugLingoExec, "Executing script type: %s, id: %d", scriptType2str(type), id); + debugC(1, kDebugLingoExec, "Executing script type: %s, id: %d, function: %d", scriptType2str(type), id, function); - _currentScript = _scripts[type][id]; + _currentScriptContext = _scriptContexts[type][id]; + _currentScript = _currentScriptContext->functions[function]; _pc = 0; _returning = false; @@ -226,10 +236,14 @@ void Lingo::restartLingo() { warning("STUB: restartLingo()"); for (int i = 0; i <= kMaxScriptType; i++) { - for (ScriptHash::iterator it = _scripts[i].begin(); it != _scripts[i].end(); ++it) + for (ScriptContextHash::iterator it = _scriptContexts[i].begin(); it != _scriptContexts[i].end(); ++it) { + for (size_t j = 0; j < it->_value->functions.size(); j++) { + delete it->_value->functions[j]; + } delete it->_value; + } - _scripts[i].clear(); + _scriptContexts[i].clear(); } // TODO @@ -392,7 +406,7 @@ void Lingo::runTests() { addCode(script, kMovieScript, counter); if (!_hadError) - executeScript(kMovieScript, counter); + executeScript(kMovieScript, counter, 0); else debug(">> Skipping execution"); diff --git a/engines/director/lingo/lingo.h b/engines/director/lingo/lingo.h index 4e8e711cd4..72aea5e9d5 100644 --- a/engines/director/lingo/lingo.h +++ b/engines/director/lingo/lingo.h @@ -148,7 +148,11 @@ struct Builtin { Builtin(void (*func1)(void), int nargs1) : func(func1), nargs(nargs1) {} }; -typedef Common::HashMap ScriptHash; +struct ScriptContext { + Common::Array functions; +}; + +typedef Common::HashMap ScriptContextHash; typedef Common::Array StackData; typedef Common::HashMap SymbolHash; typedef Common::HashMap BuiltinHash; @@ -172,7 +176,7 @@ public: void addCode(const char *code, ScriptType type, uint16 id); void addCodeV4(Common::SeekableSubReadStreamEndian &stream, ScriptType type, uint16 id); - void executeScript(ScriptType type, uint16 id); + void executeScript(ScriptType type, uint16 id, uint16 function); void printStack(const char *s); Common::String decodeInstruction(uint pc, uint *newPC = NULL); @@ -532,9 +536,11 @@ public: Datum getTheCast(Datum &id, int field); public: - ScriptData *_currentScript; ScriptType _currentScriptType; uint16 _currentEntityId; + ScriptContext *_currentScriptContext; + uint16 _currentScriptFunction; + ScriptData *_currentScript; bool _returning; bool _indef; bool _ignoreMe; @@ -575,7 +581,7 @@ private: Common::HashMap _eventHandlerTypeIds; Common::HashMap _audioAliases; - ScriptHash _scripts[kMaxScriptType + 1]; + ScriptContextHash _scriptContexts[kMaxScriptType + 1]; SymbolHash _globalvars; SymbolHash *_localvars; diff --git a/engines/director/score.cpp b/engines/director/score.cpp index e9f49336d9..f0b6d39c11 100644 --- a/engines/director/score.cpp +++ b/engines/director/score.cpp @@ -70,7 +70,7 @@ Score::Score(DirectorEngine *vm) { // FIXME: TODO: Check whether the original truely does it if (_vm->getVersion() <= 3) { - _lingo->executeScript(kMovieScript, 0); + _lingo->executeScript(kMovieScript, 0, 0); } _movieScriptCount = 0; _labels = NULL; -- cgit v1.2.3