[Scummvm-git-logs] scummvm master -> 4d9b5212774a7dfcdc09aa9fde6c4b2f503432a4
djsrv
dservilla at gmail.com
Wed Jul 21 22:28:12 UTC 2021
This automated email contains information about 12 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
25318b3298 DIRECTOR: LINGO: Process events at beginning of Lingo::execute loop
e3eae64def DIRECTOR: LINGO: Clean up call stack when aborting execution
dd58b445f2 DIRECTOR: LINGO: Clean up func_goto
6cf6412e0c DIRECTOR: Fix stepMovie version check
fb1e63fc94 DIRECTOR: LINGO: Remove pc arg from Lingo::execute
3c0b31ef97 DIRECTOR: LINGO: Code name arguments as string
8d56798784 DIRECTOR: LINGO: Properly ref count script contexts
2e8d061cc8 DIRECTOR: LINGO: Remove g_lingo->_currentArchive
e2a34fccc1 DIRECTOR: LINGO: Temporarily freeze script context in func_goto
07f8f718c1 DIRECTOR: LINGO: Completely untie script contexts from Lingo archives
89f85abe03 DIRECTOR: LINGO: Fix factory script context name
4d9b521277 DIRECTOR: LINGO: Overwrite factory when already defined
Commit: 25318b3298ac1b10b8a4a1a925ff9041c3e50300
https://github.com/scummvm/scummvm/commit/25318b3298ac1b10b8a4a1a925ff9041c3e50300
Author: djsrv (dservilla at gmail.com)
Date: 2021-07-21T18:27:05-04:00
Commit Message:
DIRECTOR: LINGO: Process events at beginning of Lingo::execute loop
Previously, events may have been processed right before the loop ended,
which is totally unnecessary. If we do it at the beginning, we know we
have at least one instruction left to execute.
Changed paths:
engines/director/lingo/lingo.cpp
diff --git a/engines/director/lingo/lingo.cpp b/engines/director/lingo/lingo.cpp
index 91328bdc26..c1678b38e4 100644
--- a/engines/director/lingo/lingo.cpp
+++ b/engines/director/lingo/lingo.cpp
@@ -403,6 +403,13 @@ void Lingo::execute(uint pc) {
break;
}
+ // process events every so often
+ if (localCounter > 0 && localCounter % 100 == 0) {
+ _vm->processEvents();
+ if (_vm->getCurrentMovie()->getScore()->_playState == kPlayStopped)
+ break;
+ }
+
Common::String instr = decodeInstruction(_currentArchive, _currentScript, _pc);
uint current = _pc;
@@ -429,19 +436,12 @@ void Lingo::execute(uint pc) {
printAllVars();
}
- if (!_abort && _pc >= (*_currentScript).size()) {
- warning("Lingo::execute(): Bad PC (%d)", _pc);
- break;
- }
-
_globalCounter++;
localCounter++;
- // process events every so often
- if (localCounter % 100 == 0) {
- _vm->processEvents();
- if (_vm->getCurrentMovie()->getScore()->_playState == kPlayStopped)
- break;
+ if (!_abort && _pc >= (*_currentScript).size()) {
+ warning("Lingo::execute(): Bad PC (%d)", _pc);
+ break;
}
}
Commit: e3eae64defb8a28c808fefa842b8a24f13ad4cc3
https://github.com/scummvm/scummvm/commit/e3eae64defb8a28c808fefa842b8a24f13ad4cc3
Author: djsrv (dservilla at gmail.com)
Date: 2021-07-21T18:27:05-04:00
Commit Message:
DIRECTOR: LINGO: Clean up call stack when aborting execution
Changed paths:
engines/director/lingo/lingo.cpp
diff --git a/engines/director/lingo/lingo.cpp b/engines/director/lingo/lingo.cpp
index c1678b38e4..d9ee4d1e0b 100644
--- a/engines/director/lingo/lingo.cpp
+++ b/engines/director/lingo/lingo.cpp
@@ -445,6 +445,13 @@ void Lingo::execute(uint pc) {
}
}
+ if (_abort) {
+ // Clean up call stack
+ while (_callstack.size()) {
+ popContext();
+ }
+ }
+
_abort = false;
}
Commit: dd58b445f2b6ea06464f7469b358850910af610c
https://github.com/scummvm/scummvm/commit/dd58b445f2b6ea06464f7469b358850910af610c
Author: djsrv (dservilla at gmail.com)
Date: 2021-07-21T18:27:05-04:00
Commit Message:
DIRECTOR: LINGO: Clean up func_goto
All those returns made things confusing, and _skipFrameAdvance wasn't
getting set when the movie was non-VOID.
Changed paths:
engines/director/lingo/lingo-funcs.cpp
diff --git a/engines/director/lingo/lingo-funcs.cpp b/engines/director/lingo/lingo-funcs.cpp
index d4a93d8134..a4f522b041 100644
--- a/engines/director/lingo/lingo-funcs.cpp
+++ b/engines/director/lingo/lingo-funcs.cpp
@@ -187,6 +187,13 @@ void Lingo::func_goto(Datum &frame, Datum &movie) {
if (!_vm->getCurrentMovie())
return;
+ if (movie.type == VOID && frame.type == VOID)
+ return;
+
+ Score *score = _vm->getCurrentMovie()->getScore();
+
+ _vm->_skipFrameAdvance = true;
+
if (movie.type != VOID) {
Common::String movieFilenameRaw = movie.asString();
Window *stage = _vm->getCurrentWindow();
@@ -194,37 +201,25 @@ void Lingo::func_goto(Datum &frame, Datum &movie) {
if (!stage->setNextMovie(movieFilenameRaw))
return;
- stage->getCurrentMovie()->getScore()->_playState = kPlayStopped;
+ score->_playState = kPlayStopped;
stage->_nextMovie.frameS.clear();
stage->_nextMovie.frameI = -1;
- if (frame.type == VOID)
- return;
-
if (frame.type == STRING) {
stage->_nextMovie.frameS = *frame.u.s;
- return;
+ } else if (frame.type != VOID) {
+ stage->_nextMovie.frameI = frame.asInt();
}
- stage->_nextMovie.frameI = frame.asInt();
-
return;
}
- if (frame.type == VOID)
- return;
-
- _vm->_skipFrameAdvance = true;
-
if (frame.type == STRING) {
- if (_vm->getCurrentMovie())
- _vm->getCurrentMovie()->getScore()->setStartToLabel(*frame.u.s);
- return;
+ score->setStartToLabel(*frame.u.s);
+ } else {
+ score->setCurrentFrame(frame.asInt());
}
-
- if (_vm->getCurrentMovie())
- _vm->getCurrentMovie()->getScore()->setCurrentFrame(frame.asInt());
}
void Lingo::func_gotoloop() {
Commit: 6cf6412e0c670a77f3f59034eea17fc7c1711cd7
https://github.com/scummvm/scummvm/commit/6cf6412e0c670a77f3f59034eea17fc7c1711cd7
Author: djsrv (dservilla at gmail.com)
Date: 2021-07-21T18:27:05-04:00
Commit Message:
DIRECTOR: Fix stepMovie version check
Changed paths:
engines/director/score.cpp
diff --git a/engines/director/score.cpp b/engines/director/score.cpp
index 10e8d6fc3b..2aec497450 100644
--- a/engines/director/score.cpp
+++ b/engines/director/score.cpp
@@ -419,7 +419,7 @@ void Score::update() {
// Enter and exit from previous frame
if (!_vm->_playbackPaused) {
_movie->processEvent(kEventEnterFrame); // Triggers the frame script in D2-3, explicit enterFrame handlers in D4+
- if (_vm->getVersion() == 300) {
+ if (_vm->getVersion() >= 300 && _vm->getVersion() < 400) {
// Movie version of enterFrame, for D3 only. The Lingo Dictionary claims
// "This handler executes before anything else when the playback head moves."
// but this is incorrect. The frame script is executed first.
Commit: fb1e63fc9464c887eca512b1f37c73802d83f48e
https://github.com/scummvm/scummvm/commit/fb1e63fc9464c887eca512b1f37c73802d83f48e
Author: djsrv (dservilla at gmail.com)
Date: 2021-07-21T18:27:05-04:00
Commit Message:
DIRECTOR: LINGO: Remove pc arg from Lingo::execute
This arg should always just be the same as _pc.
Changed paths:
engines/director/lingo/lingo-events.cpp
engines/director/lingo/lingo.cpp
engines/director/lingo/lingo.h
diff --git a/engines/director/lingo/lingo-events.cpp b/engines/director/lingo/lingo-events.cpp
index 9c95044703..fef73ac9a7 100644
--- a/engines/director/lingo/lingo-events.cpp
+++ b/engines/director/lingo/lingo-events.cpp
@@ -353,7 +353,7 @@ void Lingo::processEvent(LEvent event, ScriptType st, CastMemberID scriptId, int
if (script && script->_eventHandlers.contains(event)) {
debugC(1, kDebugEvents, "Lingo::processEvent(%s, %s, %s): executing event handler", _eventHandlerTypes[event], scriptType2str(st), scriptId.asString().c_str());
LC::call(script->_eventHandlers[event], 0, false);
- execute(_pc);
+ execute();
} else {
debugC(9, kDebugEvents, "Lingo::processEvent(%s, %s, %s): no handler", _eventHandlerTypes[event], scriptType2str(st), scriptId.asString().c_str());
}
diff --git a/engines/director/lingo/lingo.cpp b/engines/director/lingo/lingo.cpp
index d9ee4d1e0b..b2a0470879 100644
--- a/engines/director/lingo/lingo.cpp
+++ b/engines/director/lingo/lingo.cpp
@@ -393,10 +393,10 @@ Common::String Lingo::decodeInstruction(LingoArchive *archive, ScriptData *sd, u
return res;
}
-void Lingo::execute(uint pc) {
+void Lingo::execute() {
uint localCounter = 0;
- for (_pc = pc; !_abort && (*_currentScript)[_pc] != STOP;) {
+ while (!_abort && (*_currentScript)[_pc] != STOP) {
if (_globalCounter > 1000 && debugChannelSet(-1, kDebugFewFramesOnly)) {
warning("Lingo::execute(): Stopping due to debug few frames only");
_vm->getCurrentMovie()->getScore()->_playState = kPlayStopped;
@@ -478,14 +478,14 @@ void Lingo::executeScript(ScriptType type, CastMemberID id) {
Symbol sym = sc->_eventHandlers[kEventGeneric];
LC::call(sym, 0, false);
- execute(_pc);
+ execute();
}
void Lingo::executeHandler(const Common::String &name) {
debugC(1, kDebugLingoExec, "Executing script handler : %s", name.c_str());
Symbol sym = getHandler(name);
LC::call(sym, 0, false);
- execute(_pc);
+ execute();
}
void Lingo::lingoError(const char *s, ...) {
@@ -1066,7 +1066,7 @@ void Lingo::executePerFrameHook(int frame, int subframe) {
push(frame);
push(subframe);
LC::call(method, 3, false);
- execute(_pc);
+ execute();
}
}
}
diff --git a/engines/director/lingo/lingo.h b/engines/director/lingo/lingo.h
index 7779bed1f4..304966547c 100644
--- a/engines/director/lingo/lingo.h
+++ b/engines/director/lingo/lingo.h
@@ -284,7 +284,7 @@ public:
void processEvents();
public:
- void execute(uint pc);
+ void execute();
void pushContext(const Symbol funcSym, bool allowRetVal, Datum defaultRetVal);
void popContext();
void cleanLocalVars();
Commit: 3c0b31ef97d32c9c28bad04537fc3a4483cd0cb0
https://github.com/scummvm/scummvm/commit/3c0b31ef97d32c9c28bad04537fc3a4483cd0cb0
Author: djsrv (dservilla at gmail.com)
Date: 2021-07-21T18:27:05-04:00
Commit Message:
DIRECTOR: LINGO: Code name arguments as string
We can't just code the names as integer IDs and look them up later.
The name table will be deleted when the movies switches.
Changed paths:
engines/director/lingo/lingo-bytecode.cpp
engines/director/lingo/lingo-code.cpp
engines/director/lingo/lingo.cpp
diff --git a/engines/director/lingo/lingo-bytecode.cpp b/engines/director/lingo/lingo-bytecode.cpp
index 293489f2f8..d6b47ba138 100644
--- a/engines/director/lingo/lingo-bytecode.cpp
+++ b/engines/director/lingo/lingo-bytecode.cpp
@@ -75,68 +75,68 @@ static LingoV4Bytecode lingoV4[] = {
{ 0x42, LC::c_argcnoretpush,"b" },
{ 0x43, LC::c_argcpush, "b" },
// 0x44, push a constant
- { 0x45, LC::c_namepush, "b" },
- { 0x46, LC::cb_varrefpush, "b" },
- { 0x48, LC::cb_globalpush, "b" }, // used in event scripts
- { 0x49, LC::cb_globalpush, "b" },
- { 0x4a, LC::cb_thepush, "b" },
- { 0x4b, LC::cb_varpush, "bpa" },
- { 0x4c, LC::cb_varpush, "bpv" },
- { 0x4e, LC::cb_globalassign,"b" }, // used in event scripts
- { 0x4f, LC::cb_globalassign,"b" },
- { 0x50, LC::cb_theassign, "b" },
- { 0x51, LC::cb_varassign, "bpa" },
- { 0x52, LC::cb_varassign, "bpv" },
+ { 0x45, LC::c_namepush, "bN" },
+ { 0x46, LC::cb_varrefpush, "bN" },
+ { 0x48, LC::cb_globalpush, "bN" }, // used in event scripts
+ { 0x49, LC::cb_globalpush, "bN" },
+ { 0x4a, LC::cb_thepush, "bN" },
+ { 0x4b, LC::cb_varpush, "bpaN" },
+ { 0x4c, LC::cb_varpush, "bpvN" },
+ { 0x4e, LC::cb_globalassign,"bN" }, // used in event scripts
+ { 0x4f, LC::cb_globalassign,"bN" },
+ { 0x50, LC::cb_theassign, "bN" },
+ { 0x51, LC::cb_varassign, "bpaN" },
+ { 0x52, LC::cb_varassign, "bpvN" },
{ 0x53, LC::c_jump, "jb" },
{ 0x54, LC::c_jump, "jbn" },
{ 0x55, LC::c_jumpifz, "jb" },
{ 0x56, LC::cb_localcall, "b" },
- { 0x57, LC::cb_call, "b" },
+ { 0x57, LC::cb_call, "bN" },
{ 0x58, LC::cb_objectcall, "b" },
{ 0x59, LC::cb_v4assign, "b" },
{ 0x5a, LC::cb_v4assign2, "b" },
{ 0x5b, LC::cb_delete, "b" },
{ 0x5c, LC::cb_v4theentitypush, "b" },
{ 0x5d, LC::cb_v4theentityassign, "b" },
- { 0x5f, LC::cb_thepush2, "b" },
- { 0x60, LC::cb_theassign2, "b" },
- { 0x61, LC::cb_objectfieldpush, "b" },
- { 0x62, LC::cb_objectfieldassign, "b" },
+ { 0x5f, LC::cb_thepush2, "bN" },
+ { 0x60, LC::cb_theassign2, "bN" },
+ { 0x61, LC::cb_objectfieldpush, "bN" },
+ { 0x62, LC::cb_objectfieldassign, "bN" },
{ 0x63, LC::cb_call, "b" }, // tellcall
{ 0x64, LC::c_stackpeek, "b" },
{ 0x65, LC::c_stackdrop, "b" },
- { 0x66, LC::cb_v4theentitynamepush, "b" },
+ { 0x66, LC::cb_v4theentitynamepush, "bN" },
{ 0x81, LC::c_intpush, "W" },
{ 0x82, LC::c_argcnoretpush,"w" },
{ 0x83, LC::c_argcpush, "w" },
// 0x84, push a constant
- { 0x85, LC::c_namepush, "w" },
- { 0x86, LC::cb_varrefpush, "w" },
- { 0x88, LC::cb_globalpush, "w" }, // used in event scripts
- { 0x89, LC::cb_globalpush, "w" },
- { 0x8a, LC::cb_thepush, "w" },
- { 0x8b, LC::cb_varpush, "wpa" },
- { 0x8c, LC::cb_varpush, "wpv" },
- { 0x8e, LC::cb_globalassign,"w" }, // used in event scripts
- { 0x8f, LC::cb_globalassign,"w" },
- { 0x90, LC::cb_theassign, "w" },
- { 0x91, LC::cb_varassign, "wpa" },
- { 0x92, LC::cb_varassign, "wpv" },
+ { 0x85, LC::c_namepush, "wN" },
+ { 0x86, LC::cb_varrefpush, "wN" },
+ { 0x88, LC::cb_globalpush, "wN" }, // used in event scripts
+ { 0x89, LC::cb_globalpush, "wN" },
+ { 0x8a, LC::cb_thepush, "wN" },
+ { 0x8b, LC::cb_varpush, "wpaN" },
+ { 0x8c, LC::cb_varpush, "wpvN" },
+ { 0x8e, LC::cb_globalassign,"wN" }, // used in event scripts
+ { 0x8f, LC::cb_globalassign,"wN" },
+ { 0x90, LC::cb_theassign, "wN" },
+ { 0x91, LC::cb_varassign, "wpaN" },
+ { 0x92, LC::cb_varassign, "wpvN" },
{ 0x93, LC::c_jump, "jw" },
{ 0x94, LC::c_jump, "jwn" },
{ 0x95, LC::c_jumpifz, "jw" },
{ 0x96, LC::cb_localcall, "w" },
- { 0x97, LC::cb_call, "w" },
+ { 0x97, LC::cb_call, "wN" },
{ 0x98, LC::cb_objectcall, "w" },
{ 0x99, LC::cb_v4assign, "w" },
{ 0x9a, LC::cb_v4assign2, "w" },
{ 0x9c, LC::cb_v4theentitypush, "w" },
{ 0x9d, LC::cb_v4theentityassign, "w" },
- { 0x9f, LC::cb_thepush2, "w" },
- { 0xa0, LC::cb_theassign2, "w" },
- { 0xa1, LC::cb_objectfieldpush, "w" },
- { 0xa2, LC::cb_objectfieldassign, "w" },
- { 0xa6, LC::cb_v4theentitynamepush, "w" },
+ { 0x9f, LC::cb_thepush2, "wN" },
+ { 0xa0, LC::cb_theassign2, "wN" },
+ { 0xa1, LC::cb_objectfieldpush, "wN" },
+ { 0xa2, LC::cb_objectfieldassign, "wN" },
+ { 0xa6, LC::cb_v4theentitynamepush, "wN" },
{ 0, 0, 0 }
};
@@ -519,8 +519,7 @@ void LC::cb_proplist() {
void LC::cb_call() {
- int nameId = g_lingo->readInt();
- Common::String name = g_lingo->_currentArchive->getName(nameId);
+ Common::String name = g_lingo->readString();
Datum nargs = g_lingo->pop();
if ((nargs.type == ARGC) || (nargs.type == ARGCNORET)) {
@@ -534,8 +533,7 @@ void LC::cb_call() {
void LC::cb_globalpush() {
- int nameId = g_lingo->readInt();
- Common::String name = g_lingo->_currentArchive->getName(nameId);
+ Common::String name = g_lingo->readString();
Datum target(name);
target.type = GLOBALREF;
debugC(3, kDebugLingoExec, "cb_globalpush: pushing %s to stack", name.c_str());
@@ -545,8 +543,7 @@ void LC::cb_globalpush() {
void LC::cb_globalassign() {
- int nameId = g_lingo->readInt();
- Common::String name = g_lingo->_currentArchive->getName(nameId);
+ Common::String name = g_lingo->readString();
Datum target(name);
target.type = GLOBALREF;
debugC(3, kDebugLingoExec, "cb_globalassign: assigning to %s", name.c_str());
@@ -555,31 +552,27 @@ void LC::cb_globalassign() {
}
void LC::cb_objectfieldassign() {
- int fieldNameId = g_lingo->readInt();
- Common::String fieldName = g_lingo->_currentArchive->getName(fieldNameId);
+ Common::String fieldName = g_lingo->readString();
Datum value = g_lingo->pop();
Datum object = g_lingo->pop();
g_lingo->setObjectProp(object, fieldName, value);
}
void LC::cb_objectfieldpush() {
- int fieldNameId = g_lingo->readInt();
- Common::String fieldName = g_lingo->_currentArchive->getName(fieldNameId);
+ Common::String fieldName = g_lingo->readString();
Datum object = g_lingo->pop();
g_lingo->getObjectProp(object, fieldName);
}
void LC::cb_varrefpush() {
- int nameId = g_lingo->readInt();
- Common::String name = g_lingo->_currentArchive->getName(nameId);
+ Common::String name = g_lingo->readString();
Datum result(name);
result.type = SYMBOL;
g_lingo->push(result);
}
void LC::cb_theassign() {
- int nameId = g_lingo->readInt();
- Common::String name = g_lingo->_currentArchive->getName(nameId);
+ Common::String name = g_lingo->readString();
Datum value = g_lingo->pop();
if (g_lingo->_currentMe.type == OBJECT) {
if (g_lingo->_currentMe.u.obj->hasProp(name)) {
@@ -593,15 +586,13 @@ void LC::cb_theassign() {
}
void LC::cb_theassign2() {
- int nameId = g_lingo->readInt();
- Common::String name = g_lingo->_currentArchive->getName(nameId);
+ Common::String name = g_lingo->readString();
Datum value = g_lingo->pop();
warning("STUB: cb_theassign2(%s, %s)", name.c_str(), value.asString().c_str());
}
void LC::cb_thepush() {
- int nameId = g_lingo->readInt();
- Common::String name = g_lingo->_currentArchive->getName(nameId);
+ Common::String name = g_lingo->readString();
if (g_lingo->_currentMe.type == OBJECT) {
if (g_lingo->_currentMe.u.obj->hasProp(name)) {
g_lingo->push(g_lingo->_currentMe.u.obj->getProp(name));
@@ -617,9 +608,8 @@ void LC::cb_thepush() {
}
void LC::cb_thepush2() {
- int nameId = g_lingo->readInt();
Datum result;
- Common::String name = g_lingo->_currentArchive->getName(nameId);
+ Common::String name = g_lingo->readString();
if (g_lingo->_theEntities.contains(name)) {
TheEntity *entity = g_lingo->_theEntities[name];
Datum id;
@@ -635,8 +625,7 @@ void LC::cb_thepush2() {
}
void LC::cb_varpush() {
- int nameId = g_lingo->readInt();
- Common::String name = g_lingo->_currentArchive->getName(nameId);
+ Common::String name = g_lingo->readString();
Datum target(name);
target.type = LOCALREF;
debugC(3, kDebugLingoExec, "cb_varpush: pushing %s to stack", name.c_str());
@@ -646,8 +635,7 @@ void LC::cb_varpush() {
void LC::cb_varassign() {
- int nameId = g_lingo->readInt();
- Common::String name = g_lingo->_currentArchive->getName(nameId);
+ Common::String name = g_lingo->readString();
Datum target(name);
target.type = LOCALREF;
debugC(3, kDebugLingoExec, "cb_varassign: assigning to %s", name.c_str());
@@ -787,8 +775,7 @@ void LC::cb_v4theentitynamepush() {
warning("cb_v4theentitynamepush: first arg should be of type ARGC or ARGCNORET, not %s", nargs.type2str());
}
- int nameId = g_lingo->readInt();
- Common::String name = g_lingo->_currentArchive->getName(nameId);
+ Common::String name = g_lingo->readString();
Datum id;
id.u.s = NULL;
@@ -1367,6 +1354,7 @@ ScriptContext *LingoCompiler::compileLingoV4(Common::SeekableReadStreamEndian &s
size_t argc = strlen(g_lingo->_lingoV4[opcode]->proto);
if (argc) {
+ bool codeName = false;
int arg = 0;
for (uint c = 0; c < argc; c++) {
switch (g_lingo->_lingoV4[opcode]->proto[c]) {
@@ -1429,11 +1417,19 @@ ScriptContext *LingoCompiler::compileLingoV4(Common::SeekableReadStreamEndian &s
// argument refers to a code offset; fix alignment in post
jumpList.push_back(offsetList.size());
break;
+ case 'N':
+ // argument is a name in the name table
+ codeName = true;
+ break;
default:
break;
}
}
- codeInt(arg);
+ if (codeName) {
+ codeString(_assemblyArchive->getName(arg).c_str());
+ } else {
+ codeInt(arg);
+ }
}
} else {
// unimplemented instruction
diff --git a/engines/director/lingo/lingo-code.cpp b/engines/director/lingo/lingo-code.cpp
index 82c0af95a1..faf1df0a64 100644
--- a/engines/director/lingo/lingo-code.cpp
+++ b/engines/director/lingo/lingo-code.cpp
@@ -110,7 +110,7 @@ static struct FuncDescr {
{ LC::c_lt, "c_lt", "" },
{ LC::c_mod, "c_mod", "" },
{ LC::c_mul, "c_mul", "" },
- { LC::c_namepush, "c_namepush", "N" },
+ { LC::c_namepush, "c_namepush", "s" },
{ LC::c_negate, "c_negate", "" },
{ LC::c_neq, "c_neq", "" },
{ LC::c_not, "c_not", "" },
@@ -143,31 +143,31 @@ static struct FuncDescr {
{ LC::c_wordToOf, "c_wordToOf", "" }, // D3
{ LC::c_wordToOfRef, "c_wordToOfRef", "" }, // D3
{ LC::c_xpop, "c_xpop", "" },
- { LC::cb_call, "cb_call", "N" },
+ { LC::cb_call, "cb_call", "s" },
{ LC::cb_delete, "cb_delete", "i" },
{ LC::cb_hilite, "cb_hilite", "" },
- { LC::cb_globalassign, "cb_globalassign", "N" },
- { LC::cb_globalpush, "cb_globalpush", "N" },
+ { LC::cb_globalassign, "cb_globalassign", "s" },
+ { LC::cb_globalpush, "cb_globalpush", "s" },
{ LC::cb_list, "cb_list", "" },
{ LC::cb_proplist, "cb_proplist", "" },
{ LC::cb_localcall, "cb_localcall", "i" },
{ LC::cb_objectcall, "cb_objectcall", "i" },
- { LC::cb_objectfieldassign, "cb_objectfieldassign", "N" },
- { LC::cb_objectfieldpush, "cb_objectfieldpush", "N" },
- { LC::cb_varrefpush, "cb_varrefpush", "N" },
- { LC::cb_theassign, "cb_theassign", "N" },
- { LC::cb_theassign2, "cb_theassign2", "N" },
- { LC::cb_thepush, "cb_thepush", "N" },
- { LC::cb_thepush2, "cb_thepush2", "N" },
+ { LC::cb_objectfieldassign, "cb_objectfieldassign", "s" },
+ { LC::cb_objectfieldpush, "cb_objectfieldpush", "s" },
+ { LC::cb_varrefpush, "cb_varrefpush", "s" },
+ { LC::cb_theassign, "cb_theassign", "s" },
+ { LC::cb_theassign2, "cb_theassign2", "s" },
+ { LC::cb_thepush, "cb_thepush", "s" },
+ { LC::cb_thepush2, "cb_thepush2", "s" },
{ LC::cb_unk, "cb_unk", "i" },
{ LC::cb_unk1, "cb_unk1", "ii" },
{ LC::cb_unk2, "cb_unk2", "iii" },
- { LC::cb_varassign, "cb_varassign", "N" },
- { LC::cb_varpush, "cb_varpush", "N" },
+ { LC::cb_varassign, "cb_varassign", "s" },
+ { LC::cb_varpush, "cb_varpush", "s" },
{ LC::cb_v4assign, "cb_v4assign", "i" },
{ LC::cb_v4assign2, "cb_v4assign2", "i" },
{ LC::cb_v4theentitypush,"cb_v4theentitypush","i" },
- { LC::cb_v4theentitynamepush,"cb_v4theentitynamepush","N" },
+ { LC::cb_v4theentitynamepush,"cb_v4theentitynamepush","s" },
{ LC::cb_v4theentityassign,"cb_v4theentityassign","i" },
{ LC::cb_zeropush, "cb_zeropush", "" },
{ LC::c_stackpeek, "c_stackpeek", "i" },
@@ -385,8 +385,7 @@ void LC::c_symbolpush() {
}
void LC::c_namepush() {
- int i = g_lingo->readInt();
- Datum d(Common::String(g_lingo->_currentArchive->getName(i)));
+ Datum d(g_lingo->readString());
d.type = SYMBOL;
g_lingo->push(d);
}
diff --git a/engines/director/lingo/lingo.cpp b/engines/director/lingo/lingo.cpp
index b2a0470879..af6ad107a7 100644
--- a/engines/director/lingo/lingo.cpp
+++ b/engines/director/lingo/lingo.cpp
@@ -368,14 +368,6 @@ Common::String Lingo::decodeInstruction(LingoArchive *archive, ScriptData *sd, u
res += Common::String::format(" %s", field2str(v));
break;
}
- case 'N':
- {
- i = (*sd)[pc++];
- int v = READ_UINT32(&i);
-
- res += Common::String::format(" \"%s\"", archive->names[v].c_str());
- break;
- }
default:
warning("decodeInstruction: Unknown parameter type: %c", pars[-1]);
}
Commit: 8d5679878465040d55d66e2428e92a6edb5bf4e0
https://github.com/scummvm/scummvm/commit/8d5679878465040d55d66e2428e92a6edb5bf4e0
Author: djsrv (dservilla at gmail.com)
Date: 2021-07-21T18:27:05-04:00
Commit Message:
DIRECTOR: LINGO: Properly ref count script contexts
Changed paths:
engines/director/lingo/lingo-code.cpp
engines/director/lingo/lingo.cpp
diff --git a/engines/director/lingo/lingo-code.cpp b/engines/director/lingo/lingo-code.cpp
index faf1df0a64..9e2c75fa24 100644
--- a/engines/director/lingo/lingo-code.cpp
+++ b/engines/director/lingo/lingo-code.cpp
@@ -239,8 +239,10 @@ void Lingo::pushContext(const Symbol funcSym, bool allowRetVal, Datum defaultRet
if (funcSym.target)
g_lingo->_currentMe = funcSym.target;
- if (funcSym.ctx)
+ if (funcSym.ctx) {
g_lingo->_currentScriptContext = funcSym.ctx;
+ *g_lingo->_currentScriptContext->_refCount += 1;
+ }
g_lingo->_currentArchive = funcSym.archive;
@@ -315,8 +317,8 @@ void Lingo::popContext() {
error("handler %s popped extra %d values", fp->sp.name->c_str(), fp->stackSizeBefore - _stack.size());
}
- // Destroy anonymous function context
- if (fp->sp.anonymous) {
+ *g_lingo->_currentScriptContext->_refCount -= 1;
+ if (*g_lingo->_currentScriptContext->_refCount <= 0) {
delete g_lingo->_currentScriptContext;
}
diff --git a/engines/director/lingo/lingo.cpp b/engines/director/lingo/lingo.cpp
index af6ad107a7..6faa32c008 100644
--- a/engines/director/lingo/lingo.cpp
+++ b/engines/director/lingo/lingo.cpp
@@ -212,7 +212,9 @@ void Lingo::reloadBuiltIns() {
LingoArchive::~LingoArchive() {
for (int i = 0; i <= kMaxScriptType; i++) {
for (ScriptContextHash::iterator it = scriptContexts[i].begin(); it != scriptContexts[i].end(); ++it) {
- delete it->_value;
+ *it->_value->_refCount -= 1;
+ if (*it->_value->_refCount <= 0)
+ delete it->_value;
}
}
}
Commit: 2e8d061cc8e794f43a78b27b74adc9ba38f43d66
https://github.com/scummvm/scummvm/commit/2e8d061cc8e794f43a78b27b74adc9ba38f43d66
Author: djsrv (dservilla at gmail.com)
Date: 2021-07-21T18:27:05-04:00
Commit Message:
DIRECTOR: LINGO: Remove g_lingo->_currentArchive
All uses of this have been removed since we can't rely on the archive to
still exist when switching movies.
Changed paths:
engines/director/lingo/lingo-bytecode.cpp
engines/director/lingo/lingo-code.cpp
engines/director/lingo/lingo-codegen.cpp
engines/director/lingo/lingo-object.cpp
engines/director/lingo/lingo.cpp
engines/director/lingo/lingo.h
diff --git a/engines/director/lingo/lingo-bytecode.cpp b/engines/director/lingo/lingo-bytecode.cpp
index d6b47ba138..5e50655e31 100644
--- a/engines/director/lingo/lingo-bytecode.cpp
+++ b/engines/director/lingo/lingo-bytecode.cpp
@@ -1521,7 +1521,7 @@ ScriptContext *LingoCompiler::compileLingoV4(Common::SeekableReadStreamEndian &s
uint pc = 0;
while (pc < _currentAssembly->size()) {
uint spc = pc;
- Common::String instr = g_lingo->decodeInstruction(_assemblyArchive, _currentAssembly, pc, &pc);
+ Common::String instr = g_lingo->decodeInstruction(_currentAssembly, pc, &pc);
out.writeString(Common::String::format("[%5d] %s\n", spc, instr.c_str()));
}
out.writeString(Common::String::format("<end code>\n\n"));
diff --git a/engines/director/lingo/lingo-code.cpp b/engines/director/lingo/lingo-code.cpp
index 9e2c75fa24..b034dbaed1 100644
--- a/engines/director/lingo/lingo-code.cpp
+++ b/engines/director/lingo/lingo-code.cpp
@@ -227,7 +227,6 @@ void Lingo::pushContext(const Symbol funcSym, bool allowRetVal, Datum defaultRet
fp->retpc = g_lingo->_pc;
fp->retscript = g_lingo->_currentScript;
fp->retctx = g_lingo->_currentScriptContext;
- fp->retarchive = g_lingo->_currentArchive;
fp->localvars = g_lingo->_localvars;
fp->retMe = g_lingo->_currentMe;
fp->sp = funcSym;
@@ -244,8 +243,6 @@ void Lingo::pushContext(const Symbol funcSym, bool allowRetVal, Datum defaultRet
*g_lingo->_currentScriptContext->_refCount += 1;
}
- g_lingo->_currentArchive = funcSym.archive;
-
DatumHash *localvars = g_lingo->_localvars;
if (!funcSym.anonymous) {
// Execute anonymous functions within the current var frame.
@@ -324,7 +321,6 @@ void Lingo::popContext() {
g_lingo->_currentScript = fp->retscript;
g_lingo->_currentScriptContext = fp->retctx;
- g_lingo->_currentArchive = fp->retarchive;
g_lingo->_pc = fp->retpc;
g_lingo->_currentMe = fp->retMe;
diff --git a/engines/director/lingo/lingo-codegen.cpp b/engines/director/lingo/lingo-codegen.cpp
index d6cf341f35..15f5a399d9 100644
--- a/engines/director/lingo/lingo-codegen.cpp
+++ b/engines/director/lingo/lingo-codegen.cpp
@@ -151,7 +151,7 @@ ScriptContext *LingoCompiler::compileLingo(const Common::U32String &code, LingoA
uint pc = 0;
while (pc < _currentAssembly->size()) {
uint spc = pc;
- Common::String instr = g_lingo->decodeInstruction(_assemblyArchive, _currentAssembly, pc, &pc);
+ Common::String instr = g_lingo->decodeInstruction(_currentAssembly, pc, &pc);
debugC(2, kDebugCompile, "[%5d] %s", spc, instr.c_str());
}
debugC(2, kDebugCompile, "<end code>");
diff --git a/engines/director/lingo/lingo-object.cpp b/engines/director/lingo/lingo-object.cpp
index 9b10410322..97e24034a6 100644
--- a/engines/director/lingo/lingo-object.cpp
+++ b/engines/director/lingo/lingo-object.cpp
@@ -226,7 +226,7 @@ Symbol ScriptContext::define(const Common::String &name, ScriptData *code, Commo
uint pc = 0;
while (pc < sym.u.defn->size()) {
uint spc = pc;
- Common::String instr = g_lingo->decodeInstruction(_archive, sym.u.defn, pc, &pc);
+ Common::String instr = g_lingo->decodeInstruction(sym.u.defn, pc, &pc);
debugC(1, kDebugCompile, "[%5d] %s", spc, instr.c_str());
}
debugC(1, kDebugCompile, "<end define code>");
diff --git a/engines/director/lingo/lingo.cpp b/engines/director/lingo/lingo.cpp
index 6faa32c008..319f276f92 100644
--- a/engines/director/lingo/lingo.cpp
+++ b/engines/director/lingo/lingo.cpp
@@ -149,7 +149,6 @@ PCell::PCell(const Datum &prop, const Datum &val) {
Lingo::Lingo(DirectorEngine *vm) : _vm(vm) {
g_lingo = this;
- _currentArchive = nullptr;
_currentScript = 0;
_currentScriptContext = nullptr;
@@ -308,7 +307,7 @@ void Lingo::printCallStack(uint pc) {
}
}
-Common::String Lingo::decodeInstruction(LingoArchive *archive, ScriptData *sd, uint pc, uint *newPc) {
+Common::String Lingo::decodeInstruction(ScriptData *sd, uint pc, uint *newPc) {
Symbol sym;
Common::String res;
@@ -404,7 +403,7 @@ void Lingo::execute() {
break;
}
- Common::String instr = decodeInstruction(_currentArchive, _currentScript, _pc);
+ Common::String instr = decodeInstruction(_currentScript, _pc);
uint current = _pc;
if (debugChannelSet(5, kDebugLingoExec))
diff --git a/engines/director/lingo/lingo.h b/engines/director/lingo/lingo.h
index 304966547c..b85ef90a2d 100644
--- a/engines/director/lingo/lingo.h
+++ b/engines/director/lingo/lingo.h
@@ -197,7 +197,6 @@ struct CFrame { /* proc/func call stack frame */
int retpc; /* where to resume after return */
ScriptData *retscript; /* which script to resume after return */
ScriptContext *retctx; /* which script context to use after return */
- LingoArchive *retarchive; /* which archive to use after return */
DatumHash *localvars;
Datum retMe; /* which me obj to use after return */
uint stackSizeBefore;
@@ -255,7 +254,7 @@ public:
void executeScript(ScriptType type, CastMemberID id);
void printStack(const char *s, uint pc);
void printCallStack(uint pc);
- Common::String decodeInstruction(LingoArchive *archive, ScriptData *sd, uint pc, uint *newPC = NULL);
+ Common::String decodeInstruction(ScriptData *sd, uint pc, uint *newPC = NULL);
void reloadBuiltIns();
void initBuiltIns();
@@ -365,7 +364,6 @@ public:
LingoCompiler *_compiler;
int _currentChannelId;
- LingoArchive *_currentArchive;
ScriptContext *_currentScriptContext;
ScriptData *_currentScript;
Datum _currentMe;
Commit: e2a34fccc1af0ff04ca4b4eb3acfbf65d65e07f0
https://github.com/scummvm/scummvm/commit/e2a34fccc1af0ff04ca4b4eb3acfbf65d65e07f0
Author: djsrv (dservilla at gmail.com)
Date: 2021-07-21T18:27:05-04:00
Commit Message:
DIRECTOR: LINGO: Temporarily freeze script context in func_goto
Changed paths:
engines/director/lingo/lingo-code.cpp
engines/director/lingo/lingo-funcs.cpp
engines/director/lingo/lingo.cpp
engines/director/lingo/lingo.h
engines/director/score.cpp
diff --git a/engines/director/lingo/lingo-code.cpp b/engines/director/lingo/lingo-code.cpp
index b034dbaed1..08b471865a 100644
--- a/engines/director/lingo/lingo-code.cpp
+++ b/engines/director/lingo/lingo-code.cpp
@@ -227,6 +227,7 @@ void Lingo::pushContext(const Symbol funcSym, bool allowRetVal, Datum defaultRet
fp->retpc = g_lingo->_pc;
fp->retscript = g_lingo->_currentScript;
fp->retctx = g_lingo->_currentScriptContext;
+ fp->retFreezeContext = g_lingo->_freezeContext;
fp->localvars = g_lingo->_localvars;
fp->retMe = g_lingo->_currentMe;
fp->sp = funcSym;
@@ -242,6 +243,7 @@ void Lingo::pushContext(const Symbol funcSym, bool allowRetVal, Datum defaultRet
g_lingo->_currentScriptContext = funcSym.ctx;
*g_lingo->_currentScriptContext->_refCount += 1;
}
+ g_lingo->_freezeContext = false;
DatumHash *localvars = g_lingo->_localvars;
if (!funcSym.anonymous) {
@@ -321,6 +323,7 @@ void Lingo::popContext() {
g_lingo->_currentScript = fp->retscript;
g_lingo->_currentScriptContext = fp->retctx;
+ g_lingo->_freezeContext = fp->retFreezeContext;
g_lingo->_pc = fp->retpc;
g_lingo->_currentMe = fp->retMe;
diff --git a/engines/director/lingo/lingo-funcs.cpp b/engines/director/lingo/lingo-funcs.cpp
index a4f522b041..7c23590522 100644
--- a/engines/director/lingo/lingo-funcs.cpp
+++ b/engines/director/lingo/lingo-funcs.cpp
@@ -194,6 +194,9 @@ void Lingo::func_goto(Datum &frame, Datum &movie) {
_vm->_skipFrameAdvance = true;
+ // Freeze this script context. We'll return to it after entering the next frame.
+ g_lingo->_freezeContext = true;
+
if (movie.type != VOID) {
Common::String movieFilenameRaw = movie.asString();
Window *stage = _vm->getCurrentWindow();
diff --git a/engines/director/lingo/lingo.cpp b/engines/director/lingo/lingo.cpp
index 319f276f92..288c3e8097 100644
--- a/engines/director/lingo/lingo.cpp
+++ b/engines/director/lingo/lingo.cpp
@@ -155,6 +155,7 @@ Lingo::Lingo(DirectorEngine *vm) : _vm(vm) {
_currentChannelId = -1;
_globalCounter = 0;
_pc = 0;
+ _freezeContext = false;
_abort = false;
_expectError = false;
_caughtError = false;
@@ -389,7 +390,7 @@ Common::String Lingo::decodeInstruction(ScriptData *sd, uint pc, uint *newPc) {
void Lingo::execute() {
uint localCounter = 0;
- while (!_abort && (*_currentScript)[_pc] != STOP) {
+ while (!_abort && !_freezeContext && (*_currentScript)[_pc] != STOP) {
if (_globalCounter > 1000 && debugChannelSet(-1, kDebugFewFramesOnly)) {
warning("Lingo::execute(): Stopping due to debug few frames only");
_vm->getCurrentMovie()->getScore()->_playState = kPlayStopped;
@@ -444,8 +445,11 @@ void Lingo::execute() {
popContext();
}
}
-
_abort = false;
+
+ if (_freezeContext) {
+ debugC(1, kDebugLingoExec, "Lingo::execute(): Context is frozen, pausing execution");
+ }
}
void Lingo::executeScript(ScriptType type, CastMemberID id) {
diff --git a/engines/director/lingo/lingo.h b/engines/director/lingo/lingo.h
index b85ef90a2d..5e5ac0eb83 100644
--- a/engines/director/lingo/lingo.h
+++ b/engines/director/lingo/lingo.h
@@ -197,6 +197,7 @@ struct CFrame { /* proc/func call stack frame */
int retpc; /* where to resume after return */
ScriptData *retscript; /* which script to resume after return */
ScriptContext *retctx; /* which script context to use after return */
+ bool retFreezeContext; /* whether the context should be frozen after return */
DatumHash *localvars;
Datum retMe; /* which me obj to use after return */
uint stackSizeBefore;
@@ -368,6 +369,7 @@ public:
ScriptData *_currentScript;
Datum _currentMe;
+ bool _freezeContext;
bool _abort;
bool _expectError;
bool _caughtError;
diff --git a/engines/director/score.cpp b/engines/director/score.cpp
index 2aec497450..3273cc2a7b 100644
--- a/engines/director/score.cpp
+++ b/engines/director/score.cpp
@@ -308,6 +308,8 @@ void Score::stopPlay() {
}
void Score::update() {
+ uint initialCallStackSize = g_lingo->_callstack.size();
+
if (_activeFade) {
if (!_soundManager->fadeChannel(_activeFade))
_activeFade = 0;
@@ -428,6 +430,19 @@ void Score::update() {
}
// TODO Director 6 - another order
+ // If we have more call stack frames than we started with, then we have a newly
+ // added frozen context. We'll deal with that later.
+ if (g_lingo->_callstack.size() == initialCallStackSize) {
+ // We may have frozen Lingo context(s) from func_goto.
+ // Now that we've entered a new frame and we don't have any new frozen
+ // contexts just added on, let's unfreeze all the contexts.
+ while (g_lingo->_freezeContext) {
+ debugC(1, kDebugLingoExec, "Score::update(): Unfreezing Lingo context");
+ g_lingo->_freezeContext = false;
+ g_lingo->execute();
+ }
+ }
+
byte tempo = _frames[_currentFrame]->_tempo;
if (tempo) {
_puppetTempo = 0;
Commit: 07f8f718c1749a15a09d4ef1f7ad4e1dd302f688
https://github.com/scummvm/scummvm/commit/07f8f718c1749a15a09d4ef1f7ad4e1dd302f688
Author: djsrv (dservilla at gmail.com)
Date: 2021-07-21T18:27:05-04:00
Commit Message:
DIRECTOR: LINGO: Completely untie script contexts from Lingo archives
A context can outlast its containing archive, so we don't want it to
have any references to the archive.
Changed paths:
engines/director/lingo/lingo-bytecode.cpp
engines/director/lingo/lingo-codegen.cpp
engines/director/lingo/lingo-object.cpp
engines/director/lingo/lingo-object.h
engines/director/lingo/lingo.cpp
engines/director/lingo/lingo.h
diff --git a/engines/director/lingo/lingo-bytecode.cpp b/engines/director/lingo/lingo-bytecode.cpp
index 5e50655e31..f4e9cdff4c 100644
--- a/engines/director/lingo/lingo-bytecode.cpp
+++ b/engines/director/lingo/lingo-bytecode.cpp
@@ -981,12 +981,12 @@ ScriptContext *LingoCompiler::compileLingoV4(Common::SeekableReadStreamEndian &s
}
debugC(1, kDebugCompile, "Add V4 script %d: factory '%s'", scriptId, factoryName.c_str());
- sc = _assemblyContext = new ScriptContext(factoryName, _assemblyArchive, scriptType, castId);
+ sc = _assemblyContext = new ScriptContext(factoryName, scriptType, castId);
registerFactory(factoryName);
} else {
debugC(1, kDebugCompile, "Add V4 script %d: %s %d", scriptId, scriptType2str(scriptType), castId);
- sc = _assemblyContext = new ScriptContext(!castName.empty() ? castName : Common::String::format("%d", castId), _assemblyArchive, scriptType, castId);
+ sc = _assemblyContext = new ScriptContext(!castName.empty() ? castName : Common::String::format("%d", castId), scriptType, castId);
}
// initialise each property
@@ -1531,6 +1531,15 @@ ScriptContext *LingoCompiler::compileLingoV4(Common::SeekableReadStreamEndian &s
_currentAssembly = nullptr;
}
+ if (!_assemblyContext->isFactory()) {
+ // Register this context's functions with the containing archive.
+ for (SymbolHash::iterator it = _assemblyContext->_functionHandlers.begin(); it != _assemblyContext->_functionHandlers.end(); ++it) {
+ if (!_assemblyArchive->functionHandlers.contains(it->_key)) {
+ _assemblyArchive->functionHandlers[it->_key] = it->_value;
+ }
+ }
+ }
+
if (!skipdump && ConfMan.getBool("dump_scripts")) {
out.flush();
out.close();
diff --git a/engines/director/lingo/lingo-codegen.cpp b/engines/director/lingo/lingo-codegen.cpp
index 15f5a399d9..8c9a381e33 100644
--- a/engines/director/lingo/lingo-codegen.cpp
+++ b/engines/director/lingo/lingo-codegen.cpp
@@ -103,7 +103,7 @@ ScriptContext *LingoCompiler::compileAnonymous(const Common::U32String &code) {
ScriptContext *LingoCompiler::compileLingo(const Common::U32String &code, LingoArchive *archive, ScriptType type, CastMemberID id, const Common::String &scriptName, bool anonymous) {
_assemblyArchive = archive;
_assemblyAST = nullptr;
- ScriptContext *mainContext = _assemblyContext = new ScriptContext(scriptName, archive, type, id.member);
+ ScriptContext *mainContext = _assemblyContext = new ScriptContext(scriptName, type, id.member);
_currentAssembly = new ScriptData;
_methodVars = new VarTypeHash;
@@ -164,7 +164,6 @@ ScriptContext *LingoCompiler::compileLingo(const Common::U32String &code, LingoA
Common::String typeStr = Common::String(scriptType2str(type));
currentFunc.name = new Common::String("[" + typeStr + " " + _assemblyContext->getName() + "]");
currentFunc.ctx = _assemblyContext;
- currentFunc.archive = archive;
currentFunc.anonymous = anonymous;
Common::Array<Common::String> *argNames = new Common::Array<Common::String>;
Common::Array<Common::String> *varNames = new Common::Array<Common::String>;
@@ -194,6 +193,13 @@ ScriptContext *LingoCompiler::compileLingo(const Common::U32String &code, LingoA
delete _currentAssembly;
}
+ // Register this context's functions with the containing archive.
+ for (SymbolHash::iterator it = _assemblyContext->_functionHandlers.begin(); it != _assemblyContext->_functionHandlers.end(); ++it) {
+ if (!_assemblyArchive->functionHandlers.contains(it->_key)) {
+ _assemblyArchive->functionHandlers[it->_key] = it->_value;
+ }
+ }
+
delete _methodVars;
_methodVars = nullptr;
_currentAssembly = nullptr;
@@ -347,8 +353,6 @@ void LingoCompiler::registerMethodVar(const Common::String &name, VarType type)
}
void LingoCompiler::registerFactory(Common::String &name) {
- // FIXME: The factory's context should not be tied to the LingoArchive
- // but bytecode needs it to resolve names
_assemblyContext->setName(name);
_assemblyContext->setFactory(true);
if (!g_lingo->_globalvars.contains(name) || g_lingo->_globalvars[name].type == VOID) {
@@ -388,7 +392,7 @@ bool LingoCompiler::visitScriptNode(ScriptNode *node) {
bool LingoCompiler::visitFactoryNode(FactoryNode *node) {
_inFactory = true;
ScriptContext *mainContext = _assemblyContext;
- _assemblyContext = new ScriptContext(mainContext->getName(), mainContext->_archive, mainContext->_scriptType, mainContext->_id);
+ _assemblyContext = new ScriptContext(mainContext->getName(), mainContext->_scriptType, mainContext->_id);
COMPILE_LIST(node->methods);
registerFactory(*node->name);
diff --git a/engines/director/lingo/lingo-object.cpp b/engines/director/lingo/lingo-object.cpp
index 97e24034a6..2534eac740 100644
--- a/engines/director/lingo/lingo-object.cpp
+++ b/engines/director/lingo/lingo-object.cpp
@@ -181,8 +181,8 @@ void LM::m_dispose(int nargs) {
/* ScriptContext */
-ScriptContext::ScriptContext(Common::String name, LingoArchive *archive, ScriptType type, int id)
- : Object<ScriptContext>(name), _archive(archive), _scriptType(type), _id(id) {
+ScriptContext::ScriptContext(Common::String name, ScriptType type, int id)
+ : Object<ScriptContext>(name), _scriptType(type), _id(id) {
_objType = kScriptObj;
}
@@ -200,7 +200,6 @@ ScriptContext::ScriptContext(const ScriptContext &sc) : Object<ScriptContext>(sc
_constants = sc._constants;
_properties = sc._properties;
- _archive = sc._archive;
_id = sc._id;
}
@@ -220,7 +219,6 @@ Symbol ScriptContext::define(const Common::String &name, ScriptData *code, Commo
sym.argNames = argNames;
sym.varNames = varNames;
sym.ctx = this;
- sym.archive = _archive;
if (debugChannelSet(1, kDebugCompile)) {
uint pc = 0;
@@ -234,9 +232,6 @@ Symbol ScriptContext::define(const Common::String &name, ScriptData *code, Commo
if (!g_lingo->_eventHandlerTypeIds.contains(name)) {
_functionHandlers[name] = sym;
- if (_scriptType == kMovieScript && _archive && !_archive->functionHandlers.contains(name)) {
- _archive->functionHandlers[name] = sym;
- }
} else {
_eventHandlers[g_lingo->_eventHandlerTypeIds[name]] = sym;
}
diff --git a/engines/director/lingo/lingo-object.h b/engines/director/lingo/lingo-object.h
index 0cf4e8f641..6534e7bcf5 100644
--- a/engines/director/lingo/lingo-object.h
+++ b/engines/director/lingo/lingo-object.h
@@ -187,7 +187,6 @@ SymbolHash *Object<Derived>::_methods = nullptr;
class ScriptContext : public Object<ScriptContext> {
public:
- LingoArchive *_archive;
ScriptType _scriptType;
int _id;
Common::Array<Common::String> _functionNames; // used by cb_localcall
@@ -198,7 +197,7 @@ public:
Common::HashMap<uint32, Datum> _objArray;
public:
- ScriptContext(Common::String name, LingoArchive *archive = nullptr, ScriptType type = kNoneScript, int id = 0);
+ ScriptContext(Common::String name, ScriptType type = kNoneScript, int id = 0);
ScriptContext(const ScriptContext &sc);
~ScriptContext() override;
diff --git a/engines/director/lingo/lingo.cpp b/engines/director/lingo/lingo.cpp
index 288c3e8097..39a814c594 100644
--- a/engines/director/lingo/lingo.cpp
+++ b/engines/director/lingo/lingo.cpp
@@ -67,7 +67,6 @@ Symbol::Symbol() {
argNames = nullptr;
varNames = nullptr;
ctx = nullptr;
- archive = nullptr;
target = nullptr;
anonymous = false;
}
@@ -84,7 +83,6 @@ Symbol::Symbol(const Symbol &s) {
argNames = s.argNames;
varNames = s.varNames;
ctx = s.ctx;
- archive = s.archive;
target = s.target;
anonymous = s.anonymous;
}
@@ -105,7 +103,6 @@ Symbol& Symbol::operator=(const Symbol &s) {
argNames = s.argNames;
varNames = s.varNames;
ctx = s.ctx;
- archive = s.archive;
target = s.target;
anonymous = s.anonymous;
diff --git a/engines/director/lingo/lingo.h b/engines/director/lingo/lingo.h
index 5e5ac0eb83..b7c9435257 100644
--- a/engines/director/lingo/lingo.h
+++ b/engines/director/lingo/lingo.h
@@ -98,7 +98,6 @@ struct Symbol { /* symbol table entry */
Common::Array<Common::String> *argNames;
Common::Array<Common::String> *varNames;
ScriptContext *ctx; /* optional script context to execute with */
- LingoArchive *archive; /* optional archive to execute with */
AbstractObject *target; /* optional method target */
bool anonymous;
Commit: 89f85abe032272473cfc0c90296944836d7e1d85
https://github.com/scummvm/scummvm/commit/89f85abe032272473cfc0c90296944836d7e1d85
Author: djsrv (dservilla at gmail.com)
Date: 2021-07-21T18:27:06-04:00
Commit Message:
DIRECTOR: LINGO: Fix factory script context name
Changed paths:
engines/director/lingo/lingo-codegen.cpp
diff --git a/engines/director/lingo/lingo-codegen.cpp b/engines/director/lingo/lingo-codegen.cpp
index 8c9a381e33..ea85e6040d 100644
--- a/engines/director/lingo/lingo-codegen.cpp
+++ b/engines/director/lingo/lingo-codegen.cpp
@@ -392,7 +392,7 @@ bool LingoCompiler::visitScriptNode(ScriptNode *node) {
bool LingoCompiler::visitFactoryNode(FactoryNode *node) {
_inFactory = true;
ScriptContext *mainContext = _assemblyContext;
- _assemblyContext = new ScriptContext(mainContext->getName(), mainContext->_scriptType, mainContext->_id);
+ _assemblyContext = new ScriptContext(*node->name, mainContext->_scriptType, mainContext->_id);
COMPILE_LIST(node->methods);
registerFactory(*node->name);
Commit: 4d9b5212774a7dfcdc09aa9fde6c4b2f503432a4
https://github.com/scummvm/scummvm/commit/4d9b5212774a7dfcdc09aa9fde6c4b2f503432a4
Author: djsrv (dservilla at gmail.com)
Date: 2021-07-21T18:27:06-04:00
Commit Message:
DIRECTOR: LINGO: Overwrite factory when already defined
I have confirmed that this is the correct behavior.
Changed paths:
engines/director/lingo/lingo-codegen.cpp
diff --git a/engines/director/lingo/lingo-codegen.cpp b/engines/director/lingo/lingo-codegen.cpp
index ea85e6040d..38c6db9e0c 100644
--- a/engines/director/lingo/lingo-codegen.cpp
+++ b/engines/director/lingo/lingo-codegen.cpp
@@ -355,11 +355,7 @@ void LingoCompiler::registerMethodVar(const Common::String &name, VarType type)
void LingoCompiler::registerFactory(Common::String &name) {
_assemblyContext->setName(name);
_assemblyContext->setFactory(true);
- if (!g_lingo->_globalvars.contains(name) || g_lingo->_globalvars[name].type == VOID) {
- g_lingo->_globalvars[name] = _assemblyContext;
- } else {
- warning("BUILDBOT: Factory '%s' already defined", name.c_str());
- }
+ g_lingo->_globalvars[name] = _assemblyContext;
}
void LingoCompiler::updateLoopJumps(uint nextTargetPos, uint exitTargetPos) {
More information about the Scummvm-git-logs
mailing list