aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorScott Percival2019-10-31 23:29:40 +0800
committerEugene Sandulenko2019-11-17 22:31:54 +0100
commit02a43f98af197b5c4cd6bd1fdab793540a2a1666 (patch)
treea4d382e7795368a2b528d5948442d6cca321297c
parent5f6e158fd3d60ab400074c667c275932d36a275c (diff)
downloadscummvm-rg350-02a43f98af197b5c4cd6bd1fdab793540a2a1666.tar.gz
scummvm-rg350-02a43f98af197b5c4cd6bd1fdab793540a2a1666.tar.bz2
scummvm-rg350-02a43f98af197b5c4cd6bd1fdab793540a2a1666.zip
DIRECTOR: Add ScriptContext struct to track all attributes of the current script.
-rw-r--r--engines/director/lingo/lingo-bytecode.cpp21
-rw-r--r--engines/director/lingo/lingo-events.cpp6
-rw-r--r--engines/director/lingo/lingo.cpp36
-rw-r--r--engines/director/lingo/lingo.h14
-rw-r--r--engines/director/score.cpp2
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; i<functions_count; i++) {
+ _currentScriptFunction = i;
+ _currentScriptContext->functions.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<int32, ScriptData *> ScriptHash;
+struct ScriptContext {
+ Common::Array<ScriptData *> functions;
+};
+
+typedef Common::HashMap<int32, ScriptContext *> ScriptContextHash;
typedef Common::Array<Datum> StackData;
typedef Common::HashMap<Common::String, Symbol *, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> SymbolHash;
typedef Common::HashMap<Common::String, Builtin *, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> 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<Common::String, uint32> _eventHandlerTypeIds;
Common::HashMap<Common::String, Audio::AudioStream *> _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;