[Scummvm-git-logs] scummvm master -> 54814386cfdaf7ce719a00dd1df2fa6cb31b36ba

sev- noreply at scummvm.org
Sun Aug 2 00:19:49 UTC 2026


This automated email contains information about 5 new commits which have been
pushed to the 'scummvm' repo located at https://api.github.com/repos/scummvm/scummvm .

Summary:
9c097cae27 DIRECTOR: LINGO: Fix input events being dropped during freeze
723b16ae07 DIRECTOR: LINGO: Fix more dropped events during freeze
441cdab3a4 DIRECTOR: LINGO: Reset _passEvent at start of event chain
2463138c44 GRAPHICS: MACGUI: Improve editable textbox rendering
54814386cf DIRECTOR: LINGO: Do _playDone context switch before stopMovie


Commit: 9c097cae2702232b90c3b6d5ad1763d42c1007bd
    https://github.com/scummvm/scummvm/commit/9c097cae2702232b90c3b6d5ad1763d42c1007bd
Author: Scott Percival (code at moral.net.au)
Date: 2026-08-02T02:19:41+02:00

Commit Message:
DIRECTOR: LINGO: Fix input events being dropped during freeze

Fixes D4-unit/T_EVNT04.DIR

Changed paths:
    engines/director/lingo/lingo-events.cpp


