[Scummvm-git-logs] scummvm master -> 612104336fd7844b39049cc0a48dfa77895cd6da
djsrv
dservilla at gmail.com
Thu Jun 18 00:39:32 UTC 2020
This automated email contains information about 4 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
b248a78732 DIRECTOR: LINGO: Merge Sprite/Frame/Score Script
8db0405d31 DIRECTOR: Load D4 cast scripts
af62c56624 DIRECTOR: Consider sprites with CastScripts active
612104336f DIRECTOR: LINGO: Rework event handling
Commit: b248a7873248fc2c54adde0669e1f072dbfa07e0
https://github.com/scummvm/scummvm/commit/b248a7873248fc2c54adde0669e1f072dbfa07e0
Author: djsrv (dservilla at gmail.com)
Date: 2020-06-17T20:38:49-04:00
Commit Message:
DIRECTOR: LINGO: Merge Sprite/Frame/Score Script
Changed paths:
engines/director/lingo/lingo-events.cpp
engines/director/lingo/lingo-patcher.cpp
engines/director/lingo/lingo-the.cpp
engines/director/lingo/lingo.cpp
engines/director/score-loading.cpp
engines/director/types.h
engines/director/util.cpp
diff --git a/engines/director/lingo/lingo-events.cpp b/engines/director/lingo/lingo-events.cpp
index a2a9a3cbcd..8ab93ca4fd 100644
--- a/engines/director/lingo/lingo-events.cpp
+++ b/engines/director/lingo/lingo-events.cpp
@@ -88,7 +88,7 @@ ScriptType Lingo::event2script(LEvent ev) {
//case kEventStartMovie: // We are precompiling it now
// return kMovieScript;
case kEventEnterFrame:
- return kFrameScript;
+ return kScoreScript;
default:
return kNoneScript;
}
@@ -161,10 +161,10 @@ void Lingo::registerInputEvent(LEvent event) {
if (_vm->getVersion() > 3) {
if (true) {
// TODO: Check whether occurring over a sprite
- _eventQueue.push(LingoEvent(event, kSpriteScript, sprite->_scriptId));
+ _eventQueue.push(LingoEvent(event, kScoreScript, sprite->_scriptId));
}
_eventQueue.push(LingoEvent(event, kCastScript, sprite->_castId));
- _eventQueue.push(LingoEvent(event, kFrameScript, currentFrame->_actionId));
+ _eventQueue.push(LingoEvent(event, kScoreScript, currentFrame->_actionId));
// TODO: Is the kFrameScript call above correct?
} else if (event == kEventMouseDown || event == kEventMouseUp) {
// If sprite is immediate, its script is run on mouseDown, otherwise on mouseUp
@@ -175,14 +175,14 @@ void Lingo::registerInputEvent(LEvent event) {
queueEventNone = true;
}
- // Frame script overrides sprite script
+ // Score (sprite) script overrides cast script
if (sprite->_scriptId) {
if (queueEventNone)
- _eventQueue.push(LingoEvent(kEventNone, kFrameScript, sprite->_scriptId, spriteId));
+ _eventQueue.push(LingoEvent(kEventNone, kScoreScript, sprite->_scriptId, spriteId));
} else {
if (queueEventNone)
- _eventQueue.push(LingoEvent(kEventNone, kSpriteScript, sprite->_castId));
- _eventQueue.push(LingoEvent(event, kSpriteScript, sprite->_castId));
+ _eventQueue.push(LingoEvent(kEventNone, kCastScript, sprite->_castId));
+ _eventQueue.push(LingoEvent(event, kCastScript, sprite->_castId));
}
}
@@ -235,7 +235,7 @@ void Lingo::registerFrameEvent(LEvent event) {
assert(score->_frames[score->getCurrentFrame()] != nullptr);
entity = score->_frames[score->getCurrentFrame()]->_actionId;
}
- _eventQueue.push(LingoEvent(event, kFrameScript, entity));
+ _eventQueue.push(LingoEvent(event, kScoreScript, entity));
runMovieScript(event);
}
diff --git a/engines/director/lingo/lingo-patcher.cpp b/engines/director/lingo/lingo-patcher.cpp
index b55bc7d907..88362a9b1c 100644
--- a/engines/director/lingo/lingo-patcher.cpp
+++ b/engines/director/lingo/lingo-patcher.cpp
@@ -40,11 +40,11 @@ struct ScriptPatch {
const char *replace;
} const scriptPatches[] = {
// Garbage at end of script
- {"warlock", kPlatformMacintosh, "WARLOCKSHIP/WARLOCKSHIP/UpForeECall", kFrameScript, 12,
+ {"warlock", kPlatformMacintosh, "WARLOCKSHIP/WARLOCKSHIP/UpForeECall", kScoreScript, 12,
2, "SS Warlock:DATA:WARLOCKSHIP:Up.GCGunner", ""},
- {"warlock", kPlatformMacintosh, "WARLOCKSHIP/WARLOCKSHIP/UpForeECall", kFrameScript, 12,
+ {"warlock", kPlatformMacintosh, "WARLOCKSHIP/WARLOCKSHIP/UpForeECall", kScoreScript, 12,
3, "Channels 17 to 18", ""},
- {"warlock", kPlatformMacintosh, "WARLOCKSHIP/WARLOCKSHIP/UpForeECall", kFrameScript, 12,
+ {"warlock", kPlatformMacintosh, "WARLOCKSHIP/WARLOCKSHIP/UpForeECall", kScoreScript, 12,
4, "Frames 150 to 160", ""},
// Unbalanced 'end if' at the end of the script
@@ -52,11 +52,11 @@ struct ScriptPatch {
5, "end if", ""},
// Garbage at end of script
- {"warlock", kPlatformWindows, "WRLCKSHP/UpForeECall", kFrameScript, 12,
+ {"warlock", kPlatformWindows, "WRLCKSHP/UpForeECall", kScoreScript, 12,
2, "SS Warlock:DATA:WARLOCKSHIP:Up.GCGunner", ""},
- {"warlock", kPlatformWindows, "WRLCKSHP/UpForeECall", kFrameScript, 12,
+ {"warlock", kPlatformWindows, "WRLCKSHP/UpForeECall", kScoreScript, 12,
3, "Channels 17 to 18", ""},
- {"warlock", kPlatformWindows, "WRLCKSHP/UpForeECall", kFrameScript, 12,
+ {"warlock", kPlatformWindows, "WRLCKSHP/UpForeECall", kScoreScript, 12,
4, "Frames 150 to 160", ""},
// Unbalanced 'end if' at the end of the script
@@ -65,7 +65,7 @@ struct ScriptPatch {
// Unbalanced 'end if' at the end of the script
- {"jman", kPlatformWindows, "mmm/TSA RR 06", kFrameScript, 26,
+ {"jman", kPlatformWindows, "mmm/TSA RR 06", kScoreScript, 26,
17, "end if", ""},
{nullptr, kPlatformUnknown, nullptr, kNoneScript, 0, 0, nullptr, nullptr}
diff --git a/engines/director/lingo/lingo-the.cpp b/engines/director/lingo/lingo-the.cpp
index a5aace3e5f..68837cc305 100644
--- a/engines/director/lingo/lingo-the.cpp
+++ b/engines/director/lingo/lingo-the.cpp
@@ -1088,7 +1088,7 @@ void Lingo::setTheCast(Datum &id1, int field, Datum &d) {
return;
}
// FIXME: What if the cast member is in a different archive than the current one?
- addCode(d.u.s->c_str(), _archiveIndex, kSpriteScript, id);
+ addCode(d.u.s->c_str(), _archiveIndex, kCastScript, id);
castInfo->script = d.asString();
break;
diff --git a/engines/director/lingo/lingo.cpp b/engines/director/lingo/lingo.cpp
index 23a6f497d0..a1a1f6c321 100644
--- a/engines/director/lingo/lingo.cpp
+++ b/engines/director/lingo/lingo.cpp
@@ -370,10 +370,10 @@ ScriptContext *Lingo::addCode(const char *code, int archiveIndex, ScriptType typ
currentFunc.u.defn = _currentAssembly;
// guess the name. don't actually bind it to the event, there's a seperate
// triggering mechanism for that.
- if (type == kFrameScript) {
- currentFunc.name = new Common::String("enterFrame");
- } else if (type == kSpriteScript) {
- currentFunc.name = new Common::String("mouseUp");
+ if (type == kScoreScript) {
+ currentFunc.name = new Common::String("[score script]");
+ } else if (type == kCastScript) {
+ currentFunc.name = new Common::String("[cast script");
} else {
currentFunc.name = new Common::String("[unknown]");
}
@@ -1023,9 +1023,9 @@ void Lingo::executeImmediateScripts(Frame *frame) {
// From D5 only explicit event handlers are processed
// Before that you could specify commands which will be executed on mouse up
if (_vm->getVersion() < 5)
- g_lingo->processEvent(kEventNone, kFrameScript, frame->_sprites[i]->_scriptId, i);
+ g_lingo->processEvent(kEventNone, kScoreScript, frame->_sprites[i]->_scriptId, i);
else
- g_lingo->processEvent(kEventMouseUp, kFrameScript, frame->_sprites[i]->_scriptId, i);
+ g_lingo->processEvent(kEventMouseUp, kScoreScript, frame->_sprites[i]->_scriptId, i);
}
}
}
diff --git a/engines/director/score-loading.cpp b/engines/director/score-loading.cpp
index 4151984369..18f7acd2fa 100644
--- a/engines/director/score-loading.cpp
+++ b/engines/director/score-loading.cpp
@@ -44,8 +44,6 @@ namespace Director {
const char *scriptTypes[] = {
"MovieScript",
- "SpriteScript",
- "FrameScript",
"CastScript",
"GlobalScript",
"ScoreScript"
@@ -1002,7 +1000,7 @@ void Score::loadActions(Common::SeekableSubReadStreamEndian &stream) {
if (ConfMan.getBool("dump_scripts"))
for (j = _actions.begin(); j != _actions.end(); ++j) {
if (!j->_value.empty())
- dumpScript(j->_value.c_str(), kFrameScript, j->_key);
+ dumpScript(j->_value.c_str(), kScoreScript, j->_key);
}
for (j = _actions.begin(); j != _actions.end(); ++j) {
@@ -1011,7 +1009,7 @@ void Score::loadActions(Common::SeekableSubReadStreamEndian &stream) {
// continue;
}
if (!j->_value.empty()) {
- _lingo->addCode(j->_value.c_str(), _lingoArchive, kFrameScript, j->_key);
+ _lingo->addCode(j->_value.c_str(), _lingoArchive, kScoreScript, j->_key);
processImmediateFrameScript(j->_value, j->_key);
}
@@ -1125,10 +1123,10 @@ void Score::loadCastInfo(Common::SeekableSubReadStreamEndian &stream, uint16 id)
ci->script = castStrings[0];
if (!ci->script.empty() && ConfMan.getBool("dump_scripts"))
- dumpScript(ci->script.c_str(), kSpriteScript, id);
+ dumpScript(ci->script.c_str(), kCastScript, id);
if (!ci->script.empty())
- _lingo->addCode(ci->script.c_str(), _lingoArchive, kSpriteScript, id);
+ _lingo->addCode(ci->script.c_str(), _lingoArchive, kCastScript, id);
ci->name = getString(castStrings[1]);
ci->directory = getString(castStrings[2]);
diff --git a/engines/director/types.h b/engines/director/types.h
index 34367fabb1..5b332fd6d0 100644
--- a/engines/director/types.h
+++ b/engines/director/types.h
@@ -44,12 +44,10 @@ enum CastType {
enum ScriptType {
kNoneScript = -1,
kMovieScript = 0,
- kSpriteScript = 1,
- kFrameScript = 2,
- kCastScript = 3,
- kGlobalScript = 4,
- kScoreScript = 5,
- kMaxScriptType = 5 // Sync with score.cpp:45, array scriptTypes[]
+ kCastScript = 1,
+ kGlobalScript = 2,
+ kScoreScript = 3,
+ kMaxScriptType = 3 // Sync with score.cpp:45, array scriptTypes[]
};
enum ShapeType {
diff --git a/engines/director/util.cpp b/engines/director/util.cpp
index 619a17fcbb..c79c51602c 100644
--- a/engines/director/util.cpp
+++ b/engines/director/util.cpp
@@ -522,15 +522,9 @@ Common::String dumpScriptName(const char *prefix, int type, int id, const char *
case kNoneScript:
default:
error("dumpScriptName(): Incorrect call (type %d)", type);
- case kFrameScript:
- typeName = "frame";
- break;
case kMovieScript:
typeName = "movie";
break;
- case kSpriteScript:
- typeName = "sprite";
- break;
case kCastScript:
typeName = "cast";
break;
Commit: 8db0405d31b1ee74087b42cb2dac1bf1df80d667
https://github.com/scummvm/scummvm/commit/8db0405d31b1ee74087b42cb2dac1bf1df80d667
Author: djsrv (dservilla at gmail.com)
Date: 2020-06-17T20:38:49-04:00
Commit Message:
DIRECTOR: Load D4 cast scripts
Changed paths:
engines/director/score-loading.cpp
diff --git a/engines/director/score-loading.cpp b/engines/director/score-loading.cpp
index 18f7acd2fa..15247b3ae7 100644
--- a/engines/director/score-loading.cpp
+++ b/engines/director/score-loading.cpp
@@ -880,15 +880,16 @@ void Score::loadCastData(Common::SeekableSubReadStreamEndian &stream, uint16 id,
}
} else {
if (!ci->script.empty()) {
+ ScriptType scriptType = kCastScript;
+ // the script type here could be wrong!
if (member->_type == kCastLingoScript) {
- // the script type here could be wrong!
- if (ConfMan.getBool("dump_scripts"))
- dumpScript(ci->script.c_str(), ((ScriptCast *)member)->_scriptType, id);
-
- _lingo->addCode(ci->script.c_str(), _lingoArchive, ((ScriptCast *)member)->_scriptType, id);
- } else {
- warning("Score::loadCastData(): Wrong cast type: %d", member->_type);
+ scriptType = ((ScriptCast *)member)->_scriptType;
}
+
+ if (ConfMan.getBool("dump_scripts"))
+ dumpScript(ci->script.c_str(), scriptType, id);
+
+ _lingo->addCode(ci->script.c_str(), _lingoArchive, scriptType, id);
}
}
Commit: af62c56624d214d6772a3172df99c8d1f245c1ad
https://github.com/scummvm/scummvm/commit/af62c56624d214d6772a3172df99c8d1f245c1ad
Author: djsrv (dservilla at gmail.com)
Date: 2020-06-17T20:38:49-04:00
Commit Message:
DIRECTOR: Consider sprites with CastScripts active
Changed paths:
engines/director/sprite.cpp
diff --git a/engines/director/sprite.cpp b/engines/director/sprite.cpp
index 01a0f8eb6d..a06d225b9e 100644
--- a/engines/director/sprite.cpp
+++ b/engines/director/sprite.cpp
@@ -22,6 +22,7 @@
#include "director/director.h"
#include "director/cast.h"
+#include "director/lingo/lingo.h"
#include "director/sprite.h"
#include "director/score.h"
@@ -108,7 +109,14 @@ bool Sprite::isDirty() {
}
bool Sprite::isActive() {
- return _moveable || _puppet || _scriptId;
+ if (_moveable || _puppet || _scriptId)
+ return true;
+
+ if (g_lingo->getScriptContext(kArchMain, kCastScript, _castId)
+ || g_lingo->getScriptContext(kArchShared, kCastScript, _castId))
+ return true;
+
+ return false;
}
void Sprite::setClean() {
Commit: 612104336fd7844b39049cc0a48dfa77895cd6da
https://github.com/scummvm/scummvm/commit/612104336fd7844b39049cc0a48dfa77895cd6da
Author: djsrv (dservilla at gmail.com)
Date: 2020-06-17T20:38:49-04:00
Commit Message:
DIRECTOR: LINGO: Rework event handling
Setup for proper event delegation. It probably needs adjustments but
it should be mostly correct for D4.
Changed paths:
engines/director/events.cpp
engines/director/lingo/lingo-builtins.cpp
engines/director/lingo/lingo-bytecode.cpp
engines/director/lingo/lingo-codegen.cpp
engines/director/lingo/lingo-events.cpp
engines/director/lingo/lingo.cpp
engines/director/lingo/lingo.h
engines/director/score.cpp
diff --git a/engines/director/events.cpp b/engines/director/events.cpp
index 557ef9dc6a..9d3e84f1c1 100644
--- a/engines/director/events.cpp
+++ b/engines/director/events.cpp
@@ -108,7 +108,7 @@ void DirectorEngine::processEvents(bool bufferLingoEvents) {
sc->_lastClickTime = sc->_lastEventTime;
debugC(3, kDebugEvents, "event: Button Down @(%d, %d), sprite id: %d", pos.x, pos.y, spriteId);
- _lingo->registerEvent(kEventMouseDown);
+ _lingo->registerEvent(kEventMouseDown, spriteId);
if (sc->getSpriteById(spriteId)->_moveable)
g_director->setDraggedSprite(spriteId);
@@ -136,7 +136,7 @@ void DirectorEngine::processEvents(bool bufferLingoEvents) {
cast->_hilite = !cast->_hilite;
}
- _lingo->registerEvent(kEventMouseUp);
+ _lingo->registerEvent(kEventMouseUp, spriteId);
sc->_currentMouseDownSpriteId = 0;
break;
diff --git a/engines/director/lingo/lingo-builtins.cpp b/engines/director/lingo/lingo-builtins.cpp
index dfef2c5cdb..30f18c855c 100644
--- a/engines/director/lingo/lingo-builtins.cpp
+++ b/engines/director/lingo/lingo-builtins.cpp
@@ -520,7 +520,7 @@ void LB::b_value(int nargs) {
Common::String code = "scummvm_returnNumber " + expr;
// Compile the code to an anonymous function and call it
ScriptContext *sc = g_lingo->addCode(code.c_str(), kArchNone, kNoneScript, 0);
- Symbol sym = sc->functions[0];
+ Symbol sym = sc->eventHandlers[kEventNone];
LC::call(sym, 0);
delete sc;
}
diff --git a/engines/director/lingo/lingo-bytecode.cpp b/engines/director/lingo/lingo-bytecode.cpp
index d2dc160b25..f15c92101d 100644
--- a/engines/director/lingo/lingo-bytecode.cpp
+++ b/engines/director/lingo/lingo-bytecode.cpp
@@ -741,7 +741,6 @@ void Lingo::addCodeV4(Common::SeekableSubReadStreamEndian &stream, int archiveIn
_assemblyArchive = archiveIndex;
_assemblyContext = new ScriptContext;
- _currentEntityId = id;
_archives[_assemblyArchive].scriptContexts[type][id] = _assemblyContext;
if (stream.size() < 0x5c) {
diff --git a/engines/director/lingo/lingo-codegen.cpp b/engines/director/lingo/lingo-codegen.cpp
index 1b61c5f84f..76b6c284ed 100644
--- a/engines/director/lingo/lingo-codegen.cpp
+++ b/engines/director/lingo/lingo-codegen.cpp
@@ -98,8 +98,9 @@ Symbol Lingo::define(Common::String &name, int nargs, ScriptData *code, Common::
if (!_eventHandlerTypeIds.contains(name)) {
_archives[_assemblyArchive].functionHandlers[name] = sym;
+ _assemblyContext->functionHandlers[name] = sym;
} else {
- _archives[_assemblyArchive].eventHandlers[ENTITY_INDEX(_eventHandlerTypeIds[name], _currentEntityId)] = sym;
+ _assemblyContext->eventHandlers[_eventHandlerTypeIds[name]] = sym;
}
}
@@ -107,9 +108,8 @@ Symbol Lingo::define(Common::String &name, int nargs, ScriptData *code, Common::
}
Symbol Lingo::codeDefine(Common::String &name, int start, int nargs, Object *factory, int end, bool removeCode) {
- debugC(1, kDebugCompile, "codeDefine(\"%s\"(len: %d), %d, %d, \"%s\", %d) entity: %d",
- name.c_str(), _currentAssembly->size() - 1, start, nargs, (factory ? factory->name->c_str() : ""),
- end, _currentEntityId);
+ debugC(1, kDebugCompile, "codeDefine(\"%s\"(len: %d), %d, %d, \"%s\", %d)",
+ name.c_str(), _currentAssembly->size() - 1, start, nargs, (factory ? factory->name->c_str() : ""), end);
if (end == -1)
end = _currentAssembly->size();
diff --git a/engines/director/lingo/lingo-events.cpp b/engines/director/lingo/lingo-events.cpp
index 8ab93ca4fd..afaa93c32c 100644
--- a/engines/director/lingo/lingo-events.cpp
+++ b/engines/director/lingo/lingo-events.cpp
@@ -114,26 +114,26 @@ void Lingo::primaryEventHandler(LEvent event) {
* the message by including the dontPassEventCommand in the script
* [D4 docs page 77]
*/
- debugC(3, kDebugLingoExec, "calling primary event handler (%s)", _eventHandlerTypes[event]);
+ /* N.B.: No primary event handlers for events other than
+ * keyup, keydown, mouseup, mousedown, timeout
+ * [see: www.columbia.edu/itc/visualarts/r4110/s2001/handouts
+ * /03_03_Event_Hierarchy.pdf]
+ */
switch (event) {
case kEventMouseDown:
case kEventMouseUp:
case kEventKeyUp:
case kEventKeyDown:
case kEventTimeout:
- executeScript(kGlobalScript, event, 0);
+ debugC(3, kDebugLingoExec, "calling primary event handler (%s)", _eventHandlerTypes[event]);
+ executeScript(kGlobalScript, event);
break;
default:
- /* N.B.: No primary event handlers for events other than
- * keyup, keydown, mouseup, mousedown, timeout
- * [see: www.columbia.edu/itc/visualarts/r4110/s2001/handouts
- * /03_03_Event_Hierarchy.pdf]
- */
- warning("primaryEventHandler() on event other than mouseDown, mouseUp, keyUp, keyDown, timeout");
+ break;
}
}
-void Lingo::registerInputEvent(LEvent event) {
+void Lingo::registerSpriteEvent(LEvent event, int spriteId) {
/* When the mouseDown or mouseUp occurs over a sprite, the message
* goes first to the sprite script, then to the script of the cast
* member, to the frame script and finally to the movie scripts.
@@ -147,64 +147,41 @@ void Lingo::registerInputEvent(LEvent event) {
Score *score = _vm->getCurrentScore();
Frame *currentFrame = score->_frames[score->getCurrentFrame()];
assert(currentFrame != nullptr);
- uint16 spriteId = score->_currentMouseDownSpriteId;
Sprite *sprite = score->getSpriteById(spriteId);
- primaryEventHandler(event);
-
- if (_dontPassEvent) {
- _dontPassEvent = false;
-
- return;
- }
-
- if (_vm->getVersion() > 3) {
- if (true) {
- // TODO: Check whether occurring over a sprite
- _eventQueue.push(LingoEvent(event, kScoreScript, sprite->_scriptId));
- }
- _eventQueue.push(LingoEvent(event, kCastScript, sprite->_castId));
- _eventQueue.push(LingoEvent(event, kScoreScript, currentFrame->_actionId));
- // TODO: Is the kFrameScript call above correct?
- } else if (event == kEventMouseDown || event == kEventMouseUp) {
- // If sprite is immediate, its script is run on mouseDown, otherwise on mouseUp
- bool queueEventNone = false;
- if (event == kEventMouseDown && sprite->_immediate) {
- queueEventNone = true;
- } else if (event == kEventMouseUp && !sprite->_immediate) {
- queueEventNone = true;
- }
-
- // Score (sprite) script overrides cast script
- if (sprite->_scriptId) {
- if (queueEventNone)
- _eventQueue.push(LingoEvent(kEventNone, kScoreScript, sprite->_scriptId, spriteId));
+ // Sprite (score) script
+ if (sprite->_scriptId) {
+ if (_vm->getVersion() <= 3) {
+ // In D3 the event lingo is not contained in a handler
+ // If sprite is immediate, its script is run on mouseDown, otherwise on mouseUp
+ if ((event == kEventMouseDown && sprite->_immediate)
+ || (event == kEventMouseUp && !sprite->_immediate)) {
+ _eventQueue.push(LingoEvent(kEventNone, kArchMain, kScoreScript, sprite->_scriptId, spriteId));
+ return;
+ }
} else {
- if (queueEventNone)
- _eventQueue.push(LingoEvent(kEventNone, kCastScript, sprite->_castId));
- _eventQueue.push(LingoEvent(event, kCastScript, sprite->_castId));
+ ScriptContext *script = getScriptContext(kArchMain, kScoreScript, sprite->_scriptId);
+ if (script && script->eventHandlers.contains(event)) {
+ _eventQueue.push(LingoEvent(event, kArchMain, kScoreScript, sprite->_scriptId, spriteId));
+ return;
+ }
}
}
- runMovieScript(event);
-}
-
-void Lingo::runMovieScript(LEvent event) {
- /* If more than one movie script handles the same message, Lingo
- * searches the movie scripts according to their order in the cast
- * window [p.81 of D4 docs]
- */
-
- if (_dontPassEvent)
+ // Cast script
+ int archiveIndex = kArchMain;
+ ScriptContext *script = getScriptContext(archiveIndex, kCastScript, sprite->_castId);
+ if (!script) {
+ archiveIndex = kArchShared;
+ script = getScriptContext(archiveIndex, kCastScript, sprite->_castId);
+ }
+ if (script && script->eventHandlers.contains(event)) {
+ _eventQueue.push(LingoEvent(event, archiveIndex, kCastScript, sprite->_castId, spriteId));
return;
-
- for (ScriptContextHash::iterator it = _archives[_archiveIndex].scriptContexts[kMovieScript].begin();
- it != _archives[_archiveIndex].scriptContexts[kMovieScript].end(); ++it) {
- if (_archives[_archiveIndex].eventHandlers.contains(ENTITY_INDEX(event, it->_key))) {
- _eventQueue.push(LingoEvent(event, kMovieScript, it->_key));
- break;
- }
}
+
+ // Delegate to the frame
+ registerFrameEvent(event);
}
void Lingo::registerFrameEvent(LEvent event) {
@@ -214,66 +191,72 @@ void Lingo::registerFrameEvent(LEvent event) {
* message goes to movie scripts.
* [p.81 of D4 docs]
*/
- // TODO: Same for D2-3 or not?
+
Score *score = _vm->getCurrentScore();
- if (event == kEventTimeout) {
- primaryEventHandler(event);
- }
+ // if (event == kEventPrepareFrame || event == kEventIdle) {
+ // entity = score->getCurrentFrame();
+ // } else {
- if (_dontPassEvent) {
- _dontPassEvent = false;
+ assert(score->_frames[score->getCurrentFrame()] != nullptr);
+ int scriptId = score->_frames[score->getCurrentFrame()]->_actionId;
+ if (scriptId) {
+ _eventQueue.push(LingoEvent(event, kArchMain, kScoreScript, scriptId));
return;
}
- int entity;
+ // Delegate to the movie
+ registerMovieEvent(event);
+}
- if (event == kEventPrepareFrame || event == kEventIdle) {
- entity = score->getCurrentFrame();
- } else {
- assert(score->_frames[score->getCurrentFrame()] != nullptr);
- entity = score->_frames[score->getCurrentFrame()]->_actionId;
- }
- _eventQueue.push(LingoEvent(event, kScoreScript, entity));
+void Lingo::registerMovieEvent(LEvent event) {
+ /* If more than one movie script handles the same message, Lingo
+ * searches the movie scripts according to their order in the cast
+ * window [p.81 of D4 docs]
+ */
- runMovieScript(event);
-}
+ if (event == kEventNone)
+ return;
-void Lingo::registerGenericEvent(LEvent event) {
- // Movie Script
- if (event == kEventStart || event == kEventStartUp || event == kEventPrepareMovie ||
- event == kEventStartMovie || event == kEventStopMovie)
- ; // we're OK
- else
- warning("STUB: processGenericEvent called for unprocessed event, additional logic probably needed");
+ // FIXME: shared cast movie scripts could come before main movie ones
+ for (ScriptContextHash::iterator it = _archives[kArchMain].scriptContexts[kMovieScript].begin();
+ it != _archives[kArchMain].scriptContexts[kMovieScript].end(); ++it) {
+ if (it->_value->eventHandlers.contains(event)) {
+ _eventQueue.push(LingoEvent(event, kArchMain, kMovieScript, it->_key));
+ return;
+ }
+ }
+ for (ScriptContextHash::iterator it = _archives[kArchShared].scriptContexts[kMovieScript].begin();
+ it != _archives[kArchShared].scriptContexts[kMovieScript].end(); ++it) {
+ if (it->_value->eventHandlers.contains(event)) {
+ _eventQueue.push(LingoEvent(event, kArchShared, kMovieScript, it->_key));
+ return;
+ }
+ }
- runMovieScript(event);
+ debugC(9, kDebugEvents, "Lingo::registerEvent(%s): no handler", _eventHandlerTypes[event]);
}
-void Lingo::registerSpriteEvent(LEvent event) {
- Score *score = _vm->getCurrentScore();
- Frame *currentFrame = score->_frames[score->getCurrentFrame()];
- if (event == kEventBeginSprite) {
- // TODO: Check if this is also possibly a kSpriteScript?
- for (uint16 i = 0; i <= score->_numChannelsDisplayed; i++)
- if (currentFrame->_sprites[i]->_enabled)
- _eventQueue.push(LingoEvent(event, kCastScript, currentFrame->_sprites[i]->_scriptId));
+void Lingo::registerEvent(LEvent event, int spriteId) {
+ primaryEventHandler(event);
- } else {
- warning("STUB: processSpriteEvent called for something else than kEventBeginSprite, additional logic probably needed");
+ if (_dontPassEvent) {
+ _dontPassEvent = false;
+ return;
}
-}
-
-void Lingo::registerEvent(LEvent event) {
switch (event) {
case kEventKeyUp:
case kEventKeyDown:
case kEventMouseUp:
case kEventMouseDown:
- registerInputEvent(event);
- break;
+ case kEventBeginSprite:
+ if (spriteId) {
+ registerSpriteEvent(event, spriteId);
+ break;
+ }
+ // fall through
case kEventIdle:
case kEventEnterFrame:
@@ -288,21 +271,16 @@ void Lingo::registerEvent(LEvent event) {
case kEventStopMovie:
case kEventTimeout:
case kEventPrepareMovie:
- registerGenericEvent(event);
- break;
- case kEventBeginSprite:
- registerSpriteEvent(event);
+ registerMovieEvent(event);
break;
default:
warning("registerEvent: Unhandled event %s", _eventHandlerTypes[event]);
}
-
- _dontPassEvent = false;
}
-void Lingo::processEvent(LEvent event) {
- registerEvent(event);
+void Lingo::processEvent(LEvent event, int spriteId) {
+ registerEvent(event, spriteId);
processEvents();
}
@@ -313,34 +291,24 @@ void Lingo::processEvents() {
if (_vm->getCurrentScore()->_stopPlay && el.event != kEventStopMovie)
continue;
- processEvent(el.event, el.st, el.entityId, el.channelId);
+ processEvent(el.event, el.archiveIndex, el.st, el.scriptId, el.channelId);
}
}
-void Lingo::processEvent(LEvent event, ScriptType st, int entityId, int channelId) {
- if (entityId < 0)
- return;
-
- if (_dontPassEvent)
- return;
-
- _currentEntityId = entityId;
+void Lingo::processEvent(LEvent event, int archiveIndex, ScriptType st, int scriptId, int channelId) {
_currentChannelId = channelId;
if (!_eventHandlerTypes.contains(event))
- error("processEvent: Unknown event %d for entity %d", event, entityId);
-
- if (_archives[kArchMain].eventHandlers.contains(ENTITY_INDEX(event, entityId)) ||
- _archives[kArchShared].eventHandlers.contains(ENTITY_INDEX(event, entityId))) {
- // handler
- debugC(1, kDebugEvents, "Lingo::processEvent(%s, %s, %d): executing event handler", _eventHandlerTypes[event], scriptType2str(st), entityId);
- executeHandler(_eventHandlerTypes[event]);
- } else if (_vm->getVersion() < 4 && event == kEventNone && getScriptContext(_archiveIndex, st, entityId)) {
- // script (D3)
- debugC(1, kDebugEvents, "Lingo::processEvent(%s, %s, %d): executing event script", _eventHandlerTypes[event], scriptType2str(st), entityId);
- executeScript(st, entityId, 0);
+ error("processEvent: Unknown event %d", event);
+
+ ScriptContext *script = getScriptContext(archiveIndex, st, scriptId);
+
+ if (script && script->eventHandlers.contains(event)) {
+ debugC(1, kDebugEvents, "Lingo::processEvent(%s, %d, %s, %d): executing event handler", _eventHandlerTypes[event], archiveIndex, scriptType2str(st), scriptId);
+ LC::call(script->eventHandlers[event], 0);
+ execute(_pc);
} else {
- debugC(9, kDebugEvents, "Lingo::processEvent(%s, %s, %d): no handler", _eventHandlerTypes[event], scriptType2str(st), entityId);
+ debugC(9, kDebugEvents, "Lingo::processEvent(%s, %d, %s, %d): no handler", _eventHandlerTypes[event], archiveIndex, scriptType2str(st), scriptId);
}
}
diff --git a/engines/director/lingo/lingo.cpp b/engines/director/lingo/lingo.cpp
index a1a1f6c321..5ce1a4131a 100644
--- a/engines/director/lingo/lingo.cpp
+++ b/engines/director/lingo/lingo.cpp
@@ -132,7 +132,6 @@ Lingo::Lingo(DirectorEngine *vm) : _vm(vm) {
_currentAssembly = nullptr;
_assemblyContext = nullptr;
- _currentEntityId = 0;
_currentChannelId = -1;
_pc = 0;
_abort = false;
@@ -215,16 +214,6 @@ Symbol Lingo::getHandler(const Common::String &name) {
return result;
}
-
- uint32 entityIndex = ENTITY_INDEX(_eventHandlerTypeIds[name], _currentEntityId);
- // local scripts
- if (_archives[kArchMain].eventHandlers.contains(entityIndex))
- return _archives[kArchMain].eventHandlers[entityIndex];
-
- // shared scripts
- if (_archives[kArchShared].eventHandlers.contains(entityIndex))
- return _archives[kArchShared].eventHandlers[entityIndex];
-
return result;
}
@@ -279,7 +268,6 @@ ScriptContext *Lingo::addCode(const char *code, int archiveIndex, ScriptType typ
_assemblyArchive = archiveIndex;
ScriptContext *sc = _assemblyContext = new ScriptContext;
_currentAssembly = new ScriptData;
- _currentEntityId = id;
if (archiveIndex >= 0)
_archives[_assemblyArchive].scriptContexts[type][id] = _assemblyContext;
@@ -408,7 +396,7 @@ ScriptContext *Lingo::addCode(const char *code, int archiveIndex, ScriptType typ
currentFunc.argNames = argNames;
currentFunc.varNames = varNames;
- _assemblyContext->functions.push_back(currentFunc);
+ _assemblyContext->eventHandlers[kEventNone] = currentFunc;
_assemblyContext = nullptr;
_currentAssembly = nullptr;
return sc;
@@ -577,21 +565,17 @@ void Lingo::execute(uint pc) {
_abort = false;
}
-void Lingo::executeScript(ScriptType type, uint16 id, uint16 function) {
+void Lingo::executeScript(ScriptType type, uint16 id) {
ScriptContext *sc = getScriptContext(_archiveIndex, type, id);
if (!sc) {
debugC(3, kDebugLingoExec, "Request to execute non-existant script type %d id %d", type, id);
return;
}
- if (function >= sc->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, function: %d", scriptType2str(type), id, function);
+ debugC(1, kDebugLingoExec, "Executing script type: %s, id: %d", scriptType2str(type), id);
- Symbol sym = sc->functions[function];
+ Symbol sym = sc->eventHandlers[kEventNone];
LC::call(sym, 0);
execute(_pc);
}
@@ -613,7 +597,8 @@ void Lingo::restartLingo(bool keepSharedCast) {
LingoArchive *arch = &_archives[a];
for (int i = 0; i <= kMaxScriptType; i++) {
for (ScriptContextHash::iterator it = arch->scriptContexts[i].begin(); it != arch->scriptContexts[i].end(); ++it) {
- it->_value->functions.clear();
+ it->_value->eventHandlers.clear();
+ it->_value->functionHandlers.clear();
delete it->_value;
}
@@ -621,7 +606,6 @@ void Lingo::restartLingo(bool keepSharedCast) {
}
arch->names.clear();
- arch->eventHandlers.clear();
arch->functionHandlers.clear();
}
@@ -1003,7 +987,7 @@ void Lingo::runTests() {
if (!debugChannelSet(-1, kDebugCompileOnly)) {
if (!_hadError)
- executeScript(kMovieScript, counter, 0);
+ executeScript(kMovieScript, counter);
else
debug(">> Skipping execution");
}
@@ -1023,9 +1007,9 @@ void Lingo::executeImmediateScripts(Frame *frame) {
// From D5 only explicit event handlers are processed
// Before that you could specify commands which will be executed on mouse up
if (_vm->getVersion() < 5)
- g_lingo->processEvent(kEventNone, kScoreScript, frame->_sprites[i]->_scriptId, i);
+ g_lingo->processEvent(kEventNone, kArchMain, kScoreScript, frame->_sprites[i]->_scriptId, i);
else
- g_lingo->processEvent(kEventMouseUp, kScoreScript, frame->_sprites[i]->_scriptId, i);
+ g_lingo->processEvent(kEventMouseUp, kArchMain, kScoreScript, frame->_sprites[i]->_scriptId, i);
}
}
}
diff --git a/engines/director/lingo/lingo.h b/engines/director/lingo/lingo.h
index 0cc68c991a..4fae571de7 100644
--- a/engines/director/lingo/lingo.h
+++ b/engines/director/lingo/lingo.h
@@ -204,11 +204,6 @@ struct Builtin {
Builtin(void (*func1)(void), int nargs1) : func(func1), nargs(nargs1) {}
};
-struct ScriptContext {
- Common::Array<Symbol> functions;
- Common::Array<Datum> constants;
-};
-
typedef Common::HashMap<int32, ScriptContext *> ScriptContextHash;
typedef Common::Array<Datum> StackData;
typedef Common::HashMap<Common::String, Symbol, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> SymbolHash;
@@ -218,6 +213,13 @@ typedef Common::HashMap<Common::String, Builtin *, Common::IgnoreCase_Hash, Comm
typedef Common::HashMap<Common::String, TheEntity *, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> TheEntityHash;
typedef Common::HashMap<Common::String, TheEntityField *, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> TheEntityFieldHash;
+struct ScriptContext {
+ Common::Array<Symbol> functions; // used only by bytecode
+ Common::HashMap<uint32, Symbol> eventHandlers;
+ SymbolHash functionHandlers;
+ Common::Array<Datum> constants;
+};
+
enum ObjectType {
kNoneObj = 0,
kFactoryObj = 1 << 0,
@@ -278,14 +280,16 @@ struct CFrame { /* proc/func call stack frame */
struct LingoEvent {
LEvent event;
+ int archiveIndex;
ScriptType st;
- int entityId;
+ int scriptId;
int channelId;
- LingoEvent (LEvent e, ScriptType s, int ei, int ci = -1) {
+ LingoEvent (LEvent e, int ai, ScriptType s, int si, int ci = -1) {
event = e;
+ archiveIndex = ai;
st = s;
- entityId = ei;
+ scriptId = si;
channelId = ci;
}
};
@@ -294,7 +298,6 @@ struct LingoEvent {
struct LingoArchive {
ScriptContextHash scriptContexts[kMaxScriptType + 1];
Common::Array<Common::String> names;
- Common::HashMap<uint32, Symbol> eventHandlers;
Common::HashMap<uint32, Common::String> primaryEventHandlers;
SymbolHash functionHandlers;
};
@@ -316,7 +319,7 @@ public:
void addCodeV4(Common::SeekableSubReadStreamEndian &stream, int archiveIndex, ScriptType type, uint16 id, Common::String &archName);
void addNamesV4(Common::SeekableSubReadStreamEndian &stream, int archiveIndex);
void executeHandler(const Common::String &name);
- void executeScript(ScriptType type, uint16 id, uint16 function);
+ void executeScript(ScriptType type, uint16 id);
void printStack(const char *s, uint pc);
void printCallStack(uint pc);
Common::String decodeInstruction(ScriptData *sd, uint pc, uint *newPC = NULL);
@@ -347,12 +350,10 @@ private:
void initEventHandlerTypes();
void setPrimaryEventHandler(LEvent event, const Common::String &code);
void primaryEventHandler(LEvent event);
- void registerInputEvent(LEvent event);
+ void registerSpriteEvent(LEvent event, int spriteId);
void registerFrameEvent(LEvent event);
- void registerGenericEvent(LEvent event);
- void runMovieScript(LEvent event);
- void registerSpriteEvent(LEvent event);
- void processEvent(LEvent event, ScriptType st, int entityId, int channelId = -1);
+ void registerMovieEvent(LEvent event);
+ void processEvent(LEvent event, int archiveIndex, ScriptType st, int entityId, int channelId = -1);
Common::Queue<LingoEvent> _eventQueue;
@@ -363,9 +364,9 @@ public:
Symbol getHandler(const Common::String &name);
int getEventCount();
- void processEvent(LEvent event);
+ void processEvent(LEvent event, int spriteId = 0);
void processEvents();
- void registerEvent(LEvent event);
+ void registerEvent(LEvent event, int spriteId = 0);
public:
void execute(uint pc);
diff --git a/engines/director/score.cpp b/engines/director/score.cpp
index a3ed671ad2..cbc89f11e3 100644
--- a/engines/director/score.cpp
+++ b/engines/director/score.cpp
@@ -106,7 +106,7 @@ Score::Score(DirectorEngine *vm) {
// FIXME: TODO: Check whether the original truely does it
if (_vm->getVersion() <= 3) {
- _lingo->executeScript(kMovieScript, 0, 0);
+ _lingo->executeScript(kMovieScript, 0);
}
_movieScriptCount = 0;
_labels = nullptr;
@@ -484,9 +484,9 @@ void Score::update() {
_lingo->executeImmediateScripts(_frames[_currentFrame]);
if (_vm->getVersion() >= 6) {
- _lingo->processEvent(kEventBeginSprite);
+ // _lingo->processEvent(kEventBeginSprite);
// TODO Director 6 step: send beginSprite event to any sprites whose span begin in the upcoming frame
- _lingo->processEvent(kEventPrepareFrame);
+ // _lingo->processEvent(kEventPrepareFrame);
// TODO: Director 6 step: send prepareFrame event to all sprites and the script channel in upcoming frame
}
More information about the Scummvm-git-logs
mailing list