aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFilippos Karapetis2009-02-20 10:49:43 +0000
committerFilippos Karapetis2009-02-20 10:49:43 +0000
commit7886aedebb0e09ebfec62498293c42fdece69f02 (patch)
treeb13b1b764b22f9f5bb341e7449139cd2ce147677
parent0155a1d0b4aeea44c7f27405675bbb2c52d660d6 (diff)
downloadscummvm-rg350-7886aedebb0e09ebfec62498293c42fdece69f02.tar.gz
scummvm-rg350-7886aedebb0e09ebfec62498293c42fdece69f02.tar.bz2
scummvm-rg350-7886aedebb0e09ebfec62498293c42fdece69f02.zip
Fixed a nasty regression from the script system rewrite (commit #35670), which will cause crashes under certain conditions, and probably makes SAGA games non-completable.
When a script thread is waiting for another thread, the current instruction offset should not be modified. The thread processing function would incorrectly continue in some special cases, and would incorrectly alter the current instruction offset. This becomes apparent in some special cases only, which made it hard to spot - plus, SAGA games have not been tested for 0.13.0, so there weren't any reports for this. This change SHOULD go to the 0.13.0 branch, but we've already tagged... svn-id: r38581
-rw-r--r--engines/saga/script.cpp15
-rw-r--r--engines/saga/sthread.cpp4
2 files changed, 14 insertions, 5 deletions
diff --git a/engines/saga/script.cpp b/engines/saga/script.cpp
index a850e59252..7a7e15c249 100644
--- a/engines/saga/script.cpp
+++ b/engines/saga/script.cpp
@@ -614,12 +614,14 @@ void Script::opCcall(SCRIPTOP_PARAMS) {
if (scriptFunction == &Saga::Script::sfScriptGotoScene) {
stopParsing = true; // cause abortAllThreads called and _this_ thread destroyed
+ breakOut = true;
return;
}
#ifdef ENABLE_IHNM
if (scriptFunction == &Saga::Script::sfVsetTrack) {
stopParsing = true;
+ breakOut = true;
return; // cause abortAllThreads called and _this_ thread destroyed
}
#endif
@@ -661,12 +663,14 @@ void Script::opCcallV(SCRIPTOP_PARAMS) {
if (scriptFunction == &Saga::Script::sfScriptGotoScene) {
stopParsing = true;
+ breakOut = true;
return; // cause abortAllThreads called and _this_ thread destroyed
}
#ifdef ENABLE_IHNM
if (scriptFunction == &Saga::Script::sfVsetTrack) {
stopParsing = true;
+ breakOut = true;
return; // cause abortAllThreads called and _this_ thread destroyed
}
#endif
@@ -691,6 +695,7 @@ void Script::opReturn(SCRIPTOP_PARAMS) {
if (thread->pushedSize() == 0) {
thread->_flags |= kTFlagFinished;
stopParsing = true;
+ breakOut = true;
return;
} else {
thread->pop(); //cause it 0
@@ -712,6 +717,7 @@ void Script::opReturnV(SCRIPTOP_PARAMS) {
if (thread->pushedSize() == 0) {
thread->_flags |= kTFlagFinished;
stopParsing = true;
+ breakOut = true;
return;
} else {
thread->pop(); //cause it 0
@@ -954,7 +960,8 @@ void Script::opLXor(SCRIPTOP_PARAMS) {
void Script::opSpeak(SCRIPTOP_PARAMS) {
if (_vm->_actor->isSpeaking()) {
thread->wait(kWaitTypeSpeech);
- stopParsing = false;
+ stopParsing = true;
+ breakOut = false;
return;
}
@@ -1007,7 +1014,8 @@ void Script::opSpeak(SCRIPTOP_PARAMS) {
void Script::opDialogBegin(SCRIPTOP_PARAMS) {
if (_conversingThread) {
thread->wait(kWaitTypeDialogBegin);
- stopParsing = false;
+ stopParsing = true;
+ breakOut = false;
return;
}
_conversingThread = thread;
@@ -1019,7 +1027,8 @@ void Script::opDialogEnd(SCRIPTOP_PARAMS) {
_vm->_interface->activate();
_vm->_interface->setMode(kPanelConverse);
thread->wait(kWaitTypeDialogEnd);
- stopParsing = false;
+ stopParsing = true;
+ breakOut = false;
return;
}
}
diff --git a/engines/saga/sthread.cpp b/engines/saga/sthread.cpp
index 9e015179d9..3dc6bd57d2 100644
--- a/engines/saga/sthread.cpp
+++ b/engines/saga/sthread.cpp
@@ -213,10 +213,10 @@ bool Script::runThread(ScriptThread *thread) {
debug(8, "Executing thread offset: %u (%x) stack: %d", thread->_instructionOffset, operandChar, thread->pushedSize());
stopParsing = false;
- (this->*_scriptOpsList[operandChar].scriptOp)(thread, &scriptS, stopParsing, breakOut);
debug(4, "Calling op %s", this->_scriptOpsList[operandChar].scriptOpName);
+ (this->*_scriptOpsList[operandChar].scriptOp)(thread, &scriptS, stopParsing, breakOut);
if (stopParsing)
- return true;
+ return breakOut;
if (thread->_flags & (kTFlagFinished | kTFlagAborted)) {
error("Wrong flags %d in thread", thread->_flags);