[Scummvm-git-logs] scummvm master -> f5b2c47614cf271c74937f9120435442eedb5b50

sev- noreply at scummvm.org
Sun Mar 31 14:58:41 UTC 2024


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

Summary:
18da5fb1c2 DIRECTOR: XOBJ: Add XFCN/XCMD stubs from The Seven Colors
e8e1a2948d DIRECTOR: Exclude modifier keys from keyDown/keyUp events
f26fad6182 DIRECTOR: XOBJ: Fix regressions in FileIO
5df3b7b8cd DIRECTOR: Playing a sound after a fade should restore the volume
c301c1f2b5 DIRECTOR: Fix film-loop loading
d43612db85 DIRECTOR: XOBJ: Refactor methods to pass path to library
95ca062e6d DIRECTOR: Always disable puppet sounds on movie change
637caad1c3 DIRECTOR: Fix setting "the volume of sound"
12cf67948d DIRECTOR: Allow multiple concurrent sound fades
e2a46585e5 DIRECTOR: Add actions command to debugger
403c923342 DIRECTOR: XOBJ: Implement RemixXCMD from The Seven Colors
0c65e4a2e4 DIRECTOR: LINGO: Add script patch for Rodney's Fun Screen
8050b050f5 DIRECTOR: Update detection tables
d285d1a9d5 DIRECTOR: Add guardrail for empty film loops
f3bdc30464 DIRECTOR: Prevent negative rect dimensions in transition code
f5b2c47614 DIRECTOR: XOBJ: Refactor RemixXCMD to have proper memory management


Commit: 18da5fb1c2e019e10fe5a46fd1222404e4108e34
    https://github.com/scummvm/scummvm/commit/18da5fb1c2e019e10fe5a46fd1222404e4108e34
Author: Scott Percival (code at moral.net.au)
Date: 2024-03-31T16:58:31+02:00

Commit Message:
DIRECTOR: XOBJ: Add XFCN/XCMD stubs from The Seven Colors

Changed paths:
  A engines/director/lingo/xlibs/closebleedwindowxcmd.cpp
  A engines/director/lingo/xlibs/closebleedwindowxcmd.h
  A engines/director/lingo/xlibs/getscreenrectsxfcn.cpp
  A engines/director/lingo/xlibs/getscreenrectsxfcn.h
  A engines/director/lingo/xlibs/getscreensizexfcn.cpp
  A engines/director/lingo/xlibs/getscreensizexfcn.h
  A engines/director/lingo/xlibs/openbleedwindowxcmd.cpp
  A engines/director/lingo/xlibs/openbleedwindowxcmd.h
  A engines/director/lingo/xlibs/portaxcmd.cpp
  A engines/director/lingo/xlibs/portaxcmd.h
  A engines/director/lingo/xlibs/remixxcmd.cpp
  A engines/director/lingo/xlibs/remixxcmd.h
    engines/director/lingo/lingo-object.cpp
    engines/director/module.mk


diff --git a/engines/director/lingo/lingo-object.cpp b/engines/director/lingo/lingo-object.cpp
index 571e44c137a..ca0cd4f152d 100644
--- a/engines/director/lingo/lingo-object.cpp
+++ b/engines/director/lingo/lingo-object.cpp
@@ -36,6 +36,7 @@
 #include "director/lingo/xlibs/batqt.h"
 #include "director/lingo/xlibs/blitpict.h"
 #include "director/lingo/xlibs/cdromxobj.h"
+#include "director/lingo/xlibs/closebleedwindowxcmd.h"
 #include "director/lingo/xlibs/colorxobj.h"
 #include "director/lingo/xlibs/colorcursorxobj.h"
 #include "director/lingo/xlibs/consumer.h"
@@ -63,6 +64,8 @@
 #include "director/lingo/xlibs/findwin.h"
 #include "director/lingo/xlibs/flushxobj.h"
 #include "director/lingo/xlibs/fplayxobj.h"
+#include "director/lingo/xlibs/getscreenrectsxfcn.h"
+#include "director/lingo/xlibs/getscreensizexfcn.h"
 #include "director/lingo/xlibs/gpid.h"
 #include "director/lingo/xlibs/hitmap.h"
 #include "director/lingo/xlibs/jwxini.h"
@@ -81,11 +84,13 @@
 #include "director/lingo/xlibs/movemousexobj.h"
 #include "director/lingo/xlibs/movieidxxobj.h"
 #include "director/lingo/xlibs/movutils.h"
+#include "director/lingo/xlibs/openbleedwindowxcmd.h"
 #include "director/lingo/xlibs/orthoplayxobj.h"
 #include "director/lingo/xlibs/palxobj.h"
 #include "director/lingo/xlibs/panel.h"
 #include "director/lingo/xlibs/popupmenuxobj.h"
 #include "director/lingo/xlibs/porta.h"
+#include "director/lingo/xlibs/portaxcmd.h"
 #include "director/lingo/xlibs/prefpath.h"
 #include "director/lingo/xlibs/printomatic.h"
 #include "director/lingo/xlibs/processxobj.h"
@@ -94,6 +99,7 @@
 #include "director/lingo/xlibs/qtvr.h"
 #include "director/lingo/xlibs/quicktime.h"
 #include "director/lingo/xlibs/registercomponent.h"
+#include "director/lingo/xlibs/remixxcmd.h"
 #include "director/lingo/xlibs/serialportxobj.h"
 #include "director/lingo/xlibs/soundjam.h"
 #include "director/lingo/xlibs/spacemgr.h"
