[Scummvm-git-logs] scummvm master -> 4d6cd80e24fba55e9d69444a47e0c65f1b8d16d9

sev- noreply at scummvm.org
Sat Aug 9 13:28:37 UTC 2025


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

Summary:
2b665ecafd DIRECTOR: Add documentation for mcmillennium quirks
58a4efe977 AUDIO: Warn if QuickTimeAudioTrack edit list entry has rate other than 1.0
f5425d9cf4 DIRECTOR: Fix noisy cursor comparison errors
47e2010262 DIRECTOR: LINGO: Fix c_delete, add more test cases
a3564d0df8 DIRECTOR: LINGO: Format test output to fix linebreaks
3fa52f0f77 DIRECTOR: XOBJ: Add quirk for overriding FileIO type
c552509d77 DIRECTOR: Improve accuracy of editable flag
973b5a8f5a DIRECTOR: Add detection entry for Elroy Goes Bugzerk
fa9368799c DIRECTOR: LINGO: Improve accuracy of keyUp/keyDown events
86a68643cd DIRECTOR: Reset puppet flag of score sound channels
4d6cd80e24 DIRECTOR: Improve accuracy of b_puppetSound(0)


Commit: 2b665ecafd312265201221681270c5ebdca29c37
    https://github.com/scummvm/scummvm/commit/2b665ecafd312265201221681270c5ebdca29c37
Author: Scott Percival (code at moral.net.au)
Date: 2025-08-09T15:28:30+02:00

Commit Message:
DIRECTOR: Add documentation for mcmillennium quirks

Changed paths:
    engines/director/game-quirks.cpp
    engines/director/lingo/lingo-patcher.cpp


diff --git a/engines/director/game-quirks.cpp b/engines/director/game-quirks.cpp
index 16c501e144b..981e8eefe7a 100644
--- a/engines/director/game-quirks.cpp
+++ b/engines/director/game-quirks.cpp
@@ -118,7 +118,10 @@ struct CachedFile {
 	{"finkletimes", Common::kPlatformWindows, "lernscor.txt", (const byte *)"", 0},
 	{"finkletimes", Common::kPlatformWindows, "namelist.txt", (const byte *)"", 0},
 	{"finkletimes", Common::kPlatformWindows, "userlist.txt", (const byte *)"", 0},
+
+	// Mission Code: Millennium expects the installer to have added an empty save file.
 	{"mcmillennium", Common::kPlatformWindows, "pc/players", (const byte *)"", 0},
+
 	{ nullptr, Common::kPlatformUnknown, nullptr, nullptr, 0 }
 };
 
