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

moralrecordings noreply at scummvm.org
Sat Oct 24 10:09:19 UTC 2026


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

Summary:
4e8598bef1 DIRECTOR: Add file quirk for frankenstein
b453165eb1 DIRECTOR: XOBJ: Add stubs for frankenstein-mac
da764ba914 DIRECTOR: Add support for multi-file Mac projectors


Commit: 4e8598bef11beee8d28604a763b92e78e56eba1a
    https://github.com/scummvm/scummvm/commit/4e8598bef11beee8d28604a763b92e78e56eba1a
Author: Scott Percival (code at moral.net.au)
Date: 2026-10-24T18:07:29+08:00

Commit Message:
DIRECTOR: Add file quirk for frankenstein

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


diff --git a/engines/director/game-quirks.cpp b/engines/director/game-quirks.cpp
index 4ed09bbf540..ca677ca61d7 100644
--- a/engines/director/game-quirks.cpp
+++ b/engines/director/game-quirks.cpp
@@ -175,6 +175,9 @@ struct CachedFile {
 	{ "pingu1", Common::kPlatformWindows, "PINGUDRV.PNG", (const byte *)"C:\\\r\nC:\\\r\nD:\\\r\n", -1},
 	{ "pingu1", Common::kPlatformWindows, "CHECKDRV.PNG", (const byte *)"D:\\\r\n", -1},
 
+	{ "frankenstein", Common::kPlatformWindows, "GAMEFILE/VOLUME", (const byte *)"D:\\", -1},
+	{ "frankenstein", Common::kPlatformMacintosh, "GAMEFILE/VOLUME", (const byte *)"@", -1},
+
 	{ nullptr, Common::kPlatformUnknown, nullptr, nullptr, 0 }
 };
 


Commit: b453165eb18e9d1847b99ba04d7002cd9eb7dfd2
    https://github.com/scummvm/scummvm/commit/b453165eb18e9d1847b99ba04d7002cd9eb7dfd2
Author: Scott Percival (code at moral.net.au)
Date: 2026-10-24T18:07:29+08:00

Commit Message:
DIRECTOR: XOBJ: Add stubs for frankenstein-mac

Changed paths:
  A engines/director/lingo/xlibs/q/qtversionxfcn.cpp
  A engines/director/lingo/xlibs/q/qtversionxfcn.h
  A engines/director/lingo/xlibs/s/stagetocast.cpp
  A engines/director/lingo/xlibs/s/stagetocast.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 158691a8179..cb2c78b7184 100644
--- a/engines/director/lingo/lingo-object.cpp
+++ b/engines/director/lingo/lingo-object.cpp
@@ -125,6 +125,7 @@
 #include "director/lingo/xlibs/q/qtcatmovieplayerxobj.h"
 #include "director/lingo/xlibs/q/qtsupport.h"
 #include "director/lingo/xlibs/q/qtmovie.h"
+#include "director/lingo/xlibs/q/qtversionxfcn.h"
 #include "director/lingo/xlibs/q/qtvr.h"
 #include "director/lingo/xlibs/q/quicktime.h"
 #include "director/lingo/xlibs/r/registercomponent.h"
@@ -134,6 +135,7 @@
 #include "director/lingo/xlibs/s/soundjam.h"
 #include "director/lingo/xlibs/s/spacemgr.h"
 #include "director/lingo/xlibs/s/stagetc.h"
+#include "director/lingo/xlibs/s/stagetocast.h"
 #include "director/lingo/xlibs/s/syscolor.h"
 #include "director/lingo/xlibs/s/savenrestorexobj.h"
 #include "director/lingo/xlibs/s/stagectl.h"
