[Scummvm-git-logs] scummvm master -> 747a1bad2945761f107d397f3d6b7df3c2a59c7d

sev- noreply at scummvm.org
Thu Jan 11 19:41:51 UTC 2024


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

Summary:
716bd7e6bf DIRECTOR: LINGO: XOBJ: Add video player stubs for BatQT
c2f9829783 DIRECTOR: Fix chan/mk debugger commands
bfac83547e DIRECTOR: Fix linebreak format for the labelList
94bd08a4dd DIRECTOR: Change assert to no-op when queueing events
ed97e05a1d DEVTOOLS: Refactor director-generate-xobj-stub to allow multiple formats
9597e77dab DEVTOOLS: Add include statement injection to director-generate-xobj-stub
eeedb676ed DIRECTOR: LINGO: XOBJ: Add stubs for XCMDGlue
a83d40a575 DIRECTOR: LINGO: XOBJ: Fix m_new boilerplate
bdb30a3cc1 DEVTOOLS: Add XFCN/XCMD support to director-generate-xobj-stub
747a1bad29 DIRECTOR: LINGO: XCMD: Add stubs missing for Puppet Motel


Commit: 716bd7e6bf3516880c7a3632fc8f8a8a67933d00
    https://github.com/scummvm/scummvm/commit/716bd7e6bf3516880c7a3632fc8f8a8a67933d00
Author: Scott Percival (code at moral.net.au)
Date: 2024-01-11T20:41:43+01:00

Commit Message:
DIRECTOR: LINGO: XOBJ: Add video player stubs for BatQT

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


diff --git a/engines/director/lingo/xlibs/batqt.cpp b/engines/director/lingo/xlibs/batqt.cpp
index c2b440194b5..373b9edeb30 100644
--- a/engines/director/lingo/xlibs/batqt.cpp
+++ b/engines/director/lingo/xlibs/batqt.cpp
@@ -53,7 +53,9 @@
  * XS     mSetBatch               -- Applies a set of batch commands
  */
 
+#include "video/qt_decoder.h"
 #include "director/director.h"
+#include "director/util.h"
 #include "director/lingo/lingo.h"
 #include "director/lingo/lingo-object.h"
 #include "director/lingo/lingo-utils.h"