diff --git a/engines/director/lingo/lingo-patcher.cpp b/engines/director/lingo/lingo-patcher.cpp
index 49da2d4811d..da0f710ee83 100644
--- a/engines/director/lingo/lingo-patcher.cpp
+++ b/engines/director/lingo/lingo-patcher.cpp
@@ -443,7 +443,10 @@ on exitFrame\r\
   go(1, \"C:\\PG_WORLD\\A_IN01\")\r\
 ";
 
-
+/*
+ * Mission Code: Millennium has some drive detection code which prevents the game from loading
+ * if it detects DESTINA.MLD is present "on the hard disk". Provide the same code without that check.
+ */
 const char *const mcmillenniumDriveDetectionFix = "\
 on initPaths\r\
   global PD, theCDPath, theHDPath, theVCAudioPath, theNotePath, proxPath\r\
@@ -468,6 +471,11 @@ on initPaths\r\
 end\r\
 ";
 
+/*
+ * Mission Code: Millennium has a bizarre method of checking the dimensions of the screen by
+ * measuring the stage position of a 512x384 movie and seeing if it matches 640x480.
+ * Even when forcing desktop mode this doesn't match up exactly, so patch it out.
+ */
 const char *const mcmillenniumResDetectionFix = "\
 on getRes\r\
 end\r\
@@ -513,6 +521,7 @@ struct ScriptHandlerPatch {
 	{"pinkgear", nullptr, kPlatformWindows, "GOTOPINK.EXE", kMovieScript, 4, DEFAULT_CAST_LIB, &pinkGearDriveDetectionFix1},
 	{"pinkgear", nullptr, kPlatformWindows, "GOTOPINK.EXE", kScoreScript, 6, DEFAULT_CAST_LIB, &pinkGearDriveDetectionFix2},
 	{"mcmillennium", nullptr, kPlatformWindows, "PC\\MILL.EXE", kMovieScript, 15, DEFAULT_CAST_LIB, &mcmillenniumResDetectionFix},
+	{"mcmillennium", nullptr, kPlatformMacintosh, "Mission Code Millennium:Mission Code Millennium", kMovieScript, 15, DEFAULT_CAST_LIB, &mcmillenniumResDetectionFix},
 	{"mcmillennium", nullptr, kPlatformWindows, "PC\\SHARED.DXR", kMovieScript, 1013, DEFAULT_CAST_LIB, &mcmillenniumDriveDetectionFix},
 	{"mcmillennium", nullptr, kPlatformMacintosh, "Mission Code Millennium:SHARED.Dxr", kMovieScript, 1013, DEFAULT_CAST_LIB, &mcmillenniumDriveDetectionFix},
 	{nullptr, nullptr, kPlatformUnknown, nullptr, kNoneScript, 0, 0, nullptr},


Commit: 58a4efe97744f2b3ddc9998f93922d8724ba6587
    https://github.com/scummvm/scummvm/commit/58a4efe97744f2b3ddc9998f93922d8724ba6587
Author: Scott Percival (code at moral.net.au)
Date: 2025-08-09T15:28:30+02:00

Commit Message:
AUDIO: Warn if QuickTimeAudioTrack edit list entry has rate other than 1.0

Fixes QT/splash1.mov in Mission Code: Millennium.

Changed paths:
    audio/decoders/quicktime.cpp


diff --git a/audio/decoders/quicktime.cpp b/audio/decoders/quicktime.cpp
index 1a1d8e0d34e..0bc128e392d 100644
--- a/audio/decoders/quicktime.cpp
+++ b/audio/decoders/quicktime.cpp
@@ -434,7 +434,7 @@ void QuickTimeAudioDecoder::QuickTimeAudioTrack::enterNewEdit(const Timestamp &p
 	// I really hope I never need to implement this :P
 	// But, I'll throw in this error just to make sure I catch anything with this...
 	if (_parentTrack->editList[_curEdit].mediaRate != 1)
-		error("Unhandled QuickTime audio rate change");
+		warning("QuickTimeAudioDecoder: Unhandled QuickTime audio rate change");
 
 	// Reinitialize the codec
 	((AudioSampleDesc *)_parentTrack->sampleDescs[0])->initCodec();


Commit: f5425d9cf4cf6baaf00759db367e3e077def2851
    https://github.com/scummvm/scummvm/commit/f5425d9cf4cf6baaf00759db367e3e077def2851
Author: Scott Percival (code at moral.net.au)
Date: 2025-08-09T15:28:30+02:00

Commit Message:
DIRECTOR: Fix noisy cursor comparison errors

Changed paths:
    engines/director/cursor.cpp


diff --git a/engines/director/cursor.cpp b/engines/director/cursor.cpp
index 666beeb7e98..30fc64ea802 100644
--- a/engines/director/cursor.cpp
+++ b/engines/director/cursor.cpp
@@ -51,12 +51,12 @@ CursorRef Cursor::getRef() {
 
 bool Cursor::operator==(const Cursor &c) {
 	return _cursorType == c._cursorType &&
-		c._cursorResId == _cursorResId;
+		(LC::eqData(c._cursorResId, _cursorResId).asInt());
 }
 
 bool Cursor::operator==(const CursorRef &c) {
 	return _cursorType == c._cursorType &&
-			c._cursorResId == _cursorResId;
+			(LC::eqData(c._cursorResId, _cursorResId).asInt());
 }
 
 void Cursor::readFromCast(Datum cursorCasts) {
@@ -67,7 +67,6 @@ void Cursor::readFromCast(Datum cursorCasts) {
 	if (_cursorResId.type == ARRAY && LC::eqData(_cursorResId, cursorCasts).asInt())
 		return;
 
-
 	CastMemberID cursorId = cursorCasts.u.farr->arr[0].asMemberID();
 	CastMember *cursorCast = g_director->getCurrentMovie()->getCastMember(cursorId);
 	if (!cursorCast || cursorCast->_type != kCastBitmap) {
@@ -301,12 +300,12 @@ CursorRef::CursorRef() {
 
 bool CursorRef::operator==(const Cursor &c) {
 	return _cursorType == c._cursorType &&
-		c._cursorResId == _cursorResId;
+		(LC::eqData(c._cursorResId, _cursorResId).asInt());
 }
 
 bool CursorRef::operator==(const CursorRef &c) {
 	return _cursorType == c._cursorType &&
-		c._cursorResId == _cursorResId;
+		(LC::eqData(c._cursorResId, _cursorResId).asInt());
 }
 
 } // End of namespace Director


Commit: 47e20102624a477c377befcca176de7feff10ab9
    https://github.com/scummvm/scummvm/commit/47e20102624a477c377befcca176de7feff10ab9
Author: Scott Percival (code at moral.net.au)
Date: 2025-08-09T15:28:30+02:00

Commit Message:
DIRECTOR: LINGO: Fix c_delete, add more test cases

Changed paths:
    engines/director/lingo/lingo-code.cpp
    engines/director/lingo/tests/delete.lingo


diff --git a/engines/director/lingo/lingo-code.cpp b/engines/director/lingo/lingo-code.cpp
index 15e15e57000..6056d556fa0 100644
--- a/engines/director/lingo/lingo-code.cpp
+++ b/engines/director/lingo/lingo-code.cpp
@@ -1156,6 +1156,9 @@ Datum LC::chunkRef(ChunkType type, int startChunk, int endChunk, const Datum &sr
 	Datum res;
 	res.u.cref = new ChunkReference(src, type, startChunk, endChunk, exprStartIdx, exprEndIdx);
 	res.type = CHUNKREF;
+	if (debugChannelSet(5, kDebugLingoExec)) {
+		debugC(5, kDebugLingoExec, "LC::chunkRef: type: %d, startChunk: %d, endChunk: %d, exprStartIdx: %d, exprEndIdx: %d -> %s", type, startChunk, endChunk, exprStartIdx, exprEndIdx, res.asString(true).c_str());
+	}
 	return res;
 }
 
@@ -1844,10 +1847,15 @@ void LC::c_delete() {
 	Datum field;
 	int start, end;
 	if (d.type == CHUNKREF) {
+		// bail out if the chunk is invalid
+		if (d.u.cref->start == -1)
+			return;
 		start = d.u.cref->start;
 		end = d.u.cref->end;
 		field = d.u.cref->source;
 		while (field.type == CHUNKREF) {
+			if (field.u.cref->start == -1)
+				return;
 			start += field.u.cref->start;
 			end += field.u.cref->start;
 			field = field.u.cref->source;
@@ -1879,12 +1887,19 @@ void LC::c_delete() {
 			break;
 		case kChunkItem:
 		case kChunkLine:
-			// when deleting the first item, include the delimiter after the item
-			// deleting another item, remove the delimiter in front
-			if ((start == 0) || ((start > 0) && (text[start-1] == '\r'))) {
-				end++;
-			} else {
-				start--;
+			{
+				Common::u32char_type_t split = (d.u.cref->type == kChunkItem) ? g_lingo->_itemDelimiter : '\r';
+				bool isFirstItem = (start == 0) || ((start > 0) && (text[start-1] != split));
+				bool isLastItem = (end == ((int)text.size())) || ((end < ((int)text.size())) && (text[end] != split));
+				if (isFirstItem && isLastItem) {
+					// if the target is a whole line, change nothing
+				} else if (isFirstItem) {
+					// when deleting the first item, include the delimiter after the item
+					end++;
+				} else {
+					// deleting another item, remove the delimiter in front
+					start--;
+				}
 			}
 			break;
 		}
diff --git a/engines/director/lingo/tests/delete.lingo b/engines/director/lingo/tests/delete.lingo
index 00c2142e996..84504cca6ed 100644
--- a/engines/director/lingo/tests/delete.lingo
+++ b/engines/director/lingo/tests/delete.lingo
@@ -65,3 +65,29 @@ scummvmAssertEqual(test, "lorem" & RETURN & "ipsum" & RETURN & "dolor" & RETURN
 put "foo" & RETURN & "lorem ipsum" into test
 delete char 3 of word 2 of line 2 of test
 scummvmAssertEqual(test, "foo" & RETURN & "lorem ipum")
+
+put "lorem" & RETURN & "ipsum" & RETURN & "dolor,sit,amet" & RETURN & "nunc" into test
+delete item 1 of line 3 of test
+scummvmAssertEqual(test, "lorem" & RETURN & "ipsum" & RETURN & "sit,amet" & RETURN & "nunc")
+
+put "lorem" & RETURN & "ipsum" & RETURN & "dolor,sit,amet" & RETURN & "nunc" into test
+delete item 2 of line 3 of test
+scummvmAssertEqual(test, "lorem" & RETURN & "ipsum" & RETURN & "dolor,amet" & RETURN & "nunc")
+
+put "lorem" & RETURN & "ipsum" & RETURN & "dolor,sit,amet" & RETURN & "nunc" into test
+delete item 3 of line 3 of test
+scummvmAssertEqual(test, "lorem" & RETURN & "ipsum" & RETURN & "dolor,sit" & RETURN & "nunc")
+
+put "lorem" & RETURN & "ipsum" & RETURN & "dolor,sit,amet" & RETURN & "nunc" into test
+delete item 1 of line 2 of test
+scummvmAssertEqual(test, "lorem" & RETURN & RETURN & "dolor,sit,amet" & RETURN & "nunc")
+delete item 1 of line 2 of test
+scummvmAssertEqual(test, "lorem" & RETURN & RETURN & "dolor,sit,amet" & RETURN & "nunc")
+delete item 4 of line 2 of test
+scummvmAssertEqual(test, "lorem" & RETURN & RETURN & "dolor,sit,amet" & RETURN & "nunc")
+delete item 4 of line 4 of test
+scummvmAssertEqual(test, "lorem" & RETURN & RETURN & "dolor,sit,amet" & RETURN & "nunc")
+delete item 1 of line 4 of test
+scummvmAssertEqual(test, "lorem" & RETURN & RETURN & "dolor,sit,amet" & RETURN)
+
+


Commit: a3564d0df81432ab2b737ae6fb59162ada9bc922
    https://github.com/scummvm/scummvm/commit/a3564d0df81432ab2b737ae6fb59162ada9bc922
Author: Scott Percival (code at moral.net.au)
Date: 2025-08-09T15:28:30+02:00

Commit Message:
DIRECTOR: LINGO: Format test output to fix linebreaks

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


diff --git a/engines/director/lingo/lingo-builtins.cpp b/engines/director/lingo/lingo-builtins.cpp
index dac1d45768d..165addecc08 100644
--- a/engines/director/lingo/lingo-builtins.cpp
+++ b/engines/director/lingo/lingo-builtins.cpp
@@ -3818,7 +3818,7 @@ void LB::b_scummvmassertequal(int nargs) {
 	}
 
 	if (!result) {
-		warning("BUILDBOT: LB::b_scummvmassertequals: %s is not equal %s at line %d", d1.asString().c_str(), d2.asString().c_str(), line.asInt());
+		warning("BUILDBOT: LB::b_scummvmassertequal: %s is not equal %s at line %d", formatStringForDump(d1.asString()).c_str(), formatStringForDump(d2.asString()).c_str(), line.asInt());
 	}
 	if (debugChannelSet(-1, kDebugLingoStrict)) {
 		assert(result == 1);


Commit: 3fa52f0f773eb303a0dd0a1b21a08a5c509b5206
    https://github.com/scummvm/scummvm/commit/3fa52f0f773eb303a0dd0a1b21a08a5c509b5206
Author: Scott Percival (code at moral.net.au)
Date: 2025-08-09T15:28:30+02:00

Commit Message:
DIRECTOR: XOBJ: Add quirk for overriding FileIO type

Changed paths:
    engines/director/director.cpp
    engines/director/director.h
    engines/director/game-quirks.cpp
    engines/director/lingo/xlibs/fileio.cpp


diff --git a/engines/director/director.cpp b/engines/director/director.cpp
index eb1fc9c1c9c..c200111d94b 100644
--- a/engines/director/director.cpp
+++ b/engines/director/director.cpp
@@ -106,6 +106,7 @@ DirectorEngine::DirectorEngine(OSystem *syst, const DirectorGameDescription *gam
 	_forceDate.tm_wday = -1;
 	_loadSlowdownFactor = 0;
 	_loadSlowdownCooldownTime = 0;
+	_fileIOType = 0;
 
 	_wm = nullptr;
 
diff --git a/engines/director/director.h b/engines/director/director.h
index 277c940b042..abfd2a09ca9 100644
--- a/engines/director/director.h
+++ b/engines/director/director.h
@@ -301,6 +301,7 @@ public:
 	TimeDate _forceDate;
 	uint32 _loadSlowdownFactor;
 	uint32 _loadSlowdownCooldownTime;
+	int _fileIOType;
 
 private:
 	byte _currentPalette[768];
diff --git a/engines/director/game-quirks.cpp b/engines/director/game-quirks.cpp
index 981e8eefe7a..9aa848bd19d 100644
--- a/engines/director/game-quirks.cpp
+++ b/engines/director/game-quirks.cpp
@@ -148,6 +148,14 @@ static void quirkPretend16Bit() {
 	g_director->_colorDepth = 16;
 }
 
+static void quirkForceFileIOXObj() {
+	g_director->_fileIOType = kXObj;
+}
+
+static void quirkForceFileIOXtra() {
+	g_director->_fileIOType = kXtraObj;
+}
+
 static void quirkHollywoodHigh() {
 	// Hollywood High demo has a killswitch that stops playback
 	// if the year is after 1996.
@@ -263,6 +271,18 @@ const struct Quirk {
 	{ "flipper", Common::kPlatformMacintosh, &quirkPretend16Bit },
 	{ "flipper", Common::kPlatformWindows, &quirkPretend16Bit },
 
+	// The standard FileIO xlib exists as both an XObject and Xtra version, with similar functionality
+	// but incompatible APIs.
+	// We don't currently do any kind of introspection apart from filename, so for now here's a hint.
+	// Puppet Motel New Edition includes the Xtra edition in the Xtra folder, but embeds the XObject
+	// in the projector as a resource. New edition expects Xtra, old edition is D4 and won't be affected.
+	{ "puppetmotel", Common::kPlatformWindows, &quirkForceFileIOXtra },
+	{ "puppetmotel", Common::kPlatformMacintosh, &quirkForceFileIOXtra },
+	// Ingenious bundles both the Xtra and XObject editions in the Xtra folder, but expects the XObject
+	// version to be available.
+	{ "ingenious", Common::kPlatformWindows, &quirkForceFileIOXObj },
+	{ "ingenious", Common::kPlatformMacintosh, &quirkForceFileIOXObj },
+
 	{ nullptr, Common::kPlatformUnknown, nullptr }
 };
 
diff --git a/engines/director/lingo/xlibs/fileio.cpp b/engines/director/lingo/xlibs/fileio.cpp
index 08a768591b1..8ef6feca48d 100644
--- a/engines/director/lingo/xlibs/fileio.cpp
+++ b/engines/director/lingo/xlibs/fileio.cpp
@@ -188,8 +188,14 @@ static const BuiltinProto xlibBuiltins[] = {
 
 void FileIO::open(ObjectType type, const Common::Path &path) {
 	FileObject::initMethods(xlibMethods);
+	// manual override for game quirks
+	if (g_director->_fileIOType == kXtraObj && g_director->getVersion() >= 500) {
+		type = kXtraObj;
+	} else if (g_director->_fileIOType == kXObj) {
+		type = kXObj;
+	}
 	FileObject *xobj = new FileObject(type);
-	if (g_director->getVersion() >= 500)
+	if (type == kXtraObj)
 		g_lingo->_openXtras.push_back(xlibName);
 	g_lingo->exposeXObject(xlibName, xobj);
 	g_lingo->initBuiltIns(xlibBuiltins);


Commit: c552509d77dc923fcefbd7d93a484e3367fa1d2c
    https://github.com/scummvm/scummvm/commit/c552509d77dc923fcefbd7d93a484e3367fa1d2c
Author: Scott Percival (code at moral.net.au)
Date: 2025-08-09T15:28:30+02:00

Commit Message:
DIRECTOR: Improve accuracy of editable flag

For text cast members, the cast _editable flag and the sprite-level
_editable flag are ORed together when updating the widget. Don't merge
the status into the sprite flag, as this state is separate.

Fixes save game text box editability in Elroy Goes Bugzerk.

Changed paths:
    engines/director/castmember/text.cpp
    engines/director/channel.cpp
    engines/director/sprite.cpp
    engines/director/sprite.h


diff --git a/engines/director/castmember/text.cpp b/engines/director/castmember/text.cpp
index e7b6865ffde..460c579c293 100644
--- a/engines/director/castmember/text.cpp
+++ b/engines/director/castmember/text.cpp
@@ -331,11 +331,11 @@ Graphics::MacWidget *TextCastMember::createWidget(Common::Rect &bbox, Channel *c
 		}
 		widget = createWindowOrWidget(bbox, dims, macFont);
 		if (_textType != kTextTypeScrolling) {
-			((Graphics::MacText *)widget)->setEditable(channel->_sprite->_editable);
+			((Graphics::MacText *)widget)->setEditable(channel->_sprite->_editable || _editable);
 		}
 
 		// since we disable the ability of setActive in setEdtiable, then we need to set active widget manually
-		if (channel->_sprite->_editable) {
+		if (channel->_sprite->_editable || _editable) {
 			Graphics::MacWidget *activeWidget = g_director->_wm->getActiveWidget();
 			if (activeWidget == nullptr || !activeWidget->isEditable())
 				g_director->_wm->setActiveWidget(widget);
diff --git a/engines/director/channel.cpp b/engines/director/channel.cpp
index 540d1930346..2090cb987b8 100644
--- a/engines/director/channel.cpp
+++ b/engines/director/channel.cpp
@@ -61,9 +61,6 @@ Channel::Channel(Score *sc, Sprite *sp, int priority) {
 
 	_visible = true;
 	_dirty = true;
-
-	if (_sprite)
-		_sprite->updateEditable();
 }
 
 Channel::Channel(const Channel &channel) {
@@ -451,7 +448,6 @@ void Channel::setClean(Sprite *nextSprite, bool partial) {
 	// for the dirty puppet sprites, we will always replaceWidget since previousCastId is 0, but we shouldn't replace the widget of there are only position changing
 	// e.g. we won't want a puppet editable text sprite changing because that will cause the loss of text.
 	if (replace) {
-		_sprite->updateEditable();
 		replaceWidget(previousCastId, dimsChanged || spriteTypeChanged);
 	}
 
@@ -488,8 +484,7 @@ void Channel::updateTextCast() {
 	if (!_sprite->_cast || _sprite->_cast->_type != kCastText)
 		return;
 
-	_sprite->updateEditable();
-	setEditable(_sprite->_editable);
+	setEditable(_sprite->getEditable());
 
 	if (_widget) {
 		Graphics::MacText *textWidget = (Graphics::MacText *)_widget;
diff --git a/engines/director/sprite.cpp b/engines/director/sprite.cpp
index a5e4138f03b..843af364693 100644
--- a/engines/director/sprite.cpp
+++ b/engines/director/sprite.cpp
@@ -290,12 +290,11 @@ uint32 Sprite::getForeColor() {
 	}
 }
 
-void Sprite::updateEditable() {
+bool Sprite::getEditable() {
 	if (!_cast)
-		return;
+		return _editable;
 
-	if (!_puppet)
-		_editable = _editable || _cast->isEditable();
+	return _editable || _cast->isEditable();
 }
 
 bool Sprite::respondsToMouse() {
diff --git a/engines/director/sprite.h b/engines/director/sprite.h
index 1b44615747f..765fb70bfc2 100644
--- a/engines/director/sprite.h
+++ b/engines/director/sprite.h
@@ -65,7 +65,7 @@ public:
 
 	void reset();
 
-	void updateEditable();
+	bool getEditable();
 
 	bool respondsToMouse();
 	bool isActive();


Commit: 973b5a8f5aa1a7f9e289d352b604bef00166fd58
    https://github.com/scummvm/scummvm/commit/973b5a8f5aa1a7f9e289d352b604bef00166fd58
Author: Scott Percival (code at moral.net.au)
Date: 2025-08-09T15:28:30+02:00

Commit Message:
DIRECTOR: Add detection entry for Elroy Goes Bugzerk

Changed paths:
    engines/director/detection_tables.h


diff --git a/engines/director/detection_tables.h b/engines/director/detection_tables.h
index 64260fbca7d..3eb9632e04e 100644
--- a/engines/director/detection_tables.h
+++ b/engines/director/detection_tables.h
@@ -4185,6 +4185,8 @@ static const DirectorGameDescription gameDescriptions[] = {
 	// Demo is found on Pantsylvania CD
 	MACGAME1("elroybug", "", "Elroy Goes Bugzerk", "r:ea646eccc9a53f44ce082459d4809a06", 520674, 400),
 	WINGAME1("elroybug", "", "BUGZERK.EXE", "t:3be9fa389257a608ff21e09074355fa5", 1593811, 400),
+	MACGAME1("elroybug", "1.0", "Elroy Goes Bugzerk", "r:cbce20666bfe47a9533331c6be1e6039", 321438, 404),
+	WINGAME1("elroybug", "1.0", "BUGZERK.EXE", "t:7fcb09d5dcc8096cd7ffa1fd618e5500", 1561075, 404),
 	MACDEMO1("elroybug", "Demo", "Elroy Goes Bugzerk Demo", "bcd3c718db258701496b3c5bcb827ef2", 498394, 404),
 	WINDEMO1("elroybug", "Demo", "ELRYDEMO.EXE", "cb2d86ea52d81d12d1fe8eadfb4a118c", 2438763, 404),
 


Commit: fa9368799cf9dca1a886e8f2a639fa52b87ea99f
    https://github.com/scummvm/scummvm/commit/fa9368799cf9dca1a886e8f2a639fa52b87ea99f
Author: Scott Percival (code at moral.net.au)
Date: 2025-08-09T15:28:30+02:00

Commit Message:
DIRECTOR: LINGO: Improve accuracy of keyUp/keyDown events

In Director, you can set a sprite script with a keyUp/keyDown handler,
and it will be called if that sprite is currently the active widget.

Fixes save text entry callback in Elroy Goes Bugzerk.

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


diff --git a/engines/director/events.cpp b/engines/director/events.cpp
index 6fa300b6cb7..0a569733053 100644
--- a/engines/director/events.cpp
+++ b/engines/director/events.cpp
@@ -256,11 +256,12 @@ bool Movie::processEvent(Common::Event &event) {
 		if (_timeOutKeyDown)
 			_lastTimeOut = _lastEventTime;
 
-		queueInputEvent(kEventKeyDown);
+		queueInputEvent(kEventKeyDown, sc->getSpriteIDOfActiveWidget());
 		g_director->loadSlowdownCooloff();
 		return true;
 
 	case Common::EVENT_KEYUP:
+		queueInputEvent(kEventKeyUp, sc->getSpriteIDOfActiveWidget());
 		_keyFlags = event.kbd.flags;
 		return true;
 
diff --git a/engines/director/lingo/lingo-events.cpp b/engines/director/lingo/lingo-events.cpp
index 45f75155e05..49bcfff8244 100644
--- a/engines/director/lingo/lingo-events.cpp
+++ b/engines/director/lingo/lingo-events.cpp
@@ -408,6 +408,11 @@ void Movie::queueEvent(Common::Queue<LingoEvent> &queue, LEvent event, int targe
 			// As per above, by default this will pass through to any subsequent handlers,
 			// unless the script calls "dontPassEvent".
 			queue.push(LingoEvent(event, eventId, kPrimaryHandler, true, pos));
+
+			// Key up and key down events can be sent to the channel with an active widget
+			if ((event == kEventKeyUp) || (event == kEventKeyDown)) {
+				channelId = targetId;
+			}
 		}
 		break;
 	case kEventMenuCallback:
diff --git a/engines/director/score.cpp b/engines/director/score.cpp
index b6d1eafbe2a..d32c4343e43 100644
--- a/engines/director/score.cpp
+++ b/engines/director/score.cpp
@@ -1515,6 +1515,17 @@ void Score::screenShot() {
 #endif // USE_PNG
 }
 
+uint16 Score::getSpriteIDOfActiveWidget() {
+	Graphics::MacWidget *active = g_director->_wm->getActiveWidget();
+	if (!active)
+		return 0;
+	for (int i = _channels.size() - 1; i >= 0; i--) {
+		if (active == _channels[i]->_widget)
+			return i;
+	}
+	return 0;
+}
+
 uint16 Score::getSpriteIDFromPos(Common::Point pos) {
 	for (int i = _channels.size() - 1; i >= 0; i--) {
 		CollisionTest test = _channels[i]->isMouseIn(pos);
diff --git a/engines/director/score.h b/engines/director/score.h
index 8be8414434c..ce182d6fe8e 100644
--- a/engines/director/score.h
+++ b/engines/director/score.h
@@ -109,6 +109,7 @@ public:
 	int getCurrentLabelNumber();
 	int getNextLabelNumber(int referenceFrame);
 
+	uint16 getSpriteIDOfActiveWidget();
 	uint16 getSpriteIDFromPos(Common::Point pos);
 	uint16 getMouseSpriteIDFromPos(Common::Point pos);
 	uint16 getActiveSpriteIDFromPos(Common::Point pos);


Commit: 86a68643cd9a3161c3bd945738bd957ae09ea1a6
    https://github.com/scummvm/scummvm/commit/86a68643cd9a3161c3bd945738bd957ae09ea1a6
Author: Scott Percival (code at moral.net.au)
Date: 2025-08-09T15:28:30+02:00

Commit Message:
DIRECTOR: Reset puppet flag of score sound channels

This flag is not persisted when the movie is switched out.

Fixes transition between intro3.dxr and intro4.dxr in Elroy Goes
Bugzerk.

Changed paths:
    engines/director/score.cpp
    engines/director/sound.cpp
    engines/director/sound.h


diff --git a/engines/director/score.cpp b/engines/director/score.cpp
index d32c4343e43..20615b0b64f 100644
--- a/engines/director/score.cpp
+++ b/engines/director/score.cpp
@@ -332,6 +332,9 @@ void Score::startPlay() {
 
 	updateSprites(kRenderForceUpdate, true);
 
+	_soundManager->disablePuppetSound(1);
+	_soundManager->disablePuppetSound(2);
+
 	if (_vm->getVersion() >= 300)
 		_movie->processEvent(kEventStartMovie);
 }
diff --git a/engines/director/sound.cpp b/engines/director/sound.cpp
index ffe34116464..bd32cb58553 100644
--- a/engines/director/sound.cpp
+++ b/engines/director/sound.cpp
@@ -577,6 +577,13 @@ void DirectorSound::setPuppetSound(SoundID soundId, int soundChannel) {
 	}
 }
 
+void DirectorSound::disablePuppetSound(int soundChannel) {
+	if (!assertChannel(soundChannel))
+		return;
+
+	_channels[soundChannel]->puppet = SoundID();
+}
+
 void DirectorSound::playPuppetSound(int soundChannel) {
 	if (!assertChannel(soundChannel))
 		return;
diff --git a/engines/director/sound.h b/engines/director/sound.h
index 56bef9dd708..8dedb9673fa 100644
--- a/engines/director/sound.h
+++ b/engines/director/sound.h
@@ -201,6 +201,7 @@ public:
 
 	bool isChannelPuppet(int soundChannel);
 	void setPuppetSound(SoundID soundId, int soundChannel);
+	void disablePuppetSound(int soundChannel);
 	void playPuppetSound(int soundChannel);
 
 	bool getSoundEnabled() { return _enable; }


Commit: 4d6cd80e24fba55e9d69444a47e0c65f1b8d16d9
    https://github.com/scummvm/scummvm/commit/4d6cd80e24fba55e9d69444a47e0c65f1b8d16d9
Author: Scott Percival (code at moral.net.au)
Date: 2025-08-09T15:28:30+02:00

Commit Message:
DIRECTOR: Improve accuracy of b_puppetSound(0)

Fixes sound playback when picking up the furoshiki in Eastern Mind.

Changed paths:
    engines/director/sound.cpp


diff --git a/engines/director/sound.cpp b/engines/director/sound.cpp
index bd32cb58553..df60ecf26f6 100644
--- a/engines/director/sound.cpp
+++ b/engines/director/sound.cpp
@@ -569,8 +569,11 @@ void DirectorSound::setPuppetSound(SoundID soundId, int soundChannel) {
 		return;
 
 	if (soundId.isZero()) {
+		// If soundId is zero, kill the current sound and clear the puppet flag.
 		stopSound(soundChannel);
+		disablePuppetSound(soundChannel);
 	} else {
+		// soundId is non-zero, set the puppet sound value to that.
 		_channels[soundChannel]->newPuppet = true;
 		_channels[soundChannel]->puppet = soundId;
 		_channels[soundChannel]->stopOnZero = true;




More information about the Scummvm-git-logs mailing list