@@ -381,6 +383,7 @@ static const struct XLibProto {
 	XLIBDEF(QTMovie,			kXObj,			400),	// D4
 	XLIBDEF(QTSupport,			kXObj,			600),	// D4
 	XLIBDEF(QTVR,				kXObj,			400),	// D4
+	XLIBDEF(QTVersionXFCN,			kXObj,					300),	// D3
 	XLIBDEF(QtvrxtraXtra,		kXtraObj,		500),	// D5
 	XLIBDEF(Quicktime,			kXObj,			300),	// D3
 	XLIBDEF(RearWindowXObj,		kXObj,			300),	// D3
@@ -398,6 +401,7 @@ static const struct XLibProto {
 	XLIBDEF(SpaceMgr,			kXObj,			400),	// D4
 	XLIBDEF(StageControlXObj,			kXObj,					300),	// D3
 	XLIBDEF(StageTCXObj,		kXObj,			400),	// D4
+	XLIBDEF(StageToCastXObj,			kXObj,					400),	// D4
 	XLIBDEF(StayToonedBallXtra,			kXtraObj,					500),	// D5
 	XLIBDEF(StayToonedGlopXtra,			kXtraObj,					500),	// D5
 	XLIBDEF(StayToonedHallXtra,			kXtraObj,					500),	// D5
diff --git a/engines/director/lingo/xlibs/q/qtversionxfcn.cpp b/engines/director/lingo/xlibs/q/qtversionxfcn.cpp
new file mode 100644
index 00000000000..5ddf17d4ca2
--- /dev/null
+++ b/engines/director/lingo/xlibs/q/qtversionxfcn.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/q/qtversionxfcn.h"
+
+/**************************************************
+ *
+ * USED IN:
+ * frankenstein-mac
+ *
+ **************************************************/
+
+namespace Director {
+
+const char *QTVersionXFCN::xlibName = "QTVersion";
+const XlibFileDesc QTVersionXFCN::fileNames[] = {
+	{ "QTVersion", nullptr },
+	{ nullptr, nullptr }
+};
+
+static BuiltinProto builtins[] = {
+	{ "QTVersion", QTVersionXFCN::m_QTVersion, -1, 0, 300, HBLTIN },
+	{ nullptr, nullptr, 0, 0, 0, VOIDSYM }
+};
+
+void QTVersionXFCN::open(ObjectType type, const Common::Path &path) {
+	g_lingo->initBuiltIns(builtins);
+}
+
+void QTVersionXFCN::close(ObjectType type) {
+	g_lingo->cleanupBuiltIns(builtins);
+}
+
+XOBJSTUB(QTVersionXFCN::m_QTVersion, Common::String("2.0"))
+
+}
diff --git a/engines/director/lingo/xlibs/q/qtversionxfcn.h b/engines/director/lingo/xlibs/q/qtversionxfcn.h
new file mode 100644
index 00000000000..403b62cafbf
--- /dev/null
+++ b/engines/director/lingo/xlibs/q/qtversionxfcn.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_Q_QTVERSIONXFCN_H
+#define DIRECTOR_LINGO_XLIBS_Q_QTVERSIONXFCN_H
+
+namespace Director {
+
+namespace QTVersionXFCN {
+
+extern const char *xlibName;
+extern const XlibFileDesc fileNames[];
+
+void open(ObjectType type, const Common::Path &path);
+void close(ObjectType type);
+
+void m_QTVersion(int nargs);
+
+} // End of namespace QTVersionXFCN
+
+} // End of namespace Director
+
+#endif
diff --git a/engines/director/lingo/xlibs/s/stagetocast.cpp b/engines/director/lingo/xlibs/s/stagetocast.cpp
new file mode 100644
index 00000000000..9c844f82619
--- /dev/null
+++ b/engines/director/lingo/xlibs/s/stagetocast.cpp
@@ -0,0 +1,104 @@
+/* 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/s/stagetocast.h"
+
+/**************************************************
+ *
+ * USED IN:
+ * frankenstein-mac
+ *
+ **************************************************/
+
+/*
+-- StageToCast.XObj vers. 1.0.1
+--             Returns a handle to a bitmap of a
+--             particular region of the active screen,
+--             so you can assign it to a CastMember.
+--
+IIIII mNew  -- creates the object in RAM,
+--             and is used to specify the region
+--             of the screen. Four integers are in
+--             order of: Top, Left, Bottom, Right.
+--             Example of Lingo syntax:
+-- set myObj =  StageToCast( mNew, 65, 86, 65+128, 86+240 )
+--
+P mGetHandle -- returns a handle to the bitmap.
+--              Example of Lingo syntax:
+-- set the picture of cast A11 = myObj( mGetHandle )
+ */
+
+namespace Director {
+
+const char *StageToCastXObj::xlibName = "StageToCast";
+const XlibFileDesc StageToCastXObj::fileNames[] = {
+	{ "StageToCast",   nullptr },
+	{ nullptr,        nullptr },
+};
+
+static MethodProto xlibMethods[] = {
+	{ "new",				StageToCastXObj::m_new,		 4, 4,	400 },
+	{ "getHandle",				StageToCastXObj::m_getHandle,		 0, 0,	400 },
+
+	{ nullptr, nullptr, 0, 0, 0 }
+};
+
+static BuiltinProto xlibBuiltins[] = {
+
+	{ nullptr, nullptr, 0, 0, 0, VOIDSYM }
+};
+
+StageToCastXObject::StageToCastXObject(ObjectType ObjectType) :Object<StageToCastXObject>("StageToCast") {
+	_objType = ObjectType;
+}
+
+void StageToCastXObj::open(ObjectType type, const Common::Path &path) {
+    StageToCastXObject::initMethods(xlibMethods);
+    StageToCastXObject *xobj = new StageToCastXObject(type);
+    if (type == kXtraObj) {
+        g_lingo->_openXtras.push_back(xlibName);
+        g_lingo->_openXtraObjects.push_back(xobj);
+    }
+    g_lingo->exposeXObject(xlibName, xobj);
+    g_lingo->initBuiltIns(xlibBuiltins);
+}
+
+void StageToCastXObj::close(ObjectType type) {
+    StageToCastXObject::cleanupMethods();
+    g_lingo->_globalvars[xlibName] = Datum();
+
+}
+
+void StageToCastXObj::m_new(int nargs) {
+	g_lingo->printSTUBWithArglist("StageToCastXObj::m_new", nargs);
+	g_lingo->dropStack(nargs);
+	g_lingo->push(g_lingo->_state->me);
+}
+
+XOBJSTUB(StageToCastXObj::m_getHandle, 0)
+
+}
diff --git a/engines/director/lingo/xlibs/s/stagetocast.h b/engines/director/lingo/xlibs/s/stagetocast.h
new file mode 100644
index 00000000000..c99950b06a5
--- /dev/null
+++ b/engines/director/lingo/xlibs/s/stagetocast.h
@@ -0,0 +1,47 @@
+/* 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_S_STAGETOCAST_H
+#define DIRECTOR_LINGO_XLIBS_S_STAGETOCAST_H
+
+namespace Director {
+
+class StageToCastXObject : public Object<StageToCastXObject> {
+public:
+	StageToCastXObject(ObjectType objType);
+};
+
+namespace StageToCastXObj {
+
+extern const char *xlibName;
+extern const XlibFileDesc fileNames[];
+
+void open(ObjectType type, const Common::Path &path);
+void close(ObjectType type);
+
+void m_new(int nargs);
+void m_getHandle(int nargs);
+
+} // End of namespace StageToCastXObj
+
+} // End of namespace Director
+
+#endif
diff --git a/engines/director/module.mk b/engines/director/module.mk
index 39148d79e11..28550729f76 100644
--- a/engines/director/module.mk
+++ b/engines/director/module.mk
@@ -157,6 +157,7 @@ MODULE_OBJS = \
 	lingo/xlibs/q/qtcatmovieplayerxobj.o \
 	lingo/xlibs/q/qtmovie.o \
 	lingo/xlibs/q/qtsupport.o \
+	lingo/xlibs/q/qtversionxfcn.o \
 	lingo/xlibs/q/qtvr.o \
 	lingo/xlibs/q/quicktime.o \
 	lingo/xlibs/r/registercomponent.o \
@@ -168,6 +169,7 @@ MODULE_OBJS = \
 	lingo/xlibs/s/spacemgr.o \
 	lingo/xlibs/s/stagectl.o \
 	lingo/xlibs/s/stagetc.o \
+	lingo/xlibs/s/stagetocast.o \
 	lingo/xlibs/s/syscolor.o \
 	lingo/xlibs/t/temnotaxobj.o \
 	lingo/xlibs/t/tengu.o \


Commit: da764ba9144b04befd86384c5b2c33026b4514d0
    https://github.com/scummvm/scummvm/commit/da764ba9144b04befd86384c5b2c33026b4514d0
Author: Scott Percival (code at moral.net.au)
Date: 2026-10-24T18:07:29+08:00

Commit Message:
DIRECTOR: Add support for multi-file Mac projectors

Tested with frankenstein-mac and maniacsports-win.

Changed paths:
    engines/director/resource.cpp


diff --git a/engines/director/resource.cpp b/engines/director/resource.cpp
index 32f6106d813..3add8d20c47 100644
--- a/engines/director/resource.cpp
+++ b/engines/director/resource.cpp
@@ -99,7 +99,7 @@ Common::Error Window::loadInitialMovie() {
 	// load startup movie
 	Common::Path startupPath = g_director->getStartupPath();
 	if (!startupPath.empty()) {
-		Common::SeekableReadStream *const stream = SearchMan.createReadStreamForMember(startupPath);
+		Common::SeekableReadStream *const stream = Common::MacResManager::openFileOrDataFork(startupPath);
 		if (stream) {
 			uint size = stream->size();
 			char *script = (char *)calloc(size + 1, 1);
@@ -278,7 +278,7 @@ Common::SharedPtr<Archive> DirectorEngine::openArchive(const Common::Path &path)
 }
 
 void Window::loadINIStream() {
-	Common::SeekableReadStream *iniStream = SearchMan.createReadStreamForMember("LINGO.INI");
+	Common::SeekableReadStream *iniStream = Common::MacResManager::openFileOrDataFork("LINGO.INI");
 	if (iniStream) {
 		char *script = (char *)calloc(iniStream->size() + 1, 1);
 		iniStream->read(script, iniStream->size());
@@ -297,7 +297,7 @@ void Window::loadINIStream() {
 }
 
 Archive *DirectorEngine::loadEXE(const Common::Path &movie) {
-	Common::SeekableReadStream *exeStream = SearchMan.createReadStreamForMember(movie);
+	Common::SeekableReadStream *exeStream = Common::MacResManager::openFileOrDataFork(movie);
 	if (!exeStream) {
 		debugC(5, kDebugLoading, "DirectorEngine::loadEXE(): Failed to open file '%s'", movie.toString().c_str());
 		return nullptr;
@@ -408,7 +408,7 @@ Archive *DirectorEngine::loadEXEv3(Common::SeekableReadStream *stream) {
 			if (!SearchMan.hasFile(Common::Path(mmmFileName_, g_director->_dirSeparator)))
 				warning("DirectorEngine::loadEXEv3(): Failed to find MMM '%s'", mmmFileName_.c_str());
 			else {
-				Common::SeekableReadStream *const mmmFile_ = SearchMan.createReadStreamForMember(Common::Path(mmmFileName_, g_director->_dirSeparator));
+				Common::SeekableReadStream *const mmmFile_ = Common::MacResManager::openFileOrDataFork(Common::Path(mmmFileName_, g_director->_dirSeparator));
 				uint32 mmmFileSize_ = mmmFile_->size();
 				if (mmmSize_ != mmmFileSize_)
 					warning("DirectorEngine::loadEXEv3(): File size for '%s' doesn't match. Got %d (0x%x), want %d (0x%x)", mmmFileName_.c_str(), mmmFileSize_, mmmFileSize_, mmmSize_, mmmSize_);
@@ -650,7 +650,7 @@ ProjectorArchive::ProjectorArchive(Common::Path path)
 Common::SeekableReadStream *ProjectorArchive::createBufferedReadStream() {
 	const uint32 READ_BUFFER_SIZE = 1024 * 100;
 
-	Common::SeekableReadStream *stream = SearchMan.createReadStreamForMember(_path);
+	Common::SeekableReadStream *stream = Common::MacResManager::openFileOrDataFork(_path);
 	if (!stream) {
 		warning("ProjectorArchive::createBufferedReadStream(): Cannot open %s", _path.toString().c_str());
 		return nullptr;
@@ -665,12 +665,16 @@ ProjectorArchive::~ProjectorArchive() {
 
 bool ProjectorArchive::loadArchive(Common::SeekableReadStream *stream) {
 	bool bigEndian = false, found = false;
-	uint32 off, tag, rifxOffset;
-
-	stream->seek(-4, SEEK_END);
-	off = stream->readUint32LE();
-	stream->seek(off);
-	tag = stream->readUint32BE();
+	uint32 off = 0;
+
+	uint32 tag = stream->readUint32BE();
+	if ((tag & 0xffff0000) == MKTAG('M', 'Z', 0, 0)) {
+		// Windows projector: start offset of the movie data is glommed on the end
+		stream->seek(-4, SEEK_END);
+		off = stream->readUint32LE();
+		stream->seek(off);
+		tag = stream->readUint32BE();
+	}
 
 	// Check whether we got a 'PJ' tag while ignoring the version and accounting for endianness
 	if (((tag & 0xffff0000) != MKTAG('P','J', 0, 0)) && ((tag & 0x0000ffff) != MKTAG(0, 0, 'J','P'))) {
@@ -678,7 +682,7 @@ bool ProjectorArchive::loadArchive(Common::SeekableReadStream *stream) {
 		return false;
 	}
 
-	rifxOffset = stream->readUint32LE();
+	uint32 rifxOffset = stream->readUint32LE();
 
 	// if value is bigger than the stream size this is most likely a endianness issue.
 	if (rifxOffset > stream->size()) {
@@ -727,8 +731,7 @@ bool ProjectorArchive::loadArchive(Common::SeekableReadStream *stream) {
 	stream->seek(dictOff + 24);
 	uint32 cnt = bigEndian ? stream->readUint32BE() : stream->readUint32LE();
 
-	// Correction for when there is only a single element present according to the dict
-	uint8 offsetDict = bigEndian && cnt == 1 ? 2 : 0;
+	uint8 offsetDict = bigEndian ? 2 : 0;
 	bool oBigEndian = bigEndian;
 
 	// For 16-bit win projector
@@ -738,7 +741,7 @@ bool ProjectorArchive::loadArchive(Common::SeekableReadStream *stream) {
 		bigEndian = true;
 	}
 
-	debugC(1, kDebugLoading, "Dict off: 0x%x, Size: 0x%x cnt: %d", dictOff, size, cnt);
+	debugC(1, kDebugLoading, "Dict off: 0x%x, size: 0x%x, cnt: %d", dictOff, size, cnt);
 
 	uint32 pt = (cnt * 8) + (64 - offsetDict);
 	Common::StringArray arr(cnt);
@@ -752,6 +755,7 @@ bool ProjectorArchive::loadArchive(Common::SeekableReadStream *stream) {
 
 		uint32 namelen = bigEndian ? stream->readUint32BE() : stream->readUint32LE();
 		arr[i] = stream->readString(0, namelen);
+		debugC(1, kDebugLoading, "Key[%d] = %s", i, arr[i].c_str());
 
 		if (i < cnt - 1) {
 			int sub = (namelen % 4) ? (namelen % 4) : 4;
@@ -825,7 +829,7 @@ Common::SeekableReadStream *ProjectorArchive::createReadStreamForMember(const Co
 	debugC(3, kDebugLoading, "ProjectorArchive::createReadStreamForMember(): Opening built-in file '%s' @ 0x%08x, %d bytes",
 		path.toString().c_str(), fDesc->_value.offset, fDesc->_value.size);
 
-	Common::SeekableReadStream *stream = SearchMan.createReadStreamForMember(_path);
+	Common::SeekableReadStream *stream = Common::MacResManager::openFileOrDataFork(_path);
 
 	stream->seek(fDesc->_value.offset, SEEK_SET);
 	byte *data = (byte *)malloc(fDesc->_value.size);




More information about the Scummvm-git-logs mailing list