@@ -112,27 +114,165 @@ void BatQT::close(int type) {
 
 BatQTXObject::BatQTXObject(ObjectType ObjectType) : Object<BatQTXObject>("BatQt") {
 	_objType = ObjectType;
+	_video = nullptr;
+}
+
+BatQTXObject::~BatQTXObject() {
+	if (_video) {
+		delete _video;
+		_video = nullptr;
+	}
 }
 
 void BatQT::m_new(int nargs) {
 	g_lingo->push(g_lingo->_state->me);
 }
 
-XOBJSTUBNR(BatQT::m_dispose)
+void BatQT::m_dispose(int nargs) {
+	debug(5, "BatQT::m_dispose");
+	BatQTXObject *me = static_cast<BatQTXObject *>(g_lingo->_state->me.u.obj);
+	if (me->_video) {
+		delete me->_video;
+		me->_video = nullptr;
+	}
+}
+
 XOBJSTUB(BatQT::m_name, "")
 XOBJSTUB(BatQT::m_status, 0)
 XOBJSTUB(BatQT::m_error, "")
 XOBJSTUB(BatQT::m_lastError, "")
-XOBJSTUB(BatQT::m_open, 0)
-XOBJSTUB(BatQT::m_play, 0)
-XOBJSTUB(BatQT::m_stop, 0)
+
+void BatQT::m_open(int nargs) {
+	ARGNUMCHECK(2);
+	Datum unk = g_lingo->pop();
+	Datum path = g_lingo->pop();
+	TYPECHECK(path, STRING);
+	BatQTXObject *me = static_cast<BatQTXObject *>(g_lingo->_state->me.u.obj);
+	Common::Path normPath = findPath(path.asString());
+	if (!normPath.empty()) {
+		me->_video = new Video::QuickTimeDecoder();
+		debugC(5, kDebugXObj, "BatQT::m_open: Loading QT file %s", normPath.toString().c_str());
+		if (me->_video->loadFile(normPath)) {
+			me->_movieBox = Common::Rect(me->_video->getWidth(), me->_video->getHeight());
+			 if (g_director->_pixelformat.bytesPerPixel == 1) {
+				// Director supports playing back RGB and paletted video in 256 colour mode.
+				// In both cases they are dithered to match the Director palette.
+				byte palette[256 * 3];
+				g_system->getPaletteManager()->grabPalette(palette, 0, 256);
+				me->_video->setDitheringPalette(palette);
+			 }
+		} else {
+			warning("BatQT::m_open: Could not load QT file %s", normPath.toString().c_str());
+		}
+	} else {
+		warning("BatQT::m_open: Could not resolve path %s", path.asString().c_str());
+	}
+	g_lingo->push(0);
+}
+
+void BatQT::m_play(int nargs) {
+	ARGNUMCHECK(3);
+	Datum unk3 = g_lingo->pop();
+	Datum unk2 = g_lingo->pop();
+	Datum unk1 = g_lingo->pop();
+	TYPECHECK(unk1, INT);
+	TYPECHECK(unk2, INT);
+	TYPECHECK(unk3, STRING);
+	BatQTXObject *me = static_cast<BatQTXObject *>(g_lingo->_state->me.u.obj);
+	if (me->_video) {
+		debugC(5, kDebugXObj, "BatQT::m_play: Starting playback");
+		me->_video->start();
+	} else {
+		warning("BatQT::m_play: No video loaded");
+	}
+	g_lingo->push(0);
+}
+
+void BatQT::m_stop(int nargs) {
+	ARGNUMCHECK(0);
+	BatQTXObject *me = static_cast<BatQTXObject *>(g_lingo->_state->me.u.obj);
+	if (me->_video) {
+		debugC(5, kDebugXObj, "BatQT::m_stop: Stopping playback");
+		me->_video->stop();
+	} else {
+		warning("BatQT::m_stop: No video loaded");
+	}
+	g_lingo->push(0);
+}
+
 XOBJSTUB(BatQT::m_getTimeRange, "")
-XOBJSTUB(BatQT::m_getMovieBox, "0,0,320,240")
-XOBJSTUB(BatQT::m_getTime, 0)
+
+void BatQT::m_getMovieBox(int nargs) {
+	BatQTXObject *me = static_cast<BatQTXObject *>(g_lingo->_state->me.u.obj);
+	Common::String result = Common::String::format(
+		"%d,%d,%d,%d",
+		me->_movieBox.left,
+		me->_movieBox.top,
+		me->_movieBox.width(),
+		me->_movieBox.height()
+	);
+	debugC(5, kDebugXObj, "BatQT::m_getMovieBox: %s", result.c_str());
+	g_lingo->push(result);
+}
+
+void BatQT::m_getTime(int nargs) {
+	ARGNUMCHECK(0);
+	BatQTXObject *me = static_cast<BatQTXObject *>(g_lingo->_state->me.u.obj);
+	Datum result(0);
+	if (me->_video) {
+		// Game uses a polling loop of m_getTime to measure progress,
+		// therefore we need to render the frames in here
+		if (me->_video->needsUpdate()) {
+			const Graphics::Surface *frame = me->_video->decodeNextFrame();
+			if (frame) {
+				Graphics::Surface *temp = frame->scale(me->_movieBox.width(), me->_movieBox.height(), false);
+				g_system->copyRectToScreen(temp->getPixels(), temp->pitch, me->_movieBox.left, me->_movieBox.top, temp->w, temp->h);
+				g_system->updateScreen();
+				delete temp;
+			}
+		}
+		result = Datum(me->_video->getCurFrame() + 1);
+		debugC(5, kDebugXObj, "BatQT::m_getTime: %d", result.asInt());
+	} else {
+		warning("BatQT::m_getTime: No video loaded");
+	}
+	g_lingo->push(result);
+}
+
 XOBJSTUB(BatQT::m_setTime, "")
 XOBJSTUB(BatQT::m_setVolume, "")
-XOBJSTUB(BatQT::m_length, 0)
-XOBJSTUB(BatQT::m_setMovieBox, 0)
+
+void BatQT::m_length(int nargs) {
+	ARGNUMCHECK(0);
+	BatQTXObject *me = static_cast<BatQTXObject *>(g_lingo->_state->me.u.obj);
+	Datum result(0);
+	if (me->_video) {
+		result = Datum((int)me->_video->getFrameCount());
+		debugC(5, kDebugXObj, "BatQT::m_length: %d", result.asInt());
+	}
+	g_lingo->push(result);
+}
+
+void BatQT::m_setMovieBox(int nargs) {
+	ARGNUMCHECK(4);
+	Datum h = g_lingo->pop();
+	Datum w = g_lingo->pop();
+	Datum y = g_lingo->pop();
+	Datum x = g_lingo->pop();
+	TYPECHECK(h, INT);
+	TYPECHECK(w, INT);
+	TYPECHECK(y, INT);
+	TYPECHECK(x, INT);
+
+	BatQTXObject *me = static_cast<BatQTXObject *>(g_lingo->_state->me.u.obj);
+	me->_movieBox.left = x.asInt();
+	me->_movieBox.top = y.asInt();
+	me->_movieBox.setWidth(w.asInt());
+	me->_movieBox.setHeight(h.asInt());
+	debugC(5, kDebugXObj, "BatQT::m_setMovieBox: %d,%d,%d,%d", me->_movieBox.left, me->_movieBox.top, me->_movieBox.width(), me->_movieBox.height());
+	g_lingo->push(0);
+}
+
 XOBJSTUB(BatQT::m_setTimeRange, 0)
 XOBJSTUB(BatQT::m_addCallback, 0)
 XOBJSTUB(BatQT::m_removeCallback, 0)
diff --git a/engines/director/lingo/xlibs/batqt.h b/engines/director/lingo/xlibs/batqt.h
index f6faa25b7a1..622ee52dea6 100644
--- a/engines/director/lingo/xlibs/batqt.h
+++ b/engines/director/lingo/xlibs/batqt.h
@@ -22,11 +22,21 @@
 #ifndef DIRECTOR_LINGO_XLIBS_BATQT_H
 #define DIRECTOR_LINGO_XLIBS_BATQT_H
 
+#include "common/rect.h"
+
+namespace Video {
+class QuickTimeDecoder;
+}
+
 namespace Director {
 
 class BatQTXObject : public Object<BatQTXObject> {
 public:
 	BatQTXObject(ObjectType objType);
+	~BatQTXObject();
+
+	Video::QuickTimeDecoder *_video;
+	Common::Rect _movieBox;
 };
 
 namespace BatQT {


Commit: c2f9829783000c0c2ced056ed5ddfd320f72f2c7
    https://github.com/scummvm/scummvm/commit/c2f9829783000c0c2ced056ed5ddfd320f72f2c7
Author: Scott Percival (code at moral.net.au)
Date: 2024-01-11T20:41:43+01:00

Commit Message:
DIRECTOR: Fix chan/mk debugger commands

Changed paths:
    engines/director/debugger.cpp


diff --git a/engines/director/debugger.cpp b/engines/director/debugger.cpp
index 42b3534bd4a..bbe0f6b6b6a 100644
--- a/engines/director/debugger.cpp
+++ b/engines/director/debugger.cpp
@@ -336,7 +336,7 @@ bool Debugger::cmdChannels(int argc, const char **argv) {
 
 	if (frameId >= 1 && frameId <= maxSize) {
 		debugPrintf("Channel info for frame %d of %d\n", frameId, maxSize);
-		Frame *frame = score->getFrameData(frameId-1);
+		Frame *frame = score->getFrameData(frameId);
 		debugPrintf("%s\n", frame->formatChannelInfo().c_str());
 		delete frame;
 	} else {
@@ -595,7 +595,7 @@ bool Debugger::cmdMarkers(int argc, const char **argv) {
 	if (score->_labels && score->_labels->size()) {
 		debugPrintf("Score markers:\n");
 		for (auto &it : *score->_labels) {
-			debugPrintf("\"%s\" -> %d", it->name.c_str(), it->number);
+			debugPrintf("\"%s\" -> %d\n", it->name.c_str(), it->number);
 		}
 	} else {
 		debugPrintf("No score markers found.\n");


Commit: bfac83547ea112db06a84aace83f7898bc4eb380
    https://github.com/scummvm/scummvm/commit/bfac83547ea112db06a84aace83f7898bc4eb380
Author: Scott Percival (code at moral.net.au)
Date: 2024-01-11T20:41:43+01:00

Commit Message:
DIRECTOR: Fix linebreak format for the labelList

Fixes inability to close the database after opening it for the first
time in Team Xtreme: Operation Weather Disaster.

Changed paths:
    engines/director/score.cpp


diff --git a/engines/director/score.cpp b/engines/director/score.cpp
index 875d02bd110..cc1d043c3c4 100644
--- a/engines/director/score.cpp
+++ b/engines/director/score.cpp
@@ -161,7 +161,7 @@ Common::String *Score::getLabelList() {
 
 	for (auto &i : *_labels) {
 		*res += i->name;
-		*res += '\n';
+		*res += '\r';
 	}
 
 	return res;


Commit: 94bd08a4ddd027d1424a10e670552256b184b414
    https://github.com/scummvm/scummvm/commit/94bd08a4ddd027d1424a10e670552256b184b414
Author: Scott Percival (code at moral.net.au)
Date: 2024-01-11T20:41:43+01:00

Commit Message:
DIRECTOR: Change assert to no-op when queueing events

Apparently it is possible to send events if there are no frames (e.g. a
movie with no Score data and a script which redirects to another movie).

Fixes occasional crashes when starting Team Xtreme: Operation Weather
Disaster.

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


diff --git a/engines/director/lingo/lingo-events.cpp b/engines/director/lingo/lingo-events.cpp
index c33b69e2a8e..f9b3d95d499 100644
--- a/engines/director/lingo/lingo-events.cpp
+++ b/engines/director/lingo/lingo-events.cpp
@@ -161,7 +161,9 @@ void Movie::queueFrameEvent(Common::Queue<LingoEvent> &queue, LEvent event, int
 	// 	entity = score->getCurrentFrameNum();
 	// } else {
 
-	assert(_score->_currentFrame != nullptr);
+	if (_score->_currentFrame == nullptr)
+		return;
+
 	CastMemberID scriptId = _score->_currentFrame->_mainChannels.actionId;
 	if (!scriptId.member)
 		return;


Commit: ed97e05a1d6f4de3cf487212341c94a459cddd82
    https://github.com/scummvm/scummvm/commit/ed97e05a1d6f4de3cf487212341c94a459cddd82
Author: Scott Percival (code at moral.net.au)
Date: 2024-01-11T20:41:43+01:00

Commit Message:
DEVTOOLS: Refactor director-generate-xobj-stub to allow multiple formats

Changed paths:
    devtools/director-generate-xobj-stub.py


diff --git a/devtools/director-generate-xobj-stub.py b/devtools/director-generate-xobj-stub.py
index 83df7c1f37f..11ad1d360fc 100755
--- a/devtools/director-generate-xobj-stub.py
+++ b/devtools/director-generate-xobj-stub.py
@@ -6,7 +6,18 @@ import argparse
 import os
 import re
 import struct
-from typing import Any, BinaryIO
+from typing import Any, BinaryIO, Literal
+from typing_extensions import TypedDict
+
+XCodeType = Literal["XFCN", "XCMD", "XObject", "Xtra"]
+
+
+class XCode(TypedDict):
+    type: XCodeType
+    name: str
+    slug: str
+    method_table: list[str]
+
 
 DIRECTOR_SRC_PATH = os.path.abspath(
     os.path.join(__file__, "..", "..", "engines", "director")
@@ -15,7 +26,7 @@ MAKEFILE_PATH = os.path.join(DIRECTOR_SRC_PATH, "module.mk")
 LINGO_XLIBS_PATH = os.path.join(DIRECTOR_SRC_PATH, "lingo", "xlibs")
 LINGO_OBJECT_PATH = os.path.join(DIRECTOR_SRC_PATH, "lingo", "lingo-object.cpp")
 
-TEMPLATE_H = """/* ScummVM - Graphic Adventure Engine
+LEGAL = """/* 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
@@ -35,7 +46,11 @@ TEMPLATE_H = """/* ScummVM - Graphic Adventure Engine
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  *
  */
+"""
 
+TEMPLATE_H = (
+    LEGAL
+    + """
 #ifndef DIRECTOR_LINGO_XLIBS_{slug_upper}_H
 #define DIRECTOR_LINGO_XLIBS_{slug_upper}_H
 
@@ -62,30 +77,13 @@ void close(int type);
 
 #endif
 """
+)
 
 TEMPLATE_HEADER_METH = """void m_{methname}(int nargs);"""
 
-TEMPLATE = """/* 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/>.
- *
- */
-
+TEMPLATE = (
+    LEGAL
+    + """
 #include "common/system.h"
 
 #include "director/director.h"
@@ -153,6 +151,7 @@ void {xobj_class}::m_new(int nargs) {{
 
 }}
 """
+)
 XLIB_METHOD_TEMPLATE = """	{{ "{methname}",				{xobj_class}::m_{methname},		 {arg_count}, {arg_count},	{director_version} }},"""
 
 XOBJ_STUB_TEMPLATE = """XOBJSTUB({xobj_class}::m_{methname}, {default})"""
@@ -180,9 +179,9 @@ def read_uint32_be(data: bytes) -> int:
     return struct.unpack(">L", data)[0]
 
 
-def extract_xmethtable_macbinary(
-    file: BinaryIO, resource_offset: int, xobj_id: int | None = None
-) -> tuple[str, str, list[str]]:
+def extract_xcode_macbinary(
+    file: BinaryIO, resource_offset: int, xobj_id: str | None = None
+) -> XCode:
     file.seek(resource_offset)
     resource_data_offset = read_uint32_be(file.read(4))
     resource_map_offset = read_uint32_be(file.read(4))
@@ -197,64 +196,70 @@ def extract_xmethtable_macbinary(
     for _ in range(type_count + 1):
         key = file.read(4)
         types[key] = (read_uint16_be(file.read(2)) + 1, read_uint16_be(file.read(2)))
-    if b"XCOD" in types:
-        print("Found XCOD resources!")
-        file.seek(
-            resource_offset + resource_map_offset + type_list_offset + types[b"XCOD"][1]
-        )
-        resources = []
-        for _ in range(types[b"XCOD"][0]):
-            id = read_uint16_be(file.read(2))
-            name_offset = read_uint16_be(file.read(2))
-            file.read(1)
-            data_offset = (read_uint8(file.read(1)) << 16) + read_uint16_be(
-                file.read(2)
+    xobj: dict[str, dict[str, Any]] = {}
+    for chunk_type in [b"XCOD", b"XFCN", b"XCMD"]:
+        if chunk_type in types:
+            print(f"Found {chunk_type.decode('utf8')} resources!")
+            file.seek(
+                resource_offset
+                + resource_map_offset
+                + type_list_offset
+                + types[chunk_type][1]
             )
-            file.read(4)
-            resources.append((id, data_offset, name_offset))
-        xobj: dict[int, dict[str, Any]] = {}
-        for id, data_offset, name_offset in resources:
-            xobj[id] = {}
-            if name_offset != 0xFFFF:
-                file.seek(
-                    resource_offset
-                    + resource_map_offset
-                    + name_list_offset
-                    + name_offset
+            resources: list[tuple[str, int, int]] = []
+            for _ in range(types[chunk_type][0]):
+                id = f"{chunk_type.decode('utf8')}_{read_uint16_be(file.read(2))}"
+                name_offset = read_uint16_be(file.read(2))
+                file.read(1)
+                data_offset = (read_uint8(file.read(1)) << 16) + read_uint16_be(
+                    file.read(2)
                 )
-                name_size = read_uint8(file.read(1))
-                xobj[id]["name"] = file.read(name_size).decode("macroman")
-            else:
-                xobj[id]["name"] = "<unknown>"
-            file.seek(resource_offset + resource_data_offset + data_offset)
-            size = read_uint32_be(file.read(4)) - 12
-            file.read(12)
-            xobj[id]["xmethtable"] = []
-            while size > 0:
-                count = read_uint8(file.read(1))
-                if count == 0:
-                    break
-                xobj[id]["xmethtable"].append(file.read(count).decode("macroman"))
-                size -= 1 + count
-        if xobj_id is None or xobj_id not in xobj:
-            print("Please re-run with one of the following XOBJ resource IDs:")
-            for id, data in xobj.items():
-                print(f"{id} - {data['name']}")
-            raise ValueError("Need to specify XOBJ resource ID")
-        for entry in xobj[xobj_id]["xmethtable"]:
-            print(entry)
-        return (
-            xobj[xobj_id]["name"],
-            xobj[xobj_id]["name"].lower(),
-            xobj[xobj_id]["xmethtable"],
-        )
-
-    raise ValueError("No XCOD resources found!")
+                file.read(4)
+                resources.append((id, data_offset, name_offset))
+            for id, data_offset, name_offset in resources:
+                xobj[id] = {}
+                if name_offset != 0xFFFF:
+                    file.seek(
+                        resource_offset
+                        + resource_map_offset
+                        + name_list_offset
+                        + name_offset
+                    )
+                    name_size = read_uint8(file.read(1))
+                    xobj[id]["name"] = file.read(name_size).decode("macroman")
+                else:
+                    xobj[id]["name"] = "<unknown>"
+                file.seek(resource_offset + resource_data_offset + data_offset)
+                xobj[id]["dump"] = file.read(read_uint32_be(file.read(4)) - 4)
+                file.seek(resource_offset + resource_data_offset + data_offset)
+                size = read_uint32_be(file.read(4)) - 12
+                file.read(12)
+                xobj[id]["xmethtable"] = []
+                while size > 0:
+                    count = read_uint8(file.read(1))
+                    if count == 0:
+                        break
+                    xobj[id]["xmethtable"].append(file.read(count).decode("macroman"))
+                    size -= 1 + count
+    if not xobj:
+        raise ValueError("No extension resources found!")
+
+    if xobj_id is None or xobj_id not in xobj:
+        print("Please re-run with one of the following resource IDs:")
+        for id, data in xobj.items():
+            print(f"{id} - {data['name']}")
+        raise ValueError("Need to specify resource ID")
+    for entry in xobj[xobj_id]["xmethtable"]:
+        print(entry)
+    return {
+        "type": "XObject",
+        "name": xobj[xobj_id]["name"],
+        "slug": xobj[xobj_id]["name"].lower(),
+        "method_table": xobj[xobj_id]["xmethtable"],
+    }
 
 
-def extract_xmethtable_win16(
-    file: BinaryIO, ne_offset: int
-) -> tuple[str, str, list[str]]:
+def extract_xcode_win16(file: BinaryIO, ne_offset: int) -> XCode:
     # get resource table
     file.seek(ne_offset + 0x24, os.SEEK_SET)
     restable_offset = read_uint16_le(file.read(0x2))
@@ -325,10 +330,15 @@ def extract_xmethtable_win16(
         print(entry)
     library_name = xmethtable[1]
     xmethtable[1] = "--" + library_name
-    return library_name, file_name, xmethtable
+    return {
+        "type": "XObject",
+        "name": library_name,
+        "slug": file_name,
+        "method_table": xmethtable,
+    }
 
 
-def extract_xmethtable_win32(file: BinaryIO, pe_offset: int) -> tuple[str, list[str]]:
+def extract_xcode_win32(file: BinaryIO, pe_offset: int) -> XCode:
     # get the .data section
     # find a string b"msgTable\x00", get the offset
     # get the .text section
@@ -337,10 +347,10 @@ def extract_xmethtable_win32(file: BinaryIO, pe_offset: int) -> tuple[str, list[
     # lookup addr2 in .data
     # get c string, split by \x0a
 
-    return ("", [])
+    return {"type": "Xtra", "name": "", "slug": "", "method_table": []}
 
 
-def extract_xmethtable(path: str, resid: int) -> tuple[str, str, list[str]]:
+def extract_xcode(path: str, resid: str) -> XCode:
     with open(path, "rb") as file:
         magic = file.read(0x2)
         if magic == b"MZ":
@@ -350,7 +360,7 @@ def extract_xmethtable(path: str, resid: int) -> tuple[str, str, list[str]]:
             magic = file.read(0x2)
             if magic == b"NE":
                 print("Found Win16 NE DLL!")
-                return extract_xmethtable_win16(file, header_offset)
+                return extract_xcode_win16(file, header_offset)
             elif magic == b"PE":
                 raise ValueError("No support yet for extracting from Win32 DLLs")
         file.seek(0)
@@ -373,17 +383,17 @@ def extract_xmethtable(path: str, resid: int) -> tuple[str, str, list[str]]:
                 + ((128 - (data_size % 128)) if (data_size % 128) else 0)
             )
             print(f"resource offset: {resource_offset}")
-            return extract_xmethtable_macbinary(file, resource_offset, resid)
+            return extract_xcode_macbinary(file, resource_offset, resid)
 
     raise ValueError("Unknown filetype")
 
 
-def generate_stubs(
+def generate_xobject_stubs(
     xmethtable: list[str],
     slug: str,
     name: str,
     director_version: int = 400,
-    dry_run=False,
+    dry_run: bool = False,
 ) -> None:
     meths = []
     for e in xmethtable:
@@ -464,7 +474,7 @@ def main() -> None:
     )
     parser.add_argument("XOBJ_FILE", help="XObject/XLib file to test")
     parser.add_argument(
-        "--resid", help="XOBJ resource ID (for MacBinary)", type=int, default=None
+        "--resid", help="Resource ID (for MacBinary)", type=str, default=None
     )
     parser.add_argument(
         "--slug", help="Slug to use for files (e.g. {slug}.cpp, {slug}.h)"
@@ -483,10 +493,13 @@ def main() -> None:
     )
     args = parser.parse_args()
 
-    library_name, file_name, xmethtable = extract_xmethtable(args.XOBJ_FILE, args.resid)
-    slug = args.slug or file_name
-    name = args.name or library_name
-    generate_stubs(xmethtable, slug, name, args.version, args.dry_run)
+    xcode = extract_xcode(args.XOBJ_FILE, args.resid)
+    slug = args.slug or xcode["slug"]
+    name = args.name or xcode["name"]
+    if xcode["type"] == "XObject":
+        generate_xobject_stubs(
+            xcode["method_table"], slug, name, args.version, args.dry_run
+        )
 
 
 if __name__ == "__main__":


Commit: 9597e77dab78ba25d57d9eece81c2546f2680a73
    https://github.com/scummvm/scummvm/commit/9597e77dab78ba25d57d9eece81c2546f2680a73
Author: Scott Percival (code at moral.net.au)
Date: 2024-01-11T20:41:43+01:00

Commit Message:
DEVTOOLS: Add include statement injection to director-generate-xobj-stub

Changed paths:
    devtools/director-generate-xobj-stub.py


diff --git a/devtools/director-generate-xobj-stub.py b/devtools/director-generate-xobj-stub.py
index 11ad1d360fc..6f0af59f6a9 100755
--- a/devtools/director-generate-xobj-stub.py
+++ b/devtools/director-generate-xobj-stub.py
@@ -140,10 +140,8 @@ void {xobj_class}::close(int type) {{
 }}
 
 void {xobj_class}::m_new(int nargs) {{
-	if (nargs != 0) {{
-		warning("{xobj_class}::m_new: expected 0 arguments");
-		g_lingo->dropStack(nargs);
-	}}
+	g_lingo->printSTUBWithArglist("{xobj_class}::m_new", nargs);
+	g_lingo->dropStack(nargs);
 	g_lingo->push(g_lingo->_state->me);
 }}
 
@@ -179,6 +177,88 @@ def read_uint32_be(data: bytes) -> int:
     return struct.unpack(">L", data)[0]
 
 
+def inject_makefile(slug: str) -> None:
+    make_contents = open(MAKEFILE_PATH, "r").readlines()
+    expr = re.compile("^\tlingo/xlibs/([a-zA-Z0-9\\-]+).o( \\\\|)")
+    for i in range(len(make_contents)):
+        m = expr.match(make_contents[i])
+        if m:
+            if slug == m.group(1):
+                # file already in makefile
+                print(f"lingo/xlibs/{slug}.o already in {MAKEFILE_PATH}, skipping")
+                return
+            elif slug < m.group(1):
+                make_contents.insert(i, f"\tlingo/xlibs/{slug}.o \\\n")
+                with open(MAKEFILE_PATH, "w") as f:
+                    f.writelines(make_contents)
+                return
+            elif m.group(2) == "":
+                # final entry in the list
+                make_contents[i] += " \\"
+                make_contents.insert(i + 1, f"\tlingo/xlibs/{slug}.o\n")
+                with open(MAKEFILE_PATH, "w") as f:
+                    f.writelines(make_contents)
+                return
+
+
+def inject_lingo_object(slug: str, xobj_class: str, director_version: int) -> None:
+    # write include statement for the object header
+    lo_contents = open(LINGO_OBJECT_PATH, "r").readlines()
+    expr = re.compile('^#include "director/lingo/xlibs/([a-zA-Z0-9\\-]+)\\.h"')
+    in_xlibs = False
+    for i in range(len(lo_contents)):
+        m = expr.match(lo_contents[i])
+        if m:
+            in_xlibs = True
+            if slug == m.group(1):
+                print(
+                    f"lingo/xlibs/{slug}.h import already in {LINGO_OBJECT_PATH}, skipping"
+                )
+                break
+            elif slug < m.group(1):
+                lo_contents.insert(i, f'#include "director/lingo/xlibs/{slug}.h"\n')
+                with open(LINGO_OBJECT_PATH, "w") as f:
+                    f.writelines(lo_contents)
+                break
+        elif in_xlibs:
+            # final entry in the list
+            lo_contents.insert(i, f'#include "director/lingo/xlibs/{slug}.h"\n')
+            with open(LINGO_OBJECT_PATH, "w") as f:
+                f.writelines(lo_contents)
+                break
+
+    # write entry in the XLibProto table
+    lo_contents = open(LINGO_OBJECT_PATH, "r").readlines()
+    expr = re.compile("^\t\\{ ([a-zA-Z0-9_]+)::fileNames")
+    in_xlibs = False
+    for i in range(len(lo_contents)):
+        m = expr.match(lo_contents[i])
+        if m:
+            in_xlibs = True
+            if xobj_class == m.group(1):
+                print(
+                    f"{xobj_class} proto import already in {LINGO_OBJECT_PATH}, skipping"
+                )
+                break
+            elif xobj_class < m.group(1):
+                lo_contents.insert(
+                    i,
+                    f"	{{ {xobj_class}::fileNames,			{xobj_class}::open,			{xobj_class}::close,		kXObj,					{director_version} }},	// D{director_version // 100}\n",
+                )
+                with open(LINGO_OBJECT_PATH, "w") as f:
+                    f.writelines(lo_contents)
+                break
+        elif in_xlibs:
+            # final entry in the list
+            lo_contents.insert(
+                i,
+                f"	{{ {xobj_class}::fileNames,			{xobj_class}::open,			{xobj_class}::close,		kXObj,					{director_version} }},	// D{director_version // 100}\n",
+            )
+            with open(LINGO_OBJECT_PATH, "w") as f:
+                f.writelines(lo_contents)
+                break
+
+
 def extract_xcode_macbinary(
     file: BinaryIO, resource_offset: int, xobj_id: str | None = None
 ) -> XCode:
@@ -467,6 +547,10 @@ def generate_xobject_stubs(
         with open(os.path.join(LINGO_XLIBS_PATH, f"{slug}.h"), "w") as header:
             header.write(header_text)
 
+    if not dry_run:
+        inject_makefile(slug)
+        inject_lingo_object(slug, xobj_class, director_version)
+
 
 def main() -> None:
     parser = argparse.ArgumentParser(
@@ -486,10 +570,14 @@ def main() -> None:
         "--version",
         metavar="VER",
         help="Minimum Director version (default: 400)",
-        default="400",
+		type=int,
+        default=400,
     )
     parser.add_argument(
-        "--dry-run", help="Test only, don't write files", action="store_true"
+        "--write",
+        help="Write generated stubs to the source tree",
+        dest="dry_run",
+        action="store_false",
     )
     args = parser.parse_args()
 


Commit: eeedb676ed46a55aa70fdfabf7176bb834c5eed3
    https://github.com/scummvm/scummvm/commit/eeedb676ed46a55aa70fdfabf7176bb834c5eed3
Author: Scott Percival (code at moral.net.au)
Date: 2024-01-11T20:41:43+01:00

Commit Message:
DIRECTOR: LINGO: XOBJ: Add stubs for XCMDGlue

Changed paths:
  A engines/director/lingo/xlibs/xcmdglue.cpp
  A engines/director/lingo/xlibs/xcmdglue.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 95ef2b9eea3..c42983bf119 100644
--- a/engines/director/lingo/lingo-object.cpp
+++ b/engines/director/lingo/lingo-object.cpp
@@ -99,6 +99,7 @@
 #include "director/lingo/xlibs/widgetxobj.h"
 #include "director/lingo/xlibs/wininfo.h"
 #include "director/lingo/xlibs/winxobj.h"
+#include "director/lingo/xlibs/xcmdglue.h"
 #include "director/lingo/xlibs/xio.h"
 #include "director/lingo/xlibs/xplayanim.h"
 #include "director/lingo/xlibs/yasix.h"
@@ -242,6 +243,7 @@ static struct XLibProto {
 	{ VolumeList::fileNames,			VolumeList::open,			VolumeList::close,			kXObj,					300 },	// D3
 	{ WinInfoXObj::fileNames,			WinInfoXObj::open,			WinInfoXObj::close,			kXObj,					400 },  // D4
 	{ WidgetXObj::fileNames,			WidgetXObj::open,			WidgetXObj::close, 			kXObj,					400 },  // D4
+	{ XCMDGlueXObj::fileNames,			XCMDGlueXObj::open,			XCMDGlueXObj::close,		kXObj,					200 },	// D2
 	{ XioXObj::fileNames,				XioXObj::open,				XioXObj::close,				kXObj,					400 },	// D3
 	{ XPlayAnim::fileNames,				XPlayAnim::open,			XPlayAnim::close,			kXObj,					300 },	// D3
 	{ Yasix::fileNames,					Yasix::open,				Yasix::close,				kXObj,					300 },	// D3
diff --git a/engines/director/lingo/xlibs/xcmdglue.cpp b/engines/director/lingo/xlibs/xcmdglue.cpp
new file mode 100644
index 00000000000..343af208084
--- /dev/null
+++ b/engines/director/lingo/xlibs/xcmdglue.cpp
@@ -0,0 +1,106 @@
+/* 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/xcmdglue.h"
+
+/**************************************************
+ *
+ * USED IN:
+ * Standard Macromedia Director XObject
+ *
+ **************************************************/
+
+/*
+--XCMDGlue, Tool, 1.6.4, 14aug93
+--Interface to XCMD's and XFCN's
+--© 1989, 1990 MacroMind, Inc.
+--by John Thompson
+ISI 	mNew
+X 	mDispose
+XI 	mVerbDispose
+S 	mName
+V	mVerb
+XO	mSetHandler
+O	mGetHandler
+ */
+
+namespace Director {
+
+const char *XCMDGlueXObj::xlibName = "XCMDGlue";
+const char *XCMDGlueXObj::fileNames[] = {
+	"XCMDGlue",
+	nullptr
+};
+
+static MethodProto xlibMethods[] = {
+	{ "new",				XCMDGlueXObj::m_new,		 2, 2,	200 },
+	{ "dispose",				XCMDGlueXObj::m_dispose,		 0, 0,	200 },
+	{ "verbDispose",				XCMDGlueXObj::m_verbDispose,		 1, 1,	200 },
+	{ "name",				XCMDGlueXObj::m_name,		 0, 0,	200 },
+	{ "verb",				XCMDGlueXObj::m_verb,		 0, 0,	200 },
+	{ "setHandler",				XCMDGlueXObj::m_setHandler,		 1, 1,	200 },
+	{ "getHandler",				XCMDGlueXObj::m_getHandler,		 0, 0,	200 },
+	{ nullptr, nullptr, 0, 0, 0 }
+};
+
+XCMDGlueXObject::XCMDGlueXObject(ObjectType ObjectType) :Object<XCMDGlueXObject>("XCMDGlueXObj") {
+	_objType = ObjectType;
+}
+
+void XCMDGlueXObj::open(int type) {
+	if (type == kXObj) {
+		XCMDGlueXObject::initMethods(xlibMethods);
+		XCMDGlueXObject *xobj = new XCMDGlueXObject(kXObj);
+		g_lingo->exposeXObject(xlibName, xobj);
+	} else if (type == kXtraObj) {
+		// TODO - Implement Xtra
+	}
+}
+
+void XCMDGlueXObj::close(int type) {
+	if (type == kXObj) {
+		XCMDGlueXObject::cleanupMethods();
+		g_lingo->_globalvars[xlibName] = Datum();
+	} else if (type == kXtraObj) {
+		// TODO - Implement Xtra
+	}
+}
+
+void XCMDGlueXObj::m_new(int nargs) {
+	g_lingo->printSTUBWithArglist("XCMDGlueXObj::m_new", nargs);
+	g_lingo->dropStack(nargs);
+	g_lingo->push(g_lingo->_state->me);
+}
+
+XOBJSTUBNR(XCMDGlueXObj::m_dispose)
+XOBJSTUBNR(XCMDGlueXObj::m_verbDispose)
+XOBJSTUB(XCMDGlueXObj::m_name, "")
+XOBJSTUB(XCMDGlueXObj::m_verb, 0)
+XOBJSTUBNR(XCMDGlueXObj::m_setHandler)
+XOBJSTUB(XCMDGlueXObj::m_getHandler, 0)
+
+}
diff --git a/engines/director/lingo/xlibs/xcmdglue.h b/engines/director/lingo/xlibs/xcmdglue.h
new file mode 100644
index 00000000000..2987b5d4d37
--- /dev/null
+++ b/engines/director/lingo/xlibs/xcmdglue.h
@@ -0,0 +1,52 @@
+/* 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_XCMDGLUE_H
+#define DIRECTOR_LINGO_XLIBS_XCMDGLUE_H
+
+namespace Director {
+
+class XCMDGlueXObject : public Object<XCMDGlueXObject> {
+public:
+	XCMDGlueXObject(ObjectType objType);
+};
+
+namespace XCMDGlueXObj {
+
+extern const char *xlibName;
+extern const char *fileNames[];
+
+void open(int type);
+void close(int type);
+
+void m_new(int nargs);
+void m_dispose(int nargs);
+void m_verbDispose(int nargs);
+void m_name(int nargs);
+void m_verb(int nargs);
+void m_setHandler(int nargs);
+void m_getHandler(int nargs);
+
+} // End of namespace XCMDGlueXObj
+
+} // End of namespace Director
+
+#endif
diff --git a/engines/director/module.mk b/engines/director/module.mk
index fb22987db30..1bae0ddd928 100644
--- a/engines/director/module.mk
+++ b/engines/director/module.mk
@@ -122,6 +122,7 @@ MODULE_OBJS = \
 	lingo/xlibs/widgetxobj.o \
 	lingo/xlibs/winxobj.o \
 	lingo/xlibs/wininfo.o \
+	lingo/xlibs/xcmdglue.o \
 	lingo/xlibs/xio.o \
 	lingo/xlibs/xplayanim.o \
 	lingo/xlibs/yasix.o


Commit: a83d40a57586d9bd45d456d925b4318b35c16bbe
    https://github.com/scummvm/scummvm/commit/a83d40a57586d9bd45d456d925b4318b35c16bbe
Author: Scott Percival (code at moral.net.au)
Date: 2024-01-11T20:41:43+01:00

Commit Message:
DIRECTOR: LINGO: XOBJ: Fix m_new boilerplate

Changed paths:
    engines/director/lingo/xlibs/askuser.cpp
    engines/director/lingo/xlibs/blitpict.cpp
    engines/director/lingo/xlibs/colorcursorxobj.cpp
    engines/director/lingo/xlibs/colorxobj.cpp
    engines/director/lingo/xlibs/consumer.cpp
    engines/director/lingo/xlibs/cursorxobj.cpp
    engines/director/lingo/xlibs/dirutil.cpp
    engines/director/lingo/xlibs/maniacbg.cpp
    engines/director/lingo/xlibs/mapnavigatorxobj.cpp
    engines/director/lingo/xlibs/memcheckxobj.cpp
    engines/director/lingo/xlibs/mmaskxobj.cpp
    engines/director/lingo/xlibs/movemousexobj.cpp
    engines/director/lingo/xlibs/movieidxxobj.cpp
    engines/director/lingo/xlibs/qtcatmovieplayerxobj.cpp
    engines/director/lingo/xlibs/qtvr.cpp
    engines/director/lingo/xlibs/wininfo.cpp


diff --git a/engines/director/lingo/xlibs/askuser.cpp b/engines/director/lingo/xlibs/askuser.cpp
index 5b48f660d1c..9ae487b9da6 100644
--- a/engines/director/lingo/xlibs/askuser.cpp
+++ b/engines/director/lingo/xlibs/askuser.cpp
@@ -82,10 +82,8 @@ void AskUser::close(int type) {
 }
 
 void AskUser::m_new(int nargs) {
-	if (nargs != 0) {
-		warning("AskUser::m_new: expected 0 arguments");
-		g_lingo->dropStack(nargs);
-	}
+	g_lingo->printSTUBWithArglist("AskUser::m_new", nargs);
+	g_lingo->dropStack(nargs);
 	g_lingo->push(g_lingo->_state->me);
 }
 
diff --git a/engines/director/lingo/xlibs/blitpict.cpp b/engines/director/lingo/xlibs/blitpict.cpp
index 1a0a646e819..7d830d2541c 100644
--- a/engines/director/lingo/xlibs/blitpict.cpp
+++ b/engines/director/lingo/xlibs/blitpict.cpp
@@ -96,10 +96,8 @@ void BlitPictXObj::close(int type) {
 }
 
 void BlitPictXObj::m_new(int nargs) {
-	if (nargs != 0) {
-		warning("BlitPictXObj::m_new: expected 0 arguments");
-		g_lingo->dropStack(nargs);
-	}
+	g_lingo->printSTUBWithArglist("BlitPictXObj::m_new", nargs);
+	g_lingo->dropStack(nargs);
 	g_lingo->push(g_lingo->_state->me);
 }
 
diff --git a/engines/director/lingo/xlibs/colorcursorxobj.cpp b/engines/director/lingo/xlibs/colorcursorxobj.cpp
index c7fe582254c..a73f7b5b28f 100644
--- a/engines/director/lingo/xlibs/colorcursorxobj.cpp
+++ b/engines/director/lingo/xlibs/colorcursorxobj.cpp
@@ -82,10 +82,8 @@ void ColorCursorXObj::close(int type) {
 }
 
 void ColorCursorXObj::m_new(int nargs) {
-	if (nargs != 0) {
-		warning("ColorCursorXObj::m_new: expected 0 arguments");
-		g_lingo->dropStack(nargs);
-	}
+	g_lingo->printSTUBWithArglist("ColorCursorXObj::m_new", nargs);
+	g_lingo->dropStack(nargs);
 	g_lingo->push(g_lingo->_state->me);
 }
 
diff --git a/engines/director/lingo/xlibs/colorxobj.cpp b/engines/director/lingo/xlibs/colorxobj.cpp
index cdf84e0c024..a3ecdd03b05 100644
--- a/engines/director/lingo/xlibs/colorxobj.cpp
+++ b/engines/director/lingo/xlibs/colorxobj.cpp
@@ -103,10 +103,8 @@ void ColorXObj::close(int type) {
 
 
 void ColorXObj::m_new(int nargs) {
-	if (nargs != 0) {
-		warning("ColorXObj::m_new: expected 0 arguments");
-		g_lingo->dropStack(nargs);
-	}
+	g_lingo->printSTUBWithArglist("ColorXObj::m_new", nargs);
+	g_lingo->dropStack(nargs);
 	g_lingo->push(g_lingo->_state->me);
 }
 
diff --git a/engines/director/lingo/xlibs/consumer.cpp b/engines/director/lingo/xlibs/consumer.cpp
index c84a378cdf6..aaa17c444d3 100644
--- a/engines/director/lingo/xlibs/consumer.cpp
+++ b/engines/director/lingo/xlibs/consumer.cpp
@@ -102,10 +102,8 @@ void ConsumerXObj::close(int type) {
 }
 
 void ConsumerXObj::m_new(int nargs) {
-	if (nargs != 0) {
-		warning("Consumer::m_new: expected 0 arguments");
-		g_lingo->dropStack(nargs);
-	}
+	g_lingo->printSTUBWithArglist("ConsumerXObj::m_new", nargs);
+	g_lingo->dropStack(nargs);
 	g_lingo->push(g_lingo->_state->me);
 }
 
diff --git a/engines/director/lingo/xlibs/cursorxobj.cpp b/engines/director/lingo/xlibs/cursorxobj.cpp
index 2193d3eff38..c7253441add 100644
--- a/engines/director/lingo/xlibs/cursorxobj.cpp
+++ b/engines/director/lingo/xlibs/cursorxobj.cpp
@@ -81,10 +81,8 @@ void CursorXObj::close(int type) {
 }
 
 void CursorXObj::m_new(int nargs) {
-	if (nargs != 0) {
-		warning("CursorXObj::m_new: expected 0 arguments");
-		g_lingo->dropStack(nargs);
-	}
+	g_lingo->printSTUBWithArglist("CursorXObj::m_new", nargs);
+	g_lingo->dropStack(nargs);
 	g_lingo->push(g_lingo->_state->me);
 }
 
diff --git a/engines/director/lingo/xlibs/dirutil.cpp b/engines/director/lingo/xlibs/dirutil.cpp
index caf2eb71b20..772427e1a97 100644
--- a/engines/director/lingo/xlibs/dirutil.cpp
+++ b/engines/director/lingo/xlibs/dirutil.cpp
@@ -96,10 +96,8 @@ void DirUtilXObj::close(int type) {
 }
 
 void DirUtilXObj::m_new(int nargs) {
-	if (nargs != 0) {
-		warning("DirUtilXObj::m_new: expected 0 arguments");
-		g_lingo->dropStack(nargs);
-	}
+	g_lingo->printSTUBWithArglist("DirUtilXObj::m_new", nargs);
+	g_lingo->dropStack(nargs);
 	g_lingo->push(g_lingo->_state->me);
 }
 
diff --git a/engines/director/lingo/xlibs/maniacbg.cpp b/engines/director/lingo/xlibs/maniacbg.cpp
index dc4ee34ef89..1213666d2f5 100644
--- a/engines/director/lingo/xlibs/maniacbg.cpp
+++ b/engines/director/lingo/xlibs/maniacbg.cpp
@@ -82,10 +82,8 @@ void ManiacBgXObj::close(int type) {
 }
 
 void ManiacBgXObj::m_new(int nargs) {
-	if (nargs != 0) {
-		warning("ManiacBgXObj::m_new: expected 0 arguments");
-		g_lingo->dropStack(nargs);
-	}
+	g_lingo->printSTUBWithArglist("ManiacBgXObj::m_new", nargs);
+	g_lingo->dropStack(nargs);
 	g_lingo->push(g_lingo->_state->me);
 }
 
diff --git a/engines/director/lingo/xlibs/mapnavigatorxobj.cpp b/engines/director/lingo/xlibs/mapnavigatorxobj.cpp
index cd0df48522b..012372447f4 100644
--- a/engines/director/lingo/xlibs/mapnavigatorxobj.cpp
+++ b/engines/director/lingo/xlibs/mapnavigatorxobj.cpp
@@ -133,10 +133,8 @@ void MapNavigatorXObj::close(int type) {
 }
 
 void MapNavigatorXObj::m_new(int nargs) {
-	if (nargs != 0) {
-		warning("MapNavigatorXObj::m_new: expected 0 arguments");
-		g_lingo->dropStack(nargs);
-	}
+	g_lingo->printSTUBWithArglist("MapNavigatorXObj::m_new", nargs);
+	g_lingo->dropStack(nargs);
 	g_lingo->push(g_lingo->_state->me);
 }
 
diff --git a/engines/director/lingo/xlibs/memcheckxobj.cpp b/engines/director/lingo/xlibs/memcheckxobj.cpp
index 767a8a72379..6fe48e2c19f 100644
--- a/engines/director/lingo/xlibs/memcheckxobj.cpp
+++ b/engines/director/lingo/xlibs/memcheckxobj.cpp
@@ -91,10 +91,8 @@ void MemCheckXObj::close(int type) {
 }
 
 void MemCheckXObj::m_new(int nargs) {
-	if (nargs != 0) {
-		warning("MemCheckXObj::m_new: expected 0 arguments");
-		g_lingo->dropStack(nargs);
-	}
+	g_lingo->printSTUBWithArglist("MemCheckXObj::m_new", nargs);
+	g_lingo->dropStack(nargs);
 	g_lingo->push(g_lingo->_state->me);
 }
 
diff --git a/engines/director/lingo/xlibs/mmaskxobj.cpp b/engines/director/lingo/xlibs/mmaskxobj.cpp
index c3a1e4320a0..8b76b3188f5 100644
--- a/engines/director/lingo/xlibs/mmaskxobj.cpp
+++ b/engines/director/lingo/xlibs/mmaskxobj.cpp
@@ -79,10 +79,8 @@ void MMaskXObj::close(int type) {
 }
 
 void MMaskXObj::m_new(int nargs) {
-	if (nargs != 0) {
-		warning("MMaskXObj::m_new: expected 0 arguments");
-		g_lingo->dropStack(nargs);
-	}
+	g_lingo->printSTUBWithArglist("MMaskXObj::m_new", nargs);
+	g_lingo->dropStack(nargs);
 	g_lingo->push(g_lingo->_state->me);
 }
 
diff --git a/engines/director/lingo/xlibs/movemousexobj.cpp b/engines/director/lingo/xlibs/movemousexobj.cpp
index adf3da2f5c7..f4447feb77d 100644
--- a/engines/director/lingo/xlibs/movemousexobj.cpp
+++ b/engines/director/lingo/xlibs/movemousexobj.cpp
@@ -78,16 +78,14 @@ void MoveMouseXObj::close(int type) {
 }
 
 void MoveMouseXObj::m_new(int nargs) {
-	if (nargs != 0) {
-		warning("MoveMouse::m_new: expected 0 arguments");
-		g_lingo->dropStack(nargs);
-	}
+	g_lingo->printSTUBWithArglist("MoveMouseXObj::m_new", nargs);
+	g_lingo->dropStack(nargs);
 	g_lingo->push(g_lingo->_state->me);
 }
 
 void MoveMouseXObj::m_setMouseLoc(int nargs) {
 	if (nargs != 2) {
-		warning("MoveMouse::m_setMouseLoc: expected 2 arguments");
+		warning("MoveMouseXObj::m_setMouseLoc: expected 2 arguments");
 		g_lingo->dropStack(nargs);
 		return;
 	}
diff --git a/engines/director/lingo/xlibs/movieidxxobj.cpp b/engines/director/lingo/xlibs/movieidxxobj.cpp
index af135c27695..34f35b82aad 100644
--- a/engines/director/lingo/xlibs/movieidxxobj.cpp
+++ b/engines/director/lingo/xlibs/movieidxxobj.cpp
@@ -88,10 +88,8 @@ void MovieIdxXObj::close(int type) {
 }
 
 void MovieIdxXObj::m_new(int nargs) {
-	if (nargs != 0) {
-		warning("MovieIdxXObj::m_new: expected 0 arguments");
-		g_lingo->dropStack(nargs);
-	}
+	g_lingo->printSTUBWithArglist("MovieIdxXObj::m_new", nargs);
+	g_lingo->dropStack(nargs);
 	g_lingo->push(g_lingo->_state->me);
 }
 
diff --git a/engines/director/lingo/xlibs/qtcatmovieplayerxobj.cpp b/engines/director/lingo/xlibs/qtcatmovieplayerxobj.cpp
index cdd3add5a13..de411f49e98 100644
--- a/engines/director/lingo/xlibs/qtcatmovieplayerxobj.cpp
+++ b/engines/director/lingo/xlibs/qtcatmovieplayerxobj.cpp
@@ -90,10 +90,8 @@ void QTCatMoviePlayerXObj::close(int type) {
 }
 
 void QTCatMoviePlayerXObj::m_new(int nargs) {
-	if (nargs != 0) {
-		warning("QTCatMoviePlayerXObj::m_new: expected 0 arguments");
-		g_lingo->dropStack(nargs);
-	}
+	g_lingo->printSTUBWithArglist("QTCatMoviePlayerXObj::m_new", nargs);
+	g_lingo->dropStack(nargs);
 	g_lingo->push(g_lingo->_state->me);
 }
 
diff --git a/engines/director/lingo/xlibs/qtvr.cpp b/engines/director/lingo/xlibs/qtvr.cpp
index 0993e6c1150..b28c00b6a0a 100644
--- a/engines/director/lingo/xlibs/qtvr.cpp
+++ b/engines/director/lingo/xlibs/qtvr.cpp
@@ -118,10 +118,8 @@ void QTVR::close(int type) {
 
 
 void QTVR::m_new(int nargs) {
-	if (nargs != 0) {
-		warning("QTVR::m_new: expected 0 arguments");
-		g_lingo->dropStack(nargs);
-	}
+	g_lingo->printSTUBWithArglist("QTVR::m_new", nargs);
+	g_lingo->dropStack(nargs);
 	g_lingo->push(g_lingo->_state->me);
 }
 
diff --git a/engines/director/lingo/xlibs/wininfo.cpp b/engines/director/lingo/xlibs/wininfo.cpp
index a610f5b7341..ae1b4c3c793 100644
--- a/engines/director/lingo/xlibs/wininfo.cpp
+++ b/engines/director/lingo/xlibs/wininfo.cpp
@@ -83,10 +83,8 @@ void WinInfoXObj::close(int type) {
 }
 
 void WinInfoXObj::m_new(int nargs) {
-	if (nargs != 0) {
-		warning("WinInfoXObj::m_new: expected 0 arguments");
-		g_lingo->dropStack(nargs);
-	}
+	g_lingo->printSTUBWithArglist("WinInfoXObj::m_new", nargs);
+	g_lingo->dropStack(nargs);
 	g_lingo->push(g_lingo->_state->me);
 }
 


Commit: bdb30a3cc181f89b9907297e18681679ea057505
    https://github.com/scummvm/scummvm/commit/bdb30a3cc181f89b9907297e18681679ea057505
Author: Scott Percival (code at moral.net.au)
Date: 2024-01-11T20:41:43+01:00

Commit Message:
DEVTOOLS: Add XFCN/XCMD support to director-generate-xobj-stub

Changed paths:
    devtools/director-generate-xobj-stub.py


diff --git a/devtools/director-generate-xobj-stub.py b/devtools/director-generate-xobj-stub.py
index 6f0af59f6a9..6a7bba3e0a6 100755
--- a/devtools/director-generate-xobj-stub.py
+++ b/devtools/director-generate-xobj-stub.py
@@ -16,6 +16,7 @@ class XCode(TypedDict):
     type: XCodeType
     name: str
     slug: str
+    filename: str
     method_table: list[str]
 
 
@@ -105,9 +106,9 @@ TEMPLATE = (
 
 namespace Director {{
 
-const char *{xobj_class}::xlibName = "{slug}";
+const char *{xobj_class}::xlibName = "{name}";
 const char *{xobj_class}::fileNames[] = {{
-	"{slug}",
+	"{filename}",
 	nullptr
 }};
 
@@ -152,6 +153,79 @@ void {xobj_class}::m_new(int nargs) {{
 )
 XLIB_METHOD_TEMPLATE = """	{{ "{methname}",				{xobj_class}::m_{methname},		 {arg_count}, {arg_count},	{director_version} }},"""
 
+XCMD_TEMPLATE_H = (
+    LEGAL
+    + """
+#ifndef DIRECTOR_LINGO_XLIBS_{slug_upper}_H
+#define DIRECTOR_LINGO_XLIBS_{slug_upper}_H
+
+namespace Director {{
+
+namespace {xobj_class} {{
+
+extern const char *xlibName;
+extern const char *fileNames[];
+
+void open(int type);
+void close(int type);
+
+{methlist}
+
+}} // End of namespace {xobj_class}
+
+}} // End of namespace Director
+
+#endif
+"""
+)
+
+XCMD_TEMPLATE = (
+    LEGAL
+    + """
+#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/{slug}.h"
+
+/**************************************************
+ *
+ * USED IN:
+ * [insert game here]
+ *
+ **************************************************/
+
+namespace Director {{
+
+const char *{xobj_class}::xlibName = "{name}";
+const char *{xobj_class}::fileNames[] = {{
+	"{filename}",
+	nullptr
+}};
+
+static BuiltinProto builtins[] = {{
+{xlib_builtins}
+	{{ nullptr, nullptr, 0, 0, 0, VOIDSYM }}
+}};
+
+void {xobj_class}::open(int type) {{
+	g_lingo->initBuiltIns(builtins);
+}}
+
+void {xobj_class}::close(int type) {{
+	g_lingo->cleanupBuiltIns(builtins);
+}}
+
+{xobj_stubs}
+
+}}
+"""
+)
+
+XCMD_BUILTIN_TEMPLATE = """	{{ "{name}", {xobj_class}::m_{name}, -1, 0, {director_version}, {methtype} }},"""
+
 XOBJ_STUB_TEMPLATE = """XOBJSTUB({xobj_class}::m_{methname}, {default})"""
 
 XOBJ_NR_STUB_TEMPLATE = """XOBJSTUBNR({xobj_class}::m_{methname})"""
@@ -331,10 +405,21 @@ def extract_xcode_macbinary(
         raise ValueError("Need to specify resource ID")
     for entry in xobj[xobj_id]["xmethtable"]:
         print(entry)
+    type: XCodeType = (
+        "XFCN"
+        if xobj_id.startswith("XFCN_")
+        else "XCMD"
+        if xobj_id.startswith("XCMD_")
+        else "XObject"
+    )
+    slug = xobj[xobj_id]["name"].lower()
+    if type in ["XFCN", "XCMD"]:
+        slug += type.lower()
     return {
-        "type": "XObject",
+        "type": type,
         "name": xobj[xobj_id]["name"],
-        "slug": xobj[xobj_id]["name"].lower(),
+        "slug": slug,
+        "filename": xobj[xobj_id]["name"],
         "method_table": xobj[xobj_id]["xmethtable"],
     }
 
@@ -413,7 +498,8 @@ def extract_xcode_win16(file: BinaryIO, ne_offset: int) -> XCode:
     return {
         "type": "XObject",
         "name": library_name,
-        "slug": file_name,
+        "slug": file_name.lower(),
+        "filename": file_name,
         "method_table": xmethtable,
     }
 
@@ -427,7 +513,7 @@ def extract_xcode_win32(file: BinaryIO, pe_offset: int) -> XCode:
     # lookup addr2 in .data
     # get c string, split by \x0a
 
-    return {"type": "Xtra", "name": "", "slug": "", "method_table": []}
+    return {"type": "Xtra", "name": "", "slug": "", "filename": "", "method_table": []}
 
 
 def extract_xcode(path: str, resid: str) -> XCode:
@@ -472,6 +558,7 @@ def generate_xobject_stubs(
     xmethtable: list[str],
     slug: str,
     name: str,
+    filename: str,
     director_version: int = 400,
     dry_run: bool = False,
 ) -> None:
@@ -504,6 +591,8 @@ def generate_xobject_stubs(
 
     cpp_text = TEMPLATE.format(
         slug=slug,
+        name=name,
+        filename=filename,
         xmethtable="\n".join(xmethtable),
         xobject_class=xobject_class,
         xobj_class=xobj_class,
@@ -535,8 +624,8 @@ def generate_xobject_stubs(
 
     header_text = TEMPLATE_H.format(
         slug_upper=slug.upper(),
-        xobject_class=f"{name}XObject",
-        xobj_class=f"{name}XObj",
+        xobject_class=xobject_class,
+        xobj_class=xobj_class,
         methlist="\n".join([TEMPLATE_HEADER_METH.format(**x) for x in meths]),
     )
     if dry_run:
@@ -552,6 +641,57 @@ def generate_xobject_stubs(
         inject_lingo_object(slug, xobj_class, director_version)
 
 
+def generate_xcmd_stubs(
+    type: Literal["XCMD", "XFCN"],
+    slug: str,
+    name: str,
+    filename: str,
+    director_version: int = 400,
+    dry_run: bool = False,
+) -> None:
+    xobj_class = f"{name}{type}"
+    methtype = "CBLTIN" if type == "XCMD" else "HBLTIN"
+    cpp_text = XCMD_TEMPLATE.format(
+        slug=slug,
+        name=name,
+        filename=filename,
+        xobj_class=xobj_class,
+        xlib_builtins=XCMD_BUILTIN_TEMPLATE.format(
+            name=name,
+            xobj_class=xobj_class,
+            director_version=director_version,
+            methtype=methtype,
+        ),
+        xobj_stubs=XOBJ_STUB_TEMPLATE.format(
+            xobj_class=xobj_class, methname=name, default=0
+        ),
+    )
+    if dry_run:
+        print("C++ output:")
+        print(cpp_text)
+        print()
+    else:
+        with open(os.path.join(LINGO_XLIBS_PATH, f"{slug}.cpp"), "w") as cpp:
+            cpp.write(cpp_text)
+
+    header_text = XCMD_TEMPLATE_H.format(
+        slug_upper=slug.upper(),
+        xobj_class=xobj_class,
+        methlist=TEMPLATE_HEADER_METH.format(methname=name),
+    )
+    if dry_run:
+        print("Header output:")
+        print(header_text)
+        print()
+    else:
+        with open(os.path.join(LINGO_XLIBS_PATH, f"{slug}.h"), "w") as header:
+            header.write(header_text)
+
+    if not dry_run:
+        inject_makefile(slug)
+        inject_lingo_object(slug, xobj_class, director_version)
+
+
 def main() -> None:
     parser = argparse.ArgumentParser(
         description="Extract the method table from a Macromedia Director XObject/XLib and generate method stubs."
@@ -570,7 +710,7 @@ def main() -> None:
         "--version",
         metavar="VER",
         help="Minimum Director version (default: 400)",
-		type=int,
+        type=int,
         default=400,
     )
     parser.add_argument(
@@ -586,7 +726,16 @@ def main() -> None:
     name = args.name or xcode["name"]
     if xcode["type"] == "XObject":
         generate_xobject_stubs(
-            xcode["method_table"], slug, name, args.version, args.dry_run
+            xcode["method_table"],
+            slug,
+            name,
+            xcode["filename"],
+            args.version,
+            args.dry_run,
+        )
+    elif xcode["type"] == "XFCN" or xcode["type"] == "XCMD":
+        generate_xcmd_stubs(
+            xcode["type"], slug, name, xcode["filename"], args.version, args.dry_run
         )
 
 


Commit: 747a1bad2945761f107d397f3d6b7df3c2a59c7d
    https://github.com/scummvm/scummvm/commit/747a1bad2945761f107d397f3d6b7df3c2a59c7d
Author: Scott Percival (code at moral.net.au)
Date: 2024-01-11T20:41:43+01:00

Commit Message:
DIRECTOR: LINGO: XCMD: Add stubs missing for Puppet Motel

Changed paths:
  A engines/director/lingo/xlibs/fadegammadownxcmd.cpp
  A engines/director/lingo/xlibs/fadegammadownxcmd.h
  A engines/director/lingo/xlibs/fadegammaupxcmd.cpp
  A engines/director/lingo/xlibs/fadegammaupxcmd.h
  A engines/director/lingo/xlibs/fadegammaxcmd.cpp
  A engines/director/lingo/xlibs/fadegammaxcmd.h
  A engines/director/lingo/xlibs/findereventsxcmd.cpp
  A engines/director/lingo/xlibs/findereventsxcmd.h
  A engines/director/lingo/xlibs/vmisonxfcn.cpp
  A engines/director/lingo/xlibs/vmisonxfcn.h
  A engines/director/lingo/xlibs/xsoundxfcn.cpp
  A engines/director/lingo/xlibs/xsoundxfcn.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 c42983bf119..1e2658ec906 100644
--- a/engines/director/lingo/lingo-object.cpp
+++ b/engines/director/lingo/lingo-object.cpp
@@ -49,11 +49,15 @@
 #include "director/lingo/xlibs/draw.h"
 #include "director/lingo/xlibs/ednox.h"
 #include "director/lingo/xlibs/eventq.h"
+#include "director/lingo/xlibs/fadegammadownxcmd.h"
+#include "director/lingo/xlibs/fadegammaupxcmd.h"
+#include "director/lingo/xlibs/fadegammaxcmd.h"
 #include "director/lingo/xlibs/fedracul.h"
 #include "director/lingo/xlibs/feimasks.h"
 #include "director/lingo/xlibs/feiprefs.h"
 #include "director/lingo/xlibs/fileexists.h"
 #include "director/lingo/xlibs/fileio.h"
+#include "director/lingo/xlibs/findereventsxcmd.h"
 #include "director/lingo/xlibs/findfolder.h"
 #include "director/lingo/xlibs/findsys.h"
 #include "director/lingo/xlibs/findwin.h"
@@ -95,6 +99,7 @@
 #include "director/lingo/xlibs/unittest.h"
 #include "director/lingo/xlibs/valkyrie.h"
 #include "director/lingo/xlibs/videodiscxobj.h"
+#include "director/lingo/xlibs/vmisonxfcn.h"
 #include "director/lingo/xlibs/volumelist.h"
 #include "director/lingo/xlibs/widgetxobj.h"
 #include "director/lingo/xlibs/wininfo.h"
@@ -102,6 +107,7 @@
 #include "director/lingo/xlibs/xcmdglue.h"
 #include "director/lingo/xlibs/xio.h"
 #include "director/lingo/xlibs/xplayanim.h"
+#include "director/lingo/xlibs/xsoundxfcn.h"
 #include "director/lingo/xlibs/yasix.h"
 
 namespace Director {
@@ -196,11 +202,15 @@ static struct XLibProto {
 	{ FEDraculXObj::fileNames,			FEDraculXObj::open,			FEDraculXObj::close,		kXObj,					400 },	// D4
 	{ FEIMasksXObj::fileNames,			FEIMasksXObj::open,			FEIMasksXObj::close,		kXObj,					400 },	// D4
 	{ FEIPrefsXObj::fileNames,			FEIPrefsXObj::open,			FEIPrefsXObj::close,		kXObj,					400 },	// D4
+	{ FadeGammaDownXCMD::fileNames,			FadeGammaDownXCMD::open,			FadeGammaDownXCMD::close,		kXObj,					400 },	// D4
+	{ FadeGammaUpXCMD::fileNames,			FadeGammaUpXCMD::open,			FadeGammaUpXCMD::close,		kXObj,					400 },	// D4
+	{ FadeGammaXCMD::fileNames,			FadeGammaXCMD::open,			FadeGammaXCMD::close,		kXObj,					400 },	// D4
 	{ FileExists::fileNames,			FileExists::open,			FileExists::close,			kXObj,					300 },	// D3
 	{ FileIO::fileNames,				FileIO::open,				FileIO::close,				kXObj | kXtraObj,		200 },	// D2
 	{ FindFolder::fileNames,			FindFolder::open,			FindFolder::close,			kXObj,					300 },	// D3
 	{ FindSys::fileNames,				FindSys::open,				FindSys::close,				kXObj,					400 },	// D4
 	{ FindWin::fileNames,				FindWin::open,				FindWin::close,				kXObj,					400 },	// D4
+	{ 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
 	{ GpidXObj::fileNames,				GpidXObj::open,				GpidXObj::close,			kXObj,					400 },	// D4
@@ -238,12 +248,14 @@ static struct XLibProto {
 	{ SpaceMgr::fileNames,				SpaceMgr::open,				SpaceMgr::close,			kXObj,					400 },	// D4
 	{ StageTCXObj::fileNames,			StageTCXObj::open,			StageTCXObj::close,			kXObj,					400 },	// D4
 	{ UnitTest::fileNames,				UnitTest::open,				UnitTest::close,			kXObj,					400 },	// D4
+	{ VMisOnXFCN::fileNames,			VMisOnXFCN::open,			VMisOnXFCN::close,		kXObj,					400 },	// D4
 	{ ValkyrieXObj::fileNames,			ValkyrieXObj::open,			ValkyrieXObj::close,		kXObj,					400 },	// D4
 	{ VideodiscXObj::fileNames,			VideodiscXObj::open,		VideodiscXObj::close,		kXObj,					200 },	// D2
 	{ VolumeList::fileNames,			VolumeList::open,			VolumeList::close,			kXObj,					300 },	// D3
 	{ WinInfoXObj::fileNames,			WinInfoXObj::open,			WinInfoXObj::close,			kXObj,					400 },  // D4
 	{ WidgetXObj::fileNames,			WidgetXObj::open,			WidgetXObj::close, 			kXObj,					400 },  // D4
 	{ XCMDGlueXObj::fileNames,			XCMDGlueXObj::open,			XCMDGlueXObj::close,		kXObj,					200 },	// D2
+	{ XSoundXFCN::fileNames,			XSoundXFCN::open,			XSoundXFCN::close,		kXObj,					400 },	// D4
 	{ XioXObj::fileNames,				XioXObj::open,				XioXObj::close,				kXObj,					400 },	// D3
 	{ XPlayAnim::fileNames,				XPlayAnim::open,			XPlayAnim::close,			kXObj,					300 },	// D3
 	{ Yasix::fileNames,					Yasix::open,				Yasix::close,				kXObj,					300 },	// D3
diff --git a/engines/director/lingo/xlibs/fadegammadownxcmd.cpp b/engines/director/lingo/xlibs/fadegammadownxcmd.cpp
new file mode 100644
index 00000000000..c9386aa5041
--- /dev/null
+++ b/engines/director/lingo/xlibs/fadegammadownxcmd.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/fadegammadownxcmd.h"
+
+/**************************************************
+ *
+ * USED IN:
+ * puppetmotel
+ *
+ **************************************************/
+
+namespace Director {
+
+const char *FadeGammaDownXCMD::xlibName = "FadeGammaDown";
+const char *FadeGammaDownXCMD::fileNames[] = {
+	"FadeGammaDown",
+	nullptr
+};
+
+static BuiltinProto builtins[] = {
+	{ "FadeGammaDown", FadeGammaDownXCMD::m_FadeGammaDown, -1, 0, 400, CBLTIN },
+	{ nullptr, nullptr, 0, 0, 0, VOIDSYM }
+};
+
+void FadeGammaDownXCMD::open(int type) {
+	g_lingo->initBuiltIns(builtins);
+}
+
+void FadeGammaDownXCMD::close(int type) {
+	g_lingo->cleanupBuiltIns(builtins);
+}
+
+XOBJSTUB(FadeGammaDownXCMD::m_FadeGammaDown, 0)
+
+}
diff --git a/engines/director/lingo/xlibs/fadegammadownxcmd.h b/engines/director/lingo/xlibs/fadegammadownxcmd.h
new file mode 100644
index 00000000000..d422ebd4e52
--- /dev/null
+++ b/engines/director/lingo/xlibs/fadegammadownxcmd.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_FADEGAMMADOWNXCMD_H
+#define DIRECTOR_LINGO_XLIBS_FADEGAMMADOWNXCMD_H
+
+namespace Director {
+
+namespace FadeGammaDownXCMD {
+
+extern const char *xlibName;
+extern const char *fileNames[];
+
+void open(int type);
+void close(int type);
+
+void m_FadeGammaDown(int nargs);
+
+} // End of namespace FadeGammaDownXCMD
+
+} // End of namespace Director
+
+#endif
diff --git a/engines/director/lingo/xlibs/fadegammaupxcmd.cpp b/engines/director/lingo/xlibs/fadegammaupxcmd.cpp
new file mode 100644
index 00000000000..7afb86af224
--- /dev/null
+++ b/engines/director/lingo/xlibs/fadegammaupxcmd.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/fadegammaupxcmd.h"
+
+/**************************************************
+ *
+ * USED IN:
+ * puppetmotel
+ *
+ **************************************************/
+
+namespace Director {
+
+const char *FadeGammaUpXCMD::xlibName = "FadeGammaUp";
+const char *FadeGammaUpXCMD::fileNames[] = {
+	"FadeGammaUp",
+	nullptr
+};
+
+static BuiltinProto builtins[] = {
+	{ "FadeGammaUp", FadeGammaUpXCMD::m_FadeGammaUp, -1, 0, 400, CBLTIN },
+	{ nullptr, nullptr, 0, 0, 0, VOIDSYM }
+};
+
+void FadeGammaUpXCMD::open(int type) {
+	g_lingo->initBuiltIns(builtins);
+}
+
+void FadeGammaUpXCMD::close(int type) {
+	g_lingo->cleanupBuiltIns(builtins);
+}
+
+XOBJSTUB(FadeGammaUpXCMD::m_FadeGammaUp, 0)
+
+}
diff --git a/engines/director/lingo/xlibs/fadegammaupxcmd.h b/engines/director/lingo/xlibs/fadegammaupxcmd.h
new file mode 100644
index 00000000000..18b4a1d3611
--- /dev/null
+++ b/engines/director/lingo/xlibs/fadegammaupxcmd.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_FADEGAMMAUPXCMD_H
+#define DIRECTOR_LINGO_XLIBS_FADEGAMMAUPXCMD_H
+
+namespace Director {
+
+namespace FadeGammaUpXCMD {
+
+extern const char *xlibName;
+extern const char *fileNames[];
+
+void open(int type);
+void close(int type);
+
+void m_FadeGammaUp(int nargs);
+
+} // End of namespace FadeGammaUpXCMD
+
+} // End of namespace Director
+
+#endif
diff --git a/engines/director/lingo/xlibs/fadegammaxcmd.cpp b/engines/director/lingo/xlibs/fadegammaxcmd.cpp
new file mode 100644
index 00000000000..db34b9ebcf5
--- /dev/null
+++ b/engines/director/lingo/xlibs/fadegammaxcmd.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/fadegammaxcmd.h"
+
+/**************************************************
+ *
+ * USED IN:
+ * puppetmotel
+ *
+ **************************************************/
+
+namespace Director {
+
+const char *FadeGammaXCMD::xlibName = "FadeGamma";
+const char *FadeGammaXCMD::fileNames[] = {
+	"FadeGamma",
+	nullptr
+};
+
+static BuiltinProto builtins[] = {
+	{ "FadeGamma", FadeGammaXCMD::m_FadeGamma, -1, 0, 400, CBLTIN },
+	{ nullptr, nullptr, 0, 0, 0, VOIDSYM }
+};
+
+void FadeGammaXCMD::open(int type) {
+	g_lingo->initBuiltIns(builtins);
+}
+
+void FadeGammaXCMD::close(int type) {
+	g_lingo->cleanupBuiltIns(builtins);
+}
+
+XOBJSTUB(FadeGammaXCMD::m_FadeGamma, 0)
+
+}
diff --git a/engines/director/lingo/xlibs/fadegammaxcmd.h b/engines/director/lingo/xlibs/fadegammaxcmd.h
new file mode 100644
index 00000000000..d85745d26a9
--- /dev/null
+++ b/engines/director/lingo/xlibs/fadegammaxcmd.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_FADEGAMMAXCMD_H
+#define DIRECTOR_LINGO_XLIBS_FADEGAMMAXCMD_H
+
+namespace Director {
+
+namespace FadeGammaXCMD {
+
+extern const char *xlibName;
+extern const char *fileNames[];
+
+void open(int type);
+void close(int type);
+
+void m_FadeGamma(int nargs);
+
+} // End of namespace FadeGammaXCMD
+
+} // End of namespace Director
+
+#endif
diff --git a/engines/director/lingo/xlibs/findereventsxcmd.cpp b/engines/director/lingo/xlibs/findereventsxcmd.cpp
new file mode 100644
index 00000000000..ea4fd7c24ab
--- /dev/null
+++ b/engines/director/lingo/xlibs/findereventsxcmd.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/findereventsxcmd.h"
+
+/**************************************************
+ *
+ * USED IN:
+ * puppetmotel
+ *
+ **************************************************/
+
+namespace Director {
+
+const char *FinderEventsXCMD::xlibName = "FinderEvents";
+const char *FinderEventsXCMD::fileNames[] = {
+	"FinderEvents",
+	nullptr
+};
+
+static BuiltinProto builtins[] = {
+	{ "FinderEvents", FinderEventsXCMD::m_FinderEvents, -1, 0, 400, CBLTIN },
+	{ nullptr, nullptr, 0, 0, 0, VOIDSYM }
+};
+
+void FinderEventsXCMD::open(int type) {
+	g_lingo->initBuiltIns(builtins);
+}
+
+void FinderEventsXCMD::close(int type) {
+	g_lingo->cleanupBuiltIns(builtins);
+}
+
+XOBJSTUB(FinderEventsXCMD::m_FinderEvents, 0)
+
+}
diff --git a/engines/director/lingo/xlibs/findereventsxcmd.h b/engines/director/lingo/xlibs/findereventsxcmd.h
new file mode 100644
index 00000000000..028edd1aae9
--- /dev/null
+++ b/engines/director/lingo/xlibs/findereventsxcmd.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_FINDEREVENTSXCMD_H
+#define DIRECTOR_LINGO_XLIBS_FINDEREVENTSXCMD_H
+
+namespace Director {
+
+namespace FinderEventsXCMD {
+
+extern const char *xlibName;
+extern const char *fileNames[];
+
+void open(int type);
+void close(int type);
+
+void m_FinderEvents(int nargs);
+
+} // End of namespace FinderEventsXCMD
+
+} // End of namespace Director
+
+#endif
diff --git a/engines/director/lingo/xlibs/vmisonxfcn.cpp b/engines/director/lingo/xlibs/vmisonxfcn.cpp
new file mode 100644
index 00000000000..cb93dcb442c
--- /dev/null
+++ b/engines/director/lingo/xlibs/vmisonxfcn.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/vmisonxfcn.h"
+
+/**************************************************
+ *
+ * USED IN:
+ * puppetmotel
+ *
+ **************************************************/
+
+namespace Director {
+
+const char *VMisOnXFCN::xlibName = "VMisOn";
+const char *VMisOnXFCN::fileNames[] = {
+	"VMisOn",
+	nullptr
+};
+
+static BuiltinProto builtins[] = {
+	{ "VMisOn", VMisOnXFCN::m_VMisOn, -1, 0, 400, HBLTIN },
+	{ nullptr, nullptr, 0, 0, 0, VOIDSYM }
+};
+
+void VMisOnXFCN::open(int type) {
+	g_lingo->initBuiltIns(builtins);
+}
+
+void VMisOnXFCN::close(int type) {
+	g_lingo->cleanupBuiltIns(builtins);
+}
+
+XOBJSTUB(VMisOnXFCN::m_VMisOn, 0)
+
+}
diff --git a/engines/director/lingo/xlibs/vmisonxfcn.h b/engines/director/lingo/xlibs/vmisonxfcn.h
new file mode 100644
index 00000000000..f4c23ea2848
--- /dev/null
+++ b/engines/director/lingo/xlibs/vmisonxfcn.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_VMISONXFCN_H
+#define DIRECTOR_LINGO_XLIBS_VMISONXFCN_H
+
+namespace Director {
+
+namespace VMisOnXFCN {
+
+extern const char *xlibName;
+extern const char *fileNames[];
+
+void open(int type);
+void close(int type);
+
+void m_VMisOn(int nargs);
+
+} // End of namespace VMisOnXFCN
+
+} // End of namespace Director
+
+#endif
diff --git a/engines/director/lingo/xlibs/xsoundxfcn.cpp b/engines/director/lingo/xlibs/xsoundxfcn.cpp
new file mode 100644
index 00000000000..6a4cfae707b
--- /dev/null
+++ b/engines/director/lingo/xlibs/xsoundxfcn.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/xsoundxfcn.h"
+
+/**************************************************
+ *
+ * USED IN:
+ * puppetmotel
+ *
+ **************************************************/
+
+namespace Director {
+
+const char *XSoundXFCN::xlibName = "XSound";
+const char *XSoundXFCN::fileNames[] = {
+	"XSound",
+	nullptr
+};
+
+static BuiltinProto builtins[] = {
+	{ "XSound", XSoundXFCN::m_XSound, -1, 0, 400, HBLTIN },
+	{ nullptr, nullptr, 0, 0, 0, VOIDSYM }
+};
+
+void XSoundXFCN::open(int type) {
+	g_lingo->initBuiltIns(builtins);
+}
+
+void XSoundXFCN::close(int type) {
+	g_lingo->cleanupBuiltIns(builtins);
+}
+
+XOBJSTUB(XSoundXFCN::m_XSound, 0)
+
+}
diff --git a/engines/director/lingo/xlibs/xsoundxfcn.h b/engines/director/lingo/xlibs/xsoundxfcn.h
new file mode 100644
index 00000000000..7d5b7ca2c0a
--- /dev/null
+++ b/engines/director/lingo/xlibs/xsoundxfcn.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_XSOUNDXFCN_H
+#define DIRECTOR_LINGO_XLIBS_XSOUNDXFCN_H
+
+namespace Director {
+
+namespace XSoundXFCN {
+
+extern const char *xlibName;
+extern const char *fileNames[];
+
+void open(int type);
+void close(int type);
+
+void m_XSound(int nargs);
+
+} // End of namespace XSoundXFCN
+
+} // End of namespace Director
+
+#endif
diff --git a/engines/director/module.mk b/engines/director/module.mk
index 1bae0ddd928..ae812b388f3 100644
--- a/engines/director/module.mk
+++ b/engines/director/module.mk
@@ -72,11 +72,15 @@ MODULE_OBJS = \
 	lingo/xlibs/draw.o \
 	lingo/xlibs/ednox.o \
 	lingo/xlibs/eventq.o \
+	lingo/xlibs/fadegammadownxcmd.o \
+	lingo/xlibs/fadegammaupxcmd.o \
+	lingo/xlibs/fadegammaxcmd.o \
 	lingo/xlibs/fedracul.o \
 	lingo/xlibs/feimasks.o \
 	lingo/xlibs/feiprefs.o \
 	lingo/xlibs/fileexists.o \
 	lingo/xlibs/fileio.o \
+	lingo/xlibs/findereventsxcmd.o \
 	lingo/xlibs/findfolder.o \
 	lingo/xlibs/findsys.o \
 	lingo/xlibs/findwin.o \
@@ -118,6 +122,7 @@ MODULE_OBJS = \
 	lingo/xlibs/unittest.o \
 	lingo/xlibs/valkyrie.o \
 	lingo/xlibs/videodiscxobj.o \
+	lingo/xlibs/vmisonxfcn.o \
 	lingo/xlibs/volumelist.o \
 	lingo/xlibs/widgetxobj.o \
 	lingo/xlibs/winxobj.o \
@@ -125,6 +130,7 @@ MODULE_OBJS = \
 	lingo/xlibs/xcmdglue.o \
 	lingo/xlibs/xio.o \
 	lingo/xlibs/xplayanim.o \
+	lingo/xlibs/xsoundxfcn.o \
 	lingo/xlibs/yasix.o
 
 # HACK: Skip this when including the file for detection objects.




More information about the Scummvm-git-logs mailing list