[Scummvm-git-logs] scummvm master -> 44ad31a043702b073990a69c65a4f78cc81454e0
djsrv
dservilla at gmail.com
Thu Jul 22 01:07:48 UTC 2021
This automated email contains information about 2 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
5a7c191ac4 DIRECTOR: LINGO: Create one call stack per window
44ad31a043 DIRECTOR: LINGO: Only freeze one context at a time
Commit: 5a7c191ac4b013ad9123a664b23ad19e7c51c611
https://github.com/scummvm/scummvm/commit/5a7c191ac4b013ad9123a664b23ad19e7c51c611
Author: djsrv (dservilla at gmail.com)
Date: 2021-07-21T20:35:40-04:00
Commit Message:
DIRECTOR: LINGO: Create one call stack per window
Since there may be frames left on the call stack after Lingo::execute()
is called now, it isn't safe to share one call stack between several
movies executing in parallel.
Changed paths:
engines/director/lingo/lingo-builtins.cpp
engines/director/lingo/lingo-bytecode.cpp
engines/director/lingo/lingo-code.cpp
engines/director/lingo/lingo.cpp
engines/director/lingo/lingo.h
engines/director/score.cpp
engines/director/window.h
diff --git a/engines/director/lingo/lingo-builtins.cpp b/engines/director/lingo/lingo-builtins.cpp
index a381d3ed25..7f00d8eea8 100644
--- a/engines/director/lingo/lingo-builtins.cpp
+++ b/engines/director/lingo/lingo-builtins.cpp
@@ -1289,7 +1289,7 @@ void LB::b_quit(int nargs) {
}
void LB::b_return(int nargs) {
- CFrame *fp = g_lingo->_callstack.back();
+ CFrame *fp = g_director->getCurrentWindow()->_callstack.back();
Datum retVal;
if (nargs > 0) {
diff --git a/engines/director/lingo/lingo-bytecode.cpp b/engines/director/lingo/lingo-bytecode.cpp
index 4ebaee00d2..e6e855ddea 100644
--- a/engines/director/lingo/lingo-bytecode.cpp
+++ b/engines/director/lingo/lingo-bytecode.cpp
@@ -29,6 +29,7 @@
#include "director/castmember.h"
#include "director/movie.h"
#include "director/util.h"
+#include "director/window.h"
#include "director/lingo/lingo.h"
#include "director/lingo/lingo-code.h"
#include "director/lingo/lingo-codegen.h"
@@ -336,7 +337,8 @@ Datum Lingo::findVarV4(int varType, const Datum &id) {
case 4: // arg
case 5: // local
{
- if (g_lingo->_callstack.empty()) {
+ Common::Array<CFrame *> &callstack = _vm->getCurrentWindow()->_callstack;
+ if (callstack.empty()) {
warning("BUILDBOT: findVarV4: no call frame");
return res;
}
@@ -346,8 +348,8 @@ Datum Lingo::findVarV4(int varType, const Datum &id) {
}
int varIndex = id.asInt() / 6;
Common::Array<Common::String> *varNames = (varType == 4)
- ? _callstack.back()->sp.argNames
- : _callstack.back()->sp.varNames;
+ ? callstack.back()->sp.argNames
+ : callstack.back()->sp.varNames;
if (varIndex < (int)varNames->size()) {
res = (*varNames)[varIndex];
diff --git a/engines/director/lingo/lingo-code.cpp b/engines/director/lingo/lingo-code.cpp
index 08b471865a..cac2fde665 100644
--- a/engines/director/lingo/lingo-code.cpp
+++ b/engines/director/lingo/lingo-code.cpp
@@ -221,7 +221,9 @@ void LC::c_xpop() {
}
void Lingo::pushContext(const Symbol funcSym, bool allowRetVal, Datum defaultRetVal) {
- debugC(5, kDebugLingoExec, "Pushing frame %d", g_lingo->_callstack.size() + 1);
+ Common::Array<CFrame *> &callstack = _vm->getCurrentWindow()->_callstack;
+
+ debugC(5, kDebugLingoExec, "Pushing frame %d", callstack.size() + 1);
CFrame *fp = new CFrame;
fp->retpc = g_lingo->_pc;
@@ -288,7 +290,7 @@ void Lingo::pushContext(const Symbol funcSym, bool allowRetVal, Datum defaultRet
fp->stackSizeBefore = _stack.size();
- g_lingo->_callstack.push_back(fp);
+ callstack.push_back(fp);
if (debugChannelSet(2, kDebugLingoExec)) {
g_lingo->printCallStack(0);
@@ -296,9 +298,11 @@ void Lingo::pushContext(const Symbol funcSym, bool allowRetVal, Datum defaultRet
}
void Lingo::popContext() {
- debugC(5, kDebugLingoExec, "Popping frame %d", g_lingo->_callstack.size());
- CFrame *fp = g_lingo->_callstack.back();
- g_lingo->_callstack.pop_back();
+ Common::Array<CFrame *> &callstack = _vm->getCurrentWindow()->_callstack;
+
+ debugC(5, kDebugLingoExec, "Popping frame %d", callstack.size());
+ CFrame *fp = callstack.back();
+ callstack.pop_back();
if (_stack.size() == fp->stackSizeBefore + 1) {
if (!fp->allowRetVal) {
@@ -1560,7 +1564,9 @@ void LC::call(const Symbol &funcSym, int nargs, bool allowRetVal) {
}
void LC::c_procret() {
- if (g_lingo->_callstack.size() == 0) {
+ Common::Array<CFrame *> &callstack = g_director->getCurrentWindow()->_callstack;
+
+ if (callstack.size() == 0) {
warning("LC::c_procret(): Call stack underflow");
g_lingo->_abort = true;
return;
@@ -1568,7 +1574,7 @@ void LC::c_procret() {
g_lingo->popContext();
- if (g_lingo->_callstack.size() == 0) {
+ if (callstack.size() == 0) {
debugC(5, kDebugLingoExec, "Call stack empty, returning");
g_lingo->_abort = true;
return;
diff --git a/engines/director/lingo/lingo.cpp b/engines/director/lingo/lingo.cpp
index 39a814c594..9d21a0839f 100644
--- a/engines/director/lingo/lingo.cpp
+++ b/engines/director/lingo/lingo.cpp
@@ -281,20 +281,21 @@ void Lingo::printStack(const char *s, uint pc) {
}
void Lingo::printCallStack(uint pc) {
- if (g_lingo->_callstack.size() == 0) {
+ Common::Array<CFrame *> &callstack = _vm->getCurrentWindow()->_callstack;
+ if (callstack.size() == 0) {
debugC(2, kDebugLingoExec, "\nEnd of execution");
return;
}
debugC(2, kDebugLingoExec, "\nCall stack:");
- for (int i = 0; i < (int)g_lingo->_callstack.size(); i++) {
- CFrame *frame = g_lingo->_callstack[i];
+ for (int i = 0; i < (int)callstack.size(); i++) {
+ CFrame *frame = callstack[i];
uint framePc = pc;
- if (i < (int)g_lingo->_callstack.size() - 1)
- framePc = g_lingo->_callstack[i + 1]->retpc;
+ if (i < (int)callstack.size() - 1)
+ framePc = callstack[i + 1]->retpc;
if (frame->sp.type != VOIDSYM) {
debugC(2, kDebugLingoExec, "#%d %s:%d", i + 1,
- g_lingo->_callstack[i]->sp.name->c_str(),
+ callstack[i]->sp.name->c_str(),
framePc
);
} else {
@@ -438,7 +439,7 @@ void Lingo::execute() {
if (_abort) {
// Clean up call stack
- while (_callstack.size()) {
+ while (_vm->getCurrentWindow()->_callstack.size()) {
popContext();
}
}
diff --git a/engines/director/lingo/lingo.h b/engines/director/lingo/lingo.h
index b7c9435257..c1248ffc68 100644
--- a/engines/director/lingo/lingo.h
+++ b/engines/director/lingo/lingo.h
@@ -373,7 +373,6 @@ public:
bool _expectError;
bool _caughtError;
- Common::Array<CFrame *> _callstack;
TheEntityHash _theEntities;
TheEntityFieldHash _theEntityFields;
diff --git a/engines/director/score.cpp b/engines/director/score.cpp
index fcd2563a02..40de8d0358 100644
--- a/engines/director/score.cpp
+++ b/engines/director/score.cpp
@@ -403,7 +403,7 @@ void Score::update() {
debugC(1, kDebugImages, "****************************** Current frame: %d", _currentFrame);
- uint initialCallStackSize = g_lingo->_callstack.size();
+ uint initialCallStackSize = _window->_callstack.size();
_lingo->executeImmediateScripts(_frames[_currentFrame]);
@@ -432,7 +432,7 @@ void Score::update() {
// 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) {
+ if (_window->_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.
diff --git a/engines/director/window.h b/engines/director/window.h
index c2a4266070..3c34d94976 100644
--- a/engines/director/window.h
+++ b/engines/director/window.h
@@ -172,6 +172,8 @@ public:
Common::List<MovieReference> _movieStack;
bool _newMovieStarted;
+ Common::Array<CFrame *> _callstack;
+
private:
uint32 _stageColor;
Commit: 44ad31a043702b073990a69c65a4f78cc81454e0
https://github.com/scummvm/scummvm/commit/44ad31a043702b073990a69c65a4f78cc81454e0
Author: djsrv (dservilla at gmail.com)
Date: 2021-07-21T20:41:36-04:00
Commit Message:
DIRECTOR: LINGO: Only freeze one context at a time
Changed paths:
engines/director/lingo/lingo-funcs.cpp
engines/director/score.cpp
engines/director/window.cpp
engines/director/window.h
diff --git a/engines/director/lingo/lingo-funcs.cpp b/engines/director/lingo/lingo-funcs.cpp
index 7c23590522..cd8ae4fc7a 100644
--- a/engines/director/lingo/lingo-funcs.cpp
+++ b/engines/director/lingo/lingo-funcs.cpp
@@ -190,16 +190,20 @@ void Lingo::func_goto(Datum &frame, Datum &movie) {
if (movie.type == VOID && frame.type == VOID)
return;
+ Window *stage = _vm->getCurrentWindow();
Score *score = _vm->getCurrentMovie()->getScore();
_vm->_skipFrameAdvance = true;
- // Freeze this script context. We'll return to it after entering the next frame.
- g_lingo->_freezeContext = true;
+ // If there isn't already frozen Lingo (e.g. from a previous func_goto we haven't yet unfrozen),
+ // freeze this script context. We'll return to it after entering the next frame.
+ if (!stage->_hasFrozenLingo) {
+ g_lingo->_freezeContext = true;
+ stage->_hasFrozenLingo = true;
+ }
if (movie.type != VOID) {
Common::String movieFilenameRaw = movie.asString();
- Window *stage = _vm->getCurrentWindow();
if (!stage->setNextMovie(movieFilenameRaw))
return;
diff --git a/engines/director/score.cpp b/engines/director/score.cpp
index 40de8d0358..5db7f1725c 100644
--- a/engines/director/score.cpp
+++ b/engines/director/score.cpp
@@ -433,14 +433,14 @@ void Score::update() {
// 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 (_window->_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) {
+ // We may have a frozen Lingo context from func_goto.
+ // Now that we've entered a new frame, let's unfreeze that context.
+ if (g_lingo->_freezeContext) {
debugC(1, kDebugLingoExec, "Score::update(): Unfreezing Lingo context");
g_lingo->_freezeContext = false;
g_lingo->execute();
}
+ _window->_hasFrozenLingo = false;
}
byte tempo = _frames[_currentFrame]->_tempo;
diff --git a/engines/director/window.cpp b/engines/director/window.cpp
index 929765d599..f1322c8483 100644
--- a/engines/director/window.cpp
+++ b/engines/director/window.cpp
@@ -61,6 +61,8 @@ Window::Window(int id, bool scrollable, bool resizable, bool editable, Graphics:
_windowType = -1;
_titleVisible = true;
updateBorderType();
+
+ _hasFrozenLingo = false;
}
Window::~Window() {
diff --git a/engines/director/window.h b/engines/director/window.h
index 3c34d94976..1375800376 100644
--- a/engines/director/window.h
+++ b/engines/director/window.h
@@ -173,6 +173,7 @@ public:
bool _newMovieStarted;
Common::Array<CFrame *> _callstack;
+ bool _hasFrozenLingo;
private:
uint32 _stageColor;
More information about the Scummvm-git-logs
mailing list