[Scummvm-git-logs] scummvm master -> 7b2924b83e8336b2984086659f46592703b8bb54

sev- noreply at scummvm.org
Sun Aug 6 12:49:34 UTC 2023


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:
b351758701 TINSEL: Fix ControlOff() doing the opposite
7b2924b83e TINSEL: Fix token function calls from non-coroutines


Commit: b35175870162f9ac873fa83c8cad3cf86ef1d5e0
    https://github.com/scummvm/scummvm/commit/b35175870162f9ac873fa83c8cad3cf86ef1d5e0
Author: PushmePullyu (127053144+PushmePullyu at users.noreply.github.com)
Date: 2023-08-06T14:49:30+02:00

Commit Message:
TINSEL: Fix ControlOff() doing the opposite

Changed paths:
    engines/tinsel/events.cpp


diff --git a/engines/tinsel/events.cpp b/engines/tinsel/events.cpp
index 5c76aab7751..2a34183b211 100644
--- a/engines/tinsel/events.cpp
+++ b/engines/tinsel/events.cpp
@@ -170,7 +170,7 @@ void ControlOn() {
  */
 void ControlOff() {
 	if (TinselVersion <= 1) {
-		Control(CONTROL_ON);
+		Control(CONTROL_OFF);
 		return;
 	}
 


Commit: 7b2924b83e8336b2984086659f46592703b8bb54
    https://github.com/scummvm/scummvm/commit/7b2924b83e8336b2984086659f46592703b8bb54
Author: PushmePullyu (127053144+PushmePullyu at users.noreply.github.com)
Date: 2023-08-06T14:49:30+02:00

Commit Message:
TINSEL: Fix token function calls from non-coroutines

Add extra bools to track token status. This allows setting
the owner to nullptr when a token is acquired from a
non-coroutine context / nullContext without marking it as free.

Fixes the following assert in Discworld 1 (see #13220):

After using the matches on the drainpipe to get the golden chimney
brush, the game switches to non-interactive scenes twice.
When changing back to the original scene, player control should be
disabled while a short animation plays, but this is not the case.
A mouse click by the player during this animation will then initiate
a walk action and cause a failed assert:

engines/tinsel/events.cpp:280:
 void Tinsel::WalkProcess(Common::CoroBaseContext*&, const void*):
 Assertion `_ctx->pMover->hCpath != NOPOLY' failed.

The game attempts to disable user control via the following call chain:
Tinsel::TinselEngine::NextGameCycle()
  Tinsel::ChangeScene()
    Tinsel::DoRestoreSceneFrame()
      Tinsel::Background::StartupBackground()
        Tinsel::ControlStartOff()
	  Tinsel::Control()
            Tinsel::GetControlToken()

This will set the owner of the control token to the current coroutine:
g_tokens[TOKEN_CONTROL].proc = CoroScheduler.getCurrentProcess()

However, since StartupBackground() is called from a non-coroutine
with a nullContext, getCurrentProcess() will return nullptr,
thereby marking the control token as free and allowing player actions.

Changed paths:
    engines/tinsel/token.cpp


diff --git a/engines/tinsel/token.cpp b/engines/tinsel/token.cpp
index 6494bc28836..2acdbd7fbe0 100644
--- a/engines/tinsel/token.cpp
+++ b/engines/tinsel/token.cpp
@@ -31,6 +31,7 @@ namespace Tinsel {
 
 struct Token {
 	Common::PROCESS		*proc;
+	bool				isFree;
 };
 
 // These vars are reset upon engine destruction
@@ -44,13 +45,15 @@ static void TerminateProcess(Common::PROCESS *tProc) {
 
 	// Release tokens held by the process
 	for (int i = 0; i < NUMTOKENS; i++) {
-		if (g_tokens[i].proc == tProc) {
+		if (!g_tokens[i].isFree && g_tokens[i].proc == tProc) {
 			g_tokens[i].proc = nullptr;
+			g_tokens[i].isFree = true;
 		}
 	}
 
 	// Kill the process
-	CoroScheduler.killProcess(tProc);
+	if (tProc != nullptr)
+		CoroScheduler.killProcess(tProc);
 }
 
 /**
@@ -59,8 +62,9 @@ static void TerminateProcess(Common::PROCESS *tProc) {
 void GetControlToken() {
 	const int which = TOKEN_CONTROL;
 
-	if (g_tokens[which].proc == NULL) {
+	if (g_tokens[which].isFree) {
 		g_tokens[which].proc = CoroScheduler.getCurrentProcess();
+		g_tokens[which].isFree = false;
 	}
 }
 
@@ -70,6 +74,7 @@ void GetControlToken() {
 void FreeControlToken() {
 	// Allow anyone to free TOKEN_CONTROL
 	g_tokens[TOKEN_CONTROL].proc = nullptr;
+	g_tokens[TOKEN_CONTROL].isFree = true;
 }
 
 
@@ -84,12 +89,13 @@ void FreeControlToken() {
 void GetToken(int which) {
 	assert(TOKEN_LEAD <= which && which < NUMTOKENS);
 
-	if (g_tokens[which].proc != NULL) {
+	if (!g_tokens[which].isFree) {
 		assert(g_tokens[which].proc != CoroScheduler.getCurrentProcess());
 		TerminateProcess(g_tokens[which].proc);
 	}
 
 	g_tokens[which].proc = CoroScheduler.getCurrentProcess();
+	g_tokens[which].isFree = false;
 }
 
 /**
@@ -102,6 +108,7 @@ void FreeToken(int which) {
 	assert(g_tokens[which].proc == CoroScheduler.getCurrentProcess());	// we'd have been killed if some other proc had taken this token
 
 	g_tokens[which].proc = nullptr;
+	g_tokens[which].isFree = true;
 }
 
 /**
@@ -111,7 +118,7 @@ bool TestToken(int which) {
 	if (which < 0 || which >= NUMTOKENS)
 		return false;
 
-	return (g_tokens[which].proc == NULL);
+	return (g_tokens[which].isFree);
 }
 
 /**
@@ -120,6 +127,7 @@ bool TestToken(int which) {
 void FreeAllTokens() {
 	for (int i = 0; i < NUMTOKENS; i++) {
 		g_tokens[i].proc = nullptr;
+		g_tokens[i].isFree = true;
 	}
 }
 




More information about the Scummvm-git-logs mailing list