[Scummvm-git-logs] scummvm master -> 3d330f1a1211335619cd0b3df0c447949d14033d
sev-
noreply at scummvm.org
Sat Aug 30 19:10:09 UTC 2025
This automated email contains information about 5 new commits which have been
pushed to the 'scummvm' repo located at https://api.github.com/repos/scummvm/scummvm .
Summary:
e7596b74b3 DIRECTOR: Fix detection entry for selfish
aab775fcb8 DIRECTOR: XOBJ: Add XPlayPACo XFCN stub
82f8fef925 DIRECTOR: Use shared cast filename resource in projector file
b4a6a978d5 DIRECTOR: Don't create digital video widget if video hasn't loaded
3d330f1a12 DIRECTOR: XOBJ: Implement XPLayPACoXFCN
Commit: e7596b74b3e9ce421010649753dfa14308277db7
https://github.com/scummvm/scummvm/commit/e7596b74b3e9ce421010649753dfa14308277db7
Author: Scott Percival (code at moral.net.au)
Date: 2025-08-30T21:10:04+02:00
Commit Message:
DIRECTOR: Fix detection entry for selfish
Changed paths:
engines/director/detection_tables.h
diff --git a/engines/director/detection_tables.h b/engines/director/detection_tables.h
index be33d271ee4..2e72d1b2dbd 100644
--- a/engines/director/detection_tables.h
+++ b/engines/director/detection_tables.h
@@ -3215,7 +3215,8 @@ static const DirectorGameDescription gameDescriptions[] = {
MACDEMO1("sculpt4d", "Vol.5 Demo", "Sculpt Demo Vol.5", "f54ac20d51c496911f9144ee595ade60", 1456309, 300),
MACDEMO1("sculpt4d", "Using Demo", "UsingSculpt1.0", "2ce360c9ea2da80a2c6d1040b0ad92dd", 383380, 313),
- WINGAME1("selfish", "", "selfish.exe", "t:260d50f7d51adba057a06bbcb6da3d43", 371037, 300),
+ MACGAME1("selfish", "", "Click for Story! (8mb)", "r:7f443f2e63fd497a9ad85b10dc880a91", 384549, 310),
+ WINGAME1("selfish", "", "SELFISH/SELFISH.EXE", "t:260d50f7d51adba057a06bbcb6da3d43", 371037, 310),
MACGAME1("sfk", "D3", "More SFK Products!", "r:1ae45c23586b41997ba52e2e7c771c4c", 377667, 310),
Commit: aab775fcb8cdf45162235edd95aebc9d05f6d0d8
https://github.com/scummvm/scummvm/commit/aab775fcb8cdf45162235edd95aebc9d05f6d0d8
Author: Scott Percival (code at moral.net.au)
Date: 2025-08-30T21:10:04+02:00
Commit Message:
DIRECTOR: XOBJ: Add XPlayPACo XFCN stub
Changed paths:
A engines/director/lingo/xlibs/xplaypacoxfcn.cpp
A engines/director/lingo/xlibs/xplaypacoxfcn.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 b564dc58ad6..6bcd48387ba 100644
--- a/engines/director/lingo/lingo-object.cpp
+++ b/engines/director/lingo/lingo-object.cpp
@@ -137,6 +137,7 @@
#include "director/lingo/xlibs/xcmdglue.h"
#include "director/lingo/xlibs/xio.h"
#include "director/lingo/xlibs/xplayanim.h"
+#include "director/lingo/xlibs/xplaypacoxfcn.h"
#include "director/lingo/xlibs/xsoundxfcn.h"
#include "director/lingo/xlibs/xwin.h"
#include "director/lingo/xlibs/yasix.h"
@@ -338,6 +339,7 @@ static const struct XLibProto {
XLIBDEF(WidgetXObj, kXObj, 400), // D4
XLIBDEF(WindowXObj, kXObj, 200), // D2
XLIBDEF(XCMDGlueXObj, kXObj, 200), // D2
+ XLIBDEF(XPlayPACoXFCN, kXObj, 300), // D3
XLIBDEF(XSoundXFCN, kXObj, 400), // D4
XLIBDEF(XWINXObj, kXObj, 300), // D3
XLIBDEF(XioXObj, kXObj, 400), // D3
diff --git a/engines/director/lingo/xlibs/xplaypacoxfcn.cpp b/engines/director/lingo/xlibs/xplaypacoxfcn.cpp
new file mode 100644
index 00000000000..d16e8129435
--- /dev/null
+++ b/engines/director/lingo/xlibs/xplaypacoxfcn.cpp
@@ -0,0 +1,61 @@
+/* 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/xplaypacoxfcn.h"
+
+/**************************************************
+ *
+ * USED IN:
+ * jman
+ *
+ **************************************************/
+
+namespace Director {
+
+const char *XPlayPACoXFCN::xlibName = "XPlayPACo";
+const XlibFileDesc XPlayPACoXFCN::fileNames[] = {
+ { "Presto.rsrc", "jman" },
+ { "XPlayPACo", nullptr },
+ { nullptr, nullptr }
+};
+
+static BuiltinProto builtins[] = {
+ { "XPlayPACo", XPlayPACoXFCN::m_XPlayPACo, -1, 0, 300, HBLTIN },
+ { nullptr, nullptr, 0, 0, 0, VOIDSYM }
+};
+
+void XPlayPACoXFCN::open(ObjectType type, const Common::Path &path) {
+ g_lingo->initBuiltIns(builtins);
+}
+
+void XPlayPACoXFCN::close(ObjectType type) {
+ g_lingo->cleanupBuiltIns(builtins);
+}
+
+XOBJSTUB(XPlayPACoXFCN::m_XPlayPACo, 0)
+
+}
diff --git a/engines/director/lingo/xlibs/xplaypacoxfcn.h b/engines/director/lingo/xlibs/xplaypacoxfcn.h
new file mode 100644
index 00000000000..b50856464e2
--- /dev/null
+++ b/engines/director/lingo/xlibs/xplaypacoxfcn.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_XPLAYPACOXFCN_H
+#define DIRECTOR_LINGO_XLIBS_XPLAYPACOXFCN_H
+
+namespace Director {
+
+namespace XPlayPACoXFCN {
+
+extern const char *xlibName;
+extern const XlibFileDesc fileNames[];
+
+void open(ObjectType type, const Common::Path &path);
+void close(ObjectType type);
+
+void m_XPlayPACo(int nargs);
+
+} // End of namespace XPlayPACoXFCN
+
+} // End of namespace Director
+
+#endif
diff --git a/engines/director/module.mk b/engines/director/module.mk
index ea429650ee7..fb4fefdd5dd 100644
--- a/engines/director/module.mk
+++ b/engines/director/module.mk
@@ -168,6 +168,7 @@ MODULE_OBJS = \
lingo/xlibs/xcmdglue.o \
lingo/xlibs/xio.o \
lingo/xlibs/xplayanim.o \
+ lingo/xlibs/xplaypacoxfcn.o \
lingo/xlibs/xsoundxfcn.o \
lingo/xlibs/xwin.o \
lingo/xlibs/yasix.o \
Commit: 82f8fef925a05b18aec627203e445c0c7840b6b5
https://github.com/scummvm/scummvm/commit/82f8fef925a05b18aec627203e445c0c7840b6b5
Author: Scott Percival (code at moral.net.au)
Date: 2025-08-30T21:10:04+02:00
Commit Message:
DIRECTOR: Use shared cast filename resource in projector file
On Mac Director normally this is "Shared Cast", but there's at least
one example out there of it being something else entirely.
Fixes shared cast loading in Journeyman Project.
Changed paths:
engines/director/resource.cpp
engines/director/window.cpp
engines/director/window.h
diff --git a/engines/director/resource.cpp b/engines/director/resource.cpp
index cf3e1eed1f2..24f276be59a 100644
--- a/engines/director/resource.cpp
+++ b/engines/director/resource.cpp
@@ -146,6 +146,22 @@ void Window::probeResources(Archive *archive) {
}
}
+ // Mac Director will check resource STR# id 200 from the projector
+ // executable, and use the second string in the list.
+ // Usually this is "Shared Cast", but Journeyman Project
+ // has this set to "Mars ESG Upper 03"??
+ if (archive->hasResource(MKTAG('S', 'T', 'R', '#'), 200)) {
+ Common::SeekableReadStreamEndian *name = archive->getResource(MKTAG('S', 'T', 'R', '#'), 200);
+ int num = name->readUint16();
+ if (num < 2) {
+ warning("Window::probeResources: Missing data in the Filenames resource of the Projector file");
+ delete name;
+ } else {
+ _soundsFilenameHint = decodePlatformEncoding(name->readPascalString());
+ _sharedCastFilenameHint = decodePlatformEncoding(name->readPascalString());
+ }
+ }
+
if (archive->hasResource(MKTAG('S', 'T', 'R', '#'), 0)) {
if (_currentMovie)
_currentMovie->setArchive(archive);
diff --git a/engines/director/window.cpp b/engines/director/window.cpp
index 940f61ddf3b..8c9f6535a0f 100644
--- a/engines/director/window.cpp
+++ b/engines/director/window.cpp
@@ -645,13 +645,18 @@ bool Window::step() {
Common::Path Window::getSharedCastPath() {
Common::Array<Common::String> namesToTry;
if (_vm->getVersion() < 400) {
- if (g_director->getPlatform() == Common::kPlatformWindows) {
+ if (!_sharedCastFilenameHint.empty()) {
+ namesToTry.push_back(_sharedCastFilenameHint);
+ } else if (g_director->getPlatform() == Common::kPlatformWindows) {
namesToTry.push_back("SHARDCST.MMM");
} else {
namesToTry.push_back("Shared Cast");
}
} else if (_vm->getVersion() < 500) {
namesToTry.push_back("Shared.dir");
+ if (!_sharedCastFilenameHint.empty()) {
+ namesToTry.push_back(_sharedCastFilenameHint);
+ }
}
Common::Path result;
diff --git a/engines/director/window.h b/engines/director/window.h
index d84b017263f..db9c587efa9 100644
--- a/engines/director/window.h
+++ b/engines/director/window.h
@@ -225,6 +225,8 @@ private:
int _windowType;
bool _isModal;
+ Common::String _sharedCastFilenameHint;
+ Common::String _soundsFilenameHint;
private:
static void drawChannelBox(Director::Movie *currentMovie, Graphics::ManagedSurface *blitTo, int selectedChannel);
Commit: b4a6a978d54969349a37d088eb79510702e3b768
https://github.com/scummvm/scummvm/commit/b4a6a978d54969349a37d088eb79510702e3b768
Author: Scott Percival (code at moral.net.au)
Date: 2025-08-30T21:10:04+02:00
Commit Message:
DIRECTOR: Don't create digital video widget if video hasn't loaded
Fixes performance degradation when games load a stub video (e.g. gothos,
jman).
Changed paths:
engines/director/castmember/digitalvideo.cpp
diff --git a/engines/director/castmember/digitalvideo.cpp b/engines/director/castmember/digitalvideo.cpp
index 0b6471ae76c..1bc6cb81dd9 100644
--- a/engines/director/castmember/digitalvideo.cpp
+++ b/engines/director/castmember/digitalvideo.cpp
@@ -186,6 +186,10 @@ bool DigitalVideoCastMember::loadVideoFromCast() {
bool DigitalVideoCastMember::loadVideo(Common::String path) {
// TODO: detect file type (AVI, QuickTime, FLIC) based on magic number,
// insert the right video decoder
+ if (_filename == path) {
+ // we've already loaded this video, or not. no point trying again.
+ return _video ? true : false;
+ }
if (_video) {
delete _video;
@@ -357,21 +361,16 @@ Graphics::MacWidget *DigitalVideoCastMember::createWidget(Common::Rect &bbox, Ch
if (_emptyFile)
return nullptr;
- Graphics::MacWidget *widget = new Graphics::MacWidget(g_director->getCurrentWindow(), bbox.left, bbox.top, bbox.width(), bbox.height(), g_director->_wm, false);
-
- _channel = channel;
-
if (!_video || !_video->isVideoLoaded()) {
// try and load the video if not already
- loadVideoFromCast();
+ if (!loadVideoFromCast()) {
+ return nullptr;
+ }
}
- if (!_video || !_video->isVideoLoaded()) {
- warning("DigitalVideoCastMember::createWidget: No video decoder");
- delete widget;
+ Graphics::MacWidget *widget = new Graphics::MacWidget(g_director->getCurrentWindow(), bbox.left, bbox.top, bbox.width(), bbox.height(), g_director->_wm, false);
- return nullptr;
- }
+ _channel = channel;
// Do not render stopped videos
if (_channel->_movieRate == 0.0 && !_getFirstFrame && _lastFrame) {
Commit: 3d330f1a1211335619cd0b3df0c447949d14033d
https://github.com/scummvm/scummvm/commit/3d330f1a1211335619cd0b3df0c447949d14033d
Author: Scott Percival (code at moral.net.au)
Date: 2025-08-30T21:10:04+02:00
Commit Message:
DIRECTOR: XOBJ: Implement XPLayPACoXFCN
Fixes various animations in The Journeyman Project.
Changed paths:
engines/director/lingo/xlibs/xplaypacoxfcn.cpp
diff --git a/engines/director/lingo/xlibs/xplaypacoxfcn.cpp b/engines/director/lingo/xlibs/xplaypacoxfcn.cpp
index d16e8129435..e0ebca38491 100644
--- a/engines/director/lingo/xlibs/xplaypacoxfcn.cpp
+++ b/engines/director/lingo/xlibs/xplaypacoxfcn.cpp
@@ -34,8 +34,125 @@
*
**************************************************/
+#include "video/paco_decoder.h"
+
namespace Director {
+struct PACoPlayer {
+ Video::PacoDecoder *_video;
+};
+
+class XPlayPACoState : public Object<XPlayPACoState> {
+public:
+ XPlayPACoState();
+ ~XPlayPACoState();
+
+ int openfile(Common::String &rawPath);
+ int close(int playerId);
+ Common::String play(int playerId, int posX, int posY);
+
+ Common::HashMap<int, PACoPlayer> _players;
+
+ int _nextId;
+};
+
+XPlayPACoState::XPlayPACoState() : Object<XPlayPACoState>("XPlayPACo") {
+ _nextId = 1;
+}
+
+XPlayPACoState::~XPlayPACoState() {
+ for (auto it : _players) {
+ delete it._value._video;
+ it._value._video = nullptr;
+ }
+}
+
+int XPlayPACoState::openfile(Common::String &rawPath) {
+ Common::Path path = findPath(rawPath);
+ if (path.empty()) {
+ warning("XPlayPACo::openfile: Could not resolve path %s", rawPath.c_str());
+ return -1;
+ }
+ Video::PacoDecoder *dec = new Video::PacoDecoder();
+ if (!dec->loadFile(path)) {
+ delete dec;
+ return -1;
+ }
+ int result = _nextId;
+ _nextId++;
+ _players[result] = PACoPlayer();
+ _players[result]._video = dec;
+ return result;
+}
+
+int XPlayPACoState::close(int playerId) {
+ if (_players.contains(playerId)) {
+ _players[playerId]._video->close();
+ delete _players[playerId]._video;
+ _players.erase(playerId);
+ }
+ return 0;
+}
+
+Common::String XPlayPACoState::play(int playerId, int posX, int posY) {
+ if (_players.contains(playerId)) {
+ Video::PacoDecoder *video = _players[playerId]._video;
+ // save the current palette
+ byte origPalette[256 * 3];
+ uint16 origCount = g_director->getPaletteColorCount();
+ if (origCount > 256) {
+ warning("callPacoPlay: too big palette, %d > 256", origCount);
+ origCount = 256;
+ }
+
+ memcpy(origPalette, g_director->getPalette(), origCount * 3);
+ byte videoPalette[256 * 3];
+
+ Graphics::Surface const *frame = nullptr;
+ Common::Event event;
+ bool keepPlaying = true;
+ video->start();
+ memcpy(videoPalette, video->getPalette(), 256 * 3);
+ while (!video->endOfVideo()) {
+ if (g_director->pollEvent(event)) {
+ switch (event.type) {
+ case Common::EVENT_QUIT:
+ g_director->processEventQUIT();
+ // fallthrough
+ case Common::EVENT_KEYDOWN:
+ case Common::EVENT_RBUTTONDOWN:
+ case Common::EVENT_LBUTTONDOWN:
+ keepPlaying = false;
+ break;
+ default:
+ break;
+ }
+ }
+ if (!keepPlaying)
+ break;
+ if (video->needsUpdate()) {
+ frame = video->decodeNextFrame();
+ // Palette info gets set after the frame is decoded
+ if (video->hasDirtyPalette()) {
+ byte *palette = const_cast<byte *>(video->getPalette());
+ memcpy(videoPalette, palette, 256 * 3);
+ }
+
+ // Video palette order is going to be different to the screen, we need to untangle it
+ Graphics::Surface *dither = frame->convertTo(g_director->_wm->_pixelformat, videoPalette, 256, origPalette, origCount, Graphics::kDitherNaive);
+ int width = MIN(dither->w + posX, (int)g_system->getWidth()) - posX;
+ int height = MIN(dither->h + posY, (int)g_system->getHeight()) - posY;
+ g_system->copyRectToScreen(dither->getPixels(), dither->pitch, posX, posY, width, height);
+ dither->free();
+ delete dither;
+ }
+ g_system->updateScreen();
+ g_director->delayMillis(10);
+ }
+ }
+ return "0 0";
+}
+
const char *XPlayPACoXFCN::xlibName = "XPlayPACo";
const XlibFileDesc XPlayPACoXFCN::fileNames[] = {
{ "Presto.rsrc", "jman" },
@@ -50,12 +167,70 @@ static BuiltinProto builtins[] = {
void XPlayPACoXFCN::open(ObjectType type, const Common::Path &path) {
g_lingo->initBuiltIns(builtins);
+
+ if (!g_lingo->_openXLibsState.contains("XPlayPACo")) {
+ XPlayPACoState *pacoState = new XPlayPACoState();
+ g_lingo->_openXLibsState.setVal("XPlayPACo", pacoState);
+ }
}
void XPlayPACoXFCN::close(ObjectType type) {
g_lingo->cleanupBuiltIns(builtins);
+ if (g_lingo->_openXLibsState.contains("XPlayPACo")) {
+ AbstractObject *pacoState = g_lingo->_openXLibsState.getVal("XPlayPACo");
+ delete pacoState;
+ g_lingo->_openXLibsState.erase("XPlayPACo");
+ }
}
-XOBJSTUB(XPlayPACoXFCN::m_XPlayPACo, 0)
+void XPlayPACoXFCN::m_XPlayPACo(int nargs) {
+ g_lingo->printSTUBWithArglist("m_XPlayPACo", nargs);
+ XPlayPACoState *state = (XPlayPACoState *)g_lingo->_openXLibsState.getVal("XPlayPACo");
+ Datum result;
+ if (nargs == 0) {
+ warning("XPlayPACoXFCN: no arguments");
+ } else {
+ Common::String cmd = g_lingo->peek(nargs - 1).asString();
+ if (cmd.equalsIgnoreCase("openfile")) {
+ if (nargs == 2) {
+ Common::String filename = g_lingo->peek(0).asString();
+ result = state->openfile(filename);
+ } else {
+ warning("XPlayPACoXFCN: expected 1 arg for openfile");
+ }
+ } else if (cmd.equals("set")) {
+
+ } else if (cmd.equals("play")) {
+ if (nargs >= 2) {
+ int playerId = g_lingo->peek(nargs - 2).asInt();
+ int posX = 0;
+ int posY = 0;
+ for (int i = nargs - 3; i >= 0; i -= 2) {
+ Datum paramName = g_lingo->peek(i);
+ Datum paramValue = g_lingo->peek(i - 1);
+ if (paramName.asString().equalsIgnoreCase("posX")) {
+ posX = paramValue.asInt();
+ } else if (paramName.asString().equalsIgnoreCase("posY")) {
+ posY = paramValue.asInt();
+ }
+ }
+ result = state->play(playerId, posX, posY);
+ } else {
+ warning("XPlayPACoXFCN: expected at least 1 arg for play");
+ }
+ } else if (cmd.equals("close")) {
+ if (nargs == 2) {
+ int playerId = g_lingo->peek(nargs - 2).asInt();
+ result = state->close(playerId);
+ } else {
+ warning("XPlayPACoXFCN: expected 1 arg for close");
+ }
+ } else {
+ warning("XPlayPACoXFCN: Unknown command %s", cmd.c_str());
+ }
+ }
+ g_lingo->dropStack(nargs);
+ g_lingo->push(result);
+}
}
More information about the Scummvm-git-logs
mailing list