@@ -190,6 +196,7 @@ static struct XLibProto {
 	{ BatQT::fileNames,					BatQT::open,				BatQT::close,				kXObj,					400 },	// D4
 	{ BlitPictXObj::fileNames,			BlitPictXObj::open,			BlitPictXObj::close,		kXObj,					400 },	// D4
 	{ CDROMXObj::fileNames,				CDROMXObj::open,			CDROMXObj::close,			kXObj,					200 },	// D2
+	{ CloseBleedWindowXCMD::fileNames,			CloseBleedWindowXCMD::open,			CloseBleedWindowXCMD::close,		kXObj,					300 },	// D3
 	{ ColorXObj::fileNames,				ColorXObj::open,			ColorXObj::close,			kXObj,					400 },	// D4
 	{ ColorCursorXObj::fileNames,		ColorCursorXObj::open,		ColorCursorXObj::close,		kXObj,					400 },	// D4
 	{ ConsumerXObj::fileNames,			ConsumerXObj::open,			ConsumerXObj::close,		kXObj,					400 },	// D4
@@ -217,6 +224,8 @@ static struct XLibProto {
 	{ FinderEventsXCMD::fileNames,		FinderEventsXCMD::open,		FinderEventsXCMD::close,	kXObj,					400 },	// D4
 	{ FlushXObj::fileNames,				FlushXObj::open,			FlushXObj::close,			kXObj,					300 },	// D3
 	{ FPlayXObj::fileNames,				FPlayXObj::open,			FPlayXObj::close,			kXObj,					200 },	// D2
+	{ GetScreenRectsXFCN::fileNames,			GetScreenRectsXFCN::open,			GetScreenRectsXFCN::close,		kXObj,					300 },	// D3
+	{ GetScreenSizeXFCN::fileNames,			GetScreenSizeXFCN::open,			GetScreenSizeXFCN::close,		kXObj,					300 },	// D3
 	{ GpidXObj::fileNames,				GpidXObj::open,				GpidXObj::close,			kXObj,					400 },	// D4
 	{ HitMap::fileNames,				HitMap::open,				HitMap::close,				kXObj,					400 },	// D4
 	{ IsCD::fileNames,					IsCD::open,					IsCD::close,				kXObj,					300 },	// D3
@@ -235,11 +244,13 @@ static struct XLibProto {
 	{ MoveMouseXObj::fileNames,			MoveMouseXObj::open,		MoveMouseXObj::close,		kXObj,					400 },	// D4
 	{ MovieIdxXObj::fileNames,			MovieIdxXObj::open,			MovieIdxXObj::close,		kXObj,					400 },	// D4
 	{ MovUtilsXObj::fileNames,			MovUtilsXObj::open,			MovUtilsXObj::close,		kXObj,					400 },	// D4
+	{ OpenBleedWindowXCMD::fileNames,			OpenBleedWindowXCMD::open,			OpenBleedWindowXCMD::close,		kXObj,					300 },	// D3
 	{ OrthoPlayXObj::fileNames,			OrthoPlayXObj::open,		OrthoPlayXObj::close,		kXObj,					400 },	// D4
 	{ PalXObj::fileNames,				PalXObj::open,				PalXObj::close,				kXObj,					400 },	// D4
 	{ PanelXObj::fileNames,				PanelXObj::open,			PanelXObj::close,			kXObj,					200 },	// D2
 	{ PopUpMenuXObj::fileNames,			PopUpMenuXObj::open,		PopUpMenuXObj::close,		kXObj,					200 },	// D2
 	{ Porta::fileNames,					Porta::open,				Porta::close,				kXObj,					300 },	// D3
+	{ PortaXCMD::fileNames,			PortaXCMD::open,			PortaXCMD::close,		kXObj,					300 },	// D3
 	{ PrefPath::fileNames,				PrefPath::open,				PrefPath::close,			kXObj,					400 },	// D4
 	{ PrintOMaticXObj::fileNames,		PrintOMaticXObj::open,		PrintOMaticXObj::close,		kXObj,					400 },	// D4
 	{ ProcessXObj::fileNames,			ProcessXObj::open,			ProcessXObj::close,		kXObj,					400 },	// D4
@@ -249,6 +260,7 @@ static struct XLibProto {
 	{ Quicktime::fileNames,				Quicktime::open,			Quicktime::close,			kXObj,					300 },	// D3
 	{ RearWindowXObj::fileNames,		RearWindowXObj::open,		RearWindowXObj::close,		kXObj,					400 },	// D4
 	{ RegisterComponent::fileNames,		RegisterComponent::open,	RegisterComponent::close,	kXObj,					400 },	// D4
+	{ RemixXCMD::fileNames,			RemixXCMD::open,			RemixXCMD::close,		kXObj,					300 },	// D3
 	{ ScrnUtilXtra::fileNames,			ScrnUtilXtra::open,			ScrnUtilXtra::close,		kXtraObj,					500 },	// D5
 	{ SerialPortXObj::fileNames,		SerialPortXObj::open,		SerialPortXObj::close,		kXObj,					200 },	// D2
 	{ SoundJam::fileNames,				SoundJam::open,				SoundJam::close,			kXObj,					400 },	// D4
diff --git a/engines/director/lingo/xlibs/closebleedwindowxcmd.cpp b/engines/director/lingo/xlibs/closebleedwindowxcmd.cpp
new file mode 100644
index 00000000000..e431c90c20d
--- /dev/null
+++ b/engines/director/lingo/xlibs/closebleedwindowxcmd.cpp
@@ -0,0 +1,60 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "common/system.h"
+
+#include "director/director.h"
+#include "director/lingo/lingo.h"
+#include "director/lingo/lingo-object.h"
+#include "director/lingo/lingo-utils.h"
+#include "director/lingo/xlibs/closebleedwindowxcmd.h"
+
+/**************************************************
+ *
+ * USED IN:
+ * the7colors
+ *
+ **************************************************/
+
+namespace Director {
+
+const char *CloseBleedWindowXCMD::xlibName = "CloseBleedWindow";
+const char *CloseBleedWindowXCMD::fileNames[] = {
+	"CloseBleedWindow",
+	nullptr
+};
+
+static BuiltinProto builtins[] = {
+	{ "CloseBleedWindow", CloseBleedWindowXCMD::m_CloseBleedWindow, -1, 0, 300, CBLTIN },
+	{ nullptr, nullptr, 0, 0, 0, VOIDSYM }
+};
+
+void CloseBleedWindowXCMD::open(ObjectType type) {
+	g_lingo->initBuiltIns(builtins);
+}
+
+void CloseBleedWindowXCMD::close(ObjectType type) {
+	g_lingo->cleanupBuiltIns(builtins);
+}
+
+XOBJSTUB(CloseBleedWindowXCMD::m_CloseBleedWindow, 0)
+
+}
diff --git a/engines/director/lingo/xlibs/closebleedwindowxcmd.h b/engines/director/lingo/xlibs/closebleedwindowxcmd.h
new file mode 100644
index 00000000000..c72c06489fa
--- /dev/null
+++ b/engines/director/lingo/xlibs/closebleedwindowxcmd.h
@@ -0,0 +1,41 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef DIRECTOR_LINGO_XLIBS_CLOSEBLEEDWINDOWXCMD_H
+#define DIRECTOR_LINGO_XLIBS_CLOSEBLEEDWINDOWXCMD_H
+
+namespace Director {
+
+namespace CloseBleedWindowXCMD {
+
+extern const char *xlibName;
+extern const char *fileNames[];
+
+void open(ObjectType type);
+void close(ObjectType type);
+
+void m_CloseBleedWindow(int nargs);
+
+} // End of namespace CloseBleedWindowXCMD
+
+} // End of namespace Director
+
+#endif
diff --git a/engines/director/lingo/xlibs/getscreenrectsxfcn.cpp b/engines/director/lingo/xlibs/getscreenrectsxfcn.cpp
new file mode 100644
index 00000000000..a8c16aa29fe
--- /dev/null
+++ b/engines/director/lingo/xlibs/getscreenrectsxfcn.cpp
@@ -0,0 +1,60 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "common/system.h"
+
+#include "director/director.h"
+#include "director/lingo/lingo.h"
+#include "director/lingo/lingo-object.h"
+#include "director/lingo/lingo-utils.h"
+#include "director/lingo/xlibs/getscreenrectsxfcn.h"
+
+/**************************************************
+ *
+ * USED IN:
+ * the7colors
+ *
+ **************************************************/
+
+namespace Director {
+
+const char *GetScreenRectsXFCN::xlibName = "GetScreenRects";
+const char *GetScreenRectsXFCN::fileNames[] = {
+	"GetScreenRects",
+	nullptr
+};
+
+static BuiltinProto builtins[] = {
+	{ "GetScreenRects", GetScreenRectsXFCN::m_GetScreenRects, -1, 0, 300, HBLTIN },
+	{ nullptr, nullptr, 0, 0, 0, VOIDSYM }
+};
+
+void GetScreenRectsXFCN::open(ObjectType type) {
+	g_lingo->initBuiltIns(builtins);
+}
+
+void GetScreenRectsXFCN::close(ObjectType type) {
+	g_lingo->cleanupBuiltIns(builtins);
+}
+
+XOBJSTUB(GetScreenRectsXFCN::m_GetScreenRects, 0)
+
+}
diff --git a/engines/director/lingo/xlibs/getscreenrectsxfcn.h b/engines/director/lingo/xlibs/getscreenrectsxfcn.h
new file mode 100644
index 00000000000..9a69db43008
--- /dev/null
+++ b/engines/director/lingo/xlibs/getscreenrectsxfcn.h
@@ -0,0 +1,41 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef DIRECTOR_LINGO_XLIBS_GETSCREENRECTSXFCN_H
+#define DIRECTOR_LINGO_XLIBS_GETSCREENRECTSXFCN_H
+
+namespace Director {
+
+namespace GetScreenRectsXFCN {
+
+extern const char *xlibName;
+extern const char *fileNames[];
+
+void open(ObjectType type);
+void close(ObjectType type);
+
+void m_GetScreenRects(int nargs);
+
+} // End of namespace GetScreenRectsXFCN
+
+} // End of namespace Director
+
+#endif
diff --git a/engines/director/lingo/xlibs/getscreensizexfcn.cpp b/engines/director/lingo/xlibs/getscreensizexfcn.cpp
new file mode 100644
index 00000000000..23bbc0f90c5
--- /dev/null
+++ b/engines/director/lingo/xlibs/getscreensizexfcn.cpp
@@ -0,0 +1,60 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "common/system.h"
+
+#include "director/director.h"
+#include "director/lingo/lingo.h"
+#include "director/lingo/lingo-object.h"
+#include "director/lingo/lingo-utils.h"
+#include "director/lingo/xlibs/getscreensizexfcn.h"
+
+/**************************************************
+ *
+ * USED IN:
+ * the7colors
+ *
+ **************************************************/
+
+namespace Director {
+
+const char *GetScreenSizeXFCN::xlibName = "GetScreenSize";
+const char *GetScreenSizeXFCN::fileNames[] = {
+	"GetScreenSize",
+	nullptr
+};
+
+static BuiltinProto builtins[] = {
+	{ "GetScreenSize", GetScreenSizeXFCN::m_GetScreenSize, -1, 0, 300, HBLTIN },
+	{ nullptr, nullptr, 0, 0, 0, VOIDSYM }
+};
+
+void GetScreenSizeXFCN::open(ObjectType type) {
+	g_lingo->initBuiltIns(builtins);
+}
+
+void GetScreenSizeXFCN::close(ObjectType type) {
+	g_lingo->cleanupBuiltIns(builtins);
+}
+
+XOBJSTUB(GetScreenSizeXFCN::m_GetScreenSize, 0)
+
+}
diff --git a/engines/director/lingo/xlibs/getscreensizexfcn.h b/engines/director/lingo/xlibs/getscreensizexfcn.h
new file mode 100644
index 00000000000..2c389ff5438
--- /dev/null
+++ b/engines/director/lingo/xlibs/getscreensizexfcn.h
@@ -0,0 +1,41 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef DIRECTOR_LINGO_XLIBS_GETSCREENSIZEXFCN_H
+#define DIRECTOR_LINGO_XLIBS_GETSCREENSIZEXFCN_H
+
+namespace Director {
+
+namespace GetScreenSizeXFCN {
+
+extern const char *xlibName;
+extern const char *fileNames[];
+
+void open(ObjectType type);
+void close(ObjectType type);
+
+void m_GetScreenSize(int nargs);
+
+} // End of namespace GetScreenSizeXFCN
+
+} // End of namespace Director
+
+#endif
diff --git a/engines/director/lingo/xlibs/openbleedwindowxcmd.cpp b/engines/director/lingo/xlibs/openbleedwindowxcmd.cpp
new file mode 100644
index 00000000000..338f1f7df86
--- /dev/null
+++ b/engines/director/lingo/xlibs/openbleedwindowxcmd.cpp
@@ -0,0 +1,60 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "common/system.h"
+
+#include "director/director.h"
+#include "director/lingo/lingo.h"
+#include "director/lingo/lingo-object.h"
+#include "director/lingo/lingo-utils.h"
+#include "director/lingo/xlibs/openbleedwindowxcmd.h"
+
+/**************************************************
+ *
+ * USED IN:
+ * the7colors
+ *
+ **************************************************/
+
+namespace Director {
+
+const char *OpenBleedWindowXCMD::xlibName = "OpenBleedWindow";
+const char *OpenBleedWindowXCMD::fileNames[] = {
+	"OpenBleedWindow",
+	nullptr
+};
+
+static BuiltinProto builtins[] = {
+	{ "OpenBleedWindow", OpenBleedWindowXCMD::m_OpenBleedWindow, -1, 0, 300, CBLTIN },
+	{ nullptr, nullptr, 0, 0, 0, VOIDSYM }
+};
+
+void OpenBleedWindowXCMD::open(ObjectType type) {
+	g_lingo->initBuiltIns(builtins);
+}
+
+void OpenBleedWindowXCMD::close(ObjectType type) {
+	g_lingo->cleanupBuiltIns(builtins);
+}
+
+XOBJSTUB(OpenBleedWindowXCMD::m_OpenBleedWindow, 0)
+
+}
diff --git a/engines/director/lingo/xlibs/openbleedwindowxcmd.h b/engines/director/lingo/xlibs/openbleedwindowxcmd.h
new file mode 100644
index 00000000000..128c0f00247
--- /dev/null
+++ b/engines/director/lingo/xlibs/openbleedwindowxcmd.h
@@ -0,0 +1,41 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef DIRECTOR_LINGO_XLIBS_OPENBLEEDWINDOWXCMD_H
+#define DIRECTOR_LINGO_XLIBS_OPENBLEEDWINDOWXCMD_H
+
+namespace Director {
+
+namespace OpenBleedWindowXCMD {
+
+extern const char *xlibName;
+extern const char *fileNames[];
+
+void open(ObjectType type);
+void close(ObjectType type);
+
+void m_OpenBleedWindow(int nargs);
+
+} // End of namespace OpenBleedWindowXCMD
+
+} // End of namespace Director
+
+#endif
diff --git a/engines/director/lingo/xlibs/portaxcmd.cpp b/engines/director/lingo/xlibs/portaxcmd.cpp
new file mode 100644
index 00000000000..a50d5518776
--- /dev/null
+++ b/engines/director/lingo/xlibs/portaxcmd.cpp
@@ -0,0 +1,60 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "common/system.h"
+
+#include "director/director.h"
+#include "director/lingo/lingo.h"
+#include "director/lingo/lingo-object.h"
+#include "director/lingo/lingo-utils.h"
+#include "director/lingo/xlibs/portaxcmd.h"
+
+/**************************************************
+ *
+ * USED IN:
+ * the7colors
+ *
+ **************************************************/
+
+namespace Director {
+
+const char *PortaXCMD::xlibName = "Porta";
+const char *PortaXCMD::fileNames[] = {
+	"Porta",
+	nullptr
+};
+
+static BuiltinProto builtins[] = {
+	{ "Porta", PortaXCMD::m_Porta, -1, 0, 300, CBLTIN },
+	{ nullptr, nullptr, 0, 0, 0, VOIDSYM }
+};
+
+void PortaXCMD::open(ObjectType type) {
+	g_lingo->initBuiltIns(builtins);
+}
+
+void PortaXCMD::close(ObjectType type) {
+	g_lingo->cleanupBuiltIns(builtins);
+}
+
+XOBJSTUB(PortaXCMD::m_Porta, 0)
+
+}
diff --git a/engines/director/lingo/xlibs/portaxcmd.h b/engines/director/lingo/xlibs/portaxcmd.h
new file mode 100644
index 00000000000..93f0de16c63
--- /dev/null
+++ b/engines/director/lingo/xlibs/portaxcmd.h
@@ -0,0 +1,41 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef DIRECTOR_LINGO_XLIBS_PORTAXCMD_H
+#define DIRECTOR_LINGO_XLIBS_PORTAXCMD_H
+
+namespace Director {
+
+namespace PortaXCMD {
+
+extern const char *xlibName;
+extern const char *fileNames[];
+
+void open(ObjectType type);
+void close(ObjectType type);
+
+void m_Porta(int nargs);
+
+} // End of namespace PortaXCMD
+
+} // End of namespace Director
+
+#endif
diff --git a/engines/director/lingo/xlibs/remixxcmd.cpp b/engines/director/lingo/xlibs/remixxcmd.cpp
new file mode 100644
index 00000000000..9e27b7fba17
--- /dev/null
+++ b/engines/director/lingo/xlibs/remixxcmd.cpp
@@ -0,0 +1,60 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "common/system.h"
+
+#include "director/director.h"
+#include "director/lingo/lingo.h"
+#include "director/lingo/lingo-object.h"
+#include "director/lingo/lingo-utils.h"
+#include "director/lingo/xlibs/remixxcmd.h"
+
+/**************************************************
+ *
+ * USED IN:
+ * the7colors
+ *
+ **************************************************/
+
+namespace Director {
+
+const char *RemixXCMD::xlibName = "Remix";
+const char *RemixXCMD::fileNames[] = {
+	"Remix",
+	nullptr
+};
+
+static BuiltinProto builtins[] = {
+	{ "Remix", RemixXCMD::m_Remix, -1, 0, 300, CBLTIN },
+	{ nullptr, nullptr, 0, 0, 0, VOIDSYM }
+};
+
+void RemixXCMD::open(ObjectType type) {
+	g_lingo->initBuiltIns(builtins);
+}
+
+void RemixXCMD::close(ObjectType type) {
+	g_lingo->cleanupBuiltIns(builtins);
+}
+
+XOBJSTUB(RemixXCMD::m_Remix, 0)
+
+}
diff --git a/engines/director/lingo/xlibs/remixxcmd.h b/engines/director/lingo/xlibs/remixxcmd.h
new file mode 100644
index 00000000000..5225e95550a
--- /dev/null
+++ b/engines/director/lingo/xlibs/remixxcmd.h
@@ -0,0 +1,41 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef DIRECTOR_LINGO_XLIBS_REMIXXCMD_H
+#define DIRECTOR_LINGO_XLIBS_REMIXXCMD_H
+
+namespace Director {
+
+namespace RemixXCMD {
+
+extern const char *xlibName;
+extern const char *fileNames[];
+
+void open(ObjectType type);
+void close(ObjectType type);
+
+void m_Remix(int nargs);
+
+} // End of namespace RemixXCMD
+
+} // End of namespace Director
+
+#endif
diff --git a/engines/director/module.mk b/engines/director/module.mk
index a769b2dc274..4d076902a2e 100644
--- a/engines/director/module.mk
+++ b/engines/director/module.mk
@@ -60,6 +60,7 @@ MODULE_OBJS = \
 	lingo/xlibs/batqt.o \
 	lingo/xlibs/blitpict.o \
 	lingo/xlibs/cdromxobj.o \
+	lingo/xlibs/closebleedwindowxcmd.o \
 	lingo/xlibs/colorxobj.o \
 	lingo/xlibs/colorcursorxobj.o \
 	lingo/xlibs/consumer.o \
@@ -87,6 +88,8 @@ MODULE_OBJS = \
 	lingo/xlibs/findwin.o \
 	lingo/xlibs/flushxobj.o \
 	lingo/xlibs/fplayxobj.o \
+	lingo/xlibs/getscreenrectsxfcn.o \
+	lingo/xlibs/getscreensizexfcn.o \
 	lingo/xlibs/gpid.o \
 	lingo/xlibs/hitmap.o \
 	lingo/xlibs/iscd.o \
@@ -105,11 +108,13 @@ MODULE_OBJS = \
 	lingo/xlibs/movemousexobj.o \
 	lingo/xlibs/movieidxxobj.o \
 	lingo/xlibs/movutils.o \
+	lingo/xlibs/openbleedwindowxcmd.o \
 	lingo/xlibs/orthoplayxobj.o \
 	lingo/xlibs/palxobj.o \
 	lingo/xlibs/panel.o \
 	lingo/xlibs/popupmenuxobj.o \
 	lingo/xlibs/porta.o \
+	lingo/xlibs/portaxcmd.o \
 	lingo/xlibs/prefpath.o \
 	lingo/xlibs/printomatic.o \
 	lingo/xlibs/processxobj.o \
@@ -118,6 +123,7 @@ MODULE_OBJS = \
 	lingo/xlibs/qtvr.o \
 	lingo/xlibs/quicktime.o \
 	lingo/xlibs/registercomponent.o \
+	lingo/xlibs/remixxcmd.o \
 	lingo/xlibs/serialportxobj.o \
 	lingo/xlibs/soundjam.o \
 	lingo/xlibs/spacemgr.o \


Commit: e8e1a2948d56775b24ddcf2340801b28ba967ffc
    https://github.com/scummvm/scummvm/commit/e8e1a2948d56775b24ddcf2340801b28ba967ffc
Author: Scott Percival (code at moral.net.au)
Date: 2024-03-31T16:58:31+02:00

Commit Message:
DIRECTOR: Exclude modifier keys from keyDown/keyUp events

Fixes issue in Eastern Mind where pressing Ctrl/Command sends you to the
game exit screen.

Changed paths:
    engines/director/events.cpp


diff --git a/engines/director/events.cpp b/engines/director/events.cpp
index 419c7406ccc..2d5714c9c03 100644
--- a/engines/director/events.cpp
+++ b/engines/director/events.cpp
@@ -269,6 +269,14 @@ bool Movie::processEvent(Common::Event &event) {
 		_key = (unsigned char)(event.kbd.ascii & 0xff);
 		_keyFlags = event.kbd.flags;
 
+		if (event.kbd.keycode == Common::KEYCODE_LSHIFT || event.kbd.keycode == Common::KEYCODE_RSHIFT ||
+			event.kbd.keycode == Common::KEYCODE_LCTRL || event.kbd.keycode == Common::KEYCODE_RCTRL ||
+			event.kbd.keycode == Common::KEYCODE_LALT || event.kbd.keycode == Common::KEYCODE_RALT ||
+			event.kbd.keycode == Common::KEYCODE_LSUPER || event.kbd.keycode == Common::KEYCODE_RSUPER) {
+			// modifier keys don't trigger a KEYDOWN event
+			return true;
+		}
+
 		debugC(1, kDebugEvents, "Movie::processEvent(): movie '%s', keycode: %d", _macName.c_str(), _keyCode);
 
 		_lastEventTime = g_director->getMacTicks();


Commit: f26fad6182e07e7b197921dc398b8fa5f02888d1
    https://github.com/scummvm/scummvm/commit/f26fad6182e07e7b197921dc398b8fa5f02888d1
Author: Scott Percival (code at moral.net.au)
Date: 2024-03-31T16:58:31+02:00

Commit Message:
DIRECTOR: XOBJ: Fix regressions in FileIO

Changed paths:
    engines/director/lingo/xlibs/fileio.cpp


diff --git a/engines/director/lingo/xlibs/fileio.cpp b/engines/director/lingo/xlibs/fileio.cpp
index c6fce12970e..365b903f95d 100644
--- a/engines/director/lingo/xlibs/fileio.cpp
+++ b/engines/director/lingo/xlibs/fileio.cpp
@@ -339,10 +339,7 @@ void FileIO::m_new(int nargs) {
 		Common::String path = d2.asString();
 		FileIOError result = me->open(path, option);
 		if (result != kErrorNone) {
-			me->dispose();
 			me->_lastError = result;
-			g_lingo->push(Datum(result));
-			return;
 		}
 	}
 	g_lingo->push(g_lingo->_state->me);


Commit: 5df3b7b8cd496ce0e686a86e6702e2c37ad9fbba
    https://github.com/scummvm/scummvm/commit/5df3b7b8cd496ce0e686a86e6702e2c37ad9fbba
Author: Scott Percival (code at moral.net.au)
Date: 2024-03-31T16:58:31+02:00

Commit Message:
DIRECTOR: Playing a sound after a fade should restore the volume

Fixes stacked volume changes between scenes in The Seven Colors; e.g.
going straight from the start room to the cat room.

Changed paths:
    engines/director/sound.cpp


diff --git a/engines/director/sound.cpp b/engines/director/sound.cpp
index 0ed9645fabe..18a373130e1 100644
--- a/engines/director/sound.cpp
+++ b/engines/director/sound.cpp
@@ -199,7 +199,6 @@ void DirectorSound::playCastMember(CastMemberID memberID, uint8 soundChannel, bo
 					warning("DirectorSound::playCastMember: audio data failed to load from cast");
 					return;
 				}
-				debugC(5, kDebugSound, "DirectorSound::playCastMember(): playing cast ID %s, channel %d, looping %d, stopOnZero %d, forPuppet %d", memberID.asString().c_str(), soundChannel, looping, stopOnZero, forPuppet);
 				// For looping sounds, keep a copy of the AudioStream so it is
 				// possible to gracefully stop the playback
 				if (looping)
@@ -207,6 +206,7 @@ void DirectorSound::playCastMember(CastMemberID memberID, uint8 soundChannel, bo
 				else
 					_channels[soundChannel]->loopPtr = nullptr;
 				playStream(*as, soundChannel);
+				debugC(5, kDebugSound, "DirectorSound::playCastMember(): playing cast ID %s, channel %d, looping %d, stopOnZero %d, forPuppet %d, volume %d", memberID.asString().c_str(), soundChannel, looping, stopOnZero, forPuppet, _channels[soundChannel]->volume);
 				setLastPlayedSound(soundChannel, memberID, stopOnZero);
 			}
 		} else {
@@ -291,7 +291,6 @@ bool DirectorSound::fadeChannel(uint8 soundChannel) {
 
 	fade->lapsedTicks = _window->getVM()->getMacTicks() - fade->startTicks;
 	if (fade->lapsedTicks > fade->totalTicks) {
-		cancelFade(soundChannel);
 		return false;
 	}
 
@@ -317,7 +316,9 @@ void DirectorSound::cancelFade(uint8 soundChannel) {
 	// why this method is private.
 
 	if (_channels[soundChannel]->fade) {
-		_mixer->setChannelVolume(_channels[soundChannel]->handle, _channels[soundChannel]->fade->targetVol);
+		int restoreVol = _channels[soundChannel]->fade->fadeIn ? _channels[soundChannel]->fade->targetVol : _channels[soundChannel]->fade->startVol;
+		debugC(5, kDebugSound, "DirectorSound::cancelFade(): resetting channel %d volume to %d", soundChannel, restoreVol);
+		_mixer->setChannelVolume(_channels[soundChannel]->handle, restoreVol);
 
 		delete _channels[soundChannel]->fade;
 		_channels[soundChannel]->fade = nullptr;
@@ -445,7 +446,7 @@ void DirectorSound::playExternalSound(uint16 menu, uint16 submenu, uint8 soundCh
 		loadSampleSounds(menu);
 
 	if (1 <= submenu && submenu <= menuSounds.size()) {
-		debugC(5, kDebugSound, "DirectorSound::playExternalSound(): playing menu ID %d, submenu ID %d, channel %d", menu, submenu, soundChannel);
+		debugC(5, kDebugSound, "DirectorSound::playExternalSound(): playing menu ID %d, submenu ID %d, channel %d, volume %d", menu, submenu, soundChannel, _channels[soundChannel]->volume);
 		playStream(*(menuSounds[submenu - 1]->getAudioStream()), soundChannel);
 		setLastPlayedSound(soundChannel, soundId);
 	} else {


Commit: c301c1f2b58edc7ab90b7e70cc685d431f40f51e
    https://github.com/scummvm/scummvm/commit/c301c1f2b58edc7ab90b7e70cc685d431f40f51e
Author: Scott Percival (code at moral.net.au)
Date: 2024-03-31T16:58:31+02:00

Commit Message:
DIRECTOR: Fix film-loop loading

Previously it would attempt to use the sprite loader with the puppet
flag switched on, which lead to most of the fields being ignored.

Changed paths:
    engines/director/castmember/filmloop.cpp


diff --git a/engines/director/castmember/filmloop.cpp b/engines/director/castmember/filmloop.cpp
index cf09e467dd5..828d5636cd7 100644
--- a/engines/director/castmember/filmloop.cpp
+++ b/engines/director/castmember/filmloop.cpp
@@ -164,7 +164,6 @@ void FilmLoopCastMember::loadFilmLoopDataD2(Common::SeekableReadStreamEndian &st
 				}
 
 				sprite._spriteType = kCastMemberSprite;
-				sprite._puppet = 1;
 				sprite._stretch = 1;
 
 				uint16 needSize = MIN((uint16)(nextStart - offset), segSize);
@@ -273,13 +272,12 @@ void FilmLoopCastMember::loadFilmLoopDataD4(Common::SeekableReadStreamEndian &st
 				if (newFrame.sprites.contains(channel)) {
 					// In some cases, particularly in Total Distortion, there could be sprites of type kInactiveSprite.
 					// We need to skip processing them to avoid issues.
-					
+
 					if (newFrame.sprites.getVal(channel)._spriteType == kBitmapSprite) {
 						sprite = newFrame.sprites.getVal(channel);
 					}
 				}
 
-				sprite._puppet = 1;
 				sprite._stretch = 1;
 
 				uint16 needSize = MIN((uint16)(nextStart - offset), segSize);


Commit: d43612db8560d104813a4c3a792b3f2b6aac0a6b
    https://github.com/scummvm/scummvm/commit/d43612db8560d104813a4c3a792b3f2b6aac0a6b
Author: Scott Percival (code at moral.net.au)
Date: 2024-03-31T16:58:31+02:00

Commit Message:
DIRECTOR: XOBJ: Refactor methods to pass path to library

Changed paths:
    engines/director/cast.cpp
    engines/director/lingo/lingo-builtins.cpp
    engines/director/lingo/lingo-object.cpp
    engines/director/lingo/lingo.h
    engines/director/lingo/xlibs/aiff.cpp
    engines/director/lingo/xlibs/aiff.h
    engines/director/lingo/xlibs/applecdxobj.cpp
    engines/director/lingo/xlibs/applecdxobj.h
    engines/director/lingo/xlibs/askuser.cpp
    engines/director/lingo/xlibs/askuser.h
    engines/director/lingo/xlibs/barakeobj.cpp
    engines/director/lingo/xlibs/barakeobj.h
    engines/director/lingo/xlibs/batqt.cpp
    engines/director/lingo/xlibs/batqt.h
    engines/director/lingo/xlibs/blitpict.cpp
    engines/director/lingo/xlibs/blitpict.h
    engines/director/lingo/xlibs/cdromxobj.cpp
    engines/director/lingo/xlibs/cdromxobj.h
    engines/director/lingo/xlibs/closebleedwindowxcmd.cpp
    engines/director/lingo/xlibs/closebleedwindowxcmd.h
    engines/director/lingo/xlibs/colorcursorxobj.cpp
    engines/director/lingo/xlibs/colorcursorxobj.h
    engines/director/lingo/xlibs/colorxobj.cpp
    engines/director/lingo/xlibs/colorxobj.h
    engines/director/lingo/xlibs/consumer.cpp
    engines/director/lingo/xlibs/consumer.h
    engines/director/lingo/xlibs/cursorxobj.cpp
    engines/director/lingo/xlibs/cursorxobj.h
    engines/director/lingo/xlibs/darkenscreen.cpp
    engines/director/lingo/xlibs/darkenscreen.h
    engines/director/lingo/xlibs/developerStack.cpp
    engines/director/lingo/xlibs/developerStack.h
    engines/director/lingo/xlibs/dialogsxobj.cpp
    engines/director/lingo/xlibs/dialogsxobj.h
    engines/director/lingo/xlibs/dirutil.cpp
    engines/director/lingo/xlibs/dirutil.h
    engines/director/lingo/xlibs/dpwavi.cpp
    engines/director/lingo/xlibs/dpwavi.h
    engines/director/lingo/xlibs/dpwqtw.cpp
    engines/director/lingo/xlibs/dpwqtw.h
    engines/director/lingo/xlibs/draw.cpp
    engines/director/lingo/xlibs/draw.h
    engines/director/lingo/xlibs/ednox.cpp
    engines/director/lingo/xlibs/ednox.h
    engines/director/lingo/xlibs/eventq.cpp
    engines/director/lingo/xlibs/eventq.h
    engines/director/lingo/xlibs/fadegammadownxcmd.cpp
    engines/director/lingo/xlibs/fadegammadownxcmd.h
    engines/director/lingo/xlibs/fadegammaupxcmd.cpp
    engines/director/lingo/xlibs/fadegammaupxcmd.h
    engines/director/lingo/xlibs/fadegammaxcmd.cpp
    engines/director/lingo/xlibs/fadegammaxcmd.h
    engines/director/lingo/xlibs/fedracul.cpp
    engines/director/lingo/xlibs/fedracul.h
    engines/director/lingo/xlibs/feimasks.cpp
    engines/director/lingo/xlibs/feimasks.h
    engines/director/lingo/xlibs/feiprefs.cpp
    engines/director/lingo/xlibs/feiprefs.h
    engines/director/lingo/xlibs/fileexists.cpp
    engines/director/lingo/xlibs/fileexists.h
    engines/director/lingo/xlibs/fileio.cpp
    engines/director/lingo/xlibs/fileio.h
    engines/director/lingo/xlibs/findereventsxcmd.cpp
    engines/director/lingo/xlibs/findereventsxcmd.h
    engines/director/lingo/xlibs/findfolder.cpp
    engines/director/lingo/xlibs/findfolder.h
    engines/director/lingo/xlibs/findsys.cpp
    engines/director/lingo/xlibs/findsys.h
    engines/director/lingo/xlibs/findwin.cpp
    engines/director/lingo/xlibs/findwin.h
    engines/director/lingo/xlibs/flushxobj.cpp
    engines/director/lingo/xlibs/flushxobj.h
    engines/director/lingo/xlibs/fplayxobj.cpp
    engines/director/lingo/xlibs/fplayxobj.h
    engines/director/lingo/xlibs/getscreenrectsxfcn.cpp
    engines/director/lingo/xlibs/getscreenrectsxfcn.h
    engines/director/lingo/xlibs/getscreensizexfcn.cpp
    engines/director/lingo/xlibs/getscreensizexfcn.h
    engines/director/lingo/xlibs/gpid.cpp
    engines/director/lingo/xlibs/gpid.h
    engines/director/lingo/xlibs/hitmap.cpp
    engines/director/lingo/xlibs/hitmap.h
    engines/director/lingo/xlibs/iscd.cpp
    engines/director/lingo/xlibs/iscd.h
    engines/director/lingo/xlibs/ispippin.cpp
    engines/director/lingo/xlibs/ispippin.h
    engines/director/lingo/xlibs/jitdraw3.cpp
    engines/director/lingo/xlibs/jitdraw3.h
    engines/director/lingo/xlibs/jwxini.cpp
    engines/director/lingo/xlibs/jwxini.h
    engines/director/lingo/xlibs/labeldrvxobj.cpp
    engines/director/lingo/xlibs/labeldrvxobj.h
    engines/director/lingo/xlibs/maniacbg.cpp
    engines/director/lingo/xlibs/maniacbg.h
    engines/director/lingo/xlibs/mapnavigatorxobj.cpp
    engines/director/lingo/xlibs/mapnavigatorxobj.h
    engines/director/lingo/xlibs/memcheckxobj.cpp
    engines/director/lingo/xlibs/memcheckxobj.h
    engines/director/lingo/xlibs/memoryxobj.cpp
    engines/director/lingo/xlibs/memoryxobj.h
    engines/director/lingo/xlibs/misc.cpp
    engines/director/lingo/xlibs/misc.h
    engines/director/lingo/xlibs/miscx.cpp
    engines/director/lingo/xlibs/miscx.h
    engines/director/lingo/xlibs/mmaskxobj.cpp
    engines/director/lingo/xlibs/mmaskxobj.h
    engines/director/lingo/xlibs/moovxobj.cpp
    engines/director/lingo/xlibs/moovxobj.h
    engines/director/lingo/xlibs/movemousexobj.cpp
    engines/director/lingo/xlibs/movemousexobj.h
    engines/director/lingo/xlibs/movieidxxobj.cpp
    engines/director/lingo/xlibs/movieidxxobj.h
    engines/director/lingo/xlibs/movutils.cpp
    engines/director/lingo/xlibs/movutils.h
    engines/director/lingo/xlibs/openbleedwindowxcmd.cpp
    engines/director/lingo/xlibs/openbleedwindowxcmd.h
    engines/director/lingo/xlibs/orthoplayxobj.cpp
    engines/director/lingo/xlibs/orthoplayxobj.h
    engines/director/lingo/xlibs/palxobj.cpp
    engines/director/lingo/xlibs/palxobj.h
    engines/director/lingo/xlibs/panel.cpp
    engines/director/lingo/xlibs/panel.h
    engines/director/lingo/xlibs/popupmenuxobj.cpp
    engines/director/lingo/xlibs/popupmenuxobj.h
    engines/director/lingo/xlibs/porta.cpp
    engines/director/lingo/xlibs/porta.h
    engines/director/lingo/xlibs/portaxcmd.cpp
    engines/director/lingo/xlibs/portaxcmd.h
    engines/director/lingo/xlibs/prefpath.cpp
    engines/director/lingo/xlibs/prefpath.h
    engines/director/lingo/xlibs/printomatic.cpp
    engines/director/lingo/xlibs/printomatic.h
    engines/director/lingo/xlibs/processxobj.cpp
    engines/director/lingo/xlibs/processxobj.h
    engines/director/lingo/xlibs/qtcatmovieplayerxobj.cpp
    engines/director/lingo/xlibs/qtcatmovieplayerxobj.h
    engines/director/lingo/xlibs/qtmovie.cpp
    engines/director/lingo/xlibs/qtmovie.h
    engines/director/lingo/xlibs/qtvr.cpp
    engines/director/lingo/xlibs/qtvr.h
    engines/director/lingo/xlibs/quicktime.cpp
    engines/director/lingo/xlibs/quicktime.h
    engines/director/lingo/xlibs/registercomponent.cpp
    engines/director/lingo/xlibs/registercomponent.h
    engines/director/lingo/xlibs/remixxcmd.cpp
    engines/director/lingo/xlibs/remixxcmd.h
    engines/director/lingo/xlibs/serialportxobj.cpp
    engines/director/lingo/xlibs/serialportxobj.h
    engines/director/lingo/xlibs/soundjam.cpp
    engines/director/lingo/xlibs/soundjam.h
    engines/director/lingo/xlibs/spacemgr.cpp
    engines/director/lingo/xlibs/spacemgr.h
    engines/director/lingo/xlibs/stagetc.cpp
    engines/director/lingo/xlibs/stagetc.h
    engines/director/lingo/xlibs/unittest.cpp
    engines/director/lingo/xlibs/unittest.h
    engines/director/lingo/xlibs/valkyrie.cpp
    engines/director/lingo/xlibs/valkyrie.h
    engines/director/lingo/xlibs/videodiscxobj.cpp
    engines/director/lingo/xlibs/videodiscxobj.h
    engines/director/lingo/xlibs/vmisonxfcn.cpp
    engines/director/lingo/xlibs/vmisonxfcn.h
    engines/director/lingo/xlibs/volumelist.cpp
    engines/director/lingo/xlibs/volumelist.h
    engines/director/lingo/xlibs/widgetxobj.cpp
    engines/director/lingo/xlibs/widgetxobj.h
    engines/director/lingo/xlibs/window.cpp
    engines/director/lingo/xlibs/window.h
    engines/director/lingo/xlibs/wininfo.cpp
    engines/director/lingo/xlibs/wininfo.h
    engines/director/lingo/xlibs/winxobj.cpp
    engines/director/lingo/xlibs/winxobj.h
    engines/director/lingo/xlibs/xcmdglue.cpp
    engines/director/lingo/xlibs/xcmdglue.h
    engines/director/lingo/xlibs/xio.cpp
    engines/director/lingo/xlibs/xio.h
    engines/director/lingo/xlibs/xplayanim.cpp
    engines/director/lingo/xlibs/xplayanim.h
    engines/director/lingo/xlibs/xsoundxfcn.cpp
    engines/director/lingo/xlibs/xsoundxfcn.h
    engines/director/lingo/xlibs/yasix.cpp
    engines/director/lingo/xlibs/yasix.h
    engines/director/lingo/xtras/scrnutil.cpp
    engines/director/lingo/xtras/scrnutil.h
    engines/director/resource.cpp
    engines/director/util.cpp
    engines/director/util.h


diff --git a/engines/director/cast.cpp b/engines/director/cast.cpp
index 05a75e780c0..d2041e7d670 100644
--- a/engines/director/cast.cpp
+++ b/engines/director/cast.cpp
@@ -530,7 +530,7 @@ void Cast::loadCast() {
 		for (auto &iterator : xcod) {
 			Resource res = _castArchive->getResourceDetail(MKTAG('X', 'C', 'O', 'D'), iterator);
 			debug(0, "Detected XObject '%s'", res.name.c_str());
-			g_lingo->openXLib(res.name, kXObj);
+			g_lingo->openXLib(res.name, kXObj, _castArchive->getPathName());
 		}
 	}
 
diff --git a/engines/director/lingo/lingo-builtins.cpp b/engines/director/lingo/lingo-builtins.cpp
index 8517c69bfa6..6719da90592 100644
--- a/engines/director/lingo/lingo-builtins.cpp
+++ b/engines/director/lingo/lingo-builtins.cpp
@@ -29,15 +29,16 @@
 
 #include "director/director.h"
 #include "director/cast.h"
+#include "director/channel.h"
 #include "director/debugger.h"
 #include "director/frame.h"
 #include "director/movie.h"
 #include "director/score.h"
 #include "director/sound.h"
 #include "director/sprite.h"
-#include "director/channel.h"
-#include "director/window.h"
 #include "director/stxt.h"
+#include "director/util.h"
+#include "director/window.h"
 #include "director/castmember/castmember.h"
 #include "director/castmember/bitmap.h"
 #include "director/castmember/palette.h"
@@ -1308,11 +1309,12 @@ void LB::b_openXlib(int nargs) {
 	Common::String xlibName;
 
 	Datum d = g_lingo->pop();
+
+	Common::Path xlibPath = findXLibPath(d.asString(), true, false);
 	if (g_director->getPlatform() == Common::kPlatformMacintosh) {
 		// try opening the file as a Macintosh resource fork
-		Common::Path resPath(g_director->getCurrentWindow()->getCurrentPath() + d.asString(), g_director->_dirSeparator);
 		MacArchive *resFile = new MacArchive();
-		if (resFile->openFile(resPath)) {
+		if (resFile->openFile(xlibPath)) {
 			uint32 XCOD = MKTAG('X', 'C', 'O', 'D');
 			uint32 XCMD = MKTAG('X', 'C', 'M', 'D');
 			uint32 XFCN = MKTAG('X', 'F', 'C', 'N');
@@ -1321,19 +1323,19 @@ void LB::b_openXlib(int nargs) {
 
 			for (uint i = 0; i < rsrcList.size(); i++) {
 				xlibName = resFile->getResourceDetail(XCOD, rsrcList[i]).name.c_str();
-				g_lingo->openXLib(xlibName, kXObj);
+				g_lingo->openXLib(xlibName, kXObj, xlibPath);
 			}
 
 			rsrcList = resFile->getResourceIDList(XCMD);
 			for (uint i = 0; i < rsrcList.size(); i++) {
 				xlibName = resFile->getResourceDetail(XCMD, rsrcList[i]).name.c_str();
-				g_lingo->openXLib(xlibName, kXObj);
+				g_lingo->openXLib(xlibName, kXObj, xlibPath);
 			}
 
 			rsrcList = resFile->getResourceIDList(XFCN);
 			for (uint i = 0; i < rsrcList.size(); i++) {
 				xlibName = resFile->getResourceDetail(XFCN, rsrcList[i]).name.c_str();
-				g_lingo->openXLib(xlibName, kXObj);
+				g_lingo->openXLib(xlibName, kXObj, xlibPath);
 			}
 			delete resFile;
 			return;
@@ -1345,9 +1347,9 @@ void LB::b_openXlib(int nargs) {
 
 	// TODO: Figure out a nicer way of differentiating Xtras from XLibs on Mac
 	if (xlibName.hasSuffixIgnoreCase(".x16") || xlibName.hasSuffixIgnoreCase(".x32")) {
-		g_lingo->openXLib(xlibName, kXtraObj);
+		g_lingo->openXLib(xlibName, kXtraObj, xlibPath);
 	} else {
-		g_lingo->openXLib(xlibName, kXObj);
+		g_lingo->openXLib(xlibName, kXObj, xlibPath);
 	}
 }
 
diff --git a/engines/director/lingo/lingo-object.cpp b/engines/director/lingo/lingo-object.cpp
index ca0cd4f152d..79236c223b2 100644
--- a/engines/director/lingo/lingo-object.cpp
+++ b/engines/director/lingo/lingo-object.cpp
@@ -184,8 +184,8 @@ void Lingo::cleanupMethods() {
 
 static struct XLibProto {
 	const char **names;
-	XLibFunc opener;
-	XLibFunc closer;
+	XLibOpenerFunc opener;
+	XLibCloserFunc closer;
 	int type;
 	int version;
 } xlibs[] = {
@@ -325,7 +325,7 @@ Common::String Lingo::normalizeXLibName(Common::String name) {
 	return name;
 }
 
-void Lingo::openXLib(Common::String name, ObjectType type) {
+void Lingo::openXLib(Common::String name, ObjectType type, const Common::Path &path) {
 	name = normalizeXLibName(name);
 
 	if (_openXLibs.contains(name))
@@ -334,7 +334,7 @@ void Lingo::openXLib(Common::String name, ObjectType type) {
 	_openXLibs[name] = type;
 
 	if (_xlibOpeners.contains(name)) {
-		(*_xlibOpeners[name])(type);
+		(*_xlibOpeners[name])(type, path);
 	} else {
 		warning("Lingo::openXLib: Unimplemented xlib: '%s'", name.c_str());
 	}
@@ -368,7 +368,8 @@ void Lingo::reloadOpenXLibs() {
 	OpenXLibsHash openXLibsCopy = _openXLibs;
 	for (auto &it : openXLibsCopy) {
 		closeXLib(it._key);
-		openXLib(it._key, it._value);
+		// FIXME: keep track of where the xlib path is
+		openXLib(it._key, it._value, Common::Path());
 	}
 }
 
diff --git a/engines/director/lingo/lingo.h b/engines/director/lingo/lingo.h
index 937f40cbfee..cd6f7f47b5e 100644
--- a/engines/director/lingo/lingo.h
+++ b/engines/director/lingo/lingo.h
@@ -235,8 +235,10 @@ typedef Common::HashMap<Common::String, Symbol, Common::IgnoreCase_Hash, Common:
 typedef Common::HashMap<Common::String, Datum, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> DatumHash;
 typedef Common::HashMap<Common::String, Builtin *, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> BuiltinHash;
 typedef Common::HashMap<Common::String, VarType, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> VarTypeHash;
-typedef void (*XLibFunc)(ObjectType);
-typedef Common::HashMap<Common::String, XLibFunc, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> XLibFuncHash;
+typedef void (*XLibOpenerFunc)(ObjectType, const Common::Path &);
+typedef void (*XLibCloserFunc)(ObjectType);
+typedef Common::HashMap<Common::String, XLibOpenerFunc, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> XLibOpenerFuncHash;
+typedef Common::HashMap<Common::String, XLibCloserFunc, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> XLibCloserFuncHash;
 typedef Common::HashMap<Common::String, ObjectType, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> OpenXLibsHash;
 
 typedef Common::HashMap<Common::String, TheEntity *, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> TheEntityHash;
@@ -361,7 +363,7 @@ public:
 	void cleanupXLibs();
 
 	Common::String normalizeXLibName(Common::String name);
-	void openXLib(Common::String name, ObjectType type);
+	void openXLib(Common::String name, ObjectType type, const Common::Path &path);
 	void closeXLib(Common::String name);
 	void closeOpenXLibs();
 	void reloadOpenXLibs();
@@ -489,8 +491,8 @@ public:
 	SymbolHash _builtinConsts;
 	SymbolHash _builtinListHandlers;
 	SymbolHash _methods;
-	XLibFuncHash _xlibOpeners;
-	XLibFuncHash _xlibClosers;
+	XLibOpenerFuncHash _xlibOpeners;
+	XLibCloserFuncHash _xlibClosers;
 
 	OpenXLibsHash _openXLibs;
 
diff --git a/engines/director/lingo/xlibs/aiff.cpp b/engines/director/lingo/xlibs/aiff.cpp
index c835db4c73e..203bb2337f7 100644
--- a/engines/director/lingo/xlibs/aiff.cpp
+++ b/engines/director/lingo/xlibs/aiff.cpp
@@ -67,7 +67,7 @@ static MethodProto xlibMethods[] = {
 	{ nullptr, nullptr, 0, 0, 0 }
 };
 
-void AiffXObj::open(ObjectType type) {
+void AiffXObj::open(ObjectType type, const Common::Path &path) {
 	if (type == kXObj) {
 		AiffXObject::initMethods(xlibMethods);
 		AiffXObject *xobj = new AiffXObject(kXObj);
diff --git a/engines/director/lingo/xlibs/aiff.h b/engines/director/lingo/xlibs/aiff.h
index a5ec875ec4b..1a7063516ac 100644
--- a/engines/director/lingo/xlibs/aiff.h
+++ b/engines/director/lingo/xlibs/aiff.h
@@ -35,7 +35,7 @@ namespace AiffXObj {
 extern const char *xlibName;
 extern const char *fileNames[];
 
-void open(ObjectType type);
+void open(ObjectType type, const Common::Path &path);
 void close(ObjectType type);
 
 void m_new(int nargs);
diff --git a/engines/director/lingo/xlibs/applecdxobj.cpp b/engines/director/lingo/xlibs/applecdxobj.cpp
index 847addb9a3a..f0c5812c80f 100644
--- a/engines/director/lingo/xlibs/applecdxobj.cpp
+++ b/engines/director/lingo/xlibs/applecdxobj.cpp
@@ -124,7 +124,7 @@ static MethodProto xlibMethods[] = {
     { nullptr, nullptr, 0, 0, 0 }
 };
 
-void AppleCDXObj::open(ObjectType type) {
+void AppleCDXObj::open(ObjectType type, const Common::Path &path) {
 	if (type == kXObj) {
 		AppleCDXObject::initMethods(xlibMethods);
 		AppleCDXObject *xobj = new AppleCDXObject(kXObj);
diff --git a/engines/director/lingo/xlibs/applecdxobj.h b/engines/director/lingo/xlibs/applecdxobj.h
index 0ad75e3b145..eac54292057 100644
--- a/engines/director/lingo/xlibs/applecdxobj.h
+++ b/engines/director/lingo/xlibs/applecdxobj.h
@@ -47,7 +47,7 @@ namespace AppleCDXObj {
 extern const char *xlibName;
 extern const char *fileNames[];
 
-void open(ObjectType type);
+void open(ObjectType type, const Common::Path &path);
 void close(ObjectType type);
 
 void m_new(int nargs);
diff --git a/engines/director/lingo/xlibs/askuser.cpp b/engines/director/lingo/xlibs/askuser.cpp
index 38ae2024e72..ff10e37040a 100644
--- a/engines/director/lingo/xlibs/askuser.cpp
+++ b/engines/director/lingo/xlibs/askuser.cpp
@@ -62,7 +62,7 @@ AskUserXObject::AskUserXObject(ObjectType ObjectType) :Object<AskUserXObject>("A
 	_objType = ObjectType;
 }
 
-void AskUser::open(ObjectType type) {
+void AskUser::open(ObjectType type, const Common::Path &path) {
 	if (type == kXObj) {
 		AskUserXObject::initMethods(xlibMethods);
 		AskUserXObject *xobj = new AskUserXObject(kXObj);
diff --git a/engines/director/lingo/xlibs/askuser.h b/engines/director/lingo/xlibs/askuser.h
index de51e726cd0..0211d2de103 100644
--- a/engines/director/lingo/xlibs/askuser.h
+++ b/engines/director/lingo/xlibs/askuser.h
@@ -34,7 +34,7 @@ namespace AskUser {
 extern const char *xlibName;
 extern const char *fileNames[];
 
-void open(ObjectType type);
+void open(ObjectType type, const Common::Path &path);
 void close(ObjectType type);
 
 void m_new(int nargs);
diff --git a/engines/director/lingo/xlibs/barakeobj.cpp b/engines/director/lingo/xlibs/barakeobj.cpp
index c3880d1f67a..ab84a9b781a 100644
--- a/engines/director/lingo/xlibs/barakeobj.cpp
+++ b/engines/director/lingo/xlibs/barakeobj.cpp
@@ -57,7 +57,7 @@ static MethodProto xlibMethods[] = {
 	{ nullptr, nullptr, 0, 0, 0 }
 };
 
-void BarakeObj::open(ObjectType type) {
+void BarakeObj::open(ObjectType type, const Common::Path &path) {
 	if (type == kXObj) {
 		BarakeObject::initMethods(xlibMethods);
 		BarakeObject *xobj = new BarakeObject(kXObj);
diff --git a/engines/director/lingo/xlibs/barakeobj.h b/engines/director/lingo/xlibs/barakeobj.h
index dc0191dad00..52db77bb1e9 100644
--- a/engines/director/lingo/xlibs/barakeobj.h
+++ b/engines/director/lingo/xlibs/barakeobj.h
@@ -34,7 +34,7 @@ namespace BarakeObj {
 extern const char *xlibName;
 extern const char *fileNames[];
 
-void open(ObjectType type);
+void open(ObjectType type, const Common::Path &path);
 void close(ObjectType type);
 
 void m_new(int nargs);
diff --git a/engines/director/lingo/xlibs/batqt.cpp b/engines/director/lingo/xlibs/batqt.cpp
index 7df78d27f01..919cb3c6bb2 100644
--- a/engines/director/lingo/xlibs/batqt.cpp
+++ b/engines/director/lingo/xlibs/batqt.cpp
@@ -97,7 +97,7 @@ static MethodProto xlibMethods[] = {
 	{ nullptr, nullptr, 0, 0, 0 }
 };
 
-void BatQT::open(ObjectType type) {
+void BatQT::open(ObjectType type, const Common::Path &path) {
 	if (type == kXObj) {
 		BatQTXObject::initMethods(xlibMethods);
 		BatQTXObject *xobj = new BatQTXObject(kXObj);
diff --git a/engines/director/lingo/xlibs/batqt.h b/engines/director/lingo/xlibs/batqt.h
index 2f6d4a3f913..d9cf27fea05 100644
--- a/engines/director/lingo/xlibs/batqt.h
+++ b/engines/director/lingo/xlibs/batqt.h
@@ -44,7 +44,7 @@ namespace BatQT {
 extern const char *xlibName;
 extern const char *fileNames[];
 
-void open(ObjectType type);
+void open(ObjectType type, const Common::Path &path);
 void close(ObjectType type);
 
 void m_new(int nargs);
diff --git a/engines/director/lingo/xlibs/blitpict.cpp b/engines/director/lingo/xlibs/blitpict.cpp
index 0b993668eed..457005e48da 100644
--- a/engines/director/lingo/xlibs/blitpict.cpp
+++ b/engines/director/lingo/xlibs/blitpict.cpp
@@ -76,7 +76,7 @@ BlitPictXObject::BlitPictXObject(ObjectType ObjectType) :Object<BlitPictXObject>
 	_objType = ObjectType;
 }
 
-void BlitPictXObj::open(ObjectType type) {
+void BlitPictXObj::open(ObjectType type, const Common::Path &path) {
 	if (type == kXObj) {
 		BlitPictXObject::initMethods(xlibMethods);
 		BlitPictXObject *xobj = new BlitPictXObject(kXObj);
diff --git a/engines/director/lingo/xlibs/blitpict.h b/engines/director/lingo/xlibs/blitpict.h
index 32b55792d61..0f47021ce92 100644
--- a/engines/director/lingo/xlibs/blitpict.h
+++ b/engines/director/lingo/xlibs/blitpict.h
@@ -34,7 +34,7 @@ namespace BlitPictXObj {
 extern const char *xlibName;
 extern const char *fileNames[];
 
-void open(ObjectType type);
+void open(ObjectType type, const Common::Path &path);
 void close(ObjectType type);
 
 void m_new(int nargs);
diff --git a/engines/director/lingo/xlibs/cdromxobj.cpp b/engines/director/lingo/xlibs/cdromxobj.cpp
index e3e82a895db..7e00ff87bb5 100644
--- a/engines/director/lingo/xlibs/cdromxobj.cpp
+++ b/engines/director/lingo/xlibs/cdromxobj.cpp
@@ -210,7 +210,7 @@ static MethodProto xlibMethods[] = {
 	{ nullptr, nullptr, 0, 0, 0 }
 };
 
-void CDROMXObj::open(ObjectType type) {
+void CDROMXObj::open(ObjectType type, const Common::Path &path) {
 	if (type == kXObj) {
 		CDROMXObject::initMethods(xlibMethods);
 		CDROMXObject *xobj = new CDROMXObject(kXObj);
diff --git a/engines/director/lingo/xlibs/cdromxobj.h b/engines/director/lingo/xlibs/cdromxobj.h
index 3b306eab023..6f41c371e12 100644
--- a/engines/director/lingo/xlibs/cdromxobj.h
+++ b/engines/director/lingo/xlibs/cdromxobj.h
@@ -37,7 +37,7 @@ namespace CDROMXObj {
 extern const char *xlibName;
 extern const char *fileNames[];
 
-void open(ObjectType type);
+void open(ObjectType type, const Common::Path &path);
 void close(ObjectType type);
 
 void m_new(int nargs);
diff --git a/engines/director/lingo/xlibs/closebleedwindowxcmd.cpp b/engines/director/lingo/xlibs/closebleedwindowxcmd.cpp
index e431c90c20d..ab22ef72a02 100644
--- a/engines/director/lingo/xlibs/closebleedwindowxcmd.cpp
+++ b/engines/director/lingo/xlibs/closebleedwindowxcmd.cpp
@@ -47,7 +47,7 @@ static BuiltinProto builtins[] = {
 	{ nullptr, nullptr, 0, 0, 0, VOIDSYM }
 };
 
-void CloseBleedWindowXCMD::open(ObjectType type) {
+void CloseBleedWindowXCMD::open(ObjectType type, const Common::Path &path) {
 	g_lingo->initBuiltIns(builtins);
 }
 
diff --git a/engines/director/lingo/xlibs/closebleedwindowxcmd.h b/engines/director/lingo/xlibs/closebleedwindowxcmd.h
index c72c06489fa..6da8dd057fe 100644
--- a/engines/director/lingo/xlibs/closebleedwindowxcmd.h
+++ b/engines/director/lingo/xlibs/closebleedwindowxcmd.h
@@ -29,7 +29,7 @@ namespace CloseBleedWindowXCMD {
 extern const char *xlibName;
 extern const char *fileNames[];
 
-void open(ObjectType type);
+void open(ObjectType type, const Common::Path &path);
 void close(ObjectType type);
 
 void m_CloseBleedWindow(int nargs);
diff --git a/engines/director/lingo/xlibs/colorcursorxobj.cpp b/engines/director/lingo/xlibs/colorcursorxobj.cpp
index 96e182ff5f0..b8d7e624261 100644
--- a/engines/director/lingo/xlibs/colorcursorxobj.cpp
+++ b/engines/director/lingo/xlibs/colorcursorxobj.cpp
@@ -62,7 +62,7 @@ ColorCursorXObject::ColorCursorXObject(ObjectType ObjectType) :Object<ColorCurso
 	_objType = ObjectType;
 }
 
-void ColorCursorXObj::open(ObjectType type) {
+void ColorCursorXObj::open(ObjectType type, const Common::Path &path) {
 	if (type == kXObj) {
 		ColorCursorXObject::initMethods(xlibMethods);
 		ColorCursorXObject *xobj = new ColorCursorXObject(kXObj);
diff --git a/engines/director/lingo/xlibs/colorcursorxobj.h b/engines/director/lingo/xlibs/colorcursorxobj.h
index f7b49003d04..9828eafc5f3 100644
--- a/engines/director/lingo/xlibs/colorcursorxobj.h
+++ b/engines/director/lingo/xlibs/colorcursorxobj.h
@@ -34,7 +34,7 @@ namespace ColorCursorXObj {
 extern const char *xlibName;
 extern const char *fileNames[];
 
-void open(ObjectType type);
+void open(ObjectType type, const Common::Path &path);
 void close(ObjectType type);
 
 void m_new(int nargs);
diff --git a/engines/director/lingo/xlibs/colorxobj.cpp b/engines/director/lingo/xlibs/colorxobj.cpp
index a6a9d0e6958..e8dc200d122 100644
--- a/engines/director/lingo/xlibs/colorxobj.cpp
+++ b/engines/director/lingo/xlibs/colorxobj.cpp
@@ -82,7 +82,7 @@ ColorXObject::ColorXObject(ObjectType ObjectType) :Object<ColorXObject>("Color")
 	_objType = ObjectType;
 }
 
-void ColorXObj::open(ObjectType type) {
+void ColorXObj::open(ObjectType type, const Common::Path &path) {
 	if (type == kXObj) {
 		ColorXObject::initMethods(xlibMethods);
 		ColorXObject *xobj = new ColorXObject(kXObj);
diff --git a/engines/director/lingo/xlibs/colorxobj.h b/engines/director/lingo/xlibs/colorxobj.h
index 1f0dd198dbc..6cf7d5e1ac6 100644
--- a/engines/director/lingo/xlibs/colorxobj.h
+++ b/engines/director/lingo/xlibs/colorxobj.h
@@ -29,7 +29,7 @@ namespace ColorXObj {
 extern const char *xlibName;
 extern const char *fileNames[];
 
-void open(ObjectType type);
+void open(ObjectType type, const Common::Path &path);
 void close(ObjectType type);
 
 void m_new(int nargs);
diff --git a/engines/director/lingo/xlibs/consumer.cpp b/engines/director/lingo/xlibs/consumer.cpp
index 0c25230d999..ac681a08d50 100644
--- a/engines/director/lingo/xlibs/consumer.cpp
+++ b/engines/director/lingo/xlibs/consumer.cpp
@@ -82,7 +82,7 @@ ConsumerXObject::ConsumerXObject(ObjectType ObjectType) :Object<ConsumerXObject>
 	_objType = ObjectType;
 }
 
-void ConsumerXObj::open(ObjectType type) {
+void ConsumerXObj::open(ObjectType type, const Common::Path &path) {
 	if (type == kXObj) {
 		ConsumerXObject::initMethods(xlibMethods);
 		ConsumerXObject *xobj = new ConsumerXObject(kXObj);
diff --git a/engines/director/lingo/xlibs/consumer.h b/engines/director/lingo/xlibs/consumer.h
index 43c05cb3ab4..49ade34795b 100644
--- a/engines/director/lingo/xlibs/consumer.h
+++ b/engines/director/lingo/xlibs/consumer.h
@@ -34,7 +34,7 @@ namespace ConsumerXObj {
 extern const char *xlibName;
 extern const char *fileNames[];
 
-void open(ObjectType type);
+void open(ObjectType type, const Common::Path &path);
 void close(ObjectType type);
 
 void m_new(int nargs);
diff --git a/engines/director/lingo/xlibs/cursorxobj.cpp b/engines/director/lingo/xlibs/cursorxobj.cpp
index c28d22520a6..e087beab45b 100644
--- a/engines/director/lingo/xlibs/cursorxobj.cpp
+++ b/engines/director/lingo/xlibs/cursorxobj.cpp
@@ -61,7 +61,7 @@ CursorXObject::CursorXObject(ObjectType ObjectType) :Object<CursorXObject>("Curs
 	_objType = ObjectType;
 }
 
-void CursorXObj::open(ObjectType type) {
+void CursorXObj::open(ObjectType type, const Common::Path &path) {
 	if (type == kXObj) {
 		CursorXObject::initMethods(xlibMethods);
 		CursorXObject *xobj = new CursorXObject(kXObj);
diff --git a/engines/director/lingo/xlibs/cursorxobj.h b/engines/director/lingo/xlibs/cursorxobj.h
index 54266c1e397..515ca324ab2 100644
--- a/engines/director/lingo/xlibs/cursorxobj.h
+++ b/engines/director/lingo/xlibs/cursorxobj.h
@@ -34,7 +34,7 @@ namespace CursorXObj {
 extern const char *xlibName;
 extern const char *fileNames[];
 
-void open(ObjectType type);
+void open(ObjectType type, const Common::Path &path);
 void close(ObjectType type);
 
 void m_new(int nargs);
diff --git a/engines/director/lingo/xlibs/darkenscreen.cpp b/engines/director/lingo/xlibs/darkenscreen.cpp
index 2dc49312ee1..7c2a21a0b5b 100644
--- a/engines/director/lingo/xlibs/darkenscreen.cpp
+++ b/engines/director/lingo/xlibs/darkenscreen.cpp
@@ -50,7 +50,7 @@ static BuiltinProto builtins[] = {
 	{ nullptr, nullptr, 0, 0, 0, VOIDSYM }
 };
 
-void DarkenScreen::open(ObjectType type) {
+void DarkenScreen::open(ObjectType type, const Common::Path &path) {
 	g_lingo->initBuiltIns(builtins);
 }
 
diff --git a/engines/director/lingo/xlibs/darkenscreen.h b/engines/director/lingo/xlibs/darkenscreen.h
index a2a38c45c7a..6dc3a5e1977 100644
--- a/engines/director/lingo/xlibs/darkenscreen.h
+++ b/engines/director/lingo/xlibs/darkenscreen.h
@@ -29,7 +29,7 @@ namespace DarkenScreen {
 extern const char *xlibName;
 extern const char *fileNames[];
 
-void open(ObjectType type);
+void open(ObjectType type, const Common::Path &path);
 void close(ObjectType type);
 
 void m_darkenscreen(int nargs);
diff --git a/engines/director/lingo/xlibs/developerStack.cpp b/engines/director/lingo/xlibs/developerStack.cpp
index e1945bd56b9..2391a106930 100644
--- a/engines/director/lingo/xlibs/developerStack.cpp
+++ b/engines/director/lingo/xlibs/developerStack.cpp
@@ -141,7 +141,7 @@ static BuiltinProto builtins[] = {
 	{ nullptr, nullptr, 0, 0, 0, VOIDSYM }
 };
 
-void DeveloperStack::open(ObjectType type) {
+void DeveloperStack::open(ObjectType type, const Common::Path &path) {
 	g_lingo->initBuiltIns(builtins);
 }
 
diff --git a/engines/director/lingo/xlibs/developerStack.h b/engines/director/lingo/xlibs/developerStack.h
index a21b8939326..a3be8cf95cb 100644
--- a/engines/director/lingo/xlibs/developerStack.h
+++ b/engines/director/lingo/xlibs/developerStack.h
@@ -29,7 +29,7 @@ namespace DeveloperStack {
 extern const char *xlibName;
 extern const char *fileNames[];
 
-void open(ObjectType type);
+void open(ObjectType type, const Common::Path &path);
 void close(ObjectType type);
 
 void b_setvolume(int nargs);
diff --git a/engines/director/lingo/xlibs/dialogsxobj.cpp b/engines/director/lingo/xlibs/dialogsxobj.cpp
index 7c85d772d39..ef3be9dfab6 100644
--- a/engines/director/lingo/xlibs/dialogsxobj.cpp
+++ b/engines/director/lingo/xlibs/dialogsxobj.cpp
@@ -70,7 +70,7 @@ static MethodProto xlibMethods[] = {
 	{ nullptr, nullptr, 0, 0, 0 }
 };
 
-void DialogsXObj::open(ObjectType type) {
+void DialogsXObj::open(ObjectType type, const Common::Path &path) {
 	if (type == kXObj) {
 		DialogsXObject::initMethods(xlibMethods);
 		DialogsXObject *xobj = new DialogsXObject(kXObj);
diff --git a/engines/director/lingo/xlibs/dialogsxobj.h b/engines/director/lingo/xlibs/dialogsxobj.h
index a9c61d59825..094444b27d9 100644
--- a/engines/director/lingo/xlibs/dialogsxobj.h
+++ b/engines/director/lingo/xlibs/dialogsxobj.h
@@ -33,7 +33,7 @@ namespace DialogsXObj {
 extern const char *xlibNames[];
 extern const char *fileNames[];
 
-void open(ObjectType type);
+void open(ObjectType type, const Common::Path &path);
 void close(ObjectType type);
 
 void m_new(int nargs);
diff --git a/engines/director/lingo/xlibs/dirutil.cpp b/engines/director/lingo/xlibs/dirutil.cpp
index 3a5f725a50f..437fdd248f2 100644
--- a/engines/director/lingo/xlibs/dirutil.cpp
+++ b/engines/director/lingo/xlibs/dirutil.cpp
@@ -76,7 +76,7 @@ DirUtilXObject::DirUtilXObject(ObjectType ObjectType) :Object<DirUtilXObject>("D
 	_objType = ObjectType;
 }
 
-void DirUtilXObj::open(ObjectType type) {
+void DirUtilXObj::open(ObjectType type, const Common::Path &path) {
 	if (type == kXObj) {
 		DirUtilXObject::initMethods(xlibMethods);
 		DirUtilXObject *xobj = new DirUtilXObject(kXObj);
diff --git a/engines/director/lingo/xlibs/dirutil.h b/engines/director/lingo/xlibs/dirutil.h
index 7282ed2d4b5..917f70fba4b 100644
--- a/engines/director/lingo/xlibs/dirutil.h
+++ b/engines/director/lingo/xlibs/dirutil.h
@@ -34,7 +34,7 @@ namespace DirUtilXObj {
 extern const char *xlibName;
 extern const char *fileNames[];
 
-void open(ObjectType type);
+void open(ObjectType type, const Common::Path &path);
 void close(ObjectType type);
 
 void m_new(int nargs);
diff --git a/engines/director/lingo/xlibs/dpwavi.cpp b/engines/director/lingo/xlibs/dpwavi.cpp
index ed89dd8e5d6..816b11c92b9 100644
--- a/engines/director/lingo/xlibs/dpwavi.cpp
+++ b/engines/director/lingo/xlibs/dpwavi.cpp
@@ -60,7 +60,7 @@ static MethodProto xlibMethods[] = {
 	{ nullptr, nullptr, 0, 0, 0 }
 };
 
-void DPwAVI::open(ObjectType type) {
+void DPwAVI::open(ObjectType type, const Common::Path &path) {
 	if (type == kXObj) {
 		DPwAVIXObject::initMethods(xlibMethods);
 		DPwAVIXObject *xobj = new DPwAVIXObject(kXObj);
diff --git a/engines/director/lingo/xlibs/dpwavi.h b/engines/director/lingo/xlibs/dpwavi.h
index eb38baacc7b..5130d1e0b50 100644
--- a/engines/director/lingo/xlibs/dpwavi.h
+++ b/engines/director/lingo/xlibs/dpwavi.h
@@ -34,7 +34,7 @@ namespace DPwAVI {
 extern const char *xlibName;
 extern const char *fileNames[];
 
-void open(ObjectType type);
+void open(ObjectType type, const Common::Path &path);
 void close(ObjectType type);
 
 void m_new(int nargs);
diff --git a/engines/director/lingo/xlibs/dpwqtw.cpp b/engines/director/lingo/xlibs/dpwqtw.cpp
index 7eb09b4ccc9..dfcdbe9221f 100644
--- a/engines/director/lingo/xlibs/dpwqtw.cpp
+++ b/engines/director/lingo/xlibs/dpwqtw.cpp
@@ -59,7 +59,7 @@ static MethodProto xlibMethods[] = {
 	{ nullptr, nullptr, 0, 0, 0 }
 };
 
-void DPwQTw::open(ObjectType type) {
+void DPwQTw::open(ObjectType type, const Common::Path &path) {
 	if (type == kXObj) {
 		DPwQTwXObject::initMethods(xlibMethods);
 		DPwQTwXObject *xobj = new DPwQTwXObject(kXObj);
diff --git a/engines/director/lingo/xlibs/dpwqtw.h b/engines/director/lingo/xlibs/dpwqtw.h
index 0b5b868ce08..dcdeb061418 100644
--- a/engines/director/lingo/xlibs/dpwqtw.h
+++ b/engines/director/lingo/xlibs/dpwqtw.h
@@ -34,7 +34,7 @@ namespace DPwQTw {
 extern const char *xlibName;
 extern const char *fileNames[];
 
-void open(ObjectType type);
+void open(ObjectType type, const Common::Path &path);
 void close(ObjectType type);
 
 void m_new(int nargs);
diff --git a/engines/director/lingo/xlibs/draw.cpp b/engines/director/lingo/xlibs/draw.cpp
index aa94a150a02..6644e26a35d 100644
--- a/engines/director/lingo/xlibs/draw.cpp
+++ b/engines/director/lingo/xlibs/draw.cpp
@@ -116,7 +116,7 @@ static MethodProto xlibMethods[] = {
 	{ nullptr, nullptr, 0, 0, 0 }
 };
 
-void DrawXObj::open(ObjectType type) {
+void DrawXObj::open(ObjectType type, const Common::Path &path) {
 	if (type == kXObj) {
 		DrawXObject::initMethods(xlibMethods);
 		DrawXObject *xobj = new DrawXObject(kXObj);
diff --git a/engines/director/lingo/xlibs/draw.h b/engines/director/lingo/xlibs/draw.h
index eed5d9ec6b9..a8776818fc8 100644
--- a/engines/director/lingo/xlibs/draw.h
+++ b/engines/director/lingo/xlibs/draw.h
@@ -34,7 +34,7 @@ namespace DrawXObj {
 extern const char *xlibName;
 extern const char *fileNames[];
 
-void open(ObjectType type);
+void open(ObjectType type, const Common::Path &path);
 void close(ObjectType type);
 
 void m_new(int nargs);
diff --git a/engines/director/lingo/xlibs/ednox.cpp b/engines/director/lingo/xlibs/ednox.cpp
index 825849322c2..1645bb5124e 100644
--- a/engines/director/lingo/xlibs/ednox.cpp
+++ b/engines/director/lingo/xlibs/ednox.cpp
@@ -95,7 +95,7 @@ static MethodProto xlibMethods[] = {
 	{ nullptr, nullptr, 0, 0, 0 }
 };
 
-void Ednox::open(ObjectType type) {
+void Ednox::open(ObjectType type, const Common::Path &path) {
 	if (type == kXObj) {
 		EdnoxObject::initMethods(xlibMethods);
 		EdnoxObject *xobj = new EdnoxObject(kXObj);
diff --git a/engines/director/lingo/xlibs/ednox.h b/engines/director/lingo/xlibs/ednox.h
index 65aff033971..0f17ac264b1 100644
--- a/engines/director/lingo/xlibs/ednox.h
+++ b/engines/director/lingo/xlibs/ednox.h
@@ -34,7 +34,7 @@ namespace Ednox {
 extern const char *xlibName;
 extern const char *fileNames[];
 
-void open(ObjectType type);
+void open(ObjectType type, const Common::Path &path);
 void close(ObjectType type);
 
 void m_new(int nargs);
diff --git a/engines/director/lingo/xlibs/eventq.cpp b/engines/director/lingo/xlibs/eventq.cpp
index 2c4a789b8b5..bbef84c263a 100644
--- a/engines/director/lingo/xlibs/eventq.cpp
+++ b/engines/director/lingo/xlibs/eventq.cpp
@@ -70,7 +70,7 @@ static MethodProto xlibMethods[] = {
 	{ nullptr, nullptr, 0, 0, 0 }
 };
 
-void EventQXObj::open(ObjectType type) {
+void EventQXObj::open(ObjectType type, const Common::Path &path) {
 	if (type == kXObj) {
 		EventQXObject::initMethods(xlibMethods);
 		EventQXObject *xobj = new EventQXObject(kXObj);
diff --git a/engines/director/lingo/xlibs/eventq.h b/engines/director/lingo/xlibs/eventq.h
index 59067c6c4f8..11bae008c50 100644
--- a/engines/director/lingo/xlibs/eventq.h
+++ b/engines/director/lingo/xlibs/eventq.h
@@ -33,7 +33,7 @@ namespace EventQXObj {
 extern const char *xlibNames[];
 extern const char *fileNames[];
 
-void open(ObjectType type);
+void open(ObjectType type, const Common::Path &path);
 void close(ObjectType type);
 
 void m_new(int nargs);
diff --git a/engines/director/lingo/xlibs/fadegammadownxcmd.cpp b/engines/director/lingo/xlibs/fadegammadownxcmd.cpp
index 40df9cf1970..e7345dee394 100644
--- a/engines/director/lingo/xlibs/fadegammadownxcmd.cpp
+++ b/engines/director/lingo/xlibs/fadegammadownxcmd.cpp
@@ -47,7 +47,7 @@ static BuiltinProto builtins[] = {
 	{ nullptr, nullptr, 0, 0, 0, VOIDSYM }
 };
 
-void FadeGammaDownXCMD::open(ObjectType type) {
+void FadeGammaDownXCMD::open(ObjectType type, const Common::Path &path) {
 	g_lingo->initBuiltIns(builtins);
 }
 
diff --git a/engines/director/lingo/xlibs/fadegammadownxcmd.h b/engines/director/lingo/xlibs/fadegammadownxcmd.h
index 0ba5225712d..6b5354fe401 100644
--- a/engines/director/lingo/xlibs/fadegammadownxcmd.h
+++ b/engines/director/lingo/xlibs/fadegammadownxcmd.h
@@ -29,7 +29,7 @@ namespace FadeGammaDownXCMD {
 extern const char *xlibName;
 extern const char *fileNames[];
 
-void open(ObjectType type);
+void open(ObjectType type, const Common::Path &path);
 void close(ObjectType type);
 
 void m_FadeGammaDown(int nargs);
diff --git a/engines/director/lingo/xlibs/fadegammaupxcmd.cpp b/engines/director/lingo/xlibs/fadegammaupxcmd.cpp
index 023003964d4..a38cdc79b99 100644
--- a/engines/director/lingo/xlibs/fadegammaupxcmd.cpp
+++ b/engines/director/lingo/xlibs/fadegammaupxcmd.cpp
@@ -47,7 +47,7 @@ static BuiltinProto builtins[] = {
 	{ nullptr, nullptr, 0, 0, 0, VOIDSYM }
 };
 
-void FadeGammaUpXCMD::open(ObjectType type) {
+void FadeGammaUpXCMD::open(ObjectType type, const Common::Path &path) {
 	g_lingo->initBuiltIns(builtins);
 }
 
diff --git a/engines/director/lingo/xlibs/fadegammaupxcmd.h b/engines/director/lingo/xlibs/fadegammaupxcmd.h
index 0c3d775fbc5..5dc1ae2c13e 100644
--- a/engines/director/lingo/xlibs/fadegammaupxcmd.h
+++ b/engines/director/lingo/xlibs/fadegammaupxcmd.h
@@ -29,7 +29,7 @@ namespace FadeGammaUpXCMD {
 extern const char *xlibName;
 extern const char *fileNames[];
 
-void open(ObjectType type);
+void open(ObjectType type, const Common::Path &path);
 void close(ObjectType type);
 
 void m_FadeGammaUp(int nargs);
diff --git a/engines/director/lingo/xlibs/fadegammaxcmd.cpp b/engines/director/lingo/xlibs/fadegammaxcmd.cpp
index a440c07ba00..5b59674ead9 100644
--- a/engines/director/lingo/xlibs/fadegammaxcmd.cpp
+++ b/engines/director/lingo/xlibs/fadegammaxcmd.cpp
@@ -47,7 +47,7 @@ static BuiltinProto builtins[] = {
 	{ nullptr, nullptr, 0, 0, 0, VOIDSYM }
 };
 
-void FadeGammaXCMD::open(ObjectType type) {
+void FadeGammaXCMD::open(ObjectType type, const Common::Path &path) {
 	g_lingo->initBuiltIns(builtins);
 }
 
diff --git a/engines/director/lingo/xlibs/fadegammaxcmd.h b/engines/director/lingo/xlibs/fadegammaxcmd.h
index ff6099005d2..02bb4453667 100644
--- a/engines/director/lingo/xlibs/fadegammaxcmd.h
+++ b/engines/director/lingo/xlibs/fadegammaxcmd.h
@@ -29,7 +29,7 @@ namespace FadeGammaXCMD {
 extern const char *xlibName;
 extern const char *fileNames[];
 
-void open(ObjectType type);
+void open(ObjectType type, const Common::Path &path);
 void close(ObjectType type);
 
 void m_FadeGamma(int nargs);
diff --git a/engines/director/lingo/xlibs/fedracul.cpp b/engines/director/lingo/xlibs/fedracul.cpp
index 14981899957..da78baee06e 100644
--- a/engines/director/lingo/xlibs/fedracul.cpp
+++ b/engines/director/lingo/xlibs/fedracul.cpp
@@ -66,7 +66,7 @@ static MethodProto xlibMethods[] = {
 	{ nullptr, nullptr, 0, 0, 0 }
 };
 
-void FEDraculXObj::open(ObjectType type) {
+void FEDraculXObj::open(ObjectType type, const Common::Path &path) {
    if (type == kXObj) {
 		FEDraculXObject::initMethods(xlibMethods);
 		FEDraculXObject *xobj = new FEDraculXObject(kXObj);
diff --git a/engines/director/lingo/xlibs/fedracul.h b/engines/director/lingo/xlibs/fedracul.h
index 7fa4472a5c9..ec0b67bb899 100644
--- a/engines/director/lingo/xlibs/fedracul.h
+++ b/engines/director/lingo/xlibs/fedracul.h
@@ -35,7 +35,7 @@ namespace FEDraculXObj {
 extern const char *xlibName;
 extern const char *fileNames[];
 
-void open(ObjectType type);
+void open(ObjectType type, const Common::Path &path);
 void close(ObjectType type);
 
 void m_new(int nargs);
diff --git a/engines/director/lingo/xlibs/feimasks.cpp b/engines/director/lingo/xlibs/feimasks.cpp
index 15a7293e498..9226da68d74 100644
--- a/engines/director/lingo/xlibs/feimasks.cpp
+++ b/engines/director/lingo/xlibs/feimasks.cpp
@@ -55,7 +55,7 @@ static MethodProto xlibMethods[] = {
 	{ nullptr, nullptr, 0, 0, 0 }
 };
 
-void FEIMasksXObj::open(ObjectType type) {
+void FEIMasksXObj::open(ObjectType type, const Common::Path &path) {
    if (type == kXObj) {
 		FEIMasksXObject::initMethods(xlibMethods);
 		FEIMasksXObject *xobj = new FEIMasksXObject(kXObj);
diff --git a/engines/director/lingo/xlibs/feimasks.h b/engines/director/lingo/xlibs/feimasks.h
index 879bfd2162c..0bd8377857b 100644
--- a/engines/director/lingo/xlibs/feimasks.h
+++ b/engines/director/lingo/xlibs/feimasks.h
@@ -35,7 +35,7 @@ namespace FEIMasksXObj {
 extern const char *xlibName;
 extern const char *fileNames[];
 
-void open(ObjectType type);
+void open(ObjectType type, const Common::Path &path);
 void close(ObjectType type);
 
 void m_new(int nargs);
diff --git a/engines/director/lingo/xlibs/feiprefs.cpp b/engines/director/lingo/xlibs/feiprefs.cpp
index 1362b31a5d5..88a311a648e 100644
--- a/engines/director/lingo/xlibs/feiprefs.cpp
+++ b/engines/director/lingo/xlibs/feiprefs.cpp
@@ -60,7 +60,7 @@ static MethodProto xlibMethods[] = {
 	{ nullptr, nullptr, 0, 0, 0 }
 };
 
-void FEIPrefsXObj::open(ObjectType type) {
+void FEIPrefsXObj::open(ObjectType type, const Common::Path &path) {
    if (type == kXObj) {
 		FEIPrefsXObject::initMethods(xlibMethods);
 		FEIPrefsXObject *xobj = new FEIPrefsXObject(kXObj);
diff --git a/engines/director/lingo/xlibs/feiprefs.h b/engines/director/lingo/xlibs/feiprefs.h
index 3073f1f2a2d..4c300b6b376 100644
--- a/engines/director/lingo/xlibs/feiprefs.h
+++ b/engines/director/lingo/xlibs/feiprefs.h
@@ -35,7 +35,7 @@ namespace FEIPrefsXObj {
 extern const char *xlibName;
 extern const char *fileNames[];
 
-void open(ObjectType type);
+void open(ObjectType type, const Common::Path &path);
 void close(ObjectType type);
 
 void m_new(int nargs);
diff --git a/engines/director/lingo/xlibs/fileexists.cpp b/engines/director/lingo/xlibs/fileexists.cpp
index 2d05a3385b5..5505d92b1b1 100644
--- a/engines/director/lingo/xlibs/fileexists.cpp
+++ b/engines/director/lingo/xlibs/fileexists.cpp
@@ -53,7 +53,7 @@ static BuiltinProto builtins[] = {
 	{ nullptr, nullptr, 0, 0, 0, VOIDSYM }
 };
 
-void FileExists::open(ObjectType type) {
+void FileExists::open(ObjectType type, const Common::Path &path) {
 	g_lingo->initBuiltIns(builtins);
 }
 
diff --git a/engines/director/lingo/xlibs/fileexists.h b/engines/director/lingo/xlibs/fileexists.h
index 212e4ffbb66..4a6e8af7b84 100644
--- a/engines/director/lingo/xlibs/fileexists.h
+++ b/engines/director/lingo/xlibs/fileexists.h
@@ -29,7 +29,7 @@ namespace FileExists {
 extern const char *xlibName;
 extern const char *fileNames[];
 
-void open(ObjectType type);
+void open(ObjectType type, const Common::Path &path);
 void close(ObjectType type);
 
 void m_fileexists(int nargs);
diff --git a/engines/director/lingo/xlibs/fileio.cpp b/engines/director/lingo/xlibs/fileio.cpp
index 365b903f95d..44526d233cf 100644
--- a/engines/director/lingo/xlibs/fileio.cpp
+++ b/engines/director/lingo/xlibs/fileio.cpp
@@ -180,7 +180,7 @@ static BuiltinProto xlibBuiltins[] = {
 };
 
 
-void FileIO::open(ObjectType type) {
+void FileIO::open(ObjectType type, const Common::Path &path) {
 	FileObject::initMethods(xlibMethods);
 	FileObject *xobj = new FileObject(type);
 	g_lingo->exposeXObject(xlibName, xobj);
diff --git a/engines/director/lingo/xlibs/fileio.h b/engines/director/lingo/xlibs/fileio.h
index 374cb688ca0..dabc79433ae 100644
--- a/engines/director/lingo/xlibs/fileio.h
+++ b/engines/director/lingo/xlibs/fileio.h
@@ -74,7 +74,7 @@ namespace FileIO {
 	extern const char *xlibName;
 	extern const char *fileNames[];
 
-	void open(ObjectType type);
+	void open(ObjectType type, const Common::Path &path);
 	void close(ObjectType type);
 
 	bool charInMatchString(char ch, const Common::String &matchString);
diff --git a/engines/director/lingo/xlibs/findereventsxcmd.cpp b/engines/director/lingo/xlibs/findereventsxcmd.cpp
index 87b1d31355a..e225cf79abc 100644
--- a/engines/director/lingo/xlibs/findereventsxcmd.cpp
+++ b/engines/director/lingo/xlibs/findereventsxcmd.cpp
@@ -47,7 +47,7 @@ static BuiltinProto builtins[] = {
 	{ nullptr, nullptr, 0, 0, 0, VOIDSYM }
 };
 
-void FinderEventsXCMD::open(ObjectType type) {
+void FinderEventsXCMD::open(ObjectType type, const Common::Path &path) {
 	g_lingo->initBuiltIns(builtins);
 }
 
diff --git a/engines/director/lingo/xlibs/findereventsxcmd.h b/engines/director/lingo/xlibs/findereventsxcmd.h
index 8104b3277ca..17892cd8f3f 100644
--- a/engines/director/lingo/xlibs/findereventsxcmd.h
+++ b/engines/director/lingo/xlibs/findereventsxcmd.h
@@ -29,7 +29,7 @@ namespace FinderEventsXCMD {
 extern const char *xlibName;
 extern const char *fileNames[];
 
-void open(ObjectType type);
+void open(ObjectType type, const Common::Path &path);
 void close(ObjectType type);
 
 void m_FinderEvents(int nargs);
diff --git a/engines/director/lingo/xlibs/findfolder.cpp b/engines/director/lingo/xlibs/findfolder.cpp
index cdaaa665c5a..49039ec635e 100644
--- a/engines/director/lingo/xlibs/findfolder.cpp
+++ b/engines/director/lingo/xlibs/findfolder.cpp
@@ -101,7 +101,7 @@ static BuiltinProto builtins[] = {
 	{ nullptr, nullptr, 0, 0, 0, VOIDSYM }
 };
 
-void FindFolder::open(ObjectType type) {
+void FindFolder::open(ObjectType type, const Common::Path &path) {
 	g_lingo->initBuiltIns(builtins);
 }
 
diff --git a/engines/director/lingo/xlibs/findfolder.h b/engines/director/lingo/xlibs/findfolder.h
index da782e0f71e..5187efc6ef1 100644
--- a/engines/director/lingo/xlibs/findfolder.h
+++ b/engines/director/lingo/xlibs/findfolder.h
@@ -29,7 +29,7 @@ namespace FindFolder {
 extern const char *xlibName;
 extern const char *fileNames[];
 
-void open(ObjectType type);
+void open(ObjectType type, const Common::Path &path);
 void close(ObjectType type);
 
 void m_findfolder(int nargs);
diff --git a/engines/director/lingo/xlibs/findsys.cpp b/engines/director/lingo/xlibs/findsys.cpp
index c7370e260f3..3c300654095 100644
--- a/engines/director/lingo/xlibs/findsys.cpp
+++ b/engines/director/lingo/xlibs/findsys.cpp
@@ -60,7 +60,7 @@ static MethodProto xlibMethods[] = {
 	{ nullptr, nullptr, 0, 0, 0 }
 };
 
-void FindSys::open(ObjectType type) {
+void FindSys::open(ObjectType type, const Common::Path &path) {
 	if (type == kXObj) {
 		FindSysXObject::initMethods(xlibMethods);
 		FindSysXObject *xobj = new FindSysXObject(kXObj);
diff --git a/engines/director/lingo/xlibs/findsys.h b/engines/director/lingo/xlibs/findsys.h
index b5587ac3ab6..3c392205c02 100644
--- a/engines/director/lingo/xlibs/findsys.h
+++ b/engines/director/lingo/xlibs/findsys.h
@@ -34,7 +34,7 @@ namespace FindSys {
 extern const char *xlibName;
 extern const char *fileNames[];
 
-void open(ObjectType type);
+void open(ObjectType type, const Common::Path &path);
 void close(ObjectType type);
 
 void m_new(int nargs);
diff --git a/engines/director/lingo/xlibs/findwin.cpp b/engines/director/lingo/xlibs/findwin.cpp
index 6bdfa8a3d85..de57e9ef2c8 100644
--- a/engines/director/lingo/xlibs/findwin.cpp
+++ b/engines/director/lingo/xlibs/findwin.cpp
@@ -57,7 +57,7 @@ static MethodProto xlibMethods[] = {
 	{ nullptr, nullptr, 0, 0, 0 }
 };
 
-void FindWin::open(ObjectType type) {
+void FindWin::open(ObjectType type, const Common::Path &path) {
 	if (type == kXObj) {
 		FindWinXObject::initMethods(xlibMethods);
 		FindWinXObject *xobj = new FindWinXObject(kXObj);
diff --git a/engines/director/lingo/xlibs/findwin.h b/engines/director/lingo/xlibs/findwin.h
index f303ea7597d..6ba81ce895d 100644
--- a/engines/director/lingo/xlibs/findwin.h
+++ b/engines/director/lingo/xlibs/findwin.h
@@ -34,7 +34,7 @@ namespace FindWin {
 extern const char *xlibName;
 extern const char *fileNames[];
 
-void open(ObjectType type);
+void open(ObjectType type, const Common::Path &path);
 void close(ObjectType type);
 
 void m_new(int nargs);
diff --git a/engines/director/lingo/xlibs/flushxobj.cpp b/engines/director/lingo/xlibs/flushxobj.cpp
index 1814ee4eab5..1ca5ce4413d 100644
--- a/engines/director/lingo/xlibs/flushxobj.cpp
+++ b/engines/director/lingo/xlibs/flushxobj.cpp
@@ -84,7 +84,7 @@ static MethodProto xlibMethods[] = {
 	{ nullptr, nullptr, 0, 0, 0 }
 };
 
-void FlushXObj::open(ObjectType type) {
+void FlushXObj::open(ObjectType type, const Common::Path &path) {
 	if (type == kXObj) {
 		FlushXObject::initMethods(xlibMethods);
 		FlushXObject *xobj = new FlushXObject(kXObj);
diff --git a/engines/director/lingo/xlibs/flushxobj.h b/engines/director/lingo/xlibs/flushxobj.h
index 1106fa1493c..8a42bc68a95 100644
--- a/engines/director/lingo/xlibs/flushxobj.h
+++ b/engines/director/lingo/xlibs/flushxobj.h
@@ -34,7 +34,7 @@ namespace FlushXObj {
 extern const char *xlibNames[];
 extern const char *fileNames[];
 
-void open(ObjectType type);
+void open(ObjectType type, const Common::Path &path);
 void close(ObjectType type);
 
 void m_new(int nargs);
diff --git a/engines/director/lingo/xlibs/fplayxobj.cpp b/engines/director/lingo/xlibs/fplayxobj.cpp
index 7f2f344d709..f922439e522 100644
--- a/engines/director/lingo/xlibs/fplayxobj.cpp
+++ b/engines/director/lingo/xlibs/fplayxobj.cpp
@@ -64,7 +64,7 @@ static BuiltinProto builtins[] = {
 	{ nullptr, nullptr, 0, 0, 0, VOIDSYM }
 };
 
-void FPlayXObj::open(ObjectType type) {
+void FPlayXObj::open(ObjectType type, const Common::Path &path) {
 	g_lingo->initBuiltIns(builtins);
 }
 
diff --git a/engines/director/lingo/xlibs/fplayxobj.h b/engines/director/lingo/xlibs/fplayxobj.h
index 8f4fb1fe5b4..f7e493748c5 100644
--- a/engines/director/lingo/xlibs/fplayxobj.h
+++ b/engines/director/lingo/xlibs/fplayxobj.h
@@ -29,7 +29,7 @@ namespace FPlayXObj {
 extern const char *xlibName;
 extern const char *fileNames[];
 
-void open(ObjectType type);
+void open(ObjectType type, const Common::Path &path);
 void close(ObjectType type);
 
 void b_fplay(int nargs);
diff --git a/engines/director/lingo/xlibs/getscreenrectsxfcn.cpp b/engines/director/lingo/xlibs/getscreenrectsxfcn.cpp
index a8c16aa29fe..269029a1e8e 100644
--- a/engines/director/lingo/xlibs/getscreenrectsxfcn.cpp
+++ b/engines/director/lingo/xlibs/getscreenrectsxfcn.cpp
@@ -47,7 +47,7 @@ static BuiltinProto builtins[] = {
 	{ nullptr, nullptr, 0, 0, 0, VOIDSYM }
 };
 
-void GetScreenRectsXFCN::open(ObjectType type) {
+void GetScreenRectsXFCN::open(ObjectType type, const Common::Path &path) {
 	g_lingo->initBuiltIns(builtins);
 }
 
diff --git a/engines/director/lingo/xlibs/getscreenrectsxfcn.h b/engines/director/lingo/xlibs/getscreenrectsxfcn.h
index 9a69db43008..c19b702b701 100644
--- a/engines/director/lingo/xlibs/getscreenrectsxfcn.h
+++ b/engines/director/lingo/xlibs/getscreenrectsxfcn.h
@@ -29,7 +29,7 @@ namespace GetScreenRectsXFCN {
 extern const char *xlibName;
 extern const char *fileNames[];
 
-void open(ObjectType type);
+void open(ObjectType type, const Common::Path &path);
 void close(ObjectType type);
 
 void m_GetScreenRects(int nargs);
diff --git a/engines/director/lingo/xlibs/getscreensizexfcn.cpp b/engines/director/lingo/xlibs/getscreensizexfcn.cpp
index 23bbc0f90c5..64ee65afba4 100644
--- a/engines/director/lingo/xlibs/getscreensizexfcn.cpp
+++ b/engines/director/lingo/xlibs/getscreensizexfcn.cpp
@@ -47,7 +47,7 @@ static BuiltinProto builtins[] = {
 	{ nullptr, nullptr, 0, 0, 0, VOIDSYM }
 };
 
-void GetScreenSizeXFCN::open(ObjectType type) {
+void GetScreenSizeXFCN::open(ObjectType type, const Common::Path &path) {
 	g_lingo->initBuiltIns(builtins);
 }
 
diff --git a/engines/director/lingo/xlibs/getscreensizexfcn.h b/engines/director/lingo/xlibs/getscreensizexfcn.h
index 2c389ff5438..a6160e8d6c2 100644
--- a/engines/director/lingo/xlibs/getscreensizexfcn.h
+++ b/engines/director/lingo/xlibs/getscreensizexfcn.h
@@ -29,7 +29,7 @@ namespace GetScreenSizeXFCN {
 extern const char *xlibName;
 extern const char *fileNames[];
 
-void open(ObjectType type);
+void open(ObjectType type, const Common::Path &path);
 void close(ObjectType type);
 
 void m_GetScreenSize(int nargs);
diff --git a/engines/director/lingo/xlibs/gpid.cpp b/engines/director/lingo/xlibs/gpid.cpp
index 4c4608a9a1e..dea247ec04d 100644
--- a/engines/director/lingo/xlibs/gpid.cpp
+++ b/engines/director/lingo/xlibs/gpid.cpp
@@ -69,7 +69,7 @@ static MethodProto xlibMethods[] = {
 	{ nullptr, nullptr, 0, 0, 0 }
 };
 
-void GpidXObj::open(ObjectType type) {
+void GpidXObj::open(ObjectType type, const Common::Path &path) {
 	if (type == kXObj) {
 		ProductIdXObject::initMethods(xlibMethods);
 		ProductIdXObject *xobj = new ProductIdXObject(kXObj);
diff --git a/engines/director/lingo/xlibs/gpid.h b/engines/director/lingo/xlibs/gpid.h
index b7ebcbb2713..b994b8b833b 100644
--- a/engines/director/lingo/xlibs/gpid.h
+++ b/engines/director/lingo/xlibs/gpid.h
@@ -35,7 +35,7 @@ namespace GpidXObj {
 extern const char *xlibName;
 extern const char *fileNames[];
 
-void open(ObjectType type);
+void open(ObjectType type, const Common::Path &path);
 void close(ObjectType type);
 
 void m_new(int nargs);
diff --git a/engines/director/lingo/xlibs/hitmap.cpp b/engines/director/lingo/xlibs/hitmap.cpp
index 607c9732d5e..6dbf191cf83 100644
--- a/engines/director/lingo/xlibs/hitmap.cpp
+++ b/engines/director/lingo/xlibs/hitmap.cpp
@@ -61,7 +61,7 @@ static MethodProto xlibMethods[] = {
 	{ nullptr, nullptr, 0, 0, 0 }
 };
 
-void HitMap::open(ObjectType type) {
+void HitMap::open(ObjectType type, const Common::Path &path) {
 	if (type == kXObj) {
 		HitMapObject::initMethods(xlibMethods);
 		HitMapObject *xobj = new HitMapObject(kXObj);
diff --git a/engines/director/lingo/xlibs/hitmap.h b/engines/director/lingo/xlibs/hitmap.h
index e4a020c0ab5..774efc7fa80 100644
--- a/engines/director/lingo/xlibs/hitmap.h
+++ b/engines/director/lingo/xlibs/hitmap.h
@@ -34,7 +34,7 @@ namespace HitMap {
 extern const char *xlibName;
 extern const char *fileNames[];
 
-void open(ObjectType type);
+void open(ObjectType type, const Common::Path &path);
 void close(ObjectType type);
 
 void m_new(int nargs);
diff --git a/engines/director/lingo/xlibs/iscd.cpp b/engines/director/lingo/xlibs/iscd.cpp
index 62cd883af68..009a1ae84a7 100644
--- a/engines/director/lingo/xlibs/iscd.cpp
+++ b/engines/director/lingo/xlibs/iscd.cpp
@@ -45,7 +45,7 @@ static BuiltinProto builtins[] = {
 	{ nullptr, nullptr, 0, 0, 0, VOIDSYM }
 };
 
-void IsCD::open(ObjectType type) {
+void IsCD::open(ObjectType type, const Common::Path &path) {
 	g_lingo->initBuiltIns(builtins);
 }
 
diff --git a/engines/director/lingo/xlibs/iscd.h b/engines/director/lingo/xlibs/iscd.h
index f3cff380eb8..e57270ba6e8 100644
--- a/engines/director/lingo/xlibs/iscd.h
+++ b/engines/director/lingo/xlibs/iscd.h
@@ -29,7 +29,7 @@ namespace IsCD {
 extern const char *xlibName;
 extern const char *fileNames[];
 
-void open(ObjectType type);
+void open(ObjectType type, const Common::Path &path);
 void close(ObjectType type);
 
 void m_iscd(int nargs);
diff --git a/engines/director/lingo/xlibs/ispippin.cpp b/engines/director/lingo/xlibs/ispippin.cpp
index b334cefbb58..1370e7062fa 100644
--- a/engines/director/lingo/xlibs/ispippin.cpp
+++ b/engines/director/lingo/xlibs/ispippin.cpp
@@ -45,7 +45,7 @@ static BuiltinProto builtins[] = {
 	{ nullptr, nullptr, 0, 0, 0, VOIDSYM }
 };
 
-void IsPippin::open(ObjectType type) {
+void IsPippin::open(ObjectType type, const Common::Path &path) {
 	g_lingo->initBuiltIns(builtins);
 }
 
diff --git a/engines/director/lingo/xlibs/ispippin.h b/engines/director/lingo/xlibs/ispippin.h
index b65958e6c47..9697ad379eb 100644
--- a/engines/director/lingo/xlibs/ispippin.h
+++ b/engines/director/lingo/xlibs/ispippin.h
@@ -29,7 +29,7 @@ namespace IsPippin {
 extern const char *xlibName;
 extern const char *fileNames[];
 
-void open(ObjectType type);
+void open(ObjectType type, const Common::Path &path);
 void close(ObjectType type);
 
 void m_ispippin(int nargs);
diff --git a/engines/director/lingo/xlibs/jitdraw3.cpp b/engines/director/lingo/xlibs/jitdraw3.cpp
index 0db9dc934ea..e9e11607f0b 100644
--- a/engines/director/lingo/xlibs/jitdraw3.cpp
+++ b/engines/director/lingo/xlibs/jitdraw3.cpp
@@ -90,7 +90,7 @@ static MethodProto xlibMethods[] = {
 	{ nullptr, nullptr, 0, 0, 0 }
 };
 
-void JITDraw3XObj::open(ObjectType type) {
+void JITDraw3XObj::open(ObjectType type, const Common::Path &path) {
 	if (type == kXObj) {
 		JITDraw3XObject::initMethods(xlibMethods);
 		JITDraw3XObject *xobj = new JITDraw3XObject(kXObj);
diff --git a/engines/director/lingo/xlibs/jitdraw3.h b/engines/director/lingo/xlibs/jitdraw3.h
index 2932977f442..ca43e278db9 100644
--- a/engines/director/lingo/xlibs/jitdraw3.h
+++ b/engines/director/lingo/xlibs/jitdraw3.h
@@ -34,7 +34,7 @@ namespace JITDraw3XObj {
 extern const char *xlibName;
 extern const char *fileNames[];
 
-void open(ObjectType type);
+void open(ObjectType type, const Common::Path &path);
 void close(ObjectType type);
 
 void m_new(int nargs);
diff --git a/engines/director/lingo/xlibs/jwxini.cpp b/engines/director/lingo/xlibs/jwxini.cpp
index 49e951a8e99..bb88b8e0cec 100644
--- a/engines/director/lingo/xlibs/jwxini.cpp
+++ b/engines/director/lingo/xlibs/jwxini.cpp
@@ -66,7 +66,7 @@ static MethodProto xlibMethods[] = {
     { nullptr, nullptr, 0, 0, 0 }
 };
 
-void JourneyWareXINIXObj::open(ObjectType type) {
+void JourneyWareXINIXObj::open(ObjectType type, const Common::Path &path) {
    if (type == kXObj) {
 	   JourneyWareXINIXObject::initMethods(xlibMethods);
 	   JourneyWareXINIXObject *xobj = new JourneyWareXINIXObject(kXObj);
diff --git a/engines/director/lingo/xlibs/jwxini.h b/engines/director/lingo/xlibs/jwxini.h
index e10848d9c4b..74c46339605 100644
--- a/engines/director/lingo/xlibs/jwxini.h
+++ b/engines/director/lingo/xlibs/jwxini.h
@@ -35,7 +35,7 @@ namespace JourneyWareXINIXObj {
 extern const char *xlibName;
 extern const char *fileNames[];
 
-void open(ObjectType type);
+void open(ObjectType type, const Common::Path &path);
 void close(ObjectType type);
 
 void m_new(int nargs);
diff --git a/engines/director/lingo/xlibs/labeldrvxobj.cpp b/engines/director/lingo/xlibs/labeldrvxobj.cpp
index ca7aea56a93..986f6f780e8 100644
--- a/engines/director/lingo/xlibs/labeldrvxobj.cpp
+++ b/engines/director/lingo/xlibs/labeldrvxobj.cpp
@@ -55,7 +55,7 @@ static MethodProto xlibMethods[] = {
 	{ nullptr, nullptr, 0, 0, 0 }
 };
 
-void LabelDrvXObj::open(ObjectType type) {
+void LabelDrvXObj::open(ObjectType type, const Common::Path &path) {
 	if (type == kXObj) {
 		LabelDrvXObject::initMethods(xlibMethods);
 		LabelDrvXObject *xobj = new LabelDrvXObject(kXObj);
diff --git a/engines/director/lingo/xlibs/labeldrvxobj.h b/engines/director/lingo/xlibs/labeldrvxobj.h
index 81672e0a1c9..6bbeac4baec 100644
--- a/engines/director/lingo/xlibs/labeldrvxobj.h
+++ b/engines/director/lingo/xlibs/labeldrvxobj.h
@@ -37,7 +37,7 @@ namespace LabelDrvXObj {
 extern const char *xlibName;
 extern const char *fileNames[];
 
-void open(ObjectType type);
+void open(ObjectType type, const Common::Path &path);
 void close(ObjectType type);
 
 void m_new(int nargs);
diff --git a/engines/director/lingo/xlibs/maniacbg.cpp b/engines/director/lingo/xlibs/maniacbg.cpp
index 2d1bbecb818..8b74b51fd45 100644
--- a/engines/director/lingo/xlibs/maniacbg.cpp
+++ b/engines/director/lingo/xlibs/maniacbg.cpp
@@ -62,7 +62,7 @@ ManiacBgXObject::ManiacBgXObject(ObjectType ObjectType) :Object<ManiacBgXObject>
 	_objType = ObjectType;
 }
 
-void ManiacBgXObj::open(ObjectType type) {
+void ManiacBgXObj::open(ObjectType type, const Common::Path &path) {
 	if (type == kXObj) {
 		ManiacBgXObject::initMethods(xlibMethods);
 		ManiacBgXObject *xobj = new ManiacBgXObject(kXObj);
diff --git a/engines/director/lingo/xlibs/maniacbg.h b/engines/director/lingo/xlibs/maniacbg.h
index a21a8794636..73f28672a7d 100644
--- a/engines/director/lingo/xlibs/maniacbg.h
+++ b/engines/director/lingo/xlibs/maniacbg.h
@@ -34,7 +34,7 @@ namespace ManiacBgXObj {
 extern const char *xlibName;
 extern const char *fileNames[];
 
-void open(ObjectType type);
+void open(ObjectType type, const Common::Path &path);
 void close(ObjectType type);
 
 void m_new(int nargs);
diff --git a/engines/director/lingo/xlibs/mapnavigatorxobj.cpp b/engines/director/lingo/xlibs/mapnavigatorxobj.cpp
index ba210b4de91..90317c3d3e7 100644
--- a/engines/director/lingo/xlibs/mapnavigatorxobj.cpp
+++ b/engines/director/lingo/xlibs/mapnavigatorxobj.cpp
@@ -113,7 +113,7 @@ MapNavigatorXObject::MapNavigatorXObject(ObjectType ObjectType) :Object<MapNavig
 	_objType = ObjectType;
 }
 
-void MapNavigatorXObj::open(ObjectType type) {
+void MapNavigatorXObj::open(ObjectType type, const Common::Path &path) {
 	if (type == kXObj) {
 		MapNavigatorXObject::initMethods(xlibMethods);
 		MapNavigatorXObject *xobj = new MapNavigatorXObject(kXObj);
diff --git a/engines/director/lingo/xlibs/mapnavigatorxobj.h b/engines/director/lingo/xlibs/mapnavigatorxobj.h
index 6bfba00c306..c45c8d50aee 100644
--- a/engines/director/lingo/xlibs/mapnavigatorxobj.h
+++ b/engines/director/lingo/xlibs/mapnavigatorxobj.h
@@ -34,7 +34,7 @@ namespace MapNavigatorXObj {
 extern const char *xlibName;
 extern const char *fileNames[];
 
-void open(ObjectType type);
+void open(ObjectType type, const Common::Path &path);
 void close(ObjectType type);
 
 void m_new(int nargs);
diff --git a/engines/director/lingo/xlibs/memcheckxobj.cpp b/engines/director/lingo/xlibs/memcheckxobj.cpp
index 0ea599c4b3b..943222e84c4 100644
--- a/engines/director/lingo/xlibs/memcheckxobj.cpp
+++ b/engines/director/lingo/xlibs/memcheckxobj.cpp
@@ -71,7 +71,7 @@ MemCheckXObject::MemCheckXObject(ObjectType ObjectType) :Object<MemCheckXObject>
 	_objType = ObjectType;
 }
 
-void MemCheckXObj::open(ObjectType type) {
+void MemCheckXObj::open(ObjectType type, const Common::Path &path) {
 	if (type == kXObj) {
 		MemCheckXObject::initMethods(xlibMethods);
 		MemCheckXObject *xobj = new MemCheckXObject(kXObj);
diff --git a/engines/director/lingo/xlibs/memcheckxobj.h b/engines/director/lingo/xlibs/memcheckxobj.h
index 6e8d6773dbd..2c7d687572a 100644
--- a/engines/director/lingo/xlibs/memcheckxobj.h
+++ b/engines/director/lingo/xlibs/memcheckxobj.h
@@ -34,7 +34,7 @@ namespace MemCheckXObj {
 extern const char *xlibName;
 extern const char *fileNames[];
 
-void open(ObjectType type);
+void open(ObjectType type, const Common::Path &path);
 void close(ObjectType type);
 
 void m_new(int nargs);
diff --git a/engines/director/lingo/xlibs/memoryxobj.cpp b/engines/director/lingo/xlibs/memoryxobj.cpp
index 3fbcca85d2c..1ff36ac88a8 100644
--- a/engines/director/lingo/xlibs/memoryxobj.cpp
+++ b/engines/director/lingo/xlibs/memoryxobj.cpp
@@ -80,7 +80,7 @@ static MethodProto xlibMethods[] = {
 	{ nullptr, nullptr, 0, 0, 0 }
 };
 
-void MemoryXObj::open(ObjectType type) {
+void MemoryXObj::open(ObjectType type, const Common::Path &path) {
 	if (type == kXObj) {
 		MemoryXObject::initMethods(xlibMethods);
 		MemoryXObject *xobj = new MemoryXObject(kXObj);
diff --git a/engines/director/lingo/xlibs/memoryxobj.h b/engines/director/lingo/xlibs/memoryxobj.h
index 6634379d988..56b67aec89a 100644
--- a/engines/director/lingo/xlibs/memoryxobj.h
+++ b/engines/director/lingo/xlibs/memoryxobj.h
@@ -35,7 +35,7 @@ namespace MemoryXObj {
 extern const char *xlibName;
 extern const char *fileNames[];
 
-void open(ObjectType type);
+void open(ObjectType type, const Common::Path &path);
 void close(ObjectType type);
 
 void m_new(int nargs);
diff --git a/engines/director/lingo/xlibs/misc.cpp b/engines/director/lingo/xlibs/misc.cpp
index 50a6252f161..b2ceda750d9 100644
--- a/engines/director/lingo/xlibs/misc.cpp
+++ b/engines/director/lingo/xlibs/misc.cpp
@@ -49,7 +49,7 @@ static MethodProto xlibMethods[] = {
     { nullptr, nullptr, 0, 0, 0 }
 };
 
-void Misc::open(ObjectType type) {
+void Misc::open(ObjectType type, const Common::Path &path) {
     if (type == kXObj) {
         MiscObject::initMethods(xlibMethods);
         MiscObject *xobj = new MiscObject(kXObj);
diff --git a/engines/director/lingo/xlibs/misc.h b/engines/director/lingo/xlibs/misc.h
index fb815d6dc05..b51aaeb3fc7 100644
--- a/engines/director/lingo/xlibs/misc.h
+++ b/engines/director/lingo/xlibs/misc.h
@@ -34,7 +34,7 @@ namespace Misc {
 extern const char *xlibName;
 extern const char *fileNames[];
 
-void open(ObjectType type);
+void open(ObjectType type, const Common::Path &path);
 void close(ObjectType type);
 
 void m_getProfileString(int nargs);
diff --git a/engines/director/lingo/xlibs/miscx.cpp b/engines/director/lingo/xlibs/miscx.cpp
index 86d7407cdf2..52729951bf2 100644
--- a/engines/director/lingo/xlibs/miscx.cpp
+++ b/engines/director/lingo/xlibs/miscx.cpp
@@ -103,7 +103,7 @@ MiscXObject::MiscXObject(ObjectType ObjectType) :Object<MiscXObject>("MiscX") {
 	_objType = ObjectType;
 }
 
-void MiscX::open(ObjectType type) {
+void MiscX::open(ObjectType type, const Common::Path &path) {
 	if (type == kXObj) {
 		MiscXObject::initMethods(xlibMethods);
 		MiscXObject *xobj = new MiscXObject(kXObj);
diff --git a/engines/director/lingo/xlibs/miscx.h b/engines/director/lingo/xlibs/miscx.h
index 6359b5f7820..9c9aede9a47 100644
--- a/engines/director/lingo/xlibs/miscx.h
+++ b/engines/director/lingo/xlibs/miscx.h
@@ -34,7 +34,7 @@ namespace MiscX {
 extern const char *xlibName;
 extern const char *fileNames[];
 
-void open(ObjectType type);
+void open(ObjectType type, const Common::Path &path);
 void close(ObjectType type);
 
 void m_new(int nargs);
diff --git a/engines/director/lingo/xlibs/mmaskxobj.cpp b/engines/director/lingo/xlibs/mmaskxobj.cpp
index 84e65dafdcd..5c1f1c5ab66 100644
--- a/engines/director/lingo/xlibs/mmaskxobj.cpp
+++ b/engines/director/lingo/xlibs/mmaskxobj.cpp
@@ -59,7 +59,7 @@ MMaskXObject::MMaskXObject(ObjectType ObjectType) :Object<MMaskXObject>("MMaskXO
 	_objType = ObjectType;
 }
 
-void MMaskXObj::open(ObjectType type) {
+void MMaskXObj::open(ObjectType type, const Common::Path &path) {
 	if (type == kXObj) {
 		MMaskXObject::initMethods(xlibMethods);
 		MMaskXObject *xobj = new MMaskXObject(kXObj);
diff --git a/engines/director/lingo/xlibs/mmaskxobj.h b/engines/director/lingo/xlibs/mmaskxobj.h
index 0caf552b33b..010dce36866 100644
--- a/engines/director/lingo/xlibs/mmaskxobj.h
+++ b/engines/director/lingo/xlibs/mmaskxobj.h
@@ -34,7 +34,7 @@ namespace MMaskXObj {
 extern const char *xlibName;
 extern const char *fileNames[];
 
-void open(ObjectType type);
+void open(ObjectType type, const Common::Path &path);
 void close(ObjectType type);
 
 void m_new(int nargs);
diff --git a/engines/director/lingo/xlibs/moovxobj.cpp b/engines/director/lingo/xlibs/moovxobj.cpp
index 939f9bbefd4..b31cfb9094b 100644
--- a/engines/director/lingo/xlibs/moovxobj.cpp
+++ b/engines/director/lingo/xlibs/moovxobj.cpp
@@ -78,7 +78,7 @@ static MethodProto xlibMethods[] = {
 	{ nullptr, nullptr, 0, 0, 0 }
 };
 
-void MoovXObj::open(ObjectType type) {
+void MoovXObj::open(ObjectType type, const Common::Path &path) {
 	if (type == kXObj) {
 		MoovXObject::initMethods(xlibMethods);
 		MoovXObject *xobj = new MoovXObject(kXObj);
diff --git a/engines/director/lingo/xlibs/moovxobj.h b/engines/director/lingo/xlibs/moovxobj.h
index 9ef1c0f4b58..6eab8d9d750 100644
--- a/engines/director/lingo/xlibs/moovxobj.h
+++ b/engines/director/lingo/xlibs/moovxobj.h
@@ -44,7 +44,7 @@ namespace MoovXObj {
 extern const char *xlibName;
 extern const char *fileNames[];
 
-void open(ObjectType type);
+void open(ObjectType type, const Common::Path &path);
 void close(ObjectType type);
 
 void m_new(int nargs);
diff --git a/engines/director/lingo/xlibs/movemousexobj.cpp b/engines/director/lingo/xlibs/movemousexobj.cpp
index c4e1b8149ab..5c1a5b77f8b 100644
--- a/engines/director/lingo/xlibs/movemousexobj.cpp
+++ b/engines/director/lingo/xlibs/movemousexobj.cpp
@@ -58,7 +58,7 @@ MoveMouseXObject::MoveMouseXObject(ObjectType ObjectType) :Object<MoveMouseXObje
 	_objType = ObjectType;
 }
 
-void MoveMouseXObj::open(ObjectType type) {
+void MoveMouseXObj::open(ObjectType type, const Common::Path &path) {
 	if (type == kXObj) {
 		MoveMouseXObject::initMethods(xlibMethods);
 		MoveMouseXObject *xobj = new MoveMouseXObject(kXObj);
diff --git a/engines/director/lingo/xlibs/movemousexobj.h b/engines/director/lingo/xlibs/movemousexobj.h
index 24a51003cfe..641e3010ba3 100644
--- a/engines/director/lingo/xlibs/movemousexobj.h
+++ b/engines/director/lingo/xlibs/movemousexobj.h
@@ -34,7 +34,7 @@ namespace MoveMouseXObj {
 extern const char *xlibName;
 extern const char *fileNames[];
 
-void open(ObjectType type);
+void open(ObjectType type, const Common::Path &path);
 void close(ObjectType type);
 
 void m_new(int nargs);
diff --git a/engines/director/lingo/xlibs/movieidxxobj.cpp b/engines/director/lingo/xlibs/movieidxxobj.cpp
index a6eff7a10c8..c2ce6b4fec7 100644
--- a/engines/director/lingo/xlibs/movieidxxobj.cpp
+++ b/engines/director/lingo/xlibs/movieidxxobj.cpp
@@ -68,7 +68,7 @@ MovieIdxXObject::MovieIdxXObject(ObjectType ObjectType) :Object<MovieIdxXObject>
 	_objType = ObjectType;
 }
 
-void MovieIdxXObj::open(ObjectType type) {
+void MovieIdxXObj::open(ObjectType type, const Common::Path &path) {
 	if (type == kXObj) {
 		MovieIdxXObject::initMethods(xlibMethods);
 		MovieIdxXObject *xobj = new MovieIdxXObject(kXObj);
diff --git a/engines/director/lingo/xlibs/movieidxxobj.h b/engines/director/lingo/xlibs/movieidxxobj.h
index d3ffcb7917d..3d4465c5524 100644
--- a/engines/director/lingo/xlibs/movieidxxobj.h
+++ b/engines/director/lingo/xlibs/movieidxxobj.h
@@ -34,7 +34,7 @@ namespace MovieIdxXObj {
 extern const char *xlibName;
 extern const char *fileNames[];
 
-void open(ObjectType type);
+void open(ObjectType type, const Common::Path &path);
 void close(ObjectType type);
 
 void m_new(int nargs);
diff --git a/engines/director/lingo/xlibs/movutils.cpp b/engines/director/lingo/xlibs/movutils.cpp
index 649d139845b..e30220394bd 100644
--- a/engines/director/lingo/xlibs/movutils.cpp
+++ b/engines/director/lingo/xlibs/movutils.cpp
@@ -120,7 +120,7 @@ static MethodProto xlibMethods[] = {
 	{ nullptr, nullptr, 0, 0, 0 }
 };
 
-void MovUtilsXObj::open(ObjectType type) {
+void MovUtilsXObj::open(ObjectType type, const Common::Path &path) {
 	if (type == kXObj) {
 		MovieUtilsXObject::initMethods(xlibMethods);
 		MovieUtilsXObject *xobj = new MovieUtilsXObject(kXObj);
diff --git a/engines/director/lingo/xlibs/movutils.h b/engines/director/lingo/xlibs/movutils.h
index 7d57e4d3924..0f73247c289 100644
--- a/engines/director/lingo/xlibs/movutils.h
+++ b/engines/director/lingo/xlibs/movutils.h
@@ -35,7 +35,7 @@ namespace MovUtilsXObj {
 extern const char *xlibNames[];
 extern const char *fileNames[];
 
-void open(ObjectType type);
+void open(ObjectType type, const Common::Path &path);
 void close(ObjectType type);
 
 void m_new(int nargs);
diff --git a/engines/director/lingo/xlibs/openbleedwindowxcmd.cpp b/engines/director/lingo/xlibs/openbleedwindowxcmd.cpp
index 338f1f7df86..54970cb1e38 100644
--- a/engines/director/lingo/xlibs/openbleedwindowxcmd.cpp
+++ b/engines/director/lingo/xlibs/openbleedwindowxcmd.cpp
@@ -47,7 +47,7 @@ static BuiltinProto builtins[] = {
 	{ nullptr, nullptr, 0, 0, 0, VOIDSYM }
 };
 
-void OpenBleedWindowXCMD::open(ObjectType type) {
+void OpenBleedWindowXCMD::open(ObjectType type, const Common::Path &path) {
 	g_lingo->initBuiltIns(builtins);
 }
 
diff --git a/engines/director/lingo/xlibs/openbleedwindowxcmd.h b/engines/director/lingo/xlibs/openbleedwindowxcmd.h
index 128c0f00247..cb1d4db7332 100644
--- a/engines/director/lingo/xlibs/openbleedwindowxcmd.h
+++ b/engines/director/lingo/xlibs/openbleedwindowxcmd.h
@@ -29,7 +29,7 @@ namespace OpenBleedWindowXCMD {
 extern const char *xlibName;
 extern const char *fileNames[];
 
-void open(ObjectType type);
+void open(ObjectType type, const Common::Path &path);
 void close(ObjectType type);
 
 void m_OpenBleedWindow(int nargs);
diff --git a/engines/director/lingo/xlibs/orthoplayxobj.cpp b/engines/director/lingo/xlibs/orthoplayxobj.cpp
index 5094eb37223..90454ec0cb8 100644
--- a/engines/director/lingo/xlibs/orthoplayxobj.cpp
+++ b/engines/director/lingo/xlibs/orthoplayxobj.cpp
@@ -125,7 +125,7 @@ static MethodProto xlibMethods[] = {
 	{ nullptr, nullptr, 0, 0, 0 }
 };
 
-void OrthoPlayXObj::open(ObjectType type) {
+void OrthoPlayXObj::open(ObjectType type, const Common::Path &path) {
 	if (type == kXObj) {
 		OrthoPlayXObject::initMethods(xlibMethods);
 		OrthoPlayXObject *xobj = new OrthoPlayXObject(kXObj);
diff --git a/engines/director/lingo/xlibs/orthoplayxobj.h b/engines/director/lingo/xlibs/orthoplayxobj.h
index ba5dd7d56fc..cab7e755fcc 100644
--- a/engines/director/lingo/xlibs/orthoplayxobj.h
+++ b/engines/director/lingo/xlibs/orthoplayxobj.h
@@ -34,7 +34,7 @@ namespace OrthoPlayXObj {
 extern const char *xlibName;
 extern const char *fileNames[];
 
-void open(ObjectType type);
+void open(ObjectType type, const Common::Path &path);
 void close(ObjectType type);
 
 void m_new(int nargs);
diff --git a/engines/director/lingo/xlibs/palxobj.cpp b/engines/director/lingo/xlibs/palxobj.cpp
index d10b4c28bd3..42cda592eb6 100644
--- a/engines/director/lingo/xlibs/palxobj.cpp
+++ b/engines/director/lingo/xlibs/palxobj.cpp
@@ -70,7 +70,7 @@ static MethodProto xlibMethods[] = {
 	{ nullptr, nullptr, 0, 0, 0 }
 };
 
-void PalXObj::open(ObjectType type) {
+void PalXObj::open(ObjectType type, const Common::Path &path) {
 	if (type == kXObj) {
 		PalXObject::initMethods(xlibMethods);
 		PalXObject *xobj = new PalXObject(kXObj);
diff --git a/engines/director/lingo/xlibs/palxobj.h b/engines/director/lingo/xlibs/palxobj.h
index 2222bd79474..439a2679235 100644
--- a/engines/director/lingo/xlibs/palxobj.h
+++ b/engines/director/lingo/xlibs/palxobj.h
@@ -37,7 +37,7 @@ namespace PalXObj {
 extern const char *xlibName;
 extern const char *fileNames[];
 
-void open(ObjectType type);
+void open(ObjectType type, const Common::Path &path);
 void close(ObjectType type);
 
 void m_new(int nargs);
diff --git a/engines/director/lingo/xlibs/panel.cpp b/engines/director/lingo/xlibs/panel.cpp
index 3c55f1ad975..4b57ef50917 100644
--- a/engines/director/lingo/xlibs/panel.cpp
+++ b/engines/director/lingo/xlibs/panel.cpp
@@ -94,7 +94,7 @@ PanelXObject::PanelXObject(ObjectType ObjectType) :Object<PanelXObject>("PanelXO
 	_objType = ObjectType;
 }
 
-void PanelXObj::open(ObjectType type) {
+void PanelXObj::open(ObjectType type, const Common::Path &path) {
 	if (type == kXObj) {
 		PanelXObject::initMethods(xlibMethods);
 		PanelXObject *xobj = new PanelXObject(kXObj);
diff --git a/engines/director/lingo/xlibs/panel.h b/engines/director/lingo/xlibs/panel.h
index 345e58541cc..f59adeb2868 100644
--- a/engines/director/lingo/xlibs/panel.h
+++ b/engines/director/lingo/xlibs/panel.h
@@ -34,7 +34,7 @@ namespace PanelXObj {
 extern const char *xlibName;
 extern const char *fileNames[];
 
-void open(ObjectType type);
+void open(ObjectType type, const Common::Path &path);
 void close(ObjectType type);
 
 void m_new(int nargs);
diff --git a/engines/director/lingo/xlibs/popupmenuxobj.cpp b/engines/director/lingo/xlibs/popupmenuxobj.cpp
index 99f361c5346..4e8cbf976a2 100644
--- a/engines/director/lingo/xlibs/popupmenuxobj.cpp
+++ b/engines/director/lingo/xlibs/popupmenuxobj.cpp
@@ -136,7 +136,7 @@ static MethodProto xlibMethods[] = {
 	{ nullptr, nullptr, 0, 0, 0 }
 };
 
-void PopUpMenuXObj::open(ObjectType type) {
+void PopUpMenuXObj::open(ObjectType type, const Common::Path &path) {
 	if (type == kXObj) {
 		PopUpMenuXObject::initMethods(xlibMethods);
 		PopUpMenuXObject *xobj = new PopUpMenuXObject(kXObj);
diff --git a/engines/director/lingo/xlibs/popupmenuxobj.h b/engines/director/lingo/xlibs/popupmenuxobj.h
index f94e6c7a95f..d155ba1fc90 100644
--- a/engines/director/lingo/xlibs/popupmenuxobj.h
+++ b/engines/director/lingo/xlibs/popupmenuxobj.h
@@ -35,7 +35,7 @@ namespace PopUpMenuXObj {
 extern const char *xlibName;
 extern const char *fileNames[];
 
-void open(ObjectType type);
+void open(ObjectType type, const Common::Path &path);
 void close(ObjectType type);
 
 void m_new(int nargs);
diff --git a/engines/director/lingo/xlibs/porta.cpp b/engines/director/lingo/xlibs/porta.cpp
index 399e5294643..0a5e1c5fe5f 100644
--- a/engines/director/lingo/xlibs/porta.cpp
+++ b/engines/director/lingo/xlibs/porta.cpp
@@ -48,7 +48,7 @@ static BuiltinProto builtins[] = {
 	{ nullptr, nullptr, 0, 0, 0, VOIDSYM }
 };
 
-void Porta::open(ObjectType type) {
+void Porta::open(ObjectType type, const Common::Path &path) {
 	g_lingo->initBuiltIns(builtins);
 }
 
diff --git a/engines/director/lingo/xlibs/porta.h b/engines/director/lingo/xlibs/porta.h
index 27fbad9f352..9e6a55f9f2a 100644
--- a/engines/director/lingo/xlibs/porta.h
+++ b/engines/director/lingo/xlibs/porta.h
@@ -29,7 +29,7 @@ namespace Porta {
 extern const char *xlibName;
 extern const char *fileNames[];
 
-void open(ObjectType type);
+void open(ObjectType type, const Common::Path &path);
 void close(ObjectType type);
 
 void b_porta(int nargs);
diff --git a/engines/director/lingo/xlibs/portaxcmd.cpp b/engines/director/lingo/xlibs/portaxcmd.cpp
index a50d5518776..9c0d07bfdad 100644
--- a/engines/director/lingo/xlibs/portaxcmd.cpp
+++ b/engines/director/lingo/xlibs/portaxcmd.cpp
@@ -47,7 +47,7 @@ static BuiltinProto builtins[] = {
 	{ nullptr, nullptr, 0, 0, 0, VOIDSYM }
 };
 
-void PortaXCMD::open(ObjectType type) {
+void PortaXCMD::open(ObjectType type, const Common::Path &path) {
 	g_lingo->initBuiltIns(builtins);
 }
 
diff --git a/engines/director/lingo/xlibs/portaxcmd.h b/engines/director/lingo/xlibs/portaxcmd.h
index 93f0de16c63..2efbe1d0c58 100644
--- a/engines/director/lingo/xlibs/portaxcmd.h
+++ b/engines/director/lingo/xlibs/portaxcmd.h
@@ -29,7 +29,7 @@ namespace PortaXCMD {
 extern const char *xlibName;
 extern const char *fileNames[];
 
-void open(ObjectType type);
+void open(ObjectType type, const Common::Path &path);
 void close(ObjectType type);
 
 void m_Porta(int nargs);
diff --git a/engines/director/lingo/xlibs/prefpath.cpp b/engines/director/lingo/xlibs/prefpath.cpp
index f136f42027b..7b450c06a39 100644
--- a/engines/director/lingo/xlibs/prefpath.cpp
+++ b/engines/director/lingo/xlibs/prefpath.cpp
@@ -51,7 +51,7 @@ static MethodProto xlibMethods[] = {
 	{ nullptr, nullptr, 0, 0, 0 }
 };
 
-void PrefPath::open(ObjectType type) {
+void PrefPath::open(ObjectType type, const Common::Path &path) {
 	if (type == kXObj) {
 		PrefPathObject::initMethods(xlibMethods);
 		PrefPathObject *xobj = new PrefPathObject(kXObj);
diff --git a/engines/director/lingo/xlibs/prefpath.h b/engines/director/lingo/xlibs/prefpath.h
index 577378cbaf4..bfa49f55185 100644
--- a/engines/director/lingo/xlibs/prefpath.h
+++ b/engines/director/lingo/xlibs/prefpath.h
@@ -34,7 +34,7 @@ namespace PrefPath {
 extern const char *xlibName;
 extern const char *fileNames[];
 
-void open(ObjectType type);
+void open(ObjectType type, const Common::Path &path);
 void close(ObjectType type);
 
 void m_new(int nargs);
diff --git a/engines/director/lingo/xlibs/printomatic.cpp b/engines/director/lingo/xlibs/printomatic.cpp
index 0bb8dec495b..23544d3d99a 100644
--- a/engines/director/lingo/xlibs/printomatic.cpp
+++ b/engines/director/lingo/xlibs/printomatic.cpp
@@ -141,7 +141,7 @@ static MethodProto xlibMethods[] = {
 	{ nullptr, nullptr, 0, 0, 0 }
 };
 
-void PrintOMaticXObj::open(ObjectType type) {
+void PrintOMaticXObj::open(ObjectType type, const Common::Path &path) {
 	if (type == kXObj) {
 		PrintOMaticXObject::initMethods(xlibMethods);
 		PrintOMaticXObject *xobj = new PrintOMaticXObject(kXObj);
diff --git a/engines/director/lingo/xlibs/printomatic.h b/engines/director/lingo/xlibs/printomatic.h
index a68da6db177..33e653167be 100644
--- a/engines/director/lingo/xlibs/printomatic.h
+++ b/engines/director/lingo/xlibs/printomatic.h
@@ -34,7 +34,7 @@ namespace PrintOMaticXObj {
 extern const char *xlibName;
 extern const char *fileNames[];
 
-void open(ObjectType type);
+void open(ObjectType type, const Common::Path &path);
 void close(ObjectType type);
 
 void m_new(int nargs);
diff --git a/engines/director/lingo/xlibs/processxobj.cpp b/engines/director/lingo/xlibs/processxobj.cpp
index e9d2f31ac29..463828d69f7 100644
--- a/engines/director/lingo/xlibs/processxobj.cpp
+++ b/engines/director/lingo/xlibs/processxobj.cpp
@@ -64,7 +64,7 @@ ProcessXObject::ProcessXObject(ObjectType ObjectType) :Object<ProcessXObject>("P
 	_objType = ObjectType;
 }
 
-void ProcessXObj::open(ObjectType type) {
+void ProcessXObj::open(ObjectType type, const Common::Path &path) {
 	if (type == kXObj) {
 		ProcessXObject::initMethods(xlibMethods);
 		ProcessXObject *xobj = new ProcessXObject(kXObj);
diff --git a/engines/director/lingo/xlibs/processxobj.h b/engines/director/lingo/xlibs/processxobj.h
index 870a57637f6..47288c4c02c 100644
--- a/engines/director/lingo/xlibs/processxobj.h
+++ b/engines/director/lingo/xlibs/processxobj.h
@@ -34,7 +34,7 @@ namespace ProcessXObj {
 extern const char *xlibName;
 extern const char *fileNames[];
 
-void open(ObjectType type);
+void open(ObjectType type, const Common::Path &path);
 void close(ObjectType type);
 
 void m_new(int nargs);
diff --git a/engines/director/lingo/xlibs/qtcatmovieplayerxobj.cpp b/engines/director/lingo/xlibs/qtcatmovieplayerxobj.cpp
index 9f36e365a71..320e85c3a35 100644
--- a/engines/director/lingo/xlibs/qtcatmovieplayerxobj.cpp
+++ b/engines/director/lingo/xlibs/qtcatmovieplayerxobj.cpp
@@ -70,7 +70,7 @@ QTCatMoviePlayerXObject::QTCatMoviePlayerXObject(ObjectType ObjectType) :Object<
 	_objType = ObjectType;
 }
 
-void QTCatMoviePlayerXObj::open(ObjectType type) {
+void QTCatMoviePlayerXObj::open(ObjectType type, const Common::Path &path) {
 	if (type == kXObj) {
 		QTCatMoviePlayerXObject::initMethods(xlibMethods);
 		QTCatMoviePlayerXObject *xobj = new QTCatMoviePlayerXObject(kXObj);
diff --git a/engines/director/lingo/xlibs/qtcatmovieplayerxobj.h b/engines/director/lingo/xlibs/qtcatmovieplayerxobj.h
index 93b78c3e113..e7c4023924d 100644
--- a/engines/director/lingo/xlibs/qtcatmovieplayerxobj.h
+++ b/engines/director/lingo/xlibs/qtcatmovieplayerxobj.h
@@ -34,7 +34,7 @@ namespace QTCatMoviePlayerXObj {
 extern const char *xlibName;
 extern const char *fileNames[];
 
-void open(ObjectType type);
+void open(ObjectType type, const Common::Path &path);
 void close(ObjectType type);
 
 void m_new(int nargs);
diff --git a/engines/director/lingo/xlibs/qtmovie.cpp b/engines/director/lingo/xlibs/qtmovie.cpp
index 848771f5567..96ae96761f3 100644
--- a/engines/director/lingo/xlibs/qtmovie.cpp
+++ b/engines/director/lingo/xlibs/qtmovie.cpp
@@ -50,7 +50,7 @@ static BuiltinProto builtins[] = {
 	{ nullptr, nullptr, 0, 0, 0, VOIDSYM }
 };
 
-void QTMovie::open(ObjectType type) {
+void QTMovie::open(ObjectType type, const Common::Path &path) {
 	g_lingo->initBuiltIns(builtins);
 }
 
diff --git a/engines/director/lingo/xlibs/qtmovie.h b/engines/director/lingo/xlibs/qtmovie.h
index 8e9bba5198a..f438773e240 100644
--- a/engines/director/lingo/xlibs/qtmovie.h
+++ b/engines/director/lingo/xlibs/qtmovie.h
@@ -29,7 +29,7 @@ namespace QTMovie {
 extern const char *xlibName;
 extern const char *fileNames[];
 
-void open(ObjectType type);
+void open(ObjectType type, const Common::Path &path);
 void close(ObjectType type);
 
 void m_qtmovie(int nargs);
diff --git a/engines/director/lingo/xlibs/qtvr.cpp b/engines/director/lingo/xlibs/qtvr.cpp
index 4b57e9256ac..cd885c69ca0 100644
--- a/engines/director/lingo/xlibs/qtvr.cpp
+++ b/engines/director/lingo/xlibs/qtvr.cpp
@@ -97,7 +97,7 @@ QTVRXObject::QTVRXObject(ObjectType ObjectType) :Object<QTVRXObject>("QTVR") {
 	_objType = ObjectType;
 }
 
-void QTVR::open(ObjectType type) {
+void QTVR::open(ObjectType type, const Common::Path &path) {
 	if (type == kXObj) {
 		QTVRXObject::initMethods(xlibMethods);
 		QTVRXObject *xobj = new QTVRXObject(kXObj);
diff --git a/engines/director/lingo/xlibs/qtvr.h b/engines/director/lingo/xlibs/qtvr.h
index d77e2328913..9d74177e29b 100644
--- a/engines/director/lingo/xlibs/qtvr.h
+++ b/engines/director/lingo/xlibs/qtvr.h
@@ -29,7 +29,7 @@ namespace QTVR {
 extern const char *xlibName;
 extern const char *fileNames[];
 
-void open(ObjectType type);
+void open(ObjectType type, const Common::Path &path);
 void close(ObjectType type);
 
 void m_new(int nargs);
diff --git a/engines/director/lingo/xlibs/quicktime.cpp b/engines/director/lingo/xlibs/quicktime.cpp
index 7dba5a0423d..91110b5960a 100644
--- a/engines/director/lingo/xlibs/quicktime.cpp
+++ b/engines/director/lingo/xlibs/quicktime.cpp
@@ -50,7 +50,7 @@ static MethodProto xlibMethods[] = {
     { nullptr, nullptr, 0, 0, 0 }
 };
 
-void Quicktime::open(ObjectType type) {
+void Quicktime::open(ObjectType type, const Common::Path &path) {
     if (type == kXObj) {
         QuicktimeObject::initMethods(xlibMethods);
         QuicktimeObject *xobj = new QuicktimeObject(kXObj);
diff --git a/engines/director/lingo/xlibs/quicktime.h b/engines/director/lingo/xlibs/quicktime.h
index c7dc8a9196c..ff888d4eab8 100644
--- a/engines/director/lingo/xlibs/quicktime.h
+++ b/engines/director/lingo/xlibs/quicktime.h
@@ -34,7 +34,7 @@ namespace Quicktime {
 extern const char *xlibName;
 extern const char *fileNames[];
 
-void open(ObjectType type);
+void open(ObjectType type, const Common::Path &path);
 void close(ObjectType type);
 
 void m_playStage(int nargs);
diff --git a/engines/director/lingo/xlibs/registercomponent.cpp b/engines/director/lingo/xlibs/registercomponent.cpp
index 97eec0fe230..6790330aefb 100644
--- a/engines/director/lingo/xlibs/registercomponent.cpp
+++ b/engines/director/lingo/xlibs/registercomponent.cpp
@@ -43,7 +43,7 @@ static BuiltinProto builtins[] = {
 	{ nullptr, nullptr, 0, 0, 0, VOIDSYM }
 };
 
-void RegisterComponent::open(ObjectType type) {
+void RegisterComponent::open(ObjectType type, const Common::Path &path) {
 	g_lingo->initBuiltIns(builtins);
 }
 
diff --git a/engines/director/lingo/xlibs/registercomponent.h b/engines/director/lingo/xlibs/registercomponent.h
index d23720714f2..2f7663ff4b7 100644
--- a/engines/director/lingo/xlibs/registercomponent.h
+++ b/engines/director/lingo/xlibs/registercomponent.h
@@ -41,7 +41,7 @@ namespace RegisterComponent {
 extern const char *xlibName;
 extern const char *fileNames[];
 
-void open(ObjectType type);
+void open(ObjectType type, const Common::Path &path);
 void close(ObjectType type);
 
 void b_RegisterComponent(int nargs);
diff --git a/engines/director/lingo/xlibs/remixxcmd.cpp b/engines/director/lingo/xlibs/remixxcmd.cpp
index 9e27b7fba17..195cfcaca89 100644
--- a/engines/director/lingo/xlibs/remixxcmd.cpp
+++ b/engines/director/lingo/xlibs/remixxcmd.cpp
@@ -47,7 +47,10 @@ static BuiltinProto builtins[] = {
 	{ nullptr, nullptr, 0, 0, 0, VOIDSYM }
 };
 
-void RemixXCMD::open(ObjectType type) {
+// Turntable minigame in The Seven Colors.
+// Uses a resource file containing samples + this XCMD to play them.
+
+void RemixXCMD::open(ObjectType type, const Common::Path &path) {
 	g_lingo->initBuiltIns(builtins);
 }
 
diff --git a/engines/director/lingo/xlibs/remixxcmd.h b/engines/director/lingo/xlibs/remixxcmd.h
index 5225e95550a..344bb47c431 100644
--- a/engines/director/lingo/xlibs/remixxcmd.h
+++ b/engines/director/lingo/xlibs/remixxcmd.h
@@ -29,7 +29,7 @@ namespace RemixXCMD {
 extern const char *xlibName;
 extern const char *fileNames[];
 
-void open(ObjectType type);
+void open(ObjectType type, const Common::Path &path);
 void close(ObjectType type);
 
 void m_Remix(int nargs);
diff --git a/engines/director/lingo/xlibs/serialportxobj.cpp b/engines/director/lingo/xlibs/serialportxobj.cpp
index bfbeec049a5..71deb069c2f 100644
--- a/engines/director/lingo/xlibs/serialportxobj.cpp
+++ b/engines/director/lingo/xlibs/serialportxobj.cpp
@@ -64,7 +64,7 @@ static MethodProto xlibMethods[] = {
 	{ nullptr, nullptr, 0, 0, 0 }
 };
 
-void SerialPortXObj::open(ObjectType type) {
+void SerialPortXObj::open(ObjectType type, const Common::Path &path) {
 	if (type == kXObj) {
 		SerialPortXObject::initMethods(xlibMethods);
 		SerialPortXObject *xobj = new SerialPortXObject(kXObj);
diff --git a/engines/director/lingo/xlibs/serialportxobj.h b/engines/director/lingo/xlibs/serialportxobj.h
index 134143cca1e..ecd936755fa 100644
--- a/engines/director/lingo/xlibs/serialportxobj.h
+++ b/engines/director/lingo/xlibs/serialportxobj.h
@@ -34,7 +34,7 @@ namespace SerialPortXObj {
 extern const char *xlibName;
 extern const char *fileNames[];
 
-void open(ObjectType type);
+void open(ObjectType type, const Common::Path &path);
 void close(ObjectType type);
 
 void m_new(int nargs);
diff --git a/engines/director/lingo/xlibs/soundjam.cpp b/engines/director/lingo/xlibs/soundjam.cpp
index f2fc98e2226..07c6cb9b2bb 100644
--- a/engines/director/lingo/xlibs/soundjam.cpp
+++ b/engines/director/lingo/xlibs/soundjam.cpp
@@ -76,7 +76,7 @@ static MethodProto xlibMethods[] = {
 	{ nullptr, nullptr, 0, 0, 0 }
 };
 
-void SoundJam::open(ObjectType type) {
+void SoundJam::open(ObjectType type, const Common::Path &path) {
 	if (type == kXObj) {
 		SoundJamObject::initMethods(xlibMethods);
 		SoundJamObject *xobj = new SoundJamObject(kXObj);
diff --git a/engines/director/lingo/xlibs/soundjam.h b/engines/director/lingo/xlibs/soundjam.h
index f2f0050e9bd..231a789241a 100644
--- a/engines/director/lingo/xlibs/soundjam.h
+++ b/engines/director/lingo/xlibs/soundjam.h
@@ -37,7 +37,7 @@ namespace SoundJam {
 extern const char *xlibName;
 extern const char *fileNames[];
 
-void open(ObjectType type);
+void open(ObjectType type, const Common::Path &path);
 void close(ObjectType type);
 
 void m_new(int nargs);
diff --git a/engines/director/lingo/xlibs/spacemgr.cpp b/engines/director/lingo/xlibs/spacemgr.cpp
index b84257f6719..97a0841e1d3 100644
--- a/engines/director/lingo/xlibs/spacemgr.cpp
+++ b/engines/director/lingo/xlibs/spacemgr.cpp
@@ -137,7 +137,7 @@ SpaceMgrXObject::SpaceMgrXObject(ObjectType ObjectType) :Object<SpaceMgrXObject>
 	_objType = ObjectType;
 }
 
-void SpaceMgr::open(ObjectType type) {
+void SpaceMgr::open(ObjectType type, const Common::Path &path) {
 	if (type == kXObj) {
 		SpaceMgrXObject::initMethods(xlibMethods);
 		SpaceMgrXObject *xobj = new SpaceMgrXObject(kXObj);
diff --git a/engines/director/lingo/xlibs/spacemgr.h b/engines/director/lingo/xlibs/spacemgr.h
index a16c3fbd8c5..1ef5a4a64da 100644
--- a/engines/director/lingo/xlibs/spacemgr.h
+++ b/engines/director/lingo/xlibs/spacemgr.h
@@ -50,7 +50,7 @@ struct SpaceCollection {
 extern const char *xlibName;
 extern const char *fileNames[];
 
-void open(ObjectType type);
+void open(ObjectType type, const Common::Path &path);
 void close(ObjectType type);
 
 void m_new(int nargs);
diff --git a/engines/director/lingo/xlibs/stagetc.cpp b/engines/director/lingo/xlibs/stagetc.cpp
index a19afae5b3a..3899b71fac0 100644
--- a/engines/director/lingo/xlibs/stagetc.cpp
+++ b/engines/director/lingo/xlibs/stagetc.cpp
@@ -53,7 +53,7 @@ static MethodProto xlibMethods[] = {
 	{ nullptr, nullptr, 0, 0, 0 }
 };
 
-void StageTCXObj::open(ObjectType type) {
+void StageTCXObj::open(ObjectType type, const Common::Path &path) {
 	if (type == kXObj) {
 		StageTCXObject::initMethods(xlibMethods);
 		StageTCXObject *xobj = new StageTCXObject(kXObj);
diff --git a/engines/director/lingo/xlibs/stagetc.h b/engines/director/lingo/xlibs/stagetc.h
index 9913e8fbeaf..6c95d8e849e 100644
--- a/engines/director/lingo/xlibs/stagetc.h
+++ b/engines/director/lingo/xlibs/stagetc.h
@@ -34,7 +34,7 @@ namespace StageTCXObj {
 extern const char *xlibName;
 extern const char *fileNames[];
 
-void open(ObjectType type);
+void open(ObjectType type, const Common::Path &path);
 void close(ObjectType type);
 
 void m_new(int nargs);
diff --git a/engines/director/lingo/xlibs/unittest.cpp b/engines/director/lingo/xlibs/unittest.cpp
index fc19610d0e0..59588035efb 100644
--- a/engines/director/lingo/xlibs/unittest.cpp
+++ b/engines/director/lingo/xlibs/unittest.cpp
@@ -53,7 +53,7 @@ static BuiltinProto builtins[] = {
 	{ nullptr, nullptr, 0, 0, 0, VOIDSYM }
 };
 
-void UnitTest::open(ObjectType type) {
+void UnitTest::open(ObjectType type, const Common::Path &path) {
 	g_lingo->initBuiltIns(builtins);
 }
 
diff --git a/engines/director/lingo/xlibs/unittest.h b/engines/director/lingo/xlibs/unittest.h
index 5d4b9315aad..65041d7c4b3 100644
--- a/engines/director/lingo/xlibs/unittest.h
+++ b/engines/director/lingo/xlibs/unittest.h
@@ -29,7 +29,7 @@ namespace UnitTest {
 extern const char *xlibName;
 extern const char *fileNames[];
 
-void open(ObjectType type);
+void open(ObjectType type, const Common::Path &path);
 void close(ObjectType type);
 
 void m_UTScreenshot(int nargs);
diff --git a/engines/director/lingo/xlibs/valkyrie.cpp b/engines/director/lingo/xlibs/valkyrie.cpp
index 02aaa6dc43f..56a82706ade 100644
--- a/engines/director/lingo/xlibs/valkyrie.cpp
+++ b/engines/director/lingo/xlibs/valkyrie.cpp
@@ -65,7 +65,7 @@ static MethodProto xlibMethods[] = {
 	{ nullptr, nullptr, 0, 0, 0 }
 };
 
-void ValkyrieXObj::open(ObjectType type) {
+void ValkyrieXObj::open(ObjectType type, const Common::Path &path) {
 	if (type == kXObj) {
 		ValkyrieXObject::initMethods(xlibMethods);
 		ValkyrieXObject *xobj = new ValkyrieXObject(kXObj);
diff --git a/engines/director/lingo/xlibs/valkyrie.h b/engines/director/lingo/xlibs/valkyrie.h
index 699da38a72a..cb0a02afc11 100644
--- a/engines/director/lingo/xlibs/valkyrie.h
+++ b/engines/director/lingo/xlibs/valkyrie.h
@@ -34,7 +34,7 @@ namespace ValkyrieXObj {
 extern const char *xlibName;
 extern const char *fileNames[];
 
-void open(ObjectType type);
+void open(ObjectType type, const Common::Path &path);
 void close(ObjectType type);
 
 void m_new(int nargs);
diff --git a/engines/director/lingo/xlibs/videodiscxobj.cpp b/engines/director/lingo/xlibs/videodiscxobj.cpp
index 6081ddfb5c7..6c133f1a3a9 100644
--- a/engines/director/lingo/xlibs/videodiscxobj.cpp
+++ b/engines/director/lingo/xlibs/videodiscxobj.cpp
@@ -151,7 +151,7 @@ static MethodProto xlibMethods[] = {
 	{ nullptr, nullptr, 0, 0, 0 }
 };
 
-void VideodiscXObj::open(ObjectType type) {
+void VideodiscXObj::open(ObjectType type, const Common::Path &path) {
 	if (type == kXObj) {
 		VideodiscXObject::initMethods(xlibMethods);
 		VideodiscXObject *xobj = new VideodiscXObject(kXObj);
diff --git a/engines/director/lingo/xlibs/videodiscxobj.h b/engines/director/lingo/xlibs/videodiscxobj.h
index 66454b6a7dc..49f780334a7 100644
--- a/engines/director/lingo/xlibs/videodiscxobj.h
+++ b/engines/director/lingo/xlibs/videodiscxobj.h
@@ -34,7 +34,7 @@ namespace VideodiscXObj {
 extern const char *xlibName;
 extern const char *fileNames[];
 
-void open(ObjectType type);
+void open(ObjectType type, const Common::Path &path);
 void close(ObjectType type);
 
 void m_new(int nargs);
diff --git a/engines/director/lingo/xlibs/vmisonxfcn.cpp b/engines/director/lingo/xlibs/vmisonxfcn.cpp
index c29c65b0f07..cd22b3a943e 100644
--- a/engines/director/lingo/xlibs/vmisonxfcn.cpp
+++ b/engines/director/lingo/xlibs/vmisonxfcn.cpp
@@ -47,7 +47,7 @@ static BuiltinProto builtins[] = {
 	{ nullptr, nullptr, 0, 0, 0, VOIDSYM }
 };
 
-void VMisOnXFCN::open(ObjectType type) {
+void VMisOnXFCN::open(ObjectType type, const Common::Path &path) {
 	g_lingo->initBuiltIns(builtins);
 }
 
diff --git a/engines/director/lingo/xlibs/vmisonxfcn.h b/engines/director/lingo/xlibs/vmisonxfcn.h
index f44a9a6f01d..28ff3cfa3dd 100644
--- a/engines/director/lingo/xlibs/vmisonxfcn.h
+++ b/engines/director/lingo/xlibs/vmisonxfcn.h
@@ -29,7 +29,7 @@ namespace VMisOnXFCN {
 extern const char *xlibName;
 extern const char *fileNames[];
 
-void open(ObjectType type);
+void open(ObjectType type, const Common::Path &path);
 void close(ObjectType type);
 
 void m_VMisOn(int nargs);
diff --git a/engines/director/lingo/xlibs/volumelist.cpp b/engines/director/lingo/xlibs/volumelist.cpp
index 12b44e9f9bb..bed86586f43 100644
--- a/engines/director/lingo/xlibs/volumelist.cpp
+++ b/engines/director/lingo/xlibs/volumelist.cpp
@@ -50,7 +50,7 @@ static BuiltinProto builtins[] = {
 	{ nullptr, nullptr, 0, 0, 0, VOIDSYM }
 };
 
-void VolumeList::open(ObjectType type) {
+void VolumeList::open(ObjectType type, const Common::Path &path) {
 	g_lingo->initBuiltIns(builtins);
 }
 
diff --git a/engines/director/lingo/xlibs/volumelist.h b/engines/director/lingo/xlibs/volumelist.h
index 16ceb95ae5d..8cb53ffae31 100644
--- a/engines/director/lingo/xlibs/volumelist.h
+++ b/engines/director/lingo/xlibs/volumelist.h
@@ -29,7 +29,7 @@ namespace VolumeList {
 extern const char *xlibName;
 extern const char *fileNames[];
 
-void open(ObjectType type);
+void open(ObjectType type, const Common::Path &path);
 void close(ObjectType type);
 
 void m_volumelist(int nargs);
diff --git a/engines/director/lingo/xlibs/widgetxobj.cpp b/engines/director/lingo/xlibs/widgetxobj.cpp
index 8df0b8b806c..309ddbdce88 100644
--- a/engines/director/lingo/xlibs/widgetxobj.cpp
+++ b/engines/director/lingo/xlibs/widgetxobj.cpp
@@ -59,7 +59,7 @@ static MethodProto xlibMethods[] = {
 	{ nullptr, nullptr, 0, 0, 0 }
 };
 
-void WidgetXObj::open(ObjectType type) {
+void WidgetXObj::open(ObjectType type, const Common::Path &path) {
 	if (type == kXObj) {
 		WidgetXObject::initMethods(xlibMethods);
 		WidgetXObject *xobj = new WidgetXObject(kXObj);
diff --git a/engines/director/lingo/xlibs/widgetxobj.h b/engines/director/lingo/xlibs/widgetxobj.h
index c8a6afb72ae..dc9ac3112bc 100644
--- a/engines/director/lingo/xlibs/widgetxobj.h
+++ b/engines/director/lingo/xlibs/widgetxobj.h
@@ -34,7 +34,7 @@ namespace WidgetXObj {
 extern const char *xlibName;
 extern const char *fileNames[];
 
-void open(ObjectType type);
+void open(ObjectType type, const Common::Path &path);
 void close(ObjectType type);
 
 void m_new(int nargs);
diff --git a/engines/director/lingo/xlibs/window.cpp b/engines/director/lingo/xlibs/window.cpp
index 34711613550..1dfc7a7d522 100644
--- a/engines/director/lingo/xlibs/window.cpp
+++ b/engines/director/lingo/xlibs/window.cpp
@@ -107,7 +107,7 @@ WindowXObject::WindowXObject(ObjectType ObjectType) :Object<WindowXObject>("Wind
 	_objType = ObjectType;
 }
 
-void WindowXObj::open(ObjectType type) {
+void WindowXObj::open(ObjectType type, const Common::Path &path) {
 	if (type == kXObj) {
 		WindowXObject::initMethods(xlibMethods);
 		WindowXObject *xobj = new WindowXObject(kXObj);
diff --git a/engines/director/lingo/xlibs/window.h b/engines/director/lingo/xlibs/window.h
index 4e5abafa253..2cff4bf3dfc 100644
--- a/engines/director/lingo/xlibs/window.h
+++ b/engines/director/lingo/xlibs/window.h
@@ -34,7 +34,7 @@ namespace WindowXObj {
 extern const char *xlibName;
 extern const char *fileNames[];
 
-void open(ObjectType type);
+void open(ObjectType type, const Common::Path &path);
 void close(ObjectType type);
 
 void m_new(int nargs);
diff --git a/engines/director/lingo/xlibs/wininfo.cpp b/engines/director/lingo/xlibs/wininfo.cpp
index 5c13ebc5d3e..506bcb027e0 100644
--- a/engines/director/lingo/xlibs/wininfo.cpp
+++ b/engines/director/lingo/xlibs/wininfo.cpp
@@ -63,7 +63,7 @@ WinInfoXObject::WinInfoXObject(ObjectType ObjectType) : Object<WinInfoXObject>("
 	_objType = ObjectType;
 }
 
-void WinInfoXObj::open(ObjectType type) {
+void WinInfoXObj::open(ObjectType type, const Common::Path &path) {
 	if (type == kXObj) {
 		WinInfoXObject::initMethods(xlibMethods);
 		WinInfoXObject *xobj = new WinInfoXObject(kXObj);
diff --git a/engines/director/lingo/xlibs/wininfo.h b/engines/director/lingo/xlibs/wininfo.h
index 9fdc77046a3..6fdea36b3de 100644
--- a/engines/director/lingo/xlibs/wininfo.h
+++ b/engines/director/lingo/xlibs/wininfo.h
@@ -34,7 +34,7 @@ namespace WinInfoXObj {
 extern const char *xlibName;
 extern const char *fileNames[];
 
-void open(ObjectType type);
+void open(ObjectType type, const Common::Path &path);
 void close(ObjectType type);
 
 void m_new(int nargs);
diff --git a/engines/director/lingo/xlibs/winxobj.cpp b/engines/director/lingo/xlibs/winxobj.cpp
index fb522c66c16..8394e9b0ce7 100644
--- a/engines/director/lingo/xlibs/winxobj.cpp
+++ b/engines/director/lingo/xlibs/winxobj.cpp
@@ -247,7 +247,7 @@ static MethodProto xlibMethods[] = {
 	{ nullptr, nullptr, 0, 0, 0 }
 };
 
-void RearWindowXObj::open(ObjectType type) {
+void RearWindowXObj::open(ObjectType type, const Common::Path &path) {
 	if (type == kXObj) {
 		RearWindowXObject::initMethods(xlibMethods);
 		RearWindowXObject *xobj = new RearWindowXObject(kXObj);
diff --git a/engines/director/lingo/xlibs/winxobj.h b/engines/director/lingo/xlibs/winxobj.h
index 59200763915..515f5ad8bb9 100644
--- a/engines/director/lingo/xlibs/winxobj.h
+++ b/engines/director/lingo/xlibs/winxobj.h
@@ -35,7 +35,7 @@ namespace RearWindowXObj {
 extern const char *xlibName;
 extern const char *fileNames[];
 
-void open(ObjectType type);
+void open(ObjectType type, const Common::Path &path);
 void close(ObjectType type);
 
 void m_new(int nargs);
diff --git a/engines/director/lingo/xlibs/xcmdglue.cpp b/engines/director/lingo/xlibs/xcmdglue.cpp
index 17091c80ce6..0c83190caf8 100644
--- a/engines/director/lingo/xlibs/xcmdglue.cpp
+++ b/engines/director/lingo/xlibs/xcmdglue.cpp
@@ -71,7 +71,7 @@ XCMDGlueXObject::XCMDGlueXObject(ObjectType ObjectType) :Object<XCMDGlueXObject>
 	_objType = ObjectType;
 }
 
-void XCMDGlueXObj::open(ObjectType type) {
+void XCMDGlueXObj::open(ObjectType type, const Common::Path &path) {
 	if (type == kXObj) {
 		XCMDGlueXObject::initMethods(xlibMethods);
 		XCMDGlueXObject *xobj = new XCMDGlueXObject(kXObj);
diff --git a/engines/director/lingo/xlibs/xcmdglue.h b/engines/director/lingo/xlibs/xcmdglue.h
index a6d28ee43ab..dff41a061c8 100644
--- a/engines/director/lingo/xlibs/xcmdglue.h
+++ b/engines/director/lingo/xlibs/xcmdglue.h
@@ -34,7 +34,7 @@ namespace XCMDGlueXObj {
 extern const char *xlibName;
 extern const char *fileNames[];
 
-void open(ObjectType type);
+void open(ObjectType type, const Common::Path &path);
 void close(ObjectType type);
 
 void m_new(int nargs);
diff --git a/engines/director/lingo/xlibs/xio.cpp b/engines/director/lingo/xlibs/xio.cpp
index c2d43792220..4254f7e1b43 100644
--- a/engines/director/lingo/xlibs/xio.cpp
+++ b/engines/director/lingo/xlibs/xio.cpp
@@ -60,7 +60,7 @@ static MethodProto xlibMethods[] = {
 	{ nullptr, nullptr, 0, 0, 0 }
 };
 
-void XioXObj::open(ObjectType type) {
+void XioXObj::open(ObjectType type, const Common::Path &path) {
 	if (type == kXObj) {
 		XioXObject::initMethods(xlibMethods);
 		XioXObject *xobj = new XioXObject(kXObj);
diff --git a/engines/director/lingo/xlibs/xio.h b/engines/director/lingo/xlibs/xio.h
index 15d5b176468..2e0744b2c70 100644
--- a/engines/director/lingo/xlibs/xio.h
+++ b/engines/director/lingo/xlibs/xio.h
@@ -34,7 +34,7 @@ namespace XioXObj {
 extern const char *xlibName;
 extern const char *fileNames[];
 
-void open(ObjectType type);
+void open(ObjectType type, const Common::Path &path);
 void close(ObjectType type);
 
 void m_new(int nargs);
diff --git a/engines/director/lingo/xlibs/xplayanim.cpp b/engines/director/lingo/xlibs/xplayanim.cpp
index 88393000a93..f7159501243 100644
--- a/engines/director/lingo/xlibs/xplayanim.cpp
+++ b/engines/director/lingo/xlibs/xplayanim.cpp
@@ -47,7 +47,7 @@ static BuiltinProto builtins[] = {
 	{ nullptr, nullptr, 0, 0, 0, VOIDSYM }
 };
 
-void XPlayAnim::open(ObjectType type) {
+void XPlayAnim::open(ObjectType type, const Common::Path &path) {
 	g_lingo->initBuiltIns(builtins);
 }
 
diff --git a/engines/director/lingo/xlibs/xplayanim.h b/engines/director/lingo/xlibs/xplayanim.h
index 42c291f3b22..975f7f540da 100644
--- a/engines/director/lingo/xlibs/xplayanim.h
+++ b/engines/director/lingo/xlibs/xplayanim.h
@@ -38,7 +38,7 @@ namespace XPlayAnim {
 extern const char *xlibName;
 extern const char *fileNames[];
 
-void open(ObjectType type);
+void open(ObjectType type, const Common::Path &path);
 void close(ObjectType type);
 
 void b_xplayanim(int nargs);
diff --git a/engines/director/lingo/xlibs/xsoundxfcn.cpp b/engines/director/lingo/xlibs/xsoundxfcn.cpp
index 022a1228803..47feab4dbf0 100644
--- a/engines/director/lingo/xlibs/xsoundxfcn.cpp
+++ b/engines/director/lingo/xlibs/xsoundxfcn.cpp
@@ -47,7 +47,7 @@ static BuiltinProto builtins[] = {
 	{ nullptr, nullptr, 0, 0, 0, VOIDSYM }
 };
 
-void XSoundXFCN::open(ObjectType type) {
+void XSoundXFCN::open(ObjectType type, const Common::Path &path) {
 	g_lingo->initBuiltIns(builtins);
 }
 
diff --git a/engines/director/lingo/xlibs/xsoundxfcn.h b/engines/director/lingo/xlibs/xsoundxfcn.h
index cb0195a8ee8..d5ffa128aec 100644
--- a/engines/director/lingo/xlibs/xsoundxfcn.h
+++ b/engines/director/lingo/xlibs/xsoundxfcn.h
@@ -29,7 +29,7 @@ namespace XSoundXFCN {
 extern const char *xlibName;
 extern const char *fileNames[];
 
-void open(ObjectType type);
+void open(ObjectType type, const Common::Path &path);
 void close(ObjectType type);
 
 void m_XSound(int nargs);
diff --git a/engines/director/lingo/xlibs/yasix.cpp b/engines/director/lingo/xlibs/yasix.cpp
index e719ef65773..20ff032b866 100644
--- a/engines/director/lingo/xlibs/yasix.cpp
+++ b/engines/director/lingo/xlibs/yasix.cpp
@@ -49,7 +49,7 @@ static BuiltinProto builtins[] = {
 	{ nullptr, nullptr, 0, 0, 0, VOIDSYM }
 };
 
-void Yasix::open(ObjectType type) {
+void Yasix::open(ObjectType type, const Common::Path &path) {
 	g_lingo->initBuiltIns(builtins);
 }
 
diff --git a/engines/director/lingo/xlibs/yasix.h b/engines/director/lingo/xlibs/yasix.h
index acd8eac2363..0a109d3b5a5 100644
--- a/engines/director/lingo/xlibs/yasix.h
+++ b/engines/director/lingo/xlibs/yasix.h
@@ -29,7 +29,7 @@ namespace Yasix {
 extern const char *xlibName;
 extern const char *fileNames[];
 
-void open(ObjectType type);
+void open(ObjectType type, const Common::Path &path);
 void close(ObjectType type);
 
 void m_yasix(int nargs);
diff --git a/engines/director/lingo/xtras/scrnutil.cpp b/engines/director/lingo/xtras/scrnutil.cpp
index fcf268de975..8ebf24050c5 100644
--- a/engines/director/lingo/xtras/scrnutil.cpp
+++ b/engines/director/lingo/xtras/scrnutil.cpp
@@ -68,7 +68,7 @@ ScrnUtilXtraObject::ScrnUtilXtraObject(ObjectType ObjectType) :Object<ScrnUtilXt
 	_objType = ObjectType;
 }
 
-void ScrnUtilXtra::open(ObjectType type) {
+void ScrnUtilXtra::open(ObjectType type, const Common::Path &path) {
     ScrnUtilXtraObject::initMethods(xlibMethods);
     ScrnUtilXtraObject *xobj = new ScrnUtilXtraObject(type);
     g_lingo->exposeXObject(xlibName, xobj);
diff --git a/engines/director/lingo/xtras/scrnutil.h b/engines/director/lingo/xtras/scrnutil.h
index cd94de83e9a..2987e26c15c 100644
--- a/engines/director/lingo/xtras/scrnutil.h
+++ b/engines/director/lingo/xtras/scrnutil.h
@@ -34,7 +34,7 @@ namespace ScrnUtilXtra {
 extern const char *xlibName;
 extern const char *fileNames[];
 
-void open(ObjectType type);
+void open(ObjectType type, const Common::Path &path);
 void close(ObjectType type);
 
 void m_ScreenToClipboard(int nargs);
diff --git a/engines/director/resource.cpp b/engines/director/resource.cpp
index b4bb76749ca..a1166dae05c 100644
--- a/engines/director/resource.cpp
+++ b/engines/director/resource.cpp
@@ -176,14 +176,14 @@ void Window::probeResources(Archive *archive) {
 		// fork of the file to state which XObject or HyperCard XCMD/XFCNs
 		// need to be loaded in.
 		MacArchive *resFork = new MacArchive();
-		Common::Path resForkPathName = archive->getPathName();
-		if (resFork->openFile(findPath(resForkPathName))) {
+		Common::Path resForkPathName = findPath(archive->getPathName());
+		if (resFork->openFile(resForkPathName)) {
 			if (resFork->hasResource(MKTAG('X', 'C', 'O', 'D'), -1)) {
 				Common::Array<uint16> xcod = resFork->getResourceIDList(MKTAG('X', 'C', 'O', 'D'));
 				for (auto &iterator : xcod) {
 					Resource res = resFork->getResourceDetail(MKTAG('X', 'C', 'O', 'D'), iterator);
 					debug(0, "Detected XObject '%s'", res.name.c_str());
-					g_lingo->openXLib(res.name, kXObj);
+					g_lingo->openXLib(res.name, kXObj, resForkPathName);
 				}
 			}
 			if (resFork->hasResource(MKTAG('X', 'C', 'M', 'D'), -1)) {
@@ -191,7 +191,7 @@ void Window::probeResources(Archive *archive) {
 				for (auto &iterator : xcmd) {
 					Resource res = resFork->getResourceDetail(MKTAG('X', 'C', 'M', 'D'), iterator);
 					debug(0, "Detected XCMD '%s'", res.name.c_str());
-					g_lingo->openXLib(res.name, kXObj);
+					g_lingo->openXLib(res.name, kXObj, resForkPathName);
 				}
 			}
 			if (resFork->hasResource(MKTAG('X', 'F', 'C', 'N'), -1)) {
@@ -199,7 +199,7 @@ void Window::probeResources(Archive *archive) {
 				for (auto &iterator : xfcn) {
 					Resource res = resFork->getResourceDetail(MKTAG('X', 'F', 'C', 'N'), iterator);
 					debug(0, "Detected XFCN '%s'", res.name.c_str());
-					g_lingo->openXLib(res.name, kXObj);
+					g_lingo->openXLib(res.name, kXObj, resForkPathName);
 				}
 			}
 		}
@@ -228,7 +228,7 @@ void Window::probeResources(Archive *archive) {
 				d.getChildren(xtras, Common::FSNode::kListFilesOnly);
 				for (auto &it : xtras) {
 					debug(0, "Detected Xtra '%s'", it.getName().c_str());
-					g_lingo->openXLib(it.getName(), kXtraObj);
+					g_lingo->openXLib(it.getName(), kXtraObj, basePath.appendComponent(it.getName()));
 				}
 			}
 		}
@@ -589,9 +589,9 @@ Archive *DirectorEngine::loadMac(const Common::Path &movie) {
 
 void Window::loadStartMovieXLibs() {
 	if (strcmp(g_director->getGameId(), "warlock") == 0 && g_director->getPlatform() != Common::kPlatformWindows) {
-		g_lingo->openXLib("FPlayXObj", kXObj);
+		g_lingo->openXLib("FPlayXObj", kXObj, Common::Path());
 	}
-	g_lingo->openXLib("SerialPort", kXObj);
+	g_lingo->openXLib("SerialPort", kXObj, Common::Path());
 }
 
 ProjectorArchive::ProjectorArchive(Common::Path path)
diff --git a/engines/director/util.cpp b/engines/director/util.cpp
index 049bf95f922..7cd33acb2be 100644
--- a/engines/director/util.cpp
+++ b/engines/director/util.cpp
@@ -947,6 +947,24 @@ Common::Path findMoviePath(const Common::String &path, bool currentFolder, bool
 	return result;
 }
 
+Common::Path findXLibPath(const Common::String &path, bool currentFolder, bool searchPaths) {
+	const char *extsD3[] = { ".DLL", nullptr };
+	const char *extsD5[] = { ".DLL", ".X16", ".X32", nullptr };
+
+	const char **exts = nullptr;
+	if (g_director->getVersion() < 500) {
+		exts = extsD3;
+	} else if (g_director->getVersion() < 600) {
+		exts = extsD5;
+	} else {
+		warning("findXLibPath(): file extensions not yet supported for version %d, falling back to D5", g_director->getVersion());
+		exts = extsD5;
+	}
+
+	Common::Path result = findPath(path, currentFolder, searchPaths, false, exts);
+	return result;
+}
+
 Common::Path findAudioPath(const Common::String &path, bool currentFolder, bool searchPaths) {
 	const char *exts[] = { ".AIF", ".WAV", nullptr };
 
diff --git a/engines/director/util.h b/engines/director/util.h
index fa594324fcc..0364cb0fc7e 100644
--- a/engines/director/util.h
+++ b/engines/director/util.h
@@ -51,6 +51,7 @@ Common::Path findAbsolutePath(const Common::String &path, bool directory = false
 Common::Path findPath(const Common::Path &path, bool currentFolder = true, bool searchPaths = true, bool directory = false, const char **exts = nullptr);
 Common::Path findPath(const Common::String &path, bool currentFolder = true, bool searchPaths = true, bool directory = false, const char **exts = nullptr);
 Common::Path findMoviePath(const Common::String &path, bool currentFolder = true, bool searchPaths = true);
+Common::Path findXLibPath(const Common::String &path, bool currentFolder = true, bool searchPaths = true);
 Common::Path findAudioPath(const Common::String &path, bool currentFolder = true, bool searchPaths = true);
 
 


Commit: 95ca062e6d78ea07d367710928765203281c5d5d
    https://github.com/scummvm/scummvm/commit/95ca062e6d78ea07d367710928765203281c5d5d
Author: Scott Percival (code at moral.net.au)
Date: 2024-03-31T16:58:31+02:00

Commit Message:
DIRECTOR: Always disable puppet sounds on movie change

Previously the puppetSound flag condition would only be disabled if the
sound was playing at the time of the movie switch.

Fixes music when entering the cat room straight from the start room
in The Seven Colors.

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


diff --git a/engines/director/score.cpp b/engines/director/score.cpp
index aec48c540d2..a2a109ad9cb 100644
--- a/engines/director/score.cpp
+++ b/engines/director/score.cpp
@@ -1465,8 +1465,10 @@ Channel *Score::getChannelById(uint16 id) {
 }
 
 void Score::playSoundChannel(bool puppetOnly) {
-	debugC(5, kDebugSound, "playSoundChannel(): Sound1 %s Sound2 %s", _currentFrame->_mainChannels.sound1.asString().c_str(), _currentFrame->_mainChannels.sound2.asString().c_str());
 	DirectorSound *sound = _window->getSoundManager();
+	debugC(5, kDebugSound, "Score::playSoundChannel(): Sound1: %s puppet: %d type: %d, Sound2: %s puppet: %d, type: %d",
+			_currentFrame->_mainChannels.sound1.asString().c_str(), sound->isChannelPuppet(1), _currentFrame->_mainChannels.soundType1,
+			_currentFrame->_mainChannels.sound2.asString().c_str(), sound->isChannelPuppet(2), _currentFrame->_mainChannels.soundType2);
 
 	if (sound->isChannelPuppet(1)) {
 		sound->playPuppetSound(1);
diff --git a/engines/director/sound.cpp b/engines/director/sound.cpp
index 18a373130e1..a1b1c80a0b1 100644
--- a/engines/director/sound.cpp
+++ b/engines/director/sound.cpp
@@ -457,11 +457,11 @@ void DirectorSound::playExternalSound(uint16 menu, uint16 submenu, uint8 soundCh
 void DirectorSound::changingMovie() {
 	for (auto it : _channels) {
 		it._value->movieChanged = true;
-		if (isChannelActive(it._key)) {
-			if (isChannelPuppet(it._key)) {
-				setPuppetSound(SoundID(), it._key); // disable puppet sound
-			}
+		if (isChannelPuppet(it._key)) {
+			setPuppetSound(SoundID(), it._key); // disable puppet sound
+		}
 
+		if (isChannelActive(it._key)) {
 			// Don't stop this sound until there's a new, non-zero sound in this channel.
 			it._value->stopOnZero = false;
 


Commit: 637caad1c387c9346aa41486fc4652ffd020ae28
    https://github.com/scummvm/scummvm/commit/637caad1c387c9346aa41486fc4652ffd020ae28
Author: Scott Percival (code at moral.net.au)
Date: 2024-03-31T16:58:31+02:00

Commit Message:
DIRECTOR: Fix setting "the volume of sound"

Previously, volume changes would only be picked up by the next sound
started in the channel (if at all).

Fixes the hint music clashing in the fortune teller floor of the
department store and Club Exclaim in The Seven Colors.

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


diff --git a/engines/director/lingo/lingo-the.cpp b/engines/director/lingo/lingo-the.cpp
index e0fcbc967e7..c49f0b365fb 100644
--- a/engines/director/lingo/lingo-the.cpp
+++ b/engines/director/lingo/lingo-the.cpp
@@ -828,7 +828,7 @@ Datum Lingo::getTheEntity(int entity, Datum &id, int field) {
 		break;
 	case kTheSoundLevel:
 		// getting sound level of channel 1, maybe need to be amended in higher version
-		d = _vm->getCurrentWindow()->getSoundManager()->getSoundLevel(1);
+		d = _vm->getCurrentWindow()->getSoundManager()->getChannelVolume(1) / 32;
 		break;
 	case kTheSprite:
 		d = getTheSprite(id, field);
@@ -1136,10 +1136,7 @@ void Lingo::setTheEntity(int entity, Datum &id, int field, Datum &d) {
 			switch (field) {
 			case kTheVolume:
 				{
-					SoundChannel *chan = _vm->getCurrentWindow()->getSoundManager()->getChannel(id.asInt());
-					if (chan) {
-						chan->volume = (byte)d.asInt();
-					}
+					_vm->getCurrentWindow()->getSoundManager()->setChannelVolume(id.asInt(), MAX(0, MIN(d.asInt(), 255)));
 				}
 				break;
 			default:
@@ -1150,7 +1147,7 @@ void Lingo::setTheEntity(int entity, Datum &id, int field, Datum &d) {
 		break;
 	case kTheSoundLevel:
 		// setting all of the channel for now
-		_vm->getCurrentWindow()->getSoundManager()->setSoundLevel(-1, d.asInt());
+		_vm->getCurrentWindow()->getSoundManager()->setChannelVolume(-1, MAX(0, MIN(d.asInt() * 32, 255)));
 		break;
 	case kTheSprite:
 		setTheSprite(id, field, d);
diff --git a/engines/director/score.cpp b/engines/director/score.cpp
index a2a109ad9cb..5de8e3ab279 100644
--- a/engines/director/score.cpp
+++ b/engines/director/score.cpp
@@ -1466,9 +1466,9 @@ Channel *Score::getChannelById(uint16 id) {
 
 void Score::playSoundChannel(bool puppetOnly) {
 	DirectorSound *sound = _window->getSoundManager();
-	debugC(5, kDebugSound, "Score::playSoundChannel(): Sound1: %s puppet: %d type: %d, Sound2: %s puppet: %d, type: %d",
-			_currentFrame->_mainChannels.sound1.asString().c_str(), sound->isChannelPuppet(1), _currentFrame->_mainChannels.soundType1,
-			_currentFrame->_mainChannels.sound2.asString().c_str(), sound->isChannelPuppet(2), _currentFrame->_mainChannels.soundType2);
+	debugC(5, kDebugSound, "Score::playSoundChannel(): Sound1: %s puppet: %d type: %d, volume: %d, Sound2: %s puppet: %d, type: %d, volume: %d",
+			_currentFrame->_mainChannels.sound1.asString().c_str(), sound->isChannelPuppet(1), _currentFrame->_mainChannels.soundType1, sound->getChannelVolume(1),
+			_currentFrame->_mainChannels.sound2.asString().c_str(), sound->isChannelPuppet(2), _currentFrame->_mainChannels.soundType2, sound->getChannelVolume(2));
 
 	if (sound->isChannelPuppet(1)) {
 		sound->playPuppetSound(1);
diff --git a/engines/director/sound.cpp b/engines/director/sound.cpp
index a1b1c80a0b1..d757e29f3c4 100644
--- a/engines/director/sound.cpp
+++ b/engines/director/sound.cpp
@@ -640,40 +640,33 @@ void DirectorSound::playFPlaySound(const Common::Array<Common::String> &fplayLis
 	playFPlaySound();
 }
 
-void DirectorSound::setSoundLevelInternal(uint8 soundChannel, uint8 soundLevel) {
-	// we have 8 level of sounds, and in ScummVM, we have range 0 to 255, thus 1 level represent 32
-	_channels[soundChannel]->volume = soundLevel * 32;
-	_volumes[soundChannel] = soundLevel * 32;
+void DirectorSound::setChannelVolumeInternal(uint8 soundChannel, uint8 volume) {
+	if (volume == _channels[soundChannel]->volume)
+		return;
+
+	cancelFade(soundChannel);
 
-	if (_enable && isChannelActive(soundChannel))
+	_channels[soundChannel]->volume = volume;
+	_volumes[soundChannel] = volume;
+
+	if (_enable)
 		_mixer->setChannelVolume(_channels[soundChannel]->handle, _channels[soundChannel]->volume);
 }
 
 // -1 represent all the sound channel
-void DirectorSound::setSoundLevel(int channel, uint8 soundLevel) {
-	if (soundLevel >= 8) {
-		warning("DirectorSound::setSoundLevel: soundLevel %d out of bounds", soundLevel);
-		return;
-	}
-
+void DirectorSound::setChannelVolume(int channel, uint8 volume) {
 	if (channel != -1) {
 		if (!assertChannel(channel))
 			return;
-		debugC(5, kDebugSound, "DirectorSound::setSoundLevel: setting channel %d to level %d", channel, soundLevel);
-		setSoundLevelInternal(channel, soundLevel);
+		debugC(5, kDebugSound, "DirectorSound::setChannelVolume: setting channel %d to volume %d", channel, volume);
+		setChannelVolumeInternal(channel, volume);
 	} else {
-		debugC(5, kDebugSound, "DirectorSound::setSoundLevel: setting all channels to level %d", soundLevel);
+		debugC(5, kDebugSound, "DirectorSound::setChannelVolume: setting all channels to volume %d", volume);
 		for (uint i = 0; i < _channels.size(); i++)
-			setSoundLevelInternal(i + 1, soundLevel);
+			setChannelVolumeInternal(i + 1, volume);
 	}
 }
 
-uint8 DirectorSound::getSoundLevel(uint8 soundChannel) {
-	if (!assertChannel(soundChannel))
-		return 0;
-	return _channels[soundChannel]->volume / 32;
-}
-
 SNDDecoder::SNDDecoder()
 		: AudioDecoder() {
 	_data = nullptr;
diff --git a/engines/director/sound.h b/engines/director/sound.h
index 0071be127ef..9c66a4aeea2 100644
--- a/engines/director/sound.h
+++ b/engines/director/sound.h
@@ -185,8 +185,6 @@ public:
 	void playExternalSound(uint16 menu, uint16 submenu, uint8 soundChannel);
 	void playFPlaySound(const Common::Array<Common::String> &fplayList);
 	void playFPlaySound();
-	void setSoundLevel(int channel, uint8 soundLevel);
-	uint8 getSoundLevel(uint8 soundChannel);
 	void setSoundEnabled(bool enabled);
 	void systemBeep();
 	void changingMovie();
@@ -207,6 +205,7 @@ public:
 
 	bool isChannelActive(uint8 soundChannel);
 	uint8 getChannelVolume(uint8 soundChannel);
+	void setChannelVolume(int channel, uint8 volume);
 	void stopSound(uint8 soundChannel);
 	void stopSound();
 	void setChannelDefaultVolume(int soundChannel);
@@ -216,7 +215,7 @@ private:
 	bool isLastPlayedSound(uint8 soundChannel, const SoundID &soundId);
 	bool shouldStopOnZero(uint8 soundChannel);
 
-	void setSoundLevelInternal(uint8 soundChannel, uint8 soundLevel);
+	void setChannelVolumeInternal(uint8 soundChannel, uint8 volume);
 	bool assertChannel(int soundChannel);
 	void cancelFade(uint8 soundChannel);
 };


Commit: 12cf67948dc9a5c139c81c5ae5f87760b97b422c
    https://github.com/scummvm/scummvm/commit/12cf67948dc9a5c139c81c5ae5f87760b97b422c
Author: Scott Percival (code at moral.net.au)
Date: 2024-03-31T16:58:31+02:00

Commit Message:
DIRECTOR: Allow multiple concurrent sound fades

Fixes collecting the orange heart in The Seven Colors.

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


diff --git a/engines/director/lingo/lingo-builtins.cpp b/engines/director/lingo/lingo-builtins.cpp
index 6719da90592..0486bd7aaeb 100644
--- a/engines/director/lingo/lingo-builtins.cpp
+++ b/engines/director/lingo/lingo-builtins.cpp
@@ -3123,7 +3123,7 @@ void LB::b_sound(int nargs) {
 
 		TYPECHECK(firstArg, INT);
 		soundManager->registerFade(firstArg.u.i, true, ticks);
-		score->_activeFade = firstArg.u.i;
+		score->_activeFade = true;
 		return;
 	} else if (verb.u.s->equalsIgnoreCase("fadeOut")) {
 		if (nargs > 2) {
@@ -3135,7 +3135,7 @@ void LB::b_sound(int nargs) {
 
 		TYPECHECK2(firstArg, INT, FLOAT);
 		soundManager->registerFade(firstArg.asInt(), false, ticks);
-		score->_activeFade = firstArg.u.i;
+		score->_activeFade = true;
 		return;
 	} else if (verb.u.s->equalsIgnoreCase("playFile")) {
 		ARGNUMCHECK(3)
diff --git a/engines/director/score.cpp b/engines/director/score.cpp
index 5de8e3ab279..1f84567d8aa 100644
--- a/engines/director/score.cpp
+++ b/engines/director/score.cpp
@@ -79,7 +79,7 @@ Score::Score(Movie *movie) {
 	_cursorDirty = false;
 	_waitForClick = false;
 	_waitForClickCursor = false;
-	_activeFade = 0;
+	_activeFade = false;
 	_playState = kPlayNotStarted;
 
 	_numChannelsDisplayed = 0;
@@ -490,8 +490,7 @@ void Score::updateNextFrameTime() {
 
 void Score::update() {
 	if (_activeFade) {
-		if (!_soundManager->fadeChannel(_activeFade))
-			_activeFade = 0;
+		_activeFade = _soundManager->fadeChannels();
 	}
 
 	if (!debugChannelSet(-1, kDebugFast)) {
@@ -825,8 +824,7 @@ bool Score::renderPrePaletteCycle(RenderMode mode) {
 				g_director->setPalette(calcPal, 256);
 				g_director->draw();
 				if (_activeFade) {
-					if (!_soundManager->fadeChannel(_activeFade))
-					_activeFade = 0;
+					_activeFade = _soundManager->fadeChannels();
 				}
 				// On click, stop loop and reset palette
 				if (_vm->processEvents(true)) {
@@ -869,8 +867,7 @@ bool Score::renderPrePaletteCycle(RenderMode mode) {
 				g_director->setPalette(calcPal, 256);
 				g_director->draw();
 				if (_activeFade) {
-					if (!_soundManager->fadeChannel(_activeFade))
-					_activeFade = 0;
+					_activeFade = _soundManager->fadeChannels();
 				}
 				// On click, stop loop and reset palette
 				if (_vm->processEvents(true)) {
@@ -986,8 +983,7 @@ void Score::renderPaletteCycle(RenderMode mode) {
 					g_director->shiftPalette(firstColor, lastColor, false);
 					g_director->draw();
 					if (_activeFade) {
-						if (!_soundManager->fadeChannel(_activeFade))
-						_activeFade = 0;
+						_activeFade = _soundManager->fadeChannels();
 					}
 					// On click, stop loop and reset palette
 					if (_vm->processEvents(true)) {
@@ -1004,8 +1000,7 @@ void Score::renderPaletteCycle(RenderMode mode) {
 						g_director->shiftPalette(firstColor, lastColor, true);
 						g_director->draw();
 						if (_activeFade) {
-							if (!_soundManager->fadeChannel(_activeFade))
-							_activeFade = 0;
+							_activeFade = _soundManager->fadeChannels();
 						}
 						// On click, stop loop and reset palette
 						if (_vm->processEvents(true)) {
@@ -1126,8 +1121,7 @@ void Score::renderPaletteCycle(RenderMode mode) {
 				for (int i = 0; i < kFadeColorWait; i++) {
 					uint32 startTime = g_system->getMillis();
 					if (_activeFade) {
-						if (!_soundManager->fadeChannel(_activeFade))
-						_activeFade = 0;
+						_activeFade = _soundManager->fadeChannels();
 					}
 					// On click, stop loop and reset palette
 					if (_vm->processEvents(true)) {
@@ -1154,8 +1148,7 @@ void Score::renderPaletteCycle(RenderMode mode) {
 					g_director->setPalette(calcPal, 256);
 					g_director->draw();
 					if (_activeFade) {
-						if (!_soundManager->fadeChannel(_activeFade))
-						_activeFade = 0;
+						_activeFade = _soundManager->fadeChannels();
 					}
 					// On click, stop loop and reset palette
 					if (_vm->processEvents(true)) {
diff --git a/engines/director/score.h b/engines/director/score.h
index 25e89fa7dfe..f007be24638 100644
--- a/engines/director/score.h
+++ b/engines/director/score.h
@@ -181,7 +181,7 @@ public:
 	bool _waitForClick;
 	bool _waitForClickCursor;
 	bool _cursorDirty;
-	int _activeFade;
+	bool _activeFade;
 	Cursor _defaultCursor;
 	CursorRef _currentCursor;
 	bool _skipTransition;
diff --git a/engines/director/sound.cpp b/engines/director/sound.cpp
index d757e29f3c4..6854b65ddff 100644
--- a/engines/director/sound.cpp
+++ b/engines/director/sound.cpp
@@ -278,35 +278,33 @@ void DirectorSound::registerFade(uint8 soundChannel, bool fadeIn, int ticks) {
 	_channels[soundChannel]->volume = startVol;
 }
 
-bool DirectorSound::fadeChannel(uint8 soundChannel) {
-	if (!assertChannel(soundChannel))
-		return false;
-
-	if (!_mixer->isSoundHandleActive(_channels[soundChannel]->handle))
-		return false;
-
-	FadeParams *fade = _channels[soundChannel]->fade;
-	if (!fade)
-		return false;
+bool DirectorSound::fadeChannels() {
+	bool ongoing = false;
 
-	fade->lapsedTicks = _window->getVM()->getMacTicks() - fade->startTicks;
-	if (fade->lapsedTicks > fade->totalTicks) {
-		return false;
-	}
+	for (auto &it : _channels) {
+		FadeParams *fade = it._value->fade;
+		if (!fade)
+			continue;
 
-	int fadeVol;
-	if (fade->fadeIn) {
-		fadeVol = MIN(fade->lapsedTicks * ((float)fade->targetVol / fade->totalTicks), (float)Audio::Mixer::kMaxChannelVolume);
-	} else {
-		fadeVol = MAX((fade->totalTicks - fade->lapsedTicks) * ((float)fade->startVol / fade->totalTicks), (float)0);
-	}
+		fade->lapsedTicks = _window->getVM()->getMacTicks() - fade->startTicks;
+		if (fade->lapsedTicks > fade->totalTicks) {
+			continue;
+		}
 
-	debugC(5, kDebugSound, "DirectorSound::fadeChannel(): fading channel %d volume to %d", soundChannel, fadeVol);
-	_mixer->setChannelVolume(_channels[soundChannel]->handle, fadeVol);
+		int fadeVol;
+		if (fade->fadeIn) {
+			fadeVol = MIN(fade->lapsedTicks * ((float)fade->targetVol / fade->totalTicks), (float)Audio::Mixer::kMaxChannelVolume);
+		} else {
+			fadeVol = MAX((fade->totalTicks - fade->lapsedTicks) * ((float)fade->startVol / fade->totalTicks), (float)0);
+		}
 
-	_channels[soundChannel]->volume = fadeVol;
+		debugC(5, kDebugSound, "DirectorSound::fadeChannel(): fading channel %d volume to %d", it._key, fadeVol);
+		_mixer->setChannelVolume(it._value->handle, fadeVol);
 
-	return true;
+		it._value->volume = fadeVol;
+		ongoing = true;
+	}
+	return ongoing;
 }
 
 void DirectorSound::cancelFade(uint8 soundChannel) {
diff --git a/engines/director/sound.h b/engines/director/sound.h
index 9c66a4aeea2..dc132273ad6 100644
--- a/engines/director/sound.h
+++ b/engines/director/sound.h
@@ -201,7 +201,7 @@ public:
 	Common::String getCurrentSound() { return _currentSoundName; }
 
 	void registerFade(uint8 soundChannel, bool fadeIn, int ticks);
-	bool fadeChannel(uint8 soundChannel);
+	bool fadeChannels();
 
 	bool isChannelActive(uint8 soundChannel);
 	uint8 getChannelVolume(uint8 soundChannel);


Commit: e2a46585e53a09fd32b4aa7114ea7782d66e4a46
    https://github.com/scummvm/scummvm/commit/e2a46585e53a09fd32b4aa7114ea7782d66e4a46
Author: Scott Percival (code at moral.net.au)
Date: 2024-03-31T16:58:31+02:00

Commit Message:
DIRECTOR: Add actions command to debugger

Changed paths:
    engines/director/debugger.cpp
    engines/director/debugger.h
    engines/director/movie.h


diff --git a/engines/director/debugger.cpp b/engines/director/debugger.cpp
index 68fddb88dde..f04c3bd6976 100644
--- a/engines/director/debugger.cpp
+++ b/engines/director/debugger.cpp
@@ -75,6 +75,8 @@ Debugger::Debugger(): GUI::Debugger() {
 	registerCmd("da", WRAP_METHOD(Debugger, cmdDisasm));
 	registerCmd("var", WRAP_METHOD(Debugger, cmdVar));
 	registerCmd("v", WRAP_METHOD(Debugger, cmdVar));
+	registerCmd("actions", WRAP_METHOD(Debugger, cmdActions));
+	registerCmd("act", WRAP_METHOD(Debugger, cmdActions));
 	registerCmd("markers", WRAP_METHOD(Debugger, cmdMarkers));
 	registerCmd("mk", WRAP_METHOD(Debugger, cmdMarkers));
 	registerCmd("step", WRAP_METHOD(Debugger, cmdStep));
@@ -168,6 +170,7 @@ bool Debugger::cmdHelp(int argc, const char **argv) {
 	debugPrintf(" stack / st - Lists the elements on the stack\n");
 	debugPrintf(" scriptframe / sf - Prints the current script frame\n");
 	debugPrintf(" funcs - Lists all of the functions available in the current script frame\n");
+	debugPrintf(" actions / act - Lists all of the action scripts available in the current score\n");
 	debugPrintf(" var / v - Lists all of the variables available in the current script frame\n");
 	debugPrintf(" markers / mk - Lists all of the frame markers in the current score\n");
 	debugPrintf(" step / s [n] - Steps forward one or more operations\n");
@@ -476,6 +479,20 @@ bool Debugger::cmdFuncs(int argc, const char **argv) {
 	return true;
 }
 
+bool Debugger::cmdActions(int argc, const char **argv) {
+	Movie *movie = g_director->getCurrentMovie();
+	Score *score = movie->getScore();
+	debugPrintf("Actions:\n");
+	for (auto &it : score->_actions) {
+		debugPrintf("  %d:\n", it._key);
+		debugPrintf("%s\n", formatStringForDump(it._value).c_str());
+	}
+	debugPrintf("D3 movie script:\n");
+	debugPrintf("%s\n", formatStringForDump(movie->_script).c_str());
+
+	return true;
+}
+
 bool Debugger::cmdBacktrace(int argc, const char **argv) {
 	Lingo *lingo = g_director->getLingo();
 	debugPrintf("%s\n", lingo->formatCallStack(lingo->_state->pc).c_str());
diff --git a/engines/director/debugger.h b/engines/director/debugger.h
index 95900f2229b..1d0771075fe 100644
--- a/engines/director/debugger.h
+++ b/engines/director/debugger.h
@@ -100,6 +100,7 @@ private:
 	bool cmdStack(int argc, const char **argv);
 	bool cmdScriptFrame(int argc, const char **argv);
 	bool cmdFuncs(int argc, const char **argv);
+	bool cmdActions(int argc, const char **argv);
 	bool cmdVar(int argc, const char **argv);
 	bool cmdMarkers(int argc, const char **argv);
 	bool cmdStep(int argc, const char **argv);
diff --git a/engines/director/movie.h b/engines/director/movie.h
index cf42210267f..f232be6ad3e 100644
--- a/engines/director/movie.h
+++ b/engines/director/movie.h
@@ -185,6 +185,8 @@ public:
 
 	bool _isBeepOn;
 
+	Common::String _script;
+
 private:
 	Window *_window;
 	DirectorEngine *_vm;
@@ -197,7 +199,6 @@ private:
 	uint32 _flags;
 
 	Common::String _macName;
-	Common::String _script;
 
 	bool _mouseDownWasInButton;
 	Channel *_currentDraggedChannel;


Commit: 403c9233420413f119088d2111a2d4cc62e901bb
    https://github.com/scummvm/scummvm/commit/403c9233420413f119088d2111a2d4cc62e901bb
Author: Scott Percival (code at moral.net.au)
Date: 2024-03-31T16:58:31+02:00

Commit Message:
DIRECTOR: XOBJ: Implement RemixXCMD from The Seven Colors

Changed paths:
    engines/director/lingo/xlibs/remixxcmd.cpp
    engines/director/lingo/xlibs/remixxcmd.h


diff --git a/engines/director/lingo/xlibs/remixxcmd.cpp b/engines/director/lingo/xlibs/remixxcmd.cpp
index 195cfcaca89..439f77e33be 100644
--- a/engines/director/lingo/xlibs/remixxcmd.cpp
+++ b/engines/director/lingo/xlibs/remixxcmd.cpp
@@ -19,13 +19,18 @@
  *
  */
 
+#include "audio/audiostream.h"
 #include "common/system.h"
 
 #include "director/director.h"
+#include "director/archive.h"
 #include "director/lingo/lingo.h"
 #include "director/lingo/lingo-object.h"
 #include "director/lingo/lingo-utils.h"
 #include "director/lingo/xlibs/remixxcmd.h"
+#include "director/sound.h"
+#include "director/types.h"
+#include "director/window.h"
 
 /**************************************************
  *
@@ -43,21 +48,249 @@ const char *RemixXCMD::fileNames[] = {
 };
 
 static BuiltinProto builtins[] = {
-	{ "Remix", RemixXCMD::m_Remix, -1, 0, 300, CBLTIN },
+	{ "Remix", RemixXCMD::m_Remix, 1, 1, 300, CBLTIN },
 	{ nullptr, nullptr, 0, 0, 0, VOIDSYM }
 };
 
+struct RemixState {
+	MacArchive *arch = nullptr;
+	Common::Array<Common::Array<int>> sequence;
+	Common::Array<SNDDecoder *> samples;
+	bool faderLeft = true;
+	bool newRecord = false;
+	int deckA = 0;
+	int deckASeqID = 0;
+	int deckASubseqID = 0;
+	int deckB = 0;
+	int deckBSeqID = 0;
+	int deckBSubseqID = 0;
+	int totalLength = 0;
+};
+
+static RemixState remixState;
+
 // Turntable minigame in The Seven Colors.
 // Uses a resource file containing samples + this XCMD to play them.
 
 void RemixXCMD::open(ObjectType type, const Common::Path &path) {
 	g_lingo->initBuiltIns(builtins);
+	if (!remixState.arch) {
+		remixState.arch = new MacArchive();
+		if (!remixState.arch->openFile(path)) {
+			warning("RemixXCMD::open: unable to open %s", path.toString().c_str());
+			delete remixState.arch;
+			remixState.arch = nullptr;
+		}
+		for (int i = 1; i <= 12; i++) {
+			Common::SeekableReadStreamEndian *snd = remixState.arch->getResource(MKTAG('s', 'n', 'd', ' '), 10000 + i);
+			if (!snd) {
+				warning("RemixXCMD::open: couldn't find sample %d", i);
+
+				continue;
+			}
+			SNDDecoder *decoder = new SNDDecoder();
+			decoder->loadStream(*snd);
+			remixState.samples.push_back(decoder);
+		}
+	}
 }
 
 void RemixXCMD::close(ObjectType type) {
 	g_lingo->cleanupBuiltIns(builtins);
+	doResetSound();
+}
+
+void RemixXCMD::endGame(bool success) {
+	Datum totalLengthRef("TotalLength");
+	totalLengthRef.type = GLOBALREF;
+	DirectorSound *sound = g_director->getCurrentWindow()->getSoundManager();
+
+	g_lingo->varAssign(totalLengthRef, success ? 100 : 200);
+	sound->stopSound(1);
+	sound->stopSound(2);
+	sound->setPuppetSound(SoundID(), 1);
+	sound->setPuppetSound(SoundID(), 2);
+	sound->setChannelVolume(1, 192);
+	sound->setChannelVolume(2, 192);
+}
+
+void RemixXCMD::doSetSound() {
+	if (!remixState.arch) {
+		warning("RemixXCMD::DoSetSound: No archive found");
+		return;
+	}
+	// load from sequ resource 10000
+	Common::SeekableReadStream *sequ = remixState.arch->getResource(MKTAG('s', 'e', 'q', 'u'), 10000);
+	if (!sequ) {
+		warning("RemixCMD::DoSetSound: sequ resource 10000 not found");
+		return;
+	}
+	remixState.sequence.clear();
+	for (int i = 0; i < 5 && !sequ->eos(); i++) {
+		int count = sequ->readByte();
+		Common::Array<int> selection;
+		debugC(5, kDebugXObj, "RemixXCMD::DoSetSound(): bank %d: ", i+1);
+		while (count > 0 && !sequ->eos()) {
+			byte id = sequ->readByte();
+			selection.push_back(id);
+			debugC(5, kDebugXObj, "%d, ", id);
+			count -= 1;
+		}
+		debugC(5, kDebugXObj, "\n");
+		remixState.sequence.push_back(selection);
+	}
+}
+
+void RemixXCMD::doResetSound() {
+	for (auto &it : remixState.samples)
+		delete it;
+	remixState.samples.clear();
+	remixState.sequence.clear();
+	if (remixState.arch) {
+		delete remixState.arch;
+		remixState.arch = nullptr;
+	}
+}
+
+void RemixXCMD::doKeySound(int bank) {
+	DirectorSound *sound = g_director->getCurrentWindow()->getSoundManager();
+	if (!bank) {
+		// hit crossfader
+		remixState.faderLeft = !remixState.faderLeft;
+		if (remixState.newRecord) {
+			// start playing the new deck
+			if (remixState.faderLeft) {
+				sound->stopSound(1);
+				remixState.deckASeqID = remixState.deckA;
+				remixState.deckASubseqID = 0;
+			} else {
+				sound->stopSound(2);
+				remixState.deckBSeqID = remixState.deckB;
+				remixState.deckBSubseqID = 0;
+			}
+			remixState.newRecord = false;
+		}
+		// lower the volume on the old deck
+		sound->setChannelVolume(remixState.faderLeft ? 1 : 2, 192);
+		sound->setChannelVolume(remixState.faderLeft ? 2 : 1, 0);
+	} else {
+		// clicked a record
+		if (remixState.faderLeft) {
+			remixState.deckB = bank;
+		} else {
+			remixState.deckA = bank;
+		}
+		remixState.newRecord = true;
+		// ReturnSwitchFlag
+		Datum switchFlagRef("SwitchFlag");
+		switchFlagRef.type = GLOBALREF;
+		g_lingo->varAssign(switchFlagRef, Datum(1));
+	}
+}
+
+void RemixXCMD::doStartSound() {
+	remixState.deckA = 1;
+	remixState.deckB = 0;
+	remixState.deckASeqID = 1;
+	remixState.deckASubseqID = 0;
+	remixState.deckBSeqID = 0;
+	remixState.deckBSubseqID = 0;
+	remixState.faderLeft = true;
+	remixState.totalLength = 0;
+	DirectorSound *sound = g_director->getCurrentWindow()->getSoundManager();
+	sound->stopSound(1);
+	sound->stopSound(2);
 }
 
-XOBJSTUB(RemixXCMD::m_Remix, 0)
+void RemixXCMD::interruptCheck() {
+	if (!remixState.arch)
+		return;
+
+	DirectorSound *sound = g_director->getCurrentWindow()->getSoundManager();
+
+	// this function gets called on every frame.
+	// both decks have music playing simultaneously, but with only one audible
+	// at the same time.
+	// if the record ends while you're crossfaded to it, you lose the minigame.
+
+	Datum totalLengthRef("TotalLength");
+	totalLengthRef.type = GLOBALREF;
+
+	if (!sound->isChannelActive(1) && remixState.deckASeqID) {
+		if (remixState.faderLeft && remixState.deckASubseqID >= (int)remixState.sequence[remixState.deckASeqID-1].size()) {
+			// record ran out, trigger failure state
+			endGame(false);
+			return;
+		}
+		int currentSample = remixState.sequence[remixState.deckASeqID-1][remixState.deckASubseqID];
+
+		debugC(5, kDebugXObj, "RemixXCMD::InterruptCheck(): deck A, bank: %d, subseq: %d, id: %d", remixState.deckASeqID, remixState.deckASubseqID, currentSample);
+		sound->setPuppetSound(SoundID(kSoundExternal, -1, -1), 1);
+		Audio::AudioStream *sample = remixState.samples[currentSample-1]->getAudioStream(0, true, DisposeAfterUse::YES);
+		sound->playStream(*sample, 1);
+		remixState.deckASubseqID += 1;
+
+		if (remixState.faderLeft) {
+			remixState.totalLength += 2;
+			g_lingo->varAssign(totalLengthRef, remixState.totalLength);
+		}
+	}
+
+	if (!sound->isChannelActive(2) && remixState.deckBSeqID) {
+		if (!remixState.faderLeft && remixState.deckBSubseqID >= (int)remixState.sequence[remixState.deckBSeqID-1].size()) {
+			// record ran out, trigger failure state
+			endGame(true);
+			return;
+		}
+		int currentSample = remixState.sequence[remixState.deckBSeqID-1][remixState.deckBSubseqID];
+
+		debugC(5, kDebugXObj, "RemixXCMD::InterruptCheck(): deck B, bank: %d, subseq: %d, id: %d", remixState.deckBSeqID, remixState.deckBSubseqID, currentSample);
+		sound->setPuppetSound(SoundID(kSoundExternal, -1, -1), 2);
+		Audio::AudioStream *sample = remixState.samples[currentSample-1]->getAudioStream(0, true, DisposeAfterUse::YES);
+		sound->playStream(*sample, 2);
+		remixState.deckBSubseqID += 1;
+
+		if (!remixState.faderLeft) {
+			remixState.totalLength += 2;
+			g_lingo->varAssign(totalLengthRef, remixState.totalLength);
+		}
+	}
+
+	// if we've been mixing for long enough, success
+	if (remixState.totalLength > 45) {
+		endGame(true);
+	}
+}
+
+void RemixXCMD::m_Remix(int nargs) {
+	g_lingo->printSTUBWithArglist("RemixXCMD::m_Remix", nargs);
+	Datum result;
+	if (nargs != 1) {
+		result = Datum("Wrong number of params");
+		g_lingo->dropStack(nargs);
+		g_lingo->push(result);
+		return;
+	}
+
+	int arg = g_lingo->pop().asInt();
+	if (arg == 0) {
+		doSetSound();
+	} else if (arg == -1) {
+		doResetSound();
+	} else if ((arg >= 1) && (arg <= 5)) {
+		doKeySound(arg);
+	} else if (arg == 6) {
+		doKeySound(0);
+	} else if (arg == 98) {
+		doStartSound();
+	} else if (arg == 99) {
+		interruptCheck();
+	} else {
+		result = Datum("Parameter must be 0-15 or 0");
+	}
+
+	g_lingo->push(result);
+	return;
+}
 
 }
diff --git a/engines/director/lingo/xlibs/remixxcmd.h b/engines/director/lingo/xlibs/remixxcmd.h
index 344bb47c431..85db8a3824e 100644
--- a/engines/director/lingo/xlibs/remixxcmd.h
+++ b/engines/director/lingo/xlibs/remixxcmd.h
@@ -32,6 +32,14 @@ extern const char *fileNames[];
 void open(ObjectType type, const Common::Path &path);
 void close(ObjectType type);
 
+void endGame(bool success);
+
+void doSetSound();
+void doResetSound();
+void doKeySound(int bank);
+void doStartSound();
+void interruptCheck();
+
 void m_Remix(int nargs);
 
 } // End of namespace RemixXCMD


Commit: 0c65e4a2e49c20decda5d5c8d2ecb1c2ccdabb52
    https://github.com/scummvm/scummvm/commit/0c65e4a2e49c20decda5d5c8d2ecb1c2ccdabb52
Author: Scott Percival (code at moral.net.au)
Date: 2024-03-31T16:58:31+02:00

Commit Message:
DIRECTOR: LINGO: Add script patch for Rodney's Fun Screen

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


diff --git a/engines/director/lingo/lingo-patcher.cpp b/engines/director/lingo/lingo-patcher.cpp
index 7f7c7a50eb7..2d3443256a7 100644
--- a/engines/director/lingo/lingo-patcher.cpp
+++ b/engines/director/lingo/lingo-patcher.cpp
@@ -125,6 +125,9 @@ struct ScriptPatch {
 	{"warlock", nullptr, kPlatformWindows, "STARBIRD:ABOUT", kScoreScript, 4, DEFAULT_CAST_LIB,
 			1, "installmenu A13", ""},
 
+	// Typo
+	{"rodneyfs", nullptr, kPlatformMacintosh, "Shared Cast", kMovieScript, 496, DEFAULT_CAST_LIB,
+			7, "if the soundLevel <> 7 then set the the soundLevel to 7", "if the soundLevel <> 7 then set the soundLevel to 7"},
 
 	// Patching dead loop which was fixed in v2
 	{"lzone", "", kPlatformMacintosh, "DATA:R-A:Ami-00", kScoreScript, 3, DEFAULT_CAST_LIB,


Commit: 8050b050f5c2486a249f274283df122254cf412d
    https://github.com/scummvm/scummvm/commit/8050b050f5c2486a249f274283df122254cf412d
Author: Scott Percival (code at moral.net.au)
Date: 2024-03-31T16:58:31+02:00

Commit Message:
DIRECTOR: Update detection tables

Changed paths:
    engines/director/detection_tables.h


diff --git a/engines/director/detection_tables.h b/engines/director/detection_tables.h
index 2fa150482d2..b3cfb18a208 100644
--- a/engines/director/detection_tables.h
+++ b/engines/director/detection_tables.h
@@ -2587,7 +2587,7 @@ static const DirectorGameDescription gameDescriptions[] = {
 	MACDEMO1_l("hypermaterial", "Demo", "Browser_Demo", "f5277c53bacd27936158dd3867e587e2", 966053, Common::JA_JPN, 311),
 
 	// Sanctuary Woods promos from Bird's Life, not present in the Win files.
-	MACGAME1("ilearn", "", "More Fun!", "2ce360c9ea2da80a2c6d1040b0ad92dd", 14007865, 313),
+	MACDEMO1("ilearn", "", "More Fun!", "2ce360c9ea2da80a2c6d1040b0ad92dd", 14007865, 313),
 
 	MACDEMO1("iliad", "", "Iliad 3.0 Demo", "cfa68a1bc49251497ebde18e5fc9c217", 270830, 200),
 
@@ -2610,11 +2610,11 @@ static const DirectorGameDescription gameDescriptions[] = {
 	// Original filename is 犬組デモ
 	MACDEMO1_l("inugumi", "Demo", "Inugumi Demo", "f5277c53bacd27936158dd3867e587e2", 2366437, Common::JA_JPN, 311),
 
-	MACGAME1("ipc", "", "About InterActive Publishing", "ec7aaa66647e526d72cb1c1d802df48b", 3056270, 313),
-	WINGAME1("ipc", "", "ABOUTIPC.EXE", "65d06b5fef155a2473434571aff5bc29", 4270544, 310),
+	MACDEMO1("ipc", "", "About InterActive Publishing", "ec7aaa66647e526d72cb1c1d802df48b", 3056270, 313),
+	WINDEMO1("ipc", "", "ABOUTIPC.EXE", "65d06b5fef155a2473434571aff5bc29", 4270544, 310),
 	// From Supersonic: A Multimedia Guide to Modern Military Aircraft
-	MACGAME1("ipc", "", "About InterActive Publishing", "ec7aaa66647e526d72cb1c1d802df48b", 3033242, 313),
-	WINGAME1("ipc", "", "ABOUTIPC.EXE", "4e6303630f4dd588e730d09241cf7e76", 3275100, 310),
+	MACDEMO1("ipc", "", "About InterActive Publishing", "ec7aaa66647e526d72cb1c1d802df48b", 3033242, 313),
+	WINDEMO1("ipc", "", "ABOUTIPC.EXE", "4e6303630f4dd588e730d09241cf7e76", 3275100, 310),
 
 	// Bilingual English/Spanish
 	// Uses audio tracks
@@ -3202,7 +3202,7 @@ static const DirectorGameDescription gameDescriptions[] = {
 	// American release, French version
 	MACGAME1_l("wallobee", "American rerelease", "Bingi Burra", "2ce360c9ea2da80a2c6d1040b0ad92dd", 384688, Common::FR_FRA, 313),
 
-	MACGAME1("wallobee2", "", "Thai Sun", "2ce360c9ea2da80a2c6d1040b0ad92dd", 384678, 313),
+	MACGAME1("wallobee2", "", "THAI SUN ENGLISH/Thai Sun", "2ce360c9ea2da80a2c6d1040b0ad92dd", 384678, 313),
 
 	WINDEMO1("wep", "Demo", "WEP.EXE", "2b3543a9131a49f665982d26513a84f8", 1796465, 310),
 


Commit: d285d1a9d564070fe867c2de89580d23afa98546
    https://github.com/scummvm/scummvm/commit/d285d1a9d564070fe867c2de89580d23afa98546
Author: Scott Percival (code at moral.net.au)
Date: 2024-03-31T16:58:31+02:00

Commit Message:
DIRECTOR: Add guardrail for empty film loops

Changed paths:
    engines/director/channel.cpp


diff --git a/engines/director/channel.cpp b/engines/director/channel.cpp
index 6dcd545d93f..021d82d9640 100644
--- a/engines/director/channel.cpp
+++ b/engines/director/channel.cpp
@@ -410,9 +410,14 @@ void Channel::setClean(Sprite *nextSprite, bool partial) {
 		// if the next sprite in the channel shares the cast member
 		if (nextSprite->_cast && _sprite->_castId == nextSprite->_castId) {
 			if (nextSprite->_cast->_type == kCastFilmLoop) {
-				// increment the film loop counter
-				_filmLoopFrame += 1;
-				_filmLoopFrame %= ((FilmLoopCastMember *)nextSprite->_cast)->_frames.size();
+				FilmLoopCastMember *fl = ((FilmLoopCastMember *)nextSprite->_cast);
+				if (!fl->_frames.empty()) {
+					// increment the film loop counter
+					_filmLoopFrame += 1;
+					_filmLoopFrame %= ((FilmLoopCastMember *)nextSprite->_cast)->_frames.size();
+				} else {
+					warning("Channel::setClean(): invalid film loop in castId %s", nextSprite->_castId.asString().c_str());
+				}
 			}
 		}
 


Commit: f3bdc30464ad235edde3597ddc74a890841982e0
    https://github.com/scummvm/scummvm/commit/f3bdc30464ad235edde3597ddc74a890841982e0
Author: Scott Percival (code at moral.net.au)
Date: 2024-03-31T16:58:31+02:00

Commit Message:
DIRECTOR: Prevent negative rect dimensions in transition code

Changed paths:
    engines/director/transitions.cpp


diff --git a/engines/director/transitions.cpp b/engines/director/transitions.cpp
index ed56796f6b7..dbc0556c18c 100644
--- a/engines/director/transitions.cpp
+++ b/engines/director/transitions.cpp
@@ -292,65 +292,65 @@ void Window::playTransition(uint frame, RenderMode mode, uint16 transDuration, u
 
 		switch (t.type) {
 		case kTransWipeRight:								// 1
-			rto.setWidth(t.xStepSize * i);
+			rto.setWidth(MAX((int16)0, (int16)(t.xStepSize * i)));
 			rfrom = rto;
 			break;
 
 		case kTransWipeLeft:								// 2
-			rto.setWidth(t.xStepSize * i);
+			rto.setWidth(MAX((int16)0, (int16)(t.xStepSize * i)));
 			rto.translate(w - t.xStepSize * i, 0);
 			rfrom = rto;
 			break;
 
 		case kTransWipeDown:								// 3
-			rto.setHeight(t.yStepSize * i);
+			rto.setHeight(MAX((int16)0, (int16)(t.yStepSize * i)));
 			rfrom = rto;
 			break;
 
 		case kTransWipeUp:									// 4
-			rto.setHeight(t.yStepSize * i);
+			rto.setHeight(MAX((int16)0, (int16)(t.yStepSize * i)));
 			rto.translate(0, h - t.yStepSize * i);
 			rfrom = rto;
 			break;
 
 		case kTransCenterOutHorizontal:						// 5
 			t.xpos += t.xStepSize;
-			rto.setWidth(t.xpos * 2);
+			rto.setWidth(MAX((int16)0, (int16)(t.xpos * 2)));
 			rto.translate(w / 2 - t.xpos, 0);
 			rfrom = rto;
 			break;
 
 		case kTransEdgesInHorizontal:						// 6
-			rto.setWidth(w - t.xStepSize * i * 2);
+			rto.setWidth(MAX((int16)0, (int16)(w - t.xStepSize * i * 2)));
 			rto.translate(t.xStepSize * i, 0);
 			rfrom = rto;
 			break;
 
 		case kTransCenterOutVertical:						// 7
 			t.ypos += t.yStepSize;
-			rto.setHeight(t.ypos * 2);
+			rto.setHeight(MAX((int16)0, (int16)(t.ypos * 2)));
 			rto.translate(0, h / 2 - t.ypos);
 			rfrom = rto;
 			break;
 
 		case kTransEdgesInVertical:							// 8
-			rto.setHeight(h - t.yStepSize * i * 2);
+			rto.setHeight(MAX((int16)0, (int16)(h - t.yStepSize * i * 2)));
 			rto.translate(0, t.yStepSize * i);
 			rfrom = rto;
 			break;
 
 		case kTransCenterOutSquare: 						// 9
 			t.ypos += t.yStepSize;
-			rto.setHeight(t.ypos * 2);
+			rto.setHeight(MAX((int16)0, (int16)(t.ypos * 2)));
 			t.xpos += t.xStepSize;
-			rto.setWidth(t.xpos * 2);
+			rto.setWidth(MAX((int16)0, (int16)(t.xpos * 2)));
 			rto.translate(w / 2 - t.xpos, h / 2 - t.ypos);
 			rfrom = rto;
 			break;
 
 		case kTransEdgesInSquare:							// 10
-			rto.setHeight(h - t.yStepSize * i * 2);
-			rto.setWidth(w - t.xStepSize * i * 2);
+			rto.setHeight(MAX((int16)0, (int16)(h - t.yStepSize * i * 2)));
+			rto.setWidth(MAX((int16)0, (int16)(w - t.xStepSize * i * 2)));
 			rto.moveTo(t.xStepSize * i, t.yStepSize * i);
 			rfrom = rto;
 			break;
@@ -362,30 +362,30 @@ void Window::playTransition(uint frame, RenderMode mode, uint16 transDuration, u
 			_composeSurface->blitFrom(nextFrame, rfrom, Common::Point(rto.left, rto.top));
 
 			rfrom.translate(t.xStepSize * i, 0);
-			rfrom.setWidth(w - t.xStepSize * i);
+			rfrom.setWidth(MAX((int16)0, (int16)(w - t.xStepSize * i)));
 			rto.moveTo(clipRect.left, clipRect.top);
 			break;
 
 		case kTransPushRight:								// 12
 			rfrom.translate(w - t.xStepSize * i, 0);
-			rfrom.setWidth(t.xStepSize * i);
+			rfrom.setWidth(MAX((int16)0, (int16)(t.xStepSize * i)));
 			_composeSurface->blitFrom(nextFrame, rfrom, Common::Point(rto.left, rto.top));
 
-			rto.setWidth(w - t.xStepSize * i);
+			rto.setWidth(MAX((int16)0, (int16)(w - t.xStepSize * i)));
 			rto.translate(t.xStepSize * i, 0);
 			rfrom.moveTo(clipRect.left, clipRect.top);
-			rfrom.setWidth(w - t.xStepSize * i);
+			rfrom.setWidth(MAX((int16)0, (int16)(w - t.xStepSize * i)));
 			break;
 
 		case kTransPushDown:								// 13
 			rfrom.translate(0, h - t.yStepSize * i);
-			rfrom.setHeight(t.yStepSize * i);
+			rfrom.setHeight(MAX((int16)0, (int16)(t.yStepSize * i)));
 			_composeSurface->blitFrom(nextFrame, rfrom, Common::Point(rto.left, rto.top));
 
-			rto.setHeight(h - t.yStepSize * i);
+			rto.setHeight(MAX((int16)0, (int16)(h - t.yStepSize * i)));
 			rto.translate(0, t.yStepSize * i);
 			rfrom.moveTo(clipRect.left, clipRect.top);
-			rfrom.setHeight(h - t.yStepSize * i);
+			rfrom.setHeight(MAX((int16)0, (int16)(h - t.yStepSize * i)));
 			break;
 
 		case kTransPushUp:									// 14
@@ -395,7 +395,7 @@ void Window::playTransition(uint frame, RenderMode mode, uint16 transDuration, u
 			_composeSurface->blitFrom(nextFrame, rfrom, Common::Point(rto.left, rto.top));
 
 			rfrom.translate(0, t.yStepSize * i);
-			rfrom.setHeight(h - t.yStepSize * i);
+			rfrom.setHeight(MAX((int16)0, (int16)(h - t.yStepSize * i)));
 			rto.moveTo(clipRect.left, clipRect.top);
 			break;
 


Commit: f5b2c47614cf271c74937f9120435442eedb5b50
    https://github.com/scummvm/scummvm/commit/f5b2c47614cf271c74937f9120435442eedb5b50
Author: Scott Percival (code at moral.net.au)
Date: 2024-03-31T16:58:31+02:00

Commit Message:
DIRECTOR: XOBJ: Refactor RemixXCMD to have proper memory management

Changed paths:
    engines/director/lingo/lingo.cpp
    engines/director/lingo/lingo.h
    engines/director/lingo/xlibs/remixxcmd.cpp
    engines/director/lingo/xlibs/remixxcmd.h


diff --git a/engines/director/lingo/lingo.cpp b/engines/director/lingo/lingo.cpp
index 4656119fd44..f8f69110e14 100644
--- a/engines/director/lingo/lingo.cpp
+++ b/engines/director/lingo/lingo.cpp
@@ -222,6 +222,9 @@ Lingo::~Lingo() {
 	cleanupFuncs();
 	cleanupMethods();
 	delete _compiler;
+	for (auto &it : _openXLibsState) {
+		delete it._value;
+	}
 }
 
 void Lingo::reloadBuiltIns() {
diff --git a/engines/director/lingo/lingo.h b/engines/director/lingo/lingo.h
index cd6f7f47b5e..64c0700369a 100644
--- a/engines/director/lingo/lingo.h
+++ b/engines/director/lingo/lingo.h
@@ -240,6 +240,7 @@ typedef void (*XLibCloserFunc)(ObjectType);
 typedef Common::HashMap<Common::String, XLibOpenerFunc, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> XLibOpenerFuncHash;
 typedef Common::HashMap<Common::String, XLibCloserFunc, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> XLibCloserFuncHash;
 typedef Common::HashMap<Common::String, ObjectType, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> OpenXLibsHash;
+typedef Common::HashMap<Common::String, AbstractObject *, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> OpenXLibsStateHash;
 
 typedef Common::HashMap<Common::String, TheEntity *, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> TheEntityHash;
 typedef Common::HashMap<Common::String, TheEntityField *, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> TheEntityFieldHash;
@@ -495,6 +496,7 @@ public:
 	XLibCloserFuncHash _xlibClosers;
 
 	OpenXLibsHash _openXLibs;
+	OpenXLibsStateHash _openXLibsState;
 
 	Common::String _floatPrecisionFormat;
 
diff --git a/engines/director/lingo/xlibs/remixxcmd.cpp b/engines/director/lingo/xlibs/remixxcmd.cpp
index 439f77e33be..21e51e112fd 100644
--- a/engines/director/lingo/xlibs/remixxcmd.cpp
+++ b/engines/director/lingo/xlibs/remixxcmd.cpp
@@ -52,7 +52,17 @@ static BuiltinProto builtins[] = {
 	{ nullptr, nullptr, 0, 0, 0, VOIDSYM }
 };
 
-struct RemixState {
+class RemixXCMDState : public Object<RemixXCMDState> {
+public:
+	RemixXCMDState(const Common::Path &path);
+	~RemixXCMDState();
+
+	void endGame(bool success);
+	void doSetSound();
+	void doKeySound(int bank);
+	void doStartSound();
+	void interruptCheck();
+
 	MacArchive *arch = nullptr;
 	Common::Array<Common::Array<int>> sequence;
 	Common::Array<SNDDecoder *> samples;
@@ -67,40 +77,63 @@ struct RemixState {
 	int totalLength = 0;
 };
 
-static RemixState remixState;
+RemixXCMDState::RemixXCMDState(const Common::Path &path) : Object<RemixXCMDState>("Remix") {
+	arch = new MacArchive();
+	if (!arch->openFile(path)) {
+		warning("RemixXCMDState: unable to open %s", path.toString().c_str());
+		delete arch;
+		arch = nullptr;
+	}
+	for (int i = 1; i <= 12; i++) {
+		if (!arch)
+			continue;
+		Common::SeekableReadStreamEndian *snd = arch->getResource(MKTAG('s', 'n', 'd', ' '), 10000 + i);
+		if (!snd) {
+			warning("RemixXCMDState: couldn't find sample %d", i);
+
+			continue;
+		}
+		SNDDecoder *decoder = new SNDDecoder();
+		decoder->loadStream(*snd);
+		samples.push_back(decoder);
+		delete snd;
+	}
+}
+
+
+RemixXCMDState::~RemixXCMDState() {
+	for (auto &it : samples)
+		delete it;
+	samples.clear();
+	sequence.clear();
+	if (arch) {
+		delete arch;
+	}
+}
 
 // Turntable minigame in The Seven Colors.
 // Uses a resource file containing samples + this XCMD to play them.
 
 void RemixXCMD::open(ObjectType type, const Common::Path &path) {
 	g_lingo->initBuiltIns(builtins);
-	if (!remixState.arch) {
-		remixState.arch = new MacArchive();
-		if (!remixState.arch->openFile(path)) {
-			warning("RemixXCMD::open: unable to open %s", path.toString().c_str());
-			delete remixState.arch;
-			remixState.arch = nullptr;
-		}
-		for (int i = 1; i <= 12; i++) {
-			Common::SeekableReadStreamEndian *snd = remixState.arch->getResource(MKTAG('s', 'n', 'd', ' '), 10000 + i);
-			if (!snd) {
-				warning("RemixXCMD::open: couldn't find sample %d", i);
 
-				continue;
-			}
-			SNDDecoder *decoder = new SNDDecoder();
-			decoder->loadStream(*snd);
-			remixState.samples.push_back(decoder);
-		}
+	if (!g_lingo->_openXLibsState.contains("Remix")) {
+		RemixXCMDState *remixState = new RemixXCMDState(path);
+		g_lingo->_openXLibsState.setVal("Remix", remixState);
 	}
+
 }
 
 void RemixXCMD::close(ObjectType type) {
 	g_lingo->cleanupBuiltIns(builtins);
-	doResetSound();
+	if (g_lingo->_openXLibsState.contains("Remix")) {
+		AbstractObject *remixState = g_lingo->_openXLibsState.getVal("Remix");
+		delete remixState;
+		g_lingo->_openXLibsState.erase("Remix");
+	}
 }
 
-void RemixXCMD::endGame(bool success) {
+void RemixXCMDState::endGame(bool success) {
 	Datum totalLengthRef("TotalLength");
 	totalLengthRef.type = GLOBALREF;
 	DirectorSound *sound = g_director->getCurrentWindow()->getSoundManager();
@@ -114,22 +147,23 @@ void RemixXCMD::endGame(bool success) {
 	sound->setChannelVolume(2, 192);
 }
 
-void RemixXCMD::doSetSound() {
-	if (!remixState.arch) {
-		warning("RemixXCMD::DoSetSound: No archive found");
+
+void RemixXCMDState::doSetSound() {
+	if (!arch) {
+		warning("RemixXCMDState::DoSetSound: No archive found");
 		return;
 	}
 	// load from sequ resource 10000
-	Common::SeekableReadStream *sequ = remixState.arch->getResource(MKTAG('s', 'e', 'q', 'u'), 10000);
+	Common::SeekableReadStream *sequ = arch->getResource(MKTAG('s', 'e', 'q', 'u'), 10000);
 	if (!sequ) {
-		warning("RemixCMD::DoSetSound: sequ resource 10000 not found");
+		warning("RemixCMDState::DoSetSound: sequ resource 10000 not found");
 		return;
 	}
-	remixState.sequence.clear();
+	sequence.clear();
 	for (int i = 0; i < 5 && !sequ->eos(); i++) {
 		int count = sequ->readByte();
 		Common::Array<int> selection;
-		debugC(5, kDebugXObj, "RemixXCMD::DoSetSound(): bank %d: ", i+1);
+		debugC(5, kDebugXObj, "RemixXCMDState::DoSetSound(): bank %d: ", i+1);
 		while (count > 0 && !sequ->eos()) {
 			byte id = sequ->readByte();
 			selection.push_back(id);
@@ -137,50 +171,41 @@ void RemixXCMD::doSetSound() {
 			count -= 1;
 		}
 		debugC(5, kDebugXObj, "\n");
-		remixState.sequence.push_back(selection);
+		sequence.push_back(selection);
 	}
+	delete sequ;
 }
 
-void RemixXCMD::doResetSound() {
-	for (auto &it : remixState.samples)
-		delete it;
-	remixState.samples.clear();
-	remixState.sequence.clear();
-	if (remixState.arch) {
-		delete remixState.arch;
-		remixState.arch = nullptr;
-	}
-}
 
-void RemixXCMD::doKeySound(int bank) {
+void RemixXCMDState::doKeySound(int bank) {
 	DirectorSound *sound = g_director->getCurrentWindow()->getSoundManager();
 	if (!bank) {
 		// hit crossfader
-		remixState.faderLeft = !remixState.faderLeft;
-		if (remixState.newRecord) {
+		faderLeft = !faderLeft;
+		if (newRecord) {
 			// start playing the new deck
-			if (remixState.faderLeft) {
+			if (faderLeft) {
 				sound->stopSound(1);
-				remixState.deckASeqID = remixState.deckA;
-				remixState.deckASubseqID = 0;
+				deckASeqID = deckA;
+				deckASubseqID = 0;
 			} else {
 				sound->stopSound(2);
-				remixState.deckBSeqID = remixState.deckB;
-				remixState.deckBSubseqID = 0;
+				deckBSeqID = deckB;
+				deckBSubseqID = 0;
 			}
-			remixState.newRecord = false;
+			newRecord = false;
 		}
 		// lower the volume on the old deck
-		sound->setChannelVolume(remixState.faderLeft ? 1 : 2, 192);
-		sound->setChannelVolume(remixState.faderLeft ? 2 : 1, 0);
+		sound->setChannelVolume(faderLeft ? 1 : 2, 192);
+		sound->setChannelVolume(faderLeft ? 2 : 1, 0);
 	} else {
 		// clicked a record
-		if (remixState.faderLeft) {
-			remixState.deckB = bank;
+		if (faderLeft) {
+			deckB = bank;
 		} else {
-			remixState.deckA = bank;
+			deckA = bank;
 		}
-		remixState.newRecord = true;
+		newRecord = true;
 		// ReturnSwitchFlag
 		Datum switchFlagRef("SwitchFlag");
 		switchFlagRef.type = GLOBALREF;
@@ -188,22 +213,22 @@ void RemixXCMD::doKeySound(int bank) {
 	}
 }
 
-void RemixXCMD::doStartSound() {
-	remixState.deckA = 1;
-	remixState.deckB = 0;
-	remixState.deckASeqID = 1;
-	remixState.deckASubseqID = 0;
-	remixState.deckBSeqID = 0;
-	remixState.deckBSubseqID = 0;
-	remixState.faderLeft = true;
-	remixState.totalLength = 0;
+void RemixXCMDState::doStartSound() {
+	deckA = 1;
+	deckB = 0;
+	deckASeqID = 1;
+	deckASubseqID = 0;
+	deckBSeqID = 0;
+	deckBSubseqID = 0;
+	faderLeft = true;
+	totalLength = 0;
 	DirectorSound *sound = g_director->getCurrentWindow()->getSoundManager();
 	sound->stopSound(1);
 	sound->stopSound(2);
 }
 
-void RemixXCMD::interruptCheck() {
-	if (!remixState.arch)
+void RemixXCMDState::interruptCheck() {
+	if (!arch)
 		return;
 
 	DirectorSound *sound = g_director->getCurrentWindow()->getSoundManager();
@@ -216,48 +241,52 @@ void RemixXCMD::interruptCheck() {
 	Datum totalLengthRef("TotalLength");
 	totalLengthRef.type = GLOBALREF;
 
-	if (!sound->isChannelActive(1) && remixState.deckASeqID) {
-		if (remixState.faderLeft && remixState.deckASubseqID >= (int)remixState.sequence[remixState.deckASeqID-1].size()) {
+	if (!sound->isChannelActive(1) && deckASeqID) {
+		if (faderLeft && deckASubseqID >= (int)sequence[deckASeqID-1].size()) {
 			// record ran out, trigger failure state
 			endGame(false);
 			return;
 		}
-		int currentSample = remixState.sequence[remixState.deckASeqID-1][remixState.deckASubseqID];
-
-		debugC(5, kDebugXObj, "RemixXCMD::InterruptCheck(): deck A, bank: %d, subseq: %d, id: %d", remixState.deckASeqID, remixState.deckASubseqID, currentSample);
-		sound->setPuppetSound(SoundID(kSoundExternal, -1, -1), 1);
-		Audio::AudioStream *sample = remixState.samples[currentSample-1]->getAudioStream(0, true, DisposeAfterUse::YES);
-		sound->playStream(*sample, 1);
-		remixState.deckASubseqID += 1;
-
-		if (remixState.faderLeft) {
-			remixState.totalLength += 2;
-			g_lingo->varAssign(totalLengthRef, remixState.totalLength);
+		if (deckASubseqID < (int)sequence[deckASeqID-1].size()) {
+			int currentSample = sequence[deckASeqID-1][deckASubseqID];
+
+			debugC(5, kDebugXObj, "RemixXCMDState::InterruptCheck(): deck A, bank: %d, subseq: %d, id: %d", deckASeqID, deckASubseqID, currentSample);
+			sound->setPuppetSound(SoundID(kSoundExternal, -1, -1), 1);
+			Audio::AudioStream *sample = samples[currentSample-1]->getAudioStream(0, true, DisposeAfterUse::YES);
+			sound->playStream(*sample, 1);
+			deckASubseqID += 1;
+
+			if (faderLeft) {
+				totalLength += 2;
+				g_lingo->varAssign(totalLengthRef, totalLength);
+			}
 		}
 	}
 
-	if (!sound->isChannelActive(2) && remixState.deckBSeqID) {
-		if (!remixState.faderLeft && remixState.deckBSubseqID >= (int)remixState.sequence[remixState.deckBSeqID-1].size()) {
+	if (!sound->isChannelActive(2) && deckBSeqID) {
+		if (!faderLeft && deckBSubseqID >= (int)sequence[deckBSeqID-1].size()) {
 			// record ran out, trigger failure state
-			endGame(true);
+			endGame(false);
 			return;
 		}
-		int currentSample = remixState.sequence[remixState.deckBSeqID-1][remixState.deckBSubseqID];
-
-		debugC(5, kDebugXObj, "RemixXCMD::InterruptCheck(): deck B, bank: %d, subseq: %d, id: %d", remixState.deckBSeqID, remixState.deckBSubseqID, currentSample);
-		sound->setPuppetSound(SoundID(kSoundExternal, -1, -1), 2);
-		Audio::AudioStream *sample = remixState.samples[currentSample-1]->getAudioStream(0, true, DisposeAfterUse::YES);
-		sound->playStream(*sample, 2);
-		remixState.deckBSubseqID += 1;
-
-		if (!remixState.faderLeft) {
-			remixState.totalLength += 2;
-			g_lingo->varAssign(totalLengthRef, remixState.totalLength);
+		if (deckASubseqID < (int)sequence[deckBSeqID-1].size()) {
+			int currentSample = sequence[deckBSeqID-1][deckBSubseqID];
+
+			debugC(5, kDebugXObj, "RemixXCMDState::InterruptCheck(): deck B, bank: %d, subseq: %d, id: %d", deckBSeqID, deckBSubseqID, currentSample);
+			sound->setPuppetSound(SoundID(kSoundExternal, -1, -1), 2);
+			Audio::AudioStream *sample = samples[currentSample-1]->getAudioStream(0, true, DisposeAfterUse::YES);
+			sound->playStream(*sample, 2);
+			deckBSubseqID += 1;
+
+			if (!faderLeft) {
+				totalLength += 2;
+				g_lingo->varAssign(totalLengthRef, totalLength);
+			}
 		}
 	}
 
 	// if we've been mixing for long enough, success
-	if (remixState.totalLength > 45) {
+	if (totalLength > 45) {
 		endGame(true);
 	}
 }
@@ -272,19 +301,25 @@ void RemixXCMD::m_Remix(int nargs) {
 		return;
 	}
 
+	if (!g_lingo->_openXLibsState.contains("Remix")) {
+		warning("RemixXCMD::m_Remix: Missing state");
+		return;
+	}
+	RemixXCMDState *state = (RemixXCMDState *)g_lingo->_openXLibsState.getVal("Remix");
+
 	int arg = g_lingo->pop().asInt();
 	if (arg == 0) {
-		doSetSound();
+		state->doSetSound();
 	} else if (arg == -1) {
-		doResetSound();
+		// handled by destructor
 	} else if ((arg >= 1) && (arg <= 5)) {
-		doKeySound(arg);
+		state->doKeySound(arg);
 	} else if (arg == 6) {
-		doKeySound(0);
+		state->doKeySound(0);
 	} else if (arg == 98) {
-		doStartSound();
+		state->doStartSound();
 	} else if (arg == 99) {
-		interruptCheck();
+		state->interruptCheck();
 	} else {
 		result = Datum("Parameter must be 0-15 or 0");
 	}
diff --git a/engines/director/lingo/xlibs/remixxcmd.h b/engines/director/lingo/xlibs/remixxcmd.h
index 85db8a3824e..344bb47c431 100644
--- a/engines/director/lingo/xlibs/remixxcmd.h
+++ b/engines/director/lingo/xlibs/remixxcmd.h
@@ -32,14 +32,6 @@ extern const char *fileNames[];
 void open(ObjectType type, const Common::Path &path);
 void close(ObjectType type);
 
-void endGame(bool success);
-
-void doSetSound();
-void doResetSound();
-void doKeySound(int bank);
-void doStartSound();
-void interruptCheck();
-
 void m_Remix(int nargs);
 
 } // End of namespace RemixXCMD




More information about the Scummvm-git-logs mailing list