diff --git a/engines/director/lingo/lingo-events.cpp b/engines/director/lingo/lingo-events.cpp
index c348263e8f3..e966b3d0a7f 100644
--- a/engines/director/lingo/lingo-events.cpp
+++ b/engines/director/lingo/lingo-events.cpp
@@ -672,7 +672,7 @@ void Movie::queueInputEvent(LEvent event, int targetId, Common::Point pos) {
 
 
 bool Movie::processInputEvent(LEvent event, int targetId, Common::Point pos) {
-	if (!_lingo->_state->callstack.empty()) {
+	if ((!_lingo->_state->callstack.empty()) || (_lingo->_currentInputEvent.type != VOIDSYM)) {
 		// We're in the middle of executing something else, queue input event for later
 		queueInputEvent(event, targetId, pos);
 		return true;


Commit: 723b16ae0728c9f7a6d989399af75343b479b1cb
    https://github.com/scummvm/scummvm/commit/723b16ae0728c9f7a6d989399af75343b479b1cb
Author: Scott Percival (code at moral.net.au)
Date: 2026-08-02T02:19:41+02:00

Commit Message:
DIRECTOR: LINGO: Fix more dropped events during freeze

Fixes D4-unit/T_EVNT06.DIR

Changed paths:
    engines/director/lingo/lingo-events.cpp


diff --git a/engines/director/lingo/lingo-events.cpp b/engines/director/lingo/lingo-events.cpp
index e966b3d0a7f..148416371ec 100644
--- a/engines/director/lingo/lingo-events.cpp
+++ b/engines/director/lingo/lingo-events.cpp
@@ -247,6 +247,9 @@ void Movie::resolveScriptEvent(LingoEvent &event) {
 	 * [D4 docs] */
 	case kSpriteHandler:
 		{
+			if (!event.channelId)
+				return;
+
 			CastMemberID scriptId;
 			bool immediate = false;
 			Common::String initializerParams;
@@ -256,9 +259,6 @@ void Movie::resolveScriptEvent(LingoEvent &event) {
 				scriptId = _currentMouseDownSpriteScriptID;
 				immediate = _currentMouseDownSpriteImmediate;
 			} else {
-				if (!event.channelId)
-					return;
-
 				// clickOn must reflect the release sprite so drop-target scripts
 				// can identify the channel
 				if ((event.event == kEventMouseUp || event.event == kEventRightMouseUp) && event.channelId)
@@ -672,16 +672,14 @@ void Movie::queueInputEvent(LEvent event, int targetId, Common::Point pos) {
 
 
 bool Movie::processInputEvent(LEvent event, int targetId, Common::Point pos) {
+	queueInputEvent(event, targetId, pos);
 	if ((!_lingo->_state->callstack.empty()) || (_lingo->_currentInputEvent.type != VOIDSYM)) {
 		// We're in the middle of executing something else, queue input event for later
-		queueInputEvent(event, targetId, pos);
 		return true;
 	}
-	// Try and process event inline
-	Common::Queue<LingoEvent> queue;
-	queueEvent(queue, event, targetId, pos);
+	// Try and process input events now
 	_vm->setCurrentWindow(this->getWindow());
-	_lingo->processEvents(queue, true);
+	_lingo->processEvents(_inputEventQueue, true);
 	return _lingo->_passEvent;
 }
 


Commit: 441cdab3a4e1bbc40e070580d27e805d7632ff5c
    https://github.com/scummvm/scummvm/commit/441cdab3a4e1bbc40e070580d27e805d7632ff5c
Author: Scott Percival (code at moral.net.au)
Date: 2026-08-02T02:19:41+02:00

Commit Message:
DIRECTOR: LINGO: Reset _passEvent at start of event chain

Without this, _passEvent is leaked from the last event chain that was run.
A fun corollary is that if there are no handlers attached at all to an
event (i.e. on keyDown), the value returned by
Movie::processInputEvent() would be whatever the class was
initialised with (i.e. false), which would then be used by the window manager
as a signal for whether to propagate the event to the widgets (i.e.
should typing in a text field add letters).

Fixes most simple text entry widgets, e.g. "add" in Lingo Dictionary.

Changed paths:
    engines/director/lingo/lingo-events.cpp


diff --git a/engines/director/lingo/lingo-events.cpp b/engines/director/lingo/lingo-events.cpp
index 148416371ec..afe0a50a36c 100644
--- a/engines/director/lingo/lingo-events.cpp
+++ b/engines/director/lingo/lingo-events.cpp
@@ -727,6 +727,12 @@ void Lingo::processEvents(Common::Queue<LingoEvent> &queue, bool isInputEvent) {
 		// fetch the sprite ID, script ID to call, etc if not present.
 		movie->resolveScriptEvent(el);
 
+		// if this is the first event in the handler chain,
+		// ignore _passEvent for the first time
+		if (el.eventHandlerSourceType == kPrimaryHandler) {
+			_passEvent = true;
+		}
+
 		if (el.scriptType == kNoneScript) {
 			debugC(9, kDebugEvents, "Lingo::processEvents: no matching script for event (%s, %s, %s, %d), continuing",
 				_eventHandlerTypes[el.event], scriptType2str(el.scriptType), el.scriptId.asString().c_str(), el.channelId


Commit: 2463138c4494b959062038c42ce38945e3ccd6ad
    https://github.com/scummvm/scummvm/commit/2463138c4494b959062038c42ce38945e3ccd6ad
Author: Scott Percival (code at moral.net.au)
Date: 2026-08-02T02:19:41+02:00

Commit Message:
GRAPHICS: MACGUI: Improve editable textbox rendering

5dc90a8a0111b946c3bd8017bacfcf2c4fb1bb94 introduced a number of bugs
with textbox rendering. In particular, the mask surface was not being
reset after inserting a character in a non-left alignment mode, and the
foreground colour information was getting lost from the default settings.

Fixes textbox rendering in Eastern Mind.

Changed paths:
    graphics/macgui/mactext.cpp


diff --git a/graphics/macgui/mactext.cpp b/graphics/macgui/mactext.cpp
index 878b9855897..079150e2527 100644
--- a/graphics/macgui/mactext.cpp
+++ b/graphics/macgui/mactext.cpp
@@ -21,6 +21,7 @@
 
 #include "common/file.h"
 #include "common/timer.h"
+#include "graphics/font.h"
 #include "graphics/macgui/macwindowborder.h"
 
 #include "graphics/macgui/mactext.h"
@@ -236,6 +237,7 @@ void MacText::init(uint32 fgcolor, uint32 bgcolor, int maxWidth, TextAlign textA
 	_selStart = -1;
 
 	_defaultFormatting.wm = _wm;
+	_defaultFormatting.fgcolor = fgcolor;
 
 	_canvas.splitString(_str, -1, _defaultFormatting);
 	recalcDims();
@@ -701,6 +703,20 @@ void MacText::recalcDims() {
 			}
 			_fullRefresh = true;
 			_contentIsDirty = true;
+
+			if (_charBoxMaskSurface) {
+				_charBoxMaskSurface->free();
+				delete _charBoxMaskSurface;
+				_charBoxMaskSurface = new ManagedSurface(_dims.width(), _dims.height(), Graphics::PixelFormat::createFormatCLUT8());
+				_charBoxMaskSurface->clear(0);
+			}
+
+			if (_glyphMaskSurface) {
+				_glyphMaskSurface->free();
+				delete _glyphMaskSurface;
+				_glyphMaskSurface = new ManagedSurface(_dims.width(), _dims.height(), Graphics::PixelFormat::createFormatCLUT8());
+				_glyphMaskSurface->clear(0);
+			}
 		}
 	}
 }
@@ -943,6 +959,9 @@ void MacText::draw(ManagedSurface *g, int x, int y, int w, int h, int xoff, int
 
 	drawStep(g, _canvas._surface, &_borderSurface, x, y, w, h, xoff, yoff, _canvas._tbgcolor, _wm->_pixelformat.isCLUT8() ? _wm->_colorGreen : 0);
 
+	//_canvas._surface->rawSurface().debugPrint(0, 0, 0, 0, 0, 1, 320);
+	//_canvas._glyphMask->rawSurface().debugPrint(0, 0, 0, 0, 0, 1, 320);
+	//_canvas._charBoxMask->rawSurface().debugPrint(0, 0, 0, 0, 0, 1, 320);
 	drawStep(_glyphMaskSurface, _canvas._glyphMask, &_borderMaskSurface, x, y, w, h, xoff, yoff, 0, 0);
 	drawStep(_charBoxMaskSurface, _canvas._charBoxMask, &_borderMaskSurface, x, y, w, h, xoff, yoff, 0, 0);
 
@@ -1216,12 +1235,12 @@ void MacText::drawSelection(int xoff, int yoff) {
 		numLines--;
 
 		byte *ptr = (byte *)_composeSurface->getBasePtr(x1, MIN<int>(y + yoff, maxSelectionHeight - 1));
+		byte *maskPtr = (byte *)_glyphMaskSurface->getBasePtr(x1, MIN<int>(y + yoff, maxSelectionHeight - 1));
 
-		for (int x = x1; x < x2; x++, ptr++)
-			if (*ptr == _canvas._tfgcolor)
-				*ptr = _canvas._tbgcolor;
-			else
-				*ptr = _canvas._tfgcolor;
+		for (int x = x1; x < x2; x++, ptr++, maskPtr++) {
+			*ptr = (*ptr == _canvas._tfgcolor) ? _canvas._tbgcolor : _canvas._tfgcolor;
+			*maskPtr = (*maskPtr == 0xff) ? 0x00 : 0xff;
+		}
 	}
 }
 
@@ -2047,7 +2066,10 @@ void MacText::insertChar(byte c, int *row, int *col) {
 
 	(*col)++;
 
-	if (_canvas.getLineWidth(*row) - oldw + chunkw > _canvas._maxWidth) { // Needs reshuffle
+	bool needsReshuffle = _canvas.getLineWidth(*row) - oldw + chunkw > _canvas._maxWidth;
+	needsReshuffle |= (_canvas._textAlignment != kTextAlignLeft);
+
+	if (needsReshuffle) {
 		_canvas.reshuffleParagraph(row, col, _defaultFormatting);
 		_fullRefresh = true;
 		recalcDims();


Commit: 54814386cfdaf7ce719a00dd1df2fa6cb31b36ba
    https://github.com/scummvm/scummvm/commit/54814386cfdaf7ce719a00dd1df2fa6cb31b36ba
Author: Scott Percival (code at moral.net.au)
Date: 2026-08-02T02:19:41+02:00

Commit Message:
DIRECTOR: LINGO: Do _playDone context switch before stopMovie

Fixes D4-unit/T_PLAY01.DIR
Confirmed to work with bodyfun and cybergrannies.

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 8d758122047..db6ff976d35 100644
--- a/engines/director/lingo/lingo-code.cpp
+++ b/engines/director/lingo/lingo-code.cpp
@@ -408,7 +408,10 @@ void Lingo::freezePlayState() {
 
 void Lingo::requeuePlayState() {
 	Window *window = _vm->getCurrentWindow();
-	window->requeueLingoPlayState();
+	if (window->requeueLingoPlayState()) {
+		window->thawLingoState();
+		switchStateFromWindow();
+	}
 }
 
 
@@ -1833,7 +1836,7 @@ void LC::call(const Symbol &funcSym, int nargs, bool allowRetVal) {
 			g_lingo->_state->me = retMe;
 		} else {
 			// sendSprite/sendAllSprites/call/send can be used both as a command and
-			// as a function (returning the handler's result). 
+			// as a function (returning the handler's result).
 			if (funcSym.name && (funcSym.name->equalsIgnoreCase("sendSprite") ||
 					funcSym.name->equalsIgnoreCase("sendAllSprites") ||
 					funcSym.name->equalsIgnoreCase("call") ||
diff --git a/engines/director/lingo/lingo.cpp b/engines/director/lingo/lingo.cpp
index a2c4928794a..85fcb6633b9 100644
--- a/engines/director/lingo/lingo.cpp
+++ b/engines/director/lingo/lingo.cpp
@@ -717,6 +717,19 @@ bool Lingo::execute(int targetFrame) {
 			warning("Lingo::execute(): Bad PC (%d)", _state->pc);
 			break;
 		}
+
+		if (_playDone) {
+			// Returning from a script with "play done" does not freeze the state. Instead it obliterates it,
+			// replacing it with the script context from the entry "play" statement.
+			// To be clear, if "play movie B" was invoked in movie A, and "play done" was invoked in movie B,
+			// the script from movie A will be resumed in movie B -before- the normal movie switch procedure.
+			while (_state->callstack.size()) {
+				popContext(true);
+			}
+
+			_playDone = false;
+			requeuePlayState();
+		}
 	}
 
 	bool result = !_freezeState;
@@ -726,20 +739,16 @@ bool Lingo::execute(int targetFrame) {
 	} else if (_freezeState) {
 		debugC(5, kDebugLingoExec, "Lingo::execute(): Context is frozen, pausing execution");
 		freezeState();
-	// Returning from a script with "play done" does not freeze the state. Instead it obliterates it.
-	} else if (_abort || _playDone || _vm->getCurrentMovie()->getScore()->_playState == kPlayStopped) {
+	} else if (_abort || _vm->getCurrentMovie()->getScore()->_playState == kPlayStopped) {
 		// Clean up call stack
 		while (_state->callstack.size()) {
 			popContext(true);
 		}
-		if (_playDone) {
-			_playDone = false;
-			requeuePlayState();
-		}
 	}
 	_abort = false;
 	_freezeState = false;
 	_freezePlay = false;
+	_playDone = false;
 
 	g_debugger->stepHook();
 	// return true if execution finished, false if the context froze for later




More information about the Scummvm-git-logs mailing list